From d508336422aeaae76c62574929c3e7b46271798a Mon Sep 17 00:00:00 2001 From: blitz-research Date: Thu, 23 Jan 2014 11:32:46 +1300 Subject: [PATCH] Added modules. --- mod/brl.mod/appstub.mod/appstub.bmx | 71 + mod/brl.mod/appstub.mod/appstub.linux.c | 17 + mod/brl.mod/appstub.mod/appstub.macos.m | 139 + mod/brl.mod/appstub.mod/appstub.win32.c | 70 + mod/brl.mod/appstub.mod/debugger.stdio.bmx | 711 + mod/brl.mod/appstub.mod/debugger_mt.stdio.bmx | 725 + mod/brl.mod/audio.mod/audio.bmx | 381 + mod/brl.mod/audio.mod/doc/allocchannel.bmx | 11 + mod/brl.mod/audio.mod/doc/channelplaying.bmx | 10 + mod/brl.mod/audio.mod/doc/cuesound.bmx | 12 + mod/brl.mod/audio.mod/doc/intro.bbdoc | 14 + mod/brl.mod/audio.mod/doc/loadsound.bmx | 8 + mod/brl.mod/audio.mod/doc/playsound.bmx | 8 + mod/brl.mod/audio.mod/doc/setchanneldepth.bmx | 25 + mod/brl.mod/audio.mod/doc/setchannelpan.bmx | 24 + mod/brl.mod/audio.mod/doc/setchannelrate.bmx | 12 + .../audio.mod/doc/setchannelvolume.bmx | 12 + mod/brl.mod/audio.mod/doc/shoot.wav | Bin 0 -> 10576 bytes mod/brl.mod/audio.mod/doc/stopchannel.bmx | 14 + mod/brl.mod/audiosample.mod/audiosample.bmx | 203 + .../audiosample.mod/doc/createaudiosample.bmx | 13 + mod/brl.mod/audiosample.mod/doc/intro.bbdoc | 2 + mod/brl.mod/audiosample.mod/sample.bmx | 161 + mod/brl.mod/bank.mod/bank.bmx | 531 + mod/brl.mod/bank.mod/doc/intro.bbdoc | 12 + mod/brl.mod/bankstream.mod/bankstream.bmx | 95 + mod/brl.mod/bankstream.mod/doc/intro.bbdoc | 6 + mod/brl.mod/basic.mod/basic.bmx | 27 + mod/brl.mod/blitz.mod/blitz.bmx | 874 + mod/brl.mod/blitz.mod/blitz.c | 2 + mod/brl.mod/blitz.mod/blitz.h | 56 + mod/brl.mod/blitz.mod/blitz_app.c | 355 + mod/brl.mod/blitz.mod/blitz_app.h | 42 + mod/brl.mod/blitz.mod/blitz_array.c | 399 + mod/brl.mod/blitz.mod/blitz_array.h | 51 + mod/brl.mod/blitz.mod/blitz_bbdoc.bmx | 297 + mod/brl.mod/blitz.mod/blitz_cclib.c | 117 + mod/brl.mod/blitz.mod/blitz_cclib.h | 56 + mod/brl.mod/blitz.mod/blitz_classes.i | 72 + mod/brl.mod/blitz.mod/blitz_debug.c | 25 + mod/brl.mod/blitz.mod/blitz_debug.h | 76 + mod/brl.mod/blitz.mod/blitz_ex.c | 117 + mod/brl.mod/blitz.mod/blitz_ex.h | 30 + mod/brl.mod/blitz.mod/blitz_ex.macos.ppc.s | 64 + mod/brl.mod/blitz.mod/blitz_gc.c | 3 + mod/brl.mod/blitz.mod/blitz_gc.h | 89 + mod/brl.mod/blitz.mod/blitz_gc.macos.ppc.s | 11 + mod/brl.mod/blitz.mod/blitz_gc_ms.c | 581 + mod/brl.mod/blitz.mod/blitz_gc_rc.c | 383 + mod/brl.mod/blitz.mod/blitz_handle.c | 69 + mod/brl.mod/blitz.mod/blitz_handle.h | 21 + mod/brl.mod/blitz.mod/blitz_incbin.c | 56 + mod/brl.mod/blitz.mod/blitz_incbin.h | 19 + mod/brl.mod/blitz.mod/blitz_memory.c | 53 + mod/brl.mod/blitz.mod/blitz_memory.h | 23 + mod/brl.mod/blitz.mod/blitz_module.c | 17 + mod/brl.mod/blitz.mod/blitz_module.h | 26 + mod/brl.mod/blitz.mod/blitz_object.c | 107 + mod/brl.mod/blitz.mod/blitz_object.h | 66 + mod/brl.mod/blitz.mod/blitz_string.c | 645 + mod/brl.mod/blitz.mod/blitz_string.h | 75 + mod/brl.mod/blitz.mod/blitz_thread.c | 463 + mod/brl.mod/blitz.mod/blitz_thread.h | 129 + mod/brl.mod/blitz.mod/blitz_types.c | 48 + mod/brl.mod/blitz.mod/blitz_types.h | 50 + mod/brl.mod/blitz.mod/blitz_unicode.h | 258 + mod/brl.mod/blitz.mod/doc/abs.bmx | 7 + mod/brl.mod/blitz.mod/doc/abstract.bmx | 60 + mod/brl.mod/blitz.mod/doc/acos.bmx | 7 + mod/brl.mod/blitz.mod/doc/and.bmx | 7 + mod/brl.mod/blitz.mod/doc/appargs.bmx | 9 + mod/brl.mod/blitz.mod/doc/appdir.bmx | 8 + mod/brl.mod/blitz.mod/doc/appfile.bmx | 3 + mod/brl.mod/blitz.mod/doc/array.bmx | 13 + mod/brl.mod/blitz.mod/doc/asc.bmx | 6 + mod/brl.mod/blitz.mod/doc/asin.bmx | 7 + mod/brl.mod/blitz.mod/doc/assert.bmx | 6 + mod/brl.mod/blitz.mod/doc/atan.bmx | 7 + mod/brl.mod/blitz.mod/doc/atan2.bmx | 17 + mod/brl.mod/blitz.mod/doc/byte.bmx | 9 + mod/brl.mod/blitz.mod/doc/case.bmx | 14 + mod/brl.mod/blitz.mod/doc/catch.bmx | 13 + mod/brl.mod/blitz.mod/doc/ceil.bmx | 7 + mod/brl.mod/blitz.mod/doc/chr.bmx | 5 + mod/brl.mod/blitz.mod/doc/const.bmx | 10 + mod/brl.mod/blitz.mod/doc/continue.bmx | 8 + mod/brl.mod/blitz.mod/doc/cos.bmx | 7 + mod/brl.mod/blitz.mod/doc/default.bmx | 13 + mod/brl.mod/blitz.mod/doc/defdata.bmx | 8 + mod/brl.mod/blitz.mod/doc/delete.bmx | 3 + mod/brl.mod/blitz.mod/doc/double.bmx | 14 + mod/brl.mod/blitz.mod/doc/eachin.bmx | 9 + mod/brl.mod/blitz.mod/doc/else.bmx | 14 + mod/brl.mod/blitz.mod/doc/elseif.bmx | 14 + mod/brl.mod/blitz.mod/doc/end.bmx | 7 + mod/brl.mod/blitz.mod/doc/endextern.bmx | 9 + mod/brl.mod/blitz.mod/doc/endfunction.bmx | 12 + mod/brl.mod/blitz.mod/doc/endif.bmx | 9 + mod/brl.mod/blitz.mod/doc/endmethod.bmx | 14 + mod/brl.mod/blitz.mod/doc/endrem.bmx | 7 + mod/brl.mod/blitz.mod/doc/endselect.bmx | 16 + mod/brl.mod/blitz.mod/doc/endtry.bmx | 4 + mod/brl.mod/blitz.mod/doc/endtype.bmx | 13 + mod/brl.mod/blitz.mod/doc/exit.bmx | 9 + mod/brl.mod/blitz.mod/doc/extends.bmx | 54 + mod/brl.mod/blitz.mod/doc/extern.bmx | 11 + mod/brl.mod/blitz.mod/doc/false.bmx | 9 + mod/brl.mod/blitz.mod/doc/field.bmx | 13 + mod/brl.mod/blitz.mod/doc/final.bmx | 15 + mod/brl.mod/blitz.mod/doc/float.bmx | 17 + mod/brl.mod/blitz.mod/doc/floor.bmx | 7 + mod/brl.mod/blitz.mod/doc/for.bmx | 9 + mod/brl.mod/blitz.mod/doc/forever.bmx | 8 + mod/brl.mod/blitz.mod/doc/function.bmx | 21 + mod/brl.mod/blitz.mod/doc/gcmalloc.bmx | 0 mod/brl.mod/blitz.mod/doc/global.bmx | 12 + mod/brl.mod/blitz.mod/doc/goto.bmx | 9 + mod/brl.mod/blitz.mod/doc/if.bmx | 9 + mod/brl.mod/blitz.mod/doc/import.bmx | 15 + mod/brl.mod/blitz.mod/doc/incbin.bmx | 10 + mod/brl.mod/blitz.mod/doc/incbinlen.bmx | 12 + mod/brl.mod/blitz.mod/doc/incbinptr.bmx | 12 + mod/brl.mod/blitz.mod/doc/int.bmx | 13 + mod/brl.mod/blitz.mod/doc/intro.bbdoc | 3 + mod/brl.mod/blitz.mod/doc/launchdir.bmx | 3 + mod/brl.mod/blitz.mod/doc/len.bmx | 13 + mod/brl.mod/blitz.mod/doc/local.bmx | 13 + mod/brl.mod/blitz.mod/doc/log.bmx | 7 + mod/brl.mod/blitz.mod/doc/log10.bmx | 7 + mod/brl.mod/blitz.mod/doc/long.bmx | 9 + mod/brl.mod/blitz.mod/doc/maxim.bmx | 7 + mod/brl.mod/blitz.mod/doc/method.bmx | 15 + mod/brl.mod/blitz.mod/doc/minim.bmx | 6 + mod/brl.mod/blitz.mod/doc/mod.bmx | 7 + mod/brl.mod/blitz.mod/doc/module.bmx | 11 + mod/brl.mod/blitz.mod/doc/moduleinfo.bmx | 10 + mod/brl.mod/blitz.mod/doc/new.bmx | 27 + mod/brl.mod/blitz.mod/doc/next.bmx | 5 + mod/brl.mod/blitz.mod/doc/not.bmx | 6 + mod/brl.mod/blitz.mod/doc/null.bmx | 13 + mod/brl.mod/blitz.mod/doc/object.bmx | 13 + mod/brl.mod/blitz.mod/doc/onend.bmx | 11 + mod/brl.mod/blitz.mod/doc/or.bmx | 7 + mod/brl.mod/blitz.mod/doc/pi.bmx | 5 + mod/brl.mod/blitz.mod/doc/private.bmx | 12 + mod/brl.mod/blitz.mod/doc/protected.bmx | 4 + mod/brl.mod/blitz.mod/doc/ptr.bmx | 20 + mod/brl.mod/blitz.mod/doc/public.bmx | 11 + mod/brl.mod/blitz.mod/doc/release.bmx | 18 + mod/brl.mod/blitz.mod/doc/rem.bmx | 23 + mod/brl.mod/blitz.mod/doc/repeat.bmx | 8 + mod/brl.mod/blitz.mod/doc/restoredata.bmx | 11 + mod/brl.mod/blitz.mod/doc/return.bmx | 17 + mod/brl.mod/blitz.mod/doc/runtimeerror.bmx | 3 + mod/brl.mod/blitz.mod/doc/sar.bmx | 9 + mod/brl.mod/blitz.mod/doc/select.bmx | 18 + mod/brl.mod/blitz.mod/doc/self.bmx | 28 + mod/brl.mod/blitz.mod/doc/sgn.bmx | 7 + mod/brl.mod/blitz.mod/doc/shl.bmx | 9 + mod/brl.mod/blitz.mod/doc/short.bmx | 9 + mod/brl.mod/blitz.mod/doc/shr.bmx | 9 + mod/brl.mod/blitz.mod/doc/sin.bmx | 7 + mod/brl.mod/blitz.mod/doc/sizeof.bmx | 22 + mod/brl.mod/blitz.mod/doc/sortarray.bmx | 4 + mod/brl.mod/blitz.mod/doc/sqr.bmx | 9 + mod/brl.mod/blitz.mod/doc/step.bmx | 9 + mod/brl.mod/blitz.mod/doc/strict.bmx | 9 + mod/brl.mod/blitz.mod/doc/string.bmx | 6 + mod/brl.mod/blitz.mod/doc/stringfind.bmx | 6 + mod/brl.mod/blitz.mod/doc/super.bmx | 19 + mod/brl.mod/blitz.mod/doc/tan.bmx | 7 + mod/brl.mod/blitz.mod/doc/then.bmx | 5 + mod/brl.mod/blitz.mod/doc/throw.bmx | 13 + mod/brl.mod/blitz.mod/doc/to.bmx | 7 + mod/brl.mod/blitz.mod/doc/true.bmx | 13 + mod/brl.mod/blitz.mod/doc/try.bmx | 14 + mod/brl.mod/blitz.mod/doc/type.bmx | 17 + mod/brl.mod/blitz.mod/doc/until.bmx | 9 + mod/brl.mod/blitz.mod/doc/var.bmx | 21 + mod/brl.mod/blitz.mod/doc/varptr.bmx | 10 + mod/brl.mod/blitz.mod/doc/wend.bmx | 8 + mod/brl.mod/blitz.mod/doc/while.bmx | 13 + mod/brl.mod/bmploader.mod/bmploader.bmx | 134 + mod/brl.mod/d3d7max2d.mod/d3d7max2d.bmx | 806 + mod/brl.mod/d3d9max2d.mod/d3d9max2d.bmx | 648 + mod/brl.mod/data.mod/data.bmx | 12 + .../directsoundaudio.mod/directsoundaudio.bmx | 340 + mod/brl.mod/dxgraphics.mod/d3d7graphics.bmx | 611 + mod/brl.mod/dxgraphics.mod/d3d9graphics.bmx | 380 + mod/brl.mod/dxgraphics.mod/dxgraphics.bmx | 74 + mod/brl.mod/endianstream.mod/doc/intro.bbdoc | 21 + mod/brl.mod/endianstream.mod/endianstream.bmx | 156 + mod/brl.mod/event.mod/doc/intro.bbdoc | 39 + mod/brl.mod/event.mod/event.bmx | 254 + mod/brl.mod/event.mod/event.h | 62 + mod/brl.mod/eventqueue.mod/doc/intro.bbdoc | 8 + mod/brl.mod/eventqueue.mod/eventqueue.bmx | 216 + mod/brl.mod/filesystem.mod/doc/changedir.bmx | 11 + mod/brl.mod/filesystem.mod/doc/createdir.bmx | 4 + mod/brl.mod/filesystem.mod/doc/createfile.bmx | 4 + mod/brl.mod/filesystem.mod/doc/currentdir.bmx | 4 + mod/brl.mod/filesystem.mod/doc/deletedir.bmx | 4 + mod/brl.mod/filesystem.mod/doc/deletefile.bmx | 4 + mod/brl.mod/filesystem.mod/doc/extractdir.bmx | 3 + mod/brl.mod/filesystem.mod/doc/extractext.bmx | 3 + mod/brl.mod/filesystem.mod/doc/filemode.bmx | 19 + mod/brl.mod/filesystem.mod/doc/filesize.bmx | 5 + mod/brl.mod/filesystem.mod/doc/filetime.bmx | 3 + mod/brl.mod/filesystem.mod/doc/filetype.bmx | 5 + mod/brl.mod/filesystem.mod/doc/intro.bbdoc | 19 + mod/brl.mod/filesystem.mod/doc/loaddir.bmx | 11 + mod/brl.mod/filesystem.mod/doc/openfile.bmx | 12 + mod/brl.mod/filesystem.mod/doc/readdir.bmx | 14 + mod/brl.mod/filesystem.mod/doc/readfile.bmx | 13 + mod/brl.mod/filesystem.mod/doc/realpath.bmx | 5 + .../filesystem.mod/doc/setfilemode.bmx | 17 + mod/brl.mod/filesystem.mod/doc/stripall.bmx | 3 + mod/brl.mod/filesystem.mod/doc/stripdir.bmx | 3 + mod/brl.mod/filesystem.mod/doc/stripext.bmx | 3 + mod/brl.mod/filesystem.mod/doc/stripslash.bmx | 3 + mod/brl.mod/filesystem.mod/doc/writefile.bmx | 9 + mod/brl.mod/filesystem.mod/filesystem.bmx | 489 + mod/brl.mod/font.mod/font.bmx | 67 + .../freeaudioaudio.mod/freeaudioaudio.bmx | 211 + mod/brl.mod/freetypefont.mod/freetypefont.bmx | 218 + mod/brl.mod/glgraphics.mod/gldrawtextfont.bin | Bin 0 -> 1536 bytes mod/brl.mod/glgraphics.mod/glgraphics.bmx | 376 + mod/brl.mod/glgraphics.mod/glgraphics.linux.c | 429 + mod/brl.mod/glgraphics.mod/glgraphics.macos.m | 343 + mod/brl.mod/glgraphics.mod/glgraphics.win32.c | 434 + mod/brl.mod/glmax2d.mod/glmax2d.bmx | 538 + mod/brl.mod/glmax2d.mod/rectnode.bmx | 63 + mod/brl.mod/gnet.mod/doc/intro.bbdoc | 23 + mod/brl.mod/gnet.mod/gnet.bmx | 1000 + .../graphics.mod/doc/graphicsmodes.bmx | 8 + mod/brl.mod/graphics.mod/doc/intro.bbdoc | 60 + .../graphics.mod/doc/setgraphicsdriver.bmx | 17 + mod/brl.mod/graphics.mod/graphics.bmx | 538 + mod/brl.mod/hook.mod/doc/addhook.bmx | 26 + mod/brl.mod/hook.mod/doc/intro.bbdoc | 16 + mod/brl.mod/hook.mod/hook.bmx | 121 + mod/brl.mod/httpstream.mod/httpstream.bmx | 47 + mod/brl.mod/jpgloader.mod/jpgloader.bmx | 120 + mod/brl.mod/keycodes.mod/doc/intro.bbdoc | 129 + mod/brl.mod/keycodes.mod/keycodes.bmx | 155 + mod/brl.mod/keycodes.mod/keycodes.h | 58 + mod/brl.mod/linkedlist.mod/doc/createlist.bmx | 17 + mod/brl.mod/linkedlist.mod/doc/intro.bbdoc | 10 + mod/brl.mod/linkedlist.mod/linkedlist.bmx | 553 + mod/brl.mod/map.mod/map.bmx | 566 + mod/brl.mod/math.mod/math.bmx | 114 + mod/brl.mod/math.mod/math.c | 60 + mod/brl.mod/max2d.mod/blitz.fon | Bin 0 -> 4368 bytes mod/brl.mod/max2d.mod/blitzfont.bin | Bin 0 -> 1536 bytes mod/brl.mod/max2d.mod/convfont.bmx | 33 + mod/brl.mod/max2d.mod/doc/bullet.png | Bin 0 -> 332 bytes mod/brl.mod/max2d.mod/doc/cls.bmx | 15 + mod/brl.mod/max2d.mod/doc/collideimage.bmx | 50 + mod/brl.mod/max2d.mod/doc/createimage.bmx | 21 + mod/brl.mod/max2d.mod/doc/drawline.bmx | 19 + mod/brl.mod/max2d.mod/doc/drawoval.bmx | 18 + mod/brl.mod/max2d.mod/doc/drawpoly.bmx | 15 + mod/brl.mod/max2d.mod/doc/drawrect.bmx | 25 + mod/brl.mod/max2d.mod/doc/drawtext.bmx | 22 + mod/brl.mod/max2d.mod/doc/grabimage.bmx | 27 + mod/brl.mod/max2d.mod/doc/graphics.bmx | 11 + mod/brl.mod/max2d.mod/doc/intro.bbdoc | 79 + mod/brl.mod/max2d.mod/doc/plot.bmx | 17 + mod/brl.mod/max2d.mod/driver.bmx | 53 + mod/brl.mod/max2d.mod/image.bmx | 92 + mod/brl.mod/max2d.mod/imagefont.bmx | 156 + mod/brl.mod/max2d.mod/max2d.bmx | 1562 ++ mod/brl.mod/maxlua.mod/doc/intro.bbdoc | 50 + mod/brl.mod/maxlua.mod/lua_driver.bmx | 25 + mod/brl.mod/maxlua.mod/lua_object.c | 30 + mod/brl.mod/maxlua.mod/maxlua.bmx | 455 + mod/brl.mod/maxutil.mod/maxutil.bmx | 89 + mod/brl.mod/oggloader.mod/oggloader.bmx | 90 + mod/brl.mod/openalaudio.mod/openalaudio.bmx | 402 + mod/brl.mod/pixmap.mod/doc/intro.bbdoc | 21 + mod/brl.mod/pixmap.mod/pixel.bmx | 236 + mod/brl.mod/pixmap.mod/pixmap.bmx | 587 + mod/brl.mod/pngloader.mod/pngloader.bmx | 229 + .../polledinput.mod/doc/appterminate.bmx | 10 + mod/brl.mod/polledinput.mod/doc/intro.bbdoc | 6 + mod/brl.mod/polledinput.mod/doc/keydown.bmx | 13 + mod/brl.mod/polledinput.mod/doc/keyhit.bmx | 13 + mod/brl.mod/polledinput.mod/doc/mousedown.bmx | 11 + mod/brl.mod/polledinput.mod/doc/mousehit.bmx | 11 + mod/brl.mod/polledinput.mod/doc/mousex.bmx | 10 + mod/brl.mod/polledinput.mod/doc/mousey.bmx | 10 + mod/brl.mod/polledinput.mod/doc/mousez.bmx | 10 + mod/brl.mod/polledinput.mod/doc/movemouse.bmx | 27 + mod/brl.mod/polledinput.mod/polledinput.bmx | 352 + mod/brl.mod/ramstream.mod/ramstream.bmx | 87 + mod/brl.mod/random.mod/doc/intro.bbdoc | 14 + mod/brl.mod/random.mod/doc/rand.bmx | 14 + mod/brl.mod/random.mod/doc/rnd.bmx | 19 + mod/brl.mod/random.mod/doc/rnddouble.bmx | 25 + mod/brl.mod/random.mod/doc/rndfloat.bmx | 25 + mod/brl.mod/random.mod/doc/rndseed.bmx | 20 + mod/brl.mod/random.mod/doc/seedrnd.bmx | 20 + mod/brl.mod/random.mod/random.bmx | 102 + mod/brl.mod/reflection.mod/doc/intro.bbdoc | 77 + mod/brl.mod/reflection.mod/reflection.bmx | 831 + mod/brl.mod/reflection.mod/reflection.cpp | 81 + mod/brl.mod/retro.mod/doc/intro.bbdoc | 14 + mod/brl.mod/retro.mod/retro.bmx | 175 + mod/brl.mod/socket.mod/socket.bmx | 352 + mod/brl.mod/socketstream.mod/socketstream.bmx | 107 + mod/brl.mod/standardio.mod/doc/input.bmx | 6 + mod/brl.mod/standardio.mod/doc/intro.bbdoc | 3 + mod/brl.mod/standardio.mod/doc/print.bmx | 5 + mod/brl.mod/standardio.mod/standardio.bmx | 60 + mod/brl.mod/stream.mod/doc/intro.bbdoc | 36 + mod/brl.mod/stream.mod/doc/readstream.bmx | 13 + mod/brl.mod/stream.mod/doc/writestream.bmx | 22 + mod/brl.mod/stream.mod/stream.bmx | 1138 + mod/brl.mod/system.mod/doc/confirm.bmx | 5 + mod/brl.mod/system.mod/doc/createtimer.bmx | 14 + mod/brl.mod/system.mod/doc/currentdate.bmx | 3 + mod/brl.mod/system.mod/doc/currenttime.bmx | 3 + mod/brl.mod/system.mod/doc/delay.bmx | 11 + mod/brl.mod/system.mod/doc/intro.bbdoc | 8 + mod/brl.mod/system.mod/doc/millisecs.bmx | 9 + mod/brl.mod/system.mod/doc/notify.bmx | 3 + mod/brl.mod/system.mod/doc/proceed.bmx | 5 + mod/brl.mod/system.mod/doc/requestdir.bmx | 5 + mod/brl.mod/system.mod/doc/requestfile.bmx | 6 + mod/brl.mod/system.mod/doc/waittimer.bmx | 4 + mod/brl.mod/system.mod/driver.bmx | 22 + mod/brl.mod/system.mod/system.bmx | 312 + mod/brl.mod/system.mod/system.c | 10 + mod/brl.mod/system.mod/system.h | 61 + mod/brl.mod/system.mod/system.linux.bmx | 100 + mod/brl.mod/system.mod/system.linux.c | 398 + mod/brl.mod/system.mod/system.macos.bmx | 110 + mod/brl.mod/system.mod/system.macos.m | 664 + mod/brl.mod/system.mod/system.win32.bmx | 129 + mod/brl.mod/system.mod/system.win32.c | 515 + mod/brl.mod/textstream.mod/textstream.bmx | 398 + mod/brl.mod/tgaloader.mod/tgaloader.bmx | 219 + mod/brl.mod/threads.mod/doc/createmutex.bmx | 53 + .../threads.mod/doc/createsemaphore.bmx | 43 + mod/brl.mod/threads.mod/doc/createthread.bmx | 38 + mod/brl.mod/threads.mod/doc/intro.bbdoc | 16 + mod/brl.mod/threads.mod/threads.bmx | 559 + mod/brl.mod/threads.mod/threads.c | 152 + mod/brl.mod/timer.mod/doc/waittimer.bmx | 8 + mod/brl.mod/timer.mod/timer.bmx | 137 + mod/brl.mod/timer.mod/timer.linux.c | 83 + mod/brl.mod/timer.mod/timer.macos.m | 46 + mod/brl.mod/timer.mod/timer.win32.c | 48 + mod/brl.mod/wavloader.mod/wavloader.bmx | 92 + mod/maxgui.mod/cocoamaxgui.mod/cocoa.macos.m | 8892 +++++++ mod/maxgui.mod/cocoamaxgui.mod/cocoagui.bmx | 1026 + .../cocoamaxgui.mod/cocoamaxgui.bmx | 18 + mod/maxgui.mod/cocoamaxgui.mod/version.txt | 212 + mod/maxgui.mod/drivers.mod/drivers.bmx | 29 + mod/maxgui.mod/drivers.mod/version.txt | 9 + mod/maxgui.mod/fltkmaxgui.mod/CHANGES | 3598 +++ mod/maxgui.mod/fltkmaxgui.mod/CREDITS | 60 + .../fltkmaxgui.mod/FL/Enumerations.H | 920 + mod/maxgui.mod/fltkmaxgui.mod/FL/Fl.H | 1117 + .../fltkmaxgui.mod/FL/Fl_Adjuster.H | 82 + .../fltkmaxgui.mod/FL/Fl_BMP_Image.H | 50 + mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Bitmap.H | 85 + mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Box.H | 69 + mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Browser.H | 324 + .../fltkmaxgui.mod/FL/Fl_Browser_.H | 378 + mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Button.H | 180 + mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Cairo.H | 97 + .../fltkmaxgui.mod/FL/Fl_Cairo_Window.H | 92 + mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Chart.H | 160 + .../fltkmaxgui.mod/FL/Fl_Check_Browser.H | 122 + .../fltkmaxgui.mod/FL/Fl_Check_Button.H | 60 + mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Choice.H | 108 + mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Clock.H | 137 + .../fltkmaxgui.mod/FL/Fl_Color_Chooser.H | 199 + mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Counter.H | 124 + mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Device.H | 381 + mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Dial.H | 97 + .../fltkmaxgui.mod/FL/Fl_Double_Window.H | 81 + mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Export.H | 49 + .../fltkmaxgui.mod/FL/Fl_File_Browser.H | 120 + .../fltkmaxgui.mod/FL/Fl_File_Chooser.H | 235 + .../fltkmaxgui.mod/FL/Fl_File_Icon.H | 168 + .../fltkmaxgui.mod/FL/Fl_File_Input.H | 104 + .../fltkmaxgui.mod/FL/Fl_Fill_Dial.H | 48 + .../fltkmaxgui.mod/FL/Fl_Fill_Slider.H | 47 + .../fltkmaxgui.mod/FL/Fl_Float_Input.H | 57 + .../fltkmaxgui.mod/FL/Fl_FormsBitmap.H | 56 + .../fltkmaxgui.mod/FL/Fl_FormsPixmap.H | 63 + mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Free.H | 89 + .../fltkmaxgui.mod/FL/Fl_GIF_Image.H | 51 + .../fltkmaxgui.mod/FL/Fl_Gl_Window.H | 244 + mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Group.H | 235 + .../fltkmaxgui.mod/FL/Fl_Help_Dialog.H | 95 + .../fltkmaxgui.mod/FL/Fl_Help_View.H | 387 + .../fltkmaxgui.mod/FL/Fl_Hold_Browser.H | 61 + .../fltkmaxgui.mod/FL/Fl_Hor_Fill_Slider.H | 46 + .../fltkmaxgui.mod/FL/Fl_Hor_Nice_Slider.H | 46 + .../fltkmaxgui.mod/FL/Fl_Hor_Slider.H | 46 + .../fltkmaxgui.mod/FL/Fl_Hor_Value_Slider.H | 46 + mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Image.H | 230 + mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Input.H | 109 + mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Input_.H | 455 + .../fltkmaxgui.mod/FL/Fl_Input_Choice.H | 222 + .../fltkmaxgui.mod/FL/Fl_Int_Input.H | 55 + .../fltkmaxgui.mod/FL/Fl_JPEG_Image.H | 53 + .../fltkmaxgui.mod/FL/Fl_Light_Button.H | 59 + .../fltkmaxgui.mod/FL/Fl_Line_Dial.H | 46 + mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Menu.H | 33 + mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Menu_.H | 168 + .../fltkmaxgui.mod/FL/Fl_Menu_Bar.H | 89 + .../fltkmaxgui.mod/FL/Fl_Menu_Button.H | 72 + .../fltkmaxgui.mod/FL/Fl_Menu_Item.H | 419 + .../fltkmaxgui.mod/FL/Fl_Menu_Window.H | 68 + .../fltkmaxgui.mod/FL/Fl_Multi_Browser.H | 62 + .../fltkmaxgui.mod/FL/Fl_Multi_Label.H | 47 + .../fltkmaxgui.mod/FL/Fl_Multiline_Input.H | 65 + .../fltkmaxgui.mod/FL/Fl_Multiline_Output.H | 64 + .../FL/Fl_Native_File_Chooser.H | 51 + .../FL/Fl_Native_File_Chooser_FLTK.H | 142 + .../FL/Fl_Native_File_Chooser_MAC.H | 121 + .../FL/Fl_Native_File_Chooser_WIN32.H | 120 + .../fltkmaxgui.mod/FL/Fl_Nice_Slider.H | 46 + mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Object.H | 36 + mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Output.H | 68 + .../fltkmaxgui.mod/FL/Fl_Overlay_Window.H | 79 + .../fltkmaxgui.mod/FL/Fl_PNG_Image.H | 52 + .../fltkmaxgui.mod/FL/Fl_PNM_Image.H | 52 + mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Pack.H | 84 + .../fltkmaxgui.mod/FL/Fl_Paged_Device.H | 92 + mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Pixmap.H | 99 + mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Plugin.H | 106 + .../fltkmaxgui.mod/FL/Fl_Positioner.H | 103 + .../fltkmaxgui.mod/FL/Fl_PostScript.H | 308 + .../fltkmaxgui.mod/FL/Fl_Preferences.H | 285 + mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Printer.H | 268 + .../fltkmaxgui.mod/FL/Fl_Progress.H | 81 + .../fltkmaxgui.mod/FL/Fl_RGB_Image.H | 35 + .../fltkmaxgui.mod/FL/Fl_Radio_Button.H | 46 + .../fltkmaxgui.mod/FL/Fl_Radio_Light_Button.H | 46 + .../fltkmaxgui.mod/FL/Fl_Radio_Round_Button.H | 46 + .../fltkmaxgui.mod/FL/Fl_Repeat_Button.H | 63 + .../fltkmaxgui.mod/FL/Fl_Return_Button.H | 60 + mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Roller.H | 56 + .../fltkmaxgui.mod/FL/Fl_Round_Button.H | 57 + .../fltkmaxgui.mod/FL/Fl_Round_Clock.H | 48 + mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Scroll.H | 199 + .../fltkmaxgui.mod/FL/Fl_Scrollbar.H | 120 + .../fltkmaxgui.mod/FL/Fl_Secret_Input.H | 56 + .../fltkmaxgui.mod/FL/Fl_Select_Browser.H | 60 + .../fltkmaxgui.mod/FL/Fl_Shared_Image.H | 110 + .../fltkmaxgui.mod/FL/Fl_Simple_Counter.H | 50 + .../fltkmaxgui.mod/FL/Fl_Single_Window.H | 67 + mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Slider.H | 120 + mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Spinner.H | 266 + .../fltkmaxgui.mod/FL/Fl_Sys_Menu_Bar.H | 80 + mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Tabs.H | 86 + .../fltkmaxgui.mod/FL/Fl_Text_Buffer.H | 783 + .../fltkmaxgui.mod/FL/Fl_Text_Display.H | 481 + .../fltkmaxgui.mod/FL/Fl_Text_Editor.H | 141 + mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Tile.H | 102 + .../fltkmaxgui.mod/FL/Fl_Tiled_Image.H | 70 + mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Timer.H | 87 + .../fltkmaxgui.mod/FL/Fl_Toggle_Button.H | 60 + .../FL/Fl_Toggle_Light_Button.H | 37 + .../FL/Fl_Toggle_Round_Button.H | 37 + mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Tooltip.H | 109 + mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Tree.H | 918 + .../fltkmaxgui.mod/FL/Fl_Tree_Item.H | 337 + .../fltkmaxgui.mod/FL/Fl_Tree_Item_Array.H | 90 + .../fltkmaxgui.mod/FL/Fl_Tree_Prefs.H | 361 + .../fltkmaxgui.mod/FL/Fl_Valuator.H | 144 + .../fltkmaxgui.mod/FL/Fl_Value_Input.H | 135 + .../fltkmaxgui.mod/FL/Fl_Value_Output.H | 95 + .../fltkmaxgui.mod/FL/Fl_Value_Slider.H | 69 + mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Widget.H | 977 + mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Window.H | 461 + mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Wizard.H | 70 + .../fltkmaxgui.mod/FL/Fl_XBM_Image.H | 50 + .../fltkmaxgui.mod/FL/Fl_XPM_Image.H | 51 + mod/maxgui.mod/fltkmaxgui.mod/FL/Flmm_Tabs.H | 56 + mod/maxgui.mod/fltkmaxgui.mod/FL/Makefile.in | 63 + mod/maxgui.mod/fltkmaxgui.mod/FL/Xutf8.h | 176 + mod/maxgui.mod/fltkmaxgui.mod/FL/dirent.h | 34 + mod/maxgui.mod/fltkmaxgui.mod/FL/filename.H | 177 + mod/maxgui.mod/fltkmaxgui.mod/FL/fl_ask.H | 77 + mod/maxgui.mod/fltkmaxgui.mod/FL/fl_draw.H | 734 + mod/maxgui.mod/fltkmaxgui.mod/FL/fl_message.H | 32 + .../fltkmaxgui.mod/FL/fl_show_colormap.H | 58 + .../fltkmaxgui.mod/FL/fl_show_input.H | 32 + mod/maxgui.mod/fltkmaxgui.mod/FL/fl_types.h | 66 + mod/maxgui.mod/fltkmaxgui.mod/FL/fl_utf8.h | 259 + mod/maxgui.mod/fltkmaxgui.mod/FL/forms.H | 845 + mod/maxgui.mod/fltkmaxgui.mod/FL/gl.h | 112 + mod/maxgui.mod/fltkmaxgui.mod/FL/gl2opengl.h | 35 + mod/maxgui.mod/fltkmaxgui.mod/FL/gl_draw.H | 35 + mod/maxgui.mod/fltkmaxgui.mod/FL/glu.h | 60 + mod/maxgui.mod/fltkmaxgui.mod/FL/glut.H | 491 + mod/maxgui.mod/fltkmaxgui.mod/FL/mac.H | 198 + mod/maxgui.mod/fltkmaxgui.mod/FL/math.h | 71 + mod/maxgui.mod/fltkmaxgui.mod/FL/names.h | 123 + mod/maxgui.mod/fltkmaxgui.mod/FL/win32.H | 156 + mod/maxgui.mod/fltkmaxgui.mod/FL/x.H | 177 + mod/maxgui.mod/fltkmaxgui.mod/FLU/CHANGES | 258 + .../fltkmaxgui.mod/FLU/FluSimpleString.h | 147 + .../fltkmaxgui.mod/FLU/FluVectorClass.h | 104 + .../fltkmaxgui.mod/FLU/Flu_Button.h | 91 + .../fltkmaxgui.mod/FLU/Flu_Chat_Buffer.h | 111 + .../fltkmaxgui.mod/FLU/Flu_Choice_Group.h | 73 + .../FLU/Flu_Collapsable_Group.h | 196 + .../fltkmaxgui.mod/FLU/Flu_Combo_Box.h | 118 + .../fltkmaxgui.mod/FLU/Flu_Combo_List.h | 51 + .../fltkmaxgui.mod/FLU/Flu_Combo_Tree.h | 50 + mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_DND.h | 206 + .../FLU/Flu_Dual_Progress_Meter.h | 143 + .../fltkmaxgui.mod/FLU/Flu_Dual_Slider.h | 99 + .../fltkmaxgui.mod/FLU/Flu_Enumerations.h | 71 + .../fltkmaxgui.mod/FLU/Flu_File_Chooser.h | 616 + .../fltkmaxgui.mod/FLU/Flu_Float_Input.h | 58 + .../fltkmaxgui.mod/FLU/Flu_GL_Canvas.h | 105 + .../fltkmaxgui.mod/FLU/Flu_GL_Window.h | 179 + .../fltkmaxgui.mod/FLU/Flu_Helpers.h | 79 + .../fltkmaxgui.mod/FLU/Flu_Int_Input.h | 58 + mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Label.h | 72 + .../fltkmaxgui.mod/FLU/Flu_Link_Button.h | 42 + .../fltkmaxgui.mod/FLU/Flu_Output.h | 52 + .../fltkmaxgui.mod/FLU/Flu_Progress.h | 50 + .../fltkmaxgui.mod/FLU/Flu_Progress_Meter.h | 151 + .../fltkmaxgui.mod/FLU/Flu_Return_Button.h | 34 + .../fltkmaxgui.mod/FLU/Flu_Separator.h | 55 + .../fltkmaxgui.mod/FLU/Flu_Simple_Group.h | 40 + .../fltkmaxgui.mod/FLU/Flu_Spinner.h | 164 + .../fltkmaxgui.mod/FLU/Flu_Toggle_Group.h | 72 + .../fltkmaxgui.mod/FLU/Flu_Tree_Browser.h | 1237 + .../fltkmaxgui.mod/FLU/Flu_Wrap_Group.h | 195 + mod/maxgui.mod/fltkmaxgui.mod/FLU/LICENSE | 569 + mod/maxgui.mod/fltkmaxgui.mod/FLU/Makefile | 17 + mod/maxgui.mod/fltkmaxgui.mod/FLU/README | 13 + .../fltkmaxgui.mod/FLU/flu_export.h | 27 + .../FLU/flu_file_chooser_pixmaps.h | 35 + .../fltkmaxgui.mod/FLU/flu_pixmaps.h | 54 + .../FLU_src/FluSimpleString.cpp | 146 + .../fltkmaxgui.mod/FLU_src/Flu_Button.cpp | 196 + .../FLU_src/Flu_Chat_Buffer.cpp | 320 + .../FLU_src/Flu_Choice_Group.cpp | 142 + .../FLU_src/Flu_Collapsable_Group.cpp | 179 + .../fltkmaxgui.mod/FLU_src/Flu_Combo_Box.cpp | 295 + .../fltkmaxgui.mod/FLU_src/Flu_Combo_List.cpp | 93 + .../fltkmaxgui.mod/FLU_src/Flu_Combo_Tree.cpp | 100 + .../fltkmaxgui.mod/FLU_src/Flu_DND.cpp | 264 + .../FLU_src/Flu_Dual_Progress_Meter.cpp | 96 + .../FLU_src/Flu_Dual_Slider.cpp | 338 + .../FLU_src/Flu_File_Chooser.cpp | 4261 ++++ .../FLU_src/Flu_Float_Input.cpp | 26 + .../fltkmaxgui.mod/FLU_src/Flu_GL_Canvas.cpp | 36 + .../fltkmaxgui.mod/FLU_src/Flu_GL_Window.cpp | 197 + .../fltkmaxgui.mod/FLU_src/Flu_Helpers.cpp | 177 + .../fltkmaxgui.mod/FLU_src/Flu_Int_Input.cpp | 26 + .../fltkmaxgui.mod/FLU_src/Flu_Label.cpp | 65 + .../FLU_src/Flu_Link_Button.cpp | 29 + .../fltkmaxgui.mod/FLU_src/Flu_Output.cpp | 26 + .../fltkmaxgui.mod/FLU_src/Flu_Progress.cpp | 94 + .../FLU_src/Flu_Progress_Meter.cpp | 137 + .../FLU_src/Flu_Return_Button.cpp | 26 + .../fltkmaxgui.mod/FLU_src/Flu_Separator.cpp | 31 + .../FLU_src/Flu_Simple_Group.cpp | 64 + .../fltkmaxgui.mod/FLU_src/Flu_Spinner.cpp | 416 + .../FLU_src/Flu_Toggle_Group.cpp | 97 + .../FLU_src/Flu_Tree_Browser.cpp | 3698 +++ .../fltkmaxgui.mod/FLU_src/Flu_Wrap_Group.cpp | 412 + .../FLU_src/flu_file_chooser_pixmaps.cpp | 2470 ++ .../fltkmaxgui.mod/FLU_src/flu_pixmaps.cpp | 1629 ++ .../fltkmaxgui.mod/FLU_src/linux_path_info.c | 218 + mod/maxgui.mod/fltkmaxgui.mod/Flmm/COPYING | 528 + mod/maxgui.mod/fltkmaxgui.mod/Flmm/CREDITS | 12 + mod/maxgui.mod/fltkmaxgui.mod/Flmm/readme.txt | 34 + mod/maxgui.mod/fltkmaxgui.mod/README | 189 + mod/maxgui.mod/fltkmaxgui.mod/cocoa_bridge.mm | 23 + mod/maxgui.mod/fltkmaxgui.mod/config.h | 351 + mod/maxgui.mod/fltkmaxgui.mod/doc/intro.bbdoc | 22 + mod/maxgui.mod/fltkmaxgui.mod/fltkdecls.bmx | 541 + mod/maxgui.mod/fltkmaxgui.mod/fltkfonts.bmx | 382 + mod/maxgui.mod/fltkmaxgui.mod/fltkglue.cpp | 2056 ++ mod/maxgui.mod/fltkmaxgui.mod/fltkgui.bmx | 3152 +++ mod/maxgui.mod/fltkmaxgui.mod/fltkimports.bmx | 240 + mod/maxgui.mod/fltkmaxgui.mod/fltkmaxgui.bmx | 23 + mod/maxgui.mod/fltkmaxgui.mod/fltksystem.bmx | 97 + .../fltkmaxgui.mod/maxgui_templates.h | 174 + .../fltkmaxgui.mod/src/CMakeLists.txt | 447 + mod/maxgui.mod/fltkmaxgui.mod/src/Fl.cxx | 1806 ++ .../fltkmaxgui.mod/src/Fl_Adjuster.cxx | 182 + .../fltkmaxgui.mod/src/Fl_BMP_Image.cxx | 495 + .../fltkmaxgui.mod/src/Fl_Bitmap.cxx | 482 + mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Box.cxx | 44 + .../fltkmaxgui.mod/src/Fl_Browser.cxx | 919 + .../fltkmaxgui.mod/src/Fl_Browser_.cxx | 1107 + .../fltkmaxgui.mod/src/Fl_Browser_load.cxx | 70 + .../fltkmaxgui.mod/src/Fl_Button.cxx | 218 + .../fltkmaxgui.mod/src/Fl_Chart.cxx | 436 + .../fltkmaxgui.mod/src/Fl_Check_Browser.cxx | 326 + .../fltkmaxgui.mod/src/Fl_Check_Button.cxx | 47 + .../fltkmaxgui.mod/src/Fl_Choice.cxx | 213 + .../fltkmaxgui.mod/src/Fl_Clock.cxx | 218 + .../fltkmaxgui.mod/src/Fl_Color_Chooser.cxx | 630 + .../fltkmaxgui.mod/src/Fl_Counter.cxx | 211 + .../fltkmaxgui.mod/src/Fl_Device.cxx | 56 + mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Dial.cxx | 166 + .../fltkmaxgui.mod/src/Fl_Double_Window.cxx | 461 + .../fltkmaxgui.mod/src/Fl_File_Browser.cxx | 643 + .../fltkmaxgui.mod/src/Fl_File_Chooser.cxx | 473 + .../fltkmaxgui.mod/src/Fl_File_Chooser.fl | 474 + .../fltkmaxgui.mod/src/Fl_File_Chooser2.cxx | 1655 ++ .../fltkmaxgui.mod/src/Fl_File_Icon.cxx | 492 + .../fltkmaxgui.mod/src/Fl_File_Icon2.cxx | 1022 + .../fltkmaxgui.mod/src/Fl_File_Input.cxx | 297 + mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Font.H | 119 + .../fltkmaxgui.mod/src/Fl_GDI_Printer.cxx | 286 + .../fltkmaxgui.mod/src/Fl_GIF_Image.cxx | 390 + .../fltkmaxgui.mod/src/Fl_Gl_Choice.H | 124 + .../fltkmaxgui.mod/src/Fl_Gl_Choice.cxx | 416 + .../src/Fl_Gl_Device_Plugin.cxx | 153 + .../fltkmaxgui.mod/src/Fl_Gl_Overlay.cxx | 248 + .../fltkmaxgui.mod/src/Fl_Gl_Window.cxx | 549 + .../fltkmaxgui.mod/src/Fl_Group.cxx | 836 + .../fltkmaxgui.mod/src/Fl_Help_Dialog.cxx | 301 + .../fltkmaxgui.mod/src/Fl_Help_Dialog.fl | 265 + .../fltkmaxgui.mod/src/Fl_Help_Dialog_Dox.cxx | 120 + .../fltkmaxgui.mod/src/Fl_Help_View.cxx | 6306 +++++ .../fltkmaxgui.mod/src/Fl_Image.cxx | 590 + .../fltkmaxgui.mod/src/Fl_Input.cxx | 663 + .../fltkmaxgui.mod/src/Fl_Input_.cxx | 1258 + .../fltkmaxgui.mod/src/Fl_JPEG_Image.cxx | 370 + .../fltkmaxgui.mod/src/Fl_Light_Button.cxx | 174 + mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Menu.cxx | 1048 + .../fltkmaxgui.mod/src/Fl_Menu_.cxx | 435 + .../fltkmaxgui.mod/src/Fl_Menu_Bar.cxx | 78 + .../fltkmaxgui.mod/src/Fl_Menu_Button.cxx | 122 + .../fltkmaxgui.mod/src/Fl_Menu_Window.cxx | 110 + .../fltkmaxgui.mod/src/Fl_Menu_add.cxx | 494 + .../fltkmaxgui.mod/src/Fl_Menu_global.cxx | 60 + .../fltkmaxgui.mod/src/Fl_Multi_Label.cxx | 80 + .../src/Fl_Native_File_Chooser.cxx | 45 + .../src/Fl_Native_File_Chooser_FLTK.cxx | 504 + .../src/Fl_Native_File_Chooser_MAC.cxx | 584 + .../src/Fl_Native_File_Chooser_WIN32.cxx | 854 + .../src/Fl_Native_File_Chooser_common.cxx | 83 + .../fltkmaxgui.mod/src/Fl_Overlay_Window.cxx | 176 + .../fltkmaxgui.mod/src/Fl_PNG_Image.cxx | 160 + .../fltkmaxgui.mod/src/Fl_PNM_Image.cxx | 197 + mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Pack.cxx | 157 + .../fltkmaxgui.mod/src/Fl_Paged_Device.cxx | 292 + .../fltkmaxgui.mod/src/Fl_Pixmap.cxx | 563 + .../fltkmaxgui.mod/src/Fl_Positioner.cxx | 161 + .../fltkmaxgui.mod/src/Fl_PostScript.cxx | 1563 ++ .../fltkmaxgui.mod/src/Fl_Preferences.cxx | 1974 ++ .../fltkmaxgui.mod/src/Fl_Printer.cxx | 95 + .../fltkmaxgui.mod/src/Fl_Progress.cxx | 123 + .../fltkmaxgui.mod/src/Fl_Quartz_Printer.mm | 302 + .../fltkmaxgui.mod/src/Fl_Repeat_Button.cxx | 70 + .../fltkmaxgui.mod/src/Fl_Return_Button.cxx | 73 + .../fltkmaxgui.mod/src/Fl_Roller.cxx | 185 + .../fltkmaxgui.mod/src/Fl_Round_Button.cxx | 48 + .../fltkmaxgui.mod/src/Fl_Scroll.cxx | 420 + .../fltkmaxgui.mod/src/Fl_Scrollbar.cxx | 292 + .../fltkmaxgui.mod/src/Fl_Shared_Image.cxx | 463 + .../fltkmaxgui.mod/src/Fl_Single_Window.cxx | 41 + .../fltkmaxgui.mod/src/Fl_Slider.cxx | 369 + .../fltkmaxgui.mod/src/Fl_Sys_Menu_Bar.cxx | 288 + mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Tabs.cxx | 446 + .../fltkmaxgui.mod/src/Fl_Text_Buffer.cxx | 1637 ++ .../fltkmaxgui.mod/src/Fl_Text_Display.cxx | 3771 +++ .../fltkmaxgui.mod/src/Fl_Text_Editor.cxx | 637 + mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Tile.cxx | 214 + .../fltkmaxgui.mod/src/Fl_Tiled_Image.cxx | 135 + .../fltkmaxgui.mod/src/Fl_Tooltip.cxx | 282 + mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Tree.cxx | 919 + .../fltkmaxgui.mod/src/Fl_Tree_Item.cxx | 929 + .../fltkmaxgui.mod/src/Fl_Tree_Item_Array.cxx | 157 + .../fltkmaxgui.mod/src/Fl_Tree_Prefs.cxx | 170 + .../fltkmaxgui.mod/src/Fl_Valuator.cxx | 196 + .../fltkmaxgui.mod/src/Fl_Value_Input.cxx | 149 + .../fltkmaxgui.mod/src/Fl_Value_Output.cxx | 108 + .../fltkmaxgui.mod/src/Fl_Value_Slider.cxx | 86 + .../fltkmaxgui.mod/src/Fl_Widget.cxx | 344 + .../fltkmaxgui.mod/src/Fl_Window.cxx | 283 + .../src/Fl_Window_fullscreen.cxx | 95 + .../fltkmaxgui.mod/src/Fl_Window_hotspot.cxx | 100 + .../fltkmaxgui.mod/src/Fl_Window_iconize.cxx | 49 + .../fltkmaxgui.mod/src/Fl_Wizard.cxx | 195 + .../fltkmaxgui.mod/src/Fl_XBM_Image.cxx | 112 + mod/maxgui.mod/fltkmaxgui.mod/src/Fl_XColor.H | 46 + .../fltkmaxgui.mod/src/Fl_XPM_Image.cxx | 136 + .../fltkmaxgui.mod/src/Fl_abort.cxx | 102 + .../fltkmaxgui.mod/src/Fl_add_idle.cxx | 123 + mod/maxgui.mod/fltkmaxgui.mod/src/Fl_arg.cxx | 550 + mod/maxgui.mod/fltkmaxgui.mod/src/Fl_cocoa.mm | 3281 +++ .../fltkmaxgui.mod/src/Fl_compose.cxx | 82 + .../fltkmaxgui.mod/src/Fl_display.cxx | 60 + .../fltkmaxgui.mod/src/Fl_get_key.cxx | 69 + .../fltkmaxgui.mod/src/Fl_get_key_mac.cxx | 118 + .../fltkmaxgui.mod/src/Fl_get_key_win32.cxx | 138 + .../src/Fl_get_system_colors.cxx | 426 + mod/maxgui.mod/fltkmaxgui.mod/src/Fl_grab.cxx | 105 + mod/maxgui.mod/fltkmaxgui.mod/src/Fl_lock.cxx | 403 + mod/maxgui.mod/fltkmaxgui.mod/src/Fl_mac.cxx | 2870 +++ .../fltkmaxgui.mod/src/Fl_own_colormap.cxx | 90 + .../fltkmaxgui.mod/src/Fl_visual.cxx | 155 + .../fltkmaxgui.mod/src/Fl_win32.cxx | 1981 ++ mod/maxgui.mod/fltkmaxgui.mod/src/Fl_x.cxx | 1870 ++ .../fltkmaxgui.mod/src/Flmm_Tabs.cxx | 390 + mod/maxgui.mod/fltkmaxgui.mod/src/Makefile | 801 + mod/maxgui.mod/fltkmaxgui.mod/src/aimm.h | 431 + .../fltkmaxgui.mod/src/allfiles.xbm | 6 + mod/maxgui.mod/fltkmaxgui.mod/src/cgdebug.h | 215 + mod/maxgui.mod/fltkmaxgui.mod/src/cmap.cxx | 181 + mod/maxgui.mod/fltkmaxgui.mod/src/d1.xbm | 6 + mod/maxgui.mod/fltkmaxgui.mod/src/d1_mask.xbm | 6 + .../fltkmaxgui.mod/src/dump_compose.c | 26 + mod/maxgui.mod/fltkmaxgui.mod/src/ew.xbm | 8 + mod/maxgui.mod/fltkmaxgui.mod/src/ew_mask.xbm | 8 + mod/maxgui.mod/fltkmaxgui.mod/src/fastarrow.h | 6 + .../fltkmaxgui.mod/src/filename_absolute.cxx | 237 + .../fltkmaxgui.mod/src/filename_expand.cxx | 134 + .../fltkmaxgui.mod/src/filename_ext.cxx | 58 + .../fltkmaxgui.mod/src/filename_isdir.cxx | 103 + .../fltkmaxgui.mod/src/filename_list.cxx | 136 + .../fltkmaxgui.mod/src/filename_match.cxx | 128 + .../fltkmaxgui.mod/src/filename_setext.cxx | 60 + mod/maxgui.mod/fltkmaxgui.mod/src/fl_arc.cxx | 91 + mod/maxgui.mod/fltkmaxgui.mod/src/fl_arci.cxx | 131 + mod/maxgui.mod/fltkmaxgui.mod/src/fl_ask.cxx | 496 + .../fltkmaxgui.mod/src/fl_boxtype.cxx | 429 + .../fltkmaxgui.mod/src/fl_call_main.c | 143 + mod/maxgui.mod/fltkmaxgui.mod/src/fl_cmap.h | 256 + .../fltkmaxgui.mod/src/fl_color.cxx | 474 + .../fltkmaxgui.mod/src/fl_color_mac.cxx | 94 + .../fltkmaxgui.mod/src/fl_color_win32.cxx | 254 + .../fltkmaxgui.mod/src/fl_cursor.cxx | 337 + .../fltkmaxgui.mod/src/fl_curve.cxx | 110 + .../fltkmaxgui.mod/src/fl_diamond_box.cxx | 80 + mod/maxgui.mod/fltkmaxgui.mod/src/fl_dnd.cxx | 38 + .../fltkmaxgui.mod/src/fl_dnd_mac.cxx | 54 + .../fltkmaxgui.mod/src/fl_dnd_win32.cxx | 522 + .../fltkmaxgui.mod/src/fl_dnd_x.cxx | 201 + mod/maxgui.mod/fltkmaxgui.mod/src/fl_draw.cxx | 487 + .../fltkmaxgui.mod/src/fl_draw_image.cxx | 576 + .../fltkmaxgui.mod/src/fl_draw_image_mac.cxx | 173 + .../src/fl_draw_image_win32.cxx | 341 + .../fltkmaxgui.mod/src/fl_draw_pixmap.cxx | 429 + .../fltkmaxgui.mod/src/fl_encoding_latin1.cxx | 137 + .../src/fl_encoding_mac_roman.cxx | 134 + .../fltkmaxgui.mod/src/fl_engraved_label.cxx | 93 + .../fltkmaxgui.mod/src/fl_file_dir.cxx | 194 + mod/maxgui.mod/fltkmaxgui.mod/src/fl_font.cxx | 91 + .../fltkmaxgui.mod/src/fl_font_mac.cxx | 498 + .../fltkmaxgui.mod/src/fl_font_win32.cxx | 421 + .../fltkmaxgui.mod/src/fl_font_x.cxx | 348 + .../fltkmaxgui.mod/src/fl_font_xft.cxx | 678 + mod/maxgui.mod/fltkmaxgui.mod/src/fl_gtk.cxx | 304 + .../fltkmaxgui.mod/src/fl_images_core.cxx | 106 + .../fltkmaxgui.mod/src/fl_labeltype.cxx | 144 + .../fltkmaxgui.mod/src/fl_line_style.cxx | 174 + .../fltkmaxgui.mod/src/fl_open_uri.cxx | 380 + .../fltkmaxgui.mod/src/fl_oval_box.cxx | 66 + .../fltkmaxgui.mod/src/fl_overlay.cxx | 129 + .../fltkmaxgui.mod/src/fl_overlay_visual.cxx | 105 + .../fltkmaxgui.mod/src/fl_plastic.cxx | 381 + .../fltkmaxgui.mod/src/fl_read_image.cxx | 503 + .../fltkmaxgui.mod/src/fl_read_image_mac.cxx | 83 + .../src/fl_read_image_win32.cxx | 72 + mod/maxgui.mod/fltkmaxgui.mod/src/fl_rect.cxx | 727 + .../fltkmaxgui.mod/src/fl_round_box.cxx | 122 + .../fltkmaxgui.mod/src/fl_rounded_box.cxx | 99 + .../fltkmaxgui.mod/src/fl_scroll_area.cxx | 170 + .../fltkmaxgui.mod/src/fl_set_font.cxx | 97 + .../fltkmaxgui.mod/src/fl_set_fonts.cxx | 46 + .../fltkmaxgui.mod/src/fl_set_fonts_mac.cxx | 152 + .../fltkmaxgui.mod/src/fl_set_fonts_win32.cxx | 173 + .../fltkmaxgui.mod/src/fl_set_fonts_x.cxx | 350 + .../fltkmaxgui.mod/src/fl_set_fonts_xft.cxx | 384 + .../fltkmaxgui.mod/src/fl_shadow_box.cxx | 56 + .../fltkmaxgui.mod/src/fl_shortcut.cxx | 375 + .../fltkmaxgui.mod/src/fl_show_colormap.cxx | 162 + .../fltkmaxgui.mod/src/fl_symbols.cxx | 714 + mod/maxgui.mod/fltkmaxgui.mod/src/fl_utf.c | 909 + mod/maxgui.mod/fltkmaxgui.mod/src/fl_utf8.cxx | 827 + .../fltkmaxgui.mod/src/fl_vertex.cxx | 372 + mod/maxgui.mod/fltkmaxgui.mod/src/flstring.c | 105 + mod/maxgui.mod/fltkmaxgui.mod/src/flstring.h | 104 + .../fltkmaxgui.mod/src/forms_bitmap.cxx | 53 + .../src/forms_compatability.cxx | 213 + .../fltkmaxgui.mod/src/forms_free.cxx | 114 + .../fltkmaxgui.mod/src/forms_fselect.cxx | 67 + .../fltkmaxgui.mod/src/forms_pixmap.cxx | 63 + .../fltkmaxgui.mod/src/forms_timer.cxx | 186 + .../fltkmaxgui.mod/src/freeglut_geometry.cxx | 1110 + .../src/freeglut_stroke_mono_roman.cxx | 2848 +++ .../src/freeglut_stroke_roman.cxx | 2848 +++ .../fltkmaxgui.mod/src/freeglut_teapot.cxx | 164 + .../fltkmaxgui.mod/src/freeglut_teapot_data.h | 145 + mod/maxgui.mod/fltkmaxgui.mod/src/gl_draw.cxx | 567 + .../fltkmaxgui.mod/src/gl_start.cxx | 134 + .../fltkmaxgui.mod/src/glut_compatability.cxx | 522 + .../fltkmaxgui.mod/src/glut_font.cxx | 198 + mod/maxgui.mod/fltkmaxgui.mod/src/makedepend | 1120 + .../fltkmaxgui.mod/src/makefile.wat | 238 + .../fltkmaxgui.mod/src/mediumarrow.h | 6 + mod/maxgui.mod/fltkmaxgui.mod/src/new.xbm | 6 + mod/maxgui.mod/fltkmaxgui.mod/src/ns.xbm | 8 + mod/maxgui.mod/fltkmaxgui.mod/src/ns_mask.xbm | 8 + .../fltkmaxgui.mod/src/numericsort.c | 111 + .../fltkmaxgui.mod/src/print_panel.cxx | 597 + .../fltkmaxgui.mod/src/print_panel.h | 55 + .../fltkmaxgui.mod/src/ps_image.cxx | 550 + mod/maxgui.mod/fltkmaxgui.mod/src/scandir.c | 125 + .../fltkmaxgui.mod/src/scandir_win32.c | 135 + .../fltkmaxgui.mod/src/screen_xywh.cxx | 258 + mod/maxgui.mod/fltkmaxgui.mod/src/slowarrow.h | 6 + mod/maxgui.mod/fltkmaxgui.mod/src/tile.xpm | 91 + mod/maxgui.mod/fltkmaxgui.mod/src/up.xbm | 6 + mod/maxgui.mod/fltkmaxgui.mod/src/vsnprintf.c | 281 + .../fltkmaxgui.mod/src/xutf8/COPYING | 50 + .../fltkmaxgui.mod/src/xutf8/Makefile | 132 + .../fltkmaxgui.mod/src/xutf8/README | 67 + .../fltkmaxgui.mod/src/xutf8/Ximint.h | 0 .../fltkmaxgui.mod/src/xutf8/Xlibint.h | 0 .../fltkmaxgui.mod/src/xutf8/case.c | 126 + .../fltkmaxgui.mod/src/xutf8/headers/case.h | 1770 ++ .../src/xutf8/headers/case_tbl.txt | 8 + .../src/xutf8/headers/dingbats_.h | 565 + .../src/xutf8/headers/spacing.h | 1978 ++ .../src/xutf8/headers/spacing_tbl.txt | 10 + .../src/xutf8/headers/symbol_.h | 1126 + .../fltkmaxgui.mod/src/xutf8/headers/tbl.txt | 122 + .../fltkmaxgui.mod/src/xutf8/imKStoUCS.c | 324 + .../fltkmaxgui.mod/src/xutf8/is_right2left.c | 84 + .../fltkmaxgui.mod/src/xutf8/is_spacing.c | 90 + .../fltkmaxgui.mod/src/xutf8/keysym2Ucs.c | 41 + .../src/xutf8/lcUniConv/8bit_tab_to_h.c | 536 + .../src/xutf8/lcUniConv/COPYRIGHT | 39 + .../fltkmaxgui.mod/src/xutf8/lcUniConv/README | 12 + .../src/xutf8/lcUniConv/armscii_8.h | 98 + .../src/xutf8/lcUniConv/ascii.h | 26 + .../fltkmaxgui.mod/src/xutf8/lcUniConv/big5.h | 4142 +++ .../src/xutf8/lcUniConv/big5_emacs.h | 164 + .../src/xutf8/lcUniConv/cjk_tab_to_h.c | 1025 + .../src/xutf8/lcUniConv/cp1133.h | 92 + .../src/xutf8/lcUniConv/cp1251.h | 113 + .../src/xutf8/lcUniConv/cp1255.h | 121 + .../src/xutf8/lcUniConv/cp1256.h | 135 + .../src/xutf8/lcUniConv/cp936ext.h | 6250 +++++ .../src/xutf8/lcUniConv/gb2312.h | 2553 ++ .../src/xutf8/lcUniConv/gbk_tab_to_h.c | 1020 + .../src/xutf8/lcUniConv/georgian_academy.h | 88 + .../src/xutf8/lcUniConv/georgian_ps.h | 105 + .../src/xutf8/lcUniConv/iso8859_1.h | 23 + .../src/xutf8/lcUniConv/iso8859_10.h | 88 + .../src/xutf8/lcUniConv/iso8859_11.h | 78 + .../src/xutf8/lcUniConv/iso8859_13.h | 91 + .../src/xutf8/lcUniConv/iso8859_14.h | 109 + .../src/xutf8/lcUniConv/iso8859_15.h | 63 + .../src/xutf8/lcUniConv/iso8859_16.h | 98 + .../src/xutf8/lcUniConv/iso8859_2.h | 94 + .../src/xutf8/lcUniConv/iso8859_3.h | 100 + .../src/xutf8/lcUniConv/iso8859_4.h | 94 + .../src/xutf8/lcUniConv/iso8859_5.h | 77 + .../src/xutf8/lcUniConv/iso8859_6.h | 80 + .../src/xutf8/lcUniConv/iso8859_7.h | 88 + .../src/xutf8/lcUniConv/iso8859_8.h | 89 + .../src/xutf8/lcUniConv/iso8859_9.h | 67 + .../src/xutf8/lcUniConv/iso8859_9e.h | 103 + .../src/xutf8/lcUniConv/jisx0201.h | 48 + .../src/xutf8/lcUniConv/jisx0208.h | 2397 ++ .../src/xutf8/lcUniConv/jisx0212.h | 2164 ++ .../src/xutf8/lcUniConv/koi8_c.h | 103 + .../src/xutf8/lcUniConv/koi8_r.h | 135 + .../src/xutf8/lcUniConv/koi8_u.h | 143 + .../src/xutf8/lcUniConv/ksc5601.h | 3003 +++ .../src/xutf8/lcUniConv/mulelao.h | 78 + .../src/xutf8/lcUniConv/tatar_cyr.h | 123 + .../fltkmaxgui.mod/src/xutf8/lcUniConv/tcvn.h | 134 + .../src/xutf8/lcUniConv/tis620.h | 78 + .../src/xutf8/lcUniConv/ucs2be.h | 32 + .../fltkmaxgui.mod/src/xutf8/lcUniConv/utf8.h | 110 + .../src/xutf8/lcUniConv/viscii.h | 123 + .../fltkmaxgui.mod/src/xutf8/makedepend | 27 + .../fltkmaxgui.mod/src/xutf8/mk_wcwidth.c | 353 + .../fltkmaxgui.mod/src/xutf8/stamp-h | 1 + .../fltkmaxgui.mod/src/xutf8/stamp-h.in | 1 + .../fltkmaxgui.mod/src/xutf8/test.c | 292 + .../fltkmaxgui.mod/src/xutf8/test2.c | 223 + .../fltkmaxgui.mod/src/xutf8/ucs2fontmap.c | 380 + .../src/xutf8/ucs2fontmap.c.mini | 46 + .../fltkmaxgui.mod/src/xutf8/utf8Input.c | 457 + .../fltkmaxgui.mod/src/xutf8/utf8Utils.c | 238 + .../fltkmaxgui.mod/src/xutf8/utf8Wrap.c | 902 + .../fltkmaxgui.mod/src/xutf8/utils/INSTALL | 26 + .../fltkmaxgui.mod/src/xutf8/utils/Makefile | 22 + .../fltkmaxgui.mod/src/xutf8/utils/README | 14 + .../fltkmaxgui.mod/src/xutf8/utils/case.sh | 105 + .../fltkmaxgui.mod/src/xutf8/utils/conv_gen.c | 174 + .../src/xutf8/utils/convert_map.c | 179 + .../src/xutf8/utils/create_table.c | 112 + .../fltkmaxgui.mod/src/xutf8/utils/euc_tw.c | 67 + .../src/xutf8/utils/non_spacing.sh | 101 + .../fltkmaxgui.mod/src/xutf8/utils/tbl_gen.sh | 179 + mod/maxgui.mod/fltkmaxgui.mod/version.txt | 240 + .../localization.mod/doc/createlanguage.bmx | 47 + .../localization.mod/doc/intro.bbdoc | 10 + mod/maxgui.mod/localization.mod/language.bmx | 377 + .../localization.mod/localization.bmx | 420 + mod/maxgui.mod/localization.mod/version.txt | 8 + .../maxgui.mod/doc/canvasbeginpaint.bmx | 36 + .../maxgui.mod/doc/createbutton.bmx | 38 + .../maxgui.mod/doc/createcanvas.bmx | 50 + .../maxgui.mod/doc/createcombobox.bmx | 51 + .../maxgui.mod/doc/createhtmlview.bmx | 23 + mod/maxgui.mod/maxgui.mod/doc/createlabel.bmx | 17 + .../maxgui.mod/doc/createlistbox.bmx | 37 + mod/maxgui.mod/maxgui.mod/doc/createmenu.bmx | 58 + mod/maxgui.mod/maxgui.mod/doc/createpanel.bmx | 34 + .../maxgui.mod/doc/createprogbar.bmx | 24 + .../maxgui.mod/doc/createslider.bmx | 42 + .../maxgui.mod/doc/createtabber.bmx | 65 + .../maxgui.mod/doc/createtextarea.bmx | 29 + .../maxgui.mod/doc/createtextfield.bmx | 35 + mod/maxgui.mod/maxgui.mod/doc/createtimer.bmx | 23 + .../maxgui.mod/doc/createtoolbar.bmx | 36 + .../maxgui.mod/doc/createtreeview.bmx | 30 + .../maxgui.mod/doc/createwindow.bmx | 36 + mod/maxgui.mod/maxgui.mod/doc/fltkbuttons.png | Bin 0 -> 1783 bytes .../maxgui.mod/doc/fltkcombobox.png | Bin 0 -> 638 bytes mod/maxgui.mod/maxgui.mod/doc/fltklistbox.png | Bin 0 -> 1104 bytes mod/maxgui.mod/maxgui.mod/doc/fltkmenu.png | Bin 0 -> 3143 bytes mod/maxgui.mod/maxgui.mod/doc/fltkpanels.png | Bin 0 -> 535 bytes mod/maxgui.mod/maxgui.mod/doc/fltkprogbar.png | Bin 0 -> 347 bytes mod/maxgui.mod/maxgui.mod/doc/fltksliders.png | Bin 0 -> 1548 bytes mod/maxgui.mod/maxgui.mod/doc/fltktabber.png | Bin 0 -> 1005 bytes .../maxgui.mod/doc/fltktextarea.png | Bin 0 -> 2291 bytes .../maxgui.mod/doc/fltktextfield.png | Bin 0 -> 540 bytes .../maxgui.mod/doc/fltktreeview.png | Bin 0 -> 1456 bytes mod/maxgui.mod/maxgui.mod/doc/fltkwindow.png | Bin 0 -> 6458 bytes mod/maxgui.mod/maxgui.mod/doc/gadgetclass.bmx | 37 + mod/maxgui.mod/maxgui.mod/doc/intro.bbdoc | 207 + .../maxgui.mod/doc/lookupguicolor.bmx | 38 + .../maxgui.mod/doc/lookupguifont.bmx | 50 + mod/maxgui.mod/maxgui.mod/doc/osxbuttons.png | Bin 0 -> 8820 bytes mod/maxgui.mod/maxgui.mod/doc/osxcombobox.png | Bin 0 -> 4509 bytes mod/maxgui.mod/maxgui.mod/doc/osxlistbox.png | Bin 0 -> 3151 bytes mod/maxgui.mod/maxgui.mod/doc/osxmenu.png | Bin 0 -> 16672 bytes mod/maxgui.mod/maxgui.mod/doc/osxpanels.png | Bin 0 -> 458 bytes mod/maxgui.mod/maxgui.mod/doc/osxprogbar.png | Bin 0 -> 1135 bytes mod/maxgui.mod/maxgui.mod/doc/osxsliders.png | Bin 0 -> 10237 bytes mod/maxgui.mod/maxgui.mod/doc/osxtabber.png | Bin 0 -> 8816 bytes mod/maxgui.mod/maxgui.mod/doc/osxtextarea.png | Bin 0 -> 4058 bytes .../maxgui.mod/doc/osxtextfield.png | Bin 0 -> 1666 bytes mod/maxgui.mod/maxgui.mod/doc/osxtreeview.png | Bin 0 -> 4060 bytes mod/maxgui.mod/maxgui.mod/doc/osxwindow.png | Bin 0 -> 15119 bytes .../maxgui.mod/doc/popupwindowmenu.bmx | 30 + .../maxgui.mod/doc/redrawgadget.bmx | 89 + .../maxgui.mod/doc/requestcolor.bmx | 28 + mod/maxgui.mod/maxgui.mod/doc/requestfont.bmx | 33 + .../maxgui.mod/doc/setgadgetfilter.bmx | 40 + mod/maxgui.mod/maxgui.mod/doc/setpointer.bmx | 41 + mod/maxgui.mod/maxgui.mod/doc/toolbar.png | Bin 0 -> 5744 bytes .../maxgui.mod/doc/win32buttons.png | Bin 0 -> 1418 bytes .../maxgui.mod/doc/win32combobox.png | Bin 0 -> 1513 bytes .../maxgui.mod/doc/win32htmlview.png | Bin 0 -> 2130 bytes .../maxgui.mod/doc/win32listbox.png | Bin 0 -> 1127 bytes mod/maxgui.mod/maxgui.mod/doc/win32menu.png | Bin 0 -> 2766 bytes mod/maxgui.mod/maxgui.mod/doc/win32panels.png | Bin 0 -> 343 bytes .../maxgui.mod/doc/win32progbar.png | Bin 0 -> 236 bytes .../maxgui.mod/doc/win32sliders.png | Bin 0 -> 1303 bytes mod/maxgui.mod/maxgui.mod/doc/win32tabber.png | Bin 0 -> 1342 bytes .../maxgui.mod/doc/win32textarea.png | Bin 0 -> 2780 bytes .../maxgui.mod/doc/win32textfield.png | Bin 0 -> 621 bytes .../maxgui.mod/doc/win32toolbar.png | Bin 0 -> 9715 bytes .../maxgui.mod/doc/win32treeview.png | Bin 0 -> 3281 bytes mod/maxgui.mod/maxgui.mod/doc/win32window.png | Bin 0 -> 7051 bytes mod/maxgui.mod/maxgui.mod/driver.bmx | 192 + mod/maxgui.mod/maxgui.mod/event.bmx | 43 + mod/maxgui.mod/maxgui.mod/gadget.bmx | 1088 + mod/maxgui.mod/maxgui.mod/gadgetitem.bmx | 18 + mod/maxgui.mod/maxgui.mod/guifont.bmx | 23 + mod/maxgui.mod/maxgui.mod/iconstrip.bmx | 16 + mod/maxgui.mod/maxgui.mod/maxgui.bmx | 2394 ++ mod/maxgui.mod/maxgui.mod/maxgui.h | 174 + mod/maxgui.mod/maxgui.mod/version.txt | 101 + .../proxygadgets.mod/doc/createhyperlink.bmx | 41 + .../doc/createscrollpanel.bmx | 63 + .../proxygadgets.mod/doc/createsplitter.bmx | 37 + .../doc/scroll_dimensions.png | Bin 0 -> 205920 bytes .../proxygadgets.mod/doc/scroll_position.png | Bin 0 -> 143877 bytes mod/maxgui.mod/proxygadgets.mod/hyperlink.bmx | 120 + .../proxygadgets.mod/proxygadgets.bmx | 16 + .../proxygadgets.mod/scrollpanel.bmx | 518 + mod/maxgui.mod/proxygadgets.mod/splitter.bmx | 817 + mod/maxgui.mod/proxygadgets.mod/version.txt | 31 + mod/maxgui.mod/win32maxguiex.mod/comdef.h | 331 + mod/maxgui.mod/win32maxguiex.mod/comutil.h | 2244 ++ .../win32maxguiex.mod/doc/intro.bbdoc | 21 + mod/maxgui.mod/win32maxguiex.mod/mshtmhst.h | 1409 ++ .../win32maxguiex.mod/mshtmlview.cpp | 1115 + mod/maxgui.mod/win32maxguiex.mod/mshtmlview.h | 23 + mod/maxgui.mod/win32maxguiex.mod/tom.bmx | 226 + mod/maxgui.mod/win32maxguiex.mod/version.txt | 279 + .../win32maxguiex.mod/win32maxguiex.bmx | 5053 ++++ .../win32maxguiex.mod/winimports.bmx | 1076 + mod/maxgui.mod/xpmanifest.mod/xpmanifest.bmx | 18 + mod/maxgui.mod/xpmanifest.mod/xpmanifest.o | Bin 0 -> 708 bytes mod/pub.mod/directx.mod/d3d.bmx | 628 + mod/pub.mod/directx.mod/d3d7.bmx | 224 + mod/pub.mod/directx.mod/d3d9.bmx | 690 + mod/pub.mod/directx.mod/d3d9x.bmx | 25 + mod/pub.mod/directx.mod/dd.bmx | 1764 ++ mod/pub.mod/directx.mod/directx.bmx | 35 + mod/pub.mod/directx.mod/dsound.bmx | 167 + mod/pub.mod/enet.mod/api.txt | 290 + mod/pub.mod/enet.mod/design.txt | 117 + mod/pub.mod/enet.mod/enet.bmx | 116 + mod/pub.mod/enet.mod/host.c | 390 + mod/pub.mod/enet.mod/include/enet/enet.h | 422 + mod/pub.mod/enet.mod/include/enet/list.h | 42 + mod/pub.mod/enet.mod/include/enet/memory.h | 22 + mod/pub.mod/enet.mod/include/enet/protocol.h | 157 + mod/pub.mod/enet.mod/include/enet/time.h | 18 + mod/pub.mod/enet.mod/include/enet/types.h | 13 + mod/pub.mod/enet.mod/include/enet/unix.h | 32 + mod/pub.mod/enet.mod/include/enet/utility.h | 12 + mod/pub.mod/enet.mod/include/enet/win32.h | 32 + mod/pub.mod/enet.mod/license.txt | 26 + mod/pub.mod/enet.mod/list.c | 57 + mod/pub.mod/enet.mod/memory.c | 48 + mod/pub.mod/enet.mod/packet.c | 73 + mod/pub.mod/enet.mod/peer.c | 613 + mod/pub.mod/enet.mod/protocol.c | 1260 + mod/pub.mod/enet.mod/tutorial.txt | 325 + mod/pub.mod/enet.mod/unix.c | 367 + mod/pub.mod/enet.mod/win32.c | 291 + mod/pub.mod/freeaudio.mod/alsadevice.cpp | 146 + mod/pub.mod/freeaudio.mod/audiodevice.h | 0 mod/pub.mod/freeaudio.mod/coreaudiodevice.cpp | 137 + mod/pub.mod/freeaudio.mod/dsound.h | 152 + mod/pub.mod/freeaudio.mod/dsounddevice.cpp | 222 + mod/pub.mod/freeaudio.mod/freeaudio.bmx | 125 + mod/pub.mod/freeaudio.mod/freeaudio.cpp | 590 + mod/pub.mod/freeaudio.mod/freeaudio.h | 312 + mod/pub.mod/freeaudio.mod/freeaudioglue.cpp | 154 + mod/pub.mod/freeaudio.mod/freeaudioglue.h | 40 + mod/pub.mod/freeaudio.mod/mmdevice.cpp | 208 + mod/pub.mod/freeaudio.mod/ossdevice.cpp | 93 + mod/pub.mod/freejoy.mod/doc/intro.bbdoc | 3 + mod/pub.mod/freejoy.mod/doc/joycount.bmx | 56 + mod/pub.mod/freejoy.mod/freejoy.bmx | 294 + mod/pub.mod/freejoy.mod/freejoy.h | 15 + mod/pub.mod/freejoy.mod/freejoy.linux.c | 160 + mod/pub.mod/freejoy.mod/freejoy.macosx.c | 348 + mod/pub.mod/freejoy.mod/freejoy.win32.c | 94 + mod/pub.mod/freeprocess.mod/freeprocess.bmx | 205 + mod/pub.mod/freeprocess.mod/freeprocess.c | 346 + mod/pub.mod/freetype.mod/freetype.bmx | 184 + .../include/freetype/config/ftconfig.h | 500 + .../include/freetype/config/ftheader.h | 780 + .../include/freetype/config/ftmodule.h | 32 + .../include/freetype/config/ftoption.h | 708 + .../include/freetype/config/ftstdlib.h | 173 + .../freetype.mod/include/freetype/freetype.h | 3868 +++ .../freetype.mod/include/freetype/ftadvanc.h | 179 + .../freetype.mod/include/freetype/ftbbox.h | 94 + .../freetype.mod/include/freetype/ftbdf.h | 209 + .../freetype.mod/include/freetype/ftbitmap.h | 227 + .../freetype.mod/include/freetype/ftcache.h | 1125 + .../include/freetype/ftchapters.h | 103 + .../freetype.mod/include/freetype/ftcid.h | 166 + .../freetype.mod/include/freetype/fterrdef.h | 239 + .../freetype.mod/include/freetype/fterrors.h | 206 + .../freetype.mod/include/freetype/ftgasp.h | 120 + .../freetype.mod/include/freetype/ftglyph.h | 613 + .../freetype.mod/include/freetype/ftgxval.h | 358 + .../freetype.mod/include/freetype/ftgzip.h | 102 + .../freetype.mod/include/freetype/ftimage.h | 1285 + .../freetype.mod/include/freetype/ftincrem.h | 349 + .../freetype.mod/include/freetype/ftlcdfil.h | 172 + .../freetype.mod/include/freetype/ftlist.h | 273 + .../freetype.mod/include/freetype/ftlzw.h | 99 + .../freetype.mod/include/freetype/ftmac.h | 274 + .../freetype.mod/include/freetype/ftmm.h | 378 + .../freetype.mod/include/freetype/ftmodapi.h | 445 + .../freetype.mod/include/freetype/ftmoderr.h | 155 + .../freetype.mod/include/freetype/ftotval.h | 203 + .../freetype.mod/include/freetype/ftoutln.h | 538 + .../freetype.mod/include/freetype/ftpfr.h | 172 + .../freetype.mod/include/freetype/ftrender.h | 234 + .../freetype.mod/include/freetype/ftsizes.h | 159 + .../freetype.mod/include/freetype/ftsnames.h | 171 + .../freetype.mod/include/freetype/ftstroke.h | 716 + .../freetype.mod/include/freetype/ftsynth.h | 80 + .../freetype.mod/include/freetype/ftsystem.h | 346 + .../freetype.mod/include/freetype/fttrigon.h | 350 + .../freetype.mod/include/freetype/fttypes.h | 588 + .../freetype.mod/include/freetype/ftwinfnt.h | 274 + .../freetype.mod/include/freetype/ftxf86.h | 83 + .../include/freetype/internal/autohint.h | 231 + .../include/freetype/internal/ftcalc.h | 179 + .../include/freetype/internal/ftdebug.h | 250 + .../include/freetype/internal/ftdriver.h | 422 + .../include/freetype/internal/ftgloadr.h | 168 + .../include/freetype/internal/ftmemory.h | 368 + .../include/freetype/internal/ftobjs.h | 1401 ++ .../include/freetype/internal/ftpic.h | 67 + .../include/freetype/internal/ftrfork.h | 196 + .../include/freetype/internal/ftserv.h | 620 + .../include/freetype/internal/ftstream.h | 539 + .../include/freetype/internal/fttrace.h | 139 + .../include/freetype/internal/ftvalid.h | 150 + .../include/freetype/internal/internal.h | 51 + .../include/freetype/internal/pcftypes.h | 56 + .../include/freetype/internal/psaux.h | 873 + .../include/freetype/internal/pshints.h | 712 + .../freetype/internal/services/svbdf.h | 77 + .../freetype/internal/services/svcid.h | 83 + .../freetype/internal/services/svgldict.h | 82 + .../freetype/internal/services/svgxval.h | 72 + .../freetype/internal/services/svkern.h | 51 + .../include/freetype/internal/services/svmm.h | 104 + .../freetype/internal/services/svotval.h | 55 + .../freetype/internal/services/svpfr.h | 66 + .../freetype/internal/services/svpostnm.h | 79 + .../freetype/internal/services/svpscmap.h | 164 + .../freetype/internal/services/svpsinfo.h | 92 + .../freetype/internal/services/svsfnt.h | 102 + .../freetype/internal/services/svttcmap.h | 106 + .../freetype/internal/services/svtteng.h | 53 + .../freetype/internal/services/svttglyf.h | 67 + .../freetype/internal/services/svwinfnt.h | 50 + .../freetype/internal/services/svxf86nm.h | 55 + .../include/freetype/internal/sfnt.h | 897 + .../include/freetype/internal/t1types.h | 270 + .../include/freetype/internal/tttypes.h | 1543 ++ .../freetype.mod/include/freetype/t1tables.h | 504 + .../freetype.mod/include/freetype/ttnameid.h | 1247 + .../freetype.mod/include/freetype/tttables.h | 756 + .../freetype.mod/include/freetype/tttags.h | 107 + .../freetype.mod/include/freetype/ttunpat.h | 59 + mod/pub.mod/freetype.mod/include/ft2build.h | 39 + .../freetype.mod/src/autofit/afangles.c | 292 + .../freetype.mod/src/autofit/afangles.h | 7 + mod/pub.mod/freetype.mod/src/autofit/afcjk.c | 1512 ++ mod/pub.mod/freetype.mod/src/autofit/afcjk.h | 57 + .../freetype.mod/src/autofit/afdummy.c | 60 + .../freetype.mod/src/autofit/afdummy.h | 42 + .../freetype.mod/src/autofit/aferrors.h | 40 + .../freetype.mod/src/autofit/afglobal.c | 320 + .../freetype.mod/src/autofit/afglobal.h | 71 + .../freetype.mod/src/autofit/afhints.c | 1265 + .../freetype.mod/src/autofit/afhints.h | 333 + .../freetype.mod/src/autofit/afindic.c | 130 + .../freetype.mod/src/autofit/afindic.h | 40 + .../freetype.mod/src/autofit/aflatin.c | 2227 ++ .../freetype.mod/src/autofit/aflatin.h | 212 + .../freetype.mod/src/autofit/aflatin2.c | 2344 ++ .../freetype.mod/src/autofit/aflatin2.h | 39 + .../freetype.mod/src/autofit/afloader.c | 539 + .../freetype.mod/src/autofit/afloader.h | 73 + .../freetype.mod/src/autofit/afmodule.c | 94 + .../freetype.mod/src/autofit/afmodule.h | 37 + mod/pub.mod/freetype.mod/src/autofit/afpic.c | 92 + mod/pub.mod/freetype.mod/src/autofit/afpic.h | 64 + .../freetype.mod/src/autofit/aftypes.h | 403 + mod/pub.mod/freetype.mod/src/autofit/afwarp.c | 338 + mod/pub.mod/freetype.mod/src/autofit/afwarp.h | 64 + .../freetype.mod/src/autofit/autofit.c | 41 + mod/pub.mod/freetype.mod/src/base/basepic.c | 83 + mod/pub.mod/freetype.mod/src/base/basepic.h | 62 + mod/pub.mod/freetype.mod/src/base/ftadvanc.c | 163 + mod/pub.mod/freetype.mod/src/base/ftapi.c | 121 + mod/pub.mod/freetype.mod/src/base/ftbase.c | 41 + mod/pub.mod/freetype.mod/src/base/ftbase.h | 57 + mod/pub.mod/freetype.mod/src/base/ftbbox.c | 662 + mod/pub.mod/freetype.mod/src/base/ftbdf.c | 88 + mod/pub.mod/freetype.mod/src/base/ftbitmap.c | 663 + mod/pub.mod/freetype.mod/src/base/ftcalc.c | 957 + mod/pub.mod/freetype.mod/src/base/ftcid.c | 117 + mod/pub.mod/freetype.mod/src/base/ftdbgmem.c | 997 + mod/pub.mod/freetype.mod/src/base/ftdebug.c | 246 + mod/pub.mod/freetype.mod/src/base/ftfstype.c | 62 + mod/pub.mod/freetype.mod/src/base/ftgasp.c | 61 + mod/pub.mod/freetype.mod/src/base/ftgloadr.c | 401 + mod/pub.mod/freetype.mod/src/base/ftglyph.c | 623 + mod/pub.mod/freetype.mod/src/base/ftgxval.c | 129 + mod/pub.mod/freetype.mod/src/base/ftinit.c | 252 + mod/pub.mod/freetype.mod/src/base/ftlcdfil.c | 351 + mod/pub.mod/freetype.mod/src/base/ftmac.c | 1057 + mod/pub.mod/freetype.mod/src/base/ftmm.c | 202 + mod/pub.mod/freetype.mod/src/base/ftobjs.c | 4478 ++++ mod/pub.mod/freetype.mod/src/base/ftotval.c | 84 + mod/pub.mod/freetype.mod/src/base/ftoutln.c | 1128 + mod/pub.mod/freetype.mod/src/base/ftpatent.c | 285 + mod/pub.mod/freetype.mod/src/base/ftpfr.c | 143 + mod/pub.mod/freetype.mod/src/base/ftpic.c | 54 + mod/pub.mod/freetype.mod/src/base/ftrfork.c | 821 + mod/pub.mod/freetype.mod/src/base/ftsnames.c | 94 + mod/pub.mod/freetype.mod/src/base/ftstream.c | 852 + mod/pub.mod/freetype.mod/src/base/ftstroke.c | 2041 ++ mod/pub.mod/freetype.mod/src/base/ftsynth.c | 160 + mod/pub.mod/freetype.mod/src/base/ftsystem.c | 302 + mod/pub.mod/freetype.mod/src/base/fttrigon.c | 546 + mod/pub.mod/freetype.mod/src/base/fttype1.c | 94 + mod/pub.mod/freetype.mod/src/base/ftutil.c | 501 + mod/pub.mod/freetype.mod/src/base/ftwinfnt.c | 51 + mod/pub.mod/freetype.mod/src/base/ftxf86.c | 40 + mod/pub.mod/freetype.mod/src/bdf/bdf.c | 34 + mod/pub.mod/freetype.mod/src/bdf/bdf.h | 295 + mod/pub.mod/freetype.mod/src/bdf/bdfdrivr.c | 879 + mod/pub.mod/freetype.mod/src/bdf/bdfdrivr.h | 80 + mod/pub.mod/freetype.mod/src/bdf/bdferror.h | 44 + mod/pub.mod/freetype.mod/src/bdf/bdflib.c | 2481 ++ mod/pub.mod/freetype.mod/src/cache/ftcache.c | 31 + mod/pub.mod/freetype.mod/src/cache/ftcbasic.c | 851 + mod/pub.mod/freetype.mod/src/cache/ftccache.c | 595 + mod/pub.mod/freetype.mod/src/cache/ftccache.h | 316 + mod/pub.mod/freetype.mod/src/cache/ftccback.h | 90 + mod/pub.mod/freetype.mod/src/cache/ftccmap.c | 431 + mod/pub.mod/freetype.mod/src/cache/ftcerror.h | 40 + mod/pub.mod/freetype.mod/src/cache/ftcglyph.c | 209 + mod/pub.mod/freetype.mod/src/cache/ftcglyph.h | 323 + mod/pub.mod/freetype.mod/src/cache/ftcimage.c | 163 + mod/pub.mod/freetype.mod/src/cache/ftcimage.h | 107 + mod/pub.mod/freetype.mod/src/cache/ftcmanag.c | 743 + mod/pub.mod/freetype.mod/src/cache/ftcmanag.h | 175 + mod/pub.mod/freetype.mod/src/cache/ftcmru.c | 357 + mod/pub.mod/freetype.mod/src/cache/ftcmru.h | 246 + mod/pub.mod/freetype.mod/src/cache/ftcsbits.c | 404 + mod/pub.mod/freetype.mod/src/cache/ftcsbits.h | 98 + mod/pub.mod/freetype.mod/src/cff/cff.c | 30 + mod/pub.mod/freetype.mod/src/cff/cffcmap.c | 219 + mod/pub.mod/freetype.mod/src/cff/cffcmap.h | 67 + mod/pub.mod/freetype.mod/src/cff/cffdrivr.c | 690 + mod/pub.mod/freetype.mod/src/cff/cffdrivr.h | 38 + mod/pub.mod/freetype.mod/src/cff/cfferrs.h | 41 + mod/pub.mod/freetype.mod/src/cff/cffgload.c | 2840 +++ mod/pub.mod/freetype.mod/src/cff/cffgload.h | 201 + mod/pub.mod/freetype.mod/src/cff/cffload.c | 1638 ++ mod/pub.mod/freetype.mod/src/cff/cffload.h | 81 + mod/pub.mod/freetype.mod/src/cff/cffobjs.c | 967 + mod/pub.mod/freetype.mod/src/cff/cffobjs.h | 181 + mod/pub.mod/freetype.mod/src/cff/cffparse.c | 917 + mod/pub.mod/freetype.mod/src/cff/cffparse.h | 102 + mod/pub.mod/freetype.mod/src/cff/cffpic.c | 99 + mod/pub.mod/freetype.mod/src/cff/cffpic.h | 80 + mod/pub.mod/freetype.mod/src/cff/cfftoken.h | 97 + mod/pub.mod/freetype.mod/src/cff/cfftypes.h | 274 + mod/pub.mod/freetype.mod/src/cid/ciderrs.h | 40 + mod/pub.mod/freetype.mod/src/cid/cidgload.c | 438 + mod/pub.mod/freetype.mod/src/cid/cidgload.h | 51 + mod/pub.mod/freetype.mod/src/cid/cidload.c | 672 + mod/pub.mod/freetype.mod/src/cid/cidload.h | 53 + mod/pub.mod/freetype.mod/src/cid/cidobjs.c | 481 + mod/pub.mod/freetype.mod/src/cid/cidobjs.h | 154 + mod/pub.mod/freetype.mod/src/cid/cidparse.c | 225 + mod/pub.mod/freetype.mod/src/cid/cidparse.h | 123 + mod/pub.mod/freetype.mod/src/cid/cidriver.c | 240 + mod/pub.mod/freetype.mod/src/cid/cidriver.h | 43 + mod/pub.mod/freetype.mod/src/cid/cidtoken.h | 112 + mod/pub.mod/freetype.mod/src/cid/type1cid.c | 29 + mod/pub.mod/freetype.mod/src/gzip/adler32.c | 48 + mod/pub.mod/freetype.mod/src/gzip/ftgzip.c | 688 + mod/pub.mod/freetype.mod/src/gzip/infblock.c | 387 + mod/pub.mod/freetype.mod/src/gzip/infblock.h | 36 + mod/pub.mod/freetype.mod/src/gzip/infcodes.c | 250 + mod/pub.mod/freetype.mod/src/gzip/infcodes.h | 31 + mod/pub.mod/freetype.mod/src/gzip/inffixed.h | 151 + mod/pub.mod/freetype.mod/src/gzip/inflate.c | 273 + mod/pub.mod/freetype.mod/src/gzip/inftrees.c | 468 + mod/pub.mod/freetype.mod/src/gzip/inftrees.h | 63 + mod/pub.mod/freetype.mod/src/gzip/infutil.c | 86 + mod/pub.mod/freetype.mod/src/gzip/infutil.h | 98 + mod/pub.mod/freetype.mod/src/gzip/zconf.h | 284 + mod/pub.mod/freetype.mod/src/gzip/zlib.h | 830 + mod/pub.mod/freetype.mod/src/gzip/zutil.c | 181 + mod/pub.mod/freetype.mod/src/gzip/zutil.h | 215 + mod/pub.mod/freetype.mod/src/lzw/ftlzw.c | 416 + mod/pub.mod/freetype.mod/src/lzw/ftzopen.c | 401 + mod/pub.mod/freetype.mod/src/lzw/ftzopen.h | 171 + .../freetype.mod/src/otvalid/otvalid.c | 31 + .../freetype.mod/src/otvalid/otvalid.h | 78 + .../freetype.mod/src/otvalid/otvbase.c | 318 + .../freetype.mod/src/otvalid/otvcommn.c | 1086 + .../freetype.mod/src/otvalid/otvcommn.h | 437 + .../freetype.mod/src/otvalid/otverror.h | 43 + .../freetype.mod/src/otvalid/otvgdef.c | 224 + .../freetype.mod/src/otvalid/otvgpos.c | 1017 + .../freetype.mod/src/otvalid/otvgpos.h | 36 + .../freetype.mod/src/otvalid/otvgsub.c | 585 + .../freetype.mod/src/otvalid/otvjstf.c | 258 + .../freetype.mod/src/otvalid/otvmath.c | 452 + mod/pub.mod/freetype.mod/src/otvalid/otvmod.c | 280 + mod/pub.mod/freetype.mod/src/otvalid/otvmod.h | 43 + mod/pub.mod/freetype.mod/src/pcf/pcf.c | 36 + mod/pub.mod/freetype.mod/src/pcf/pcf.h | 237 + mod/pub.mod/freetype.mod/src/pcf/pcfdrivr.c | 695 + mod/pub.mod/freetype.mod/src/pcf/pcfdrivr.h | 48 + mod/pub.mod/freetype.mod/src/pcf/pcferror.h | 40 + mod/pub.mod/freetype.mod/src/pcf/pcfread.c | 1274 + mod/pub.mod/freetype.mod/src/pcf/pcfread.h | 45 + mod/pub.mod/freetype.mod/src/pcf/pcfutil.c | 104 + mod/pub.mod/freetype.mod/src/pcf/pcfutil.h | 55 + mod/pub.mod/freetype.mod/src/pfr/pfr.c | 29 + mod/pub.mod/freetype.mod/src/pfr/pfrcmap.c | 166 + mod/pub.mod/freetype.mod/src/pfr/pfrcmap.h | 46 + mod/pub.mod/freetype.mod/src/pfr/pfrdrivr.c | 214 + mod/pub.mod/freetype.mod/src/pfr/pfrdrivr.h | 43 + mod/pub.mod/freetype.mod/src/pfr/pfrerror.h | 40 + mod/pub.mod/freetype.mod/src/pfr/pfrgload.c | 828 + mod/pub.mod/freetype.mod/src/pfr/pfrgload.h | 49 + mod/pub.mod/freetype.mod/src/pfr/pfrload.c | 941 + mod/pub.mod/freetype.mod/src/pfr/pfrload.h | 118 + mod/pub.mod/freetype.mod/src/pfr/pfrobjs.c | 581 + mod/pub.mod/freetype.mod/src/pfr/pfrobjs.h | 96 + mod/pub.mod/freetype.mod/src/pfr/pfrsbit.c | 698 + mod/pub.mod/freetype.mod/src/pfr/pfrsbit.h | 36 + mod/pub.mod/freetype.mod/src/pfr/pfrtypes.h | 362 + mod/pub.mod/freetype.mod/src/psaux/afmparse.c | 964 + mod/pub.mod/freetype.mod/src/psaux/afmparse.h | 87 + mod/pub.mod/freetype.mod/src/psaux/psaux.c | 34 + mod/pub.mod/freetype.mod/src/psaux/psauxerr.h | 41 + mod/pub.mod/freetype.mod/src/psaux/psauxmod.c | 139 + mod/pub.mod/freetype.mod/src/psaux/psauxmod.h | 42 + mod/pub.mod/freetype.mod/src/psaux/psconv.c | 472 + mod/pub.mod/freetype.mod/src/psaux/psconv.h | 71 + mod/pub.mod/freetype.mod/src/psaux/psobjs.c | 1703 ++ mod/pub.mod/freetype.mod/src/psaux/psobjs.h | 212 + mod/pub.mod/freetype.mod/src/psaux/t1cmap.c | 341 + mod/pub.mod/freetype.mod/src/psaux/t1cmap.h | 105 + mod/pub.mod/freetype.mod/src/psaux/t1decode.c | 1577 ++ mod/pub.mod/freetype.mod/src/psaux/t1decode.h | 64 + .../freetype.mod/src/pshinter/pshalgo.c | 2302 ++ .../freetype.mod/src/pshinter/pshalgo.h | 255 + .../freetype.mod/src/pshinter/pshglob.c | 750 + .../freetype.mod/src/pshinter/pshglob.h | 196 + .../freetype.mod/src/pshinter/pshinter.c | 29 + .../freetype.mod/src/pshinter/pshmod.c | 118 + .../freetype.mod/src/pshinter/pshmod.h | 39 + .../freetype.mod/src/pshinter/pshnterr.h | 40 + .../freetype.mod/src/pshinter/pshpic.c | 67 + .../freetype.mod/src/pshinter/pshpic.h | 53 + .../freetype.mod/src/pshinter/pshrec.c | 1224 + .../freetype.mod/src/pshinter/pshrec.h | 176 + .../freetype.mod/src/psnames/psmodule.c | 596 + .../freetype.mod/src/psnames/psmodule.h | 38 + .../freetype.mod/src/psnames/psnamerr.h | 41 + .../freetype.mod/src/psnames/psnames.c | 26 + mod/pub.mod/freetype.mod/src/psnames/pspic.c | 77 + mod/pub.mod/freetype.mod/src/psnames/pspic.h | 54 + .../freetype.mod/src/psnames/pstables.h | 4095 +++ mod/pub.mod/freetype.mod/src/raster/ftmisc.h | 109 + .../freetype.mod/src/raster/ftraster.c | 3563 +++ .../freetype.mod/src/raster/ftraster.h | 46 + mod/pub.mod/freetype.mod/src/raster/ftrend1.c | 291 + mod/pub.mod/freetype.mod/src/raster/ftrend1.h | 44 + mod/pub.mod/freetype.mod/src/raster/raster.c | 27 + .../freetype.mod/src/raster/rasterrs.h | 41 + mod/pub.mod/freetype.mod/src/raster/rastpic.c | 89 + mod/pub.mod/freetype.mod/src/raster/rastpic.h | 50 + mod/pub.mod/freetype.mod/src/sfnt/sfdriver.c | 653 + mod/pub.mod/freetype.mod/src/sfnt/sfdriver.h | 38 + mod/pub.mod/freetype.mod/src/sfnt/sferrors.h | 41 + mod/pub.mod/freetype.mod/src/sfnt/sfnt.c | 42 + mod/pub.mod/freetype.mod/src/sfnt/sfntpic.c | 101 + mod/pub.mod/freetype.mod/src/sfnt/sfntpic.h | 88 + mod/pub.mod/freetype.mod/src/sfnt/sfobjs.c | 1130 + mod/pub.mod/freetype.mod/src/sfnt/sfobjs.h | 54 + mod/pub.mod/freetype.mod/src/sfnt/ttbdf.c | 250 + mod/pub.mod/freetype.mod/src/sfnt/ttbdf.h | 46 + mod/pub.mod/freetype.mod/src/sfnt/ttcmap.c | 3507 +++ mod/pub.mod/freetype.mod/src/sfnt/ttcmap.h | 125 + mod/pub.mod/freetype.mod/src/sfnt/ttcmapc.h | 55 + mod/pub.mod/freetype.mod/src/sfnt/ttkern.c | 306 + mod/pub.mod/freetype.mod/src/sfnt/ttkern.h | 52 + mod/pub.mod/freetype.mod/src/sfnt/ttload.c | 1251 + mod/pub.mod/freetype.mod/src/sfnt/ttload.h | 112 + mod/pub.mod/freetype.mod/src/sfnt/ttmtx.c | 468 + mod/pub.mod/freetype.mod/src/sfnt/ttmtx.h | 55 + mod/pub.mod/freetype.mod/src/sfnt/ttpost.c | 521 + mod/pub.mod/freetype.mod/src/sfnt/ttpost.h | 46 + mod/pub.mod/freetype.mod/src/sfnt/ttsbit.c | 1507 ++ mod/pub.mod/freetype.mod/src/sfnt/ttsbit.h | 79 + mod/pub.mod/freetype.mod/src/sfnt/ttsbit0.c | 1011 + mod/pub.mod/freetype.mod/src/smooth/ftgrays.c | 2090 ++ mod/pub.mod/freetype.mod/src/smooth/ftgrays.h | 58 + .../freetype.mod/src/smooth/ftsmerrs.h | 41 + .../freetype.mod/src/smooth/ftsmooth.c | 481 + .../freetype.mod/src/smooth/ftsmooth.h | 49 + mod/pub.mod/freetype.mod/src/smooth/ftspic.c | 97 + mod/pub.mod/freetype.mod/src/smooth/ftspic.h | 50 + mod/pub.mod/freetype.mod/src/smooth/smooth.c | 27 + .../freetype.mod/src/truetype/truetype.c | 37 + .../freetype.mod/src/truetype/ttdriver.c | 477 + .../freetype.mod/src/truetype/ttdriver.h | 38 + .../freetype.mod/src/truetype/tterrors.h | 40 + .../freetype.mod/src/truetype/ttgload.c | 2037 ++ .../freetype.mod/src/truetype/ttgload.h | 63 + .../freetype.mod/src/truetype/ttgxvar.c | 1547 ++ .../freetype.mod/src/truetype/ttgxvar.h | 182 + .../freetype.mod/src/truetype/ttinterp.c | 7844 ++++++ .../freetype.mod/src/truetype/ttinterp.h | 311 + .../freetype.mod/src/truetype/ttobjs.c | 951 + .../freetype.mod/src/truetype/ttobjs.h | 431 + mod/pub.mod/freetype.mod/src/truetype/ttpic.c | 79 + mod/pub.mod/freetype.mod/src/truetype/ttpic.h | 59 + .../freetype.mod/src/truetype/ttpload.c | 572 + .../freetype.mod/src/truetype/ttpload.h | 75 + mod/pub.mod/freetype.mod/src/type1/t1afm.c | 394 + mod/pub.mod/freetype.mod/src/type1/t1afm.h | 54 + mod/pub.mod/freetype.mod/src/type1/t1driver.c | 331 + mod/pub.mod/freetype.mod/src/type1/t1driver.h | 42 + mod/pub.mod/freetype.mod/src/type1/t1errors.h | 40 + mod/pub.mod/freetype.mod/src/type1/t1gload.c | 497 + mod/pub.mod/freetype.mod/src/type1/t1gload.h | 53 + mod/pub.mod/freetype.mod/src/type1/t1load.c | 2231 ++ mod/pub.mod/freetype.mod/src/type1/t1load.h | 102 + mod/pub.mod/freetype.mod/src/type1/t1objs.c | 593 + mod/pub.mod/freetype.mod/src/type1/t1objs.h | 171 + mod/pub.mod/freetype.mod/src/type1/t1parse.c | 483 + mod/pub.mod/freetype.mod/src/type1/t1parse.h | 135 + mod/pub.mod/freetype.mod/src/type1/t1tokens.h | 143 + mod/pub.mod/freetype.mod/src/type1/type1.c | 33 + .../freetype.mod/src/type42/t42drivr.c | 246 + .../freetype.mod/src/type42/t42drivr.h | 42 + .../freetype.mod/src/type42/t42error.h | 40 + mod/pub.mod/freetype.mod/src/type42/t42objs.c | 648 + mod/pub.mod/freetype.mod/src/type42/t42objs.h | 124 + .../freetype.mod/src/type42/t42parse.c | 1178 + .../freetype.mod/src/type42/t42parse.h | 90 + .../freetype.mod/src/type42/t42types.h | 56 + mod/pub.mod/freetype.mod/src/type42/type42.c | 25 + .../freetype.mod/src/winfonts/fnterrs.h | 41 + .../freetype.mod/src/winfonts/winfnt.c | 1135 + .../freetype.mod/src/winfonts/winfnt.h | 171 + mod/pub.mod/glew.mod/GL/glew.h | 12262 +++++++++ mod/pub.mod/glew.mod/GL/glxew.h | 1397 + mod/pub.mod/glew.mod/GL/wglew.h | 1165 + mod/pub.mod/glew.mod/glew.bmx | 4415 ++++ mod/pub.mod/glew.mod/glew.c | 12180 +++++++++ mod/pub.mod/glew.mod/glew2bmx.bmx | 211 + mod/pub.mod/glew.mod/glew_static.c | 3 + mod/pub.mod/libjpeg.mod/jcapimin.c | 280 + mod/pub.mod/libjpeg.mod/jcapistd.c | 161 + mod/pub.mod/libjpeg.mod/jccoefct.c | 449 + mod/pub.mod/libjpeg.mod/jccolor.c | 459 + mod/pub.mod/libjpeg.mod/jcdctmgr.c | 387 + mod/pub.mod/libjpeg.mod/jchuff.c | 909 + mod/pub.mod/libjpeg.mod/jchuff.h | 47 + mod/pub.mod/libjpeg.mod/jcinit.c | 72 + mod/pub.mod/libjpeg.mod/jcmainct.c | 293 + mod/pub.mod/libjpeg.mod/jcmarker.c | 664 + mod/pub.mod/libjpeg.mod/jcmaster.c | 590 + mod/pub.mod/libjpeg.mod/jcomapi.c | 106 + mod/pub.mod/libjpeg.mod/jcparam.c | 610 + mod/pub.mod/libjpeg.mod/jcphuff.c | 833 + mod/pub.mod/libjpeg.mod/jcprepct.c | 354 + mod/pub.mod/libjpeg.mod/jcsample.c | 519 + mod/pub.mod/libjpeg.mod/jctrans.c | 388 + mod/pub.mod/libjpeg.mod/jdapimin.c | 395 + mod/pub.mod/libjpeg.mod/jdapistd.c | 275 + mod/pub.mod/libjpeg.mod/jdatadst.c | 152 + mod/pub.mod/libjpeg.mod/jdatasrc.c | 212 + mod/pub.mod/libjpeg.mod/jdcoefct.c | 736 + mod/pub.mod/libjpeg.mod/jdcolor.c | 396 + mod/pub.mod/libjpeg.mod/jdct.h | 176 + mod/pub.mod/libjpeg.mod/jddctmgr.c | 269 + mod/pub.mod/libjpeg.mod/jdhuff.c | 651 + mod/pub.mod/libjpeg.mod/jdhuff.h | 201 + mod/pub.mod/libjpeg.mod/jdinput.c | 381 + mod/pub.mod/libjpeg.mod/jdmainct.c | 512 + mod/pub.mod/libjpeg.mod/jdmarker.c | 1360 + mod/pub.mod/libjpeg.mod/jdmaster.c | 557 + mod/pub.mod/libjpeg.mod/jdmerge.c | 400 + mod/pub.mod/libjpeg.mod/jdphuff.c | 668 + mod/pub.mod/libjpeg.mod/jdpostct.c | 290 + mod/pub.mod/libjpeg.mod/jdsample.c | 478 + mod/pub.mod/libjpeg.mod/jdtrans.c | 143 + mod/pub.mod/libjpeg.mod/jerror.c | 254 + mod/pub.mod/libjpeg.mod/jerror.h | 291 + mod/pub.mod/libjpeg.mod/jfdctflt.c | 168 + mod/pub.mod/libjpeg.mod/jfdctfst.c | 224 + mod/pub.mod/libjpeg.mod/jfdctint.c | 283 + mod/pub.mod/libjpeg.mod/jidctflt.c | 242 + mod/pub.mod/libjpeg.mod/jidctfst.c | 368 + mod/pub.mod/libjpeg.mod/jidctint.c | 389 + mod/pub.mod/libjpeg.mod/jidctred.c | 398 + mod/pub.mod/libjpeg.mod/jinclude.h | 99 + mod/pub.mod/libjpeg.mod/jmemmgr.c | 1118 + mod/pub.mod/libjpeg.mod/jmemnobs.c | 109 + mod/pub.mod/libjpeg.mod/jmemsys.h | 198 + mod/pub.mod/libjpeg.mod/jmorecfg.h | 363 + mod/pub.mod/libjpeg.mod/jpegint.h | 392 + mod/pub.mod/libjpeg.mod/jpeglib.h | 1098 + mod/pub.mod/libjpeg.mod/jquant1.c | 856 + mod/pub.mod/libjpeg.mod/jquant2.c | 1310 + mod/pub.mod/libjpeg.mod/jutils.c | 179 + mod/pub.mod/libjpeg.mod/jversion.h | 14 + mod/pub.mod/libjpeg.mod/libjpeg.bmx | 76 + mod/pub.mod/libjpeg.mod/loadjpeg.c | 161 + mod/pub.mod/libjpeg.mod/transupp.h | 135 + mod/pub.mod/libpng.mod/ANNOUNCE | 51 + mod/pub.mod/libpng.mod/CHANGES | 1624 ++ mod/pub.mod/libpng.mod/INSTALL | 195 + mod/pub.mod/libpng.mod/KNOWNBUG | 23 + mod/pub.mod/libpng.mod/LICENSE | 109 + mod/pub.mod/libpng.mod/README | 263 + mod/pub.mod/libpng.mod/TODO | 24 + mod/pub.mod/libpng.mod/Y2KINFO | 55 + mod/pub.mod/libpng.mod/configure | 13 + mod/pub.mod/libpng.mod/example.c | 814 + mod/pub.mod/libpng.mod/libpng.3 | 4092 +++ mod/pub.mod/libpng.mod/libpng.bmx | 105 + mod/pub.mod/libpng.mod/libpng.txt | 2972 +++ mod/pub.mod/libpng.mod/libpngpf.3 | 784 + mod/pub.mod/libpng.mod/png.5 | 74 + mod/pub.mod/libpng.mod/png.c | 847 + mod/pub.mod/libpng.mod/png.h | 3481 +++ mod/pub.mod/libpng.mod/pngbar.jpg | Bin 0 -> 2498 bytes mod/pub.mod/libpng.mod/pngbar.png | Bin 0 -> 2399 bytes mod/pub.mod/libpng.mod/pngconf.h | 1474 ++ mod/pub.mod/libpng.mod/pngerror.c | 313 + mod/pub.mod/libpng.mod/pnggccrd.c | 5420 ++++ mod/pub.mod/libpng.mod/pngget.c | 937 + mod/pub.mod/libpng.mod/pngmem.c | 598 + mod/pub.mod/libpng.mod/pngnow.png | Bin 0 -> 2069 bytes mod/pub.mod/libpng.mod/pngpread.c | 1578 ++ mod/pub.mod/libpng.mod/pngread.c | 1461 ++ mod/pub.mod/libpng.mod/pngrio.c | 164 + mod/pub.mod/libpng.mod/pngrtran.c | 4219 ++++ mod/pub.mod/libpng.mod/pngrutil.c | 3123 +++ mod/pub.mod/libpng.mod/pngset.c | 1265 + mod/pub.mod/libpng.mod/pngtest.c | 1552 ++ mod/pub.mod/libpng.mod/pngtest.png | Bin 0 -> 8574 bytes mod/pub.mod/libpng.mod/pngtrans.c | 652 + mod/pub.mod/libpng.mod/pngvcrd.c | 3904 +++ mod/pub.mod/libpng.mod/pngwio.c | 228 + mod/pub.mod/libpng.mod/pngwrite.c | 1513 ++ mod/pub.mod/libpng.mod/pngwtran.c | 572 + mod/pub.mod/libpng.mod/pngwutil.c | 2750 ++ mod/pub.mod/lua.mod/doc/Lua-Logo_32x32.png | Bin 0 -> 1856 bytes mod/pub.mod/lua.mod/doc/commands.html | 1201 + mod/pub.mod/lua.mod/doc/intro.bbdoc | 56 + mod/pub.mod/lua.mod/lua-5.1.4/COPYRIGHT | 34 + mod/pub.mod/lua.mod/lua-5.1.4/HISTORY | 183 + mod/pub.mod/lua.mod/lua-5.1.4/INSTALL | 99 + mod/pub.mod/lua.mod/lua-5.1.4/Makefile | 128 + mod/pub.mod/lua.mod/lua-5.1.4/README | 37 + mod/pub.mod/lua.mod/lua-5.1.4/doc/amazon.gif | Bin 0 -> 797 bytes .../lua.mod/lua-5.1.4/doc/contents.html | 499 + mod/pub.mod/lua.mod/lua-5.1.4/doc/cover.png | Bin 0 -> 3305 bytes mod/pub.mod/lua.mod/lua-5.1.4/doc/logo.gif | Bin 0 -> 4232 bytes mod/pub.mod/lua.mod/lua-5.1.4/doc/lua.1 | 163 + mod/pub.mod/lua.mod/lua-5.1.4/doc/lua.css | 41 + mod/pub.mod/lua.mod/lua-5.1.4/doc/lua.html | 172 + mod/pub.mod/lua.mod/lua-5.1.4/doc/luac.1 | 136 + mod/pub.mod/lua.mod/lua-5.1.4/doc/luac.html | 145 + mod/pub.mod/lua.mod/lua-5.1.4/doc/manual.css | 13 + mod/pub.mod/lua.mod/lua-5.1.4/doc/manual.html | 8801 +++++++ mod/pub.mod/lua.mod/lua-5.1.4/doc/readme.html | 40 + mod/pub.mod/lua.mod/lua-5.1.4/etc/Makefile | 44 + mod/pub.mod/lua.mod/lua-5.1.4/etc/README | 37 + mod/pub.mod/lua.mod/lua-5.1.4/etc/all.c | 38 + mod/pub.mod/lua.mod/lua-5.1.4/etc/lua.hpp | 9 + mod/pub.mod/lua.mod/lua-5.1.4/etc/lua.ico | Bin 0 -> 1078 bytes mod/pub.mod/lua.mod/lua-5.1.4/etc/lua.pc | 31 + mod/pub.mod/lua.mod/lua-5.1.4/etc/luavs.bat | 28 + mod/pub.mod/lua.mod/lua-5.1.4/etc/min.c | 39 + mod/pub.mod/lua.mod/lua-5.1.4/etc/noparser.c | 50 + mod/pub.mod/lua.mod/lua-5.1.4/etc/strict.lua | 41 + mod/pub.mod/lua.mod/lua-5.1.4/src/Makefile | 182 + mod/pub.mod/lua.mod/lua-5.1.4/src/lapi.c | 1087 + mod/pub.mod/lua.mod/lua-5.1.4/src/lapi.h | 16 + mod/pub.mod/lua.mod/lua-5.1.4/src/lauxlib.c | 652 + mod/pub.mod/lua.mod/lua-5.1.4/src/lauxlib.h | 174 + mod/pub.mod/lua.mod/lua-5.1.4/src/lbaselib.c | 653 + mod/pub.mod/lua.mod/lua-5.1.4/src/lcode.c | 839 + mod/pub.mod/lua.mod/lua-5.1.4/src/lcode.h | 76 + mod/pub.mod/lua.mod/lua-5.1.4/src/ldblib.c | 397 + mod/pub.mod/lua.mod/lua-5.1.4/src/ldebug.c | 638 + mod/pub.mod/lua.mod/lua-5.1.4/src/ldebug.h | 33 + mod/pub.mod/lua.mod/lua-5.1.4/src/ldo.c | 518 + mod/pub.mod/lua.mod/lua-5.1.4/src/ldo.h | 57 + mod/pub.mod/lua.mod/lua-5.1.4/src/ldump.c | 164 + mod/pub.mod/lua.mod/lua-5.1.4/src/lfunc.c | 174 + mod/pub.mod/lua.mod/lua-5.1.4/src/lfunc.h | 34 + mod/pub.mod/lua.mod/lua-5.1.4/src/lgc.c | 711 + mod/pub.mod/lua.mod/lua-5.1.4/src/lgc.h | 110 + mod/pub.mod/lua.mod/lua-5.1.4/src/linit.c | 38 + mod/pub.mod/lua.mod/lua-5.1.4/src/liolib.c | 553 + mod/pub.mod/lua.mod/lua-5.1.4/src/llex.c | 461 + mod/pub.mod/lua.mod/lua-5.1.4/src/llex.h | 81 + mod/pub.mod/lua.mod/lua-5.1.4/src/llimits.h | 128 + mod/pub.mod/lua.mod/lua-5.1.4/src/lmathlib.c | 263 + mod/pub.mod/lua.mod/lua-5.1.4/src/lmem.c | 86 + mod/pub.mod/lua.mod/lua-5.1.4/src/lmem.h | 49 + mod/pub.mod/lua.mod/lua-5.1.4/src/loadlib.c | 666 + mod/pub.mod/lua.mod/lua-5.1.4/src/lobject.c | 214 + mod/pub.mod/lua.mod/lua-5.1.4/src/lobject.h | 381 + mod/pub.mod/lua.mod/lua-5.1.4/src/lopcodes.c | 102 + mod/pub.mod/lua.mod/lua-5.1.4/src/lopcodes.h | 268 + mod/pub.mod/lua.mod/lua-5.1.4/src/loslib.c | 243 + mod/pub.mod/lua.mod/lua-5.1.4/src/lparser.c | 1339 + mod/pub.mod/lua.mod/lua-5.1.4/src/lparser.h | 82 + mod/pub.mod/lua.mod/lua-5.1.4/src/lstate.c | 214 + mod/pub.mod/lua.mod/lua-5.1.4/src/lstate.h | 169 + mod/pub.mod/lua.mod/lua-5.1.4/src/lstring.c | 111 + mod/pub.mod/lua.mod/lua-5.1.4/src/lstring.h | 31 + mod/pub.mod/lua.mod/lua-5.1.4/src/lstrlib.c | 869 + mod/pub.mod/lua.mod/lua-5.1.4/src/ltable.c | 588 + mod/pub.mod/lua.mod/lua-5.1.4/src/ltable.h | 40 + mod/pub.mod/lua.mod/lua-5.1.4/src/ltablib.c | 287 + mod/pub.mod/lua.mod/lua-5.1.4/src/ltm.c | 75 + mod/pub.mod/lua.mod/lua-5.1.4/src/ltm.h | 54 + mod/pub.mod/lua.mod/lua-5.1.4/src/lua.c | 392 + mod/pub.mod/lua.mod/lua-5.1.4/src/lua.h | 388 + mod/pub.mod/lua.mod/lua-5.1.4/src/luac.c | 200 + mod/pub.mod/lua.mod/lua-5.1.4/src/luaconf.h | 772 + mod/pub.mod/lua.mod/lua-5.1.4/src/lualib.h | 53 + mod/pub.mod/lua.mod/lua-5.1.4/src/lundump.c | 227 + mod/pub.mod/lua.mod/lua-5.1.4/src/lundump.h | 36 + mod/pub.mod/lua.mod/lua-5.1.4/src/lvm.c | 763 + mod/pub.mod/lua.mod/lua-5.1.4/src/lvm.h | 36 + mod/pub.mod/lua.mod/lua-5.1.4/src/lzio.c | 82 + mod/pub.mod/lua.mod/lua-5.1.4/src/lzio.h | 67 + mod/pub.mod/lua.mod/lua-5.1.4/src/print.c | 227 + mod/pub.mod/lua.mod/lua-5.1.4/test/README | 26 + mod/pub.mod/lua.mod/lua-5.1.4/test/bisect.lua | 27 + mod/pub.mod/lua.mod/lua-5.1.4/test/cf.lua | 16 + mod/pub.mod/lua.mod/lua-5.1.4/test/echo.lua | 5 + mod/pub.mod/lua.mod/lua-5.1.4/test/env.lua | 7 + .../lua.mod/lua-5.1.4/test/factorial.lua | 32 + mod/pub.mod/lua.mod/lua-5.1.4/test/fib.lua | 40 + mod/pub.mod/lua.mod/lua-5.1.4/test/fibfor.lua | 13 + .../lua.mod/lua-5.1.4/test/globals.lua | 13 + mod/pub.mod/lua.mod/lua-5.1.4/test/hello.lua | 3 + mod/pub.mod/lua.mod/lua-5.1.4/test/life.lua | 111 + mod/pub.mod/lua.mod/lua-5.1.4/test/luac.lua | 7 + mod/pub.mod/lua.mod/lua-5.1.4/test/printf.lua | 7 + .../lua.mod/lua-5.1.4/test/readonly.lua | 12 + mod/pub.mod/lua.mod/lua-5.1.4/test/sieve.lua | 29 + mod/pub.mod/lua.mod/lua-5.1.4/test/sort.lua | 66 + mod/pub.mod/lua.mod/lua-5.1.4/test/table.lua | 12 + .../lua.mod/lua-5.1.4/test/trace-calls.lua | 32 + .../lua.mod/lua-5.1.4/test/trace-globals.lua | 38 + mod/pub.mod/lua.mod/lua-5.1.4/test/xd.lua | 14 + mod/pub.mod/lua.mod/lua.bmx | 929 + mod/pub.mod/macos.mod/macos.bmx | 31 + mod/pub.mod/macos.mod/macos.h | 19 + mod/pub.mod/macos.mod/macos.m | 59 + .../oggvorbis.mod/libogg-1.1.3/AUTHORS | 4 + .../oggvorbis.mod/libogg-1.1.3/CHANGES | 33 + .../oggvorbis.mod/libogg-1.1.3/COPYING | 28 + mod/pub.mod/oggvorbis.mod/libogg-1.1.3/README | 103 + .../libogg-1.1.3/include/ogg/ogg.h | 202 + .../libogg-1.1.3/include/ogg/os_types.h | 136 + .../oggvorbis.mod/libogg-1.1.3/src/bitwise.c | 784 + .../oggvorbis.mod/libogg-1.1.3/src/framing.c | 1800 ++ .../oggvorbis.mod/libvorbis-1.1.2/AUTHORS | 3 + .../oggvorbis.mod/libvorbis-1.1.2/COPYING | 28 + .../oggvorbis.mod/libvorbis-1.1.2/README | 132 + .../libvorbis-1.1.2/include/vorbis/codec.h | 240 + .../include/vorbis/vorbisenc.h | 112 + .../include/vorbis/vorbisfile.h | 143 + .../libvorbis-1.1.2/lib/analysis.c | 121 + .../libvorbis-1.1.2/lib/backends.h | 146 + .../libvorbis-1.1.2/lib/barkmel.c | 64 + .../libvorbis-1.1.2/lib/bitrate.c | 253 + .../libvorbis-1.1.2/lib/bitrate.h | 59 + .../oggvorbis.mod/libvorbis-1.1.2/lib/block.c | 989 + .../lib/books/coupled/res_books_stereo.h | 20989 ++++++++++++++++ .../lib/books/floor/floor_books.h | 1838 ++ .../lib/books/uncoupled/res_books_uncoupled.h | 11517 +++++++++ .../libvorbis-1.1.2/lib/codebook.c | 615 + .../libvorbis-1.1.2/lib/codebook.h | 160 + .../libvorbis-1.1.2/lib/codec_internal.h | 137 + .../libvorbis-1.1.2/lib/envelope.c | 382 + .../libvorbis-1.1.2/lib/envelope.h | 81 + .../libvorbis-1.1.2/lib/floor0.c | 223 + .../libvorbis-1.1.2/lib/floor1.c | 1090 + .../libvorbis-1.1.2/lib/highlevel.h | 57 + .../oggvorbis.mod/libvorbis-1.1.2/lib/info.c | 607 + .../libvorbis-1.1.2/lib/lookup.c | 94 + .../libvorbis-1.1.2/lib/lookup.h | 32 + .../libvorbis-1.1.2/lib/lookup_data.h | 189 + .../libvorbis-1.1.2/lib/lookups.pl | 142 + .../oggvorbis.mod/libvorbis-1.1.2/lib/lpc.c | 149 + .../oggvorbis.mod/libvorbis-1.1.2/lib/lpc.h | 29 + .../oggvorbis.mod/libvorbis-1.1.2/lib/lsp.c | 455 + .../oggvorbis.mod/libvorbis-1.1.2/lib/lsp.h | 28 + .../libvorbis-1.1.2/lib/mapping0.c | 844 + .../libvorbis-1.1.2/lib/masking.h | 785 + .../oggvorbis.mod/libvorbis-1.1.2/lib/mdct.c | 564 + .../oggvorbis.mod/libvorbis-1.1.2/lib/mdct.h | 83 + .../oggvorbis.mod/libvorbis-1.1.2/lib/misc.h | 52 + .../libvorbis-1.1.2/lib/modes/floor_all.h | 248 + .../libvorbis-1.1.2/lib/modes/psych_11.h | 51 + .../libvorbis-1.1.2/lib/modes/psych_16.h | 129 + .../libvorbis-1.1.2/lib/modes/psych_44.h | 666 + .../libvorbis-1.1.2/lib/modes/psych_8.h | 102 + .../libvorbis-1.1.2/lib/modes/residue_16.h | 163 + .../libvorbis-1.1.2/lib/modes/residue_44.h | 294 + .../libvorbis-1.1.2/lib/modes/residue_44u.h | 318 + .../libvorbis-1.1.2/lib/modes/residue_8.h | 97 + .../libvorbis-1.1.2/lib/modes/setup_11.h | 141 + .../libvorbis-1.1.2/lib/modes/setup_16.h | 149 + .../libvorbis-1.1.2/lib/modes/setup_22.h | 128 + .../libvorbis-1.1.2/lib/modes/setup_32.h | 132 + .../libvorbis-1.1.2/lib/modes/setup_44.h | 107 + .../libvorbis-1.1.2/lib/modes/setup_44u.h | 74 + .../libvorbis-1.1.2/lib/modes/setup_8.h | 146 + .../libvorbis-1.1.2/lib/modes/setup_X.h | 226 + .../oggvorbis.mod/libvorbis-1.1.2/lib/os.h | 159 + .../oggvorbis.mod/libvorbis-1.1.2/lib/psy.c | 1224 + .../oggvorbis.mod/libvorbis-1.1.2/lib/psy.h | 186 + .../libvorbis-1.1.2/lib/psytune.c | 521 + .../libvorbis-1.1.2/lib/registry.c | 46 + .../libvorbis-1.1.2/lib/registry.h | 32 + .../oggvorbis.mod/libvorbis-1.1.2/lib/res0.c | 909 + .../libvorbis-1.1.2/lib/scales.h | 86 + .../libvorbis-1.1.2/lib/sharedbook.c | 734 + .../libvorbis-1.1.2/lib/smallft.c | 1255 + .../libvorbis-1.1.2/lib/smallft.h | 34 + .../libvorbis-1.1.2/lib/synthesis.c | 170 + .../oggvorbis.mod/libvorbis-1.1.2/lib/tone.c | 54 + .../libvorbis-1.1.2/lib/vorbisenc.c | 1184 + .../libvorbis-1.1.2/lib/vorbisfile.c | 1981 ++ .../libvorbis-1.1.2/lib/window.c | 2136 ++ .../libvorbis-1.1.2/lib/window.h | 26 + mod/pub.mod/oggvorbis.mod/oggdecoder.c | 78 + mod/pub.mod/oggvorbis.mod/oggvorbis.bmx | 60 + mod/pub.mod/openal.mod/openal.bmx | 1325 + mod/pub.mod/openal.mod/openal.c | 89 + mod/pub.mod/opengl.mod/doc/intro.bbdoc | 5 + mod/pub.mod/opengl.mod/glu.bmx | 60 + mod/pub.mod/opengl.mod/opengl.bmx | 900 + mod/pub.mod/stdc.mod/stdc.bmx | 207 + mod/pub.mod/stdc.mod/stdc.c | 487 + mod/pub.mod/win32.mod/com.bmx | 423 + mod/pub.mod/win32.mod/commctrl.bmx | 1583 ++ mod/pub.mod/win32.mod/commdlg.bmx | 80 + mod/pub.mod/win32.mod/gdi32.bmx | 517 + mod/pub.mod/win32.mod/kernel32.bmx | 48 + mod/pub.mod/win32.mod/richedit.bmx | 1807 ++ mod/pub.mod/win32.mod/user32.bmx | 833 + mod/pub.mod/win32.mod/win32.bmx | 46 + mod/pub.mod/win32.mod/winmm.bmx | 6 + mod/pub.mod/zlib.mod/adler32.c | 149 + mod/pub.mod/zlib.mod/algorithm.txt | 209 + mod/pub.mod/zlib.mod/compress.c | 79 + mod/pub.mod/zlib.mod/crc32.c | 423 + mod/pub.mod/zlib.mod/crc32.h | 441 + mod/pub.mod/zlib.mod/deflate.c | 1736 ++ mod/pub.mod/zlib.mod/deflate.h | 331 + mod/pub.mod/zlib.mod/example.c | 565 + mod/pub.mod/zlib.mod/gzio.c | 1026 + mod/pub.mod/zlib.mod/infback.c | 623 + mod/pub.mod/zlib.mod/inffast.c | 318 + mod/pub.mod/zlib.mod/inffast.h | 11 + mod/pub.mod/zlib.mod/inffixed.h | 94 + mod/pub.mod/zlib.mod/inflate.c | 1368 + mod/pub.mod/zlib.mod/inflate.h | 115 + mod/pub.mod/zlib.mod/inftrees.c | 329 + mod/pub.mod/zlib.mod/inftrees.h | 55 + mod/pub.mod/zlib.mod/minigzip.c | 322 + mod/pub.mod/zlib.mod/trees.c | 1219 + mod/pub.mod/zlib.mod/trees.h | 128 + mod/pub.mod/zlib.mod/uncompr.c | 61 + mod/pub.mod/zlib.mod/zconf.h | 332 + mod/pub.mod/zlib.mod/zlib.bmx | 48 + mod/pub.mod/zlib.mod/zlib.h | 1357 + mod/pub.mod/zlib.mod/zlib.html | 971 + mod/pub.mod/zlib.mod/zutil.c | 318 + mod/pub.mod/zlib.mod/zutil.h | 269 + 1782 files changed, 635927 insertions(+) create mode 100644 mod/brl.mod/appstub.mod/appstub.bmx create mode 100644 mod/brl.mod/appstub.mod/appstub.linux.c create mode 100644 mod/brl.mod/appstub.mod/appstub.macos.m create mode 100644 mod/brl.mod/appstub.mod/appstub.win32.c create mode 100644 mod/brl.mod/appstub.mod/debugger.stdio.bmx create mode 100644 mod/brl.mod/appstub.mod/debugger_mt.stdio.bmx create mode 100644 mod/brl.mod/audio.mod/audio.bmx create mode 100644 mod/brl.mod/audio.mod/doc/allocchannel.bmx create mode 100644 mod/brl.mod/audio.mod/doc/channelplaying.bmx create mode 100644 mod/brl.mod/audio.mod/doc/cuesound.bmx create mode 100644 mod/brl.mod/audio.mod/doc/intro.bbdoc create mode 100644 mod/brl.mod/audio.mod/doc/loadsound.bmx create mode 100644 mod/brl.mod/audio.mod/doc/playsound.bmx create mode 100644 mod/brl.mod/audio.mod/doc/setchanneldepth.bmx create mode 100644 mod/brl.mod/audio.mod/doc/setchannelpan.bmx create mode 100644 mod/brl.mod/audio.mod/doc/setchannelrate.bmx create mode 100644 mod/brl.mod/audio.mod/doc/setchannelvolume.bmx create mode 100644 mod/brl.mod/audio.mod/doc/shoot.wav create mode 100644 mod/brl.mod/audio.mod/doc/stopchannel.bmx create mode 100644 mod/brl.mod/audiosample.mod/audiosample.bmx create mode 100644 mod/brl.mod/audiosample.mod/doc/createaudiosample.bmx create mode 100644 mod/brl.mod/audiosample.mod/doc/intro.bbdoc create mode 100644 mod/brl.mod/audiosample.mod/sample.bmx create mode 100644 mod/brl.mod/bank.mod/bank.bmx create mode 100644 mod/brl.mod/bank.mod/doc/intro.bbdoc create mode 100644 mod/brl.mod/bankstream.mod/bankstream.bmx create mode 100644 mod/brl.mod/bankstream.mod/doc/intro.bbdoc create mode 100644 mod/brl.mod/basic.mod/basic.bmx create mode 100644 mod/brl.mod/blitz.mod/blitz.bmx create mode 100644 mod/brl.mod/blitz.mod/blitz.c create mode 100644 mod/brl.mod/blitz.mod/blitz.h create mode 100644 mod/brl.mod/blitz.mod/blitz_app.c create mode 100644 mod/brl.mod/blitz.mod/blitz_app.h create mode 100644 mod/brl.mod/blitz.mod/blitz_array.c create mode 100644 mod/brl.mod/blitz.mod/blitz_array.h create mode 100644 mod/brl.mod/blitz.mod/blitz_bbdoc.bmx create mode 100644 mod/brl.mod/blitz.mod/blitz_cclib.c create mode 100644 mod/brl.mod/blitz.mod/blitz_cclib.h create mode 100644 mod/brl.mod/blitz.mod/blitz_classes.i create mode 100644 mod/brl.mod/blitz.mod/blitz_debug.c create mode 100644 mod/brl.mod/blitz.mod/blitz_debug.h create mode 100644 mod/brl.mod/blitz.mod/blitz_ex.c create mode 100644 mod/brl.mod/blitz.mod/blitz_ex.h create mode 100644 mod/brl.mod/blitz.mod/blitz_ex.macos.ppc.s create mode 100644 mod/brl.mod/blitz.mod/blitz_gc.c create mode 100644 mod/brl.mod/blitz.mod/blitz_gc.h create mode 100644 mod/brl.mod/blitz.mod/blitz_gc.macos.ppc.s create mode 100644 mod/brl.mod/blitz.mod/blitz_gc_ms.c create mode 100644 mod/brl.mod/blitz.mod/blitz_gc_rc.c create mode 100644 mod/brl.mod/blitz.mod/blitz_handle.c create mode 100644 mod/brl.mod/blitz.mod/blitz_handle.h create mode 100644 mod/brl.mod/blitz.mod/blitz_incbin.c create mode 100644 mod/brl.mod/blitz.mod/blitz_incbin.h create mode 100644 mod/brl.mod/blitz.mod/blitz_memory.c create mode 100644 mod/brl.mod/blitz.mod/blitz_memory.h create mode 100644 mod/brl.mod/blitz.mod/blitz_module.c create mode 100644 mod/brl.mod/blitz.mod/blitz_module.h create mode 100644 mod/brl.mod/blitz.mod/blitz_object.c create mode 100644 mod/brl.mod/blitz.mod/blitz_object.h create mode 100644 mod/brl.mod/blitz.mod/blitz_string.c create mode 100644 mod/brl.mod/blitz.mod/blitz_string.h create mode 100644 mod/brl.mod/blitz.mod/blitz_thread.c create mode 100644 mod/brl.mod/blitz.mod/blitz_thread.h create mode 100644 mod/brl.mod/blitz.mod/blitz_types.c create mode 100644 mod/brl.mod/blitz.mod/blitz_types.h create mode 100644 mod/brl.mod/blitz.mod/blitz_unicode.h create mode 100644 mod/brl.mod/blitz.mod/doc/abs.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/abstract.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/acos.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/and.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/appargs.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/appdir.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/appfile.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/array.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/asc.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/asin.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/assert.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/atan.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/atan2.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/byte.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/case.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/catch.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/ceil.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/chr.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/const.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/continue.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/cos.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/default.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/defdata.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/delete.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/double.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/eachin.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/else.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/elseif.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/end.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/endextern.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/endfunction.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/endif.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/endmethod.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/endrem.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/endselect.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/endtry.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/endtype.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/exit.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/extends.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/extern.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/false.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/field.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/final.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/float.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/floor.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/for.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/forever.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/function.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/gcmalloc.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/global.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/goto.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/if.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/import.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/incbin.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/incbinlen.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/incbinptr.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/int.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/intro.bbdoc create mode 100644 mod/brl.mod/blitz.mod/doc/launchdir.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/len.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/local.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/log.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/log10.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/long.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/maxim.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/method.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/minim.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/mod.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/module.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/moduleinfo.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/new.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/next.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/not.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/null.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/object.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/onend.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/or.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/pi.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/private.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/protected.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/ptr.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/public.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/release.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/rem.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/repeat.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/restoredata.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/return.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/runtimeerror.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/sar.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/select.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/self.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/sgn.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/shl.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/short.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/shr.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/sin.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/sizeof.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/sortarray.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/sqr.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/step.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/strict.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/string.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/stringfind.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/super.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/tan.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/then.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/throw.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/to.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/true.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/try.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/type.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/until.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/var.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/varptr.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/wend.bmx create mode 100644 mod/brl.mod/blitz.mod/doc/while.bmx create mode 100644 mod/brl.mod/bmploader.mod/bmploader.bmx create mode 100644 mod/brl.mod/d3d7max2d.mod/d3d7max2d.bmx create mode 100644 mod/brl.mod/d3d9max2d.mod/d3d9max2d.bmx create mode 100644 mod/brl.mod/data.mod/data.bmx create mode 100644 mod/brl.mod/directsoundaudio.mod/directsoundaudio.bmx create mode 100644 mod/brl.mod/dxgraphics.mod/d3d7graphics.bmx create mode 100644 mod/brl.mod/dxgraphics.mod/d3d9graphics.bmx create mode 100644 mod/brl.mod/dxgraphics.mod/dxgraphics.bmx create mode 100644 mod/brl.mod/endianstream.mod/doc/intro.bbdoc create mode 100644 mod/brl.mod/endianstream.mod/endianstream.bmx create mode 100644 mod/brl.mod/event.mod/doc/intro.bbdoc create mode 100644 mod/brl.mod/event.mod/event.bmx create mode 100644 mod/brl.mod/event.mod/event.h create mode 100644 mod/brl.mod/eventqueue.mod/doc/intro.bbdoc create mode 100644 mod/brl.mod/eventqueue.mod/eventqueue.bmx create mode 100644 mod/brl.mod/filesystem.mod/doc/changedir.bmx create mode 100644 mod/brl.mod/filesystem.mod/doc/createdir.bmx create mode 100644 mod/brl.mod/filesystem.mod/doc/createfile.bmx create mode 100644 mod/brl.mod/filesystem.mod/doc/currentdir.bmx create mode 100644 mod/brl.mod/filesystem.mod/doc/deletedir.bmx create mode 100644 mod/brl.mod/filesystem.mod/doc/deletefile.bmx create mode 100644 mod/brl.mod/filesystem.mod/doc/extractdir.bmx create mode 100644 mod/brl.mod/filesystem.mod/doc/extractext.bmx create mode 100644 mod/brl.mod/filesystem.mod/doc/filemode.bmx create mode 100644 mod/brl.mod/filesystem.mod/doc/filesize.bmx create mode 100644 mod/brl.mod/filesystem.mod/doc/filetime.bmx create mode 100644 mod/brl.mod/filesystem.mod/doc/filetype.bmx create mode 100644 mod/brl.mod/filesystem.mod/doc/intro.bbdoc create mode 100644 mod/brl.mod/filesystem.mod/doc/loaddir.bmx create mode 100644 mod/brl.mod/filesystem.mod/doc/openfile.bmx create mode 100644 mod/brl.mod/filesystem.mod/doc/readdir.bmx create mode 100644 mod/brl.mod/filesystem.mod/doc/readfile.bmx create mode 100644 mod/brl.mod/filesystem.mod/doc/realpath.bmx create mode 100644 mod/brl.mod/filesystem.mod/doc/setfilemode.bmx create mode 100644 mod/brl.mod/filesystem.mod/doc/stripall.bmx create mode 100644 mod/brl.mod/filesystem.mod/doc/stripdir.bmx create mode 100644 mod/brl.mod/filesystem.mod/doc/stripext.bmx create mode 100644 mod/brl.mod/filesystem.mod/doc/stripslash.bmx create mode 100644 mod/brl.mod/filesystem.mod/doc/writefile.bmx create mode 100644 mod/brl.mod/filesystem.mod/filesystem.bmx create mode 100644 mod/brl.mod/font.mod/font.bmx create mode 100644 mod/brl.mod/freeaudioaudio.mod/freeaudioaudio.bmx create mode 100644 mod/brl.mod/freetypefont.mod/freetypefont.bmx create mode 100644 mod/brl.mod/glgraphics.mod/gldrawtextfont.bin create mode 100644 mod/brl.mod/glgraphics.mod/glgraphics.bmx create mode 100644 mod/brl.mod/glgraphics.mod/glgraphics.linux.c create mode 100644 mod/brl.mod/glgraphics.mod/glgraphics.macos.m create mode 100644 mod/brl.mod/glgraphics.mod/glgraphics.win32.c create mode 100644 mod/brl.mod/glmax2d.mod/glmax2d.bmx create mode 100644 mod/brl.mod/glmax2d.mod/rectnode.bmx create mode 100644 mod/brl.mod/gnet.mod/doc/intro.bbdoc create mode 100644 mod/brl.mod/gnet.mod/gnet.bmx create mode 100644 mod/brl.mod/graphics.mod/doc/graphicsmodes.bmx create mode 100644 mod/brl.mod/graphics.mod/doc/intro.bbdoc create mode 100644 mod/brl.mod/graphics.mod/doc/setgraphicsdriver.bmx create mode 100644 mod/brl.mod/graphics.mod/graphics.bmx create mode 100644 mod/brl.mod/hook.mod/doc/addhook.bmx create mode 100644 mod/brl.mod/hook.mod/doc/intro.bbdoc create mode 100644 mod/brl.mod/hook.mod/hook.bmx create mode 100644 mod/brl.mod/httpstream.mod/httpstream.bmx create mode 100644 mod/brl.mod/jpgloader.mod/jpgloader.bmx create mode 100644 mod/brl.mod/keycodes.mod/doc/intro.bbdoc create mode 100644 mod/brl.mod/keycodes.mod/keycodes.bmx create mode 100644 mod/brl.mod/keycodes.mod/keycodes.h create mode 100644 mod/brl.mod/linkedlist.mod/doc/createlist.bmx create mode 100644 mod/brl.mod/linkedlist.mod/doc/intro.bbdoc create mode 100644 mod/brl.mod/linkedlist.mod/linkedlist.bmx create mode 100644 mod/brl.mod/map.mod/map.bmx create mode 100644 mod/brl.mod/math.mod/math.bmx create mode 100644 mod/brl.mod/math.mod/math.c create mode 100644 mod/brl.mod/max2d.mod/blitz.fon create mode 100644 mod/brl.mod/max2d.mod/blitzfont.bin create mode 100644 mod/brl.mod/max2d.mod/convfont.bmx create mode 100644 mod/brl.mod/max2d.mod/doc/bullet.png create mode 100644 mod/brl.mod/max2d.mod/doc/cls.bmx create mode 100644 mod/brl.mod/max2d.mod/doc/collideimage.bmx create mode 100644 mod/brl.mod/max2d.mod/doc/createimage.bmx create mode 100644 mod/brl.mod/max2d.mod/doc/drawline.bmx create mode 100644 mod/brl.mod/max2d.mod/doc/drawoval.bmx create mode 100644 mod/brl.mod/max2d.mod/doc/drawpoly.bmx create mode 100644 mod/brl.mod/max2d.mod/doc/drawrect.bmx create mode 100644 mod/brl.mod/max2d.mod/doc/drawtext.bmx create mode 100644 mod/brl.mod/max2d.mod/doc/grabimage.bmx create mode 100644 mod/brl.mod/max2d.mod/doc/graphics.bmx create mode 100644 mod/brl.mod/max2d.mod/doc/intro.bbdoc create mode 100644 mod/brl.mod/max2d.mod/doc/plot.bmx create mode 100644 mod/brl.mod/max2d.mod/driver.bmx create mode 100644 mod/brl.mod/max2d.mod/image.bmx create mode 100644 mod/brl.mod/max2d.mod/imagefont.bmx create mode 100644 mod/brl.mod/max2d.mod/max2d.bmx create mode 100644 mod/brl.mod/maxlua.mod/doc/intro.bbdoc create mode 100644 mod/brl.mod/maxlua.mod/lua_driver.bmx create mode 100644 mod/brl.mod/maxlua.mod/lua_object.c create mode 100644 mod/brl.mod/maxlua.mod/maxlua.bmx create mode 100644 mod/brl.mod/maxutil.mod/maxutil.bmx create mode 100644 mod/brl.mod/oggloader.mod/oggloader.bmx create mode 100644 mod/brl.mod/openalaudio.mod/openalaudio.bmx create mode 100644 mod/brl.mod/pixmap.mod/doc/intro.bbdoc create mode 100644 mod/brl.mod/pixmap.mod/pixel.bmx create mode 100644 mod/brl.mod/pixmap.mod/pixmap.bmx create mode 100644 mod/brl.mod/pngloader.mod/pngloader.bmx create mode 100644 mod/brl.mod/polledinput.mod/doc/appterminate.bmx create mode 100644 mod/brl.mod/polledinput.mod/doc/intro.bbdoc create mode 100644 mod/brl.mod/polledinput.mod/doc/keydown.bmx create mode 100644 mod/brl.mod/polledinput.mod/doc/keyhit.bmx create mode 100644 mod/brl.mod/polledinput.mod/doc/mousedown.bmx create mode 100644 mod/brl.mod/polledinput.mod/doc/mousehit.bmx create mode 100644 mod/brl.mod/polledinput.mod/doc/mousex.bmx create mode 100644 mod/brl.mod/polledinput.mod/doc/mousey.bmx create mode 100644 mod/brl.mod/polledinput.mod/doc/mousez.bmx create mode 100644 mod/brl.mod/polledinput.mod/doc/movemouse.bmx create mode 100644 mod/brl.mod/polledinput.mod/polledinput.bmx create mode 100644 mod/brl.mod/ramstream.mod/ramstream.bmx create mode 100644 mod/brl.mod/random.mod/doc/intro.bbdoc create mode 100644 mod/brl.mod/random.mod/doc/rand.bmx create mode 100644 mod/brl.mod/random.mod/doc/rnd.bmx create mode 100644 mod/brl.mod/random.mod/doc/rnddouble.bmx create mode 100644 mod/brl.mod/random.mod/doc/rndfloat.bmx create mode 100644 mod/brl.mod/random.mod/doc/rndseed.bmx create mode 100644 mod/brl.mod/random.mod/doc/seedrnd.bmx create mode 100644 mod/brl.mod/random.mod/random.bmx create mode 100644 mod/brl.mod/reflection.mod/doc/intro.bbdoc create mode 100644 mod/brl.mod/reflection.mod/reflection.bmx create mode 100644 mod/brl.mod/reflection.mod/reflection.cpp create mode 100644 mod/brl.mod/retro.mod/doc/intro.bbdoc create mode 100644 mod/brl.mod/retro.mod/retro.bmx create mode 100644 mod/brl.mod/socket.mod/socket.bmx create mode 100644 mod/brl.mod/socketstream.mod/socketstream.bmx create mode 100644 mod/brl.mod/standardio.mod/doc/input.bmx create mode 100644 mod/brl.mod/standardio.mod/doc/intro.bbdoc create mode 100644 mod/brl.mod/standardio.mod/doc/print.bmx create mode 100644 mod/brl.mod/standardio.mod/standardio.bmx create mode 100644 mod/brl.mod/stream.mod/doc/intro.bbdoc create mode 100644 mod/brl.mod/stream.mod/doc/readstream.bmx create mode 100644 mod/brl.mod/stream.mod/doc/writestream.bmx create mode 100644 mod/brl.mod/stream.mod/stream.bmx create mode 100644 mod/brl.mod/system.mod/doc/confirm.bmx create mode 100644 mod/brl.mod/system.mod/doc/createtimer.bmx create mode 100644 mod/brl.mod/system.mod/doc/currentdate.bmx create mode 100644 mod/brl.mod/system.mod/doc/currenttime.bmx create mode 100644 mod/brl.mod/system.mod/doc/delay.bmx create mode 100644 mod/brl.mod/system.mod/doc/intro.bbdoc create mode 100644 mod/brl.mod/system.mod/doc/millisecs.bmx create mode 100644 mod/brl.mod/system.mod/doc/notify.bmx create mode 100644 mod/brl.mod/system.mod/doc/proceed.bmx create mode 100644 mod/brl.mod/system.mod/doc/requestdir.bmx create mode 100644 mod/brl.mod/system.mod/doc/requestfile.bmx create mode 100644 mod/brl.mod/system.mod/doc/waittimer.bmx create mode 100644 mod/brl.mod/system.mod/driver.bmx create mode 100644 mod/brl.mod/system.mod/system.bmx create mode 100644 mod/brl.mod/system.mod/system.c create mode 100644 mod/brl.mod/system.mod/system.h create mode 100644 mod/brl.mod/system.mod/system.linux.bmx create mode 100644 mod/brl.mod/system.mod/system.linux.c create mode 100644 mod/brl.mod/system.mod/system.macos.bmx create mode 100644 mod/brl.mod/system.mod/system.macos.m create mode 100644 mod/brl.mod/system.mod/system.win32.bmx create mode 100644 mod/brl.mod/system.mod/system.win32.c create mode 100644 mod/brl.mod/textstream.mod/textstream.bmx create mode 100644 mod/brl.mod/tgaloader.mod/tgaloader.bmx create mode 100644 mod/brl.mod/threads.mod/doc/createmutex.bmx create mode 100644 mod/brl.mod/threads.mod/doc/createsemaphore.bmx create mode 100644 mod/brl.mod/threads.mod/doc/createthread.bmx create mode 100644 mod/brl.mod/threads.mod/doc/intro.bbdoc create mode 100644 mod/brl.mod/threads.mod/threads.bmx create mode 100644 mod/brl.mod/threads.mod/threads.c create mode 100644 mod/brl.mod/timer.mod/doc/waittimer.bmx create mode 100644 mod/brl.mod/timer.mod/timer.bmx create mode 100644 mod/brl.mod/timer.mod/timer.linux.c create mode 100644 mod/brl.mod/timer.mod/timer.macos.m create mode 100644 mod/brl.mod/timer.mod/timer.win32.c create mode 100644 mod/brl.mod/wavloader.mod/wavloader.bmx create mode 100644 mod/maxgui.mod/cocoamaxgui.mod/cocoa.macos.m create mode 100644 mod/maxgui.mod/cocoamaxgui.mod/cocoagui.bmx create mode 100644 mod/maxgui.mod/cocoamaxgui.mod/cocoamaxgui.bmx create mode 100644 mod/maxgui.mod/cocoamaxgui.mod/version.txt create mode 100644 mod/maxgui.mod/drivers.mod/drivers.bmx create mode 100644 mod/maxgui.mod/drivers.mod/version.txt create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/CHANGES create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/CREDITS create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Enumerations.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Adjuster.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_BMP_Image.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Bitmap.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Box.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Browser.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Browser_.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Button.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Cairo.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Cairo_Window.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Chart.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Check_Browser.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Check_Button.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Choice.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Clock.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Color_Chooser.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Counter.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Device.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Dial.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Double_Window.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Export.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_File_Browser.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_File_Chooser.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_File_Icon.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_File_Input.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Fill_Dial.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Fill_Slider.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Float_Input.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_FormsBitmap.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_FormsPixmap.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Free.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_GIF_Image.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Gl_Window.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Group.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Help_Dialog.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Help_View.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Hold_Browser.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Hor_Fill_Slider.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Hor_Nice_Slider.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Hor_Slider.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Hor_Value_Slider.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Image.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Input.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Input_.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Input_Choice.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Int_Input.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_JPEG_Image.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Light_Button.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Line_Dial.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Menu.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Menu_.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Menu_Bar.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Menu_Button.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Menu_Item.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Menu_Window.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Multi_Browser.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Multi_Label.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Multiline_Input.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Multiline_Output.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Native_File_Chooser.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Native_File_Chooser_FLTK.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Native_File_Chooser_MAC.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Native_File_Chooser_WIN32.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Nice_Slider.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Object.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Output.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Overlay_Window.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_PNG_Image.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_PNM_Image.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Pack.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Paged_Device.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Pixmap.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Plugin.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Positioner.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_PostScript.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Preferences.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Printer.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Progress.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_RGB_Image.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Radio_Button.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Radio_Light_Button.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Radio_Round_Button.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Repeat_Button.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Return_Button.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Roller.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Round_Button.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Round_Clock.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Scroll.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Scrollbar.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Secret_Input.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Select_Browser.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Shared_Image.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Simple_Counter.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Single_Window.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Slider.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Spinner.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Sys_Menu_Bar.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Tabs.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Text_Buffer.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Text_Display.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Text_Editor.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Tile.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Tiled_Image.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Timer.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Toggle_Button.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Toggle_Light_Button.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Toggle_Round_Button.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Tooltip.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Tree.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Tree_Item.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Tree_Item_Array.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Tree_Prefs.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Valuator.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Value_Input.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Value_Output.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Value_Slider.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Widget.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Window.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Wizard.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_XBM_Image.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_XPM_Image.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Flmm_Tabs.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Makefile.in create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/Xutf8.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/dirent.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/filename.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/fl_ask.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/fl_draw.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/fl_message.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/fl_show_colormap.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/fl_show_input.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/fl_types.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/fl_utf8.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/forms.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/gl.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/gl2opengl.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/gl_draw.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/glu.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/glut.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/mac.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/math.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/names.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/win32.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FL/x.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU/CHANGES create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU/FluSimpleString.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU/FluVectorClass.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Button.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Chat_Buffer.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Choice_Group.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Collapsable_Group.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Combo_Box.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Combo_List.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Combo_Tree.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_DND.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Dual_Progress_Meter.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Dual_Slider.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Enumerations.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_File_Chooser.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Float_Input.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_GL_Canvas.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_GL_Window.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Helpers.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Int_Input.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Label.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Link_Button.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Output.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Progress.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Progress_Meter.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Return_Button.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Separator.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Simple_Group.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Spinner.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Toggle_Group.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Tree_Browser.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Wrap_Group.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU/LICENSE create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU/Makefile create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU/README create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU/flu_export.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU/flu_file_chooser_pixmaps.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU/flu_pixmaps.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU_src/FluSimpleString.cpp create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Button.cpp create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Chat_Buffer.cpp create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Choice_Group.cpp create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Collapsable_Group.cpp create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Combo_Box.cpp create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Combo_List.cpp create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Combo_Tree.cpp create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_DND.cpp create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Dual_Progress_Meter.cpp create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Dual_Slider.cpp create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_File_Chooser.cpp create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Float_Input.cpp create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_GL_Canvas.cpp create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_GL_Window.cpp create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Helpers.cpp create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Int_Input.cpp create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Label.cpp create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Link_Button.cpp create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Output.cpp create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Progress.cpp create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Progress_Meter.cpp create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Return_Button.cpp create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Separator.cpp create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Simple_Group.cpp create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Spinner.cpp create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Toggle_Group.cpp create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Tree_Browser.cpp create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Wrap_Group.cpp create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU_src/flu_file_chooser_pixmaps.cpp create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU_src/flu_pixmaps.cpp create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/FLU_src/linux_path_info.c create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/Flmm/COPYING create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/Flmm/CREDITS create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/Flmm/readme.txt create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/README create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/cocoa_bridge.mm create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/config.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/doc/intro.bbdoc create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/fltkdecls.bmx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/fltkfonts.bmx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/fltkglue.cpp create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/fltkgui.bmx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/fltkimports.bmx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/fltkmaxgui.bmx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/fltksystem.bmx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/maxgui_templates.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/CMakeLists.txt create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Adjuster.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_BMP_Image.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Bitmap.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Box.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Browser.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Browser_.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Browser_load.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Button.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Chart.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Check_Browser.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Check_Button.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Choice.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Clock.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Color_Chooser.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Counter.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Device.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Dial.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Double_Window.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_File_Browser.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_File_Chooser.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_File_Chooser.fl create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_File_Chooser2.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_File_Icon.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_File_Icon2.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_File_Input.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Font.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_GDI_Printer.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_GIF_Image.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Gl_Choice.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Gl_Choice.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Gl_Device_Plugin.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Gl_Overlay.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Gl_Window.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Group.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Help_Dialog.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Help_Dialog.fl create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Help_Dialog_Dox.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Help_View.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Image.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Input.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Input_.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_JPEG_Image.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Light_Button.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Menu.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Menu_.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Menu_Bar.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Menu_Button.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Menu_Window.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Menu_add.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Menu_global.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Multi_Label.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Native_File_Chooser.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Native_File_Chooser_FLTK.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Native_File_Chooser_MAC.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Native_File_Chooser_WIN32.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Native_File_Chooser_common.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Overlay_Window.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_PNG_Image.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_PNM_Image.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Pack.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Paged_Device.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Pixmap.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Positioner.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_PostScript.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Preferences.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Printer.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Progress.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Quartz_Printer.mm create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Repeat_Button.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Return_Button.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Roller.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Round_Button.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Scroll.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Scrollbar.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Shared_Image.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Single_Window.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Slider.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Sys_Menu_Bar.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Tabs.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Text_Buffer.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Text_Display.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Text_Editor.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Tile.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Tiled_Image.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Tooltip.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Tree.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Tree_Item.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Tree_Item_Array.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Tree_Prefs.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Valuator.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Value_Input.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Value_Output.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Value_Slider.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Widget.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Window.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Window_fullscreen.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Window_hotspot.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Window_iconize.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Wizard.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_XBM_Image.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_XColor.H create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_XPM_Image.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_abort.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_add_idle.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_arg.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_cocoa.mm create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_compose.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_display.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_get_key.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_get_key_mac.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_get_key_win32.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_get_system_colors.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_grab.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_lock.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_mac.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_own_colormap.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_visual.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_win32.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Fl_x.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Flmm_Tabs.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/Makefile create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/aimm.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/allfiles.xbm create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/cgdebug.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/cmap.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/d1.xbm create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/d1_mask.xbm create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/dump_compose.c create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/ew.xbm create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/ew_mask.xbm create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fastarrow.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/filename_absolute.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/filename_expand.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/filename_ext.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/filename_isdir.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/filename_list.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/filename_match.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/filename_setext.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_arc.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_arci.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_ask.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_boxtype.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_call_main.c create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_cmap.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_color.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_color_mac.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_color_win32.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_cursor.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_curve.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_diamond_box.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_dnd.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_dnd_mac.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_dnd_win32.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_dnd_x.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_draw.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_draw_image.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_draw_image_mac.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_draw_image_win32.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_draw_pixmap.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_encoding_latin1.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_encoding_mac_roman.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_engraved_label.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_file_dir.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_font.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_font_mac.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_font_win32.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_font_x.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_font_xft.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_gtk.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_images_core.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_labeltype.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_line_style.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_open_uri.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_oval_box.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_overlay.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_overlay_visual.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_plastic.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_read_image.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_read_image_mac.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_read_image_win32.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_rect.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_round_box.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_rounded_box.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_scroll_area.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_set_font.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_set_fonts.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_set_fonts_mac.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_set_fonts_win32.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_set_fonts_x.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_set_fonts_xft.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_shadow_box.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_shortcut.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_show_colormap.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_symbols.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_utf.c create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_utf8.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/fl_vertex.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/flstring.c create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/flstring.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/forms_bitmap.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/forms_compatability.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/forms_free.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/forms_fselect.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/forms_pixmap.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/forms_timer.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/freeglut_geometry.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/freeglut_stroke_mono_roman.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/freeglut_stroke_roman.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/freeglut_teapot.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/freeglut_teapot_data.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/gl_draw.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/gl_start.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/glut_compatability.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/glut_font.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/makedepend create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/makefile.wat create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/mediumarrow.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/new.xbm create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/ns.xbm create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/ns_mask.xbm create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/numericsort.c create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/print_panel.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/print_panel.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/ps_image.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/scandir.c create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/scandir_win32.c create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/screen_xywh.cxx create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/slowarrow.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/tile.xpm create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/up.xbm create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/vsnprintf.c create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/COPYING create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/Makefile create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/README create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/Ximint.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/Xlibint.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/case.c create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/headers/case.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/headers/case_tbl.txt create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/headers/dingbats_.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/headers/spacing.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/headers/spacing_tbl.txt create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/headers/symbol_.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/headers/tbl.txt create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/imKStoUCS.c create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/is_right2left.c create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/is_spacing.c create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/keysym2Ucs.c create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/8bit_tab_to_h.c create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/COPYRIGHT create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/README create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/armscii_8.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/ascii.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/big5.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/big5_emacs.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/cjk_tab_to_h.c create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/cp1133.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/cp1251.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/cp1255.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/cp1256.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/cp936ext.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/gb2312.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/gbk_tab_to_h.c create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/georgian_academy.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/georgian_ps.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_1.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_10.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_11.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_13.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_14.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_15.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_16.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_2.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_3.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_4.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_5.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_6.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_7.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_8.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_9.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_9e.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/jisx0201.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/jisx0208.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/jisx0212.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/koi8_c.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/koi8_r.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/koi8_u.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/ksc5601.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/mulelao.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/tatar_cyr.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/tcvn.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/tis620.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/ucs2be.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/utf8.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/viscii.h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/makedepend create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/mk_wcwidth.c create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/stamp-h create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/stamp-h.in create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/test.c create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/test2.c create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/ucs2fontmap.c create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/ucs2fontmap.c.mini create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/utf8Input.c create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/utf8Utils.c create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/utf8Wrap.c create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/utils/INSTALL create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/utils/Makefile create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/utils/README create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/utils/case.sh create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/utils/conv_gen.c create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/utils/convert_map.c create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/utils/create_table.c create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/utils/euc_tw.c create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/utils/non_spacing.sh create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/utils/tbl_gen.sh create mode 100644 mod/maxgui.mod/fltkmaxgui.mod/version.txt create mode 100644 mod/maxgui.mod/localization.mod/doc/createlanguage.bmx create mode 100644 mod/maxgui.mod/localization.mod/doc/intro.bbdoc create mode 100644 mod/maxgui.mod/localization.mod/language.bmx create mode 100644 mod/maxgui.mod/localization.mod/localization.bmx create mode 100644 mod/maxgui.mod/localization.mod/version.txt create mode 100644 mod/maxgui.mod/maxgui.mod/doc/canvasbeginpaint.bmx create mode 100644 mod/maxgui.mod/maxgui.mod/doc/createbutton.bmx create mode 100644 mod/maxgui.mod/maxgui.mod/doc/createcanvas.bmx create mode 100644 mod/maxgui.mod/maxgui.mod/doc/createcombobox.bmx create mode 100644 mod/maxgui.mod/maxgui.mod/doc/createhtmlview.bmx create mode 100644 mod/maxgui.mod/maxgui.mod/doc/createlabel.bmx create mode 100644 mod/maxgui.mod/maxgui.mod/doc/createlistbox.bmx create mode 100644 mod/maxgui.mod/maxgui.mod/doc/createmenu.bmx create mode 100644 mod/maxgui.mod/maxgui.mod/doc/createpanel.bmx create mode 100644 mod/maxgui.mod/maxgui.mod/doc/createprogbar.bmx create mode 100644 mod/maxgui.mod/maxgui.mod/doc/createslider.bmx create mode 100644 mod/maxgui.mod/maxgui.mod/doc/createtabber.bmx create mode 100644 mod/maxgui.mod/maxgui.mod/doc/createtextarea.bmx create mode 100644 mod/maxgui.mod/maxgui.mod/doc/createtextfield.bmx create mode 100644 mod/maxgui.mod/maxgui.mod/doc/createtimer.bmx create mode 100644 mod/maxgui.mod/maxgui.mod/doc/createtoolbar.bmx create mode 100644 mod/maxgui.mod/maxgui.mod/doc/createtreeview.bmx create mode 100644 mod/maxgui.mod/maxgui.mod/doc/createwindow.bmx create mode 100644 mod/maxgui.mod/maxgui.mod/doc/fltkbuttons.png create mode 100644 mod/maxgui.mod/maxgui.mod/doc/fltkcombobox.png create mode 100644 mod/maxgui.mod/maxgui.mod/doc/fltklistbox.png create mode 100644 mod/maxgui.mod/maxgui.mod/doc/fltkmenu.png create mode 100644 mod/maxgui.mod/maxgui.mod/doc/fltkpanels.png create mode 100644 mod/maxgui.mod/maxgui.mod/doc/fltkprogbar.png create mode 100644 mod/maxgui.mod/maxgui.mod/doc/fltksliders.png create mode 100644 mod/maxgui.mod/maxgui.mod/doc/fltktabber.png create mode 100644 mod/maxgui.mod/maxgui.mod/doc/fltktextarea.png create mode 100644 mod/maxgui.mod/maxgui.mod/doc/fltktextfield.png create mode 100644 mod/maxgui.mod/maxgui.mod/doc/fltktreeview.png create mode 100644 mod/maxgui.mod/maxgui.mod/doc/fltkwindow.png create mode 100644 mod/maxgui.mod/maxgui.mod/doc/gadgetclass.bmx create mode 100644 mod/maxgui.mod/maxgui.mod/doc/intro.bbdoc create mode 100644 mod/maxgui.mod/maxgui.mod/doc/lookupguicolor.bmx create mode 100644 mod/maxgui.mod/maxgui.mod/doc/lookupguifont.bmx create mode 100644 mod/maxgui.mod/maxgui.mod/doc/osxbuttons.png create mode 100644 mod/maxgui.mod/maxgui.mod/doc/osxcombobox.png create mode 100644 mod/maxgui.mod/maxgui.mod/doc/osxlistbox.png create mode 100644 mod/maxgui.mod/maxgui.mod/doc/osxmenu.png create mode 100644 mod/maxgui.mod/maxgui.mod/doc/osxpanels.png create mode 100644 mod/maxgui.mod/maxgui.mod/doc/osxprogbar.png create mode 100644 mod/maxgui.mod/maxgui.mod/doc/osxsliders.png create mode 100644 mod/maxgui.mod/maxgui.mod/doc/osxtabber.png create mode 100644 mod/maxgui.mod/maxgui.mod/doc/osxtextarea.png create mode 100644 mod/maxgui.mod/maxgui.mod/doc/osxtextfield.png create mode 100644 mod/maxgui.mod/maxgui.mod/doc/osxtreeview.png create mode 100644 mod/maxgui.mod/maxgui.mod/doc/osxwindow.png create mode 100644 mod/maxgui.mod/maxgui.mod/doc/popupwindowmenu.bmx create mode 100644 mod/maxgui.mod/maxgui.mod/doc/redrawgadget.bmx create mode 100644 mod/maxgui.mod/maxgui.mod/doc/requestcolor.bmx create mode 100644 mod/maxgui.mod/maxgui.mod/doc/requestfont.bmx create mode 100644 mod/maxgui.mod/maxgui.mod/doc/setgadgetfilter.bmx create mode 100644 mod/maxgui.mod/maxgui.mod/doc/setpointer.bmx create mode 100644 mod/maxgui.mod/maxgui.mod/doc/toolbar.png create mode 100644 mod/maxgui.mod/maxgui.mod/doc/win32buttons.png create mode 100644 mod/maxgui.mod/maxgui.mod/doc/win32combobox.png create mode 100644 mod/maxgui.mod/maxgui.mod/doc/win32htmlview.png create mode 100644 mod/maxgui.mod/maxgui.mod/doc/win32listbox.png create mode 100644 mod/maxgui.mod/maxgui.mod/doc/win32menu.png create mode 100644 mod/maxgui.mod/maxgui.mod/doc/win32panels.png create mode 100644 mod/maxgui.mod/maxgui.mod/doc/win32progbar.png create mode 100644 mod/maxgui.mod/maxgui.mod/doc/win32sliders.png create mode 100644 mod/maxgui.mod/maxgui.mod/doc/win32tabber.png create mode 100644 mod/maxgui.mod/maxgui.mod/doc/win32textarea.png create mode 100644 mod/maxgui.mod/maxgui.mod/doc/win32textfield.png create mode 100644 mod/maxgui.mod/maxgui.mod/doc/win32toolbar.png create mode 100644 mod/maxgui.mod/maxgui.mod/doc/win32treeview.png create mode 100644 mod/maxgui.mod/maxgui.mod/doc/win32window.png create mode 100644 mod/maxgui.mod/maxgui.mod/driver.bmx create mode 100644 mod/maxgui.mod/maxgui.mod/event.bmx create mode 100644 mod/maxgui.mod/maxgui.mod/gadget.bmx create mode 100644 mod/maxgui.mod/maxgui.mod/gadgetitem.bmx create mode 100644 mod/maxgui.mod/maxgui.mod/guifont.bmx create mode 100644 mod/maxgui.mod/maxgui.mod/iconstrip.bmx create mode 100644 mod/maxgui.mod/maxgui.mod/maxgui.bmx create mode 100644 mod/maxgui.mod/maxgui.mod/maxgui.h create mode 100644 mod/maxgui.mod/maxgui.mod/version.txt create mode 100644 mod/maxgui.mod/proxygadgets.mod/doc/createhyperlink.bmx create mode 100644 mod/maxgui.mod/proxygadgets.mod/doc/createscrollpanel.bmx create mode 100644 mod/maxgui.mod/proxygadgets.mod/doc/createsplitter.bmx create mode 100644 mod/maxgui.mod/proxygadgets.mod/doc/scroll_dimensions.png create mode 100644 mod/maxgui.mod/proxygadgets.mod/doc/scroll_position.png create mode 100644 mod/maxgui.mod/proxygadgets.mod/hyperlink.bmx create mode 100644 mod/maxgui.mod/proxygadgets.mod/proxygadgets.bmx create mode 100644 mod/maxgui.mod/proxygadgets.mod/scrollpanel.bmx create mode 100644 mod/maxgui.mod/proxygadgets.mod/splitter.bmx create mode 100644 mod/maxgui.mod/proxygadgets.mod/version.txt create mode 100644 mod/maxgui.mod/win32maxguiex.mod/comdef.h create mode 100644 mod/maxgui.mod/win32maxguiex.mod/comutil.h create mode 100644 mod/maxgui.mod/win32maxguiex.mod/doc/intro.bbdoc create mode 100644 mod/maxgui.mod/win32maxguiex.mod/mshtmhst.h create mode 100644 mod/maxgui.mod/win32maxguiex.mod/mshtmlview.cpp create mode 100644 mod/maxgui.mod/win32maxguiex.mod/mshtmlview.h create mode 100644 mod/maxgui.mod/win32maxguiex.mod/tom.bmx create mode 100644 mod/maxgui.mod/win32maxguiex.mod/version.txt create mode 100644 mod/maxgui.mod/win32maxguiex.mod/win32maxguiex.bmx create mode 100644 mod/maxgui.mod/win32maxguiex.mod/winimports.bmx create mode 100644 mod/maxgui.mod/xpmanifest.mod/xpmanifest.bmx create mode 100644 mod/maxgui.mod/xpmanifest.mod/xpmanifest.o create mode 100644 mod/pub.mod/directx.mod/d3d.bmx create mode 100644 mod/pub.mod/directx.mod/d3d7.bmx create mode 100644 mod/pub.mod/directx.mod/d3d9.bmx create mode 100644 mod/pub.mod/directx.mod/d3d9x.bmx create mode 100644 mod/pub.mod/directx.mod/dd.bmx create mode 100644 mod/pub.mod/directx.mod/directx.bmx create mode 100644 mod/pub.mod/directx.mod/dsound.bmx create mode 100644 mod/pub.mod/enet.mod/api.txt create mode 100644 mod/pub.mod/enet.mod/design.txt create mode 100644 mod/pub.mod/enet.mod/enet.bmx create mode 100644 mod/pub.mod/enet.mod/host.c create mode 100644 mod/pub.mod/enet.mod/include/enet/enet.h create mode 100644 mod/pub.mod/enet.mod/include/enet/list.h create mode 100644 mod/pub.mod/enet.mod/include/enet/memory.h create mode 100644 mod/pub.mod/enet.mod/include/enet/protocol.h create mode 100644 mod/pub.mod/enet.mod/include/enet/time.h create mode 100644 mod/pub.mod/enet.mod/include/enet/types.h create mode 100644 mod/pub.mod/enet.mod/include/enet/unix.h create mode 100644 mod/pub.mod/enet.mod/include/enet/utility.h create mode 100644 mod/pub.mod/enet.mod/include/enet/win32.h create mode 100644 mod/pub.mod/enet.mod/license.txt create mode 100644 mod/pub.mod/enet.mod/list.c create mode 100644 mod/pub.mod/enet.mod/memory.c create mode 100644 mod/pub.mod/enet.mod/packet.c create mode 100644 mod/pub.mod/enet.mod/peer.c create mode 100644 mod/pub.mod/enet.mod/protocol.c create mode 100644 mod/pub.mod/enet.mod/tutorial.txt create mode 100644 mod/pub.mod/enet.mod/unix.c create mode 100644 mod/pub.mod/enet.mod/win32.c create mode 100644 mod/pub.mod/freeaudio.mod/alsadevice.cpp create mode 100644 mod/pub.mod/freeaudio.mod/audiodevice.h create mode 100644 mod/pub.mod/freeaudio.mod/coreaudiodevice.cpp create mode 100644 mod/pub.mod/freeaudio.mod/dsound.h create mode 100644 mod/pub.mod/freeaudio.mod/dsounddevice.cpp create mode 100644 mod/pub.mod/freeaudio.mod/freeaudio.bmx create mode 100644 mod/pub.mod/freeaudio.mod/freeaudio.cpp create mode 100644 mod/pub.mod/freeaudio.mod/freeaudio.h create mode 100644 mod/pub.mod/freeaudio.mod/freeaudioglue.cpp create mode 100644 mod/pub.mod/freeaudio.mod/freeaudioglue.h create mode 100644 mod/pub.mod/freeaudio.mod/mmdevice.cpp create mode 100644 mod/pub.mod/freeaudio.mod/ossdevice.cpp create mode 100644 mod/pub.mod/freejoy.mod/doc/intro.bbdoc create mode 100644 mod/pub.mod/freejoy.mod/doc/joycount.bmx create mode 100644 mod/pub.mod/freejoy.mod/freejoy.bmx create mode 100644 mod/pub.mod/freejoy.mod/freejoy.h create mode 100644 mod/pub.mod/freejoy.mod/freejoy.linux.c create mode 100644 mod/pub.mod/freejoy.mod/freejoy.macosx.c create mode 100644 mod/pub.mod/freejoy.mod/freejoy.win32.c create mode 100644 mod/pub.mod/freeprocess.mod/freeprocess.bmx create mode 100644 mod/pub.mod/freeprocess.mod/freeprocess.c create mode 100644 mod/pub.mod/freetype.mod/freetype.bmx create mode 100644 mod/pub.mod/freetype.mod/include/freetype/config/ftconfig.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/config/ftheader.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/config/ftmodule.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/config/ftoption.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/config/ftstdlib.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/freetype.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/ftadvanc.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/ftbbox.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/ftbdf.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/ftbitmap.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/ftcache.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/ftchapters.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/ftcid.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/fterrdef.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/fterrors.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/ftgasp.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/ftglyph.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/ftgxval.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/ftgzip.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/ftimage.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/ftincrem.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/ftlcdfil.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/ftlist.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/ftlzw.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/ftmac.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/ftmm.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/ftmodapi.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/ftmoderr.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/ftotval.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/ftoutln.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/ftpfr.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/ftrender.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/ftsizes.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/ftsnames.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/ftstroke.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/ftsynth.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/ftsystem.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/fttrigon.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/fttypes.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/ftwinfnt.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/ftxf86.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/internal/autohint.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/internal/ftcalc.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/internal/ftdebug.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/internal/ftdriver.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/internal/ftgloadr.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/internal/ftmemory.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/internal/ftobjs.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/internal/ftpic.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/internal/ftrfork.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/internal/ftserv.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/internal/ftstream.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/internal/fttrace.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/internal/ftvalid.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/internal/internal.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/internal/pcftypes.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/internal/psaux.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/internal/pshints.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/internal/services/svbdf.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/internal/services/svcid.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/internal/services/svgldict.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/internal/services/svgxval.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/internal/services/svkern.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/internal/services/svmm.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/internal/services/svotval.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/internal/services/svpfr.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/internal/services/svpostnm.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/internal/services/svpscmap.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/internal/services/svpsinfo.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/internal/services/svsfnt.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/internal/services/svttcmap.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/internal/services/svtteng.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/internal/services/svttglyf.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/internal/services/svwinfnt.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/internal/services/svxf86nm.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/internal/sfnt.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/internal/t1types.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/internal/tttypes.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/t1tables.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/ttnameid.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/tttables.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/tttags.h create mode 100644 mod/pub.mod/freetype.mod/include/freetype/ttunpat.h create mode 100644 mod/pub.mod/freetype.mod/include/ft2build.h create mode 100644 mod/pub.mod/freetype.mod/src/autofit/afangles.c create mode 100644 mod/pub.mod/freetype.mod/src/autofit/afangles.h create mode 100644 mod/pub.mod/freetype.mod/src/autofit/afcjk.c create mode 100644 mod/pub.mod/freetype.mod/src/autofit/afcjk.h create mode 100644 mod/pub.mod/freetype.mod/src/autofit/afdummy.c create mode 100644 mod/pub.mod/freetype.mod/src/autofit/afdummy.h create mode 100644 mod/pub.mod/freetype.mod/src/autofit/aferrors.h create mode 100644 mod/pub.mod/freetype.mod/src/autofit/afglobal.c create mode 100644 mod/pub.mod/freetype.mod/src/autofit/afglobal.h create mode 100644 mod/pub.mod/freetype.mod/src/autofit/afhints.c create mode 100644 mod/pub.mod/freetype.mod/src/autofit/afhints.h create mode 100644 mod/pub.mod/freetype.mod/src/autofit/afindic.c create mode 100644 mod/pub.mod/freetype.mod/src/autofit/afindic.h create mode 100644 mod/pub.mod/freetype.mod/src/autofit/aflatin.c create mode 100644 mod/pub.mod/freetype.mod/src/autofit/aflatin.h create mode 100644 mod/pub.mod/freetype.mod/src/autofit/aflatin2.c create mode 100644 mod/pub.mod/freetype.mod/src/autofit/aflatin2.h create mode 100644 mod/pub.mod/freetype.mod/src/autofit/afloader.c create mode 100644 mod/pub.mod/freetype.mod/src/autofit/afloader.h create mode 100644 mod/pub.mod/freetype.mod/src/autofit/afmodule.c create mode 100644 mod/pub.mod/freetype.mod/src/autofit/afmodule.h create mode 100644 mod/pub.mod/freetype.mod/src/autofit/afpic.c create mode 100644 mod/pub.mod/freetype.mod/src/autofit/afpic.h create mode 100644 mod/pub.mod/freetype.mod/src/autofit/aftypes.h create mode 100644 mod/pub.mod/freetype.mod/src/autofit/afwarp.c create mode 100644 mod/pub.mod/freetype.mod/src/autofit/afwarp.h create mode 100644 mod/pub.mod/freetype.mod/src/autofit/autofit.c create mode 100644 mod/pub.mod/freetype.mod/src/base/basepic.c create mode 100644 mod/pub.mod/freetype.mod/src/base/basepic.h create mode 100644 mod/pub.mod/freetype.mod/src/base/ftadvanc.c create mode 100644 mod/pub.mod/freetype.mod/src/base/ftapi.c create mode 100644 mod/pub.mod/freetype.mod/src/base/ftbase.c create mode 100644 mod/pub.mod/freetype.mod/src/base/ftbase.h create mode 100644 mod/pub.mod/freetype.mod/src/base/ftbbox.c create mode 100644 mod/pub.mod/freetype.mod/src/base/ftbdf.c create mode 100644 mod/pub.mod/freetype.mod/src/base/ftbitmap.c create mode 100644 mod/pub.mod/freetype.mod/src/base/ftcalc.c create mode 100644 mod/pub.mod/freetype.mod/src/base/ftcid.c create mode 100644 mod/pub.mod/freetype.mod/src/base/ftdbgmem.c create mode 100644 mod/pub.mod/freetype.mod/src/base/ftdebug.c create mode 100644 mod/pub.mod/freetype.mod/src/base/ftfstype.c create mode 100644 mod/pub.mod/freetype.mod/src/base/ftgasp.c create mode 100644 mod/pub.mod/freetype.mod/src/base/ftgloadr.c create mode 100644 mod/pub.mod/freetype.mod/src/base/ftglyph.c create mode 100644 mod/pub.mod/freetype.mod/src/base/ftgxval.c create mode 100644 mod/pub.mod/freetype.mod/src/base/ftinit.c create mode 100644 mod/pub.mod/freetype.mod/src/base/ftlcdfil.c create mode 100644 mod/pub.mod/freetype.mod/src/base/ftmac.c create mode 100644 mod/pub.mod/freetype.mod/src/base/ftmm.c create mode 100644 mod/pub.mod/freetype.mod/src/base/ftobjs.c create mode 100644 mod/pub.mod/freetype.mod/src/base/ftotval.c create mode 100644 mod/pub.mod/freetype.mod/src/base/ftoutln.c create mode 100644 mod/pub.mod/freetype.mod/src/base/ftpatent.c create mode 100644 mod/pub.mod/freetype.mod/src/base/ftpfr.c create mode 100644 mod/pub.mod/freetype.mod/src/base/ftpic.c create mode 100644 mod/pub.mod/freetype.mod/src/base/ftrfork.c create mode 100644 mod/pub.mod/freetype.mod/src/base/ftsnames.c create mode 100644 mod/pub.mod/freetype.mod/src/base/ftstream.c create mode 100644 mod/pub.mod/freetype.mod/src/base/ftstroke.c create mode 100644 mod/pub.mod/freetype.mod/src/base/ftsynth.c create mode 100644 mod/pub.mod/freetype.mod/src/base/ftsystem.c create mode 100644 mod/pub.mod/freetype.mod/src/base/fttrigon.c create mode 100644 mod/pub.mod/freetype.mod/src/base/fttype1.c create mode 100644 mod/pub.mod/freetype.mod/src/base/ftutil.c create mode 100644 mod/pub.mod/freetype.mod/src/base/ftwinfnt.c create mode 100644 mod/pub.mod/freetype.mod/src/base/ftxf86.c create mode 100644 mod/pub.mod/freetype.mod/src/bdf/bdf.c create mode 100644 mod/pub.mod/freetype.mod/src/bdf/bdf.h create mode 100644 mod/pub.mod/freetype.mod/src/bdf/bdfdrivr.c create mode 100644 mod/pub.mod/freetype.mod/src/bdf/bdfdrivr.h create mode 100644 mod/pub.mod/freetype.mod/src/bdf/bdferror.h create mode 100644 mod/pub.mod/freetype.mod/src/bdf/bdflib.c create mode 100644 mod/pub.mod/freetype.mod/src/cache/ftcache.c create mode 100644 mod/pub.mod/freetype.mod/src/cache/ftcbasic.c create mode 100644 mod/pub.mod/freetype.mod/src/cache/ftccache.c create mode 100644 mod/pub.mod/freetype.mod/src/cache/ftccache.h create mode 100644 mod/pub.mod/freetype.mod/src/cache/ftccback.h create mode 100644 mod/pub.mod/freetype.mod/src/cache/ftccmap.c create mode 100644 mod/pub.mod/freetype.mod/src/cache/ftcerror.h create mode 100644 mod/pub.mod/freetype.mod/src/cache/ftcglyph.c create mode 100644 mod/pub.mod/freetype.mod/src/cache/ftcglyph.h create mode 100644 mod/pub.mod/freetype.mod/src/cache/ftcimage.c create mode 100644 mod/pub.mod/freetype.mod/src/cache/ftcimage.h create mode 100644 mod/pub.mod/freetype.mod/src/cache/ftcmanag.c create mode 100644 mod/pub.mod/freetype.mod/src/cache/ftcmanag.h create mode 100644 mod/pub.mod/freetype.mod/src/cache/ftcmru.c create mode 100644 mod/pub.mod/freetype.mod/src/cache/ftcmru.h create mode 100644 mod/pub.mod/freetype.mod/src/cache/ftcsbits.c create mode 100644 mod/pub.mod/freetype.mod/src/cache/ftcsbits.h create mode 100644 mod/pub.mod/freetype.mod/src/cff/cff.c create mode 100644 mod/pub.mod/freetype.mod/src/cff/cffcmap.c create mode 100644 mod/pub.mod/freetype.mod/src/cff/cffcmap.h create mode 100644 mod/pub.mod/freetype.mod/src/cff/cffdrivr.c create mode 100644 mod/pub.mod/freetype.mod/src/cff/cffdrivr.h create mode 100644 mod/pub.mod/freetype.mod/src/cff/cfferrs.h create mode 100644 mod/pub.mod/freetype.mod/src/cff/cffgload.c create mode 100644 mod/pub.mod/freetype.mod/src/cff/cffgload.h create mode 100644 mod/pub.mod/freetype.mod/src/cff/cffload.c create mode 100644 mod/pub.mod/freetype.mod/src/cff/cffload.h create mode 100644 mod/pub.mod/freetype.mod/src/cff/cffobjs.c create mode 100644 mod/pub.mod/freetype.mod/src/cff/cffobjs.h create mode 100644 mod/pub.mod/freetype.mod/src/cff/cffparse.c create mode 100644 mod/pub.mod/freetype.mod/src/cff/cffparse.h create mode 100644 mod/pub.mod/freetype.mod/src/cff/cffpic.c create mode 100644 mod/pub.mod/freetype.mod/src/cff/cffpic.h create mode 100644 mod/pub.mod/freetype.mod/src/cff/cfftoken.h create mode 100644 mod/pub.mod/freetype.mod/src/cff/cfftypes.h create mode 100644 mod/pub.mod/freetype.mod/src/cid/ciderrs.h create mode 100644 mod/pub.mod/freetype.mod/src/cid/cidgload.c create mode 100644 mod/pub.mod/freetype.mod/src/cid/cidgload.h create mode 100644 mod/pub.mod/freetype.mod/src/cid/cidload.c create mode 100644 mod/pub.mod/freetype.mod/src/cid/cidload.h create mode 100644 mod/pub.mod/freetype.mod/src/cid/cidobjs.c create mode 100644 mod/pub.mod/freetype.mod/src/cid/cidobjs.h create mode 100644 mod/pub.mod/freetype.mod/src/cid/cidparse.c create mode 100644 mod/pub.mod/freetype.mod/src/cid/cidparse.h create mode 100644 mod/pub.mod/freetype.mod/src/cid/cidriver.c create mode 100644 mod/pub.mod/freetype.mod/src/cid/cidriver.h create mode 100644 mod/pub.mod/freetype.mod/src/cid/cidtoken.h create mode 100644 mod/pub.mod/freetype.mod/src/cid/type1cid.c create mode 100644 mod/pub.mod/freetype.mod/src/gzip/adler32.c create mode 100644 mod/pub.mod/freetype.mod/src/gzip/ftgzip.c create mode 100644 mod/pub.mod/freetype.mod/src/gzip/infblock.c create mode 100644 mod/pub.mod/freetype.mod/src/gzip/infblock.h create mode 100644 mod/pub.mod/freetype.mod/src/gzip/infcodes.c create mode 100644 mod/pub.mod/freetype.mod/src/gzip/infcodes.h create mode 100644 mod/pub.mod/freetype.mod/src/gzip/inffixed.h create mode 100644 mod/pub.mod/freetype.mod/src/gzip/inflate.c create mode 100644 mod/pub.mod/freetype.mod/src/gzip/inftrees.c create mode 100644 mod/pub.mod/freetype.mod/src/gzip/inftrees.h create mode 100644 mod/pub.mod/freetype.mod/src/gzip/infutil.c create mode 100644 mod/pub.mod/freetype.mod/src/gzip/infutil.h create mode 100644 mod/pub.mod/freetype.mod/src/gzip/zconf.h create mode 100644 mod/pub.mod/freetype.mod/src/gzip/zlib.h create mode 100644 mod/pub.mod/freetype.mod/src/gzip/zutil.c create mode 100644 mod/pub.mod/freetype.mod/src/gzip/zutil.h create mode 100644 mod/pub.mod/freetype.mod/src/lzw/ftlzw.c create mode 100644 mod/pub.mod/freetype.mod/src/lzw/ftzopen.c create mode 100644 mod/pub.mod/freetype.mod/src/lzw/ftzopen.h create mode 100644 mod/pub.mod/freetype.mod/src/otvalid/otvalid.c create mode 100644 mod/pub.mod/freetype.mod/src/otvalid/otvalid.h create mode 100644 mod/pub.mod/freetype.mod/src/otvalid/otvbase.c create mode 100644 mod/pub.mod/freetype.mod/src/otvalid/otvcommn.c create mode 100644 mod/pub.mod/freetype.mod/src/otvalid/otvcommn.h create mode 100644 mod/pub.mod/freetype.mod/src/otvalid/otverror.h create mode 100644 mod/pub.mod/freetype.mod/src/otvalid/otvgdef.c create mode 100644 mod/pub.mod/freetype.mod/src/otvalid/otvgpos.c create mode 100644 mod/pub.mod/freetype.mod/src/otvalid/otvgpos.h create mode 100644 mod/pub.mod/freetype.mod/src/otvalid/otvgsub.c create mode 100644 mod/pub.mod/freetype.mod/src/otvalid/otvjstf.c create mode 100644 mod/pub.mod/freetype.mod/src/otvalid/otvmath.c create mode 100644 mod/pub.mod/freetype.mod/src/otvalid/otvmod.c create mode 100644 mod/pub.mod/freetype.mod/src/otvalid/otvmod.h create mode 100644 mod/pub.mod/freetype.mod/src/pcf/pcf.c create mode 100644 mod/pub.mod/freetype.mod/src/pcf/pcf.h create mode 100644 mod/pub.mod/freetype.mod/src/pcf/pcfdrivr.c create mode 100644 mod/pub.mod/freetype.mod/src/pcf/pcfdrivr.h create mode 100644 mod/pub.mod/freetype.mod/src/pcf/pcferror.h create mode 100644 mod/pub.mod/freetype.mod/src/pcf/pcfread.c create mode 100644 mod/pub.mod/freetype.mod/src/pcf/pcfread.h create mode 100644 mod/pub.mod/freetype.mod/src/pcf/pcfutil.c create mode 100644 mod/pub.mod/freetype.mod/src/pcf/pcfutil.h create mode 100644 mod/pub.mod/freetype.mod/src/pfr/pfr.c create mode 100644 mod/pub.mod/freetype.mod/src/pfr/pfrcmap.c create mode 100644 mod/pub.mod/freetype.mod/src/pfr/pfrcmap.h create mode 100644 mod/pub.mod/freetype.mod/src/pfr/pfrdrivr.c create mode 100644 mod/pub.mod/freetype.mod/src/pfr/pfrdrivr.h create mode 100644 mod/pub.mod/freetype.mod/src/pfr/pfrerror.h create mode 100644 mod/pub.mod/freetype.mod/src/pfr/pfrgload.c create mode 100644 mod/pub.mod/freetype.mod/src/pfr/pfrgload.h create mode 100644 mod/pub.mod/freetype.mod/src/pfr/pfrload.c create mode 100644 mod/pub.mod/freetype.mod/src/pfr/pfrload.h create mode 100644 mod/pub.mod/freetype.mod/src/pfr/pfrobjs.c create mode 100644 mod/pub.mod/freetype.mod/src/pfr/pfrobjs.h create mode 100644 mod/pub.mod/freetype.mod/src/pfr/pfrsbit.c create mode 100644 mod/pub.mod/freetype.mod/src/pfr/pfrsbit.h create mode 100644 mod/pub.mod/freetype.mod/src/pfr/pfrtypes.h create mode 100644 mod/pub.mod/freetype.mod/src/psaux/afmparse.c create mode 100644 mod/pub.mod/freetype.mod/src/psaux/afmparse.h create mode 100644 mod/pub.mod/freetype.mod/src/psaux/psaux.c create mode 100644 mod/pub.mod/freetype.mod/src/psaux/psauxerr.h create mode 100644 mod/pub.mod/freetype.mod/src/psaux/psauxmod.c create mode 100644 mod/pub.mod/freetype.mod/src/psaux/psauxmod.h create mode 100644 mod/pub.mod/freetype.mod/src/psaux/psconv.c create mode 100644 mod/pub.mod/freetype.mod/src/psaux/psconv.h create mode 100644 mod/pub.mod/freetype.mod/src/psaux/psobjs.c create mode 100644 mod/pub.mod/freetype.mod/src/psaux/psobjs.h create mode 100644 mod/pub.mod/freetype.mod/src/psaux/t1cmap.c create mode 100644 mod/pub.mod/freetype.mod/src/psaux/t1cmap.h create mode 100644 mod/pub.mod/freetype.mod/src/psaux/t1decode.c create mode 100644 mod/pub.mod/freetype.mod/src/psaux/t1decode.h create mode 100644 mod/pub.mod/freetype.mod/src/pshinter/pshalgo.c create mode 100644 mod/pub.mod/freetype.mod/src/pshinter/pshalgo.h create mode 100644 mod/pub.mod/freetype.mod/src/pshinter/pshglob.c create mode 100644 mod/pub.mod/freetype.mod/src/pshinter/pshglob.h create mode 100644 mod/pub.mod/freetype.mod/src/pshinter/pshinter.c create mode 100644 mod/pub.mod/freetype.mod/src/pshinter/pshmod.c create mode 100644 mod/pub.mod/freetype.mod/src/pshinter/pshmod.h create mode 100644 mod/pub.mod/freetype.mod/src/pshinter/pshnterr.h create mode 100644 mod/pub.mod/freetype.mod/src/pshinter/pshpic.c create mode 100644 mod/pub.mod/freetype.mod/src/pshinter/pshpic.h create mode 100644 mod/pub.mod/freetype.mod/src/pshinter/pshrec.c create mode 100644 mod/pub.mod/freetype.mod/src/pshinter/pshrec.h create mode 100644 mod/pub.mod/freetype.mod/src/psnames/psmodule.c create mode 100644 mod/pub.mod/freetype.mod/src/psnames/psmodule.h create mode 100644 mod/pub.mod/freetype.mod/src/psnames/psnamerr.h create mode 100644 mod/pub.mod/freetype.mod/src/psnames/psnames.c create mode 100644 mod/pub.mod/freetype.mod/src/psnames/pspic.c create mode 100644 mod/pub.mod/freetype.mod/src/psnames/pspic.h create mode 100644 mod/pub.mod/freetype.mod/src/psnames/pstables.h create mode 100644 mod/pub.mod/freetype.mod/src/raster/ftmisc.h create mode 100644 mod/pub.mod/freetype.mod/src/raster/ftraster.c create mode 100644 mod/pub.mod/freetype.mod/src/raster/ftraster.h create mode 100644 mod/pub.mod/freetype.mod/src/raster/ftrend1.c create mode 100644 mod/pub.mod/freetype.mod/src/raster/ftrend1.h create mode 100644 mod/pub.mod/freetype.mod/src/raster/raster.c create mode 100644 mod/pub.mod/freetype.mod/src/raster/rasterrs.h create mode 100644 mod/pub.mod/freetype.mod/src/raster/rastpic.c create mode 100644 mod/pub.mod/freetype.mod/src/raster/rastpic.h create mode 100644 mod/pub.mod/freetype.mod/src/sfnt/sfdriver.c create mode 100644 mod/pub.mod/freetype.mod/src/sfnt/sfdriver.h create mode 100644 mod/pub.mod/freetype.mod/src/sfnt/sferrors.h create mode 100644 mod/pub.mod/freetype.mod/src/sfnt/sfnt.c create mode 100644 mod/pub.mod/freetype.mod/src/sfnt/sfntpic.c create mode 100644 mod/pub.mod/freetype.mod/src/sfnt/sfntpic.h create mode 100644 mod/pub.mod/freetype.mod/src/sfnt/sfobjs.c create mode 100644 mod/pub.mod/freetype.mod/src/sfnt/sfobjs.h create mode 100644 mod/pub.mod/freetype.mod/src/sfnt/ttbdf.c create mode 100644 mod/pub.mod/freetype.mod/src/sfnt/ttbdf.h create mode 100644 mod/pub.mod/freetype.mod/src/sfnt/ttcmap.c create mode 100644 mod/pub.mod/freetype.mod/src/sfnt/ttcmap.h create mode 100644 mod/pub.mod/freetype.mod/src/sfnt/ttcmapc.h create mode 100644 mod/pub.mod/freetype.mod/src/sfnt/ttkern.c create mode 100644 mod/pub.mod/freetype.mod/src/sfnt/ttkern.h create mode 100644 mod/pub.mod/freetype.mod/src/sfnt/ttload.c create mode 100644 mod/pub.mod/freetype.mod/src/sfnt/ttload.h create mode 100644 mod/pub.mod/freetype.mod/src/sfnt/ttmtx.c create mode 100644 mod/pub.mod/freetype.mod/src/sfnt/ttmtx.h create mode 100644 mod/pub.mod/freetype.mod/src/sfnt/ttpost.c create mode 100644 mod/pub.mod/freetype.mod/src/sfnt/ttpost.h create mode 100644 mod/pub.mod/freetype.mod/src/sfnt/ttsbit.c create mode 100644 mod/pub.mod/freetype.mod/src/sfnt/ttsbit.h create mode 100644 mod/pub.mod/freetype.mod/src/sfnt/ttsbit0.c create mode 100644 mod/pub.mod/freetype.mod/src/smooth/ftgrays.c create mode 100644 mod/pub.mod/freetype.mod/src/smooth/ftgrays.h create mode 100644 mod/pub.mod/freetype.mod/src/smooth/ftsmerrs.h create mode 100644 mod/pub.mod/freetype.mod/src/smooth/ftsmooth.c create mode 100644 mod/pub.mod/freetype.mod/src/smooth/ftsmooth.h create mode 100644 mod/pub.mod/freetype.mod/src/smooth/ftspic.c create mode 100644 mod/pub.mod/freetype.mod/src/smooth/ftspic.h create mode 100644 mod/pub.mod/freetype.mod/src/smooth/smooth.c create mode 100644 mod/pub.mod/freetype.mod/src/truetype/truetype.c create mode 100644 mod/pub.mod/freetype.mod/src/truetype/ttdriver.c create mode 100644 mod/pub.mod/freetype.mod/src/truetype/ttdriver.h create mode 100644 mod/pub.mod/freetype.mod/src/truetype/tterrors.h create mode 100644 mod/pub.mod/freetype.mod/src/truetype/ttgload.c create mode 100644 mod/pub.mod/freetype.mod/src/truetype/ttgload.h create mode 100644 mod/pub.mod/freetype.mod/src/truetype/ttgxvar.c create mode 100644 mod/pub.mod/freetype.mod/src/truetype/ttgxvar.h create mode 100644 mod/pub.mod/freetype.mod/src/truetype/ttinterp.c create mode 100644 mod/pub.mod/freetype.mod/src/truetype/ttinterp.h create mode 100644 mod/pub.mod/freetype.mod/src/truetype/ttobjs.c create mode 100644 mod/pub.mod/freetype.mod/src/truetype/ttobjs.h create mode 100644 mod/pub.mod/freetype.mod/src/truetype/ttpic.c create mode 100644 mod/pub.mod/freetype.mod/src/truetype/ttpic.h create mode 100644 mod/pub.mod/freetype.mod/src/truetype/ttpload.c create mode 100644 mod/pub.mod/freetype.mod/src/truetype/ttpload.h create mode 100644 mod/pub.mod/freetype.mod/src/type1/t1afm.c create mode 100644 mod/pub.mod/freetype.mod/src/type1/t1afm.h create mode 100644 mod/pub.mod/freetype.mod/src/type1/t1driver.c create mode 100644 mod/pub.mod/freetype.mod/src/type1/t1driver.h create mode 100644 mod/pub.mod/freetype.mod/src/type1/t1errors.h create mode 100644 mod/pub.mod/freetype.mod/src/type1/t1gload.c create mode 100644 mod/pub.mod/freetype.mod/src/type1/t1gload.h create mode 100644 mod/pub.mod/freetype.mod/src/type1/t1load.c create mode 100644 mod/pub.mod/freetype.mod/src/type1/t1load.h create mode 100644 mod/pub.mod/freetype.mod/src/type1/t1objs.c create mode 100644 mod/pub.mod/freetype.mod/src/type1/t1objs.h create mode 100644 mod/pub.mod/freetype.mod/src/type1/t1parse.c create mode 100644 mod/pub.mod/freetype.mod/src/type1/t1parse.h create mode 100644 mod/pub.mod/freetype.mod/src/type1/t1tokens.h create mode 100644 mod/pub.mod/freetype.mod/src/type1/type1.c create mode 100644 mod/pub.mod/freetype.mod/src/type42/t42drivr.c create mode 100644 mod/pub.mod/freetype.mod/src/type42/t42drivr.h create mode 100644 mod/pub.mod/freetype.mod/src/type42/t42error.h create mode 100644 mod/pub.mod/freetype.mod/src/type42/t42objs.c create mode 100644 mod/pub.mod/freetype.mod/src/type42/t42objs.h create mode 100644 mod/pub.mod/freetype.mod/src/type42/t42parse.c create mode 100644 mod/pub.mod/freetype.mod/src/type42/t42parse.h create mode 100644 mod/pub.mod/freetype.mod/src/type42/t42types.h create mode 100644 mod/pub.mod/freetype.mod/src/type42/type42.c create mode 100644 mod/pub.mod/freetype.mod/src/winfonts/fnterrs.h create mode 100644 mod/pub.mod/freetype.mod/src/winfonts/winfnt.c create mode 100644 mod/pub.mod/freetype.mod/src/winfonts/winfnt.h create mode 100644 mod/pub.mod/glew.mod/GL/glew.h create mode 100644 mod/pub.mod/glew.mod/GL/glxew.h create mode 100644 mod/pub.mod/glew.mod/GL/wglew.h create mode 100644 mod/pub.mod/glew.mod/glew.bmx create mode 100644 mod/pub.mod/glew.mod/glew.c create mode 100644 mod/pub.mod/glew.mod/glew2bmx.bmx create mode 100644 mod/pub.mod/glew.mod/glew_static.c create mode 100644 mod/pub.mod/libjpeg.mod/jcapimin.c create mode 100644 mod/pub.mod/libjpeg.mod/jcapistd.c create mode 100644 mod/pub.mod/libjpeg.mod/jccoefct.c create mode 100644 mod/pub.mod/libjpeg.mod/jccolor.c create mode 100644 mod/pub.mod/libjpeg.mod/jcdctmgr.c create mode 100644 mod/pub.mod/libjpeg.mod/jchuff.c create mode 100644 mod/pub.mod/libjpeg.mod/jchuff.h create mode 100644 mod/pub.mod/libjpeg.mod/jcinit.c create mode 100644 mod/pub.mod/libjpeg.mod/jcmainct.c create mode 100644 mod/pub.mod/libjpeg.mod/jcmarker.c create mode 100644 mod/pub.mod/libjpeg.mod/jcmaster.c create mode 100644 mod/pub.mod/libjpeg.mod/jcomapi.c create mode 100644 mod/pub.mod/libjpeg.mod/jcparam.c create mode 100644 mod/pub.mod/libjpeg.mod/jcphuff.c create mode 100644 mod/pub.mod/libjpeg.mod/jcprepct.c create mode 100644 mod/pub.mod/libjpeg.mod/jcsample.c create mode 100644 mod/pub.mod/libjpeg.mod/jctrans.c create mode 100644 mod/pub.mod/libjpeg.mod/jdapimin.c create mode 100644 mod/pub.mod/libjpeg.mod/jdapistd.c create mode 100644 mod/pub.mod/libjpeg.mod/jdatadst.c create mode 100644 mod/pub.mod/libjpeg.mod/jdatasrc.c create mode 100644 mod/pub.mod/libjpeg.mod/jdcoefct.c create mode 100644 mod/pub.mod/libjpeg.mod/jdcolor.c create mode 100644 mod/pub.mod/libjpeg.mod/jdct.h create mode 100644 mod/pub.mod/libjpeg.mod/jddctmgr.c create mode 100644 mod/pub.mod/libjpeg.mod/jdhuff.c create mode 100644 mod/pub.mod/libjpeg.mod/jdhuff.h create mode 100644 mod/pub.mod/libjpeg.mod/jdinput.c create mode 100644 mod/pub.mod/libjpeg.mod/jdmainct.c create mode 100644 mod/pub.mod/libjpeg.mod/jdmarker.c create mode 100644 mod/pub.mod/libjpeg.mod/jdmaster.c create mode 100644 mod/pub.mod/libjpeg.mod/jdmerge.c create mode 100644 mod/pub.mod/libjpeg.mod/jdphuff.c create mode 100644 mod/pub.mod/libjpeg.mod/jdpostct.c create mode 100644 mod/pub.mod/libjpeg.mod/jdsample.c create mode 100644 mod/pub.mod/libjpeg.mod/jdtrans.c create mode 100644 mod/pub.mod/libjpeg.mod/jerror.c create mode 100644 mod/pub.mod/libjpeg.mod/jerror.h create mode 100644 mod/pub.mod/libjpeg.mod/jfdctflt.c create mode 100644 mod/pub.mod/libjpeg.mod/jfdctfst.c create mode 100644 mod/pub.mod/libjpeg.mod/jfdctint.c create mode 100644 mod/pub.mod/libjpeg.mod/jidctflt.c create mode 100644 mod/pub.mod/libjpeg.mod/jidctfst.c create mode 100644 mod/pub.mod/libjpeg.mod/jidctint.c create mode 100644 mod/pub.mod/libjpeg.mod/jidctred.c create mode 100644 mod/pub.mod/libjpeg.mod/jinclude.h create mode 100644 mod/pub.mod/libjpeg.mod/jmemmgr.c create mode 100644 mod/pub.mod/libjpeg.mod/jmemnobs.c create mode 100644 mod/pub.mod/libjpeg.mod/jmemsys.h create mode 100644 mod/pub.mod/libjpeg.mod/jmorecfg.h create mode 100644 mod/pub.mod/libjpeg.mod/jpegint.h create mode 100644 mod/pub.mod/libjpeg.mod/jpeglib.h create mode 100644 mod/pub.mod/libjpeg.mod/jquant1.c create mode 100644 mod/pub.mod/libjpeg.mod/jquant2.c create mode 100644 mod/pub.mod/libjpeg.mod/jutils.c create mode 100644 mod/pub.mod/libjpeg.mod/jversion.h create mode 100644 mod/pub.mod/libjpeg.mod/libjpeg.bmx create mode 100644 mod/pub.mod/libjpeg.mod/loadjpeg.c create mode 100644 mod/pub.mod/libjpeg.mod/transupp.h create mode 100644 mod/pub.mod/libpng.mod/ANNOUNCE create mode 100644 mod/pub.mod/libpng.mod/CHANGES create mode 100644 mod/pub.mod/libpng.mod/INSTALL create mode 100644 mod/pub.mod/libpng.mod/KNOWNBUG create mode 100644 mod/pub.mod/libpng.mod/LICENSE create mode 100644 mod/pub.mod/libpng.mod/README create mode 100644 mod/pub.mod/libpng.mod/TODO create mode 100644 mod/pub.mod/libpng.mod/Y2KINFO create mode 100644 mod/pub.mod/libpng.mod/configure create mode 100644 mod/pub.mod/libpng.mod/example.c create mode 100644 mod/pub.mod/libpng.mod/libpng.3 create mode 100644 mod/pub.mod/libpng.mod/libpng.bmx create mode 100644 mod/pub.mod/libpng.mod/libpng.txt create mode 100644 mod/pub.mod/libpng.mod/libpngpf.3 create mode 100644 mod/pub.mod/libpng.mod/png.5 create mode 100644 mod/pub.mod/libpng.mod/png.c create mode 100644 mod/pub.mod/libpng.mod/png.h create mode 100644 mod/pub.mod/libpng.mod/pngbar.jpg create mode 100644 mod/pub.mod/libpng.mod/pngbar.png create mode 100644 mod/pub.mod/libpng.mod/pngconf.h create mode 100644 mod/pub.mod/libpng.mod/pngerror.c create mode 100644 mod/pub.mod/libpng.mod/pnggccrd.c create mode 100644 mod/pub.mod/libpng.mod/pngget.c create mode 100644 mod/pub.mod/libpng.mod/pngmem.c create mode 100644 mod/pub.mod/libpng.mod/pngnow.png create mode 100644 mod/pub.mod/libpng.mod/pngpread.c create mode 100644 mod/pub.mod/libpng.mod/pngread.c create mode 100644 mod/pub.mod/libpng.mod/pngrio.c create mode 100644 mod/pub.mod/libpng.mod/pngrtran.c create mode 100644 mod/pub.mod/libpng.mod/pngrutil.c create mode 100644 mod/pub.mod/libpng.mod/pngset.c create mode 100644 mod/pub.mod/libpng.mod/pngtest.c create mode 100644 mod/pub.mod/libpng.mod/pngtest.png create mode 100644 mod/pub.mod/libpng.mod/pngtrans.c create mode 100644 mod/pub.mod/libpng.mod/pngvcrd.c create mode 100644 mod/pub.mod/libpng.mod/pngwio.c create mode 100644 mod/pub.mod/libpng.mod/pngwrite.c create mode 100644 mod/pub.mod/libpng.mod/pngwtran.c create mode 100644 mod/pub.mod/libpng.mod/pngwutil.c create mode 100644 mod/pub.mod/lua.mod/doc/Lua-Logo_32x32.png create mode 100644 mod/pub.mod/lua.mod/doc/commands.html create mode 100644 mod/pub.mod/lua.mod/doc/intro.bbdoc create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/COPYRIGHT create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/HISTORY create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/INSTALL create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/Makefile create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/README create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/doc/amazon.gif create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/doc/contents.html create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/doc/cover.png create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/doc/logo.gif create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/doc/lua.1 create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/doc/lua.css create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/doc/lua.html create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/doc/luac.1 create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/doc/luac.html create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/doc/manual.css create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/doc/manual.html create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/doc/readme.html create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/etc/Makefile create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/etc/README create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/etc/all.c create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/etc/lua.hpp create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/etc/lua.ico create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/etc/lua.pc create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/etc/luavs.bat create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/etc/min.c create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/etc/noparser.c create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/etc/strict.lua create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/Makefile create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/lapi.c create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/lapi.h create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/lauxlib.c create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/lauxlib.h create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/lbaselib.c create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/lcode.c create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/lcode.h create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/ldblib.c create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/ldebug.c create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/ldebug.h create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/ldo.c create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/ldo.h create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/ldump.c create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/lfunc.c create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/lfunc.h create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/lgc.c create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/lgc.h create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/linit.c create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/liolib.c create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/llex.c create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/llex.h create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/llimits.h create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/lmathlib.c create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/lmem.c create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/lmem.h create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/loadlib.c create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/lobject.c create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/lobject.h create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/lopcodes.c create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/lopcodes.h create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/loslib.c create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/lparser.c create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/lparser.h create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/lstate.c create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/lstate.h create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/lstring.c create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/lstring.h create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/lstrlib.c create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/ltable.c create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/ltable.h create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/ltablib.c create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/ltm.c create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/ltm.h create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/lua.c create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/lua.h create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/luac.c create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/luaconf.h create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/lualib.h create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/lundump.c create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/lundump.h create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/lvm.c create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/lvm.h create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/lzio.c create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/lzio.h create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/src/print.c create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/test/README create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/test/bisect.lua create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/test/cf.lua create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/test/echo.lua create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/test/env.lua create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/test/factorial.lua create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/test/fib.lua create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/test/fibfor.lua create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/test/globals.lua create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/test/hello.lua create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/test/life.lua create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/test/luac.lua create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/test/printf.lua create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/test/readonly.lua create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/test/sieve.lua create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/test/sort.lua create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/test/table.lua create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/test/trace-calls.lua create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/test/trace-globals.lua create mode 100644 mod/pub.mod/lua.mod/lua-5.1.4/test/xd.lua create mode 100644 mod/pub.mod/lua.mod/lua.bmx create mode 100644 mod/pub.mod/macos.mod/macos.bmx create mode 100644 mod/pub.mod/macos.mod/macos.h create mode 100644 mod/pub.mod/macos.mod/macos.m create mode 100644 mod/pub.mod/oggvorbis.mod/libogg-1.1.3/AUTHORS create mode 100644 mod/pub.mod/oggvorbis.mod/libogg-1.1.3/CHANGES create mode 100644 mod/pub.mod/oggvorbis.mod/libogg-1.1.3/COPYING create mode 100644 mod/pub.mod/oggvorbis.mod/libogg-1.1.3/README create mode 100644 mod/pub.mod/oggvorbis.mod/libogg-1.1.3/include/ogg/ogg.h create mode 100644 mod/pub.mod/oggvorbis.mod/libogg-1.1.3/include/ogg/os_types.h create mode 100644 mod/pub.mod/oggvorbis.mod/libogg-1.1.3/src/bitwise.c create mode 100644 mod/pub.mod/oggvorbis.mod/libogg-1.1.3/src/framing.c create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/AUTHORS create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/COPYING create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/README create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/include/vorbis/codec.h create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/include/vorbis/vorbisenc.h create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/include/vorbis/vorbisfile.h create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/analysis.c create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/backends.h create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/barkmel.c create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/bitrate.c create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/bitrate.h create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/block.c create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/books/coupled/res_books_stereo.h create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/books/floor/floor_books.h create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/books/uncoupled/res_books_uncoupled.h create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/codebook.c create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/codebook.h create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/codec_internal.h create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/envelope.c create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/envelope.h create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/floor0.c create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/floor1.c create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/highlevel.h create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/info.c create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/lookup.c create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/lookup.h create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/lookup_data.h create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/lookups.pl create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/lpc.c create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/lpc.h create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/lsp.c create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/lsp.h create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/mapping0.c create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/masking.h create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/mdct.c create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/mdct.h create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/misc.h create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/floor_all.h create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/psych_11.h create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/psych_16.h create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/psych_44.h create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/psych_8.h create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/residue_16.h create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/residue_44.h create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/residue_44u.h create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/residue_8.h create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/setup_11.h create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/setup_16.h create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/setup_22.h create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/setup_32.h create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/setup_44.h create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/setup_44u.h create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/setup_8.h create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/setup_X.h create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/os.h create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/psy.c create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/psy.h create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/psytune.c create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/registry.c create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/registry.h create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/res0.c create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/scales.h create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/sharedbook.c create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/smallft.c create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/smallft.h create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/synthesis.c create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/tone.c create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/vorbisenc.c create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/vorbisfile.c create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/window.c create mode 100644 mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/window.h create mode 100644 mod/pub.mod/oggvorbis.mod/oggdecoder.c create mode 100644 mod/pub.mod/oggvorbis.mod/oggvorbis.bmx create mode 100644 mod/pub.mod/openal.mod/openal.bmx create mode 100644 mod/pub.mod/openal.mod/openal.c create mode 100644 mod/pub.mod/opengl.mod/doc/intro.bbdoc create mode 100644 mod/pub.mod/opengl.mod/glu.bmx create mode 100644 mod/pub.mod/opengl.mod/opengl.bmx create mode 100644 mod/pub.mod/stdc.mod/stdc.bmx create mode 100644 mod/pub.mod/stdc.mod/stdc.c create mode 100644 mod/pub.mod/win32.mod/com.bmx create mode 100644 mod/pub.mod/win32.mod/commctrl.bmx create mode 100644 mod/pub.mod/win32.mod/commdlg.bmx create mode 100644 mod/pub.mod/win32.mod/gdi32.bmx create mode 100644 mod/pub.mod/win32.mod/kernel32.bmx create mode 100644 mod/pub.mod/win32.mod/richedit.bmx create mode 100644 mod/pub.mod/win32.mod/user32.bmx create mode 100644 mod/pub.mod/win32.mod/win32.bmx create mode 100644 mod/pub.mod/win32.mod/winmm.bmx create mode 100644 mod/pub.mod/zlib.mod/adler32.c create mode 100644 mod/pub.mod/zlib.mod/algorithm.txt create mode 100644 mod/pub.mod/zlib.mod/compress.c create mode 100644 mod/pub.mod/zlib.mod/crc32.c create mode 100644 mod/pub.mod/zlib.mod/crc32.h create mode 100644 mod/pub.mod/zlib.mod/deflate.c create mode 100644 mod/pub.mod/zlib.mod/deflate.h create mode 100644 mod/pub.mod/zlib.mod/example.c create mode 100644 mod/pub.mod/zlib.mod/gzio.c create mode 100644 mod/pub.mod/zlib.mod/infback.c create mode 100644 mod/pub.mod/zlib.mod/inffast.c create mode 100644 mod/pub.mod/zlib.mod/inffast.h create mode 100644 mod/pub.mod/zlib.mod/inffixed.h create mode 100644 mod/pub.mod/zlib.mod/inflate.c create mode 100644 mod/pub.mod/zlib.mod/inflate.h create mode 100644 mod/pub.mod/zlib.mod/inftrees.c create mode 100644 mod/pub.mod/zlib.mod/inftrees.h create mode 100644 mod/pub.mod/zlib.mod/minigzip.c create mode 100644 mod/pub.mod/zlib.mod/trees.c create mode 100644 mod/pub.mod/zlib.mod/trees.h create mode 100644 mod/pub.mod/zlib.mod/uncompr.c create mode 100644 mod/pub.mod/zlib.mod/zconf.h create mode 100644 mod/pub.mod/zlib.mod/zlib.bmx create mode 100644 mod/pub.mod/zlib.mod/zlib.h create mode 100644 mod/pub.mod/zlib.mod/zlib.html create mode 100644 mod/pub.mod/zlib.mod/zutil.c create mode 100644 mod/pub.mod/zlib.mod/zutil.h diff --git a/mod/brl.mod/appstub.mod/appstub.bmx b/mod/brl.mod/appstub.mod/appstub.bmx new file mode 100644 index 0000000..77f36e0 --- /dev/null +++ b/mod/brl.mod/appstub.mod/appstub.bmx @@ -0,0 +1,71 @@ + +Strict + +NoDebug + +Module BRL.AppStub + +ModuleInfo "Version: 1.20" +ModuleInfo "Authors: Mark Sibly, Simon Armstrong" +ModuleInfo "License: zlib/libpng" +ModuleInfo "Copyright: Blitz Research Ltd" +ModuleInfo "Modserver: BRL" + +ModuleInfo "History: 1.20 Release" +ModuleInfo "History: Fixed 'invalid typetag' issue" +ModuleInfo "History: 1.19 Release" +ModuleInfo "History: Removed some debug output" +ModuleInfo "History: 1.18 Release" +ModuleInfo "History: Changed debugger.stdio.bmx so it handles deep stacks better" +ModuleInfo "History: 1.17 Release" +ModuleInfo "History: Added Brucey's SIGPIPE fix for GTK" +ModuleInfo "History: 1.16 Release" +ModuleInfo "History: Added experimental dll support" +ModuleInfo "History: 1.15 Release" +ModuleInfo "History: Fixed Const string reporting not being escaped" +ModuleInfo "History: 1.14 Release" +ModuleInfo "History: Debug output lines now prepended with ~>" +ModuleInfo "History: 1.13 Release" +ModuleInfo "History: Removed unused debugger sources" +ModuleInfo "History: 1.12 Release" +ModuleInfo "History: Now manually builds app menu for MacOS Tiger" +ModuleInfo "History: 1.11 Release" +ModuleInfo "History: Fixed MacOS debug string overflow" +ModuleInfo "History: 1.10 Release" +ModuleInfo "History: Added kludge for MacOS Menu Quit generating errors" +ModuleInfo "History: 1.09 Release" +ModuleInfo "History: Fixed MacOS AutoreleasePool problem" +ModuleInfo "History: 1.08 Release" +ModuleInfo "History: Fixed Tiger build warnings in debugger.macos.m" +ModuleInfo "History: 1.07 Release" +ModuleInfo "History: Improved Win32 debugger switching" +ModuleInfo "History: Fixed macos debugger dying with extern types" +ModuleInfo "History: 1.06 Release" +ModuleInfo "History: Tweaked MacOS debugger" +ModuleInfo "History: 1.05 Release" +ModuleInfo "History: Fixed C Compiler warnings" +ModuleInfo "History: Fixed multidim arrays hanging debugger" +ModuleInfo "History: 1.04 Release" +ModuleInfo "History: Fixed buffer overflow in debug strings" +ModuleInfo "History: Modified float and double debug output to match compiler precision" + +?Debug +'Import "debugger.stdio.bmx" +Import "debugger_mt.stdio.bmx" 'Let's give Otus's new MT friendly debugger a whirl! +? + +?MacOS +Import "appstub.macos.m" +Import "-framework Cocoa" +Import "-framework Carbon" +?Win32 +Import "appstub.win32.c" +?Linux +Import "appstub.linux.c" +? + +Extern +Function _bb_main() +End Extern + +_bb_main diff --git a/mod/brl.mod/appstub.mod/appstub.linux.c b/mod/brl.mod/appstub.mod/appstub.linux.c new file mode 100644 index 0000000..722c998 --- /dev/null +++ b/mod/brl.mod/appstub.mod/appstub.linux.c @@ -0,0 +1,17 @@ + +#include + +#include + +void __bb_appstub_appstub(); + +int main( int argc,char *argv[] ){ + + signal( SIGPIPE,SIG_IGN ); + + bbStartup( argc,argv,0,0 ); + + __bb_appstub_appstub(); + + return 0; +} diff --git a/mod/brl.mod/appstub.mod/appstub.macos.m b/mod/brl.mod/appstub.mod/appstub.macos.m new file mode 100644 index 0000000..aaac128 --- /dev/null +++ b/mod/brl.mod/appstub.mod/appstub.macos.m @@ -0,0 +1,139 @@ + +#include + +#import + +void __bb_appstub_appstub(); + +static int app_argc; +static char **app_argv; + +static NSMutableArray *_appArgs; +static NSAutoreleasePool *_globalPool; + +static void createAppMenu( NSString *appName ){ + + NSMenu *appMenu; + NSMenuItem *item; + NSString *title; + + [NSApp setMainMenu:[NSMenu new]]; + + appMenu=[NSMenu new]; + + title=[@"Hide " stringByAppendingString:appName]; + [appMenu addItemWithTitle:@"Hide" action:@selector(hide:) keyEquivalent:@"h"]; + + item=(NSMenuItem*)[appMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"]; + [item setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)]; + + [appMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""]; + + [appMenu addItem:[NSMenuItem separatorItem]]; + + title=[@"Quit " stringByAppendingString:appName]; + [appMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"]; + + item=[NSMenuItem new]; + [item setSubmenu:appMenu]; + [[NSApp mainMenu] addItem:item]; + + [NSApp performSelector:NSSelectorFromString(@"setAppleMenu:") withObject:appMenu]; +} + +static void run(){ + + signal( SIGPIPE,SIG_IGN ); + + bbStartup( app_argc,app_argv,0,0 ); + + __bb_appstub_appstub(); + + exit( 0 ); +} + +void bbFlushAutoreleasePool(){ + [_globalPool release]; + _globalPool=[[NSAutoreleasePool alloc] init]; +} + +@interface BlitzMaxAppDelegate : NSObject{ +} +@end + +@implementation BlitzMaxAppDelegate +-(void)applicationWillTerminate:(NSNotification*)notification{ + exit(0); +} + +-(NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication*)sender{ + return NSTerminateCancel; +} + +-(BOOL)application:(NSApplication*)app openFile:(NSString*)path{ + [_appArgs addObject:path]; + return YES; +} + +-(void)applicationDidFinishLaunching:(NSNotification*)notification{ + int i; + app_argc=[_appArgs count]; + app_argv=(char**)malloc( (app_argc+1)*sizeof(char*) ); + for( i=0;i + +#include + +//Enable exception debugging +#define BB_DEBUG_EXCEPTIONS + +#ifdef BB_DEBUG_EXCEPTIONS + +static LONG WINAPI unhandledExceptionFilter( EXCEPTION_POINTERS *xinfo ){ + const char *p="EXCEPTION_UNKNOWN"; + switch( xinfo->ExceptionRecord->ExceptionCode ){ + case EXCEPTION_ACCESS_VIOLATION:p="EXCEPTION_ACCESS_VIOLATION";break; + case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:p="EXCEPTION_ARRAY_BOUNDS_EXCEEDED";break; + case EXCEPTION_BREAKPOINT:p="EXCEPTION_BREAKPOINT";break; + case EXCEPTION_DATATYPE_MISALIGNMENT:p="EXCEPTION_DATATYPE_MISALIGNMENT";break; + case EXCEPTION_FLT_DENORMAL_OPERAND:p="EXCEPTION_FLT_DENORMAL_OPERAND";break; + case EXCEPTION_FLT_DIVIDE_BY_ZERO:p="EXCEPTION_FLT_DIVIDE_BY_ZERO";break; + case EXCEPTION_FLT_INEXACT_RESULT:p="EXCEPTION_FLT_INEXACT_RESULT";break; + case EXCEPTION_FLT_INVALID_OPERATION:p="EXCEPTION_FLT_INVALID_OPERATION";break; + case EXCEPTION_FLT_OVERFLOW:p="EXCEPTION_FLT_OVERFLOW";break; + case EXCEPTION_FLT_STACK_CHECK:p="EXCEPTION_FLT_STACK_CHECK";break; + case EXCEPTION_FLT_UNDERFLOW:p="EXCEPTION_FLT_UNDERFLOW";break; + case EXCEPTION_ILLEGAL_INSTRUCTION:p="EXCEPTION_ILLEGAL_INSTRUCTION";break; + case EXCEPTION_IN_PAGE_ERROR:p="EXCEPTION_IN_PAGE_ERROR";break; + case EXCEPTION_INT_DIVIDE_BY_ZERO:p="EXCEPTION_INT_DIVIDE_BY_ZERO";break; + case EXCEPTION_INT_OVERFLOW:p="EXCEPTION_INT_OVERFLOW";break; + case EXCEPTION_INVALID_DISPOSITION:p="EXCEPTION_INVALID_DISPOSITION";break; + case EXCEPTION_NONCONTINUABLE_EXCEPTION:p="EXCEPTION_NONCONTINUABLE_EXCEPTION";break; + case EXCEPTION_PRIV_INSTRUCTION:p="EXCEPTION_PRIV_INSTRUCTION";break; + case EXCEPTION_SINGLE_STEP:p="EXCEPTION_SINGLE_STEP";break; + case EXCEPTION_STACK_OVERFLOW:p="EXCEPTION_STACK_OVERFLOW";break; + } + MessageBoxA( GetActiveWindow(),p,"Windows exception",MB_OK ); + bbOnDebugStop(); + exit( 0 ); +} + +#endif + +void bbLibStartup(); + +void __bb_appstub_appstub(); + +int main( int argc,char *argv[] ){ + +#ifdef BB_DEBUG_EXCEPTIONS + + SetUnhandledExceptionFilter( unhandledExceptionFilter ); + +#endif + + bbStartup( argc,argv,0,0 ); + + __bb_appstub_appstub(); + + return 0; +} + +BOOL WINAPI DllMain( HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved ){ + + if( fdwReason!=DLL_PROCESS_ATTACH ) return 1; + + bbLibStartup(); + + __bb_appstub_appstub(); + + return 1; +} diff --git a/mod/brl.mod/appstub.mod/debugger.stdio.bmx b/mod/brl.mod/appstub.mod/debugger.stdio.bmx new file mode 100644 index 0000000..07e92b1 --- /dev/null +++ b/mod/brl.mod/appstub.mod/debugger.stdio.bmx @@ -0,0 +1,711 @@ + +Strict + +NoDebug + +Private + +?Win32 +Extern "Win32" +Const SW_SHOW=5 +Const SW_RESTORE=9 +Function IsIconic( hwnd ) +Function GetForegroundWindow() +Function SetForegroundWindow( hwnd ) +Function ShowWindow( hwnd,cmdShow ) +Function GetCurrentThreadId() +End Extern +? + +?MacOS +Extern +Function CGDisplayIsCaptured( displayId ) +End Extern +? + +Extern +Global bbStringClass:Byte +Global bbArrayClass:Byte +Global bbNullObject:Byte +Global bbEmptyArray:Byte +Global bbEmptyString:Byte +Global brl_blitz_NullFunctionError:Byte Ptr +Function bbIsMainThread()="bbIsMainThread" +Function bbGCValidate:Int( mem:Int ) = "bbGCValidate" +End Extern + +Function ToHex$( val ) + Local buf:Short[8] + For Local k=7 To 0 Step -1 + Local n=(val&15)+Asc("0") + If n>Asc("9") n=n+(Asc("A")-Asc("9")-1) + buf[k]=n + val:Shr 4 + Next + Return String.FromShorts( buf,8 ).ToLower() +End Function + +Function IsAlpha( ch ) + Return (ch>=Asc("a") And ch<=Asc("z")) Or (ch>=Asc("A") And ch<=Asc("Z")) +End Function + +Function IsNumeric( ch ) + Return ch>=Asc("0") And ch<=Asc("9") +End Function + +Function IsAlphaNumeric( ch ) + Return IsAlpha(ch) Or IsNumeric(ch) +End Function + +Function IsUnderscore( ch ) + Return ch=Asc("_") +End Function + +Function Ident$( tag$ Var ) + If Not tag Return "" + If Not IsAlpha( tag[0] ) And Not IsUnderscore( tag[0] ) Return "" + Local i=1 + While i"]" DebugError "Invalid array typetag" + tag=tag[1..] + Return TypeName( tag )+t+"]" + Case "(" + If tag[..1]<>")" + t:+TypeName( tag ) + While tag[..1]="," + tag=tag[1..] + t:+","+TypeName( tag ) + Wend + If tag[..1]<>")" DebugError "Invalid function typetag" + EndIf + tag=tag[1..] + Return TypeName( tag )+t+")" + End Select + + DebugError "Invalid debug typetag:"+t + +End Function + +'int offsets into 12 byte DebugStm struct +Const DEBUGSTM_FILE=0 +Const DEBUGSTM_LINE=1 +Const DEBUGSTM_CHAR=2 + +'int offsets into 16 byte DebugDecl struct +Const DEBUGDECL_KIND=0 +Const DEBUGDECL_NAME=1 +Const DEBUGDECL_TYPE=2 +Const DEBUGDECL_ADDR=3 + +'DEBUGDECL_KIND values +Const DEBUGDECLKIND_END=0 +Const DEBUGDECLKIND_CONST=1 +Const DEBUGDECLKIND_LOCAL=2 +Const DEBUGDECLKIND_FIELD=3 +Const DEBUGDECLKIND_GLOBAL=4 +Const DEBUGDECLKIND_VARPARAM=5 +Const DEBUGDECLKIND_TYPEMETHOD=6 +Const DEBUGDECLKIND_TYPEFUNCTION=7 + +'int offsets into 12+n_decls*4 byte DebugScope struct +Const DEBUGSCOPE_KIND=0 +Const DEBUGSCOPE_NAME=1 +Const DEBUGSCOPE_DECLS=2 + +'DEBUGSCOPE_KIND values +Const DEBUGSCOPEKIND_FUNCTION=1 +Const DEBUGSCOPEKIND_TYPE=2 +Const DEBUGSCOPEKIND_LOCAL=3 + +Function DebugError( t$ ) + WriteStderr "Debugger Error:"+t+"~n" + End +End Function + +Function DebugStmFile$( stm:Int Ptr ) + Return String.FromCString( Byte Ptr stm[DEBUGSTM_FILE] ) +End Function + +Function DebugStmLine( stm:Int Ptr ) + Return stm[DEBUGSTM_LINE] +End Function + +Function DebugStmChar( stm:Int Ptr ) + Return stm[DEBUGSTM_CHAR] +End Function + +Function DebugDeclKind$( decl:Int Ptr ) + Select decl[DEBUGDECL_KIND] + Case DEBUGDECLKIND_CONST Return "Const" + Case DEBUGDECLKIND_LOCAL Return "Local" + Case DEBUGDECLKIND_FIELD Return "Field" + Case DEBUGDECLKIND_GLOBAL Return "Global" + Case DEBUGDECLKIND_VARPARAM Return "Local" + End Select + DebugError "Invalid decl kind" +End Function + +Function DebugDeclName$( decl:Int Ptr ) + Return String.FromCString( Byte Ptr decl[DEBUGDECL_NAME] ) +End Function + +Function DebugDeclType$( decl:Int Ptr ) + Local t$=String.FromCString( Byte Ptr decl[DEBUGDECL_TYPE] ) + Local ty$=TypeName( t ) + Return ty +End Function + +Function DebugDeclSize( decl:Int Ptr ) + + Local tag=(Byte Ptr Ptr(decl+DEBUGDECL_TYPE))[0][0] + + Select tag + Case Asc("b") Return 1 + Case Asc("s") Return 2 + Case Asc("l") Return 8 + Case Asc("d") Return 8 + End Select + + Return 4 + +End Function + +Function DebugEscapeString$( s$ ) + s=s.Replace( "~~","~~~~") + s=s.Replace( "~0","~~0" ) + s=s.Replace( "~t","~~t" ) + s=s.Replace( "~n","~~n" ) + s=s.Replace( "~r","~~r" ) + s=s.Replace( "~q","~~q" ) + Return "~q"+s+"~q" +End Function + +Function DebugDeclValue$( decl:Int Ptr,inst:Byte Ptr ) + If decl[DEBUGDECL_KIND]=DEBUGDECLKIND_CONST + Local p:Byte Ptr=Byte Ptr decl[DEBUGDECL_ADDR] + Return DebugEscapeString(String.FromShorts( Short Ptr(p+12),(Int Ptr (p+8))[0] )) + EndIf + + Local p:Byte Ptr + Select decl[DEBUGDECL_KIND] + Case DEBUGDECLKIND_GLOBAL + p=Byte Ptr decl[DEBUGDECL_ADDR] + Case DEBUGDECLKIND_LOCAL,DEBUGDECLKIND_FIELD + p=Byte Ptr (inst+decl[DEBUGDECL_ADDR]) + Case DEBUGDECLKIND_VARPARAM + p=Byte Ptr (inst+decl[DEBUGDECL_ADDR]) + p=Byte Ptr ( (Int Ptr p)[0] ) + Default + DebugError "Invalid decl kind" + End Select + + Local tag=(Byte Ptr Ptr(decl+DEBUGDECL_TYPE))[0][0] + + Select tag + Case Asc("b") + Return String.FromInt( (Byte Ptr p)[0] ) + Case Asc("s") + Return String.FromInt( (Short Ptr p)[0] ) + Case Asc("i") + Return String.FromInt( (Int Ptr p)[0] ) + Case Asc("l") + Return String.FromLong( (Long Ptr p)[0] ) + Case Asc("f") + Return String.FromFloat( (Float Ptr p)[0] ) + Case Asc("d") + Return String.FromDouble( (Double Ptr p)[0] ) + Case Asc("$") + p=(Byte Ptr Ptr p)[0] + Local sz=Int Ptr(p+8)[0] + Local s$=String.FromShorts( Short Ptr(p+12),sz ) + Return DebugEscapeString( s ) + Case Asc("z") + p=(Byte Ptr Ptr p)[0] + If Not p Return "Null" + Local s$=String.FromCString( p ) + Return DebugEscapeString( s ) + Case Asc("w") + p=(Byte Ptr Ptr p)[0] + If Not p Return "Null" + Local s$=String.FromWString( Short Ptr p ) + Return DebugEscapeString( s ) + Case Asc("*"),Asc("?") + Return "$"+ToHex( (Int Ptr p)[0] ) + Case Asc("(") + p=(Byte Ptr Ptr p)[0] + If p=brl_blitz_NullFunctionError Return "Null" + Case Asc(":") + p=(Byte Ptr Ptr p)[0] + If p=Varptr bbNullObject Return "Null" + If p=Varptr bbEmptyArray Return "Null[]" + If p=Varptr bbEmptyString Return "Null$" + Case Asc("[") + p=(Byte Ptr Ptr p)[0] + If Not p Return "Null" + If Not (Int Ptr (p+20))[0] Return "Null" + Default + DebugError "Invalid decl typetag:"+Chr(tag) + End Select + + Return "$"+ToHex( Int p ) + +End Function + +Function DebugScopeKind$( scope:Int Ptr ) + Select scope[DEBUGSCOPE_KIND] + Case DEBUGSCOPEKIND_FUNCTION Return "Function" + Case DEBUGSCOPEKIND_TYPE Return "Type" + Case DEBUGSCOPEKIND_LOCAL Return "Local" + End Select + DebugError "Invalid scope kind" +End Function + +Function DebugScopeName$( scope:Int Ptr ) + Return String.FromCString( Byte Ptr scope[DEBUGSCOPE_NAME] ) +End Function + +Function DebugScopeDecls:Int Ptr[]( scope:Int Ptr ) + Local n,p:Int Ptr=scope+DEBUGSCOPE_DECLS + While p[n]<>DEBUGDECLKIND_END + n:+1 + Wend + Local decls:Int Ptr[n] + For Local i=0 Until n + decls[i]=p+i*4 + Next + Return decls +End Function + +Function DebugObjectScope:Int Ptr( inst:Byte Ptr ) + Local clas:Int Ptr Ptr=(Int Ptr Ptr Ptr inst)[0] + Return clas[2] +End Function + +Extern +Global bbOnDebugStop() +Global bbOnDebugLog( message$ ) +Global bbOnDebugEnterStm( stm:Int Ptr ) +Global bbOnDebugEnterScope( scope:Int Ptr,inst:Byte Ptr ) +Global bbOnDebugLeaveScope() +Global bbOnDebugPushExState() +Global bbOnDebugPopExState() +Global bbOnDebugUnhandledEx( ex:Object ) +End Extern + +bbOnDebugStop=OnDebugStop +bbOnDebugLog=OnDebugLog +bbOnDebugEnterStm=OnDebugEnterStm +bbOnDebugEnterScope=OnDebugEnterScope +bbOnDebugLeaveScope=OnDebugLeaveScope +bbOnDebugPushExState=OnDebugPushExState +bbOnDebugPopExState=OnDebugPopExState +bbOnDebugUnhandledEx=OnDebugUnhandledEx + +?Win32 +Global _ideHwnd=GetForegroundWindow(); +Global _appHwnd +? + +'********** Debugger code here ********** + +Const MODE_RUN=0 +Const MODE_STEP=1 +Const MODE_STEPIN=2 +Const MODE_STEPOUT=3 + +Type TScope + Field scope:Int Ptr,inst:Byte Ptr,stm:Int Ptr +End Type + +Type TExState + Field scopeStackTop +End Type + +Global mode,debugLevel,funcLevel +Global currentScope:TScope=New TScope +Global scopeStack:TScope[],scopeStackTop +Global exStateStack:TExState[],exStateStackTop + +Function ReadDebug$() + Return ReadStdin() +End Function + +Function WriteDebug( t$ ) + WriteStderr "~~>"+t +End Function + +Function DumpScope( scope:Int Ptr,inst:Byte Ptr ) + + Local decl:Int Ptr=scope+DEBUGSCOPE_DECLS + + Local kind$=DebugScopeKind( scope ),name$=DebugScopeName( scope ) + + If Not name name="" + + WriteDebug kind+" "+name+"~n" + + While decl[DEBUGDECL_KIND]<>DEBUGDECLKIND_END + + Select decl[DEBUGDECL_KIND] + Case DEBUGDECLKIND_TYPEMETHOD,DEBUGDECLKIND_TYPEFUNCTION + decl:+4 + Continue + End Select + + Local kind$=DebugDeclKind( decl ) + Local name$=DebugDeclname( decl ) + Local tipe$=DebugDeclType( decl ) + Local value$=DebugDeclValue( decl,inst ) + + WriteDebug kind+" "+name+":"+tipe+"="+value+"~n" + + decl:+4 + Wend +End Function + +Function DumpClassScope( clas:Int Ptr,inst:Byte Ptr ) + + Local supa:Int Ptr=Int Ptr clas[0] + + If Not supa Return + + DumpClassScope supa,inst + + DumpScope Int Ptr clas[2],inst + +End Function + +Function DumpObject( inst:Byte Ptr,index ) + + Local clas:Int Ptr=(Int Ptr Ptr inst)[0] + + If clas=Int Ptr Varptr bbStringClass + + WriteDebug DebugEscapeString(String.FromShorts( Short Ptr(inst+12),(Int Ptr (inst+8))[0] ))+"~n" + + Return + + Else If clas=Int Ptr Varptr bbArrayClass + + Local length=(Int Ptr (inst+20))[0] + + If Not length Return + + Local decl:Int[3] + decl[0]=DEBUGDECLKIND_LOCAL + decl[2]=(Int Ptr (inst+8))[0] + + Local sz=DebugDeclSize( decl ) + + Local p:Byte Ptr=Byte Ptr(20+(Int Ptr (inst+12))[0]*4) + + For Local i=1 To 10 + + If index>=length Exit + + decl[3]=Int(p+index*sz) + + Local value$=DebugDeclValue( decl,inst ) + + WriteDebug "["+index+"]="+value+"~n" + + index:+1 + + Next + + If index~n" + DumpScope t.scope,t.inst + Next +End Function + +Function UpdateDebug( msg$ ) + Global indebug + If indebug Return + indebug=True + +?Win32 + _appHwnd=GetForegroundWindow(); + 'SetForegroundWindow( _ideHwnd ); +? +?MacOs + 'fullscreen debug too hard in MacOS! + If CGDisplayIsCaptured( 0 ) + WriteStdout msg + End + EndIf +? + WriteDebug msg + Repeat + WriteDebug "~n" + Local line$=ReadDebug() + + Select line[..1].ToLower() + Case "r" + mode=MODE_RUN + Exit + Case "s" + mode=MODE_STEP + debugLevel=funcLevel + Exit + Case "e" + mode=MODE_STEPIN + Exit + Case "l" + mode=MODE_STEPOUT + debugLevel=scopeStackTop-1 + Exit + Case "t" + WriteDebug "StackTrace{~n" + DumpScopeStack + WriteDebug "}~n" + Case "d" + Local t$=line[1..].Trim() + Local index + Local i=t.Find(":") + If i<>-1 + index=Int( t[i+1..] ) + t=t[..i] + EndIf + If t[..1]="$" t=t[1..].Trim() + If t[..2].ToLower()="0x" t=t[2..].Trim() + Local pointer = Int( "$"+t ) + If Not (pointer And bbGCValidate(pointer)) Then Continue + Local inst:Int Ptr=Int Ptr pointer + + Local cmd$="ObjectDump@"+ToHex( Int inst ) + If i<>-1 cmd:+":"+index + WriteDebug cmd$+"{~n" + + DumpObject inst,index + WriteDebug "}~n" + Case "h" + WriteDebug "T - Stack trace~n" + WriteDebug "R - Run from here~n" + WriteDebug "S - Step through source code~n" + WriteDebug "E - Step into function call~n" + WriteDebug "L - Leave function or local block~n" + WriteDebug "Q - Quit~n" + WriteDebug "H - This text~n" + WriteDebug "Dxxxxxxxx - Dump object at hex address xxxxxxxx~n" + Case "q" + End + End Select + Forever + +?Win32 + If _appHwnd And _appHwnd<>_ideHwnd + If IsIconic(_apphwnd) + ShowWindow _appHwnd,SW_RESTORE + Else + ShowWindow _appHwnd,SW_SHOW + EndIf + _apphwnd=0 + EndIf +? + indebug=False +End Function + +Function OnDebugStop() +?Threaded + If Not bbIsMainThread() Return +? + UpdateDebug "DebugStop:~n" +End Function + +Function OnDebugLog( message$ ) +?Threaded + If Not bbIsMainThread() Return +? + WriteStdout "DebugLog:"+message+"~n" +End Function + +Function OnDebugEnterStm( stm:Int Ptr ) +?Threaded + If Not bbIsMainThread() Return +? + currentScope.stm=stm + + Select mode + Case MODE_RUN + Return + Case MODE_STEP + If funcLevel>debugLevel + Return + EndIf + Case MODE_STEPOUT + If scopeStackTop>debugLevel + Return + EndIf + End Select + + UpdateDebug "Debug:~n" +End Function + +Function OnDebugEnterScope( scope:Int Ptr,inst:Byte Ptr ) +?Threaded + If Not bbIsMainThread() Return +? + GCSuspend + + If scopeStackTop=scopeStack.length + scopeStack=scopeStack[..scopeStackTop * 2 + 32] + For Local i=scopeStackTop Until scopeStack.length + scopeStack[i]=New TScope + Next + EndIf + + currentScope=scopeStack[scopeStackTop] + + currentScope.scope=scope + currentScope.inst=inst + + scopeStackTop:+1 + + If currentScope.scope[DEBUGSCOPE_KIND]=DEBUGSCOPEKIND_FUNCTION funcLevel:+1 + + GCResume +End Function + +Function OnDebugLeaveScope() +?Threaded + If Not bbIsMainThread() Return +? + GCSuspend + + If Not scopeStackTop DebugError "scope stack underflow" + + If currentScope.scope[DEBUGSCOPE_KIND]=DEBUGSCOPEKIND_FUNCTION funcLevel:-1 + + scopeStackTop:-1 + + If scopeStackTop + currentScope=scopeStack[scopeStackTop-1] + Else + currentScope=New TScope + EndIf + + GCResume +End Function + +Function OnDebugPushExState() +?Threaded + If Not bbIsMainThread() Return +? + GCSuspend + + If exStateStackTop=exStateStack.length + exStateStack=exStateStack[..exStateStackTop * 2 + 32] + For Local i=exStateStackTop Until exStateStack.length + exStateStack[i]=New TExState + Next + EndIf + + exStateStack[exStateStackTop].scopeStackTop=scopeStackTop + + exStateStackTop:+1 + + GCResume +End Function + +Function OnDebugPopExState() +?Threaded + If Not bbIsMainThread() Return +? + GCSuspend + + If Not exStateStackTop DebugError "exception stack underflow" + + exStateStackTop:-1 + + scopeStackTop=exStateStack[exStateStackTop].scopeStackTop + + If scopeStackTop + currentScope=scopeStack[scopeStackTop-1] + Else + currentScope=New TScope + EndIf + + GCResume +End Function + +Function OnDebugUnhandledEx( ex:Object ) +?Threaded + If Not bbIsMainThread() Return +? + GCSuspend + + UpdateDebug "Unhandled Exception:"+ex.ToString()+"~n" + + GCResume +End Function + diff --git a/mod/brl.mod/appstub.mod/debugger_mt.stdio.bmx b/mod/brl.mod/appstub.mod/debugger_mt.stdio.bmx new file mode 100644 index 0000000..2b26383 --- /dev/null +++ b/mod/brl.mod/appstub.mod/debugger_mt.stdio.bmx @@ -0,0 +1,725 @@ +Strict + +NoDebug + +Private + +?Win32 +Extern "Win32" +Const SW_SHOW=5 +Const SW_RESTORE=9 +Function IsIconic( hwnd ) +Function GetForegroundWindow() +Function SetForegroundWindow( hwnd ) +Function ShowWindow( hwnd,cmdShow ) +Function GetCurrentThreadId() +End Extern +? + +?MacOS +Extern +Function CGDisplayIsCaptured( displayId ) +End Extern +? + +Extern +Global bbStringClass:Byte +Global bbArrayClass:Byte +Global bbNullObject:Byte +Global bbEmptyArray:Byte +Global bbEmptyString:Byte +Global brl_blitz_NullFunctionError:Byte Ptr +Function bbIsMainThread()="bbIsMainThread" +Function bbGCValidate:Int( mem:Int ) = "bbGCValidate" +End Extern + +Function ToHex$( val ) + Local buf:Short[8] + For Local k=7 To 0 Step -1 + Local n=(val&15)+Asc("0") + If n>Asc("9") n=n+(Asc("A")-Asc("9")-1) + buf[k]=n + val:Shr 4 + Next + Return String.FromShorts( buf,8 ).ToLower() +End Function + +Function IsAlpha( ch ) + Return (ch>=Asc("a") And ch<=Asc("z")) Or (ch>=Asc("A") And ch<=Asc("Z")) +End Function + +Function IsNumeric( ch ) + Return ch>=Asc("0") And ch<=Asc("9") +End Function + +Function IsAlphaNumeric( ch ) + Return IsAlpha(ch) Or IsNumeric(ch) +End Function + +Function IsUnderscore( ch ) + Return ch=Asc("_") +End Function + +Function Ident$( tag$ Var ) + If Not tag Return "" + If Not IsAlpha( tag[0] ) And Not IsUnderscore( tag[0] ) Return "" + Local i=1 + While i"]" DebugError "Invalid array typetag" + tag=tag[1..] + Return TypeName( tag )+t+"]" + Case "(" + If tag[..1]<>")" + t:+TypeName( tag ) + While tag[..1]="," + tag=tag[1..] + t:+","+TypeName( tag ) + Wend + If tag[..1]<>")" DebugError "Invalid function typetag" + EndIf + tag=tag[1..] + Return TypeName( tag )+t+")" + End Select + + DebugError "Invalid debug typetag:"+t + +End Function + +'int offsets into 12 byte DebugStm struct +Const DEBUGSTM_FILE=0 +Const DEBUGSTM_LINE=1 +Const DEBUGSTM_CHAR=2 + +'int offsets into 16 byte DebugDecl struct +Const DEBUGDECL_KIND=0 +Const DEBUGDECL_NAME=1 +Const DEBUGDECL_TYPE=2 +Const DEBUGDECL_ADDR=3 + +'DEBUGDECL_KIND values +Const DEBUGDECLKIND_END=0 +Const DEBUGDECLKIND_CONST=1 +Const DEBUGDECLKIND_LOCAL=2 +Const DEBUGDECLKIND_FIELD=3 +Const DEBUGDECLKIND_GLOBAL=4 +Const DEBUGDECLKIND_VARPARAM=5 +Const DEBUGDECLKIND_TYPEMETHOD=6 +Const DEBUGDECLKIND_TYPEFUNCTION=7 + +'int offsets into 12+n_decls*4 byte DebugScope struct +Const DEBUGSCOPE_KIND=0 +Const DEBUGSCOPE_NAME=1 +Const DEBUGSCOPE_DECLS=2 + +'DEBUGSCOPE_KIND values +Const DEBUGSCOPEKIND_FUNCTION=1 +Const DEBUGSCOPEKIND_TYPE=2 +Const DEBUGSCOPEKIND_LOCAL=3 + +Function DebugError( t$ ) + WriteStderr "Debugger Error:"+t+"~n" + End +End Function + +Function DebugStmFile$( stm:Int Ptr ) + Return String.FromCString( Byte Ptr stm[DEBUGSTM_FILE] ) +End Function + +Function DebugStmLine( stm:Int Ptr ) + Return stm[DEBUGSTM_LINE] +End Function + +Function DebugStmChar( stm:Int Ptr ) + Return stm[DEBUGSTM_CHAR] +End Function + +Function DebugDeclKind$( decl:Int Ptr ) + Select decl[DEBUGDECL_KIND] + Case DEBUGDECLKIND_CONST Return "Const" + Case DEBUGDECLKIND_LOCAL Return "Local" + Case DEBUGDECLKIND_FIELD Return "Field" + Case DEBUGDECLKIND_GLOBAL Return "Global" + Case DEBUGDECLKIND_VARPARAM Return "Local" + End Select + DebugError "Invalid decl kind" +End Function + +Function DebugDeclName$( decl:Int Ptr ) + Return String.FromCString( Byte Ptr decl[DEBUGDECL_NAME] ) +End Function + +Function DebugDeclType$( decl:Int Ptr ) + Local t$=String.FromCString( Byte Ptr decl[DEBUGDECL_TYPE] ) + Local ty$=TypeName( t ) + Return ty +End Function + +Function DebugDeclSize( decl:Int Ptr ) + + Local tag=(Byte Ptr Ptr(decl+DEBUGDECL_TYPE))[0][0] + + Select tag + Case Asc("b") Return 1 + Case Asc("s") Return 2 + Case Asc("l") Return 8 + Case Asc("d") Return 8 + End Select + + Return 4 + +End Function + +Function DebugEscapeString$( s$ ) + If s.length>4096 s=s[..4096] + s=s.Replace( "~~","~~~~") + s=s.Replace( "~0","~~0" ) + s=s.Replace( "~t","~~t" ) + s=s.Replace( "~n","~~n" ) + s=s.Replace( "~r","~~r" ) + s=s.Replace( "~q","~~q" ) + Return "~q"+s+"~q" +End Function + +Function DebugDeclValue$( decl:Int Ptr,inst:Byte Ptr ) + If decl[DEBUGDECL_KIND]=DEBUGDECLKIND_CONST + Local p:Byte Ptr=Byte Ptr decl[DEBUGDECL_ADDR] + Return DebugEscapeString(String.FromShorts( Short Ptr(p+12),(Int Ptr (p+8))[0] )) + EndIf + + Local p:Byte Ptr + Select decl[DEBUGDECL_KIND] + Case DEBUGDECLKIND_GLOBAL + p=Byte Ptr decl[DEBUGDECL_ADDR] + Case DEBUGDECLKIND_LOCAL,DEBUGDECLKIND_FIELD + p=Byte Ptr (inst+decl[DEBUGDECL_ADDR]) + Case DEBUGDECLKIND_VARPARAM + p=Byte Ptr (inst+decl[DEBUGDECL_ADDR]) + p=Byte Ptr ( (Int Ptr p)[0] ) + Default + DebugError "Invalid decl kind" + End Select + + Local tag=(Byte Ptr Ptr(decl+DEBUGDECL_TYPE))[0][0] + + Select tag + Case Asc("b") + Return String.FromInt( (Byte Ptr p)[0] ) + Case Asc("s") + Return String.FromInt( (Short Ptr p)[0] ) + Case Asc("i") + Return String.FromInt( (Int Ptr p)[0] ) + Case Asc("l") + Return String.FromLong( (Long Ptr p)[0] ) + Case Asc("f") + Return String.FromFloat( (Float Ptr p)[0] ) + Case Asc("d") + Return String.FromDouble( (Double Ptr p)[0] ) + Case Asc("$") + p=(Byte Ptr Ptr p)[0] + Local sz=Int Ptr(p+8)[0] + Local s$=String.FromShorts( Short Ptr(p+12),sz ) + Return DebugEscapeString( s ) + Case Asc("z") + p=(Byte Ptr Ptr p)[0] + If Not p Return "Null" + Local s$=String.FromCString( p ) + Return DebugEscapeString( s ) + Case Asc("w") + p=(Byte Ptr Ptr p)[0] + If Not p Return "Null" + Local s$=String.FromWString( Short Ptr p ) + Return DebugEscapeString( s ) + Case Asc("*"),Asc("?") + Return "$"+ToHex( (Int Ptr p)[0] ) + Case Asc("(") + p=(Byte Ptr Ptr p)[0] + If p=brl_blitz_NullFunctionError Return "Null" + Case Asc(":") + p=(Byte Ptr Ptr p)[0] + If p=Varptr bbNullObject Return "Null" + If p=Varptr bbEmptyArray Return "Null[]" + If p=Varptr bbEmptyString Return "Null$" + Case Asc("[") + p=(Byte Ptr Ptr p)[0] + If Not p Return "Null" + If Not (Int Ptr (p+20))[0] Return "Null" + Default + DebugError "Invalid decl typetag:"+Chr(tag) + End Select + + Return "$"+ToHex( Int p ) + +End Function + +Function DebugScopeKind$( scope:Int Ptr ) + Select scope[DEBUGSCOPE_KIND] + Case DEBUGSCOPEKIND_FUNCTION Return "Function" + Case DEBUGSCOPEKIND_TYPE Return "Type" + Case DEBUGSCOPEKIND_LOCAL Return "Local" + End Select + DebugError "Invalid scope kind" +End Function + +Function DebugScopeName$( scope:Int Ptr ) + Return String.FromCString( Byte Ptr scope[DEBUGSCOPE_NAME] ) +End Function + +Function DebugScopeDecls:Int Ptr[]( scope:Int Ptr ) + Local n,p:Int Ptr=scope+DEBUGSCOPE_DECLS + While p[n]<>DEBUGDECLKIND_END + n:+1 + Wend + Local decls:Int Ptr[n] + For Local i=0 Until n + decls[i]=p+i*4 + Next + Return decls +End Function + +Function DebugObjectScope:Int Ptr( inst:Byte Ptr ) + Local clas:Int Ptr Ptr=(Int Ptr Ptr Ptr inst)[0] + Return clas[2] +End Function + +Extern +Global bbOnDebugStop() +Global bbOnDebugLog( message$ ) +Global bbOnDebugEnterStm( stm:Int Ptr ) +Global bbOnDebugEnterScope( scope:Int Ptr,inst:Byte Ptr ) +Global bbOnDebugLeaveScope() +Global bbOnDebugPushExState() +Global bbOnDebugPopExState() +Global bbOnDebugUnhandledEx( ex:Object ) +End Extern + +bbOnDebugStop=OnDebugStop +bbOnDebugLog=OnDebugLog +bbOnDebugEnterStm=OnDebugEnterStm +bbOnDebugEnterScope=OnDebugEnterScope +bbOnDebugLeaveScope=OnDebugLeaveScope +bbOnDebugPushExState=OnDebugPushExState +bbOnDebugPopExState=OnDebugPopExState +bbOnDebugUnhandledEx=OnDebugUnhandledEx + +?Win32 +Global _ideHwnd=GetForegroundWindow(); +Global _appHwnd +? + +'********** Debugger code here ********** + +Const MODE_RUN=0 +Const MODE_STEP=1 +Const MODE_STEPIN=2 +Const MODE_STEPOUT=3 + +Type TScope + Field scope:Int Ptr,inst:Byte Ptr,stm:Int Ptr +End Type + +Type TExState + Field scopeStackTop +End Type + +Type TDbgState + Field mode,debugLevel,funcLevel + Field currentScope:TScope=New TScope + Field scopeStack:TScope[],scopeStackTop + Field exStateStack:TExState[],exStateStackTop +End Type + +?Threaded +Extern +Function bbThreadAllocData() +Function bbThreadSetData( index,data:Object ) +Function bbThreadGetData:TDbgState( index ) +End Extern +? + +Function GetDbgState:TDbgState() + Global dbgStateMain:TDbgState=New TDbgState +?Threaded + If bbIsMainThread() Return dbgStateMain + Global dbgStateId:Int=bbThreadAllocData() + Local dbgState:TDbgState=bbThreadGetData( dbgStateId ) + If Not dbgState + dbgState = New TDbgState + bbThreadSetData( dbgStateId,dbgState ) + End If + Return dbgState +?Not Threaded + Return dbgStateMain +? +End Function + +Function ReadDebug$() + Return ReadStdin() +End Function + +Function WriteDebug( t$ ) + WriteStderr "~~>"+t +End Function + +Function DumpScope( scope:Int Ptr,inst:Byte Ptr ) + + Local decl:Int Ptr=scope+DEBUGSCOPE_DECLS + + Local kind$=DebugScopeKind( scope ),name$=DebugScopeName( scope ) + + If Not name name="" + + WriteDebug kind+" "+name+"~n" + + While decl[DEBUGDECL_KIND]<>DEBUGDECLKIND_END + + Select decl[DEBUGDECL_KIND] + Case DEBUGDECLKIND_TYPEMETHOD,DEBUGDECLKIND_TYPEFUNCTION + decl:+4 + Continue + End Select + + Local kind$=DebugDeclKind( decl ) + Local name$=DebugDeclname( decl ) + Local tipe$=DebugDeclType( decl ) + Local value$=DebugDeclValue( decl,inst ) + + WriteDebug kind+" "+name+":"+tipe+"="+value+"~n" + + decl:+4 + Wend +End Function + +Function DumpClassScope( clas:Int Ptr,inst:Byte Ptr ) + + Local supa:Int Ptr=Int Ptr clas[0] + + If Not supa Return + + DumpClassScope supa,inst + + DumpScope Int Ptr clas[2],inst + +End Function + +Function DumpObject( inst:Byte Ptr,index ) + + Local clas:Int Ptr=(Int Ptr Ptr inst)[0] + + If clas=Int Ptr Varptr bbStringClass + + WriteDebug DebugEscapeString(String.FromShorts( Short Ptr(inst+12),(Int Ptr (inst+8))[0] ))+"~n" + + Return + + Else If clas=Int Ptr Varptr bbArrayClass + + Local length=(Int Ptr (inst+20))[0] + + If Not length Return + + Local decl:Int[3] + decl[0]=DEBUGDECLKIND_LOCAL + decl[2]=(Int Ptr (inst+8))[0] + + Local sz=DebugDeclSize( decl ) + + Local p:Byte Ptr=Byte Ptr(20+(Int Ptr (inst+12))[0]*4) + + For Local i=1 To 10 + + If index>=length Exit + + decl[3]=Int(p+index*sz) + + Local value$=DebugDeclValue( decl,inst ) + + WriteDebug "["+index+"]="+value+"~n" + + index:+1 + + Next + + If index~n" + DumpScope t.scope,t.inst + Next +End Function + +Function UpdateDebug( msg$ ) + Global indebug + If indebug Return + indebug=True + + Local dbgState:TDbgState = GetDbgState() + +?Win32 + _appHwnd=GetForegroundWindow(); + 'SetForegroundWindow( _ideHwnd ); +? +?MacOs + 'fullscreen debug too hard in MacOS! + If CGDisplayIsCaptured( 0 ) + WriteStdout msg + End + EndIf +? + WriteDebug msg + Repeat + WriteDebug "~n" + Local line$=ReadDebug() + + Select line[..1].ToLower() + Case "r" + dbgState.mode=MODE_RUN + Exit + Case "s" + dbgState.mode=MODE_STEP + dbgState.debugLevel=dbgState.funcLevel + Exit + Case "e" + dbgState.mode=MODE_STEPIN + Exit + Case "l" + dbgState.mode=MODE_STEPOUT + dbgState.debugLevel=dbgState.scopeStackTop-1 + Exit + Case "t" + WriteDebug "StackTrace{~n" + DumpScopeStack + WriteDebug "}~n" + Case "d" + Local t$=line[1..].Trim() + Local index + Local i=t.Find(":") + If i<>-1 + index=Int( t[i+1..] ) + t=t[..i] + EndIf + If t[..1]="$" t=t[1..].Trim() + If t[..2].ToLower()="0x" t=t[2..].Trim() + Local pointer = Int( "$"+t ) + If Not (pointer And bbGCValidate(pointer)) Then Continue + Local inst:Int Ptr=Int Ptr pointer + + Local cmd$="ObjectDump@"+ToHex( Int inst ) + If i<>-1 cmd:+":"+index + WriteDebug cmd$+"{~n" + + DumpObject inst,index + WriteDebug "}~n" + Case "h" + WriteDebug "T - Stack trace~n" + WriteDebug "R - Run from here~n" + WriteDebug "S - Step through source code~n" + WriteDebug "E - Step into function call~n" + WriteDebug "L - Leave function or local block~n" + WriteDebug "Q - Quit~n" + WriteDebug "H - This text~n" + WriteDebug "Dxxxxxxxx - Dump object at hex address xxxxxxxx~n" + Case "q" + End + End Select + Forever + +?Win32 + If _appHwnd And _appHwnd<>_ideHwnd + If IsIconic(_apphwnd) + ShowWindow _appHwnd,SW_RESTORE + Else + ShowWindow _appHwnd,SW_SHOW + EndIf + _apphwnd=0 + EndIf +? + indebug=False +End Function + +Function OnDebugStop() + UpdateDebug "DebugStop:~n" +End Function + +Function OnDebugLog( message$ ) + WriteStdout "DebugLog:"+message+"~n" +End Function + +Function OnDebugEnterStm( stm:Int Ptr ) + Local dbgState:TDbgState = GetDbgState() + dbgState.currentScope.stm=stm + + Select dbgState.mode + Case MODE_RUN + Return + Case MODE_STEP + If dbgState.funcLevel>dbgState.debugLevel + Return + EndIf + Case MODE_STEPOUT + If dbgState.scopeStackTop>dbgState.debugLevel + Return + EndIf + End Select + + UpdateDebug "Debug:~n" +End Function + +Function OnDebugEnterScope( scope:Int Ptr,inst:Byte Ptr ) + + Local dbgState:TDbgState = GetDbgState() + GCSuspend + + If dbgState.scopeStackTop=dbgState.scopeStack.length + dbgState.scopeStack=dbgState.scopeStack[..dbgState.scopeStackTop * 2 + 32] + For Local i=dbgState.scopeStackTop Until dbgState.scopeStack.length + dbgState.scopeStack[i]=New TScope + Next + EndIf + + dbgState.currentScope=dbgState.scopeStack[dbgState.scopeStackTop] + + dbgState.currentScope.scope=scope + dbgState.currentScope.inst=inst + + dbgState.scopeStackTop:+1 + + If dbgState.currentScope.scope[DEBUGSCOPE_KIND]=DEBUGSCOPEKIND_FUNCTION dbgState.funcLevel:+1 + + GCResume +End Function + +Function OnDebugLeaveScope() + + Local dbgState:TDbgState = GetDbgState() + GCSuspend + + If Not dbgState.scopeStackTop DebugError "scope stack underflow" + + If dbgState.currentScope.scope[DEBUGSCOPE_KIND]=DEBUGSCOPEKIND_FUNCTION dbgState.funcLevel:-1 + + dbgState.scopeStackTop:-1 + + If dbgState.scopeStackTop + dbgState.currentScope=dbgState.scopeStack[dbgState.scopeStackTop-1] + Else + dbgState.currentScope=New TScope + EndIf + + GCResume +End Function + +Function OnDebugPushExState() + + Local dbgState:TDbgState = GetDbgState() + GCSuspend + + If dbgState.exStateStackTop=dbgState.exStateStack.length + dbgState.exStateStack=dbgState.exStateStack[..dbgState.exStateStackTop * 2 + 32] + For Local i=dbgState.exStateStackTop Until dbgState.exStateStack.length + dbgState.exStateStack[i]=New TExState + Next + EndIf + + dbgState.exStateStack[dbgState.exStateStackTop].scopeStackTop=dbgState.scopeStackTop + + dbgState.exStateStackTop:+1 + + GCResume +End Function + +Function OnDebugPopExState() + + Local dbgState:TDbgState = GetDbgState() + GCSuspend + + If Not dbgState.exStateStackTop DebugError "exception stack underflow" + + dbgState.exStateStackTop:-1 + + dbgState.scopeStackTop=dbgState.exStateStack[dbgState.exStateStackTop].scopeStackTop + + If dbgState.scopeStackTop + dbgState.currentScope=dbgState.scopeStack[dbgState.scopeStackTop-1] + Else + dbgState.currentScope=New TScope + EndIf + + GCResume +End Function + +Function OnDebugUnhandledEx( ex:Object ) + + GCSuspend + + UpdateDebug "Unhandled Exception:"+ex.ToString()+"~n" + + GCResume +End Function \ No newline at end of file diff --git a/mod/brl.mod/audio.mod/audio.bmx b/mod/brl.mod/audio.mod/audio.bmx new file mode 100644 index 0000000..d2733d1 --- /dev/null +++ b/mod/brl.mod/audio.mod/audio.bmx @@ -0,0 +1,381 @@ + +Strict + +Rem +bbdoc: Audio/Audio playback +End Rem +Module BRL.Audio + +ModuleInfo "Version: 1.07" +ModuleInfo "Author: Mark Sibly" +ModuleInfo "License: zlib/libpng" +ModuleInfo "Copyright: Blitz Research Ltd" +ModuleInfo "Modserver: BRL" + +ModuleInfo "History: 1.07 Release" +ModuleInfo "History: Added flags to LoadSound" +ModuleInfo "History: Driver now set to Null if SetAudioDriver fails" +ModuleInfo "History: 1.06 Release" +ModuleInfo "History: Changed default device to FreeAudio" +ModuleInfo "History: 1.05 Release" +ModuleInfo "History: Added driver list and SetAudioDriver" + +Import BRL.AudioSample + +Private + +Global _nullDriver:TAudioDriver=New TAudioDriver + +Global _driver:TAudioDriver,_drivers:TAudioDriver + +Function Driver:TAudioDriver() + If _driver Return _driver +?Win32 + If SetAudioDriver( "DirectSound" ) Return _driver +?Not Win32 + If SetAudioDriver( "FreeAudio" ) Return _driver +? + SetAudioDriver "Null" + Return _driver +End Function + +Function Shutdown() + If Not _driver Return + _driver.Shutdown + _driver=Null +End Function + +atexit_ Shutdown + +Public + +Const SOUND_LOOP=1 +Const SOUND_HARDWARE=2 + +Rem +bbdoc: Audio sound type +End Rem +Type TSound + + Rem + bbdoc: Play the sound + returns: An audio channel object + about: + Starts a sound playing through an audio channel. + If no channel is specified, #Play automatically allocates a channel for you. + End Rem + Method Play:TChannel( alloced_channel:TChannel=Null ) + Return New TChannel + End Method + + Rem + bbdoc: Cue the sound for playback + returns: An audio channel object + about: + Prepares an audio channel for playback of a sound. + To actually start the sound, you must use the channel's #SetPaused method. + If no channel is specified, #Cue automatically allocates a channel for you. + + #Cue allows you to setup various audio channel states such as volume, pan, depth and rate before a sound + actually starts playing. + End Rem + Method Cue:TChannel( alloced_channel:TChannel=Null ) + Return New TChannel + End Method + + Rem + bbdoc: Load sound + returns: A sound object + about: + @url can be either a string, a stream or an audio sample object. + The returned sound object can be played using #Play or #Cue. + End Rem + Function Load:TSound( url:Object,loop_flag ) + Local sample:TAudioSample + sample=TAudioSample( url ) + If Not sample sample=LoadAudioSample( url ) + If sample Return Driver().CreateSound( sample,loop_flag ) + End Function + +End Type + +Rem +bbdoc: Audio channel Type +End Rem +Type TChannel + Rem + bbdoc: Stop audio channel playback + about: + Shuts down the audio channel. Further commands on this audio channel will have no effect. + End Rem + Method Stop() + End Method + Rem + bbdoc: Pause or unpause audio channel playback + about: + If @paused is True, the audio channel is paused. Otherwise, the audio channel is unpaused. + End Rem + Method SetPaused( paused ) + End Method + Rem + bbdoc: Set audio channel volume + about: + @volume should be in the range 0 (silence) to 1 (full volume). + End Rem + Method SetVolume( volume# ) + End Method + Rem + bbdoc: Set audio channel stereo pan + about: + @pan should be in the range -1 (full left) to 1 (full right). + End Rem + Method SetPan( pan# ) + End Method + Rem + bbdoc: Set audio channel depth + about: + @depth should be in the range -1 (back) to 1 (front). + End Rem + Method SetDepth( depth# ) + End Method + Rem + bbdoc: Set audio channel playback rate + about: + @rate is a multiplier used to modify the audio channel's frequency. + For example, a rate of .5 will cause the audio channel + to play at half speed (ie: an octave down) while a rate of 2 will + cause the audio channel to play at double speed (ie: an octave up). + End Rem + Method SetRate( rate# ) + End Method + Rem + bbdoc: Determine whether audio channel is playing + returns: True if @channel is currently playing + about: + #Playing will return False if the audio channel is either paused, or has been stopped + using #Stop. + End Rem + Method Playing() + End Method + +End Type + +Type TAudioDriver + + Method New() + _succ=_drivers + _drivers=Self + End Method + + Method Name$() + Return "Null" + End Method + + Method Startup() + Return True + End Method + + Method Shutdown() + End Method + + Method CreateSound:TSound( sample:TAudioSample,loop_flag ) + Return New TSound + End Method + + Method AllocChannel:TChannel() + Return New TChannel + End Method + + Method LoadSound:TSound( url:Object, flags:Int = 0) + Return TSound.Load(url, flags) + End Method + + Field _succ:TAudioDriver + +End Type + +Rem +bbdoc: Load a sound +returns: A sound object +about: +@url can be either a string, a stream or a #TAudioSample object. +The returned sound can be played using #PlaySound or #CueSound. + +The @flags parameter can be any combination of: + +[ @{Flag value} | @Effect +* SOUND_LOOP | The sound should loop when played back. +* SOUND_HARDWARE | The sound should be placed in onboard soundcard memory if possible. +] + +To combine flags, use the binary 'or' operator: '|'. +End Rem +Function LoadSound:TSound( url:Object,flags=0 ) + Return Driver().LoadSound( url,flags ) +End Function + +Rem +bbdoc: Play a sound +returns: An audio channel object +about: +#PlaySound starts a sound playing through an audio channel. +If no @channel is specified, #PlaySound automatically allocates a channel for you. +end rem +Function PlaySound:TChannel( sound:TSound,channel:TChannel=Null ) + Return sound.Play( channel ) +End Function + +Rem +bbdoc: Cue a sound +returns: An audio channel object +about: +Prepares a sound for playback through an audio channel. +To actually start the sound, you must use #ResumeChannel. +If no @channel is specified, #CueSound automatically allocates a channel for you. + +#CueSound allows you to setup various audio channel states such as volume, pan, depth +and rate before a sound actually starts playing. +End Rem +Function CueSound:TChannel( sound:TSound,channel:TChannel=Null ) + Return sound.Cue( channel ) +End Function + +Rem +bbdoc: Allocate audio channel +returns: An audio channel object +about: +Allocates an audio channel for use with #PlaySound and #CueSound. +Once you are finished with an audio channel, you should use #StopChannel. +end rem +Function AllocChannel:TChannel() + Return Driver().AllocChannel() +End Function + +Rem +bbdoc: Stop an audio channel +about: +Shuts down an audio channel. Further commands using this channel will have no effect. +end rem +Function StopChannel( channel:TChannel ) + channel.Stop +End Function + +Rem +bbdoc: Determine whether an audio channel is playing +returns: #True if @channel is currently playing +about: +#ChannelPlaying will return #False if either the channel has been paused using #PauseChannel, +or stopped using #StopChannel. +end rem +Function ChannelPlaying( channel:TChannel ) + Return channel.Playing() +End Function + +Rem +bbdoc: Set playback volume of an audio channel +about: +@volume should be in the range 0 (silent) to 1 (full volume) +end rem +Function SetChannelVolume( channel:TChannel,volume# ) + channel.SetVolume volume +End Function + +Rem +bbdoc: Set stereo balance of an audio channel +about: +@pan should be in the range -1 (left) to 1 (right) +end rem +Function SetChannelPan( channel:TChannel,pan# ) + channel.SetPan pan +End Function + +Rem +bbdoc: Set surround sound depth of an audio channel +about: +@depth should be in the range -1 (back) to 1 (front) +end rem +Function SetChannelDepth( channel:TChannel,depth# ) + channel.SetDepth depth +End Function + +Rem +bbdoc: Set playback rate of an audio channel +about: +@rate is a multiplier used to modify the audio channel's frequency. +For example, a rate of .5 will cause the audio channel +to play at half speed (ie: an octave down) while a rate of 2 will +cause the audio channel to play at double speed (ie: an octave up). +end rem +Function SetChannelRate( channel:TChannel,rate# ) + channel.SetRate rate +End Function + +Rem +bbdoc: Pause audio channel playback +about: +Pauses audio channel playback. +end rem +Function PauseChannel( channel:TChannel ) + channel.SetPaused True +End Function + +Rem +bbdoc: Resume audio channel playback +about: +Resumes audio channel playback after it has been paused by #CueSound or #PauseChannel. +end rem +Function ResumeChannel( channel:TChannel ) + channel.SetPaused False +End Function + +Rem +bbdoc: Get audio drivers +about: +Returns an array of strings, where each string describes an audio driver. +End Rem +Function AudioDrivers$[]() + Local devs$[100],n + Local t:TAudioDriver=_drivers + While t And n<100 + devs[n]=t.Name() + n:+1 + t=t._succ + Wend + Return devs[..n] +End Function + +Rem +bbdoc: Determine if an audio driver exists +about: +Returns True if the audio drvier specified by @driver exists. +End Rem +Function AudioDriverExists( name$ ) + name=name.ToLower() + Local t:TAudioDriver=_drivers + While t + If t.Name().ToLower()=name Return True + t=t._succ + Wend +End Function + +Rem +bbdoc: Set current audio driver +about: +Returns true if the audio driver was successfully set. +End Rem +Function SetAudioDriver( name$ ) + name=name.ToLower() + Shutdown + _driver=_nullDriver + Local t:TAudioDriver=_drivers + While t + If t.Name().ToLower()=name + If t.Startup() + _driver=t + Return True + EndIf + Return False + EndIf + t=t._succ + Wend +End Function diff --git a/mod/brl.mod/audio.mod/doc/allocchannel.bmx b/mod/brl.mod/audio.mod/doc/allocchannel.bmx new file mode 100644 index 0000000..a908a2c --- /dev/null +++ b/mod/brl.mod/audio.mod/doc/allocchannel.bmx @@ -0,0 +1,11 @@ +'AllocChannel.bmx + +timer=createtimer(20) + +sound=LoadSound ("shoot.wav") +channel=AllocChannel() + +for i=1 to 20 + waittimer timer + playsound sound,channel +next diff --git a/mod/brl.mod/audio.mod/doc/channelplaying.bmx b/mod/brl.mod/audio.mod/doc/channelplaying.bmx new file mode 100644 index 0000000..b0e6007 --- /dev/null +++ b/mod/brl.mod/audio.mod/doc/channelplaying.bmx @@ -0,0 +1,10 @@ +' channelplaying.bmx + +sound = LoadSound ("shoot.wav") + +Input "Hit return to begin channelplaying test, use ctrl-C to exit" + +channel=playsound (sound) +while true + print "ChannelPlaying(channel)="+ChannelPlaying(channel) +wend diff --git a/mod/brl.mod/audio.mod/doc/cuesound.bmx b/mod/brl.mod/audio.mod/doc/cuesound.bmx new file mode 100644 index 0000000..c9156ad --- /dev/null +++ b/mod/brl.mod/audio.mod/doc/cuesound.bmx @@ -0,0 +1,12 @@ +Rem +CueSound example +End Rem + +sound=LoadSound("shoot.wav") +channel=CueSound(sound) + +Input "Press return key to play cued sound" + +ResumeChannel channel + +Input "Press return key to quit" diff --git a/mod/brl.mod/audio.mod/doc/intro.bbdoc b/mod/brl.mod/audio.mod/doc/intro.bbdoc new file mode 100644 index 0000000..05ec375 --- /dev/null +++ b/mod/brl.mod/audio.mod/doc/intro.bbdoc @@ -0,0 +1,14 @@ + +The BlitzMax audio module contains commands to load and play sounds. + +A sound file can be played in BlitzMax with a combination of #LoadSound that loads a sound file +and #PlaySound which plays the sound through the systems audio system if available. + +BlitzMax contains native support for sound files in both .wav (uncompressed) +and .ogg (compressed) file formats. + +Playback of sounds can be controlled with various audio channel +operators including #SetChannelVolume, #SetChannelPan, #SetChannelDepth and #SetChannelRate. + +A channel handle is obtained from either the return value of #PlaySound and #CueSound or from +reserving a channel with #AllocChannel. diff --git a/mod/brl.mod/audio.mod/doc/loadsound.bmx b/mod/brl.mod/audio.mod/doc/loadsound.bmx new file mode 100644 index 0000000..66fedaf --- /dev/null +++ b/mod/brl.mod/audio.mod/doc/loadsound.bmx @@ -0,0 +1,8 @@ +Rem +Load and Play a small example wav file. +End Rem + +sound=LoadSound("shoot.wav") +PlaySound sound + +Input "Press any key to continue" diff --git a/mod/brl.mod/audio.mod/doc/playsound.bmx b/mod/brl.mod/audio.mod/doc/playsound.bmx new file mode 100644 index 0000000..5807eba --- /dev/null +++ b/mod/brl.mod/audio.mod/doc/playsound.bmx @@ -0,0 +1,8 @@ +Rem +Load and Play a small example wav file with looping. +End Rem + +sound=LoadSound("shoot.wav",true) +PlaySound sound + +Input "Press any key to continue" diff --git a/mod/brl.mod/audio.mod/doc/setchanneldepth.bmx b/mod/brl.mod/audio.mod/doc/setchanneldepth.bmx new file mode 100644 index 0000000..8ba371b --- /dev/null +++ b/mod/brl.mod/audio.mod/doc/setchanneldepth.bmx @@ -0,0 +1,25 @@ +' setchanneldepth.bmx + +Graphics 640, 480 + +channel = AllocChannel () +sound = LoadSound ("shoot.wav") ' Use a short sample... + +Repeat + If MouseHit(1) PlaySound sound,channel + + pan# = MouseX () / (640 / 2.0) - 1 + depth# = MouseY () / (480 /2.0) -1 + + SetChannelPan channel,pan + SetChannelDepth channel,depth + + Cls + DrawText "Click to play...", 240, 200 + DrawText "Pan : " + pan, 240, 220 + DrawText "Depth : " + depth, 240, 240 + + Flip +Until KeyHit (KEY_ESCAPE) + +End diff --git a/mod/brl.mod/audio.mod/doc/setchannelpan.bmx b/mod/brl.mod/audio.mod/doc/setchannelpan.bmx new file mode 100644 index 0000000..353bcf7 --- /dev/null +++ b/mod/brl.mod/audio.mod/doc/setchannelpan.bmx @@ -0,0 +1,24 @@ +' setchannelpan.bmx + +Graphics 640, 480 + +channel = AllocChannel () +sound = LoadSound ("shoot.wav") ' Use a short sample... + +Repeat + If MouseHit(1) PlaySound sound,channel + + pan# = MouseX () / (GraphicsWidth () / 2.0) - 1 + vol# = 1 - MouseY () / 480.0 + SetChannelPan channel, pan + SetChannelVolume channel, vol*2 + + Cls + DrawText "Click to play...", 240, 200 + DrawText "Pan : " + pan, 240, 220 + DrawText "Volume: " + vol, 240, 240 + + Flip +Until KeyHit (KEY_ESCAPE) + +End diff --git a/mod/brl.mod/audio.mod/doc/setchannelrate.bmx b/mod/brl.mod/audio.mod/doc/setchannelrate.bmx new file mode 100644 index 0000000..6af0cd9 --- /dev/null +++ b/mod/brl.mod/audio.mod/doc/setchannelrate.bmx @@ -0,0 +1,12 @@ +' setchannelrate.bmx + +timer=CreateTimer(20) + +sound = LoadSound ("shoot.wav",True) +channel=CueSound(sound) +ResumeChannel channel + +For rate#=1.0 To 4 Step 0.01 + WaitTimer timer + SetChannelRate channel,rate +Next diff --git a/mod/brl.mod/audio.mod/doc/setchannelvolume.bmx b/mod/brl.mod/audio.mod/doc/setchannelvolume.bmx new file mode 100644 index 0000000..4783eeb --- /dev/null +++ b/mod/brl.mod/audio.mod/doc/setchannelvolume.bmx @@ -0,0 +1,12 @@ +' setchannelvolume.bmx + +timer=CreateTimer(20) + +sound = LoadSound ("shoot.wav") + +For volume#=.1 To 2 Step .05 + WaitTimer timer + channel=CueSound(sound) + SetChannelVolume channel,volume + ResumeChannel channel +Next diff --git a/mod/brl.mod/audio.mod/doc/shoot.wav b/mod/brl.mod/audio.mod/doc/shoot.wav new file mode 100644 index 0000000000000000000000000000000000000000..0bea437d98e7f9e954a0255c8f882b66cf17a359 GIT binary patch literal 10576 zcmXwf1$Y$K_x6>M)r2G@!Ci_LFYfMAyjbv-;9A_BVns>`?(XjH?i80K#MefyeCPLn zo-g;=&F;?Z&YdIgd5^Sj*0^!g5(ss!*QwEf_|XNjA%rljh*Ag@>VyzM*-*beqx%$r zbN>Gy{=XLl8Pb%QGF>LiPf|z(?^EPs`BdJLMCO&PP&)oY`Kra~0on=Qr%%)tB$^IT za^mK=J|g%k>L{Db*J3A6;Zyi37GfvZ8@s;U%>HUWXJ43uOLl^nVtLqAKA%nGLEe}T z7YY0{-y#Rd{xS|#$2IX>RF@1U3|A-B$qzh;tRZJ`PwXNd%HZ>6^bX0u185XoK%4}V zIwS`Tw5u$$#+M zygy&Xn~SILYO1I$4)B`17Ox_%@x8n%-@`qk4eWRVi|2dU5FRd4`0rvfpUHKR!4r7` zpT>LhL%f}gL1j@snZWalqoR^5Ef1`}Gb)URpx02I_pEll^)Wuzs&K+DiH8b_kCTg+1iSYzmKOWyB!Slob$(;(ylEQCt?Sg)Z-j zE;0iiGvq<>SacT0#IJInOag7Km#6VlvPSi*P3R@mfc&8h#7;7d7R24qd$8dX=z}OE z3P}aDeTr2THSM|FZ#T88SqJT-d@8KT{1MB>9<#wb&Dz5H^J%Q9eM?MdbL4(;0_-zg zHX?tayC@G%LTAMynka+#1D+v|p*P5_6h%oi4(}jyz!&Z-eUz`HCXOY8$QxxlN+%0-yZ}fL3=5|Nah@4fcgRG?0hBrhd;@z_B>L7-~H~`S?ff!bJ6|+vU$pVkcND9NnFO37`cojM$>=rkK+X2>SA7&XZ(`>3_s9!2IUm(@(X!Ya;Zi{s?7T8<8o zjnN=>2A_3aR&*s(3}tPt8uF_iNhc}2&;nz!m@Kc-W%?iFrW|Db#VX+a_^RGX{lFW_ zLTol`sm!F^)JaNtxkkRXpQ9&gHF8|-OZM@zq7Wx|rZ!1Apll-(>{9$DpT|q;&7G6U za9Rvu<13$rZ=l~D#Ca8+!Mh%-O%!r?If=n z5Jv*bf-QxR87v%~))aLF?`JKyxtVTkVnUq#-8~#Adl1I#2!7y_ZAE9sd8lIKTA9N!*PwSFaIAoO#jtC}&h6qLn zXjxiAwURPHKdEPuHzIqeif?u3f&EN;!hX4jFUGmmp039vYdX`eZigL97A8(vDOW>wef^EH;$IT3aqS7|AjjdxbiQ&-zoeB!AB@FWWzx!IGz@JM7A>t6)}GOcz=Db? z0sXB0LEEQ9a1@C2jq~>m#j$k!O!=24;f^$?c229P_i%P|9uJ#G}FEkI%&LSH)NRHXqPuN^PYLkx+P9(eLdqn)12G1 ztz@hn9vISoKg>C`6Vr@rD!haY4!=t#bkBDfk{VS=p~`~BD#?YBd<_%Pbm(b`qbRn^(a(Lukij-y>r50NS6 z0PA@yo3o$I)ZoBCLSR&|UFeF@&%P(~t8vcF?l!KY`bhOHy-thJ8#oW@FGryRq!Jy8 z>adH!U$SB|64FU#bANZkW_L+#$9JzkVnAek_%N4O-GIX7bCE;T;$7KN78J|KEOnOJ zpETslL;3wbvas)j-y7oQeepsm2Y-aD|V^J@h|rk&8u%G}K$&>~wiHcq}(}j?g}l=I8}4 zWLGw9|B}qFX<=zrTK~)$fxPx-G)v8J+;VU64);EH|Lj`m=%Z;$C9)e$lxxK|euT$} zcsT=4qq)?Q+6ygC`;Q)%jqSyuGyc6<8!|6|?hE)%`7-^RLLobV@@ap#zlV>HOo<#5 zu{P|D>p!g)orA85NxTiaWJR0LLSKTtgD-+{Mh|NiTPc144!R6o5>Ht{d#Ab0C~B-X zMnYUdXgayA6xSC!+h9G_!2K?kx(;##VnH9AT!1{GT;yW zYyHh^{!UboOQlZ^M;-7bGDJyJrPf3Ls@+zrE6JoknMoq(3tCuB)J8gmOrK zaJ%2_Yn-_)y>Hs4)J3Ud(z<43_YDjdvTBIx*o(FRljKg3svNrm#4x=HtSk3W?WWQCHY#X2q51W#RWb?;Ws3-?3U zGG{}FU%RNTQl`@$Bo@Dud&M$7i{-cfF>`{)89!x> z_0I_9w-1V@stgtHK)xuAOC3stVKDj11 z@9AGuT`544dequ}ww(~d7dYOQqdcHos6Y1$~a}8@}ycRoZwKTIr z>w>KV1^tzLe`dYNT$s5u^G@cFtRcRS{++=SMjiVb--de9BH9&4jJvd#g)PW-AYwse zL{wZ<&!_@X&m&t$E|1uiZCQBhFsJulcRp8F$6W2H;-RhZboqrh27Z`k3=J$rog<>)ifoujX2kIh~tN{O7E?Q2+l??CrN=XianIvy$;Rb&kR$sS^w zp*_Lrfdl@c{+GTdzEb|({tn`89q3GTBS~ zKi*R86A^N|ED5>gUK~%l(uvAYwWl^pU+Ng{Ea6IZjd$;IKX5;BKXw1>#_mO~lg{0a zHF`tsl%jydR?4gVt?jT}1`p)-_sH6pk(@R-)%tNLIWehrQYi6NqLnx$sZ?@-AKgyiu1kun0Hxtg@}uht+W3VeJEygY`+{ka;$@u zkmK(h<#H^DT@*7Wx(;AKrHJO?gS~y+U7dOK8_H_ZAC(v3?3;NobSiM%cRDjHV?)}w z)VP#{AD$nxl1nFlOgfTuBgv6mKY2v*z2t#EXv!zp$>p?X>4h^VW*ztC3#<=zGfG(w z_Ka_r8}SahMcu4#bk29z_r4A5knLE+qsUcJt+SubZe=eRjiMiA@0k5SRIaG@5P=qD ziwifr3q9rC&z*lbvb6bX7X6b%;?)w1{w&=ZY`To=!G8mj0hcak=~;6#V>3TxyvVqk z@iwDG=7!8%S*NoO`yTsoa6ssh(aZX1_u;9cJ=%)TkP~#K(pdGWi?vvNyuKZn;C6km zo?l<171h?L50p$m)1G8HK7;(SlpG3`q(VG_4w8*J6|P)U*Jv~JMvjnUi?f;Qg{zwTcR=?h?t<>SuI{cI&dSb( zjuZMFEmL)N?$G3@!Yw}UC)~y)-+p-h<=d+qdI4A99<#C6Z<}PUXC?6R^(Wn zV`Ywia#YGOF*YG)L-gwGGongHUd%QkoQ93{{O2m*tg81_m(Xjt7>XBfSr=QiZW{5S zZow&m&HnwqQ(1SwWnz}I6m3B0(6{M{HWt`4DmvtEs z&=dSQ)CCaZuyw=!!k+Mp;*4C6_TiR)Ot6{+WyKb3}xq>t%h`YTlb2)#lkk||^b8AjTW zDx?D$2zb+gG$-|mhh#xzZUdf&|G?dF4O|c#XdfDga-q9&k*qEg#ZVD068U;Qns??o z`E9nCO=JBb0x0Z*eaYTs_pyuGPWz^H%}Ta1Eo4W56_>GF+3W59?3}C(`-k~h1^yc! z!ngBOoPZXK5dE({^ebwP+QPN_p~k2@%7gNv3aBE~J%53! zWL?w%4M$thO{g*{xIS)$JK}|SD^z$cKt`N|V@MOYn<$cpSU4T(Z`<%*d;sr;|C{km zd=;PgzvpN89sZ0{F%-OrN(zwLq!VdJMv@I=Ke<5e0vf+3XUTeU5!Mc}fGi_B;n;Sl zmHtJ>lWwF2p!6ra0@$2{I@TccUAC21MOAT(m*>Y>d3Mn5W&dPvx5`*Y%!1}#qm5w# zyDJiUAN(uWIG8;c2;2*73M>x92l@pT2IdB~1&#$?2MPxJ1z!alhYp518pX_S<{GP^ z{n1{)Y5+sHCML)ps4Vv5TVw&PuXxoD>LqQSUfbbzUUZId<#AteH}#zN)c5Z5qOcNS z9l{2L#fJ?JYaA98_R)LT+aEmahG!x$qx$X}t{7Jj=Q>BC-cDZx3^=>mLfJqck(|Kt zmZMuxLCp!7&|tRQ-etWpbDM*WH6aUf@i&16f$RRs{(}Caz7f7^z6js5tZP{}vkqjP z$~u|#HY>ZY9`NMlzGuFi{;~c{e~G}1fCzL9ehv-^?F^~LRKsUXH;Y;itQmG0mc-Wc z`r^JA34Gx-nt)4?L!>G_Knp47l^As~VCVqtvsOv}TX#C*9nT#dojaWw&R(u9fG9Uz z?_A$q8Lp4;>bPr#tD&o$E4%BVbGLJdv#|4tW0#}4v&Sjh`OFQPcRVpp&k*l#bZ6y(mIpnB2GtYRwWQ)7>D+}LLH zHCh;rjEY7zqm|Li7-Y;dju_XBGsXv_pjq4OXRb7#n#pEvYp}J+x?>fxhuLfFTlQzW z9Gk=TLhY{r@5q<%dpw_*EG`Kq8q0<9y>y^5s2AFZz5*Y}fji+jV9%@Y9(*4^1Dn2p z--4BvAo)pMGJ(t?3FJAUG(a**4Ak~J(F(K;okAzVz0Iaa=qj|Vm(U5cAFWMY^f}o`eudw+@N4j+>A*>1px>b2yJ#w! zfEqzB=&L*=N6UsFtvkS8ri#(x58)Aqfx9;5rMZXSV+YtcR*My4m02l<*njpj+h-@+ zXY951pZ0Kjn!Uk3XfL#v*h}rd?X3{oy4daQ4si6j{mD+UGwm4Gi>+fjV4Y;QA-YuI zEqO0K3VKAxcox(aiiy&qy_gFGh#x^+ zy*udwm8p0#2JUS$ISw6;CnTL{6jMJb0#a*9C(&tiAoNSx(iXH4^hx4i4WaYsc-ogX z2du0}>qDfLoGpKoO=PT07ayS8b6dO>FU0||2Uz}a$j*BJTI3Y5qOiy#Onw=y}@Ss^LXBzSK+02N!|i7wvoI8FAE)!3`Tfv9uBWCr#upvgoEee z^>{Vjmj4C6vYjvDGx!3&60GhF|IU-)x80(Ys1CC1FUE-zP*t&nAF7A7Wd&IjG&~6Q zy;eSu`B5trho+!q=qh>u(tV92s*4vu|LiHgh>zhrP-H7cnu3H^f^=_@EU?B1nvX_O zPRh`Rv?<861IV@vtafw|$a)qX1{OLKtZotAN;kkK8|Z)3ps(l(I-O31bIZZEedG+- z_+&B(dV29B0&Maf=yM+)jeo%e`YJb}@3a@qL=otsTp>ruGV+O-A@T_-KJ)W@H=oGs z@My@vj^NP3x+)*ScZ7vhG>ytd>?itDIHD`pGJ0Rj{gB zt*l|zF6*?l&020Pv2Ix(;5-``e0}ia>$YVR$aV6v4s0IV09B&R>;VV%Z1pm~Pp~_+9qk`2uYD2ZV zx=LN4PE`A=)6~Oiy4q0tP3x_V*XC;fY74afT0FdOq?Oeow2$g_U<23HgOH>5QJbsf zAWy%i+*i&h%akTc4&@=(b{(2Z&OyW)Pg;^fMtRjnH!ai${x4rfbYp7MlinIde8*`ai#|$%5jb!7a@yNIg)tG-F zo1J3}H<|(>b^|=DXOw^#=MNPy+QYG{fQuiE3?tV3!(46Ng`Bst)x{cMjj$v9>MNd0%!6KDL%Bp=0Yq$wmZKEZ7WSPCechIDCm%^6Ish;&r_x1P zsk~G2sa@3#YNFaeo2PBk61D1jKYf7SU60qt05iIzKh-TgOHb6l=lQQpwwbSdphbJ7nG_q&7NS0NIR zxF7c73&2XeV11*&UtWn_VyF01M2oB7uNCff@1`*l-$ojRwZA#z13+ zanMlBa%O#Vq`B0*YAV(*R$prsSY|2URwL}qzz}Ld2l_e-18(&<^wn#L`Qjt=mRo>- zY?I$)8Q@F%kr$5verMq-WGL{Mcf>`jfE|vfyD3t7D_23D!_?jCP4$}^p)~`G+pO(? zx?YBs3YGVO7OpqaC+S-uo4Kf;00}PESL)mJefkFAo>TRfdT~969<7_&V{MVvTFb6| zR&T4@)H&){wWXRv&43C+7bTUh25iks&jB_|d>Gu!?Mq2p|c zgJPIS1*SQW=L1~32t2bN%gy}u9ecSw33z5T$YHixZLM&~WU%G7a#|%Uhm~eNG!L6A z%s8{D*#e|p$BZ@8jJL*ZW9bXBm&^bL>?IE&lDENyupeDRhtMvFP7?sps~|VJ0DQZV^uZ*;WYJNS6*^RN zPD6xf5Ah>{+w2nC#Fjucx+U<~;w+3gShD@lK4g!z8`_0zkDYF%1Hb=beFS{G43;>; z>SWcn+E_yXFGhoZU$j13s$IY?X;-$(+g0qw(813O@2c8OAnFgYq1y;ZS_>ln47L%j z_K>|~HY>}=@)JCb7ljV?Sg}Fe5-B1l?6bWb3y8WC=1aayf-1vZtb)mi{Sa^80lw;x zr!>GVAZOW+Q?M7}^8~1(JOTUuKrB)oWYPmB9pY$j+J$z8=#xOtL7w`J3Ti=K<%LyB zX`s|rN-9N_yh;qL%F3@wPk7W;YAB_ZNJRy^eMRrnopdf8N?X&?R0CGv0~U4&@`C;l z1FMtDkUhPF++rK>wyAg$c-mO7h9HM!?=%qU>`v`M?oX2*cNt>?FWXm1TwERECJAS zIeeDD76JF_3(_3T*0Lk)5IfCofXyZ`0f>+X_&{lxSZTnk!*fgCg^%G20VR&|r(n+) z;aZ;{7c)2&`Jw(;NwgDVL~k(yuy`R@`3ca04f8M+K@UCU5Wtf$z*x7z)C!Z4s358d zETIGH13FoZj-!__uVR5t^5ELI7ewr}_%_7uAGjdMryelO-vCLQlUk$^TRFtgKww1*tE0Z6wge77sc0&!V0LC~KJw+EGOFIG6Gz-yK)D;-xFQ_<* zfsE3F66F`*JKJGmq&sM(3hoY;2#o@H<7;qiQWUrzJOz2VLGTZe4{cvmjbSr52jlxiF#1WYYu)lL5vr_ z0}~t$);z4>+O|X9G4|1Uqmh#P82Ay|fKxt=7Pl&q?5JCjco=fal&s*U>@H#wK8M$6+5Q z&}q=n6?6{H+6A0*8Q9YxR1fxE0rp-QICTrC33P^?4@JGf=GsGTxfxUh^1)q|L_Yzh zaj2)h1Kza;WHD04$sQ0#s)O80$_VL&o~$X-#T&>T-T_DZEbfVOkbj*Khe6(3Afwp> zy!?pR4)R|QsCWe4Z--A0iARuad=kk5$pYX3-2w6Y!lS!vEgQfLS8@3>*h>S@O-ayE zez=kXwOS4uN`~*HfSzojfu{0+?#jY$8bLPD3hKFiH@D?!>g`PAsGhtya435741N$K$2&G zs~-h9J^=Rl9sK}|d;?lYgKB>UN`{H9iy-|IaQ-T^0{snAUJAO|23pyVj={03po6>U z7P6DTL6ARBM~mS5o1hl64xYEcY}WzU#d0`% z1)RSOzA+s21bk==tJeSNDL;yWdBKmJRYATb!7Iyy%!`55hr#lIhyKqqib4&w2*|!994QAfZVB@I15j!-ctwBN z3*Pktw5<)tipqlEO@(AW&_^Db8@^QxG*}+KQxCKf2iKhqYcy!LBRqP6{d5P+>kd=0 MemFree samples + End Method + + Rem + bbdoc: Copy audio sample + returns: A new audio sample object + end rem + Method Copy:TAudioSample() + Local t:TAudioSample=Create( length,hertz,format ) + CopySamples samples,t.samples,format,length + Return t + End Method + + Rem + bbdoc: Convert audio sample + returns: A new audio sample object in the specified format + end rem + Method Convert:TAudioSample( to_format ) + Local t:TAudioSample=Create( length,hertz,to_format ) + ConvertSamples samples,format,t.samples,to_format,length + Return t + End Method + + Rem + bbdoc: Create an audio sample + returns: A new audio sample object + end rem + Function Create:TAudioSample( length,hertz,format ) + Local t:TAudioSample=New TAudioSample + Local capacity=length*BytesPerSample[format] + t.samples=MemAlloc( capacity ) + t.length=length + t.hertz=hertz + t.format=format + t.capacity=capacity + Return t + End Function + + Rem + bbdoc: Create a static audio sample + returns: A new audio sample object that references an existing block of memory + end rem + Function CreateStatic:TAudioSample( samples:Byte Ptr,length,hertz,format ) + Local t:TAudioSample=New TAudioSample + t.samples=samples + t.length=length + t.hertz=hertz + t.format=format + t.capacity=-1 + Return t + End Function + +End Type + +Private +Global sample_loaders:TAudioSampleLoader +Public + +'deprecated +Function AddAudioSampleLoader( loader:TAudioSampleLoader ) +' If( loader._succ ) Return +' loader._succ=sample_loaders +' sample_loaders=loader +End Function + +Rem +bbdoc: Audio sample loader type +about: To create your own audio sample loaders, you should extend this type and +provide a @LoadAudioSample method. To add your audio sample loader to the system, +simply create an instance of it using @New. +end rem +Type TAudioSampleLoader + Field _succ:TAudioSampleLoader + + Method New() + _succ=sample_loaders + sample_loaders=Self + End Method + + Rem + bbdoc: Load an audio sample + returns: A new audio sample object, or Null if sample could not be loaded + about: Extending types must implement this method. + end rem + Method LoadAudioSample:TAudioSample( stream:TStream ) Abstract + +End Type + +Rem +bbdoc: Create an audio sample +returns: An audio sample object +about: +@length is the number of samples to allocate for the sample. @hertz is the frequency in samples per second (hz) +the audio sample will be played. @format should be one of: + +[ @Format | @Description + +* &SF_MONO8 | Mono unsigned 8 bit + +* &SF_MONO16LE | Mono signed 16 bit little endian + +* &SF_MONO16BE | Mono signed 16 bit big endian + +* &SF_STEREO8 | Stereo unsigned 8 bit + +* &SF_STEREO16LE | Stereo signed 16 bit little endian + +* &SF_STEREO16BE | Stereo signed 16 bit big endian +] +End Rem +Function CreateAudioSample:TAudioSample( length,hertz,format ) + Return TAudioSample.Create( length,hertz,format ) +End Function + +Rem +bbdoc: Create an audio sample with existing data +returns: An audio sample object that references an existing block of memory +about: +The memory referenced by a static audio sample is not released when the audio sample is +deleted. + +See #CreateAudioSample for possile @format values. +End Rem +Function CreateStaticAudioSample:TAudioSample( samples:Byte Ptr,length,hertz,format ) + Return TAudioSample.CreateStatic( samples,length,hertz,format ) +End Function + +Rem +bbdoc: Load an audio sample +returns: An audio sample object +end rem +Function LoadAudioSample:TAudioSample( url:Object ) + + Local stream:TStream=ReadStream( url ) + If Not stream Return + + Local pos=stream.Pos() + If pos=-1 RuntimeError "Stream is not seekable" + + Local sample:TAudioSample + Local loader:TAudioSampleLoader=sample_loaders + + While loader + stream.Seek pos + Try + sample=loader.LoadAudioSample( stream ) + Catch ex:TStreamException + End Try + If sample Exit + loader=loader._succ + Wend + stream.Close + Return sample +End Function diff --git a/mod/brl.mod/audiosample.mod/doc/createaudiosample.bmx b/mod/brl.mod/audiosample.mod/doc/createaudiosample.bmx new file mode 100644 index 0000000..354b890 --- /dev/null +++ b/mod/brl.mod/audiosample.mod/doc/createaudiosample.bmx @@ -0,0 +1,13 @@ +' createaudiosample.bmx + +Local sample:TAudioSample=CreateAudioSample( 32,11025,SF_MONO8 ) + +For Local k=0 Until 32 + sample.samples[k]=Sin(k*360/32)*127.5+127.5 +Next + +Local sound:TSound=LoadSound( sample,True ) + +PlaySound(sound) + +Input \ No newline at end of file diff --git a/mod/brl.mod/audiosample.mod/doc/intro.bbdoc b/mod/brl.mod/audiosample.mod/doc/intro.bbdoc new file mode 100644 index 0000000..ce2b8e6 --- /dev/null +++ b/mod/brl.mod/audiosample.mod/doc/intro.bbdoc @@ -0,0 +1,2 @@ +The BlitzMax audiosample module contains commands to create and load audio samples for +use with the BlitzMax #BRL.Audio module. diff --git a/mod/brl.mod/audiosample.mod/sample.bmx b/mod/brl.mod/audiosample.mod/sample.bmx new file mode 100644 index 0000000..3bae972 --- /dev/null +++ b/mod/brl.mod/audiosample.mod/sample.bmx @@ -0,0 +1,161 @@ + +Strict + +Const SF_MONO8=1 +Const SF_MONO16LE=2 +Const SF_MONO16BE=3 + +Const SF_STEREO8=4 +Const SF_STEREO16LE=5 +Const SF_STEREO16BE=6 + +Const SF_STDFORMAT=SF_STEREO16BE + +Global BytesPerSample[]=[0,1,2,2,2,4,4] +Global ChannelsPerSample[]=[0,1,1,1,2,2,2] + +Function CopySamples( in_buf:Byte Ptr,out_buf:Byte Ptr,format,count ) + MemCopy out_buf,in_buf,count*BytesPerSample[format] +End Function + +Function ConvertSamples( in_buf:Byte Ptr,in_format,out_buf:Byte Ptr,out_format,count ) + If in_format=out_format + CopySamples in_buf,out_buf,out_format,count + Else If in_format=SF_STDFORMAT + ConvertSamplesFromStdFormat in_buf,out_buf,out_format,count + Else If out_format=SF_STDFORMAT + ConvertSamplesToStdFormat in_buf,out_buf,in_format,count + Else + Local tmp_buf:Byte[count*BytesPerSample[SF_STDFORMAT]] + ConvertSamplesToStdFormat in_buf,tmp_buf,in_format,count + ConvertSamplesFromStdFormat tmp_buf,out_buf,out_format,count + EndIf +End Function + +Function ConvertSamplesToStdFormat( in_buf:Byte Ptr,out_buf:Byte Ptr,format,count ) + + If format=SF_STDFORMAT + CopySamples in_buf,out_buf,format,count + Return + EndIf + + Local in:Byte Ptr=in_buf,out:Byte Ptr=out_buf + Local out_end:Byte Ptr=out+count*BytesPerSample[SF_STDFORMAT] + + Select format + Case SF_MONO8 + While out<>out_end + Local t=in[0]*257-$8000 + out[0]=t Shr 8 + out[1]=t + out[2]=t Shr 8 + out[3]=t + in:+1;out:+4 + Wend + Case SF_MONO16LE + While out<>out_end + Local t=in[1] Shl 8 | in[0] + out[0]=in[1] + out[1]=in[0] + out[2]=in[1] + out[3]=in[0] + in:+2;out:+4 + Wend + Case SF_MONO16BE + While out<>out_end + out[0]=in[0] + out[1]=in[1] + out[2]=in[0] + out[3]=in[1] + in:+2;out:+4 + Wend + Case SF_STEREO8 + While out<>out_end + Local x=in[0]*257-$8000 + Local y=in[1]*257-$8000 + out[0]=x Shr 8 + out[1]=x + out[2]=y Shr 8 + out[3]=y + in:+2;out:+4 + Wend + Case SF_STEREO16LE + While out<>out_end + out[0]=in[1] + out[1]=in[0] + out[2]=in[3] + out[3]=in[2] + in:+4;out:+4 + Wend + Default + RuntimeError "Unimplemented sample format conversion" + End Select + +End Function + +Function ConvertSamplesFromStdFormat( in_buf:Byte Ptr,out_buf:Byte Ptr,format,count ) + + If format=SF_STDFORMAT + CopySamples in_buf,out_buf,format,count + Return + EndIf + + Local out:Byte Ptr=out_buf,in:Byte Ptr=in_buf + Local in_end:Byte Ptr=in+count*BytesPerSample[SF_STDFORMAT] + + Select format + Case SF_MONO8 + While in<>in_end + Local x=in[0] Shl 8 | in[1] + Local y=in[2] Shl 8 | in[3] + If x & $8000 x:|$ffff0000 + If y & $8000 y:|$ffff0000 + Local t=(x+y)/2 + out[0]=(t+$8000)/257 + in:+4;out:+1 + Wend + Case SF_MONO16LE + While in<>in_end + Local x=in[0] Shl 8 | in[1] + Local y=in[2] Shl 8 | in[3] + If x & $8000 x:|$ffff0000 + If y & $8000 y:|$ffff0000 + Local t=(x+y)/2 + out[0]=t + out[1]=t Shr 8 + in:+4;out:+2 + Wend + Case SF_MONO16BE + While in<>in_end + Local x=in[0] Shl 8 | in[1] + Local y=in[2] Shl 8 | in[3] + If x & $8000 x:|$ffff0000 + If y & $8000 y:|$ffff0000 + Local t=(x+y)/2 + out[0]=t Shr 8 + out[1]=t + in:+4;out:+2 + Wend + Case SF_STEREO8 + While in<>in_end + Local x=in[0] Shl 8 | in[1] + Local y=in[2] Shl 8 | in[3] + If x & $8000 x:|$ffff0000 + If y & $8000 y:|$ffff0000 + out[0]=(x+$8000)/257 + out[1]=(y+$8000)/257 + in:+4;out:+2 + Wend + Case SF_STEREO16LE + While in<>in_end + out[0]=in[1] + out[1]=in[0] + out[2]=in[3] + out[3]=in[2] + in:+4;out:+4 + Wend + Default + RuntimeError "Unimplemented sample format conversion" + End Select + +End Function diff --git a/mod/brl.mod/bank.mod/bank.bmx b/mod/brl.mod/bank.mod/bank.bmx new file mode 100644 index 0000000..216c83a --- /dev/null +++ b/mod/brl.mod/bank.mod/bank.bmx @@ -0,0 +1,531 @@ + +Strict + +Rem +bbdoc: Miscellaneous/Banks +End Rem +Module BRL.Bank + +ModuleInfo "Version: 1.06" +ModuleInfo "Author: Mark Sibly" +ModuleInfo "License: zlib/libpng" +ModuleInfo "Copyright: Blitz Research Ltd" +ModuleInfo "Modserver: BRL" + +ModuleInfo "History: 1.06 Release" +ModuleInfo "History: Added Lock/Unlock to replace Buf" +ModuleInfo "History: 1.05 Release" +ModuleInfo "History: Fixed Read/Write using ReadBytes/WriteBytes" + +Import BRL.Stream + +Rem +bbdoc: Memory bank +end rem +Type TBank + + Field _buf:Byte Ptr,_size,_capacity,_locked + + Method _pad() + End Method + + Method Delete() + Assert Not _locked + If _capacity>=0 MemFree _buf + End Method + + Rem + bbdoc: Get a bank's memory pointer + returns: A byte pointer to the memory block controlled by the bank + about: + Please use #Lock and #Unlock instead of this method. + End Rem + Method Buf:Byte Ptr() + Return _buf + End Method + + Rem + bbdoc: Lock a bank's memory block + returns: A byte pointer to the memory block controlled by the bank + about: + While locked, a bank cannot be resized. + + After you have finished with a bank's memory block, you must use #Unlock + to return it to the bank. + End Rem + Method Lock:Byte Ptr() + _locked:+1 + Return _buf + End Method + + Rem + bbdoc: Unlock a bank's memory pointer + about: + After you have finished with a bank's memory block, you must use #Unlock + to return it to the bank. + End Rem + Method Unlock() + _locked:-1 + End Method + + Rem + bbdoc: Get a bank's size + returns: The size, in bytes, of the memory block controlled by the bank + End Rem + Method Size() + Return _size + End Method + + Rem + bbdoc: Get capacity of bank + returns: The capacity, in bytes, of the bank's internal memory buffer + end rem + Method Capacity() + Return _capacity + End Method + + Rem + bbdoc: Resize a bank + end rem + Method Resize( size ) + Assert _locked=0 Else "Locked banks cannot be resize" + Assert _capacity>=0 Else "Static banks cannot be resized" + If size>_capacity + Local n=_capacity*3/2 + If n=0 And offset<=_size-count Else "Illegal bank offset" + Return stream.Read( _buf+offset,count ) + End Method + + Rem + bbdoc: Write bytes in a bank to a stream + end rem + Method Write( stream:TStream,offset,count ) + Assert offset>=0 And offset<=_size-count Else "Illegal bank offset" + Return stream.Write( _buf+offset,count ) + End Method + + Rem + bbdoc: Peek a byte from a bank + returns: The byte value at the specified byte offset within the bank + end rem + Method PeekByte( offset ) + Assert offset>=0 And offset<_size Else "Illegal bank offset" + Return _buf[offset] + End Method + + Rem + bbdoc: Poke a byte into a bank + end rem + Method PokeByte( offset,value ) + Assert offset>=0 And offset<_size Else "Illegal bank offset" + _buf[offset]=value + End Method + + Rem + bbdoc: Peek a short from a bank + returns: The short value at the specified byte offset within the bank + end rem + Method PeekShort( offset ) + Assert offset>=0 And offset<_size-1 Else "Illegal bank offset" + Return (Short Ptr(_buf+offset))[0] + End Method + + Rem + bbdoc: Poke a short into a bank + end rem + Method PokeShort( offset,value ) + Assert offset>=0 And offset<_size-1 Else "Illegal bank offset" + (Short Ptr(_buf+offset))[0]=value + End Method + + Rem + bbdoc: Peek an int from a bank + returns: The int value at the specified byte offset within the bank + end rem + Method PeekInt( offset ) + Assert offset>=0 And offset<_size-3 Else "Illegal bank offset" + Return (Int Ptr(_buf+offset))[0] + End Method + + Rem + bbdoc: Poke an int into a bank + end rem + Method PokeInt( offset,value ) + Assert offset>=0 And offset<_size-3 Else "Illegal bank offset" + (Int Ptr(_buf+offset))[0]=value + End Method + + Rem + bbdoc: Peek a long from a bank + returns: The long value at the specified byte offset within the bank + end rem + Method PeekLong:Long( offset ) + Assert offset>=0 And offset<_size-7 Else "Illegal bank offset" + Return (Long Ptr(_buf+offset))[0] + End Method + + Rem + bbdoc: Poke a long value into a bank + end rem + Method PokeLong( offset,value:Long ) + Assert offset>=0 And offset<_size-7 Else "Illegal bank offset" + (Long Ptr(_buf+offset))[0]=value + End Method + + Rem + bbdoc: Peek a float from a bank + returns: The float value at the specified byte offset within the bank + end rem + Method PeekFloat#( offset ) + Assert offset>=0 And offset<_size-3 Else "Illegal bank offset" + Return (Float Ptr(_buf+offset))[0] + End Method + + Rem + bbdoc: Poke a float value into a bank + end rem + Method PokeFloat( offset,value# ) + Assert offset>=0 And offset<_size-3 Else "Illegal bank offset" + (Float Ptr(_buf+offset))[0]=value + End Method + + Rem + bbdoc: Peek a double from a bank + returns: The double value at the specified byte offset within the bank + end rem + Method PeekDouble!( offset ) + Assert offset>=0 And offset<_size-7 Else "Illegal bank offset" + Return (Double Ptr(_buf+offset))[0] + End Method + + Rem + bbdoc: Poke a double value into a bank + end rem + Method PokeDouble( offset,value! ) + Assert offset>=0 And offset<_size-7 Else "Illegal bank offset" + (Double Ptr(_buf+offset))[0]=value + End Method + + Rem + bbdoc: Save a bank to a stream + about: + Return True if successful, otherwise False. + end rem + Method Save( url:Object ) + Local stream:TStream=WriteStream( url ) + If Not stream Return + Local n=stream.WriteBytes( _buf,_size ) + stream.Close + Return True + End Method + + Rem + bbdoc: Load a bank from a stream + returns: A new TBank object + about: + Returns a new TBank object if successfull, otherwise Null. + end rem + Function Load:TBank( url:Object ) + Local stream:TStream=ReadStream( url ) + If Not stream Return + Local data:Byte[]=LoadByteArray( stream ) + Local bank:TBank=Create( data.length ) + MemCopy bank.Buf(),data,data.length + stream.Close + Return bank + End Function + + Rem + bbdoc: Create a bank + returns: A new TBank object with an initial size of @size + end rem + Function Create:TBank( size ) + Assert size>=0 Else "Illegal bank size" + Local bank:TBank=New TBank + bank._buf=MemAlloc( size ) + bank._size=size + bank._capacity=size + Return bank + End Function + + Rem + bbdoc: Create a bank from an existing block of memory + end rem + Function CreateStatic:TBank( buf:Byte Ptr,size ) + Assert size>=0 Else "Illegal bank size" + Local bank:TBank=New TBank + bank._buf=buf + bank._size=size + bank._capacity=-1 + Return bank + End Function + +End Type + +Rem +bbdoc: Create a bank +returns: A bank object with an initial size of @size bytes +about: +#CreateBank creates a Bank allocating a specified amount of memory that +can be used for storage of binary data using the various Poke and +Peek commands. +End Rem +Function CreateBank:TBank( size=0 ) + Return TBank.Create( size ) +End Function + +Rem +bbdoc: Create a bank with existing data +returns: A bank object that references an existing block of memory +about: +The memory referenced by a static bank is not released when the bank is deleted. +A static bank cannot be resized. +End Rem +Function CreateStaticBank:TBank( buf:Byte Ptr,size ) + Return TBank.CreateStatic( buf,size ) +End Function + +Rem +bbdoc: Load a bank +returns: A bank containing the binary contents of @url, or null if @url could not be opened +about: +#LoadBank reads the entire contents of a binary file from a specified @url into a newly +created bank with a size matching that of the file. +end rem +Function LoadBank:TBank( url:Object ) + Return TBank.Load( url ) +End Function + +Rem +bbdoc: Save a bank +returns: True if successful. +about: +#SaveBank writes it's entire contents to a @url. If the @url is a file path a new +file is created. +end rem +Function SaveBank( bank:TBank,url:Object ) + Return bank.Save( url ) +End Function + +Rem +bbdoc: Get bank's memory buffer +returns: A byte pointer to the bank's internal memory buffer +about: +Please use #LockBank and #UnlockBank instead of this method. +End Rem +Function BankBuf:Byte Ptr( bank:TBank ) + Return bank.Buf() +End Function + +Rem +bbdoc: Lock a bank's memory block +returns: A byte pointer to the memory block controlled by the bank. +about: +While locked, a bank cannot be resized. + +After you have finished with a bank's memory block, you must use #UnlockBank +to return it to the bank. +End Rem +Function LockBank:Byte Ptr( bank:TBank ) + Return bank.Lock() +End Function + +Rem +bbdoc: Unlock a bank's memory block +about: +After you have finished with a bank's memory block, you must use #UnlockBank +to return it to the bank. +End Rem +Function UnlockBank( bank:TBank ) + bank.Unlock +End Function + +Rem +bbdoc: Get size of bank +returns: The size, in bytes, of the bank's internal memory buffer +end rem +Function BankSize( bank:TBank ) + Return bank.Size() +End Function + +Rem +bbdoc: Get capacity of bank +returns: The capacity, in bytes, of the bank's internal memory buffer +about: +The capacity of a bank is the size limit before a bank must allocate +more memory due to a resize. Bank capacity may be increased due to a call +to #ResizeBank by either 50% or the requested amount, whichever is greater. +Capacity never decreases. +end rem +Function BankCapacity( bank:TBank ) + Return bank.Capacity() +End Function + +Rem +bbdoc: Resize a bank +about: +#ResizeBank modifies the size limit of a bank. This may cause memory to be +allocated if the requested size is greater than the bank's current capacity, +see #BankCapacity for more information. +end rem +Function ResizeBank( bank:TBank,size ) + bank.Resize size +End Function + +Rem +bbdoc: Copy bank contents +about: +#CopyBank copies @count bytes from @src_offset in @src_bank to @dst_offset +in @dst_bank. +end rem +Function CopyBank( src_bank:TBank,src_offset,dst_bank:TBank,dst_offset,count ) + Assert.. + count>=0 And.. + src_offset>=0 And.. + dst_offset>=0 And.. + src_offset+count<=src_bank.Size() And.. + dst_offset+count<=dst_bank.size() Else "Illegal range for CopyBank" + MemCopy( dst_bank.Buf()+dst_offset,src_bank.Buf()+src_offset,count ) +End Function + +Rem +bbdoc: Peek a byte from a bank +returns: The byte value at the specified byte offset within the bank +about: +A byte is an unsigned 8 bit value with a range of 0..255. +end rem +Function PeekByte( bank:TBank,offset ) + Return bank.PeekByte( offset ) +End Function + +Rem +bbdoc: Poke a byte into a bank +end rem +Function PokeByte( bank:TBank,offset,value ) + bank.PokeByte offset,value +End Function + +Rem +bbdoc: Peek a short from a bank +returns: The short value at the specified byte offset within the bank +about: +A short is an unsigned 16 bit (2 bytes) value with a range of 0..65535. +end rem +Function PeekShort( bank:TBank,offset ) + Return bank.PeekShort( offset ) +End Function + +Rem +bbdoc: Poke a short into a bank +about: +An short is an unsigned 16 bit value that requires 2 bytes of storage. +end rem +Function PokeShort( bank:TBank,offset,value ) + bank.PokeShort offset,value +End Function + +Rem +bbdoc: Peek an int from a bank +returns: The int value at the specified byte offset within the bank +about: +An int is a signed 32 bit value (4 bytes). +end rem +Function PeekInt( bank:TBank,offset ) + Return bank.PeekInt( offset ) +End Function + +Rem +bbdoc: Poke an int into a bank +about: +An int is a signed 32 bit value that requires 4 bytes of storage. +end rem +Function PokeInt( bank:TBank,offset,value ) + bank.PokeInt offset,value +End Function + +Rem +bbdoc: Peek a long integer from a bank +returns: The long integer value at the specified byte offset within the bank +about: +A long is a 64 bit integer that requires 8 bytes of memory. +end rem +Function PeekLong:Long( bank:TBank,offset ) + Return bank.PeekLong( offset ) +End Function + +Rem +bbdoc: Poke a long integer int into a bank +about: +A long is a 64 bit integer that requires 8 bytes of storage. +end rem +Function PokeLong( bank:TBank,offset,value:Long ) + bank.PokeLong offset,value +End Function + +Rem +bbdoc: Peek a float from a bank +returns: The float value at the specified byte offset within the bank +about: +A float requires 4 bytes of storage +end rem +Function PeekFloat#( bank:TBank,offset ) + Return bank.PeekFloat( offset ) +End Function + +Rem +bbdoc: Poke a float into a bank +about: +A float requires 4 bytes of storage +end rem +Function PokeFloat( bank:TBank,offset,value# ) + bank.PokeFloat offset,value +End Function + +Rem +bbdoc: Peek a double from a bank +returns: The double value at the specified byte offset within the bank +about: +A double requires 8 bytes of storage +end rem +Function PeekDouble!( bank:TBank,offset ) + Return bank.PeekDouble( offset ) +End Function + +Rem +bbdoc: Poke a double into a bank +about: +A double requires 8 bytes of storage +end rem +Function PokeDouble( bank:TBank,offset,value! ) + bank.PokeDouble offset,value +End Function + +Rem +bbdoc: Read bytes from a Stream to a Bank +returns: The number of bytes successfully read from the Stream +end rem +Function ReadBank( bank:TBank,stream:TStream,offset,count ) + Return bank.Read( stream,offset,count ) +End Function + +Rem +bbdoc: Write bytes from a Bank to a Stream +returns: The number of bytes successfully written to the Stream +end rem +Function WriteBank( bank:TBank,stream:TStream,offset,count ) + Return bank.Write( stream,offset,count ) +End Function diff --git a/mod/brl.mod/bank.mod/doc/intro.bbdoc b/mod/brl.mod/bank.mod/doc/intro.bbdoc new file mode 100644 index 0000000..e0d7fa7 --- /dev/null +++ b/mod/brl.mod/bank.mod/doc/intro.bbdoc @@ -0,0 +1,12 @@ +A bank object encapsulates a block of memory you can use to store arbitrary data. + +Banks are useful for storing data that is of no fixed type - for example, the contents +of a binary file. + +To create a bank, use the #CreateBank command. + +To write data to a bank, use one of 'Poke' style commands, such as #PokeByte. + +To read data from a bank, use one of the 'Peek' style commands, such as #PeekByte. + +In addition, banks can be loaded or saved using #LoadBank or #SaveBank. diff --git a/mod/brl.mod/bankstream.mod/bankstream.bmx b/mod/brl.mod/bankstream.mod/bankstream.bmx new file mode 100644 index 0000000..73fd1a4 --- /dev/null +++ b/mod/brl.mod/bankstream.mod/bankstream.bmx @@ -0,0 +1,95 @@ + +Strict + +Rem +bbdoc: Streams/Bank streams +End Rem +Module BRL.BankStream + +ModuleInfo "Version: 1.01" +ModuleInfo "Author: Mark Sibly" +ModuleInfo "License: zlib/libpng" +ModuleInfo "Copyright: Blitz Research Ltd" +ModuleInfo "Modserver: BRL" + +ModuleInfo "History: Added TBankStreamFactory" + +Import BRL.Bank +Import BRL.Stream + +Rem +bbdoc: BankStream Object +End Rem +Type TBankStream Extends TStream + + Field _pos,_bank:TBank + + Method Pos() + Return _pos + End Method + + Method Size() + Return _bank.Size() + End Method + + Method Seek( pos ) + If pos<0 pos=0 Else If pos>_bank.Size() pos=_bank.Size() + _pos=pos + Return _pos + End Method + + Method Read( buf:Byte Ptr,count ) + If count<=0 Or _pos>=_bank.Size() Return 0 + If _pos+count>_bank.Size() count=_bank.Size()-_pos + MemCopy buf,_bank.Buf()+_pos,count + _pos:+count + Return count + End Method + + Method Write( buf:Byte Ptr,count ) + If count<=0 Or _pos>_bank.Size() Return 0 + If _pos+count>_bank.Size() _bank.Resize _pos+count + MemCopy _bank.Buf()+_pos,buf,count + _pos:+count + Return count + End Method + + Rem + bbdoc: Create a bank stream + returns: A bank stream object + about: + A bank stream allows you to read data into or out of a bank. A bank stream extends a stream so + can be used in place of a stream. + end rem + Function Create:TBankStream( bank:TBank ) + Local stream:TBankStream=New TBankStream + stream._bank=bank + Return stream + End Function + +End Type + +Rem +bbdoc: Create a bank stream +returns: A bank stream object +about: +A bank stream allows you to read data into or out of a bank. A bank stream extends a stream so +can be used in place of a stream. +end rem +Function CreateBankStream:TBankStream( bank:TBank ) + If Not bank bank=TBank.Create(0) + Return TBankStream.Create( bank ) +End Function + +Type TBankStreamFactory Extends TStreamFactory + + Method CreateStream:TBankStream( url:Object,proto$,path$,readable,writeable ) + Local bank:TBank=TBank(url) + If bank Return CreateBankStream( bank ) + End Method + +End Type + +New TBankStreamFactory + + diff --git a/mod/brl.mod/bankstream.mod/doc/intro.bbdoc b/mod/brl.mod/bankstream.mod/doc/intro.bbdoc new file mode 100644 index 0000000..33a7b78 --- /dev/null +++ b/mod/brl.mod/bankstream.mod/doc/intro.bbdoc @@ -0,0 +1,6 @@ +A bank stream allows you to read data into or out of a bank. A bank stream can be used with +any of the stream commands, or anywhere a #TStream object is expected. + +To create a bank stream, use the #CreateBankStream command. + +As with all streams, you should use #CloseStream when you are finished with the bank stream. diff --git a/mod/brl.mod/basic.mod/basic.bmx b/mod/brl.mod/basic.mod/basic.bmx new file mode 100644 index 0000000..f392980 --- /dev/null +++ b/mod/brl.mod/basic.mod/basic.bmx @@ -0,0 +1,27 @@ + +Strict + +Module BRL.Basic + +ModuleInfo "Version: 1.02" +ModuleInfo "Author: Mark Sibly" +ModuleInfo "License: zlib/libpng" +ModuleInfo "Copyright: Blitz Research Ltd" +ModuleInfo "Modserver: BRL" + +ModuleInfo "History: 1.02 Release" +ModuleInfo "History: Added BRL.Socket" + +Import BRL.Math +Import BRL.Bank +Import BRL.Random +Import BRL.Socket +Import BRL.Stream +Import BRL.RamStream +Import BRL.BankStream +Import BRL.EndianStream +Import BRL.SocketStream +Import BRL.HTTPStream +Import BRL.StandardIO +Import BRL.LinkedList +Import BRL.FileSystem diff --git a/mod/brl.mod/blitz.mod/blitz.bmx b/mod/brl.mod/blitz.mod/blitz.bmx new file mode 100644 index 0000000..a352c9e --- /dev/null +++ b/mod/brl.mod/blitz.mod/blitz.bmx @@ -0,0 +1,874 @@ + +Strict + +NoDebug + +Rem +bbdoc: BASIC/BlitzMax runtime +End Rem +Module BRL.Blitz + +ModuleInfo "Version: 1.17" +ModuleInfo "Author: Mark Sibly" +ModuleInfo "License: zlib/libpng" +ModuleInfo "Copyright: Blitz Research Ltd" +ModuleInfo "Modserver: BRL" + +ModuleInfo "History: 1.17 Release" +ModuleInfo "History: Added kludges for Lion llvm" +ModuleInfo "History: Removed Nan/Inf" +ModuleInfo "History: 1.16 Release" +ModuleInfo "History: String.Find now converts start index <0 to 0" +ModuleInfo "History: 1.15 Release" +ModuleInfo "History: Changed ReadStdin so it can handle any length input" +ModuleInfo "History: 1.14 Release" +ModuleInfo "History: Fixed leak in WriteStdout and WriteStderr" +ModuleInfo "History: 1.13 Release" +ModuleInfo "History: Added LibStartUp stub" +ModuleInfo "History: 1.12 Release" +ModuleInfo "History: Added GCSuspend and GCResume" +ModuleInfo "History: 1.11 Release" +ModuleInfo "History: Added experimental dll support" +ModuleInfo "History: 1.10 Release" +ModuleInfo "History: Added Nan and Inf keyword docs" +ModuleInfo "History: 1.09 Release" +ModuleInfo "History: BCC extern CString fix" +ModuleInfo "History: 1.08 Release" +ModuleInfo "History: Removed printf from 'Throw'" +ModuleInfo "History: 1.07 Release" +ModuleInfo "History: Added AppTitle$ global var" +ModuleInfo "History: 1.06 Release" +ModuleInfo "History: Restored ReadData" +ModuleInfo "History: 1.05 Release" +ModuleInfo "History: Lotsa little tidyups" +ModuleInfo "History: 1.04 Release" +ModuleInfo "History: Fixed C Compiler warnings" + +Import "blitz_app.c" +Import "blitz_types.c" +Import "blitz_cclib.c" +Import "blitz_memory.c" +Import "blitz_module.c" +Import "blitz_object.c" +Import "blitz_string.c" +Import "blitz_array.c" +Import "blitz_handle.c" +Import "blitz_debug.c" +Import "blitz_incbin.c" +Import "blitz_thread.c" +Import "blitz_ex.c" +Import "blitz_gc.c" + +?Threaded +Import "blitz_gc_ms.c" +?Not Threaded +Import "blitz_gc_rc.c" +? + +?Win32X86 +Import "blitz_ex.win32.x86.s" +Import "blitz_gc.win32.x86.s" +Import "blitz_ftoi.win32.x86.s" +?LinuxX86 +Import "blitz_ex.linux.x86.s" +Import "blitz_gc.linux.x86.s" +Import "blitz_ftoi.linux.x86.s" +?MacosX86 +Import "blitz_ex.macos.x86.s" +Import "blitz_gc.macos.x86.s" +Import "blitz_ftoi.macos.x86.s" +?MacosPPC +Import "blitz_ex.macos.ppc.s" +Import "blitz_gc.macos.ppc.s" +? + +Extern +Global OnDebugStop()="bbOnDebugStop" +Global OnDebugLog( message$ )="bbOnDebugLog" +End Extern + +Type TBlitzException +End Type + +Type TNullObjectException Extends TBlitzException + Method ToString$() + Return "Attempt to access field or method of Null object" + End Method +End Type + +Type TNullMethodException Extends TBlitzException + Method ToString$() + Return "Attempt to call abstract method" + End Method +End Type + +Type TNullFunctionException Extends TBlitzException + Method ToString$() + Return "Attempt to call uninitialized function pointer" + End Method +End Type + +Type TArrayBoundsException Extends TBlitzException + Method ToString$() + Return "Attempt to index array element beyond array length" + End Method +End Type + +Type TOutOfDataException Extends TBlitzException + Method ToString$() + Return "Attempt to read beyond end of data" + End Method +End Type + +Type TRuntimeException Extends TBlitzException + Field error$ + Method ToString$() + Return error + End Method + Function Create:TRuntimeException( error$ ) + Local t:TRuntimeException=New TRuntimeException + t.error=error + Return t + End Function +End Type + +Function NullObjectError() + Throw New TNullObjectException +End Function + +Function NullMethodError() + Throw New TNullMethodException +End Function + +Function NullFunctionError() + Throw New TNullFunctionException +End Function + +Function ArrayBoundsError() + Throw New TArrayBoundsException +End Function + +Function OutOfDataError() + Throw New TOutOfDataException +End Function + +Rem +bbdoc: Generate a runtime error +about: Throws a TRuntimeException. +End Rem +Function RuntimeError( message$ ) + Throw TRuntimeException.Create( message ) +End Function + +Rem +bbdoc: Stop program execution and enter debugger +about: If there is no debugger present, this command is ignored. +end rem +Function DebugStop() + OnDebugStop +End Function + +Rem +bbdoc: Write a string to debug log +about: If there is no debugger present, this command is ignored. +end rem +Function DebugLog( message$ ) + OnDebugLog message +End Function + +Extern + +Rem +bbdoc: Application directory +about: The #AppDir global variable contains the fully qualified directory of the currently +executing application. An application's initial current directory is also set to #AppDir +when an application starts. +End Rem +Global AppDir$="bbAppDir" + +Rem +bbdoc: Application file name +about: The #AppFile global variable contains the fully qualified file name of the currently +executing application. +End Rem +Global AppFile$="bbAppFile" + +Rem +bbdoc: Application title +about: The #AppTitle global variable is used by various commands when a +default application title is required - for example, when opening simple +windows or requesters.
+
+Initially, #AppTitle is set the value "BlitzMax Application". However, you may change +#AppTitle at any time with a simple assignment. +End Rem +Global AppTitle$="bbAppTitle" + +Rem +bbdoc: Arguments passed to the application at startup +about: The #AppArgs global array contains the command line parameters sent to an application +when it was started. The first element of #AppArgs always contains the name of the +application. However, the format of the name may change depending on how the application +was launched. Use #AppDir or #AppFile for consistent information about the applications name +or directory. +End Rem +Global AppArgs$[]="bbAppArgs" + +Rem +bbdoc: Directory from which application was launched +about: The #LaunchDir global variable contains the current directory at the time the +application was launched. This is mostly of use to command line tools which may need to +access the 'shell' current directory as opposed to the application directory. +End Rem +Global LaunchDir$="bbLaunchDir" + +Rem +bbdoc: Add a function to be called when the program ends +about: #OnEnd allows you to specify a function to be called when the program ends. OnEnd functions are called +in the reverse order to that in which they were added. +end rem +Function OnEnd( fun() )="bbOnEnd" + +Rem +bbdoc: Read a string from stdin +returns: A string read from stdin. The newline terminator, if any, is included in the returned string. +end rem +Function ReadStdin$()="bbReadStdin" + +Rem +bbdoc: Write a string to stdout +about: Writes @str to stdout and flushes stdout. +end rem +Function WriteStdout( str$ )="bbWriteStdout" + +Rem +bbdoc: Write a string to stderr +about: Writes @str to stderr and flushes stderr. +end rem +Function WriteStderr( str$ )="bbWriteStderr" + +Rem +bbdoc: Wait for a given number of milliseconds +about: +#Delay suspends program execution for at least @millis milliseconds.
+
+A millisecond is one thousandth of a second. +End Rem +Function Delay( millis )="bbDelay" + +Rem +bbdoc: Get millisecond counter +returns: Milliseconds since computer turned on. +about: +#MilliSecs returns the number of milliseconds elapsed since the computer +was turned on.
+
+A millisecond is one thousandth of a second. +End Rem +Function MilliSecs()="bbMilliSecs" + +Rem +bbdoc: Allocate memory +returns: A new block of memory @size bytes long +End Rem +Function MemAlloc:Byte Ptr( size )="bbMemAlloc" + +Rem +bbdoc: Free allocated memory +about: The memory specified by @mem must have been previously allocated by #MemAlloc or #MemExtend. +End Rem +Function MemFree( mem:Byte Ptr )="bbMemFree" + +Rem +bbdoc: Extend a block of memory +returns: A new block of memory @new_size bytes long +about: An existing block of memory specified by @mem and @size is copied into a new block +of memory @new_size bytes long. The existing block is released and the new block is returned. +end rem +Function MemExtend:Byte Ptr( mem:Byte Ptr,size,new_size )="bbMemExtend" + +Rem +bbdoc: Clear a block of memory to 0 +end rem +Function MemClear( mem:Byte Ptr,size )="bbMemClear" + +Rem +bbdoc: Copy a non-overlapping block of memory +end rem +Function MemCopy( dst:Byte Ptr,src:Byte Ptr,size )="bbMemCopy" + +Rem +bbdoc: Copy a potentially overlapping block of memory +end rem +Function MemMove( dst:Byte Ptr,src:Byte Ptr,size )="bbMemMove" + +Rem +bbdoc: Set garbage collector mode +about: +@mode can be one of the following:
+1 : automatic GC - memory will be automatically garbage collected
+2 : manual GC - no memory will be collected until a call to GCCollect is made
+
+The default GC mode is automatic GC. +End Rem +Function GCSetMode( mode )="bbGCSetMode" + +Rem +bbdoc: Suspend garbage collector +about: +#GCSuspend temporarily suspends the garbage collector. No garbage +collection will be performed following a call to #GCSuspend.
+
+Use #GCResume to resume the garbage collector. Note that #GCSuspend +and #GCResume 'nest', meaning that each call to #GCSuspend must be +matched by a call to #GCResume. +End Rem +Function GCSuspend()="bbGCSuspend" + +Rem +bbdoc: Resume garbage collector +about: +#GCResume resumes garbage collection following a call to #GCSuspend.
+
+See #GCSuspend for more details. +End Rem +Function GCResume()="bbGCResume" + +Rem +bbdoc: Run garbage collector +returns: The amount of memory, in bytes, collected. +about: +This function will have no effect if the garbage collector has been +suspended due to #GCSuspend. +End Rem +Function GCCollect()="bbGCCollect" + +Rem +bbdoc: Memory allocated by application +returns: The amount of memory, in bytes, currently allocated by the application +about: +This function only returns 'managed memory'. This includes all objects, strings and +arrays in use by the application. +End Rem +Function GCMemAlloced()="bbGCMemAlloced" + +Rem +bbdoc: Private: do not use +End Rem +Function GCEnter()="bbGCEnter" + +Rem +bbdoc: Private: do not use +End Rem +Function GCLeave()="bbGCLeave" + +Rem +bbdoc: Convert object to integer handle +returns: An integer object handle +about: +After converting an object to an integer handle, you must later +release it using the #Release command. +End Rem +Function HandleFromObject( obj:Object )="bbHandleFromObject" + +Rem +bbdoc: Convert integer handle to object +returns: The object associated with the integer handle +End Rem +Function HandleToObject:Object( handle )="bbHandleToObject" + +End Extern + +'BlitzMax keyword definitions + +Rem +bbdoc: Set strict mode +about: +See the BlitzMax Language Reference for more information on Strict mode programming. +keyword: "Strict" +End Rem + +Rem +bbdoc: Set SuperStrict mode +keyword: "SuperStrict" +End Rem + +Rem +bbdoc: End program execution +keyword: "End" +End Rem + +Rem +bbdoc: Begin a remark block +keyword: "Rem" +End Rem + +Rem +bbdoc: End a remark block +keyword: "EndRem" +End Rem + +Rem +bbdoc: Constant integer of value 1 +keyword: "True" +End Rem + +Rem +bbdoc: Constant integer of value 0 +keyword: "False" +End Rem + +Rem +bbdoc: Constant Pi value: 3.1415926535897932384626433832795 +keyword: "Pi" +End Rem + +Rem +bbdoc: Get Default Null value +keyword: "Null" +End Rem + +Rem +bbdoc: Unsigned 8 bit integer Type +keyword: "Byte" +End Rem + +Rem +bbdoc: Unsigned 16 bit integer Type +keyword: "Short" +End Rem + +Rem +bbdoc: Signed 32 bit integer Type +keyword: "Int" +End Rem + +Rem +bbdoc: Signed 64 bit integer Type +keyword: "Long" +End Rem + +Rem +bbdoc: 32 bit Floating point Type +keyword: "Float" +End Rem + +Rem +bbdoc: 64 bit floating point Type +keyword: "Double" +End Rem + +Rem +bbdoc: String Type +keyword: "String" +End Rem + +Rem +bbdoc: Object Type +keyword: "Object" +End Rem + +Rem +bbdoc: Composite Type specifier for 'by reference' types +keyword: "Var" +End Rem + +Rem +bbdoc: Composite Type specifier for pointer types +keyword: "Ptr" +End Rem + +Rem +bbdoc: Begin a conditional block. +keyword: "If" +End Rem + +Rem +bbdoc: Optional separator between the condition and associated code in an If statement. +keyword: "Then" +End Rem + +Rem +bbdoc: Else provides the ability For an If Then construct to execute a second block of code when the If condition is False. +keyword: "Else" +End Rem + +Rem +bbdoc: ElseIf provides the ability to test and execute a section of code if the initial condition failed. +keyword: "ElseIf" +End Rem + +Rem +bbdoc: Marks the End of an If Then block. +keyword: "EndIf" +End Rem + +Rem +bbdoc: Marks the start of a loop that uses an iterator to execute a section of code repeatedly. +keyword: "For" +End Rem + +Rem +bbdoc: Followed by a constant which is used to calculate when to exit a For..Next loop. +keyword: "To" +End Rem + +Rem +bbdoc: Specifies an optional constant that is used to increment the For iterator. +keyword: "Step" +End Rem + +Rem +bbdoc: End a For block +keyword: "Next" +End Rem + +Rem +bbdoc: Iterate through an array or collection +keyword: "EachIn" +End Rem + +Rem +bbdoc: Execute a block of code While a condition is True +keyword: "While" +End Rem + +Rem +bbdoc: End a While block +keyword: "Wend" +End Rem + +Rem +bbdoc: End a While block +keyword: "EndWhile" +End Rem + +Rem +bbdoc: Execute a block of code Until a termination condition is met, or Forever +keyword: "Repeat" +End Rem + +Rem +bbdoc: Conditionally continue a Repeat block +keyword: "Until" +End Rem + +Rem +bbdoc: Continue a Repeat block Forever +keyword: "Forever" +End Rem + +Rem +bbdoc: Begin a Select block +keyword: "Select" +End Rem + +Rem +bbdoc: End a Select block +keyword: "EndSelect" +End Rem + +Rem +bbdoc: Conditional code inside a Select block +keyword: "Case" +End Rem + +Rem +bbdoc: Default code inside a Select block +keyword: "Default" +End Rem + +Rem +bbdoc: Exit enclosing loop +keyword: "Exit" +End Rem + +Rem +bbdoc: Continue execution of enclosing loop +keyword: "Continue" +End Rem + +Rem +bbdoc: Declare a constant +keyword: "Const" +End Rem + +Rem +bbdoc: Declare a Local variable +keyword: "Local" +End Rem + +Rem +bbdoc: Declare a Global variable +keyword: "Global" +End Rem + +Rem +bbdoc: Declare a Field variable +keyword: "Field" +End Rem + +Rem +bbdoc: Begin a Function declaration +keyword: "Function" +End Rem + +Rem +bbdoc: End a Function declaration +keyword: "EndFunction" +End Rem + +Rem +bbdoc: Return from a Function +keyword: "Return" +End Rem + +Rem +bbdoc: Begin a user defined Type declaration +keyword: "Type" +End Rem + +Rem +bbdoc: End a user defined Type declaration +keyword: "EndType" +End Rem + +Rem +bbdoc: Specify user defined Type supertype +keyword: "Extends" +End Rem + +Rem +bbdoc: Begin a Method declaration +keyword: "Method" +End Rem + +Rem +bbdoc: End a Method declaration +keyword: "EndMethod" +End Rem + +Rem +bbdoc: Denote a Type or Method as Abstract +keyword: "Abstract" +End Rem + +Rem +bbdoc: Denote a Type or Method as Final +keyword: "Final" +End Rem + +Rem +bbdoc: Create an instance of a user defined Type +keyword: "New" +End Rem + +Rem +bbdoc: Reference to this Method's Object instance +keyword: "Self" +End Rem + +Rem +bbdoc: Reference to the Super Type Object instance +keyword: "Super" +End Rem + +Rem +bbdoc: Reserved for future expansion +keyword: "Delete" +End Rem + +Rem +bbdoc: Release an integer Object handle +keyword: "Release" +End Rem + +Rem +bbdoc: Public makes a Constant, Global variable or Function accessible from outside the current source file (Default) +keyword: "Public" +End Rem + +Rem +bbdoc: Private makes a Constant, Global variable or Function only accessible from within the current source file +keyword: "Private" +End Rem + +Rem +bbdoc: Extern marks the beginning of an external list of Function declarations +keyword: "Extern" +End Rem + +Rem +bbdoc: EndExtern marks the End of an Extern section +keyword: "EndExtern" +End Rem + +Rem +bbdoc: Declare Module scope and identifier +about: +See the BlitzMax Language Reference for more information on BlitzMax Modules. +keyword: "Module" +End Rem + +Rem +bbdoc: Define Module properties +keyword: "ModuleInfo" +End Rem + +Rem +bbdoc: Embed a data file +keyword: "Incbin" +End Rem + +Rem +bbdoc: Get start address of embedded data file +keyword: "IncbinPtr" +End Rem + +Rem +bbdoc: Get length of embedded data file +keyword: "IncbinLen" +End Rem + +Rem +bbdoc: Include effectively 'inserts' the specified file into the file being compiled. +keyword: "Include" +End Rem + +Rem +bbdoc: Framework builds the BlitzMax application with only the Module specified rather than all modules installed. +keyword: "Framework" +End Rem + +Rem +bbdoc: Import declarations from a Module or source file +keyword: "Import" +End Rem + +Rem +bbdoc: Throw a RuntimeError if a condition is False +keyword: "Assert" +End Rem + +Rem +bbdoc: Transfer program flow to specified label +keyword: "Goto" +End Rem + +Rem +bbdoc: Begin declaration of a Try block +keyword: "Try" +End Rem + +Rem +bbdoc: End declaration of a Try block +keyword: "EndTry" +End Rem + +Rem +bbdoc: Catch an exception Object in a Try block +keyword: "Catch" +End Rem + +Rem +bbdoc: Throw an exception Object to the enclosing Try block +keyword: "Throw" +End Rem + +Rem +bbdoc: Define class BASIC style data +keyword: "DefData" +End Rem + +Rem +bbdoc: Read classic BASIC style data +keyword: "ReadData" +End Rem + +Rem +bbdoc: Restore classic BASIC style data +keyword: "RestoreData" +End Rem + +Rem +bbdoc: Conditional 'And' binary operator +keyword: "And" +End Rem + +Rem +bbdoc: Conditional 'Or' binary operator +keyword: "Or" +End Rem + +Rem +bbdoc: Conditional 'Not' binary operator +keyword: "Not" +End Rem + +Rem +bbdoc: Bitwise 'Shift left' binary operator +keyword: "Shl" +End Rem + +Rem +bbdoc: Bitwise 'Shift right' binary operator +keyword: "Shr" +End Rem + +Rem +bbdoc: Bitwise 'Shift arithmetic right' binary operator +keyword: "Sar" +End Rem + +Rem +bbdoc: Number of characters in a String or elements in an array +keyword: "Len" +End Rem + +Rem +bbdoc: Numeric 'absolute value' unary operator +keyword: "Abs" +End Rem + +Rem +bbdoc: Numeric 'modulus' or 'remainder' binary operator +keyword: "Mod" +End Rem + +Rem +bbdoc: Numeric 'sign' unary operator +keyword: "Sgn" +End Rem + +Rem +bbdoc: Numeric 'minimum' builtin function +returns: The lesser of the two numeric arguments +keyword: "Min" +End Rem + +Rem +bbdoc: Numeric 'maximum' builtin function +returns: The larger of the two numeric arguments +keyword: "Max" +End Rem + +Rem +bbdoc: Find the address of a variable +keyword: "Varptr" +End Rem + +Rem +bbdoc: Size, in bytes, occupied by a variable, string, array or object +keyword: "SizeOf" +End Rem + +Rem +bbdoc: Get character value of the first character of a string +keyword: "Asc" +End Rem + +Rem +bbdoc: Create a string of length 1 with a character code +keyword: "Chr" +End Rem + diff --git a/mod/brl.mod/blitz.mod/blitz.c b/mod/brl.mod/blitz.mod/blitz.c new file mode 100644 index 0000000..ff0e6a7 --- /dev/null +++ b/mod/brl.mod/blitz.mod/blitz.c @@ -0,0 +1,2 @@ + +#include "blitz.h" diff --git a/mod/brl.mod/blitz.mod/blitz.h b/mod/brl.mod/blitz.mod/blitz.h new file mode 100644 index 0000000..a3e753d --- /dev/null +++ b/mod/brl.mod/blitz.mod/blitz.h @@ -0,0 +1,56 @@ + +#ifndef BLITZ_H +#define BLITZ_H + +#include +#include +#include +#include + +//Which GC to use... + +#ifdef THREADED +# define BB_GC_MS +#else +# define BB_GC_RC +#endif + +#include "blitz_types.h" +#include "blitz_memory.h" +#include "blitz_thread.h" +#include "blitz_gc.h" +#include "blitz_ex.h" +#include "blitz_cclib.h" +#include "blitz_debug.h" +#include "blitz_module.h" +#include "blitz_incbin.h" +#include "blitz_object.h" +#include "blitz_string.h" +#include "blitz_array.h" +#include "blitz_handle.h" +#include "blitz_app.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +extern void brl_blitz_NullObjectError(); +extern void brl_blitz_NullMethodError(); +extern void brl_blitz_NullFunctionError(); +extern void brl_blitz_ArrayBoundsError(); +extern void brl_blitz_OutOfDataError(); +extern void brl_blitz_RuntimeError( BBString *error ); + +extern BBClass brl_blitz_TBlitzException; +extern BBClass brl_blitz_TNullObjectException; +extern BBClass brl_blitz_TNullMethodException; +extern BBClass brl_blitz_TNullFunctionException; +extern BBClass brl_blitz_TArrayBoundsException; +extern BBClass brl_blitz_TOutOfDataException; +extern BBClass brl_blitz_TRuntimeExeption; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/mod/brl.mod/blitz.mod/blitz_app.c b/mod/brl.mod/blitz.mod/blitz_app.c new file mode 100644 index 0000000..980a4e5 --- /dev/null +++ b/mod/brl.mod/blitz.mod/blitz_app.c @@ -0,0 +1,355 @@ + +#include "blitz.h" + +#include + +BBString* bbAppDir=BBNULLSTRING; +BBString* bbAppFile=BBNULLSTRING; +BBString* bbAppTitle=BBNULLSTRING; +BBString* bbLaunchDir=BBNULLSTRING; +BBArray* bbAppArgs=BBNULLSTRING; + +void **bbGCStackTop; + +void bbEnd(){ + exit(0); +} + +void bbOnEnd( void (*f)() ){ + atexit( f ); +} + +void bbWriteStdout( BBString *t ){ + char *p=bbStringToCString( t ); + fprintf( stdout,"%s",p ); + fflush( stdout ); + bbMemFree(p); +} + +void bbWriteStderr( BBString *t ){ + char *p=bbStringToCString( t ); + fprintf( stderr,"%s",p ); + fflush( stderr ); + bbMemFree(p); +} + +BBString *bbReadStdin(){ + +#define BUF_SIZE 256 + int sz=0; + char *str=0; + BBString *t; + for(;;){ + int t_sz; + char buf[BUF_SIZE],*p; + fgets( buf,BUF_SIZE,stdin ); + buf[BUF_SIZE-1]=0; + if( p=strchr( buf,'\n' ) ){ + t_sz=p-buf; + if( t_sz && isspace(buf[t_sz-1]) ) --t_sz; + }else{ + t_sz=strlen( buf ); + } + str=(char*)bbMemExtend( str,sz,sz+t_sz ); + bbMemCopy( str+sz,buf,t_sz ); + sz+=t_sz; + if( t_sz + +#include +#include +#include + +static pthread_t _mainThread; + +static void startup(){ + _mainThread=pthread_self(); +} + +void bbDelay( int millis ){ + if (millis<0) return; + usleep( millis*1000 ); +} + +int bbMilliSecs(){ + double t; + UnsignedWide uw; + Microseconds( &uw ); + t=(uw.hi<<(32-9))|(uw.lo>>9); //divide by 512...! + + return (int) (long long) ( t/(1000.0/512.0) ); +} + +int bbIsMainThread(){ + return pthread_self()==_mainThread; +} + +#elif _WIN32 + +#include + +#include + +int _bbusew; //internal 'use unicode' flag + +static DWORD _mainThread; + +static void startup(){ + _mainThread=GetCurrentThreadId(); +} + +void bbDelay( int millis ){ + if (millis<0) return; + Sleep( millis ); +} + +int bbMilliSecs(){ + return timeGetTime(); +} + +int bbIsMainThread(){ + return GetCurrentThreadId()==_mainThread; +} + +#elif __linux + +#include +#include +#include +#include +#include +#include + +static int base_time; +static pthread_t _mainThread; + +static void startup(){ + struct sysinfo info; + + _mainThread=pthread_self(); + + sysinfo( &info ); + base_time=bbMilliSecs()-info.uptime*1000; +} + +//***** ThreadSafe! ***** +void bbDelay( int millis ){ + int i,e; + + if( millis<0 ) return; + + e=bbMilliSecs()+millis; + + for( i=0;;++i ){ + int t=e-bbMilliSecs(); + if( t<=0 ){ + if( !i ) usleep( 0 ); //always sleep at least once. + break; + } + usleep( t*1000 ); + } +} + +//***** ThreadSafe! ***** +int bbMilliSecs(){ + int t; + struct timeval tv; + gettimeofday(&tv,0); + t=tv.tv_sec*1000; + t+=tv.tv_usec/1000; + return t-base_time; +} + +int bbIsMainThread(){ + return pthread_self()==_mainThread; +} + +#endif + +void bbStartup( int argc,char *argv[],void *dummy1,void *dummy2 ){ + + int i,k; + BBString **p; + + //Start up GC and create bbAppFile, bbAppDir and bbLaunchDir + +#if _WIN32 + + char *ebp; + OSVERSIONINFO os={ sizeof(os) }; + + asm( "movl %%ebp,%0;":"=r"(ebp) );//::"%ebp" ); + + bbGCStackTop=ebp+28; + + bbThreadStartup(); + bbGCStartup(); + + if( GetVersionEx( &os ) ){ + if( os.dwPlatformId==VER_PLATFORM_WIN32_NT ){ + _bbusew=1; + } + } + + if( _bbusew ){ + int e=0; + wchar_t buf[MAX_PATH]; + + _wgetcwd( buf,MAX_PATH ); + for( i=0;buf[i];++i ){ + if( buf[i]=='\\' ) buf[i]='/'; + } + bbLaunchDir=bbStringFromWString( buf ); + + GetModuleFileNameW( GetModuleHandleW(0),buf,MAX_PATH ); + for( i=0;buf[i];++i ){ + if( buf[i]=='\\' ) buf[i]='/'; + if( buf[i]=='/' ) e=i; + } + bbAppFile=bbStringFromWString( buf ); + + if( e ){ + if( buf[e-1]==':' ) ++e; + bbAppDir=bbStringFromShorts( buf,e ); + }else{ + bbAppDir=&bbEmptyString; + } + + _wchdir( bbTmpWString( bbAppDir ) ); + + }else{ + int e=0; + char buf[MAX_PATH]; + + _getcwd( buf,MAX_PATH ); + for( i=0;buf[i];++i ){ + if( buf[i]=='\\' ) buf[i]='/'; + } + bbLaunchDir=bbStringFromCString( buf ); + + GetModuleFileNameA( GetModuleHandleA(0),buf,MAX_PATH ); + for( i=0;buf[i];++i ){ + if( buf[i]=='\\' ) buf[i]='/'; + if( buf[i]=='/' ) e=i; + } + bbAppFile=bbStringFromCString( buf ); + + if( e ){ + if( buf[e-1]==':' ) ++e; + bbAppDir=bbStringFromBytes( buf,e ); + }else{ + bbAppDir=&bbEmptyString; + } + + _chdir( bbTmpCString( bbAppDir ) ); + } + +#elif __linux + + char *ebp; + char buf[PATH_MAX]; + char lnk[PATH_MAX]; + pid_t pid; + + asm( "movl %%ebp,%0;":"=r"(ebp) );//::"%ebp" ); + + bbGCStackTop=ebp+28; + + bbThreadStartup(); + bbGCStartup(); + + getcwd( buf,PATH_MAX ); + bbLaunchDir=bbStringFromUTF8String( buf ); + + pid=getpid(); + sprintf( lnk,"/proc/%i/exe",pid ); + i=readlink( lnk,buf,PATH_MAX ); + if( i>0 ){ + char *p; + buf[i]=0; + bbAppFile=bbStringFromUTF8String( buf ); + p=strrchr( buf,'/' ); + if( p ){ + *p=0; + bbAppDir=bbStringFromUTF8String( buf ); + }else{ + bbAppDir=&bbEmptyString; + } + }else{ + bbAppFile=&bbEmptyString; + bbAppDir=&bbEmptyString; + } + + chdir( bbTmpUTF8String( bbAppDir ) ); + +#elif __APPLE__ + + CFURLRef url; + char buf[PATH_MAX],*e; + +#if BB_ARGP + bbGCStackTop=bbArgp(0); +#else + bbGCStackTop=&argc; +#endif + + bbThreadStartup(); + bbGCStartup(); + + getcwd( buf,PATH_MAX ); + bbLaunchDir=bbStringFromUTF8String( buf ); + + url=CFBundleCopyExecutableURL( CFBundleGetMainBundle() ); + CFURLGetFileSystemRepresentation( url,true,(UInt8*)buf,PATH_MAX ); + CFRelease( url ); + + bbAppFile=bbStringFromUTF8String( buf ); + + if( e=strstr( buf,".app/Contents/MacOS/" ) ){ + *e=0; + } + if( e=strrchr( buf,'/' ) ){ + *e=0; + bbAppDir=bbStringFromUTF8String( buf ); + }else{ + bbAppDir=&bbEmptyString; + } + + chdir( bbTmpUTF8String( bbAppDir ) ); + +#endif + + BBINCREFS( bbLaunchDir ); + BBINCREFS( bbAppDir ); + BBINCREFS( bbAppFile ); + + bbAppTitle=bbStringFromCString( "BlitzMax Application" ); + BBINCREFS( bbAppTitle ); + + bbAppArgs=bbArrayNew1D( "$",argc ); + BBINCREFS( bbAppArgs ); + + p=(BBString**)BBARRAYDATA( bbAppArgs,1 ); + + for( k=0;k + +static void bbArrayFree( BBObject *o ); + +static BBDebugScope debugScope={ + BBDEBUGSCOPE_USERTYPE, + "Array", + BBDEBUGDECL_END +}; + +BBClass bbArrayClass={ + &bbObjectClass, //extends + bbArrayFree, //free + &debugScope, //DebugScope + 0, //instance_size + 0, //ctor + 0, //dtor + + bbObjectToString, + bbObjectCompare, + bbObjectSendMessage, + bbObjectReserved, + bbObjectReserved, + bbObjectReserved, + + bbArraySort, + bbArrayDimensions +}; + +BBArray bbEmptyArray={ + &bbArrayClass, //clas + BBGC_MANYREFS, //refs + "", //type + 0, //dims + 0, //size + 0 //scales[0] +}; + +//***** Note: Only used by ref counting GC. +static void bbArrayFree( BBObject *o ){ +#ifdef BB_GC_RC + int k; + BBObject **p; + BBArray *arr=(BBArray*)o; + + if( arr==&bbEmptyArray ){ + arr->refs=BBGC_MANYREFS; + return; + } + + switch( arr->type[0] ){ + case ':':case '$':case '[': + p=(BBObject**)BBARRAYDATA(arr,arr->dims); + for( k=arr->scales[0];k>0;--k ){ + BBObject *o=*p++; + BBDECREFS( o ); + } + break; + } + bbGCDeallocObject( arr,BBARRAYSIZE( arr->size,arr->dims ) ); +#endif +} + +static BBArray *allocateArray( const char *type,int dims,int *lens ){ + int k,*len; + int size=4; + int length=1; + int flags=BBGC_ATOMIC; + BBArray *arr; + + len=lens; + for( k=0;ktype=type; + arr->dims=dims; + arr->size=size; + + len=lens; + for( k=0;kscales[k]=*len++; + for( k=dims-2;k>=0;--k ) arr->scales[k]*=arr->scales[k+1]; + + return arr; +} + +static void *arrayInitializer( BBArray *arr ){ + switch( arr->type[0] ){ + case ':':return &bbNullObject; + case '$':return &bbEmptyString; + case '[':return &bbEmptyArray; + case '(':return &brl_blitz_NullFunctionError; + } + return 0; +} + +static void initializeArray( BBArray *arr ){ + void *init,**p; + + if( !arr->size ) return; + + init=arrayInitializer( arr ); + p=(void**)(BBARRAYDATA( arr,arr->dims )); + + if( init ){ + int k; + for( k=arr->scales[0];k>0;--k ) *p++=init; + }else{ + memset( p,0,arr->size ); + } +} + +static volatile void *t; +void *addressOfParam( void *p ){ + t=p; + return t; +} + +BBArray *bbArrayNew( const char *type,int dims,... ){ + +#if BB_ARGP + int *lens=(int*)bbArgp(8); +#else + int *lens=&dims+1; +#endif + + BBArray *arr=allocateArray( type,dims,lens ); + + initializeArray( arr ); + + return arr; +} + +BBArray *bbArrayNewEx( const char *type,int dims,int *lens ){ + + BBArray *arr=allocateArray( type,dims,lens ); + + initializeArray( arr ); + + return arr; +} + +BBArray *bbArrayNew1D( const char *type,int length ){ + + BBArray *arr=allocateArray( type,1,&length ); + + initializeArray( arr ); + + return arr; +} + +BBArray *bbArraySlice( const char *type,BBArray *inarr,int beg,int end ){ + + char *p; + void *init; + BBArray *arr; + int n,k,el_size; + int length=end-beg; + + if( length<=0 ) return &bbEmptyArray; + + arr=allocateArray( type,1,&length ); + + el_size=arr->size/length; + + init=arrayInitializer( arr ); + p=(char*)BBARRAYDATA( arr,1 ); + + n=-beg; + if( n>0 ){ + if( beg+n>end ) n=end-beg; + if( init ){ + void **dst=(void**)p; + for( k=0;kscales[0]-beg; + if( n>0 ){ + if( beg+n>end ) n=end-beg; +#ifdef BB_GC_RC + if( type[0]==':' || type[0]=='$' || type[0]=='[' ){ + BBObject **dst=(BBObject**)p; + BBObject **src=(BBObject**)BBARRAYDATA(inarr,inarr->dims)+beg; + for( k=0;kdims)+beg*el_size,n*el_size ); + p+=n*el_size; + } +#else + memcpy( p,(char*)BBARRAYDATA(inarr,inarr->dims)+beg*el_size,n*el_size ); + p+=n*el_size; +#endif + beg+=n; + if( beg==end ) return arr; + } + n=end-beg; + if( n>0 ){ + if( init ){ + void **dst=(void**)p; + for( k=0;kscales[0]+y->scales[0]; + + if( length<=0 ) return &bbEmptyArray; + + arr=allocateArray( type,1,&length ); + + data=(char*)BBARRAYDATA( arr,1 ); + + memcpy( data,BBARRAYDATA( x,1 ),x->size ); + memcpy( data+x->size,BBARRAYDATA( y,1 ),y->size ); + +#ifdef BB_GC_RC + if( type[0]==':' || type[0]=='$' || type[0]=='[' ){ + int i; + BBObject **p=(BBObject**)data; + for( i=0;isize ); + } + return arr; +} + +BBArray *bbArrayDimensions( BBArray *arr ){ + int *p,i,n; + BBArray *dims; + + if( !arr->scales[0] ) return &bbEmptyArray; + + n=arr->dims; + dims=bbArrayNew1D( "i",n ); + p=(int*)BBARRAYDATA( dims,1 ); + + for( i=0;iscales[i]/arr->scales[i+1]; + } + p[i]=arr->scales[i]; + + return dims; +} + +BBArray *bbArrayCastFromObject( BBObject *o,const char *type ){ + BBArray *arr=(BBArray*)o; + if( arr==&bbEmptyArray ) return arr; + if( arr->clas!=&bbArrayClass ) return (BBArray*)BBNULLOBJECT; + if( arr->type[0]==':' && type[0]==':' ) return arr; + if( strcmp( arr->type,type ) ) return (BBArray*)BBNULLOBJECT; + return arr; +} + +#define SWAP(X,Y) {t=*(X);*(X)=*(Y);*(Y)=t;} +#define QSORTARRAY( TYPE,IDENT )\ +static void IDENT( TYPE *lo,TYPE *hi ){\ + TYPE t;\ + TYPE *i;\ + TYPE *x;\ + TYPE *y;\ + if( hi<=lo ) return;\ + if( lo+1==hi ){\ + if( LESSTHAN(hi,lo) ) SWAP(lo,hi);\ + return;\ + }\ + i=(hi-lo)/2+lo;\ + if( LESSTHAN(i,lo) ) SWAP(i,lo);\ + if( LESSTHAN(hi,i) ){\ + SWAP(i,hi);\ + if( LESSTHAN(i,lo) ) SWAP(i,lo);\ + }\ + x=lo+1;\ + y=hi-1;\ + do{\ + while( LESSTHAN(x,i) ) ++x;\ + while( LESSTHAN(i,y) ) --y;\ + if( x>y ) break;\ + if( xclas->Compare(*(X),*(Y))<0) +QSORTARRAY( BBObject*,qsort_obj ); +#undef LESSTHAN +#define LESSTHAN(X,Y) (*(X)>*(Y)) +QSORTARRAY( unsigned char,qsort_b_d ) +QSORTARRAY( unsigned short,qsort_s_d ) +QSORTARRAY( int,qsort_i_d ) +QSORTARRAY( BBInt64,qsort_l_d ); +QSORTARRAY( float,qsort_f_d ); +QSORTARRAY( double,qsort_d_d ); +#undef LESSTHAN +#define LESSTHAN(X,Y) ((*X)->clas->Compare(*(X),*(Y))>0) +QSORTARRAY( BBObject*,qsort_obj_d ); + +void bbArraySort( BBArray *arr,int ascending ){ + int n; + void *p; + n=arr->scales[0]-1; + if( n<=0 ) return; + p=BBARRAYDATA(arr,arr->dims); + if( ascending ){ + switch( arr->type[0] ){ + case 'b':_qsort_b( (unsigned char*)p,(unsigned char*)p+n );break; + case 's':qsort_s( (unsigned short*)p,(unsigned short*)p+n );break; + case 'i':qsort_i( (int*)p,(int*)p+n );break; + case 'l':qsort_l( (BBInt64*)p,(BBInt64*)p+n );break; + case 'f':qsort_f( (float*)p,(float*)p+n );break; + case 'd':qsort_d( (double*)p,(double*)p+n );break; + case '$':case ':':qsort_obj( (BBObject**)p,(BBObject**)p+n );break; + } + }else{ + switch( arr->type[0] ){ + case 'b':qsort_b_d( (unsigned char*)p,(unsigned char*)p+n );break; + case 's':qsort_s_d( (unsigned short*)p,(unsigned short*)p+n );break; + case 'i':qsort_i_d( (int*)p,(int*)p+n );break; + case 'l':qsort_l_d( (BBInt64*)p,(BBInt64*)p+n );break; + case 'f':qsort_f_d( (float*)p,(float*)p+n );break; + case 'd':qsort_d_d( (double*)p,(double*)p+n );break; + case '$':case ':':qsort_obj_d( (BBObject**)p,(BBObject**)p+n );break; + } + } +} diff --git a/mod/brl.mod/blitz.mod/blitz_array.h b/mod/brl.mod/blitz.mod/blitz_array.h new file mode 100644 index 0000000..80e49bb --- /dev/null +++ b/mod/brl.mod/blitz.mod/blitz_array.h @@ -0,0 +1,51 @@ + +#ifndef BLITZ_ARRAY_H +#define BLITZ_ARRAY_H + +#include "blitz_types.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +#define BBNULLARRAY (&bbEmptyArray) + +#define BBARRAYSIZE(q,n) (20+(n)*sizeof(int)+(q)) +#define BBARRAYDATA(p,n) ((void*)((char*)(p)+20+(n)*sizeof(int))) + +struct BBArray{ + //extends BBObject + BBClass* clas; + int refs; + + const char* type; //8 + int dims; //12 + int size; //16 : total size minus this header + int scales[1]; //20 : [dims] + //sizeof=20+dims*sizeof(int) +}; + +extern BBClass bbArrayClass; +extern BBArray bbEmptyArray; + +BBArray* bbArrayNew( const char *type,int dims,... ); +BBArray* bbArrayNew1D( const char *type,int length ); +BBArray* bbArrayNewEx( const char *type,int dims,int *lens ); //alternate version of New... + +BBArray* bbArraySlice( const char *type,BBArray *arr,int beg,int end ); +BBArray* bbArrayFromData( const char *type,int length,void *data ); +BBArray* bbArrayCastFromObject( BBObject *o,const char *type_encoding ); + +void bbArraySort( BBArray *arr,int ascending ); + +BBArray* bbArrayDimensions( BBArray *arr ); + +BBArray* bbArrayConcat( const char *type,BBArray *x,BBArray *y ); + +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/mod/brl.mod/blitz.mod/blitz_bbdoc.bmx b/mod/brl.mod/blitz.mod/blitz_bbdoc.bmx new file mode 100644 index 0000000..6605561 --- /dev/null +++ b/mod/brl.mod/blitz.mod/blitz_bbdoc.bmx @@ -0,0 +1,297 @@ + +'BlitzMax keyword definitions + +Rem +keyword: Strict +bbdoc: Use strict mode +about: Strict mode advises the compiler to report as errors all auto defined variables. #Strict should appear +at the top of your source code before any program code. + +keyword: End +bbdoc: End program execution + +keyword: "Rem" +bbdoc: Begin a remark block +about: All code between #Rem and #EndRem is ignored by the BlitzMax compiler. + +keyword: "EndRem" +bbdoc: End a remark block +about:All code between #Rem and #EndRem is ignored by the BlitzMax compiler. + +keyword: True +bbdoc: Constant integer of value 1 + +keyword: False +bbdoc: Constant integer of value 0 + +keyword: Pi +bbdoc: Constant double of value 3.1415926535897932384626433832795 + +keyword: Null +bbdoc: Get Default value +about: #Null returns a different value depending on context. When used in a numeric context, the value 0 is +returned. When used in a string or array context, an empty string or array is returned. When used in an +object context, the 'null object' is returned. + +keyword: Byte +bbdoc: Unsigned 8 bit integer type + +keyword: Short +bbdoc: Unsigned 16 bit integer type + +keyword: Int +bbdoc: Signed 32 bit integer type + +keyword: Long +bbdoc: Signed 64 bit integer type + +keyword: Float +bbdoc: 32 bit Floating point type + +keyword: Double +bbdoc: 64 bit floating point type + +keyword: String +bbdoc: String type + +keyword: Object +bbdoc: Object type + +keyword: Var +bbdoc: Composite type specifier for 'by reference' types + +keyword: Ptr +bbdoc: Composite type specifier for pointer types + +keyword: If +bbdoc: Begin a conditional block. + +keyword: Then +bbdoc: Optional separator between the condition and associated code in an If statement. + +keyword: Else +bbdoc: Else provides the ability for an If Then construct to execute a second block of code when the If condition is false. + +keyword: ElseIf +bbdoc: ElseIf provides the ability to test and execute a section of code if the initial condition failed. + +keyword: EndIf +bbdoc: Marks the end of an If Then block. + +keyword: For +bbdoc: Marks the start of a loop that uses an iterator to execute a section of code repeatedly. + +keyword: To +bbdoc: Followed by a constant which is used to calculate when to exit a For..Next loop. + +keyword: Step +bbdoc: Specifies an optional constant that is used to increment the For iterator. + +keyword: Next +bbdoc: End a for block + +keyword: EachIn +bbdoc: Iterate throough and array or collection + +keyword: While +bbdoc: Execute a block of close while a condition is true + +keyword: Wend +bbdoc: End a while block + +keyword: Repeat +bbdoc: Execute a block of code until a termination condition is met, or forever + +keyword: Until +bbdoc: End a repeat block + +keyword: Forever +bbdoc: End a repeat block + +keyword: Select +bbdoc: Begin a select block + +keyword: EndSelect +bbdoc: End a select block + +keyword: Case +bbdoc: Conditional code inside a select block + +keyword: Default +bbdoc: Default code inside a select block + +keyword: Exit +bbdoc: Exit enclosing loop + +keyword: Continue +bbdoc: Continue execution of enclosing loop + +keyword: Const +bbdoc: Declare a constant + +keyword: Local +bbdoc: Declare a local variable + +keyword: Global +bbdoc: Declare a global variable + +keyword: Field +bbdoc: Declare a field variable + +keyword: Function +bbdoc: Begin a function declaration + +keyword: EndFunction +bbdoc: End a function declaration + +keyword: Return +bbdoc: Return from a function + +keyword: Type +bbdoc: Begin a user defined type declaration + +keyword: EndType +bbdoc: End a user defined type declaration + +keyword: Extends +bbdoc: Specify user defined type supertype + +keyword: Method +bbdoc: Begin a method declaration + +keyword: EndMethod +bbdoc: End a method declaration + +keyword: Abstract +bbdoc: Denote a type or method as abstract +about: An abstract type cannot be instantiated using New - it is designed to be +extended. A type with any abstract methods is itself automatically abstract. + +keyword: Final +bbdoc: Denote a type or method as final +about: Final types can not be extended and final methods can not be overridden. All methods of a final +type are themselves automatically final. + +keyword: New +bbdoc: Create an instance of a user defined type + +keyword: Self +bbdoc: Self is used in BlitzMax Methods to reference the invoking variable. + +keyword: Super +bbdoc: Super evaluates to Self cast to the method's immediate base class. + +keyword: Delete +bbdoc: Reserved for future expansion + +keyword: Release +bbdoc: Release references to a handle or object + +keyword: Public +bbdoc: Public makes a variable, function or method accessible from outside the current source file (default). + +keyword: Private +bbdoc: Private makes a variable, function or method only accessible from within the current source file. + +keyword: Extern +bbdoc: Extern marks the beginning of an external list of function declarations. + +keyword: EndExtern +bbdoc: EndExtern marks the end of an Extern section. + +keyword: Module +bbdoc: Declare module scope and identifier + +keyword: ModuleInfo +bbdoc: Define module properties + +keyword: Incbin +bbdoc: Embed a data file + +keyword: IncbinPtr +bbdoc: Get start address of embedded data file + +keyword: IncbinLen +bbdoc: Get length of embedded data file + +keyword: Import +bbdoc: Import declarations from a module of source file + +keyword: Assert +bbdoc: Throw a runtimeerror if a condition is false + +keyword: Goto +bbdoc: Transfer program flow to specified label + +keyword: Try +bbdoc: Begin declaration of a try block + +keyword: EndTry +bbdoc: End declaration of a try block + +keyword: Catch +bbdoc: Catch an exception object in a try block + +keyword: Throw +bbdoc: Throw an exception object to the enclosing try block + +keyword: DefData +bbdoc: Define class BASIC style data + +keyword: ReadData +bbdoc: Read classic BASIC style data + +keyword: RestoreData +bbdoc: Restore classic BASIC style data + +keyword: And +bbdoc: Conditional 'and' binary operator + +keyword: Or +bbdoc: Conditional 'Or' binary operator + +keyword: Not +bbdoc: Conditional 'Not' binary operator + +keyword: Shl +bbdoc: Bitwise 'Shift left' binary operator + +keyword: Shr +bbdoc: Bitwise 'Shift right' binary operator + +keyword: Sar +bbdoc: Bitwise 'Shit arithmetic right' binary operator + +keyword: Len +bbdoc: Number of characters in a string or elements in an array + +keyword: Abs +bbdoc: Numeric 'absolute value' unary operator + +keyword: Mod +bbdoc: Numeric 'modulus' or 'remainder' binary operator + +keyword: Sgn +bbdoc: Numeric 'sign' unary operator + +keyword: Min +bbdoc: Numeric 'minimum' binary operator + +keyword: Max +bbdoc: Numeric 'maximum' binary operator + +keyword: Varptr +bbdoc: Find the address of a variable + +keyword: SizeOf +bbdoc: Bytes of memory occupied by a variable, string, array or object + +keyword: Asc +bbdoc: Get character value of the first character of a string +about: #Asc returns -1 if string has 0 length. + +keyword: Chr +bbdoc: Create a string of length 1 with a character code + +EndRem + diff --git a/mod/brl.mod/blitz.mod/blitz_cclib.c b/mod/brl.mod/blitz.mod/blitz_cclib.c new file mode 100644 index 0000000..1b47443 --- /dev/null +++ b/mod/brl.mod/blitz.mod/blitz_cclib.c @@ -0,0 +1,117 @@ + +#include "blitz.h" +#include + +int bbIntAbs( int x ){ + return x>=0 ? x : -x; +} +int bbIntSgn( int x ){ + return x==0 ? 0 : (x>0 ? 1 : -1); +} +int bbIntMod( int x,int y ){ + return x % y; +} +int bbIntMin( int x,int y ){ + return xy ? x : y; +} +void bbIntToLong( BBInt64 *r,int x ){ + *r=x; +} + +double bbFloatAbs( double x ){ + return fabs( x ); +} +double bbFloatSgn( double x ){ + return x==0 ? 0 : (x>0 ? 1 : -1); +} +double bbFloatPow( double x,double y ){ + return pow(x,y); +} +double bbFloatMod( double x,double y ){ + return fmod( x,y ); +} +double bbFloatMin( double x,double y ){ + return xy ? x : y; +} +void bbFloatToLong( BBInt64 *r,double x ){ + *r=x; +} + +void bbLongNeg( BBInt64 *r,BBInt64 x ){ + *r=-x; +} +void bbLongNot( BBInt64 *r,BBInt64 x ){ + *r=~x; +} +void bbLongAbs( BBInt64 *r,BBInt64 x ){ + *r=x>=0 ? x : -x; +} +void bbLongSgn( BBInt64 *r,BBInt64 x ){ + *r=x>0 ? 1 : (x<0 ? -1 : 0); +} +void bbLongAdd( BBInt64 *r,BBInt64 x,BBInt64 y ){ + *r=x+y; +} +void bbLongSub( BBInt64 *r,BBInt64 x,BBInt64 y ){ + *r=x-y; +} +void bbLongMul( BBInt64 *r,BBInt64 x,BBInt64 y ){ + *r=x*y; +} +void bbLongDiv( BBInt64 *r,BBInt64 x,BBInt64 y ){ + *r=x/y; +} +void bbLongMod( BBInt64 *r,BBInt64 x,BBInt64 y ){ + *r=x%y; +} +void bbLongMin( BBInt64 *r,BBInt64 x,BBInt64 y ){ + *r=xy ? x : y; +} +void bbLongAnd( BBInt64 *r,BBInt64 x,BBInt64 y ){ + *r=x&y; +} +void bbLongOrl( BBInt64 *r,BBInt64 x,BBInt64 y ){ + *r=x|y; +} +void bbLongXor( BBInt64 *r,BBInt64 x,BBInt64 y ){ + *r=x^y; +} +void bbLongShl( BBInt64 *r,BBInt64 x,BBInt64 y ){ + *r=x<>(BBUInt64)y; +} +void bbLongSar( BBInt64 *r,BBInt64 x,BBInt64 y ){ + *r=x>>y; +} +int bbLongSlt( BBInt64 x,BBInt64 y ){ + return xy; +} +int bbLongSle( BBInt64 x,BBInt64 y ){ + return x<=y; +} +int bbLongSge( BBInt64 x,BBInt64 y ){ + return x>=y; +} +int bbLongSeq( BBInt64 x,BBInt64 y ){ + return x==y; +} +int bbLongSne( BBInt64 x,BBInt64 y ){ + return x!=y; +} +double bbLongToFloat( BBInt64 x ){ + return (double)x; +} diff --git a/mod/brl.mod/blitz.mod/blitz_cclib.h b/mod/brl.mod/blitz.mod/blitz_cclib.h new file mode 100644 index 0000000..603f3de --- /dev/null +++ b/mod/brl.mod/blitz.mod/blitz_cclib.h @@ -0,0 +1,56 @@ + +#ifndef BLITZ_CCLIB_H +#define BLITZ_CCLIB_H + +#include "blitz_types.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +int bbIntAbs( int x ); +int bbIntSgn( int x ); +int bbIntMod( int x,int y ); +int bbIntMin( int x,int y ); +int bbIntMax( int x,int y ); +void bbIntToLong( BBInt64 *r,int x ); + +double bbFloatAbs( double x ); +double bbFloatSgn( double x ); +double bbFloatPow( double x,double y ); +double bbFloatMod( double x,double y ); +double bbFloatMin( double x,double y ); +double bbFloatMax( double x,double y ); +int bbFloatToInt( double x ); +void bbFloatToLong( BBInt64 *r,double x ); + +void bbLongNeg( BBInt64 *r,BBInt64 x ); +void bbLongNot( BBInt64 *r,BBInt64 x ); +void bbLongAbs( BBInt64 *r,BBInt64 x ); +void bbLongSgn( BBInt64 *r,BBInt64 x ); +void bbLongAdd( BBInt64 *r,BBInt64 x,BBInt64 y ); +void bbLongSub( BBInt64 *r,BBInt64 x,BBInt64 y ); +void bbLongMul( BBInt64 *r,BBInt64 x,BBInt64 y ); +void bbLongDiv( BBInt64 *r,BBInt64 x,BBInt64 y ); +void bbLongMod( BBInt64 *r,BBInt64 x,BBInt64 y ); +void bbLongMin( BBInt64 *r,BBInt64 x,BBInt64 y ); +void bbLongMax( BBInt64 *r,BBInt64 x,BBInt64 y ); +void bbLongAnd( BBInt64 *r,BBInt64 x,BBInt64 y ); +void bbLongOrl( BBInt64 *r,BBInt64 x,BBInt64 y ); +void bbLongXor( BBInt64 *r,BBInt64 x,BBInt64 y ); +void bbLongShl( BBInt64 *r,BBInt64 x,BBInt64 y ); +void bbLongShr( BBInt64 *r,BBInt64 x,BBInt64 y ); +void bbLongSar( BBInt64 *r,BBInt64 x,BBInt64 y ); +int bbLongSlt( BBInt64 x,BBInt64 y ); +int bbLongSgt( BBInt64 x,BBInt64 y ); +int bbLongSle( BBInt64 x,BBInt64 y ); +int bbLongSge( BBInt64 x,BBInt64 y ); +int bbLongSeq( BBInt64 x,BBInt64 y ); +int bbLongSne( BBInt64 x,BBInt64 y ); +double bbLongToFloat( BBInt64 x ); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/mod/brl.mod/blitz.mod/blitz_classes.i b/mod/brl.mod/blitz.mod/blitz_classes.i new file mode 100644 index 0000000..6afe193 --- /dev/null +++ b/mod/brl.mod/blitz.mod/blitz_classes.i @@ -0,0 +1,72 @@ + +Object^Null{ + + -New()="bbObjectCtor" + -Delete()="bbObjectDtor" + + -ToString:String()="bbObjectToString" + -Compare:Int( otherObject:Object )="bbObjectCompare" + -SendMessage:Object( message:Object,source:object )="bbObjectSendMessage" + + -_reserved1_()="bbObjectReserved" + -_reserved2_()="bbObjectReserved" + -_reserved3_()="bbObjectReserved" + +}="bbObjectClass" + +String^Object{ + + .length:Int + + -ToString:String()="bbStringToString" + -Compare:Int(otherObject:Object)="bbStringCompare" + + -Find:Int( subString:String,startIndex=0 )="bbStringFind" + -FindLast:Int( subString:String,startIndex=0 )="bbStringFindLast" + + -Trim:String()="bbStringTrim" + -Replace:String( substring:String,withString:String )="bbStringReplace" + + -ToLower:String()="bbStringToLower" + -ToUpper:String()="bbStringToUpper" + + -ToInt:Int()="bbStringToInt" + -ToLong:Long()="bbStringToLong" + -ToFloat:Float()="bbStringToFloat" + -ToDouble:Double()="bbStringToDouble" + -ToCString:Byte Ptr()="bbStringToCString" + -ToWString:Short Ptr()="bbStringToWString" + + +FromInt:String( intValue:Int)="bbStringFromInt" + +FromLong:String( longValue:Long )="bbStringFromLong" + +FromFloat:String( floatValue:Float )="bbStringFromFloat" + +FromDouble:String( doubleValue:Double )="bbStringFromDouble" + +FromCString:String( cString:Byte Ptr )="bbStringFromCString" + +FromWString:String( wString:Short ptr )="bbStringFromWString" + + +FromBytes:String( bytes:Byte Ptr,count )="bbStringFromBytes" + +FromShorts:String( shorts:Short Ptr,count )="bbStringFromShorts" + + -StartsWith:Int( subString:String )="bbStringStartsWith" + -EndsWith:Int( subString:String )="bbStringEndsWith" + -Contains:Int( subString:String )="bbStringContains" + + -Split:String[]( separator:String )="bbStringSplit" + -Join:String( bits:String[] )="bbStringJoin" + + +FromUTF8String:String( utf8String:Byte Ptr )="bbStringFromUTF8String" + -ToUTF8String:Byte Ptr()="bbStringToUTF8String" + +}AF="bbStringClass" + +Array^Object{ + + .elementTypeEncoding:Byte Ptr + .numberOfDimensions:Int + .sizeMinusHeader:Int + .length:Int + + -Sort( ascending=1 )="bbArraySort" + -Dimensions:Int[]()="bbArrayDimensions" + +}AF="bbArrayClass" diff --git a/mod/brl.mod/blitz.mod/blitz_debug.c b/mod/brl.mod/blitz.mod/blitz_debug.c new file mode 100644 index 0000000..ed76702 --- /dev/null +++ b/mod/brl.mod/blitz.mod/blitz_debug.c @@ -0,0 +1,25 @@ + +#include "blitz.h" + +void bbCAssertEx(){ + bbExThrowCString( "C Assert failed" ); +} + +static void debugNop(){ +} + +static void debugUnhandledEx( BBObject *ex ){ + bbWriteStderr( ex->clas->ToString( ex ) ); + exit(-1); +} + +void (*bbOnDebugStop)()=debugNop; +void (*bbOnDebugLog)( BBString *str )=debugNop; +void (*bbOnDebugEnterStm)( BBDebugStm *stm )=debugNop; +void (*bbOnDebugEnterScope)( BBDebugScope *scope,void *inst )=debugNop; +void (*bbOnDebugLeaveScope)()=debugNop; +void (*bbOnDebugPushExState)()=debugNop; +void (*bbOnDebugPopExState)()=debugNop; + +void (*bbOnDebugUnhandledEx)( BBObject *ex )=debugUnhandledEx; + diff --git a/mod/brl.mod/blitz.mod/blitz_debug.h b/mod/brl.mod/blitz.mod/blitz_debug.h new file mode 100644 index 0000000..f5ab800 --- /dev/null +++ b/mod/brl.mod/blitz.mod/blitz_debug.h @@ -0,0 +1,76 @@ + +#ifndef BLITZ_DEBUG_H +#define BLITZ_DEBUG_H + +#include "blitz_types.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +#ifndef NDEBUG +#define bbassert( x ) if( !(x) ) bbCAssertEx() +#else +#define bbassert( x ) +#endif + +typedef struct BBDebugStm BBDebugStm; +typedef struct BBDebugDecl BBDebugDecl; +typedef struct BBDebugScope BBDebugScope; + +enum{ + BBDEBUGDECL_END=0, + BBDEBUGDECL_CONST=1, + BBDEBUGDECL_LOCAL=2, + BBDEBUGDECL_FIELD=3, + BBDEBUGDECL_GLOBAL=4, + BBDEBUGDECL_VARPARAM=5, + + BBDEBUGDECL_TYPEMETHOD=6, + BBDEBUGDECL_TYPEFUNCTION=7 +}; + +struct BBDebugDecl{ + int kind; + const char *name,*type_tag; + union{ + BBString* const_value; + int local_offset; + int field_offset; + void *global_address; + }; +}; + +enum{ + BBDEBUGSCOPE_FUNCTION=1, + BBDEBUGSCOPE_USERTYPE=2, + BBDEBUGSCOPE_LOCALBLOCK=3 +}; + +struct BBDebugScope{ + int kind; + const char *name; + BBDebugDecl decls[1]; +}; + +struct BBDebugStm{ + const char *source_file; + int line_num,char_num; +}; + +extern void bbCAssertEx(); + +extern void (*bbOnDebugStop)(); +extern void (*bbOnDebugLog)( BBString *msg ); +extern void (*bbOnDebugEnterStm)( BBDebugStm *stm ); +extern void (*bbOnDebugEnterScope)( BBDebugScope *scope,void *inst ); +extern void (*bbOnDebugLeaveScope)(); +extern void (*bbOnDebugPushExState)(); +extern void (*bbOnDebugPopExState)(); +extern void (*bbOnDebugUnhandledEx)( BBObject *ex ); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/mod/brl.mod/blitz.mod/blitz_ex.c b/mod/brl.mod/blitz.mod/blitz_ex.c new file mode 100644 index 0000000..9862012 --- /dev/null +++ b/mod/brl.mod/blitz.mod/blitz_ex.c @@ -0,0 +1,117 @@ + +#include "blitz.h" + +#define EX_GROW 10 + +typedef struct BBExEnv{ + char _cpu_state[256]; //worse case - bit ugly, but better than an #ifdef +}BBExEnv; + +typedef struct BBExStack{ + BBExEnv *ex_base,*ex_sp,*ex_end; +}BBExStack; + +#ifdef _WIN32 + +#include + +static DWORD exKey(){ + static int done; + static DWORD key; + if( !done ){ + key=TlsAlloc(); + done=1; + } + return key; +} + +BBExStack *getExStack(){ + return (BBExStack*)TlsGetValue( exKey() ); +} + +void setExStack( BBExStack *st ){ + TlsSetValue( exKey(),st ); +} + +#else + +#include + +static pthread_key_t exKey(){ + static int done; + static pthread_key_t key; + if( !done ){ + pthread_key_create( &key,0 ); + done=1; + } + return key; +} + +BBExStack *getExStack(){ + return (BBExStack*)pthread_getspecific( exKey() ); +} + +void setExStack( BBExStack *st ){ + pthread_setspecific( exKey(),st ); +} + +#endif + +static BBExStack *exStack(){ + BBExStack *st=getExStack(); + if( !st ){ + st=(BBExStack*)bbMemAlloc( sizeof( BBExStack ) ); + memset( st,0,sizeof( BBExStack ) ); + setExStack( st ); + } + return st; +} + +static void freeExStack( BBExStack *st ){ + bbMemFree( st->ex_base ); + bbMemFree( st ); + setExStack( 0 ); +} + +void *bbExEnter(){ + BBExStack *st=exStack(); + + if( st->ex_sp==st->ex_end ){ + int len=st->ex_sp-st->ex_base,new_len=len+EX_GROW; + st->ex_base=(BBExEnv*)bbMemExtend( st->ex_base,len*sizeof(BBExEnv),new_len*sizeof(BBExEnv) ); + st->ex_end=st->ex_base+new_len; + st->ex_sp=st->ex_base+len; + } + + return (st->ex_sp++)->_cpu_state; +} + +void bbExThrow( BBObject *p ){ + BBExStack *st=getExStack(); + + if( !st ) bbOnDebugUnhandledEx( p ); + + if( --st->ex_sp==st->ex_base ){ + static char buf[256]; + memcpy( buf,st->ex_sp->_cpu_state,256 ); + freeExStack( st ); + _bbExThrow( buf,p ); + }else{ + _bbExThrow( st->ex_sp->_cpu_state,p ); + } +} + +void bbExLeave(){ + BBExStack *st=getExStack(); + + //invariant...leaving a Try! + //assert( st && st->ex_sp!=st->ex_base ); + + if( --st->ex_sp==st->ex_base ){ + freeExStack( st ); + } +} + +void bbExThrowCString( const char *p ){ + bbExThrow( (BBObject*)bbStringFromCString( p ) ); +} diff --git a/mod/brl.mod/blitz.mod/blitz_ex.h b/mod/brl.mod/blitz.mod/blitz_ex.h new file mode 100644 index 0000000..9db77ae --- /dev/null +++ b/mod/brl.mod/blitz.mod/blitz_ex.h @@ -0,0 +1,30 @@ + +#ifndef BLITZ_EX_H +#define BLITZ_EX_H + +#include "blitz_types.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +#if __APPLE__ +#if __i386__ +#define BB_ARGP 1 +void* bbArgp( int offset ); +#endif +#endif + +void* bbExEnter(); +void bbExThrow( BBObject *p ); +void bbExThrowCString( const char *p ); +void bbExLeave(); + +void _bbExEnter( void *_cpu_state ); +void* _bbExThrow( void *_cpu_state,void *p ); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/mod/brl.mod/blitz.mod/blitz_ex.macos.ppc.s b/mod/brl.mod/blitz.mod/blitz_ex.macos.ppc.s new file mode 100644 index 0000000..c6b0893 --- /dev/null +++ b/mod/brl.mod/blitz.mod/blitz_ex.macos.ppc.s @@ -0,0 +1,64 @@ + + .globl __bbExEnter + .globl __bbExThrow + + .text + + ;inputs: + ;r3 = state block +__bbExEnter: + stmw r13,0(r3) + stfd f14,76(r3) + stfd f15,84(r3) + stfd f16,92(r3) + stfd f17,100(r3) + stfd f18,108(r3) + stfd f19,116(r3) + stfd f20,124(r3) + stfd f21,132(r3) + stfd f22,140(r3) + stfd f23,148(r3) + stfd f24,156(r3) + stfd f25,164(r3) + stfd f26,172(r3) + stfd f27,180(r3) + stfd f28,188(r3) + stfd f29,196(r3) + stfd f30,204(r3) + stfd f31,212(r3) + ; + mflr r0 + stw r1,220(r3) + stw r0,224(r3) + li r3,0 + blr + + ;inputs: + ;r3 = state block + ;r4 = Return value +__bbExThrow: + lfd f31,212(r3) + lfd f30,204(r3) + lfd f29,196(r3) + lfd f28,188(r3) + lfd f27,180(r3) + lfd f26,172(r3) + lfd f25,164(r3) + lfd f24,156(r3) + lfd f23,148(r3) + lfd f22,140(r3) + lfd f21,132(r3) + lfd f20,124(r3) + lfd f19,116(r3) + lfd f18,108(r3) + lfd f17,100(r3) + lfd f16,92(r3) + lfd f15,84(r3) + lfd f14,76(r3) + lmw r13,0(r3) + ; + lwz r0,224(r3) + lwz r1,220(r3) + mr r3,r4 + mtlr r0 + blr diff --git a/mod/brl.mod/blitz.mod/blitz_gc.c b/mod/brl.mod/blitz.mod/blitz_gc.c new file mode 100644 index 0000000..3ab3214 --- /dev/null +++ b/mod/brl.mod/blitz.mod/blitz_gc.c @@ -0,0 +1,3 @@ + +#include "blitz.h" + diff --git a/mod/brl.mod/blitz.mod/blitz_gc.h b/mod/brl.mod/blitz.mod/blitz_gc.h new file mode 100644 index 0000000..b9eae5c --- /dev/null +++ b/mod/brl.mod/blitz.mod/blitz_gc.h @@ -0,0 +1,89 @@ + +#ifndef BLITZ_GC_H +#define BLITZ_GC_H + +#include "blitz_types.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +#define BBGC_MANYREFS 0x40000000 + +//for bbGCSetMode +#define BBGC_AUTOMATIC 1 +#define BBGC_MANUAL 2 +#define BBGC_AGGRESSIVE -1 + +//for bbGCSetDebug +#define BBGC_NODEBUG 0 +#define BBGC_STDOUTDEBUG 1 + +//for bbGCAlloc +#define BBGC_ATOMIC 1 +#define BBGC_FINALIZE 2 + +//Probably shouldn't be here... +#if __ppc__ +#define BBGC_NUM_ROOTREGS 19 +#else +#define BBGC_NUM_ROOTREGS 4 +#endif +void* bbGCRootRegs( void *p ); + +void bbGCStartup(); +void bbGCSetMode( int mode ); +void bbGCSetDebug( int debug ); +void* bbGCMalloc( int size,int flags ); +BBObject* bbGCAllocObject( int size,BBClass *clas,int flags ); +int bbGCValidate( void *p ); +int bbGCMemAlloced(); +int bbGCCollect(); +void bbGCSuspend(); +void bbGCResume(); +void bbGCRetain( BBObject *p ); +void bbGCRelease( BBObject *p ); + +// BBRETAIN/BBRELEASE should be used to prevent an object from garbage collection. +// +// This is mainly of use if an object is being stored outside of BlitzMax's 'sight' - say, in a C++ table. +// +// You can also use bbGCRetain/bbGCRelease functions above if necessary - MACROS are just faster. + +// For ref counting GC... +// +#ifdef BB_GC_RC +#define BBRETAIN(X) {++(X)->refs;} +#define BBRELEASE(X) {if( !--(X)->refs ) bbGCFree(X);} +#endif + +// For Mark Sibly GC... +// +#ifdef BB_GC_MS +#define BBRETAIN(X) bbGCRetain( ((BBObject*)(X)) ); +#define BBRELEASE(X) bbGCRelease( ((BBObject*)(X)) ); +#endif + +// For BDW GC... +// +#ifdef BB_GC_BDW +#define BBRETAIN(X) {} +#define BBRELEASE(X) {} +#endif + +// Internal use only +#ifdef BB_GC_RC +void bbGCFree( BBObject *p ); //called when refs==0 - MAY be eligble for GC +void bbGCDeallocObject( BBObject *p,int size ); //called after destruction - Sayonara! +#define BBINCREFS(X) {++(X)->refs;} +#define BBDECREFS(X) {if( !--(X)->refs ) bbGCFree(X);} +#else +#define BBINCREFS(X) {} +#define BBDECREFS(X) {} +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/mod/brl.mod/blitz.mod/blitz_gc.macos.ppc.s b/mod/brl.mod/blitz.mod/blitz_gc.macos.ppc.s new file mode 100644 index 0000000..eecf4e8 --- /dev/null +++ b/mod/brl.mod/blitz.mod/blitz_gc.macos.ppc.s @@ -0,0 +1,11 @@ + + .globl _bbGCRootRegs + + .text + + ;inputs: + ;r3 = state block +_bbGCRootRegs: + stmw r13,0(r3) + addi r3,r1,0 + blr diff --git a/mod/brl.mod/blitz.mod/blitz_gc_ms.c b/mod/brl.mod/blitz.mod/blitz_gc_ms.c new file mode 100644 index 0000000..e8f3906 --- /dev/null +++ b/mod/brl.mod/blitz.mod/blitz_gc_ms.c @@ -0,0 +1,581 @@ + +#include "blitz.h" + +#ifdef BB_GC_MS + +//#define DEBUG_GC + +#define SIZEALIGN 16 +#define ALIGNMASK (SIZEALIGN-1) + +#define BBGC_MARKED 4 +#define BBGC_LOCKED 8 + +#define PAGE_BITS 12 +#define PAGE_SIZE (1<clas; + BBDebugScope *d=c->debug_scope; + if( d ) return d->name; + return "?"; +} + +/* +static void *getTIB(){ + void *tib; + __asm__( "movl %%fs:0x18,%0":"=r"(tib) ); + return tib; +} + +static int atomic_add( volatile int *p,int incr ){ + int result; + + __asm__ __volatile__ ("lock; xaddl %0, %1" : + "=r" (result), "=m" (*p) : "0" (incr), "m" (*p) + : "memory"); + + return result; +} + +static int compare_and_swap( volatile int *addr,int old,int new_val ){ + char result; + + __asm__ __volatile__("lock; cmpxchgl %3, %0; setz %1" + : "=m"(*addr), "=q"(result) + : "m"(*addr), "r" (new_val), "a"(old) : "memory"); + + return (int) result; +} +*/ + +static void gcError( void *p,const char *msg ){ + printf( "GC ERROR: %s, object=$%p\n",msg,p ); + fflush( stdout ); + bbExThrowCString( msg ); +} + +static int setMemBit( void *p ){ + unsigned page; + unsigned offset; + unsigned mask; + + page=(unsigned)p>>(PAGE_BITS+7); + if( !pages[page] ){ + ++pagesAlloced; + pages[page]=malloc( PAGE_SIZE ); + memset( pages[page],0,PAGE_SIZE ); + } + + offset=((unsigned)p>>9) & PAGE_MASK; + mask=1<<( ((unsigned)p>>4) & 31 ); + + if( pages[page][offset] & mask ) gcError( p,"setMemBit error: membit already set" ); + + pages[page][offset]|=mask; +} + +static void clrMemBit( void *p ){ + unsigned page; + unsigned offset; + unsigned mask; + + page=(unsigned)p>>(PAGE_BITS+7); + if( !pages[page] ) gcError( p,"clrMemBit error: mempage does not exist" ); + + offset=((unsigned)p>>9) & PAGE_MASK; + mask=1<<( ((unsigned)p>>4) & 31 ); + + if( !(pages[page][offset] & mask) ) gcError( p,"clrMemBit error: membit not set" ); + + pages[page][offset]&=~mask; +} + +static int tstMemBit( void *p ){ + unsigned page; + unsigned offset; + unsigned mask; + + if( (unsigned)p & 15 ) return 0; + + page=(unsigned)p>>(PAGE_BITS+7); + if( !pages[page] )return 0; + + offset=((unsigned)p>>9) & PAGE_MASK; + mask=1<<( ((unsigned)p>>4) & 31 ); + + return pages[page][offset] & mask; +} + +static void collectMem( int ); + +static int heap_alloced,heap_size; + +static void *heapAlloc( int size ){ + void *p,*q; + + size+=SIZEALIGN+4; + + p=malloc( size ); + + if( !p ){ + bbGCCollect(); + p=malloc( size ); + if( !p ) return 0; + } + + heap_alloced+=size; + + if( heap_alloced>heap_size ){ + heap_size=heap_alloced; +#ifdef DEBUG_GC + printf( "heap_size=%i\n",heap_size );fflush( stdout ); +#endif + } + + q=(void*)( ((unsigned)p+ALIGNMASK+4) & ~ALIGNMASK ); + *((void**)q-1)=p; + + return q; +} + +static void heapFree( void *p,int size ){ + heap_alloced-=size; + + free( *((void**)p-1) ); +} + +static void *allocMem( int size,int flags ){ + size=(size + sizeof(GCBlock) + 15) & ~15; + int i=size/16; + + GCBlock *t; + + if( i<256 && (t=freeBlocks[i]) ){ + freeBlocks[i]=t->succ; + }else{ + static int alloced; + if( gc_mode==BBGC_AUTOMATIC && (gc_alloced-alloced)>heap_size/3 ){ + collectMem(0); + alloced=gc_alloced; + } + + if( i>255 ){ + t=heapAlloc( size ); + setMemBit( t ); + }else if( t=freeBlocks[i] ){ + freeBlocks[i]=t->succ; + }else{ + if( size>freeBufSize ){ + if( freeBufSize ){ + int i=freeBufSize/16; + GCBlock *t=freeBuf; + t->flags=BBGC_MARKED; + t->succ=freeBlocks[i]; + freeBlocks[i]=t; + setMemBit( t ); + } + freeBufSize=65536; + freeBuf=heapAlloc( freeBufSize ); + } + t=freeBuf; + freeBuf+=size; + freeBufSize-=size; + setMemBit( t ); + } + } + + t->succ=usedBlocks; + t->flags=size|flags; + usedBlocks=t; + + gc_alloced+=size; + return t->data; +} + +static GCBlock *getBlock( void *p ){ + GCBlock *q=(GCBlock*)p-1; + if( tstMemBit( q ) ) return q; + return 0; +} + +static void freeBlock( GCBlock *t ){ + int flags=t->flags; + int size=flags & ~15; + int i=size/16; + + if( i>255 ){ + clrMemBit( t ); + heapFree( t,size ); + }else{ + t->flags=BBGC_MARKED; + t->succ=freeBlocks[i]; + freeBlocks[i]=t; + } + gc_alloced-=size; +} + +static void mark( void *p ){ + GCBlock *t=getBlock( p ); + if( !t ) return; + + if( t->flags & BBGC_MARKED ) return; + + t->flags|=BBGC_MARKED; + + if( t->flags & BBGC_ATOMIC ) return; + + int size=t->flags & ~15,i; + + for( i=sizeof(GCBlock);isucc ){ + + for( i=0;i<32;++i ){ + mark( thread->data[i] ); + } + + if( thread==curThread ){ + void *regs[BBGC_NUM_ROOTREGS]; + void **sp=bbGCRootRegs( regs ); + for( i=0;istackTop;++r ){ + mark( *r ); + } + }else{ + for( i=0;ilocked_regs[i] ); + } + for( r=(void**)thread->locked_sp;r!=thread->stackTop;++r ){ + mark( *r ); + } + } + } + + for( i=0;isucc ){ + if( t->flags & BBGC_LOCKED ) mark( t->data ); + } + + //resurrect or free finalized blocks + while( t=finalizedBlocks ){ + finalizedBlocks=t->succ; + if( t->flags & BBGC_MARKED ){ + //resurrect me! + t->succ=usedBlocks; + usedBlocks=t; + if( t->flags & BBGC_FINALIZE ){ + t->flags&=~BBGC_FINALIZE; +#ifdef DEBUG_GC + BBObject *q=(BBObject*)t->data; + printf( "GC resurrected:%s @%p\n",typeName( q ),q );fflush( stdout ); +#endif + } + }else{ + freeBlock( t ); + } + } + + GCBlock **p=&usedBlocks; + + int n_finalized=0; + + while( t=*p ){ + if( t->flags & BBGC_MARKED ){ + p=&t->succ; + t->flags&=~BBGC_MARKED; + }else{ + *p=t->succ; + if( t->flags & BBGC_FINALIZE ){ + ++n_finalized; + BBObject *q=(BBObject*)t->data; +// printf( "GC finalizing:%s\n",typeName( q ) );fflush( stdout ); + BBClass *c=q->clas; + c->free( q ); + q->clas=c; + } + t->succ=finalizedBlocks; + finalizedBlocks=t; + } + } + + if( !n_finalized ){ + // + //No finalizers were run, so it's OK to free blocks NOW. + // + while( t=finalizedBlocks ){ + finalizedBlocks=t->succ; + freeBlock( t ); + } + } + + _bbThreadUnlockThreads(); + +#ifdef DEBUG_GC + int end_ms=bbMilliSecs(); + printf( "gc ms=%i, marked=%i, marked_ms=%i, freed=%i, freed_ms=%i\n",end_ms-ms,n_marked,mark_ms-ms,n_freed,end_ms-mark_ms );fflush( stdout ); +#endif + + recurs=0; +} + +//***** GC Interface *****// +static int isGlobalVar( int *p ){ + if( p==&bbNullObject ) return 1; + if( p==&bbEmptyString ) return 1; + if( p==&bbEmptyArray ) return 1; + if( ( p>=DATA_START && pclas=clas; + q->refs=0; + + BB_UNLOCK + +// if( clas!=&bbStringClass ){ +// printf( "%s = %p\n",typeName(q),q );fflush( stdout ); +// } + + return q; +} + +int bbGCValidate( void *p ){ + int r; + + BB_LOCK + + r=getBlock( p ) ? 1 : 0; + + BB_UNLOCK + return r; +} + +int bbGCMemAlloced(){ + return gc_alloced; +} + +int bbGCCollect(){ + int t; + + if( gc_suspended ) return 0; + + BB_LOCK + + t=gc_alloced; + collectMem( 0 ); + t-=gc_alloced; + + BB_UNLOCK + return t; +} + +void bbGCSuspend(){ + BB_LOCK + + ++gc_suspended; + + BB_UNLOCK +} + +void bbGCResume(){ + BB_LOCK + + --gc_suspended; + + BB_UNLOCK +} + +void bbGCRetain( BBObject *p ){ + BB_LOCK + + GCBlock *t=getBlock( p ); + if( t ){ + if( !p->refs++ ) t->flags|=BBGC_LOCKED; + } + + BB_UNLOCK +} + +void bbGCRelease( BBObject *p ){ + BB_LOCK + + GCBlock *t=getBlock( p ); + if( t ){ + if( !--p->refs ) t->flags&=~BBGC_LOCKED; + } + + BB_UNLOCK +} + +#endif diff --git a/mod/brl.mod/blitz.mod/blitz_gc_rc.c b/mod/brl.mod/blitz.mod/blitz_gc_rc.c new file mode 100644 index 0000000..7ba349b --- /dev/null +++ b/mod/brl.mod/blitz.mod/blitz_gc_rc.c @@ -0,0 +1,383 @@ + +#include "blitz.h" + +#ifdef BB_GC_RC + +//#define DEBUG_GC + +#ifdef _WIN32 +#include +#endif + +#define SIZEALIGN 16 +#define ALIGNMASK (SIZEALIGN-1) + +#define BUF_GROW 1024 + +#define BBGC_ZERO 0x80000000 + +#define PAGE_BITS 12 +#define PAGE_SIZE (1<clas; + BBDebugScope *d=c->debug_scope; + if( d ) return d->name; + return "?"; +} + +static void debugObject( void *p,const char *msg ){ + GCDebugInfo *db=dbInfos+(dbIndex & DEBUG_MASK); + db->object=p; + db->typename=typeName( p ); + db->msg=msg; + ++dbIndex; + if( debugAtExit ) return; + atexit( dumpDebugInfo ); + debugAtExit=1; +} + +static void dumpDebugInfo(){ + int i; + printf( "GC Debug info:\n" ); + for( i=0;iobject ) continue; + printf( "%s %s @ $%p\n",db->msg,db->typename,db->object ); + } + fflush( stdout ); +} + +#else + +#define DEBUG_OBJECT(X,Y) + +#endif + +static void gcError( void *p,const char *msg ){ +#ifdef DEBUG_GC + printf( "GC ERROR: %s, object=$%p\n",msg,p ); + fflush( stdout ); +#endif + bbExThrowCString( msg ); +} + +static int setMemBit( void *p ){ + int page; + int offset; + int mask; + + page=(unsigned)p>>(PAGE_BITS+7); + + if( !pages[page] ){ + ++pagesAlloced; + pages[page]=malloc( PAGE_SIZE ); + memset( pages[page],0,PAGE_SIZE ); + } + + offset=((unsigned)p>>9) & PAGE_MASK; + mask=1<<( ((unsigned)p>>4) & 31 ); + + if( pages[page][offset] & mask ) gcError( p,"setMemBit error: membit already set" ); + + pages[page][offset]|=mask; + + DEBUG_OBJECT( p,"setMemBit" ); +} + +static void clrMemBit( void *p ){ + int page; + int offset; + int mask; + + page=(unsigned)p>>(PAGE_BITS+7); + + if( !pages[page] ) gcError( p,"clrMemBit error: mempage does not exist" ); + + offset=((unsigned)p>>9) & PAGE_MASK; + mask=1<<( ((unsigned)p>>4) & 31 ); + + if( !(pages[page][offset] & mask) ) gcError( p,"clrMemBit error: membit not set" ); + + pages[page][offset]&=~mask; + + DEBUG_OBJECT( p,"clrMemBit" ); +} + +static int tstMemBit( void *p ){ + int page; + int offset; + int mask; + + if( (int)p & 15 ) return 0; + + page=(unsigned)p>>(PAGE_BITS+7); + if( !pages[page] ){ + return 0; + } + offset=((unsigned)p>>9) & PAGE_MASK; + mask=1<<( ((unsigned)p>>4) & 31 ); + + return pages[page][offset] & mask; +} + +static int collectMem( int dummy ){ + + int i,n; + BBObject *p; + void **sp,**spBase,**tsp; + void *rootRegs[BBGC_NUM_ROOTREGS]; + + if( gc_suspended || !bbGCStackTop ) return 0; + + ++gc_suspended; + + gc_memfreed=bbGCMemAlloced(); + + if( gc_debug ){ + gc_millisecs=-1; +#if _WIN32 + gc_millisecs=timeGetTime(); +#endif + } + + spBase=bbGCRootRegs( rootRegs ); + + n=bbGCStackTop-spBase+BBGC_NUM_ROOTREGS; + if( n>live_len ){ + void **t=live; + int new_len=live_len+1000; + if( n>new_len ) new_len=n; + live=(void**)malloc( new_len*4 ); + if( t ) free( t ); + live_len=new_len; + } + + tsp=live; + sp=spBase; + while( sp!=bbGCStackTop ){ + p=*sp++; + if( tstMemBit( p ) ) *tsp++=p; + } + sp=rootRegs; + for( n=0;nrefs; + } + + i=0; + gc_objsfreed=0; + while( i!=(buf_put-buf_base) ){ + p=buf_base[i++]; + if( p->refs>=0 ){ + printf( "bad refs:obj=$%x refs=$%x\n",(unsigned)p,(unsigned)p->refs ); + if( p->clas==&bbStringClass ){ + printf( "String:%s\n",bbStringToCString( (BBString*)p ) ); + } + fflush( stdout ); + } + if( p->refs&=~BBGC_ZERO ) continue; + p->clas->free( p ); + ++gc_objsfreed; + } + buf_put=buf_base; + + sp=live; + while( sp!=tsp ){ + p=*sp++; + if( !--p->refs ) bbGCFree( p ); + } + + gc_memfreed-=bbGCMemAlloced(); + + if( gc_debug ){ +#if _WIN32 + gc_millisecs=timeGetTime()-gc_millisecs; +#endif + printf( "GC collectMem: memFreed=%i, time=%ims, objsFreed=%i, objsScanned=%i, objsLive=%i\n", + gc_memfreed, + gc_millisecs, + gc_objsfreed, + bbGCStackTop-spBase, + tsp-live ); + fflush( stdout ); + } + + --gc_suspended; + + return gc_memfreed; +} + +//***** GC INTERFACE *****// +void bbGCStartup(){ +} + +void bbGCSetMode( int mode ){ + gc_mode=mode; +} + +void bbGCSetDebug( int debug ){ + gc_debug=debug; +} + +BBObject *bbGCAllocObject( int size,BBClass *clas,int flags ){ + BBObject *p; + + if( gc_mode==BBGC_AUTOMATIC && !gc_suspended ){ + static int alloced; + static int rate=500; + alloced+=size; + if( alloced>(1024*1024) || buf_put-buf_base>rate ){ + collectMem(0); + rate+=500-gc_objsfreed; + alloced=0; + } + }else if( gc_mode==BBGC_AGGRESSIVE ){ + collectMem(0); + } + + if( size<=0 ) return 0; + + if( size>(MAXSIZE-SIZEALIGN) ){ + p=bbMemAlloc( size ); + }else{ + int n=(size+ALIGNMASK)/SIZEALIGN; + p=freelists[n]; + + if( p ){ + freelists[n]=*(char**)p; + }else if( size<=freebufsize ){ + p=freebuf; + n*=SIZEALIGN; + freebuf+=n; + freebufsize-=n; + }else{ + if( freebufsize ){ + int n=(freebufsize+ALIGNMASK)/SIZEALIGN; + *(char**)freebuf=freelists[n]; + freelists[n]=freebuf; + } + p=bbMemAlloc( MAXFREEBUFSIZE ); + n*=SIZEALIGN; + freebuf=(char*)p+n; + freebufsize=MAXFREEBUFSIZE-n; + } + } + setMemBit( p ); + gc_alloced+=size; + p->clas=clas; + p->refs=0; + bbGCFree( p ); + return p; +} + +int bbGCValidate( void *p ){ + return tstMemBit( p ) ? 1 : 0; +} + +int bbGCMemAlloced(){ + return gc_alloced; +} + +int bbGCCollect(){ + return collectMem(0); +} + +void bbGCSuspend(){ + ++gc_suspended; +} + +void bbGCResume(){ + --gc_suspended; +} + +void bbGCRetain( BBObject *p ){ + BBINCREFS( p ); +} + +void bbGCRelease( BBObject *p ){ + BBDECREFS( p ); +} + +//***** Ref counter specific *****// +void bbGCFree( BBObject *p ){ + if( p->refs ){ + bbExThrowCString( "GC bbGCFree: mem has non-0 refs" ); + } + if( buf_put==buf_end ){ + int len=buf_put-buf_base,new_len=len+BUF_GROW; + buf_base=(void**)bbMemExtend( buf_base,len*4,new_len*4 ); + buf_end=buf_base+new_len; + buf_put=buf_base+len; + if( new_len>max_buflen ) max_buflen=new_len; + } + p->refs=BBGC_ZERO; + *buf_put++=p; +} + +void bbGCDeallocObject( BBObject *p,int size ){ + if( !p ) return; + clrMemBit( p ); + if( size>(MAXSIZE-SIZEALIGN) ){ + bbMemFree( p ); + }else{ + int n=(size+ALIGNMASK)/SIZEALIGN; + *(char**)p=freelists[n]; + freelists[n]=(char*)p; + } + gc_alloced-=size; +} + +#endif diff --git a/mod/brl.mod/blitz.mod/blitz_handle.c b/mod/brl.mod/blitz.mod/blitz_handle.c new file mode 100644 index 0000000..6efa0dd --- /dev/null +++ b/mod/brl.mod/blitz.mod/blitz_handle.c @@ -0,0 +1,69 @@ + +#include "blitz.h" + +#define HASH_SIZE 1024 +#define HASH_SLOT(X) (((X)/8)&(HASH_SIZE-1)) // divide-by-8 for better void* mapping. + +static int _handle_id; + +typedef struct Hash Hash; + +struct Hash{ + Hash *succ; + int key,value; +}; + +static Hash *object_hash[HASH_SIZE]; +static Hash *handle_hash[HASH_SIZE]; + +static int hashFind( Hash **table,int key ){ + Hash *t,**p; + int t_key=HASH_SLOT(key); + for( p=&table[t_key];(t=*p) && t->key!=key;p=&t->succ ){} + return t ? t->value : 0; +} + +static int hashRemove( Hash **table,int key ){ + Hash *t,**p; + int t_key=HASH_SLOT(key),n; + for( p=&table[t_key];(t=*p) && key!=t->key;p=&t->succ ){} + if( !t ) return 0; + n=t->value; + *p=t->succ; + bbMemFree( t ); + return n; +} + +static void hashInsert( Hash **table,int key,int value ){ + int t_key=HASH_SLOT(key); + Hash *t=(Hash*)bbMemAlloc( sizeof(Hash) ); + t->key=key; + t->value=value; + t->succ=table[t_key]; + table[t_key]=t; +} + +int bbHandleFromObject( BBObject *o ){ + int n; + if( o==&bbNullObject ) return 0; + n=hashFind( object_hash,(int)o ); + if( n ) return n/8; + BBRETAIN( o ); + _handle_id+=8; + if( !(_handle_id/8) ) _handle_id+=8; //just-in-case! + hashInsert( object_hash,(int)o,_handle_id ); + hashInsert( handle_hash,_handle_id,(int)o ); + return _handle_id/8; +} + +BBObject *bbHandleToObject( int handle ){ + BBObject *o=(BBObject*)hashFind( handle_hash,handle*8 ); + return o ? o : &bbNullObject; +} + +void bbHandleRelease( int handle ){ + BBObject *o=(BBObject*)hashRemove( handle_hash,handle*8 ); + if( !o ) return; + hashRemove( object_hash,(int)o ); + BBRELEASE( o ); +} diff --git a/mod/brl.mod/blitz.mod/blitz_handle.h b/mod/brl.mod/blitz.mod/blitz_handle.h new file mode 100644 index 0000000..5240db9 --- /dev/null +++ b/mod/brl.mod/blitz.mod/blitz_handle.h @@ -0,0 +1,21 @@ + +#ifndef BLITZ_HANDLE_H +#define BLITZ_HANDLE_H + +#include "blitz_types.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +int bbHandleFromObject( BBObject *o ); +BBObject* bbHandleToObject( int handle ); +void bbHandleRelease( int handle ); + +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/mod/brl.mod/blitz.mod/blitz_incbin.c b/mod/brl.mod/blitz.mod/blitz_incbin.c new file mode 100644 index 0000000..5cfdd08 --- /dev/null +++ b/mod/brl.mod/blitz.mod/blitz_incbin.c @@ -0,0 +1,56 @@ + +#include "blitz.h" + +typedef struct BBIncbin BBIncbin; + +struct BBIncbin{ + BBIncbin *succ; + BBString *path; + void *ptr; + int len; +}; + +static BBIncbin *incs; + +static BBIncbin *find( BBString *path ){ + BBIncbin *p; + for( p=incs;p;p=p->succ ){ + if( !bbStringCompare(path,p->path) ) return p; + + } + return 0; +} + +int bbIncbinAdd( BBString *path,void *ptr,int len ){ + BBIncbin *p; + + p=find( path ); + if( p ) return 0; + + p=(BBIncbin*)bbMemAlloc( sizeof(BBIncbin) ); + + BBRETAIN( path ); + p->path=path; + p->ptr=ptr; + p->len=len; + p->succ=incs; + incs=p; + + return 1; +} + +void *bbIncbinPtr( BBString *path ){ + BBIncbin *p; + + p=find( path ); + + return p ? p->ptr : 0; +} + +int bbIncbinLen( BBString *path ){ + BBIncbin *p; + + p=find( path ); + + return p ? p->len : 0; +} diff --git a/mod/brl.mod/blitz.mod/blitz_incbin.h b/mod/brl.mod/blitz.mod/blitz_incbin.h new file mode 100644 index 0000000..020b003 --- /dev/null +++ b/mod/brl.mod/blitz.mod/blitz_incbin.h @@ -0,0 +1,19 @@ + +#ifndef BLITZ_INCBIN_H +#define BLITZ_INCBIN_H + +#include "blitz_types.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +int bbIncbinAdd( BBString *file,void *ptr,int len ); +void* bbIncbinPtr( BBString *file ); +int bbIncbinLen( BBString *file ); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/mod/brl.mod/blitz.mod/blitz_memory.c b/mod/brl.mod/blitz.mod/blitz_memory.c new file mode 100644 index 0000000..83e8f80 --- /dev/null +++ b/mod/brl.mod/blitz.mod/blitz_memory.c @@ -0,0 +1,53 @@ + +#include "blitz.h" + +#define SIZEALIGN 16 +#define ALIGNMASK (SIZEALIGN-1) + +//Allocates mem on 16 byte aligned boundary. +// +//Used by (some) GC routines to allocate large chunks, and GC mem needs to be on 16 byte boundary for +//mem bit flags system in ref couter/Mark Sibly GCs... +// +void *bbMemAlloc( int size ){ + void *p,*q; + + size+=SIZEALIGN+4; + + p=malloc( size ); + + if( !p ){ + bbGCCollect(); + p=malloc( size ); + if( !p ) return 0; + } + + q=(void*)( ((unsigned)p+ALIGNMASK+4) & ~ALIGNMASK ); + *((void**)q-1)=p; + + return q; +} + +void bbMemFree( void *p ){ + if( p ) free( ((void**)p)[-1] ); +} + +void *bbMemExtend( void *mem,int size,int new_size ){ + void *p; + p=bbMemAlloc( new_size ); + bbMemCopy( p,mem,size ); + bbMemFree( mem ); + return p; +} + +void bbMemClear( void *dst,int size ){ + memset( dst,0,size ); +} + +void bbMemCopy( void *dst,const void *src,int size ){ + memcpy( dst,src,size ); +} + +void bbMemMove( void *dst,const void *src,int size ){ + memmove( dst,src,size ); +} diff --git a/mod/brl.mod/blitz.mod/blitz_memory.h b/mod/brl.mod/blitz.mod/blitz_memory.h new file mode 100644 index 0000000..42ad95f --- /dev/null +++ b/mod/brl.mod/blitz.mod/blitz_memory.h @@ -0,0 +1,23 @@ + +#ifndef BLITZ_MEMORY_H +#define BLITZ_MEMORY_H + +#include "blitz_types.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +void* bbMemAlloc( int ); +void bbMemFree( void *mem ); +void* bbMemExtend( void *mem,int size,int new_size ); + +void bbMemClear( void *dst,int size ); +void bbMemCopy( void *dst,const void *src,int size ); +void bbMemMove( void *dst,const void *src,int size ); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/mod/brl.mod/blitz.mod/blitz_module.c b/mod/brl.mod/blitz.mod/blitz_module.c new file mode 100644 index 0000000..a15d786 --- /dev/null +++ b/mod/brl.mod/blitz.mod/blitz_module.c @@ -0,0 +1,17 @@ + +#include "blitz.h" + +static BBModule *modules; + +void bbModuleImport( BBModule *mod ){ + BBModule *t; + for( t=modules;t;t=t->succ ){ + if( t==mod ) return; + } + mod->entry(); +} + +void bbModuleRegister( BBModule *mod ){ + mod->succ=modules; + modules=mod; +} diff --git a/mod/brl.mod/blitz.mod/blitz_module.h b/mod/brl.mod/blitz.mod/blitz_module.h new file mode 100644 index 0000000..4ab66b1 --- /dev/null +++ b/mod/brl.mod/blitz.mod/blitz_module.h @@ -0,0 +1,26 @@ + +#ifndef BLITZ_MODULE_H +#define BLITZ_MODULE_H + +#include "blitz_types.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +typedef struct BBModule BBModule; + +struct BBModule{ + BBModule* succ; + const char* ident; + void (*entry)(); +}; + +void bbModuleImport( BBModule *mod ); +void bbModuleRegister( BBModule *mod ); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/mod/brl.mod/blitz.mod/blitz_object.c b/mod/brl.mod/blitz.mod/blitz_object.c new file mode 100644 index 0000000..d111f94 --- /dev/null +++ b/mod/brl.mod/blitz.mod/blitz_object.c @@ -0,0 +1,107 @@ + +#include "blitz.h" + +#define REG_GROW 256 + +static BBClass **reg_base,**reg_put,**reg_end; + +static BBDebugScope debugScope={ + BBDEBUGSCOPE_USERTYPE, + "Object", + BBDEBUGDECL_END +}; + +BBClass bbObjectClass={ + 0, //super + bbObjectFree, //free + &debugScope, //debug_scope + 8, //instance_size + + bbObjectCtor, + bbObjectDtor, + bbObjectToString, + bbObjectCompare, + bbObjectSendMessage, + bbObjectReserved, + bbObjectReserved, + bbObjectReserved, +}; + +BBObject bbNullObject={ + 0, //clas + BBGC_MANYREFS //refs +}; + +BBObject *bbObjectNew( BBClass *clas ){ + int flags=( clas->dtor!=bbObjectDtor ) ? BBGC_FINALIZE : 0; + BBObject *o=(BBObject*)bbGCAllocObject( clas->instance_size,clas,flags ); + clas->ctor( o ); + return o; +} + +void bbObjectFree( BBObject *o ){ + BBClass *clas=o->clas; + +#ifdef BB_GC_RC + + if( o==&bbNullObject ){ + o->refs=BBGC_MANYREFS; + return; + } + + clas->dtor( o ); + bbGCDeallocObject( o,clas->instance_size ); + +#else + + clas->dtor( o ); + +#endif +} + +void bbObjectCtor( BBObject *o ){ + o->clas=&bbObjectClass; +} + +void bbObjectDtor( BBObject *o ){ + o->clas=0; +} + +BBString *bbObjectToString( BBObject *o ){ + char buf[32]; + sprintf( buf,"%p",o ); + return bbStringFromCString( buf ); +} + +int bbObjectCompare( BBObject *x,BBObject *y ){ + return (char*)x-(char*)y; +} + +BBObject *bbObjectSendMessage( BBObject *m,BBObject *s ){ + return &bbNullObject; +} + +void bbObjectReserved(){ + bbExThrowCString( "Illegal call to reserved method" ); +} + +BBObject *bbObjectDowncast( BBObject *o,BBClass *t ){ + BBClass *p=o->clas; + while( p && p!=t ) p=p->super; + return p ? o : &bbNullObject; +} + +void bbObjectRegisterType( BBClass *clas ){ + if( reg_put==reg_end ){ + int len=reg_put-reg_base,new_len=len+REG_GROW; + reg_base=(BBClass**)bbMemExtend( reg_base,len*sizeof(BBClass*),new_len*sizeof(BBClass*) ); + reg_end=reg_base+new_len; + reg_put=reg_base+len; + } + *reg_put++=clas; +} + +BBClass **bbObjectRegisteredTypes( int *count ){ + *count=reg_put-reg_base; + return reg_base; +} diff --git a/mod/brl.mod/blitz.mod/blitz_object.h b/mod/brl.mod/blitz.mod/blitz_object.h new file mode 100644 index 0000000..44f3697 --- /dev/null +++ b/mod/brl.mod/blitz.mod/blitz_object.h @@ -0,0 +1,66 @@ + +#ifndef BLITZ_OBJECT_H +#define BLITZ_OBJECT_H + +#include "blitz_types.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +#define BBNULL (&bbNullObject) + +#define BBNULLOBJECT (&bbNullObject) + +struct BBClass{ + //extends BBGCPool + BBClass* super; + void (*free)( BBObject *o ); + + BBDebugScope*debug_scope; + + int instance_size; + + void (*ctor)( BBObject *o ); + void (*dtor)( BBObject *o ); + + BBString* (*ToString)( BBObject *x ); + int (*Compare)( BBObject *x,BBObject *y ); + BBObject* (*SendMessage)( BBObject *m,BBObject *s ); + void (*_reserved1_)(); + void (*_reserved2_)(); + void (*_reserved3_)(); + + void* vfns[32]; +}; + +struct BBObject{ + //extends BBGCMem + BBClass* clas; + int refs; +}; + +extern BBClass bbObjectClass; +extern BBObject bbNullObject; + +BBObject* bbObjectNew( BBClass *t ); +void bbObjectFree( BBObject *o ); + +void bbObjectCtor( BBObject *o ); +void bbObjectDtor( BBObject *o ); + +BBString* bbObjectToString( BBObject *o ); +int bbObjectCompare( BBObject *x,BBObject *y ); +BBObject* bbObjectSendMessage( BBObject *m,BBObject *s ); +void bbObjectReserved(); + +BBObject* bbObjectDowncast( BBObject *o,BBClass *t ); + +void bbObjectRegisterType( BBClass *clas ); +BBClass** bbObjectRegisteredTypes( int *count ); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/mod/brl.mod/blitz.mod/blitz_string.c b/mod/brl.mod/blitz.mod/blitz_string.c new file mode 100644 index 0000000..88ecbb7 --- /dev/null +++ b/mod/brl.mod/blitz.mod/blitz_string.c @@ -0,0 +1,645 @@ + +#include "blitz.h" + +#include "blitz_unicode.h" + +static void bbStringFree( BBObject *o ); + +static BBDebugScope debugScope={ + BBDEBUGSCOPE_USERTYPE, + "String", + BBDEBUGDECL_END +}; + +BBClass bbStringClass={ + &bbObjectClass, //super + bbStringFree, //free + &debugScope, //DebugScope + 0, //instance_size + 0, //ctor + 0, //dtor + + (BBString*(*)(BBObject*))bbStringToString, + (int(*)(BBObject*,BBObject*))bbStringCompare, + bbObjectSendMessage, + bbObjectReserved, + bbObjectReserved, + bbObjectReserved, + + bbStringFind, + bbStringFindLast, + bbStringTrim, + bbStringReplace, + + bbStringToLower, + bbStringToUpper, + + bbStringToInt, + bbStringToLong, + bbStringToFloat, + bbStringToDouble, + bbStringToCString, + bbStringToWString, + + bbStringFromInt, + bbStringFromLong, + bbStringFromFloat, + bbStringFromDouble, + bbStringFromCString, + bbStringFromWString, + + bbStringFromBytes, + bbStringFromShorts, + + bbStringStartsWith, + bbStringEndsWith, + bbStringContains, + + bbStringSplit, + bbStringJoin, + + bbStringFromUTF8String, + bbStringToUTF8String +}; + +BBString bbEmptyString={ + &bbStringClass, //clas + BBGC_MANYREFS, //refs + 0 //length +}; + +static int wstrlen( const BBChar *p ){ + const BBChar *t=p; + while( *t ) ++t; + return t-p; +} + +static int charsEqual( unsigned short *a,unsigned short *b,int n ){ + while( n-- ){ + if (*a!=*b) return 0; + a++;b++; + } + return 1; +} + +//***** Note: Not called in THREADED mode. +static void bbStringFree( BBObject *o ){ +#ifdef BB_GC_RC + BBString *str=(BBString*)o; + if( str==&bbEmptyString ){ + str->refs=BBGC_MANYREFS; + return; + } + bbGCDeallocObject( str,sizeof(BBString)+str->length*sizeof(BBChar) ); +#endif +} + +BBString *bbStringNew( int len ){ + int flags; + BBString *str; + if( !len ) return &bbEmptyString; + str=(BBString*)bbGCAllocObject( sizeof(BBString)+len*sizeof(BBChar),&bbStringClass,BBGC_ATOMIC ); + str->length=len; + return str; +} + +BBString *bbStringFromChar( int c ){ + BBString *str=bbStringNew(1); + str->buf[0]=c; + return str; +} + +BBString *bbStringFromInt( int n ){ + char buf[64],*p=buf+64; + int neg=n<0; + if( neg ){ + n=-n;if( n<0 ) return bbStringFromBytes( "-2147483648",11 ); + } + do{ + *--p=n%10+'0'; + }while(n/=10); + if( neg ) *--p='-'; + return bbStringFromBytes( p,buf+64-p ); +} + +BBString *bbStringFromLong( BBInt64 n ){ + char buf[64],*p=buf+64; + int neg=n<0; + if( neg ){ + n=-n;if( n<0 ) return bbStringFromBytes( "-9223372036854775808",20 ); + } + do{ + *--p=n%10+'0'; + }while(n/=10); + if( neg ) *--p='-'; + return bbStringFromBytes( p,buf+64-p ); +} + +BBString *bbStringFromFloat( float n ){ + char buf[64]; + sprintf( buf,"%#.9g",n ); + return bbStringFromCString(buf); +} + +BBString *bbStringFromDouble( double n ){ + char buf[64]; + sprintf( buf,"%#.17lg",n ); + return bbStringFromCString(buf); +} + +BBString *bbStringFromBytes( const char *p,int n ){ + int k; + BBString *str; + if( !n ) return &bbEmptyString; + str=bbStringNew( n ); + for( k=0;kbuf[k]=(unsigned char)p[k]; + return str; +} + +BBString *bbStringFromShorts( const unsigned short *p,int n ){ + BBString *str; + if( !n ) return &bbEmptyString; + str=bbStringNew( n ); + bbMemCopy( str->buf,p,n*sizeof(short) ); + return str; +} + +BBString *bbStringFromInts( const int *p,int n ){ + int k; + BBString *str; + if( !n ) return &bbEmptyString; + str=bbStringNew( n ); + for( k=0;kbuf[k]=p[k]; + return str; +} + +BBString *bbStringFromArray( BBArray *arr ){ + int n; + void *p; + if( arr->dims!=1 ) return &bbEmptyString; + n=arr->scales[0]; + p=BBARRAYDATA(arr,arr->dims); + switch( arr->type[0] ){ + case 'b':return bbStringFromBytes( p,n ); + case 's':return bbStringFromShorts( p,n ); + case 'i':return bbStringFromInts( p,n ); + } + return &bbEmptyString; +} + +BBString *bbStringFromCString( const char *p ){ + return p ? bbStringFromBytes( p,strlen(p) ) : &bbEmptyString; +} + +BBString *bbStringFromWString( const BBChar *p ){ + return p ? bbStringFromShorts( p,wstrlen(p) ) : &bbEmptyString; +} + +BBString *bbStringFromUTF8String( const char *p ){ + int c,n; + short *d,*q; + BBString *str; + + if( !p ) return &bbEmptyString; + + n=strlen(p); + d=(short*)malloc( n*2 ); + q=d; + + while( c=*p++ & 0xff ){ + if( c<0x80 ){ + *q++=c; + }else{ + int d=*p++ & 0x3f; + if( c<0xe0 ){ + *q++=((c&31)<<6) | d; + }else{ + int e=*p++ & 0x3f; + if( c<0xf0 ){ + *q++=((c&15)<<12) | (d<<6) | e; + }else{ + int f=*p++ & 0x3f; + int v=((c&7)<<18) | (d<<12) | (e<<6) | f; + if( v & 0xffff0000 ) bbExThrowCString( "Unicode character out of UCS-2 range" ); + *q++=v; + } + } + } + } + str=bbStringFromShorts( d,q-d ); + free( d ); + return str; +} + +BBString *bbStringToString( BBString *t ){ + return t; +} + +int bbStringCompare( BBString *x,BBString *y ){ + int k,n,sz; + sz=x->lengthlength ? x->length : y->length; + for( k=0;kbuf[k]-y->buf[k] ) return n; + return x->length-y->length; +} + +int bbStringStartsWith( BBString *x,BBString *y ){ + BBChar *p,*q; + int k,sz=y->length; + if( x->lengthbuf; + q=y->buf; + for( k=0;klength; + if( x->lengthbuf+x->length-sz; + q=y->buf; + for( k=0;klength+y->length; + BBString *t=bbStringNew(len); + memcpy( t->buf,x->buf,x->length*sizeof(BBChar) ); + memcpy( t->buf+x->length,y->buf,y->length*sizeof(BBChar) ); + return t; +} + +BBString *bbStringSlice( BBString *in,int beg,int end ){ + BBChar *p; + BBString *out; + int k,n,len,inlen; + + len=end-beg; + if( len<=0 ) return &bbEmptyString; + + out=bbStringNew( len ); + + p=out->buf; + inlen=in->length; + + if( (n=-beg)>0 ){ + if( beg+n>end ) n=end-beg; + for( k=0;k0 ){ + BBChar *q=in->buf+beg; + if( beg+n>end ) n=end-beg; + for( k=0;k0 ){ + for( k=0;klength; + while( bbuf[b]<=' ' ) ++b; + if( b==e ) return &bbEmptyString; + while( str->buf[e-1]<=' ' ) --e; + if( e-b==str->length ) return str; + return bbStringFromShorts( str->buf+b,e-b ); +} + +BBString *bbStringReplace( BBString *str,BBString *sub,BBString *rep ){ + int i,d,n,j,p; + if( !sub->length ) return str; + i=0;n=0; + while( (i=bbStringFind(str,sub,i))!=-1 ) {i+=sub->length;n++;} + if (!n) return str; + d=rep->length-sub->length; + BBString *t=bbStringNew( str->length+d*n ); + i=0;p=0; + while( (j=bbStringFind(str,sub,i))!=-1 ) + { + n=j-i;if (n) {memcpy( t->buf+p,str->buf+i,n*sizeof(BBChar) );p+=n;} + n=rep->length;memcpy( t->buf+p,rep->buf,n*sizeof(BBChar) );p+=n; + i=j+sub->length; + } + n=str->length-i; + if (n) memcpy( t->buf+p,str->buf+i,n*sizeof(BBChar) ); + return t; +} + +int bbStringAsc( BBString *t ){ + return t->length ? t->buf[0] : -1; +} + +int bbStringFind( BBString *x,BBString *y,int i ){ + if( i<0 ) i=0; + while( i+y->length<=x->length ){ + if( charsEqual( x->buf+i,y->buf,y->length ) ) return i; + ++i; + } + return -1; +} + +int bbStringFindLast( BBString *x,BBString *y,int i ){ + bbassert( i>=0 ); + i=x->length-i; + if (i+y->length>x->length) i=x->length-y->length; + while (i>=0) + { + if( charsEqual( x->buf+i,y->buf,y->length ) ) return i; + --i; + } + return -1; +} + +int bbStringToInt( BBString *t ){ + int i=0,neg=0,n=0; + + while( ilength && isspace(t->buf[i]) ) ++i; + if( i==t->length ) return 0; + + if( t->buf[i]=='+' ) ++i; + else if( neg=(t->buf[i]=='-') ) ++i; + if( i==t->length ) return 0; + + if( t->buf[i]=='%' ){ + for( ++i;ilength;++i ){ + int c=t->buf[i]; + if( c!='0' && c!='1' ) break; + n=n*2+(c-'0'); + } + }else if( t->buf[i]=='$' ){ + for( ++i;ilength;++i ){ + int c=toupper(t->buf[i]); + if( !isxdigit(c) ) break; + if( c>='A' ) c-=('A'-'0'-10); + n=n*16+(c-'0'); + } + }else{ + for( ;ilength;++i ){ + int c=t->buf[i]; + if( !isdigit(c) ) break; + n=n*10+(c-'0'); + } + } + return neg ? -n : n; +} + +void bbStringToLong( BBString *t,BBInt64 *r ){ + int i=0,neg=0; + BBInt64 n=0; + + while( ilength && isspace(t->buf[i]) ) ++i; + if( i==t->length ){ *r=0;return; } + + if( t->buf[i]=='+' ) ++i; + else if( neg=(t->buf[i]=='-') ) ++i; + if( i==t->length ){ *r=0;return; } + + if( t->buf[i]=='%' ){ + for( ++i;ilength;++i ){ + int c=t->buf[i]; + if( c!='0' && c!='1' ) break; + n=n*2+(c-'0'); + } + }else if( t->buf[i]=='$' ){ + for( ++i;ilength;++i ){ + int c=toupper(t->buf[i]); + if( !isxdigit(c) ) break; + if( c>='A' ) c-=('A'-'0'-10); + n=n*16+(c-'0'); + } + }else{ + for( ;ilength;++i ){ + int c=t->buf[i]; + if( !isdigit(c) ) break; + n=n*10+(c-'0'); + } + } + *r=neg ? -n : n; +} + +float bbStringToFloat( BBString *t ){ + char *p=bbStringToCString( t ); + float n=atof( p ); + bbMemFree( p ); + return n; +} + +double bbStringToDouble( BBString *t ){ + char *p=bbStringToCString( t ); + double n=atof( p ); + bbMemFree( p ); + return n; +} + +BBString *bbStringToLower( BBString *str ){ + int k; + BBString *t; + t=bbStringNew( str->length ); + for( k=0;klength;++k ){ + int c=str->buf[k]; + if( c<192 ){ + c=(c>='A' && c<='Z') ? (c|32) : c; + }else{ + int lo=0,hi=sizeof(bbToLowerData)/4-1; + while( lo<=hi ){ + int mid=(lo+hi)/2; + if( cbbToLowerData[mid*2] ){ + lo=mid+1; + }else{ + c=bbToLowerData[mid*2+1]; + break; + } + } + } + t->buf[k]=c; + } + return t; +} + +BBString *bbStringToUpper( BBString *str ){ + int k; + BBString *t; + t=bbStringNew( str->length ); + for( k=0;klength;++k ){ + int c=str->buf[k]; + if( c<181 ){ + c=(c>='a' && c<='z') ? (c&~32) : c; + }else{ + int lo=0,hi=sizeof(bbToUpperData)/4-1; + while( lo<=hi ){ + int mid=(lo+hi)/2; + if( cbbToUpperData[mid*2] ){ + lo=mid+1; + }else{ + c=bbToUpperData[mid*2+1]; + break; + } + } + } + t->buf[k]=c; + } + return t; +} + +char *bbStringToCString( BBString *str ){ + char *p; + int k,sz=str->length; + p=(char*)bbMemAlloc( sz+1 ); + for( k=0;kbuf[k]; + p[sz]=0; + return p; +} + +BBChar *bbStringToWString( BBString *str ){ + BBChar *p; + int k,sz=str->length; + p=(BBChar*)bbMemAlloc( (sz+1)*sizeof(BBChar) ); + memcpy(p,str->buf,sz*sizeof(BBChar)); + p[sz]=0; + return p; +} + +char *bbStringToUTF8String( BBString *str ){ + int i,len=str->length; + char *buf=(char*)bbMemAlloc( len*3+1 ); + char *q=buf; + unsigned short *p=str->buf; + for( i=0;i>6); + *q++=0x80|(c&0x3f); + }else{ + *q++=0xe0|(c>>12); + *q++=0x80|((c>>6)&0x3f); + *q++=0x80|(c&0x3f); + } + } + *q=0; + return buf; +} + +BBArray *bbStringSplit( BBString *str,BBString *sep ){ + int i,i2,n; + BBString **p,*bit; + BBArray *bits; + + if( sep->length ){ + i=0;n=1; + while( (i2=bbStringFind( str,sep,i ))!=-1 ){ + ++n; + i=i2+sep->length; + } + + bits=bbArrayNew1D( "$",n ); + p=(BBString**)BBARRAYDATA( bits,1 ); + + i=0; + while( n-- ){ + i2=bbStringFind( str,sep,i ); + if( i2==-1 ) i2=str->length; + bit=bbStringSlice( str,i,i2 ); + BBINCREFS( bit ); + *p++=bit; + i=i2+sep->length; + } + return bits; + } + + i=0;n=0; + for(;;){ + while( i!=str->length && str->buf[i]<33 ) ++i; + if( i++==str->length ) break; + while( i!=str->length && str->buf[i]>32 ) ++i; + ++n; + } + if( !n ) return &bbEmptyArray; + + bits=bbArrayNew1D( "$",n ); + p=(BBString**)BBARRAYDATA( bits,1 ); + + i=0; + while( n-- ){ + while( str->buf[i]<33 ) ++i; + i2=i++; + while( i!=str->length && str->buf[i]>32 ) ++i; + bit=bbStringSlice( str,i2,i ); + BBINCREFS( bit ); + *p++=bit; + } + return bits; +} + +BBString *bbStringJoin( BBString *sep,BBArray *bits ){ + int i,sz=0; + int n_bits=bits->scales[0]; + BBString **p,*str; + BBChar *t; + + if( bits==&bbEmptyArray ){ + return &bbEmptyString; + } + + p=(BBString**)BBARRAYDATA( bits,1 ); + for( i=0;ilength; + } + + sz+=(n_bits-1)*sep->length; + str=bbStringNew( sz ); + t=str->buf; + + p=(BBString**)BBARRAYDATA( bits,1 ); + for( i=0;ibuf,sep->length*sizeof(BBChar) ); + t+=sep->length; + } + BBString *bit=*p++; + memcpy( t,bit->buf,bit->length*sizeof(BBChar) ); + t+=bit->length; + } + + return str; +} + +static void mktmp( void *p ){ + static int i; + static void *bufs[32]; + int n=bbAtomicAdd( &i,1 ) & 31; + bbMemFree( bufs[n] ); + bufs[n]=p; +} + +char *bbTmpCString( BBString *str ){ + char *p=bbStringToCString( str ); + mktmp( p ); + return p; +} + +BBChar *bbTmpWString( BBString *str ){ + BBChar *p=bbStringToWString( str ); + mktmp( p ); + return p; +} + +char *bbTmpUTF8String( BBString *str ){ + char *p=bbStringToUTF8String( str ); + mktmp( p ); + return p; +} diff --git a/mod/brl.mod/blitz.mod/blitz_string.h b/mod/brl.mod/blitz.mod/blitz_string.h new file mode 100644 index 0000000..0a59076 --- /dev/null +++ b/mod/brl.mod/blitz.mod/blitz_string.h @@ -0,0 +1,75 @@ + +#ifndef BLITZ_STRING_H +#define BLITZ_STRING_H + +#include "blitz_types.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +#define BBNULLSTRING (&bbEmptyString) + +struct BBString{ + BBClass* clas; + int refs; + int length; + BBChar buf[]; +}; + +extern BBClass bbStringClass; +extern BBString bbEmptyString; + +BBString*bbStringNew( int len ); +BBString*bbStringFromChar( int c ); + +BBString*bbStringFromInt( int n ); +BBString* bbStringFromLong( BBInt64 n ); +BBString*bbStringFromFloat( float n ); +BBString* bbStringFromDouble( double n ); +BBString* bbStringFromBytes( const char *p,int n ); +BBString* bbStringFromShorts( const unsigned short *p,int n ); +BBString* bbStringFromInts( const int *p,int n ); +BBString*bbStringFromArray( BBArray *arr ); +BBString* bbStringFromCString( const char *p ); +BBString*bbStringFromWString( const BBChar *p ); +BBString*bbStringFromUTF8String( const char *p ); + +BBString* bbStringToString( BBString *t ); +int bbStringCompare( BBString *x,BBString *y ); +int bbStringStartsWith( BBString *x,BBString *y ); +int bbStringEndsWith( BBString *x,BBString *y ); +int bbStringContains( BBString *x,BBString *y ); + +BBString*bbStringConcat( BBString *x,BBString *y ); + +BBString* bbStringTrim( BBString *t ); +BBString* bbStringSlice( BBString *t,int beg,int end ); +BBString* bbStringReplace( BBString *str,BBString *sub,BBString *rep ); + +int bbStringAsc( BBString *t ); +int bbStringFind( BBString *x,BBString *y,int i ); +int bbStringFindLast( BBString *x,BBString *y,int i ); +BBString* bbStringToLower( BBString *str ); +BBString* bbStringToUpper( BBString *str ); + +int bbStringToInt( BBString *str ); +float bbStringToFloat( BBString *str ); +double bbStringToDouble( BBString *str ); +void bbStringToLong( BBString *str,BBInt64 *r ); +char* bbStringToCString( BBString *str ); +BBChar* bbStringToWString( BBString *str ); +char* bbStringToUTF8String( BBString *str ); + +BBArray* bbStringSplit( BBString *str,BBString *sep ); +BBString* bbStringJoin( BBString *sep,BBArray *bits ); + +char* bbTmpCString( BBString *str ); +BBChar* bbTmpWString( BBString *str ); +char* bbTmpUTF8String( BBString *str ); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/mod/brl.mod/blitz.mod/blitz_thread.c b/mod/brl.mod/blitz.mod/blitz_thread.c new file mode 100644 index 0000000..0ac8b68 --- /dev/null +++ b/mod/brl.mod/blitz.mod/blitz_thread.c @@ -0,0 +1,463 @@ + +#include "blitz.h" + +//#define DEBUG_THREADS + +//***** Common ***** + +int _bbNeedsLock; +bb_mutex_t _bbLock; + +static int threadDataId; + +static BBThread *threads; +static BBThread *deadThreads; + +static BBThread *mainThread; + +static void flushDeadThreads(){ + BBThread **p=&deadThreads,*t; + while( t=*p ){ + if( t->detached ){ + *p=t->succ; +#ifdef _WIN32 + CloseHandle( t->handle ); +#endif + free( t ); + }else{ + p=&t->succ; + } + } +} + +static void addThread( BBThread *thread ){ + flushDeadThreads(); + thread->succ=threads; + threads=thread; +} + +static void removeThread( BBThread *thread ){ + BBThread **p=&threads,*t; + while( t=*p ){ + if( t==thread ){ + *p=t->succ; + if( t->detached ){ +#ifdef _WIN32 + CloseHandle( t->handle ); +#endif + free( t ); + }else{ + t->succ=deadThreads; + deadThreads=t; + } + break; + }else{ + p=&t->succ; + } + } +} + +int bbThreadAllocData(){ + if( threadDataId<31 ) return ++threadDataId; + return 0; +} + +void bbThreadSetData( int index,BBObject *data ){ + bbThreadGetCurrent()->data[index]=data; +} + +BBObject *bbThreadGetData( int index ){ + BBObject *data=bbThreadGetCurrent()->data[index]; + return data ? data : &bbNullObject; +} + +//***** Windows threads ***** +#ifdef _WIN32 + +static DWORD curThreadTls; + +static DWORD WINAPI threadProc( void *p ){ + BBThread *thread=p; + + TlsSetValue( curThreadTls,thread ); + + DWORD ret=(DWORD)thread->proc( thread->data[0] ); + + BB_LOCK + removeThread( thread ); + BB_UNLOCK + + return ret; +} + +void bbThreadStartup(){ + + if( bb_mutex_init( &_bbLock )<0 ) exit(-1); + + curThreadTls=TlsAlloc(); + + BBThread *thread=malloc( sizeof( BBThread ) ); + + thread->proc=0; + memset( thread->data,0,sizeof(thread->data) ); + thread->detached=0; + thread->stackTop=bbGCStackTop; + thread->id=GetCurrentThreadId(); + if( !DuplicateHandle( GetCurrentProcess(),GetCurrentThread(),GetCurrentProcess(),&thread->handle,0,FALSE,DUPLICATE_SAME_ACCESS ) ){ + exit( -1 ); + } + + TlsSetValue( curThreadTls,thread ); + + thread->succ=threads; + threads=thread; + mainThread=thread; +} + +BBThread *bbThreadCreate( BBThreadProc proc,BBObject *data ){ + BBThread *thread=malloc( sizeof( BBThread ) ); + + thread->proc=proc; + memset( thread->data,0,sizeof(thread->data) ); + thread->data[0]=data; + thread->detached=0; + thread->handle=CreateThread( 0,0,threadProc,thread,CREATE_SUSPENDED,&thread->id ); + + CONTEXT ctx={CONTEXT_CONTROL}; + GetThreadContext( thread->handle,&ctx ); + thread->stackTop=ctx.Esp; + + BB_LOCK + addThread( thread ); + BB_UNLOCK + + _bbNeedsLock=1; + + return thread; +} + +void bbThreadDetach( BBThread *thread ){ + thread->detached=1; +} + +BBObject *bbThreadWait( BBThread *thread ){ + if( WaitForSingleObject( thread->handle,INFINITE )==WAIT_OBJECT_0 ){ + BBObject *p; + if( GetExitCodeThread( thread->handle,(DWORD*)&p ) ){ + thread->detached=1; + return p; + }else{ + printf( "ERROR! bbThreadWait: GetExitCodeThread failed!\n" ); + } + }else{ + printf( "ERROR! bbThreadWait: WaitForSingleObject failed!\n" ); + } + printf( "LastError=%i\n",GetLastError() ); + + return &bbNullObject; +} + +BBThread *bbThreadGetMain(){ + return mainThread; +} + +BBThread *bbThreadGetCurrent(){ + return TlsGetValue( curThreadTls ); +} + +int bbThreadSuspend( BBThread *thread ){ + return SuspendThread( thread->handle ); +} + +int bbThreadResume( BBThread *thread ){ + return ResumeThread( thread->handle ); +} + +BBThread *_bbThreadLockThreads(){ + BBThread *curThread=bbThreadGetCurrent(); + BBThread *t; + for( t=threads;t;t=t->succ ){ + if( t!=curThread ){ + SuspendThread( t->handle ); + CONTEXT ctx={CONTEXT_INTEGER|CONTEXT_CONTROL}; + GetThreadContext( t->handle,&ctx ); + t->locked_regs[0]=ctx.Edi; + t->locked_regs[1]=ctx.Esi; + t->locked_regs[2]=ctx.Ebx; + t->locked_regs[3]=ctx.Edx; + t->locked_regs[4]=ctx.Ecx; + t->locked_regs[5]=ctx.Eax; + t->locked_regs[6]=ctx.Ebp; + t->locked_sp=ctx.Esp; + } + } + return threads; +} + +void _bbThreadUnlockThreads(){ + BBThread *curThread=bbThreadGetCurrent(); + BBThread *t; + for( t=threads;t;t=t->succ ){ + if( t!=curThread ){ + ResumeThread( t->handle ); + } + } +} + +//***** POSIX threads ***** +#else + +#include +#include + +#if __linux +#define MUTEX_RECURSIVE 1 +#elif __APPLE__ +#define MUTEX_RECURSIVE 2 +#endif + +pthread_mutexattr_t _bb_mutexattr; + +static BBThread *threads; +static pthread_key_t curThreadTls; + +static void suspendSigHandler( int sig ){//,siginfo_t *info,ucontext_t *ctx ){ + BBThread *thread=pthread_getspecific( curThreadTls ); + + thread->locked_sp=bbGCRootRegs( thread->locked_regs ); + +#ifdef DEBUG_THREADS + printf( "In suspendSigHandler! thread=%p locked_sp=%p\n",thread,thread->locked_sp );fflush( stdout ); +#endif + + bb_sem_post( &thread->acksema ); + + //wait for resume - apparently very naughty! + bb_sem_wait( &thread->runsema ); + +#ifdef DEBUG_THREADS + printf( "Got resume!\n" );fflush( stdout ); +#endif +} + +void bbThreadStartup(){ + + if( pthread_mutexattr_init( &_bb_mutexattr )<0 ) exit(-1); + if( pthread_mutexattr_settype( &_bb_mutexattr,MUTEX_RECURSIVE )<0 ) exit(-1); + + if( pthread_key_create( &curThreadTls,0 )<0 ) exit(-1); + + if( bb_mutex_init( &_bbLock )<0 ) exit(-1); + + struct sigaction act; + memset( &act,0,sizeof(act) ); + act.sa_handler=suspendSigHandler; + act.sa_flags=SA_RESTART; + + if( sigaction( SIGUSR2,&act,0 )<0 ) exit(-1); + + BBThread *thread=malloc( sizeof( BBThread ) ); + memset( thread->data,0,sizeof(thread->data) ); + + thread->proc=0; + thread->detached=0; + thread->suspended=0; + thread->handle=pthread_self(); + if( !bb_sem_init( &thread->runsema,0 ) ) exit(-1); + if( !bb_sem_init( &thread->acksema,0 ) ) exit(-1); + + thread->stackTop=bbGCStackTop; + pthread_setspecific( curThreadTls,thread ); + + thread->succ=threads; + threads=thread; + mainThread=thread; +} + +static void *threadProc( void *p ){ + BBThread *thread=p; + + thread->stackTop=bbGCRootRegs( thread->locked_regs ); + pthread_setspecific( curThreadTls,thread ); + + BB_LOCK + addThread( thread ); + BB_UNLOCK + + bb_sem_post( &thread->acksema ); + bb_sem_wait( &thread->runsema ); + +#ifdef DEBUG_THREADS + printf( "Thread %p added, stackTop=%p\n",thread,thread->stackTop );fflush( stdout ); +#endif + + void *ret=thread->proc( thread->data[0] ); + + BB_LOCK + removeThread( thread ); + BB_UNLOCK + + bb_sem_destroy( &thread->runsema ); + bb_sem_destroy( &thread->acksema ); + +#ifdef DEBUG_THREADS + printf( "Thread %p removed\n",thread );fflush( stdout ); +#endif + + return ret; +} + +BBThread *bbThreadCreate( BBThreadProc proc,BBObject *data ){ + BBThread *thread=malloc( sizeof( BBThread ) ); + memset( thread->data,0,sizeof(thread->data) ); + + thread->proc=proc; + thread->data[0]=data; + thread->detached=0; + thread->suspended=1; + if( bb_sem_init( &thread->runsema,0 ) ){ + if( bb_sem_init( &thread->acksema,0 ) ){ + if( pthread_create( &thread->handle,0,threadProc,thread )>=0 ){ + bb_sem_wait( &thread->acksema ); + _bbNeedsLock=1; + return thread; + } + bb_sem_destroy( &thread->acksema ); + } + bb_sem_destroy( &thread->runsema ); + } + free( thread ); + return 0; +} + +void bbThreadDetach( BBThread *thread ){ + thread->detached=1; + pthread_detach( thread->handle ); +} + +BBObject *bbThreadWait( BBThread *thread ){ + BBObject *p=0; + thread->detached=1; + pthread_join( thread->handle,&p ); + return p; +} + +BBThread *bbThreadGetMain(){ + return mainThread; +} + +BBThread *bbThreadGetCurrent(){ + return pthread_getspecific( curThreadTls ); +} + +int bbThreadSuspend( BBThread *thread ){ + BB_LOCK + + int n=thread->suspended++; + + if( n==0 ){ + pthread_kill( thread->handle,SIGUSR2 ); + bb_sem_wait( &thread->acksema ); + } + + BB_UNLOCK + + return n; +} + +int bbThreadResume( BBThread *thread ){ + BB_LOCK + + int n=thread->suspended--; + + if( n==1 ){ + bb_sem_post( &thread->runsema ); + } + + BB_UNLOCK + + return n; +} + +BBThread *_bbThreadLockThreads(){ + BBThread *curThread=bbThreadGetCurrent(); + BBThread *t; + for( t=threads;t;t=t->succ ){ + if( t!=curThread ){ + if( !t->suspended++ ){ + pthread_kill( t->handle,SIGUSR2 ); + bb_sem_wait( &t->acksema ); + } + } + } + return threads; +} + +void _bbThreadUnlockThreads(){ + BBThread *curThread=bbThreadGetCurrent(); + BBThread *t; + for( t=threads;t;t=t->succ ){ + if( t!=curThread ){ + if( !--t->suspended ){ + bb_sem_post( &t->runsema ); + } + } + } +} + +#endif + +//***** Atomic ops ***** +#if __ppc__ + +int bbAtomicCAS( volatile int *addr,int old,int new_val ){ + int oldval; + int result=0; + + __asm__ __volatile__( + "1:lwarx %0,0,%2\n" /* load and reserve */ + "cmpw %0, %4\n" /* if load is not equal to */ + "bne 2f\n" /* old, fail */ + "stwcx. %3,0,%2\n" /* else store conditional */ + "bne- 1b\n" /* retry if lost reservation */ + "li %1,1\n" /* result = 1; */ + "2:\n" + : "=&r"(oldval), "=&r"(result) + : "r"(addr), "r"(new_val), "r"(old), "1"(result) + : "memory", "cc"); + + return result; +} + +int bbAtomicAdd( volatile int *p,int incr ){ + int old; + for(;;){ + old=*p; + if( bbAtomicCAS( p,old,old+incr ) ) return old; + } +} + +#else + +int bbAtomicCAS( volatile int *addr,int old,int new_val ){ + char result; + + __asm__ __volatile__( + "lock; cmpxchgl %3, %0; setz %1" + : "=m"(*addr), "=q"(result) + : "m"(*addr), "r" (new_val), "a"(old) : "memory"); + + return (int)result; +} + +int bbAtomicAdd( volatile int *p,int incr ){ + int result; + + __asm__ __volatile__ ("lock; xaddl %0, %1" : + "=r" (result), "=m" (*p) : "0" (incr), "m" (*p) + : "memory"); + + return result; +} + +#endif diff --git a/mod/brl.mod/blitz.mod/blitz_thread.h b/mod/brl.mod/blitz.mod/blitz_thread.h new file mode 100644 index 0000000..c40a3b7 --- /dev/null +++ b/mod/brl.mod/blitz.mod/blitz_thread.h @@ -0,0 +1,129 @@ + +#ifndef BLITZ_THREAD_H +#define BLITZ_THREAD_H + +#ifdef _WIN32 + +#include +typedef CRITICAL_SECTION bb_mutex_t; +#define bb_mutex_init(MUTPTR) (InitializeCriticalSection(MUTPTR),1) +#define bb_mutex_destroy(MUTPTR) DeleteCriticalSection(MUTPTR) +#define bb_mutex_lock(MUTPTR) EnterCriticalSection(MUTPTR) +#define bb_mutex_unlock(MUTPTR) LeaveCriticalSection(MUTPTR) +#define bb_mutex_trylock(MUTPTR) (TryEnterCriticalSection(MUTPTR)!=0) + +/* +typedef HANDLE bb_mutex_t; +#define bb_mutex_init(MUTPTR) ((*(MUTPTR)=CreateMutex(0,0,0))!=0) +#define bb_mutex_destroy(MUTPTR) CloseHandle(*(MUTPTR)) +#define bb_mutex_lock(MUTPTR) WaitForSingleObject(*(MUTPTR),INFINITE) +#define bb_mutex_unlock(MUTPTR) ReleaseMutex(*(MUTPTR)) +#define bb_mutex_trylock(MUTPTR) (WaitForSingleObject(*(MUTPTR),0 )==WAIT_OBJECT_0) +*/ + +typedef HANDLE bb_sem_t; +#define bb_sem_init(SEMPTR,COUNT) ((*(SEMPTR)=CreateSemaphore(0,(COUNT),0x7fffffff,0))!=0) +#define bb_sem_destroy(SEMPTR) CloseHandle(*(SEMPTR)) +#define bb_sem_wait(SEMPTR) WaitForSingleObject(*(SEMPTR),INFINITE) +#define bb_sem_post(SEMPTR) ReleaseSemaphore(*(SEMPTR),1,0) + +#else + +#include +typedef pthread_mutex_t bb_mutex_t; +extern pthread_mutexattr_t _bb_mutexattr; +#define bb_mutex_init(MUTPTR) (pthread_mutex_init((MUTPTR),&_bb_mutexattr)>=0) +#define bb_mutex_destroy(MUTPTR) pthread_mutex_destroy(MUTPTR) +#define bb_mutex_lock(MUTPTR) pthread_mutex_lock(MUTPTR) +#define bb_mutex_unlock(MUTPTR) pthread_mutex_unlock(MUTPTR) +#define bb_mutex_trylock(MUTPTR) (pthread_mutex_trylock(MUTPTR)==0) + +#endif + +#ifdef __APPLE__ + +#include +#include +typedef semaphore_t bb_sem_t; +#define bb_sem_init(SEMPTR,COUNT) (semaphore_create( mach_task_self(),(SEMPTR),SYNC_POLICY_FIFO,(COUNT) )>=0) +#define bb_sem_destroy(SEMPTR) semaphore_destroy( mach_task_self(),*(SEMPTR) ) +#define bb_sem_wait(SEMPTR) semaphore_wait( *(SEMPTR) ) +#define bb_sem_post(SEMPTR) semaphore_signal( *(SEMPTR) ) + +#endif + +#ifdef __linux + +#include +typedef sem_t bb_sem_t; +#define bb_sem_init(SEMPTR,COUNT) (sem_init((SEMPTR),0,(COUNT))>=0) +#define bb_sem_destroy sem_destroy +#define bb_sem_wait sem_wait +#define bb_sem_post sem_post + +#endif + +#ifdef _WIN32 +#define BB_THREADREGS 7 //via GetThreadContext() +#elif __ppc__ +#define BB_THREADREGS 19 //via bbGCRootRegs() +#else +#define BB_THREADREGS 4 //vid bbGCRootRegs() +#endif + +#include "blitz_types.h" + +typedef BBObject *(*BBThreadProc)( BBObject* ); + +typedef struct BBThread BBThread; + +struct BBThread{ + BBThread *succ; + BBThreadProc proc; + void *data[32]; + int detached; + void *stackTop; + void *locked_sp; + int locked_regs[BB_THREADREGS]; +#ifdef _WIN32 + HANDLE handle; + DWORD id; +#else + pthread_t handle; + int suspended; + bb_sem_t runsema; + bb_sem_t acksema; +#endif +}; + +void bbThreadStartup(); + +BBThread* bbThreadCreate( BBThreadProc entry,BBObject *data ); +void bbThreadDetach( BBThread *thread ); +BBObject* bbThreadWait( BBThread *thread ); + +BBThread* bbThreadGetMain(); +BBThread* bbThreadGetCurrent(); + +int bbThreadSuspend( BBThread *thread ); +int bbThreadResume( BBThread *thread ); + +int bbThreadAllocData(); +void bbThreadSetData( int index,BBObject *data ); +BBObject* bbThreadGetData( int index ); + +//These MUST be inside a BB_LOCK/BB_UNLOCK +BBThread* _bbThreadLockThreads(); +void _bbThreadUnlockThreads(); + +int bbAtomicCAS( volatile int *target,int oldVal,int newVal ); +int bbAtomicAdd( volatile int *target,int incr ); + +//Internal locks... +extern int _bbNeedsLock; +extern bb_mutex_t _bbLock; + +#define BB_LOCK if( _bbNeedsLock ){ bb_mutex_lock( &_bbLock ); } +#define BB_UNLOCK if( _bbNeedsLock ){ bb_mutex_unlock( &_bbLock ); } + +#endif diff --git a/mod/brl.mod/blitz.mod/blitz_types.c b/mod/brl.mod/blitz.mod/blitz_types.c new file mode 100644 index 0000000..bd0d129 --- /dev/null +++ b/mod/brl.mod/blitz.mod/blitz_types.c @@ -0,0 +1,48 @@ + +#include "blitz.h" + +const char *bbVoidTypeTag="?"; +const char *bbByteTypeTag="b"; +const char *bbShortTypeTag="s"; +const char *bbIntTypeTag="i"; +const char *bbFloatTypeTag="f"; +const char *bbDoubleTypeTag="d"; +const char *bbStringTypeTag="$"; +const char *bbObjectTypeTag=":Object"; +const char *bbBytePtrTypeTag="*b"; + +BBINT bbConvertToInt( void *val,const char *tag ){ + switch( tag[0] ){ + case 'b':return *(BBBYTE*)val; + case 's':return *(BBSHORT*)val; + case 'i':return *(BBINT*)val; + case 'f':return *(BBFLOAT*)val; + case 'd':return *(BBDOUBLE*)val; + case '$':return bbStringToInt( *(BBSTRING*)val ); + } + return 0; +} + +BBDOUBLE bbConvertToFloat( void *val,const char *tag ){ + switch( tag[0] ){ + case 'b':return *(BBBYTE*)val; + case 's':return *(BBSHORT*)val; + case 'i':return *(BBINT*)val; + case 'f':return *(BBFLOAT*)val; + case 'd':return *(BBDOUBLE*)val; + case '$':return bbStringToFloat( *(BBSTRING*)val ); + } + return 0; +} + +BBSTRING bbConvertToString( void *val,const char *tag ){ + switch( tag[0] ){ + case 'b':return bbStringFromInt( *(BBBYTE*)val ); + case 's':return bbStringFromInt( *(BBSHORT*)val ); + case 'i':return bbStringFromInt( *(BBINT*)val ); + case 'f':return bbStringFromFloat( *(BBFLOAT*)val ); + case 'd':return bbStringFromFloat( *(BBDOUBLE*)val ); + case '$':return *(BBSTRING*)val; + } + return 0; +} diff --git a/mod/brl.mod/blitz.mod/blitz_types.h b/mod/brl.mod/blitz.mod/blitz_types.h new file mode 100644 index 0000000..5bff85b --- /dev/null +++ b/mod/brl.mod/blitz.mod/blitz_types.h @@ -0,0 +1,50 @@ + +#ifndef BLITZ_TYPES_H +#define BLITZ_TYPES_H + +#ifdef __cplusplus +extern "C"{ +#endif + +#ifdef _MSC_VER + typedef __int64 BBInt64; + typedef unsigned __int64 BBUInt64; +#else + typedef long long BBInt64; + typedef unsigned long long BBUInt64; +#endif + +typedef unsigned short BBChar; + +typedef struct BBClass BBClass; +typedef struct BBObject BBObject; +typedef struct BBString BBString; +typedef struct BBArray BBArray; + +typedef unsigned char BBBYTE; +typedef unsigned short BBSHORT; +typedef signed int BBINT; +typedef BBInt64 BBLONG; +typedef float BBFLOAT; +typedef double BBDOUBLE; +typedef BBClass* BBCLASS; +typedef BBObject* BBOBJECT; +typedef BBString* BBSTRING; +typedef BBArray* BBARRAY; + +extern const char *bbVoidTypeTag; //"?" +extern const char *bbByteTypeTag; //"b" +extern const char *bbShortTypeTag; //"s" +extern const char *bbIntTypeTag; //"i" +extern const char *bbLongTypeTag; //"l" +extern const char *bbFloatTypeTag; //"f" +extern const char *bbDoubleTypeTag; //"d" +extern const char *bbStringTypeTag; //"$" +extern const char *bbObjectTypeTag; //":Object" +extern const char *bbBytePtrTypeTag;//"*b" + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/mod/brl.mod/blitz.mod/blitz_unicode.h b/mod/brl.mod/blitz.mod/blitz_unicode.h new file mode 100644 index 0000000..e039dd6 --- /dev/null +++ b/mod/brl.mod/blitz.mod/blitz_unicode.h @@ -0,0 +1,258 @@ + +#ifndef BLITZ_UNICODE_H +#define BLITZ_UNICODE_H + +unsigned short bbToLowerData[]={ +// 65,97,66,98,67,99,68,100,69,101,70,102,71,103,72,104, +// 73,105,74,106,75,107,76,108,77,109,78,110,79,111,80,112, +// 81,113,82,114,83,115,84,116,85,117,86,118,87,119,88,120, +// 89,121,90,122, + 192,224,193,225,194,226,195,227,196,228,197,229, + 198,230,199,231,200,232,201,233,202,234,203,235,204,236,205,237, + 206,238,207,239,208,240,209,241,210,242,211,243,212,244,213,245, + 214,246,216,248,217,249,218,250,219,251,220,252,221,253,222,254, + 256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271, + 272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287, + 288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303, + 304,105,306,307,308,309,310,311,313,314,315,316,317,318,319,320, + 321,322,323,324,325,326,327,328,330,331,332,333,334,335,336,337, + 338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353, + 354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369, + 370,371,372,373,374,375,376,255,377,378,379,380,381,382,385,595, + 386,387,388,389,390,596,391,392,393,598,394,599,395,396,398,477, + 399,601,400,603,401,402,403,608,404,611,406,617,407,616,408,409, + 412,623,413,626,415,629,416,417,418,419,420,421,422,640,423,424, + 425,643,428,429,430,648,431,432,433,650,434,651,435,436,437,438, + 439,658,440,441,444,445,452,454,453,454,455,457,456,457,458,460, + 459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474, + 475,476,478,479,480,481,482,483,484,485,486,487,488,489,490,491, + 492,493,494,495,497,499,498,499,500,501,502,405,503,447,504,505, + 506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521, + 522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537, + 538,539,540,541,542,543,544,414,546,547,548,549,550,551,552,553, + 554,555,556,557,558,559,560,561,562,563,570,11365,571,572,573,410, + 574,11366,577,578,579,384,580,649,581,652,582,583,584,585,586,587, + 588,589,590,591,880,881,882,883,886,887,902,940,904,941,905,942, + 906,943,908,972,910,973,911,974,913,945,914,946,915,947,916,948, + 917,949,918,950,919,951,920,952,921,953,922,954,923,955,924,956, + 925,957,926,958,927,959,928,960,929,961,931,963,932,964,933,965, + 934,966,935,967,936,968,937,969,938,970,939,971,975,983,984,985, + 986,987,988,989,990,991,992,993,994,995,996,997,998,999,1000,1001, + 1002,1003,1004,1005,1006,1007,1012,952,1015,1016,1017,1010,1018,1019,1021,891, + 1022,892,1023,893,1024,1104,1025,1105,1026,1106,1027,1107,1028,1108,1029,1109, + 1030,1110,1031,1111,1032,1112,1033,1113,1034,1114,1035,1115,1036,1116,1037,1117, + 1038,1118,1039,1119,1040,1072,1041,1073,1042,1074,1043,1075,1044,1076,1045,1077, + 1046,1078,1047,1079,1048,1080,1049,1081,1050,1082,1051,1083,1052,1084,1053,1085, + 1054,1086,1055,1087,1056,1088,1057,1089,1058,1090,1059,1091,1060,1092,1061,1093, + 1062,1094,1063,1095,1064,1096,1065,1097,1066,1098,1067,1099,1068,1100,1069,1101, + 1070,1102,1071,1103,1120,1121,1122,1123,1124,1125,1126,1127,1128,1129,1130,1131, + 1132,1133,1134,1135,1136,1137,1138,1139,1140,1141,1142,1143,1144,1145,1146,1147, + 1148,1149,1150,1151,1152,1153,1162,1163,1164,1165,1166,1167,1168,1169,1170,1171, + 1172,1173,1174,1175,1176,1177,1178,1179,1180,1181,1182,1183,1184,1185,1186,1187, + 1188,1189,1190,1191,1192,1193,1194,1195,1196,1197,1198,1199,1200,1201,1202,1203, + 1204,1205,1206,1207,1208,1209,1210,1211,1212,1213,1214,1215,1216,1231,1217,1218, + 1219,1220,1221,1222,1223,1224,1225,1226,1227,1228,1229,1230,1232,1233,1234,1235, + 1236,1237,1238,1239,1240,1241,1242,1243,1244,1245,1246,1247,1248,1249,1250,1251, + 1252,1253,1254,1255,1256,1257,1258,1259,1260,1261,1262,1263,1264,1265,1266,1267, + 1268,1269,1270,1271,1272,1273,1274,1275,1276,1277,1278,1279,1280,1281,1282,1283, + 1284,1285,1286,1287,1288,1289,1290,1291,1292,1293,1294,1295,1296,1297,1298,1299, + 1300,1301,1302,1303,1304,1305,1306,1307,1308,1309,1310,1311,1312,1313,1314,1315, + 1329,1377,1330,1378,1331,1379,1332,1380,1333,1381,1334,1382,1335,1383,1336,1384, + 1337,1385,1338,1386,1339,1387,1340,1388,1341,1389,1342,1390,1343,1391,1344,1392, + 1345,1393,1346,1394,1347,1395,1348,1396,1349,1397,1350,1398,1351,1399,1352,1400, + 1353,1401,1354,1402,1355,1403,1356,1404,1357,1405,1358,1406,1359,1407,1360,1408, + 1361,1409,1362,1410,1363,1411,1364,1412,1365,1413,1366,1414,4256,11520,4257,11521, + 4258,11522,4259,11523,4260,11524,4261,11525,4262,11526,4263,11527,4264,11528,4265,11529, + 4266,11530,4267,11531,4268,11532,4269,11533,4270,11534,4271,11535,4272,11536,4273,11537, + 4274,11538,4275,11539,4276,11540,4277,11541,4278,11542,4279,11543,4280,11544,4281,11545, + 4282,11546,4283,11547,4284,11548,4285,11549,4286,11550,4287,11551,4288,11552,4289,11553, + 4290,11554,4291,11555,4292,11556,4293,11557,7680,7681,7682,7683,7684,7685,7686,7687, + 7688,7689,7690,7691,7692,7693,7694,7695,7696,7697,7698,7699,7700,7701,7702,7703, + 7704,7705,7706,7707,7708,7709,7710,7711,7712,7713,7714,7715,7716,7717,7718,7719, + 7720,7721,7722,7723,7724,7725,7726,7727,7728,7729,7730,7731,7732,7733,7734,7735, + 7736,7737,7738,7739,7740,7741,7742,7743,7744,7745,7746,7747,7748,7749,7750,7751, + 7752,7753,7754,7755,7756,7757,7758,7759,7760,7761,7762,7763,7764,7765,7766,7767, + 7768,7769,7770,7771,7772,7773,7774,7775,7776,7777,7778,7779,7780,7781,7782,7783, + 7784,7785,7786,7787,7788,7789,7790,7791,7792,7793,7794,7795,7796,7797,7798,7799, + 7800,7801,7802,7803,7804,7805,7806,7807,7808,7809,7810,7811,7812,7813,7814,7815, + 7816,7817,7818,7819,7820,7821,7822,7823,7824,7825,7826,7827,7828,7829,7838,223, + 7840,7841,7842,7843,7844,7845,7846,7847,7848,7849,7850,7851,7852,7853,7854,7855, + 7856,7857,7858,7859,7860,7861,7862,7863,7864,7865,7866,7867,7868,7869,7870,7871, + 7872,7873,7874,7875,7876,7877,7878,7879,7880,7881,7882,7883,7884,7885,7886,7887, + 7888,7889,7890,7891,7892,7893,7894,7895,7896,7897,7898,7899,7900,7901,7902,7903, + 7904,7905,7906,7907,7908,7909,7910,7911,7912,7913,7914,7915,7916,7917,7918,7919, + 7920,7921,7922,7923,7924,7925,7926,7927,7928,7929,7930,7931,7932,7933,7934,7935, + 7944,7936,7945,7937,7946,7938,7947,7939,7948,7940,7949,7941,7950,7942,7951,7943, + 7960,7952,7961,7953,7962,7954,7963,7955,7964,7956,7965,7957,7976,7968,7977,7969, + 7978,7970,7979,7971,7980,7972,7981,7973,7982,7974,7983,7975,7992,7984,7993,7985, + 7994,7986,7995,7987,7996,7988,7997,7989,7998,7990,7999,7991,8008,8000,8009,8001, + 8010,8002,8011,8003,8012,8004,8013,8005,8025,8017,8027,8019,8029,8021,8031,8023, + 8040,8032,8041,8033,8042,8034,8043,8035,8044,8036,8045,8037,8046,8038,8047,8039, + 8072,8064,8073,8065,8074,8066,8075,8067,8076,8068,8077,8069,8078,8070,8079,8071, + 8088,8080,8089,8081,8090,8082,8091,8083,8092,8084,8093,8085,8094,8086,8095,8087, + 8104,8096,8105,8097,8106,8098,8107,8099,8108,8100,8109,8101,8110,8102,8111,8103, + 8120,8112,8121,8113,8122,8048,8123,8049,8124,8115,8136,8050,8137,8051,8138,8052, + 8139,8053,8140,8131,8152,8144,8153,8145,8154,8054,8155,8055,8168,8160,8169,8161, + 8170,8058,8171,8059,8172,8165,8184,8056,8185,8057,8186,8060,8187,8061,8188,8179, + 8486,969,8490,107,8491,229,8498,8526,8544,8560,8545,8561,8546,8562,8547,8563, + 8548,8564,8549,8565,8550,8566,8551,8567,8552,8568,8553,8569,8554,8570,8555,8571, + 8556,8572,8557,8573,8558,8574,8559,8575,8579,8580,9398,9424,9399,9425,9400,9426, + 9401,9427,9402,9428,9403,9429,9404,9430,9405,9431,9406,9432,9407,9433,9408,9434, + 9409,9435,9410,9436,9411,9437,9412,9438,9413,9439,9414,9440,9415,9441,9416,9442, + 9417,9443,9418,9444,9419,9445,9420,9446,9421,9447,9422,9448,9423,9449,11264,11312, + 11265,11313,11266,11314,11267,11315,11268,11316,11269,11317,11270,11318,11271,11319,11272,11320, + 11273,11321,11274,11322,11275,11323,11276,11324,11277,11325,11278,11326,11279,11327,11280,11328, + 11281,11329,11282,11330,11283,11331,11284,11332,11285,11333,11286,11334,11287,11335,11288,11336, + 11289,11337,11290,11338,11291,11339,11292,11340,11293,11341,11294,11342,11295,11343,11296,11344, + 11297,11345,11298,11346,11299,11347,11300,11348,11301,11349,11302,11350,11303,11351,11304,11352, + 11305,11353,11306,11354,11307,11355,11308,11356,11309,11357,11310,11358,11360,11361,11362,619, + 11363,7549,11364,637,11367,11368,11369,11370,11371,11372,11373,593,11374,625,11375,592, + 11378,11379,11381,11382,11392,11393,11394,11395,11396,11397,11398,11399,11400,11401,11402,11403, + 11404,11405,11406,11407,11408,11409,11410,11411,11412,11413,11414,11415,11416,11417,11418,11419, + 11420,11421,11422,11423,11424,11425,11426,11427,11428,11429,11430,11431,11432,11433,11434,11435, + 11436,11437,11438,11439,11440,11441,11442,11443,11444,11445,11446,11447,11448,11449,11450,11451, + 11452,11453,11454,11455,11456,11457,11458,11459,11460,11461,11462,11463,11464,11465,11466,11467, + 11468,11469,11470,11471,11472,11473,11474,11475,11476,11477,11478,11479,11480,11481,11482,11483, + 11484,11485,11486,11487,11488,11489,11490,11491,42560,42561,42562,42563,42564,42565,42566,42567, + 42568,42569,42570,42571,42572,42573,42574,42575,42576,42577,42578,42579,42580,42581,42582,42583, + 42584,42585,42586,42587,42588,42589,42590,42591,42594,42595,42596,42597,42598,42599,42600,42601, + 42602,42603,42604,42605,42624,42625,42626,42627,42628,42629,42630,42631,42632,42633,42634,42635, + 42636,42637,42638,42639,42640,42641,42642,42643,42644,42645,42646,42647,42786,42787,42788,42789, + 42790,42791,42792,42793,42794,42795,42796,42797,42798,42799,42802,42803,42804,42805,42806,42807, + 42808,42809,42810,42811,42812,42813,42814,42815,42816,42817,42818,42819,42820,42821,42822,42823, + 42824,42825,42826,42827,42828,42829,42830,42831,42832,42833,42834,42835,42836,42837,42838,42839, + 42840,42841,42842,42843,42844,42845,42846,42847,42848,42849,42850,42851,42852,42853,42854,42855, + 42856,42857,42858,42859,42860,42861,42862,42863,42873,42874,42875,42876,42877,7545,42878,42879, + 42880,42881,42882,42883,42884,42885,42886,42887,42891,42892,65313,65345,65314,65346,65315,65347, + 65316,65348,65317,65349,65318,65350,65319,65351,65320,65352,65321,65353,65322,65354,65323,65355, + 65324,65356,65325,65357,65326,65358,65327,65359,65328,65360,65329,65361,65330,65362,65331,65363, + 65332,65364,65333,65365,65334,65366,65335,65367,65336,65368,65337,65369,65338,65370 }; + +unsigned short bbToUpperData[]={ +// 97,65,98,66,99,67,100,68,101,69,102,70,103,71,104,72, +// 105,73,106,74,107,75,108,76,109,77,110,78,111,79,112,80, +// 113,81,114,82,115,83,116,84,117,85,118,86,119,87,120,88, +// 121,89,122,90, + 181,924,224,192,225,193,226,194,227,195,228,196, + 229,197,230,198,231,199,232,200,233,201,234,202,235,203,236,204, + 237,205,238,206,239,207,240,208,241,209,242,210,243,211,244,212, + 245,213,246,214,248,216,249,217,250,218,251,219,252,220,253,221, + 254,222,255,376,257,256,259,258,261,260,263,262,265,264,267,266, + 269,268,271,270,273,272,275,274,277,276,279,278,281,280,283,282, + 285,284,287,286,289,288,291,290,293,292,295,294,297,296,299,298, + 301,300,303,302,305,73,307,306,309,308,311,310,314,313,316,315, + 318,317,320,319,322,321,324,323,326,325,328,327,331,330,333,332, + 335,334,337,336,339,338,341,340,343,342,345,344,347,346,349,348, + 351,350,353,352,355,354,357,356,359,358,361,360,363,362,365,364, + 367,366,369,368,371,370,373,372,375,374,378,377,380,379,382,381, + 383,83,384,579,387,386,389,388,392,391,396,395,402,401,405,502, + 409,408,410,573,414,544,417,416,419,418,421,420,424,423,429,428, + 432,431,436,435,438,437,441,440,445,444,447,503,452,453,454,453, + 455,456,457,456,458,459,460,459,462,461,464,463,466,465,468,467, + 470,469,472,471,474,473,476,475,477,398,479,478,481,480,483,482, + 485,484,487,486,489,488,491,490,493,492,495,494,497,498,499,498, + 501,500,505,504,507,506,509,508,511,510,513,512,515,514,517,516, + 519,518,521,520,523,522,525,524,527,526,529,528,531,530,533,532, + 535,534,537,536,539,538,541,540,543,542,547,546,549,548,551,550, + 553,552,555,554,557,556,559,558,561,560,563,562,572,571,578,577, + 583,582,585,584,587,586,589,588,591,590,592,11375,593,11373,595,385, + 596,390,598,393,599,394,601,399,603,400,608,403,611,404,616,407, + 617,406,619,11362,623,412,625,11374,626,413,629,415,637,11364,640,422, + 643,425,648,430,649,580,650,433,651,434,652,581,658,439,837,921, + 881,880,883,882,887,886,891,1021,892,1022,893,1023,940,902,941,904, + 942,905,943,906,945,913,946,914,947,915,948,916,949,917,950,918, + 951,919,952,920,953,921,954,922,955,923,956,924,957,925,958,926, + 959,927,960,928,961,929,962,931,963,931,964,932,965,933,966,934, + 967,935,968,936,969,937,970,938,971,939,972,908,973,910,974,911, + 976,914,977,920,981,934,982,928,983,975,985,984,987,986,989,988, + 991,990,993,992,995,994,997,996,999,998,1001,1000,1003,1002,1005,1004, + 1007,1006,1008,922,1009,929,1010,1017,1013,917,1016,1015,1019,1018,1072,1040, + 1073,1041,1074,1042,1075,1043,1076,1044,1077,1045,1078,1046,1079,1047,1080,1048, + 1081,1049,1082,1050,1083,1051,1084,1052,1085,1053,1086,1054,1087,1055,1088,1056, + 1089,1057,1090,1058,1091,1059,1092,1060,1093,1061,1094,1062,1095,1063,1096,1064, + 1097,1065,1098,1066,1099,1067,1100,1068,1101,1069,1102,1070,1103,1071,1104,1024, + 1105,1025,1106,1026,1107,1027,1108,1028,1109,1029,1110,1030,1111,1031,1112,1032, + 1113,1033,1114,1034,1115,1035,1116,1036,1117,1037,1118,1038,1119,1039,1121,1120, + 1123,1122,1125,1124,1127,1126,1129,1128,1131,1130,1133,1132,1135,1134,1137,1136, + 1139,1138,1141,1140,1143,1142,1145,1144,1147,1146,1149,1148,1151,1150,1153,1152, + 1163,1162,1165,1164,1167,1166,1169,1168,1171,1170,1173,1172,1175,1174,1177,1176, + 1179,1178,1181,1180,1183,1182,1185,1184,1187,1186,1189,1188,1191,1190,1193,1192, + 1195,1194,1197,1196,1199,1198,1201,1200,1203,1202,1205,1204,1207,1206,1209,1208, + 1211,1210,1213,1212,1215,1214,1218,1217,1220,1219,1222,1221,1224,1223,1226,1225, + 1228,1227,1230,1229,1231,1216,1233,1232,1235,1234,1237,1236,1239,1238,1241,1240, + 1243,1242,1245,1244,1247,1246,1249,1248,1251,1250,1253,1252,1255,1254,1257,1256, + 1259,1258,1261,1260,1263,1262,1265,1264,1267,1266,1269,1268,1271,1270,1273,1272, + 1275,1274,1277,1276,1279,1278,1281,1280,1283,1282,1285,1284,1287,1286,1289,1288, + 1291,1290,1293,1292,1295,1294,1297,1296,1299,1298,1301,1300,1303,1302,1305,1304, + 1307,1306,1309,1308,1311,1310,1313,1312,1315,1314,1377,1329,1378,1330,1379,1331, + 1380,1332,1381,1333,1382,1334,1383,1335,1384,1336,1385,1337,1386,1338,1387,1339, + 1388,1340,1389,1341,1390,1342,1391,1343,1392,1344,1393,1345,1394,1346,1395,1347, + 1396,1348,1397,1349,1398,1350,1399,1351,1400,1352,1401,1353,1402,1354,1403,1355, + 1404,1356,1405,1357,1406,1358,1407,1359,1408,1360,1409,1361,1410,1362,1411,1363, + 1412,1364,1413,1365,1414,1366,7545,42877,7549,11363,7681,7680,7683,7682,7685,7684, + 7687,7686,7689,7688,7691,7690,7693,7692,7695,7694,7697,7696,7699,7698,7701,7700, + 7703,7702,7705,7704,7707,7706,7709,7708,7711,7710,7713,7712,7715,7714,7717,7716, + 7719,7718,7721,7720,7723,7722,7725,7724,7727,7726,7729,7728,7731,7730,7733,7732, + 7735,7734,7737,7736,7739,7738,7741,7740,7743,7742,7745,7744,7747,7746,7749,7748, + 7751,7750,7753,7752,7755,7754,7757,7756,7759,7758,7761,7760,7763,7762,7765,7764, + 7767,7766,7769,7768,7771,7770,7773,7772,7775,7774,7777,7776,7779,7778,7781,7780, + 7783,7782,7785,7784,7787,7786,7789,7788,7791,7790,7793,7792,7795,7794,7797,7796, + 7799,7798,7801,7800,7803,7802,7805,7804,7807,7806,7809,7808,7811,7810,7813,7812, + 7815,7814,7817,7816,7819,7818,7821,7820,7823,7822,7825,7824,7827,7826,7829,7828, + 7835,7776,7841,7840,7843,7842,7845,7844,7847,7846,7849,7848,7851,7850,7853,7852, + 7855,7854,7857,7856,7859,7858,7861,7860,7863,7862,7865,7864,7867,7866,7869,7868, + 7871,7870,7873,7872,7875,7874,7877,7876,7879,7878,7881,7880,7883,7882,7885,7884, + 7887,7886,7889,7888,7891,7890,7893,7892,7895,7894,7897,7896,7899,7898,7901,7900, + 7903,7902,7905,7904,7907,7906,7909,7908,7911,7910,7913,7912,7915,7914,7917,7916, + 7919,7918,7921,7920,7923,7922,7925,7924,7927,7926,7929,7928,7931,7930,7933,7932, + 7935,7934,7936,7944,7937,7945,7938,7946,7939,7947,7940,7948,7941,7949,7942,7950, + 7943,7951,7952,7960,7953,7961,7954,7962,7955,7963,7956,7964,7957,7965,7968,7976, + 7969,7977,7970,7978,7971,7979,7972,7980,7973,7981,7974,7982,7975,7983,7984,7992, + 7985,7993,7986,7994,7987,7995,7988,7996,7989,7997,7990,7998,7991,7999,8000,8008, + 8001,8009,8002,8010,8003,8011,8004,8012,8005,8013,8017,8025,8019,8027,8021,8029, + 8023,8031,8032,8040,8033,8041,8034,8042,8035,8043,8036,8044,8037,8045,8038,8046, + 8039,8047,8048,8122,8049,8123,8050,8136,8051,8137,8052,8138,8053,8139,8054,8154, + 8055,8155,8056,8184,8057,8185,8058,8170,8059,8171,8060,8186,8061,8187,8064,8072, + 8065,8073,8066,8074,8067,8075,8068,8076,8069,8077,8070,8078,8071,8079,8080,8088, + 8081,8089,8082,8090,8083,8091,8084,8092,8085,8093,8086,8094,8087,8095,8096,8104, + 8097,8105,8098,8106,8099,8107,8100,8108,8101,8109,8102,8110,8103,8111,8112,8120, + 8113,8121,8115,8124,8126,921,8131,8140,8144,8152,8145,8153,8160,8168,8161,8169, + 8165,8172,8179,8188,8526,8498,8560,8544,8561,8545,8562,8546,8563,8547,8564,8548, + 8565,8549,8566,8550,8567,8551,8568,8552,8569,8553,8570,8554,8571,8555,8572,8556, + 8573,8557,8574,8558,8575,8559,8580,8579,9424,9398,9425,9399,9426,9400,9427,9401, + 9428,9402,9429,9403,9430,9404,9431,9405,9432,9406,9433,9407,9434,9408,9435,9409, + 9436,9410,9437,9411,9438,9412,9439,9413,9440,9414,9441,9415,9442,9416,9443,9417, + 9444,9418,9445,9419,9446,9420,9447,9421,9448,9422,9449,9423,11312,11264,11313,11265, + 11314,11266,11315,11267,11316,11268,11317,11269,11318,11270,11319,11271,11320,11272,11321,11273, + 11322,11274,11323,11275,11324,11276,11325,11277,11326,11278,11327,11279,11328,11280,11329,11281, + 11330,11282,11331,11283,11332,11284,11333,11285,11334,11286,11335,11287,11336,11288,11337,11289, + 11338,11290,11339,11291,11340,11292,11341,11293,11342,11294,11343,11295,11344,11296,11345,11297, + 11346,11298,11347,11299,11348,11300,11349,11301,11350,11302,11351,11303,11352,11304,11353,11305, + 11354,11306,11355,11307,11356,11308,11357,11309,11358,11310,11361,11360,11365,570,11366,574, + 11368,11367,11370,11369,11372,11371,11379,11378,11382,11381,11393,11392,11395,11394,11397,11396, + 11399,11398,11401,11400,11403,11402,11405,11404,11407,11406,11409,11408,11411,11410,11413,11412, + 11415,11414,11417,11416,11419,11418,11421,11420,11423,11422,11425,11424,11427,11426,11429,11428, + 11431,11430,11433,11432,11435,11434,11437,11436,11439,11438,11441,11440,11443,11442,11445,11444, + 11447,11446,11449,11448,11451,11450,11453,11452,11455,11454,11457,11456,11459,11458,11461,11460, + 11463,11462,11465,11464,11467,11466,11469,11468,11471,11470,11473,11472,11475,11474,11477,11476, + 11479,11478,11481,11480,11483,11482,11485,11484,11487,11486,11489,11488,11491,11490,11520,4256, + 11521,4257,11522,4258,11523,4259,11524,4260,11525,4261,11526,4262,11527,4263,11528,4264, + 11529,4265,11530,4266,11531,4267,11532,4268,11533,4269,11534,4270,11535,4271,11536,4272, + 11537,4273,11538,4274,11539,4275,11540,4276,11541,4277,11542,4278,11543,4279,11544,4280, + 11545,4281,11546,4282,11547,4283,11548,4284,11549,4285,11550,4286,11551,4287,11552,4288, + 11553,4289,11554,4290,11555,4291,11556,4292,11557,4293,42561,42560,42563,42562,42565,42564, + 42567,42566,42569,42568,42571,42570,42573,42572,42575,42574,42577,42576,42579,42578,42581,42580, + 42583,42582,42585,42584,42587,42586,42589,42588,42591,42590,42595,42594,42597,42596,42599,42598, + 42601,42600,42603,42602,42605,42604,42625,42624,42627,42626,42629,42628,42631,42630,42633,42632, + 42635,42634,42637,42636,42639,42638,42641,42640,42643,42642,42645,42644,42647,42646,42787,42786, + 42789,42788,42791,42790,42793,42792,42795,42794,42797,42796,42799,42798,42803,42802,42805,42804, + 42807,42806,42809,42808,42811,42810,42813,42812,42815,42814,42817,42816,42819,42818,42821,42820, + 42823,42822,42825,42824,42827,42826,42829,42828,42831,42830,42833,42832,42835,42834,42837,42836, + 42839,42838,42841,42840,42843,42842,42845,42844,42847,42846,42849,42848,42851,42850,42853,42852, + 42855,42854,42857,42856,42859,42858,42861,42860,42863,42862,42874,42873,42876,42875,42879,42878, + 42881,42880,42883,42882,42885,42884,42887,42886,42892,42891,65345,65313,65346,65314,65347,65315, + 65348,65316,65349,65317,65350,65318,65351,65319,65352,65320,65353,65321,65354,65322,65355,65323, + 65356,65324,65357,65325,65358,65326,65359,65327,65360,65328,65361,65329,65362,65330,65363,65331, + 65364,65332,65365,65333,65366,65334,65367,65335,65368,65336,65369,65337,65370,65338 }; + +#endif diff --git a/mod/brl.mod/blitz.mod/doc/abs.bmx b/mod/brl.mod/blitz.mod/doc/abs.bmx new file mode 100644 index 0000000..281be9e --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/abs.bmx @@ -0,0 +1,7 @@ +Rem +Abs is a mathematical operator that performs the Absolute function. +End Rem + +For f#=-1 To 1 Step 0.125 + Print "Abs "+f+"="+Abs f +Next diff --git a/mod/brl.mod/blitz.mod/doc/abstract.bmx b/mod/brl.mod/blitz.mod/doc/abstract.bmx new file mode 100644 index 0000000..b2bf850 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/abstract.bmx @@ -0,0 +1,60 @@ +Rem +A BlitzMax type that contains Abstract methods becomes abstract itself. +Abstract types are used to define interfaces that extending types must +implement before they can be used to create new instances. + +In the following code TShape is an abstract type in that you can not +create a TShape but anything extending a TShape must implement a Draw() +method. +End Rem + +Type TShape + Field xpos,ypos + Method Draw() Abstract +End Type + +Type TCircle extends TShape + Field radius + + Function Create:TCircle(x,y,r) + local c:TCircle=new TCircle + c.xpos=x;c.ypos=y;c.radius=r + return c + End Function + + Method Draw() + DrawOval xpos,ypos,radius,radius + End Method +End Type + +Type TRect extends TShape + Field width,height + + Function Create:TRect(x,y,w,h) + local r:TRect=new TRect + r.xpos=x;r.ypos=y;r.width=w;r.height=h + return r + End Function + + Method Draw() + DrawRect xpos,ypos,width,height + End Method +End Type + +local shapelist:TShape[4] +local shape:TShape + +shapelist[0]=TCircle.Create(200,50,50) +shapelist[1]=TRect.Create(300,50,40,40) +shapelist[2]=TCircle.Create(400,50,50) +shapelist[3]=TRect.Create(200,180,250,20) + +graphics 640,480 +while not keyhit(KEY_ESCAPE) + cls + for shape=eachin shapelist + shape.draw + next + flip +wend +end diff --git a/mod/brl.mod/blitz.mod/doc/acos.bmx b/mod/brl.mod/blitz.mod/doc/acos.bmx new file mode 100644 index 0000000..b13bbe1 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/acos.bmx @@ -0,0 +1,7 @@ +Rem +Inverse Cosine of x +End Rem + +for d!=-1.0 to 1.0 step 0.125 + print "ACos("+d+")="+ACos(d) +next diff --git a/mod/brl.mod/blitz.mod/doc/and.bmx b/mod/brl.mod/blitz.mod/doc/and.bmx new file mode 100644 index 0000000..bdce11e --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/and.bmx @@ -0,0 +1,7 @@ +Rem +And is a boolean operator that performs the AND function. +End Rem + +For i=1 To 10 + If i>3 And i<6 Print "!" Else Print i +Next diff --git a/mod/brl.mod/blitz.mod/doc/appargs.bmx b/mod/brl.mod/blitz.mod/doc/appargs.bmx new file mode 100644 index 0000000..94c8bbe --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/appargs.bmx @@ -0,0 +1,9 @@ +' appargs.bmx +' print the command line arguments passed to the program at runtime + +Print "Number of arguments = "+AppArgs.length + +For a$=EachIn AppArgs +Print a$ +Next + diff --git a/mod/brl.mod/blitz.mod/doc/appdir.bmx b/mod/brl.mod/blitz.mod/doc/appdir.bmx new file mode 100644 index 0000000..381894c --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/appdir.bmx @@ -0,0 +1,8 @@ +' appdir.bmx +' requests the user to select a file from the application's directory + +Print "Application Directory="+AppDir$ + +file$=RequestFile("Select File to Open","",False,AppDir$) + +Print "file selected was :"+file \ No newline at end of file diff --git a/mod/brl.mod/blitz.mod/doc/appfile.bmx b/mod/brl.mod/blitz.mod/doc/appfile.bmx new file mode 100644 index 0000000..5e9e442 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/appfile.bmx @@ -0,0 +1,3 @@ +' appfile.bmx + +Print "This program's executable is located at "+AppFile$ diff --git a/mod/brl.mod/blitz.mod/doc/array.bmx b/mod/brl.mod/blitz.mod/doc/array.bmx new file mode 100644 index 0000000..94ff842 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/array.bmx @@ -0,0 +1,13 @@ +Rem +The Array command creates a BlitzMax array, a container type containing a sequence +of a specified primitive or custom &Type. +End Rem + +Local a[] +Local b#[] +Local c[][] + +a=Array[20] 'an integer array with 20 elements +b=Array#[10] 'a floating point array of 10 elements + +print len b diff --git a/mod/brl.mod/blitz.mod/doc/asc.bmx b/mod/brl.mod/blitz.mod/doc/asc.bmx new file mode 100644 index 0000000..97cbd68 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/asc.bmx @@ -0,0 +1,6 @@ +Rem +Asc returns the unicode value of the first character of a string. +End Rem + +print Asc("A") '65 +Print "A"[0] '65 - equivalent index style implementation diff --git a/mod/brl.mod/blitz.mod/doc/asin.bmx b/mod/brl.mod/blitz.mod/doc/asin.bmx new file mode 100644 index 0000000..8c75295 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/asin.bmx @@ -0,0 +1,7 @@ +Rem +Inverse Sine of x +End Rem + +for d!=-1.0 to 1.0 step 0.125 + print "ASin("+d+")="+ASin(d) +next diff --git a/mod/brl.mod/blitz.mod/doc/assert.bmx b/mod/brl.mod/blitz.mod/doc/assert.bmx new file mode 100644 index 0000000..0c6bfe1 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/assert.bmx @@ -0,0 +1,6 @@ +Rem +Assert generates a BlitzMax runtime error if the specified condition is false. +End Rem + +a=LoadImage("nonexistant image file") +Assert a,"Image Failed to Load" diff --git a/mod/brl.mod/blitz.mod/doc/atan.bmx b/mod/brl.mod/blitz.mod/doc/atan.bmx new file mode 100644 index 0000000..cb5c3da --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/atan.bmx @@ -0,0 +1,7 @@ +Rem +ATan returns the Inverse Tangent of x +End Rem + +for d!=-1.0 to 1.0 step 0.125 + print "ATan("+d+")="+ATan(d) +next diff --git a/mod/brl.mod/blitz.mod/doc/atan2.bmx b/mod/brl.mod/blitz.mod/doc/atan2.bmx new file mode 100644 index 0000000..34014a6 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/atan2.bmx @@ -0,0 +1,17 @@ +Rem +ATan2 returns the Inverse Tangent of two variables +End Rem + +function Angle!(x0!,y0!,x1!,y1!) + return ATan2(y1-y0,x1-x0) +end function + +graphics 640,480 +while not keyhit(KEY_ESCAPE) + cls + x#=mousex() + y#=mousey() + drawline 320,240,x,y + drawtext "Angle="+Angle(320,240,x,y),20,20 + flip +wend diff --git a/mod/brl.mod/blitz.mod/doc/byte.bmx b/mod/brl.mod/blitz.mod/doc/byte.bmx new file mode 100644 index 0000000..0d37b88 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/byte.bmx @@ -0,0 +1,9 @@ +Rem +Byte is an unsigned 8 bit integer BlitzMax primitive type. +End Rem + +Local a:byte + +a=512;print "a="+a 'prints 0 +a=-1;print "a="+a 'prints 255 + diff --git a/mod/brl.mod/blitz.mod/doc/case.bmx b/mod/brl.mod/blitz.mod/doc/case.bmx new file mode 100644 index 0000000..ad6c842 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/case.bmx @@ -0,0 +1,14 @@ +' case.bmx + +' Case performs a comparison with the preceeding value(s) and that +' listed in the enclosing Select statement: + +a=Int( Input("Enter a number between 1 and 5 ") ) + +Select a + Case 1 Print "You think small" + Case 2 Print "You are even tempered" + Case 3,4 Print "You are middle of the road" + Case 5 Print "You think big" + Default Print "You are unable to follow instructions" +End Select diff --git a/mod/brl.mod/blitz.mod/doc/catch.bmx b/mod/brl.mod/blitz.mod/doc/catch.bmx new file mode 100644 index 0000000..1803e57 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/catch.bmx @@ -0,0 +1,13 @@ +Rem +Catch defines an exception handler following a Try..EndTry Block. +End Rem + +Try + repeat + a:+1 + print a + if a>20 throw "chunks" + forever +Catch a$ + print "caught exception "+a$ +EndTry diff --git a/mod/brl.mod/blitz.mod/doc/ceil.bmx b/mod/brl.mod/blitz.mod/doc/ceil.bmx new file mode 100644 index 0000000..07c4e48 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/ceil.bmx @@ -0,0 +1,7 @@ +Rem +Ceil(x#) returns the smallest integral value not less than x +End Rem + +for i#=-1 to 1 step .2 + print "Ceil("+i+")="+Ceil(i) +next diff --git a/mod/brl.mod/blitz.mod/doc/chr.bmx b/mod/brl.mod/blitz.mod/doc/chr.bmx new file mode 100644 index 0000000..a52daa9 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/chr.bmx @@ -0,0 +1,5 @@ +Rem +Chr returns a String of length 1 containing the unicode character of the value. +End Rem + +print Chr(65) 'A diff --git a/mod/brl.mod/blitz.mod/doc/const.bmx b/mod/brl.mod/blitz.mod/doc/const.bmx new file mode 100644 index 0000000..b9b7030 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/const.bmx @@ -0,0 +1,10 @@ +Rem +Const defines the preceeding variable declaration as constant. +End Rem + +Const ON=TRUE +Const OFF=FALSE + +Const TWOPI#=2*PI + +print TWOPI diff --git a/mod/brl.mod/blitz.mod/doc/continue.bmx b/mod/brl.mod/blitz.mod/doc/continue.bmx new file mode 100644 index 0000000..2c29b7a --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/continue.bmx @@ -0,0 +1,8 @@ +Rem +Continue causes program flow to return to the start of the enclosing While, Repeat or For program loop +End Rem + +For i=1 To 20 + If i Mod 2 Continue + Print i +Next diff --git a/mod/brl.mod/blitz.mod/doc/cos.bmx b/mod/brl.mod/blitz.mod/doc/cos.bmx new file mode 100644 index 0000000..6035070 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/cos.bmx @@ -0,0 +1,7 @@ +Rem +Cosine of x +End Rem + +for d=0 to 360 step 45 + print "Cos("+d+")="+cos(d) +next diff --git a/mod/brl.mod/blitz.mod/doc/default.bmx b/mod/brl.mod/blitz.mod/doc/default.bmx new file mode 100644 index 0000000..f5400a9 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/default.bmx @@ -0,0 +1,13 @@ +Rem +Default is used in a Select block to mark a code section that is executed if all prior Case statements fail. +End Rem + +a$=Input("What is your favorite color?") +a$=lower(a$) 'make sure the answer is lower case + +Select a$ + case "yellow" Print "You a bright and breezy" + case "blue" Print "You are a typical boy" + case "pink" Print "You are a typical girl" + default Print "You are quite unique!" +End Select diff --git a/mod/brl.mod/blitz.mod/doc/defdata.bmx b/mod/brl.mod/blitz.mod/doc/defdata.bmx new file mode 100644 index 0000000..f74ca93 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/defdata.bmx @@ -0,0 +1,8 @@ +' defdata.bmx + +ReadData name$ +ReadData age,skill + +Print "name="+name+" age="+age+" skill="+skill + +DefData "Simon",37,5000 \ No newline at end of file diff --git a/mod/brl.mod/blitz.mod/doc/delete.bmx b/mod/brl.mod/blitz.mod/doc/delete.bmx new file mode 100644 index 0000000..680c6ae --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/delete.bmx @@ -0,0 +1,3 @@ +Rem +Reserved for future expansions. +End Rem diff --git a/mod/brl.mod/blitz.mod/doc/double.bmx b/mod/brl.mod/blitz.mod/doc/double.bmx new file mode 100644 index 0000000..afb85ac --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/double.bmx @@ -0,0 +1,14 @@ +Rem +Double is a 64 bit floating point BlitzMax primitive type. +End Rem + +Local speedoflight:Double +Local distance:Double +Local seconds:Double + +speedoflight=299792458:Double 'meters per second +distance=149597890000:Double 'average distance in meters from earth sun + +seconds=distance/speedoflight + +Print "Number of seconds for light to travel from earth to sun="+seconds \ No newline at end of file diff --git a/mod/brl.mod/blitz.mod/doc/eachin.bmx b/mod/brl.mod/blitz.mod/doc/eachin.bmx new file mode 100644 index 0000000..8958e6a --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/eachin.bmx @@ -0,0 +1,9 @@ +Rem +Specifies a BlitzMax collection type whose values are assigned sequentially to the For iterator. +End Rem + +Local a[]=[0,5,12,13,20] + +for b=eachin a + print b +next diff --git a/mod/brl.mod/blitz.mod/doc/else.bmx b/mod/brl.mod/blitz.mod/doc/else.bmx new file mode 100644 index 0000000..65145d2 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/else.bmx @@ -0,0 +1,14 @@ +Rem +Else provides the ability for an If Then construct to execute a second block of code when the If condition is false. +End Rem + +i=3 + +If i<5 Print "i<5" Else Print "i>=5" ' single line If Else + +If i<5 'block style If Else + Print "i<5" +Else + Print "i>=5" +EndIf + diff --git a/mod/brl.mod/blitz.mod/doc/elseif.bmx b/mod/brl.mod/blitz.mod/doc/elseif.bmx new file mode 100644 index 0000000..7de1a2c --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/elseif.bmx @@ -0,0 +1,14 @@ +Rem +ElseIf provides the ability to test and execute a section of code if the initial condition failed. +End Rem + +age=Int( Input("How old Are You?") ) + +If age<13 + Print "You are young" +ElseIf age<20 + Print "You are a teen!" +Else + Print "You are neither young nor a teen" +EndIf + \ No newline at end of file diff --git a/mod/brl.mod/blitz.mod/doc/end.bmx b/mod/brl.mod/blitz.mod/doc/end.bmx new file mode 100644 index 0000000..1e73e71 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/end.bmx @@ -0,0 +1,7 @@ +Rem +The End command causes a program to exit immediately. +End Rem + +Print "Hello!" +End +Print "This line will never be printed as the program has already been ended." diff --git a/mod/brl.mod/blitz.mod/doc/endextern.bmx b/mod/brl.mod/blitz.mod/doc/endextern.bmx new file mode 100644 index 0000000..b3fd7ce --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/endextern.bmx @@ -0,0 +1,9 @@ +Rem +EndExtern marks the end of an Extern section. +End Rem + +Extern + Function puts( str$z ) +End Extern + +puts "Using clib's put string!" diff --git a/mod/brl.mod/blitz.mod/doc/endfunction.bmx b/mod/brl.mod/blitz.mod/doc/endfunction.bmx new file mode 100644 index 0000000..4962fef --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/endfunction.bmx @@ -0,0 +1,12 @@ +Rem +Function marks the end of a BlitzMax function declaration. +End Rem + +Function RandomName$() + local a$[]=["Bob","Joe","Bill"] + Return a[Rnd(Len a)] +End Function + +For i=1 To 5 + Print RandomName$() +Next diff --git a/mod/brl.mod/blitz.mod/doc/endif.bmx b/mod/brl.mod/blitz.mod/doc/endif.bmx new file mode 100644 index 0000000..653fa2b --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/endif.bmx @@ -0,0 +1,9 @@ +Rem +EndIf marks the end of an If Then block. +End Rem + +i=5 + +If i<10 + Print "i<10" +EndIf \ No newline at end of file diff --git a/mod/brl.mod/blitz.mod/doc/endmethod.bmx b/mod/brl.mod/blitz.mod/doc/endmethod.bmx new file mode 100644 index 0000000..2ede099 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/endmethod.bmx @@ -0,0 +1,14 @@ +Rem +EndMethod marks the end of a BlitzMax Method declaration. +End Rem + +Type TPoint + field x,y + + Method ToString$() + return x+","+y + End Method +End Type + +a:TPoint=new TPoint +print a.ToString() diff --git a/mod/brl.mod/blitz.mod/doc/endrem.bmx b/mod/brl.mod/blitz.mod/doc/endrem.bmx new file mode 100644 index 0000000..96f8d24 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/endrem.bmx @@ -0,0 +1,7 @@ +Rem +All code between Rem and EndRem is ignored by the BlitzMax compiler. +Print "hello" +End Rem + +Print "goodbye" + \ No newline at end of file diff --git a/mod/brl.mod/blitz.mod/doc/endselect.bmx b/mod/brl.mod/blitz.mod/doc/endselect.bmx new file mode 100644 index 0000000..45e3dbc --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/endselect.bmx @@ -0,0 +1,16 @@ +Rem +EndSelect marks the end of a Select block. +End Rem + +SeedRnd MilliSecs() + +a=Rand(5) + +Select a + Case 1 Print "one" + Case 2 Print "two" + Case 3 Print "three" + Case 4 Print "four" + Case 5 Print "five" + Default Print "Program Error" +End Select diff --git a/mod/brl.mod/blitz.mod/doc/endtry.bmx b/mod/brl.mod/blitz.mod/doc/endtry.bmx new file mode 100644 index 0000000..be47198 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/endtry.bmx @@ -0,0 +1,4 @@ +Rem +EndTry +EndTry marks the end of a Try block. +End Rem diff --git a/mod/brl.mod/blitz.mod/doc/endtype.bmx b/mod/brl.mod/blitz.mod/doc/endtype.bmx new file mode 100644 index 0000000..582aa78 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/endtype.bmx @@ -0,0 +1,13 @@ +Rem +EndType marks the end of a BlitzMax custom type. +End Rem + +Type TVector + Field x,y,z +End Type + +Local a:TVector=new TVector + +a.x=10 +a.y=20 +a.z=30 diff --git a/mod/brl.mod/blitz.mod/doc/exit.bmx b/mod/brl.mod/blitz.mod/doc/exit.bmx new file mode 100644 index 0000000..0868643 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/exit.bmx @@ -0,0 +1,9 @@ +Rem +Exit causes program flow to exit the enclosing While, Repeat or For loop. +End Rem + +Repeat + Print n + n:+1 + If n=5 Exit +Forever diff --git a/mod/brl.mod/blitz.mod/doc/extends.bmx b/mod/brl.mod/blitz.mod/doc/extends.bmx new file mode 100644 index 0000000..817525a --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/extends.bmx @@ -0,0 +1,54 @@ +Rem +Extends is used in a BlitzMax Type declaration to derive the Type from a specified base class. +End Rem + +Type TShape + Field xpos,ypos + Method Draw() Abstract +End Type + +Type TCircle extends TShape + Field radius + + Function Create:TCircle(x,y,r) + local c:TCircle=new TCircle + c.xpos=x;c.ypos=y;c.radius=r + return c + End Function + + Method Draw() + DrawOval xpos,ypos,radius,radius + End Method +End Type + +Type TRect extends TShape + Field width,height + + Function Create:TRect(x,y,w,h) + local r:TRect=new TRect + r.xpos=x;r.ypos=y;r.width=w;r.height=h + return r + End Function + + Method Draw() + DrawRect xpos,ypos,width,height + End Method +End Type + +local shapelist:TShape[4] +local shape:TShape + +shapelist[0]=TCircle.Create(200,50,50) +shapelist[1]=TRect.Create(300,50,40,40) +shapelist[2]=TCircle.Create(400,50,50) +shapelist[3]=TRect.Create(200,180,250,20) + +graphics 640,480 +while not keyhit(KEY_ESCAPE) + cls + for shape=eachin shapelist + shape.draw + next + flip +wend +end diff --git a/mod/brl.mod/blitz.mod/doc/extern.bmx b/mod/brl.mod/blitz.mod/doc/extern.bmx new file mode 100644 index 0000000..93349b4 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/extern.bmx @@ -0,0 +1,11 @@ +Rem +Extern marks the beginning of an external list of function declarations. +End Rem + +Extern + Function puts( str$z ) + Function my_puts( str$z )="puts" +End Extern + +puts "Using clib's put string!" +my_puts "Also using clib's put string!" diff --git a/mod/brl.mod/blitz.mod/doc/false.bmx b/mod/brl.mod/blitz.mod/doc/false.bmx new file mode 100644 index 0000000..e74c864 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/false.bmx @@ -0,0 +1,9 @@ +Rem +False is a Constant Integer assigned the value 0. +End Rem + +Print "False="+False + +If False + Print "This code will never be executed" +Endif diff --git a/mod/brl.mod/blitz.mod/doc/field.bmx b/mod/brl.mod/blitz.mod/doc/field.bmx new file mode 100644 index 0000000..1ce4132 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/field.bmx @@ -0,0 +1,13 @@ +Rem +Field is used to declare the member variable(s) of a type. +End Rem + +Type TVector + Field x,y,z +End Type + +Local a:TVector=new TVector + +a.x=10 +a.y=20 +a.z=30 diff --git a/mod/brl.mod/blitz.mod/doc/final.bmx b/mod/brl.mod/blitz.mod/doc/final.bmx new file mode 100644 index 0000000..1ad592e --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/final.bmx @@ -0,0 +1,15 @@ +Rem +Final stops methods from being redefined in super classes. +End Rem + +Type T1 + Method ToString$() Final + return "T1" + end method +End Type + +Type T2 extends T1 + method ToString$() 'compile time error "Final methods cannot be overridden" + return "T2" + end method +End Type diff --git a/mod/brl.mod/blitz.mod/doc/float.bmx b/mod/brl.mod/blitz.mod/doc/float.bmx new file mode 100644 index 0000000..9638e53 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/float.bmx @@ -0,0 +1,17 @@ +Rem +Float is a 32 bit floating point BlitzMax primitive type. +End Rem + +Local a:float + +a=1 + +for i=1 to 8 + print a + a=a*0.1 +next + +for i=1 to 8 + a=a*10 + print a +next diff --git a/mod/brl.mod/blitz.mod/doc/floor.bmx b/mod/brl.mod/blitz.mod/doc/floor.bmx new file mode 100644 index 0000000..bc3e0df --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/floor.bmx @@ -0,0 +1,7 @@ +Rem +Floor(x!) returns the largest integral value not greater than x +End Rem + +for i!=-1 to 1 step .2 + print "Floor("+i+")="+Floor(i) +next diff --git a/mod/brl.mod/blitz.mod/doc/for.bmx b/mod/brl.mod/blitz.mod/doc/for.bmx new file mode 100644 index 0000000..2f295d3 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/for.bmx @@ -0,0 +1,9 @@ +Rem +For marks the start of a loop that uses an iterator to execute a section of code repeatedly. +End Rem + +' print 5 times table + +For i=1 to 12 + Print "5*"+i+"="+5*i +Next diff --git a/mod/brl.mod/blitz.mod/doc/forever.bmx b/mod/brl.mod/blitz.mod/doc/forever.bmx new file mode 100644 index 0000000..340e8ae --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/forever.bmx @@ -0,0 +1,8 @@ +Rem +Forever is an alternate ending to a Repeat block that will cause the loop to always repeat. +End Rem + +Repeat + Print i+" Ctrl-C to End!" + i:+1 +Forever diff --git a/mod/brl.mod/blitz.mod/doc/function.bmx b/mod/brl.mod/blitz.mod/doc/function.bmx new file mode 100644 index 0000000..acbbb64 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/function.bmx @@ -0,0 +1,21 @@ +Rem +Function marks the beginning of a BlitzMax function declaration. + +When a function does not return a value the use of brackets when +calling the function is optional. +End Rem + +Function NextArg(a$) + Local p + p=instr(a$,",") + if p + NextArg a$[p..] + print a$[..p-1] + else + print a$ + endif +End Function + +NextArg("one,two,three,four") + +NextArg "22,25,20" 'look ma, no brackets diff --git a/mod/brl.mod/blitz.mod/doc/gcmalloc.bmx b/mod/brl.mod/blitz.mod/doc/gcmalloc.bmx new file mode 100644 index 0000000..e69de29 diff --git a/mod/brl.mod/blitz.mod/doc/global.bmx b/mod/brl.mod/blitz.mod/doc/global.bmx new file mode 100644 index 0000000..98ab847 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/global.bmx @@ -0,0 +1,12 @@ +Rem +Global defines a variable as Global allowing it be accessed from within Methods and Functions. +End Rem + +Global a=20 + +Function TestGlobal() + print "a="+a +End Function + +TestGlobal +print "a="+a diff --git a/mod/brl.mod/blitz.mod/doc/goto.bmx b/mod/brl.mod/blitz.mod/doc/goto.bmx new file mode 100644 index 0000000..2235357 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/goto.bmx @@ -0,0 +1,9 @@ +Rem +Causes program execution to jump to the #label specified. +End Rem + +Print "one" +Goto here +Print "two" +#here +Print "three" \ No newline at end of file diff --git a/mod/brl.mod/blitz.mod/doc/if.bmx b/mod/brl.mod/blitz.mod/doc/if.bmx new file mode 100644 index 0000000..7647e35 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/if.bmx @@ -0,0 +1,9 @@ +Rem +If begins a conditional block. +End Rem + +If 3<5 Print "3<5" 'single line if + +If 5<7 'if block + Print "5<7" +EndIf diff --git a/mod/brl.mod/blitz.mod/doc/import.bmx b/mod/brl.mod/blitz.mod/doc/import.bmx new file mode 100644 index 0000000..e76a93d --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/import.bmx @@ -0,0 +1,15 @@ +Rem +:Import specifies the external BlitzMax modules and source files used by the program. +End Rem + +Framework BRL.GlMax2D + +Import BRL.System + +Graphics 640,480,32 + +While Not KeyHit(KEY_ESCAPE) + Cls + DrawText "Minimal 2D App!",0,0 + Flip +Wend diff --git a/mod/brl.mod/blitz.mod/doc/incbin.bmx b/mod/brl.mod/blitz.mod/doc/incbin.bmx new file mode 100644 index 0000000..331f79a --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/incbin.bmx @@ -0,0 +1,10 @@ +Rem +IncBin embeds an external data file in a BlitzMax program that can +then be read using the "incbin::" device name. +End Rem + +' code snippet from demos/firepaint/firepaint.bmx + +Incbin "stars.png" + +Local stars=LoadImage( "incbin::stars.png" ) diff --git a/mod/brl.mod/blitz.mod/doc/incbinlen.bmx b/mod/brl.mod/blitz.mod/doc/incbinlen.bmx new file mode 100644 index 0000000..b245035 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/incbinlen.bmx @@ -0,0 +1,12 @@ +Rem +IncBinLen returns the size in bytes of the specified embedded binary file. +End Rem + +incbin "incbinlen.bmx" + +local p:byte ptr=IncBinPtr("incbinlen.bmx") +local bytes=incbinlen("incbinlen.bmx") + +local s$=StringFromBytes(p,bytes) + +Print "StringFromBytes(p,bytes)="+s$ diff --git a/mod/brl.mod/blitz.mod/doc/incbinptr.bmx b/mod/brl.mod/blitz.mod/doc/incbinptr.bmx new file mode 100644 index 0000000..7e6b783 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/incbinptr.bmx @@ -0,0 +1,12 @@ +Rem +IncBinPtr returns a byte pointer to the specified embedded binary file. +End Rem + +Incbin "incbinptr.bmx" + +Local p:Byte Ptr=IncbinPtr("incbinptr.bmx") +Local bytes=IncbinLen("incbinptr.bmx") + +Local s$=String.FromBytes(p,bytes) + +Print "StringFromBytes(p,bytes)="+s$ diff --git a/mod/brl.mod/blitz.mod/doc/int.bmx b/mod/brl.mod/blitz.mod/doc/int.bmx new file mode 100644 index 0000000..cd495ba --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/int.bmx @@ -0,0 +1,13 @@ +Rem +Int is a signed 32 bit integer BlitzMax primitive type. +End Rem + +Local a:Int + +' the following values all print 0 as BlitzMax "rounds to zero" +' when converting from floating point to integer + +a=0.1;print a +a=0.9;print a +a=-0.1;print a +a=-0.9;print a diff --git a/mod/brl.mod/blitz.mod/doc/intro.bbdoc b/mod/brl.mod/blitz.mod/doc/intro.bbdoc new file mode 100644 index 0000000..bd95e13 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/intro.bbdoc @@ -0,0 +1,3 @@ +The Blitz runtime module provides low level functionality required by BlitzMax applications when they are running. This includes things like memory management, exception handling and string and array operations.
+
+Much of the functionality provided by this module is hidden from application programmers, but is instead used 'behind the scenes' by the compiler. However, there are some very useful commands for debugging, memory management and simple standard IO. diff --git a/mod/brl.mod/blitz.mod/doc/launchdir.bmx b/mod/brl.mod/blitz.mod/doc/launchdir.bmx new file mode 100644 index 0000000..6119867 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/launchdir.bmx @@ -0,0 +1,3 @@ +' launchdir.bmx + +Print "This program was launched from "+LaunchDir$ diff --git a/mod/brl.mod/blitz.mod/doc/len.bmx b/mod/brl.mod/blitz.mod/doc/len.bmx new file mode 100644 index 0000000..78fbe2e --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/len.bmx @@ -0,0 +1,13 @@ +Rem +Len is a BlitzMax operator that returns the number of elements in a container Type. +End Rem + +a$="BlitzMax Rocks" +Print Len a$ 'prints 14 + +Local b[] +Print Len b 'prints 0 + +b=new Int[20] +Print Len b 'prints 20 + diff --git a/mod/brl.mod/blitz.mod/doc/local.bmx b/mod/brl.mod/blitz.mod/doc/local.bmx new file mode 100644 index 0000000..17b94a0 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/local.bmx @@ -0,0 +1,13 @@ +Rem +Local defines a variable as local to the Method or Function it is defined meaning it is automatically released when the function returns. +End Rem + +Function TestLocal() + Local a + a=20 + print "a="+a + Return +End Function + +TestLocal +print "a="+a 'prints 0 or if in Strict mode is an error as a is only local to the TestLocal function diff --git a/mod/brl.mod/blitz.mod/doc/log.bmx b/mod/brl.mod/blitz.mod/doc/log.bmx new file mode 100644 index 0000000..448d5a6 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/log.bmx @@ -0,0 +1,7 @@ +Rem +Log(n#) returns the natural logarithm of n +End Rem + +for n#=1 to 20 + print "Log("+n+")="+Log(n) +next diff --git a/mod/brl.mod/blitz.mod/doc/log10.bmx b/mod/brl.mod/blitz.mod/doc/log10.bmx new file mode 100644 index 0000000..94bf13b --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/log10.bmx @@ -0,0 +1,7 @@ +Rem +Log10(n#) returns the Base 10 logarithm of n +End Rem + +for n#=0 to 100 step 10 + print "Log10("+n+")="+Log10(n) +next diff --git a/mod/brl.mod/blitz.mod/doc/long.bmx b/mod/brl.mod/blitz.mod/doc/long.bmx new file mode 100644 index 0000000..d09e903 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/long.bmx @@ -0,0 +1,9 @@ +Rem +Long is a signed 64 bit integer BlitzMax primitive type. +End Rem + +Const MAXLONG:Long=$7fffffffffffffff:Long +Const MINLONG:Long=$8000000000000000:Long + +Print "A long can have the maximum value of:"+MAXLONG +Print "A long can have the minimum value of:"+MINLONG diff --git a/mod/brl.mod/blitz.mod/doc/maxim.bmx b/mod/brl.mod/blitz.mod/doc/maxim.bmx new file mode 100644 index 0000000..53bfd54 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/maxim.bmx @@ -0,0 +1,7 @@ +Rem +Maxim +Maxim evaluates to the value of the largest of the two operators. +End Rem + +Print Maxim(10,20) '20 +Print Maxim(20,10) '20 \ No newline at end of file diff --git a/mod/brl.mod/blitz.mod/doc/method.bmx b/mod/brl.mod/blitz.mod/doc/method.bmx new file mode 100644 index 0000000..1ccd88c --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/method.bmx @@ -0,0 +1,15 @@ +Rem +Method marks the beginning of a BlitzMax custom type member function. +End Rem + +Type TPoint + field x,y + + Method ToString$() + return x+","+y + End Method +End Type + +a:TPoint=new TPoint +print a.ToString() + \ No newline at end of file diff --git a/mod/brl.mod/blitz.mod/doc/minim.bmx b/mod/brl.mod/blitz.mod/doc/minim.bmx new file mode 100644 index 0000000..d8209c4 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/minim.bmx @@ -0,0 +1,6 @@ +Rem +Minim evaluates to the value of the smallest of the two operators. +End Rem + +Print Minim(10,20) '10 +Print Minim(20,10) '10 \ No newline at end of file diff --git a/mod/brl.mod/blitz.mod/doc/mod.bmx b/mod/brl.mod/blitz.mod/doc/mod.bmx new file mode 100644 index 0000000..7becfbd --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/mod.bmx @@ -0,0 +1,7 @@ +Rem +Mod is a mathematical operator that performs the Modulo function. +End Rem + +For i=6 to -6 Step -1 + Print i+" Mod 3="+(i Mod 3) +Next diff --git a/mod/brl.mod/blitz.mod/doc/module.bmx b/mod/brl.mod/blitz.mod/doc/module.bmx new file mode 100644 index 0000000..c9e134b --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/module.bmx @@ -0,0 +1,11 @@ +Rem +The Module keyword advises the BlitzMax program maker BMK to create a code +module from the source file. +End Rem + +Module PUB.Sequencer + +ModuleInfo "Framework: Audio Sequencer for use with FreeAudio" +ModuleInfo "Copyright: Blitz Research Ltd" +ModuleInfo "Author: Simon Armstrong" +ModuleInfo "Version: 1.00" diff --git a/mod/brl.mod/blitz.mod/doc/moduleinfo.bmx b/mod/brl.mod/blitz.mod/doc/moduleinfo.bmx new file mode 100644 index 0000000..b2479ed --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/moduleinfo.bmx @@ -0,0 +1,10 @@ +Rem +ModuleInfo allows properties such as Author and Copyright to be included in a module file. +End Rem + +Module PUB.Sequencer + +ModuleInfo "Framework: Audio Sequencer for use with FreeAudio" +ModuleInfo "Copyright: Blitz Research Ltd" +ModuleInfo "Author: Simon Armstrong" +ModuleInfo "Version: 1.00" diff --git a/mod/brl.mod/blitz.mod/doc/new.bmx b/mod/brl.mod/blitz.mod/doc/new.bmx new file mode 100644 index 0000000..b4b98fb --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/new.bmx @@ -0,0 +1,27 @@ +Rem +New creates a BlitzMax variable of the Type specified. +End Rem + +Type MyType + Field a,b,c +End Type + +Local t:MyType +t=New MyType +t.a=20 + +print t.a + +' if a new method is defined for the type it will also be called + +Type MyClass + Field a,b,c + Method New() + print "Constructor invoked!" + a=10 + End Method +End Type + +Local c:MyClass +c=new MyClass +print c.a diff --git a/mod/brl.mod/blitz.mod/doc/next.bmx b/mod/brl.mod/blitz.mod/doc/next.bmx new file mode 100644 index 0000000..35964bf --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/next.bmx @@ -0,0 +1,5 @@ +Rem +Marks the end of a For section. +End Rem + +For i=1 to 5;print i;Next \ No newline at end of file diff --git a/mod/brl.mod/blitz.mod/doc/not.bmx b/mod/brl.mod/blitz.mod/doc/not.bmx new file mode 100644 index 0000000..5bd2e63 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/not.bmx @@ -0,0 +1,6 @@ +Rem +Not is a boolean unary operator that performs the NOT function. +End Rem + +Print Not 0 'prints 1 (TRUE) +Print Not 20 'prints 0 (FALSE) diff --git a/mod/brl.mod/blitz.mod/doc/null.bmx b/mod/brl.mod/blitz.mod/doc/null.bmx new file mode 100644 index 0000000..7ae1f85 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/null.bmx @@ -0,0 +1,13 @@ +Rem +Null is a BlitzMax Constant representing an empty Object reference. +End Rem + +Type mytype + Field atypevariable +End Type + +Global a:mytype + +if a=null Print "a is uninitialized" +a=new mytype +if a<>null Print "a is initialized" \ No newline at end of file diff --git a/mod/brl.mod/blitz.mod/doc/object.bmx b/mod/brl.mod/blitz.mod/doc/object.bmx new file mode 100644 index 0000000..88d16b7 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/object.bmx @@ -0,0 +1,13 @@ +Rem +Object is the base class of all BlitzMax types. + +The following function attempts to cast from any object to +the custom type TImage and returns true if the given object +is an instance of TImage or an instance of a &Type derived +from TImage. +End Rem + +Function IsImage(obj:Object) + If TImage(obj) return True + Return False +End Function diff --git a/mod/brl.mod/blitz.mod/doc/onend.bmx b/mod/brl.mod/blitz.mod/doc/onend.bmx new file mode 100644 index 0000000..2888a5a --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/onend.bmx @@ -0,0 +1,11 @@ +' onend.bmx + +Function cleanup() +Print "cleaning up" +End Function + +OnEnd cleanup +Print "program running" +End 'the cleanup function will be called at this time + + diff --git a/mod/brl.mod/blitz.mod/doc/or.bmx b/mod/brl.mod/blitz.mod/doc/or.bmx new file mode 100644 index 0000000..38e6539 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/or.bmx @@ -0,0 +1,7 @@ +Rem +Or is a boolean operator that performs the OR function. +End Rem + +For i=1 To 5 + If i=2 Or i=4 Print "!" Else Print i +Next \ No newline at end of file diff --git a/mod/brl.mod/blitz.mod/doc/pi.bmx b/mod/brl.mod/blitz.mod/doc/pi.bmx new file mode 100644 index 0000000..dca7812 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/pi.bmx @@ -0,0 +1,5 @@ +Rem +Pi is a Constant Double assigned the value 3.1415926535897932384626433832795 +End Rem + +Print "Pi="+Pi diff --git a/mod/brl.mod/blitz.mod/doc/private.bmx b/mod/brl.mod/blitz.mod/doc/private.bmx new file mode 100644 index 0000000..f00f6e5 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/private.bmx @@ -0,0 +1,12 @@ +Rem +Private makes a variable, function or method only accessible from within the +current source file. +End Rem + +Public + +Global Score,Lives,Health + +Private + +Global posx,posy,posz diff --git a/mod/brl.mod/blitz.mod/doc/protected.bmx b/mod/brl.mod/blitz.mod/doc/protected.bmx new file mode 100644 index 0000000..1bec021 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/protected.bmx @@ -0,0 +1,4 @@ +Rem +Protected +Protected makes a variable, function or method only accessible from within the current source file. +End Rem diff --git a/mod/brl.mod/blitz.mod/doc/ptr.bmx b/mod/brl.mod/blitz.mod/doc/ptr.bmx new file mode 100644 index 0000000..72813a2 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/ptr.bmx @@ -0,0 +1,20 @@ +Rem +Ptr is a composite type containing a pointer to a variable of the specified Type. +End Rem + +' the following illustrates the use of traditional c style pointers + +Local c[]=[1,2,3,4] +Local p:Int Ptr + +p=c +Print "pointer 'p' points to:"+p[0] '1 + +p:+1 +Print "pointer 'p' points to:"+p[0] '2 + +p:+1 +Print "pointer 'p' points to:"+p[0] '3 + +p:+1 +Print "pointer 'p' points to:"+p[0] '4 diff --git a/mod/brl.mod/blitz.mod/doc/public.bmx b/mod/brl.mod/blitz.mod/doc/public.bmx new file mode 100644 index 0000000..8d244d1 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/public.bmx @@ -0,0 +1,11 @@ +Rem +Public makes a variable, function or method accessible from outside the current source file (default). +End Rem + +Public + +Global Score,Lives,Health + +Private + +Global posx,posy,posz diff --git a/mod/brl.mod/blitz.mod/doc/release.bmx b/mod/brl.mod/blitz.mod/doc/release.bmx new file mode 100644 index 0000000..e75dba1 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/release.bmx @@ -0,0 +1,18 @@ +Rem +Release removes the internal reference caused by creating an integer handle to a type. +End Rem + +Type MyType + Field bigmap[1024*1024] +End Type + +GCCollect +Print GCMemAlloced() + +a=New MyType +GCCollect +Print GCMemAlloced() + +Release a +GCCollect +Print GCMemAlloced() diff --git a/mod/brl.mod/blitz.mod/doc/rem.bmx b/mod/brl.mod/blitz.mod/doc/rem.bmx new file mode 100644 index 0000000..6632905 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/rem.bmx @@ -0,0 +1,23 @@ +Rem + +My Rem Example +First created 9th August, 2004 + +(C)2050 Blitz Intergalactic Software Corporation + +End Rem + +Print "This program has no useful function" + +Rem + +Remarks are useful for making your program easily readable. +You can leave details explaining the function of your program +in a remarks section so that you and any other programmers +that work with your code can more easily understand the workings +of your program + +End Rem + +Print "Sorry." +End diff --git a/mod/brl.mod/blitz.mod/doc/repeat.bmx b/mod/brl.mod/blitz.mod/doc/repeat.bmx new file mode 100644 index 0000000..fd332b7 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/repeat.bmx @@ -0,0 +1,8 @@ +Rem +Repeat executes the following section of code until a terminating condition is true. +End Rem + +Repeat + print i + i:+1 +Until i=5 diff --git a/mod/brl.mod/blitz.mod/doc/restoredata.bmx b/mod/brl.mod/blitz.mod/doc/restoredata.bmx new file mode 100644 index 0000000..e11bc53 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/restoredata.bmx @@ -0,0 +1,11 @@ +' restoredata.bmx + +For i=1 To 5 + RestoreData mydata 'reset the data pointer everly loop so we don't read past the end + ReadData name$,age,skill + Print "name="+name+" age="+age+" skill="+skill +Next + +#mydata 'program label that can be used with the RestoreData command + +DefData "Simon",37,5000 diff --git a/mod/brl.mod/blitz.mod/doc/return.bmx b/mod/brl.mod/blitz.mod/doc/return.bmx new file mode 100644 index 0000000..e6605ef --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/return.bmx @@ -0,0 +1,17 @@ +Rem +Return exits a BlitzMax function or method with an optional value. +The type of return value is dictated by the type of the function. +End Rem + +Function CrossProduct#(x0#,y0#,z0#,x1#,y1#,z1#) + Return x0*x1+y0*y1+z0*z1 +End Function + +Print "(0,1,2)x(2,3,4)="+CrossProduct(0,1,2,2,3,4) + +Function LongRand:long() + Return (rand($80000000,$7fffffff) shl 32)|(rand($80000000,$7fffffff)) +End Function + +Print "LongRand()="+LongRand() +Print "LongRand()="+LongRand() diff --git a/mod/brl.mod/blitz.mod/doc/runtimeerror.bmx b/mod/brl.mod/blitz.mod/doc/runtimeerror.bmx new file mode 100644 index 0000000..eaf1d59 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/runtimeerror.bmx @@ -0,0 +1,3 @@ +' runtimeerror.bmx + +If a=0 RuntimeError "This program has failed badly." diff --git a/mod/brl.mod/blitz.mod/doc/sar.bmx b/mod/brl.mod/blitz.mod/doc/sar.bmx new file mode 100644 index 0000000..534ccf9 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/sar.bmx @@ -0,0 +1,9 @@ +Rem +Sar is a binary operator that performs the arithmetic shift to right function. +End Rem + +b=$f0f0f0f0 +for i=1 to 32 + print bin(b) + b=b sar 1 +next diff --git a/mod/brl.mod/blitz.mod/doc/select.bmx b/mod/brl.mod/blitz.mod/doc/select.bmx new file mode 100644 index 0000000..8ed30b1 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/select.bmx @@ -0,0 +1,18 @@ +Rem +Select begins a block featuring a sequence of multiple comparisons with a single value. +End Rem + +a=Int( Input("Enter Your Country Code ") ) + +Select a + Case 1 + Print "You are from America" + Case 44 + Print "You are from the United Kingdom" + Case 62 + Print "You are from Australia" + Case 64 + Print "You are from New Zealand" + Default + Print "I cannot tell which country you are from" +End Select diff --git a/mod/brl.mod/blitz.mod/doc/self.bmx b/mod/brl.mod/blitz.mod/doc/self.bmx new file mode 100644 index 0000000..4eb4e21 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/self.bmx @@ -0,0 +1,28 @@ +Rem +Self is used in BlitzMax Methods to reference the invoking variable. +End Rem + +Type MyClass + Global count + Field id + + Method new() + id=count + count:+1 + ClassList.AddLast(self) 'adds this new instance to a global list + End Method +End Type + +Global ClassList:TList + +classlist=new TList + +local c:MyClass + +c=new MyClass +c=new MyClass +c=new MyClass + +for c=eachin ClassList + print c.id +next diff --git a/mod/brl.mod/blitz.mod/doc/sgn.bmx b/mod/brl.mod/blitz.mod/doc/sgn.bmx new file mode 100644 index 0000000..ce4ba67 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/sgn.bmx @@ -0,0 +1,7 @@ +Rem +Sgn is a mathematical operator that returns the sign of a value. +End Rem + +Print Sgn 50 '1 +Print Sgn 0 '0 +Print Sgn -50 '-1 \ No newline at end of file diff --git a/mod/brl.mod/blitz.mod/doc/shl.bmx b/mod/brl.mod/blitz.mod/doc/shl.bmx new file mode 100644 index 0000000..8e08ad6 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/shl.bmx @@ -0,0 +1,9 @@ +Rem +Shl is a binary operator that performs the shift to left function. +End Rem + +b=1 +for i=1 to 32 + print bin(b) + b=b shl 1 +next diff --git a/mod/brl.mod/blitz.mod/doc/short.bmx b/mod/brl.mod/blitz.mod/doc/short.bmx new file mode 100644 index 0000000..5a5909c --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/short.bmx @@ -0,0 +1,9 @@ +Rem +Short is an unsigned 16 bit integer BlitzMax primitive type. +End Rem + +Local a:short + +a=65536;print "a="+a 'prints 0 +a=-1;print "a="+a 'prints 65535 + diff --git a/mod/brl.mod/blitz.mod/doc/shr.bmx b/mod/brl.mod/blitz.mod/doc/shr.bmx new file mode 100644 index 0000000..669aaf4 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/shr.bmx @@ -0,0 +1,9 @@ +Rem +Shr is a binary operator that performs the shift to right function. +End Rem + +b=-1 +for i=1 to 32 + print bin(b) + b=b shr 1 +next diff --git a/mod/brl.mod/blitz.mod/doc/sin.bmx b/mod/brl.mod/blitz.mod/doc/sin.bmx new file mode 100644 index 0000000..6eb6ca6 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/sin.bmx @@ -0,0 +1,7 @@ +Rem +Sin:Double( x:Double ) +End Rem + +for d=0 to 360 step 45 + print "Sin("+d+")="+sin(d) +next diff --git a/mod/brl.mod/blitz.mod/doc/sizeof.bmx b/mod/brl.mod/blitz.mod/doc/sizeof.bmx new file mode 100644 index 0000000..0328e99 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/sizeof.bmx @@ -0,0 +1,22 @@ +Rem +SizeOf returns the number of bytes of system memory used to store the variable. +End Rem + +Type MyType + Field a,b,c +End Type + +Local t:MyType +print sizeof t 'prints 12 + +Local f! +print sizeof f 'prints 8 + +Local i +print sizeof i 'prints 4 + +Local b:Byte +print sizeof b 'prints 1 + +a$="Hello World" +print sizeof a 'prints 22 (unicode characters take 2 bytes each) \ No newline at end of file diff --git a/mod/brl.mod/blitz.mod/doc/sortarray.bmx b/mod/brl.mod/blitz.mod/doc/sortarray.bmx new file mode 100644 index 0000000..e7efc87 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/sortarray.bmx @@ -0,0 +1,4 @@ +Rem +SortArray +Reserved for future expansion. +End Rem diff --git a/mod/brl.mod/blitz.mod/doc/sqr.bmx b/mod/brl.mod/blitz.mod/doc/sqr.bmx new file mode 100644 index 0000000..a3c6ab0 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/sqr.bmx @@ -0,0 +1,9 @@ +Rem +Square root of x +End Rem + +Function Length!(x!,y!) + return Sqr(x*x+y*y) +End Function + +Print "The length of the vector 25,3 is "+Length(25,3) diff --git a/mod/brl.mod/blitz.mod/doc/step.bmx b/mod/brl.mod/blitz.mod/doc/step.bmx new file mode 100644 index 0000000..5846ec9 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/step.bmx @@ -0,0 +1,9 @@ +Rem +Specifies an optional constant that is used to increment the For iterator. +End Rem + +' count backwards from 10 to 0 + +For i=10 to 0 step -1 + Print i +Next diff --git a/mod/brl.mod/blitz.mod/doc/strict.bmx b/mod/brl.mod/blitz.mod/doc/strict.bmx new file mode 100644 index 0000000..f0052b3 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/strict.bmx @@ -0,0 +1,9 @@ +Rem +Strict advises the BlitzMax compiler to report as errors all auto defined variables. +End Rem + +Strict + +local a=10 + +b=20 'compiler error, strict mode means variables must be declared b4 use diff --git a/mod/brl.mod/blitz.mod/doc/string.bmx b/mod/brl.mod/blitz.mod/doc/string.bmx new file mode 100644 index 0000000..cbcaa24 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/string.bmx @@ -0,0 +1,6 @@ +Rem +String is a BlitzMax container type containing a sequence of unicode characters. +End Rem + +quote:String=Chr(34) +Print quote+"Hello World!"+quote diff --git a/mod/brl.mod/blitz.mod/doc/stringfind.bmx b/mod/brl.mod/blitz.mod/doc/stringfind.bmx new file mode 100644 index 0000000..bb99eda --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/stringfind.bmx @@ -0,0 +1,6 @@ +Rem + StringFind( str$,sub$,start=0 ) +Look for a substring within a string +The index of the first instance of substring found within str, or -1 +if substring is not found +End Rem diff --git a/mod/brl.mod/blitz.mod/doc/super.bmx b/mod/brl.mod/blitz.mod/doc/super.bmx new file mode 100644 index 0000000..41a0052 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/super.bmx @@ -0,0 +1,19 @@ +Rem +Super evaluates to Self cast to the method's immediate base class. +End Rem + +Type TypeA + Method Report() + print "TypeA reporting" + End Method +End Type + +Type TypeB extends TypeA + Method Report() + Print "TypeB Reporting" + super.Report() + End Method +End Type + +b:TypeB=new TypeB +b.Report() diff --git a/mod/brl.mod/blitz.mod/doc/tan.bmx b/mod/brl.mod/blitz.mod/doc/tan.bmx new file mode 100644 index 0000000..ab31c83 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/tan.bmx @@ -0,0 +1,7 @@ +Rem +Tangent of x degrees +End Rem + +for d=0 to 360 step 45 + print "Tan("+d+")="+float(Tan(d)) +next diff --git a/mod/brl.mod/blitz.mod/doc/then.bmx b/mod/brl.mod/blitz.mod/doc/then.bmx new file mode 100644 index 0000000..d066edf --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/then.bmx @@ -0,0 +1,5 @@ +Rem +Then is an optional separator between the condition and the block of code following an If statement. +End Rem + +If 3<5 Then Print "3<5" diff --git a/mod/brl.mod/blitz.mod/doc/throw.bmx b/mod/brl.mod/blitz.mod/doc/throw.bmx new file mode 100644 index 0000000..66c1ac8 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/throw.bmx @@ -0,0 +1,13 @@ +Rem +Throw generates a BlitzMax exception. +End Rem + +Try + repeat + a:+1 + print a + if a>20 throw "chunks" + forever +Catch a$ + print "caught exception "+a$ +EndTry diff --git a/mod/brl.mod/blitz.mod/doc/to.bmx b/mod/brl.mod/blitz.mod/doc/to.bmx new file mode 100644 index 0000000..d9b2de5 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/to.bmx @@ -0,0 +1,7 @@ +Rem +Followed by a constant which is used to calculate when to exit a For..Next loop. +End Rem + +For i=1 To 5 + print i +Next diff --git a/mod/brl.mod/blitz.mod/doc/true.bmx b/mod/brl.mod/blitz.mod/doc/true.bmx new file mode 100644 index 0000000..672ee69 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/true.bmx @@ -0,0 +1,13 @@ +Rem +True is a Constant Integer assigned the value 1. +End Rem + +Print "True="+True + +If True + Print "This line will always be executed" +EndIf + +If Not True + Print "This line will never be executed" +EndIf diff --git a/mod/brl.mod/blitz.mod/doc/try.bmx b/mod/brl.mod/blitz.mod/doc/try.bmx new file mode 100644 index 0000000..a62e0aa --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/try.bmx @@ -0,0 +1,14 @@ +Rem +Begin declaration of a Try block. +End Rem + +Try + repeat + a:+1 + print a + if a>20 throw "chunks" + forever +Catch a$ + print "caught exception "+a$ +EndTry + diff --git a/mod/brl.mod/blitz.mod/doc/type.bmx b/mod/brl.mod/blitz.mod/doc/type.bmx new file mode 100644 index 0000000..2161d7f --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/type.bmx @@ -0,0 +1,17 @@ +Rem +Type marks the beginning of a BlitzMax custom type. + +Standard BlitzMax types use a preceeding "T" naming +convention to differentiate themselves from standard +BlitzMax variable names. +End Rem + +Type TVector + Field x,y,z +End Type + +Local a:TVector=new TVector + +a.x=10 +a.y=20 +a.z=30 diff --git a/mod/brl.mod/blitz.mod/doc/until.bmx b/mod/brl.mod/blitz.mod/doc/until.bmx new file mode 100644 index 0000000..3004721 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/until.bmx @@ -0,0 +1,9 @@ +Rem +Until marks the end of a Repeat block and is followed by a terminating condition. +End Rem + +i=2 +Repeat + print i + i:*2 +Until i>1000000 diff --git a/mod/brl.mod/blitz.mod/doc/var.bmx b/mod/brl.mod/blitz.mod/doc/var.bmx new file mode 100644 index 0000000..f6e6226 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/var.bmx @@ -0,0 +1,21 @@ +Rem +Var is a composite type containing a reference to a variable of the +specified Type. +End Rem + +' the following illustrates parsing function parameters by reference + +Function ReturnMultiplevalues(a Var,b Var,c Var) + a=10 + b=20 + c=30 + Return +End Function + +Local x,y,z + +ReturnMultipleValues(x,y,z) + +Print "x="+x '10 +Print "y="+y '20 +Print "z="+z '30 diff --git a/mod/brl.mod/blitz.mod/doc/varptr.bmx b/mod/brl.mod/blitz.mod/doc/varptr.bmx new file mode 100644 index 0000000..41dc92a --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/varptr.bmx @@ -0,0 +1,10 @@ +Rem +Varptr returns the address of a variable in system memory. +End Rem + +Local a:int +Local p:int ptr + +a=20 +p=varptr a +print p[0] diff --git a/mod/brl.mod/blitz.mod/doc/wend.bmx b/mod/brl.mod/blitz.mod/doc/wend.bmx new file mode 100644 index 0000000..1659455 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/wend.bmx @@ -0,0 +1,8 @@ +Rem +Wend marks the end of a While section. +End Rem + +While i<5 + print i + i:+1 +Wend \ No newline at end of file diff --git a/mod/brl.mod/blitz.mod/doc/while.bmx b/mod/brl.mod/blitz.mod/doc/while.bmx new file mode 100644 index 0000000..a6ecf81 --- /dev/null +++ b/mod/brl.mod/blitz.mod/doc/while.bmx @@ -0,0 +1,13 @@ +Rem +While executes the following section of code repeatedly while a given condition is true. +End Rem + +Graphics 640,480 +While Not KeyHit(KEY_ESCAPE) 'loop until escape key is pressed + Cls + For i=1 to 200 + DrawLine rnd(640),rnd(480),rnd(640),rnd(480) + Next + Flip +Wend + \ No newline at end of file diff --git a/mod/brl.mod/bmploader.mod/bmploader.bmx b/mod/brl.mod/bmploader.mod/bmploader.bmx new file mode 100644 index 0000000..c4f63ec --- /dev/null +++ b/mod/brl.mod/bmploader.mod/bmploader.bmx @@ -0,0 +1,134 @@ + +Strict + +Rem +bbdoc: Graphics/BMP loader +about: +The BMP loader module provides the ability to load BMP format #pixmaps. +End Rem +Module BRL.BMPLoader + +ModuleInfo "Version: 1.07" +ModuleInfo "Author: Simon Armstrong" +ModuleInfo "License: zlib/libpng" +ModuleInfo "Copyright: Blitz Research Ltd" +ModuleInfo "Modserver: BRL" + +ModuleInfo "History: 1.07 Release" +ModuleInfo "History: Added 32 bit alpha support" +ModuleInfo "History: 1.06 Release" +ModuleInfo "History: Fixed inverted 1 bit bitmaps" +ModuleInfo "History: 1.05 Release" +ModuleInfo "History: Fixed palettized bitmaps failing when biClrUsed=0" + +Import BRL.Pixmap +Import BRL.EndianStream + +Type TPixmapLoaderBMP Extends TPixmapLoader + + Method LoadPixmap:TPixmap( stream:TStream ) + + stream=LittleEndianStream( stream ) + + Local line:Int[],palette:Int[],pix:Byte[],buf:Byte[64] + Local pixmap:TPixmap + Local hsize,hoffset,pad + Local size,width,height + Local planes,bits,compression,isize,xpels,ypels,cols,inuse + Local w,x,y,c0,c1,p + + If stream.ReadBytes( buf,2 )=2 + If buf[0]=Asc("B") And buf[1]=Asc("M") + hsize=ReadInt(stream) + pad=ReadInt(stream) + hoffset=ReadInt(stream) + size=ReadInt(stream) + width=ReadInt(stream) + height=ReadInt(stream) + planes=ReadShort(stream) + bits=ReadShort(stream) + compression=ReadInt(stream) + isize=ReadInt(stream) + xpels=ReadInt(stream) + ypels=ReadInt(stream) + cols=ReadInt(stream) + inuse=ReadInt(stream) + hoffset:-54 + If Not cols cols=1 Shl bits + If bits=32 + pixmap=TPixmap.Create( width,height,PF_BGRA8888 ) + Else + pixmap=TPixmap.Create( width,height,PF_BGR888 ) + EndIf + Select bits + Case 1 + c0=ReadInt(stream) + c1=ReadInt(stream) + w=(width+7)/8 + w=(w+3)&$fffc + pix=New Byte[w] + For y=height-1 To 0 Step -1 + stream.ReadBytes(pix,w) + For x=0 Until width + If pix[x Shr 3]&(128 Shr (x&7)) + ConvertPixels(Varptr c1,PF_BGR888,pixmap.pixelptr(x,y),pixmap.format,1) + Else + ConvertPixels(Varptr c0,PF_BGR888,pixmap.pixelptr(x,y),pixmap.format,1) + EndIf + Next + Next + Case 4 + palette=New Int[16] + line=New Int[width] + stream.ReadBytes(palette,cols*4) + w=(width+1)/2 + w=(w+3)&$fffc + pix=New Byte[w] + For y=height-1 To 0 Step -1 + stream.ReadBytes(pix,w) + For x=0 Until width + p=(pix[x Shr 1]Shr((1-x&1)*4))&15 + line[x]=palette[p] + Next + ConvertPixels(line,PF_BGRA8888,pixmap.pixelptr(0,y),pixmap.format,width) + Next + Case 8 + palette=New Int[256] + line=New Int[width] + stream.ReadBytes(palette,cols*4) + w=(width+3)&$fffc + pix=New Byte[w] + For y=height-1 To 0 Step -1 + stream.ReadBytes(pix,w) + For x=0 Until width + line[x]=palette[pix[x]&255] + Next + ConvertPixels(line,PF_BGRA8888,pixmap.pixelptr(0,y),pixmap.format,width) + Next + Case 24 + w=width*3 + w=(w+3)&$fffc + pix=New Byte[w] + For y=height-1 To 0 Step -1 + stream.ReadBytes(pix,w) + ConvertPixels(pix,PF_BGR888,pixmap.pixelptr(0,y),pixmap.format,width) + Next + Case 32 + w=width*4 + pix=New Byte[w] + For y=height-1 To 0 Step -1 + stream.ReadBytes(pix,w) + ConvertPixels(pix,PF_BGRA8888,pixmap.pixelptr(0,y),pixmap.format,width) + Next + Default + pixmap=Null + End Select + Return pixmap + EndIf + EndIf + End Method + +End Type + +New TPixmapLoaderBMP + diff --git a/mod/brl.mod/d3d7max2d.mod/d3d7max2d.bmx b/mod/brl.mod/d3d7max2d.mod/d3d7max2d.bmx new file mode 100644 index 0000000..3ff8e20 --- /dev/null +++ b/mod/brl.mod/d3d7max2d.mod/d3d7max2d.bmx @@ -0,0 +1,806 @@ + +Strict + +Rem +bbdoc: Graphics/Direct3D7 Max2D +about: +The Direct3D7 Max2D module provides a Direct3D7 driver for #Max2D. +End Rem +Module BRL.D3D7Max2D + +ModuleInfo "Version: 1.19" +ModuleInfo "Author: Simon Armstrong" +ModuleInfo "License: zlib/libpng" +ModuleInfo "Copyright: Blitz Research Ltd" +ModuleInfo "Modserver: BRL" + +ModuleInfo "History: 1.19 Release" +ModuleInfo "History: Fixed/cleaned up a few things" +ModuleInfo "History: 1.18 Release" +ModuleInfo "History: Updated to work with d3d7graphics rewrite" +ModuleInfo "History: Removed buffered driver" +ModuleInfo "History: 1.17 Release" +ModuleInfo "History: Modified TD3D7Max2DDriver.SetGraphics for new dxgraphics commands" +ModuleInfo "History: 1.16 Release" +ModuleInfo "History: Fixed BufferedD3D7 vertex color errors" +ModuleInfo "History: 1.15 Release" +ModuleInfo "History: Changed DrawImage tristrip to trifan to fix subpixel cracking" +ModuleInfo "History: 1.14 Release" +ModuleInfo "History: Fixed MIPMAPPEDIMAGE flag effect on FILTEREDIMAGE setting" +ModuleInfo "History: 1.14 Release" +ModuleInfo "History: Fixed lost device from fullscreen tabbing" +ModuleInfo "History: 1.13 Release" +ModuleInfo "History: Fixed memory leak in TD3d7ImageFrame" +ModuleInfo "History: 1.12 Release" +ModuleInfo "History: Fixed default mipmap filtering for imageframes" +ModuleInfo "History: 1.11 Release" +ModuleInfo "History: Added flush to BufferedD3D7Max2DDriver for SetBlend and SetViewPort and Draw/GrabPixmap" +ModuleInfo "History: 1.10 Release" +ModuleInfo "History: Added new BufferedD3D7Max2DDriver for optimization testing" +ModuleInfo "History: 1.09 Release" +ModuleInfo "History: Replaced texture factor with vertex colors to improve compatability" +ModuleInfo "History: 1.08 Release" +ModuleInfo "History: Added GL fallback for DX device failure" +ModuleInfo "History: 1.07 Release" +ModuleInfo "History: Added line width support and tweaked line positioning" +ModuleInfo "History: 1.06 Release" +ModuleInfo "History: Added MIPMAPPEDIMAGE support" +ModuleInfo "History: 1.05 Release" +ModuleInfo "History: Added a bunch of redundant state change checks" +ModuleInfo "History: 1.04 Release" +ModuleInfo "History: Now default driver for Win32" +ModuleInfo "History: 1.03 Release" +ModuleInfo "History: Fixed negative scales" +ModuleInfo "History: 1.02 Release" +ModuleInfo "History: Fixed LIGHTBLEND" +ModuleInfo "History: Clamped alpha/color/clsColor" +ModuleInfo "History: Fixed viewport (now uses clip planes)" +ModuleInfo "History: Fixed Mag filter" + +?Win32 + +Import BRL.DXGraphics +Import BRL.GLMax2D + +Type TD3D7Max2DDriver Extends TMax2DDriver + + Field device:IDirect3DDevice7 + Field d3d7graphics:TD3D7Graphics + + Field drawalpha '0..255 + Field drawcolor + Field clscolor + Field ix#,iy#,jx#,jy# + Field linewidth# + Field cverts#[16] + Field vrts:Int Ptr'=Int Ptr(Varptr cverts[0]) + Field vp_rect[] + Field activeBlend + Field activeFrame:TD3D7ImageFrame + Field activeFrameFlags + + Method New() + vrts=Int Ptr(Varptr cverts[0]) + End Method + + Method ToString$() + Return "DirectX7" + End Method + + Method IsValid() + Return TD3D7graphicsDriver.IsValid + End Method + + Method GraphicsModes:TGraphicsMode[]() + Return D3D7GraphicsDriver().GraphicsModes() + End Method + + Method AttachGraphics:TMax2DGraphics( widget,flags ) + Local g:TD3D7Graphics=D3D7GraphicsDriver().AttachGraphics( widget,flags ) + If g Return TMax2DGraphics.Create( g,Self ) + End Method + + Method CreateGraphics:TMax2DGraphics( width,height,depth,hertz,flags ) + Local g:TD3D7Graphics=D3D7GraphicsDriver().CreateGraphics( width,height,depth,hertz,flags ) + If g Return TMax2DGraphics.Create( g,Self ) + End Method + + Method SetGraphics( g:TGraphics ) + If Not g + TMax2DGraphics.ClearCurrent + D3D7GraphicsDriver().EndScene + D3D7GraphicsDriver().SetGraphics Null + Return + EndIf + + Local t:TMax2DGraphics=TMax2DGraphics( g ) + Assert t And TD3D7Graphics( t._graphics ) + + D3D7GraphicsDriver().SetGraphics t._graphics + + ResetD3DDevice t + + t.MakeCurrent + + D3D7GraphicsDriver().BeginScene + End Method + + Method ResetD3DDevice( g:TGraphics ) + If Not IsValid() Return + + Local gw,gh,gd,gr,gf + g.GetSettings gw,gh,gd,gr,gf + + device=D3D7GraphicsDriver().Direct3DDevice7() + + Local viewport:D3DVIEWPORT7=New D3DVIEWPORT7 + viewport.dwX=0 + viewport.dwY=0 + viewport.dwWidth=gw + viewport.dwHeight=gh + viewport.dvMinZ=0.0 + viewport.dvMaxZ=1.0 + device.SetViewport(viewport) + + device.SetTexture 0,Null + + device.SetRenderState D3DRS_ALPHAREF,$80 + device.SetRenderState D3DRS_ALPHAFUNC,D3DCMP_GREATEREQUAL + device.SetRenderState D3DRS_ALPHATESTENABLE,False + device.SetRenderState D3DRS_ALPHABLENDENABLE,False + + device.SetRenderState D3DRS_LIGHTING,False + device.SetRenderState D3DRS_CULLMODE,D3DCULL_NONE + + device.SetTextureStageState 0,D3DTSS_COLOROP,D3DTOP_SELECTARG2 + device.SetTextureStageState 0,D3DTSS_COLORARG1,D3DTA_TEXTURE + device.SetTextureStageState 0,D3DTSS_COLORARG2,D3DTA_DIFFUSE + + device.SetTextureStageState 0,D3DTSS_ALPHAOP,D3DTOP_SELECTARG2 + device.SetTextureStageState 0,D3DTSS_ALPHAARG1,D3DTA_TEXTURE + device.SetTextureStageState 0,D3DTSS_ALPHAARG2,D3DTA_DIFFUSE + + device.SetTextureStageState 0,D3DTSS_ADDRESS,D3DTADDRESS_CLAMP + + device.SetTextureStageState 0,D3DTSS_MAGFILTER,D3DTFG_POINT + device.SetTextureStageState 0,D3DTSS_MINFILTER,D3DTFN_POINT + device.SetTextureStageState 0,D3DTSS_MIPFILTER,D3DTFP_POINT + + activeFrame=Null + activeFrameFlags=0 + activeBlend=SOLIDBLEND + End Method + + Method Flip( sync ) + Local seq=GraphicsSeq + Local wasValid=IsValid() + + D3D7GraphicsDriver().Flip sync + + If Not IsValid() Return + + If wasValid And seq=GraphicsSeq Return + + ResetD3DDevice TMax2DGraphics.Current() + + TMax2DGraphics.Current().Validate + End Method + + Method CreateFrameWithSize:TImageFrame( width,height,flags ) + If Not IsValid() Return + + Local frame:TD3D7ImageFrame=TD3D7ImageFrame.Create(Self,width,height,flags) + Return frame + End Method + + Method CreateFrameFromPixmap:TImageFrame( pixmap:TPixmap,flags ) + If Not IsValid() Return + + Local frame:TD3D7ImageFrame=TD3D7ImageFrame.Create(Self,pixmap.Width,pixmap.Height,flags) + Local locked:TPixmap=frame.Lock( False,True ) + locked.Paste pixmap,0,0 + frame.Unlock() + Return frame + End Method + + Method SetBlend( blend ) + If blend=activeBlend Return + activeBlend=blend + + If Not IsValid() Return + + Select activeBlend + Case SOLIDBLEND + device.SetRenderState D3DRS_ALPHATESTENABLE,False + device.SetRenderState D3DRS_ALPHABLENDENABLE,False + Case MASKBLEND + device.SetRenderState D3DRS_ALPHATESTENABLE,True + device.SetRenderState D3DRS_ALPHABLENDENABLE,False + Case ALPHABLEND + device.SetRenderState D3DRS_ALPHATESTENABLE,False + device.SetRenderState D3DRS_ALPHABLENDENABLE,True + device.SetRenderState D3DRS_SRCBLEND,D3DBLEND_SRCALPHA + device.SetRenderState D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA + Case LIGHTBLEND + device.SetRenderState D3DRS_ALPHATESTENABLE,False + device.SetRenderState D3DRS_ALPHABLENDENABLE,True + device.SetRenderState D3DRS_SRCBLEND,D3DBLEND_SRCALPHA + device.SetRenderState D3DRS_DESTBLEND,D3DBLEND_ONE + Case SHADEBLEND + device.SetRenderState D3DRS_ALPHATESTENABLE,False + device.SetRenderState D3DRS_ALPHABLENDENABLE,True + device.SetRenderState D3DRS_SRCBLEND,D3DBLEND_ZERO + device.SetRenderState D3DRS_DESTBLEND,D3DBLEND_SRCCOLOR + End Select + End Method + + Method SetAlpha( alpha# ) + alpha=Max(Min(alpha,1),0) + drawcolor=(Int(255*alpha) Shl 24)|(drawcolor&$ffffff) + vrts[3]=drawcolor + vrts[7]=drawcolor + vrts[11]=drawcolor + vrts[15]=drawcolor + End Method + + Method SetColor( red,green,blue ) + red=Max(Min(red,255),0) + green=Max(Min(green,255),0) + blue=Max(Min(blue,255),0) + drawcolor=(drawcolor&$ff000000)|(red Shl 16)|(green Shl 8)|blue + vrts[3]=drawcolor + vrts[7]=drawcolor + vrts[11]=drawcolor + vrts[15]=drawcolor + End Method + + Method SetClsColor( red,green,blue ) + red=Max(Min(red,255),0) + green=Max(Min(green,255),0) + blue=Max(Min(blue,255),0) + clscolor=$ff000000|(red Shl 16)|(green Shl 8)|blue + End Method + + Method SetViewport( x,y,width,height ) + vp_rect=[x,y,x+width,y+height] + + If Not IsValid() Return + + If x=0 And y=0 And width=GraphicsWidth() And height=GraphicsHeight() + device.SetRenderState D3DRS_CLIPPLANEENABLE,0 + Else + Local err + If device.SetClipPlane(0,[1.0,0.0,0.0,-Float(x)]) err=True + If device.SetClipPlane(1,[-1.0,0.0,0.0,Float(x+width)]) err=True + If device.SetClipPlane(2,[0.0,1.0,0.0,-Float(y)]) err=True + If device.SetClipPlane(3,[0.0,-1.0,0.0,Float(y+height)]) err=True + If err Throw "device does not support clipplanes" + device.SetRenderState D3DRS_CLIPPLANEENABLE,15 + EndIf + End Method + + Method SetTransform( xx#,xy#,yx#,yy# ) + ix=xx + iy=xy + jx=yx + jy=yy + End Method + + Method SetLineWidth( width# ) + linewidth=width + End Method + + Method Cls() + If Not IsValid() Return + + device.Clear 1,vp_rect,D3DCLEAR_TARGET,clscolor,0,0 + End Method + + Method Plot( x#,y# ) + If Not IsValid() Return + + cverts[0]=x+.5001 + cverts[1]=y+.5001 + + SetActiveFrame Null + device.DrawPrimitive(D3DPT_POINTLIST,D3DFVF_XYZ|D3DFVF_DIFFUSE,cverts,1,0) + End Method + + Method DrawLine( x0#,y0#,x1#,y1#,tx#,ty# ) + If Not IsValid() Return + + Local lx0#,ly0#,lx1#,ly1# + + lx0=x0*ix+y0*iy+tx + ly0=x0*jx+y0*jy+ty + lx1=x1*ix+y1*iy+tx + ly1=x1*jx+y1*jy+ty + + If linewidth<=1 + cverts[0]=lx0+.5001 + cverts[1]=ly0+.5001 + cverts[4]=lx1+.5001 + cverts[5]=ly1+.5001 + SetActiveFrame Null + device.DrawPrimitive(D3DPT_LINELIST,D3DFVF_XYZ|D3DFVF_DIFFUSE,cverts,2,0) + Else + Local lw#=linewidth*0.5 + If Abs(ly1-ly0)>Abs(lx1-lx0) + cverts[0]=lx0-lw + cverts[1]=ly0 + cverts[4]=lx0+lw + cverts[5]=ly0 + cverts[8]=lx1-lw + cverts[9]=ly1 + cverts[12]=lx1+lw + cverts[13]=ly1 + Else + cverts[0]=lx0 + cverts[1]=ly0-lw + cverts[4]=lx0 + cverts[5]=ly0+lw + cverts[8]=lx1 + cverts[9]=ly1-lw + cverts[12]=lx1 + cverts[13]=ly1+lw + EndIf + SetActiveFrame Null + device.DrawPrimitive(D3DPT_TRIANGLESTRIP,D3DFVF_XYZ|D3DFVF_DIFFUSE,cverts,4,0) + EndIf + End Method + + Method DrawRect( x0#,y0#,x1#,y1#,tx#,ty# ) + If Not IsValid() Return + + cverts[0]=x0*ix+y0*iy+tx + cverts[1]=x0*jx+y0*jy+ty + cverts[4]=x1*ix+y0*iy+tx + cverts[5]=x1*jx+y0*jy+ty + cverts[8]=x0*ix+y1*iy+tx + cverts[9]=x0*jx+y1*jy+ty + cverts[12]=x1*ix+y1*iy+tx + cverts[13]=x1*jx+y1*jy+ty + SetActiveFrame Null + device.DrawPrimitive(D3DPT_TRIANGLESTRIP,D3DFVF_XYZ|D3DFVF_DIFFUSE,cverts,4,0) + End Method + + Method DrawOval( x0#,y0#,x1#,y1#,tx#,ty# ) + If Not IsValid() Return + + Local xr#=(x1-x0)*.5 + Local yr#=(y1-y0)*.5 + Local segs=Abs(xr)+Abs(yr) + segs=Max(segs,12)&~3 + x0:+xr + y0:+yr + Local vrts#[]=New Float[segs*4] + Local c:Int Ptr=Int Ptr(Float Ptr(vrts)) + For Local i=0 Until segs + Local th#=-i*360#/segs + Local x#=x0+Cos(th)*xr + Local y#=y0-Sin(th)*yr + vrts[i*4+0]=x*ix+y*iy+tx + vrts[i*4+1]=x*jx+y*jy+ty + c[i*4+3]=drawcolor + Next + SetActiveFrame Null + device.DrawPrimitive(D3DPT_TRIANGLEFAN,D3DFVF_XYZ|D3DFVF_DIFFUSE,vrts,segs,0) + End Method + + Method DrawPoly( xy#[],handlex#,handley#,tx#,ty# ) + If Not IsValid() Return + + If xy.length<6 Or (xy.length&1) Return + Local segs=xy.length/2 + Local vrts#[]=New Float[segs*4] + Local c:Int Ptr=Int Ptr(Float Ptr(vrts)) + For Local i=0 Until Len xy Step 2 + Local x#=xy[i+0]+handlex + Local y#=xy[i+1]+handley + vrts[i*2+0]=x*ix+y*iy+tx + vrts[i*2+1]=x*jx+y*jy+ty + c[i*2+3]=drawcolor + Next + SetActiveFrame Null + device.DrawPrimitive(D3DPT_TRIANGLEFAN,D3DFVF_XYZ|D3DFVF_DIFFUSE,vrts,segs,0) + End Method + + Method DrawFrame( frame:TD3D7ImageFrame,x0#,y0#,x1#,y1#,tx#,ty#,sx#,sy#,sw#,sh# ) + If Not IsValid() Return + + Local u0#=sx * frame.uscale + Local v0#=sy * frame.vscale + Local u1#=(sx+sw) * frame.uscale + Local v1#=(sy+sh) * frame.vscale + frame.SetUV u0,v0,u1,v1 + + Local uv:Float Ptr + Local c:Int Ptr + uv=frame.xyzuv + c=Int Ptr(uv) + + uv[0]=x0*ix+y0*iy+tx + uv[1]=x0*jx+y0*jy+ty + c[3]=drawcolor + + uv[6]=x1*ix+y0*iy+tx + uv[7]=x1*jx+y0*jy+ty + c[9]=drawcolor + + uv[12]=x1*ix+y1*iy+tx + uv[13]=x1*jx+y1*jy+ty + c[15]=drawcolor + + uv[18]=x0*ix+y1*iy+tx + uv[19]=x0*jx+y1*jy+ty + c[21]=drawcolor + + SetActiveFrame frame + device.DrawPrimitive(D3DPT_TRIANGLEFAN,D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1,uv,4,0) + End Method + + Method DrawPixmap( pixmap:TPixmap,x,y ) + If Not IsValid() Return + + Local srcdc,destdc + Local surf:IDirectDrawSurface7 + Local renderSurf:IDirectDrawSurface7 + + D3D7GraphicsDriver().EndScene + + device.GetRenderTarget Varptr renderSurf + + renderSurf.GetDC Varptr destdc + surf=surffrompixmap( pixmap ) + surf.GetDC Varptr srcdc + BitBlt destdc,x,y,pixmap.width,pixmap.height,srcdc,0,0,ROP_SRCCOPY + surf.ReleaseDC srcdc + renderSurf.ReleaseDC destdc + surf.Release_ + + D3D7GraphicsDriver().BeginScene + End Method + + Method GrabPixmap:TPixmap( x,y,width,height ) + If Not IsValid() Return + + Local pixmap:TPixmap + Local srcdc,destdc + Local surf:IDirectDrawSurface7 + Local renderSurf:IDirectDrawSurface7 + + D3D7GraphicsDriver().EndScene + + device.GetRenderTarget Varptr renderSurf + + pixmap=TPixmap.Create( width,height,PF_BGR888 ) + renderSurf.GetDC Varptr srcdc + surf=surffrompixmap( pixmap ) + surf.GetDC Varptr destdc + BitBlt destdc,0,0,width,height,srcdc,x,y,ROP_SRCCOPY + surf.ReleaseDC destdc + renderSurf.ReleaseDC srcdc + surf.Release_() + D3D7GraphicsDriver().BeginScene + + Return pixmap + End Method + + Method SetResolution( width#,height# ) + Local gw=GraphicsWidth() + Local gh=GraphicsHeight() + Local world#[]=[.. + gw/width,0.0,0.0,0.0,.. + 0.0,gh/height,0.0,0.0,.. + 0.0,0.0,1.0,0.0,.. + 0.0,0.0,0.0,1.0 ] + device.SetTransform D3DTS_WORLD,world + Local proj#[]=[.. + 2.0/gw,0.0,0.0,0.0,.. + 0.0,-2.0/gh,0.0,0.0,.. + 0.0,0.0,1.0,0.0,.. + -1-(1.0/gw),1+(1.0/gh),1.0,1.0] + device.SetTransform D3DTS_PROJECTION,proj + End Method + + Method surffrompixmap:IDirectDrawSurface7(pixmap:TPixmap) + Local surf:IDirectDrawSurface7 + Local desc:DDSURFACEDESC2=New DDSURFACEDESC2 + Local res + + If pixmap.format=PF_I8 pixmap=pixmap.convert(PF_BGR888) + If pixmap.format=PF_A8 pixmap=pixmap.convert(PF_BGRA8888) + desc.dwSize=SizeOf(desc) + desc.dwFlags=DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT + desc.dwWidth=pixmap.width + desc.dwHeight=pixmap.height + desc.lPitch=pixmap.pitch + desc.lpSurface=pixmap.pixels + desc.ddsCaps=DDSCAPS_SYSTEMMEMORY|DDSCAPS_OFFSCREENPLAIN + desc.ddpf_dwSize=SizeOf(DDPIXELFORMAT) + Select pixmap.format + Case PF_BGR888 + desc.ddpf_dwFlags=DDPF_RGB + desc.ddpf_BitCount=24 + desc.ddpf_BitMask_0=$ff0000 + desc.ddpf_BitMask_1=$00ff00 + desc.ddpf_BitMask_2=$0000ff + Case PF_RGB888 + desc.ddpf_dwFlags=DDPF_RGB + desc.ddpf_BitCount=24 + desc.ddpf_BitMask_0=$0000ff + desc.ddpf_BitMask_1=$00ff00 + desc.ddpf_BitMask_2=$ff0000 + Case PF_BGRA8888 + desc.ddpf_dwFlags=DDPF_RGB|DDPF_ALPHAPIXELS + desc.ddpf_BitCount=32 + desc.ddpf_BitMask_0=$ff0000 + desc.ddpf_BitMask_1=$00ff00 + desc.ddpf_BitMask_2=$0000ff + desc.ddpf_BitMask_3=$ff000000 + Case PF_RGBA8888 + desc.ddpf_dwFlags=DDPF_RGB|DDPF_ALPHAPIXELS + desc.ddpf_BitCount=32 + desc.ddpf_BitMask_0=$0000ff + desc.ddpf_BitMask_1=$00ff00 + desc.ddpf_BitMask_2=$ff0000 + desc.ddpf_BitMask_3=$ff000000 + End Select + + res=D3D7GraphicsDriver().DirectDraw7().CreateSurface( desc,Varptr surf,Null ) + + If res<>DD_OK RuntimeError "D3D7Max2D Create System Surface Failed" + Return surf + End Method + + Method SetActiveFrame( frame:TD3D7ImageFrame ) + If frame=activeFrame Return + + If frame + device.SetTexture 0,frame.surface + + If Not activeFrame + device.SetTextureStageState 0,D3DTSS_COLOROP,D3DTOP_MODULATE + device.SetTextureStageState 0,D3DTSS_ALPHAOP,D3DTOP_MODULATE + EndIf + + Local flags=frame.flags & FILTEREDIMAGE + If flags<>activeFrameFlags + If flags & FILTEREDIMAGE + device.SetTextureStageState 0,D3DTSS_MAGFILTER,D3DTFG_LINEAR + device.SetTextureStageState 0,D3DTSS_MINFILTER,D3DTFG_LINEAR + device.SetTextureStageState 0,D3DTSS_MIPFILTER,D3DTFG_LINEAR + Else + device.SetTextureStageState 0,D3DTSS_MAGFILTER,D3DTFG_POINT + device.SetTextureStageState 0,D3DTSS_MINFILTER,D3DTFG_POINT + device.SetTextureStageState 0,D3DTSS_MIPFILTER,D3DTFG_POINT + EndIf + activeFrameFlags=flags + EndIf + Else + device.SetTexture 0,Null + device.SetTextureStageState 0,D3DTSS_COLOROP,D3DTOP_SELECTARG2 + device.SetTextureStageState 0,D3DTSS_ALPHAOP,D3DTOP_SELECTARG2 + EndIf + + activeFrame=frame + End Method + +End Type + +Type TD3D7ImageFrame Extends TImageFrame + + Field seq + Field driver:TD3D7Max2DDriver + Field surface:IDirectDrawSurface7 + Field sinfo:DDSurfaceDesc2 + Field xyzuv#[24] + Field width,height,flags + Field uscale#,vscale# + + Method Delete() + If Not surface Return + If seq=GraphicsSeq D3D7GraphicsDriver().DestroySurface surface + surface=Null + End Method + + Method SetUV(u0#,v0#,u1#,v1#) + xyzuv[4]=u0 + xyzuv[5]=v0 + xyzuv[10]=u1 + xyzuv[11]=v0 + xyzuv[16]=u1 + xyzuv[17]=v1 + xyzuv[22]=u0 + xyzuv[23]=v1 + End Method + + Function Create:TD3D7ImageFrame( driver:TD3D7Max2DDriver,width,height,flags ) + Function Pow2Size( n ) + Local t=1 + While tDYNAMICIMAGE desc.ddsCaps2=DDSCAPS2_TEXTUREMANAGE + + desc.ddpf_dwSize=SizeOf(DDPIXELFORMAT) + desc.ddpf_dwFlags=DDPF_RGB|DDPF_ALPHAPIXELS + desc.ddpf_BitCount=32 + desc.ddpf_BitMask_0=$ff0000 + desc.ddpf_BitMask_1=$00ff00 + desc.ddpf_BitMask_2=$0000ff + desc.ddpf_BitMask_3=$ff000000 + If flags & MIPMAPPEDIMAGE desc.ddsCaps:|DDSCAPS_MIPMAP|DDSCAPS_COMPLEX + + Local surf:IDirectDrawSurface7=D3D7GraphicsDriver().CreateSurface( desc ) + If Not surf Throw "Create DX7 surface Failed" + + Local frame:TD3D7ImageFrame=New TD3D7ImageFrame + frame.seq=GraphicsSeq + frame.driver=driver + frame.surface=surf + frame.sinfo=New DDSurfaceDesc2 + frame.sinfo.dwSize=SizeOf(frame.sinfo) + frame.xyzuv=New Float[24] + frame.width=width + frame.height=height + frame.flags=flags + frame.uscale=1.0/swidth + frame.vscale=1.0/sheight + frame.SetUV 0.0,0.0,width * frame.uscale,height * frame.vscale + Return frame + End Function + + Method Lock:TPixmap( read_lock,write_lock ) + Local lflags=DDLOCK_WAIT|DDLOCK_SURFACEMEMORYPTR + If read_lock And Not write_lock lflags:|DDLOCK_READONLY + If write_lock And Not read_lock lflags:|DDLOCK_WRITEONLY + Local res=surface.Lock(Null,sinfo,lflags,Null) + If res<>DD_OK RuntimeError "DD3D7ImageFrame Lock failed" ' Return + Return TPixmap.CreateStatic( sinfo.lpSurface,sinfo.dwWidth,sinfo.dwHeight,sinfo.lPitch,PF_BGRA8888 ) + End Method + + Method Unlock() + SmearEdges + surface.Unlock Null + If flags & MIPMAPPEDIMAGE BuildMipMaps + End Method + + Method Draw( x0#,y0#,x1#,y1#,tx#,ty#,sx#,sy#,sw#,sh# ) + driver.DrawFrame Self,x0#,y0#,x1#,y1#,tx#,ty#,sx,sy,sw,sh + End Method + + Function Mix(c0,c1) + Local c + c=((c0 Shr 1)&$7f7f7f7f)+((c1 Shr 1)&$7f7f7f7f) + c:+(c Shr 3)&$01010101 + Return c + End Function + + Method SmearEdges() + Local p:Byte Ptr + Local n,x,y,c + If width<>sinfo.dwWidth + n=1 + If flags & MIPMAPPEDIMAGE n=sinfo.dwWidth-width + For y=0 Until height + p=sinfo.lpSurface+y*sinfo.lPitch + c=Int Ptr(p)[width-1] + For x=0 Until n + Int Ptr(p)[width+x]=c + Next + Next + EndIf + If height<>sinfo.dwHeight + n=1 + If flags & MIPMAPPEDIMAGE n=sinfo.dwHeight-height + p=sinfo.lpSurface+(height-1)*sinfo.lPitch + For y=1 To n + MemCopy p+y*sinfo.lPitch,p,sinfo.dwWidth*4 + Next + EndIf + End Method + + Method BuildMipMaps() + + Type TMip + Field surf:IDirectDrawSurface7 + Field info:DDSURFACEDESC2=New DDSURFACEDESC2 + + Method Lock(srf:IDirectDrawSurface7) + surf=srf + info.dwSize=SizeOf(info) + Return surf.Lock(Null,info,DDLOCK_WAIT,0) + End Method + + Method Write(x,y,argb) + Local p:Byte Ptr + x=Min(x,info.dwWidth-1) + y=Min(y,info.dwHeight-1) + p=info.lpSurface+y*info.lPitch + Int Ptr(p)[x]=argb + End Method + + Method Read(x,y) + Local p:Byte Ptr + x=Min(x,info.dwWidth-1) + y=Min(y,info.dwHeight-1) + p=info.lpSurface+y*info.lPitch + Return Int Ptr(p)[x] + End Method + + Method Unlock() + surf.Unlock Null + End Method + + End Type + + Local caps2:DDSCAPS2 + Local src:IDirectDrawSurface7 + Local dest:IDirectDrawSurface7 + Local srcmip:TMip + Local dstmip:TMip + Local res,x,y,w,h,c0,c1,c2,c3 + + caps2=New DDSCAPS2 + caps2.dwCaps=DDSCAPS_TEXTURE + caps2.dwCaps2=DDSCAPS2_MIPMAPSUBLEVEL + srcmip=New TMip + dstmip=New TMip + src=surface + While True + res=src.GetAttachedSurface(caps2,Varptr dest) + If res Exit + res=srcmip.Lock(src) + If res RuntimeError "BuildMipMaps: lock failed" + res=dstmip.Lock(dest) + If res RuntimeError "BuildMipMaps: lock failed" + w=dstmip.info.dwWidth + h=dstmip.info.dwHeight + For y=0 Until h + For x=0 Until w + c0=srcmip.read(x*2,y*2) + c1=srcmip.read(x*2+1,y*2) + c2=srcmip.read(x*2,y*2+1) + c3=srcmip.read(x*2+1,y*2+1) + dstmip.write x,y,mix(mix(c0,c1),mix(c2,c3)) + Next + Next + srcmip.Unlock + dstmip.Unlock + dest.Release_ + src=dest + Wend + End Method +End Type + +Rem +bbdoc: Get Direct3D7 Max2D Driver +about: +The returned driver can be used with #SetGraphicsDriver to enable Direct3D Max2D rendering. +End Rem +Function D3D7Max2DDriver:TD3D7Max2DDriver() + If D3D7GraphicsDriver() + Global _driver:TD3D7Max2DDriver=New TD3D7Max2DDriver + Return _driver + EndIf +End Function + +Local driver:TD3D7Max2DDriver=D3D7Max2DDriver() +If driver SetGraphicsDriver driver diff --git a/mod/brl.mod/d3d9max2d.mod/d3d9max2d.bmx b/mod/brl.mod/d3d9max2d.mod/d3d9max2d.bmx new file mode 100644 index 0000000..bde202b --- /dev/null +++ b/mod/brl.mod/d3d9max2d.mod/d3d9max2d.bmx @@ -0,0 +1,648 @@ + +Strict + +Rem +bbdoc: Graphics/Direct3D9 Max2D +about: +The Direct3D9 Max2D module provides a Direct3D9 driver for #Max2D. +End Rem +Module BRL.D3D9Max2D + +ModuleInfo "License: zlib/libpng" +ModuleInfo "Copyright: Blitz Research Ltd" + +?Win32 + +Import BRL.Max2D +Import BRL.DXGraphics + +Import BRL.D3D7Max2D + +Const LOG_ERRS=True'False + +Private + +Global _gw,_gh,_gd,_gr,_gf +Global _color +Global _clscolor +Global _ix#,_iy#,_jx#,_jy# +Global _fverts#[24] +Global _iverts:Int Ptr=Int Ptr( Varptr _fverts[0] ) +Global _lineWidth# + +Global _bound_texture:IDirect3DTexture9 +Global _texture_enabled + +Global _active_blend + +Global _driver:TD3D9Max2DDriver +Global _d3dDev:IDirect3DDevice9 +Global _d3d9Graphics:TD3D9Graphics +Global _max2dGraphics:TMax2dGraphics + +Function Pow2Size( n ) + Local t=1 + While tPF_BGRA8888 pixmap=pixmap.Convert( PF_BGRA8888 ) + EndIf + + Local levels=(flags & MIPMAPPEDIMAGE)=0 + Local format=D3DFMT_A8R8G8B8 + Local usage=0 + Local pool=D3DPOOL_MANAGED + + If _d3dDev.CreateTexture( pow2width,pow2height,levels,usage,format,pool,_texture,Null )<0 + d3derr "Unable to create texture~n" + Return + EndIf + + _d3d9Graphics.AutoRelease _texture + + Local level + Repeat + Local dstsurf:IDirect3DSurface9 + If _texture.GetSurfaceLevel( level,dstsurf )<0 + If level=0 + d3derr "_texture.GetSurfaceLevel failed~n" + EndIf + Exit + EndIf + + Local lockedrect:D3DLOCKED_RECT=New D3DLOCKED_RECT + If dstsurf.LockRect( lockedrect,Null,0 )<0 + d3derr "dstsurf.LockRect failed~n" + EndIf + + For Local y=0 Until pixmap.height + Local src:Byte Ptr=pixmap.pixels+y*pixmap.pitch + Local dst:Byte Ptr=lockedrect.pBits+y*lockedrect.Pitch + MemCopy dst,src,pixmap.width*4 + Next + + dstsurf.UnlockRect + dstsurf.Release_ + + If (flags & MIPMAPPEDIMAGE)=0 Exit + + level:+1 + + If pixmap.width>1 And pixmap.height>1 + pixmap=ResizePixmap( pixmap,pixmap.width/2,pixmap.height/2 ) + Else If pixmap.width>1 + pixmap=ResizePixmap( pixmap,pixmap.width/2,pixmap.height ) + Else If pixmap.height>1 + pixmap=ResizePixmap( pixmap,pixmap.width,pixmap.height/2 ) + EndIf + Forever + + _uscale=1.0/pow2width + _vscale=1.0/pow2height + + Local u0#,u1#=width * _uscale + Local v0#,v1#=height * _vscale + + _fverts[4]=u0 + _fverts[5]=v0 + _fverts[10]=u1 + _fverts[11]=v0 + _fverts[16]=u1 + _fverts[17]=v1 + _fverts[22]=u0 + _fverts[23]=v1 + + If flags & FILTEREDIMAGE + _magfilter=D3DTFG_LINEAR + _minfilter=D3DTFG_LINEAR + _mipfilter=D3DTFG_LINEAR + Else + _magfilter=D3DTFG_POINT + _minfilter=D3DTFG_POINT + _mipfilter=D3DTFG_POINT + EndIf + + _seq=GraphicsSeq + + Return Self + End Method + + Method Draw( x0#,y0#,x1#,y1#,tx#,ty#,sx#,sy#,sw#,sh# ) + Local u0#=sx * _uscale + Local v0#=sy * _vscale + Local u1#=(sx+sw) * _uscale + Local v1#=(sy+sh) * _vscale + + _fverts[0]=x0*_ix+y0*_iy+tx + _fverts[1]=x0*_jx+y0*_jy+ty + _iverts[3]=_color + _fverts[4]=u0 + _fverts[5]=v0 + + _fverts[6]=x1*_ix+y0*_iy+tx + _fverts[7]=x1*_jx+y0*_jy+ty + _iverts[9]=_color + _fverts[10]=u1 + _fverts[11]=v0 + + _fverts[12]=x1*_ix+y1*_iy+tx + _fverts[13]=x1*_jx+y1*_jy+ty + _iverts[15]=_color + _fverts[16]=u1 + _fverts[17]=v1 + + _fverts[18]=x0*_ix+y1*_iy+tx + _fverts[19]=x0*_jx+y1*_jy+ty + _iverts[21]=_color + _fverts[22]=u0 + _fverts[23]=v1 + + If _texture<>_bound_texture + _d3dDev.SetTexture 0,_texture + _d3dDev.SetTextureStageState 0,D3DTSS_MAGFILTER,_magfilter + _d3dDev.SetTextureStageState 0,D3DTSS_MINFILTER,_minfilter + _d3dDev.SetTextureStageState 0,D3DTSS_MIPFILTER,_mipfilter + _bound_texture=_texture + EndIf + + If Not _texture_enabled + _d3dDev.SetTextureStageState 0,D3DTSS_COLOROP,D3DTOP_MODULATE + _d3dDev.SetTextureStageState 0,D3DTSS_ALPHAOP,D3DTOP_MODULATE + _texture_enabled=True + EndIf + + _d3dDev.DrawPrimitiveUP D3DPT_TRIANGLEFAN,2,_fverts,24 + End Method + + Field _texture:IDirect3DTexture9,_seq + + Field _magfilter,_minfilter,_mipfilter,_uscale#,_vscale# + + Field _fverts#[24],_iverts:Int Ptr=Int Ptr( Varptr _fverts[0] ) + +End Type + +Type TD3D9Max2DDriver Extends TMax2dDriver + + Method ToString$() + Return "DirectX9" + End Method + + Method Create:TD3D9Max2DDriver() + If Not D3D9GraphicsDriver() Return Null + + Local d3d:IDirect3D9=D3D9GraphicsDriver().GetDirect3D() + + If d3d.CheckDeviceFormat( D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,D3DFMT_X8R8G8B8,0,D3DRTYPE_TEXTURE,D3DFMT_A8R8G8B8 )<0 + Return Null + EndIf + + Return Self + End Method + + '***** TGraphicsDriver ***** + Method GraphicsModes:TGraphicsMode[]() + Return D3D9GraphicsDriver().GraphicsModes() + End Method + + Method AttachGraphics:TGraphics( widget,flags ) + Local g:TD3D9Graphics=D3D9GraphicsDriver().AttachGraphics( widget,flags ) + If g Return TMax2DGraphics.Create( g,Self ) + End Method + + Method CreateGraphics:TGraphics( width,height,depth,hertz,flags ) + Local g:TD3D9Graphics=D3D9GraphicsDriver().CreateGraphics( width,height,depth,hertz,flags ) + If Not g Return Null + Return TMax2DGraphics.Create( g,Self ) + End Method + + Method SetGraphics( g:TGraphics ) + If Not g + If _d3dDev + _d3dDev.EndScene + _d3dDev=Null + EndIf + _d3d9graphics=Null + _max2dGraphics=Null + TMax2DGraphics.ClearCurrent + D3D9GraphicsDriver().SetGraphics Null + Return + EndIf + + _max2dGraphics=TMax2dGraphics( g ) + + _d3d9graphics=TD3D9Graphics( _max2dGraphics._graphics ) + + Assert _max2dGraphics And _d3d9graphics + + _d3dDev=_d3d9Graphics.GetDirect3DDevice() + + D3D9GraphicsDriver().SetGraphics _d3d9Graphics + + If _d3dDev.TestCooperativeLevel()<>D3D_OK Return + + ResetDevice + + _max2dGraphics.MakeCurrent + + End Method + + Method Flip( sync ) + _d3dDev.EndScene + If D3D9GraphicsDriver().Flip( sync ) + _d3dDev.BeginScene + Else If _d3dDev.TestCooperativeLevel()=D3D_OK + ResetDevice + _max2dGraphics.MakeCurrent + EndIf + + End Method + + Method ResetDevice() + + _d3d9graphics.ValidateSize + _d3d9graphics.GetSettings _gw,_gh,_gd,_gr,_gf + + Local viewport:D3DVIEWPORT9=New D3DVIEWPORT9 + viewport.X=0 + viewport.Y=0 + viewport.Width=_gw + viewport.Height=_gh + viewport.MinZ=0.0 + viewport.MaxZ=1.0 + _d3dDev.SetViewport viewport + + _d3dDev.SetRenderState D3DRS_ALPHAREF,$80 + _d3dDev.SetRenderState D3DRS_ALPHAFUNC,D3DCMP_GREATEREQUAL + + _d3dDev.SetRenderState D3DRS_ALPHATESTENABLE,False + _d3dDev.SetRenderState D3DRS_ALPHABLENDENABLE,False + _active_blend=SOLIDBLEND + + _d3dDev.SetRenderState D3DRS_LIGHTING,False + _d3dDev.SetRenderState D3DRS_CULLMODE,D3DCULL_NONE + + _d3dDev.SetTexture 0,Null + _bound_texture=Null + + _d3dDev.SetFVF D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1 + + _d3dDev.SetTextureStageState 0,D3DTSS_COLORARG1,D3DTA_TEXTURE + _d3dDev.SetTextureStageState 0,D3DTSS_COLORARG2,D3DTA_DIFFUSE + _d3dDev.SetTextureStageState 0,D3DTSS_COLOROP,D3DTOP_SELECTARG2 + _d3dDev.SetTextureStageState 0,D3DTSS_ALPHAARG1,D3DTA_TEXTURE + _d3dDev.SetTextureStageState 0,D3DTSS_ALPHAARG2,D3DTA_DIFFUSE + _d3dDev.SetTextureStageState 0,D3DTSS_ALPHAOP,D3DTOP_SELECTARG2 + _texture_enabled=False + + _d3dDev.SetTextureStageState 0,D3DTSS_ADDRESS,D3DTADDRESS_CLAMP + + _d3dDev.SetTextureStageState 0,D3DTSS_MAGFILTER,D3DTFG_POINT + _d3dDev.SetTextureStageState 0,D3DTSS_MINFILTER,D3DTFN_POINT + _d3dDev.SetTextureStageState 0,D3DTSS_MIPFILTER,D3DTFP_POINT + + _d3dDev.BeginScene + + End Method + + '***** TMax2DDriver ***** + Method CreateFrameFromPixmap:TImageFrame( pixmap:TPixmap,flags ) + Return New TD3D9ImageFrame.Create( pixmap,flags ) + End Method + + Method SetBlend( blend ) + If blend=_active_blend Return + Select blend + Case SOLIDBLEND + _d3dDev.SetRenderState D3DRS_ALPHATESTENABLE,False + _d3dDev.SetRenderState D3DRS_ALPHABLENDENABLE,False + Case MASKBLEND + _d3dDev.SetRenderState D3DRS_ALPHATESTENABLE,True + _d3dDev.SetRenderState D3DRS_ALPHABLENDENABLE,False + Case ALPHABLEND + _d3dDev.SetRenderState D3DRS_ALPHATESTENABLE,False + _d3dDev.SetRenderState D3DRS_ALPHABLENDENABLE,True + _d3dDev.SetRenderState D3DRS_SRCBLEND,D3DBLEND_SRCALPHA + _d3dDev.SetRenderState D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA + Case LIGHTBLEND + _d3dDev.SetRenderState D3DRS_ALPHATESTENABLE,False + _d3dDev.SetRenderState D3DRS_ALPHABLENDENABLE,True + _d3dDev.SetRenderState D3DRS_SRCBLEND,D3DBLEND_SRCALPHA + _d3dDev.SetRenderState D3DRS_DESTBLEND,D3DBLEND_ONE + Case SHADEBLEND + _d3dDev.SetRenderState D3DRS_ALPHATESTENABLE,False + _d3dDev.SetRenderState D3DRS_ALPHABLENDENABLE,True + _d3dDev.SetRenderState D3DRS_SRCBLEND,D3DBLEND_ZERO + _d3dDev.SetRenderState D3DRS_DESTBLEND,D3DBLEND_SRCCOLOR + End Select + _active_blend=blend + End Method + + Method SetAlpha( alpha# ) + alpha=Max(Min(alpha,1),0) + _color=(Int(255*alpha) Shl 24)|(_color&$ffffff) + _iverts[3]=_color + _iverts[9]=_color + _iverts[15]=_color + _iverts[21]=_color + End Method + + Method SetColor( red,green,blue ) + red=Max(Min(red,255),0) + green=Max(Min(green,255),0) + blue=Max(Min(blue,255),0) + _color=(_color&$ff000000)|(red Shl 16)|(green Shl 8)|blue + _iverts[3]=_color + _iverts[9]=_color + _iverts[15]=_color + _iverts[21]=_color + End Method + + Method SetClsColor( red,green,blue ) + red=Max(Min(red,255),0) + green=Max(Min(green,255),0) + blue=Max(Min(blue,255),0) + _clscolor=$ff000000|(red Shl 16)|(green Shl 8)|blue + End Method + + Method SetViewport( x,y,width,height ) + If x=0 And y=0 And width=_gw And height=_gh 'GraphicsWidth() And height=GraphicsHeight() + _d3dDev.SetRenderState D3DRS_SCISSORTESTENABLE,False + Else + _d3dDev.SetRenderState D3DRS_SCISSORTESTENABLE,True + Local rect[]=[x,y,x+width,y+height] + _d3dDev.SetScissorRect rect + EndIf + End Method + + Method SetTransform( xx#,xy#,yx#,yy# ) + _ix=xx + _iy=xy + _jx=yx + _jy=yy + End Method + + Method SetLineWidth( width# ) + _lineWidth=width + End Method + + Method Cls() + _d3dDev.Clear 0,Null,D3DCLEAR_TARGET,_clscolor,0,0 + End Method + + Method Plot( x#,y# ) + _fverts[0]=x+.5 + _fverts[1]=y+.5 + DisableTex + _d3dDev.DrawPrimitiveUP D3DPT_POINTLIST,1,_fverts,24 + End Method + + Method DrawLine( x0#,y0#,x1#,y1#,tx#,ty# ) + Local lx0# = x0*_ix + y0*_iy + tx + Local ly0# = x0*_jx + y0*_jy + ty + Local lx1# = x1*_ix + y1*_iy + tx + Local ly1# = x1*_jx + y1*_jy + ty + If _lineWidth<=1 + _fverts[0]=lx0+.5 + _fverts[1]=ly0+.5 + _fverts[6]=lx1+.5 + _fverts[7]=ly1+.5 + DisableTex + _d3dDev.DrawPrimitiveUP D3DPT_LINELIST,1,_fverts,24 + Return + EndIf + Local lw#=_lineWidth*.5 + If Abs(ly1-ly0)>Abs(lx1-lx0) + _fverts[0]=lx0-lw + _fverts[1]=ly0 + _fverts[6]=lx0+lw + _fverts[7]=ly0 + _fverts[12]=lx1-lw + _fverts[13]=ly1 + _fverts[18]=lx1+lw + _fverts[19]=ly1 + Else + _fverts[0]=lx0 + _fverts[1]=ly0-lw + _fverts[6]=lx0 + _fverts[7]=ly0+lw + _fverts[12]=lx1 + _fverts[13]=ly1-lw + _fverts[18]=lx1 + _fverts[19]=ly1+lw + EndIf + DisableTex + _d3dDev.DrawPrimitiveUP D3DPT_TRIANGLESTRIP,2,_fverts,24 + End Method + + Method DrawRect( x0#,y0#,x1#,y1#,tx#,ty# ) + _fverts[0] = x0*_ix + y0*_iy + tx + _fverts[1] = x0*_jx + y0*_jy + ty + _fverts[6] = x1*_ix + y0*_iy + tx + _fverts[7] = x1*_jx + y0*_jy + ty + _fverts[12] = x0*_ix + y1*_iy + tx + _fverts[13] = x0*_jx + y1*_jy + ty + _fverts[18] = x1*_ix + y1*_iy + tx + _fverts[19] = x1*_jx + y1*_jy + ty + DisableTex + _d3dDev.DrawPrimitiveUP D3DPT_TRIANGLESTRIP,2,_fverts,24 + End Method + + Method DrawOval( x0#,y0#,x1#,y1#,tx#,ty# ) + Local xr#=(x1-x0)*.5 + Local yr#=(y1-y0)*.5 + Local segs=Abs(xr)+Abs(yr) + segs=Max(segs,12)&~3 + x0:+xr + y0:+yr + Local fverts#[segs*6] + Local iverts:Int Ptr=Int Ptr( Varptr fverts[0] ) + For Local i=0 Until segs + Local th#=-i*360#/segs + Local x#=x0+Cos(th)*xr + Local y#=y0-Sin(th)*yr + fverts[i*6+0]=x*_ix+y*_iy+tx + fverts[i*6+1]=x*_jx+y*_jy+ty + iverts[i*6+3]=_color + Next + DisableTex + _d3dDev.DrawPrimitiveUP D3DPT_TRIANGLEFAN,segs-2,fverts,24 + End Method + + Method DrawPoly( verts#[],handlex#,handley#,tx#,ty# ) + If verts.length<6 Or (verts.length&1) Return + Local segs=verts.length/2 + Local fverts#[segs*6] + Local iverts:Int Ptr=Int Ptr( Varptr fverts[0] ) + For Local i=0 Until segs + Local x#=verts[i*2+0]+handlex + Local y#=verts[i*2+1]+handley + fverts[i*6+0]= x*_ix + y*_iy + tx + fverts[i*6+1]= x*_jx + y*_jy + ty + iverts[i*6+3]=_color + Next + DisableTex + _d3dDev.DrawPrimitiveUP D3DPT_TRIANGLEFAN,segs-2,fverts,24 + End Method + + 'GetDC/BitBlt MUCH faster than locking backbuffer! + Method DrawPixmap( pixmap:TPixmap,x,y ) + Local width=pixmap.width,height=pixmap.height + + Local dstsurf:IDirect3DSurface9 + If _d3dDev.GetRenderTarget( 0,dstsurf )<0 + d3derr "GetRenderTarget failed~n" + Return + EndIf + + Local desc:D3DSURFACE_DESC=New D3DSURFACE_DESC + If dstsurf.GetDesc( desc )<0 + d3derr "GetDesc failed~n" + EndIf + + Local rect[]=[x,y,x+width,y+height] + Local lockedrect:D3DLOCKED_RECT=New D3DLOCKED_RECT + If dstsurf.LockRect( lockedrect,rect,0 )<0 + d3derr "Unable to lock render target surface~n" + dstsurf.Release_ + Return + EndIf + + Local dstpixmap:TPixmap=CreateStaticPixmap( lockedrect.pBits,width,height,lockedrect.Pitch,PF_BGRA8888 ); + + dstpixmap.Paste pixmap,0,0 + + dstsurf.UnlockRect + dstsurf.Release_ + End Method + + 'GetDC/BitBlt MUCH faster than locking backbuffer! + Method GrabPixmap:TPixmap( x,y,width,height ) + + Local srcsurf:IDirect3DSurface9 + If _d3dDev.GetRenderTarget( 0,srcsurf )<0 + d3derr "GetRenderTarget failed~n" + EndIf + + Local dstsurf:IDirect3DSurface9 + If _d3dDev.CreateOffscreenPlainSurface( width,height,D3DFMT_X8R8G8B8,D3DPOOL_SYSTEMMEM,dstsurf,Null )<0 + d3derr "CreateOffscreenPlainSurface failed~n" + EndIf + + Local srcdc:Byte Ptr + If srcsurf.GetDC( srcdc )<0 + d3derr "srcsurf.GetDC failed~n" + EndIf + + Local dstdc:Byte Ptr + If dstsurf.GetDC( dstdc )<0 + d3derr "dstsurf.GetDC failed~n" + EndIf + + BitBlt Int(dstdc),0,0,width,height,Int(srcdc),x,y,ROP_SRCCOPY + + srcsurf.ReleaseDC srcdc + dstsurf.ReleaseDC dstdc + + Local lockedrect:D3DLOCKED_RECT=New D3DLOCKED_RECT + If dstsurf.LockRect( lockedrect,Null,D3DLOCK_READONLY )<0 + d3derr "dstsurf.LockRect failed~n" + EndIf + + Local pixmap:TPixmap=CreatePixmap( width,height,PF_BGRA8888 ) + + 'Copy and set alpha in the process... + For Local y=0 Until height + Local src:Int Ptr=Int Ptr( lockedrect.pBits+y*lockedrect.Pitch ) + Local dst:Int Ptr=Int Ptr( pixmap.PixelPtr( 0,y ) ) + For Local x=0 Until width + dst[x]=src[x] | $ff000000 + Next + Next + + srcsurf.Release_ + dstsurf.Release_ + + Return pixmap + End Method + + Method SetResolution( width#,height# ) + Local matrix#[]=[.. + 2.0/width,0.0,0.0,0.0,.. + 0.0,-2.0/height,0.0,0.0,.. + 0.0,0.0,1.0,0.0,.. + -1-(1.0/width),1+(1.0/height),1.0,1.0] + + _d3dDev.SetTransform D3DTS_PROJECTION,matrix + End Method + +End Type + +Rem +bbdoc: Get Direct3D9 Max2D Driver +about: +The returned driver can be used with #SetGraphicsDriver to enable Direct3D9 Max2D rendering. +End Rem +Function D3D9Max2DDriver:TD3D9Max2DDriver() + Global _done + If Not _done + _driver=New TD3D9Max2DDriver.Create() + _done=True + EndIf + Return _driver +End Function + +Local driver:TD3D9Max2DDriver=D3D9Max2DDriver() +If driver SetGraphicsDriver driver + +? diff --git a/mod/brl.mod/data.mod/data.bmx b/mod/brl.mod/data.mod/data.bmx new file mode 100644 index 0000000..6961149 --- /dev/null +++ b/mod/brl.mod/data.mod/data.bmx @@ -0,0 +1,12 @@ + +Strict + +Module BRL.Data + +ModuleInfo "Version: 1.02" +ModuleInfo "Author: Mark Sibly" +ModuleInfo "License: zlib/libpng" +ModuleInfo "Copyright: Blitz Research Ltd" +ModuleInfo "Modserver: BRL" + +ModuleInfo "History: Deprecated!!!!!" diff --git a/mod/brl.mod/directsoundaudio.mod/directsoundaudio.bmx b/mod/brl.mod/directsoundaudio.mod/directsoundaudio.bmx new file mode 100644 index 0000000..8610ff8 --- /dev/null +++ b/mod/brl.mod/directsoundaudio.mod/directsoundaudio.bmx @@ -0,0 +1,340 @@ + +Strict + +Rem +bbdoc: Audio/DirectSound audio +about: +The DirectSound audio module provides DirectSound drivers for use with the #audio module. +End Rem +Module BRL.DirectSoundAudio + +ModuleInfo "Version: 1.05" +ModuleInfo "Author: Mark Sibly" +ModuleInfo "License: zlib/libpng" +ModuleInfo "Copyright: Blitz Research Ltd" +ModuleInfo "Modserver: BRL" + +ModuleInfo "History: 1.05 Release" +ModuleInfo "History: Added hardware caps checking" +ModuleInfo "History: 1.04 Release" +ModuleInfo "History: First batch of fixes!" +ModuleInfo "History: 1.02 Release" +ModuleInfo "History: Added volume,pan,rate states to channel" +ModuleInfo "History: 1.01 Initial Release" + +?Win32 + +Import BRL.Math +Import BRL.Audio +Import Pub.DirectX + +Private + +Const CLOG=False + +Global _driver:TDirectSoundAudioDriver + +Type TBuf + Field _succ:TBuf + Field _buffer:IDirectSoundBuffer,_seq,_paused + + Method Playing() + If _paused Return False + Local status + DSASS _buffer.GetStatus( status ) + Return (status & DSBSTATUS_PLAYING)<>0 + End Method + + Method Active() + If _paused Return True + Local status + DSASS _buffer.GetStatus( status ) + Return (status & DSBSTATUS_PLAYING)<>0 + End Method + +End Type + +Function DSASS( n,t$="DirectSound" ) + If n>=0 Return + Throw t+" failed ("+(n & 65535)+")" +End Function + +Public + +Type TDirectSoundSound Extends TSound + + Method Delete() + If _seq=_driver._seq + _driver.AddLonely _bufs + EndIf + End Method + + Method Play:TDirectSoundChannel( alloced_channel:TChannel=Null ) + Local t:TDirectSoundChannel=Cue( alloced_channel ) + t.SetPaused False + Return t + End Method + + Method Cue:TDirectSoundChannel( alloced_channel:TChannel=Null ) + Local t:TDirectSoundChannel=TDirectSoundChannel( alloced_channel ) + If t + Assert t._static + Else + t=TDirectSoundChannel.Create( False ) + EndIf + t.Cue Self + Return t + End Method + + Function Create:TDirectSoundSound( sample:TAudioSample,flags ) + _driver.FlushLonely + + Select sample.format + Case SF_MONO16BE + sample=sample.Convert( SF_MONO16LE ) + Case SF_STEREO16BE + sample=sample.Convert( SF_STEREO16LE ) + End Select + + GCSuspend + + Local length=sample.length + Local hertz=sample.hertz + Local format=sample.format + Local chans=ChannelsPerSample[format] + Local bps=BytesPerSample[format]/chans + Local size=length*chans*bps + + Local fmt:WAVEFORMATEX=New WAVEFORMATEX + fmt.wFormatTag=1 + fmt.nChannels=chans + fmt.nSamplesPerSec=hertz + fmt.wBitsPerSample=bps*8 + fmt.nBlockAlign=fmt.wBitsPerSample/8*fmt.nChannels + fmt.nAvgBytesPerSec=fmt.nSamplesPerSec*fmt.nBlockAlign + + Local desc:DSBUFFERDESC=New DSBUFFERDESC + desc.dwSize=SizeOf(DSBUFFERDESC) + desc.dwFlags=DSBCAPS_GLOBALFOCUS|DSBCAPS_STATIC|DSBCAPS_CTRLPAN|DSBCAPS_CTRLVOLUME|DSBCAPS_CTRLFREQUENCY + If _driver._mode=1 Or (flags & 2)<>2 desc.dwFlags:|DSBCAPS_LOCSOFTWARE + desc.dwBufferBytes=size + desc.lpwfxFormat=fmt + + Local buf:IDirectSoundBuffer + DSASS _driver._dsound.CreateSoundBuffer( desc,buf,Null ),"CreateSoundBuffer" + If CLOG WriteStdout "Created DirectSound buffer~n" + + Local ptr1:Byte Ptr,bytes1,ptr2:Byte Ptr,bytes2 + DSASS buf.Lock( 0,size,ptr1,bytes1,ptr2,bytes2,0 ),"Lock SoundBuffer" + MemCopy ptr1,sample.samples,size + DSASS buf.Unlock( ptr1,bytes1,ptr2,bytes2 ),"Unlock SoundBuffer" + + Local t:TDirectSoundSound=New TDirectSoundSound + t._seq=_driver._seq + t._buffer=buf + t._hertz=hertz + t._loop=flags & 1 + t._bufs=New TBuf + t._bufs._buffer=buf + + GCResume + + Return t + End Function + + Field _seq,_buffer:IDirectSoundBuffer,_hertz,_loop,_bufs:TBuf + +End Type + +Type TDirectSoundChannel Extends TChannel + + Method Delete() + If Not _buf Or _seq<>_buf._seq Return + If _buf._paused Stop + End Method + + Method Stop() + If Not _buf Or _seq<>_buf._seq Return + _buf._buffer.Stop + _buf._paused=False + _buf._seq:+1 + _buf=Null + End Method + + Method SetPaused( paused ) + If Not _buf Or _seq<>_buf._seq Return + If Not _buf.Active() + _buf._seq:+1 + _buf=Null + Return + EndIf + If paused + _buf._buffer.Stop + Else + _buf._buffer.Play 0,0,_playFlags + EndIf + _buf._paused=paused + End Method + + Method SetVolume( volume# ) + volume=Min(Max(volume,0),1)^.1 + _volume=volume + If Not _buf Or _seq<>_buf._seq Return + _buf._buffer.SetVolume (1-volume)*-10000 + End Method + + Method SetPan( pan# ) + pan=Min(Max(pan,-1),1) + pan=Sgn(pan) * (1-(1-Abs(pan))^.1) + _pan=pan + If Not _buf Or _seq<>_buf._seq Return + _buf._buffer.SetPan pan*10000 + End Method + + Method SetDepth( depth# ) + If Not _buf Or _seq<>_buf._seq Return + End Method + + Method SetRate( rate# ) + _rate=rate + If Not _buf Or _seq<>_buf._seq Return + _buf._buffer.SetFrequency _hertz * rate + End Method + + Method Playing() + If Not _buf Or _seq<>_buf._seq Return + Return _buf.Playing() + End Method + + Method Cue( sound:TDirectSoundSound ) + Stop + Local t:TBuf=sound._bufs + While t + If Not t.Active() + t._seq:+1 + Exit + EndIf + t=t._succ + Wend + If Not t + _driver.FlushLonely + Local buf:IDirectSoundBuffer + If _driver._dsound.DuplicateSoundBuffer( sound._buffer,buf )<0 Return False + If CLOG WriteStdout "Duplicated DirectSound buffer~n" + t=New TBuf + t._buffer=buf + t._succ=sound._bufs + sound._bufs=t + EndIf + _sound=sound + _buf=t + _seq=_buf._seq + _hertz=sound._hertz + If sound._loop _playFlags=DSBPLAY_LOOPING Else _playFlags=0 + _buf._paused=True + _buf._buffer.SetCurrentPosition 0 + _buf._buffer.SetVolume (1-_volume)*-10000 + _buf._buffer.SetPan _pan * 10000 + _buf._buffer.SetFrequency _hertz * _rate + Return True + End Method + + Function Create:TDirectSoundChannel( static ) + Local t:TDirectSoundChannel=New TDirectSoundChannel + t._static=static + Return t + End Function + + Field _volume#=1,_pan#=0,_rate#=1,_static + Field _sound:TSound,_buf:TBuf,_seq,_hertz,_playFlags + +End Type + +Type TDirectSoundAudioDriver Extends TAudioDriver + + Method Name$() + Return _name + End Method + + Method Startup() + If DirectSoundCreate( Null,_dsound,Null )>=0 + If _dsound.SetCooperativeLevel( GetDesktopWindow(),DSSCL_PRIORITY )>=0 + Rem + 'Never seen this succeed! + 'Apparently a NOP on Win2K/XP/Vista, and + 'probably best not to mess with it on Win98 anyway. + Global primBuf:IDirectSoundBuffer + Local desc:DSBUFFERDESC=New DSBUFFERDESC + desc.dwSize=SizeOf(DSBUFFERDESC) + desc.dwFlags=DSBCAPS_PRIMARYBUFFER + If _dsound.CreateSoundBuffer( desc,primBuf,Null )>=0 + Local fmt:WAVEFORMATEX=New WAVEFORMATEX + fmt.wFormatTag=1 + fmt.nChannels=2 + fmt.wBitsPerSample=16 + fmt.nSamplesPerSec=44100 + fmt.nBlockAlign=fmt.wBitsPerSample/8*fmt.nChannels + fmt.nAvgBytesPerSec=fmt.nSamplesPerSec*fmt.nBlockAlign + primBuf.SetFormat fmt + primBuf.Release_ + EndIf + End Rem + _driver=Self + Return True + EndIf + _dsound.Release_ + EndIf + End Method + + Method Shutdown() + _seq:+1 + _driver=Null + _lonely=Null + _dsound.Release_ + End Method + + Method CreateSound:TDirectSoundSound( sample:TAudioSample,flags ) + Return TDirectSoundSound.Create( sample,flags ) + End Method + + Method AllocChannel:TDirectSoundChannel() + Return TDirectSoundChannel.Create( True ) + End Method + + Function Create:TDirectSoundAudioDriver( name$,mode ) + Local t:TDirectSoundAudioDriver=New TDirectSoundAudioDriver + t._name=name + t._mode=mode + Return t + End Function + + Method AddLonely( bufs:TBuf ) + Local t:TBuf=bufs + While t._succ + t=t._succ + Wend + t._succ=_lonely + _lonely=bufs + End Method + + Method FlushLonely() + Local t:TBuf=_lonely,p:TBuf + While t + If t.Active() + p=t + Else + t._buffer.Release_ + If CLOG WriteStdout "Released DirectSound buffer~n" + If p p._succ=t._succ Else _lonely=t._succ + EndIf + t=t._succ + Wend + End Method + + Field _name$,_mode,_dsound:IDirectSound,_lonely:TBuf + + Global _seq + +End Type + +If DirectSoundCreate TDirectSoundAudioDriver.Create "DirectSound",0 diff --git a/mod/brl.mod/dxgraphics.mod/d3d7graphics.bmx b/mod/brl.mod/dxgraphics.mod/d3d7graphics.bmx new file mode 100644 index 0000000..3e99f37 --- /dev/null +++ b/mod/brl.mod/dxgraphics.mod/d3d7graphics.bmx @@ -0,0 +1,611 @@ + +Strict + +Import BRL.Graphics +Import BRL.LinkedList + +Import Pub.DirectX + +Private + +Extern + +Global _bbusew + +End Extern + +Const DLOG_ENABLED=False + +Const DDERR=$88760000 + +Const DDERR_OK=0 +Const DDERR_PRIMARYSURFACEALREADYEXISTS=DDERR|564 +Const DDERR_WRONGMODE=DDERR|587 +Const DDERR_NOEXCLUSIVEMODE=DDERR|225 +Const DDERR_EXCLUSIVEMODEALREADYSET=DDERR|581 +Const DDERR_UNSUPPORTEDMODE=DDERR|590 +Const DDERR_SURFACELOST=DDERR|450 + +Type TD3D7Surface + Field surf:IDirectDrawSurface7 +End Type + +Global _driver:TD3D7GraphicsDriver +Global _wndClass:Byte Ptr="BBDX7Device Window Class".ToCString() +Global _wndClassW:Short Ptr="BBDX7Device Window Class".ToWString() + +Function dderrstr$( code ) + Select code + Case DDERR_OK Return "OK" + Case DDERR_PRIMARYSURFACEALREADYEXISTS Return "PRIMARYSURFACEALREADYEXISTS" + Case DDERR_WRONGMODE Return "WRONGMODE" + Case DDERR_NOEXCLUSIVEMODE Return "NOEXCLUSIVEMODE" + Case DDERR_EXCLUSIVEMODEALREADYSET Return "EXCLUSIVEMODEALREADYSET" + Case DDERR_UNSUPPORTEDMODE Return "UNSUPPORTEDMODE" + Case DDERR_SURFACELOST Return "SURFACELOST" + End Select +' Return "UNKNOWN:"+Hex( code )+" "+(code & 65535) + Return "UNKNOWN:"+( code )+" "+(code & 65535) +End Function + +Function dlog( t$ ) + If Not DLOG_ENABLED Return + WriteStdout t+"~n" +End Function + +Function WndProc( hwnd,message,wp,lp ) "win32" + bbSystemEmitOSEvent hwnd,message,wp,lp,Null + + Select message + Case WM_CLOSE + Return + Case WM_SYSKEYDOWN + If wp<>KEY_F4 Return + Case WM_SETFOCUS + dlog "WM_SETFOCUS" + _driver.ValidateGraphics + Case WM_KILLFOCUS + dlog "WM_KILLFOCUS" + _driver.ValidateGraphics + End Select + + If _bbusew Return DefWindowProcW( hwnd,message,wp,lp ) + Return DefWindowProcA( hwnd,message,wp,lp ) + +End Function + +Function EnumModesCallback( desc:Byte Ptr,context:Object ) "win32" + Local p:Int Ptr=Int Ptr(desc) + Local t:TGraphicsMode=New TGraphicsMode + t.width=p[3] + t.height=p[2] + t.depth=p[21] + t.hertz=p[6] + If t.depth>=16 TList(context).AddLast t + Return D3DENUMRET_OK +End Function + +Function DXASS( n,msg$="DXERROR" ) + If n>=0 Return + WriteStdout msg+" err="+dderrstr( n )+"~n" +?Debug + DebugStop +? + End +End Function + +Function FindMode:TGraphicsMode( width,height,depth,hertz,modes:TGraphicsMode[] ) + Local mode:TGraphicsMode,md=$7fff + For Local t:TGraphicsMode=EachIn modes + If width=t.width And height=t.height And depth=t.depth + Local d=Abs(hertz-t.hertz) + If d=0 _renderSurf.Unlock Null + + If _depth + Local flags + If Not sync flags=DDFLIP_NOVSYNC + _primSurf.Flip Null,flags + Else + Local src[]=[0,0,_width,_height] + Local dest[]=[0,0,_width,_height] + ClientToScreen _hwnd,dest + dest[2]:+dest[0] + dest[3]:+dest[1] + If sync dd7.WaitForVerticalBlank DDWAITVB_BLOCKBEGIN,0 + _primSurf.SetClipper( _clipper ) + _primSurf.Blt( dest,_renderSurf,src,0,Null ) + _primSurf.SetClipper( Null ) + EndIf + End Method + + Method RenderSurface:IDirectDrawSurface7() + ValidateSize + Return _renderSurf + End Method + + Method CreateRenderSurface:IDirectDrawSurface7() + Local dd7:IDirectDraw7=_driver.DirectDraw7() + + If _depth + DXASS dd7.SetCooperativeLevel( _hwnd,DDSCL_FULLSCREEN|DDSCL_EXCLUSIVE|DDSCL_ALLOWREBOOT|DDSCL_FPUPRESERVE ) + DXASS dd7.SetDisplayMode( _width,_height,_depth,_hertz,0 ) + + Local desc:DDSURFACEDESC2=New DDSURFACEDESC2 + desc.dwSize=SizeOf(desc) + desc.dwFlags=DDSD_CAPS|DDSD_BACKBUFFERCOUNT + desc.ddsCaps=DDSCAPS_PRIMARYSURFACE|DDSCAPS_COMPLEX|DDSCAPS_FLIP|DDSCAPS_3DDEVICE + desc.dwBackBufferCount=1 + + DXASS dd7.CreateSurface( desc,Varptr _primSurf,Null ) + + Local caps:DDSCAPS2=New DDSCAPS2 + caps.dwCaps=DDSCAPS_BACKBUFFER + + DXASS _primSurf.GetAttachedSurface( caps,Varptr _renderSurf ) + Else + If _primSurf + _primSurf.AddRef + Else + Local desc:DDSURFACEDESC2=New DDSURFACEDESC2 + desc.dwSize=SizeOf(desc) + desc.dwFlags=DDSD_CAPS + desc.ddsCaps=DDSCAPS_PRIMARYSURFACE + DXASS dd7.CreateSurface( desc,Varptr _primSurf,Null ) + EndIf + + Local desc:DDSURFACEDESC2=New DDSURFACEDESC2 + desc.dwSize=SizeOf(desc) + desc.dwFlags=DDSD_WIDTH|DDSD_HEIGHT|DDSD_CAPS + desc.dwWidth=_width + desc.dwHeight=_height + desc.ddsCaps=DDSCAPS_OFFSCREENPLAIN|DDSCAPS_3DDEVICE + dlog "CreateRenderSurface _width="+_width+" _height="+_height + DXASS dd7.CreateSurface( desc,Varptr _renderSurf,Null ) + DXASS dd7.CreateClipper( 0,Varptr _clipper,Null ) + DXASS _clipper.SetHWnd( 0,_hwnd ) + EndIf + _primRefs:+1 + Return _renderSurf + End Method + + Method DestroyRenderSurface() + If _clipper + dlog "_clipper.Release_="+_clipper.Release_() + _clipper=Null + EndIf + If _renderSurf + dlog "_renderSurf.Release_="+_renderSurf.Release_() + _renderSurf=Null + EndIf + If _primSurf + dlog "_primSurf.Release_="+_primSurf.Release_() + _primRefs:-1 + If Not _primRefs _primSurf=Null + EndIf + End Method + + Function Attach:TD3D7Graphics( hwnd,flags ) + Local rect[4] + GetClientRect( hwnd,rect ) + Local t:TD3D7Graphics=New TD3D7Graphics + t._hwnd=hwnd + t._width=rect[2] + t._height=rect[3] + t._flags=flags + Return t + End Function + + Function Create:TD3D7Graphics( width,height,depth,hertz,flags ) + Global _reg + If Not _reg + If _bbusew + Local wc:WNDCLASSW=New WNDCLASSW + wc.hInstance=GetModuleHandleA( Null ) + wc.lpfnWndProc=WndProc + wc.hCursor=LoadCursorA( Null,Byte Ptr IDC_ARROW ) + wc.lpszClassName=_wndClassW + RegisterClassW( wc ) + _reg=True + Else + Local wc:WNDCLASS=New WNDCLASS + wc.hInstance=GetModuleHandleA( Null ) + wc.lpfnWndProc=WndProc + wc.hCursor=LoadCursorA( Null,Byte Ptr IDC_ARROW ) + wc.lpszClassName=_wndClass + RegisterClassA( wc ) + _reg=True + EndIf + EndIf + + Local hinst=GetModuleHandleA( Null ) + Local title:Byte Ptr=AppTitle.ToCString() + + Local titleW$=AppTitle + Local _wndClassW$=String.FromCString( _wndClass ) + + Local hwnd + + If depth + If _bbusew + hwnd=CreateWindowExW( 0,_wndClassW,titleW,WS_VISIBLE|WS_POPUP,0,0,width,height,0,0,hinst,Null ) + Else + hwnd=CreateWindowExA( 0,_wndClass,title,WS_VISIBLE|WS_POPUP,0,0,width,height,0,0,hinst,Null ) + EndIf + Else + Local style=WS_VISIBLE|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX + Local rect[]=[32,32,width+32,height+32] + + Local desktopHWND:Int=GetDesktopWindow() + Local desktopRect:Int[]=New Int[4] + GetWindowRect( desktopHWND,desktopRect) + + rect[0]=desktopRect[2]/2-width/2; + rect[1]=desktopRect[3]/2-height/2; + rect[2]=rect[0]+width; + rect[3]=rect[1]+height; + + AdjustWindowRect rect,style,0 + If _bbusew + hwnd=CreateWindowExW( 0,_wndClassW,titleW,style,rect[0],rect[1],rect[2]-rect[0],rect[3]-rect[1],0,0,hinst,Null ) + Else + hwnd=CreateWindowExA( 0,_wndClass,title,style,rect[0],rect[1],rect[2]-rect[0],rect[3]-rect[1],0,0,hinst,Null ) + EndIf + GetClientRect hwnd,rect + width=rect[2]-rect[0] + height=rect[3]-rect[1] + EndIf + + MemFree title + + If Not hwnd Return + + Local t:TD3D7Graphics=New TD3D7Graphics + t._hwnd=hwnd + t._width=width + t._height=height + t._depth=depth + t._hertz=hertz + t._flags=flags + Return t + End Function + + Method ValidateSize() + If _depth Return + Local rect[4] + GetClientRect _hwnd,rect + Local width=rect[2],height=rect[3] + If width<=0 Or height<=0 Return + If width=_width And height=_height Return + dlog "Size invalidated" + DestroyRenderSurface + _width=width + _height=height + End Method + + Field _width,_height,_depth,_hertz,_flags + + Field _hwnd + Field _clipper:IDirectDrawClipper + Field _renderSurf:IDirectDrawSurface7 + + Global _primSurf:IDirectDrawSurface7,_primRefs + +End Type + +Type TD3D7GraphicsDriver Extends TGraphicsDriver + + Method GraphicsModes:TGraphicsMode[]() + Return _modes + End Method + + Method AttachGraphics:TD3D7Graphics( hwnd,flags ) + If _n_fullscreen Return + Local g:TD3D7graphics=TD3D7Graphics.Attach( hwnd,flags ) + If g _n_graphics:+1 + _graphicss.AddLast g + Return g + End Method + + Method CreateGraphics:TD3D7Graphics( width,height,depth,hertz,flags ) + If _n_fullscreen Return + If depth + If _n_graphics Return + Local mode:TGraphicsMode=BestMode( width,height,depth,hertz,_modes ) + If Not mode Return + depth=mode.depth + hertz=mode.hertz + EndIf + Local g:TD3D7Graphics=TD3D7Graphics.Create( width,height,depth,hertz,flags ) + If Not g Return + _graphicss.AddLast g + If depth _n_fullscreen:+1 + _n_graphics:+1 + Return g + End Method + + 'Internal use only... + Method CloseGraphics( g:TD3D7Graphics ) + If _n_graphics=1 + _Destroy + Else + g.DestroyRenderSurface + EndIf + _graphicss.Remove g + If g=_graphics + _graphics=Null + IsValid=False + EndIf + _n_graphics:-1 + _n_fullscreen=0 + End Method + + Method SetGraphics( g:TGraphics ) + _graphics=TD3D7Graphics( g ) + ValidateGraphics True + End Method + + Method Graphics:TD3D7Graphics() + Return _graphics + End Method + + Method Flip( sync ) + If IsValid + If _inScene _d3ddev7.EndScene + _graphics.Flip sync + EndIf + ValidateGraphics True + End Method + + Method DirectDraw7:IDirectDraw7() + Return _dd7 + End Method + + Method Direct3D7:IDirect3D7() + Return _d3d7 + End Method + + Method Direct3DDevice7:IDirect3DDevice7() + Return _d3ddev7 + End Method + + Method BeginScene() + _inScene=True + If IsValid _d3ddev7.BeginScene + End Method + + Method EndScene() + If IsValid _d3ddev7.EndScene + _inScene=False + End Method + + Method CreateSurface:IDirectDrawSurface7( desc:DDSURFACEDESC2 ) + Local surf:IDirectDrawSurface7 + Local err=_dd7.CreateSurface( desc,Varptr surf,Null ) + If err<0 + dlog "CreateSurface failed:"+dderrstr(err) + Return Null + EndIf + Local t:TD3D7Surface=New TD3D7Surface + t.surf=surf + _surfaces.AddLast t + dlog "CreateSurface OK" + Return surf + End Method + + Method DestroySurface( surf:IDirectDrawSurface7 ) + For Local t:TD3D7Surface=EachIn _surfaces + If t.surf<>surf Continue + dlog "Destroy surface="+surf.Release_() + _surfaces.Remove t + Return + Next + End Method + + Method _ValidateGraphics() + If Not _graphics Return False + + Local coop + + If _dd7 + coop=_dd7.TestCooperativeLevel() + If coop=DDERR_WRONGMODE + dlog "DDERR_WRONGMODE" + _Destroy + EndIf + EndIf + + If Not _dd7 + If Not _Create() Return False + coop=_dd7.TestCooperativeLevel() + EndIf + + If coop<0 Return False + + Local renderSurf:IDirectDrawSurface7=_graphics.RenderSurface() + If renderSurf + If renderSurf.IsLost()<0 + DXASS _dd7.RestoreAllSurfaces() + EndIf + DXASS _d3ddev7.SetRenderTarget( renderSurf,0 ) + Else + renderSurf=_graphics.CreateRenderSurface() + If _d3ddev7 + DXASS _d3ddev7.SetRenderTarget( renderSurf,0 ) + Else + If _d3d7.CreateDevice( IID_IDirect3DTnLDevice,renderSurf,Varptr _d3ddev7 )<0 + DXASS _d3d7.CreateDevice( IID_IDirect3DHALDevice,renderSurf,Varptr _d3ddev7 ) + EndIf + EndIf + EndIf + + Return True + + End Method + + Method ValidateGraphics( force=False ) + Global _busy + If _busy + dlog "busy: Valid="+IsValid + Return IsValid + EndIf + _busy=True + + Local valid=IsValid + If valid Or force valid=_ValidateGraphics() + + If valid<>IsValid + dlog "Valid="+valid + If valid And _inScene _d3ddev7.BeginScene() + EndIf + + IsValid=valid + + _busy=False + Return IsValid + End Method + + Function Create:TD3D7GraphicsDriver() + If _driver Return _driver + + _driver=New TD3D7GraphicsDriver._Create() + If Not _driver Return + + Local mlist:TList=New TList + _driver._dd7.EnumDisplayModes( DDEDM_REFRESHRATES,Null,mlist,EnumModesCallback ) + Local i + _driver._modes=New TGraphicsMode[mlist.Count()] + For Local mode:TGraphicsMode=EachIn mlist + _driver._modes[i]=mode + i:+1 + Next + + _driver._Destroy + Return _driver + End Function + + Method _Create:TD3D7GraphicsDriver() + + If Not DirectDrawCreateEx Return Null + + If DirectDrawCreateEx( Null,Varptr _dd7,IID_IDirectDraw7,Null )<0 Return _Destroy() + + If _dd7.SetCooperativeLevel( 0,DDSCL_NORMAL|DDSCL_FPUPRESERVE )<0 Return _Destroy() + + Local caps:DDCAPS_DX7=New DDCAPS_DX7 + caps.dwSize=SizeOf( DDCAPS_DX7 ) + If _dd7.GetCaps( caps,Null )<0 Return _Destroy() + If Not (caps.dwCaps & DDCAPS_3D) Return _Destroy() + + If _dd7.QueryInterface( IID_IDirect3D7,Byte Ptr Ptr(Varptr _d3d7) )<0 Return _Destroy() + + BumpGraphicsSeq + + dlog "_Created" + + Return Self + End Method + + Method _Destroy:TD3D7GraphicsDriver() + + dlog "_Destroying" + + BumpGraphicsSeq + + 'have to destroy device before renderSurfs or crash in fullscreen + If _d3ddev7 _d3ddev7.Release_ + + For Local t:TD3D7Surface=EachIn _surfaces + dlog "Destroy surface="+t.surf.Release_() + Next + + For Local t:TD3D7Graphics=EachIn _graphicss + t.DestroyRenderSurface + Next + + If _d3d7 _d3d7.Release_ + + If _dd7 dlog "Release dd7="+_dd7.Release_() + + _dd7=Null + _d3d7=Null + _d3ddev7=Null + _surfaces.Clear + + Return Null + End Method + + Global IsValid + + Field _modes:TGraphicsMode[] + + Field _dd7:IDirectDraw7 + Field _d3d7:IDirect3D7 + Field _d3ddev7:IDirect3DDevice7 + + Field _graphics:TD3D7Graphics + Field _n_graphics,_n_fullscreen,_inScene + + Field _surfaces:TList=New TList + Field _graphicss:TList=New TList + +End Type + +Function D3D7GraphicsDriver:TD3D7GraphicsDriver() + Return TD3D7GraphicsDriver.Create() +End Function + diff --git a/mod/brl.mod/dxgraphics.mod/d3d9graphics.bmx b/mod/brl.mod/dxgraphics.mod/d3d9graphics.bmx new file mode 100644 index 0000000..faae08a --- /dev/null +++ b/mod/brl.mod/dxgraphics.mod/d3d9graphics.bmx @@ -0,0 +1,380 @@ + +Strict + +Import BRL.Graphics + +Import Pub.DirectX + +Import BRL.LinkedList + + +Private + +Global _wndClass$="BBDX9Device Window Class" + +Global _driver:TD3D9graphicsDriver + +Global _d3d:IDirect3D9 +Global _d3dCaps:D3DCAPS9 +Global _modes:TGraphicsMode[] + +Global _d3dDev:IDirect3DDevice9 +Global _d3dDevRefs + +Global _presentParams:D3DPRESENT_PARAMETERS + +Global _graphics:TD3D9Graphics + +Global _autoRelease:TList + +Type TD3D9AutoRelease + Field unk:IUnknown +End Type + +Function D3D9WndProc( hwnd,msg,wp,lp ) "win32" + + bbSystemEmitOSEvent hwnd,msg,wp,lp,Null + + Select msg + Case WM_CLOSE + Return + Case WM_SYSKEYDOWN + If wp<>KEY_F4 Return + End Select + + Return DefWindowProcW( hwnd,msg,wp,lp ) + +End Function + +Function OpenD3DDevice( hwnd,width,height,depth,hertz,flags ) + + If _d3dDevRefs + If Not _presentParams.Windowed Return False + If depth<>0 Return False + _d3dDevRefs:+1 + Return True + EndIf + + Local windowed=(depth=0) + Local fullscreen=(depth<>0) + + Local pp:D3DPRESENT_PARAMETERS=New D3DPRESENT_PARAMETERS + pp.BackBufferWidth=width + pp.BackBufferHeight=height + pp.BackBufferCount=1 + pp.BackBufferFormat=(D3DFMT_X8R8G8B8 * fullscreen) + (D3DFMT_UNKNOWN * windowed) + pp.MultiSampleType=D3DMULTISAMPLE_NONE + pp.SwapEffect=(D3DSWAPEFFECT_DISCARD * fullscreen) + (D3DSWAPEFFECT_COPY * windowed) + pp.hDeviceWindow=hwnd + pp.Windowed=windowed + pp.Flags=D3DPRESENTFLAG_LOCKABLE_BACKBUFFER + pp.FullScreen_RefreshRateInHz=(hertz * fullscreen) + pp.PresentationInterval=D3DPRESENT_INTERVAL_ONE 'IMMEDIATE + + Local cflags=D3DCREATE_FPU_PRESERVE + + 'OK, try hardware vertex processing... + Local tflags=D3DCREATE_PUREDEVICE|D3DCREATE_HARDWARE_VERTEXPROCESSING|cflags + If _d3d.CreateDevice( 0,D3DDEVTYPE_HAL,hwnd,tflags,pp,_d3dDev )<0 + + 'Failed! Try mixed vertex processing... + tflags=D3DCREATE_MIXED_VERTEXPROCESSING|cflags + If _d3d.CreateDevice( 0,D3DDEVTYPE_HAL,hwnd,tflags,pp,_d3dDev )<0 + + 'Failed! Try software vertex processing... + tflags=D3DCREATE_SOFTWARE_VERTEXPROCESSING|cflags + If _d3d.CreateDevice( 0,D3DDEVTYPE_HAL,hwnd,tflags,pp,_d3dDev )<0 + + 'Failed! Go home and watch family guy instead... + Return False + EndIf + EndIf + EndIf + + _presentParams=pp + + _d3dDevRefs:+1 + + _autoRelease=New TList + + Return True +End Function + +Function CloseD3DDevice() + _d3dDevRefs:-1 + If Not _d3dDevRefs + + For Local t:TD3D9AutoRelease=EachIn _autoRelease + t.unk.Release_ + Next + _autoRelease=Null + + _d3dDev.Release_ + _d3dDev=Null + _presentParams=Null + EndIf +End Function + +Function ResetD3DDevice() + If _d3dDev.Reset( _presentParams )<0 + Throw "_d3dDev.Reset failed" + EndIf + +End Function + +Public + +Type TD3D9Graphics Extends TGraphics + + Method Attach:TD3D9Graphics( hwnd,flags ) + Local rect[4] + GetClientRect hwnd,rect + Local width=rect[2]-rect[0] + Local height=rect[3]-rect[1] + + OpenD3DDevice hwnd,width,height,0,0,flags + + _hwnd=hwnd + _width=width + _height=height + _flags=flags + _attached=True + Return Self + End Method + + Method Create:TD3D9Graphics( width,height,depth,hertz,flags ) + Local wstyle + + If depth + wstyle=WS_VISIBLE|WS_POPUP + Else + wstyle=WS_VISIBLE|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX + EndIf + + Local rect[4] + + If Not depth + Local desktopRect[4] + GetWindowRect GetDesktopWindow(),desktopRect + + rect[0]=desktopRect[2]/2-width/2; + rect[1]=desktopRect[3]/2-height/2; + rect[2]=rect[0]+width; + rect[3]=rect[1]+height; + + AdjustWindowRect rect,wstyle,0 + EndIf + + Local hwnd=CreateWindowExW( 0,_wndClass,AppTitle,wstyle,rect[0],rect[1],rect[2]-rect[0],rect[3]-rect[1],0,0,GetModuleHandleA(Null),Null ) + If Not hwnd Return Null + + If Not depth + GetClientRect hwnd,rect + width=rect[2]-rect[0] + height=rect[3]-rect[1] + EndIf + + If Not OpenD3DDevice( hwnd,width,height,depth,hertz,flags ) + DestroyWindow hwnd + Return Null + EndIf + + _hwnd=hwnd + _width=width + _height=height + _depth=depth + _hertz=hertz + _flags=flags + + Return Self + End Method + + Method GetDirect3DDevice:IDirect3DDevice9() + Return _d3dDev + End Method + + Method ValidateSize() + If _attached + Local rect[4] + GetClientRect _hwnd,rect + _width=rect[2]-rect[0] + _height=rect[3]-rect[1] + If _width>_presentParams.BackBufferWidth Or _height>_presentParams.BackBufferHeight + _presentParams.BackBufferWidth=Max( _width,_presentParams.BackBufferWidth ) + _presentParams.BackBufferHeight=Max( _height,_presentParams.BackbufferHeight ) + ResetD3DDevice + EndIf + EndIf + End Method + + 'NOTE: Returns 1 if flip was successful, otherwise device lost or reset... + Method Flip( sync ) + + Local reset + + If sync sync=D3DPRESENT_INTERVAL_ONE Else sync=D3DPRESENT_INTERVAL_IMMEDIATE + If sync<>_presentParams.PresentationInterval + _presentParams.PresentationInterval=sync + reset=True + EndIf + + Select _d3dDev.TestCooperativeLevel() + Case D3D_OK + If reset + + ResetD3DDevice + + Else If _attached + + Local rect[]=[0,0,_width,_height] + Return _d3dDev.Present( rect,rect,_hwnd,Null )>=0 + + Else + + Return _d3dDev.Present( Null,Null,_hwnd,Null )>=0 + + EndIf + Case D3DERR_DEVICENOTRESET + + ResetD3DDevice + + End Select + + + End Method + + Method Driver:TGraphicsDriver() + Return _driver + End Method + + Method GetSettings( width Var,height Var,depth Var,hertz Var,flags Var ) + ' + ValidateSize + ' + width=_width + height=_height + depth=_depth + hertz=_hertz + flags=_flags + End Method + + Method Close() + If Not _hwnd Return + CloseD3DDevice + If Not _attached DestroyWindow( _hwnd ) + _hwnd=0 + End Method + + Method AutoRelease( unk:IUnknown ) + Local t:TD3D9AutoRelease=New TD3D9AutoRelease + t.unk=unk + _autoRelease.AddLast t + End Method + + Method ReleaseNow( unk:IUnknown ) + For Local t:TD3D9AutoRelease=EachIn _autoRelease + If t.unk=unk + unk.Release_ + _autoRelease.Remove t + Return + EndIf + Next + End Method + + + Field _hwnd + Field _width + Field _height + Field _depth + Field _hertz + Field _flags + Field _attached + +End Type + +Type TD3D9GraphicsDriver Extends TGraphicsDriver + + Method Create:TD3D9GraphicsDriver() + + 'create d3d9 + If Not d3d9Lib Return + + _d3d=Direct3DCreate9( 32 ) + If Not _d3d Return Null + + 'get caps + _d3dCaps=New D3DCAPS9 + If _d3d.GetDeviceCaps( D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,_d3dCaps )<0 + _d3d.Release_ + _d3d=Null + Return Null + EndIf + + 'enum graphics modes + Local n=_d3d.GetAdapterModeCount( D3DADAPTER_DEFAULT,D3DFMT_X8R8G8B8 ) + _modes=New TGraphicsMode[n] + Local j + For Local i=0 Until n + Local d3dmode:D3DDISPLAYMODE=New D3DDISPLAYMODE + + If _d3d.EnumAdapterModes( D3DADAPTER_DEFAULT,D3DFMT_X8R8G8B8,i,d3dmode )<0 + Continue + EndIf + + Local mode:TGraphicsMode=New TGraphicsMode + mode.width=d3dmode.Width + mode.height=d3dmode.Height + mode.hertz=d3dmode.RefreshRate + mode.depth=32 + + _modes[j]=mode + j:+1 + Next + _modes=_modes[..j] + + 'register wndclass + Local wndclass:WNDCLASSW=New WNDCLASSW + wndclass.hInstance=GetModuleHandleW( Null ) + wndclass.lpfnWndProc=D3D9WndProc + wndclass.hCursor=LoadCursorW( Null,Short Ptr IDC_ARROW ) + wndclass.lpszClassName=_wndClass.ToWString() + RegisterClassW wndclass + MemFree wndclass.lpszClassName + + Return Self + End Method + + Method GraphicsModes:TGraphicsMode[]() + Return _modes + End Method + + Method AttachGraphics:TD3D9Graphics( widget,flags ) + Return New TD3D9Graphics.Attach( widget,flags ) + End Method + + Method CreateGraphics:TD3D9Graphics( width,height,depth,hertz,flags ) + Return New TD3D9Graphics.Create( width,height,depth,hertz,flags ) + End Method + + Method SetGraphics( g:TGraphics ) + _graphics=TD3D9Graphics( g ) + End Method + + Method Flip( sync ) + Return _graphics.Flip( sync ) + End Method + + Method GetDirect3D:IDirect3D9() + Return _d3d + End Method + +End Type + +Function D3D9GraphicsDriver:TD3D9GraphicsDriver() + Global _done + If Not _done + _driver=New TD3D9GraphicsDriver.Create() + _done=True + EndIf + Return _driver +End Function diff --git a/mod/brl.mod/dxgraphics.mod/dxgraphics.bmx b/mod/brl.mod/dxgraphics.mod/dxgraphics.bmx new file mode 100644 index 0000000..0cf6263 --- /dev/null +++ b/mod/brl.mod/dxgraphics.mod/dxgraphics.bmx @@ -0,0 +1,74 @@ + +Strict + +Module BRL.DXGraphics + +ModuleInfo "Version: 1.30" +ModuleInfo "Author: Simon Armstrong, Mark Sibly" +ModuleInfo "License: zlib/libpng" +ModuleInfo "Copyright: Blitz Research Ltd" +ModuleInfo "Modserver: BRL" + +ModuleInfo "History: 1.30 Release" +ModuleInfo "History: Adjusted graphics size after creating window" +ModuleInfo "History: 1.29 Release" +ModuleInfo "History: d3d7graphics render ahead hack now in fullscreen too" +ModuleInfo "History: 1.28 Release" +ModuleInfo "History: Fixed bad beginScene logic when graphics restored" +ModuleInfo "History: 1.27 Release" +ModuleInfo "History: Fixed incorrect GraphicsWidth()/GraphicsHeight() in d3d7" +ModuleInfo "History: driver due to no more (well, fewer) redundant size validations" +ModuleInfo "History: 1.26 Release" +ModuleInfo "History: Fixed resizing window bug and seq bug" +ModuleInfo "History: 1.25 Release" +ModuleInfo "History: Fixed fullscreen graphics mode failing if depth/hertz not exact" +ModuleInfo "History: 1.24 Release" +ModuleInfo "History: Fixed multiple primary surfaces issue" +ModuleInfo "History: 1.23 Release" +ModuleInfo "History: Rewrote d3d7graphics" +ModuleInfo "History: 1.22 Release" +ModuleInfo "History: Fixed d3d7graphics reset" +ModuleInfo "History: 1.21 Release" +ModuleInfo "History: Fixed d3d7graphics device enumeration" +ModuleInfo "History: 1.20 Release" +ModuleInfo "History: Fixed windowed Graphics not closing due to 1.19 fix" +ModuleInfo "History: 1.19 Release" +ModuleInfo "History: Fixed crash closing an unused TD3D7Graphics context" +ModuleInfo "History: 1.18 Release" +ModuleInfo "History: Fixed TD3D7GraphicsDriver to close on FreeGraphics" +ModuleInfo "History: Windowed graphics origin now matches glgraphics" +ModuleInfo "History: 1.17 Release" +ModuleInfo "History: Fixed TD3D7GraphicsDriver to not close on FreeCanvas" +ModuleInfo "History: 1.16 Release" +ModuleInfo "History: Fixed render ahead lag with flip waitlocking on previous flip" +ModuleInfo "History: 1.15 Release" +ModuleInfo "History: Fixed windowed mode flips ignoring sync" +ModuleInfo "History: 1.14 Release" +ModuleInfo "History: Fixed GetSettings ignoring depth/hertz/flags" +ModuleInfo "History: 1.13 Release" +ModuleInfo "History: Fixed unhandled exception with multiple SetGraphics" +ModuleInfo "History: 1.11 Release" +ModuleInfo "History: Changed TD3D7GraphicsDriver.CreateGraphics returns Null instead of Throw on failure" +ModuleInfo "History: 1.10 Release" +ModuleInfo "History: Changed Asserts to Ifs" +ModuleInfo "History: 1.09 Release" +ModuleInfo "History: Fixed CanvasGraphics closing the primary device" +ModuleInfo "History: 1.08 Release" +ModuleInfo "History: Fixed multiple WNDCLASS registrations" +ModuleInfo "History: 1.07 Release" +ModuleInfo "History: D3D7 looks for TnL device first" +ModuleInfo "History: 1.06 Release" +ModuleInfo "History: Added D3D7 FPU preserve flag to SetCooperativeLevel" +ModuleInfo "History: 1.05 Release" +ModuleInfo "History: Fixed d3d7 fullscreen failing with strange hertz" +ModuleInfo "History: 1.04 Release" +ModuleInfo "History: Added AppTitle support" +ModuleInfo "History: 1.03 Release" +ModuleInfo "History: Fixed EnumDisplayModes returning swapped depth<->hertz" +ModuleInfo "History: 1.02 Release" +ModuleInfo "History: Fixed D3D7 mouse capture in 'windowed' fullscreen mode" + +?Win32 +Import "d3d7graphics.bmx" +Import "d3d9graphics.bmx" +? diff --git a/mod/brl.mod/endianstream.mod/doc/intro.bbdoc b/mod/brl.mod/endianstream.mod/doc/intro.bbdoc new file mode 100644 index 0000000..4848e17 --- /dev/null +++ b/mod/brl.mod/endianstream.mod/doc/intro.bbdoc @@ -0,0 +1,21 @@ +Endian streams allow you to swap the byte order of stream data.
+
+This can be useful for reading or writing binary streams which are in a fixed endian format on multiple platforms.
+
+Endian format refers to the order multi-byte values are stored. For example, an integer is four bytes long, but in what order should each byte be stored? Low byte first or high byte first?
+
+This choice is generally dictated by the CPU. For example, Intel CPU's such as the pentium store multi-byte values 'low byte first' which is known as little endian. On the other hand, PowerPC CPU's store multi-byte values 'high byte first' which is known as big endian.
+
+Most of the time, you don't have to worry about endian issues. As long as the same endian format is being used to read and write data, there is no problem. However, endian issues do need to be taken into account when reading or writing binary files. For example, writing a binary file on a PC (which is little endian) and reading it back on a Mac (which is big endian) may produce odd results if the file contains multibyte values.
+
+Endian streams help solve this problem by modifying the behaviour of stream commands that read or write multi-byte values. These commands are: +ReadShort, +ReadInt, +ReadLong, +ReadFloat, +ReadDouble, +WriteShort, +WriteInt, +WriteLong, +WriteFloat and +WriteDouble. diff --git a/mod/brl.mod/endianstream.mod/endianstream.bmx b/mod/brl.mod/endianstream.mod/endianstream.bmx new file mode 100644 index 0000000..95e79fa --- /dev/null +++ b/mod/brl.mod/endianstream.mod/endianstream.bmx @@ -0,0 +1,156 @@ + +Strict + +Rem +bbdoc: Streams/Endian streams +End Rem +Module BRL.EndianStream + +ModuleInfo "Version: 1.01" +ModuleInfo "Author: Mark Sibly" +ModuleInfo "License: zlib/libpng" +ModuleInfo "Copyright: Blitz Research Ltd" +ModuleInfo "Modserver: BRL" + +Import BRL.Stream + +Type TXEndianStream Extends TStreamWrapper + + Method Swap2( buf:Byte Ptr ) + Local t + t=buf[0];buf[0]=buf[1];buf[1]=t + End Method + + Method Swap4( buf:Byte Ptr ) + Local t + t=buf[0];buf[0]=buf[3];buf[3]=t + t=buf[1];buf[1]=buf[2];buf[2]=t + End Method + + Method Swap8( buf:Byte Ptr ) + Local t + t=buf[0];buf[0]=buf[7];buf[7]=t + t=buf[1];buf[1]=buf[6];buf[6]=t + t=buf[2];buf[2]=buf[5];buf[5]=t + t=buf[3];buf[3]=buf[4];buf[4]=t + End Method + + Method ReadShort() + Local q:Short + ReadBytes Varptr q,2 + Swap2 Varptr q + Return q + End Method + + Method WriteShort( n ) + Local q:Short=n + Swap2 Varptr q + WriteBytes Varptr q,2 + End Method + + Method ReadInt() + Local q:Int + ReadBytes Varptr q,4 + Swap4 Varptr q + Return q + End Method + + Method WriteInt( n ) + Local q:Int=n + Swap4 Varptr q + WriteBytes Varptr q,4 + End Method + + Method ReadLong:Long() + Local q:Long + ReadBytes Varptr q,8 + Swap8 Varptr q + Return q + End Method + + Method WriteLong( n:Long ) + Local q:Long=n + Swap8 Varptr q + WriteBytes Varptr q,8 + End Method + + Method ReadFloat#() + Local q:Float + ReadBytes Varptr q,4 + Swap4 Varptr q + Return q + End Method + + Method WriteFloat( n# ) + Local q:Float=n + Swap4 Varptr q + WriteBytes Varptr q,4 + End Method + + Method ReadDouble!() + Local q:Double + ReadBytes Varptr q,8 + Swap8 Varptr q + Return q + End Method + + Method WriteDouble( n! ) + Local q:Double=n + Swap8 Varptr q + WriteBytes Varptr q,8 + End Method + + Function Create:TStream( stream:TStream ) + If Not stream Return + Local t:TXEndianStream=New TXEndianStream + t.SetStream( stream ) + Return t + End Function + + Function BigEndian:TStream( stream:TStream ) +?LittleEndian + Return Create( stream ) +?BigEndian + Return stream +? + End Function + + Function LittleEndian:TStream( stream:TStream ) +?BigEndian + Return Create( stream ) +?LittleEndian + Return stream +? + End Function + +End Type + +Rem +bbdoc: BigEndianStream +returns: A big endian stream +end rem +Function BigEndianStream:TStream( stream:TStream ) + Return TXEndianStream.BigEndian( stream ) +End Function + +Rem +bbdoc: LittleEndianStream +returns: A little endian stream +end rem +Function LittleEndianStream:TStream( stream:TStream ) + Return TXEndianStream.LittleEndian( stream ) +End Function + +Type TXEndianStreamFactory Extends TStreamFactory + Method CreateStream:TStream( url:Object,proto$,path$,readable,writeable ) + Select proto$ + Case "bigendian" + Return TXEndianStream.BigEndian( OpenStream(path,readable,writeable) ) + Case "littleendian" + Return TXEndianStream.LittleEndian( OpenStream(path,readable,writeable) ) + End Select + End Method +End Type + +New TXEndianStreamFactory + diff --git a/mod/brl.mod/event.mod/doc/intro.bbdoc b/mod/brl.mod/event.mod/doc/intro.bbdoc new file mode 100644 index 0000000..22dfdc6 --- /dev/null +++ b/mod/brl.mod/event.mod/doc/intro.bbdoc @@ -0,0 +1,39 @@ + +Event objects are used to notify your application about external events such as user input, +user interface activity and so on. + +The are two main ways your program can receive events: either by adding a hook function to +the #EmitEventHook hook, or by using using the global #{event queue} + +The most important field in an event object is the @id field, which identifies the kind of +event: + +[ @{Event id} | @Description +* EVENT_APPSUSPEND | Application suspended +* EVENT_APPRESUME | Application resumed +* EVENT_APPTERMINATE | Application wants to terminate +* EVENT_KEYDOWN | Key pressed. Event data contains keycode +* EVENT_KEYUP | Key released. Event data contains keycode +* EVENT_KEYCHAR | Key character. Event data contains unicode value +* EVENT_MOUSEDOWN | Mouse button pressed. Event data contains mouse button code +* EVENT_MOUSEUP | Mouse button released. Event data contains mouse button code +* EVENT_MOUSEMOVE | Mouse moved. Event x and y contain mouse coordinates +* EVENT_MOUSEWHEEL | Mouse wheel spun. Event data contains delta clicks +* EVENT_MOUSEENTER | Mouse entered gadget area +* EVENT_MOUSELEAVE | Mouse left gadget area +* EVENT_TIMERTICK | Timer ticked. Event source contains timer object +* EVENT_HOTKEYHIT | Hot key hit. Event data and mods contains hotkey keycode and modifier +* EVENT_MENUACTION | Menu has been selected +* EVENT_WINDOWMOVE | Window has been moved +* EVENT_WINDOWSIZE | Window has been resized +* EVENT_WINDOWCLOSE | Window close icon clicked +* EVENT_WINDOWACTIVATE | Window activated +* EVENT_WINDOWACCEPT | Drag and Drop operation was attempted +* EVENT_GADGETACTION | Gadget state has been updated +* EVENT_GADGETPAINT | A Canvas Gadget needs to be redrawn +* EVENT_GADGETSELECT | A TreeView Node has been selected +* EVENT_GADGETMENU | User has right clicked a TreeView Node or TextArea gadget +* EVENT_GADGETOPEN | A TreeView Node has been expanded +* EVENT_GADGETCLOSE | A TreeView Node has been collapsed +* EVENT_GADGETDONE | An HTMLView has completed loading a page +] diff --git a/mod/brl.mod/event.mod/event.bmx b/mod/brl.mod/event.mod/event.bmx new file mode 100644 index 0000000..c198334 --- /dev/null +++ b/mod/brl.mod/event.mod/event.bmx @@ -0,0 +1,254 @@ + +Strict + +Rem +bbdoc: Events/Events +End Rem +Module BRL.Event + +ModuleInfo "Version: 1.03" +ModuleInfo "Author: Mark Sibly" +ModuleInfo "License: zlib/libpng" +ModuleInfo "Copyright: Blitz Research Ltd" +ModuleInfo "Modserver: BRL" + +ModuleInfo "History: 1.03 Release" +ModuleInfo "History: Added missing EVENT_HOTKEY ToString case" +ModuleInfo "History: Added process events" +ModuleInfo "History: 1.02 Release" +ModuleInfo "History: Added EVENT_GADGETLOSTFOCUS" +ModuleInfo "History: 1.01 Release" +ModuleInfo "History: Added EVENT_KEYREPEAT" + +Import BRL.Hook + +Rem +bbdoc: Hook id for emitted events +about: +The #EmitEventHook global variable contains a hook id for use with #AddHook. + +Each time #EmitEvent is called, the event is passed to all #EmitEventHook +hook functions by means of the hook function @data parameter. +End Rem +Global EmitEventHook=AllocHookId() + +Rem +bbdoc: Event object type +EndRem +Type TEvent + + Rem + bbdoc: Event identifier + End Rem + Field id + + Rem + bbdoc: Event source object + End Rem + Field source:Object + + Rem + bbdoc: Event specific data + End Rem + Field data + + Rem + bbdoc: Event specific modifiers + End Rem + Field mods + + Rem + bbdoc: Event specific position data + End Rem + Field x + + Rem + bbdoc: Event specific position data + End Rem + Field y + + Rem + bbdoc: Event specific extra information + End Rem + Field extra:Object + + Rem + bbdoc: Emit this event + about: + This method runs all #EmitEventHook hook function, passing @Self as + the hook data. + End Rem + Method Emit() + RunHooks EmitEventHook,Self + End Method + + Rem + bbdoc: Convert event to a string + about: + This method is mainly useful for debugging purposes. + End Rem + Method ToString$() + Local t$=DescriptionForId( id ) + If Not t + If id & EVENT_USEREVENTMASK + t="UserEvent"+(id-EVENT_USEREVENTMASK) + Else + t="Unknown Event, id="+id + EndIf + EndIf + Return t+": data="+data+", mods="+mods+", x="+x+", y="+y+", extra=~q"+String(extra)+"~q" + End Method + + Rem + bbdoc: Create an event object + returns: A new event object + End Rem + Function Create:TEvent( id,source:Object=Null,data=0,mods=0,x=0,y=0,extra:Object=Null ) + Local t:TEvent=New TEvent + t.id=id + t.source=source + t.data=data + t.mods=mods + t.x=x + t.y=y + t.extra=extra + Return t + End Function + + Rem + bbdoc: Allocate a user event id + returns: A new user event id + End Rem + Function AllocUserId() + Global _id=EVENT_USEREVENTMASK + _id:+1 + Return _id + End Function + + Function RegisterId( id,description$ ) + _regids:+String(id)+"{"+description+"}" + End Function + + Function DescriptionForId$( id ) + Local t$="}"+String(id)+"{" + Local i=_regids.Find( t ) + If i=-1 Return + i:+t.length + Local i2=_regids.Find( "}",i ) + If i2=-1 Return + Return _regids[i..i2] + End Function + + Global _regids$="}" + +End Type + +Const EVENT_APPMASK=$100 +Const EVENT_APPSUSPEND=$101 +Const EVENT_APPRESUME=$102 +Const EVENT_APPTERMINATE=$103 +Const EVENT_APPOPENFILE=$104 +Const EVENT_APPIDLE=$105 'Reserved by Mark! +Const EVENT_KEYMASK=$200 +Const EVENT_KEYDOWN=$201 +Const EVENT_KEYUP=$202 +Const EVENT_KEYCHAR=$203 +Const EVENT_KEYREPEAT=$204 +Const EVENT_MOUSEMASK=$400 +Const EVENT_MOUSEDOWN=$401 +Const EVENT_MOUSEUP=$402 +Const EVENT_MOUSEMOVE=$403 +Const EVENT_MOUSEWHEEL=$404 +Const EVENT_MOUSEENTER=$405 +Const EVENT_MOUSELEAVE=$406 +Const EVENT_TIMERMASK=$800 +Const EVENT_TIMERTICK=$801 +Const EVENT_HOTKEYMASK=$1000 +Const EVENT_HOTKEYHIT=$1001 +Const EVENT_GADGETMASK=$2000 +Const EVENT_GADGETACTION=$2001 +Const EVENT_GADGETPAINT=$2002 +Const EVENT_GADGETSELECT=$2003 +Const EVENT_GADGETMENU=$2004 +Const EVENT_GADGETOPEN=$2005 +Const EVENT_GADGETCLOSE=$2006 +Const EVENT_GADGETDONE=$2007 +Const EVENT_GADGETLOSTFOCUS=$2008 +Const EVENT_GADGETSHAPE=$2009 'reserved by Mark! +Const EVENT_WINDOWMASK=$4000 +Const EVENT_WINDOWMOVE=$4001 +Const EVENT_WINDOWSIZE=$4002 +Const EVENT_WINDOWCLOSE=$4003 +Const EVENT_WINDOWACTIVATE=$4004 +Const EVENT_WINDOWACCEPT=$4005 +Const EVENT_MENUMASK=$8000 +Const EVENT_MENUACTION=$8001 +Const EVENT_STREAMMASK=$10000 +Const EVENT_STREAMEOF=$10001 +Const EVENT_STREAMAVAIL=$10002 +Const EVENT_PROCESSMASK=$20000 +Const EVENT_PROCESSEXIT=$20001 +Const EVENT_USEREVENTMASK=$80000000 + +TEvent.RegisterId EVENT_APPSUSPEND,"AppSuspend" +TEvent.RegisterId EVENT_APPRESUME,"AppResume" +TEvent.RegisterId EVENT_APPTERMINATE,"AppTerminate" +TEvent.RegisterId EVENT_APPOPENFILE,"AppOpenFile" +TEvent.RegisterId EVENT_APPIDLE,"AppIdle" +TEvent.RegisterId EVENT_KEYDOWN,"KeyDown" +TEvent.RegisterId EVENT_KEYUP,"KeyUp" +TEvent.RegisterId EVENT_KEYCHAR,"KeyChar" +TEvent.RegisterId EVENT_KEYREPEAT,"KeyRepeat" +TEvent.RegisterId EVENT_MOUSEDOWN,"MouseDown" +TEvent.RegisterId EVENT_MOUSEUP,"MouseUp" +TEvent.RegisterId EVENT_MOUSEMOVE,"MouseMove" +TEvent.RegisterId EVENT_MOUSEWHEEL,"MouseWheel" +TEvent.RegisterId EVENT_MOUSEENTER,"MouseEnter" +TEvent.RegisterId EVENT_MOUSELEAVE,"MouseLeave" +TEvent.RegisterId EVENT_TIMERTICK,"TimerTick" +TEvent.RegisterId EVENT_HOTKEYHIT,"HotkeyHit" +TEvent.RegisterId EVENT_GADGETACTION,"GadgetAction" +TEvent.RegisterId EVENT_GADGETPAINT,"GadgetPaint" +TEvent.RegisterId EVENT_GADGETSELECT,"GadgetSelect" +TEvent.RegisterId EVENT_GADGETMENU,"GadgetMenu" +TEvent.RegisterId EVENT_GADGETOPEN,"GadgetOpen" +TEvent.RegisterId EVENT_GADGETCLOSE,"GadgetClose" +TEvent.RegisterId EVENT_GADGETDONE,"GadgetDone" +TEvent.RegisterId EVENT_GADGETLOSTFOCUS,"GadgetLostFocus" +TEvent.RegisterId EVENT_GADGETSHAPE,"GadgetShape" +TEvent.RegisterId EVENT_WINDOWMOVE,"WindowMove" +TEvent.RegisterId EVENT_WINDOWSIZE,"WindowSize" +TEvent.RegisterId EVENT_WINDOWCLOSE,"WindowClose" +TEvent.RegisterId EVENT_WINDOWACTIVATE,"WindowActivate" +TEvent.RegisterId EVENT_WINDOWACCEPT,"WindowAccept" +TEvent.RegisterId EVENT_MENUACTION,"MenuAction" +TEvent.RegisterId EVENT_STREAMEOF,"StreamEof" +TEvent.RegisterId EVENT_STREAMAVAIL,"StreamAvail" +TEvent.RegisterId EVENT_PROCESSEXIT,"ProcessExit" + +Rem +bbdoc: Emit an event +about: +Runs all #EmitEventHook hooks, passing @event as the hook data. +End Rem +Function EmitEvent( event:TEvent ) + event.Emit +End Function + +Rem +bbdoc: Create an event object +returns: A new event object +End Rem +Function CreateEvent:TEvent( id,source:Object=Null,data=0,mods=0,x=0,y=0,extra:Object=Null ) + Return TEvent.Create( id,source,data,mods,x,y,extra ) +End Function + +Rem +bbdoc: Allocate a user event id +returns: A new user event id +End Rem +Function AllocUserEventId( description$="" ) + Local id=TEvent.AllocUserId() + If description TEvent.RegisterId id,description + Return id +End Function diff --git a/mod/brl.mod/event.mod/event.h b/mod/brl.mod/event.mod/event.h new file mode 100644 index 0000000..7ef99b3 --- /dev/null +++ b/mod/brl.mod/event.mod/event.h @@ -0,0 +1,62 @@ + +#ifndef BB_BRL_EVENT_H +#define BB_BRL_EVENT_H + +enum{ + BBEVENT_APPMASK=0x100, + BBEVENT_APPSUSPEND=0x101, + BBEVENT_APPRESUME=0x102, + BBEVENT_APPTERMINATE=0x103, + BBEVENT_APPOPENFILE=0x104, + BBEVENT_APPIDLE=0x105, + + BBEVENT_KEYMASK=0x200, + BBEVENT_KEYDOWN=0x201, + BBEVENT_KEYUP=0x202, + BBEVENT_KEYCHAR=0x203, + BBEVENT_KEYREPEAT=0x204, + + BBEVENT_MOUSEMASK=0x400, + BBEVENT_MOUSEDOWN=0x401, + BBEVENT_MOUSEUP=0x402, + BBEVENT_MOUSEMOVE=0x403, + BBEVENT_MOUSEWHEEL=0x404, + BBEVENT_MOUSEENTER=0x405, + BBEVENT_MOUSELEAVE=0x406, + + BBEVENT_TIMERMASK=0x800, + BBEVENT_TIMERTICK=0x801, + + BBEVENT_HOTKEYMASK=0x1000, + BBEVENT_HOTKEYHIT=0x1001, + + BBEVENT_GADGETMASK=0x2000, + BBEVENT_GADGETACTION=0x2001, + BBEVENT_GADGETPAINT=0x2002, + BBEVENT_GADGETSELECT=0x2003, + BBEVENT_GADGETMENU=0x2004, + BBEVENT_GADGETOPEN=0x2005, + BBEVENT_GADGETCLOSE=0x2006, + BBEVENT_GADGETDONE=0x2007, + BBEVENT_GADGETLOSTFOCUS=0x2008, + BBEVENT_GADGETSHAPE=0x2009, + + BBEVENT_WINDOWMASK=0x4000, + BBEVENT_WINDOWMOVE=0x4001, + BBEVENT_WINDOWSIZE=0x4002, + BBEVENT_WINDOWCLOSE=0x4003, + BBEVENT_WINDOWACTIVATE=0x4004, + BBEVENT_WINDOWACCEPT=0x4005, + + BBEVENT_MENUMASK=0x8000, + BBEVENT_MENUACTION=0x8001, + + BBEVENT_STREAMMASK=0x10000, + BBEVENT_STREAMEOF=0x10001, + BBEVENT_STREAMAVAIL=0x10002, + + BBEVENT_PROCESSMASK=0x20000, + BBEVENT_PROCESSEXIT=0x20001 +}; + +#endif diff --git a/mod/brl.mod/eventqueue.mod/doc/intro.bbdoc b/mod/brl.mod/eventqueue.mod/doc/intro.bbdoc new file mode 100644 index 0000000..88c73e3 --- /dev/null +++ b/mod/brl.mod/eventqueue.mod/doc/intro.bbdoc @@ -0,0 +1,8 @@ + +The event queue is a simple first-in, first-out queue that is used to collect +#TEvent objects emitted by your application. + +The #PollEvent and #WaitEvent commands can be used to receive the next event from the event +queue, while the #PeekEvent command can be used to check if the event queue is empty. + +Events are added to the event queue using #PostEvent. diff --git a/mod/brl.mod/eventqueue.mod/eventqueue.bmx b/mod/brl.mod/eventqueue.mod/eventqueue.bmx new file mode 100644 index 0000000..2a1465a --- /dev/null +++ b/mod/brl.mod/eventqueue.mod/eventqueue.bmx @@ -0,0 +1,216 @@ + +Strict + +Rem +bbdoc: Events/Event queue +End Rem +Module BRL.EventQueue + +ModuleInfo "Version: 1.01" +ModuleInfo "Author: Mark Sibly" +ModuleInfo "License: zlib/libpng" +ModuleInfo "Copyright: Blitz Research Ltd" +ModuleInfo "Modserver: BRL" + +ModuleInfo "History: 1.01 Release" +ModuleInfo "History: Fixed CurrentEvent being retained in queue array" +ModuleInfo "History: 1.00 Release" +ModuleInfo "History: Created module" + +Import BRL.Event +Import BRL.System + +Private + +Const QUEUESIZE=256 +Const QUEUEMASK=QUEUESIZE-1 +Global queue:TEvent[QUEUESIZE],queue_put,queue_get + +Function Hook:Object( id,data:Object,context:Object ) + Local ev:TEvent=TEvent( data ) + If Not ev Return + + Select ev.id + Case EVENT_WINDOWMOVE,EVENT_WINDOWSIZE,EVENT_TIMERTICK,EVENT_GADGETACTION + PostEvent ev,True + Default + PostEvent ev + End Select + + Return data +End Function + +AddHook EmitEventHook,Hook,Null,-10000 + +Global NullEvent:TEvent=New TEvent + +Public + +Rem +bbdoc: Current Event +about: The #CurrentEvent global variable contains the event most recently returned by +#PollEvent or #WaitEvent. +End Rem +Global CurrentEvent:TEvent=NullEvent + +Rem +bbdoc: Examine the next event in the event queue +about: +#PeekEvent examines the next event in the event queue, without removing it from the +event queue or modifying the #CurrentEvent global variable. + +If there are no events in the event queue, #PeekEvent returns #Null. +End Rem +Function PeekEvent:TEvent() + If queue_get=queue_put + PollSystem + If queue_get=queue_put Return Null + EndIf + Return queue[queue_get & QUEUEMASK] +End Function + +Rem +bbdoc: Get the next event from the event queue +returns: The id of the next event in the event queue, or 0 if the event queue is empty +about: +#PollEvent removes an event from the event queue and updates the #CurrentEvent +global variable. + +If there are no events in the event queue, #PollEvent returns 0. +End Rem +Function PollEvent() + If queue_get=queue_put + PollSystem + If queue_get=queue_put + CurrentEvent=NullEvent + Return 0 + EndIf + EndIf + CurrentEvent=queue[queue_get & QUEUEMASK] + queue[queue_get & QUEUEMASK]=Null + queue_get:+1 + Return CurrentEvent.id +End Function + +Rem +bbdoc: Get the next event from the event queue, waiting if necessary +returns: The id of the next event in the event queue +about: +#WaitEvent removes an event from the event queue and updates the #CurrentEvent +global variable. + +If there are no events in the event queue, #WaitEvent halts program execution until +an event is available. +End Rem +Function WaitEvent() + While queue_get=queue_put + WaitSystem + Wend + CurrentEvent=queue[queue_get & QUEUEMASK] + queue[queue_get & QUEUEMASK]=Null + queue_get:+1 + Return CurrentEvent.id +End Function + +Rem +bbdoc: Post an event to the event queue +about:#PostEvent adds an event to the end of the event queue. + +The @update flag can be used to update an existing event. If @update is True +and an event with the same @id and @source is found in the event +queue, the existing event will be updated instead of @event +being added to the event queue. This can be useful to prevent high frequency +events such as timer events from flooding the event queue. +End Rem +Function PostEvent( event:TEvent,update=False ) + If update + Local i=queue_get + While i<>queue_put + Local t:TEvent=queue[i & QUEUEMASK ] + If t.id=event.id And t.source=event.source + t.data=event.data + t.mods=event.mods + t.x=event.x + t.y=event.y + t.extra=event.extra + Return + EndIf + i:+1 + Wend + EndIf + If queue_put-queue_get=QUEUESIZE Return + queue[queue_put & QUEUEMASK]=event + queue_put:+1 +End Function + +Rem +bbdoc: Get current event id +returns: The @id field of the #CurrentEvent global variable +EndRem +Function EventID() + Return CurrentEvent.id +End Function + +Rem +bbdoc: Get current event data +returns: The @data field of the #CurrentEvent global variable +EndRem +Function EventData() + Return CurrentEvent.data +End Function + +Rem +bbdoc: Get current event modifiers +returns: The @mods field of the #CurrentEvent global variable +EndRem +Function EventMods() + Return CurrentEvent.mods +End Function + +Rem +bbdoc: Get current event x value +returns: The @x field of the #CurrentEvent global variable +EndRem +Function EventX() + Return CurrentEvent.x +End Function + +Rem +bbdoc: Get current event y value +returns: The @y field of the #CurrentEvent global variable +EndRem +Function EventY() + Return CurrentEvent.y +End Function + +Rem +bbdoc: Get current event extra value +returns: The @extra field of the #CurrentEvent global variable +EndRem +Function EventExtra:Object() + Return CurrentEvent.extra +End Function + +Rem +bbdoc: Get current event extra value converted to a string +returns: The @extra field of the #CurrentEvent global variable converted to a string +EndRem +Function EventText$() + Return String( CurrentEvent.extra ) +End Function + +Rem +bbdoc: Get current event source object +returns: The @source field of the #CurrentEvent global variable +EndRem +Function EventSource:Object() + Return CurrentEvent.source +End Function + +Rem +bbdoc: Get current event source object handle +returns: The @source field of the #CurrentEvent global variable converted to an integer handle +EndRem +Function EventSourceHandle() + Return HandleFromObject( CurrentEvent.source ) +End Function diff --git a/mod/brl.mod/filesystem.mod/doc/changedir.bmx b/mod/brl.mod/filesystem.mod/doc/changedir.bmx new file mode 100644 index 0000000..49a7a27 --- /dev/null +++ b/mod/brl.mod/filesystem.mod/doc/changedir.bmx @@ -0,0 +1,11 @@ +' changedir.bmx + +print "CurrentDir()="+currentdir() + +' change current folder to the parent folder + +changedir ".." + +' print new CurrentDir() + +print "CurrentDir()="+currentdir() diff --git a/mod/brl.mod/filesystem.mod/doc/createdir.bmx b/mod/brl.mod/filesystem.mod/doc/createdir.bmx new file mode 100644 index 0000000..ad45094 --- /dev/null +++ b/mod/brl.mod/filesystem.mod/doc/createdir.bmx @@ -0,0 +1,4 @@ +' createdir.bmx + +success=createdir("myfolder") +if not success runtimeerror "error creating directory" diff --git a/mod/brl.mod/filesystem.mod/doc/createfile.bmx b/mod/brl.mod/filesystem.mod/doc/createfile.bmx new file mode 100644 index 0000000..1ed644f --- /dev/null +++ b/mod/brl.mod/filesystem.mod/doc/createfile.bmx @@ -0,0 +1,4 @@ +' createfile.bmx + +success=createfile("myfile") +if not success runtimeerror "error creating file" diff --git a/mod/brl.mod/filesystem.mod/doc/currentdir.bmx b/mod/brl.mod/filesystem.mod/doc/currentdir.bmx new file mode 100644 index 0000000..449d90b --- /dev/null +++ b/mod/brl.mod/filesystem.mod/doc/currentdir.bmx @@ -0,0 +1,4 @@ +' currentdir.bmx + +cd$=currentdir() +print "CurrentDir()="+cd$ diff --git a/mod/brl.mod/filesystem.mod/doc/deletedir.bmx b/mod/brl.mod/filesystem.mod/doc/deletedir.bmx new file mode 100644 index 0000000..87bc6ab --- /dev/null +++ b/mod/brl.mod/filesystem.mod/doc/deletedir.bmx @@ -0,0 +1,4 @@ +' deletedir.bmx + +success=deletedir("myfolder") +if not success runtimeerror "error deleting directory" diff --git a/mod/brl.mod/filesystem.mod/doc/deletefile.bmx b/mod/brl.mod/filesystem.mod/doc/deletefile.bmx new file mode 100644 index 0000000..6451715 --- /dev/null +++ b/mod/brl.mod/filesystem.mod/doc/deletefile.bmx @@ -0,0 +1,4 @@ +' deletefile.bmx + +success=deletefile("myfile") +if not success runtimeerror "error deleting file" diff --git a/mod/brl.mod/filesystem.mod/doc/extractdir.bmx b/mod/brl.mod/filesystem.mod/doc/extractdir.bmx new file mode 100644 index 0000000..bb7ffdd --- /dev/null +++ b/mod/brl.mod/filesystem.mod/doc/extractdir.bmx @@ -0,0 +1,3 @@ +' extractdir.bmx + +print extractdir("mypath/myfile.bmx") 'prints mypath diff --git a/mod/brl.mod/filesystem.mod/doc/extractext.bmx b/mod/brl.mod/filesystem.mod/doc/extractext.bmx new file mode 100644 index 0000000..fde73d4 --- /dev/null +++ b/mod/brl.mod/filesystem.mod/doc/extractext.bmx @@ -0,0 +1,3 @@ +' extractext.bmx + +print extractext("mypath/myfile.bmx") 'prints bmx diff --git a/mod/brl.mod/filesystem.mod/doc/filemode.bmx b/mod/brl.mod/filesystem.mod/doc/filemode.bmx new file mode 100644 index 0000000..db66451 --- /dev/null +++ b/mod/brl.mod/filesystem.mod/doc/filemode.bmx @@ -0,0 +1,19 @@ +' filemode.bmx + +' the following function converts the file mode to +' the standard unix permission bits string + +Function Permissions$(mode) + local testbit,pos + local p$="rwxrwxrwx" + testbit=%100000000 + pos=1 + while (testbit) + if mode & testbit res$:+mid$(p$,pos,1) else res$:+"-" + testbit=testbit shr 1 + pos:+1 + wend + return res +End Function + +print Permissions$(filemode("filemode.bmx")) diff --git a/mod/brl.mod/filesystem.mod/doc/filesize.bmx b/mod/brl.mod/filesystem.mod/doc/filesize.bmx new file mode 100644 index 0000000..aecc364 --- /dev/null +++ b/mod/brl.mod/filesystem.mod/doc/filesize.bmx @@ -0,0 +1,5 @@ +' filesize.bmx + +' the following prints the size of this source file in bytes + +print filesize("filesize.bmx") diff --git a/mod/brl.mod/filesystem.mod/doc/filetime.bmx b/mod/brl.mod/filesystem.mod/doc/filetime.bmx new file mode 100644 index 0000000..f1061dd --- /dev/null +++ b/mod/brl.mod/filesystem.mod/doc/filetime.bmx @@ -0,0 +1,3 @@ +' filetime.bmx + +print filetime("filetime.bmx") diff --git a/mod/brl.mod/filesystem.mod/doc/filetype.bmx b/mod/brl.mod/filesystem.mod/doc/filetype.bmx new file mode 100644 index 0000000..3853337 --- /dev/null +++ b/mod/brl.mod/filesystem.mod/doc/filetype.bmx @@ -0,0 +1,5 @@ +' filetype.bmx + +print filetype(".") 'prints 2 for directory type +print filetype("filetype.bmx") 'prints 1 for file type +print filetype("notfound.file") 'prints 0 for doesn't exist diff --git a/mod/brl.mod/filesystem.mod/doc/intro.bbdoc b/mod/brl.mod/filesystem.mod/doc/intro.bbdoc new file mode 100644 index 0000000..390e3f6 --- /dev/null +++ b/mod/brl.mod/filesystem.mod/doc/intro.bbdoc @@ -0,0 +1,19 @@ + +The BlitzMax filesystem module contains commands to perform operations on the computer's +files and directories. + +#OpenFile, #ReadFile and #WriteFile return a stream object for reading and or writing data +to files. + +Directories can be examined file by file using a combination of the +#ReadDir, #NextFile and #CloseDir commands, or #LoadDir can be used to read the file names +of a directory into a string array. + +File properties can be examined with the #FileType, #FileTime, #FileSize and #FileMode commands. + +Files and directories (folders) can be created and deleted with the #CreateFile, #CreateDir +#DeleteFile and #DeleteDir commands. + +Finally, the FileSystem module contains various utility functions for handling file paths +in a system independent manner. These commands include #RealPath, #StripDir, #StripExt, +#StripAll, #ExtractDir and #ExtractExt. diff --git a/mod/brl.mod/filesystem.mod/doc/loaddir.bmx b/mod/brl.mod/filesystem.mod/doc/loaddir.bmx new file mode 100644 index 0000000..d53a103 --- /dev/null +++ b/mod/brl.mod/filesystem.mod/doc/loaddir.bmx @@ -0,0 +1,11 @@ +' loaddir.bmx + +' declare a string array + +local files$[] + +files=loaddir(currentdir()) + +for t$=eachin files + print t +next diff --git a/mod/brl.mod/filesystem.mod/doc/openfile.bmx b/mod/brl.mod/filesystem.mod/doc/openfile.bmx new file mode 100644 index 0000000..ae38e7b --- /dev/null +++ b/mod/brl.mod/filesystem.mod/doc/openfile.bmx @@ -0,0 +1,12 @@ +' openfile.bmx + +' the following prints the contents of this source file + +file=openfile("openfile.bmx") + +if not file runtimeerror "could not open file openfile.bmx" + +while not eof(file) + print readline(file) +wend +closestream file diff --git a/mod/brl.mod/filesystem.mod/doc/readdir.bmx b/mod/brl.mod/filesystem.mod/doc/readdir.bmx new file mode 100644 index 0000000..d4d94c4 --- /dev/null +++ b/mod/brl.mod/filesystem.mod/doc/readdir.bmx @@ -0,0 +1,14 @@ +' readdir.bmx + +dir=ReadDir(CurrentDir()) + +If Not dir RuntimeError "failed to read current directory" + +Repeat + t$=NextFile( dir ) + If t="" Exit + If t="." Or t=".." Continue + Print t +Forever + +CloseDir dir diff --git a/mod/brl.mod/filesystem.mod/doc/readfile.bmx b/mod/brl.mod/filesystem.mod/doc/readfile.bmx new file mode 100644 index 0000000..933cf40 --- /dev/null +++ b/mod/brl.mod/filesystem.mod/doc/readfile.bmx @@ -0,0 +1,13 @@ +' readfile.bmx + +' the following prints the contents of this source file + +file=readfile("readfile.bmx") + +if not file runtimeerror "could not open file openfile.bmx" + +while not eof(file) + print readline(file) +wend + +closestream file diff --git a/mod/brl.mod/filesystem.mod/doc/realpath.bmx b/mod/brl.mod/filesystem.mod/doc/realpath.bmx new file mode 100644 index 0000000..9627834 --- /dev/null +++ b/mod/brl.mod/filesystem.mod/doc/realpath.bmx @@ -0,0 +1,5 @@ +' realpath.bmx + +print realpath("realpath.bmx") 'prints full path of this source + +print realpath("..") 'prints full path of parent directory diff --git a/mod/brl.mod/filesystem.mod/doc/setfilemode.bmx b/mod/brl.mod/filesystem.mod/doc/setfilemode.bmx new file mode 100644 index 0000000..90e26a7 --- /dev/null +++ b/mod/brl.mod/filesystem.mod/doc/setfilemode.bmx @@ -0,0 +1,17 @@ +' setfilemode.bmx + +' the following makes this source file readonly + +writebits=%010010010 + +' read the file mode + +mode=filemode("setfilemode.bmx") + +'mask out the write bits to make readonly + +mode=mode & ~writebits + +'set the new file mode + +setfilemode("setfilemode.bmx",mode) diff --git a/mod/brl.mod/filesystem.mod/doc/stripall.bmx b/mod/brl.mod/filesystem.mod/doc/stripall.bmx new file mode 100644 index 0000000..d97765a --- /dev/null +++ b/mod/brl.mod/filesystem.mod/doc/stripall.bmx @@ -0,0 +1,3 @@ +' stripall.bmx + +print stripall("mypath/myfile.bmx") 'prints myfile diff --git a/mod/brl.mod/filesystem.mod/doc/stripdir.bmx b/mod/brl.mod/filesystem.mod/doc/stripdir.bmx new file mode 100644 index 0000000..00f9ae5 --- /dev/null +++ b/mod/brl.mod/filesystem.mod/doc/stripdir.bmx @@ -0,0 +1,3 @@ +' stripdir.bmx + +print stripdir("mypath/myfile.bmx") 'prints myfile.bmx diff --git a/mod/brl.mod/filesystem.mod/doc/stripext.bmx b/mod/brl.mod/filesystem.mod/doc/stripext.bmx new file mode 100644 index 0000000..200dc29 --- /dev/null +++ b/mod/brl.mod/filesystem.mod/doc/stripext.bmx @@ -0,0 +1,3 @@ +' stripext.bmx + +print stripext("mypath/myfile.bmx") 'prints mypath/myfile diff --git a/mod/brl.mod/filesystem.mod/doc/stripslash.bmx b/mod/brl.mod/filesystem.mod/doc/stripslash.bmx new file mode 100644 index 0000000..e92c482 --- /dev/null +++ b/mod/brl.mod/filesystem.mod/doc/stripslash.bmx @@ -0,0 +1,3 @@ +' stripslash.bmx + +print stripslash("mypath/") 'prints mypath diff --git a/mod/brl.mod/filesystem.mod/doc/writefile.bmx b/mod/brl.mod/filesystem.mod/doc/writefile.bmx new file mode 100644 index 0000000..45b0d15 --- /dev/null +++ b/mod/brl.mod/filesystem.mod/doc/writefile.bmx @@ -0,0 +1,9 @@ +' writefile.bmx + +file=writefile("test.txt") + +if not file runtimeerror "failed to open test.txt file" + +writeline file,"hello world" + +closestream file diff --git a/mod/brl.mod/filesystem.mod/filesystem.bmx b/mod/brl.mod/filesystem.mod/filesystem.bmx new file mode 100644 index 0000000..97bd607 --- /dev/null +++ b/mod/brl.mod/filesystem.mod/filesystem.bmx @@ -0,0 +1,489 @@ + +Strict + +Rem +bbdoc: System/File system +End Rem +Module BRL.FileSystem + +ModuleInfo "Version: 1.09" +ModuleInfo "Author: Mark Sibly" +ModuleInfo "License: zlib/libpng" +ModuleInfo "Copyright: Blitz Research Ltd" +ModuleInfo "Modserver: BRL" + +ModuleInfo "History: 1.09 Release" +ModuleInfo "History: Fixed RealPath breaking win32 //server paths" +ModuleInfo "History: 1.08 Release" +ModuleInfo "History: Rebuild for StdC chmod_ linkage" +ModuleInfo "History: 1.07 Release" +ModuleInfo "History: Fixed RealPath failing with 'hidden' dirs" +ModuleInfo "History: 1.06 Release" +ModuleInfo "History: 1.05 Release" +ModuleInfo "History: Fixed Win32 CreateDir" +ModuleInfo "History: 1.04 Release" +ModuleInfo "History: Cleaned up FixPath and RealPath" +ModuleInfo "History: Added optional resurse parameter to CreateDir" + +Import Pub.StdC +Import BRL.BankStream + +Const FILETYPE_NONE=0,FILETYPE_FILE=1,FILETYPE_DIR=2 + +Private + +Function _RootPath$( path$ ) +?Win32 + If path.StartsWith( "//" ) + Return path[ ..path.Find( "/",2 )+1 ] + EndIf + Local i=path.Find( ":" ) + If i<>-1 And path.Find( "/" )=i+1 Return path[..i+2] +? + If path.StartsWith( "/" ) Return "/" +End Function + +Function _IsRootPath( path$ ) + Return path And _RootPath( path )=path +End Function + +Function _IsRealPath( path$ ) + Return _RootPath( path )<>"" +End Function + +?Win32 +Function _CurrentDrive$() + Local cd$=getcwd_() + Local i=cd.Find( ":" ) + If i<>-1 Return cd[..i] +End Function +? + +Public + +Function FixPath( path$ Var,dirPath=False ) + path=path.Replace("\","/") +?Win32 + If path.StartsWith( "//" ) + If path.Find( "/",2 )=-1 path:+"/" + Else + Local i=path.Find( ":" ) + If i<>-1 And ( i=path.length-1 Or path[i+1]<>Asc(":") ) + Local i2=path.Find( "/" ) + If i2=-1 Or i2>i+1 path=path[..i+1]+"/"+path[i+1..] + EndIf + EndIf +? + If dirPath And path.EndsWith( "/" ) + If Not _IsRootPath( path ) path=path[..path.length-1] + EndIf + +End Function + +Rem +bbdoc: Strip directory from a file path +End Rem +Function StripDir$( path$ ) + FixPath path + Local i=path.FindLast( "/" ) + If i<>-1 Return path[i+1..] + Return path +End Function + +Rem +bbdoc: Strip extension from a file path +End Rem +Function StripExt$( path$ ) + FixPath path + Local i=path.FindLast( "." ) + If i<>-1 And path.Find( "/",i+1 )=-1 Return path[..i] + Return path +End Function + +Rem +bbdoc: Strip directory and extension from a file path +End Rem +Function StripAll$( path$ ) + Return StripDir( StripExt( path ) ) +End Function + +Rem +bbdoc: Strip trailing slash from a file path +about: +#StripSlash will not remove the trailing slash from a 'root' path. For example, "/" +or (on Win32 only) "C:/". +End Rem +Function StripSlash$( path$ ) + FixPath path + If path.EndsWith( "/" ) And Not _IsRootPath( path ) path=path[..path.length-1] + Return path +End Function + +Rem +bbdoc: Extract directory from a file path +End Rem +Function ExtractDir$( path$ ) + FixPath path + If path="." Or path=".." Or _IsRootPath( path ) Return path + + Local i=path.FindLast( "/" ) + If i=-1 Return "" + + If _IsRootPath( path[..i+1] ) i:+1 + Return path[..i] +End Function + +Rem +bbdoc: Extract extension from a file path +End Rem +Function ExtractExt$( path$ ) + FixPath path + Local i=path.FindLast( "." ) + If i<>-1 And path.Find( "/",i+1 )=-1 Return path[i+1..] +End Function + +Rem +bbdoc: Get Current Directory +returns: The current directory +End Rem +Function CurrentDir$() + Local path$=getcwd_() + FixPath path + Return path +End Function + +Rem +bbdoc: Get real, absolute path of a file path +End Rem +Function RealPath$( path$ ) +?Win32 + If path.StartsWith( "/" ) And Not path.StartsWith( "//" ) + path=_CurrentDrive()+":"+path + EndIf +? + FixPath path + Local cd$=_RootPath( path ) + + If cd + path=path[cd.length..] + Else + cd=CurrentDir() + EndIf + + path:+"/" + While path + Local i=path.Find( "/" ) + Local t$=path[..i] + path=path[i+1..] + Select t + Case "" + Case "." + Case ".." + If Not _IsRootPath( cd ) cd=cd[..cd.FindLast("/")] + Default + If Not cd.EndsWith( "/" ) cd:+"/" + cd:+t + End Select + Wend + + Return cd +End Function + +Rem +bbdoc: Get file type +returns: 0 if file at @path doesn't exist, FILETYPE_FILE (1) if the file is a plain file or FILETYPE_DIR (2) if the file is a directory +End Rem +Function FileType( path$ ) + FixPath path + Local mode,size,mtime,ctime + If stat_( path,mode,size,mtime,ctime ) Return 0 + Select mode & S_IFMT_ + Case S_IFREG_ Return FILETYPE_FILE + Case S_IFDIR_ Return FILETYPE_DIR + End Select + Return FILETYPE_NONE +End Function + +Rem +bbdoc: Get file time +returns: The time the file at @path was last modified +End Rem +Function FileTime( path$ ) + FixPath path + Local mode,size,mtime,ctime + If stat_( path,mode,size,mtime,ctime ) Return 0 + Return mtime +End Function + +Rem +bbdoc: Get file size +returns: Size, in bytes, of the file at @path, or -1 if the file does not exist +end rem +Function FileSize( path$ ) + FixPath path + Local mode,size,mtime,ctime + If stat_( path,mode,size,mtime,ctime ) Return -1 + Return size +End Function + +Rem +bbdoc: Get file mode +returns: file mode flags +end rem +Function FileMode( path$ ) + FixPath path + Local mode,size,mtime,ctime + If stat_( path,mode,size,mtime,ctime ) Return -1 + Return mode & 511 +End Function + +Rem +bbdoc: Set file mode +end rem +Function SetFileMode( path$,mode ) + FixPath path + chmod_ path,mode +End Function + +Rem +bbdoc: Create a file +returns: True if successful +End Rem +Function CreateFile( path$ ) + FixPath path + remove_ path + Local t=fopen_( path,"wb" ) + If t fclose_ t + If FileType( path )=FILETYPE_FILE Return True +End Function + +Rem +bbdoc: Create a directory +returns: True if successful +about: +If @recurse is true, any required subdirectories are also created. +End Rem +Function CreateDir( path$,recurse=False ) + FixPath path,True + If Not recurse + mkdir_ path,1023 + Return FileType(path)=FILETYPE_DIR + EndIf + Local t$ + path=RealPath(path)+"/" + While path + Local i=path.find("/")+1 + t:+path[..i] + path=path[i..] + Select FileType(t) + Case FILETYPE_DIR + Case FILETYPE_NONE + Local s$=StripSlash(t) + mkdir_ StripSlash(s),1023 + If FileType(s)<>FILETYPE_DIR Return False + Default + Return False + End Select + Wend + Return True +End Function + +Rem +bbdoc: Delete a file +returns: True if successful +End Rem +Function DeleteFile( path$ ) + FixPath path + remove_ path + Return FileType(path)=FILETYPE_NONE +End Function + +Rem +bbdoc: Renames a file +returns: True if successful +End Rem +Function RenameFile( oldpath$,newpath$ ) + FixPath oldpath + FixPath newpath + Return rename_( oldpath,newpath)=0 +End Function + +Rem +bbdoc: Copy a file +returns: True if successful +End Rem +Function CopyFile( src$,dst$ ) + Local in:TStream=ReadStream( src ),ok + If in + Local out:TStream=WriteStream( dst ) + If out + Try + CopyStream in,out + ok=True + Catch ex:TStreamWriteException + End Try + out.Close + EndIf + in.Close + EndIf + Return ok +End Function + +Rem +bbdoc: Copy a directory +returns: True if successful +End Rem +Function CopyDir( src$,dst$ ) + + Function CopyDir_( src$,dst$ ) + If FileType( dst )=FILETYPE_NONE CreateDir dst + If FileType( dst )<>FILETYPE_DIR Return False + For Local file$=EachIn LoadDir( src ) + Select FileType( src+"/"+file ) + Case FILETYPE_DIR + If Not CopyDir_( src+"/"+file,dst+"/"+file ) Return False + Case FILETYPE_FILE + If Not CopyFile( src+"/"+file,dst+"/"+file ) Return False + End Select + Next + Return True + End Function + + FixPath src + If FileType( src )<>FILETYPE_DIR Return False + + FixPath dst + + Return CopyDir_( src,dst ) + +End Function + +Rem +bbdoc: Delete a directory +returns: True if successful +about: Set @recurse to true to delete all subdirectories and files recursively - +but be careful! +End Rem +Function DeleteDir( path$,recurse=False ) + FixPath path,True + If recurse + Local dir=ReadDir( path ) + If Not dir Return + Repeat + Local t$=NextFile( dir ) + If t="" Exit + If t="." Or t=".." Continue + Local f$=path+"/"+t + Select FileType( f ) + Case 1 DeleteFile f + Case 2 DeleteDir f,True + End Select + Forever + CloseDir dir + EndIf + rmdir_ path + If FileType( path )=0 Return True +End Function + +Rem +bbdoc: Change current directory +returns: True if successful +End Rem +Function ChangeDir( path$ ) + FixPath path,True + If chdir_( path )=0 Return True +End Function + +Rem +bbdoc: Open a directory +returns: An integer directory handle, or 0 if the directory does not exist +End Rem +Function ReadDir( path$ ) + FixPath path,True + Return opendir_( path ) +End Function + +Rem +bbdoc: Return next file in a directory +returns: File name of next file in directory opened using #ReadDir, or an empty string if there are no more files to read. +End Rem +Function NextFile$( dir ) + Return readdir_( dir ) +End Function + +Rem +bbdoc: Close a directory +End Rem +Function CloseDir( dir ) + closedir_ dir +End Function + +Rem +bbdoc: Load a directory +returns: A string array containing contents of @dir +about: The @skip_dots parameter, if true, removes the '.' (current) and '..' +(parent) directories from the returned array. +end rem +Function LoadDir$[]( dir$,skip_dots=True ) + FixPath dir,True + Local d=ReadDir( dir ) + If Not d Return + Local i$[100],n + Repeat + Local f$=NextFile( d ) + If Not f Exit + If skip_dots And (f="." Or f="..") Continue + If n=i.length i=i[..n+100] + i[n]=f + n=n+1 + Forever + CloseDir d + Return i[..n] +End Function + +Rem +bbdoc: Open a file for input and/or output. +about: +This command is similar to the #OpenStream command but will attempt +to cache the contents of the file to ensure serial streams such as +http: based url's are seekable. Use the #CloseStream command when +finished reading and or writing to a Stream returned by #OpenFile. +End Rem +Function OpenFile:TStream( url:Object,readable=True,writeable=True ) + Local stream:TStream=OpenStream( url,readable,writeable ) + If Not stream Return + If stream.Pos()=-1 Return TBankStream.Create( TBank.Load(stream) ) + Return stream +End Function + +Rem +bbdoc: Open a file for input. +about: +This command is similar to the #ReadStream command but will attempt +to cache the contents of the file to ensure serial streams such as +http: based url's are seekable. Use the #CloseStream command when +finished reading and or writing to a Stream returned by #OpenFile. +End Rem +Function ReadFile:TStream( url:Object ) + Return OpenFile( url,True,False ) +End Function + +Rem +bbdoc: Open a file for output. +about: +This command is identical to the #WriteStream command. +End Rem +Function WriteFile:TStream( url:Object ) + Return OpenFile( url,False,True ) +End Function + +Rem +bbdoc: Closes a file stream. +about: +After performing file operations on an open file make sure to +close the file stream with either #CloseFile or the identical +#CloseStream command. +End Rem +Function CloseFile( stream:TStream ) + stream.Close +End Function diff --git a/mod/brl.mod/font.mod/font.bmx b/mod/brl.mod/font.mod/font.bmx new file mode 100644 index 0000000..592c2ec --- /dev/null +++ b/mod/brl.mod/font.mod/font.bmx @@ -0,0 +1,67 @@ + +Strict + +Module BRL.Font + +ModuleInfo "Version: 1.05" +ModuleInfo "Author: Mark Sibly" +ModuleInfo "License: zlib/libpng" +ModuleInfo "Copyright: Blitz Research Ltd" +ModuleInfo "Modserver: BRL" + +ModuleInfo "History: 1.05 Release" +ModuleInfo "History: Modified interface for improved unicode support" + +Const BOLDFONT=1 +Const ITALICFONT=2 +Const SMOOTHFONT=4 + +Type TGlyph + + Method Pixels:Object() Abstract + + Method Advance#() Abstract + Method GetRect( x Var,y Var,width Var,height Var ) Abstract + +End Type + +Type TFont + + Method Style() Abstract + Method Height() Abstract + Method CountGlyphs() Abstract + Method CharToGlyph( char ) Abstract + Method LoadGlyph:TGlyph( index ) Abstract + +End Type + +Type TFontLoader + Field _succ:TFontLoader + + Method LoadFont:TFont( url:Object,size,style ) Abstract + +End Type + +Private + +Global _loaders:TFontloader + +Public + +Function AddFontLoader( loader:TFontLoader ) + If loader._succ Return + loader._succ=_loaders + _loaders=loader +End Function + +Function LoadFont:TFont( url:Object,size,style=SMOOTHFONT ) + + Local loader:TFontLoader=_loaders + + While loader + Local font:TFont=loader.LoadFont( url,size,style ) + If font Return font + loader=loader._succ + Wend + +End Function diff --git a/mod/brl.mod/freeaudioaudio.mod/freeaudioaudio.bmx b/mod/brl.mod/freeaudioaudio.mod/freeaudioaudio.bmx new file mode 100644 index 0000000..3d036c6 --- /dev/null +++ b/mod/brl.mod/freeaudioaudio.mod/freeaudioaudio.bmx @@ -0,0 +1,211 @@ + +Strict +Rem +bbdoc: Audio/FreeAudio audio +about: +The FreeAudio audio module provides FreeAudio drivers for use with the #audio module. +End Rem +Module BRL.FreeAudioAudio + +ModuleInfo "Version: 1.13" +ModuleInfo "Author: Mark Sibly" +ModuleInfo "License: zlib/libpng" +ModuleInfo "Copyright: Blitz Research Ltd" +ModuleInfo "Modserver: BRL" + +ModuleInfo "History: 1.13 Release" +ModuleInfo "History: Fixed bug in FreeChannel Playing()" +ModuleInfo "History: 1.12 Release" +ModuleInfo "History: Added call to fa_FreeChannel to TFreeAudioChannel destructor" +ModuleInfo "History: 1.11 Release" +ModuleInfo "History: Nudge" +ModuleInfo "History: 1.10 Release" +ModuleInfo "History: Bumped" +ModuleInfo "History: 1.08 Release" +ModuleInfo "History: Added src sample reference to TFreeAudioSound" +ModuleInfo "History: Channel playing now returns sample playback position" +ModuleInfo "History: 1.07 Release" +ModuleInfo "History: Added DirectSound driver" +ModuleInfo "History: 1.06 Release" +ModuleInfo "History: Added Method TFreeAudioChannel.Position" +ModuleInfo "History: 1.05 Release" +ModuleInfo "History: Mono and 8 bit sample support added" + +Import BRL.Audio +Import Pub.FreeAudio +Import Pub.DirectX + +Private + +Const CLOG=False + +Public + +Type TFreeAudioSound Extends TSound + + Field fa_sound + + Method Delete() + fa_FreeSound fa_sound + If CLOG WriteStdout "Deleted FreeAudio sound "+fa_sound+"~n" + End Method + + Method Play:TFreeAudioChannel( alloced_channel:TChannel ) + Local channel:TFreeAudioChannel,fa_channel + If alloced_channel + channel=TFreeAudioChannel( alloced_channel ) + If Not channel Return + fa_channel=channel.fa_channel + EndIf + fa_channel=fa_PlaySound(fa_sound,False,fa_channel) + If Not fa_channel Return + If channel And channel.fa_channel=fa_channel Return channel + Return TFreeAudioChannel.CreateWithChannel( fa_channel ) + End Method + + Method Cue:TFreeAudioChannel( alloced_channel:TChannel ) + Local channel:TFreeAudioChannel,fa_channel + If alloced_channel + channel=TFreeAudioChannel( alloced_channel ) + If Not channel Return + fa_channel=channel.fa_channel + EndIf + fa_channel=fa_PlaySound( fa_sound,True,fa_channel ) + If Not fa_channel Return + If channel And channel.fa_channel=fa_channel Return channel + Return TFreeAudioChannel.CreateWithChannel( fa_channel ) + End Method + + Function CreateWithSound:TFreeAudioSound( fa_sound,src:TAudioSample ) + Local t:TFreeAudioSound=New TFreeAudioSound + t.fa_sound=fa_sound +' t.src=src + Return t + End Function + +End Type + +Type TFreeAudioChannel Extends TChannel + + Field fa_channel + + Method Delete() + If fa_channel fa_FreeChannel fa_channel + End Method + + Method Stop() + fa_StopChannel fa_channel + fa_channel=0 + End Method + + Method SetPaused( paused ) + fa_SetChannelPaused fa_channel,paused + End Method + + Method SetVolume( volume# ) + fa_SetChannelVolume fa_channel,volume + End Method + + Method SetPan( pan# ) + fa_SetChannelPan fa_channel,pan + End Method + + Method SetDepth( depth# ) + fa_SetChannelDepth fa_channel,depth + End Method + + Method SetRate( rate# ) + fa_SetChannelRate fa_channel,rate + End Method + + Method Playing() + Local status=fa_ChannelStatus( fa_channel ) + If status=FA_CHANNELSTATUS_FREE Return False + If status&FA_CHANNELSTATUS_STOPPED Return False + If status&FA_CHANNELSTATUS_PAUSED Return False + Return True + End Method + + Method Position() + Return fa_ChannelPosition( fa_channel ) + End Method + + Function CreateWithChannel:TFreeAudioChannel( fa_channel ) + Local t:TFreeAudioChannel=New TFreeAudioChannel + t.fa_channel=fa_channel + Return t + End Function + +End Type + +Type TFreeAudioAudioDriver Extends TAudioDriver + + Method Name$() + Return _name + End Method + + Method Startup() + If _mode<>-1 Return fa_Init( _mode )<>-1 + If fa_Init( 0 )<>-1 Return True +?Win32 + Return fa_Init( 1 )<>-1 +? + End Method + + Method Shutdown() + fa_Close + End Method + + Method CreateSound:TFreeAudioSound( sample:TAudioSample,flags ) + Local channels,bits + + Select sample.format +?BigEndian + Case SF_MONO16LE + sample=sample.Convert(SF_MONO16BE) + Case SF_STEREO16LE + sample=sample.Convert(SF_STEREO16BE) +?LittleEndian + Case SF_MONO16BE + sample=sample.Convert(SF_MONO16LE) + Case SF_STEREO16BE + sample=sample.Convert(SF_STEREO16LE) +? + End Select + Local loop_flag + If (flags & 1) loop_flag=-1 + channels=ChannelsPerSample[sample.format] + If Not channels Return + bits=8*BytesPerSample[sample.format]/channels + Local fa_sound=fa_CreateSound( sample.length,bits,channels,sample.hertz,sample.samples,loop_flag ) + If CLOG WriteStdout "Generated FreeAudio sound "+fa_sound+"~n" + Return TFreeAudioSound.CreateWithSound( fa_sound,sample ) + End Method + + Method AllocChannel:TFreeAudioChannel() + Local fa_channel=fa_AllocChannel() + If fa_channel Return TFreeAudioChannel.CreateWithChannel( fa_channel ) + End Method + + Function Create:TFreeAudioAudioDriver( name$,mode ) + Local t:TFreeAudioAudioDriver=New TFreeAudioAudioDriver + t._name=name + t._mode=mode + Return t + End Function + + Field _name$,_mode + +End Type + +?Win32 +If DirectSoundCreate TFreeAudioAudioDriver.Create "FreeAudio DirectSound",1 +TFreeAudioAudioDriver.Create "FreeAudio Multimedia",0 +?MacOS +TFreeAudioAudioDriver.Create "FreeAudio CoreAudio",0 +?Linux +TFreeAudioAudioDriver.Create "FreeAudio OpenSound System",0 +'TFreeAudioAudioDriver.Create "FreeAudio ALSA System",1 +? +TFreeAudioAudioDriver.Create "FreeAudio",-1 + diff --git a/mod/brl.mod/freetypefont.mod/freetypefont.bmx b/mod/brl.mod/freetypefont.mod/freetypefont.bmx new file mode 100644 index 0000000..f4aeeca --- /dev/null +++ b/mod/brl.mod/freetypefont.mod/freetypefont.bmx @@ -0,0 +1,218 @@ + +Strict + +Module BRL.FreeTypeFont + +ModuleInfo "Version: 1.09" +ModuleInfo "Author: Simon Armstrong, Mark Sibly" +ModuleInfo "License: zlib/libpng" +ModuleInfo "Copyright: Blitz Research Ltd" +ModuleInfo "Modserver: BRL" + +ModuleInfo "History: 1.09 Release" +ModuleInfo "History: Offset glyph rect to allow for smooth font border" +ModuleInfo "History: 1.08 Release" +ModuleInfo "History: Fixed freetypelib being reopened per font" +ModuleInfo "History: 1.07 Release" +ModuleInfo "History: Added one pixel blank border around SMOOTHFONT glyphs for ultra smooth subpixel positioning." +ModuleInfo "History: 1.06 Release" +ModuleInfo "History: Fixed memory (incbin::) fonts" +ModuleInfo "History: 1.05 Release" +ModuleInfo "History: Improved unicode support" +ModuleInfo "History: Replaced stream hooks with New_Memory_Face" +ModuleInfo "History: 1.04 Release" +ModuleInfo "History: Added stream hooks" + +Import BRL.Font +Import BRL.Pixmap +Import Pub.FreeType + +Private + +Function PadPixmap:TPixmap( p:TPixmap ) + Local t:TPixmap=TPixmap.Create( p.width+2,p.height+2,p.format ) + MemClear t.pixels,t.capacity + t.Paste p,1,1 + Return t +End Function + +Public + +Type TFreeTypeGlyph Extends TGlyph + + Field _pixmap:TPixmap + Field _advance#,_x,_y,_w,_h + + Method Pixels:TPixmap() + If _pixmap Return _pixmap + + Return _pixmap + End Method + + Method Advance#() + Return _advance + End Method + + Method GetRect( x Var,y Var,w Var,h Var ) + x=_x + y=_y + w=_w + h=_h + End Method + +End Type + +Type TFreeTypeFont Extends BRL.Font.TFont + + Field _face:FTFace + Field _ft_face:Byte Ptr + Field _style,_height + Field _ascend,_descend + Field _glyphs:TFreeTypeGlyph[] + Field _buf:Byte Ptr,_buf_size + + Method Delete() + FT_Done_Face _ft_face + MemFree _buf + End Method + + Method Style() + Return _style + End Method + + Method Height() + Return _height + End Method + + Method CountGlyphs() + Return _glyphs.length + End Method + + Method CharToGlyph( char ) + Return FT_Get_Char_Index( _ft_face,char )-1 + End Method + + Method LoadGlyph:TFreeTypeGlyph( index ) + + Local glyph:TFreeTypeGlyph=_glyphs[index] + If glyph Return glyph + + glyph=New TFreeTypeGlyph + _glyphs[index]=glyph + + If FT_Load_Glyph( _ft_face,index+1,FT_LOAD_RENDER ) Return glyph + + Local slot:FTGlyph=New FTGlyph + MemCopy slot,_face.glyphslot,SizeOf slot + + glyph._x=slot.bitmap_left + glyph._y=-slot.bitmap_top+_ascend + glyph._w=slot.width + glyph._h=slot.rows + glyph._advance=slot.advancex Sar 6 + + If slot.width=0 Return glyph + + Local pixmap:TPixmap + + If slot.numgreys + pixmap=TPixmap.CreateStatic( slot.buffer,slot.width,slot.rows,slot.pitch,PF_A8 ).Copy() + Else + pixmap=CreatePixmap( slot.width,slot.rows,PF_A8 ) + Local b + For Local y=0 Until slot.rows + Local dst:Byte Ptr=pixmap.PixelPtr(0,y) + Local src:Byte Ptr=slot.buffer+y*slot.pitch + For Local x=0 Until slot.width + If (x&7)=0 b=src[x/8] + If b & $80 dst[x]=$ff Else dst[x]=0 + b:+b + Next + Next + EndIf + + If _style & SMOOTHFONT + glyph._x:-1 + glyph._y:-1 + glyph._w:+2 + glyph._h:+2 + pixmap=PadPixmap(pixmap) + EndIf + + glyph._pixmap=pixmap + + Return glyph + + End Method + + Function Load:TFreeTypeFont( src$,size,style ) + + Global ft_lib:Byte Ptr + + If Not ft_lib + If FT_Init_FreeType( Varptr ft_lib ) Return + EndIf + + Local buf:Byte Ptr,buf_size + + Local ft_face:Byte Ptr + + If src.Find( "::" )>0 + Local tmp:Byte[]=LoadByteArray( src ) + buf_size=tmp.length + If Not buf_size Return + buf=MemAlloc( buf_size ) + MemCopy buf,tmp,buf_size + If FT_New_Memory_Face( ft_lib,buf,buf_size,0,Varptr ft_face ) + MemFree buf + Return + EndIf + Else + If FT_New_Face( ft_lib,src$,0,Varptr ft_face ) Return + EndIf + + While size + If Not FT_Set_Pixel_Sizes( ft_face,0,size ) Exit + size:-1 + Wend + If Not size + FT_Done_Face ft_face + Return + EndIf + + Local face:FTFace=New FTFace + MemCopy face,ft_face,SizeOf face + + Local metrics:FTMetrics=New FTMetrics + MemCopy metrics,face.metrics,SizeOf metrics + + Local font:TFreeTypeFont=New TFreeTypeFont + font._face=face + font._ft_face=ft_face + font._style=style + font._height=metrics.height Sar 6 + font._ascend=metrics.ascend Sar 6 + font._descend=metrics.descend Sar 6 + font._glyphs=New TFreeTypeGlyph[face.numglyphs] + font._buf=buf + font._buf_size=buf_size + + Return font + + End Function + +End Type + +Type TFreeTypeFontLoader Extends TFontLoader + + Method LoadFont:TFreeTypeFont( url:Object,size,style ) + + Local src$=String( url ) + + If src Return TFreeTypeFont.Load( src,size,style ) + + End Method + +End Type + +AddFontLoader New TFreeTypeFontLoader diff --git a/mod/brl.mod/glgraphics.mod/gldrawtextfont.bin b/mod/brl.mod/glgraphics.mod/gldrawtextfont.bin new file mode 100644 index 0000000000000000000000000000000000000000..70a484cad2e07fc13151c0780a385695f2e119bd GIT binary patch literal 1536 zcmeH{ziJ#Y5XJ`=!xiG#Don8)F7g1vgk_7vb)Lc1lH#f@t}-bGVO-}K@+_*RG^w@< z#?_TBQlvUWzR_+jxnKfmTt#q_Mt^?#=9Bh_UZ=$H&*yAu+x&Ht_^ga$!>ypywJNHY zMT_bjswPdPsHLN^nMaz;?A}VC*pm=brafxnnNat6wHMb6zFH?C-uT#^wPukmn|Vke zp)i|C+@Y>TYMsMH92Y)Lk$B=S=eT4DcweTct_iUwo2|{cXRiE#f=!@<&)|3b{NQAE z{%AwsXtb*OJ&RxZ&-ri1H~V%KqPUsEL2`b_JV3BSlKdNg!{zbB@9i>#NYucuBTP-m zPeyomOuF?|R-pfr8#rnoD8%IaIEn7BQi^)Sw8mj7iS7EDi^MgTV#$(1|I{3t00BhE z)a>KV^ONFzD8mo=wbFmC{4ebz_);j5JP7Bjj3t>U&=42>2khVQ^c`kxGWM4~BW36N zwHI;zMz9$6wSInYaV`6AJyw)yeG7i|KN$EaTW~(~%kAtxM0Fk80k97Iv5Yx{!TEK5 z;XB@V@AJJ0^naNBG3VbjLc-u%^gXlxgbpIq((Sy@yB(72pV13>=3}(-JNL!6V!n(P zmiI$rlfSw@&cDE8*Qm;>B6vT7hmRpf(;Dnm-WqPRv3o7yE>a=fr{Ax|xPva-FJpf* z+R^V9?{g{sc{M+Sxy8r}<>@qr@9Web@HA?`xi+|WI^+BQ!)lpYnm>*^pG1WJhtn8( SZ4EdtW4e65OZdNe*?}L)+Bv!a literal 0 HcmV?d00001 diff --git a/mod/brl.mod/glgraphics.mod/glgraphics.bmx b/mod/brl.mod/glgraphics.mod/glgraphics.bmx new file mode 100644 index 0000000..e688d5c --- /dev/null +++ b/mod/brl.mod/glgraphics.mod/glgraphics.bmx @@ -0,0 +1,376 @@ + +Strict + +Rem +bbdoc: Graphics/OpenGL Graphics +End Rem +Module BRL.GLGraphics + +ModuleInfo "Version: 1.14" +ModuleInfo "Author: Mark Sibly, Simon Armstrong" +ModuleInfo "License: zlib/libpng" +ModuleInfo "Copyright: Blitz Research Ltd" +ModuleInfo "Modserver: BRL" + +ModuleInfo "History: 1.14 Release" +ModuleInfo "History: Adjusted graphics size after creating window" +ModuleInfo "History: 1.13 Release" +ModuleInfo "History: Implemented Brucey's linux window title fix" +ModuleInfo "History: 1.12 Release" +ModuleInfo "History: Added GLDrawPixmp" +ModuleInfo "History: 1.11 Release" +ModuleInfo "History: Trapped Win32 WM_CLOSE" +ModuleInfo "History: 1.10 Release" +ModuleInfo "History: Added extra check for use of flip sync extensions under Linux" +ModuleInfo "History: 1.09 Release" +ModuleInfo "History: Fixed MacOS shared context" +ModuleInfo "History: 1.08 Release" +ModuleInfo "History: Minor maintanance" +ModuleInfo "History: 1.07 Release" +ModuleInfo "History: Fixed Linux _calchertz" +ModuleInfo "History: 1.06 Release" +ModuleInfo "History: Changed MacOS DisplayCapture to CaptureAllDisplays" +ModuleInfo "History: 1.05 Release" +ModuleInfo "History: Added SetAcceptsMouseMovedEvents to MacOS windowed mode" +ModuleInfo "History: 1.04 Release" +ModuleInfo "History: Fixed (removed for now) MacOS atexit issue" +ModuleInfo "History: 1.03 Release" +ModuleInfo "History: Linux fullscreen fixed" +ModuleInfo "History: 1.02 Release" +ModuleInfo "History: Added AppTitle support" +ModuleInfo "History: 1.01 Release" +ModuleInfo "History: Added graphics flags handling" + +Import BRL.Graphics +Import BRL.Pixmap +Import Pub.OpenGL + +?Win32 +Import "glgraphics.win32.c" +?MacOS +Import "glgraphics.macos.m" +?Linux +Import "-lX11" +Import "-lXxf86vm" +Import "-lGL" +Import "glgraphics.linux.c" +? + +Private + +Incbin "gldrawtextfont.bin" + +Extern + Function bbGLGraphicsShareContexts() + Function bbGLGraphicsGraphicsModes( buf:Byte Ptr,size ) + Function bbGLGraphicsAttachGraphics( widget,flags ) + Function bbGLGraphicsCreateGraphics( width,height,depth,hertz,flags ) + Function bbGLGraphicsGetSettings( context,width Var,height Var,depth Var,hertz Var,flags Var ) + Function bbGLGraphicsClose( context ) + Function bbGLGraphicsSetGraphics( context ) + Function bbGLGraphicsFlip( sync ) +End Extern + +Public + +Type TGLGraphics Extends TGraphics + + Method Driver:TGLGraphicsDriver() + Assert _context + Return GLGraphicsDriver() + End Method + + Method GetSettings( width Var,height Var,depth Var,hertz Var,flags Var ) + Assert _context + Local w,h,d,r,f + bbGLGraphicsGetSettings _context,w,h,d,r,f + width=w + height=h + depth=d + hertz=r + flags=f + End Method + + Method Close() + If Not _context Return + bbGLGraphicsClose( _context ) + _context=0 + End Method + + Field _context + +End Type + +Type TGLGraphicsDriver Extends TGraphicsDriver + + Method GraphicsModes:TGraphicsMode[]() + Local buf[1024*4] + Local count=bbGLGraphicsGraphicsModes( buf,1024 ) + Local modes:TGraphicsMode[count],p:Int Ptr=buf + For Local i=0 Until count + Local t:TGraphicsMode=New TGraphicsMode + t.width=p[0] + t.height=p[1] + t.depth=p[2] + t.hertz=p[3] + modes[i]=t + p:+4 + Next + Return modes + End Method + + Method AttachGraphics:TGLGraphics( widget,flags ) + Local t:TGLGraphics=New TGLGraphics + t._context=bbGLGraphicsAttachGraphics( widget,flags ) + Return t + End Method + + Method CreateGraphics:TGLGraphics( width,height,depth,hertz,flags ) + Local t:TGLGraphics=New TGLGraphics + t._context=bbGLGraphicsCreateGraphics( width,height,depth,hertz,flags ) + Return t + End Method + + Method SetGraphics( g:TGraphics ) + Local context + Local t:TGLGraphics=TGLGraphics( g ) + If t context=t._context + bbGLGraphicsSetGraphics context + End Method + + Method Flip( sync ) + bbGLGraphicsFlip sync + End Method + +End Type + +Rem +bbdoc: Get OpenGL graphics driver +returns: An OpenGL graphics driver +about: +The returned driver can be used with #SetGraphicsDriver +End Rem +Function GLGraphicsDriver:TGLGraphicsDriver() + Global _driver:TGLGraphicsDriver=New TGLGraphicsDriver + Return _driver +End Function + +Rem +bbdoc: Create OpenGL graphics +returns: An OpenGL graphics object +about: +This is a convenience function that allows you to easily create an OpenGL graphics context. +End Rem +Function GLGraphics:TGraphics( width,height,depth=0,hertz=60,flags=GRAPHICS_BACKBUFFER|GRAPHICS_DEPTHBUFFER ) + SetGraphicsDriver GLGraphicsDriver() + Return Graphics( width,height,depth,hertz,flags ) +End Function + +SetGraphicsDriver GLGraphicsDriver() + +'----- Helper Functions ----- + +Private + +Global fontTex +Global fontSeq + +Global ortho_mv![16],ortho_pj![16] + +Function BeginOrtho() + Local vp[4] + + glPushAttrib GL_ENABLE_BIT|GL_TEXTURE_BIT|GL_TRANSFORM_BIT + + glGetIntegerv GL_VIEWPORT,vp + glGetDoublev GL_MODELVIEW_MATRIX,ortho_mv + glGetDoublev GL_PROJECTION_MATRIX,ortho_pj + + glMatrixMode GL_MODELVIEW + glLoadIdentity + glMatrixMode GL_PROJECTION + glLoadIdentity + glOrtho 0,vp[2],vp[3],0,-1,1 + + glDisable GL_CULL_FACE + glDisable GL_ALPHA_TEST + glDisable GL_DEPTH_TEST +End Function + +Function EndOrtho() + glMatrixMode GL_PROJECTION + glLoadMatrixd ortho_pj + glMatrixMode GL_MODELVIEW + glLoadMatrixd ortho_mv + + glPopAttrib +End Function + +Public + +Rem +bbdoc: Helper function to calculate nearest valid texture size +about: This functions rounds @width and @height up to the nearest valid texture size +End Rem +Function GLAdjustTexSize( width Var,height Var ) + Function Pow2Size( n ) + Local t=1 + While t1 width:/2 + If height>1 height:/2 + Forever +End Function + +Rem +bbdoc: Helper function to create a texture from a pixmap +returns: Integer GL Texture name +about: @pixmap is resized to a valid texture size before conversion. +end rem +Function GLTexFromPixmap( pixmap:TPixmap,mipmap=True ) + If pixmap.format<>PF_RGBA8888 pixmap=pixmap.Convert( PF_RGBA8888 ) + Local width=pixmap.width,height=pixmap.height + GLAdjustTexSize width,height + If width<>pixmap.width Or height<>pixmap.height pixmap=ResizePixmap( pixmap,width,height ) + + Local old_name,old_row_len + glGetIntegerv GL_TEXTURE_BINDING_2D,Varptr old_name + glGetIntegerv GL_UNPACK_ROW_LENGTH,Varptr old_row_len + + Local name + glGenTextures 1,Varptr name + glBindtexture GL_TEXTURE_2D,name + + Local mip_level + Repeat + glPixelStorei GL_UNPACK_ROW_LENGTH,pixmap.pitch/BytesPerPixel[pixmap.format] + glTexImage2D GL_TEXTURE_2D,mip_level,GL_RGBA8,width,height,0,GL_RGBA,GL_UNSIGNED_BYTE,pixmap.pixels + If Not mipmap Exit + If width=1 And height=1 Exit + If width>1 width:/2 + If height>1 height:/2 + pixmap=ResizePixmap( pixmap,width,height ) + mip_level:+1 + Forever + + glBindTexture GL_TEXTURE_2D,old_name + glPixelStorei GL_UNPACK_ROW_LENGTH,old_row_len + + Return name +End Function + +Rem +bbdoc:Helper function to output a simple rectangle +about: +Draws a rectangle relative to top-left of current viewport. +End Rem +Function GLDrawRect( x,y,width,height ) + BeginOrtho + glBegin GL_QUADS + glVertex2i x,y + glVertex2i x+width,y + glVertex2i x+width,y+height + glVertex2i x,y+height + glEnd + EndOrtho +End Function + +Rem +bbdoc: Helper function to output some simple 8x16 font text +about: +Draws text relative to top-left of current viewport.
+
+The font used is an internal fixed point 8x16 font.
+
+This function is intended for debugging purposes only - performance is unlikely to be stellar. +End Rem +Function GLDrawText( text$,x,y ) +' If fontSeq<>graphicsSeq + If Not fontTex + Local pixmap:TPixmap=TPixmap.Create( 1024,16,PF_RGBA8888 ) + Local p:Byte Ptr=IncbinPtr( "gldrawtextfont.bin" ) + For Local y=0 Until 16 + For Local x=0 Until 96 + Local b=p[x] + For Local n=0 Until 8 + If b & (1 Shl n) + pixmap.WritePixel x*8+n,y,~0 + Else + pixmap.WritePixel x*8+n,y,0 + EndIf + Next + Next + p:+96 + Next + fontTex=GLTexFromPixmap( pixmap ) + fontSeq=graphicsSeq + EndIf + + BeginOrtho + + glEnable GL_TEXTURE_2D + glBindTexture GL_TEXTURE_2D,fontTex + + For Local i=0 Until text.length + Local c=text[i]-32 + If c>=0 And c<96 + Const adv#=8/1024.0 + Local t#=c*adv; + glBegin GL_QUADS + glTexcoord2f t,0 + glVertex2f x,y + glTexcoord2f t+adv,0 + glVertex2f x+8,y + glTexcoord2f t+adv,1 + glVertex2f x+8,y+16 + glTexcoord2f t,1 + glVertex2f x,y+16 + glEnd + EndIf + x:+8 + Next + + EndOrtho +End Function + +Rem +bbdoc: Helper function to draw a pixmap to a gl context +about: +Draws the pixmap relative to top-left of current viewport.
+
+This function is intended for debugging purposes only - performance is unlikely to be stellar. +End Rem +Function GLDrawPixmap( pixmap:TPixmap,x,y ) + BeginOrtho + + Local t:TPixmap=YFlipPixmap(pixmap) + If t.format<>PF_RGBA8888 t=ConvertPixmap( t,PF_RGBA8888 ) + glRasterPos2i 0,0 + glBitmap 0,0,0,0,x,-y-t.height,Null + glDrawPixels t.width,t.height,GL_RGBA,GL_UNSIGNED_BYTE,t.pixels + + EndOrtho +End Function + +Rem +bbdoc: Enable OpenGL context sharing +about: +Calling #GLShareContexts will cause all opengl graphics contexts created to +shared displaylists, textures, shaders etc. + +This should be called before any opengl contexts are created. +End Rem +Function GLShareContexts() + bbGLGraphicsShareContexts +End Function diff --git a/mod/brl.mod/glgraphics.mod/glgraphics.linux.c b/mod/brl.mod/glgraphics.mod/glgraphics.linux.c new file mode 100644 index 0000000..13c54a1 --- /dev/null +++ b/mod/brl.mod/glgraphics.mod/glgraphics.linux.c @@ -0,0 +1,429 @@ + +#include +#include +#include +#include +#include + +/* Added by BaH */ +#include +#include + +extern void bbSystemPoll(); +extern Display *bbSystemDisplay(); +extern void bbSetSystemWindow(int window); + +static XF86VidModeModeInfo **modes,*mode; +static Display *xdisplay; + +static int xscreen,xwindow,xfullscreen; + +typedef int (* GLXSWAPINTERVALEXT) (int); + +GLXSWAPINTERVALEXT glXSwapIntervalEXT; + +void *glXExtension(Display *dpy,int screen,const char *catagory,const char *name){ + const char *extensions; + extensions=glXQueryExtensionsString(dpy,screen); + if (strstr(extensions,catagory)) { + return (void*)glXGetProcAddressARB(name); + } + return (void*)0; +} + +enum{ + MODE_SHARED=0, + MODE_WIDGET=1, + MODE_WINDOW=2, + MODE_DISPLAY=3 +}; + +enum{ + FLAGS_BACKBUFFER= 0x2, + FLAGS_ALPHABUFFER= 0x4, + FLAGS_DEPTHBUFFER= 0x8, + FLAGS_STENCILBUFFER=0x10, + FLAGS_ACCUMBUFFER= 0x20, + FLAGS_FULLSCREEN=0x80000000 +}; + +typedef struct BBGLContext BBGLContext; + +struct BBGLContext{ + int mode,width,height,depth,hertz,flags,sync; + int window; + GLXContext glContext; +}; + +// glgraphics.bmx interface + +int bbGLGraphicsGraphicsModes( int *imodes,int maxcount ); +BBGLContext *bbGLGraphicsAttachGraphics( int window,int flags ); +BBGLContext *bbGLGraphicsCreateGraphics( int width,int height,int depth,int hz,int flags ); +void bbGLGraphicsGetSettings( BBGLContext *context,int *width,int *height,int *depth,int *hz,int *flags ); +void bbGLGraphicsClose( BBGLContext *context ); +void bbGLGraphicsSetGraphics( BBGLContext *context ); +void bbGLGraphicsFlip( int sync ); +void bbGLExit(); + +static BBGLContext *_currentContext; +static BBGLContext *_activeContext; +static BBGLContext *_sharedContext; + +#define INTERLACE 0x010 +#define DBLSCAN 0x020 + +static XF86VidModeModeInfo _oldMode; + +int _calchertz(XF86VidModeModeInfo *m){ + int freq; + freq=(m->dotclock*1000.0)/(m->htotal*m->vtotal)+.5; + if (m->flags&INTERLACE) freq<<=1; + if (m->flags&DBLSCAN) freq>>=1; + return freq; +} + +int _initDisplay(){ + int major,minor; + if (xdisplay) return 0; + xdisplay=bbSystemDisplay(); + if (!xdisplay) return -1; + if (glXQueryVersion(xdisplay,&major,&minor)==0) return -1; + +// printf("glXVersion=%d.%d\n",major,minor);fflush(stdout); + + XF86VidModeQueryVersion(xdisplay,&major,&minor); + +// printf("XF86VidModeExtension-Version %d.%d\n", major,minor); + + xscreen=DefaultScreen(xdisplay); + +// glXSwapIntervalEXT=(GLXSWAPINTERVALEXT)glXGetProcAddressARB("glXSwapIntervalSGI"); + + glXSwapIntervalEXT=(GLXSWAPINTERVALEXT)glXExtension(xdisplay,xscreen,"GLX_SGI_swap_control","glXSwapIntervalSGI"); + atexit( bbGLExit ); + return 0; +} + +int bbGLGraphicsGraphicsModes( int *imodes,int maxcount ){ + XF86VidModeModeInfo **xmodes,*m; + int count,i; + + if (_initDisplay()) return 0; + XF86VidModeGetAllModeLines(xdisplay,xscreen,&count,&xmodes); + if (count>maxcount) count=maxcount; + for (i=0;ihdisplay; //width + *imodes++=m->vdisplay; //height; + *imodes++=24; + *imodes++=_calchertz(m); + } + XFree(xmodes); + return count; +} + +static void _swapBuffers( BBGLContext *context ){ + if( !context ) return; + glXSwapBuffers(xdisplay,context->window); + bbSystemPoll(); +} + +BBGLContext *bbGLGraphicsAttachGraphics( int window,int flags ){ + BBGLContext *context=(BBGLContext*)malloc( sizeof(BBGLContext) ); + memset( context,0,sizeof(BBGLContext) ); + context->mode=MODE_WIDGET; + context->flags=flags; + context->sync=-1; + context->window=window; + return context; +} + +XVisualInfo *_chooseVisual(flags){ + int glspec[32],*s; + s=glspec; + *s++=GLX_RGBA; + if (flags&FLAGS_BACKBUFFER) *s++=GLX_DOUBLEBUFFER; + if (flags&FLAGS_ALPHABUFFER) {*s++=GLX_ALPHA_SIZE;*s++=1;} + if (flags&FLAGS_DEPTHBUFFER) {*s++=GLX_DEPTH_SIZE;*s++=1;} + if (flags&FLAGS_STENCILBUFFER) {*s++=GLX_STENCIL_SIZE;*s++=1;} + if (flags&FLAGS_ACCUMBUFFER) + { + *s++=GLX_ACCUM_RED_SIZE;*s++=1; + *s++=GLX_ACCUM_GREEN_SIZE;*s++=1; + *s++=GLX_ACCUM_BLUE_SIZE;*s++=1; + *s++=GLX_ACCUM_ALPHA_SIZE;*s++=1; + } + *s++=None; + return glXChooseVisual(xdisplay,xscreen,glspec); +} + +void _makeCurrent( BBGLContext *context ){ + glXMakeCurrent(xdisplay,context->window,context->glContext); + _currentContext=context; +} + +static void _validateSize( BBGLContext *context ){ + Window root_return; + int x,y; + unsigned int w,h,border,d; + if( !context || context->mode!=MODE_WIDGET ) return; + if (_initDisplay()) return; + XGetGeometry(xdisplay,context->window,&root_return,&x,&y,&w,&h,&border,&d); + context->width=w; + context->height=h; +} + +static void _validateContext( BBGLContext *context ){ + GLXContext sharedcontext=0; + XVisualInfo *vizinfo; + + if( !context || context->glContext ) return; + + if (_initDisplay()) return; + + //_initSharedContext(); + if( _sharedContext ) sharedcontext=_sharedContext->glContext; + + vizinfo=_chooseVisual(context->flags); + context->glContext=glXCreateContext(xdisplay,vizinfo,sharedcontext,True); + glXMakeCurrent(xdisplay,context->window,context->glContext); + bbSetSystemWindow(context->window); +} + +void bbGLGraphicsGetSettings( BBGLContext *context,int *width,int *height,int *depth,int *hertz,int *flags ){ + _validateSize( context ); + *width=context->width; + *height=context->height; + *depth=context->depth; + *hertz=context->hertz; + *flags=context->flags; +} + +static Bool WaitForNotify(Display *display,XEvent *event,XPointer arg){ + return (event->type==MapNotify) && (event->xmap.window==(Window)arg); +} + +void bbGLGraphicsShareContexts(){ + if( _sharedContext ) return; + _sharedContext=bbGLGraphicsCreateGraphics(0,0,0,0,0); +} + +BBGLContext *bbGLGraphicsCreateGraphics( int width,int height,int depth,int hz,int flags ){ + XSetWindowAttributes swa; + XVisualInfo *vizinfo; + XEvent event; + GLXContext context; + int window; + int count,i; + int displaymode; + int initingShared=0; + GLXContext sharedcontext=0; + char *appTitle; + + if (_initDisplay()) return 0; + + if( width==0 && height==0 ) + { + width=100; + height=100; + initingShared=1; + } + else + { + if( _sharedContext ) sharedcontext=_sharedContext->glContext; + + //_initSharedContext(); + //sharedcontext=_sharedContext->glContext; + } + + vizinfo=_chooseVisual(flags); + + if (depth) + { + XF86VidModeGetModeLine(xdisplay,xscreen,&_oldMode.dotclock,(XF86VidModeModeLine*)&_oldMode.hdisplay ); + + XF86VidModeGetAllModeLines(xdisplay,xscreen,&count,&modes); + mode=0; + for (i=0;ihdisplay && height==modes[i]->vdisplay && hz==_calchertz(modes[i])) + { + mode=modes[i]; + break; + } + } + if (mode==0) + { + for (i=0;ihdisplay && height==modes[i]->vdisplay) + { + mode=modes[i]; + break; + } + } + } + if (mode==0) return; + width=mode->hdisplay; + height=mode->vdisplay; + vizinfo=_chooseVisual(flags); + + swa.border_pixel=0; + swa.event_mask=StructureNotifyMask; + swa.colormap=XCreateColormap(xdisplay,RootWindow(xdisplay,0),vizinfo->visual,AllocNone); + swa.override_redirect=True; + + XF86VidModeSwitchToMode(xdisplay,xscreen,mode); + XF86VidModeSetViewPort(xdisplay,xscreen,0,0); + + window=XCreateWindow( + xdisplay, + RootWindow(xdisplay,xscreen), + 0, + 0, + width,height, + 0, + vizinfo->depth, + InputOutput, + vizinfo->visual, + CWBorderPixel|CWEventMask|CWColormap|CWOverrideRedirect, + &swa + ); + + xfullscreen=1; + displaymode=MODE_DISPLAY; + } + else + { + Atom atom; + XSizeHints *hints; + + swa.border_pixel=0; + swa.event_mask=StructureNotifyMask; + swa.colormap=XCreateColormap( xdisplay,RootWindow(xdisplay,0),vizinfo->visual,AllocNone ); + + window=XCreateWindow( + xdisplay, + RootWindow(xdisplay,xscreen), + 0, + 0, + width,height, + 0, + vizinfo->depth, + InputOutput, + vizinfo->visual, + CWBorderPixel|CWColormap|CWEventMask, + &swa + ); + + //Tell window to send us 'close window events' + atom=XInternAtom( xdisplay,"WM_DELETE_WINDOW",True ); + XSetWMProtocols( xdisplay,window,&atom,1 ); + + //Set window min/max size + hints=XAllocSizeHints(); + hints->flags=PMinSize|PMaxSize; + hints->min_width=hints->max_width=width; + hints->min_height=hints->max_height=height; + XSetWMNormalHints( xdisplay,window,hints ); + + displaymode=MODE_WINDOW; + } + + context=glXCreateContext(xdisplay,vizinfo,sharedcontext,True); + + if( !initingShared ) + { + XMapRaised(xdisplay,window); + if (xfullscreen) + { + XWarpPointer(xdisplay,None,window,0,0,0,0,0,0); + XGrabKeyboard(xdisplay,window,True,GrabModeAsync,GrabModeAsync,CurrentTime); + XGrabPointer(xdisplay,window,True,ButtonPressMask,GrabModeAsync,GrabModeAsync,window,None,CurrentTime); + } + glXMakeCurrent(xdisplay,window,context); + XIfEvent(xdisplay,&event,WaitForNotify,(XPointer)window); + XSelectInput(xdisplay,window,ResizeRedirectMask|PointerMotionMask|ButtonPressMask|ButtonReleaseMask|KeyPressMask|KeyReleaseMask); + xwindow=window; + bbSetSystemWindow(xwindow); + } + + appTitle=bbTmpUTF8String( bbAppTitle ); + + XChangeProperty( xdisplay,window, + XInternAtom( xdisplay,"_NET_WM_NAME",True ), + XInternAtom( xdisplay,"UTF8_STRING",True ), + 8,PropModeReplace,appTitle,strlen( appTitle ) ); + +// XStoreName( xdisplay,window,appTitle ); + + bbSystemPoll(); + + BBGLContext *bbcontext=(BBGLContext*)malloc( sizeof(BBGLContext) ); + memset( bbcontext,0,sizeof(BBGLContext) ); + bbcontext->mode=displaymode; + bbcontext->width=width; + bbcontext->height=height; + bbcontext->depth=24; + bbcontext->hertz=hz; + bbcontext->flags=flags; + bbcontext->sync=-1; + bbcontext->window=window; + bbcontext->glContext=context; + return bbcontext; +} + +void bbGLGraphicsSetGraphics( BBGLContext *context ){ + if( context ){ + _validateSize( context ); + _validateContext( context ); + } + if( !context || context==_currentContext ) return; + _makeCurrent(context); + _activeContext=context; +} + +void bbGLGraphicsFlip( int sync ){ + if( !_currentContext ) return; + sync=sync ? 1 : 0; + if( sync!=_currentContext->sync ){ + _currentContext->sync=sync; + if ( glXSwapIntervalEXT ) { + glXSwapIntervalEXT( sync ); + } + } + _swapBuffers( _currentContext ); +} + +void bbGLGraphicsClose( BBGLContext *context ){ + if (context){ + if (_currentContext==context) _currentContext=0; + if (context->glContext) + { + glXMakeCurrent(xdisplay,None,NULL); + glXDestroyContext(xdisplay,context->glContext); + } + if (context->window && context->mode!=MODE_WIDGET){ + XDestroyWindow(xdisplay,context->window); + } + if (context->mode==MODE_DISPLAY){ + XF86VidModeSwitchToMode(xdisplay,xscreen,&_oldMode); + XF86VidModeSetViewPort(xdisplay,xscreen,0,0); + XFlush(xdisplay); + XFree(modes); + modes=0; + mode=0; + xfullscreen=0; + } + free( context ); + } +} + +void bbGLExit(){ + bbGLGraphicsClose( _currentContext ); + bbGLGraphicsClose( _sharedContext ); + _currentContext=0; + _sharedContext=0; +} diff --git a/mod/brl.mod/glgraphics.mod/glgraphics.macos.m b/mod/brl.mod/glgraphics.mod/glgraphics.macos.m new file mode 100644 index 0000000..6aa2935 --- /dev/null +++ b/mod/brl.mod/glgraphics.mod/glgraphics.macos.m @@ -0,0 +1,343 @@ + +#include +#include +#include +#include + +#include + +enum{ + FLAGS_BACKBUFFER= 0x2, + FLAGS_ALPHABUFFER= 0x4, + FLAGS_DEPTHBUFFER= 0x8, + FLAGS_STENCILBUFFER=0x10, + FLAGS_ACCUMBUFFER= 0x20, + FLAGS_FULLSCREEN= 0x80000000 +}; + +enum{ + MODE_WIDGET= 1, + MODE_WINDOW= 2, + MODE_DISPLAY= 3 +}; + +@interface BBGLWindow : NSWindow{ +} +@end +@implementation BBGLWindow +-(void)sendEvent:(NSEvent*)event{ + bbSystemEmitOSEvent( event,[self contentView],&bbNullObject ); + switch( [event type] ){ + case NSKeyDown:case NSKeyUp: + //prevent 'beeps'! + return; + } + [super sendEvent:event]; +} +-(BOOL)windowShouldClose:(id)sender{ + bbSystemEmitEvent( BBEVENT_APPTERMINATE,&bbNullObject,0,0,0,0,&bbNullObject ); + return NO; +} +- (BOOL)canBecomeKeyWindow{ + return YES; +} +@end + +typedef struct BBGLContext BBGLContext; + +struct BBGLContext{ + int mode,width,height,depth,hertz,flags,sync; + + NSView *view; + BBGLWindow *window; + NSOpenGLContext *glContext; +}; + +static BBGLContext *_currentContext; +static BBGLContext *_displayContext; + +static CFDictionaryRef oldDisplayMode; + +extern void bbFlushAutoreleasePool(); + +void bbGLGraphicsClose( BBGLContext *context ); +void bbGLGraphicsGetSettings( BBGLContext *context,int *width,int *height,int *depth,int *hertz,int *flags ); +void bbGLGraphicsSetGraphics( BBGLContext *context ); + +static int _initAttrs( CGLPixelFormatAttribute attrs[16],int flags ){ + int n=0; + if( flags & FLAGS_BACKBUFFER ) attrs[n++]=kCGLPFADoubleBuffer; + if( flags & FLAGS_ALPHABUFFER ){ attrs[n++]=kCGLPFAAlphaSize;attrs[n++]=1; } + if( flags & FLAGS_DEPTHBUFFER ){ attrs[n++]=kCGLPFADepthSize;attrs[n++]=1; } + if( flags & FLAGS_STENCILBUFFER ){ attrs[n++]=kCGLPFAStencilSize;attrs[n++]=1; } + if( flags & FLAGS_ACCUMBUFFER ){ attrs[n++]=kCGLPFAAccumSize;attrs[n++]=1; } + if( flags & FLAGS_FULLSCREEN ){ + attrs[n++]=kCGLPFAFullScreen; + attrs[n++]=kCGLPFADisplayMask; + attrs[n++]=CGDisplayIDToOpenGLDisplayMask( kCGDirectMainDisplay ); + }else{ + attrs[n++]=kCGLPFANoRecovery; + } + attrs[n]=0; + return n; +} + +static NSOpenGLContext *_sharedContext; + +static void _validateSize( BBGLContext *context ){ + NSRect rect; + + if( !context || context->mode!=MODE_WIDGET ) return; + + rect=[context->view bounds]; + if( rect.size.width==context->width && rect.size.height==context->height ) return; + + context->width=rect.size.width; + context->height=rect.size.height; + + if( context->glContext ) [context->glContext update]; +} + +static void _validateContext( BBGLContext *context ){ + int flags; + NSOpenGLContext *shared; + NSOpenGLContext *glContext; + NSOpenGLPixelFormat *glFormat; + CGLPixelFormatAttribute attrs[16]; + + if( !context || context->glContext ) return; + + flags=context->flags; + +// if( context->mode==MODE_DISPLAY ) flags|=FLAGS_FULLSCREEN; + + _initAttrs( attrs,flags ); + + glFormat=[[NSOpenGLPixelFormat alloc] initWithAttributes:attrs]; + glContext=[[NSOpenGLContext alloc] initWithFormat:glFormat shareContext:_sharedContext]; + [glFormat release]; + + if( !glContext ) bbExThrowCString( "Unable to create GL Context" ); + + switch( context->mode ){ + case MODE_WIDGET: + [glContext setView:context->view]; + break; + case MODE_WINDOW: + case MODE_DISPLAY: + [glContext setView:[context->window contentView]]; + break; + } + + context->glContext=glContext; +} + +void bbGLGraphicsShareContexts(){ + NSOpenGLPixelFormat *glFormat; + CGLPixelFormatAttribute attrs[16]; + + if( _sharedContext ) return; + + _initAttrs( attrs,0 ); + glFormat=[[NSOpenGLPixelFormat alloc] initWithAttributes:attrs]; + _sharedContext=[[NSOpenGLContext alloc] initWithFormat:glFormat shareContext:0]; + [glFormat release]; +} + +int bbGLGraphicsGraphicsModes( int *modes,int count ){ + int i=0,n=0,sz; + CFArrayRef displayModeArray; + + displayModeArray=CGDisplayAvailableModes( kCGDirectMainDisplay ); + sz=CFArrayGetCount( displayModeArray ); + + while( imode=MODE_WIDGET; + context->width=rect.size.width; + context->height=rect.size.height; + context->flags=flags; + context->sync=-1; + + context->view=view; + + return context; +} + +BBGLContext *bbGLGraphicsCreateGraphics( int width,int height,int depth,int hertz,int flags ){ + int mode; + BBGLWindow *window=0; + BBGLContext *context; + int sysv=0; + + Gestalt( 'sysv',&sysv ); + + if( depth ){ + + CFDictionaryRef displayMode; + CGCaptureAllDisplays(); + + oldDisplayMode=CGDisplayCurrentMode( kCGDirectMainDisplay ); + CFRetain( (CFTypeRef)oldDisplayMode ); + + if( !hertz ){ + displayMode=CGDisplayBestModeForParameters( kCGDirectMainDisplay,depth,width,height,0 ); + }else{ + displayMode=CGDisplayBestModeForParametersAndRefreshRate( kCGDirectMainDisplay,depth,width,height,hertz,0 ); + } + if( CGDisplaySwitchToMode( kCGDirectMainDisplay,displayMode ) ){ + CFRelease( (CFTypeRef)oldDisplayMode ); + bbExThrowCString( "Unable to set display mode" ); + } + HideMenuBar(); + + window=[[NSWindow alloc] + initWithContentRect:NSMakeRect( 0,0,width,height ) + styleMask:NSBorderlessWindowMask + backing:NSBackingStoreBuffered + defer:YES]; + + [window setOpaque:YES]; + [window setBackgroundColor:[NSColor blackColor]]; + [window setLevel:CGShieldingWindowLevel()]; + + [window makeKeyAndOrderFront:NSApp]; + + mode=MODE_DISPLAY; + + }else{ + + window=[[BBGLWindow alloc] + initWithContentRect:NSMakeRect( 0,0,width,height ) + styleMask:NSTitledWindowMask|NSClosableWindowMask + backing:NSBackingStoreBuffered + defer:YES]; + + if( !window ) return 0; + + [window setDelegate:window]; + [window setAcceptsMouseMovedEvents:YES]; + + [window setTitle:[NSString stringWithUTF8String:bbTmpUTF8String(bbAppTitle)]]; + [window center]; + + [window makeKeyAndOrderFront:NSApp]; + + mode=MODE_WINDOW; + } + + context=(BBGLContext*)malloc( sizeof(BBGLContext) ); + memset( context,0,sizeof(BBGLContext) ); + + context->mode=mode; + context->width=width; + context->height=height; + context->depth=depth; + context->hertz=hertz; + context->flags=flags; + context->sync=-1; + context->window=window; + + if( mode==MODE_DISPLAY ) _displayContext=context; + + return context; +} + +void bbGLGraphicsGetSettings( BBGLContext *context,int *width,int *height,int *depth,int *hertz, int *flags ){ + _validateSize( context ); + *width=context->width; + *height=context->height; + *depth=context->depth; + *hertz=context->hertz; + *flags=context->flags; +} + +void bbGLGraphicsClose( BBGLContext *context ){ + if( context==_currentContext ) bbGLGraphicsSetGraphics( 0 ); + + [context->glContext clearDrawable]; + [context->glContext release]; + + switch( context->mode ){ + case MODE_WINDOW: + case MODE_DISPLAY: + bbSystemViewClosed( [context->window contentView] ); + [context->window close]; + break; + } + if( context==_displayContext ){ + CGDisplaySwitchToMode( kCGDirectMainDisplay,oldDisplayMode ); + CFRelease( (CFTypeRef)oldDisplayMode ); + CGReleaseAllDisplays(); + CGDisplayShowCursor( kCGDirectMainDisplay ); + ShowMenuBar(); + _displayContext=0; + } + + free( context ); +} + +void bbGLGraphicsSetGraphics( BBGLContext *context ){ + if( context ){ + _validateSize( context ); + _validateContext( context ); + [context->glContext makeCurrentContext]; + }else{ + [NSOpenGLContext clearCurrentContext]; + } + _currentContext=context; +} + +void bbGLGraphicsFlip( int sync ){ + if( !_currentContext ) return; + + sync=sync ? 1 : 0; + + static int _sync=-1; + + if( sync!=_currentContext->sync ){ + _currentContext->sync=sync; + [_currentContext->glContext setValues:(long*)&sync forParameter:kCGLCPSwapInterval]; + } + + [_currentContext->glContext flushBuffer]; +} diff --git a/mod/brl.mod/glgraphics.mod/glgraphics.win32.c b/mod/brl.mod/glgraphics.mod/glgraphics.win32.c new file mode 100644 index 0000000..9686c1a --- /dev/null +++ b/mod/brl.mod/glgraphics.mod/glgraphics.win32.c @@ -0,0 +1,434 @@ + +#include + +#include + +#include + +enum{ + _BACKBUFFER= 0x2, + _ALPHABUFFER= 0x4, + _DEPTHBUFFER= 0x8, + _STENCILBUFFER= 0x10, + _ACCUMBUFFER= 0x20, +}; + +enum{ + MODE_SHARED, + MODE_WIDGET, + MODE_WINDOW, + MODE_DISPLAY +}; + +extern int _bbusew; + +static const char *CLASS_NAME="BlitzMax GLGraphics"; +static const wchar_t *CLASS_NAMEW=L"BlitzMax GLGraphics"; + +typedef struct BBGLContext BBGLContext; + +struct BBGLContext{ + BBGLContext *succ; + int mode,width,height,depth,hertz,flags; + + HDC hdc; + HWND hwnd; + HGLRC hglrc; +}; + +static BBGLContext *_contexts; +static BBGLContext *_sharedContext; +static BBGLContext *_currentContext; + +typedef BOOL (APIENTRY * WGLSWAPINTERVALEXT) (int); + +void bbGLGraphicsClose( BBGLContext *context ); +void bbGLGraphicsGetSettings( BBGLContext *context,int *width,int *height,int *depth,int *hertz,int *flags ); +void bbGLGraphicsSetGraphics( BBGLContext *context ); + +static const char *appTitle(){ + return bbTmpCString( bbAppTitle ); +} + +static const wchar_t *appTitleW(){ + return bbTmpWString( bbAppTitle ); +} + +static void _initPfd( PIXELFORMATDESCRIPTOR *pfd,int flags ){ + + memset( pfd,0,sizeof(*pfd) ); + + pfd->nSize=sizeof(pfd); + pfd->nVersion=1; + pfd->cColorBits=1; + pfd->iPixelType=PFD_TYPE_RGBA; + pfd->iLayerType=PFD_MAIN_PLANE; + pfd->dwFlags=PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL; + + pfd->dwFlags|=(flags & _BACKBUFFER) ? PFD_DOUBLEBUFFER : 0; + pfd->cAlphaBits=(flags & _ALPHABUFFER) ? 1 : 0; + pfd->cDepthBits=(flags & _DEPTHBUFFER) ? 1 : 0; + pfd->cStencilBits=(flags & _STENCILBUFFER) ? 1 : 0; + pfd->cAccumBits=(flags & _ACCUMBUFFER) ? 1 : 0; +} + +static int _setSwapInterval( int n ){ + WGLSWAPINTERVALEXT wglSwapIntervalEXT=(WGLSWAPINTERVALEXT)wglGetProcAddress("wglSwapIntervalEXT"); + if( wglSwapIntervalEXT ) wglSwapIntervalEXT( n ); +} + +static _stdcall long _wndProc( HWND hwnd,UINT msg,WPARAM wp,LPARAM lp ){ + + static HWND _fullScreen; + + BBGLContext *c; + for( c=_contexts;c && c->hwnd!=hwnd;c=c->succ ){} + if( !c ){ + return _bbusew ? DefWindowProcW( hwnd,msg,wp,lp ) : DefWindowProc( hwnd,msg,wp,lp ); + } + + bbSystemEmitOSEvent( hwnd,msg,wp,lp,&bbNullObject ); + + switch( msg ){ + case WM_CLOSE: + return 0; + case WM_SYSCOMMAND: + if (wp==SC_SCREENSAVE) return 1; + if (wp==SC_MONITORPOWER) return 1; + break; + case WM_SYSKEYDOWN: + if( wp!=VK_F4 ) return 0; + break; + case WM_SETFOCUS: + if( c && c->mode==MODE_DISPLAY && hwnd!=_fullScreen ){ + DEVMODE dm; + int swapInt=0; + memset( &dm,0,sizeof(dm) ); + dm.dmSize=sizeof(dm); + dm.dmPelsWidth=c->width; + dm.dmPelsHeight=c->height; + dm.dmBitsPerPel=c->depth; + dm.dmFields=DM_PELSWIDTH|DM_PELSHEIGHT|DM_BITSPERPEL; + if( c->hertz ){ + dm.dmDisplayFrequency=c->hertz; + dm.dmFields|=DM_DISPLAYFREQUENCY; + swapInt=1; + } + if( ChangeDisplaySettings( &dm,CDS_FULLSCREEN )==DISP_CHANGE_SUCCESSFUL ){ + _fullScreen=hwnd; + }else if( dm.dmFields & DM_DISPLAYFREQUENCY ){ + dm.dmDisplayFrequency=0; + dm.dmFields&=~DM_DISPLAYFREQUENCY; + if( ChangeDisplaySettings( &dm,CDS_FULLSCREEN )==DISP_CHANGE_SUCCESSFUL ){ + _fullScreen=hwnd; + swapInt=0; + } + } + + if( !_fullScreen ) bbExThrowCString( "GLGraphicsDriver failed to set display mode" ); + + _setSwapInterval( swapInt ); + } + return 0; + case WM_DESTROY: + case WM_KILLFOCUS: + if( hwnd==_fullScreen ){ + ChangeDisplaySettings( 0,CDS_FULLSCREEN ); + ShowWindow( hwnd,SW_MINIMIZE ); + _setSwapInterval( 0 ); + _fullScreen=0; + } + return 0; + case WM_PAINT: + ValidateRect( hwnd,0 ); + return 0; + } + return _bbusew ? DefWindowProcW( hwnd,msg,wp,lp ) : DefWindowProc( hwnd,msg,wp,lp ); +} + +static void _initWndClass(){ + static int _done; + if( _done ) return; + + if( _bbusew ){ + WNDCLASSEXW wc={sizeof(wc)}; + wc.style=CS_HREDRAW|CS_VREDRAW|CS_OWNDC; + wc.lpfnWndProc=(WNDPROC)_wndProc; + wc.hInstance=GetModuleHandle(0); + wc.lpszClassName=CLASS_NAMEW; + wc.hCursor=(HCURSOR)LoadCursor( 0,IDC_ARROW ); + wc.hbrBackground=0; + if( !RegisterClassExW( &wc ) ) exit( -1 ); + }else{ + WNDCLASSEX wc={sizeof(wc)}; + wc.style=CS_HREDRAW|CS_VREDRAW|CS_OWNDC; + wc.lpfnWndProc=(WNDPROC)_wndProc; + wc.hInstance=GetModuleHandle(0); + wc.lpszClassName=CLASS_NAME; + wc.hCursor=(HCURSOR)LoadCursor( 0,IDC_ARROW ); + wc.hbrBackground=0; + if( !RegisterClassEx( &wc ) ) exit( -1 ); + } + + _done=1; +} + +static void _validateSize( BBGLContext *context ){ + if( context->mode==MODE_WIDGET ){ + RECT rect; + GetClientRect( context->hwnd,&rect ); + context->width=rect.right-rect.left; + context->height=rect.bottom-rect.top; + } +} + +void bbGLGraphicsShareContexts(){ + BBGLContext *context; + HDC hdc; + HWND hwnd; + HGLRC hglrc; + long pf; + PIXELFORMATDESCRIPTOR pfd; + + if( _sharedContext ) return; + + _initWndClass(); + + if( _bbusew ){ + hwnd=CreateWindowExW( 0,CLASS_NAMEW,0,WS_POPUP,0,0,1,1,0,0,GetModuleHandle(0),0 ); + }else{ + hwnd=CreateWindowEx( 0,CLASS_NAME,0,WS_POPUP,0,0,1,1,0,0,GetModuleHandle(0),0 ); + } + + _initPfd( &pfd,0 ); + + hdc=GetDC( hwnd ); + pf=ChoosePixelFormat( hdc,&pfd ); + if( !pf ){ + exit(0); + DestroyWindow( hwnd ); + return; + } + SetPixelFormat( hdc,pf,&pfd ); + hglrc=wglCreateContext( hdc ); + if( !hglrc ) exit(0); + + _sharedContext=(BBGLContext*)malloc( sizeof(BBGLContext) ); + memset( _sharedContext,0,sizeof(BBGLContext) ); + + _sharedContext->mode=MODE_SHARED; + _sharedContext->width=1; + _sharedContext->height=1; + + _sharedContext->hdc=hdc; + _sharedContext->hwnd=hwnd; + _sharedContext->hglrc=hglrc; +} + +int bbGLGraphicsGraphicsModes( int *modes,int count ){ + int i=0,n=0; + while( nhglrc,hglrc ); + + GetClientRect( hwnd,&rect ); + + context=(BBGLContext*)malloc( sizeof(BBGLContext) ); + memset( context,0,sizeof(*context) ); + + context->mode=MODE_WIDGET; + context->width=rect.right; + context->height=rect.bottom; + context->flags=flags; + + context->hdc=hdc; + context->hwnd=hwnd; + context->hglrc=hglrc; + + context->succ=_contexts; + _contexts=context; + + return context; +} + +BBGLContext *bbGLGraphicsCreateGraphics( int width,int height,int depth,int hertz,int flags ){ + BBGLContext *context; + + int mode; + HDC hdc; + HWND hwnd; + HGLRC hglrc; + + long pf; + PIXELFORMATDESCRIPTOR pfd; + int hwnd_style; + RECT rect={0,0,width,height}; + + _initWndClass(); + + if( depth ){ + mode=MODE_DISPLAY; + hwnd_style=WS_POPUP; + }else{ + HWND desktop = GetDesktopWindow(); + RECT desktopRect; + GetWindowRect(desktop, &desktopRect); + + rect.left=desktopRect.right/2-width/2; + rect.top=desktopRect.bottom/2-height/2; + rect.right=rect.left+width; + rect.bottom=rect.top+height; + + mode=MODE_WINDOW; + hwnd_style=WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX; + } + + AdjustWindowRectEx( &rect,hwnd_style,0,0 ); + + if( _bbusew ){ + hwnd=CreateWindowExW( + 0,CLASS_NAMEW,appTitleW(), + hwnd_style,rect.left,rect.top,rect.right-rect.left,rect.bottom-rect.top,0,0,GetModuleHandle(0),0 ); + }else{ + hwnd=CreateWindowEx( + 0,CLASS_NAME,appTitle(), + hwnd_style,rect.left,rect.top,rect.right-rect.left,rect.bottom-rect.top,0,0,GetModuleHandle(0),0 ); + } + + if( !hwnd ) return 0; + + GetClientRect( hwnd,&rect ); + width=rect.right-rect.left; + height=rect.bottom-rect.top; + + _initPfd( &pfd,flags ); + + hdc=GetDC( hwnd ); + pf=ChoosePixelFormat( hdc,&pfd ); + if( !pf ){ + DestroyWindow( hwnd ); + return 0; + } + SetPixelFormat( hdc,pf,&pfd ); + hglrc=wglCreateContext( hdc ); + + if( _sharedContext ) wglShareLists( _sharedContext->hglrc,hglrc ); + + context=(BBGLContext*)malloc( sizeof(BBGLContext) ); + memset( context,0,sizeof(context) ); + + context->mode=mode; + context->width=width; + context->height=height; + context->depth=depth; + context->hertz=hertz; + context->flags=flags; + + context->hdc=hdc; + context->hwnd=hwnd; + context->hglrc=hglrc; + + context->succ=_contexts; + _contexts=context; + + ShowWindow( hwnd,SW_SHOW ); + + return context; +} + +void bbGLGraphicsGetSettings( BBGLContext *context,int *width,int *height,int *depth,int *hertz,int *flags ){ + _validateSize( context ); + *width=context->width; + *height=context->height; + *depth=context->depth; + *hertz=context->hertz; + *flags=context->flags; +} + +void bbGLGraphicsClose( BBGLContext *context ){ + BBGLContext **p,*t; + + for( p=&_contexts;(t=*p) && (t!=context);p=&t->succ ){} + if( !t ) return; + + if( t==_currentContext ){ + bbGLGraphicsSetGraphics( 0 ); + } + + wglDeleteContext( context->hglrc ); + + if( t->mode==MODE_DISPLAY || t->mode==MODE_WINDOW ){ + DestroyWindow( t->hwnd ); + } + + *p=t->succ; +} + +void bbGLGraphicsSetGraphics( BBGLContext *context ){ + + if( context==_currentContext ) return; + + _currentContext=context; + + if( context ){ + wglMakeCurrent( context->hdc,context->hglrc ); + }else{ + wglMakeCurrent( 0,0 ); + } +} + +void bbGLGraphicsFlip( int sync ){ + if( !_currentContext ) return; + + _setSwapInterval( sync ? 1 : 0 ); + + /* + static int _sync=-1; + + sync=sync ? 1 : 0; + if( sync!=_sync ){ + _sync=sync; + _setSwapInterval( _sync ); + } + */ + + SwapBuffers( _currentContext->hdc ); +} diff --git a/mod/brl.mod/glmax2d.mod/glmax2d.bmx b/mod/brl.mod/glmax2d.mod/glmax2d.bmx new file mode 100644 index 0000000..55cc9e1 --- /dev/null +++ b/mod/brl.mod/glmax2d.mod/glmax2d.bmx @@ -0,0 +1,538 @@ + +Strict + +Rem +bbdoc: Graphics/OpenGL Max2D +about: +The OpenGL Max2D module provides an OpenGL driver for #Max2D. +End Rem +Module BRL.GLMax2D + +ModuleInfo "Version: 1.13" +ModuleInfo "Author: Mark Sibly" +ModuleInfo "License: zlib/libpng" +ModuleInfo "Copyright: Blitz Research Ltd" +ModuleInfo "Modserver: BRL" + +ModuleInfo "History: 1.13 Release" +ModuleInfo "History: Cleaned up SetGraphics" +ModuleInfo "History: 1.12 Release" +ModuleInfo "History: Fixed filtered image min filters" +ModuleInfo "History: 1.11 Release" +ModuleInfo "History: Fixed texture delete logic" +ModuleInfo "History: 1.10 Release" +ModuleInfo "History: Add SetColor/SetClsColor clamping" +ModuleInfo "History: 1.09 Release" +ModuleInfo "History: Fixed DrawPixmap using current blend mode - now always uses SOLIDBLEND" +ModuleInfo "History: 1.08 Release" +ModuleInfo "History: Added MIPMAPPEDIMAGE support" +ModuleInfo "History: 1.07 Release" +ModuleInfo "History: Now default driver for MacOS/Linux only (D3D7 for windows)" +ModuleInfo "History: 1.06 Release" +ModuleInfo "History: Ripped out a bunch of dead code" +ModuleInfo "History: 1.05 Release" +ModuleInfo "History: Added checks to prevent invalid textures deletes" + +Import BRL.Max2D +Import BRL.GLGraphics + +Private + +Global _driver:TGLMax2DDriver + +'Naughty! +Const GL_BGR=$80E0 +Const GL_BGRA=$80E1 +Const GL_CLAMP_TO_EDGE=$812F +Const GL_CLAMP_TO_BORDER=$812D + +Global ix#,iy#,jx#,jy# +Global color4ub:Byte[4] + +Global state_blend +Global state_boundtex +Global state_texenabled + +Function BindTex( name ) + If name=state_boundtex Return + glBindTexture GL_TEXTURE_2D,name + state_boundtex=name +End Function + +Function EnableTex( name ) + BindTex name + If state_texenabled Return + glEnable GL_TEXTURE_2D + state_texenabled=True +End Function + +Function DisableTex() + If Not state_texenabled Return + glDisable GL_TEXTURE_2D + state_texenabled=False +End Function + +Function Pow2Size( n ) + Local t=1 + While tdead_tex_seq Return + + 'add tex to queue + If dead_texs.length=n_dead_texs + dead_texs=dead_texs[..n_dead_texs+10] + EndIf + dead_texs[n_dead_texs]=name + n_dead_texs:+1 + ' +End Function + +Function CreateTex( width,height,flags ) + + 'alloc new tex + Local name + glGenTextures 1,Varptr name + + 'flush dead texs + If dead_tex_seq=GraphicsSeq + For Local i=0 Until n_dead_texs + glDeleteTextures 1,Varptr dead_texs[i] + Next + EndIf + n_dead_texs=0 + dead_tex_seq=GraphicsSeq + + 'bind new tex + BindTex name + + 'set texture parameters + glTexParameteri GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE + glTexParameteri GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE + + If flags & FILTEREDIMAGE + glTexParameteri GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR + If flags & MIPMAPPEDIMAGE + glTexParameteri GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR + Else + glTexParameteri GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR + EndIf + Else + glTexParameteri GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST + If flags & MIPMAPPEDIMAGE + glTexParameteri GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST_MIPMAP_NEAREST + Else + glTexParameteri GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST + EndIf + EndIf + + Local mip_level + + Repeat + glTexImage2D GL_TEXTURE_2D,mip_level,GL_RGBA8,width,height,0,GL_RGBA,GL_UNSIGNED_BYTE,Null + If Not (flags & MIPMAPPEDIMAGE) Exit + If width=1 And height=1 Exit + If width>1 width:/2 + If height>1 height:/2 + mip_level:+1 + Forever + + Return name +End Function + +Function UploadTex( pixmap:TPixmap,flags ) + Local mip_level + Repeat + glPixelStorei GL_UNPACK_ROW_LENGTH,pixmap.pitch/BytesPerPixel[pixmap.format] + glTexSubImage2D GL_TEXTURE_2D,mip_level,0,0,pixmap.width,pixmap.height,GL_RGBA,GL_UNSIGNED_BYTE,pixmap.pixels + If Not (flags & MIPMAPPEDIMAGE) Exit + If pixmap.width>1 And pixmap.height>1 + pixmap=ResizePixmap( pixmap,pixmap.width/2,pixmap.height/2 ) + Else If pixmap.width>1 + pixmap=ResizePixmap( pixmap,pixmap.width/2,pixmap.height ) + Else If pixmap.height>1 + pixmap=ResizePixmap( pixmap,pixmap.width,pixmap.height/2 ) + Else + Exit + EndIf + mip_level:+1 + Forever + glPixelStorei GL_UNPACK_ROW_LENGTH,0 +End Function + +Function AdjustTexSize( width Var,height Var ) + 'calc texture size + width=Pow2Size( width ) + height=Pow2Size( height ) + Repeat + Local t + glTexImage2D GL_PROXY_TEXTURE_2D,0,4,width,height,0,GL_RGBA,GL_UNSIGNED_BYTE,Null + glGetTexLevelParameteriv GL_PROXY_TEXTURE_2D,0,GL_TEXTURE_WIDTH,Varptr t + If t Return + If width=1 And height=1 RuntimeError "Unable to calculate tex size" + If width>1 width:/2 + If height>1 height:/2 + Forever +End Function + +Public + +Type TGLImageFrame Extends TImageFrame + + Field u0#,v0#,u1#,v1#,uscale#,vscale# + + Field name,seq + + Method New() + seq=GraphicsSeq + End Method + + Method Delete() + If Not seq Return + DeleteTex name,seq + seq=0 + End Method + + Method Draw( x0#,y0#,x1#,y1#,tx#,ty#,sx#,sy#,sw#,sh# ) + Assert seq=GraphicsSeq Else "Image does not exist" + + Local u0#=sx * uscale + Local v0#=sy * vscale + Local u1#=(sx+sw) * uscale + Local v1#=(sy+sh) * vscale + + EnableTex name + glBegin GL_QUADS + glTexCoord2f u0,v0 + glVertex2f x0*ix+y0*iy+tx,x0*jx+y0*jy+ty + glTexCoord2f u1,v0 + glVertex2f x1*ix+y0*iy+tx,x1*jx+y0*jy+ty + glTexCoord2f u1,v1 + glVertex2f x1*ix+y1*iy+tx,x1*jx+y1*jy+ty + glTexCoord2f u0,v1 + glVertex2f x0*ix+y1*iy+tx,x0*jx+y1*jy+ty + glEnd + End Method + + Function CreateFromPixmap:TGLImageFrame( src:TPixmap,flags ) + 'determine tex size + Local tex_w=src.width + Local tex_h=src.height + AdjustTexSize tex_w,tex_h + + 'make sure pixmap fits texture + Local width=Min( src.width,tex_w ) + Local height=Min( src.height,tex_h ) + If src.width<>width Or src.height<>height src=ResizePixmap( src,width,height ) + + 'create texture pixmap + Local tex:TPixmap=src + + '"smear" right/bottom edges if necessary + If widthPF_RGBA8888 tex=tex.Convert( PF_RGBA8888 ) + EndIf + + 'create tex + Local name=CreateTex( tex_w,tex_h,flags ) + + 'upload it + UploadTex tex,flags + + 'done! + Local frame:TGLImageFrame=New TGLImageFrame + frame.name=name + frame.uscale=1.0/tex_w + frame.vscale=1.0/tex_h + frame.u1=width * frame.uscale + frame.v1=height * frame.vscale + Return frame + + End Function + +End Type + +Type TGLMax2DDriver Extends TMax2DDriver + + Method Create:TGLMax2DDriver() + If Not GLGraphicsDriver() Return Null + + Return Self + End Method + + 'graphics driver overrides + Method GraphicsModes:TGraphicsMode[]() + Return GLGraphicsDriver().GraphicsModes() + End Method + + Method AttachGraphics:TMax2DGraphics( widget,flags ) + Local g:TGLGraphics=GLGraphicsDriver().AttachGraphics( widget,flags ) + If g Return TMax2DGraphics.Create( g,Self ) + End Method + + Method CreateGraphics:TMax2DGraphics( width,height,depth,hertz,flags ) + Local g:TGLGraphics=GLGraphicsDriver().CreateGraphics( width,height,depth,hertz,flags ) + If g Return TMax2DGraphics.Create( g,Self ) + End Method + + Method SetGraphics( g:TGraphics ) + If Not g + TMax2DGraphics.ClearCurrent + GLGraphicsDriver().SetGraphics Null + Return + EndIf + + Local t:TMax2DGraphics=TMax2DGraphics(g) + Assert t And TGLGraphics( t._graphics ) + + GLGraphicsDriver().SetGraphics t._graphics + + ResetGLContext t + + t.MakeCurrent + End Method + + Method ResetGLContext( g:TGraphics ) + Local gw,gh,gd,gr,gf + g.GetSettings gw,gh,gd,gr,gf + + state_blend=0 + state_boundtex=0 + state_texenabled=0 + glDisable GL_TEXTURE_2D + glMatrixMode GL_PROJECTION + glLoadIdentity + glOrtho 0,gw,gh,0,-1,1 + glMatrixMode GL_MODELVIEW + glLoadIdentity + glViewport 0,0,gw,gh + End Method + + Method Flip( sync ) + GLGraphicsDriver().Flip sync + End Method + + Method ToString$() + Return "OpenGL" + End Method + + Method CreateFrameFromPixmap:TGLImageFrame( pixmap:TPixmap,flags ) + Local frame:TGLImageFrame + frame=TGLImageFrame.CreateFromPixmap( pixmap,flags ) + Return frame + End Method + + Method SetBlend( blend ) + If blend=state_blend Return + state_blend=blend + Select blend + Case MASKBLEND + glDisable GL_BLEND + glEnable GL_ALPHA_TEST + glAlphaFunc GL_GEQUAL,.5 + Case SOLIDBLEND + glDisable GL_BLEND + glDisable GL_ALPHA_TEST + Case ALPHABLEND + glEnable GL_BLEND + glBlendFunc GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA + glDisable GL_ALPHA_TEST + Case LIGHTBLEND + glEnable GL_BLEND + glBlendFunc GL_SRC_ALPHA,GL_ONE + glDisable GL_ALPHA_TEST + Case SHADEBLEND + glEnable GL_BLEND + glBlendFunc GL_DST_COLOR,GL_ZERO + glDisable GL_ALPHA_TEST + Default + glDisable GL_BLEND + glDisable GL_ALPHA_TEST + End Select + End Method + + Method SetAlpha( alpha# ) + If alpha>1.0 alpha=1.0 + If alpha<0.0 alpha=0.0 + color4ub[3]=alpha*255 + glColor4ubv color4ub + End Method + + Method SetLineWidth( width# ) + glLineWidth width + End Method + + Method SetColor( red,green,blue ) + color4ub[0]=Min(Max(red,0),255) + color4ub[1]=Min(Max(green,0),255) + color4ub[2]=Min(Max(blue,0),255) + glColor4ubv color4ub + End Method + + Method SetClsColor( red,green,blue ) + red=Min(Max(red,0),255) + green=Min(Max(green,0),255) + blue=Min(Max(blue,0),255) + glClearColor red/255.0,green/255.0,blue/255.0,1.0 + End Method + + Method SetViewport( x,y,w,h ) + If x=0 And y=0 And w=GraphicsWidth() And h=GraphicsHeight() + glDisable GL_SCISSOR_TEST + Else + glEnable GL_SCISSOR_TEST + glScissor x,GraphicsHeight()-y-h,w,h + EndIf + End Method + + Method SetTransform( xx#,xy#,yx#,yy# ) + ix=xx + iy=xy + jx=yx + jy=yy + End Method + + Method Cls() + glClear GL_COLOR_BUFFER_BIT + End Method + + Method Plot( x#,y# ) + DisableTex + glBegin GL_POINTS + glVertex2f x+.5,y+.5 + glEnd + End Method + + Method DrawLine( x0#,y0#,x1#,y1#,tx#,ty# ) + DisableTex + glBegin GL_LINES + glVertex2f x0*ix+y0*iy+tx+.5,x0*jx+y0*jy+ty+.5 + glVertex2f x1*ix+y1*iy+tx+.5,x1*jx+y1*jy+ty+.5 + glEnd + End Method + + Method DrawRect( x0#,y0#,x1#,y1#,tx#,ty# ) + DisableTex + glBegin GL_QUADS + glVertex2f x0*ix+y0*iy+tx,x0*jx+y0*jy+ty + glVertex2f x1*ix+y0*iy+tx,x1*jx+y0*jy+ty + glVertex2f x1*ix+y1*iy+tx,x1*jx+y1*jy+ty + glVertex2f x0*ix+y1*iy+tx,x0*jx+y1*jy+ty + glEnd + End Method + + Method DrawOval( x0#,y0#,x1#,y1#,tx#,ty# ) + + Local xr#=(x1-x0)*.5 + Local yr#=(y1-y0)*.5 + Local segs=Abs(xr)+Abs(yr) + + segs=Max(segs,12)&~3 + + x0:+xr + y0:+yr + + DisableTex + glBegin GL_POLYGON + For Local i=0 Until segs + Local th#=i*360#/segs + Local x#=x0+Cos(th)*xr + Local y#=y0-Sin(th)*yr + glVertex2f x*ix+y*iy+tx,x*jx+y*jy+ty + Next + glEnd + + End Method + + Method DrawPoly( xy#[],handle_x#,handle_y#,origin_x#,origin_y# ) + If xy.length<6 Or (xy.length&1) Return + + DisableTex + glBegin GL_POLYGON + For Local i=0 Until Len xy Step 2 + Local x#=xy[i+0]+handle_x + Local y#=xy[i+1]+handle_y + glVertex2f x*ix+y*iy+origin_x,x*jx+y*jy+origin_y + Next + glEnd + End Method + + Method DrawPixmap( p:TPixmap,x,y ) + Local blend=state_blend + DisableTex + SetBlend SOLIDBLEND + + Local t:TPixmap=p + If t.format<>PF_RGBA8888 t=ConvertPixmap( t,PF_RGBA8888 ) + + glPixelZoom 1,-1 + glRasterPos2i 0,0 + glBitmap 0,0,0,0,x,-y,Null + glPixelStorei GL_UNPACK_ROW_LENGTH, t.pitch Shr 2 + glDrawPixels t.width,t.height,GL_RGBA,GL_UNSIGNED_BYTE,t.pixels + glPixelStorei GL_UNPACK_ROW_LENGTH,0 + glPixelZoom 1,1 + + SetBlend blend + End Method + + Method GrabPixmap:TPixmap( x,y,w,h ) + Local blend=state_blend + SetBlend SOLIDBLEND + Local p:TPixmap=CreatePixmap( w,h,PF_RGBA8888 ) + glReadPixels x,GraphicsHeight()-h-y,w,h,GL_RGBA,GL_UNSIGNED_BYTE,p.pixels + p=YFlipPixmap( p ) + SetBlend blend + Return p + End Method + + Method SetResolution( width#,height# ) + glMatrixMode GL_PROJECTION + glLoadIdentity + glOrtho 0,width,height,0,-1,1 + glMatrixMode GL_MODELVIEW + End Method + +End Type + +Rem +bbdoc: Get OpenGL Max2D Driver +about: +The returned driver can be used with #SetGraphicsDriver to enable OpenGL Max2D +rendering. +End Rem +Function GLMax2DDriver:TGLMax2DDriver() + Global _done + If Not _done + _driver=New TGLMax2DDriver.Create() + _done=True + EndIf + Return _driver +End Function + +Local driver:TGLMax2DDriver=GLMax2DDriver() +If driver SetGraphicsDriver driver diff --git a/mod/brl.mod/glmax2d.mod/rectnode.bmx b/mod/brl.mod/glmax2d.mod/rectnode.bmx new file mode 100644 index 0000000..dbf17cc --- /dev/null +++ b/mod/brl.mod/glmax2d.mod/rectnode.bmx @@ -0,0 +1,63 @@ + +Strict + +Rem +Simple rect packer +Based on lightmap packing code by blackpawn +To remove a rect, set its kind to HOLLOW and optimize the root rect +End Rem + +Type TRectNode + + Const NODE=0,SOLID=1,HOLLOW=-1 + + Field x,y,width,height,kind + Field child0:TRectNode,child1:TRectNode + + Method Insert:TRectNode( w,h ) + Local r:TRectNode + If kind=NODE + r=child0.Insert( w,h ) + If r Return r + Return child1.Insert( w,h ) + EndIf + If kind=SOLID Return Null + If w>width Or h>height Return Null + If w=width And h=height + kind=SOLID + Return Self + EndIf + kind=NODE + Local dw=width-w + Local dh=height-h + If dw>dh + child0=Create( x,y,w,height ) + child1=Create( x+w,y,dw,height ) + Else + child0=Create( x,y,width,h ) + child1=Create( x,y+h,width,dh ) + EndIf + Return child0.Insert( w,h ) + End Method + + Method Optimize() + If kind<>NODE Return + child0.Optimize + child1.Optimize + If child0.kind<>HOLLOW Or child1.kind<>HOLLOW Return + kind=HOLLOW + child0=Null + child1=Null + End Method + + Function Create:TRectNode( x,y,w,h ) + Local r:TRectNode=New TRectNode + r.x=x + r.y=y + r.width=w + r.height=h + r.kind=HOLLOW + Return r + End Function + +End Type diff --git a/mod/brl.mod/gnet.mod/doc/intro.bbdoc b/mod/brl.mod/gnet.mod/doc/intro.bbdoc new file mode 100644 index 0000000..91f0adc --- /dev/null +++ b/mod/brl.mod/gnet.mod/doc/intro.bbdoc @@ -0,0 +1,23 @@ + ++GameNet + +The GameNet module (GNet for short) provides a set of commands for creating and managing multiplayer network +games. + +GNet works a little differently than other networking libraries. Instead of being primarily 'message based', GNet +works by synchronizing a collection of GNet %objects over a network. + +Each GNet object contains 32 &slots which are similar in nature to the fields of BlitzMax objects. You can write to these slots using the #SetGNetInt, #SetGNetFloat and #SetGNetString commands, and read from these slots using the #GetGNetInt, #GetGNetFloat and #GetGNetString commands. The actual meaning of the data contained in these slots is completely up to you, but will typically include such information as player position, score, hitpoints and so on. + +Note that you can only modify GNet objects that you have yourself created. Such objects are known as %local objects, while objects created elsewhere are known as %remote objects. + +To start using GNet, you must first create a GNet %host with the #CreateGNetHost command. Once you have created a host, you can either connect to other GNet hosts using #GNetConnect, or prepare to accept connections from other hosts using #GNetListen. + +The #GNetSync command brings all GNet objects up to date. This involves notifying other hosts about any modifications you have made to local GNet objects, and processing notifications from other hosts about any modifications to remote GNet objects. + +Following a #GNetSync, you can check which objects have been modified, created or closed using the #GnetObjects command. This returns a linked list of GNet objects in a particular state. + +GNet also provides a simple messaging system. A GNet message is actually just a special type of GNet object, so you initialize messages using the standard GNet commands for writing slots. Once created and initialized, a message can be sent to a remote object using the #SendGNetMessage command. + +Incoming messages can be processed using the #GNetMessages command after a #GNetSync. This function returns a linked +list of messages objects which can be examined using the standard GNet commands for reading slots. In addition, the #GNetMessageObject command can be used to determine which local object a message was intended for. diff --git a/mod/brl.mod/gnet.mod/gnet.bmx b/mod/brl.mod/gnet.mod/gnet.bmx new file mode 100644 index 0000000..b32e13a --- /dev/null +++ b/mod/brl.mod/gnet.mod/gnet.bmx @@ -0,0 +1,1000 @@ + +Strict + +Rem +bbdoc: Networking/GameNet +End Rem +Module BRL.GNet + +ModuleInfo "Version: 1.06" +ModuleInfo "Author: Mark Sibly" +ModuleInfo "License: zlib/libpng" +ModuleInfo "Copyright: Blitz Research Ltd" +ModuleInfo "Modserver: BRL" + +ModuleInfo "History: 1.06 Release" +ModuleInfo "History: Object id's now unmapped ASAP" +ModuleInfo "History: 1.05 Release" +ModuleInfo "History: Some doc fixes" +ModuleInfo "History: 1.04 Release" +ModuleInfo "Histort: Fixed low level send/recv leaks" +ModuleInfo "History: 1.03 Release" +ModuleInfo "History: Now uses Pub.ENet" +ModuleInfo "History: 1.02 Release" +ModuleInfo "History: Fixed Closing host not closing server socket" +ModuleInfo "History: 1.01 Release" + +Import Pub.ENet +Import BRL.Socket +Import BRL.LinkedList +Import BRL.System + +Private + +Const GNET_INT= 1 +Const GNET_FLOAT16= 2 +Const GNET_STRING= 3 +Const GNET_UINT8= 4 +Const GNET_UINT16= 5 +Const GNET_FLOAT32= 6 + +Global GNET_DIAGNOSTICS=False + +Const GNET_MAXIDS= 4096 + +?Debug +Function dprint( t$ ) + If GNET_DIAGNOSTICS WriteStdout t+"~n" +End Function +? + +Function PackFloat16( f# ) + Local i=(Int Ptr Varptr f)[0] + If i=$00000000 Return $0000 '+0 + If i=$80000000 Return $8000 '-0 + Local M=i Shl 9 + Local S=i Shr 31 + Local E=(i Shr 23 & $ff)-127 + If E=128 + If M Return $ffff 'NaN + Return S Shl 15 | $7c00 '+/-Infinity + EndIf + M:+$00200000 + If Not (M & $ffe00000) E:+1 + If E>15 + Return S Shl 15 | $7c00 '+/-Infinity + Else If E<-15 + Return S Shl 15 '+/- 0 + EndIf + Return S Shl 15 | (E+15) Shl 10 | M Shr 22 +End Function + +Function UnpackFloat16#( i ) + i:&$ffff + If i=$0000 Return +0.0 + If i=$8000 Return -0.0 + Local M=i Shl 22 + Local S=i Shr 15 + Local E=(i Shr 10 & $1f)-15 + If E=16 + If M Return 0.0/0.0 'NaN + If S Return -1.0/0.0 '-Infinity + Return +1.0/0.0 '+Infinity + Else If E = -15 'denormal as float16, but normal as float32. + Local i + For i = 0 To 9 'find the leading 1-bit + Local bit = M & $80000000 + M:Shl 1 + If bit Exit + Next + E:-i + End If + Local n=S Shl 31 | (E+127) Shl 23 | M Shr 9 + Return (Float Ptr Varptr n)[0] +End Function + +Function PackFloat32( f# ) + Return (Int Ptr Varptr f)[0] +End Function + +Function UnpackFloat32#( i ) + Return (Float Ptr Varptr i)[0] +End Function + +Public + +Const GNET_ALL= 0 + +'object states +Const GNET_CREATED= 1 +Const GNET_MODIFIED= 2 +Const GNET_CLOSED= 3 +Const GNET_SYNCED= 4 +Const GNET_MESSAGE= 5 +Const GNET_ZOMBIE= -1 + +Type TGNetMsg + + Field id + Field state + Field data:Byte[] + +End Type + +Type TGNetSlot + Field _type + Field _int + Field _float# + Field _string$ + + Method SetInt( data ) + Assert _type=0 Or _type=GNET_INT Or _type=GNET_UINT8 Or _type=GNET_UINT16 + _int=data + If data<0 + _type=GNET_INT + Else If data<=255 + _type=GNET_UINT8 + Else If data<=65535 + _type=GNET_UINT16 + Else + _type=GNET_INT + EndIf + End Method + + Method SetFloat( data# ) + Assert _type=0 Or _type=GNET_FLOAT32 + _float=data + _type=GNET_FLOAT32 + End Method + + Method SetString( data$ ) + Assert _type=0 Or _type=GNET_STRING + _string=data + _type=GNET_STRING + End Method + + Method GetInt() + Assert _type=GNET_INT Or _type=GNET_UINT8 Or _type=GNET_UINT16 + Return _int + End Method + + Method GetFloat#() + Assert _type=GNET_FLOAT32 + Return _float + End Method + + Method GetString$() + Assert _type=GNET_STRING + Return _string + End Method + +End Type + +Type TGNetObject + + Method New() + For Local i=0 Until 32 + _slots[i]=New TGNetSlot + Next + End Method + + Method State() + Return _state + End Method + + 'close object + Method Close() + Select _state + Case GNET_CREATED + _state=GNET_ZOMBIE + Case GNET_MODIFIED,GNET_SYNCED + _state=GNET_CLOSED + Case GNET_CLOSED + Default + Throw "Illegal object state" + End Select + End Method + + Method SetInt( index,data ) + WriteSlot( index ).SetInt data + End Method + + Method SetFloat( index,data# ) + WriteSlot( index ).SetFloat data + End Method + + Method SetString( index,data$ ) + WriteSlot( index ).SetString data + End Method + + Method GetInt( index ) + Return _slots[index].GetInt() + End Method + + Method GetFloat#( index ) + Return _slots[index].GetFloat() + End Method + + Method GetString$( index ) + Return _slots[index].GetString() + End Method + + Method WriteSlot:TGNetSlot( index ) + Assert _state<>GNET_CLOSED And _state<>GNET_ZOMBIE Else "Object has been closed" + _modified:|1 Shl index + If _state=GNET_SYNCED _state=GNET_MODIFIED + Return _slots[index] + End Method + + Method Sync:TGNetMsg() + Select _state + Case GNET_SYNCED,GNET_ZOMBIE + Return + End Select + + Local msg:TGNetMsg + + If Not _peer + msg:TGNetMsg=New TGNetmsg + msg.id=_id + msg.state=_state + msg.data=PackSlots( _modified ) + EndIf + + _modified=0 + + Select _state + Case GNET_CREATED,GNET_MODIFIED + _state=GNET_SYNCED + Case GNET_CLOSED + _target=Null + _state=GNET_ZOMBIE + End Select + + Return msg + End Method + + Method Update( msg:TGNetMsg ) + Assert _id=msg.id + UnpackSlots msg.data + _state=msg.state + End Method + + Method CreatedMsg:TGNetMsg() + Local msg:TGNetMsg=New TGNetmsg + msg.id=_id + msg.state=GNET_CREATED + msg.data=PackSlots( ~0 ) + Return msg + End Method + + Method ClosedMsg:TGNetMsg() + Local msg:TGNetMsg=New TGNetMsg + msg.id=_id + msg.state=GNET_CLOSED + msg.data=PackSlots( 0 ) + Return msg + End Method + + Method MessageMsg:TGNetMsg( id ) + Local msg:TGNetMsg=New TGNetMsg + msg.id=id + msg.state=GNET_MESSAGE + msg.data=PackSlots( ~0 ) + Return msg + End Method + + Method PackSlots:Byte[]( mask ) + Local sz + For Local index=0 Until 32 + If Not (mask & 1 Shl index) Continue + Local ty=_slots[index]._type + If Not ty Continue + Select ty + Case GNET_INT + sz:+5 + Case GNET_UINT8 + sz:+2 + Case GNET_UINT16 + sz:+3 + Case GNET_FLOAT16 + sz:+3 + Case GNET_FLOAT32 + sz:+5 + Case GNET_STRING + sz:+3+GetString(index).length + End Select + Next + If sz>$fff0 Throw "GNet message data too large" + Local data:Byte[sz] + Local p:Byte Ptr=data + For Local index=0 Until 32 + If Not (mask & 1 Shl index) Continue + Local ty=_slots[index]._type + If Not ty Continue + Select ty + Case GNET_INT + Local n=GetInt( index ) + p[0]=GNET_INT Shl 5 | index + p[1]=n Shr 24 + p[2]=n Shr 16 + p[3]=n Shr 8 + p[4]=n Shr 0 + p:+5 + Case GNET_UINT8 + Local n=GetInt( index ) + p[0]=GNET_UINT8 Shl 5 | index + p[1]=n + p:+2 + Case GNET_UINT16 + Local n=GetInt( index ) + p[0]=GNET_UINT16 Shl 5 | index + p[1]=n Shr 8 + p[2]=n Shr 0 + p:+3 + Case GNET_FLOAT16 + Local n=PackFloat16( GetFloat(index) ) + p[0]=GNET_FLOAT16 Shl 5 | index + p[1]=n Shr 8 + p[2]=n Shr 0 + p:+3 + Case GNET_FLOAT32 + Local n=PackFloat32( GetFloat(index) ) + p[0]=GNET_FLOAT32 Shl 5 | index + p[1]=n Shr 24 + p[2]=n Shr 16 + p[3]=n Shr 8 + p[4]=n Shr 0 + p:+5 + Case GNET_STRING + Local data$=GetString( index ) + Local n=data.length + p[0]=GNET_STRING Shl 5 | index + p[1]=n Shr 8 + p[2]=n Shr 0 + Local t:Byte Ptr=data.ToCString() + MemCopy p+3,t,n + MemFree t + p:+3+n + Default + Throw "Invalid GNet data type" + End Select + Next + Return data + End Method + + Method UnpackSlots( data:Byte[] ) + Local p:Byte Ptr=data + Local e:Byte Ptr=p+data.length + While pe Throw "Corrupt GNet message" + End Method + + Function Create:TGNetObject( id,state,host:TGNetHost,peer:TGNetPeer ) + Local t:TGNetObject=New TGNetObject + t._id=id + t._state=state + t._host=host + t._peer=peer + Return t + End Function + + Field _id + Field _state + Field _host:TGNetHost + Field _peer:TGNetPeer + Field _target:Object + + Field _slots:TGNetSlot[32],_modified + +End Type + +Type TGNetHost + + Method UpdateENetEvents() + If Not _enetHost Return + Repeat + Local ev:ENetEvent=New ENetEvent + If Not enet_host_service( _enetHost,ev,0 ) Return + _enetEvents.AddLast ev + Forever + End Method + + Method Sync() + + _created.Clear + _modified.Clear + _closed.Clear + _messages.Clear + + Local succ:TLink + + 'sync all objects + succ=_objects.FirstLink() + While succ + Local link:TLink=succ + succ=link.NextLink() + + Local obj:TGNetObject=TGNetObject(link.Value()) + + Local msg:TGNetMsg=obj.Sync() + If msg BroadCast msg,obj._peer + + If obj._state=GNET_ZOMBIE + If Not obj._peer UnmapObject obj + link.Remove + EndIf + Wend + + Repeat + + UpdateENetEvents + + If _enetEvents.IsEmpty() Return + + Local ev:ENetEvent=ENetEvent( _enetEvents.RemoveFirst() ) + + Local peer:TGNetPeer + For Local t:TGNetPeer=EachIn _peers + If t._enetPeer=ev.peer + peer=t + Exit + EndIf + Next + + Select ev.event + Case ENET_EVENT_TYPE_CONNECT + Assert Not peer Else "GNet error" + peer=AddPeer( ev.peer ) + Case ENET_EVENT_TYPE_DISCONNECT + If peer + For Local obj:TGNetObject=EachIn _objects + If obj._peer<>peer Continue + BroadCast obj.ClosedMsg(),peer + peer.UnmapLocalId obj._id + UnmapObject obj + _closed.AddLast obj + obj.Close + Next + _peers.Remove peer + EndIf + Case ENET_EVENT_TYPE_RECEIVE + Assert peer Else "GNet error" + Local msg:TGNetMsg=peer.RecvMsg( ev.packet ) + enet_packet_destroy ev.packet + Select msg.state + Case GNET_MESSAGE + Local obj:TGNetObject=_idMap[msg.id] + If Not obj Continue + If obj._peer + obj._peer.SendMsg msg + Else + obj=TGNetObject.Create( msg.id,GNET_MESSAGE,Self,Null ) + _messages.AddLast obj + obj.Update msg + EndIf + Default + Local obj:TGNetObject + Select msg.state + Case GNET_CREATED + obj=TGNetObject.Create( AllocId(),GNET_CREATED,Self,peer ) + MapObject obj + peer.MapLocalId obj._id,msg.id + msg.id=obj._id + _objects.AddLast obj + _created.AddLast obj + Case GNET_MODIFIED + obj=_idMap[msg.id] + _modified.AddLast obj + Case GNET_CLOSED + obj=_idMap[msg.id] + Assert peer=obj._peer + peer.UnmapLocalId obj._id + UnmapObject obj + _closed.AddLast obj + End Select + BroadCast msg,peer + obj.Update msg + End Select + Default + Throw "GNet error" + End Select + + Forever + + End Method + + Method Close() + If Not _peers Return + For Local peer:TGNetPeer=EachIn _peers + peer.Close + Next + _peers=Null + If _enetHost + enet_host_flush _enetHost + enet_host_destroy _enetHost + EndIf + End Method + + Method BroadCast( msg:TGNetMsg,except:TGNetPeer ) + For Local peer:TGNetPeer=EachIn _peers + If peer<>except peer.SendMsg msg + Next + End Method + + Method AddPeer:TGNetPeer( enetPeer:Byte Ptr ) + Local peer:TGNetPeer=TGNetPeer.Create( enetPeer ) +?Debug + dprint "Adding peer" +? + _peers.AddLast peer + For Local obj:TGNetObject=EachIn _objects + Select obj._state + Case GNET_SYNCED,GNET_MODIFIED + peer.SendMsg obj.CreatedMsg() + End Select + Next + Return peer + End Method + + Method Objects:TList() + Return _objects + End Method + + Method Peers:TList() + Return _peers + End Method + + Method ObjectsCreated:TList() + Return _created + End Method + + Method ObjectsModified:TList() + Return _modified + End Method + + Method ObjectsClosed:TList() + Return _closed + End Method + + Method CreateObject:TGNetObject() + Local obj:TGNetObject=TGNetObject.Create( AllocId(),GNET_CREATED,Self,Null ) + MapObject obj + _objects.AddLast obj + Return obj + End Method + + Method CreateMessage:TGNetObject() + Return TGNetObject.Create( 0,GNET_MESSAGE,Self,Null ) + End Method + + Method SendGNetMessage( msg:TGNetObject,toObject:TGNetObject ) + If toObject._peer + toObject._peer.SendMsg msg.MessageMsg( toObject._id ) + EndIf + End Method + + Method AllocId() + For Local id=1 Until GNET_MAXIDS + If Not _idMap[id] Return id + Next + Throw "Out of GNet object IDs" + End Method + + Method MapObject( obj:TGNetObject ) + Assert Not _idMap[obj._id] + _idMap[obj._id]=obj + End Method + + Method UnmapObject( obj:TGNetObject ) + Assert _idMap[obj._id]=obj + _idMap[obj._id]=Null + End Method + + Method Listen( port ) + If _enetHost Return + Local addr:Byte Ptr=enet_address_create( ENET_HOST_ANY,port ) + _enetHost=enet_host_create( addr,32,0,0 ) + enet_address_destroy addr + If Not _enetHost Return + Return True + End Method + + Method Connect( ip,port,timeout ) + If _enetHost Return + _enetHost=enet_host_create( Null,32,0,0 ) + If Not _enetHost Return + Local addr:Byte Ptr=enet_address_create( ip,port ) + Local peer:Byte Ptr=enet_host_connect( _enetHost,addr,1 ) + enet_address_destroy addr + If peer + timeout:+MilliSecs() + While timeout-MilliSecs()>0 + UpdateENetEvents + For Local ev:ENetEvent=EachIn _enetEvents + If ev.event=ENET_EVENT_TYPE_CONNECT And ev.peer=peer + _enetEvents.Remove ev + AddPeer peer + Return True + EndIf + Next + Wend + EndIf + enet_host_destroy _enetHost + _enetHost=Null + End Method + + Function Create:TGNetHost() + Local t:TGNetHost=New TGNetHost + Return t + End Function + + Field _enetHost:Byte Ptr + Field _enetEvents:TList=New TList + + Field _peers:TList=New TList 'active peers + Field _objects:TList=New TList 'all objects + + Field _created:TList=New TList 'created remote objects + Field _modified:TList=New TList 'modified remote objects + Field _closed:TList=New TList 'closed remote objects + Field _messages:TList=New TList 'messages received + + Field _idMap:TGNetObject[GNET_MAXIDS] + +End Type + +Type TGNetPeer + + 'enet peer + Field _enetPeer:Byte Ptr + + 'id mapping + Field _localToRemote[GNET_MAXIDS] + Field _remoteToLocal[GNET_MAXIDS] + + Method Close() + If Not _enetPeer Return + enet_peer_disconnect _enetPeer + _enetPeer=Null + End Method + + Method MapLocalId( localId,remoteId ) + Assert Not _localToRemote[localId] And Not _remoteToLocal[remoteId] + _localToRemote[localId]=remoteId + _remoteToLocal[remoteId]=localId +?Debug + dprint "Mapped localId:"+localId+"<->remoteId:"+remoteId +? + End Method + + Method UnmapLocalId( localId ) + Local remoteId=_localToRemote[localId] + Assert _localToRemote[localId]=remoteId And _remoteToLocal[remoteId]=localId + _localToRemote[localId]=0 + _remoteToLocal[remoteId]=0 +?Debug + dprint "Unmapped localId:"+localId+"<->remoteId:"+remoteId +? + End Method + + Method RecvMsg:TGNetMsg( packet:Byte Ptr ) + + Local buf:Byte Ptr=enet_packet_data( packet ) + Local sz=enet_packet_size( packet )-2 + + Local id=(buf[0] Shl 8 | buf[1]) & (GNET_MAXIDS-1) + Local state=(buf[0] Shl 8 | buf[1]) Shr 12 + + If state<>GNET_MESSAGE + id=_remoteToLocal[id] + If id + Assert state<>GNET_CREATED Else "Illegal remoteId" + Else + Assert state=GNET_CREATED Else "Unmapped remoteId: obj.state="+buf[1] + id=(buf[0] Shl 8 | buf[1]) & (GNET_MAXIDS-1) + EndIf + EndIf + + Local msg:TGNetMsg=New TGNetmsg + msg.id=id + msg.state=state + + If sz + msg.data=New Byte[sz] + MemCopy msg.data,buf+2,sz + EndIf +?Debug + If msg.state<>2 dprint "RecvMsg id="+msg.id+", state="+msg.state+", size="+sz +? + Return msg + End Method + + Method SendMsg( msg:TGNetMsg ) + Local sz=msg.data.length + Local buf:Byte Ptr=MemAlloc( sz+2 ) + + Local id=msg.id + If msg.state=GNET_MESSAGE + id=_localToRemote[id] + Assert id Else "SendMsg: Unmapped localId="+msg.id + EndIf + + buf[0]=(msg.state Shl 12 | id) Shr 8 + buf[1]=(msg.state Shl 12 | id) Shr 0 + If sz MemCopy buf+2,msg.data,sz +?Debug + dprint "SendMsg id="+id+", state="+msg.state+", size="+sz +? + Local packet:Byte Ptr=enet_packet_create( buf,sz+2,ENET_PACKET_FLAG_RELIABLE ) + + MemFree buf + + If enet_peer_send( _enetPeer,0,packet )<0 Throw "ENet errror" + + End Method + + Function Create:TGNetPeer( enetPeer:Byte Ptr ) + Local t:TGNetPeer=New TGNetPeer + t._enetPeer=enetPeer + Return t + End Function + +End Type + +Rem +bbdoc: Create GNet host +returns: A new GNet host +about: +Once you have created a GNet host, you can use it to create objects with #CreateGNetObject, +connect to other hosts with #GNetConnect and listen for connections from other hosts with +#GNetListen. +End Rem +Function CreateGNetHost:TGNetHost() + Return TGNetHost.Create() +End Function + +Rem +bbdoc: Close a GNet host +about: +Once closed, a GNet host cannot be reopened. +End Rem +Function CloseGNetHost( host:TGNetHost ) + host.Close +End Function + +Rem +bbdoc: Synchronize GNet host +about: +#GNetSync will update the state of all GNet objects. Once you have used this command, +use the #GNetObjects function to determine which objects have been remotely created, modified +or closed. +End Rem +Function GNetSync( host:TGNetHost ) + Return host.Sync() +End Function + +Rem +bbdoc: Listen for connections +returns: True if successful, otherwise false +about: +Causes @host to start listening for connection attempts on the specified @port. +Once a host is listening, hosts on other machines can connect using #GNetConnect. + +#GNetListen may fail if @port is already in use by another application, or if @host +is already listening or has already connected to a remote host using #GNetConnect. +End Rem +Function GNetListen( host:TGNetHost,port ) + Return host.Listen( port ) +End Function + +Rem +bbdoc: Connect to a remote GNet host +returns: True if connection successful, otherwise false +about: +Attempts to connect @host to the specified remote address and port. + +A GNet host must be listening (see #GNetListen) at the specified address and port for the +connection to succeed. +End Rem +Function GNetConnect( host:TGNetHost,address$,port,timeout_ms=10000 ) + Return host.Connect( HostIp(address),port,timeout_ms ) +End Function + +Rem +bbdoc: Get a list of GNet objects +returns: A linked list +about: +#GNetObjects returns a list of GNet objects in a certain state. + +The @state parameter controls which objects are listed, and can be one of &GNET_ALL, +&GNET_CREATED, &GNET_MODIFIED or &GNET_CLOSED. + +Note that with the exception of &GNET_ALL, the returned lists will only ever contain remote objects. +End Rem +Function GNetObjects:TList( host:TGNetHost,state=GNET_ALL ) + Select state + Case GNET_ALL + Return host.Objects() + Case GNET_CREATED + Return host.ObjectsCreated() + Case GNET_MODIFIED + Return host.ObjectsModified() + Case GNET_CLOSED + Return host.ObjectsClosed() + End Select + Throw "Unknown object state" +End Function + +Rem +bbdoc: Get a list of GNet messages sent to local objects +returns: A linked list +End Rem +Function GNetMessages:TList( host:TGNetHost ) + Return host._messages +End Function + +Rem +bbdoc: Create a GNet object +returns: A new GNet object +End Rem +Function CreateGNetObject:TGNetObject( host:TGNetHost ) + Return host.CreateObject() +End Function + +Rem +bbdoc: Create a GNet message object +returns: A new GNet object +End Rem +Function CreateGNetMessage:TGNetObject( host:TGNetHost ) + Return host.CreateMessage() +End Function + +Rem +bbdoc: Send a GNet message to a remote object +End Rem +Function SendGNetMessage( msg:TGNetObject,toObject:TGNetObject ) + Return msg._host.SendGNetMessage( msg,toObject ) +End Function + +Rem +bbdoc: Get message target object +returns: The object that @msg was sent to +End Rem +Function GNetMessageObject:TGNetObject( msg:TGNetObject ) + Return msg._host._idMap[msg._id] +End Function + +Rem +bbdoc: Get state of a GNet object +returns: An integer state +about:The returned value can be one of the following: + + + + + + + + +
Object StateMeaning
GNET_CREATEDObject has been created
GNET_SYNCEDObject is in sync
GNET_MODIFIEDObject has been modified
GNET_CLOSEDObject has been closed
GNET_ZOMBIEObject is a zombie
GNET_MESSAGEObject is a message object
+Zombie objects are objects that have been successfully closed and will never again be used +by GameNet. Therefore, such objects will never appear in any list returned by the +#GNetObjects function. +End Rem +Function GNetObjectState( obj:TGNetObject ) + Return obj.State() +End Function + +Rem +bbdoc: Determine whether a GNet object is local +returns: True if object is a local object +End Rem +Function GNetObjectLocal( obj:TGNetObject ) + Return obj._peer=Null +End Function + +Rem +bbdoc: Determine whether a GNet object is remote +returns: True if object is a remote object +End Rem +Function GNetObjectRemote( obj:TGNetObject ) + Return obj._peer<>Null +End Function + +Rem +bbdoc: Set GNet object int data +End Rem +Function SetGNetInt( obj:TGNetObject,index,value ) + obj.SetInt index,value +End Function + +Rem +bbdoc: Set GNet object float data +End Rem +Function SetGNetFloat( obj:TGNetObject,index,value# ) + obj.SetFloat index,value +End Function + +Rem +bbdoc: Set GNet object string data +End Rem +Function SetGNetString( obj:TGNetObject,index,value$ ) + obj.SetString index,value +End Function + +Rem +bbdoc: Get GNet object int data +End Rem +Function GetGNetInt( obj:TGNetObject,index ) + Return obj.GetInt( index ) +End Function + +Rem +bbdoc: Get GNet object float data +End Rem +Function GetGNetFloat#( obj:TGNetObject,index ) + Return obj.GetFloat( index ) +End Function + +Rem +bbdoc: Get GNet object string data +End Rem +Function GetGNetString$( obj:TGNetObject,index ) + Return obj.GetString( index ) +End Function + +Rem +bbdoc: Set a GNet object's target object +about: +This command allows you to bind an abitrary object to a GNet object. +End Rem +Function SetGNetTarget( obj:TGNetObject,target:Object ) + obj._target=target +End Function + +Rem +bbdoc: Get a GNet object's target object +returns: The currently bound target object +End Rem +Function GetGNetTarget:Object( obj:TGNetObject ) + Return obj._target +End Function + +Rem +bbdoc: Close a GNet object +End Rem +Function CloseGNetObject( obj:TGNetObject ) + Assert Not obj._peer Else "CloseGNetObject can only be used with local objects" + obj.Close +End Function diff --git a/mod/brl.mod/graphics.mod/doc/graphicsmodes.bmx b/mod/brl.mod/graphics.mod/doc/graphicsmodes.bmx new file mode 100644 index 0000000..c254bb8 --- /dev/null +++ b/mod/brl.mod/graphics.mod/doc/graphicsmodes.bmx @@ -0,0 +1,8 @@ + +Print "Available graphics modes:" + +For mode:TGraphicsMode=EachIn GraphicsModes() + + Print mode.width+","+mode.height+","+mode.depth+","+mode.hertz + +Next diff --git a/mod/brl.mod/graphics.mod/doc/intro.bbdoc b/mod/brl.mod/graphics.mod/doc/intro.bbdoc new file mode 100644 index 0000000..ce8e602 --- /dev/null +++ b/mod/brl.mod/graphics.mod/doc/intro.bbdoc @@ -0,0 +1,60 @@ + +The graphics module provides the ability to create and 'flip' graphics objects. + +A graphics object represents a rectangular area you can render to. However, the graphics module +does not provide any commands for actual rendering - this is left to other modules such as +#max2D to implement. + +The graphics module maintains 2 'current' objects - the current graphics driver and the currect +graphics object. To change the current graphics driver, use #SetGraphicsDriver. To change the +current graphics object, use #SetGraphics. + +To create a graphics object, use either #Graphics or #CreateGraphics. The kind of graphics +object created will depend upon the current graphics driver. For example, the following code: +{{ +SetGraphicsDriver GLGraphicsDriver() +Local g:TGraphics=CreateGraphics( 640,480,32,60,GRAPHICS_BACKBUFFER ) +}} +Will create an OpenGL graphics object. + +You can 'select' this object for rendering using: +{{ +SetGraphics g 'we can now execute OpenGL code +glClearColor .5,0,1,1 'tada! +glClear 'yes! +Flip 'must do this as the graphics is double buffered +}} +One you have finished with a graphics object, use #CloseGraphics to close it. + +#Graphics and #CreateGraphics both accept the following parameters: @width, @height, @depth, +@hertz and @flags. + +The @width and @height parameters specify the dimensions of the graphics, in pixels. + +The @depth parameter selects a pixel bit depth. This value can be 0, 16, 24 or 32 depending +on the graphics modes available. A depth of 0 can be used to select 'windowed mode' graphics, +while non-0 depths select 'fullscreen' graphics. + +The @hertz parameter selects a refresh rate, which refers to the number of times the screen +refreshes per second. The refresh rates available depend on the graphics modes available, +which differ from graphics card to graphics card. Note that creating graphics with an +unsupported refresh rate will not fail - instead, a default refresh rate will be used. + +The #Graphics command can be used to achieve a fixed refresh rate. When using #Flip to +present such graphics, BlitzMax will guarantee the desired refresh rate is honored regardless +of the available hardware's capabilities. This is achieved by using software timing +techniques when necessary. + +The @flags parameter can be any combination of the following: +[ @Flags | @Meaning +* GRAPHICS_BACKBUFFER | Create graphics with a back buffer +* GRAPHICS_ALPHABUFFER | Create graphics with an alpha buffer +* GRAPHICS_DEPTHBUFFER | Create graphics with a depth buffer +* GRAPHICS_STENCILBUFFER | Create graphics with a stencil buffer +* GRAPHICS_ACCUMBUFFER | Create graphics with an accumulation buffer +] +Flags can be combined with the | (or) operator. For example, GRAPHICS_BACKBUFFER|GRAPHICS_DEPTHBUFFER +can be used to create graphics which has both a back buffer and a depth buffer. + +Graphics created with the GRAPHICS_BACKBUFFER flag must be 'flipped' after you have finished +rendering using #Flip. diff --git a/mod/brl.mod/graphics.mod/doc/setgraphicsdriver.bmx b/mod/brl.mod/graphics.mod/doc/setgraphicsdriver.bmx new file mode 100644 index 0000000..5390056 --- /dev/null +++ b/mod/brl.mod/graphics.mod/doc/setgraphicsdriver.bmx @@ -0,0 +1,17 @@ + +SetGraphicsDriver GLMax2DDriver() + +Graphics 640,480 +DrawText "OpenGL Max2D Graphics! Hit any key (next to the whatever key)...",0,0 +Flip +WaitKey +EndGraphics + +SetGraphicsDriver GLGraphicsDriver() + +Graphics 640,480 +glClear GL_COLOR_BUFFER_BIT +GLDrawText "'Raw' OpenGL Graphics! Hit any key...",0,0 +Flip +WaitKey + diff --git a/mod/brl.mod/graphics.mod/graphics.bmx b/mod/brl.mod/graphics.mod/graphics.bmx new file mode 100644 index 0000000..d32b051 --- /dev/null +++ b/mod/brl.mod/graphics.mod/graphics.bmx @@ -0,0 +1,538 @@ + +Strict + +Rem +bbdoc: Graphics/Graphics +End Rem +Module BRL.Graphics + +ModuleInfo "Version: 1.08" +ModuleInfo "Author: Mark Sibly" +ModuleInfo "License: zlib/libpng" +ModuleInfo "Copyright: Blitz Research Ltd" +ModuleInfo "Modserver: BRL" + +ModuleInfo "History: 1.08 Release" +ModuleInfo "History: Mouse repositioned only in fullscreen mode" +ModuleInfo "History: 1.07 Release" +ModuleInfo "History: Flip mode for attached graphics changed to 0" +ModuleInfo "History: 1.06 Release" +ModuleInfo "History: Fixed softsync period init bug" +ModuleInfo "History: 1.05 Release" +ModuleInfo "History: Fixed softsync routine to prevent overflow" +ModuleInfo "History: 1.04 Release" +ModuleInfo "History: Graphics exceptions now caught" +ModuleInfo "History: 1.03 Release" +ModuleInfo "History: Added DefaultGraphicsFlags() Function" +ModuleInfo "History: 1.02 Release" +ModuleInfo "History: Restored FlipHook" +ModuleInfo "History: 1.01 Release" +ModuleInfo "History: Added default flags to SetGraphicsDriver" + +Import BRL.System +Import BRL.PolledInput + +Rem +bbdoc: Flip Hook id +about: +Use this id with #AddHook to register a function that +is called every #Flip. +End Rem +Global FlipHook=AllocHookId() + +Const GRAPHICS_BACKBUFFER= $2 +Const GRAPHICS_ALPHABUFFER= $4 +Const GRAPHICS_DEPTHBUFFER= $8 +Const GRAPHICS_STENCILBUFFER= $10 +Const GRAPHICS_ACCUMBUFFER= $20 + +'Const GRAPHICS_SWAPINTERVAL0= $40 +'Const GRAPHICS_SWAPINTERVAL1= $80 + +'Const GRAPHICS_SWAPINTERVALMASK=GRAPHICS_SWAPINTERVAL0|GRAPHICS_SWAPINTERVAL1 + +Type TGraphics + + Method _pad() + End Method + + Method Driver:TGraphicsDriver() Abstract + + Method GetSettings( width Var,height Var,depth Var,hertz Var,flags Var ) Abstract + + Method Close() Abstract + +End Type + +Type TGraphicsMode + + Field width,height,depth,hertz + + Method ToString$() + Return width+","+height+","+depth+" "+hertz+"Hz" + End Method + +End Type + +Type TGraphicsDriver + + Method GraphicsModes:TGraphicsMode[]() Abstract + + Method AttachGraphics:TGraphics( widget,flags ) Abstract + + Method CreateGraphics:TGraphics( width,height,depth,hertz,flags ) Abstract + + Method SetGraphics( g:TGraphics ) Abstract + + Method Flip( sync ) Abstract + +End Type + +Private + +Global _defaultFlags +Global _driver:TGraphicsDriver +Global _graphicsModes:TGraphicsMode[] +Global _graphics:TGraphics,_gWidth,_gHeight,_gDepth,_gHertz,_gFlags + +Global _exGraphics:TGraphics + +'Only valid if _exGraphics=_graphics +Global _softSync,_hardSync,_syncRate,_syncPeriod,_syncFrac,_syncAccum,_syncTime + +Public + +Global GraphicsSeq=1 + +Function BumpGraphicsSeq() + GraphicsSeq:+1 + If Not GraphicsSeq GraphicsSeq=1 +End Function + +Rem +bbdoc: Set current graphics driver +about: +The current graphics driver determines what kind of graphics are created when you use +the #CreateGraphics or #Graphics functions, as well as the graphics modes available. + +The #GLGraphicsDriver, #GLMax2DDriver, #D3D7Max2DDriver and #D3D9Max2DDriver functions can all be +used to obtain a graphics driver. + +The @defaultFlags parameter allows you to specify graphics flags that will be applied to any +graphics created with #CreateGraphics or #Graphics. +End Rem +Function SetGraphicsDriver( driver:TGraphicsDriver,defaultFlags=GRAPHICS_BACKBUFFER ) + BumpGraphicsSeq + If driver<>_driver + If _driver And _graphics _driver.SetGraphics Null + _graphicsModes=Null + _driver=driver + EndIf + _defaultFlags=defaultFlags + _graphics=Null + _gWidth=0 + _gHeight=0 + _gDepth=0 + _gHertz=0 + _gFlags=0 +End Function + +Rem +bbdoc: Get current graphics driver +about: +Returns the current graphics driver as selected by #SetGraphicsDriver +End Rem +Function GetGraphicsDriver:TGraphicsDriver() + Return _driver +End Function + +Rem +bbdoc: Get current default graphics flags +End Rem +Function DefaultGraphicsFlags() + Return _defaultFlags +End Function + +Rem +bbdoc: Get graphics modes available under the current graphics driver +returns: An array of TGraphicsMode objects +about: +A TGraphicsMode object contains the following fields: @width, @height, @depth and @hertz +End Rem +Function GraphicsModes:TGraphicsMode[]() + If Not _graphicsModes _graphicsModes=_driver.GraphicsModes() + Return _graphicsModes[..] +End Function + +Rem +bbdoc: Get number of graphics modes available under the current graphics driver +returns: Number of available Graphics modes +about: +Use #GetGraphicsMode To obtain information about an individual Graphics mode +End Rem +Function CountGraphicsModes() + Return GraphicsModes().length +End Function + +Rem +bbdoc: Get information about a graphics mode +about: +#GetGraphicsMode returns information about a specific graphics mode. @mode should be +in the range 0 (inclusive) to the value returned by #CountGraphicsModes (exclusive). +End Rem +Function GetGraphicsMode( index,width Var,height Var,depth Var,hertz Var ) + Local mode:TGraphicsMode=GraphicsModes()[index] + width=mode.width + height=mode.height + depth=mode.depth + hertz=mode.hertz +End Function + +Rem +bbdoc: Determine if a graphics mode exists +returns: True if a matching graphics mode is found +about: +A value of 0 for any of @width, @height, @depth or @hertz will cause that +parameter to be ignored. +End Rem +Function GraphicsModeExists( width,height,depth=0,hertz=0 ) + For Local mode:TGraphicsMode=EachIn GraphicsModes() + If width And width<>mode.width Continue + If height And height<>mode.height Continue + If depth And depth<>mode.depth Continue + If hertz And hertz<>mode.hertz Continue + Return True + Next + Return False +End Function + +Rem +bbdoc: Create a graphics object +returns: A graphics object +about: +#CreateGraphics creates a graphics object. To use this object for rendering, you will +first have to select it using #SetGraphics. + +The kind of graphics object returned depends upon the current graphics driver as set by +#SetGraphicsDriver. +End Rem +Function CreateGraphics:TGraphics( width,height,depth,hertz,flags ) + flags:|_defaultFlags + Local g:TGraphics + Try + g=_driver.CreateGraphics( width,height,depth,hertz,flags ) + Catch ex:Object +?Debug + WriteStdout "CreateGraphics failed:"+ex.ToString() +? + End Try + Return g +End Function + +Function AttachGraphics:TGraphics( widget,flags ) + flags:|_defaultFlags + Local g:TGraphics + Try + g=_driver.AttachGraphics( widget,flags ) + Catch ex:Object +?Debug + WriteStdout "AttachGraphics failed:"+ex.ToString() +? + End Try + Return g +End Function + +Rem +bbdoc: Close a graphics object +about: +Once closed, a graphics object can no longer be used. +End Rem +Function CloseGraphics( g:TGraphics ) + If g=_exGraphics _exGraphics=Null + If g=_graphics SetGraphics Null + g.Close +End Function + +Rem +bbdoc: Set current graphics object +about: +#SetGraphics will also change the current graphics driver if @g uses a different driver +than the current driver. +End Rem +Function SetGraphics( g:TGraphics ) + If Not g + If _driver And _graphics _driver.SetGraphics Null + _graphics=Null + _gWidth=0 + _gHeight=0 + _gDepth=0 + _gHertz=0 + _gFlags=0 + Return + EndIf + Local d:TGraphicsDriver=g.Driver() + If d<>_driver + If _driver And _graphics _driver.SetGraphics Null + _graphicsModes=Null + _driver=d + EndIf + g.GetSettings _gWidth,_gHeight,_gDepth,_gHertz,_gFlags + d.SetGraphics g + _graphics=g +End Function + +Rem +bbdoc: Get width of current graphics object +returns: The width, in pixels, of the current graphics object +about: +The current graphics object can be changed using #SetGraphics. +End Rem +Function GraphicsWidth() + Return _gWidth +End Function + +Rem +bbdoc: Get height of current graphics object +returns: The height, in pixels, of the current graphics object +about: +The current graphics object can be changed using #SetGraphics. +End Rem +Function GraphicsHeight() + Return _gHeight +End Function + +Rem +bbdoc: Get depth of current graphics object +returns: The depth, in bits, of the current graphics object +about: +The current graphics object can be changed using #SetGraphics. +End Rem +Function GraphicsDepth() + Return _gDepth +End Function + +Rem +bbdoc: Get refresh rate of current graphics object +returns: The refresh rate, in frames per second, of the current graphics object +about: +The current graphics object can be changed using #SetGraphics. +End Rem +Function GraphicsHertz() + Return _gHertz +End Function + +Rem +bbdoc: Get flags of current graphics object +returns: The flags of the current graphics object +about: +The current graphics object can be changed using #SetGraphics. +End Rem +Function GraphicsFlags() + Return _gFlags +End Function + +Rem +bbdoc: Flip current graphics object +about: +#Flip swap the front and back buffers of the current graphics objects. + +If @sync is 0, then the flip occurs as soon as possible. If @sync is 1, then the flip occurs +on the next vertical blank. + +If @sync is -1 and the current graphics object was created with the #Graphics command, +then flips will occur at the graphics object's refresh rate, unless the graphics object was +created with a refresh rate of 0 in which case flip occurs immediately. + +If @sync is -1 and the current graphics object was NOT created with the #Graphics command, +then the flip will occur on the next vertical blank. +End Rem +Function Flip( sync=-1 ) + RunHooks FlipHook,Null + + If sync<>-1 + _driver.Flip sync + Return + EndIf + + If _graphics<>_exGraphics + _driver.Flip True + Return + EndIf + + If _softSync + _syncTime:+_syncPeriod + _syncAccum:+_syncFrac + If _syncAccum>=_syncRate + _syncAccum:-_syncRate + _syncTime:+1 + EndIf + Local dt=_syncTime-MilliSecs() + If dt>0 + Delay dt + Else + _syncTime:-dt + EndIf + _driver.Flip False + Else If _hardSync + _driver.Flip True + Else + _driver.Flip False + EndIf + +End Function + +Rem +Function Flip( sync=-1 ) + RunHooks FlipHook,Null + If sync<>-1 + _driver.Flip sync + Return + EndIf + If _graphics<>_exGraphics Or Not _softSync + Local sync=False + If _gDepth sync=True + _driver.Flip sync + Return + EndIf + _syncTime:+_syncPeriod + _syncAccum:+_syncFrac + If _syncAccum>=_syncRate + _syncAccum:-_syncRate + _syncTime:+1 + EndIf + Local dt=_syncTime-MilliSecs() + If dt>0 + Delay dt + Else + _syncTime:-dt + EndIf + _driver.Flip False +End Function +End Rem + +Rem +bbdoc: Begin graphics +returns: A graphics object +about: +#Graphics is a convenience function that simplifies the process of creating a graphics +object. + +Once #Graphics has executed, you can begin rendering immediately without any need for +#SetGraphics. + +#Graphics also enables #{polled input} mode, providing a simple way to monitor the keyboard +and mouse. +End Rem +Function Graphics:TGraphics( width,height,depth=0,hertz=60,flags=0 ) + EndGraphics + flags:|_defaultFlags + + Local g:TGraphics=CreateGraphics( width,height,depth,hertz,flags ) + If Not g Return + + BumpGraphicsSeq + + SetGraphics g + + If depth + _softSync=False + _hardSync=(hertz<>0) + MoveMouse width/2,height/2 + Else + _hardSync=False + _softSync=(hertz<>0) + EndIf + + If _softSync + _syncRate=hertz + If _syncRate _syncPeriod=1000/_syncRate Else _syncPeriod=0 + _syncFrac=1000-_syncPeriod*_syncRate + _syncAccum=0 + _syncTime=MilliSecs() + EndIf + + EnablePolledInput + + _exGraphics=g + + Global _onEnd + If Not _onEnd + _onEnd=True + OnEnd EndGraphics + EndIf + + Return g +End Function + +Rem +Function Graphics:TGraphics( width,height,depth=0,hertz=60,flags=0 ) + + EndGraphics + flags:|_defaultFlags + + Local g:TGraphics=CreateGraphics( width,height,depth,hertz,flags ) + If Not g Return + + GraphicsSeq:+1 + If Not GraphicsSeq GraphicsSeq=1 + + SetGraphics g + + _softSync=True + If Not hertz + _softSync=False + Else If depth + Local e=MilliSecs()+1000,n + While e-MilliSecs()>0 + Local t=MilliSecs() + _driver.Flip True + t=(MilliSecs()-t)-1000/hertz + If t>=-1 And t<=1 + n:+1 + If n<3 Continue + _softSync=False + Exit + EndIf + n=0 + Wend + EndIf + _syncRate=hertz + If _syncRate _syncPeriod=1000/_syncRate Else _syncPeriod=0 + _syncFrac=1000-_syncPeriod*_syncRate + _syncAccum=0 + _syncTime=MilliSecs() + + _exGraphics=g + + If depth + MoveMouse width/2,height/2 + EndIf + + EnablePolledInput + + Global _onEnd + If Not _onEnd + _onEnd=True + OnEnd EndGraphics + EndIf + + Return g + +End Function +End Rem + +Rem +bbdoc: End graphics +about: +#EndGraphics closes the graphics object returned by #Graphics. +End Rem +Function EndGraphics() + If Not _exGraphics Return + + GraphicsSeq:+1 + If Not GraphicsSeq GraphicsSeq=1 + + DisablePolledInput + + CloseGraphics _exGraphics +End Function diff --git a/mod/brl.mod/hook.mod/doc/addhook.bmx b/mod/brl.mod/hook.mod/doc/addhook.bmx new file mode 100644 index 0000000..396742c --- /dev/null +++ b/mod/brl.mod/hook.mod/doc/addhook.bmx @@ -0,0 +1,26 @@ + +'This function will be automagically called every Flip +Function MyHook:Object( id,data:Object,context:Object ) + Global count + + count:+1 + If count Mod 10=0 Print "Flips="+count + +End Function + +'Add our hook to the system +AddHook FlipHook,MyHook + +'Some simple graphics +Graphics 640,480,0 + +While Not KeyHit( KEY_ESCAPE ) + + Cls + DrawText MouseX()+","+MouseY(),0,0 + Flip + +Wend + + + diff --git a/mod/brl.mod/hook.mod/doc/intro.bbdoc b/mod/brl.mod/hook.mod/doc/intro.bbdoc new file mode 100644 index 0000000..64dac30 --- /dev/null +++ b/mod/brl.mod/hook.mod/doc/intro.bbdoc @@ -0,0 +1,16 @@ + +This module provides a generic way to hook into various BlitzMax commands, and to add support for +hooks into your own code. + +The following hook ids are currently used by BlitzMax modules: + +[ @{Hook id} | @Description | @Data +* FlipHook | A Max2D #Flip is about to occur | Null +* EmitEventHook | An event has been emitted by a call to #EmitEvent | A #TEvent object +] +To hook into any of these functions, use #AddHook with the specified hook id and your hook function. + +To provide hook support for your own code, use #AllocHookId to generate a valid integer hook id +somewhere in your program's startup code. Then, when the section of code you would like to be +'hookable' is about to execute, simply call #RunHooks with the previously generated hook id and your +own custom 'data' object. diff --git a/mod/brl.mod/hook.mod/hook.bmx b/mod/brl.mod/hook.mod/hook.bmx new file mode 100644 index 0000000..751abe5 --- /dev/null +++ b/mod/brl.mod/hook.mod/hook.bmx @@ -0,0 +1,121 @@ + +Strict + +Rem +bbdoc: Events/Hook functions +End Rem +Module BRL.Hook + +ModuleInfo "Version: 1.01" +ModuleInfo "Author: Mark Sibly" +ModuleInfo "License: zlib/libpng" +ModuleInfo "Copyright: Blitz Research Ltd" +ModuleInfo "Modserver: BRL" + +ModuleInfo "History: 1.01 Release" +ModuleInfo "History: Added Context parameter to RemoveHook function" + +Private + +Type THook + Field succ:THook + Field priority + Field func:Object( id,data:Object,context:Object ) + Field context:Object +End Type + +Global hooks:THook[256] + +Public + +Rem +bbdoc: Allocate a hook id +returns: An integer hook id +about: +The returned hook id can be used with #AddHook, #RunHooks and #RemoveHook. +end rem +Function AllocHookId() + Global id=-1 + id:+1 + If id>255 Throw "Too many hook ids" + Return id +End Function + +Rem +bbdoc: Add a hook function +returns: A hook object that can be used with the #RemoveHook command. +about: +Add a hook function to be executed when #RunHooks is called with the specified hook @id. +End Rem +Function AddHook( id,func:Object( id,data:Object,context:Object ),context:Object=Null,priority=0 ) + + Local t:THook=New THook + t.priority=priority + t.func=func + t.context=context + + Local pred:THook + Local hook:THook=hooks[id] + + While hook + If priority>hook.priority Exit + pred=hook + hook=hook.succ + Wend + + If pred + t.succ=pred.succ + pred.succ=t + Else + t.succ=hooks[id] + hooks[id]=t + EndIf + +End Function + +Rem +bbdoc: Run hook functions +returns: The data produced by the last hook function +about: +#RunHooks runs all hook functions that have been added for the specified hook @id. + +The first hook function is called with the provided @data object. The object returned by +this function is then passed as the @data parameter to the next hook function and so on. +Therefore, hook functions should generally return the @data parameter when finished. +End Rem +Function RunHooks:Object( id,data:Object ) + + Local hook:THook=hooks[id] + While hook + data=hook.Func( id,data,hook.context ) + hook=hook.succ + Wend + Return data + +End Function + +Rem +bbdoc:Remove a hook function +about: +Removes the hook function specified by @id, @func and @context. +End Rem +Function RemoveHook( id,func:Object( id,data:Object,context:Object ),context:Object=Null ) + + Local pred:THook + Local hook:THook=hooks[id] + + While hook And (hook.func<>func Or hook.context<>context) + pred=hook + hook=hook.succ + Wend + + If Not hook Return + + If pred + pred.succ=hook.succ + Else + hooks[id]=hook.succ + EndIf + +End Function + diff --git a/mod/brl.mod/httpstream.mod/httpstream.bmx b/mod/brl.mod/httpstream.mod/httpstream.bmx new file mode 100644 index 0000000..1740c3f --- /dev/null +++ b/mod/brl.mod/httpstream.mod/httpstream.bmx @@ -0,0 +1,47 @@ + +Strict + +Module BRL.HTTPStream + +ModuleInfo "Version: 1.02" +ModuleInfo "Author: Mark Sibly" +ModuleInfo "License: zlib/libpng" +ModuleInfo "Copyright: Blitz Research Ltd" +ModuleInfo "Modserver: BRL" + +ModuleInfo "History: 1.02 Release" + +Import BRL.SocketStream + +Type THTTPStreamFactory Extends TStreamFactory + + Method CreateStream:TStream( url:Object,proto$,path$,readable,writeable ) + If proto="http" + + Local i=path.Find( "/",0 ),server$,file$ + If i<>-1 + server=path[..i] + file=path[i..] + Else + server=path + file="/" + EndIf + + Local stream:TStream=TSocketStream.CreateClient( server,80 ) + If Not stream Return + + stream.WriteLine "GET "+file+" HTTP/1.0" + stream.WriteLine "Host: "+server + stream.WriteLine "" + + While Not Eof( stream ) + If Not stream.ReadLine() Exit + Wend + + Return stream + EndIf + End Method + +End Type + +New THTTPStreamFactory diff --git a/mod/brl.mod/jpgloader.mod/jpgloader.bmx b/mod/brl.mod/jpgloader.mod/jpgloader.bmx new file mode 100644 index 0000000..71d29c1 --- /dev/null +++ b/mod/brl.mod/jpgloader.mod/jpgloader.bmx @@ -0,0 +1,120 @@ + +Strict + +Rem +bbdoc: Graphics/JPG loader +about: +The JPG loader module provides the ability to load JPG format #pixmaps. +End Rem +Module BRL.JPGLoader + +ModuleInfo "Version: 1.05" +ModuleInfo "Author: Simon Armstrong, Jeffrey D. Panici" +ModuleInfo "License: zlib/libpng" +ModuleInfo "Copyright: Blitz Research Ltd" +ModuleInfo "Modserver: BRL" + +ModuleInfo "History: 1.05 Release" +ModuleInfo "History: Fixed SavePixmapJPeg" +ModuleInfo "History: 1.04 Release" +ModuleInfo "History: Removed print" +ModuleInfo "History: 1.03 Release" +ModuleInfo "History: Changed ReadBytes to Read for loader" +ModuleInfo "History: Added SaveJPEG function, thanks to Jeffrey D. Panici for the writefunc `fix'" +ModuleInfo "History: 1.02 Release" +ModuleInfo "History: Added support for monochrome / single channel" + +Import BRL.Pixmap +Import Pub.LibJPEG + +Private + +Function readfunc%( buf:Byte Ptr,count,src:Object ) + Local stream:TStream + stream=TStream(src) + Local n=stream.Read( buf,count ) + Return n +End Function + +Function writefunc%( buf:Byte Ptr,count,src:Object ) + Local stream:TStream + stream=TStream(src) + Local n=stream.Write( buf,count ) + Return n +End Function + +Public + +Rem +bbdoc: Load a Pixmap in JPeg format +about: +#LoadPixmapJPeg loads a pixmap from @url in JPeg format. + +If the pixmap cannot be loaded, Null is returned. +End Rem +Function LoadPixmapJPeg:TPixmap( url:Object ) + + Local jpg,width,height,depth,y + Local pix:Byte Ptr + Local pixmap:TPixmap + Local stream:TStream + + stream=ReadStream( url ) + If Not stream Return + + Local res=loadjpg(stream,readfunc,width,height,depth,pix) + stream.Close + If res Return Null + + If width=0 Return + Select depth + Case 1 + pixmap=CreatePixmap( width,height,PF_I8 ) + For y=0 Until height + CopyPixels pix+y*width,pixmap.PixelPtr(0,y),PF_I8,width + Next + Case 3 + pixmap=CreatePixmap( width,height,PF_RGB888 ) + For y=0 Until height + CopyPixels pix+y*width*3,pixmap.PixelPtr(0,y),PF_RGB888,width + Next + End Select + free_ pix + Return pixmap +End Function + +Rem +bbdoc: Save a Pixmap in JPeg format +about: +Saves @pixmap to @url in JPeg format. If successful, #SavePixmapJPeg returns +True, otherwise False. + +The optional @quality parameter should be in the range 0 to 100, where +0 indicates poor quality (smallest) and 100 indicates best quality (largest). +End Rem +Function SavePixmapJPeg( pixmap:TPixmap,url:Object,quality=75 ) + + Assert quality>=1 And quality<=100 + + Local stream:TStream=WriteStream( url ) + If Not stream Return + + pixmap=pixmap.convert(PF_RGB888) + + Local pix:Byte Ptr=pixmap.PixelPtr( 0,0 ) + + savejpg(stream,writefunc,pixmap.width,pixmap.height,pixmap.pitch,pix,quality) + + stream.Close + Return True +End Function + +Private + +Type TPixmapLoaderJPG Extends TPixmapLoader + Method LoadPixmap:TPixmap( stream:TStream ) + Return LoadPixmapJPeg( stream ) + End Method +End Type + +New TPixmapLoaderJPG diff --git a/mod/brl.mod/keycodes.mod/doc/intro.bbdoc b/mod/brl.mod/keycodes.mod/doc/intro.bbdoc new file mode 100644 index 0000000..9750b35 --- /dev/null +++ b/mod/brl.mod/keycodes.mod/doc/intro.bbdoc @@ -0,0 +1,129 @@ + +The key codes module contains a list of constants representing numeric codes for +keys, modifiers and mouse buttons. + +These codes are used by key and mouse #events, and by the #{polled input} module. + +[ @{Mouse Button} | @{Value} +* Left mouse button | MOUSE_LEFT +* Right mouse button | MOUSE_RIGHT +* Middle mouse button | MOUSE_MIDDLE +] + +[ @{Modifier} | @{Value} +* Shift modifier | MODIFIER_SHIFT +* Control modifier | MODIFIER_CONTROL +* Option modifier | MODIFIER_OPTION +* System modifier | MODIFIER_SYSTEM +* Command modifier | MODIFIER_COMMAND +] + +[ @{Key} | @{Value} +* Backspace | KEY_BACKSPACE +* Tab | KEY_TAB +* Clear | KEY_CLEAR +* Return | KEY_RETURN +* Enter | KEY_ENTER +* Pause | KEY_PAUSE +* Escape | KEY_ESCAPE +* Space | KEY_SPACE +* Page Up | KEY_PAGEUP +* Page Down | KEY_PAGEDOWN +* End | KEY_END +* Home | KEY_HOME +* Cursor (Left) | KEY_LEFT +* Cursor (Up) | KEY_UP +* Cursor (Right) | KEY_RIGHT +* Cursor (Down) | KEY_DOWN +* Select | KEY_SELECT +* Print | KEY_PRINT +* Execute | KEY_EXECUTE +* Screen | KEY_SCREEN +* Insert | KEY_INSERT +* Delete | KEY_DELETE +* Help | KEY_HELP +* 0 | KEY_0 +* 1 | KEY_1 +* 2 | KEY_2 +* 3 | KEY_3 +* 4 | KEY_4 +* 5 | KEY_5 +* 6 | KEY_6 +* 7 | KEY_7 +* 8 | KEY_8 +* 9 | KEY_9 +* A | KEY_A +* B | KEY_B +* C | KEY_C +* D | KEY_D +* E | KEY_E +* F | KEY_F +* G | KEY_G +* H | KEY_H +* I | KEY_I +* J | KEY_J +* K | KEY_K +* L | KEY_L +* M | KEY_M +* N | KEY_N +* O | KEY_O +* P | KEY_P +* Q | KEY_Q +* R | KEY_R +* S | KEY_S +* T | KEY_T +* U | KEY_U +* V | KEY_V +* W | KEY_W +* X | KEY_X +* Y | KEY_Y +* Z | KEY_Z +* Sys key (Left) | KEY_LSYS +* Sys key (Right) | KEY_RSYS +* Numpad 0 | KEY_NUM0 +* Numpad 1 | KEY_NUM1 +* Numpad 2 | KEY_NUM2 +* Numpad 3 | KEY_NUM3 +* Numpad 4 | KEY_NUM4 +* Numpad 5 | KEY_NUM5 +* Numpad 6 | KEY_NUM6 +* Numpad 7 | KEY_NUM7 +* Numpad 8 | KEY_NUM8 +* Numpad 9 | KEY_NUM9 +* Numpad * | KEY_NUMMULTIPLY +* Numpad + | KEY_NUMADD +* Numpad - | KEY_NUMSUBTRACT +* Numpad . | KEY_NUMDECIMAL +* Numpad / | KEY_NUMDIVIDE +* F1 | KEY_F1 +* F2 | KEY_F2 +* F3 | KEY_F3 +* F4 | KEY_F4 +* F5 | KEY_F5 +* F6 | KEY_F6 +* F7 | KEY_F7 +* F8 | KEY_F8 +* F9 | KEY_F9 +* F10 | KEY_F10 +* F11 | KEY_F11 +* F12 | KEY_F12 +* Num Lock | KEY_NUMLOCK +* Scroll Lock | KEY_SCROLL +* Shift (Left) | KEY_LSHIFT +* Shift (Right) | KEY_RSHIFT +* Control (Left) | KEY_LCONTROL +* Control (Right) | KEY_RCONTROL +* Alt key (Left) | KEY_LALT +* Alt key (Right) | KEY_RALT +* Tilde | KEY_TILDE +* Minus | KEY_MINUS +* Equals | KEY_EQUALS +* Bracket (Open) | KEY_OPENBRACKET +* Bracket (Close) | KEY_CLOSEBRACKET +* Backslash | KEY_BACKSLASH +* Semi-colon | KEY_SEMICOLON +* Quote | KEY_QUOTES +* Comma | KEY_COMMA +* Period | KEY_PERIOD +* Slash | KEY_SLASH +] diff --git a/mod/brl.mod/keycodes.mod/keycodes.bmx b/mod/brl.mod/keycodes.mod/keycodes.bmx new file mode 100644 index 0000000..ee19f54 --- /dev/null +++ b/mod/brl.mod/keycodes.mod/keycodes.bmx @@ -0,0 +1,155 @@ + +Strict + +Rem +bbdoc: User input/Key codes +End Rem +Module BRL.KeyCodes + +ModuleInfo "Version: 1.05" +ModuleInfo "Author: Mark Sibly" +ModuleInfo "License: zlib/libpng" +ModuleInfo "Copyright: Blitz Research Ltd" +ModuleInfo "Modserver: BRL" + +ModuleInfo "History: 1.05 Release" +ModuleInfo "History: Removed KEY_NUMSLASH from docs" + +Const MOUSE_LEFT=1 +Const MOUSE_RIGHT=2 +Const MOUSE_MIDDLE=3 + +Const MODIFIER_NONE=0 +Const MODIFIER_SHIFT=1 'shift key +Const MODIFIER_CONTROL=2 'ctrl key +Const MODIFIER_OPTION=4 'alt or menu key +Const MODIFIER_SYSTEM=8 'windows or apple key + +Const MODIFIER_LMOUSE=16 'reserved by Mark! +Const MODIFIER_RMOUSE=32 'reserved by Mark! +Const MODIFIER_MMOUSE=64 'reserved by Mark! + +Const MODIFIER_ALT=MODIFIER_OPTION +Const MODIFIER_MENU=MODIFIER_OPTION +Const MODIFIER_APPLE=MODIFIER_SYSTEM +Const MODIFIER_WINDOWS=MODIFIER_SYSTEM + +?MACOS +Const MODIFIER_COMMAND=MODIFIER_APPLE +?Win32 +Const MODIFIER_COMMAND=MODIFIER_CONTROL +?Linux +Const MODIFIER_COMMAND=MODIFIER_CONTROL +? + +Const KEY_BACKSPACE=8 +Const KEY_TAB=9 +Const KEY_CLEAR=12 +Const KEY_RETURN=13 +Const KEY_ENTER=13 +Const KEY_ESCAPE=27 +Const KEY_SPACE=32 +Const KEY_PAGEUP=33 +Const KEY_PAGEDOWN=34 +Const KEY_END=35 +Const KEY_HOME=36 + +Const KEY_LEFT=37,KEY_UP=38,KEY_RIGHT=39,KEY_DOWN=40 + +Const KEY_SELECT=41 +Const KEY_PRINT=42 +Const KEY_EXECUTE=43 +Const KEY_SCREEN=44 +Const KEY_INSERT=45 +Const KEY_DELETE=46 + +Const KEY_0=48,KEY_1=49,KEY_2=50,KEY_3=51,KEY_4=52 +Const KEY_5=53,KEY_6=54,KEY_7=55,KEY_8=56,KEY_9=57 +Const KEY_A=65,KEY_B=66,KEY_C=67,KEY_D=68,KEY_E=69 +Const KEY_F=70,KEY_G=71,KEY_H=72,KEY_I=73,KEY_J=74 +Const KEY_K=75,KEY_L=76,KEY_M=77,KEY_N=78,KEY_O=79 +Const KEY_P=80,KEY_Q=81,KEY_R=82,KEY_S=83,KEY_T=84 +Const KEY_U=85,KEY_V=86,KEY_W=87,KEY_X=88,KEY_Y=89 +Const KEY_Z=90 + +Const KEY_NUM0=96 +Const KEY_NUM1=97 +Const KEY_NUM2=98 +Const KEY_NUM3=99 +Const KEY_NUM4=100 +Const KEY_NUM5=101 +Const KEY_NUM6=102 +Const KEY_NUM7=103 +Const KEY_NUM8=104 +Const KEY_NUM9=105 + +Const KEY_NUMMULTIPLY=106 +Const KEY_NUMADD=107 +Const KEY_NUMSUBTRACT=109 +Const KEY_NUMDECIMAL=110 +Const KEY_NUMDIVIDE=111 + +Const KEY_F1=112 +Const KEY_F2=113 +Const KEY_F3=114 +Const KEY_F4=115 +Const KEY_F5=116 +Const KEY_F6=117 +Const KEY_F7=118 +Const KEY_F8=119 +Const KEY_F9=120 +Const KEY_F10=121 +Const KEY_F11=122 +Const KEY_F12=123 + +Const KEY_TILDE=192 +Const KEY_MINUS=189 +Const KEY_EQUALS=187 + +Const KEY_OPENBRACKET=219 +Const KEY_CLOSEBRACKET=221 +Const KEY_BACKSLASH=226 + +Const KEY_SEMICOLON=186 +Const KEY_QUOTES=222 + +Const KEY_COMMA=188 +Const KEY_PERIOD=190 +Const KEY_SLASH=191 + +Const KEY_LSHIFT=160 +Const KEY_RSHIFT=161 +Const KEY_LCONTROL=162 +Const KEY_RCONTROL=163 +Const KEY_LALT=164 +Const KEY_RALT=165 +Const KEY_LSYS=91 +Const KEY_RSYS=92 + +Rem +Const KEY_PAUSE=19 +Const KEY_CAPSLOCK=20 +Const KEY_HELP=47 +Const KEY_NUMSLASH=108 +Const KEY_START=93 +Const KEY_NUMLOCK=144 +Const KEY_SCROLL=145 +Const KEY_BROWSER_BACK=166 +Const KEY_BROWSER_FORWARD=167 +Const KEY_BROWSER_REFRESH=168 +Const KEY_BROWSER_STOP=169 +Const KEY_BROWSER_SEARCH=170 +Const KEY_BROWSER_FAVORITES=171 +Const KEY_BROWSER_HOME=172 +Const KEY_VOLUME_MUTE=173 +Const KEY_VOLUME_DOWN=174 +Const KEY_VOLUME_UP=175 +Const KEY_MEDIA_NEXT_TRACK=176 +Const KEY_MEDIA_PREV_TRACK=177 +Const KEY_MEDIA_STOP=178 +Const KEY_MEDIA_PLAY_PAUSE=179 +Const KEY_LAUNCH_MAIL=180 +Const KEY_LAUNCH_MEDIA_SELECT=181 +Const KEY_LAUNCH_APP1=182 +Const KEY_LAUNCH_APP2=183 +End Rem diff --git a/mod/brl.mod/keycodes.mod/keycodes.h b/mod/brl.mod/keycodes.mod/keycodes.h new file mode 100644 index 0000000..36223ff --- /dev/null +++ b/mod/brl.mod/keycodes.mod/keycodes.h @@ -0,0 +1,58 @@ + +#ifndef BB_BRL_KEYCODES_H +#define BB_BRL_KEYCODES_H + +enum{ + MOUSE_LEFT=1, + MOUSE_RIGHT=2, + MOUSE_MIDDLE=3 +}; + +enum{ + MODIFIER_NONE=0, + MODIFIER_SHIFT=1, + MODIFIER_CONTROL=2, + MODIFIER_OPTION=4, + MODIFIER_SYSTEM=8, + + MODIFIER_ALT=MODIFIER_OPTION, + MODIFIER_MENU=MODIFIER_OPTION, + MODIFIER_APPLE=MODIFIER_SYSTEM, + MODIFIER_WINDOWS=MODIFIER_SYSTEM +}; + +enum{ + KEY_BACKSPACE=8,KEY_TAB, + KEY_ENTER=13, + KEY_ESC=27, + KEY_SPACE=32, + KEY_PAGEUP=33,KEY_PAGEDOWN,KEY_END,KEY_HOME, + KEY_LEFT=37,KEY_UP,KEY_RIGHT,KEY_DOWN, + KEY_INSERT=45,KEY_DELETE, + KEY_0=48,KEY_1,KEY_2,KEY_3,KEY_4,KEY_5,KEY_6,KEY_7,KEY_8,KEY_9, + KEY_A=65,KEY_B,KEY_C,KEY_D,KEY_E,KEY_F,KEY_G,KEY_H,KEY_I,KEY_J, + KEY_K,KEY_L,KEY_M,KEY_N,KEY_O,KEY_P,KEY_Q,KEY_R,KEY_S,KEY_T, + KEY_U,KEY_V,KEY_W,KEY_X,KEY_Y,KEY_Z, + + KEY_LSYS=91,KEY_RSYS, + + KEY_NUM0=96,KEY_NUM1,KEY_NUM2,KEY_NUM3,KEY_NUM4, + KEY_NUM5,KEY_NUM6,KEY_NUM7,KEY_NUM8,KEY_NUM9, + KEY_NUMMULTIPLY=106,KEY_NUMADD,KEY_NUMSLASH, + KEY_NUMSUBTRACT,KEY_NUMDECIMAL,KEY_NUMDIVIDE, + + KEY_F1=112,KEY_F2,KEY_F3,KEY_F4,KEY_F5,KEY_F6, + KEY_F7,KEY_F8,KEY_F9,KEY_F10,KEY_F11,KEY_F12, + + KEY_LSHIFT=160,KEY_RSHIFT, + KEY_LCONTROL=162,KEY_RCONTROL, + KEY_LALT=164,KEY_RALT, + + KEY_TILDE=192,KEY_MINUS=189,KEY_EQUALS=187, + KEY_OPENBRACKET=219,KEY_CLOSEBRACKET=221,KEY_BACKSLASH=226, + KEY_SEMICOLON=186,KEY_QUOTES=222, + KEY_COMMA=188,KEY_PERIOD=190,KEY_SLASH=191 +}; + +#endif + diff --git a/mod/brl.mod/linkedlist.mod/doc/createlist.bmx b/mod/brl.mod/linkedlist.mod/doc/createlist.bmx new file mode 100644 index 0000000..08ccddb --- /dev/null +++ b/mod/brl.mod/linkedlist.mod/doc/createlist.bmx @@ -0,0 +1,17 @@ +' createlist.bmx + +' create a list to hold some objects + +list:TList=createlist() + +' add some string objects to the list + +listaddlast list,"one" +listaddlast list,"two" +listaddlast list,"three" + +' enumerate all the strings in the list + +for a$=eachin list + print a$ +next diff --git a/mod/brl.mod/linkedlist.mod/doc/intro.bbdoc b/mod/brl.mod/linkedlist.mod/doc/intro.bbdoc new file mode 100644 index 0000000..9f105b8 --- /dev/null +++ b/mod/brl.mod/linkedlist.mod/doc/intro.bbdoc @@ -0,0 +1,10 @@ + ++Linked lists + +A linked list allows you to efficiently add and remove objects to and from a collection of objects. + +To create a linked list, use the #CreateList command. + +Add objects to a linked list using #ListAddFirst or #ListAddLast. Both commands return a link object which can be used to later remove the object with the #RemoveLink command. You can also remove objects with the #ListRemove command. However this is not as efficient as using #RemoveLink because the list must first be searched for the object to be removed. + +To visit all the objects in a linked list, you can use an #EachIn loop. diff --git a/mod/brl.mod/linkedlist.mod/linkedlist.bmx b/mod/brl.mod/linkedlist.mod/linkedlist.bmx new file mode 100644 index 0000000..fd2ec64 --- /dev/null +++ b/mod/brl.mod/linkedlist.mod/linkedlist.bmx @@ -0,0 +1,553 @@ + +Strict + +Rem +bbdoc: Data structures/Linked lists +End Rem +Module BRL.LinkedList + +ModuleInfo "Version: 1.07" +ModuleInfo "Author: Mark Sibly" +ModuleInfo "License: zlib/libpng" +ModuleInfo "Copyright: Blitz Research Ltd" +ModuleInfo "Modserver: BRL" + +ModuleInfo "History: 1.07 Release" +ModuleInfo "History: Changed Reverse to maintain TLink stability" +ModuleInfo "History: 1.06 Release" +ModuleInfo "History: Added optional CompareFunc parameter to Sort" +ModuleInfo "History: 1.05 Release" +ModuleInfo "History: Sort now swaps links instead of values" + +Function CompareObjects( o1:Object,o2:Object ) + Return o1.Compare( o2 ) +End Function + +Rem +bbdoc: Link Object used by TList +End Rem +Type TLink + + Field _value:Object + Field _succ:TLink,_pred:TLink + + Rem + bbdoc: Returns the Object associated with this Link. + End Rem + Method Value:Object() + Return _value + End Method + + Rem + bbdoc: Returns the next link in the List. + End Rem + Method NextLink:TLink() + If _succ._value<>_succ Return _succ + End Method + + Rem + bbdoc: Returns the previous link in the List. + End Rem + Method PrevLink:TLink() + If _pred._value<>_pred Return _pred + End Method + + Rem + bbdoc: Removes the link from the List. + End Rem + Method Remove() + _value=Null + _succ._pred=_pred + _pred._succ=_succ + End Method + +End Type + +Rem +bbdoc: Enumerator Object use by TList in order to implement Eachin support. +End Rem +Type TListEnum + + Field _link:TLink + + Method HasNext() + Return _link._value<>_link + End Method + + Method NextObject:Object() + Local value:Object=_link._value + Assert value<>_link + _link=_link._succ + Return value + End Method + +End Type + +Rem +bbdoc: Linked List +End Rem +Type TList + + Field _head:TLink + + Method _pad() + End Method + + Method New() + _head=New TLink + _head._succ=_head + _head._pred=_head + _head._value=_head + End Method + +?Not Threaded + Method Delete() + Clear + _head._value=Null + _head._succ=Null + _head._pred=Null + End Method +? + Rem + bbdoc: Clear a linked list + about: Removes all objects from @list. + End Rem + Method Clear() + While _head._succ<>_head + _head._succ.Remove + Wend + End Method + + Rem + bbdoc: Check if list is empty + returns: True if list is empty, else false + end rem + Method IsEmpty() + Return _head._succ=_head + End Method + + Rem + bbdoc: Check if list contains a value + returns: True if list contains @value, else false + end rem + Method Contains( value:Object ) + Local link:TLink=_head._succ + While link<>_head + If link._value.Compare( value )=0 Return True + link=link._succ + Wend + Return False + End Method + + Rem + bbdoc: Add an object to the start of the list + returns: A link object + End Rem + Method AddFirst:TLink( value:Object ) + Assert value Else "Can't insert Null object into list" + Return InsertAfterLink( value,_head ) + End Method + + Rem + bbdoc: Add an object to the end of the list + returns: A link object + End Rem + Method AddLast:TLink( value:Object ) + Assert value Else "Can't insert Null object into list" + Return InsertBeforeLink( value,_head ) + End Method + + Rem + bbdoc: Returns the first object in the list + about: Returns Null if the list is empty. + End Rem + Method First:Object() + If IsEmpty() Return + Return _head._succ._value + End Method + + Rem + bbdoc: Returns the last object in the list + about: Returns Null if the list is empty. + End Rem + Method Last:Object() + If IsEmpty() Return + Return _head._pred._value + End Method + + Rem + bbdoc: Removes and returns the first object in the list. + about: Returns Null if the list is empty. + End Rem + Method RemoveFirst:Object() + If IsEmpty() Return + Local value:Object=_head._succ._value + _head._succ.remove + Return value + End Method + + Rem + bbdoc: Removes and returns the last object in the list. + about: Returns Null if the list is empty. + End Rem + Method RemoveLast:Object() + If IsEmpty() Return + Local value:Object=_head._pred._value + _head._pred.remove + Return value + End Method + + Rem + bbdoc: Returns the first link the list or null if the list is empty. + End Rem + Method FirstLink:TLink() + If _head._succ<>_head Return _head._succ + End Method + + Rem + bbdoc: Returns the last link the list or null if the list is empty. + End Rem + Method LastLink:TLink() + If _head._pred<>_head Return _head._pred + End Method + + Rem + bbdoc: Inserts an object before the specified list link. + End Rem + Method InsertBeforeLink:TLink( value:Object,succ:TLink ) + Assert value Else "Can't insert Null object into list" + Local link:TLink=New TLink + link._value=value + link._succ=succ + link._pred=succ._pred + link._pred._succ=link + succ._pred=link + Return link + End Method + + Rem + bbdoc: Inserts an object after the specified list link. + End Rem + Method InsertAfterLink:TLink( value:Object,pred:TLink ) + Assert value Else "Can't insert Null object into list" + Local link:TLink=New TLink + link._value=value + link._pred=pred + link._succ=pred._succ + link._succ._pred=link + pred._succ=link + Return link + End Method + + Rem + bbdoc: Returns the first link in the list with the given value, or null if none found. + End Rem + Method FindLink:TLink( value:Object ) + Local link:TLink=_head._succ + While link<>_head + If link._value.Compare( value )=0 Return link + link=link._succ + Wend + End Method + + Rem + bbdoc: Returns the value of the link at the given index. + about: Throws an exception if the index is out of range (must be 0..list.Count()-1 inclusive). + End Rem + Method ValueAtIndex:Object( index ) + Assert index>=0 Else "Object index must be positive" + Local link:TLink=_head._succ + While link<>_head + If Not index Return link._value + link=link._succ + index:-1 + Wend + RuntimeError "List index out of range" + End Method + + Rem + bbdoc: Count list length + returns: The numbers of objects in @list. + end rem + Method Count() + Local link:TLink=_head._succ,count + While link<>_head + count:+1 + link=link._succ + Wend + Return count + End Method + + Rem + bbdoc: Remove an object from a linked list + about: Remove scans a list for the specified value and removes its link. + End Rem + Method Remove( value:Object ) + Local link:TLink=FindLink( value ) + If Not link Return False + link.Remove + Return True + End Method + + Rem + bbdoc: Swap contents with the list specified. + End Rem + Method Swap( list:TList ) + Local head:TLink=_head + _head=list._head + list._head=head + End Method + + Rem + bbdoc: Creates an identical copy of the list. + End Rem + Method Copy:TList() + Local list:TList=New TList + Local link:TLink=_head._succ + While link<>_head + list.AddLast link._value + link=link._succ + Wend + Return list + End Method + + Rem + bbdoc: Reverse the order of the list. + End Rem + Method Reverse() + Local pred:TLink=_head,succ:TLink=pred._succ + Repeat + Local link:TLink=succ._succ + pred._pred=succ + succ._succ=pred + pred=succ + succ=link + Until pred=_head + End Method + + Rem + bbdoc: Creates a new list that is the reversed version of this list. + End Rem + Method Reversed:TList() + Local list:TList=New TList + Local link:TLink=_head._succ + While link<>_head + list.AddFirst link._value + link=link._succ + Wend + Return list + End Method + + Rem + bbdoc: Sort a list in either ascending (default) or decending order. + about: User types should implement a Compare method in order to be sorted. + End Rem + Method Sort( ascending=True,compareFunc( o1:Object,o2:Object )=CompareObjects ) + Local ccsgn=-1 + If ascending ccsgn=1 + + Local insize=1 + Repeat + Local merges + Local tail:TLink=_head + Local p:TLink=_head._succ + + While p<>_head + merges:+1 + Local q:TLink=p._succ,qsize=insize,psize=1 + + While psize_head + psize:+1 + q=q._succ + Wend + + Repeat + Local t:TLink + If psize And qsize And q<>_head + Local cc=CompareFunc( p._value,q._value ) * ccsgn + If cc<=0 + t=p + p=p._succ + psize:-1 + Else + t=q + q=q._succ + qsize:-1 + EndIf + Else If psize + t=p + p=p._succ + psize:-1 + Else If qsize And q<>_head + t=q + q=q._succ + qsize:-1 + Else + Exit + EndIf + t._pred=tail + tail._succ=t + tail=t + Forever + p=q + Wend + tail._succ=_head + _head._pred=tail + + If merges<=1 Return + + insize:*2 + Forever + End Method + + Method ObjectEnumerator:TListEnum() + Local enum:TListEnum=New TListEnum + enum._link=_head._succ + Return enum + End Method + + Rem + bbdoc: convert a list to an array + returns: An array of objects + end rem + Method ToArray:Object[]() + Local arr:Object[Count()],i + Local link:TLink=_head._succ + While link<>_head + arr[i]=link._value + link=link._succ + i:+1 + Wend + Return arr + End Method + + Rem + bbdoc: Create a list from an array + returns: A new linked list + end rem + Function FromArray:TList( arr:Object[] ) + Local list:TList=New TList + For Local i=0 Until arr.length + list.AddLast arr[i] + Next + Return list + End Function + +End Type + +Rem +bbdoc: Create a linked list +returns: A new linked list object +end rem +Function CreateList:TList() + Return New TList +End Function + +Rem +bbdoc: Clear a linked list +about: Removes all objects from @list. +end rem +Function ClearList( list:TList ) + list.Clear +End Function + +Rem +bbdoc: Count list length +returns: The numbers of objects in @list. +end rem +Function CountList( list:TList ) + Return list.Count() +End Function + +Rem +bbdoc: Check if list is empty +returns: True if list is empty, else false +end rem +Function ListIsEmpty( list:TList ) + Return list.IsEmpty() +End Function + +Rem +bbdoc: Check if list contains a value +returns: True if list contains @value, else false +end rem +Function ListContains( list:TList,value:Object ) + Return list.Contains( value ) +End Function + +Rem +bbdoc: Sort a list +end rem +Function SortList( list:TList,ascending=True,compareFunc( o1:Object,o2:Object )=CompareObjects ) + list.Sort ascending,compareFunc +End Function + +Rem +bbdoc: Create a list from an array +returns: A new linked list +end rem +Function ListFromArray:TList( arr:Object[] ) + Return TList.FromArray( arr ) +End Function + +Rem +bbdoc: convert a list to an array +returns: An array of objects +end rem +Function ListToArray:Object[]( list:TList ) + Return list.ToArray() +End Function + +Rem +bbdoc: Swap the contents of 2 lists +end rem +Function SwapLists( list_x:TList,list_y:TList ) + list_x.Swap list_y +End Function + +Rem +bbdoc: Reverse the order of elements of a list +end rem +Function ReverseList( list:TList ) + list.Reverse +End Function + +Rem +bbdoc: Find a link in a list +returns: The link containting @value +end rem +Function ListFindLink:TLink( list:TList,value:Object ) + Return list.FindLink( value ) +End Function + +Rem +bbdoc: Add an object to a linked list +returns: A link object +end rem +Function ListAddLast:TLink( list:TList,value:Object ) + Return list.AddLast( value ) +End Function + +Rem +bbdoc: Add an object to a linked list +returns: A link object +end rem +Function ListAddFirst:TLink( list:TList,value:Object ) + Return list.AddFirst( value ) +End Function + +Rem +bbdoc: Remove an object from a linked list +about: #ListRemove scans a list for the specified value and removes its link. +end rem +Function ListRemove( list:TList,value:Object ) + list.Remove value +End Function + +Rem +bbdoc: Remove an object from a linked list +about: #RemoveLink is more efficient than #ListRemove. +end rem +Function RemoveLink( link:TLink ) + link.Remove +End Function diff --git a/mod/brl.mod/map.mod/map.bmx b/mod/brl.mod/map.mod/map.bmx new file mode 100644 index 0000000..58bb7e4 --- /dev/null +++ b/mod/brl.mod/map.mod/map.bmx @@ -0,0 +1,566 @@ + +Strict + +Rem +bbdoc: Data structures/Maps +End Rem +Module BRL.Map + +ModuleInfo "Version: 1.07" +ModuleInfo "Author: Mark Sibly" +ModuleInfo "License: zlib/libpng" +ModuleInfo "Copyright: Blitz Research Ltd" +ModuleInfo "Modserver: BRL" + +ModuleInfo "History: 1.07 Release" +ModuleInfo "History: Fixed MapKeys/MapValues functions to return enumerators" +ModuleInfo "History: 1.06 Release" +ModuleInfo "History: Restored KeyValue enumerator" +ModuleInfo "History: 1.05 Release" +ModuleInfo "History: Added Copy method" +ModuleInfo "History: 1.04 Release" +ModuleInfo "History: Fixed Clear memleak" +ModuleInfo "History: 1.03 Release" +ModuleInfo "History: Finally changed to red/back tree!" +ModuleInfo "History: Added procedural interface" +ModuleInfo "History: 1.02 Release" +ModuleInfo "History: Fixed TMap.Remove:TNode not returning node" + +Private + +Global nil:TNode=New TNode + +nil._color=TMap.BLACK +nil._parent=nil +nil._left=nil +nil._right=nil + +Public + +Type TKeyValue + + Method Key:Object() + Return _key + End Method + + Method Value:Object() + Return _value + End Method + + '***** PRIVATE ***** + + Field _key:Object,_value:Object + +End Type + +Type TNode Extends TKeyValue + + Method NextNode:TNode() + Local node:TNode=Self + If node._right<>nil + node=_right + While node._left<>nil + node=node._left + Wend + Return node + EndIf + Local parent:TNode=_parent + While node=parent._right + node=parent + parent=parent._parent + Wend + Return parent + End Method + + Method PrevNode:TNode() + Local node:TNode=Self + If node._left<>nil + node=node._left + While node._right<>nil + node=node._right + Wend + Return node + EndIf + Local parent:TNode=node._parent + While node=parent._left + node=parent + parent=node._parent + Wend + Return parent + End Method + + Method Clear() + _parent=Null + If _left<>nil _left.Clear + If _right<>nil _right.Clear + End Method + + Method Copy:TNode( parent:TNode ) + Local t:TNode=New TNode + t._key=_key + t._value=_value + t._color=_color + t._parent=parent + If _left<>nil t._left=_left.Copy( t ) + If _right<>nil t._right=_right.Copy( t ) + Return t + End Method + + Method Key:Object() + Return _key + End Method + + Method Value:Object() + Return _value + End Method + + '***** PRIVATE ***** + + Field _color,_parent:TNode=nil,_left:TNode=nil,_right:TNode=nil + +End Type + +Type TNodeEnumerator + Method HasNext() + Return _node<>nil + End Method + + Method NextObject:Object() + Local node:TNode=_node + _node=_node.NextNode() + Return node + End Method + + '***** PRIVATE ***** + + Field _node:TNode +End Type + +Type TKeyEnumerator Extends TNodeEnumerator + Method NextObject:Object() + Local node:TNode=_node + _node=_node.NextNode() + Return node._key + End Method +End Type + +Type TValueEnumerator Extends TNodeEnumerator + Method NextObject:Object() + Local node:TNode=_node + _node=_node.NextNode() + Return node._value + End Method +End Type + +Type TMapEnumerator + Method ObjectEnumerator:TNodeEnumerator() + Return _enumerator + End Method + Field _enumerator:TNodeEnumerator +End Type + +'***** PUBLIC ***** + +Type TMap + +?Not Threaded + Method Delete() + Clear + End Method +? + Method Clear() + If _root=nil Return + _root.Clear + _root=nil + End Method + + Method IsEmpty() + Return _root=nil + End Method + + Method Insert( key:Object,value:Object ) + + Assert key Else "Can't insert Null key into map" + + Local node:TNode=_root,parent:TNode=nil,cmp + + While node<>nil + parent=node + cmp=key.Compare( node._key ) + If cmp>0 + node=node._right + Else If cmp<0 + node=node._left + Else + node._value=value + Return + EndIf + Wend + + node=New TNode + node._key=key + node._value=value + node._color=RED + node._parent=parent + + If parent=nil + _root=node + Return + EndIf + If cmp>0 + parent._right=node + Else + parent._left=node + EndIf + + _InsertFixup node + End Method + + Method Contains( key:Object ) + Return _FindNode( key )<>nil + End Method + + Method ValueForKey:Object( key:Object ) + Local node:TNode=_FindNode( key ) + If node<>nil Return node._value + End Method + + Method Remove( key:Object ) + Local node:TNode=_FindNode( key ) + If node=nil Return 0 + _RemoveNode node + Return 1 + End Method + + Method Keys:TMapEnumerator() + Local nodeenum:TNodeEnumerator=New TKeyEnumerator + nodeenum._node=_FirstNode() + Local mapenum:TMapEnumerator=New TMapEnumerator + mapenum._enumerator=nodeenum + Return mapenum + End Method + + Method Values:TMapEnumerator() + Local nodeenum:TNodeEnumerator=New TValueEnumerator + nodeenum._node=_FirstNode() + Local mapenum:TMapEnumerator=New TMapEnumerator + mapenum._enumerator=nodeenum + Return mapenum + End Method + + Method Copy:TMap() + Local map:TMap=New TMap + map._root=_root.Copy( nil ) + Return map + End Method + + Method ObjectEnumerator:TNodeEnumerator() + Local nodeenum:TNodeEnumerator=New TNodeEnumerator + nodeenum._node=_FirstNode() + Return nodeenum + End Method + + '***** PRIVATE ***** + + Method _FirstNode:TNode() + Local node:TNode=_root + While node._left<>nil + node=node._left + Wend + Return node + End Method + + Method _LastNode:TNode() + Local node:TNode=_root + While node._right<>nil + node=node._right + Wend + Return node + End Method + + Method _FindNode:TNode( key:Object ) + Local node:TNode=_root + While node<>nil + Local cmp=key.Compare( node._key ) + If cmp>0 + node=node._right + Else If cmp<0 + node=node._left + Else + Return node + EndIf + Wend + Return node + End Method + + Method _RemoveNode( node:TNode ) + Local splice:TNode,child:TNode + + If node._left=nil + splice=node + child=node._right + Else If node._right=nil + splice=node + child=node._left + Else + splice=node._left + While splice._right<>nil + splice=splice._right + Wend + child=splice._left + node._key=splice._key + node._value=splice._value + EndIf + Local parent:TNode=splice._parent + If child<>nil + child._parent=parent + EndIf + If parent=nil + _root=child + Return + EndIf + If splice=parent._left + parent._left=child + Else + parent._right=child + EndIf + + If splice._color=BLACK _DeleteFixup child,parent + End Method + + Method _InsertFixup( node:TNode ) + While node._parent._color=RED And node._parent._parent<>nil + If node._parent=node._parent._parent._left + Local uncle:TNode=node._parent._parent._right + If uncle._color=RED + node._parent._color=BLACK + uncle._color=BLACK + uncle._parent._color=RED + node=uncle._parent + Else + If node=node._parent._right + node=node._parent + _RotateLeft node + EndIf + node._parent._color=BLACK + node._parent._parent._color=RED + _RotateRight node._parent._parent + EndIf + Else + Local uncle:TNode=node._parent._parent._left + If uncle._color=RED + node._parent._color=BLACK + uncle._color=BLACK + uncle._parent._color=RED + node=uncle._parent + Else + If node=node._parent._left + node=node._parent + _RotateRight node + EndIf + node._parent._color=BLACK + node._parent._parent._color=RED + _RotateLeft node._parent._parent + EndIf + EndIf + Wend + _root._color=BLACK + End Method + + Method _RotateLeft( node:TNode ) + Local child:TNode=node._right + node._right=child._left + If child._left<>nil + child._left._parent=node + EndIf + child._parent=node._parent + If node._parent<>nil + If node=node._parent._left + node._parent._left=child + Else + node._parent._right=child + EndIf + Else + _root=child + EndIf + child._left=node + node._parent=child + End Method + + Method _RotateRight( node:TNode ) + Local child:TNode=node._left + node._left=child._right + If child._right<>nil + child._right._parent=node + EndIf + child._parent=node._parent + If node._parent<>nil + If node=node._parent._right + node._parent._right=child + Else + node._parent._left=child + EndIf + Else + _root=child + EndIf + child._right=node + node._parent=child + End Method + + Method _DeleteFixup( node:TNode,parent:TNode ) + + While node<>_root And node._color=BLACK + If node=parent._left + + Local sib:TNode=parent._right + + If sib._color=RED + sib._color=BLACK + parent._color=RED + _RotateLeft parent + sib=parent._right + EndIf + + If sib._left._color=BLACK And sib._right._color=BLACK + sib._color=RED + node=parent + parent=parent._parent + Else + If sib._right._color=BLACK + sib._left._color=BLACK + sib._color=RED + _RotateRight sib + sib=parent._right + EndIf + sib._color=parent._color + parent._color=BLACK + sib._right._color=BLACK + _RotateLeft parent + node=_root + EndIf + Else + Local sib:TNode=parent._left + + If sib._color=RED + sib._color=BLACK + parent._color=RED + _RotateRight parent + sib=parent._left + EndIf + + If sib._right._color=BLACK And sib._left._color=BLACK + sib._color=RED + node=parent + parent=parent._parent + Else + If sib._left._color=BLACK + sib._right._color=BLACK + sib._color=RED + _RotateLeft sib + sib=parent._left + EndIf + sib._color=parent._color + parent._color=BLACK + sib._left._color=BLACK + _RotateRight parent + node=_root + EndIf + EndIf + Wend + node._color=BLACK + End Method + + Const RED=-1,BLACK=1 + + Field _root:TNode=nil + +End Type + +Rem +bbdoc: Create a map +returns: A new map object +End Rem +Function CreateMap:TMap() + Return New TMap +End Function + +Rem +bbdoc: Clear a map +about: +#ClearMap removes all keys and values from @map +End Rem +Function ClearMap( map:TMap ) + map.Clear +End Function + +Rem +bbdoc: Check if a map is empty +returns: True if @map is empty, otherwise false +End Rem +Function MapIsEmpty( map:TMap ) + Return map.IsEmpty() +End Function + +Rem +bbdoc: Insert a key/value pair into a map +about: +If @map already contained @key, it's value is overwritten with @value. +End Rem +Function MapInsert( map:TMap,key:Object,value:Object ) + map.Insert key,value +End Function + +Rem +bbdoc: Find a value given a key +returns: The value associated with @key +about: +If @map does not contain @key, a #Null object is returned. +End Rem +Function MapValueForKey:Object( map:TMap,key:Object ) + Return map.ValueForKey( key ) +End Function + +Rem +bbdoc: Check if a map contains a key +returns: True if @map contains @key +End Rem +Function MapContains( map:TMap,key:Object ) + Return map.Contains( key ) +End Function + +Rem +bbdoc: Remove a key/value pair from a map +End Rem +Function MapRemove( map:TMap,key:Object ) + map.Remove key +End Function + +Rem +bbdoc: Get map keys +returns: An iterator object +about: +The object returned by #MapKeys can be used with #EachIn to iterate through +the keys in @map. +End Rem +Function MapKeys:TMapEnumerator( map:TMap ) + Return map.Keys() +End Function + +Rem +bbdoc: Get map values +returns: An iterator object +about: +The object returned by #MapValues can be used with #EachIn to iterate through +the values in @map. +End Rem +Function MapValues:TMapEnumerator( map:TMap ) + Return map.Values() +End Function + +Rem +bbdoc: Copy a map +returns: A copy of @map +End Rem +Function CopyMap:TMap( map:TMap ) + Return map.Copy() +End Function diff --git a/mod/brl.mod/math.mod/math.bmx b/mod/brl.mod/math.mod/math.bmx new file mode 100644 index 0000000..9a67900 --- /dev/null +++ b/mod/brl.mod/math.mod/math.bmx @@ -0,0 +1,114 @@ + +Strict + +Rem +bbdoc: Math/Math +End Rem +Module BRL.Math + +ModuleInfo "Version: 1.05" +ModuleInfo "Author: Mark Sibly" +ModuleInfo "License: zlib/libpng" +ModuleInfo "Copyright: Blitz Research Ltd" +ModuleInfo "Modserver: BRL" + +ModuleInfo "History: 1.05 Release" +ModuleInfo "History: Added IsNan and IsInf" + +Import "math.c" + +Extern + +Rem +bbdoc: Check if a value is NAN +returns: True if @x is 'not a number' (eg: Sqr(-1)) +End Rem +Function IsNan( x:Double )="bbIsNan" + +Rem +bbdoc: Check if a value is infinite (eg: 1.0/0.0) +returns: True if @x is infinite +End Rem +Function IsInf( x:Double )="bbIsInf" + +Rem +bbdoc: Square root of @x +End Rem +Function Sqr:Double( x:Double )="bbSqr" + +Rem +bbdoc: Sine of @x degrees +End Rem +Function Sin:Double( x:Double )="bbSin" + +Rem +bbdoc: Cosine of @x degrees +End Rem +Function Cos:Double( x:Double )="bbCos" + +Rem +bbdoc: Tangent of @x degrees +End Rem +Function Tan:Double( x:Double )="bbTan" + +Rem +bbdoc: Inverse Sine of @x +End Rem +Function ASin:Double( x:Double )="bbASin" + +Rem +bbdoc: Inverse Cosine of @x +End Rem +Function ACos:Double( x:Double )="bbACos" + +Rem +bbdoc: Inverse Tangent of @x +End Rem +Function ATan:Double( x:Double )="bbATan" + +Rem +bbdoc: Inverse Tangent of two variables @x , @y +End Rem +Function ATan2:Double( y:Double,x:Double )="bbATan2" + +Rem +bbdoc: Hyperbolic sine of @x +End Rem +Function Sinh:Double( x:Double )="bbSinh" + +Rem +bbdoc: Hyperbolic cosine of @x +End Rem +Function Cosh:Double( x:Double )="bbCosh" + +Rem +bbdoc: Hyperbolic tangent of @x +End Rem +Function Tanh:Double( x:Double )="bbTanh" + +Rem +bbdoc: Exponential function +end rem +Function Exp:Double( x:Double )="bbExp" + +Rem +bbdoc: Natural logarithm +End Rem +Function Log:Double( x:Double )="bbLog" + +Rem +bbdoc: Base 10 logarithm +End Rem +Function Log10:Double( x:Double )="bbLog10" + +Rem +bbdoc: Smallest integral value not less than @x +End Rem +Function Ceil:Double( x:Double )="bbCeil" + +Rem +bbdoc: Largest integral value not greater than @x +End Rem +Function Floor:Double( x:Double )="bbFloor" + +End Extern diff --git a/mod/brl.mod/math.mod/math.c b/mod/brl.mod/math.mod/math.c new file mode 100644 index 0000000..e0d8380 --- /dev/null +++ b/mod/brl.mod/math.mod/math.c @@ -0,0 +1,60 @@ + +#include + +#define RAD_TO_DEG 57.2957795130823208767981548141052 +#define DEG_TO_RAD 0.0174532925199432957692369076848861 + +int bbIsNan( double x ){ + return isnan(x) ? 1 : 0; +} +int bbIsInf( double x ){ + return isinf(x) ? 1 : 0; +} +double bbSqr( double x ){ + return sqrt( x ); +} +double bbSin( double x ){ + return sin( x*DEG_TO_RAD ); +} +double bbCos( double x ){ + return cos( x*DEG_TO_RAD ); +} +double bbTan( double x ){ + return tan( x*DEG_TO_RAD ); +} +double bbASin( double x ){ + return asin( x ) * RAD_TO_DEG; +} +double bbACos( double x ){ + return acos( x ) * RAD_TO_DEG; +} +double bbATan( double x ){ + return atan( x ) * RAD_TO_DEG; +} +double bbATan2( double y,double x ){ + return atan2( y,x ) * RAD_TO_DEG; +} +double bbSinh( double x ){ + return sinh( x ); +} +double bbCosh( double x ){ + return cosh( x ); +} +double bbTanh( double x ){ + return tanh( x ); +} +double bbExp( double x ){ + return exp( x ); +} +double bbFloor( double x ){ + return floor( x ); +} +double bbLog( double x ){ + return log(x); +} +double bbLog10( double x ){ + return log10(x); +} +double bbCeil( double x ){ + return ceil( x ); +} diff --git a/mod/brl.mod/max2d.mod/blitz.fon b/mod/brl.mod/max2d.mod/blitz.fon new file mode 100644 index 0000000000000000000000000000000000000000..ca5cd010243e301a05ebafc10e64955e121e5c73 GIT binary patch literal 4368 zcmds)d2Ae48Ni=C8~erCY&Pi@rs?4B4%+}BgpDbyb-Eqzx^alXN0KI#m?AbzW5?LF zT|32z6LuqtI9d=z+z1di0>oWGRBi#{3jghbJaZ=b@#@Lg$rF{7Yj#D&aUK_ zmKSH1kKdACK5^@9v&$z|^5e7N^5V+k^r`%fvkNybuCDCf+*gc3PmFA+HcbXJ+#WS1 zPW@z3Q>RpuKhi@a({6Lc!AYs!^OC<(+mu!Z)4R;Ij@q`X`&7y6I&T_P@BYb&Bl|`V z_Y9AX9+?`D#_iH{c;trso>FPoV445D!}GJJ*3fOAF3GKXev4AJefapwY?$A_xNs`} zABa+Ys=?nT8&s*gy2y63Drrvn^@jR^G0ZTG5i^#({BMtazr(m%-S24Co6;%=1=tPO z!T~r6Pk}`^2hW9p_5%xd;kAo+`30Q^}JP%$0 zZ-)25$KWD-8-5OdgszQRW#CG9C_Ea5VG?eFS$G=U4tK$;;cf5%_#}K8z6Za8Kf{JT zt+v5cunPuZKimKfxCPeW+3;d`9lR4h2%mwk!H?j#@Hg1FNvj9IgP{c1!DHb@xEXGR zCfo@xhd04{;iK>c_!j&O{s1b?eF59yA#e@UVFI2AC*d}D2D|`X1#gA-!zbWN@Ll*N z+y|-6T5W}XcsNvG1P;TKVII!Fv*1PWT6hQC1D}Sk!Vlp$@K?|otu6;29tl+#g~vk( zOYn5K16~Gig!jNl;PdcJ_$mAz)*-z`t1Dm!JPK+s4pZ@?z&-_(a*c43hH`mZ`~VfD zRW^u42XiNbO>+S=sZ=BE&3KiiP;O~enV+we&MqumD~jvttei#CZYdHstx9e>5|<~S zJ5_a?Zgt8GN^q^&vnI6dnvBzon%Wj~(dG0Izflt<2*a7Vl`srMaVr&5k?9tMjuSK* zjh1zDoQ&gGw^Z8OH8$2vr^V93r5Rg-5G9PFwH!N6!v>%=w#da$+y|>npq<3F;+l#i zPdD8o0Yn1+B9Uf{rZo&@AY~>b2CTDO>6}2d3;; zX|(&yM8%1JC$!xNt_d(?){2FdKH>EI>7~>2(k#~JH-lFMrRY@R;bE%lJT{oNDt157Y7)uE5s~HZ{yQ; z<0fve4@SF5#0?1~9kazyY}R&#luguej9ZfuqIT(1$wYlzx7ta^PIo&Rfur>ygjt}n ziG@=3I`b+CutqkAmfQ+vdSyZ?OBIfpb~!SX;vwR?UdH2SzoPb>ncN=*_F@q|zV`kP zmCo~(;x1ACcgmJ!iG^3672BXaKkwUnTe-!2wwleF{ZS8m-w({4jpM4{%JIf9>uY-3 zAWHT72M-jt_3b+?(R>@y9zB2j(4lePbWv`~D|(7sES9bQK7VVZ1npk|rorqoeU1qvzK6CAeIJzmFif?koXX_RJC*}EOl(owX!}91=jjeueHnzwrWb@3t zQdv#tT+R>tRelsD6`f011}74VuM!H=(Fs63SGYTO?>s#^DTAv1LJcYOr_x#7D&&jR zV!pssrIL!yB`m&5C|S+-t`RmxDyisP!s5$kaqOnlIloXiQz-c7lp36v@dpNW?%3fk zOQoJ)7m>1AsE(p@31x61q4?~Bb{{FI?&oyQHyiUo{>aGap+o*n5_;9FsBc3j6rD>b zK0Dcp$p9rMlZV3kx*!T~pK5n7JbaxfY^08&a|vZ|BB5|EwB2OC zwiSs{-Z*q%G=4+}^;)eSq5MB{W6#_1@8?kM!B$jqBQJf0FtE}`(1*|C)M zHQfP|YWk4%`~cOm`JxPB3zdqObu$^n3Vk{jlTK`rpPY*Q72iTb*N-1N-i$&|Gt3Ti kn-RLB5W1rft)t);EfMdZM&2xtT_M~$76~6o`v>ypywJNHY zMT_bjswPdPsHLN^nMaz;?A}VC*pm=brafxnnNat6wHMb6zFH?C-uT#^wPukmn|Vke zp)i|C+@Y>TYMsMH92Y)Lk$B=S=eT4DcweTct_iUwo2|{cXRiE#f=!@<&)|3b{NQAE z{%AwsXtb*OJ&RxZ&-ri1H~V%KqPUsEL2`b_JV3BSlKdNg!{zbB@9i>#NYucuBTP-m zPeyomOuF?|R-pfr8#rnoD8%IaIEn7BQi^)Sw8mj7iS7EDi^MgTV#$(1|I{3t00BhE z)a>KV^ONFzD8mo=wbFmC{4ebz_);j5JP7Bjj3t>U&=42>2khVQ^c`kxGWM4~BW36N zwHI;zMz9$6wSInYaV`6AJyw)yeG7i|KN$EaTW~(~%kAtxM0Fk80k97Iv5Yx{!TEK5 z;XB@V@AJJ0^naNBG3VbjLc-u%^gXlxgbpIq((Sy@yB(72pV13>=3}(-JNL!6V!n(P zmiI$rlfSw@&cDE8*Qm;>B6vT7hmRpf(;Dnm-WqPRv3o7yE>a=fr{Ax|xPva-FJpf* z+R^V9?{g{sc{M+Sxy8r}<>@qr@9Web@HA?`xi+|WI^+BQ!)lpYnm>*^pG1WJhtn8( SZ4EdtW4e65OZdNe*?}L)+Bv!a literal 0 HcmV?d00001 diff --git a/mod/brl.mod/max2d.mod/convfont.bmx b/mod/brl.mod/max2d.mod/convfont.bmx new file mode 100644 index 0000000..0329b33 --- /dev/null +++ b/mod/brl.mod/max2d.mod/convfont.bmx @@ -0,0 +1,33 @@ + +Strict + +Graphics 1024,768 + +Local font:TImageFont=LoadImageFont( "blitz.fon",14 ) +If Not font End + +SetImageFont font + +For Local x=0 Until 96 + DrawText Chr(x+32),x*8,0 +Next + +Local pixmap:TPixmap=GrabPixmap( 0,0,96*8,16 ) + +Local out:TStream=WriteStream( "blitzfont.bin" ) + +For Local y=0 Until 16 + For Local x=0 Until 96 + Local b + For Local n=0 Until 8 + If ReadPixel( pixmap,x*8+n,y ) & $ff + b:|(1 Shl n) + EndIf + Next + WriteByte out,b + Next +Next + +CloseStream out + + diff --git a/mod/brl.mod/max2d.mod/doc/bullet.png b/mod/brl.mod/max2d.mod/doc/bullet.png new file mode 100644 index 0000000000000000000000000000000000000000..f45d3aed3d87cf9bc15159f1be4e1503ffb63cac GIT binary patch literal 332 zcmV-S0ki&zP)%xKL7v#{z*hZRCt`dk)c+^Fc3xWb`7#3A~FI|xdMS4v7(=Vj6~)W_7f^A zE0Gb1$`O1(MdgafNF)*wy6o8&a6Fas=FXcr6WEg9bYZ`V7JB-V_V5S~@BwDka7))B z#{0uCyw&vtDWxBlTC#gc&~I(OolOYmrdelKzYSXH-)IrJDX*RHLX1&FKw^v_SI(FA z7c_*BbDrnfd$HCw&0R{#Id?oBbI#>B)is)PF3nxnl}9l{2xY?V8dcRN)poh@=-i8l zh*)c_wO!X$mjG2&)fUhbfSy_?=4I^OIcJP1F3`YzoH)GWhY? +
+Before using any of the Max2D commands, you must first create a Max2D graphics +object. The easiest way to do this is using the #Graphics command.
+
+By default, Max2D is double buffered which means you will have to use +#Flip once you have finished drawing each frame of graphics.
+
+

Drawing

+Max2D provides support for the following drawing commands:
+
+ + + + + + + + + + + +
Drawing commandAction
ClsClears the viewport
PlotDraws a single pixel
DrawLineDraws a line
DrawRectDraws a rectangle
DrawOvalDraws an oval
DrawPolyDraws a polygon
DrawTextDraws some text
DrawImageDraws an image
DrawPixmapDraws a pixmap
+
+

Viewport, origin and handle

+Drawing commands are clipped to a rectangular area known as the viewport. Only the area within the viewport is ever modified, and attempting to draw outside the viewport will result in the drawing command being clipped or chopped to the viewport. To set the viewport, use the SetViewport command.
+
+Drawing commands are also offset by the current origin and handle. To set these properties, use the SetOrigin and SetHandle commands.
+
+The current handle is an x,y coordinate subtracted from all drawing x,y coordinates before any rotation or scaling occurs. This allows you to provide a local 'center' for drawing. On the other hand, the current origin is an x,y coordinate added to all drawing x,y coordinates after any rotation or scaling.
+
+

Color, alpha and blend mode

+Drawing commands are affected by the current color, alpha and blend mode. You can set these properties by using the SetColor, SetAlpha and SetBlend commands.
+
+The current alpha value controls the transparency level when using the ALPHABLEND blend mode.
+
+The current blend mode controls how pixels are combined with existing pixels in the back buffer and can be one of the following:
+
+ + + + + + + +
Blend modeEffect
SOLIDBLENDPixels overwrite existing backbuffer pixels
MASKBLENDPixels are drawn only if their alpha component is greater than .5
ALPHABLENDPixels are alpha blended with existing backbuffer pixels
LIGHTBLENDPixel colors are added to backbuffer pixel colors, giving a 'lighting' effect
SHADEBLENDPixel colors are multiplied with backbuffer pixel colors, giving a 'shading' effect
+
+

Rotation and scale

+Drawing commands can be scaled and rotated using the SetScale and SetRotation commands. Rotation and scaling occur relative to the current handle.
+
+

Images

+Images are pre-rendered chunks of graphics that can be efficiently drawn using a single DrawImage command. Images are typically stored in png, bmp or jpg format, and can be loaded using the LoadImage command.
+
+Image drawing is also affected by color, alpha, blend, rotation and scale. The current color is multiplied with each pixel color before the image is drawn to the backbuffer, allowing you to tint images. To disable this effect, you should set the current color to white.
+
+Images can also have a mask color. This is the color that represents transparency when an image is drawn using the MASKBLEND blend mode. To set the mask color, use the SetMaskColor command.
+
+Images can be created by snapshotting regions of the back buffer using the GrabImage command. +

Pixmaps

+Pixmaps are used to manipulate images at a pixel level, see the #pixmaps module for details.

+ +LockImage allows for direct Image pixel access and requires a corresponding call to +UnlockImage when you have have finished reading or modifying the pixels. +The DrawPixmap and GrabPixmap +commands allow you to move pixels to and from the current graphic display's backbuffer. +

Collisions

+Max2D features a multilayered pixel perfect collision system. +The CollideRect and +CollideImage commands +provide a dual function allowing the drawing and hit testing of Rects and +Images with any combination of 32 collision layers.

+The current Scale, Rotation, Origin and Handle settings are taken into account +so coordinates for the collision commands acurately match their drawing counterparts +DrawRect and DrawImage.

+ResetCollisions is used +to clear any or all of the 32 collision layers provided.
+
+ diff --git a/mod/brl.mod/max2d.mod/doc/plot.bmx b/mod/brl.mod/max2d.mod/doc/plot.bmx new file mode 100644 index 0000000..fa4f095 --- /dev/null +++ b/mod/brl.mod/max2d.mod/doc/plot.bmx @@ -0,0 +1,17 @@ +' plot.bmx + +' plots a cosine graph +' scrolls along the graph using an incrementing frame variable + +Graphics 640,480 + +While Not KeyHit(KEY_ESCAPE) + Cls + For x=0 To 640 + theta=x+frame + y=240-Cos(theta)*240 + Plot x,y + Next + frame=frame+1 + Flip +Wend diff --git a/mod/brl.mod/max2d.mod/driver.bmx b/mod/brl.mod/max2d.mod/driver.bmx new file mode 100644 index 0000000..6eb7aed --- /dev/null +++ b/mod/brl.mod/max2d.mod/driver.bmx @@ -0,0 +1,53 @@ + +Strict + +Import BRL.Pixmap +Import BRL.Graphics + +'modes for SetBlend +Const MASKBLEND=1 +Const SOLIDBLEND=2 +Const ALPHABLEND=3 +Const LIGHTBLEND=4 +Const SHADEBLEND=5 + +'flags for frames/images +Const MASKEDIMAGE= $1 +Const FILTEREDIMAGE= $2 +Const MIPMAPPEDIMAGE= $4 +Const DYNAMICIMAGE= $8 + +'current driver +Global _max2dDriver:TMax2DDriver + +Type TImageFrame + + Method Draw( x0#,y0#,x1#,y1#,tx#,ty#,sx#,sy#,sw#,sh# ) Abstract + +End Type + +Type TMax2DDriver Extends TGraphicsDriver + + Method CreateFrameFromPixmap:TImageFrame( pixmap:TPixmap,flags ) Abstract + + Method SetBlend( blend ) Abstract + Method SetAlpha( alpha# ) Abstract + Method SetColor( red,green,blue ) Abstract + Method SetClsColor( red,green,blue ) Abstract + Method SetViewport( x,y,width,height ) Abstract + Method SetTransform( xx#,xy#,yx#,yy# ) Abstract + Method SetLineWidth( width# ) Abstract + + Method Cls() Abstract + Method Plot( x#,y# ) Abstract + Method DrawLine( x0#,y0#,x1#,y1#,tx#,ty# ) Abstract + Method DrawRect( x0#,y0#,x1#,y1#,tx#,ty# ) Abstract + Method DrawOval( x0#,y0#,x1#,y1#,tx#,ty# ) Abstract + Method DrawPoly( xy#[],handlex#,handley#,originx#,originy# ) Abstract + + Method DrawPixmap( pixmap:TPixmap,x,y ) Abstract + Method GrabPixmap:TPixmap( x,y,width,height ) Abstract + + Method SetResolution( width#,height# ) Abstract + +End Type diff --git a/mod/brl.mod/max2d.mod/image.bmx b/mod/brl.mod/max2d.mod/image.bmx new file mode 100644 index 0000000..e8bdbea --- /dev/null +++ b/mod/brl.mod/max2d.mod/image.bmx @@ -0,0 +1,92 @@ + +Strict + +Import "driver.bmx" + +Rem +bbdoc: Max2D Image type +End Rem +Type TImage + + Field width,height,flags + Field mask_r,mask_g,mask_b + Field handle_x#,handle_y# + Field pixmaps:TPixmap[] + + Field frames:TImageFrame[] + Field seqs[] + + Method _pad() + End Method + + Method Frame:TImageFrame( index ) + If seqs[index]=GraphicsSeq Return frames[index] + frames[index]=_max2dDriver.CreateFrameFromPixmap( Lock(index,True,False),flags ) + If frames[index] seqs[index]=GraphicsSeq Else seqs[index]=0 + Return frames[index] + End Method + + Method Lock:TPixmap( index,read,write ) + If write + seqs[index]=0 + frames[index]=Null + EndIf + If Not pixmaps[index] + pixmaps[index]=CreatePixmap( width,height,PF_RGBA8888 ) + EndIf + Return pixmaps[index] + End Method + + Method SetPixmap( index,pixmap:TPixmap ) + If (flags & MASKEDIMAGE) And AlphaBitsPerPixel[pixmap.format]=0 + pixmap=MaskPixmap( pixmap,mask_r,mask_g,mask_b ) + EndIf + pixmaps[index]=pixmap + seqs[index]=0 + frames[index]=Null + End Method + + Function Create:TImage( width,height,frames,flags,mr,mg,mb ) + Local t:TImage=New TImage + t.width=width + t.height=height + t.flags=flags + t.mask_r=mr + t.mask_g=mg + t.mask_b=mb + t.pixmaps=New TPixmap[frames] + t.frames=New TImageFrame[frames] + t.seqs=New Int[frames] + Return t + End Function + + Function Load:TImage( url:Object,flags,mr,mg,mb ) + Local pixmap:TPixmap=TPixmap(url) + If Not pixmap pixmap=LoadPixmap(url) + If Not pixmap Return + Local t:TImage=Create( pixmap.width,pixmap.height,1,flags,mr,mg,mb ) + t.SetPixmap 0,pixmap + Return t + End Function + + Function LoadAnim:TImage( url:Object,cell_width,cell_height,first,count,flags,mr,mg,mb ) + Local pixmap:TPixmap=TPixmap(url) + If Not pixmap pixmap=LoadPixmap(url) + If Not pixmap Return + + Local x_cells=pixmap.width/cell_width + Local y_cells=pixmap.height/cell_height + If first+count>x_cells*y_cells Return + + Local t:TImage=Create( cell_width,cell_height,count,flags,mr,mg,mb ) + + For Local cell=first To first+count-1 + Local x=cell Mod x_cells * cell_width + Local y=cell / x_cells * cell_height + Local window:TPixmap=pixmap.Window( x,y,cell_width,cell_height ) + t.SetPixmap cell-first,window.Copy() + Next + Return t + End Function + +End Type diff --git a/mod/brl.mod/max2d.mod/imagefont.bmx b/mod/brl.mod/max2d.mod/imagefont.bmx new file mode 100644 index 0000000..1477d25 --- /dev/null +++ b/mod/brl.mod/max2d.mod/imagefont.bmx @@ -0,0 +1,156 @@ + +Strict + +Import BRL.Font + +Import "image.bmx" + +Incbin "blitzfont.bin" + +Type TImageGlyph + + Field _image:TImage + Field _advance#,_x,_y,_w,_h + + Method Pixels:TImage() + Return _image + End Method + + Method Advance#() + Return _advance + End Method + + Method GetRect( x Var,y Var,w Var,h Var ) + x=_x + y=_y + w=_w + h=_h + End Method + +End Type + +Type TImageFont + + Field _src_font:TFont + Field _glyphs:TImageGlyph[] + Field _imageFlags + + Method Style() + If _src_font Return _src_font.Style() + Return 0 + End Method + + Method Height() + If _src_font Return _src_font.Height() + Return 16 + End Method + + Method CountGlyphs() + Return _glyphs.length + End Method + + Method CharToGlyph( char ) + If _src_font Return _src_font.CharToGlyph( char ) + If char>=32 And char<128 Return char-32 + Return -1 + End Method + + Method LoadGlyph:TImageGlyph( index ) + + Assert index>=0 And index<_glyphs.length + + Local glyph:TImageGlyph=_glyphs[index] + If glyph Return glyph + + glyph:TImageGlyph=New TImageGlyph + _glyphs[index]=glyph + + Local src_glyph:TGlyph=_src_font.LoadGlyph( index ) + + glyph._advance=src_glyph.Advance() + src_glyph.GetRect glyph._x,glyph._y,glyph._w,glyph._h + + Local pixmap:TPixmap=TPixmap( src_glyph.Pixels() ) + If Not pixmap Return glyph + + glyph._image=TImage.Load( pixmap.Copy(),_imageFlags,0,0,0 ) + + Return glyph + + End Method + + Method Draw( text$,x#,y#,ix#,iy#,jx#,jy# ) + + For Local i=0 Until text.length + + Local n=CharToGlyph( text[i] ) + If n<0 Continue + + Local glyph:TImageGlyph=LoadGlyph(n) + Local image:TImage=glyph._image + + If image + Local frame:TImageFrame=image.Frame(0) + If frame + Local tx#=glyph._x*ix+glyph._y*iy + Local ty#=glyph._x*jx+glyph._y*jy + frame.Draw 0,0,image.width,image.height,x+tx,y+ty,0,0,image.width,image.height + EndIf + EndIf + + x:+glyph._advance*ix + y:+glyph._advance*jx + Next + + End Method + + Function Load:TImageFont( url:Object,size,style ) + + Local src:TFont=LoadFont( url,size,style ) + If Not src Return + + Local font:TImageFont=New TImageFont + font._src_font=src + font._glyphs=New TImageGlyph[src.CountGlyphs()] + If style & SMOOTHFONT font._imageFlags=FILTEREDIMAGE|MIPMAPPEDIMAGE + + Return font + + End Function + + Function CreateDefault:TImageFont() + + Local font:TImageFont=New TImageFont + font._glyphs=New TImageGlyph[96] + + Local pixmap:TPixmap=TPixmap.Create( 96*8,16,PF_RGBA8888 ) + + Local p:Byte Ptr=IncbinPtr( "blitzfont.bin" ) + + For Local y=0 Until 16 + For Local x=0 Until 96 + Local b=p[x] + For Local n=0 Until 8 + If b & (1 Shl n) + pixmap.WritePixel x*8+n,y,~0 + Else + pixmap.WritePixel x*8+n,y,0 + EndIf + Next + Next + p:+96 + Next + + For Local n=0 Until 96 + Local glyph:TImageGlyph=New TImageGlyph + font._glyphs[n]=glyph + glyph._advance=8 + glyph._w=8 + glyph._h=16 + glyph._image=TImage.Load( pixmap.Window(n*8,0,8,16).Copy(),0,0,0,0 ) + Next + + Return font + End Function + +End Type diff --git a/mod/brl.mod/max2d.mod/max2d.bmx b/mod/brl.mod/max2d.mod/max2d.bmx new file mode 100644 index 0000000..21de592 --- /dev/null +++ b/mod/brl.mod/max2d.mod/max2d.bmx @@ -0,0 +1,1562 @@ + +Strict + +Rem +bbdoc: Graphics/Max2D +End Rem +Module BRL.Max2D + +ModuleInfo "Version: 1.22" +ModuleInfo "Author: Mark Sibly, Simon Armstrong" +ModuleInfo "License: zlib/libpng" +ModuleInfo "Copyright: Blitz Research Ltd" +ModuleInfo "Modserver: BRL" + +ModuleInfo "History: 1.22 Release" +ModuleInfo "History: fixed ResetCollision not resetting recycled collision quads" +ModuleInfo "History: 1.21 Release" +ModuleInfo "History: makecurrent now does validate before initial cls" +ModuleInfo "History: 1.20 Release" +ModuleInfo "History: Fixed TImageFont.Draw so it uses float translation" +ModuleInfo "History: 1.19 Release" +ModuleInfo "History: Fixed collision bug with non alpha/masked images" +ModuleInfo "History: 1.18 Release" +ModuleInfo "History: Add Flip Hook and polledinput" +ModuleInfo "History: 1.17 Release" +ModuleInfo "History: Added MIPMAPPEDIMAGE to smooth fonts" +ModuleInfo "History: Fixed ImageFont TImage.Load parameters in wrong order!" +ModuleInfo "History: 1.16 Release" +ModuleInfo "History: Improved ImageFont unicode support" +ModuleInfo "History: 1.15 Release" +ModuleInfo "History: Added OnEnd EndGraphics" +ModuleInfo "History: 1.14 Release" +ModuleInfo "History: CreateImage/LockImage now always returns RGBA8888 pixmap" +ModuleInfo "History: Fixed multiple Graphics calls crashing due to using Flip before DetectSync" +ModuleInfo "History: 1.13 Release" +ModuleInfo "History: LoadImageFont generates filteredimage images only for smoothfont fonts" +ModuleInfo "History: 1.12 Release" +ModuleInfo "History: Added MIPMAPPEDIMAGE flag" +ModuleInfo "History: 1.11 Release" +ModuleInfo "History: Fixed Garbage at graphics startup" +ModuleInfo "History: 1.10 Release" +ModuleInfo "History: Fixed LockImage bug" +ModuleInfo "History: 1.09 Release" +ModuleInfo "History: Integrated with new graphics system" +ModuleInfo "History: ImageFrames now lazily evaluated" +ModuleInfo "History: Fixed GetMaskColor" +ModuleInfo "History: 1.08 Release" +ModuleInfo "History: Collision system optimized" +ModuleInfo "History: Graphics now does an EndGraphics first" +ModuleInfo "History: 1.07 Release" +ModuleInfo "History: 1.06 Release" +ModuleInfo "History: Added GetLineWidth#()" +ModuleInfo "History: Added GetClsColor( red Var,green Var,blue Var )" +ModuleInfo "History: Fixed Object reference bug in Collision system" +ModuleInfo "History: 1.05 Release" +ModuleInfo "History: Fixed AnimImage collisions" +ModuleInfo "History: Fixed ImagesCollide/ImagesCollide2 parameter types" + +Import BRL.PolledInput +Import BRL.LinkedList +Import BRL.Hook + +Import "image.bmx" +Import "driver.bmx" +Import "imagefont.bmx" + +Private + +Global gc:TMax2DGraphics + +Function UpdateTransform() + Local s#=Sin(gc.tform_rot) + Local c#=Cos(gc.tform_rot) + gc.tform_ix= c*gc.tform_scale_x + gc.tform_iy=-s*gc.tform_scale_y + gc.tform_jx= s*gc.tform_scale_x + gc.tform_jy= c*gc.tform_scale_y + _max2dDriver.SetTransform gc.tform_ix,gc.tform_iy,gc.tform_jx,gc.tform_jy + SetCollisions2DTransform gc.tform_ix,gc.tform_iy,gc.tform_jx,gc.tform_jy +End Function + +Public + +Type TMax2DGraphics Extends TGraphics + + Field color_red,color_green,color_blue + Field color_alpha# + Field clscolor_red,clscolor_green,clscolor_blue + Field line_width# + Field tform_rot#,tform_scale_x#,tform_scale_y# + Field tform_ix#,tform_iy#,tform_jx#,tform_jy# + Field viewport_x,viewport_y,viewport_w,viewport_h + Field origin_x#,origin_y# + Field handle_x#,handle_y# + Field image_font:TImageFont + Field blend_mode + Field vres_width#,vres_height# + Field vres_mousexscale#,vres_mouseyscale# + + Field g_width,g_height + + Global default_font:TImageFont + Global mask_red,mask_green,mask_blue + Global auto_midhandle + Global auto_imageflags=MASKEDIMAGE|FILTEREDIMAGE + + Field _graphics:TGraphics,_driver:TMax2DDriver,_setup + + Method Driver:TMax2DDriver() + Return _driver + End Method + + Method GetSettings( width Var,height Var,depth Var,hertz Var,flags Var ) + Local w,h,d,r,f + _graphics.GetSettings w,h,d,r,f + width=w + height=h + depth=d + hertz=r + flags=f + End Method + + Method Close() + If Not _graphics Return + _graphics.Close + _graphics=Null + _driver=Null + End Method + + Method Validate() + Local w,h,d,r,f + _graphics.GetSettings w,h,d,r,f + If w<>g_width Or h<>g_height + g_width=w + g_height=h + vres_width=w + vres_height=h + vres_mousexscale=1 + vres_mouseyscale=1 + EndIf + SetVirtualResolution vres_width,vres_height + SetBlend blend_mode + SetColor color_red,color_green,color_blue + SetAlpha color_alpha + SetClsColor clscolor_red,clscolor_green,clscolor_blue + SetLineWidth line_width + SetRotation tform_rot + SetScale tform_scale_x,tform_scale_y + SetViewport viewport_x,viewport_y,viewport_w,viewport_h + SetOrigin origin_x,origin_y + SetHandle -handle_x,-handle_y + SetImageFont image_font + End Method + + Method MakeCurrent() + gc=Self + _max2dDriver=TMax2DDriver( Driver() ) + Assert _max2dDriver + Validate + If _setup Return + Cls + Flip 0 + Cls + Flip 0 + _setup=True + End Method + + Function ClearCurrent() + gc=Null + _max2dDriver=Null + End Function + + Function Current:TMax2DGraphics() + Return gc + End Function + + Function Create:TMax2DGraphics( g:TGraphics,d:TMax2DDriver ) + Local gw,gh,gd,gr,gf + g.GetSettings gw,gh,gd,gr,gf + + If Not default_font default_font=TImageFont.CreateDefault() + + Local t:TMax2DGraphics=New TMax2DGraphics + + t.g_width=gw + t.g_height=gh + t.blend_mode=MASKBLEND + t.color_red=255 + t.color_green=255 + t.color_blue=255 + t.color_alpha=1 + t.clscolor_red=0 + t.clscolor_green=0 + t.clscolor_blue=0 + t.line_width=1 + t.tform_rot=0 + t.tform_scale_x=1 + t.tform_scale_y=1 + t.tform_ix=1 + t.tform_iy=0 + t.tform_jx=1 + t.tform_jy=0 + t.viewport_x=0 + t.viewport_y=0 + t.viewport_w=gw + t.viewport_h=gh + t.origin_x=0 + t.origin_y=0 + t.handle_x=0 + t.handle_y=0 + t.image_font=default_font + t.vres_width=gw + t.vres_height=gh + t.vres_mousexscale=1 + t.vres_mouseyscale=1 + + t._graphics=g + t._driver=d + t._setup=False + + Return t + End Function + +End Type + +Rem +bbdoc: Clear graphics buffer +about: +Clears the graphics buffer to the current cls color as determined by #SetClsColor. +End Rem +Function Cls() + _max2dDriver.Cls +End Function + +Rem +bbdoc: Set current #Cls color +about: +The @red, @green and @blue parameters should be in the range of 0 to 255. + +The default cls color is black. +End Rem +Function SetClsColor( red,green,blue ) + gc.clscolor_red=red + gc.clscolor_green=green + gc.clscolor_blue=blue + _max2dDriver.SetClsColor red,green,blue +End Function + +Rem +bbdoc: Get red, green and blue component of current cls color. +returns: Red, green and blue values in the range 0..255 in the variables supplied. +End Rem +Function GetClsColor( red Var,green Var,blue Var ) + red=gc.clscolor_red + green=gc.clscolor_green + blue=gc.clscolor_blue +End Function + +Rem +bbdoc: Plot a pixel +about: +Sets the color of a single pixel on the back buffer to the current drawing color +defined with the #SetColor command. Other commands that affect the operation of +#Plot include #SetOrigin, #SetViewPort, #SetBlend and #SetAlpha. +End Rem +Function Plot( x#,y# ) + _max2dDriver.Plot x+gc.origin_x,y+gc.origin_y +End Function + +Rem +bbdoc: Draw a rectangle +about: +Sets the color of a rectangular area of pixels using the current drawing color +defined with the #SetColor command. + +Other commands that affect the operation of #DrawRect include #SetHandle, #SetScale, +#SetRotation, #SetOrigin, #SetViewPort, #SetBlend and #SetAlpha. +End Rem +Function DrawRect( x#,y#,width#,height# ) + _max2dDriver.DrawRect.. + gc.handle_x,gc.handle_y,.. + gc.handle_x+width,gc.handle_y+height,.. + x+gc.origin_x,y+gc.origin_y +End Function + +Rem +bbdoc: Draw a line +about: +#DrawLine draws a line from @x, @y to @x2, @y2 with the current drawing color. + +BlitzMax commands that affect the drawing of lines include #SetLineWidth, #SetColor, #SetHandle, +#SetScale, #SetRotation, #SetOrigin, #SetViewPort, #SetBlend and #SetAlpha. +The optional @draw_last_pixel parameter can be used to control whether the last pixel of the line is drawn or not. +Not drawing the last pixel can be useful if you are using certain blending modes. +End Rem +Function DrawLine( x#,y#,x2#,y2#,draw_last_pixel=True ) + _max2dDriver.DrawLine.. + gc.handle_x,gc.handle_y,.. + gc.handle_x+x2-x,gc.handle_y+y2-y,.. + x+gc.origin_x,y+gc.origin_y + If Not draw_last_pixel Return + Local px#=gc.handle_x+x2-x,py#=gc.handle_y+y2-y + _max2dDriver.Plot.. + px*gc.tform_ix+py*gc.tform_iy+x+gc.origin_x,px*gc.tform_jx+py*gc.tform_jy+y+gc.origin_y +End Function + +Rem +bbdoc: Draw an oval +about: +#DrawOval draws an oval that fits in the rectangular area defined by @x, @y, @width +and @height parameters. + +BlitzMax commands that affect the drawing of ovals include #SetColor, #SetHandle, +#SetScale, #SetRotation, #SetOrigin, #SetViewPort, #SetBlend and #SetAlpha. +End Rem +Function DrawOval( x#,y#,width#,height# ) + _max2dDriver.DrawOval.. + gc.handle_x,gc.handle_y,.. + gc.handle_x+width,gc.handle_y+height,.. + x+gc.origin_x,y+gc.origin_y +End Function + +Rem +bbdoc: Draw a polygon +about: +#DrawPoly draws a polygon with corners defined by an array of x#,y# coordinate pairs. + +BlitzMax commands that affect the drawing of polygons include #SetColor, #SetHandle, +#SetScale, #SetRotation, #SetOrigin, #SetViewPort, #SetBlend and #SetAlpha. +End Rem +Function DrawPoly( xy#[] ) + _max2dDriver.DrawPoly xy,.. + gc.handle_x,gc.handle_y,.. + gc.origin_x,gc.origin_y +End Function + +Rem +bbdoc: Draw text +about: +#DrawText prints strings at position @x,@y of the graphics display using +the current image font specified by the #SetImageFont command. + +Other commands that affect #DrawText include #SetColor, #SetHandle, +#SetScale, #SetRotation, #SetOrigin, #SetViewPort, #SetBlend and #SetAlpha. + +It is recomended that the blend mode be set to ALPHABLEND using the #SetBlend +command for non jagged antialiased text. Text that will be drawn at a smaller +size using the #SetScale command should use fonts loaded with the SMOOTHFONT +style to benefit from mip-mapped filtering, see #LoadImageFont for more information. +End Rem +Function DrawText( t$,x#,y# ) + gc.image_font.Draw t,.. + x+gc.origin_x+gc.handle_x*gc.tform_ix+gc.handle_y*gc.tform_iy,.. + y+gc.origin_y+gc.handle_x*gc.tform_jx+gc.handle_y*gc.tform_jy,.. + gc.tform_ix,gc.tform_iy,gc.tform_jx,gc.tform_jy +End Function + +Rem +bbdoc: Draw an image to the back buffer +about: +Drawing is affected by the current blend mode, color, scale and rotation. + +If the blend mode is ALPHABLEND the image is affected by the current alpha value +and images with alpha channels are blended correctly with the background. +End Rem +Function DrawImage( image:TImage,x#,y#,frame=0 ) + Local x0#=-image.handle_x,x1#=x0+image.width + Local y0#=-image.handle_y,y1#=y0+image.height + Local iframe:TImageFrame=image.Frame(frame) + If iframe iframe.Draw x0,y0,x1,y1,x+gc.origin_x,y+gc.origin_y,0,0,image.width,image.height +End Function + +Rem +bbdoc: Draw an image to a rectangular area of the back buffer +about: +@x, @y, @w and @h specify the destination rectangle to draw to. + +@frame is the image frame to draw. + +Drawing is affected by the current blend mode, color, scale and rotation. + +If the blend mode is ALPHABLEND, then the image is also affected by the current alpha value. +End Rem +Function DrawImageRect( image:TImage,x#,y#,w#,h#,frame=0 ) + Local x0#=-image.handle_x,x1#=x0+w + Local y0#=-image.handle_y,y1#=y0+h + Local iframe:TImageFrame=image.Frame(frame) + If iframe iframe.Draw x0,y0,x1,y1,x+gc.origin_x,y+gc.origin_y,0,0,image.width,image.height +End Function + +Rem +bbdoc: Draw a sub rectangle of an image to a rectangular area of the back buffer +about: +@x, @y, @w and @h specify the destination rectangle to draw to. + +@sx, @sy, @sw and @sh specify the source rectangle within the image to draw from. + +@hx and @hy specify a handle offset within the source rectangle. + +@frame is the image frame to draw. + +Drawing is affected by the current blend mode, color, scale and rotation. + +If the blend mode is ALPHABLEND, then the image is also affected by the current alpha value. +End Rem +Function DrawSubImageRect( image:TImage,x#,y#,w#,h#,sx#,sy#,sw#,sh#,hx#=0,hy#=0,frame=0 ) + Local x0#=-hx*w/sw,x1#=x0+w + Local y0#=-hy*h/sh,y1#=y0+h + Local iframe:TImageFrame=image.Frame(frame) + If iframe iframe.Draw x0,y0,x1,y1,x+gc.origin_x,y+gc.origin_y,sx,sy,sw,sh +End Function + +Rem +bbdoc: Draw an image in a tiled pattern +about: +#TileImage draws an image in a repeating, tiled pattern, filling the current viewport. +End Rem +Function TileImage( image:TImage,x#=0#,y#=0#,frame=0 ) + Local iframe:TImageFrame=image.Frame(frame) + If Not iframe Return + + _max2dDriver.SetTransform 1,0,0,1 + + Local w=image.width + Local h=image.height + Local ox=gc.viewport_x-w+1 + Local oy=gc.viewport_y-h+1 + Local px#=x+gc.origin_x-image.handle_x + Local py#=y+gc.origin_y-image.handle_y + Local fx#=px-Floor(px) + Local fy#=py-Floor(py) + Local tx=Floor(px)-ox + Local ty=Floor(py)-oy + + If tx>=0 tx=tx Mod w + ox Else tx=w - -tx Mod w + ox + If ty>=0 ty=ty Mod h + oy Else ty=h - -ty Mod h + oy + + Local vr=gc.viewport_x+gc.viewport_w,vb=gc.viewport_y+gc.viewport_h + + Local iy=ty + While iy=image_font.CountGlyphs() Continue + Local x,y,w,h + image_font.Glyph(c).GetRect( x,y,w,h ) + height=Max(height,h) + Next + Return height + End Rem +End Function + +Rem +bbdoc: Load an image +returns: A new image object +about: +@url can be either a string or an existing pixmap. + +@flags can be 0, -1 or any combination of: + +[ @{Flags value} | @{Effect} + +* MASKEDIMAGE | The image is masked with the current mask color. + +* FILTEREDIMAGE | The image is smoothed when scaled up to greater than its original +size, when rotated, or when drawn at fractional pixel coordinates. + +* MIPMAPPEDIMAGE | The image is smoothed when scaled down to less than its original size. + +* DYNAMICIMAGE | The image can be modified using #LockImage or #GrabImage. +] + + +Note MIPMAPPEDIMAGE images consume extra video memory, so this flag should only be used +when really necessary. + +If flags is -1, the auto image flags are used: See #AutoImageFlags. + +To combine flags, use the | (boolean OR) operator. +End Rem +Function LoadImage:TImage( url:Object,flags=-1 ) + If flags=-1 flags=gc.auto_imageflags + Local image:TImage=TImage.Load( url,flags,gc.mask_red,gc.mask_green,gc.mask_blue ) + If Not image Return + If gc.auto_midhandle MidHandleImage image + Return image +End Function + +Rem +bbdoc: Load a multi-frame image +returns: An image object +about: +#LoadAnimImage extracts multiple image frames from a single, larger image. @url can be either a string or an +existing pixmap. + +See #LoadImage for valid @flags values. +End Rem +Function LoadAnimImage:TImage( url:Object,cell_width,cell_height,first_cell,cell_count,flags=-1 ) + If flags=-1 flags=gc.auto_imageflags + Local image:TImage=TImage.LoadAnim( url,cell_width,cell_height,first_cell,cell_count,flags,gc.mask_red,gc.mask_green,gc.mask_blue ) + If Not image Return + If gc.auto_midhandle MidHandleImage image + Return image +End Function + +Rem +bbdoc: Set an image's handle to an arbitrary point +about: +An image's handle is subtracted from the coordinates of #DrawImage before +rotation and scale are applied. +End Rem +Function SetImageHandle( image:TImage,x#,y# ) + image.handle_x=x + image.handle_y=y +End Function + +Rem +bbdoc: Enable or disable auto midhandle mode +about: +When auto midhandle mode is enabled, all images are automatically 'midhandled' (see #MidHandleImage) +when they are created. If auto midhandle mode is disabled, images are handled by their top left corner. + +AutoMidHandle defaults to False after calling #Graphics. +End Rem +Function AutoMidHandle( enable ) + gc.auto_midhandle=enable +End Function + +Rem +bbdoc: Set auto image flags +about: +The auto image flags are used by #LoadImage and #CreateImage when no image +flags are specified. See #LoadImage for a full list of valid image flags. +AutoImageFlags defaults to MASKEDIMAGE | FILTEREDIMAGE. +End Rem +Function AutoImageFlags( flags ) + If flags=-1 Return + gc.auto_imageflags=flags +End Function + +Rem +bbdoc: Set an image's handle to its center +End Rem +Function MidHandleImage( image:TImage ) + image.handle_x=image.width*.5 + image.handle_y=image.height*.5 +End Function + +Rem +bbdoc: Get width of an image +returns: The width, in pixels, of @image +End Rem +Function ImageWidth( image:TImage ) + Return image.width +End Function + +Rem +bbdoc: Get height of an image +returns: The height, in pixels, of @image +End Rem +Function ImageHeight( image:TImage ) + Return image.height +End Function + +Rem +bbdoc: Create an empty image +returns: A new image object +about: +#CreateImage creates an 'empty' image, which should be initialized using either #GrabImage or #LockImage +before being drawn. + +Please refer to #LoadImage for valid @flags values. The @flags value is always combined with DYNAMICIMAGE. +End Rem +Function CreateImage:TImage( width,height,frames=1,flags=-1 ) + If flags=-1 flags=gc.auto_imageflags + Local image:TImage=TImage.Create( width,height,frames,flags|DYNAMICIMAGE,gc.mask_red,gc.mask_green,gc.mask_blue ) + If gc.auto_midhandle MidHandleImage image + Return image +End Function + +Rem +bbdoc: Lock an image for direct access +returns: A pixmap representing the image contents +about: +Locking an image allows you to directly access an image's pixels. + +Only images created with the DYNAMICIMAGE flag can be locked. + +Locked images must eventually be unlocked with #UnlockImage before they can be drawn. +End Rem +Function LockImage:TPixmap( image:TImage,frame=0,read_lock=True,write_lock=True ) + Return image.Lock( frame,read_lock,write_lock ) +End Function + +Rem +bbdoc: Unlock an image +about: +Unlocks an image previously locked with #LockImage. +end rem +Function UnlockImage( image:TImage,frame=0 ) +End Function + +Rem +bbdoc: Grab an image from the back buffer +about: +Copies pixels from the back buffer to an image frame. + +Only images created with the DYNAMICIMAGE flag can be grabbed. +End Rem +Function GrabImage( image:TImage,x,y,frame=0 ) + Local pixmap:TPixmap=_max2dDriver.GrabPixmap( x,y,image.width,image.height ) + If image.flags&MASKEDIMAGE + pixmap=MaskPixmap( pixmap,gc.mask_red,gc.mask_green,gc.mask_blue ) + EndIf + image.SetPixmap frame,pixmap +End Function + +Rem +bbdoc: Draw pixmap +end rem +Function DrawPixmap( pixmap:TPixmap,x,y ) + _max2dDriver.DrawPixmap pixmap,x,y +End Function + +Rem +bbdoc: Grab pixmap +end rem +Function GrabPixmap:TPixmap( x,y,width,height ) + Return _max2dDriver.GrabPixmap( x,y,width,height ) +End Function + +Const COLLISION_LAYER_ALL=0 +Const COLLISION_LAYER_1=$0001 +Const COLLISION_LAYER_2=$0002 +Const COLLISION_LAYER_3=$0004 +Const COLLISION_LAYER_4=$0008 +Const COLLISION_LAYER_5=$0010 +Const COLLISION_LAYER_6=$0020 +Const COLLISION_LAYER_7=$0040 +Const COLLISION_LAYER_8=$0080 +Const COLLISION_LAYER_9=$0100 +Const COLLISION_LAYER_10=$0200 +Const COLLISION_LAYER_11=$0400 +Const COLLISION_LAYER_12=$0800 +Const COLLISION_LAYER_13=$1000 +Const COLLISION_LAYER_14=$2000 +Const COLLISION_LAYER_15=$4000 +Const COLLISION_LAYER_16=$8000 +Const COLLISION_LAYER_17=$00010000 +Const COLLISION_LAYER_18=$00020000 +Const COLLISION_LAYER_19=$00040000 +Const COLLISION_LAYER_20=$00080000 +Const COLLISION_LAYER_21=$00100000 +Const COLLISION_LAYER_22=$00200000 +Const COLLISION_LAYER_23=$00400000 +Const COLLISION_LAYER_24=$00800000 +Const COLLISION_LAYER_25=$01000000 +Const COLLISION_LAYER_26=$02000000 +Const COLLISION_LAYER_27=$04000000 +Const COLLISION_LAYER_28=$08000000 +Const COLLISION_LAYER_29=$10000000 +Const COLLISION_LAYER_30=$20000000 +Const COLLISION_LAYER_31=$40000000 +Const COLLISION_LAYER_32=$80000000 + +Rem +bbdoc: Tests if two images collide +returns: True if any pixels of the two images specified at the given location overlap. +about: +#ImagesCollide uses the current Rotation and Scale factors from the most previous +call to #SetScale and #SetRotation to calculate at a pixel level if the two images collide. +End Rem +Function ImagesCollide(image1:TImage,x1,y1,frame1,image2:TImage,x2,y2,frame2) + ResetCollisions COLLISION_LAYER_32 + CollideImage image1,x1,y1,frame1,0,COLLISION_LAYER_32 + If CollideImage(image2,x2,y2,frame2,COLLISION_LAYER_32,0) Return True +End Function + +Rem +bbdoc: Tests if two images with arbitrary Rotation and Scales collide +returns: True if any pixels of the two images specified at the given location overlap. +about: +#ImagesCollide2 uses the specified Rotation and Scale paramteters +to calculate at a pixel level if the two images collide (overlap). +End Rem +Function ImagesCollide2(image1:TImage,x1,y1,frame1,rot1#,scalex1#,scaley1#,image2:TImage,x2,y2,frame2,rot2#,scalex2#,scaley2#) + Local _scalex#,_scaley#,_rot#,res + _rot=GetRotation() + GetScale _scalex,_scaley + ResetCollisions COLLISION_LAYER_32 + SetRotation rot1 + SetScale scalex1,scaley1 + CollideImage image1,x1,y1,frame1,0,COLLISION_LAYER_32 + SetRotation rot2 + SetScale scalex2,scaley2 + If CollideImage(image2,x2,y2,frame2,COLLISION_LAYER_32,0) res=True + SetRotation _rot + SetScale _scalex,_scaley + Return res +End Function + +Rem +bbdoc: Clears collision layers specified by the value of @mask, mask=0 for all layers. +about: +The BlitzMax 2D collision system manages 32 layers, the @mask parameter can +be a combination of the following values or the special value COLLISION_LAYER_ALL in order +to perform collision operations on multiple layers. + +Note: COLLISION_LAYER_32 is used by the #ImagesCollide and #ImagesCollide2 commands. + +[ @Layer | @{Mask value} +* COLLISION_LAYER_ALL | 0 +* COLLISION_LAYER_1 | $0001 +* COLLISION_LAYER_2 | $0002 +* COLLISION_LAYER_3 | $0004 +* COLLISION_LAYER_4 | $0008 +* COLLISION_LAYER_5 | $0010 +* COLLISION_LAYER_6 | $0020 +* COLLISION_LAYER_7 | $0040 +* COLLISION_LAYER_8 | $0080 +* COLLISION_LAYER_9 | $0100 +* COLLISION_LAYER_10 | $0200 +* COLLISION_LAYER_11 | $0400 +* COLLISION_LAYER_12 | $0800 +* COLLISION_LAYER_13 | $1000 +* COLLISION_LAYER_14 | $2000 +* COLLISION_LAYER_15 | $4000 +* COLLISION_LAYER_16 | $8000 +] +EndRem +Function ResetCollisions(mask%=0) + Local i,q:TQuad + For i=0 To 31 + If mask=0 Or mask&(1 Shl i) + q=quadlayer[i] + If q + q.mask=Null + q.id=Null + While q.link + q=q.link + q.mask=Null + q.id=Null + Wend + q.link=freequads + q=quadlayer[i] + freequads=q + quadlayer[i]=Null + EndIf + EndIf + Next +End Function + +Rem +bbdoc: Pixel accurate collision testing between transformed Images. +about: +The @collidemask specifies any layers to test for collision with. + +The @writemask specifies which if any collision layers the @image is added to in it's currently transformed state. + +The id specifies an object to be returned to future #CollideImage calls when collisions occur. +EndRem +Function CollideImage:Object[](image:TImage,x,y,frame,collidemask%,writemask%,id:Object=Null) + Local q:TQuad + q=CreateQuad(image,frame,x,y,image.width,image.height,id) + Return CollideQuad(q,collidemask,writemask) +End Function + +Rem +bbdoc: Pixel accurate collision testing between image layers +about: +The @collidemask specifies any layers to test for collision with. + +The @writemask specifies which if any collision layers the @image is added to in it's currently transformed state. + +The @id specifies an object to be returned to future #CollideImage calls when collisions occur. +EndRem +Function CollideRect:Object[](x,y,w,h,collidemask%,writemask%,id:Object=Null) + Local q:TQuad + q=CreateQuad(Null,0,x,y,w,h,id) + Return CollideQuad(q,collidemask,writemask) +End Function + +Private + +Global cix#,ciy#,cjx#,cjy# + +Function SetCollisions2DTransform(ix#,iy#,jx#,jy#) 'callback from module Blitz2D + cix=ix + ciy=iy + cjx=jx + cjy=jy +End Function + +Global TextureMaps:TPixmap[] +Global LineBuffer[] +Global quadlayer:TQuad[32] +Global freequads:TQuad + +Const POLYX=0 +Const POLYY=1 +Const POLYU=2 +Const POLYV=3 + +Function DotProduct(x0#,y0#,x1#,y1#,x2#,y2#) + Return (((x2-x1)*(y1-y0))-((x1-x0)*(y2-y1))) +End Function + +Function ClockwisePoly(data#[],channels) 'flips order if anticlockwise + Local count,clk,i,j + Local r0,r1,r2 + Local t# + + count=Len(data)/channels +' clock wise test + r0=0 + r1=channels + clk=2 + For i=2 To count-1 + r2=r1+channels + If DotProduct(data[r0+POLYX],data[r0+POLYY],data[r1+POLYX],data[r1+POLYY],data[r2+POLYX],data[r2+POLYY])>=0 clk:+1 + r1=r2 + Next + If clkbot bot=y + j:+p.channels + Wend + p.Right=p.Left + Next + active=New TList + pcount=0 +' draw top to bottom + For y=top To bot-1 +' get left gradient + For p=EachIn polys + If p.state=2 Continue + If p.state=0 And y=Int(data[p.Left+POLYY]) + j=p.Left + i=(p.Left-p.channels) + If i<0 i:+p.size + While i<>p.Left + If Int(data[i+POLYY])>y Exit + j=i + i=(i-p.channels) + If i<0 i:+p.size + Wend + h=Int(data[i+POLYY])-Int(data[j+POLYY]) + If i=p.Left Or h<=0 + active.remove p +' p.remove + pcount:-1 + p.state=2 + Continue + EndIf + p.ldat=data[j..j+p.channels] + p.ladd=data[i..i+p.channels] + For j=0 To p.channels-1 + p.ladd[j]=(p.ladd[j]-p.ldat[j])/h + p.ldat[j]:+p.ladd[j]*0.5 + Next + p.Left=i + If p.state=0 + p.state=1 + active.AddLast p + pcount:+1 + EndIf + EndIf +' get right gradient + If y>=Int(data[p.Right+POLYY]) + i=(p.Right+p.channels) Mod p.size + j=p.Right + While i<>p.Right + If Int(data[i+POLYY])>y Exit + j=i + i=(i+p.channels)Mod p.size + Wend + h=Int(data[i+POLYY])-Int(data[j+POLYY]) + If i=p.Right Or h<=0 + active.remove p + pcount:-1 + p.state=2 + Continue + EndIf + p.rdat=data[j..j+p.channels] + p.radd=data[i..i+p.channels] + For j=0 To p.channels-1 + p.radd[j]=(p.radd[j]-p.rdat[j])/h + p.rdat[j]:+p.radd[j]*0.5 + Next + p.Right=i + If p.state=0 + p.state=1 + active.AddLast p + pcount:+1 + EndIf + EndIf + Next +' call renderer + If pcount + res=renderspans(active,pcount,y) + If res<0 Return res + EndIf +' increment spans + For p=EachIn active + For j=0 To p.channels-1 + p.ldat[j]:+p.ladd[j] + p.rdat[j]:+p.radd[j] + Next + Next + Next + Return res +End Function + +Function CollideSpans(polys:TList,count,y) + Local p:rpoly + Local startx,endx + Local x0,x1,w,x + Local u#,v#,ui#,vi# + Local pix Ptr + Local src:TPixmap + Local tw,th,tp,argb + Local width,skip# + + + startx=$7fffffff + endx=$80000000 + If count<2 Return 0 + p=rpoly(polys.ValueAtIndex(0)) + startx=p.ldat[POLYX] + endx=p.rdat[POLYX] + p=rpoly(polys.ValueAtIndex(1)) + x0=p.ldat[POLYX] + x1=p.rdat[POLYX] + If x0>=endx Return 0 + If x1<=startx Return 0 + If x0>startx startx=x0 + If x1Len(LineBuffer) LineBuffer=New Int[width] + MemClear LineBuffer,width*4 + For p=EachIn polys + src=p.texture + If src + x0=p.ldat[POLYX] + x1=p.rdat[POLYX] + w=x1-x0 + If w<=0 Continue + u=p.ldat[POLYU] + v=p.ldat[POLYV] + ui=(p.rdat[POLYU]-u)/w + vi=(p.rdat[POLYV]-v)/w + skip=(startx-x0)+0.5 + u=u+ui*skip + v=v+vi*skip + pix=Int Ptr(src.pixels) + tw=src.width + th=src.height + tp=src.pitch/4 + For x=0 Until width + If u<0.0 u=0.0 + If v<0.0 v=0.0 + If u>1.0 u=1.0 + If v>1.0 v=1.0 +?BigEndian + argb=$00000080 & pix[(Int(v*th))*tp+(Int(u*tw))] +?LittleEndian + argb=$80000000 & pix[(Int(v*th))*tp+(Int(u*tw))] +? + If (argb) + If LineBuffer[x] Return -1 + LineBuffer[x]=argb + EndIf + u:+ui + v:+vi + Next + Else + For x=0 Until width + If LineBuffer[x] Return -1 + LineBuffer[x]=-1 + Next + EndIf + Next + Return 0 +End Function + +Type TQuad + Field link:TQuad + Field id:Object + Field mask:TPixmap + Field frame + Field minx#,miny#,maxx#,maxy# + Field xyuv#[16] + + Method SetCoords(tx0#,ty0#,tx1#,ty1#,tx2#,ty2#,tx3#,ty3#) + xyuv[0]=tx0 + xyuv[1]=ty0 + xyuv[2]=0.0 + xyuv[3]=0.0 + xyuv[4]=tx1 + xyuv[5]=ty1 + xyuv[6]=1.0 + xyuv[7]=0.0 + xyuv[8]=tx2 + xyuv[9]=ty2 + xyuv[10]=1.0 + xyuv[11]=1.0 + xyuv[12]=tx3 + xyuv[13]=ty3 + xyuv[14]=0.0 + xyuv[15]=1.0 + minx=Min(Min(Min(tx0,tx1),tx2),tx3) + miny=Min(Min(Min(ty0,ty1),ty2),ty3) + maxx=Max(Max(Max(tx0,tx1),tx2),tx3) + maxy=Max(Max(Max(ty0,ty1),ty2),ty3) + End Method +End Type + +Function QuadsCollide(p:TQuad,q:TQuad) + If p.maxxq.maxx Or p.miny>q.maxy Return False + Local vertlist#[][2] + Local textures:TPixmap[2] + Local channels[2] + vertlist[0]=p.xyuv + vertlist[1]=q.xyuv + textures[0]=p.mask + textures[1]=q.mask + channels[0]=4 + channels[1]=4 + Return RenderPolys(vertlist,channels,textures,CollideSpans) +End Function + +Function CreateQuad:TQuad(image:TImage,frame,x#,y#,w#,h#,id:Object) + Local x0#,y0#,x1#,y1#,tx#,ty# + Local tx0#,ty0#,tx1#,ty1#,tx2#,ty2#,tx3#,ty3# + Local minx#,miny#,maxx#,maxy# + Local q:TQuad + Local pix:TPixmap + + If image + x0=-image.handle_x + y0=-image.handle_y + EndIf + x1=x0+w + y1=y0+h + tx=x+gc.origin_x + ty=y+gc.origin_y + tx0=x0*cix+y0*ciy+tx + ty0=x0*cjx+y0*cjy+ty + tx1=x1*cix+y0*ciy+tx + ty1=x1*cjx+y0*cjy+ty + tx2=x1*cix+y1*ciy+tx + ty2=x1*cjx+y1*cjy+ty + tx3=x0*cix+y1*ciy+tx + ty3=x0*cjx+y1*cjy+ty + If freequads + q=freequads + freequads=q.link + q.link=Null + Else + q=New TQuad + EndIf + q.id=id + If image + pix=image.Lock( frame,True,False ) + If AlphaBitsPerPixel[pix.format] q.mask=pix + EndIf + q.setcoords(tx0,ty0,tx1,ty1,tx2,ty2,tx3,ty3) + Return q +End Function + +Function CollideQuad:Object[](pquad:TQuad,collidemask%,writemask%) + Local result:Object[] + Local p:TQuad,q:TQuad + Local i,j,count + + p=pquad 'CreateImageQuad(image,frame,x,y) +' check for collisions + For i=0 To 31 + If collidemask & (1 Shl i) + q=quadlayer[i] + While q + If QuadsCollide(p,q) + If count=Len(result) result=result[..((count+4)*1.2)] + result[count]=q.id + count:+1 + EndIf + q=q.link + Wend + EndIf + Next +' write to layers + For i=0 To 31 + If writemask & (1 Shl i) + If freequads + q=freequads + freequads=q.link + Else + q=New TQuad + EndIf + q.id=p.id; 'TODO:optimize with memcpy? + q.mask=p.mask; + q.frame=p.frame + MemCopy q.xyuv,p.xyuv,64 + q.minx=p.minx;q.miny=p.miny;q.maxx=p.maxx;q.maxy=p.maxy; + q.link=quadlayer[i] + quadlayer[i]=q + EndIf + Next +' return result + If count Return result[..count] +End Function diff --git a/mod/brl.mod/maxlua.mod/doc/intro.bbdoc b/mod/brl.mod/maxlua.mod/doc/intro.bbdoc new file mode 100644 index 0000000..13ab1dd --- /dev/null +++ b/mod/brl.mod/maxlua.mod/doc/intro.bbdoc @@ -0,0 +1,50 @@ + +The MaxLua module provides a way to use the Lua scripting language from within Blitzmax programs. + +Lua is a simple but fast and powerful scripting language. For more information on programming in Lua, please visit the official Lua site at http://www.lua.org + +Here is an example of the MaxLua module in action: + +{{ +Strict + +'Our TDemo type... +' +Type TDemo + + Method SayHello$( name$ ) + Return "Hello "+name+"! Peace be with you..." + End Method + +End Type + +'Register a demo object with Lua. +' +'Lua code can now access the object using the identifier "Demo". +' +Local demo:TDemo=New TDemo +LuaRegisterObject demo,"Demo" + +'source code to our little Lua program... +' +Local source$=.. +"function hello()~n"+.. +"print( Demo.SayHello( 'Fredborg' ) )~n"+.. +"end~n"+.. +"function goodbye()~n"+.. +"print( Demo.SayHello( 'CandyMan' ) )~n"+.. +"end~n" + +'create a Lua 'class' and set it's source code... +' +Local class:TLuaClass=TLuaClass.Create( source ) + +'Now, create an instance of the class. +' +Local instance:TLuaObject=TLuaObject.Create( class,Null ) + +'We can no invoke methods of the class. +' +instance.Invoke "hello",Null +instance.Invoke "goodbye",Null +}} diff --git a/mod/brl.mod/maxlua.mod/lua_driver.bmx b/mod/brl.mod/maxlua.mod/lua_driver.bmx new file mode 100644 index 0000000..a4ad9de --- /dev/null +++ b/mod/brl.mod/maxlua.mod/lua_driver.bmx @@ -0,0 +1,25 @@ + +Strict + +Import Pub.Lua +Import BRL.StandardIO + +Global LuaState:Byte Ptr=luaL_newstate() +luaL_openlibs LuaState + +Function LuaRegInt( name$,value ) + lua_pushinteger LuaState,value + lua_setfield LuaState,LUA_GLOBALSINDEX,name +End Function + +Function LuaRegFunc( name$,value:Byte Ptr ) + lua_pushcclosure LuaState,value,0 + lua_setfield LuaState,LUA_GLOBALSINDEX,name +End Function + +Function LuaDumpErr() + WriteStdout "ERROR~n" + WriteStdout lua_tostring( LuaState,-1 ) +End Function + + diff --git a/mod/brl.mod/maxlua.mod/lua_object.c b/mod/brl.mod/maxlua.mod/lua_object.c new file mode 100644 index 0000000..bd7c8ce --- /dev/null +++ b/mod/brl.mod/maxlua.mod/lua_object.c @@ -0,0 +1,30 @@ + +#include + +#include + +void lua_boxobject( lua_State *L,BBObject *obj ){ + void *p; + BBRETAIN( obj ); + p=lua_newuserdata( L,4 ); + *(BBObject**)p=obj; +} + +BBObject *lua_unboxobject( lua_State *L,int index ){ + void *p; + p=lua_touserdata( L,index ); + return *(BBObject**)p; +} + +void lua_pushlightobject( lua_State *L,BBObject *obj ){ + lua_pushlightuserdata( L,obj ); +} + +BBObject *lua_tolightobject( lua_State *L,int index ){ + return (BBObject*)( lua_touserdata( L,index ) ); +} + +void lua_gcobject( lua_State *L ){ + BBObject *obj=lua_unboxobject( L,1 ); + BBRELEASE( obj ); +} diff --git a/mod/brl.mod/maxlua.mod/maxlua.bmx b/mod/brl.mod/maxlua.mod/maxlua.bmx new file mode 100644 index 0000000..1027d3b --- /dev/null +++ b/mod/brl.mod/maxlua.mod/maxlua.bmx @@ -0,0 +1,455 @@ + +Strict + +Rem +bbdoc: System/Lua scripting +End Rem +Module BRL.MaxLua + +ModuleInfo "Version: 1.00" +ModuleInfo "License: zlib/libpng" +ModuleInfo "Copyright: Blitz Research Ltd" +ModuleInfo "Author: Mark Sibly" +ModuleInfo "Modserver: BRL" + +ModuleInfo "History: 1.00" + +Import Pub.Lua +Import BRL.Reflection + +Import "lua_object.c" + +Private + +Extern + +Function lua_boxobject( L:Byte Ptr,obj:Object ) +Function lua_unboxobject:Object( L:Byte Ptr,index ) +Function lua_pushlightobject( L:Byte Ptr,obj:Object ) +Function lua_tolightobject:Object( L:Byte Ptr,index ) +Function lua_gcobject( L:Byte Ptr ) + +End Extern + +Function LuaState:Byte Ptr() + Global _luaState:Byte Ptr + If Not _luaState + _luaState=luaL_newstate() + luaL_openlibs _luaState + EndIf + Return _luaState +End Function + +Function LuaRegInt( name$,value ) + lua_pushinteger LuaState(),value + lua_setfield LuaState(),LUA_GLOBALSINDEX,name +End Function + +Function LuaRegFunc( name$,value:Byte Ptr ) + lua_pushcclosure LuaState(),value,0 + lua_setfield LuaState(),LUA_GLOBALSINDEX,name +End Function + +Function LuaDumpErr() + WriteStdout "ERROR~n" + WriteStdout lua_tostring( LuaState(),-1 ) +End Function + +Function Invoke( L:Byte Ptr ) + Local obj:Object=lua_unboxobject( L,LUA_GLOBALSINDEX-1 ) + Local meth:TMethod=TMethod( lua_tolightobject( L,LUA_GLOBALSINDEX-2 ) ) + Local tys:TTypeId[]=meth.ArgTypes(),args:Object[tys.length] + For Local i=0 Until args.length + Select tys[i] + Case IntTypeId, ShortTypeId, ByteTypeId, LongTypeId + args[i]=String.FromInt( lua_tointeger( L,i+1 ) ) + Case FloatTypeId + args[i]=String.FromFloat( lua_tonumber( L,i+1 ) ) + Case DoubleTypeId + args[i]=String.FromDouble( lua_tonumber( L,i+1 ) ) + Case StringTypeId + args[i]=lua_tostring( L,i+1 ) + Default + args[i]=lua_unboxobject( L,i+1 ) + End Select + Next + Local t:Object=meth.Invoke( obj,args ) + Select meth.TypeId() + Case IntTypeId, ShortTypeId, ByteTypeId, LongTypeId + lua_pushinteger L,t.ToString().ToInt() + Case FloatTypeId + lua_pushnumber L,t.ToString().ToFloat() + Case DoubleTypeId + lua_pushnumber L,t.ToString().ToDouble() + Case StringTypeId + Local s$=t.ToString() + lua_pushlstring L,s,s.length + Default + lua_pushobject L,t + End Select + Return 1 +End Function + +Function Index( L:Byte Ptr ) + Local obj:Object=lua_unboxobject( L,1 ) + Local typeId:TTypeId=TTypeId.ForObject( obj ) + Local ident$=lua_tostring( L,2 ) + + Local mth:TMethod=typeId.FindMethod( ident ) + If mth + lua_pushvalue L,1 + lua_pushlightobject L,mth + lua_pushcclosure L,Invoke,2 + Return True + EndIf + + Local fld:TField=typeId.FindField( ident ) + If fld + Select fld.TypeId() ' BaH - added more types + Case IntTypeId, ShortTypeId, ByteTypeId, LongTypeId + lua_pushinteger L,fld.GetInt( obj ) + Case FloatTypeId + lua_pushnumber L,fld.GetFloat( obj ) + Case DoubleTypeId + lua_pushnumber L,fld.GetDouble( obj ) + Case StringTypeId + Local t$=fld.GetString( obj ) + lua_pushlstring L,t,t.length + Default + lua_pushobject L,fld.Get( obj ) + End Select + Return True + EndIf +End Function + +Function NewIndex( L:Byte Ptr ) + Local obj:Object=lua_unboxobject( L,1 ) + Local typeId:TTypeId=TTypeId.ForObject( obj ) + Local ident$=lua_tostring( L,2 ) + + Local mth:TMethod=typeId.FindMethod( ident ) + If mth + Throw "ERROR" + EndIf + + Local fld:TField=typeId.FindField( ident ) + If fld + Select fld.TypeId() + Case IntTypeId, ShortTypeId, ByteTypeId, LongTypeId + fld.SetInt obj,lua_tointeger( L,3 ) + Case FloatTypeId + fld.SetFloat obj,lua_tonumber( L,3 ) + Case DoubleTypeId + fld.SetDouble obj,lua_tonumber( L,3 ) + Case StringTypeId + fld.SetString obj,lua_tostring( L,3 ) + Default + fld.Set obj,lua_unboxobject( L,3 ) + End Select + Return True + EndIf +End Function + +Function IndexObject( L:Byte Ptr ) + If Index( L ) Return 1 +End Function + +Function NewIndexObject( L:Byte Ptr ) + If NewIndex( L ) Return + Throw "ERROR" +End Function + +Function IndexSelf( L:Byte Ptr ) + lua_getfield( L,1,"super" ) + lua_replace L,1 + If Index( L ) Return 1 + lua_remove L,1 + lua_gettable L,LUA_GLOBALSINDEX + Return 1 +End Function + +Function NewIndexSelf( L:Byte Ptr ) + lua_rawset L,1 +End Function + +Function ObjMetaTable() + Global _objMetaTable,done + If Not done + lua_newtable LuaState() + lua_pushcfunction LuaState(),lua_gcobject + lua_setfield LuaState(),-2,"__gc" + lua_pushcfunction LuaState(),IndexObject + lua_setfield LuaState(),-2,"__index" + lua_pushcfunction LuaState(),NewIndexObject + lua_setfield LuaState(),-2,"__newindex" + _objMetaTable=luaL_ref( LuaState(),LUA_REGISTRYINDEX ) + done=True + EndIf + Return _objMetaTable +End Function + +Function lua_pushobject( L:Byte Ptr,obj:Object ) + lua_boxobject L,obj + lua_rawgeti L,LUA_REGISTRYINDEX,ObjMetaTable() + lua_setmetatable L,-2 +End Function + +' create a table and load with array contents +Function lua_pusharray( L:Byte Ptr,obj:Object ) + Local typeId:TTypeId=TTypeId.ForObject( obj ) + Local size:Int = typeId.ArrayLength(obj) + + lua_createtable L,size,0 + + For Local i:Int = 0 Until size + + ' the index + lua_pushinteger L, i + + Select typeId.ElementType() + Case IntTypeId, ShortTypeId, ByteTypeId, LongTypeId + lua_pushinteger L, typeId.GetArrayElement(obj, i).ToString().ToInt() + Case FloatTypeId + lua_pushnumber L, typeId.GetArrayElement(obj, i).ToString().ToFloat() + Case DoubleTypeId + lua_pushnumber L, typeId.GetArrayElement(obj, i).ToString().ToDouble() + Case StringTypeId + Local s:String = typeId.GetArrayElement(obj, i).ToString() + lua_pushlstring L, s, s.length + Case ArrayTypeId + lua_pusharray(L, typeId.GetArrayElement(obj, i)) + Default ' for everything else, we just push the object.. + lua_pushobject L, typeId.GetArrayElement(obj, i) + End Select + + lua_settable L, -3 + Next + +End Function + +Function lua_registerobject( L:Byte Ptr,obj:Object,name$ ) + lua_pushobject L,obj + lua_setglobal L,name +End Function + +Type TDummyLuaSuper +End Type + +Global DummyLuaSuper:TDummyLuaSuper=New TDummyLuaSuper + +Public + +Rem +bbdoc: A Lua 'object' +End Rem +Type TLuaObject + + Rem + bbdoc: Initialize the lua object + about: + Sets the object's class and super object. + + If the object was created with the TLuaObject.Create function, you do not need to call + this method. + End Rem + Method Init:TLuaObject( class:TLuaClass,supr:Object ) + Local L:Byte Ptr=LuaState() + + 'Currently needs a super object + If Not supr supr=DummyLuaSuper + + 'push class block + If Not class.lua_pushchunk() Return + + 'create fenv table + lua_newtable L + + 'saveit + lua_pushvalue L,-1 + _fenv=luaL_ref( L,LUA_REGISTRYINDEX ) + _class=class + + If supr + 'set self/super object + lua_pushvalue L,-1 + lua_setfield L,-2,"self" + lua_pushobject L,supr + lua_setfield L,-2,"super" + 'set meta indices + lua_pushcfunction L,IndexSelf + lua_setfield L,-2,"__index" + lua_pushcfunction L,NewIndexSelf + lua_setfield L,-2,"__newindex" + EndIf + + 'set fenv metatable + lua_pushvalue L,-1 + lua_setmetatable L,-2 + + 'ready! + lua_setfenv L,-2 + If lua_pcall( L,0,0,0 ) LuaDumpErr + + Return Self + End Method + + Rem + bbdoc: Invoke an object method + about: + @name should refer to a function within the object's classes' source code. + End Rem + Method Invoke:Object( name$,args:Object[] ) + Local L:Byte Ptr=LuaState() + + lua_pushfenv + lua_getfield L,-1,name + If lua_isnil( L,-1 ) + lua_pop L,2 + Return + EndIf + For Local i=0 Until args.length + Local typeId:TTypeId=TTypeId.ForObject( args[i] ) + Select typeId + Case IntTypeId, ShortTypeId, ByteTypeId, LongTypeId + lua_pushinteger L, args[i].ToString().ToInt() + Case FloatTypeId + lua_pushnumber L, args[i].ToString().ToFloat() + Case DoubleTypeId + lua_pushnumber L, args[i].ToString().ToDouble() + Case StringTypeId + Local s:String = args[i].ToString() + lua_pushlstring L,s,s.length + Case ArrayTypeId + lua_pusharray(L, args[i]) + Default + lua_pushobject L,args[i] + End Select + Next + If lua_pcall( L,args.length,1,0 ) LuaDumpErr + + + Local ret:Object + If Not lua_isnil( L,-1 ) Then + ' TODO: returning arrays from tables might be nice! + ret = lua_tostring( L, -1 ) + End If + ' pop the result + lua_pop L,1 + + ' pop the fenv ? + lua_pop L,1 + + Return ret + End Method + + Rem + bbdoc: Create a lua object + about: + Once a lua object has been created, object methods (actually lua functions defined in the + class) can be invoked using the #Invoke method. + End Rem + Function Create:TLuaObject( class:TLuaClass,supr:Object ) + Return New TLuaObject.Init( class,supr ) + End Function + + Method lua_pushfenv() + Local L:Byte Ptr=LuaState() + + lua_rawgeti L,LUA_REGISTRYINDEX,_fenv + End Method + + Method Delete() + Local L:Byte Ptr=LuaState() + luaL_unref L,LUA_REGISTRYINDEX,_fenv + End Method + + + Field _fenv + Field _class:TLuaClass + +End Type + +Rem +bbdoc: A Lua 'class' +about: +The TLuaClass type is used to contain lua source code. + +The source code should consist of a series of one or more lua functions. + +To actually invoke these functions a lua object must first be created - see #TLuaObject. +End Rem +Type TLuaClass + + Rem + bbdoc: Get source code + returns: The lua source code for the class. + End Rem + Method SourceCode$() + Return _source + End Method + + Rem + bbdoc: Set source code + about: + Sets the class source code. + + If the class was created with the TLuaClass.Create function, you do not need to call this + method. + End Rem + Method SetSourceCode:TLuaClass( source$ ) + Local L:Byte Ptr=LuaState() + _source=source + If _chunk + luaL_unref L,LUA_REGISTRYINDEX,_chunk + _chunk=0 + EndIf + Return Self + End Method + + Rem + bbdoc: Create a lua class + returns: A new lua class object. + about: + The @source parameter must be valid Lua source code, and should contain a series of one or + more lua function definitions. + + These functions can later be invoked by using the TLuaObject.Invoke method. + End Rem + Function Create:TLuaClass( source$ ) + Return New TLuaClass.SetSourceCode( source ) + End Function + + Method lua_pushchunk() + Local L:Byte Ptr=LuaState() + + If Not _chunk + If luaL_loadstring( L,_source ) + WriteStdout "Error loading script :~n" + lua_tostring( L,-1 ) + "~n" + lua_pop L,1 + Return False + EndIf + _chunk=luaL_ref( L,LUA_REGISTRYINDEX ) + EndIf + lua_rawgeti L,LUA_REGISTRYINDEX,_chunk + Return True + End Method + + Method Delete() + Local L:Byte Ptr=LuaState() + + luaL_unref L,LUA_REGISTRYINDEX,_chunk + End Method + + Field _source$ + Field _chunk + +End Type + +Rem +bbdoc: Register a global object with Lua +about: +Once registered, the object can be accessed from within Lua scripts using the @name identifer. +End Rem +Function LuaRegisterObject( obj:Object,name$ ) + lua_registerobject LuaState(),obj,name +End Function diff --git a/mod/brl.mod/maxutil.mod/maxutil.bmx b/mod/brl.mod/maxutil.mod/maxutil.bmx new file mode 100644 index 0000000..b18c82f --- /dev/null +++ b/mod/brl.mod/maxutil.mod/maxutil.bmx @@ -0,0 +1,89 @@ + +Strict + +Module BRL.MaxUtil + +ModuleInfo "Version: 1.01" +ModuleInfo "Author: Mark Sibly" +ModuleInfo "License: zlib/libpng" +ModuleInfo "Copyright: Blitz Research Ltd" +ModuleInfo "Modserver: BRL" + +ModuleInfo "History: 1.01 Release" +ModuleInfo "History: 1.00 Release" + +Import BRL.LinkedList +Import BRL.FileSystem + +Import Pub.StdC + +Function BlitzMaxPath$() + Global bmxpath$ + If bmxpath Return bmxpath + Local p$=getenv_("BMXPATH") + If p + bmxpath=p + Return p + EndIf + p=AppDir + Repeat + Local t$=p+"/bin/bmk" + ?Win32 + t:+".exe" + ? + If FileType(t)=FILETYPE_FILE + putenv_ "BMXPATH="+p + bmxpath=p + Return p + EndIf + Local q$=ExtractDir( p ) + If q=p Throw "Unable to locate BlitzMax path" + p=q + Forever +End Function + +Function ModulePath$( modid$ ) + Local p$=BlitzMaxPath()+"/mod" + If modid p:+"/"+modid.Replace(".",".mod/")+".mod" + Return p +End Function + +Function ModuleIdent$( modid$ ) + Return modid[modid.FindLast(".")+1..] +End Function + +Function ModuleSource$( modid$ ) + Return ModulePath(modid)+"/"+ModuleIdent(modid)+".bmx" +End Function + +Function ModuleArchive$( modid$,mung$="" ) + If mung And mung[0]<>Asc(".") mung="."+mung + Return ModulePath(modid)+"/"+ModuleIdent(modid)+mung+".a" +End Function + +Function ModuleInterface$( modid$,mung$="" ) + If mung And mung[0]<>Asc(".") mung="."+mung + Return ModulePath(modid)+"/"+ModuleIdent(modid)+mung+".i" +End Function + +Function EnumModules:TList( modid$="",mods:TList=Null ) + If Not mods mods=New TList + + Local dir$=ModulePath( modid ) + Local files$[]=LoadDir( dir ) + + For Local file$=EachIn files + Local path$=dir+"/"+file + If file[file.length-4..]<>".mod" Or FileType(path)<>FILETYPE_DIR Continue + + Local t$=file[..file.length-4] + If modid t=modid+"."+t + + Local i=t.Find( "." ) + If i<>-1 And t.Find( ".",i+1)=-1 mods.AddLast t + + mods=EnumModules( t,mods ) + Next + + Return mods +End Function diff --git a/mod/brl.mod/oggloader.mod/oggloader.bmx b/mod/brl.mod/oggloader.mod/oggloader.bmx new file mode 100644 index 0000000..c41a6ae --- /dev/null +++ b/mod/brl.mod/oggloader.mod/oggloader.bmx @@ -0,0 +1,90 @@ + +Strict + +Rem +bbdoc: Audio/OGG loader +about: +The OGG loader module provides the ability to load OGG format #{audio samples}. +End Rem +Module BRL.OGGLoader + +ModuleInfo "Version: 1.04" +ModuleInfo "Author: Simon Armstrong" +ModuleInfo "License: zlib/libpng" +ModuleInfo "Copyright: Blitz Research Ltd" +ModuleInfo "Modserver: BRL" + +ModuleInfo "History: 1.04 Release" +ModuleInfo "History: Moved SaveOgg to module axe.saveogg" +ModuleInfo "History: 1.03 Release" +ModuleInfo "History: Added Function SaveOgg" +ModuleInfo "History: 1.02 Release" +ModuleInfo "History: Fixed reading past end of stream with some short files" + +Import Pub.OggVorbis +Import BRL.AudioSample + +Private + +Function readfunc( buf@Ptr,size,nmemb,src:Object ) + Local bytes=TStream(src).Read(buf,size*nmemb) + Return bytes/size +End Function + +Function seekfunc( src_obj:Object,off0,off1,whence ) + Local off + Local src:TStream=TStream(src_obj) +?X86 + off=off0 +?PPC + off=off1 +? + Local res=-1 + Select whence + Case 0 + res=src.Seek(off) 'SEEK_SET + Case 1 + res=src.Seek(src.Pos()+off) 'SEEK_CUR + Case 2 + res=src.Seek(src.Size()+off) 'SEEK_END + End Select + If res>=0 Return 0 + Return -1 +End Function + +Function closefunc( src:Object ) +End Function + +Function tellfunc( src:Object ) + Return TStream(src).Pos() +End Function + +Type TAudioSampleLoaderOGG Extends TAudioSampleLoader + + Method LoadAudioSample:TAudioSample( stream:TStream ) + + Local samples,channels,freq + Local ogg:Byte Ptr=Decode_Ogg(stream,readfunc,seekfunc,closefunc,tellfunc,samples,channels,freq) + + If Not ogg Return + + Local format +?PPC + If channels=1 format=SF_MONO16BE Else format=SF_STEREO16BE +?X86 + If channels=1 format=SF_MONO16LE Else format=SF_STEREO16LE +? + Local size=samples*2*channels + Local sample:TAudioSample=TAudioSample.Create( samples,freq,format ) + + Local err=Read_Ogg( ogg,sample.samples,size ) + Read_Ogg( ogg,Null,0 ) + If err Return + + Return sample + + End Method + +End Type + +AddAudioSampleLoader New TAudioSampleLoaderOGG diff --git a/mod/brl.mod/openalaudio.mod/openalaudio.bmx b/mod/brl.mod/openalaudio.mod/openalaudio.bmx new file mode 100644 index 0000000..7da3300 --- /dev/null +++ b/mod/brl.mod/openalaudio.mod/openalaudio.bmx @@ -0,0 +1,402 @@ + +Strict + +Rem +bbdoc: Audio/OpenAL audio +about: +The OpenAL audio module provide OpenAL drivers for use with the #audio module. +End Rem +Module BRL.OpenALAudio + +ModuleInfo "Version: 1.05" +ModuleInfo "Author: Mark Sibly" +ModuleInfo "License: zlib/libpng" +ModuleInfo "Copyright: Blitz Research Ltd" +ModuleInfo "Modserver: BRL" + +ModuleInfo "History: 1.05 Release" +ModuleInfo "History: Fixed default channel volume,pan,rate" +ModuleInfo "History: Fixed behaviour of channel going out of scope" +ModuleInfo "History: 1.04 Release" +ModuleInfo "History: Fixed channel playing to return true if active (playing or paused)" +ModuleInfo "History: 1.03 Release" +ModuleInfo "History: Added (synced) alDeleteBuffers" +ModuleInfo "History: 1.02 Release" +ModuleInfo "History: Added EnableOpenALAudio" +ModuleInfo "History: 1.01 Initial Release" + +Import BRL.Math +Import BRL.Audio +Import Pub.OpenAL + +Private + +Const CLOG=False + +'list of all non-static sources +Global _sources:TOpenALSource + +Function CheckAL() + Local err$ + Select alGetError() + Case AL_NO_ERROR + Return True + Case AL_INVALID_NAME + err="INVALID_NAME" + Case AL_INVALID_ENUM + err="INVALID_ENUM" + Case AL_INVALID_VALUE + err="INVALID_VALUE" + Case AL_INVALID_OPERATION + err="INVALID_OPERATION" + Case AL_OUT_OF_MEMORY + err="OUT_OF_MEMORY" + Default + err="?????" + End Select + If CLOG WriteStdout "OpenAL Error: "+err+"~n" + Return False +End Function + +Type TOpenALSource + + Field _succ:TOpenALSource,_id,_seq,_sound:TOpenALSound,_avail + + Method Playing() + Local st + alGetSourcei _id,AL_SOURCE_STATE,Varptr st + Return st=AL_PLAYING + End Method + + Method Paused() + Local st + alGetSourcei _id,AL_SOURCE_STATE,Varptr st + Return st=AL_PAUSED Or st=AL_INITIAL + End Method + + Method Active() + Local st + alGetSourcei _id,AL_SOURCE_STATE,Varptr st + Return st=AL_PLAYING Or st=AL_PAUSED Or st=AL_INITIAL + End Method + + Method LogState() + Local st + alGetSourcei _id,AL_SOURCE_STATE,Varptr st + Select st + Case AL_PAUSED WriteStdout "AL_PAUSED~n" + Case AL_INITIAL WriteStdout "AL_INITIAL~n" + Case AL_STOPPED WriteStdout "AL_STOPPED~n" + Case AL_PLAYING WriteStdout "AL_PLAYING~n" + Default WriteStdout "AL_DUNNO, st="+st+"~n" + End Select + End Method + +End Type + +Function EnumOpenALDevices$[]() + Local p:Byte Ptr=alcGetString( 0,ALC_DEVICE_SPECIFIER ) + If Not p Return + Local devs$[100],n + While p[0] And n<100 + Local sz + Repeat + sz:+1 + Until Not p[sz] + devs[n]=String.FromBytes( p,sz ) + n:+1 + p:+sz+1 + Wend + Return devs[..n] +End Function + +Public + +Type TOpenALSound Extends TSound + + Method Delete() + alDeleteBuffers 1,Varptr _buffer + CheckAL + If CLOG WriteStdout "Deleted OpenAL buffer "+_buffer+"~n" + End Method + + Method Play:TOpenALChannel( alloced_channel:TChannel=Null ) + Local t:TOpenALChannel=Cue( alloced_channel ) + t.SetPaused False + Return t + End Method + + Method Cue:TOpenALChannel( alloced_channel:TChannel=Null ) + Local t:TOpenALChannel=TOpenALChannel( alloced_channel ) + If t + Assert t._static + Else + t=TOpenALChannel.Create( False ) + EndIf + t.Cue Self + Return t + End Method + + Function Create:TOpenALSound( sample:TAudioSample,flags ) + Local alfmt + Select sample.format + Case SF_MONO8 + alfmt=AL_FORMAT_MONO8 + Case SF_MONO16LE + alfmt=AL_FORMAT_MONO16 +?BigEndian + sample=sample.Convert( SF_MONO16BE ) +? + Case SF_MONO16BE + alfmt=AL_FORMAT_MONO16 +?LittleEndian + sample=sample.Convert( SF_MONO16LE ) +? + Case SF_STEREO8 + alfmt=AL_FORMAT_STEREO8 + Case SF_STEREO16LE + alfmt=AL_FORMAT_STEREO16 +?BigEndian + sample=sample.Convert( SF_STEREO16BE ) +? + Case SF_STEREO16BE + alfmt=AL_FORMAT_STEREO16 +?LittleEndian + sample=sample.Convert( SF_STEREO16LE ) +? + End Select + + Local buffer=-1 + alGenBuffers 1,Varptr buffer + CheckAL + + If CLOG WriteStdout "Generated OpenAL buffer "+buffer+"~n" + + alBufferData buffer,alfmt,sample.samples,sample.length*BytesPerSample[sample.format],sample.hertz + CheckAL + + Local t:TOpenALSound=New TOpenALSound + t._buffer=buffer + If (flags & 1) t._loop=1 + Return t + End Function + + Field _buffer,_loop + +End Type + +Type TOpenALChannel Extends TChannel + + Method Delete() + If _seq<>_source._seq Return + + If _static 'LEAKED! + Stop 'Just in case... + Return + EndIf + + If Not _source.Playing() + alSourceStop _source._id + alSourcei _source._id,AL_BUFFER,0 + _source._sound=Null + EndIf + + End Method + + Method Stop() + If _seq<>_source._seq Return + + _source._seq:+1 + + alSourceStop _source._id + alSourcei _source._id,AL_BUFFER,0 + _source._sound=Null + + If _static + _source._avail=True + _source._succ=_sources + _sources=_source + EndIf + End Method + + Method SetPaused( paused ) + If _seq<>_source._seq Return + + If paused + alSourcePause _source._id + Else + If _source.Paused() alSourcePlay _source._id + EndIf + End Method + + Method SetVolume( volume# ) + If _seq<>_source._seq Return + + alSourcef _source._id,AL_GAIN,volume + End Method + + Method SetPan( pan# ) + If _seq<>_source._seq Return + + pan:*90 + alSource3f _source._id,AL_POSITION,Sin(pan),0,-Cos(pan) + End Method + + Method SetDepth( depth# ) + If _seq<>_source._seq Return + End Method + + Method SetRate( rate# ) + If _seq<>_source._seq Return + + alSourcef _source._id,AL_PITCH,rate + End Method + + Method Playing() + If _seq<>_source._seq Return + + Return _source.Playing() + End Method + + Method Cue( sound:TOpenALSound ) + If _seq<>_source._seq Return + + _source._sound=sound + alSourceRewind _source._id + alSourcei _source._id,AL_LOOPING,sound._loop + alSourcei _source._id,AL_BUFFER,sound._buffer + End Method + + Function Create:TOpenALChannel( static ) + + Local source:TOpenALSource=_sources,pred:TOpenALSource + While source + If source._avail Or Not source.Active() + source._seq:+1 + If pred pred._succ=source._succ Else _sources=source._succ + If CLOG WriteStdout "Recycling OpenAL source "+source._id+"~n" + If CLOG source.LogState + alSourceRewind source._id 'return to FA_INITIAL state + If CLOG source.LogState + alSourcei source._id,AL_BUFFER,0 + source._sound=Null + Exit + EndIf + pred=source + source=source._succ + Wend + + If Not source + source=New TOpenALSource + + alGenSources 1,Varptr source._id + CheckAL + + If source._id + If CLOG WriteStdout "Generated OpenAL source "+source._id+"~n" + Else + If CLOG WriteStdout "Failed to generate OpenAL source~n" + EndIf + EndIf + + Local t:TOpenALChannel=New TOpenALChannel + t._source=source + t._seq=source._seq + t._static=static + If source._id + alSourcei source._id,AL_SOURCE_RELATIVE,True + alSourcef source._id,AL_GAIN,1 + alSourcef source._id,AL_PITCH,1 + alSource3f source._id,AL_POSITION,0,0,1 + If Not static + source._avail=False + source._succ=_sources + _sources=source + EndIf + Else + t._seq:+1 + EndIf + Return t + End Function + + Field _source:TOpenALSource,_seq,_static + +End Type + +Type TOpenALAudioDriver Extends TAudioDriver + + Method Name$() + Return _name + End Method + + Method Startup() + _device=0 + If _devname + _device=alcOpenDevice( _devname ) + Else If OpenALInstalled() + _device=alcOpenDevice( Null ) + If Not _device + _device=alcOpenDevice( "Generic Hardware" ) + If Not _device + _device=alcOpenDevice( "Generic Software" ) + EndIf + EndIf + EndIf + If _device + _context=alcCreateContext( _device,Null ) + If _context + alcMakeContextCurrent _context + alDistanceModel AL_NONE + Return True + EndIf + alcCloseDevice( _device ) + EndIf + End Method + + Method Shutdown() + _sources=Null + alcDestroyContext _context + alcCloseDevice _device + End Method + + Method CreateSound:TOpenALSound( sample:TAudioSample,flags ) + Return TOpenALSound.Create( sample,flags ) + End Method + + Method AllocChannel:TOpenALChannel() + Return TOpenALChannel.Create( True ) + End Method + + Function Create:TOpenALAudioDriver( name$,devname$ ) + Local t:TOpenALAudioDriver=New TOpenALAudioDriver + t._name=name + t._devname=devname + Return t + End Function + + Field _name$,_devname$,_device,_context + +End Type + +If OpenALInstalled() TOpenALAudioDriver.Create "OpenAL","" + +Rem +bbdoc: Enable OpenAL Audio +returns: True if successful +about: +After successfully executing this command, OpenAL audio drivers will be added +to the array of drivers returned by #AudioDrivers. +End Rem +Function EnableOpenALAudio() + Global done,okay + If done Return okay + If OpenALInstalled() And alcGetString + For Local devname$=EachIn EnumOpenALDevices() + TOpenALAudioDriver.Create( "OpenAL "+devname,devname ) + Next + TOpenALAudioDriver.Create "OpenAL Default",String.FromCString( alcGetString( 0,ALC_DEFAULT_DEVICE_SPECIFIER ) ) + okay=True + EndIf + done=True + Return okay +End Function diff --git a/mod/brl.mod/pixmap.mod/doc/intro.bbdoc b/mod/brl.mod/pixmap.mod/doc/intro.bbdoc new file mode 100644 index 0000000..ac846d5 --- /dev/null +++ b/mod/brl.mod/pixmap.mod/doc/intro.bbdoc @@ -0,0 +1,21 @@ + +Pixmaps provide storage for rectangular regions of pixels. + +You can create a new pixmap using the #CreatePixmap command, or load a pixmap +using #LoadPixmap. + +Pixmaps have 5 properties: width, height, a byte pointer to the pixmap's pixels, pitch and +format. + +You can retrieve a pointer to a pixmap's pixels using the #PixmapPixelPtr command. + +A pixmap's pitch refers to the number of bytes between one row of pixels in the pixmap +and the next. To retrieve a pixmap's pitch, use the #PixmapPitch command. + +A pixmap's pixel format determines how the pixels within a pixmap are stored in memory. This +must be taken into account if you want to access pixels directly via a pixmap's pixel pointer. +You can retrieve the format of a pixmap using the #PixmapFormat command, and convert pixmaps +from one format to another using #ConvertPixmap. + +You can also use #ResizePixmap to resize a pixmap and flip a pixmap horizontally or vertically +with #XFlipPixmap and #YFlipPixmap. diff --git a/mod/brl.mod/pixmap.mod/pixel.bmx b/mod/brl.mod/pixmap.mod/pixel.bmx new file mode 100644 index 0000000..03454bc --- /dev/null +++ b/mod/brl.mod/pixmap.mod/pixel.bmx @@ -0,0 +1,236 @@ + +Strict + +Const PF_I8= 1 +Const PF_A8= 2 +Const PF_BGR888= 3 +Const PF_RGB888= 4 +Const PF_BGRA8888= 5 +Const PF_RGBA8888= 6 + +Const PF_STDFORMAT= PF_RGBA8888 + +'New pixel formats +' +'These are GL compatible - all are 8 bit versions. +' +'NOT FULLY IMPLEMENTED YET!!!!! +' +Const PF_RED= 7 +Const PF_GREEN= 8 +Const PF_BLUE= 9 +Const PF_ALPHA= 10 +Const PF_INTENSITY= 11 +Const PF_LUMINANCE= 12 +Const PF_RGB= PF_RGB888 +Const PF_BGR= PF_BGR888 +Const PF_RGBA= PF_RGBA8888 +Const PF_BGRA= PF_BGRA8888 + +?BigEndian +Const PF_COLOR= PF_RGB +Const PF_COLORALPHA= PF_RGBA +?LittleEndian +Const PF_COLOR= PF_BGR +Const PF_COLORALPHA= PF_BGRA +? + +Global BytesPerPixel[]= [0,1,1,3,3,4,4 , 1,1,1,1,1,1] + +Global RedBitsPerPixel[]= [0,0,0,8,8,8,8, 8,0,0,0,0,0] +Global GreenBitsPerPixel[]= [0,0,0,8,8,8,8, 0,8,0,0,0,0] +Global BlueBitsPerPixel[]= [0,0,0,8,8,8,8, 0,0,8,0,0,0] +Global AlphaBitsPerPixel[]= [0,0,8,0,0,8,8, 0,0,0,8,0,0] +Global IntensityBitsPerPixel[]= [0,0,0,0,0,0,0, 0,0,0,0,8,0] +Global LuminanceBitsPerPixel[]= [0,0,0,0,0,0,0, 0,0,0,0,0,8] + +Global BitsPerPixel[]= [0,8,8,24,24,32,32, 4,4,4,4,4,4] +Global ColorBitsPerPixel[]= [0,0,0,24,24,24,24, 8,8,8,0,0,0] + +Function CopyPixels( in_buf:Byte Ptr,out_buf:Byte Ptr,format,count ) + MemCopy out_buf,in_buf,count*BytesPerPixel[format] +End Function + +Function ConvertPixels( in_buf:Byte Ptr,in_format,out_buf:Byte Ptr,out_format,count ) + If in_format=out_format + CopyPixels in_buf,out_buf,out_format,count + Else If in_format=PF_STDFORMAT + ConvertPixelsFromStdFormat in_buf,out_buf,out_format,count + Else If out_format=PF_STDFORMAT + ConvertPixelsToStdFormat in_buf,out_buf,in_format,count + Else + Local tmp_buf:Int[count] + ConvertPixelsToStdFormat in_buf,tmp_buf,in_format,count + ConvertPixelsFromStdFormat tmp_buf,out_buf,out_format,count + EndIf +End Function + +Function ConvertPixelsToStdFormat( in_buf:Byte Ptr,out_buf:Byte Ptr,format,count ) + Local in:Byte Ptr=in_buf + Local out:Byte Ptr=out_buf + Local out_end:Byte Ptr=out+count*BytesPerPixel[PF_STDFORMAT] + Select format + Case PF_A8 + While out<>out_end + out[0]=255 + out[1]=255 + out[2]=255 + out[3]=in[0] + in:+1;out:+4 + Wend + Case PF_I8 + While out<>out_end + out[0]=in[0] + out[1]=in[0] + out[2]=in[0] + out[3]=255 + in:+1;out:+4 + Wend + Case PF_RGB888 + While out<>out_end + out[0]=in[0] + out[1]=in[1] + out[2]=in[2] + out[3]=255 + in:+3;out:+4 + Wend + Case PF_BGR888 + While out<>out_end + out[0]=in[2] + out[1]=in[1] + out[2]=in[0] + out[3]=255 + in:+3;out:+4 + Wend + Case PF_BGRA8888 + While out<>out_end + out[0]=in[2] + out[1]=in[1] + out[2]=in[0] + out[3]=in[3] + in:+4;out:+4 + Wend + Case PF_RED + While out<>out_end + out[0]=in[0] + out[1]=0 + out[2]=0 + out[3]=1 + in:+1;out:+4 + Wend + Case PF_GREEN + While out<>out_end + out[0]=0 + out[1]=in[0] + out[2]=0 + out[3]=1 + in:+1;out:+4 + Wend + Case PF_BLUE + While out<>out_end + out[0]=0 + out[1]=0 + out[2]=in[0] + out[3]=1 + in:+1;out:+4 + Wend + Case PF_ALPHA + While out<>out_end + out[0]=0 + out[1]=0 + out[2]=0 + out[3]=in[0] + in:+1;out:+4 + Wend + Case PF_INTENSITY + While out<>out_end + out[0]=in[0] + out[1]=in[0] + out[2]=in[0] + out[3]=in[0] + in:+1;out:+4 + Wend + Case PF_LUMINANCE + While out<>out_end + out[0]=in[0] + out[1]=in[0] + out[2]=in[0] + out[3]=1 + in:+1;out:+4 + Wend + Case PF_STDFORMAT + CopyPixels in_buf,out_buf,PF_STDFORMAT,count + End Select +End Function + +Function ConvertPixelsFromStdFormat( in_buf:Byte Ptr,out_buf:Byte Ptr,format,count ) + Local out:Byte Ptr=out_buf + Local in:Byte Ptr=in_buf + Local in_end:Byte Ptr=in+count*BytesPerPixel[PF_STDFORMAT] + Select format + Case PF_A8 + While in<>in_end + out[0]=in[3] + in:+4;out:+1 + Wend + Case PF_I8 + While in<>in_end + out[0]=(in[0]+in[1]+in[2])/3 + in:+4;out:+1 + Wend + Case PF_RGB888 + While in<>in_end + out[0]=in[0] + out[1]=in[1] + out[2]=in[2] + in:+4;out:+3 + Wend + Case PF_BGR888 + While in<>in_end + out[0]=in[2] + out[1]=in[1] + out[2]=in[0] + in:+4;out:+3 + Wend + Case PF_BGRA8888 + While in<>in_end + out[0]=in[2] + out[1]=in[1] + out[2]=in[0] + out[3]=in[3] + in:+4;out:+4 + Wend + Case PF_RED + While in<>in_end + out[0]=in[0] + in:+4;out:+1 + Wend + Case PF_GREEN + While in<>in_end + out[0]=in[1] + in:+4;out:+1 + Wend + Case PF_BLUE + While in<>in_end + out[0]=in[2] + in:+4;out:+1 + Wend + Case PF_ALPHA + While in<>in_end + out[0]=in[3] + in:+4;out:+1 + Wend + Case PF_INTENSITY + While in<>in_end + out[0]=(in[0]+in[1]+in[2]+in[3])/4 + in:+4;out:+1 + Wend + Case PF_LUMINANCE + While in<>in_end + out[0]=(in[0]+in[1]+in[2])/3 + in:+4;out:+1 + Wend + Case PF_STDFORMAT + CopyPixels in_buf,out_buf,PF_STDFORMAT,count + End Select +End Function diff --git a/mod/brl.mod/pixmap.mod/pixmap.bmx b/mod/brl.mod/pixmap.mod/pixmap.bmx new file mode 100644 index 0000000..a6e013d --- /dev/null +++ b/mod/brl.mod/pixmap.mod/pixmap.bmx @@ -0,0 +1,587 @@ + +Strict + +Rem +bbdoc: Graphics/Pixmaps +End Rem +Module BRL.Pixmap + +ModuleInfo "Version: 1.07" +ModuleInfo "Author: Mark Sibly" +ModuleInfo "License: zlib/libpng" +ModuleInfo "Copyright: Blitz Research Ltd" +ModuleInfo "Modserver: BRL" + +ModuleInfo "History: 1.07 Release" +ModuleInfo "History: Added ClearPixels" +ModuleInfo "History: 1.06 Release" +ModuleInfo "History: Added new GL compatible pixel formats" +ModuleInfo "History: 1.05 Release" +ModuleInfo "History: Added _source:Object field" +ModuleInfo "History: Removed AddPixmapLoader function" + +Import BRL.Math +Import BRL.Stream + +Import "pixel.bmx" + +Rem +bbdoc: The Pixmap type +end rem +Type TPixmap + + Method _pad() + End Method + + Rem + bbdoc: A byte pointer to the pixmap's pixels + end rem + Field pixels:Byte Ptr + + Rem + bbdoc: The width, in pixels, of the pixmap + end rem + Field width + + Rem + bbdoc: The height, in pixels, of the pixmap + end rem + Field height + + Rem + bbdoc: The pitch, in bytes, of the pixmap + end rem + Field pitch + + Rem + bbdoc: The pixel format of the pixmap + end rem + Field format + + Rem + bbdoc: The capacity, in bytes, of the pixmap, or -1 for a static pixmap + end rem + Field capacity + + 'Hack to provide robust PixmapWindow functionality + Field _source:Object + + Method Delete() + If capacity>=0 + MemFree pixels + EndIf + End Method + + Rem + bbdoc: Get memory address of a pixel + returns: A byte pointer to the pixel at coordinates @x, @y + End Rem + Method PixelPtr:Byte Ptr( x,y ) + Return pixels+y*pitch+x*BytesPerPixel[format] + End Method + + Rem + bbdoc: Create a virtual window into a pixmap + returns: A static pixmap that references the specified rectangle. + End Rem + Method Window:TPixmap( x,y,width,height ) + Assert.. + x>=0 And width>=0 And x+width<=Self.width And.. + y>=0 And height>=0 And y+height<=Self.height Else "Pixmap coordinates out of bounds" + Local t:TPixmap=CreateStatic( PixelPtr(x,y),width,height,pitch,format ) + t._source=Self + Return t + End Method + + Rem + bbdoc: Duplicate a pixmap + returns: A new TPixmap object. + end rem + Method Copy:TPixmap() + Local pixmap:TPixmap=Create( width,height,format ) + For Local y=0 Until height + CopyPixels Self.PixelPtr(0,y),pixmap.PixelPtr(0,y),format,width + Next + Return pixmap + End Method + + Rem + bbdoc: Paste a pixmap + end rem + Method Paste( source:TPixmap,x,y ) + For Local h=0 Until source.height + ConvertPixels source.PixelPtr(0,h),source.format,Self.PixelPtr(x,y+h),Self.format,source.width + Next + End Method + + Rem + bbdoc: Convert a pixmap + returns: A new TPixmap object in the specified format + end rem + Method Convert:TPixmap( format ) + Local pixmap:TPixmap=Create( width,height,format ) + For Local y=0 Until height + ConvertPixels Self.PixelPtr(0,y),Self.format,pixmap.PixelPtr(0,y),pixmap.format,pixmap.width + Next + Return pixmap + End Method + + Rem + bbdoc: Read a pixel from a pixmap + returns: The pixel at the specified coordinates packed into an integer + end rem + Method ReadPixel( x,y ) + Assert x>=0 And x=0 And y=0 And x=0 And y. +End Rem +Type TPixmapLoader + Field _succ:TPixmapLoader + + Method New() + _succ=pixmap_loaders + pixmap_loaders=Self + End Method + + Rem + bbdoc: Load a pixmap + about: This method must be implemented by extending types. + end rem + Method LoadPixmap:TPixmap( stream:TStream ) Abstract + +End Type + +Rem +bbdoc: Create a pixmap +returns: A new pixmap object of the specified @width and @height +about: +@format should be one of the following: + +[ @Format | @Description +* PF_A8 | 8 bit alpha +* PF_I8 | 8 bit intensity +* PF_RGB888 | 24 bit big endian RGB +* PF_BGR888 | 24 bit little endian RGB +* PF_RGBA8888 | 32 bit big endian RGB with alpha +* PF_BGRA8888 | 32 bit little endian RGB with alpha +] + +Note that the newly created pixmap will contain random data. #ClearPixels can +be used to set all pixels to a known value prior to use. +End Rem +Function CreatePixmap:TPixmap( width,height,format,align_bytes=4 ) + Return TPixmap.Create( width,height,format,align_bytes ) +End Function + +Rem +bbdoc: Create a pixmap with existing pixel data +returns: A new pixmap object that references an existing block of memory +about: +The memory referenced by a static pixmap is not released when the pixmap is deleted. + +See #CreatePixmap for valid pixmap formats. +End Rem +Function CreateStaticPixmap:TPixmap( pixels:Byte Ptr,width,height,pitch,format ) + Return TPixmap.CreateStatic( pixels,width,height,pitch,format ) +End Function + +Rem +bbdoc: Copy a pixmap +returns: A new pixmap object +end rem +Function CopyPixmap:TPixmap( pixmap:TPixmap ) + Return pixmap.Copy() +End Function + +Rem +bbdoc: Convert pixel format of a pixmap +returns: A new pixmap object with the specified pixel format +about: +See #CreatePixmap for valid pixmap formats. +end rem +Function ConvertPixmap:TPixmap( pixmap:TPixmap,format ) + Return pixmap.Convert( format ) +End Function + +Rem +bbdoc: Get pixmap width +returns: The width, in pixels, of @pixmap +end rem +Function PixmapWidth( pixmap:TPixmap ) + Return pixmap.width +End Function + +Rem +bbdoc: Get pixmap width +returns: The height, in pixels, of @pixmap +end rem +Function PixmapHeight( pixmap:TPixmap ) + Return pixmap.height +End Function + +Rem +bbdoc: Get pixmap pitch +returns: The pitch, in bytes, of @pixmap +about: +Pitch refers to the difference, in bytes, between the start of one row of pixels and the start of the next row. +end rem +Function PixmapPitch( pixmap:TPixmap ) + Return pixmap.pitch +End Function + +Rem +bbdoc: Get pixmap format +returns: The format of the pixels stored in @pixmap +about: +See #CreatePixmap for supported formats. +End Rem +Function PixmapFormat( pixmap:TPixmap ) + Return pixmap.format +End Function + +Rem +bbdoc: Get pixmap pixels +returns: A byte pointer to the pixels stored in @pixmap +end rem +Function PixmapPixelPtr:Byte Ptr( pixmap:TPixmap,x=0,y=0 ) + Return pixmap.PixelPtr( x,y ) +End Function + +Rem +bbdoc: Create a pixmap window +returns: A new pixmap object +about: #PixmapWindow creates a 'virtual' window into @pixmap. +end rem +Function PixmapWindow:TPixmap( pixmap:TPixmap,x,y,width,height ) + Return pixmap.Window( x,y,width,height ) +End Function + +Rem +bbdoc: Mask a pixmap +returns: A new pixmap object +about: @MaskPixmap builds a new pixmap with alpha components set to '0' wherever the pixel colors +in the original @pixmap match @mask_red, @mask_green and @mask_blue. @mask_red, @mask_green and @mask_blue +should be in the range 0 to 255. +end rem +Function MaskPixmap:TPixmap( pixmap:TPixmap,mask_red,mask_green,mask_blue ) NoDebug + + Local tmp:TPixmap=pixmap + If tmp.format<>PF_RGBA8888 tmp=tmp.Convert( PF_RGBA8888 ) + + Local out:TPixmap=CreatePixmap( tmp.width,tmp.height,PF_RGBA8888 ) + + For Local y=0 Until pixmap.height + Local t:Byte Ptr=tmp.PixelPtr( 0,y ) + Local o:Byte Ptr=out.PixelPtr( 0,y ) + For Local x=0 Until pixmap.width + If t[0]<>mask_red Or t[1]<>mask_green Or t[2]<>mask_blue + o[0]=t[0] + o[1]=t[1] + o[2]=t[2] + o[3]=255 + Else + Local r,g,b,n + For Local ty=y-1 To y+1 + Local t:Byte Ptr=tmp.pixelptr( x-1,ty ) + For Local tx=x-1 To x+1 + If tx>=0 And tx=0 And tymask_red Or t[1]<>mask_green Or t[2]<>mask_blue + r:+t[0] + g:+t[1] + b:+t[2] + n:+1 + EndIf + EndIf + t:+4 + Next + Next + If n + o[0]=r/n + o[1]=g/n + o[2]=b/n + Else + o[0]=0't[0] + o[1]=0't[1] + o[2]=0't[2] + EndIf + o[3]=0 + EndIf + t:+4 + o:+4 + Next + Next + Return out +End Function + +Rem +bbdoc: Flip a pixmap horizontally +returns: A new pixmap object +end rem +Function XFlipPixmap:TPixmap( pixmap:TPixmap ) NoDebug + Local out:TPixmap=CreatePixmap( pixmap.width,pixmap.height,pixmap.format ) + For Local x=0 Until pixmap.width + out.Paste pixmap.Window(pixmap.width-x-1,0,1,pixmap.height),x,0 + Next + Return out +End Function + +Rem +bbdoc: Flip a pixmap vertically +returns: A new pixmap object +end rem +Function YFlipPixmap:TPixmap( pixmap:TPixmap ) NoDebug + Local out:TPixmap=CreatePixmap( pixmap.width,pixmap.height,pixmap.format ) + For Local y=0 Until pixmap.height + out.paste pixmap.Window(0,pixmap.height-y-1,pixmap.width,1),0,y + Next + Return out +End Function + +Rem +bbdoc: Resize a pixmap +returns: A new pixmap object of the specified @width and @height +end rem +Function ResizePixmap:TPixmap( pixmap:TPixmap,width,height ) NoDebug + Local in_pixmap:TPixmap=pixmap + If in_pixmap.format<>PF_STDFORMAT in_pixmap=pixmap.Convert( PF_STDFORMAT ) + Local tmp:Byte[width*4] + Local x_sc#=Float(in_pixmap.width)/width + Local y_sc#=Float(in_pixmap.height)/height + Local out_pixmap:TPixmap=CreatePixmap( width,height,pixmap.format ) + For Local y=0 Until height + Local ty#=(y+.5)*y_sc-.5 + Local iy#=Floor(ty),fy#=ty-iy + Local in_pitch=in_pixmap.pitch + If iy<0 + iy=0;fy=0;in_pitch=0 + Else If iy>=in_pixmap.height-1 + iy=in_pixmap.height-1;fy=0;in_pitch=0 + EndIf + Local src:Byte Ptr=in_pixmap.PixelPtr(0,iy),dst:Byte Ptr=tmp + For Local x=0 Until width + Local tx#=(x+.5)*x_sc-.5 + Local ix#=Floor(tx),fx#=tx-ix + Local in_off=4 + If ix<0 + ix=0;fx=0;in_off=0 + Else If ix>=in_pixmap.width-1 + ix=in_pixmap.width-1;fx=0;in_off=0 + EndIf + Local p:Byte Ptr=src+Int(ix)*4 + For Local n=0 Until 4 + Local v0#=p[n],v1#=p[n+in_off] + Local v2#=p[n+in_pitch],v3#=p[n+in_pitch+in_off] + Local va#=(v1-v0)*fx+v0,vb#=(v3-v2)*fx+v2,vt#=(vb-va)*fy+va + dst[n]=vt + Next + dst:+4 + Next + ConvertPixels tmp,PF_STDFORMAT,out_pixmap.Pixelptr(0,y),out_pixmap.format,width + Next + Return out_pixmap +End Function + +Rem +bbdoc: Load a pixmap +returns: A pixmap object +end rem +Function LoadPixmap:TPixmap( url:Object ) + Local stream:TStream=ReadStream( url ) + If Not stream Return + + Local pos=stream.Pos() + If pos=-1 + stream.Close + Return + EndIf + + Local pixmap:TPixmap + Local loader:TPixmapLoader=pixmap_loaders + + While loader + stream.Seek pos + Try + pixmap=loader.LoadPixmap( stream ) + Catch ex:TStreamException + End Try + If pixmap Exit + loader=loader._succ + Wend + stream.Close + Return pixmap +End Function + +Rem +bbdoc: Read a pixel from a pixmap +returns: A 32 bit pixel value +about: +The returned 32 bit value contains the following components: + +[ bits 24-31 | pixel alpha +* bits 16-23 | pixel red +* bits 8-15 | pixel green +* bits 0-7 | pixel blue +] +End Rem +Function ReadPixel( pixmap:TPixmap,x,y ) + Return pixmap.ReadPixel( x,y ) +End Function + +Rem +bbdoc: Write a pixel to a pixmap +about: +The 32 bit @argb value contains the following components: + +[ bits 24-31 | pixel alpha +* bits 16-23 | pixel red +* bits 8-15 | pixel green +* bits 0-7 | pixel blue +] +End Rem +Function WritePixel( pixmap:TPixmap,x,y,argb ) + pixmap.WritePixel x,y,argb +End Function + +Rem +bbdoc: Clear a pixmap +about: +Sets all pixels in a pixmap to a 32 bit pixel value. + +The 32 bit @argb value contains the following components: + +[ bits 24-31 | pixel alpha +* bits 16-23 | pixel red +* bits 8-15 | pixel green +* bits 0-7 | pixel blue +] +End Rem +Function ClearPixels( pixmap:TPixmap,argb=0 ) + pixmap.ClearPixels argb +End Function diff --git a/mod/brl.mod/pngloader.mod/pngloader.bmx b/mod/brl.mod/pngloader.mod/pngloader.bmx new file mode 100644 index 0000000..123c032 --- /dev/null +++ b/mod/brl.mod/pngloader.mod/pngloader.bmx @@ -0,0 +1,229 @@ + +Strict + +Rem +bbdoc: Graphics/PNG loader +about: +The PNG loader module provides the ability to load PNG format #pixmaps. +End Rem +Module BRL.PNGLoader + +ModuleInfo "Version: 1.04" +ModuleInfo "Author: Mark Sibly" +ModuleInfo "License: zlib/libpng" +ModuleInfo "Copyright: Blitz Research Ltd" +ModuleInfo "Modserver: BRL" + +ModuleInfo "History: 1.04" +ModuleInfo "History: libpng update to 1.2.12." +ModuleInfo "History: Extra load error handling." +ModuleInfo "History: 1.03 Release" +ModuleInfo "History: Added Gray/Alpha support" +ModuleInfo "History: 1.02 Release" +ModuleInfo "History: Fixed palettized/grayscale support" + +Import BRL.Pixmap +Import Pub.LibPNG + +Private + +Global png_stream:TStream + +Function png_read_fn( png_ptr,buf:Byte Ptr,size ) + Return png_stream.ReadBytes( buf,size ) +End Function + +Function png_write_fn( png_ptr,buf:Byte Ptr,size ) + Return png_stream.WriteBytes( buf,size ) +End Function + +Function png_flush_fn( png_ptr ) + png_stream.Flush +End Function + +Public + +Rem +bbdoc: Load a Pixmap in PNG format +about: +#LoadPixmapPNG loads a pixmap from @url in PNG format. + +If the pixmap cannot be loaded, Null is returned. +End Rem +Function LoadPixmapPNG:TPixmap( url:Object ) + + png_stream=ReadStream( url ) + If Not png_stream Return + + Local buf:Byte[8] + + If png_stream.ReadBytes( buf,8 )<>8 Or png_sig_cmp( buf,0,8 )<>0 + png_stream.Close + png_stream=Null + Return + EndIf + + Try + Local png_ptr=png_create_read_struct( "1.2.12",Null,Null,Null ) + + ' check for valid png_ptr + If Not png_ptr Then + png_stream.Close + png_stream=Null + Return + End If + + Local info_ptr=png_create_info_struct( png_ptr ) + + ' check for valid info_ptr + If Not info_ptr Then + png_stream.Close + png_stream=Null + png_destroy_read_struct Varptr png_ptr,Null,Null + Return + End If + + png_set_sig_bytes png_ptr,8 + + png_set_read_fn png_ptr,Null,png_read_fn + + png_read_png png_ptr,info_ptr,PNG_TRANSFORM_EXPAND|PNG_TRANSFORM_STRIP_16,0 + + Local width,height,bit_depth,color_type,interlace_type,compression_type,filter_method + png_get_IHDR png_ptr,info_ptr,width,height,bit_depth,color_type,interlace_type,compression_type,filter_method + + Local pixmap:TPixmap + + If bit_depth=8 + Local pf + Select color_type + Case PNG_COLOR_TYPE_GRAY + pf=PF_I8 + Case PNG_COLOR_TYPE_RGB + pf=PF_RGB888 + Case PNG_COLOR_TYPE_RGBA + pf=PF_RGBA8888 + Case PNG_COLOR_TYPE_GRAY_ALPHA + pixmap=CreatePixmap( width,height,PF_RGBA8888 ) + Local rows:Byte Ptr Ptr=png_get_rows( png_ptr,info_ptr ) + For Local y=0 Until height + Local src:Byte Ptr=rows[y] + Local dst:Byte Ptr=pixmap.PixelPtr(0,y) + For Local x=0 Until width + Local a=src[0] + Local i=src[1] + dst[0]=i + dst[1]=i + dst[2]=i + dst[3]=a + src:+2 + dst:+4 + Next + Next + End Select + If pf + pixmap=CreatePixmap( width,height,pf ) + Local rows:Byte Ptr Ptr=png_get_rows( png_ptr,info_ptr ) + For Local y=0 Until height + CopyPixels rows[y],pixmap.PixelPtr(0,y),pf,width + Next + EndIf + EndIf + + png_destroy_read_struct Varptr png_ptr,Varptr info_ptr,Null + + png_stream.Close + png_stream=Null + Return pixmap + + Catch ex:String + + If ex<>"PNG ERROR" Throw ex + + End Try + +End Function + +Rem +bbdoc: Save a Pixmap in PNG format +about: +#SavePixmapPNG saves @pixmap to @url in PNG format. If successful, #SavePixmapPNG returns +True, otherwise False. + +The optional @compression parameter should be in the range 0 to 9, where +0 indicates no compression (fastest) and 9 indicates full compression (slowest). +End Rem +Function SavePixmapPNG( pixmap:TPixmap,url:Object,compression=5 ) + + compression=Min( Max( compression,0 ),9 ) + + png_stream:TStream=WriteStream( url ) + If Not png_stream Return + + Try + Local png_ptr=png_create_write_struct( "1.2.12",Null,Null,Null ) + Local info_ptr=png_create_info_struct( png_ptr ) + + png_set_write_fn png_ptr,Null,png_write_fn,png_flush_fn + + Local bitdepth,colortype,transform + + Select pixmap.format + Case PF_I8 + colortype=PNG_COLOR_TYPE_GRAY + Case PF_RGB888 + colortype=PNG_COLOR_TYPE_RGB + Case PF_BGR888 + colortype=PNG_COLOR_TYPE_RGB + transform=PNG_TRANSFORM_BGR + Case PF_RGBA8888 + colortype=PNG_COLOR_TYPE_RGBA + Case PF_BGRA8888 + colortype=PNG_COLOR_TYPE_RGBA + transform=PNG_TRANSFORM_BGR + Default + colortype=PNG_COLOR_TYPE_RGBA + pixmap=pixmap.Convert( PF_RGBA8888 ) + End Select + + png_set_compression_level png_ptr,compression + + png_set_IHDR png_ptr,info_ptr,pixmap.width,pixmap.height,8,colortype,PNG_INTERLACE_NONE,PNG_COMPRESSION_TYPE_DEFAULT,PNG_FILTER_TYPE_DEFAULT + + Local rows:Byte Ptr[pixmap.height] + For Local i=0 Until pixmap.height + rows[i]=pixmap.PixelPtr( 0,i ) + Next + + png_set_rows png_ptr,info_ptr,rows + + png_write_png png_ptr,info_ptr,transform,Null + + png_destroy_write_struct Varptr png_ptr,Varptr info_ptr,Null + + png_stream.Close + png_stream=Null + + Return True + + Catch ex:String + + If ex<>"PNG ERROR" Throw ex + + End Try + +End Function + +Private + +Type TPixmapLoaderPNG Extends TPixmapLoader + + Method LoadPixmap:TPixmap( stream:TStream ) + + Return LoadPixmapPNG( stream ) + + End Method + +End Type + +New TPixmapLoaderPNG diff --git a/mod/brl.mod/polledinput.mod/doc/appterminate.bmx b/mod/brl.mod/polledinput.mod/doc/appterminate.bmx new file mode 100644 index 0000000..5ee80fb --- /dev/null +++ b/mod/brl.mod/polledinput.mod/doc/appterminate.bmx @@ -0,0 +1,10 @@ + +Graphics 640,480,0 + +While Not AppTerminate() Or Not Confirm( "Terminate?" ) + + Cls + DrawText MouseX()+","+MouseY(),0,0 + Flip + +Wend diff --git a/mod/brl.mod/polledinput.mod/doc/intro.bbdoc b/mod/brl.mod/polledinput.mod/doc/intro.bbdoc new file mode 100644 index 0000000..7570a7e --- /dev/null +++ b/mod/brl.mod/polledinput.mod/doc/intro.bbdoc @@ -0,0 +1,6 @@ + ++Polled input + +The polled input module provides an easy way to detect keyboard and mouse input. + +The functions in this module are only available when your program is running in #Graphics mode. When working on GUI applications, you should use #events instead. diff --git a/mod/brl.mod/polledinput.mod/doc/keydown.bmx b/mod/brl.mod/polledinput.mod/doc/keydown.bmx new file mode 100644 index 0000000..037bdb5 --- /dev/null +++ b/mod/brl.mod/polledinput.mod/doc/keydown.bmx @@ -0,0 +1,13 @@ +' keydown.bmx + +' the following code draws a circle if the +' program detects the spacebar is pressed +' and exits when it detects the ESCAPE key has +' been pressed + +Graphics 640,480 +While Not KeyHit(KEY_ESCAPE) + Cls + If KeyDown(KEY_SPACE) DrawOval 0,0,640,480 + Flip +Wend diff --git a/mod/brl.mod/polledinput.mod/doc/keyhit.bmx b/mod/brl.mod/polledinput.mod/doc/keyhit.bmx new file mode 100644 index 0000000..c3f8827 --- /dev/null +++ b/mod/brl.mod/polledinput.mod/doc/keyhit.bmx @@ -0,0 +1,13 @@ +' keyhit.bmx + +' the following code draws a circle every time the +' program detects the spacebar has been pressed +' and exits when it detects the ESCAPE key has +' been pressed + +graphics 640,480 +while not keyhit(KEY_ESCAPE) + cls + if keyhit(KEY_SPACE) drawoval 0,0,640,480 + flip +wend diff --git a/mod/brl.mod/polledinput.mod/doc/mousedown.bmx b/mod/brl.mod/polledinput.mod/doc/mousedown.bmx new file mode 100644 index 0000000..01d8550 --- /dev/null +++ b/mod/brl.mod/polledinput.mod/doc/mousedown.bmx @@ -0,0 +1,11 @@ +' mousedown.bmx + +graphics 640,480 + +while not keyhit(KEY_ESCAPE) + cls + if mousedown(1) drawrect 0,0,200,200 + if mousedown(2) drawrect 200,0,200,200 + if mousedown(3) drawrect 400,0,200,200 + flip +wend diff --git a/mod/brl.mod/polledinput.mod/doc/mousehit.bmx b/mod/brl.mod/polledinput.mod/doc/mousehit.bmx new file mode 100644 index 0000000..780138c --- /dev/null +++ b/mod/brl.mod/polledinput.mod/doc/mousehit.bmx @@ -0,0 +1,11 @@ +' mousehit.bmx + +graphics 640,480 + +while not keyhit(KEY_ESCAPE) + cls + if mousehit(1) drawrect 0,0,200,200 + if mousehit(2) drawrect 200,0,200,200 + if mousehit(3) drawrect 400,0,200,200 + flip +wend diff --git a/mod/brl.mod/polledinput.mod/doc/mousex.bmx b/mod/brl.mod/polledinput.mod/doc/mousex.bmx new file mode 100644 index 0000000..dd8571a --- /dev/null +++ b/mod/brl.mod/polledinput.mod/doc/mousex.bmx @@ -0,0 +1,10 @@ +' mousex.bmx + +' the following tracks the position of the mouse + +graphics 640,480 +while not keyhit(KEY_ESCAPE) + cls + drawoval mousex()-10,mousey()-10,20,20 + flip +wend diff --git a/mod/brl.mod/polledinput.mod/doc/mousey.bmx b/mod/brl.mod/polledinput.mod/doc/mousey.bmx new file mode 100644 index 0000000..e2c4ef6 --- /dev/null +++ b/mod/brl.mod/polledinput.mod/doc/mousey.bmx @@ -0,0 +1,10 @@ +' mousey.bmx + +' the following tracks the position of the mouse + +graphics 640,480 +while not keyhit(KEY_ESCAPE) + cls + drawrect mousex()-10,mousey()-10,20,20 + flip +wend diff --git a/mod/brl.mod/polledinput.mod/doc/mousez.bmx b/mod/brl.mod/polledinput.mod/doc/mousez.bmx new file mode 100644 index 0000000..b09b8dc --- /dev/null +++ b/mod/brl.mod/polledinput.mod/doc/mousez.bmx @@ -0,0 +1,10 @@ +' mousez.bmx + +' prints mousez() the mousewheel position + +Graphics 640,480 +While Not keyhit(KEY_ESCAPE) + cls + drawtext "MouseZ()="+MouseZ(),0,0 + flip +Wend diff --git a/mod/brl.mod/polledinput.mod/doc/movemouse.bmx b/mod/brl.mod/polledinput.mod/doc/movemouse.bmx new file mode 100644 index 0000000..8f7ad90 --- /dev/null +++ b/mod/brl.mod/polledinput.mod/doc/movemouse.bmx @@ -0,0 +1,27 @@ +' movemouse.bmx + +' demonstrates using the mouse as a proportional controller +' by locking the mouse to the center of the screen and reporting +' MouseXSpeed and MouseYSpeed variables + +Global MouseXSpeed,MouseYSpeed + +Function SampleMouse() + MouseXSpeed=MouseX()-320 + MouseYSpeed=MouseY()-240 + MoveMouse 320,240 +End Function + +Graphics 640,480 + +HideMouse +MoveMouse 320,240 + +While Not KeyHit(KEY_ESCAPE) + SampleMouse + Cls + DrawText "MouseXSpeed="+MouseXSpeed,0,0 + DrawText "MouseYSpeed="+MouseYSpeed,0,20 + Flip +Wend + diff --git a/mod/brl.mod/polledinput.mod/polledinput.bmx b/mod/brl.mod/polledinput.mod/polledinput.bmx new file mode 100644 index 0000000..6561655 --- /dev/null +++ b/mod/brl.mod/polledinput.mod/polledinput.bmx @@ -0,0 +1,352 @@ + +Strict + +Rem +bbdoc: User input/Polled input +End Rem +Module BRL.PolledInput + +ModuleInfo "Version: 1.01" +ModuleInfo "Author: Mark Sibly, Simon Armstrong" +ModuleInfo "License: zlib/libpng" +ModuleInfo "Copyright: Blitz Research Ltd" +ModuleInfo "Modserver: BRL" + +ModuleInfo "History: 1.01 Release" +ModuleInfo "History: Fixed charQueue bug" + +Import BRL.System + +Private + +Global enabled +Global autoPoll=True +Global inputSource:Object +Global suspended,terminate + +Global keyStates[256],keyHits[256] +Global charGet,charPut,charQueue[256] + +Global mouseStates[4],mouseHits[4] +Global mouseLocation[4],lastMouseLocation[4] + +Function Hook:Object( id,data:Object,context:Object ) + + Local ev:TEvent=TEvent(data) + If Not ev Return data + + If inputSource And inputSource<>ev.source Return data + + Select ev.id + Case EVENT_KEYDOWN + If Not keyStates[ev.data] + keyStates[ev.data]=1 + keyHits[ev.data]:+1 + EndIf + Case EVENT_KEYUP + keyStates[ev.data]=0 + Case EVENT_KEYCHAR + If charPut-charGet<256 + charQueue[charPut & 255]=ev.data + charPut:+1 + EndIf + Case EVENT_MOUSEDOWN + If Not mouseStates[ev.data] + mouseStates[ev.data]=1 + mouseHits[ev.data]:+1 + EndIf + Case EVENT_MOUSEUP + mouseStates[ev.data]=0 + Case EVENT_MOUSEMOVE + mouseLocation[0]=ev.x + mouseLocation[1]=ev.y + Case EVENT_MOUSEWHEEL + mouseLocation[2]:+ev.data + Case EVENT_APPSUSPEND + FlushKeys + FlushMouse + suspended=True + Case EVENT_APPRESUME + FlushKeys + FlushMouse + suspended=False + Case EVENT_APPTERMINATE + terminate=True + End Select + + Return data + +End Function + +Public + +Rem +Currently only called by Graphics/bglCreateContext. +Private for now, as it really needs a source:object parameter. +End Rem +Function EnablePolledInput( source:Object=Null ) + If enabled Return + inputSource=source + FlushKeys + FlushMouse + AddHook EmitEventHook,Hook,Null,0 + enabled=True +End Function + +Rem +Currently only called by EndGraphics/bglDeleteContext +End Rem +Function DisablePolledInput() + If Not enabled Return + RemoveHook EmitEventHook,Hook + FlushKeys + FlushMouse + inputSource=Null + enabled=False +End Function + +Rem +bbdoc: Get app suspended state +returns: True if application is currently suspended. +End Rem +Function AppSuspended() + If autoPoll PollSystem + Return suspended +End Function + +Rem +bbdoc: Return app terminate state +returns: True if user has requested to terminate application +End Rem +Function AppTerminate() + If autoPoll PollSystem + Local n=terminate + terminate=False + Return n +End Function + +Rem +bbdoc: Check for key hit +returns: Number of times @key has been hit. +about: +The returned value represents the number of the times @key has been hit since the last +call to #KeyHit with the same @key. + +See the #{key codes} module for a list of valid key codes. +End Rem +Function KeyHit( key ) + If autoPoll PollSystem + Local n=keyHits[key] + keyHits[key]=0 + Return n +End Function + +Rem +bbdoc: Check for key state +returns: #True if @key is currently down +about: +See the #{key codes} module for a list of valid keycodes. +End Rem +Function KeyDown( key ) + If autoPoll PollSystem + Return keyStates[key] +End Function + +Rem +bbdoc: Get next character +returns: The character code of the next character. +about: +As the user hits keys on the keyboard, BlitzMax records the character codes of these +keystrokes into an internal 'character queue'. + +#GetChar removes the next character code from this queue and returns it the application. + +If the character queue is empty, 0 is returned. +End Rem +Function GetChar() + If autoPoll PollSystem + If charGet=charPut Return 0 + Local n=charQueue[charGet & 255] + charGet:+1 + Return n +End Function + +Rem +bbdoc: Flush key states and character queue. +about: +#FlushKeys resets the state of all keys to 'off', and resets the character queue +used by #GetChar. +End Rem +Function FlushKeys() + PollSystem + charGet=0 + charPut=0 + For Local i=0 Until 256 + keyStates[i]=0 + keyHits[i]=0 + Next +End Function + +Rem +bbdoc: Get mouse x location +returns: Mouse x axis location +about: +The returned value is relative to the left of the screen. +end rem +Function MouseX() + If autoPoll PollSystem + Return mouseLocation[0] +End Function + +Rem +bbdoc: Get mouse y location +returns: Mouse y axis location +about: +The returned value is relative to the top of the screen. +end rem +Function MouseY() + If autoPoll PollSystem + Return mouseLocation[1] +End Function + +Rem +bbdoc: Get mouse wheel +returns: Mouse wheel value +about: +The mouse wheel value increments when the mouse wheel is rolled 'away' from the user, and +decrements when the mouse wheel is rolled 'towards' the user. +end rem +Function MouseZ() + If autoPoll PollSystem + Return mouseLocation[2] +End Function + +Rem +bbdoc: Get mouse x speed +returns: Mouse x speed +End Rem +Function MouseXSpeed() + If autoPoll PollSystem + Local d=mouseLocation[0]-lastMouseLocation[0] + lastMouseLocation[0]=mouseLocation[0] + Return d +EndFunction + +Rem +bbdoc: Get mouse y speed +returns: Mouse y speed +End Rem +Function MouseYSpeed() + If autoPoll PollSystem + Local d=mouseLocation[1]-lastMouseLocation[1] + lastMouseLocation[1]=mouseLocation[1] + Return d +EndFunction + +Rem +bbdoc: Get mouse z speed +returns: Mouse z speed +End Rem +Function MouseZSpeed() + If autoPoll PollSystem + Local d=mouseLocation[2]-lastMouseLocation[2] + lastMouseLocation[2]=mouseLocation[2] + Return d +EndFunction + +Rem +bbdoc: Flush mouse button states +about: +#FlushMouse resets the state of all mouse buttons to 'off'. +End Rem +Function FlushMouse() + PollSystem + For Local i=0 Until 4 + mouseStates[i]=0 + mouseHits[i]=0 + Next + mouseLocation[2]=0 +End Function + +Rem +bbdoc: Check for mouse button click +returns: Number of times @button has been clicked. +about: +The returned value represents the number of the times @button has been clicked since the +last call to #MouseHit with the same @button. + +@button should be 1 for the left mouse button, 2 for the right mouse button or 3 for the +middle mouse button. +End Rem +Function MouseHit( button ) + If autoPoll PollSystem + Local n=mouseHits[button] + mouseHits[button]=0 + Return n +End Function + +Rem +bbdoc: Check for mouse button down state +returns: #True if @button is currently down +about: +@button should be 1 for the left mouse button, 2 for the right mouse button or 3 for the +middle mouse button. +end rem +Function MouseDown( button ) + If autoPoll PollSystem + Return mouseStates[button] +End Function + +Rem +bbdoc: Wait for a key press +returns: The keycode of the pressed key +about: +#WaitKey suspends program execution until a key has been hit. The keycode of this +key is then returned to the application. + +See the #{key codes} module for a list of valid keycodes. +End Rem +Function WaitKey() + FlushKeys + Repeat + WaitSystem + For Local n=1 To 255 + If KeyHit(n) Return n + Next + Forever +End Function + +Rem +bbdoc: Wait for a key press +returns: The character code of the pressed key +about: +#WaitChar suspends program execution until a character is available from #GetChar. This +character is then returned to the application. +End Rem +Function WaitChar() + FlushKeys + Repeat + WaitSystem + Local n=GetChar() + If n Return n + Forever +End Function + +Rem +bbdoc: Wait for mouse button click +returns: The clicked button +about: +#WaitMouse suspends program execution until a mouse button is clicked. + +#WaitMouse returns 1 if the left mouse button was clicked, 2 if the right mouse button was +clicked or 3 if the middle mouse button was clicked. +End Rem +Function WaitMouse() + FlushMouse + Repeat + WaitSystem + For Local n=1 To 3 + If MouseHit(n) Return n + Next + Forever +End Function diff --git a/mod/brl.mod/ramstream.mod/ramstream.bmx b/mod/brl.mod/ramstream.mod/ramstream.bmx new file mode 100644 index 0000000..edc0c4d --- /dev/null +++ b/mod/brl.mod/ramstream.mod/ramstream.bmx @@ -0,0 +1,87 @@ + +Strict + +Rem +bbdoc: Streams/Ram streams +End Rem +Module BRL.RamStream + +ModuleInfo "Version: 1.01" +ModuleInfo "Author: Mark Sibly" +ModuleInfo "License: zlib/libpng" +ModuleInfo "Copyright: Blitz Research Ltd" +ModuleInfo "Modserver: BRL" + +Import BRL.Stream + +Type TRamStream Extends TStream + + Field _pos,_size,_buf:Byte Ptr,_read,_write + + Method Pos() + Return _pos + End Method + + Method Size() + Return _size + End Method + + Method Seek( pos ) + If pos<0 pos=0 Else If pos>_size pos=_size + _pos=pos + Return _pos + End Method + + Method Read( buf:Byte Ptr,count ) + If count<=0 Or _read=False Return 0 + If _pos+count>_size count=_size-_pos + MemCopy buf,_buf+_pos,count + _pos:+count + Return count + End Method + + Method Write( buf:Byte Ptr,count ) + If count<=0 Or _write=False Return 0 + If _pos+count>_size count=_size-_pos + MemCopy _buf+_pos,buf,count + _pos:+count + Return count + End Method + + Function Create:TRamStream( buf:Byte Ptr,size,readable,writeable ) + Local stream:TRamStream=New TRamStream + stream._pos=0 + stream._size=size + stream._buf=buf + stream._read=readable + stream._write=writeable + Return stream + End Function + +End Type + +Rem +bbdoc: Create a ram stream +returns: A ram stream object +about: A ram stream allows you to read and/or write data directly from/to memory. +A ram stream extends a stream object so can be used anywhere a stream is expected. + +Be careful when working with ram streams, as any attempt to access memory +which has not been allocated to your application can result in a runtime crash. +End Rem +Function CreateRamStream:TRamStream( ram:Byte Ptr,size,readable,writeable ) + Return TRamStream.Create( ram,size,readable,writeable ) +End Function + +Type TRamStreamFactory Extends TStreamFactory + Method CreateStream:TRamStream( url:Object,proto$,path$,readable,writeable ) + If proto="incbin" And writeable=False + Local buf:Byte Ptr=IncbinPtr( path ) + If Not buf Return + Local size=IncbinLen( path ) + Return TRamStream.Create( buf,size,readable,writeable ) + EndIf + End Method +End Type + +New TRamStreamFactory diff --git a/mod/brl.mod/random.mod/doc/intro.bbdoc b/mod/brl.mod/random.mod/doc/intro.bbdoc new file mode 100644 index 0000000..82a9bc3 --- /dev/null +++ b/mod/brl.mod/random.mod/doc/intro.bbdoc @@ -0,0 +1,14 @@ + ++Random numbers + +The random module contains commands for generating random numbers. + +The numbers generated are not really random, as without special hardware support a software algorithm cannot produce 'real' random numbers. + +Instead, the algorithm produces values that merely appear to be random. In reality, each generated value actually depends on the previously generated value. + +You can set the 'state' of the random number generator using the #SeedRnd command. A common practice is to seed the random number generator with the system time when your program starts up, for example: +{{ +SeedRnd MilliSecs() +}} +This ensures that the random number generator does not start in the same state each time your program is run, which would cause it to produce the same sequence of random numbers. diff --git a/mod/brl.mod/random.mod/doc/rand.bmx b/mod/brl.mod/random.mod/doc/rand.bmx new file mode 100644 index 0000000..a540ffa --- /dev/null +++ b/mod/brl.mod/random.mod/doc/rand.bmx @@ -0,0 +1,14 @@ +' Rand.bmx +' Toss a pair of dice. Result is in the range 1+1 to 6+6. +' Count how many times each result appears. + +Local count[13] + +For n = 1 To 3600 + toss = Rand(1,6) + Rand(1,6) + count[toss] :+ 1 +Next + +For toss = 2 To 12 + Print LSet(toss, 5)+count[toss] +Next diff --git a/mod/brl.mod/random.mod/doc/rnd.bmx b/mod/brl.mod/random.mod/doc/rnd.bmx new file mode 100644 index 0000000..a187189 --- /dev/null +++ b/mod/brl.mod/random.mod/doc/rnd.bmx @@ -0,0 +1,19 @@ +' Rnd.bmx +' Use Rnd() to estimate area inside the unit circle x^2 + y^2 = 1. + +totalpoints = 1000000 + +For n = 1 to totalpoints + x! = Rnd( -1.0, 1.0 ) ' Generate random point in 2 by 2 square. + y! = Rnd( -1.0, 1.0 ) + + If x*x + y*y < 1.0 Then inpoints :+ 1 ' point is inside the circle +Next + +' Note: Ratio of areas circle/square is exactly Pi/4. + +Print "Estimated area = " + ( 4.0 * Double(inpoints)/Double(totalpoints) ) +Print +Print " Exact area = " + Pi ' 4 * Pi/4, compare with estimate + +Input ; End diff --git a/mod/brl.mod/random.mod/doc/rnddouble.bmx b/mod/brl.mod/random.mod/doc/rnddouble.bmx new file mode 100644 index 0000000..189b007 --- /dev/null +++ b/mod/brl.mod/random.mod/doc/rnddouble.bmx @@ -0,0 +1,25 @@ +' RndDouble.bmx +' Two players take turns shooting at a target. The first hit wins. +' Player 1 hits 30% of the time, player 2 hits 40%. +' What is the probability that player 1 wins? + +Function winner() ' play game once, return winner 1 or 2 + Repeat + If RndDouble() < 0.3 Then Return 1 + If RndDouble() < 0.4 Then Return 2 + Forever +End Function + +Local count[3] + +trials = 1000000 + +For n = 1 to trials + count[ winner() ] :+ 1 +Next + +Print "Estimated probability = " + ( Double( count[1] ) / Double( trials ) ) +Print +Print " Exact probability = " + ( 15.0 / 29.0 ) + +Input ; End \ No newline at end of file diff --git a/mod/brl.mod/random.mod/doc/rndfloat.bmx b/mod/brl.mod/random.mod/doc/rndfloat.bmx new file mode 100644 index 0000000..2bf3b0f --- /dev/null +++ b/mod/brl.mod/random.mod/doc/rndfloat.bmx @@ -0,0 +1,25 @@ +' RndFloat.bmx +' Two players take turns shooting at a target. The first hit wins. +' Player 1 hits 30% of the time, player 2 hits 40%. +' What is the probability that player 1 wins? + +Function winner() ' play game once, return winner 1 or 2 + Repeat + If RndFloat() < 0.3 Then Return 1 + If RndFloat() < 0.4 Then Return 2 + Forever +End Function + +Local count[3] + +trials = 1000000 + +For n = 1 to trials + count[ winner() ] :+ 1 +Next + +Print "Estimated probability = " + ( Float( count[1] ) / Float( trials ) ) +Print +Print " Exact probability = " + ( 15.0 / 29.0 ) + +Input ; End \ No newline at end of file diff --git a/mod/brl.mod/random.mod/doc/rndseed.bmx b/mod/brl.mod/random.mod/doc/rndseed.bmx new file mode 100644 index 0000000..b3950e6 --- /dev/null +++ b/mod/brl.mod/random.mod/doc/rndseed.bmx @@ -0,0 +1,20 @@ +' RndSeed.bmx and SeedRnd.bmx ( one example for both ) +' Get/Set random number seed. + +SeedRnd MilliSecs() + +seed=RndSeed() + +Print "Initial seed="+seed + +For k=1 To 10 +Print Rand(10) +Next + +Print "Restoring seed" + +SeedRnd seed + +For k=1 To 10 +Print Rand(10) +Next diff --git a/mod/brl.mod/random.mod/doc/seedrnd.bmx b/mod/brl.mod/random.mod/doc/seedrnd.bmx new file mode 100644 index 0000000..b3950e6 --- /dev/null +++ b/mod/brl.mod/random.mod/doc/seedrnd.bmx @@ -0,0 +1,20 @@ +' RndSeed.bmx and SeedRnd.bmx ( one example for both ) +' Get/Set random number seed. + +SeedRnd MilliSecs() + +seed=RndSeed() + +Print "Initial seed="+seed + +For k=1 To 10 +Print Rand(10) +Next + +Print "Restoring seed" + +SeedRnd seed + +For k=1 To 10 +Print Rand(10) +Next diff --git a/mod/brl.mod/random.mod/random.bmx b/mod/brl.mod/random.mod/random.bmx new file mode 100644 index 0000000..09276d3 --- /dev/null +++ b/mod/brl.mod/random.mod/random.bmx @@ -0,0 +1,102 @@ + +Strict + +Rem +bbdoc: Math/Random numbers +End Rem +Module BRL.Random + +ModuleInfo "Version: 1.05" +ModuleInfo "Author: Mark Sibly, Floyd" +ModuleInfo "License: zlib/libpng" +ModuleInfo "Copyright: Blitz Research Ltd" +ModuleInfo "Modserver: BRL" + +ModuleInfo "History: 1.05 Release" +ModuleInfo "History: Fixed Rand() with negative min value bug" + +Private +Global rnd_state=$1234 +Const RND_A=48271,RND_M=2147483647,RND_Q=44488,RND_R=3399 +Public + +Rem +bbdoc: Generate random float +returns: A random float in the range 0 (inclusive) to 1 (exclusive) +End Rem +Function RndFloat#() + rnd_state=RND_A*(rnd_state Mod RND_Q)-RND_R*(rnd_state/RND_Q) + If rnd_state<0 rnd_state=rnd_state+RND_M + Return (rnd_state & $ffffff0) / 268435456# 'divide by 2^28 +End Function + +Rem +bbdoc: Generate random double +returns: A random double in the range 0 (inclusive) to 1 (exclusive) +End Rem +Function RndDouble!() + Const TWO27! = 134217728.0 '2 ^ 27 + Const TWO29! = 536870912.0 '2 ^ 29 + + rnd_state=RND_A*(rnd_state Mod RND_Q)-RND_R*(rnd_state/RND_Q) + If rnd_state<0 rnd_state=rnd_state+RND_M + Local r_hi! = rnd_state & $1ffffffc + + rnd_state=RND_A*(rnd_state Mod RND_Q)-RND_R*(rnd_state/RND_Q) + If rnd_state<0 rnd_state=rnd_state+RND_M + Local r_lo! = rnd_state & $1ffffff8 + + Return (r_hi + r_lo/TWO27)/TWO29 +End Function + +Rem +bbdoc: Generate random double +returns: A random double in the range min (inclusive) to max (exclusive) +about: +The optional parameters allow you to use Rnd in 3 ways: + +[ @Format | @Result +* &Rnd() | Random double in the range 0 (inclusive) to 1 (exclusive) +* &Rnd(_x_) | Random double in the range 0 (inclusive) to n (exclusive) +* &Rnd(_x,y_) | Random double in the range x (inclusive) to y (exclusive) +] +End Rem +Function Rnd!( min_value!=1,max_value!=0 ) + If max_value>min_value Return RndDouble()*(max_value-min_value)+min_value + Return RndDouble()*(min_value-max_value)+max_value +End Function + +Rem +bbdoc: Generate random integer +returns: A random integer in the range min (inclusive) to max (inclusive) +about: +The optional parameter allows you to use #Rand in 2 ways: + +[ @Format | @Result +* &Rand(x) | Random integer in the range 1 to x (inclusive) +* &Rand(x,y) | Random integer in the range x to y (inclusive) +] +End Rem +Function Rand( min_value,max_value=1 ) + Local range=max_value-min_value + If range>0 Return Int( RndDouble()*(1+range) )+min_value + Return Int( RndDouble()*(1-range) )+max_value +End Function + +Rem +bbdoc: Set random number generator seed +End Rem +Function SeedRnd( seed ) + rnd_state=seed & $7fffffff 'enforces rnd_state >= 0 + If rnd_state=0 Or rnd_state=RND_M rnd_state=$1234 'disallow 0 and M +End Function + +Rem +bbdoc: Get random number generator seed +returns: The current random number generator seed +about: Use in conjunction with SeedRnd, RndSeed allows you to reproduce sequences of random +numbers. +End Rem +Function RndSeed() + Return rnd_state +End Function diff --git a/mod/brl.mod/reflection.mod/doc/intro.bbdoc b/mod/brl.mod/reflection.mod/doc/intro.bbdoc new file mode 100644 index 0000000..031ea36 --- /dev/null +++ b/mod/brl.mod/reflection.mod/doc/intro.bbdoc @@ -0,0 +1,77 @@ + ++Reflection + +BlitzMax provides limited support for a form of runtime %reflection. + +Using reflection, programs can 'inspect' objects and types at runtime. You can determine the fields and methods contained in an object or type, set and get object fields and invoke - or 'call' - object methods. + +To use reflection, you first need a TTypeId object. TTypeId objects correspond to BlitzMax user defined types, and there is a single TTypeId object for every user defined type in the program. There are also TTypeId objects for the 'primitive' types - byte, short, int, long, float, double and string. TTypeId objects are returned by the @TTypeId.ForName and @TTypeId.ForObject functions. + +Once you have a TTypeId object, you can inspect the fields and methods of a user defined type using the @EnumFields and @EnumMethods methods. These methods return @TField and @TMethod objects that describe the fields and methods within the type. For example: +{{ +Strict + +Type TMyType + Field x,y,z +End Type + +Local id:TTypeId=TTypeId.ForName( "TMyType" ) + +For Local fld:TField=EachIn id.EnumFields() + Print fld.Name()+":"+fld.TypeId().Name() +Next +}} +This simple program will print "x:Int", "y:Int" and "z:Int" - the names and types of the fields within TMyType. Note that this is done without actually creating a new TMyType. + +The following example sets the fields of an object: +{{ +Strict + +Type TMyType + Field x,y,z +End Type + +Local obj:TMyType=New TMyType +Local id:TTypeId=TTypeId.ForObject( obj ) + +For Local fld:TField=EachIn id.EnumFields() + fld.Set obj,String( Rand(10) ) +Next + +Print obj.x+","+obj.y+","+obj.z +}} +In this case we need an actual instance of TMyType, otherwise we have nothing to set the fields of! Also, we have used TTypeId.ForObject instead of TTypeId.ForName to get a TTypeId. While in this case TTypeId.ForName could have been used to achieve the same result, in general we may not know the exact type of the object, and therefore we wont know its type name. + +Also note that the code that actually sets the fields uses String( Rand(10) ). This is because the @Set method takes an object - but our fields are ints! BlitzMax reflection deals with this by using strings to represent numeric types. The same rule applies to the @Get method. Any numeric fields will be returned as strings which you must then convert to the appropriate type if necessary. + +Finally, let's invoke an object method: +{{ +Strict + +Type TMyType + Method Update( t# ) + Print "TMyType.Update:"+t + End Method +End Type + +Local obj:TMyType=New TMyType +Local id:TTypeId=TTypeId.ForObject( obj ) + +Local update:TMethod=id.FindMethod( "Update" ) + +update.Invoke obj,[String( .25 )] +}} +This example uses @FindMethod to locate a type method and @Invoke to call it. Arguments to the method are contained in an object array, and again the float argument is converted to a string. + +In addition to the TTypeId, TField and TMethod types, the BlitzMax reflection module also declares a number of global TTypeId objects: +[ +* @ByteTypeId +* @ShortTypeId +* @IntTypeId +* @LongTypeId +* @FloatTypeId +* @DoubleTypeId +* @StringTypeId +* @ObjectTypeId +] +These may be used instead of the corresponding TTypeId.ForName call. For example, @{TTypeId.ForName( "Int" )} and @IntTypeId will return the same object. diff --git a/mod/brl.mod/reflection.mod/reflection.bmx b/mod/brl.mod/reflection.mod/reflection.bmx new file mode 100644 index 0000000..72263aa --- /dev/null +++ b/mod/brl.mod/reflection.mod/reflection.bmx @@ -0,0 +1,831 @@ + +Strict + +Rem +bbdoc: BASIC/Reflection +End Rem +Module BRL.Reflection + +ModuleInfo "Version: 1.02" +ModuleInfo "Author: Mark Sibly" +ModuleInfo "License: zlib/libpng" +ModuleInfo "Copyright: Blitz Research Ltd" +ModuleInfo "Modserver: BRL" + +ModuleInfo "History: 1.02 Release" +ModuleInfo "History: Added Brucey's size fix to GetArrayElement()/SetArrayElement()." +ModuleInfo "History: 1.01 Release" +ModuleInfo "History: Fixed NewArray using temp type name" + +Import BRL.LinkedList +Import BRL.Map + +Import "reflection.cpp" + +Private + +Extern + +Function bbObjectNew:Object( class ) +Function bbObjectRegisteredTypes:Int Ptr( count Var ) + +Function bbArrayNew1D:Object( typeTag:Byte Ptr,length ) + + +Function bbRefArrayClass() +Function bbRefStringClass() +Function bbRefObjectClass() + +Function bbRefArrayLength( array:Object, dim:Int = 0 ) +Function bbRefArrayTypeTag$( array:Object ) +Function bbRefArrayDimensions:Int( array:Object ) +Function bbRefArrayCreate:Object( typeTag:Byte Ptr,dims:Int[] ) + +Function bbRefFieldPtr:Byte Ptr( obj:Object,index ) +Function bbRefMethodPtr:Byte Ptr( obj:Object,index ) +Function bbRefArrayElementPtr:Byte Ptr( sz,array:Object,index ) + +Function bbRefGetObject:Object( p:Byte Ptr ) +Function bbRefPushObject( p:Byte Ptr,obj:Object ) +Function bbRefInitObject( p:Byte Ptr,obj:Object ) +Function bbRefAssignObject( p:Byte Ptr,obj:Object ) + +Function bbRefGetObjectClass( obj:Object ) +Function bbRefGetSuperClass( class ) + +End Extern + +Type TClass + + Method Compare( with:Object ) + Return _class-TClass( with )._class + End Method + + Method SetClass:TClass( class ) + _class=class + Return Self + End Method + + Field _class +End Type + +Function _Get:Object( p:Byte Ptr,typeId:TTypeId ) + Select typeId + Case ByteTypeId + Return String.FromInt( (Byte Ptr p)[0] ) + Case ShortTypeId + Return String.FromInt( (Short Ptr p)[0] ) + Case IntTypeId + Return String.FromInt( (Int Ptr p)[0] ) + Case LongTypeId + Return String.FromLong( (Long Ptr p)[0] ) + Case FloatTypeId + Return String.FromFloat( (Float Ptr p)[0] ) + Case DoubleTypeId + Return String.FromDouble( (Double Ptr p)[0] ) + Default + Return bbRefGetObject( p ) + End Select +End Function + +Function _Push:Byte Ptr( sp:Byte Ptr,typeId:TTypeId,value:Object ) + Select typeId + Case ByteTypeId,ShortTypeId,IntTypeId + (Int Ptr sp)[0]=value.ToString().ToInt() + Return sp+4 + Case LongTypeId + (Long Ptr sp)[0]=value.ToString().ToLong() + Return sp+8 + Case FloatTypeId + (Float Ptr sp)[0]=value.ToString().ToFloat() + Return sp+4 + Case DoubleTypeId + (Double Ptr sp)[0]=value.ToString().ToDouble() + Return sp+8 + Case StringTypeId + If Not value value="" + bbRefPushObject sp,value + Return sp+4 + Default + If value + Local c=typeId._class + Local t=bbRefGetObjectClass( value ) + While t And t<>c + t=bbRefGetSuperClass( t ) + Wend + If Not t Throw "ERROR" + EndIf + bbRefPushObject sp,value + Return sp+4 + End Select +End Function + +Function _Assign( p:Byte Ptr,typeId:TTypeId,value:Object ) + Select typeId + Case ByteTypeId + (Byte Ptr p)[0]=value.ToString().ToInt() + Case ShortTypeId + (Short Ptr p)[0]=value.ToString().ToInt() + Case IntTypeId + (Int Ptr p)[0]=value.ToString().ToInt() + Case LongTypeId + (Long Ptr p)[0]=value.ToString().ToLong() + Case FloatTypeId + (Float Ptr p)[0]=value.ToString().ToFloat() + Case DoubleTypeId + (Double Ptr p)[0]=value.ToString().ToDouble() + Case StringTypeId + If Not value value="" + bbRefAssignObject p,value + Default + If value + Local c=typeId._class + Local t=bbRefGetObjectClass( value ) + While t And t<>c + t=bbRefGetSuperClass( t ) + Wend + If Not t Throw "ERROR" + EndIf + bbRefAssignObject p,value + End Select +End Function + +Function _Call:Object( p:Byte Ptr,typeId:TTypeId,obj:Object,args:Object[],argTypes:TTypeId[] ) + Local q[10],sp:Byte Ptr=q + bbRefPushObject sp,obj + sp:+4 + If typeId=LongTypeId sp:+8 + For Local i=0 Until args.length + If Int Ptr(sp)>=Int Ptr(q)+8 Throw "ERROR" + sp=_Push( sp,argTypes[i],args[i] ) + Next + If Int Ptr(sp)>Int Ptr(q)+8 Throw "ERROR" + Select typeId + Case ByteTypeId,ShortTypeId,IntTypeId + Local f(p0,p1,p2,p3,p4,p5,p6,p7)=p + Return String.FromInt( f( q[0],q[1],q[2],q[3],q[4],q[5],q[6],q[7] ) ) + Case LongTypeId + Throw "TODO" + Case FloatTypeId + Local f:Float(p0,p1,p2,p3,p4,p5,p6,p7)=p + Return String.FromFloat( f( q[0],q[1],q[2],q[3],q[4],q[5],q[6],q[7] ) ) + Case DoubleTypeId + Local f:Double(p0,p1,p2,p3,p4,p5,p6,p7)=p + Return String.FromDouble( f( q[0],q[1],q[2],q[3],q[4],q[5],q[6],q[7] ) ) + Default + Local f:Object(p0,p1,p2,p3,p4,p5,p6,p7)=p + Return f( q[0],q[1],q[2],q[3],q[4],q[5],q[6],q[7] ) + End Select +End Function + +Function TypeTagForId$( id:TTypeId ) + If id.ExtendsType( ArrayTypeId ) + Return "[]"+TypeTagForId( id.ElementType() ) + EndIf + If id.ExtendsType( ObjectTypeId ) + Return ":"+id.Name() + EndIf + Select id + Case ByteTypeId Return "b" + Case ShortTypeId Return "s" + Case IntTypeId Return "i" + Case LongTypeId Return "l" + Case FloatTypeId Return "f" + Case DoubleTypeId Return "d" + Case StringTypeId Return "$" + End Select + Throw "ERROR" +End Function + +Function TypeIdForTag:TTypeId( ty$ ) + If ty.StartsWith( "[" ) + Local dims:Int = ty.split(",").length + ty=ty[ty.Find("]")+1..] + Local id:TTypeId = TypeIdForTag( ty ) + If id Then + id._arrayType = Null + id=id.ArrayType(dims) + End If + Return id + EndIf + If ty.StartsWith( ":" ) + ty=ty[1..] + Local i=ty.FindLast( "." ) + If i<>-1 ty=ty[i+1..] + Return TTypeId.ForName( ty ) + EndIf + Select ty + Case "b" Return ByteTypeId + Case "s" Return ShortTypeId + Case "i" Return IntTypeId + Case "l" Return LongTypeId + Case "f" Return FloatTypeId + Case "d" Return DoubleTypeId + Case "$" Return StringTypeId + End Select +End Function + +Function ExtractMetaData$( meta$,key$ ) + If Not key Return meta + Local i=0 + While i 1 Then + For Local i:Int = 1 Until dims + dim :+ "," + Next + End If + _arrayType=New TTypeId.Init( _name+"[" + dim + "]",4,bbRefArrayClass() ) + _arrayType._elementType=Self + If _super + _arrayType._super=_super.ArrayType() + Else + _arrayType._super=ArrayTypeId + EndIf + EndIf + Return _arrayType + End Method + + Rem + bbdoc: Get element type + End Rem + Method ElementType:TTypeId() + Return _elementType + End Method + + Rem + bbdoc: Determine if type extends a type + End Rem + Method ExtendsType( typeId:TTypeId ) + If Self=typeId Return True + If _super Return _super.ExtendsType( typeId ) + End Method + + Rem + bbdoc: Get list of derived types + End Rem + Method DerivedTypes:TList() + If Not _derived _derived=New TList + Return _derived + End Method + + Rem + bbdoc: Create a new object + End Rem + Method NewObject:Object() + If Not _class Throw "Unable to create new object" + Return bbObjectNew( _class ) + End Method + + Rem + bbdoc: Get list of fields + about: Only returns fields declared in this type, not in super types. + End Rem + Method Fields:TList() + Return _fields + End Method + + Rem + bbdoc: Get list of methods + about: Only returns methods declared in this type, not in super types. + End Rem + Method Methods:TList() + Return _methods + End Method + + Rem + bbdoc: Find a field by name + about: Searchs type hierarchy for field called @name. + End Rem + Method FindField:TField( name$ ) + name=name.ToLower() + For Local t:TField=EachIn _fields + If t.Name().ToLower()=name Return t + Next + If _super Return _super.FindField( name ) + End Method + + Rem + bbdoc: Find a method by name + about: Searchs type hierarchy for method called @name. + End Rem + Method FindMethod:TMethod( name$ ) + name=name.ToLower() + For Local t:TMethod=EachIn _methods + If t.Name().ToLower()=name Return t + Next + If _super Return _super.FindMethod( name ) + End Method + + Rem + bbdoc: Enumerate all fields + about: Returns a list of all fields in type hierarchy + End Rem + Method EnumFields:TList( list:TList=Null ) + If Not list list=New TList + If _super _super.EnumFields list + For Local t:TField=EachIn _fields + list.AddLast t + Next + Return list + End Method + + Rem + bbdoc: Enumerate all methods + about: Returns a list of all methods in type hierarchy - TO DO: handle overrides! + End Rem + Method EnumMethods:TList( list:TList=Null ) + If Not list list=New TList + If _super _super.EnumMethods list + For Local t:TMethod=EachIn _methods + list.AddLast t + Next + Return list + End Method + + Rem + bbdoc: Create a new array + End Rem + Method NewArray:Object( length, dims:Int[] = Null ) + If Not _elementType Throw "TypeID is not an array type" + Local tag:Byte Ptr=_elementType._typeTag + If Not tag + tag=TypeTagForId( _elementType ).ToCString() + _elementType._typeTag=tag + EndIf + If Not dims Then + Return bbArrayNew1D( tag,length ) + Else + Return bbRefArrayCreate( tag, dims ) + End If + End Method + + Rem + bbdoc: Get array length + End Rem + Method ArrayLength( array:Object, dim:Int = 0 ) + If Not _elementType Throw "TypeID is not an array type" + Return bbRefArrayLength( array, dim ) + End Method + + Rem + bbdoc: Get the number of dimensions + End Rem + Method ArrayDimensions:Int( array:Object ) + If Not _elementType Throw "TypeID is not an array type" + Return bbRefArrayDimensions( array ) + End Method + + Rem + bbdoc: Get an array element + End Rem + Method GetArrayElement:Object( array:Object,index ) + If Not _elementType Throw "TypeID is not an array type" + Local p:Byte Ptr=bbRefArrayElementPtr( _elementType._size,array,index ) + Return _Get( p,_elementType ) + End Method + + Rem + bbdoc: Set an array element + End Rem + Method SetArrayElement( array:Object,index,value:Object ) + If Not _elementType Throw "TypeID is not an array type" + Local p:Byte Ptr=bbRefArrayElementPtr( _elementType._size,array,index ) + _Assign p,_elementType,value + End Method + + Rem + bbdoc: Get Type by name + End Rem + Function ForName:TTypeId( name$ ) + _Update + If name.EndsWith( "]" ) + ' TODO + name=name[..name.length-2] + Return TTypeId( _nameMap.ValueForKey( name.ToLower() ) ).ArrayType() + Else + Return TTypeId( _nameMap.ValueForKey( name.ToLower() ) ) + EndIf + End Function + + Rem + bbdoc: Get Type by object + End Rem + Function ForObject:TTypeId( obj:Object ) + _Update + Local class=bbRefGetObjectClass( obj ) + If class=ArrayTypeId._class + If Not bbRefArrayLength( obj ) Return ArrayTypeId + Return TypeIdForTag( bbRefArrayTypeTag( obj ) ).ArrayType() + Else + Return TTypeId( _classMap.ValueForKey( New TClass.SetClass( class ) ) ) + EndIf + End Function + + Rem + bbdoc: Get list of all types + End Rem + Function EnumTypes:TList() + _Update + Local list:TList=New TList + For Local t:TTypeId=EachIn _nameMap.Values() + list.AddLast t + Next + Return list + End Function + + '***** PRIVATE ***** + + Method Init:TTypeId( name$,size,class=0,supor:TTypeId=Null ) + _name=name + _size=size + _class=class + _super=supor + _fields=New TList + _methods=New TList + _nameMap.Insert _name.ToLower(),Self + If class _classMap.Insert New TClass.SetClass( class ),Self + Return Self + End Method + + Method SetClass:TTypeId( class ) + Local debug=(Int Ptr class)[2] + Local name$=String.FromCString( Byte Ptr( (Int Ptr debug)[1] ) ),meta$ + Local i=name.Find( "{" ) + If i<>-1 + meta=name[i+1..name.length-1] + name=name[..i] + EndIf + _name=name + _meta=meta + _class=class + _nameMap.Insert _name.ToLower(),Self + _classMap.Insert New TClass.SetClass( class ),Self + Return Self + End Method + + Function _Update() + Local count,p:Int Ptr=bbObjectRegisteredTypes( count ) + If count=_count Return + Local list:TList=New TList + For Local i=_count Until count + Local ty:TTypeId=New TTypeId.SetClass( p[i] ) + list.AddLast ty + Next + _count=count + For Local t:TTypeId=EachIn list + t._Resolve + Next + End Function + + Method _Resolve() + If _fields Or Not _class Return + + _fields=New TList + _methods=New TList + _super=TTypeId( _classMap.ValueForKey( New TClass.SetClass( (Int Ptr _class)[0] ) ) ) + If Not _super _super=ObjectTypeId + If Not _super._derived _super._derived=New TList + _super._derived.AddLast Self + + Local debug=(Int Ptr _class)[2] + Local p:Int Ptr=(Int Ptr debug)+2 + + While p[0] + Local id$=String.FromCString( Byte Ptr p[1] ) + Local ty$=String.FromCString( Byte Ptr p[2] ) + + Local meta$ + Local i=ty.Find( "{" ) + If i<>-1 + meta=ty[i+1..ty.length-1] + ty=ty[..i] + EndIf + + Select p[0] + Case 3 'field + Local typeId:TTypeId=TypeIdForTag( ty ) + If typeId _fields.AddLast New TField.Init( id,typeId,meta,p[3] ) + Case 6 'method + Local t$[]=ty.Split( ")" ) + Local retType:TTypeId=TypeIdForTag( t[1] ) + If retType + Local argTypes:TTypeId[] + If t[0].length>1 + Local i,b,q$=t[0][1..],args:TList=New TList + While i +#include + +extern "C"{ + +void *bbRefFieldPtr( BBObject *obj,int index ){ + return (char*)obj+index; +} + +void *bbRefMethodPtr( BBObject *obj,int index ){ + return *( (void**) ((char*)obj->clas+index) ); +} + +void *bbRefArrayElementPtr( int sz,BBArray *array,int index ){ + return (char*)BBARRAYDATA( array,array->dims )+sz*index; +} + +int bbRefArrayClass(){ + return (int)&bbArrayClass; +} + +int bbRefStringClass(){ + return (int)&bbStringClass; +} + +int bbRefObjectClass(){ + return (int)&bbObjectClass; +} + +int bbRefArrayLength( BBArray *array, int dim ){ + return array->scales[((dim <= array->dims)? dim : 0)]; +} + +int bbRefArrayDimensions( BBArray *array ){ + return array->dims; +} + +//Note: arrDims must be 1D int array... +BBArray *bbRefArrayCreate( const char *type,BBArray *arrDims ){ +// assert( arrDims->dims==1 ); +// assert( arrDims->type[0]=='i' ); + + int dims=arrDims->scales[0]; + int *lens=(int*)BBARRAYDATA( arrDims,1 ); + + return bbArrayNewEx( type,dims,lens ); +} + +BBString *bbRefArrayTypeTag( BBArray *array ){ + return bbStringFromCString( array->type ); +} + +BBObject *bbRefGetObject( BBObject **p ){ + return *p; +} + +void bbRefPushObject( BBObject **p,BBObject *t ){ + *p=t; +} + +void bbRefInitObject( BBObject **p,BBObject *t ){ + BBRETAIN( t ); + *p=t; +} + +void bbRefAssignObject( BBObject **p,BBObject *t ){ + BBRETAIN( t ); + BBRELEASE( *p ); + *p=t; +} + +BBClass *bbRefGetObjectClass( BBObject *p ){ + return p->clas; +} + +BBClass *bbRefGetSuperClass( BBClass *clas ){ + return clas->super; +} + +} diff --git a/mod/brl.mod/retro.mod/doc/intro.bbdoc b/mod/brl.mod/retro.mod/doc/intro.bbdoc new file mode 100644 index 0000000..1bac939 --- /dev/null +++ b/mod/brl.mod/retro.mod/doc/intro.bbdoc @@ -0,0 +1,14 @@ + +The BASIC compatibility module provides miscellaneous functions that emulate the behaviour +of 'classic' BASIC. + +The functions in this module have largely been superceded by BlitzMax features such as +'string slicing', and the Find, Replace, Trim, ToLower and ToUpper string methods. + +However, for programmers from a classic BASIC background, these utility functions should make +the transition to BlitzMax a little easier. + +NOTE: Strings in classic BASIC are '1 based'. This means that the first character within a +string is at index 1, the second at index 2 and so on. However, BlitzMax strings are '0 based', +meaning the first character is at index 0, the second at index 1 and so on. The #instr and +#Mid functions in this module retain the '1 based' behaviour of classic BASIC. diff --git a/mod/brl.mod/retro.mod/retro.bmx b/mod/brl.mod/retro.mod/retro.bmx new file mode 100644 index 0000000..3fd5a38 --- /dev/null +++ b/mod/brl.mod/retro.mod/retro.bmx @@ -0,0 +1,175 @@ + +Strict + +Rem +bbdoc: BASIC/BASIC compatibility +End Rem +Module BRL.Retro + +ModuleInfo "Version: 1.09" +ModuleInfo "Author: Mark Sibly" +ModuleInfo "License: zlib/libpng" +ModuleInfo "Copyright: Blitz Research Ltd" +ModuleInfo "Modserver: BRL" + +ModuleInfo "History: 1.09 Release" +ModuleInfo "History: Cleaned up Mid$" +ModuleInfo "History: 1.08 Release" +ModuleInfo "History: Deleted network stuff" + +Import BRL.Basic + +Rem +bbdoc: Extract substring from a string +returns: A sequence of characters from @str starting at position @pos and of length @size +about: +The Mid$ command returns a substring of a String. + +Given an existing string, a @position from the start of the string and +an optional @size, #Mid creates a new string equal to the section specified. +If no size if given, #Mid returns the characters in the existing string from +@position to the end of the string. + +For compatibility with classic BASIC, the @pos parameter is 'one based'. +End Rem +Function Mid$( str$,pos,size=-1 ) + If pos>Len( str ) Return Null + pos:-1 + If( size<0 ) Return str[pos..] + If pos<0 size=size+pos;pos=0 + If pos+size>Len( str ) size=Len( str )-pos + Return str[pos..pos+size] +End Function + +Rem +bbdoc: Find a string within a string +returns: The position within @str of the first matching occurance of @sub +about: +The @start parameter allows you to specifying a starting index for the search. + +For compatiblity with classic BASIC, the @start parameter and returned position +are both 'one based'. +End Rem +Function Instr( str$,sub$,start=1 ) + Return str.Find( sub,start-1 )+1 +End Function + +Rem +bbdoc: Extract characters from the beginning of a string +returns: @size leftmost characers of @str +about: +The Left$ command returns a substring of a String. +Given an existing String and a @size, Left$ returns the first @size +characters from the start of the String in a new String. +End Rem +Function Left$( str$,n ) + If n>Len(str) n=Len(str) + Return str[..n] +End Function + +Rem +bbdoc: Extract characters from the end of a string +returns: @size rightmost characters of @str +about: +The Right$ command returns a substring of a String. +Given an existing String and a @size, Right$ returns the last @size +characters from the end of the String. +End Rem +Function Right$( str$,n ) + If n>Len(str) n=Len(str) + Return str[Len(str)-n..] +End Function + +Rem +bbdoc: Left justify string +returns: A string of length @n, padded with spaces +endrem +Function LSet$( str$,n ) + Return str[..n] +End Function + +Rem +bbdoc: Right justify string +returns: A string of length @n, padded with spaces +endrem +Function RSet$( str$,n ) + Return str[Len(str)-n..] +End Function + +Rem +bbdoc: Performs a search and replace function +returns: A string with all instances of @sub$ replaced by @replace$ +about: +The Replace$ command replaces all instances of one string with another. +End Rem +Function Replace$( str$,sub$,replaceWith$ ) + Return str.Replace( sub,replaceWith ) +End Function + +Rem +bbdoc: Remove unprintable characters from ends a string +returns: @str with leading and trailing unprintable characters removed +End Rem +Function Trim$( str$ ) + Return str.Trim() +End Function + +Rem +bbdoc: Convert string to lowercase +returns: Lowercase equivalent of @str +End Rem +Function Lower$( str$ ) + Return str.ToLower() +End Function + +Rem +bbdoc: Convert string to uppercase +returns: Uppercase equivalent of @str +End Rem +Function Upper$( str$ ) + Return str.ToUpper() +End Function + +Rem +bbdoc: Convert an integer value to a hexadecimal string +returns: The hexadecimal string representation of @val +End Rem +Function Hex$( val ) + Local buf:Short[8] + For Local k=7 To 0 Step -1 + Local n=(val&15)+Asc("0") + If n>Asc("9") n=n+(Asc("A")-Asc("9")-1) + buf[k]=n + val:Shr 4 + Next + Return String.FromShorts( buf,8 ) +End Function + +Rem +bbdoc: Convert an integer value to a binary string +returns: The binary string representation of @val +End Rem +Function Bin$( val ) + Local buf:Short[32] + For Local k=31 To 0 Step -1 + buf[k]=(val&1)+Asc("0") + val:Shr 1 + Next + Return String.FromShorts( buf,32 ) +End Function + +Rem +bbdoc: Convert a 64 bit long integer value to a hexadecimal string +returns: The hexadecimal string representation of @val +End Rem +Function LongHex$( val:Long ) + Return Hex$( val Shr 32 )+Hex$( val ) +End Function + +Rem +bbdoc: Convert a 64 bit long integer value to a binary string +returns: The binary string representation of @val +End Rem +Function LongBin$( val:Long ) + Return Bin$( val Shr 32 )+Bin$( val ) +End Function diff --git a/mod/brl.mod/socket.mod/socket.bmx b/mod/brl.mod/socket.mod/socket.bmx new file mode 100644 index 0000000..3c00ab5 --- /dev/null +++ b/mod/brl.mod/socket.mod/socket.bmx @@ -0,0 +1,352 @@ + +Strict + +Rem +bbdoc: Networking/Sockets +End Rem +Module BRL.Socket + +ModuleInfo "Version: 1.02" +ModuleInfo "Author: Mark Sibly" +ModuleInfo "License: zlib/libpng" +ModuleInfo "Copyright: Blitz Research Ltd" +ModuleInfo "Modserver: BRL" + +ModuleInfo "History: 1.02 Release" +ModuleInfo "History: Fixed socket name 0 failing" + +Import Pub.StdC + +Private + +Extern "os" +?Win32 +Const FIONREAD=$4004667F +Function ioctl_( socket,opt,buf:Byte Ptr )="ioctlsocket@12" +?MacOS +Const FIONREAD=$4004667F +Function ioctl_( socket,opt,buf:Byte Ptr )="ioctl" +?Linux +Const FIONREAD=$541b +Function ioctl_( socket,opt,buf:Byte Ptr )="ioctl" +? +End Extern + +Public + +Type TSocketException + Method ToString$() + Return "Internal socket error" + End Method +End Type + +Type TSocket + + Method Send( buf:Byte Ptr,count,flags=0 ) + Local n=send_( _socket,buf,count,flags ) + If n<0 Return 0 + Return n + End Method + + Method Recv( buf:Byte Ptr,count,flags=0 ) + Local n=recv_( _socket,buf,count,flags ) + If n<0 Return 0 + Return n + End Method + + Method Close() + If _socket<0 Return + If _autoClose closesocket_ _socket + _socket=-1 + _localIp=-1 + _localPort=-1 + _remoteIp=-1 + _remotePort=-1 + End Method + + Method Connected() + If _socket<0 Return False + Local read=_socket + If select_( 1,Varptr read,0,Null,0,Null,0 )<>1 Or ReadAvail()<>0 Return True + Close + Return False + End Method + + Method Bind( localPort ) + If bind_( _socket,AF_INET_,localPort )<0 Return False + UpdateLocalName + Return True + End Method + + Method Connect( remoteIp,remotePort ) + Local addr=htonl_( remoteIp ) + If connect_( _socket,Varptr addr,AF_INET_,4,remotePort )<0 Return False + UpdateLocalName + UpdateRemoteName + Return True + End Method + + Method Listen( backlog ) + Return listen_( _socket,backlog )>=0 + End Method + + Method Accept:TSocket( timeout ) + Local read=_socket + If select_( 1,Varptr read,0,Null,0,Null,timeout )<>1 Return + Local client=accept_( _socket,Null,Null ) + If client>0 Return Create( client ) + End Method + + Method ReadAvail() + Local n + Local t=ioctl_( _socket,FIONREAD,Varptr n ) + If t<0 Return 0 + Return n + End Method + + Method SetTCPNoDelay( enable ) + Local flag=enable + setsockopt_( _socket,IPPROTO_TCP,TCP_NODELAY,Varptr flag,4 ) + End Method + + Method Socket() + Return _socket + End Method + + Method LocalIp() + Return _localIp + End Method + + Method LocalPort() + Return _localPort + End Method + + Method RemoteIp() + Return _remoteIp + End Method + + Method RemotePort() + Return _remotePort + End Method + + Method UpdateLocalName() + Local addr:Byte[16],size=16 + If getsockname_( _socket,addr,size )<0 + _localIp=0 + _localPort=0 + EndIf + _localIp=addr[4] Shl 24 | addr[5] Shl 16 | addr[6] Shl 8 | addr[7] + _localPort=addr[2] Shl 8 | addr[3] + End Method + + Method UpdateRemoteName() + Local addr:Byte[16],size=16 + If getpeername_( _socket,addr,size )<0 + _remoteIp=0 + _remotePort=0 + Return + EndIf + _remoteIp=addr[4] Shl 24 | addr[5] Shl 16 | addr[6] Shl 8 | addr[7] + _remotePort=addr[2] Shl 8 | addr[3] + End Method + + Function Create:TSocket( socket,autoClose=True ) + If socket<0 Return + Local addr:Byte[16],size + Local t:TSocket=New TSocket + t._socket=socket + t._autoClose=autoClose + t.UpdateLocalName + t.UpdateRemoteName + Return t + End Function + + Function CreateUDP:TSocket() + Local socket=socket_( AF_INET_,SOCK_DGRAM_,0 ) + If socket>=0 Return Create( socket,True ) + End Function + + Function CreateTCP:TSocket() + Local socket=socket_( AF_INET_,SOCK_STREAM_,0 ) + If socket>=0 Return Create( socket,True ) + End Function + + Field _socket,_autoClose + + Field _localIp,_localPort + Field _remoteIp,_remotePort + +End Type + +Rem +bbdoc: Create a UDP socket +returns: A new socket +about: +The new socket is not bound to any local or remote address. +End Rem +Function CreateUDPSocket:TSocket() + Return TSocket.CreateUDP() +End Function + +Rem +bbdoc: Create a TCP socket +returns: A new socket +about: +The new socket is not bound to any local or remote address. +End Rem +Function CreateTCPSocket:TSocket() + Return TSocket.CreateTCP() +End Function + +Rem +bbdoc: Close a socket +about: +All sockets should eventually be closed. Once closed, a socket can no longer +be used. +End Rem +Function CloseSocket( socket:TSocket ) + socket.Close +End Function + +Rem +bbdoc: Bind a socket to a local port +returns: True if successful, otherwise false +about: +If @localPort is 0, a new local port will be allocated. If @localPort is not 0, +#BindSocket will fail if there is already an application bound to @localPort. +End Rem +Function BindSocket( socket:TSocket,localPort ) + Return socket.Bind( localPort ) +End Function + +Rem +bbdoc: Connect a socket to a remote ip and port +returns: True if successful, otherwise false +about: +For both UDP and TCP sockets, #ConnectSocket will fail if the specified +ip address could not be reached. + +In the case of TCP sockets, #ConnectSocket will also fail if there is +no application listening at the remote port. +End Rem +Function ConnectSocket( socket:TSocket,remoteIp,remotePort ) + Return socket.Connect( remoteIp,remotePort ) +End Function + +Rem +bbdoc: Start listening at a socket +about: +The specified socket must be a TCP socket, and must already be bound to a local port. +End Rem +Function SocketListen( socket:TSocket,backlog=0 ) + Return socket.Listen( backlog ) +End Function + +Rem +bbdoc: Accept new connections on a listening socket +returns: A new socket, or Null if no connection was made in the specified timeout +about: +The specified socket must be a TCP socket, and must be listening. +End Rem +Function SocketAccept:TSocket( socket:TSocket,timeout=0 ) + Return socket.Accept( timeout ) +End Function + +Rem +bbdoc: Get socket connection status +returns: True if socket is connected +about: +#SocketConnected allows you to determine if a TCP connection is still +alive or has been remotely closed. + +#SocketConnected should only be used with TCP sockets that have already +connected via #ConnectSocket or #SocketAccept. +End Rem +Function SocketConnected( socket:TSocket ) + Return socket.Connected() +End Function + +Rem +bbdoc: Get number of bytes available for reading from a socket +returns: Number of bytes that may be read without causing the socket to block +End Rem +Function SocketReadAvail( socket:TSocket ) + Return socket.ReadAvail() +End Function + +Rem +bbdoc: Get local ip of a socket +End Rem +Function SocketLocalIP( socket:TSocket ) + Return socket.LocalIP() +End Function + +Rem +bbdoc: Get local port of a socket +End Rem +Function SocketLocalPort( socket:TSocket ) + Return socket.LocalPort() +End Function + +Rem +bbdoc: Get remote ip of a socket +End Rem +Function SocketRemoteIP( socket:TSocket ) + Return socket.RemoteIP() +End Function + +Rem +bbdoc: Get remote port of a socket +End Rem +Function SocketRemotePort( socket:TSocket ) + Return socket.RemotePort() +End Function + +Rem +bbdoc: Convert an ip address to a dotted string +returns: Dotted string version of ip address +End Rem +Function DottedIP$( ip ) + Return (ip Shr 24)+"."+(ip Shr 16 & 255)+"."+(ip Shr 8 & 255 )+"."+(ip & 255) +End Function + +Rem +bbdoc: Convert a host name to an ip address +returns: Host ip address, or 0 if host not found +End Rem +Function HostIp( HostName$,index=0 ) + If index<0 Return + Local ips[]=HostIps( HostName ) + If indexAF_INET_ Or addr_len<>4 Return + Local n + While addrs[n] + n:+1 + Wend + Local ips[n] + For Local i=0 Until n + Local p:Byte Ptr=addrs[i] + ips[i]=p[0] Shl 24 | p[1] Shl 16 | p[2] Shl 8 | p[3] + Next + Return ips +End Function + +Rem +bbdoc: Convert a host ip address to a name +returns: Name of host, or Null if host not found +End Rem +Function HostName$( HostIp ) + Local addr=htonl_( HostIp ) + Local p:Byte Ptr=gethostbyaddr_( Varptr addr,4,AF_INET_ ) + If p Return String.FromCString(p) +End Function diff --git a/mod/brl.mod/socketstream.mod/socketstream.bmx b/mod/brl.mod/socketstream.mod/socketstream.bmx new file mode 100644 index 0000000..1fecec8 --- /dev/null +++ b/mod/brl.mod/socketstream.mod/socketstream.bmx @@ -0,0 +1,107 @@ + +Strict + +Rem +bbdoc: Streams/Socket streams +End Rem +Module BRL.SocketStream + +ModuleInfo "Version: 1.05" +ModuleInfo "Author: Mark Sibly" +ModuleInfo "License: zlib/libpng" +ModuleInfo "Copyright: Blitz Research Ltd" +ModuleInfo "Modserver: BRL" + +ModuleInfo "History: 1.05 Release" +ModuleInfo "History: CreateStream port handling fix documented" +ModuleInfo "History: 1.04 Release" +ModuleInfo "History: TSocketStream now just wraps a TSocket" + +Import BRL.Socket +Import BRL.Stream + +Type TSocketStream Extends TStream + + Method Read( buf:Byte Ptr,count ) + Return _socket.Recv( buf,count ) + End Method + + Method Write( buf:Byte Ptr,count ) + Return _socket.Send( buf,count ) + End Method + + Method Eof() + If Not _socket Return True + If _socket.Connected() Return False + Close + Return True + End Method + + Method Close() + If Not _socket Return + If _autoClose _socket.Close + _socket=Null + End Method + + Method Socket:TSocket() + Return _socket + End Method + + Function Create:TSocketStream( socket:TSocket,autoClose=True ) + Local t:TSocketStream=New TSocketStream + t._socket=socket + t._autoClose=autoClose + Return t + End Function + + Function CreateClient:TSocketStream( remoteHost$,remotePort ) + Local remoteIp=HostIp( remoteHost ) + If Not remoteIp Return + + Local socket:TSocket=TSocket.CreateTCP() + If socket + If socket.Connect( remoteIp,remotePort ) + Return Create( socket,True ) + EndIf + socket.Close + EndIf + + End Function + + Field _socket:TSocket,_autoClose + +End Type + +Type TSocketStreamFactory Extends TStreamFactory + Method CreateStream:TSocketStream( url:Object,proto$,path$,readable,writeable ) + If proto$="tcp" + Local i=path.Find( ":",0 ),server$,port + If i>=0 Return TSocketStream.CreateClient( path[..i],Int(path[i+1..]) ) + Return TSocketStream.CreateClient( path,80 ) + EndIf + End Method +End Type + +New TSocketStreamFactory + +Rem +bbdoc: Create a socket stream +returns: A new socket stream +about: +A socket stream allows you to treat a socket as if it were a stream. + +If @autoClose is true, @socket will be automatically closed when the socket +stream is closed. Otherwise, it is up to you to somehow close @socket at +a later time. +End Rem +Function CreateSocketStream:TSocketStream( socket:TSocket,autoClose=True ) + Return TSocketStream.Create( socket,autoClose ) +End Function + +Rem +bbdoc: Get underlying socket from a socket stream +returns: The socket used to create the socket stream +End Rem +Function SocketStreamSocket:TSocket( stream:TSocketStream ) + Return stream.Socket() +End Function diff --git a/mod/brl.mod/standardio.mod/doc/input.bmx b/mod/brl.mod/standardio.mod/doc/input.bmx new file mode 100644 index 0000000..d80eb93 --- /dev/null +++ b/mod/brl.mod/standardio.mod/doc/input.bmx @@ -0,0 +1,6 @@ +Rem +Use the Input command to read user input from the console to a BlitzMax String. +End Rem + +name$=Input("What is your name") +print "Hello "+name diff --git a/mod/brl.mod/standardio.mod/doc/intro.bbdoc b/mod/brl.mod/standardio.mod/doc/intro.bbdoc new file mode 100644 index 0000000..7b8e1d8 --- /dev/null +++ b/mod/brl.mod/standardio.mod/doc/intro.bbdoc @@ -0,0 +1,3 @@ +The BlitzMax StandardIO module contains commands for reading and writing text to the standard IO (Input/Output) stream.
+
+The standard IO stream is generally connected to a 'console', allowing you to interact with an application in a very simple way. diff --git a/mod/brl.mod/standardio.mod/doc/print.bmx b/mod/brl.mod/standardio.mod/doc/print.bmx new file mode 100644 index 0000000..3db87dc --- /dev/null +++ b/mod/brl.mod/standardio.mod/doc/print.bmx @@ -0,0 +1,5 @@ +Rem +Use the Print command to output BlitzMax strings to the Console window. +End Rem + +Print "Hello World" \ No newline at end of file diff --git a/mod/brl.mod/standardio.mod/standardio.bmx b/mod/brl.mod/standardio.mod/standardio.bmx new file mode 100644 index 0000000..3070634 --- /dev/null +++ b/mod/brl.mod/standardio.mod/standardio.bmx @@ -0,0 +1,60 @@ + +Strict + +Rem +bbdoc: System/StandardIO +End Rem +Module BRL.StandardIO + +ModuleInfo "Version: 1.05" +ModuleInfo "Author: Mark Sibly" +ModuleInfo "License: zlib/libpng" +ModuleInfo "Copyright: Blitz Research Ltd" +ModuleInfo "Modserver: BRL" + +ModuleInfo "History: 1.05 Release" +ModuleInfo "History: 1.04 Release" +ModuleInfo "History: CStandardIO now goes through a UTF8 textstream" + +Import BRL.TextStream + +Type TCStandardIO Extends TStream + + Method Flush() + fflush_ stdout_ + End Method + + Method Read( buf:Byte Ptr,count ) + Return fread_( buf,1,count,stdin_ ) + End Method + + Method Write( buf:Byte Ptr,count ) + Return fwrite_( buf,1,count,stdout_ ) + End Method + +End Type + +Rem +bbdoc: BlitzMax Stream object used for Print and Input +about: The #Print and #Input commands can be redirected by setting the @StandardIOStream Global to an alternative Stream Object. +End Rem +Global StandardIOStream:TStream=TTextStream.Create( New TCStandardIO,TTextStream.UTF8 ) + +Rem +bbdoc: Write a string to the standard IO stream +about: A newline character is also written after @str. +End Rem +Function Print( str$="" ) + StandardIOStream.WriteLine str + StandardIOStream.Flush +End Function + +Rem +bbdoc: Receive a line of text from the standard IO stream +about: The optional @prompt is displayed before input is returned. +End Rem +Function Input$( prompt$=">" ) + StandardIOStream.WriteString prompt + StandardIOStream.Flush + Return StandardIOStream.ReadLine() +End Function diff --git a/mod/brl.mod/stream.mod/doc/intro.bbdoc b/mod/brl.mod/stream.mod/doc/intro.bbdoc new file mode 100644 index 0000000..0ffa0d6 --- /dev/null +++ b/mod/brl.mod/stream.mod/doc/intro.bbdoc @@ -0,0 +1,36 @@ + +Streams are used to read or write data in a sequential manner. + +BlitzMax supports many kinds of streams, including standard file streams +(for reading and writing to files), #{bank streams} (for reading and writing to banks) and +#{endian streams} (for swapping the byte order of stream data). + +Streams are usually created using #OpenStream, #ReadStream or #WriteStream. However, +some kinds of streams provide their own methods for creating streams. For example, banks +streams are created with the #CreateBankStream command. + +#OpenStream, #ReadStream and #WriteStream all require a %url parameter, which is used to +'locate' the stream. A url is usually a string value. + +If the url contains the string "::", then a stream %protocol is being specified. If not, +then the url is assumed to be a simple filename. + +External modules can add their own stream protocols to the system, allowing you to use streams +for a wide variety of purposes. For example, the "incbin::" protocol allows you to read data +from a binary file that has been embedded in an application using the #Incbin command. + +Other protocols include "http::" for reading and writing data over a network, and +"littleendian::" and "bigendian::" for swapping the byte order of streams. + +To write to a stream, use one of the 'Write' style commands, such as #WriteByte. + +To read from a stream, use one of the 'Read' style commands, such as #ReadByte. + +Some kinds of streams (for example, file streams and bank streams) support %{random access}. +This means that you can modify where in the stream the next read or write is to occur using +the #SeekStream command. You can also tell where you are in such streams using the +#StreamPos command. + +When you are finished with a stream, you should always close it using #CloseStream. +Failure to do so may result in a resource leak, or prevent the stream from successfully +opening in future. diff --git a/mod/brl.mod/stream.mod/doc/readstream.bmx b/mod/brl.mod/stream.mod/doc/readstream.bmx new file mode 100644 index 0000000..ed02f8f --- /dev/null +++ b/mod/brl.mod/stream.mod/doc/readstream.bmx @@ -0,0 +1,13 @@ +' readstream.bmx + +' opens a read stream to the blitzbasic.com website and +' dumps the homepage to the console using readline and print + +in=ReadStream("http::blitzbasic.com") + +If Not in RuntimeError "Failed to open a ReadStream to file http::www.blitzbasic.com" + +While Not Eof(in) + Print ReadLine(in) +Wend +CloseStream in diff --git a/mod/brl.mod/stream.mod/doc/writestream.bmx b/mod/brl.mod/stream.mod/doc/writestream.bmx new file mode 100644 index 0000000..241309c --- /dev/null +++ b/mod/brl.mod/stream.mod/doc/writestream.bmx @@ -0,0 +1,22 @@ +' writestream.bmx + +' opens a write stream to the file mygame.ini and +' outputs a simple text file using WriteLine + +out=WriteStream("mygame.ini") + +if not out RuntimeError "Failed to open a WriteStream to file mygame.ini" + +WriteLine out,"[display]" +WriteLine out,"width=800" +WriteLine out,"height=600" +WriteLine out,"depth=32" +WriteLine out,"" +WriteLine out,"[highscores]" +WriteLine out,"AXE=1000" +WriteLine out,"HAL=950" +WriteLine out,"MAK=920" + +CloseStream out + +print "File mygame.ini created, bytes="+FileSize("mygame.ini") \ No newline at end of file diff --git a/mod/brl.mod/stream.mod/stream.bmx b/mod/brl.mod/stream.mod/stream.bmx new file mode 100644 index 0000000..53fe1fd --- /dev/null +++ b/mod/brl.mod/stream.mod/stream.bmx @@ -0,0 +1,1138 @@ + +Strict + +Rem +bbdoc: Streams/Streams +End Rem +Module BRL.Stream + +ModuleInfo "Version: 1.09" +ModuleInfo "Author: Mark Sibly" +ModuleInfo "License: zlib/libpng" +ModuleInfo "Copyright: Blitz Research Ltd" +ModuleInfo "Modserver: BRL" + +ModuleInfo "History: 1.09 Release" +ModuleInfo "History: Fixed 'excpetion' typos" +ModuleInfo "History: 1.08 Release" +ModuleInfo "History: Fixed resource leak in CasedFileName" +ModuleInfo "History: 1.07 Release" +ModuleInfo "History: OpenStream protocol:: now case insensitive" +ModuleInfo "History: Fixed ReadString with 0 length strings" +ModuleInfo "History: Removed LoadStream - use LoadByteArray instead" +ModuleInfo "History: Removed AddStreamFactory function" +ModuleInfo "History: Added url parameter to TStreamFactory CreateStream method" +ModuleInfo "History: 1.06 Release" +ModuleInfo "History: Added checks to CStream for reading from write only stream and vice versa" +ModuleInfo "History: 1.05 Release" +ModuleInfo "History: Fixed Eof bug" +ModuleInfo "History: 1.04 Release" +ModuleInfo "History: Added LoadString" +ModuleInfo "History: Added LoadByteArray" +ModuleInfo "History: Cleaned up docs a bit" + +Import Pub.StdC + +Rem +bbdoc: Base exception type thrown by streams +End Rem +Type TStreamException +End Type + +Rem +bbdoc: Exception type thrown by streams in the event of read errors +about: +#TStreamReadException is usually thrown when a stream operation failed to read enough +bytes. For example, if the stream ReadInt method fails to read 4 bytes, it will throw +a #TStreamReadException. +End Rem +Type TStreamReadException Extends TStreamException + Method ToString$() + Return "Error reading from stream" + End Method +End Type + +Rem +bbdoc: Exception type thrown by streams in the event of write errors +about: +#TStreamWriteException is usually thrown when a stream operation failed to write enough +bytes. For example, if the stream WriteInt method fails to write 4 bytes, it will throw +a #TStreamWriteException. +End Rem +Type TStreamWriteException Extends TStreamException + Method ToString$() + Return "Error writing to stream" + End Method +End Type + +Rem +bbdoc: Base input/output type +about: +To create your own stream types, you should extend TStream and implement +at least these methods. + +You should also make sure your stream can handle multiple calls to the Close method. +End Rem +Type TIO + Rem + bbdoc: Get stream end of file status + returns: True for end of file reached, otherwise False + about: + For seekable streams such as file streams, Eof generally returns True if the file + position equals the file size. This means that no more bytes can be read from the + stream. However, it may still be possible to write bytes, in which case the file will + 'grow'. + + For communication type streams such as socket streams, Eof returns True if the stream + has been shut down for some reason - either locally or by the remote host. In this case, + no more bytes can be read from or written to the stream. + End Rem + Method Eof() + Return Pos()=Size() + End Method + + Rem + bbdoc: Get position of seekable stream + returns: Stream position as a byte offset, or -1 if stream is not seekable + End Rem + Method Pos() + Return -1 + End Method + + Rem + bbdoc: Get size of seekable stream + returns: Size, in bytes, of seekable stream, or 0 if stream is not seekable + End Rem + Method Size() + Return 0 + End Method + + Rem + bbdoc: Seek to position in seekable stream + returns: New stream position, or -1 if stream is not seekable + End Rem + Method Seek( pos ) + Return -1 + End Method + + Rem + bbdoc: Flush stream + about: + Flushes any internal stream buffers. + End Rem + Method Flush() + End Method + + Rem + bbdoc: Close stream + about: + Closes the stream after flushing any internal stream buffers. + End Rem + Method Close() + End Method + + Rem + bbdoc: Read at least 1 byte from a stream + returns: Number of bytes successfully read + about: + This method may 'block' if it is not possible to read at least one byte due to IO + buffering. + + If this method returns 0, the stream has reached end of file. + End Rem + Method Read( buf:Byte Ptr,count ) + RuntimeError "Stream is not readable" + Return 0 + End Method + + Rem + bbdoc: Write at least 1 byte to a stream + returns: Number of bytes successfully written + about: + This method may 'block' if it is not possible to write at least one byte due to IO + buffering. + + If this method returns 0, the stream has reached end of file. + End Rem + Method Write( buf:Byte Ptr,count ) + RuntimeError "Stream is not writeable" + Return 0 + End Method + + Method Delete() + Close + End Method + +End Type + +Rem +bbdoc: Data stream type +about: +#TStream extends #TIO to provide methods for reading and writing various types of values +to and from a stream. + +Note that methods dealing with strings - ReadLine, WriteLine, ReadString and WriteString - +assume that strings are represented by bytes in the stream. In future, a more powerful +TextStream type will be added capable of decoding text streams in multiple formats. +End Rem +Type TStream Extends TIO + + Rem + bbdoc: Reads bytes from a stream + about: + #ReadBytes reads @count bytes from the stream into the memory block specified by @buf. + + If @count bytes were not successfully read, a #TStreamReadException is thrown. This typically + occurs due to end of file. + End Rem + Method ReadBytes( buf:Byte Ptr,count ) + Local t=count + While count>0 + Local n=Read( buf,count ) + If Not n Throw New TStreamReadException + count:-n + buf:+n + Wend + Return t + End Method + + Rem + bbdoc: Writes bytes to a stream + about: + #WriteBytes writes @count bytes from the memory block specified by @buf to the stream. + + If @count bytes were not successfully written, a #TStreamWriteException is thrown. This typically + occurs due to end of file. + End Rem + Method WriteBytes( buf:Byte Ptr,count ) + Local t=count + While count>0 + Local n=Write( buf,count ) + If Not n Throw New TStreamWriteException + count:-n + buf:+n + Wend + Return t + End Method + + Rem + bbdoc: Skip bytes in a stream + about: + #SkipBytes read @count bytes from the stream and throws them away. + + If @count bytes were not successfully read, a #TStreamReadException is thrown. This typically + occurs due to end of file. + End Rem + Method SkipBytes( count ) + Local t=count + Local buf:Byte[1024] + While count>0 + Local n=Read( buf,Min(count,buf.length) ) + If Not n Throw New TStreamReadException + count:-n + Wend + Return t + End Method + + Rem + bbdoc: Read a byte from the stream + returns: The read value + about: + If a value could not be read (possibly due to end of file), a #TStreamReadException is thrown. + End Rem + Method ReadByte() + Local n:Byte + ReadBytes Varptr n,1 + Return n + End Method + + Rem + bbdoc: Write a byte to the stream + about: + If the value could not be written (possibly due to end of file), a #TStreamWriteException is thrown. + End Rem + Method WriteByte( n ) + Local q:Byte=n + WriteBytes Varptr q,1 + End Method + + Rem + bbdoc: Read a short (two bytes) from the stream + returns: The read value + about: + If a value could not be read (possibly due to end of file), a #TStreamReadException is thrown. + End Rem + Method ReadShort() + Local n:Short + ReadBytes Varptr n,2 + Return n + End Method + + Rem + bbdoc: Write a short (two bytes) to the stream + about: + If the value could not be written (possibly due to end of file), a #TStreamWriteException is thrown. + End Rem + Method WriteShort( n ) + Local q:Short=n + WriteBytes Varptr q,2 + End Method + + Rem + bbdoc: Read an int (four bytes) from the stream + returns: The read value + about: + If a value could not be read (possibly due to end of file), a #TStreamReadException is thrown. + End Rem + Method ReadInt() + Local n + ReadBytes Varptr n,4 + Return n + End Method + + Rem + bbdoc: Write an int (four bytes) to the stream + about: + If the value could not be written (possibly due to end of file), a #TStreamWriteException is thrown. + End Rem + Method WriteInt( n ) + Local q:Int=n + WriteBytes Varptr q,4 + End Method + + Rem + bbdoc: Read a long (eight bytes) from the stream + returns: The read value + about: + If a value could not be read (possibly due to end of file), a #TStreamReadException is thrown. + End Rem + Method ReadLong:Long() + Local n:Long + ReadBytes Varptr n,8 + Return n + End Method + + Rem + bbdoc: Write a long (eight bytes) to the stream + about: + If the value could not be written (possibly due to end of file), a #TStreamWriteException is thrown. + End Rem + Method WriteLong( n:Long ) + Local q:Long=n + WriteBytes Varptr q,8 + End Method + + Rem + bbdoc: Read a float (four bytes) from the stream + returns: The read value + about: + If a value could not be read (possibly due to end of file), a #TStreamReadException is thrown. + End Rem + Method ReadFloat#() + Local n# + ReadBytes Varptr n,4 + Return n + End Method + + Rem + bbdoc: Write a float (four bytes) to the stream + about: + If the value could not be written (possibly due to end of file), a #TStreamWriteException is thrown. + End Rem + Method WriteFloat( n# ) + Local q#=n + WriteBytes Varptr q,4 + End Method + + Rem + bbdoc: Read a double (eight bytes) from the stream + returns: The read value + about: + If a value could not be read (possibly due to end of file), a #TStreamReadException is thrown. + End Rem + Method ReadDouble!() + Local n! + ReadBytes Varptr n,8 + Return n + End Method + + Rem + bbdoc: Write a double (eight bytes) to the stream + about: + If the value could not be written (possibly due to end of file), a #TStreamWriteException is thrown. + End Rem + Method WriteDouble( n! ) + Local q!=n + WriteBytes Varptr q,8 + End Method + + Rem + bbdoc: Read a line of text from the stream + about: + Bytes are read from the stream until a newline character (ascii code 10) or null + character (ascii code 0) is read, or end of file is detected. + + Carriage return characters (ascii code 13) are silently ignored. + + The bytes read are returned in the form of a string, excluding any terminating newline + or null character. + End Rem + Method ReadLine$() + Local buf:Byte[1024],sz + Repeat + Local ch:Byte + If Read( Varptr ch,1 )<>1 Or ch=0 Or ch=10 Exit + If ch=13 Continue + If sz=buf.length buf=buf[..sz*2] + buf[sz]=ch + sz:+1 + Forever + Return String.FromBytes( buf,sz ) + End Method + + Rem + bbdoc: Write a line of text to the stream + returns: True if line successfully written, else False + about: A sequence of bytes is written to the stream (one for each character in @str) + followed by the line terminating sequence "~r~n". + End Rem + Method WriteLine( str$ ) + Local buf:Byte Ptr=str.ToCString() + Local ok=Write( buf,str.length )=str.length And Write( [13:Byte,10:Byte],2 )=2 + MemFree buf + Return ok + End Method + + Rem + bbdoc: Read characters from the stream + returns: A string composed of @length bytes read from the stream + about: + A #TStreamReadException is thrown if not all bytes could be read. + End Rem + Method ReadString$( length ) + Assert length>=0 Else "Illegal String length" + Local buf:Byte[length] + Readbytes buf,length + Return String.FromBytes( buf,length ) + End Method + + Rem + bbdoc: Write characters to the stream + about: + A #TStreamWriteException is thrown if not all bytes could be written. + End Rem + Method WriteString( str$ ) + Local buf:Byte Ptr=str.ToCString() + WriteBytes buf,str.length + MemFree buf + End Method + + Method ReadObject:Object() + Throw "Unable to read object" + End Method + + Method WriteObject( obj:Object ) + Throw "Unable to write object" + End Method + +End Type + +Rem +bbdoc: Utility stream wrapper type +about: +#TStreamWrapper 'wraps' an existing stream, redirecting all TIO method calls to the wrapped +stream. + +This can be useful for writing stream 'filters' that modify the behaviour of existing +streams. + +Note that the Close method causes the underlying stream to be closed, which may not always +be desirable. If necessary, you should override Close with a NOP version. +End Rem +Type TStreamWrapper Extends TStream + Field _stream:TStream + + Rem + bbdoc: Set underlying stream + about: + Sets the stream to be 'wrapped'. All calls to TIO methods of this stream will be + redirected to @stream. + end rem + Method SetStream( stream:TStream ) + _stream=stream + End Method + + Method Eof() + Return _stream.Eof() + End Method + + Method Pos() + Return _stream.Pos() + End Method + + Method Size() + Return _stream.Size() + End Method + + Method Seek( pos ) + Return _stream.Seek( pos ) + End Method + + Method Flush() + _stream.Flush + End Method + + Method Close() + _stream.Close + End Method + + Method Read( buf:Byte Ptr,count ) + Return _stream.Read( buf,count ) + End Method + + Method Write( buf:Byte Ptr,count ) + Return _stream.Write( buf,count ) + End Method + + Method ReadByte() + Return _stream.ReadByte() + End Method + + Method WriteByte( n ) + _stream.WriteByte n + End Method + + Method ReadShort() + Return _stream.ReadShort() + End Method + + Method WriteShort( n ) + _stream.WriteShort n + End Method + + Method ReadInt() + Return _stream.ReadInt() + End Method + + Method WriteInt( n ) + _stream.WriteInt n + End Method + + Method ReadFloat:Float() + Return _stream.ReadFloat() + End Method + + Method WriteFloat( n:Float ) + _stream.WriteFloat n + End Method + + Method ReadDouble:Double() + Return _stream.ReadDouble() + End Method + + Method WriteDouble( n:Double ) + _stream.WriteDouble n + End Method + + Method ReadLine$() + Return _stream.ReadLine() + End Method + + Method WriteLine( t$ ) + Return _stream.WriteLine( t ) + End Method + + Method ReadString$( n ) + Return _stream.ReadString( n ) + End Method + + Method WriteString( t$ ) + _stream.WriteString t + End Method + + Method ReadObject:Object() + Return _stream.ReadObject() + End Method + + Method WriteObject( obj:Object ) + _stream.WriteObject obj + End Method + +End Type + +Type TStreamStream Extends TStreamWrapper + + Method Close() + SetStream Null + End Method + + Function Create:TStreamStream( stream:TStream ) + Local t:TStreamStream=New TStreamStream + t.SetStream stream + Return t + End Function + +End Type + +Rem +bbdoc: Standard C file stream type +about: +End Rem +Type TCStream Extends TStream + + Const MODE_READ=1 + Const MODE_WRITE=2 + + Field _pos,_size,_cstream,_mode + + Method Pos() + Return _pos + End Method + + Method Size() + Return _size + End Method + + Method Seek( pos ) + Assert _cstream Else "Attempt to seek closed stream" + fseek_ _cstream,pos,SEEK_SET_ + _pos=ftell_( _cstream ) + Return _pos + End Method + + Method Read( buf:Byte Ptr,count ) + Assert _cstream Else "Attempt to read from closed stream" + Assert _mode & MODE_READ Else "Attempt to read from write-only stream" + count=fread_( buf,1,count,_cstream ) + _pos:+count + Return count + End Method + + Method Write( buf:Byte Ptr,count ) + Assert _cstream Else "Attempt to write to closed stream" + Assert _mode & MODE_WRITE Else "Attempt to write to read-only stream" + count=fwrite_( buf,1,count,_cstream ) + _pos:+count + If _pos>_size _size=_pos + Return count + End Method + + Method Flush() + If _cstream fflush_ _cstream + End Method + + Method Close() + If Not _cstream Return + Flush + fclose_ _cstream + _pos=0 + _size=0 + _cstream=0 + End Method + + Method Delete() + Close + End Method + + Rem + bbdoc: Create a TCStream from a 'C' filename + End Rem + Function OpenFile:TCStream( path$,readable,writeable ) + Local mode$,_mode + If readable And writeable + mode="r+b" + _mode=MODE_READ|MODE_WRITE + Else If writeable + mode="wb" + _mode=MODE_WRITE + Else + mode="rb" + _mode=MODE_READ + EndIf + path=path.Replace( "\","/" ) + Local cstream=fopen_( path,mode ) +?Linux + If (Not cstream) And (Not writeable) + path=CasedFileName(path) + If path cstream=fopen_( path,mode ) + EndIf +? + If cstream Return CreateWithCStream( cstream,_mode ) + End Function + + Rem + bbdoc: Create a TCStream from a 'C' stream handle + end rem + Function CreateWithCStream:TCStream( cstream,mode ) + Local stream:TCStream=New TCStream + stream._cstream=cstream + stream._pos=ftell_( cstream ) + fseek_ cstream,0,SEEK_END_ + stream._size=ftell_( cstream ) + fseek_ cstream,stream._pos,SEEK_SET_ + stream._mode=mode + Return stream + End Function + +End Type + +Private +Global stream_factories:TStreamFactory +Public + +Rem +bbdoc: Base stream factory type +about: +Stream factories are used by the #OpenStream, #ReadStream and #WriteStream functions +to create streams based on a 'url object'. + +Url objects are usually strings, in which case the url is divided into 2 parts - a +protocol and a path. These are separated by a double colon string - "::". + +To create your own stream factories, you should extend the TStreamFactory type and +implement the CreateStream method. + +To install your stream factory, simply create an instance of it using 'New'. +End Rem +Type TStreamFactory + Field _succ:TStreamFactory + + Method New() + _succ=stream_factories + stream_factories=Self + End Method + + Rem + bbdoc: Create a stream based on a url object + about: + Types which extends TStreamFactory must implement this method. + + @url contains the original url object as supplied to #OpenStream, #ReadStream or + #WriteStream. + + If @url is a string, @proto contains the url protocol - for example, the "incbin" part + of "incbin::myfile". + + If @url is a string, @path contains the remainder of the url - for example, the "myfile" + part of "incbin::myfile". + + If @url is not a string, both @proto and @path will be Null. + End Rem + Method CreateStream:TStream( url:Object,proto$,path$,readable,writeable ) Abstract + +End Type + +Rem +bbdoc: Open a stream for reading/writing +returns: A stream object +about: All streams created by #OpenStream, #ReadStream or #WriteStream should eventually be +closed using #CloseStream. +End Rem +Function OpenStream:TStream( url:Object,readable=True,writeable=True ) + + Local stream:TStream=TStream( url ) + If stream + Return TStreamStream.Create( stream ) + EndIf + + Local str$=String( url ),proto$,path$ + If str + Local i=str.Find( "::",0 ) + If i=-1 Return TCStream.OpenFile( str,readable,writeable ) + proto$=str[..i].ToLower() + path$=str[i+2..] + EndIf + + Local factory:TStreamFactory=stream_factories + + While factory + Local stream:TStream=factory.CreateStream( url,proto,path,readable,writeable ) + If stream Return stream + factory=factory._succ + Wend +End Function + +Rem +bbdoc: Open a stream for reading +returns: A stream object +about: All streams created by #OpenStream, #ReadStream or #WriteStream should eventually +be closed using #CloseStream. +End Rem +Function ReadStream:TStream( url:Object ) + Return OpenStream( url,True,False ) +End Function + +Rem +bbdoc: Open a stream for writing +returns: A stream object +about: All streams created by #OpenStream, #ReadStream or #WriteStream should eventually +be closed using #CloseStream. +End Rem +Function WriteStream:TStream( url:Object ) + Return OpenStream( url,False,True ) +End Function + +Rem +bbdoc: Get stream end of file status +returns: True If stream is at end of file +End Rem +Function Eof( stream:TStream ) + Return stream.Eof() +End Function + +Rem +bbdoc: Get current position of seekable stream +returns: Current stream position, or -1 If stream is not seekable +End Rem +Function StreamPos( stream:TStream ) + Return stream.Pos() +End Function + +Rem +bbdoc: Get current size of seekable stream +returns: Current stream size in bytes, or -1 If stream is not seekable +End Rem +Function StreamSize( stream:TStream ) + Return stream.Size() +End Function + +Rem +bbdoc: Set stream position of seekable stream +returns: New stream position, or -1 If stream is not seekable +End Rem +Function SeekStream( stream:TStream,pos ) + Return stream.Seek( pos ) +End Function + +Rem +bbdoc: Flush a stream +about: #FlushStream writes any outstanding buffered data to @stream. +End Rem +Function FlushStream( stream:TStream ) + stream.Flush +End Function + +Rem +bbdoc: Close a stream +about: +All streams should be closed when they are no longer required. +Closing a stream also flushes the stream before it closes. +End Rem +Function CloseStream( stream:TStream ) + stream.Close +End Function + +Rem +bbdoc: Read a Byte from a stream +returns: A Byte value +about: #ReadByte reads a single Byte from @stream. +A TStreamReadException is thrown If there is not enough data available. +End Rem +Function ReadByte( stream:TStream ) + Return stream.ReadByte() +End Function + +Rem +bbdoc: Read a Short from a stream +returns: A Short value +about: #ReadShort reads 2 bytes from @stream. +A TStreamReadException is thrown If there is not enough data available. +End Rem +Function ReadShort( stream:TStream ) + Return stream.ReadShort() +End Function + +Rem +bbdoc: Read an Int from a stream +returns: An Int value +about: #ReadInt reads 4 bytes from @stream. +A TStreamReadException is thrown If there is not enough data available. +End Rem +Function ReadInt( stream:TStream ) + Return stream.ReadInt() +End Function + +Rem +bbdoc: Read a Long from a stream +returns: A Long value +about: #ReadLong reads 8 bytes from @stream. +A TStreamReadException is thrown If there is not enough data available. +End Rem +Function ReadLong:Long( stream:TStream ) + Return stream.ReadLong() +End Function + +Rem +bbdoc: Read a Float from a stream +returns: A Float value +about: #ReadFloat reads 4 bytes from @stream. +A TStreamReadException is thrown If there is not enough data available. +End Rem +Function ReadFloat#( stream:TStream ) + Return stream.ReadFloat() +End Function + +Rem +bbdoc: Read a Double from a stream +returns: A Double value +about: #ReadDouble reads 8 bytes from @stream. +A TStreamWriteException is thrown If there is not enough data available. +End Rem +Function ReadDouble!( stream:TStream ) + Return stream.ReadDouble() +End Function + +Rem +bbdoc: Write a Byte to a stream +about: #WriteByte writes a single Byte to @stream. +A TStreamWriteException is thrown If the Byte could Not be written +End Rem +Function WriteByte( stream:TStream,n ) + stream.WriteByte n +End Function + +Rem +bbdoc: Write a Short to a stream +about: #WriteShort writes 2 bytes to @stream. +A TStreamWriteException is thrown if not all bytes could be written +End Rem +Function WriteShort( stream:TStream,n ) + stream.WriteShort n +End Function + +Rem +bbdoc: Write an Int to a stream +about: #WriteInt writes 4 bytes to @stream. +A TStreamWriteException is thrown if not all bytes could be written +End Rem +Function WriteInt( stream:TStream,n ) + stream.WriteInt n +End Function + +Rem +bbdoc: Write a Long to a stream +about: #WriteLong writes 8 bytes to @stream. +A TStreamWriteException is thrown if not all bytes could be written +End Rem +Function WriteLong( stream:TStream,n:Long ) + stream.WriteLong n +End Function + +Rem +bbdoc: Write a Float to a stream +about: #WriteFloat writes 4 bytes to @stream. +A TStreamWriteException is thrown if not all bytes could be written +End Rem +Function WriteFloat( stream:TStream,n# ) + stream.WriteFloat n +End Function + +Rem +bbdoc: Write a Double to a stream +about: #WriteDouble writes 8 bytes to @stream. +A TStreamWriteException is thrown if not all bytes could be written +End Rem +Function WriteDouble( stream:TStream,n! ) + stream.WriteDouble n +End Function + +Rem +bbdoc: Read a String from a stream +returns: A String of length @length +about: +A #TStreamReadException is thrown if not all bytes could be read. +end rem +Function ReadString$( stream:TStream,length ) + Return stream.ReadString( length ) +End Function + +Rem +bbdoc: Write a String to a stream +about: +Each character in @str is written to @stream. + +A #TStreamWriteException is thrown if not all bytes could be written. +End Rem +Function WriteString( stream:TStream,str$ ) + stream.WriteString str +End Function + +Rem +bbdoc: Read a line of text from a stream +returns: A string +about: +Bytes are read from @stream until a newline character (ascii code 10) or null +character (ascii code 0) is read, or end of file is detected. + +Carriage Return characters (ascii code 13) are silently ignored. + +The bytes read are returned in the form of a string, excluding any terminating newline +or null character. +End Rem +Function ReadLine$( stream:TStream ) + Return stream.ReadLine() +End Function + +Rem +bbdoc: Write a line of text to a stream +returns: True if line successfully written, else False +about: +A sequence of bytes is written to the stream (one for each character in @str) +followed by the line terminating sequence "~r~n". +End Rem +Function WriteLine( stream:TStream,str$ ) + Return stream.WriteLine( str ) +End Function + +Rem +bbdoc: Load a String from a stream +returns: A String +about: +The specified @url is opened for reading, and each byte in the resultant stream +(until eof of file is reached) is read into a string. + +A #TStreamReadException is thrown if the stream could not be read. +End Rem +Function LoadString$( url:Object ) + Local t:Byte[]=LoadByteArray(url) + Return String.FromBytes( t,t.length ) +End Function + +Rem +bbdoc: Save a String to a stream +about: +The specified @url is opened For writing, and each character of @str is written to the +resultant stream. + +A #TStreamWriteException is thrown if not all bytes could be written. +End Rem +Function SaveString( str$,url:Object ) + Local stream:TStream=WriteStream( url ) + If Not stream Throw New TStreamWriteException + Local t:Byte Ptr=str.ToCString() + stream.WriteBytes t,str.length 'Should be in a try block...or t is leaked! + MemFree t + stream.Close +End Function + +Function LoadObject:Object( url:Object ) + Local stream:TStream=ReadStream( url ) + If Not stream Throw New TStreamReadException + Local obj:Object=stream.ReadObject() + stream.Close + Return obj +End Function + +Function SaveObject( obj:Object,url:Object ) + Local stream:TStream=WriteStream( url ) + If Not stream Throw New TStreamWriteException + stream.WriteObject obj + stream.Close +End Function + +Rem +bbdoc: Load a Byte array from a stream +returns: A Byte array +about: +The specified @url is opened for reading, and each byte in the resultant stream +(until eof of reached) is read into a byte array. +End Rem +Function LoadByteArray:Byte[]( url:Object ) + Local stream:TStream=ReadStream( url ) + If Not stream Throw New TStreamReadException + Local data:Byte[1024],size + While Not stream.Eof() + If size=data.length data=data[..size*3/2] + size:+stream.Read( (Byte Ptr data)+size,data.length-size ) + Wend + stream.Close + Return data[..size] +End Function + +Rem +bbdoc: Save a Byte array to a stream +about: +The specified @url is opened For writing, and each element of @byteArray is written to the +resultant stream. + +A #TStreamWriteException is thrown if not all bytes could be written. +End Rem +Function SaveByteArray( byteArray:Byte[],url:Object ) + Local stream:TStream=WriteStream( url ) + If Not stream Throw New TStreamWriteException + stream.WriteBytes byteArray,byteArray.length + stream.Close +End Function + +Rem +bbdoc: Copy stream contents to another stream +about: +#CopyStream copies bytes from @fromStream to @toStream Until @fromStream reaches end +of file. + +A #TStreamWriteException is thrown if not all bytes could be written. +End Rem +Function CopyStream( fromStream:TStream,toStream:TStream,bufSize=4096 ) + Assert bufSize>0 + Local buf:Byte[bufSize] + While Not fromStream.Eof() + toStream.WriteBytes buf,fromStream.Read( buf,bufSize ) + Wend +End Function + +Rem +bbdoc: Copy bytes from one stream to another +about: +#CopyBytes copies @count bytes from @fromStream to @toStream. + +A #TStreamReadException is thrown if not all bytes could be read, and a +#TStreamWriteException is thrown if not all bytes could be written. +End Rem +Function CopyBytes( fromStream:TStream,toStream:TStream,count,bufSize=4096 ) + Assert count>=0 And bufSize>0 + Local buf:Byte[bufSize] + While count + Local n=Min(count,bufSize) + fromStream.ReadBytes buf,n + toStream.WriteBytes buf,n + count:-n + Wend +End Function + +Rem +bbdoc: Returns a case sensitive filename if it exists from a case insensitive file path. +End Rem +Function CasedFileName$(path$) + Local dir,sub$,s$,f$,folder$,p + Local mode,size,mtime,ctime + + If stat_( path,mode,size,mtime,ctime )=0 + mode:&S_IFMT_ + If mode=S_IFREG_ Or mode=S_IFDIR_ Return path + EndIf + folder$="." + For p=Len(path)-2 To 0 Step -1 + If path[p]=47 Exit + Next + If p>0 + sub=path[0..p] + sub$=CasedFileName(sub$) + If Not sub$ Return + path=path$[Len(sub)+1..] + folder$=sub + EndIf + s=path.ToLower() + dir=opendir_(folder) + If dir + While True + f=readdir_(dir) + If Not f Exit + If s=f.ToLower() + If sub f=sub+"/"+f + closedir_(dir) + Return f + EndIf + Wend + closedir_(dir) + EndIf +End Function diff --git a/mod/brl.mod/system.mod/doc/confirm.bmx b/mod/brl.mod/system.mod/doc/confirm.bmx new file mode 100644 index 0000000..ab4f752 --- /dev/null +++ b/mod/brl.mod/system.mod/doc/confirm.bmx @@ -0,0 +1,5 @@ +' confirm.bmx + +result=Confirm("Are you sure?") + +print result diff --git a/mod/brl.mod/system.mod/doc/createtimer.bmx b/mod/brl.mod/system.mod/doc/createtimer.bmx new file mode 100644 index 0000000..3c30e45 --- /dev/null +++ b/mod/brl.mod/system.mod/doc/createtimer.bmx @@ -0,0 +1,14 @@ +Rem +The following BlitzMax program prints a new line to the console 5 times a second. +End Rem + +' testtimer.bmx + +t=createtimer(5) +frame=0 + +for i=1 to 10 + waittimer(t) + print frame + frame:+1 +next diff --git a/mod/brl.mod/system.mod/doc/currentdate.bmx b/mod/brl.mod/system.mod/doc/currentdate.bmx new file mode 100644 index 0000000..b74d186 --- /dev/null +++ b/mod/brl.mod/system.mod/doc/currentdate.bmx @@ -0,0 +1,3 @@ +' currentdate.bmx + +Print "The date is "+CurrentDate$() diff --git a/mod/brl.mod/system.mod/doc/currenttime.bmx b/mod/brl.mod/system.mod/doc/currenttime.bmx new file mode 100644 index 0000000..8bed200 --- /dev/null +++ b/mod/brl.mod/system.mod/doc/currenttime.bmx @@ -0,0 +1,3 @@ +' currenttime.bmx + +Print "The time is "+CurrentTime$() diff --git a/mod/brl.mod/system.mod/doc/delay.bmx b/mod/brl.mod/system.mod/doc/delay.bmx new file mode 100644 index 0000000..1cbfff4 --- /dev/null +++ b/mod/brl.mod/system.mod/doc/delay.bmx @@ -0,0 +1,11 @@ +Rem +The following BlitzMax program prints a new line to the console 10 times a second. +End Rem + +' testtimer.bmx + +for i=1 to 10 + print frame + frame:+1 + delay 100 +next diff --git a/mod/brl.mod/system.mod/doc/intro.bbdoc b/mod/brl.mod/system.mod/doc/intro.bbdoc new file mode 100644 index 0000000..ca02bcc --- /dev/null +++ b/mod/brl.mod/system.mod/doc/intro.bbdoc @@ -0,0 +1,8 @@ + +The system module's primary function is to provide synchronization with the operating system. + +This achieved through the #PollSystem and #WaitSystem commands. However, you don't usually +have to call these commands yourself as other BlitzMax commands will call them when necessary. + +In addition, the system module also provides commands for checking the date and time, for moving +the mouse pointer and for generating simple system requesters. diff --git a/mod/brl.mod/system.mod/doc/millisecs.bmx b/mod/brl.mod/system.mod/doc/millisecs.bmx new file mode 100644 index 0000000..e18916e --- /dev/null +++ b/mod/brl.mod/system.mod/doc/millisecs.bmx @@ -0,0 +1,9 @@ +Rem +Millisecs is useful for seeding the random number generator. +End Rem + +seedrnd(millisecs()) + +for i=1 to 10 + print rnd() +next diff --git a/mod/brl.mod/system.mod/doc/notify.bmx b/mod/brl.mod/system.mod/doc/notify.bmx new file mode 100644 index 0000000..dee455b --- /dev/null +++ b/mod/brl.mod/system.mod/doc/notify.bmx @@ -0,0 +1,3 @@ +' notify.bmx + +Notify "Hello World" diff --git a/mod/brl.mod/system.mod/doc/proceed.bmx b/mod/brl.mod/system.mod/doc/proceed.bmx new file mode 100644 index 0000000..119ecde --- /dev/null +++ b/mod/brl.mod/system.mod/doc/proceed.bmx @@ -0,0 +1,5 @@ +' proceed.bmx + +result=Proceed("Are you sure you want to continue?") + +print result diff --git a/mod/brl.mod/system.mod/doc/requestdir.bmx b/mod/brl.mod/system.mod/doc/requestdir.bmx new file mode 100644 index 0000000..fe577f6 --- /dev/null +++ b/mod/brl.mod/system.mod/doc/requestdir.bmx @@ -0,0 +1,5 @@ +' requestdir.bmx + +path$=RequestDir("Select a Folder",CurrentDir()) + +Print "directory selected was "+path diff --git a/mod/brl.mod/system.mod/doc/requestfile.bmx b/mod/brl.mod/system.mod/doc/requestfile.bmx new file mode 100644 index 0000000..11a3d8b --- /dev/null +++ b/mod/brl.mod/system.mod/doc/requestfile.bmx @@ -0,0 +1,6 @@ +' requestfile.bmx + +filter$="Image Files:png,jpg,bmp;Text Files:txt;All Files:*" +filename$=RequestFile( "Select graphic file to open",filter$ ) + +Print filename diff --git a/mod/brl.mod/system.mod/doc/waittimer.bmx b/mod/brl.mod/system.mod/doc/waittimer.bmx new file mode 100644 index 0000000..0cd753e --- /dev/null +++ b/mod/brl.mod/system.mod/doc/waittimer.bmx @@ -0,0 +1,4 @@ +Rem + WaitTimer( timer:TSyncTimer ) +Waits for a timer to trigger. +End Rem diff --git a/mod/brl.mod/system.mod/driver.bmx b/mod/brl.mod/system.mod/driver.bmx new file mode 100644 index 0000000..2295697 --- /dev/null +++ b/mod/brl.mod/system.mod/driver.bmx @@ -0,0 +1,22 @@ + +Strict + +Type TSystemDriver + + Method Poll() Abstract + Method Wait() Abstract + + Method MoveMouse( x,y ) Abstract + Method SetMouseVisible( visible ) Abstract + + Method Notify( text$,serious ) Abstract + Method Confirm( text$,serious ) Abstract + Method Proceed( text$,serious ) Abstract + Method RequestFile$( text$,exts$,save,file$ ) Abstract + Method RequestDir$( text$,path$ ) Abstract + + Method OpenURL( url$ ) Abstract + +End Type + +Global Driver:TSystemDriver diff --git a/mod/brl.mod/system.mod/system.bmx b/mod/brl.mod/system.mod/system.bmx new file mode 100644 index 0000000..2a6f626 --- /dev/null +++ b/mod/brl.mod/system.mod/system.bmx @@ -0,0 +1,312 @@ + +Strict + +Rem +bbdoc: System/System +End Rem +Module BRL.System + +ModuleInfo "Version: 1.26" +ModuleInfo "Author: Mark Sibly, Simon Armstrong" +ModuleInfo "License: zlib/libpng" +ModuleInfo "Copyright: Blitz Research Ltd" +ModuleInfo "Modserver: BRL" + +ModuleInfo "History: Moved event enums from system.h to event.mod/event.h" +ModuleInfo "Histroy: Moved keycode enums from system.h to keycodes.mod/keycodes.h" +ModuleInfo "History: 1.26 Release" +ModuleInfo "History: Fixed win32 filerequester causing activewindow dramas" +ModuleInfo "History: 1.25 Release" +ModuleInfo "History: Fixed unretained object issue with mouse tracking" +ModuleInfo "History: 1.24 Release" +ModuleInfo "History: Fixed windowed mode HideMouse issue" +ModuleInfo "History: 1.23 Release" +ModuleInfo "History: Fixed win32 requestfile default extension bug#2" +ModuleInfo "History: 1.22 Release" +ModuleInfo "History: Fixed win32 requestfile default extension bug" +ModuleInfo "History: 1.21 Release" +ModuleInfo "History: New Linux implementation of OpenURL" +ModuleInfo "History: 1.20 Release" +ModuleInfo "History: RequestFile now adds extension to filename on Windows" +ModuleInfo "History: 1.19 Release" +ModuleInfo "History: Added EVENT_GADGETLOSTFOCUS handling" +ModuleInfo "History: 1.18 Release" +ModuleInfo "History: Added EVENT_KEYREPEAT handling" +ModuleInfo "History: 1.17 Release" +ModuleInfo "History: OpenURL now attempts to fully qualify file / http url supplied" +ModuleInfo "History: 1.16 Release" +ModuleInfo "History: Fixed MacOS RequestFile to respect wild card filter" +ModuleInfo "History: 1.15 Release" +ModuleInfo "History: Fixed mouse hidden by default" +ModuleInfo "History: 1.14 Release" +ModuleInfo "History: Fixed HideMouse causing mouse to disappear when in non-client areas" +ModuleInfo "History: 1.13 Release" +ModuleInfo "History: Fixed Linux MoveMouse to be relative to the origin of the current Graphics window" +ModuleInfo "History: 1.12 Release" +ModuleInfo "History: Added Linux X11 import to remove glgraphics.mod dependency" +ModuleInfo "History: Fixed linux middle button crash" +ModuleInfo "History: 1.11 Release" +ModuleInfo "History: Fixed win32 clipboard glitches with QS_ALLINPUT bbSystemWait mod" +ModuleInfo "History: 1.11 Release" +ModuleInfo "History: CGSetLocalEventsSuppressionInterval fix for MacOS bbSystemMoveMouse" +ModuleInfo "History: 1.10 Release" +ModuleInfo "History: Ripped out input stuff and added hook" +ModuleInfo "History: 1.09 Release" +ModuleInfo "History: Tweaked MacOS GetChar()" +ModuleInfo "History: 1.07 Release" +ModuleInfo "History: Added AppTitle support for requesters" +ModuleInfo "History: 1.06 Release" +ModuleInfo "History: Fixed MacOS RequestDir ignoring initial path" +ModuleInfo "History: 1.05 Release" +ModuleInfo "History: Added RequestDir support for MacOS" +ModuleInfo "History: 1.04 Release" +ModuleInfo "History: Added mouse capture to Win32" +ModuleInfo "History: Fixed C Compiler warnings" + +Import BRL.Event +Import BRL.KeyCodes +Import BRL.Hook +Import BRL.FileSystem +Import Pub.StdC + +Import "driver.bmx" + +Import "system.c" + +?MacOS +Import "system.macos.bmx" +Driver=New TMacOSSystemDriver +?Win32 +Import "system.win32.bmx" +Import "-lcomdlg32" +Driver=New TWin32SystemDriver +?Linux +Import "-lX11" +Import "system.linux.bmx" +Driver=New TLinuxSystemDriver +? + +Private + +Global _busy + +Public + +Rem +bbdoc: Poll operating system +about: +#PollSystem returns control back to the operating system, allowing such +events as keystrokes and gadget actions to be processed. Control is then +returned back to your program. + +If #PollSystem encounters a key, mouse or app suspend/resume/terminate +event, an equivalent #TEvent object event will be generated which may be intercepted using +the #EmitEventHook hook. +End Rem +Function PollSystem() + If _busy Return + _busy=True + Driver.Poll + _busy=False +End Function + +Rem +bbdoc: Wait for operating system +about: +#WaitSystem returns control back to the operating system, waiting until +an event such as a keystroke or gadget action occurs. + +Note that #WaitSystem may wait indefinitely if there is no possibility +of any events occuring, so use with caution. + +If #WaitSystem encounters a key, mouse or app suspend/resume/terminate +event, an equivalent #TEvent object will be generated which may be intercepted using +the #EmitEventHook hook. +End Rem +Function WaitSystem() + If _busy Return + _busy=True + Driver.Wait + _busy=False +End Function + +Rem +bbdoc: Get current date +returns: The current date as a string +about: +Returns the current date in the format: DD MON YYYY (i.e. 10 DEC 2000). +End Rem +Function CurrentDate$() + Local time[256],buff:Byte[256] + time_(time) + strftime_(buff,256,"%d %b %Y",localtime_( time )) + Return String.FromCString(buff) +End Function + +Rem +bbdoc: Get current time +returns: The current time as a string +about: +Returns the current time in the format: HH:MM:SS (i.e. 14:31:57). +End Rem +Function CurrentTime$() + Local time[256],buff:Byte[256] + time_(time) + strftime_( buff,256,"%H:%M:%S",localtime_( time ) ); + Return String.FromCString(buff) +End Function + +Rem +bbdoc: Move mouse pointer +about: +#MoveMouse positions the mouse cursor at a specific location within +the current window or graphics display. +End Rem +Function MoveMouse( x,y ) + Driver.MoveMouse x,y +End Function + +Rem +bbdoc: Make the mouse pointer visible +End Rem +Function ShowMouse() + Driver.SetMouseVisible True +End Function + +Rem +bbdoc: Make the mouse pointer invisible +End Rem +Function HideMouse() + Driver.SetMouseVisible False +End Function + +Rem +bbdoc: Notify user +about: +#Notify activates a simple user interface element informing the user of an event. +The optional @serious flag can be used to indicate a 'critical' event. + +Note that a user interface may not be available when in graphics mode on some platforms. +End Rem +Function Notify( text$,serious=False ) + Driver.Notify text,serious +End Function + +Rem +bbdoc: Request user confirmation. +returns: True or False depending on the user's selection +about: +#Confirm activates a simple user interface element requesting the user to select between +YES and NO options. If the user selects YES, then #Confirm returns True. Otherwise, +False is returned. + +Note that a user interface may not be available when in graphics mode on some platforms. +End Rem +Function Confirm( text$,serious=False ) + Return Driver.Confirm( text,serious ) +End Function + +Rem +bbdoc: Request user confirmation or cancellation. +returns: 1, 0 or -1 depending on the user's selection +about: +#Proceed activates a simple user interface element requesting the user to select between +YES, NO and CANCEL options. If the user selects YES, then #Proceed return 1. If the user +selects NO, then #Proceed returns 0. Otherwise, #Proceed returns -1. + +Note that a user interface may not be available when in graphics mode on some platforms. +End Rem +Function Proceed( text$,serious=False ) + Return Driver.Proceed( text,serious ) +End Function + +Rem +bbdoc: Display system file requester. +returns: The path of the selected file or an empty string if the operation was cancelled. +about: +@text is used as the title of the file requester. + +The optional @extensions string can either be a comma separated list of +file extensions or as in the following example groups of extensions +that begin with a "group:" and separated by a semicolon. +@save_flag can be True to create a save-style requester, or False to create a load-style requester. + +@initial_path is the initial path for the file requester. + +Note that a user interface may not be available when in graphics mode on some platforms. +End Rem +Function RequestFile$( text$,extensions$="",save_flag=False,initial_path$="" ) + Return Driver.RequestFile( text,extensions,save_flag,initial_path ) +End Function + +Rem +bbdoc: Display system folder requester. +returns: The path of the selected folder or an empty string if the operation was cancelled. +about: +@text is used as the title of the file requester. + +@initial_path is the initial path for the folder requester. + +Note that a user interface may not be available when in graphics mode on some platforms. +End Rem +Function RequestDir$( text$,initial_path$="" ) + Return Driver.RequestDir( text,initial_path ) +End Function + +Rem +bbdoc: Opens a URL with the system's default web browser. +about: Note that a user interface may not be available when in graphics mode on some platforms. +End Rem +Function OpenURL( url$ ) + Local dev$,anchor$ + + dev=url[..5].toLower() + If dev<>"http:" And dev<>"file:" And url[..6].ToLower()<>"https:" + Local h=url.find("#") + If h>-1 + anchor=url[h..] + url=url[..h] + EndIf + Local f$=RealPath(url) + If FileType(f) + url="file:"+f +anchor + Else + url="http:"+url+anchor + EndIf + EndIf + Return Driver.OpenURL( url ) +End Function + +Extern + +Rem +bbdoc: Get desktop width +returns: Width of the desktop, in pixels +End Rem +Function DesktopWidth()="bbSystemDesktopWidth" + +Rem +bbdoc: Get desktop height +returns: Height of the desktop, in pixels +End Rem +Function DesktopHeight()="bbSystemDesktopHeight" + +Rem +bbdoc: Get desktop depth +returns: Bits per pixel depth of the desktop +about: +The depth of the desktop is the number of bits per pixel. + +Note that on some platforms this function may return 0 if the desktop depth cannot be determined. +End Rem +Function DesktopDepth()="bbSystemDesktopDepth" + +Rem +bbdoc: Get desktop refresh rate +returns: Refresh rate, in cycles per second, of the desktop +about: +Note that on some platforms this function may return 0 if the desktop refresh rate cannot be determined. +End Rem +Function DesktopHertz()="bbSystemDesktopHertz" + +End Extern diff --git a/mod/brl.mod/system.mod/system.c b/mod/brl.mod/system.mod/system.c new file mode 100644 index 0000000..508c853 --- /dev/null +++ b/mod/brl.mod/system.mod/system.c @@ -0,0 +1,10 @@ + +#include "system.h" + +void brl_event_EmitEvent( BBObject *event ); +BBObject *brl_event_CreateEvent( int id,BBObject *source,int data,int mods,int x,int y,BBObject *extra ); + +void bbSystemEmitEvent( int id,BBObject *source,int data,int mods,int x,int y,BBObject *extra ){ + BBObject *event=brl_event_CreateEvent( id,source,data,mods,x,y,extra ); + brl_event_EmitEvent( event ); +} diff --git a/mod/brl.mod/system.mod/system.h b/mod/brl.mod/system.mod/system.h new file mode 100644 index 0000000..ad93fcd --- /dev/null +++ b/mod/brl.mod/system.mod/system.h @@ -0,0 +1,61 @@ + +#ifndef BB_BRL_SYSTEM_H +#define BB_BRL_SYSTEM_H + +#include + +#include //event enums + +#include //keycode enums + +typedef int (*BBAsyncOp)( int asyncInfo ); +typedef void (*BBSyncOp)( BBObject *syncInfo,int asyncRet ); + +void bbSystemPostSyncOp( BBSyncOp syncOp,BBObject *syncInfo,int asyncRet ); +void bbSystemStartAsyncOp( BBAsyncOp asyncOp,int asyncInfo,BBSyncOp syncOp,BBObject *syncInfo ); + +#ifdef __cplusplus +extern "C"{ +#endif + +void bbSystemEmitEvent( int id,BBObject *source,int data,int mods,int x,int y,BBObject *extra ); + +#if _WIN32 + +#include + +#define WM_BBRESERVED1 0x7001 + +void bbSystemEmitOSEvent( HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam,BBObject *source ); + +#elif __APPLE__ + +#define BB_RESERVEDEVENTSUBTYPE1 0x7001 //reserved event substype + +#ifdef __OBJC__ +#include +#else +typedef void *NSView; +typedef void *NSEvent; +#endif + +int bbSystemTranslateKey( int key ); +int bbSystemTranslateChar( int chr ); +int bbSystemTranslateMods( int mods ); +void bbSystemViewClosed( NSView *view ); +void bbSystemEmitOSEvent( NSEvent *event,NSView *view,BBObject *source ); + +BBString * brl_blitz_bbStringFromUTF8String(const char * text); + +#elif __linux + +#include +void bbSystemEmitOSEvent( XEvent *event,BBObject *source ); + +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/mod/brl.mod/system.mod/system.linux.bmx b/mod/brl.mod/system.mod/system.linux.bmx new file mode 100644 index 0000000..3816fd6 --- /dev/null +++ b/mod/brl.mod/system.mod/system.linux.bmx @@ -0,0 +1,100 @@ + +Strict + +Import "driver.bmx" +Import "system.linux.c" + +Import "-lXxf86vm" + +Import pub.stdc + +Extern + +Function bbSystemStartup() +Function bbSystemPoll() +Function bbSystemWait() + +Function bbSetMouseVisible(visible) +Function bbMoveMouse(x,y) +Function bbSystemDisplay() +Function bbSystemEventHandler( callback(xevent:Byte Ptr) ) + +Function bbSystemPostSyncOp( syncOp( syncInfo:Object,asyncRet ),syncInfo:Object,asyncRet ) +Function bbSystemStartAsyncOp( asyncOp( asyncInfo ),asyncInfo,syncOp( syncInfo:Object,asyncRet ),syncInfo:Object ) + +Function bbSystemAsyncFD() +Function bbSystemFlushAsyncOps() + +End Extern + +Const XKeyPress=2 +Const XKeyRelease=3 + +Function XKeyHandler(keyevent,key,mask) + WriteStdout "XKeyHandler "+keyevent+","+key+","+mask+"~n" +End Function + +Type TLinuxSystemDriver Extends TSystemDriver + + Method New() + bbSystemStartup + End Method + + Method Poll() + bbSystemPoll() + End Method + + Method Wait() + bbSystemWait() + End Method + + Method Emit( osevent:Byte Ptr,source:Object ) + Throw "simon come here" + End Method + + Method SetMouseVisible( visible ) + bbSetMouseVisible(visible) + End Method + + Method MoveMouse( x,y ) + bbMoveMouse x,y + End Method + + Method Notify( text$,serious ) + WriteStdout text+"~r~n" + End Method + + Method Confirm( text$,serious ) + WriteStdout text+" (Yes/No)?" + Local t$=ReadStdin().ToLower() + If t[..1]="y" Return 1 + Return 0 + End Method + + Method Proceed( text$,serious ) + WriteStdout text+" (Yes/No/Cancel)?" + Local t$=ReadStdin().ToLower() + If t[..1]="y" Return 1 + If t[..1]="n" Return 0 + Return -1 + End Method + + Method RequestFile$( text$,exts$,save,file$ ) + WriteStdout "Enter a filename:" + Return ReadStdin() + End Method + + Method RequestDir$( text$,path$ ) + WriteStdout "Enter a directory name:" + Return ReadStdin() + End Method + + Method OpenURL( url$ ) + If getenv_("KDE_FULL_DESKTOP") + system_ "kfmclient exec ~q"+url+"~q" + ElseIf getenv_("GNOME_DESKTOP_SESSION_ID") + system_ "gnome-open ~q"+url+"~q" + EndIf + End Method + +End Type diff --git a/mod/brl.mod/system.mod/system.linux.c b/mod/brl.mod/system.mod/system.linux.c new file mode 100644 index 0000000..d5c0821 --- /dev/null +++ b/mod/brl.mod/system.mod/system.linux.c @@ -0,0 +1,398 @@ + +#include "system.h" + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#define INTERLACE 0x010 +#define DBLSCAN 0x020 + +typedef struct AsyncOp{ + struct AsyncOp *succ; + BBSyncOp syncOp; + BBObject *syncInfo; + int asyncRet; + BBAsyncOp asyncOp; + int asyncInfo; +}AsyncOp; + +static AsyncOp *asyncOps; +static pthread_mutex_t asyncMutex=PTHREAD_MUTEX_INITIALIZER; +static int async_pipe[2]; + +static Display *x_display; +static int x_fd; +static int x_window; +static Cursor x_cursor; + +int (*xeventhandler)(XEvent *); + +int getxkey(XEvent *event); + +int brl_system_XKeyHandler(int type,int key,int mask); + +static void postAsyncOp( AsyncOp *p ){ + int ch=0; + XEvent event; + AsyncOp **q=&asyncOps,*t; + + p->succ=0; + + pthread_mutex_lock( &asyncMutex ); + + while( *q ) q=&(*q)->succ; + *q=p; + + write( async_pipe[1],&ch,1 ); + + pthread_mutex_unlock( &asyncMutex ); +} + +int bbSystemAsyncFD(){ + return async_pipe[0]; +} + +void bbSystemFlushAsyncOps(){ + int rd; + AsyncOp *p; + + if( !asyncOps ) return; + + pthread_mutex_lock( &asyncMutex ); + + p=asyncOps; + asyncOps=0; + + if( !ioctl( async_pipe[0],FIONREAD,&rd ) ){ + static char *buf; + static int buf_sz; + if( rd>buf_sz ){ + free( buf ); + buf=(char*)malloc( rd ); + buf_sz=rd; + } + read( async_pipe[0],buf,rd ); + } + + pthread_mutex_unlock( &asyncMutex ); + + while( p ){ + AsyncOp *t=p->succ; + p->syncOp( p->syncInfo,p->asyncRet ); + if( p->asyncOp ){ + BBRELEASE( p->syncInfo ); + } + free( p ); + p=t; + } +} + +void bbSystemShutdown(){ +// XCloseDisplay(x_display); causes crash with fltk canvas usage +} + +void bbSystemStartup(){ + atexit( bbSystemShutdown ); + + XInitThreads(); + + x_display=XOpenDisplay(0); + + x_fd=ConnectionNumber( x_display ); + + pipe( async_pipe ); +} + +Display *bbSystemDisplay(){ + return x_display; +} + +void bbSetSystemWindow(int window){ + x_window=window; +} + +void bbMoveMouse(int x,int y){ + XWarpPointer(x_display,None,x_window,0,0,0,0,x,y); +} + +void bbSetMouseVisible(visible){ + if (!x_window) return; + + if (visible) + { + XUndefineCursor(x_display,x_window); + } + else + { + if (!x_cursor) + { + XColor black; + char bm[]={0,0,0,0,0,0,0,0}; + Pixmap pix=XCreateBitmapFromData(x_display,x_window,bm,8,8); + memset(&black,0,sizeof(XColor)); + black.flags=DoRed|DoGreen|DoBlue; + x_cursor=XCreatePixmapCursor(x_display,pix,pix,&black,&black,0,0); + XFreePixmap(x_display,pix); + } + XDefineCursor(x_display,x_window,x_cursor); + } +} + +void bbSystemEventHandler( int(*handler)(XEvent*) ){ + xeventhandler=handler; +} + +void bbSystemEmitOSEvent( XEvent *xevent,BBObject *source ){ + + XKeyEvent *keyevent; + BBObject *event; + int id,data=0,x=0,y=0,mods=0; + char mybuffer[16]; + KeySym mykeysym; + int i,n; + + if (xeventhandler){ + if (xeventhandler(xevent)) return; + } + + x=xevent->xbutton.x; + y=xevent->xbutton.y; + + switch( xevent->type ){ + case KeyPress: + // + data=getxkey(xevent); + bbSystemEmitEvent( BBEVENT_KEYDOWN,source,data,mods,x,y,&bbNullObject ); + // + //Mark swapped above/below - ie: keydown before keychar + // + n=XLookupString( xevent,mybuffer,15,&mykeysym,0 ); + for (i=0;ixbutton.button; + if (data==4) + { + id=BBEVENT_MOUSEWHEEL; + data=1; + break; + } + if (data==5) + { + id=BBEVENT_MOUSEWHEEL; + data=-1; + break; + } + id=BBEVENT_MOUSEDOWN; + if (data>1) data=5-data; + break; + case ButtonRelease: + id=BBEVENT_MOUSEUP; + data=xevent->xbutton.button; + if (data>1) data=5-data; + break; + case MotionNotify: + id=BBEVENT_MOUSEMOVE; + break; + case ClientMessage: + if( xevent->xclient.data.l[0]==XInternAtom( x_display,"WM_DELETE_WINDOW",True ) ){ + id=BBEVENT_APPTERMINATE; + }else{ + return; + } + break; + default: + return; + } + bbSystemEmitEvent( id,source,data,mods,x,y,&bbNullObject ); +} + +void bbSystemPoll(){ + if( !x_display ) return; + + while( XPending( x_display ) ){ + XEvent event; + XNextEvent( x_display,&event ); + + bbSystemEmitOSEvent(&event,&bbNullObject); + } + bbSystemFlushAsyncOps(); +} + +void bbSystemWait(){ + fd_set in_fds; + struct timeval tv; + + if( !x_display ) return; + + FD_ZERO( &in_fds ); + FD_SET( x_fd,&in_fds ); + FD_SET( async_pipe[0],&in_fds ); + + tv.tv_sec=10; + tv.tv_usec=0; + + select( (x_fd>async_pipe[0] ? x_fd : async_pipe[0]) + 1,&in_fds,0,0,&tv ); + + bbSystemPoll(); +} + +int getxkey(XEvent *event) +{ + int key; + key=XLookupKeysym(&event->xkey,0)&255; + if (key>=97&&key<=126) return key+(65-97); //a..z + if (key>=81&&key<=84) return key+(37-81); //arrow keys + if (key>=190 && key<=201) return key+(112-190); //function keys + if (key==99) return 45; //insert + if (key==227) return 162; //lctrl + if (key==233) return 164; //lalt + if (key==234) return 165; //ralt + if (key==228) return 163; //rctrl + if (key==225) return 160; //lshift + if (key==226) return 161; //rshiftz + if (key==127) return 144; //numlock + if (key==20) return 145; //scroll + if (key==158) return 96; //numkeys 0..9 + if (key==156) return 97; + if (key==153) return 98; + if (key==155) return 99; + if (key==150) return 100; + if (key==157) return 101; + if (key==152) return 102; + if (key==149) return 103; + if (key==151) return 104; + if (key==154) return 105; + if (key==235) return 91; //left windows key + if (key==236) return 92; //right windows key + if (key==103) return 93; //startmenu windows key + if (key==80) return 36; //home + if (key==85) return 33; //pageup + if (key==255) return 46; //delete + if (key==87) return 35; //end + if (key==86) return 34; //pagedown + if (key==97) return 42; //print screen + if (key==159) return 110; //keypad . + if (key==141) return 13; //keypad enter + if (key==171) return 107; //keypad add + if (key==173) return 109; //keypad minus + if (key==170) return 106; //keypad mult + if (key==175) return 111; //keypad divide + if (key==96) return 192; //tilde key + if (key=='-') return 189; //minus + if (key=='=') return 187; //equals + if (key==91) return 219; //[ + if (key==93) return 221; //] + if (key==92) return 226; //backslash + if (key==59) return 186; //semicolon + if (key==39) return 222; //quotes + if (key==44) return 188; //comma key + if (key==46) return 190; //period key + if (key==47) return 191; //questionmark key + + return key; +} + +void *asyncOpThread( void *t ){ + AsyncOp *p=(AsyncOp*)t; + p->asyncRet=p->asyncOp( p->asyncInfo ); + postAsyncOp( p ); + return 0; +} + +void bbSystemPostSyncOp( BBSyncOp syncOp,BBObject *syncInfo,int asyncRet ){ + AsyncOp *p=(AsyncOp*)malloc( sizeof( AsyncOp ) ); + p->asyncOp=0; + p->asyncRet=asyncRet; + p->syncOp=syncOp; + p->syncInfo=syncInfo; + postAsyncOp( p ); +} + +void bbSystemStartAsyncOp( BBAsyncOp asyncOp,int asyncInfo,BBSyncOp syncOp,BBObject *syncInfo ){ + pthread_t thread; + AsyncOp *p=(AsyncOp*)malloc( sizeof( AsyncOp ) ); + BBRETAIN( syncInfo ); + p->asyncOp=asyncOp; + p->asyncInfo=asyncInfo; + p->syncOp=syncOp; + p->syncInfo=syncInfo; + pthread_create( &thread,0,asyncOpThread,p ); + pthread_detach( thread ); +} + +static int _calchertz( XF86VidModeModeInfo *m ){ + int freq=( m->dotclock*1000.0 )/( m->htotal*m->vtotal )+.5; + if( m->flags&INTERLACE ) freq<<=1; + if( m->flags&DBLSCAN ) freq>>=1; + return freq; +} + +int bbSystemDesktopWidth(){ + int count=0,sz=0; + XF86VidModeModeInfo **xmodes=0; + XF86VidModeGetAllModeLines( x_display,DefaultScreen( x_display ),&count,&xmodes ); + sz=count>0 ? xmodes[0]->hdisplay : 640; + XFree( xmodes ); + return sz; +} + +int bbSystemDesktopHeight(){ + int count=0,sz=0; + XF86VidModeModeInfo **xmodes=0; + XF86VidModeGetAllModeLines( x_display,DefaultScreen( x_display ),&count,&xmodes ); + sz=count>0 ? xmodes[0]->vdisplay : 480; + XFree( xmodes ); + return sz; +} + +int bbSystemDesktopDepth(){ + return 24; +} + +int bbSystemDesktopHertz(){ + int count=0,sz=0; + XF86VidModeModeInfo **xmodes=0; + XF86VidModeGetAllModeLines( x_display,DefaultScreen( x_display ),&count,&xmodes ); + sz=count>0 ? _calchertz( xmodes[0] ) : 60; + XFree( xmodes ); + return sz; +} diff --git a/mod/brl.mod/system.mod/system.macos.bmx b/mod/brl.mod/system.mod/system.macos.bmx new file mode 100644 index 0000000..5441596 --- /dev/null +++ b/mod/brl.mod/system.mod/system.macos.bmx @@ -0,0 +1,110 @@ +Strict + +Import BRL.Event + +Import "driver.bmx" +Import "system.macos.m" + +Extern + +Function bbSystemStartup() +Function bbSystemPoll() +Function bbSystemWait() +Function bbSystemIntr() +Function bbSystemMoveMouse( x,y ) +Function bbSystemSetMouseVisible( visible ) +Function bbSystemNotify( text$,serious ) +Function bbSystemConfirm( text$,serious ) +Function bbSystemProceed( text$,serious ) +Function bbSystemRequestFile$( text$,exts$,save,file$,dir$ ) +Function bbSystemRequestDir$( text$,dir$ ) +Function bbOpenURL( url$ ) + +Function bbSystemPostSyncOp( syncOp( syncInfo:Object,asyncRet ),syncInfo:Object,asyncRet ) +Function bbSystemStartAsyncOp( asyncOp( asyncInfo ),asyncInfo,syncOp( syncInfo:Object,asyncRet ),syncInfo:Object ) + +End Extern + +Private + +Function Hook:Object( id,data:Object,context:Object ) + bbSystemIntr + Return data +End Function + +AddHook EmitEventHook,Hook,Null,10000 + +Public + +Type TMacOSSystemDriver Extends TSystemDriver + + Method New() + bbSystemStartup + End Method + + Method Poll() + bbSystemPoll() + End Method + + Method Wait() + bbSystemWait() + End Method + + Method MoveMouse( x,y ) + bbSystemMoveMouse x,y + End Method + + Method SetMouseVisible( visible ) + bbSystemSetMouseVisible visible + End Method + + Method Notify( text$,serious ) + bbSystemNotify text,serious + End Method + + Method Confirm( text$,serious ) + Return bbSystemConfirm( text,serious ) + End Method + + Method Proceed( text$,serious ) + Return bbSystemProceed( text,serious ) + End Method + + Method RequestFile$( text$,exts$,save,path$ ) + Local file$,dir$,filter$ + + path=path.Replace( "\","/" ) + Local i=path.FindLast( "/" ) + If i<>-1 + dir=path[..i] + file=path[i+1..] + Else + file=path + EndIf + + exts=exts.Replace( ";","," ) + While exts + Local p=exts.Find(",")+1 + If p=0 p=exts.length + Local q=exts.Find(":")+1 + If q=0 Or q>p q=0 + filter:+exts[q..p] + exts=exts[p..] + Wend + If filter.find("*")>-1 filter="" + + Return bbSystemRequestFile( text,filter,save,file,dir ) + End Method + + Method RequestDir$( text$,dir$ ) + dir=dir.Replace( "\","/" ) + Return bbSystemRequestDir( text,dir ) + End Method + + Method OpenURL( url$ ) +' Return system_( "open "" + url.Replace("~q","") + "~q" ) + bbOpenURL( url ) + End Method + +End Type + diff --git a/mod/brl.mod/system.mod/system.macos.m b/mod/brl.mod/system.mod/system.macos.m new file mode 100644 index 0000000..a6baefe --- /dev/null +++ b/mod/brl.mod/system.mod/system.macos.m @@ -0,0 +1,664 @@ + +#import + +#include + +#include + +static unsigned char key_table[]={ + //0... + KEY_A, KEY_S, KEY_D, KEY_F, KEY_H, KEY_G, KEY_Z, KEY_X, + KEY_C, KEY_V, 0, KEY_B, KEY_Q, KEY_W, KEY_E, KEY_R, + KEY_Y, KEY_T, KEY_1, KEY_2, KEY_3, KEY_4, KEY_6, KEY_5, + KEY_EQUALS, KEY_9, KEY_7, KEY_MINUS, KEY_8, KEY_0, KEY_CLOSEBRACKET,KEY_O, + //32... + KEY_U, KEY_OPENBRACKET,KEY_I, KEY_P, KEY_ENTER, KEY_L, KEY_J, KEY_QUOTES, + KEY_K, KEY_SEMICOLON,KEY_BACKSLASH,KEY_COMMA,KEY_SLASH,KEY_N, KEY_M, KEY_PERIOD, + KEY_TAB, KEY_SPACE, KEY_TILDE, KEY_BACKSPACE,0, KEY_ESC, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + //64... + 0, KEY_NUMDECIMAL,0, KEY_NUMMULTIPLY,0, KEY_NUMADD, 0, 0, + 0, 0, 0, KEY_NUMDIVIDE,KEY_ENTER,0, KEY_NUMSUBTRACT,0, + //80... + 0, 0, KEY_NUM0, KEY_NUM1, KEY_NUM2, KEY_NUM3, KEY_NUM4, KEY_NUM5, + KEY_NUM6, KEY_NUM7, 0, KEY_NUM8, KEY_NUM9, 0, 0, 0, + //96... + KEY_F5, KEY_F6, KEY_F7, KEY_F3, KEY_F8, KEY_F9, 0, KEY_F11, + 0, 0, 0, 0, 0, KEY_F10, 0, KEY_F12, + 0, 0, KEY_INSERT, KEY_HOME, KEY_PAGEUP, KEY_DELETE, KEY_F4, KEY_END, + KEY_F2, KEY_PAGEDOWN,KEY_F1, KEY_LEFT, KEY_RIGHT, KEY_DOWN, KEY_UP, 0, + //128... +}; + +void bbSystemPoll(); +void bbFlushAutoreleasePool(); + +static int mods,deltaMods; +static NSDate *distantPast,*distantFuture; + +static int mouseVisible=1; +static int displayCaptured=0; + +static NSView *mouseView; +static BBObject *mouseSource; +static NSTrackingRectTag mouseTrackTag; + +static NSEvent *anullEvent; +static NSView *capturedView; + +static int appWaiting; +static NSWindow *keyWin; + +#define LSHIFTMASK 0x2 +#define RSHIFTMASK 0x4 +#define LCTRLMASK 0x1 +#define RCTRLMASK 0x2000 +#define LSYSMASK 0x8 +#define RSYSMASK 0x10 +#define LALTMASK 0x20 +#define RALTMASK 0x40 + +typedef struct AsyncOp{ + BBAsyncOp asyncOp; + int asyncInfo; + int asyncRet; + BBSyncOp syncOp; + BBObject *syncInfo; +}AsyncOp; + +@interface BBSystemAppDelegate : NSObject{ +} +@end + +static BBSystemAppDelegate *appDelegate; + +static NSString *tmpNSString( BBString *str ){ + return [NSString stringWithCharacters:str->buf length:str->length]; +} + +static BBString *stringFromNSString( NSString *nsstr ){ + return bbStringFromUTF8String( [nsstr UTF8String] ); +} + +static NSString *appTitle(){ + return tmpNSString( bbAppTitle ); +} + +int bbSystemTranslateKey( key ){ + return (key>=0 && key<128) ? key_table[key] : 0; +} + +int bbSystemTranslateChar( chr ){ + switch(chr){ + case 127:return 8; + case 63272:return 127; + } + return chr; +} + +int bbSystemTranslateMods( mods ){ + int n=0; + if( mods & NSShiftKeyMask ) n|=MODIFIER_SHIFT; + if( mods & NSControlKeyMask ) n|=MODIFIER_CONTROL; + if( mods & NSAlternateKeyMask ) n|=MODIFIER_OPTION; + if( mods & NSCommandKeyMask ) n|=MODIFIER_SYSTEM; + return n; +} + +static void updateMouseVisibility(){ + static int cursorVisible=1; + + int visible=mouseVisible; + + if( !visible && !displayCaptured ){ + + NSArray *windows=(NSArray*)[NSApp windows]; + int count=[windows count],i; + + visible=1; + + for( i=0;i=rect.size.width || point.y>=rect.size.height ) continue; + + visible=0; + break; + } + } + if( visible ){ + if( !CGCursorIsVisible() ){ + CGDisplayShowCursor( kCGDirectMainDisplay ); + } + }else{ + if( CGCursorIsVisible() ){ + CGDisplayHideCursor( kCGDirectMainDisplay ); + } + } +} + +static int mouseViewPos( NSView *view,int *x,int *y ){ + NSRect rect; + NSPoint point; + NSWindow *window; + if( displayCaptured || !view ){ + Point point; + GetMouse( &point ); + *x=point.h; + *y=point.v; + return 1; + } + window=[view window]; + point=[window mouseLocationOutsideOfEventStream]; + rect=[view bounds]; + point=[view convertPoint:point fromView:nil]; + if( ![view isFlipped] ) point.y=rect.size.height-point.y; + *x=point.x; + *y=point.y; + return point.x>=0 && point.y>=0 && point.xasyncRet=p->asyncOp( p->asyncInfo ); + [NSApp postEvent:event atStart:NO]; +} +@end + +static void updateDisplayCaptured(){ + displayCaptured=CGDisplayIsCaptured( kCGDirectMainDisplay ); +} + +static void updateEvents( NSDate *until ){ + NSEvent *event; + + updateDisplayCaptured(); + updateMouseVisibility(); + + while( event=[NSApp nextEventMatchingMask:NSAnyEventMask untilDate:until inMode:NSDefaultRunLoopMode dequeue:YES] ){ + if( [event type]==NSApplicationDefined ){ + if( [event subtype]==BB_RESERVEDEVENTSUBTYPE1 ){ + AsyncOp *p=(AsyncOp*)[event data1]; + p->syncOp( p->syncInfo,p->asyncRet ); + if( p->asyncOp ){ + BBRELEASE( p->syncInfo ); + } + free( p ); + continue; + } + } + if( displayCaptured ){ + bbSystemEmitOSEvent( event,0,&bbNullObject ); + }else{ + [NSApp sendEvent:event]; + } + until=distantPast; + } + + bbFlushAutoreleasePool(); +} + +static void checkDisplay(){ + updateDisplayCaptured(); + if( displayCaptured ) bbExThrowCString( "GUI unavailable in fullscreen mode" ); +} + +static void beginPanel(){ + checkDisplay(); + keyWin=[NSApp keyWindow]; + if( !keyWin ) [NSApp activateIgnoringOtherApps:YES]; +} + +static void endPanel(){ + if( keyWin ) [keyWin makeKeyWindow]; +} + +static NSWindow *appMainWindow(){ + int i; + if( ![[NSApp windows] count] ) return 0; + for( i=0;i<10;++i ){ + NSWindow *window=[NSApp mainWindow]; + if( window ) return window; + bbSystemPoll(); + } + return 0; +} + +void bbSystemPoll(){ + updateEvents( distantPast ); +} + +void bbSystemWait(){ + appWaiting=1; + updateEvents( distantFuture ); + appWaiting=0; +} + +void bbSystemIntr(){ + if( !appWaiting ) return; + appWaiting=0; + [NSApp postEvent:anullEvent atStart:NO]; +} + +void bbSystemViewClosed( NSView *view ){ + if( view!=mouseView ) return; + [mouseView removeTrackingRect:mouseTrackTag]; + mouseView=0; +} + +void bbSystemEmitOSEvent( NSEvent *event,NSView *view,BBObject *source ){ + int inView; + NSEventType type; + NSString *characters; + int ev=0,data=0,x=0,y=0,oldMods=mods,mask; + float f; + + mods=[event modifierFlags]; + + type=[event type]; + + switch( type ){ + case NSKeyDown: + if( data=bbSystemTranslateKey( [event keyCode] ) ){ + ev=[event isARepeat] ? BBEVENT_KEYREPEAT : BBEVENT_KEYDOWN; + bbSystemEmitEvent( ev,source,data,bbSystemTranslateMods(mods),0,0,&bbNullObject ); + } + characters=[event characters]; + if( [characters length]!=1 ) return; + data=[characters characterAtIndex:0]; + if( data>=0xf700 && data<=0xf8ff ) return; + ev=BBEVENT_KEYCHAR; + data=bbSystemTranslateChar( data ); + break; + case NSKeyUp: + data=bbSystemTranslateKey( [event keyCode] ); + if( !data ) return; + ev=BBEVENT_KEYUP; + break; + case NSFlagsChanged: + deltaMods=mods^oldMods; + if( deltaMods & (mask=LSHIFTMASK) ) data=KEY_LSHIFT; + else if( deltaMods & (mask=RSHIFTMASK) ) data=KEY_RSHIFT; + else if( deltaMods & (mask=LCTRLMASK) ) data=KEY_LCONTROL; + else if( deltaMods & (mask=RCTRLMASK) ) data=KEY_RCONTROL; + else if( deltaMods & (mask=LALTMASK) ) data=KEY_LALT; + else if( deltaMods & (mask=RALTMASK) ) data=KEY_RALT; + else if( deltaMods & (mask=LSYSMASK) ) data=KEY_LSYS; + else if( deltaMods & (mask=RSYSMASK) ) data=KEY_RSYS; + if( !data ) return; + ev=(mods & mask) ? BBEVENT_KEYDOWN : BBEVENT_KEYUP; + break; + case NSLeftMouseDown: + case NSRightMouseDown: + case NSOtherMouseDown: + inView=mouseViewPos( view,&x,&y ); + if( !inView ) return; + setMouseView( view,x,y,source ); + capturedView=mouseView; + ev=BBEVENT_MOUSEDOWN; + data=(type==NSLeftMouseDown) ? 1 : (type==NSRightMouseDown ? 2 : 3); + break; + case NSLeftMouseUp: + case NSRightMouseUp: + case NSOtherMouseUp: + inView=mouseViewPos( view,&x,&y ); + if( !inView && !capturedView ) return; + capturedView=0; + ev=BBEVENT_MOUSEUP; + data=(type==NSLeftMouseUp) ? 1 : (type==NSRightMouseUp ? 2 : 3); + break; + case NSMouseMoved: + case NSLeftMouseDragged: + case NSRightMouseDragged: + case NSOtherMouseDragged: + inView=mouseViewPos( view,&x,&y ); + setMouseView( inView ? view : 0,x,y,source ); + if( !inView && !capturedView ) return; + ev=BBEVENT_MOUSEMOVE; + data=(type==NSLeftMouseDragged) ? 1 : (type==NSRightMouseDragged ? 2 : (type==NSOtherMouseDragged ? 3 : 0)); + break; + case NSScrollWheel: + inView=mouseViewPos( view,&x,&y ); + if( !inView && view!=capturedView ) return; + ev=BBEVENT_MOUSEWHEEL; + f=[event deltaY]; + data=f>0 ? ceil(f) : floor(f); + break; + default: + return; + } + bbSystemEmitEvent( ev,source,data,bbSystemTranslateMods(mods),x,y,&bbNullObject ); +} + +void bbSystemMoveMouse( int x,int y ){ + NSEvent *event; + CGPoint cgPoint={x,y}; + + CGSetLocalEventsSuppressionInterval(0.0); + + if( !CGDisplayIsCaptured(kCGDirectMainDisplay) ){ + NSPoint nsPoint={x,y}; + + NSWindow *window=appMainWindow(); + + if( !window ) return; + + nsPoint.y=[[window contentView] bounds].size.height-1-nsPoint.y; + nsPoint=[window convertBaseToScreen:nsPoint]; + + cgPoint.x=nsPoint.x; + cgPoint.y=CGDisplayPixelsHigh(kCGDirectMainDisplay)-nsPoint.y; + } + + CGDisplayMoveCursorToPoint( kCGDirectMainDisplay,cgPoint ); + + bbSystemEmitEvent( BBEVENT_MOUSEMOVE,&bbNullObject,0,bbSystemTranslateMods(mods),x,y,&bbNullObject ); +} + +void bbSystemSetMouseVisible( int visible ){ + mouseVisible=visible; + updateDisplayCaptured(); + updateMouseVisibility(); +} + +void bbSystemStartup(){ + anullEvent=[appDefEvent( -1,0,0 ) retain]; + distantPast=[[NSDate distantPast] retain]; + distantFuture=[[NSDate distantFuture] retain]; + appDelegate=[[BBSystemAppDelegate alloc] init]; + [NSApp setDelegate:appDelegate]; +} + +typedef int (*AlertPanel)( + NSString *title, + NSString *msg, + NSString *defaultButton, + NSString *alternateButton, + NSString *otherButton ); + +void bbSystemNotify( BBString *text,int serious ){ + AlertPanel panel=serious ? (void*)NSRunCriticalAlertPanel : (void*)NSRunAlertPanel; + + beginPanel(); + panel( + appTitle(), + tmpNSString(text), + @"OK",0,0 ); + + endPanel(); +} + +int bbSystemConfirm( BBString *text,int serious ){ + int n; + AlertPanel panel=serious ? (void*)NSRunCriticalAlertPanel : (void*)NSRunAlertPanel; + + beginPanel(); + n=panel( + appTitle(), + tmpNSString(text), + @"OK",@"Cancel",0 ); + + endPanel(); + + switch( n ){ + case NSAlertDefaultReturn:return 1; + } + return 0; +} + +int bbSystemProceed( BBString *text,int serious ){ + int n; + AlertPanel panel=serious ? (void*)NSRunCriticalAlertPanel : (void*)NSRunAlertPanel; + + beginPanel(); + n=panel( + appTitle(), + tmpNSString(text), + @"Yes",@"No",@"Cancel" ); + endPanel(); + + switch( n ){ + case NSAlertDefaultReturn:return 1; + case NSAlertAlternateReturn:return 0; + } + return -1; +} + +BBString *bbSystemRequestFile( BBString *title,BBString *exts,int save,BBString *file,BBString *dir ){ + + NSString *nsdir=0; + NSString *nsfile=0; + NSString *nstitle=0; + NSMutableArray *nsexts=0; + + BBString *str=&bbEmptyString; + + if( dir->length ){ + char tmp[PATH_MAX]; + realpath( bbTmpUTF8String(dir),tmp ); + nsdir=[NSString stringWithUTF8String:tmp]; + } + + if( file->length ){ + nsfile=tmpNSString(file); + } + + if( title->length ){ + nstitle=tmpNSString(title); + } + + if( exts->length ){ + char *p=bbTmpUTF8String(exts),*t; + nsexts=[NSMutableArray arrayWithCapacity:10]; + while( t=strchr(p,',') ){ + *t=0; + [nsexts addObject:[NSString stringWithUTF8String:p]]; + p=t+1; + } + if( *p ) [nsexts addObject:[NSString stringWithUTF8String:p]]; + } + + beginPanel(); + + if( save ){ + NSSavePanel *panel=[NSSavePanel savePanel]; + + if( nstitle ) [panel setTitle:nstitle]; + + if( nsexts ){ + [panel setAllowedFileTypes:nsexts]; + [panel setAllowsOtherFileTypes:YES]; + } + + if( [panel runModalForDirectory:nsdir file:nsfile]==NSFileHandlingPanelOKButton ){ + str=stringFromNSString([panel filename]); + } + + }else{ + NSOpenPanel *panel=[NSOpenPanel openPanel]; + + if( nstitle ) [panel setTitle:nstitle]; + + if( [panel runModalForDirectory:nsdir file:nsfile types:nsexts]==NSFileHandlingPanelOKButton ){ + str=stringFromNSString([panel filename]); + } + } + endPanel(); + + return str; +} + +BBString *bbSystemRequestDir( BBString *title,BBString *dir ){ + + NSString *nsdir=0; + NSString *nstitle=0; + NSOpenPanel *panel; + + BBString *str=&bbEmptyString; + + if( dir->length ){ + char tmp[PATH_MAX]; + realpath( bbTmpUTF8String(dir),tmp ); + nsdir=[NSString stringWithUTF8String:tmp]; + } + + if( title->length ){ + nstitle=tmpNSString(title); + } + + panel=[NSOpenPanel openPanel]; + + [panel setCanChooseFiles:NO]; + [panel setCanChooseDirectories:YES]; + [panel setCanCreateDirectories:YES]; + + if( title ) [panel setTitle:nstitle]; + + beginPanel(); + if( [panel runModalForDirectory:nsdir file:0 types:0]==NSFileHandlingPanelOKButton ){ + str=stringFromNSString([panel filename]); + } + endPanel(); + + return str; +} + +int bbOpenURL( BBString *bburl ){ + NSURL *url; + NSString *loc; + int res=0; + + checkDisplay(); + loc=tmpNSString(bburl); + url=[NSURL URLWithString:[loc stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; + if( url ) res=[[NSWorkspace sharedWorkspace] openURL:url]; + return res; +} + +void bbSystemPostSyncOp( BBSyncOp syncOp,BBObject *syncInfo,int asyncRet ){ + AsyncOp *p=(AsyncOp*)malloc( sizeof(AsyncOp) ); + NSEvent *event=appDefEvent( BB_RESERVEDEVENTSUBTYPE1,(int)p,0 ); + p->asyncOp=0; + p->asyncRet=asyncRet; + p->syncOp=syncOp; + p->syncInfo=syncInfo; + [NSApp postEvent:event atStart:NO]; +} + +void bbSystemStartAsyncOp( BBAsyncOp asyncOp,int asyncInfo,BBSyncOp syncOp,BBObject *syncInfo ){ + AsyncOp *p=(AsyncOp*)malloc( sizeof( AsyncOp ) ); + NSEvent *event=appDefEvent( BB_RESERVEDEVENTSUBTYPE1,(int)p,0 ); + BBRETAIN( syncInfo ); + p->asyncOp=asyncOp; + p->asyncInfo=asyncInfo; + p->syncOp=syncOp; + p->syncInfo=syncInfo; + [NSThread detachNewThreadSelector:@selector(asyncOpThread:) toTarget:appDelegate withObject:event]; +} + +static NSScreen *DesktopScreen(){ + NSArray *screens; + if( screens=[NSScreen screens] ){ + if( [screens count] ) return [screens objectAtIndex:0]; + } + return 0; +} + +int bbSystemDesktopWidth(){ + NSScreen *screen=DesktopScreen(); + if( screen ) return [screen frame].size.width; + return 640; +} + +int bbSystemDesktopHeight(){ + NSScreen *screen=DesktopScreen(); + if( screen ) return [screen frame].size.height; + return 480; +} + +int bbSystemDesktopDepth(){ + NSScreen *screen=DesktopScreen(); + if( screen ) return NSBitsPerPixelFromDepth( [screen depth] ); + return 32; +} + +int bbSystemDesktopHertz(){ + return 60; +} diff --git a/mod/brl.mod/system.mod/system.win32.bmx b/mod/brl.mod/system.mod/system.win32.bmx new file mode 100644 index 0000000..935d4a3 --- /dev/null +++ b/mod/brl.mod/system.mod/system.win32.bmx @@ -0,0 +1,129 @@ + +Strict + +Import "driver.bmx" +Import "system.win32.c" + +Import "-lshell32" +Import "-lcomctl32" + +Const WM_BBSYNCOP=$7001 'wp=function, lp=arg + +Extern + +Function bbSystemStartup() +Function bbSystemPoll() +Function bbSystemWait() +Function bbSystemMoveMouse( x,y ) +Function bbSystemSetMouseVisible( visible ) + +Function bbSystemNotify( text$,serious ) +Function bbSystemConfirm( text$,serious ) +Function bbSystemProceed( text$,serious ) +Function bbSystemRequestFile$( text$,exts$,defext,save,file$,dir$ ) +Function bbSystemRequestDir$( text$,dir$ ) +Function bbOpenURL( url$ ) + +Function bbSystemEmitOSEvent( hwnd,msg,wparam,lparam,source:Object ) + +Function bbSystemPostSyncOp( syncOp( syncInfo:Object,asyncRet ),syncInfo:Object,asyncRet ) +Function bbSystemStartAsyncOp( asyncOp( asyncInfo ),asyncInfo,syncOp( syncInfo:Object,asyncRet ),syncInfo:Object ) + +End Extern + +Type TWin32SystemDriver Extends TSystemDriver + + Method New() + bbSystemStartup + End Method + + Method Poll() + bbSystemPoll() + End Method + + Method Wait() + bbSystemWait() + End Method + + Method MoveMouse( x,y ) + bbSystemMoveMouse x,y + End Method + + Method SetMouseVisible( visible ) + bbSystemSetMouseVisible visible + End Method + + Method Notify( text$,serious ) + bbSystemNotify text,serious + End Method + + Method Confirm( text$,serious ) + Return bbSystemConfirm( text,serious ) + End Method + + Method Proceed( text$,serious ) + Return bbSystemProceed( text,serious ) + End Method + + Method RequestFile$( text$,exts$,save,path$ ) + Local file$,dir$ + + path=path.Replace( "/","\" ) + + Local i=path.FindLast( "\" ) + If i<>-1 + dir=path[..i] + file=path[i+1..] + Else + file=path + EndIf + +' calculate default index of extension in extension list from path name + + Local ext$,defext,p,q + p=path.Find(".") + If (p>-1) + ext=","+path[p+1..].toLower()+"," + Local exs$=exts.toLower() + exs=exs.Replace(":",":,") + exs=exs.Replace(";",",;") + p=exs.find(ext) + If p>-1 + Local q=-1 + defext=1 + While True + q=exs.find(";",q+1) + If q>p Exit + If q=-1 defext=0;Exit + defext:+1 + Wend + EndIf + EndIf + + If exts + If exts.Find(":")=-1 + exts="Files~0*."+exts + Else + exts=exts.Replace(":","~0*.") + EndIf + exts=exts.Replace(";","~0") + exts=exts.Replace(",",";*.")+"~0" + EndIf + + Return bbSystemRequestFile( text,exts,defext,save,file,dir ) + + End Method + + Method RequestDir$( text$,dir$ ) + + dir=dir.Replace( "/","\" ) + + Return bbSystemRequestDir( text,dir ) + + End Method + + Method OpenURL( url$ ) + bbOpenURL( url ) + End Method + +End Type diff --git a/mod/brl.mod/system.mod/system.win32.c b/mod/brl.mod/system.mod/system.win32.c new file mode 100644 index 0000000..4b5cb64 --- /dev/null +++ b/mod/brl.mod/system.mod/system.win32.c @@ -0,0 +1,515 @@ + +#include "system.h" +#include + +typedef struct AsyncOp{ + BBSyncOp syncOp; + BBObject *syncInfo; + int asyncRet; + BBAsyncOp asyncOp; + int asyncInfo; +}AsyncOp; + +static int _usew; + +static HHOOK msghook; +static int mainThreadId; + +static int mods; +static int started; + +static HWND mouseHwnd; +static BBObject *mouseSource; +static int mouseVisible; + +static const wchar_t *appTitleW(){ + return bbStringToWString( bbAppTitle ); +} + +static const char *appTitleA(){ + return bbStringToCString( bbAppTitle ); +} + +static int keyCode( int wp,int lp ){ + switch( ((lp>>17)&0x80)|((lp>>16)&0x7f) ){ + case 42:return VK_LSHIFT; + case 54:return VK_RSHIFT; + case 29:return VK_LCONTROL; + case 157:return VK_RCONTROL; + case 56:return VK_LMENU; + case 184:return VK_RMENU; + } + return wp; +} + +static void updateMods(){ + mods=0; + if( GetKeyState( VK_SHIFT )<0 ) mods|=MODIFIER_SHIFT; + if( GetKeyState( VK_CONTROL )<0 ) mods|=MODIFIER_CONTROL; + if( GetKeyState( VK_MENU )<0 ) mods|=MODIFIER_OPTION; + if( GetKeyState( VK_LWIN )<0 || GetKeyState( VK_RWIN )<0 ) mods|=MODIFIER_SYSTEM; +} + +static void bbSystemShutdown(){ + if( !started ) return; + timeEndPeriod( 1 ); + started=0; +} + +static int isControl( HWND hwnd ){ + int style=GetWindowLong( hwnd,GWL_STYLE) & (WS_TABSTOP|WS_CHILD); + return style==(WS_TABSTOP|WS_CHILD); +} + +static void updateMouseVisibility(){ + int visible=mouseVisible || !mouseHwnd; + int n=ShowCursor( visible ); + if( n<-1 || n>0 ) ShowCursor( !visible ); +} + +static void setMouseHwnd( HWND hwnd,int x,int y,BBObject *source ){ + if( hwnd==mouseHwnd ) return; + + if( hwnd && source ){ + BBRETAIN( source ); + } + + if( mouseHwnd ){ + POINT p; + GetCursorPos( &p ); + ScreenToClient( mouseHwnd,&p ); + bbSystemEmitEvent( BBEVENT_MOUSELEAVE,mouseSource,0,0,p.x,p.y,&bbNullObject ); + if( mouseSource ){ + BBRELEASE( mouseSource ); + } + } + mouseHwnd=hwnd; + updateMouseVisibility(); + if( mouseHwnd ){ + TRACKMOUSEEVENT tm={sizeof(tm),TME_LEAVE,hwnd,0}; + mouseSource=source; + bbSystemEmitEvent( BBEVENT_MOUSEENTER,mouseSource,0,0,x,y,&bbNullObject ); + _TrackMouseEvent( &tm ); + } +} + +static HWND focHwnd; + +static void beginPanel(){ + focHwnd=GetFocus(); +} + +static void endPanel(){ + SetFocus( focHwnd ); +} + +static LRESULT CALLBACK getMessageHook( int code,WPARAM wp,LPARAM lp ){ + if( code>=0 && wp==PM_REMOVE ){ + MSG *msg=(MSG*)lp; + if( msg->message==WM_BBRESERVED1 ){ + AsyncOp *p=(AsyncOp*)msg->lParam; + p->syncOp( p->syncInfo,p->asyncRet ); + if( p->asyncOp ){ + BBRELEASE( p->syncInfo ); + } + free( p ); + } + } + return CallNextHookEx( msghook,code,wp,lp ); +} + +void bbSystemEmitOSEvent( HWND hwnd,UINT msg,WPARAM wp,LPARAM lp,BBObject *source ){ + + RECT rect; + POINT point; + int inRect,id,data=0,x=0,y=0; + + switch( msg ){ + case WM_KEYDOWN:case WM_SYSKEYDOWN: + if( wp<1 || wp>255 ) return; + id=( lp & 0x40000000 ) ? BBEVENT_KEYREPEAT : BBEVENT_KEYDOWN; + data=keyCode( wp,lp ); + break; + case WM_KEYUP:case WM_SYSKEYUP: + if( wp<1 || wp>255 ) return; + id=BBEVENT_KEYUP; + data=keyCode( wp,lp ); + break; + case WM_CHAR:case WM_SYSCHAR: + id=BBEVENT_KEYCHAR; + data=wp; + break; + case WM_LBUTTONDOWN:case WM_RBUTTONDOWN:case WM_MBUTTONDOWN: + SetCapture( hwnd ); + id=BBEVENT_MOUSEDOWN; + data=(msg==WM_LBUTTONDOWN) ? 1 : (msg==WM_RBUTTONDOWN ? 2 : 3); + x=(short)LOWORD(lp); + y=(short)HIWORD(lp); + break; + case WM_LBUTTONUP:case WM_RBUTTONUP:case WM_MBUTTONUP: + ReleaseCapture(); + id=BBEVENT_MOUSEUP; + data=(msg==WM_LBUTTONUP) ? 1 : (msg==WM_RBUTTONUP ? 2 : 3); + x=(short)LOWORD(lp); + y=(short)HIWORD(lp); + break; + case WM_MOUSEMOVE: + x=(short)LOWORD(lp); + y=(short)HIWORD(lp); + if (wp&MK_LBUTTON) data=1; + if (wp&MK_MBUTTON) data=4; + if (wp&MK_RBUTTON) data=2; + GetClientRect( hwnd,&rect ); + inRect=(x>=0 && y>=0 && xlength ? bbTmpWString( dir ) : 0; + of.nMaxFile=MAX_PATH; + of.Flags=OFN_HIDEREADONLY|OFN_NOCHANGEDIR; + + beginPanel(); + if( save ){ + of.lpstrDefExt=L""; + of.Flags|=OFN_OVERWRITEPROMPT; + if( GetSaveFileNameW( &of ) ){ + str=bbStringFromWString( buf ); + } + }else{ + of.Flags|=OFN_FILEMUSTEXIST; + if( GetOpenFileNameW( &of ) ){ + str=bbStringFromWString( buf ); + } + } + endPanel(); + }else{ + char buf[MAX_PATH]; + OPENFILENAMEA of={sizeof(of)}; + + strcpy( buf,bbTmpCString( file ) ); + + of.hwndOwner=GetActiveWindow(); + of.lpstrTitle=bbTmpCString( text ); + of.lpstrFilter=bbTmpCString( exts ); + of.nFilterIndex=defext; + of.lpstrFile=buf; + of.lpstrInitialDir=dir->length ? bbTmpCString( dir ) : 0; + of.nMaxFile=MAX_PATH; + of.Flags=OFN_HIDEREADONLY|OFN_NOCHANGEDIR; + + beginPanel(); + + if( save ){ + of.lpstrDefExt=""; + of.Flags|=OFN_OVERWRITEPROMPT; + if( GetSaveFileNameA( &of ) ){ + str=bbStringFromCString( buf ); + } + }else{ + of.Flags|=OFN_FILEMUSTEXIST; + if( GetOpenFileNameA( &of ) ){ + str=bbStringFromCString( buf ); + } + } + endPanel(); + } + return str; +} + +static int CALLBACK BrowseForFolderCallbackW( HWND hwnd,UINT uMsg,LPARAM lp,LPARAM pData ){ + wchar_t szPath[MAX_PATH]; + switch( uMsg ){ + case BFFM_INITIALIZED: + SendMessageW( hwnd,BFFM_SETSELECTIONW,TRUE,pData ); + break; + case BFFM_SELCHANGED: + if( SHGetPathFromIDListW( (LPITEMIDLIST)lp,szPath ) ){ + SendMessageW( hwnd,BFFM_SETSTATUSTEXTW,0,(LPARAM)szPath ); + } + break; + } + return 0; +} + +static int CALLBACK BrowseForFolderCallbackA( HWND hwnd,UINT uMsg,LPARAM lp,LPARAM pData ){ + char szPath[MAX_PATH]; + switch( uMsg ){ + case BFFM_INITIALIZED: + SendMessageA( hwnd,BFFM_SETSELECTIONA,TRUE,pData ); + break; + case BFFM_SELCHANGED: + if( SHGetPathFromIDListA( (LPITEMIDLIST)lp,szPath ) ){ + SendMessageA( hwnd,BFFM_SETSTATUSTEXTA,0,(LPARAM)szPath ); + } + break; + } + return 0; +} + +BBString *bbSystemRequestDir( BBString *text,BBString *dir ){ + + BBString *str=&bbEmptyString; + + if( _usew ){ + LPMALLOC shm; + ITEMIDLIST *idlist; + BROWSEINFOW bi={0}; + wchar_t buf[MAX_PATH],*p; + + GetFullPathNameW( bbTmpWString(dir),MAX_PATH,buf,&p ); + + bi.hwndOwner=GetActiveWindow(); + bi.lpszTitle=bbTmpWString( text ); + bi.ulFlags=BIF_RETURNONLYFSDIRS|BIF_NEWDIALOGSTYLE; + bi.lpfn=BrowseForFolderCallbackW; + bi.lParam=(LPARAM)buf; + + beginPanel(); + idlist=SHBrowseForFolderW(&bi); + endPanel(); + + if( idlist ){ + SHGetPathFromIDListW( idlist,buf ); + str=bbStringFromWString( buf ); + //SHFree( idlist ); //?!? + } + } else { + LPMALLOC shm; + ITEMIDLIST *idlist; + BROWSEINFOA bi={0}; + char buf[MAX_PATH],*p; + + GetFullPathNameA( bbTmpCString(dir),MAX_PATH,buf,&p ); + + bi.hwndOwner=GetActiveWindow(); + bi.lpszTitle=bbTmpCString( text ); + bi.ulFlags=BIF_RETURNONLYFSDIRS|BIF_NEWDIALOGSTYLE; + bi.lpfn=BrowseForFolderCallbackA; + bi.lParam=(LPARAM)buf; + + beginPanel(); + idlist=SHBrowseForFolderA(&bi); + endPanel(); + + if( idlist ){ + SHGetPathFromIDListA( idlist,buf ); + str=bbStringFromCString( buf ); + //SHFree( idlist ); //?!? + } + } + return str; +} + +int bbOpenURL( BBString *url ){ + int n; + if( _usew ){ + n=(int)ShellExecuteW( 0,0,(wchar_t*)bbTmpWString(url),0,0,10 )>32; //SW_SHOWDEFAULT + }else{ + n=(int)ShellExecuteA( 0,0,bbTmpCString(url),0,0,10 )>32; //SW_SHOWDEFAULT + } + return n; +} + +static DWORD WINAPI asyncOpThread( void *t ){ + AsyncOp *p=(AsyncOp*)t; + p->asyncRet=p->asyncOp( p->asyncInfo ); + PostThreadMessage( mainThreadId,WM_BBRESERVED1,0,(LPARAM)p ); +} + +void bbSystemPostSyncOp( BBSyncOp syncOp,BBObject *syncInfo,int asyncRet ){ + AsyncOp *p=(AsyncOp*)malloc( sizeof( AsyncOp ) ); + p->asyncOp=0; + p->asyncRet=asyncRet; + p->syncOp=syncOp; + p->syncInfo=syncInfo; + PostThreadMessage( mainThreadId,WM_BBRESERVED1,0,(LPARAM)p ); +} + +void bbSystemStartAsyncOp( BBAsyncOp asyncOp,int asyncInfo,BBSyncOp syncOp,BBObject *syncInfo ){ + DWORD threadId; + AsyncOp *p=(AsyncOp*)malloc( sizeof( AsyncOp ) ); + BBRETAIN( syncInfo ); + p->asyncOp=asyncOp; + p->asyncInfo=asyncInfo; + p->syncOp=syncOp; + p->syncInfo=syncInfo; + CreateThread( 0,0,asyncOpThread,p,0,&threadId ); +} + +int bbSystemDesktopWidth(){ + return GetDeviceCaps( GetDC( GetDesktopWindow() ),HORZRES ); +} + +int bbSystemDesktopHeight(){ + return GetDeviceCaps( GetDC( GetDesktopWindow() ),VERTRES ); +} + +int bbSystemDesktopDepth(){ + return GetDeviceCaps( GetDC( GetDesktopWindow() ),BITSPIXEL ); +} + +int bbSystemDesktopHertz(){ + return GetDeviceCaps( GetDC( GetDesktopWindow() ),VREFRESH ); +} diff --git a/mod/brl.mod/textstream.mod/textstream.bmx b/mod/brl.mod/textstream.mod/textstream.bmx new file mode 100644 index 0000000..b3bbab5 --- /dev/null +++ b/mod/brl.mod/textstream.mod/textstream.bmx @@ -0,0 +1,398 @@ + +Strict + +Rem +bbdoc: Streams/Text streams +about: +The Text Stream module allows you to load and save text in a number +of formats: LATIN1, UTF8 and UTF16. + +The LATIN1 format uses a single byte to represent each character, and +is therefore only capable of manipulating 256 distinct character values. + +The UTF8 and UTF16 formats are capable of manipulating up to 1114112 +character values, but will generally use greater storage space. In addition, +many text processing applications are unable to handle UTF8 and UTF16 files. +End Rem +Module BRL.TextStream + +ModuleInfo "Version: 1.03 " +ModuleInfo "Author: Mark Sibly" +ModuleInfo "License: zlib/libpng" +ModuleInfo "Copyright: Blitz Research Ltd" +ModuleInfo "Modserver: BRL" + +ModuleInfo "History: 1.03 Release" +ModuleInfo "History: Modified LoadText to handle stream URLs" +ModuleInfo "History: 1.02 Release" +ModuleInfo "History: Added LoadText, SaveText" +ModuleInfo "History: Fixed UTF16LE=4" +ModuleInfo "History: 1.01 Release" +ModuleInfo "History: 1.00 Release" +ModuleInfo "History: Added TextStream module" + +Import BRL.Stream + +Type TTextStream Extends TStreamWrapper + + '***** PUBLIC ***** + + Const LATIN1=1 + Const UTF8=2 + Const UTF16BE=3 + Const UTF16LE=4 + + Method Read( buf:Byte Ptr,count ) + For Local i=0 Until count + If _bufcount=32 _FlushRead + Local hi=_ReadByte() + Local lo=_ReadByte() + hi:-48;If hi>9 hi:-7 + lo:-48;If lo>9 lo:-7 + buf[i]=hi Shl 4 | lo + _bufcount:+1 + Next + Return count + End Method + + Method Write( buf:Byte Ptr,count ) + For Local i=0 Until count + Local hi=buf[i] Shr 4 + Local lo=buf[i] & $f + hi:+48;If hi>57 hi:+7 + lo:+48;If lo>57 lo:+7 + _WriteByte hi + _WriteByte lo + _bufcount:+1 + If _bufcount=32 _FlushWrite + Next + Return count + End Method + + Method ReadByte() + _FlushRead + Return Int( ReadLine() ) + End Method + + Method WriteByte( n ) + _FlushWrite + WriteLine n + End Method + + Method ReadShort() + _FlushRead + Return Int( ReadLine() ) + End Method + + Method WriteShort( n ) + _FlushWrite + WriteLine n + End Method + + Method ReadInt() + _FlushRead + Return Int( ReadLine() ) + End Method + + Method WriteInt( n ) + _FlushWrite + WriteLine n + End Method + + Method ReadLong:Long() + _FlushRead + Return Long( ReadLine() ) + End Method + + Method WriteLong( n:Long ) + _FlushWrite + WriteLine n + End Method + + Method ReadFloat:Float() + _FlushRead + Return Float( ReadLine() ) + End Method + + Method WriteFloat( n:Float ) + _FlushWrite + WriteLine n + End Method + + Method ReadDouble:Double() + _FlushRead + Return Double( ReadLine() ) + End Method + + Method WriteDouble( n:Double ) + _FlushWrite + WriteLine n + End Method + + Method ReadLine$() + _FlushRead + Local buf:Short[1024],i + While Not Eof() + Local n=ReadChar() + If n=0 Exit + If n=10 Exit + If n=13 Continue + If buf.length=i buf=buf[..i+1024] + buf[i]=n + i:+1 + Wend + Return String.FromShorts(buf,i) + End Method + + Method ReadFile$() + _FlushRead + Local buf:Short[1024],i + While Not Eof() + Local n=ReadChar() + If buf.length=i buf=buf[..i+1024] + buf[i]=n + i:+1 + Wend + Return String.FromShorts( buf,i ) + End Method + + Method WriteLine( str$ ) + _FlushWrite + WriteString str + WriteString "~r~n" + End Method + + Method ReadString$( length ) + _FlushRead + Local buf:Short[length] + For Local i=0 Until length + buf[i]=ReadChar() + Next + Return String.FromShorts(buf,length) + End Method + + Method WriteString( str$ ) + _FlushWrite + For Local i=0 Until str.length + WriteChar str[i] + Next + End Method + + Method ReadChar() + Local c=_ReadByte() + Select _encoding + Case LATIN1 + Return c + Case UTF8 + If c<128 Return c + Local d=_ReadByte() + If c<224 Return (c-192)*64+(d-128) + Local e=_ReadByte() + If c<240 Return (c-224)*4096+(d-128)*64+(e-128) + Case UTF16BE + Local d=_ReadByte() + Return c Shl 8 | d + Case UTF16LE + Local d=_ReadByte() + Return d Shl 8 | c + End Select + End Method + + Method WriteChar( char ) + Assert char>=0 And char<=$ffff + Select _encoding + Case LATIN1 + _WriteByte char + Case UTF8 + If char<128 + _WriteByte char + Else If char<2048 + _WriteByte char/64 | 192 + _WriteByte char Mod 64 | 128 + Else + _WriteByte char/4096 | 224 + _WriteByte char/64 Mod 64 | 128 + _WriteByte char Mod 64 | 128 + EndIf + Case UTF16BE + _WriteByte char Shr 8 + _WriteByte char + Case UTF16LE + _WriteByte char + _WriteByte char Shr 8 + End Select + End Method + + Function Create:TTextStream( stream:TStream,encoding ) + Local t:TTextStream=New TTextStream + t._encoding=encoding + t.SetStream stream + Return t + End Function + + '***** PRIVATE ***** + + Method _ReadByte() + Return Super.ReadByte() + End Method + + Method _WriteByte( n ) + Super.WriteByte n + End Method + + Method _FlushRead() + If Not _bufcount Return + Local n=_ReadByte() + If n=13 n=_ReadByte() + If n<>10 Throw "Malformed line terminator" + _bufcount=0 + End Method + + Method _FlushWrite() + If Not _bufcount Return + _WriteByte 13 + _WriteByte 10 + _bufcount=0 + End Method + + Field _encoding,_bufcount + +End Type + +Type TTextStreamFactory Extends TStreamFactory + + Method CreateStream:TStream( url:Object,proto$,path$,readable,writeable ) + Local encoding + Select proto$ + Case "latin1" + encoding=TTextStream.LATIN1 + Case "utf8" + encoding=TTextStream.UTF8 + Case "utf16be" + encoding=TTextStream.UTF16BE + Case "utf16le" + encoding=TTextStream.UTF16LE + End Select + If Not encoding Return + Local stream:TStream=OpenStream( path,readable,writeable ) + If stream Return TTextStream.Create( stream,encoding ) + End Method +End Type + +New TTextStreamFactory + +Rem +bbdoc: Load text from a stream +returns: A string containing the text +about: +#LoadText loads LATIN1, UTF8 or UTF16 text from @url. + +The first bytes read from the stream control the format of the text: +[ &$fe $ff | Text is big endian UTF16 +* &$ff $fe | Text is little endian UTF16 +* &$ef $bb $bf | Text is UTF8 +] + +If the first bytes don't match any of the above values, the stream +is assumed to contain LATIN1 text. + +A #TStreamReadException is thrown if not all bytes could be read. +End Rem +Function LoadText$( url:Object ) + + Local stream:TStream=ReadStream( url ) + If Not stream Throw New TStreamReadException + + Local format,size,c,d,e + + If Not stream.Eof() + c=stream.ReadByte() + size:+1 + If Not stream.Eof() + d=stream.ReadByte() + size:+1 + If c=$fe And d=$ff + format=TTextStream.UTF16BE + Else If c=$ff And d=$fe + format=TTextStream.UTF16LE + Else If c=$ef And d=$bb + If Not stream.Eof() + e=stream.ReadByte() + size:+1 + If e=$bf format=TTextStream.UTF8 + EndIf + EndIf + EndIf + EndIf + + If Not format + Local data:Byte[1024] + data[0]=c;data[1]=d;data[2]=e + While Not stream.Eof() + If size=data.length data=data[..size*2] + size:+stream.Read( (Byte Ptr data)+size,data.length-size ) + Wend + stream.Close + Return String.FromBytes( data,size ) + EndIf + + Local TStream:TTextStream=TTextStream.Create( stream,format ) + Local str$=TStream.ReadFile() + TStream.Close + stream.Close + Return str + +End Function + +Rem +bbdoc: Save text to a stream +about: +#SaveText saves the characters in @str to @url. + +If @str contains any characters with a character code greater than 255, +then @str is saved in UTF16 format. Otherwise, @str is saved in LATIN1 format. + +A #TStreamWriteException is thrown if not all bytes could be written. +End Rem +Function SaveText( str$,url:Object ) + + Local format + For Local i=0 Until str.length + If str[i]>255 +?BigEndian + format=TTextStream.UTF16BE +?LittleEndian + format=TTextStream.UTF16LE +? + Exit + EndIf + Next + + If Not format + SaveString str,url + Return True + EndIf + + Local stream:TStream=WriteStream( url ) + If Not stream Throw New TStreamWriteException + + Select format + Case TTextStream.UTF8 + stream.WriteByte $ef + stream.WriteByte $bb + Case TTextStream.UTF16BE + stream.WriteByte $fe + stream.WriteByte $ff + Case TTextStream.UTF16LE + stream.WriteByte $ff + stream.WriteByte $fe + End Select + + Local TStream:TTextStream=TTextStream.Create( stream,format ) + TStream.WriteString str + TStream.Close + stream.Close + Return True + +End Function + diff --git a/mod/brl.mod/tgaloader.mod/tgaloader.bmx b/mod/brl.mod/tgaloader.mod/tgaloader.bmx new file mode 100644 index 0000000..617ae24 --- /dev/null +++ b/mod/brl.mod/tgaloader.mod/tgaloader.bmx @@ -0,0 +1,219 @@ + +Strict + +Rem +bbdoc: Graphics/TGA loader +about: +The TGA loader module provides the ability to load TGA format #pixmaps. +End Rem +Module BRL.TGALoader + +ModuleInfo "Version: 1.07" +ModuleInfo "Author: Simon Armstrong" +ModuleInfo "License: zlib/libpng" +ModuleInfo "Copyright: Blitz Research Ltd" +ModuleInfo "Modserver: BRL" +ModuleInfo "History: 1.07 Release" +ModuleInfo "History: Fixed memory error due to pointer based array reference" +ModuleInfo "History: 1.06 Release" +ModuleInfo "History: Support for Run Length Encoded compression" +ModuleInfo "History: 1.05 Release" +ModuleInfo "History: Fixed 24 bit byte ordering" + +Import BRL.Pixmap +Import BRL.EndianStream + +Const TGA_NULL=0 +Const TGA_MAP=1 +Const TGA_RGB=2 +Const TGA_MONO=3 +Const TGA_RLEMAP=9 +Const TGA_RLERGB=10 +Const TGA_RLEMONO=11 +Const TGA_COMPMAP=32 +Const TGA_COMPMAP4=33 + +Type tgahdr + Field idlen:Byte,colourmaptype:Byte,imgtype:Byte,indexlo:Byte,indexhi:Byte,lenlo:Byte,lenhi:Byte,cosize:Byte + Field x0:Short,y0:Short,width:Short,height:Short + Field psize:Byte,attbits:Byte +End Type + +Function makeargb(a,r,g,b) +?BigEndian + Return (b Shl 24)|(g Shl 16)|(r Shl 8)|a +? + Return (a Shl 24)|(r Shl 16)|(g Shl 8)|b +End Function + +Type TPixmapLoaderTGA Extends TPixmapLoader + + Method LoadPixmap:TPixmap( stream:TStream ) + Local hdr:tgahdr + Local w,h,tgatype,bits + Local buffer[] + Local sbuffer:Short[] + Local bbuffer:Byte[] + Local i,x,y,t,a + Local pixmap:TPixmap + + stream=LittleEndianStream( stream ) + hdr=New tgahdr + If stream.ReadBytes( hdr,8 )<>8 Return Null + hdr.x0=stream.ReadShort() + hdr.y0=stream.ReadShort() + hdr.width=stream.ReadShort() + hdr.height=stream.ReadShort() + hdr.psize=stream.ReadByte() + hdr.attbits=stream.ReadByte() + + bits=hdr.psize + w=hdr.width + h=hdr.height + tgatype=hdr.imgtype + + If hdr.colourmaptype Return Null + If Not (tgatype=TGA_MAP Or tgatype=TGA_RGB Or tgatype=TGA_RLERGB) Return Null + If Not (bits=15 Or bits=16 Or bits=24 Or bits=32) Return Null + If w<1 Or w>4096 Return Null + If h<1 Or h>4096 Return Null + + If bits=16 Or bits=32 + pixmap=CreatePixmap( w,h,PF_RGBA8888) + Else + pixmap=CreatePixmap( w,h,PF_RGB888) + EndIf + + For i=1 To hdr.idlen + stream.ReadByte + Next + + buffer=New Int[w] + bbuffer=New Byte[w*3] + + Select tgatype + Case TGA_RGB + For y=h-1 To 0 Step -1 + Select bits + Case 15 + For x=0 Until w + t=stream.ReadShort() + buffer[x]=makeargb(255,(t Shr 7)&$f8,(t Shr 2)&$f8,(t Shl 3)&$f8) + Next + Case 16 + For x=0 Until w + t=stream.ReadShort() + a=255 + If (t&$8000) a=0 + buffer[x]=makeargb(a,(t Shr 7)&$f8,(t Shr 2)&$f8,(t Shl 3)&$f8) + Next + Case 24 + stream.readbytes(bbuffer,w*3) + For x=0 Until w + buffer[x]=makeargb(255,bbuffer[x*3+2],bbuffer[x*3+1],bbuffer[x*3+0]) + Next + Case 32 + stream.readbytes(buffer,w*4) + End Select + ConvertPixels(buffer,PF_BGRA8888,pixmap.pixelptr(0,y),pixmap.format,w) + Next + Case TGA_RLERGB + Local n,argb + For y=h-1 To 0 Step -1 + x=0 + Select bits + Case 15 + While x + +//***** Threads ***** +BBThread *threads_CreateThread( BBThreadProc entry,BBObject *data ){ + BBThread *thread=bbThreadCreate( entry,data ); + bbThreadResume( thread ); + return thread; +} + +void threads_DetachThread( BBThread *thread ){ + bbThreadDetach( thread ); +} + +BBObject *threads_WaitThread( BBThread *thread ){ + return bbThreadWait( thread ); +} + +//***** Mutexes ***** +bb_mutex_t *threads_CreateMutex(){ + bb_mutex_t *mutex=malloc( sizeof(bb_mutex_t) ); + if( bb_mutex_init( mutex ) ) return mutex; + free( mutex ); + return 0; +} + +void threads_CloseMutex( bb_mutex_t *mutex ){ + bb_mutex_destroy( mutex ); + free( mutex ); +} + +void threads_LockMutex( bb_mutex_t *mutex ){ + bb_mutex_lock( mutex ); +} + +void threads_UnlockMutex( bb_mutex_t *mutex ){ + bb_mutex_unlock( mutex ); +} + +int threads_TryLockMutex( bb_mutex_t *mutex ){ + return bb_mutex_trylock( mutex ); +} + +//***** Semaphores ***** +bb_sem_t *threads_CreateSemaphore( int count ){ + bb_sem_t *sem=malloc( sizeof(bb_sem_t) ); + if( bb_sem_init( sem,count ) ) return sem; + free( sem ); + return 0; +} + +void threads_CloseSemaphore( bb_sem_t *sem ){ + bb_sem_destroy( sem ); + free( sem ); +} + +void threads_WaitSemaphore( bb_sem_t *sem ){ + bb_sem_wait( sem ); +} + +void threads_PostSemaphore( bb_sem_t *sem ){ + bb_sem_post( sem ); +} + +//***** CondVars ***** +#ifdef _WIN32 + +typedef struct BBCond BBCond; + +struct BBCond{ + int waiters; + bb_sem_t sema; +}; + +BBCond *threads_CreateCond(){ + BBCond *cond=(BBCond*)malloc( sizeof( BBCond ) ); + + cond->waiters=0; + bb_sem_init( &cond->sema,0 ); + + return cond; +} + +void threads_CloseCond( BBCond *cond ){ + bb_sem_destroy( &cond->sema ); + free( cond ); +} + +void threads_WaitCond( BBCond *cond,bb_mutex_t *mutex ){ + bbAtomicAdd( &cond->waiters,1 ); + + //Ok, the below is not strictly speaking 'fair'. + //A context switch below the mutex_unlock and sem_wait could end up + //starving this thread (I think). Possibly not a problem unless app is + //really thrashing, but should be fixed none-the-less. + // + bb_mutex_unlock( mutex ); + + bb_sem_wait( &cond->sema ); + + bb_mutex_lock( mutex ); +} + +void threads_SignalCond( BBCond *cond ){ + int waiters; + while( waiters=cond->waiters ){ + if( bbAtomicCAS( &cond->waiters,waiters,waiters-1 ) ){ + bb_sem_post( &cond->sema ); + return; + } + } +} + +void threads_BroadcastCond( BBCond *cond ){ + int waiters; + while( waiters=cond->waiters ){ + if( bbAtomicCAS( &cond->waiters,waiters,0 ) ){ + while( waiters-- ){ + bb_sem_post( &cond->sema ); + } + return; + } + } +} + +#else + +pthread_cond_t *threads_CreateCond(){ + pthread_cond_t *cond=malloc( sizeof( pthread_cond_t ) ); + if( pthread_cond_init( cond,0 )>=0 ) return cond; + free( cond ); + return 0; +} + +void threads_CloseCond( pthread_cond_t *cond ){ + pthread_cond_destroy( cond ); + free( cond ); +} + +void threads_WaitCond( pthread_cond_t *cond,bb_mutex_t *mutex ){ + pthread_cond_wait( cond,mutex ); +} + +void threads_SignalCond( pthread_cond_t *cond ){ + pthread_cond_signal( cond ); +} + +void threads_BroadcastCond( pthread_cond_t *cond ){ + pthread_cond_broadcast( cond ); +} + +#endif diff --git a/mod/brl.mod/timer.mod/doc/waittimer.bmx b/mod/brl.mod/timer.mod/doc/waittimer.bmx new file mode 100644 index 0000000..6c9a147 --- /dev/null +++ b/mod/brl.mod/timer.mod/doc/waittimer.bmx @@ -0,0 +1,8 @@ + +timer=CreateTimer( 10 ) + +Repeat + Print "Ticks="+WaitTimer( timer ) +Forever + + diff --git a/mod/brl.mod/timer.mod/timer.bmx b/mod/brl.mod/timer.mod/timer.bmx new file mode 100644 index 0000000..75d4c5f --- /dev/null +++ b/mod/brl.mod/timer.mod/timer.bmx @@ -0,0 +1,137 @@ + +Strict + +Rem +bbdoc: Events/Timers +End Rem +Module BRL.Timer + +ModuleInfo "Version: 1.02" +ModuleInfo "Author: Simon Armstrong, Mark Sibly" +ModuleInfo "License: zlib/libpng" +ModuleInfo "Copyright: Blitz Research Ltd" +ModuleInfo "Modserver: BRL" + +Rem +History: + +Removed use of _cycle:TTimer field to keep timer's alive - didn't work with 'real' GC! +Replaced with BBRETAIN/BBRELEASE in C code. + +Added check for OS timer creation failure + +Added check for Win32 timer firing after timeKillEvent + +Removed brl.standardio dependancy +End Rem + +Import BRL.System + +?Win32 +Import "timer.win32.c" +?MacOS +Import "timer.macos.m" +?Linux +Import "timer.linux.c" +? + +Extern +Function bbTimerStart( hertz#,timer:TTimer ) +Function bbTimerStop( handle,timer:TTimer ) +End Extern + +Function _TimerFired( timer:TTimer ) + timer.Fire +End Function + +Type TTimer + + Method Ticks() + Return _ticks + End Method + + Method Stop() + If Not _handle Return + bbTimerStop _handle,Self + _handle=0 + _event=Null +' _cycle=Null + End Method + + Method Fire() + If Not _handle Return + _ticks:+1 + If _event + EmitEvent _event + Else + EmitEvent CreateEvent( EVENT_TIMERTICK,Self,_ticks ) + EndIf + End Method + + Method Wait() + If Not _handle Return + Local n + Repeat + WaitSystem + n=_ticks-_wticks + Until n + _wticks:+n + Return n + End Method + + Function Create:TTimer( hertz#,event:TEvent=Null ) + Local t:TTimer=New TTimer + Local handle=bbTimerStart( hertz,t ) + If Not handle Return +' t._cycle=t + t._event=event + t._handle=handle + Return t + End Function + + Field _ticks + Field _wticks + Field _cycle:TTimer 'no longer used...see history + Field _event:TEvent + Field _handle + +End Type + +Rem +bbdoc: Create a timer +returns: A new timer object +about: +#CreateTimer creates a timer object that 'ticks' @hertz times per second. + +Each time the timer ticks, @event will be emitted using #EmitEvent. + +If @event is Null, an event with an @id equal to EVENT_TIMERTICK and +@source equal to the timer object will be emitted instead. +End Rem +Function CreateTimer:TTimer( hertz#,event:TEvent=Null ) + Return TTimer.Create( hertz,event ) +End Function + +Rem +bbdoc: Get timer tick counter +returns: The number of times @timer has ticked over +End Rem +Function TimerTicks( timer:TTimer ) + Return timer.Ticks() +End Function + +Rem +bbdoc: Wait until a timer ticks +returns: The number of ticks since the last call to #WaitTimer +End Rem +Function WaitTimer( timer:TTimer ) + Return timer.Wait() +End Function + +Rem +bbdoc: Stop a timer +about:Once stopped, a timer can no longer be used. +End Rem +Function StopTimer( timer:TTimer ) + timer.Stop +End Function diff --git a/mod/brl.mod/timer.mod/timer.linux.c b/mod/brl.mod/timer.mod/timer.linux.c new file mode 100644 index 0000000..cedc66f --- /dev/null +++ b/mod/brl.mod/timer.mod/timer.linux.c @@ -0,0 +1,83 @@ + +//Oh the fun...no multiple timers in Linux (!) so we have to roll our own... +// +#include + +#include + +typedef struct BBTimer{ + pthread_t thread; + int status; + int puts; + int gets; + int start; + int period; + BBObject *bbTimer; +}BBTimer; + +extern int bbMilliSecs(); +extern void bbDelay( int millis ); + +extern void brl_timer__TimerFired( BBObject *bbTimer ); + +static void timerSyncOp( BBObject *user,int ret ){ + BBTimer *timer=(BBTimer*)ret; + + ++timer->gets; + + switch( timer->status ){ + case 1: + brl_timer__TimerFired( timer->bbTimer ); + break; + case 2: + if( timer->puts==timer->gets ){ + BBRELEASE( timer->bbTimer ); + free( timer ); + } + break; + } +} + +static void *timerProc( void *data ){ + BBTimer *timer=(BBTimer*)data; + + int time=timer->start; + + while( timer->status==1 ){ + time+=timer->period; + + bbDelay( time-bbMilliSecs() ); + + ++timer->puts; + bbSystemPostSyncOp( timerSyncOp,&bbNullObject,(int)timer ); + } + + bbSystemPostSyncOp( timerSyncOp,&bbNullObject,(int)timer ); +} + +BBTimer *bbTimerStart( float hertz,BBObject *bbTimer ){ + BBTimer *timer; + int start=bbMilliSecs(); + + timer=(BBTimer*)malloc( sizeof( BBTimer ) ); + + timer->status=1; + timer->puts=1; + timer->gets=0; + timer->start=start; + timer->period=1000.0f/hertz; + timer->bbTimer=bbTimer; + + if( pthread_create( &timer->thread,0,(void*(*)(void*))timerProc,timer )<0 ){ + free( timer ); + return 0; + } + + BBRETAIN( timer->bbTimer ); + + return timer; +} + +void bbTimerStop( BBTimer *timer,BBObject *bbTimer ){ + timer->status=2; +} diff --git a/mod/brl.mod/timer.mod/timer.macos.m b/mod/brl.mod/timer.mod/timer.macos.m new file mode 100644 index 0000000..62cdfaf --- /dev/null +++ b/mod/brl.mod/timer.mod/timer.macos.m @@ -0,0 +1,46 @@ + +#import + +#include + +void brl_timer__TimerFired( void *data ); + +@interface BBTimer : NSObject{ + NSTimer *_timer; + void *_data; +} +-(id)initWithPeriod:(double)period data:(void*)data; +-(void)stop; +@end + +@implementation BBTimer +-(id)initWithPeriod:(double)period data:(void*)data{ + self=[super init]; + _timer=[NSTimer scheduledTimerWithTimeInterval:period target:self selector:@selector(onTick:) userInfo:nil repeats:YES]; + _data=data; + return self; +} +-(void)stop{ + [_timer invalidate]; + _timer=0; +} +-(void)onTick:(NSTimer*)timer{ + brl_timer__TimerFired( _data ); +} +@end + +BBTimer *bbTimerStart( float hertz,BBObject *bbTimer ){ + BBTimer *timer=[[BBTimer alloc] initWithPeriod:1.0/hertz data:bbTimer]; + if( !timer ) return 0; + + BBRETAIN( bbTimer ); + + return timer; +} + +void bbTimerStop( BBTimer *timer,BBObject *bbTimer ){ + [timer stop]; + [timer release]; + + BBRELEASE( bbTimer ); +} diff --git a/mod/brl.mod/timer.mod/timer.win32.c b/mod/brl.mod/timer.mod/timer.win32.c new file mode 100644 index 0000000..0d650c5 --- /dev/null +++ b/mod/brl.mod/timer.mod/timer.win32.c @@ -0,0 +1,48 @@ + +#include +#include +#include + +#include + +#define MAX_TIMERS 16 + +void brl_timer__TimerFired( BBObject *bbTimer ); + +static int timers[MAX_TIMERS],n_timers; + +static void timerSyncOp( BBObject *bbTimer,int timer ){ + int i; + for( i=0;i4 Return + Return Chr(tag[0])+Chr(tag[1])+Chr(tag[2])+Chr(tag[3]) +End Function + +Public + +Type TAudioSampleLoaderWAV Extends TAudioSampleLoader + + Method LoadAudioSample:TAudioSample( stream:TStream ) + + stream=LittleEndianStream(stream) + + If ReadTag( stream )<>"RIFF" Return + + Local w_len=stream.ReadInt()-8 + + If ReadTag( stream )<>"WAVE" Return + If ReadTag( stream )<>"fmt " Return + + Local w_len2=stream.ReadInt() + + Local w_comp=stream.ReadShort() + If w_comp<>1 Return + + Local w_chans=stream.ReadShort() + Local w_hz=stream.ReadInt() + Local w_bytespersec=stream.ReadInt() + Local w_pad=stream.ReadShort() + Local w_bits=stream.ReadShort() + + Local format=0 + Select True + Case w_bits=8 And w_chans=1 + format=SF_MONO8 + Case w_bits=8 And w_chans=2 + format=SF_STEREO8 + Case w_bits=16 And w_chans=1 + format=SF_MONO16LE + Case w_bits=16 And w_chans=2 + format=SF_STEREO16LE + Default + Return + End Select + + If w_len2>16 stream.SkipBytes( w_len2-16 ) + + While Not stream.Eof() + + Local tag$=Readtag( stream ) + If tag<>"data" + Local sz=stream.ReadInt() + stream.SkipBytes( sz ) + Continue + EndIf + + Local w_sizebytes=stream.ReadInt() + Local length=w_sizebytes/BytesPerSample[format],hertz=w_hz + Local t:TAudioSample=TAudioSample.Create( length,hertz,format ) + + stream.ReadBytes t.samples,w_sizebytes + + Return t + + Wend + + End Method + +End Type + +AddAudioSampleLoader New TAudioSampleLoaderWAV diff --git a/mod/maxgui.mod/cocoamaxgui.mod/cocoa.macos.m b/mod/maxgui.mod/cocoamaxgui.mod/cocoa.macos.m new file mode 100644 index 0000000..029311e --- /dev/null +++ b/mod/maxgui.mod/cocoamaxgui.mod/cocoa.macos.m @@ -0,0 +1,8892 @@ +// cocoa.macos.m + +// blitzmax cocoa interface + +// by simonarmstrong@blitzbasic.com + + + +// removed lowfi pointer bitmaps + +// fixed xcode 5.1 compiler conformance + + + +#include + +#include + +#include a + +#include + +#include + +#include + +#include + + + +#include + +#include + +#include + + + +#define STATUSBARHEIGHT 18 + + + +void brl_event_EmitEvent(BBObject *event); + +BBObject *maxgui_maxgui_HotKeyEvent(int key,int mods); + +void maxgui_maxgui_DispatchGuiEvents(); + +void maxgui_cocoamaxgui_EmitCocoaOSEvent(NSEvent *event,void *handle,BBObject *gadget); + +int maxgui_cocoamaxgui_EmitCocoaMouseEvent(NSEvent *event,void *handle); + +int maxgui_cocoamaxgui_EmitCocoaKeyEvent(NSEvent *event,void *handle); + +void maxgui_cocoamaxgui_PostCocoaGuiEvent(int ev,void *handle,int data,int mods,int x,int y,BBObject *extra); + + + +int maxgui_cocoamaxgui_FilterChar(void *handle,int key,int mods); + +int maxgui_cocoamaxgui_FilterKeyDown(void *handle,int key,int mods); + + + +static void EmitOSEvent(NSEvent *event,void *handle){ + + maxgui_cocoamaxgui_EmitCocoaOSEvent(event,handle,&bbNullObject); + +} + + + +int HaltMouseEvents; + + + +static int EmitMouseEvent(NSEvent *event,void *handle){ + + if(([event type] == NSScrollWheel) && ([event deltaY] == 0)) return 0; + + if(!HaltMouseEvents) return maxgui_cocoamaxgui_EmitCocoaMouseEvent(event,handle); + +} + + + +static int EmitKeyEvent(NSEvent *event,void *handle){ + + return maxgui_cocoamaxgui_EmitCocoaKeyEvent(event,handle); + +} + + + +static void PostGuiEvent(int ev,void *handle,int data,int mods,int x,int y,BBObject *extra){ + + if (extra==0) extra=&bbNullObject; + + maxgui_cocoamaxgui_PostCocoaGuiEvent(ev,handle,data,mods,x,y,extra); + +} + + + +static int filterKeyDownEvent(NSEvent *event,id source){ + + int i,sz,res,key,mods; + + NSString *ch; + + key=bbSystemTranslateKey([event keyCode]); + + mods=bbSystemTranslateMods([event modifierFlags]); + + res=maxgui_cocoamaxgui_FilterKeyDown(source,key,mods); + + if (res==0) return 0; + + ch=[event characters]; + + sz=[ch length]; + + for(i=0;i)sender; + +-(BOOL)performDragOperation:(id )sender; + +-(void)didResize; + +-(void)didMove; + +-(void)zoom; + +-(NSRect)localRect; + +-(BOOL)canBecomeKeyWindow; + +-(BOOL)canBecomeMainWindow; + +-(BOOL)becomeFirstResponder; + +-(void)setEnabled:(BOOL)flag; + +-(BOOL)isEnabled; + +-(void)dealloc; + +@end + + + +@interface ToolView:NSPanel{ + + id view; + + id label[3]; + + nsgadget *gadget; + + int enabled; + + int zooming; + + NSView *dragging; + +} + +-(id)textFirstResponder; + +-(id)initWithContentRect:(NSRect)rect styleMask:(unsigned int)mask backing:(NSBackingStoreType)backing defer:(BOOL)flag withGadget:(nsgadget*)_gadget; + +-(id)clientView; + +-(void)setStatus:(NSString*)text align:(int)pos; + +-(void)sendEvent:(NSEvent*)event; + +-(NSDragOperation)draggingEntered:(id )sender; + +-(BOOL)performDragOperation:(id )sender; + +-(void)didResize; + +-(void)didMove; + +-(void)zoom; + +-(NSRect)localRect; + +-(BOOL)canBecomeKeyWindow; + +-(BOOL)canBecomeMainWindow; + +-(BOOL)becomeFirstResponder; + +-(void)setEnabled:(BOOL)flag; + +-(BOOL)isEnabled; + +-(void)dealloc; + +@end + + + +static CocoaApp *GlobalApp; + + + +@class HTMLView; + +@interface HTMLView:WebView{ + + int _state,_style; + +} + +-(id)initWithFrame:(NSRect)rect; + +-(int)loaded; + +-(void)setStyle:(int)style; + +-(void)setAddress:(NSString*)address; + +-(NSString*)address; + +@end + +@implementation HTMLView + +-(id)initWithFrame:(NSRect)rect{ + + self=[super initWithFrame:rect]; + + [self setAutoresizingMask:NSViewNotSizable]; + + [self setPolicyDelegate:self]; + + [self setFrameLoadDelegate:self]; + + [self setUIDelegate:self]; + + [self unregisterDraggedTypes]; + + _state=0; + + return self; + +} + +-(int)loaded{ + + return _state; + +} + +-(void)setStyle:(int)style{ + + _style=style; + +} + +-(NSString*)address{ + + WebDataSource *datasource; + + datasource=[[self mainFrame] provisionalDataSource]; + + if(datasource==nil) datasource=[[self mainFrame] dataSource]; + + if(datasource==nil) return [[NSString alloc] initWithString:@""]; + + return [[[datasource request] URL] absoluteString]; + +} + +-(void)setAddress:(NSString*)address{ + + NSURL *url; + + NSURLRequest *request; + + WebFrame *frame; + + + + url=[NSURL URLWithString:address]; + + if (url==nil) url=[NSURL fileURLWithPath:address]; + + if (url==nil) return; + + _state=1; + + request=[NSURLRequest requestWithURL:url]; + + frame=[self mainFrame]; + + [frame loadRequest:request]; + +} + +- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame{ + + int oldstate=_state; + + NSURLRequest *url; + + BBString*text; + + + + _state=0; + + + + url=[[frame dataSource]initialRequest]; + + text=bbStringFromCString((char*)[[[url URL] relativePath] cString]); + + + + if(oldstate) + + PostGuiEvent(BBEVENT_GADGETDONE,sender,0,0,0,0,(BBObject*)text); + +} + +- (void)webView:(WebView *)sender didChangeLocationWithinPageForFrame:(WebFrame *)frame{ + + int oldstate=_state; + + NSURLRequest *url; + + BBString*text; + + _state=0; + + url=[[frame dataSource]initialRequest]; + + text=bbStringFromCString((char*)[[[url URL] relativePath] cString]); + + if(oldstate) + + PostGuiEvent(BBEVENT_GADGETDONE,sender,0,0,0,0,(BBObject*)text); + +} + +- (void)webView:(WebView *)sender decidePolicyForNavigationAction:(NSDictionary *)actionInformation request:(NSURLRequest *)url frame:(WebFrame *)frame decisionListener:(id)listener{ + + BBString*text; + + int key; + + key=(int)[[actionInformation objectForKey:WebActionNavigationTypeKey] intValue]; + + switch (key){ + + case WebNavigationTypeOther: + + case WebNavigationTypeLinkClicked: + + if ((_state==0) && (_style & HTMLVIEW_NONAVIGATE)) { + + [listener ignore]; + + text=bbStringFromCString((char*)[[[url URL] absoluteString] cString]); + + PostGuiEvent(BBEVENT_GADGETACTION,sender,0,0,0,0,(BBObject*)text); + + }else{ + + [listener use]; + + } + + default: + + [listener use]; + + } + +} + +- (NSArray *)webView:(WebView *)sender contextMenuItemsForElement:(NSDictionary *)element defaultMenuItems:(NSArray *)defaultMenuItems{ + + if(_style&HTMLVIEW_NOCONTEXTMENU) + + return [NSArray array]; + + else + + return defaultMenuItems; + +} + +@end + + + + + +//Toolbar + + + +@class Toolbar; + +@interface Toolbar:NSToolbar{ + + NSMutableDictionary *dictionary; + + NSMutableArray *items; + +} + +-(id)initWithIdentifier:(NSString *)string; + +-(void)setToolbarItem:(NSToolbarItem *)item atIndex:(int)index; + +-(void)setSeparatorAtIndex:(int)index; + +-(NSArray *)toolbarAllowedItemIdentifiers; + +-(NSArray *)toolbarDefaultItemIdentifiers; + +@end + +@implementation Toolbar + +-(id)initWithIdentifier:(NSString *)string{ + + self=[super initWithIdentifier:string]; + + dictionary=[[NSMutableDictionary dictionaryWithCapacity:10] retain]; + + items=[[[NSMutableArray alloc] initWithCapacity:10] retain]; + + return self; + +} + +-(void)setToolbarItem:(NSToolbarItem *)item atIndex:(int)index{ + + [items insertObject:item atIndex:(NSUInteger)index]; + + [dictionary setObject:item forKey:[item itemIdentifier]]; + +} + +-(void)setSeparatorAtIndex:(int)index{ + + static NSToolbarItem *NullItem=nil; + + if(NullItem==nil){ + + NullItem=[[NSToolbarItem alloc] retain]; + + } + + [items insertObject:NullItem atIndex:(NSUInteger)index]; + +} + +-(NSArray *)toolbarAllowedItemIdentifiers{ + + return [dictionary allValues]; + +} + +-(NSArray *)toolbarDefaultItemIdentifiers{ + + return [dictionary allValues]; + +} + +@end + + + + + +// CocoaApp + +@implementation CocoaApp + ++(void)dispatchGuiEvents{ + + maxgui_maxgui_DispatchGuiEvents(); + +} + ++(void)delayedGadgetAction:(NSObject*)o{ // See controlTextDidChange + + PostGuiEvent(BBEVENT_GADGETACTION, + + o, + + [o respondsToSelector:@selector(indexOfSelectedItem)] ? [o indexOfSelectedItem] : 0, + + 0,0,0,0); + +} + +-(void)controlTextDidEndEditing:(NSNotification*)n{ + + PostGuiEvent(BBEVENT_GADGETLOSTFOCUS,[n object],0,0,0,0,0); + +} + +-(void)controlTextDidChange:(NSNotification*)n{ + + NSObject *o=[n object]; + + [CocoaApp performSelector:@selector(delayedGadgetAction:) withObject:o afterDelay:0.0]; + +} + + + +-(id)init{ + + toolbaritems=[[NSMutableDictionary dictionaryWithCapacity:10] retain]; + + menuitems=[[NSMutableArray arrayWithCapacity:10] retain]; + + return self; + +} + +-(BOOL)windowShouldClose:(id)sender{ + + PostGuiEvent(BBEVENT_WINDOWCLOSE,sender,0,0,0,0,0); + + return NO; + +} + +-(void)windowDidResize:(NSNotification *)aNotification{ + + WindowView *window; + + ToolView * panel; + + if ([[aNotification object] isKindOfClass:[WindowView class]]) { + + window=(WindowView*)[aNotification object]; + + [window didResize]; + + } else { + + panel =(ToolView*)[aNotification object]; + + [panel didResize]; + + } + +} + +-(void)windowDidMove:(NSNotification *)aNotification{ + + WindowView *window; + + ToolView * panel; + + if ([[aNotification object] isKindOfClass:[WindowView class]]) { + + window=(WindowView*)[aNotification object]; + + [window didMove]; + + } else { + + panel =(ToolView*)[aNotification object]; + + [panel didMove]; + + } + +} + +-(BOOL)windowShouldZoom:(NSWindow *)sender toFrame:(NSRect)newFrame{ + + [(WindowView*)sender zoom]; + + return YES; + +} + +-(void)windowDidBecomeKey:(NSNotification *)aNotification{ + + NSWindow *window; + + window=(NSWindow*)[aNotification object]; + + PostGuiEvent(BBEVENT_WINDOWACTIVATE,window,0,0,0,0,0); + +} + +-(void)menuSelect:(id)sender{ + + PostGuiEvent(BBEVENT_MENUACTION,sender,[sender tag],0,0,0,0); + +} + +-(void)iconSelect:(id)sender{ + + Toolbar *toolbar; + + int index; + + toolbar=[sender toolbar]; + + index=[[toolbar items] indexOfObject:sender]; + + PostGuiEvent(BBEVENT_GADGETACTION,toolbar,index,0,0,0,0); + +} + +-(void)sliderSelect:(id)sender{ + + PostGuiEvent(BBEVENT_GADGETACTION,sender,0,0,0,0,0); + +} + +-(void)scrollerSelect:(id)sender{ + + NSScroller *scroller; + + int delta=0; + + scroller=(NSScroller *)sender; + + switch([scroller hitPart]){ + + case NSScrollerDecrementLine: + + delta=-1; + + break; + + case NSScrollerDecrementPage: + + delta=-2; + + break; + + case NSScrollerIncrementLine: + + delta=1; + + break; + + case NSScrollerIncrementPage: + + delta=2; + + break; + + } + + PostGuiEvent(BBEVENT_GADGETACTION,sender,delta,0,0,0,0); + +} + +-(void)buttonPush:(id)sender{ + + if([sender allowsMixedState]) [sender setAllowsMixedState:NO]; + + PostGuiEvent(BBEVENT_GADGETACTION,sender,0,0,0,0,0); + +} + +-(void)textEdit:(id)sender{ + + PostGuiEvent(BBEVENT_GADGETACTION,sender,0,0,0,0,0); + +} + +-(void)comboBoxSelectionDidChange:(NSNotification *)notification{ + + NSControl *o=(NSComboBox*)[notification object]; + + [CocoaApp performSelector:@selector(delayedGadgetAction:) withObject:o afterDelay:0.0]; + +} + +-(void)comboBoxSelectionIsChanging:(NSNotification *)notification{ + + + +} + +-(void)comboBoxWillPopUp:(NSNotification *)notification{ + + HaltMouseEvents=1; + +} + +-(void)comboBoxWillDismiss:(NSNotification *)notification{ + + HaltMouseEvents=0; + +} + +-(void)addToolbarItem:(NSToolbarItem *)item{ + + [toolbaritems setObject:item forKey:[item itemIdentifier]]; + +} + +-(NSToolbarItem *)toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString *)itemIdentifier willBeInsertedIntoToolbar:(BOOL)flag{ + + return [toolbaritems objectForKey:itemIdentifier]; + +} + +-(NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar *)toolbar{ + + Toolbar *mytoolbar=(Toolbar*)toolbar; + + return [mytoolbar toolbarAllowedItemIdentifiers]; + +} + +-(NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar *)toolbar{ + + Toolbar *mytoolbar=(Toolbar*)toolbar; + + return [mytoolbar toolbarDefaultItemIdentifiers]; + +} + +-(BOOL)validateToolbarItem:(NSToolbarItem *)item{ + + return [item isEnabled]; + +} + +-(void)addMenuItem:(NSMenuItem *)item{ + + [menuitems addObject:item]; + +} + +-(void)removeMenuItem:(NSMenuItem *)item{ + + [menuitems removeObject:item]; + +} + + + +@end + + + +// Scroller + + + +@implementation Scroller + +-(id)init{ + + [super init]; + + [self setAlphaValue:.5f]; + + return self; + +} + +//-(void)drawKnob{} + +//-(void)drawParts{} + +//-(void)drawKnobSlotInRect:(NSRect)slotRect highlight:(BOOL)flag{} + +//-(void)drawArrow:(NSScrollerArrow)arrow highlight:(BOOL)flag{} + +//-(void)highlight:(BOOL)flag{} + +@end + + + +// FlippedView + + + +@implementation FlippedView + +-(BOOL)isFlipped{ + + return YES; + +} + +-(BOOL)mouseDownCanMoveWindow{ + + return YES; + +} + +@end + + + +// PanelView + + + +@implementation PanelView + +- (BOOL)acceptsFirstResponder{ + + return YES; + +} + +-(BOOL)becomeFirstResponder{ + + return [self isEnabled]; + +} + +-(void)setColor:(NSColor *)rgb{ + + [[self contentView] setColor:rgb]; + +} + +-(void)setAlpha:(float)al{ + + [[self contentView] setAlpha:al]; + +} + +-(void)setImage:(NSImage *)img withFlags:(int)flags{ + + [[self contentView] setImage:img withFlags:flags]; + +} + +-(void)setEnabled:(BOOL)e{ + + enabled=e; + +} + +-(BOOL)isEnabled{ + + return (enabled)?YES:NO; + +} + +-(void)setStyle:(int)s{ + + + + gadget->sensitivity |= (s & PANEL_ACTIVE) ? (SENSITIZE_MOUSE|SENSITIZE_KEYS) : 0; + + + + switch (s & (PANEL_SUNKEN|PANEL_RAISED|PANEL_GROUP)){ + + case PANEL_GROUP: + + [self setContentViewMargins: NSMakeSize(4.0,4.0)]; + + [self setBoxType:NSBoxPrimary]; + + [self setBorderType: NSBezelBorder]; + + [self setTitlePosition: NSAtTop]; + + break; + + case PANEL_RAISED: + + case PANEL_SUNKEN: + + [self setContentViewMargins: NSMakeSize(0.0,0.0)]; + + [self setBoxType: NSBoxOldStyle]; + + [self setBorderType: NSLineBorder]; + + [self setTitlePosition: NSNoTitle]; + + break; + + default: + + [self setContentViewMargins: NSMakeSize(0.0,0.0)]; + + [self setBorderType: NSNoBorder]; + + [self setTitlePosition: NSNoTitle]; + + } + + + + style=s; + +} + +-(void)setGadget:(nsgadget*)_gadget{ + + gadget=_gadget; + +} + +-(BOOL)mouseDownCanMoveWindow{ + + return NO; + +} + +@end + + + +//PanelViewContent + +@implementation PanelViewContent + +-(BOOL)isFlipped{ + + return YES; + +} + +-(BOOL)mouseDownCanMoveWindow{ + + return NO; + +} + +-(void)setColor:(NSColor *)rgb{ + + if (color){ + + [color release]; + + color=0; + + } + + if(rgb){ + + color=[rgb colorWithAlphaComponent:1.0]; + + [color retain]; + + } + + [self setNeedsDisplay:YES]; + +} + +-(void)setImage:(NSImage *)img withFlags:(int)flags{ + + if (img) [img retain]; + + if (image) [image release]; + + image=img; + + imageflags=flags; + + [self setNeedsDisplay:YES]; + +} + +-(void)setAlpha:(float)al{ + + alpha=al; + + if (color){ + + [color release]; + + color=[color colorWithAlphaComponent:alpha]; + + [color retain]; + + } + + [self setNeedsDisplay:YES]; + +} + +-(void)drawRect:(NSRect)rect{ + + + + NSRect dest=NSUnionRect(rect,[self frame]); + + + + if (color){ + + [color set]; + + if (alpha<1.0) + + NSRectFillUsingOperation(dest,NSCompositeSourceOver); + + else + + NSRectFill(dest); + + } + + + + if (image){ + + int op,x,y,w,h; + + float a; + + float m,mm; + + NSRect src,tile; + + + + a=alpha; + + op=NSCompositeSourceOver; + + src.origin.x=0; + + src.origin.y=0; + + src.size=[image size]; + + [image setFlipped:YES]; + + + + switch (imageflags&(GADGETPIXMAP_ICON-1)){ + + case PANELPIXMAP_TILE: + + tile.size=[image size]; + + for (y=0;ymm) m=mm; + + dest.origin.x+=(dest.size.width-src.size.width*m)/2; + + dest.origin.y+=(dest.size.height-src.size.height*m)/2; + + dest.size.width=src.size.width*m; + + dest.size.height=src.size.height*m; + + [image drawInRect:dest fromRect:src operation:op fraction:a]; + + break; + + case PANELPIXMAP_STRETCH: + + [image drawInRect:dest fromRect:src operation:op fraction:a]; + + break; + + case PANELPIXMAP_FIT2: + + m=dest.size.width/dest.size.height; + + + + if ((dest.size.width/src.size.width)<(dest.size.height/src.size.height)){ + + src.origin.x=(src.size.width-(src.size.height*m))/2; + + src.size.width=src.size.height*m; + + } else { + + src.origin.y=(src.size.height-(src.size.width/m))/2; + + src.size.height=src.size.width/m; + + } + + + + [image drawInRect:dest fromRect:src operation:op fraction:a]; + + break; + + } + + [image setFlipped:NO]; + + } + + + + [super drawRect:rect]; + +} + +@end + + + +// CanvasView + +@implementation CanvasView + +-(void)drawRect:(NSRect)rect{ + + [super drawRect:rect]; + + PostGuiEvent(BBEVENT_GADGETPAINT,self,0,0,0,0,0); + +} + +- (BOOL)acceptsFirstResponder{ + + return YES; + +} + +-(BOOL)becomeFirstResponder{ + + return [self isEnabled]; + +} + +@end + + + +// ImageString + + + +@class ImageString; + +@interface ImageString:NSObject{ + + NSString *_string; + + NSImage *_image; + + NSString *_tip; + + BBObject *_extra; + +} + +-(id)initWithString:(NSString *)text image:(NSImage *)image tip:(NSString *)tip extra:(BBObject*)extra; + +-(void)dealloc; + +-(id)copyWithZone:(NSZone *)zone; + +-(NSString*)string; + +-(NSImage*)image; + +-(NSString*)description; + +-(BBObject*)extra; + +@end + +@implementation ImageString + +-(id)initWithString:(NSString *)string image:(NSImage *)image tip:(NSString*)tip extra:(BBObject*)extra{ + + _string=string; + + _image=image; + + _tip=tip; + + _extra=extra; + + if (string) [string retain]; + + if (image) [image retain]; + + if (tip) [tip retain]; + + return self; + +} + +-(void)dealloc{ + + if (_string) [_string release]; + + if (_image) [_image release]; + + if (_tip) [_tip release]; + + [super dealloc]; + +} + +-(id)copyWithZone:(NSZone *)zone{ + + ImageString *copy=[[[self class] allocWithZone:zone] initWithString:_string image:_image tip:_tip extra:_extra]; + + return copy; + +} + +-(NSString*)string{return _string;} + +-(NSImage*)image{return _image;} + +-(NSString*)description{return _tip;} + +-(BBObject*)extra{return _extra;} + +@end + + + +// ListView + + + +@implementation ListView + +-(id)initWithFrame:(NSRect)rect{ + + [super initWithFrame:rect]; + + [self setBorderType:NSNoBorder]; + + [self setHasVerticalScroller:YES]; + + [self setHasHorizontalScroller:YES]; + + [self setAutohidesScrollers:YES]; + + column=[[NSTableColumn alloc] init]; + + cell=[[NSBrowserCell alloc] init]; + + [cell setLeaf:YES]; + + [column setDataCell:cell]; + + NSSize contentSize=[self contentSize]; + + table=[[TableView alloc] initWithFrame:NSMakeRect(0,0,contentSize.width,contentSize.height)]; + + [table setAutoresizingMask:(NSViewWidthSizable|NSViewHeightSizable)]; + + items=[[NSMutableArray alloc] initWithCapacity:10]; + + [table setHeaderView:nil]; + + [table setDataSource:self]; + + [table setDelegate:self]; + + [self setDocumentView:table]; + + [table addTableColumn:column]; + + [table sizeLastColumnToFit]; + + return self; + +} + +-(id)table{ + + return table; + +} + +-(id)items{ + + return items; + +} + +-(void)removeItemAtIndex:(int)index{ + + ImageString *item=(ImageString*)[items objectAtIndex:index]; + + [items removeObjectAtIndex:index]; + + [item release]; + + [table reloadData]; + + [self queueWidthUpdate]; + +} + +-(void)setColor:(NSColor*)color{ + + [table setBackgroundColor:color]; + +} + +-(void)setEnabled:(BOOL)e{ + + [table setEnabled:e]; + +} + +-(BOOL)isEnabled{ + + return [table isEnabled]; + +} + +-(void)setTextColor:(NSColor*)color{ + + if (textstyle) {[textstyle release];textstyle=nil;} + + if (color){ + + textstyle=[NSDictionary dictionaryWithObjectsAndKeys:color,NSForegroundColorAttributeName,nil]; + + [textstyle retain]; + + } + +} + +-(int)numberOfRowsInTableView:(NSTableView *)aTableView{ + + return [items count]; + +} + +-(id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex{ + + return [items objectAtIndex:rowIndex]; + +} + +-(BOOL)tableView:(NSTableView *)tableView shouldEditTableColumn:(NSTableColumn *)tableColumn row:(int)rowIndex{ /*new from BAH*/ + + PostGuiEvent(BBEVENT_GADGETACTION,self,rowIndex,0,0,0,0); + + return NO; + +} + +-(void)clear{ + + [table setDelegate:nil]; + + + + ImageString *item; + + int count,i; + + count=[items count]; + + for (i=0;i=0) item=(ImageString*)[items objectAtIndex:index]; else index=-1; + + if (item){ + + PostGuiEvent(BBEVENT_GADGETSELECT,self,index,0,0,0,[item extra]); + + }else{ + + PostGuiEvent(BBEVENT_GADGETSELECT,self,-1,0,0,0,&bbNullObject); + + } + +} + +-(void)tableView:(NSTableView *)table willDisplayCell:(id)aCell forTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex{ + + NSString *text=[[items objectAtIndex:rowIndex] string]; + + if (textstyle){ + + NSAttributedString *atext=[[[NSAttributedString alloc] initWithString:text attributes:textstyle] autorelease]; + + [aCell setAttributedStringValue:atext]; + + }else{ + + [aCell setStringValue:text]; + + } + + [aCell setImage:[[items objectAtIndex:rowIndex] image]]; + +} + +-(void)updateWidthForString:(ImageString *) imgstring{ + + + + NSCell* dcell; + + float cellWidth; + + + + dcell=[column dataCell]; + + [dcell setStringValue:[imgstring string]]; + + [dcell setImage:[imgstring image]]; + + cellWidth=((NSSize)[dcell cellSize]).width; + + + + if([column minWidth] < cellWidth){ + + [column setMinWidth:cellWidth]; + + [column setWidth:cellWidth]; + + [table setNeedsDisplay:YES]; + + } + + + +} + +-(void)updateWidth{ + + int i,count; + + count=[items count]; + + [column setMinWidth:0]; + + for (i=0;i-1 && i<[self numberOfRows]){ + + node=[self itemAtRow:i]; + + PostGuiEvent(BBEVENT_GADGETMENU,[self dataSource],(int)node,0,0,0,0); //[self superview] + + } + + return nil; + +} + +@end + + + +// TreeView + + + +@implementation TreeView + +-(id)initWithFrame:(NSRect)rect{ + + [super initWithFrame:rect]; + + [self setBorderType:NSNoBorder]; + + [self setHasVerticalScroller:YES]; + + [self setHasHorizontalScroller:YES]; + + [self setAutohidesScrollers:YES]; + + rootNode=[[NodeItem alloc] initWithTitle:@"root"]; + + [rootNode setOwner:self]; + + NSSize contentSize=[self contentSize]; + + outline=[[OutlineView alloc] initWithFrame:NSMakeRect(0,0,contentSize.width,contentSize.height)]; + + [outline setHeaderView:nil]; + + [outline setAutoresizingMask:(NSViewWidthSizable|NSViewHeightSizable)]; + + [outline setDataSource:self]; + + [outline setDelegate:self]; + + column=[[NSTableColumn alloc] init]; + + [outline addTableColumn:column]; + + [outline setOutlineTableColumn:column]; + + cell=[[NSBrowserCell alloc] init]; + + [cell setLeaf:YES]; + + [cell setScrollable:YES]; + + [column setDataCell:cell]; + + [self setDocumentView:outline]; + + [outline sizeLastColumnToFit]; + + return self; + +} + +-(void)dealloc{ + + [outline autorelease]; + + [column autorelease]; + + [cell autorelease]; + + if (textstyle) { + + [textstyle release]; + + } + + [super dealloc]; + +} + +-(void)refresh{ + + [rootNode updateWidth]; + + [outline reloadData]; + +} + +-(int)outlineView:(NSOutlineView*)outlineView numberOfChildrenOfItem:(id)item{ + + if(!item) item=rootNode; + + return [[item kids] count]; + +} + +-(id)outlineView:(NSOutlineView*)outlineView child:(int)index ofItem:(id)item{ + + if(!item) item=rootNode; + + if (index>=[[item kids] count]) return 0; + + return [[item kids] objectAtIndex:index]; + +} + +-(BOOL)outlineView:(NSOutlineView*)outlineView isItemExpandable:(id)item{ + + if(!item) item=rootNode; + + return [item canExpand]; + +} + +-(id)outlineView:(NSOutlineView*)outlineView objectValueForTableColumn:(NSTableColumn*)tableColumn byItem:(id)item{ + + if (tableColumn==colin) return @""; + + if(!item) item=rootNode; + + return [item value]; + +} + +-(unsigned)count{ + + return [rootNode count]; + +} + +-(id)rootNode{ + + return rootNode; + +} + +-(id)selectedNode{ + + int index; + + index=[outline selectedRow]; + + if (index==-1) return nil; + + return [outline itemAtRow:index]; + +} + +-(void)selectNode:(id)node{ + + int index; + + [node show]; + + [outline setDelegate:nil]; + + index=[outline rowForItem:node]; + + [outline selectRowIndexes:[NSIndexSet indexSetWithIndex:index] byExtendingSelection:NO]; + + [outline setDelegate:self]; + + [outline scrollRowToVisible:index]; + +} + +-(void)expandNode:(id)node{ + + [outline setDelegate:nil]; + + [outline expandItem:node]; + + [outline tile]; + + [outline setDelegate:self]; + + [node queueWidthUpdate]; + +} + +-(void)collapseNode:(id)node{ + + [outline setDelegate:nil]; + + [outline collapseItem:node]; + + [outline tile]; + + [outline setDelegate:self]; + + [column setMinWidth:0]; + + [rootNode queueWidthUpdate]; + +} + +-(void)outlineViewItemDidExpand:(NSNotification *)notification{ + + id node; + + node=[[notification userInfo] objectForKey:@"NSObject"]; + + [node queueWidthUpdate]; + + PostGuiEvent(BBEVENT_GADGETOPEN,self,(int)node,0,0,0,0); + +} + +-(void)outlineViewItemDidCollapse:(NSNotification *)notification{ + + id node; + + node=[[notification userInfo] objectForKey:@"NSObject"]; + + [column setMinWidth:0]; + + [rootNode queueWidthUpdate]; + + PostGuiEvent(BBEVENT_GADGETCLOSE,self,(int)node,0,0,0,0); + +} + +-(void)outlineViewSelectionDidChange:(NSNotification *)notification{ + + id node; + + node=[self selectedNode]; + + PostGuiEvent(BBEVENT_GADGETSELECT,self,(int)node,0,0,0,0); + +} + +-(BOOL)outlineView:(NSOutlineView *)outlineView shouldEditTableColumn:(NSTableColumn *)tableColumn item:(id)item{ + + PostGuiEvent(BBEVENT_GADGETACTION,self,(int)item,0,0,0,0); + + return NO; + +} + +-(void)setColor:(NSColor*)color{ + + [outline setBackgroundColor:color]; + +} + +-(void)setTextColor:(NSColor*)color{ + + if (textstyle) {[textstyle release];textstyle=nil;} + + if (color){ + + textstyle=[NSDictionary dictionaryWithObjectsAndKeys:color,NSForegroundColorAttributeName,nil]; + + [textstyle retain]; + + } + +} + +- (void)setFont:(NSFont*)font{ + + if (font) { + + NSLayoutManager* layoutManager=[[[NSLayoutManager alloc] init] autorelease]; + + int i; + + NSArray *columnsArray=[outline tableColumns]; + + for (i= 0; i < [columnsArray count]; i++) + + [[[columnsArray objectAtIndex:i] dataCell] setFont:font]; + + [outline setRowHeight: [layoutManager defaultLineHeightForFont:font]+1]; + + [rootNode queueWidthUpdate]; + + } + +} + +- (void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(id)dcell forTableColumn:(NSTableColumn *)tableColumn item:(id)node{ + + if (textstyle){ + + NSAttributedString *atext=[[[NSAttributedString alloc] initWithString:[node value] attributes:textstyle] autorelease]; + + [dcell setAttributedStringValue:atext]; + + } + + else{ + + [dcell setStringValue:[node value]]; + + } + + [dcell setImage:[node icon]]; + +} + +-(void)setEnabled:(BOOL)e{ + + [outline setEnabled:e]; + +} + +-(BOOL)isEnabled{ + + return [outline isEnabled]; + +} + +@end + + + +// NodeItem + + + +@implementation NodeItem + +-(void)dealloc{} + +-(id)initWithTitle:(NSString*)text{ + + owner=nil; + + parent=nil; + + title=text; + + icon=nil; + + [title retain]; + + kids=[[NSMutableArray alloc] initWithCapacity:10]; + + [kids retain]; + + return self; + +} + +-(void)updateWidth{ + + int i; + + float cellWidth; + + float indentationWidth; + + + + NSCell* dcell; + + NSArray* columnsArray; + + + + if(owner==nil) return; + + + + NSOutlineView* outline=owner->outline; + + NSTableColumn* tableColumn=owner->column; + + + + if(tableColumn!=nil){ + + dcell=[tableColumn dataCell]; + + [dcell setStringValue:title]; + + [dcell setImage:icon]; + + cellWidth=((NSSize)[dcell cellSize]).width; + + indentationWidth=[outline levelForItem: self]; + + if(isnan(indentationWidth)) indentationWidth=0; else indentationWidth=([outline indentationPerLevel]*(indentationWidth+1)); + + if((owner->rootNode == self) || [outline isItemExpanded:self]) + + for (i= 0; i < [kids count]; i++) [[kids objectAtIndex:i] updateWidth]; + + if([tableColumn minWidth] < (cellWidth+indentationWidth)){ + + [tableColumn setMinWidth:(cellWidth+indentationWidth)]; + + [tableColumn setWidth:(cellWidth+indentationWidth)]; + + } + + } + +} + +-(void)queueWidthUpdate{ + + [NSObject cancelPreviousPerformRequestsWithTarget: self selector:@selector(updateWidth) object:nil]; + + [self performSelector:@selector(updateWidth) withObject:nil afterDelay:0.0]; + +} + +-(void)setOwner:(TreeView*)treeview{ + + owner=treeview; + +} + +-(id)getOwner{ + + return owner; + +} + +-(void)show{ + + if (parent){ + + [parent show]; + + [owner expandNode:parent]; + + } + +} + +-(void)attach:(NodeItem*)parent_ atIndex:(unsigned)index_{ + + parent=parent_; + + if(parent){ + + owner=parent->owner; + + [[parent kids] insertObject:self atIndex:index_]; + + [self release]; + + } + + if (owner) [owner refresh]; + +} + +-(void)remove{ + + if(parent) [[parent kids] removeObject:self]; + + if (owner) [owner refresh]; + +} + +-(BOOL)canExpand{ + + return [kids count]>0; + +} + +-(NSMutableArray*)kids{ + + return kids; + +} + +-(NSString *)value{return title;} + +-(NSImage *)icon{return icon;} + +-(void)setTitle:(NSString*)text{ + + [title release]; + + title=text; + + [title retain]; + + if (owner){ + + [owner->outline reloadItem:self]; + + [owner->rootNode queueWidthUpdate]; + + } + +} + +-(void)setIcon:(NSImage*)image{ + + if (icon) [icon release]; + + icon=image; + + if (icon) [icon retain]; + + if (owner){ + + [owner->outline reloadItem:self]; + + [(icon ? self : owner->rootNode) queueWidthUpdate]; + + } + +} + +-(unsigned)count{ + + return [kids count]; + +} + +@end + + + +// TextView + + + +@implementation TextView + +-(id)initWithFrame:(NSRect)rect{ + + + + scroll=[[NSScrollView alloc] initWithFrame:rect]; + + + +// [scroll setVerticalScroller:[[Scroller alloc] init]]; + +// [scroll setHorizontalScroller:[[Scroller alloc] init]]; + + + + [scroll setHasVerticalScroller:YES]; + + [scroll setHasHorizontalScroller:YES]; + + + + [scroll setDrawsBackground:NO]; + + [scroll setRulersVisible:NO]; + + [scroll setBorderType:NSNoBorder]; + + [scroll setAutohidesScrollers:YES]; + + + + NSSize contentSize=[scroll contentSize]; + + + + self=[super initWithFrame:NSMakeRect(0,0,contentSize.width,contentSize.height)]; + + [self setMinSize:NSMakeSize(contentSize.width,contentSize.height)]; + + [self setMaxSize:NSMakeSize(FLT_MAX,FLT_MAX)]; + + [self setVerticallyResizable:YES]; + + [self setHorizontallyResizable:YES]; + + [self setAutoresizingMask:(NSViewWidthSizable|NSViewHeightSizable)]; + + [[self textContainer] setContainerSize:NSMakeSize(FLT_MAX,FLT_MAX)]; + + [[self textContainer] setWidthTracksTextView:NO]; + + [self setDelegate:self]; + + [self setUsesRuler:NO]; + + + + [scroll setDocumentView:self]; + + + + style=[[NSParagraphStyle defaultParagraphStyle] mutableCopy]; + + [style setLineBreakMode:NSLineBreakByClipping]; + + + + styles=[NSMutableDictionary dictionaryWithObject:style forKey:NSParagraphStyleAttributeName]; + + [styles retain]; + + storage=[self textStorage]; + + [storage setDelegate:self]; + + + + lockedNest=0; + + + + [self setTabs: 4]; + + if ([self respondsToSelector: @selector(setDefaultParagraphStyle)]) + + [self setDefaultParagraphStyle: style]; + + + + if ([self respondsToSelector: @selector(setAutomaticLinkDetectionEnabled)]) + + [self setAutomaticLinkDetectionEnabled: NO]; + + if ([self respondsToSelector: @selector(setAutomaticQuoteSubstitutionEnabled)]) + + [self setAutomaticQuoteSubstitutionEnabled: NO]; + + if ([self respondsToSelector: @selector(setAutomaticSpellingCorrectionEnabled)]) + + [self setAutomaticSpellingCorrectionEnabled: NO]; + + if ([self respondsToSelector: @selector(setAutomaticTextReplacementEnabled)]) + + [self setAutomaticTextReplacementEnabled: NO]; + + if ([self respondsToSelector: @selector(setAutomaticDataDetectionEnabled)]) + + [self setAutomaticDataDetectionEnabled: NO]; + + + + return self; + +} + +-(void)free{ + + [scroll setDocumentView:nil]; + + [scroll release]; + + [style release]; + + [styles release]; + + [storage release]; + +} + +-(void)setHidden:(BOOL)flag{ + + [scroll setHidden:flag]; + +} + +-(id)storage{ + + return storage; + +} + +-(NSSize)contentSize{ + + return [scroll contentSize]; + +} + +-(id)getScroll{ + + return scroll; + +} + +-(void)setWordWrap:(BOOL)flag{ + + NSSize contentSize=[self contentSize]; + + if (flag){ + + [scroll setHasHorizontalScroller:NO]; + + [self setHorizontallyResizable:NO]; + + [self setAutoresizingMask:NSViewWidthSizable]; + + [[self textContainer] setContainerSize:NSMakeSize(contentSize.width,FLT_MAX)]; + + [[self textContainer] setWidthTracksTextView:YES]; + + [style setLineBreakMode:NSLineBreakByWordWrapping]; + + } + + else{ + + [scroll setHasHorizontalScroller:YES]; + + [self setHorizontallyResizable:YES]; + + [self setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)]; + + [[self textContainer] setContainerSize:NSMakeSize(FLT_MAX,FLT_MAX)]; + + [[self textContainer] setWidthTracksTextView:NO]; + + [style setLineBreakMode:NSLineBreakByClipping]; + + } + + [storage addAttribute:NSParagraphStyleAttributeName value:style range:NSMakeRange(0,[storage length])]; + +} + + + +-(void)setTabs:(int)tabs{ + + [style setTabStops:[NSArray array]]; //Clear any TabStops + + [style setDefaultTabInterval: tabs]; //Set recurring TabStops remembering to convert from twips->pixels + + [storage addAttribute:NSParagraphStyleAttributeName value:style range:NSMakeRange(0,[storage length])]; + +} + + + +-(void)setMargins:(int)leftmargin{ + + + + [self setTextContainerInset:NSMakeSize(leftmargin,0) ]; + +// [style setFirstLineHeadIndent: leftmargin*8]; + +// [style setHeadIndent: leftmargin*8]; + +// [storage addAttribute:NSParagraphStyleAttributeName value:style range:NSMakeRange(0,[storage length])]; + +} + + + +-(void)setText:(NSString*)text{ + + NSAttributedString *astring; + + astring=[[NSAttributedString alloc] initWithString:text attributes:styles]; + + if (lockedNest) [storage endEditing]; + + [storage setAttributedString:astring]; + + if (lockedNest) [storage beginEditing]; else [self setSelectedRange:NSMakeRange(0,0)]; + +} + +-(void)addText:(NSString*)text{ + + NSAttributedString *astring; + + astring=[[NSAttributedString alloc] initWithString:text attributes:styles]; + + if (lockedNest) [storage endEditing]; + + [storage appendAttributedString:astring]; + + if (lockedNest) [storage beginEditing]; + +} + +-(void)setScrollFrame:(NSRect)rect{ + + [scroll setFrame:rect]; + +} + +-(void)setTextColor:(NSColor*)color{ + + [styles setObject:color forKey:NSForegroundColorAttributeName]; + + [storage addAttribute:NSForegroundColorAttributeName value:color range:NSMakeRange(0,[storage length])]; + + [self setInsertionPointColor:color]; + +} + +-(void)setColor:(NSColor*)color{ + + if(color){ + + [self setBackgroundColor:color]; + + [self setDrawsBackground:true]; + + [scroll setBackgroundColor:color]; + + [scroll setDrawsBackground:true]; + + }else{ + + [self setDrawsBackground:false]; + + [scroll setDrawsBackground:false]; + + } + +} + +-(void)setFont:(NSFont*)font{ + + [styles setObject:font forKey:NSFontAttributeName]; + + [storage setFont:font]; + + [super setFont:font]; + +} + +-(NSMenu *)menuForEvent:(NSEvent *)event{ + + NSPoint p; + + int x,y; + + p=[event locationInWindow]; + + x=(int)p.x;y=(int)p.y; + + PostGuiEvent(BBEVENT_GADGETMENU,self,0,0,x,y,0); + + return nil; + +} + +-(void)updateDragTypeRegistration{ + +} + +-(NSArray *)acceptableDragTypes{ + + return nil; + +} + +-(void)textDidBeginEditing:(NSNotification*)n{ + +// printf("textDidBeginEditing:%p\n",_textEditor);fflush(stdout); + +} + +-(void)textDidChange:(NSNotification*)n{ + + PostGuiEvent(BBEVENT_GADGETACTION,self,0,0,0,0,0); + +} + +-(void)textDidEndEditing:(NSNotification*)n{ + +// printf("textDidEndEditing:%p\n",_textEditor);fflush(stdout); + + PostGuiEvent(BBEVENT_GADGETLOSTFOCUS,[n object],0,0,0,0,0); + +} + +-(void)textViewDidChangeSelection:(NSNotification *)aNotification{ + + PostGuiEvent(BBEVENT_GADGETSELECT,self,0,0,0,0,0); + +} + +-(void)textStorageDidProcessEditing:(NSNotification *)aNotification{ + + + +} + +-(void)textStorageWillProcessEditing:(NSNotification *)aNotification{ + + [storage removeAttribute:NSLinkAttributeName range:[storage editedRange]]; + +} + +@end + + + + + +// TabViewItem + + + +@class TabViewItem; + +@interface TabViewItem:NSTabViewItem{ + + NSImage *_image; + +} + +-(id)initWithIdentifier:(NSString *)text; + +-(void)setImage:(NSImage*)image; + +-(id)copyWithZone:(NSZone *)zone; + +-(NSImage*)image; + +-(NSSize)sizeOfLabel:(BOOL)shouldTruncateLabel; + +-(void)drawLabel:(BOOL)shouldTruncateLabel inRect:(NSRect)tabRect; + +@end + +@implementation TabViewItem + +-(id)initWithIdentifier:(NSString *)string{ + + self=[super initWithIdentifier:string]; + + _image=nil; + + return self; + +} + +-(void)setImage:(NSImage*)image{ + + _image=image; + + if (_image) [_image setScalesWhenResized:YES]; + +} + +-(id)copyWithZone:(NSZone *)zone{ + + TabViewItem *copy=[[[self class] allocWithZone:zone] initWithIdentifier:[self identifier]]; + + return copy; + +} + +-(NSImage*)image{ + + return _image; + +} + +-(NSSize)sizeOfLabel:(BOOL)shouldTruncateLabel{ + + NSSize size; + + NSSize imageDimensions; + + float ratio; + + size=[super sizeOfLabel:shouldTruncateLabel]; + + + + if (_image) { + + imageDimensions=[_image size]; + + if (imageDimensions.height > size.height){ + + ratio=size.height/imageDimensions.height; + + imageDimensions.width*=ratio;imageDimensions.height*=ratio; + + [_image setSize: imageDimensions]; + + } + + size.width += imageDimensions.height; + + } + + return size; + +} + +-(void)drawLabel:(BOOL)shouldTruncateLabel inRect:(NSRect)content{ + + NSSize imageDimensions; + + NSPoint point; + + if (_image){ + + imageDimensions=[_image size]; + + point=NSMakePoint(content.origin.x,content.origin.y+imageDimensions.height); + + [_image compositeToPoint:point operation:NSCompositeSourceOver]; + + content.origin.x+=imageDimensions.width;content.size.width-=imageDimensions.width; + + } + + [super drawLabel:shouldTruncateLabel inRect:content]; + +} + +@end + + + +// TabView + + + +@implementation TabView + +-(id)initWithFrame:(NSRect)rect{ + + rect.size.height+=8; + + self=[super initWithFrame:rect]; + + [super setControlSize:NSSmallControlSize]; + + [super setFont:[NSFont labelFontOfSize:[NSFont smallSystemFontSize]]]; + + client=[[FlippedView alloc] initWithFrame:[self contentRect]]; + + [client setAutoresizingMask:(NSViewWidthSizable|NSViewHeightSizable)]; + + [client retain]; + + user=1; + + [self setDelegate:self]; + + return self; + +} + +-(id)clientView{ + + return client; + +} + +-(void)selectTabViewItemAtIndex:(int)index{ + + user=0; + + [super selectTabViewItemAtIndex:index]; + + user=1; + +} + +-(void)setFrame:(NSRect)rect{ + + rect.size.height+=8; + + [super setFrame:rect]; + +} + +-(BOOL)tabView:(NSTabView *)tabView shouldSelectTabViewItem:(NSTabViewItem *)tabViewItem{ + + int index; + + [tabViewItem setView:client]; + + [client setFrame:[self contentRect]]; + + if (user){ + + index=[self indexOfTabViewItem:tabViewItem]; + + PostGuiEvent(BBEVENT_GADGETACTION,self,index,0,0,0,0); + + } + + return YES; + +} + +-(void)dealloc{ + + NSArray *items; + + int i,n; + + + + items=[self tabViewItems]; + + n=[items count]; + + for (i=0;istyle&WINDOW_STATUS){ + + rect.origin.x=rect.origin.y=0; + + rect.size.height-=STATUSBARHEIGHT; + + client=[[FlippedView alloc] initWithFrame:rect]; + + [client setAutoresizingMask:(NSViewWidthSizable|NSViewHeightSizable)]; + + [view addSubview:client]; + +// label for window status + + rect.origin.y=rect.size.height+3; + + rect.size.height=STATUSBARHEIGHT-4; + + rect.size.width-=[NSScroller scrollerWidth]; + + for (i=0;i<3;i++){ + + l=[[NSText alloc] initWithFrame:rect]; + + [l setDrawsBackground:NO]; + + [l setEditable:NO]; + + [l setSelectable:NO]; + + [l setAutoresizingMask:NSViewWidthSizable|NSViewMinYMargin]; + + switch (i){ + + case 0:[l setAlignment:NSLeftTextAlignment];break; + + case 1:[l setAlignment:NSCenterTextAlignment];break; + + case 2:[l setAlignment:NSRightTextAlignment];break; + + } + + if (view) [view addSubview:l]; + + label[i]=l; + + } + + + + rect.origin.y-=3; + + rect.size.height=2; + + rect.size.width+=[NSScroller scrollerWidth]; + + + + box=[[NSBox alloc] initWithFrame:rect]; + + [box setBoxType:NSBoxSeparator]; + + [box setTitlePosition:NSNoTitle]; + + [box setAutoresizingMask:NSViewWidthSizable|NSViewMinYMargin]; + + if (view) [view addSubview:box]; + + + +// set clientview to inner view + + view=client; + + } + + return self; + +} + +-(id)clientView{ + + return view; + +} + +-(void)setStatus:(NSString*)text align:(int)pos{ + + if (label[pos]) [label[pos] setString:text]; + +} + +-(void)sendEvent:(NSEvent*)event{ + + + + static int lastHotKey; + + int key; + + id source; + + + + // Handling of Generic Key/Mouse Events + + + + switch([event type]){ + + case NSMouseEntered: + + [self disableCursorRects]; + + case NSLeftMouseDown: + + case NSRightMouseDown: + + case NSOtherMouseDown: + + if([event type] != NSMouseEntered){ + + dragging=[[self contentView] hitTest:[event locationInWindow]]; + + [self makeFirstResponder:dragging]; + + } + + case NSMouseMoved: + + case NSMouseExited: + + case NSScrollWheel: + + { + + NSView *hitView=[[self contentView] hitTest:[event locationInWindow]]; + + if (hitView) EmitMouseEvent(event,hitView); + + if(![self isEnabled]) return; + + break; + + } + + case NSLeftMouseUp: + + case NSRightMouseUp: + + case NSOtherMouseUp: + + { + + //fire event for the dragged view + + if (dragging) { + + EmitMouseEvent(event,dragging); + + dragging=nil; + + } else { + + //fire the event for the recieving view (if it exists) + + NSView *hitView=[[self contentView] hitTest:[event locationInWindow]]; + + if (hitView) EmitMouseEvent(event,hitView); + + } + + + + if(![self isEnabled]) return; + + break; + + } + + case NSLeftMouseDragged: + + case NSRightMouseDragged: + + case NSOtherMouseDragged: + + { + + if(dragging == nil) dragging=[[self contentView] hitTest:[event locationInWindow]]; + + if(dragging) EmitMouseEvent(event,dragging); + + if(![self isEnabled]) return; + + break; + + } + + case NSKeyDown: + + case NSKeyUp: + + case NSFlagsChanged: + + { + + NSResponder *handle=(NSResponder*)NSActiveGadget(); + + if(handle && EmitKeyEvent(event,handle)) return; + + break; + + } + + } + + + + // End of Generic Key/Mouse Events + + + + // Gadget Filterkey Processing + + + + switch([event type]){ + + case NSKeyDown: + + if(key=bbSystemTranslateKey([event keyCode])){ + + int mods=bbSystemTranslateMods([event modifierFlags]); + + BBObject *event=maxgui_maxgui_HotKeyEvent(key,mods); + + if(event!=&bbNullObject){ + + lastHotKey=key; + + brl_event_EmitEvent(event); + + return; + + } + + } + + source=[self textFirstResponder]; + + if(source && !filterKeyDownEvent(event,source)) return; + + if(![self isEnabled]) return; + + break; + + case NSKeyUp: + + key=bbSystemTranslateKey([event keyCode]); + + if(lastHotKey && (key==lastHotKey)){ + + lastHotKey=0; + + return; + + } + + if(![self isEnabled]) return; + + break; + + } + + lastHotKey=0; + + + + // End of FilterKey Processing + + + + [super sendEvent:event]; + +} + +- (NSDragOperation)draggingEntered:(id )sender{ + +// printf("windowview got dragenter\n");fflush(stdout); + + return YES; + +} + +- (BOOL)performDragOperation:(id )sender{ + + NSPasteboard *pboard=[sender draggingPasteboard]; + + if ([[pboard types] containsObject:NSFilenamesPboardType]) { + + NSArray *files=[pboard propertyListForType:NSFilenamesPboardType]; + + int numberOfFiles=[files count]; + + // Perform operation using the list of files + + // printf("windowview got drag\n");fflush(stdout); + + int i; + + for (i=0;istyle; + + if (style&WINDOW_CLIENTCOORDS){ + + rect=[self contentRectForFrameRect:rect]; + + if (style&WINDOW_STATUS) { + + rect.size.height-=STATUSBARHEIGHT; + + rect.origin.y+=STATUSBARHEIGHT; + + } + + } + + vis=[[NSScreen deepestScreen] visibleFrame]; + + rect.origin.x-=vis.origin.x; + + rect.origin.y=vis.size.height-(rect.origin.y-vis.origin.y)-rect.size.height; + + return rect; + +} + +-(BOOL)canBecomeKeyWindow{ + + return ([self isEnabled]); + +} + +-(BOOL)canBecomeMainWindow{ + + return ([self isEnabled] && [self isVisible] && ([self parentWindow]==nil)); + +} + +-(BOOL)becomeFirstResponder{ + + return ([self isEnabled] && [self isVisible]); + +} + +-(void)setEnabled:(BOOL)e{ + + enabled=e; + + if (enabled) [self makeKeyWindow]; + +} + +-(BOOL)isEnabled{ + + return (enabled)?YES:NO; + +} + +-(void)dealloc{ + + int i; + + id sview; + + if (gadget->style&WINDOW_STATUS) { + + for (i=0; i < 3; i++) { + + if (label[i]) { + + [label[i] removeFromSuperview]; + + [label[i] release]; + + } + + } + + + + sview=[view superview]; + + [view removeFromSuperview]; + + [view release]; + + + + [sview removeFromSuperview]; + + [sview release]; + + } else { + + [view removeFromSuperview]; + + [view release]; + + } + + + + [super dealloc]; + +} + +@end + + + +// ToolView + + + +@implementation ToolView + +-(id)textFirstResponder{ + + id r=[self firstResponder]; + + //if ([r isKindOfClass:[PanelView class]]) return r; + + if ([r isKindOfClass:[NSTextView class]]){ + + id d=[r delegate]; + + if([d isKindOfClass:[NSTextField class]]) return d; + + } + + return r; + +} + +-(id)initWithContentRect:(NSRect)rect styleMask:(unsigned int)mask backing:(NSBackingStoreType)backing defer:(BOOL)flag withGadget:(nsgadget*)_gadget{ + + id client; + + int i; + + NSText *l; + + NSBox *box; + + dragging=nil; + + + + self=[super initWithContentRect:rect styleMask:mask backing:backing defer:flag]; + + gadget=_gadget; + + view=[[FlippedView alloc] init]; + + enabled=true; + + [self setContentView:view]; + + [self setAcceptsMouseMovedEvents:YES]; + + [self disableCursorRects]; //Fixes NSSetPointer not sticking. + + if (gadget->style&WINDOW_STATUS){ //status){ //mask&NSTexturedBackgroundWindowMask) + + rect.origin.x=rect.origin.y=0; + + rect.size.height-=STATUSBARHEIGHT; + + client=[[FlippedView alloc] initWithFrame:rect]; + + [client setAutoresizingMask:(NSViewWidthSizable|NSViewHeightSizable)]; + + [view addSubview:client]; + +// label for window status + + rect.origin.y=rect.size.height+3; + + rect.size.height=STATUSBARHEIGHT-4; + + rect.size.width-=[NSScroller scrollerWidth]; + + for (i=0;i<3;i++){ + + l=[[NSText alloc] initWithFrame:rect]; + + [l setDrawsBackground:NO]; + + [l setEditable:NO]; + + [l setSelectable:NO]; + + [l setAutoresizingMask:NSViewWidthSizable|NSViewMinYMargin]; + + switch (i){ + + case 0:[l setAlignment:NSLeftTextAlignment];break; + + case 1:[l setAlignment:NSCenterTextAlignment];break; + + case 2:[l setAlignment:NSRightTextAlignment];break; + + } + + if (view) [view addSubview:l]; + + label[i]=l; + + } + + + + rect.origin.y-=3; + + rect.size.height=2; + + rect.size.width+=[NSScroller scrollerWidth]; + + + + box=[[NSBox alloc] initWithFrame:rect]; + + [box setBoxType:NSBoxSeparator]; + + [box setTitlePosition:NSNoTitle]; + + [box setAutoresizingMask:NSViewWidthSizable|NSViewMinYMargin]; + + if (view) [view addSubview:box]; + + + +// set clientview to inner view + + view=client; + + } + + if ([self respondsToSelector: @selector(setShowsToolbarButton)]) [self setShowsToolbarButton: NO]; + + return self; + +} + +-(id)clientView{ + + return view; + +} + +-(void)setStatus:(NSString*)text align:(int)pos{ + + if (label[pos]) [label[pos] setString:text]; + +} + +-(void)sendEvent:(NSEvent*)event{ + + static int lastHotKey; + + int key; + + id source; + + + + // Handling of Generic Key/Mouse Events + + + + switch([event type]){ + + case NSMouseEntered: + + [self disableCursorRects]; + + case NSLeftMouseDown: + + case NSRightMouseDown: + + case NSOtherMouseDown: + + { + + if([event type] != NSMouseEntered){ + + dragging=[[self contentView] hitTest:[event locationInWindow]]; + + [self makeFirstResponder:dragging]; + + } + + } + + case NSMouseMoved: + + case NSMouseExited: + + case NSScrollWheel: + + { + + NSView *hitView=[[self contentView] hitTest:[event locationInWindow]]; + + if (hitView) EmitMouseEvent(event,hitView); + + if(![self isEnabled]) return; + + break; + + } + + case NSLeftMouseUp: + + case NSRightMouseUp: + + case NSOtherMouseUp: + + { + + //fire event for the dragged view + + if (dragging) { + + EmitMouseEvent(event,dragging); + + dragging=nil; + + } else { + + //fire the event for the recieving view (if it exists) + + NSView *hitView=[[self contentView] hitTest:[event locationInWindow]]; + + if (hitView) EmitMouseEvent(event,hitView); + + } + + + + if(![self isEnabled]) return; + + break; + + } + + case NSLeftMouseDragged: + + case NSRightMouseDragged: + + case NSOtherMouseDragged: + + { + + if(dragging == nil) dragging=[[self contentView] hitTest:[event locationInWindow]]; + + if(dragging) EmitMouseEvent(event,dragging); + + if(![self isEnabled]) return; + + break; + + } + + case NSKeyDown: + + case NSKeyUp: + + case NSFlagsChanged: + + { + + NSResponder *handle=(NSResponder*)NSActiveGadget(); + + if(handle && EmitKeyEvent(event,handle)) return; + + break; + + } + + } + + + + // End of Generic Key/Mouse Events + + + + // Gadget Filterkey Processing + + + + switch([event type]){ + + case NSKeyDown: + + if(key=bbSystemTranslateKey([event keyCode])){ + + int mods=bbSystemTranslateMods([event modifierFlags]); + + BBObject *event=maxgui_maxgui_HotKeyEvent(key,mods); + + if(event!=&bbNullObject){ + + lastHotKey=key; + + brl_event_EmitEvent(event); + + return; + + } + + } + + source=[self textFirstResponder]; + + if(source && !filterKeyDownEvent(event,source)) return; + + if(![self isEnabled]) return; + + break; + + case NSKeyUp: + + key=bbSystemTranslateKey([event keyCode]); + + if(lastHotKey && (key==lastHotKey)){ + + lastHotKey=0; + + return; + + } + + if(![self isEnabled]) return; + + break; + + } + + lastHotKey=0; + + + + // End of FilterKey Processing + + + + [super sendEvent:event]; + +} + +- (NSDragOperation)draggingEntered:(id )sender{ + +// printf("windowview got dragenter\n");fflush(stdout); + + return YES; + +} + +- (BOOL)performDragOperation:(id )sender{ + + NSPasteboard *pboard=[sender draggingPasteboard]; + + if ([[pboard types] containsObject:NSFilenamesPboardType]) { + + NSArray *files=[pboard propertyListForType:NSFilenamesPboardType]; + + int numberOfFiles=[files count]; + + // Perform operation using the list of files + + // printf("windowview got drag\n");fflush(stdout); + + int i; + + for (i=0;istyle; + + if (style&WINDOW_CLIENTCOORDS){ + + rect=[self contentRectForFrameRect:rect]; + + if (style&WINDOW_STATUS) { + + rect.size.height-=STATUSBARHEIGHT; + + rect.origin.y+=STATUSBARHEIGHT; + + } + + } + + vis=[[NSScreen deepestScreen] visibleFrame]; + + rect.origin.x=rect.origin.x-vis.origin.x; + + rect.origin.y=vis.size.height-(rect.origin.y-vis.origin.y)-rect.size.height; + + return rect; + +} + +-(BOOL)canBecomeKeyWindow{ + + return ([self isEnabled]); + +} + +-(BOOL)canBecomeMainWindow{ + + return ([self isEnabled] && [self isVisible] && ([self parentWindow]==nil)); + +} + +-(BOOL)becomeFirstResponder{ + + return ([self isEnabled] && [self isVisible]); + +} + +-(void)setEnabled:(BOOL)e{ + + enabled=e; + + if (enabled) [self makeKeyWindow]; + +} + +-(BOOL)isEnabled{ + + return (enabled)?YES:NO; + +} + +-(void)dealloc{ + + int i; + + id sview; + + if (gadget->style&WINDOW_STATUS) { + + for (i=0; i < 3; i++) { + + if (label[i]) { + + [label[i] removeFromSuperview]; + + [label[i] release]; + + } + + } + + + + sview=[view superview]; + + [view removeFromSuperview]; + + [view release]; + + + + [sview removeFromSuperview]; + + [sview release]; + + } else { + + [view removeFromSuperview]; + + [view release]; + + } + + + + [super dealloc]; + +} + +@end + + + +// global app stuff + + + +void NSBegin(){ + + GlobalApp=[[CocoaApp alloc] init]; + + HaltMouseEvents=0; + +} + + + +void NSEnd(){ + + [GlobalApp release]; + +} + + + +int NSActiveGadget(){ + + NSWindow *window; + + NSResponder *responder; + + window=[NSApp keyWindow]; + + if (!window) return 0; + + responder=[window firstResponder]; + + if (!responder) return (int)window; + + if ([responder isKindOfClass:[NSTextView class]] && + + [window fieldEditor:NO forObject:nil] != nil) { + + NSTextView *view=(NSTextView*)responder; + + return (int)[view delegate]; + + } + + return (int)responder; + +} + + + +void NSInitGadget(nsgadget *gadget){ + + NSRect rect; + + NSRect vis; + + NSString *text; + + NSView *view; + + NSWindow *window; + + NSButton *button; + + NSTextField *textfield; + + TextView *textarea; + + NSControl *combobox; + + Toolbar *toolbar; + + TabView *tabber; + + TreeView *treeview; + + HTMLView *htmlview; + + PanelView *panel; + + PanelViewContent *pnlcontent; + + CanvasView *canvas; + + ListView *listbox; + + NSText *label; + + NSBox *box; + + NSSlider *slider; + + NSScroller *scroller; + + NSStepper *stepper; + + NSProgressIndicator *progbar; + + NSMenu *menu; + + NSMenuItem *menuitem; + + NodeItem *node,*parent; + + nsgadget *group; + + int style; + + int flags; + + NSImage *image; + + + + rect=NSMakeRect(gadget->x,gadget->y,gadget->w,gadget->h); + + text=NSStringFromBBString(gadget->textarg); + + style=gadget->style;flags=0; + + group=gadget->group; + + if (group==(nsgadget*)&bbNullObject) group=0; + + if (group) view=gadget->group->view; + + + + switch (gadget->internalclass){ + + case GADGET_DESKTOP: + + rect=[[NSScreen deepestScreen] frame]; + + gadget->x=rect.origin.x; + + gadget->y=rect.origin.y; + + gadget->w=rect.size.width; + + gadget->h=rect.size.height; + + break; + + case GADGET_WINDOW: + + vis=[[NSScreen deepestScreen] visibleFrame]; + + rect.origin.x+=vis.origin.x; + + rect.origin.y=vis.origin.y+vis.size.height-rect.origin.y-rect.size.height; + + if (style&WINDOW_TITLEBAR) flags|=NSTitledWindowMask|NSClosableWindowMask; + + if (style&WINDOW_RESIZABLE){ + + flags|=NSResizableWindowMask; + + if (!(group && (group->internalclass==GADGET_WINDOW))) flags |=NSMiniaturizableWindowMask; + + } + + if (style&WINDOW_TOOL) flags|=NSUtilityWindowMask; + + [NSApp activateIgnoringOtherApps:YES]; + + if (!(style&WINDOW_CLIENTCOORDS)){ + + rect=[NSWindow contentRectForFrameRect:rect styleMask:flags]; + + }else{ + + if (style&WINDOW_STATUS) { + + rect.origin.y-=STATUSBARHEIGHT; + + rect.size.height+=STATUSBARHEIGHT; + + } + + } + + if (!(style&WINDOW_TOOL)) { + + window=[[WindowView alloc] initWithContentRect:rect styleMask:flags backing:NSBackingStoreBuffered defer:YES withGadget:gadget]; + + } else { + + window=[[ToolView alloc] initWithContentRect:rect styleMask:flags backing:NSBackingStoreBuffered defer:YES withGadget:gadget]; + + } + + [window setOpaque:NO]; + + [window setAlphaValue:.999f]; + + + + if (style&WINDOW_HIDDEN) [window orderOut:window]; else [window makeKeyAndOrderFront:NSApp]; + + + + if (group && (group->internalclass==GADGET_WINDOW)){ + + NSWindow *parent; + + parent=(NSWindow*)group->handle; + + if(!(style&WINDOW_HIDDEN)) [parent addChildWindow:window ordered:NSWindowAbove]; + + [window setParentWindow:parent]; + + } + + + + if (style&WINDOW_ACCEPTFILES) + + [window registerForDraggedTypes:[NSArray arrayWithObject:NSFilenamesPboardType]]; + + + + [window setTitle:text]; + + [window setDelegate:GlobalApp]; + + gadget->handle=window; + + gadget->view=[window clientView]; + + break; + + + + case GADGET_BUTTON: + + button=[[NSButton alloc] initWithFrame:rect]; + + [button setTitle:text]; + + + + [button setBezelStyle:NSRoundedBezelStyle]; + + + + switch (style&7){ + + case 0: + + // Push Button Size Hack + + if (gadget->h > 30) { + + [button setBezelStyle:NSRegularSquareBezelStyle]; + + } else { + + if (gadget->h < 24) [button setBezelStyle:NSShadowlessSquareBezelStyle]; + + else [button setBezelStyle:NSRoundedBezelStyle]; + + } + + break; + + case BUTTON_CHECKBOX: + + if (style&BUTTON_PUSH){ + + [button setBezelStyle:NSShadowlessSquareBezelStyle]; + + [button setButtonType:NSPushOnPushOffButton]; + + } else { + + [button setButtonType:NSSwitchButton]; + + } + + break; + + case BUTTON_RADIO: + + if (style&BUTTON_PUSH){ + + [button setBezelStyle:NSShadowlessSquareBezelStyle]; + + [button setButtonType:NSPushOnPushOffButton]; + + } else { + + [button setButtonType:NSRadioButton]; + + } + + break; + + case BUTTON_OK: + + [button setKeyEquivalent:@"\r"]; + + break; + + case BUTTON_CANCEL: + + [button setKeyEquivalent:@"\x1b"]; + + break; + + } + + [button setTarget:GlobalApp]; + + [button setAction:@selector(buttonPush:)]; + + if (view) [view addSubview:button]; + + gadget->handle=button; + + gadget->view=button; + + break; + + case GADGET_PANEL: + + panel=[[PanelView alloc] initWithFrame:rect]; + + [panel setContentViewMargins:NSMakeSize(0.0,0.0)]; + + pnlcontent=[[PanelViewContent alloc] initWithFrame:[[panel contentView] frame]]; + + [pnlcontent setAutoresizesSubviews:NO]; + + [panel setContentView:pnlcontent]; + + [panel setGadget:gadget]; + + [panel setStyle:style]; + + [panel setEnabled:true]; + + [panel setTitle:text]; + + [pnlcontent setAlpha:1.0]; + + if (view) [view addSubview:panel]; + + gadget->view=pnlcontent; + + gadget->handle=panel; + + break; + + case GADGET_CANVAS: + + canvas=[[CanvasView alloc] initWithFrame:rect]; + + [canvas setAutoresizesSubviews:NO]; + + [canvas setGadget:gadget]; + + if (view) [view addSubview:canvas]; + + [canvas setStyle:style|PANEL_ACTIVE]; + + [canvas setEnabled:true]; + + gadget->view=[canvas contentView]; + + gadget->handle=canvas; + + break; + + case GADGET_TEXTFIELD: + + if (style==TEXTFIELD_PASSWORD){ + + textfield=[[NSSecureTextField alloc] initWithFrame:rect]; + + }else{ + + textfield=[[NSTextField alloc] initWithFrame:rect]; + + } + + [textfield setDelegate:GlobalApp]; + + [textfield setEditable:YES]; + + [[textfield cell] setWraps:NO]; + + [[textfield cell] setScrollable:YES]; + + if (view) [view addSubview:textfield]; + + gadget->handle=textfield; + + gadget->view=textfield; + + break; + + case GADGET_TEXTAREA://http://developer.apple.com/documentation/Cocoa/Conceptual/TextUILayer/Tasks/TextInScrollView.html + + textarea=[[TextView alloc] initWithFrame:rect]; + + if (style&TEXTAREA_READONLY) [textarea setEditable:NO]; + + if (style&TEXTAREA_WORDWRAP) [textarea setWordWrap:YES]; + + if (view) [view addSubview:[textarea getScroll]]; + + gadget->handle=textarea; + + gadget->view=[textarea getScroll];// simon was here textarea; + + break; + + case GADGET_COMBOBOX: + + if (rect.size.height > 26) rect.size.height=26; + + combobox=[[NSComboBox alloc] initWithFrame:rect]; + + [combobox setUsesDataSource:NO]; + + [combobox setCompletes:YES]; + + [combobox setDelegate:GlobalApp]; + + [combobox setEditable:(style&COMBOBOX_EDITABLE)?YES:NO]; + + [combobox setSelectable:YES]; + + if (view) [view addSubview:combobox]; + + gadget->handle=combobox; + + gadget->view=combobox; + + break; + + case GADGET_LISTBOX: + + listbox=[[ListView alloc] initWithFrame:rect]; + + if (view) [view addSubview:listbox]; + + gadget->handle=listbox; + + gadget->view=listbox; + + break; + + case GADGET_TOOLBAR: + + toolbar=[[Toolbar alloc] initWithIdentifier:text]; + + [toolbar setSizeMode:NSToolbarSizeModeSmall]; + + [toolbar setDisplayMode:NSToolbarDisplayModeIconOnly]; + + [toolbar setDelegate:GlobalApp]; + + window=(WindowView*)group->handle; + + [window setToolbar:toolbar]; + + gadget->handle=toolbar; + + gadget->view=[window clientView]; + + break; + + case GADGET_TABBER: + + tabber=[[TabView alloc] initWithFrame:rect]; + + [tabber setAutoresizesSubviews:NO]; + + if (view) [view addSubview:tabber]; //[tabber hostView]]; + + gadget->handle=tabber; + + gadget->view=[tabber clientView]; + + break; + + case GADGET_TREEVIEW: + + treeview=[[TreeView alloc] initWithFrame:rect]; //NSOutlineView + + if (view) [view addSubview:treeview]; + + gadget->handle=treeview; + + gadget->view=treeview; + + break; + + case GADGET_HTMLVIEW: + + htmlview=[[HTMLView alloc] initWithFrame:rect]; + + if (view) [view addSubview:htmlview]; + + [htmlview setStyle: style]; + + gadget->handle=htmlview; + + gadget->view=htmlview; + + break; + + case GADGET_LABEL: /* BaH */ + + switch (style&3) { + + case LABEL_SEPARATOR: + + + + box=[[NSBox alloc] initWithFrame:rect]; + + + + [box setTitle:text]; + + [box setBoxType:NSBoxSeparator]; + + [box setTitlePosition:NSNoTitle]; + + + + [box setContentView:[[FlippedView alloc] init]]; + + + + if (view) [view addSubview:box]; + + gadget->handle=box; + + gadget->view=[box contentView]; + + + + break; + + + + default: + + + + textfield=[[NSTextField alloc] initWithFrame:rect]; + + + + [textfield setEditable:NO]; + + [textfield setDrawsBackground:NO]; + + + + if ((style&3)==LABEL_SUNKENFRAME) { + + [textfield setBezeled:YES]; + + [textfield setBezelStyle:NSTextFieldSquareBezel]; + + } else { + + [textfield setBezeled:NO]; + + if ((style&3)==LABEL_FRAME) + + [textfield setBordered:YES]; + + else + + [textfield setBordered:NO]; + + } + + + + [[textfield cell] setWraps:YES]; + + [[textfield cell] setScrollable:NO]; + + [textfield setStringValue:text]; + + + + switch (style&24){ + + case LABEL_LEFT:[textfield setAlignment:NSLeftTextAlignment];break; + + case LABEL_RIGHT:[textfield setAlignment:NSRightTextAlignment];break; + + case LABEL_CENTER:[textfield setAlignment:NSCenterTextAlignment];break; + + } + + + + if (view) [view addSubview: textfield]; + + gadget->handle=textfield; + + gadget->view=textfield; + + + + break; + + } + + break; + + case GADGET_SLIDER: + + switch (style&12){ + + case SLIDER_SCROLLBAR: + + if (rect.size.width>rect.size.height) { + + rect.size.height=[NSScroller scrollerWidth]; + + } + + else{ + + rect.size.width=[NSScroller scrollerWidth]; + + } + + scroller=[[NSScroller alloc] initWithFrame:rect]; + + [scroller setEnabled:YES]; + + [scroller setArrowsPosition:NSScrollerArrowsDefaultSetting]; + + [scroller setAction:@selector(scrollerSelect:)]; + + if (view) [view addSubview:scroller]; + + gadget->handle=scroller; + + gadget->view=scroller; + + break; + + case SLIDER_TRACKBAR: + + slider=[[NSSlider alloc] initWithFrame:rect]; + + [slider setEnabled:YES]; + + [slider setAction:@selector(sliderSelect:)]; + + if (view) [view addSubview:slider]; + + gadget->handle=slider; + + gadget->view=slider; + + break; + + case SLIDER_STEPPER: + + stepper=[[NSStepper alloc] initWithFrame:rect]; + + [stepper setEnabled:YES]; + + [stepper setAction:@selector(sliderSelect:)]; + + [stepper setValueWraps:NO]; + + if (view) [view addSubview:stepper]; + + gadget->handle=stepper; + + gadget->view=stepper; + + break; + + } + + break; + + case GADGET_PROGBAR: + + progbar=[[NSProgressIndicator alloc] initWithFrame:rect]; + + [progbar setStyle:NSProgressIndicatorBarStyle]; + + [progbar setIndeterminate:NO]; + + [progbar setMaxValue:1.0]; + + if (view) [view addSubview:progbar]; + + gadget->handle=progbar; + + gadget->view=progbar; + + break; + + case GADGET_MENUITEM: + + // Allows a popup-menu to be created with no text without crashing. + + if ([text length] || (group->internalclass == GADGET_DESKTOP)) { + + menuitem=[[NSMenuItem alloc] initWithTitle:text action:@selector(menuSelect:) keyEquivalent:@""]; + + [menuitem setTag:style]; + + [GlobalApp addMenuItem:menuitem]; + + } + + else{ + + menuitem=(NSMenuItem*)[NSMenuItem separatorItem]; + + } + + if (group){ + + switch (group->internalclass){ + + case GADGET_WINDOW: + + menu=[[NSMenu alloc] initWithTitle:text]; + + [menu setAutoenablesItems:NO]; + + [menu setSubmenu:menu forItem:menuitem]; + + [menu release]; + + menu=[NSApp mainMenu]; + + [menu addItem:menuitem]; + + if ([text length]){ + + [menuitem release]; + + } + + break; + + case GADGET_MENUITEM: + + menu=(NSMenu*)[group->handle submenu]; + + if (!menu){ + + menu=(NSMenu*)[[NSMenu alloc] initWithTitle:text]; + + [menu setAutoenablesItems:NO]; + + [group->handle setSubmenu:menu]; + + [menu addItem:menuitem]; + + [menu release]; + + } else { + + [menu addItem:menuitem]; + + } + + if ([text length]){ + + [menuitem release]; + + } + + break; + + } + + } + + gadget->handle=menuitem; + + break; + + case GADGET_NODE: + + if (!group) break; + + parent=0; + + switch (group->internalclass){ + + case GADGET_TREEVIEW: + + parent=[((TreeView*)group->handle) rootNode]; + + break; + + case GADGET_NODE: + + parent=(NodeItem*)group->handle; + + break; + + } + + if (!parent) break; + + node=[[NodeItem alloc] initWithTitle:text]; + + int index=style; + + if (index==-1) index=[parent count]; + + if (index>[parent count]) index=[parent count]; + + [node attach:parent atIndex:index]; + + gadget->handle=node; + + break; + + } + +} + + + +@class color_delegate; + +@interface color_delegate:NSObject{} + +@end + +@implementation color_delegate + +- (void)windowWillClose:(NSNotification *)aNotification{[NSApp stopModal];} + +@end + + + +int NSColorRequester(int r,int g,int b){ + + NSColorPanel *panel; + + NSColor *color; + + color_delegate *dele; + + dele=[[color_delegate alloc] init]; + + color=[NSColor colorWithCalibratedRed:r/255.0L green:g/255.0L blue:b/255.0L alpha:1.0]; + + panel=[NSColorPanel sharedColorPanel]; + + [panel setColor:color]; + + [panel setDelegate:dele]; + + [NSApp runModalForWindow:panel]; + + color=[panel color]; + + if (color){ + + color=[color colorUsingColorSpaceName:NSCalibratedRGBColorSpace]; + + r=(int)((255*[color redComponent])+0.5); + + g=(int)((255*[color greenComponent])+0.5); + + b=(int)((255*[color blueComponent])+0.5); + + } + + return 0xff000000|(r<<16)|(g<<8)|b; + +} + + + +@class font_delegate; + +@interface font_delegate:NSObject{ + + NSFont *_font; + +} + +-(id)initWithFont:(NSFont*)font; + +-(void)changeFont:(id)sender; + +-(id)font; + +-(void)windowWillClose:(NSNotification *)aNotification; + +-(unsigned int)validModesForFontPanel:(NSFontPanel *)fontPanel; + +@end + +@implementation font_delegate + +-(id)initWithFont:(NSFont*)font{ + + _font=font; + + return self; + +} + +-(id)font{ + + return _font; + +} + +-(void)changeFont:(id)sender{ + + _font=[sender convertFont:_font]; + + return; + +} + +- (void)windowWillClose:(NSNotification *)aNotification{ + + [NSApp stopModal]; + +} + +-(unsigned int)validModesForFontPanel:(NSFontPanel *)fontPanel{ + + return NSFontPanelFaceModeMask|NSFontPanelSizeModeMask|NSFontPanelCollectionModeMask;//|NSFontPanelUnderlineEffectModeMask; + +} + +@end + + + +int NSGetSysColor(int colorindex,int* red,int* green,int* blue){ + + + + float r,g,b; + + NSColor* c; + + NSWindow* w; + + + + switch(colorindex){ + + case GUICOLOR_WINDOWBG: + + w=[[NSWindow alloc] initWithContentRect:NSZeroRect styleMask:NSTitledWindowMask backing:NSBackingStoreBuffered defer:YES]; + + c=[w backgroundColor]; + + [w release]; + + break; + + case GUICOLOR_GADGETBG: + + c=[NSColor controlBackgroundColor]; + + break; + + case GUICOLOR_GADGETFG: + + c=[NSColor controlTextColor]; + + break; + + case GUICOLOR_SELECTIONBG: + + c=[NSColor selectedTextBackgroundColor]; + + break; + + default: + + return 0; + + break; + + } + + + + [[c colorUsingColorSpaceName:NSCalibratedRGBColorSpace] getRed:&r green:&g blue:&b alpha:NULL]; + + + + *red=(int)(255 * r); + + *green=(int)(255 * g); + + *blue=(int)(255 * b); + + + + return 1; + +} + + + +NSFont *NSRequestFont(NSFont *font){ + + NSFontPanel *panel; + + font_delegate *dele; + + if (!font) font=[NSFont userFontOfSize:0]; + + dele=[[font_delegate alloc] initWithFont:font]; + + panel=[NSFontPanel sharedFontPanel]; + + if (font) [panel setPanelFont:font isMultiple:NO]; + + [panel setEnabled:YES]; + + [panel setDelegate:dele]; + + [NSApp runModalForWindow:panel]; + + return [dele font]; + +} + + + +NSFont *NSLoadFont(BBString *name,double size,int flags){ + + NSString *text; + + NSFont *font; + + NSFontManager *manager; + + + + text=NSStringFromBBString(name); + + font=[NSFont fontWithName:text size:size]; + + if (!font) font=[NSFont systemFontOfSize:size]; + + if (flags){ + + manager=[NSFontManager sharedFontManager]; + + if (flags&FONT_BOLD) font=[manager convertFont:font toHaveTrait:NSBoldFontMask]; + + if (flags&FONT_ITALIC) font=[manager convertFont:font toHaveTrait:NSItalicFontMask]; + + } + + [font retain]; + + return font; + +} + + + +NSFont *NSGetDefaultFont(){ + + return [NSFont systemFontOfSize:[NSFont systemFontSize]]; + +} + + + +BBString *NSFontName(NSFont *font){ + + return bbStringFromNSString([font displayName]); + +} + + + +int NSFontStyle(NSFont *font){ + + int intBBStyleFlags; + + int intCocoaFontTraits; + + NSFontManager *manager; + + + + manager=[NSFontManager sharedFontManager]; + + intCocoaFontTraits=[manager traitsOfFont: font]; + + + + intBBStyleFlags=0; + + if (intCocoaFontTraits & NSBoldFontMask) intBBStyleFlags|=FONT_BOLD; + + if (intCocoaFontTraits & NSItalicFontMask) intBBStyleFlags|=FONT_ITALIC; + + + + return intBBStyleFlags; + +} + + + +double NSFontSize(NSFont *font){ + + return (double)[font pointSize]; + +} + + + +void* NSSuperview(NSView* handle){ + + if(handle) return [handle superview]; + + return 0; + +} + + + +// generic gadget commands + + + +void NSFreeGadget(nsgadget *gadget){ + + nsgadget *group; + + NSWindow *parent; + + TextView *textview; + + FlippedView * flipped; + + if (gadget->textcolor){ + + [gadget->textcolor release]; + + gadget->textcolor=0; + + } + + if (gadget->handle){ + + switch (gadget->internalclass){ + + case GADGET_WINDOW: + + if ([gadget->handle parentWindow]!=nil){ + + [[gadget->handle parentWindow] removeChildWindow:(NSWindow*)gadget->handle]; + + } + + [gadget->handle close]; + + break; + + case GADGET_NODE: + + [gadget->handle remove]; + + [gadget->handle autorelease]; + + break; + + case GADGET_MENUITEM: + + [GlobalApp removeMenuItem:gadget->handle]; + + [[gadget->handle menu] removeItem:gadget->handle]; + + break; + + case GADGET_TEXTAREA: + + textview=(TextView*)gadget->handle; + + [gadget->view removeFromSuperview]; + + [textview free]; + + [textview autorelease]; + + break; + + case GADGET_LABEL: + + switch (gadget->style&3) { + + case LABEL_SEPARATOR: + + flipped=(FlippedView*)gadget->view; + + [flipped removeFromSuperview]; + + [gadget->handle removeFromSuperview]; + + [flipped release]; + + break; + + default: + + [gadget->view removeFromSuperview]; + + break; + + } + + [gadget->handle autorelease]; + + break; + + case GADGET_TABBER: + + flipped=(FlippedView*)gadget->view; + + [flipped removeFromSuperview]; + + [gadget->handle removeFromSuperview]; + + [flipped release]; + + //Cocoa throws an exception if items exist when handle is autoreleased. + + NSClearItems(gadget); + + [gadget->handle autorelease]; + + break; + + case GADGET_PANEL: + + [gadget->handle setColor:nil]; + + [gadget->handle removeFromSuperview]; + + [gadget->handle autorelease]; + + break; + + default: + + [[gadget->view superview] setNeedsDisplayInRect:[gadget->view frame]]; + + [gadget->view removeFromSuperview]; + + [gadget->handle autorelease]; + + break; + + } + + } + + gadget->handle=0; + +} + + + +void NSEnable(nsgadget *gadget,int state){ + + switch (gadget->internalclass){ + + case GADGET_WINDOW: + + case GADGET_SLIDER: + + case GADGET_TEXTFIELD: + + case GADGET_MENUITEM: + + case GADGET_BUTTON: + + case GADGET_LISTBOX: + + case GADGET_COMBOBOX: + + case GADGET_TREEVIEW: + + case GADGET_PANEL: + + case GADGET_CANVAS: + + [gadget->handle setEnabled:state]; + + break; + + case GADGET_TEXTAREA: + + [gadget->handle setSelectable:state]; + + if (!(gadget->style&TEXTAREA_READONLY)) [gadget->handle setEditable:state]; + + break; + + } + +} + + + +void NSShow(nsgadget *gadget,int state){ + + switch (gadget->internalclass){ + + case GADGET_WINDOW: + + if (state==[gadget->handle isVisible]) return; + + + + if (state) { + + if( + + (gadget->group!=&bbNullObject) && + + (gadget->group->internalclass==GADGET_WINDOW) && + + ([gadget->handle parentWindow]==nil) + + ) + + { + + [gadget->group->handle addChildWindow: gadget->handle ordered:NSWindowAbove]; + + } + + [gadget->handle makeKeyAndOrderFront:NSApp]; + + + + NSWindow *window=(NSWindow*)gadget->handle; + + + + [window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary]; + + + + } else { + + if([gadget->handle parentWindow]!=nil) [[gadget->handle parentWindow] removeChildWindow:(NSWindow*)gadget->handle]; + + [gadget->handle orderOut:NSApp]; + + } + + + + break; + + case GADGET_TOOLBAR: + + [gadget->handle setVisible:state]; + + break; + + default: + + [gadget->handle setHidden:!state]; + + } + +} + + + +void NSCheck(nsgadget *gadget,int state){ + + NSButton *button; + + switch (gadget->internalclass){ + + case GADGET_MENUITEM: + + [gadget->handle setState:state]; + + break; + + case GADGET_BUTTON: + + button=(NSButton *)gadget->handle; + + if(state==NSMixedState) [button setAllowsMixedState:YES]; else [button setAllowsMixedState:NO]; + + [button setState:state]; + + break; + + } + +} + + + +void NSPopupMenu(nsgadget *gadget,nsgadget *menugadget){ + + NSView *view; + + NSWindow *window; + + NSMenuItem *menuitem; + + NSEvent *event; + + NSPoint loc; + + + + window=(NSWindow*)gadget->handle; + + view=gadget->view; + + menuitem=(NSMenuItem*)menugadget->handle; + + event=[NSEvent + + mouseEventWithType:NSRightMouseUp + + location:[window convertScreenToBase:[NSEvent mouseLocation]] + + modifierFlags:nil + + timestamp:0 + + windowNumber:[window windowNumber] + + context:nil + + eventNumber:nil + + clickCount:1 + + pressure:0]; + + [NSMenu popUpContextMenu:[menuitem submenu] withEvent:event forView:view]; + +// [event release]; + +} + + + +int NSState(nsgadget *gadget){ + + NSWindow *window; + + TextView *textview; + + NSButton *button; + + NSView *view; + + Toolbar *toolbar; + + HTMLView *browser; + + NSMenuItem *menuItem; + + int state; + + + + state=0; + + + + switch (gadget->internalclass){ + + case GADGET_TEXTAREA: + + textview=(TextView*)gadget->handle; + + if ([textview isHidden]) state|=STATE_HIDDEN; + + if ((!(gadget->style&TEXTAREA_READONLY)) && (![textview isEditable])) state|=STATE_DISABLED; + + break; + + case GADGET_HTMLVIEW: + + browser=(HTMLView*)gadget->handle; + + return [browser loaded]; + + case GADGET_WINDOW: + + window=(NSWindow*)gadget->handle; + + if ([window isMiniaturized]) state|=STATE_MINIMIZED; + + if ([window isZoomed]) state|=STATE_MAXIMIZED; + + if (![window isVisible]) state|=STATE_HIDDEN; + + break; + + case GADGET_MENUITEM: + + menuItem=(NSMenuItem*)gadget->handle; + + if ([menuItem state]==NSOnState) state|=STATE_SELECTED; + + if (![menuItem isEnabled]) state|=STATE_DISABLED; + + break; + + case GADGET_BUTTON: + + button=(NSButton *)gadget->handle; + + switch (gadget->style&7){ + + case BUTTON_RADIO: case BUTTON_CHECKBOX: + + if ([button state]==NSOnState) state|=STATE_SELECTED; + + if ([button state]==NSMixedState) state|=STATE_INDETERMINATE; + + } + + if ([button isHidden]) state|=STATE_HIDDEN; + + if (![button isEnabled]) state|=STATE_DISABLED; + + break; + + case GADGET_TOOLBAR: + + toolbar=(Toolbar*)gadget->handle; + + if ([toolbar isVisible]==NO) state|=STATE_HIDDEN; + + break; + + case GADGET_PROGBAR: + + view=(NSView*)gadget->handle; + + if ([view isHidden]) state|=STATE_HIDDEN; + + break; + + default: + + view=(NSView*)gadget->handle; + + if ([view isHidden]) state|=STATE_HIDDEN; + + if (![view isEnabled]) state|=STATE_DISABLED; + + break; + + } + + return state; + +} + + + +void NSSetMinimumSize(nsgadget *gadget,int width,int height){ + + NSWindow *window; + + NSRect rect; + + int style; + + window=(NSWindow*)gadget->handle; + + rect.origin.x=0; + + rect.origin.y=0; + + rect.size.width=width; + + rect.size.height=height; + + style=gadget->style; + + if (!(style&WINDOW_CLIENTCOORDS)){ + + rect=[window contentRectForFrameRect:rect]; + + rect.size.width-=rect.origin.x; + + rect.size.height-=rect.origin.y; + + }else{ + + if (style&WINDOW_STATUS) rect.size.height+=STATUSBARHEIGHT; + + } + + [window setContentMinSize:rect.size]; + +} + + + +void NSSetMaximumSize(nsgadget *gadget,int width,int height){ + + NSWindow *window; + + NSRect rect; + + int style; + + window=(NSWindow*)gadget->handle; + + rect.origin.x=0; + + rect.origin.y=0; + + rect.size.width=width; + + rect.size.height=height; + + style=gadget->style; + + if (!(style&WINDOW_CLIENTCOORDS)){ + + rect=[window contentRectForFrameRect:rect]; + + rect.size.width-=rect.origin.x; + + rect.size.height-=rect.origin.y; + + }else{ + + if (style&WINDOW_STATUS) rect.size.height+=STATUSBARHEIGHT; + + } + + [window setContentMaxSize:rect.size]; + +} + + + + + +void NSSetStatus(nsgadget *gadget,BBString *data,int pos){ + + NSString *text; + + WindowView *window; + + ToolView *toolview; + + + + text=NSStringFromBBString(data); + + if ((gadget->style&WINDOW_TOOL) == 0) { + + window=(WindowView*)gadget->handle; + + [window setStatus:text align:pos]; + + } else { + + toolview =(ToolView*)gadget->handle; + + [toolview setStatus:text align:pos]; + + } + +} + + + +int NSClientWidth(nsgadget *gadget){ + + NSRect frame; + + if (gadget->internalclass==GADGET_DESKTOP){ + + frame=[[NSScreen deepestScreen] visibleFrame]; + + return frame.size.width; + + } + + if (!gadget->view) return gadget->w; + + frame=[gadget->view frame]; + + return frame.size.width; + +} + + + +int NSClientHeight(nsgadget *gadget){ + + NSRect frame; + + if (gadget->internalclass==GADGET_DESKTOP){ + + frame=[[NSScreen deepestScreen] visibleFrame]; + + return frame.size.height; + + } + + if (!gadget->view) return gadget->h; + + frame=[gadget->view frame]; + + return frame.size.height; + +} + + + +void NSRedraw(nsgadget *gadget){ + + NSView *view; + switch (gadget->internalclass){ + case GADGET_WINDOW: + //window=(NSWindow*)gadget->handle; + break; + case GADGET_PANEL: + break; + default: + view=(NSView*)gadget->handle; + [view setNeedsDisplay]; + } +} + + + +void NSActivate(nsgadget *gadget,int code){ + + NSWindow *window; + + NSView *view; + + NSRect frame; + + NodeItem *node; + + TreeView *treeview; + + HTMLView *browser; + + TextView *textview; + + NSTextField *textfield; + + NSText *text; + + NSComboBox *combo; + + + +// generic commands + + + + switch (code){ + + case ACTIVATE_REDRAW: + + NSRedraw(gadget); + + return; + + } + + + +// gadget specific + + + + switch (gadget->internalclass){ + + case GADGET_WINDOW: + + window=(NSWindow*)gadget->handle; + + switch (code){ + + case ACTIVATE_FOCUS: + + if([window isVisible]) [window makeKeyAndOrderFront:NSApp]; + + break; + + case ACTIVATE_CUT: + + break; + + case ACTIVATE_COPY: + + break; + + case ACTIVATE_PASTE: + + break; + + case ACTIVATE_MINIMIZE: + + NSShow(gadget,true); + + [window miniaturize:window]; + + break; + + case ACTIVATE_MAXIMIZE: + + if ([window isMiniaturized]) [window deminiaturize:window]; + + if ([window isZoomed]==NO) [window performZoom:window]; + + NSShow(gadget,true); + + break; + + case ACTIVATE_RESTORE: + + if ([window isMiniaturized]) [window deminiaturize:window]; + + if ([window isZoomed]) [window performZoom:window]; + + NSShow(gadget,true); + + break; + +// case ACTIVATE_FULLSCREEN: + +// [NSApp setPresentationOptions:NSApplicationPresentationFullScreen]; + +// break; + + } + + break; + + + + case GADGET_TEXTFIELD: + + textfield=(NSTextField*)gadget->handle; + + window=[textfield window]; + + if (window) + + switch (code){ + + case ACTIVATE_FOCUS: + + [window makeFirstResponder:textfield]; + + break; + + case ACTIVATE_CUT: + + text=[[textfield window] fieldEditor:YES forObject:textfield]; + + [text cut:textfield]; + + break; + + case ACTIVATE_COPY: + + text=[[textfield window] fieldEditor:YES forObject:textfield]; + + [text copy:textfield]; + + break; + + case ACTIVATE_PASTE: + + text=[[textfield window] fieldEditor:YES forObject:textfield]; + + [text paste:textfield]; + + break; + + } + + break; + + + + case GADGET_TEXTAREA: + + textview=(TextView*)gadget->handle; + + switch (code){ + + case ACTIVATE_FOCUS: + + window=[textview window]; + + if (window) [window makeFirstResponder:textview]; + + break; + + case ACTIVATE_CUT: + + [textview cut:textview]; + + break; + + case ACTIVATE_COPY: + + [textview copy:textview]; + + break; + + case ACTIVATE_PASTE: + + [textview pasteAsPlainText:textview];//paste:textview]; + + break; + + case ACTIVATE_PRINT: + + [textview print:textview]; + + break; + + } + + break; + + + + case GADGET_NODE: + + node=(NodeItem*)gadget->handle; + + treeview=[node getOwner]; + + switch (code){ + + case ACTIVATE_SELECT: + + [treeview selectNode:node]; + + break; + + case ACTIVATE_EXPAND: + + [treeview expandNode:node]; + + break; + + case ACTIVATE_COLLAPSE: + + [treeview collapseNode:node]; + + break; + + } + + break; + + + + case GADGET_COMBOBOX: + + switch (code){ + + case ACTIVATE_FOCUS: + + combo=(NSComboBox*)gadget->handle; + + [combo selectText:nil]; + + break; + + } + + break; + + + + case GADGET_HTMLVIEW: + + browser=(HTMLView*)gadget->handle; + + switch(code){ + + case ACTIVATE_COPY: + + [browser copy:browser]; + + break; + + case ACTIVATE_BACK: + + [browser goBack:browser]; + + break; + + case ACTIVATE_FORWARD: + + [browser goForward:browser]; + + break; + + case ACTIVATE_PRINT: + + view=[[[browser mainFrame] frameView] documentView]; + + if (view != nil) [view print:view]; + + break; + + } + + + + default: + + switch (code){ + + case ACTIVATE_FOCUS: + + window=[gadget->handle window]; + + if (window) [window makeFirstResponder:gadget->handle]; + + break; + + } + + } + +} + + + +void NSRethink(nsgadget *gadget){ + + NSView *view; + + NSRect rect,vis; + + TextView *textview; + + TabView *tabber; + + NSButton *button; + + NSControl *combobox; + + int shouldhide; + + + + view=(NSView*)gadget->handle; + + rect=NSMakeRect(gadget->x,gadget->y,gadget->w,gadget->h); + + + + shouldhide=FALSE; + + + + switch(gadget->internalclass){ + + case GADGET_WINDOW: + + vis=[[NSScreen deepestScreen] visibleFrame]; + + rect.origin.x+=vis.origin.x; + + rect.origin.y=vis.origin.y+vis.size.height-rect.origin.y-rect.size.height; + + if ((gadget->style&WINDOW_CLIENTCOORDS)!=0){ + + if (gadget->style&WINDOW_STATUS) { + + rect.origin.y-=STATUSBARHEIGHT; + + rect.size.height+=STATUSBARHEIGHT; + + } + + rect=[(NSWindow*)view frameRectForContentRect:rect]; + + } + + + + if(![view isVisible]) shouldhide=TRUE; + + [view setFrame:rect display:YES]; + + if(shouldhide) [view orderOut:view]; + + return; + + case GADGET_NODE: + + case GADGET_MENUITEM: + + case GADGET_TOOLBAR: + + return; + + case GADGET_TEXTAREA: + + textview=(TextView*)view; + + [textview setScrollFrame:rect]; + + return; + + case GADGET_COMBOBOX: + + if (rect.size.height > 26) rect.size.height=26; + + break; + + case GADGET_BUTTON: + + button=(NSButton*)view; + + // Push Button Size Hack + + if ((gadget->style&7)==0){ + + if (gadget->h > 30) { + + [button setBezelStyle:NSRegularSquareBezelStyle]; + + } else { + + if (gadget->h < 24) { + + [button setBezelStyle:NSShadowlessSquareBezelStyle]; + + } else { + + [button setBezelStyle:NSRoundedBezelStyle]; + + } + + } + + } + + break; + + case GADGET_SLIDER: + + switch (gadget->style&12){ + + case SLIDER_SCROLLBAR: + + if (gadget->style & SLIDER_HORIZONTAL) + + rect.size.height=[NSScroller scrollerWidth]; + + else + + rect.size.width=[NSScroller scrollerWidth]; + + break; + + } + + } + + [[view superview] setNeedsDisplayInRect:[view frame]]; + + [view setFrame:rect]; + + [view setNeedsDisplay:YES]; + +} + + + +void NSRemoveColor(nsgadget *gadget){ + + switch (gadget->internalclass){ + + case GADGET_BUTTON: + + if ([[gadget->handle cell] respondsToSelector:@selector(setDrawsBackground)]){ + + [[gadget->handle cell] setDrawsBackground:false]; + + } + + break; + + case GADGET_WINDOW: + + [gadget->handle setBackgroundColor:nil]; + + [gadget->handle display]; + + break; + + case GADGET_LABEL: + + if((gadget->style&3)==LABEL_SEPARATOR) break; + + case GADGET_COMBOBOX: + + case GADGET_TEXTFIELD: + + [gadget->handle setDrawsBackground:false]; + + break; + + case GADGET_LISTBOX: + + case GADGET_TREEVIEW: + + case GADGET_PANEL: + + case GADGET_TEXTAREA: + + [gadget->handle setColor:nil]; + + break; + + } + +} + + + +void NSSetColor(nsgadget *gadget,int r,int g,int b){ + + NSColor *color; + + + + color=[NSColor colorWithDeviceRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:1.0]; + + + + switch (gadget->internalclass){ + + case GADGET_BUTTON: + + if ([[gadget->handle cell] respondsToSelector:@selector(setBackgroundColor)]) [[gadget->handle cell] setBackgroundColor:color]; + + break; + + case GADGET_COMBOBOX: + + case GADGET_WINDOW: + + [gadget->handle setBackgroundColor:color]; + + [gadget->handle display]; + + break; + + case GADGET_LABEL: + + if((gadget->style&3)==LABEL_SEPARATOR) break; + + [gadget->handle setDrawsBackground:YES]; + + case GADGET_TEXTFIELD: + + [gadget->handle setBackgroundColor:color]; + + break; + + case GADGET_LISTBOX: + + case GADGET_TREEVIEW: + + case GADGET_PANEL: + + case GADGET_TEXTAREA: + + [gadget->handle setColor:color]; + + break; + + } + +} + + + +void NSSetAlpha(nsgadget *gadget,float alpha){ + + NSWindow *window; + + PanelView *panel; + + + + switch (gadget->internalclass){ + + case GADGET_WINDOW: + + window=(NSWindow*)gadget->handle; + + [window setAlphaValue:alpha]; + + break; + + case GADGET_PANEL: + + panel=(PanelView*)gadget->handle; + + [panel setAlpha:alpha]; + + break; + + } + +} + + + +BBString *NSGetUserName(){ + + return bbStringFromNSString(CSCopyUserName(true)); + +} + + + +BBString *NSGetComputerName(){ + + return bbStringFromNSString(CSCopyMachineName()); + +} + + + +BBString *NSRun(nsgadget *gadget,BBString *text){ + + HTMLView *htmlview; + + NSString *script; + + BBString *result; + + + + result=&bbEmptyString; + + switch (gadget->internalclass){ + + case GADGET_HTMLVIEW: + + htmlview=(HTMLView*)gadget->handle; + + script=NSStringFromBBString(text); + + script=[htmlview stringByEvaluatingJavaScriptFromString:script]; + + result=bbStringFromNSString(script); + + break; + + } + + return result; + +} + + + +void NSSetText(nsgadget *gadget,BBString *data){ + + NSString *text; + + NSMutableDictionary *textAttributes; + + NSMutableParagraphStyle *parastyle; + + NSAttributedString *attribtext; + + NSObject *nsobject; + + + + attribtext=nil; + + + + if(data == nil) data=&bbEmptyString; + + + + text=NSStringFromBBString(data); + + + + nsobject=(NSObject*)gadget->handle; + + + + //printf("data->length: %d\n",data->length);fflush(stdout); + + + + switch (gadget->internalclass){ + + case GADGET_TEXTAREA: + + [nsobject setText:text]; + + break; + + case GADGET_HTMLVIEW: + + [nsobject setAddress:text]; + + break; + + case GADGET_LABEL: /* BaH */ + + switch (gadget->style&3) { + + case LABEL_SEPARATOR: + + return; + + default: + + [nsobject setStringValue:text]; + + return; + + } + + break; + + case GADGET_BUTTON: + + + + //if ([nsobject respondsToSelector:@selector(setAttributedTitle)] /*&& [nsobject respondsToSelector:@selector(font)]*/){ + + + + // Create attribute dictionary (autorelease'd) + + textAttributes=[NSMutableDictionary dictionary]; + + + + // Font + + [textAttributes setObject: [nsobject font] forKey:NSFontAttributeName]; + + + + // Paragraph style + + parastyle=[[NSMutableParagraphStyle alloc] init]; + + [parastyle setParagraphStyle:[NSParagraphStyle defaultParagraphStyle]]; + + + + if(gadget->internalclass == GADGET_BUTTON){ + + if(((gadget->style & BUTTON_PUSH) == BUTTON_PUSH) || + + (((gadget->style & 7) != BUTTON_RADIO) && + + ((gadget->style & 7) != BUTTON_CHECKBOX))) + + [parastyle setAlignment:NSCenterTextAlignment]; + + } + + + + [textAttributes setObject: parastyle forKey:NSParagraphStyleAttributeName]; + + [parastyle release]; + + + + // Text color + + if(gadget->textcolor) [textAttributes setObject: gadget->textcolor forKey: NSForegroundColorAttributeName]; + + + + // Underline / strikethrough + + [textAttributes setObject: [NSNumber numberWithInt:0] forKey: NSUnderlineStyleAttributeName]; + + [textAttributes setObject: [NSNumber numberWithInt:0] forKey: NSStrikethroughStyleAttributeName]; + + + + if ((gadget->intFontStyle&FONT_UNDERLINE)!=0) [textAttributes setObject: [NSNumber numberWithInt:(NSUnderlineStyleSingle|NSUnderlinePatternSolid)] forKey: NSUnderlineStyleAttributeName]; + + if ((gadget->intFontStyle&FONT_STRIKETHROUGH)!=0) [textAttributes setObject: [NSNumber numberWithInt:(NSUnderlineStyleSingle|NSUnderlinePatternSolid)] forKey: NSStrikethroughStyleAttributeName]; + + + + // Create attibuted text + + attribtext=[[NSAttributedString alloc] initWithString: text attributes: textAttributes]; + + + + [nsobject setAttributedTitle:attribtext]; + + break; + + //} + + case GADGET_MENUITEM: + + [nsobject setTitle:text]; + + // Required otherwise root window menus aren't updated. + + [[nsobject submenu] setTitle:text]; + + break; + + case GADGET_PANEL: + + case GADGET_NODE: + + case GADGET_WINDOW: + + [nsobject setTitle:text]; + + break; + + case GADGET_COMBOBOX: + + if(!(gadget->style & COMBOBOX_EDITABLE)) break; + + case GADGET_TEXTFIELD: + + [nsobject setStringValue:text]; + + break; + + } + +} + + + +BBString *NSGetText(nsgadget *gadget){ + + + + NSObject *nsobject; + + BBString *result; + + + + result=&bbEmptyString; + + nsobject=(NSObject*)gadget->handle; + + + + switch (gadget->internalclass){ + + case GADGET_TEXTAREA: + + result=bbStringFromNSString([[nsobject storage] string]); + + break; + + case GADGET_TEXTFIELD: + + case GADGET_COMBOBOX: + + result=bbStringFromNSString([nsobject stringValue]); + + break; + + case GADGET_HTMLVIEW: + + result=bbStringFromNSString([nsobject address]); + + break; + + case GADGET_NODE: + + result=bbStringFromNSString([nsobject value]); + + break; + + case GADGET_LABEL: /* BaH */ + + switch (gadget->style&3) { + + case 0: + + case LABEL_FRAME: + + case LABEL_SUNKENFRAME: + + result=bbStringFromNSString([nsobject stringValue]); + + } + + break; + + case GADGET_PANEL: + + case GADGET_WINDOW: + + case GADGET_BUTTON: + + case GADGET_MENUITEM: + + result=bbStringFromNSString([nsobject title]); + + break; + + } + + return result; + +} + + + +int NSCharWidth(NSFont *font,int charcode){ + + NSSize size=[font advancementForGlyph:charcode]; + + return (int)size.width; + +} + + + +void NSSetFont(nsgadget *gadget,NSFont *font){ + + NSView *view; + + + + view=(NSView*)gadget->handle; + + + + switch (gadget->internalclass){ + + case GADGET_LABEL: + + if ((gadget->style&3)==LABEL_SEPARATOR) break; + + case GADGET_BUTTON: + + [view setFont:font]; + + NSSetText(gadget,NSGetText(gadget)); //Apply underline/strikethough formatting as attributed text in NSSetText(). + + break; + + case GADGET_LISTBOX: + + case GADGET_TREEVIEW: + + case GADGET_COMBOBOX: + + case GADGET_TEXTAREA: + + case GADGET_TEXTFIELD: + + case GADGET_TABBER: + + [view setFont:font]; + + break; + + + + } + +} + + + +BBString * NSGetTooltip(nsgadget *gadget){ + + + + BBString *result; + + NSView *view; + + + + result=&bbEmptyString; + + view=(NSView*)gadget->handle; + + + + if(view) result=bbStringFromNSString([view toolTip]); + + + + return result; + +} + + + +int NSSetTooltip(nsgadget *gadget,BBString *data){ + + + + NSString *text; + + NSView *view; + + + + view =(NSView*)gadget->handle; + + text=NSStringFromBBString(data); + + + + if(view){ + + [view setToolTip:text]; + + return 1; + + } + + + + return 0; + +} + + + +// gadgetitem commands + + + +void NSClearItems(nsgadget *gadget) + +{ + + ListView *listbox; + + NSControl *combo; + + NSTabView *tabber; + + Toolbar *toolbar; + + NSToolbarItem *item; + + NSArray *items; + + int i,n; + + + + switch (gadget->internalclass){ + + case GADGET_LISTBOX: + + listbox=(ListView*)gadget->handle; + + [listbox clear]; + + break; + + case GADGET_COMBOBOX: + + combo=(NSControl*)gadget->handle; + + [combo removeAllItems]; + + break; + + case GADGET_TABBER: + + tabber=(NSTabView*)gadget->handle; + + items=[tabber tabViewItems]; + + n=[tabber numberOfTabViewItems]; + + for (i=0;ihandle; + + items=[toolbar items]; + + n=[items count]; + + for (i=0;iinternalclass){ + + case GADGET_LISTBOX: + + listbox=(ListView*)gadget->handle; + + [listbox addItem:text atIndex:index withImage:image withTip:tiptext withExtra:extra]; + + break; + + case GADGET_COMBOBOX: + + combo=(NSControl*)gadget->handle; + + [combo insertItemWithObjectValue:text atIndex:index]; + +// [[combo itemAtIndex:index] setImage:image]; + + break; + + case GADGET_TABBER: + + tabber=(NSTabView*)gadget->handle; + + tabitem=[[TabViewItem alloc] initWithIdentifier:text]; + + [tabitem setLabel:text]; + + [tabitem setImage:image]; + + [tabber insertTabViewItem:tabitem atIndex:index]; + + [tabitem release]; + + break; + + case GADGET_TOOLBAR: + + toolbar=(Toolbar*)gadget->handle; + + if (image==0){ + + int v; + + Gestalt('sysv',&v); + + if(v>=0x1070){ + + [toolbar insertItemWithItemIdentifier:NSToolbarSpaceItemIdentifier atIndex:index]; + + }else{ + + [toolbar insertItemWithItemIdentifier:NSToolbarSeparatorItemIdentifier atIndex:index]; + + } + + [toolbar setSeparatorAtIndex:index]; + + } + + else{ + + item=[[NSToolbarItem alloc] initWithItemIdentifier:text]; + + [item setImage:image]; + +// [item setLabel:text]; + + [item setAction:@selector(iconSelect:)]; + + [item setTarget:GlobalApp]; + + [item setToolTip:tiptext]; + + [item setTag:0]; + + [GlobalApp addToolbarItem:item]; + + [toolbar setToolbarItem:item atIndex:index]; + + [toolbar insertItemWithItemIdentifier:text atIndex:index]; + + } + + break; + + } + +} + + + +NSToolbarItem *FindToolbarItem(NSToolbar *toolbar,int index){ + + return (NSToolbarItem*)[[toolbar items] objectAtIndex:index]; + +} + + + +void NSSetItem(nsgadget *gadget,int index,BBString *data,BBString *tip,NSImage *image,BBObject *extra){ + + NSString *text,*tiptext; + + NSControl *combo; + + NSTabView *tabber; + + TabViewItem *tabitem; + + ListView *listbox; + + Toolbar *toolbar; + + NSToolbarItem *item; + + + + text=NSStringFromBBString(data); + + tiptext=NSStringFromBBString(tip); + + + + switch (gadget->internalclass){ + + case GADGET_LISTBOX: + + listbox=(ListView*)gadget->handle; + + [listbox setItem:text atIndex:index withImage:image withTip:tiptext withExtra:extra]; + + break; + + case GADGET_COMBOBOX: + + combo=(NSControl*)gadget->handle; + + [combo removeItemAtIndex:index]; + + [combo insertItemWithObjectValue:text atIndex:index]; + + // [[combo itemAtIndex:index] setImage:image]; + + break; + + case GADGET_TABBER: + + tabber=(NSTabView*)gadget->handle; + + tabitem=(TabViewItem*)[tabber tabViewItemAtIndex:index]; + + [tabitem setLabel:text]; + + [tabitem setImage:image]; + + break; + + case GADGET_TOOLBAR: + + toolbar=(Toolbar*)gadget->handle; + + item=FindToolbarItem(toolbar,index); + + if (item) { + + // [item setLabel:text]; + + [item setImage:image]; + + [item setToolTip:tiptext]; + + [item setTag:0]; + + } + + break; + + } + +} + + + +void NSRemoveItem(nsgadget *gadget,int index){ + + ListView *listbox; + + NSControl *combo; + + NSTabView *tabber; + + TabViewItem *tabitem; + + Toolbar *toolbar; + + + + switch (gadget->internalclass){ + + case GADGET_LISTBOX: + + listbox=(ListView*)gadget->handle; + + [listbox removeItemAtIndex:index]; + + break; + + case GADGET_COMBOBOX: + + combo=(NSControl*)gadget->handle; + + [combo removeItemAtIndex:index]; + + break; + + case GADGET_TABBER: + + tabber=(NSTabView*)gadget->handle; + + tabitem=(TabViewItem*)[tabber tabViewItemAtIndex:index]; + + [tabber removeTabViewItem:tabitem]; + + break; + + case GADGET_TOOLBAR: + + toolbar=(Toolbar*)gadget->handle; + + [toolbar removeItemAtIndex:(int)index]; + + break; + + } + +} + + + +void NSSelectItem(nsgadget *gadget,int index,int state){ + + NSControl *combo; + + NSTabView *tabber; + + ListView *listbox; + + Toolbar *toolbar; + + NSToolbarItem *item; + + + + switch (gadget->internalclass){ + + case GADGET_LISTBOX: + + listbox=(ListView*)gadget->handle; + + if(state) [listbox selectItem:index]; else [listbox deselectItem:index]; + + break; + + case GADGET_COMBOBOX: + + combo=(NSControl*)gadget->handle; + + [combo setDelegate:nil]; + + [combo selectItemAtIndex:index]; + + [combo setObjectValue:[combo objectValueOfSelectedItem]]; + + [combo setDelegate:GlobalApp]; + + break; + + case GADGET_TABBER: + + tabber=(NSTabView*)gadget->handle; + + [tabber selectTabViewItemAtIndex:index]; + + break; + + case GADGET_TOOLBAR: + + toolbar=(Toolbar*)gadget->handle; + + item=FindToolbarItem(toolbar,index); + + BOOL enable=(state&STATE_DISABLED)?false:true; + + [item setEnabled:enable]; + + int pressed=(state&STATE_SELECTED)?1:0; + + [item setTag:pressed]; + + break; + + } + +} + + + +int NSSelectedItem(nsgadget *gadget,int index){ + + NSComboBox *combo; + + NSTabView *tabber; + + ListView *listbox; + + Toolbar *toolbar; + + NSToolbarItem *item; + + int state; + + + + state=0; + + switch (gadget->internalclass){ + + case GADGET_LISTBOX: + + listbox=(ListView*)gadget->handle; + + if ([[listbox table] selectedRow]==index) state|=STATE_SELECTED; + + break; + + case GADGET_COMBOBOX: + + combo=(NSControl*)gadget->handle; + + if ([combo indexOfSelectedItem]==index) state|=STATE_SELECTED; + + break; + + case GADGET_TABBER: + + tabber=(NSTabView*)gadget->handle; + + if ([tabber indexOfTabViewItem:[tabber selectedTabViewItem]]==index) state|=STATE_SELECTED; + + break; + + case GADGET_TOOLBAR: + + toolbar=(Toolbar*)gadget->handle; + + item=FindToolbarItem(toolbar,index); + + if (![item isEnabled]) state|=STATE_DISABLED; + + if ([item tag]!=0) state|=STATE_SELECTED; + + break; + + } + + return state; + +} + + + +// treeview commands + + + +int NSCountKids(nsgadget *gadget){ + + TreeView *treeview; + + NodeItem *node; + + + + switch (gadget->internalclass){ + + case GADGET_TREEVIEW: + + treeview=(TreeView*)gadget->handle; + + return [treeview count]; + + case GADGET_NODE: + + node=(NodeItem*)gadget->handle; + + return [node count]; + + } + + return 0; + +} + + + +int NSSelectedNode(nsgadget *gadget){ + + TreeView *treeview; + + + + switch (gadget->internalclass){ + + case GADGET_TREEVIEW: + + treeview=(TreeView*)gadget->handle; + + return (int)[treeview selectedNode]; + + } + + return -1; + +} + + + +// textarea commands + + + +int LinePos(NSString *text,int pos){ + + int line,i; + + line=0; + + for (i=0;i0){ + + if ([text characterAtIndex:pos]=='\n') line--; + + pos++; + + } + + return pos; + +} + + + +NSRange GetRange(NSTextStorage *storage,int pos,int count,int units){ + + + + NSString *text; + + unsigned int max; + + + + if (units==TEXTAREA_LINES){ + + text=[storage string]; + + if (count==TEXTAREA_ALL) + + count=[storage length]; + + else + + count=CharPos(text,pos+count); + + pos=CharPos(text,pos); + + max=[storage length]-pos; + + count-=pos; + + } + + else{ + + max=[storage length]-pos; + + if (count==TEXTAREA_ALL) count=max; + + } + + + + if (count > max) count=max; + + if (count<0) count=0; + + + + //NSLog(@"GetRange() pos: %d,count: %d,length: %d\n",pos,count,[storage length]); + + + + return NSMakeRange(pos,count); + + + +} + + + +void NSReplaceText(nsgadget *gadget,int pos,int count,BBString *data,int units){ + + NSString *text; + + TextView *textarea; + + NSRange range,snap; + + NSTextStorage *storage; + + unsigned int size; + + + + text=NSStringFromBBString(data); + + textarea=(TextView*)gadget->handle; + + + + if(([[textarea string] length] == 0) || ((pos == 0) && (count == TEXTAREA_ALL))){ + + + + [textarea setText:text]; + + + + } else { + + + + snap=[textarea selectedRange]; + + range=GetRange([textarea storage],pos,count,units); + + storage=[textarea storage]; + + [storage replaceCharactersInRange:range withString:text]; + + size=[storage length]; + + if (snap.location>size) snap.location=size; + + if (snap.location+snap.length>size) snap.length=size-snap.location; + + [textarea setSelectedRange:snap]; + + + + } + + + +} + + + +void NSAddText(nsgadget *gadget,BBString *data){ + + NSString *text; + + TextView *textarea; + + NSRange range; + + + + text=NSStringFromBBString(data); + + textarea=(TextView*)gadget->handle; + + [textarea addText:text]; + + range=GetRange([textarea textStorage],[[textarea string] length],0,0); + + [textarea setSelectedRange:range]; + + [textarea scrollRangeToVisible:range]; + +} + + + +BBString *NSAreaText(nsgadget *gadget,int pos,int length,int units){ + + TextView *textarea; + + NSRange range; + + NSAttributedString *astring; + + BBString *bstring; + + + + textarea=(TextView*)gadget->handle; + + range=GetRange([textarea storage],pos,length,units); + + astring=[[textarea storage] attributedSubstringFromRange:range]; + + bstring=bbStringFromNSString([astring string]); + + return bstring; + +} + + + +int NSAreaLen(nsgadget *gadget,int units){ + + TextView *textarea; + + NSTextStorage *storage; + + unsigned ulen; + + + + textarea=(TextView*)gadget->handle; + + storage=[textarea storage]; + + ulen=[storage length]; + + if (units==TEXTAREA_LINES) ulen=LinePos([storage string],ulen)+1; + + return ulen; + +} + + + +void NSSetSelection(nsgadget *gadget,int pos,int length,int units){ + + TextView *textarea; + + NSRange range; + + + + textarea=(TextView*)gadget->handle; + + range=GetRange([textarea textStorage],pos,length,units); + + [textarea setSelectedRange:range]; + + if(!textarea->lockedNest) [textarea scrollRangeToVisible:range]; + +} + + + +void NSLockText(nsgadget *gadget){ + + TextView *textarea; + + + + textarea=(TextView*)gadget->handle; + + + + if(!textarea->lockedNest){ + + textarea->lockedRange=[textarea rangeForUserTextChange]; + + [textarea->storage beginEditing]; + + } + + + + ++textarea->lockedNest; + +} + + + +void NSUnlockText(nsgadget *gadget){ + + TextView *textarea; + + + + textarea=(TextView*)gadget->handle; + + + + --textarea->lockedNest; + + + + if(!textarea->lockedNest){ + + NSRange range=textarea->lockedRange; + + [textarea->storage endEditing]; + + if(range.location+range.length>[textarea->storage length]) range=NSMakeRange(0,0); + + [textarea setSelectedRange:range]; + + } + +} + + + +void NSSetTabs(nsgadget *gadget,int tabwidth){ + + TextView *textarea; + + textarea=(TextView*)gadget->handle; + + [textarea setTabs:tabwidth]; + +} + + + +void NSSetMargins(nsgadget *gadget,int leftmargin){ + + TextView *textarea; + + textarea=(TextView*)gadget->handle; + + [textarea setMargins:leftmargin]; + +} + + + +int NSCharAt(nsgadget *gadget,int line){ + + TextView *textarea; + + NSString *text; + + int n,i; + + + + textarea=(TextView*)gadget->handle; + + text=[[textarea storage] string]; + + n=[text length];i=0; + + while (line){ + + if (i==n) break; + + if ([text characterAtIndex:i]=='\n') line--; + + i++; + + } + + return i; + +} + + + +int NSLineAt(nsgadget *gadget,int pos){ + + TextView *textarea; + + textarea=(TextView*)gadget->handle; + + return LinePos([[textarea storage] string],pos); + +} + + + +int NSCharX(nsgadget *gadget,int pos){ + + unsigned int rectCount; + + NSRectArray rectArray; + + TextView *textarea=(TextView*)gadget->handle; + + NSRange range=GetRange([textarea textStorage],pos,0,TEXTAREA_CHARS); + + rectArray=[[textarea layoutManager] rectArrayForCharacterRange:range withinSelectedCharacterRange:range inTextContainer: [textarea textContainer] rectCount:&rectCount]; + + if(rectCount > 0) return (int)(((NSRect)rectArray[0]).origin.x-([textarea visibleRect].origin.x-[textarea textContainerOrigin].x)); + +} + + + +int NSCharY(nsgadget *gadget,int pos){ + + unsigned int rectCount; + + NSRectArray rectArray; + + TextView *textarea=(TextView*)gadget->handle; + + NSRange range=GetRange([textarea textStorage],pos,0,TEXTAREA_CHARS); + + rectArray=[[textarea layoutManager] rectArrayForCharacterRange:range withinSelectedCharacterRange:range inTextContainer: [textarea textContainer] rectCount:&rectCount]; + + if(rectCount > 0) return (int)(((NSRect)rectArray[0]).origin.y-([textarea visibleRect].origin.y-[textarea textContainerOrigin].y)); + +} + + + +int NSGetCursorPos(nsgadget *gadget,int units){ + + TextView *textarea; + + NSRange range; + + + + textarea=(TextView*)gadget->handle; + + range=[textarea rangeForUserTextChange]; + + if (range.location == NSNotFound) return 0; //KORIOLIS (avoids read-only text-area crash) + + if (units==TEXTAREA_LINES) return NSLineAt(gadget,range.location); + + return range.location; + +} + + + +int NSGetSelectionlength(nsgadget *gadget,int units){ + + TextView *textarea; + + NSRange range; + + + + textarea=(TextView*)gadget->handle; + + range=[textarea rangeForUserTextChange]; + + if (range.location == NSNotFound) return 0; //KORIOLIS (avoids read-only text-area crash) + + if (range.length == 0) return 0; + + if (units == TEXTAREA_LINES){ + + int l0=NSLineAt(gadget,range.location); + + int l1=NSLineAt(gadget,range.location+range.length-1); + + return (l1-l0+1); + + } + + return range.length; + +} + + + +void NSSetTextColor(nsgadget *gadget,int r,int g,int b){ + + + + if(gadget->textcolor) [gadget->textcolor release]; + + gadget->textcolor=[[NSColor colorWithDeviceRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:1.0] retain]; + + + + switch (gadget->internalclass){ + + case GADGET_LABEL: + + switch (gadget->style&3) { + + case LABEL_SEPARATOR: + + return; + + } + + case GADGET_TEXTFIELD: + + case GADGET_LISTBOX: + + case GADGET_TREEVIEW: + + case GADGET_TEXTAREA: + + [gadget->handle setTextColor:gadget->textcolor]; + + break; + + default: + + NSSetText(gadget,NSGetText(gadget)); //Attempt to reset text with NSAttributedString + + break; + + } + +} + + + +void NSSetStyle(nsgadget *gadget,int r,int g,int b,int flags,int pos,int length,int units) { + + TextView *textarea; + + NSRange _range; + + NSColor *color; + + int traits=0; + + + + textarea=(TextView*)gadget->handle; + + _range=GetRange([textarea storage],pos,length,units); + + color=[NSColor colorWithDeviceRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:1.0]; + + + + [[textarea storage] removeAttribute:NSLinkAttributeName range:_range]; + + [[textarea storage] addAttribute:NSForegroundColorAttributeName value:color range:_range]; + + [[textarea storage] addAttribute:NSUnderlineStyleAttributeName value:[NSNumber numberWithInt:(flags & 4)?NSUnderlineStyleSingle:NSUnderlineStyleNone] range:_range]; + + [[textarea storage] addAttribute:NSStrikethroughStyleAttributeName value:[NSNumber numberWithInt:(flags & 8)?NSUnderlineStyleSingle:NSUnderlineStyleNone] range:_range]; + + + + traits |= (flags & 1)?NSBoldFontMask:NSUnboldFontMask; + + traits |= (flags & 2)?NSItalicFontMask:NSUnitalicFontMask; + + + + [[textarea storage] applyFontTraits: traits range:_range]; + +} + + + +void NSSetValue(nsgadget *gadget,float value){ + + NSProgressIndicator *progbar; + + NSDate *date; + + NSValue *info; + + NSRunLoop *runloop; + + + + switch (gadget->internalclass){ + + case GADGET_PROGBAR: + + progbar=(NSProgressIndicator*)gadget->handle; + + [progbar setDoubleValue:value]; + + break; + + } + +} + + + +// slider / scrollbar + + + +void NSSetSlider(nsgadget *gadget,double value,double small,double big){ + + NSScroller *scroller; + + NSSlider *slider; + + NSStepper *stepper; + + NSRect frame; + + float size; + + + + switch (gadget->style&12){ + + case SLIDER_SCROLLBAR: + + scroller=(NSScroller*)gadget->handle; + + if(value > (big-small)) + + value=1.0L; + + else if(big-small) + + value/=(big-small); + + else + + value=0.0L; + + [scroller setKnobProportion:(small/big)]; + + [scroller setDoubleValue:value]; + + break; + + case SLIDER_TRACKBAR: + + slider=(NSSlider*)gadget->handle; + + [slider setMinValue:small]; + + [slider setMaxValue:big]; + + [slider setDoubleValue:value]; + + break; + + case SLIDER_STEPPER: + + stepper=(NSStepper*)gadget->handle; + + [stepper setMinValue:small]; + + [stepper setMaxValue:big]; + + [stepper setDoubleValue:value]; + + break; + + } + +} + + + +double NSGetSlider(nsgadget *gadget){ + + NSControl *control; + + control=(NSControl*)gadget->handle; + + return [control doubleValue]; + +} + + + +void NSSetPointer(int shape){ + + NSCursor *cursor; + + cursor=[NSCursor arrowCursor]; + + + + switch (shape){ + +// case POINTER_DEFAULT:cursor=[NSCursor ];break; + + case POINTER_ARROW:cursor=[NSCursor arrowCursor];break; + + case POINTER_IBEAM:cursor=[NSCursor IBeamCursor];break; + +// case POINTER_WAIT:cursor=[NSCursor ];break; + + case POINTER_CROSS:cursor=[NSCursor crosshairCursor];break; + + case POINTER_UPARROW:cursor=[NSCursor resizeUpCursor];break; + + + +// case POINTER_SIZENWSE:cursor=NSCursorCreateStock(curNWSE);break; + +// case POINTER_SIZENESW:cursor=NSCursorCreateStock(curNESW);break; + +// case POINTER_SIZEALL:cursor=NSCursorCreateStock(curSizeAll);break; + +// case POINTER_NO:cursor=NSCursorCreateStock(curNoEntry);break; + +// case POINTER_HELP:cursor=NSCursorCreateStock(curHelp);break; + + + + case POINTER_SIZEWE:cursor=[NSCursor resizeLeftRightCursor];break; + + case POINTER_SIZENS:cursor=[NSCursor resizeUpDownCursor];break; + + case POINTER_HAND:cursor=[NSCursor pointingHandCursor];break; + +// case POINTER_APPSTARTING:cursor=[NSCursor ];break; + + } + + [cursor set]; + +} + + + +typedef struct bbpixmap bbpixmap; + + + +struct bbpixmap{ + +// BBObject + + void *class; + + int refs; + +// pixmap + + unsigned char *pixels; + + int width,height,pitch,format,capacity; + +}; + + + + + +#define PF_I8 1 + +#define PF_A8 2 + +#define PF_BGR888 3 + +#define PF_RGB888 4 + +#define PF_BGRA8888 5 + +#define PF_RGBA8888 6 + +#define PF_STDFORMAT PF_RGBA8888 + + + +const static char BytesPerPixel[]={0,1,1,3,3,4,4}; + +const static char BitsPerPixel[]={0,8,8,24,24,32,32}; + +const static char RedBitsPerPixel[]={0,0,0,8,8,8,8}; + +const static char GreenBitsPerPixel[]={0,0,0,8,8,8,8}; + +const static char BlueBitsPerPixel[]={0,0,0,8,8,8,8}; + +const static char AlphaBitsPerPixel[]={0,0,8,0,0,8,8}; + + + +NSImage *NSPixmapImage(bbpixmap *pix){ + + NSImage *image; + + NSBitmapImageRep *bitmap; + + int spp,bpp,i; + + int bytesperrow; + + BOOL alpha; + + unsigned char * data; + + + + alpha=AlphaBitsPerPixel[pix->format]?YES:NO; + + spp=BytesPerPixel[pix->format]; + + bpp=BitsPerPixel[pix->format]; + + bytesperrow=pix->width*spp; + + + + bitmap=[[[NSBitmapImageRep alloc] + + initWithBitmapDataPlanes:NULL + + pixelsWide:pix->width + + pixelsHigh:pix->height + + bitsPerSample:8 + + samplesPerPixel:spp + + hasAlpha:alpha + + isPlanar:NO + + colorSpaceName:NSDeviceRGBColorSpace + +// bitmapFormat:NSAlphaNonpremultipliedBitmapFormat + + bytesPerRow:bytesperrow + + bitsPerPixel:bpp] autorelease]; + + + + data=[bitmap bitmapData]; + + + + for(i=0; i < pix->height; i++) { + + memcpy(data + (i * bytesperrow),pix->pixels + (i * pix->pitch),bytesperrow); + + } + + + + image=[[NSImage alloc] initWithSize:NSMakeSize(pix->width,pix->height)]; + + [image addRepresentation:bitmap]; + + [image retain]; + + return image; + +} + + + +void NSSetImage(nsgadget *gadget,NSImage *image,int flags){ + + PanelView *panel; + + NSButton *button; + + NSMenuItem *menu; + + + + switch (gadget->internalclass){ + + case GADGET_PANEL: + + panel=(PanelView*)gadget->handle; + + [panel setImage:image withFlags:flags]; + + break; + + case GADGET_BUTTON: + + if ((flags & GADGETPIXMAP_ICON) && (gadget->style <= BUTTON_PUSH)){ + + button=(NSButton *)gadget->handle; + + [button setImage:image]; + + if (flags & GADGETPIXMAP_NOTEXT) { + + [button setImagePosition:NSImageOnly]; + + } else { + + [button setImagePosition:NSImageLeft]; + + } + + } + + break; + + case GADGET_MENUITEM: + + if (flags & GADGETPIXMAP_ICON){ + + menu=(NSMenuItem*)gadget->handle; + + [menu setImage:image]; + + } + + break; + + } + +} + + + +void NSSetIcon(nsgadget *gadget,NSImage *image){ + + NodeItem *node; + + + + switch (gadget->internalclass){ + + case GADGET_NODE: + + node=(NodeItem*)gadget->handle; + + [node setIcon:image]; + + break; + + } + +} + + + +void NSSetNextView(nsgadget *gadget,nsgadget *nextgadget){ + + NSView *view,*nextview; + + view=(NSView*)gadget->handle; + + nextview=(NSView*)nextgadget->handle; + + [view setNextKeyView:nextview]; + +} + + + +static int keyToChar(int key){ + + if(key>=KEY_A && key<=KEY_Z) return key-KEY_A+'a'; + + if(key>=KEY_F1 && key<=KEY_F12) return key-KEY_F1+NSF1FunctionKey; + + + + switch(key){ + + case KEY_BACKSPACE:return 8; + + case KEY_TAB:return 9; + + case KEY_ESC:return 27; + + case KEY_SPACE:return 32; + + case KEY_PAGEUP:return NSPageUpFunctionKey; + + case KEY_PAGEDOWN:return NSPageDownFunctionKey; + + case KEY_END:return NSEndFunctionKey; + + case KEY_HOME:return NSHomeFunctionKey; + + case KEY_UP:return NSUpArrowFunctionKey; + + case KEY_DOWN:return NSDownArrowFunctionKey; + + case KEY_LEFT:return NSLeftArrowFunctionKey; + + case KEY_RIGHT:return NSRightArrowFunctionKey; + + case KEY_INSERT:return NSInsertFunctionKey; + + case KEY_DELETE:return NSDeleteFunctionKey; + + case KEY_TILDE:return '~'; + + case KEY_MINUS:return '-'; + + case KEY_EQUALS:return '='; + + case KEY_OPENBRACKET:return '['; + + case KEY_CLOSEBRACKET:return ']'; + + case KEY_BACKSLASH:return '\\'; + + case KEY_SEMICOLON:return ';'; + + case KEY_QUOTES:return '\''; + + case KEY_COMMA:return ','; + + case KEY_PERIOD:return '.'; + + case KEY_SLASH:return '/'; + + } + + return 0; + +} + + + +void NSSetHotKey(nsgadget *gadget,int key,int modifier){ + + int chr; + + unichar uchar[1]; + + NSString *keyStr; + + int modMask; + + NSMenuItem *menuItem; + + if(gadget->internalclass!=GADGET_MENUITEM) return; + + modMask=0; + + if(modifier & 1) modMask|=NSShiftKeyMask; + + if(modifier & 2) modMask|=NSControlKeyMask; + + if(modifier & 4) modMask|=NSAlternateKeyMask; + + if(modifier & 8) modMask|=NSCommandKeyMask; + + menuItem=(NSMenuItem*)gadget->handle; + + chr=keyToChar(key); + + if(!chr) { + + [menuItem setKeyEquivalent:@""]; + + [menuItem setKeyEquivalentModifierMask:0]; + + return; + + } + + uchar[0]=chr; + + keyStr=[NSString stringWithCharacters:uchar length:1]; + + [menuItem setKeyEquivalent:keyStr]; + + [menuItem setKeyEquivalentModifierMask:modMask]; + +} \ No newline at end of file diff --git a/mod/maxgui.mod/cocoamaxgui.mod/cocoagui.bmx b/mod/maxgui.mod/cocoamaxgui.mod/cocoagui.bmx new file mode 100644 index 0000000..ebf62fd --- /dev/null +++ b/mod/maxgui.mod/cocoamaxgui.mod/cocoagui.bmx @@ -0,0 +1,1026 @@ +Strict + +Import MaxGUI.MaxGUI +Import Pub.MacOs + +Import "-framework WebKit" +Import "cocoa.macos.m" + +Extern + + Function bbSystemEmitOSEvent( nsevent:Byte Ptr,nsview:Byte Ptr,source:Object ) + + Function ScheduleEventDispatch() + + Function NSBegin() + Function NSEnd() + + Function NSGetSysColor(colorindex,r:Int Ptr,g:Int Ptr, b:Int Ptr) + Function NSColorRequester(r,g,b) + Function NSSetPointer(shape) + + Function NSCharWidth(font,charcode) + ' create + Function NSInitGadget(gadget:TNSGadget) + ' generic + Function NSActiveGadget() + Function NSFreeGadget(gadget:TNSGadget) + Function NSClientWidth(gadget:TNSGadget) + Function NSClientHeight(gadget:TNSGadget) + Function NSRethink(gadget:TNSGadget) + Function NSRedraw(gadget:TNSGadget) + Function NSActivate(gadget:TNSGadget,code) + Function NSState(gadget:TNSGadget) + Function NSShow(gadget:TNSGadget,bool) + Function NSEnable(gadget:TNSGadget,bool) + Function NSCheck(gadget:TNSGadget,bool) + Function NSSetNextView(gadget:TNSGadget,nextgadget:TNSGadget) + Function NSSetHotKey(gadget:TNSGadget,hotkey,modifier) + Function NSSetTooltip(gadget:TNSGadget,tip$) + Function NSGetTooltip$(gadget:TNSGadget) + Function NSSuperview(view:Int) + ' window + Function NSSetStatus(gadget:TNSGadget,text$,pos) + Function NSSetMinimumSize(gadget:TNSGadget,width,height) + Function NSSetMaximumSize(gadget:TNSGadget,width,height) + Function NSPopupMenu(gadget:TNSGadget,menu:TNSGadget) + ' font + Function NSRequestFont(font) + Function NSLoadFont(name$,size:Double,flags) + Function NSGetDefaultFont() + Function NSSetFont(gadget:TNSGadget,font) + Function NSFontName$(font) + Function NSFontStyle(font) + Function NSFontSize:Double(font) + ' items + Function NSClearItems(gadget:TNSGadget) + Function NSAddItem(gadget:TNSGadget,index,text$,tip$,image,extra:Object) + Function NSSetItem(gadget:TNSGadget,index,text$,tip$,image,extra:Object) + Function NSRemoveItem(gadget:TNSGadget,index) + Function NSSelectItem(gadget:TNSGadget,index,state) + Function NSSelectedItem(gadget:TNSGadget,index) + Function NSSelectedNode(gadget:TNSGadget) + ' text + Function NSSetText(gadget:TNSGadget,text$) + Function NSGetText$(gadget:TNSGadget) + Function NSReplaceText(gadget:TNSGadget,pos,length,text$,units) + Function NSAddText(gadget:TNSGadget,text$) + Function NSAreaText$(gadget:TNSGadget,pos,length,units) + Function NSAreaLen(gadget:TNSGadget,units) + Function NSLockText(gadget:TNSGadget) + Function NSUnlockText(gadget:TNSGadget) + Function NSSetTabs(gadget:TNSGadget,tabwidth) + Function NSSetMargins(gadget:TNSGadget,leftmargin) + Function NSSetColor(gadget:TNSGadget,r,g,b) + Function NSRemoveColor(gadget:TNSGadget) + Function NSSetAlpha(gadget:TNSGadget,alpha#) + Function NSSetTextColor(gadget:TNSGadget,r,g,b) + Function NSGetCursorPos(gadget:TNSGadget,units) + Function NSGetSelectionlength(gadget:TNSGadget,units) + Function NSSetStyle(gadget:TNSGadget,r,g,b,flags,pos,length,units) + Function NSSetSelection(gadget:TNSGadget,pos,length,units) + Function NSCharAt(gadget:TNSGadget,line) + Function NSLineAt(gadget:TNSGadget,index) + Function NSCharX(gadget:TGadget,char) + Function NSCharY(gadget:TGadget,char) + ' prop + Function NSSetValue(gadget:TNSGadget,value#) + ' slider + Function NSSetSlider(gadget:TNSGadget,value:Double,small:Double,big:Double) + Function NSGetSlider:Double(gadget:TNSGadget) + ' images for panels and nodes + Function NSPixmapImage(image:TPixmap) + Function NSSetImage(gadget:TNSGadget,nsimage,flags) + Function NSSetIcon(gadget:TNSGadget,nsimage) + Function NSCountKids(gadget:TNSGadget) + ' html + Function NSRun$(gadget:TNSGadget,script$) + ' misc + Function NSRelease(nsobject) + ' system + Function NSGetUserName$() + Function NSGetComputerName$() + +EndExtern + +Global GadgetMap:TMap=New TMap + +maxgui_driver=New TCocoaMaxGuiDriver + +Type TCocoaMaxGUIDriver Extends TMaxGUIDriver + + Global CocoaGuiFont:TCocoaGuiFont + + Method New() + NSBegin + atexit_ NSEnd + If Not CocoaGuiFont Then CocoaGuiFont = TCocoaGuiFont(LibraryFont(GUIFONT_SYSTEM)) + End Method + + Method UserName$() + Return NSGetUserName$() + End Method + + Method ComputerName$() + Return NSGetComputerName$() + End Method + + Method CreateGadget:TGadget(internalclass,name$,x,y,w,h,group:TGadget,style) + Local p,hotkey + If internalclass=GADGET_MENUITEM + name=name.Replace("&","") + ElseIf internalclass=GADGET_BUTTON + p=name.Find("&") + If p>-1 +' hotkey=Asc(name[p..p+1]) 'to do - convert and call SetHotKey before return + name=name[..p]+name[p+1..] + EndIf + ElseIf internalclass=GADGET_TOOLBAR + Global _toolbarcount + _toolbarcount:+1 + name="Toolbar"+_toolbarcount + EndIf + Local gadget:TNSGadget = TNSGadget.Create(internalclass,name,x,y,w,h,TNSGadget(group),style) + If internalclass<>GADGET_WINDOW And internalclass<>GADGET_MENUITEM And internalclass<>GADGET_DESKTOP + gadget.SetLayout EDGE_CENTERED,EDGE_CENTERED,EDGE_CENTERED,EDGE_CENTERED + EndIf + If group Then gadget._SetParent group + gadget.SetTextColor(0,0,0) + gadget.LinkView + Return gadget + End Method + + Function CreateFont:TGuiFont(handle,flags=FONT_NORMAL) + Local font:TGuiFont = New TCocoaGuiFont + font.handle = handle + font.name = NSFontName(handle) + font.size = NSFontSize(handle) + font.style = NSFontStyle(handle)|flags + Return font + EndFunction + + Method LoadFont:TGuiFont(name$,size,flags) + Return CreateFont(NSLoadFont(name,Double(size),flags),flags) + End Method + + Method LoadFontWithDouble:TGuiFont(name$,size:Double,flags) + Return CreateFont(NSLoadFont(name,size,flags),flags) + End Method + + Method LibraryFont:TGuiFont( pFontType% = GUIFONT_SYSTEM, pFontSize:Double = 0, pFontStyle% = FONT_NORMAL ) + If pFontType = GUIFONT_SYSTEM Then + Local tmpHandle% = NSGetDefaultFont() + If pFontSize <= 0 Then pFontSize = NSFontSize(tmpHandle) + Return LoadFontWithDouble( NSFontName(tmpHandle), pFontSize, NSFontStyle(tmpHandle)|pFontStyle ) + Else + Return Super.LibraryFont( pFontType, pFontSize, pFontStyle ) + EndIf + EndMethod + + Method LookupColor( colorindex:Int, red:Byte Var, green:Byte Var, blue:Byte Var ) + + Local r, g, b + + If NSGetSysColor( colorindex, Varptr r, Varptr g, Varptr b ) + red = r & $FF + green = g & $FF + blue = b & $FF + Return True + EndIf + + Return Super.LookupColor( colorindex, red, green, blue ) + + EndMethod + + Method RequestColor(r,g,b) + Return NSColorRequester(r,g,b) + End Method + + Method RequestFont:TGuiFont(font:TGuiFont) + Local handle + If font handle=font.handle + handle=NSRequestFont(handle) + If handle + If font And handle=font.handle Return font + Return CreateFont(handle) + EndIf + End Method + + Method SetPointer(shape) + NSSetPointer shape + End Method + + Method ActiveGadget:TGadget() + PollSystem() + Local handle = NSActiveGadget() + If handle Return GadgetFromHandle(handle) + End Method + + Method LoadIconStrip:TIconStrip(source:Object) + Return TCocoaIconStrip.Create(source) + End Method +End Type + +Function GadgetFromHandle:TNSGadget( handle ) + Return TNSGadget( GadgetMap.ValueForKey( TIntWrapper.Create(handle) ) ) +End Function + +Function EmitCocoaOSEvent( event:Byte Ptr,handle,gadget:Object = Null ) + Local owner:TGadget = TGadget(gadget) + If Not owner Then owner = GadgetFromHandle( handle ) + If owner Then + While owner.source + owner = owner.source + Wend + EndIf + bbSystemEmitOSEvent event,Byte Ptr(handle),owner +End Function + +Function EmitCocoaMouseEvent( event:Byte Ptr, handle ) + Local gadget:TNSGadget +' While handle + gadget = GadgetFromHandle( handle ) + If gadget Then + If (gadget.sensitivity & SENSITIZE_MOUSE) Then + EmitCocoaOSEvent( event, handle, gadget ) + Return 1 + EndIf + Return 0 + EndIf +' handle = NSSuperview(handle) +' Wend +End Function + +Function EmitCocoaKeyEvent( event:Byte Ptr, handle ) + Local gadget:TNSGadget + While handle + gadget = GadgetFromHandle( handle ) + If gadget Then + If (gadget.sensitivity & SENSITIZE_KEYS) Then + EmitCocoaOSEvent( event, handle, gadget ) + Return 1 + EndIf + Return 0 + EndIf + handle = NSSuperview(handle) + Wend +End Function + +Function PostCocoaGuiEvent( id,handle,data,mods,x,y,extra:Object ) + + Local gadget:TNSGadget + + DispatchGuiEvents() + + If handle Then + + gadget = GadgetFromHandle(handle) + + If gadget Then + + Select gadget.internalclass + Case GADGET_TREEVIEW + extra=GadgetFromHandle(data) + data = 0 + EndSelect + + Select id + Case EVENT_WINDOWSIZE + If gadget.width <> x Or gadget.height <> y Then + gadget.SetRect gadget.xpos,gadget.ypos,x,y + gadget.LayoutKids + Else + Return + EndIf + + Case EVENT_WINDOWMOVE + If gadget.xpos <> x Or gadget.ypos <> y Then + gadget.SetRect x,y,gadget.width,gadget.height + Else + Return + EndIf + + Case EVENT_MENUACTION + extra=TNSGadget.popupextra + TNSGadget.popupextra=Null + + Case EVENT_GADGETACTION + + Select gadget.internalclass + Case GADGET_SLIDER + Local oldValue:Int = gadget.GetProp() + If data Then + Select (gadget.style&(SLIDER_SCROLLBAR|SLIDER_TRACKBAR|SLIDER_STEPPER)) + Case SLIDER_SCROLLBAR + If data > 1 Then + data = gadget.small + ElseIf data < -1 Then + data = -gadget.small + EndIf + EndSelect + gadget.SetProp(oldValue+data) + data=gadget.GetProp() + If (data = oldValue) Then Return + Else + data=gadget.GetProp() + EndIf + Case GADGET_LISTBOX, GADGET_COMBOBOX, GADGET_TABBER + If (data > -1 And data < gadget.items.length) extra=gadget.ItemExtra(data) + Case GADGET_BUTTON + Select (gadget.style&7) + Case BUTTON_CHECKBOX + If ButtonState(gadget) = CHECK_INDETERMINATE Then SetButtonState(gadget, CHECK_SELECTED ) + Case BUTTON_RADIO + If (gadget.style&BUTTON_PUSH) Then SetButtonState(gadget,CHECK_SELECTED) + gadget.ExcludeOthers() + EndSelect + data=ButtonState(gadget) + Case GADGET_TOOLBAR + If data>-1 Then + extra=gadget.ItemExtra(data) + If (gadget.ItemFlags(data)&GADGETITEM_TOGGLE) Then gadget.SelectItem(data,2) + EndIf + EndSelect + + Case EVENT_GADGETSELECT, EVENT_GADGETMENU + Select gadget.internalclass + Case GADGET_LISTBOX, GADGET_COMBOBOX, GADGET_TABBER + If data>-1 Then extra=gadget.ItemExtra(data) + EndSelect + + Case EVENT_GADGETLOSTFOCUS + + QueueGuiEvent id,gadget,data,mods,x,y,extra + ScheduleEventDispatch() + Return + + EndSelect + EndIf + + EndIf + + PostGuiEvent id,gadget,data,mods,x,y,extra + +EndFunction + +Function FilterKeyDown( handle,key,mods ) + Local source:TNSGadget + If handle + source=GadgetFromHandle(handle) + EndIf + If source And source.eventfilter<>Null + Local event:TEvent=CreateEvent(EVENT_KEYDOWN,source,key,mods) + Return source.eventfilter(event,source.context) + EndIf + Return 1 +End Function + +Function FilterChar( handle,key,mods ) + Local source:TNSGadget + Select key + ' Return true if they are arrow key characters + Case 63232, 63233, 63234, 63235 + Return 1 + EndSelect + If handle + source=GadgetFromHandle(handle) + EndIf + If source And source.eventfilter<>Null 'Return source.charfilter(char,mods,source.context) + Local event:TEvent=CreateEvent(EVENT_KEYCHAR,source,key,mods) + Return source.eventfilter(event,source.context) + EndIf + Return 1 +End Function + +Type TNSGadget Extends TGadget + + Field internalclass, origclass 'internalclass: Class the Cocoa driver uses to draw the gadget, origclass: Expected class to be returned by Class() method + Field handle + Field view, textcolor 'view: NSView handle, textcolor: NSColor handle for Objective-C code + Field intFontStyle 'Copy of font.style used by cocoa.macos.m to handle underlining/strikethrough etc. that isn't included in NSFont + Field pixmap:TPixmap + Field icons:TCocoaIconStrip + Field small, big + Field canvas:TGraphics + Field font:TCocoaGuiFont + Field enabled:Int = True, forceDisable:Int = False + +' main factory command + + Function Create:TNSGadget(internalclass,text$,x,y,w,h,group:TGadget,style) + + Local gadget:TNSGadget = New TNSGadget + gadget.origclass = internalclass + gadget.internalclass = internalclass + + If Not group And internalclass<>GADGET_DESKTOP Then group = Desktop() + gadget.parent = group + + gadget.name = text + gadget.SetRect x,y,w,h 'setarea + gadget.style = style + gadget.font = TCocoaMaxGUIDriver.CocoaGUIFont + + If TNSGadget(group) Then + gadget.forceDisable = Not (TNSGadget(group).enabled And Not TNSGadget(group).forceDisable) + EndIf + + NSInitGadget gadget + + If internalclass<>GADGET_TOOLBAR 'toolbars retain name to key insertgadgetitem + gadget.name = Null + EndIf + + GadgetMap.Insert TIntWrapper.Create(gadget.handle),gadget + If gadget.view And gadget.handle <> gadget.view Then + GadgetMap.Insert TIntWrapper.Create(gadget.view),gadget + EndIf + + If internalclass=GADGET_SLIDER Then gadget.SetRange(1,10) + gadget.LockLayout() + + If (internalclass=GADGET_WINDOW) And (style&WINDOW_STATUS) Then + If (style&WINDOW_CLIENTCOORDS) Then + gadget.SetMinimumSize(25,0) + Else + gadget.SetMinimumSize(25,70) + EndIf + EndIf + + If LocalizationMode() & LOCALIZATION_OVERRIDE Then LocalizeGadget(gadget,text,"") + + gadget.SetEnabled(gadget.enabled) + + Return gadget + + End Function + + Method Class() + Return origclass + EndMethod + + Function ToView:TNSGadget(value:Object) + Local view:TNSGadget = TNSGadget(value) + If Not view Return + Select view.internalclass + Case GADGET_DESKTOP,GADGET_WINDOW,GADGET_TOOLBAR,GADGET_LABEL,GADGET_PROGBAR,GADGET_MENUITEM,GADGET_NODE + Return Null + End Select + Return view + End Function + + Method LinkView() + Local First:TNSGadget + Local prev:TNSGadget + Local i,n + + If Not parent Return + If Not ToView(Self) Return + n=parent.kids.count()-1 + If n<0 Return +' find first view in family + For i=0 Until n + First=ToView(parent.kids.ValueAtIndex(i)) + If First Exit + Next + If Not First Return +' find last view in family + For i=n-1 To 0 Step -1 + prev=ToView(parent.kids.ValueAtIndex(i)) + If prev Exit + Next + If Not prev Return + NSSetNextView(prev,Self) + NSSetNextView(Self,First) + End Method + + Method Delete() + Free() + End Method + +' generic gadget commands + + Method Query(queryid) + Select queryid + Case QUERY_NSVIEW + Return handle + Case QUERY_NSVIEW_CLIENT + Return view + End Select + End Method + + Method Free() + If handle Then + + If canvas Then canvas.close + + GadgetMap.Remove TIntWrapper.Create(handle) + If view And handle <> view Then + GadgetMap.Remove TIntWrapper.Create(view) + view = Null + EndIf + + If parent Then + parent.kids.Remove Self + End If + + NSFreeGadget Self + font = Null + + handle = Null + + EndIf + End Method + + Method Rethink() 'resize - was recursive + NSRethink( Self ) + End Method + + Method ClientWidth() + Return Max(NSClientWidth(Self),0) + End Method + + Method ClientHeight() + Return Max(NSClientHeight(Self),0) + End Method + + Method Activate(cmd) + NSActivate( Self, cmd ) + End Method + + Method State() + Local tmpState:Int = NSState(Self)&~STATE_DISABLED + If Not enabled Then tmpState:|STATE_DISABLED + Return tmpState + End Method + + Method SetShow(bool) + NSShow( Self, bool ) + End Method + + Method SetText(msg$) + If internalclass=GADGET_HTMLVIEW + Local anchor$,a + a=msg.Find("#") + If a<>-1 anchor=msg[a..];msg=msg[..a] + If msg[0..7].ToLower()<>"http://" And msg[0..7].ToLower()<>"file://" + If FileType(msg) + msg="file://"+msg + Else + msg="http://"+msg + EndIf + EndIf + msg:+anchor + msg=msg.Replace(" ","%20") + ElseIf internalclass=GADGET_MENUITEM + msg=msg.Replace("&", "") + EndIf + NSSetText Self,msg + End Method + + Method Run$(msg$) + If internalclass=GADGET_HTMLVIEW Return NSRun(Self,msg) + End Method + + Method GetText$() + Return NSGetText(Self) + End Method + + Method SetFont(pFont:TGuiFont) + If Not TCocoaGuiFont(pFont) Then pFont = TCocoaMaxGUIDriver.CocoaGuiFont + font = TCocoaGuiFont(pFont) + intFontStyle = font.style + NSSetFont( Self, font.handle ) + End Method + + Method SetColor(r,g,b) + NSSetColor Self,r,g,b + End Method + + Method RemoveColor() + NSRemoveColor Self + End Method + + Method SetAlpha(alpha#) + NSSetAlpha Self,alpha + End Method + + Method SetTextColor(r,g,b) + NSSetTextColor Self,r,g,b + End Method + + Method SetPixmap(pixmap:TPixmap,flags) + Local nsimage, x + If pixmap + Select pixmap.format + Case PF_I8,PF_BGR888 + pixmap=pixmap.Convert( PF_RGB888 ) + Case PF_A8,PF_BGRA8888 + pixmap=pixmap.Convert( PF_RGBA8888 ) + End Select + + If AlphaBitsPerPixel[ pixmap.format ] + For Local y=0 Until pixmap.height + For x=0 Until pixmap.width + Local argb=pixmap.ReadPixel( x,y ) + pixmap.WritePixel x,y,premult(argb) + Next + Next + EndIf + nsimage=NSPixmapImage(pixmap) + EndIf + NSSetImage(Self,nsimage,flags) + End Method + + Method SetTooltip(pTip$) + Select internalclass + Case GADGET_WINDOW, GADGET_DESKTOP, GADGET_LISTBOX, GADGET_MENUITEM, GADGET_TOOLBAR, GADGET_TABBER, GADGET_NODE + Default;Return NSSetTooltip( Self, pTip ) + EndSelect + EndMethod + + Method GetTooltip$() + Select internalclass + Case GADGET_WINDOW, GADGET_DESKTOP, GADGET_LISTBOX, GADGET_MENUITEM, GADGET_TOOLBAR, GADGET_TABBER, GADGET_NODE + Default;Return NSGetTooltip( Self ) + EndSelect + EndMethod + + Method ExcludeOthers() + For Local g:TNSGadget = EachIn parent.kids + If g<>Self And g.internalclass=GADGET_BUTTON And (g.style&7)=BUTTON_RADIO + NSCheck g,False + EndIf + Next + End Method + + Method SetSelected(bool) + NSCheck Self,bool + If internalclass=GADGET_BUTTON And (style&7)=BUTTON_RADIO And bool + ExcludeOthers + EndIf + End Method + + Method SetEnabled(enable) + Local old:Int = enabled And Not forceDisable + enabled = enable + If Class() = GADGET_WINDOW Then + NSEnable Self, enable + Else + enable = enable And Not forceDisable + NSEnable Self, enable + If (enable <> old) Then + For Local tmpGadget:TNSGadget = EachIn kids + tmpGadget.forceDisable = Not enable + If tmpGadget.Class() <> GADGET_WINDOW Then tmpGadget.SetEnabled(tmpGadget.enabled) + Next + EndIf + EndIf + End Method + + Method SetHotKey(hotkey,modifier) + NSSetHotKey Self,hotkey,modifier + End Method + +' window commands + + Field _statustext$ + + Method GetStatusText$() + Return _statustext + EndMethod + + Method SetStatusText(msg$) + Local t,m0$,m1$,m2$ + _statustext = msg + m0=msg + t=m0.find("~t");If t<>-1 m1=m0[t+1..];m0=m0[..t]; + t=m1.find("~t");If t<>-1 m2=m1[t+1..];m1=m1[..t]; + NSSetStatus Self,m0,0 + NSSetStatus Self,m1,1 + NSSetStatus Self,m2,2 + End Method + + Method GetMenu:TGadget() + Return Self + End Method + + Global popupextra:Object + + Method PopupMenu(menu:TGadget,extra:Object) + popupextra=extra + NSPopupMenu Self,TNSGadget(menu) + End Method + + Method UpdateMenu() + End Method + + Method SetMinimumSize(w,h) + NSSetMinimumSize Self,w,h + End Method + + Method SetMaximumSize(w,h) + NSSetMaximumSize Self,w,h + End Method + + Method SetIconStrip(iconstrip:TIconStrip) + icons=TCocoaIconStrip(iconstrip) + End Method + +' item handling commands + + Method ClearListItems() + NSClearItems Self + End Method + + Method InsertListItem(index,item$,tip$,icon,extra:Object) + Local image + If internalclass=GADGET_TOOLBAR + item=name+":"+index + EndIf + If icons And icon>=0 image=icons.images[icon] + NSAddItem Self,index,item,tip,image,extra + End Method + + Method SetListItem(index,item$,tip$,icon,extra:Object) + Local image + If internalclass=GADGET_TOOLBAR + item=name+":"+index + EndIf + If icons And icon>=0 image=icons.images[icon] + NSSetItem Self,index,item,tip,image,extra + End Method + + Method RemoveListItem(index) + NSRemoveItem Self,index + End Method + + Method SetListItemState(index,state) + NSSelectItem Self,index,state + End Method + + Method ListItemState(index) + Return NSSelectedItem(Self,index) + End Method + +' treeview commands + + Method RootNode:TGadget() + Return Self + End Method + + Method SetIcon(icon) + Local p:TNSGadget + p=Self + While p + If p.icons Exit + p=TNSGadget(p.parent) + Wend + If p + If icon>-1 + NSSetIcon Self,p.icons.images[icon] + Else + NSSetIcon Self,Null + EndIf + EndIf + End Method + + Method InsertNode:TGadget(index,text$,icon) + Local node:TNSGadget = Create(GADGET_NODE,text,0,0,0,0,Self,index) + node.SetIcon icon + node._SetParent Self + Return node + End Method + + Method ModifyNode(text$,icon) + NSSetText Self,text + SetIcon icon + End Method + + Method SelectedNode:TGadget() + Local index = NSSelectedNode(Self) + If (index) Return GadgetFromHandle(index) + End Method + + Method CountKids() + Return NSCountKids(Self) + End Method + +' textarea commands + + Method ReplaceText(pos,length,text$,units) +?debug + If pos<0 Or pos+length>AreaLen(units) Throw "Illegal Range" +? + NSReplaceText Self,pos,length,text$,units + End Method + + Method AddText(text$) + NSAddText Self,text + End Method + + Method AreaText$(pos,length,units) +?debug + If pos<0 Or pos+length>AreaLen(units) Throw "Illegal Range" +? + Return NSAreaText(Self,pos,length,units) + End Method + + Method AreaLen(units) + Return NSAreaLen(Self,units) + End Method + + Method LockText() + NSLockText Self + End Method + + Method UnlockText() + NSUnlockText Self + End Method + + Method SetTabs(tabwidth) + NSSetTabs Self,tabwidth + End Method + + Method SetMargins(leftmargin) + NSSetMargins Self,leftmargin + End Method + + Method GetCursorPos(units) + Return NSGetCursorPos(Self,units) + End Method + + Method GetSelectionLength(units) + Return NSGetSelectionLength(Self,units) + End Method + + Method SetStyle(r,g,b,flags,pos,length,units) +?debug + If pos<0 Or pos+length>AreaLen(units) Throw "Illegal Range" +? + If length NSSetStyle Self,r,g,b,flags,pos,length,units + End Method + + Method SetSelection(pos,length,units) +?debug + If pos<0 Or pos+length>AreaLen(units) Throw "Illegal Range" +? + NSSetSelection Self,pos,length,units + End Method + + Method CharAt(line) +?debug + If line<0 Or line>AreaLen(TEXTAREA_LINES) Throw "Parameter Out Of Range" +? + Return NSCharAt(Self,line) + End Method + + Method LineAt(index) +?debug + If index<0 Or index>AreaLen(TEXTAREA_CHARS) Throw "Parameter Out Of Range" +? + Return NSLineAt(Self,index) + End Method + + Method CharX(char) + Return NSCharX(Self,char) + EndMethod + + Method CharY(char) + Return NSCharY(Self,char) + EndMethod + +' progbar + + Method SetValue(value#) + NSSetValue Self,value + End Method + +' slider / scrollbar + + Method SetRange(_small,_big) + small=_small + big=_big + NSSetSlider Self,GetProp(),small,big + End Method + + Method SetProp(pos) + NSSetSlider Self,pos,small,big + End Method + + Method GetProp() + Local value:Double = NSGetSlider(Self) + If Not (style&(SLIDER_TRACKBAR|SLIDER_STEPPER)) + value:*(big-small) + If value>big-small value=big-small + EndIf + Return Int(value+0.5:Double) + End Method + +' canvas + + Method AttachGraphics:TGraphics( flags ) + canvas=brl.Graphics.AttachGraphics( Query(QUERY_NSVIEW_CLIENT),flags ) + End Method + + Method CanvasGraphics:TGraphics() + Return canvas + End Method + +End Type + + +Type TCocoaIconStrip Extends TIconStrip + + Field images[] + + Function IsNotBlank(pixmap:TPixmap) + Local y, h = pixmap.height + Local c = pixmap.ReadPixel(0,0) + For Local x = 0 Until h + For y = 0 Until h + If pixmap.ReadPixel(x,y)<>c Return True + Next + Next + End Function + + Function Create:TCocoaIconStrip(source:Object) + Local icons:TCocoaIconStrip + Local pixmap:TPixmap,pix:TPixmap + Local n,x,w,nsimage + pixmap=TPixmap(source) + If Not pixmap pixmap=LoadPixmap(source) + If Not pixmap Return + Select pixmap.format + Case PF_I8,PF_BGR888 + pixmap=pixmap.Convert( PF_RGB888 ) + Case PF_A8,PF_BGRA8888 + pixmap=pixmap.Convert( PF_RGBA8888 ) + End Select + + If AlphaBitsPerPixel[ pixmap.format ] + For Local y=0 Until pixmap.height + For x=0 Until pixmap.width + Local argb=pixmap.ReadPixel( x,y ) + pixmap.WritePixel x,y,premult(argb) + Next + Next + EndIf + + n=pixmap.width/pixmap.height; + If n=0 Return + icons=New TCocoaIconStrip + icons.pixmap=pixmap + icons.count=n + icons.images=New Int[n] + w=pixmap.width/n + For x=0 Until n + pix=pixmap.Window(x*w,0,w,pixmap.height) + If IsNotBlank(pix) icons.images[x]=NSPixmapImage(pix) + Next + Return icons + EndFunction + +EndType + +Type TCocoaGuiFont Extends TGuiFont + + Method Delete() + If handle Then + NSRelease(handle) + handle = 0 + EndIf + EndMethod + + Method CharWidth(char) + If handle + Return NSCharWidth(handle,char) + EndIf + Return 0 + EndMethod + +EndType + +Type TIntWrapper Final + Field value:Int + Function Create:TIntWrapper(value:Int) + Local tmpWrapper:TIntWrapper = New TIntWrapper + tmpWrapper.value = value + Return tmpWrapper + EndFunction + Method Compare( o:Object ) + Local c:TIntWrapper = TIntWrapper(o) + If c Then Return (value - c.value) + Return Super.Compare(o) + EndMethod + Method ToString$() + Return value + EndMethod +EndType + +Private + +Function premult(argb) + Local a = ((argb Shr 24) & $FF) + Return ((((argb&$ff00ff)*a)Shr 8)&$ff00ff)|((((argb&$ff00)*a)Shr 8)&$ff00)|(a Shl 24) +End Function diff --git a/mod/maxgui.mod/cocoamaxgui.mod/cocoamaxgui.bmx b/mod/maxgui.mod/cocoamaxgui.mod/cocoamaxgui.bmx new file mode 100644 index 0000000..d9b8653 --- /dev/null +++ b/mod/maxgui.mod/cocoamaxgui.mod/cocoamaxgui.bmx @@ -0,0 +1,18 @@ +Rem +bbdoc: MaxGUI Drivers/CocoaMaxGUI +about: +This Module provides a Cocoa based #MaxGUI driver For MacOS. + +See version.txt for history +End Rem +Module MaxGUI.CocoaMaxGUI + +Strict + +ModuleInfo "Version: 1.56" +ModuleInfo "Author: Simon Armstrong, Seb Hollington" +ModuleInfo "License: zlib/libpng" + +?MacOs +Import "cocoagui.bmx" +? diff --git a/mod/maxgui.mod/cocoamaxgui.mod/version.txt b/mod/maxgui.mod/cocoamaxgui.mod/version.txt new file mode 100644 index 0000000..2d4f533 --- /dev/null +++ b/mod/maxgui.mod/cocoamaxgui.mod/version.txt @@ -0,0 +1,212 @@ +History for cocoa.macos.m +1.56 +fix forward references to conform to latest xcode rule +1.55 Dev +Added patch for blank toolbar items in Lion +Added UserName$ and ComputerName$ support +Stopped EmitCocoaMouseEvent from crashing htmlview +1.54 Release +Added RemoveGadgetColor support +Removed use of NSPopoupButton for non editable ComboBoxes /topic=91200 +Reduced ambiguous use of gadget.(arg)name$ /topic=91292 +1.53 Release +Added GetStatusText() implementation. +1.52b Release +Fixed several TextArea CTDs. +1.51 Release +skn3[ac]'s canvas EVENT_MOUSEUP firing fix. +Added icon support to non-editable ComboBoxes. +Fixed ComboBox events and implemented non-editable ComboBoxes as NSPopUpButtons. +1.50 Release +Added LookupColor() method to TCocoaMaxGUIDriver. +1.49b Release +Fixed EVENT_GADGETLOSTFOCUS interrupting modal drop-down boxes. +1.49 Release +Fixed SetTextAreaText style problem. +Added support for thumb-size jumps for scroll-bars. +1.48b Release +Removed NSString helper functions, instead linking to those in Pub.MacOS. +Swapped out NSInteger for (int) to avoid compile errors for OS X < 10.5. +1.48 Release +Fixed mouse and key events for various different gadgets. +Added support for mouse wheel events. +Fixed listbox tooltip crash. +1.47 Release +Fixed DeselectGadgetItem() for ListBox gadgets. +Applied d-bug's NSScrollbar sizing fix. +1.46b Release +Swapped out deprecated selectItem() selectors for their selectItemIndexes() counterparts. +1.46 Release +Fixed panel pixmaps with alpha components. +Fixed NSColorRequester(). +1.45 Release +Fixed event generation for canvas gadgets. +Fixed the CanvasView setAlpha unrecognized selector error. +1.44 Release +Added explicit removal of NSLinkAttributeName in NSSetStyle(). +Fixed NSScroller events. +Swapped out deprecated float selectors for their double-precision counterparts. +Disabled a few unwanted NSTextView features. +Fixed progress bar NSState() crash. +Disabling a panel should now grey out all of its children. +Fixed a few issues concerning client areas and toolbars. +Suppressed arrow keys EVENT_GADGETCHAR filter. +Fixed group panel initial text setting. +Fixed NSSetPointer through disableCursorRects calls. +Fixed HTMLView navigation bugs, and added support for both style constants. +Finished treeview icon support. +Fixed listview/treeview scrollbar problems. +Added recursive owner.source handling to EmitCocoaOSEvent. +PanelViews now extend and use NSBox. +Added separator for statusbar. +Attempt to fix PANEL_SUNKENFRAME offset issues. +LABEL_SUNKENFRAME alignment fix. +Added TCocoaGuiFont and corresponding Delete() method. +Attempt to fix button fonts and colors. +Fixed ClearGadgetItems() for tabber. +Fixed exception when freeing tabbers. +1.43 Release +Nodes should now be added to their parent's 'kids' list. +1.42 Release +Updated NSGadget struct in cocoa.macos.m with recent changes made to MaxGUI TGadget. +1.41 Release +Fixed clipping issue involving tabs with icons. +Fixed strange combobox popup list behaviour when appearing over mouse-sensitive gadgets. +Added EVENT_GADGETMENU for tabbers. +Added maximum size restraint (26px) for comboboxes to avoid warnings on Leopard. +Fixed crashes caused by changing NSFont pointers. Use GetFontHandle() to refresh. +1.40 Release +Added CharX() and CharY() methods for text areas. +Fixed activation issues when windows are restored from a minimized state. +Fixed drawing when PANELPIXMAP_FIT2 was used with the PANEL_BORDER flag. +Fixed hidden child window behaviour (a problem causing the IDE Options window to show when restoring from the dock). +1.39 Release +Fixed ACTIVATE_PRINT code for HTMLViews so that the page is printed instead of just the visible region. +Added hack so that treeviews now have a horizontal scrollbar (if required). +Changed child window behaviour so that they are more like child windows in MaxGUI.Win32MaxGUIEx. +Added several Window checks to determine if it is hidden before proceeding. +Fixed textcolor memory access error in NSFreeGadget. +Fixed NSGetText() for HTMLViews and NodeItems. +Added new BUTTON_PUSH support for radio/checkboxes. +Fixed FontStyle() so that it now returns values. +Added LibraryFont() method to TCocoaMaxGUIDriver. +1.38 Release +Added new Class() method to return a gadget's class for the new GadgetClass() function. +1.37 Release +Fixed push, ok and cancel buttons returning alternate values from ButtonState() - now returns 0. +NSState() and NSCheck() tweaked for CHECK_INDETERMINATE. +Disabled text-areas should no longer allow you to select text. +Fixed limited tabstops in textareas (now uses setDefaultTabInterval selector). +Cleaned up NSSetText(), NSGetText(), NSRedraw() and NSRethink(). +Added label, button and text-field text colors. +Added button, text-field and window background colors. +Added SetSensitivity() and GetSensitivity() methods. +1.36 Release +Added GadgetText() support for more gadgets (e.g. buttons/menus etc.). +Improved handling of text-areas in NSState to avoid crash. +Swapped tabber icon drawing code (so that it works). +Added finishing touch to tool-window support (thanks Brucey)! +Fixed TCocoaIconStrip to work with ExtractIconPixmapFromStrip(). +Tidied up PostCocoaGUIEvent() and added item-extra to tabber events. +1.35 Release +Added SetMaximumSize method to TNSGadget for possible future implementation of SetMaxWindowSize(). +Added gadget font support for Buttons, Listboxes, Treeviews and Comboboxes. +Added a workaround for missing setEnabled responder on textareas. +Added Koriolis's fix for read-only text-areas in NSGetCursorPos() and NSGetSelectionlength(). +Added SetGadgetTooltip() support for non-item based gadgets. +Added Brucey's icon support for buttons and menus using SetGadgetPixmap(). +Added possible fix for app crashing when popup-menus are created with no text. +Added possible fix for GadgetDisabled() on certain gadgets. +Added style hack to accomodate taller buttons. +1.34 Release +Fixed excessive memory usage by NSPixmapImage +1.33 Release +Implemented Brucey's fixes +1.32 Release +Fixed to support new SetDataSource fields in TGadget +1.31 Release +Fixed TreeView generating extra events +Added Seb's fix for button state in EVENT_GADGETACTION data +1.30 Release +Fixed ClearGadgetItems on ListBox generating event +Strip windows hotkey shortcut '&' from CreateButton text +Fixed FreeGadget childwindow crash +Fixed SetPanelPixmap panel,Null +1.29 Release +Added fixes for new label code +1.28 Release +Optimized ListView tooltip usage +Added Brucey's fixes for ListView events +Added Brucey's fixes for Label alignment +1.27 Release +Bumped version for bizzarro TEXTFORMAT_????? issue +1.26 Release +Fixed gadget and extra data fields for EVENT_GADGETMENU node events +Added itemx extra object to relevant GADGETACTION events +Tweaked bounds checking on textarea CharAt and LineAt +1.25 Release +Fixed keyboard filtering bug introduced in 1.23 +1.24 Release +Bumped to keep in sync with new TMap +1.23 Release +Fixed ActiveGadget, Cut, Copy and Paste for TextFields +Fixed RequestColor exception with non RGB colors +1.22 Release +Premultiply pixels when calling NSPixmap with alpha +1.21 Release +Fixed SetMinWindowSize +1.20 Release +Fixed WINDOW_CLIENTCOORDS behavior +Desktop() client shape now based on [Screen visibleFrame] +1.19 Release +Fixed multiple toolbar errors +1.18 Release +Added EVENT_GADGETLOSTFOCUS +1.17 Release +Rebuilt under 10.3.9 +1.16 Release +Fixed SetGadgetText to work with menu items courtesy Byteemoz +1.15 Release +Fixed Radio Buttons to exclude others in group +1.14 Release +Fixed TNSGadget.GetText$() for menu items +1.13 Release +NSLoadFont now defaults to systemFontOfSize if font not found +1.12 Release +Rebuilt under 10.3.9 +1.11 Release +Stopped borderless window exceptions (NSDrawWindowBackground) +1.10 Release +Added ComboBox support in NSGetText and NSSetText +Fixed ListBox gadget action not reporting selection in EventData +1.09 Release +Fixed TextView::SetFont (affecting empty TextAreas like MaxIDE output) +1.08 Release +Removed NSCompositeCopy so 32bit panelpixmaps blend with window not desktop +Fixed DisableGadget for TextFields, Sliders and Menus +Stopped TreeViewNode with iconstrip crashing with no icon (icon=-1) +Stopped stepper Slider value from wrapping around +Fixed TextField to scroll single line correctly +Added out of range error checks for TextArea commands +1.07 Release +Added support for ActiveGadget() command +Fixed FreeGadget TextArea not removing the view +1.06 Release +Fixed RedrawGadget with window gadgets +Fixed unselecting item in listbox error +1.05 Release +Fixed redraw of superview after setframe on view +Fixed InsertTreeViewNode ignoring index +Fixed SelectTreeViewNode generating multiple events +1.04 Release +Fixed NSEnable and NSState STATE_DISABLED issues +1.03 Release +Fixed NSRequestFont behavior with null default +Fixed Disable on Panel and Canvas NSGadgets +1.02 Release +Added Query(QUERY_NSVIEW) and Query(QUERY_NSVIEW_CLIENT) +Fixed positioning of PopupWindowMenu +Flipped coordinate system for PANEL_VIEW client +1.01 Release +Now uses default app menu instead of creating new menu + diff --git a/mod/maxgui.mod/drivers.mod/drivers.bmx b/mod/maxgui.mod/drivers.mod/drivers.bmx new file mode 100644 index 0000000..21e7ca9 --- /dev/null +++ b/mod/maxgui.mod/drivers.mod/drivers.bmx @@ -0,0 +1,29 @@ + +Strict + +Rem +bbdoc: MaxGUI/Drivers +about: +Your MaxGUI applications should import this module if they want BlitzMax to selectively import the latest official #{MaxGUI drivers} for your application and platform: + +[ @Platform | @{Default Driver} +* Windows 2000/XP/Vista | #MaxGUI.Win32MaxGUIEx +* Windows 9X | #MaxGUI.Win32MaxGUIEx (requires unicows.dll or MSLU to run) +* Linux | #MaxGUI.FLTKMaxGUI +* Mac OS X | #MaxGUI.CocoaMaxGUI +] +End Rem +Module MaxGUI.Drivers + +ModuleInfo "Version: 0.04" +ModuleInfo "Author: Simon Armstrong" +ModuleInfo "License: zlib/libpng" + +?Win32 +Import MaxGUI.Win32MaxGUIEx +Import "-lunicows" +?MacOs +Import Maxgui.CocoaMaxGui +?Linux +Import Maxgui.FLTKMaxGui +? diff --git a/mod/maxgui.mod/drivers.mod/version.txt b/mod/maxgui.mod/drivers.mod/version.txt new file mode 100644 index 0000000..29ba8cf --- /dev/null +++ b/mod/maxgui.mod/drivers.mod/version.txt @@ -0,0 +1,9 @@ +0.04 Release +MaxGUI.Win32MaxGUIEx has now become the standard Windows MaxGUI driver. +0.03 Release +The most appropriate driver is automatically selected at run-time for the OS. +Both the old ANSI and new UNICODE Windows modules are now imported. +0.02 Release +Added compiler directives and removed MaxGUI.MaxGUI. +0.01 Release +Initial release required for BlitzMax 1.28 examples update. diff --git a/mod/maxgui.mod/fltkmaxgui.mod/CHANGES b/mod/maxgui.mod/fltkmaxgui.mod/CHANGES new file mode 100644 index 0000000..7cef1a9 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/CHANGES @@ -0,0 +1,3598 @@ +CHANGES IN FLTK 1.3.0 + + - Fixed Fl_Text_Display Tabulator calculations (STR #2450) + - Fixed file access code to use UTF-8 strings (STR #2440) + - Fixed ARM Unicode cross compilation issue (STR #2432) + - Improved support for faulty X11 clients (STR #2385) + - Fixed xclass support for Fl_Window (STR #2053) + - Fixed Caps Lock handling in X11/XIM (STR #2366) + - Fixed handling of missing fonts in Xft (STR #2355) + - Added alternative Xft font names (STR #2215) + - Update lib png access (STR #2442) + - Fixed OpenGL hide/show issue in OS X (STR #2260) + - Added visual feedback for button shortcuts (STR #2372) + - Fixed internationalisation of menus using FLuid (STR #2246) + - Fixed blinking of selection when the mouse was dragged + outside of the Fl_Text_* widget + - Added drag'n'drop support for Fl_Text_* + - Fixed Unicode support for Fl_Text_* widgets + - Added mouse!=0 check in Fl_Glut_Window::handle (STR #2381) + - Fixed menu and shortcut handling (STR #2243) + - Removed support for gcc 2.x (or older) + - Fixed fltk-config to give --libs on one line (STR #2408) + - Fixed tab key navigation to inactive widgets (STR #2420) + - Fixed outside label redraw damage areas (STR #2436) + - Added callback when double-clicking file in a file chooser + (STR #2346) + - Fixed label alignment (STR #2436) + - Added interface to set color chooser mode (STR #2407) + - Fixed compile errors when HAVE_LIBJPEG was not defined + (STR #2382) + - Fixed special handling for ISO back-tab keycode (STR #2369) + - Fixed wrong relative path (STR #2384) + - Fixed static allocation in Fl_Tabs (STR #2370) + - Fixed Fl_Widget::measure_label() to const (STR #2406) + - Added step by step README's for MSWindows, OS X, and four + Linux distros + - Fixed unbalanced Windows OleInitialize/OleUnitialize calls + when loading/unloading the FLTK dll (STR #2417) + - Fixed X11/XDBE double buffering (STR #2152, #2197) + - Added new label and image alignments (STR #2269) + - Added documentation for event delivery (STR #1983) + - Fixed menu and tooltip window animation bug under X11 (compiz) + by setting an appropriate window type (STR #2082) + - redesigned CMake files (STR #2317). + - Fixed max. fd calculation, if USE_POLL is enabled (STR #2324) + - Fixed clipping for offscreen rendering (OSX, STR #2330) + - Added printing support (Fl_Printer class and friends) for native + printing on Windows and Mac OS X, PostScript printing on X11 + with CUPS or lp, and PostScript file output on all platforms + - Added basic Fl_Device abstraction layer for all drawing functions + - Fixed possibility of wrong flags() in Fl_Window::iconlabel() + (STR #2161) + - Fixed Scrollbar events when max is less than min (STR #2283) + - Added argument-less constructor in Fuid Widget Class + - Fixed menu item counting issue in Fluid (STR #2322) + - Added Fl_Menu_::find_item by callback + - Removed redundant Fl_Group casts + - Added indexing to Fl_Preferences + - Integrated default menu into Demo test app + - Added automated Xcode IDE file generation to Fluid + - Fixed lost top item in Fluid's tree browser (STR #2233) + - Fixed crash in test/Editor when freeing buffer + too soon (STR #2294) + - Fixed Fl_Preferences Cygwin wide character bug (STR #2164) + - Fixed sorting in Fl_Browser - last item would not + be sorted (STR #2300) + - Fixed window levels in OS X Cocoa (STR #2316) + - Added jpeg support to Fluid image() element + - Added loading jpeg images from memory + - Added binary data type to Fluid + - File chosser preview would hang if a device was choosen + - Replaced _WIN32 symbols that had come with UTF-8 and the + new Fl_Table widget with WIN32 + - Fixed a buffer overflow in fl_utf8from_mb() (STR #2279) + - Fixed a Windows GDI leak when testing alpha blending capabilities + - Fixed a name conflict with new (VS 2008 Express) winsock2.h + versions and another conflict that produced compile errors + with VS 2008 Express (STR #2301) + - Widgets now remove stale entries from the default callback + queue when they are deleted (STR #2302) + - Moved OS X code base to the more moder Cocoa toolkit thanks + to the awesome work of Manolo Gouy (STR #2221) + - Added template to generate new projects with Xcode. + - Managing all Widget flags in a single location now (STR #2161) + - Fixed all color related call to Fl_Color type (STR #2208) + - File chooser preview now recognizes utf8 encoded + text files (STR #2218) + - Empty functions in Fluid no longer create an + implementation (STR #2259) + - Fixed Fluid dependency on X11 (STR #2261) + - Updated the bundled libpng to v1.2.40 (released Sep. 10, 2009) + - Fixed Fl_Choice contrast with light-on-dark settings (STR #2219) + - Fixed X server "lock", if a modal dialog window is opened + while a menu is active (STR #1986) + - Updated mirror sites in documentation (STR #2220) + - Setting a default font for Xft (STR #2216) + - Temporarily limited builds to 32-bit on OX S to stay + compatible to Snow Leopard + - Fixed Windows compile bug with "#define USE_COLORMAP 0" + (STR #2241) + - Fixed glibc 2.10 compiler problems (Fedora 11 and others) + with scandir() and strchr() (STR #2222) + - Corrected const methods of Fl_Text_{Buffer|Display|Selection} + to be declared const, corrected an Fl_Text_Buffer attrib. typo + - Fixed OpenGL shared context handling (STR #2135) + - Fixed gray-scale images with alpha channel (STR #2105) + - Fixed unexpected shortcut behavior for Win32 (STR #2199) + - Fixed documentation for Fl_Progress (STR #2209) + - Fluid printing used wrong colors under Windows (STR #2195) + - Updated documentation for Fl_Input_ + - Fixed fl_draw_image to obey the alpha channel, hoping that + this has no adverse effect on existing software (OS X only) + - Added OS X cursor control to Fl_Input (STR #2169) + - Fix for multiple popups, when dragging and calling fl_alert() + and friends from the callback (STR #2159) + - Avoiding crashes for recursive common dialogs (this does not + fix the issue at hand yet) (STR #1986, 2150) + - Fixed control key keycodes with modifiers on OS X + - Added menu shortcut alignment for OS X + - Fixed bad system menu hadling in OS X (STR #2153) + - Fixed File Input mouse pointer dragging (STR #2181) + - Added alternative text input awareness on OS X + - Fixed 'del' keycode on OS X (must be verified for all keyboards) + - Fixed OS X support for sending and receiving dnd data as utf8 + - Added drop box to utf8 test that will show the utf8 encoding + for the first dropped character + - Restructured the unittest application + - Fl_Preferences.H now doesn't include windows.h any more + (Windows only, STR #2173). + - Fl_Window::draw() now doesn't reset its x/y-coordinates to 0 + anymore before drawing itself and its children. + - All draw() methods of widgets are now protected (STR #2142). + - The new configure option --enable-x11 (lowercase 'x') enables + Cygwin builds under Windows (with --enable-cygwin) to use X11 + instead of GDI drawing (STR #2147, #2183) and is ignored otherwise. + - Added Fl_Scroll::bbox() documentation (STR #1893) + - Removed an XForms compatibility "feature" that prevented the down + array of Fl_Menu_Button from drawing (STR #2141). + - New class Fl_Widget_Tracker to simplify safe handling of widget + deletion in callbacks. This is used in Fl_Widget::do_callback() + to prevent accessing widgets after deletion in the callback. + - Fl_Help_View handles HTML2 font color specification (STR #890) + - Copyright dates are now updated to 2009 (STR #2036) + - Copy/Paste operations should now work as expected, + with utf8,16 support and fltk1.1 compatibility. (STR #2104,2121). + - Widgets now remove themselves from their parent group (if any), + when destroyed (STR #1894) + - Added flexible gap size for text buffer (STR #2046) + - Fixed static linking of image libraries (STR #1962) + - Fixed fl_set_spot() for Windows (STR #2101) + - Added sorting to Fl_Browser_ (STR #2113) + - Added utf8 support for OS X copy and paste + - Improved handling of composed keys in OS X 10.5 and up + - Fixed callback would not be called when shortcut was used with + radio and toggle buttons in default FL_RELEASE mode. + - Fixed a problem with TrackMouseEvent() (Windows only) that would + generate wrong FL_LEAVE events with subwindows. TrackMouseEvent + is now enabled by default (it was disabled for GNU compilers). + It can be disabled by defining NO_TRACK_MOUSE. + Improved test/subwindow.cxx (STR #2079) + - Fixed documentation (added missing COMCTRL32.LIB dependency) + - Fixed menu position close to screen border (STR #2057) + - Improved stability of fl_read_image (STR #2021) + - Fixed adding an idle handler during + a draw() call (STR #1950) + - Fl_Group::clip_children() is now public (STR #2017) + - Added clarification to Fl_GL_Window mode + function (STR #1945) + - Fixed Fluid textcolor output (STR #1992) + - Fixed wrong default value of Fl_Spinner in + Fluid (STR #1991) + - Fixed first modifier key event (STR #1952) + - Fl_Group and Fl_Scroll now resize themselves before + resizing their children (STR #2032) + - "fltk-config --post foo" now creates an application + bundle rather than attaching a resource fork. + - Added scroll_to(int,int) to Fl_Scroll, replacing + position(int,int) which now behaves as it should (STR #1303) + - Fixed Fl_Scroll inside Fl_Scroll (STR #265) + - Hardcoded 1.1 references in src/Makefile to 1.3 (STR #1922) + - Changed font index to 32 bit + - Changed font size to 32 bit + - Changed widget coordinates to 32 bit + - Added support for shortcuts for Fl_Input_, + Fl_Value_Input, and Fl_Text_Display derived + widgets (STR #1770) + - Initial setup (STR #1904) + - winsock dll is dynamically loaded and by default + ws2_32.dll, use of winsock1 is still possible by defining + USE_WSOCK1 at compile time. + - Cairo support: added --enable-cairo and --enable-cairoext + configure options. + - visualc(6) & vc2005 devenv's are in the ide subdirectory + - hide() and show() methods are now virtual from Fl_Widget, + was only virtual since Fl_Window derived classes before. + So now widget->hide() will work if widget is a window. + - New widgets: Fl_Tree, Fl_Table, Fl_Native_File_Chooser + - added Fl_Menu_ methods: insert(), find_index(), clear_submenu() + - Bug reports/enhancements now refer to the STR form http://www.fltk.org/str.php + +CHANGES IN FLTK 1.1.9 + + - Improved color contrast in secondary selection blocks + of Fl_Text_Display (STR #1917) + - Fixed regression in callback handling (STR #1918) + - Fixed wrong relative path when absolute path has a + trailing slash in fl_filename_relative (STR #1920) + - Fixed multiple selction of files and directories in + Fl_File_Chooser (STR #1913) + - Fixed MSWindows crash when selecting umlauts + in Fl_Help_View (STR #1912) + + +CHANGES IN FLTK 1.1.8 + + - Documentation fixes (STR #1454, STR #1455, STR #1456, + STR #1457, STR #1458, STR #1460, STR #1481, STR #1578, + STR #1639, STR #1645, STR #1644, STR #1792, STR #1793, + STR #1742, STR #1777, STR #1794, STR #1827, STR #1843, + STR #1796, STR #1815, STR #1726, STR #1753, STR #1855, + STR #1862, STR #1867, STR #1874, STR #1888) + - Fixed library path in Makefile (STR #1885) + - Fixed image read for partial regions on X11 + (STR #1716) + - Fixed KDE/Gnome icon paths (STR #1795) + - Fixed Tab key to wrap around menu bars (STR #1877) + - Fixed possible timer leak in Scrollbar (STR #1880) + - Added documentation about the potential limitations + of Fl::grab on newer operating systems (STR #1747) + - Fixed lockout when mixing popups and alerts + (STR # 1869) + - Fixed recursion crash in event handling (STR #1873) + - Fixed missing return code in 'fltk-config' (STR #1875) + - Fixed inconsistencies with CHANGED flags (STR #1719) + - Fixed message sent to hidden widgets (STR #1849) + - Fixed width calculation in Fl_Help_View (STR #1868) + - Fixed offset bug in OS X pixmap code (STR #1856) + - Fixed potential buffer overrun + in Fl_Preferences (STR #1853) + - Fixed method attributes in consecutive class + declarations in FLUID (STR #1741) + - FLUID checks for seperately declared callbacks to + avoid a bogus "extern" declaration (STR #1776) + - Added "protected" class memebrs in FLUID + - Double-clicking a widget in a FLUID layout will show + the item in the widget browser + - Fixed color highlighting in Text_Display + - Fixed 16 bit PNM image support (STR #1847) + - Fixed exposure event on zero size windows (STR #1824) + - Fixed overlay offset for OS X Quartz (STR #1729) + - gl_font() support for Xft+X11 (STR #1809) + - Fl_Gl_Window::mode() needed to hide and show the window + when toggling stereo mode (STR #1846) + - Fl_Gl_Window::show() did not work reliably on Mac OS X + (STR #1707) + - Added Fl_Group::clip_children() methods to support + automatic clipping of child widget drawing (STR #1844) + - Fl_Browser_ and friends now support FL_WHEN_ENTER_KEY + for both Enter/Return and double-clicks (STR #1818) + - Fl_Help_View did not release the images it used (STR + #1817) + - Shared libraries would not build on 64-bit Linux + systems with an existing non-PIC FLTK installation + (STR #1791) + - Fl_Browser::hide() and Fl_Browser::show() did not + correctly update the scrollbar (STR #1724) + - The configure script now shows a summry of the + configuration results (STR #1810) + - "fltk-config --use-* --libs" did not list all of the + dependent libraries (STR #1799) + - Hiding a nested window on WIN32 caused 100% CPU (STR #1748) + - Changing the window size in FLUID would not mark the + project as modified (STR #1751) + - Fixed fl_filename_isdir for "/"-path (STR #1761) + - Fixed Fl_Chart drawing (STR #1756) + - Fixed mapping of subwindows with unmapped parent + windows (STR #1706) + - Fixed rendering of grayscale images with alpha + channel (STR #1703) + - Fixed occasional incomplete refresh (STR #1681) + - Improved fl_down, fl_frame, added fl_box (STR #1678) + - Fixed selection of submenu items in + input_choice (STR #1676) + - Fixed calculation of stride for image scaling and + color manipulation (STR #1673) + - Made -O3 the default optimization on Cygwin/Mingw since + -Os currently creates bad code (STR #1656) + - OSF/Tru64 now uses 'install-sh' instead of 'install' to + accomodate for a missing '-d' option (STR #1632) + - New option in Fluid project settings to translate all + shortcut modifiers from FL_META or FL_CTRL to FL_COMMAND + - Made icon size fixed (50x50) in fl_message etc. (STR #1626) + - Fixed selection of first word in Fl_Help_View + - Fixed endless loop in Fl_Text_Display (STR #1655) + - Allowing shortcuts in Tabs (STR #1652) + - Fixed Makefile "make clean" (STR #1642, + STR #1643, STR #1641) + - The sample RPM spec file now enables large file support + and threading support (STR #1603) + - Changed minimum contrast between background and text to + 99 and added more weight to the blue component to improve + readability for certain color combinations (STR #1625) + - Fixed VCNet OpenGL project file (STR #1617) + - Fixed scrolling of clipped areas in MSWindows (STR + #1601) + - Fixed clipping in OS X Quartz offscreen buffers (STR + #1595) + - Now flush file chooser preferences after every change to + avoid data loss (STR #1609) + - The Fl_File_Chooser constructor now saves and restores the + current group (STR #1611) + - Added Fl::awake(fn*,void*) to set a handler for thread + messages (STR #1536) + - Added "mute sound" option to Sudoku game. + - Updated the bundled zlib to v1.2.3. + - Updated the bundled libpng to v1.2.16. + - "make install" now uses the install command (or the + included install-sh script) to copy files to the + install directories, to ensure that permissions are + correct. + - Fixed DLL generation via MingW/Cygwin (STR #1546) + - FLUID incorrectly opened the display when generating + source code for Fl_Help_View widgets (STR #1318) + - Fl_Double_Window did not always show the scheme + background image. + - Fixed first window behavior in OS X (STR #1548) + - Fixed calculation of character widths for OS X + Quartz rendering (no STR) + - Fixed OS X mouse click handling (STR #1504) + - Added missing GLUT functions so that FLTK can be used + as a fairly complete C++ replacement for the original + GLUT library (STR #1522) + - Fl::awake() could block on X11 and OSX (STR #1537) + - Updated recursive mutex code to run on platforms other + than Linux and to do a run-time check to determine + whether they are supported by the kernel (STR #1575) + - WIN32 did check callbacks after the event processing instead of + before as documented (STR #1535) + - Fl_File_Chooser now hides the window before doing a callback + when the user clicks on the OK button (STR #1565) + - Fixed indentation of nested HTML elements (STR #1549) + - Made layout of Fl_Help_Dialog consistent with other + help windows and web browsers. + - Improved GTK+ schemed round box (STR #1531) + - Fluid avoids writing unsupported combinations of the + "when()" flags (STR #1501) + - Fl_Browser_ would allow keyboard callbacks even though + "when()" was set to "never" (STR #1501) + - Added automated little helpers to Sudoku + - Added example code for Wizard with the + Tabs demo (STR #1564) + - Optimized Fl_Tabs drawing for speed (STR #1520) + - OS X resource fork now obsolete (STR #1453) + - Added chapter 10 about multithreading (STR #1532, + 1533) + - OS X system menu bar top level attribute support + improved (STR #1505) + - Fixed Quartz image drawing bug (STR #1438) + - Fixed Quartz fl_read_image + - Overlay drawing is now avoiding XOR mode (STR #1438) + - Fixed Scroll crash in Fluid Live Mode (STR #1524) + - Fixed mousewheel event propagation (STR #1521) + - Fixed drawing issues of a tile in a scroll (STR #1507) + - Fixed dismissing buttons in menu bars (STR #1494) + - Making a child group visible in a Fl_Tabs or Fl_Wizard + group now shows that tab or pane. + - Added fl_open_uri() function as proposed on + fltk.development. + - Added Fl::has_check() which previously was prototyped + and documented, but not implemented (STR #1542) + - Enabled Fl::add_check() on OS X (STR #1534) + - Documented tooltip inheritance (STR #1467) + - Better event mouse handling fixing detached menus and + sticky tooltips (STR #1463, STR #449) + - Added Fl::scrollbar_size() methods that are used by all + of the scrollbar-using widgets (STR #1500) + - fl_read_image() was broken on Intel-based Macs (STR + #1490) + - Fl_Progress was using the wrong width to calculate + progress (STR #1492) + - Fl::x(), Fl::y(), Fl::w(), and Fl::h() did not report + the desktop work area on X11 (STR #1482) + - Shortcut events could be sent to the wrong window (STR + #1451) + - Fl_Spinner did not handle the arrow keys properly (STR + #1476) + - Fl_File_Browser did not calculate the width of + directory items correctly (STR #1469, STR #1470) + - Fl_Pack incorrectly started widgets at an offset of 1/2 + the spacing value. + - FLUID did not generate correct window class code if + the class name was not a standard FLTK window class. + - FLUID incorrectly included for + widget classes that were not subclassed from a standard + FLTK widget class. + - The demo master test program now supports scheme + selection and all demos use it (STR #1459) + - fl_arc() and fl_pie() did not draw properly on WIN32 + when the start and end points were identical (STR + #1461) + - Fl_Input and Fl_Text_Editor now hide the mouse pointer + when typing into them (STR #1466) + - Implemented alpha blending for Quartz, WIN32, and X11 + - Check buttons did not redraw properly with box() set to + FL_NO_BOX (STR #1440) + - Added the Bluecurve-inspired scheme "gtk+". + - Updated documentation (STR #1420, STR #1421) + - Fixed font caching issue (STR #1415) + - Fixed crash in fl_file_chooser (STR #1410) + - Fixed Fluid hotspot bug (STR #1416) + - Fixed image copy code (STR #1412) + - Fixed latin-to-roman text conversion (STR #1411) + - Fixed Cygwin timeout for "select" calls (STR #1151) + - Improved Mac OS X subwindow handling (STR #1402) + - Fixed more inconsistencies between fl_draw and + fl_measure (STR #1408) + - Fixed fl_measure which mistook a trailing '@@' for a + symbol (STR #1406) + - Fixed GLUT behavior on window creation (STR #1403) + - Fixed OS X bug that would hide tooltips before they + were shown (STR #1392) + - Fixed Fl_Tabs tooltip reappearing (STR #1324) + - Added a new demo game called "Block Attack!" + - Updated the Sudoku game to show a notice about Hard and + Impossible puzzles having multiple solutions which are + not a bug or error (STR #1361) + - Fixed filechooser to behave as documented when file + pattern changes (STR #1359) + - Completed the global function index and added an + alphabetical list of all methods (STR #1319) + - Avoiding problems with some platforms that don't + implement hypot() (STR #1366) + - Fixed floating point value formatting for Fl_Spinner + (STR #1331) + - Fixed Fl_Positioner callback when released (STR #1387) + - Fixed WIN32 zero size window issue (STR #1387) + - Fixed Sudoku window positioning (STR #1398) + - Fluid Code Declarations can now handle C++ style + comments (STR #1383) + - Fixed uninitialized data in OS X and WIN32 timeout + functions (STR #1374). + - Fixed speed issues when measuring text on OS X with + Quartz (STR #1386). + - Fixed focus issues on OS X (STR #1377) + - Optional precision argument when storing floats or + doubles in a Preferences file (STR #1381) + - Fixed callback not called when using arrow keys in + Fl_Slider (STR #1333) + - Changing the shortcut of a widget in fluid now marks the + document as dirty (STR #1382) + - Fl_Text_Editor now correctly handles middle mouse + clicks (STR #1384) + - Added some GLUT4 functions (STR #1370) + - Added "context_changed()" function for OpenGL windows + which allows efficient texture loading (STR #1372) + - Added missing "const" to GLUT call (STR #1371) + - Fixed stray FL_RELEASE events after clicking system + areas on OS X (STR #1376) + - FLUID now only writes definitions of "o" and "w" + variables as needed, reducing the number of "variable + is shadowed" warnings from GCC. + - Added access to Xft font pointer (STR #1328) + - Fixed endianness in OS X mouse cursor graphics (STR + #1348) + - Fixed crash on mixed use of keyboard and mouse for + Fl_Menu_Button (STR #1356) + - Fixed Fl_Window::visible() and shown() for OS X + (STR #1341) + - Fixed Fl_Window::copy_label() losing copy (STR #1332) + - Documentation fixes (STR #1336, STR #1329, STR #1339, + STR #1340) + - Added support for floating point Fl_Spinner in the + API, documentation, and Fluid (STR #1331) + - Repeat button now cancels timeout if it should get + deactivated during a callback (STR #1330) + - Added support for assigning Fl_Menu_Items to array + variables in Fluid (STR #1280) + - Added --with-archflags configure option to allow + passing of specific architecture-selection options to + the compiler and linker. + - Fixed WIN32 window stacking bug (STR #1296) + - Fixed wrong code generated by FLUID for Scrollbars (STR + #1287) + - Loading a file would not update the Widget Properties + dialog in FLUID (STR #1326) + - Fixed key compose sequences for shifted keys (STR + #1194) + - Added text selection and copy to Fl_Help_View. + - Fixed position of popup menu titles (STR #1322) + - Showing any window will disable the current tooltip + so it won't pop over menus (STR #1321) + - Updated documentation to reflect limitation of + Fl::delete_widget() (STR #1306) + - Fixed line wrapping in Fl_Text_Display (STR #1227) + - New function Fl::event_original_key() returns key code + before NumLock handling. + - Many OS X Quartz fixes (STR #1310, etc.) + - Fixed shortcut and default focus for message dialogs + (STR #1298) + - Fixed focus issues (STR #1286, STR #1289, STR #1296) + - Fixed window resizing in OS X (STR #1297) + - In FLUID, declarations starting with the keyword + 'typedef', 'class', or 'struct' are now treated + correctly if inside a class (STR #1283) + - Tabs now show the correct tooltip (STR #1282) + - Included fltk.spec in configure.in (STR #1274) + - Fixed insufficiently invalidated cache + in Fl_Browser (STR #1265) + - Attempt to fix multi monitor issues (STR #1153) + - Fixed warnings when compiling w/Cygwin (STR #1152) + - Fixed missing reset of flag in FLUID (STR #1187) + - Fixed maximizing in OS X (STR #1221) + - Fixed 'make distclean' to remove binaries inside + MacOS app packages (STR #1169) + - FLUID Code Viewer is now truly a viewer, not a text + editor because edited text can not be saved. + - Fl_Spinner is now fully supported by FLUID (STR #1158) + - Fixed usage of deleted object after menu pulldown + (STR #1162) + - Calling fl_font(0, 0) under Xft would access a NULL + pointer (STR #1205) + - Setting a new value in Fl_Input_ wil now actually move + cursor to the end of the input field as documented + (STR #1161) + - FLUID crashed on WIN32 with international characters + (STR #1176) + - Fl_Check_Browser did not allow the user to toggle the + check boxes (STR #1232) + - Fl_Help_View crashed on WIN32 with international + characters (STR #1228) + - Fl::run() no longer clears resources on WIN32 (STR + #1231) + - Fl::add_timeout() leaked resources on OSX (STR #1233) + - Accented characters could not be entered on OSX (STR + #1195) + - The caret key lookup was missing for OS X + - FLUID didn't handle loading .fl files with + international characters properly with all compilers + (STR #1150) + - Fl_Spinner's minimum() and maximum() "get" methods were + misspelled (STR #1146) + - The largefile support changes in 1.1.7 broke binary + compability for fl_filename_list(); you must now use + "--enable-largefile" when configuring to get large file + support, and the large file support definitions are + added to the output of "fltk-config --cflags" (STR + #1159) + + +CHANGES IN FLTK 1.1.7 + + - Documentation fixes (STR #571, STR #648, STR #692, STR + #730, STR #744, STR #745, STR #931, STR #942, STR #960, + STR #969) + - Various menu widget fixes (STR #1140, STR #1143, STR + #1144) + - The threads demo would display negative prime numbers + on MacOS X; this appears to be a MacOS X bug, but we + added a workaround to "fix" this (STR #1138) + - Fl::dnd() now sets the content type of the drag to + "text/uri-list" when it sees the dragged text is + composed of URIs. + - Fixed keyboard shortcut handling in FLUID and shortcut + labeling in FLTK (STR #1129) + - Fixed include path for CMake build (STR #1123) + - Fixed unnecessary delay in WIN32 event handling + (STR #1104) + - Fixed handling of Ctrl-C in Fl_Text_Display (STR #1122) + - OS X Quartz version now draw a nice resize control (STR + #1099) + - FLTK now enables large file support when available (STR + #1087) + - Fl_Clock_Output depended on a time value that was the + same as an unsigned long, which is incorrect for WIN64 + and VC++ 2005 (STR #1079) + - Fl_Text_Display::wrap_mode() would crash if no buffer + was associated with the widget (STR #1069) + - Updated the default label and text colors of all widgets + to use FL_FOREGROUND_COLOR instead of FL_BLACK (STR + #1052) + - Fl::set_fonts() now works with Xft (STR #1012) + - Fl_Value_Input now uses the screen-absolute position + instead of the window-relative position when dragging + the value; this avoids some jumping conditions (STR + #1037) + - Menus now pop up fully inside the screen if possible + (STR #973) + - Fixed illegal access in Preferences (STR #1025) + - Fixed x-offset problem in Help_Widget (STR #998) + - Clipboard will persist if owner window is hidden (STR + #1019) + - Fixed handling of Win32 Device Contexts (STR #1007) + - Fixed C++ style comments in C files (STR #997) + - Fixed signedness of scanf() argument (STR #996) + - Fixed cross-compiling problem (STR #995). + - FLUID now knows if a static callback is already + declared in a class and won't declare it 'extern' (STR + #776) + - Some actions in FLUID would not set the "changed" flag + (STR #984, STR #999) + - fl_filename_list now always appends a forward slash to + directory names (STR #874) + - Multiline Input will update right if a space character is + inserted in word wrap mode (STR #981) + - FLUID group labels redraw correctly (STR #959) + - FLUID now updates color of Fl_Tabs children (STR #979) + - FLUID now supports 'size_range()' (STR #851) + - FLUID selection boxes now synchronised (STR #964) + - fl_filename_list() now recognizes pathnames without + trailing slash as directions (STR #854) + - Fl_Text_Display now auto-scrolls in all + directions (STR #915) + - Borderless windows will not show in the taskbar anymore + on X11 (STR #933) + - Fixed event_text() field on FL_DND_* event on + OS X and WIN32 (STR #968) + - The fltk-config utility now supports "--cc" and "--cxx" + options to get the C and C++ compilers that were used + to compile FLTK (STR #868) + - Fl_Valuator-derived widgets could show more digits than + were necessary (STR #971) + - Fl_GIF_Image did not handle images with an incorrect + number of data bits (STR #914) + - Fixed some plastic drawing artifacts (STR #906) + - Fl_Help_View now draws the box outside the scrollbars, + like the other scrollable widgets (STR #871) + - The fltk-config script now handles invocation via a + symlink (STR #869) + - Updated WIN32 cut/paste code to consistently handle DOS + text (STR #961) + - Added shared library support for Cygwin and MingW (STR + #893) + - Fl_File_Chooser did not implement the user_data() + methods (STR #970) + - Compilation could fail if a previous installation of + FLTK was in the same (non-standard) directory as an + image library (STR #926) + - Fixed OSX compilation problems with non-HFS filesystems + (STR #972) + - Problems with CMake on MinGW have been solved, thanks + to Mr. "fltk.x0", who submitted the patch. (STR #863) + - Fixed memory leak in Fl_Check_Browser reported by + "miguel2i". (STR #967) + - Fl_File_Input could draw in the wrong window (STR #958) + - WIN32: Internal WM_PAINT message now ignored (STR #831) + - Added Windows support for Fl_Window::xclass() (STR #848) + - Floating point input field allows characters from + current locale (STR #903) + - Fixed integration of Fl_Input_Choice into FLUID (STR + #879) + - New windows touching the right screen border would be + positioned all the way to the left (STR #898) + - Made pie drawing size for WIN32 and OS X the same as + X11 (STR #905) + - Fixed OS X issue with OpenGL windows inside of Tabs + (STR #602) + - FLUID Code Editor would occasionally not draw the last + character in the buffer (STR #798) + - FLUID Declaration private flag fixed (STR #799) + - FLUID overlay now shows a seperate bounding box of + selected items with correct handles and a dotted + boundig box for all labels (STR #790) + - Fixed left overhang of large chracters in Fl_Input_ + (STR #941) + - Fixed button resizing in File Chooser (STR #884) + - Fixed FLUID redraw issue (STR #912) + - Added 32bit BMP Image file format support (STR #918) + - Value Sliders would not receive focus when clicked on + (STR #911) + - Added redraw of some widgets to show focus change (STR + #910) + - Fl::set_font would not clear 'pretty' name (STR #902) + - Fixed unescaped '@' in fonts demo (STR #867) + - FLUID should not open the Display connection anymore if + creating code only (STR #904) + - Improved hidden copy / ctor implementation (STR #860) + - Increased matrix stack depth and added over/underflow + error (STR #924) + - Reverted Mac Carbon Clipping simplification that broke + subwindow clipping (STR #908, SVN r4386) + - Fixed bitmap scaling code + - Fixed tiny memory leak (STR #878) + - Fixed hang on corrupt jpeg (STR #915) + - Fixed static allocation of font buffer in demo (STR #909) + - Added symbols 'refresh', 'reload', 'undo', and 'redo'. + - Fixed focus loss on Fl_Window:resize() + - Fl::delete_widget would hang fl_wait after deleting the + window (STR #679) + - Fl::paste would sometimes not recoginze external + changes of the clipboard (STR #722) + - Clipping fixes for OSX + - Removed attempt to find items via + Fl_Menu_::find_item() in linked submenus + - FLUID interactive window resizing fixes (STR #873, 791) + - FLUID panel resize and alignment fixes (STR #891) + - Fl_Window::show(argc, argv) now sets the scheme before + showing the window; this should eliminate any + flickering between the standard and plastic schemes on + startup (STR #886) + - Selected tabs are now drawn slightly larger than + unselected tabs so they stand out more (STR #882) + - Round Plastic boxes now draw round (STR #841) + - FL_PLASTIC_DOWN_BOX drew with artifacts (STR #852) + - Changed initializations on WIN32 (STR #862) + - Fl_Preferences::getUserdataPath() didn't work for + sub-groups (STR #872) + - Fixed some redraw issues on Windows XP. + - FLUID didn't set the initial size of widgets properly + (STR #850) + - Fl_Tabs would steal focus away from its children on a + window focus change (STR #870) + - filename_relative() now converts the current directory + to forward slashes as needed on WIN32 (STR #816) + - Fl_File_Chooser::value() and ::directory() now handle + paths with backslashes on WIN32 (STR #811) + - Added the standard rgb.txt file from X11 to the test + directory, allowing all platforms to try the colbrowser + demo (STR #843) + - Resizing of OpenGL subwindows was broken on OSX (STR #804) + - The fltk-config script now supports running from a + source directory (STR #840) + - Fl_Browser_ didn't update the position properly when an + item was deleted (STR #839) + - fl_contrast() now compares the luminosity of each color + (STR #837) + - Fl_Input_ crashed on some platforms when wrapping + international text characters (STR #836) + - Fixed some BMP images loading bugs (STR #825) + - Fl_File_Chooser now returns directory names with a + trailing slash to avoid problems with relative + filenames (STR #819) + - Fl_Help_View now supports the FONT and U elements (STR + #815) + - OpenGL windows that were completely off-screen caused + problems with some graphics cards on WIN32 (STR #831) + - Multiple screen support didn't work on Windows NT and + 95 (STR #821) + - Fl_Scrollbar didn't compute the correct knob size when + using the "nice" types (STR #845) + - fl_draw() would segfault on WIN32 if no font was set; + it now uses the default font (STR #828) + - Fl_Browser_ was calling the callback multiple times for + a single selection change with FL_WHEN_CHANGED (STR + #834) + - Added "filenew", "fileopen", "filesave", "filesaveas", + and "fileprint" symbols with standard toolbar + symbology. + - Updated Fl_Tabs to check the contrast of the label + color against the tab background, and to highlight the + top 5 lines of the tab pane with the selection color so + that selected tabs stand out more. + - The example programs can now compile separate from the + FLTK source distribution (STR #809) + - The example programs are now installed with the + documentation (STR #809) + - Fixed the drawing of the Fl_Browser_ selection box (STR + #786) + - Dropped Codewarrier project files and support. + - The FLTK string functions are now compiled in on all + systems (STR #774) + - Fixed symbol demo label bug (STR #777) + - Fixed position of menu titles (STR #795) + - Added missing Fl_Window::copy_label() method. + - Fixed wrong tooltip in FLUID (STR #784) + - Added zlib path to FLUID (STR #783) + - Menus and other pop-up windows now obey screen + boundaries on multi-screen displays (STR #781) + - Fl_Chart would draw outside its bounding box (STR #780) + - Added Fl::screen_count() and Fl::screen_xywh() APIs to + support multi-screen displays. + - FLUID now supports direct creation of widget classes. + - Fl_File_Chooser now correctly handles multiple + selections that are a mix of files and directories. + - Fl_File_Chooser no longer resets the type() when + choosing a single file, and it now works when selecting + multiple directories (STR #747) + - Fl_File_Icon::load_system_icons() now only loads 16x16 + and 32x32 icon images to improve startup performance. + - Pressing Enter in the file chooser when selecting a + directory will choose that directory if it is currently + shown (STR #746) + - Added a fl_file_chooser_ok_label() function to set the + "OK" button label for the fl_file_chooser() and + fl_dir_chooser() functions. + - Added Fl_File_Chooser::ok_label() methods to set the + "OK" button label. + - The fl_ask() function is now deprecated since it does + not conform to the FLTK Human Interface Guidelines. + - The Fl_File_Chooser window now properly resizes its + controls (STR #766) + - The Fl_Help_Dialog window now properly resizes its + controls (STR #768) + - The Fl_File_Chooser favorites window is now resizable + (STR #770) + - Now provide FL_PLASTIC_ROUND_UP/DOWN_BOX box types + which are used by the plastic scheme. + - FLUID windows that are resized through the widget panel + now remain resizable by the window manager. + - Increased the size of the background image used by + the plastic scheme to reduce the CPU load of redraws + (STR #769) + - Fixed a syntax highlighting bug in the editor demo. + - Fl_Progress now contrasts the label color with the bar + color, so labels will be readable at all times. + - fl_read_image() didn't use the right red, green, and + blue masks on XFree86. + - Fixed Quickdraw drawing of 3 and 4 sided polygons (STR + #765) + - Fixed fl_message() code so that it does not get + accidentaly addded to the current group (STR #253) + - FLUID now highlights code in the widget callback and + code editors. + - FLUID now supports printing of windows. + - Fixed inactive drawing of border, embossed, and + engraved box types. + - Added Fl_Spinner widget (another combination of + existing widgets in a header file) + - FLUID now provides support for UI templates. + - fl_not_clipped() incorrectly used the current window + dimensions for gross clipping, which interfered with + off-screen rendering. + - Fl_Window::draw() and Fl_Window::iconlabel() could leak + memory if copy_label() was used on the window. + - fl_shortcut_label() now shows letter shortcuts in + uppercase, e.g. "Ctrl+N" instead of "Ctrl+n" to be + consistent with other toolkits. + - FLUID now provides unlimited undo/redo support. + - FLUID now provides an option to choose which scheme + (default, none, plastic) to display. + - Fixed scheme background issue with windows in FLUID. + - In FLUID, new widgets are now created with the ideal + size by default, and menu bars are positioned to use + the entire width of the window. + - Added Layout/Widget Size submenu to select default + label and text size (Tiny, Small, and Normal). + - Added Edit/Duplicate command to FLUID to duplicate the + current selection. + - FLUID now tracks the current state of the widget bin + and overlays. + - Now fill the widget image paths with relative + filenames. + - Fixed frame drawing of Fl_Text_Display (STR #762) + - Fl_Clock_Output::value() did not return the previously + set value (STR #748) + - Added comment type to FLUID. This is useful for + generating copyright notices in the source and header + files. + - Fl_Valuator would not format text output with decimal + point when the step value was fractional, but above 1. + - fl_filename_relative() didn't compare drive letters in + a case-insensitive way (STR #741) + - Fixed menu item width calculations with symbols (STR + #740) + - The keyboard shortcut handling code did not handle + 8-bit characters properly (STR #731) + - Fl_JPEG_Image could still crash an app with a corrupt + JPEG file (STR #739) + - Using the layout alignment controls on a menu widget + would cause FLUID to crash (STR #742) + - Added QNX bug workaround for menu handling (STR #704) + - Added Greg Ercolano's simple Fl_Input_Choice widget + which is a combination of the Fl_Input and + Fl_Menu_Button widgets (STR #650) + - Fl_Multiline_Input now scrolls the full height of the + widget instead of 5 lines when the user presses PageUp + or PageDown (STR #727) + - CMake build fixes (STR #724) + - Fl_Browser::swap() didn't handle redraws properly when + the swapped lines had different heights (STR #729) + - FL_MOUSEWHEEL events are now sent first to the widget + under the mouse pointer and then to the first widget + which accepts them. This is similar to the way + shortcut events are handled and is consistent with the + way the mouse wheel is handled by other toolkits. + - Fl::wait() could block on WIN32 if the window was + deleted via Fl::delete_widget() (STR #679) + - Fl_Preferences::RootNode did not find the user's home + directory on some non-US versions of Windows (STR + #720) + - Fl_Window::hide() didn't delete the current clipping + region on WIN32, causing a GDI resource leak in some + situations (STR #723) + - Removed a few warnings when compiling on OS X + - Fl_Menu now draws the arrow more like other toolkits + and 2.0 (STR #651) + - Fixed a VC++ compiler error in Fl_JPEG_Image.cxx (STR + #676) + - FL_SHADOW_BOX/FRAME drew outside of the bounding box + (STR #694) + - Fl_Widget::copy_label(NULL) didn't work (STR #707) + - Fl_Choice now allows click selection like + Fl_Menu_Button and Fl_Menubar (STR #706) + - Updated cmake support (STR #645) + - Fl_Check_Browser didn't draw properly when inactive + (STR #681) + - Removed some redundant code in Fl_Group::handle() (STR + #669) + - The file chooser didn't always deactivate the OK + button when necessary (STR #653) + - Image drawing on OSX changed the current drawing + colors (STR #662) + - Fixed some compiler errors on WIN32 (STR #647, STR + #726) + - FLUID didn't update the widget panel X/Y/W/H values + when moving the selected window (STR #701) + - FLUID didn't use the label type constant names for + menu items, causing them to be drawn using the normal + label type (STR #668) + - Fl_File_Chooser was slow with large directories (STR + #654) + - FLUID didn't add xclass() calls to windows (STR #718) + - The X11 DND code did not correctly select a text + format for incoming data (STR #711) + - Fixes to Fl_JPEG_Image error handler. + - Fl_Menu::popup() and ::pulldown() would crash an + application if a callback created widgets before they + returned (STR #685) + - Fl_Double_Window would cause a full redraw, even if + only small parts of the UI were changed on Mac OS X. + - Fl_JPEG_Image did not correctly handle errors reported + by the JPEG library (STR #652) + - Fl_Menu now draws sub-menu arrows like other toolkits + and FLTK 2.0 (STR #651) + - Fixed a compiler warning in Fl_Window.H (STR #641) + - Tooltips disabled shortcut processing (STR #643) + - Fl::event_number() didn't always match the value sent + to the handle() method (STR #634) + - Fl_Shared_Image::reload() didn't set the image_ + pointer properly in all cases (STR #632) + - Fl_Help_View::topline() incorrectly set the changed() + flag (STR #631) + - Fl_Choice::value() now supports NULL or -1 to deselect + the current item (STR #637) + - More VC++ 6 project file fixes (STR #638) + - Added missing Watcom makefile in the test directory + (STR #636) + - Fl_Text_Display::word_left would hang if the cursor + was at position 0 (STR #635) + + +CHANGES IN FLTK 1.1.6 + + - Documentation updates (STR #552, STR #608) + - Added the 2.0 Fl_Widget::copy_label() method to + allow FLTK 1.x applications to have their label + strings managed by FLTK (STR #630) + - Added Fl::delete_widget() method to safely delete + widgets in callback methods (STR #629) + - Fl_Widget::damage(uchar,int,int,int,int) didn't clip + the bounding box properly (STR #626) + - Windows could appear on the wrong screen on OSX (STR + #628) + - Fl_Double_Window produced an error on resize with X11 + - FLUID didn't display menu items using images properly + (STR #564) + - Fl_Sys_Menu_Bar didn't compile on case-sensitive + file-systems (STR #622) + - FLUID didn't handle default function parameters + properly (STR #579) + - Moving or resizing widgets in FLUID didn't always + update the widget panel (STR #600) + - FLTK windows could appear off-screen on X11 (STR #586) + - The configure script did not support + --disable-localfoo to completely disable image file + support (STR #582) + - The Visual C++ 6.0 project files still listed the old + JPEG, PNG, and ZLIB library names (STR #577) + - Fixed the scandir() conditional code for HP-UX 11i + (STR #585) + - Fl_Text_Display didn't support CTRL/CMD-A/C (STR #601) + - Watcom fixes (STR #581, STR #584, STR #594, STR #595, + STR #623, STR #627) + - Fixed library include order when building DSOs on + MacOS X (STR #596) + - fl_xid() could cause a WIN32 application to crash (STR + #560, STR #576, STR #618) + - Fl_Browser::remove_() removed the item from the list + before computing the item height, which caused + problems with some programs (STR #613) + + +CHANGES IN FLTK 1.1.5 + + - Documentation updates (STR #568, STR #570) + - Shortcuts were incorrectly underlined in multi-line + labels (STR #566) + - More CMake updates (STR #499) + - The Watcom C++ compiler needed a small change (STR + #567) + - Added DESTDIR support and now remove all man pages for + the "uninstall" target (STR #545) + - Fix PNG drawing on buggy WIN32 graphics cards (STR + #548) + - The configure script didn't propagate the CPPFLAGS + environment variable (STR #549) + - The numpad keys didn't work properly on WIN32 (STR + #502) + - fl_input() and friends now set the input focus to the + text field when the dialog is shown (STR #553) + - Fixed background color mixup when drawing Fl_Choice + menus (STR #544) + - Fixed MingW makefiles (STR #550) + - More VC++ project file tweaking (STR #559) + - Fl_PNG_Image didn't use the png_set_trns_to_alpha + function when available (STR #547) + - The FL_UNFOCUS event wasn't always sent when switching + tabs (STR #558) + + +CHANGES IN FLTK 1.1.5rc3 + + - Documentation updates (STR #505, STR #513) + - Updated PNG library source to 1.2.7. + - Updated ZLIB library source to 1.2.1. + - Fixed VC++ project file problems (STR #476, STR #478, + STR #520, STR #527, STR #537) + - Now look for 8 bits of alpha when the developer has + requested FL_RGB8 (STR #541) + - The last line in an Fl_Help_View widget was not + aligned properly (STR #536) + - The "search" symbol looked like a Q (STR #536) + - Changed Fl_Help_View::get_color() to use a lookup + table to avoid serious Borland C++ 5.5 compiler bugs + (STR #533) + - Fixed Watcom compiler warnings with FL/Fl_Widget.H + (STR #540) + - The image class copy() methods did not always make a + separate copy of the image data (STR #539) + - Fixed an edge case in fl_old_shortcut() that could + cause it to read beyond then end of the shortcut + string (used for XForms named shortcuts) + - Added (unsupported) CMake files (STR #499) + - Tooltips would not reappear on the same widget, and + the initial tooltip delay was not used after a tooltip + was shown (STR #465) + - Fixed a compile problem with the Linux 2.6 threading + support (STR #483) + - Fixed problems with 2-byte Xpm files on 64-bit + platforms (STR #525) + - FLTK didn't handle the ReparentNotify event on X11 + (STR #524) + - The old source file "fl_set_gray.cxx" is not needed + (STR #516) + - Fl_Text_Display still called delete[] instead of + free() in one place (STR #503) + - The symbol test program did not handle the @+ symbol + properly (STR #490) + - Fl_File_Chooser didn't correctly call isprint() and + isspace() when checking to see if the current file was + text that can be previewed (STR #517) + - FLUID didn't compile with Borland C++ due to a + compiler bug (STR #496) + - Fl_Positioner did not handle reversed min and max + values (STR #510) + - fl_descent(), fl_height(), and fl_width() would crash + a program if you didn't call fl_font() first; they now + return -1 if no font is set (STR #500) + - Added test/unittests to verify pixel drawing and + alignment across platforms + - Fl_Menu_::find_item() didn't determine the menu path + properly (STR #481) + - The build system now installs image library header + files in FL/images/filename.h so that FLTK programs + will use the same header files as the FLTK image + libraries. + - The build system now creates image libraries named + "libfltk_name.a" instead of "libname.a" to avoid + clobbering an existing installed library (STR #480) + + +CHANGES IN FLTK 1.1.5rc2 + + - Documentation updates (STR #365, STR #399, STR #407, + STR #412, STR #414, STR #452, STR #462) + - Fl_Text_Display did not handle drawing of overlapping + text (italic next to plain, etc.) properly (STR #381) + - All of the core widgets now consistently set changed() + before calling the callback function for a change in + value; this allows programs to check the changed() + state in a callback to see why they are being called + (STR #475) + - Fl_File_Chooser did not handle some cases for filename + completion (STR #376) + - Fl_Help_View didn't properly compute the default + maximum width of the page properly, resulting in + non-wrapped text in table cells (STR #464) + - Fl_Text_Editor no longer tries to emulate the Emacs + CTRL-A shortcut to move to the first column, since + there is a key for that and the widget does not + emulate any other Emacs keys (STR #421) + - Fl_File_Chooser always disabled the OK button when the + user pressed DELETE or BACKSPACE (STR #397) + - Added Fl_Browser::swap() methods (STR #459) + - Fl_Counter didn't use a thin down box for the text + field if the box type was set to FL_THIN_UP_BOX (STR + #467) + - Fl_Help_View now resets the scrollbars if they go + outside the current view (STR #464) + - fl_dir_chooser() did not show the previous selection + as documented (STR #443) + - Fl_Text_Display used delete[] instead of free() in + some places (STR #466) + - FLTK now includes copies of the PNG, JPEG, and ZLIB + libraries for platforms that do not have them (STR + #441) + - The fltk-config script did not include the + "-mno-cygwin" option under CygWin (STR #434) + - Fl_Help_View::find() did not check for a NULL value + (STR #442) + - Added search symbol to the search field of + Fl_Help_Dialog (STR #417) + - Added two new symbols, @search and @FLTK, which can be + used in labels. + - MacOS X: fixed NumLock mixup, added support for + FL_Menu and FL_Delete keys on external (PC) keyboards + (STR #445) + - Fl_File_Icon::draw() did not support drawing of complex + polygons in icon descriptions (STR #474) + - The configure script now offers options for JPEG, PNG, + and ZLIB libraries (STR #416) + - The first menu item in a list would not go invisible + (STR #406) + - Fl_Text_Buffer::replace() now range checks its input + (STR #385) + - FLTK now builds with the current release of MinGW (STR + #325, STR #401, STR #402) + - FLTK now honors the numlock key state (STR #369) + - The Fl_Text_Display widget did not redraw selections + when focus changed (STR #390) + - The plastic background image is now less contrasty + (STR #394) + - Fl_Scroll now uses a full redraw when the scheme is + set to plastic and the box type is a frame (STR #205) + - Fl_Window::resize() did not work properly with KDE 3.2 + (STR #356) + - FLTK didn't delete font bitmaps when the last OpenGL + window was deleted, preventing future text from + displaying (STR #310) + - FLUID didn't include a full initialization record for + the trailing NULL menu items (STR #375) + - Fl_Browser::item_width() did not properly handle + format modifiers (STR #372) + - Fl_Browser::item_height() did not handle columns + properly (STR #371) + - Fl_Gl_Window's on WIN32 now prefer accelerated pixel + formats over generic formats (STR #382) + - Fl_Window::resize() did not work on some systems if + the window was not shown (STR #373) + - FLUID did not write the user_data type if the + user_data field was empty (STR #374) + - The value(const Fl_Menu_Item*) method was not + implemented for Fl_Choice (STR #366) + - Fl_Pack didn't draw child widget labels the same way + as Fl_Group, causing display problems (STR #360) + - fl_read_image() didn't work when reading from an + offscreen buffer with some X11 servers (STR #364) + + +CHANGES IN FLTK 1.1.5rc1 + + - Documentation updates (STR #186, STR #245, STR #250, + STR #277, STR #281, STR #328, STR #338) + - fl_scroll() did not handle scrolling from off-screen on + WIN32 (STR #315) + - Fl_File_Chooser did not allow manual entry of a drive + letter (STR #339) + - Fl_Menu now uses the boxtype to redraw the menu + background (STR #204) + - Fl_Scroll now shows the background image when a framed + box type is used and the Fl_Scroll is a direct + decendent of a window (STR #205) + - Added a new_directory_tooltip string pointer to allow + localization of the file chooser's new directory + button (STR #340) + - Added Fl_Menu_::find_item() method (STR #316) + - The Fl_Widget copy operator definitions were not + conditionally compiled properly (STR #329) + - FLUID's Layout functionality did not move child + widgets when laying out group widgets (STR #319) + - FLUID's Layout->Center In Group functionality did not + properly handle widgets that were children of a + Fl_Window widget (STR #318) + - The Fl_Text_Display destructor did not remove the + predelete callback associated with the current buffer + (STR #332) + - Fixed several bugs in the MacOS X Fl::add_fd() + handling (STR #333, STR #337) + - The Fl_Text_Display widget did not display selections + set by the application (STR #322) + - FLUID crashed if you did layout with a window widget + (STR #317) + - Fl_Scroll::clear() didn't remove the child widget from + the Fl_Scroll widget (STR #327) + - Fl_Value_Slider::draw_bg() didn't always apply the + clipping rectangle (STR #235) + - fl_filename_relative() returned the wrong string if + the absolute pathname was equal to the current working + directory (STR #224) + - Fl_Help_Dialog didn't correctly restore the scroll + position when going forward/back in the link history + if the file changed (STR #218) + - glutGetModifiers() did not mask off extra state bits, + confusing some GLUT-based applications (STR #213) + - Fixed mouse capture problems on MacOS X (STR #209, STR + #229) + - Fl_Sys_Menu_Bar is now built into the library for + MacOS X (STR #229) + - Fl_Menu_ now provides item_pathname() methods to get + the "pathname" of a menu item, e.g. "File/Quit" (STR + #283) + - Fl_Text_Display now provides cursor_color() methods to + get and set the cursor color (STR #271) + - Fl_Scroll didn't honor FL_NO_BOX (STR #305) + - FLUID declaration blocks didn't support public/private + definitions (STR #301) + - Fl_Preferences incorrectly created the preferences + directory before necessary (STR #247) + - The WIN32 project files still defined the (obsolete) + FL_STATIC constant (STR #279) + - Fl_Text_Display::buffer() did not support NULL values, + making it impossible to clean up text buffers from a + subclass (STR #295) + - Fl_Text_Display did not support a NULL + unfinishedStyleCB function (STR #241) + - Fl::background2() incorrectly marked the foreground + color as initialized (STR #255) + - Fixed the X11 CTRL + "-" detection code to properly + track the state of the CTRL key (STR #264) + - Fl_File_Icon::load_system_icons() didn't support KDE + 3.x (STR #299) + - WIN32's scandir() emulation did not allocate enough + memory for directory names (STR #263) + - Fl::compose() did not handle special keys like + backspace properly (STR #293) + - Fl_Choice did not clip its text when drawing using the + plastic scheme (STR #287) + - Fl_Group incorrectly mapped the emacs CTRL keys to + keyboard navigation (STR #228) + - Fl_File_Browser::load() didn't handle a NULL directory + name (STR #266) + - 64-bit library fixes (STR #261) + - The Fl_Valuator::format() function did not limit the + size of the number buffer (STR #268) + - The keypad Enter key works as the normal Enter/Return + key in common widgets (STR #191) + - Fixed some OS/2-specific build problems (STR #185, STR + #197) + - Calling Fl_Text_Display::buffer() with the same buffer + would cause an application to lockup (STR #196) + - Some of the widgets could crash an application if the + cursor was changed after a window was deleted (STR + #181) + - The Fl_Gl_Window WIN32 pixel format code did not + choose the pixel format with the largest depth buffer + (STR #175) + - The configure script didn't leave space between the + CFLAGS/CXXFLAGS and X_CFLAGS variables (STR #174) + - The Fl_JPEG_Image and Fl_PNG_Image classes did not + trap errors from the corresponding image libraries + (STR #168) + - Added "--with-links" configure option to control + whether symlinks are created for the FLTK header files + (STR #164) + - Added new hoverdelay() to Fl_Tooltip to control how + quickly recent tooltips appear (STR #126) + - FLUID now sets the size range when a window is shown. + This seems to be necessary with some window managers + (STR #166) + + +CHANGES IN FLTK 1.1.4 + + - The fl_read_image() function was not implemented on + OSX (STR #161) + - VC++ 7.1 didn't like how the copy operators were + disabled for the Fl_Widget class; now include inline + code which will never be used but makes VC++ happy + (STR #156) + - Fixed an IRIX compile problem caused by a missing + #include (STR #157) + - FLUID didn't write color/selection_color() calls using + the symbolic names when possible, nor did it cast + integer colors to Fl_Color (STR #146) + - Fl_File_Chooser was very close for multiple file + selection in large directories (STR #140) + - Fl_Text_Display/Editor did not disable the current + selection when focus was shifted to another widget + (STR #131) + - Fl_Choice didn't use the normal focus box when the + plastic scheme was in use (STR #129) + - Fl_Text_Editor didn't use selection_color() + consistently (STR #130) + - The fltk_forms, fltk_gl, and fltk_images DSO's and + HP-UX shared libraries are now linked against the fltk + shared library to provide complete dependency + resolution (STR #118) + - The configure.in file did not work with autoconf 2.57. + - FLUID didn't redraw widgets when changing the X, Y, W, + or H values in the widget panel (STR #120) + - Fl_Window::show(argc, argv) wasn't calling + Fl::get_system_colors() as documented (STR #119) + - DSO (shared library) building wasn't quite right for + some platforms (STR #118) + - OSX: some changes to make ProjectBuilder compiles + possible. + - OSX: FLTK would not know where a window was positioned + by the OS. As a result, popup menus could open at + wrong positions. + + +CHANGES IN FLTK 1.1.4rc2 + + - Fl_Window::show(argc,argv) incorrectly opened the + display prior to parsing the arguments; this prevented + the "-display foo" option from working (STR #111) + - Images were not clipped properly on MacOS X (STR #114) + - Fl::reload_scheme() and Fl::scheme("foo") incorrectly + called Fl::get_system_colors(). This prevented an + application from setting its own color preferences + (STR #115) + - The 'Enter' key event on OS X would not set + Fl::e_text. + - Changed behaviour of FLUID to always paste into + a selected group (STR #88) + - Menuitem now changes font, even if fontsize + is not set (STR #110) + - Swapped shortcut labels in OS X (STR #86) + - Non-square Fl_Dial would calculate angle from user + input wrong (STR #101) + - Updated documentatiopn of fl_draw (STR #94) + and Fl_Menu_::add() (STR #99) + - FLUID collapse triangle events were not offset by + horizontal scroll (STR #106) + - QuitAppleEvent now correctly returns from Fl::run() + instead of just exiting (STR #87) + - Hiding the first created OpenGL context was not + possible. FLTK now manages a list of contexts (STR #77) + - FLUID didn't keep the double/single buffer type for + windows. + - FLTK didn't work with Xft2. + - OSX window resizing didn't work (STR #64) + - Fixed MacOS X shared library generation (STR #51) + - Several widgets defined their own size() method but + didn't provide an inline method that mapped to the + Fl_Widget::size() method (STR #62) + - Fl_Scroll didn't provide its own clear() method, so + calling clear() on a Fl_Scroll widget would also + destroy the scrollbars (STR #75) + - Fl::event_text() was sometimes initialized to NULL + instead of an empty string (STR #70) + - fl_draw() didn't properly handle a trailing escaped + "@" character (STR #84) + - Added documentation for all forms of + Fl_Widget::damage() (STR #61) + - Fl_Double_Window now has a type() value of + FL_DOUBLE_WINDOW, to allow double-buffered windows to + process redraws properly on WIN32 (STR #46) + - Added FL_DAMAGE_USER1 and FL_DAMAGE_USER2 damage bits + for use by widget developers (STR #57) + - Fl_Help_View didn't support numeric character entities + (STR #66) + - Menu shortcuts didn't use the Mac key names under + MacOS X (STR #71) + - CodeWarrior Mac OS X updated to work with current + CW8.3 (STR #34) + - Apple-C/X/V/Z didn't work in the Fl_Input widget due + to a bad mapping to control keys (STR #79) + - Added the OSX-specific fl_open_callback() function to + handle Open Documents messages from the Finder (STR + #80) + - The configure script contained erroneous whitespace in + various tests which caused errors on some platforms + (STR #60) + - The fltk-config script still supported the deprecated + --prefix and --exec-prefix options; dropped them since + they serve no useful purpose and would never have + worked for the intended purpose anyways... (STR #56) + - fl_filename_list returned 0 on Win32 if no directory + existed (STR #54) + - Pressing 'home' after the last letter in a Text_Editor + would move the cursor to pos 0 (STR #39) + - Fl::get_key(x) would mix up Ctrl and Meta on OS X (STR + #55) + - The configure script used the wrong dynamic library + linking command for OSX (STR #51) + - The Fl_Text_Editor widget did not set changed() nor + did it call the widget's callback function for + FL_WHEN_CHANGED when processing characters that + Fl::compose() handles (STR #52) + + +CHANGES IN FLTK 1.1.4rc1 + + - The file chooser did not reset the click count when + changing directories; if you clicked on a file in the + same position after changing directories with a + double-click, the chooser treated it as a triple + click (STR #27) + - Symbols with outlines did not get drawn inactive. + - The Fl_Help_View widget now provides a find() method + to search for text within the page. + - The Fl_Help_Dialog widget now provides a search box + for entering text to search for. + - The default font encoding on OSX did not match the + default on WIN32 or X11. + - Menu items were not drawn using the font specified in + the Fl_Menu_Item structure (STR #30) + - Long menus that were aligned such that the top of an + item was exactly at the top of the screen would not + scroll (STR #33) + - The OS issues appendix incorrectly stated that MacOS + 8.6 and 9 were supported; they are not (STR #28) + - Fixed handling of nested double-buffered windows (STR + #1) + - Showing a subwindow inside a hidden window would crash + the application (STR #23) + - OSX users couldn't enter some special chars when using + some foreign key layouts (STR #32) + - Hiding subwindows on OSX would hide the parent window + (STR #22) + - Added thin plastic box types. + - Fl_Pack ignored the box() setting and cleared any + unused areas to the widget color; it now only does so + if the box() is set to something other than FL_NO_BOX. + - Updated the Fl_Tabs widget to offset the first tab by + the box dx value to avoid visual errors. + - Updated the plastic up box to draw only a single + border frame instead of the old double one for + improved appearance. + - Updated the default background color on OSX to provide + better contrast. + - Fl_Text_Display and friends now look for the next + non-punctuation/space character for word boundaries + (STR #26) + - gl_font() didn't work properly for X11 when Xft was + used (STR #12) + - Fl_File_Browser incorrectly included "." on WIN32 (STR + #9) + - Include shellapi.h instead of ShellAPI.h in the WIN32 + drag-n-drop code in order to work with the MingW cross + compiler (STR #6) + - The cursor was not properly restored when doing + drag-n-drop on X11 (STR #4) + - Fl::remove_fd() didn't recalculate the highest file + descriptor properly (STR #20) + - Fl_Preferences::deleteGroup() didn't work properly + (STR #13) + - Fixed the fl_show_file_selector() function - it was + copying using the wrong string size (STR #14) + - fl_font() and fl_size() were not implemented on MacOS + X. + - Sorted the icon menu bar in FLUID. + - Fixed minor memory access complaints from Valgrind + - Compiling src/flstring.h on OS X with BSD header would + fail. + - Fl_Text_Editor didn't scroll the buffer when the user + pressed Ctrl+End or Ctrl+Home. + - Fl_Text_Editor didn't show its cursor when the mouse + was moved inside the window. + - FLUID now uses an Fl_Text_Display widget for command + output, which allows you to copy and paste text from + command output into other windows. + - Fl_Gl_Window could cause a bus error on MacOS X if the + parent window was not yet shown. + - FLUID could crash after displaying a syntax error + dialog for the callback code. + - FLUID would reset the callback code if you opened the + widget panel for multiple widgets. + - Added a NULL check to Fl_Text_Display (SF Bug #706921). + - The fltk-config script placed the LDFLAGS at the wrong + place in the linker options. + - Fl_Text_Display didn't draw the outer box in the right + dimensions, so it was invisible. + - Fl_Help_Dialog used the same color for links as for + the background, causing links to be invisible on pages + without a background color set. + + +CHANGES IN FLTK 1.1.3 + + - Documentation updates. + - FLTK now ignores KeyRelease events when X11 sends them + for repeating keys. + - FLUID now supports up to two additional qualifiers + before a class name (FL_EXPORT, etc.) to aide in + developing DLL interfaces for WIN32. + - Additional NULL checks in Fl_Button, + fl_draw_boxtype(), Fl_File_Chooser, and + Fl_Window::hotspot(). + - The Fl_Preferences header file needed to FL_EXPORT all + of the nested classes for WIN32. + - Fl_Double_Window couldn't be nested on WIN32. [SF Bug + #658219] + - Fl_Slider didn't call the callback function when the + user changed the value using the keyboard and the + "when" condition was FL_WHEN_RELEASE. [SF Bug #647072] + - Lines with less than 2 unique vertices and polygons + with less the 3 unique vertices were not drawn + properly. [SF Bug #647067] + - The size_range() values were not honored under MacOS + X. [SF Bug #647074] + - OpenGL windows didn't resize correctly on MacOS X. + [SF Bug #667855] + - The menus incorrectly used the overlay visual when one + or more menu items contained an image. [SF Bug #653846] + - Changed some error messages to use Fl::error() instead + of fprintf()... + - Fl_Text_Buffer and Fl_Text_Display used free to free + memory that was allocated using the new operator. + - Tweeked the plastic scheme under MacOSX to better + match the colors. + - The Fl_Image.H always included the x.H header file, + which included many system headers that could + interfere with normal GUI applications. It now uses + the corresponding based types for the image id and + mask to avoid this. + - The FLUID widget panel wasn't sorted, so keyboard + navigation was strange. [SF Bug #647069] + - Fl_Scroll didn't compute the location of labels to the + right or below when determining the area to erase. + - Added backward-compatibility macro for + filename_setext(). + - Fl_Bitmap::copy(), Fl_Pixmap::copy(), and + Fl_RGB_Image::copy() all could overflow the source + image when scaling the image. + - Double/triple clicks in Fl_Input fields didn't copy + the expanded selection to the clipboard. + - Fl_Glut_Window and Fl_Gl_Window didn't always initialize + the OpenGL context on MacOS. + + +CHANGES IN FLTK 1.1.2 + + - Fl_Menu_Bar now supports drawing vertical dividers + between menu items and submenus in the menu bar. + - Fl_File_Chooser::value() didn't return NULL when the + user clicked Cancel while selecting a directory. This + bug also affected fl_dir_chooser(). + - Fl_Menu_::add(const char *) used too small a menu item + label buffer and didn't do bounds checking. + - Eliminate some compiler warnings with CodeWarrier + under WIN32 (Paul Chambers) + - Fl_Gl_Window widgets did not resize properly under + MacOS X. + - The cursor could be set for the wrong window in the + text widgets. + - Fl_Check_Browser didn't provide const char * add + methods as documented. + - Fl_Check_Browser didn't draw the same style of check + marks at the other widgets. + - Fl_Button, Fl_Choice, and Fl_Menu_Button incorrectly + activated the button/menu when the spacebar was + pressed in conjunction with shift, control, alt, or + meta. + - FLTK should now compile with Xft 2.0. + - Some versions of Tru64 4.0 have snprintf and + vnsprintf, but don't have the prototypes for those + functions. + - FLTK had trouble doing character composition with some + keyboard layouts under X11 (in particular, Belgian). + - Fl_Text_Editor would cause a segfault if the user + pressed CTRL-V (paste) without having any data in the + clipboard... + - The tab key moved backwards in menus instead of + forwards. Shift-tab still moves backwards. + - The redraw_label() method didn't damage the parent + window when the label was outside the widget's + bounding box. + - Added a "draw_children()" method to Fl_Group to make + subclassing Fl_Group with a custom draw() function + easier. + - Fl_Text_Editor now supports basic undo functionality. + - FLUID now uses Fl_Text_Editor widgets for all + multi-line code fields. + - Added new widget bin and icons to FLUID. + - FLUID would try running multiple commands in parallel, + even though it wasn't capable of handling it. + - FLUID didn't generate code for some attributes when + using custom/named widget classes. + - Added a new FL_COMMAND state bit which maps to FL_CTRL + on X11 and WIN32 and FL_META on MacOS. + - MacOS keyboard modifiers mapping corrections. Cmd and + Control are no longer swapped, event_key and event_text + return (mostly) the same values as on other platforms. + - The Fl_Tabs widget should no longer be a focus hog; + previously it would take focus from child widgets. + - The file chooser now activates the OK button when + opening a directory in directory selection mode. + - Fixed a bug in the file chooser when entering an + absolute path. + - Back-ported some FLTK 2.0 tooltip changes to eliminate + erroneous tooltip display. + - MacOS windows were resizable, even when size_range + would not allow for resizing. + - Fl_Text_Editor now supports Shift+Delete, Ctrl+Insert, + and Shift+Insert for cut, copy, and paste, + respectively. + - Fl_Text_Display didn't restore the mouse pointer when + hidden. + - Fl::arg() now ignores the MacOS X -psn_N_NNNNN option. + - Added another change to the WIN32 redraw handling for + the MingW compilers. + - Fl_File_Chooser didn't handle WIN32 home directories + that used backslashes instead of forward slashes. + - Fl_Text_Display didn't limit the resize height to 1 + line. + - Fl_Scrollbar widgets incorrectly took keyboard focus + when clicked on. This caused widgets such as + Fl_Text_Display to hide the cursor when you scrolled + the text. + + +CHANGES IN FLTK 1.1.1 + + - Fl_Text_Display didn't always show the cursor. + - Fl_Tabs now only redraws the tabs themselves when + making focus changes. This reduces flicker in tabbed + interfaces. + - The WIN32 redraw handler now correctly merges the FLTK + and Windows redraw regions. + - The Fl_Text_* widgets use the C++ bool type, which is + not supported by older C++ compilers. Added a + configure check and workaround code for this. + - Fl_X::set_xid() didn't initialize the backbuffer_bad + element that was used with XDBE. + - Fl_Shared_Image::uncache() was not implemented. + - Fl::set_font() didn't 0-initialize all font descriptor + data. + - Some OpenGL implementations don't support single- + buffered visuals. The Fl_Gl_Window class now emulates + single-buffered windows using double-buffered + windows. + - Added a workaround for a compiler bug in Borland C++ + that prevented Fl_Help_View.cxx from compiling. + - Checkmarks didn't scale properly; copied the 2.0 check + mark code over. + - Replaced several memcpy's with memmove's for + portability (memmove allows for overlapping copies, + memcpy does not) + - Bug #621737: Fl_Bitmap::copy(), Fl_Pixmap::copy(), and + Fl_RGB_Image::copy() now range-check the new width and + height to make sure they are positive integers. + - Bug #621740: the WIN32 port needed to handle WM_MOUSELEAVE events + in order to avoid problems with tooltips. + - Fl_PNM_Image didn't set the "alloc" flag for the data, + which could lead to a memory leak. + - fl_filename_match() was inconsistently doing case- + insensitive matching. + - Fl_Button redraw fix for bug #620979 (focus boxes and + check buttons). + - Fl_Text_Display fix for bug #620633 (crash on + redisplay). + - Fl_Output now calls its callback when the user clicks + or drags in the widget. + - Shortcuts now cause buttons to take focus when visible + focus is enabled. + - fl_filename_relative() didn't check that the path was + absolute under WIN32. + - fl_filename_relative() didn't check that the path was + on the current drive under WIN32. + - The Fl_BMP_Image class now handles 16-bit BMP files + and BMP files with a transparency mask. + - The fltk-config script didn't add the required include + path, if any, when compiling a program. + - Added a license clarification that the FLTK manual is + covered by the same license as FLTK itself. + - Fl_Check_Browser wasn't documented. + - Fl_Preferences::Node::addChild(), deleteEntry(), and + remove() didn't set the "dirty" flag. + - The "no change" button didn't work in the FLUID widget + panel. + - Vertical scrollbars did not draw the arrows inactive + when the scrollbar was inactive. + + +CHANGES IN FLTK 1.1.0 + + - Documentation updates. + - Added a Fl_Widget::redraw_label() method which flags a + redraw of the appropriate area. This helps to + eliminate flicker when updating the value of a widget. + - Fl_Wizard::value() now resets the mouse cursor to the + window's default cursor. + - Fl_File_Chooser::type() didn't enable/disable the new + directory button correctly. + - Fl_Preferences::entryExists() did not work properly. + - FLUID's image file chooser pattern was incorrect. + - Fl_File_Icon::load_system_icons() now detects KDE + icons in /opt/kde, /usr/local, and /usr automatically, + and supports the KDEDIR environment variable as well. + - Submenus now display to the left of the parent menu if + they won't fit to the right. Previously they would + display right on top of the parent menu... + - Fl_Menu_:add() didn't handle a trailing "\" character + gracefully. + - Clicking/dragging the middle mouse button in a + scrollbar now moves directly to that scroll position, + matching the behavior of other toolkits. + - Added some more range checking to the Fl_Text_Display + widget. + - The editor demo did not correctly update the style + (syntax highlighting) information. + + +CHANGES IN FLTK 1.1.0rc7 + + - Updated the Fl_Text_Buffer and Fl_Text_Display classes + to be based on NEdit 5.3 (patch from George Garvey). + - Fixed a problem with Fl::wait(0.0) on MacOS X 10.2; + this affected the fractals demo and other OpenGL + applications. + - Fl_Glut_Window now takes keyboard focus and handles + shortcut events. + - The MacOS X implementation of fl_ready() now checks + the event queue for events. + - Fl_PNM_Image now supports the XV/GIMP thumbnail format + (P7). + - Fl_Preferences would not find groups inside the root + group. + - Small bug fixes for Fl_Chart, Fl_Scrollbar, Fl_Tabs, + and FLUID from Matthew Morrise. + - Fl_Chart didn't have its own destructor, so data in + the chart wasn't freed. + - Fl_Menu_Button no longer responds to focus or keyboard + events when box() is FL_NO_BOX. + - FLTK convenience dialogs put the buttons in the wrong + order. + - Fl_BMP_Image didn't load 4-bit BMP files properly. + - Minor tweeks to the WIN32 DLL support. + - Fl_Text_Display::resize() could go into an infinite + loop if the buffer is emptied. + - Fl::handle() didn't pass FL_RELEASE events to the + grab() widget if pushed() was set (for proper menu + handling...) + - DND events were being sent to the target window + instead of the target widget under WIN32. + - The newest Cygwin needs the same scandir() handling as + HP-UX. + - FLUID didn't register the image formats in the + fltk_images library, and had some other image + management problems. + - Fixed one more redraw bug in Fl_Browser_ where we + weren't using the box function to erase empty space in + the list. + - Fl_Text_Display::buffer() now calls resize() to show + the buffer. + - Fl_Help_View didn't support HTML comments. + - Fl_Help_View didn't include the extra cellpadding when + handling colspan attributes in cells. + - Fl_Help_View didn't support table alignment. + + +CHANGES IN FLTK 1.1.0rc6 + + - Documentation updates. + - Fl::handle() didn't apply the modal tests for + FL_RELEASE events, which caused Fl_Tabs to allow users + to change tabs even when a modal window was open. + - Fl_Browser_, Fl_Input_, Fl_Slider now use the box + function to erase the background. This fixes some + long-standing redraw problems. + - More snprintf/strlcpy/strlcat changes where needed. + - Fl::get_font_name() would leak 128 bytes. + - Eliminated most of the "shadowed" variables to avoid + potential problems with using the wrong copy of "foo" + in a class method. + - Moved Fl_BMP_Image, Fl_GIF_Image, and Fl_PNM_Image to + the fltk_images library, so the only image formats + that are supported by the core library are XBM and XPM + files. This reduces the size of the FLTK core library + by about 16k... + - The Fl_Text_Display::resize() method was incorrectly + flagged as protected. + - Fixed some memory/initialization bugs in + Fl_File_Chooser that valgrind caught. + - The PNG library png_read_destroy() is deprecated and + does not free all of the memory allocated by + png_create_read_struct(). This caused a memory leak in + FLTK apps that loaded PNG images. + - Added uncache() method to Fl_Image and friends. + - Added image() methods to Fl_Menu_Item. + - Added default_cursor() method and data to Fl_Window. + - Fl_Group would send FL_ENTER events before FL_LEAVE + events, causing problems with adjacent widgets. + - Fixed filename problems with Fl_File_Chooser - + changing the filename field directly or choosing files + from the root directory could yield interesting + filenames. + - Fl_Input_ could crash if it received an empty paste + event. + - The mouse pointer now changes to the I beam + (FL_CURSOR_INSERT) when moved over an input field or + text widget. + - "make install" didn't automatically (re)compile the + FLUID executable. + - Added an Fl::get_boxtype() method to get the current + drawing function for a specific box type. + - Fl_Output and Fl_Multiline_Output didn't prevent + middle-mouse pastes. + - Fl_JPEG_Image didn't compile out-of-the-box with Cygwin + due to a bug in the Cygwin JPEG library headers. + - Fl_BMP_Image still didn't work with some old BMP files. + - "make distclean" didn't really clean out everything. + - Tweeked the look of the check button with a patch from + Albrecht Schlosser. + + +CHANGES IN FLTK 1.1.0rc5 + + - Added "wrap" type bit to Fl_Input_, so you can now + have a multiline text field that wraps text. + - Setting the value() of an output text field no longer + selects the text in it. + - Output text fields now show a caret for the cursor + instead of the vertical bar. + - The newButton and previewButton widgets are now public + members of the Fl_File_Chooser class. This allows + developers to disable or hide the "new directory" and + "preview" buttons as desired. + - Added new visible focus flag bit and methods to + Fl_Widget, so it is now possible to do both global and + per-widget keyboard focus control. + - Removed extra 3 pixel border around input fields. + - No longer quote characters from 0x80 to 0x9f in input + fields. + - Improved speed of Fl_Browser_::display() method with + large lists (patch from Stephen Davies.) + - Fl_Help_View didn't properly handle NULL from the link + callback (the original filename/directory name were + not preserved...) + - Fl_Help_View didn't use the boxtype border values when + clipping the page that was displayed. + - Added first steps to CodeWarrior/OS_X support (see + fltk-1.1.x/CodeWarrior/OS_X.sit) + - Cleaned up the WIN32 export definitions for some of + the widget classes. + - Fixed a filename completion bug when changing + directories. + - Fl_File_Chooser::value() would return directories with + a trailing slash, but would not accept a directory + without a trailing slash. + - When installing shared libraries, FLUID is now linked + against the shared libraries. + - MacOS: missing compile rule for .dylib files. + - Fl_Group::current(), Fl_Group::begin(), and + Fl_Group::end() are no longer inlined so that they are + properly exported in DLLs under WIN32. Similar + changes for all static inline methods in other + classes. + - MacOS: support for Mac system menu (Fl_Sys_Menu_Bar) + - MacOS: wait(0) would not handle all pending events + - Added new makeinclude file for MingW using GCC 3.1.x. + - Fl_Choice::value(n) didn't range check "n". + - The MingW and OS/2 makeinclude files didn't have the + new fltk_images library definitions. + - Fl_Text_Editor didn't scroll the text in the widget + when dragging text. + - Config header file changes for Borland C++. + - FLTK didn't provide a Fl::remove_handler() method. + + +CHANGES IN FLTK 1.1.0rc4 + + - Added new filter_value() methods to Fl_File_Chooser to + get and set the current file filters. + - Added support for custom filters to Fl_File_Chooser. + - Added Borland C++ Builder IDE project files from + Alexey Parshin. + - Resource leak fixes under WIN32 from Ori Berger. + - Now register a WIN32 message for thread messages. + - Fl_Window didn't initialize the min and max window + size fields. + - The JPEG and PNG image classes have been moved to the + fltk_images library, a la FLTK 2.0. You can register + all image file formats provided in fltk_images using + the new fl_register_images() function. + - Fl_XBM_Image didn't correctly load XBM files. + - MacOS: Added Greg Ercolano's file descriptor support. + - MacOS: Fixed text width bug. + - A change in fl_fix_focus() broken click-focus in FLWM. + - Cygwin with -mnocygwin didn't like the FL/math.h + header file. + - Fl_Browser_ cleared the click count unnecessarily. + - MacOS: Pixmap draw fix, gl_font implemented + FL_FOCUS fix, window type fix for modal and nonmodal + windows, glut uninitialised 'display' proc fix + - Now support FLTK_1_0_COMPAT symbol to define + compatibility macros for the old FLTK 1.0.x function + names to the 1.1.x names. + - Now translate the window coordinates when a window is + shown, moved, or resized. This should fix the "menus + showing up at the wrong position" bug under XFree86. + - Fixed some more problems with the Fl_BMP_Image file + loader. + - BC++ fixes. + - The pixmap_browser demo didn't check for a NULL image + pointer. + - Fl_File_Icon::find() now uses fl_filename_isdir() + under WIN32 to check for directories. + - Fl_File_Chooser's preview code called refcount() + on the deleted image's object. + - Fixed another problem with the Fl_BMP_Image loader. + - The fl_file_chooser() callback was being called with a + NULL filename. + - Documented that fl_push_clip() is preferred over + fl_clip(), with a corresponding source change. + - Minor changes to the MacOS X event handling code. + - Added syntax highlighting example code to the editor + test program. + - Fl_Text_Display didn't range check style buffer + values. + - Added "dark" color constants (FL_DARK_RED, etc.) + - The MacOS font code was missing definitions for + fl_font_ and fl_size_. + + +CHANGES IN FLTK 1.1.0rc3 + + - Documentation updates. + - New file chooser from design contest. + - Did some testing with Valgrind and fixed some memory + problems in Fl_Help_View::Fl_HelpView, + Fl_Menu_::remove(), Fl_Text_Display::draw_vline(), and + resizeform() (convenience dialogs). + - Fixed some redraw() bugs, and now redraw portions of + the parent widget when the label appears outside the + widget. + - The boolean (char) value methods in Fl_Preferences + have been removed since some C++ compilers can't + handle char and int value methods with the same name. + - Added fl_read_image() function. + - Fixed Fl_Valuator::format() so that the correct format + type is used when step == 1.0. + - Fl_Help_View didn't support the TT markup. + - Fl_Shared_Image used a double-pointer to the image + handler functions, which was unnecessary and + unintuitive. + - Fl_PNM_Image didn't load the height of the image + properly. + - Fl_BMP_Image, Fl_JPEG_Image, Fl_PNG_Image, and + Fl_Shared_Image didn't delete image data that was + allocated. + - Enabled the OpenGL and threads demos when compiling + for MingW. + - Fl_File_Input didn't update the directory buttons if a + callback was registered with the widget. + - The file chooser would return the last selected + file(s) when cancel was pressed. + - The file chooser limited the resizing of the chooser + window unnecessarily. + - Fixed WM_PAINT handling under WIN32. + - Minor tweeks to MingW and OS/2 config headers. + - Fl_Value_Input now correctly determines if step() + specifies an integer value. + - Fl_Help_View didn't add links inside PRE elements. + - OS/2 build fixes from Alexander Mai. + - Now use strlcat() instead of strncat() which could + cause buffer overflows. + - Now use of strlcpy() instead of strncpy() to simplify + the code. + - Drag-n-drop under WIN32 now shows a [+] cursor instead + of the link cursor. + - Fixed widget width tooltip and default argument + handling code in FLUID. + - Fixed colors used when drawing antialiased text using + Xft. + - Fl_Preferences::makePath() now uses access() instead + of stat() when checking to see if the destination + directory already exists. + - Fl_BMP_Image now supports older BMP files with the 12 + byte header. + - Optimized the redrawing of tabs and radio/check + buttons when the keyboard focus changes. + - More tooltip fixes. + - DND text operations would loop under X11. + + +CHANGES IN FLTK 1.1.0rc2 + + - Portability fixes. + - Backported 2.0 tooltip changes. + - Several of the valuators did not support tooltips. + - The last menu item in a menu didn't pick up on font + changes. + - FLUID now properly handles default argument parameters + properly. + - Fixed WM_PAINT handling under WIN32 - didn't validate + the correct region that was drawn. + - Fl_Multiline_Output would insert the enter key. + - Fl_File_Browser didn't clip items to the column width. + - Fl_Window::draw() cleared the window label but didn't + restore it, so windows could lose their titles. + - Eliminated multiple definitions of dirent structure + when compiling under WIN32. + - Adjusted the size of the circle that is drawn inside + radio buttons to scale better for larger labels. + - FLUID was opening the display when it shouldn't have. + - Fl_File_Chooser.cxx defined the file chooser functions + again; they should only be defined in the header file. + - Wide arcs would draw with "teeth". + - The preferences demo included Fl/Fl_Preferences.H + instead of FL/Fl_Preferences.H. + + +CHANGES IN FLTK 1.1.0rc1 + + - The fl_file_chooser() and fl_dir_chooser() functions + now support an optional "relative" argument to get + relative pathnames; the default is to return absolute + pathnames. + - The backspace and delete keys now work as expected in + the file chooser when doing filename completion. + - FLUID now supports running shell commands. + - New Fl_File_Input widget that shows directory + separators with filename in input field. + - The Fl_File_Chooser dialog now shows the absolute path + in the filename field using the Fl_File_Input widget. + - FLUID now keeps track of grid, tooltip, and other + GUI options, along with the last 10 files opened. + - Tooltip windows would show up in the task bar under + WIN32. + - Now append trailing slash to directory names in names + in WIN32 version of scandir(). This takes care of a + file chooser performance problem with large + directories. + - Added Fl_Preferences class from Matthias Melcher, + including binary data support. + - FLUID now recognizes the "using" keyword in + declarations. + - fl_file_chooser() didn't highlight the requested file + the second time the file chooser dialog was shown. + - Fixed rendering of Fl_Light_Button with the plastic + scheme. + - Fixed a bug in the MacOS font enumeration code. + - Now show a "locked" icon next to static/private + elements in FLUID, and "unlocked" icon next to + global/public elements. + - Implemented Fl_Menu_Item image labels using older + 1.0.x labeltype method. + - Updated the PNG library check to support both png.h + and libpng/png.h. + - Fixed a recursion bug in tooltips that was causing + random crashes. + - fl_file_chooser() could cause a segfault when passed a + NULL filename parameter in some situations. + - Added a "-g" option to fltk-config to support quick + compiling with debugging enabled. + - Fixed redraw problem with Fl_Input and anti-aliased + text. + - Added threading support for MacOS X and Darwin. + - The filesystem list in the file chooser now works under + MacOS X and Darwin. + - The fl_msg structure now contains all data passed to + the WndProc function under WIN32. + - Fixed some window focus/positioning problems under + MacOS X. + - Added fl_create_alphamask() function to create an alpha + mask from 8-bit data; currently this always generates a + 1-bit screen-door bitmask, however in the future it will + allow us to generate N-bit masks as needed by various + OS's. + - Fl_File_Browser::load() didn't properly show drives + when compiled in Cygwin mode. + - Now pass correctly pass keyboard and mouse events to + widget under tooltip as needed... + - Added new Fl::dnd_text_ops() methods to enable/disable + drag-and-drop text operations. + - Fl_Input now supports clicking inside a selection to + set the new text position when drag-and-drop is + enabled. + - Added support of X resources for scheme, dnd_text_ops, + tooltips, and visible_focus... + - Fixed some case problems in includes for the MacOS X + code. + - Fl_Widget::handle() returned 1 for FL_ENTER and + FL_LEAVE events, which caused some compatibility + problems with 1.0 code. + - Fl_Box::handle() now returns 1 for FL_ENTER and + FL_LEAVE events so that tooltips will work with Fl_Box + widgets. + - Some source files still defined strcasecmp and + strncasecmp under WIN32. + - Some source files still used the "false" and "true" + C++ keywords, even though several of our "supported" + C++ compilers don't support them. Using 0 and 1 until + FLTK 2.0 (which uses the bool type instead of int for + any boolean values...) + - Minor Fl_Color revamping, so that color constants map + to the color cube and FL_FOREGROUND_COLOR, + FL_BACKGROUND_COLOR, FL_BACKGROUND2_COLOR, + FL_INACTIVE_COLOR, and FL_SELECTION_COLOR map to the + user-defined colors. + + +CHANGES IN FLTK 1.1.0b13 + + - Fixed a bug in the Xft support in Fl_Window::hide() + (the config header wasn't included, so the Xft code + wasn't getting called) + - Xdbe support must now be enabled explicitly using + --enable-xdbe due to inconsistent bugs in XFree86 and + others. + - Windows resized by a program would revert to their + original size when moved under WIN32. + - Cygwin can only compile the new WIN32 drag-n-drop code + using GCC 3.x. + - Tooltips now appear for inactive and output widgets. + - Tooltips no longer steal keyboard events other than + ESCape. + - Tooltips are no longer delayed when moving between + adjacent widgets. + - fl_beep(FL_BEEP_DEFAULT) now uses the PC speaker under + Windows (0xFFFFFFFF) rather than an event sound. + - The configure script didn't include the -mwindows or + -DWIN32 compiler options in the output of fltk-config + when using the Cygwin tools. + - Fl_Output didn't take input focus when needed, so it + was unable to support CTRL-C for copying text in the + field and did not unhighlight selections when the + widget lost focus. + - The fl_filename_name() function didn't handle a NULL + input string. + - The input field used by the fl_input() and + fl_password() functions was resized too small in + 1.1.0b12. + - Added casts in fl_set_fonts_win32.cxx for VC++ 5.0. + - Fl_File_Icon::find() did not check the basename of a + filename for a match; this caused matches for a + specific filename (e.g. "fluid") to fail. + - The Fl_Shared_Image class now supports additional + image handling functions - this allows you to support + additional image file formats transparently. + + +CHANGES IN FLTK 1.1.0b12 + + - Documentation updates. + - Fl_Choice didn't clip the current value properly - it + wasn't accounting for the box border width. + - The forms compatibility functions are now placed in a + "fltk_forms" library to match FLTK 2.0. + - Renamed down() and frame() to fl_down() and + fl_frame(), filename_xyz() to fl_filename_xyz(), and + all of the define_FL_FOO() functions for the custom + boxtypes to fl_define_FL_FOO() to avoid namespace + clashes. + - Stereo OpenGL support (patch from Stuart Levy) + - All of the convenience functions defined in fl_ask.H + now resize the widgets and dialog window as needed for + the labels and prompt. + - Backported FLTK 2.0 dual cut/paste buffer code. + - Added support for Xft library to provide anti-aliased + text on X11. + - Fl_Help_View didn't keep track of the background color + of cells properly. + - Fl_Browser::item_width() didn't compute the width of + the item properly when column_widths() was set. + - Fl_Button didn't check to see if the widget could + accept focus before taking input focus. + - Fl_Help_View didn't preserve target names (e.g. + "filename.html#target") when following links. + - Drag-and-drop support for MacOS. + - Updated MacOS issues documentation. + + +CHANGES IN FLTK 1.1.0b11 + + - Now conditionally use the WIN32 TrackMouseEvent API + (default is no...) + - Fixed a table rendering bug in the Fl_Help_View + widget. + - The fltk-config script now recognizes all common C++ + extensions. + - The menu code was using overlay visuals when the + scheme was set to "plastic". + - Fixed some drawing problems with Fl_Light_Button and + its subclasses. + - Fixed a minor event propagation bug in Fl_Group that + caused mousewheel events to be passed to scrollbars + that were not visible. + - The fl_file_chooser() function did not preserve the + old file/directory like the old file chooser did. + - The prototypes for fl_input() and fl_password() did + not default the "default value" to NULL. + - Fl_Tabs now draws tabs using the selection_color() of + the child groups; this allows the tabs to be colored + separately from the body. Selected tabs are a mix of + the Fl_Tabs selection_color() and the child group's + selection_color(). + - Fl_Tabs didn't include images in the measurement of + the tabs if no label text was defined. + - The WIN32 code didn't return 0 from the window + procedure after handling WM_PAINT messages. + - fl_draw() would incorrectly test the clipping of + labels the lay outside the bounding box. + - filename_relative() didn't always return the correct + relative path. + - Updated the test makefile to work with more versions + of "make". + - Added new "--with-optim" configure option to set the + optimization flags to use when compiling FLTK. + - The fltk-config script no longer reports the + optimization flags that were used to compile FLTK. + - Initial port of FLTK 2.0 drag-and-drop support. + + +CHANGES IN FLTK 1.1.0b10 + + - Fixed the new WIN32 TrackMouseEvent code. + - Fixed the VC++ project files to link against + comctl32.lib. + + +CHANGES IN FLTK 1.1.0b9 + + - Better FL_LEAVE event handling for WIN32. + - The alpha mask was bit-reversed. + - Fl::scheme() applied the scheme tile image to overlay + and menu windows, which caused problems when the + overlay planes were in use. + - Fixed Fl::event_button() value when hiding tooltip on + some systems. + - Added Fl_BMP_Image class to support loading of Windows + bitmap (BMP) files. + - The shiny demo didn't work on some systems (no + single-buffered OpenGL visual), and the new box types + were reset when show(argc, argv) was called. + - Fl::scheme() didn't update windows that were not + shown. + - The fractals demo would get far ahead of the UI with + some Linux OpenGL drivers. Now use glFinish() instead + of glFlush() so we are at most 1 frame ahead. + - The fractals demo Y axis controls were backwards for + the "flying" mode. + - MacOS: cleaned up src/Fl_mac.cxx + - MacOS: fixed Fl::wait(0.0), fixed Cmd-Q handling + - Update CygWin support for Fl::add_fd(). + - Update the plastic scheme to not override the default + colors - move the color code to the MacOS-specific + code. Also updates the tile image colormap to match + the current background color. + - Add fl_parse_color() to X11 as well, removing a bunch + of conditional code and providing a common interface + for looking up color values. + - Fixed the make problems in the test directory - some + make programs had trouble handling the recursive + dependencies on the FLUID files... + - Now use rint() to round floating-point coordinates. + - Demo cleanup - made sure they all worked with schemes. + - Fl_Tabs no longer clears the unused area of the tab + bar. + - Added show(argc, argv) method to Fl_Help_Dialog. + - MacOS: implemented cut/copy/paste. + - MacOS: improved keyboard handling, fixed keyboard + focus handling, fixed get_key, modified 'keyboard' + demo to show second mouse wheel and additional keys + 'help' and FL_NK+'=' + + +CHANGES IN FLTK 1.1.0b8 + + - OS/2 build fixes. + - fl_draw() didn't ignore symbol escapes properly for + the browsers... + - New Fl::scheme() methods from FLTK 2.0; currently only + the standard ("") and plastic ("plastic") methods are + supported. Schemes can be set on the command-line + ("-scheme plastic") or using the FLTK_SCHEME + environment variable. + - MacOS: fixed iBook keyboard handling, moved + remaining message handling to Carbon, added mouse + capture support, added timer support, added overlay + support, fixed double-buffering side effects. + - The configure script wasn't using the -fpermissive or + -fno-exceptions options with GCC. + - Fl_JPEG_Image and friends didn't set the depth if the + image file couldn't be loaded; since Fl_RGB_Image + didn't check for this, it could fail when displaying + or copying these images. + - filename_absolute() did not always free its temporary + buffer. + - filename_relative() did not do a case-insensitive + comparison under MacOS, OS/2, and Windows. + - filename_isdir() didn't properly handle "D:L" under + WIN32. + - Fl_Shared_Image::get() did not check to see if the + image could not be loaded. + - Fl_Help_View didn't clear the line array in the + Fl_Help_Block structure; this causes erratic + formatting for some pages. + - The font and size members of Fl_Help_Block were never + used. + - The threading functions (Fl::lock() and friends) were + not exported under WIN32. + - The Fl_Text_Display destructor deleted the scrollbars + twice... + - Fl_Help_View didn't reset the horizontal scroll + position when showing a new page. + - Fl_Pack now allows any child widget to be the + resizable() widget, not just the last one. + - MacOS: opaque window resizing, all events except + Mac menus are now handled using Carbon, window + activation fixed, GL_SWAP_TYPE default changed to + make gl_overlay work. + - Fl_Help_View::resize() didn't resize the horizontal + scrollbar. + - MacOS: list all fonts, fixed clipping and mouse + pointer bugs. + - The Fl_File_Chooser widget now uses hotspot() to + position the dialog under the mouse pointer prior to + showing it. + - Added a configure check for *BSD - use -pthread option + instead of -lpthread. + - Fl_Text_Display could get in an infinite loop when + redrawing a portion of the screen. Added a check for + the return value from fl_clip_box() so that the + correct bounding box is used. + - Removed the Fl_Mutex and Fl_Signal_Mutex classes from + the threads example, since they weren't being used + and apparently are not very portable. + - Fl_Help_View now ignores links when the link callback + returns NULL, and displays a sensible error message + when an unhandled URI scheme is used (e.g. http:, + ftp:) + - Fl_File_Icon::load_system_icons() no longer complains + about missing icon files, just files that exist but + can't be loaded. + - FLUID didn't list the plastic box and frame types. + - Now hide the tooltip window whenever a window is + hidden. Otherwise a tooltip window could keep an + application running. + - Updated FLUID to only append a trailing semicolon to + code lines in a callback (so "#include" and friends + will work...) + - The Fl_Color_Chooser widget now supports keyboard + navigation. + - Fixed button and valuator widgets to call Fl::focus() + instead of take_focus(). + - Tweeked the radio button drawing code for better + circles with different boxtypes. + - The Fl_File_Chooser widget did not provide a shown() + method, and fl_file_chooser() and fl_dir_chooser() did + not wait on shown(); this would cause them to return + prematurely if you switched desktops/workspaces. + - Cosmetic changes to plastic boxtypes. Now look much + better for large areas and the buttons now have a much + greater "3D" feeling to them. + - Added new Fl::draw_box_active() method so that + boxtypes can find out if the widget they are drawing + for is active or not. + - Fl_Button and its subclasses did not redraw the parent + when the boxtype was FL_NO_BOX and they lost keyboard + focus (the parent redraw clears the focus box.) + - Fixed the example program makefile - wasn't building + the mandelbrot and shiny demos right. + - Fl::set_font(Fl_Font, Fl_Font) was not implemented. + - Fixed the documentation Makefile commands; was not + using the fltk.book file for some reason... + + +CHANGES IN FLTK 1.1.0b7 + + - More documentation updates... + - Mac OS X support works 95% + - The Fl_Window::hotspot() off-screen avoidance code was + commented out. + - Mac OS X uses mostly Carbon event handling to support + Mousewheel, three buttons, all modifier keys, etc. + - Updated paragraph 4 of the FLTK license exceptions; + there was some question about the requirement to show + that a program uses FLTK, which is required by section + 6 of the LGPL. The new exemption specifies that + inclusion of the FLTK license is not required, just a + statement that the program uses FLTK. + - Fl_Button::handle() was calling take_focus() for both + FL_PUSH and FL_DRAG. + - File and memory fixes for Fl_GIF_Image, Fl_PNG_Image, + Fl_PNM_Image, Fl_Shared_Image, Fl_Tiled_Image, and + Fl_XBM_Image. + - filename_match() didn't handle backslashes properly + under WIN32, and didn't use a case-insensitive + comparison under MacOS X. + - The Fl class was missing access methods for the + FL_MOUSEWHEEL event values - Fl::event_dx() and + Fl::event_dy(). + - The default help string didn't include the -nokbd + option. + - "make uninstall" didn't uninstall the static OpenGL + widget library. + - Mac cursor shapes added... + - Fl_Text_Display would lockup when all text was + deleted; for example, when running the editor + demo, you couldn't load a second file. + - Added Fl::lock() and friends from FLTK 2.0 to + support multi-threaded applications; see the + "threads" demo for an example of this. + - Fl_Check_Button and Fl_Round_Button now use the + FL_NO_BOX box type to show the background of the + parent widget. + - Tweeked the plastic boxtype code to draw with the + right shading for narrow, but horizontal buttons. + - Fl_Progress now shades the bounding box instead of + drawing a polygon inside it. + - Fl::warning() under WIN32 defaults to no action. This + avoids warning dialogs when an image file cannot be + loaded. + - Some Win32 drivers would draw into wrong buffers + after OpenGL mode change + - The file chooser would cause a segfault if you + clicked in an empty area of the file list. + - Fl_File_Icon::labeltype() would cause a segfault + if the value pointer was NULL. + - Fl_File_Icon::load_image() could cause segfaults + (NULL data and incrementing the data pointer too + often.) + - Fl_File_Icon::load_image() now handles 2-byte + per color XPM files. + - Some Win32 drivers would draw into wrong buffers + after OpenGL mode change. + - Message handling and Resources for MacOS port. + - Fl_Help_View could get in an infinitely loop when + determining the maximum width of the page; this + was due to a bug in the get_length() method with + percentages (100% width would cause the bug.) + - Don't need -lgdi32 for CygWin, since -mwindows + does this for us. + - The WIN32 event handler did not properly handle + WM_SYNCPAINT messages. + - Fl_Tabs now uses the boxtype exclusively to draw + both the tabs and surrounding box, so alternate + box types actually work and the look is a little + nicer. + - Fixed the drawing of large areas with the new + plastic boxtypes. + - Updated the Visual C++ demo projects to use FLUID + to generate the GUI files as needed. + - The demo program didn't load the right menu file + when compiled for debugging under WIN32. + - Added plastic box types to forms demo. + - Added mousewheel to keyboard demo. + - The Fl_Text_Editor widget caused an infinite loop + when it received keyboard focus. + - filename_isdir() didn't properly handle drive letters + properly; WIN32 needs a trailing slash for drive + letters by themselves, but cannot have a trailing + slash for directory names, go figure... + - The Fl_Text_Buffer and Fl_Text_Display classes did not + initialize all of their members. + - fl_normal_label() had a totally redundant set of + if/else tests, which the new code handles all from + fl_draw(). + - The Fl_File_Chooser dialog contained two hotspots. + - The fl_draw_pixmap() function didn't free the 2-byte + color lookup table properly (delete instead of + delete[]). + - fl_draw() reset the text color under WIN32, causing + bitmaps to draw incorrectly. + - Fl::get_font_sizes() is now implemented under WIN32. + - Fl_Text_Display now uses the same default colors for + selection and text as Fl_Input_ and friends. + - Changed the default line scrolling in Fl_Text_Display + to 3 lines for the mouse wheel and scrollbar arrows. + + +CHANGES IN FLTK 1.1.0b6 + + - Documentation updates... + - The configure script now works within the CygWin + environment. + - Tooltips are now enabled by default, but are not + re-enabled when calling the Fl_Widget::tooltip() + method. + - Added new Fl::version() method to get the current + FLTK library version (for shared libraries/DLLs) + - Added new Fl::event() method to get the current + event that is being processed. + - Added new fl_beep() function to do audible + notifications of various types. + - Added new Fl_GIF_Image, Fl_JPEG_Image, Fl_PNG_Image, + Fl_PNM_Image, Fl_XBM_Image, and Fl_XPM_Image classes. + - Added new Fl_Shared_Image class, a la FLTK 2.0. + - Added new Fl_Tiled_Image class for tiled backgrounds. + - Added new copy(), desaturate(), inactive(), and + color_average() methods to the Fl_Image classes. + - Added a horizontal scrollbar to the Fl_Help_View + widget. + - Added new FL_PLASTIC_{UP/DOWN}_{BOX/FRAME} boxtypes + for a more "modern" look (sort of a cross between KDE + 2.2 and Aqua.) + - Fl_Float_Input and Fl_Int_Input no longer accept + pasted text that is not a floating point or integer + value. Pasted numbers now replace text in these + widgets. + - Implemented the Fl_File_Icon::load_png() method. + - The Fl_File_Icon::load_system_icons() method now + supports KDE 2.x icons. + - Fixed PNG support in Fl_Help_View. + - Removed the "Microsoft" mode button from the menubar + demo. + - The browser demo now makes sure that the input field + contains a number. + - The Fl_Browser::make_visible() method now range checks + the input. + - Updated the fl_draw() and fl_measure() methods to + accept an optional draw_symbols argument, which + controls whether symbols are drawn in the text. + - Added new Fl::visible_focus() methods to control + whether the focus box is drawn. + - The focus box is now drawn using the contrast color. + - Fl_Repeat_Button didn't accept keyboard focus. + - Added new Fl::visible_focus() method and standard + "-kbd" and "-nokbd" options in Fl::args() processing + to control whether keyboard focus is shown and handled + by non-text widgets. + - The wrong tooltip could be shown if the user moved the + mouse over adjacent widgets with tooltips. + - The drop-down button on Fl_Choice widgets was not + limited in width. + - Tooltips could appear off the screen. + - Mouse wheel events are now sent to the focus widget + first, then to any other interested widget. + - The Fl_RGB_Image class now supports images with an + alpha channel. Images are currently drawn using + "screen door" transparency... See the "image" demo + for an example. + - Added new fl_create_bitmask() and fl_delete_bitmask() + functions that create bitmap objects for masking and + bitmap drawing. + - Was sending FL_RELEASE events for buttons 4 and 5 + under X11, which are only for FL_MOUSEWHEEL. + - Fl_Help_View now supports the EM and STRONG elements. + - Didn't do callbacks when changing tabs via keyboard. + - FLUID didn't write tooltip strings to the message + catalog file. + - Fl_File_Icon now uses Fl_Shared_Image to load icon + images; the load_png() and load_xpm() methods have + been replaced by a single load_image() method. + - Fl_File_Icon::load_system_icons() now does a better + job of finding KDE icons. + - Now use Fl::warning() and Fl::error() in place of + printf's in some of the newer widgets. + - The default behavior of Fl::error() is now to display + an error but not to exit; Fl::fatal() still exits. + - FLUID now uses the Fl_Shared_Image class, so FLUID- + generated GUIs can embed any of the supported image + file formats. + - New filename_relative() function to convert an + absolute filename to a relative one. + - Updated the filename_absolute(), filename_expand(), + and filename_setext() functions to take the + destination string size, with inline functions for the + old FL_PATH_MAX size. + - fl_file_chooser() and fl_dir_chooser() now return a + relative path. + - Fl_Help_View now supports all ampersand escapes. + + +CHANGES IN FLTK 1.1.0b5 + + **** NOTE: DUE TO CHANGES IN THE WIDGET CLASSES, **** + **** YOU MUST RECOMPILE ALL SOURCE FILES **** + **** THAT USE FLTK!!! **** + + - All FLTK color values are now 32-bits and support + both the legacy 8-bit color values as well as 24-bit + RGB values (0xRRGGBB00 for 24-bit RGB, 0x000000II + for indexed color). + - Fl::set_boxtype() and fl_internal_boxtype() now keep + track of when a boxtype is changed; this allows you to + override the "special" boxtypes without references to + those boxtypes causing them to be reset. + - Fl_Help_Func now takes a Fl_Widget pointer as well as + a pathname. + - Added code to support FL_KEYUP events. + - Focus did not return to the Fl_Text_Display and Editor + widgets when scrolling and then clicking inside the + editor window. + - Now set the line size of the vertical scrollbar in the + text editor to 1. + - The symbols demo didn't show the strings needed to + show the corresponding symbol (the label string was + not quoted...) + - FLTK should now compile with Cygwin cleanly. + - Shortcut changes were not being saved by FLUID. + - FLUID didn't write the deimage() static data. + + +CHANGES IN FLTK 1.1.0b4 + + **** NOTE: DUE TO CHANGES IN THE FL_WIDGET CLASS, **** + **** YOU MUST RECOMPILE ALL SOURCE FILES **** + **** THAT USE FLTK!!! **** + + - Updated the flags_ member of Fl_Widget to be an + integer instead of uchar, to support the new + FL_OVERRIDE flag for Fl_Window. + + - The parent() method of Fl_Widget now uses pointers to + Fl_Group instead of Fl_Widget. + + - Fl_Window now provides the FLTK 2.0 "override()" and + "set_override()" methods for windows. + + - Added a configure check (and warning) for GCC 3.0.x. + + - Updated the configure script to check for the + png_set_tRNS_to_alpha() function. + + - Updated the config.h files for all platforms for the + image and FLTK documentation defines. + + - Updated the makeinclude files for all platforms to + match the current makeinclude.in file. + + - FLUID would crash if you cleared an image for a + widget. + + - Fl_Help_View::add_image() did not initialize the image + member of the base (unscaled) image. + + - Fl_Help_View didn't support A elements with both a + NAME and HREF attribute - the HREF was ignored. + + - Miscellaneous compile warning fixes. + + - Tooltips were being reset by Fl::belowmouse(), which + caused problems with the FLUID main window (flashing + tooltip windows and serious problems with KDE 2.2) + + - The editor demo had the save and discard button + actions reversed. + + - The Fl_Help_View widget now uses + png_destroy_read_struct() if the older + png_read_destroy() function is not available. + + - The WIN32 DLL library now includes the OpenGL widgets. + This is a simpler solution for the export/import + dillemma under WIN32, as OpenGL and non-OpenGL symbols + need to be exported at different times with the + separate library scheme. Since OpenGL is standard + under Windows, this is less of a problem than under + UNIX... + + +CHANGES IN FLTK 1.1.0b3 + + - The top-level makefile did not include the makeinclude + file, causing the fltk-config installation commands to + fail. + + - The fl_file_chooser.cxx source file conflicted with + Fl_File_Chooser.cxx under Windows. Similarly, the + fl_file_chooser.H header file conflicts with the + Fl_File_Chooser.H header file. + + - Now save and restore the GDI pen object when + responding to WIN32 paint messages. + + - Documentation updates from A. Suatoni. + + +CHANGES IN FLTK 1.1.0b2 + + - New fltk-config script. + + - Fixed image/text label handling; in b1 the label + needed a non-blank text string to display the image. + This bug also caused all sorts of crashes and display + problems. + + - Added new filetype() method to Fl_FileBrowser to allow + for file or directory browsing. + + - Fixed the drawing of the focus box around + Fl_Return_Button. + + - Fixed menu item measurement bug (wasn't initializing + image pointers to 0...) + + - Radio and checkbox menu items now draw with the new + style (round radio buttons with dots and square check + buttons with check marks.) + + - Improved the appearance of Fl_Check_Button. + + - Improved the Fl_HelpView table formatting code; now + dynamically sizes the table columns, and supports + COLSPAN. + + - The FLUID keyboard shortcuts now work as expected + (CTRL-C copies, SHIFT-CTRL-C writes code, etc.) + + - The FLTK_DOCDIR environment variable can now be + used to tell FLUID where to find the on-line + documentation files. + + - FLUID now supports image labels in addition to text + labels + text over image alignment. + + - FLUID now supports tooltips. + + - The widget panel in FLUID is now tabbed, a la FLTK + 2.0. + + - The FLUID pixmap destructor tried to free 1 too many + lines of image data. + + - FLUID now provides on-line help. + + - Changed Fl_FileXYZ to Fl_File_XYZ. + + - Changed Fl_HelpXYZ to Fl_Help_XYZ. + + - Tooltip fixes for Fl_Browser_, Fl_Choice, and Fl_Input_. + + - Added tooltips to FLUID, help dialog, and file chooser. + + - Now load system icons in FLUID. + + +CHANGES IN FLTK 1.1.0b1 + + - Added new image() and deimage() methods to support + image + text labels more easily. + + - Added new alignment bit FL_ALIGN_TEXT_OVER_IMAGE. + + - Added tooltip support using Jacques Tremblay's tooltip + patch. + + - Added keyboard navigation to all widgets. + + - Added support for mouse wheels using the new + FL_MOUSEWHEEL event type. Get the mouse wheel + movement values from Fl::e_dx (horizontal) and + Fl::e_dy (vertical). + + - Added the Fl_Check_Browser, Fl_FileBrowser, + Fl_FileChooser, Fl_FileIcon, Fl_HelpDialog, + Fl_HelpView, Fl_Progress, and Fl_Wizard widgets from + the bazaar. + + - Added 2.0 Fl_Text_Display and Fl_Text_Editor widgets + based on NEdit. + + - The Fl_Choice widget now looks more line a combo box + than a Motif option menu. + + - Moved the OpenGL widgets into a separate library + called fltkgl - this eliminates shared library + dependencies on OpenGL when no OpenGL functionality is + used/required. + + - FLUID now supports the new Fl_CheckBrowser, + Fl_FileBrowser, Fl_FileIcon, Fl_HelpView, + Fl_Text_Display, Fl_Text_Editor, and Fl_Wizard + widgets. + + - Updated configure stuff to support shared libraries + under AIX (link to -lfltk_s) + + - Symbol labels can now contain regular text. + + - FLUID now supports relative filenames for the source + and header files you generate. + + - Fl_Menu_Item::add() didn't use the flags that were + passed in. + + - Fixed a bug in Fl_Scrollbar - clicking in the "trough" + of the scrollbar would move the scroller in the wrong + direction. + + - Made the Forms pixmap parameter const to match the + Fl_Pixmap.H definitions. + + - Changed the Fl_Pixmap constructor to use the explicit + keyword which should work for all C++ compilers. + + - Fl_Menu_add of a menu item with the same name as an + existing submenu title would mess up by replacing that + menu title, it now adds a new item. + + - Fl_Menu::add() of text starting with '/' to a menu is + assummed to be a filename. So "/foo/bar" creates a + single menu item. You can also put filenames into + submenus by doing "submenu//foo/bar", this will create + a submenu called "submenu" with an item "/foo/bar". + Menu items starting with "\_" will insert an item + starting with '_' rather than a divider line. These + changes make the menus compatable with fltk 2.0. + + - Another little fix for the BoXX OpenGL overlays. + + - Fl_Gl_Window no longer blanks the mouse pointer on + WIN32 unless an OpenGL overlay is being used. This + should make non-overlay displays faster when a cursor + is set. + + +CHANGES SINCE FLTK 1.0.10 + + - CHANGED THE DEFAULT RUN-TIME LINKING TO "MULTITHREADED + DLL". You'll need to change your project settings to + use this as well or you'll get errors. + + - Added new --disable-gl option to configure script. + + - Added new const const pointer versions of pixmap + functions to eliminate an annoying pointer warning + message that was generated by the Sun and other C++ + compilers. + + - Eliminated all "var hides class::var" warnings. + + - Eliminated all "string literal converted to char *" + warnings. + + - OS/2 updates from Alexander Mai. + + - Tidied up the HTML documentation to be more standards + compliant. + + - Compiling with -DBOXX_BUGS will work around some + problems with the newest X drivers that BoXX delivers, + the problems all affect use of Overlays for normal X + drawing and OpenGL drawing. Normal compilation is + unchanged. + + - The file chooser buttons use user_data() rather than + the label to decide what to do, allowing the label to + be somewhat cleaner. + + - Selection color on X changed to blue, to match what + happens on Windows now. + + - Added support for AIX (static library only). + + - Added support for SunOS 4.x + + - Now process WIN32 WM_ACTIVATEAPP message to reset the + key and button states in Fl::e_state. + + - Fl_has_idle only tested N-1 callbacks and missed one. + + - Restored WM_SYNCPAINT handling under WIN32; this fixed + a refresh bug under some versions of Windows. + + - Check for OpenGL headers before checking to see if + OpenGL is supported. This should eliminate compile + errors due to missing non-FLTK header files... + + - Add -D_INCLUDE_POSIX_SOURCE option when compiling with + the HP compilers. + + - Replaced remaining _WIN32 symbols with WIN32 + + - Removed reference to unused GL/glu.h header file, which is missing on + some Linux systems. + + - Fl_Gl_Window has a new method to allow you to get and set the context: + + void Fl_Gl_Window::context(void*, int destroy = 0) + void* Fl_Gl_Window::context() const; + + Return or set a pointer to the GLContext that this window is + using. This is a system-dependent structure, but it is portable to + copy the context from one window to another. You can also set it to + NULL, which will force FLTK to recreate the context the next time + make_current() is called, this is useful for getting around bugs in + OpenGL implementations. + + If destroy_flag is true the context will be destroyed by fltk when + the window is destroyed, or when the mode() is changed, or the next + time context(x) is called. + + - Some cleanup of Fl_Gl_Choice to move most of the system dependent + #ifdefs into Fl_Gl_Choice.cxx. + + - Fl_Gl_Window does not set drawbuffer(BACKBUFFER) for + single-buffered windows. + + - Fl_Input::replace(...) correctly updates the display + if the replaced region does not include the mark, + point, or selected region. + + - Added Fl::add_check(...), Fl::remove_check, and + Fl::has_check. These are similar to idle callbacks but + are only called just before it waits for new events. + They can be used to watch for changes in global state + and respond to them. + + - "accu-timer": some changes to repeat_timeout that seem + to make it accurate on Unix and WIN32 at speeds up to + 500000 timeouts/second (and 700000 on Linux), and + within about .001% as accurate as the system clock. + + - Fix to Fl_Valuator::step() by Guillermo Andrade. + + - Fixed the FLUID write-menu bug introduced in 1.0.10 + + - Fl::flush() now calls GdiFlush() under WIN32 to + ensure that all graphics are drawn. + + - fl_curve() now uses a much better algorithim to figure + out how many pieces to cut the curve into. + + - FLUID now uses GetTempPath() under WIN32 to determine + where to store the clipboard. + + - Right-ctrl does not delete selected text in Fl_Input, + until you type a composed character. + + - Added simple FLTK and FLUID manual pages. + + - Fl_Gl_Window leaked memory under WIN32. + + - The colbrowser demo was missing an include file when + compiled under OS/2. + + +CHANGES SINCE FLTK 1.0.9 + + - Added a strcasecmp() function to FLUID; AIX doesn't + have it. + + - Bug #115509: Fl_Scroll not repainting background. + + - Updated the configure script and makeinclude.in file + to work with the Sun PRO compilers. + + - Disabled the WIN32 async socket select code by default: + it doesn't seem to work anymore... + + - Fl::below_mouse() was incorrectly clearing e_is_click; + this prevented any double-clicks from getting + through... + + - No longer clear Fl::keysym on every event, this makes + better back compatability and fixes Win2000 + + - FLUID now restores which tab in an Fl_Tabs was + selected when loads .fl files. + + - Hack to fix the annoying "raise another application + when a modal window is closed" problem on WIN32. + + - Fl_Tabs now draws the background behind the tabs. + + - Fl::set_fonts() on WIN32 fixed to work before the + first window is shown. + + - CUA function keys, code submitted by George Yohng + + + - Another attempt to get glut.h to work on WIN32. + + - Fl_Menu_::add() ignores '&' signs when comparing menu + items, so you don't have to make the shortcuts the + same all the time. + + - Fixed bit-flipping patterns in WIN32 bitmap code. + + - Fixed size of data written by gif images to .C files + + - Menu titles and buttons in the menubar can be images + (allows it to be used as a toolbar) + + - Reads selectBackground from the xrdb database to set + the selection color. Adding this to your .Xdefaults + will make fltk and Motif programs look much more + Windoze-like: + + *selectForeground: white + *selectBackground: #000080 + + - FL_WHEN_RELEASE on Fl_Input will now do the callback + when the input field is hidden, for instance when it + is on a tab and the user switches to another tab. + + - Fl_Gl_Window with an overlay on X always resized any + child windows even if you turned resizable() off + because it turned it back on to resize the overlay + window. This patch avoids changing resizable(). + + - Fix so multiple Fl::add_idle() calls works + + - The input focus got messed up if you called + Fl_Tabs::value(x) and there was something that took + focus on an earlier tab. + + - Removed some (not all) of the warnings when compiled + with -Wwrite-strings, this should also get similar + warnings Solaris produces. + + - Made Fl_Browser not hide the Fl_Widget::show() method + + - Changes & additions for OS/2 from Alexander Mai + + - Patch from Mike Lindner to make the turning on/off of + scrollbars on Fl_Scroll smarter. + + - Added missing FL_EXPORT for Fl_Valuator::format() + + - Shortcuts for "buttons" in a Fl_Menu_Bar work again. + + - Fix for cut/paste support and Xdnd. + + - Shortcuts for submenu titles in a menubar pop up the + submenu (rather than calling the callback) + + - Added documentation for GL_SWAP_TYPE + + - Buttons with box(FL_NO_BOX) did not draw. Apparently + they did in older versions of fltk, I restored this. + (bug 108771) + + - Removed 8-bit colormap drawing code that was not doing + anything in fl_draw_image due to the colormap + allocation changes. I also made fl_color(r,g,b) + actually allocate the requested color rather than the + nearest fltk color-cube color (this is only done for + the first color that maps to a given entry in the fltk + color cube), the result is that pixmaps with a small + number of colors are drawn much more accurately. The + resulting code seems to produce better images and is a + good deal smaller! + + - Fixed makeinclude.in so CFLAGS are used for c source + code instead of CXXFLAGS. (bug 108694) + + - Better fix for gif files suggested by pauly (bug + 108770) + + - Performance of Fl_Gl_Window may be improved on some + types of OpenGL implementations, in particular MESA + or other software emulators, by setting the + GL_SWAP_TYPE environment variable. This variable + declares what is in the back buffer after you do a + swapbuffers: + + setenv GL_SWAP_TYPE COPY + + This indicates that the back buffer is copied to + the front buffer, and still contains it's old + data. This is true of many hardware + implementations. Setting this will speed up + emulation of overlays, and widgets that can do + partial update can take advantage of this as + damage() will not be cleared to -1. + + setenv GL_SWAP_TYPE NODAMAGE + + This indicates that nothing changes the back + buffer except drawing into it. This is true of + MESA and Win32 software emulation and perhaps some + hardware emulation on systems with lots of memory. + + All other values for GL_SWAP_TYPE, and not setting + the variable, cause fltk to assumme that the back + buffer must be completely redrawn after a swap. + + This is easily tested by running the gl_overlay demo + program and seeing if the display is correct when + you drag another window over it or if you drag the + window off the screen and back on. You have to exit + and run the program again for it to see any changes + to the environment variable. + + - Optimized colormap usage on 8-bit displays with + images. New code only allocates colors as they are + needed (still converts indexed images to full RGB and + dithers, tho...) + + - Fixed .gif files in FLUID, they were broken by the fix + for large .xpm files in version 1.0.9. + + - Fix for OpenGL hardware overlays with the transparent + index != 0. Tested on the brand new HP Linux + Workstations, this is the only bug encountered. Both + X and OpenGL hardware overlay works perfectly on + these, though configue may not enable it by + default...) + + - Fl_Choice and all other Fl_Menu_ subclasses draw the + items using textcolor() as the default color of the + text. + + - Fix suggested by Stuart Levy to fix scrolling when + deleting items from the browser. + + - Replaced the -$(MAKEFLAGS) with $(MFLAGS) as per the + gmake documenation. Apperntly this works with other + make programs and MAKEFLAGS is passed invisibly by + gmake, though the documenation is not too clear... + + +CHANGES SINCE FLTK 1.0.8 + + - More documentation fixes. + - GLUT_STROKE_*_ROMAN in glut.h are defined as 0,1 on + WIN32 to match the glut header files there. + - Added Fl::has_timeout() and Fl::has_idle() functions. + - Added new Fl::repeat_timeout() method that + measures time from when the last timeout was called. + This has slightly less overhead and allows accurate + spacing of timeouts. + - More Cygwin changes + - FLUID could crash with identifiers with trailing + whitespace. + - Fixed the XPM loading code in FLUID to handle files + longer than 2048 lines. + - Added a bunch of missing FL_EXTERN's to glut.h to + eliminate GLUT linking errors under WIN32. + - Fix for sliders so that clicking on one with a small + (or zero) slider_size will not move the slider. + - fl_shortcut.cxx didn't export fl_old_shortcut() in the + WIN32 DLL. + - Fixed xpaint link in the documentation. + - Included Fl_Input word-wrap fixes from Alexander Rabi + Beels. This will not affect things much because + word-wrap is normally disabled. + - Patch from Stuart Levy so the *last* widget in an + Fl_Pack may be resizable. This should be compatable + because resizable didn't do anything before so there + was no reason to set it. + - Cleaned up the timeout and Fl::wait() code. The new + code calls the clock function less than half as much, + which results in a noticable performance improvement + in some apps. + - Fl::wait(time) with a time greater than the system can + handle (24.855 days on NT, the same on some Unix + systems) will now act as though the time is infinity. + Before it would do unpredictable things. + - "USE_POLL" now compiles and works, although it is + disabled by default. poll() is an alternative to the + UNIX select() call which is available on some version + of UNIX and may be faster depending on the platform; + try it by editing config.h. + - The WIN32 USE_ASYNC_SELECT code now does translation + and dispatching of the select events; this makes + Windows a lot happier. + - Added a check for an open display in Fl::wait() so + that you don't need an open window under X to call it. + + [changes in snapshot 2] + + - fl_old_shortcut() wasn't being exported in the WIN32 DLL + project. + - Updated Cygwin and Mingw makefiles. + - Updated the BC++ project file. + - You can no longer insert control chars into Fl_Int/Float_Input. + - Fl_Multiline_Input now resets the horizontal position when + focus is changed; this caused problems when multiple multiline + widgets were used in an application. + - All handle() methods are now public, and all draw() methods are + now protected in FLTK widgets. + - More fixes to the OpenGL overlay code on win32. This now + seems to work quite reliably on several different pieces of + hardware. Apparently doing SetLayerPaletteEntries with a + palette larger than the overlay size caused the drivers to + screw up in unpredictable ways. Also SwapBuffers swapped both + the overlay and main window, which is not what fltk's + interface wanted, this was easy to fix however. + - Patch for full scrollbars so that clicking on them does not + move anything. + - Documentation fixes. + - Better horizontal scrolling of Fl_Input when cursor is near + the end of the line. + - Fl_Input::value(x) selects all text. + - Fl_Output and Fl_Multiline_Output would scroll to the end + of the text. + - filename_isdir() now drops any trailing slash from the + filename (needed for Windows) + - Added return type for main() function in line_style demo. + - Running FLUID with the "-cs" option writes the I18N message + file. + - The WIN32 version of XParseGeometry() didn't initialize some + variables. This caused a compiler warning but did not affect + the actual code. + + [changes in snapshot 1] + + - EMail changes - fltk-bugs@easysw.com now officially + fltk-bugs@fltk.org. + - The FLTK DLL project file didn't include fl_compose.cxx + - Dropped the GCC -fno-rtti option since it caused problems + with existing programs. + - Moved the .fl rules back to the test directory. + - Fixed some makefile and spec file problems. + - Fixed hardware overlays. The problem was the new + fl_clipped() code, which tests against the current window + size. The hardware overlay code did not set the current + window when drawing the overlay. I needed hardware overlay + for DD's code, I'm not sure if these fixes are good enough to + enable this in our general release. Hardware overlay still + only works on SGI Irix. + - Some patches to turn off the MSVC++ -Oa (assumme no aliasing) + optimization flag. Suprisingly this only broke a few parts + of fltk, or at least these are the only ones I found. + - Does not unmap child windows when the main window is + iconized. This reduces flashing when the window is + deiconized. + - Fl::key() is set to zero by all events except key down/up. + This will allow you to reliably test if an event or callback + was produced by a keystroke. Fixes the bug posted about + stopping Escape from closing the window. + - User defined cursors on OpenGL windows slowed down NT a + *LOT*. Some attempts to fix this by turning off the cursor + while drawing the window. + - Filename completion in the file chooser works better on NT. + Typing TAB fixes the case of everything you typed to match + the shortest name that can be completed. + + +CHANGES SINCE FLTK 1.0.7 + + - Many documentation changes/fixes/improvements. + - FLUID didn't save Fl_Double_Window's as + double-buffered windows. + - Fl_Menu_ text color is used if Fl_Menu_Item text color + is not set. + - Added Fl::first_window(window) method to change the + "top" window that is used when showing modal windows. + By default it is the window the user last + clicked/typed in. + - The Fl_Menu::global() handler now uses the current top + window instead of the menu bar for modal stuff. + - Added fl_line_style() function to set the line style. + Note that user-defined line styles ONLY WORK UNDER X11 + and Windows NT/2000. Windows 95/98 do, however, + support the "standard" line styles. + - Fl::wait() does not return immediately when no windows + - XForms keyboard shortcuts using hex keycode constants + now work. + - Updated the configure script for *BSD and to turn off + exceptions and RTTI in the FLTK library itself (does + not affect applications which use these things) + - FLUID now supports I18N using the POSIX or GNU + mechanisms. + - Fixed definition of glutBitmapWidth to match header + file. + - Does not turn visible() on when a window is iconized() + or if a modal window is shown and it's parent is + iconized. This allows the code "while (w->visible() + && w->damage()) Fl::check();" to reliably wait for the + window to be mapped and drawn the first time. + - Setting box(FL_NO_BOX) on a button makes it an + invisible overlay + - FL_NORMAL_SIZE is now a global variable so you can + change the default text size prior to creating your + widgets. + - Menus now draw properly with a box type of + FL_FLAT_BOX. + - Cygwin fixes to compile in POSIX mode. + - Fl_Value_Input callback can call value() or + destructor. + - OpenGL overlays now work under Windows NT! + - Fl_Slider and Fl_Scrollbar could cause a divide by + zero. + - Clicking in an Fl_Input field no longer selects the + whole field, it just moves the text cursor. + - Tru64 UNIX fixes for filename_list() + - Fl_Browser now draws itself properly when deactivated. + - FLUID GUIs now use Courier font for all code input. + - The FLUID OK and Cancel buttons are now all shown in + the same order in all windows. + - Fixes to compile under GCC 2.95.2 + - Fixed the BC5 project files. + - FL_LEFT_MOUSE and friends are now in + + - Fixes for fake OpenGL overlay code under WIN32. + - Message windows are now resizeable. + - On WIN32 non_modal (but not modal) windows have the + close and size boxes. + - Fl_Button and friends didn't honor the + FL_WHEN_NOT_CHANGED condition. + - Disabled XDBE on all platforms. + - XGetDefault patch from James Roth + - New fl_open_display(Display *) function to allow FLTK + to share a display connection with another toolkit + (like Xt, GTK, etc.) + - Shortcut labels for special keys should now display + properly under WIN32. + - fl_set_fonts() did not reuse fonts. + - Fixed shortcut problem under WIN32 when the focus + window changes. + - "dead" keys should now work under X11. + - Fixes to make FLTK compile with GCC 2.95.2 + - FL_SHORTCUT fix for I18N. + - Fixed cut/paste problems under WIN32 + - FLUID now produces correct code for nested class + destructors. + - Nested windows should now redraw properly under WIN32. + - "table" is now static in fl_cursor.cxx + - Fl_Chart used the textcolor() and not the color() for + horizontal bar charts. + - Now set the input hint for TWM and TWM-derived window + managers. + - Now look for TrueColor visual if FLTK is compiled with + USE_COLORMAP == 0. + - Fl_Scrollbar could generate a divide-by-0 error if the + min and max values were the same. + - Fl_Menu_::remove() now removes whole submenus if + needed. + - Scrollbar buttons now draw themselves pushed in as + needed. + - Fixed the gl_overlay demo (and gl overlays in general) + when they are faked with no hardware and the window is + resized. + - Selections weren't shown in Fl_Browser widgets when an + item used the @B (background) format. + - Windows can now be resized by the program under X11 + for more window managers. + - OS/2 makeinclude updates. + - Added Fl.H required by an inline function in + Fl_Repeat_Button.H + - Fl_add_idle adds new functions to the end of the queue + ring, rather than the start, so they are executed in + the order added, and a callback that adds itself does + not prevent others from being called. + - FLUID lets you type in code that starts with '#' for + cpp directives. + - XBell() could be called before the X11 display was + opened, causing a segfault. + - Fixed Fl_Gl_Window::ortho() - Borland C++ doesn't + define GLint to "int", but instead to "long"... + - Fixed Fl_Browser scrollbars within an Fl_Scroll + widget. + - Fl_Output (and non-focused Fl_Input) now scroll in + response to position() + - Fl_Input now does not scroll horizontally if the + entire string will fit in the widget. + - Fl_Scrollbar didn't push the right arrow buttons when + you clicked outside the scroller. + - Now use WSAAsyncSelect() for better socket performance + with Fl::add_fd() + + +CHANGES SINCE FLTK 1.0.6 + + - Fixed Fl_Input_ bug under WIN32 - no longer stop accepting input + when one of the "Windows" keys is pressed. + - Now call TranslateEvent for all events under WIN32. + - Fixes for OpenBSD and NetBSD + - The FL_CURSOR_HAND cursor now uses the IDC_HAND cursor instead of + IDC_UPARROW under Windows 98 and 2000. + - Fl_Scrollbar now does a page-up/down when you click outside the + scroller. + - Fl_Window::show(0, NULL) causes core dump + - Fixed a compile-time error in fl_call_main.c for Borland C++. + - "fluid -c filename.fl" would try to open an X display if the + FLUID file contained an Fl_Browser widget. + - Fl_Browser now correctly measures items with @C or @B color + formatting commands. + - Fixed a bitmap drawing bug for WIN32 (bit reversal table was wrong) + - fl_xyz() dialogs now set a title in the title bar. + - fl_alert() sounds the bell under X11. + - fl_xyz() dialogs now call MessageBeep() under WIN32. + - Fl_Browser_ didn't draw the selection box with the inactive color + when the browser wasn't activated. + - Fl_Browser now responds to FL_KEYBOARD as well as FL_SHORTCUT. If + you subclass it to accept focus then keyboard navigation will work. + - Fl_Tile and Fl_Tabs do their callback when the user changes their + display. + - Made some of the private methods of Fl_Browser protected. + - Now set win_gravity correctly, this helps some X + window managers that use it position the window where + FLTK wants it to be. + - 0-width browsers crashed. + - Minor change: if the X window manager does not do + anything else with windows that don't have their + position specified, the windows appear centered in the + screen, rather than in the top-left corner. This + happened with modal windows under Irix 4Dwm. This + also causes windows to be centered when no window + manager is running, which might be useful for + installation gui programs? + - Clicking in an Fl_Input field the first time selects the entire + field. + - Clicking the middle mouse button in an Fl_Input field now inserts + the text at the indicated position instead of the cursor position. + - Drag-selecting text in an Fl_Input field now copies the text + automatically. + - Fl::flush() no longer calls the draw() method for invisible windows. + - Calling deactivate() on an invisible widget could cause an + infinite loop in some obscure cases. + - Added #pragma's for SGI C++ compilers - the 6.{23} X headers had + errors in them. + - Fl_Gl_Window::ortho() changed so that text and images + are not erased if the origin is off the left/bottom of the + window. + - Small change to Fl_Input so that a click that gives it + the focus also selects all the text. + - Fixed a slider drawing problem. + - You can now add/delete children of Fl_Tabs widgets whether or + not they are visible. + - Now embed woff options for SGI C++ compilers (gets rid of X11 + header warnings) + - draw_pixmap used a cast that the Digital UNIX C++ compiler didn't + like. + - The GLUT function key constants were off by one. + - The XPM reading code didn't handle RGB colors other than #rrggbb. + + +CHANGES SINCE FLTK 1.0.5 + + - Fl_win32.cxx defined WM_MOUSE_LEAVE instead of WM_MOUSELEAVE. + - Fl_get_key_win32.cxx needed to include + - gl_draw_pixmap.cxx needed a pointer cast for ANSI C++. + - Fl_Repeat_Button didn't always delete its timeout. + - Now keep track of the current OpenGL context; this provides + significant performance improvements for OpenGL applications + with a single context. + + +CHANGES SINCE FLTK 1.0.4 + + - Fl_Roller didn't handle a width and height of 0. + - filename_list() fix for FreeBSD. + - Fixed RPM install docos - needed "--install" option... + - Fl_Browser_ wouldn't draw the vertical scrollbar right away if it + added a horizontal one which covered the last line. + - Fl_Tabs problems - single-character labels don't show up (problem in + measure_tabs() or measure_label() methods?), and doesn't clear top + tab area before drawing tabs. + - Fl_Browser needs a destructor. + - fl_draw_label() quoted characters between 0x80 and 0xa0, which + caused problems for some programs using the WinANSI character set. + - FLUID didn't handle declared class destructors. + - Fixed another WIN32 cut/paste bug. + - Fl_Tabs didn't work properly when there was only 1 tab. + - Fl_Menu::add() didn't delete the old array. + - Fl_Repeat_Button didn't delete its timeout when disabled. + - fl_draw() would crash if no font was set (now defaults to + a 14-pixel Helvetica font) + - Can't forward declare classes; need to check for "class ", "struct ", + "union ", etc. See Bill's message + - Added #pragma around xlib.h for IRIX + - FL_KEYBOARD events have the correct x/y when sent to child X + windows. Note that if you worked around this bug by adjusting the + x/y yourself you will have to change your code. In addition all + events have the correct x/y when sent to the grab() widget. And + the code to do all this was simplified a lot. + - The XPM code didn't handle named colors with spaces in the names. + - Pressing ESCape closed the window with pointer focus, even if there + was a modal window open (now closes the modal window). + - FLUID no longer produces trigraphs accidentally in the image data. + - FLUID uses string constant concatenation to produce shorter image + data. + - The Fl_Group deletion code crashed if there was exactly one child + widget. + - Simulated overlays in single-buffered Fl_Gl_Windows now draw + correctly (though very slowly as it requires the entire window to + be redrawn to erase the overlay). This fix ported our Digital + Domain programs better to systems with no overlay hardware. + - Added support for extern "C" declarations in FLUID. + - Added Fl_Pack support to FLUID. + - Fixed the order of #include's in FLUID generated header files. + - Fixed detection of vsnprintf and snprintf under HP-UX 10.20 once + and for all. + - The checkers demo did not compile with GCC 2.95 + - FLUID didn't output virtual destructors properly. + - Added inline "make_visible()" method to Fl_Browser. + - Fl::wait() now returns immediately if any timeouts are + called. + - 16-bit XPM files are now properly handled. + - Fl_Window::resize() was missing FL_EXPORT (caused problems + with Windows DLLs) + - FLUID was writing extern declarations twice. + - New FLUID arrow key functionality: arrows move by one pixel, shift+arrow + resizes, ctrl+arrow steps by grid + + +CHANGES SINCE FLTK 1.0.3 + + - Documentation updates + - Fl_Browser::bottomline(size) didn't scroll to the bottom + if the second-to-last line was visible. + - fl_wait() didn't poll FDs properly for WIN32. + - Fixed DLL definitions for BC++. + - FLUID now handles nested classes properly. + - The "connect" demo now does a wait() for the PPP process + so that you aren't left with a lot of zombie processes. + - Fixed the FLTK colormap to use FF instead of F4 for full + intensity values. + - Minor change to scrollbar drawing code to match other + toolkits. + - New selections would cancel themselves out in WIN32. + - The header file links were broken in the IRIX + distributions. + - fl_elapsed() now always uses GetClockTick() for WIN32. + - fl_display is now initialized to GetModuleHandle(NULL) - + this fixes problems people had with Cygwin and MingW32. + - WinMain() is no longer compiled in with Cygwin and + MingW32; it wasn't being used for those compilers anyways. + - Added Solaris compiler options to configure script. + - Fl_Value_Input wouldn't update properly if you set the + value from a callback. + - Fl_Tile wouldn't resize if the resizeable widget was the + last child. + - Was missing #include and #include in + several files, which caused problems on some platforms. + - Fixed another case where Fl_Browser_ could get in an + infinite resizing loop. + - Fl_win32.cxx now includes to export missing + DLL symbols. + - FLUID didn't handle member functions that include the + scope operator. + - Fl_Chart was dividing by 0 if there were no data samples + or if they were all the same (min == max). + + +CHANGES SINCE FLTK 1.0.2 + + - XDBE is now enabled for IRIX 6.[234] as well as 6.5. + - FLUID didn't write the when() condition properly. + - Tab/space/backtab/backspace can be used to navigate + through menus. + - Changed $(DSONAME) in the src/Makefile to "libfltk.so.1 + libfltk.sl.1". + - Fl_Browser could read past the end of the string when + computing the item height. + - Fl_Browser could get in an infinite loop when checking to + see if scrollbars needed to be displayed. + - FLUID now honors the return type of the outermost widget. + This was a problem when substituting Fl_Group in an + Fl_Window widget. + - Fl_Menu_::copy() wasn't allocating a power of 2 for the + array size. + - FLWM would crash if fl_xmousewin was deleted. + - The fast_slow demo now uses output widgets. + - Timers under WIN32 were unreliable. + + +CHANGES SINCE FLTK 1.0.1 + + - Documentation updates + - The Visual C++ project files didn't include fl_add_idle.cxx. + - LIBRARY/DSO name inconsistencies in src/Makefile. + - src/Makefile didn't clean the DSO. + - The valuator demo now has only a single callback. + - The code looked for HAVE_SYS_SELECT_H, but the + config file uses HAVE_SYS_SELECT. + - Fl_Image redraw not quite right under X11 or WIN32 + - Problems with timeouts & cube demo under WIN32 + - FLUID problems with inline functions. + - Documentation fixes... + - Fl_Browser::item_height() didn't handle blank lines or + non-default fonts properly. + - FL/math.h didn't have #ifndef...#define...#endif guards + against multiple inclusion... + - Fl_Menu_::copy() fix - didn't allocate power of 2... + - Fl::damage() now remains true until all windows are actually + redrawn. + - Fl_Widget destructor, hide(), and deactivate() methods no longer + send FL_LEAVE, FL_RELEASE, or FL_UNFOCUS events to the widget + (which could cause applications to crash). + - FLUID now outputs symbolic names for align() and when(). + - Fixed select() to use maxfd + 1 instead of maxfd. + - Added "Fl::remove_fd(fd, when)" function so you can remove the + read and write callbacks separately. + - The Fl::add_fd() and Fl::add_timeout() arrays are now dynamically + allocated. + - FLUID didn't always turn the FL_SUBMENU flag on for submenu titles. + - The "extra code" in FLUID now is placed before the "o->end()" call + for Fl_Group and its derived classes. + - You can now set a FL_Window widget's class in FLUID to Fl_Group to + generate a function or class that builds part of a GUI (i.e. no window). + - FLUID now displays "Save file before exiting?" with the standard yes, + no, and cancel buttons rather than "Discard changes?". + - Fl_Menu_::add() now works with any type of menu, even one set with + the menu() method. + - The keypad keys were not always decoded properly under X11. + - Some pointers were not being turned off when widgets were deleted, + which caused some applications (like FLWM) to crash. + + +CHANGES SINCE FLTK 1.0 + + - Documentation fixes. + - Fl::check() didn't return the correct value, breaking a number + of applications. + - Fixed FLUID bug that caused styles patch to crash when you delete + a menu item. + - Updated valuators demo to put the values in the gui box. + - Fl_Browser_::item_height() didn't always compute the correct + value. + - Fixed the alignment of Fl_Choice text. + - Fixes for OS/2. + - Fl_Menu_Item::clear() didn't clear value. + - Added some changes to make FLTK work with Borland C++. + - ANSI C++ fixes. + - Plugged a memory leak in the fractal demo. + - Fl::add_timeout() didn't work under WIN32 with small values. + - The configure script and makefiles now define DSONAME and + use the static library for all example programs. diff --git a/mod/maxgui.mod/fltkmaxgui.mod/CREDITS b/mod/maxgui.mod/fltkmaxgui.mod/CREDITS new file mode 100644 index 0000000..0dee811 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/CREDITS @@ -0,0 +1,60 @@ +CREDITS - Fast Light Tool Kit (FLTK) Version 1.3.0 +-------------------------------------------------- + + This file lists the people responsible for the toolkit you + are now using. If you've looking for your name in lights + but we've forgotten you here, please use the report on the + following page, and we'll update this file accordingly: + + http://www.fltk.org/str.php + + +CORE DEVELOPERS + + The following people do the day-to-day development of FLTK: + + Fabien Costantini (fabien67@users.sf.net) + Craig P. Earls + Curtis Edwards (trilec@users.sourceforge.net) + Gustavo Hime (hime@users.sourceforge.net) + Talbot Hughes + Robert Kesterson (robertk@users.sourceforge.net) + Matthias Melcher (mm@robowerk.com) + James Dean Palmer (jamespalmer@users.sourceforge.net) + Vincent Penne (vincentp@users.sourceforge.net) + Bill Spitzak (spitzak@users.sourceforge.net) + Michael Sweet (easysw@users.sourceforge.net) + Carl Thompson (clip@users.sourceforge.net) + Nafees Bin Zafar (nafees@users.sourceforge.net) + + +OTHER CONTRIBUTORS + + The following people have contributed fixes or enhancements + for FLTK: + + Teun Burgers + Paul Chambers + Stephen Davies + Yuri D'Elia + Greg Ercolano + Yuri Fedorchenko + George Garvey + Duncan Gibson + Manolo Gouy + Mikael Hultgren + Stuart Levy + Howard Lightstone + Mike Lindner + Alexander Mai + Alexander Rabi + James Roth + Albrecht Schlosser + Andrea Suatoni + Michael Surette + Paul Sydney + Aaron Ucko + Emanuele Vicentini + Josef Vitu + Jim Wilson + Ken Yarnall diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Enumerations.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Enumerations.H new file mode 100644 index 0000000..a503aa8 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Enumerations.H @@ -0,0 +1,920 @@ +// +// "$Id: Enumerations.H 7903 2010-11-28 21:06:39Z matt $" +// +// Enumerations for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/** \file + * This file contains type definitions and general enumerations. + */ + +#ifndef Fl_Enumerations_H +#define Fl_Enumerations_H + +# include "Fl_Export.H" +# include "fl_types.h" + +/** \name Version Numbers + + FLTK defines some constants to help the programmer to + find out, for which FLTK version a program is compiled. + + The following constants are defined: + */ +/*@{*/ + +/** + * The major release version of this FLTK library. + \sa FL_VERSION + */ +#define FL_MAJOR_VERSION 1 + +/** + * The minor release version for this library. + * + * FLTK remains mostly source-code compatible between minor version changes. + */ +#define FL_MINOR_VERSION 3 + +/** + * The patch version for this library. + * + * FLTK remains binary compatible between patches. + */ +#define FL_PATCH_VERSION 0 + +/** + * The FLTK version number as a \em double. + * + * This is changed slightly from the beta versions + * because the old "const double" definition would not allow for conditional + * compilation... + * + * FL_VERSION is a double that describes the major and minor version numbers. + * Version 1.1 is actually stored as 1.01 to allow for more than 9 minor + * releases. + * + * The FL_MAJOR_VERSION, FL_MINOR_VERSION, and FL_PATCH_VERSION constants + * give the integral values for the major, minor, and patch releases + * respectively. + */ +#define FL_VERSION ((double)FL_MAJOR_VERSION + \ + (double)FL_MINOR_VERSION * 0.01 + \ + (double)FL_PATCH_VERSION * 0.0001) + +/*@}*/ // group: Version Numbers + +/** + * Every time a user moves the mouse pointer, clicks a button, + * or presses a key, an event is generated and sent to your + * application. Events can also come from other programs like the + * window manager. + * + * Events are identified by the integer argument passed to the + * Fl_Widget::handle() virtual method. Other information about the + * most recent event is stored in static locations and acquired by + * calling the Fl::event_*() methods. This static information remains + * valid until the next event is read from the window system, so it + * is ok to look at it outside of the handle() method. + * + * \sa Fl::event_text(), Fl::event_key(), class Fl:: + */ +enum Fl_Event { // events + /** No event. */ + FL_NO_EVENT = 0, + + /** A mouse button has gone down with the mouse pointing at this + * widget. You can find out what button by calling Fl::event_button(). + * You find out the mouse position by calling Fl::event_x() and + * Fl::event_y(). + * + * A widget indicates that it "wants" the mouse click by returning non-zero + * from its Fl_Widget::handle() method. It will then become the + * Fl::pushed() widget and will get FL_DRAG and the matching FL_RELEASE events. + * If Fl_Widget::handle() returns zero then FLTK will try sending the FL_PUSH + * to another widget. + */ + FL_PUSH = 1, + + /** A mouse button has been released. You can find out what button by + * calling Fl::event_button(). + * + * In order to receive the FL_RELEASE event, the widget must return + * non-zero when handling FL_PUSH. + */ + FL_RELEASE = 2, + + /** The mouse has been moved to point at this widget. This can + * be used for highlighting feedback. If a widget wants to + * highlight or otherwise track the mouse, it indicates this by + * returning non-zero from its handle() method. It then + * becomes the Fl::belowmouse() widget and will receive + * FL_MOVE and FL_LEAVE events. + */ + FL_ENTER = 3, + + /** The mouse has moved out of the widget. + * In order to receive the FL_LEAVE event, the widget must + * return non-zero when handling FL_ENTER. + */ + FL_LEAVE = 4, + + /** The mouse has moved with a button held down. The current button state + * is in Fl::event_state(). The mouse position is in Fl::event_x() and + * Fl::event_y(). + * + * In order to receive FL_DRAG events, the widget must return non-zero + * when handling FL_PUSH. + */ + FL_DRAG = 5, + + /** This indicates an attempt to give a widget the keyboard focus. + * + * If a widget wants the focus, it should change itself to display the + * fact that it has the focus, and return non-zero from its handle() method. + * It then becomes the Fl::focus() widget and gets FL_KEYDOWN, FL_KEYUP, + * and FL_UNFOCUS events. + * + * The focus will change either because the window manager changed which + * window gets the focus, or because the user tried to navigate using tab, + * arrows, or other keys. You can check Fl::event_key() to figure out why + * it moved. For navigation it will be the key pressed and interaction + * with the window manager it will be zero. + */ + FL_FOCUS = 6, + + /** This event is sent to the previous Fl::focus() widget when another + * widget gets the focus or the window loses focus. + */ + FL_UNFOCUS = 7, + + /** A key was pressed or released. The key can be found in Fl::event_key(). + * The text that the key should insert can be found with Fl::event_text() + * and its length is in Fl::event_length(). If you use the key handle() + * should return 1. If you return zero then FLTK assumes you ignored the + * key and will then attempt to send it to a parent widget. If none of + * them want it, it will change the event into a FL_SHORTCUT event. + * + * To receive FL_KEYBOARD events you must also respond to the FL_FOCUS + * and FL_UNFOCUS events. + * + * If you are writing a text-editing widget you may also want to call + * the Fl::compose() function to translate individual keystrokes into + * foreign characters. + * + * FL_KEYUP events are sent to the widget that currently has focus. This + * is not necessarily the same widget that received the corresponding + * FL_KEYDOWN event because focus may have changed between events. + */ + FL_KEYDOWN = 8, + + /** Equvalent to FL_KEYDOWN. + * \see FL_KEYDOWN + */ + FL_KEYBOARD = 8, + + /** Key release event. + * \see FL_KEYDOWN + */ + FL_KEYUP = 9, + + /** The user clicked the close button of a window. + * This event is used internally only to trigger the callback of + * Fl_Window derived classed. The default callback closes the + * window calling Fl_Window::hide(). + */ + FL_CLOSE = 10, + + /** The mouse has moved without any mouse buttons held down. + * This event is sent to the Fl::belowmouse() widget. + * + * In order to receive FL_MOVE events, the widget must return + * non-zero when handling FL_ENTER. + */ + FL_MOVE = 11, + + /** If the Fl::focus() widget is zero or ignores an FL_KEYBOARD + * event then FLTK tries sending this event to every widget it + * can, until one of them returns non-zero. FL_SHORTCUT is first + * sent to the Fl::belowmouse() widget, then its parents and siblings, + * and eventually to every widget in the window, trying to find an + * object that returns non-zero. FLTK tries really hard to not to ignore + * any keystrokes! + * + * You can also make "global" shortcuts by using Fl::add_handler(). A + * global shortcut will work no matter what windows are displayed or + * which one has the focus. + */ + FL_SHORTCUT = 12, + + /** This widget is no longer active, due to Fl_Widget::deactivate() + * being called on it or one of its parents. Fl_Widget::active() may + * still be true after this, the widget is only active if Fl_Widget::active() + * is true on it and all its parents (use Fl_Widget::active_r() to check this). + */ + FL_DEACTIVATE = 13, + + /** This widget is now active, due to Fl_Widget::activate() being + * called on it or one of its parents. + */ + FL_ACTIVATE = 14, + + /** This widget is no longer visible, due to Fl_Widget::hide() being + * called on it or one of its parents, or due to a parent window being + * minimized. Fl_Widget::visible() may still be true after this, but the + * widget is visible only if visible() is true for it and all its + * parents (use Fl_Widget::visible_r() to check this). + */ + FL_HIDE = 15, + + /** This widget is visible again, due to Fl_Widget::show() being called on + * it or one of its parents, or due to a parent window being restored. + * Child Fl_Windows respond to this by actually creating the window if not + * done already, so if you subclass a window, be sure to pass FL_SHOW + * to the base class Fl_Widget::handle() method! + */ + FL_SHOW = 16, + + /** You should get this event some time after you call Fl::paste(). + * The contents of Fl::event_text() is the text to insert and the number + * of characters is in Fl::event_length(). + */ + FL_PASTE = 17, + + /** The Fl::selection_owner() will get this event before the selection is + * moved to another widget. This indicates that some other widget or program + * has claimed the selection. Motif programs used this to clear the selection + * indication. Most modern programs ignore this. + */ + FL_SELECTIONCLEAR = 18, + + /** The user has moved the mouse wheel. The Fl::event_dx() and Fl::event_dy() + * methods can be used to find the amount to scroll horizontally and vertically. + */ + FL_MOUSEWHEEL = 19, + + /** The mouse has been moved to point at this widget. A widget that is + * interested in receiving drag'n'drop data must return 1 to receive + * FL_DND_DRAG, FL_DND_LEAVE and FL_DND_RELEASE events. + */ + FL_DND_ENTER = 20, + + /** The mouse has been moved inside a widget while dragging data. A + * widget that is interested in receiving drag'n'drop data should + * indicate the possible drop position. + */ + FL_DND_DRAG = 21, + + /** The mouse has moved out of the widget. + */ + FL_DND_LEAVE = 22, + + /** The user has released the mouse button dropping data into the widget. + * If the widget returns 1, it will receive the data in the immediately + * following FL_PASTE event. + */ + FL_DND_RELEASE = 23 +}; + +/** \name When Conditions */ +/*@{*/ +/** These constants determine when a callback is performed. + * + * \sa Fl_Widget::when(); + * \todo doxygen comments for values are incomplete and maybe wrong or unclear + */ +enum Fl_When { // Fl_Widget::when(): + FL_WHEN_NEVER = 0, ///< Never call the callback + FL_WHEN_CHANGED = 1, ///< Do the callback only when the widget value changes + FL_WHEN_NOT_CHANGED = 2, ///< Do the callback whenever the user interacts with the widget + FL_WHEN_RELEASE = 4, ///< Do the callback when the button or key is released and the value changes + FL_WHEN_RELEASE_ALWAYS= 6, ///< Do the callback when the button or key is released, even if the value doesn't change + FL_WHEN_ENTER_KEY = 8, ///< Do the callback when the user presses the ENTER key and the value changes + FL_WHEN_ENTER_KEY_ALWAYS=10, ///< Do the callback when the user presses the ENTER key, even if the value doesn't change + FL_WHEN_ENTER_KEY_CHANGED=11 ///< ? +}; + +/*@}*/ // group: When Conditions + +/** \name Mouse and Keyboard Events + + This and the following constants define the non-ASCII keys on the + keyboard for FL_KEYBOARD and FL_SHORTCUT events. + + \todo FL_Button and FL_key... constants could be structured better + (use an enum or some doxygen grouping ?) + + \sa Fl::event_key() and Fl::get_key(int) (use ascii letters for all other keys): + */ + +/*@{*/ + +// FIXME: These codes collide with valid Unicode keys + +#define FL_Button 0xfee8 ///< A mouse button; use Fl_Button + n for mouse button n. +#define FL_BackSpace 0xff08 ///< The backspace key. +#define FL_Tab 0xff09 ///< The tab key. +#define FL_Enter 0xff0d ///< The enter key. +#define FL_Pause 0xff13 ///< The pause key. +#define FL_Scroll_Lock 0xff14 ///< The scroll lock key. +#define FL_Escape 0xff1b ///< The escape key. +#define FL_Home 0xff50 ///< The home key. +#define FL_Left 0xff51 ///< The left arrow key. +#define FL_Up 0xff52 ///< The up arrow key. +#define FL_Right 0xff53 ///< The right arrow key. +#define FL_Down 0xff54 ///< The down arrow key. +#define FL_Page_Up 0xff55 ///< The page-up key. +#define FL_Page_Down 0xff56 ///< The page-down key. +#define FL_End 0xff57 ///< The end key. +#define FL_Print 0xff61 ///< The print (or print-screen) key. +#define FL_Insert 0xff63 ///< The insert key. +#define FL_Menu 0xff67 ///< The menu key. +#define FL_Help 0xff68 ///< The 'help' key on Mac keyboards +#define FL_Num_Lock 0xff7f ///< The num lock key. +#define FL_KP 0xff80 ///< One of the keypad numbers; use FL_KP + n for number n. +#define FL_KP_Enter 0xff8d ///< The enter key on the keypad, same as Fl_KP+'\\r'. +#define FL_KP_Last 0xffbd ///< The last keypad key; use to range-check keypad. +#define FL_F 0xffbd ///< One of the function keys; use FL_F + n for function key n. +#define FL_F_Last 0xffe0 ///< The last function key; use to range-check function keys. +#define FL_Shift_L 0xffe1 ///< The lefthand shift key. +#define FL_Shift_R 0xffe2 ///< The righthand shift key. +#define FL_Control_L 0xffe3 ///< The lefthand control key. +#define FL_Control_R 0xffe4 ///< The righthand control key. +#define FL_Caps_Lock 0xffe5 ///< The caps lock key. +#define FL_Meta_L 0xffe7 ///< The left meta/Windows key. +#define FL_Meta_R 0xffe8 ///< The right meta/Windows key. +#define FL_Alt_L 0xffe9 ///< The left alt key. +#define FL_Alt_R 0xffea ///< The right alt key. +#define FL_Delete 0xffff ///< The delete key. + +/*@}*/ // group: Mouse and Keyboard Events + +/** \name Mouse Buttons + + These constants define the button numbers for FL_PUSH and FL_RELEASE events. + + \sa Fl::event_button() +*/ + +/*@{*/ + +#define FL_LEFT_MOUSE 1 ///< The left mouse button +#define FL_MIDDLE_MOUSE 2 ///< The middle mouse button +#define FL_RIGHT_MOUSE 3 ///< The right mouse button + +/*@}*/ // group: Mouse Buttons + + +/** \name Event States + + The following constants define bits in the Fl::event_state() value. +*/ + +/*@{*/ // group: Event States + +// FIXME: it would be nice to have the modifiers in the upper 8 bit so that +// a unicode ke (24bit) can be sent as an unsigned with the modifiers. + +#define FL_SHIFT 0x00010000 ///< One of the shift keys is down +#define FL_CAPS_LOCK 0x00020000 ///< The caps lock is on +#define FL_CTRL 0x00040000 ///< One of the ctrl keys is down +#define FL_ALT 0x00080000 ///< One of the alt keys is down +#define FL_NUM_LOCK 0x00100000 ///< The num lock is on + // most X servers do this? +#define FL_META 0x00400000 ///< One of the meta/Windows keys is down + // correct for XFree86 +#define FL_SCROLL_LOCK 0x00800000 ///< The scroll lock is on + // correct for XFree86 +#define FL_BUTTON1 0x01000000 ///< Mouse button 1 is pushed +#define FL_BUTTON2 0x02000000 ///< Mouse button 2 is pushed +#define FL_BUTTON3 0x04000000 ///< Mouse button 3 is pushed +#define FL_BUTTONS 0x7f000000 ///< Any mouse button is pushed +#define FL_BUTTON(n) (0x00800000<<(n)) ///< Mouse button n (n > 0) is pushed + +#define FL_KEY_MASK 0x0000ffff ///< All keys are 16 bit for now + // FIXME: Unicode needs 24 bits! + +#ifdef __APPLE__ +# define FL_COMMAND FL_META ///< An alias for FL_CTRL on WIN32 and X11, or FL_META on MacOS X +# define FL_CONTROL FL_CTRL ///< An alias for FL_META on WIN32 and X11, or FL_META on MacOS X +#else +# define FL_COMMAND FL_CTRL ///< An alias for FL_CTRL on WIN32 and X11, or FL_META on MacOS X +# define FL_CONTROL FL_META ///< An alias for FL_META on WIN32 and X11, or FL_META on MacOS X +#endif // __APPLE__ + +/*@}*/ // group: Event States + +/** \name Box Types + \brief FLTK standard box types + + This enum defines the standard box types included with FLTK. + + FL_NO_BOX means nothing is drawn at all, so whatever is already + on the screen remains. The FL_..._FRAME types only draw their edges, + leaving the interior unchanged. The blue color in Figure 1 + is the area that is not drawn by the frame types. + + \image html boxtypes.gif "Figure 1: FLTK standard box types" + \image latex boxtypes.eps "FLTK standard box types" width=10cm + \todo Description of boxtypes is incomplete. + See below for the defined enum Fl_Boxtype. + \see src/Fl_get_system_colors.cxx +*/ +/*@{*/ +enum Fl_Boxtype { // boxtypes (if you change these you must fix fl_boxtype.C): + + FL_NO_BOX = 0, ///< nothing is drawn at all, this box is invisible + FL_FLAT_BOX, ///< a flat box + FL_UP_BOX, ///< see figure 1 + FL_DOWN_BOX, ///< see figure 1 + FL_UP_FRAME, ///< see figure 1 + FL_DOWN_FRAME, ///< see figure 1 + FL_THIN_UP_BOX, ///< see figure 1 + FL_THIN_DOWN_BOX, ///< see figure 1 + FL_THIN_UP_FRAME, ///< see figure 1 + FL_THIN_DOWN_FRAME, ///< see figure 1 + FL_ENGRAVED_BOX, ///< see figure 1 + FL_EMBOSSED_BOX, ///< see figure 1 + FL_ENGRAVED_FRAME, ///< see figure 1 + FL_EMBOSSED_FRAME, ///< see figure 1 + FL_BORDER_BOX, ///< see figure 1 + _FL_SHADOW_BOX, ///< see figure 1 + FL_BORDER_FRAME, ///< see figure 1 + _FL_SHADOW_FRAME, ///< see figure 1 + _FL_ROUNDED_BOX, ///< see figure 1 + _FL_RSHADOW_BOX, ///< see figure 1 + _FL_ROUNDED_FRAME, ///< see figure 1 + _FL_RFLAT_BOX, ///< see figure 1 + _FL_ROUND_UP_BOX, ///< see figure 1 + _FL_ROUND_DOWN_BOX, ///< see figure 1 + _FL_DIAMOND_UP_BOX, ///< see figure 1 + _FL_DIAMOND_DOWN_BOX, ///< see figure 1 + _FL_OVAL_BOX, ///< see figure 1 + _FL_OSHADOW_BOX, ///< see figure 1 + _FL_OVAL_FRAME, ///< see figure 1 + _FL_OFLAT_BOX, ///< see figure 1 + _FL_PLASTIC_UP_BOX, ///< plastic version of FL_UP_BOX + _FL_PLASTIC_DOWN_BOX, ///< plastic version of FL_DOWN_BOX + _FL_PLASTIC_UP_FRAME, ///< plastic version of FL_UP_FRAME + _FL_PLASTIC_DOWN_FRAME, ///< plastic version of FL_DOWN_FRAME + _FL_PLASTIC_THIN_UP_BOX, ///< plastic version of FL_THIN_UP_BOX + _FL_PLASTIC_THIN_DOWN_BOX, ///< plastic version of FL_THIN_DOWN_BOX + _FL_PLASTIC_ROUND_UP_BOX, ///< plastic version of FL_ROUND_UP_BOX + _FL_PLASTIC_ROUND_DOWN_BOX, ///< plastic version of FL_ROUND_DOWN_BOX + _FL_GTK_UP_BOX, ///< gtk+ version of FL_UP_BOX + _FL_GTK_DOWN_BOX, ///< gtk+ version of FL_DOWN_BOX + _FL_GTK_UP_FRAME, ///< gtk+ version of FL_UP_FRAME + _FL_GTK_DOWN_FRAME, ///< gtk+ version of FL_DOWN_RAME + _FL_GTK_THIN_UP_BOX, ///< gtk+ version of FL_THIN_UP_BOX + _FL_GTK_THIN_DOWN_BOX, ///< gtk+ version of FL_THIN_DOWN_BOX + _FL_GTK_THIN_UP_FRAME, ///< gtk+ version of FL_UP_FRAME + _FL_GTK_THIN_DOWN_FRAME, ///< gtk+ version of FL_THIN_DOWN_FRAME + _FL_GTK_ROUND_UP_BOX, ///< gtk+ version of FL_ROUND_UP_BOX + _FL_GTK_ROUND_DOWN_BOX, ///< gtk+ version of FL_ROUND_DOWN_BOX + FL_FREE_BOXTYPE ///< the first free box type for creation of new box types +}; +extern FL_EXPORT Fl_Boxtype fl_define_FL_ROUND_UP_BOX(); +#define FL_ROUND_UP_BOX fl_define_FL_ROUND_UP_BOX() +#define FL_ROUND_DOWN_BOX (Fl_Boxtype)(fl_define_FL_ROUND_UP_BOX()+1) +extern FL_EXPORT Fl_Boxtype fl_define_FL_SHADOW_BOX(); +#define FL_SHADOW_BOX fl_define_FL_SHADOW_BOX() +#define FL_SHADOW_FRAME (Fl_Boxtype)(fl_define_FL_SHADOW_BOX()+2) +extern FL_EXPORT Fl_Boxtype fl_define_FL_ROUNDED_BOX(); +#define FL_ROUNDED_BOX fl_define_FL_ROUNDED_BOX() +#define FL_ROUNDED_FRAME (Fl_Boxtype)(fl_define_FL_ROUNDED_BOX()+2) +extern FL_EXPORT Fl_Boxtype fl_define_FL_RFLAT_BOX(); +#define FL_RFLAT_BOX fl_define_FL_RFLAT_BOX() +extern FL_EXPORT Fl_Boxtype fl_define_FL_RSHADOW_BOX(); +#define FL_RSHADOW_BOX fl_define_FL_RSHADOW_BOX() +extern FL_EXPORT Fl_Boxtype fl_define_FL_DIAMOND_BOX(); +#define FL_DIAMOND_UP_BOX fl_define_FL_DIAMOND_BOX() +#define FL_DIAMOND_DOWN_BOX (Fl_Boxtype)(fl_define_FL_DIAMOND_BOX()+1) +extern FL_EXPORT Fl_Boxtype fl_define_FL_OVAL_BOX(); +#define FL_OVAL_BOX fl_define_FL_OVAL_BOX() +#define FL_OSHADOW_BOX (Fl_Boxtype)(fl_define_FL_OVAL_BOX()+1) +#define FL_OVAL_FRAME (Fl_Boxtype)(fl_define_FL_OVAL_BOX()+2) +#define FL_OFLAT_BOX (Fl_Boxtype)(fl_define_FL_OVAL_BOX()+3) + +extern FL_EXPORT Fl_Boxtype fl_define_FL_PLASTIC_UP_BOX(); +#define FL_PLASTIC_UP_BOX fl_define_FL_PLASTIC_UP_BOX() +#define FL_PLASTIC_DOWN_BOX (Fl_Boxtype)(fl_define_FL_PLASTIC_UP_BOX()+1) +#define FL_PLASTIC_UP_FRAME (Fl_Boxtype)(fl_define_FL_PLASTIC_UP_BOX()+2) +#define FL_PLASTIC_DOWN_FRAME (Fl_Boxtype)(fl_define_FL_PLASTIC_UP_BOX()+3) +#define FL_PLASTIC_THIN_UP_BOX (Fl_Boxtype)(fl_define_FL_PLASTIC_UP_BOX()+4) +#define FL_PLASTIC_THIN_DOWN_BOX (Fl_Boxtype)(fl_define_FL_PLASTIC_UP_BOX()+5) +#define FL_PLASTIC_ROUND_UP_BOX (Fl_Boxtype)(fl_define_FL_PLASTIC_UP_BOX()+6) +#define FL_PLASTIC_ROUND_DOWN_BOX (Fl_Boxtype)(fl_define_FL_PLASTIC_UP_BOX()+7) + +extern FL_EXPORT Fl_Boxtype fl_define_FL_GTK_UP_BOX(); +#define FL_GTK_UP_BOX fl_define_FL_GTK_UP_BOX() +#define FL_GTK_DOWN_BOX (Fl_Boxtype)(fl_define_FL_GTK_UP_BOX()+1) +#define FL_GTK_UP_FRAME (Fl_Boxtype)(fl_define_FL_GTK_UP_BOX()+2) +#define FL_GTK_DOWN_FRAME (Fl_Boxtype)(fl_define_FL_GTK_UP_BOX()+3) +#define FL_GTK_THIN_UP_BOX (Fl_Boxtype)(fl_define_FL_GTK_UP_BOX()+4) +#define FL_GTK_THIN_DOWN_BOX (Fl_Boxtype)(fl_define_FL_GTK_UP_BOX()+5) +#define FL_GTK_THIN_UP_FRAME (Fl_Boxtype)(fl_define_FL_GTK_UP_BOX()+6) +#define FL_GTK_THIN_DOWN_FRAME (Fl_Boxtype)(fl_define_FL_GTK_UP_BOX()+7) +#define FL_GTK_ROUND_UP_BOX (Fl_Boxtype)(fl_define_FL_GTK_UP_BOX()+8) +#define FL_GTK_ROUND_DOWN_BOX (Fl_Boxtype)(fl_define_FL_GTK_UP_BOX()+9) + +// conversions of box types to other boxtypes: +/** + Get the filled version of a frame. + If no filled version of a given frame exists, the behavior of this function + is undefined and some random box or frame is returned, + */ +inline Fl_Boxtype fl_box(Fl_Boxtype b) { + return (Fl_Boxtype)((b1)?b:(b-2)); +} +/** + Get the "pressed" or "down" version of a box. + If no "down" version of a given box exists, the behavior of this function + is undefined and some random box or frame is returned, + */ +inline Fl_Boxtype fl_down(Fl_Boxtype b) { + return (Fl_Boxtype)((b + Fl_Color => 0xrrggbbii + | | | | + | | | +--- index between 0 and 255 + | | +----- blue color component (8 bit) + | +------- green component (8 bit) + +--------- red component (8 bit) + + + A color can have either an index or an rgb value. Colors with rgb set + and an index >0 are reserved for special use. + + */ + +typedef unsigned int Fl_Color; + +// Standard colors. These are used as default colors in widgets and altered as necessary +const Fl_Color FL_FOREGROUND_COLOR = 0; ///< the default foreground color (0) used for labels and text +const Fl_Color FL_BACKGROUND2_COLOR = 7; ///< the default background color for text, list, and valuator widgets +const Fl_Color FL_INACTIVE_COLOR = 8; ///< the inactive foreground color +const Fl_Color FL_SELECTION_COLOR = 15; ///< the default selection/highlight color + + // boxtypes generally limit themselves to these colors so + // the whole ramp is not allocated: + +const Fl_Color FL_GRAY0 = 32; // 'A' +const Fl_Color FL_DARK3 = 39; // 'H' +const Fl_Color FL_DARK2 = 45; // 'N' +const Fl_Color FL_DARK1 = 47; // 'P' +const Fl_Color FL_BACKGROUND_COLOR = 49; // 'R' default background color +const Fl_Color FL_LIGHT1 = 50; // 'S' +const Fl_Color FL_LIGHT2 = 52; // 'U' +const Fl_Color FL_LIGHT3 = 54; // 'W' + + // FLTK provides a 5x8x5 color cube that is used with colormap visuals + +const Fl_Color FL_BLACK = 56; +const Fl_Color FL_RED = 88; +const Fl_Color FL_GREEN = 63; +const Fl_Color FL_YELLOW = 95; +const Fl_Color FL_BLUE = 216; +const Fl_Color FL_MAGENTA = 248; +const Fl_Color FL_CYAN = 223; +const Fl_Color FL_DARK_RED = 72; + +const Fl_Color FL_DARK_GREEN = 60; +const Fl_Color FL_DARK_YELLOW = 76; +const Fl_Color FL_DARK_BLUE = 136; +const Fl_Color FL_DARK_MAGENTA = 152; +const Fl_Color FL_DARK_CYAN = 140; + +const Fl_Color FL_WHITE = 255; + + +#define FL_FREE_COLOR (Fl_Color)16 +#define FL_NUM_FREE_COLOR 16 +#define FL_GRAY_RAMP (Fl_Color)32 +#define FL_NUM_GRAY 24 +#define FL_GRAY FL_BACKGROUND_COLOR +#define FL_COLOR_CUBE (Fl_Color)56 +#define FL_NUM_RED 5 +#define FL_NUM_GREEN 8 +#define FL_NUM_BLUE 5 + +FL_EXPORT Fl_Color fl_inactive(Fl_Color c); + +FL_EXPORT Fl_Color fl_contrast(Fl_Color fg, Fl_Color bg); + +FL_EXPORT Fl_Color fl_color_average(Fl_Color c1, Fl_Color c2, float weight); + +inline Fl_Color fl_lighter(Fl_Color c) { return fl_color_average(c, FL_WHITE, .67f); } + +inline Fl_Color fl_darker(Fl_Color c) { return fl_color_average(c, FL_BLACK, .67f); } + +/** return 24-bit color value closest to \p r, \p g, \p b. */ +inline Fl_Color fl_rgb_color(uchar r, uchar g, uchar b) { + if (!r && !g && !b) return FL_BLACK; + else return (Fl_Color)(((((r << 8) | g) << 8) | b) << 8); +} + +/** return 24-bit color value closest to \p grayscale */ +inline Fl_Color fl_rgb_color(uchar g) { + if (!g) return FL_BLACK; + else return (Fl_Color)(((((g << 8) | g) << 8) | g) << 8); +} + +inline Fl_Color fl_gray_ramp(int i) {return (Fl_Color)(i+FL_GRAY_RAMP);} + +inline Fl_Color fl_color_cube(int r, int g, int b) { + return (Fl_Color)((b*FL_NUM_RED + r) * FL_NUM_GREEN + g + FL_COLOR_CUBE);} + +//*@}*/ // group: Colors + +/** \name Cursors + + The following constants define the mouse cursors that are available in FLTK. + + The double-headed arrows are bitmaps provided by FLTK on X, the others + are provided by system-defined cursors. + + \todo enum Fl_Cursor needs some more comments for values + (and maybe an image), see Fl/Enumerations.H +*/ +enum Fl_Cursor { // standard cursors + FL_CURSOR_DEFAULT = 0, + FL_CURSOR_ARROW = 35, + FL_CURSOR_CROSS = 66, + FL_CURSOR_WAIT = 76, + FL_CURSOR_INSERT = 77, + FL_CURSOR_HAND = 31, + FL_CURSOR_HELP = 47, + FL_CURSOR_MOVE = 27, + // fltk provides bitmaps for these: + FL_CURSOR_NS = 78, + FL_CURSOR_WE = 79, + FL_CURSOR_NWSE = 80, + FL_CURSOR_NESW = 81, + FL_CURSOR_NONE = 255, + // for back compatability (non MSWindows ones): + FL_CURSOR_N = 70, + FL_CURSOR_NE = 69, + FL_CURSOR_E = 49, + FL_CURSOR_SE = 8, + FL_CURSOR_S = 9, + FL_CURSOR_SW = 7, + FL_CURSOR_W = 36, + FL_CURSOR_NW = 68 + //FL_CURSOR_NS = 22, + //FL_CURSOR_WE = 55, +}; + +enum { // values for "when" passed to Fl::add_fd() + FL_READ = 1, + FL_WRITE = 4, + FL_EXCEPT = 8 +}; + +enum Fl_Mode { // visual types and Fl_Gl_Window::mode() (values match Glut) + FL_RGB = 0, + FL_INDEX = 1, + FL_SINGLE = 0, + FL_DOUBLE = 2, + FL_ACCUM = 4, + FL_ALPHA = 8, + FL_DEPTH = 16, + FL_STENCIL = 32, + FL_RGB8 = 64, + FL_MULTISAMPLE= 128, + FL_STEREO = 256, + FL_FAKE_SINGLE = 512 // Fake single buffered windows using double-buffer +}; + +// image alpha blending + +#define FL_IMAGE_WITH_ALPHA 0x40000000 + +// damage masks + +enum Fl_Damage { + FL_DAMAGE_CHILD = 0x01, + FL_DAMAGE_EXPOSE = 0x02, + FL_DAMAGE_SCROLL = 0x04, + FL_DAMAGE_OVERLAY = 0x08, + FL_DAMAGE_USER1 = 0x10, + FL_DAMAGE_USER2 = 0x20, + FL_DAMAGE_ALL = 0x80 +}; + +// FLTK 1.0.x compatibility definitions... +# ifdef FLTK_1_0_COMPAT +# define contrast fl_contrast +# define down fl_down +# define frame fl_frame +# define inactive fl_inactive +# endif // FLTK_1_0_COMPAT + +#endif + +// +// End of "$Id: Enumerations.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl.H new file mode 100644 index 0000000..6f083f2 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl.H @@ -0,0 +1,1117 @@ +// +// "$Id: Fl.H 7903 2010-11-28 21:06:39Z matt $" +// +// Main header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl static class. + */ + +#ifndef Fl_H +# define Fl_H + +#ifdef HAVE_CAIRO +# include +#endif + +# include "fl_utf8.h" +# include "Enumerations.H" +# ifndef Fl_Object +# define Fl_Object Fl_Widget /**< for back compatibility - use Fl_Widget! */ +# endif + +# ifdef check +# undef check +# endif + + +class Fl_Widget; +class Fl_Window; +class Fl_Image; +struct Fl_Label; + + +/** \defgroup callback_functions Callback function typedefs + \brief Typedefs for callback or handler functions passed as function parameters. + + FLTK uses callback functions as parameters for some function calls, e.g. to + set up global event handlers (Fl::add_handler()), to add a timeout handler + (Fl::add_timeout()), and many more. + + The typedefs defined in this group describe the function parameters used to set + up or clear the callback functions and should also be referenced to define the + callback function to handle such events in the user's code. + + \see Fl::add_handler(), Fl::add_timeout(), Fl::repeat_timeout(), + Fl::remove_timeout() and others + @{ */ + +/** signature of some label drawing functions passed as parameters */ +typedef void (Fl_Label_Draw_F)(const Fl_Label *label, int x, int y, int w, int h, Fl_Align align); + +/** signature of some label measurement functions passed as parameters */ +typedef void (Fl_Label_Measure_F)(const Fl_Label *label, int &width, int &height); + +/** signature of some box drawing functions passed as parameters */ +typedef void (Fl_Box_Draw_F)(int x, int y, int w, int h, Fl_Color color); + +/** signature of some timeout callback functions passed as parameters */ +typedef void (*Fl_Timeout_Handler)(void *data); + +/** signature of some wakeup callback functions passed as parameters */ +typedef void (*Fl_Awake_Handler)(void *data); + +/** signature of add_idle callback functions passed as parameters */ +typedef void (*Fl_Idle_Handler)(void *data); + +/** signature of set_idle callback functions passed as parameters */ +typedef void (*Fl_Old_Idle_Handler)(); + +/** signature of add_fd functions passed as parameters */ +typedef void (*Fl_FD_Handler)(int fd, void *data); + +/** signature of add_handler functions passed as parameters */ +typedef int (*Fl_Event_Handler)(int event); + +/** signature of set_abort functions passed as parameters */ +typedef void (*Fl_Abort_Handler)(const char *format,...); + +/** signature of set_atclose functions passed as parameters */ +typedef void (*Fl_Atclose_Handler)(Fl_Window *window, void *data); + +/** signature of args functions passed as parameters */ +typedef int (*Fl_Args_Handler)(int argc, char **argv, int &i); + +/** @} */ /* group callback_functions */ + + +/** + The Fl is the FLTK global (static) containing + state information and global methods for the current application. +*/ +class FL_EXPORT Fl { + Fl() {}; // no constructor! + +public: // should be private! +#ifndef FL_DOXYGEN + static int e_number; + static int e_x; + static int e_y; + static int e_x_root; + static int e_y_root; + static int e_dx; + static int e_dy; + static int e_state; + static int e_clicks; + static int e_is_click; + static int e_keysym; + static char* e_text; + static int e_length; + static Fl_Widget* belowmouse_; + static Fl_Widget* pushed_; + static Fl_Widget* focus_; + static int damage_; + static Fl_Widget* selection_owner_; + static Fl_Window* modal_; + static Fl_Window* grab_; + static int compose_state; + static int visible_focus_; + static int dnd_text_ops_; +#endif + /** + If true then flush() will do something. + */ + static void damage(int d) {damage_ = d;} + +public: + typedef enum { + /// If set, the arrow keys can change focus from a text widget to another + /// widget. If clear, only Tab and BackTab can. + OPTION_ARROW_FOCUS = 0, + /// If set, calls to fl_file_chooser will open the native file chooser. + /// If clear, the FLTK file chooser will open instead. + /// \todo Fl::OPTION_NATIVE_FILECHOOSER not yet supported + OPTION_NATIVE_FILECHOOSER, + // don't change this, leave it always as the last element + OPTION_LAST + } Fl_Option; + +private: + static unsigned char options_[OPTION_LAST]; + static unsigned char options_read_; + +public: + /** + Return a global setting for all FLTK applications, possibly overridden + by a setting specifically for this application. + + \param opt + \returns true or false + */ + static bool option(Fl_Option opt); + + /** + The currently executing idle callback function: DO NOT USE THIS DIRECTLY! + + This is now used as part of a higher level system allowing multiple + idle callback functions to be called. + \see add_idle(), remove_idle() + */ + static void (*idle)(); + +#ifndef FL_DOXYGEN + static Fl_Awake_Handler *awake_ring_; + static void **awake_data_; + static int awake_ring_size_; + static int awake_ring_head_; + static int awake_ring_tail_; + static const char* scheme_; + static Fl_Image* scheme_bg_; + + static int e_original_keysym; // late addition + static int scrollbar_size_; +#endif + + + static int add_awake_handler_(Fl_Awake_Handler, void*); + static int get_awake_handler_(Fl_Awake_Handler&, void*&); + +public: + + // API version number + static double version(); + + // argument parsers: + static int arg(int argc, char **argv, int& i); + static int args(int argc, char **argv, int& i, Fl_Args_Handler cb = 0); + static void args(int argc, char **argv); + /** + Usage string displayed if Fl::args() detects an invalid argument. + This may be changed to point to customized text at run-time. + */ + static const char* const help; + + // things called by initialization: + static void display(const char*); + static int visual(int); + /** + This does the same thing as Fl::visual(int) but also requires OpenGL + drawing to work. This must be done if you want to draw in + normal windows with OpenGL with gl_start() and gl_end(). + It may be useful to call this so your X windows use the same visual + as an Fl_Gl_Window, which on some servers will reduce colormap flashing. + + See Fl_Gl_Window for a list of additional values for the argument. + */ + static int gl_visual(int, int *alist=0); // platform dependent + static void own_colormap(); + static void get_system_colors(); + static void foreground(uchar, uchar, uchar); + static void background(uchar, uchar, uchar); + static void background2(uchar, uchar, uchar); + + // schemes: + static int scheme(const char*); + /** See void scheme(const char *name) */ + static const char* scheme() {return scheme_;} + /** + Called by scheme according to scheme name. + Loads or reloads the current scheme selection. + See void scheme(const char *name) + */ + static int reload_scheme(); // platform dependent + static int scrollbar_size(); + static void scrollbar_size(int W); + + // execution: + static int wait(); + static double wait(double time); + static int check(); + static int ready(); + static int run(); + static Fl_Widget* readqueue(); + /** + Adds a one-shot timeout callback. The function will be called by + Fl::wait() at t seconds after this function is called. + The optional void* argument is passed to the callback. + + You can have multiple timeout callbacks. To remove a timeout + callback use Fl::remove_timeout(). + + If you need more accurate, repeated timeouts, use Fl::repeat_timeout() to + reschedule the subsequent timeouts. + + The following code will print "TICK" each second on + stdout with a fair degree of accuracy: + + \code + void callback(void*) { + puts("TICK"); + Fl::repeat_timeout(1.0, callback); + } + + int main() { + Fl::add_timeout(1.0, callback); + return Fl::run(); + } + \endcode + */ + static void add_timeout(double t, Fl_Timeout_Handler,void* = 0); // platform dependent + /** + Repeats a timeout callback from the expiration of the + previous timeout, allowing for more accurate timing. You may only call + this method inside a timeout callback. + + The following code will print "TICK" each second on + stdout with a fair degree of accuracy: + + \code + void callback(void*) { + puts("TICK"); + Fl::repeat_timeout(1.0, callback); + } + + int main() { + Fl::add_timeout(1.0, callback); + return Fl::run(); + } + \endcode + */ + static void repeat_timeout(double t, Fl_Timeout_Handler, void* = 0); // platform dependent + static int has_timeout(Fl_Timeout_Handler, void* = 0); + static void remove_timeout(Fl_Timeout_Handler, void* = 0); + static void add_check(Fl_Timeout_Handler, void* = 0); + static int has_check(Fl_Timeout_Handler, void* = 0); + static void remove_check(Fl_Timeout_Handler, void* = 0); + /** + Adds file descriptor fd to listen to. + + When the fd becomes ready for reading Fl::wait() will call the + callback and then return. The callback is passed the fd and the + arbitrary void* argument. + + The second version takes a when bitfield, with the bits + FL_READ, FL_WRITE, and FL_EXCEPT defined, + to indicate when the callback should be done. + + There can only be one callback of each type for a file descriptor. + Fl::remove_fd() gets rid of all the callbacks for a given + file descriptor. + + Under UNIX any file descriptor can be monitored (files, + devices, pipes, sockets, etc.). Due to limitations in Microsoft Windows, + WIN32 applications can only monitor sockets. + */ + static void add_fd(int fd, int when, Fl_FD_Handler cb, void* = 0); // platform dependent + /** See void add_fd(int fd, int when, Fl_FD_Handler cb, void* = 0) */ + static void add_fd(int fd, Fl_FD_Handler cb, void* = 0); // platform dependent + /** Removes a file descriptor handler. */ + static void remove_fd(int, int when); // platform dependent + /** Removes a file descriptor handler. */ + static void remove_fd(int); // platform dependent + + static void add_idle(Fl_Idle_Handler cb, void* data = 0); + static int has_idle(Fl_Idle_Handler cb, void* data = 0); + static void remove_idle(Fl_Idle_Handler cb, void* data = 0); + /** If true then flush() will do something. */ + static int damage() {return damage_;} + static void redraw(); + static void flush(); + /** \addtogroup group_comdlg + @{ */ + /** + FLTK calls Fl::warning() to output a warning message. + + The default version on Windows returns \e without printing a warning + message, because Windows programs normally don't have stderr (a console + window) enabled. + + The default version on all other platforms prints the warning message to stderr. + + You can override the behavior by setting the function pointer to your + own routine. + + Fl::warning() means that there was a recoverable problem, the display may + be messed up, but the user can probably keep working - all X protocol + errors call this, for example. The default implementation returns after + displaying the message. + */ + static void (*warning)(const char*, ...); + /** + FLTK calls Fl::error() to output a normal error message. + + The default version on Windows displays the error message in a MessageBox window. + + The default version on all other platforms prints the error message to stderr. + + You can override the behavior by setting the function pointer to your + own routine. + + Fl::error() means there is a recoverable error such as the inability to read + an image file. The default implementation returns after displaying the message. + */ + static void (*error)(const char*, ...); + /** + FLTK calls Fl::fatal() to output a fatal error message. + + The default version on Windows displays the error message in a MessageBox window. + + The default version on all other platforms prints the error message to stderr. + + You can override the behavior by setting the function pointer to your + own routine. + + Fl::fatal() must not return, as FLTK is in an unusable state, however your + version may be able to use longjmp or an exception to continue, as long as + it does not call FLTK again. The default implementation exits with status 1 + after displaying the message. + */ + static void (*fatal)(const char*, ...); + /** @} */ + + /** \defgroup fl_windows Windows handling functions + Windows and standard dialogs handling + @{ */ + static Fl_Window* first_window(); + static void first_window(Fl_Window*); + static Fl_Window* next_window(const Fl_Window*); + + /** + Returns the top-most modal() window currently shown. + + This is the most recently shown() window with modal() true, or NULL + if there are no modal() windows shown(). + The modal() window has its handle() method called + for all events, and no other windows will have handle() + called (grab() overrides this). + */ + static Fl_Window* modal() {return modal_;} + /** + This is used when pop-up menu systems are active. + + Send all events to the passed window no matter where the pointer or + focus is (including in other programs). The window does not have + to be shown() , this lets the handle() method of a + "dummy" window override all event handling and allows you to + map and unmap a complex set of windows (under both X and WIN32 + some window must be mapped because the system interface needs a + window id). + + If grab() is on it will also affect show() of windows by doing + system-specific operations (on X it turns on override-redirect). + These are designed to make menus popup reliably + and faster on the system. + + To turn off grabbing do Fl::grab(0). + + Be careful that your program does not enter an infinite loop + while grab() is on. On X this will lock up your screen! + To avoid this potential lockup, all newer operating systems seem to + limit mouse pointer grabbing to the time during which a mouse button + is held down. Some OS's may not support grabbing at all. + */ + static Fl_Window* grab() {return grab_;} + /** Selects the window to grab. See Fl_Window* Fl::grab() */ + static void grab(Fl_Window*); // platform dependent + /** @} */ + + /** \defgroup fl_events Events handling functions + Fl class events handling API + @{ + */ + // event information: + /** + Returns the last event that was processed. This can be used + to determine if a callback is being done in response to a + keypress, mouse click, etc. + */ + static int event() {return e_number;} + /** + Returns the mouse position of the event relative to the Fl_Window + it was passed to. + */ + static int event_x() {return e_x;} + /** + Returns the mouse position of the event relative to the Fl_Window + it was passed to. + */ + static int event_y() {return e_y;} + /** + Returns the mouse position on the screen of the event. To find the + absolute position of an Fl_Window on the screen, use the + difference between event_x_root(),event_y_root() and + event_x(),event_y(). + */ + static int event_x_root() {return e_x_root;} + /** + Returns the mouse position on the screen of the event. To find the + absolute position of an Fl_Window on the screen, use the + difference between event_x_root(),event_y_root() and + event_x(),event_y(). + */ + static int event_y_root() {return e_y_root;} + /** + Returns the current horizontal mouse scrolling associated with the + FL_MOUSEWHEEL event. Right is positive. + */ + static int event_dx() {return e_dx;} + /** + Returns the current vertical mouse scrolling associated with the + FL_MOUSEWHEEL event. Down is positive. + */ + static int event_dy() {return e_dy;} + /** + Return where the mouse is on the screen by doing a round-trip query to + the server. You should use Fl::event_x_root() and + Fl::event_y_root() if possible, but this is necessary if you are + not sure if a mouse event has been processed recently (such as to + position your first window). If the display is not open, this will + open it. + */ + static void get_mouse(int &,int &); // platform dependent + /** + Returns non zero if we had a double click event. + \retval Non-zero if the most recent FL_PUSH or FL_KEYBOARD was a "double click". + \retval N-1 for N clicks. + A double click is counted if the same button is pressed + again while event_is_click() is true. + + */ + static int event_clicks() {return e_clicks;} + /** + Manually sets the number returned by Fl::event_clicks(). + This can be used to set it to zero so that + later code does not think an item was double-clicked. + \param[in] i corresponds to no double-click if 0, i+1 mouse clicks otherwise + \see int event_clicks() + */ + static void event_clicks(int i) {e_clicks = i;} + /** + The first form returns non-zero if the mouse has not moved far enough + and not enough time has passed since the last FL_PUSH or + FL_KEYBOARD event for it to be considered a "drag" rather than a + "click". You can test this on FL_DRAG, FL_RELEASE, + and FL_MOVE events. The second form clears the value returned + by Fl::event_is_click(). Useful to prevent the next + click from being counted as a double-click or to make a popup menu + pick an item with a single click. Don't pass non-zero to this. + */ + static int event_is_click() {return e_is_click;} + /** + Only i=0 works! See int event_is_click(). + */ + static void event_is_click(int i) {e_is_click = i;} + /** + Gets which particular mouse button caused the current event. + This returns garbage if the most recent event was not a FL_PUSH or FL_RELEASE event. + \retval FL_LEFT_MOUSE \retval FL_MIDDLE_MOUSE \retval FL_RIGHT_MOUSE. + \see Fl::event_buttons() + */ + static int event_button() {return e_keysym-FL_Button;} + /** + This is a bitfield of what shift states were on and what mouse buttons + were held down during the most recent event. The second version + returns non-zero if any of the passed bits are turned on. + The legal bits are: + + \li FL_SHIFT + \li FL_CAPS_LOCK + \li FL_CTRL + \li FL_ALT + \li FL_NUM_LOCK + \li FL_META + \li FL_SCROLL_LOCK + \li FL_BUTTON1 + \li FL_BUTTON2 + \li FL_BUTTON3 + + X servers do not agree on shift states, and FL_NUM_LOCK, FL_META, and + FL_SCROLL_LOCK may not work. The values were selected to match the + XFree86 server on Linux. In addition there is a bug in the way X works + so that the shift state is not correctly reported until the first event + after the shift key is pressed or released. + */ + static int event_state() {return e_state;} + /** See int event_state() */ + static int event_state(int i) {return e_state&i;} + /** + Gets which key on the keyboard was last pushed. + + The returned integer 'key code' is not necessarily a text + equivalent for the keystroke. For instance: if someone presses '5' on the + numeric keypad with numlock on, Fl::event_key() may return the 'key code' + for this key, and NOT the character '5'. To always get the '5', use Fl::event_text() instead. + + \returns an integer 'key code', or 0 if the last event was not a key press or release. + \see int event_key(int), event_text(), compose(int&). + */ + static int event_key() {return e_keysym;} + /** + Returns the keycode of the last key event, regardless of the NumLock state. + + If NumLock is deactivated, FLTK translates events from the + numeric keypad into the corresponding arrow key events. + event_key() returns the translated key code, whereas + event_original_key() returns the keycode before NumLock translation. + */ + static int event_original_key(){return e_original_keysym;} + /** + Returns true if the given \p key was held + down (or pressed) during the last event. This is constant until + the next event is read from the server. + + Fl::get_key(int) returns true if the given key is held down now. + Under X this requires a round-trip to the server and is much + slower than Fl::event_key(int). + + Keys are identified by the unshifted values. FLTK defines a + set of symbols that should work on most modern machines for every key + on the keyboard: + + \li All keys on the main keyboard producing a printable ASCII + character use the value of that ASCII character (as though shift, + ctrl, and caps lock were not on). The space bar is 32. + \li All keys on the numeric keypad producing a printable ASCII + character use the value of that ASCII character plus FL_KP. + The highest possible value is FL_KP_Last so you can + range-check to see if something is on the keypad. + \li All numbered function keys use the number on the function key plus + FL_F. The highest possible number is FL_F_Last, so you + can range-check a value. + \li Buttons on the mouse are considered keys, and use the button + number (where the left button is 1) plus FL_Button. + \li All other keys on the keypad have a symbol: FL_Escape, + FL_BackSpace, FL_Tab, FL_Enter, FL_Print, FL_Scroll_Lock, FL_Pause, + FL_Insert, FL_Home, FL_Page_Up, FL_Delete, FL_End, FL_Page_Down, + FL_Left, FL_Up, FL_Right, FL_Down, FL_Shift_L, FL_Shift_R, + FL_Control_L, FL_Control_R, FL_Caps_Lock, FL_Alt_L, FL_Alt_R, + FL_Meta_L, FL_Meta_R, FL_Menu, FL_Num_Lock, FL_KP_Enter. Be + careful not to confuse these with the very similar, but all-caps, + symbols used by Fl::event_state(). + + On X Fl::get_key(FL_Button+n) does not work. + + On WIN32 Fl::get_key(FL_KP_Enter) and Fl::event_key(FL_KP_Enter) do not work. + */ + static int event_key(int key); + /** + Returns true if the given \p key is held down now. + Under X this requires a round-trip to the server and is much + slower than Fl::event_key(int). \see event_key(int) + */ + static int get_key(int key); // platform dependent + /** + Returns the text associated with the current event, including FL_PASTE or FL_DND_RELEASE events. + This can be used in response to FL_KEYUP, FL_KEYDOWN, FL_PASTE, FL_DND_RELEASE. + + When responding to FL_KEYUP/FL_KEYDOWN, use this function instead of Fl::event_key() + to get the text equivalent of keystrokes suitable for inserting into strings + and text widgets. + + The returned string is guaranteed to be be NULL terminated. + However, see Fl::event_length() for the actual length of the string, + in case the string itself contains NULLs that are part of the text data. + + \returns A NULL terminated text string equivalent of the last keystroke. + */ + static const char* event_text() {return e_text;} + /** + Returns the length of the text in Fl::event_text(). There + will always be a nul at this position in the text. However there may + be a nul before that if the keystroke translates to a nul character or + you paste a nul character. + */ + static int event_length() {return e_length;} + + static int compose(int &del); + /** + If the user moves the cursor, be sure to call Fl::compose_reset(). + The next call to Fl::compose() will start out in an initial state. In + particular it will not set "del" to non-zero. This call is very fast + so it is ok to call it many times and in many places. + */ + static void compose_reset() {compose_state = 0;} + static int event_inside(int,int,int,int); + static int event_inside(const Fl_Widget*); + static int test_shortcut(Fl_Shortcut); + + // event destinations: + static int handle(int, Fl_Window*); + /** Gets the widget that is below the mouse. + \see belowmouse(Fl_Widget*) */ + static Fl_Widget* belowmouse() {return belowmouse_;} + static void belowmouse(Fl_Widget*); + /** Gets the widget that is being pushed. + \see void pushed(Fl_Widget*) */ + static Fl_Widget* pushed() {return pushed_;} + static void pushed(Fl_Widget*); + /** Gets the current Fl::focus() widget. \sa Fl::focus(Fl_Widget*) */ + static Fl_Widget* focus() {return focus_;} + static void focus(Fl_Widget*); + static void add_handler(Fl_Event_Handler h); + static void remove_handler(Fl_Event_Handler h); + /** @} */ + + /** \defgroup fl_clipboard Selection & Clipboard functions + fl global copy/cut/paste functions + @{ */ + // cut/paste: + /** + Copies the data pointed to by \p stuff to the selection (0) or + primary (1) clipboard. The selection clipboard is used for + middle-mouse pastes and for drag-and-drop selections. The primary + clipboard is used for traditional copy/cut/paste operations. + */ + static void copy(const char* stuff, int len, int clipboard = 0); // platform dependent + /** + Pastes the data from the selection (0) or primary (1) clipboard into receiver. + The selection clipboard is used for middle-mouse pastes and for + drag-and-drop selections. The primary clipboard is used for + traditional copy/cut/paste operations. + */ + static void paste(Fl_Widget &receiver, int clipboard /*=0*/); // platform dependent + /** + Initiate a Drag And Drop operation. The clipboard should be + filled with relevant data before calling this method. FLTK will + then initiate the system wide drag and drop handling. Dropped data + will be marked as text. + */ + static int dnd(); // platform dependent + + // These are for back-compatibility only: + /** back-compatibility only: Gets the widget owning the current selection + \see Fl_Widget* selection_owner(Fl_Widget*) */ + static Fl_Widget* selection_owner() {return selection_owner_;} + static void selection_owner(Fl_Widget*); + static void selection(Fl_Widget &owner, const char*, int len); + static void paste(Fl_Widget &receiver); +/** @} */ +/** \defgroup fl_screen Screen functions + fl global screen functions + @{ */ + // screen size: + /** Returns the origin of the current screen, where 0 indicates the left side of the screen. */ + static int x(); // platform dependent + /** Returns the origin of the current screen, where 0 indicates the top edge of the screen. */ + static int y(); // platform dependent + /** Returns the width of the screen in pixels. */ + static int w(); // platform dependent + /** Returns the height of the screen in pixels. */ + static int h(); // platform dependent + + // multi-head support: + static int screen_count(); + /** + Gets the bounding box of a screen that contains the mouse pointer. + \param[out] X,Y,W,H the corresponding screen bounding box + \see void screen_xywh(int &x, int &y, int &w, int &h, int mx, int my) + */ + static void screen_xywh(int &X, int &Y, int &W, int &H) { + screen_xywh(X, Y, W, H, e_x_root, e_y_root); + } + static void screen_xywh(int &X, int &Y, int &W, int &H, int mx, int my); + static void screen_xywh(int &X, int &Y, int &W, int &H, int n); + + /** @} */ + + /** \defgroup fl_attributes Color & Font functions + fl global color, font functions + @{ */ + + // color map: + static void set_color(Fl_Color, uchar, uchar, uchar); + /** + Sets an entry in the fl_color index table. You can set it to any + 8-bit RGB color. The color is not allocated until fl_color(i) is used. + */ + static void set_color(Fl_Color i, unsigned c); // platform dependent + static unsigned get_color(Fl_Color i); + static void get_color(Fl_Color i, uchar &red, uchar &green, uchar &blue); + /** + Frees the specified color from the colormap, if applicable. + If overlay is non-zero then the color is freed from the + overlay colormap. + */ + static void free_color(Fl_Color i, int overlay = 0); // platform dependent + + // fonts: + static const char* get_font(Fl_Font); + /** + Get a human-readable string describing the family of this face. This + is useful if you are presenting a choice to the user. There is no + guarantee that each face has a different name. The return value points + to a static buffer that is overwritten each call. + + The integer pointed to by \p attributes (if the pointer is not + zero) is set to zero, FL_BOLD or FL_ITALIC or + FL_BOLD | FL_ITALIC. To locate a "family" of fonts, search + forward and back for a set with non-zero attributes, these faces along + with the face with a zero attribute before them constitute a family. + */ + static const char* get_font_name(Fl_Font, int* attributes = 0); + /** + Return an array of sizes in \p sizep. The return value is the + length of this array. The sizes are sorted from smallest to largest + and indicate what sizes can be given to fl_font() that will + be matched exactly (fl_font() will pick the closest size for + other sizes). A zero in the first location of the array indicates a + scalable font, where any size works, although the array may list sizes + that work "better" than others. Warning: the returned array + points at a static buffer that is overwritten each call. Under X this + will open the display. + */ + static int get_font_sizes(Fl_Font, int*& sizep); + static void set_font(Fl_Font, const char*); + static void set_font(Fl_Font, Fl_Font); + /** + FLTK will open the display, and add every fonts on the server to the + face table. It will attempt to put "families" of faces together, so + that the normal one is first, followed by bold, italic, and bold + italic. + + The optional argument is a string to describe the set of fonts to + add. Passing NULL will select only fonts that have the + ISO8859-1 character set (and are thus usable by normal text). Passing + "-*" will select all fonts with any encoding as long as they have + normal X font names with dashes in them. Passing "*" will list every + font that exists (on X this may produce some strange output). Other + values may be useful but are system dependent. With WIN32 NULL + selects fonts with ISO8859-1 encoding and non-NULL selects + all fonts. + + The return value is how many faces are in the table after this is done. + */ + static Fl_Font set_fonts(const char* = 0); // platform dependent + + /** @} */ + /** \defgroup fl_drawings Drawing functions + FLTK global graphics and GUI drawing functions. + These functions are declared in , + and in for offscreen buffer-related ones. + @{ */ + // + /** @} */ + + // labeltypes: + static void set_labeltype(Fl_Labeltype,Fl_Label_Draw_F*,Fl_Label_Measure_F*); + /** Sets the functions to call to draw and measure a specific labeltype. */ + static void set_labeltype(Fl_Labeltype, Fl_Labeltype from); // is it defined ? + + // boxtypes: + static Fl_Box_Draw_F *get_boxtype(Fl_Boxtype); + static void set_boxtype(Fl_Boxtype, Fl_Box_Draw_F*,uchar,uchar,uchar,uchar); + static void set_boxtype(Fl_Boxtype, Fl_Boxtype from); + static int box_dx(Fl_Boxtype); + static int box_dy(Fl_Boxtype); + static int box_dw(Fl_Boxtype); + static int box_dh(Fl_Boxtype); + static int draw_box_active(); + + // back compatibility: + /** \addtogroup fl_windows + @{ */ + /** For back compatibility, sets the void Fl::fatal handler callback */ + static void set_abort(Fl_Abort_Handler f) {fatal = f;} + static void (*atclose)(Fl_Window*,void*); + static void default_atclose(Fl_Window*,void*); + /** For back compatibility, sets the Fl::atclose handler callback. You + can now simply change the callback for the window instead. + \see Fl_Window::callback(Fl_Callback*) */ + static void set_atclose(Fl_Atclose_Handler f) {atclose = f;} + /** @} */ + + /** \addtogroup fl_events + @{ */ + /** Returns non-zero if the Shift key is pressed. */ + static int event_shift() {return e_state&FL_SHIFT;} + /** Returns non-zero if the Control key is pressed. */ + static int event_ctrl() {return e_state&FL_CTRL;} + /** Returns non-zero if the FL_COMMAND key is pressed, either FL_CTRL or on OSX FL_META. */ + static int event_command() {return e_state&FL_COMMAND;} + /** Returns non-zero if the Alt key is pressed. */ + static int event_alt() {return e_state&FL_ALT;} + /** + Returns the mouse buttons state bits; if non-zero, then at least one + button is pressed now. This function returns the button state at the + time of the event. During an FL_RELEASE event, the state + of the released button will be 0. To find out, which button + caused an FL_RELEASE event, you can use Fl::event_button() instead. + \return a bit mask value like { [FL_BUTTON1] | [FL_BUTTON2] | [FL_BUTTON3] } + */ + static int event_buttons() {return e_state&0x7f000000;} + /** + Returns non-zero if mouse button 1 is currently held down. + For more details, see Fl::event_buttons(). + */ + static int event_button1() {return e_state&FL_BUTTON1;} + /** + Returns non-zero if button 2 is currently held down. + For more details, see Fl::event_buttons(). + */ + static int event_button2() {return e_state&FL_BUTTON2;} + /** + Returns non-zero if button 3 is currently held down. + For more details, see Fl::event_buttons(). + */ + static int event_button3() {return e_state&FL_BUTTON3;} + /** @} */ + + /** + Sets an idle callback. + + \deprecated This method is obsolete - use the add_idle() method instead. + */ + static void set_idle(Fl_Old_Idle_Handler cb) {idle = cb;} + /** See Fl_Window* grab() */ + static void grab(Fl_Window&win) {grab(&win);} + /** Releases the current grabbed window, equals grab(0). + \deprecated Use Fl::grab(0) instead. + \see Fl_Window* grab() */ + static void release() {grab(0);} + + // Visible focus methods... + /** + Gets or sets the visible keyboard focus on buttons and other + non-text widgets. The default mode is to enable keyboard focus + for all widgets. + */ + static void visible_focus(int v) { visible_focus_ = v; } + /** + Gets or sets the visible keyboard focus on buttons and other + non-text widgets. The default mode is to enable keyboard focus + for all widgets. + */ + static int visible_focus() { return visible_focus_; } + + // Drag-n-drop text operation methods... + /** + Gets or sets whether drag and drop text operations are supported. + This specifically affects whether selected text can + be dragged from text fields or dragged within a text field as a + cut/paste shortcut. + */ + static void dnd_text_ops(int v) { dnd_text_ops_ = v; } + /** + Gets or sets whether drag and drop text operations are + supported. This specifically affects whether selected text can + be dragged from text fields or dragged within a text field as a + cut/paste shortcut. + */ + static int dnd_text_ops() { return dnd_text_ops_; } + /** \defgroup fl_multithread Multithreading support functions + fl multithreading support functions + @{ */ + + // Multithreading support: + static void lock(); + static void unlock(); + static void awake(void* message = 0); + /** See void awake(void* message=0). */ + static int awake(Fl_Awake_Handler cb, void* message = 0); + /** + The thread_message() method returns the last message + that was sent from a child by the awake() method. + + See also: multithreading + */ + static void* thread_message(); // platform dependent + /** @} */ + + /** \defgroup fl_del_widget Safe widget deletion support functions + + These functions support deletion of widgets inside callbacks. + + Fl::delete_widget() should be called when deleting widgets + or complete widget trees (Fl_Group, Fl_Window, ...) inside + callbacks. + + The other functions are intended for internal use. The preferred + way to use them is by using the helper class Fl_Widget_Tracker. + + The following is to show how it works ... + + There are three groups of related methods: + + -# scheduled widget deletion + - Fl::delete_widget() schedules widgets for deletion + - Fl::do_widget_deletion() deletes all scheduled widgets + -# widget watch list ("smart pointers") + - Fl::watch_widget_pointer() adds a widget pointer to the watch list + - Fl::release_widget_pointer() removes a widget pointer from the watch list + - Fl::clear_widget_pointer() clears a widget pointer \e in the watch list + -# the class Fl_Widget_Tracker: + - the constructor calls Fl::watch_widget_pointer() + - the destructor calls Fl::release_widget_pointer() + - the access methods can be used to test, if a widget has been deleted + \see Fl_Widget_Tracker. + + @{ */ + // Widget deletion: + static void delete_widget(Fl_Widget *w); + static void do_widget_deletion(); + static void watch_widget_pointer(Fl_Widget *&w); + static void release_widget_pointer(Fl_Widget *&w); + static void clear_widget_pointer(Fl_Widget const *w); + /** @} */ + +#ifdef HAVE_CAIRO + /** \defgroup group_cairo Cairo support functions and classes + @{ + */ +public: + // Cairo support API + static cairo_t * cairo_make_current(Fl_Window* w); + /** when HAVE_CAIRO is defined and cairo_autolink_context() is true, + any current window dc is linked to a current context. + This is not the default, because it may not be necessary + to add cairo support to all fltk supported windows. + When you wish to associate a cairo context in this mode, + you need to call explicitly in your draw() overridden method, + FL::cairo_make_current(Fl_Window*). This will create a cairo context + but only for this Window. + Still in custom cairo application it is possible to handle + completely this process automatically by setting \p alink to true. + In this last case, you don't need anymore to call Fl::cairo_make_current(). + You can use Fl::cairo_cc() to get the current cairo context anytime. + \note Only available when configure has the --enable-cairo option + */ + static void cairo_autolink_context(bool alink) {cairo_state_.autolink(alink);} + /** + Gets the current autolink mode for cairo support. + \retval false if no cairo context autolink is made for each window. + \retval true if any fltk window is attached a cairo context when it + is current. \see void cairo_autolink_context(bool alink) + \note Only available when configure has the --enable-cairo option + */ + static bool cairo_autolink_context() {return cairo_state_.autolink();} + /** Gets the current cairo context linked with a fltk window. */ + static cairo_t * cairo_cc() { return cairo_state_.cc(); } + /** Sets the current cairo context to \p c. + Set \p own to true if you want fltk to handle this cc deletion. + \note Only available when configure has the --enable-cairo option +*/ + static void cairo_cc(cairo_t * c, bool own=false){ cairo_state_.cc(c, own); } + +private: + static cairo_t * cairo_make_current(void* gc); + static cairo_t * cairo_make_current(void* gc, int W, int H); + static Fl_Cairo_State cairo_state_; +public: + /** @} */ + +#endif // HAVE_CAIRO + +}; + +/** + This class should be used to control safe widget deletion. + + You can use an Fl_Widget_Tracker object to watch another widget, if you + need to know, if this widget has been deleted during a callback. + + This simplifies the use of the "safe widget deletion" methods + Fl::watch_widget_pointer() and Fl::release_widget_pointer() and + makes their use more reliable, because the destructor autmatically + releases the widget pointer from the widget watch list. + + It is intended to be used as an automatic (local/stack) variable, + such that the automatic destructor is called when the object's + scope is left. This ensures that no stale widget pointers are + left in the widget watch list (see example below). + + You can also create Fl_Widget_Tracker objects with \c new, but then it + is your responsibility to delete the object (and thus remove the + widget pointer from the watch list) when it is not needed any more. + + Example: + + \code + int MyClass::handle (int event) { + + if (...) { + Fl_Widget_Tracker wp(this); // watch myself + do_callback(); // call the callback + + if (wp.deleted()) return 1; // exit, if deleted + + // Now we are sure that the widget has not been deleted. + // It is safe to access the widget + + clear_changed(); // access the widget + } + } + \endcode + +*/ +class FL_EXPORT Fl_Widget_Tracker { + + Fl_Widget* wp_; + +public: + + Fl_Widget_Tracker(Fl_Widget *wi); + ~Fl_Widget_Tracker(); + + /** + Returns a pointer to the watched widget. + + This pointer is \c NULL, if the widget has been deleted. + */ + Fl_Widget *widget() {return wp_;} + + /** + Returns 1, if the watched widget has been deleted. + + This is a convenience method. You can also use something like + + if (wp.widget() == 0) // ... + + where \p wp is an Fl_Widget_Tracker object. + */ + int deleted() {return wp_ == 0;} + + /** + Returns 1, if the watched widget exists (has not been deleted). + + This is a convenience method. You can also use something like + + if (wp.widget() != 0) // ... + + where \p wp is an Fl_Widget_Tracker object. + */ + int exists() {return wp_ != 0;} + +}; + + /** \defgroup fl_unicode Unicode and UTF-8 functions + fl global Unicode and UTF-8 handling functions + @{ */ + /** @} */ + +#endif // !Fl_H + +// +// End of "$Id: Fl.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Adjuster.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Adjuster.H new file mode 100644 index 0000000..a3a77e3 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Adjuster.H @@ -0,0 +1,82 @@ +// +// "$Id: Fl_Adjuster.H 7903 2010-11-28 21:06:39Z matt $" +// +// Adjuster widget header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Adjuster widget . */ + +// 3-button "slider", made for Nuke + +#ifndef Fl_Adjuster_H +#define Fl_Adjuster_H + +#ifndef Fl_Valuator_H +#include "Fl_Valuator.H" +#endif + +/** + The Fl_Adjuster widget was stolen from Prisms, and has proven + to be very useful for values that need a large dynamic range. + \image html adjuster1.gif + \image latex adjuster1.eps "Fl_Adjuster" width=4cm +

When you press a button and drag to the right the value increases. + When you drag to the left it decreases. The largest button adjusts by + 100 * step(), the next by 10 * step() and that + smallest button by step(). Clicking on the buttons + increments by 10 times the amount dragging by a pixel does. Shift + + click decrements by 10 times the amount. +*/ +class FL_EXPORT Fl_Adjuster : public Fl_Valuator { + int drag; + int ix; + int soft_; +protected: + void draw(); + int handle(int); + void value_damage(); +public: + Fl_Adjuster(int X,int Y,int W,int H,const char *l=0); + /** + If "soft" is turned on, the user is allowed to drag the value outside + the range. If they drag the value to one of the ends, let go, then + grab again and continue to drag, they can get to any value. Default is + one. + */ + void soft(int s) {soft_ = s;} + /** + If "soft" is turned on, the user is allowed to drag the value outside + the range. If they drag the value to one of the ends, let go, then + grab again and continue to drag, they can get to any value. Default is + one. + */ + int soft() const {return soft_;} +}; + +#endif + +// +// End of "$Id: Fl_Adjuster.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_BMP_Image.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_BMP_Image.H new file mode 100644 index 0000000..2204dc0 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_BMP_Image.H @@ -0,0 +1,50 @@ +// +// "$Id: Fl_BMP_Image.H 7903 2010-11-28 21:06:39Z matt $" +// +// BMP image header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_BMP_Image widget . */ + +#ifndef Fl_BMP_Image_H +#define Fl_BMP_Image_H +# include "Fl_Image.H" + +/** + The Fl_BMP_Image class supports loading, caching, + and drawing of Windows Bitmap (BMP) image files. +*/ +class FL_EXPORT Fl_BMP_Image : public Fl_RGB_Image { + + public: + + Fl_BMP_Image(const char* filename); +}; + +#endif + +// +// End of "$Id: Fl_BMP_Image.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Bitmap.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Bitmap.H new file mode 100644 index 0000000..35256c7 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Bitmap.H @@ -0,0 +1,85 @@ +// +// "$Id: Fl_Bitmap.H 7903 2010-11-28 21:06:39Z matt $" +// +// Bitmap header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Bitmap widget . */ + +#ifndef Fl_Bitmap_H +#define Fl_Bitmap_H +# include "Fl_Image.H" + +class Fl_Widget; +struct Fl_Menu_Item; + +/** + The Fl_Bitmap class supports caching and drawing of mono-color + (bitmap) images. Images are drawn using the current color. +*/ +class FL_EXPORT Fl_Bitmap : public Fl_Image { + friend class Fl_Quartz_Graphics_Driver; + friend class Fl_GDI_Graphics_Driver; + friend class Fl_Xlib_Graphics_Driver; +public: + + /** pointer to raw bitmap data */ + const uchar *array; + /** Non-zero if array points to bitmap data allocated internally */ + int alloc_array; + + private: + +#if defined(__APPLE__) || defined(WIN32) + /** for internal use */ + void *id_; +#else + /** for internal use */ + unsigned id_; +#endif // __APPLE__ || WIN32 + + public: + + /** The constructors create a new bitmap from the specified bitmap data */ + Fl_Bitmap(const uchar *bits, int W, int H) : + Fl_Image(W,H,0), array(bits), alloc_array(0), id_(0) {data((const char **)&array, 1);} + /** The constructors create a new bitmap from the specified bitmap data */ + Fl_Bitmap(const char *bits, int W, int H) : + Fl_Image(W,H,0), array((const uchar *)bits), alloc_array(0), id_(0) {data((const char **)&array, 1);} + virtual ~Fl_Bitmap(); + virtual Fl_Image *copy(int W, int H); + Fl_Image *copy() { return copy(w(), h()); } + virtual void draw(int X, int Y, int W, int H, int cx=0, int cy=0); + void draw(int X, int Y) {draw(X, Y, w(), h(), 0, 0);} + virtual void label(Fl_Widget*w); + virtual void label(Fl_Menu_Item*m); + virtual void uncache(); +}; + +#endif + +// +// End of "$Id: Fl_Bitmap.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Box.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Box.H new file mode 100644 index 0000000..9de875d --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Box.H @@ -0,0 +1,69 @@ +// +// "$Id: Fl_Box.H 7903 2010-11-28 21:06:39Z matt $" +// +// Box header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Box widget . */ + +#ifndef Fl_Box_H +#define Fl_Box_H + +#ifndef Fl_Widget_H +#include "Fl_Widget.H" +#endif + +/** + This widget simply draws its box, and possibly it's label. Putting it + before some other widgets and making it big enough to surround them + will let you draw a frame around them. +*/ +class FL_EXPORT Fl_Box : public Fl_Widget { +protected: + void draw(); +public: + /** + - The first constructor sets box() to FL_NO_BOX, which + means it is invisible. However such widgets are useful as placeholders + or Fl_Group::resizable() + values. To change the box to something visible, use box(n). + - The second form of the constructor sets the box to the specified box + type. +

The destructor removes the box. + */ + Fl_Box(int X, int Y, int W, int H, const char *l=0) + : Fl_Widget(X,Y,W,H,l) {} + /** See Fl_Box::Fl_Box(int x, int y, int w, int h, const char * = 0) */ + Fl_Box(Fl_Boxtype b, int X, int Y, int W, int H, const char *l) + : Fl_Widget(X,Y,W,H,l) {box(b);} + + virtual int handle(int); +}; + +#endif + +// +// End of "$Id: Fl_Box.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Browser.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Browser.H new file mode 100644 index 0000000..f756d3a --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Browser.H @@ -0,0 +1,324 @@ +// +// "$Id: Fl_Browser.H 7903 2010-11-28 21:06:39Z matt $" +// +// Browser header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Browser widget . */ + +// Forms-compatable browser. Probably useful for other +// lists of textual data. Notice that the line numbers +// start from 1, and 0 means "no line". + +#ifndef Fl_Browser_H +#define Fl_Browser_H + +#include "Fl_Browser_.H" +#include "Fl_Image.H" + +struct FL_BLINE; + +/** + The Fl_Browser widget displays a scrolling list of text + lines, and manages all the storage for the text. This is not a text + editor or spreadsheet! But it is useful for showing a vertical list of + named objects to the user. + + Each line in the browser is identified by number. The numbers + start at one (this is so that zero can be reserved for "no line" in + the selective browsers). Unless otherwise noted, the methods do not + check to see if the passed line number is in range and legal. It must + always be greater than zero and <= size(). + + Each line contains a null-terminated string of text and a void * + data pointer. The text string is displayed, the void * + pointer can be used by the callbacks to reference the object the text + describes. + + The base class does nothing when the user clicks on it. The + subclasses + Fl_Select_Browser, + Fl_Hold_Browser, and + Fl_Multi_Browser react to user clicks to select lines in + the browser and do callbacks. + + The base class + Fl_Browser_ provides the scrolling and selection mechanisms of + this and all the subclasses, but the dimensions and appearance of each + item are determined by the subclass. You can use Fl_Browser_ + to display information other than text, or text that is dynamically + produced from your own data structures. If you find that loading the + browser is a lot of work or is inefficient, you may want to make a + subclass of Fl_Browser_. + + Some common coding patterns used for working with Fl_Browser: + \code + // How to loop through all the items in the browser + for ( int t=1; t<=browser->size(); t++ ) { // index 1 based..! + printf("item #%d, label='%s'\n", t, browser->text(t)); + } + \endcode + + Note: If you are subclassing Fl_Browser, it's more efficient + to use the protected methods item_first() and item_next(), since + Fl_Browser internally uses linked lists to manage the browser's items. + For more info, see find_item(int). +*/ +class FL_EXPORT Fl_Browser : public Fl_Browser_ { + + FL_BLINE *first; // the array of lines + FL_BLINE *last; + FL_BLINE *cache; + int cacheline; // line number of cache + int lines; // Number of lines + int full_height_; + const int* column_widths_; + char format_char_; // alternative to @-sign + char column_char_; // alternative to tab + +protected: + + // required routines for Fl_Browser_ subclass: + void* item_first() const ; + void* item_next(void* item) const ; + void* item_prev(void* item) const ; + void* item_last()const ; + int item_selected(void* item) const ; + void item_select(void* item, int val); + int item_height(void* item) const ; + int item_width(void* item) const ; + void item_draw(void* item, int X, int Y, int W, int H) const ; + int full_height() const ; + int incr_height() const ; + const char *item_text(void *item) const; + /** Swap the items \p a and \p b. + You must call redraw() to make any changes visible. + \param[in] a,b the items to be swapped. + \see swap(int,int), item_swap() + */ + void item_swap(void *a, void *b) { swap((FL_BLINE*)a, (FL_BLINE*)b); } + /** Return the item at specified \p line. + \param[in] line The line of the item to return. (1 based) + \returns The item, or NULL if line out of range. + \see item_at(), find_line(), lineno() + */ + void *item_at(int line) const { return (void*)find_line(line); } + + FL_BLINE* find_line(int line) const ; + FL_BLINE* _remove(int line) ; + void insert(int line, FL_BLINE* item); + int lineno(void *item) const ; + void swap(FL_BLINE *a, FL_BLINE *b); + +public: + + void remove(int line); + void add(const char* newtext, void* d = 0); + void insert(int line, const char* newtext, void* d = 0); + void move(int to, int from); + int load(const char* filename); + void swap(int a, int b); + void clear(); + + /** + Returns how many lines are in the browser. + The last line number is equal to this. + Returns 0 if browser is empty. + */ + int size() const { return lines; } + void size(int W, int H) { Fl_Widget::size(W, H); } + + int topline() const ; + /** For internal use only? */ + enum Fl_Line_Position { TOP, BOTTOM, MIDDLE }; + void lineposition(int line, Fl_Line_Position pos); + /** + Scrolls the browser so the top item in the browser + is showing the specified \p line. + \param[in] line The line to be displayed at the top. + \see topline(), middleline(), bottomline(), displayed(), lineposition() + */ + void topline(int line) { lineposition(line, TOP); } + /** + Scrolls the browser so the bottom item in the browser + is showing the specified \p line. + \param[in] line The line to be displayed at the bottom. + \see topline(), middleline(), bottomline(), displayed(), lineposition() + */ + void bottomline(int line) { lineposition(line, BOTTOM); } + /** + Scrolls the browser so the middle item in the browser + is showing the specified \p line. + \param[in] line The line to be displayed in the middle. + \see topline(), middleline(), bottomline(), displayed(), lineposition() + */ + void middleline(int line) { lineposition(line, MIDDLE); } + + int select(int line, int val=1); + int selected(int line) const ; + void show(int line); + /** Shows the entire Fl_Browser widget -- opposite of hide(). */ + void show() { Fl_Widget::show(); } + void hide(int line); + /** Hides the entire Fl_Browser widget -- opposite of show(). */ + void hide() { Fl_Widget::hide(); } + int visible(int line) const ; + + int value() const ; + /** + Sets the browser's value(), which selects the specified \p line. + This is the same as calling select(line). + \see select(), selected(), value(), item_select(), item_selected() + */ + void value(int line) { select(line); } + const char* text(int line) const ; + void text(int line, const char* newtext); + void* data(int line) const ; + void data(int line, void* d); + + Fl_Browser(int X, int Y, int W, int H, const char *L = 0); + /** + The destructor deletes all list items and destroys the browser. + */ + ~Fl_Browser() { clear(); } + + /** + Gets the current format code prefix character, which by default is '\@'. + A string of formatting codes at the start of each column are stripped off + and used to modify how the rest of the line is printed: + + \li '\@.' Print rest of line, don't look for more '\@' signs + \li '\@\@' Print rest of line starting with '\@' + \li '\@l' Use a LARGE (24 point) font + \li '\@m' Use a medium large (18 point) font + \li '\@s' Use a small (11 point) font + \li '\@b' Use a bold font (adds FL_BOLD to font) + \li '\@i' Use an italic font (adds FL_ITALIC to font) + \li '\@f' or '\@t' Use a fixed-pitch + font (sets font to FL_COURIER) + \li '\@c' Center the line horizontally + \li '\@r' Right-justify the text + \li '\@B0', '\@B1', ... '\@B255' Fill the backgound with + fl_color(n) + \li '\@C0', '\@C1', ... '\@C255' Use fl_color(n) to draw the text + \li '\@F0', '\@F1', ... Use fl_font(n) to draw the text + \li '\@S1', '\@S2', ... Use point size n to draw the text + \li '\@u' or '\@_' Underline the text. + \li '\@-' draw an engraved line through the middle. + + Notice that the '\@.' command can be used to reliably + terminate the parsing. To print a random string in a random color, use + sprintf("@C%d@.%s", color, string) and it will work even if the + string starts with a digit or has the format character in it. + */ + char format_char() const { return format_char_; } + /** + Sets the current format code prefix character to \p c. + The default prefix is '\@'. Set the prefix to 0 to disable formatting. + \see format_char() for list of '\@' codes + */ + void format_char(char c) { format_char_ = c; } + /** + Gets the current column separator character. + The default is '\\t' (tab). + \see column_char(), column_widths() + */ + char column_char() const { return column_char_; } + /** + Sets the column separator to c. + This will only have an effect if you also set column_widths(). + The default is '\\t' (tab). + \see column_char(), column_widths() + */ + void column_char(char c) { column_char_ = c; } + /** + Gets the current column width array. + This array is zero-terminated and specifies the widths in pixels of + each column. The text is split at each column_char() and each part is + formatted into it's own column. After the last column any remaining + text is formatted into the space between the last column and the + right edge of the browser, even if the text contains instances of + column_char() . The default value is a one-element array of just + a zero, which means there are no columns. + + Example: + \code + Fl_Browser *b = new Fl_Browser(..); + int widths[] = { 50, 50, 50, 70, 70, 40, 40, 70, 70, 50, 0 }; // widths for each column + b->column_widths(widths); // assign array to widget + b->column_char('\t'); // use tab as the column character + b->add("USER\tPID\tCPU\tMEM\tVSZ\tRSS\tTTY\tSTAT\tSTART\tTIME\tCOMMAND"); + b->add("root\t2888\t0.0\t0.0\t1352\t0\ttty3\tSW\tAug15\t0:00\t@b@f/sbin/mingetty tty3"); + b->add("root\t13115\t0.0\t0.0\t1352\t0\ttty2\tSW\tAug30\t0:00\t@b@f/sbin/mingetty tty2"); + [..] + \endcode + \see column_char(), column_widths() + */ + const int* column_widths() const { return column_widths_; } + /** + Sets the current array to \p arr. Make sure the last entry is zero. + \see column_char(), column_widths() + */ + void column_widths(const int* arr) { column_widths_ = arr; } + + /** + Returns non-zero if \p line has been scrolled to a position where it is being displayed. + Checks to see if the item's vertical position is within the top and bottom + edges of the display window. This does NOT take into account the hide()/show() + status of the widget or item. + \param[in] line The line to be checked + \returns 1 if visible, 0 if not visible. + \see topline(), middleline(), bottomline(), displayed(), lineposition() + */ + int displayed(int line) const { return Fl_Browser_::displayed(find_line(line)); } + + /** + Make the item at the specified \p line visible(). + Functionally similar to show(int line). + If \p line is out of range, redisplay top or bottom of list as appropriate. + \param[in] line The line to be made visible. + \see show(int), hide(int), display(), visible(), make_visible() + */ + void make_visible(int line) { + if (line < 1) Fl_Browser_::display(find_line(1)); + else if (line > lines) Fl_Browser_::display(find_line(lines)); + else Fl_Browser_::display(find_line(line)); + } + + // icon support + void icon(int line, Fl_Image* icon); + Fl_Image* icon(int line) const; + void remove_icon(int line); + + /** For back compatibility only. */ + void replace(int a, const char* b) { text(a, b); } + void display(int line, int val=1); +}; + +#endif + +// +// End of "$Id: Fl_Browser.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Browser_.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Browser_.H new file mode 100644 index 0000000..d5c8b6a --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Browser_.H @@ -0,0 +1,378 @@ +// +// "$Id: Fl_Browser_.H 7903 2010-11-28 21:06:39Z matt $" +// +// Common browser header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Browser_ widget . */ + +// Yes, I know this should be a template... + +#ifndef Fl_Browser__H +#define Fl_Browser__H + +#ifndef Fl_Group_H +#include "Fl_Group.H" +#endif +#include "Fl_Scrollbar.H" +#include // Fl::scrollbar_size() + +#define FL_NORMAL_BROWSER 0 /**< type() of Fl_Browser */ +#define FL_SELECT_BROWSER 1 /**< type() of FL_Select_Browser */ +#define FL_HOLD_BROWSER 2 /**< type() of Fl_Hold_Browser */ +#define FL_MULTI_BROWSER 3 /**< type() of Fl_Multi_Browser */ + +#define FL_SORT_ASCENDING 0 /**< sort browser items in ascending alphabetic order. */ +#define FL_SORT_DESCENDING 1 /**< sort in descending order */ + +/** + This is the base class for browsers. To be useful it must be + subclassed and several virtual functions defined. The Forms-compatible + browser and the file chooser's browser are subclassed off of this. + + This has been designed so that the subclass has complete control + over the storage of the data, although because next() and + prev() functions are used to index, it works best as a linked list + or as a large block of characters in which the line breaks must be + searched for. + + A great deal of work has been done so that the "height" of a data + object does not need to be determined until it is drawn. This is + useful if actually figuring out the size of an object requires + accessing image data or doing stat() on a file or doing some + other slow operation. +*/ +class FL_EXPORT Fl_Browser_ : public Fl_Group { + int position_; // where user wants it scrolled to + int real_position_; // the current vertical scrolling position + int hposition_; // where user wants it panned to + int real_hposition_; // the current horizontal scrolling position + int offset_; // how far down top_ item the real_position is + int max_width; // widest object seen so far + uchar has_scrollbar_; // which scrollbars are enabled + Fl_Font textfont_; + Fl_Fontsize textsize_; + Fl_Color textcolor_; + void* top_; // which item scrolling position is in + void* selection_; // which is selected (except for FL_MULTI_BROWSER) + void *redraw1,*redraw2; // minimal update pointers + void* max_width_item; // which item has max_width_ + int scrollbar_size_; // size of scrollbar trough + + void update_top(); + +protected: + + // All of the following must be supplied by the subclass: + /** + This method must be provided by the subclass + to return the first item in the list. + \see item_first(), item_next(), item_last(), item_prev() + */ + virtual void *item_first() const = 0; + /** + This method must be provided by the subclass + to return the item in the list after \p item. + \see item_first(), item_next(), item_last(), item_prev() + */ + virtual void *item_next(void *item) const = 0; + /** + This method must be provided by the subclass + to return the item in the list before \p item. + \see item_first(), item_next(), item_last(), item_prev() + */ + virtual void *item_prev(void *item) const = 0; + /** + This method must be provided by the subclass + to return the last item in the list. + \see item_first(), item_next(), item_last(), item_prev() + */ + virtual void *item_last() const { return 0L; } + /** + This method must be provided by the subclass to return + the height of \p item in pixels. + Allow for two additional pixels for the list selection box. + \param[in] item The item whose height is returned. + \returns The height of the specified \p item in pixels. + \see item_height(), item_width(), item_quick_height() + */ + virtual int item_height(void *item) const = 0; + /** + This method must be provided by the subclass to return the width of the + \p item in pixels. Allow for two additional pixels for the list + selection box. + \param[in] item The item whose width is returned. + \returns The width of the item in pixels. + */ + virtual int item_width(void *item) const = 0; + virtual int item_quick_height(void *item) const ; + /** + This method must be provided by the subclass to draw the \p item + in the area indicated by \p X, \p Y, \p W, \p H. + */ + virtual void item_draw(void *item,int X,int Y,int W,int H) const = 0; + /** + This optional method returns a string (label) that may be used for sorting. + \param[in] item The item whose label text is returned. + \returns The item's text label. (Can be NULL if blank) + */ + virtual const char *item_text(void *item) const { return 0L; } + /** + This optional method should be provided by the subclass + to efficiently swap browser items \p a and \p b, such as for sorting. + \param[in] a,b The two items to be swapped. + */ + virtual void item_swap(void *a,void *b) { } + /** + This method must be provided by the subclass + to return the item for the specified \p index. + \param[in] index The \p index of the item to be returned + \returns The item at the specified \p index. + */ + virtual void *item_at(int index) const { return 0L; } + // you don't have to provide these but it may help speed it up: + virtual int full_width() const ; // current width of all items + virtual int full_height() const ; // current height of all items + virtual int incr_height() const ; // average height of an item + // These only need to be done by subclass if you want a multi-browser: + virtual void item_select(void *item,int val=1); + virtual int item_selected(void *item) const ; + + // things the subclass may want to call: + /** + Returns the item that appears at the top of the list. + */ + void *top() const { return top_; } + /** + Returns the item currently selected, or NULL if there is no selection. + + For multiple selection browsers this call returns the currently focused item, + even if it is not selected. To find all selected items, call + Fl_Multi_Browser::selected() for every item in question. + */ + void *selection() const { return selection_; } + void new_list(); // completely clobber all data, as though list replaced + void deleting(void *item); // get rid of any pointers to item + void replacing(void *a,void *b); // change a pointers to b + void swapping(void *a,void *b); // exchange pointers a and b + void inserting(void *a,void *b); // insert b near a + int displayed(void *item) const ; // true if this item is visible + void redraw_line(void *item); // minimal update, no change in size + /** + This method will cause the entire list to be redrawn. + \see redraw_lines(), redraw_line() + */ + void redraw_lines() { damage(FL_DAMAGE_SCROLL); } // redraw all of them + void bbox(int &X,int &Y,int &W,int &H) const; + int leftedge() const; // x position after scrollbar & border + void *find_item(int ypos); // item under mouse + + void draw(); + Fl_Browser_(int X,int Y,int W,int H,const char *L=0); + +public: + + /** + Vertical scrollbar. Public, so that it can be accessed directly. + */ + Fl_Scrollbar scrollbar; + /** + Horizontal scrollbar. Public, so that it can be accessed directly. + */ + Fl_Scrollbar hscrollbar; + + int handle(int event); + void resize(int X,int Y,int W,int H); + + int select(void *item,int val=1,int docallbacks=0); + int select_only(void *item,int docallbacks=0); + int deselect(int docallbacks=0); + /** + Gets the vertical scroll position of the list as a pixel position \p pos. + The position returned is how many pixels of the list are scrolled off the top edge + of the screen. Example: A position of '3' indicates the top 3 pixels of + the list are scrolled off the top edge of the screen. + \see position(), hposition() + */ + int position() const { return position_; } + void position(int pos); // scroll to here + /** + Gets the horizontal scroll position of the list as a pixel position \p pos. + The position returned is how many pixels of the list are scrolled off the left edge + of the screen. Example: A position of '18' indicates the left 18 pixels of + the list are scrolled off the left edge of the screen. + \see position(), hposition() + */ + int hposition() const { return hposition_; } + void hposition(int); // pan to here + void display(void *item); // scroll so this item is shown + + /** + Values for has_scrollbar(). + */ + /** Anonymous enum bit flags for has_scrollbar(). + - bit 0: horizontal + - bit 1: vertical + - bit 2: 'always' (to be combined with bits 0 and 1) + - bit 3-31: reserved for future use + */ + enum { // values for has_scrollbar() + HORIZONTAL = 1, ///< Only show horizontal scrollbar. + VERTICAL = 2, ///< Only show vertical scrollbar. + BOTH = 3, ///< Show both scrollbars. (default) + ALWAYS_ON = 4, ///< Specified scrollbar(s) should 'always' be shown (to be used with HORIZONTAL/VERTICAL) + HORIZONTAL_ALWAYS = 5, ///< Horizontal scrollbar always on. + VERTICAL_ALWAYS = 6, ///< Vertical scrollbar always on. + BOTH_ALWAYS = 7 ///< Both scrollbars always on. + }; + /** + Returns the current scrollbar mode, see Fl_Browser_::has_scrollbar(uchar) + */ + uchar has_scrollbar() const { return has_scrollbar_; } + /** + Sets whether the widget should have scrollbars or not (default Fl_Browser_::BOTH). + By default you can scroll in both directions, and the scrollbars + disappear if the data will fit in the widget. + has_scrollbar() changes this based on the value of \p mode: + + - 0 - No scrollbars. + + - Fl_Browser_::HORIZONTAL - Only a horizontal scrollbar. + + - Fl_Browser_::VERTICAL - Only a vertical scrollbar. + + - Fl_Browser_::BOTH - The default is both scrollbars. + + - Fl_Browser_::HORIZONTAL_ALWAYS - Horizontal scrollbar always on, + vertical always off. + + - Fl_Browser_::VERTICAL_ALWAYS - Vertical scrollbar always on, + horizontal always off. + + - Fl_Browser_::BOTH_ALWAYS - Both always on. + */ + void has_scrollbar(uchar mode) { has_scrollbar_ = mode; } + + /** + Gets the default text font for the lines in the browser. + \see textfont(), textsize(), textcolor() + */ + Fl_Font textfont() const { return textfont_; } + /** + Sets the default text font for the lines in the browser to \p font. + */ + void textfont(Fl_Font font) { textfont_ = font; } + + /** + Gets the default text size (in pixels) for the lines in the browser. + */ + Fl_Fontsize textsize() const { return textsize_; } + /** + Sets the default text size (in pixels) for the lines in the browser to \p size. + */ + void textsize(Fl_Fontsize size) { textsize_ = size; } + + /** + Gets the default text color for the lines in the browser. + */ + Fl_Color textcolor() const { return textcolor_; } + /** + Sets the default text color for the lines in the browser to color \p col. + */ + void textcolor(Fl_Color col) { textcolor_ = col; } + + /** + Gets the current size of the scrollbars' troughs, in pixels. + + If this value is zero (default), this widget will use the + Fl::scrollbar_size() value as the scrollbar's width. + + \returns Scrollbar size in pixels, or 0 if the global Fl::scrollsize() is being used. + \see Fl::scrollbar_size(int) + */ + int scrollbar_size() const { + return(scrollbar_size_); + } + /** + Sets the pixel size of the scrollbars' troughs to the \p size, in pixels. + + Normally you should not need this method, and should use + Fl::scrollbar_size(int) instead to manage the size of ALL + your widgets' scrollbars. This ensures your application + has a consistent UI, is the default behavior, and is normally + what you want. + + Only use THIS method if you really need to override the global + scrollbar size. The need for this should be rare. + + Setting \p size to the special value of 0 causes the widget to + track the global Fl::scrollbar_size(), which is the default. + + \param[in] size Sets the scrollbar size in pixels.\n + If 0 (default), scrollbar size tracks the global Fl::scrollbar_size() + \see Fl::scrollbar_size() + */ + void scrollbar_size(int size) { + scrollbar_size_ = size; + } + /** + This method has been deprecated, existing for backwards compatibility only. + Use scrollbar_size() instead. + This method always returns the global value Fl::scrollbar_size(). + \returns Always returns the global value Fl::scrollbar_size(). + \todo This method should eventually be removed in 1.4+ + */ + int scrollbar_width() const { + return(Fl::scrollbar_size()); + } + /** + This method has been deprecated, existing for backwards compatibility only. + Use scrollbar_size(int) instead. + This method sets the global Fl::scrollbar_size(), and forces this + instance of the widget to use it. + \todo This method should eventually be removed in 1.4+ + */ + void scrollbar_width(int width) { + Fl::scrollbar_size(width); + scrollbar_size_ = 0; + } + /** + Moves the vertical scrollbar to the righthand side of the list. + For back compatibility. + */ + void scrollbar_right() { scrollbar.align(FL_ALIGN_RIGHT); } + /** + Moves the vertical scrollbar to the lefthand side of the list. + For back compatibility. + */ + void scrollbar_left() { scrollbar.align(FL_ALIGN_LEFT); } + void sort(int flags=0); +}; + +#endif + +// +// End of "$Id: Fl_Browser_.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Button.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Button.H new file mode 100644 index 0000000..39050dc --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Button.H @@ -0,0 +1,180 @@ +// +// "$Id: Fl_Button.H 7903 2010-11-28 21:06:39Z matt $" +// +// Button header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Button widget . */ + +#ifndef Fl_Button_H +#define Fl_Button_H + +#ifndef Fl_Widget_H +#include "Fl_Widget.H" +#endif + +// values for type() +#define FL_NORMAL_BUTTON 0 /**< value() will be set to 1 during the press of the button and + reverts back to 0 when the button is released */ +#define FL_TOGGLE_BUTTON 1 ///< value() toggles between 0 and 1 at every click of the button +#define FL_RADIO_BUTTON (FL_RESERVED_TYPE+2) /**< is set to 1 at button press, and all other + buttons in the same group with type() == FL_RADIO_BUTTON + are set to zero.*/ +#define FL_HIDDEN_BUTTON 3 ///< for Forms compatibility + +extern FL_EXPORT Fl_Shortcut fl_old_shortcut(const char*); + +class Fl_Widget_Tracker; + +/** + \class Fl_Button + \brief Buttons generate callbacks when they are clicked by the user. + + You control exactly when and how by changing the values for type() and + when(). Buttons can also generate callbacks in response to \c FL_SHORTCUT + events. The button can either have an explicit shortcut(int s) value or a + letter shortcut can be indicated in the label() with an '\&' character + before it. For the label shortcut it does not matter if \e Alt is held + down, but if you have an input field in the same window, the user will have + to hold down the \e Alt key so that the input field does not eat the event + first as an \c FL_KEYBOARD event. + + \todo Refactor the doxygen comments for Fl_Button type() documentation. + + For an Fl_Button object, the type() call returns one of: + \li \c FL_NORMAL_BUTTON (0): value() remains unchanged after button press. + \li \c FL_TOGGLE_BUTTON: value() is inverted after button press. + \li \c FL_RADIO_BUTTON: value() is set to 1 after button press, and all other + buttons in the current group with type() == FL_RADIO_BUTTON + are set to zero. + + \todo Refactor the doxygen comments for Fl_Button when() documentation. + + For an Fl_Button object, the following when() values are useful, the default + being \c FL_WHEN_RELEASE: + \li \c 0: The callback is not done, instead changed() is turned on. + \li \c FL_WHEN_RELEASE: The callback is done after the user successfully + clicks the button, or when a shortcut is typed. + \li \c FL_WHEN_CHANGED: The callback is done each time the value() changes + (when the user pushes and releases the button, and as the mouse is + dragged around in and out of the button). +*/ +class FL_EXPORT Fl_Button : public Fl_Widget { + + int shortcut_; + char value_; + char oldval; + uchar down_box_; + +protected: + + static Fl_Widget_Tracker *key_release_tracker; + static void key_release_timeout(void*); + void simulate_key_action(); + + virtual void draw(); + +public: + + virtual int handle(int); + + Fl_Button(int X, int Y, int W, int H, const char *L = 0); + + int value(int v); + + /** + Returns the current value of the button (0 or 1). + */ + char value() const {return value_;} + + /** + Same as \c value(1). + \see value(int v) + */ + int set() {return value(1);} + + /** + Same as \c value(0). + \see value(int v) + */ + int clear() {return value(0);} + + void setonly(); // this should only be called on FL_RADIO_BUTTONs + + /** + Returns the current shortcut key for the button. + \retval int + */ + int shortcut() const {return shortcut_;} + + /** + Sets the shortcut key to \c s. + Setting this overrides the use of '\&' in the label(). + The value is a bitwise OR of a key and a set of shift flags, for example: + FL_ALT | 'a', or + FL_ALT | (FL_F + 10), or just + 'a'. + A value of 0 disables the shortcut. + + The key can be any value returned by Fl::event_key(), but will usually be + an ASCII letter. Use a lower-case letter unless you require the shift key + to be held down. + + The shift flags can be any set of values accepted by Fl::event_state(). + If the bit is on, that shift key must be pushed. Meta, Alt, Ctrl, and + Shift must be off if they are not in the shift flags (zero for the other + bits indicates a "don't care" setting). + \param[in] s bitwise OR of key and shift flags + */ + void shortcut(int s) {shortcut_ = s;} + + /** + Returns the current down box type, which is drawn when value() is non-zero. + \retval Fl_Boxtype + */ + Fl_Boxtype down_box() const {return (Fl_Boxtype)down_box_;} + + /** + Sets the down box type. The default value of 0 causes FLTK to figure out + the correct matching down version of box(). + \param[in] b down box type + */ + void down_box(Fl_Boxtype b) {down_box_ = b;} + + /// (for backwards compatibility) + void shortcut(const char *s) {shortcut(fl_old_shortcut(s));} + + /// (for backwards compatibility) + Fl_Color down_color() const {return selection_color();} + + /// (for backwards compatibility) + void down_color(unsigned c) {selection_color(c);} +}; + +#endif + +// +// End of "$Id: Fl_Button.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Cairo.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Cairo.H new file mode 100644 index 0000000..f4529a4 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Cairo.H @@ -0,0 +1,97 @@ +// +// "$Id: Fl_Cairo.H 7903 2010-11-28 21:06:39Z matt $" +// +// Main header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Handling transparently platform dependent cairo include files +*/ + +#ifndef FL_CAIRO_H +# define FL_CAIRO_H +# ifdef HAVE_CAIRO + +// Cairo is currently supported for the following platforms: +// Win32, Apple Quartz, X11 + +# include + +# if defined(USE_X11) // X11 +# include +# elif defined(WIN32) +# include +# elif defined(__APPLE_QUARTZ__) +# include +# else +# error Cairo is not supported on that platform. +# endif + +/** + \addtogroup group_cairo + @{ +*/ + +/** + Contains all the necessary info on the current cairo context. + A private internal & unique corresponding object is created to + permit cairo context state handling while keeping it opaque. + For internal use only. + \note Only available when configure has the --enable-cairo option +*/ +class FL_EXPORT Fl_Cairo_State { +public: + Fl_Cairo_State() : cc_(0), own_cc_(false), autolink_(false), window_(0), gc_(0) {} + + // access attributes + cairo_t* cc() const {return cc_;} ///< Gets the current cairo context + bool autolink() const {return autolink_;} ///< Gets the autolink option. See Fl::cairo_autolink_context(bool) + /** Sets the current cairo context, \p own indicates cc deletion is handle externally by user */ + void cc(cairo_t* c, bool own=true) { + if (cc_ && own_cc_) cairo_destroy(cc_); + cc_=c; + if (!cc_) window_=0; + own_cc_=own; + } + void autolink(bool b); ///< Sets the autolink option, only available with --enable-cairoext + void window(void* w) {window_=w;} ///< Sets the window \p w to keep track on + void* window() const {return window_;} ///< Gets the last window attached to a cc + void gc(void* c) {gc_=c;} ///< Sets the gc \p c to keep track on + void* gc() const {return gc_;} ///< Gets the last gc attached to a cc + +private: + cairo_t * cc_; // contains the unique autoupdated cairo context + bool own_cc_; // indicates whether we must delete the cc, useful for internal cleanup + bool autolink_; // true by default, permits to prevent the automatic cairo mapping on fltk windows for custom cairo implementations + void* window_, *gc_; // for keeping track internally of last win+gc treated +}; + +/** @} */ + +# endif // HAVE_CAIRO +#endif // FL_CAIRO_H + +// +// End of "$Id: Fl_Cairo.H 7903 2010-11-28 21:06:39Z matt $" . +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Cairo_Window.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Cairo_Window.H new file mode 100644 index 0000000..169b248 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Cairo_Window.H @@ -0,0 +1,92 @@ +// +// "$Id: Fl_Cairo_Window.H 7903 2010-11-28 21:06:39Z matt $" +// +// Main header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Cairo_Window Handling transparently a fltk window incorporte a cairo draw callback. +*/ + +#ifndef FL_CAIRO_WINDOW_H +# define FL_CAIRO_WINDOW_H +# ifdef HAVE_CAIRO + +// Cairo is currently supported for the following platforms: +// Win32, Apple Quartz, X11 +# include +# include + +/** + \addtogroup group_cairo + @{ +*/ + +/** + This defines a pre-configured cairo fltk window. + This class overloads the virtual draw() method for you, + so that the only thing you have to do is to provide your cairo code. + All cairo context handling is achieved transparently. + \note You can alternatively define your custom cairo fltk window, + and thus at least override the draw() method to provide custom cairo + support. In this case you will probably use Fl::cairo_make_current(Fl_Window*) + to attach a context to your window. You should do it only when your window is + the current window. \see Fl_Window::current() +*/ +class FL_EXPORT Fl_Cairo_Window : public Fl_Double_Window { + +public: + Fl_Cairo_Window(int w, int h) : Fl_Double_Window(w,h),draw_cb_(0) {} + +protected: + /** Overloaded to provide cairo callback support */ + void draw() { + Fl_Double_Window::draw(); + // manual method ? if yes explicitly get a cairo_context here + if (!Fl::cairo_autolink_context()) + Fl::cairo_make_current(this); + if (draw_cb_) draw_cb_(this, Fl::cairo_cc()); + } + +public: + /** This defines the cairo draw callback prototype that you must further */ + typedef void (*cairo_draw_cb) (Fl_Cairo_Window* self, cairo_t* def); + /** + You must provide a draw callback which will implement your cairo rendering. + This method will permit you to set your cairo callback to \p cb. + */ + void set_draw_cb(cairo_draw_cb cb){draw_cb_=cb;} +private: + cairo_draw_cb draw_cb_; +}; + + +/** @} */ + +# endif // HAVE_CAIRO +#endif // FL_CAIRO_WINDOW_H + +// +// End of "$Id: Fl_Cairo_Window.H 7903 2010-11-28 21:06:39Z matt $" . +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Chart.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Chart.H new file mode 100644 index 0000000..526c8b1 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Chart.H @@ -0,0 +1,160 @@ +// +// "$Id: Fl_Chart.H 7903 2010-11-28 21:06:39Z matt $" +// +// Forms chart header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Chart widget . */ + +#ifndef Fl_Chart_H +#define Fl_Chart_H + +#ifndef Fl_Widget_H +#include "Fl_Widget.H" +#endif + +// values for type() +#define FL_BAR_CHART 0 /**< type() for Bar Chart variant */ +#define FL_HORBAR_CHART 1 /**< type() for Horizontal Bar Chart variant */ +#define FL_LINE_CHART 2 /**< type() for Line Chart variant */ +#define FL_FILL_CHART 3 /**< type() for Fill Line Chart variant */ +#define FL_SPIKE_CHART 4 /**< type() for Spike Chart variant */ +#define FL_PIE_CHART 5 /**< type() for Pie Chart variant */ +#define FL_SPECIALPIE_CHART 6 /**< type() for Special Pie Chart variant */ + +#define FL_FILLED_CHART FL_FILL_CHART /**< for compatibility */ + +#define FL_CHART_MAX 128 /**< max entries per chart */ +#define FL_CHART_LABEL_MAX 18 /**< max label length for entry */ + +/** For internal use only */ +struct FL_CHART_ENTRY { + float val; /**< For internal use only. */ + unsigned col; /**< For internal use only. */ + char str[FL_CHART_LABEL_MAX+1]; /**< For internal use only. */ +}; + +/** + \class Fl_Chart + \brief Fl_Chart displays simple charts. + It is provided for Forms compatibility. + + \image html charts.gif + \image latex charts.eps "Fl_Chart" width=10cm + \todo Refactor Fl_Chart::type() information. + + The type of an Fl_Chart object can be set using type(uchar t) to: + \li \c FL_BAR_CHART: Each sample value is drawn as a vertical bar. + \li \c FL_FILLED_CHART: The chart is filled from the bottom of the graph + to the sample values. + \li \c FL_HORBAR_CHART: Each sample value is drawn as a horizontal bar. + \li \c FL_LINE_CHART: The chart is drawn as a polyline with vertices at + each sample value. + \li \c FL_PIE_CHART: A pie chart is drawn with each sample value being + drawn as a proportionate slice in the circle. + \li \c FL_SPECIALPIE_CHART: Like \c FL_PIE_CHART, but the first slice is + separated from the pie. + \li \c FL_SPIKE_CHART: Each sample value is drawn as a vertical line. + */ +class FL_EXPORT Fl_Chart : public Fl_Widget { + int numb; + int maxnumb; + int sizenumb; + FL_CHART_ENTRY *entries; + double min,max; + uchar autosize_; + Fl_Font textfont_; + Fl_Fontsize textsize_; + Fl_Color textcolor_; +protected: + void draw(); +public: + Fl_Chart(int X, int Y, int W, int H, const char *L = 0); + + ~Fl_Chart(); + + void clear(); + + void add(double val, const char *str = 0, unsigned col = 0); + + void insert(int ind, double val, const char *str = 0, unsigned col = 0); + + void replace(int ind, double val, const char *str = 0, unsigned col = 0); + + /** + Gets the lower and upper bounds of the chart values. + \param[out] a, b are set to lower, upper + */ + void bounds(double *a,double *b) const {*a = min; *b = max;} + + void bounds(double a,double b); + + /** + Returns the number of data values in the chart. + */ + int size() const {return numb;} + + void size(int W, int H) { Fl_Widget::size(W, H); } + + /** + Gets the maximum number of data values for a chart. + */ + int maxsize() const {return maxnumb;} + + void maxsize(int m); + + /** Gets the chart's text font */ + Fl_Font textfont() const {return textfont_;} + /** Sets the chart's text font to \p s. */ + void textfont(Fl_Font s) {textfont_ = s;} + + /** Gets the chart's text size */ + Fl_Fontsize textsize() const {return textsize_;} + /** gets the chart's text size to \p s. */ + void textsize(Fl_Fontsize s) {textsize_ = s;} + + /** Gets the chart's text color */ + Fl_Color textcolor() const {return textcolor_;} + /** gets the chart's text color to \p n. */ + void textcolor(Fl_Color n) {textcolor_ = n;} + + /** + Get whether the chart will automatically adjust the bounds of the chart. + \returns non-zero if auto-sizing is enabled and zero if disabled. + */ + uchar autosize() const {return autosize_;} + + /** + Set whether the chart will automatically adjust the bounds of the chart. + \param[in] n non-zero to enable automatic resizing, zero to disable. + */ + void autosize(uchar n) {autosize_ = n;} +}; + +#endif + +// +// End of "$Id: Fl_Chart.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Check_Browser.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Check_Browser.H new file mode 100644 index 0000000..57cd961 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Check_Browser.H @@ -0,0 +1,122 @@ +// +// "$Id: Fl_Check_Browser.H 7903 2010-11-28 21:06:39Z matt $" +// +// Fl_Check_Browser header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Check_Browser widget . */ + +#ifndef Fl_Check_Browser_H +#define Fl_Check_Browser_H + +#include "Fl.H" +#include "Fl_Browser_.H" + +/** + The Fl_Check_Browser widget displays a scrolling list of text + lines that may be selected and/or checked by the user. +*/ +class FL_EXPORT Fl_Check_Browser : public Fl_Browser_ { + /* required routines for Fl_Browser_ subclass: */ + + void *item_first() const; + void *item_next(void *) const; + void *item_prev(void *) const; + int item_height(void *) const; + int item_width(void *) const; + void item_draw(void *, int, int, int, int) const; + void item_select(void *, int); + int item_selected(void *) const; + + /* private data */ + + public: // IRIX 5.3 C++ compiler doesn't support private structures... + +#ifndef FL_DOXYGEN + /** For internal use only. */ + struct cb_item { + cb_item *next; /**< For internal use only. */ + cb_item *prev; /**< For internal use only. */ + char checked; /**< For internal use only. */ + char selected; /**< For internal use only. */ + char *text; /**< For internal use only. */ + }; +#endif // !FL_DOXYGEN + + private: + + cb_item *first; + cb_item *last; + cb_item *cache; + int cached_item; + int nitems_; + int nchecked_; + cb_item *find_item(int) const; + int lineno(cb_item *) const; + + public: + + Fl_Check_Browser(int x, int y, int w, int h, const char *l = 0); + /** The destructor deletes all list items and destroys the browser. */ + ~Fl_Check_Browser() { clear(); } + int add(char *s); // add an (unchecked) item + int add(char *s, int b); // add an item and set checked + // both return the new nitems() + int remove(int item); // delete an item. Returns nitems() + + // inline const char * methods to avoid breaking binary compatibility... + /** See int Fl_Check_Browser::add(char *s) */ + int add(const char *s) { return add((char *)s); } + /** See int Fl_Check_Browser::add(char *s) */ + int add(const char *s, int b) { return add((char *)s, b); } + + void clear(); // delete all items + /** + Returns how many lines are in the browser. The last line number is equal to + this. + */ + int nitems() const { return nitems_; } + /** Returns how many items are currently checked. */ + int nchecked() const { return nchecked_; } + int checked(int item) const; + void checked(int item, int b); + /** Equivalent to Fl_Check_Browser::checked(item, 1). */ + void set_checked(int item) { checked(item, 1); } + void check_all(); + void check_none(); + int value() const; // currently selected item + char *text(int item) const; // returns pointer to internal buffer + + protected: + + int handle(int); +}; + +#endif // Fl_Check_Browser_H + +// +// End of "$Id: Fl_Check_Browser.H 7903 2010-11-28 21:06:39Z matt $". +// + diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Check_Button.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Check_Button.H new file mode 100644 index 0000000..4145746 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Check_Button.H @@ -0,0 +1,60 @@ +// +// "$Id: Fl_Check_Button.H 7903 2010-11-28 21:06:39Z matt $" +// +// Check button header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Check_Button widget . */ + +#ifndef Fl_Check_Button_H +#define Fl_Check_Button_H + +#include "Fl_Light_Button.H" + +/** + \class Fl_Check_Button + \brief A button with an "checkmark" to show its status. + + \image html Fl_Check_Button.gif + \image latex Fl_Check_Button.eps "Fl_Check_Button" width=4cm + Buttons generate callbacks when they are clicked by the user. You control + exactly when and how by changing the values for type() and when(). + + The Fl_Check_Button subclass displays its "ON" state by showing a "checkmark" + rather than drawing itself pushed in. + + \todo Refactor Fl_Check_Button doxygen comments (add color() info etc?) + \todo Generate Fl_Check_Button.gif with visible checkmark. + */ +class FL_EXPORT Fl_Check_Button : public Fl_Light_Button { +public: + Fl_Check_Button(int X, int Y, int W, int H, const char *L = 0); +}; + +#endif + +// +// End of "$Id: Fl_Check_Button.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Choice.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Choice.H new file mode 100644 index 0000000..d5c5efa --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Choice.H @@ -0,0 +1,108 @@ +// +// "$Id: Fl_Choice.H 7903 2010-11-28 21:06:39Z matt $" +// +// Choice header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Choice widget . */ + +#ifndef Fl_Choice_H +#define Fl_Choice_H + +#include "Fl_Menu_.H" + +/** + \class Fl_Choice + \brief A button that is used to pop up a menu. + + This is a button that, when pushed, pops up a menu (or hierarchy of menus) + defined by an array of Fl_Menu_Item objects. + Motif calls this an OptionButton. + + The only difference between this and a Fl_Menu_Button is that the name of + the most recent chosen menu item is displayed inside the box, while the + label is displayed outside the box. However, since the use of this is most + often to control a single variable rather than do individual callbacks, + some of the Fl_Menu_Button methods are redescribed here in those terms. + + When the user picks an item off the menu the value() is set to that item + and then the item's callback is done with the menu_button as the + \c Fl_Widget* argument. If the item does not have a callback the + menu_button's callback is done instead. + + All three mouse buttons pop up the menu. The Forms behavior of the first + two buttons to increment/decrement the choice is not implemented. This + could be added with a subclass, however. + + The menu will also pop up in response to shortcuts indicated by putting + a '\&' character in the label(). See Fl_Button::shortcut(int s) for a + description of this. + + Typing the shortcut() of any of the items will do exactly the same as when + you pick the item with the mouse. The '\&' character in item names are + only looked at when the menu is popped up, however. + + \image html choice.gif + \image latex choice.eps "Fl_Choice" width=4cm + \todo Refactor the doxygen comments for Fl_Choice changed() documentation. + + \li int Fl_Widget::changed() const + This value is true the user picks a different value. It is turned + off by value() and just before doing a callback (the callback can turn + it back on if desired). + \li void Fl_Widget::set_changed() + This method sets the changed() flag. + \li void Fl_Widget::clear_changed() + This method clears the changed() flag. + \li Fl_Boxtype Fl_Choice::down_box() const + Gets the current down box, which is used when the menu is popped up. + The default down box type is \c FL_DOWN_BOX. + \li void Fl_Choice::down_box(Fl_Boxtype b) + Sets the current down box type to \p b. + */ +class FL_EXPORT Fl_Choice : public Fl_Menu_ { +protected: + void draw(); +public: + int handle(int); + + Fl_Choice(int X, int Y, int W, int H, const char *L = 0); + + /** + Gets the index of the last item chosen by the user. + The index is zero initially. + */ + int value() const {return Fl_Menu_::value();} + + int value(int v); + + int value(const Fl_Menu_Item* v); +}; + +#endif + +// +// End of "$Id: Fl_Choice.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Clock.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Clock.H new file mode 100644 index 0000000..aefd4d6 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Clock.H @@ -0,0 +1,137 @@ +// +// "$Id: Fl_Clock.H 7903 2010-11-28 21:06:39Z matt $" +// +// Clock header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Clock, Fl_Clock_Output widgets . */ + +#ifndef Fl_Clock_H +#define Fl_Clock_H + +#ifndef Fl_Widget_H +#include "Fl_Widget.H" +#endif + +// values for type: +#define FL_SQUARE_CLOCK 0 /**< type() of Square Clock variant */ +#define FL_ROUND_CLOCK 1 /**< type() of Round Clock variant */ +#define FL_ANALOG_CLOCK FL_SQUARE_CLOCK /**< An analog clock is square */ +#define FL_DIGITAL_CLOCK FL_SQUARE_CLOCK /**< Not yet implemented */ + +// fabien: Please keep the horizontal formatting of both images in class desc, +// don't lose vert. space for nothing! + +/** + \class Fl_Clock_Output + \brief This widget can be used to display a program-supplied time. + + The time shown on the clock is not updated. To display the current time, + use Fl_Clock instead. + + \htmlonly
+
type() FL_SQUARE_CLOCK and FL_ROUND_CLOCK
\endhtmlonly + \image html clock.gif + \htmlonly \endhtmlonly + \image html round_clock.gif + \htmlonly
\endhtmlonly + \image latex clock.eps "FL_SQUARE_CLOCK type" width=4cm + \image latex round_clock.eps "FL_ROUND_CLOCK type" width=4cm + */ +class FL_EXPORT Fl_Clock_Output : public Fl_Widget { + int hour_, minute_, second_; + ulong value_; + void drawhands(Fl_Color,Fl_Color); // part of draw +protected: + void draw(); + void draw(int X, int Y, int W, int H); +public: + + Fl_Clock_Output(int X, int Y, int W, int H, const char *L = 0); + + void value(ulong v); // set to this Unix time + + void value(int H, int m, int s); + + /** + Returns the displayed time. + Returns the time in seconds since the UNIX epoch (January 1, 1970). + \see value(ulong) + */ + ulong value() const {return value_;} + + /** + Returns the displayed hour (0 to 23). + \see value(), minute(), second() + */ + int hour() const {return hour_;} + + /** + Returns the displayed minute (0 to 59). + \see value(), hour(), second() + */ + int minute() const {return minute_;} + + /** + Returns the displayed second (0 to 60, 60=leap second). + \see value(), hour(), minute() + */ + int second() const {return second_;} +}; + +// a Fl_Clock displays the current time always by using a timeout: + +/** + \class Fl_Clock + \brief This widget provides a round analog clock display. + + Fl_Clock is provided for Forms compatibility. + It installs a 1-second timeout callback using Fl::add_timeout(). + You can choose the rounded or square type of the clock with type(), see below. + \htmlonly
+
type() FL_SQUARE_CLOCK and FL_ROUND_CLOCK
\endhtmlonly + \image html clock.gif + \htmlonly \endhtmlonly + \image html round_clock.gif + \htmlonly
\endhtmlonly + \image latex clock.eps "FL_SQUARE_CLOCK type" width=4cm + \image latex round_clock.eps "FL_ROUND_CLOCK type" width=4cm + */ +class FL_EXPORT Fl_Clock : public Fl_Clock_Output { +public: + int handle(int); + + Fl_Clock(int X, int Y, int W, int H, const char *L = 0); + + Fl_Clock(uchar t, int X, int Y, int W, int H, const char *L); + + ~Fl_Clock(); +}; + +#endif + +// +// End of "$Id: Fl_Clock.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Color_Chooser.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Color_Chooser.H new file mode 100644 index 0000000..0001bad --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Color_Chooser.H @@ -0,0 +1,199 @@ +// +// "$Id: Fl_Color_Chooser.H 7903 2010-11-28 21:06:39Z matt $" +// +// Color chooser header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/** \file + Fl_Color_Chooser widget . */ + +// The color chooser object and the color chooser popup. The popup +// is just a window containing a single color chooser and some boxes +// to indicate the current and cancelled color. + +#ifndef Fl_Color_Chooser_H +#define Fl_Color_Chooser_H + +#include +#include +#include +#include +#include + +#ifndef FL_DOXYGEN + +/** For internal use only */ +class FL_EXPORT Flcc_HueBox : public Fl_Widget { + int px, py; +protected: + void draw(); + int handle_key(int); +public: + int handle(int); + Flcc_HueBox(int X, int Y, int W, int H) : Fl_Widget(X,Y,W,H) { + px = py = 0;} +}; + +/** For internal use only */ +class FL_EXPORT Flcc_ValueBox : public Fl_Widget { + int py; +protected: + void draw(); + int handle_key(int); +public: + int handle(int); + Flcc_ValueBox(int X, int Y, int W, int H) : Fl_Widget(X,Y,W,H) { + py = 0;} +}; + +/** For internal use only */ +class FL_EXPORT Flcc_Value_Input : public Fl_Value_Input { +public: + int format(char*); + Flcc_Value_Input(int X, int Y, int W, int H) : Fl_Value_Input(X,Y,W,H) {} +}; + +#endif // !FL_DOXYGEN + +/** \addtogroup group_comdlg + @{ */ + +/** + \class Fl_Color_Chooser + \brief The Fl_Color_Chooser widget provides a standard RGB color chooser. + + \image html fl_color_chooser.jpg + \image latex fl_color_chooser.eps "fl_color_chooser()" width=5cm + + You can place any number of the widgets into a panel of your own design. + The diagram shows the widget as part of a color chooser dialog created by + the fl_color_chooser() function. The Fl_Color_Chooser widget contains the + hue box, value slider, and rgb input fields from the above diagram (it + does not have the color chips or the Cancel or OK buttons). + The callback is done every time the user changes the rgb value. It is not + done if they move the hue control in a way that produces the \e same rgb + value, such as when saturation or value is zero. + + The fl_color_chooser() function pops up a window to let the user pick an + arbitrary RGB color. They can pick the hue and saturation in the "hue box" + on the left (hold down CTRL to just change the saturation), and the + brightness using the vertical slider. Or they can type the 8-bit numbers + into the RGB Fl_Value_Input fields, or drag the mouse across them to adjust + them. The pull-down menu lets the user set the input fields to show RGB, + HSV, or 8-bit RGB (0 to 255). + + fl_color_chooser() returns non-zero if the user picks ok, and updates the + RGB values. If the user picks cancel or closes the window this returns + zero and leaves RGB unchanged. + + If you use the color chooser on an 8-bit screen, it will allocate all the + available colors, leaving you no space to exactly represent the color the + user picks! You can however use fl_rectf() to fill a region with a simulated + color using dithering. + */ +/** @} */ +class FL_EXPORT Fl_Color_Chooser : public Fl_Group { + Flcc_HueBox huebox; + Flcc_ValueBox valuebox; + Fl_Choice choice; + Flcc_Value_Input rvalue; + Flcc_Value_Input gvalue; + Flcc_Value_Input bvalue; + Fl_Box resize_box; + double hue_, saturation_, value_; + double r_, g_, b_; + void set_valuators(); + static void rgb_cb(Fl_Widget*, void*); + static void mode_cb(Fl_Widget*, void*); +public: + + /** + Returns which Fl_Color_Chooser variant is currently active + \return color modes are rgb(0), byte(1), hex(2), or hsv(3) + */ + int mode() {return choice.value();} + + /** + Set which Fl_Color_Chooser variant is currently active + \param[in] newMode color modes are rgb(0), byte(1), hex(2), or hsv(3) + */ + void mode(int newMode); + + /** + Returns the current hue. + 0 <= hue < 6. Zero is red, one is yellow, two is green, etc. + This value is convenient for the internal calculations - some other + systems consider hue to run from zero to one, or from 0 to 360. + */ + double hue() const {return hue_;} + + /** + Returns the saturation. + 0 <= saturation <= 1. + */ + double saturation() const {return saturation_;} + + /** + Returns the value/brightness. + 0 <= value <= 1. + */ + double value() const {return value_;} + + /** + Returns the current red value. + 0 <= r <= 1. + */ + double r() const {return r_;} + + /** + Returns the current green value. + 0 <= g <= 1. + */ + double g() const {return g_;} + + /** + Returns the current blue value. + 0 <= b <= 1. + */ + double b() const {return b_;} + + int hsv(double H, double S, double V); + + int rgb(double R, double G, double B); + + static void hsv2rgb(double H, double S, double V, double& R, double& G, double& B); + + static void rgb2hsv(double R, double G, double B, double& H, double& S, double& V); + + Fl_Color_Chooser(int X, int Y, int W, int H, const char *L = 0); +}; + +FL_EXPORT int fl_color_chooser(const char* name, double& r, double& g, double& b, int m=-1); +FL_EXPORT int fl_color_chooser(const char* name, uchar& r, uchar& g, uchar& b, int m=-1); + +#endif + +// +// End of "$Id: Fl_Color_Chooser.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Counter.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Counter.H new file mode 100644 index 0000000..912bc5a --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Counter.H @@ -0,0 +1,124 @@ +// +// "$Id: Fl_Counter.H 7903 2010-11-28 21:06:39Z matt $" +// +// Counter header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Counter widget . */ + +// A numerical value with up/down step buttons. From Forms. + +#ifndef Fl_Counter_H +#define Fl_Counter_H + +#ifndef Fl_Valuator_H +#include "Fl_Valuator.H" +#endif + +// values for type(): +#define FL_NORMAL_COUNTER 0 /**< type() for counter with fast buttons */ +#define FL_SIMPLE_COUNTER 1 /**< type() for counter without fast buttons */ + +/** + Controls a single floating point value with button (or keyboard) arrows. + Double arrows buttons achieve larger steps than simple arrows. + \see Fl_Spinner for value input with vertical step arrows. +

\image html counter.gif

+ \image latex counter.eps "Fl_Counter" width=4cm + + \todo Refactor the doxygen comments for Fl_Counter type() documentation. + + The type of an Fl_Counter object can be set using type(uchar t) to: + \li \c FL_NORMAL_COUNTER: Displays a counter with 4 arrow buttons. + \li \c FL_SIMPLE_COUNTER: Displays a counter with only 2 arrow buttons. +*/ +class FL_EXPORT Fl_Counter : public Fl_Valuator { + + Fl_Font textfont_; + Fl_Fontsize textsize_; + Fl_Color textcolor_; + double lstep_; + uchar mouseobj; + static void repeat_callback(void *); + int calc_mouseobj(); + void increment_cb(); + +protected: + + void draw(); + +public: + + int handle(int); + + Fl_Counter(int X, int Y, int W, int H, const char* L = 0); + ~Fl_Counter(); + + /** + Sets the increment for the large step buttons. + The default value is 1.0. + \param[in] a large step increment. + */ + void lstep(double a) {lstep_ = a;} + + /** + Sets the increments for the normal and large step buttons. + \param[in] a, b normal and large step increments. + */ + void step(double a,double b) {Fl_Valuator::step(a); lstep_ = b;} + + /** + Sets the increment for the normal step buttons. + \param[in] a normal step increment. + */ + void step(double a) {Fl_Valuator::step(a);} + + /** + Returns the increment for normal step buttons. + */ + double step() const {return Fl_Valuator::step();} + + /** Gets the text font */ + Fl_Font textfont() const {return textfont_;} + /** Sets the text font to \p s */ + void textfont(Fl_Font s) {textfont_ = s;} + + /** Gets the font size */ + Fl_Fontsize textsize() const {return textsize_;} + /** Sets the font size to \p s */ + void textsize(Fl_Fontsize s) {textsize_ = s;} + + /** Gets the font color */ + Fl_Color textcolor() const {return textcolor_;} + /** Sets the font color to \p s */ + void textcolor(Fl_Color s) {textcolor_ = s;} + +}; + +#endif + +// +// End of "$Id: Fl_Counter.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Device.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Device.H new file mode 100644 index 0000000..672dd9b --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Device.H @@ -0,0 +1,381 @@ +// +// "$Id: Fl_Device.H 7719 2010-10-12 09:25:37Z manolo $" +// +// Definition of classes Fl_Device, Fl_Graphics_Driver, Fl_Surface_Device, Fl_Display_Device +// for the Fast Light Tool Kit (FLTK). +// +// Copyright 2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// +/** \file Fl_Device.H + \brief declaration of classes Fl_Device, Fl_Graphics_Driver, Fl_Surface_Device, Fl_Display_Device. +*/ + +#ifndef Fl_Device_H +#define Fl_Device_H + +#include +#include +#include +#include +#include +#include +#ifdef WIN32 +#include +#elif defined(__APPLE__) +#else +#include +#endif + +class Fl_Graphics_Driver; +class Fl_Display_Device; +class Fl_Surface_Device; +/** \brief Points to the driver that currently receives all graphics requests */ +FL_EXPORT extern Fl_Graphics_Driver *fl_graphics_driver; +/** \brief Points to the surface that currently receives all graphics requests */ +FL_EXPORT extern Fl_Surface_Device *fl_surface; +/** \brief Points to the platform's display */ +FL_EXPORT extern Fl_Display_Device *fl_display_device; + +/** + signature of image generation callback function. + \param[in] data user data passed to function + \param[in] x,y,w position and width of scan line in image + \param[out] buf buffer for generated image data. You must copy \p w + pixels from scanline \p y, starting at pixel \p x + to this buffer. + */ +typedef void (*Fl_Draw_Image_Cb)(void* data,int x,int y,int w,uchar* buf); + +/** + \brief All graphical output devices and all graphics systems. + */ +class Fl_Device { +protected: + /** \brief The device type */ + const char *type_; + /** \brief A string that identifies each subclass of Fl_Device. + * + Function type() applied to a device of this class returns this string. + */ + static const char *device_type; +public: + /** + @brief An RTTI emulation of device classes. + * + The type of an instance of an Fl_Device subclass can be checked with code such as: + \code + if ( instance->type() == Fl_Printer::device_type ) { ... } + \endcode + */ + inline const char *type() {return type_;}; +}; + +/** + \brief A virtual class subclassed for each graphics driver FLTK uses. + * + The protected virtual methods of this class are those that a graphics driver should implement to + support all of FLTK drawing functions. +
The public API for drawing operations is functionally presented in \ref drawing and as function lists + in the \ref fl_drawings and \ref fl_attributes modules. + */ +class Fl_Graphics_Driver : public Fl_Device { +protected: +/* ** \brief red color for background and/or mixing if device does not support masking or alpha * + uchar bg_r_; + ** \brief green color for background and/or mixing if device does not support masking or alpha * + uchar bg_g_; + ** \brief blue color for background and/or mixing if device does not support masking or alpha * + uchar bg_b_; */ + friend class Fl_Pixmap; + friend class Fl_Bitmap; + friend class Fl_RGB_Image; + friend class Fl_PostScript_Graphics_Driver; + friend void fl_rect(int x, int y, int w, int h); + friend void fl_rectf(int x, int y, int w, int h); + friend void fl_line_style(int style, int width, char* dashes); + friend void fl_xyline(int x, int y, int x1); + friend void fl_xyline(int x, int y, int x1, int y2); + friend void fl_xyline(int x, int y, int x1, int y2, int x3); + friend void fl_yxline(int x, int y, int y1); + friend void fl_yxline(int x, int y, int y1, int x2); + friend void fl_yxline(int x, int y, int y1, int x2, int y3); + friend void fl_line(int x, int y, int x1, int y1); + friend void fl_line(int x, int y, int x1, int y1, int x2, int y2); + friend void fl_draw(const char *str, int n, int x, int y); +#ifdef __APPLE__ + friend void fl_draw(const char *str, int n, float x, float y); +#endif + friend void fl_draw(int angle, const char *str, int n, int x, int y); + friend void fl_rtl_draw(const char *str, int n, int x, int y); + friend void fl_font(Fl_Font face, Fl_Fontsize size); + friend void fl_color(Fl_Color c); + friend void fl_color(uchar r, uchar g, uchar b); + friend void fl_point(int x, int y); + friend void fl_loop(int x0, int y0, int x1, int y1, int x2, int y2); + friend void fl_loop(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3); + friend void fl_polygon(int x0, int y0, int x1, int y1, int x2, int y2); + friend void fl_polygon(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3); + friend void fl_begin_points(); + friend void fl_begin_line(); + friend void fl_begin_loop(); + friend void fl_begin_polygon(); + friend void fl_vertex(double x, double y); + friend void fl_curve(double X0, double Y0, double X1, double Y1, double X2, double Y2, double X3, double Y3); + friend void fl_circle(double x, double y, double r); + friend void fl_arc(double x, double y, double r, double start, double end); + friend void fl_arc(int x, int y, int w, int h, double a1, double a2); + friend void fl_pie(int x, int y, int w, int h, double a1, double a2); + friend void fl_end_points(); + friend void fl_end_line(); + friend void fl_end_loop(); + friend void fl_end_polygon(); + friend void fl_transformed_vertex(double xf, double yf); + friend void fl_push_clip(int x, int y, int w, int h); + friend int fl_clip_box(int x, int y, int w, int h, int &X, int &Y, int &W, int &H); + friend int fl_not_clipped(int x, int y, int w, int h); + friend void fl_push_no_clip(); + friend void fl_pop_clip(); + friend void fl_begin_complex_polygon(); + friend void fl_gap(); + friend void fl_end_complex_polygon(); + friend void fl_draw_image(const uchar* buf, int X,int Y,int W,int H, int D, int L); + friend void fl_draw_image_mono(const uchar* buf, int X,int Y,int W,int H, int D, int L); + friend void fl_draw_image(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D); + friend FL_EXPORT void fl_draw_image_mono(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D); + + /** \brief The constructor. */ + Fl_Graphics_Driver() {}; + /** \brief see fl_rect(int x, int y, int w, int h). */ + virtual void rect(int x, int y, int w, int h); + /** \brief see fl_rectf(int x, int y, int w, int h). */ + virtual void rectf(int x, int y, int w, int h); + /** \brief see fl_line_style(int style, int width, char* dashes). */ + virtual void line_style(int style, int width=0, char* dashes=0); + /** \brief see fl_xyline(int x, int y, int x1). */ + virtual void xyline(int x, int y, int x1); + /** \brief see fl_xyline(int x, int y, int x1, int y2). */ + virtual void xyline(int x, int y, int x1, int y2); + /** \brief see fl_xyline(int x, int y, int x1, int y2, int x3). */ + virtual void xyline(int x, int y, int x1, int y2, int x3); + /** \brief see fl_yxline(int x, int y, int y1). */ + virtual void yxline(int x, int y, int y1); + /** \brief see fl_yxline(int x, int y, int y1, int x2). */ + virtual void yxline(int x, int y, int y1, int x2); + /** \brief see fl_yxline(int x, int y, int y1, int x2, int y3). */ + virtual void yxline(int x, int y, int y1, int x2, int y3); + /** \brief see fl_line(int x, int y, int x1, int y1). */ + virtual void line(int x, int y, int x1, int y1); + /** \brief see fl_line(int x, int y, int x1, int y1, int x2, int y2). */ + virtual void line(int x, int y, int x1, int y1, int x2, int y2); + /** \brief see fl_draw(const char *str, int n, int x, int y). */ + virtual void draw(const char *str, int n, int x, int y); + /** \brief see fl_draw(int angle, const char *str, int n, int x, int y). */ + virtual void draw(int angle, const char *str, int n, int x, int y); + /** \brief see fl_rtl_draw(const char *str, int n, int x, int y). */ + virtual void rtl_draw(const char *str, int n, int x, int y); + /** \brief see fl_font(Fl_Font face, Fl_Fontsize size). */ + virtual void font(Fl_Font face, Fl_Fontsize size); + /** \brief see fl_color(Fl_Color c). */ + virtual void color(Fl_Color c); + /** \brief see fl_color(uchar r, uchar g, uchar b). */ + virtual void color(uchar r, uchar g, uchar b); + /** \brief see fl_point(int x, int y). */ + virtual void point(int x, int y); + /** \brief see fl_loop(int x0, int y0, int x1, int y1, int x2, int y2). */ + virtual void loop(int x0, int y0, int x1, int y1, int x2, int y2); + /** \brief see fl_loop(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3). */ + virtual void loop(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3); + /** \brief see fl_polygon(int x0, int y0, int x1, int y1, int x2, int y2). */ + virtual void polygon(int x0, int y0, int x1, int y1, int x2, int y2); + /** \brief see fl_polygon(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3). */ + virtual void polygon(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3); + /** \brief see fl_begin_points(). */ + virtual void begin_points(); + /** \brief see fl_begin_line(). */ + virtual void begin_line(); + /** \brief see fl_begin_loop(). */ + virtual void begin_loop(); + /** \brief see fl_begin_polygon(). */ + virtual void begin_polygon(); + /** \brief see fl_vertex(double x, double y). */ + virtual void vertex(double x, double y); + /** \brief see fl_curve(double X0, double Y0, double X1, double Y1, double X2, double Y2, double X3, double Y3). */ + virtual void curve(double X0, double Y0, double X1, double Y1, double X2, double Y2, double X3, double Y3); + /** \brief see fl_circle(double x, double y, double r). */ + virtual void circle(double x, double y, double r); + /** \brief see fl_arc(double x, double y, double r, double start, double end). */ + virtual void arc(double x, double y, double r, double start, double end); + /** \brief see fl_arc(int x, int y, int w, int h, double a1, double a2). */ + virtual void arc(int x, int y, int w, int h, double a1, double a2); + /** \brief see fl_pie(int x, int y, int w, int h, double a1, double a2). */ + virtual void pie(int x, int y, int w, int h, double a1, double a2); + /** \brief see fl_end_points(). */ + virtual void end_points(); + /** \brief see fl_end_line(). */ + virtual void end_line(); + /** \brief see fl_end_loop(). */ + virtual void end_loop(); + /** \brief see fl_end_polygon(). */ + virtual void end_polygon(); + /** \brief see fl_begin_complex_polygon(). */ + virtual void begin_complex_polygon(); + /** \brief see fl_gap(). */ + virtual void gap(); + /** \brief see fl_end_complex_polygon(). */ + virtual void end_complex_polygon(); + /** \brief see fl_transformed_vertex(double xf, double yf). */ + virtual void transformed_vertex(double xf, double yf); + /** \brief see fl_push_clip(int x, int y, int w, int h). */ + virtual void push_clip(int x, int y, int w, int h); + /** \brief see fl_clip_box(int x, int y, int w, int h, int &X, int &Y, int &W, int &H). */ + virtual int clip_box(int x, int y, int w, int h, int &X, int &Y, int &W, int &H); + /** \brief see fl_not_clipped(int x, int y, int w, int h). */ + virtual int not_clipped(int x, int y, int w, int h); + /** \brief see fl_push_no_clip(). */ + virtual void push_no_clip(); + /** \brief see fl_pop_clip(). */ + virtual void pop_clip(); + // Images + /** \brief see fl_draw_image(const uchar* buf, int X,int Y,int W,int H, int D, int L). */ + virtual void draw_image(const uchar* buf, int X,int Y,int W,int H, int D=3, int L=0); + /** \brief see fl_draw_image_mono(const uchar* buf, int X,int Y,int W,int H, int D, int L). */ + virtual void draw_image_mono(const uchar* buf, int X,int Y,int W,int H, int D=1, int L=0); + /** \brief see fl_draw_image(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D). */ + virtual void draw_image(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D=3); + /** \brief see fl_draw_image_mono(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D). */ + virtual void draw_image_mono(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D=1); + // Image classes + /** \brief Draws an Fl_RGB_Image object to the device. + * + Specifies a bounding box for the image, with the origin (upper left-hand corner) of + the image offset by the cx and cy arguments. + */ + virtual void draw(Fl_RGB_Image * rgb,int XP, int YP, int WP, int HP, int cx, int cy) {}; + /** \brief Draws an Fl_Pixmap object to the device. + * + Specifies a bounding box for the image, with the origin (upper left-hand corner) of + the image offset by the cx and cy arguments. + */ + virtual void draw(Fl_Pixmap * pxm,int XP, int YP, int WP, int HP, int cx, int cy) {}; + /** \brief Draws an Fl_Bitmap object to the device. + * + Specifies a bounding box for the image, with the origin (upper left-hand corner) of + the image offset by the cx and cy arguments. + */ + virtual void draw(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy) {}; + +public: + static const char *device_type; + /** \brief The destructor */ + virtual ~Fl_Graphics_Driver() {}; +}; + +#if defined(__APPLE__) || defined(FL_DOXYGEN) +/** + \brief The Mac OS X-specific graphics class. + * + This class is implemented only on the Mac OS X platform. + */ +class Fl_Quartz_Graphics_Driver : public Fl_Graphics_Driver { +public: + /** \brief The constructor. */ + Fl_Quartz_Graphics_Driver() { type_ = device_type; }; + static const char *device_type; + void draw(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy); + void draw(Fl_Bitmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy); + void draw(Fl_RGB_Image *img, int XP, int YP, int WP, int HP, int cx, int cy); +}; +#endif +#if defined(WIN32) || defined(FL_DOXYGEN) +/** + \brief The MSWindows-specific graphics class. + * + This class is implemented only on the MSWindows platform. + */ +class Fl_GDI_Graphics_Driver : public Fl_Graphics_Driver { +public: + /** \brief The constructor. */ + Fl_GDI_Graphics_Driver() { type_ = device_type; }; + static const char *device_type; + void draw(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy); + void draw(Fl_Bitmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy); + void draw(Fl_RGB_Image *img, int XP, int YP, int WP, int HP, int cx, int cy); +}; +#endif +#if !(defined(__APPLE__) || defined(WIN32)) +/** + \brief The Xlib-specific graphics class. + * + This class is implemented only on the Xlib platform. + */ +class Fl_Xlib_Graphics_Driver : public Fl_Graphics_Driver { +public: + /** \brief The constructor. */ + Fl_Xlib_Graphics_Driver() { type_ = device_type; }; + static const char *device_type; + void draw(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy); + void draw(Fl_Bitmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy); + void draw(Fl_RGB_Image *img, int XP, int YP, int WP, int HP, int cx, int cy); +}; +#endif + +/** + \brief A surface that's susceptible to receive graphical output. + */ +class Fl_Surface_Device : public Fl_Device { + /** \brief The graphics driver in use by this surface. */ + Fl_Graphics_Driver *_driver; +protected: + /** \brief Constructor that sets the graphics driver to use for the created surface. */ + Fl_Surface_Device(Fl_Graphics_Driver *graphics_driver) {_driver = graphics_driver; }; +public: + static const char *device_type; + virtual void set_current(void); + /** \brief Sets the graphics driver of this drawing surface. */ + inline void driver(Fl_Graphics_Driver *graphics_driver) {_driver = graphics_driver;}; + /** \brief Returns the graphics driver of this drawing surface. */ + inline Fl_Graphics_Driver *driver() {return _driver; }; + /** \brief the surface that currently receives graphics output */ + static Fl_Surface_Device *surface() {return fl_surface; }; + /** \brief The destructor. */ + virtual ~Fl_Surface_Device() {} +}; + +/** + \brief A display to which the computer can draw. + */ +class Fl_Display_Device : public Fl_Surface_Device { +public: + static const char *device_type; + /** \brief A constructor that sets the graphics driver used by the display */ + Fl_Display_Device(Fl_Graphics_Driver *graphics_driver) : Fl_Surface_Device( graphics_driver) { type_ = device_type; }; + /** + @brief Returns the platform's display device. + */ + static Fl_Display_Device *display_device() { return fl_display_device; }; +}; + +#endif // Fl_Device_H + +// +// End of "$Id: Fl_Device.H 7719 2010-10-12 09:25:37Z manolo $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Dial.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Dial.H new file mode 100644 index 0000000..75e6064 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Dial.H @@ -0,0 +1,97 @@ +// +// "$Id: Fl_Dial.H 7903 2010-11-28 21:06:39Z matt $" +// +// Dial header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Dial widget . */ + +#ifndef Fl_Dial_H +#define Fl_Dial_H + +#ifndef Fl_Valuator_H +#include "Fl_Valuator.H" +#endif + +// values for type(): +#define FL_NORMAL_DIAL 0 /**< type() for dial variant with dot */ +#define FL_LINE_DIAL 1 /**< type() for dial variant with line */ +#define FL_FILL_DIAL 2 /**< type() for dial variant with filled arc */ + +/** + The Fl_Dial widget provides a circular dial to control a + single floating point value. +

\image html dial.gif + \image latex dial.eps "Fl_Dial" width=4cm + Use type() to set the type of the dial to: +

    +
  • FL_NORMAL_DIAL - Draws a normal dial with a knob.
  • +
  • FL_LINE_DIAL - Draws a dial with a line.
  • +
  • FL_FILL_DIAL - Draws a dial with a filled arc.
  • +
+ +*/ +class FL_EXPORT Fl_Dial : public Fl_Valuator { + + short a1,a2; + +protected: + + // these allow subclasses to put the dial in a smaller area: + void draw(int X, int Y, int W, int H); + int handle(int event, int X, int Y, int W, int H); + void draw(); + +public: + + int handle(int); + /** + Creates a new Fl_Dial widget using the given position, size, + and label string. The default type is FL_NORMAL_DIAL. + */ + Fl_Dial(int x,int y,int w,int h, const char *l = 0); + /** + Sets Or gets the angles used for the minimum and maximum values. The default + values are 45 and 315 (0 degrees is straight down and the angles + progress clockwise). Normally angle1 is less than angle2, but if you + reverse them the dial moves counter-clockwise. + */ + short angle1() const {return a1;} + /** See short angle1() const */ + void angle1(short a) {a1 = a;} + /** See short angle1() const */ + short angle2() const {return a2;} + /** See short angle1() const */ + void angle2(short a) {a2 = a;} + /** See short angle1() const */ + void angles(short a, short b) {a1 = a; a2 = b;} + +}; + +#endif + +// +// End of "$Id: Fl_Dial.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Double_Window.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Double_Window.H new file mode 100644 index 0000000..20ab25b --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Double_Window.H @@ -0,0 +1,81 @@ +// +// "$Id: Fl_Double_Window.H 7903 2010-11-28 21:06:39Z matt $" +// +// Double-buffered window header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Double_Window widget . */ + +#ifndef Fl_Double_Window_H +#define Fl_Double_Window_H + +#include "Fl_Window.H" + +/** + The Fl_Double_Window provides a double-buffered window. + If possible this will use the X double buffering extension (Xdbe). If + not, it will draw the window data into an off-screen pixmap, and then + copy it to the on-screen window. +

It is highly recommended that you put the following code before the + first show() of any window in your program:

+ \code + Fl::visual(FL_DOUBLE|FL_INDEX) + \endcode + This makes sure you can use Xdbe on servers where double buffering + does not exist for every visual. +*/ +class FL_EXPORT Fl_Double_Window : public Fl_Window { +protected: + void flush(int eraseoverlay); + /** + Force double buffering, even if the OS already buffers windows + (overlays need that on MacOS and Windows2000) + */ + char force_doublebuffering_; +public: + void show(); + void show(int a, char **b) {Fl_Window::show(a,b);} + void flush(); + void resize(int,int,int,int); + void hide(); + ~Fl_Double_Window(); + /** + Creates a new Fl_Double_Window widget using the given + position, size, and label (title) string. + */ + Fl_Double_Window(int W, int H, const char *l = 0) + : Fl_Window(W,H,l), force_doublebuffering_(0) { type(FL_DOUBLE_WINDOW); } + /** + See Fl_Double_Window::Fl_Double_Window(int w, int h, const char *label = 0) + */ + Fl_Double_Window(int X, int Y, int W, int H, const char *l = 0) + : Fl_Window(X,Y,W,H,l), force_doublebuffering_(0) { type(FL_DOUBLE_WINDOW); } +}; + +#endif + +// +// End of "$Id: Fl_Double_Window.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Export.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Export.H new file mode 100644 index 0000000..875a278 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Export.H @@ -0,0 +1,49 @@ +/* + * "$Id: Fl_Export.H 7903 2010-11-28 21:06:39Z matt $" + * + * WIN32 DLL export . + * + * Copyright 1998-2010 by Bill Spitzak and others. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems on the following page: + * + * http://www.fltk.org/str.php + */ + +#ifndef Fl_Export_H +# define Fl_Export_H + +/* + * The following is only used when building DLLs under WIN32... + */ + +# if defined(FL_DLL) +# ifdef FL_LIBRARY +# define FL_EXPORT __declspec(dllexport) +# else +# define FL_EXPORT __declspec(dllimport) +# endif /* FL_LIBRARY */ +# else +# define FL_EXPORT +# endif /* FL_DLL */ + +#endif /* !Fl_Export_H */ + +/* + * End of "$Id: Fl_Export.H 7903 2010-11-28 21:06:39Z matt $". + */ diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_File_Browser.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_File_Browser.H new file mode 100644 index 0000000..c327817 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_File_Browser.H @@ -0,0 +1,120 @@ +// +// "$Id: Fl_File_Browser.H 7903 2010-11-28 21:06:39Z matt $" +// +// FileBrowser definitions. +// +// Copyright 1999-2010 by Michael Sweet. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_File_Browser widget . */ + +// +// Include necessary header files... +// + +#ifndef _Fl_File_Browser_H_ +# define _Fl_File_Browser_H_ + +# include "Fl_Browser.H" +# include "Fl_File_Icon.H" +# include "filename.H" + + +// +// Fl_File_Browser class... +// + +/** The Fl_File_Browser widget displays a list of filenames, optionally with file-specific icons. */ +class FL_EXPORT Fl_File_Browser : public Fl_Browser +{ + int filetype_; + const char *directory_; + uchar iconsize_; + const char *pattern_; + + int full_height() const; + int item_height(void *) const; + int item_width(void *) const; + void item_draw(void *, int, int, int, int) const; + int incr_height() const { return (item_height(0)); } + +public: + enum { FILES, DIRECTORIES }; + + /** + The constructor creates the Fl_File_Browser widget at the specified position and size. + The destructor destroys the widget and frees all memory that has been allocated. + */ + Fl_File_Browser(int, int, int, int, const char * = 0); + + /** Sets or gets the size of the icons. The default size is 20 pixels. */ + uchar iconsize() const { return (iconsize_); }; + /** Sets or gets the size of the icons. The default size is 20 pixels. */ + void iconsize(uchar s) { iconsize_ = s; redraw(); }; + + /** + Sets or gets the filename filter. The pattern matching uses + the fl_filename_match() + function in FLTK. + */ + void filter(const char *pattern); + /** + Sets or gets the filename filter. The pattern matching uses + the fl_filename_match() + function in FLTK. + */ + const char *filter() const { return (pattern_); }; + + /** + Loads the specified directory into the browser. If icons have been + loaded then the correct icon is associated with each file in the list. + +

The sort argument specifies a sort function to be used with + fl_filename_list(). + */ + int load(const char *directory, Fl_File_Sort_F *sort = fl_numericsort); + + Fl_Fontsize textsize() const { return Fl_Browser::textsize(); }; + void textsize(Fl_Fontsize s) { Fl_Browser::textsize(s); iconsize_ = (uchar)(3 * s / 2); }; + + /** + Sets or gets the file browser type, FILES or + DIRECTORIES. When set to FILES, both + files and directories are shown. Otherwise only directories are + shown. + */ + int filetype() const { return (filetype_); }; + /** + Sets or gets the file browser type, FILES or + DIRECTORIES. When set to FILES, both + files and directories are shown. Otherwise only directories are + shown. + */ + void filetype(int t) { filetype_ = t; }; +}; + +#endif // !_Fl_File_Browser_H_ + +// +// End of "$Id: Fl_File_Browser.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_File_Chooser.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_File_Chooser.H new file mode 100644 index 0000000..162c0a4 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_File_Chooser.H @@ -0,0 +1,235 @@ +// +// "$Id: Fl_File_Chooser.H 7903 2010-11-28 21:06:39Z matt $" +// +// Fl_File_Chooser dialog for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// generated by Fast Light User Interface Designer (fluid) version 1.0300 + +#ifndef Fl_File_Chooser_H +#define Fl_File_Chooser_H +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class FL_EXPORT Fl_File_Chooser { +public: + enum { SINGLE = 0, MULTI = 1, CREATE = 2, DIRECTORY = 4 }; +private: + static Fl_Preferences prefs_; + void (*callback_)(Fl_File_Chooser*, void *); + void *data_; + char directory_[1024]; + char pattern_[1024]; + char preview_text_[2048]; + int type_; + void favoritesButtonCB(); + void favoritesCB(Fl_Widget *w); + void fileListCB(); + void fileNameCB(); + void newdir(); + static void previewCB(Fl_File_Chooser *fc); + void showChoiceCB(); + void update_favorites(); + void update_preview(); +public: + Fl_File_Chooser(const char *d, const char *p, int t, const char *title); +private: + Fl_Double_Window *window; + void cb_window_i(Fl_Double_Window*, void*); + static void cb_window(Fl_Double_Window*, void*); + Fl_Choice *showChoice; + void cb_showChoice_i(Fl_Choice*, void*); + static void cb_showChoice(Fl_Choice*, void*); + Fl_Menu_Button *favoritesButton; + void cb_favoritesButton_i(Fl_Menu_Button*, void*); + static void cb_favoritesButton(Fl_Menu_Button*, void*); +public: + Fl_Button *newButton; +private: + void cb_newButton_i(Fl_Button*, void*); + static void cb_newButton(Fl_Button*, void*); + void cb__i(Fl_Tile*, void*); + static void cb_(Fl_Tile*, void*); + Fl_File_Browser *fileList; + void cb_fileList_i(Fl_File_Browser*, void*); + static void cb_fileList(Fl_File_Browser*, void*); + Fl_Box *previewBox; +public: + Fl_Check_Button *previewButton; +private: + void cb_previewButton_i(Fl_Check_Button*, void*); + static void cb_previewButton(Fl_Check_Button*, void*); + Fl_File_Input *fileName; + void cb_fileName_i(Fl_File_Input*, void*); + static void cb_fileName(Fl_File_Input*, void*); + Fl_Return_Button *okButton; + void cb_okButton_i(Fl_Return_Button*, void*); + static void cb_okButton(Fl_Return_Button*, void*); + Fl_Button *cancelButton; + void cb_cancelButton_i(Fl_Button*, void*); + static void cb_cancelButton(Fl_Button*, void*); + Fl_Double_Window *favWindow; + Fl_File_Browser *favList; + void cb_favList_i(Fl_File_Browser*, void*); + static void cb_favList(Fl_File_Browser*, void*); + Fl_Button *favUpButton; + void cb_favUpButton_i(Fl_Button*, void*); + static void cb_favUpButton(Fl_Button*, void*); + Fl_Button *favDeleteButton; + void cb_favDeleteButton_i(Fl_Button*, void*); + static void cb_favDeleteButton(Fl_Button*, void*); + Fl_Button *favDownButton; + void cb_favDownButton_i(Fl_Button*, void*); + static void cb_favDownButton(Fl_Button*, void*); + Fl_Button *favCancelButton; + void cb_favCancelButton_i(Fl_Button*, void*); + static void cb_favCancelButton(Fl_Button*, void*); + Fl_Return_Button *favOkButton; + void cb_favOkButton_i(Fl_Return_Button*, void*); + static void cb_favOkButton(Fl_Return_Button*, void*); +public: + ~Fl_File_Chooser(); + void callback(void (*cb)(Fl_File_Chooser *, void *), void *d = 0); + void color(Fl_Color c); + Fl_Color color(); + int count(); + void directory(const char *d); + char * directory(); + void filter(const char *p); + const char * filter(); + int filter_value(); + void filter_value(int f); + void hide(); + void iconsize(uchar s); + uchar iconsize(); + void label(const char *l); + const char * label(); + void ok_label(const char *l); + const char * ok_label(); + void preview(int e); + int preview() const { return previewButton->value(); }; + void rescan(); + void rescan_keep_filename(); + void show(); + int shown(); + void textcolor(Fl_Color c); + Fl_Color textcolor(); + void textfont(Fl_Font f); + Fl_Font textfont(); + void textsize(Fl_Fontsize s); + Fl_Fontsize textsize(); + void type(int t); + int type(); + void * user_data() const; + void user_data(void *d); + const char *value(int f = 1); + void value(const char *filename); + int visible(); + /** + [standard text may be customized at run-time] + */ + static const char *add_favorites_label; + /** + [standard text may be customized at run-time] + */ + static const char *all_files_label; + /** + [standard text may be customized at run-time] + */ + static const char *custom_filter_label; + /** + [standard text may be customized at run-time] + */ + static const char *existing_file_label; + /** + [standard text may be customized at run-time] + */ + static const char *favorites_label; + /** + [standard text may be customized at run-time] + */ + static const char *filename_label; + /** + [standard text may be customized at run-time] + */ + static const char *filesystems_label; + /** + [standard text may be customized at run-time] + */ + static const char *manage_favorites_label; + /** + [standard text may be customized at run-time] + */ + static const char *new_directory_label; + /** + [standard text may be customized at run-time] + */ + static const char *new_directory_tooltip; + /** + [standard text may be customized at run-time] + */ + static const char *preview_label; + /** + [standard text may be customized at run-time] + */ + static const char *save_label; + /** + [standard text may be customized at run-time] + */ + static const char *show_label; + /** + the sort function that is used when loading + the contents of a directory. + */ + static Fl_File_Sort_F *sort; +private: + Fl_Widget* ext_group; +public: + Fl_Widget* add_extra(Fl_Widget* gr); + Fl_File_Browser *browser(void) {return fileList; }; +}; +FL_EXPORT char *fl_dir_chooser(const char *message,const char *fname,int relative=0); +FL_EXPORT char *fl_file_chooser(const char *message,const char *pat,const char *fname,int relative=0); +FL_EXPORT void fl_file_chooser_callback(void (*cb)(const char*)); +FL_EXPORT void fl_file_chooser_ok_label(const char*l); +#endif + +// +// End of "$Id: Fl_File_Chooser.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_File_Icon.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_File_Icon.H new file mode 100644 index 0000000..bf5dc58 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_File_Icon.H @@ -0,0 +1,168 @@ +// +// "$Id: Fl_File_Icon.H 7903 2010-11-28 21:06:39Z matt $" +// +// Fl_File_Icon definitions. +// +// Copyright 1999-2010 by Michael Sweet. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_File_Icon widget . */ + +// +// Include necessary header files... +// + +#ifndef _Fl_Fl_File_Icon_H_ +# define _Fl_Fl_File_Icon_H_ + +# include "Fl.H" + + +// +// Special color value for the icon color. +// + +# define FL_ICON_COLOR (Fl_Color)0xffffffff /**< icon color [background?]*/ + + +// +// Fl_File_Icon class... +// + +/** + The Fl_File_Icon class manages icon images that can be used + as labels in other widgets and as icons in the FileBrowser widget. +*/ +class FL_EXPORT Fl_File_Icon //// Icon data +{ + static Fl_File_Icon *first_; // Pointer to first icon/filetype + Fl_File_Icon *next_; // Pointer to next icon/filetype + const char *pattern_; // Pattern string + int type_; // Match only if directory or file? + int num_data_; // Number of data elements + int alloc_data_; // Number of allocated elements + short *data_; // Icon data + + public: + + enum // File types + { + ANY, // Any kind of file + PLAIN, // Only plain files + FIFO, // Only named pipes + DEVICE, // Only character and block devices + LINK, // Only symbolic links + DIRECTORY // Only directories + }; + + enum // Data opcodes + { + END, // End of primitive/icon + COLOR, // Followed by color value (2 shorts) + LINE, // Start of line + CLOSEDLINE, // Start of closed line + POLYGON, // Start of polygon + OUTLINEPOLYGON, // Followed by outline color (2 shorts) + VERTEX // Followed by scaled X,Y + }; + + Fl_File_Icon(const char *p, int t, int nd = 0, short *d = 0); + ~Fl_File_Icon(); + + short *add(short d); + + /** + Adds a color value to the icon array, returning a pointer to it. + \param[in] c color value + */ + short *add_color(Fl_Color c) + { short *d = add((short)COLOR); add((short)(c >> 16)); add((short)c); return (d); } + + /** + Adds a vertex value to the icon array, returning a pointer to it. + The integer version accepts coordinates from 0 to 10000. + The origin (0.0) is in the lower-lefthand corner of the icon. + \param[in] x, y vertex coordinates + */ + short *add_vertex(int x, int y) + { short *d = add((short)VERTEX); add((short)x); add((short)y); return (d); } + + /** + Adds a vertex value to the icon array, returning a pointer to it. + The floating point version goes from 0.0 to 1.0. + The origin (0.0) is in the lower-lefthand corner of the icon. + \param[in] x, y vertex coordinates + */ + short *add_vertex(float x, float y) + { short *d = add((short)VERTEX); add((short)(x * 10000.0)); + add((short)(y * 10000.0)); return (d); } + + /** Clears all icon data from the icon.*/ + void clear() { num_data_ = 0; } + + void draw(int x, int y, int w, int h, Fl_Color ic, int active = 1); + + void label(Fl_Widget *w); + + static void labeltype(const Fl_Label *o, int x, int y, int w, int h, Fl_Align a); + void load(const char *f); + int load_fti(const char *fti); + int load_image(const char *i); + + /** Returns next file icon object. See Fl_File_Icon::first() */ + Fl_File_Icon *next() { return (next_); } + + /** Returns the filename matching pattern for the icon.*/ + const char *pattern() { return (pattern_); } + + /** Returns the number of words of data used by the icon.*/ + int size() { return (num_data_); } + + /** + Returns the filetype associated with the icon, which can be one of the + following: + + \li Fl_File_Icon::ANY, any kind of file. + \li Fl_File_Icon::PLAIN, plain files. + \li Fl_File_Icon::FIFO, named pipes. + \li Fl_File_Icon::DEVICE, character and block devices. + \li Fl_File_Icon::LINK, symbolic links. + \li Fl_File_Icon::DIRECTORY, directories. + */ + int type() { return (type_); } + + /** Returns the data array for the icon.*/ + short *value() { return (data_); } + + static Fl_File_Icon *find(const char *filename, int filetype = ANY); + + /** Returns a pointer to the first icon in the list.*/ + static Fl_File_Icon *first() { return (first_); } + static void load_system_icons(void); +}; + +#endif // !_Fl_Fl_File_Icon_H_ + +// +// End of "$Id: Fl_File_Icon.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_File_Input.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_File_Input.H new file mode 100644 index 0000000..6fedc65 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_File_Input.H @@ -0,0 +1,104 @@ +// +// "$Id: Fl_File_Input.H 7903 2010-11-28 21:06:39Z matt $" +// +// File_Input header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// Original version Copyright 1998 by Curtis Edwards. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_File_Input widget . */ + +#ifndef Fl_File_Input_H +# define Fl_File_Input_H + +# include + +/** + \class Fl_File_Input + \brief This widget displays a pathname in a text input field. + + A navigation bar located above the input field allows the user to + navigate upward in the directory tree. + You may want to handle FL_WHEN_CHANGED events for tracking text changes + and also FL_WHEN_RELEASE for button release when changing to parent dir. + FL_WHEN_RELEASE callback won't be called if the directory clicked + is the same that the current one. +

\image html Fl_File_Input.gif

+ \image latex Fl_File_Input.eps "Fl_File_Input" width=6cm + \note As all Fl_Input derived objects, Fl_File_Input may call its callback + when loosing focus (see FL_UNFOCUS) to update its state like its cursor shape. + One resulting side effect is that you should call clear_changed() early in your callback + to avoid reentrant calls if you plan to show another window or dialog box in the callback. +*/ +class FL_EXPORT Fl_File_Input : public Fl_Input +{ + Fl_Color errorcolor_; + char ok_entry_; + uchar down_box_; + short buttons_[200]; + short pressed_; + + void draw_buttons(); + int handle_button(int event); + void update_buttons(); + +public: + + Fl_File_Input(int X, int Y, int W, int H, const char *L=0); + + virtual int handle(int event); + +protected: + virtual void draw(); + +public: + /** Gets the box type used for the navigation bar. */ + Fl_Boxtype down_box() const { return (Fl_Boxtype)down_box_; } + /** Sets the box type to use for the navigation bar. */ + void down_box(Fl_Boxtype b) { down_box_ = b; } + + /** + Gets the current error color. + \todo Better docs for Fl_File_Input::errorcolor() - is it even used? + */ + Fl_Color errorcolor() const { return errorcolor_; } + /** Sets the current error color to \p c */ + void errorcolor(Fl_Color c) { errorcolor_ = c; } + + int value(const char *str); + int value(const char *str, int len); + + /** + Returns the current value, which is a pointer to an internal buffer + and is valid only until the next event is handled. + */ + const char *value() { return Fl_Input_::value(); } +}; + +#endif // !Fl_File_Input_H + + +// +// End of "$Id: Fl_File_Input.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Fill_Dial.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Fill_Dial.H new file mode 100644 index 0000000..41cc968 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Fill_Dial.H @@ -0,0 +1,48 @@ +// +// "$Id: Fl_Fill_Dial.H 7903 2010-11-28 21:06:39Z matt $" +// +// Filled dial header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Fill_Dial widget . */ + +#ifndef Fl_Fill_Dial_H +#define Fl_Fill_Dial_H + +#include "Fl_Dial.H" + +/** Draws a dial with a filled arc */ +class Fl_Fill_Dial : public Fl_Dial { +public: + /** Creates a filled dial, also setting its type to FL_FILL_DIAL. */ + Fl_Fill_Dial(int x,int y,int w,int h, const char *l = 0) + : Fl_Dial(x,y,w,h,l) {type(FL_FILL_DIAL);} +}; + +#endif + +// +// End of "$Id: Fl_Fill_Dial.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Fill_Slider.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Fill_Slider.H new file mode 100644 index 0000000..711729f --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Fill_Slider.H @@ -0,0 +1,47 @@ +// +// "$Id: Fl_Fill_Slider.H 7903 2010-11-28 21:06:39Z matt $" +// +// Filled slider header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Fill_Slider widget . */ + +#ifndef Fl_Fill_Slider_H +#define Fl_Fill_Slider_H + +#include "Fl_Slider.H" +/** Widget that draws a filled horizontal slider, useful as a progress or value meter*/ +class Fl_Fill_Slider : public Fl_Slider { +public: + /** Creates the slider from its position,size and optional title. */ + Fl_Fill_Slider(int x,int y,int w,int h,const char *l=0) + : Fl_Slider(x,y,w,h,l) {type(FL_VERT_FILL_SLIDER);} +}; + +#endif + +// +// End of "$Id: Fl_Fill_Slider.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Float_Input.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Float_Input.H new file mode 100644 index 0000000..bc021e7 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Float_Input.H @@ -0,0 +1,57 @@ +// +// "$Id: Fl_Float_Input.H 7903 2010-11-28 21:06:39Z matt $" +// +// Floating point input header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Float_Input widget . */ + + +#ifndef Fl_Float_Input_H +#define Fl_Float_Input_H + +#include "Fl_Input.H" + +/** + The Fl_Float_Input class is a subclass of Fl_Input + that only allows the user to type floating point numbers (sign, + digits, decimal point, more digits, 'E' or 'e', sign, digits). +*/ +class Fl_Float_Input : public Fl_Input { +public: + /** + Creates a new Fl_Float_Input widget using the given position, + size, and label string. The default boxtype is FL_DOWN_BOX. +

Inherited destructor destroys the widget and any value associated with it + */ + Fl_Float_Input(int X,int Y,int W,int H,const char *l = 0) + : Fl_Input(X,Y,W,H,l) {type(FL_FLOAT_INPUT);} +}; + +#endif + +// +// End of "$Id: Fl_Float_Input.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_FormsBitmap.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_FormsBitmap.H new file mode 100644 index 0000000..5558262 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_FormsBitmap.H @@ -0,0 +1,56 @@ +// +// "$Id: Fl_FormsBitmap.H 7903 2010-11-28 21:06:39Z matt $" +// +// Forms bitmap header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_FormsBitmap widget . */ + +#ifndef Fl_FormsBitmap_H +#define Fl_FormsBitmap_H + +#include "Fl_Bitmap.H" + +/** + Forms compatibility Bitmap Image Widget +*/ +class FL_EXPORT Fl_FormsBitmap : public Fl_Widget { + Fl_Bitmap *b; +protected: + void draw(); +public: + Fl_FormsBitmap(Fl_Boxtype, int, int, int, int, const char * = 0); + void set(int W, int H, const uchar *bits); + /** Sets a new bitmap. */ + void bitmap(Fl_Bitmap *B) {b = B;} + /** Gets a the current associated Fl_Bitmap objects. */ + Fl_Bitmap *bitmap() const {return b;} +}; + +#endif + +// +// End of "$Id: Fl_FormsBitmap.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_FormsPixmap.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_FormsPixmap.H new file mode 100644 index 0000000..1eb01de --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_FormsPixmap.H @@ -0,0 +1,63 @@ +// +// "$Id: Fl_FormsPixmap.H 7903 2010-11-28 21:06:39Z matt $" +// +// Forms pixmap header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_FormsPixmap widget . */ + +#ifndef Fl_FormsPixmap_H +#define Fl_FormsPixmap_H + +#include "Fl_Pixmap.H" + +/** + \class Fl_FormsPixmap + \brief Forms pixmap drawing routines +*/ +class FL_EXPORT Fl_FormsPixmap : public Fl_Widget { + Fl_Pixmap *b; +protected: + void draw(); +public: + Fl_FormsPixmap(Fl_Boxtype t, int X, int Y, int W, int H, const char *L= 0); + + void set(/*const*/char * const * bits); + + /** + Set the internal pixmap pointer to an existing pixmap. + \param[in] B existing pixmap + */ + void Pixmap(Fl_Pixmap *B) {b = B;} + + /** Get the internal pixmap pointer. */ + Fl_Pixmap *Pixmap() const {return b;} +}; + +#endif + +// +// End of "$Id: Fl_FormsPixmap.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Free.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Free.H new file mode 100644 index 0000000..367443c --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Free.H @@ -0,0 +1,89 @@ +// +// "$Id: Fl_Free.H 7903 2010-11-28 21:06:39Z matt $" +// +// Forms free header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Free widget . */ + +#ifndef Fl_Free_H +#define Fl_Free_H + +#ifndef Fl_Widget_H +#include "Fl_Widget.H" +#endif + +#define FL_NORMAL_FREE 1 /**< normal event handling */ +#define FL_SLEEPING_FREE 2 /**< deactivate event handling */ +#define FL_INPUT_FREE 3 /**< accepts FL_FOCUS events */ +#define FL_CONTINUOUS_FREE 4 /**< repeated timeout handling */ +#define FL_ALL_FREE 5 /**< FL_INPUT_FREE and FL_CONTINOUS_FREE */ + +/** appropriate signature for handle function */ +typedef int (*FL_HANDLEPTR)(Fl_Widget *, int , float, float, char); + +/** + Emulation of the Forms "free" widget. + + This emulation allows the free demo to run, and appears to be useful for + porting programs written in Forms which use the free widget or make + subclasses of the Forms widgets. + + There are five types of free, which determine when the handle function + is called: + + \li \c FL_NORMAL_FREE normal event handling. + \li \c FL_SLEEPING_FREE deactivates event handling (widget is inactive). + \li \c FL_INPUT_FREE accepts FL_FOCUS events. + \li \c FL_CONTINUOUS_FREE sets a timeout callback 100 times a second and + provides an FL_STEP event. This has obvious + detrimental effects on machine performance. + \li \c FL_ALL_FREE same as FL_INPUT_FREE and FL_CONTINUOUS_FREE. + +*/ +class FL_EXPORT Fl_Free : public Fl_Widget { + FL_HANDLEPTR hfunc; + static void step(void *); +protected: + void draw(); +public: + int handle(int e); + Fl_Free(uchar t,int X,int Y,int W,int H,const char *L,FL_HANDLEPTR hdl); + ~Fl_Free(); +}; + +// old event names for compatibility: +#define FL_MOUSE FL_DRAG /**< for backward compatibility */ +#define FL_DRAW 100 /**< for backward compatibility [UNUSED]*/ +#define FL_STEP 101 /**< for backward compatibility */ +#define FL_FREEMEM 102 /**< for backward compatibility [UNUSED]*/ +#define FL_FREEZE 103 /**< for backward compatibility [UNUSED]*/ +#define FL_THAW 104 /**< for backward compatibility [UNUSED]*/ + +#endif + +// +// End of "$Id: Fl_Free.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_GIF_Image.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_GIF_Image.H new file mode 100644 index 0000000..69f055b --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_GIF_Image.H @@ -0,0 +1,51 @@ +// +// "$Id: Fl_GIF_Image.H 7903 2010-11-28 21:06:39Z matt $" +// +// GIF image header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_GIF_Image widget . */ + +#ifndef Fl_GIF_Image_H +#define Fl_GIF_Image_H +# include "Fl_Pixmap.H" + +/** + The Fl_GIF_Image class supports loading, caching, + and drawing of Compuserve GIFSM images. The class + loads the first image and supports transparency. +*/ +class FL_EXPORT Fl_GIF_Image : public Fl_Pixmap { + + public: + + Fl_GIF_Image(const char* filename); +}; + +#endif + +// +// End of "$Id: Fl_GIF_Image.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Gl_Window.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Gl_Window.H new file mode 100644 index 0000000..d03cd77 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Gl_Window.H @@ -0,0 +1,244 @@ +// +// "$Id: Fl_Gl_Window.H 7903 2010-11-28 21:06:39Z matt $" +// +// OpenGL header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Gl_Window widget . */ + +#ifndef Fl_Gl_Window_H +#define Fl_Gl_Window_H + +#include "Fl_Window.H" + +#ifndef GLContext +/** + Opaque pointer type to hide system specific implementation. +*/ +typedef void* GLContext; // actually a GLXContext or HGLDC +#endif + +class Fl_Gl_Choice; // structure to hold result of glXChooseVisual + +/** + The Fl_Gl_Window widget sets things up so OpenGL works. + + It also keeps an OpenGL "context" for that window, so that changes to the + lighting and projection may be reused between redraws. Fl_Gl_Window + also flushes the OpenGL streams and swaps buffers after draw() returns. + + OpenGL hardware typically provides some overlay bit planes, which + are very useful for drawing UI controls atop your 3D graphics. If the + overlay hardware is not provided, FLTK tries to simulate the overlay. + This works pretty well if your graphics are double buffered, but not + very well for single-buffered. + + Please note that the FLTK drawing and clipping functions + will not work inside an Fl_Gl_Window. All drawing + should be done using OpenGL calls exclusively. + Even though Fl_Gl_Window is derived from Fl_Group, + it is not useful to add other FLTK Widgets as children, + unless those widgets are modified to draw using OpenGL calls. +*/ +class FL_EXPORT Fl_Gl_Window : public Fl_Window { + + int mode_; + const int *alist; + Fl_Gl_Choice *g; + GLContext context_; + char valid_f_; + char damage1_; // damage() of back buffer + virtual void draw_overlay(); + void init(); + + void *overlay; + void make_overlay(); + friend class _Fl_Gl_Overlay; + + static int can_do(int, const int *); + int mode(int, const int *); + +public: + + void show(); + void show(int a, char **b) {Fl_Window::show(a,b);} + void flush(); + void hide(); + void resize(int,int,int,int); + int handle(int); + + /** + Is turned off when FLTK creates a new context for this window or + when the window resizes, and is turned on \e after draw() is called. + You can use this inside your draw() method to avoid unnecessarily + initializing the OpenGL context. Just do this: + \code + void mywindow::draw() { + if (!valid()) { + glViewport(0,0,w(),h()); + glFrustum(...); + ...other initialization... + } + if (!context_valid()) { + ...load textures, etc. ... + } + ... draw your geometry here ... + } + \endcode + + You can turn valid() on by calling valid(1). You + should only do this after fixing the transformation inside a draw() + or after make_current(). This is done automatically after + draw() returns. + */ + char valid() const {return valid_f_ & 1;} + /** + See char Fl_Gl_Window::valid() const + */ + void valid(char v) {if (v) valid_f_ |= 1; else valid_f_ &= 0xfe;} + void invalidate(); + + /** + Will only be set if the + OpenGL context is created or recreated. It differs from + Fl_Gl_Window::valid() which is also set whenever the context + changes size. + */ + char context_valid() const {return valid_f_ & 2;} + /** + See char Fl_Gl_Window::context_valid() const + */ + void context_valid(char v) {if (v) valid_f_ |= 2; else valid_f_ &= 0xfd;} + + /** Returns non-zero if the hardware supports the given or current OpenGL mode. */ + static int can_do(int m) {return can_do(m,0);} + /** Returns non-zero if the hardware supports the given or current OpenGL mode. */ + static int can_do(const int *m) {return can_do(0, m);} + /** Returns non-zero if the hardware supports the given or current OpenGL mode. */ + int can_do() {return can_do(mode_,alist);} + /** + Set or change the OpenGL capabilites of the window. The value can be + any of the following OR'd together: + + - \c FL_RGB - RGB color (not indexed) + - \c FL_RGB8 - RGB color with at least 8 bits of each color + - \c FL_INDEX - Indexed mode + - \c FL_SINGLE - not double buffered + - \c FL_DOUBLE - double buffered + - \c FL_ACCUM - accumulation buffer + - \c FL_ALPHA - alpha channel in color + - \c FL_DEPTH - depth buffer + - \c FL_STENCIL - stencil buffer + - \c FL_MULTISAMPLE - multisample antialiasing + + FL_RGB and FL_SINGLE have a value of zero, so they + are "on" unless you give FL_INDEX or FL_DOUBLE. + + If the desired combination cannot be done, FLTK will try turning off + FL_MULTISAMPLE. If this also fails the show() will call + Fl::error() and not show the window. + + You can change the mode while the window is displayed. This is most + useful for turning double-buffering on and off. Under X this will + cause the old X window to be destroyed and a new one to be created. If + this is a top-level window this will unfortunately also cause the + window to blink, raise to the top, and be de-iconized, and the xid() + will change, possibly breaking other code. It is best to make the GL + window a child of another window if you wish to do this! + + mode() must not be called within draw() since it + changes the current context. + */ + Fl_Mode mode() const {return (Fl_Mode)mode_;} + /** See Fl_Mode mode() const */ + int mode(int a) {return mode(a,0);} + /** See Fl_Mode mode() const */ + int mode(const int *a) {return mode(0, a);} + /** void See void context(void* v, int destroy_flag) */ + void* context() const {return context_;} + void context(void*, int destroy_flag = 0); + void make_current(); + void swap_buffers(); + void ortho(); + + /** + Returns true if the hardware overlay is possible. If this is false, + FLTK will try to simulate the overlay, with significant loss of update + speed. Calling this will cause FLTK to open the display. + */ + int can_do_overlay(); + /** + This method causes draw_overlay() to be called at a later time. + Initially the overlay is clear. If you want the window to display + something in the overlay when it first appears, you must call this + immediately after you show() your window. + */ + void redraw_overlay(); + void hide_overlay(); + /** + The make_overlay_current() method selects the OpenGL context + for the widget's overlay. It is called automatically prior to the + draw_overlay() method being called and can also be used to + implement feedback and/or selection within the handle() + method. + */ + void make_overlay_current(); + + /** Returns an Fl_Gl_Window pointer if this widget is an Fl_Gl_Window. + \retval NULL if this widget is not derived from Fl_Gl_Window. + \note This method is provided to avoid dynamic_cast. + \todo More documentation ... + */ + virtual Fl_Gl_Window* as_gl_window() {return this;} + + ~Fl_Gl_Window(); + /** + Creates a new Fl_Gl_Window widget using the given size, and label string. + The default boxtype is FL_NO_BOX. The default mode is FL_RGB|FL_DOUBLE|FL_DEPTH. + */ + Fl_Gl_Window(int W, int H, const char *l=0) : Fl_Window(W,H,l) {init();} + /** + Creates a new Fl_Gl_Window widget using the given position, + size, and label string. The default boxtype is FL_NO_BOX. The + default mode is FL_RGB|FL_DOUBLE|FL_DEPTH. + */ + + Fl_Gl_Window(int X, int Y, int W, int H, const char *l=0) + : Fl_Window(X,Y,W,H,l) {init();} + +protected: + /** + Draws the Fl_Gl_Window. + + You \e \b must override the draw() method. + */ + virtual void draw(); +}; + +#endif + +// +// End of "$Id: Fl_Gl_Window.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Group.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Group.H new file mode 100644 index 0000000..0d8f687 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Group.H @@ -0,0 +1,235 @@ +// +// "$Id: Fl_Group.H 7903 2010-11-28 21:06:39Z matt $" +// +// Group header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Group, Fl_End classes . */ + +#ifndef Fl_Group_H +#define Fl_Group_H + +#ifndef Fl_Widget_H +#include "Fl_Widget.H" +#endif + +/** + The Fl_Group class is the FLTK container widget. It maintains + an array of child widgets. These children can themselves be any widget + including Fl_Group. The most important subclass of Fl_Group + is Fl_Window, however groups can also be used to control radio buttons + or to enforce resize behavior. +*/ +class FL_EXPORT Fl_Group : public Fl_Widget { + + Fl_Widget** array_; + Fl_Widget* savedfocus_; + Fl_Widget* resizable_; + int children_; + int *sizes_; // remembered initial sizes of children + + int navigation(int); + static Fl_Group *current_; + + // unimplemented copy ctor and assignment operator + Fl_Group(const Fl_Group&); + Fl_Group& operator=(const Fl_Group&); + +protected: + void draw(); + void draw_child(Fl_Widget& widget) const; + void draw_children(); + void draw_outside_label(const Fl_Widget& widget) const ; + void update_child(Fl_Widget& widget) const; + int *sizes(); + +public: + + int handle(int); + void begin(); + void end(); + static Fl_Group *current(); + static void current(Fl_Group *g); + + /** + Returns how many child widgets the group has. + */ + int children() const {return children_;} + /** + Returns array()[n]. No range checking is done! + */ + Fl_Widget* child(int n) const {return array()[n];} + int find(const Fl_Widget*) const; + /** + See int Fl_Group::find(const Fl_Widget *w) const + */ + int find(const Fl_Widget& o) const {return find(&o);} + Fl_Widget* const* array() const; + + void resize(int,int,int,int); + /** + Creates a new Fl_Group widget using the given position, size, + and label string. The default boxtype is FL_NO_BOX. + */ + Fl_Group(int,int,int,int, const char * = 0); + virtual ~Fl_Group(); + void add(Fl_Widget&); + /** + See void Fl_Group::add(Fl_Widget &w) + */ + void add(Fl_Widget* o) {add(*o);} + void insert(Fl_Widget&, int i); + /** + This does insert(w, find(before)). This will append the + widget if \p before is not in the group. + */ + void insert(Fl_Widget& o, Fl_Widget* before) {insert(o,find(before));} + void remove(int index); + void remove(Fl_Widget&); + /** + Removes the widget \p o from the group. + \sa void remove(Fl_Widget&) + */ + void remove(Fl_Widget* o) {remove(*o);} + void clear(); + + /** + See void Fl_Group::resizable(Fl_Widget *box) + */ + void resizable(Fl_Widget& o) {resizable_ = &o;} + /** + The resizable widget defines the resizing box for the group. When the + group is resized it calculates a new size and position for all of its + children. Widgets that are horizontally or vertically inside the + dimensions of the box are scaled to the new size. Widgets outside the + box are moved. + + In these examples the gray area is the resizable: + + \image html resizebox1.gif + + \image html resizebox2.gif + + \image latex resizebox1.eps "before resize" width=4cm + + \image latex resizebox2.eps "after resize" width=4cm + + The resizable may be set to the group itself, in which case all the + contents are resized. This is the default value for Fl_Group, + although NULL is the default for Fl_Window and Fl_Pack. + + If the resizable is NULL then all widgets remain a fixed size + and distance from the top-left corner. + + It is possible to achieve any type of resize behavior by using an + invisible Fl_Box as the resizable and/or by using a hierarchy + of child Fl_Group's. + */ + void resizable(Fl_Widget* o) {resizable_ = o;} + /** + See void Fl_Group::resizable(Fl_Widget *box) + */ + Fl_Widget* resizable() const {return resizable_;} + /** + Adds a widget to the group and makes it the resizable widget. + */ + void add_resizable(Fl_Widget& o) {resizable_ = &o; add(o);} + void init_sizes(); + + /** + Controls whether the group widget clips the drawing of + child widgets to its bounding box. + + Set \p c to 1 if you want to clip the child widgets to the + bounding box. + + The default is to not clip (0) the drawing of child widgets. + */ + void clip_children(int c) { if (c) set_flag(CLIP_CHILDREN); else clear_flag(CLIP_CHILDREN); } + /** + Returns the current clipping mode. + + \return true, if clipping is enabled, false otherwise. + + \see void Fl_Group::clip_children(int c) + */ + unsigned int clip_children() { return (flags() & CLIP_CHILDREN) != 0; } + + /** Returns an Fl_Group pointer if this widget is an Fl_Group. + + \retval NULL if this widget is not derived from Fl_Group. + \note This method is provided to avoid dynamic_cast. + \todo More documentation ... + */ + virtual Fl_Group* as_group() { return this; } + + // back compatibility functions: + + /** + \deprecated This is for backwards compatibility only. You should use + \e W->%take_focus() instead. + \sa Fl_Widget::take_focus(); + */ + void focus(Fl_Widget* W) {W->take_focus();} + + /** This is for forms compatibility only */ + Fl_Widget* & _ddfdesign_kludge() {return resizable_;} + + /** This is for forms compatibility only */ + void forms_end(); +}; + +// dummy class used to end child groups in constructors for complex +// subclasses of Fl_Group: +/** + This is a dummy class that allows you to end a Fl_Group in a constructor list of a + class: + \code + class MyClass { + Fl_Group group; + Fl_Button button_in_group; + Fl_End end; + Fl_Button button_outside_group; + MyClass(); + }; + MyClass::MyClass() : + group(10,10,100,100), + button_in_group(20,20,60,30), + end(), + button_outside_group(10,120,60,30) + {} + \endcode +*/ +class FL_EXPORT Fl_End { +public: + /** All it does is calling Fl_Group::current()->end() */ + Fl_End() {Fl_Group::current()->end();} +}; + +#endif + +// +// End of "$Id: Fl_Group.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Help_Dialog.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Help_Dialog.H new file mode 100644 index 0000000..c341590 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Help_Dialog.H @@ -0,0 +1,95 @@ +// +// "$Id: Fl_Help_Dialog.H 7903 2010-11-28 21:06:39Z matt $" +// +// Fl_Help_Dialog dialog for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Help_Dialog widget . */ + +// generated by Fast Light User Interface Designer (fluid) version 1.0108 + +#ifndef Fl_Help_Dialog_H +#define Fl_Help_Dialog_H +#include +#include +#include +#include +#include +#include +#include + +class FL_EXPORT Fl_Help_Dialog { + int index_; + int max_; + int line_[100]; + char file_[100][256]; + int find_pos_; +public: + Fl_Help_Dialog(); +private: + Fl_Double_Window *window_; + Fl_Button *back_; + void cb_back__i(Fl_Button*, void*); + static void cb_back_(Fl_Button*, void*); + Fl_Button *forward_; + void cb_forward__i(Fl_Button*, void*); + static void cb_forward_(Fl_Button*, void*); + Fl_Button *smaller_; + void cb_smaller__i(Fl_Button*, void*); + static void cb_smaller_(Fl_Button*, void*); + Fl_Button *larger_; + void cb_larger__i(Fl_Button*, void*); + static void cb_larger_(Fl_Button*, void*); + Fl_Input *find_; + void cb_find__i(Fl_Input*, void*); + static void cb_find_(Fl_Input*, void*); + Fl_Help_View *view_; + void cb_view__i(Fl_Help_View*, void*); + static void cb_view_(Fl_Help_View*, void*); +public: + ~Fl_Help_Dialog(); + int h(); + void hide(); + void load(const char *f); + void position(int xx, int yy); + void resize(int xx, int yy, int ww, int hh); + void show(); + void show(int argc, char **argv); + void textsize(Fl_Fontsize s); + Fl_Fontsize textsize(); + void topline(const char *n); + void topline(int n); + void value(const char *f); + const char * value() const; + int visible(); + int w(); + int x(); + int y(); +}; +#endif + +// +// End of "$Id: Fl_Help_Dialog.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Help_View.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Help_View.H new file mode 100644 index 0000000..c370ff7 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Help_View.H @@ -0,0 +1,387 @@ +// +// "$Id: Fl_Help_View.H 5991 2007-12-15 16:08:23Z mike $" +// +// Help Viewer widget definitions. +// +// Copyright 1997-2005 by Easy Software Products. +// Image support donated by Matthias Melcher, Copyright 2000. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// +// Inline: +// +// Fl_Help_View::directory() - Get the directory string. +// Fl_Help_View::filename() - Get the filename string. +// Fl_Help_View::link() - Set the link callback. +// Fl_Help_View::size() - Get the total document length. +// Fl_Help_View::size() - Set the document width and height. +// Fl_Help_View::textcolor() - Set the default text color. +// Fl_Help_View::textcolor() - Get the default text color. +// Fl_Help_View::textsize() - Set the default font size. +// Fl_Help_View::textsize() - Get the default font size. +// Fl_Help_View::title() - Get the title string. +// Fl_Help_View::topline() - Get the top line in document. +// Fl_Help_View::leftline() - Get the left line position. +// Fl_Help_View::value() - Get the HTML text value. +// Fl_Help_View::monofont() - Set the default mono font. +// Fl_Help_View::monofont() - Get the default mono font. +// Fl_Help_View::reformat() - Format the help text. +// Fl_Help_View::sansfont() - Set the default sans font. +// Fl_Help_View::sansfont() - Get the default sans font. +// Fl_Help_View::serifont() - Set the default serif font. +// Fl_Help_View::serifont() - Get the default serif font. +// + +#ifndef Fl_Help_View_H +# define Fl_Help_View_H + +// +// Include necessary header files... +// + +# include +# include "Fl.H" +# include "Fl_Group.H" +# include "Fl_Scrollbar.H" +# include "fl_draw.H" +# include "Fl_Shared_Image.H" + + +// +// Fl_Help_Func type - link callback function for files... +// + +typedef const char *(Fl_Help_Func)(Fl_Widget *, const char *); + +// +// Fl_Help_Block structure +// + +// note: we can change private structs accessed by pointers +struct Fl_Help_Block +{ + const char *start, // Start of text + *end; // End of text + unsigned char border; // Draw border? + Fl_Color bgcolor; // Background color + int x, // Indentation/starting X coordinate + y, // Starting Y coordinate + w, // Width + h; // Height + // new fields, removed int line[32]; + unsigned char fsize; // current font size + int font, // current font + maxh, // max image height + imgy, // image y position + pre, // pre text flag + type, // blockquote/ol/ul/li type parameter + tag, // tag/element fourcc int + line, // Left starting position for each line + cbi; // current block index +}; + +// +// Fl_Help_Link structure +// + +struct Fl_Help_Link +{ + char filename[192], // Link reference filename + name[32]; // Link target name, blank if none + int x, // X offset of link text + y, // Y offset of link text + w, // Width of link text + h; // Height of link text +}; + +// +// Fl_Help_Target structure +// + +// note: hijacking this lets us add new data members via the d-pointer +struct Fl_Help_Target +{ + // new fields, removed char name[32]; int y; + Fl_Help_Link *targets, // Targets + *linkp; // Currently clicked link + unsigned char ispush, // link is pushed + islink, // link clicked + resized, // window resized + ispath, // is path used + nstyle, // navigation style flag + isnew, // is new page + pad7, // + pad8; // + int top, // current topline + ltop, // last topline + isnav, // is nav link + rwidth, // resize width + cssurllen, // css url length + csswordlen, // css word length + *cssword; // css word value + long rtime, // resize time + rsec, // resize seconds + rmil, // resize millisecs + csstextlen; // css text length + char *csstext, // css text value + *cssurl, // css url value + path[1024], // current file path + lpath[1024]; // last file path + int nfonts, // number of fonts in stack + fonts[100][2]; // font stack +}; + +// +// Fl_Help_View class... +// + +class FL_EXPORT Fl_Help_View : public Fl_Group // Help viewer widget +{ +private: + + enum { RIGHT = -1, CENTER, LEFT }; // Alignments + + char title_[1024]; // Title string + Fl_Color defcolor_, // Default text color + bgcolor_, // Background color + textcolor_, // Text color + linkcolor_; // Link color + unsigned char textfont_, // Default font - replaced + textsize_; // Default font size - replaced + const char *value_; // HTML text value + + int nblocks_, // Number of blocks/lines + ablocks_; // Allocated blocks + Fl_Help_Block *blocks_; // Blocks + + int nfonts_; // Number of fonts in stack - replaced + unsigned char fonts_[100][2]; // Font stack - replaced + + Fl_Help_Func *link_; // Link transform function + + int nlinks_, // Number of links + alinks_; // Allocated links + Fl_Help_Link *links_; // Links + + int ntargets_, // Number of targets + atargets_; // Allocated targets + Fl_Help_Target *d; // d-pointer struct - was *targets_ + // note: we can rename existing data members + + char directory_[1024], // Directory for current file + filename_[1024]; // Current filename + int topline_, // Top line in document + leftline_, // Left line position + size_, // Total document length + hsize_; // Maximum document width + Fl_Scrollbar scrollbar_, // Vertical scrollbar for document + hscrollbar_; // Horizontal scrollbar + + static int selection_first; // Text selection + static int selection_last; + static int selection_push_first; + static int selection_push_last; + static int selection_drag_first; + static int selection_drag_last; + static int selected; + static int draw_mode; + static int mouse_x; + static int mouse_y; + static int current_pos; + static Fl_Help_View *current_view; + static Fl_Color hv_selection_color; + static Fl_Color hv_selection_text_color; + + // new private static class variables + static int serifont_; // default serif font + static int sansfont_; // default sans font + static int monofont_; // default monospace font + static unsigned char fontsize_; // default font size + static short face_[250][4]; // font face table [m,b,i,p] + static unsigned char flet_[30]; // first face for letter table + static unsigned char fref_[1000]; // face reference table + + Fl_Help_Block *add_block(const char *sp, int xx, int yy, int ww, int hh, unsigned char bc = 0); + void add_link(const char *np, int xx, int yy, int ww, int hh); + void add_target(const char *np, int yy); + static int compare_targets(const Fl_Help_Target *t0, const Fl_Help_Target *t1); + int do_align(Fl_Help_Block *b, int li, int xx, int ca, int &sl); + void draw(); + void format(); + void format_table(int *tw, int *maxcols, const char *tp); + void free_data(); + int get_align(const char *ap, int da); + const char *get_attr(const char *ap, const char *np, char *buf, int sb); + Fl_Color get_color(const char *np, Fl_Color dc); + Fl_Shared_Image *get_image(const char *np, int iw, int ih); + int get_length(const char *lp); + //int handle(int event); // moved to public + // note: you can remove private non-virtual functions if not called by inline functions + + void initfont(unsigned char &fi, unsigned char &fs) { // Reset stack - replaced, for when nfonts > 255 + nfonts_ = 0; + fl_font(fi = fonts_[0][0] = serifont_, fs = fonts_[0][1] = fontsize_); + } + void pushfont(unsigned char fi, unsigned char fs) { // Push font - replaced + if (nfonts_ < 99) nfonts_ ++; + fl_font(fonts_[nfonts_][0] = fi, fonts_[nfonts_][1] = fs); + } + void popfont(unsigned char &fi, unsigned char &fs) { // Pop font - replaced + if (nfonts_ > 0) nfonts_ --; + fl_font(fi = fonts_[nfonts_][0], fs = fonts_[nfonts_][1]); + } + + void hv_draw(const char *tp, int xx, int yy); + char begin_selection(); + char extend_selection(); + void end_selection(int cb = 0); + void clear_global_selection(); + Fl_Help_Link *find_link(int xx, int yy); + void follow_link(Fl_Help_Link *lp); + + // new private functions + // note: for BC we can't modify existing function declarations + Fl_Help_Block *add_block(const Fl_Help_Block &b, const char *sp, int ww); + unsigned char build_faces(); + static int cmp_targets(const Fl_Help_Link *t0, const Fl_Help_Link *t1); + const char *format_table(int &tw, int *maxcols, const char *tp, int xx, int rc); + int get_css_value(const char *sp, const char *pp, char *vp); + int get_font_size(const char *hp); + int get_length(const char *lp, int hw); + void initfont(int &fi, unsigned char &fs); + int load_css(const char *fp); + void parse_css(Fl_Help_Block &b, const char *sp, char *buf); + void popfont(int &fi, unsigned char &fs); + void pushfont(int fi, unsigned char fs); + +public: + + Fl_Help_View(int xx, int yy, int ww, int hh, const char *lp = 0); + ~Fl_Help_View(); + + const char *directory() const { // Get the directory string + if (directory_[0]) return directory_; + else return (const char *)0; + } + const char *filename() const { // Get the filename string + if (filename_[0]) return filename_; + else return (const char *)0; + } + + int find(const char *sp, int pos = 0); + + void link(Fl_Help_Func *fn) { // Set the link callback + link_ = fn; + } + + int load(const char *fp); + void resize(int xx, int yy, int ww, int hh); + + int size() const { // Get the total document length + return size_; + } + void size(int ww, int hh) { // Set the document width and height + Fl_Widget::size(ww, hh); + } + void textcolor(Fl_Color tc) { // Set the default text color + if (textcolor_ == defcolor_) textcolor_ = tc; + defcolor_ = tc; + } + Fl_Color textcolor() const { // Get the default text color + return defcolor_; + } + void textfont(unsigned char fi) { // Set the text font, obsolete + textfont_ = fi; + //format(); // removed + // note: we can remove the contents of inline functions + } + unsigned char textfont() const { // Get the text font, obsolete + return textfont_; + } + void textsize(unsigned char fs) { // Set the default font size + fontsize_ = fs; + //format(); // removed + } + unsigned char textsize() const { // Get the default font size + return fontsize_; + } + const char *title() { // Get the title string + return title_; + } + + void topline(const char *np); + void topline(int yy); + int topline() const { // Get the top line in document + return topline_; + } + + void leftline(int xx); + int leftline() const { // Get the left line position + return leftline_; + } + + void value(const char *tp); + const char *value() const { // Get the HTML text value + return value_; + } + + void clear_selection(); + void select_all(); + + // new public functions + int fileislink(); + void filepath(const char *fp); + char *filepath(); + int font_face(const char *sp); + int font_style(int fi, unsigned char fs); + int gettopline(); + int handle(int event); // moved from private + + void monofont(int fi) { // set the default mono font + monofont_ = fi; + } + int monofont() const { // get the default mono font + return monofont_; + } + void reformat() { // format the help text - wrapper function + format(); + } + void sansfont(int fi) { // set the default sans font + sansfont_ = fi; + } + int sansfont() const { // get the default sans font + return sansfont_; + } + void serifont(int fi) { // set the default serif font + serifont_ = fi; + } + int serifont() const { // get the default serif font + return serifont_; + } + + void setstyle(int flag); + +}; + +#endif // !Fl_Help_View_H + +// +// End of "$Id: Fl_Help_View.H 5991 2007-12-15 16:08:23Z mike $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Hold_Browser.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Hold_Browser.H new file mode 100644 index 0000000..67761dc --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Hold_Browser.H @@ -0,0 +1,61 @@ +// +// "$Id: Fl_Hold_Browser.H 7903 2010-11-28 21:06:39Z matt $" +// +// Hold browser header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Hold_Browser widget . */ + +#ifndef Fl_Hold_Browser_H +#define Fl_Hold_Browser_H + +#include "Fl_Browser.H" + +/** + The Fl_Hold_Browser is a subclass of Fl_Browser + which lets the user select a single item, or no items by clicking on + the empty space. As long as the mouse button is held down the item + pointed to by it is highlighted, and this highlighting remains on when + the mouse button is released. Normally the callback is done when the + user releases the mouse, but you can change this with when(). +

See Fl_Browser for methods to add and remove lines from the browser. +*/ +class Fl_Hold_Browser : public Fl_Browser { +public: + /** + Creates a new Fl_Hold_Browser widget using the given + position, size, and label string. The default boxtype is FL_DOWN_BOX. + The constructor specializes Fl_Browser() by setting the type to FL_HOLD_BROWSER. + The destructor destroys the widget and frees all memory that has been allocated. + */ + Fl_Hold_Browser(int X,int Y,int W,int H,const char *l=0) + : Fl_Browser(X,Y,W,H,l) {type(FL_HOLD_BROWSER);} +}; + +#endif + +// +// End of "$Id: Fl_Hold_Browser.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Hor_Fill_Slider.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Hor_Fill_Slider.H new file mode 100644 index 0000000..f4fa54c --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Hor_Fill_Slider.H @@ -0,0 +1,46 @@ +// +// "$Id: Fl_Hor_Fill_Slider.H 7903 2010-11-28 21:06:39Z matt $" +// +// Horizontal fill slider header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Hor_Fill_Slider widget . */ + +#ifndef Fl_Hor_Fill_Slider_H +#define Fl_Hor_Fill_Slider_H + +#include "Fl_Slider.H" + +class Fl_Hor_Fill_Slider : public Fl_Slider { +public: + Fl_Hor_Fill_Slider(int x,int y,int w,int h,const char *l=0) + : Fl_Slider(x,y,w,h,l) {type(FL_HOR_FILL_SLIDER);} +}; + +#endif + +// +// End of "$Id: Fl_Hor_Fill_Slider.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Hor_Nice_Slider.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Hor_Nice_Slider.H new file mode 100644 index 0000000..336b307 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Hor_Nice_Slider.H @@ -0,0 +1,46 @@ +// +// "$Id: Fl_Hor_Nice_Slider.H 7903 2010-11-28 21:06:39Z matt $" +// +// Horizontal "nice" slider header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Hor_Nice_Slider widget . */ + +#ifndef Fl_Hor_Nice_Slider_H +#define Fl_Hor_Nice_Slider_H + +#include "Fl_Slider.H" + +class Fl_Hor_Nice_Slider : public Fl_Slider { +public: + Fl_Hor_Nice_Slider(int x,int y,int w,int h,const char *l=0) + : Fl_Slider(x,y,w,h,l) {type(FL_HOR_NICE_SLIDER); box(FL_FLAT_BOX);} +}; + +#endif + +// +// End of "$Id: Fl_Hor_Nice_Slider.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Hor_Slider.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Hor_Slider.H new file mode 100644 index 0000000..768dc90 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Hor_Slider.H @@ -0,0 +1,46 @@ +// +// "$Id: Fl_Hor_Slider.H 7903 2010-11-28 21:06:39Z matt $" +// +// Horizontal slider header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Hor_Slider widget . */ + +#ifndef Fl_Hor_Slider_H +#define Fl_Hor_Slider_H + +#include "Fl_Slider.H" + +class Fl_Hor_Slider : public Fl_Slider { +public: + Fl_Hor_Slider(int X,int Y,int W,int H,const char *l=0) + : Fl_Slider(X,Y,W,H,l) {type(FL_HOR_SLIDER);} +}; + +#endif + +// +// End of "$Id: Fl_Hor_Slider.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Hor_Value_Slider.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Hor_Value_Slider.H new file mode 100644 index 0000000..f196ddc --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Hor_Value_Slider.H @@ -0,0 +1,46 @@ +// +// "$Id: Fl_Hor_Value_Slider.H 7903 2010-11-28 21:06:39Z matt $" +// +// Horizontal value slider header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Hor_Value_Slider widget . */ + +#ifndef Fl_Hor_Value_Slider_H +#define Fl_Hor_Value_Slider_H + +#include "Fl_Value_Slider.H" + +class Fl_Hor_Value_Slider : public Fl_Value_Slider { +public: + Fl_Hor_Value_Slider(int X,int Y,int W,int H,const char *l=0) + : Fl_Value_Slider(X,Y,W,H,l) {type(FL_HOR_SLIDER);} +}; + +#endif + +// +// End of "$Id: Fl_Hor_Value_Slider.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Image.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Image.H new file mode 100644 index 0000000..6f76906 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Image.H @@ -0,0 +1,230 @@ +// +// "$Id: Fl_Image.H 7903 2010-11-28 21:06:39Z matt $" +// +// Image header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Image, Fl_RGB_Image classes . */ + +#ifndef Fl_Image_H +# define Fl_Image_H + +# include "Enumerations.H" + +class Fl_Widget; +struct Fl_Menu_Item; +struct Fl_Label; + +/** + Fl_Image is the base class used for caching and + drawing all kinds of images in FLTK. This class keeps track of + common image data such as the pixels, colormap, width, height, + and depth. Virtual methods are used to provide type-specific + image handling.

+ +

Since the Fl_Image class does not support image + drawing by itself, calling the draw() method results in + a box with an X in it being drawn instead. +*/ +class FL_EXPORT Fl_Image { + int w_, h_, d_, ld_, count_; + const char * const *data_; + + // Forbid use of copy contructor and assign operator + Fl_Image & operator=(const Fl_Image &); + Fl_Image(const Fl_Image &); + + protected: + + /** + The first form of the w() method returns the current + image width in pixels.

+ +

The second form is a protected method that sets the current + image width. + */ + void w(int W) {w_ = W;} + /** + The first form of the h() method returns the current + image height in pixels.

+ +

The second form is a protected method that sets the current + image height. + */ + void h(int H) {h_ = H;} + /** + The first form of the d() method returns the current + image depth. The return value will be 0 for bitmaps, 1 for + pixmaps, and 1 to 4 for color images.

+ +

The second form is a protected method that sets the current + image depth. + */ + void d(int D) {d_ = D;} + /** See int ld() */ + void ld(int LD) {ld_ = LD;} + /** See const char * const *data() */ + void data(const char * const *p, int c) {data_ = p; count_ = c;} + void draw_empty(int X, int Y); + + static void labeltype(const Fl_Label *lo, int lx, int ly, int lw, int lh, Fl_Align la); + static void measure(const Fl_Label *lo, int &lw, int &lh); + + public: + + /** See void Fl_Image::w(int) */ + int w() const {return w_;} + /** See void Fl_Image::h(int) */ + int h() const {return h_;} + /** + The first form of the d() method returns the current + image depth. The return value will be 0 for bitmaps, 1 for + pixmaps, and 1 to 4 for color images.

+ +

The second form is a protected method that sets the current + image depth. + */ + int d() const {return d_;} + /** + The first form of the ld() method returns the current + line data size in bytes. Line data is extra data that is included + after each line of color image data and is normally not present.

+ +

The second form is a protected method that sets the current + line data size in bytes. + */ + int ld() const {return ld_;} + /** + The count() method returns the number of data values + associated with the image. The value will be 0 for images with + no associated data, 1 for bitmap and color images, and greater + than 2 for pixmap images. + */ + int count() const {return count_;} + /** + The first form of the data() method returns a + pointer to the current image data array. Use the + count() method to find the size of the data array.

+ +

The second form is a protected method that sets the current + array pointer and count of pointers in the array. + */ + const char * const *data() const {return data_;} + + /** + The constructor creates an empty image with the specified + width, height, and depth. The width and height are in pixels. + The depth is 0 for bitmaps, 1 for pixmap (colormap) images, and + 1 to 4 for color images. + */ + Fl_Image(int W, int H, int D) {w_ = W; h_ = H; d_ = D; ld_ = 0; count_ = 0; data_ = 0;} + virtual ~Fl_Image(); + virtual Fl_Image *copy(int W, int H); + /** + The copy() method creates a copy of the specified + image. If the width and height are provided, the image is + resized to the specified size. The image should be deleted (or in + the case of Fl_Shared_Image, released) when you are done + with it. + */ + Fl_Image *copy() { return copy(w(), h()); } + virtual void color_average(Fl_Color c, float i); + /** + The inactive() method calls + color_average(FL_BACKGROUND_COLOR, 0.33f) to produce + an image that appears grayed out. This method does not + alter the original image data. + */ + void inactive() { color_average(FL_GRAY, .33f); } + virtual void desaturate(); + virtual void label(Fl_Widget*w); + virtual void label(Fl_Menu_Item*m); + /** + The draw() methods draw the image. This form specifies + a bounding box for the image, with the origin + (upper-lefthand corner) of the image offset by the cx + and cy arguments. + */ + virtual void draw(int X, int Y, int W, int H, int cx=0, int cy=0); // platform dependent + /** + The draw() methods draw the image. This form + specifies the upper-lefthand corner of the image + */ + void draw(int X, int Y) {draw(X, Y, w(), h(), 0, 0);} // platform dependent + virtual void uncache(); +}; + +/** + The Fl_RGB_Image class supports caching and drawing + of full-color images with 1 to 4 channels of color information. + Images with an even number of channels are assumed to contain + alpha information, which is used to blend the image with the + contents of the screen.

+ +

Fl_RGB_Image is defined in + <FL/Fl_Image.H>, however for compatibility reasons + <FL/Fl_RGB_Image.H> should be included. +*/ +class FL_EXPORT Fl_RGB_Image : public Fl_Image { + friend class Fl_Quartz_Graphics_Driver; + friend class Fl_GDI_Graphics_Driver; + friend class Fl_Xlib_Graphics_Driver; +public: + + const uchar *array; + int alloc_array; // Non-zero if array was allocated + + private: + +#if defined(__APPLE__) || defined(WIN32) + void *id_; // for internal use + void *mask_; // for internal use (mask bitmap) +#else + unsigned id_; // for internal use + unsigned mask_; // for internal use (mask bitmap) +#endif // __APPLE__ || WIN32 + + public: + +/** The constructor creates a new image from the specified data. */ + Fl_RGB_Image(const uchar *bits, int W, int H, int D=3, int LD=0) : + Fl_Image(W,H,D), array(bits), alloc_array(0), id_(0), mask_(0) {data((const char **)&array, 1); ld(LD);} + virtual ~Fl_RGB_Image(); + virtual Fl_Image *copy(int W, int H); + Fl_Image *copy() { return copy(w(), h()); } + virtual void color_average(Fl_Color c, float i); + virtual void desaturate(); + virtual void draw(int X, int Y, int W, int H, int cx=0, int cy=0); + void draw(int X, int Y) {draw(X, Y, w(), h(), 0, 0);} + virtual void label(Fl_Widget*w); + virtual void label(Fl_Menu_Item*m); + virtual void uncache(); +}; + +#endif // !Fl_Image_H + +// +// End of "$Id: Fl_Image.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Input.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Input.H new file mode 100644 index 0000000..fb535e5 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Input.H @@ -0,0 +1,109 @@ +// +// "$Id: Fl_Input.H 7903 2010-11-28 21:06:39Z matt $" +// +// Input header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Input widget . */ + +#ifndef Fl_Input_H +#define Fl_Input_H + +#include "Fl_Input_.H" + +/** + This is the FLTK text input widget. It displays a single line + of text and lets the user edit it. Normally it is drawn with an + inset box and a white background. The text may contain any + characters (even 0), and will correctly display any UTF text, using + ^X notation for unprintable control characters. It assumes the + font can draw any characters of the used scripts, which is true + for standard fonts under MSWindows and Mac OS X. + Characters can be input using the keyboard or the character palette/map. + Character composition is done using using dead keys and/or a compose + key as defined by the operating system. +

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
Mouse button 1Moves the cursor to + this point. Drag selects characters. Double click selects words. + Triple click selects all text. Shift+click extends the selection. + When you select text it is automatically copied to the clipboard. +
Mouse button 2Insert the clipboard at + the point clicked. You can also select a region and replace it with the + clipboard by selecting the region with mouse button 2. +
Mouse button 3Currently acts like button 1.
BackspaceDeletes one character to the left, or + deletes the selected region.
EnterMay cause the callback, see when().
^A or HomeGo to start of line.
^B or LeftMove left
^CCopy the selection to the clipboard
^D or DeleteDeletes one character to the right + or deletes the selected region.
^E or EndGo to the end of line.
^F or RightMove right
^KDelete to the end of line (next \\n character) + or deletes a single \\n character. These deletions are all concatenated + into the clipboard.
^N or DownMove down (for Fl_Multiline_Input + only, otherwise it moves to the next input field).
^P or UpMove up (for Fl_Multiline_Input only, + otherwise it moves to the previous input field).
^UDelete everything.
^V or ^YPaste the clipboard
^X or ^WCopy the region to the clipboard and + delete it.
^Z or ^_Undo. This is a single-level undo + mechanism, but all adjacent deletions and insertions are concatenated + into a single "undo". Often this will undo a lot more than you + expected.
Shift+moveMove the cursor but also extend the + selection.
+ */ +class FL_EXPORT Fl_Input : public Fl_Input_ { + int handle_key(); + int shift_position(int p); + int shift_up_down_position(int p); + void handle_mouse(int keepmark=0); +protected: + void draw(); +public: + int handle(int); + Fl_Input(int,int,int,int,const char * = 0); +}; + +#endif + +// +// End of "$Id: Fl_Input.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Input_.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Input_.H new file mode 100644 index 0000000..70137e8 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Input_.H @@ -0,0 +1,455 @@ +// +// "$Id: Fl_Input_.H 7903 2010-11-28 21:06:39Z matt $" +// +// Input base class header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Input_ widget . */ + +#ifndef Fl_Input__H +#define Fl_Input__H + +#ifndef Fl_Widget_H +#include "Fl_Widget.H" +#endif + +#define FL_NORMAL_INPUT 0 +#define FL_FLOAT_INPUT 1 +#define FL_INT_INPUT 2 +#define FL_HIDDEN_INPUT 3 +#define FL_MULTILINE_INPUT 4 +#define FL_SECRET_INPUT 5 +#define FL_INPUT_TYPE 7 +#define FL_INPUT_READONLY 8 +#define FL_NORMAL_OUTPUT (FL_NORMAL_INPUT | FL_INPUT_READONLY) +#define FL_MULTILINE_OUTPUT (FL_MULTILINE_INPUT | FL_INPUT_READONLY) +#define FL_INPUT_WRAP 16 +#define FL_MULTILINE_INPUT_WRAP (FL_MULTILINE_INPUT | FL_INPUT_WRAP) +#define FL_MULTILINE_OUTPUT_WRAP (FL_MULTILINE_INPUT | FL_INPUT_READONLY | FL_INPUT_WRAP) + +/** + This class provides a low-overhead text input field. + + This is a virtual base class below Fl_Input. It has all + the same interfaces, but lacks the handle() and + draw() method. You may want to subclass it if you are + one of those people who likes to change how the editing keys + work. It may also be useful for adding scrollbars + to the input field. + + This can act like any of the subclasses of Fl_Input, by + setting type() to one of the following values: + + \code + #define FL_NORMAL_INPUT 0 + #define FL_FLOAT_INPUT 1 + #define FL_INT_INPUT 2 + #define FL_MULTILINE_INPUT 4 + #define FL_SECRET_INPUT 5 + #define FL_INPUT_TYPE 7 + #define FL_INPUT_READONLY 8 + #define FL_NORMAL_OUTPUT (FL_NORMAL_INPUT | FL_INPUT_READONLY) + #define FL_MULTILINE_OUTPUT (FL_MULTILINE_INPUT | FL_INPUT_READONLY) + #define FL_INPUT_WRAP 16 + #define FL_MULTILINE_INPUT_WRAP (FL_MULTILINE_INPUT | FL_INPUT_WRAP) + #define FL_MULTILINE_OUTPUT_WRAP (FL_MULTILINE_INPUT | FL_INPUT_READONLY | FL_INPUT_WRAP) + \endcode + + All variables that represent an index into a text buffer are byte-oriented, + not character oriented. Since utf8 characters can be up to six bytes long, + simply incrementing such an index will not reliably advance to the next character + in the text buffer. + + Indices and pointers into the text buffer should always point at a 7 bit ASCII + character or the beginning of a utf8 character sequence. Behavior for false + utf8 sequences and pointers into the middle of a seqeunce are undefined. + + \see Fl_Text_Display, Fl_Text_Editor for more powerful text handling widgets + + \internal + When porting this widget from ASCII to UTF8, previously legal pointers into + the text of this widget can become illegal by pointing into the middle of + a UTF8 seuence. This is not a big problem for Fl_Input_ because all code + in this module is quite tolerant. It could be problematic though when deriving + from this class because no feedback for illegal pointers is given. Additionaly, + a careless "copy" call can put partial UTF8 sequnces into the clipboard. + + None of these issues should be desasterous. Nevertheless, we should + discuss how FLTK should handle false UTF8 suequences and pointers. +*/ +class FL_EXPORT Fl_Input_ : public Fl_Widget { + + /** \internal Storage for the text field. */ + const char* value_; + + /** \internal Buffer memory for expanded text. \see expand() */ + char* buffer; + + /** \internal Size of text in bytes in the \p value_ field. */ + int size_; + + /** \internal \todo Please document me! */ + int bufsize; + + /** \internal Positin of the cursor in the document */ + int position_; + + /** \internal Position of the other end of the selected text. If \p position_ equals + \p mark_, no text is selected */ + int mark_; + + /** \internal Offset to text origin within widget bounds */ + int xscroll_, yscroll_; + + /** \internal Minimal update pointer. Display requirs redraw from here to the end + of the buffer. */ + int mu_p; + + /** \internal Maximum size of buffer. \todo Is this really needed? */ + int maximum_size_; + + /** \internal Shortcut key that will fetch focus for this widget. */ + int shortcut_; + + /** \internal This is set if no text but only the cursor needs updating. */ + uchar erase_cursor_only; + + /** \internal The font used for the entire text. */ + Fl_Font textfont_; + + /** \internal Height of the font used for the entire text. */ + Fl_Fontsize textsize_; + + /** \internal color of the entire text */ + Fl_Color textcolor_; + + /** \internal color of the text cursor */ + Fl_Color cursor_color_; + + /** \internal Horizontal cursor position in pixels while movin up or down. */ + static double up_down_pos; + + /** \internal Flag to remember last cursor move. */ + static int was_up_down; + + /* Convert a given text segment into the text that will be rendered on screen. */ + const char* expand(const char*, char*) const; + + /* Calculates the width in pixels of part of a text buffer. */ + double expandpos(const char*, const char*, const char*, int*) const; + + /* Mark a range of characters for update. */ + void minimal_update(int, int); + + /* Mark a range of characters for update. */ + void minimal_update(int p); + + /* Copy the value from a possibly static entry into the internal buffer. */ + void put_in_buffer(int newsize); + + /* Set the current font and font size. */ + void setfont() const; + +protected: + + /* Find the start of a word. */ + int word_start(int i) const; + + /* Find the end of a word. */ + int word_end(int i) const; + + /* Find the start of a line. */ + int line_start(int i) const; + + /* Find the end of a line. */ + int line_end(int i) const; + + /* Draw the text in the passed bounding box. */ + void drawtext(int, int, int, int); + + /* Move the cursor to the column given by up_down_pos. */ + int up_down_position(int, int keepmark=0); + + /* Handle mouse clicks and mose moves. */ + void handle_mouse(int, int, int, int, int keepmark=0); + + /* Handle all kinds of text field related events. */ + int handletext(int e, int, int, int, int); + + /* Check the when() field and do a callback if indicated. */ + void maybe_do_callback(); + + /** \internal Horizontal offset of text to left edge of widget. */ + int xscroll() const {return xscroll_;} + + /** \internal Vertical offset of text to top edge of widget. */ + int yscroll() const {return yscroll_;} + void yscroll(int y) { yscroll_ = y; damage(FL_DAMAGE_EXPOSE);} + + /* Return the number of lines displayed on a single page. */ + int linesPerPage(); + +public: + + /* Change the size of the widget. */ + void resize(int, int, int, int); + + /* Constructor */ + Fl_Input_(int, int, int, int, const char* = 0); + + /* Destructor */ + ~Fl_Input_(); + + /* Changes the widget text. */ + int value(const char*); + + /* Changes the widget text. */ + int value(const char*, int); + + /* Changes the widget text. */ + int static_value(const char*); + + /* Changes the widget text. */ + int static_value(const char*, int); + + /** + Returns the text displayed in the widget. + + This function returns the current value, which is a pointer + to the internal buffer and is valid only until the next event is + handled. + + \return pointer to an internal buffer - do not free() this + \see Fl_Input_::value(const char*) + */ + const char* value() const {return value_;} + + /* Returns the character at index \p i. */ + Fl_Char index(int i) const; + + /** + Returns the number of bytes in value(). + + This may be greater than strlen(value()) if there are + \c nul characters in the text. + + \return number of bytes in the text + */ + int size() const {return size_;} + + /** Sets the width and height of this widget. + \param [in] W, H new width and height + \see Fl_Widget::size(int, int) */ + void size(int W, int H) { Fl_Widget::size(W, H); } + + /** Gets the maximum length of the input field. + \todo It is not clear if this function is actually required */ + int maximum_size() const {return maximum_size_;} + + /** Sets the maximum length of the input field. + \todo It is not clear if this function is actually required */ + void maximum_size(int m) {maximum_size_ = m;} + + /** Gets the position of the text cursor. + \return the cursor position as an index + \see position(int, int) + */ + int position() const {return position_;} + + /** Gets the current selection mark. + \return index into the text */ + int mark() const {return mark_;} + + /* Sets the index for the cursor and mark. */ + int position(int p, int m); + + /** Set the cursor position and mark. + position(n) is the same as position(n, n). + \param p new index for cursor and mark + \return 0 if no positions changed + \see position(int, int), position(), mark(int) + */ + int position(int p) {return position(p, p);} + + /** Sets the current selection mark. + mark(n) is the same as position(position(),n). + \param m new index of the mark + \return 0 if the mark did not change + \see position(), position(int, int) */ + int mark(int m) {return position(position(), m);} + + /* Deletes text from b to e and inserts the new string text. */ + int replace(int, int, const char*, int=0); + + /** + Deletes the current selection. + + This function deletes the currently selected text + \e without storing it in the clipboard. To use the clipboard, + you may call copy() first or copy_cuts() after + this call. + + \return 0 if no data was copied + */ + int cut() {return replace(position(), mark(), 0);} + + /** + Deletes the next \p n bytes rounded to characters before or after the cursor. + + This function deletes the currently selected text + \e without storing it in the clipboard. To use the clipboard, + you may call copy() first or copy_cuts() after + this call. + + \param n number of bytes rounded to full characters and clamped to the buffer. + A negative number will cut characters to the left of the cursor. + \return 0 if no data was copied + */ + int cut(int n) {return replace(position(), position()+n, 0);} + + /** + Deletes all characters between index \p a and \p b. + + This function deletes the currently selected text + \e without storing it in the clipboard. To use the clipboard, + you may call copy() first or copy_cuts() after + this call. + + \param a, b range of bytes rounded to full characters and clamped to the buffer + \return 0 if no data was copied + */ + int cut(int a, int b) {return replace(a, b, 0);} + + /** + Inserts text at the cursor position. + + This function inserts the string in \p t at the cursor + position() and moves the new position and mark to + the end of the inserted text. + + \param [in] t text that will be inserted + \param [in] l length of text, or 0 if the string is terminated by \c nul. + \return 0 if no text was inserted + */ + int insert(const char* t, int l=0){return replace(position_, mark_, t, l);} + + /* Put the current selection into the clipboard. */ + int copy(int clipboard); + + /* Undo previous changes to the text buffer. */ + int undo(); + + /* Copy the yank buffer to the clipboard. */ + int copy_cuts(); + + /** Return the shortcut key associtaed with this widget. + \return shortcut keystroke + \see Fl_Button::shortcut() */ + int shortcut() const {return shortcut_;} + + /** + Sets the shortcut key associtaed with this widget. + Pressing the shortcut key gives text editing focus to this widget. + \param [in] s new shortcut keystroke + \see Fl_Button::shortcut() + */ + void shortcut(int s) {shortcut_ = s;} + + /** Gets the font of the text in the input field. + \return the current Fl_Font index */ + Fl_Font textfont() const {return textfont_;} + + /** Sets the font of the text in the input field. + The text font defaults to \c FL_HELVETICA. + \param [in] s the new text font */ + void textfont(Fl_Font s) {textfont_ = s;} + + /** Gets the size of the text in the input field. + \return the text height in pixels */ + Fl_Fontsize textsize() const {return textsize_;} + + /** Sets the size of the text in the input field. + The text height defaults to \c FL_NORMAL_SIZE. + \param [in] s the new font height in pixel units */ + void textsize(Fl_Fontsize s) {textsize_ = s;} + + /** Gets the color of the text in the input field. + \return the text color + \see textcolor(Fl_Color) */ + Fl_Color textcolor() const {return textcolor_;} + + /** Sets the color of the text in the input field. + The text color defaults to \c FL_FOREGROUND_COLOR. + \param [in] n new text color + \see textcolor() */ + void textcolor(Fl_Color n) {textcolor_ = n;} + + /** Gets the color of the cursor. + \return the current cursor color */ + Fl_Color cursor_color() const {return cursor_color_;} + + /** Sets the color of the cursor. + The default color for the cursor is \c FL_BLACK. + \param [in] n the new cursor color */ + void cursor_color(Fl_Color n) {cursor_color_ = n;} + + /** Gets the input field type. + \return the current input type */ + int input_type() const {return type() & FL_INPUT_TYPE; } + + /** Sets the input field type. + A redraw() is required to reformat the input field. + \param [in] t new input type */ + void input_type(int t) { type((uchar)(t | readonly())); } + + /** Gets the read-only state of the input field. + \return non-zero if this widget is read-only */ + int readonly() const { return type() & FL_INPUT_READONLY; } + + /** Sets the read-only state of the input field. + \param [in] b if \p b is 0, the text in this widget can be edited by the user */ + void readonly(int b) { if (b) type((uchar)(type() | FL_INPUT_READONLY)); + else type((uchar)(type() & ~FL_INPUT_READONLY)); } + + /** + Gets the word wrapping state of the input field. + Word wrap is only functional with multi-line input fields. + */ + int wrap() const { return type() & FL_INPUT_WRAP; } + + /** + Sets the word wrapping state of the input field. + Word wrap is only functional with multi-line input fields. + */ + void wrap(int b) { if (b) type((uchar)(type() | FL_INPUT_WRAP)); + else type((uchar)(type() & ~FL_INPUT_WRAP)); } + +}; + +#endif + +// +// End of "$Id: Fl_Input_.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Input_Choice.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Input_Choice.H new file mode 100644 index 0000000..aa3f016 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Input_Choice.H @@ -0,0 +1,222 @@ +// +// "$Id: Fl_Input_Choice.H 7903 2010-11-28 21:06:39Z matt $" +// +// An input/chooser widget. +// ______________ ____ +// | || __ | +// | input area || \/ | +// |______________||____| +// +// Copyright 1998-2010 by Bill Spitzak and others. +// Copyright 2004 by Greg Ercolano. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Input_Choice widget . */ + + + +#ifndef Fl_Input_Choice_H +#define Fl_Input_Choice_H + +#include +#include +#include +#include +#include +#include + +/** + A combination of the input widget and a menu button. + The user can either type into the input area, or use the + menu button chooser on the right, which loads the input area + with predefined text. Normally it is drawn with an inset box + and a white background. +

+ The application can directly access both the input and menu + widgets directly, using the menubutton() + and input() accessor methods. +*/ +class Fl_Input_Choice : public Fl_Group { + // Private class to handle slightly 'special' behavior of menu button + class InputMenuButton : public Fl_Menu_Button { + void draw() { + draw_box(FL_UP_BOX, color()); + fl_color(active_r() ? labelcolor() : fl_inactive(labelcolor())); + int xc = x()+w()/2, yc=y()+h()/2; + fl_polygon(xc-5,yc-3,xc+5,yc-3,xc,yc+3); + if (Fl::focus() == this) draw_focus(); + } + public: + InputMenuButton(int x,int y,int w,int h,const char*l=0) : + Fl_Menu_Button(x,y,w,h,l) { box(FL_UP_BOX); } + }; + + Fl_Input *inp_; + InputMenuButton *menu_; + + static void menu_cb(Fl_Widget*, void *data) { + Fl_Input_Choice *o=(Fl_Input_Choice *)data; + Fl_Widget_Tracker wp(o); + const Fl_Menu_Item *item = o->menubutton()->mvalue(); + if (item && item->flags & (FL_SUBMENU|FL_SUBMENU_POINTER)) return; // ignore submenus + if (!strcmp(o->inp_->value(), o->menu_->text())) + { + o->Fl_Widget::clear_changed(); + if (o->when() & FL_WHEN_NOT_CHANGED) + o->do_callback(); + } + else + { + o->inp_->value(o->menu_->text()); + o->inp_->set_changed(); + o->Fl_Widget::set_changed(); + if (o->when() & (FL_WHEN_CHANGED|FL_WHEN_RELEASE)) + o->do_callback(); + } + + if (wp.deleted()) return; + + if (o->callback() != default_callback) + { + o->Fl_Widget::clear_changed(); + o->inp_->clear_changed(); + } + } + + static void inp_cb(Fl_Widget*, void *data) { + Fl_Input_Choice *o=(Fl_Input_Choice *)data; + Fl_Widget_Tracker wp(o); + if (o->inp_->changed()) { + o->Fl_Widget::set_changed(); + if (o->when() & (FL_WHEN_CHANGED|FL_WHEN_RELEASE)) + o->do_callback(); + } else { + o->Fl_Widget::clear_changed(); + if (o->when() & FL_WHEN_NOT_CHANGED) + o->do_callback(); + } + + if (wp.deleted()) return; + + if (o->callback() != default_callback) + o->Fl_Widget::clear_changed(); + } + + // Custom resize behavior -- input stretches, menu button doesn't + inline int inp_x() { return(x() + Fl::box_dx(box())); } + inline int inp_y() { return(y() + Fl::box_dy(box())); } + inline int inp_w() { return(w() - Fl::box_dw(box()) - 20); } + inline int inp_h() { return(h() - Fl::box_dh(box())); } + + inline int menu_x() { return(x() + w() - 20 - Fl::box_dx(box())); } + inline int menu_y() { return(y() + Fl::box_dy(box())); } + inline int menu_w() { return(20); } + inline int menu_h() { return(h() - Fl::box_dh(box())); } + +public: + /** + Creates a new Fl_Input_Choice widget using the given position, size, + and label string. +

Inherited destructor Destroys the widget and any value associated with it. + */ + Fl_Input_Choice (int x,int y,int w,int h,const char*l=0) : Fl_Group(x,y,w,h,l) { + Fl_Group::box(FL_DOWN_BOX); + align(FL_ALIGN_LEFT); // default like Fl_Input + inp_ = new Fl_Input(inp_x(), inp_y(), + inp_w(), inp_h()); + inp_->callback(inp_cb, (void*)this); + inp_->box(FL_FLAT_BOX); // cosmetic + inp_->when(FL_WHEN_CHANGED|FL_WHEN_NOT_CHANGED); + menu_ = new InputMenuButton(menu_x(), menu_y(), + menu_w(), menu_h()); + menu_->callback(menu_cb, (void*)this); + menu_->box(FL_FLAT_BOX); // cosmetic + end(); + } + + /** Adds an item to the menu.*/ + void add(const char *s) { menu_->add(s); } + int changed() const { return inp_->changed() | Fl_Widget::changed();} + void clear_changed() { + inp_->clear_changed(); + Fl_Widget::clear_changed(); + } + void set_changed() { + inp_->set_changed(); + // no need to call Fl_Widget::set_changed() + } + /** Removes all items from the menu. */ + void clear() { menu_->clear(); } + /** Gets the box type of the menu button */ + Fl_Boxtype down_box() const { return (menu_->down_box()); } + /** Sets the box type of the menu button */ + void down_box(Fl_Boxtype b) { menu_->down_box(b); } + /** Gets the Fl_Menu_Item array used for the menu. */ + const Fl_Menu_Item *menu() { return (menu_->menu()); } + /** Sets the Fl_Menu_Item array used for the menu. */ + void menu(const Fl_Menu_Item *m) { menu_->menu(m); } + void resize(int X, int Y, int W, int H) { + Fl_Group::resize(X,Y,W,H); + inp_->resize(inp_x(), inp_y(), inp_w(), inp_h()); + menu_->resize(menu_x(), menu_y(), menu_w(), menu_h()); + } + /** Gets the encapsulated input text color attributes */ + Fl_Color textcolor() const { return (inp_->textcolor());} + /** Sets the encapsulated input text color attributes */ + void textcolor(Fl_Color c) { inp_->textcolor(c);} + /** Gets the encapsulated input text font attributes */ + Fl_Font textfont() const { return (inp_->textfont());} + /** Sets the encapsulated input text font attributes */ + void textfont(Fl_Font f) { inp_->textfont(f);} + /** Gets the encapsulated input size attributes */ + Fl_Fontsize textsize() const { return (inp_->textsize()); } + /** Sets the encapsulated input size attributes */ + void textsize(Fl_Fontsize s) { inp_->textsize(s); } + /** See void Fl_Input_Choice::value(const char *s) */ + const char* value() const { return (inp_->value()); } + /** + Sets or returns the input widget's current contents. The + second form sets the contents using the index into the menu + which you can set as an integer. Setting the value effectively + 'chooses' this menu item, and sets it as the new input text, + deleting the previous text. + */ + void value(const char *val) { inp_->value(val); } + /** See void Fl_Input_Choice::value(const char *s) */ + void value(int val) { + menu_->value(val); + inp_->value(menu_->text(val)); + } + /** Returns a reference to the internal Fl_Menu_Button widget. */ + Fl_Menu_Button *menubutton() { return menu_; } + /** + Returns a reference to the internal Fl_Input widget.

+ */ + Fl_Input *input() { return inp_; } +}; + +#endif // !Fl_Input_Choice_H + +// +// End of "$Id: Fl_Input_Choice.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Int_Input.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Int_Input.H new file mode 100644 index 0000000..9da96df --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Int_Input.H @@ -0,0 +1,55 @@ +// +// "$Id: Fl_Int_Input.H 7903 2010-11-28 21:06:39Z matt $" +// +// Integer input header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Int_Input widget . */ + +#ifndef Fl_Int_Input_H +#define Fl_Int_Input_H + +#include "Fl_Input.H" + +/** + The Fl_Int_Input class is a subclass of Fl_Input + that only allows the user to type decimal digits (or hex numbers of the form 0xaef). +*/ +class Fl_Int_Input : public Fl_Input { +public: + /** + Creates a new Fl_Int_Input widget using the given position, + size, and label string. The default boxtype is FL_DOWN_BOX. +

Inherited destructor Destroys the widget and any value associated with it. + */ + Fl_Int_Input(int X,int Y,int W,int H,const char *l = 0) + : Fl_Input(X,Y,W,H,l) {type(FL_INT_INPUT);} +}; + +#endif + +// +// End of "$Id: Fl_Int_Input.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_JPEG_Image.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_JPEG_Image.H new file mode 100644 index 0000000..06f3a4c --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_JPEG_Image.H @@ -0,0 +1,53 @@ +// +// "$Id: Fl_JPEG_Image.H 7903 2010-11-28 21:06:39Z matt $" +// +// JPEG image header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_JPEG_Image class . */ + +#ifndef Fl_JPEG_Image_H +#define Fl_JPEG_Image_H +# include "Fl_Image.H" + +/** + The Fl_JPEG_Image class supports loading, caching, + and drawing of Joint Photographic Experts Group (JPEG) File + Interchange Format (JFIF) images. The class supports grayscale + and color (RGB) JPEG image files. +*/ +class FL_EXPORT Fl_JPEG_Image : public Fl_RGB_Image { + +public: + + Fl_JPEG_Image(const char *filename); + Fl_JPEG_Image(const char *name, const unsigned char *data); +}; + +#endif + +// +// End of "$Id: Fl_JPEG_Image.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Light_Button.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Light_Button.H new file mode 100644 index 0000000..1a71b9f --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Light_Button.H @@ -0,0 +1,59 @@ +// +// "$Id: Fl_Light_Button.H 7903 2010-11-28 21:06:39Z matt $" +// +// Lighted button header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Light_Button widget . */ + +#ifndef Fl_Light_Button_H +#define Fl_Light_Button_H + +#include "Fl_Button.H" + +/** +

This subclass displays the "on" state by turning on a light, + rather than drawing pushed in. The shape of the "light" + is initially set to FL_DOWN_BOX. The color of the light when + on is controlled with selection_color(), which defaults to FL_YELLOW. + + Buttons generate callbacks when they are clicked by the user. You + control exactly when and how by changing the values for type() and when(). +

\image html Fl_Light_Button.gif

+ \image latex Fl_Light_Button.eps "Fl_Light_Button" width=4cm +*/ +class FL_EXPORT Fl_Light_Button : public Fl_Button { +protected: + virtual void draw(); +public: + virtual int handle(int); + Fl_Light_Button(int x,int y,int w,int h,const char *l = 0); +}; + +#endif + +// +// End of "$Id: Fl_Light_Button.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Line_Dial.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Line_Dial.H new file mode 100644 index 0000000..8962cb1 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Line_Dial.H @@ -0,0 +1,46 @@ +// +// "$Id: Fl_Line_Dial.H 7903 2010-11-28 21:06:39Z matt $" +// +// Line dial header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Line_Dial widget . */ + +#ifndef Fl_Line_Dial_H +#define Fl_Line_Dial_H + +#include "Fl_Dial.H" + +class Fl_Line_Dial : public Fl_Dial { +public: + Fl_Line_Dial(int x,int y,int w,int h, const char *l = 0) + : Fl_Dial(x,y,w,h,l) {type(FL_LINE_DIAL);} +}; + +#endif + +// +// End of "$Id: Fl_Line_Dial.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Menu.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Menu.H new file mode 100644 index 0000000..a35dd4a --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Menu.H @@ -0,0 +1,33 @@ +// +// "$Id: Fl_Menu.H 7903 2010-11-28 21:06:39Z matt $" +// +// Old menu header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// this include file is for back compatibility only +#include "Fl_Menu_Item.H" + +// +// End of "$Id: Fl_Menu.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Menu_.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Menu_.H new file mode 100644 index 0000000..278ad8c --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Menu_.H @@ -0,0 +1,168 @@ +// +// "$Id: Fl_Menu_.H 7903 2010-11-28 21:06:39Z matt $" +// +// Menu base class header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Menu_ widget . */ + +#ifndef Fl_Menu__H +#define Fl_Menu__H + +#ifndef Fl_Widget_H +#include "Fl_Widget.H" +#endif +#include "Fl_Menu_Item.H" + +/** + Base class of all widgets that have a menu in FLTK. + Currently FLTK provides you with + Fl_Menu_Button, Fl_Menu_Bar, and Fl_Choice. + +

The class contains a pointer to an array of structures of type Fl_Menu_Item. The + array may either be supplied directly by the user program, or it may + be "private": a dynamically allocated array managed by the Fl_Menu_. +*/ +class FL_EXPORT Fl_Menu_ : public Fl_Widget { + + Fl_Menu_Item *menu_; + const Fl_Menu_Item *value_; + +protected: + + uchar alloc; // flag indicates if menu_ is a dynamic copy (=1) or not (=0) + uchar down_box_; + Fl_Font textfont_; + Fl_Fontsize textsize_; + Fl_Color textcolor_; + +public: + Fl_Menu_(int,int,int,int,const char * =0); + ~Fl_Menu_(); + + int item_pathname(char *name, int namelen, const Fl_Menu_Item *finditem=0) const; + const Fl_Menu_Item* picked(const Fl_Menu_Item*); + const Fl_Menu_Item* find_item(const char *name); + const Fl_Menu_Item* find_item(Fl_Callback*); + int find_index(const char *name) const; + int find_index(const Fl_Menu_Item *item) const; + int find_index(Fl_Callback *cb) const; + + /** + Returns the menu item with the entered shortcut (key value). + + This searches the complete menu() for a shortcut that matches the + entered key value. It must be called for a FL_KEYBOARD or FL_SHORTCUT + event. + + If a match is found, the menu's callback will be called. + + \return matched Fl_Menu_Item or NULL. + */ + const Fl_Menu_Item* test_shortcut() {return picked(menu()->test_shortcut());} + void global(); + + /** + Returns a pointer to the array of Fl_Menu_Items. This will either be + the value passed to menu(value) or the private copy. + */ + const Fl_Menu_Item *menu() const {return menu_;} + void menu(const Fl_Menu_Item *m); + void copy(const Fl_Menu_Item *m, void* user_data = 0); + int insert(int index, const char*, int shortcut, Fl_Callback*, void* = 0, int = 0); + int add(const char*, int shortcut, Fl_Callback*, void* = 0, int = 0); + /** See int Fl_Menu_::add(const char* label, int shortcut, Fl_Callback*, void *user_data=0, int flags=0) */ + int add(const char* a, const char* b, Fl_Callback* c, void* d = 0, int e = 0) { + return add(a,fl_old_shortcut(b),c,d,e); + } + /** See int Fl_Menu_::insert(const char* label, int shortcut, Fl_Callback*, void *user_data=0, int flags=0) */ + int insert(int index, const char* a, const char* b, Fl_Callback* c, void* d = 0, int e = 0) { + return insert(index,a,fl_old_shortcut(b),c,d,e); + } + int add(const char *); + int size() const ; + void size(int W, int H) { Fl_Widget::size(W, H); } + void clear(); + int clear_submenu(int index); + void replace(int,const char *); + void remove(int); + /** Changes the shortcut of item i to n. */ + void shortcut(int i, int s) {menu_[i].shortcut(s);} + /** Sets the flags of item i. For a list of the flags, see Fl_Menu_Item. */ + void mode(int i,int fl) {menu_[i].flags = fl;} + /** Gets the flags of item i. For a list of the flags, see Fl_Menu_Item. */ + int mode(int i) const {return menu_[i].flags;} + + /** Returns a pointer to the last menu item that was picked. */ + const Fl_Menu_Item *mvalue() const {return value_;} + /** Returns the index into menu() of the last item chosen by the user. It is zero initially. */ + int value() const {return value_ ? (int)(value_-menu_) : -1;} + int value(const Fl_Menu_Item*); + /** + The value is the index into menu() of the last item chosen by + the user. It is zero initially. You can set it as an integer, or set + it with a pointer to a menu item. The set routines return non-zero if + the new value is different than the old one. + */ + int value(int i) {return value(menu_+i);} + /** Returns the title of the last item chosen. */ + const char *text() const {return value_ ? value_->text : 0;} + /** Returns the title of item i. */ + const char *text(int i) const {return menu_[i].text;} + + /** Gets the current font of menu item labels. */ + Fl_Font textfont() const {return textfont_;} + /** Sets the current font of menu item labels. */ + void textfont(Fl_Font c) {textfont_=c;} + /** Gets the font size of menu item labels. */ + Fl_Fontsize textsize() const {return textsize_;} + /** Sets the font size of menu item labels. */ + void textsize(Fl_Fontsize c) {textsize_=c;} + /** Get the current color of menu item labels. */ + Fl_Color textcolor() const {return textcolor_;} + /** Sets the current color of menu item labels. */ + void textcolor(Fl_Color c) {textcolor_=c;} + + /** + This box type is used to surround the currently-selected items in the + menus. If this is FL_NO_BOX then it acts like + FL_THIN_UP_BOX and selection_color() acts like + FL_WHITE, for back compatibility. + */ + Fl_Boxtype down_box() const {return (Fl_Boxtype)down_box_;} + /** See Fl_Boxtype Fl_Menu_::down_box() const */ + void down_box(Fl_Boxtype b) {down_box_ = b;} + + /** For back compatibility, same as selection_color() */ + Fl_Color down_color() const {return selection_color();} + /** For back compatibility, same as selection_color() */ + void down_color(unsigned c) {selection_color(c);} +}; + +#endif + +// +// End of "$Id: Fl_Menu_.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Menu_Bar.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Menu_Bar.H new file mode 100644 index 0000000..0b58454 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Menu_Bar.H @@ -0,0 +1,89 @@ +// +// "$Id: Fl_Menu_Bar.H 7903 2010-11-28 21:06:39Z matt $" +// +// Menu bar header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Menu_Bar widget . */ + +#ifndef Fl_Menu_Bar_H +#define Fl_Menu_Bar_H + +#include "Fl_Menu_.H" + +/** + This widget provides a standard menubar interface. Usually you will + put this widget along the top edge of your window. The height of the + widget should be 30 for the menu titles to draw correctly with the + default font. +

The items on the bar and the menus they bring up are defined by a + single Fl_Menu_Item + array. Because a Fl_Menu_Item array defines a hierarchy, the + top level menu defines the items in the menubar, while the submenus + define the pull-down menus. Sub-sub menus and lower pop up to the right + of the submenus.

+

\image html menubar.gif

+ \image latex menubar.eps " menubar" width=12cm +

If there is an item in the top menu that is not a title of a + submenu, then it acts like a "button" in the menubar. Clicking on it + will pick it.

+

When the user picks an item off the menu, the item's callback is + done with the menubar as the Fl_Widget* argument. If the item + does not have a callback the menubar's callback is done instead.

+

Submenus will also pop up in response to shortcuts indicated by + putting a '&' character in the name field of the menu item. If you put a + '&' character in a top-level "button" then the shortcut picks it. The + '&' character in submenus is ignored until the menu is popped up.

+

Typing the shortcut() of any of the menu items will cause + callbacks exactly the same as when you pick the item with the mouse. +*/ +class FL_EXPORT Fl_Menu_Bar : public Fl_Menu_ { +protected: + void draw(); +public: + int handle(int); + /** + Creates a new Fl_Menu_Bar widget using the given position, + size, and label string. The default boxtype is FL_UP_BOX. +

The constructor sets menu() to NULL. See + Fl_Menu_ for the methods to set or change the menu.

+

labelsize(), labelfont(), and labelcolor() + are used to control how the menubar items are drawn. They are + initialized from the Fl_Menu static variables, but you can + change them if desired.

+

label() is ignored unless you change align() to + put it outside the menubar. +

The destructor removes the Fl_Menu_Bar widget and all of its + menu items. + */ + Fl_Menu_Bar(int X, int Y, int W, int H,const char *l=0) + : Fl_Menu_(X,Y,W,H,l) {} +}; + +#endif + +// +// End of "$Id: Fl_Menu_Bar.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Menu_Button.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Menu_Button.H new file mode 100644 index 0000000..a11abd9 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Menu_Button.H @@ -0,0 +1,72 @@ +// +// "$Id: Fl_Menu_Button.H 7903 2010-11-28 21:06:39Z matt $" +// +// Menu button header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Menu_Button widget . */ + +#ifndef Fl_Menu_Button_H +#define Fl_Menu_Button_H + +#include "Fl_Menu_.H" + +/** + This is a button that when pushed pops up a menu (or hierarchy of + menus) defined by an array of + Fl_Menu_Item objects. +

\image html menu_button.gif

+ \image latex menu_button.eps " menu_button" width=5cm +

Normally any mouse button will pop up a menu and it is lined up + below the button as shown in the picture. However an Fl_Menu_Button + may also control a pop-up menu. This is done by setting the type() + , see below.

+

The menu will also pop up in response to shortcuts indicated by + putting a '&' character in the label().

+

Typing the shortcut() of any of the menu items will cause + callbacks exactly the same as when you pick the item with the mouse. + The '&' character in menu item names are only looked at when the menu is + popped up, however.

+

When the user picks an item off the menu, the item's callback is + done with the menu_button as the Fl_Widget* argument. If the + item does not have a callback the menu_button's callback is done + instead. +*/ +class FL_EXPORT Fl_Menu_Button : public Fl_Menu_ { +protected: + void draw(); +public: + // values for type: + enum {POPUP1 = 1, POPUP2, POPUP12, POPUP3, POPUP13, POPUP23, POPUP123}; + int handle(int); + const Fl_Menu_Item* popup(); + Fl_Menu_Button(int,int,int,int,const char * =0); +}; + +#endif + +// +// End of "$Id: Fl_Menu_Button.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Menu_Item.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Menu_Item.H new file mode 100644 index 0000000..5b038e7 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Menu_Item.H @@ -0,0 +1,419 @@ +// +// "$Id: Fl_Menu_Item.H 7903 2010-11-28 21:06:39Z matt $" +// +// Menu item header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Menu_Item_H +#define Fl_Menu_Item_H + +# include "Fl_Widget.H" +# include "Fl_Image.H" + +# if defined(__APPLE__) && defined(check) +# undef check +# endif + +enum { // values for flags: + FL_MENU_INACTIVE = 1, ///< Deactivate menu item (gray out) + FL_MENU_TOGGLE= 2, ///< Item is a checkbox toggle (shows checkbox for on/off state) + FL_MENU_VALUE = 4, ///< The on/off state for checkbox/radio buttons (if set, state is 'on') + FL_MENU_RADIO = 8, ///< Item is a radio button (one checkbox of many can be on) + FL_MENU_INVISIBLE = 0x10, ///< Item will not show up (shortcut will work) + FL_SUBMENU_POINTER = 0x20, ///< Indicates user_data() is a pointer to another menu array + FL_SUBMENU = 0x40, ///< This item is a submenu to other items + FL_MENU_DIVIDER = 0x80, ///< Creates divider line below this item. Also ends a group of radio buttons. + FL_MENU_HORIZONTAL = 0x100 ///< ??? -- reserved +}; + +extern FL_EXPORT Fl_Shortcut fl_old_shortcut(const char*); + +class Fl_Menu_; + +/** + The Fl_Menu_Item structure defines a single menu item that + is used by the Fl_Menu_ class. + \code + struct Fl_Menu_Item { + const char* text; // label() + ulong shortcut_; + Fl_Callback* callback_; + void* user_data_; + int flags; + uchar labeltype_; + uchar labelfont_; + uchar labelsize_; + uchar labelcolor_; + }; + + enum { // values for flags: + FL_MENU_INACTIVE = 1, // Deactivate menu item (gray out) + FL_MENU_TOGGLE = 2, // Item is a checkbox toggle (shows checkbox for on/off state) + FL_MENU_VALUE = 4, // The on/off state for checkbox/radio buttons (if set, state is 'on') + FL_MENU_RADIO = 8, // Item is a radio button (one checkbox of many can be on) + FL_MENU_INVISIBLE = 0x10, // Item will not show up (shortcut will work) + FL_SUBMENU_POINTER = 0x20, // Indicates user_data() is a pointer to another menu array + FL_SUBMENU = 0x40, // This item is a submenu to other items + FL_MENU_DIVIDER = 0x80, // Creates divider line below this item. Also ends a group of radio buttons. + FL_MENU_HORIZONTAL = 0x100 // ??? -- reserved + }; + \endcode + Typically menu items are statically defined; for example: + \code + Fl_Menu_Item popup[] = { + {"&alpha", FL_ALT+'a', the_cb, (void*)1}, + {"&beta", FL_ALT+'b', the_cb, (void*)2}, + {"gamma", FL_ALT+'c', the_cb, (void*)3, FL_MENU_DIVIDER}, + {"&strange", 0, strange_cb}, + {"&charm", 0, charm_cb}, + {"&truth", 0, truth_cb}, + {"b&eauty", 0, beauty_cb}, + {"sub&menu", 0, 0, 0, FL_SUBMENU}, + {"one"}, + {"two"}, + {"three"}, + {0}, + {"inactive", FL_ALT+'i', 0, 0, FL_MENU_INACTIVE|FL_MENU_DIVIDER}, + {"invisible",FL_ALT+'i', 0, 0, FL_MENU_INVISIBLE}, + {"check", FL_ALT+'i', 0, 0, FL_MENU_TOGGLE|FL_MENU_VALUE}, + {"box", FL_ALT+'i', 0, 0, FL_MENU_TOGGLE}, + {0}}; + \endcode + produces: + + \image html menu.gif + \image latex menu.eps "menu" width=10cm + + A submenu title is identified by the bit FL_SUBMENU in the + flags field, and ends with a label() that is NULL. + You can nest menus to any depth. A pointer to the first item in the + submenu can be treated as an Fl_Menu array itself. It is also + possible to make separate submenu arrays with FL_SUBMENU_POINTER flags. + + You should use the method functions to access structure members and + not access them directly to avoid compatibility problems with future + releases of FLTK. +*/ +struct FL_EXPORT Fl_Menu_Item { + const char *text; ///< menu item text, returned by label() + int shortcut_; ///< menu item shortcut + Fl_Callback *callback_; ///< menu item callback + void *user_data_; ///< menu item user_data for 3rd party apps + int flags; ///< menu item flags like FL_MENU_TOGGLE, FL_MENU_RADIO + uchar labeltype_; ///< how the menu item text looks like + Fl_Font labelfont_; ///< which font for this menu item text + Fl_Fontsize labelsize_; ///< size of menu item text + Fl_Color labelcolor_; ///< menu item text color + + // advance N items, skipping submenus: + const Fl_Menu_Item *next(int=1) const; + + /** + Advances a pointer by n items through a menu array, skipping + the contents of submenus and invisible items. There are two calls so + that you can advance through const and non-const data. + */ + Fl_Menu_Item *next(int i=1) { + return (Fl_Menu_Item*)(((const Fl_Menu_Item*)this)->next(i));} + + /** Returns the first menu item, same as next(0). */ + const Fl_Menu_Item *first() const { return next(0); } + + /** Returns the first menu item, same as next(0). */ + Fl_Menu_Item *first() { return next(0); } + + // methods on menu items: + /** + Returns the title of the item. + A NULL here indicates the end of the menu (or of a submenu). + A '&' in the item will print an underscore under the next letter, + and if the menu is popped up that letter will be a "shortcut" to pick + that item. To get a real '&' put two in a row. + */ + const char* label() const {return text;} + + /** See const char* Fl_Menu_Item::label() const */ + void label(const char* a) {text=a;} + + /** See const char* Fl_Menu_Item::label() const */ + void label(Fl_Labeltype a,const char* b) {labeltype_ = a; text = b;} + + /** + A labeltype identifies a routine that draws the label of the + widget. This can be used for special effects such as emboss, or to use + the label() pointer as another form of data such as a bitmap. + The value FL_NORMAL_LABEL prints the label as text. + */ + Fl_Labeltype labeltype() const {return (Fl_Labeltype)labeltype_;} + + /** + A labeltype identifies a routine that draws the label of the + widget. This can be used for special effects such as emboss, or to use + the label() pointer as another form of data such as a bitmap. + The value FL_NORMAL_LABEL prints the label as text. + */ + void labeltype(Fl_Labeltype a) {labeltype_ = a;} + + /** + This color is passed to the labeltype routine, and is typically the + color of the label text. This defaults to FL_BLACK. If this + color is not black fltk will not use overlay bitplanes to draw + the menu - this is so that images put in the menu draw correctly. + */ + Fl_Color labelcolor() const {return labelcolor_;} + + /** See Fl_Color Fl_Menu_Item::labelcolor() const */ + void labelcolor(Fl_Color a) {labelcolor_ = a;} + /** + Fonts are identified by small 8-bit indexes into a table. See the + enumeration list for predefined fonts. The default value is a + Helvetica font. The function Fl::set_font() can define new fonts. + */ + Fl_Font labelfont() const {return labelfont_;} + + /** + Fonts are identified by small 8-bit indexes into a table. See the + enumeration list for predefined fonts. The default value is a + Helvetica font. The function Fl::set_font() can define new fonts. + */ + void labelfont(Fl_Font a) {labelfont_ = a;} + + /** Gets the label font pixel size/height.*/ + Fl_Fontsize labelsize() const {return labelsize_;} + + /** Sets the label font pixel size/height.*/ + void labelsize(Fl_Fontsize a) {labelsize_ = a;} + + /** + Each item has space for a callback function and an argument for that + function. Due to back compatibility, the Fl_Menu_Item itself + is not passed to the callback, instead you have to get it by calling + ((Fl_Menu_*)w)->mvalue() where w is the widget argument. + */ + Fl_Callback_p callback() const {return callback_;} + + /** See Fl_Callback_p Fl_MenuItem::callback() const */ + void callback(Fl_Callback* c, void* p) {callback_=c; user_data_=p;} + + /** See Fl_Callback_p Fl_MenuItem::callback() const */ + void callback(Fl_Callback* c) {callback_=c;} + + /** See Fl_Callback_p Fl_MenuItem::callback() const */ + void callback(Fl_Callback0*c) {callback_=(Fl_Callback*)c;} + + /** See Fl_Callback_p Fl_MenuItem::callback() const */ + void callback(Fl_Callback1*c, long p=0) {callback_=(Fl_Callback*)c; user_data_=(void*)p;} + + /** + Get or set the user_data argument that is sent to the + callback function. + */ + void* user_data() const {return user_data_;} + /** + Get or set the user_data argument that is sent to the + callback function. + */ + void user_data(void* v) {user_data_ = v;} + /** + For convenience you can also define the callback as taking a long + argument. This is implemented by casting this to a Fl_Callback + and casting the long to a void* and may not be + portable to some machines. + */ + long argument() const {return (long)user_data_;} + /** + For convenience you can also define the callback as taking a long + argument. This is implemented by casting this to a Fl_Callback + and casting the long to a void* and may not be + portable to some machines. + */ + void argument(long v) {user_data_ = (void*)v;} + + /** Gets what key combination shortcut will trigger the menu item. */ + int shortcut() const {return shortcut_;} + + /** + Sets exactly what key combination will trigger the menu item. The + value is a logical 'or' of a key and a set of shift flags, for instance + FL_ALT+'a' or FL_ALT+FL_F+10 or just 'a'. A value of + zero disables the shortcut. + + The key can be any value returned by Fl::event_key(), but will usually + be an ASCII letter. Use a lower-case letter unless you require the shift + key to be held down. + + The shift flags can be any set of values accepted by Fl::event_state(). + If the bit is on that shift key must be pushed. Meta, Alt, Ctrl, + and Shift must be off if they are not in the shift flags (zero for the + other bits indicates a "don't care" setting). + */ + void shortcut(int s) {shortcut_ = s;} + /** + Returns true if either FL_SUBMENU or FL_SUBMENU_POINTER + is on in the flags. FL_SUBMENU indicates an embedded submenu + that goes from the next item through the next one with a NULL + label(). FL_SUBMENU_POINTER indicates that user_data() + is a pointer to another menu array. + */ + int submenu() const {return flags&(FL_SUBMENU|FL_SUBMENU_POINTER);} + /** + Returns true if a checkbox will be drawn next to this item. This is + true if FL_MENU_TOGGLE or FL_MENU_RADIO is set in the flags. + */ + int checkbox() const {return flags&FL_MENU_TOGGLE;} + /** + Returns true if this item is a radio item. When a radio button is + selected all "adjacent" radio buttons are turned off. A set of radio + items is delimited by an item that has radio() false, or by an + item with FL_MENU_DIVIDER turned on. + */ + int radio() const {return flags&FL_MENU_RADIO;} + /** Returns the current value of the check or radio item. */ + int value() const {return flags&FL_MENU_VALUE;} + /** + Turns the check or radio item "on" for the menu item. Note that this + does not turn off any adjacent radio items like set_only() does. + */ + void set() {flags |= FL_MENU_VALUE;} + + /** Turns the check or radio item "off" for the menu item. */ + void clear() {flags &= ~FL_MENU_VALUE;} + + void setonly(); + + /** Gets the visibility of an item. */ + int visible() const {return !(flags&FL_MENU_INVISIBLE);} + + /** Makes an item visible in the menu. */ + void show() {flags &= ~FL_MENU_INVISIBLE;} + + /** Hides an item in the menu. */ + void hide() {flags |= FL_MENU_INVISIBLE;} + + /** Gets whether or not the item can be picked. */ + int active() const {return !(flags&FL_MENU_INACTIVE);} + + /** Allows a menu item to be picked. */ + void activate() {flags &= ~FL_MENU_INACTIVE;} + /** + Prevents a menu item from being picked. Note that this will also cause + the menu item to appear grayed-out. + */ + void deactivate() {flags |= FL_MENU_INACTIVE;} + /** Returns non 0 if FL_INACTIVE and FL_INVISIBLE are cleared, 0 otherwise. */ + int activevisible() const {return !(flags & (FL_MENU_INACTIVE|FL_MENU_INVISIBLE));} + + // compatibility for FLUID so it can set the image of a menu item... + + /** compatibility api for FLUID, same as a->label(this) */ + void image(Fl_Image* a) {a->label(this);} + + /** compatibility api for FLUID, same as a.label(this) */ + void image(Fl_Image& a) {a.label(this);} + + // used by menubar: + int measure(int* h, const Fl_Menu_*) const; + void draw(int x, int y, int w, int h, const Fl_Menu_*, int t=0) const; + + // popup menus without using an Fl_Menu_ widget: + const Fl_Menu_Item* popup( + int X, int Y, + const char *title = 0, + const Fl_Menu_Item* picked=0, + const Fl_Menu_* = 0) const; + const Fl_Menu_Item* pulldown( + int X, int Y, int W, int H, + const Fl_Menu_Item* picked = 0, + const Fl_Menu_* = 0, + const Fl_Menu_Item* title = 0, + int menubar=0) const; + const Fl_Menu_Item* test_shortcut() const; + const Fl_Menu_Item* find_shortcut(int *ip=0, const bool require_alt = false) const; + + /** + Calls the Fl_Menu_Item item's callback, and provides the + Fl_Widget argument (and optionally overrides the user_data() + argument). You must first check that callback() is non-zero + before calling this. + */ + void do_callback(Fl_Widget* o) const {callback_(o, user_data_);} + + /** + Calls the Fl_Menu_Item item's callback, and provides the + Fl_Widget argument (and optionally overrides the user_data() + argument). You must first check that callback() is non-zero + before calling this. + */ + void do_callback(Fl_Widget* o,void* arg) const {callback_(o, arg);} + + /** + Calls the Fl_Menu_Item item's callback, and provides the + Fl_Widget argument (and optionally overrides the user_data() + argument). You must first check that callback() is non-zero + before calling this. + */ + void do_callback(Fl_Widget* o,long arg) const {callback_(o, (void*)arg);} + + // back-compatibility, do not use: + + /** back compatibility only \deprecated. */ + int checked() const {return flags&FL_MENU_VALUE;} + + /** back compatibility only \deprecated. */ + void check() {flags |= FL_MENU_VALUE;} + + /** back compatibility only \deprecated. */ + void uncheck() {flags &= ~FL_MENU_VALUE;} + + int insert(int,const char*,int,Fl_Callback*,void* =0, int =0); + int add(const char*, int shortcut, Fl_Callback*, void* =0, int = 0); + + /** See int add(const char*, int shortcut, Fl_Callback*, void*, int) */ + int add(const char*a, const char* b, Fl_Callback* c, + void* d = 0, int e = 0) { + return add(a,fl_old_shortcut(b),c,d,e);} + + int size() const ; +}; + +typedef Fl_Menu_Item Fl_Menu; // back compatibility + +enum { // back-compatibility enum: + FL_PUP_NONE = 0, + FL_PUP_GREY = FL_MENU_INACTIVE, + FL_PUP_GRAY = FL_MENU_INACTIVE, + FL_MENU_BOX = FL_MENU_TOGGLE, + FL_PUP_BOX = FL_MENU_TOGGLE, + FL_MENU_CHECK = FL_MENU_VALUE, + FL_PUP_CHECK = FL_MENU_VALUE, + FL_PUP_RADIO = FL_MENU_RADIO, + FL_PUP_INVISIBLE = FL_MENU_INVISIBLE, + FL_PUP_SUBMENU = FL_SUBMENU_POINTER +}; + +#endif + +// +// End of "$Id: Fl_Menu_Item.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Menu_Window.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Menu_Window.H new file mode 100644 index 0000000..cca5a97 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Menu_Window.H @@ -0,0 +1,68 @@ +// +// "$Id: Fl_Menu_Window.H 7903 2010-11-28 21:06:39Z matt $" +// +// Menu window header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Menu_Window widget . */ + +#ifndef Fl_Menu_Window_H +#define Fl_Menu_Window_H + +#include "Fl_Single_Window.H" + +/** + The Fl_Menu_Window widget is a window type used for menus. By + default the window is drawn in the hardware overlay planes if they are + available so that the menu don't force the rest of the window to + redraw. +*/ +class FL_EXPORT Fl_Menu_Window : public Fl_Single_Window { +public: + void show(); + void erase(); + void flush(); + void hide(); + /** Tells if hardware overlay mode is set */ + unsigned int overlay() {return !(flags()&NO_OVERLAY);} + /** Tells FLTK to use hardware overlay planes if they are available. */ + void set_overlay() {clear_flag(NO_OVERLAY);} + /** Tells FLTK to use normal drawing planes instead of overlay planes. + This is usually necessary if your menu contains multi-color pixmaps. */ + void clear_overlay() {set_flag(NO_OVERLAY);} + ~Fl_Menu_Window(); + /** Creates a new Fl_Menu_Window widget using the given size, and label string. */ + Fl_Menu_Window(int W, int H, const char *l = 0) + : Fl_Single_Window(W,H,l) { image(0); } + /** Creates a new Fl_Menu_Window widget using the given position, size, and label string. */ + Fl_Menu_Window(int X, int Y, int W, int H, const char *l = 0) + : Fl_Single_Window(X,Y,W,H,l) { image(0); } +}; + +#endif + +// +// End of "$Id: Fl_Menu_Window.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Multi_Browser.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Multi_Browser.H new file mode 100644 index 0000000..4a608b1 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Multi_Browser.H @@ -0,0 +1,62 @@ +// +// "$Id: Fl_Multi_Browser.H 7903 2010-11-28 21:06:39Z matt $" +// +// Multi browser header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Multi_Browser widget . */ + +#ifndef Fl_Multi_Browser_H +#define Fl_Multi_Browser_H + +#include "Fl_Browser.H" + +/** + The Fl_Multi_Browser class is a subclass of Fl_Browser + which lets the user select any set of the lines. The user interface + is Macintosh style: clicking an item turns off all the others and + selects that one, dragging selects all the items the mouse moves over, + and shift + click toggles the items. This is different then how forms + did it. Normally the callback is done when the user releases the + mouse, but you can change this with when(). +

See Fl_Browser for methods to add and remove lines from the browser. +*/ +class Fl_Multi_Browser : public Fl_Browser { +public: + /** + Creates a new Fl_Multi_Browser widget using the given + position, size, and label string. The default boxtype is FL_DOWN_BOX. + The constructor specializes Fl_Browser() by setting the type to FL_MULTI_BROWSER. + The destructor destroys the widget and frees all memory that has been allocated. + */ + Fl_Multi_Browser(int X,int Y,int W,int H,const char *L=0) + : Fl_Browser(X,Y,W,H,L) {type(FL_MULTI_BROWSER);} +}; + +#endif + +// +// End of "$Id: Fl_Multi_Browser.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Multi_Label.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Multi_Label.H new file mode 100644 index 0000000..0b160d1 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Multi_Label.H @@ -0,0 +1,47 @@ +// +// "$Id: Fl_Multi_Label.H 7903 2010-11-28 21:06:39Z matt $" +// +// Multi-label header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Multi_Label_H +#define Fl_Multi_Label_H + +class Fl_Widget; +struct Fl_Menu_Item; + +struct FL_EXPORT Fl_Multi_Label { + const char* labela; + const char* labelb; + uchar typea; + uchar typeb; + void label(Fl_Widget*); + void label(Fl_Menu_Item*); +}; + +#endif + +// +// End of "$Id: Fl_Multi_Label.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Multiline_Input.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Multiline_Input.H new file mode 100644 index 0000000..2c907bc --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Multiline_Input.H @@ -0,0 +1,65 @@ +// +// "$Id: Fl_Multiline_Input.H 7903 2010-11-28 21:06:39Z matt $" +// +// Multiline input header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Multiline_Input widget . */ + + +#ifndef Fl_Multiline_Input_H +#define Fl_Multiline_Input_H + +#include "Fl_Input.H" + +/** + This input field displays '\n' characters as new lines rather than ^J, + and accepts the Return, Tab, and up and down arrow keys. This is for + editing multiline text. + + This is far from the nirvana of text editors, and is probably only + good for small bits of text, 10 lines at most. Note that this widget + does not support scrollbars or per-character color control. + + If you are presenting large amounts of text and need scrollbars + or full color control of characters, you probably want Fl_Text_Editor + instead. +*/ +class Fl_Multiline_Input : public Fl_Input { +public: + /** + Creates a new Fl_Multiline_Input widget using the given + position, size, and label string. The default boxtype is FL_DOWN_BOX. +

Inherited destructor destroys the widget and any value associated with it. + */ + Fl_Multiline_Input(int X,int Y,int W,int H,const char *l = 0) + : Fl_Input(X,Y,W,H,l) {type(FL_MULTILINE_INPUT);} +}; + +#endif + +// +// End of "$Id: Fl_Multiline_Input.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Multiline_Output.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Multiline_Output.H new file mode 100644 index 0000000..1708a94 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Multiline_Output.H @@ -0,0 +1,64 @@ +// +// "$Id: Fl_Multiline_Output.H 7903 2010-11-28 21:06:39Z matt $" +// +// Multi line output header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Multiline_Output widget . */ + +#ifndef Fl_Multiline_Output_H +#define Fl_Multiline_Output_H + +#include "Fl_Output.H" + +/** + This widget is a subclass of Fl_Output that displays multiple + lines of text. It also displays tab characters as whitespace to the + next column. + + Note that this widget does not support scrollbars, or per-character + color control. + + If you are presenting large amounts of read-only text + and need scrollbars, or full color control of characters, + then use Fl_Text_Display. If you want to display HTML text, + use Fl_Help_View. +*/ +class Fl_Multiline_Output : public Fl_Output { +public: + /** + Creates a new Fl_Multiline_Output widget using the given + position, size, and label string. The default boxtype is FL_DOWN_BOX +

Inherited destructor destroys the widget and any value associated with it. + */ + Fl_Multiline_Output(int X,int Y,int W,int H,const char *l = 0) + : Fl_Output(X,Y,W,H,l) {type(FL_MULTILINE_OUTPUT);} +}; + +#endif + +// +// End of "$Id: Fl_Multiline_Output.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Native_File_Chooser.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Native_File_Chooser.H new file mode 100644 index 0000000..de88a29 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Native_File_Chooser.H @@ -0,0 +1,51 @@ +// +// "$Id: Fl_Native_File_Chooser.H 7903 2010-11-28 21:06:39Z matt $" +// +// FLTK native OS file chooser widget +// +// Copyright 1998-2010 by Bill Spitzak and others. +// Copyright 2004 Greg Ercolano. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef FL_NATIVE_FILE_CHOOSER_H +#define FL_NATIVE_FILE_CHOOSER_H + +// Use Windows' chooser +#ifdef WIN32 +#include +#endif + +// Use Apple's chooser +#ifdef __APPLE__ +#include +#endif + +// All else falls back to FLTK's own chooser +#if ! defined(__APPLE__) && !defined(WIN32) +#include +#endif + +#endif /*FL_NATIVE_FILE_CHOOSER_H*/ + +// +// End of "$Id: Fl_Native_File_Chooser.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Native_File_Chooser_FLTK.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Native_File_Chooser_FLTK.H new file mode 100644 index 0000000..8f1ae26 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Native_File_Chooser_FLTK.H @@ -0,0 +1,142 @@ +// +// "$Id: Fl_Native_File_Chooser_FLTK.H 7007 2010-01-14 23:08:06Z greg.ercolano $" +// +// FLTK native OS file chooser widget +// +// Copyright 1998-2009 by Bill Spitzak and others. +// Copyright 2005 by Nathan Vander Wilt. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Native_File_Chooser widget. */ + +#include +#include // _POSIX_NAME_MAX + +/** + This class lets an FLTK application easily and consistently access + the operating system's native file chooser. Some operating systems + have very complex and specific file choosers that many users want + access to specifically, instead of FLTK's default file chooser(s). +

+ In cases where there is no native file browser, FLTK's own file browser + is used instead. +

+ \code + // Create and post the local native file chooser + #include + [..] + Fl_Native_File_Chooser fnfc; + fnfc.title("Pick a file"); + fnfc.type(Fl_Native_File_Chooser::BROWSE_FILE); + fnfc.filter("Text\t*.txt\n" + "C Files\t*.{cxx,h,c}"); + fnfc.directory("/var/tmp"); + // Show native chooser + switch ( fnfc.show() ) { + case -1: printf("ERROR: %s\n", fnfc.errmsg()); break; // ERROR + case 1: printf("CANCEL\n"); break; // CANCEL + default: printf("PICKED: %s\n", fnfc.filename()); break; // FILE CHOSEN + } + \endcode +

+ Platform Specific Caveats +

+ - Under X windows, it's best if you call Fl_File_Icon::load_system_icons() + at the start of main(), to enable the nicer looking file browser widgets. + - Some operating systems support certain OS specific options; see + Fl_Native_File_Chooser::options() for a list. +*/ +class Fl_Native_File_Chooser { +public: + enum Type { + BROWSE_FILE = 0, ///< browse files (lets user choose one file) + BROWSE_DIRECTORY, ///< browse directories (lets user choose one directory) + BROWSE_MULTI_FILE, ///< browse files (lets user choose multiple files) + BROWSE_MULTI_DIRECTORY, ///< browse directories (lets user choose multiple directories) + BROWSE_SAVE_FILE, ///< browse to save a file + BROWSE_SAVE_DIRECTORY ///< browse to save a directory + }; + enum Option { + NO_OPTIONS = 0x0000, ///< no options enabled + SAVEAS_CONFIRM = 0x0001, ///< Show native 'Save As' overwrite confirm dialog (if supported) + NEW_FOLDER = 0x0002, ///< Show 'New Folder' icon (if supported) + PREVIEW = 0x0004, ///< enable preview mode + }; +private: + int _btype; // kind-of browser to show() + int _options; // general options + int _nfilters; + char *_filter; // user supplied filter + char *_parsedfilt; // parsed filter + int _filtvalue; // selected filter + char *_preset_file; + char *_prevvalue; // Returned filename + char *_directory; + char *_errmsg; // error message + char *_old_dir; + Fl_File_Chooser *_file_chooser; + + // added by MG + Fl_File_Browser *my_fileList; + Fl_Check_Button *show_hidden; + int prev_filtervalue; + static void show_hidden_cb(Fl_Check_Button *o, void *data); + static void remove_hidden_files(Fl_File_Browser *my_fileList); + + // Private methods + void errmsg(const char *msg); + int type_fl_file(int); + void parse_filter(); + void keeplocation(); + int exist_dialog(); + +public: + Fl_Native_File_Chooser(int val=BROWSE_FILE); + ~Fl_Native_File_Chooser(); + + // Public methods + void type(int); + int type() const; + void options(int); + int options() const; + int count() const; + const char *filename() const; + const char *filename(int i) const; + void directory(const char *val); + const char *directory() const; + void title(const char *); + const char* title() const; + const char *filter() const; + void filter(const char *); + int filters() const; + void filter_value(int i); + int filter_value() const; + void preset_file(const char*); + const char* preset_file() const; + const char *errmsg() const; + int show(); +}; + +// +// End of "$Id: Fl_Native_File_Chooser_FLTK.H 7007 2010-01-14 23:08:06Z greg.ercolano $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Native_File_Chooser_MAC.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Native_File_Chooser_MAC.H new file mode 100644 index 0000000..ebef7f8 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Native_File_Chooser_MAC.H @@ -0,0 +1,121 @@ +// +// "$Id: Fl_Native_File_Chooser_MAC.H 7788 2010-10-31 20:47:50Z matt $" +// +// FLTK native OS file chooser widget +// +// Copyright 1998-2009 by Bill Spitzak and others. +// Copyright 2004 Greg Ercolano. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef FL_DOXYGEN // PREVENT DOXYGEN'S USE OF THIS FILE + +// OSX-SPECIFIC NATIVE BROWSER +#include + +#undef check // necessary for use of Fl::check() + +#include +#define MAXFILTERS 80 + +class Fl_Native_File_Chooser { +public: + enum Type { + BROWSE_FILE = 0, + BROWSE_DIRECTORY, + BROWSE_MULTI_FILE, + BROWSE_MULTI_DIRECTORY, + BROWSE_SAVE_FILE, + BROWSE_SAVE_DIRECTORY + }; + enum Option { + NO_OPTIONS = 0x0000, // no options enabled + SAVEAS_CONFIRM = 0x0001, // Show native 'Save As' overwrite confirm dialog (if supported) + NEW_FOLDER = 0x0002, // Show 'New Folder' icon (if supported) + PREVIEW = 0x0004 // enable preview mode + }; +private: + int _btype; // kind-of browser to show() + int _options; // general options + void *_panel; + char **_pathnames; // array of pathnames + int _tpathnames; // total pathnames + char *_directory; // default pathname to use + char *_title; // title for window + char *_preset_file; // the 'save as' filename + + char *_filter; // user-side search filter, eg: + // C Files\t*.[ch]\nText Files\t*.txt" + + char *_filt_names; // filter names (tab delimited) + // eg. "C Files\tText Files" + + char *_filt_patt[MAXFILTERS]; + // array of filter patterns, eg: + // _filt_patt[0]="*.{cxx,h}" + // _filt_patt[1]="*.txt" + + int _filt_total; // parse_filter() # of filters loaded + int _filt_value; // index of the selected filter + char *_errmsg; // error message + + // Private methods + void errmsg(const char *msg); + void clear_pathnames(); + void set_single_pathname(const char *s); + int get_saveas_basename(void); + void clear_filters(); + void add_filter(const char *, const char *); + void parse_filter(const char *from); + int post(); + +public: + Fl_Native_File_Chooser(int val = BROWSE_FILE); + ~Fl_Native_File_Chooser(); + + // Public methods + void type(int); + int type() const; + void options(int); + int options() const; + int count() const; + const char *filename() const; + const char *filename(int i) const; + void directory(const char *); + const char *directory() const; + void title(const char *); + const char *title() const; + const char *filter() const; + void filter(const char *); + void filter_value(int i) { _filt_value = i; } + int filter_value() { return(_filt_value); } + int filters() { return(_filt_total); } + void preset_file(const char *); + const char *preset_file(); + const char *errmsg() const; + int show(); +}; + +#endif /*!FL_DOXYGEN*/ + +// +// End of "$Id: Fl_Native_File_Chooser_MAC.H 7788 2010-10-31 20:47:50Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Native_File_Chooser_WIN32.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Native_File_Chooser_WIN32.H new file mode 100644 index 0000000..d6aa53a --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Native_File_Chooser_WIN32.H @@ -0,0 +1,120 @@ +// +// "$Id: Fl_Native_File_Chooser_WIN32.H 7003 2010-01-14 20:47:59Z greg.ercolano $" +// +// FLTK native OS file chooser widget +// +// Copyright 1998-2005 by Bill Spitzak and others. +// Copyright 2004 by Greg Ercolano. +// April 2005 - API changes, improved filter processing by Nathan Vander Wilt +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems to: +// +// http://www.fltk.org/str.php +// + +#ifndef FL_DOXYGEN // PREVENT DOXYGEN'S USE OF THIS FILE + +// #define _WIN32_WINNT 0x0501 // needed for OPENFILENAME's 'FlagsEx' +#include +#include // malloc +#include +#include // OPENFILENAME, GetOpenFileName() +#include // BROWSEINFO, SHBrowseForFolder() + +class Fl_Native_File_Chooser { +public: + enum Type { + BROWSE_FILE = 0, + BROWSE_DIRECTORY, + BROWSE_MULTI_FILE, + BROWSE_MULTI_DIRECTORY, + BROWSE_SAVE_FILE, + BROWSE_SAVE_DIRECTORY + }; + enum Option { + NO_OPTIONS = 0x0000, // no options enabled + SAVEAS_CONFIRM = 0x0001, // Show native 'Save As' overwrite confirm dialog (if supported) + NEW_FOLDER = 0x0002, // Show 'New Folder' icon (if supported) + PREVIEW = 0x0004, // enable preview mode + }; +private: + int _btype; // kind-of browser to show() + int _options; // general options + OPENFILENAMEW _ofn; // GetOpenFileName() & GetSaveFileName() struct + BROWSEINFO _binf; // SHBrowseForFolder() struct + char **_pathnames; // array of pathnames + int _tpathnames; // total pathnames + char *_directory; // default pathname to use + char *_title; // title for window + char *_filter; // user-side search filter + char *_parsedfilt; // filter parsed for Windows dialog + int _nfilters; // number of filters parse_filter counted + char *_preset_file; // the file to preselect + char *_errmsg; // error message + + // Private methods + void errmsg(const char *msg); + + void clear_pathnames(); + void set_single_pathname(const char *s); + void add_pathname(const char *s); + + void FreePIDL(ITEMIDLIST *pidl); + void ClearOFN(); + void ClearBINF(); + void Win2Unix(char *s); + void Unix2Win(char *s); + int showfile(); + static int CALLBACK Dir_CB(HWND win, UINT msg, LPARAM param, LPARAM data); + int showdir(); + + void parse_filter(const char *); + void clear_filters(); + void add_filter(const char *, const char *); + +public: + Fl_Native_File_Chooser(int val = BROWSE_FILE); + ~Fl_Native_File_Chooser(); + + // Public methods + void type(int val); + int type() const; + void options(int); + int options() const; + int count() const; + const char *filename() const; + const char *filename(int i) const; + void directory(const char *val); + const char *directory() const; + void title(const char *val); + const char *title() const; + const char *filter() const; + void filter(const char *val); + int filters() const { return _nfilters; } + void filter_value(int i); + int filter_value() const; + void preset_file(const char *); + const char *preset_file() const; + const char *errmsg() const; + int show(); +}; +#endif /*!FL_DOXYGEN*/ + +// +// End of "$Id: Fl_Native_File_Chooser_WIN32.H 7003 2010-01-14 20:47:59Z greg.ercolano $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Nice_Slider.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Nice_Slider.H new file mode 100644 index 0000000..c1a731c --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Nice_Slider.H @@ -0,0 +1,46 @@ +// +// "$Id: Fl_Nice_Slider.H 7903 2010-11-28 21:06:39Z matt $" +// +// "Nice" slider header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Nice_Slider widget . */ + +#ifndef Fl_Nice_Slider_H +#define Fl_Nice_Slider_H + +#include "Fl_Slider.H" + +class Fl_Nice_Slider : public Fl_Slider { +public: + Fl_Nice_Slider(int x,int y,int w,int h,const char *l=0) + : Fl_Slider(x,y,w,h,l) {type(FL_VERT_NICE_SLIDER); box(FL_FLAT_BOX);} +}; + +#endif + +// +// End of "$Id: Fl_Nice_Slider.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Object.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Object.H new file mode 100644 index 0000000..c743999 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Object.H @@ -0,0 +1,36 @@ +// +// "$Id: Fl_Object.H 7903 2010-11-28 21:06:39Z matt $" +// +// Old Fl_Object header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// This file is provided for back compatibility only. Please use Fl_Widget +#ifndef Fl_Object +#define Fl_Object Fl_Widget +#endif +#include "Fl_Widget.H" + +// +// End of "$Id: Fl_Object.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Output.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Output.H new file mode 100644 index 0000000..4c08a9c --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Output.H @@ -0,0 +1,68 @@ +// +// "$Id: Fl_Output.H 7903 2010-11-28 21:06:39Z matt $" +// +// Output header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Output widget . */ + +#ifndef Fl_Output_H +#define Fl_Output_H + +#include "Fl_Input.H" +/** + This widget displays a piece of text. When you set the value() + , Fl_Output does a strcpy() to it's own storage, + which is useful for program-generated values. The user may select + portions of the text using the mouse and paste the contents into other + fields or programs. +

\image html text.gif

+ \image latex text.eps "Fl_Output" width=8cm +

There is a single subclass, + Fl_Multiline_Output, which allows you to display multiple lines of + text. Fl_Multiline_Output does not provide scroll bars. If a more + complete text editing widget is needed, use Fl_Text_Display instead.

+

The text may contain any characters except \\0, and will correctly + display anything, using ^X notation for unprintable control characters + and \\nnn notation for unprintable characters with the high bit set. It + assumes the font can draw any characters in the ISO-Latin1 character + set. +*/ +class Fl_Output : public Fl_Input { +public: + /** + Creates a new Fl_Output widget using the given position, + size, and label string. The default boxtype is FL_DOWN_BOX. +

Inherited destrucor destroys the widget and any value associated with it. + */ + Fl_Output(int X,int Y,int W,int H, const char *l = 0) + : Fl_Input(X, Y, W, H, l) {type(FL_NORMAL_OUTPUT);} +}; + +#endif + +// +// End of "$Id: Fl_Output.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Overlay_Window.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Overlay_Window.H new file mode 100644 index 0000000..918b671 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Overlay_Window.H @@ -0,0 +1,79 @@ +// +// "$Id: Fl_Overlay_Window.H 7903 2010-11-28 21:06:39Z matt $" +// +// Overlay window header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Overlay_Window class . */ + +#ifndef Fl_Overlay_Window_H +#define Fl_Overlay_Window_H + +#include "Fl_Double_Window.H" + +/** + This window provides double buffering and also the ability to draw the + "overlay" which is another picture placed on top of the main image. The + overlay is designed to be a rapidly-changing but simple graphic such as + a mouse selection box. Fl_Overlay_Window uses the overlay + planes provided by your graphics hardware if they are available. +

If no hardware support is found the overlay is simulated by drawing + directly into the on-screen copy of the double-buffered window, and + "erased" by copying the backbuffer over it again. This means the + overlay will blink if you change the image in the window. +*/ +class FL_EXPORT Fl_Overlay_Window : public Fl_Double_Window { + friend class _Fl_Overlay; + virtual void draw_overlay() = 0; + Fl_Window *overlay_; +public: + void show(); + void flush(); + void hide(); + void resize(int,int,int,int); + ~Fl_Overlay_Window(); + int can_do_overlay(); + void redraw_overlay(); + /** + Creates a new Fl_Overlay_Window widget using the given + position, size, and label (title) string. If the + positions (x,y) are not given, then the window manager + will choose them. + */ + Fl_Overlay_Window(int W, int H, const char *l=0) + : Fl_Double_Window(W,H,l) {overlay_ = 0; force_doublebuffering_=1; image(0); } + /** + See Fl_Overlay_Window::Fl_Overlay_Window(int W, int H, const char *l=0) + */ + Fl_Overlay_Window(int X, int Y, int W, int H, const char *l=0) + : Fl_Double_Window(X,Y,W,H,l) {overlay_ = 0; force_doublebuffering_=1; image(0); } + void show(int a, char **b) {Fl_Double_Window::show(a,b);} +}; + +#endif + +// +// End of "$Id: Fl_Overlay_Window.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_PNG_Image.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_PNG_Image.H new file mode 100644 index 0000000..733b3a0 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_PNG_Image.H @@ -0,0 +1,52 @@ +// +// "$Id: Fl_PNG_Image.H 7903 2010-11-28 21:06:39Z matt $" +// +// PNG image header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_PNG_Image class . */ + +#ifndef Fl_PNG_Image_H +#define Fl_PNG_Image_H +# include "Fl_Image.H" + +/** + The Fl_PNG_Image class supports loading, caching, + and drawing of Portable Network Graphics (PNG) image files. The + class loads colormapped and full-color images and handles color- + and alpha-based transparency. +*/ +class FL_EXPORT Fl_PNG_Image : public Fl_RGB_Image { + + public: + + Fl_PNG_Image(const char* filename); +}; + +#endif + +// +// End of "$Id: Fl_PNG_Image.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_PNM_Image.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_PNM_Image.H new file mode 100644 index 0000000..739fc07 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_PNM_Image.H @@ -0,0 +1,52 @@ +// +// "$Id: Fl_PNM_Image.H 7903 2010-11-28 21:06:39Z matt $" +// +// PNM image header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_PNM_Image class . */ + +#ifndef Fl_PNM_Image_H +#define Fl_PNM_Image_H +# include "Fl_Image.H" + +/** + The Fl_PNM_Image class supports loading, caching, + and drawing of Portable Anymap (PNM, PBM, PGM, PPM) image files. The class + loads bitmap, grayscale, and full-color images in both ASCII and + binary formats. +*/ +class FL_EXPORT Fl_PNM_Image : public Fl_RGB_Image { + + public: + + Fl_PNM_Image(const char* filename); +}; + +#endif + +// +// End of "$Id: Fl_PNM_Image.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Pack.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Pack.H new file mode 100644 index 0000000..4ff3ae4 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Pack.H @@ -0,0 +1,84 @@ +// +// "$Id: Fl_Pack.H 7903 2010-11-28 21:06:39Z matt $" +// +// Pack header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Pack widget . */ + +#ifndef Fl_Pack_H +#define Fl_Pack_H + +#include + +/** + This widget was designed to add the functionality of compressing and + aligning widgets. +

If type() is Fl_Pack::HORIZONTAL all the children are + resized to the height of the Fl_Pack, and are moved next to + each other horizontally. If type() is not Fl_Pack::HORIZONTAL + then the children are resized to the width and are stacked below each + other. Then the Fl_Pack resizes itself to surround the child + widgets. +

This widget is needed for the Fl_Tabs. + In addition you may want to put the Fl_Pack inside an + Fl_Scroll. + +

The resizable for Fl_Pack is set to NULL by default.

+

See also: Fl_Group::resizable() +*/ +class FL_EXPORT Fl_Pack : public Fl_Group { + int spacing_; + +public: + enum { // values for type(int) + VERTICAL = 0, + HORIZONTAL = 1 + }; + +protected: + void draw(); + +public: + Fl_Pack(int x,int y,int w ,int h,const char *l = 0); + /** + Gets the number of extra pixels of blank space that are added + between the children. + */ + int spacing() const {return spacing_;} + /** + Sets the number of extra pixels of blank space that are added + between the children. + */ + void spacing(int i) {spacing_ = i;} + /** Same as Fl_Group::type() */ + uchar horizontal() const {return type();} +}; + +#endif + +// +// End of "$Id: Fl_Pack.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Paged_Device.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Paged_Device.H new file mode 100644 index 0000000..345a4ba --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Paged_Device.H @@ -0,0 +1,92 @@ +// +// "$Id: Fl_Paged_Device.H 7622 2010-05-27 17:50:51Z manolo $" +// +// Printing support for the Fast Light Tool Kit (FLTK). +// +// Copyright 2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/** \file Fl_Paged_Device.H + \brief declaration of class Fl_Paged_Device. + */ + +#ifndef Fl_Paged_Device_H +#define Fl_Paged_Device_H + +#include + +/** + \brief Represents page-structured drawing surfaces. + * + This class has no public constructor: don't instantiate it; use Fl_Printer + or Fl_PostScript_File_Device instead. + */ +class Fl_Paged_Device : public Fl_Surface_Device { +private: +#ifdef __APPLE__ + struct chain_elt { + Fl_Image *image; + const uchar *data; + struct chain_elt *next; + }; + void add_image(Fl_Image *image, const uchar *data); // adds an image to the page image list +#endif + void traverse(Fl_Widget *widget); // finds subwindows of widget and prints them +protected: + /** \brief horizontal offset to the origin of graphics coordinates */ + int x_offset; + /** \brief vertical offset to the origin of graphics coordinates */ + int y_offset; + /** \brief chained list of Fl_Image's used in this page */ + struct chain_elt *image_list_; +#ifdef __APPLE__ + /** \brief deletes the page image list */ + void delete_image_list(); +#endif + /** \brief The constructor */ + Fl_Paged_Device() : Fl_Surface_Device(NULL) {type_ = device_type;}; + /** \brief The destructor */ + virtual ~Fl_Paged_Device() {}; +public: + static const char *device_type; + virtual int start_job(int pagecount, int *frompage = NULL, int *topage = NULL); + virtual int start_page(void); + virtual int printable_rect(int *w, int *h); + virtual void margins(int *left, int *top, int *right, int *bottom); + virtual void origin(int x, int y); + void origin(int *x, int *y); + virtual void scale(float scale_x, float scale_y); + virtual void rotate(float angle); + virtual void translate(int x, int y); + virtual void untranslate(void); + void print_widget(Fl_Widget* widget, int delta_x = 0, int delta_y = 0); + void print_window_part(Fl_Window *win, int x, int y, int w, int h, int delta_x = 0, int delta_y = 0); + virtual int end_page (void); + virtual void end_job (void); +}; + +#endif // Fl_Paged_Device_H + +// +// End of "$Id: Fl_Paged_Device.H 7622 2010-05-27 17:50:51Z manolo $" +// + diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Pixmap.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Pixmap.H new file mode 100644 index 0000000..bc6438b --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Pixmap.H @@ -0,0 +1,99 @@ +// +// "$Id: Fl_Pixmap.H 7903 2010-11-28 21:06:39Z matt $" +// +// Pixmap header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Pixmap widget . */ + +#ifndef Fl_Pixmap_H +#define Fl_Pixmap_H +# include "Fl_Image.H" + +class Fl_Widget; +struct Fl_Menu_Item; + +// Older C++ compilers don't support the explicit keyword... :( +# if defined(__sgi) && !defined(_COMPILER_VERSION) +# define explicit +# endif // __sgi && !_COMPILER_VERSION + +/** + The Fl_Pixmap class supports caching and drawing of colormap + (pixmap) images, including transparency. +*/ +class FL_EXPORT Fl_Pixmap : public Fl_Image { + friend class Fl_Quartz_Graphics_Driver; + friend class Fl_GDI_Graphics_Driver; + friend class Fl_Xlib_Graphics_Driver; + void copy_data(); + void delete_data(); + void set_data(const char * const *p); + + protected: + + void measure(); + + public: + + int alloc_data; // Non-zero if data was allocated + + private: + +#if defined(__APPLE__) || defined(WIN32) + void *id_; // for internal use + void *mask_; // for internal use (mask bitmap) +#else + unsigned id_; // for internal use + unsigned mask_; // for internal use (mask bitmap) +#endif // __APPLE__ || WIN32 + + public: + + /** The constructors create a new pixmap from the specified XPM data. */ + explicit Fl_Pixmap(char * const * D) : Fl_Image(-1,0,1), alloc_data(0), id_(0), mask_(0) {set_data((const char*const*)D); measure();} + /** The constructors create a new pixmap from the specified XPM data. */ + explicit Fl_Pixmap(uchar* const * D) : Fl_Image(-1,0,1), alloc_data(0), id_(0), mask_(0) {set_data((const char*const*)D); measure();} + /** The constructors create a new pixmap from the specified XPM data. */ + explicit Fl_Pixmap(const char * const * D) : Fl_Image(-1,0,1), alloc_data(0), id_(0), mask_(0) {set_data((const char*const*)D); measure();} + /** The constructors create a new pixmap from the specified XPM data. */ + explicit Fl_Pixmap(const uchar* const * D) : Fl_Image(-1,0,1), alloc_data(0), id_(0), mask_(0) {set_data((const char*const*)D); measure();} + virtual ~Fl_Pixmap(); + virtual Fl_Image *copy(int W, int H); + Fl_Image *copy() { return copy(w(), h()); } + virtual void color_average(Fl_Color c, float i); + virtual void desaturate(); + virtual void draw(int X, int Y, int W, int H, int cx=0, int cy=0); + void draw(int X, int Y) {draw(X, Y, w(), h(), 0, 0);} + virtual void label(Fl_Widget*w); + virtual void label(Fl_Menu_Item*m); + virtual void uncache(); +}; + +#endif + +// +// End of "$Id: Fl_Pixmap.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Plugin.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Plugin.H new file mode 100644 index 0000000..231a802 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Plugin.H @@ -0,0 +1,106 @@ +// +// "$Id: Fl_Plugin.H 6995 2010-01-12 08:48:55Z matt $" +// +// A Plugin system for FLTK, implemented in Fl_Preferences.cxx. +// +// Copyright 2002-2010 by Matthias Melcher. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Plugin class . */ + +#ifndef Fl_Plugin_H +# define Fl_Plugin_H + +# include "Fl_Preferences.H" + + +/** + \brief Fl_Plugin allows link-time and run-time integration of binary modules. + + Fl_Plugin and Fl_Plugin_Manager provide a small and simple solution for + linking C++ classes at run-time, or optionally linking modules at compile + time without the need to change the main application. + + Fl_Plugin_Manager uses static initialisation to create the plugin interface + early during startup. Plugins are stored in a temporary database, organized + in classes. + + Plugins should derive a new class from Fl_Plugin as a base: + \code + class My_Plugin : public Fl_Plugin { + public: + My_Plugin() : Fl_Plugin("effects", "blur") { } + void do_something(...); + }; + My_Plugin blur_plugin(); + \endcode + + Plugins can be put into modules and either linked befor distribution, or loaded + from dynamically linkable files. An Fl_Plugin_Manager is used to list and + access all currently loaded plugins. + \code + Fl_Plugin_Manager mgr("effects"); + int i, n = mgr.plugins(); + for (i=0; ido_something(); + } + \endcode + */ +class FL_EXPORT Fl_Plugin +{ + Fl_Preferences::ID id; +public: + Fl_Plugin(const char *klass, const char *name); + virtual ~Fl_Plugin(); +}; + + +/** + \brief Fl_Plugin_Manager manages link-time and run-time plugin binaries. + \see Fl_Plugin + */ +class FL_EXPORT Fl_Plugin_Manager : public Fl_Preferences +{ +public: + Fl_Plugin_Manager(const char *klass); + ~Fl_Plugin_Manager(); + + /** \brief Return the number of plugins in the klass. + */ + int plugins() { return groups(); } + Fl_Plugin *plugin(int index); + Fl_Plugin *plugin(const char *name); + Fl_Preferences::ID addPlugin(const char *name, Fl_Plugin *plugin); + + static void removePlugin(Fl_Preferences::ID id); + static int load(const char *filename); + static int loadAll(const char *filepath, const char *pattern=0); +}; + + +#endif // !Fl_Preferences_H + +// +// End of "$Id: Fl_Preferences.H 6995 2010-01-12 08:48:55Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Positioner.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Positioner.H new file mode 100644 index 0000000..8c4af4a --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Positioner.H @@ -0,0 +1,103 @@ +// +// "$Id: Fl_Positioner.H 7903 2010-11-28 21:06:39Z matt $" +// +// Positioner header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Positioner widget . */ + +#ifndef Fl_Positioner_H +#define Fl_Positioner_H + +#ifndef Fl_Widget_H +#include "Fl_Widget.H" +#endif + +/** + This class is provided for Forms compatibility. It provides 2D input. + It would be useful if this could be put atop another widget so that the + crosshairs are on top, but this is not implemented. The color of the + crosshairs is selection_color(). +

\image html positioner.gif

+ \image latex positioner.eps " Fl_Positioner" width=4cm +*/ +class FL_EXPORT Fl_Positioner : public Fl_Widget { + + double xmin, ymin; + double xmax, ymax; + double xvalue_, yvalue_; + double xstep_, ystep_; + +protected: + + // these allow subclasses to put the dial in a smaller area: + void draw(int, int, int, int); + int handle(int, int, int, int, int); + void draw(); + +public: + + int handle(int); + /** + Creates a new Fl_Positioner widget using the given position, + size, and label string. The default boxtype is FL_NO_BOX. + */ + Fl_Positioner(int x,int y,int w,int h, const char *l=0); + /** Gets the X axis coordinate.*/ + double xvalue() const {return xvalue_;} + /** Gets the Y axis coordinate.*/ + double yvalue() const {return yvalue_;} + int xvalue(double); + int yvalue(double); + int value(double,double); + void xbounds(double, double); + /** Gets the X axis minimum */ + double xminimum() const {return xmin;} + /** Same as xbounds(a, xmaximum()) */ + void xminimum(double a) {xbounds(a,xmax);} + /** Gets the X axis maximum */ + double xmaximum() const {return xmax;} + /** Same as xbounds(xminimum(), a) */ + void xmaximum(double a) {xbounds(xmin,a);} + void ybounds(double, double); + /** Gets the Y axis minimum */ + double yminimum() const {return ymin;} + /** Same as ybounds(a, ymaximum()) */ + void yminimum(double a) {ybounds(a, ymax);} + /** Gets the Y axis maximum */ + double ymaximum() const {return ymax;} + /** Same as ybounds(ymininimum(), a) */ + void ymaximum(double a) {ybounds(ymin, a);} + /** Sets the stepping value for the X axis.*/ + void xstep(double a) {xstep_ = a;} + /** Sets the stepping value for the Y axis.*/ + void ystep(double a) {ystep_ = a;} +}; + +#endif + +// +// End of "$Id: Fl_Positioner.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_PostScript.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_PostScript.H new file mode 100644 index 0000000..ae285e7 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_PostScript.H @@ -0,0 +1,308 @@ +// +// "$Id: Fl_PostScript.H 7719 2010-10-12 09:25:37Z manolo $" +// +// Support for graphics output to PostScript file for the Fast Light Tool Kit (FLTK). +// +// Copyright 2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// +/** \file Fl_PostScript.H + \brief declaration of classes Fl_PostScript_Graphics_Driver, Fl_PostScript_File_Device. + */ + + +#ifndef Fl_PostScript_H +#define Fl_PostScript_H + +#include +#include + +#define NO_PAGE_FORMATS 30 /* MSVC6 compilation fix */ + +/** + \brief PostScript graphical backend. + * + PostScript text uses vectorial fonts for the latin alphabet (exactly: all unicode + characters between U+0020 and U+017F, that is, ASCII, Latin-1 Supplement and Latin Extended-A charts) + plus a few other characters: + + + + + + + + + + + + + + + +
CharCodepointName CharCodepointName CharCodepointName
ƒU+0192florinΓ’Β€ΒšU+201Aquotesinglbase҄’U+2122trademark
ˆU+02C6circumflexΓ’Β€ΒœU+201CquotedblleftΓ’ΒˆΒ‚U+2202partialdiff
ˇU+02C7caronҀU+201DquotedblrightΓŽΒ”U+2206Delta
Γ‹Β˜U+02D8breveΓ’Β€ΒžU+201EquotedblbaseΓ’ΒˆΒ‘U+2211summation
˙U+02D9dotaccentҀ U+2020dagger҈šU+221Aradical
Γ‹ΒšU+02DAringҀ‘U+2021daggerdbl҈žU+221Einfinity
˛U+02DBogonekҀ’U+2022bullet҉ U+2260notequal
Γ‹ΒœU+02DCtildeҀ¦U+2026ellipsis҉€U+2264lessequal
˝U+02DDhungarumlautҀ°U+2030perthousandΓ’Β‰Β₯U+2265greaterequal
Ҁ“U+2013endashҀ¹U+2039guilsinglleftΓ’Β—ΒŠU+25CAlozenge
Ҁ”U+2014emdashҀºU+203AguilsinglrightfiU+FB01fi
Γ’Β€Β˜U+2018quoteleft/U+2044fractionflU+FB02fl
Ҁ™U+2019quoteright҂¬U+20ACEuroU+F8FFapple (Mac OS only)
+
All other unicode characters are output as a bitmap. +
FLTK standard fonts are output using PostScript standard fonts: Helvetica, Courier, + Times (and their bold, oblique, italic variants). + */ +class Fl_PostScript_Graphics_Driver : public Fl_Graphics_Driver { +public: + static const char *device_type; + /** + \brief Possible page formats. + */ + enum Page_Format { + A0 = 0, + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + B0, + B1, + B2, + B3, + B4, + B5, + B6, + B7, + B8, + B9, + B10, + C5E, + DLE, + EXECUTIVE, + FOLIO, + LEDGER, + LEGAL, + LETTER, + TABLOID, + ENVELOPE, + MEDIA = 0x1000 + }; + + /** + \brief Possible page layouts. + */ + enum Page_Layout {PORTRAIT = 0, LANDSCAPE = 0x100, REVERSED = 0x200, ORIENTATION = 0x300}; + +#ifndef FL_DOXYGEN +public: + enum SHAPE{NONE=0, LINE, LOOP, POLYGON, POINTS}; + +typedef struct page_format { + int width; + int height; + const char *name; +} page_format; + +class Clip { + public: + int x, y, w, h; + Clip *prev; + }; + Clip * clip_; + + int lang_level_; + int font_; + int size_; + int gap_; + int pages_; + + double width_; + double height_; + + int shape_; + int linewidth_;// need for clipping, lang level 1-2 + int linestyle_;// + int interpolate_; //interpolation of images + unsigned char cr_,cg_,cb_; + char linedash_[256];//should be enough + void concat(); // transform ror scalable dradings... + void reconcat(); //invert + void recover(); //recovers the state after grestore (such as line styles...) + void reset(); + + uchar * mask; + int mx; // width of mask; + int my; // mask lines + //Fl_Color bg_; + int (*close_cmd_)(FILE *); + int page_policy_; + int nPages; + int orientation_; + + float scale_x; + float scale_y; + float angle; + int left_margin; + int top_margin; + + FILE *output; + double pw_, ph_; + static const page_format page_formats[NO_PAGE_FORMATS]; + + uchar bg_r, bg_g, bg_b; + int start_postscript (int pagecount, enum Page_Format format, enum Page_Layout layout); + /* int alpha_mask(const uchar * data, int w, int h, int D, int LD=0); + */ + void draw(const char* s, int n, int x, int y) {transformed_draw(s,n,x,y); }; + void draw(int angle, const char *str, int n, int x, int y); + void transformed_draw(const char* s, int n, double x, double y); //precise text placing + void transformed_draw(const char* s, double x, double y); + int alpha_mask(const uchar * data, int w, int h, int D, int LD=0); + void draw_scaled_image(const uchar *data, double x, double y, double w, double h, int iw, int ih, int D=3, int LD=0); + void draw_scaled_image_mono(const uchar *data, double x, double y, double w, double h, int iw, int ih, int D=3, int LD=0); + void draw_scaled_image(Fl_Draw_Image_Cb call, void *data, double x, double y, double w, double h, int iw, int ih, int D); + void draw_scaled_image_mono(Fl_Draw_Image_Cb call, void *data, double x, double y, double w, double h, int iw, int ih, int D); + + enum Page_Format page_format_; + char *ps_filename_; + // implementation of drawing methods + void color(Fl_Color c); + void color(uchar r, uchar g, uchar b); + + void push_clip(int x, int y, int w, int h); + int clip_box(int x, int y, int w, int h, int &X, int &Y, int &W, int &H); + int not_clipped(int x, int y, int w, int h); + void push_no_clip(); + void pop_clip(); + + void line_style(int style, int width=0, char* dashes=0); + + void rect(int x, int y, int w, int h); + void rectf(int x, int y, int w, int h); + + void xyline(int x, int y, int x1); + void xyline(int x, int y, int x1, int y2); + void xyline(int x, int y, int x1, int y2, int x3); + + void yxline(int x, int y, int y1); + void yxline(int x, int y, int y1, int x2); + void yxline(int x, int y, int y1, int x2, int y3); + + void line(int x1, int y1, int x2, int y2); + void line(int x1, int y1, int x2, int y2, int x3, int y3); + + void loop(int x0, int y0, int x1, int y1, int x2, int y2); + void loop(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3); + void polygon(int x0, int y0, int x1, int y1, int x2, int y2); + void polygon(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3); + void point(int x, int y); + + void begin_points(); + void begin_line(); + void begin_loop(); + void begin_polygon(); + void vertex(double x, double y); + void curve(double x, double y, double x1, double y1, double x2, double y2, double x3, double y3); + void circle(double x, double y, double r); + void arc(double x, double y, double r, double start, double a); + void arc(int x, int y, int w, int h, double a1, double a2); + void pie(int x, int y, int w, int h, double a1, double a2); + void end_points(); + void end_line(); + void end_loop(); + void end_polygon(); + void begin_complex_polygon(){begin_polygon();}; + void gap(){gap_=1;}; + void end_complex_polygon(){end_polygon();}; + void transformed_vertex(double x, double y); + + void font(int face, int size); + int font(){return font_;}; + int size(){return size_;}; + double width(unsigned c); + double width(const char* s, int n); + int descent(); + int height(); + + void draw_image(const uchar* d, int x,int y,int w,int h, int delta=3, int ldelta=0){draw_scaled_image(d,x,y,w,h,w,h,delta,ldelta);}; + void draw_image_mono(const uchar* d, int x,int y,int w,int h, int delta=1, int ld=0){draw_scaled_image_mono(d,x,y,w,h,w,h,delta,ld);}; + void draw_image(Fl_Draw_Image_Cb call, void* data, int x,int y, int w, int h, int delta=3){draw_scaled_image(call,data, x, y, w, h, w, h, delta);}; + void draw_image_mono(Fl_Draw_Image_Cb call, void* data, int x,int y, int w, int h, int delta=1){draw_scaled_image_mono(call, data, x, y, w, h, w, h, delta);}; + +public: + void page_policy(int p); + int page_policy(){return page_policy_;}; + void close_command( int (*cmd)(FILE *)){close_cmd_=cmd;}; + FILE * file() {return output;}; + //void orientation (int o); + //Fl_PostScript_Graphics_Driver(FILE *o, int lang_level, int pages = 0); // ps (also multi-page) constructor + //Fl_PostScript_Graphics_Driver(FILE *o, int lang_level, int x, int y, int w, int h); //eps constructor + void interpolate(int i){interpolate_=i;}; + int interpolate(){return interpolate_;} + + void page(double pw, double ph, int media = 0); + void page(int format); + + void place(double x, double y, double tx, double ty, double scale = 1); +#endif // FL_DOXYGEN + Fl_PostScript_Graphics_Driver(); + void draw(Fl_Pixmap * pxm,int XP, int YP, int WP, int HP, int cx, int cy); + void draw(Fl_Bitmap * bitmap,int XP, int YP, int WP, int HP, int cx, int cy); + void draw(Fl_RGB_Image * rgb,int XP, int YP, int WP, int HP, int cx, int cy); + ~Fl_PostScript_Graphics_Driver(); +}; + +/** + \brief To send graphical output to a PostScript file. + */ +class Fl_PostScript_File_Device : public Fl_Paged_Device { +#ifdef __APPLE__ + CGContextRef gc; +#endif +protected: + Fl_PostScript_Graphics_Driver *driver(); +public: + static const char *device_type; + Fl_PostScript_File_Device(); + ~Fl_PostScript_File_Device(); + int start_job(int pagecount, enum Fl_PostScript_Graphics_Driver::Page_Format format = Fl_PostScript_Graphics_Driver::A4, + enum Fl_PostScript_Graphics_Driver::Page_Layout layout = Fl_PostScript_Graphics_Driver::PORTRAIT); + int start_job(FILE *ps_output, int pagecount, enum Fl_PostScript_Graphics_Driver::Page_Format format = Fl_PostScript_Graphics_Driver::A4, + enum Fl_PostScript_Graphics_Driver::Page_Layout layout = Fl_PostScript_Graphics_Driver::PORTRAIT); + int start_page (void); + int printable_rect(int *w, int *h); + void margins(int *left, int *top, int *right, int *bottom); + void origin(int x, int y); + void scale (float scale_x, float scale_y); + void rotate(float angle); + void translate(int x, int y); + void untranslate(void); + int end_page (void); + void end_job(void); +#ifdef __APPLE__ + void set_current() { fl_gc = gc; Fl_Paged_Device::set_current(); } +#endif + + static const char *file_chooser_title; +}; + +#endif // Fl_PostScript_H + +// +// End of "$Id: Fl_PostScript.H 7719 2010-10-12 09:25:37Z manolo $" +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Preferences.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Preferences.H new file mode 100644 index 0000000..aa74c8a --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Preferences.H @@ -0,0 +1,285 @@ +// +// "$Id: Fl_Preferences.H 7903 2010-11-28 21:06:39Z matt $" +// +// Preferences . +// +// Copyright 2002-2010 by Matthias Melcher. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Preferences class . */ + +#ifndef Fl_Preferences_H +# define Fl_Preferences_H + +# include +# include "Fl_Export.H" + + +/** + \brief Fl_Preferences provides methods to store user + settings between application starts. + + It is similar to the + Registry on WIN32 and Preferences on MacOS, and provides a + simple configuration mechanism for UNIX. + + Fl_Preferences uses a hierarchy to store data. It + bundles similar data into groups and manages entries into those + groups as name/value pairs. + + Preferences are stored in text files that can be edited + manually. The file format is easy to read and relatively + forgiving. Preferences files are the same on all platforms. User + comments in preference files are preserved. Filenames are unique + for each application by using a vendor/application naming + scheme. The user must provide default values for all entries to + ensure proper operation should preferences be corrupted or not + yet exist. + + Entries can be of any length. However, the size of each + preferences file should be kept small for performance + reasons. One application can have multiple preferences files. + Extensive binary data however should be stored in separate + files: see getUserdataPath(). + + \note Starting with FLTK 1.3, preference databases are expected to + be in utf8 encoding. Previous databases were stored in the + current chracter set or code page which renders them incompatible + for text entries using international characters. + */ +class FL_EXPORT Fl_Preferences +{ + +public: + + /** + Define the scope of the preferences. + */ + enum Root { + SYSTEM=0, ///< Preferences are used system-wide + USER ///< Preferences apply only to the current user + }; + + /** + Every Fl_Preferences-Group has a uniqe ID. + + ID's can be retrieved from an Fl_Preferences-Group and can then be used + to create more Fl_Preference references to the same data set, as long as the + database remains open. + */ + typedef void *ID; + + static const char *newUUID(); + + Fl_Preferences( Root root, const char *vendor, const char *application ); + Fl_Preferences( const char *path, const char *vendor, const char *application ); + Fl_Preferences( Fl_Preferences &parent, const char *group ); + Fl_Preferences( Fl_Preferences *parent, const char *group ); + Fl_Preferences( Fl_Preferences &parent, int groupIndex ); + Fl_Preferences( Fl_Preferences *parent, int groupIndex ); + Fl_Preferences(const Fl_Preferences&); + Fl_Preferences( ID id ); + virtual ~Fl_Preferences(); + + /** Return an ID that can later be reused to open more references to this dataset. + */ + ID id() { return (ID)node; } + + /** Remove the group with this ID from a database. + */ + static char remove(ID id_) { return ((Node*)id_)->remove(); } + + /** Return the name of this entry. + */ + const char *name() { return node->name(); } + + /** Return the the full path to this entry. + */ + const char *path() { return node->path(); } + + int groups(); + const char *group( int num_group ); + char groupExists( const char *key ); + char deleteGroup( const char *group ); + char deleteAllGroups(); + + int entries(); + const char *entry( int index ); + char entryExists( const char *key ); + char deleteEntry( const char *entry ); + char deleteAllEntries(); + + char clear(); + + char set( const char *entry, int value ); + char set( const char *entry, float value ); + char set( const char *entry, float value, int precision ); + char set( const char *entry, double value ); + char set( const char *entry, double value, int precision ); + char set( const char *entry, const char *value ); + char set( const char *entry, const void *value, int size ); + + char get( const char *entry, int &value, int defaultValue ); + char get( const char *entry, float &value, float defaultValue ); + char get( const char *entry, double &value, double defaultValue ); + char get( const char *entry, char *&value, const char *defaultValue ); + char get( const char *entry, char *value, const char *defaultValue, int maxSize ); + char get( const char *entry, void *&value, const void *defaultValue, int defaultSize ); + char get( const char *entry, void *value, const void *defaultValue, int defaultSize, int maxSize ); + + int size( const char *entry ); + + char getUserdataPath( char *path, int pathlen ); + + void flush(); + + // char export( const char *filename, Type fileFormat ); + // char import( const char *filename ); + + /** + 'Name' provides a simple method to create numerical or more complex + procedural names for entries and groups on the fly. + + Example: prefs.set(Fl_Preferences::Name("File%d",i),file[i]);. + + See test/preferences.cxx as a sample for writing arrays into preferences.

+ 'Name' is actually implemented as a class inside Fl_Preferences. It casts + into const char* and gets automatically destroyed after the enclosing call + ends. + */ + class FL_EXPORT Name { + + char *data_; + + public: + + Name( unsigned int n ); + Name( const char *format, ... ); + + /** + Return the Name as a "C" string. + \internal + */ + operator const char *() { return data_; } + ~Name(); + }; + + /** \internal An entry associates a preference name to its corresponding value */ + struct Entry + { + char *name, *value; + }; + +private: + + Fl_Preferences() : node(0), rootNode(0) { } + Fl_Preferences &operator=(const Fl_Preferences&); + + static char nameBuffer[128]; + static char uuidBuffer[40]; + static Fl_Preferences *runtimePrefs; + + class RootNode; + + class FL_EXPORT Node // a node contains a list to all its entries + { // and all means to manage the tree structure + Node *child_, *next_; + union { // these two are mutually exclusive + Node *parent_; // top_ bit clear + RootNode *root_; // top_ bit set + }; + char *path_; + Entry *entry_; + int nEntry_, NEntry_; + unsigned char dirty_:1; + unsigned char top_:1; + unsigned char indexed_:1; + // indexing routines + Node **index_; + int nIndex_, NIndex_; + void createIndex(); + void updateIndex(); + void deleteIndex(); + public: + static int lastEntrySet; + public: + Node( const char *path ); + ~Node(); + // node methods + int write( FILE *f ); + const char *name(); + const char *path() { return path_; } + Node *find( const char *path ); + Node *search( const char *path, int offset=0 ); + Node *childNode( int ix ); + Node *addChild( const char *path ); + void setParent( Node *parent ); + Node *parent() { return top_?0L:parent_; } + void setRoot(RootNode *r) { root_ = r; top_ = 1; } + RootNode *findRoot(); + char remove(); + char dirty(); + void deleteAllChildren(); + // entry methods + int nChildren(); + const char *child( int ix ); + void set( const char *name, const char *value ); + void set( const char *line ); + void add( const char *line ); + const char *get( const char *name ); + int getEntry( const char *name ); + char deleteEntry( const char *name ); + void deleteAllEntries(); + int nEntry() { return nEntry_; } + Entry &entry(int i) { return entry_[i]; } + }; + friend class Node; + + class FL_EXPORT RootNode // the root node manages file paths and basic reading and writing + { + Fl_Preferences *prefs_; + char *filename_; + char *vendor_, *application_; + public: + RootNode( Fl_Preferences *, Root root, const char *vendor, const char *application ); + RootNode( Fl_Preferences *, const char *path, const char *vendor, const char *application ); + RootNode( Fl_Preferences * ); + ~RootNode(); + int read(); + int write(); + char getPath( char *path, int pathlen ); + }; + friend class RootNode; + +protected: + + Node *node; + RootNode *rootNode; +}; + + +#endif // !Fl_Preferences_H + +// +// End of "$Id: Fl_Preferences.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Printer.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Printer.H new file mode 100644 index 0000000..a7f117d --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Printer.H @@ -0,0 +1,268 @@ +// +// "$Id: Fl_Printer.H 7894 2010-11-26 10:22:40Z manolo $" +// +// Printing support for the Fast Light Tool Kit (FLTK). +// +// Copyright 2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// +/** \file Fl_Printer.H + \brief declaration of classes Fl_System_Printer, Fl_PostScript_Printer, Fl_Printer, Fl_Device_Plugin. + */ + +#ifndef Fl_Printer_H +#define Fl_Printer_H + +#include +#include +#include +#include +#include +#include +#if !(defined(__APPLE__) || defined(WIN32)) +#include +#endif + +#if defined(__APPLE__) || defined(WIN32) || defined(FL_DOXYGEN) +/** + \brief Print support under MSWindows and Mac OS X. +* + Class Fl_System_Printer is implemented only on the MSWindows and Mac OS X platforms. + Use Fl_Printer instead that is cross-platform and has the same API. + Fl_Printer is typedef'ed to Fl_System_Printer under MSWindows and Mac OS X. + */ +class Fl_System_Printer : public Fl_Paged_Device { +private: + /** \brief the printer's graphics context, if there's one, NULL otherwise */ + void *gc; + void set_current(void); +#ifdef __APPLE__ + float scale_x; + float scale_y; + float angle; // rotation angle in radians + PMPrintSession printSession; + PMPageFormat pageFormat; + PMPrintSettings printSettings; +#elif defined(WIN32) + int abortPrint; + PRINTDLG pd; + HDC hPr; + int prerr; + int left_margin; + int top_margin; + void absolute_printable_rect(int *x, int *y, int *w, int *h); +#endif +public: + static const char *device_type; + /** + @brief The constructor. + */ + Fl_System_Printer(void); + int start_job(int pagecount, int *frompage = NULL, int *topage = NULL); + int start_page (void); + int printable_rect(int *w, int *h); + void margins(int *left, int *top, int *right, int *bottom); + void origin(int x, int y); + void scale (float scale_x, float scale_y); + void rotate(float angle); + void translate(int x, int y); + void untranslate(void); + int end_page (void); + void end_job (void); + + /** + @brief The destructor. + */ + ~Fl_System_Printer(void); +#ifndef FL_DOXYGEN +public: + static const char *dialog_title; + static const char *dialog_printer; + static const char *dialog_range; + static const char *dialog_copies; + static const char *dialog_all; + static const char *dialog_pages; + static const char *dialog_from; + static const char *dialog_to; + static const char *dialog_properties; + static const char *dialog_copyNo; + static const char *dialog_print_button; + static const char *dialog_cancel_button; + static const char *dialog_print_to_file; + static const char *property_title; + static const char *property_pagesize; + static const char *property_mode; + static const char *property_use; + static const char *property_save; + static const char *property_cancel; +#endif // FL_DOXYGEN +}; // class Fl_System_Printer + +typedef Fl_System_Printer Fl_Printer; +#endif + +#if !(defined(__APPLE__) || defined(WIN32)) +/** + \brief Print support under Unix/Linux. + * + Class Fl_PostScript_Printer is implemented only on the Unix/Linux platform. + Use Fl_Printer instead that is cross-platform and has the same API. + Fl_Printer is typedef'ed to Fl_PostScript_Printer under Unix/Linux. + */ +class Fl_PostScript_Printer : public Fl_PostScript_File_Device { +public: + static const char *device_type; + int start_job(int pages, int *firstpage = NULL, int *lastpage = NULL); + +#ifndef FL_DOXYGEN + static const char *dialog_title; + static const char *dialog_printer; + static const char *dialog_range; + static const char *dialog_copies; + static const char *dialog_all; + static const char *dialog_pages; + static const char *dialog_from; + static const char *dialog_to; + static const char *dialog_properties; + static const char *dialog_copyNo; + static const char *dialog_print_button; + static const char *dialog_cancel_button; + static const char *dialog_print_to_file; + static const char *property_title; + static const char *property_pagesize; + static const char *property_mode; + static const char *property_use; + static const char *property_save; + static const char *property_cancel; +#endif // FL_DOXYGEN +}; + +typedef Fl_PostScript_Printer Fl_Printer; +#endif + +/** + * @brief OS-independent print support. + * + Fl_Printer allows to use all FLTK drawing, color, text, and clip functions, and to have them operate + on printed page(s). There are two main, non exclusive, ways to use it. +

  • Print any widget (standard, custom, Fl_Window, Fl_Gl_Window) as it appears + on screen, with optional translation, scaling and rotation. This is done by calling print_widget() + or print_window_part(). +
  • Use a series of FLTK graphics commands (e.g., font, text, lines, colors, clip, image) to + compose a page appropriately shaped for printing. +
+ In both cases, begin by start_job(), start_page(), printable_rect() and origin() calls + and finish by end_page() and end_job() calls. +

Platform specifics +
Fl_Printer is typedef'ed to Fl_PostScript_Printer under Unix/Linux + and to Fl_System_Printer otherwise. Both classes have the same API. +

    +
  • Unix/Linux platforms: + Class Fl_RGB_Image prints but loses its transparency if it has one. + See class Fl_PostScript_Graphics_Driver for a description of how UTF-8 strings appear in print. + Use the static public attributes of this class to set the print dialog to other languages + than English. For example, the "Printer:" dialog item Fl_Printer::dialog_printer can be set to French with: + \code + Fl_Printer::dialog_printer = "Imprimante:"; + \endcode + before creation of the Fl_Printer object. + Use Fl_PostScript_File_Device::file_chooser_title to customize the title of the file chooser dialog that opens + when using the "Print To File" option of the print dialog. +
  • MSWindows platform: Transparent Fl_RGB_Image 's don't print with exact transparency on most printers. + Fl_RGB_Image 's don't rotate() well. + A workaround is to use the print_window_part() call. +
  • Mac OS X platform: all graphics requests print as on display. +
+ */ +#ifdef FL_DOXYGEN +// this class is NOT compiled. It's here for Doxygen documentation purpose only +class Fl_Printer : public Fl_System_Printer, Fl_PostScript_Printer { +public: + static const char *device_type; + /** @brief The constructor */ + Fl_Printer(void); + int start_job(int pagecount, int *frompage = NULL, int *topage = NULL); + int start_page(void); + int printable_rect(int *w, int *h); + void margins(int *left, int *top, int *right, int *bottom); + void origin(int x, int y); + void scale(float scale_x, float scale_y); + void rotate(float angle); + void translate(int x, int y); + void untranslate(void); + int end_page (void); + void end_job (void); + /** @brief The destructor */ + ~Fl_Printer(void); + + /** \name These attributes are effective under the Xlib platform only. + \{ + */ + static const char *dialog_title; + static const char *dialog_printer; + static const char *dialog_range; + static const char *dialog_copies; + static const char *dialog_all; + static const char *dialog_pages; + static const char *dialog_from; + static const char *dialog_to; + static const char *dialog_properties; + static const char *dialog_copyNo; + static const char *dialog_print_button; + static const char *dialog_cancel_button; + static const char *dialog_print_to_file; + static const char *property_title; + static const char *property_pagesize; + static const char *property_mode; + static const char *property_use; + static const char *property_save; + static const char *property_cancel; + /** \} */ +}; +#endif + +/** + This plugin socket allows the integration of new device drivers for special + window or screen types. It is currently used to provide an automated printing + service for OpenGL windows, if linked with fltk_gl. + */ +class Fl_Device_Plugin : public Fl_Plugin { +public: + /** \brief The constructor */ + Fl_Device_Plugin(const char *name) + : Fl_Plugin(klass(), name) { } + /** \brief Returns the class name */ + virtual const char *klass() { return "fltk:device"; } + /** \brief Returns the plugin name */ + virtual const char *name() = 0; + /** \brief Prints a widget + \param w the widget + \param x,y offsets where to print relatively to coordinates origin + \param height height of the current drawing area + */ + virtual int print(Fl_Widget* w, int x, int y, int height) { return 0; } +}; + +#endif // Fl_Printer_H + +// +// End of "$Id: Fl_Printer.H 7894 2010-11-26 10:22:40Z manolo $" +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Progress.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Progress.H new file mode 100644 index 0000000..5182848 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Progress.H @@ -0,0 +1,81 @@ +// +// "$Id: Fl_Progress.H 7903 2010-11-28 21:06:39Z matt $" +// +// Progress bar widget definitions. +// +// Copyright 2000-2010 by Michael Sweet. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Progress widget . */ + +#ifndef _Fl_Progress_H_ +# define _Fl_Progress_H_ + +// +// Include necessary headers. +// + +#include "Fl_Widget.H" + + +// +// Progress class... +// +/** + Displays a progress bar for the user. +*/ +class FL_EXPORT Fl_Progress : public Fl_Widget +{ + float value_, + minimum_, + maximum_; + + protected: + + virtual void draw(); + + public: + + Fl_Progress(int x, int y, int w, int h, const char *l = 0); + + /** Sets the maximum value in the progress widget. */ + void maximum(float v) { maximum_ = v; redraw(); } + /** Gets the maximum value in the progress widget. */ + float maximum() const { return (maximum_); } + + /** Sets the minimum value in the progress widget. */ + void minimum(float v) { minimum_ = v; redraw(); } + /** Gets the minimum value in the progress widget. */ + float minimum() const { return (minimum_); } + + /** Sets the current value in the progress widget. */ + void value(float v) { value_ = v; redraw(); } + /** Gets the current value in the progress widget. */ + float value() const { return (value_); } +}; + +#endif // !_Fl_Progress_H_ + +// +// End of "$Id: Fl_Progress.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_RGB_Image.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_RGB_Image.H new file mode 100644 index 0000000..bf1285e --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_RGB_Image.H @@ -0,0 +1,35 @@ +// +// "$Id: Fl_RGB_Image.H 7903 2010-11-28 21:06:39Z matt $" +// +// RGB Image header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_RGB_Image_H +# define Fl_RGB_Image_H +# include "Fl_Image.H" +#endif // !Fl_RGB_Image_H + +// +// End of "$Id: Fl_RGB_Image.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Radio_Button.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Radio_Button.H new file mode 100644 index 0000000..913dd8a --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Radio_Button.H @@ -0,0 +1,46 @@ +// +// "$Id: Fl_Radio_Button.H 7903 2010-11-28 21:06:39Z matt $" +// +// Radio button header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Radio_Button widget . */ + +#ifndef Fl_Radio_Button_H +#define Fl_Radio_Button_H + +#include "Fl_Button.H" + +class Fl_Radio_Button : public Fl_Button { +public: + Fl_Radio_Button(int x,int y,int w,int h,const char *l=0) + : Fl_Button(x,y,w,h,l) {type(FL_RADIO_BUTTON);} +}; + +#endif + +// +// End of "$Id: Fl_Radio_Button.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Radio_Light_Button.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Radio_Light_Button.H new file mode 100644 index 0000000..034c631 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Radio_Light_Button.H @@ -0,0 +1,46 @@ +// +// "$Id: Fl_Radio_Light_Button.H 7903 2010-11-28 21:06:39Z matt $" +// +// Radio light button header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Radio_Light_Button widget . */ + +#ifndef Fl_Radio_Light_Button_H +#define Fl_Radio_Light_Button_H + +#include "Fl_Light_Button.H" + +class Fl_Radio_Light_Button : public Fl_Light_Button { +public: + Fl_Radio_Light_Button(int X,int Y,int W,int H,const char *l=0) + : Fl_Light_Button(X,Y,W,H,l) {type(FL_RADIO_BUTTON);} +}; + +#endif + +// +// End of "$Id: Fl_Radio_Light_Button.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Radio_Round_Button.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Radio_Round_Button.H new file mode 100644 index 0000000..8fd891f --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Radio_Round_Button.H @@ -0,0 +1,46 @@ +// +// "$Id: Fl_Radio_Round_Button.H 7903 2010-11-28 21:06:39Z matt $" +// +// Radio round button header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Radio_Round_Button widget . */ + +#ifndef Fl_Radio_Round_Button_H +#define Fl_Radio_Round_Button_H + +#include "Fl_Round_Button.H" + +class Fl_Radio_Round_Button : public Fl_Round_Button { +public: + Fl_Radio_Round_Button(int x,int y,int w,int h,const char *l=0) + : Fl_Round_Button(x,y,w,h,l) {type(FL_RADIO_BUTTON);} +}; + +#endif + +// +// End of "$Id: Fl_Radio_Round_Button.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Repeat_Button.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Repeat_Button.H new file mode 100644 index 0000000..dc6d42e --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Repeat_Button.H @@ -0,0 +1,63 @@ +// +// "$Id: Fl_Repeat_Button.H 7903 2010-11-28 21:06:39Z matt $" +// +// Repeat button header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Repeat_Button widget . */ + +#ifndef Fl_Repeat_Button_H +#define Fl_Repeat_Button_H +#include "Fl.H" +#include "Fl_Button.H" + +/** + The Fl_Repeat_Button is a subclass of Fl_Button that + generates a callback when it is pressed and then repeatedly generates + callbacks as long as it is held down. The speed of the repeat is fixed + and depends on the implementation. +*/ +class FL_EXPORT Fl_Repeat_Button : public Fl_Button { + static void repeat_callback(void *); +public: + int handle(int); + /** + Creates a new Fl_Repeat_Button widget using the given + position, size, and label string. The default boxtype is FL_UP_BOX. + Deletes the button. + */ + Fl_Repeat_Button(int X,int Y,int W,int H,const char *l=0) + : Fl_Button(X,Y,W,H,l) {} + void deactivate() { + Fl::remove_timeout(repeat_callback,this); + Fl_Button::deactivate(); + } +}; + +#endif + +// +// End of "$Id: Fl_Repeat_Button.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Return_Button.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Return_Button.H new file mode 100644 index 0000000..c7d60a9 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Return_Button.H @@ -0,0 +1,60 @@ +// +// "$Id: Fl_Return_Button.H 7903 2010-11-28 21:06:39Z matt $" +// +// Return button header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Return_Button widget . */ + +#ifndef Fl_Return_Button_H +#define Fl_Return_Button_H +#include "Fl_Button.H" + +/** + The Fl_Return_Button is a subclass of Fl_Button that + generates a callback when it is pressed or when the user presses the + Enter key. A carriage-return symbol is drawn next to the button label. +

\image html Fl_Return_Button.gif + \image latex Fl_Return_Button.eps "Fl_Return_Button" width=4cm +*/ +class FL_EXPORT Fl_Return_Button : public Fl_Button { +protected: + void draw(); +public: + int handle(int); + /** + Creates a new Fl_Return_Button widget using the given + position, size, and label string. The default boxtype is FL_UP_BOX. +

The inherited destructor deletes the button. + */ + Fl_Return_Button(int X, int Y, int W, int H,const char *l=0) + : Fl_Button(X,Y,W,H,l) {} +}; + +#endif + +// +// End of "$Id: Fl_Return_Button.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Roller.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Roller.H new file mode 100644 index 0000000..a9cf713 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Roller.H @@ -0,0 +1,56 @@ +// +// "$Id: Fl_Roller.H 7903 2010-11-28 21:06:39Z matt $" +// +// Roller header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Roller widget . */ + +#ifndef Fl_Roller_H +#define Fl_Roller_H + +#ifndef Fl_Valuator_H +#include "Fl_Valuator.H" +#endif + +/** + The Fl_Roller widget is a "dolly" control commonly used to + move 3D objects. +

\image html Fl_Roller.gif + \image latex Fl_Roller.eps "Fl_Roller" width=4cm +*/ +class FL_EXPORT Fl_Roller : public Fl_Valuator { +protected: + void draw(); +public: + int handle(int); + Fl_Roller(int X,int Y,int W,int H,const char* L=0); +}; + +#endif + +// +// End of "$Id: Fl_Roller.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Round_Button.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Round_Button.H new file mode 100644 index 0000000..6f7bbe1 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Round_Button.H @@ -0,0 +1,57 @@ +// +// "$Id: Fl_Round_Button.H 7903 2010-11-28 21:06:39Z matt $" +// +// Round button header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Round_Button widget . */ + +#ifndef Fl_Round_Button_H +#define Fl_Round_Button_H + +#include "Fl_Light_Button.H" + +/** + Buttons generate callbacks when they are clicked by the user. You + control exactly when and how by changing the values for type() + and when(). +

\image html Fl_Round_Button.gif

+ \image latex Fl_Round_Button.eps " Fl_Round_Button" width=4cm +

The Fl_Round_Button subclass display the "on" state by + turning on a light, rather than drawing pushed in. The shape of the + "light" is initially set to FL_ROUND_DOWN_BOX. The color of the light + when on is controlled with selection_color(), which defaults to + FL_RED. +*/ +class FL_EXPORT Fl_Round_Button : public Fl_Light_Button { +public: + Fl_Round_Button(int x,int y,int w,int h,const char *l = 0); +}; + +#endif + +// +// End of "$Id: Fl_Round_Button.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Round_Clock.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Round_Clock.H new file mode 100644 index 0000000..f00f9cc --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Round_Clock.H @@ -0,0 +1,48 @@ +// +// "$Id: Fl_Round_Clock.H 7903 2010-11-28 21:06:39Z matt $" +// +// Round clock header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Round_Clock widget . */ + +#ifndef Fl_Round_Clock_H +#define Fl_Round_Clock_H + +#include "Fl_Clock.H" + +/** A clock widget of type FL_ROUND_CLOCK. Has no box. */ +class Fl_Round_Clock : public Fl_Clock { +public: + /** Creates the clock widget, setting his type and box. */ + Fl_Round_Clock(int x,int y,int w,int h, const char *l = 0) + : Fl_Clock(x,y,w,h,l) {type(FL_ROUND_CLOCK); box(FL_NO_BOX);} +}; + +#endif + +// +// End of "$Id: Fl_Round_Clock.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Scroll.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Scroll.H new file mode 100644 index 0000000..5c96662 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Scroll.H @@ -0,0 +1,199 @@ +// +// "$Id: Fl_Scroll.H 7903 2010-11-28 21:06:39Z matt $" +// +// Scroll header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Scroll widget . */ + +#ifndef Fl_Scroll_H +#define Fl_Scroll_H + +#include "Fl_Group.H" +#include "Fl_Scrollbar.H" + +/** + This container widget lets you maneuver around a set of widgets much + larger than your window. If the child widgets are larger than the size + of this object then scrollbars will appear so that you can scroll over + to them: + \image html Fl_Scroll.gif + \image latex Fl_Scroll.eps "Fl_Scroll" width=4cm + + If all of the child widgets are packed together into a solid + rectangle then you want to set box() to FL_NO_BOX or + one of the _FRAME types. This will result in the best output. + However, if the child widgets are a sparse arrangement you must + set box() to a real _BOX type. This can result in some + blinking during redrawing, but that can be solved by using a + Fl_Double_Window. + + By default you can scroll in both directions, and the scrollbars + disappear if the data will fit in the area of the scroll. + + Use Fl_Scroll::type() to change this as follows : +

    +
  • 0 - No scrollbars
  • +
  • Fl_Scroll::HORIZONTAL - Only a horizontal scrollbar.
  • +
  • Fl_Scroll::VERTICAL - Only a vertical scrollbar.
  • +
  • Fl_Scroll::BOTH - The default is both scrollbars.
  • +
  • Fl_Scroll::HORIZONTAL_ALWAYS - Horizontal scrollbar always on, vertical always off.
  • +
  • Fl_Scroll::VERTICAL_ALWAYS - Vertical scrollbar always on, horizontal always off.
  • +
  • Fl_Scroll::BOTH_ALWAYS - Both always on.
  • +
+ + Use scrollbar.align(int) ( see void Fl_Widget::align(Fl_Align) ) : + to change what side the scrollbars are drawn on. + + If the FL_ALIGN_LEFT bit is on, the vertical scrollbar is on the left. + If the FL_ALIGN_TOP bit is on, the horizontal scrollbar is on + the top. Note that only the alignment flags in scrollbar are + considered. The flags in hscrollbar however are ignored. + + This widget can also be used to pan around a single child widget + "canvas". This child widget should be of your own class, with a + draw() method that draws the contents. The scrolling is done by + changing the x() and y() of the widget, so this child + must use the x() and y() to position its drawing. + To speed up drawing it should test fl_push_clip(). + + Another very useful child is a single Fl_Pack, which is itself a group + that packs its children together and changes size to surround them. + Filling the Fl_Pack with Fl_Tabs groups (and then putting + normal widgets inside those) gives you a very powerful scrolling list + of individually-openable panels. + + Fluid lets you create these, but you can only lay out objects that + fit inside the Fl_Scroll without scrolling. Be sure to leave + space for the scrollbars, as Fluid won't show these either. + + You cannot use Fl_Window as a child of this since the + clipping is not conveyed to it when drawn, and it will draw over the + scrollbars and neighboring objects. +*/ +class FL_EXPORT Fl_Scroll : public Fl_Group { + + int xposition_, yposition_; + int oldx, oldy; + int scrollbar_size_; + static void hscrollbar_cb(Fl_Widget*, void*); + static void scrollbar_cb(Fl_Widget*, void*); + void fix_scrollbar_order(); + static void draw_clip(void*,int,int,int,int); + +private: + + // + // Structure to manage scrollbar and widget interior sizes. + // + // Private for now -- we'd like to expose some of this at + // some point to solve STR#1895.) + // + typedef struct { + int scrollsize; // the scrollsize (global|local) + int innerbox_x, innerbox_y, innerbox_w, innerbox_h; // widget's inner box (excludes scrollbars) + int innerchild_x, innerchild_y, innerchild_w, innerchild_h; // widget's inner box including scrollbars + int child_l, child_r, child_b, child_t; // child bounding box: left/right/bottom/top + int hneeded, vneeded; // hor + ver scrollbar visibility + int hscroll_x, hscroll_y, hscroll_w, hscroll_h; // hor scrollbar size/position + int vscroll_x, vscroll_y, vscroll_w, vscroll_h; // ver scrollbar size/position + int hpos, hsize, hfirst, htotal; // hor scrollbar values (pos/size/first/total) + int vpos, vsize, vfirst, vtotal; // ver scrollbar values (pos/size/first/total) + } ScrollInfo; + void recalc_scrollbars(ScrollInfo &si); + +protected: + + void bbox(int&,int&,int&,int&); + void draw(); + +public: + + Fl_Scrollbar scrollbar; + Fl_Scrollbar hscrollbar; + + void resize(int,int,int,int); + int handle(int); + + Fl_Scroll(int X,int Y,int W,int H,const char*l=0); + + enum { // values for type() + HORIZONTAL = 1, + VERTICAL = 2, + BOTH = 3, + ALWAYS_ON = 4, + HORIZONTAL_ALWAYS = 5, + VERTICAL_ALWAYS = 6, + BOTH_ALWAYS = 7 + }; + + /** Gets the current horizontal scrolling position. */ + int xposition() const {return xposition_;} + /** Gets the current vertical scrolling position. */ + int yposition() const {return yposition_;} + void scroll_to(int, int); + void clear(); + /** + Gets the current size of the scrollbars' troughs, in pixels. + + If this value is zero (default), this widget will use the + Fl::scrollbar_size() value as the scrollbar's width. + + \returns Scrollbar size in pixels, or 0 if the global Fl::scrollsize() is being used. + \see Fl::scrollbar_size(int) + */ + int scrollbar_size() const { + return(scrollbar_size_); + } + /** + Sets the pixel size of the scrollbars' troughs to the \p size, in pixels. + + Normally you should not need this method, and should use + Fl::scrollbar_size(int) instead to manage the size of ALL + your widgets' scrollbars. This ensures your application + has a consistent UI, is the default behavior, and is normally + what you want. + + Only use THIS method if you really need to override the global + scrollbar size. The need for this should be rare. + + Setting \p size to the special value of 0 causes the widget to + track the global Fl::scrollbar_size(), which is the default. + + \param[in] size Sets the scrollbar size in pixels.\n + If 0 (default), scrollbar size tracks the global Fl::scrollbar_size() + \see Fl::scrollbar_size() + */ + void scrollbar_size(int size) { + if ( size != scrollbar_size_ ) redraw(); + scrollbar_size_ = size; + } +}; + +#endif + +// +// End of "$Id: Fl_Scroll.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Scrollbar.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Scrollbar.H new file mode 100644 index 0000000..a3b926c --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Scrollbar.H @@ -0,0 +1,120 @@ +// +// "$Id: Fl_Scrollbar.H 7903 2010-11-28 21:06:39Z matt $" +// +// Scroll bar header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Scrollbar widget . */ + +#ifndef Fl_Scrollbar_H +#define Fl_Scrollbar_H + +#include "Fl_Slider.H" + +/** + The Fl_Scrollbar widget displays a slider with arrow buttons at + the ends of the scrollbar. Clicking on the arrows move up/left and + down/right by linesize(). Scrollbars also accept FL_SHORTCUT events: + the arrows move by linesize(), and vertical scrollbars take Page + Up/Down (they move by the page size minus linesize()) and Home/End + (they jump to the top or bottom). + + Scrollbars have step(1) preset (they always return integers). If + desired you can set the step() to non-integer values. You will then + have to use casts to get at the floating-point versions of value() + from Fl_Slider. + + \image html scrollbar.gif + \image latex scrollbar.eps "Fl_Scrollbar" width=4cm +*/ +class FL_EXPORT Fl_Scrollbar : public Fl_Slider { + + int linesize_; + int pushed_; + static void timeout_cb(void*); + void increment_cb(); +protected: + void draw(); + +public: + + Fl_Scrollbar(int X,int Y,int W,int H, const char *L = 0); + ~Fl_Scrollbar(); + int handle(int); + + /** + Gets the integer value (position) of the slider in the scrollbar. + You can get the floating point value with Fl_Slider::value(). + + \see Fl_Scrollbar::value(int p) + \see Fl_Scrollbar::value(int pos, int size, int first, int total) + */ + int value() const {return int(Fl_Slider::value());} + + /** + Sets the value (position) of the slider in the scrollbar. + + \see Fl_Scrollbar::value() + \see Fl_Scrollbar::value(int pos, int size, int first, int total) + */ + int value(int p) {return int(Fl_Slider::value((double)p));} + + /** + Sets the position, size and range of the slider in the scrollbar. + \param[in] pos position, first line displayed + \param[in] size window size, number of lines displayed + \param[in] first number of first line + \param[in] total total number of lines + + You should call this every time your window changes size, your data + changes size, or your scroll position changes (even if in response + to a callback from this scrollbar). + All necessary calls to redraw() are done. + + Calls Fl_Slider::scrollvalue(int pos, int size, int first, int total). + */ + int value(int pos, int size, int first, int total) { + return scrollvalue(pos, size, first, total); + } + + /** + Get the size of step, in lines, that the arror keys move. + */ + int linesize() const {return linesize_;} + + /** + This number controls how big the steps are that the arrow keys do. + In addition page up/down move by the size last sent to value() + minus one linesize(). The default is 16. + */ + void linesize(int i) {linesize_ = i;} + +}; + +#endif + +// +// End of "$Id: Fl_Scrollbar.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Secret_Input.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Secret_Input.H new file mode 100644 index 0000000..21f1475 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Secret_Input.H @@ -0,0 +1,56 @@ +// +// "$Id: Fl_Secret_Input.H 7903 2010-11-28 21:06:39Z matt $" +// +// Secret input header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Secret_Input widget . */ + +#ifndef Fl_Secret_Input_H +#define Fl_Secret_Input_H + +#include "Fl_Input.H" + +/** + The Fl_Secret_Input class is a subclass of Fl_Input + that displays its input as a string of asterisks. This subclass is + usually used to receive passwords and other "secret" information. +*/ +class Fl_Secret_Input : public Fl_Input { +public: + /** + Creates a new Fl_Secret_Input widget using the given + position, size, and label string. The default boxtype is FL_DOWN_BOX. +

Inherited destructor destroys the widget and any value associated with it. + */ + Fl_Secret_Input(int X,int Y,int W,int H,const char *l = 0) + : Fl_Input(X,Y,W,H,l) {type(FL_SECRET_INPUT);} +}; + +#endif + +// +// End of "$Id: Fl_Secret_Input.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Select_Browser.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Select_Browser.H new file mode 100644 index 0000000..c8f6607 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Select_Browser.H @@ -0,0 +1,60 @@ +// +// "$Id: Fl_Select_Browser.H 7903 2010-11-28 21:06:39Z matt $" +// +// Select browser header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Select_Browser widget . */ + +#ifndef Fl_Select_Browser_H +#define Fl_Select_Browser_H + +#include "Fl_Browser.H" + +/** + The class is a subclass of Fl_Browser + which lets the user select a single item, or no items by clicking on + the empty space. As long as the mouse button is held down on an + unselected item it is highlighted. Normally the callback is done when the + user presses the mouse, but you can change this with when(). +

See Fl_Browser for methods to add and remove lines from the browser. +*/ +class Fl_Select_Browser : public Fl_Browser { +public: + /** + Creates a new Fl_Select_Browser widget using the given + position, size, and label string. The default boxtype is FL_DOWN_BOX. + The constructor specializes Fl_Browser() by setting the type to FL_SELECT_BROWSER. + The destructor destroys the widget and frees all memory that has been allocated. + */ + Fl_Select_Browser(int X,int Y,int W,int H,const char *l=0) + : Fl_Browser(X,Y,W,H,l) {type(FL_SELECT_BROWSER);} +}; + +#endif + +// +// End of "$Id: Fl_Select_Browser.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Shared_Image.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Shared_Image.H new file mode 100644 index 0000000..9ad394b --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Shared_Image.H @@ -0,0 +1,110 @@ +// +// "$Id: Fl_Shared_Image.H 7903 2010-11-28 21:06:39Z matt $" +// +// Shared image header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/** \file + Fl_Shared_Image class. */ + +#ifndef Fl_Shared_Image_H +# define Fl_Shared_Image_H + +# include "Fl_Image.H" + + +// Test function for adding new formats +typedef Fl_Image *(*Fl_Shared_Handler)(const char *name, uchar *header, + int headerlen); + +// Shared images class. +/** + This class supports caching, loading, + and drawing of image files. Most applications will also want to + link against the fltk_images library and call the + fl_register_images() + function to support standard image formats such as BMP, GIF, JPEG, and PNG. +*/ +class FL_EXPORT Fl_Shared_Image : public Fl_Image { + protected: + + static Fl_Shared_Image **images_; // Shared images + static int num_images_; // Number of shared images + static int alloc_images_; // Allocated shared images + static Fl_Shared_Handler *handlers_; // Additional format handlers + static int num_handlers_; // Number of format handlers + static int alloc_handlers_; // Allocated format handlers + + const char *name_; // Name of image file + int original_; // Original image? + int refcount_; // Number of times this image has been used + Fl_Image *image_; // The image that is shared + int alloc_image_; // Was the image allocated? + + static int compare(Fl_Shared_Image **i0, Fl_Shared_Image **i1); + + // Use get() and release() to load/delete images in memory... + Fl_Shared_Image(); + Fl_Shared_Image(const char *n, Fl_Image *img = 0); + virtual ~Fl_Shared_Image(); + void add(); + void update(); + + public: + /** Returns the filename of the shared image */ + const char *name() { return name_; } + /** Returns the number of references of this shared image. When reference is below 1, the image is deleted. */ + int refcount() { return refcount_; } + void release(); + void reload(); + + virtual Fl_Image *copy(int W, int H); + Fl_Image *copy() { return copy(w(), h()); } + virtual void color_average(Fl_Color c, float i); + virtual void desaturate(); + virtual void draw(int X, int Y, int W, int H, int cx, int cy); + void draw(int X, int Y) { draw(X, Y, w(), h(), 0, 0); } + virtual void uncache(); + + static Fl_Shared_Image *find(const char *n, int W = 0, int H = 0); + static Fl_Shared_Image *get(const char *n, int W = 0, int H = 0); + static Fl_Shared_Image **images(); + static int num_images(); + static void add_handler(Fl_Shared_Handler f); + static void remove_handler(Fl_Shared_Handler f); +}; + +// +// The following function is provided in the fltk_images library and +// registers all of the "extra" image file formats that are not part +// of the core FLTK library... +// + +FL_EXPORT extern void fl_register_images(); + +#endif // !Fl_Shared_Image_H + +// +// End of "$Id: Fl_Shared_Image.H 7903 2010-11-28 21:06:39Z matt $" +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Simple_Counter.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Simple_Counter.H new file mode 100644 index 0000000..1c7af94 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Simple_Counter.H @@ -0,0 +1,50 @@ +// +// "$Id: Fl_Simple_Counter.H 7903 2010-11-28 21:06:39Z matt $" +// +// Simple counter header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Simple_Counter widget . */ + +#ifndef Fl_Simple_Counter_H +#define Fl_Simple_Counter_H + +#include "Fl_Counter.H" +/** + This widget creates a counter with only 2 arrow buttons +

\image html counter.gif

+ \image latex counter.eps "Fl_Simple_Counter" width=4cm +*/ +class Fl_Simple_Counter : public Fl_Counter { +public: + Fl_Simple_Counter(int x,int y,int w,int h, const char *l = 0) + : Fl_Counter(x,y,w,h,l) {type(FL_SIMPLE_COUNTER);} +}; + +#endif + +// +// End of "$Id: Fl_Simple_Counter.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Single_Window.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Single_Window.H new file mode 100644 index 0000000..9bebc4e --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Single_Window.H @@ -0,0 +1,67 @@ +// +// "$Id: Fl_Single_Window.H 7903 2010-11-28 21:06:39Z matt $" +// +// Single-buffered window header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Single_Window class . */ + +#ifndef Fl_Single_Window_H +#define Fl_Single_Window_H + +#include "Fl_Window.H" + +/** + This is the same as Fl_Window. However, it is possible that + some implementations will provide double-buffered windows by default. + This subcan be used to force single-buffering. This may be + useful for modifying existing programs that use incremental update, or + for some types of image data, such as a movie flipbook. +*/ +class FL_EXPORT Fl_Single_Window : public Fl_Window { +public: + void show(); + void show(int a, char **b) {Fl_Window::show(a,b);} + void flush(); + /** + Creates a new Fl_Single_Window widget using the given + size, and label (title) string. + */ + Fl_Single_Window(int W, int H, const char *l=0) + : Fl_Window(W,H,l) {} + /** + Creates a new Fl_Single_Window widget using the given + position, size, and label (title) string. + */ + Fl_Single_Window(int X, int Y, int W, int H, const char *l=0) + : Fl_Window(X,Y,W,H,l) {} + int make_current(); +}; + +#endif + +// +// End of "$Id: Fl_Single_Window.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Slider.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Slider.H new file mode 100644 index 0000000..8272579 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Slider.H @@ -0,0 +1,120 @@ +// +// "$Id: Fl_Slider.H 7903 2010-11-28 21:06:39Z matt $" +// +// Slider header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Slider widget . */ + +#ifndef Fl_Slider_H +#define Fl_Slider_H + +#ifndef Fl_Valuator_H +#include "Fl_Valuator.H" +#endif + +// values for type(), lowest bit indicate horizontal: +#define FL_VERT_SLIDER 0 +#define FL_HOR_SLIDER 1 +#define FL_VERT_FILL_SLIDER 2 +#define FL_HOR_FILL_SLIDER 3 +#define FL_VERT_NICE_SLIDER 4 +#define FL_HOR_NICE_SLIDER 5 + +/** + The Fl_Slider widget contains a sliding knob inside a box. It if + often used as a scrollbar. Moving the box all the way to the + top/left sets it to the minimum(), and to the bottom/right to the + maximum(). The minimum() may be greater than the maximum() to + reverse the slider direction. + + Use void Fl_Widget::type(int) to set how the slider is drawn, + which can be one of the following: + + \li FL_VERTICAL - Draws a vertical slider (this is the default). + \li FL_HORIZONTAL - Draws a horizontal slider. + \li FL_VERT_FILL_SLIDER - Draws a filled vertical slider, + useful as a progress or value meter. + \li FL_HOR_FILL_SLIDER - Draws a filled horizontal slider, + useful as a progress or value meter. + \li FL_VERT_NICE_SLIDER - Draws a vertical slider with a nice + looking control knob. + \li FL_HOR_NICE_SLIDER - Draws a horizontal slider with a + nice looking control knob. + + \image html slider.gif + \image latex slider.eps "Fl_Slider" width=4cm +*/ +class FL_EXPORT Fl_Slider : public Fl_Valuator { + + float slider_size_; + uchar slider_; + void _Fl_Slider(); + void draw_bg(int, int, int, int); + +protected: + + // these allow subclasses to put the slider in a smaller area: + void draw(int, int, int, int); + int handle(int, int, int, int, int); + void draw(); + +public: + + int handle(int); + Fl_Slider(int X,int Y,int W,int H, const char *L = 0); + Fl_Slider(uchar t,int X,int Y,int W,int H, const char *L); + + int scrollvalue(int pos,int size,int first,int total); + void bounds(double a, double b); + + /** + Get the dimensions of the moving piece of slider. + */ + float slider_size() const {return slider_size_;} + + /** + Set the dimensions of the moving piece of slider. This is + the fraction of the size of the entire widget. If you set this + to 1 then the slider cannot move. The default value is .08. + + For the "fill" sliders this is the size of the area around the + end that causes a drag effect rather than causing the slider to + jump to the mouse. + */ + void slider_size(double v); + + /** Gets the slider box type. */ + Fl_Boxtype slider() const {return (Fl_Boxtype)slider_;} + + /** Sets the slider box type. */ + void slider(Fl_Boxtype c) {slider_ = c;} +}; + +#endif + +// +// End of "$Id: Fl_Slider.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Spinner.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Spinner.H new file mode 100644 index 0000000..79f3fbb --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Spinner.H @@ -0,0 +1,266 @@ +// +// "$Id: Fl_Spinner.H 7903 2010-11-28 21:06:39Z matt $" +// +// Spinner widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Spinner widget . */ + +#ifndef Fl_Spinner_H +# define Fl_Spinner_H + +// +// Include necessary headers... +// + +# include +# include +# include +# include +# include +# include + + +/** + This widget is a combination of the input + widget and repeat buttons. The user can either type into the + input area or use the buttons to change the value. +*/ +class Fl_Spinner : public Fl_Group +{ + double value_; // Current value + double minimum_; // Minimum value + double maximum_; // Maximum value + double step_; // Amount to add/subtract for up/down + const char *format_; // Format string + + Fl_Input input_; // Input field for the value + Fl_Repeat_Button + up_button_, // Up button + down_button_; // Down button + + + static void sb_cb(Fl_Widget *w, Fl_Spinner *sb) { + double v; // New value + + if (w == &(sb->input_)) { + // Something changed in the input field... + v = atof(sb->input_.value()); + + if (v < sb->minimum_) { + sb->value_ = sb->minimum_; + sb->update(); + } else if (v > sb->maximum_) { + sb->value_ = sb->maximum_; + sb->update(); + } else sb->value_ = v; + } else if (w == &(sb->up_button_)) { + // Up button pressed... + v = sb->value_ + sb->step_; + + if (v > sb->maximum_) sb->value_ = sb->minimum_; + else sb->value_ = v; + + sb->update(); + } else if (w == &(sb->down_button_)) { + // Down button pressed... + v = sb->value_ - sb->step_; + + if (v < sb->minimum_) sb->value_ = sb->maximum_; + else sb->value_ = v; + + sb->update(); + } + + sb->do_callback(); + } + void update() { + char s[255]; // Value string + + if (format_[0]=='%'&&format_[1]=='.'&&format_[2]=='*') { // precision argument + // this code block is a simplified version of + // Fl_Valuator::format() and works well (but looks ugly) + int c = 0; + char temp[64], *sp = temp; + sprintf(temp, "%.12f", step_); + while (*sp) sp++; + sp--; + while (sp>temp && *sp=='0') sp--; + while (sp>temp && (*sp>='0' && *sp<='9')) { sp--; c++; } + sprintf(s, format_, c, value_); + } else { + sprintf(s, format_, value_); + } + input_.value(s); + } + + public: + + /** + Creates a new Fl_Spinner widget using the given position, size, + and label string. +

Inherited destructor Destroys the widget and any value associated with it. + */ + Fl_Spinner(int X, int Y, int W, int H, const char *L = 0) + : Fl_Group(X, Y, W, H, L), + input_(X, Y, W - H / 2 - 2, H), + up_button_(X + W - H / 2 - 2, Y, H / 2 + 2, H / 2, "@-42<"), + down_button_(X + W - H / 2 - 2, Y + H - H / 2, + H / 2 + 2, H / 2, "@-42>") { + end(); + + value_ = 1.0; + minimum_ = 1.0; + maximum_ = 100.0; + step_ = 1.0; + format_ = "%g"; + + align(FL_ALIGN_LEFT); + + input_.value("1"); + input_.type(FL_INT_INPUT); + input_.when(FL_WHEN_ENTER_KEY | FL_WHEN_RELEASE); + input_.callback((Fl_Callback *)sb_cb, this); + + up_button_.callback((Fl_Callback *)sb_cb, this); + + down_button_.callback((Fl_Callback *)sb_cb, this); + } + + /** Sets or returns the format string for the value. */ + const char *format() { return (format_); } + /** Sets or returns the format string for the value. */ + void format(const char *f) { format_ = f; update(); } + + int handle(int event) { + switch (event) { + case FL_KEYDOWN : + case FL_SHORTCUT : + if (Fl::event_key() == FL_Up) { + up_button_.do_callback(); + return 1; + } else if (Fl::event_key() == FL_Down) { + down_button_.do_callback(); + return 1; + } else return 0; + + case FL_FOCUS : + if (input_.take_focus()) return 1; + else return 0; + } + + return Fl_Group::handle(event); + } + + /** Speling mistakes retained for source compatibility \deprecated */ + double maxinum() const { return (maximum_); } + /** Gets the maximum value of the widget. */ + double maximum() const { return (maximum_); } + /** Sets the maximum value of the widget. */ + void maximum(double m) { maximum_ = m; } + /** Speling mistakes retained for source compatibility \deprecated */ + double mininum() const { return (minimum_); } + /** Gets the minimum value of the widget. */ + double minimum() const { return (minimum_); } + /** Sets the minimum value of the widget. */ + void minimum(double m) { minimum_ = m; } + /** Sets the minimum and maximum values for the widget. */ + void range(double a, double b) { minimum_ = a; maximum_ = b; } + void resize(int X, int Y, int W, int H) { + Fl_Group::resize(X,Y,W,H); + + input_.resize(X, Y, W - H / 2 - 2, H); + up_button_.resize(X + W - H / 2 - 2, Y, H / 2 + 2, H / 2); + down_button_.resize(X + W - H / 2 - 2, Y + H - H / 2, + H / 2 + 2, H / 2); + } + /** + Sets or returns the amount to change the value when the user clicks a button. + Before setting step to a non-integer value, the spinner + type() should be changed to floating point. + */ + double step() const { return (step_); } + /** See double Fl_Spinner::step() const */ + void step(double s) { + step_ = s; + if (step_ != (int)step_) input_.type(FL_FLOAT_INPUT); + else input_.type(FL_INT_INPUT); + update(); + } + /** Gets the color of the text in the input field. */ + Fl_Color textcolor() const { + return (input_.textcolor()); + } + /** Sets the color of the text in the input field. */ + void textcolor(Fl_Color c) { + input_.textcolor(c); + } + /** Gets the font of the text in the input field. */ + Fl_Font textfont() const { + return (input_.textfont()); + } + /** Sets the font of the text in the input field. */ + void textfont(Fl_Font f) { + input_.textfont(f); + } + /** Gets the size of the text in the input field. */ + Fl_Fontsize textsize() const { + return (input_.textsize()); + } + /** Sets the size of the text in the input field. */ + void textsize(Fl_Fontsize s) { + input_.textsize(s); + } + /** Sets or Gets the numeric representation in the input field. + Valid values are FL_INT_INPUT and FL_FLOAT_INPUT. + The first form also changes the format() template. + Setting a new spinner type via a superclass pointer will not work. + \note type is not a virtual function. + */ + uchar type() const { return (input_.type()); } + /** See uchar Fl_Spinner::type() const */ + void type(uchar v) { + if (v==FL_FLOAT_INPUT) { + format("%.*f"); + } else { + format("%.0f"); + } + input_.type(v); + } + /** Gets the current value of the widget. */ + double value() const { return (value_); } + /** + Sets the current value of the widget. + Before setting value to a non-integer value, the spinner + type() should be changed to floating point. + */ + void value(double v) { value_ = v; update(); } +}; + +#endif // !Fl_Spinner_H + +// +// End of "$Id: Fl_Spinner.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Sys_Menu_Bar.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Sys_Menu_Bar.H new file mode 100644 index 0000000..da70c92 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Sys_Menu_Bar.H @@ -0,0 +1,80 @@ +// +// "$Id: Fl_Sys_Menu_Bar.H 7903 2010-11-28 21:06:39Z matt $" +// +// MacOS system menu bar header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Sys_Menu_Bar_H +#define Fl_Sys_Menu_Bar_H + +#include "Fl_Menu_Bar.H" +#include "x.H" + +#if defined(__APPLE__) || defined(FL_DOXYGEN) + +/** + @brief A class to create, modify and delete menus that appear on Mac OS X in the menu bar at the top of the screen. + * + * On other than Mac OS X platforms, Fl_Sys_Menu_Bar is a synonym of class Fl_Menu_Bar. + */ +class FL_EXPORT Fl_Sys_Menu_Bar : public Fl_Menu_Bar { +protected: + void draw(); +public: + /** + @brief The constructor. + * + * On Mac OS X, all arguments are unused. On other platforms they are used as by Fl_Menu_Bar::Fl_Menu_Bar(). + */ + Fl_Sys_Menu_Bar(int x,int y,int w,int h,const char *l=0) + : Fl_Menu_Bar(x,y,w,h,l) { + deactivate(); // don't let the old area take events + fl_sys_menu_bar = this; + } + void menu(const Fl_Menu_Item *m); + int add(const char* label, int shortcut, Fl_Callback*, void *user_data=0, int flags=0); + int insert(int index, const char* label, int shortcut, Fl_Callback *cb, void *user_data=0, int flags=0); + void remove(int n); + void replace(int rank, const char *name); + void clear(); + int clear_submenu(int index); +#if ! defined(FL_DOXYGEN) + enum menuOrItemOperation { itemAtIndex, setKeyEquivalent, setKeyEquivalentModifierMask, setState, initWithTitle, + numberOfItems, setSubmenu, setEnabled, addSeparatorItem, setTitle, removeItem, addNewItem, renameItem }; + // function doMenuOrItemOperation is in file Fl_cocoa.mm because it contains objective-c code + static void *doMenuOrItemOperation( menuOrItemOperation operation, ...); +#endif +}; + +#else + +typedef Fl_Menu_Bar Fl_Sys_Menu_Bar; + +#endif // defined(__APPLE__) || defined(FL_DOXYGEN) + +#endif // Fl_Sys_Menu_Bar_H + +// +// End of "$Id: Fl_Sys_Menu_Bar.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Tabs.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Tabs.H new file mode 100644 index 0000000..800bcaf --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Tabs.H @@ -0,0 +1,86 @@ +// +// "$Id: Fl_Tabs.H 7903 2010-11-28 21:06:39Z matt $" +// +// Tab header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Tabs widget . */ + +#ifndef Fl_Tabs_H +#define Fl_Tabs_H + +#include "Fl_Group.H" + +/** + The Fl_Tabs widget is the "file card tabs" + interface that allows you to put lots and lots of buttons and + switches in a panel, as popularized by many toolkits. + + \image html tabs.gif + \image latex tabs.eps "Fl_Tabs" width=8cm + + Clicking the tab makes a child visible() by calling + show() on it, and all other children are made invisible + by calling hide() on them. Usually the children are Fl_Group widgets + containing several widgets themselves. + + Each child makes a card, and its label() is printed + on the card tab, including the label font and style. The + selection color of that child is used to color the tab, while + the color of the child determines the background color of the pane. + + The size of the tabs is controlled by the bounding box of the + children (there should be some space between the children and + the edge of the Fl_Tabs), and the tabs may be placed + "inverted" on the bottom - this is determined by which + gap is larger. It is easiest to lay this out in fluid, using the + fluid browser to select each child group and resize them until + the tabs look the way you want them to. +*/ +class FL_EXPORT Fl_Tabs : public Fl_Group { + Fl_Widget *value_; + Fl_Widget *push_; + int tab_positions(int*, int*); + int tab_height(); + void draw_tab(int x1, int x2, int W, int H, Fl_Widget* o, int sel=0); +protected: + void redraw_tabs(); + void draw(); + +public: + int handle(int); + Fl_Widget *value(); + int value(Fl_Widget *); + Fl_Widget *push() const {return push_;} + int push(Fl_Widget *); + Fl_Tabs(int,int,int,int,const char * = 0); + Fl_Widget *which(int event_x, int event_y); +}; + +#endif + +// +// End of "$Id: Fl_Tabs.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Text_Buffer.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Text_Buffer.H new file mode 100644 index 0000000..d3e5f74 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Text_Buffer.H @@ -0,0 +1,783 @@ +// +// "$Id: Fl_Text_Buffer.H 7903 2010-11-28 21:06:39Z matt $" +// +// Header file for Fl_Text_Buffer class. +// +// Copyright 2001-2010 by Bill Spitzak and others. +// Original code Copyright Mark Edel. Permission to distribute under +// the LGPL for the FLTK library granted by Mark Edel. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Text_Buffer, Fl_Text_Selection widget . */ + +#ifndef FL_TEXT_BUFFER_H +#define FL_TEXT_BUFFER_H + + +#define ASSERT_UTF8 + +#ifdef ASSERT_UTF8 +# include +# define IS_UTF8_ALIGNED(a) if (a && *a) assert(fl_utf8len(*(a))>0); +# define IS_UTF8_ALIGNED2(a, b) if (b>=0 && blength()) assert(fl_utf8len(a->byte_at(b))>0); +#else +# define IS_UTF8_ALIGNED(a) +# define IS_UTF8_ALIGNED2(a, b) +#endif + + +/* + Suggested UTF-8 terminology for this file: + + ?? "length" is the number of characters in a string + ?? "size" is the number of bytes + ?? "index" is the position in a string in number of characters + ?? "offset" is the position in a string in bytes (and must be kept on a charater boundary) + (there seems to be no standard in Uncode documents, howevere "length" is commonly + referencing the number of bytes. Maybe "bytes" and "glyphs" would be the most + obvious way to describe sizes?) + + "character size" is the size of a UTF-8 character in bytes + "character width" is the width of a Unicode character in pixels + + "column" was orginally defined as a character offset from the left margin. It was + identical to the byte offset. In UTF-8, we have neither a byte offset nor + truly fixed width fonts (*). Column could be a pixel value multiplied with + an average character width (which is a bearable approximation). + + * in Unicode, there are no fixed width fonts! Even if the ASCII characters may + happen to be all the same width in pixels, chinese charcaters surely are not. + There are plenty of exceptions, like ligatures, that make special handling of + "fixed" character widths a nightmare. I decided to remove all references to + fixed fonts and see "columns" as a multiple of the average width of a + character in the main font. + - Matthias + */ + + +/* Maximum length in characters of a tab or control character expansion + of a single buffer character */ +#define FL_TEXT_MAX_EXP_CHAR_LEN 20 + +#include "Fl_Export.H" + + +/** + \class Fl_Text_Selection + \brief This is an internal class for Fl_Text_Buffer to manage text selections. + This class works correctly with utf-8 strings assuming that the parameters + for all calls are on character boundaries. + */ +class FL_EXPORT Fl_Text_Selection { + friend class Fl_Text_Buffer; + +public: + + /** + \brief Set the selection range. + \param start byte offset to first selected character + \param end byte offset pointing after last selected character + */ + void set(int start, int end); + + /** + \brief Updates a selection afer text was modified. + Updates an individual selection for changes in the corresponding text + \param pos byte offset into text buffer at which the change occured + \param nDeleted number of bytes deleted from the buffer + \param nInserted number of bytes inserted into the buffer + */ + void update(int pos, int nDeleted, int nInserted); + + /** + \brief Return the byte offset to the first selected character. + \return byte offset + */ + int start() const { return mStart; } + + /** + \brief Return the byte ofsset to the character after the last selected character. + \return byte offset + */ + int end() const { return mEnd; } + + /** + \brief Returns true if any text is selected. + \return a non-zero number if any text has been selected, or 0 + if no text is selected. + */ + bool selected() const { return mSelected; } + + /** + \brief Modify the 'selected' flag. + \param b new flag + */ + void selected(bool b) { mSelected = b; } + + /** + Return true if position \p pos with indentation \p dispIndex is in + the Fl_Text_Selection. + */ + int includes(int pos) const; + + /** + \brief Return the positions of this selection. + \param start retrun byte offset to first selected character + \param end retrun byte offset pointing after last selected character + \return true if selected + */ + int position(int* start, int* end) const; + +protected: + + int mStart; ///< byte offset to the first selected character + int mEnd; ///< byte offset to the character after the last selected character + bool mSelected; ///< this flag is set if any text is selected +}; + + +typedef void (*Fl_Text_Modify_Cb)(int pos, int nInserted, int nDeleted, + int nRestyled, const char* deletedText, + void* cbArg); + + +typedef void (*Fl_Text_Predelete_Cb)(int pos, int nDeleted, void* cbArg); + + +/** + \brief This class manages unicode displayed in one or more Fl_Text_Display widgets. + + All text in Fl_Text_Buffermust be encoded in UTF-8. All indices used in the + function calls must be aligned to the start of a UTF-8 sequence. All indices + and pointers returned will be aligned. All functions that return a single + character will return that in an unsiged int in UCS-4 encoding. + + The Fl_Text_Buffer class is used by the Fl_Text_Display + and Fl_Text_Editor to manage complex text data and is based upon the + excellent NEdit text editor engine - see http://www.nedit.org/. + */ +class FL_EXPORT Fl_Text_Buffer { +public: + + /** + Create an empty text buffer of a pre-determined size. + \param requestedSize use this to avoid unnecessary re-allocation + if you know exactly how much the buffer will need to hold + \param preferredGapSize Initial size for the buffer gap (empty space + in the buffer where text might be inserted + if the user is typing sequential chars) + */ + Fl_Text_Buffer(int requestedSize = 0, int preferredGapSize = 1024); + + /** + Frees a text buffer + */ + ~Fl_Text_Buffer(); + + /** + \brief Returns the number of bytes in the buffer. + \return size of text in bytes + */ + int length() const { return mLength; } + + /** + \brief Get a copy of the entire contents of the text buffer. + Memory is allocated to contain the returned string, which the caller + must free. + \return newly allocated text buffer - must be free'd, text is utf8 + */ + char* text() const; + + /** + Replaces the entire contents of the text buffer. + \param text Text must be valid utf8. + */ + void text(const char* text); + + /** + \brief Get a copy of a part of the text buffer. + Return a copy of the text between \p start and \p end character positions + from text buffer \p buf. Positions start at 0, and the range does not + include the character pointed to by \p end. + When you are done with the text, free it using the free() function. + \param start byte offset to first character + \param end byte offset after last character in range + \return newly allocated text buffer - must be free'd, text is utf8 + */ + char* text_range(int start, int end) const; + + /** + Returns the character at the specified position pos in the buffer. + Positions start at 0 + \param pos byte offset into buffer, pos must be at acharacter boundary + \return Unicode UCS-4 encoded character + */ + unsigned int char_at(int pos) const; + + /** + Returns the raw byte at the specified position pos in the buffer. + Positions start at 0 + \param pos byte offset into buffer + \return unencoded raw byte + */ + char byte_at(int pos) const; + + /** + Convert a byte offset in buffer into a memory address. + \param pos byte offset into buffer + \return byte offset converted to a memory address + */ + const char *address(int pos) const + { return (pos < mGapStart) ? mBuf+pos : mBuf+pos+mGapEnd-mGapStart; } + + /** + Convert a byte offset in buffer into a memory address. + \param pos byte offset into buffer + \return byte offset converted to a memory address + */ + char *address(int pos) + { return (pos < mGapStart) ? mBuf+pos : mBuf+pos+mGapEnd-mGapStart; } + + /** + Inserts null-terminated string \p text at position \p pos. + \param pos insertion position as byte offset (must be utf-8 character aligned) + \param text utf-8 encoded and nul terminated text + */ + void insert(int pos, const char* text); + + /** + Appends the text string to the end of the buffer. + \param t utf-8 encoded and nul terminated text + */ + void append(const char* t) { insert(length(), t); } + + /** + Deletes a range of characters in the buffer. + \param start byte offset to first character to be removed + \param end byte offset to charcatre after last character to be removed + */ + void remove(int start, int end); + + /** + Deletes the characters between \p start and \p end, and inserts the null-terminated string \p text in their place in the buffer. + \param start byte offset to first character to be removed and new insert position + \param end byte offset to charcatre after last character to be removed + \param text utf-8 encoded and nul terminated text + */ + void replace(int start, int end, const char *text); + + /** + Copies text from one buffer to this one. + \param fromBuf source text buffer may be the same as this + \param fromStart byte offset into buffer + \param fromEnd byte offset into buffer + \param toPos destination byte offset into buffer + */ + void copy(Fl_Text_Buffer* fromBuf, int fromStart, int fromEnd, int toPos); + + /** + Undo text modification according to the undo variables or insert text + from the undo buffer + */ + int undo(int *cp=0); + + /** + Lets the undo system know if we can undo changes + */ + void canUndo(char flag=1); + + /** + Inserts a file at the specified position. Returns 0 on success, + non-zero on error (strerror() contains reason). 1 indicates open + for read failed (no data loaded). 2 indicates error occurred + while reading data (data was partially loaded). + */ + int insertfile(const char *file, int pos, int buflen = 128*1024); + + /** + Appends the named file to the end of the buffer. Returns 0 on + success, non-zero on error (strerror() contains reason). 1 indicates + open for read failed (no data loaded). 2 indicates error occurred + while reading data (data was partially loaded). + */ + int appendfile(const char *file, int buflen = 128*1024) + { return insertfile(file, length(), buflen); } + + /** + Loads a text file into the buffer + */ + int loadfile(const char *file, int buflen = 128*1024) + { select(0, length()); remove_selection(); return appendfile(file, buflen); } + + /** + Writes the specified portions of the file to a file. Returns 0 on success, non-zero + on error (strerror() contains reason). 1 indicates open for write failed + (no data saved). 2 indicates error occurred while writing data + (data was partially saved). + */ + int outputfile(const char *file, int start, int end, int buflen = 128*1024); + + /** + Saves a text file from the current buffer + */ + int savefile(const char *file, int buflen = 128*1024) + { return outputfile(file, 0, length(), buflen); } + + /** + Gets the tab width. + */ + int tab_distance() const { return mTabDist; } + + /** + Set the hardware tab distance (width) used by all displays for this buffer, + and used in computing offsets for rectangular selection operations. + */ + void tab_distance(int tabDist); + + /** + Selects a range of characters in the buffer. + */ + void select(int start, int end); + + /** + Returns a non 0 value if text has been selected, 0 otherwise + */ + int selected() const { return mPrimary.selected(); } + + /** + Cancels any previous selection on the primary text selection object + */ + void unselect(); + + /** + Gets the selection position + */ + int selection_position(int* start, int* end); + + /** + Returns the currently selected text. When you are done with + the text, free it using the free() function. + */ + char* selection_text(); + + /** + Removes the text in the primary selection. + */ + void remove_selection(); + + /** + Replaces the text in the primary selection. + */ + void replace_selection(const char* text); + + /** + Selects a range of characters in the secondary selection. + */ + void secondary_select(int start, int end); + + /** + Returns a non 0 value if text has been selected in the secondary + text selection, 0 otherwise + */ + int secondary_selected() { return mSecondary.selected(); } + + /** + Clears any selection in the secondary text selection object. + */ + void secondary_unselect(); + + /** + Returns the current selection in the secondary text selection object. + */ + int secondary_selection_position(int* start, int* end); + + /** + Returns the text in the secondary selection. When you are + done with the text, free it using the free() function. + */ + char* secondary_selection_text(); + + /** + Removes the text from the buffer corresponding to the secondary text selection object. + */ + void remove_secondary_selection(); + + /** + Replaces the text from the buffer corresponding to the secondary + text selection object with the new string \p text. + */ + void replace_secondary_selection(const char* text); + + /** + Highlights the specified text within the buffer. + */ + void highlight(int start, int end); + + /** + Returns the highlighted text. When you are done with the + text, free it using the free() function. + */ + int highlight() { return mHighlight.selected(); } + + /** + Unhighlights text in the buffer. + */ + void unhighlight(); + + /** + Highlights the specified text between \p start and \p end within the buffer. + */ + int highlight_position(int* start, int* end); + + /** + Returns the highlighted text. When you are done with the + text, free it using the free() function. + */ + char* highlight_text(); + + /** + Adds a callback function that is called whenever the text buffer is + modified. The callback function is declared as follows: + + \code + typedef void (*Fl_Text_Modify_Cb)(int pos, int nInserted, int nDeleted, + int nRestyled, const char* deletedText, + void* cbArg); + \endcode + */ + void add_modify_callback(Fl_Text_Modify_Cb bufModifiedCB, void* cbArg); + + /** + Removes a modify callback. + */ + void remove_modify_callback(Fl_Text_Modify_Cb bufModifiedCB, void* cbArg); + + /** + Calls all modify callbacks that have been registered using + the add_modify_callback() + method. + */ + void call_modify_callbacks() { call_modify_callbacks(0, 0, 0, 0, 0); } + + /** + Adds a callback routine to be called before text is deleted from the buffer. + */ + void add_predelete_callback(Fl_Text_Predelete_Cb bufPredelCB, void* cbArg); + + /** + Removes a callback routine \p bufPreDeleteCB associated with argument \p cbArg + to be called before text is deleted from the buffer. + */ + void remove_predelete_callback(Fl_Text_Predelete_Cb predelCB, void* cbArg); + + /** + Calls the stored pre-delete callback procedure(s) for this buffer to update + the changed area(s) on the screen and any other listeners. + */ + void call_predelete_callbacks() { call_predelete_callbacks(0, 0); } + + /** + Returns the text from the entire line containing the specified + character position. When you are done with the text, free it + using the free() function. + \param pos byte index into buffer + \return copy of utf8 text, must be free'd + */ + char* line_text(int pos) const; + + /** + Returns the position of the start of the line containing position \p pos. + \param pos byte index into buffer + \return byte offset to line start + */ + int line_start(int pos) const; + + /** + Finds and returns the position of the end of the line containing position \p pos + (which is either a pointer to the newline character ending the line, + or a pointer to one character beyond the end of the buffer) + \param pos byte index into buffer + \return byte offset to line end + */ + int line_end(int pos) const; + + /** + Returns the position corresponding to the start of the word + \param pos byte index into buffer + \return byte offset to word start + */ + int word_start(int pos) const; + + /** + Returns the position corresponding to the end of the word. + \param pos byte index into buffer + \return byte offset to word end + */ + int word_end(int pos) const; + + /** + Count the number of displayed characters between buffer position + \p lineStartPos and \p targetPos. (displayed characters are the characters + shown on the screen to represent characters in the buffer, where tabs and + control characters are expanded) + */ + int count_displayed_characters(int lineStartPos, int targetPos) const; + + /** + Count forward from buffer position \p startPos in displayed characters + (displayed characters are the characters shown on the screen to represent + characters in the buffer, where tabs and control characters are expanded) + \param lineStartPos byte offset into buffer + \param nChars number of bytes that are sent to the display + \return byte offset in input after all output bytes are sent + */ + int skip_displayed_characters(int lineStartPos, int nChars); + + /** + Counts the number of newlines between \p startPos and \p endPos in buffer. + The character at position \p endPos is not counted. + */ + int count_lines(int startPos, int endPos) const; + + /** + Finds the first character of the line \p nLines forward from \p startPos + in the buffer and returns its position + */ + int skip_lines(int startPos, int nLines); + + /** + Finds and returns the position of the first character of the line \p nLines backwards + from \p startPos (not counting the character pointed to by \p startpos if + that is a newline) in the buffer. \p nLines == 0 means find the beginning of the line + */ + int rewind_lines(int startPos, int nLines); + + /** + Finds the next occurrence of the specified character. + Search forwards in buffer for character \p searchChar, starting + with the character \p startPos, and returning the result in \p foundPos + returns 1 if found, 0 if not. (The difference between this and + BufSearchForward is that it's optimized for single characters. The + overall performance of the text widget is dependent on its ability to + count lines quickly, hence searching for a single character: newline) + \param startPos byte offset to start position + \param searchChar UCS-4 character that we want to find + \param foundPos byte offset where the character was found + \return 1 if found, 0 if not + */ + int findchar_forward(int startPos, unsigned searchChar, int* foundPos) const; + + /** + Search backwards in buffer \p buf for character \p searchChar, starting + with the character BEFORE \p startPos, returning the result in \p foundPos + returns 1 if found, 0 if not. (The difference between this and + BufSearchBackward is that it's optimized for single characters. The + overall performance of the text widget is dependent on its ability to + count lines quickly, hence searching for a single character: newline) + \param startPos byte offset to start position + \param searchChar UCS-4 character that we want to find + \param foundPos byte offset where the character was found + \return 1 if found, 0 if not + */ + int findchar_backward(int startPos, unsigned searchChar, int* foundPos) const; + + /** + Search forwards in buffer for string \p searchString, starting with the + character \p startPos, and returning the result in \p foundPos + returns 1 if found, 0 if not. + \param startPos byte offset to start position + \param searchString utf8 string that we want to find + \param foundPos byte offset where the string was found + \param matchCase if set, match character case + \return 1 if found, 0 if not + */ + int search_forward(int startPos, const char* searchString, int* foundPos, + int matchCase = 0) const; + + /** + Search backwards in buffer for string searchCharssearchString, starting with the + character BEFORE \p startPos, returning the result in \p foundPos + returns 1 if found, 0 if not. + \param startPos byte offset to start position + \param searchString utf8 string that we want to find + \param foundPos byte offset where the string was found + \param matchCase if set, match character case + \return 1 if found, 0 if not + */ + int search_backward(int startPos, const char* searchString, int* foundPos, + int matchCase = 0) const; + + /** + Returns the primary selection. + */ + const Fl_Text_Selection* primary_selection() const { return &mPrimary; } + + /** + Returns the primary selection. + */ + Fl_Text_Selection* primary_selection() { return &mPrimary; } + + /** + Returns the secondary selection. + */ + const Fl_Text_Selection* secondary_selection() const { return &mSecondary; } + + /** + Returns the current highlight selection. + */ + const Fl_Text_Selection* highlight_selection() const { return &mHighlight; } + + /** + Returns the index of the previous character. + \param ix index to the current char + */ + int prev_char(int ix) const; + int prev_char_clipped(int ix) const; + + /** + Returns a pointer to the previous character. + \param c pointer to the current char + */ + char *prev_char(char *c) const; + const char *prev_char(const char *c) const; + + /** + Returns the index of the next character. + \param ix index to the current char + */ + int next_char(int ix) const; + int next_char_clipped(int ix) const; + + /** + Returns a pointer to the next character. + \param c pointer to the current char + */ + char *next_char(char *c) const; + const char *next_char(const char *c) const; + + /** + Align an index into the buffer to the current or previous utf8 boundary. + */ + int utf8_align(int) const; + +protected: + + /** + Calls the stored modify callback procedure(s) for this buffer to update the + changed area(s) on the screen and any other listeners. + */ + void call_modify_callbacks(int pos, int nDeleted, int nInserted, + int nRestyled, const char* deletedText) const; + + /** + Calls the stored pre-delete callback procedure(s) for this buffer to update + the changed area(s) on the screen and any other listeners. + */ + void call_predelete_callbacks(int pos, int nDeleted) const; + + /** + Internal (non-redisplaying) version of BufInsert. Returns the length of + text inserted (this is just strlen(\p text), however this calculation can be + expensive and the length will be required by any caller who will continue + on to call redisplay). \p pos must be contiguous with the existing text in + the buffer (i.e. not past the end). + \return the number of bytes inserted + */ + int insert_(int pos, const char* text); + + /** + Internal (non-redisplaying) version of BufRemove. Removes the contents + of the buffer between start and end (and moves the gap to the site of + the delete). + */ + void remove_(int start, int end); + + /** + Calls the stored redisplay procedure(s) for this buffer to update the + screen for a change in a selection. + */ + void redisplay_selection(Fl_Text_Selection* oldSelection, + Fl_Text_Selection* newSelection) const; + + /** + Move the gap to start at a new position. + */ + void move_gap(int pos); + + /** + Reallocates the text storage in the buffer to have a gap starting at \p newGapStart + and a gap size of \p newGapLen, preserving the buffer's current contents. + */ + void reallocate_with_gap(int newGapStart, int newGapLen); + + char* selection_text_(Fl_Text_Selection* sel) const; + + /** + Removes the text from the buffer corresponding to \p sel. + */ + void remove_selection_(Fl_Text_Selection* sel); + + /** + Replaces the \p text in selection \p sel. + */ + void replace_selection_(Fl_Text_Selection* sel, const char* text); + + /** + Updates all of the selections in the buffer for changes in the buffer's text + */ + void update_selections(int pos, int nDeleted, int nInserted); + + Fl_Text_Selection mPrimary; /**< highlighted areas */ + Fl_Text_Selection mSecondary; /**< highlighted areas */ + Fl_Text_Selection mHighlight; /**< highlighted areas */ + int mLength; /**< length of the text in the buffer (the length + of the buffer itself must be calculated: + gapEnd - gapStart + length) */ + char* mBuf; /**< allocated memory where the text is stored */ + int mGapStart; /**< points to the first character of the gap */ + int mGapEnd; /**< points to the first char after the gap */ + // The hardware tab distance used by all displays for this buffer, + // and used in computing offsets for rectangular selection operations. + int mTabDist; /**< equiv. number of characters in a tab */ + int mNModifyProcs; /**< number of modify-redisplay procs attached */ + Fl_Text_Modify_Cb *mModifyProcs;/**< procedures to call when buffer is + modified to redisplay contents */ + void** mCbArgs; /**< caller arguments for modifyProcs above */ + int mNPredeleteProcs; /**< number of pre-delete procs attached */ + Fl_Text_Predelete_Cb *mPredeleteProcs; /**< procedure to call before text is deleted + from the buffer; at most one is supported. */ + void **mPredeleteCbArgs; /**< caller argument for pre-delete proc above */ + int mCursorPosHint; /**< hint for reasonable cursor position after + a buffer modification operation */ + char mCanUndo; /**< if this buffer is used for attributes, it must + not do any undo calls */ + int mPreferredGapSize; /**< the default allocation for the text gap is 1024 + bytes and should only be increased if frequent + and large changes in buffer size are expected */ +}; + +#endif + +// +// End of "$Id: Fl_Text_Buffer.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Text_Display.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Text_Display.H new file mode 100644 index 0000000..64f6aed --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Text_Display.H @@ -0,0 +1,481 @@ +// +// "$Id: Fl_Text_Display.H 7903 2010-11-28 21:06:39Z matt $" +// +// Header file for Fl_Text_Display class. +// +// Copyright 2001-2010 by Bill Spitzak and others. +// Original code Copyright Mark Edel. Permission to distribute under +// the LGPL for the FLTK library granted by Mark Edel. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Text_Display widget . */ + +#ifndef FL_TEXT_DISPLAY_H +#define FL_TEXT_DISPLAY_H + +#include "fl_draw.H" +#include "Fl_Group.H" +#include "Fl_Widget.H" +#include "Fl_Scrollbar.H" +#include "Fl_Text_Buffer.H" + +/** + \brief Rich text display widget. + + This is the FLTK text display widget. It allows the user to view multiple lines + of text and supports highlighting and scrolling. The buffer that is displayed + in the widget is managed by the Fl_Text_Buffer class. A single Text Buffer + can be displayed by multiple Text Displays. + */ +class FL_EXPORT Fl_Text_Display: public Fl_Group +{ +public: + + /** + text display cursor shapes enumeration + */ + enum { + NORMAL_CURSOR, /**< I-beam */ + CARET_CURSOR, /**< caret under the text */ + DIM_CURSOR, /**< dim I-beam */ + BLOCK_CURSOR, /**< unfille box under the current character */ + HEAVY_CURSOR /**< thick I-beam */ + }; + + /** + the character position is the left edge of a character wheras + the cursor is thought to be between the centers of to consecutive + characters. + */ + enum { + CURSOR_POS, + CHARACTER_POS + }; + + /** + drag types - they match Fl::event_clicks() so that single clicking to + start a collection selects by character, double clicking selects by + word and triple clicking selects by line. + */ + enum { + DRAG_NONE = -2, + DRAG_START_DND = -1, + DRAG_CHAR = 0, + DRAG_WORD = 1, + DRAG_LINE = 2 + }; + + /** + wrap types - usedin wrap_mode() + */ + enum { + WRAP_NONE, /**< don't wrap text at all */ + WRAP_AT_COLUMN, /**< wrap text at the given text column */ + WRAP_AT_PIXEL, /**< wrap text at a pixel position */ + WRAP_AT_BOUNDS /**< wrap text so that it fits into the widget width */ + }; + + friend void fl_text_drag_me(int pos, Fl_Text_Display* d); + + typedef void (*Unfinished_Style_Cb)(int, void *); + + /** + This structure associates the color,font,size of a string to draw + with an attribute mask matching attr + */ + struct Style_Table_Entry { + Fl_Color color; + Fl_Font font; + Fl_Fontsize size; + unsigned attr; + }; + + Fl_Text_Display(int X, int Y, int W, int H, const char *l = 0); + ~Fl_Text_Display(); + + virtual int handle(int e); + + void buffer(Fl_Text_Buffer* buf); + + /** + Sets the current text buffer associated with the text widget. + Multiple text widgets can be associated with the same text buffer. + \param buf new text buffer + */ + void buffer(Fl_Text_Buffer& buf) { buffer(&buf); } + + /** + Gets the current text buffer associated with the text widget. + Multiple text widgets can be associated with the same text buffer. + \return current text buffer + */ + Fl_Text_Buffer* buffer() const { return mBuffer; } + + void redisplay_range(int start, int end); + void scroll(int topLineNum, int horizOffset); + void insert(const char* text); + void overstrike(const char* text); + void insert_position(int newPos); + + /** + Gets the position of the text insertion cursor for text display + \return insert position index into text buffer + */ + int insert_position() const { return mCursorPos; } + + int in_selection(int x, int y) const; + void show_insert_position(); + + int move_right(); + int move_left(); + int move_up(); + int move_down(); + int count_lines(int start, int end, bool start_pos_is_line_start) const; + int line_start(int pos) const; + int line_end(int pos, bool start_pos_is_line_start) const; + int skip_lines(int startPos, int nLines, bool startPosIsLineStart); + int rewind_lines(int startPos, int nLines); + void next_word(void); + void previous_word(void); + + void show_cursor(int b = 1); + + /** + Hides the text cursor + */ + void hide_cursor() { show_cursor(0); } + + void cursor_style(int style); + + /** + Gets the text cursor color. + \return cursor color + */ + Fl_Color cursor_color() const {return mCursor_color;} + + /** + Sets the text cursor color. + \param n new cursor color + */ + void cursor_color(Fl_Color n) {mCursor_color = n;} + + /** + Gets the width/height of the scrollbars. + /return width of scrollbars + */ + int scrollbar_width() const { return scrollbar_width_; } + + /** + Sets the width/height of the scrollbars. + \param W width of scrollbars + */ + void scrollbar_width(int W) { scrollbar_width_ = W; } + + /** + Gets the scrollbar alignment type + \return scrollbar alignment + */ + Fl_Align scrollbar_align() const { return scrollbar_align_; } + + /** + Sets the scrollbar alignment type + \param a new scrollbar alignment + */ + void scrollbar_align(Fl_Align a) { scrollbar_align_ = a; } + + /** + Moves the insert position to the beginning of the current word. + \param pos start calculation at this index + \return beginning of the wors + */ + int word_start(int pos) const { return buffer()->word_start(pos); } + + /** + Moves the insert position to the end of the current word. + \param pos start calculation at this index + \return index of first character after the end of the word + */ + int word_end(int pos) const { return buffer()->word_end(pos); } + + + void highlight_data(Fl_Text_Buffer *styleBuffer, + const Style_Table_Entry *styleTable, + int nStyles, char unfinishedStyle, + Unfinished_Style_Cb unfinishedHighlightCB, + void *cbArg); + + int position_style(int lineStartPos, int lineLen, int lineIndex) const; + + /** + \todo FIXME : get set methods pointing on shortcut_ + have no effects as shortcut_ is unused in this class and derived! + \return the current shortcut key + */ + int shortcut() const {return shortcut_;} + + /** + \todo FIXME : get set methods pointing on shortcut_ + have no effects as shortcut_ is unused in this class and derived! + \param s the new shortcut key + */ + void shortcut(int s) {shortcut_ = s;} + + /** + Gets the default font used when drawing text in the widget. + \return current text font face unless overriden by a style + */ + Fl_Font textfont() const {return textfont_;} + + /** + Sets the default font used when drawing text in the widget. + \param s default text font face + */ + void textfont(Fl_Font s) {textfont_ = s; mColumnScale = 0;} + + /** + Gets the default size of text in the widget. + \return current text height unless overriden by a style + */ + Fl_Fontsize textsize() const {return textsize_;} + + /** + Sets the default size of text in the widget. + \param s new text size + */ + void textsize(Fl_Fontsize s) {textsize_ = s; mColumnScale = 0;} + + /** + Gets the default color of text in the widget. + \return text color unless overriden by a style + */ + Fl_Color textcolor() const {return textcolor_;} + + /** + Sets the default color of text in the widget. + \param n new text color + */ + void textcolor(Fl_Color n) {textcolor_ = n;} + + int wrapped_column(int row, int column) const; + int wrapped_row(int row) const; + void wrap_mode(int wrap, int wrap_margin); + + virtual void resize(int X, int Y, int W, int H); + + /** + Convert an x pixel position into a column number. + \param x number of pixels form the left margin + \return an approximate column number based on the main font + */ + double x_to_col(double y) const; + + /** + Convert a column number into an x pixel position. + \param col an approximate column number based on the main font + \return number of pixels form the left margin to the left of an average + sized character + */ + double col_to_x(double col) const; + +protected: + // Most (all?) of this stuff should only be called from resize() or + // draw(). + // Anything with "vline" indicates thats it deals with currently + // visible lines. + + virtual void draw(); + void draw_text(int X, int Y, int W, int H); + void draw_range(int start, int end); + void draw_cursor(int, int); + + void draw_string(int style, int x, int y, int toX, const char *string, + int nChars) const; + + void draw_vline(int visLineNum, int leftClip, int rightClip, + int leftCharIndex, int rightCharIndex); + + int find_x(const char *s, int len, int style, int x) const; + + enum { + DRAW_LINE, + FIND_INDEX, + FIND_INDEX_FROM_ZERO, + GET_WIDTH + }; + + int handle_vline(int mode, + int lineStart, int lineLen, int leftChar, int rightChar, + int topClip, int bottomClip, + int leftClip, int rightClip) const; + + void draw_line_numbers(bool clearAll); + + void clear_rect(int style, int x, int y, int width, int height) const; + void display_insert(); + + void offset_line_starts(int newTopLineNum); + + void calc_line_starts(int startLine, int endLine); + + void update_line_starts(int pos, int charsInserted, int charsDeleted, + int linesInserted, int linesDeleted, int *scrolled); + + void calc_last_char(); + + int position_to_line( int pos, int* lineNum ) const; + double string_width(const char* string, int length, int style) const; + + static void scroll_timer_cb(void*); + + static void buffer_predelete_cb(int pos, int nDeleted, void* cbArg); + static void buffer_modified_cb(int pos, int nInserted, int nDeleted, + int nRestyled, const char* deletedText, + void* cbArg); + + static void h_scrollbar_cb(Fl_Scrollbar* w, Fl_Text_Display* d); + static void v_scrollbar_cb( Fl_Scrollbar* w, Fl_Text_Display* d); + void update_v_scrollbar(); + void update_h_scrollbar(); + int measure_vline(int visLineNum) const; + int longest_vline() const; + int empty_vlines() const; + int vline_length(int visLineNum) const; + int xy_to_position(int x, int y, int PosType = CHARACTER_POS) const; + + void xy_to_rowcol(int x, int y, int* row, int* column, + int PosType = CHARACTER_POS) const; + + int position_to_xy(int pos, int* x, int* y) const; + void maintain_absolute_top_line_number(int state); + int get_absolute_top_line_number() const; + void absolute_top_line_number(int oldFirstChar); + int maintaining_absolute_top_line_number() const; + void reset_absolute_top_line_number(); + int position_to_linecol(int pos, int* lineNum, int* column) const; + int scroll_(int topLineNum, int horizOffset); + + void extend_range_for_styles(int* start, int* end); + + void find_wrap_range(const char *deletedText, int pos, int nInserted, + int nDeleted, int *modRangeStart, int *modRangeEnd, + int *linesInserted, int *linesDeleted); + void measure_deleted_lines(int pos, int nDeleted); + void wrapped_line_counter(Fl_Text_Buffer *buf, int startPos, int maxPos, + int maxLines, bool startPosIsLineStart, + int styleBufOffset, int *retPos, int *retLines, + int *retLineStart, int *retLineEnd, + bool countLastLineMissingNewLine = true) const; + void find_line_end(int pos, bool start_pos_is_line_start, int *lineEnd, + int *nextLineStart) const; + double measure_proportional_character(const char *s, int colNum, int pos) const; + int wrap_uses_character(int lineEndPos) const; + + int damage_range1_start, damage_range1_end; + int damage_range2_start, damage_range2_end; + int mCursorPos; + int mCursorOn; + int mCursorOldY; /* Y pos. of cursor for blanking */ + int mCursorToHint; /* Tells the buffer modified callback + where to move the cursor, to reduce + the number of redraw calls */ + int mCursorStyle; /* One of enum cursorStyles above */ + int mCursorPreferredXPos; /* Pixel position for vert. cursor movement */ + int mNVisibleLines; /* # of visible (displayed) lines */ + int mNBufferLines; /* # of newlines in the buffer */ + Fl_Text_Buffer* mBuffer; /* Contains text to be displayed */ + Fl_Text_Buffer* mStyleBuffer; /* Optional parallel buffer containing + color and font information */ + int mFirstChar, mLastChar; /* Buffer positions of first and last + displayed character (lastChar points + either to a newline or one character + beyond the end of the buffer) */ + int mContinuousWrap; /* Wrap long lines when displaying */ + int mWrapMarginPix; /* Margin in # of pixels for + wrapping in continuousWrap mode */ + int* mLineStarts; + int mTopLineNum; /* Line number of top displayed line + of file (first line of file is 1) */ + int mAbsTopLineNum; /* In continuous wrap mode, the line + number of the top line if the text + were not wrapped (note that this is + only maintained as needed). */ + int mNeedAbsTopLineNum; /* Externally settable flag to continue + maintaining absTopLineNum even if + it isn't needed for line # display */ + int mHorizOffset; /* Horizontal scroll pos. in pixels */ + int mTopLineNumHint; /* Line number of top displayed line + of file (first line of file is 1) */ + int mHorizOffsetHint; /* Horizontal scroll pos. in pixels */ + int mNStyles; /* Number of entries in styleTable */ + const Style_Table_Entry *mStyleTable; /* Table of fonts and colors for + coloring/syntax-highlighting */ + char mUnfinishedStyle; /* Style buffer entry which triggers + on-the-fly reparsing of region */ + Unfinished_Style_Cb mUnfinishedHighlightCB; /* Callback to parse "unfinished" */ + /* regions */ + void* mHighlightCBArg; /* Arg to unfinishedHighlightCB */ + + int mMaxsize; + + int mSuppressResync; /* Suppress resynchronization of line + starts during buffer updates */ + int mNLinesDeleted; /* Number of lines deleted during + buffer modification (only used + when resynchronization is suppressed) */ + int mModifyingTabDistance; /* Whether tab distance is being + modified */ + + mutable double mColumnScale; /* Width in pixels of an average character. This + value is calculated as needed (lazy eval); it + needs to be mutable so that it can be calculated + within a method marked as "const" */ + + Fl_Color mCursor_color; + + Fl_Scrollbar* mHScrollBar; + Fl_Scrollbar* mVScrollBar; + int scrollbar_width_; + Fl_Align scrollbar_align_; + int dragPos, dragType, dragging; + int display_insert_position_hint; + struct { int x, y, w, h; } text_area; + + int shortcut_; + + Fl_Font textfont_; + Fl_Fontsize textsize_; + Fl_Color textcolor_; + + // The following are not presently used from the original NEdit code, + // but are being put here so that future versions of Fl_Text_Display + // can implement line numbers without breaking binary compatibility. + + /* Line number margin and width */ + int mLineNumLeft, mLineNumWidth; +}; + +#endif + +// +// End of "$Id: Fl_Text_Display.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Text_Editor.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Text_Editor.H new file mode 100644 index 0000000..40f9e6b --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Text_Editor.H @@ -0,0 +1,141 @@ +// +// "$Id: Fl_Text_Editor.H 7903 2010-11-28 21:06:39Z matt $" +// +// Header file for Fl_Text_Editor class. +// +// Copyright 2001-2010 by Bill Spitzak and others. +// Original code Copyright Mark Edel. Permission to distribute under +// the LGPL for the FLTK library granted by Mark Edel. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Text_Editor widget . */ + + +#ifndef FL_TEXT_EDITOR_H +#define FL_TEXT_EDITOR_H + +#include "Fl_Text_Display.H" + +// key will match in any state +#define FL_TEXT_EDITOR_ANY_STATE (-1L) + +/** + This is the FLTK text editor widget. It allows the user to + edit multiple lines of text and supports highlighting and + scrolling. The buffer that is displayed in the widget is managed + by the Fl_Text_Buffer + class. +*/ +class FL_EXPORT Fl_Text_Editor : public Fl_Text_Display { + public: + /** Key function binding callback type */ + typedef int (*Key_Func)(int key, Fl_Text_Editor* editor); + + /** Simple linked list associating a key/state to a function */ + struct Key_Binding { + int key; ///< the key pressed + int state; ///< the state of key modifiers + Key_Func function; ///< associated function + Key_Binding* next; ///< next key binding in the list + }; + + Fl_Text_Editor(int X, int Y, int W, int H, const char* l = 0); + ~Fl_Text_Editor() { remove_all_key_bindings(); } + virtual int handle(int e); + /** + Sets the current insert mode; if non-zero, new text + is inserted before the current cursor position. Otherwise, new + text replaces text at the current cursor position. + */ + void insert_mode(int b) { insert_mode_ = b; } + /** + Gets the current insert mode; if non-zero, new text + is inserted before the current cursor position. Otherwise, new + text replaces text at the current cursor position. + */ + int insert_mode() { return insert_mode_; } + + void add_key_binding(int key, int state, Key_Func f, Key_Binding** list); + /** Adds a key of state "state" with the function "function" */ + void add_key_binding(int key, int state, Key_Func f) + { add_key_binding(key, state, f, &key_bindings); } + void remove_key_binding(int key, int state, Key_Binding** list); + /** Removes the key binding associated with the key "key" of state "state". */ + void remove_key_binding(int key, int state) + { remove_key_binding(key, state, &key_bindings); } + void remove_all_key_bindings(Key_Binding** list); + /** Removes all of the key bindings associated with the text editor or list. */ + void remove_all_key_bindings() { remove_all_key_bindings(&key_bindings); } + void add_default_key_bindings(Key_Binding** list); + Key_Func bound_key_function(int key, int state, Key_Binding* list); + /** Returns the function associated with a key binding. */ + Key_Func bound_key_function(int key, int state) + { return bound_key_function(key, state, key_bindings); } + /** Sets the default key function for unassigned keys. */ + void default_key_function(Key_Func f) { default_key_function_ = f; } + + // functions for the built in default bindings + static int kf_default(int c, Fl_Text_Editor* e); + static int kf_ignore(int c, Fl_Text_Editor* e); + static int kf_backspace(int c, Fl_Text_Editor* e); + static int kf_enter(int c, Fl_Text_Editor* e); + static int kf_move(int c, Fl_Text_Editor* e); + static int kf_shift_move(int c, Fl_Text_Editor* e); + static int kf_ctrl_move(int c, Fl_Text_Editor* e); + static int kf_c_s_move(int c, Fl_Text_Editor* e); + static int kf_meta_move(int c, Fl_Text_Editor* e); + static int kf_m_s_move(int c, Fl_Text_Editor* e); + static int kf_home(int, Fl_Text_Editor* e); + static int kf_end(int c, Fl_Text_Editor* e); + static int kf_left(int c, Fl_Text_Editor* e); + static int kf_up(int c, Fl_Text_Editor* e); + static int kf_right(int c, Fl_Text_Editor* e); + static int kf_down(int c, Fl_Text_Editor* e); + static int kf_page_up(int c, Fl_Text_Editor* e); + static int kf_page_down(int c, Fl_Text_Editor* e); + static int kf_insert(int c, Fl_Text_Editor* e); + static int kf_delete(int c, Fl_Text_Editor* e); + static int kf_copy(int c, Fl_Text_Editor* e); + static int kf_cut(int c, Fl_Text_Editor* e); + static int kf_paste(int c, Fl_Text_Editor* e); + static int kf_select_all(int c, Fl_Text_Editor* e); + static int kf_undo(int c, Fl_Text_Editor* e); + + protected: + int handle_key(); + void maybe_do_callback(); + +#ifndef FL_DOXYGEN + int insert_mode_; + Key_Binding* key_bindings; + static Key_Binding* global_key_bindings; + Key_Func default_key_function_; +#endif +}; + +#endif + +// +// End of "$Id: Fl_Text_Editor.H 7903 2010-11-28 21:06:39Z matt $". +// + diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Tile.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Tile.H new file mode 100644 index 0000000..ae1722b --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Tile.H @@ -0,0 +1,102 @@ +// +// "$Id: Fl_Tile.H 7903 2010-11-28 21:06:39Z matt $" +// +// Tile header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Tile widget . */ + +#ifndef Fl_Tile_H +#define Fl_Tile_H + +#include "Fl_Group.H" + +/** + The Fl_Tile class lets you resize the children by dragging + the border between them: + +

\image html Fl_Tile.gif

+ \image latex Fl_Tile.eps "Fl_Tile" width=4cm + +

For the tiling to work correctly, the children of an + Fl_Tile must cover the entire area of the widget, but not + overlap. This means that all children must touch each + other at their edges, and no gaps can't be left inside the + Fl_Tile. + +

Fl_Tile does not normailly draw any graphics of its own. + The "borders" which can be seen in the snapshot above + are actually part of the children. Their boxtypes have been set + to FL_DOWN_BOX creating the impression of + "ridges" where the boxes touch. What you see are + actually two adjacent FL_DOWN_BOX's drawn next to each + other. All neighboring widgets share the same edge - the widget's + thick borders make it appear as though the widgets aren't actually + touching, but they are. If the edges of adjacent widgets do not + touch, then it will be impossible to drag the corresponding + edges.

+ +

Fl_Tile allows objects to be resized to zero dimensions. + To prevent this you can use the resizable() to limit where + corners can be dragged to.

+ +

Even though objects can be resized to zero sizes, they must + initially have non-zero sizes so the Fl_Tile can figure out + their layout. If desired, call position() after creating the + children but before displaying the window to set the borders where you + want. + +

Note on resizable(Fl_Widget &w) : + The "resizable" child widget (which should be invisible) limits where the + border can be dragged to. If you don't set it, it will be possible to + drag the borders right to the edge, and thus resize objects on the edge + to zero width or height. The resizable() widget is not + resized by dragging any borders. See also void Fl_Group::resizable(Fl_Widget &w) + +*/ +class FL_EXPORT Fl_Tile : public Fl_Group { +public: + int handle(int); + /** + Creates a new Fl_Tile widget using the given position, size, + and label string. The default boxtype is FL_NO_BOX. + +

The destructor also deletes all the children. This allows a + whole tree to be deleted at once, without having to keep a pointer to + all the children in the user code. A kludge has been done so the + Fl_Tile and all of it's children can be automatic (local) + variables, but you must declare the Fl_Tile first, so + that it is destroyed last. + */ + Fl_Tile(int X,int Y,int W,int H,const char*l=0) : Fl_Group(X,Y,W,H,l) {} + void resize(int, int, int, int); + void position(int, int, int, int); +}; + +#endif + +// +// End of "$Id: Fl_Tile.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Tiled_Image.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Tiled_Image.H new file mode 100644 index 0000000..d169379 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Tiled_Image.H @@ -0,0 +1,70 @@ +// +// "$Id: Fl_Tiled_Image.H 7903 2010-11-28 21:06:39Z matt $" +// +// Tiled image header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Tiled_Image widget . */ + +#ifndef Fl_Tiled_Image_H +# define Fl_Tiled_Image_H + +# include "Fl_Image.H" + + +/** + This class supports tiling of images + over a specified area. The source (tile) image is not + copied unless you call the color_average(), + desaturate(), + or inactive() + methods. +*/ +class FL_EXPORT Fl_Tiled_Image : public Fl_Image { + protected: + + Fl_Image *image_; // The image that is shared + int alloc_image_; // Did we allocate this image? + + public: + + Fl_Tiled_Image(Fl_Image *i, int W = 0, int H = 0); + virtual ~Fl_Tiled_Image(); + + virtual Fl_Image *copy(int W, int H); + Fl_Image *copy() { return copy(w(), h()); } + virtual void color_average(Fl_Color c, float i); + virtual void desaturate(); + virtual void draw(int X, int Y, int W, int H, int cx, int cy); + void draw(int X, int Y) { draw(X, Y, w(), h(), 0, 0); } + /** Gets The image that is shared */ + Fl_Image *image() { return image_; } +}; + +#endif // !Fl_Tiled_Image_H + +// +// End of "$Id: Fl_Tiled_Image.H 7903 2010-11-28 21:06:39Z matt $" +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Timer.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Timer.H new file mode 100644 index 0000000..952273f --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Timer.H @@ -0,0 +1,87 @@ +// +// "$Id: Fl_Timer.H 7903 2010-11-28 21:06:39Z matt $" +// +// Timer header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Timer widget . */ + +#ifndef Fl_Timer_H +#define Fl_Timer_H + +#ifndef Fl_Widget_H +#include "Fl_Widget.H" +#endif + +// values for type(): +#define FL_NORMAL_TIMER 0 +#define FL_VALUE_TIMER 1 +#define FL_HIDDEN_TIMER 2 + +/** + This is provided only to emulate the Forms Timer widget. It works by + making a timeout callback every 1/5 second. This is wasteful and + inaccurate if you just want something to happen a fixed time in the + future. You should directly call + Fl::add_timeout() instead. +*/ +class FL_EXPORT Fl_Timer : public Fl_Widget { + static void stepcb(void *); + void step(); + char on, direction_; + double delay, total; + long lastsec,lastusec; +protected: + void draw(); +public: + int handle(int); + Fl_Timer(uchar t,int x,int y,int w,int h, const char *l); + ~Fl_Timer(); + void value(double); + /** See void Fl_Timer::value(double) */ + double value() const {return delay>0.0?delay:0.0;} + /** + Gets or sets the direction of the timer. If the direction is zero + then the timer will count up, otherwise it will count down from the + initial value(). + */ + char direction() const {return direction_;} + /** + Gets or sets the direction of the timer. If the direction is zero + then the timer will count up, otherwise it will count down from the + initial value(). + */ + void direction(char d) {direction_ = d;} + /** Gets or sets whether the timer is suspended. */ + char suspended() const {return !on;} + void suspended(char d); +}; + +#endif + +// +// End of "$Id: Fl_Timer.H 7903 2010-11-28 21:06:39Z matt $". +// + diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Toggle_Button.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Toggle_Button.H new file mode 100644 index 0000000..02886fb --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Toggle_Button.H @@ -0,0 +1,60 @@ +// +// "$Id: Fl_Toggle_Button.H 7903 2010-11-28 21:06:39Z matt $" +// +// Toggle button header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Toggle_Button widget . */ + +#ifndef Fl_Toggle_Button_H +#define Fl_Toggle_Button_H + +#include "Fl_Button.H" + +/** + The toggle button is a push button that needs to be clicked once + to toggle on, and one more time to toggle off. + The Fl_Toggle_Button subclass displays the "on" state by + drawing a pushed-in button.

+

Buttons generate callbacks when they are clicked by the user. You + control exactly when and how by changing the values for type() + and when(). +*/ +class Fl_Toggle_Button : public Fl_Button { +public: + /** + Creates a new Fl_Toggle_Button widget using the given + position, size, and label string. +

The inherited destructor deletes the toggle button. + */ + Fl_Toggle_Button(int X,int Y,int W,int H,const char *l=0) + : Fl_Button(X,Y,W,H,l) {type(FL_TOGGLE_BUTTON);} +}; + +#endif + +// +// End of "$Id: Fl_Toggle_Button.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Toggle_Light_Button.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Toggle_Light_Button.H new file mode 100644 index 0000000..8d446d8 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Toggle_Light_Button.H @@ -0,0 +1,37 @@ +// +// "$Id: Fl_Toggle_Light_Button.H 7903 2010-11-28 21:06:39Z matt $" +// +// Toggle light button header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// provided for back-compatibility only + +#ifndef Fl_Toggle_Light_Button +#include "Fl_Light_Button.H" +#define Fl_Toggle_Light_Button Fl_Light_Button +#endif + +// +// End of "$Id: Fl_Toggle_Light_Button.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Toggle_Round_Button.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Toggle_Round_Button.H new file mode 100644 index 0000000..3fd892b --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Toggle_Round_Button.H @@ -0,0 +1,37 @@ +// +// "$Id: Fl_Toggle_Round_Button.H 7903 2010-11-28 21:06:39Z matt $" +// +// Toggle round button header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// provided for back-compatibility only + +#ifndef Fl_Toggle_Round_Button +#include "Fl_Round_Button.H" +#define Fl_Toggle_Round_Button Fl_Round_Button +#endif + +// +// End of "$Id: Fl_Toggle_Round_Button.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Tooltip.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Tooltip.H new file mode 100644 index 0000000..9c71997 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Tooltip.H @@ -0,0 +1,109 @@ +// +// "$Id: Fl_Tooltip.H 7903 2010-11-28 21:06:39Z matt $" +// +// Tooltip header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Tooltip widget . */ + +#ifndef Fl_Tooltip_H +#define Fl_Tooltip_H + +#include +#include + +/** + The Fl_Tooltip class provides tooltip support for + all FLTK widgets. It contains only static methods. +*/ +class FL_EXPORT Fl_Tooltip { +public: + /** Gets the tooltip delay. The default delay is 1.0 seconds. */ + static float delay() { return delay_; } + /** Sets the tooltip delay. The default delay is 1.0 seconds. */ + static void delay(float f) { delay_ = f; } + /** + Gets the tooltip hover delay, the delay between tooltips. + The default delay is 0.2 seconds. + */ + static float hoverdelay() { return hoverdelay_; } + /** + Sets the tooltip hover delay, the delay between tooltips. + The default delay is 0.2 seconds. + */ + static void hoverdelay(float f) { hoverdelay_ = f; } + /** Returns non-zero if tooltips are enabled. */ + static int enabled() { return enabled_; } + /** Enables tooltips on all widgets (or disables if b is false). */ + static void enable(int b = 1) { enabled_ = b;} + /** Same as enable(0), disables tooltips on all widgets. */ + static void disable() { enabled_ = 0; } + static void (*enter)(Fl_Widget* w); + static void enter_area(Fl_Widget* w, int X, int Y, int W, int H, const char* tip); + static void (*exit)(Fl_Widget *w); + /** Gets the current widget target */ + static Fl_Widget* current() {return widget_;} + static void current(Fl_Widget*); + + /** Gets the typeface for the tooltip text. */ + static Fl_Font font() { return font_; } + /** Sets the typeface for the tooltip text. */ + static void font(Fl_Font i) { font_ = i; } + /** Gets the size of the tooltip text. */ + static Fl_Fontsize size() { return size_; } + /** Sets the size of the tooltip text. */ + static void size(Fl_Fontsize s) { size_ = s; } + /** Gets the background color for tooltips. The default background color is a pale yellow. */ + static Fl_Color color() { return color_; } + /** Sets the background color for tooltips. The default background color is a pale yellow. */ + static void color(Fl_Color c) { color_ = c; } + /** Gets the color of the text in the tooltip. The default is black. */ + static Fl_Color textcolor() { return textcolor_; } + /** Sets the color of the text in the tooltip. The default is black. */ + static void textcolor(Fl_Color c) { textcolor_ = c; } + + // These should not be public, but Fl_Widget::tooltip() needs them... + // fabien: made it private with only a friend function access +private: + friend void Fl_Widget::tooltip(const char *); + static void enter_(Fl_Widget* w); + static void exit_(Fl_Widget *w); + +private: + static float delay_; //!< delay before a tooltip is shown + static float hoverdelay_; //!< delay between tooltips + static int enabled_; + static Fl_Color color_; + static Fl_Color textcolor_; + static Fl_Font font_; + static Fl_Fontsize size_; + static Fl_Widget* widget_; //!< Keeps track of the current target widget +}; + +#endif + +// +// End of "$Id: Fl_Tooltip.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Tree.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Tree.H new file mode 100644 index 0000000..e6c7b80 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Tree.H @@ -0,0 +1,918 @@ +// +// "$Id: Fl_Tree.H 7903 2010-11-28 21:06:39Z matt $" +// + +#ifndef FL_TREE_H +#define FL_TREE_H + +#include +#include +#include +#include + +#include +#include + +////////////////////// +// FL/Fl_Tree.H +////////////////////// +// +// Fl_Tree -- This file is part of the Fl_Tree widget for FLTK +// Copyright (C) 2009-2010 by Greg Ercolano. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// + +/// +/// \file +/// \brief This file contains the definitions of the Fl_Tree class +/// + +/// \class Fl_Tree +/// +/// \brief Tree widget. +/// +/// \code +/// Fl_Tree // Top level widget +/// |--- Fl_Tree_Item // Items in the tree +/// |--- Fl_Tree_Prefs // Preferences for the tree +/// |--- Fl_Tree_Connector (enum) // Connection modes +/// |--- Fl_Tree_Select (enum) // Selection modes +/// |--- Fl_Tree_Sort (enum) // Sort behavior +/// \endcode +/// +/// An expandable tree widget. +/// +/// Similar to Fl_Browser, Fl_Tree is browser of Fl_Tree_Item's, which can be +/// in a parented hierarchy. Subtrees can be expanded or closed. Items can be +/// added, deleted, inserted, sorted and re-ordered. +/// +/// The tree items may also contain other FLTK widgets, like buttons, input fields, +/// or even "custom" widgets. +/// +/// The callback() is invoked depending on the value of when(): +/// +/// - FL_WHEN_RELEASE -- callback invoked when left mouse button is released on an item +/// - FL_WHEN_CHANGED -- callback invoked when left mouse changes selection state +/// +/// The simple way to define a tree: +/// \code +/// #include +/// [..] +/// Fl_Tree tree(X,Y,W,H); +/// tree.begin(); +/// tree.add("Flintstones/Fred"); +/// tree.add("Flintstones/Wilma"); +/// tree.add("Flintstones/Pebbles"); +/// tree.add("Simpsons/Homer"); +/// tree.add("Simpsons/Marge"); +/// tree.add("Simpsons/Bart"); +/// tree.add("Simpsons/Lisa"); +/// tree.end(); +/// \endcode +/// +/// Items can be added with add(), +/// removed with remove(), +/// completely cleared with clear(), +/// inserted with insert() and insert_above(), +/// selected/deselected with select() and deselect(), +/// open/closed with open() and closed(). +/// Children of an item can be swapped around with Fl_Tree_Item::swap_children(), +/// sorting can be controlled when items are add()ed via sortorder(). +/// You can walk the entire tree with first() and next(). +/// You can walk selected items with first_selected_item() and +/// next_selected_item(). +/// Items can be found by their pathname using find_item(const char*), +/// and an item's pathname can be found with item_pathname(). +/// +/// The tree can have different selection behaviors controlled by selectmode(). +/// +/// FLTK widgets (including custom widgets) can be assigned to tree items via +/// Fl_Tree_Item::widget(). +/// +/// Icons for individual items can be changed with +/// Fl_Tree_Item::openicon(), +/// Fl_Tree_Item::closeicon(), +/// Fl_Tree_Item::usericon(). +/// +/// Various default preferences can be globally manipulated via Fl_Tree_Prefs, +/// including colors, margins, icons, connection lines. +/// +/// The tree's callback() will be invoked when items change state or are open/closed. +/// when() controls when mouse/keyboard events invoke the callback. +/// callback_item() and callback_reason() can be used to determine the cause of the callback. +/// +/// \image html tree-elements.png +/// + +/// \enum Fl_Tree_Reason +/// The reason the callback was invoked. +/// +enum Fl_Tree_Reason { + FL_TREE_REASON_NONE=0, ///< unknown reason + FL_TREE_REASON_SELECTED, ///< an item was selected + FL_TREE_REASON_DESELECTED, ///< an item was de-selected + FL_TREE_REASON_OPENED, ///< an item was opened + FL_TREE_REASON_CLOSED ///< an item was closed +}; + + +class FL_EXPORT Fl_Tree : public Fl_Group { + Fl_Tree_Item *_root; // can be null! + Fl_Tree_Item *_item_focus; // item that has focus box + Fl_Tree_Item *_callback_item; // item invoked during callback (can be NULL) + Fl_Tree_Reason _callback_reason; // reason for the callback + Fl_Tree_Prefs _prefs; // all the tree's settings + int _scrollbar_size; // size of scrollbar trough + +protected: + /// Vertical scrollbar + Fl_Scrollbar *_vscroll; + +protected: + void item_clicked(Fl_Tree_Item* val); + /// Do the callback for the item, setting the item and reason + void do_callback_for_item(Fl_Tree_Item* item, Fl_Tree_Reason reason) { + callback_reason(reason); + callback_item(item); + do_callback((Fl_Widget*)this, user_data()); + } + Fl_Tree_Item *next_visible_item(Fl_Tree_Item *start, int dir); + +public: + Fl_Tree(int X, int Y, int W, int H, const char *L=0); + ~Fl_Tree(); + int handle(int e); + void draw(); + + /////////////////////// + // root methods + /////////////////////// + + /// Set the label for the root item. + /// + /// Makes an internally managed copy of 'new_label'. + /// + void root_label(const char *new_label) { + if ( ! _root ) return; + _root->label(new_label); + } + /// Returns the root item. + Fl_Tree_Item* root() { + return(_root); + } + + //////////////////////////////// + // Item creation/removal methods + //////////////////////////////// + Fl_Tree_Item *add(const char *path); + Fl_Tree_Item* add(Fl_Tree_Item *item, const char *name); + Fl_Tree_Item *insert_above(Fl_Tree_Item *above, const char *name); + Fl_Tree_Item* insert(Fl_Tree_Item *item, const char *name, int pos); + + /// Remove the specified \p item from the tree. + /// If it has children, all those are removed too. + /// \returns 0 if done, -1 if 'item' not found. + /// + int remove(Fl_Tree_Item *item) { + if ( !item ) return(0); + if ( item == _root ) { + clear(); + } else { + Fl_Tree_Item *parent = item->parent(); // find item's parent + if ( ! parent ) return(-1); + parent->remove_child(item); // remove child + children + } + return(0); + } + /// Clear all children from the tree. + /// The tree will be left completely empty. + /// + void clear() { + if ( ! _root ) return; + _root->clear_children(); + delete _root; _root = 0; + } + /// Clear all the children of a particular node in the tree specified by \p item. + void clear_children(Fl_Tree_Item *item) { + if ( item->has_children() ) { + item->clear_children(); + redraw(); // redraw only if there were children to clear + } + } + + //////////////////////// + // Item lookup methods + //////////////////////// + Fl_Tree_Item *find_item(const char *path); + const Fl_Tree_Item *find_item(const char *path) const; + int item_pathname(char *pathname, int pathnamelen, const Fl_Tree_Item *item) const; + + const Fl_Tree_Item *find_clicked() const; + + /// Return the item that was last clicked. + /// + /// Valid only from within the callback(). + /// + /// Deprecated: use callback_item() instead. + /// + /// \returns the item clicked, or 0 if none. + /// 0 may also be used to indicate several items were clicked/changed. + /// + Fl_Tree_Item *item_clicked() { + return(_callback_item); + } + Fl_Tree_Item *first(); + Fl_Tree_Item *next(Fl_Tree_Item *item=0); + Fl_Tree_Item *prev(Fl_Tree_Item *item=0); + Fl_Tree_Item *last(); + Fl_Tree_Item *first_selected_item(); + Fl_Tree_Item *next_selected_item(Fl_Tree_Item *item=0); + + ////////////////////////// + // Item open/close methods + ////////////////////////// + + /// Open the specified 'item'. + /// This causes the item's children (if any) to be shown. + /// Handles redrawing if anything was actually changed. + /// Invokes the callback depending on the value of optional parameter \p docallback. + /// + /// The callback can use callback_item() and callback_reason() respectively to determine + /// the item changed and the reason the callback was called. + /// + /// \param[in] item -- the item to be opened + /// \param[in] docallback -- A flag that determines if the callback() is invoked or not: + /// - 0 - callback() is not invoked + /// - 1 - callback() is invoked if item changed, + /// callback_reason() will be FL_TREE_REASON_OPENED + /// + /// \returns + /// - 1 -- item was opened + /// - 0 -- item was already open, no change + /// + /// \see open(), close(), is_open(), is_close(), callback_item(), callback_reason() + /// + int open(Fl_Tree_Item *item, int docallback=1) { + if ( item->is_open() ) return(0); + item->open(); + redraw(); + if ( docallback ) { + do_callback_for_item(item, FL_TREE_REASON_OPENED); + } + return(1); + } + /// Opens the item specified by \p path (eg: "Parent/child/item"). + /// This causes the item's children (if any) to be shown. + /// Handles redrawing if anything was actually changed. + /// Invokes the callback depending on the value of optional parameter \p docallback. + /// + /// The callback can use callback_item() and callback_reason() respectively to determine + /// the item changed and the reason the callback was called. + /// + /// \param[in] path -- the tree item's pathname (eg. "Flintstones/Fred") + /// \param[in] docallback -- A flag that determines if the callback() is invoked or not: + /// - 0 - callback() is not invoked + /// - 1 - callback() is invoked if item changed, + /// callback_reason() will be FL_TREE_REASON_OPENED + /// + /// \returns + /// - 1 -- OK: item opened + /// - 0 -- OK: item was already open, no change + /// - -1 -- ERROR: item was not found + /// + /// \see open(), close(), is_open(), is_close(), callback_item(), callback_reason() + /// + int open(const char *path, int docallback=1) { + Fl_Tree_Item *item = find_item(path); + if ( ! item ) return(-1); + return(open(item, docallback)); + } + /// Toggle the open state of \p item. + /// Handles redrawing if anything was actually changed. + /// Invokes the callback depending on the value of optional parameter \p docallback. + /// + /// The callback can use callback_item() and callback_reason() respectively to determine + /// the item changed and the reason the callback was called. + /// + /// \param[in] item -- the item to be opened + /// \param[in] docallback -- A flag that determines if the callback() is invoked or not: + /// - 0 - callback() is not invoked + /// - 1 - callback() is invoked, callback_reason() will be either + /// FL_TREE_REASON_OPENED or FL_TREE_REASON_CLOSED + /// + /// \see open(), close(), is_open(), is_close(), callback_item(), callback_reason() + /// + void open_toggle(Fl_Tree_Item *item, int docallback=1) { + if ( item->is_open() ) { + close(item, docallback); + } else { + open(item, docallback); + } + } + /// Closes the specified \p item. + /// Handles redrawing if anything was actually changed. + /// Invokes the callback depending on the value of optional parameter \p docallback. + /// + /// The callback can use callback_item() and callback_reason() respectively to determine + /// the item changed and the reason the callback was called. + /// + /// \param[in] item -- the item to be closed + /// \param[in] docallback -- A flag that determines if the callback() is invoked or not: + /// - 0 - callback() is not invoked + /// - 1 - callback() is invoked if item changed, + /// callback_reason() will be FL_TREE_REASON_CLOSED + /// + /// \returns + /// - 1 -- item was closed + /// - 0 -- item was already closed, no change + /// + /// \see open(), close(), is_open(), is_close(), callback_item(), callback_reason() + /// + int close(Fl_Tree_Item *item, int docallback=1) { + if ( item->is_close() ) return(0); + item->close(); + redraw(); + if ( docallback ) { + do_callback_for_item(item, FL_TREE_REASON_CLOSED); + } + return(1); + } + /// Closes the item specified by \p path, eg: "Parent/child/item". + /// Handles redrawing if anything was actually changed. + /// Invokes the callback depending on the value of optional parameter \p docallback. + /// + /// The callback can use callback_item() and callback_reason() respectively to determine + /// the item changed and the reason the callback was called. + /// + /// \param[in] path -- the tree item's pathname (eg. "Flintstones/Fred") + /// \param[in] docallback -- A flag that determines if the callback() is invoked or not: + /// - 0 - callback() is not invoked + /// - 1 - callback() is invoked if item changed, + /// callback_reason() will be FL_TREE_REASON_CLOSED + /// + /// \returns + /// - 1 -- OK: item closed + /// - 0 -- OK: item was already closed, no change + /// - -1 -- ERROR: item was not found + /// + /// \see open(), close(), is_open(), is_close(), callback_item(), callback_reason() + /// + int close(const char *path, int docallback=1) { + Fl_Tree_Item *item = find_item(path); + if ( ! item ) return(-1); + return(close(item, docallback)); + } + /// See if \p item is open. + /// + /// Items that are 'open' are themselves not necessarily visible; + /// one of the item's parents might be closed. + /// + /// \param[in] item -- the item to be tested + /// + /// \returns + /// - 1 : item is open + /// - 0 : item is closed + /// + int is_open(Fl_Tree_Item *item) const { + return(item->is_open()?1:0); + } + /// See if item specified by \p path (eg: "Parent/child/item") is open. + /// + /// Items that are 'open' are themselves not necessarily visible; + /// one of the item's parents might be closed. + /// + /// \param[in] path -- the tree item's pathname (eg. "Flintstones/Fred") + /// + /// \returns + /// - 1 - OK: item is open + /// - 0 - OK: item is closed + /// - -1 - ERROR: item was not found + /// + int is_open(const char *path) const { + const Fl_Tree_Item *item = find_item(path); + if ( ! item ) return(-1); + return(item->is_open()?1:0); + } + /// See if the specified \p item is closed. + /// + /// \param[in] item -- the item to be tested + /// + /// \returns + /// - 1 : item is open + /// - 0 : item is closed + /// + int is_close(Fl_Tree_Item *item) const { + return(item->is_close()); + } + /// See if item specified by \p path (eg: "Parent/child/item") is closed. + /// + /// \param[in] path -- the tree item's pathname (eg. "Flintstones/Fred") + /// + /// \returns + /// - 1 - OK: item is closed + /// - 0 - OK: item is open + /// - -1 - ERROR: item was not found + /// + int is_close(const char *path) const { + const Fl_Tree_Item *item = find_item(path); + if ( ! item ) return(-1); + return(item->is_close()?1:0); + } + + /// Select the specified \p item. Use 'deselect()' to de-select it. + /// Handles redrawing if anything was actually changed. + /// Invokes the callback depending on the value of optional parameter \p docallback. + /// + /// The callback can use callback_item() and callback_reason() respectively to determine + /// the item changed and the reason the callback was called. + /// + /// \param[in] item -- the item to be selected + /// \param[in] docallback -- A flag that determines if the callback() is invoked or not: + /// - 0 - the callback() is not invoked + /// - 1 - the callback() is invoked if item changed state, + /// callback_reason() will be FL_TREE_REASON_SELECTED + /// + /// \returns + /// - 1 - item's state was changed + /// - 0 - item was already selected, no change was made + /// + int select(Fl_Tree_Item *item, int docallback=1) { + if ( ! item->is_selected() ) { + item->select(); + set_changed(); + if ( docallback ) { + do_callback_for_item(item, FL_TREE_REASON_SELECTED); + } + redraw(); + return(1); + } + return(0); + } + /// Select the item specified by \p path (eg: "Parent/child/item"). + /// Handles redrawing if anything was actually changed. + /// Invokes the callback depending on the value of optional parameter \p docallback. + /// + /// The callback can use callback_item() and callback_reason() respectively to determine + /// the item changed and the reason the callback was called. + /// + /// \param[in] path -- the tree item's pathname (eg. "Flintstones/Fred") + /// \param[in] docallback -- A flag that determines if the callback() is invoked or not: + /// - 0 - the callback() is not invoked + /// - 1 - the callback() is invoked if item changed state, + /// callback_reason() will be FL_TREE_REASON_SELECTED + /// + /// \returns + /// - 1 : OK: item's state was changed + /// - 0 : OK: item was already selected, no change was made + /// - -1 : ERROR: item was not found + /// + int select(const char *path, int docallback=1) { + Fl_Tree_Item *item = find_item(path); + if ( ! item ) return(-1); + return(select(item, docallback)); + } + /// Toggle the select state of the specified \p item. + /// Handles redrawing if anything was actually changed. + /// Invokes the callback depending on the value of optional parameter \p docallback. + /// + /// The callback can use callback_item() and callback_reason() respectively to determine + /// the item changed and the reason the callback was called. + /// + /// \param[in] item -- the item to be selected + /// \param[in] docallback -- A flag that determines if the callback() is invoked or not: + /// - 0 - the callback() is not invoked + /// - 1 - the callback() is invoked, callback_reason() will be + /// either FL_TREE_REASON_SELECTED or FL_TREE_REASON_DESELECTED + /// + void select_toggle(Fl_Tree_Item *item, int docallback=1) { + item->select_toggle(); + set_changed(); + if ( docallback ) { + do_callback_for_item(item, item->is_selected() ? FL_TREE_REASON_SELECTED + : FL_TREE_REASON_DESELECTED); + } + redraw(); + } + /// De-select the specified \p item. + /// Handles redrawing if anything was actually changed. + /// Invokes the callback depending on the value of optional parameter \p docallback. + /// + /// The callback can use callback_item() and callback_reason() respectively to determine + /// the item changed and the reason the callback was called. + /// + /// \param[in] item -- the item to be selected + /// \param[in] docallback -- A flag that determines if the callback() is invoked or not: + /// - 0 - the callback() is not invoked + /// - 1 - the callback() is invoked if item changed state, + /// callback_reason() will be FL_TREE_REASON_DESELECTED + /// + /// \returns + /// - 0 - item was already deselected, no change was made + /// - 1 - item's state was changed + /// + int deselect(Fl_Tree_Item *item, int docallback=1) { + if ( item->is_selected() ) { + item->deselect(); + set_changed(); + if ( docallback ) { + do_callback_for_item(item, FL_TREE_REASON_DESELECTED); + } + redraw(); + return(1); + } + return(0); + } + /// Deselect an item specified by \p path (eg: "Parent/child/item"). + /// Handles redrawing if anything was actually changed. + /// Invokes the callback depending on the value of optional parameter \p docallback. + /// + /// The callback can use callback_item() and callback_reason() respectively to determine + /// the item changed and the reason the callback was called. + /// + /// \param[in] path -- the tree item's pathname (eg. "Flintstones/Fred") + /// \param[in] docallback -- A flag that determines if the callback() is invoked or not: + /// - 0 - the callback() is not invoked + /// - 1 - the callback() is invoked if item changed state, + /// callback_reason() will be FL_TREE_REASON_DESELECTED + /// + /// \returns + /// - 1 - OK: item's state was changed + /// - 0 - OK: item was already deselected, no change was made + /// - -1 - ERROR: item was not found + /// + int deselect(const char *path, int docallback=1) { + Fl_Tree_Item *item = find_item(path); + if ( ! item ) return(-1); + return(deselect(item, docallback)); + } + + int deselect_all(Fl_Tree_Item *item=0, int docallback=1); + int select_only(Fl_Tree_Item *selitem, int docallback=1); + int select_all(Fl_Tree_Item *item=0, int docallback=1); + void set_item_focus(Fl_Tree_Item *o); + + /// See if the specified \p item is selected. + /// + /// \param[in] item -- the item to be tested + /// + /// \return + /// - 1 : item selected + /// - 0 : item deselected + /// + int is_selected(Fl_Tree_Item *item) const { + return(item->is_selected()?1:0); + } + /// See if item specified by \p path (eg: "Parent/child/item") is selected. + /// + /// \param[in] path -- the tree item's pathname (eg. "Flintstones/Fred") + /// + /// \returns + /// - 1 : item selected + /// - 0 : item deselected + /// - -1 : item was not found + /// + int is_selected(const char *path) { + Fl_Tree_Item *item = find_item(path); + if ( ! item ) return(-1); + return(is_selected(item)); + } + /// Print the tree as 'ascii art' to stdout. + /// Used mainly for debugging. + /// + void show_self() { + if ( ! _root ) return; + _root->show_self(); + } + + ///////////////////////////////// + // Item attribute related methods + ///////////////////////////////// + + /// Get the default label fontsize used for creating new items. + int labelsize() const { + return(_prefs.labelsize()); + } + /// Set the default label font size used for creating new items. + /// To change the font size on a per-item basis, use Fl_Tree_Item::labelsize(int) + /// + void labelsize(int val) { + _prefs.labelsize(val); + } + + /// Get the default font face used for item's labels when new items are created. + /// + /// Don't use this if you want to change an existing label() size; use + /// item->labelfont() instead. + /// + int labelfont() const { + return(_prefs.labelfont()); + } + /// Set the default font face used for item's labels when new items are created. + /// + /// Don't use this if you want to change an existing label() size; use + /// item->labelfont(int) instead. + /// + void labelfont(int val) { + _prefs.labelfont(val); + } + /// Get the amount of white space (in pixels) that should appear + /// between the widget's left border and the tree's contents. + /// + int marginleft() const { + return(_prefs.marginleft()); + } + /// Set the amount of white space (in pixels) that should appear + /// between the widget's left border and the left side of the tree's contents. + /// + void marginleft(int val) { + _prefs.marginleft(val); + redraw(); + } + /// Get the amount of white space (in pixels) that should appear + /// between the widget's top border and the top of the tree's contents. + /// + int margintop() const { + return(_prefs.margintop()); + } + /// Sets the amount of white space (in pixels) that should appear + /// between the widget's top border and the top of the tree's contents. + /// + void margintop(int val) { + _prefs.margintop(val); + redraw(); + } + /// Get the amount of white space (in pixels) that should appear + /// below an open child tree's contents. + /// + int openchild_marginbottom() const { + return(_prefs.openchild_marginbottom()); + } + /// Set the amount of white space (in pixels) that should appear + /// below an open child tree's contents. + /// + void openchild_marginbottom(int val) { + _prefs.openchild_marginbottom(val); + redraw(); + } + /// Gets the width of the horizontal connection lines (in pixels) + /// that appear to the left of each tree item's label. + /// + int connectorwidth() const { + return(_prefs.connectorwidth()); + } + /// Sets the width of the horizontal connection lines (in pixels) + /// that appear to the left of each tree item's label. + /// + void connectorwidth(int val) { + _prefs.connectorwidth(val); + redraw(); + } + /// Returns the Fl_Image being used as the default user icon for newly created items. + /// Returns zero if no icon has been set, which is the default. + /// + Fl_Image *usericon() const { + return(_prefs.usericon()); + } + /// Sets the Fl_Image to be used as the default user icon for all + /// newly created items. + /// + /// If you want to specify user icons on a per-item basis, + /// use Fl_Tree_Item::usericon() instead. + /// + /// \param[in] val -- The new image to be used, or + /// zero to disable user icons. + /// + void usericon(Fl_Image *val) { + _prefs.usericon(val); + redraw(); + } + /// Returns the icon to be used as the 'open' icon. + /// If none was set, the internal default is returned, + /// a simple '[+]' icon. + /// + Fl_Image *openicon() const { + return(_prefs.openicon()); + } + /// Sets the icon to be used as the 'open' icon. + /// This overrides the built in default '[+]' icon. + /// + /// \param[in] val -- The new image, or zero to use the default [+] icon. + /// + void openicon(Fl_Image *val) { + _prefs.openicon(val); + redraw(); + } + /// Returns the icon to be used as the 'close' icon. + /// If none was set, the internal default is returned, + /// a simple '[-]' icon. + /// + Fl_Image *closeicon() const { + return(_prefs.closeicon()); + } + /// Sets the icon to be used as the 'close' icon. + /// This overrides the built in default '[-]' icon. + /// + /// \param[in] val -- The new image, or zero to use the default [-] icon. + /// + void closeicon(Fl_Image *val) { + _prefs.closeicon(val); + redraw(); + } + /// Returns 1 if the collapse icon is enabled, 0 if not. + int showcollapse() const { + return(_prefs.showcollapse()); + } + /// Set if we should show the collapse icon or not. + /// If collapse icons are disabled, the user will not be able + /// to interactively collapse items in the tree, unless the application + /// provides some other means via open() and close(). + /// + /// \param[in] val 1: shows collapse icons (default),\n + /// 0: hides collapse icons. + /// + void showcollapse(int val) { + _prefs.showcollapse(val); + redraw(); + } + /// Returns 1 if the root item is to be shown, or 0 if not. + int showroot() const { + return(_prefs.showroot()); + } + /// Set if the root item should be shown or not. + /// \param[in] val 1 -- show the root item (default)\n + /// 0 -- hide the root item. + /// + void showroot(int val) { + _prefs.showroot(val); + redraw(); + } + /// Returns the line drawing style for inter-connecting items. + Fl_Tree_Connector connectorstyle() const { + return(_prefs.connectorstyle()); + } + /// Sets the line drawing style for inter-connecting items. + void connectorstyle(Fl_Tree_Connector val) { + _prefs.connectorstyle(val); + redraw(); + } + /// Set the default sort order used when items are added to the tree. + /// See Fl_Tree_Sort for possible values. + /// + Fl_Tree_Sort sortorder() const { + return(_prefs.sortorder()); + } + /// Gets the sort order used to add items to the tree. + void sortorder(Fl_Tree_Sort val) { + _prefs.sortorder(val); + // no redraw().. only affects new add()itions + } + /// Sets the style of box used to draw selected items. + /// This is an fltk Fl_Boxtype. + /// The default is influenced by FLTK's current Fl::scheme() + /// + Fl_Boxtype selectbox() const { + return(_prefs.selectbox()); + } + /// Gets the style of box used to draw selected items. + /// This is an fltk Fl_Boxtype. + /// The default is influenced by FLTK's current Fl::scheme() + /// + void selectbox(Fl_Boxtype val) { + _prefs.selectbox(val); + redraw(); + } + /// Gets the tree's current selection mode. + Fl_Tree_Select selectmode() const { + return(_prefs.selectmode()); + } + /// Sets the tree's selection mode. + void selectmode(Fl_Tree_Select val) { + _prefs.selectmode(val); + } + int displayed(Fl_Tree_Item *item); + void show_item(Fl_Tree_Item *item, int yoff); + void show_item(Fl_Tree_Item *item); + void show_item_bottom(Fl_Tree_Item *item); + void show_item_middle(Fl_Tree_Item *item); + void show_item_top(Fl_Tree_Item *item); + void display(Fl_Tree_Item *item); + int vposition() const; + void vposition(int ypos); + + /// See if widget \p w is one of the Fl_Tree widget's scrollbars. + /// Use this to skip over the scrollbars when walking the child() array. Example: + /// \code + /// for ( int i=0; ichildren(); i++ ) { // walk children + /// Fl_Widget *w= tree->child(i); + /// if ( brow->is_scrollbar(w) ) continue; // skip scrollbars + /// ..do work here.. + /// } + /// \endcode + /// \param[in] w Widget to test + /// \returns 1 if \p w is a scrollbar, 0 if not. + /// + int is_scrollbar(Fl_Widget *w) { + return( ( w == _vscroll ) ? 1 : 0 ); + } + /// Gets the current size of the scrollbars' troughs, in pixels. + /// + /// If this value is zero (default), this widget will use the global + /// Fl::scrollbar_size() value as the scrollbar's width. + /// + /// \returns Scrollbar size in pixels, or 0 if the global Fl::scrollsize() is being used. + /// \see Fl::scrollbar_size(int) + /// + int scrollbar_size() const { + return(_scrollbar_size); + } + /// Sets the pixel size of the scrollbars' troughs to the \p size, in pixels. + /// + /// Normally you should not need this method, and should use the global + /// Fl::scrollbar_size(int) instead to manage the size of ALL + /// your widgets' scrollbars. This ensures your application + /// has a consistent UI, is the default behavior, and is normally + /// what you want. + /// + /// Only use THIS method if you really need to override the global + /// scrollbar size. The need for this should be rare. + /// + /// Setting \p size to the special value of 0 causes the widget to + /// track the global Fl::scrollbar_size(), which is the default. + /// + /// \param[in] size Sets the scrollbar size in pixels.\n + /// If 0 (default), scrollbar size tracks the global Fl::scrollbar_size() + /// \see Fl::scrollbar_size() + /// + void scrollbar_size(int size) { + _scrollbar_size = size; + int scrollsize = _scrollbar_size ? _scrollbar_size : Fl::scrollbar_size(); + if ( _vscroll->w() != scrollsize ) { + _vscroll->resize(x()+w()-scrollsize, h(), scrollsize, _vscroll->h()); + } + } + + /////////////////////// + // callback related + /////////////////////// + + /// Sets the item that was changed for this callback. + /// Used internally to pass the item that invoked the callback. + /// + void callback_item(Fl_Tree_Item* item) { + _callback_item = item; + } + /// Gets the item that caused the callback. + /// The callback() can use this value to see which item changed. + /// + Fl_Tree_Item* callback_item() { + return(_callback_item); + } + /// Sets the reason for this callback. + /// Used internally to pass the reason the callback was invoked. + /// + void callback_reason(Fl_Tree_Reason reason) { + _callback_reason = reason; + } + /// Gets the reason for this callback. + /// + /// The callback() can use this value to see why it was called. Example: + /// \code + /// void MyTreeCallback(Fl_Widget *w, void *userdata) { + /// Fl_Tree *tree = (Fl_Tree*)w; + /// Fl_Tree_Item *item = tree->callback_item(); // the item changed (can be NULL if more than one item was changed!) + /// switch ( tree->callback_reason() ) { // reason callback was invoked + /// case FL_TREE_REASON_OPENED: ..item was opened.. + /// case FL_TREE_REASON_CLOSED: ..item was closed.. + /// case FL_TREE_REASON_SELECTED: ..item was selected.. + /// case FL_TREE_REASON_DESELECTED: ..item was deselected.. + /// } + /// } + /// \endcode + /// + Fl_Tree_Reason callback_reason() const { + return(_callback_reason); + } + + /// Load FLTK preferences + void load(class Fl_Preferences&); +}; + +#endif /*FL_TREE_H*/ + +// +// End of "$Id: Fl_Tree.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Tree_Item.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Tree_Item.H new file mode 100644 index 0000000..0b4eb1f --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Tree_Item.H @@ -0,0 +1,337 @@ +// +// "$Id: Fl_Tree_Item.H 7903 2010-11-28 21:06:39Z matt $" +// + +#ifndef FL_TREE_ITEM_H +#define FL_TREE_ITEM_H + +#include +#include +#include +#include + +#include +#include + +////////////////////// +// FL/Fl_Tree_Item.H +////////////////////// +// +// Fl_Tree -- This file is part of the Fl_Tree widget for FLTK +// Copyright (C) 2009-2010 by Greg Ercolano. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// + +/// +/// \file +/// \brief This file contains the definitions for Fl_Tree_Item +/// + +/// \brief Tree item +/// +/// This class is a single tree item, and manages all of the item's attributes. +/// Fl_Tree_Item is used by Fl_Tree, which is comprised of many instances of Fl_Tree_Item. +/// +/// Fl_Tree_Item is hierarchical; it dynamically manages an Fl_Tree_Item_Array of children +/// that are themselves instances of Fl_Tree_Item. Each item can have zero or more children. +/// When an item has children, close() and open() can be used to hide or show them. +/// +/// Items have their own attributes; font size, face, color. +/// Items maintain their own hierarchy of children. +/// +/// When you make changes to items, you'll need to tell the tree to redraw() +/// for the changes to show up. +/// +class FL_EXPORT Fl_Tree_Item { + const char *_label; // label (memory managed) + int _labelfont; // label's font face + int _labelsize; // label's font size + Fl_Color _labelfgcolor; // label's fg color + Fl_Color _labelbgcolor; // label's bg color + char _open; // item is open? + char _visible; // item is visible? + char _active; // item activated? + char _selected; // item selected? + int _xywh[4]; // xywh of this widget (if visible) + int _collapse_xywh[4]; // xywh of collapse icon (if any) + int _label_xywh[4]; // xywh of label + Fl_Widget *_widget; // item's label widget (optional) + Fl_Image *_usericon; // item's user-specific icon (optional) + Fl_Tree_Item_Array _children; // array of child items + Fl_Tree_Item *_parent; // parent item (=0 if root) + void *_userdata; // user data that can be associated with an item +protected: + void show_widgets(); + void hide_widgets(); + void draw_vertical_connector(int x, int y1, int y2, const Fl_Tree_Prefs &prefs); + void draw_horizontal_connector(int x1, int x2, int y, const Fl_Tree_Prefs &prefs); +public: + Fl_Tree_Item(const Fl_Tree_Prefs &prefs); // CTOR + ~Fl_Tree_Item(); // DTOR + Fl_Tree_Item(const Fl_Tree_Item *o); // COPY CTOR + int x() const { return(_xywh[0]); } + int y() const { return(_xywh[1]); } + int w() const { return(_xywh[2]); } + int h() const { return(_xywh[3]); } + void draw(int X, int &Y, int W, Fl_Widget *tree, Fl_Tree_Item *itemfocus, const Fl_Tree_Prefs &prefs, int lastchild=1); + void show_self(const char *indent = "") const; + void label(const char *val); + const char *label() const; + + /// Set a user-data value for the item. + inline void user_data( void* data ) { _userdata = data; } + + /// Retrieve the user-data value that has been assigned to the item. + inline void* user_data() const { return _userdata; } + + /// Set item's label font face. + void labelfont(int val) { + _labelfont = val; + } + /// Get item's label font face. + int labelfont() const { + return(_labelfont); + } + /// Set item's label font size. + void labelsize(int val) { + _labelsize = val; + } + /// Get item's label font size. + int labelsize() const { + return(_labelsize); + } + /// Set item's label foreground text color. + void labelfgcolor(Fl_Color val) { + _labelfgcolor = val; + } + /// Set item's label text color. + void labelcolor(Fl_Color val) { + _labelfgcolor = val; + } + /// Return item's label text color. + Fl_Color labelcolor() const { + return(_labelfgcolor); + } + /// Return item's label foreground text color. + Fl_Color labelfgcolor() const { + return(_labelfgcolor); + } + /// Set item's label background color. + void labelbgcolor(Fl_Color val) { + _labelbgcolor = val; + } + /// Return item's background text color. + Fl_Color labelbgcolor() const { + return(_labelbgcolor); + } + /// Assign an FLTK widget to this item. + void widget(Fl_Widget *val) { + _widget = val; + } + /// Return FLTK widget assigned to this item. + Fl_Widget *widget() const { + return(_widget); + } + /// Return the number of children this item has. + int children() const { + return(_children.total()); + } + /// Return the child item for the given 'index'. + Fl_Tree_Item *child(int index) { + return(_children[index]); + } + /// Return the const child item for the given 'index'. + const Fl_Tree_Item *child(int t) const; + /// See if this item has children. + int has_children() const { + return(children()); + } + int find_child(const char *name); + int find_child(Fl_Tree_Item *item); + int remove_child(Fl_Tree_Item *item); + int remove_child(const char *new_label); + void clear_children(); + void swap_children(int ax, int bx); + int swap_children(Fl_Tree_Item *a, Fl_Tree_Item *b); + const Fl_Tree_Item *find_child_item(char **arr) const; // const + Fl_Tree_Item *find_child_item(char **arr); // non-const + const Fl_Tree_Item *find_item(char **arr) const; // const + Fl_Tree_Item *find_item(char **arr); // non-const + ////////////////// + // Adding items + ////////////////// + Fl_Tree_Item *add(const Fl_Tree_Prefs &prefs, const char *new_label); + Fl_Tree_Item *add(const Fl_Tree_Prefs &prefs, char **arr); + Fl_Tree_Item *insert(const Fl_Tree_Prefs &prefs, const char *new_label, int pos=0); + Fl_Tree_Item *insert_above(const Fl_Tree_Prefs &prefs, const char *new_label); + int depth() const; + Fl_Tree_Item *prev(); + Fl_Tree_Item *next(); + Fl_Tree_Item *next_sibling(); + Fl_Tree_Item *prev_sibling(); + Fl_Tree_Item *next_displayed(Fl_Tree_Prefs &prefs); + Fl_Tree_Item *prev_displayed(Fl_Tree_Prefs &prefs); + + /// Return the parent for this item. Returns NULL if we are the root. + Fl_Tree_Item *parent() { + return(_parent); + } + /// Return the const parent for this item. Returns NULL if we are the root. + const Fl_Tree_Item *parent() const { + return(_parent); + } + /// Set the parent for this item. + /// Should only be used by Fl_Tree's internals. + /// + void parent(Fl_Tree_Item *val) { + _parent = val; + } + ////////////////// + // State + ////////////////// + void open(); + void close(); + /// See if the item is 'open'. + int is_open() const { + return(_open?1:0); + } + /// See if the item is 'closed'. + int is_close() const { + return(_open?0:1); + } + /// Toggle the item's open/closed state. + void open_toggle() { + _open?close():open(); + } + /// Change the item's selection state to the optionally specified 'val'. + /// If 'val' is not specified, the item will be selected. + /// + void select(int val=1) { + _selected = val; + } + /// Toggle the item's selection state. + void select_toggle() { + if ( is_selected() ) { + deselect(); // deselect if selected + } else { + select(); // select if deselected + } + } + /// Select self and all children + /// Returns count of how many items were in the 'deselected' state, + /// ie. how many items were "changed". + /// + int select_all() { + int count = 0; + if ( ! is_selected() ) { + select(); + ++count; + } + for ( int t=0; tselect_all(); + } + return(count); + } + /// Disable the item's selection state. + void deselect() { + _selected = 0; + } + /// Deselect self and all children + /// Returns count of how many items were in the 'selected' state, + /// ie. how many items were "changed". + /// + int deselect_all() { + int count = 0; + if ( is_selected() ) { + deselect(); + ++count; + } + for ( int t=0; tdeselect_all(); + } + return(count); + } + /// See if the item is selected. + char is_selected() const { + return(_selected); + } + /// Change the item's activation state to the optionally specified 'val'. + /// + /// When deactivated, the item will be 'grayed out'; the callback() + /// won't be invoked if the user clicks on the label. If the item + /// has a widget() associated with the item, its activation state + /// will be changed as well. + /// + /// If 'val' is not specified, the item will be activated. + /// + void activate(int val=1) { + _active = val; + if ( _widget && val != (int)_widget->active() ) { + if ( val ) { + _widget->activate(); + } else { + _widget->deactivate(); + } + _widget->redraw(); + } + } + /// Deactivate the item; the callback() won't be invoked when clicked. + /// Same as activate(0) + /// + void deactivate() { + activate(0); + } + /// See if the item is activated. + char is_activated() const { + return(_active); + } + /// See if the item is activated. + char is_active() const { + return(_active); + } + /// See if the item is visible. + int visible() const { + return(_visible ? 1 : 0); + } + int visible_r() const; + + /// Set the user icon's image. '0' will disable. + void usericon(Fl_Image *val) { + _usericon = val; + } + /// Get the user icon. Returns '0' if disabled. + Fl_Image *usericon() const { + return(_usericon); + } + ////////////////// + // Events + ////////////////// + const Fl_Tree_Item *find_clicked(const Fl_Tree_Prefs &prefs) const; + Fl_Tree_Item *find_clicked(const Fl_Tree_Prefs &prefs); + int event_on_collapse_icon(const Fl_Tree_Prefs &prefs) const; + int event_on_label(const Fl_Tree_Prefs &prefs) const; + /// Is this item the root of the tree? + int is_root() const { + return(_parent==0?1:0); + } +}; + +#endif /*FL_TREE_ITEM_H*/ + +// +// End of "$Id: Fl_Tree_Item.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Tree_Item_Array.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Tree_Item_Array.H new file mode 100644 index 0000000..5a91dee --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Tree_Item_Array.H @@ -0,0 +1,90 @@ +// +// "$Id: Fl_Tree_Item_Array.H 7903 2010-11-28 21:06:39Z matt $" +// + +#ifndef _FL_TREE_ITEM_ARRAY_H +#define _FL_TREE_ITEM_ARRAY_H + +#include "Fl_Export.H" + +class FL_EXPORT Fl_Tree_Item; // forward decl must *precede* first doxygen comment block + // or doxygen will not document our class.. + +////////////////////////// +// FL/Fl_Tree_Item_Array.H +////////////////////////// +// +// Fl_Tree -- This file is part of the Fl_Tree widget for FLTK +// Copyright (C) 2009-2010 by Greg Ercolano. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// + +/// +/// \file +/// \brief This file defines a class that manages an array of Fl_Tree_Item pointers. +/// + +/// \brief Manages an array of Fl_Tree_Item pointers. +/// +/// Because FLTK 1.x.x. has mandated that templates and STL not be used, +/// we use this class to dynamically manage the arrays. +/// +/// None of the methods do range checking on index values; the caller +/// must be sure that index values are within the range 0There are probably more of these classes in FLTK than any others: +

\image html valuators.gif

+ \image latex valuators.eps "Valuators derived from Fl_Valuators" width=10cm +

In the above diagram each box surrounds an actual subclass. These + are further differentiated by setting the type() of the widget t + o the symbolic value labeling the widget. + The ones labelled "0" are the default versions with a type(0). + For consistency the symbol FL_VERTICAL is defined as zero. +*/ +class FL_EXPORT Fl_Valuator : public Fl_Widget { + + double value_; + double previous_value_; + double min, max; // truncates to this range *after* rounding + double A; int B; // rounds to multiples of A/B, or no rounding if A is zero + +protected: + /** Tells if the valuator is an FL_HORIZONTAL one */ + int horizontal() const {return type()& FL_HORIZONTAL;} + Fl_Valuator(int X, int Y, int W, int H, const char* L); + + /** Gets the previous floating point value before an event changed it */ + double previous_value() const {return previous_value_;} + /** Stores the current value in the previous value */ + void handle_push() {previous_value_ = value_;} + double softclamp(double); + void handle_drag(double newvalue); + void handle_release(); // use drag() value + virtual void value_damage(); // cause damage() due to value() changing + /** Sets the current floating point value. */ + void set_value(double v) {value_ = v;} + +public: + + /** Sets the minimum (a) and maximum (b) values for the valuator widget. */ + void bounds(double a, double b) {min=a; max=b;} + /** Gets the minimum value for the valuator. */ + double minimum() const {return min;} + /** Sets the minimum value for the valuator. */ + void minimum(double a) {min = a;} + /** Gets the maximum value for the valuator. */ + double maximum() const {return max;} + /** Sets the maximum value for the valuator. */ + void maximum(double a) {max = a;} + /** + Sets the minimum and maximum values for the valuator. When + the user manipulates the widget, the value is limited to this + range. This clamping is done after rounding to the step + value (this makes a difference if the range is not a multiple of + the step). + +

The minimum may be greater than the maximum. This has the + effect of "reversing" the object so the larger values + are in the opposite direction. This also switches which end of + the filled sliders is filled.

+ +

Some widgets consider this a "soft" range. This + means they will stop at the range, but if the user releases and + grabs the control again and tries to move it further, it is + allowed.

+ +

The range may affect the display. You must redraw() + the widget after changing the range. + */ + void range(double a, double b) {min = a; max = b;} + /** See double Fl_Valuator::step() const */ + void step(int a) {A = a; B = 1;} + /** See double Fl_Valuator::step() const */ + void step(double a, int b) {A = a; B = b;} + void step(double s); + /** + Gets or sets the step value. As the user moves the mouse the + value is rounded to the nearest multiple of the step value. This + is done before clamping it to the range. For most widgets + the default step is zero. + +

For precision the step is stored as the ratio of two + integers, A/B. You can set these integers directly. Currently + setting a floating point value sets the nearest A/1 or 1/B value + possible. + */ + double step() const {return A/B;} + void precision(int); + + /** Gets the floating point(double) value. See int value(double) */ + double value() const {return value_;} + int value(double); + + virtual int format(char*); + double round(double); // round to nearest multiple of step + double clamp(double); // keep in range + double increment(double, int); // add n*step to value +}; + +#endif + +// +// End of "$Id: Fl_Valuator.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Value_Input.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Value_Input.H new file mode 100644 index 0000000..7ed3b61 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Value_Input.H @@ -0,0 +1,135 @@ +// +// "$Id: Fl_Value_Input.H 7903 2010-11-28 21:06:39Z matt $" +// +// Value input header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Value_Input widget . */ + +#ifndef Fl_Value_Input_H +#define Fl_Value_Input_H + +#include "Fl_Valuator.H" +#include "Fl_Input.H" + +/** + The Fl_Value_Input widget displays a numeric value. + The user can click in the text field and edit it - there is in + fact a hidden Fl_Input widget with + type(FL_FLOAT_INPUT) or type(FL_INT_INPUT) in + there - and when they hit return or tab the value updates to + what they typed and the callback is done. + +

If step() is non-zero and integral, then the range of numbers + is limited to integers instead of floating point numbers. As + well as displaying the value as an integer, typed input is also + limited to integer values, even if the hidden Fl_Input widget + is of type(FL_FLOAT_INPUT).

+ +

If step() is non-zero, the user can also drag the + mouse across the object and thus slide the value. The left + button moves one step() per pixel, the middle by 10 + * step(), and the right button by 100 * step(). It + is therefore impossible to select text by dragging across it, + although clicking can still move the insertion cursor.

+ +

If step() is non-zero and integral, then the range + of numbers are limited to integers instead of floating point + values. + +

\image html Fl_Value_Input.gif + \image latex Fl_Value_Input.eps "Fl_Value_Input" width=8cm +*/ +class FL_EXPORT Fl_Value_Input : public Fl_Valuator { +public: + /* This is the encapsulated Fl_input attribute to which + this class delegates the value font, color and shortcut */ + Fl_Input input; +private: + char soft_; + static void input_cb(Fl_Widget*,void*); + virtual void value_damage(); // cause damage() due to value() changing +public: + int handle(int); +protected: + void draw(); +public: + void resize(int,int,int,int); + Fl_Value_Input(int x,int y,int w,int h,const char *l=0); + ~Fl_Value_Input(); + + /** See void Fl_Value_Input::soft(char s) */ + void soft(char s) {soft_ = s;} + /** + If "soft" is turned on, the user is allowed to drag + the value outside the range. If they drag the value to one of + the ends, let go, then grab again and continue to drag, they can + get to any value. The default is true. + */ + char soft() const {return soft_;} + /** + The first form returns the current shortcut key for the Input. +

The second form sets the shortcut key to key. Setting this + overrides the use of '&' in the label(). The value is a bitwise + OR of a key and a set of shift flags, for example FL_ALT | 'a' + , FL_ALT | (FL_F + 10), or just 'a'. A value + of 0 disables the shortcut.

+

The key can be any value returned by + Fl::event_key(), but will usually be an ASCII letter. Use + a lower-case letter unless you require the shift key to be held down.

+

The shift flags can be any set of values accepted by + Fl::event_state(). If the bit is on that shift key must + be pushed. Meta, Alt, Ctrl, and Shift must be off if they are not in + the shift flags (zero for the other bits indicates a "don't care" + setting). + */ + int shortcut() const {return input.shortcut();} + /** See int Fl_Value_Input::shortcut() const */ + void shortcut(int s) {input.shortcut(s);} + + /** Gets the typeface of the text in the value box. */ + Fl_Font textfont() const {return input.textfont();} + /** Sets the typeface of the text in the value box. */ + void textfont(Fl_Font s) {input.textfont(s);} + /** Gets the size of the text in the value box. */ + Fl_Fontsize textsize() const {return input.textsize();} + /** Sets the size of the text in the value box. */ + void textsize(Fl_Fontsize s) {input.textsize(s);} + /** Gets the color of the text in the value box. */ + Fl_Color textcolor() const {return input.textcolor();} + /** Sets the color of the text in the value box.*/ + void textcolor(Fl_Color n) {input.textcolor(n);} + /** Gets the color of the text cursor. The text cursor is black by default. */ + Fl_Color cursor_color() const {return input.cursor_color();} + /** Sets the color of the text cursor. The text cursor is black by default. */ + void cursor_color(Fl_Color n) {input.cursor_color(n);} + +}; + +#endif + +// +// End of "$Id: Fl_Value_Input.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Value_Output.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Value_Output.H new file mode 100644 index 0000000..1621a5f --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Value_Output.H @@ -0,0 +1,95 @@ +// +// "$Id: Fl_Value_Output.H 7903 2010-11-28 21:06:39Z matt $" +// +// Value output header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Value_Output widget . */ + +#ifndef Fl_Value_Output_H +#define Fl_Value_Output_H + +#ifndef Fl_Valuator_H +#include "Fl_Valuator.H" +#endif + +/** + The Fl_Value_Output widget displays a floating point value. + If step() is not zero, the user can adjust the value by + dragging the mouse left and right. The left button moves one step() + per pixel, the middle by 10 * step(), and the right button by + 100 * step(). +

This is much lighter-weight than + Fl_Value_Input because it contains no text editing code or + character buffer.

+

\image html Fl_Value_Output.gif + \image latex Fl_Value_Output.eps "Fl_Value_Output" width=8cm +*/ +class FL_EXPORT Fl_Value_Output : public Fl_Valuator { + Fl_Font textfont_; + Fl_Fontsize textsize_; + uchar soft_; + Fl_Color textcolor_; + +protected: + void draw(); + +public: + int handle(int); + Fl_Value_Output(int x,int y,int w,int h,const char *l=0); + + /** + If "soft" is turned on, the user is allowed to drag the value outside + the range. If they drag the value to one of the ends, let go, then + grab again and continue to drag, they can get to any value. Default is + one. + */ + void soft(uchar s) {soft_ = s;} + /** + If "soft" is turned on, the user is allowed to drag the value outside + the range. If they drag the value to one of the ends, let go, then + grab again and continue to drag, they can get to any value. Default is + one. + */ + uchar soft() const {return soft_;} + + /** Gets the typeface of the text in the value box. */ + Fl_Font textfont() const {return textfont_;} + /** Sets the typeface of the text in the value box. */ + void textfont(Fl_Font s) {textfont_ = s;} + /** Gets the size of the text in the value box. */ + Fl_Fontsize textsize() const {return textsize_;} + void textsize(Fl_Fontsize s) {textsize_ = s;} + /** Sets the color of the text in the value box. */ + Fl_Color textcolor() const {return textcolor_;} + /** Gets the color of the text in the value box. */ + void textcolor(Fl_Color s) {textcolor_ = s;} +}; + +#endif + +// +// End of "$Id: Fl_Value_Output.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Value_Slider.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Value_Slider.H new file mode 100644 index 0000000..e22a9e6 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Value_Slider.H @@ -0,0 +1,69 @@ +// +// "$Id: Fl_Value_Slider.H 7903 2010-11-28 21:06:39Z matt $" +// +// Value slider header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Value_Slider widget . */ + +#ifndef Fl_Value_Slider_H +#define Fl_Value_Slider_H + +#include "Fl_Slider.H" + +/** + The Fl_Value_Slider widget is a Fl_Slider widget + with a box displaying the current value. +

\image html value_slider.gif + \image latex value_slider.eps "Fl_Value_Slider" width=4cm +*/ +class FL_EXPORT Fl_Value_Slider : public Fl_Slider { + Fl_Font textfont_; + Fl_Fontsize textsize_; + Fl_Color textcolor_; +protected: + void draw(); +public: + int handle(int); + Fl_Value_Slider(int x,int y,int w,int h, const char *l = 0); + /** Gets the typeface of the text in the value box. */ + Fl_Font textfont() const {return textfont_;} + /** Sets the typeface of the text in the value box. */ + void textfont(Fl_Font s) {textfont_ = s;} + /** Gets the size of the text in the value box. */ + Fl_Fontsize textsize() const {return textsize_;} + /** Sets the size of the text in the value box. */ + void textsize(Fl_Fontsize s) {textsize_ = s;} + /** Gets the color of the text in the value box. */ + Fl_Color textcolor() const {return textcolor_;} + /** Sets the color of the text in the value box. */ + void textcolor(Fl_Color s) {textcolor_ = s;} +}; + +#endif + +// +// End of "$Id: Fl_Value_Slider.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Widget.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Widget.H new file mode 100644 index 0000000..90545a8 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Widget.H @@ -0,0 +1,977 @@ +// +// "$Id: Fl_Widget.H 7903 2010-11-28 21:06:39Z matt $" +// +// Widget header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/** \file + Fl_Widget, Fl_Label classes . */ + +#ifndef Fl_Widget_H +#define Fl_Widget_H + +#include "Enumerations.H" + +class Fl_Widget; +class Fl_Window; +class Fl_Group; +class Fl_Image; + +/** Default callback type definition for all fltk widgets (by far the most used) */ +typedef void (Fl_Callback )(Fl_Widget*, void*); +/** Default callback type pointer definition for all fltk widgets */ +typedef Fl_Callback* Fl_Callback_p; // needed for BORLAND +/** One parameter callback type definition passing only the widget */ +typedef void (Fl_Callback0)(Fl_Widget*); +/** Callback type definition passing the widget and a long data value */ +typedef void (Fl_Callback1)(Fl_Widget*, long); + +/** This struct stores all information for a text or mixed graphics label. + + \todo For FLTK 1.3, the Fl_Label type will become a widget by itself. That way + we will be avoiding a lot of code duplication by handling labels in + a similar fashion to widgets containing text. We also provide an easy + interface for very complex labels, containing html or vector graphics. + */ +struct FL_EXPORT Fl_Label { + /** label text */ + const char* value; + /** optional image for an active label */ + Fl_Image* image; + /** optional image for a deactivated label */ + Fl_Image* deimage; + /** label font used in text */ + Fl_Font font; + /** size of label font */ + Fl_Fontsize size; + /** text color */ + Fl_Color color; + /** alignment of label */ + Fl_Align align_; + /** type of label. \see Fl_Labeltype */ + uchar type; + + /** Draws the label aligned to the given box */ + void draw(int,int,int,int, Fl_Align) const ; + void measure(int &w, int &h) const ; +}; + + +/** Fl_Widget is the base class for all widgets in FLTK. + + You can't create one of these because the constructor is not public. + However you can subclass it. + + All "property" accessing methods, such as color(), parent(), or argument() + are implemented as trivial inline functions and thus are as fast and small + as accessing fields in a structure. Unless otherwise noted, the property + setting methods such as color(n) or label(s) are also trivial inline + functions, even if they change the widget's appearance. It is up to the + user code to call redraw() after these. + */ +class FL_EXPORT Fl_Widget { + friend class Fl_Group; + + Fl_Group* parent_; + Fl_Callback* callback_; + void* user_data_; + int x_,y_,w_,h_; + Fl_Label label_; + unsigned int flags_; + Fl_Color color_; + Fl_Color color2_; + uchar type_; + uchar damage_; + uchar box_; + uchar when_; + + const char *tooltip_; + + /** unimplemented copy ctor */ + Fl_Widget(const Fl_Widget &); + /** unimplemented assignment operator */ + Fl_Widget& operator=(const Fl_Widget &); + +protected: + + /** Creates a widget at the given position and size. + + The Fl_Widget is a protected constructor, but all derived widgets have a + matching public constructor. It takes a value for x(), y(), w(), h(), and + an optional value for label(). + + \param[in] x, y the position of the widget relative to the enclosing window + \param[in] w, h size of the widget in pixels + \param[in] label optional text for the widget label + */ + Fl_Widget(int x, int y, int w, int h, const char *label=0L); + + /** Internal use only. Use position(int,int), size(int,int) or resize(int,int,int,int) instead. */ + void x(int v) {x_ = v;} + /** Internal use only. Use position(int,int), size(int,int) or resize(int,int,int,int) instead. */ + void y(int v) {y_ = v;} + /** Internal use only. Use position(int,int), size(int,int) or resize(int,int,int,int) instead. */ + void w(int v) {w_ = v;} + /** Internal use only. Use position(int,int), size(int,int) or resize(int,int,int,int) instead. */ + void h(int v) {h_ = v;} + /** Gets the widget flags mask */ + unsigned int flags() const {return flags_;} + /** Sets a flag in the flags mask */ + void set_flag(unsigned int c) {flags_ |= c;} + /** Clears a flag in the flags mask */ + void clear_flag(unsigned int c) {flags_ &= ~c;} + /** flags possible values enumeration. + See activate(), output(), visible(), changed(), set_visible_focus() + */ + enum { + INACTIVE = 1<<0, ///< the widget can't receive focus, and is disabled but potentially visible + INVISIBLE = 1<<1, ///< the widget is not drawn but can receive events + OUTPUT = 1<<2, ///< for output only + NOBORDER = 1<<3, ///< don't draw a decoration (Fl_Window) + FORCE_POSITION = 1<<4, ///< don't let the window manager position the window (Fl_Window) + NON_MODAL = 1<<5, ///< thisis a hovering toolbar window (Fl_Window) + SHORTCUT_LABEL = 1<<6, ///< the label contains a shortcut we need to draw + CHANGED = 1<<7, ///< the widget value changed + OVERRIDE = 1<<8, ///< position window on top (Fl_Window) + VISIBLE_FOCUS = 1<<9, ///< accepts keyboard focus navigation if the widget can have the focus + COPIED_LABEL = 1<<10, ///< the widget label is internally copied, its destruction is handled by the widget + CLIP_CHILDREN = 1<<11, ///< all drawing within this widget will be clipped (Fl_Group) + MENU_WINDOW = 1<<12, ///< a temporary popup window, dismissed by clicking outside (Fl_Window) + TOOLTIP_WINDOW = 1<<13, ///< a temporary popup, transparent to events, and dismissed easily (Fl_Window) + MODAL = 1<<14, ///< a window blocking input to all other winows (Fl_Window) + NO_OVERLAY = 1<<15, ///< window not using a hardware overlay plane (Fl_Menu_Window) + GROUP_RELATIVE = 1<<16, ///< position this idget relative to the parent group, not to the window + // (space for more flags) + USERFLAG3 = 1<<29, ///< reserved for 3rd party extensions + USERFLAG2 = 1<<30, ///< reserved for 3rd party extensions + USERFLAG1 = 1<<31 ///< reserved for 3rd party extensions + }; + void draw_box() const; + void draw_box(Fl_Boxtype t, Fl_Color c) const; + void draw_box(Fl_Boxtype t, int x,int y,int w,int h, Fl_Color c) const; + void draw_backdrop() const; + /** draws a focus rectangle around the widget */ + void draw_focus() {draw_focus(box(),x(),y(),w(),h());} + void draw_focus(Fl_Boxtype t, int x,int y,int w,int h) const; + void draw_label() const; + void draw_label(int, int, int, int) const; + +public: + + /** Destroys the widget. + Destroying single widgets is not very common. You almost always want to + destroy the parent group instead, which will destroy all of the child widgets + and groups in that group. + + \since FLTK 1.3, the widget's destructor removes the widget from its parent + group, if it is member of a group. + */ + virtual ~Fl_Widget(); + + /** Draws the widget. + Never call this function directly. FLTK will schedule redrawing whenever + needed. If your widget must be redrawn as soon as possible, call redraw() + instead. + + Override this function to draw your own widgets. + + If you ever need to call another widget's draw method from within your + own draw() method, e.g. for an embedded scrollbar, you can do it + (because draw() is virtual) like this: + + \code + Fl_Widget *s = &scroll; // scroll is an embedded Fl_Scrollbar + s->draw(); // calls Fl_Scrollbar::draw() + \endcode + */ + virtual void draw() = 0; + + /** Handles the specified event. + You normally don't call this method directly, but instead let FLTK do + it when the user interacts with the widget. + + When implemented in a widget, this function must return 0 if the + widget does not use the event or 1 otherwise. + + Most of the time, you want to call the inherited handle() method in + your overridden method so that you don't short-circuit events that you + don't handle. In this last case you should return the callee retval. + + \param[in] event the kind of event received + \retval 0 if the event was not used or understood + \retval 1 if the event was used and can be deleted + \see Fl_Event + */ + virtual int handle(int event); + + /** Returns a pointer to the parent widget. + Usually this is a Fl_Group or Fl_Window. + \retval NULL if the widget has no parent + \see Fl_Group::add(Fl_Widget*) + */ + Fl_Group* parent() const {return parent_;} + + /** Internal use only - "for hacks only". + + It is \em \b STRONGLY recommended not to use this method, because it + short-circuits Fl_Group's normal widget adding and removing methods, + if the widget is already a child widget of another Fl_Group. + + Use Fl_Group::add(Fl_Widget*) and/or Fl_Group::remove(Fl_Widget*) instead. + */ + void parent(Fl_Group* p) {parent_ = p;} // for hacks only, use Fl_Group::add() + + /** Gets the widget type. + Returns the widget type value, which is used for Forms compatibility + and to simulate RTTI. + + \todo Explain "simulate RTTI" (currently only used to decide if a widget + is a window, i.e. type()>=FL_WINDOW ?). Is type() really used in a way + that ensures "Forms compatibility" ? + */ + uchar type() const {return type_;} + + /** Sets the widget type. + This is used for Forms compatibility. + */ + void type(uchar t) {type_ = t;} + + /** Gets the widget position in its window. + \return the x position relative to the window + */ + int x() const {return x_;} + + /** Gets the widget position in its window. + \return the y position relative to the window + */ + int y() const {return y_;} + + /** Gets the widget width. + \return the width of the widget in pixels. + */ + int w() const {return w_;} + + /** Gets the widget height. + \return the height of the widget in pixels. + */ + int h() const {return h_;} + + /** Changes the size or position of the widget. + + This is a virtual function so that the widget may implement its + own handling of resizing. The default version does \e not + call the redraw() method, but instead relies on the parent widget + to do so because the parent may know a faster way to update the + display, such as scrolling from the old position. + + Some window managers under X11 call resize() a lot more often + than needed. Please verify that the position or size of a widget + did actually change before doing any extensive calculations. + + position(X, Y) is a shortcut for resize(X, Y, w(), h()), + and size(W, H) is a shortcut for resize(x(), y(), W, H). + + \param[in] x, y new position relative to the parent window + \param[in] w, h new size + \see position(int,int), size(int,int) + */ + virtual void resize(int x, int y, int w, int h); + + /** Internal use only. */ + int damage_resize(int,int,int,int); + + /** Repositions the window or widget. + + position(X, Y) is a shortcut for resize(X, Y, w(), h()). + + \param[in] X, Y new position relative to the parent window + \see resize(int,int,int,int), size(int,int) + */ + void position(int X,int Y) {resize(X,Y,w_,h_);} + + /** Changes the size of the widget. + + size(W, H) is a shortcut for resize(x(), y(), W, H). + + \param[in] W, H new size + \see position(int,int), resize(int,int,int,int) + */ + void size(int W,int H) {resize(x_,y_,W,H);} + + /** Gets the label alignment. + + \return label alignment + \see label(), align(Fl_Align), Fl_Align + \todo This function should not take uchar as an argument. + Apart from the fact that uchar is too short with only 8 bits, + it does not provide type safety (in which case we don't need + to declare Fl_Align an enum to begin with). + *NOTE* The current (FLTK 1.3) implementation (Dec 2008) is such that + Fl_Align is (typedef'd to be) "unsigned" (int), but Fl_Widget's + "align_" member variable is a bit field of 8 bits only ! + */ + Fl_Align align() const {return label_.align_;} + + /** Sets the label alignment. + This controls how the label is displayed next to or inside the widget. + The default value is FL_ALIGN_CENTER, which centers the label inside + the widget. + \param[in] alignment new label alignment + \see align(), Fl_Align + */ + void align(Fl_Align alignment) {label_.align_ = alignment;} + + /** Gets the box type of the widget. + \return the current box type + \see box(Fl_Boxtype), Fl_Boxtype + */ + Fl_Boxtype box() const {return (Fl_Boxtype)box_;} + + /** Sets the box type for the widget. + This identifies a routine that draws the background of the widget. + See Fl_Boxtype for the available types. The default depends on the + widget, but is usually FL_NO_BOX or FL_UP_BOX. + \param[in] new_box the new box type + \see box(), Fl_Boxtype + */ + void box(Fl_Boxtype new_box) {box_ = new_box;} + + /** Gets the background color of the widget. + \return current background color + \see color(Fl_Color), color(Fl_Color, Fl_Color) + */ + Fl_Color color() const {return color_;} + + /** Sets the background color of the widget. + The color is passed to the box routine. The color is either an index into + an internal table of RGB colors or an RGB color value generated using + fl_rgb_color(). + + The default for most widgets is FL_BACKGROUND_COLOR. Use Fl::set_color() + to redefine colors in the color map. + \param[in] bg background color + \see color(), color(Fl_Color, Fl_Color), selection_color(Fl_Color) + */ + void color(Fl_Color bg) {color_ = bg;} + + /** Gets the selection color. + \return the current selection color + \see selection_color(Fl_Color), color(Fl_Color, Fl_Color) + */ + Fl_Color selection_color() const {return color2_;} + + /** Sets the selection color. + The selection color is defined for Forms compatibility and is usually + used to color the widget when it is selected, although some widgets + use this color for other purposes. You can set both colors at once + with color(Fl_Color bg, Fl_Color sel). + \param[in] a the new selection color + \see selection_color(), color(Fl_Color, Fl_Color) + */ + void selection_color(Fl_Color a) {color2_ = a;} + + /** Sets the background and selection color of the widget. + + The two color form sets both the background and selection colors. + \param[in] bg background color + \param[in] sel selection color + \see color(unsigned), selection_color(unsigned) + */ + void color(Fl_Color bg, Fl_Color sel) {color_=bg; color2_=sel;} + + /** Gets the current label text. + \return a pointer to the current label text + \see label(const char *), copy_label(const char *) + */ + const char* label() const {return label_.value;} + + /** Sets the current label pointer. + + The label is shown somewhere on or next to the widget. The passed pointer + is stored unchanged in the widget (the string is \em not copied), so if + you need to set the label to a formatted value, make sure the buffer is + static, global, or allocated. The copy_label() method can be used + to make a copy of the label string automatically. + \param[in] text pointer to new label text + \see copy_label() + */ + void label(const char* text); + + /** Sets the current label. + Unlike label(), this method allocates a copy of the label + string instead of using the original string pointer. + + The internal copy will automatically be freed whenever you assign + a new label or when the widget is destroyed. + + \param[in] new_label the new label text + \see label() + */ + void copy_label(const char *new_label); + + /** Shortcut to set the label text and type in one call. + \see label(const char *), labeltype(Fl_Labeltype) + */ + void label(Fl_Labeltype a, const char* b) {label_.type = a; label_.value = b;} + + /** Gets the label type. + \return the current label type. + \see Fl_Labeltype + */ + Fl_Labeltype labeltype() const {return (Fl_Labeltype)label_.type;} + + /** Sets the label type. + The label type identifies the function that draws the label of the widget. + This is generally used for special effects such as embossing or for using + the label() pointer as another form of data such as an icon. The value + FL_NORMAL_LABEL prints the label as plain text. + \param[in] a new label type + \see Fl_Labeltype + */ + void labeltype(Fl_Labeltype a) {label_.type = a;} + + /** Gets the label color. + The default color is FL_FOREGROUND_COLOR. + \return the current label color + */ + Fl_Color labelcolor() const {return label_.color;} + + /** Sets the label color. + The default color is FL_FOREGROUND_COLOR. + \param[in] c the new label color + */ + void labelcolor(Fl_Color c) {label_.color=c;} + + /** Gets the font to use. + Fonts are identified by indexes into a table. The default value + uses a Helvetica typeface (Arial for Microsoft® Windows®). + The function Fl::set_font() can define new typefaces. + \return current font used by the label + \see Fl_Font + */ + Fl_Font labelfont() const {return label_.font;} + + /** Sets the font to use. + Fonts are identified by indexes into a table. The default value + uses a Helvetica typeface (Arial for Microsoft® Windows®). + The function Fl::set_font() can define new typefaces. + \param[in] f the new font for the label + \see Fl_Font + */ + void labelfont(Fl_Font f) {label_.font=f;} + + /** Gets the font size in pixels. + The default size is 14 pixels. + \return the current font size + */ + Fl_Fontsize labelsize() const {return label_.size;} + + /** Sets the font size in pixels. + \param[in] pix the new font size + \see Fl_Fontsize labelsize() + */ + void labelsize(Fl_Fontsize pix) {label_.size=pix;} + + /** Gets the image that is used as part of the widget label. + This image is used when drawing the widget in the active state. + \return the current image + */ + Fl_Image* image() {return label_.image;} + const Fl_Image* image() const {return label_.image;} + + /** Sets the image to use as part of the widget label. + This image is used when drawing the widget in the active state. + \param[in] img the new image for the label + */ + void image(Fl_Image* img) {label_.image=img;} + + /** Sets the image to use as part of the widget label. + This image is used when drawing the widget in the active state. + \param[in] img the new image for the label + */ + void image(Fl_Image& img) {label_.image=&img;} + + /** Gets the image that is used as part of the widget label. + This image is used when drawing the widget in the inactive state. + \return the current image for the deactivated widget + */ + Fl_Image* deimage() {return label_.deimage;} + const Fl_Image* deimage() const {return label_.deimage;} + + /** Sets the image to use as part of the widget label. + This image is used when drawing the widget in the inactive state. + \param[in] img the new image for the deactivated widget + */ + void deimage(Fl_Image* img) {label_.deimage=img;} + + /** Sets the image to use as part of the widget label. + This image is used when drawing the widget in the inactive state. + \param[in] img the new image for the deactivated widget + */ + void deimage(Fl_Image& img) {label_.deimage=&img;} + + /** Gets the current tooltip text. + \return a pointer to the tooltip text or NULL + */ + const char *tooltip() const {return tooltip_;} + + /** Sets the current tooltip text. + Sets a string of text to display in a popup tooltip window when the user + hovers the mouse over the widget. The string is not copied, so + make sure any formatted string is stored in a static, global, + or allocated buffer. + + If no tooltip is set, the tooltip of the parent is inherited. Setting a + tooltip for a group and setting no tooltip for a child will show the + group's tooltip instead. To avoid this behavior, you can set the child's + tooltip to an empty string (""). + \param[in] t new tooltip + */ + void tooltip(const char *t); + + /** Gets the current callback function for the widget. + Each widget has a single callback. + \return current callback + */ + Fl_Callback_p callback() const {return callback_;} + + /** Sets the current callback function for the widget. + Each widget has a single callback. + \param[in] cb new callback + \param[in] p user data + */ + void callback(Fl_Callback* cb, void* p) {callback_=cb; user_data_=p;} + + /** Sets the current callback function for the widget. + Each widget has a single callback. + \param[in] cb new callback + */ + void callback(Fl_Callback* cb) {callback_=cb;} + + /** Sets the current callback function for the widget. + Each widget has a single callback. + \param[in] cb new callback + */ + void callback(Fl_Callback0*cb) {callback_=(Fl_Callback*)cb;} + + /** Sets the current callback function for the widget. + Each widget has a single callback. + \param[in] cb new callback + \param[in] p user data + */ + void callback(Fl_Callback1*cb, long p=0) {callback_=(Fl_Callback*)cb; user_data_=(void*)p;} + + /** Gets the user data for this widget. + Gets the current user data (void *) argument that is passed to the callback function. + \return user data as a pointer + */ + void* user_data() const {return user_data_;} + + /** Sets the user data for this widget. + Sets the new user data (void *) argument that is passed to the callback function. + \param[in] v new user data + */ + void user_data(void* v) {user_data_ = v;} + + /** Gets the current user data (long) argument that is passed to the callback function. + */ + long argument() const {return (long)user_data_;} + + /** Sets the current user data (long) argument that is passed to the callback function. + \todo The user data value must be implemented using a \em union to avoid + 64 bit machine incompatibilities. + */ + void argument(long v) {user_data_ = (void*)v;} + + /** Returns the conditions under which the callback is called. + + You can set the flags with when(uchar), the default value is + FL_WHEN_RELEASE. + + \return set of flags + \see when(uchar) + */ + Fl_When when() const {return (Fl_When)when_;} + + /** Sets the flags used to decide when a callback is called. + + This controls when callbacks are done. The following values are useful, + the default value is FL_WHEN_RELEASE: + + \li 0: The callback is not done, but changed() is turned on. + \li FL_WHEN_CHANGED: The callback is done each time the text is + changed by the user. + \li FL_WHEN_RELEASE: The callback will be done when this widget loses + the focus, including when the window is unmapped. This is a useful + value for text fields in a panel where doing the callback on every + change is wasteful. However the callback will also happen if the + mouse is moved out of the window, which means it should not do + anything visible (like pop up an error message). + You might do better setting this to zero, and scanning all the + items for changed() when the OK button on a panel is pressed. + \li FL_WHEN_ENTER_KEY: If the user types the Enter key, the entire + text is selected, and the callback is done if the text has changed. + Normally the Enter key will navigate to the next field (or insert + a newline for a Fl_Multiline_Input) - this changes the behavior. + \li FL_WHEN_ENTER_KEY|FL_WHEN_NOT_CHANGED: The Enter key will do the + callback even if the text has not changed. Useful for command fields. + Fl_Widget::when() is a set of bitflags used by subclasses of + Fl_Widget to decide when to do the callback. + + If the value is zero then the callback is never done. Other values + are described in the individual widgets. This field is in the base + class so that you can scan a panel and do_callback() on all the ones + that don't do their own callbacks in response to an "OK" button. + \param[in] i set of flags + */ + void when(uchar i) {when_ = i;} + + /** Returns whether a widget is visible. + \retval 0 if the widget is not drawn and hence invisible. + \see show(), hide(), visible_r() + */ + unsigned int visible() const {return !(flags_&INVISIBLE);} + + /** Returns whether a widget and all its parents are visible. + \retval 0 if the widget or any of its parents are invisible. + \see show(), hide(), visible() + */ + int visible_r() const; + + /** Makes a widget visible. + An invisible widget never gets redrawn and does not get events. + The visible() method returns true if the widget is set to be + visible. The visible_r() method returns true if the widget and + all of its parents are visible. A widget is only visible if + visible() is true on it and all of its parents. + + Changing it will send FL_SHOW or FL_HIDE events to + the widget. Do not change it if the parent is not visible, as this + will send false FL_SHOW or FL_HIDE events to the widget. + redraw() is called if necessary on this or the parent. + + \see hide(), visible(), visible_r() + */ + virtual void show(); + + /** Makes a widget invisible. + \see show(), visible(), visible_r() + */ + virtual void hide(); + + /** Makes the widget visible. + You must still redraw the parent widget to see a change in the + window. Normally you want to use the show() method instead. + */ + void set_visible() {flags_ &= ~INVISIBLE;} + + /** Hides the widget. + You must still redraw the parent to see a change in the window. + Normally you want to use the hide() method instead. + */ + void clear_visible() {flags_ |= INVISIBLE;} + + /** Returns whether the widget is active. + \retval 0 if the widget is inactive + \see active_r(), activate(), deactivate() + */ + unsigned int active() const {return !(flags_&INACTIVE);} + + /** Returns whether the widget and all of its parents are active. + \retval 0 if this or any of the parent widgets are inactive + \see active(), activate(), deactivate() + */ + int active_r() const; + + /** Activates the widget. + Changing this value will send FL_ACTIVATE to the widget if + active_r() is true. + \see active(), active_r(), deactivate() + */ + void activate(); + + /** Deactivates the widget. + Inactive widgets will be drawn "grayed out", e.g. with less contrast + than the active widget. Inactive widgets will not receive any keyboard + or mouse button events. Other events (including FL_ENTER, FL_MOVE, + FL_LEAVE, FL_SHORTCUT, and others) will still be sent. A widget is + only active if active() is true on it and all of its parents. + + Changing this value will send FL_DEACTIVATE to the widget if + active_r() is true. + + Currently you cannot deactivate Fl_Window widgets. + + \see activate(), active(), active_r() + */ + void deactivate(); + + /** Returns if a widget is used for output only. + output() means the same as !active() except it does not change how the + widget is drawn. The widget will not receive any events. This is useful + for making scrollbars or buttons that work as displays rather than input + devices. + \retval 0 if the widget is used for input and output + \see set_output(), clear_output() + */ + unsigned int output() const {return (flags_&OUTPUT);} + + /** Sets a widget to output only. + \see output(), clear_output() + */ + void set_output() {flags_ |= OUTPUT;} + + /** Sets a widget to accept input. + \see set_output(), output() + */ + void clear_output() {flags_ &= ~OUTPUT;} + + /** Returns if the widget is able to take events. + This is the same as (active() && !output() + && visible()) but is faster. + \retval 0 if the widget takes no events + */ + unsigned int takesevents() const { + return !output() && active_r() && visible_r(); + } + + /** + Checks if the widget value changed since the last callback. + + "Changed" is a flag that is turned on when the user changes the value + stored in the widget. This is only used by subclasses of Fl_Widget that + store values, but is in the base class so it is easier to scan all the + widgets in a panel and do_callback() on the changed ones in response + to an "OK" button. + + Most widgets turn this flag off when they do the callback, and when + the program sets the stored value. + + \retval 0 if the value did not change + \see set_changed(), clear_changed() + */ + unsigned int changed() const {return flags_&CHANGED;} + + /** Marks the value of the widget as changed. + \see changed(), clear_changed() + */ + void set_changed() {flags_ |= CHANGED;} + + /** Marks the value of the widget as unchanged. + \see changed(), set_changed() + */ + void clear_changed() {flags_ &= ~CHANGED;} + + /** Gives the widget the keyboard focus. + Tries to make this widget be the Fl::focus() widget, by first sending + it an FL_FOCUS event, and if it returns non-zero, setting + Fl::focus() to this widget. You should use this method to + assign the focus to a widget. + \return true if the widget accepted the focus. + */ + int take_focus(); + + /** Enables keyboard focus navigation with this widget. + Note, however, that this will not necessarily mean that the widget + will accept focus, but for widgets that can accept focus, this method + enables it if it has been disabled. + \see visible_focus(), clear_visible_focus(), visible_focus(int) + */ + void set_visible_focus() { flags_ |= VISIBLE_FOCUS; } + + /** Disables keyboard focus navigation with this widget. + Normally, all widgets participate in keyboard focus navigation. + \see set_visible_focus(), visible_focus(), visible_focus(int) + */ + void clear_visible_focus() { flags_ &= ~VISIBLE_FOCUS; } + + /** Modifies keyboard focus navigation. + \param[in] v set or clear visible focus + \see set_visible_focus(), clear_visible_focus(), visible_focus() + */ + void visible_focus(int v) { if (v) set_visible_focus(); else clear_visible_focus(); } + + /** Checks whether this widget has a visible focus. + \retval 0 if this widget has no visible focus. + \see visible_focus(int), set_visible_focus(), clear_visible_focus() + */ + unsigned int visible_focus() { return flags_ & VISIBLE_FOCUS; } + + /** Sets the default callback for all widgets. + Sets the default callback, which puts a pointer to the widget on the queue + returned by Fl::readqueue(). You may want to call this from your own callback. + \param[in] cb the new callback + \param[in] d user data associated with that callback + \see callback(), do_callback(), Fl::readqueue() + */ + static void default_callback(Fl_Widget *cb, void *d); + + /** Calls the widget callback. + Causes a widget to invoke its callback function with default arguments. + \see callback() + */ + void do_callback() {do_callback(this,user_data_);} + + /** Calls the widget callback. + Causes a widget to invoke its callback function with arbitrary arguments. + \param[in] o call the callback with \p o as the widget argument + \param[in] arg call the callback with \p arg as the user data argument + \see callback() + */ + void do_callback(Fl_Widget* o,long arg) {do_callback(o,(void*)arg);} + + // Causes a widget to invoke its callback function with arbitrary arguments. + // Documentation and implementation in Fl_Widget.cxx + void do_callback(Fl_Widget* o,void* arg=0); + + /* Internal use only. */ + int test_shortcut(); + /* Internal use only. */ + static unsigned int label_shortcut(const char *t); + /* Internal use only. */ + static int test_shortcut(const char*, const bool require_alt = false); + + /** Checks if w is a child of this widget. + \param[in] w potential child widget + \return Returns 1 if \p w is a child of this widget, or is + equal to this widget. Returns 0 if \p w is NULL. + */ + int contains(const Fl_Widget *w) const ; + + /** Checks if this widget is a child of w. + Returns 1 if this widget is a child of \p w, or is + equal to \p w. Returns 0 if \p w is NULL. + \param[in] w the possible parent widget. + \see contains() + */ + int inside(const Fl_Widget* w) const {return w ? w->contains(this) : 0;} + + /** Schedules the drawing of the widget. + Marks the widget as needing its draw() routine called. + */ + void redraw(); + + /** Schedules the drawing of the label. + Marks the widget or the parent as needing a redraw for the label area + of a widget. + */ + void redraw_label(); + + /** Returns non-zero if draw() needs to be called. + The damage value is actually a bit field that the widget + subclass can use to figure out what parts to draw. + \return a bitmap of flags describing the kind of damage to the widget + \see damage(uchar), clear_damage(uchar) + */ + uchar damage() const {return damage_;} + + /** Clears or sets the damage flags. + Damage flags are cleared when parts of the widget drawing is repaired. + + The optional argument \p c specifies the bits that are set + after the call (default: 0) and \b not the bits that are cleared! + + \note Therefore it is possible to set damage bits with this method, but + this should be avoided. Use damage(uchar) instead. + + \param[in] c new bitmask of damage flags (default: 0) + \see damage(uchar), damage() + */ + void clear_damage(uchar c = 0) {damage_ = c;} + + /** Sets the damage bits for the widget. + Setting damage bits will schedule the widget for the next redraw. + \param[in] c bitmask of flags to set + \see damage(), clear_damage(uchar) + */ + void damage(uchar c); + + /** Sets the damage bits for an area inside the widget. + Setting damage bits will schedule the widget for the next redraw. + \param[in] c bitmask of flags to set + \param[in] x, y, w, h size of damaged area + \see damage(), clear_damage(uchar) + */ + void damage(uchar c, int x, int y, int w, int h); + + void draw_label(int, int, int, int, Fl_Align) const; + + /** Sets width ww and height hh accordingly with the label size. + Labels with images will return w() and h() of the image. + */ + void measure_label(int& ww, int& hh) const {label_.measure(ww, hh);} + + /** Returns a pointer to the primary Fl_Window widget. + \retval NULL if no window is associated with this widget. + \note for an Fl_Window widget, this returns its parent window + (if any), not this window. + */ + Fl_Window* window() const ; + + /** Returns an Fl_Group pointer if this widget is an Fl_Group. + + \retval NULL if this widget is not derived from Fl_Group. + \note This method is provided to avoid dynamic_cast. + \todo More documentation ... + */ + virtual Fl_Group* as_group() {return 0;} + + /** Returns an Fl_Window pointer if this widget is an Fl_Window. + + \retval NULL if this widget is not derived from Fl_Window. + \note This method is provided to avoid dynamic_cast. + \todo More documentation ... + */ + virtual Fl_Window* as_window() {return 0;} + + /** Returns an Fl_Gl_Window pointer if this widget is an Fl_Gl_Window. + \retval NULL if this widget is not derived from Fl_Gl_Window. + \note This method is provided to avoid dynamic_cast. + \todo More documentation ... + */ + virtual class Fl_Gl_Window* as_gl_window() {return 0;} + + /** For back compatibility only. + \deprecated Use selection_color() instead. + */ + Fl_Color color2() const {return (Fl_Color)color2_;} + + /** For back compatibility only. + \deprecated Use selection_color(unsigned) instead. + */ + void color2(unsigned a) {color2_ = a;} +}; + +/** + Reserved type numbers (necessary for my cheapo RTTI) start here. + Grep the header files for "RESERVED_TYPE" to find the next available + number. +*/ +#define FL_RESERVED_TYPE 100 + +#endif + +// +// End of "$Id: Fl_Widget.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Window.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Window.H new file mode 100644 index 0000000..3b1140f --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Window.H @@ -0,0 +1,461 @@ +// +// "$Id: Fl_Window.H 7903 2010-11-28 21:06:39Z matt $" +// +// Window header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Window widget . */ + +#ifndef Fl_Window_H +#define Fl_Window_H + +#include "Fl_Group.H" + +#define FL_WINDOW 0xF0 ///< window type id all subclasses have type() >= this +#define FL_DOUBLE_WINDOW 0xF1 ///< double window type id + +class Fl_X; + +/** + This widget produces an actual window. This can either be a main + window, with a border and title and all the window management controls, + or a "subwindow" inside a window. This is controlled by whether or not + the window has a parent(). + + Once you create a window, you usually add children Fl_Widget + 's to it by using window->add(child) for each new widget. + See Fl_Group for more information on how to add and remove children. + + There are several subclasses of Fl_Window that provide + double-buffering, overlay, menu, and OpenGL support. + + The window's callback is done if the user tries to close a window + using the window manager and Fl::modal() is zero or equal to the + window. Fl_Window has a default callback that calls Fl_Window::hide(). +*/ +class FL_EXPORT Fl_Window : public Fl_Group { + + static char *default_xclass_; + + friend class Fl_X; + Fl_X *i; // points at the system-specific stuff + + const char* iconlabel_; + char* xclass_; + const void* icon_; + // size_range stuff: + int minw, minh, maxw, maxh; + int dw, dh, aspect; + uchar size_range_set; + // cursor stuff + Fl_Cursor cursor_default; + Fl_Color cursor_fg, cursor_bg; + void size_range_(); + void _Fl_Window(); // constructor innards + + // unimplemented copy ctor and assignment operator + Fl_Window(const Fl_Window&); + Fl_Window& operator=(const Fl_Window&); + +protected: + + /** Stores the last window that was made current. See current() const */ + static Fl_Window *current_; + virtual void draw(); + /** Forces the window to be drawn, this window is also made current and calls draw(). */ + virtual void flush(); + + /** + Sets an internal flag that tells FLTK and the window manager to + honor position requests. + + This is used internally and should not be needed by user code. + + \param[in] force 1 to set the FORCE_POSITION flag, 0 to clear it + */ + void force_position(int force) { + if (force) set_flag(FORCE_POSITION); + else clear_flag(FORCE_POSITION); + } + /** + Returns the internal state of the window's FORCE_POSITION flag. + + \retval 1 if flag is set + \retval 0 otherwise + + \see force_position(int) + */ + int force_position() const { return ((flags() & FORCE_POSITION)?1:0); } + +public: + + /** + Creates a window from the given size and title. + If Fl_Group::current() is not NULL, the window is created as a + subwindow of the parent window. + + The first form of the constructor creates a top-level window + and asks the window manager to position the window. The second + form of the constructor either creates a subwindow or a + top-level window at the specified location (x,y) , subject to window + manager configuration. If you do not specify the position of the + window, the window manager will pick a place to show the window + or allow the user to pick a location. Use position(x,y) + or hotspot() before calling show() to request a + position on the screen. See Fl_Window::resize() + for some more details on positioning windows. + + Top-level windows initially have visible() set to 0 + and parent() set to NULL. Subwindows initially + have visible() set to 1 and parent() set to + the parent window pointer. + + Fl_Widget::box() defaults to FL_FLAT_BOX. If you plan to + completely fill the window with children widgets you should + change this to FL_NO_BOX. If you turn the window border off + you may want to change this to FL_UP_BOX. + + \see Fl_Window(int x, int y, int w, int h, const char* title = 0) + */ + Fl_Window(int w, int h, const char* title= 0); + /** Creates a window from the given position, size and title. + + \see Fl_Window::Fl_Window(int w, int h, const char *title = 0) + */ + Fl_Window(int x, int y, int w, int h, const char* title = 0); + /** + The destructor also deletes all the children. This allows a + whole tree to be deleted at once, without having to keep a pointer to + all the children in the user code. A kludge has been done so the + Fl_Window and all of its children can be automatic (local) + variables, but you must declare the Fl_Window first so + that it is destroyed last. + */ + virtual ~Fl_Window(); + + virtual int handle(int); + + /** + Changes the size and position of the window. If shown() is true, + these changes are communicated to the window server (which may + refuse that size and cause a further resize). If shown() is + false, the size and position are used when show() is called. + See Fl_Group for the effect of resizing on the child widgets. + + You can also call the Fl_Widget methods size(x,y) and position(w,h), + which are inline wrappers for this virtual function. + + A top-level window can not force, but merely suggest a position and + size to the operating system. The window manager may not be willing or + able to display a window at the desired position or with the given + dimensions. It is up to the application developer to verify window + parameters after the resize request. + */ + virtual void resize(int,int,int,int); + /** + Sets whether or not the window manager border is around the + window. The default value is true. void border(int) can be + used to turn the border on and off. Under most X window + managers this does not work after show() has been called, + although SGI's 4DWM does work. + */ + void border(int b); + /** + Fast inline function to turn the window manager border + off. It only works before show() is called. + */ + void clear_border() {set_flag(NOBORDER);} + /** See void Fl_Window::border(int) */ + unsigned int border() const {return !(flags() & NOBORDER);} + /** Activates the flags NOBORDER|FL_OVERRIDE */ + void set_override() {set_flag(NOBORDER|OVERRIDE);} + /** Returns non zero if FL_OVERRIDE flag is set, 0 otherwise. */ + unsigned int override() const { return flags()&OVERRIDE; } + /** + A "modal" window, when shown(), will prevent any events from + being delivered to other windows in the same program, and will also + remain on top of the other windows (if the X window manager supports + the "transient for" property). Several modal windows may be shown at + once, in which case only the last one shown gets events. You can see + which window (if any) is modal by calling Fl::modal(). + */ + void set_modal() {set_flag(MODAL);} + /** Returns true if this window is modal. */ + unsigned int modal() const {return flags() & MODAL;} + /** + A "non-modal" window (terminology borrowed from Microsoft Windows) + acts like a modal() one in that it remains on top, but it has + no effect on event delivery. There are three states for a + window: modal, non-modal, and normal. + */ + void set_non_modal() {set_flag(NON_MODAL);} + /** Returns true if this window is modal or non-modal. */ + unsigned int non_modal() const {return flags() & (NON_MODAL|MODAL);} + + /** + Marks the window as a menu window. + + This is intended for internal use, but it can also be used if you + write your own menu handling. However, this is not recommended. + + This flag is used for correct "parenting" of windows in communication + with the windowing system. Modern X window managers can use different + flags to distinguish menu and tooltip windows from normal windows. + + This must be called before the window is shown and cannot be changed + later. + */ + void set_menu_window() {set_flag(MENU_WINDOW);} + + /** Returns true if this window is a menu window. */ + unsigned int menu_window() const {return flags() & MENU_WINDOW;} + + /** + Marks the window as a tooltip window. + + This is intended for internal use, but it can also be used if you + write your own tooltip handling. However, this is not recommended. + + This flag is used for correct "parenting" of windows in communication + with the windowing system. Modern X window managers can use different + flags to distinguish menu and tooltip windows from normal windows. + + This must be called before the window is shown and cannot be changed + later. + + \note Since Fl_Tooltip_Window is derived from Fl_Menu_Window, this + also \b clears the menu_window() state. + */ + void set_tooltip_window() { set_flag(TOOLTIP_WINDOW); + clear_flag(MENU_WINDOW); } + /** Returns true if this window is a tooltip window. */ + unsigned int tooltip_window() const {return flags() & TOOLTIP_WINDOW;} + + /** + Positions the window so that the mouse is pointing at the given + position, or at the center of the given widget, which may be the + window itself. If the optional offscreen parameter is + non-zero, then the window is allowed to extend off the screen (this + does not work with some X window managers). \see position() + */ + void hotspot(int x, int y, int offscreen = 0); + /** See void Fl_Window::hotspot(int x, int y, int offscreen = 0) */ + void hotspot(const Fl_Widget*, int offscreen = 0); + /** See void Fl_Window::hotspot(int x, int y, int offscreen = 0) */ + void hotspot(const Fl_Widget& p, int offscreen = 0) {hotspot(&p,offscreen);} + + /** + Undoes the effect of a previous resize() or show() so that the next time + show() is called the window manager is free to position the window. + + This is for Forms compatibility only. + + \deprecated please use force_position(0) instead + */ + void free_position() {clear_flag(FORCE_POSITION);} + /** + Sets the allowable range the user can resize this window to. + This only works for top-level windows. +

    +
  • minw and minh are the smallest the window can be. + Either value must be greater than 0.
  • +
  • maxw and maxh are the largest the window can be. If either is + equal to the minimum then you cannot resize in that direction. + If either is zero then FLTK picks a maximum size in that direction + such that the window will fill the screen.
  • +
  • dw and dh are size increments. The window will be constrained + to widths of minw + N * dw, where N is any non-negative integer. + If these are less or equal to 1 they are ignored (this is ignored + on WIN32).
  • +
  • aspect is a flag that indicates that the window should preserve its + aspect ratio. This only works if both the maximum and minimum have + the same aspect ratio (ignored on WIN32 and by many X window managers). +
  • +
+ + If this function is not called, FLTK tries to figure out the range + from the setting of resizable(): +
    +
  • If resizable() is NULL (this is the default) then the window cannot + be resized and the resize border and max-size control will not be + displayed for the window.
  • +
  • If either dimension of resizable() is less than 100, then that is + considered the minimum size. Otherwise the resizable() has a minimum + size of 100.
  • +
  • If either dimension of resizable() is zero, then that is also the + maximum size (so the window cannot resize in that direction).
  • +
+ + It is undefined what happens if the current size does not fit in the + constraints passed to size_range(). + */ + void size_range(int a, int b, int c=0, int d=0, int e=0, int f=0, int g=0) { + minw=a; minh=b; maxw=c; maxh=d; dw=e; dh=f; aspect=g; size_range_();} + + /** See void Fl_Window::label(const char*) */ + const char* label() const {return Fl_Widget::label();} + /** See void Fl_Window::iconlabel(const char*) */ + const char* iconlabel() const {return iconlabel_;} + /** Sets the window title bar label. */ + void label(const char*); + /** Sets the icon label. */ + void iconlabel(const char*); + /** Sets the icon label. */ + void label(const char* label, const char* iconlabel); // platform dependent + void copy_label(const char* a); + + static void default_xclass(const char*); + static const char *default_xclass(); + const char* xclass() const; + void xclass(const char* c); + /** Gets the current icon window target dependent data. */ + const void* icon() const {return icon_;} + /** Sets the current icon window target dependent data. */ + void icon(const void * ic) {icon_ = ic;} + + /** + Returns non-zero if show() has been called (but not hide() + ). You can tell if a window is iconified with (w->shown() + && !w->visible()). + */ + int shown() {return i != 0;} + /** + Puts the window on the screen. Usually (on X) this has the side + effect of opening the display. + + If the window is already shown then it is restored and raised to the + top. This is really convenient because your program can call show() + at any time, even if the window is already up. It also means that + show() serves the purpose of raise() in other toolkits. + + Fl_Window::show(int argc, char **argv) is used for top-level + windows and allows standard arguments to be parsed from the + command-line. + + \see Fl_Window::show(int argc, char **argv) + */ + virtual void show(); + /** + Removes the window from the screen. If the window is already hidden or + has not been shown then this does nothing and is harmless. + */ + virtual void hide(); + /** + Puts the window on the screen and parses command-line arguments. + + Usually (on X) this has the side effect of opening the display. + + This form should be used for top-level windows, at least for the + first (main) window. It allows standard arguments to be parsed + from the command-line. You can use \p argc and \p argv from + main(int argc, char **argv) for this call. + + The first call also sets up some system-specific internal + variables like the system colors. + + \todo explain which system parameters are set up. + + \param argc command-line argument count, usually from main() + \param argv command-line argument vector, usually from main() + + \see virtual void Fl_Window::show() + */ + void show(int argc, char **argv); + /** + Makes the window completely fill the screen, without any window + manager border visible. You must use fullscreen_off() to undo + this. This may not work with all window managers. + */ + void fullscreen(); + /** + Turns off any side effects of fullscreen() and does + resize(x,y,w,h). + */ + void fullscreen_off(int,int,int,int); + /** + Iconifies the window. If you call this when shown() is false + it will show() it as an icon. If the window is already + iconified this does nothing. + + Call show() to restore the window. + + When a window is iconified/restored (either by these calls or by the + user) the handle() method is called with FL_HIDE and + FL_SHOW events and visible() is turned on and off. + + There is no way to control what is drawn in the icon except with the + string passed to Fl_Window::xclass(). You should not rely on + window managers displaying the icons. + */ + void iconize(); + + int x_root() const ; + int y_root() const ; + + static Fl_Window *current(); + /** + Sets things up so that the drawing functions in will go + into this window. This is useful for incremental update of windows, such + as in an idle callback, which will make your program behave much better + if it draws a slow graphic. Danger: incremental update is very hard to + debug and maintain! + + This method only works for the Fl_Window and Fl_Gl_Window derived classes. + */ + void make_current(); + + /** Returns an Fl_Window pointer if this widget is an Fl_Window. + + \retval NULL if this widget is not derived from Fl_Window. + \note This method is provided to avoid dynamic_cast. + \todo More documentation ... + */ + virtual Fl_Window* as_window() { return this; } + + // for back-compatibility only: + /** + Changes the cursor for this window. This always calls the system, if + you are changing the cursor a lot you may want to keep track of how + you set it in a static variable and call this only if the new cursor + is different. + + The type Fl_Cursor is an enumeration defined in . + (Under X you can get any XC_cursor value by passing + Fl_Cursor((XC_foo/2)+1)). The colors only work on X, they are + not implemented on WIN32. + + For back compatibility only. + */ + void cursor(Fl_Cursor, Fl_Color=FL_BLACK, Fl_Color=FL_WHITE); // platform dependent + void default_cursor(Fl_Cursor, Fl_Color=FL_BLACK, Fl_Color=FL_WHITE); + static void default_callback(Fl_Window*, void* v); + +}; + +#endif + +// +// End of "$Id: Fl_Window.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Wizard.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Wizard.H new file mode 100644 index 0000000..a2e34c0 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_Wizard.H @@ -0,0 +1,70 @@ +// +// "$Id: Fl_Wizard.H 7903 2010-11-28 21:06:39Z matt $" +// +// Fl_Wizard widget definitions. +// +// Copyright 1999-2010 by Easy Software Products. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Wizard widget . */ + +// +// Include necessary header files... +// + +#ifndef _Fl_Wizard_H_ +# define _Fl_Wizard_H_ + +# include + + +/** + This widget is based off the Fl_Tabs + widget, but instead of displaying tabs it only changes "tabs" under + program control. Its primary purpose is to support "wizards" that + step a user through configuration or troubleshooting tasks. + +

As with Fl_Tabs, wizard panes are composed of child (usually + Fl_Group) widgets. Navigation buttons must be added separately. +*/ +class FL_EXPORT Fl_Wizard : public Fl_Group +{ + Fl_Widget *value_; + + void draw(); + + public: + + Fl_Wizard(int, int, int, int, const char * = 0); + + void next(); + void prev(); + Fl_Widget *value(); + void value(Fl_Widget *); +}; + +#endif // !_Fl_Wizard_H_ + +// +// End of "$Id: Fl_Wizard.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_XBM_Image.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_XBM_Image.H new file mode 100644 index 0000000..53081eb --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_XBM_Image.H @@ -0,0 +1,50 @@ +// +// "$Id: Fl_XBM_Image.H 7903 2010-11-28 21:06:39Z matt $" +// +// XBM image header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_XBM_Image class . */ + +#ifndef Fl_XBM_Image_H +#define Fl_XBM_Image_H +# include "Fl_Bitmap.H" + +/** + The Fl_XBM_Image class supports loading, caching, + and drawing of X Bitmap (XBM) bitmap files. +*/ +class FL_EXPORT Fl_XBM_Image : public Fl_Bitmap { + + public: + + Fl_XBM_Image(const char* filename); +}; + +#endif // !Fl_XBM_Image_H + +// +// End of "$Id: Fl_XBM_Image.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_XPM_Image.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_XPM_Image.H new file mode 100644 index 0000000..2f1a18a --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Fl_XPM_Image.H @@ -0,0 +1,51 @@ +// +// "$Id: Fl_XPM_Image.H 7903 2010-11-28 21:06:39Z matt $" +// +// XPM image header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + + Fl_XPM_Image class . */ + +#ifndef Fl_XPM_Image_H +#define Fl_XPM_Image_H +# include "Fl_Pixmap.H" + +/** + The Fl_XPM_Image class supports loading, caching, + and drawing of X Pixmap (XPM) images, including transparency. +*/ +class FL_EXPORT Fl_XPM_Image : public Fl_Pixmap { + + public: + + Fl_XPM_Image(const char* filename); +}; + +#endif // !Fl_XPM_Image + +// +// End of "$Id: Fl_XPM_Image.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Flmm_Tabs.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/Flmm_Tabs.H new file mode 100644 index 0000000..aa07c51 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Flmm_Tabs.H @@ -0,0 +1,56 @@ +// +// "$Id$" +// +// Flmm_Tabs header file for the FLMM extension to FLTK. +// +// Copyright 2002-2004 by Matthias Melcher. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems to "flmm@matthiasm.com". +// + +#ifndef Flmm_Tabs_H +#define Flmm_Tabs_H + +#include + +struct Fl_Menu_Item; + +class FL_EXPORT Flmm_Tabs : public Fl_Tabs { + int xoff; + int leftmost, rightmost; + int *tab_position_array, *tab_width_array, array_size; + char overlapping; + void allocate_arrays(); +protected: + char create_menu(Fl_Menu_Item *&menu, Fl_Menu_Item *&picked); + void draw_tab(int x1, int x2, int W, int H, Fl_Widget* o, int sel=0); + int tab_positions(int*, int*); + int tab_height(); + int handle(int); + void draw(); +public: + Flmm_Tabs(int x, int y, int w, int h, const char *l=0); + ~Flmm_Tabs(); + Fl_Widget *which(int event_x, int event_y); +}; + +#endif + +// +// End of "$Id: Fl_Tabs.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Makefile.in b/mod/maxgui.mod/fltkmaxgui.mod/FL/Makefile.in new file mode 100644 index 0000000..c3364f3 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Makefile.in @@ -0,0 +1,63 @@ +# +# "$Id: Makefile.in 6614 2009-01-01 16:11:32Z matt $" +# +# Header makefile for the Fast Light Tool Kit (FLTK). +# +# Copyright 1998-2009 by Bill Spitzak and others. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. +# +# You should have received a copy of the GNU Library General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +# USA. +# +# Please report all bugs and problems on the following page: +# +# http://www.fltk.org/str.php +# + +include ../makeinclude + +all: + +clean: + +depend: + +install: + echo "Installing include files in $(DESTDIR)$(includedir)..." + $(RMDIR) $(DESTDIR)$(includedir)/FL + $(INSTALL_DIR) $(DESTDIR)$(includedir)/FL + for file in *.[hH]; do \ + $(INSTALL_DATA) $$file $(DESTDIR)$(includedir)/FL; \ + done +@HLINKS@ cd $(DESTDIR)$(includedir)/FL;\ +@HLINKS@ for file in *.H; do\ +@HLINKS@ $(RM) "`basename $$file H`h";\ +@HLINKS@ $(LN) $$file "`basename $$file H`h";\ +@HLINKS@ done +@HLINKS@ $(RM) $(DESTDIR)$(includedir)/FL/fl_file_chooser.H +@HLINKS@ $(LN) Fl_File_Chooser.H $(DESTDIR)$(includedir)/FL/fl_file_chooser.H +@HLINKS@ $(RM) $(DESTDIR)$(includedir)/FL/fl_file_chooser.h +@HLINKS@ $(LN) Fl_File_Chooser.H $(DESTDIR)$(includedir)/FL/fl_file_chooser.h +@HLINKS@ $(RM) $(DESTDIR)$(includedir)/Fl +@HLINKS@ $(LN) FL $(DESTDIR)$(includedir)/Fl + +uninstall: + echo "Uninstalling include files..." + $(RMDIR) $(DESTDIR)$(includedir)/FL +@HLINKS@ $(RM) $(DESTDIR)$(includedir)/Fl + + +# +# End of "$Id: Makefile.in 6614 2009-01-01 16:11:32Z matt $". +# diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/Xutf8.h b/mod/maxgui.mod/fltkmaxgui.mod/FL/Xutf8.h new file mode 100644 index 0000000..d01145d --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/Xutf8.h @@ -0,0 +1,176 @@ +/* "$Id: Xutf8.h 7904 2010-11-28 21:12:59Z matt $" + * + * Author: Jean-Marc Lienher ( http://oksid.ch ) + * Copyright 2000-2010 by O'ksi'D. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems on the following page: + * + * http://www.fltk.org/str.php + */ + +#ifndef _Xutf8_h +#define _Xutf8_h + +# ifdef __cplusplus +extern "C" { +# endif + +#include +#include +#include +#include + +typedef struct { + int nb_font; + char **font_name_list; + int *encodings; + XFontStruct **fonts; + Font fid; + int ascent; + int descent; + int *ranges; +} XUtf8FontStruct; + +XUtf8FontStruct * +XCreateUtf8FontStruct ( + Display *dpy, + const char *base_font_name_list); + +void +XUtf8DrawString( + Display *display, + Drawable d, + XUtf8FontStruct *font_set, + GC gc, + int x, + int y, + const char *string, + int num_bytes); + +void +XUtf8DrawRtlString( + Display *display, + Drawable d, + XUtf8FontStruct *font_set, + GC gc, + int x, + int y, + const char *string, + int num_bytes); + +void +XUtf8DrawImageString( + Display *display, + Drawable d, + XUtf8FontStruct *font_set, + GC gc, + int x, + int y, + const char *string, + int num_bytes); + +int +XUtf8TextWidth( + XUtf8FontStruct *font_set, + const char *string, + int num_bytes); +int +XUtf8UcsWidth( + XUtf8FontStruct *font_set, + unsigned int ucs); + +int +XGetUtf8FontAndGlyph( + XUtf8FontStruct *font_set, + unsigned int ucs, + XFontStruct **fnt, + unsigned short *id); + +void +XFreeUtf8FontStruct( + Display *dpy, + XUtf8FontStruct *font_set); + + +int +XConvertUtf8ToUcs( + const unsigned char *buf, + int len, + unsigned int *ucs); + +int +XConvertUcsToUtf8( + unsigned int ucs, + char *buf); + +int +XUtf8CharByteLen( + const unsigned char *buf, + int len); + +int +XCountUtf8Char( + const unsigned char *buf, + int len); + +int +XFastConvertUtf8ToUcs( + const unsigned char *buf, + int len, + unsigned int *ucs); + +long +XKeysymToUcs( + KeySym keysym); + +int +XUtf8LookupString( + XIC ic, + XKeyPressedEvent* event, + char* buffer_return, + int bytes_buffer, + KeySym* keysym, + Status* status_return); + +unsigned short +XUtf8IsNonSpacing( + unsigned int ucs); + +unsigned short +XUtf8IsRightToLeft( + unsigned int ucs); + + +int +XUtf8Tolower( + int ucs); + +int +XUtf8Toupper( + int ucs); + + +# ifdef __cplusplus +} +# endif + +#endif + +/* + * End of "$Id: Xutf8.h 7904 2010-11-28 21:12:59Z matt $". + */ diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/dirent.h b/mod/maxgui.mod/fltkmaxgui.mod/FL/dirent.h new file mode 100644 index 0000000..9013703 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/dirent.h @@ -0,0 +1,34 @@ +// +// "$Id: dirent.h 7903 2010-11-28 21:06:39Z matt $" +// +// Directory header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + + +// this file is for back-compatability only +#include "filename.H" + +// +// End of "$Id: dirent.h 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/filename.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/filename.H new file mode 100644 index 0000000..5dd8fc0 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/filename.H @@ -0,0 +1,177 @@ +/* + * "$Id: filename.H 7903 2010-11-28 21:06:39Z matt $" + * + * Filename header file for the Fast Light Tool Kit (FLTK). + * + * Copyright 1998-2010 by Bill Spitzak and others. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems on the following page: + * + * http://www.fltk.org/str.php + */ + +/* Xcode on OS X includes files by recursing down into directories. + * This code catches the cycle and directly includes the required file. + */ +#ifdef fl_dirent_h_cyclic_include +# include "/usr/include/dirent.h" +#endif + +#ifndef FL_FILENAME_H +# define FL_FILENAME_H + +# include "Fl_Export.H" + +/** \addtogroup filenames File names and URI utility functions + @{ */ + +# define FL_PATH_MAX 256 /**< all path buffers should use this length */ +/** Gets the file name from a path. + Similar to basename(3), exceptions shown below. + \code + #include + [..] + const char *out; + out = fl_filename_name("/usr/lib"); // out="lib" + out = fl_filename_name("/usr/"); // out="" (basename(3) returns "usr" instead) + out = fl_filename_name("/usr"); // out="usr" + out = fl_filename_name("/"); // out="" (basename(3) returns "/" instead) + out = fl_filename_name("."); // out="." + out = fl_filename_name(".."); // out=".." + \endcode + \return a pointer to the char after the last slash, or to \p filename if there is none. + */ +FL_EXPORT const char *fl_filename_name(const char * filename); +FL_EXPORT const char *fl_filename_ext(const char *buf); +FL_EXPORT char *fl_filename_setext(char *to, int tolen, const char *ext); +FL_EXPORT int fl_filename_expand(char *to, int tolen, const char *from); +FL_EXPORT int fl_filename_absolute(char *to, int tolen, const char *from); +FL_EXPORT int fl_filename_relative(char *to, int tolen, const char *from); +FL_EXPORT int fl_filename_match(const char *name, const char *pattern); +FL_EXPORT int fl_filename_isdir(const char *name); + +# if defined(__cplusplus) && !defined(FL_DOXYGEN) +/* + * Under WIN32, we include filename.H from numericsort.c; this should probably change... + */ + +inline char *fl_filename_setext(char *to, const char *ext) { return fl_filename_setext(to, FL_PATH_MAX, ext); } +inline int fl_filename_expand(char *to, const char *from) { return fl_filename_expand(to, FL_PATH_MAX, from); } +inline int fl_filename_absolute(char *to, const char *from) { return fl_filename_absolute(to, FL_PATH_MAX, from); } +inline int fl_filename_relative(char *to, const char *from) { return fl_filename_relative(to, FL_PATH_MAX, from); } +# endif /* __cplusplus */ + + +# if defined(WIN32) && !defined(__CYGWIN__) && !defined(__WATCOMC__) + +struct dirent {char d_name[1];}; + +# elif defined(__WATCOMC__) +# include +# include + +# else +/* + * WARNING: on some systems (very few nowadays?) may not exist. + * The correct information is in one of these files: + * + * #include + * #include + * #include + * + * plus you must do the following #define: + * + * #define dirent direct + * + * It would be best to create a file that does this... + */ +# include +# define fl_dirent_h_cyclic_include +# include +# undef fl_dirent_h_cyclic_include +# endif + +# if defined (__cplusplus) +extern "C" { +# endif /* __cplusplus */ + +# if !defined(FL_DOXYGEN) +FL_EXPORT int fl_alphasort(struct dirent **, struct dirent **); +FL_EXPORT int fl_casealphasort(struct dirent **, struct dirent **); +FL_EXPORT int fl_casenumericsort(struct dirent **, struct dirent **); +FL_EXPORT int fl_numericsort(struct dirent **, struct dirent **); +# endif + + typedef int (Fl_File_Sort_F)(struct dirent **, struct dirent **); /**< File sorting function. \see fl_filename_list() */ + +# if defined(__cplusplus) +} + +/* + * Portable "scandir" function. Ugly but necessary... + */ + +FL_EXPORT int fl_filename_list(const char *d, struct dirent ***l, + Fl_File_Sort_F *s = fl_numericsort); + +/* + * Generic function to open a Uniform Resource Identifier (URI) using a + * system-defined program (added in FLTK 1.1.8) + */ + +FL_EXPORT int fl_open_uri(const char *uri, char *msg = (char *)0, + int msglen = 0); + +# ifndef FL_DOXYGEN +/* + * _fl_filename_isdir_quick() is a private function that checks for a + * trailing slash and assumes that the passed name is a directory if + * it finds one. This function is used by Fl_File_Browser and + * Fl_File_Chooser to avoid extra stat() calls, but is not supported + * outside of FLTK... + */ +int _fl_filename_isdir_quick(const char *name); +# endif + +# endif /* __cplusplus */ + +/* + * FLTK 1.0.x compatibility definitions... + */ + +# ifdef FLTK_1_0_COMPAT +# define filename_absolute fl_filename_absolute +# define filename_expand fl_filename_expand +# define filename_ext fl_filename_ext +# define filename_isdir fl_filename_isdir +# define filename_list fl_filename_list +# define filename_match fl_filename_match +# define filename_name fl_filename_name +# define filename_relative fl_filename_relative +# define filename_setext fl_filename_setext +# define numericsort fl_numericsort +# endif /* FLTK_1_0_COMPAT */ + + +#endif /* FL_FILENAME_H */ + +/** @} */ + +/* + * End of "$Id: filename.H 7903 2010-11-28 21:06:39Z matt $". + */ diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/fl_ask.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/fl_ask.H new file mode 100644 index 0000000..f0fd4be --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/fl_ask.H @@ -0,0 +1,77 @@ +// +// "$Id: fl_ask.H 7903 2010-11-28 21:06:39Z matt $" +// +// Standard dialog header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef fl_ask_H +# define fl_ask_H + +# include "Enumerations.H" + +class Fl_Widget; +/** Different system beeps available. \relatesalso fl_beep(int) */ +enum { + FL_BEEP_DEFAULT = 0, + FL_BEEP_MESSAGE, + FL_BEEP_ERROR, + FL_BEEP_QUESTION, + FL_BEEP_PASSWORD, + FL_BEEP_NOTIFICATION +}; + +# ifdef __GNUC__ +# define __fl_attr(x) __attribute__ (x) +# else +# define __fl_attr(x) +# endif // __GNUC__ + +FL_EXPORT void fl_beep(int type = FL_BEEP_DEFAULT); +FL_EXPORT void fl_message(const char *,...) __fl_attr((__format__ (__printf__, 1, 2))); +FL_EXPORT void fl_alert(const char *,...) __fl_attr((__format__ (__printf__, 1, 2))); +// fl_ask() is deprecated since it uses "Yes" and "No" for the buttons, +// which does not conform to the current FLTK Human Interface Guidelines. +// Use fl_choice() instead with the appropriate verbs instead. +FL_EXPORT int fl_ask(const char *,...) __fl_attr((__format__ (__printf__, 1, 2), __deprecated__)); +FL_EXPORT int fl_choice(const char *q,const char *b0,const char *b1,const char *b2,...) __fl_attr((__format__ (__printf__, 1, 5))); +FL_EXPORT const char *fl_input(const char *label, const char *deflt = 0, ...) __fl_attr((__format__ (__printf__, 1, 3))); +FL_EXPORT const char *fl_password(const char *label, const char *deflt = 0, ...) __fl_attr((__format__ (__printf__, 1, 3))); + +FL_EXPORT Fl_Widget *fl_message_icon(); +extern FL_EXPORT Fl_Font fl_message_font_; +extern FL_EXPORT Fl_Fontsize fl_message_size_; +inline void fl_message_font(Fl_Font f, Fl_Fontsize s) { + fl_message_font_ = f; fl_message_size_ = s;} + +// pointers you can use to change FLTK to a foreign language: +extern FL_EXPORT const char* fl_no; +extern FL_EXPORT const char* fl_yes; +extern FL_EXPORT const char* fl_ok; +extern FL_EXPORT const char* fl_cancel; +extern FL_EXPORT const char* fl_close; +#endif // !fl_ask_H + +// +// End of "$Id: fl_ask.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/fl_draw.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/fl_draw.H new file mode 100644 index 0000000..4285025 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/fl_draw.H @@ -0,0 +1,734 @@ +// +// "$Id: fl_draw.H 7903 2010-11-28 21:06:39Z matt $" +// +// Portable drawing function header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/** + \file fl_draw.H + \brief utility header to pull drawing functions together +*/ + +#ifndef fl_draw_H +#define fl_draw_H + +#include "Enumerations.H" // for the color names +#include "Fl_Window.H" // for fl_set_spot() +#include "Fl_Device.H" + +// Image class... +class Fl_Image; + +// Label flags... +FL_EXPORT extern char fl_draw_shortcut; + +/** \addtogroup fl_attributes + @{ +*/ + +// Colors: +/** + Sets the color for all subsequent drawing operations. + For colormapped displays, a color cell will be allocated out of + \p fl_colormap the first time you use a color. If the colormap fills up + then a least-squares algorithm is used to find the closest color. + If no valid graphical context (fl_gc) is available, + the foreground is not set for the current window. + \param[in] c color + */ +inline void fl_color(Fl_Color c) {fl_graphics_driver->color(c); } // select indexed color +/** for back compatibility - use fl_color(Fl_Color c) instead */ +inline void fl_color(int c) {fl_color((Fl_Color)c);} +/** + Set the color for all subsequent drawing operations. + The closest possible match to the RGB color is used. + The RGB color is used directly on TrueColor displays. + For colormap visuals the nearest index in the gray + ramp or color cube is used. + If no valid graphical context (fl_gc) is available, + the foreground is not set for the current window. + \param[in] r,g,b color components + */ +inline void fl_color(uchar r, uchar g, uchar b) {fl_graphics_driver->color(r,g,b); } // select actual color +/** \brief The current color */ +extern FL_EXPORT Fl_Color fl_color_; +/** + Returns the last fl_color() that was set. + This can be used for state save/restore. +*/ +inline Fl_Color fl_color() {return fl_color_;} +/** @} */ + +/** \addtogroup fl_drawings + @{ +*/ +// clip: +/** + Intersects the current clip region with a rectangle and pushes this + new region onto the stack. + \param[in] x,y,w,h position and size + */ +inline void fl_push_clip(int x, int y, int w, int h) {fl_graphics_driver->push_clip(x,y,w,h); } +/** The fl_clip() name is deprecated and will be removed from future releases */ +#define fl_clip fl_push_clip +/** + Pushes an empty clip region onto the stack so nothing will be clipped. + */ +inline void fl_push_no_clip() {fl_graphics_driver->push_no_clip(); } +/** + Restores the previous clip region. + + You must call fl_pop_clip() once for every time you call fl_push_clip(). + Unpredictable results may occur if the clip stack is not empty when + you return to FLTK. + */ +inline void fl_pop_clip() {fl_graphics_driver->pop_clip(); } +/** + Does the rectangle intersect the current clip region? + \param[in] x,y,w,h position and size of rectangle + \returns non-zero if any of the rectangle intersects the current clip + region. If this returns 0 you don't have to draw the object. + + \note + Under X this returns 2 if the rectangle is partially clipped, + and 1 if it is entirely inside the clip region. + */ +inline int fl_not_clipped(int x, int y, int w, int h) {return fl_graphics_driver->not_clipped(x,y,w,h); } +/** + Intersects the rectangle with the current clip region and returns the + bounding box of the result. + + Returns non-zero if the resulting rectangle is different to the original. + This can be used to limit the necessary drawing to a rectangle. + \p W and \p H are set to zero if the rectangle is completely outside + the region. + \param[in] x,y,w,h position and size of rectangle + \param[out] X,Y,W,H position and size of resulting bounding box. + \p W and \p H are set to zero if the rectangle is + completely outside the region. + \returns Non-zero if the resulting rectangle is different to the original. + */ +inline int fl_clip_box(int x , int y, int w, int h, int& X, int& Y, int& W, int& H) + {return fl_graphics_driver->clip_box(x,y,w,h,X,Y,W,H); } +/** Undoes any clobbering of clip done by your program */ +extern void fl_restore_clip(); +/** + Replaces the top of the clipping stack with a clipping region of any shape. + + Fl_Region is an operating system specific type. + \param[in] r clipping region + */ +FL_EXPORT void fl_clip_region(Fl_Region r); +/** + returns the current clipping region. + */ +extern Fl_Region fl_clip_region(); + + +// points: +/** + Draws a single pixel at the given coordinates + */ +inline void fl_point(int x, int y) { fl_graphics_driver->point(x,y); } + +// line type: +/** + Sets how to draw lines (the "pen"). + If you change this it is your responsibility to set it back to the default + using \c fl_line_style(0). + + \param[in] style A bitmask which is a bitwise-OR of a line style, a cap + style, and a join style. If you don't specify a dash type you + will get a solid line. If you don't specify a cap or join type + you will get a system-defined default of whatever value is + fastest. + \param[in] width The thickness of the lines in pixels. Zero results in the + system defined default, which on both X and Windows is somewhat + different and nicer than 1. + \param[in] dashes A pointer to an array of dash lengths, measured in pixels. + The first location is how long to draw a solid portion, the next + is how long to draw the gap, then the solid, etc. It is terminated + with a zero-length entry. A \c NULL pointer or a zero-length + array results in a solid line. Odd array sizes are not supported + and result in undefined behavior. + + \note Because of how line styles are implemented on Win32 systems, + you \e must set the line style \e after setting the drawing + color. If you set the color after the line style you will lose + the line style settings. + \note The \p dashes array does not work under Windows 95, 98 or Me, + since those operating systems do not support complex line styles. + */ +inline void fl_line_style(int style, int width=0, char* dashes=0) {fl_graphics_driver->line_style(style,width,dashes); } +enum { + FL_SOLID = 0, ///< line style: ___________ + FL_DASH = 1, ///< line style: _ _ _ _ _ _ + FL_DOT = 2, ///< line style: . . . . . . + FL_DASHDOT = 3, ///< line style: _ . _ . _ . + FL_DASHDOTDOT = 4, ///< line style: _ . . _ . . + + FL_CAP_FLAT = 0x100, ///< cap style: end is flat + FL_CAP_ROUND = 0x200, ///< cap style: end is round + FL_CAP_SQUARE = 0x300, ///< cap style: end wraps end point + + FL_JOIN_MITER = 0x1000, ///< join style: line join extends to a point + FL_JOIN_ROUND = 0x2000, ///< join style: line join is rounded + FL_JOIN_BEVEL = 0x3000 ///< join style: line join is tidied +}; + +// rectangles tweaked to exactly fill the pixel rectangle: + +/** + Draws a 1-pixel border \e inside the given bounding box. + This function is meant for quick drawing of simple boxes. The behavior is + undefined for line widths that are not 1. + */ +inline void fl_rect(int x, int y, int w, int h) { fl_graphics_driver->rect(x,y,w,h); } + +/** Draws with passed color a 1-pixel border \e inside the given bounding box */ +inline void fl_rect(int x, int y, int w, int h, Fl_Color c) {fl_color(c); fl_rect(x,y,w,h);} +/** Colors with current color a rectangle that exactly fills the given bounding box */ +inline void fl_rectf(int x, int y, int w, int h) { fl_graphics_driver->rectf(x,y,w,h); } +/** Colors with passsed color a rectangle that exactly fills the given bounding box */ +inline void fl_rectf(int x, int y, int w, int h, Fl_Color c) {fl_color(c); fl_rectf(x,y,w,h);} + +/** + Color a rectangle with "exactly" the passed r,g,b color. + On screens with less than 24 bits of color this is done by drawing a + solid-colored block using fl_draw_image() so that the correct color + shade is produced. + */ +/* note: doxygen comment here to avoid triplication in os-speciic files */ +FL_EXPORT void fl_rectf(int x, int y, int w, int h, uchar r, uchar g, uchar b); + +// line segments: +/** + Draws a line from (x,y) to (x1,y1) + */ +inline void fl_line(int x, int y, int x1, int y1) {fl_graphics_driver->line(x,y,x1,y1); } +/** + Draws a line from (x,y) to (x1,y1) and another from (x1,y1) to (x2,y2) + */ +inline void fl_line(int x, int y, int x1, int y1, int x2, int y2) {fl_graphics_driver->line(x,y,x1,y1,x2,y2); } + +// closed line segments: +/** + Outlines a 3-sided polygon with lines + */ +inline void fl_loop(int x, int y, int x1, int y1, int x2, int y2) {fl_graphics_driver->loop(x,y,x1,y1,x2,y2); } +/** + Outlines a 4-sided polygon with lines + */ +inline void fl_loop(int x, int y, int x1, int y1, int x2, int y2, int x3, int y3) + {fl_graphics_driver->loop(x,y,x1,y1,x2,y2,x3,y3); } + +// filled polygons +/** + Fills a 3-sided polygon. The polygon must be convex. + */ +inline void fl_polygon(int x, int y, int x1, int y1, int x2, int y2) {fl_graphics_driver->polygon(x,y,x1,y1,x2,y2); } +/** + Fills a 4-sided polygon. The polygon must be convex. + */ +inline void fl_polygon(int x, int y, int x1, int y1, int x2, int y2, int x3, int y3) + { fl_graphics_driver->polygon(x,y,x1,y1,x2,y2,x3,y3); } + +// draw rectilinear lines, horizontal segment first: +/** + Draws a horizontal line from (x,y) to (x1,y) + */ +inline void fl_xyline(int x, int y, int x1) {fl_graphics_driver->xyline(x,y,x1);} +/** + Draws a horizontal line from (x,y) to (x1,y), then vertical from (x1,y) to (x1,y2) + */ +inline void fl_xyline(int x, int y, int x1, int y2) {fl_graphics_driver->xyline(x,y,x1,y2);} +/** + Draws a horizontal line from (x,y) to (x1,y), then a vertical from (x1,y) to (x1,y2) + and then another horizontal from (x1,y2) to (x3,y2) + */ +inline void fl_xyline(int x, int y, int x1, int y2, int x3) {fl_graphics_driver->xyline(x,y,x1,y2,x3);} + +// draw rectilinear lines, vertical segment first: +/** + Draws a vertical line from (x,y) to (x,y1) + */ +inline void fl_yxline(int x, int y, int y1) {fl_graphics_driver->yxline(x,y,y1);} +/** + Draws a vertical line from (x,y) to (x,y1), then a horizontal from (x,y1) to (x2,y1) + */ +inline void fl_yxline(int x, int y, int y1, int x2) {fl_graphics_driver->yxline(x,y,y1,x2);} +/** + Draws a vertical line from (x,y) to (x,y1) then a horizontal from (x,y1) + to (x2,y1), then another vertical from (x2,y1) to (x2,y3) + */ +inline void fl_yxline(int x, int y, int y1, int x2, int y3) {fl_graphics_driver->yxline(x,y,y1,x2,y3);} + +// circular lines and pie slices (code in fl_arci.C): +/** + Draw ellipse sections using integer coordinates. + + These functions match the rather limited circle drawing code provided by X + and WIN32. The advantage over using fl_arc with floating point coordinates + is that they are faster because they often use the hardware, and they draw + much nicer small circles, since the small sizes are often hard-coded bitmaps. + + If a complete circle is drawn it will fit inside the passed bounding box. + The two angles are measured in degrees counterclockwise from 3 o'clock and + are the starting and ending angle of the arc, \p a2 must be greater or equal + to \p a1. + + fl_arc() draws a series of lines to approximate the arc. Notice that the + integer version of fl_arc() has a different number of arguments than the + double version fl_arc(double x, double y, double r, double start, double end) + + \param[in] x,y,w,h bounding box of complete circle + \param[in] a1,a2 start and end angles of arc measured in degrees + counter-clockwise from 3 o'clock. \p a2 must be greater + than or equal to \p a1. + */ +inline void fl_arc(int x, int y, int w, int h, double a1, double a2) {fl_graphics_driver->arc(x,y,w,h,a1,a2); } +/** + Draw filled ellipse sections using integer coordinates. + + Like fl_arc(), but fl_pie() draws a filled-in pie slice. + This slice may extend outside the line drawn by fl_arc(); + to avoid this use w - 1 and h - 1. + + \param[in] x,y,w,h bounding box of complete circle + \param[in] a1,a2 start and end angles of arc measured in degrees + counter-clockwise from 3 o'clock. \p a2 must be greater + than or equal to \p a1. + */ +inline void fl_pie(int x, int y, int w, int h, double a1, double a2) {fl_graphics_driver->pie(x,y,w,h,a1,a2); } +/** fl_chord declaration is a place holder - the function does not yet exist */ +FL_EXPORT void fl_chord(int x, int y, int w, int h, double a1, double a2); // nyi + +// scalable drawing code (code in fl_vertex.C and fl_arc.C): +FL_EXPORT void fl_push_matrix(); +FL_EXPORT void fl_pop_matrix(); +FL_EXPORT void fl_scale(double x, double y); +FL_EXPORT void fl_scale(double x); +FL_EXPORT void fl_translate(double x, double y); +FL_EXPORT void fl_rotate(double d); +FL_EXPORT void fl_mult_matrix(double a, double b, double c, double d, double x,double y); +/** + Starts drawing a list of points. Points are added to the list with fl_vertex() + */ +inline void fl_begin_points() {fl_graphics_driver->begin_points(); } +/** + Starts drawing a list of lines. + */ +inline void fl_begin_line() {fl_graphics_driver->begin_line(); } +/** + Starts drawing a closed sequence of lines. + */ +inline void fl_begin_loop() {fl_graphics_driver->begin_loop(); } +/** + Starts drawing a convex filled polygon. + */ +inline void fl_begin_polygon() {fl_graphics_driver->begin_polygon(); } +/** + Adds a single vertex to the current path. + \param[in] x,y coordinate + */ +inline void fl_vertex(double x, double y) {fl_graphics_driver->vertex(x,y); } +/** + Add a series of points on a Bezier curve to the path. + The curve ends (and two of the points) are at X0,Y0 and X3,Y3. + \param[in] X0,Y0 curve start point + \param[in] X1,Y1 curve control point + \param[in] X2,Y2 curve control point + \param[in] X3,Y3 curve end point + */ +inline void fl_curve(double X0, double Y0, double X1, double Y1, double X2, double Y2, double X3, double Y3) + {fl_graphics_driver->curve(X0,Y0,X1,Y1,X2,Y2,X3,Y3); } +/** + Add a series of points to the current path on the arc of a circle; you + can get elliptical paths by using scale and rotate before calling fl_arc(). + \param[in] x,y,r center and radius of circular arc + \param[in] start,end angles of start and end of arc measured in degrees + counter-clockwise from 3 o'clock. If \p end is less than \p start + then it draws the arc in a clockwise direction. + */ +inline void fl_arc(double x, double y, double r, double start, double end) {fl_graphics_driver->arc(x,y,r,start,end); } +/** + fl_circle() is equivalent to fl_arc(x,y,r,0,360), but may be faster. + + It must be the \e only thing in the path: if you want a circle as part of + a complex polygon you must use fl_arc() + \param[in] x,y,r center and radius of circle + */ +inline void fl_circle(double x, double y, double r) {fl_graphics_driver->circle(x,y,r); } +/** + Ends list of points, and draws. + */ +inline void fl_end_points() {fl_graphics_driver->end_points(); } +/** + Ends list of lines, and draws. + */ +inline void fl_end_line() {fl_graphics_driver->end_line(); } +/** + Ends closed sequence of lines, and draws. + */ +inline void fl_end_loop() {fl_graphics_driver->end_loop(); } +/** + Ends convex filled polygon, and draws. + */ +inline void fl_end_polygon() {fl_graphics_driver->end_polygon(); } +/** + Starts drawing a complex filled polygon. + + The polygon may be concave, may have holes in it, or may be several + disconnected pieces. Call fl_gap() to separate loops of the path. + + To outline the polygon, use fl_begin_loop() and replace each fl_gap() + with fl_end_loop();fl_begin_loop() pairs. + + \note + For portability, you should only draw polygons that appear the same + whether "even/odd" or "non-zero" winding rules are used to fill them. + Holes should be drawn in the opposite direction to the outside loop. + */ +inline void fl_begin_complex_polygon() {fl_graphics_driver->begin_complex_polygon(); } +/** + Call fl_gap() to separate loops of the path. + + It is unnecessary but harmless to call fl_gap() before the first vertex, + after the last vertex, or several times in a row. + */ +inline void fl_gap() {fl_graphics_driver->gap(); } +/** + Ends complex filled polygon, and draws. + */ +inline void fl_end_complex_polygon() {fl_graphics_driver->end_complex_polygon(); } +// get and use transformed positions: +FL_EXPORT double fl_transform_x(double x, double y); +FL_EXPORT double fl_transform_y(double x, double y); +FL_EXPORT double fl_transform_dx(double x, double y); +FL_EXPORT double fl_transform_dy(double x, double y); +/** + Adds coordinate pair to the vertex list without further transformations. + \param[in] xf,yf transformed coordinate + */ +inline void fl_transformed_vertex(double xf, double yf) {fl_graphics_driver->transformed_vertex(xf,yf); } +/** @} */ + +/** \addtogroup fl_attributes + @{ */ +/* NOTE: doxygen comments here to avoid triplication in os-specific sources */ + +// Fonts: +/** + Sets the current font, which is then used in various drawing routines. + You may call this outside a draw context if necessary to call fl_width(), + but on X this will open the display. + + The font is identified by a \p face and a \p size. + The size of the font is measured in pixels and not "points". + Lines should be spaced \p size pixels apart or more. +*/ +inline void fl_font(Fl_Font face, Fl_Fontsize size) { fl_graphics_driver->font(face,size); } +extern FL_EXPORT Fl_Font fl_font_; ///< current font index + +/** + Returns the \p face set by the most recent call to fl_font(). + This can be used to save/restore the font. +*/ +inline Fl_Font fl_font() {return fl_font_;} +/** \brief current font size */ +extern FL_EXPORT Fl_Fontsize fl_size_; +/** + Returns the \p size set by the most recent call to fl_font(). + This can be used to save/restore the font. +*/ +inline Fl_Fontsize fl_size() {return fl_size_;} + +// information you can get about the current font: +/** + Returns the recommended minimum line spacing for the current font. + You can also use the value of \p size passed to fl_font() +*/ +FL_EXPORT int fl_height(); // using "size" should work ok +FL_EXPORT int fl_height(int font, int size); +/** + Returns the recommended distance above the bottom of a fl_height() tall box to + draw the text at so it looks centered vertically in that box. +*/ +FL_EXPORT int fl_descent(); +/** Return the typographical width of a nul-terminated string */ +FL_EXPORT double fl_width(const char* txt); +/** Return the typographical width of a sequence of \p n characters */ +FL_EXPORT double fl_width(const char* txt, int n); +/** Return the typographical width of a single character : + \note if a valid fl_gc is NOT found then it uses the first window gc, + or the screen gc if no fltk window is available when called. */ +FL_EXPORT double fl_width(unsigned int); +/** Determine the minimum pixel dimensions of a nul-terminated string. + +Usage: given a string "txt" drawn using fl_draw(txt, x, y) you would determine +its pixel extents on the display using fl_text_extents(txt, dx, dy, wo, ho) +such that a bounding box that exactly fits around the text could be drawn with +fl_rect(x+dx, y+dy, wo, ho). Note the dx, dy values hold the offset of the first +"colored in" pixel of the string, from the draw origin. +*/ +FL_EXPORT void fl_text_extents(const char*, int& dx, int& dy, int& w, int& h); // NO fltk symbol expansion will be performed +/** Determine the minimum pixel dimensions of a sequence of \p n characters. +\see fl_text_extents(const char*, int& dx, int& dy, int& w, int& h) +*/ +FL_EXPORT void fl_text_extents(const char*, int n, int& dx, int& dy, int& w, int& h); + +// font encoding: +// Note: doxygen comments here to avoid duplication for os-sepecific cases +/** + convert text from Windows/X11 latin1 charcter set to local encoding. + \param[in] t character string (latin1 encoding) + \param[in] n optional number of characters to convert (default is all) + \returns pointer to internal buffer containing converted characters + */ +FL_EXPORT const char *fl_latin1_to_local(const char *t, int n=-1); +/** + convert text from local encoding to Windowx/X11 latin1 character set. + \param[in] t character string (local encoding) + \param[in] n optional number of characters to convert (default is all) + \returns pointer to internal buffer containing converted characters + */ +FL_EXPORT const char *fl_local_to_latin1(const char *t, int n=-1); +/** + convert text from Mac Roman charcter set to local encoding. + \param[in] t character string (Mac Roman encoding) + \param[in] n optional number of characters to convert (default is all) + \returns pointer to internal buffer containing converted characters + */ +FL_EXPORT const char *fl_mac_roman_to_local(const char *t, int n=-1); +/** + convert text from local encoding to Mac Roman character set. + \param[in] t character string (local encoding) + \param[in] n optional number of characters to convert (default is all) + \returns pointer to internal buffer containing converted characters + */ +FL_EXPORT const char *fl_local_to_mac_roman(const char *t, int n=-1); +/** @} */ + +/** \addtogroup fl_drawings + @{ */ +/** + Draws a nul-terminated string starting at the given location. + + Text is aligned to the left and to the baseline of the font. + To align to the bottom, subtract fl_descent() from \p y. + To align to the top, subtract fl_descent() and add fl_height(). + This version of fl_draw provides direct access to the text drawing + function of the underlying OS. It does not apply any special handling + to control characters. +*/ +FL_EXPORT void fl_draw(const char* str, int x, int y); +/** + Draws a nul-terminated string starting at the given location and + rotating \p angle degrees counterclockwise. + This version of fl_draw provides direct access to the text drawing + function of the underlying OS and is supported by Xft, Win32 and MacOS + fltk subsets. +*/ +FL_EXPORT void fl_draw(int angle, const char* str, int x, int y); +/** + Draws an array of \p n characters starting at the given location. +*/ +inline void fl_draw(const char* str, int n, int x, int y) {fl_graphics_driver->draw(str,n,x,y); } +/** + Draws an array of \p n characters starting at the given location, + rotating \p angle degrees counterclockwise. +*/ +inline void fl_draw(int angle,const char* str, int n, int x, int y) {fl_graphics_driver->draw(angle,str,n,x,y); } +/** + Draws an array of \p n characters right to left starting at given location. +*/ +inline void fl_rtl_draw(const char* str, int n, int x, int y) {fl_graphics_driver->rtl_draw(str,n,x,y); } +FL_EXPORT void fl_measure(const char* str, int& x, int& y, + int draw_symbols = 1); +FL_EXPORT void fl_draw(const char* str, int x, int y, int w, int h, + Fl_Align align, + Fl_Image* img=0, int draw_symbols = 1); +FL_EXPORT void fl_draw(const char* str, int x, int y, int w, int h, + Fl_Align align, + void (*callthis)(const char *,int,int,int), + Fl_Image* img=0, int draw_symbols = 1); + +// boxtypes: +FL_EXPORT void fl_frame(const char* s, int x, int y, int w, int h); +FL_EXPORT void fl_frame2(const char* s, int x, int y, int w, int h); +FL_EXPORT void fl_draw_box(Fl_Boxtype, int x, int y, int w, int h, Fl_Color); + +// images: + +/** + Draw an 8-bit per color RGB or luminance image. + \param[in] buf points at the "r" data of the top-left pixel. + Color data must be in r,g,b order. + \param[in] X,Y position where to put top-left corner of image + \param[in] W,H size of the image + \param[in] D delta to add to the pointer between pixels. it may be + any value greater than or equal to 3, or it can be + negative to flip the image horizontally + \param[in] L delta to add to the pointer between lines (if 0 is + passed it uses \p W * \p D), and may be larger than + \p W * \p D to crop data, or negative to flip the + image vertically + + It is highly recommended that you put the following code before the + first show() of \e any window in your program to get rid of + the dithering if possible: + \code + Fl::visual(FL_RGB); + \endcode + Gray scale (1-channel) images may be drawn. This is done if + abs(D) is less than 3, or by calling fl_draw_image_mono(). + Only one 8-bit sample is used for each pixel, and on screens with + different numbers of bits for red, green, and blue only gray colors + are used. Setting \p D greater than 1 will let you display one channel + of a color image. + + \par Note: + The X version does not support all possible visuals. If FLTK cannot + draw the image in the current visual it will abort. FLTK supports + any visual of 8 bits or less, and all common TrueColor visuals up + to 32 bits. + */ +inline void fl_draw_image(const uchar* buf, int X,int Y,int W,int H, int D=3, int L=0) + { fl_graphics_driver->draw_image(buf, X, Y, W, H, D, L); } + +/** + Draw a gray-scale (1 channel) image. + \see fl_draw_image(const uchar* buf, int X,int Y,int W,int H, int D, int L) + */ +inline void fl_draw_image_mono(const uchar* buf, int X,int Y,int W,int H, int D=1, int L=0) + { fl_graphics_driver->draw_image_mono(buf, X, Y, W, H, D, L); } + +/** + Draw image using callback function to generate image data. + You can generate the image as it is being drawn, or do arbitrary + decompression of stored data, provided it can be decompressed to + individual scan lines easily. + \param[in] cb callback function to generate scan line data + \param[in] data user data passed to callback function + \param[in] X,Y + \param[in] W,H + \param[in] D + \see fl_draw_image(const uchar* buf, int X,int Y,int W,int H, int D, int L) + + The callback function \p cb is called with the void* \p data + user data pointer to allow access to a structure of information about + the image, and the \p x, \p y, and \p w of the scan line desired from + the image. 0,0 is the upper-left corner of the image, not \p X, \p Y. + A pointer to a buffer to put the data into is passed. You must copy + \p w pixels from scanline \p y, starting at pixel \p x, to this buffer. + + Due to cropping, less than the whole image may be requested. So \p x + may be greater than zero, the first \p y may be greater than zero, + and \p w may be less than \p W. The buffer is long enough to store + the entire \p W * \p D pixels, this is for convenience with some + decompression schemes where you must decompress the entire line at + once: decompress it into the buffer, and then if \p x is not zero, + copy the data over so the \p x'th pixel is at the start of the buffer. + + You can assume the \p y's will be consecutive, except the first one + may be greater than zero. + + If \p D is 4 or more, you must fill in the unused bytes with zero. + */ +inline void fl_draw_image(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D=3) + { fl_graphics_driver->draw_image(cb, data, X, Y, W, H, D); } + +/** + Draw gray-scale image using callback function to generate image data. + \see fl_draw_image(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D) + */ +FL_EXPORT void fl_draw_image_mono(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D=1); + +/** + Checks whether platform supports true alpha blending for RGBA images. + \returns 1 if true alpha blending supported by platform + \returns 0 not supported so FLTK will use screen door transparency + */ +/* note: doxygen comment here to avoid triplication in os-speciic files */ +FL_EXPORT char fl_can_do_alpha_blending(); + +/** + Read an RGB(A) image from the current window or off-screen buffer. + \param[in] p pixel buffer, or NULL to allocate one + \param[in] X,Y position of top-left of image to read + \param[in] W,H width and height of image to read + \param[in] alpha alpha value for image (0 fr none) + \returns pointer to pixel buffer, or NULL if allocation failed. + + The \p p argument points to a buffer that can hold the image and must + be at least \p W*H*3 bytes when reading RGB images, or \p W*H*4 bytes + when reading RGBA images. If NULL, fl_read_image() will create an + array of the proper suze which can be freed using delete[]. + + The \p alpha parameter controls whether an alpha channel is created + and the value that is placed in the alpha channel. If 0, no alpha + channel is generated. + */ +/* note: doxygen comment here to avoid triplication in os-speciic files */ +FL_EXPORT uchar *fl_read_image(uchar *p,int X,int Y,int W,int H,int alpha=0); + +// pixmaps: +FL_EXPORT int fl_draw_pixmap(/*const*/ char* const* data, int x,int y,Fl_Color=FL_GRAY); +FL_EXPORT int fl_draw_pixmap(const char* const* cdata, int x,int y,Fl_Color=FL_GRAY); +FL_EXPORT int fl_measure_pixmap(/*const*/ char* const* data, int &w, int &h); +FL_EXPORT int fl_measure_pixmap(const char* const* cdata, int &w, int &h); + +// other: +FL_EXPORT void fl_scroll(int X, int Y, int W, int H, int dx, int dy, + void (*draw_area)(void*, int,int,int,int), void* data); +FL_EXPORT const char* fl_shortcut_label(unsigned int shortcut); +FL_EXPORT const char* fl_shortcut_label(unsigned int shortcut, const char **eom); +FL_EXPORT unsigned int fl_old_shortcut(const char* s); +FL_EXPORT void fl_overlay_rect(int x,int y,int w,int h); +FL_EXPORT void fl_overlay_clear(); +FL_EXPORT void fl_cursor(Fl_Cursor, Fl_Color fg=FL_BLACK, Fl_Color bg=FL_WHITE); +FL_EXPORT const char* fl_expand_text(const char* from, char* buf, int maxbuf, + double maxw, int& n, double &width, + int wrap, int draw_symbols = 0); + +// XIM: +/** \todo provide user documentation for fl_set_status function */ +FL_EXPORT void fl_set_status(int X, int Y, int W, int H); +/** \todo provide user documentation for fl_set_spot function */ +FL_EXPORT void fl_set_spot(int font, int size, int X, int Y, int W, int H, Fl_Window *win=0); +/** \todo provide user documentation for fl_reset_spot function*/ +FL_EXPORT void fl_reset_spot(void); + + + +// XForms symbols: +FL_EXPORT int fl_draw_symbol(const char* label,int x,int y,int w,int h, Fl_Color); +FL_EXPORT int fl_add_symbol(const char* name, void (*drawit)(Fl_Color), int scalable); +/** @} */ + +#endif + +// +// End of "$Id: fl_draw.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/fl_message.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/fl_message.H new file mode 100644 index 0000000..d07949e --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/fl_message.H @@ -0,0 +1,32 @@ +// +// "$Id: fl_message.H 7903 2010-11-28 21:06:39Z matt $" +// +// Standard message header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include "fl_ask.H" + +// +// End of "$Id: fl_message.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/fl_show_colormap.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/fl_show_colormap.H new file mode 100644 index 0000000..bdcc92d --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/fl_show_colormap.H @@ -0,0 +1,58 @@ +// +// "$Id: fl_show_colormap.H 7903 2010-11-28 21:06:39Z matt $" +// +// Colormap picker header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/** \file + The fl_show_colormap() function hides the implementation classes used + to provide the popup window and color selection mechanism. +*/ + +#ifndef fl_show_colormap_H +#define fl_show_colormap_H + +/* doxygen comment here to avoid exposing ColorMenu in fl_show_colormap.cxx +*/ + +/** \addtogroup fl_attributes + @{ */ + +/** + \brief Pops up a window to let the user pick an colormap entry. + \image html fl_show_colormap.gif + \image latex fl_show_colormap.eps "fl_show_colormap" width=8cm + \param[in] oldcol color to be highlighted when grid is shown. + \retval Fl_Color value of the chosen colormap entry. + \sa Fl_Color_Chooser +*/ +FL_EXPORT Fl_Color fl_show_colormap(Fl_Color oldcol); + +/** @} */ + +#endif + +// +// End of "$Id: fl_show_colormap.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/fl_show_input.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/fl_show_input.H new file mode 100644 index 0000000..2d931a4 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/fl_show_input.H @@ -0,0 +1,32 @@ +// +// "$Id: fl_show_input.H 7903 2010-11-28 21:06:39Z matt $" +// +// Standard input dialog header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include "fl_ask.H" + +// +// End of "$Id: fl_show_input.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/fl_types.h b/mod/maxgui.mod/fltkmaxgui.mod/FL/fl_types.h new file mode 100644 index 0000000..c019821 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/fl_types.h @@ -0,0 +1,66 @@ +/* + * "$Id: fl_types.h 7903 2010-11-28 21:06:39Z matt $" + * + * Simple "C"-style types for the Fast Light Tool Kit (FLTK). + * + * Copyright 1998-2010 by Bill Spitzak and others. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems on the following page: + * + * http://www.fltk.org/str.php + */ + +/** \file + * This file contains simple "C"-style type definitions. + */ + +#ifndef FL_TYPES_H +#define FL_TYPES_H + +/** \name Miscellaneous */ +/*@{*/ /* group: Miscellaneous */ + +/** unsigned char */ +typedef unsigned char uchar; +/** unsigned long */ +typedef unsigned long ulong; + +/** Flexible length utf8 Unicode text + * + * \todo FIXME: temporary (?) typedef to mark UTF8 and Unicode conversions + */ +typedef char *Fl_String; + +/** Flexible length utf8 Unicode read-only string + * \sa Fl_String + */ +typedef const char *Fl_CString; + +/** 24-bit Unicode character + 8-bit indicator for keyboard flags */ +typedef unsigned int Fl_Shortcut; + +/** 24-bit Unicode character - upper 8-bits are unused */ +typedef unsigned int Fl_Char; + +/*@}*/ /* group: Miscellaneous */ + +#endif + +/* + * End of "$Id: fl_types.h 7903 2010-11-28 21:06:39Z matt $". + */ diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/fl_utf8.h b/mod/maxgui.mod/fltkmaxgui.mod/FL/fl_utf8.h new file mode 100644 index 0000000..791e106 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/fl_utf8.h @@ -0,0 +1,259 @@ +/* "$Id: fl_utf8.h 7903 2010-11-28 21:06:39Z matt $" + * + * Author: Jean-Marc Lienher ( http://oksid.ch ) + * Copyright 2000-2010 by O'ksi'D. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems on the following page: + * + * http://www.fltk.org/str.php + */ + +/* Merged in some functionality from the fltk-2 version. IMM. + * The following code is an attempt to merge the functions incorporated in FLTK2 + * with the functions provided in OksiD's fltk-1.1.6-utf8 port + */ + +/*** NOTE : all functions are LIMITED to 24 bits Unicode values !!! ***/ + +/** + \file fl_utf8.h + \brief header for Unicode and UTF8 chracter handling +*/ + +#ifndef _HAVE_FL_UTF8_HDR_ +#define _HAVE_FL_UTF8_HDR_ + +#include "Fl_Export.H" +#include "fl_types.h" + +#include +#include +#include + +#ifdef WIN32 +# include +# include +# include +# include +# define xchar wchar_t +# if !defined(FL_DLL) && !defined(__CYGWIN__) +# undef strdup +# define strdup _strdup +# undef putenv +# define putenv _putenv +# undef stricmp +# define stricmp _stricmp +# undef strnicmp +# define strnicmp _strnicmp +# undef hypot +# define hypot _hypot +# undef chdir +# define chdir _chdir +# endif +#elif defined(__APPLE__) +# include +# include +# define xchar wchar_t +#else /* X11 */ +# include +# include +# include "Xutf8.h" +# include +# include +# include +# define xchar unsigned short +#endif + +# ifdef __cplusplus +extern "C" { +# endif + +/** \addtogroup fl_unicode + @{ +*/ + +/* F2: comes from FLTK2 */ +/* OD: comes from OksiD */ + +/** + Return the number of bytes needed to encode the given UCS4 character in UTF8. + \param [in] ucs UCS4 encoded character + \return number of bytes required + */ +FL_EXPORT int fl_utf8bytes(unsigned ucs); + +/* OD: returns the byte length of the first UTF-8 char sequence (returns -1 if not valid) */ +FL_EXPORT int fl_utf8len(char c); + +/* OD: returns the number of Unicode chars in the UTF-8 string */ +FL_EXPORT int fl_utf_nb_char(const unsigned char *buf, int len); + +/* F2: Convert the next UTF8 char-sequence into a Unicode value (and say how many bytes were used) */ +FL_EXPORT unsigned fl_utf8decode(const char* p, const char* end, int* len); + +/* F2: Encode a Unicode value into a UTF8 sequence, return the number of bytes used */ +FL_EXPORT int fl_utf8encode(unsigned ucs, char* buf); + +/* F2: Move forward to the next valid UTF8 sequence start betwen start and end */ +FL_EXPORT const char* fl_utf8fwd(const char* p, const char* start, const char* end); + +/* F2: Move backward to the previous valid UTF8 sequence start */ +FL_EXPORT const char* fl_utf8back(const char* p, const char* start, const char* end); + +/* F2: Convert a UTF8 string into UTF16 */ +FL_EXPORT unsigned fl_utf8toUtf16(const char* src, unsigned srclen, unsigned short* dst, unsigned dstlen); + +/* F2: Convert a UTF8 string into a wide character string - makes UTF16 on win32, "UCS4" elsewhere */ +FL_EXPORT unsigned fl_utf8towc(const char *src, unsigned srclen, wchar_t *dst, unsigned dstlen); + +/* F2: Convert a wide character string to UTF8 - takes in UTF16 on win32, "UCS4" elsewhere */ +FL_EXPORT unsigned fl_utf8fromwc(char *dst, unsigned dstlen, const wchar_t *src, unsigned srclen); + +/* F2: Convert a UTF8 string into ASCII, eliding untranslatable glyphs */ +FL_EXPORT unsigned fl_utf8toa (const char *src, unsigned srclen, char *dst, unsigned dstlen); +/* OD: convert UTF-8 string to latin1 */ +/* FL_EXPORT int fl_utf2latin1(const unsigned char *src, int srclen, char *dst); */ + +/* F2: Convert 8859-1 string to UTF8 */ +FL_EXPORT unsigned fl_utf8froma (char *dst, unsigned dstlen, const char *src, unsigned srclen); +/* OD: convert latin1 str to UTF-8 */ +/* FL_EXPORT int fl_latin12utf(const unsigned char *src, int srclen, char *dst); */ + +/* F2: Returns true if the current O/S locale is UTF8 */ +FL_EXPORT int fl_utf8locale(); + +/* F2: Examine the first len characters of src, to determine if the input text is UTF8 or not + * NOTE: The value returned is not simply boolean - it contains information about the probable + * type of the src text. */ +FL_EXPORT int fl_utf8test(const char *src, unsigned len); + +/* XX: return width of "raw" ucs character in columns. + * for internal use only */ +FL_EXPORT int fl_wcwidth_(unsigned int ucs); + +/* XX: return width of utf-8 character string in columns. + * NOTE: this may also do C1 control character (0x80 to 0x9f) to CP1252 mapping, + * depending on original build options */ +FL_EXPORT int fl_wcwidth(const char *src); + +/* OD: Return true if the character is non-spacing */ +FL_EXPORT unsigned int fl_nonspacing(unsigned int ucs); + +/* F2: Convert UTF8 to a local multi-byte encoding - mainly for win32? */ +FL_EXPORT unsigned fl_utf8to_mb(const char *src, unsigned srclen, char *dst, unsigned dstlen); +/* OD: Convert UTF8 to a local multi-byte encoding */ +FL_EXPORT char* fl_utf2mbcs(const char *src); + +/* F2: Convert a local multi-byte encoding to UTF8 - mainly for win32? */ +FL_EXPORT unsigned fl_utf8from_mb(char *dst, unsigned dstlen, const char *src, unsigned srclen); +/* OD: Convert a local multi-byte encoding to UTF8 */ +/* FL_EXPORT char* fl_mbcs2utf(const char *src); */ + +/*****************************************************************************/ +#ifdef WIN32 +/* OD: Attempt to convert the UTF8 string to the current locale */ +FL_EXPORT char *fl_utf8_to_locale(const char *s, int len, unsigned int codepage); + +/* OD: Attempt to convert a string in the current locale to UTF8 */ +FL_EXPORT char *fl_locale_to_utf8(const char *s, int len, unsigned int codepage); +#endif + +/***************************************************************************** + * The following functions are intended to provide portable, UTF8 aware + * versions of standard functions + */ + +/* OD: UTF8 aware strncasecmp - converts to lower case Unicode and tests */ +FL_EXPORT int fl_utf_strncasecmp(const char *s1, const char *s2, int n); + +/* OD: UTF8 aware strcasecmp - converts to Unicode and tests */ +FL_EXPORT int fl_utf_strcasecmp(const char *s1, const char *s2); + +/* OD: return the Unicode lower case value of ucs */ +FL_EXPORT int fl_tolower(unsigned int ucs); + +/* OD: return the Unicode upper case value of ucs */ +FL_EXPORT int fl_toupper(unsigned int ucs); + +/* OD: converts the UTF8 string to the lower case equivalent */ +FL_EXPORT int fl_utf_tolower(const unsigned char *str, int len, char *buf); + +/* OD: converts the UTF8 string to the upper case equivalent */ +FL_EXPORT int fl_utf_toupper(const unsigned char *str, int len, char *buf); + +/* OD: Portable UTF8 aware chmod wrapper */ +FL_EXPORT int fl_chmod(const char* f, int mode); + +/* OD: Portable UTF8 aware access wrapper */ +FL_EXPORT int fl_access(const char* f, int mode); + +/* OD: Portable UTF8 aware stat wrapper */ +FL_EXPORT int fl_stat( const char *path, struct stat *buffer ); + +/* OD: Portable UTF8 aware getcwd wrapper */ +FL_EXPORT char* fl_getcwd( char *buf, int maxlen); + +/* OD: Portable UTF8 aware fopen wrapper */ +FL_EXPORT FILE *fl_fopen(const char *f, const char *mode); + +/* OD: Portable UTF8 aware system wrapper */ +FL_EXPORT int fl_system(const char* f); + +/* OD: Portable UTF8 aware execvp wrapper */ +FL_EXPORT int fl_execvp(const char *file, char *const *argv); + +/* OD: Portable UTF8 aware open wrapper */ +FL_EXPORT int fl_open(const char* f, int o, ...); + +/* OD: Portable UTF8 aware unlink wrapper */ +FL_EXPORT int fl_unlink(const char *f); + +/* OD: Portable UTF8 aware rmdir wrapper */ +FL_EXPORT int fl_rmdir(const char *f); + +/* OD: Portable UTF8 aware getenv wrapper */ +FL_EXPORT char* fl_getenv(const char *name); + +/* OD: Portable UTF8 aware execvp wrapper */ +FL_EXPORT int fl_mkdir(const char* f, int mode); + +/* OD: Portable UTF8 aware rename wrapper */ +FL_EXPORT int fl_rename(const char* f, const char *t); + + +/* OD: Given a full pathname, this will create the directory path needed to hold the file named */ +FL_EXPORT void fl_make_path_for_file( const char *path ); + +/* OD: recursively create a path in the file system */ +FL_EXPORT char fl_make_path( const char *path ); + + +/** @} */ + +/*****************************************************************************/ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif /* _HAVE_FL_UTF8_HDR_ */ + +/* + * End of "$Id: fl_utf8.h 7903 2010-11-28 21:06:39Z matt $". + */ diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/forms.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/forms.H new file mode 100644 index 0000000..29165f8 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/forms.H @@ -0,0 +1,845 @@ +// +// "$Id: forms.H 7903 2010-11-28 21:06:39Z matt $" +// +// Forms emulation header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef __FORMS_H__ +#define __FORMS_H__ + +#include "Fl.H" +#include "Fl_Group.H" +#include "Fl_Window.H" +#include "fl_draw.H" + +typedef Fl_Widget FL_OBJECT; +typedef Fl_Window FL_FORM; + +//////////////////////////////////////////////////////////////// +// Random constants & symbols defined by forms.h file: + +#ifndef NULL +#define NULL 0 +#endif +#ifndef FALSE +#define FALSE 0 +#define TRUE 1 +#endif + +#define FL_ON 1 +#define FL_OK 1 +#define FL_VALID 1 +#define FL_PREEMPT 1 +#define FL_AUTO 2 +#define FL_WHEN_NEEDED FL_AUTO +#define FL_OFF 0 +#define FL_NONE 0 +#define FL_CANCEL 0 +#define FL_INVALID 0 +#define FL_IGNORE -1 +//#define FL_CLOSE -2 // this variable is never used in FLTK Forms. It is removed becaus it conflicts with the window FL_CLOSE event + +#define FL_LCOL FL_BLACK +#define FL_COL1 FL_GRAY +#define FL_MCOL FL_LIGHT1 +#define FL_LEFT_BCOL FL_LIGHT3 // 53 is better match +#define FL_TOP_BCOL FL_LIGHT2 // 51 +#define FL_BOTTOM_BCOL FL_DARK2 // 40 +#define FL_RIGHT_BCOL FL_DARK3 // 36 +#define FL_INACTIVE FL_INACTIVE_COLOR +#define FL_INACTIVE_COL FL_INACTIVE_COLOR +#define FL_FREE_COL1 FL_FREE_COLOR +#define FL_FREE_COL2 ((Fl_Color)(FL_FREE_COLOR+1)) +#define FL_FREE_COL3 ((Fl_Color)(FL_FREE_COLOR+2)) +#define FL_FREE_COL4 ((Fl_Color)(FL_FREE_COLOR+3)) +#define FL_FREE_COL5 ((Fl_Color)(FL_FREE_COLOR+4)) +#define FL_FREE_COL6 ((Fl_Color)(FL_FREE_COLOR+5)) +#define FL_FREE_COL7 ((Fl_Color)(FL_FREE_COLOR+6)) +#define FL_FREE_COL8 ((Fl_Color)(FL_FREE_COLOR+7)) +#define FL_FREE_COL9 ((Fl_Color)(FL_FREE_COLOR+8)) +#define FL_FREE_COL10 ((Fl_Color)(FL_FREE_COLOR+9)) +#define FL_FREE_COL11 ((Fl_Color)(FL_FREE_COLOR+10)) +#define FL_FREE_COL12 ((Fl_Color)(FL_FREE_COLOR+11)) +#define FL_FREE_COL13 ((Fl_Color)(FL_FREE_COLOR+12)) +#define FL_FREE_COL14 ((Fl_Color)(FL_FREE_COLOR+13)) +#define FL_FREE_COL15 ((Fl_Color)(FL_FREE_COLOR+14)) +#define FL_FREE_COL16 ((Fl_Color)(FL_FREE_COLOR+15)) +#define FL_TOMATO ((Fl_Color)(131)) +#define FL_INDIANRED ((Fl_Color)(164)) +#define FL_SLATEBLUE ((Fl_Color)(195)) +#define FL_DARKGOLD ((Fl_Color)(84)) +#define FL_PALEGREEN ((Fl_Color)(157)) +#define FL_ORCHID ((Fl_Color)(203)) +#define FL_DARKCYAN ((Fl_Color)(189)) +#define FL_DARKTOMATO ((Fl_Color)(113)) +#define FL_WHEAT ((Fl_Color)(174)) + +#define FL_ALIGN_BESIDE FL_ALIGN_INSIDE + +#define FL_PUP_TOGGLE 2 // FL_MENU_TOGGLE +#define FL_PUP_INACTIVE 1 // FL_MENU_INACTIVE +#define FL_NO_FRAME FL_NO_BOX +#define FL_ROUNDED3D_UPBOX FL_ROUND_UP_BOX +#define FL_ROUNDED3D_DOWNBOX FL_ROUND_DOWN_BOX +#define FL_OVAL3D_UPBOX FL_ROUND_UP_BOX +#define FL_OVAL3D_DOWNBOX FL_ROUND_DOWN_BOX + +#define FL_MBUTTON1 1 +#define FL_LEFTMOUSE 1 +#define FL_MBUTTON2 2 +#define FL_MIDDLEMOUSE 2 +#define FL_MBUTTON3 3 +#define FL_RIGHTMOUSE 3 +#define FL_MBUTTON4 4 +#define FL_MBUTTON5 5 + +#define FL_INVALID_STYLE 255 +#define FL_NORMAL_STYLE FL_HELVETICA +#define FL_BOLD_STYLE FL_HELVETICA_BOLD +#define FL_ITALIC_STYLE FL_HELVETICA_ITALIC +#define FL_BOLDITALIC_STYLE FL_HELVETICA_BOLD_ITALIC +#define FL_FIXED_STYLE FL_COURIER +#define FL_FIXEDBOLD_STYLE FL_COURIER_BOLD +#define FL_FIXEDITALIC_STYLE FL_COURIER_ITALIC +#define FL_FIXEDBOLDITALIC_STYLE FL_COURIER_BOLD_ITALIC +#define FL_TIMES_STYLE FL_TIMES +#define FL_TIMESBOLD_STYLE FL_TIMES_BOLD +#define FL_TIMESITALIC_STYLE FL_TIMES_ITALIC +#define FL_TIMESBOLDITALIC_STYLE FL_TIMES_BOLD_ITALIC + +// hacks to change the labeltype() when passed to fl_set_object_lstyle(): +#define FL_SHADOW_STYLE (FL_SHADOW_LABEL<<8) +#define FL_ENGRAVED_STYLE (FL_ENGRAVED_LABEL<<8) +#define FL_EMBOSSED_STYLE (FL_EMBOSSED_LABEL<<0) + +// size values are different from XForms, match older Forms: +#define FL_TINY_SIZE 8 +#define FL_SMALL_SIZE 11 // 10 +//#define FL_NORMAL_SIZE 14 // 12 +#define FL_MEDIUM_SIZE 18 // 14 +#define FL_LARGE_SIZE 24 // 18 +#define FL_HUGE_SIZE 32 // 24 +#define FL_DEFAULT_SIZE FL_SMALL_SIZE +#define FL_TINY_FONT FL_TINY_SIZE +#define FL_SMALL_FONT FL_SMALL_SIZE +#define FL_NORMAL_FONT FL_NORMAL_SIZE +#define FL_MEDIUM_FONT FL_MEDIUM_SIZE +#define FL_LARGE_FONT FL_LARGE_SIZE +#define FL_HUGE_FONT FL_HUGE_SIZE +#define FL_NORMAL_FONT1 FL_SMALL_FONT +#define FL_NORMAL_FONT2 FL_NORMAL_FONT +#define FL_DEFAULT_FONT FL_SMALL_FONT + +#define FL_RETURN_END_CHANGED FL_WHEN_RELEASE +#define FL_RETURN_CHANGED FL_WHEN_CHANGED +#define FL_RETURN_END FL_WHEN_RELEASE_ALWAYS +#define FL_RETURN_ALWAYS (FL_WHEN_CHANGED|FL_WHEN_NOT_CHANGED) + +#define FL_BOUND_WIDTH 3 + +typedef int FL_Coord; +typedef int FL_COLOR; + +//////////////////////////////////////////////////////////////// +// fltk interaction: + +#define FL_CMD_OPT void +extern FL_EXPORT void fl_initialize(int*, char*[], const char*, FL_CMD_OPT*, int); +inline void fl_finish() {} + +typedef void (*FL_IO_CALLBACK) (int, void*); +inline void fl_add_io_callback(int fd, short w, FL_IO_CALLBACK cb, void* v) { + Fl::add_fd(fd,w,cb,v);} +inline void fl_remove_io_callback(int fd, short, FL_IO_CALLBACK) { + Fl::remove_fd(fd);} // removes all the callbacks! + +// type of callback is different and no "id" number is returned: +inline void fl_add_timeout(long msec, void (*cb)(void*), void* v) { + Fl::add_timeout(msec*.001, cb, v);} +inline void fl_remove_timeout(int) {} + +// type of callback is different! +inline void fl_set_idle_callback(void (*cb)()) {Fl::set_idle(cb);} + +FL_EXPORT Fl_Widget* fl_do_forms(void); +FL_EXPORT Fl_Widget* fl_check_forms(); +inline Fl_Widget* fl_do_only_forms(void) {return fl_do_forms();} +inline Fl_Widget* fl_check_only_forms(void) {return fl_check_forms();} + +// because of new redraw behavior, these are no-ops: +inline void fl_freeze_object(Fl_Widget*) {} +inline void fl_unfreeze_object(Fl_Widget*) {} +inline void fl_freeze_form(Fl_Window*) {} +inline void fl_unfreeze_form(Fl_Window*) {} +inline void fl_freeze_all_forms() {} +inline void fl_unfreeze_all_forms() {} + +inline void fl_set_focus_object(Fl_Window*, Fl_Widget* o) {Fl::focus(o);} +inline void fl_reset_focus_object(Fl_Widget* o) {Fl::focus(o);} +#define fl_set_object_focus fl_set_focus_object + +// void fl_set_form_atclose(Fl_Window*w,int (*cb)(Fl_Window*,void*),void* v) +// void fl_set_atclose(int (*cb)(Fl_Window*,void*),void*) +// fl_set_form_atactivate/atdeactivate not implemented! + +//////////////////////////////////////////////////////////////// +// Fl_Widget: + +inline void fl_set_object_boxtype(Fl_Widget* o, Fl_Boxtype a) {o->box(a);} +inline void fl_set_object_lsize(Fl_Widget* o,int s) {o->labelsize(s);} + +/* forms lib font indexes must be byte sized - extract correct byte from style word */ +inline void fl_set_object_lstyle(Fl_Widget* o,int a) { + o->labelfont((Fl_Font)(a&0xff)); o->labeltype((Fl_Labeltype)(a>>8));} +inline void fl_set_object_lcol(Fl_Widget* o, Fl_Color a) {o->labelcolor(a);} +#define fl_set_object_lcolor fl_set_object_lcol +inline void fl_set_object_lalign(Fl_Widget* o, Fl_Align a) {o->align(a);} +#define fl_set_object_align fl_set_object_lalign +inline void fl_set_object_color(Fl_Widget* o,Fl_Color a,Fl_Color b) {o->color(a,b);} +inline void fl_set_object_label(Fl_Widget* o, const char* a) {o->label(a); o->redraw();} +inline void fl_set_object_position(Fl_Widget*o,int x,int y) {o->position(x,y);} +inline void fl_set_object_size(Fl_Widget* o, int w, int h) {o->size(w,h);} +inline void fl_set_object_geometry(Fl_Widget* o,int x,int y,int w,int h) {o->resize(x,y,w,h);} + +inline void fl_get_object_geometry(Fl_Widget* o,int*x,int*y,int*w,int*h) { + *x = o->x(); *y = o->y(); *w = o->w(); *h = o->h();} +inline void fl_get_object_position(Fl_Widget* o,int*x,int*y) { + *x = o->x(); *y = o->y();} + +typedef void (*Forms_CB)(Fl_Widget*, long); +inline void fl_set_object_callback(Fl_Widget*o,Forms_CB c,long a) {o->callback(c,a);} +#define fl_set_call_back fl_set_object_callback +inline void fl_call_object_callback(Fl_Widget* o) {o->do_callback();} +inline void fl_trigger_object(Fl_Widget* o) {o->do_callback();} +inline void fl_set_object_return(Fl_Widget* o, int v) { + o->when((Fl_When)(v|FL_WHEN_RELEASE));} + +inline void fl_redraw_object(Fl_Widget* o) {o->redraw();} +inline void fl_show_object(Fl_Widget* o) {o->show();} +inline void fl_hide_object(Fl_Widget* o) {o->hide();} +inline void fl_free_object(Fl_Widget* x) {delete x;} +inline void fl_delete_object(Fl_Widget* o) {o->parent()->remove(*o);} +inline void fl_activate_object(Fl_Widget* o) {o->activate();} +inline void fl_deactivate_object(Fl_Widget* o) {o->deactivate();} + +inline void fl_add_object(Fl_Window* f, Fl_Widget* x) {f->add(x);} +inline void fl_insert_object(Fl_Widget* o, Fl_Widget* b) {b->parent()->insert(*o,b);} + +inline Fl_Window* FL_ObjWin(Fl_Widget* o) {return o->window();} + +//////////////////////////////////////////////////////////////// +// things that appered in the demos a lot that I don't emulate, but +// I did not want to edit out of all the demos... + +inline int fl_get_border_width() {return 3;} +inline void fl_set_border_width(int) {} +inline void fl_set_object_dblbuffer(Fl_Widget*, int) {} +inline void fl_set_form_dblbuffer(Fl_Window*, int) {} + +//////////////////////////////////////////////////////////////// +// Fl_Window: + +inline void fl_free_form(Fl_Window* x) {delete x;} +inline void fl_redraw_form(Fl_Window* f) {f->redraw();} + +inline Fl_Window* fl_bgn_form(Fl_Boxtype b,int w,int h) { + Fl_Window* g = new Fl_Window(w,h,0); + g->box(b); + return g; +} +FL_EXPORT void fl_end_form(); +inline void fl_addto_form(Fl_Window* f) {f->begin();} +inline Fl_Group* fl_bgn_group() {return new Fl_Group(0,0,0,0,0);} +inline void fl_end_group() {Fl_Group::current()->forms_end();} +inline void fl_addto_group(Fl_Widget* o) {((Fl_Group* )o)->begin();} +#define resizebox _ddfdesign_kludge() + +inline void fl_scale_form(Fl_Window* f, double x, double y) { + f->resizable(f); f->size(int(f->w()*x),int(f->h()*y));} +inline void fl_set_form_position(Fl_Window* f,int x,int y) {f->position(x,y);} +inline void fl_set_form_size(Fl_Window* f, int w, int h) {f->size(w,h);} +inline void fl_set_form_geometry(Fl_Window* f,int x,int y,int w,int h) { + f->resize(x,y,w,h);} +#define fl_set_initial_placement fl_set_form_geometry +inline void fl_adjust_form_size(Fl_Window*) {} + +FL_EXPORT void fl_show_form(Fl_Window* f,int p,int b,const char* n); +enum { // "p" argument values: + FL_PLACE_FREE = 0, // make resizable + FL_PLACE_MOUSE = 1, // mouse centered on form + FL_PLACE_CENTER = 2, // center of the screen + FL_PLACE_POSITION = 4,// fixed position, resizable + FL_PLACE_SIZE = 8, // fixed size, normal fltk behavior + FL_PLACE_GEOMETRY =16,// fixed size and position + FL_PLACE_ASPECT = 32, // keep aspect ratio (ignored) + FL_PLACE_FULLSCREEN=64,// fill screen + FL_PLACE_HOTSPOT = 128,// enables hotspot + FL_PLACE_ICONIC = 256,// iconic (ignored) + FL_FREE_SIZE=(1<<14), // force resizable + FL_FIX_SIZE =(1<<15) // force off resizable +}; +#define FL_PLACE_FREE_CENTER (FL_PLACE_CENTER|FL_FREE_SIZE) +#define FL_PLACE_CENTERFREE (FL_PLACE_CENTER|FL_FREE_SIZE) +enum { // "b" arguement values: + FL_NOBORDER = 0, + FL_FULLBORDER, + FL_TRANSIENT +//FL_MODAL = (1<<8) // not implemented yet in Forms +}; +inline void fl_set_form_hotspot(Fl_Window* w,int x,int y) {w->hotspot(x,y);} +inline void fl_set_form_hotobject(Fl_Window* w, Fl_Widget* o) {w->hotspot(o);} +extern FL_EXPORT char fl_flip; // in forms.C +inline void fl_flip_yorigin() {fl_flip = 1;} + +#define fl_prepare_form_window fl_show_form +inline void fl_show_form_window(Fl_Window*) {} + +inline void fl_raise_form(Fl_Window* f) {f->show();} + +inline void fl_hide_form(Fl_Window* f) {f->hide();} +inline void fl_pop_form(Fl_Window* f) {f->show();} + +extern FL_EXPORT char fl_modal_next; // in forms.C +inline void fl_activate_all_forms() {} +inline void fl_deactivate_all_forms() {fl_modal_next = 1;} +inline void fl_deactivate_form(Fl_Window*w) {w->deactivate();} +inline void fl_activate_form(Fl_Window*w) {w->activate();} + +inline void fl_set_form_title(Fl_Window* f, const char* s) {f->label(s);} +inline void fl_title_form(Fl_Window* f, const char* s) {f->label(s);} + +typedef void (*Forms_FormCB)(Fl_Widget*); +inline void fl_set_form_callback(Fl_Window* f,Forms_FormCB c) {f->callback(c);} +#define fl_set_form_call_back fl_set_form_callback + +inline void fl_init() {} +FL_EXPORT void fl_set_graphics_mode(int,int); + +inline int fl_form_is_visible(Fl_Window* f) {return f->visible();} + +inline int fl_mouse_button() {return Fl::event_button();} +#define fl_mousebutton fl_mouse_button + +#define fl_free free +#define fl_malloc malloc +#define fl_calloc calloc +#define fl_realloc realloc + +//////////////////////////////////////////////////////////////// +// Drawing functions. Only usable inside an Fl_Free object? + +inline void fl_drw_box(Fl_Boxtype b,int x,int y,int w,int h,Fl_Color bgc,int=3) { + fl_draw_box(b,x,y,w,h,bgc);} +inline void fl_drw_frame(Fl_Boxtype b,int x,int y,int w,int h,Fl_Color bgc,int=3) { + fl_draw_box(b,x,y,w,h,bgc);} + +inline void fl_drw_text(Fl_Align align, int x, int y, int w, int h, + Fl_Color fgcolor, int size, Fl_Font style, + const char* s) { + fl_font(style,size); + fl_color(fgcolor); + fl_draw(s,x,y,w,h,align); +} + +// this does not work except for CENTER... +inline void fl_drw_text_beside(Fl_Align align, int x, int y, int w, int h, + Fl_Color fgcolor, int size, Fl_Font style, + const char* s) { + fl_font(style,size); + fl_color(fgcolor); + fl_draw(s,x,y,w,h,align); +} + +inline void fl_set_font_name(Fl_Font n,const char* s) {Fl::set_font(n,s);} + +inline void fl_mapcolor(Fl_Color c, uchar r, uchar g, uchar b) {Fl::set_color(c,r,g,b);} + +#define fl_set_clipping(x,y,w,h) fl_push_clip(x,y,w,h) +#define fl_unset_clipping() fl_pop_clip() + +//////////////////////////////////////////////////////////////// +// Forms classes: + +inline Fl_Widget* fl_add_new(Fl_Widget* p) {return p;} +inline Fl_Widget* fl_add_new(uchar t,Fl_Widget* p) {p->type(t); return p;} + +#define forms_constructor(type,name) \ +inline type* name(uchar t,int x,int y,int w,int h,const char* l) { \ + return (type*)(fl_add_new(t, new type(x,y,w,h,l)));} +#define forms_constructort(type,name) \ +inline type* name(uchar t,int x,int y,int w,int h,const char* l) { \ + return (type*)(fl_add_new(new type(t,x,y,w,h,l)));} +#define forms_constructorb(type,name) \ +inline type* name(Fl_Boxtype t,int x,int y,int w,int h,const char* l) { \ + return (type*)(fl_add_new(new type(t,x,y,w,h,l)));} + +#include "Fl_FormsBitmap.H" +#define FL_NORMAL_BITMAP FL_NO_BOX +forms_constructorb(Fl_FormsBitmap, fl_add_bitmap) +inline void fl_set_bitmap_data(Fl_Widget* o, int w, int h, const uchar* b) { + ((Fl_FormsBitmap*)o)->set(w,h,b); +} + +#include "Fl_FormsPixmap.H" +#define FL_NORMAL_PIXMAP FL_NO_BOX +forms_constructorb(Fl_FormsPixmap, fl_add_pixmap) +inline void fl_set_pixmap_data(Fl_Widget* o, char*const* b) { + ((Fl_FormsPixmap*)o)->set(b); +} +//inline void fl_set_pixmap_file(Fl_Widget*, const char*); +inline void fl_set_pixmap_align(Fl_Widget* o,Fl_Align a,int,int) {o->align(a);} +//inline void fl_set_pixmap_colorcloseness(int, int, int); + +#include "Fl_Box.H" +forms_constructorb(Fl_Box, fl_add_box) + +#include "Fl_Browser.H" +forms_constructor(Fl_Browser, fl_add_browser) + +inline void fl_clear_browser(Fl_Widget* o) { + ((Fl_Browser*)o)->clear();} +inline void fl_add_browser_line(Fl_Widget* o, const char* s) { + ((Fl_Browser*)o)->add(s);} +inline void fl_addto_browser(Fl_Widget* o, const char* s) { + ((Fl_Browser*)o)->add(s);} /* should also scroll to bottom */ +//inline void fl_addto_browser_chars(Fl_Widget*, const char*) +//#define fl_append_browser fl_addto_browser_chars +inline void fl_insert_browser_line(Fl_Widget* o, int n, const char* s) { + ((Fl_Browser*)o)->insert(n,s);} +inline void fl_delete_browser_line(Fl_Widget* o, int n) { + ((Fl_Browser*)o)->remove(n);} +inline void fl_replace_browser_line(Fl_Widget* o, int n, const char* s) { + ((Fl_Browser*)o)->replace(n,s);} +inline char* fl_get_browser_line(Fl_Widget* o, int n) { + return (char*)(((Fl_Browser*)o)->text(n));} +inline int fl_load_browser(Fl_Widget* o, const char* f) { + return ((Fl_Browser*)o)->load(f);} +inline void fl_select_browser_line(Fl_Widget* o, int n) { + ((Fl_Browser*)o)->select(n,1);} +inline void fl_deselect_browser_line(Fl_Widget* o, int n) { + ((Fl_Browser*)o)->select(n,0);} +inline void fl_deselect_browser(Fl_Widget* o) { + ((Fl_Browser*)o)->deselect();} +inline int fl_isselected_browser_line(Fl_Widget* o, int n) { + return ((Fl_Browser*)o)->selected(n);} +inline int fl_get_browser_topline(Fl_Widget* o) { + return ((Fl_Browser*)o)->topline();} +inline int fl_get_browser(Fl_Widget* o) { + return ((Fl_Browser*)o)->value();} +inline int fl_get_browser_maxline(Fl_Widget* o) { + return ((Fl_Browser*)o)->size();} +//linline int fl_get_browser_screenlines(Fl_Widget*); +inline void fl_set_browser_topline(Fl_Widget* o, int n) { + ((Fl_Browser*)o)->topline(n);} +inline void fl_set_browser_fontsize(Fl_Widget* o, int s) { + ((Fl_Browser*)o)->textsize(s);} +inline void fl_set_browser_fontstyle(Fl_Widget* o, Fl_Font s) { + ((Fl_Browser*)o)->textfont(s);} +inline void fl_set_browser_specialkey(Fl_Widget* o, char c) { + ((Fl_Browser*)o)->format_char(c);} +//inline void fl_set_browser_vscrollbar(Fl_Widget*, int); +//inline void fl_set_browser_hscrollbar(Fl_Widget*, int); +//inline void fl_set_browser_leftslider(Fl_Widget*, int); +//#define fl_set_browser_leftscrollbar fl_set_browser_leftslider +//inline void fl_set_browser_line_selectable(Fl_Widget*, int, int); +//inline void fl_get_browser_dimension(Fl_Widget*,int*,int*,int*,int*); +//inline void fl_set_browser_dblclick_callback(Fl_Widget*,FL_CALLBACKPTR,long); +//inline void fl_set_browser_xoffset(Fl_Widget*, FL_Coord); +//inline void fl_set_browser_scrollbarsize(Fl_Widget*, int, int); +inline void fl_setdisplayed_browser_line(Fl_Widget* o, int n, int i) { + ((Fl_Browser*)o)->display(n,i);} +inline int fl_isdisplayed_browser_line(Fl_Widget* o, int n) { + return ((Fl_Browser*)o)->displayed(n);} + +#include "Fl_Button.H" + +#define FL_NORMAL_BUTTON 0 +#define FL_TOUCH_BUTTON 4 +#define FL_INOUT_BUTTON 5 +#define FL_RETURN_BUTTON 6 +#define FL_HIDDEN_RET_BUTTON 7 +#define FL_PUSH_BUTTON FL_TOGGLE_BUTTON +#define FL_MENU_BUTTON 9 + +FL_EXPORT Fl_Button* fl_add_button(uchar t,int x,int y,int w,int h,const char* l); +inline int fl_get_button(Fl_Widget* b) {return ((Fl_Button*)b)->value();} +inline void fl_set_button(Fl_Widget* b, int v) {((Fl_Button*)b)->value(v);} +inline int fl_get_button_numb(Fl_Widget*) {return Fl::event_button();} +inline void fl_set_button_shortcut(Fl_Widget* b, const char* s,int=0) { + ((Fl_Button*)b)->shortcut(s);} +//#define fl_set_object_shortcut(b,s) fl_set_button_shortcut(b,s) + +#include "Fl_Light_Button.H" +forms_constructor(Fl_Light_Button, fl_add_lightbutton) + +#include "Fl_Round_Button.H" +forms_constructor(Fl_Round_Button, fl_add_roundbutton) +forms_constructor(Fl_Round_Button, fl_add_round3dbutton) + +#include "Fl_Check_Button.H" +forms_constructor(Fl_Check_Button, fl_add_checkbutton) + +inline Fl_Widget* fl_add_bitmapbutton(int t,int x,int y,int w,int h,const char* l) {Fl_Widget* o = fl_add_button(t,x,y,w,h,l); return o;} +inline void fl_set_bitmapbutton_data(Fl_Widget* o,int a,int b,uchar* c) { + (new Fl_Bitmap(c,a,b))->label(o);} // does not delete old Fl_Bitmap! + +inline Fl_Widget* fl_add_pixmapbutton(int t,int x,int y,int w,int h,const char* l) {Fl_Widget* o = fl_add_button(t,x,y,w,h,l); return o;} +inline void fl_set_pixmapbutton_data(Fl_Widget* o, const char*const* c) { + (new Fl_Pixmap(c))->label(o);} // does not delete old Fl_Pixmap! + +// Fl_Canvas object not yet implemented! + +#include "Fl_Chart.H" + +forms_constructor(Fl_Chart, fl_add_chart) +inline void fl_clear_chart(Fl_Widget* o) { + ((Fl_Chart*)o)->clear();} +inline void fl_add_chart_value(Fl_Widget* o,double v,const char* s,uchar c){ + ((Fl_Chart*)o)->add(v,s,c);} +inline void fl_insert_chart_value(Fl_Widget* o, int i, double v, const char* s, uchar c) { + ((Fl_Chart*)o)->insert(i,v,s,c);} +inline void fl_replace_chart_value(Fl_Widget* o, int i, double v, const char* s, uchar c) { + ((Fl_Chart*)o)->replace(i,v,s,c);} +inline void fl_set_chart_bounds(Fl_Widget* o, double a, double b) { + ((Fl_Chart*)o)->bounds(a,b);} +inline void fl_set_chart_maxnumb(Fl_Widget* o, int v) { + ((Fl_Chart*)o)->maxsize(v);} +inline void fl_set_chart_autosize(Fl_Widget* o, int v) { + ((Fl_Chart*)o)->autosize(v);} +inline void fl_set_chart_lstyle(Fl_Widget* o, Fl_Font v) { + ((Fl_Chart*)o)->textfont(v);} +inline void fl_set_chart_lsize(Fl_Widget* o, int v) { + ((Fl_Chart*)o)->textsize(v);} +inline void fl_set_chart_lcolor(Fl_Widget* o, Fl_Color v) { + ((Fl_Chart*)o)->textcolor(v);} +#define fl_set_chart_lcol fl_set_chart_lcolor + +#include "Fl_Choice.H" + +#define FL_NORMAL_CHOICE 0 +#define FL_NORMAL_CHOICE2 0 +#define FL_DROPLIST_CHOICE 0 + +forms_constructor(Fl_Choice, fl_add_choice) +inline void fl_clear_choice(Fl_Widget* o) { + ((Fl_Choice*)o)->clear();} +inline void fl_addto_choice(Fl_Widget* o, const char* s) { + ((Fl_Choice*)o)->add(s);} +inline void fl_replace_choice(Fl_Widget* o, int i, const char* s) { + ((Fl_Choice*)o)->replace(i-1,s);} +inline void fl_delete_choice(Fl_Widget* o, int i) { + ((Fl_Choice*)o)->remove(i-1);} +inline void fl_set_choice(Fl_Widget* o, int i) { + ((Fl_Choice*)o)->value(i-1);} +// inline void fl_set_choice_text(Fl_Widget*, const char*); +inline int fl_get_choice(Fl_Widget* o) { + return ((Fl_Choice*)o)->value()+1;} +// inline const char* fl_get_choice_item_text(Fl_Widget*, int); +// inline int fl_get_choice_maxitems(Fl_Widget*); +inline const char* fl_get_choice_text(Fl_Widget* o) { + return ((Fl_Choice*)o)->text();} +inline void fl_set_choice_fontsize(Fl_Widget* o, int x) { + ((Fl_Choice*)o)->textsize(x);} +inline void fl_set_choice_fontstyle(Fl_Widget* o, Fl_Font x) { + ((Fl_Choice*)o)->textfont(x);} +// inline void fl_set_choice_item_mode(Fl_Widget*, int, unsigned); +// inline void fl_set_choice_item_shortcut(Fl_Widget*, int, const char*); + +#include "Fl_Clock.H" +forms_constructort(Fl_Clock, fl_add_clock) +inline void fl_get_clock(Fl_Widget* o, int* h, int* m, int* s) { + *h = ((Fl_Clock*)o)->hour(); + *m = ((Fl_Clock*)o)->minute(); + *s = ((Fl_Clock*)o)->second(); +} + +#include "Fl_Counter.H" +forms_constructor(Fl_Counter, fl_add_counter) +inline void fl_set_counter_value(Fl_Widget* o, double v) { + ((Fl_Counter*)o)->value(v);} +inline void fl_set_counter_bounds(Fl_Widget* o, double a, double b) { + ((Fl_Counter*)o)->bounds(a,b);} +inline void fl_set_counter_step(Fl_Widget* o, double a, double b) { + ((Fl_Counter*)o)->step(a,b);} +inline void fl_set_counter_precision(Fl_Widget* o, int v) { + ((Fl_Counter*)o)->precision(v);} +inline void fl_set_counter_return(Fl_Widget* o, int v) { + ((Fl_Counter*)o)->when((Fl_When)(v|FL_WHEN_RELEASE));} +inline double fl_get_counter_value(Fl_Widget* o) { + return ((Fl_Counter*)o)->value();} +inline void fl_get_counter_bounds(Fl_Widget* o, float* a, float* b) { + *a = float(((Fl_Counter*)o)->minimum()); + *b = float(((Fl_Counter*)o)->maximum()); +} +//inline void fl_set_counter_filter(Fl_Widget*,const char* (*)(Fl_Widget*,double,int)); + +// Cursor stuff cannot be emulated because it uses X stuff +inline void fl_set_cursor(Fl_Window* w, Fl_Cursor c) {w->cursor(c);} +#define FL_INVISIBLE_CURSOR FL_CURSOR_NONE +#define FL_DEFAULT_CURSOR FL_CURSOR_DEFAULT + +#include "Fl_Dial.H" + +#define FL_DIAL_COL1 FL_GRAY +#define FL_DIAL_COL2 37 + +forms_constructor(Fl_Dial, fl_add_dial) +inline void fl_set_dial_value(Fl_Widget* o, double v) { + ((Fl_Dial*)o)->value(v);} +inline double fl_get_dial_value(Fl_Widget* o) { + return ((Fl_Dial*)o)->value();} +inline void fl_set_dial_bounds(Fl_Widget* o, double a, double b) { + ((Fl_Dial*)o)->bounds(a, b);} +inline void fl_get_dial_bounds(Fl_Widget* o, float* a, float* b) { + *a = float(((Fl_Dial*)o)->minimum()); + *b = float(((Fl_Dial*)o)->maximum()); +} +inline void fl_set_dial_return(Fl_Widget* o, int i) { + ((Fl_Dial*)o)->when((Fl_When)(i|FL_WHEN_RELEASE));} +inline void fl_set_dial_angles(Fl_Widget* o, int a, int b) { + ((Fl_Dial*)o)->angles((short)a, (short)b);} +//inline void fl_set_dial_cross(Fl_Widget* o, int); +// inline void fl_set_dial_direction(Fl_Widget* o, uchar d) { +// ((Fl_Dial*)o)->direction(d);} +inline void fl_set_dial_step(Fl_Widget* o, double v) { + ((Fl_Dial*)o)->step(v);} + +// Frames: + +inline Fl_Widget* fl_add_frame(Fl_Boxtype i,int x,int y,int w,int h,const char* l) { + return fl_add_box(i,x-3,y-3,w+6,h+6,l);} + +// labelframe nyi +inline Fl_Widget* fl_add_labelframe(Fl_Boxtype i,int x,int y,int w,int h,const char* l) { + Fl_Widget* o = fl_add_box(i,x-3,y-3,w+6,h+6,l); + o->align(FL_ALIGN_TOP_LEFT); + return o; +} + +#include "Fl_Free.H" +inline Fl_Free* +fl_add_free(int t,double x,double y,double w,double h,const char* l, + FL_HANDLEPTR hdl) { + return (Fl_Free*)(fl_add_new( + new Fl_Free(t,int(x),int(y),int(w),int(h),l,hdl))); +} + +#include "fl_ask.H" +#include "fl_show_colormap.H" + +inline int fl_show_question(const char* c, int = 0) {return fl_choice("%s",fl_no,fl_yes,0L,c);} +FL_EXPORT void fl_show_message(const char *,const char *,const char *); +FL_EXPORT void fl_show_alert(const char *,const char *,const char *,int=0); +FL_EXPORT int fl_show_question(const char *,const char *,const char *); +inline const char *fl_show_input(const char *l,const char*d=0) {return fl_input("%s",d,l);} +FL_EXPORT /*const*/ char *fl_show_simple_input(const char *label, const char *deflt = 0); +FL_EXPORT int fl_show_choice( + const char *m1, + const char *m2, + const char *m3, + int numb, + const char *b0, + const char *b1, + const char *b2); + +inline void fl_set_goodies_font(Fl_Font a, Fl_Fontsize b) {fl_message_font(a,b);} +#define fl_show_messages fl_message +inline int fl_show_choices(const char* c,int n,const char* b1,const char* b2, + const char* b3, int) { + return fl_show_choice(0,c,0,n,b1,b2,b3); +} + +#include "filename.H" +#include "Fl_File_Chooser.H" +inline int do_matching(char* a, const char* b) {return fl_filename_match(a,b);} + +// Forms-compatable file chooser (implementation in fselect.C): +FL_EXPORT char* fl_show_file_selector(const char* message,const char* dir, + const char* pat,const char* fname); +FL_EXPORT char* fl_get_directory(); +FL_EXPORT char* fl_get_pattern(); +FL_EXPORT char* fl_get_filename(); + +#include "Fl_Input.H" +forms_constructor(Fl_Input, fl_add_input) +inline void fl_set_input(Fl_Widget* o, const char* v) { + ((Fl_Input*)o)->value(v);} +inline void fl_set_input_return(Fl_Widget* o, int x) { + ((Fl_Input*)o)->when((Fl_When)(x | FL_WHEN_RELEASE));} +inline void fl_set_input_color(Fl_Widget* o, Fl_Color a, Fl_Color b) { + ((Fl_Input*)o)->textcolor(a); + ((Fl_Input*)o)->cursor_color(b); +} +// inline void fl_set_input_scroll(Fl_Widget*, int); +inline void fl_set_input_cursorpos(Fl_Widget* o, int x, int /*y*/) { + ((Fl_Input*)o)->position(x);} +// inline void fl_set_input_selected(Fl_Widget*, int); +// inline void fl_set_input_selected_range(Fl_Widget*, int, int); +// inline void fl_set_input_maxchars(Fl_Widget*, int); +// inline void fl_set_input_format(Fl_Widget*, int, int); +// inline void fl_set_input_hscrollbar(Fl_Widget*, int); +// inline void fl_set_input_vscrollbar(Fl_Widget*, int); +// inline void fl_set_input_xoffset(Fl_Widget*, int); +// inline void fl_set_input_topline(Fl_Widget*, int); +// inline void fl_set_input_scrollbarsize(Fl_Widget*, int, int); +// inline int fl_get_input_topline(Fl_Widget*); +// inline int fl_get_input_screenlines(Fl_Widget*); +inline int fl_get_input_cursorpos(Fl_Widget* o, int*x, int*y) { + *x = ((Fl_Input*)o)->position(); *y = 0; return *x;} +// inline int fl_get_input_numberoflines(Fl_Widget*); +// inline void fl_get_input_format(Fl_Widget*, int*, int*); +inline const char* fl_get_input(Fl_Widget* o) {return ((Fl_Input*)o)->value();} + +#include "Fl_Menu_Button.H" + +// types are not implemented, they all act like FL_PUSH_MENU: +#define FL_TOUCH_MENU 0 +#define FL_PUSH_MENU 1 +#define FL_PULLDOWN_MENU 2 +forms_constructor(Fl_Menu_Button, fl_add_menu) + +inline void fl_clear_menu(Fl_Widget* o) { + ((Fl_Menu_Button*)o)->clear();} +inline void fl_set_menu(Fl_Widget* o, const char* s) { + ((Fl_Menu_Button*)o)->clear(); ((Fl_Menu_Button*)o)->add(s);} +inline void fl_addto_menu(Fl_Widget* o, const char* s) { + ((Fl_Menu_Button*)o)->add(s);} +inline void fl_replace_menu_item(Fl_Widget* o, int i, const char* s) { + ((Fl_Menu_Button*)o)->replace(i-1,s);} +inline void fl_delete_menu_item(Fl_Widget* o, int i) { + ((Fl_Menu_Button*)o)->remove(i-1);} +inline void fl_set_menu_item_shortcut(Fl_Widget* o, int i, const char* s) { + ((Fl_Menu_Button*)o)->shortcut(i-1,fl_old_shortcut(s));} +inline void fl_set_menu_item_mode(Fl_Widget* o, int i, long x) { + ((Fl_Menu_Button*)o)->mode(i-1,x);} +inline void fl_show_menu_symbol(Fl_Widget*, int ) { +/* ((Fl_Menu_Button*)o)->show_menu_symbol(i); */} +// inline void fl_set_menu_popup(Fl_Widget*, int); +inline int fl_get_menu(Fl_Widget* o) { + return ((Fl_Menu_Button*)o)->value()+1;} +inline const char* fl_get_menu_item_text(Fl_Widget* o, int i) { + return ((Fl_Menu_Button*)o)->text(i);} +inline int fl_get_menu_maxitems(Fl_Widget* o) { + return ((Fl_Menu_Button*)o)->size();} +inline int fl_get_menu_item_mode(Fl_Widget* o, int i) { + return ((Fl_Menu_Button*)o)->mode(i);} +inline const char* fl_get_menu_text(Fl_Widget* o) { + return ((Fl_Menu_Button*)o)->text();} + +#include "Fl_Positioner.H" +#define FL_NORMAL_POSITIONER 0 +forms_constructor(Fl_Positioner, fl_add_positioner) +inline void fl_set_positioner_xvalue(Fl_Widget* o, double v) { + ((Fl_Positioner*)o)->xvalue(v);} +inline double fl_get_positioner_xvalue(Fl_Widget* o) { + return ((Fl_Positioner*)o)->xvalue();} +inline void fl_set_positioner_xbounds(Fl_Widget* o, double a, double b) { + ((Fl_Positioner*)o)->xbounds(a,b);} +inline void fl_get_positioner_xbounds(Fl_Widget* o, float* a, float* b) { + *a = float(((Fl_Positioner*)o)->xminimum()); + *b = float(((Fl_Positioner*)o)->xmaximum()); +} +inline void fl_set_positioner_yvalue(Fl_Widget* o, double v) { + ((Fl_Positioner*)o)->yvalue(v);} +inline double fl_get_positioner_yvalue(Fl_Widget* o) { + return ((Fl_Positioner*)o)->yvalue();} +inline void fl_set_positioner_ybounds(Fl_Widget* o, double a, double b) { + ((Fl_Positioner*)o)->ybounds(a,b);} +inline void fl_get_positioner_ybounds(Fl_Widget* o, float* a, float* b) { + *a = float(((Fl_Positioner*)o)->yminimum()); + *b = float(((Fl_Positioner*)o)->ymaximum()); +} +inline void fl_set_positioner_xstep(Fl_Widget* o, double v) { + ((Fl_Positioner*)o)->xstep(v);} +inline void fl_set_positioner_ystep(Fl_Widget* o, double v) { + ((Fl_Positioner*)o)->ystep(v);} +inline void fl_set_positioner_return(Fl_Widget* o, int v) { + ((Fl_Positioner*)o)->when((Fl_When)(v|FL_WHEN_RELEASE));} + +#include "Fl_Slider.H" + +#define FL_HOR_BROWSER_SLIDER FL_HOR_SLIDER +#define FL_VERT_BROWSER_SLIDER FL_VERT_SLIDER + +forms_constructort(Fl_Slider, fl_add_slider) +#define FL_SLIDER_COL1 FL_GRAY +inline void fl_set_slider_value(Fl_Widget* o, double v) { + ((Fl_Slider*)o)->value(v);} +inline double fl_get_slider_value(Fl_Widget* o) { + return ((Fl_Slider*)o)->value();} +inline void fl_set_slider_bounds(Fl_Widget* o, double a, double b) { + ((Fl_Slider*)o)->bounds(a, b);} +inline void fl_get_slider_bounds(Fl_Widget* o, float* a, float* b) { + *a = float(((Fl_Slider*)o)->minimum()); + *b = float(((Fl_Slider*)o)->maximum()); +} +inline void fl_set_slider_return(Fl_Widget* o, int i) { + ((Fl_Slider*)o)->when((Fl_When)(i|FL_WHEN_RELEASE));} +inline void fl_set_slider_step(Fl_Widget* o, double v) { + ((Fl_Slider*)o)->step(v);} +// inline void fl_set_slider_increment(Fl_Widget* o, double v, double); +inline void fl_set_slider_size(Fl_Widget* o, double v) { + ((Fl_Slider*)o)->slider_size(v);} + +#include "Fl_Value_Slider.H" +forms_constructor(Fl_Value_Slider, fl_add_valslider) + +inline void fl_set_slider_precision(Fl_Widget* o, int i) { + ((Fl_Value_Slider*)o)->precision(i);} +// filter function! + +// The forms text object was the same as an Fl_Box except it inverted the +// meaning of FL_ALIGN_INSIDE. Implementation in forms.cxx +class FL_EXPORT Fl_FormsText : public Fl_Widget { +protected: + void draw(); +public: + Fl_FormsText(Fl_Boxtype b, int X, int Y, int W, int H, const char* l=0) + : Fl_Widget(X,Y,W,H,l) {box(b); align(FL_ALIGN_LEFT);} +}; +#define FL_NORMAL_TEXT FL_NO_BOX +forms_constructorb(Fl_FormsText, fl_add_text) + +#include "Fl_Timer.H" +forms_constructort(Fl_Timer, fl_add_timer) +inline void fl_set_timer(Fl_Widget* o, double v) {((Fl_Timer*)o)->value(v);} +inline double fl_get_timer(Fl_Widget* o) {return ((Fl_Timer*)o)->value();} +inline void fl_suspend_timer(Fl_Widget* o) {((Fl_Timer*)o)->suspended(1);} +inline void fl_resume_timer(Fl_Widget* o) {((Fl_Timer*)o)->suspended(0);} +inline void fl_set_timer_countup(Fl_Widget* o,char d) {((Fl_Timer*)o)->direction(d);} +void fl_gettime(long* sec, long* usec); + +// Fl_XYPlot nyi + + +// stuff from DDForms: + +inline int fl_double_click() {return Fl::event_clicks();} +inline void fl_draw() {Fl::flush();} + +#endif /* define __FORMS_H__ */ + +// +// End of "$Id: forms.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/gl.h b/mod/maxgui.mod/fltkmaxgui.mod/FL/gl.h new file mode 100644 index 0000000..68574b6 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/gl.h @@ -0,0 +1,112 @@ +// +// "$Id: gl.h 7903 2010-11-28 21:06:39Z matt $" +// +// OpenGL header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// You must include this instead of GL/gl.h to get the Microsoft +// APIENTRY stuff included (from ) prior to the OpenGL +// header files. +// +// This file also provides "missing" OpenGL functions, and +// gl_start() and gl_finish() to allow OpenGL to be used in any window +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/** \file gl.h + * This file defines wrapper functions for OpenGL in FLTK + * + * To use OpenGL from within an FLTK application you MUST use gl_visual() + * to select the default visual before doing show() on any windows. Mesa + * will crash if yoy try to use a visual not returned by glxChooseVidual. + * + * This does not work with Fl_Double_Window's! It will try to draw + * into the front buffer. Depending on the system this will either + * crash or do nothing (when pixmaps are being used as back buffer + * and GL is being done by hardware), work correctly (when GL is done + * with software, such as Mesa), or draw into the front buffer and + * be erased when the buffers are swapped (when double buffer hardware + * is being used) + */ + +#ifndef FL_gl_H +# define FL_gl_H + +# include "Enumerations.H" // for color names +# ifdef WIN32 +# include +# endif +# ifndef APIENTRY +# if defined(__CYGWIN__) +# define APIENTRY __attribute__ ((__stdcall__)) +# else +# define APIENTRY +# endif +# endif + +# ifdef __APPLE__ +# include +# else +# include +# endif + +FL_EXPORT void gl_start(); +FL_EXPORT void gl_finish(); + +FL_EXPORT void gl_color(Fl_Color i); +/** back compatability */ +inline void gl_color(int c) {gl_color((Fl_Color)c);} + +FL_EXPORT void gl_rect(int x,int y,int w,int h); +/** + Fills the given rectangle with the current color. + \see gl_rect(int x, int y, int w, int h) + */ +inline void gl_rectf(int x,int y,int w,int h) {glRecti(x,y,x+w,y+h);} + +FL_EXPORT void gl_font(int fontid, int size); +FL_EXPORT int gl_height(); +FL_EXPORT int gl_descent(); +FL_EXPORT double gl_width(const char *); +FL_EXPORT double gl_width(const char *, int n); +FL_EXPORT double gl_width(uchar); + +FL_EXPORT void gl_draw(const char*); +FL_EXPORT void gl_draw(const char*, int n); +FL_EXPORT void gl_draw(const char*, int x, int y); +FL_EXPORT void gl_draw(const char*, float x, float y); +FL_EXPORT void gl_draw(const char*, int n, int x, int y); +FL_EXPORT void gl_draw(const char*, int n, float x, float y); +FL_EXPORT void gl_draw(const char*, int x, int y, int w, int h, Fl_Align); +FL_EXPORT void gl_measure(const char*, int& x, int& y); +#ifdef __APPLE__ +extern FL_EXPORT void gl_texture_pile_height(int max); +extern FL_EXPORT int gl_texture_pile_height(); +#endif + +FL_EXPORT void gl_draw_image(const uchar *, int x,int y,int w,int h, int d=3, int ld=0); + +#endif // !FL_gl_H + +// +// End of "$Id: gl.h 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/gl2opengl.h b/mod/maxgui.mod/fltkmaxgui.mod/FL/gl2opengl.h new file mode 100644 index 0000000..b89614e --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/gl2opengl.h @@ -0,0 +1,35 @@ +/* gl.h + + GL to OpenGL translator. + If you include this, you might be able to port old GL programs. + There are also much better emulators available on the net. + +*/ + +#include +#include "gl_draw.H" + +inline void clear() {glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);} +#define RGBcolor(r,g,b) glColor3ub(r,g,b) +#define bgnline() glBegin(GL_LINE_STRIP) +#define bgnpolygon() glBegin(GL_POLYGON) +#define bgnclosedline() glBegin(GL_LINE_LOOP) +#define endline() glEnd() +#define endpolygon() glEnd() +#define endclosedline() glEnd() +#define v2f(v) glVertex2fv(v) +#define v2s(v) glVertex2sv(v) +#define cmov(x,y,z) glRasterPos3f(x,y,z) +#define charstr(s) gl_draw(s) +#define fmprstr(s) gl_draw(s) +typedef float Matrix[4][4]; +inline void pushmatrix() {glPushMatrix();} +inline void popmatrix() {glPopMatrix();} +inline void multmatrix(Matrix m) {glMultMatrixf((float *)m);} +inline void color(int n) {glIndexi(n);} +inline void rect(int x,int y,int r,int t) {gl_rect(x,y,r-x,t-y);} +inline void rectf(int x,int y,int r,int t) {glRectf(x,y,r+1,t+1);} +inline void recti(int x,int y,int r,int t) {gl_rect(x,y,r-x,t-y);} +inline void rectfi(int x,int y,int r,int t) {glRecti(x,y,r+1,t+1);} +inline void rects(int x,int y,int r,int t) {gl_rect(x,y,r-x,t-y);} +inline void rectfs(int x,int y,int r,int t) {glRects(x,y,r+1,t+1);} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/gl_draw.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/gl_draw.H new file mode 100644 index 0000000..ad0f819 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/gl_draw.H @@ -0,0 +1,35 @@ +// +// "$Id: gl_draw.H 7903 2010-11-28 21:06:39Z matt $" +// +// OpenGL header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include "gl.h" + +extern FL_EXPORT void gl_remove_displaylist_fonts(); + + +// +// End of "$Id: gl_draw.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/glu.h b/mod/maxgui.mod/fltkmaxgui.mod/FL/glu.h new file mode 100644 index 0000000..9156198 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/glu.h @@ -0,0 +1,60 @@ +// +// "$Id: glu.h 7903 2010-11-28 21:06:39Z matt $" +// +// GLu header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// You must include this instead of GL/gl.h to get the Microsoft +// APIENTRY stuff included (from ) prior to the OpenGL +// header files. +// +// This file also provides "missing" OpenGL functions, and +// gl_start() and gl_finish() to allow OpenGL to be used in any window +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef FL_glu_H +# define FL_glu_H + +# include "Enumerations.H" // for color names +# ifdef WIN32 +# include +# endif +# ifndef APIENTRY +# if defined(__CYGWIN__) +# define APIENTRY __attribute__ ((__stdcall__)) +# else +# define APIENTRY +# endif +# endif + +# ifdef __APPLE__ +# include +# else +# include +# endif + +#endif // !FL_glu_H + +// +// End of "$Id: glu.h 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/glut.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/glut.H new file mode 100644 index 0000000..9e8b966 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/glut.H @@ -0,0 +1,491 @@ +// +// "$Id: glut.H 7903 2010-11-28 21:06:39Z matt $" +// +// GLUT emulation header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Emulation of GLUT using fltk. + +// GLUT is Copyright (c) Mark J. Kilgard, 1994, 1995, 1996: +// "This program is freely distributable without licensing fees and is +// provided without guarantee or warrantee expressed or implied. This +// program is -not- in the public domain." + +// Although I have copied the GLUT API, none of my code is based on +// any GLUT implementation details and is therefore covered by the LGPL. + +// Commented out lines indicate parts of GLUT that are not emulated. + +#ifndef Fl_glut_H +# define Fl_glut_H + +# include "gl.h" + + +# include "Fl.H" +# include "Fl_Gl_Window.H" + +/** + GLUT is emulated using this window class and these static variables + (plus several more static variables hidden in glut_compatability.cxx): +*/ +class FL_EXPORT Fl_Glut_Window : public Fl_Gl_Window { + void _init(); + int mouse_down; +protected: + void draw(); + void draw_overlay(); + int handle(int); +public: // so the inline functions work + int number; + int menu[3]; + void make_current(); + void (*display)(); + void (*overlaydisplay)(); + void (*reshape)(int w, int h); + void (*keyboard)(uchar, int x, int y); + void (*mouse)(int b, int state, int x, int y); + void (*motion)(int x, int y); + void (*passivemotion)(int x, int y); + void (*entry)(int); + void (*visibility)(int); + void (*special)(int, int x, int y); + Fl_Glut_Window(int w, int h, const char *); + Fl_Glut_Window(int x, int y, int w, int h, const char *); + ~Fl_Glut_Window(); +}; + +extern FL_EXPORT Fl_Glut_Window *glut_window; // the current window +extern FL_EXPORT int glut_menu; // the current menu + +// function pointers that are not per-window: +extern FL_EXPORT void (*glut_idle_function)(); +extern FL_EXPORT void (*glut_menustate_function)(int); +extern FL_EXPORT void (*glut_menustatus_function)(int,int,int); + +//////////////////////////////////////////////////////////////// + +//# define GLUT_API_VERSION This does not match any version of GLUT exactly... + +FL_EXPORT void glutInit(int *argcp, char **argv); // creates first window + +FL_EXPORT void glutInitDisplayMode(unsigned int mode); +// the FL_ symbols have the same value as the GLUT ones: +# define GLUT_RGB FL_RGB +# define GLUT_RGBA FL_RGB +# define GLUT_INDEX FL_INDEX +# define GLUT_SINGLE FL_SINGLE +# define GLUT_DOUBLE FL_DOUBLE +# define GLUT_ACCUM FL_ACCUM +# define GLUT_ALPHA FL_ALPHA +# define GLUT_DEPTH FL_DEPTH +# define GLUT_STENCIL FL_STENCIL +# define GLUT_MULTISAMPLE FL_MULTISAMPLE +# define GLUT_STEREO FL_STEREO +// # define GLUT_LUMINANCE 512 + +FL_EXPORT void glutInitWindowPosition(int x, int y); + +FL_EXPORT void glutInitWindowSize(int w, int h); + +FL_EXPORT void glutMainLoop(); + +FL_EXPORT int glutCreateWindow(char *title); +FL_EXPORT int glutCreateWindow(const char *title); + +FL_EXPORT int glutCreateSubWindow(int win, int x, int y, int width, int height); + +FL_EXPORT void glutDestroyWindow(int win); + +inline void glutPostRedisplay() {glut_window->redraw();} + +FL_EXPORT void glutPostWindowRedisplay(int win); + +FL_EXPORT void glutSwapBuffers(); + +inline int glutGetWindow() {return glut_window->number;} + +FL_EXPORT void glutSetWindow(int win); + +inline void glutSetWindowTitle(char *t) {glut_window->label(t);} + +inline void glutSetIconTitle(char *t) {glut_window->iconlabel(t);} + +inline void glutPositionWindow(int x, int y) {glut_window->position(x,y);} + +inline void glutReshapeWindow(int w, int h) {glut_window->size(w,h);} + +inline void glutPopWindow() {glut_window->show();} + +inline void glutPushWindow() { /* do nothing */ } + +inline void glutIconifyWindow() {glut_window->iconize();} + +inline void glutShowWindow() {glut_window->show();} + +inline void glutHideWindow() {glut_window->hide();} + +inline void glutFullScreen() {glut_window->fullscreen();} + +inline void glutSetCursor(Fl_Cursor cursor) {glut_window->cursor(cursor);} +// notice that the numeric values are different than glut: +# define GLUT_CURSOR_RIGHT_ARROW ((Fl_Cursor)2) +# define GLUT_CURSOR_LEFT_ARROW ((Fl_Cursor)67) +# define GLUT_CURSOR_INFO FL_CURSOR_HAND +# define GLUT_CURSOR_DESTROY ((Fl_Cursor)45) +# define GLUT_CURSOR_HELP FL_CURSOR_HELP +# define GLUT_CURSOR_CYCLE ((Fl_Cursor)26) +# define GLUT_CURSOR_SPRAY ((Fl_Cursor)63) +# define GLUT_CURSOR_WAIT FL_CURSOR_WAIT +# define GLUT_CURSOR_TEXT FL_CURSOR_INSERT +# define GLUT_CURSOR_CROSSHAIR FL_CURSOR_CROSS +# define GLUT_CURSOR_UP_DOWN FL_CURSOR_NS +# define GLUT_CURSOR_LEFT_RIGHT FL_CURSOR_WE +# define GLUT_CURSOR_TOP_SIDE FL_CURSOR_N +# define GLUT_CURSOR_BOTTOM_SIDE FL_CURSOR_S +# define GLUT_CURSOR_LEFT_SIDE FL_CURSOR_W +# define GLUT_CURSOR_RIGHT_SIDE FL_CURSOR_E +# define GLUT_CURSOR_TOP_LEFT_CORNER FL_CURSOR_NW +# define GLUT_CURSOR_TOP_RIGHT_CORNER FL_CURSOR_NE +# define GLUT_CURSOR_BOTTOM_RIGHT_CORNER FL_CURSOR_SE +# define GLUT_CURSOR_BOTTOM_LEFT_CORNER FL_CURSOR_SW +# define GLUT_CURSOR_INHERIT FL_CURSOR_DEFAULT +# define GLUT_CURSOR_NONE FL_CURSOR_NONE +# define GLUT_CURSOR_FULL_CROSSHAIR FL_CURSOR_CROSS + +inline void glutWarpPointer(int, int) { /* do nothing */ } + +inline void glutEstablishOverlay() {glut_window->make_overlay_current();} + +inline void glutRemoveOverlay() {glut_window->hide_overlay();} + +inline void glutUseLayer(GLenum layer) { + layer ? glut_window->make_overlay_current() : glut_window->make_current();} +enum {GLUT_NORMAL, GLUT_OVERLAY}; + +inline void glutPostOverlayRedisplay() {glut_window->redraw_overlay();} + +inline void glutShowOverlay() {glut_window->redraw_overlay();} + +inline void glutHideOverlay() {glut_window->hide_overlay();} + +FL_EXPORT int glutCreateMenu(void (*)(int)); + +FL_EXPORT void glutDestroyMenu(int menu); + +inline int glutGetMenu() {return glut_menu;} + +inline void glutSetMenu(int m) {glut_menu = m;} + +FL_EXPORT void glutAddMenuEntry(char *label, int value); + +FL_EXPORT void glutAddSubMenu(char *label, int submenu); + +FL_EXPORT void glutChangeToMenuEntry(int item, char *labela, int value); + +FL_EXPORT void glutChangeToSubMenu(int item, char *label, int submenu); + +FL_EXPORT void glutRemoveMenuItem(int item); + +inline void glutAttachMenu(int b) {glut_window->menu[b] = glut_menu;} + +inline void glutDetachMenu(int b) {glut_window->menu[b] = 0;} + +inline void glutDisplayFunc(void (*f)()) {glut_window->display = f;} + +inline void glutReshapeFunc(void (*f)(int w, int h)) {glut_window->reshape=f;} + +inline void glutKeyboardFunc(void (*f)(uchar key, int x, int y)) { + glut_window->keyboard = f;} + +inline void glutMouseFunc(void (*f)(int b, int state, int x, int y)) { + glut_window->mouse = f;} +# define GLUT_LEFT_BUTTON 0 +# define GLUT_MIDDLE_BUTTON 1 +# define GLUT_RIGHT_BUTTON 2 +# define GLUT_DOWN 0 +# define GLUT_UP 1 + +inline void glutMotionFunc(void (*f)(int x, int y)) {glut_window->motion= f;} + +inline void glutPassiveMotionFunc(void (*f)(int x, int y)) { + glut_window->passivemotion= f;} + +inline void glutEntryFunc(void (*f)(int s)) {glut_window->entry = f;} +enum {GLUT_LEFT, GLUT_ENTERED}; + +inline void glutVisibilityFunc(void (*f)(int s)) {glut_window->visibility=f;} +enum {GLUT_NOT_VISIBLE, GLUT_VISIBLE}; + +FL_EXPORT void glutIdleFunc(void (*f)()); + +// Warning: this cast may not work on all machines: +inline void glutTimerFunc(unsigned int msec, void (*f)(int), int value) { + Fl::add_timeout(msec*.001, (void (*)(void *))f, (void *)value); +} + +inline void glutMenuStateFunc(void (*f)(int state)) { + glut_menustate_function = f;} + +inline void glutMenuStatusFunc(void (*f)(int status, int x, int y)) { + glut_menustatus_function = f;} +enum {GLUT_MENU_NOT_IN_USE, GLUT_MENU_IN_USE}; + +inline void glutSpecialFunc(void (*f)(int key, int x, int y)) { + glut_window->special = f;} +# define GLUT_KEY_F1 1 +# define GLUT_KEY_F2 2 +# define GLUT_KEY_F3 3 +# define GLUT_KEY_F4 4 +# define GLUT_KEY_F5 5 +# define GLUT_KEY_F6 6 +# define GLUT_KEY_F7 7 +# define GLUT_KEY_F8 8 +# define GLUT_KEY_F9 9 +# define GLUT_KEY_F10 10 +# define GLUT_KEY_F11 11 +# define GLUT_KEY_F12 12 +// WARNING: Different values than GLUT uses: +# define GLUT_KEY_LEFT FL_Left +# define GLUT_KEY_UP FL_Up +# define GLUT_KEY_RIGHT FL_Right +# define GLUT_KEY_DOWN FL_Down +# define GLUT_KEY_PAGE_UP FL_Page_Up +# define GLUT_KEY_PAGE_DOWN FL_Page_Down +# define GLUT_KEY_HOME FL_Home +# define GLUT_KEY_END FL_End +# define GLUT_KEY_INSERT FL_Insert + +//inline void glutSpaceballMotionFunc(void (*)(int x, int y, int z)); + +//inline void glutSpaceballRotateFunc(void (*)(int x, int y, int z)); + +//inline void glutSpaceballButtonFunc(void (*)(int button, int state)); + +//inline void glutButtonBoxFunc(void (*)(int button, int state)); + +//inline void glutDialsFunc(void (*)(int dial, int value)); + +//inline void glutTabletMotionFunc(void (*)(int x, int y)); + +//inline void glutTabletButtonFunc(void (*)(int button, int state, int x, int y)); + +inline void glutOverlayDisplayFunc(void (*f)()) { + glut_window->overlaydisplay = f;} + +//inline void glutWindowStatusFunc(void (*)(int state)); +//enum {GLUT_HIDDEN, GLUT_FULLY_RETAINED, GLUT_PARTIALLY_RETAINED, +// GLUT_FULLY_COVERED}; + +//inline void glutSetColor(int, GLfloat red, GLfloat green, GLfloat blue); + +//inline GLfloat glutGetColor(int ndx, int component); +//#define GLUT_RED 0 +//#define GLUT_GREEN 1 +//#define GLUT_BLUE 2 + +//inline void glutCopyColormap(int win); + +// Warning: values are changed from GLUT! +// Also relies on the GL_ symbols having values greater than 100 +FL_EXPORT int glutGet(GLenum type); +enum { + GLUT_RETURN_ZERO = 0, + GLUT_WINDOW_X, + GLUT_WINDOW_Y, + GLUT_WINDOW_WIDTH, + GLUT_WINDOW_HEIGHT, + GLUT_WINDOW_PARENT, + GLUT_SCREEN_WIDTH, + GLUT_SCREEN_HEIGHT, + GLUT_MENU_NUM_ITEMS, + GLUT_DISPLAY_MODE_POSSIBLE, + GLUT_INIT_WINDOW_X, + GLUT_INIT_WINDOW_Y, + GLUT_INIT_WINDOW_WIDTH, + GLUT_INIT_WINDOW_HEIGHT, + GLUT_INIT_DISPLAY_MODE, + GLUT_WINDOW_BUFFER_SIZE, + GLUT_VERSION +//GLUT_WINDOW_NUM_CHILDREN, +//GLUT_WINDOW_CURSOR, +//GLUT_SCREEN_WIDTH_MM, +//GLUT_SCREEN_HEIGHT_MM, +//GLUT_ELAPSED_TIME, +}; + +# define GLUT_WINDOW_STENCIL_SIZE GL_STENCIL_BITS +# define GLUT_WINDOW_DEPTH_SIZE GL_DEPTH_BITS +# define GLUT_WINDOW_RED_SIZE GL_RED_BITS +# define GLUT_WINDOW_GREEN_SIZE GL_GREEN_BITS +# define GLUT_WINDOW_BLUE_SIZE GL_BLUE_BITS +# define GLUT_WINDOW_ALPHA_SIZE GL_ALPHA_BITS +# define GLUT_WINDOW_ACCUM_RED_SIZE GL_ACCUM_RED_BITS +# define GLUT_WINDOW_ACCUM_GREEN_SIZE GL_ACCUM_GREEN_BITS +# define GLUT_WINDOW_ACCUM_BLUE_SIZE GL_ACCUM_BLUE_BITS +# define GLUT_WINDOW_ACCUM_ALPHA_SIZE GL_ACCUM_ALPHA_BITS +# define GLUT_WINDOW_DOUBLEBUFFER GL_DOUBLEBUFFER +# define GLUT_WINDOW_RGBA GL_RGBA +# define GLUT_WINDOW_COLORMAP_SIZE GL_INDEX_BITS +# ifdef GL_SAMPLES_SGIS +# define GLUT_WINDOW_NUM_SAMPLES GL_SAMPLES_SGIS +# else +# define GLUT_WINDOW_NUM_SAMPLES GLUT_RETURN_ZERO +# endif +# define GLUT_WINDOW_STEREO GL_STEREO + +# define GLUT_HAS_KEYBOARD 600 +# define GLUT_HAS_MOUSE 601 +# define GLUT_HAS_SPACEBALL 602 +# define GLUT_HAS_DIAL_AND_BUTTON_BOX 603 +# define GLUT_HAS_TABLET 604 +# define GLUT_NUM_MOUSE_BUTTONS 605 +# define GLUT_NUM_SPACEBALL_BUTTONS 606 +# define GLUT_NUM_BUTTON_BOX_BUTTONS 607 +# define GLUT_NUM_DIALS 608 +# define GLUT_NUM_TABLET_BUTTONS 609 +FL_EXPORT int glutDeviceGet(GLenum type); + +// WARNING: these values are different than GLUT uses: +# define GLUT_ACTIVE_SHIFT FL_SHIFT +# define GLUT_ACTIVE_CTRL FL_CTRL +# define GLUT_ACTIVE_ALT FL_ALT +inline int glutGetModifiers() {return Fl::event_state() & (GLUT_ACTIVE_SHIFT | GLUT_ACTIVE_CTRL | GLUT_ACTIVE_ALT);} + +FL_EXPORT int glutLayerGet(GLenum); +# define GLUT_OVERLAY_POSSIBLE 800 +//#define GLUT_LAYER_IN_USE 801 +//#define GLUT_HAS_OVERLAY 802 +# define GLUT_TRANSPARENT_INDEX 803 +# define GLUT_NORMAL_DAMAGED 804 +# define GLUT_OVERLAY_DAMAGED 805 + +extern "C" { +typedef void (*GLUTproc)(); +} + +FL_EXPORT GLUTproc glutGetProcAddress(const char *procName); + +//inline int glutVideoResizeGet(GLenum param); +//#define GLUT_VIDEO_RESIZE_POSSIBLE 900 +//#define GLUT_VIDEO_RESIZE_IN_USE 901 +//#define GLUT_VIDEO_RESIZE_X_DELTA 902 +//#define GLUT_VIDEO_RESIZE_Y_DELTA 903 +//#define GLUT_VIDEO_RESIZE_WIDTH_DELTA 904 +//#define GLUT_VIDEO_RESIZE_HEIGHT_DELTA 905 +//#define GLUT_VIDEO_RESIZE_X 906 +//#define GLUT_VIDEO_RESIZE_Y 907 +//#define GLUT_VIDEO_RESIZE_WIDTH 908 +//#define GLUT_VIDEO_RESIZE_HEIGHT 909 + +//inline void glutSetupVideoResizing(); + +//inline void glutStopVideoResizing(); + +//inline void glutVideoResize(int x, int y, int width, int height); + +//inline void glutVideoPan(int x, int y, int width, int height); + +// Font argument must be a void* for compatability, so... +/** fltk glut font/size attributes used in the glutXXX functions */ +struct Fl_Glut_Bitmap_Font {Fl_Font font; Fl_Fontsize size;}; + +extern FL_EXPORT struct Fl_Glut_Bitmap_Font + glutBitmap9By15, glutBitmap8By13, glutBitmapTimesRoman10, + glutBitmapTimesRoman24, glutBitmapHelvetica10, glutBitmapHelvetica12, + glutBitmapHelvetica18; +# define GLUT_BITMAP_9_BY_15 (&glutBitmap9By15) +# define GLUT_BITMAP_8_BY_13 (&glutBitmap8By13) +# define GLUT_BITMAP_TIMES_ROMAN_10 (&glutBitmapTimesRoman10) +# define GLUT_BITMAP_TIMES_ROMAN_24 (&glutBitmapTimesRoman24) +# define GLUT_BITMAP_HELVETICA_10 (&glutBitmapHelvetica10) +# define GLUT_BITMAP_HELVETICA_12 (&glutBitmapHelvetica12) +# define GLUT_BITMAP_HELVETICA_18 (&glutBitmapHelvetica18) + +FL_EXPORT void glutBitmapCharacter(void *font, int character); +FL_EXPORT int glutBitmapHeight(void *font); +FL_EXPORT int glutBitmapLength(void *font, const unsigned char *string); +FL_EXPORT void glutBitmapString(void *font, const unsigned char *string); +FL_EXPORT int glutBitmapWidth(void *font, int character); + +FL_EXPORT int glutExtensionSupported(char *name); + +/* GLUT stroked font sub-API */ +struct Fl_Glut_StrokeVertex { + GLfloat X, Y; +}; + +struct Fl_Glut_StrokeStrip { + int Number; + const Fl_Glut_StrokeVertex* Vertices; +}; + +struct Fl_Glut_StrokeChar { + GLfloat Right; + int Number; + const Fl_Glut_StrokeStrip* Strips; +}; + +struct Fl_Glut_StrokeFont { + char* Name; // The source font name + int Quantity; // Number of chars in font + GLfloat Height; // Height of the characters + const Fl_Glut_StrokeChar** Characters;// The characters mapping +}; +extern FL_EXPORT Fl_Glut_StrokeFont glutStrokeRoman; +extern FL_EXPORT Fl_Glut_StrokeFont glutStrokeMonoRoman; +# define GLUT_STROKE_ROMAN (&glutStrokeRoman) +# define GLUT_STROKE_MONO_ROMAN (&glutStrokeMonoRoman) + +FL_EXPORT void glutStrokeCharacter(void *font, int character); +FL_EXPORT GLfloat glutStrokeHeight(void *font); +FL_EXPORT int glutStrokeLength(void *font, const unsigned char *string); +FL_EXPORT void glutStrokeString(void *font, const unsigned char *string); +FL_EXPORT int glutStrokeWidth(void *font, int character); + +/* GLUT pre-built models sub-API */ +FL_EXPORT void glutWireSphere(GLdouble radius, GLint slices, GLint stacks); +FL_EXPORT void glutSolidSphere(GLdouble radius, GLint slices, GLint stacks); +FL_EXPORT void glutWireCone(GLdouble base, GLdouble height, GLint slices, GLint stacks); +FL_EXPORT void glutSolidCone(GLdouble base, GLdouble height, GLint slices, GLint stacks); +FL_EXPORT void glutWireCube(GLdouble size); +FL_EXPORT void glutSolidCube(GLdouble size); +FL_EXPORT void glutWireTorus(GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings); +FL_EXPORT void glutSolidTorus(GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings); +FL_EXPORT void glutWireDodecahedron(); +FL_EXPORT void glutSolidDodecahedron(); +FL_EXPORT void glutWireTeapot(GLdouble size); +FL_EXPORT void glutSolidTeapot(GLdouble size); +FL_EXPORT void glutWireOctahedron(); +FL_EXPORT void glutSolidOctahedron(); +FL_EXPORT void glutWireTetrahedron(); +FL_EXPORT void glutSolidTetrahedron(); +FL_EXPORT void glutWireIcosahedron(); +FL_EXPORT void glutSolidIcosahedron(); + +#endif // !Fl_glut_H + +// +// End of "$Id: glut.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/mac.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/mac.H new file mode 100644 index 0000000..b0b5152 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/mac.H @@ -0,0 +1,198 @@ +// +// "$Id: mac.H 7903 2010-11-28 21:06:39Z matt $" +// +// Mac header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Do not directly include this file, instead use . It will +// include this file if "__APPLE__" is defined. This is to encourage +// portability of even the system-specific code... +#ifndef FL_DOXYGEN + +#if !defined(Fl_X_H) +# error "Never use directly; include instead." +#endif // !Fl_X_H + +// Standard MacOS Carbon API includes... +#include + +#ifndef MAC_OS_X_VERSION_10_3 +#define MAC_OS_X_VERSION_10_3 1030 +#endif +#ifndef MAC_OS_X_VERSION_10_4 +#define MAC_OS_X_VERSION_10_4 1040 +#endif +#ifndef MAC_OS_X_VERSION_10_5 +#define MAC_OS_X_VERSION_10_5 1050 +#endif +#ifndef MAC_OS_X_VERSION_10_6 +#define MAC_OS_X_VERSION_10_6 1060 +#endif +#ifndef MAC_OS_X_VERSION_MAX_ALLOWED +#define MAC_OS_X_VERSION_MAX_ALLOWED MAC_OS_X_VERSION_10_3 +#endif + +#ifndef CGFLOAT_DEFINED //appears with 10.5 in CGBase.h +#if defined(__LP64__) && __LP64__ +typedef double CGFloat; +#else +typedef float CGFloat; +#endif +#endif // CGFLOAT_DEFINED + + +// Now make some fixes to the headers... +#undef check // Dunno where this comes from... + +// Some random X equivalents +struct XPoint { int x, y; }; +struct XRectangle {int x, y, width, height;}; + +typedef void *Window; // this is really a pter to the subclass FLWindow of NSWindow +typedef struct flCocoaRegion { + int count; + CGRect *rects; +} *Fl_Region; // a region is the union of a series of rectangles +extern CGRect fl_cgrectmake_cocoa(int x, int y, int w, int h); + +inline Fl_Region XRectangleRegion(int x, int y, int w, int h) { + Fl_Region R = (Fl_Region)malloc(sizeof(*R)); + R->count = 1; + R->rects = (CGRect *)malloc(sizeof(CGRect)); + *(R->rects) = fl_cgrectmake_cocoa(x, y, w, h); + return R; +} +inline void XDestroyRegion(Fl_Region r) { + if(r) { + free(r->rects); + free(r); + } +} +extern void *fl_default_cursor; +extern void *fl_system_menu; +typedef CGContextRef Fl_Offscreen; +typedef CGImageRef Fl_Bitmask; + +void fl_clip_region(Fl_Region); + +# include "Fl_Window.H" + +// This object contains all mac-specific stuff about a window: +// WARNING: this object is highly subject to change! +class Fl_X +{ +public: + Window xid; // Cocoa: FLWindow* ; Carbon: WindowRef + Fl_Offscreen other_xid; // pointer for offscreen bitmaps (doublebuffer) + Fl_Window *w; // FLTK window for + Fl_Region region; + Fl_Region subRegion; // region for this specific subwindow + Fl_X *next; // linked tree to support subwindows + Fl_X *xidChildren, *xidNext; // more subwindow tree + int wait_for_expose; + void *cursor; // is really NSCursor* + static Fl_X* first; + static Fl_X* i(const Fl_Window* w) {return w->i;} + static int fake_X_wm(const Fl_Window*,int&,int&,int&,int&,int&); + static void make(Fl_Window*); + void flush(); + // Quartz additions: + CGContextRef gc; // graphics context (NULL when using QD) + static void q_fill_context(); // fill a Quartz context with current FLTK state + static void q_clear_clipping(); // remove all clipping from a Quartz context + static void q_release_context(Fl_X *x=0); // free all resources associated with fl_gc + static void q_begin_image(CGRect&, int x, int y, int w, int h); + static void q_end_image(); +}; + +extern void MacDestroyWindow(Fl_Window*,void *); +extern void MacMapWindow(Fl_Window*,void *); +extern void MacUnmapWindow(Fl_Window*,void *); +extern WindowRef MACwindowRef(Fl_Window *w); +extern Fl_Region MacRectRegionIntersect(Fl_Region current, int x,int y,int w, int h); +extern void MacCollapseWindow(Window w); + +extern int MacUnlinkWindow(Fl_X*,Fl_X*start=0L); + +inline Window fl_xid(const Fl_Window*w) +{ + return Fl_X::i(w)->xid; +} + +extern struct Fl_XMap { + RGBColor rgb; + ulong pen; +} *fl_current_xmap; + +extern FL_EXPORT void *fl_display; +extern FL_EXPORT Window fl_window; +extern FL_EXPORT CGContextRef fl_gc; +extern FL_EXPORT class Fl_Sys_Menu_Bar *fl_sys_menu_bar; + + +extern Fl_Offscreen fl_create_offscreen(int w, int h); +extern void fl_copy_offscreen(int x,int y,int w,int h, Fl_Offscreen gWorld, int srcx,int srcy); +extern void fl_delete_offscreen(Fl_Offscreen gWorld); +extern void fl_begin_offscreen(Fl_Offscreen gWorld); +extern void fl_end_offscreen(); + + +extern FL_EXPORT Fl_Bitmask fl_create_bitmask(int w, int h, const uchar *data); +extern FL_EXPORT Fl_Bitmask fl_create_alphamask(int w, int h, int d, int ld, const uchar *data); +extern FL_EXPORT void fl_delete_bitmask(Fl_Bitmask bm); + +extern void fl_open_display(); + +extern FL_EXPORT int fl_parse_color(const char* p, uchar& r, uchar& g, uchar& b); +#endif // FL_DOXYGEN + +/** \defgroup group_macosx Mac OS X-specific functions + @{ */ + +/** @brief Register a function called for each file dropped onto an application icon + * \note \#include + */ +extern void fl_open_callback(void (*cb)(const char *)); + +/** + * \brief Attaches a callback to the "About myprog" item of the system application menu. + * \note \#include + * + * \param cb a callback that will be called by "About myprog" menu item + * with NULL 1st argument. + * \param user_data a pointer transmitted as 2nd argument to the callback. + * \param shortcut optional shortcut to attach to the "About myprog" menu item (e.g., FL_META+'a') + */ +extern void fl_mac_set_about( Fl_Callback *cb, void *user_data, int shortcut = 0); + +/** The version number of the running Mac OS X (e.g., 0x1064 for 10.6.4) + */ +extern int fl_mac_os_version; + +/** @} */ + +// +// End of "$Id: mac.H 7903 2010-11-28 21:06:39Z matt $". +// + diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/math.h b/mod/maxgui.mod/fltkmaxgui.mod/FL/math.h new file mode 100644 index 0000000..e0f1d40 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/math.h @@ -0,0 +1,71 @@ +// +// "$Id: math.h 7903 2010-11-28 21:06:39Z matt $" +// +// Math header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Xcode on OS X includes files by recursing down into directories. +// This code catches the cycle and directly includes the required file. +#ifdef fl_math_h_cyclic_include +# include "/usr/include/math.h" +#endif + +#ifndef fl_math_h +# define fl_math_h + +# define fl_math_h_cyclic_include +# include +# undef fl_math_h_cyclic_include + +# ifdef __EMX__ +# include +# endif + + +# ifndef M_PI +# define M_PI 3.14159265358979323846 +# define M_PI_2 1.57079632679489661923 +# define M_PI_4 0.78539816339744830962 +# define M_1_PI 0.31830988618379067154 +# define M_2_PI 0.63661977236758134308 +# endif // !M_PI + +# ifndef M_SQRT2 +# define M_SQRT2 1.41421356237309504880 +# define M_SQRT1_2 0.70710678118654752440 +# endif // !M_SQRT2 + +# if (defined(WIN32) || defined(CRAY)) && !defined(__MINGW32__) && !defined(__MWERKS__) + +inline double rint(double v) {return floor(v+.5);} +inline double copysign(double a, double b) {return b<0 ? -a : a;} + +# endif // (WIN32 || CRAY) && !__MINGW32__ && !__MWERKS__ + +#endif // !fl_math_h + + +// +// End of "$Id: math.h 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/names.h b/mod/maxgui.mod/fltkmaxgui.mod/FL/names.h new file mode 100644 index 0000000..952acc0 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/names.h @@ -0,0 +1,123 @@ +// +// "$Id: names.h 7903 2010-11-28 21:06:39Z matt $" +// +// Event names header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Thanks to Greg Ercolano for this addition. + +#ifndef FL_NAMES_H +#define FL_NAMES_H + +/** \defgroup fl_events Events handling functions + @{ + */ + +/** + This is an array of event names you can use to convert event numbers into names. + + The array gets defined inline wherever your '\#include ' appears. + + \b Example: + \code + #include // array will be defined here + int MyClass::handle(int e) { + printf("Event was %s (%d)\n", fl_eventnames[e], e); + // ..resulting output might be e.g. "Event was FL_PUSH (1)".. + [..] + } + \endcode + */ +const char * const fl_eventnames[] = +{ + "FL_NO_EVENT", + "FL_PUSH", + "FL_RELEASE", + "FL_ENTER", + "FL_LEAVE", + "FL_DRAG", + "FL_FOCUS", + "FL_UNFOCUS", + "FL_KEYDOWN", + "FL_KEYUP", + "FL_CLOSE", + "FL_MOVE", + "FL_SHORTCUT", + "FL_DEACTIVATE", + "FL_ACTIVATE", + "FL_HIDE", + "FL_SHOW", + "FL_PASTE", + "FL_SELECTIONCLEAR", + "FL_MOUSEWHEEL", + "FL_DND_ENTER", + "FL_DND_DRAG", + "FL_DND_LEAVE", + "FL_DND_RELEASE", +}; + +/** + This is an array of font names you can use to convert font numbers into names. + + The array gets defined inline wherever your '\#include ' appears. + + \b Example: + \code + #include // array will be defined here + int MyClass::my_callback(Fl_Widget *w, void*) { + int fnum = w->labelfont(); + // Resulting output might be e.g. "Label's font is FL_HELVETICA (0)" + printf("Label's font is %s (%d)\n", fl_fontnames[fnum], fnum); + // ..resulting output might be e.g. "Label's font is FL_HELVETICA (0)".. + [..] + } + \endcode + */ +const char * const fl_fontnames[] = +{ + "FL_HELVETICA", + "FL_HELVETICA_BOLD", + "FL_HELVETICA_ITALIC", + "FL_HELVETICA_BOLD_ITALIC", + "FL_COURIER", + "FL_COURIER_BOLD", + "FL_COURIER_ITALIC", + "FL_COURIER_BOLD_ITALIC", + "FL_TIMES", + "FL_TIMES_BOLD", + "FL_TIMES_ITALIC", + "FL_TIMES_BOLD_ITALIC", + "FL_SYMBOL", + "FL_SCREEN", + "FL_SCREEN_BOLD", + "FL_ZAPF_DINGBATS", +}; + +/** @} */ + +#endif /* FL_NAMES_H */ + +// +// End of "$Id: names.h 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/win32.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/win32.H new file mode 100644 index 0000000..81444f8 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/win32.H @@ -0,0 +1,156 @@ +// +// "$Id: win32.H 7903 2010-11-28 21:06:39Z matt $" +// +// WIN32 header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Do not directly include this file, instead use . It will +// include this file if WIN32 is defined. This is to encourage +// portability of even the system-specific code... + +#ifndef FL_DOXYGEN +#ifndef Fl_X_H +# error "Never use directly; include instead." +#endif // !Fl_X_H + +#include +// In some of the distributions, the gcc header files are missing some stuff: +#ifndef LPMINMAXINFO +#define LPMINMAXINFO MINMAXINFO* +#endif +#ifndef VK_LWIN +#define VK_LWIN 0x5B +#define VK_RWIN 0x5C +#define VK_APPS 0x5D +#endif + +#include + +// some random X equivalents +typedef HWND Window; +typedef POINT XPoint; +struct XRectangle {int x, y, width, height;}; +typedef HRGN Fl_Region; +FL_EXPORT void fl_clip_region(Fl_Region); +extern Fl_Region XRectangleRegion(int x, int y, int w, int h); +inline void XDestroyRegion(Fl_Region r) {DeleteObject(r);} +inline void XClipBox(Fl_Region r,XRectangle* rect) { + RECT win_rect; GetRgnBox(r,&win_rect); + rect->x=win_rect.left; + rect->y=win_rect.top; + rect->width=win_rect.right-win_rect.left; + rect->height=win_rect.bottom-win_rect.top; +} +#define XDestroyWindow(a,b) DestroyWindow(b) +#define XMapWindow(a,b) ShowWindow(b, SW_RESTORE) +#define XUnmapWindow(a,b) ShowWindow(b, SW_HIDE) + +#include "Fl_Window.H" +// this object contains all win32-specific stuff about a window: +// Warning: this object is highly subject to change! +class FL_EXPORT Fl_X { +public: + // member variables - add new variables only at the end of this block + Window xid; + HBITMAP other_xid; // for double-buffered windows + Fl_Window* w; + Fl_Region region; + Fl_X *next; + int wait_for_expose; + HDC private_dc; // used for OpenGL + HCURSOR cursor; + HDC saved_hdc; // saves the handle of the DC currently loaded + // static variables, static functions and member functions + static Fl_X* first; + static Fl_X* i(const Fl_Window* w) {return w->i;} + static int fake_X_wm(const Fl_Window* w,int &X, int &Y, + int &bt,int &bx,int &by); + void setwindow(Fl_Window* wi) {w=wi; wi->i=this;} + void flush() {w->flush();} + void set_minmax(LPMINMAXINFO minmax); + void mapraise(); + static Fl_X* make(Fl_Window*); +}; +extern FL_EXPORT HCURSOR fl_default_cursor; +extern FL_EXPORT UINT fl_wake_msg; +inline Window fl_xid(const Fl_Window*w) {Fl_X *temp = Fl_X::i(w); return temp ? temp->xid : 0;} +FL_EXPORT Fl_Window* fl_find(Window xid); +extern FL_EXPORT char fl_override_redirect; // hack into Fl_Window::make_xid() +extern FL_EXPORT int fl_background_pixel; // hack into Fl_Window::make_xid() + +// most recent fl_color() or fl_rgbcolor() points at one of these: +extern FL_EXPORT struct Fl_XMap { + COLORREF rgb; // this should be the type the RGB() macro returns + HPEN pen; // pen, 0 if none created yet + int brush; // ref to solid brush, 0 if none created yet +} *fl_current_xmap; +inline COLORREF fl_RGB() {return fl_current_xmap->rgb;} +inline HPEN fl_pen() {return fl_current_xmap->pen;} +FL_EXPORT HBRUSH fl_brush(); // allocates a brush if necessary +FL_EXPORT HBRUSH fl_brush_action(int); // now does the real work + +extern FL_EXPORT HINSTANCE fl_display; +extern FL_EXPORT Window fl_window; +extern FL_EXPORT HDC fl_gc; +extern FL_EXPORT HPALETTE fl_palette; // non-zero only on 8-bit displays! +extern FL_EXPORT HDC fl_GetDC(Window); +extern FL_EXPORT MSG fl_msg; +extern FL_EXPORT void fl_release_dc(HWND w, HDC dc); +extern FL_EXPORT void fl_save_dc( HWND w, HDC dc); + +// off-screen pixmaps: create, destroy, draw into, copy to window +typedef HBITMAP Fl_Offscreen; +#define fl_create_offscreen(w, h) \ + CreateCompatibleBitmap( (fl_gc ? fl_gc : fl_GetDC(0) ) , w, h) + +extern FL_EXPORT HDC fl_makeDC(HBITMAP); + +# define fl_begin_offscreen(b) \ + HDC _sgc=fl_gc; Window _sw=fl_window; \ + Fl_Surface_Device *_ss = fl_surface; fl_display_device->set_current(); \ + fl_gc=fl_makeDC(b); int _savedc = SaveDC(fl_gc); fl_window=(HWND)b; fl_push_no_clip() + +# define fl_end_offscreen() \ + fl_pop_clip(); RestoreDC(fl_gc, _savedc); DeleteDC(fl_gc); _ss->set_current(); fl_window=_sw; fl_gc = _sgc + + +FL_EXPORT void fl_copy_offscreen(int x,int y,int w,int h,HBITMAP pixmap,int srcx,int srcy); +FL_EXPORT void fl_copy_offscreen_with_alpha(int x,int y,int w,int h,HBITMAP pixmap,int srcx,int srcy); +#define fl_delete_offscreen(bitmap) DeleteObject(bitmap); + +// Bitmap masks +typedef HBITMAP Fl_Bitmask; + +extern FL_EXPORT Fl_Bitmask fl_create_bitmask(int w, int h, const uchar *data); +extern FL_EXPORT Fl_Bitmask fl_create_alphamask(int w, int h, int d, int ld, const uchar *data); +extern FL_EXPORT void fl_delete_bitmask(Fl_Bitmask bm); + +// Dummy function to register a function for opening files via the window manager... +inline void fl_open_callback(void (*)(const char *)) {} + +extern FL_EXPORT int fl_parse_color(const char* p, uchar& r, uchar& g, uchar& b); +#endif // FL_DOXYGEN +// +// End of "$Id: win32.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FL/x.H b/mod/maxgui.mod/fltkmaxgui.mod/FL/x.H new file mode 100644 index 0000000..3f0d3f0 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FL/x.H @@ -0,0 +1,177 @@ +// +// "$Id: x.H 7903 2010-11-28 21:06:39Z matt $" +// +// X11 header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// These are internal fltk symbols that are necessary or useful for +// calling Xlib. You should include this file if (and ONLY if) you +// need to call Xlib directly. These symbols may not exist on non-X +// systems. + +#if !defined(Fl_X_H) && !defined(FL_DOXYGEN) +# define Fl_X_H + +# include "Enumerations.H" + +# ifdef WIN32 +# include "win32.H" +# elif defined(__APPLE__) +# include "mac.H" +# else +# if defined(_ABIN32) || defined(_ABI64) // fix for broken SGI Irix X .h files +# pragma set woff 3322 +# endif +# include +# include +# if defined(_ABIN32) || defined(_ABI64) +# pragma reset woff 3322 +# endif +# include +# include "Fl_Window.H" +# include "Xutf8.h" +// Mirror X definition of Region to Fl_Region, for portability... +typedef Region Fl_Region; + +FL_EXPORT void fl_open_display(); +FL_EXPORT void fl_open_display(Display*); +FL_EXPORT void fl_close_display(); + +// constant info about the X server connection: +extern FL_EXPORT Display *fl_display; +extern FL_EXPORT Window fl_message_window; +extern FL_EXPORT int fl_screen; +extern FL_EXPORT XVisualInfo *fl_visual; +extern FL_EXPORT Colormap fl_colormap; + +// access to core fonts: +// This class provides a "smart pointer" that returns a pointer to an XFontStruct. +// The global variable fl_xfont can be called wherever a bitmap "core" font is +// needed, e.g. when rendering to a GL context under X11. +// With Xlib / X11 fonts, fl_xfont will return the current selected font. +// With XFT / X11 fonts, fl_xfont will attempt to return the bitmap "core" font most +// similar to (usually the same as) the current XFT font. +class Fl_XFont_On_Demand +{ +public: + Fl_XFont_On_Demand(XFontStruct* p = NULL) : ptr(p) { } + Fl_XFont_On_Demand& operator=(const Fl_XFont_On_Demand& x) + { ptr = x.ptr; return *this; } + Fl_XFont_On_Demand& operator=(XFontStruct* p) + { ptr = p; return *this; } + XFontStruct* value(); + operator XFontStruct*() { return value(); } + XFontStruct& operator*() { return *value(); } + XFontStruct* operator->() { return value(); } + bool operator==(const Fl_XFont_On_Demand& x) { return ptr == x.ptr; } + bool operator!=(const Fl_XFont_On_Demand& x) { return ptr != x.ptr; } +private: + XFontStruct *ptr; +}; +extern FL_EXPORT Fl_XFont_On_Demand fl_xfont; + +// drawing functions: +extern FL_EXPORT GC fl_gc; +extern FL_EXPORT Window fl_window; +extern FL_EXPORT void *fl_xftfont; +FL_EXPORT ulong fl_xpixel(Fl_Color i); +FL_EXPORT ulong fl_xpixel(uchar r, uchar g, uchar b); +FL_EXPORT void fl_clip_region(Fl_Region); +FL_EXPORT Fl_Region fl_clip_region(); +FL_EXPORT Fl_Region XRectangleRegion(int x, int y, int w, int h); // in fl_rect.cxx + +// feed events into fltk: +FL_EXPORT int fl_handle(const XEvent&); + +// you can use these in Fl::add_handler() to look at events: +extern FL_EXPORT const XEvent* fl_xevent; +extern FL_EXPORT ulong fl_event_time; + +// off-screen pixmaps: create, destroy, draw into, copy to window: +typedef ulong Fl_Offscreen; +# define fl_create_offscreen(w,h) \ + XCreatePixmap(fl_display, \ + (fl_surface->type() == Fl_Display_Device::device_type ? \ + fl_window : fl_xid(Fl::first_window()) ) , \ + w, h, fl_visual->depth) +// begin/end are macros that save the old state in local variables: +# define fl_begin_offscreen(pixmap) \ + Window _sw=fl_window; fl_window=pixmap; \ + Fl_Surface_Device *_ss = fl_surface; fl_display_device->set_current(); \ + fl_push_no_clip() +# define fl_end_offscreen() \ + fl_pop_clip(); fl_window = _sw; _ss->set_current() + +extern void fl_copy_offscreen(int x, int y, int w, int h, Fl_Offscreen pixmap, int srcx, int srcy); +# define fl_delete_offscreen(pixmap) XFreePixmap(fl_display, pixmap) + +// Bitmap masks +typedef ulong Fl_Bitmask; + +extern FL_EXPORT Fl_Bitmask fl_create_bitmask(int w, int h, const uchar *data); +extern FL_EXPORT Fl_Bitmask fl_create_alphamask(int w, int h, int d, int ld, const uchar *data); +extern FL_EXPORT void fl_delete_bitmask(Fl_Bitmask bm); + +// this object contains all X-specific stuff about a window: +// Warning: this object is highly subject to change! It's definition +// is only here so that fl_xid can be declared inline: +class FL_EXPORT Fl_X { +public: + Window xid; + Window other_xid; + Fl_Window *w; + Fl_Region region; + Fl_X *next; + char wait_for_expose; + char backbuffer_bad; // used for XDBE + static Fl_X* first; + static Fl_X* i(const Fl_Window* wi) {return wi->i;} + void setwindow(Fl_Window* wi) {w=wi; wi->i=this;} + void sendxjunk(); + static void make_xid(Fl_Window*,XVisualInfo* =fl_visual, Colormap=fl_colormap); + static Fl_X* set_xid(Fl_Window*, Window); + // kludges to get around protection: + void flush() {w->flush();} + static void x(Fl_Window* wi, int X) {wi->x(X);} + static void y(Fl_Window* wi, int Y) {wi->y(Y);} +}; + +// convert xid <-> Fl_Window: +inline Window fl_xid(const Fl_Window*w) {return Fl_X::i(w)->xid;} +FL_EXPORT Fl_Window* fl_find(Window xid); + +extern FL_EXPORT char fl_override_redirect; // hack into Fl_X::make_xid() +extern FL_EXPORT int fl_background_pixel; // hack into Fl_X::make_xid() + +// Dummy function to register a function for opening files via the window manager... +inline void fl_open_callback(void (*)(const char *)) {} + +extern FL_EXPORT int fl_parse_color(const char* p, uchar& r, uchar& g, uchar& b); + +# endif +#endif + +// +// End of "$Id: x.H 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU/CHANGES b/mod/maxgui.mod/fltkmaxgui.mod/FLU/CHANGES new file mode 100644 index 0000000..db9787a --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU/CHANGES @@ -0,0 +1,258 @@ +-= FLU 2.14 =- + +* Flu_File_Chooser: + - would only return a single file in multi mode if you pushed instead of + clicking "Ok" + - fixed bug where the selected file would sometimes have an extra path prepended + - added flu_multi_file_chooser() to easily choose multiple files inline +* Flu_Tree_Browser: + - changed behavior so branch_icons(0,0) turns off branch icons for newly added + nodes, and added set_default_branch_icons() to turn the default ones back on + - added swap_label_and_widget() to specify whether nodes with embedded widgets draw + the label to the left of the widget (default) or to the right of the widget + - added auto_color(), auto_label(), and auto_label_color() to help draw embedded + widgets better by allowing them to track properties of their enclosing node + - added icon_at_end() to specify whether the icon for a leaf is drawn to the left + of the label and widget, or to the right of the label and widget + - tree was not properly redrawn in some cases after removing a node + - fixed error in swap() where it didn't return a value + - tweaked the event handling code to work with embedded widgets better + - added get_hilighted() to return the currently hilighted node + - added selection_follows_hilight() to set whether the hilighted node + is also always selected + - fixed the drawing/handling/focus code to correctly handle drawing + embedded widgets that are only "damaged" + - removed Flu_DND support by default. it is too buggy and doesn't work on all OS +* added wrap_range() to Flu_Spinner to allow the value to "wrap" to the range during interaction +* Flu_Label now wraps label text by default +* fixed bug in Flu_Combo_Box where, in some situations, the popup would appear in the wrong location +* renamed a helper file to be consistent with the rest of FLU (shouldn't affect your code unless you + included it directly) +* added an Flu prefix to the names of a few internal variables/classes to avoid potential namespace conflicts +* initialized a few uninitialized variables in Flu_File_Chooser to prevent potential bugs +* added a new class, Flu_GL_Canvas, that is better suited to derive GL widgets from +* fixed bug in Flu_Toggle_Group that incorrectly activated widgets that were supposed to be deactivated +* fixed Flu_Dual_Slider so you can call low_value(float) and high_value(float) while dragging + +-= FLU 2.13 =- + +* Flu_GL_Window passed the wrong user data for the mouse wheel callback +* Flu_Tree_Browser: + - added insert(), insert_branch() and insert_leaf() to add nodes to specific positions + within a branch (valid only when the insertion_mode() is not a sorted mode) + - added a swap() method to exchange the positions of any 2 nodes (within the same tree) +* fixed a version mismatch between the .zip and .tar distributions + +-= FLU 2.12 =- + +* fixed the various Flu_*_Group widgets to account for damaged children during a draw() +* reverted the callback() for Flu_Tree_Browser to the Fl_Widget implementation for compatability with + other callback mechanisms such as fl_connect (thanks Ken!). this also eliminates the tree browser's + FLU_WIDGET_CALLBACK notifcation event for widgets in the tree. to regain the original behavior, + call Flu_Tree_Browser::use_FLU_WIDGET_CALLBACK(true); before creating a tree. +* Flu_Spinner: + - the input area is now properly activated/deactivated + - pushing 'Tab' correctly advances to the next widget + - added an editable() method to control whether the input area can be edited +* Flu_Dual_Slider: + - added an overlap() method allowing the low and high values to be the same + - fixed a bug in the keyboard handler (when using the arrow keys to change values) +* Flu_File_Chooser: + - fixed bug allowing you to choose a directory when selecting multiple files + - selected files are now not unselected when switching between list, wide-list, and detail modes + - added a few more static strings for internationalization support + - now uses the windows registry to get the correct user paths for "Desktop" and "My Documents". + this should eliminate some problems for cygwin/mingw compiles + - implemented the callback() for Flu_File_Chooser (which is called when the Ok or Cancel buttons are + pushed). this allows you to create a chooser widget, show() it, and forget it. the callback is + called just like any ordinary widget + - added a STDFILE type() flag which allows choosing both directories and files at the same time + (thanks Michel!) + - added a flu_file_and_dir_chooser() function to choose both directories and files (using the new + STDFILE flag) + +-= FLU 2.11 =- + +* added a reset() routine to Flu_Progress_Meter to make it easier to reuse + (thanks george!) +* added a convenience routine, fl_exit(), to Flu_Helpers which hides all open windows + (eventually) causing fltk to exit (you are still required to delete the windows though) +* added a new widget: Flu_Dual_Slider - like Fl_Slider but with 2 handles controlling both + a "low" value and a "high" value +* fixed Ctrl/Shift/Alt + drag increments 10x for Flu_Spinner +* fixed the box() drawing for Flu_Tree_Browser +* added a setMouseWheelFunc() to Flu_GL_Window to handle FL_MOUSEWHEEL events +* fixed Flu_Tree_Browser bug where animated open/close of branches would break if you opened a + branch with no children +* added open_without_children() to Flu_Tree_Browser to allow branches to not be opened + if they have no children +* added num_selected() and get_selected() methods to class Flu_Tree_Browser::Node +* fixed Flu_Progress so it handles value() changes better by only updating the screen when a + visible change has occurred (via Fl::check()) +* fixed a couple event-handling bugs for Flu_GL_Window +* fixed Flu_File_Chooser so it does not use SHGetSpecialFolderPath in windows anymore, but + instead uses the more compatable SHGetFolderPath +* introduced a plethora of static strings allowing programmers to customize the names of most + widgets/tooltips in Flu_File_Chooser for easier internationalization +* changed the text color of selected files in Flu_File_Chooser from black to white so they + are easier to read +* fixed the custom preview widget code (PreviewWidgetBase) for Flu_File_Chooser to work + correctly +* fixed the "quick jump" buttons in Flu_File_Chooser so they don't resize with the window +* added an extra flu_dir_chooser() method to Flu_File_Chooser that allows you to also see files + in a deactivated state +* added flu_save_chooser() method to Flu_File_Chooser that keeps the current filename in the + input field during directory traversals +* fixed flu_file_chooser() and flu_dir_chooser() so they reset the single instance of the + chooser to the correct type + +-= FLU 2.10 =- + +* added a format() method to Flu_Int_Input and Flu_Float_Input to set how the value() is displayed +* hacked Flu_Tree_Browser to allow natural support for FL_RADIO_BUTTONs. it's not the best solution, but it works +* added support for using '~' to go to your home area in Flu_File_Chooser +* added a set of location "quick jump" buttons in Flu_File_Chooser to navigate within the current directory path +* patched Flu_File_Browser to guarantee value() returns paths with a LOWERCASE drive letter on + windows (for compatability with fl_filename_relative()). this patch also fixes a fatal crash on windows. +* tweaked Flu_Combo_Box, Flu_Combo_List, Flu_Combo_Tree, and Flu_Tree_Browser so that combo boxes + hilight the item under the mouse when the mouse moves, making selection easier + +-= FLU 2.9.2 =- + +* patched Flu_Tree_Browser to make it flicker less for single-buffered apps that generate + too many FL_NO_EVENTs +* patched Flu_File_Browser to do case-insensitive matching in windows, and case-sensitive + matching on everything else. also updated to guarantee value() returns paths with an uppercase drive letter on windows. +* fixed Flu_File_Browser so it correctly primes the "Filename" field when calling flu_file_chooser() +* patched Flu_Combo_List to prevent crashes when an empty region in the popup was selected +* tweaked Flu_Combo_Box to look better if it has the focus or if you change the box() type + +-= FLU 2.9.1 =- + +* patched Flu_Tree_Browser to prevent erroneous memory access introduced in 2.9 (caused crashes on Windows) + +-= FLU 2.9 =- +* Flu_File_Chooser: + - changed value(int) to base 1 instead of base 0 to match Fl_File_Chooser behavior + - fixed bug that prevented the user from using the left/right cursor keys to + navigate within the text in the "Filename:" field + - added Up, Down, Left, Right, Home, End, Enter and Space support to make keyboard + navigation easier + - the Delete key didn't work for File Details mode (fixed) + - made a few minor aesthetic improvements when the chooser is resized + - for ease-of-use, can only change the name of a file by right-clicking instead of by + clicking twice + - when changing the name of a file, just the name is highlighted initially (not the extension) +* updated Flu_Wrap_Group to accomodate new functionality required for Flu_File_Chooser +* Flu_Progress_Meter is now derived from Fl_Double_Window, making the class a bit cleaner and more flexible +* removed unnecessary #include from Flu_Collapsable_Group.cpp (broke some msys compiles) +* Flu_Tree_Browser: + - changed Node implementation so that a NULL branch icon does not default to the gold folder, + but instead draws nothing + - added add_branch() and add_leaf() convenience methods to help disambiguate + adding nodes for the programmer + - added a new feature called auto_branches() that dynamically changes nodes from leaves to + branches depending on whether the node has any children. this makes the tree more compatible + with scene-graph-like hierarchies instead of file-structure-like hierarchies. the new example + Flu_Tree_Browser_Try2 tests this feature + - fixed a couple more event handling bugs + +-= FLU 2.8.1 =- + +* added support for cygwin environment (static libs only) +* added support for mingw/msys environment (static libs only) +* added the ability to change the label of an entry in Flu_Tree_Browser, as well as + sort the entire tree or a node's children manually +* fixed some Codewarrior compiler issues in Flu_File_Chooser and Flu_Tree_Browser, + as well as many of the example files (thanks Doyle!) +* added Codewarrior project files - static libs only (thanks Doyle!) +* tweaked Flu_File_Chooser to fix latency issues with floppy, removable and network + drives +* typing Ctrl+a in Flu_File_Chooser when in MUTLI mode now selects all files +* fixed annoying "feature" in Flu_File_Chooser where if a filename was in the filename + input field, and that filename matched an existing file, no other files matching + the current pattern were displayed +* fixed memory leak in Flu_Progress_Meter in which the destructor didn't delete the window +* fixed bug in Flu_Combo_Box where it took 2 presses of to move through the widget (now it takes only 1) +* tried to fix Flu_Combo_Box so it pops up correctly on multi-display desktops (haven't tested though) + +-= FLU 2.8 =- + +* updated configure/makefile to fix the following issues: (thanks Michael!) + - on some systems, previous versions of the FLU shared library must be removed + before a new symlink can be created. fixed by removing libflu.* and libflu_gl.* + instead of individual files + - support added to configure for Sun and several BSD variants, including systems + with a non-standard shell and systems for which the header/lib search path was + wrong or incomplete + - --disable-gl did not work for configure. fixed. + - updated examples/Makefile to account for --enable-gl or --disable-gl +* added keyboard navigation to Flu_Combo_Box: opens, + cursor keys navigate, or selects, cancels +* fixed Flu_Combo_Box bug that did not save/restore the current group correctly + before popping up the box, sometimes leading to a segfault (thanks George!) +* fixed bugs in Flu_File_Chooser: + - certain compiles on windows (e.g. mingw) when queying floppy drives took a bit + too long. changed things around so the drives are only queried when the user + clicks "Refresh Directory" or when "My Computer" is visited (thanks Ian!) + - fixed a couple really insignificant problems involving the current working + directory and flu_file_chooser() + - typing in a filename and pushing did not return that filename unless + it already existed. fixed. pressing "Ok" always worked. + - changed a char* to const char* for mingw compiler + - made entire protected section public because several compilers + (VC6 and a few gcc-2.x) did not like friend classes accessing protected members +* removed a #pragma from Flu_Enumerations.h because it was there only to eliminate + several warnings from a VC6 compile, and was largely unnecessary + +-= FLU 2.7.1 =- + +* added a clear_history() function to Flu_File_Chooser +* fixed bugs in Flu_File_Chooser: + - erroneously returned the empty string on cancel, instead of NULL + - flu_file_chooser() did not use current working directory when + first called with NULL as the filename. + - flu_file_chooser() did not throw away the last file name chosen + when called again with a different pattern. + - each call to flu_file_chooser() now clears the history for more + consistent behavior from call to call + +-= FLU 2.7 =- + +* new Flu_File_Chooser widget + +* Flu_Button enhanced with box enter/exit effects + +* added pop_height() in Flu_Combo_Box to set the size of the box that pops up + +* a couple bug fixes in Flu_Tree_Browser, Flu_Combo_Box, Flu_Wrap_Group + +* added cancel handler to the Flu_Progress demo + +* added a separate input_callback() to Flu_Combo_Box + +* when selecting an existing item in the combo box/list demo, it erroneously added + the item again to the list. fixed using new input_callback() + +* new option for Flu_Link_Button that only draws underlining when mouse is over the button + +* Flu_Spinner: shift/ctrl/alt + click increments by 10*step() + step() >= 1 --> uses Fl_Int_Input, else Fl_Float_Input + align(FL_ALIGN_INSIDE) now puts the label inside the spinner, but then you + can't edit the data in the input box + +* New FluSimpleString class (similar to the STL string class) used by several widgets + to make string handling easier + +* added make install directive to configure and Makefiles + +-= KNOWN BUGS =- + +* Flu_File_Chooser: details mode doesn't work right when there are more than 1600 files or so. + some kind of weird conflict with Fl_Scroll and Fl_Pack (the underlying widgets for details + mode). still trying to figure it out... +* Flu_File_Chooser: on OSX, the first time you open the "Location" combo box, if the + file chooser window has not been moved or resized, the combo box sometimes shows up + in the wrong place, although it is still functional. go figure +* Flu_File_Chooser: it has been reported that on some multi-display desktops the various + combo boxes do not pop up in the right place. diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU/FluSimpleString.h b/mod/maxgui.mod/fltkmaxgui.mod/FLU/FluSimpleString.h new file mode 100644 index 0000000..c3c7c8d --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU/FluSimpleString.h @@ -0,0 +1,147 @@ +// $Id: FluSimpleString.h,v 1.12 2003/11/27 01:09:04 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#ifndef _FLU_SIMPLE_STRING_H +#define _FLU_SIMPLE_STRING_H + +#include +#include +#include +#include + +#include "FLU/Flu_Enumerations.h" + +//! A simple string object that works a lot like the STL string object +class FLU_EXPORT FluSimpleString +{ + + public: + + //! Default constructor: sets to empty string ("") + FluSimpleString(); + + //! Allocates the string to be of length \b len. Does not set the buffer to any initial value + FluSimpleString( unsigned int len ); + + //! String copy constructor + FluSimpleString( const char *s ); + + //! Copy constructor + FluSimpleString( const FluSimpleString& s ); + + //! Default destructor + ~FluSimpleString(); + + //! \return a c-style nul terminated pointer to the string + inline const char* c_str() const { return str; } + + //! \return how long the string is + inline int size() const { return strlen(str); } + + //! Array operator + inline char& operator [](int i) { return str[i]; } + + //! Array operator + inline char operator [](int i) const { return str[i]; } + + //! \return the indicated substring of this string + FluSimpleString substr( int pos, int len ) const; + + //! Convert this string to uppercase + void upcase(); + + //! Convert this string to lowercase + void downcase(); + + //! \return the first index of character \b c in this string, or -1 if \c is not in this string + int find( char c ) const; + + //! \return the last index of character \b c in this string, or -1 if \c is not in this string + int rfind( char c ) const; + + //! \return 0 if this string is equal to \b s, -1 if this string is lexigraphically less than \b s, 1 if this string is lexigraphically greater than \b s (uses c-std function \b strcmp ) + int compare( const FluSimpleString &s ) const; + + //! Same as compare(), except ignores the case of the string + int casecompare( const FluSimpleString &s ) const; + + //! \return 0 if this string is equal to \b s, -1 if this string is lexigraphically less than \b s, 1 if this string is lexigraphically greater than \b s (uses c-std function \b strcmp ) + inline friend int compare( const FluSimpleString &s1, const FluSimpleString &s2 ) + { return s1.compare( s2 ); } + + //! Same as compare(), except ignores the case of the string + inline friend int casecompare( const FluSimpleString &s1, const FluSimpleString &s2 ) + { return s1.casecompare( s2 ); } + + //! Add character \b c to the end of the string + inline void push_back( char c ) + { char s[2] = { c, '\0' }; *this += s; } + + //! Alias for the \c = operator + inline void copy( const FluSimpleString& s ) + { *this = s; } + + //! Alias for the \c = operator + inline void copy( const char *s ) + { *this = s; } + + //! Copy the substring of \b s to this string + inline void copy( const FluSimpleString& s, unsigned int start, unsigned int len ) + { copy( s.c_str(), start, len ); } + + //! Copy the substring of \b s to this string + void copy( const char *s, unsigned int start, unsigned int len ); + + //! Copy operator + FluSimpleString& operator =( const char *s ); + + //! Copy operator + inline FluSimpleString& operator =( FluSimpleString s ) { return( *this = s.str ); } + + //! Less-than operator + inline bool operator <( const FluSimpleString& s ) const { return( strcmp( str, s.str ) < 0 ); } + + //! Greater-than operator + inline bool operator >( const FluSimpleString& s ) const { return( strcmp( str, s.str ) > 0 ); } + + //! Equality operator + inline bool operator ==( const FluSimpleString& s ) const { return( strcmp( str, s.str ) == 0 ); } + + //! Inequality operator + inline bool operator !=( const FluSimpleString& s ) const { return( strcmp( str, s.str ) != 0 ); } + + //! Concatenate operator + inline friend FluSimpleString operator +( const char *s1, FluSimpleString s2 ) { FluSimpleString s = s1; s += s2; return s; } + + //! Concatenate operator + inline friend FluSimpleString operator +( FluSimpleString s1, const char *s2 ) { FluSimpleString s = s1; s += s2; return s; } + + //! Concatenate operator + inline friend FluSimpleString operator +( FluSimpleString s1, FluSimpleString s2 ) { FluSimpleString s = s1; s += s2; return s; } + + //! Concatenate assignment operator + inline FluSimpleString& operator +=( const FluSimpleString& s ) { *this += s.str; return *this; } + + //! Concatenate assignment operator + FluSimpleString& operator +=( const char *s ); + + private: + + char *str; + +}; + +#endif + diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU/FluVectorClass.h b/mod/maxgui.mod/fltkmaxgui.mod/FLU/FluVectorClass.h new file mode 100644 index 0000000..554e959 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU/FluVectorClass.h @@ -0,0 +1,104 @@ +// $Id: FluVectorClass.h,v 1.2 2004/10/13 20:05:52 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#ifndef _FLU_VECTOR_CLASS_H +#define _FLU_VECTOR_CLASS_H + +// hackish macro way of making a template class for compilers that don't support templates well +#define FluMakeVectorClass( T, C ) \ +class C \ +{ \ +public: \ + \ + C() { _array = NULL; _size = 0; } \ + \ + ~C() { clear(); } \ + \ + inline void add( const T& item ) { insert( size(), item ); } \ + \ + inline T& operator [](int i) { return _array[i]; } \ + \ + inline T operator [](int i) const { return _array[i]; } \ + \ + inline unsigned int size() const { return _size; } \ + \ + C& operator =( const C &v ) \ + { \ + clear(); \ + if( v.size() ) \ + { \ + _array = new T[v.size()]; \ + for( unsigned int i = 0; i < v.size(); i++ ) \ + _array[i] = v._array[i]; \ + } \ + return *this; \ + } \ + \ + void insert( unsigned int pos, const T &item ) \ + { \ + if( pos > _size ) \ + pos = _size; \ + if( _size == 0 ) \ + { \ + _array = new T[1]; \ + } \ + else \ + { \ + if( !( _size & (_size-1) ) ) \ + { \ + T* temp = new T[_size*2]; \ + for( unsigned int i = 0; i < _size; i++ ) \ + temp[i] = _array[i]; \ + delete[] _array; \ + _array = temp; \ + } \ + for( unsigned int s = _size; s > pos; s-- ) \ + _array[s] = _array[s-1]; \ + } \ + _size++; \ + _array[pos] = item; \ + } \ + \ + void erase( unsigned int pos ) \ + { \ + if( pos >= _size ) \ + return; \ + _size--; \ + if( _size == 0 ) \ + { \ + delete[] _array; \ + _array = NULL; \ + } \ + else \ + { \ + for( ; pos < _size; pos++ ) \ + _array[pos] = _array[pos+1]; \ + } \ + } \ + \ + void clear() \ + { \ + if( _array ) \ + delete[] _array; \ + _array = NULL; \ + _size = 0; \ + } \ + \ +protected: \ + T *_array; \ + unsigned int _size; \ +} + +#endif diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Button.h b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Button.h new file mode 100644 index 0000000..3c9bcfa --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Button.h @@ -0,0 +1,91 @@ +// $Id: Flu_Button.h,v 1.11 2003/12/21 15:58:31 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#ifndef _FLU_BUTTON_H +#define _FLU_BUTTON_H + +#include +#include + +#include +#include +#include + +#include "FLU/flu_export.h" + +//! This class extends Fl_Button to make a more attractive alternative that hilights as the mouse enters/leaves and automatically grayscales any image for deactivation +class FLU_EXPORT Flu_Button : public Fl_Button +{ + public: + + //! Normal FLTK widget constructor + Flu_Button( int X,int Y,int W,int H,const char *l = 0 ); + + //! Default destructor + virtual ~Flu_Button(); + + //! Override of Fl_Widget::color() + inline void color( unsigned c ) + { col = (Fl_Color)c; Fl_Button::color(col); } + + //! Override of Fl_Widget::color() + inline Fl_Color color() const + { return col; } + + //! Override of Fl_Widget::selection_color() + inline void selection_color( unsigned c ) + { sCol = (Fl_Color)c; Fl_Button::selection_color(sCol); } + + //! Override of Fl_Widget::selection_color() + inline Fl_Color selection_color() const + { return sCol; } + + //! Set the box to use when the mouse is over the button. If this is \c FL_NO_BOX, then the regular box() is used + inline void enter_box( Fl_Boxtype b ) + { eBox = b; } + + //! Get the box to use when the mouse enters + inline Fl_Boxtype enter_box() const + { return eBox; } + + //! Override of Fl_Widget::image() + void image( Fl_Image *i ); + + //! Override of Fl_Widget::image() + inline void image( Fl_Image &i ) + { image( &i ); } + + //! Override of Fl_Button::handle() + int handle( int event ); + + // Override of Fl_Button::draw() + void draw(); + + protected: + + bool retBtn, linkBtn, overLink; + + private: + + void checkLink(); + int labelSize[4]; + bool hover; + Fl_Color col, sCol; + Fl_Image *inactiveImg; + Fl_Boxtype eBox; + +}; + +#endif diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Chat_Buffer.h b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Chat_Buffer.h new file mode 100644 index 0000000..ae829cd --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Chat_Buffer.h @@ -0,0 +1,111 @@ +// $Id: Flu_Chat_Buffer.h,v 1.5 2003/08/20 16:29:40 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#ifndef _FLU_CHAT_BUFFER_H +#define _FLU_CHAT_BUFFER_H + +/* fltk includes */ +#include +#include +#include +#include "FLU/Flu_Enumerations.h" + +//! A class for drawing text messages in the style of a "chat buffer" +/*! This class is pretty much only useful for chatting. */ +class FLU_EXPORT Flu_Chat_Buffer : public Fl_Widget +{ + + class FLU_EXPORT MessageInfo + { + public: + char type; + char *handle; + char *message; + int handleW, messageW, height; + }; + + public: + + //! Normal FLTK widget constructor + Flu_Chat_Buffer( int x, int y, int w, int h, const char *label = 0 ); + + //! Default destructor + virtual ~Flu_Chat_Buffer(); + + //! Add a system message to the chat buffer using the system font and color + void addSystemMessage( const char *msg ); + + //! Add a message from a remote person to the chat buffer using the remote font and color + void addRemoteMessage( const char *handle, const char *msg ); + + //! Add a message from a local person to the chat buffer using the local font and color + void addLocalMessage( const char *handle, const char *msg ); + + //! Clear the contents of the buffer and set the maximum number of lines it can contain to \b maximumLines + void clear( int maximumLines = 500 ); + + //! Set the font and color to use when printing system messages + /*! Default is FL_HELVETICA_ITALIC, FL_BLACK */ + inline void setSystemStyle( Fl_Font f, Fl_Color c ) + { systemFont = f; systemColor = c; } + + //! Set the font and color to use when printing the handle from a remote message + /*! Default is FL_HELVETICA_BOLD, FL_RED */ + inline void setRemoteHandleStyle( Fl_Font f, Fl_Color c ) + { remoteHandleFont = f; remoteHandleColor = c; } + + //! Set the font and color to use when printing the handle from a local message + /*! Default is FL_HELVETICA_BOLD, FL_BLUE */ + inline void setLocalHandleStyle( Fl_Font f, Fl_Color c ) + { localHandleFont = f; localHandleColor = c; } + + //! Set the font and color to use when printing a remote message + /*! Default is FL_HELVETICA, FL_RED */ + inline void setRemoteMessageStyle( Fl_Font f, Fl_Color c ) + { remoteMessageFont = f; remoteMessageColor = c; } + + //! Set the font and color to use when printing a local message + //! Default is FL_HELVETICA, FL_BLUE */ + inline void setLocalMessageStyle( Fl_Font f, Fl_Color c ) + { localMessageFont = f; localMessageColor = c; } + + //! FLTK resize of this widget + virtual void resize( int x, int y, int w, int h ); + + protected: + + inline static void _scrollbarCB( Fl_Widget* w, void* arg ) + { ((Flu_Chat_Buffer*)arg)->scrollbarCB(); } + void scrollbarCB(); + + Fl_Font systemFont, remoteHandleFont, localHandleFont, + remoteMessageFont, localMessageFont; + Fl_Color systemColor, remoteHandleColor, localHandleColor, + remoteMessageColor, localMessageColor; + + MessageInfo *buffer; + int maxLines, totalLines, currentLine; + bool recomputeFootprint; + + virtual void draw(); + + Fl_Scrollbar *scrollbar; + + void _addMessage( char type, char *handle, char *msg ); + void _computeMessageFootprint(); + +}; + +#endif diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Choice_Group.h b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Choice_Group.h new file mode 100644 index 0000000..355fb0e --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Choice_Group.h @@ -0,0 +1,73 @@ +// $Id: Flu_Choice_Group.h,v 1.9 2003/08/20 16:29:40 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#ifndef _FLU_CHOICE_GROUP_H +#define _FLU_CHOICE_GROUP_H + +#include +#include + +/* fltk includes */ +#include +#include +#include +#include + +#include "FLU/Flu_Enumerations.h" + +//! This class provides an alternative group to Fl_Tabs. It provides an Fl_Choice menu that is used to determine which child Fl_Group is visible +class FLU_EXPORT Flu_Choice_Group : public Fl_Group +{ + + public: + + //! Default FLTK constructor + Flu_Choice_Group( int x, int y, int w, int h, const char *l = 0 ); + + //! Get the currently visible child Fl_Group widget + /*! \return \c NULL if there are no child Fl_Groups, else the currently selected group */ + inline Fl_Widget* wvalue() + { return selected; } + + //! Get the index of the currently visible child Fl_Group widget + /*! \return \c -1 if there are no child Fl_Groups, else the index of the group */ + int value(); + + //! Set the currently visible child Fl_Group widget + /*! \return the index of the child Fl_Group widget that is currently selected, or \c -1 if \b newvalue cannot be found. */ + int value( Fl_Widget *newvalue ); + + //! Set the currently visible child Fl_Group widget + void value( int v ); + + //! Override of Fl_Group::draw() + void draw(); + + //! \return the number of entries able to be selected with value(int) + inline int size() + { return children()-1; } + + protected: + + static void _choiceCB( Fl_Widget *w, void *arg ) + { ((Flu_Choice_Group*)arg)->choiceCB(); } + void choiceCB(); + + Fl_Choice *choice; + Fl_Widget *selected; + +}; + +#endif diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Collapsable_Group.h b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Collapsable_Group.h new file mode 100644 index 0000000..b567a3a --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Collapsable_Group.h @@ -0,0 +1,196 @@ +// $Id: Flu_Collapsable_Group.h,v 1.8 2003/09/24 21:13:47 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#ifndef _FLU_COLLAPSABLE_GROUP_H +#define _FLU_COLLAPSABLE_GROUP_H + +#include +#include + +/* fltk includes */ +#include +#include +#include +#include + +#include "FLU/FluSimpleString.h" +#include "FLU/Flu_Button.h" + +//! This widget implements a collapsable group with a configurable framerate +/*! This class is a group with a button and an \b Fl_Group inside (both publicly exposed). The \b Fl_Group + contains the actual child widgets of this group. + + Most of the \b Fl_Group member functions are reimplemented here in a pass-through fashion to the + internal group. This means that casual use of a descendent instance will be almost exactly the same + as for a regular \b Fl_Group, with any additional access provided directly through member \b group. + + The goal of this class is to provide a dynamically collapsable group similar to those available in + other GUI toolkits. + + The callback is invoked whenever the button is pressed to open/close the group. +*/ +class FLU_EXPORT Flu_Collapsable_Group : public Fl_Group +{ + + public: + + //! Normal FLTK constructor + Flu_Collapsable_Group( int x, int y, int w, int h, const char *l = 0 ); + + //! Get the amount of time to take when animating a collapse + inline float collapse_time() const + { return _collapseTime; } + + //! Set the amount of time to take when animating a collapse + inline void collapse_time( float t ) + { _collapseTime = t; } + + //! Get the frame rate to aim for during a collapse animation + inline float frame_rate() const + { return _fps; } + + //! Set the frame rate to aim for during a collapse animation + inline void frame_rate( float f ) + { _fps = f; } + + //! Set the position of the controller widget along the top edge of the group. This only has an effect if fit() is not set. Default value is \c FL_ALIGN_LEFT + /*! Accepted values are \c FL_ALIGN_LEFT, \c FL_ALIGN_CENTER, and \c FL_ALIGN_RIGHT */ + inline void align( unsigned char a ) + { _align = a; } + + //! Get the position of the controller widget along the top edge of the group + inline unsigned char align() const + { return _align; } + + //! Pass \c true to force the button to be the same width as the group, \c false to leave it its default size. Default value is \c false + inline void fit( bool b ) + { _fit = b; } + + //! Get whether the button is being forced to fit the width of the group + inline bool fit() const + { return _fit; } + + //! Get whether the group is closed or open (i.e. collapsed or not) + inline bool open() const + { return _open; } + + //! Set whether the group is closed or open (i.e. collapsed or not). Default is \c true + void open( bool o ); + + //! Get whether the group is closed or open (i.e. collapsed or not) + inline bool closed() const + { return !_open; } + + //! Get whether the group is in the process of opening or closing + inline bool changing() const + { return _changing; } + + //! Override of Fl_Group::resize() + void resize( int x, int y, int w, int h ); + + //! Override of Fl_Group::label() + inline void label( const char *l ) + { if( l ) _label = l; else _label = ""; } + + //! Override of Fl_Group::label() + inline const char *label() + { return _label.c_str(); } + + ////////////////////// + + /*! \name Pass-through functions for the internal Fl_Group + * These are strictly for convenience. Only the most commonly called functions have been re-implemented. + * You can also explicitly access the group object for more control. + */ + //@{ + + inline void clear() + { group.clear(); } + + inline Fl_Widget *child(int n) const + { return group.child(n); } + + inline int children() const + { return group.children(); } + + inline void begin() + { group.begin(); } + + inline void end() + { group.end(); Fl_Group::end(); } + + inline void resizable(Fl_Widget *box) + { group.resizable(box); } + + inline void resizable(Fl_Widget &box) + { group.resizable(box); } + + inline Fl_Widget *resizable() const + { return group.resizable(); } + + inline void add( Fl_Widget &w ) + { group.add( w ); } + + inline void add( Fl_Widget *w ) + { group.add( w ); } + + inline void insert( Fl_Widget &w, int n ) + { group.insert( w, n ); } + + inline void insert( Fl_Widget &w, Fl_Widget* beforethis ) + { group.insert( w, beforethis ); } + + inline void remove( Fl_Widget &w ) + { group.remove( w ); } + + inline void add_resizable( Fl_Widget &box ) + { group.add_resizable( box ); } + + //@} + + Flu_Button button; + Fl_Group group; + + protected: + + ////////////////////////// + + void draw(); + + inline static void _collapseCB( Fl_Widget* w, void* arg ) + { ((Flu_Collapsable_Group*)arg)->open( !((Flu_Collapsable_Group*)arg)->open() ); } + + inline static void _updateCB( void *arg ) + { ((Flu_Collapsable_Group*)arg)->updateCB(); } + void updateCB(); + + void (*_callback)(Fl_Widget*,void*); + void *_callbackData; + + void (*_collapseCallback)(void*); + void *_collapseCallbackData; + + int _originalHeight, _newHeight; + float _deltaHeight, _currentHeight, _collapseTime, _timeout, _fps; + + Fl_Widget *_oldResizable; + + bool _open, _changing, _fit; + unsigned char _align; + FluSimpleString _label; + +}; + +#endif diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Combo_Box.h b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Combo_Box.h new file mode 100644 index 0000000..2a6bf0d --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Combo_Box.h @@ -0,0 +1,118 @@ +// $Id: Flu_Combo_Box.h,v 1.12 2004/03/24 02:49:00 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#ifndef _FLU_COMBO_BOX_H +#define _FLU_COMBO_BOX_H + +#include +#include +#include + +#include "FLU/Flu_Enumerations.h" + +//! This is a generic base class for implementing widgets with combo-box-like behavior (i.e. a pulldown menu where the "input" area is editable +class FLU_EXPORT Flu_Combo_Box : public Fl_Group +{ + +public: + + //! Normal FLTK widget constructor + Flu_Combo_Box( int x, int y, int w, int h, const char *l = 0 ); + + //! Default destructor + ~Flu_Combo_Box(); + + //! Get whether the input field can be edited. Default is \c true + inline bool editable() const + { return (int)(!input.readonly()); } + + //! Set whether the input field can be edited. + inline void editable( bool b ) + { input.readonly( (int)(!b) ); } + + //! Get the string in the input field + inline const char* value() const + { return input.value(); } + + //! Set the string in the input field and the value of the popup box. + void value( const char *v ); + + //! Set the height of the popup box + inline void pop_height( int h ) + { popHeight = h; } + + //! Get the height of the popup box + inline int pop_height() + { return popHeight; } + + //! Override of Fl_Group::handle() + int handle( int ); + + //! Override of Fl_Group::resize() + void resize( int X, int Y, int W, int H ); + + //! Set the function that will be called when the input area is interacted with + inline void input_callback( void (*cb)(Fl_Widget*,void*), void* cbd = NULL ) + { _inputCB = cb; _inputCBD = cbd; } + + //! Publicly exposed input widget + Fl_Input input; + +protected: + + void (*_inputCB)(Fl_Widget*,void*); + void* _inputCBD; + + virtual bool _value( const char *v ) = 0; + virtual const char* _next() = 0; + virtual const char* _previous() = 0; + virtual void _hilight( int x, int y ) = 0; + + void draw(); + + void selected( const char *v ); + + void set_combo_widget( Fl_Widget *w ); + + uchar _valbox; + bool _pushed, _popped; + Fl_Widget *_cbox; + int popHeight; + + static void input_cb( Fl_Widget*, void* v ); + + class FLU_EXPORT Popup : public Fl_Double_Window + { + + public: + + Popup( Flu_Combo_Box *b, Fl_Widget *c, int H ); + + ~Popup(); + + int handle( int event ); + + protected: + + Flu_Combo_Box *combo; + bool dragging; + const char* selected; + + }; + friend class Popup; + +}; + +#endif diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Combo_List.h b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Combo_List.h new file mode 100644 index 0000000..39888f1 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Combo_List.h @@ -0,0 +1,51 @@ +// $Id: Flu_Combo_List.h,v 1.6 2004/03/24 02:49:00 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#ifndef _FLU_COMBO_LIST_H +#define _FLU_COMBO_LIST_H + +#include + +#include "FLU/Flu_Combo_Box.h" + +//! Just like the Fl_Choice widget except the input area is editable +class FLU_EXPORT Flu_Combo_List : public Flu_Combo_Box +{ + +public: + + //! Normal FLTK widget constructor + Flu_Combo_List( int x, int y, int w, int h, const char *l = 0 ); + + //! Default destructor + ~Flu_Combo_List(); + + //! Publicly exposed list widget (instance of Fl_Hold_Browser) + Fl_Hold_Browser list; + + protected: + + bool _value( const char *v ); + const char* _next(); + const char* _previous(); + void _hilight( int x, int y ); + + inline static void _cb( Fl_Widget *w, void *arg ) + { ((Flu_Combo_List*)arg)->cb(); } + void cb(); + +}; + +#endif diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Combo_Tree.h b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Combo_Tree.h new file mode 100644 index 0000000..baa46d9 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Combo_Tree.h @@ -0,0 +1,50 @@ +// $Id: Flu_Combo_Tree.h,v 1.6 2004/03/24 02:49:00 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#ifndef _FLU_COMBO_TREE_H +#define _FLU_COMBO_TREE_H + +#include "FLU/Flu_Combo_Box.h" +#include "FLU/Flu_Tree_Browser.h" + +//! Just like the Fl_Choice widget except the input area is editable and it can display a tree instead of a list (using Flu_Tree_Browser) +class FLU_EXPORT Flu_Combo_Tree : public Flu_Combo_Box +{ + +public: + + //! Normal FLTK widget constructor + Flu_Combo_Tree( int x, int y, int w, int h, const char *l = 0 ); + + //! Default destructor + ~Flu_Combo_Tree(); + + //! Publicly exposed tree widget (instance of Flu_Tree_Browser) + Flu_Tree_Browser tree; + + protected: + + bool _value( const char *v ); + const char* _next(); + const char* _previous(); + void _hilight( int x, int y ); + + inline static void _cb( Fl_Widget *w, void *arg ) + { ((Flu_Combo_Tree*)arg)->cb(); } + void cb(); + +}; + +#endif diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_DND.h b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_DND.h new file mode 100644 index 0000000..743d633 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_DND.h @@ -0,0 +1,206 @@ +// $Id: Flu_DND.h,v 1.17 2003/08/20 16:29:41 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#ifndef _FLU_DND_H +#define _FLU_DND_H + +#include +#include + +#include +#include + +#include "FLU/Flu_Enumerations.h" + +#define FLU_DND_MAX_TYPES 32 + +//! This class encapsulates the event state for a single dragged object, and is designed to work exclusively with Flu_DND +class FLU_EXPORT Flu_DND_Event +{ + friend class Flu_DND; + + public: + + //! Default constructor + Flu_DND_Event(); + + //! Default destructor + ~Flu_DND_Event(); + + //! \return \c true if currently dragging an object, \c false otherwise + inline bool event_is_valid() const + { return dragging; } + + //! \return \c true if the dragged object is normal FLTK text (see Fl::copy() ), else \c false if it is an object derived from Flu_DND + inline bool event_is_text() const + { return( _text != 0 ); } + + //! \return \c true if the dragged object is an object derived from Flu_DND, else \c false if it is normal FLTK text (see Fl::copy() ) + inline bool event_is_other() const + { return( _text == 0 ); } + + //! \return the text from Fl::copy() if this event is a text event (see event_is_text() ) + /*! \note This is valid only after the object has been dropped (i.e. in Flu_DND::on_dnd_drop() )*/ + inline const char* text() const + { return _text; } + + //! \return the dragged object data as added in Flu_DND::dnd_grab() if this event is an "other" event (see event_is_other() ) + /*! \note This is valid only after the object has been dropped (i.e. in Flu_DND::on_dnd_drop() )*/ + inline void* data() const + { return _data; } + + //! \return the type of the data object that was dropped. This is \c NULL for FLTK text events + /*! \note This is valid only after the object has been dropped (i.e. in Flu_DND::on_dnd_drop() )*/ + inline const char* data_type() const + { return _dataType; } + + //! \return \c true if the type of the data object that was dropped is equal to \b t, \c false otherwise + inline bool is_data_type( const char *t ) const + { if( !_dataType ) return 0; else return( strcmp( _dataType, t ) == 0 ); } + + //! \return the x coordinate (from Fl::event_x() ) of when the object was grabbed + inline int grab_x() const + { return _grab_x; } + + //! \return the y coordinate (from Fl::event_y() ) of when the object was grabbed + inline int grab_y() const + { return _grab_y; } + + //! \return the x coordinate (from Fl::event_x() ) of when the object was dropped + inline int drop_x() const + { return _drop_x; } + + //! \return the y coordinate (from Fl::event_y() ) of when the object was dropped + inline int drop_y() const + { return _drop_y; } + + private: + + bool dragging; + void *objUnderMouse; + char *_text, *_dataType; + void *_data; + int _grab_x, _grab_y, _drop_x, _drop_y; + bool exit; + + void clear(); +}; + +//! This class augments the existing FLTK drag-n-drop feature, working with Flu_DND_Event to achieve new functionality +/*! It adds the ability to create specific DND objects, allowing classes that handle + DND to discriminate between which objects are "allowed" to be dropped on them. + + Almost all functions are protected, since only a derived class should be in charge of what kinds of events + to handle and what kinds of objects to support. +*/ +class FLU_EXPORT Flu_DND +{ + public: + + //! Set the function that is called when the dragged object is dropped. This is called in addition to the member function on_dnd_drop() + inline void dnd_callback( void (*cb)(const Flu_DND_Event*,void*), void *cbd = 0 ) + { dndCallback = cb; dndCallbackData = cbd; } + + protected: + + //! Default constructor + Flu_DND( const char *thisType ); + + //! Default destructor + virtual ~Flu_DND(); + + //! See Flu_DND_Event::event_is_text() + inline bool dnd_event_is_text() const + { return( dndEvent.dragging && !dndEvent._data ); } + + //! See Flu_DND_Event::event_is_other() + inline bool dnd_event_is_other() const + { return( dndEvent.dragging && dndEvent._data ); } + + //! See Flu_DND_Event::event_is_valid() + inline bool dnd_is_dragging() const + { return dndEvent.dragging; } + + //! See Flu_DND_Event::is_data_type() + inline bool dnd_is_data_type( const char *t ) const + { return dndEvent.is_data_type( t ); } + + //! Set whether standard FLTK text events can be dropped on this object + inline void dnd_allow_text( bool b ) + { allowTextEvents = b; } + + //! Get whether standard FLTK text events can be dropped on this object + inline bool dnd_allow_text() const + { return allowTextEvents; } + + //! Set whether this object can be dragged to another object + inline void dnd_allow_dragging( bool b ) + { allowDragging = b; } + + //! Get whether this object can be dragged to another object + inline bool dnd_allow_dragging() const + { return allowDragging; } + + //! Set whether this object can have other objects dropped on it + inline void dnd_allow_dropping( bool b ) + { allowDropping = b; } + + //! Get whether this object can have other objects dropped on it + inline bool dnd_allow_dropping() const + { return allowDropping; } + + //! Add type \b t to the list of types that are allowed to be dropped on this object (up to a compiled maximum of \c \b FLU_DND_MAX_TYPES) + void dnd_allow_type( const char *t ); + + //! \return \c true if type \b t is allowed to be dropped on this object, \c false otherwise + bool dnd_type_allowed( const char *t ) const; + + //! Descendents should call this when they detect themselves being grabbed for a drag-n-drop + void dnd_grab( void *data, const char *type ); + + //! Descendents should call this at the start of their handle() method to handle DND processing + int dnd_handle( int event ); + + //! Descendents can override this to respond to when the mouse is let go during a drag-n-drop (regardless of whether the item was dropped on you) + virtual void on_dnd_release(); + + //! Descendents can override this to respond to when the mouse has entered you during a drag-n-drop + virtual void on_dnd_enter(); + + //! Descendents can override this to respond to when the mouse has left you during a drag-n-drop + virtual void on_dnd_leave(); + + //! Descendents should override this to respond to when the dragged object has been dropped on you + virtual void on_dnd_drop( const Flu_DND_Event *e ); + + //! Descendents should override this to indicate whether the currently dragged item is allowed to be dropped on you (for example, if the item can only be dropped at certain locations) + virtual bool on_dnd_drag( int X, int Y ); + + private: + + bool ok2drop(); + + static Flu_DND_Event dndEvent; + bool allowTextEvents, allowDragging, allowDropping; + char* _thisType; + char* allowedTypes[FLU_DND_MAX_TYPES]; + int nTypes; + + void (*dndCallback)(const Flu_DND_Event*,void*); + void *dndCallbackData; + +}; + +#endif diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Dual_Progress_Meter.h b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Dual_Progress_Meter.h new file mode 100644 index 0000000..3c13a56 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Dual_Progress_Meter.h @@ -0,0 +1,143 @@ +// $Id: Flu_Dual_Progress_Meter.h,v 1.6 2003/08/20 16:29:41 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#ifndef _FLU_DUAL_PROGRESS_METER_H +#define _FLU_DUAL_PROGRESS_METER_H + +#include + +/* fltk includes */ +#include +#include +#include +#include + +#include "FLU/Flu_Label.h" +#include "FLU/Flu_Enumerations.h" + +//! This class provides a simple meter showing both current and total progress that also provides canceling behavior +class FLU_EXPORT Flu_Dual_Progress_Meter +{ + + public: + + //! Constructor which makes the progress meter with the title \b t + Flu_Dual_Progress_Meter( const char* t = NULL ); + + //! Default destructor + virtual ~Flu_Dual_Progress_Meter(); + + //! Set the title of the progress meter to \b t + inline void setTitle( const char* t ) + { if( window ) window->label( t ); } + + //! \return the title of this meter + inline const char* getTitle() const + { if( window ) return window->label(); else return ""; } + + //! Convenience routine combining setCurrentLabel() and setTotalLabel() + inline void setLabel( const char* current, const char* total ) + { if( currentLabel ) currentLabel->label( current ); if( totalLabel ) totalLabel->label( total ); } + + //! Set the "current" label displayed during the operation + inline void setCurrentLabel( const char* l ) + { if( currentLabel ) currentLabel->label( l ); } + + //! Set the "total" label displayed during the operation + inline void setTotalLabel( const char* l ) + { if( totalLabel ) totalLabel->label( l ); } + + //! Get the label for the current progress + inline const char* getCurrentLabel() const + { if( currentLabel ) return currentLabel->label(); else return ""; } + + //! Get the label for the total progress + inline const char* getTotalLabel() const + { if( totalLabel ) return totalLabel->label(); else return ""; } + + //! Set the color of the progress bar + /*! Default is FL_BLUE */ + inline void setColor( Fl_Color c ) + { if( currentSlider ) currentSlider->selection_color( c );if( totalSlider ) totalSlider->selection_color( c ); } + + //! \return the current color of the progress bar + inline Fl_Color getColor() const + { if( currentSlider ) return currentSlider->selection_color(); else return FL_BLUE; } + + //! Convenience routine combining setCurrentValue() and setTotalValue() + inline bool setValue( float currentVal, float totalVal ) + { bool b = setCurrentValue(currentVal) | setTotalValue(totalVal); return b; } + + //! Set the value of the current progress bar. \b v should be on [0,1] + /*! \return \c true if the cancel button has been pressed */ + bool setCurrentValue( float v ); + + //! Set the value of the total progress bar. \b v should be on [0,1] + /*! \return \c true if the cancel button has been pressed */ + bool setTotalValue( float v ); + + //! This function can be registered to update the progress bar + inline static void currentValueCallback( float v, void *arg ) + { ((Flu_Dual_Progress_Meter*)arg)->setCurrentValue( v ); } + + //! This function can be registered to update the progress bar + inline static void totalValueCallbackd( double v, void *arg ) + { ((Flu_Dual_Progress_Meter*)arg)->setTotalValue( (float)v ); } + + //! \return the current value of the progress bar, on [0,1] + inline float getCurrentValue() const + { if( currentSlider ) return currentSlider->value(); else return 0.0f; } + + //! \return the current value of the progress bar, on [0,1] + inline float getTotalValue() const + { if( totalSlider ) return totalSlider->value(); else return 0.0f; } + + //! Show the meter. If \b cancelBtnVisible is \c true, then the "Cancel" button will be shown + void show( bool cancelBtnVisible = false ); + + //! Hide the meter + inline void hide() + { if( window ) window->hide(); Fl::flush(); } + + //! \return \c true if the meter is shown, \c false otherwise + inline bool shown() const + { if( window ) return window->shown(); else return false; } + + //! Set the function that will be called when the "Cancel" button is pressed + inline void cancelCallback( void (*cb)(void*), void* cbd = NULL ) + { _cancelCB = cb; _cancelCBD = cbd; } + + protected: + + + private: + + void (*_cancelCB)(void*); + void* _cancelCBD; + bool _cancelled; + + static void _onCancelCB( Fl_Widget* w, void* arg ) + { ((Flu_Dual_Progress_Meter*)arg)->onCancel(); } + void onCancel() + { _cancelled = true; if( _cancelCB ) _cancelCB( _cancelCBD ); } + + Fl_Double_Window* window; + Fl_Slider *currentSlider, *totalSlider; + Fl_Button* cancel; + Flu_Label *currentLabel, *totalLabel; + +}; + +#endif diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Dual_Slider.h b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Dual_Slider.h new file mode 100644 index 0000000..5b1a9cc --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Dual_Slider.h @@ -0,0 +1,99 @@ +// $Id: Flu_Dual_Slider.h,v 1.9 2004/10/14 18:59:36 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#ifndef _FLU_DUAL_SLIDER_H +#define _FLU_DUAL_SLIDER_H + +#include +#include +#include + +#include +#include +#include + +#include "FLU/Flu_Enumerations.h" + +//! This class is essentially an Fl_Slider but with two handles. type() can be one of FL_HOR_SLIDER, FL_HOR_NICE_SLIDER, FL_VERT_SLIDER, FL_VERT_NICE_SLIDER +class FLU_EXPORT Flu_Dual_Slider : public Fl_Valuator +{ +public: + + //! Normal FLTK widget constructor + Flu_Dual_Slider( int x, int y, int w, int h, const char *l = 0 ); + + //! Default destructor + ~Flu_Dual_Slider(); + + //! Override of Fl_Valuator::handle + int handle( int event ); + + //! Override of Fl_Valuator::handle + void draw(); + + //! Set whether the low and high values can be the same (\c true), or whether they are exclusive (\c false). Default is \c false + inline void overlap( bool b ) + { _overlap = b; } + + //! Get whether the low and high values can be the same + inline bool overlap() const + { return _overlap; } + + //! Set the low value of the slider + inline void low_value( float v ) + { lowValue = v; _lVal = (lowValue-minimum())/(maximum()-minimum()); Fl_Valuator::value(v); } + + //! Get the low value of the slider + inline float low_value() const + { return minimum()>maximum() ? (minimum()+maximum()-highValue) : lowValue; } + + //! Set the high value of the slider + inline void high_value( float v ) + { highValue = v; _hVal = (highValue-minimum())/(maximum()-minimum()); Fl_Valuator::value(v); } + + //! Get the high value of the slider + inline float high_value() const + { return minimum()>maximum() ? (minimum()+maximum()-lowValue) : highValue; } + + //! Convenience routine to set low_value() and high_value() at once + inline void value( float lo, float hi ) + { low_value(lo); high_value(hi); } + + //! \return \b true if the low value slider is currently grabbed by the mouse, \c false otherwise + inline bool low_grabbed() const + { return _lGrabbed; } + + //! \return \b true if the high value slider is currently grabbed by the mouse, \c false otherwise + inline bool high_grabbed() const + { return _hGrabbed; } + +protected: + + inline bool _horizontal() + { return( type() == FL_HOR_NICE_SLIDER || type() == FL_HOR_SLIDER ); } + inline bool _nice() + { return( type() == FL_HOR_NICE_SLIDER || type() == FL_VERT_NICE_SLIDER ); } + + float highValue, lowValue; + + bool _lFocus, _flip, _overlap; + int _grab, _delta; + float _lVal, _hVal; + int _lHandle[4], _hHandle[4]; + bool _lGrabbed, _hGrabbed; + int _grabDelta; +}; + +#endif diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Enumerations.h b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Enumerations.h new file mode 100644 index 0000000..3792007 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Enumerations.h @@ -0,0 +1,71 @@ +// $Id: Flu_Enumerations.h,v 1.16 2004/04/03 17:35:41 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + +#ifndef _FLU_ENUMERATIONS_H +#define _FLU_ENUMERATIONS_H + +#include "FLU/flu_export.h" + +/* these enums are all global to conform to the fltk standard */ + +/*! Selection modes for FLU widgets that select stuff. + Used by: + Flu_Tree_Browser +*/ +enum { + FLU_NO_SELECT, + FLU_SINGLE_SELECT, + FLU_MULTI_SELECT +}; + +/*! Data insertion modes for FLU widgets that insert stuff. + Used by: + Flu_Tree_Browser +*/ +enum { + FLU_INSERT_FRONT, + FLU_INSERT_BACK, + FLU_INSERT_SORTED, + FLU_INSERT_SORTED_REVERSE +}; + +/*! Selection drag modes for FLU widgets that select stuff (used while the mouse is being dragged). + Used by: + Flu_Tree_Browser +*/ +enum { + FLU_DRAG_IGNORE, + FLU_DRAG_TO_SELECT, + FLU_DRAG_TO_MOVE +}; + +/*! Callback reasons for FLU widgets that select stuff. + Used by: + Flu_Tree_Browser +*/ +enum { + FLU_HILIGHTED, + FLU_UNHILIGHTED, + FLU_SELECTED, + FLU_UNSELECTED, + FLU_OPENED, + FLU_CLOSED, + FLU_DOUBLE_CLICK, + FLU_WIDGET_CALLBACK, + FLU_MOVED_NODE, + FLU_NEW_NODE, + FLU_NOTHING +}; + +#endif diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_File_Chooser.h b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_File_Chooser.h new file mode 100644 index 0000000..3257140 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_File_Chooser.h @@ -0,0 +1,616 @@ +// $Id: Flu_File_Chooser.h,v 1.63 2004/10/18 15:14:58 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#ifndef _FLU_FILE_CHOOSER_H +#define _FLU_FILE_CHOOSER_H + +#include +#include +#include +#include +#include +#include +#include + +#include "FLU/Flu_Button.h" +#include "FLU/Flu_Return_Button.h" +#include "FLU/Flu_Wrap_Group.h" +#include "FLU/Flu_Combo_Tree.h" +#include "FLU/Flu_Combo_List.h" +#include "FLU/flu_export.h" +#include "FLU/FluSimpleString.h" +#include "FLU/FluVectorClass.h" + +FluMakeVectorClass( FluSimpleString, FluStringVector ); + +FLU_EXPORT const char* flu_file_chooser( const char *message, const char *pattern, const char *filename ); +FLU_EXPORT int flu_multi_file_chooser( const char *message, const char *pattern, const char *filename, FluStringVector *filelist ); +FLU_EXPORT const char* flu_save_chooser( const char *message, const char *pattern, const char *filename ); +FLU_EXPORT const char* flu_dir_chooser( const char *message, const char *filename ); +FLU_EXPORT const char* flu_dir_chooser( const char *message, const char *filename, bool showFiles ); +FLU_EXPORT const char* flu_file_and_dir_chooser( const char *message, const char *filename ); + +//! A file and directory choosing widget that looks and acts similar to the stock Windows file chooser +class FLU_EXPORT Flu_File_Chooser : public Fl_Double_Window +{ + + friend class FileInput; + class FileInput : public Fl_Input + { + public: + FileInput( int x, int y, int w, int h, const char *l, Flu_File_Chooser *c ); + ~FileInput(); + + int handle( int event ); + protected: + Flu_File_Chooser *chooser; + }; + + public: + + //! strings to be set by a programmer to the correct phrase or name for their language + /*! (they are in english by default) */ + static FluSimpleString favoritesTxt; + static FluSimpleString desktopTxt; + static FluSimpleString myComputerTxt; + static FluSimpleString myDocumentsTxt; + + static FluSimpleString filenameTxt; + static FluSimpleString okTxt; + static FluSimpleString cancelTxt; + static FluSimpleString locationTxt; + static FluSimpleString showHiddenTxt; + static FluSimpleString fileTypesTxt; + static FluSimpleString directoryTxt; + static FluSimpleString allFilesTxt; + static FluSimpleString defaultFolderNameTxt; + + static FluSimpleString backTTxt; + static FluSimpleString forwardTTxt; + static FluSimpleString upTTxt; + static FluSimpleString reloadTTxt; + static FluSimpleString trashTTxt; + static FluSimpleString newDirTTxt; + static FluSimpleString addFavoriteTTxt; + static FluSimpleString previewTTxt; + static FluSimpleString listTTxt; + static FluSimpleString wideListTTxt; + static FluSimpleString detailTTxt; + + static FluSimpleString detailTxt[4]; + static FluSimpleString contextMenuTxt[3]; + static FluSimpleString diskTypesTxt[6]; + + static FluSimpleString createFolderErrTxt; + static FluSimpleString deleteFileErrTxt; + static FluSimpleString fileExistsErrTxt; + static FluSimpleString renameErrTxt; + + //! This class must be derived from to create a "preview" widget. + /*! Simply derive from this class and overload Fl_Group's methods to create a widget + able to preview whatever file type you want. Register it with Flu_File_Chooser::add_preview_handler() + When a file is previewed, all registered handlers are visited until the preview() virtual function + for one of them returns nonzero. When preview() is called, the absolute path of the file is passed in, + and the widget should determine whether it can preview the file and update itself accordingly. If + it can preview the file, it should return nonzero, else it should return zero. + */ + class FLU_EXPORT PreviewWidgetBase : public Fl_Group + { + public: + PreviewWidgetBase(); + virtual ~PreviewWidgetBase(); + virtual int preview( const char *filename ) = 0; + }; + + //! File entry type + enum { + ENTRY_NONE = 1, /*!< An empty (or non-existant) entry */ + ENTRY_DIR = 2, /*!< A directory entry */ + ENTRY_FILE = 4, /*!< A file entry */ + ENTRY_FAVORITE = 8, /*!< A favorite entry */ + ENTRY_DRIVE = 16, /*!< An entry that refers to a disk drive */ + ENTRY_MYDOCUMENTS = 32, /*!< The entry referring to the current user's documents */ + ENTRY_MYCOMPUTER = 64 /*!< The entry referring to "My Computer" in Windows */ + }; + + //! Chooser type + enum { + SINGLE = 0, /*!< Choose a single file or directory */ + MULTI = 1, /*!< Choose multiple files or directories */ + DIRECTORY = 4, /*!< Choose directories (choosing files is implicit if this bit is clear) */ + DEACTIVATE_FILES = 8, /*!< When choosing directories, also show the files in a deactivated state */ + SAVING = 16, /*!< When choosing files, whether to keep the current filename always in the input area */ + STDFILE = 32 /*!< Choose both files and directories at the same time */ + }; + + //! Structure holding the info needed for custom file types + struct FileTypeInfo + { + Fl_Image *icon; + FluSimpleString extensions; + FluSimpleString type, shortType; + }; + + //! Constructor opening a file chooser with title \b title visiting directory \b path with files filtered according to \b pattern. \b type is a logical OR of Flu_File_Chooser::SINGLE, Flu_File_Chooser::MULTI, and Flu_File_Chooser::DIRECTORY + Flu_File_Chooser( const char *path, const char *pattern, int type, const char *title ); + + //! Destructor + ~Flu_File_Chooser(); + + //! Add a custom callback that is called when the user right-clicks on an entry + /*! \param type is the type of entry to handle (i.e. a logical OR of \c ENTRY_NONE, \c ENTRY_DIR, \c ENTRY_FILE, \c ENTRY_FAVORITE, \c ENTRY_DRIVE, \c ENTRY_MYDOCUMENTS, \c ENTRY_MYCOMPUTER). To add a "nothing" handler (when the user right-clicks on nothing), use ENTRY_NONE + \param ext is the extension of the file that will cause this handler to be added to the popup menu + \param name is the name that will appear in the popup menu for this handler + */ + static void add_context_handler( int type, const char *ext, const char *name, + void (*cb)(const char*,int,void*), void *cbd ); + + //! Add a "preview" widget (derived from class Flu_File_Chooser::PreviewWidgetBase) that will handle custom previewing of files + static void add_preview_handler( PreviewWidgetBase *w ); + + //! Add descriptive information and an icon for a file type + /*! \param extensions is a space- or comma-delimited list of file extensions, or \c NULL for directories. e.g. "zip,tgz,rar" + \param short_description is a short description (!) of the file type. e.g. "Compressed Archive" + \param icon is an optional custom icon to use for this file type + */ + static void add_type( const char *extensions, const char *short_description, Fl_Image *icon = NULL ); + + //! deprecated - do not use - right click to change filenames + inline void allow_file_editing( bool b ) + { fileEditing = b; } + + //! deprecated - do not use - right click to change filenames + inline bool allow_file_editing() const + { return fileEditing; } + + //! Set whether file sorting is case insensitive. Default value is case-insensitive for windows, case-sensitive for everything else + inline void case_insensitive_sort( bool b ) + { caseSort = !b; } + + //! Get whether file sorting is case insensitive + inline bool case_insensitive_sort() const + { return !caseSort; } + + //! Change the current directory the chooser is browsing to \b path + void cd( const char *path ); + + //! Clear the history of which directories have been visited + void clear_history(); + + //! \return how many files are selected + int count(); + + //! Set the default icon to use for all files for which no other icon has been specified + inline void default_file_icon( Fl_Image* i ) + { defaultFileIcon = i; } + + //! Alias for cd() + inline void directory( const char *d ) + { cd( d ); } + + //! Alias for pattern() + inline void filter( const char *p ) + { pattern( p ); } + + //! Alias for pattern() + inline const char* filter() const + { return pattern(); } + + //! \return a pointer to a FileTypeInfo structure for files with type \b extension + static FileTypeInfo *find_type( const char *extension ); + + //! \return the current directory that the browser is visiting + inline const char* get_current_directory() const + { return currentDir.c_str(); } + + //! Override of Fl_Double_Window::handle() + int handle( int event ); + + //! Change the file filter pattern to \b p + void pattern( const char *p ); + + //! Get the current file filter pattern + inline const char* pattern() const + { return rawPattern.c_str(); } + + //! Set the state of the preview button + inline void preview( bool b ) + { previewBtn->value(b); previewBtn->do_callback(); } + + //! Get the state of the preview button + inline int preview() const + { return previewBtn->value(); } + + //! Refresh the current directory + inline void rescan() { reloadCB(); } + + //! Override of Fl_Double_Window::resize() + void resize( int x, int y, int w, int h ); + + //! Select all entries (only valid for multiple-selections) + void select_all(); + + //! Set a custom sorting function for sorting entries based on filename + inline void set_sort_function( int (*cb)(const char*,const char*) ) + { customSort = cb; rescan(); } + + //! Set the type of the chooser (see constructor) + inline void type( int t ) + { selectionType = t; rescan(); } + + //! Get the type of the chooser + inline int type( int t ) const + { return selectionType; } + + //! Unselect all entries + void unselect_all(); + + //! Set the current file the chooser is selecting + void value( const char *v ); + + //! Get the current file the chooser is selecting + const char *value(); + + //! For MULTI file queries, get selected file \b n (base 1 - i.e. 1 returns the first file, 2 the second, etc) + const char *value( int n ); + + FileInput filename; + // the key behavior is not correct for versions before 1.1.4rc2 +#if FL_MAJOR_VERSION >= 1 && FL_MINOR_VERSION >= 1 && FL_PATCH_VERSION >= 4 + Flu_Return_Button ok; +#else + Flu_Button ok; +#endif + Flu_Button cancel; + + // apparently there is a bug in VC6 that prevents friend classes from accessing + // non-public members. stupid windows + // several other compilers were reported to have a problem with this too, so + // i'm just making the whole class public to eliminate potential problems. + // bad c++ - i know... + //#ifndef WIN32 + //protected: + //#endif + + class ContextHandler + { + public: + FluSimpleString ext, name; + int type; + void (*callback)(const char*,int,void*); + void *callbackData; + inline ContextHandler& operator =( const ContextHandler &c ) + { ext = c.ext; name = c.name; type = c.type; callback = c.callback; callbackData = c.callbackData; return *this; } + }; + FluMakeVectorClass( ContextHandler, ContextHandlerVector ); + static ContextHandlerVector contextHandlers; + + typedef PreviewWidgetBase* pPreviewWidgetBase; + FluMakeVectorClass( pPreviewWidgetBase, PreviewHandlerVector ); + static PreviewHandlerVector previewHandlers; + + Fl_Check_Button *hiddenFiles; + Flu_Combo_Tree *location; + + inline static void _backCB( Fl_Widget *w, void *arg ) + { ((Flu_File_Chooser*)arg)->backCB(); } + void backCB(); + + inline static void _forwardCB( Fl_Widget *w, void *arg ) + { ((Flu_File_Chooser*)arg)->forwardCB(); } + void forwardCB(); + + inline static void _sortCB( Fl_Widget *w, void *arg ) + { ((Flu_File_Chooser*)arg)->sortCB( w ); } + void sortCB( Fl_Widget *w ); + + inline static void _previewCB( Fl_Widget*, void *arg ) + { ((Flu_File_Chooser*)arg)->previewCB(); } + void previewCB(); + + inline static void _listModeCB( Fl_Widget *w, void *arg ) + { ((Flu_File_Chooser*)arg)->listModeCB(); } + void listModeCB(); + + inline static void _filenameCB( Fl_Widget *w, void *arg ) + { ((Flu_File_Chooser*)arg)->filenameCB(); } + void filenameCB(); + + inline static void _locationCB( Fl_Widget *w, void *arg ) + { ((Flu_File_Chooser*)arg)->locationCB( ((Flu_Combo_Tree*)w)->value() ); } + void locationCB( const char *path ); + + inline static void _locationQJCB( Fl_Widget *w, void *arg ) + { ((Flu_File_Chooser*)arg)->cd( ((Fl_Button*)w)->label() ); } + + inline static void delayedCdCB( void *arg ) + { ((Flu_File_Chooser*)arg)->cd( ((Flu_File_Chooser*)arg)->delayedCd.c_str() ); } + + inline static void selectCB( void *arg ) + { ((Flu_File_Chooser*)arg)->okCB(); } + + inline static void _cancelCB( Fl_Widget*, void *arg ) + { ((Flu_File_Chooser*)arg)->cancelCB(); } + void cancelCB(); + + inline static void _okCB( Fl_Widget*, void *arg ) + { ((Flu_File_Chooser*)arg)->okCB(); } + void okCB(); + + inline static void _trashCB( Fl_Widget*, void *arg ) + { ((Flu_File_Chooser*)arg)->trashCB(); } + void trashCB( bool recycle = true ); + + inline static void _newFolderCB( Fl_Widget*, void *arg ) + { ((Flu_File_Chooser*)arg)->newFolderCB(); } + void newFolderCB(); + + inline static void upDirCB( Fl_Widget*, void *arg ) + { ((Flu_File_Chooser*)arg)->cd( "../" ); } + + inline static void reloadCB( Fl_Widget*, void *arg ) + { ((Flu_File_Chooser*)arg)->reloadCB(); } + void reloadCB(); + + inline static void _homeCB( Fl_Widget*, void *arg ) + { ((Flu_File_Chooser*)arg)->homeCB(); } + void homeCB(); + + inline static void _desktopCB( Fl_Widget*, void *arg ) + { ((Flu_File_Chooser*)arg)->desktopCB(); } + void desktopCB(); + + inline static void _favoritesCB( Fl_Widget*, void *arg ) + { ((Flu_File_Chooser*)arg)->favoritesCB(); } + void favoritesCB(); + + inline static void _myComputerCB( Fl_Widget*, void *arg ) + { ((Flu_File_Chooser*)arg)->myComputerCB(); } + void myComputerCB(); + + inline static void _addToFavoritesCB( Fl_Widget*, void *arg ) + { ((Flu_File_Chooser*)arg)->addToFavoritesCB(); } + void addToFavoritesCB(); + + inline static void _documentsCB( Fl_Widget*, void *arg ) + { ((Flu_File_Chooser*)arg)->documentsCB(); } + void documentsCB(); + + inline static void _hideCB( Fl_Widget*, void *arg ) + { ((Flu_File_Chooser*)arg)->hideCB(); } + void hideCB(); + void do_callback(); + + enum { + SORT_NAME = 1, + SORT_SIZE = 2, + SORT_TYPE = 4, + SORT_DATE = 8, + SORT_REVERSE = 16 + }; + static void _qSort( int how, bool caseSort, Fl_Widget **array, int low, int high ); + + friend class Entry; + class Entry : public Fl_Input + { + public: + Entry( const char* name, int t, bool d, Flu_File_Chooser *c ); + ~Entry(); + + int handle( int event ); + void draw(); + + void updateSize(); + void updateIcon(); + + FluSimpleString filename, date, filesize, shortname, + description, shortDescription, toolTip, altname; + //FluSimpleString permissions; + //unsigned char pU, pG, pO; // 3-bit unix style permissions + unsigned int type, idate; + unsigned long isize; + bool selected; + int editMode; + Flu_File_Chooser *chooser; + Fl_Image *icon; + + int nameW, typeW, sizeW, dateW; + bool details; + + inline static void _inputCB( Fl_Widget *w, void *arg ) + { ((Entry*)arg)->inputCB(); } + void inputCB(); + + inline static void _editCB( void *arg ) + { ((Entry*)arg)->editCB(); } + void editCB(); + }; + + friend class FileList; + class FileList : public Flu_Wrap_Group + { + public: + FileList( int x, int y, int w, int h, Flu_File_Chooser *c ); + ~FileList(); + + int handle( int event ); + void sort( int numDirs = -1 ); + + inline Fl_Widget *child(int n) const + { return Flu_Wrap_Group::child(n); } + + inline int children() const + { return Flu_Wrap_Group::children(); } + + int numDirs; + Flu_File_Chooser *chooser; + }; + + friend class FileDetails; + class FileDetails : public Fl_Pack + { + public: + FileDetails( int x, int y, int w, int h, Flu_File_Chooser *c ); + ~FileDetails(); + + int handle( int event ); + void sort( int numDirs = -1 ); + + void scroll_to( Fl_Widget *w ); + Fl_Widget* next( Fl_Widget* w ); + Fl_Widget* previous( Fl_Widget* w ); + + int numDirs; + Flu_File_Chooser *chooser; + }; + + friend class CBTile; + class CBTile : public Fl_Tile + { + public: + CBTile( int x, int y, int w, int h, Flu_File_Chooser *c ); + int handle( int event ); + Flu_File_Chooser *chooser; + }; + + friend class FileColumns; + class FileColumns : public Fl_Tile + { + public: + FileColumns( int x, int y, int w, int h, Flu_File_Chooser *c ); + ~FileColumns(); + + int handle( int event ); + void resize( int x, int y, int w, int h ); + Flu_File_Chooser *chooser; + int W1, W2, W3, W4; + }; + + friend class PreviewTile; + class PreviewTile : public Fl_Tile + { + public: + PreviewTile( int x, int y, int w, int h, Flu_File_Chooser *c ); + int handle( int event ); + Flu_File_Chooser *chooser; + int last; + }; + + class ImgTxtPreview : public PreviewWidgetBase + { + public: + int preview( const char *filename ); + unsigned char previewTxt[1024]; + }; + + friend class PreviewGroup; + class PreviewGroup : public Fl_Group + { + public: + PreviewGroup( int x, int y, int w, int h, Flu_File_Chooser *c ); + void draw(); + Flu_File_Chooser *chooser; + FluSimpleString lastFile, file; + PreviewWidgetBase* handled; + }; + + Fl_Group *getEntryGroup(); + Fl_Group *getEntryContainer(); + + void win2unix( FluSimpleString &s ); + + void cleanupPath( FluSimpleString &s ); + + bool correctPath( FluSimpleString &path ); + + void updateEntrySizes(); + + void buildLocationCombo(); + + void updateLocationQJ(); + + void addToHistory(); + + FluSimpleString formatDate( const char *d ); + + void recursiveScan( const char *dir, FluStringVector *files ); + + bool stripPatterns( FluSimpleString s, FluStringVector* patterns ); + + int popupContextMenu( Entry *entry ); + + FluSimpleString commonStr(); + + static ImgTxtPreview *imgTxtPreview; + + static int (*customSort)(const char*,const char*); + + PreviewGroup *previewGroup; + PreviewTile *previewTile; + Fl_Group *fileGroup, *locationQuickJump; + Fl_Menu_Button entryPopup; + Fl_Image *defaultFileIcon; + Entry *lastSelected; + FileList *filelist; + FileColumns *filecolumns; + Fl_Group *fileDetailsGroup; + Fl_Scroll *filescroll; + FileDetails *filedetails; + Flu_Button *detailNameBtn, *detailTypeBtn, *detailSizeBtn, *detailDateBtn; + FluSimpleString currentDir, delayedCd, rawPattern; + FluSimpleString configFilename; + FluSimpleString userHome, userDesktop, userDocs; + FluSimpleString drives[26]; + Fl_Pixmap* driveIcons[26]; + Flu_Button *fileListBtn, *fileListWideBtn, *fileDetailsBtn, *backBtn, *forwardBtn, *upDirBtn, *trashBtn, + *newDirBtn, *addFavoriteBtn, *reloadBtn, *previewBtn; + Fl_Browser *favoritesList; + Flu_Combo_List *filePattern; + int selectionType; + bool filenameEnterCallback, filenameTabCallback, walkingHistory, caseSort, fileEditing; + int sortMethod; + + FluStringVector patterns; + + static FileTypeInfo *types; + static int numTypes; + static int typeArraySize; + + static FluSimpleString dArrow[4]; + static FluSimpleString uArrow[4]; + +#ifdef WIN32 + unsigned int driveMask; + unsigned int driveTypes[26]; + FluSimpleString volumeNames[26]; + bool refreshDrives; +#endif + + class History + { + public: + History() { last = next = NULL; } + FluSimpleString path; + History *last, *next; + }; + + History *history, *currentHist; + + Fl_Callback *_callback; + void *_userdata; + +}; + +#endif diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Float_Input.h b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Float_Input.h new file mode 100644 index 0000000..a842d5b --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Float_Input.h @@ -0,0 +1,58 @@ +// $Id: Flu_Float_Input.h,v 1.10 2004/03/29 23:13:19 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#ifndef _FLU_FLOAT_INPUT_H +#define _FLU_FLOAT_INPUT_H + +#include + +#include +#include +#include + +#include "FLU/Flu_Enumerations.h" + +//! This class simply extends Fl_Float_Input to allow getting/setting the widget value as floats instead of just strings +class FLU_EXPORT Flu_Float_Input : public Fl_Float_Input +{ + public: + + //! Normal FLTK widget constructor + Flu_Float_Input( int X,int Y,int W,int H,const char *l = 0 ); + + //! Default destructor + ~Flu_Float_Input(); + + //! Set the format to use when printing the value into the input area. Only the pointer to \b f is copied. Default is "%g" + inline void format( const char *f ) + { _format = f; } + + //! Get the format to use when printing the value into the input area. + inline const char *format() const + { return _format; } + + //! \return the value of the widget as a float + inline float fvalue() const { return atof( value() ); } + + //! Set the value of the widget as a float using the given \c printf style format string + inline void fvalue( float v, const char *format = 0 ) + { char buf[32]; sprintf(buf,format?format:_format,v); value(buf); } + + private: + const char *_format; + +}; + +#endif diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_GL_Canvas.h b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_GL_Canvas.h new file mode 100644 index 0000000..0a20dff --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_GL_Canvas.h @@ -0,0 +1,105 @@ +// $Id: Flu_GL_Canvas.h,v 1.3 2004/09/23 20:16:13 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#ifndef _FLU_GL_CANVAS_H +#define _FLU_GL_CANVAS_H + +#include +#include "FLU/Flu_GL_Window.h" + +//! An easy to derive from class providing an OpenGL canvas for drawing +class FLU_EXPORT Flu_GL_Canvas : public Flu_GL_Window +{ + + public: + + //! Normal FLTK widget constructor + Flu_GL_Canvas( int x, int y, int w, int h, const char *label = 0 ); + + //! Default destructor + virtual ~Flu_GL_Canvas(); + + //! Called when the canvas is first created + virtual void init() {} + + //! Called when the canvas is resized + /*! \b width and \b height represent the new size of the OpenGL context */ + virtual void reshape( int width, int height ) {} + + //! Called when the canvas needs to be drawn + virtual void render() {} + + //! Called when the mouse scrolly wheel is scrolled + /*! \b dx and \b dy represent the amount of movement of the mouse wheel (usually 1 or -1), + and \b x and \b y represent where in the OpenGL context the event ocurred. */ + virtual void mouse_wheel( int dx, int dy, int x, int y ) {} + + //! Called when a mouse button is pressed + /*! \b button is which mouse button generated the event: { \c FL_LEFT_MOUSE | \c FL_RIGHT_MOUSE | \c FL_MIDDLE_MOUSE }, + and \b x and \b y represent where in the OpenGL context the event ocurred. */ + virtual void mouse_button_down( int button, int x, int y ) {} + + //! Called when a mouse button is released + /*! \b button is which mouse button generated the event: { \c FL_LEFT_MOUSE | \c FL_RIGHT_MOUSE | \c FL_MIDDLE_MOUSE }, + and \b x and \b y represent where in the OpenGL context the event ocurred. */ + virtual void mouse_button_up( int button, int x, int y ) {} + + //! Called when the mouse is moved with a button pressed + /*! \b x and \b y represent where in the OpenGL context the event ocurred. */ + virtual void mouse_drag( int x, int y ) {} + + //! Called when the mouse is moved without a button pressed + /*! \b x and \b y represent where in the OpenGL context the event ocurred. */ + virtual void mouse_move( int x, int y ) {} + + //! Called when the mouse enters the canvas + virtual void mouse_enter() {} + + //! Called when the mouse leaves the canvas + virtual void mouse_exit() {} + + //! Called when a key on the keyboard is pressed + /*! \b key is which key generated the event, + and \b x and \b y represent where in the OpenGL context the event ocurred. */ + virtual void keyboard( int key, int x, int y ) {} + + private: + + static inline void _initCB( void *arg ) + { ((Flu_GL_Canvas*)arg)->init(); } + static inline void _reshapeCB( int width, int height, void *arg ) + { ((Flu_GL_Canvas*)arg)->reshape(width,height); } + static inline void _renderCB( void *arg ) + { ((Flu_GL_Canvas*)arg)->render(); } + static inline void _mouse_wheelCB( int dx, int dy, int x, int y, void *arg ) + { ((Flu_GL_Canvas*)arg)->mouse_wheel(dx,dy,x,y); } + static inline void _mouse_button_downCB( int button, int x, int y, void *arg ) + { ((Flu_GL_Canvas*)arg)->mouse_button_down(button,x,y); } + static inline void _mouse_button_upCB( int button, int x, int y, void *arg ) + { ((Flu_GL_Canvas*)arg)->mouse_button_up(button,x,y); } + static inline void _mouse_dragCB( int x, int y, void *arg ) + { ((Flu_GL_Canvas*)arg)->mouse_drag(x,y); } + static inline void _mouse_moveCB( int x, int y, void *arg ) + { ((Flu_GL_Canvas*)arg)->mouse_move(x,y); } + static inline void _mouse_enterCB( void *arg ) + { ((Flu_GL_Canvas*)arg)->mouse_enter(); } + static inline void _mouse_exitCB( void *arg ) + { ((Flu_GL_Canvas*)arg)->mouse_exit(); } + static inline void _keyboardCB( int key, int x, int y, void *arg ) + { ((Flu_GL_Canvas*)arg)->keyboard(key,x,y); } + +}; + +#endif diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_GL_Window.h b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_GL_Window.h new file mode 100644 index 0000000..b19ad32 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_GL_Window.h @@ -0,0 +1,179 @@ +// $Id: Flu_GL_Window.h,v 1.12 2004/09/23 19:24:39 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#ifndef _FLU_GL_WINDOW_H +#define _FLU_GL_WINDOW_H + +#include + +/* fltk includes */ +#include +#include + +#include "FLU/Flu_Enumerations.h" + +//! A class designed to supply an easier, more functional FLTK GL window, with callback functionality similar to GLUT. +class FLU_EXPORT Flu_GL_Window : public Fl_Gl_Window +{ + + public: + + //! Normal FLTK widget constructor + Flu_GL_Window( int x, int y, int w, int h, const char *label = 0 ); + + //! Top-level window constructor + Flu_GL_Window( int w, int h, const char *label = 0 ); + + //! Default destructor + virtual ~Flu_GL_Window(); + + //! Force this window to redraw + void redraw(); + + //! \return \c true if the OpenGL context managed by this window is valid to take OpenGL calls, \c false otherwise + /*! \note This does not mean this context is the current one taking OpenGL calls, only that it *can* take calls + when it becomes current. */ + inline bool is_context_valid() + { return( can_do() > 0 ); } + + //! Setting this to \c true will report mouse input in cartesian coordinates instead of window coordinates. + /*! Default is \c true */ + inline void cartesianInput( bool b ) + { _cartesian = b; } + + //! \return \c true if mouse input is reported in cartesian coordinates, \c false otherwise + inline bool cartesianInput() const + { return _cartesian; } + + /*! \name Drawing/Input Callback Registration + * The registered functions will be called on the indicated event. + */ + //@{ + + //! The passed function must have the following signature: (void *user_data) + inline void setInitFunc( void (*cb)(void*), void* cbd = NULL ) + { _initCB = cb; _initCBD = cbd; } + + //! The passed function must have the following signature: (int width, int height, void *user_data) + /*! \b width and \b height represent the new size of the OpenGL context */ + inline void setResizeFunc( void (*cb)(int, int, void*), void* cbd = NULL ) + { _resizeCB = cb; _resizeCBD = cbd; } + + //! The passed function must have the following signature: (void *user_data) + inline void setDrawFunc( void (*cb)(void*), void* cbd = NULL ) + { _drawCB = cb; _drawCBD = cbd; } + + //! The passed function must have the following signature: (int dx, int dy, int x, int y) + /*! \b dx and \b dy represent the amount of movement of the mouse wheel (usually 1 or -1), + and \b x and \b y represent where in the OpenGL context the event ocurred. */ + inline void setMouseWheelFunc( void (*cb)(int, int, int, int, void*), void* cbd = NULL ) + { _mouseWheelCB = cb; _mouseWheelCBD = cbd; } + + //! The passed function must have the following signature: (int button, int x, int y, void *user_data) + /*! \b button is which mouse button generated the event: { \c FL_LEFT_MOUSE | \c FL_RIGHT_MOUSE | \c FL_MIDDLE_MOUSE }, + and \b x and \b y represent where in the OpenGL context the event ocurred. */ + inline void setMouseDownFunc( void (*cb)(int, int, int, void*), void* cbd = NULL ) + { _mouseDownCB = cb; _mouseDownCBD = cbd; } + + //! The passed function must have the following signature: (int button, int x, int y, void *user_data) + /*! \b button is which mouse button generated the event: { \c FL_LEFT_MOUSE | \c FL_RIGHT_MOUSE | \c FL_MIDDLE_MOUSE }, + and \b x and \b y represent where in the OpenGL context the event ocurred. */ + inline void setMouseUpFunc( void (*cb)(int, int, int, void*), void* cbd = NULL ) + { _mouseUpCB = cb; _mouseUpCBD = cbd; } + + //! The passed function must have the following signature: (int x, int y, void *user_data) + /*! \b x and \b y represent where in the OpenGL context the event ocurred. */ + inline void setMouseDragFunc( void (*cb)(int, int, void*), void* cbd = NULL ) + { _mouseDragCB = cb; _mouseDragCBD = cbd; } + + //! The passed function must have the following signature:(int x, int y, void *user_data) + /*! \b x and \b y represent where in the OpenGL context the event ocurred. */ + inline void setMouseMoveFunc( void (*cb)(int, int, void*), void* cbd = NULL ) + { _mouseMoveCB = cb; _mouseMoveCBD = cbd; } + + //! The passed function must have the following signature: (void *user_data) + inline void setMouseEnterFunc( void (*cb)(void*), void* cbd = NULL ) + { _enterCB = cb; _enterCBD = cbd; } + + //! The passed function must have the following signature: (void *user_data) + inline void setMouseExitFunc( void (*cb)(void*), void* cbd = NULL ) + { _exitCB = cb; _exitCBD = cbd; } + + //! The passed function must have the following signature: (int key, int x, int y, void *user_data) + /*! \b key is which key generated the event, + and \b x and \b y represent where in the OpenGL context the event ocurred. */ + inline void setKeyboardFunc( void (*cb)(int, int, int, void*), void* cbd = NULL ) + { _keyboardCB = cb; _keyboardCBD = cbd; } + + //@} + + //! Set a function that will be called each time a new OpenGL context is created + /*! This is useful for doing something globally specific for all contexts, such as + loading OpenGL API entrypoints under Windows. */ + inline static void setAllInitFunc( void (*cb)(void*), void* cbd = NULL ) + { allInitCB = cb; allInitCBD = cbd; } + + protected: + + void (*_drawCB)(void*); + void* _drawCBD; + + void (*_resizeCB)(int, int, void*); + void* _resizeCBD; + + void (*_initCB)(void*); + void* _initCBD; + + void (*_mouseWheelCB)(int, int, int, int, void*); + void* _mouseWheelCBD; + + void (*_mouseDownCB)(int, int, int, void*); + void* _mouseDownCBD; + + void (*_mouseUpCB)(int, int, int, void*); + void* _mouseUpCBD; + + void (*_mouseDragCB)(int, int, void*); + void* _mouseDragCBD; + + void (*_mouseMoveCB)(int, int, void*); + void* _mouseMoveCBD; + + void (*_keyboardCB)(int, int, int, void*); + void* _keyboardCBD; + + void (*_enterCB)(void*); + void* _enterCBD; + + void (*_exitCB)(void*); + void* _exitCBD; + + private: + + typedef void (*AllInitProto)(void*); + + static AllInitProto allInitCB; + static void* allInitCBD; + + bool _firstDraw; + bool _cartesian; + + /* overridden from Fl_Gl_Window */ + int handle( int event ); + void draw(); + +}; + +#endif diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Helpers.h b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Helpers.h new file mode 100644 index 0000000..572c3be --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Helpers.h @@ -0,0 +1,79 @@ +// $Id: Flu_Helpers.h,v 1.6 2004/07/14 21:10:04 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#ifndef _FLU_HELPERS_H +#define _FLU_HELPERS_H + +#include +#include +#include +#include +#include +#include +#include "FLU/Flu_Enumerations.h" + +/* Convenience routine to hide all open windows. This will (eventually) cause FLTK to exit() */ +inline static void fl_exit() +{ while( Fl::first_window() ) Fl::first_window()->hide(); } + +/* Return the index of the full menu entry 'fullname' in the menu 'menu', or + -1 if 'fullname' does not exist in 'menu'. +*/ +FLU_EXPORT int fl_Full_Find_In_Menu( const Fl_Menu_* menu, const char* fullname ); +inline int fl_Full_Find_In_Menu( const Fl_Menu_& menu, const char* fullname ) +{ return fl_Full_Find_In_Menu( &menu, fullname ); } + +/* Return the menu item at the full menu entry 'fullname' in the menu 'menu', or + NULL if 'fullname' does not exist in 'menu'. +*/ +inline const Fl_Menu_Item *fl_Full_Find_Item_In_Menu( const Fl_Menu_* menu, const char* fullname ) +{ + int index = fl_Full_Find_In_Menu( menu, fullname ); + return (index != -1) ? &(((Fl_Menu_Item*)menu->menu())[index]) : 0; +} +inline const Fl_Menu_Item *fl_Full_Find_Item_In_Menu( const Fl_Menu_& menu, const char* fullname ) +{ return fl_Full_Find_Item_In_Menu( &menu, fullname ); } + +/* Return the index of the menu entry 'name' in the menu 'menu', or + -1 if 'name' does not exist in 'menu'. +*/ +FLU_EXPORT int fl_Find_In_Menu( const Fl_Menu_* menu, const char* name ); +inline int fl_Find_In_Menu( const Fl_Menu_& menu, const char* name ) +{ return fl_Find_In_Menu( &menu, name ); } + +/* Convenience callback for an Fl_Widget to show an Fl_Window. "arg" MUST be a descendent of Fl_Window */ +inline static void fl_Show_Window_Callback( Fl_Widget* w, void* arg ) +{ ((Fl_Window*)arg)->show(); } + +/* Convenience callback for an Fl_Widget to hide an Fl_Window. "arg" MUST be a descendent of Fl_Window */ +inline static void fl_Hide_Window_Callback( Fl_Widget* w, void* arg ) +{ ((Fl_Window*)arg)->hide(); } + +/* Convenience callback for an Fl_Widget to hide an Fl_Window. "arg" MUST be a descendent of Fl_Window. + Before the window is hidden, its user_data() field is set to the widget that invoked the callback. + The user_data() can then be used to determine which widget closed the window. +*/ +inline static void fl_Hide_Window_And_Set_User_Data_Callback( Fl_Widget* w, void* arg ) +{ ((Fl_Window*)arg)->user_data( w ); ((Fl_Window*)arg)->hide(); } + +/* Convenience callback to get the value of an Fl_Button and store it (as an int) into "arg". ONLY use this for an Fl_Button and "arg" MUST point to an int. */ +inline static void fl_Get_Button_Value_Callback( Fl_Widget* w, void* arg ) +{ *((int*)arg) = ((Fl_Button*)w)->value(); } + +/* Convenience callback to get the value of an Fl_Valuator and store it (as a float) into "arg". ONLY use this for an Fl_Valuator and "arg" MUST point to a float. */ +inline static void fl_Get_Valuator_Value_Callback( Fl_Widget* w, void* arg ) +{ *((float*)arg) = ((Fl_Valuator*)w)->value(); } + +#endif diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Int_Input.h b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Int_Input.h new file mode 100644 index 0000000..4c4446b --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Int_Input.h @@ -0,0 +1,58 @@ +// $Id: Flu_Int_Input.h,v 1.9 2004/03/29 23:13:19 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#ifndef _FLU_INT_INPUT_H +#define _FLU_INT_INPUT_H + +#include + +#include +#include +#include + +#include "FLU/Flu_Enumerations.h" + +//! This class simply extends Fl_Int_Input to allow getting/setting the widget value as integers instead of strings +class FLU_EXPORT Flu_Int_Input : public Fl_Int_Input +{ + public: + + //! Normal FLTK widget constructor + Flu_Int_Input( int X,int Y,int W,int H,const char *l = 0 ); + + //! Default destructor + ~Flu_Int_Input(); + + //! Set the format to use when printing the value into the input area. Only the pointer to \b f is copied. Default is "%d" + inline void format( const char *f ) + { _format = f; } + + //! Get the format to use when printing the value into the input area. + inline const char *format() const + { return _format; } + + //! \return the value of the widget as an integer + inline int ivalue() const { return atoi( value() ); } + + //! Set the value of the widget as an integer using the given \c printf style format string + inline void ivalue( int v, const char *format = 0 ) + { char buf[32]; sprintf(buf,format?format:_format,v); value(buf); } + + private: + const char *_format; + +}; + +#endif diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Label.h b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Label.h new file mode 100644 index 0000000..3835912 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Label.h @@ -0,0 +1,72 @@ +// $Id: Flu_Label.h,v 1.7 2004/03/28 14:06:57 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#ifndef _FLU_LABEL_H +#define _FLU_LABEL_H + +#include +#include +#include + +#include "FLU/Flu_Enumerations.h" + +//! This class just provides an easier interface to making labels in FLTK +/*! All this class does is copy the label string to internal storage + since FLTK needs non-transient memory for labels. */ +class FLU_EXPORT Flu_Label : public Fl_Box +{ + + public: + + //! Normal FLTK widget constructor + Flu_Label( int x, int y, int w, int h, const char* l = 0 ); + + //! Default destructor + virtual ~Flu_Label(); + + //! Overload of Fl_Box::draw() + void draw(); + + //! Set whether the label automatically resizes itself to fit the text. Default is \c false + inline void auto_resize( bool b ) + { _autoSize = b; } + + //! Get whether the label automatically resizes itself to fit the text. + inline bool auto_resize() const + { return _autoSize; } + + //! Alias for label() + inline void value( const char* l ) + { label(l); } + + //! \return the label + inline const char* value() const + { return _label; } + + //! Set the label to \b l + void label( const char* l ); + + //! \return the label + inline const char* label() const + { return _label; } + + protected: + + char* _label; + bool _autoSize; + +}; + +#endif diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Link_Button.h b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Link_Button.h new file mode 100644 index 0000000..91b36a9 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Link_Button.h @@ -0,0 +1,42 @@ +// $Id: Flu_Link_Button.h,v 1.3 2003/10/28 15:36:06 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#ifndef _FLU_LINK_BUTTON_H +#define _FLU_LINK_BUTTON_H + +#include "FLU/Flu_Button.h" + +//! This class extends Flu_Button to make a button that looks like a hyperlink +class FLU_EXPORT Flu_Link_Button : public Flu_Button +{ + public: + + //! Normal FLTK widget constructor + Flu_Link_Button( int X,int Y,int W,int H,const char *l = 0 ); + + //! Default destructor + ~Flu_Link_Button(); + + //! Set whether the link underline appears only when the mouse is over the button. Default is \c false + inline void overlink( bool b ) + { overLink = b; } + + //! Get whether the link underline appears only when the mouse is over the button + inline bool overlink() const + { return overLink; } + +}; + +#endif diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Output.h b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Output.h new file mode 100644 index 0000000..77799c4 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Output.h @@ -0,0 +1,52 @@ +// $Id: Flu_Output.h,v 1.8 2003/08/20 16:29:42 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#ifndef _FLU_OUTPUT_H +#define _FLU_OUTPUT_H + +#include + +#include +#include +#include + +#include "FLU/Flu_Enumerations.h" + +//! This class simply extends Fl_Output to allow getting/setting the widget value as integers and floats in addition to strings +class FLU_EXPORT Flu_Output : public Fl_Output +{ + public: + + //! Normal FLTK widget constructor + Flu_Output( int X,int Y,int W,int H,const char *l = 0 ); + + //! Default destructor + ~Flu_Output(); + + //! \return the value of the widget as an integer + inline int ivalue() const { return atoi( value() ); } + + //! Set the value of the widget as an integer using the given \c printf style format string + inline void ivalue( int v, const char *format = "%d" ) { char buf[32]; sprintf(buf,format,v); value(buf); } + + //! \return the value of the widget as a float + inline float fvalue() const { return atof( value() ); } + + //! Set the value of the widget as a float using the given \c printf style format string + inline void fvalue( float v, const char *format = "%.2f" ) { char buf[32]; sprintf(buf,format,v); value(buf); } + +}; + +#endif diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Progress.h b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Progress.h new file mode 100644 index 0000000..885108b --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Progress.h @@ -0,0 +1,50 @@ +// $Id: Flu_Progress.h,v 1.6 2004/04/10 22:10:56 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#ifndef _FLU_PROGRESS_H +#define _FLU_PROGRESS_H + +#include +#include +#include + +#include "FLU/Flu_Enumerations.h" + +//! This class provides a simple progress widget similar to the way Fl_Slider is used for progress, except it is just for progress reporting and displays the progress value inside the widget +class FLU_EXPORT Flu_Progress : public Fl_Valuator +{ + +public: + + //! Normal FLTK widget constructor + Flu_Progress( int x, int y, int w, int h, const char *l = 0 ); + + //! Default destructor + ~Flu_Progress(); + + //! Override of Fl_Valuator::value() which forces a redraw only if the new value causes the integral percent to change + int value( float v ); + + //! Pass-through of Fl_Valuator::value() + inline float value() const + { return Fl_Valuator::value(); } + +protected: + + void draw(); + +}; + +#endif diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Progress_Meter.h b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Progress_Meter.h new file mode 100644 index 0000000..eb955d9 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Progress_Meter.h @@ -0,0 +1,151 @@ +// $Id: Flu_Progress_Meter.h,v 1.12 2004/06/30 00:18:00 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#ifndef _FLU_PROGRESS_METER_H +#define _FLU_PROGRESS_METER_H + +#include + +/* fltk includes */ +#include +#include +#include + +#include "FLU/Flu_Label.h" +#include "FLU/Flu_Progress.h" +#include "FLU/Flu_Enumerations.h" + +#ifdef WIN32 +#include +#include +#else +#include +#endif + +//! This class provides a simple progress meter with elapsed time, estimated time to completion, and optional canceling behavior +class FLU_EXPORT Flu_Progress_Meter : public Fl_Double_Window +{ + + public: + + //! Constructor which makes the progress meter with the title \b t + Flu_Progress_Meter( const char* t = NULL ); + + //! Default destructor + virtual ~Flu_Progress_Meter(); + + //! Set the title of the progress meter to \b t + inline void title( const char* t ) + { Fl_Double_Window::label( t ); } + + //! \return the title of this meter + inline const char* title() const + { return Fl_Double_Window::label(); } + + //! Set the label that is displayed during the operation to \b l + inline void label( const char* l ) + { if( _label ) _label->label( l ); } + + //! Get the label that is currently displayed + inline const char* label() const + { if( _label ) return _label->label(); else return ""; } + + //! Set the color of the progress bar. Default is FL_BLUE + inline void color( Fl_Color c ) + { if( progress ) progress->selection_color( c ); } + + //! \return the current color of the progress bar + inline Fl_Color color() const + { if( progress ) return progress->selection_color(); else return FL_BLUE; } + + //! Set the value of the progress bar. \b v should be on [0,1] + /*! \return \c true if the cancel button has been pressed */ + bool value( float v ); + + //! \return the current value of the progress bar, on [0,1] + inline float value() const + { if( progress ) return progress->value(); else return 0.0f; } + + //! This function can be registered to update the progress bar + inline static void value_callback( float v, void *arg ) + { ((Flu_Progress_Meter*)arg)->value( v ); } + + //! This function can be registered to update the progress bar + inline static void value_callbackd( double v, void *arg ) + { ((Flu_Progress_Meter*)arg)->value( (float)v ); } + + //! This function can be registered to update the progress bar + inline static bool cvalue_callback( float v, void *arg ) + { return ((Flu_Progress_Meter*)arg)->value( v ); } + + //! This function can be registered to update the progress bar + inline static bool cvalue_callbackd( double v, void *arg ) + { return ((Flu_Progress_Meter*)arg)->value( (float)v ); } + + //! Set whether to show the estimated time to completion of the operation. Default is \c true + inline void show_completion_time( bool b ) + { _showETC = b; } + + //! Get whether to show the estimated time to completion of the operation + inline bool show_completion_time() const + { return _showETC; } + + //! Show the meter. If \b withCancelButton is \c true, then the "Cancel" button will be shown + void show( bool withCancelButton = false ); + + void reset(); + + //! Hide the meter + void hide(); + + //! Set the function that will be called when the "Cancel" button is pressed + inline void cancel_callback( void (*cb)(void*), void* cbd = NULL ) + { _cancelCB = cb; _cancelCBD = cbd; } + + protected: + + + private: + +#ifdef WIN32 + inline void gettimeofday( struct timeval *t, void* ) + { + t->tv_sec = 0; + t->tv_usec = clock(); + } +#endif + + timeval startT; + + inline static void _secondTimerCB( void *arg ) + { ((Flu_Progress_Meter*)arg)->secondTimerCB(); } + void secondTimerCB( bool repeatTimer = true ); + + void (*_cancelCB)(void*); + void* _cancelCBD; + bool _cancelled, _showETC; + + static void _onCancelCB( Fl_Widget* w, void* arg ) + { ((Flu_Progress_Meter*)arg)->onCancel(); } + void onCancel() + { _cancelled = true; if( _cancelCB ) _cancelCB( _cancelCBD ); } + + Flu_Progress* progress; + Fl_Button* cancel; + Flu_Label *_label, *etc; + +}; + +#endif diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Return_Button.h b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Return_Button.h new file mode 100644 index 0000000..962482f --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Return_Button.h @@ -0,0 +1,34 @@ +// $Id: Flu_Return_Button.h,v 1.2 2003/08/20 16:29:42 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#ifndef _FLU_RETURN_BUTTON_H +#define _FLU_RETURN_BUTTON_H + +#include "FLU/Flu_Button.h" + +//! This class extends Flu_Button to make a button similar to Fl_Return_Button +class FLU_EXPORT Flu_Return_Button : public Flu_Button +{ + public: + + //! Normal FLTK widget constructor + Flu_Return_Button( int X,int Y,int W,int H,const char *l = 0 ); + + //! Default destructor + ~Flu_Return_Button(); + +}; + +#endif diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Separator.h b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Separator.h new file mode 100644 index 0000000..c7526a2 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Separator.h @@ -0,0 +1,55 @@ +// $Id: Flu_Separator.h,v 1.6 2003/08/20 16:29:42 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#ifndef _FLU_SEPARATOR_H +#define _FLU_SEPARATOR_H + +/* fltk includes */ +#include +#include +#include + +#include "FLU/Flu_Enumerations.h" + +//! A simple class that draws a separator line using the current box type +class FLU_EXPORT Flu_Separator : public Fl_Widget +{ + public: + + enum { + HORIZONTAL, + VERTICAL + }; + + //! Normal FLTK constructor. Default type() is \b HORIZONTAL + Flu_Separator( int X, int Y, int W, int H, const char *l = 0 ); + + //! Get the type + inline int type() const + { return _type; } + + //! Set the type + inline void type( int t ) + { _type = t; } + + protected: + + int _type; + + void draw(); + +}; + +#endif diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Simple_Group.h b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Simple_Group.h new file mode 100644 index 0000000..d4cea23 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Simple_Group.h @@ -0,0 +1,40 @@ +// $Id: Flu_Simple_Group.h,v 1.7 2003/08/20 16:29:43 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#ifndef _FLU_SIMPLE_GROUP_H +#define _FLU_SIMPLE_GROUP_H + +/* fltk includes */ +#include +#include +#include + +#include "FLU/Flu_Enumerations.h" + +//! This class provides a simple aesthetic alternative to Fl_Group +class FLU_EXPORT Flu_Simple_Group : public Fl_Group +{ + + public: + + //! Normal FLTK constructor + Flu_Simple_Group( int x, int y, int w, int h, const char *l = 0 ); + + //! Override of Fl_Group::draw() + void draw(); + +}; + +#endif diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Spinner.h b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Spinner.h new file mode 100644 index 0000000..c214f5a --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Spinner.h @@ -0,0 +1,164 @@ +// $Id: Flu_Spinner.h,v 1.11 2004/10/22 16:17:45 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#ifndef _FLU_SPINNER_H +#define _FLU_SPINNER_H + +#include +#include +#include + +#include "FLU/Flu_Enumerations.h" + +//! This class provides a simple spinner widget similar to Fl_Counter, except the manipulator buttons are vertical and you can click, click and hold, or click and drag to change the value +class FLU_EXPORT Flu_Spinner : public Fl_Valuator +{ + + class NoTabInput : public Fl_Input + { + public: + NoTabInput( Flu_Spinner *s, int x, int y, int w, int h, const char *l = 0 ); + int handle( int event ); + void draw(); + Flu_Spinner *spinner; + }; + +public: + + //! Normal FLTK widget constructor + Flu_Spinner( int x, int y, int w, int h, const char *l = 0 ); + + //! Default destructor + ~Flu_Spinner(); + + //! Get whether the spinner automatically changes when you hold the button down + inline bool enable_repeating() const + { return _doRepeat; } + + //! Set whether the spinner automatically changes when you hold the button down + inline void enable_repeating( bool b ) + { _doRepeat = b; } + + //! Set the auto repeating parameters + /*! \param initialDelay is how long to wait before repeating starts. Default is 0.5 seconds + \param initialTime is how long to wait between value changes. Default is 0.1 seconds (i.e. 10x per second) + \param rapidDelay is how long to wait before repeating more quickly. Default is 2 seconds + \param rapidTime is how long to wait between rapid value changes. Default is 0.02 seconds (i.e. 50x per second) + */ + inline void repeat( float initialDelay, float initialTime, float rapidDelay, float rapidTime ) + { _initialDelay = initialDelay; _repeatTime[0] = initialTime; _rapidDelay = rapidDelay;_repeatTime[1] = rapidTime; } + + //! Get when the input calls the callback + inline int input_when() const + { return _input.when(); } + + //! Set when the input calls the callback + inline void input_when( int w ) + { _input.when(w); } + + //! Get whether the input field can be edited. Default is \c true + inline bool editable() const + { return _editable; } + + //! Set whether the input field can be edited. + inline void editable( bool b ) + { _editable = b; } + + //! Override of Fl_Widget::handle() + int handle( int ); + + //! Override of Fl_Widget::resize() + void resize( int X, int Y, int W, int H ); + + //! The default range for Fl_Valuators is [0,1]. This function sets the range of the spinner to +/- infinity + inline void unlimited_range() + { range( -3.4e+38f, 3.4e+38f ); } + + //! Set whether the value "wraps" to the range during interaction + inline void wrap_range( bool b ) + { _wrapRange = b; } + + //! Set whether the value "wraps" to the range during interaction + inline bool wrap_range() const + { return _wrapRange; } + + //! Override of Fl_Valuator::precision() + inline void precision( int p ) + { Fl_Valuator::precision(p); value_damage(); } + + //! Override of Fl_Valuator::value_damage() + void value_damage(); + + //! Override of Fl_Valuator::hide() + inline void hide() + { Fl_Valuator::hide(); _input.hide(); } + + //! Override of Fl_Valuator::show() + inline void show() + { Fl_Valuator::show(); _input.show(); } + + //! Get the font for the widget value + inline Fl_Font valuefont() const { return (Fl_Font)_input.textfont(); } + + //! Set the font for the widget value + inline void valuefont( uchar s ) { _input.textfont(s); } + + //! Get the size of the font for the widget value + inline uchar valuesize() const { return _input.textsize(); } + + //! Set the size of the font for the widget value + inline void valuesize( uchar s ) { _input.textsize(s); } + + //! Get the background color of the widget value + inline Fl_Color valuecolor() const { return (Fl_Color)_input.color(); } + + //! Set the background color for the widget value + inline void valuecolor( unsigned s ) { _input.color(s); } + + //! Set the background and selection color for the widget value + inline void valuecolor( unsigned s, unsigned s1 ) { _input.color(s,s1); } + + //! Get the color of the font for the widget value + inline Fl_Color valuefontcolor() const { return (Fl_Color)_input.textcolor(); } + + //! Set the color of the font for the widget value + inline void valuefontcolor( unsigned s ) { _input.textcolor(s); } + +protected: + + void _setvalue( double v ); + + friend class NoTabInput; + + NoTabInput _input; + uchar _valbox[2]; + bool _up, _pushed, _editable, _dragging; + float _totalTime; + double _lastValue; + int _lastY; + float _initialDelay, _repeatTime[2], _rapidDelay; + bool _doRepeat, _wrapRange; + + static void input_cb( Fl_Widget*, void* v ); + static void repeat_callback(void *); + void increment_cb(); + +protected: + + void draw(); + +}; + +#endif diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Toggle_Group.h b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Toggle_Group.h new file mode 100644 index 0000000..e637c65 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Toggle_Group.h @@ -0,0 +1,72 @@ +// $Id: Flu_Toggle_Group.h,v 1.8 2003/08/20 16:29:43 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#ifndef _FLU_TOGGLE_GROUP_H +#define _FLU_TOGGLE_GROUP_H + +#include +#include + +/* fltk includes */ +#include +#include +#include +#include + +#include "FLU/Flu_Enumerations.h" + +//! This class provides a group that can be toggled active or inactive +class FLU_EXPORT Flu_Toggle_Group : public Fl_Group +{ + + public: + + //! Default FLTK constructor + Flu_Toggle_Group( int x, int y, int w, int h, const char *l = 0 ); + + //! Activate the group + inline void activate() + { value(1); } + + //! Deactivate the group + inline void deactivate() + { value(0); } + + //! Get the activation state of this group. + inline int active() const + { return value(); } + + //! Set the activation state of this group. 0 deactivates the group, anything else activates it. + inline void value( int v ) + { chkBtn->value(v); redraw(); } + + //! Get the activation state of this group. + inline int value() const + { return chkBtn->value(); } + + //! Override of Fl_Group::draw() + void draw(); + + protected: + + static void _toggleCB( Fl_Widget *w, void *arg ) + { ((Flu_Toggle_Group*)arg)->toggleCB(); } + void toggleCB(); + + Fl_Check_Button *chkBtn; + +}; + +#endif diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Tree_Browser.h b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Tree_Browser.h new file mode 100644 index 0000000..9512114 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Tree_Browser.h @@ -0,0 +1,1237 @@ +// $Id: Flu_Tree_Browser.h,v 1.91 2004/11/05 17:03:20 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#ifndef _FLU_TREE_BROWSER_H +#define _FLU_TREE_BROWSER_H + +#include +#include +#include + +//#define USE_FLU_DND + +/* fltk includes */ +#include +#include +#include +#include +#include +#include +#include + +/* flu includes */ +#include "FLU/Flu_Enumerations.h" +#include "FLU/FluSimpleString.h" +#ifdef USE_FLU_DND +#include "FLU/Flu_DND.h" +#else +typedef struct { bool dummy; } Flu_DND_Event; // for compatibilty when not compiling DND support +#endif + +//! This class provides a browser for hierarchical data representation (i.e. a "tree") +#ifdef USE_FLU_DND +class FLU_EXPORT Flu_Tree_Browser : public Fl_Group, public Flu_DND +#else +class FLU_EXPORT Flu_Tree_Browser : public Fl_Group +#endif +{ + + static bool USE_FLU_WIDGET_CALLBACK; + + public: + + class Node; + friend class Node; + + //! Normal FLTK widget constructor + Flu_Tree_Browser( int x, int y, int w, int h, const char *label = 0 ); + + //! Default destructor + virtual ~Flu_Tree_Browser(); + + //! Add the entry specified by \b fullpath to the tree. If \b w is not \c NULL then that widget is the entry and its label is visible depending on the value of \b showLabel. Note that the widget is destroyed by the tree/node on clear() or the destructor + /*! If \b fullpath ends in a slash ("/"), then the entry is added as a branch, else it is added as a leaf + \return a pointer to the Node of the added entry or NULL if the add failed */ + Node* add( const char* fullpath, Fl_Widget *w = 0, bool showLabel = true ); + + //! Convenience function that is the same as add() except \b path and \b name are concatenated (with a '/' added if necessary) to create the full path + Node* add( const char* path, const char* name, Fl_Widget *w = 0, bool showLabel = true ); + + //! Add entry \b name to node \b n. If \b w is not \c NULL then that widget is the entry and its label is visible depending on the value of \b showLabel. Note that the widget is destroyed by the tree/node on clear() or the destructor + /*! If \b name ends in a slash ("/"), then the entry is added as a branch, else it is added as a leaf + \return a pointer to the Node of the added entry or NULL if the add failed */ + inline Node* add( Node* n, const char* name, Fl_Widget *w = 0, bool showLabel = true ) + { return n->add( name, w, showLabel ); } + + //! Convenience function that is the same as add() except it appends a '/' to \b fullpath if one does not exist + Node* add_branch( const char* fullpath, Fl_Widget *w = 0, bool showLabel = true ); + + //! Convenience function that is the same as add() except \b path and \b name are concatenated (with a '/' added if necessary) to create the full path + Node* add_branch( const char* path, const char* name, Fl_Widget *w = 0, bool showLabel = true ); + + //! Convenience function that is the same as add() except it appends a '/' to \b name if one does not exist + inline Node* add_branch( Node* n, const char* name, Fl_Widget *w = 0, bool showLabel = true ) + { return n->add_branch( name, w, showLabel ); } + + //! Convenience function that is the same as add() except it removes any '/' at the end of \b fullpath + Node* add_leaf( const char* fullpath, Fl_Widget *w = 0, bool showLabel = true ); + + //! Convenience function that is the same as add() except \b path and \b name are concatenated (with a '/' added if necessary) to create the full path + Node* add_leaf( const char* path, const char* name, Fl_Widget *w = 0, bool showLabel = true ); + + //! Convenience function that is the same as add() except it removes any '/' at the end of \b fullpath + inline Node* add_leaf( Node* n, const char* name, Fl_Widget *w = 0, bool showLabel = true ) + { return n->add_leaf( name, w, showLabel ); } + + //! Set whether all branches are always open. Default value is \c false + inline void all_branches_always_open( bool b ) + { rdata.allBranchesAlwaysOpen = b; } + + //! Get whether all branches are always open. Default value is \c false + inline bool all_branches_always_open() + { return rdata.allBranchesAlwaysOpen; } + + //! Set whether multiple leaves with the same path are allowed. Default value is \c true + inline void allow_leaf_duplication( bool b ) + { rdata.allowDuplication = b; } + + //! Get whether multiple leaves with the same path are allowed. + inline bool allow_leaf_duplication() + { return rdata.allowDuplication; } + + //! \return \c true if drag and drop support has been compiled in, \c false otherwise + inline bool have_dnd() + { +#ifdef USE_FLU_DND + return true; +#else + return false; +#endif + } + + //! Set whether drag and drop processing is enabled for the browser. Default is \c false + /*! If DND is enabled, either text or instances of Flu_Tree_Browser::DND_Object from outside the tree can be dragged and dropped + onto the tree to create a new node. Nodes within the tree can be dragged and dropped (only within the same tree) according to + the value of selection_drag_mode(). */ + inline void allow_dnd( bool b ) + { rdata.dnd = b; } + + //! Get whether drag and drop processing is enabled for the browser. + inline bool allow_dnd() + { return rdata.dnd; } + + //! Set whether the root node is always open. Shortcut for \c get_root()->always_open(b). Default is \c false + inline void always_open( bool b ) + { root.always_open( b ); } + + //! Get whether the root node is always open + inline bool always_open() + { return root.always_open(); } + + //! Set whether animations of opening/closing branches are enabled. Default is \c false + inline void animate( bool b ) + { rdata.animate = b; } + + //! Get whether animations of opening/closing branches are enabled + inline bool animate() + { return rdata.animate; } + + //! Set whether the tree automatically determines whether a node is a branch or a leaf based on whether it has any children. Default is \c false + void auto_branches( bool b ); + + //! Get whether the tree automatically determines whether a node is a branch or a leaf based on whether it has any children + inline bool auto_branches() const + { return rdata.autoBranches; } + + //! Get the default branch text color + inline Fl_Color branch_color() const + { return rdata.defBranchColor; } + + //! Get the default branch text font + inline Fl_Font branch_font() const + { return rdata.defBranchFont; } + + //! Get the default branch text size + inline int branch_size() const + { return rdata.defBranchSize; } + + //! Set the default color, font and size to use for the text of all subsequent branches added to the tree + inline void branch_text( Fl_Color color, Fl_Font font, int size ) + { rdata.defBranchColor = color; rdata.defBranchFont = font; rdata.defBranchSize = size; } + + //! Set the default branch icons to use for all subsequent branches added to the tree + /*! Passing in \c NULL for either icon will disable that icon for the branch */ + void branch_icons( Fl_Image *closed, Fl_Image *open ); + + //! Get the type of box to draw the browser in + inline Fl_Boxtype box() const + { return _box->box(); } + + //! Set the type of box to draw the browser in. Default is FL_FLAT_BOX + inline void box( Fl_Boxtype b ) + { _box->box( b ); } + + //! Override of Fl_Widget::callback + //inline void callback( Fl_Callback *c, void *user_data = 0 ) + //{ rdata.cb = c; rdata.cbd = user_data; } + + //! Get the reason why the last callback happened. This can be one of FLU_UNHILIGHTED, FLU_HILIGHTED, FLU_SELECTED, FLU_UNSELECTED, FLU_OPENED, FLU_CLOSED, FLU_DOUBLE_CLICK, FLU_WIDGET_CALLBACK, FLU_MOVED_CALLBACK, FLU_NEW_NODE_CALLBACK + inline int callback_reason() const + { return rdata.cbReason; } + + //! Get the node on which the last callback happened. + /*! \note this node is only guaranteed to be in the tree \b during the callback. If the callback adds/removes nodes, then this node may have changed */ + inline Node* callback_node() const + { return rdata.cbNode; } + + //! Clear all entries from the tree + void clear(); + + //! Set the default collapse icons to use for all subsequent branches added to the tree + void collapse_icons( Fl_Image *closed, Fl_Image *open ); + + //! Get the amount of time to take when animating an open/close. Use in conjunction with frame_rate() + inline float collapse_time() const + { return rdata.collapseTime; } + + //! Set the amount of time to take when animating an open/close. Use in conjunction with frame_rate(). Default is 0.1 seconds + inline void collapse_time( float t ) + { rdata.collapseTime = t; } + + //! Get the background color of the browser + inline Fl_Color color() const + { return _box->color(); } + + //! Set the background color of the browser. Default is FL_WHITE + inline void color( Fl_Color c ) + { _box->color( c ); } + + //! Set the color, style, and width of the connector lines. Default is FL_DARK2, FL_DOT, 1 + inline void connector_style( Fl_Color color, int style, int width = 1 ) + { rdata.defLineColor = color; rdata.lineStyle = style; rdata.lineWidth = width; } + + //! Get the color of the connector lines + inline Fl_Color connector_color() const + { return rdata.defLineColor; } + + //! Get the style of the connector lines + inline int connector_style() const + { return rdata.lineStyle; } + + //! Get the width of the connector lines + inline int connector_width() const + { return rdata.lineWidth; } + + //! Set whether double-clicking a branch opens/closes it + inline void double_click_opens( bool b ) + { rdata.doubleClickToOpen = b; } + + //! Get whether double-clicking a branch opens/closes it + inline bool double_click_opens() + { return rdata.doubleClickToOpen; } + + //! Get the color to use for shading even entries + inline Fl_Color even_shaded_entry_color() const + { return rdata.shadedColors[0]; } + + //! Find the entry identified by \b fullpath + /*! \return a pointer to the Node of the found entry, or NULL if no matching entry was found */ + inline Node* find( const char *fullpath ) + { return find_next( fullpath ); } + + //! Find entry \b name in path \b path + /*! \return a pointer to the Node of the found entry, or NULL if no matching entry was found */ + Node* find( const char *path, const char *name ); + + //! Find the entry identified by unique id \b id + /*! \return a pointer to the Node of the found entry, or NULL if no matching entry was found */ + Node* find( unsigned int id ); + + //! Search for Node \b n in the tree + /*! \return a pointer to \b n if it is found, or NULL if it is not in the tree */ + inline Node* find( Node *n ) + { if( !n ) return NULL; else return find( n->id() ); } + + //! Find the entry containing the widget \b w + /*! \return a pointer to the Node of the found entry, or NULL if no matching entry was found */ + Node* find( Fl_Widget *w ); + + //! Find the next entry identified by \b fullpath after \b startNode + /*! \return a pointer to the Node of the found entry, or NULL if no matching entry was found */ + Node* find_next( const char *fullpath, Node* startNode = NULL ); + + //! Find the next entry \b name in path \b path after \b startNode + /*! \return a pointer to the Node of the found entry, or NULL if no matching entry was found */ + Node* find_next( const char *path, const char *name ); + + //! \return the number of discovered nodes matching path \b fullpath + int find_number( const char *fullpath ); + + //! \return the number of discovered nodes with name \b name in path \b path + int find_number( const char *path, const char *name ); + + //! \return the full path of the entry identified by unique id \b id, or the empty string if no matching entry was found + /*! \note the returned value is only valid until the next time find_path() is called */ + const char* find_path( unsigned int id ); + + //! \return the full path of the entry containing the widget \b w, or the empty string if no matching entry was found + /*! \note the returned value is only valid until the next time find_path() is called */ + const char* find_path( Fl_Widget *w ); + + //! \return the full path of Node \b n, or the empty string if \b n is not in the tree + /*! \note the returned value is only valid until the next time find_path() is called */ + inline const char* find_path( Node *n ) + { if( !n ) return ""; else return find_path( n->id() ); } + + //! \return the first node in the tree (i.e. the root) + inline Node* first() { return root.first(); } + + //! \return the first branch encountered in a depth-first traversal of the tree. NULL means there are no branches + inline Node* first_branch() { return root.first_branch(); } + + //! \return the first leaf encountered in a depth-first traversal of the tree. NULL means there are no leaves + inline Node* first_leaf() { return root.first_leaf(); } + + //! Get the frame rate to use during the open/close animation. Use in conjunction with collapse_time() + inline float frame_rate() const + { return rdata.fps; } + + //! Set the frame rate to use during the open/close animation. Use in conjunction with collapse_time(). Default is 100 frames per second + inline void frame_rate( float f ) + { if( f <= 0.0f ) rdata.fps = 0.001f; else rdata.fps = f; } + + //! \return the currently highlighted node + inline Node* get_hilighted() + { return rdata.hilighted; } + + //! \return a pointer to the root node of the tree + inline Node *get_root() { return &root; } + + //! \return the selected Node that is at \b index among all selected nodes, or \c NULL if no Node is selected + /*! For example, \c get_selected(1) will return the first selected node. */ + Node* get_selected( int index ); + + //! Override of Fl_Widget::handle + int handle( int event ); + + //! Set the horizontal icon gap for each entry. Default is 2 + inline void horizontal_gap( int g ) + { rdata.hGap = g; rdata.forceResize = true; } + + //! Get the horizontal icon gap for each entry + inline int horizontal_gap() const + { return rdata.hGap; } + + //! Set how entries are inserted into the tree. This can be one of FLU_INSERT_FRONT, FLU_INSERT_BACK, FLU_INSERT_SORTED, FLU_INSERT_SORTED_REVERSE. Default is FLU_INSERT_SORTED + void insertion_mode( int m ); + + //! Get how entries are inserted into the tree. + inline int insertion_mode() + { return rdata.insertionMode; } + + //! \return whether the point \c (x,y) is inside the entry area (not on the scrollbars) + bool inside_entry_area( int x, int y ); +// bool Flu_Tree_Browser :: inside_entry_area( int x, int y ); +// Mark sibly was here! gcc something > 3.3 doesn't like the extra Flu_Tree_Browser:: bit (understandable!) + + //! Set the title of the Tree (also the label for the root entry) + inline void label( const char *l ) + { root.text = l; } + + //! Get the title of the Tree (also the label for the root entry) + inline const char* label() const + { return root.text.c_str(); } + + //! \return the last node in the tree + inline Node* last() { return root.last(); } + + //! \return the last branch encountered in a depth-first traversal of the tree. NULL means there are no branches + inline Node* last_branch() { return root.last_branch(); } + + //! \return the last leaf encountered in a depth-first traversal of the tree. NULL means there are no leaves + inline Node* last_leaf() { return root.last_leaf(); } + + //! Get the default leaf text color + inline Fl_Color leaf_color() const + { return rdata.defLeafColor; } + + //! Get the default leaf text font + inline Fl_Font leaf_font() const + { return rdata.defLeafFont; } + + //! Get the default leaf text size + inline int leaf_size() const + { return rdata.defLeafSize; } + + //! Set the default leaf icon to use for all subsequent leaves added to the tree + void leaf_icon( Fl_Image *icon ); + + //! Set the default color, font and size to use for the text of all subsequent leaves added to the tree, Default is FL_BLACK, FL_HELVETICA, 12 + inline void leaf_text( Fl_Color color, Fl_Font font, int size ) + { rdata.defLeafColor = color; rdata.defLeafFont = font; rdata.defLeafSize = size; } + + //! Set whether items can be moved only within their group ( \c true ) or can be moved anywhere in the tree ( \c false ). Default is \c false. Used only when selection_drag_mode() is FLU_DRAG_TO_MOVE. + inline void move_only_same_group( bool b ) + { rdata.moveOnlySameGroup = b; } + + //! Get whether items can be moved only within their group ( \c true ) or can be moved anywhere in the tree ( \c false ). Used only when selection_drag_mode() is FLU_DRAG_TO_MOVE. + inline bool move_only_same_group() + { return rdata.moveOnlySameGroup; } + + //! \return the number of selected entries + int num_selected(); + + //! Get the color to use for shading odd entries + inline Fl_Color odd_shaded_entry_color() const + { return rdata.shadedColors[1]; } + + //! Set whether only a single branch (except the root branch) is allowed open at a time. Default is \c false + inline void only_one_open_branch( bool b ) + { rdata.singleBranchOpen = b; } + + //! Get whether only a single branch (except the root branch) is allowed open at a time + inline bool only_one_open_branch() + { return rdata.singleBranchOpen; } + + //! Open or close the root node + inline void open( bool b ) + { root.open( b ); } + + //! Is the root node open or closed? + inline bool open() const + { return root.open(); } + + //! Set whether you can open/close a branch even if it has no children. Default is \c false + inline void open_without_children( bool b ) + { rdata.openWOChildren = b; } + + //! Get whether you can open/close a branch even if it has no children. + inline bool open_without_children() const + { return rdata.openWOChildren; } + + //! Set whether selecting a branch also opens it. Default is \c false + inline void open_on_select( bool b ) + { rdata.openOnSelect = b; } + + //! Get whether selecting a branch also opens it + inline bool open_on_select() const + { return rdata.openOnSelect; } + + //! Print the tree to stdout + void print(); + + //! Remove the entry identified by path \b fullpath from the tree + /*! \return the unique id of the removed entry, or \c 0 if no matching entry was found */ + unsigned int remove( const char *fullpath ); + + //! Remove entry \b name in path \b path from the tree + /*! \return the unique id of the removed entry, or \c 0 if no matching entry was found */ + unsigned int remove( const char *path, const char *name ); + + //! Remove the entry identified by unique id \b id from the tree + /*! \return the unique id of the removed entry, or \c 0 if no matching entry was found */ + unsigned int remove( unsigned int id ); + + //! Remove the entry containing the widget \b w from the tree. Note that the widget is automatically destroyed + /*! \return the unique id of the removed entry, or \c 0 if no matching entry was found */ + unsigned int remove( Fl_Widget *w ); + + //! Remove Node \b n from the tree + /*! \return the id of \b n on successful removal, or \c 0 if \b n is not in the tree */ + inline unsigned int remove( Node* n ) + { if( !n ) return 0; else return remove( n->id() ); } + + //! Override of Fl_Widget::resize + void resize( int X, int Y, int W, int H ); + + //! Convenience routine to set the root label color. See Flu_Tree_Browser::Node::label_color() + inline void root_color( Fl_Color c ) + { get_root()->label_color( c ); } + + //! Convenience routine to set the root label color. See Flu_Tree_Browser::Node::label_color() + inline Fl_Color root_color() + { return get_root()->label_color(); } + + //! Convenience routine to set the root label font. See Flu_Tree_Browser::Node::label_font() + inline void root_font( Fl_Font f ) + { get_root()->label_font( f ); } + + //! Convenience routine to set the root label font. See Flu_Tree_Browser::Node::label_font() + inline Fl_Font root_font() + { return get_root()->label_font(); } + + //! Convenience routine to set the root label size. See Flu_Tree_Browser::Node::label_size() + inline void root_size( unsigned char s ) + { get_root()->label_size( s ); } + + //! Convenience routine to set the root label size. See Flu_Tree_Browser::Node::label_size() + inline unsigned char root_size() + { return get_root()->label_size(); } + + //! Select all entries in the tree + inline void select_all() + { root.select_all(); } + + //! Get the color to use when hilighting selected entries + inline Fl_Color selection_color() const + { return rdata.defSelectionColor; } + + //! Set the color to use when hilighting selected entries. Default is FL_SELECTION_COLOR + inline void selection_color( Fl_Color c ) + { rdata.defSelectionColor = c; } + + //! Set how selection is affected when the mouse is dragged. This can be one of FLU_DRAG_IGNORE, FLU_DRAG_TO_SELECT, FLU_DRAG_TO_MOVE. Default is FLU_DRAG_TO_SELECT. + inline void selection_drag_mode( int m ) + { rdata.selectionDragMode = m; } + + //! Get how selection is affected when the mouse is dragged + inline int selection_drag_mode() const + { return rdata.selectionDragMode; } + + //! Set whether the hilighted node is always selected. Default is \c false + inline void selection_follows_hilight( bool b ) + { rdata.selectionFollowsHilight = b; if( b && rdata.hilighted ) rdata.hilighted->select(true); } + + //! Get whether the hilighted node is always selected + inline bool selection_follows_hilight() + { return rdata.selectionFollowsHilight; } + + //! Set how individual entries are selected using the mouse. This can be one of FLU_NO_SELECT, FLU_SINGLE_SELECT, FLU_MULTI_SELECT. Default is FLU_MULTI_SELECT + inline void selection_mode( int m ) + { rdata.selectionMode = m; root.unselect_all(); } + + //! Get how individual entries are selected using the mouse + inline int selection_mode() const + { return rdata.selectionMode; } + + //! If selection_mode() is \c FLU_SINGLE_SELECT, then whichever node is under the mouse will always be selected, with all others unselected. Default is \c false + inline void select_under_mouse( bool b ) + { rdata.selectUnderMouse = b; } + + //! If selection_mode() is \c FLU_SINGLE_SELECT, then whichever node is under the mouse will always be selected, with all others unselected. Default is \c false + inline bool select_under_mouse() const + { return rdata.selectUnderMouse; } + + //! Calling this will cause any newly added branches to use the default branch icon + void set_default_branch_icons(); + + //! Set which node is hilighted and ready to be selected or unselected. This also scrolls the browser so \b n is visible. + void set_hilighted( Node* n ); + + //! Set the title of the root of the tree to \b label. If \b w is not \c NULL then that widget is the entry and its label is visible depending on the value of \b showLabel. Note that the widget is destroyed by the tree/node on clear() or the destructor + /*! The root icons, color, font and size are set to the current branch icons and text color, font and size */ + Node* set_root( const char *label, Fl_Widget *w = 0, bool showLabel = true ); + + //! Set the colors to use for shading every other entry. Default is FL_WHITE, FL_WHITE + inline void shaded_entry_colors( Fl_Color even, Fl_Color odd ) + { rdata.shadedColors[0] = even; rdata.shadedColors[1] = odd; } + + //! Set whether branch entries are visible. Default is \c true + inline void show_branches( bool b ) + { rdata.showBranches = b; rdata.forceResize = true; } + + //! Get whether branch entries are visible + inline bool show_branches() const + { return rdata.showBranches; } + + //! Set whether the connectors between entries are visible. Default is \c true + inline void show_connectors( bool b ) + { rdata.showConnectors = b; } + + //! Get whether the connectors between entries are visible + inline bool show_connectors() const + { return rdata.showConnectors; } + + //! Set whether the root branch (i.e. the name of the tree) is visible. Default is \c true + inline void show_root( bool b ) + { rdata.showRoot = b; rdata.forceResize = true; } + + //! Get whether the root branch (i.e. the name of the tree) is visible + inline bool show_root() const + { return rdata.showRoot; } + + //! Set whether leaf entries are visible. Default is \c true + inline void show_leaves( bool b ) + { rdata.showLeaves = b; rdata.forceResize = true; } + + //! Get whether leaf entries are visible + inline bool show_leaves() const + { return rdata.showLeaves; } + + //! Sort the tree according to insertion_mode() + inline void sort() + { root.sort(); } + + //! Unselect all entries in the tree + inline void unselect_all() + { root.unselect_all(); } + + inline static void use_FLU_WIDGET_CALLBACK( bool b ) + { USE_FLU_WIDGET_CALLBACK = b; } + + //! Set the vertical gap between tree entries. Default is 0 + inline void vertical_gap( int g ) + { rdata.vGap = g; rdata.forceResize = true; } + + //! Get the vertical gap between tree entries + inline int vertical_gap() const + { return rdata.vGap; } + + //! Override of Fl_Widget::when. Currently only FL_WHEN_NEVER, FL_WHEN_CHANGED, and FL_WHEN_NOT_CHANGED are supported. Default value is FL_WHEN_CHANGED + /*! When the callback occurs, you can use callback_reason() to determine exactly what cause the callback and callback_node() + to get the node that was affected. */ + //inline void when( unsigned int w ) + //{ rdata.when = w; } + + //! Override of Fl_Widget::when + //inline unsigned int when() const + //{ return rdata.when; } + + //! Set the gap between the widget and the icon that precedes it. Default is 2 + inline void widget_gap( int g ) + { rdata.wGap = g; rdata.forceResize = true; } + + //! Get the gap between the widget and the icon that precedes it + inline int widget_gap() const + { return rdata.wGap; } + + protected: + + class RData; + + //! Internal class holding an (alphabetically) ordered list of nodes + class FLU_EXPORT NodeList + { + public: + NodeList(); + ~NodeList(); + void add( Node* n, int position = -1 ); + inline Node* child( int n ) const { return _nodes[n]; } + int erase( Node* n ); + int erase( const char* n ); + void erase( int n ); + void clear(); + int findNum( const char *n ); // find the number of nodes in the list with name n + Node* find( const char* n, int which = 1 ); // find the which'th node in the list with name n + inline int size() const { return _nNodes; }; + void sort(); + static bool move( Node* n1, int where, Node* n2 ); + private: + friend class Node; + static int compareNodes( const void *arg1, const void* arg2 ); + static int reverseCompareNodes( const void *arg1, const void* arg2 ); + bool search( Node *n, int &index ); + bool search( const char *n, int &index ); + bool linSearch( Node *n, int &index ); + bool linSearch( const char *n, int &index ); + bool binSearch( Node *n, int &index ); + bool binSearch( const char *n, int &index ); + Node **_nodes; + int _nNodes, _size; + }; + + //! Internal class holding a stack of integers + class FLU_EXPORT IntStack + { + public: + IntStack(); + IntStack( const IntStack& s ); + ~IntStack(); + void push( int i ); + int pop(); + void clear(); + inline int operator [](int i) { return _list[i]; } + inline int size() { return _size; } + IntStack& operator =( const IntStack& s ); + private: + int *_list; + int _size, _bufferSize; + }; + + public: + enum { MOVE_BEFORE, MOVE_INSIDE, MOVE_AFTER }; // where to move a dragged node? + protected: + + //! Recursive data structure passed down through the node tree + class FLU_EXPORT RData { + public: + // volatile objects (from the perspective of each node during a recursive descent) + int x, y, totalW, totalH; + bool first, last, dragging, shiftSelect, shiftSelectAll, visibilityChanged, selectionFollowsHilight; + Node *hilighted, /**lastHilighted, */ *previous, *grabbed, *dragNode, *animatedNode; + int delta, shadedIndex, counter, searchIndex, branchIconW, dragPos, dragWhere; + Fl_Color lineColor, bgColor, selectionColor; + bool forceResize; // force the browser to resize on the next draw (which forces a recalculation of the tree layout) + unsigned int nextId; // monotonically increasing id of each entry + FluSimpleString path; // used to construct the full path during a findPath() operation + IntStack branchConnectors; + + // static objects (from the perspective of each node during a recursive descent) + int insertionMode; + Fl_Image *defaultCollapseIcons[2], *defaultBranchIcons[2]; + Fl_Image *collapseIcons[2], *branchIcons[2], *leafIcon; + int hGap, vGap, wGap; + int lineStyle, lineWidth, selectionMode, selectionDragMode; + bool showRoot, showConnectors, showLeaves, showBranches, openOnSelect, + allowDuplication, animate, animating, singleBranchOpen, moveOnlySameGroup, justOpenedClosed, + isMoveValid, doubleClickToOpen, dnd, allBranchesAlwaysOpen, autoBranches, openWOChildren, + selectUnderMouse; + float collapseTime, fps, animationDelta, animationOffset; + Fl_Color defLineColor, defSelectionColor, shadedColors[2]; + Fl_Color defLeafColor, defBranchColor; + Fl_Font defLeafFont, defBranchFont; + int defLeafSize, defBranchSize; + int browserX, browserY, browserW, browserH; + Node *root; + Flu_Tree_Browser *tree; + unsigned int cbReason; + Node *cbNode, *lastOpenBranch; + }; + + public: + +#ifdef USE_FLU_DND + //! This class can be subclassed to make an object which can be dropped on a tree to make a new node + /*! When the object is dropped, the tree will name the object according to what the function + \b name() returns */ + class FLU_EXPORT DND_Object : public Flu_DND + { + public: + + //! Default constructor + DND_Object(); + + //! The descendent should call this when the user grabs the object to start dragging it (e.g. on the FL_PUSH event) + inline void grab() + { dnd_grab( this, "DND_Object" ); } + + //! Descendents MUST implement this function to return the name of the dropped object + virtual const char* name() = 0; + + }; +#endif + + //! This class holds a single entry in the tree + class FLU_EXPORT Node + { + + protected: + + enum { ADD, REMOVE, FIND, FIND_NUMBER, GET_SELECTED }; // parameters for modify() + enum { DRAW, MEASURE, MEASURE_THIS_OPEN, HANDLE, COUNT_SELECTED }; // parameters for recurse() + + // flags + enum { SELECTED = 0x0001, COLLAPSED = 0x0002, LEAF = 0x0004, SHOW_LABEL = 0x0008, + ACTIVE = 0x0010, EXPAND_TO_WIDTH = 0x0020, ALWAYS_OPEN = 0x0040, + SOME_VISIBLE_CHILDREN = 0x0080, MOVABLE = 0x0100, DROPPABLE = 0x0200, + AUTO_LABEL_COLOR = 0x0400, AUTO_COLOR = 0x0800, AUTO_LABEL = 0x1000, + SWAP_LABEL_AND_WIDGET = 0x2000, ICON_AT_END = 0x4000 }; + + // flag manipulator functions + inline bool CHECK( unsigned short flag ) const { return flags & flag; } + inline void SET( unsigned short flag ) { flags |= flag; } + inline void SET( unsigned short flag, bool b ) { if(b) SET(flag); else CLEAR(flag); } + inline void CLEAR( unsigned short flag ) { flags &= ~flag; } + + public: + + //! Is this node currently active? + inline bool active() const + { return CHECK(ACTIVE); } + + //! Activate or deactivate this node + void active( bool b ); + + //! Activate this node + inline void activate() + { active(true); } + + //! Add the entry specified by \b fullpath to this node. If \b w is not \c NULL then that widget is the entry and the label (as specified in \b fullPath) is visible depending on the value of \b showLabel. Note that the widget is destroyed by the tree/node on clear() or the destructor + /*! \return a pointer to the Node of the added entry or NULL if the add failed */ + inline Node* add( const char* fullpath, Fl_Widget *w = 0, bool showLabel = true ) + { return( modify( fullpath, ADD, tree->rdata, w, showLabel ) ); } + + //! Convenience function that is the same as add() except it appends a '/' to \b fullpath if one does not exist + Node* add_branch( const char* fullpath, Fl_Widget *w = 0, bool showLabel = true ); + + //! Convenience function that is the same as add() except it removes any '/' at the end of \b fullpath + Node* add_leaf( const char* fullpath, Fl_Widget *w = 0, bool showLabel = true ); + + //! Convenience function that is the same as add() except \b path and \b name are concatenated (with a '/' added if necessary) to create the full path + Node* add( const char* path, const char* name, Fl_Widget *w = 0, bool showLabel = true ); + + //! Convenience function that is the same as add_branch() except \b path and \b name are concatenated (with a '/' added if necessary) to create the full path + Node* add_branch( const char* path, const char* name, Fl_Widget *w = 0, bool showLabel = true ); + + //! Convenience function that is the same as add_leaf() except \b path and \b name are concatenated (with a '/' added if necessary) to create the full path + Node* add_leaf( const char* path, const char* name, Fl_Widget *w = 0, bool showLabel = true ); + + //! Set whether a branch node is always open (only for branch nodes). Default is \c false + inline void always_open( bool b ) + { if( b ) open(true); SET(ALWAYS_OPEN,b); tree->rdata.forceResize = true; } + + //! Get whether this branch node is always open (only for branches) + inline bool always_open() const + { return CHECK(ALWAYS_OPEN); } + + //! Set whether the color of the widget in this node tracks the color of the node itself. This is useful for changing the color of the widget when the node is selected. Default is \c false + inline void auto_color( bool b ) + { SET(AUTO_COLOR,b); } + + //! Get whether the color of the widget in this node tracks the color of the node itself + inline bool auto_color() + { return CHECK(AUTO_COLOR); } + + //! Set whether the label of the widget in this node tracks the label of the node itself. This is useful for when the label of the node changes and you want the widget to reflect the change + inline void auto_label( bool b ) + { SET(AUTO_LABEL,b); } + + //! Set whether the label of the widget in this node tracks the label of the node itself. + inline bool auto_label() + { return CHECK(AUTO_LABEL); } + + //! Set whether the label color of the widget in this node tracks the label color of the node itself. This is useful for changing the label color of the widget when the node is selected. Default is \c false + inline void auto_label_color( bool b ) + { SET(AUTO_LABEL_COLOR,b); } + + //! Get whether the label color of the widget in this node tracks the label color of the node itself + inline bool auto_label_color() + { return CHECK(AUTO_LABEL_COLOR); } + + //! Set the branch icons to use for this node (only for branch nodes) + void branch_icons( Fl_Image *closed, Fl_Image *open ); + + //! Convenience routine to set both branch icons at once + inline void branch_icon( Fl_Image *icon ) + { branch_icons( icon, icon ); } + + //! \return child \b i of this node (base 0). Bounds checking is performed and NULL is returned if the child cannot be found + Node* child( int i ) const; + + //! \return the number of child nodes beneath this node + inline int children() const + { return _children.size(); } + + //! Clear all child entries from this node (does not change the entry of this node) + void clear(); + + //! Close this node (only for branches) + inline void close() + { open( false ); } + + //! Is this node closed? (only for branches) + inline bool closed() + { return !open(); } + + //! Set the collapse icons to use for this node (only for branch nodes) + /*! \note if a NULL icon is passed, the default plus/minus icons are chosen */ + void collapse_icons( Fl_Image *closed, Fl_Image *open ); + + //! Deactivate this node + inline void deactivate() + { active(false); } + + //! Get the depth of this node in the tree + unsigned short depth() const; + + //! Do the tree browser callback. \b reason should be one of FLU_HILIGHTED, FLU_UNHILIGHTED, FLU_SELECTED, FLU_UNSELECTED, FLU_OPENED, FLU_CLOSED, FLU_DOUBLE_CLICK, FLU_WIDGET_CALLBACK + void do_callback( int reason ); + + //! Set whether this node can receive new nodes as a result of dragging-and-dropping (only for branch nodes). Default is \c true + inline void droppable( bool b ) + { SET(DROPPABLE,b); } + + //! Get whether this node can receive new nodes as a result of dragging-and-dropping (only for branch nodes). + inline bool droppable() + { return CHECK(DROPPABLE); } + + //! Set whether to force the size of the embedded widget to expand to fill the visible width of the browser. Default is \c false + inline void expand_to_width( bool b ) + { SET(EXPAND_TO_WIDTH,b); tree->rdata.forceResize = true; } + + //! Get whether to force the size of the embedded widget to expand to fill the visible width of the browser + inline bool expand_to_width() const + { return CHECK(EXPAND_TO_WIDTH); } + + //! Find the entry identified by \b fullpath + /*! \return a pointer to the Node of the found entry, or NULL if no matching entry was found */ + inline Node* find( const char *fullpath ) + { return( modify( fullpath, FIND, tree->rdata ) ); } + + //! Find the entry identified by unique id \b id + /*! \return a pointer to the Node of the found entry, or NULL if no matching entry was found */ + Node* find( unsigned int id ); + + //! Find the entry containing the widget \b w + /*! \return a pointer to the Node of the found entry, or NULL if no matching entry was found */ + Node* find( Fl_Widget *w ); + + //! Search for Node \b n + /*! \return a pointer to \b n if it is found, or NULL if it is not present */ + inline Node* find( Node *n ) + { if( !n ) return NULL; else return find( n->id() ); } + + //! \return the full path of this node + /*! \note the returned value is only valid until the next time find_path() is called */ + inline const char* find_path() + { return tree->find_path( this ); } + + //! \return the first node in this hierarchy (i.e. this node) + Node* first(); + + //! \return the first branch encountered in a depth-first traversal (or this node if it is a branch). NULL means there are no branches + Node* first_branch(); + + //! \return the first leaf encountered in a depth-first traversal (or this node if it is a leaf). NULL means there are no leaves + Node* first_leaf(); + + //! Set whether this node draws the label to the left of the widget (\c false, default) or to the right of the widget (\c true) + inline void swap_label_and_widget( bool b ) + { SET(SWAP_LABEL_AND_WIDGET,b); } + + //! Get whether this node draws the label to the left of the widget (\c false, default) or to the right of the widget (\c true) + inline bool swap_label_and_widget() + { return CHECK(SWAP_LABEL_AND_WIDGET); } + + //! \return the selected Node that is at \b index among all selected nodes, or \c NULL if no Node is selected + /*! For example, \c get_selected(1) will return the first selected node. */ + Node* get_selected( int index ); + + //! Set whether the icon for this node is drawn after the label and widget (\c true) or before (\c false, default) (only for leaf nodes) + inline void icon_at_end( bool b ) + { SET(ICON_AT_END,b); } + + //! Get whether the icon for this node is drawn after the label and widget (\c true) or before (\c false, default) (only for leaf nodes) + inline bool icon_at_end() + { return CHECK(ICON_AT_END); } + + //! Get the unique ID of this node + inline unsigned int id() const + { return _id; } + + //! Get the index this node is (as a child) in its parent's list + /*! \return -1 if this node has no parent, else its index in its parent's list of children */ + int index() const; + + //! Insert a new node at position \b pos + Node* insert( const char* fullpath, int pos ); + + //! Insert a new branch at position \b pos + Node* insert_branch( const char* fullpath, int pos ); + + //! Insert a new leaf at position \b pos + Node* insert_leaf( const char* fullpath, int pos ); + + //! Is node \b n an ancestor of this node? + bool is_ancestor( Node* n ); + + //! Is this node a branch node? + bool is_branch() const; + + //! Is node \b n a descendent of this node? + bool is_descendent( Node* n ); + + //! Is this node a leaf node? + bool is_leaf() const; + + //! Is this node the root node? + inline bool is_root() const + { return( _parent == 0 ); } + + //! Set the label for this node. Note that setting the label may invalidate a sorted tree. Fix by calling Flu_Tree_Browser::sort() + inline void label( const char *l ) + { text = l; tree->redraw(); } + + //! Get the label for this node + inline const char* label() const + { return text.c_str(); } + + //! Set the label color for this node + inline void label_color( Fl_Color c ) + { textColor = c; } + + //! Get the label color for this node + inline Fl_Color label_color() const + { return textColor; } + + //! Set the label font for this node + inline void label_font( Fl_Font f ) + { textFont = f; tree->rdata.forceResize = true; } + + //! Get the label font for this node + inline Fl_Font label_font() const + { return textFont; } + + //! Set the label size for this node + inline void label_size( unsigned char s ) + { textSize = s; tree->rdata.forceResize = true; } + + //! Get the label size for this node + inline unsigned char label_size() const + { return textSize; } + + //! Is the label for this node visible? + inline bool label_visible() const + { return CHECK(SHOW_LABEL); } + + //! Set whether the label for this node is visible + inline void label_visible( bool b ) + { SET(SHOW_LABEL,b); tree->rdata.forceResize = true; } + + //! \return the last node in this hierarchy + Node* last(); + + //! \return the last branch encountered in a depth-first traversal (or this node if it is a branch and has no children). NULL means there are no branches + Node* last_branch(); + + //! \return the last leaf encountered in a depth-first traversal (or this node if it is a leaf). NULL means there are no leaves + Node* last_leaf(); + + //! Set the leaf icon to use for this node (only for leaf nodes) + void leaf_icon( Fl_Image *icon ); + + //! Set whether this node can be moved (either via move() or by dragging with the mouse). Default is \c true + inline void movable( bool b ) + { SET(MOVABLE,b); } + + //! Get whether this node can be moved (either via move() or by dragging with the mouse) + inline bool movable() + { return CHECK(MOVABLE); } + + //! Move this node to absolute position \b pos within its parent + /*! \return \c true if the move was successful, or \c false if the move is not allowed + */ + bool move( int pos ); + + //! Move this node to a position before, after, or inside node \b n + /*! \param where can be one of MOVE_BEFORE, MOVE_AFTER, or MOVE_INSIDE + \return \c true if the move was successful, or \c false if the move is not allowed + */ + inline bool move( int where, Node* n ) + { return( move( this, where, n ) ); } + + //! Move node \b n1 to a position before, after, or inside node \b n2 + /*! \param where can be one of MOVE_BEFORE, MOVE_AFTER, or MOVE_INSIDE + \return \c true if the move was successful, or \c false if the move is not allowed + */ + static bool move( Node* n1, int where, Node* n2 ); + + //! \return the next node (after this node) in this hierarchy (depth-first traversal) + Node* next(); + + //! \return the next branch (after this node) encountered in a depth-first traversal. NULL means there are no more branches + Node* next_branch(); + + //! \return the next leaf (after this node) encountered in a depth-first traversal. NULL means there are no more leaves + Node* next_leaf(); + + //! \return the next sibling (after this node) encountered in a depth-first traversal. NULL means this node is the last child w.r.t. its parent + Node* next_sibling(); + + //! \return the number of selected entries + int num_selected(); + + //! Is this node currently open? (only for branch nodes) + inline bool open() const + { return( !CHECK(COLLAPSED) || tree->rdata.allBranchesAlwaysOpen ); } + + //! Open or close this node (only for branch nodes) + void open( bool b ); + + //! Get the node that is the parent of this node, or NULL if there is no parent + inline Node* parent() const + { return _parent; } + + //! \return the previous node (before this node) in this hierarchy (depth-first traversal) + Node* previous(); + + //! \return the previous branch (before this node) encountered in a depth-first traversal. NULL means there are no more branches + Node* previous_branch(); + + //! \return the previous leaf (before this node) encountered in a depth-first traversal. NULL means there are no more leaves + Node* previous_leaf(); + + //! \return the previous sibling (before this node) encountered in a depth-first traversal. NULL means this node is the first child w.r.t. its parent + Node* previous_sibling(); + + //! Print this node and its children to stdout + void print( int spaces = 0 ); + + //! Remove the entry identified by path \b fullpath from this node + /*! \return the unique id of the removed entry, or \c 0 if no matching entry was found */ + inline unsigned int remove( const char *fullpath ) + { return( (unsigned int)modify( fullpath, REMOVE, tree->rdata ) ); } + + //! Remove the entry identified by unique id \b id from this node + /*! \return the unique id of the removed entry, or \c 0 if no matching entry was found */ + unsigned int remove( unsigned int id ); + + //! Remove the node containing the widget \b w from this node. Note that the widget is automatically destroyed + /*! \return the unique id of the removed entry, or \c 0 if no matching entry was found */ + unsigned int remove( Fl_Widget *w ); + + //! Remove Node \b n + /*! \return the id of \b n on successful removal, or \c 0 if \b n is present */ + inline unsigned int remove( Node* n ) + { if( !n ) return 0; else return remove( n->id() ); } + + //! Select this entry and all child entries + void select_all(); + + //! Is this node currently selected? + inline bool selected() const + { return CHECK(SELECTED); } + + //! Select or unselect this node + void select( bool b ); + + //! Select only this node + inline void select_only() + { tree->unselect_all(); select(true); } + + //! Sort this node's children according to Flu_Tree_Browser::insertion_mode() + inline void sort_children() + { sort(); } + + //! Swap this node and node \b n in their respective trees + /*! \return \c true if the swap was successful, else \c false */ + inline bool swap( Node* n ) + { return swap( this, n ); } + + //! Swap nodes \b n1 and \b n2 in their respective trees + /*! \return \c true if the swap was successful, else \c false */ + static bool swap( Node* n1, Node* n2 ); + + //! Unselect this entry and all child entries (except for Node \b except ) + void unselect_all( Node* except = NULL ); + + //! Get the user-specific data stored in this node + inline void* user_data() + { return userData; } + + //! Set the user-specific data stored in this node + inline void user_data( void *d ) + { userData = d; } + + //! Get the widget in this node, or NULL if there is no widget. Note that the widget is destroyed by the tree/node on clear() or the destructor + inline Fl_Widget* widget() const + { return( _widget ? _widget->w : NULL ); } + + //! Set the widget in this node. Note that the widget is destroyed by the tree/node on clear() or the destructor + void widget( Fl_Widget *w ); + + protected: + + friend class Flu_Tree_Browser; + friend class NodeList; + + // Root node constructor + Node( const char *lbl = 0 ); + + // Non-root constructor + Node( bool l, const char* n, Node *p, RData &rdata, Fl_Widget *w, bool showLabel ); + + ~Node(); + + // add/remove/find/get + Node* modify( const char* path, int what, RData &rdata, Fl_Widget *w = 0, bool showLabel = true ); + + void initType(); + + void sort(); + + void determineVisibility( bool parentVisible = true ); + + static bool isMoveValid( Node* &n1, int &where, Node* &n2 ); + + // handle/draw/measure/count + int recurse( RData &rdata, int type, int event = 0 ); + + void draw( RData &rdata, bool measure ); + + // recursively finding the full path of the node identified by id + bool findPath( unsigned int id, RData &rdata ); + + // recursively finding the full path of the node containing w + bool findPath( Fl_Widget *w, RData &rdata ); + + class FLU_EXPORT WidgetInfo + { + public: + Fl_Widget *w; + int defaultW; // the initial width of the widget + void (*CB)(Fl_Widget*,void*); + void *CBData; + }; + + unsigned int _id; // the unique id of this node + unsigned short flags; + NodeList _children; + Node *_parent; + Flu_Tree_Browser *tree; + FluSimpleString text; + WidgetInfo *_widget; // memory overhead deferred to WidgetInfo. present only if widget is + Fl_Group *_group; + void *userData; + int totalChildH; // needed for animation + Fl_Image *cIcon[2], *bIcon[2], *lIcon; + Fl_Color textColor; + Fl_Font textFont; + unsigned char textSize; // the font size of the entry label text + unsigned short textW, textH; // how big the entry label actually is (stored within the node for performance reasons) + int currentY; // needed for animation + unsigned short currentH; + + inline static void _widgetCB( Fl_Widget* w, void* arg ) + { ((Node*)arg)->widgetCB(); } + void widgetCB(); + }; + + protected: + + inline static void _scrollCB( Fl_Widget* w, void* arg ) + { ((Flu_Tree_Browser*)arg)->redraw(); } + + inline static void _timerRedrawCB( void *arg ) + { ((Flu_Tree_Browser*)arg)->timerRedrawCB(); } + void timerRedrawCB(); + + inline static void _timerScrollCB( void *arg ) + { ((Flu_Tree_Browser*)arg)->timerScrollCB(); } + void timerScrollCB(); + + void on_dnd_leave(); + + void on_dnd_release(); + + bool on_dnd_drag( int X, int Y ); + + void on_dnd_drop( const Flu_DND_Event *e ); + + /* override of Fl_Double_Window::draw() */ + void draw(); + + Fl_Group *scrollBox; + Fl_Scrollbar *scrollH, *scrollV; + Fl_Group *_box; + Node root; + RData rdata; + //int lastEvent; + float autoScrollX, autoScrollY; + bool scrolledTimerOn; + +}; + +#endif diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Wrap_Group.h b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Wrap_Group.h new file mode 100644 index 0000000..4adef76 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Flu_Wrap_Group.h @@ -0,0 +1,195 @@ +// $Id: Flu_Wrap_Group.h,v 1.10 2004/01/27 21:44:21 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#ifndef _FLU_WRAP_GROUP_H +#define _FLU_WRAP_GROUP_H + +/* fltk includes */ +#include +#include +#include +#include + +#include "FLU/Flu_Enumerations.h" + +//! This class provides an alternative to Fl_Group that automatically arranges the children either left to right and top to bottom (for type() == \c FL_VERTICAL), or top to bottom and left to right (for type() == \c FL_HORIZONTAL), within the available size of the group, with a scrollbar turning on if they don't all fit +/*! This class is a group with a scrollbar and an \b Fl_Group inside (both publicly exposed). The \b Fl_Group + contains the actual child widgets of this group. + + Most of the \b Fl_Group member functions are reimplemented here in a pass-through fashion to the + internal group. This means that casual use of a descendent instance will be almost exactly the same + as for a regular \b Fl_Group, with any additional access provided directly through member \b group. + + The goal of this class is to provide a group that dynamically and evenly distributes its children within + a fixed space, similar to those available in other GUI toolkits. +*/ +class FLU_EXPORT Flu_Wrap_Group : public Fl_Group +{ + + public: + + class Scrollbar : public Fl_Scrollbar + { + public: + Scrollbar( int x, int y, int w, int h, const char *l = 0 ); + int handle( int event ); + }; + + //! Normal FLTK constructor + Flu_Wrap_Group( int x, int y, int w, int h, const char *l = 0 ); + + //! \return the widget that is visibly above \b w in the group, or \c NULL if no such widget exists + Fl_Widget *above( Fl_Widget* w ); + + //! \return the widget that is visibly below \b w in the group, or \c NULL if no such widget exists + Fl_Widget *below( Fl_Widget* w ); + + //! Override of Fl_Group::draw() + void draw(); + + //! \return the widget that is visibly to the left of \b w in the group, or \c NULL if no such widget exists + Fl_Widget *left( Fl_Widget* w ); + + //! \return the widget that is logically after \b w in the groups order, or \c NULL if no such widget exists + Fl_Widget *next( Fl_Widget* w ); + + //! Set the offset for where the first child starts + inline void offset( int x, int y ) + { _offset[0] = x, _offset[1] = y; redraw(); } + + //! \return the x offset for where the first child starts + inline int offset_x() const + { return _offset[0]; } + + //! \return the y offset for where the first child starts + inline int offset_y() const + { return _offset[1]; } + + //! \return the widget that is logically before \b w in the groups order, or \c NULL if no such widget exists + Fl_Widget *previous( Fl_Widget* w ); + + //! Override of Fl_Group::resize() + void resize( int x, int y, int w, int h ); + + //! \return the widget that is visibly to the right of \b w in the group, or \c NULL if no such widget exists + Fl_Widget *right( Fl_Widget* w ); + + //! Scroll the group so that the given widget is shown (usually aligned to the left/top) + void scroll_to( const Fl_Widget *w ); + + //! Scroll the group so that the given widget is shown (usually aligned to the left/top) + inline void scroll_to( const Fl_Widget& w ) + { scroll_to( &w ); } + + //! Scroll the group to the beginning of the list + void scroll_to_beginning(); + + //! Scroll the group to the end of the list + void scroll_to_end(); + + //! Set the spacing between children + inline void spacing( int x, int y ) + { _spacing[0] = x, _spacing[1] = y; redraw(); } + + //! \return the x spacing between children + inline int spacing_x() const + { return _spacing[0]; } + + //! \return the y spacing between children + inline int spacing_y() const + { return _spacing[1]; } + + //! Set the wrap type. Must be either \c FL_VERTICAL (children wrap according to the width, with a vertical scrollbar) or \c FL_HORIZONTAL (children wrap according to the height, with a horizontal scrollbar). Default is \c FL_HORIZONTAL + void type( int t ); + + //! Get the wrap type + inline int type() const + { return _type; } + + /*! \name Pass-through functions for the internal Fl_Group + * These are strictly for convenience. Only the most commonly called functions have been re-implemented. + * You can also explicitly access the group object for more control. + */ + //@{ + + inline Fl_Widget* const* array() const + { return group.array(); } + + inline int find( const Fl_Widget* w ) const + { return group.find( w ); } + + inline int find( const Fl_Widget& w ) const + { return group.find( w ); } + + inline void clear() + { group.clear(); } + + inline Fl_Widget *child(int n) const + { return group.child(n); } + + inline int children() const + { return group.children(); } + + inline void begin() + { group.begin(); } + + inline void end() + { group.end(); Fl_Group::end(); } + + inline void resizable(Fl_Widget *box) + { group.resizable(box); } + + inline void resizable(Fl_Widget &box) + { group.resizable(box); } + + inline Fl_Widget *resizable() const + { return group.resizable(); } + + inline void add( Fl_Widget &w ) + { group.add( w ); } + + inline void add( Fl_Widget *w ) + { group.add( w ); } + + inline void insert( Fl_Widget &w, int n ) + { group.insert( w, n ); } + + inline void insert( Fl_Widget &w, Fl_Widget* beforethis ) + { group.insert( w, beforethis ); } + + inline void remove( Fl_Widget &w ) + { group.remove( w ); } + + inline void add_resizable( Fl_Widget &box ) + { group.add_resizable( box ); } + + //@} + + Scrollbar scrollbar; + Fl_Group group; + + protected: + + inline static void _scrollCB( Fl_Widget*, void *arg ) + { ((Flu_Wrap_Group*)arg)->redraw(); } + + int layout( bool sbVisible, bool doScrollTo, int *measure = 0 ); + + const Fl_Widget *scrollTo; + int _offset[2], _spacing[2], _type; + +}; + +#endif diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU/LICENSE b/mod/maxgui.mod/fltkmaxgui.mod/FLU/LICENSE new file mode 100644 index 0000000..273fc09 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU/LICENSE @@ -0,0 +1,569 @@ +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Jason Bryan, Ohio Supercomputer Center, Ohio State University + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * To contribute, advise, suggest, berate, recommend, criticise, + * or otherwise communicate with me: jbryan@osc.edu + * Ohio Supercomputer Center + * 1224 Kinnear Rd + * Columbus, Ohio 43212 + ***************************************************************/ + + +----------------------------------------------------------------------- + + This library depends on the following GPL free libraries: + FLTK + + This library also uses OpenGL, which is a registered trademark of Silicon + Graphics, Inc. (SGI), and Doxygen, a free HTML page generator for documentation + of C++ classes. + + + This library is hereby distributed under the same LGPL license as FLTK. + Have fun with it! + +----------------------------------------------------------------------- + + FLTK License + December 11, 2001 + +The FLTK library and included programs are provided under the terms +of the GNU Library General Public License (LGPL) with the following +exceptions: + + 1. Modifications to the FLTK configure script, config + header file, and makefiles by themselves to support + a specific platform do not constitute a modified or + derivative work. + + The authors do request that such modifications be + contributed to the FLTK project - send all + contributions to "fltk-bugs@fltk.org". + + 2. Widgets that are subclassed from FLTK widgets do not + constitute a derivative work. + + 3. Static linking of applications and widgets to the + FLTK library does not constitute a derivative work + and does not require the author to provide source + code for the application or widget, use the shared + FLTK libraries, or link their applications or + widgets against a user-supplied version of FLTK. + + If you link the application or widget to a modified + version of FLTK, then the changes to FLTK must be + provided under the terms of the LGPL in sections + 1, 2, and 4. + + 4. You do not have to provide a copy of the FLTK license + with programs that are linked to the FLTK library, nor + do you have to identify the FLTK license in your + program or documentation as required by section 6 + of the LGPL. + + However, programs must still identify their use of FLTK. + The following example statement can be included in user + documentation to satisfy this requirement: + + [program/widget] is based in part on the work of + the FLTK project (http://www.fltk.org). + +----------------------------------------------------------------------- + + GNU LIBRARY GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + [This is the first released version of the library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if +you distribute copies of the library, or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, so that any problems introduced by others will not reflect on +the original authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + + The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + + GNU LIBRARY GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +General Public License (also called "this License"). Each licensee is +addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also compile or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + c) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + d) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the source code distributed need not include anything that is normally +distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Library General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU/Makefile b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Makefile new file mode 100644 index 0000000..044946d --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU/Makefile @@ -0,0 +1,17 @@ +include ../makeinclude + +all: + +install: + @ echo "Installing include files in $(IPREFIX)..." + @ mkdir -p $(IPREFIX) + @ rm -rf $(IPREFIX)/FLU + @ mkdir -p $(IPREFIX)/FLU + @ chmod 755 $(IPREFIX)/FLU + @ cp *.h $(IPREFIX)/FLU + @ chmod 644 $(IPREFIX)/FLU/*.h + +uninstall: + @ echo "Uninstalling include files from $(IPREFIX)..." + @ rm -rf $(IPREFIX)/FLU + diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU/README b/mod/maxgui.mod/fltkmaxgui.mod/FLU/README new file mode 100644 index 0000000..af897b3 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU/README @@ -0,0 +1,13 @@ +*** NOTE FOR COMPILING ON OSX *** +when compiling the examples on OSX, if you did a local build +(i.e. you did not make install fltk or FLU, and specified +--fltk=/path/to/local/fltk as an option to FLU/configure) +fltk-config (used by examples/Makefile) appears to supply an +incompatible flag to g++. To fix this, you must edit +fltk/fltk-config and change the line: +DSOLINK="-Wl,-rpath,${exec_prefix}/lib" +to +DSOLINK="" + +again, this ONLY applies to compiling the examples when you +HAVE NOT installed either fltk or FLU to the system. diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU/flu_export.h b/mod/maxgui.mod/fltkmaxgui.mod/FLU/flu_export.h new file mode 100644 index 0000000..1ae0afe --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU/flu_export.h @@ -0,0 +1,27 @@ +// $Id: flu_export.h,v 1.2 2003/08/20 16:29:44 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + +#ifndef _FLU_EXPORT_H +#define _FLU_EXPORT_H + +#ifdef FLU_DLL + #ifdef FLU_LIBRARY + #define FLU_EXPORT __declspec(dllexport) + #else + #define FLU_EXPORT __declspec(dllimport) + #endif +#else + #define FLU_EXPORT +#endif + +#endif diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU/flu_file_chooser_pixmaps.h b/mod/maxgui.mod/fltkmaxgui.mod/FLU/flu_file_chooser_pixmaps.h new file mode 100644 index 0000000..da7ef69 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU/flu_file_chooser_pixmaps.h @@ -0,0 +1,35 @@ +// $Id: flu_file_chooser_pixmaps.h,v 1.1 2003/12/08 16:25:48 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#ifndef _FLU_FILE_CHOOSER_PIXMAPS_H +#define _FLU_FILE_CHOOSER_PIXMAPS_H + +#include "FLU/flu_export.h" + +FLU_EXPORT extern char* monalisa_xpm[]; +FLU_EXPORT extern char* filedetails_xpm[]; +FLU_EXPORT extern char* filelist_xpm[]; +FLU_EXPORT extern char* filelistwide_xpm[]; +FLU_EXPORT extern char* bighome_xpm[]; +FLU_EXPORT extern char* folder_favorite_xpm[]; +FLU_EXPORT extern char* bigfavorites_xpm[]; +FLU_EXPORT extern char* desktop_xpm[]; +FLU_EXPORT extern char* bigtemporary_xpm[]; +FLU_EXPORT extern char* bigdocuments_xpm[]; +FLU_EXPORT extern char* mini_folder_favorites_xpm[]; +FLU_EXPORT extern char* mini_desktop_xpm[]; +FLU_EXPORT extern char* my_computer_xpm[]; + +#endif diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU/flu_pixmaps.h b/mod/maxgui.mod/fltkmaxgui.mod/FLU/flu_pixmaps.h new file mode 100644 index 0000000..75a5b5a --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU/flu_pixmaps.h @@ -0,0 +1,54 @@ +// $Id: flu_pixmaps.h,v 1.12 2003/12/06 16:52:41 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#ifndef _FLU_PIXMAPS_H +#define _FLU_PIXMAPS_H + +#include "FLU/flu_export.h" + +FLU_EXPORT extern char* plus_xpm[]; +FLU_EXPORT extern char* minus_xpm[]; +FLU_EXPORT extern char* arrow_closed_xpm[]; +FLU_EXPORT extern char* arrow_open_xpm[]; +FLU_EXPORT extern char* bluedot_xpm[]; +FLU_EXPORT extern char* book_xpm[]; +FLU_EXPORT extern char* floppy_drive_xpm[]; +FLU_EXPORT extern char* network_drive_xpm[]; +FLU_EXPORT extern char* ram_drive_xpm[]; +FLU_EXPORT extern char* removable_drive_xpm[]; +FLU_EXPORT extern char* cd_drive_xpm[]; +FLU_EXPORT extern char* computer_xpm[]; +FLU_EXPORT extern char* disk_drive_xpm[]; +FLU_EXPORT extern char* filled_folder_xpm[]; +FLU_EXPORT extern char* folder_closed_xpm[]; +FLU_EXPORT extern char* folder_open_xpm[]; +FLU_EXPORT extern char* folder_up_xpm[]; +FLU_EXPORT extern char* folder_load_xpm[]; +FLU_EXPORT extern char* folder_save_xpm[]; +FLU_EXPORT extern char* big_folder_up_xpm[]; +FLU_EXPORT extern char* big_folder_new_xpm[]; +FLU_EXPORT extern char* greendot_xpm[]; +FLU_EXPORT extern char* purpledot_xpm[]; +FLU_EXPORT extern char* question_book_xpm[]; +FLU_EXPORT extern char* reddot_xpm[]; +FLU_EXPORT extern char* tealdot_xpm[]; +FLU_EXPORT extern char* textdoc_xpm[]; +FLU_EXPORT extern char* yellowdot_xpm[]; +FLU_EXPORT extern char* cdrom_xpm[]; +FLU_EXPORT extern char* trash_xpm[]; +FLU_EXPORT extern char* home_xpm[]; +FLU_EXPORT extern char* reload_xpm[]; + +#endif diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/FluSimpleString.cpp b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/FluSimpleString.cpp new file mode 100644 index 0000000..3f11eb8 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/FluSimpleString.cpp @@ -0,0 +1,146 @@ +// $Id: FluSimpleString.cpp,v 1.8 2003/11/27 01:09:05 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#include "FLU/FluSimpleString.h" + +FluSimpleString :: FluSimpleString() +{ + str = strdup(""); +} + +FluSimpleString :: FluSimpleString( unsigned int len ) +{ + if( len > 0 ) + str = (char*)malloc( len ); + else + str = strdup(""); +} + +FluSimpleString :: FluSimpleString( const char *s ) +{ + str = strdup(""); + *this = s; +} + +FluSimpleString :: FluSimpleString( const FluSimpleString& s ) +{ + str = strdup(""); + *this = s.str; +} + +FluSimpleString :: ~FluSimpleString() +{ + if(str) + free(str); +} + +void FluSimpleString :: copy( const char *s, unsigned int start, unsigned int len ) +{ + if( len == 0 ) return; + if( s == 0 ) return; + if( start+len > strlen(s) ) return; + if(str) free(str); + str = (char*)malloc( len+1 ); + strncpy( str, s+start, len ); + str[len] = '\0'; +} + +int FluSimpleString :: compare( const FluSimpleString &s ) const +{ + return strcmp( str, s.str ); +} + +int FluSimpleString :: casecompare( const FluSimpleString &s ) const +{ + FluSimpleString s1(str), s2(s); + s1.upcase(); + s2.upcase(); + return strcmp( s1.str, s2.str ); +} + +void FluSimpleString :: upcase() +{ + unsigned int l = strlen(str); + for( unsigned int i = 0; i < l; i++ ) + str[i] = toupper( str[i] ); +} + +void FluSimpleString :: downcase() +{ + unsigned int l = strlen(str); + for( unsigned int i = 0; i < l; i++ ) + str[i] = tolower( str[i] ); +} + +int FluSimpleString :: find( char c ) const +{ + const char *i = strchr( str, c ); + if( !i ) + return -1; + else + return i-str; +} + +int FluSimpleString :: rfind( char c ) const +{ + const char *i = strrchr( str, c ); + if( !i ) + return -1; + else + return i-str; +} + +FluSimpleString FluSimpleString :: substr( int pos, int len ) const +{ + if( (pos+len) <= 0 || (pos+len) > size() ) + return FluSimpleString(""); + else + { + char *buf = (char*)malloc( len+1 ); + strncpy( buf, str+pos, len ); + buf[len] = '\0'; + FluSimpleString s = buf; + free( buf ); + return s; + } +} + +FluSimpleString& FluSimpleString :: operator =( const char *s ) +{ + char* tmp; + if(s==0) + tmp = strdup(""); + else + tmp = strdup(s); + if(str) + free(str); + str = tmp; + return *this; +} + +FluSimpleString& FluSimpleString :: operator +=( const char *s ) +{ + if( s==0 ) + s = ""; + char *old = strdup(str); + int lold = strlen(old), ls = strlen(s); + free(str); + str = (char*)malloc( lold + ls + 1 ); + memcpy( str, old, lold ); + memcpy( str+lold, s, ls ); + str[lold+ls] = '\0'; + free(old); + return *this; +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Button.cpp b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Button.cpp new file mode 100644 index 0000000..0a05a96 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Button.cpp @@ -0,0 +1,196 @@ +// $Id: Flu_Button.cpp,v 1.13 2004/05/24 19:01:05 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#include +#include "FLU/Flu_Button.h" + +#include + +// taken explicitly from Fl_Return_Button.cpp +static int flu_return_arrow(int x, int y, int w, int h) +{ + int size = w; if (hcopy(); + inactiveImg->desaturate(); + Fl_Button::deimage( inactiveImg ); + } +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Chat_Buffer.cpp b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Chat_Buffer.cpp new file mode 100644 index 0000000..72c38a1 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Chat_Buffer.cpp @@ -0,0 +1,320 @@ +// $Id: Flu_Chat_Buffer.cpp,v 1.7 2003/08/20 16:29:44 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#include +#include "FLU/Flu_Chat_Buffer.h" +#include +#include +#include + +#define X_OFFSET 5 + +Flu_Chat_Buffer :: Flu_Chat_Buffer( int x, int y, int w, int h, const char *label ) + : Fl_Widget( x, y, w, h, label ) +{ + buffer = NULL; + scrollbar = new Fl_Scrollbar( x+w-22, y+2, 20, h-4 ); + scrollbar->linesize( 1 ); + scrollbar->callback( _scrollbarCB, this ); + + box( FL_DOWN_BOX ); + color( FL_WHITE ); + + setSystemStyle( FL_HELVETICA_ITALIC, FL_BLACK ); + setRemoteHandleStyle( FL_HELVETICA_BOLD, FL_RED ); + setLocalHandleStyle( FL_HELVETICA_BOLD, FL_BLUE ); + setRemoteMessageStyle( FL_HELVETICA, FL_RED ); + setLocalMessageStyle( FL_HELVETICA, FL_BLUE ); + + clear(); +} + +Flu_Chat_Buffer :: ~Flu_Chat_Buffer() +{ + clear( 0 ); +} + +void Flu_Chat_Buffer :: draw() +{ + if( recomputeFootprint ) + _computeMessageFootprint(); + + // draw the background box + draw_box(); + + // resize the scrollbar to be a constant width + scrollbar->resize( x()+w()-22, y()+2, 20, h()-4 ); + scrollbar->redraw(); + + int height = h()-4; + + int line; + if( ( currentLine == 0 ) && ( totalLines == 0 ) ) + return; + + line = currentLine - 1 - scrollbar->value(); + + fl_push_clip( x()+2, y()+2, w()-4, h()-4 ); + while( height >= 0 ) + { + switch( buffer[line].type ) + { + + case 'S': + { + height -= buffer[line].height; + fl_color( systemColor ); + fl_font( systemFont, FL_NORMAL_SIZE ); + fl_draw( buffer[line].message, x()+X_OFFSET, y()+height, + buffer[line].messageW, buffer[line].height, (Fl_Align)(FL_ALIGN_TOP_LEFT | FL_ALIGN_WRAP), NULL, 0 ); + } + break; + + case 'R': + { + height -= buffer[line].height; + fl_color( remoteHandleColor ); + fl_font( remoteHandleFont, FL_NORMAL_SIZE ); + fl_draw( buffer[line].handle, x()+X_OFFSET, y()+height, + buffer[line].handleW, buffer[line].height, (Fl_Align)(FL_ALIGN_TOP_LEFT | FL_ALIGN_WRAP), NULL, 0 ); + fl_color( remoteMessageColor ); + fl_font( remoteMessageFont, FL_NORMAL_SIZE ); + fl_draw( buffer[line].message, x()+X_OFFSET+buffer[line].handleW, y()+height, + buffer[line].messageW, buffer[line].height, (Fl_Align)(FL_ALIGN_TOP_LEFT | FL_ALIGN_WRAP), NULL, 0 ); + } + break; + + case 'L': + { + height -= buffer[line].height; + fl_color( localHandleColor ); + fl_font( localHandleFont, FL_NORMAL_SIZE ); + fl_draw( buffer[line].handle, x()+X_OFFSET, y()+height, + buffer[line].handleW, buffer[line].height, (Fl_Align)(FL_ALIGN_TOP_LEFT | FL_ALIGN_WRAP), NULL, 0 ); + fl_color( localMessageColor ); + fl_font( localMessageFont, FL_NORMAL_SIZE ); + fl_draw( buffer[line].message, x()+X_OFFSET+buffer[line].handleW, y()+height, + buffer[line].messageW, buffer[line].height, (Fl_Align)(FL_ALIGN_TOP_LEFT | FL_ALIGN_WRAP), NULL, 0 ); + } + break; + + } + + if( ( line == 0 ) && ( totalLines < maxLines ) ) + break; + + if( line == 0 ) + line = totalLines - 1; + else + line--; + } + fl_pop_clip(); +} + +void Flu_Chat_Buffer :: scrollbarCB() +{ + redraw(); +} + +void Flu_Chat_Buffer :: _addMessage( char type, char *handle, char *msg ) +{ + buffer[currentLine].type = type; + buffer[currentLine].handle = handle; + buffer[currentLine].message = msg; + + // increment the current line, and wrap to the beginning of the buffer + // if necessary + currentLine = (currentLine+1) % maxLines; + + // increment the total lines (no more than maxLines) + totalLines = ( totalLines < maxLines ) ? totalLines+1 : maxLines; + + recomputeFootprint = true; + + redraw(); +} + +void Flu_Chat_Buffer :: addSystemMessage( const char *msg ) +{ + if( !buffer || !msg ) + return; + if( strlen( msg ) == 0 ) + return; + + _addMessage( 'S', NULL, strdup(msg) ); +} + +void Flu_Chat_Buffer :: addRemoteMessage( const char *handle, const char *msg ) +{ + if( !buffer || !handle || !msg ) + return; + if( ( strlen( handle ) == 0 ) || ( strlen( msg ) == 0 ) ) + return; + + _addMessage( 'R', strdup(handle), strdup(msg) ); +} + +void Flu_Chat_Buffer :: addLocalMessage( const char *handle, const char *msg ) +{ + if( !buffer || !handle || !msg ) + return; + if( ( strlen( handle ) == 0 ) || ( strlen( msg ) == 0 ) ) + return; + + _addMessage( 'L', strdup(handle), strdup(msg) ); +} + +void Flu_Chat_Buffer :: clear( int maximumLines ) +{ + recomputeFootprint = true; + + if( buffer ) + { + for( int i = 0; i < maxLines; i++ ) + { + if( buffer[i].handle ) + free( buffer[i].handle ); + if( buffer[i].message ) + free( buffer[i].message ); + } + free( buffer ); + buffer = NULL; + } + + maxLines = maximumLines; + if( maxLines == 0 ) + return; + + buffer = (MessageInfo*)malloc( maxLines * sizeof(MessageInfo) ); + for( int i = 0; i < maxLines; i++ ) + { + buffer[i].handle = buffer[i].message = NULL; + buffer[i].type = 0; // empty + } + totalLines = currentLine = 0; +} + +void Flu_Chat_Buffer :: _computeMessageFootprint() +{ + recomputeFootprint = false; + + // restrict the width calculation to account for the scrollbar + int width = w() - scrollbar->w() - X_OFFSET; + int linesPastHeight = 0; + int totalHeight = 0; + for( int i = 0; i < totalLines; i++ ) + { + switch( buffer[i].type ) + { + + case 'S': + { + int tw = width, th; + + // set the font and color for system messages + fl_color( systemColor ); + fl_font( systemFont, FL_NORMAL_SIZE ); + + // measure how big the message is + fl_measure( buffer[i].message, tw, th ); + buffer[i].messageW = tw; + buffer[i].height = th; + + totalHeight += buffer[i].height; + if( totalHeight > h() ) + linesPastHeight++; + } + break; + + case 'R': + { + int tw = width, hh, mh; + + // set the font and color for remote handles + fl_color( remoteHandleColor ); + fl_font( remoteHandleFont, FL_NORMAL_SIZE ); + + // measure how big the handle is + fl_measure( buffer[i].handle, tw, hh ); + buffer[i].handleW = tw; + + // set the font and color for remote messages, and adjust the width so the message + // is aligned with the end of the handle + fl_color( remoteMessageColor ); + fl_font( remoteMessageFont, FL_NORMAL_SIZE ); + tw = width - tw; + + // measure how big the message is + fl_measure( buffer[i].message, tw, mh ); + buffer[i].messageW = tw; + + // increase total height by max of handle height and message height + buffer[i].height = ( mh > hh ) ? mh : hh; + totalHeight += buffer[i].height; + if( totalHeight > h() ) + linesPastHeight++; + } + break; + + case 'L': + { + int tw = width, hh, mh; + + // set the font and color for local handles + fl_color( localHandleColor ); + fl_font( localHandleFont, FL_NORMAL_SIZE ); + + // measure how big the handle is + fl_measure( buffer[i].handle, tw, hh ); + buffer[i].handleW = tw; + + // set the font and color for local messages, and adjust the width so the message + // is aligned with the end of the handle + fl_color( localMessageColor ); + fl_font( localMessageFont, FL_NORMAL_SIZE ); + tw = width - tw; + + // measure how big the message is + fl_measure( buffer[i].message, tw, mh ); + buffer[i].messageW = tw; + + // increase total height by max of handle height and message height + buffer[i].height = ( mh > hh ) ? mh : hh; + totalHeight += buffer[i].height; + if( totalHeight > h() ) + linesPastHeight++; + } + break; + + } + + } + + scrollbar->range( linesPastHeight, 0 ); + float size = float(h()) / float(totalHeight); + if( size > 1.0f ) + size = 1.0f; + if( size < 0.08f ) + size = 0.08f; + scrollbar->slider_size( size ); + + redraw(); +} + +void Flu_Chat_Buffer :: resize( int x, int y, int w, int h ) +{ + Fl_Widget::resize( x, y, w, h ); + recomputeFootprint = true; +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Choice_Group.cpp b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Choice_Group.cpp new file mode 100644 index 0000000..042ac99 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Choice_Group.cpp @@ -0,0 +1,142 @@ +// $Id: Flu_Choice_Group.cpp,v 1.18 2004/06/17 14:16:42 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#include "FLU/Flu_Choice_Group.h" +#include + +#define MAX( x, y ) ( (x)>(y) ? (x) : (y) ) +#define MIN( x, y ) ( (x)<(y) ? (x) : (y) ) + +Flu_Choice_Group :: Flu_Choice_Group( int x, int y, int w, int h, const char *l ) + : Fl_Group( x, y, w, h ) +{ + selected = NULL; + choice = new Fl_Choice( 0, 0, 0, 0 ); + choice->callback( _choiceCB, this ); + box( FL_EMBOSSED_BOX ); + align( FL_ALIGN_LEFT | FL_ALIGN_INSIDE ); +} + +void Flu_Choice_Group :: choiceCB() +{ + value( choice->value() ); + do_callback(); +} + +int Flu_Choice_Group :: value() +{ + if( children() == 1 ) + return -1; + + for( int i = 1; i < children(); i++ ) + if( child(i) == selected ) + return i-1; + + return -1; +} + +void Flu_Choice_Group :: value( int v ) +{ + v++; + if( v >= 1 && v < children() ) + value( child(v) ); +} + +int Flu_Choice_Group :: value( Fl_Widget *newvalue ) +{ + int ret = -1; + selected = NULL; + choice->clear(); + for( int i = 1; i < children(); i++ ) + { + choice->add( child(i)->label() ); + child(i)->labeltype( FL_NO_LABEL ); + if( child(i) == newvalue ) + { + ret = i-1; + child(i)->show(); + choice->value( ret ); + selected = child(i); + } + else + child(i)->hide(); + child(i)->redraw(); + } + + redraw(); + if( parent() ) + parent()->redraw(); + + return ret; +} + +void Flu_Choice_Group :: draw() +{ + int i; + + // make sure the selected child is still a child + bool found = false; + for( i = 1; i < children(); i++ ) + if( child(i) == selected ) + { + found = true; + break; + } + if( !found ) + selected = NULL; + + if( !selected && children() > 1 ) + value( child(1) ); + + int lblW = 0, lblH = 0, X; + + for( i = 1; i < children(); i++ ) + { + int W = 0, H; + fl_measure( child(i)->label(), W, H ); + if( W > lblW ) + lblW = W; + if( H > lblH ) + lblH = H; + } + + lblW += 26; + lblH += 6; + + // align the label + if( align() & FL_ALIGN_LEFT ) + X = 4; + else if( align() & FL_ALIGN_RIGHT ) + X = w() - lblW - 8; + else + X = w()/2 - lblW/2 - 2; + + // draw the main group box + if( damage() & ~FL_DAMAGE_CHILD ) + fl_draw_box( box(), x(), y()+lblH/2, w(), h()-lblH/2, color() ); + + // clip and draw the children + choice->resize( choice->x(), choice->y(), 0, 0 ); + fl_clip( x()+2, y()+lblH+1, w()-4, h()-lblH-3 ); + draw_children(); + fl_pop_clip(); + + // clear behind the button and draw it + fl_color( color() ); + fl_rectf( x()+X, y(), lblW+4, lblH ); + fl_color( labelcolor() ); + choice->resize( x()+X+2, y(), lblW, lblH ); + draw_child( *choice ); +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Collapsable_Group.cpp b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Collapsable_Group.cpp new file mode 100644 index 0000000..30d0db1 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Collapsable_Group.cpp @@ -0,0 +1,179 @@ +// $Id: Flu_Collapsable_Group.cpp,v 1.8 2004/06/17 14:16:42 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#include +#include +#include +#include +#include +#include "FLU/Flu_Collapsable_Group.h" + +Flu_Collapsable_Group :: Flu_Collapsable_Group( int x, int y, int w, int h, const char *l ) + : Fl_Group( x, y, w, h ), button( x, y, w, 20 ), group( x, y+20, w, h-20 ) +{ + _originalHeight = h; + _changing = false; + _collapseTime = 0.25f; + _fps = 60.0f; + _fit = false; + _open = true; + _currentHeight = h; + label( l ); + + box( FL_EMBOSSED_BOX ); + align( FL_ALIGN_LEFT ); + + // the group label is actually used by the button. so since we don't want this group's label + // to show up, draw it under everything + Fl_Group::align( FL_ALIGN_CENTER ); + + Fl_Group::add( &button ); + button.callback( _collapseCB, this ); + button.align( FL_ALIGN_CENTER | FL_ALIGN_CLIP ); + + Fl_Group::add( &group ); + Fl_Group::resizable( group ); + Fl_Group::end(); + group.begin(); +} + +void Flu_Collapsable_Group :: resize( int x, int y, int w, int h ) +{ + // skip over our parent's resize since we don't want it to mess with the children + Fl_Widget::resize( x, y, w, h ); + button.resize( x, y, w, 20 ); + group.resize( x, y+20, w, h-20 ); +} + +void Flu_Collapsable_Group :: open( bool o ) +{ + _open = o; + + do_callback(); + + if( !_changing ) + { + _oldResizable = group.resizable(); + group.resizable( NULL ); + } + + if( _open ) + { + group.show(); + _newHeight = _originalHeight; + } + else + { + _newHeight = button.h()+5; + if( !_changing ) + _originalHeight = h(); + } + + _currentHeight = float(h()); + if( !_changing ) + { + _timeout = 1.0f / _fps; + _deltaHeight = ( float(_newHeight) - _currentHeight ) / ( _collapseTime * _fps ); + _changing = true; + Fl::add_timeout( _timeout, _updateCB, this ); + } +} + +void Flu_Collapsable_Group :: updateCB() +{ + // update the height + _currentHeight += _deltaHeight; + + // see if we're done with the animation + if( ( _deltaHeight == 0.0f ) || + ( ( _deltaHeight > 0.0f ) && ( _currentHeight >= float(_newHeight) ) ) || + ( ( _deltaHeight < 0.0f ) && ( _currentHeight <= float(_newHeight) ) ) ) + { + resize( x(), y(), w(), _newHeight ); + + if( !_open ) + group.hide(); + _changing = false; + group.resizable( _oldResizable ); + } + else + { + resize( x(), y(), w(), int(_currentHeight) ); + Fl::repeat_timeout( _timeout, _updateCB, this ); + } + + // redraw the group + redraw(); + group.redraw(); + + // wierd hack to get parent to redraw everything (necessary since our size has changed) + if( parent() ) + parent()->init_sizes(); + if( this->window() ) + this->window()->redraw(); +} + +void Flu_Collapsable_Group :: draw() +{ + int X; + + FluSimpleString l = open() ? "- " : "+ "; + l += label(); + button.label( l.c_str() ); + + // force fit the button if necessary + if( _fit ) + button.size( w()-12, button.labelsize()+6 ); + else + { + // otherwise make it as big as its label + int W = 0, H = 0; + fl_font( button.labelfont(), button.labelsize() ); + fl_measure( button.label(), W, H ); + button.size( W+6, button.h() ); + } + + // align the button + if( align() & FL_ALIGN_LEFT ) + X = 4; + else if( align() & FL_ALIGN_RIGHT ) + X = w() - button.w() - 8; + else + X = w()/2 - button.w()/2 - 2; + + // draw the main group box + if( damage() & ~FL_DAMAGE_CHILD ) + fl_draw_box( box(), x(), y()+button.h()/2, w(), h()-button.h()/2, color() ); + + // clip and draw the internal group + fl_clip( x()+2, y()+button.h()+1, w()-4, h()-button.h()-3 ); + if( _changing ) + { + if( !_open ) + group.resize( x(), y()-_originalHeight+(int)_currentHeight+20, w(), _originalHeight ); + else + group.resize( x(), y()-_newHeight+(int)_currentHeight+20, w(), _newHeight ); + } + draw_child( group ); + fl_pop_clip(); + + // clear behind the button, resize, and draw + fl_color( color() ); + fl_rectf( x()+X, y(), button.w()+4, button.h() ); + button.position( x()+X+2, y() ); + draw_child( button ); + + button.label( 0 ); +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Combo_Box.cpp b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Combo_Box.cpp new file mode 100644 index 0000000..22989db --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Combo_Box.cpp @@ -0,0 +1,295 @@ +// $Id: Flu_Combo_Box.cpp,v 1.20 2004/10/15 14:46:12 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#include +#include +#include +#include +#include +#include + +#include "FLU/Flu_Combo_Box.h" + +Flu_Combo_Box :: Flu_Combo_Box( int X, int Y, int W, int H, const char* l ) + : Fl_Group( X, Y, W, H, l ), input( X, Y, W, H ) +{ + box( FL_DOWN_BOX ); + align( FL_ALIGN_LEFT ); + pop_height( 100 ); + + _cbox = NULL; + _valbox = FL_UP_BOX; + + input_callback( NULL ); + input.box( FL_FLAT_BOX ); + input.callback( input_cb, this ); + input.when( FL_WHEN_ENTER_KEY_ALWAYS ); + input.color( FL_WHITE, selection_color()); + input.textfont( FL_HELVETICA ); + input.textsize( FL_NORMAL_SIZE ); + input.textcolor( FL_FOREGROUND_COLOR ); + + input.resize( X+Fl::box_dx(box()), Y+Fl::box_dy(box()), + W-18-Fl::box_dw(box()), H-Fl::box_dh(box()) ); + + editable( true ); + + end(); +} + +Flu_Combo_Box::~Flu_Combo_Box() +{ +} + +void Flu_Combo_Box :: set_combo_widget( Fl_Widget *w ) +{ + _cbox = w; + this->add( w ); +} + +void Flu_Combo_Box :: input_cb( Fl_Widget*, void* v ) +{ + // taken from Fl_Counter.cxx + Flu_Combo_Box& t = *(Flu_Combo_Box*)v; + + if( strcmp( t.input.value(), t.value() )!=0 || t.input.when() & FL_WHEN_NOT_CHANGED) + { + if( t.when() ) + { + t.clear_changed(); + if( t._inputCB ) + t._inputCB( &t, t._inputCBD ); + else + t.do_callback(); + } + else + { + t.set_changed(); + } + } +} + +void Flu_Combo_Box :: resize( int X, int Y, int W, int H ) +{ + Fl_Group::resize( X, Y, W, H ); + input.resize( X+Fl::box_dx(box()), Y+Fl::box_dy(box()), + W-18-Fl::box_dw(box()), H-Fl::box_dh(box()) ); +} + +void Flu_Combo_Box :: draw() +{ + int W = 18, H = h()-4; + int X = x()+w()-W-2, Y = y()+2; + + fl_draw_box( box(), x(), y(), w(), h(), color() ); + + // draw the arrow button + fl_draw_box( (Fl_Boxtype)_valbox, X, Y, W, H, color() ); + fl_color( active_r() ? FL_FOREGROUND_COLOR : fl_inactive(FL_FOREGROUND_COLOR) ); + fl_polygon( X+W/2-5, Y+H/2-2, X+W/2+3, Y+H/2-2, X+W/2-1, Y+H/2+2 ); + + draw_child( input ); + if( Fl::focus() == this ) + draw_focus( FL_NO_BOX, input.x(), input.y(), input.w(), input.h() ); +} + +int global_x( Fl_Widget *w ) +{ + int x = Fl::x()+w->x(); + Fl_Widget *o = w->parent(); + while( o ) + { + if( o->type() >= FL_WINDOW ) x += o->x(); + o = o->parent(); + } + return x; +} + +int global_y( Fl_Widget *w ) +{ + int y = Fl::y()+w->y(); + Fl_Widget *o = w->parent(); + while( o ) + { + if( o->type() >= FL_WINDOW ) y += o->y(); + o = o->parent(); + } + return y; +} + +Flu_Combo_Box::Popup :: Popup( Flu_Combo_Box *b, Fl_Widget *c, int H ) + : Fl_Double_Window( global_x(b)-2, //Fl::x()+b->window()->x()+b->x()-2, + global_y(b)+b->h()-2, //Fl::y()+b->window()->y()+b->y()+b->h()-2, + b->w()+4, H, 0 ) +{ + combo = b; + dragging = false; + selected = NULL; + + box( FL_BORDER_FRAME ); + border( 0 ); + add( c ); + end(); + //set_non_modal(); + set_modal(); + + c->resize( 1, 1, w()-2, h()-2 ); +} + +Flu_Combo_Box::Popup :: ~Popup() +{ + while( children() ) + remove( child(0) ); +} + +void Flu_Combo_Box :: value( const char *v ) +{ + if( _value( v ) ) + input.value( v ); +} + +void Flu_Combo_Box :: selected( const char *v ) +{ + if( v ) + input.value( v ); + _popped = false; + do_callback(); +} + +int Flu_Combo_Box::Popup :: handle( int event ) +{ + if( event == FL_MOVE ) + { + // FL_MOVE is also generated while the window is moving + // this attempts to keep the popup window moving with the enclosing window + //position( combo->window()->x()+combo->x()-2, combo->window()->y()+combo->y()+combo->h()-2 ); + position( global_x(combo)-2, global_y(combo)+combo->h()-2 ); + // this lets the mouse move event also move the selected item + combo->_hilight( Fl::event_x(), Fl::event_y() ); + } + + if( event == FL_DRAG ) + dragging = true; + + // if push outside the popup window, popdown + if( event == FL_PUSH && + !Fl::event_inside( child(0) ) ) + { + combo->_popped = false; + return 0; + } + + // if release after dragging outside the popup window, popdown + if( event == FL_RELEASE && dragging && + !Fl::event_inside( child(0) ) ) + { + combo->_popped = false; + return 0; + } + + if( event == FL_KEYDOWN ) + { + if( Fl::event_key( FL_Escape ) ) + { + combo->_popped = false; + return 0; + } + else if( Fl::event_key( FL_Up ) ) + { + const char *s = combo->_previous(); + if( s ) + selected = s; + return 1; + } + else if( Fl::event_key( FL_Down ) ) + { + const char *s = combo->_next(); + if( s ) + selected = s; + return 1; + } + else if( Fl::event_key( FL_Enter ) || Fl::event_key( ' ' ) ) + { + if( selected ) + { + combo->value( selected ); + combo->selected( selected ); + } + combo->_popped = false; + return 1; + } + } + + return Fl_Double_Window::handle( event ); +} + +int Flu_Combo_Box :: handle( int event ) +{ + if( event == FL_KEYDOWN && Fl::event_key( FL_Tab ) ) + return Fl_Group::handle( event ); + + // is it time to popup? + bool open = ( event == FL_PUSH ) && + (!Fl::event_inside( &input ) || ( !editable() && Fl::event_inside( &input ) ) ); + open |= ( event == FL_KEYDOWN ) && Fl::event_key( ' ' ); + + if( open ) + { + fl_cursor( FL_CURSOR_DEFAULT ); + + _valbox = FL_THIN_DOWN_BOX; + redraw(); + + // remember old current group + Fl_Group *c = Fl_Group::current(); + + // set current group to 0 so this is a top level popup window + Fl_Group::current( 0 ); + Popup *_popup = new Popup( this, _cbox, popHeight ); + + // show it and make FLTK send all events there + value( value() ); + _popup->show(); + Fl::grab( *_popup ); + Fl::focus( _cbox ); + _popped = true; + Fl::pushed( _cbox ); + + // wait for a selection to be made + while( _popped ) + Fl::wait(); + + // restore things and delete the popup + _popup->hide(); + Fl::grab( 0 ); + delete _popup; + Fl_Group::current( c ); + Fl::focus( this ); + + _valbox = FL_UP_BOX; + redraw(); + + return 1; + } + + if( input.handle(event) ) + { + if( !editable() && ( event == FL_ENTER || event == FL_LEAVE ) ) + fl_cursor( FL_CURSOR_DEFAULT ); + return 1; + } + else + return 0; +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Combo_List.cpp b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Combo_List.cpp new file mode 100644 index 0000000..e478503 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Combo_List.cpp @@ -0,0 +1,93 @@ +// $Id: Flu_Combo_List.cpp,v 1.5 2004/03/24 02:49:13 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#include +#include +#include +#include +#include +#include + +#include "FLU/Flu_Combo_List.h" + +Flu_Combo_List :: Flu_Combo_List( int X, int Y, int W, int H, const char* l ) + : Flu_Combo_Box( X, Y, W, H, l ), list(0,0,0,0) +{ + list.box( FL_FLAT_BOX ); + list.callback( _cb, this ); + set_combo_widget( &list ); +} + +Flu_Combo_List :: ~Flu_Combo_List() +{ +} + +void Flu_Combo_List :: cb() +{ + if( list.value() ) + selected( list.text( list.value() ) ); + else + _value( value() ); +} + +void Flu_Combo_List :: _hilight( int x, int y ) +{ + if( list.scrollbar.visible() ) + { + if( x > list.x() && y > list.y() && + x < (list.x()+list.w()-list.scrollbar.w()) && + y < (list.y()+list.h()) ) + list.handle( FL_DRAG ); + } + else + { + if( x > list.x() && y > list.y() && + x < (list.x()+list.w()) && + y < (list.y()+list.h()) ) + list.handle( FL_DRAG ); + } +} + +bool Flu_Combo_List :: _value( const char *v ) +{ + // see if 'v' is in the list, and if so, make it the current selection + for( int i = 1; i <= list.size(); i++ ) + { + if( strcmp( list.text(i), v ) == 0 ) + { + list.value( i ); + return true; + } + } + return false; +} + +const char* Flu_Combo_List :: _next() +{ + int v = list.value(); + if( v < list.size() ) + list.value( v+1 ); + list.middleline( list.value() ); + return list.text(list.value()); +} + +const char* Flu_Combo_List :: _previous() +{ + int v = list.value(); + if( v > 1 ) + list.value( v-1 ); + list.middleline( list.value() ); + return list.text(list.value()); +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Combo_Tree.cpp b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Combo_Tree.cpp new file mode 100644 index 0000000..7c6ee5c --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Combo_Tree.cpp @@ -0,0 +1,100 @@ +// $Id: Flu_Combo_Tree.cpp,v 1.5 2004/08/02 14:18:16 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#include +#include +#include +#include +#include +#include + +#include "FLU/Flu_Combo_Tree.h" + +Flu_Combo_Tree :: Flu_Combo_Tree( int X, int Y, int W, int H, const char* l ) + : Flu_Combo_Box( X, Y, W, H, l ), tree(0,0,0,0) +{ + tree.callback( _cb, this ); + tree.selection_mode( FLU_SINGLE_SELECT ); + tree.when( FL_WHEN_RELEASE ); + set_combo_widget( &tree ); +} + +Flu_Combo_Tree :: ~Flu_Combo_Tree() +{ +} + +void Flu_Combo_Tree :: cb() +{ + if( tree.callback_reason() == FLU_SELECTED ) + selected( tree.callback_node()->find_path() ); +} + +void Flu_Combo_Tree :: _hilight( int x, int y ) +{ + if( tree.inside_entry_area( x, y ) ) + tree.handle( FL_PUSH ); +} + +bool Flu_Combo_Tree :: _value( const char *v ) +{ + // see if 'v' is in the tree, and if so, make it the current selection + Flu_Tree_Browser::Node *n = tree.find( v ); + if( n ) + { + tree.unselect_all(); + tree.set_hilighted( n ); + n->select( true ); + return true; + } + return false; +} + +const char* Flu_Combo_Tree :: _next() +{ + Flu_Tree_Browser::Node *n = tree.get_selected( 1 ); + if( n ) + { + Flu_Tree_Browser::Node *n2 = n->next(); + if( n2 ) + { + n->select( false ); + n2->select( true ); + tree.set_hilighted( n2 ); + const char *path = n2->find_path(); + return( strlen(path) ? path : NULL ); + } + } + return NULL; +} + +const char* Flu_Combo_Tree :: _previous() +{ + Flu_Tree_Browser::Node *n = tree.get_selected( 1 ); + if( n ) + { + Flu_Tree_Browser::Node *n2 = n->previous(); + if( n2 ) + { + if( n2->is_root() && !tree.show_root() ) + return NULL; + n->select( false ); + n2->select( true ); + tree.set_hilighted( n2 ); + const char *path = n2->find_path(); + return( strlen(path) ? path : NULL ); + } + } + return NULL; +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_DND.cpp b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_DND.cpp new file mode 100644 index 0000000..10acde6 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_DND.cpp @@ -0,0 +1,264 @@ +// $Id: Flu_DND.cpp,v 1.21 2004/08/18 11:06:38 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#include +#include "FLU/Flu_DND.h" + +Flu_DND_Event :: Flu_DND_Event() +{ + _text = _dataType = 0; + clear(); +} + +Flu_DND_Event :: ~Flu_DND_Event() +{ + clear(); +} + +void Flu_DND_Event :: clear() +{ + // reset everything + objUnderMouse = false; + dragging = false; + exit = false; + if(_text) free(_text); _text = 0; + if(_dataType) free(_dataType); _dataType = 0; + _data = 0; + _grab_x = _grab_y = _drop_x = _drop_y = 0; +} + +Flu_DND_Event Flu_DND::dndEvent; + +Flu_DND :: Flu_DND( const char *thisType ) +{ + // initialize everything + nTypes = 0; + _thisType = strdup( thisType ); + dnd_allow_text( false ); + dnd_callback( 0 ); + allowDragging = allowDropping = true; +} + +Flu_DND :: ~Flu_DND() +{ + // free all the stored types + if( _thisType ) + free( _thisType ); + for( int i = 0; i < nTypes; i++ ) + free( allowedTypes[i] ); +} + +void Flu_DND :: dnd_allow_type( const char *t ) +{ + if( nTypes >= FLU_DND_MAX_TYPES ) + return; + allowedTypes[nTypes++] = strdup( t ); +} + +bool Flu_DND :: dnd_type_allowed( const char *t ) const +{ + for( int i = 0; i < nTypes; i++ ) + if( strcmp( allowedTypes[i], t ) == 0 ) + return true; + return false; +} + +void Flu_DND :: dnd_grab( void *data, const char *type ) +{ + dndEvent.clear(); + if( !allowDragging || !data ) + return; + // remember the event + //printf( "dnd_grab %s %X\n", _thisType, this ); + dndEvent.dragging = true; + dndEvent.exit = false; + dndEvent.objUnderMouse = this; + dndEvent._data = data; + dndEvent._dataType = strdup( type ); + dndEvent._grab_x = Fl::event_x(); + dndEvent._grab_y = Fl::event_y(); + + // start the fltk system-wide DND + Fl::copy( " ", 1, 0 ); + Fl::dnd(); +} + +void Flu_DND :: on_dnd_enter() +{ +} + +void Flu_DND :: on_dnd_leave() +{ +} + +void Flu_DND :: on_dnd_drop( const Flu_DND_Event *e ) +{ +} + +void Flu_DND :: on_dnd_release() +{ +} + +bool Flu_DND :: on_dnd_drag( int X, int Y ) +{ + return true; +} + +int Flu_DND :: dnd_handle( int event ) +{ + // if dnd is on, then only DND events are generated + // but, there appears to be a bug in fltk where an FL_NO_EVENT is generated if the mouse + // is released when outside of any fltk widget. so, if we detect the NO_EVENT, and we are still + // dragging, then we need to process it as a release + if( dndEvent.dragging && event == FL_NO_EVENT ) + { + if( dndEvent.exit ) // not in any widget + { + // trash the event and return + //printf( "exit %s %X\n", _thisType, this ); + dndEvent.clear(); + return 1; + } + // otherwise the NO_EVENT is inside a widget. i don't know why a NO_EVENT is generated + // since the event is inside a widget. but, whatever. at any rate, this object should process + // it as a paste, only if it is the object the mouse is over (as tracked by dndEvent.objUnderMouse) + if( dndEvent.objUnderMouse == this ) + { + //printf( "FL_NO_EVENT %s %X\n", _thisType, this ); + event = FL_PASTE; + } + } + + //printf( "event %d %s %X\n", event, _thisType, this ); + + switch( event ) + { + case FL_DND_DRAG: + { + //printf( "FL_DND_DRAG %s %X\n", _thisType, this ); + + // if we receive a drag event and we are not holding data, then it must be + // from an fltk text widget + + // remember where the dragging occurs and check if it's ok for us + // to drop the item here + dndEvent.dragging = true; + dndEvent.objUnderMouse = this; + dndEvent._drop_x = Fl::event_x(); + dndEvent._drop_y = Fl::event_y(); + + return ok2drop(); + } + + case FL_DND_RELEASE: + //printf( "FL_DND_RELEASE %s %X\n", _thisType, this ); + on_dnd_release(); + return ok2drop(); + + //case FL_UNFOCUS: + //printf( "FL_UNFOCUS %s %X\n", _thisType, this ); + //return 1; + + //case FL_FOCUS: + //printf( "FL_FOCUS %s %X\n", _thisType, this ); + //return 1; + + case FL_DND_ENTER: + //printf( "FL_DND_ENTER %s %X\n", _thisType, this ); + dndEvent.exit = false; + dndEvent.objUnderMouse = this; + dndEvent._drop_x = Fl::event_x(); + dndEvent._drop_y = Fl::event_y(); + if( ok2drop() ) // if it's ok to drop, then it's ok to enter + { + on_dnd_enter(); + return 1; + } + else + return 0; + + case FL_DND_LEAVE: + //printf( "FL_DND_LEAVE %s %X\n", _thisType, this ); + dndEvent.exit = true; + dndEvent.objUnderMouse = NULL; + on_dnd_leave(); + return 1; + + case FL_PASTE: + //printf( "FL_PASTE %s %X\n", _thisType, this ); + on_dnd_release(); + // if the mouse is not inside a DND widget, then there's nothing to do + if( dndEvent.exit ) + { + dndEvent.clear(); + return 0; + } + + //if( dndEvent.objUnderMouse != this ) + //return 0; + + // if there's no data, then this paste is generated from an FLTK text DND event + if( !dndEvent.data() ) + { + dndEvent.clear(); + dndEvent._text = strdup( Fl::event_text() ); + } + dndEvent._drop_x = Fl::event_x(); + dndEvent._drop_y = Fl::event_y(); + + // if it's ok to drop, then call the drop processing members + if( true ) + { + if( dndCallback ) + dndCallback( &dndEvent, dndCallbackData ); + on_dnd_drop(&dndEvent); + dndEvent.clear(); + return 1; + } + else + { + dndEvent.clear(); + return 0; + } + + default: + // just in case + //printf( "event: %d\n", event ); + if( dndEvent.exit ) + { + on_dnd_release(); + dndEvent.clear(); + } + break; + } + return 0; +} + +bool Flu_DND :: ok2drop() +{ + if( !allowDropping ) + return false; + + if( dndEvent.data() ) // see if the dnd event is valid + { + // check if the source type is allowed by this class + if( !dnd_type_allowed( dndEvent.data_type() ) ) + return false; + } + else if( !allowTextEvents ) // event is a normal FLTK text dnd event + return false; + + return on_dnd_drag( Fl::event_x(), Fl::event_y() ); +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Dual_Progress_Meter.cpp b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Dual_Progress_Meter.cpp new file mode 100644 index 0000000..3729b6d --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Dual_Progress_Meter.cpp @@ -0,0 +1,96 @@ +// $Id: Flu_Dual_Progress_Meter.cpp,v 1.4 2003/08/20 16:29:45 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#include "FLU/Flu_Dual_Progress_Meter.h" + +Flu_Dual_Progress_Meter :: Flu_Dual_Progress_Meter( const char* t ) +{ + window = new Fl_Double_Window( 350, 250, t ); + currentLabel = new Flu_Label( 10, 5, 330, 65 ); + currentLabel->align( currentLabel->align() | FL_ALIGN_WRAP ); + currentSlider = new Fl_Slider( 10, 70, 330, 30 ); + totalLabel = new Flu_Label( 10, 105, 330, 65 ); + totalLabel->align( totalLabel->align() | FL_ALIGN_WRAP ); + totalSlider = new Fl_Slider( 10, 170, 330, 30 ); + cancel = new Fl_Button( window->w()/2-30, window->h()-40, 60, 30, "Cancel" ); + window->end(); + + window->hide(); + + currentSlider->deactivate(); + currentSlider->align( FL_ALIGN_TOP | FL_ALIGN_LEFT ); + currentSlider->type( FL_HOR_FILL_SLIDER ); + currentSlider->range( 0, 1 ); + currentSlider->selection_color( FL_BLUE ); + + totalSlider->deactivate(); + totalSlider->align( FL_ALIGN_TOP | FL_ALIGN_LEFT ); + totalSlider->type( FL_HOR_FILL_SLIDER ); + totalSlider->range( 0, 1 ); + totalSlider->selection_color( FL_BLUE ); + + cancel->callback( _onCancelCB, this ); + _cancelled = false; + + _cancelCB = NULL; + _cancelCBD = NULL; +} + +Flu_Dual_Progress_Meter :: ~Flu_Dual_Progress_Meter() +{ + if( window ) + window->hide(); +} + +bool Flu_Dual_Progress_Meter :: setCurrentValue( float v ) +{ + if( currentSlider ) + { + currentSlider->value( v ); + if( window->visible() ) + currentSlider->redraw(); + Fl::wait(0); + } + return _cancelled; +} + +bool Flu_Dual_Progress_Meter :: setTotalValue( float v ) +{ + if( totalSlider ) + { + totalSlider->value( v ); + if( window->visible() ) + totalSlider->redraw(); + Fl::wait(0); + } + return _cancelled; +} + +void Flu_Dual_Progress_Meter :: show( bool cancelBtnVisible ) +{ + _cancelled = false; + if( _cancelCB || cancelBtnVisible ) + cancel->show(); + else + cancel->hide(); + + if( window ) + { + window->set_modal(); + window->show(); + } + + Fl::flush(); +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Dual_Slider.cpp b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Dual_Slider.cpp new file mode 100644 index 0000000..4d4b7a7 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Dual_Slider.cpp @@ -0,0 +1,338 @@ +// $Id: Flu_Dual_Slider.cpp,v 1.2 2004/06/11 13:02:56 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#include "FLU/Flu_Dual_Slider.h" + +Flu_Dual_Slider :: Flu_Dual_Slider( int x, int y, int w, int h, const char *l ) + : Fl_Valuator( x, y, w, h, l ) +{ + _grab = 0; + _overlap = false; + _lFocus = true; + _lVal = lowValue = 0.0f; + _hVal = highValue = 1.0f; + _lGrabbed = _hGrabbed = false; + precision(2); + box( FL_DOWN_BOX ); +} + +Flu_Dual_Slider :: ~Flu_Dual_Slider() +{ +} + +int Flu_Dual_Slider :: handle( int event ) +{ + switch( event ) + { + case FL_PUSH: + if( Fl::visible_focus() ) Fl::focus(this); + if( Fl::event_inside( _lHandle[0], _lHandle[1], _lHandle[2], _lHandle[3] ) ) + { + set_value( lowValue ); + handle_push(); + _lGrabbed = true; + _lFocus = true; + _grabDelta = _horizontal() ? + Fl::event_x()-_lHandle[0] : + Fl::event_y()-_lHandle[1]; + redraw(); + return 1; + } + else if( Fl::event_inside( _hHandle[0], _hHandle[1], _hHandle[2], _hHandle[3] ) ) + { + set_value( highValue ); + handle_push(); + _hGrabbed = true; + _lFocus = false; + _grabDelta = _horizontal() ? + Fl::event_x()-_hHandle[0] : + Fl::event_y()-_hHandle[1]; + redraw(); + return 1; + } + break; + + case FL_DRAG: + { + float min = minimum(), max = maximum(); + bool flip = false; + if( min > max ) + { + min = maximum(); + max = minimum(); + flip = true; + range( min, max ); + } + //int X = x()+Fl::box_dx(box()), Y = y()+Fl::box_dy(box()), + int W = w()-Fl::box_dw(box()), H = h()-Fl::box_dh(box()); + int s = _horizontal() ? H/2 : W/2; + int S = _horizontal() ? W : H; + if( _nice() ) + s += 4; + + if( _lGrabbed ) + { + int diff = _horizontal() ? + (Fl::event_x() - _grabDelta) - x() : + (Fl::event_y() - _grabDelta) - y(); + _lVal = float(diff)/float(S-s-s); + if( _lVal < 0.0f ) _lVal = 0.0f; + if( _lVal >= _hVal ) _lVal = _hVal; + redraw(); + lowValue = min + _lVal*(max-min); + lowValue = round(lowValue); + if( lowValue >= highValue ) + lowValue = _overlap ? highValue : clamp( increment( highValue, -1 ) ); + lowValue = clamp(lowValue); + if( flip ) + range( max, min ); + handle_drag( lowValue ); + } + else if( _hGrabbed ) + { + int diff = _horizontal() ? + (Fl::event_x() - _grabDelta - s) - x() : + (Fl::event_y() - _grabDelta - s) - y(); + _hVal = float(diff)/float(S-s-s); + if( _hVal <= _lVal ) _hVal = _lVal; + if( _hVal > 1.0f ) _hVal = 1.0f; + redraw(); + highValue = min + _hVal*(max-min); + highValue = round(highValue); + if( highValue <= lowValue ) + highValue = _overlap ? lowValue : clamp( increment( lowValue, 1 ) ); + highValue = clamp(highValue); + if( flip ) + range( max, min ); + handle_drag( highValue ); + } + } + break; + + case FL_RELEASE: + _lGrabbed = _hGrabbed = false; + handle_release(); + break; + + case FL_KEYBOARD: + switch( Fl::event_key() ) + { + case FL_Up: + if( _horizontal() ) + _lFocus = !_lFocus; + else + { + int inc = minimum() > maximum() ? 1 : -1; + if( _lFocus ) + { + set_value( lowValue ); + lowValue = clamp( increment( lowValue, inc ) ); + if( lowValue >= highValue ) + lowValue = _overlap ? highValue : clamp( increment( highValue, inc ) ); + handle_drag( lowValue ); + handle_release(); + } + else + { + set_value( highValue ); + highValue = clamp( increment( highValue, inc ) ); + if( highValue <= lowValue ) + highValue = _overlap ? lowValue : clamp( increment( lowValue, -inc ) ); + handle_drag( highValue ); + handle_release(); + } + } + redraw(); + return 1; + case FL_Down: + if( _horizontal() ) + _lFocus = !_lFocus; + else + { + int inc = minimum() > maximum() ? -1 : 1; + if( _lFocus ) + { + set_value( lowValue ); + lowValue = clamp( increment( lowValue, inc ) ); + if( lowValue >= highValue ) + lowValue = _overlap ? highValue : clamp( increment( highValue, -inc ) ); + handle_drag( lowValue ); + handle_release(); + } + else + { + set_value( highValue ); + highValue = clamp( increment( highValue, inc ) ); + if( highValue <= lowValue ) + highValue = _overlap ? lowValue : clamp( increment( lowValue, inc ) ); + handle_drag( highValue ); + handle_release(); + } + } + redraw(); + return 1; + case FL_Left: + if( _horizontal() ) + { + int inc = minimum() > maximum() ? 1 : -1; + if( _lFocus ) + { + set_value( lowValue ); + lowValue = clamp( increment( lowValue, inc ) ); + if( lowValue >= highValue ) + lowValue = _overlap ? highValue : clamp( increment( highValue, inc ) ); + handle_drag( lowValue ); + handle_release(); + } + else + { + set_value( highValue ); + highValue = clamp( increment( highValue, inc ) ); + if( highValue <= lowValue ) + highValue = _overlap ? lowValue : clamp( increment( lowValue, -inc ) ); + handle_drag( highValue ); + handle_release(); + } + } + else + _lFocus = !_lFocus; + redraw(); + return 1; + case FL_Right: + if( _horizontal() ) + { + int inc = minimum() > maximum() ? -1 : 1; + if( _lFocus ) + { + set_value( lowValue ); + lowValue = clamp( increment( lowValue, inc ) ); + if( lowValue >= highValue ) + lowValue = _overlap ? highValue : clamp( increment( highValue, -inc ) ); + handle_drag( lowValue ); + handle_release(); + } + else + { + set_value( highValue ); + highValue = clamp( increment( highValue, inc ) ); + if( highValue <= lowValue ) + highValue = _overlap ? lowValue : clamp( increment( lowValue, inc ) ); + handle_drag( highValue ); + handle_release(); + } + } + else + _lFocus = !_lFocus; + redraw(); + return 1; + } + break; + + case FL_FOCUS: + case FL_UNFOCUS: + if( Fl::visible_focus() ) + { + redraw(); + return 1; + } + else + return 0; + + case FL_ENTER : + case FL_LEAVE : + return 1; + } + return Fl_Valuator::handle(event); +} + +void Flu_Dual_Slider :: draw() +{ + float min = minimum(), max = maximum(); + if( min > max ) + { + min = maximum(); + max = minimum(); + } + + float lo = (lowValue - min)/(max-min), + hi = (highValue - min)/(max-min); + + draw_box(); + + int X = x()+Fl::box_dx(box()), Y = y()+Fl::box_dy(box()), + W = w()-Fl::box_dw(box()), H = h()-Fl::box_dh(box()); + int s = _horizontal() ? h()/2 : w()/2; + int S = _horizontal() ? W : H; + if( _nice() ) + s += 4; + int loOff = _horizontal() ? + X + int(lo*float(S-s-s)) : + Y + int(lo*float(S-s-s)); + int hiOff = _horizontal() ? + X + s + int(hi*float(S-s-s)) : + Y + s + int(hi*float(S-s-s)); + + if( _nice() ) + { + Fl_Color black = active_r() ? FL_FOREGROUND_COLOR : FL_INACTIVE_COLOR; + if( _horizontal() ) + draw_box( FL_THIN_DOWN_BOX, X+2, Y+H/2-2, W-4, 4, black ); + else + draw_box( FL_THIN_DOWN_BOX, X+W/2-2, Y+2, 4, H-4, black ); + } + + if( _horizontal() ) + { + _lHandle[0] = loOff; _lHandle[1] = Y; _lHandle[2] = s; _lHandle[3] = H; + _hHandle[0] = hiOff; _hHandle[1] = Y; _hHandle[2] = s; _hHandle[3] = H; + draw_box( FL_UP_BOX, loOff, Y, s, H, FL_GRAY); + draw_box( FL_UP_BOX, hiOff, Y, s, H, FL_GRAY); + if( _nice() ) + { + draw_box( FL_THIN_DOWN_BOX, loOff+s/2-3, Y+2, 6, H-4, FL_GRAY); + draw_box( FL_THIN_DOWN_BOX, hiOff+s/2-3, Y+2, 6, H-4, FL_GRAY); + } + } + else + { + _lHandle[0] = X; _lHandle[1] = loOff; _lHandle[2] = W; _lHandle[3] = s; + _hHandle[0] = X; _hHandle[1] = hiOff; _hHandle[2] = W; _hHandle[3] = s; + draw_box( FL_UP_BOX, X, loOff, W, s, FL_GRAY); + draw_box( FL_UP_BOX, X, hiOff, W, s, FL_GRAY); + if( _nice() ) + { + draw_box( FL_THIN_DOWN_BOX, X+2, loOff+s/2-3, W-4, 6, FL_GRAY); + draw_box( FL_THIN_DOWN_BOX, X+2, hiOff+s/2-3, W-4, 6, FL_GRAY); + } + } + + if( Fl::focus() == this ) + { + if( _lFocus ) + { + if( _horizontal() ) + draw_focus( FL_UP_BOX, loOff, Y, s, H ); + else + draw_focus( FL_UP_BOX, X, loOff, W, s ); + } + else + { + if( _horizontal() ) + draw_focus( FL_UP_BOX, hiOff, Y, s, H ); + else + draw_focus( FL_UP_BOX, X, hiOff, W, s ); + } + } +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_File_Chooser.cpp b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_File_Chooser.cpp new file mode 100644 index 0000000..1f6625b --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_File_Chooser.cpp @@ -0,0 +1,4261 @@ +// $Id: Flu_File_Chooser.cpp,v 1.98 2004/11/02 00:33:31 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#include +#include +#include +#include +#include +#include +#include + +#define FLU_USE_REGISTRY + +#ifdef WIN32 +#include +#include +#include +#include +#endif + +#if defined WIN32 && !defined CYGWIN +#include +#else +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "FLU/flu_pixmaps.h" +#include "FLU/Flu_Label.h" +#include "FLU/Flu_Tree_Browser.h" +#include "FLU/Flu_Separator.h" +#include "FLU/Flu_Enumerations.h" + +#include "FLU/Flu_File_Chooser.h" +#include "FLU/flu_file_chooser_pixmaps.h" +#include "FLU/flu_pixmaps.h" + +// set default language strings +FluSimpleString Flu_File_Chooser::favoritesTxt = "Favorites"; +#ifdef WIN32 +FluSimpleString Flu_File_Chooser::myComputerTxt = "My Computer"; +FluSimpleString Flu_File_Chooser::myDocumentsTxt = "My Documents"; +FluSimpleString Flu_File_Chooser::desktopTxt = "Desktop"; +#else +FluSimpleString Flu_File_Chooser::myComputerTxt = "Home"; +FluSimpleString Flu_File_Chooser::myDocumentsTxt = "Documents"; +FluSimpleString Flu_File_Chooser::desktopTxt = "Desktop"; +#endif + +FluSimpleString Flu_File_Chooser::detailTxt[4] = { "Name", "Size", "Date", "Type" }; +FluSimpleString Flu_File_Chooser::contextMenuTxt[3] = { "New Folder", "Rename", "Delete" }; +FluSimpleString Flu_File_Chooser::diskTypesTxt[6] = { "Floppy Disk", "Removable Disk", + "Local Disk", "Compact Disk", + "Network Disk", "RAM Disk" }; + +FluSimpleString Flu_File_Chooser::filenameTxt = "Filename"; +FluSimpleString Flu_File_Chooser::okTxt = "Ok"; +FluSimpleString Flu_File_Chooser::cancelTxt = "Cancel"; +FluSimpleString Flu_File_Chooser::locationTxt = "Location"; +FluSimpleString Flu_File_Chooser::showHiddenTxt = "Show Hidden Files"; +FluSimpleString Flu_File_Chooser::fileTypesTxt = "File Types"; +FluSimpleString Flu_File_Chooser::directoryTxt = "Directory"; +FluSimpleString Flu_File_Chooser::allFilesTxt = "All Files (*)"; +FluSimpleString Flu_File_Chooser::defaultFolderNameTxt = "New Folder"; + +FluSimpleString Flu_File_Chooser::backTTxt = "Go back one directory in the history"; +FluSimpleString Flu_File_Chooser::forwardTTxt = "Go forward one directory in the history"; +FluSimpleString Flu_File_Chooser::upTTxt = "Go to the parent directory"; +FluSimpleString Flu_File_Chooser::reloadTTxt = "Refresh this directory"; +FluSimpleString Flu_File_Chooser::trashTTxt = "Delete file(s)"; +FluSimpleString Flu_File_Chooser::newDirTTxt = "Create new directory"; +FluSimpleString Flu_File_Chooser::addFavoriteTTxt = "Add this directory to my favorites"; +FluSimpleString Flu_File_Chooser::previewTTxt = "Preview files"; +FluSimpleString Flu_File_Chooser::listTTxt = "List mode"; +FluSimpleString Flu_File_Chooser::wideListTTxt = "Wide list mode"; +FluSimpleString Flu_File_Chooser::detailTTxt = "Detail mode"; + +FluSimpleString Flu_File_Chooser::createFolderErrTxt = "Could not create directory '%s'. You may not have permission to perform this operation."; +FluSimpleString Flu_File_Chooser::deleteFileErrTxt = "An error ocurred while trying to delete '%s'."; +FluSimpleString Flu_File_Chooser::fileExistsErrTxt = "File '%s' already exists!"; +FluSimpleString Flu_File_Chooser::renameErrTxt = "Unable to rename '%s' to '%s'"; + +// just a string that no file could probably ever be called +#define FAVORITES_UNIQUE_STRING "\t!@#$%^&*(Favorites)-=+" + +#define DEFAULT_ENTRY_WIDTH 235 + +Fl_Pixmap up_folder_img( (char*const*)big_folder_up_xpm ), + trash( (char*const*)trash_xpm ), + new_folder( (char*const*)big_folder_new_xpm ), + reload( (char*const*)reload_xpm ), + preview_img( (char*const*)monalisa_xpm ), + file_list_img( (char*const*)filelist_xpm ), + file_listwide_img( (char*const*)filelistwide_xpm ), + fileDetails( (char*const*)filedetails_xpm ), + add_to_favorite_folder( (char*const*)folder_favorite_xpm ), + home( (char*const*)bighome_xpm ), + favorites( (char*const*)bigfavorites_xpm ), + desktop( (char*const*)desktop_xpm ), + folder_closed( (char*const*)folder_closed_xpm ), + default_file( (char*const*)textdoc_xpm ), + my_computer( (char*const*)my_computer_xpm ), + computer( (char*const*)computer_xpm ), + disk_drive( (char*const*)disk_drive_xpm ), + cd_drive( (char*const*)cd_drive_xpm ), + floppy_drive( (char*const*)floppy_drive_xpm ), + removable_drive( (char*const*)removable_drive_xpm ), + ram_drive( (char*const*)ram_drive_xpm ), + network_drive( (char*const*)network_drive_xpm ), + documents( (char*const*)filled_folder_xpm ), + littlehome( (char*const*)home_xpm ), + little_favorites( (char*const*)mini_folder_favorites_xpm ), + little_desktop( (char*const*)mini_desktop_xpm ), + bigdocuments( (char*const*)bigdocuments_xpm ), + bigtemporary( (char*const*)bigtemporary_xpm ); + +#define streq(a,b) (strcmp(a,b)==0) + +Flu_File_Chooser::FileTypeInfo* Flu_File_Chooser::types = NULL; +int Flu_File_Chooser::numTypes = 0; +int Flu_File_Chooser::typeArraySize = 0; +Flu_File_Chooser::ContextHandlerVector Flu_File_Chooser::contextHandlers; +Flu_File_Chooser::PreviewHandlerVector Flu_File_Chooser::previewHandlers; +Flu_File_Chooser::ImgTxtPreview* Flu_File_Chooser::imgTxtPreview = 0; +int (*Flu_File_Chooser::customSort)(const char*,const char*) = 0; +FluSimpleString Flu_File_Chooser::dArrow[4]; +FluSimpleString Flu_File_Chooser::uArrow[4]; + +#ifndef WIN32 + #include "linux_path_info.c" +#endif + +#ifdef WIN32 +// Internationalized windows folder name access +// Fix suggested by Fabien Costantini +/* + CSIDL_DESKTOPDIRECTORY -- desktop + CSIDL_PERSONAL -- my documents + CSIDL_PERSONAL and strip back to last "/" -> home + */ +static FluSimpleString flu_get_special_folder( int csidl ) +{ + static char path[MAX_PATH+1]; + +#ifdef FLU_USE_REGISTRY + HKEY key; + DWORD size = MAX_PATH; + const char *keyQuery = ""; + switch( csidl ) + { + case CSIDL_DESKTOPDIRECTORY: keyQuery = "Desktop"; break; + case CSIDL_PERSONAL: keyQuery = "Personal"; break; + } + + if( RegOpenKeyEx( HKEY_CURRENT_USER, + "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", + 0, KEY_QUERY_VALUE, &key ) != ERROR_SUCCESS ) + return ""; + + if( RegQueryValueEx( key, keyQuery, 0, 0, (LPBYTE)path, &size ) != ERROR_SUCCESS ) + return ""; + + RegCloseKey( key ); + + return path; + +#else + + path[0] = '\0'; + if( SUCCEEDED( SHGetSpecialFolderPath( NULL, path, csidl, FALSE ) ) ) + //if( SUCCEEDED( SHGetFolderPath( NULL, csidl, NULL, 0, path ) ) ) + { + int len = strlen(path); + if( len > 0 && path[len-1] != '/' && path[len-1] != '\\' ) + strcat( path, "/" ); + return path; + } + return ""; +#endif +} +#endif + +// taken explicitly from fltk/src/filename_match.cxx +// and changed to support case-sensitive matching +static int flu_filename_match(const char *s, const char *p) +{ + int matched; + + for (;;) { + switch(*p++) { + + case '?' : // match any single character + if (!*s++) return 0; + break; + + case '*' : // match 0-n of any characters + if (!*p) return 1; // do trailing * quickly + while (!flu_filename_match(s, p)) if (!*s++) return 0; + return 1; + + case '[': { // match one character in set of form [abc-d] or [^a-b] + if (!*s) return 0; + int reverse = (*p=='^' || *p=='!'); if (reverse) p++; + matched = 0; + char last = 0; + while (*p) { + if (*p=='-' && last) { + if (*s <= *++p && *s >= last ) matched = 1; + last = 0; + } else { + if (*s == *p) matched = 1; + } + last = *p++; + if (*p==']') break; + } + if (matched == reverse) return 0; + s++; p++;} + break; + + case '{' : // {pattern1|pattern2|pattern3} + NEXTCASE: + if (flu_filename_match(s,p)) return 1; + for (matched = 0;;) { + switch (*p++) { + case '\\': if (*p) p++; break; + case '{': matched++; break; + case '}': if (!matched--) return 0; break; + case '|': case ',': if (matched==0) goto NEXTCASE; + case 0: return 0; + } + } + case '|': // skip rest of |pattern|pattern} when called recursively + case ',': + for (matched = 0; *p && matched >= 0;) { + switch (*p++) { + case '\\': if (*p) p++; break; + case '{': matched++; break; + case '}': matched--; break; + } + } + break; + case '}': + break; + + case 0: // end of pattern + return !*s; + + case '\\': // quote next character + if (*p) p++; + default: +#ifdef WIN32 + if (tolower(*s) != tolower(*(p-1))) return 0; +#else + if( *s != *(p-1) ) return 0; +#endif + s++; + break; + } + } +} + +void Flu_File_Chooser :: add_context_handler( int type, const char *ext, const char *name, + void (*cb)(const char*,int,void*), void *cbd ) +{ + if( cb == NULL ) + return; + ContextHandler h; + h.ext = ext ? ext : ""; + h.ext.downcase(); + h.type = type; + h.name = name; + h.callback = cb; + h.callbackData = cbd; + Flu_File_Chooser::contextHandlers.add( h ); +} + +void Flu_File_Chooser :: add_preview_handler( PreviewWidgetBase *w ) +{ + if( w == NULL ) + return; + Flu_File_Chooser::previewHandlers.add( w ); +} + +// extensions == NULL implies directories +void Flu_File_Chooser :: add_type( const char *extensions, const char *short_description, Fl_Image *icon ) +{ + FluSimpleString ext; + if( extensions ) + ext = extensions; + else + ext = "\t"; // indicates a directory + ext.upcase(); + + // are we overwriting an existing type? + for( int i = 0; i < numTypes; i++ ) + { + if( types[i].extensions == ext ) + { + types[i].icon = icon; + types[i].type = short_description; + return; + } + } + + if( numTypes == typeArraySize ) + { + int newSize = ( typeArraySize == 0 ) ? 1 : typeArraySize*2; // double the size of the old list (same behavior as STL vector) + // allocate the new list + FileTypeInfo* newTypes = new FileTypeInfo[ newSize ]; + // copy the old list to the new list + for( int i = 0; i < numTypes; i++ ) + { + newTypes[i].icon = types[i].icon; + newTypes[i].extensions = types[i].extensions; + newTypes[i].type = types[i].type; + } + // delete the old list and replace it with the new list + delete[] types; + types = newTypes; + typeArraySize = newSize; + } + + types[numTypes].icon = icon; + types[numTypes].extensions = ext; + types[numTypes].type = short_description; + + numTypes++; +} + +Flu_File_Chooser::FileTypeInfo* Flu_File_Chooser :: find_type( const char *extension ) +{ + FluSimpleString ext; + if( extension ) + ext = extension; + else + ext = "\t"; // indicates a directory + ext.upcase(); + + // lookup the type based on the extension + for( int i = 0; i < numTypes; i++ ) + { + // check extension against every token + FluSimpleString e = types[i].extensions; + char *tok = strtok( (char*)e.c_str(), " ," ); + while( tok ) + { + if( ext == tok ) + return &(types[i]); + tok = strtok( NULL, " ," ); + } + } + + return NULL; +} + +Flu_File_Chooser :: Flu_File_Chooser( const char *pathname, const char *pat, int type, const char *title ) + : Fl_Double_Window( 600, 400, title ), + filename( 70, h()-60, w()-70-85-10, 25, "", this ), + ok( w()-90, h()-60, 85, 25 ), + cancel( w()-90, h()-30, 85, 25 ), + entryPopup( 0, 0, 0, 0 ) +{ + int oldNormalSize = FL_NORMAL_SIZE; + FL_NORMAL_SIZE = 12; + + _callback = 0; + _userdata = 0; + Fl_Double_Window::callback( _hideCB, this ); + + Fl_Double_Window::size_range( 600, 400 ); + + Fl_Group *g; + + filename.label( filenameTxt.c_str() ); + ok.label( okTxt.c_str() ); + ok.labelsize( FL_NORMAL_SIZE ); + cancel.label( cancelTxt.c_str() ); + cancel.labelsize( FL_NORMAL_SIZE ); + + add_type( NULL, directoryTxt.c_str(), &folder_closed ); + + for( int j = 0; j < 4; j++ ) + { + dArrow[j] = "@-12DnArrow " + detailTxt[j]; + uArrow[j] = "@-18UpArrow " + detailTxt[j]; + } + + history = currentHist = NULL; + walkingHistory = false; + fileEditing = false; +#ifdef WIN32 + refreshDrives = true; + caseSort = false; +#else + caseSort = true; +#endif + + // determine the system paths for the user's home area, desktop, documents, app data, etc +#ifdef WIN32 + userDesktop = flu_get_special_folder( CSIDL_DESKTOPDIRECTORY ); + userDocs = flu_get_special_folder( CSIDL_PERSONAL ); + + // get home area by stripping off to the last '/' from docs + userHome = userDocs; + { + for( int i = userHome.size()-1; i > 0; i-- ) + { + if( userHome[i] == '/' ) + { + userHome[i] = '\0'; + break; + } + } + } + + // construct the user desktop path + //userDesktop = userHome + "/" + desktopTxt; + + win2unix( userDesktop ); + win2unix( userDocs ); + + // make sure they don't end in '/' + if( userDesktop[userDesktop.size()-1] == '/' ) + userDesktop[userDesktop.size()-1] = '\0'; + if( userDocs[userDocs.size()-1] == '/' ) + userDocs[userDocs.size()-1] = '\0'; + + // get the actual name of the "My Documents" folder by pulling off the last name in the field + // we do this because the actual name may vary from country to country + { + int slash = userDesktop.rfind( '/' ); + if( slash != -1 ) + desktopTxt = userDesktop.c_str() + slash + 1; + slash = userDocs.rfind( '/' ); + if( slash != -1 ) + myDocumentsTxt = userDocs.c_str() + slash + 1; + } + + // make sure they end in '/' + userHome += "/"; + userDesktop += "/"; + userDocs += "/"; + +#else + { + char buf[1024]; + fl_filename_expand( buf, 1024, "~/" ); + userHome = buf; + userDesktop = xdg_user_dir_lookup ("DESKTOP"); + userDocs = xdg_user_dir_lookup ("DOCUMENTS"); + } +#endif + configFilename = userHome + ".Flu_File_Chooser.favorites"; + + selectionType = type; + filenameEnterCallback = filenameTabCallback = false; + sortMethod = SORT_NAME; + + lastSelected = NULL; + filename.labelsize( 12 ); + filename.when( FL_WHEN_ENTER_KEY_ALWAYS ); + filename.callback( _filenameCB, this ); + filename.value( "" ); + + Fl_Group *quickIcons = new Fl_Group( 5, 5, 100, h()-10-60 ); + quickIcons->box( FL_DOWN_BOX ); + quickIcons->color( FL_DARK3 ); + + Flu_Button *desktopBtn = new Flu_Button( 30, 18, 50, 48 ); + desktopBtn->box( FL_FLAT_BOX ); + desktopBtn->image( desktop ); + desktopBtn->enter_box( FL_THIN_UP_BOX ); + desktopBtn->color( FL_DARK3 ); + desktopBtn->callback( _desktopCB, this ); + { + Flu_Label *l = new Flu_Label( 5, 62, 100, 20, desktopTxt.c_str() ); + l->labelcolor( FL_WHITE ); + l->align( FL_ALIGN_CENTER ); + } + + Flu_Button *homeBtn = new Flu_Button( 30, 98, 50, 48 ); + homeBtn->box( FL_FLAT_BOX ); + homeBtn->enter_box( FL_THIN_UP_BOX ); + homeBtn->color( FL_DARK3 ); + homeBtn->callback( _homeCB, this ); + { +#ifdef WIN32 + Flu_Label *l = new Flu_Label( 5, 142, 100, 20, myComputerTxt.c_str() ); + homeBtn->image( my_computer ); +#else + Flu_Label *l = new Flu_Label( 5, 142, 100, 20, myComputerTxt.c_str() ); + homeBtn->image( home ); +#endif + l->labelcolor( FL_WHITE ); + l->align( FL_ALIGN_CENTER ); + } + + Flu_Button *documentsBtn = new Flu_Button( 30, 178, 50, 48 ); + documentsBtn->box( FL_FLAT_BOX ); + documentsBtn->enter_box( FL_THIN_UP_BOX ); + documentsBtn->labelcolor( FL_WHITE ); + documentsBtn->color( FL_DARK3 ); + documentsBtn->callback( _documentsCB, this ); + { +#ifdef WIN32 + Flu_Label *l = new Flu_Label( 5, 222, 100, 20, myDocumentsTxt.c_str() ); + documentsBtn->image( &bigdocuments ); +#else + Flu_Label *l = new Flu_Label( 5, 222, 100, 20, myDocumentsTxt.c_str() ); + documentsBtn->image( &bigtemporary ); +#endif + l->labelcolor( FL_WHITE ); + l->align( FL_ALIGN_CENTER ); + } + + Flu_Button *favoritesBtn = new Flu_Button( 30, 258, 50, 48 ); + favoritesBtn->box( FL_FLAT_BOX ); + favoritesBtn->image( favorites ); + favoritesBtn->enter_box( FL_THIN_UP_BOX ); + favoritesBtn->color( FL_DARK3 ); + favoritesBtn->callback( _favoritesCB, this ); + { + Flu_Label *l = new Flu_Label( 5, 302, 100, 20, favoritesTxt.c_str() ); + l->labelcolor( FL_WHITE ); + l->align( FL_ALIGN_CENTER ); + } + + favoritesList = new Fl_Browser( 0, 0, 0, 0 ); + favoritesList->hide(); + + { + Fl_Group* dummy = new Fl_Group( 5, h()-10-61, 100, 1 ); + quickIcons->resizable( dummy ); + } + quickIcons->end(); + + Fl_Group *dummy = new Fl_Group( 110, 0, w()-110, 70 ); + + locationQuickJump = new Fl_Group( 166, 5, w()-171, 8 ); + locationQuickJump->box( FL_NO_BOX ); + locationQuickJump->end(); + + location = new Flu_Combo_Tree( 166, 15, w()-171, 22, locationTxt.c_str() ); + location->editable( false ); + location->pop_height( 200 ); + location->tree.all_branches_always_open( true ); +#ifdef WIN32 + location->tree.show_root( false ); +#endif + location->tree.show_connectors( false ); + location->tree.horizontal_gap( -10 ); + location->tree.show_leaves( false ); + location->callback( _locationCB, this ); + + //////////////////////////////////////////////////////////////// + + g = new Fl_Group( 110, 40, w()-110, 30 ); // group enclosing all the buttons at top + + hiddenFiles = new Fl_Check_Button( 110, 43, 130, 25, showHiddenTxt.c_str() ); + hiddenFiles->callback( reloadCB, this ); +#ifdef WIN32 + hiddenFiles->hide(); +#endif + + backBtn = new Flu_Button( 285, 43, 25, 25, "@<-" ); + backBtn->labelcolor( fl_rgb_color( 80, 180, 200 ) ); + backBtn->labelsize( 16 ); + backBtn->box( FL_FLAT_BOX ); + backBtn->enter_box( FL_THIN_UP_BOX ); + backBtn->callback( _backCB, this ); + backBtn->tooltip( backTTxt.c_str() ); + + forwardBtn = new Flu_Button( 310, 43, 25, 25, "@->" ); + forwardBtn->labelcolor( fl_rgb_color( 80, 180, 200 ) ); + forwardBtn->labelsize( 16 ); + forwardBtn->box( FL_FLAT_BOX ); + forwardBtn->enter_box( FL_THIN_UP_BOX ); + forwardBtn->callback( _forwardCB, this ); + forwardBtn->tooltip( forwardTTxt.c_str() ); + + upDirBtn = new Flu_Button( 335, 43, 25, 25 ); + upDirBtn->image( up_folder_img ); + upDirBtn->box( FL_FLAT_BOX ); + upDirBtn->enter_box( FL_THIN_UP_BOX ); + upDirBtn->callback( upDirCB, this ); + upDirBtn->tooltip( upTTxt.c_str() ); + + reloadBtn = new Flu_Button( 360, 43, 25, 25 ); + reloadBtn->image( reload ); + reloadBtn->box( FL_FLAT_BOX ); + reloadBtn->enter_box( FL_THIN_UP_BOX ); + reloadBtn->callback( reloadCB, this ); + reloadBtn->tooltip( reloadTTxt.c_str() ); + + { + Flu_Separator *sep = new Flu_Separator( 385, 42, 10, 28 ); + sep->type( Flu_Separator::VERTICAL ); + sep->box( FL_ENGRAVED_BOX ); + } + + trashBtn = new Flu_Button( 395, 43, 25, 25 ); + trashBtn->image( trash ); + trashBtn->box( FL_FLAT_BOX ); + trashBtn->enter_box( FL_THIN_UP_BOX ); + trashBtn->callback( _trashCB, this ); + trashBtn->tooltip( trashTTxt.c_str() ); + + newDirBtn = new Flu_Button( 420, 43, 25, 25 ); + newDirBtn->image( new_folder ); + newDirBtn->box( FL_FLAT_BOX ); + newDirBtn->enter_box( FL_THIN_UP_BOX ); + newDirBtn->callback( _newFolderCB, this ); + newDirBtn->tooltip( newDirTTxt.c_str() ); + + addFavoriteBtn = new Flu_Button( 445, 43, 25, 25 ); + addFavoriteBtn->image( add_to_favorite_folder ); + addFavoriteBtn->box( FL_FLAT_BOX ); + addFavoriteBtn->enter_box( FL_THIN_UP_BOX ); + addFavoriteBtn->callback( _addToFavoritesCB, this ); + addFavoriteBtn->tooltip( addFavoriteTTxt.c_str() ); + + { + Flu_Separator *sep = new Flu_Separator( 470, 42, 10, 28 ); + sep->type( Flu_Separator::VERTICAL ); + sep->box( FL_ENGRAVED_BOX ); + } + + previewBtn = new Flu_Button( 482, 43, 23, 25 ); + previewBtn->type( FL_TOGGLE_BUTTON ); + previewBtn->image( preview_img ); + previewBtn->callback( _previewCB, this ); + previewBtn->tooltip( previewTTxt.c_str() ); + + { + Fl_Group *g2 = new Fl_Group( 511, 43, 81, 25 ); + fileListBtn = new Flu_Button( 511, 43, 25, 25 ); + fileListBtn->type( FL_RADIO_BUTTON ); + fileListBtn->value(1); + fileListBtn->callback( _listModeCB, this ); + fileListBtn->image( file_list_img ); + fileListBtn->tooltip( listTTxt.c_str() ); + fileListWideBtn = new Flu_Button( 540, 43, 25, 25 ); + fileListWideBtn->type( FL_RADIO_BUTTON ); + fileListWideBtn->callback( _listModeCB, this ); + fileListWideBtn->image( file_listwide_img ); + fileListWideBtn->tooltip( wideListTTxt.c_str() ); + fileDetailsBtn = new Flu_Button( 569, 43, 25, 25 ); + fileDetailsBtn->type( FL_RADIO_BUTTON ); + fileDetailsBtn->image( fileDetails ); + fileDetailsBtn->callback( _listModeCB, this ); + fileDetailsBtn->tooltip( detailTTxt.c_str() ); + g2->end(); + } + + g->resizable( hiddenFiles ); + g->end(); + + dummy->resizable( location ); + dummy->end(); + + //////////////////////////////////////////////////////////////// + + previewTile = new PreviewTile( 110, 70, w()-110-5, h()-80-40-15, this ); + fileGroup = new Fl_Group( 110, 70, w()-120-5, h()-80-40-15 ); + { + fileGroup->box( FL_DOWN_FRAME ); + filelist = new FileList( fileGroup->x()+2, fileGroup->y()+2, fileGroup->w()-4, fileGroup->h()-4, this ); + filelist->box( FL_FLAT_BOX ); + filelist->color( FL_WHITE ); + filelist->type( FL_HORIZONTAL ); + filelist->spacing( 4, 1 ); + filelist->scrollbar.linesize( DEFAULT_ENTRY_WIDTH+4 ); + filelist->end(); + + fileDetailsGroup = new Fl_Group( fileGroup->x()+2, fileGroup->y()+2, fileGroup->w()-4, fileGroup->h()-4 ); + filecolumns = new FileColumns( fileGroup->x()+2, fileGroup->y()+2, fileGroup->w()-4, 20, this ); + filescroll = new Fl_Scroll( fileGroup->x()+2, fileGroup->y()+22, fileGroup->w()-4, fileGroup->h()-20-4 ); + filescroll->color( FL_WHITE ); + filescroll->scrollbar.linesize( 20 ); + filescroll->box( FL_FLAT_BOX ); + filescroll->type( Fl_Scroll::VERTICAL ); + { + filedetails = new FileDetails( fileGroup->x()+2, fileGroup->y()+22, fileGroup->w()-4, fileGroup->h()-20-4, this ); + filedetails->end(); + } + filescroll->end(); + fileDetailsGroup->end(); + fileDetailsGroup->resizable( filescroll ); + + fileGroup->resizable( filelist ); + } + fileGroup->end(); + + previewGroup = new PreviewGroup( fileGroup->x()+fileGroup->w(), fileGroup->y(), previewTile->w()-fileGroup->w(), fileGroup->h(), this ); + previewGroup->end(); + { + Fl_Box *b = new Fl_Box( previewTile->x()+250, previewTile->y(), previewTile->w()-350, previewTile->h() ); + previewTile->add_resizable( *b ); + } + previewTile->end(); + previewTile->position( previewGroup->x(), previewGroup->y(), previewTile->x()+previewTile->w(), previewGroup->y() ); + previewTile->last = previewTile->x()+previewTile->w()-200; + + resizable( previewTile ); + + filePattern = new Flu_Combo_List( 70, h()-30, w()-70-85-10, 25, fileTypesTxt.c_str() ); + filePattern->editable( false ); + filePattern->callback( reloadCB, this ); + filePattern->pop_height( 200 ); + + ok.callback( _okCB, this ); + cancel.callback( _cancelCB, this ); + + { + g = new Fl_Group( 0, h()-60, w(), 30 ); + g->end(); + g->add( filename ); + g->add( ok ); + g->resizable( filename ); + g = new Fl_Group( 0, h()-30, w(), 30 ); + g->end(); + g->add( filePattern ); + g->add( cancel ); + g->resizable( filePattern ); + } + + end(); + + FL_NORMAL_SIZE = oldNormalSize; + + char buf[1024]; + + // try to load the favorites + { + FILE *f = fopen( configFilename.c_str(), "r" ); + if( f ) + { + buf[0] = '\0'; + while( !feof(f) ) + { + fgets( buf, 1024, f ); + char *newline = strrchr( buf, '\n' ); + if( newline ) + *newline = '\0'; + if( strlen( buf ) > 0 ) + { + // eliminate duplicates + bool duplicate = false; + for( int i = 1; i <= favoritesList->size(); i++ ) + { + if( streq( buf, favoritesList->text(i) ) ) + { + duplicate = true; + break; + } + } + if( !duplicate ) + favoritesList->add( buf ); + } + } + fclose( f ); + } + } + + if( !imgTxtPreview ) + { + imgTxtPreview = new ImgTxtPreview(); + // make the text previewer the first one + Flu_File_Chooser::previewHandlers.insert( 0, imgTxtPreview ); + } + + pattern( pat ); + default_file_icon( &default_file ); + cd( NULL ); // prime with the current directory + clear_history(); + cd( pathname ); + + // if pathname does not start with "/" or "~", set the filename to it + if( pathname && pathname[0] != '/' && pathname[1] != ':' && pathname[0] != '~' ) + filename.value( pathname ); +} + +Flu_File_Chooser :: ~Flu_File_Chooser() +{ + //Fl::remove_timeout( Entry::_editCB ); + Fl::remove_timeout( Flu_File_Chooser::delayedCdCB ); + Fl::remove_timeout( Flu_File_Chooser::selectCB ); + + for( int i = 0; i < locationQuickJump->children(); i++ ) + free( (void*)locationQuickJump->child(i)->label() ); + + filelist->clear(); + filedetails->clear(); + + clear_history(); +} + +void Flu_File_Chooser :: hideCB() +{ + // the user hid the browser by pushing the "X" + // this is the same as cancel + cancelCB(); +} + +void Flu_File_Chooser :: cancelCB() +{ + filename.value(""); + filename.position( filename.size(), filename.size() ); + unselect_all(); + do_callback(); + hide(); +} + +void Flu_File_Chooser :: do_callback() +{ + if( _callback ) + _callback( this, _userdata ); +} + +void Flu_File_Chooser :: pattern( const char *p ) +{ + // just like in Fl_File_Chooser, we accept tab, |, and ; delimited strings like this: + // "Description (patterns)" or just "patterns" where patterns is + // of the form *.xxx or *.{xxx,yyy,zzz}} + + rawPattern = p; + + // clear out the old + filePattern->list.clear(); + filePattern->input.value( "" ); + patterns.clear(); + + if( p == 0 ) + p = "*"; + else if( p[0] == '\0' ) + p = "*"; + + FluSimpleString pat = p, pattern; + + bool addedAll = false; + const char *next = strtok( (char*)pat.c_str(), "\t|;" ); + const char *start; + while( next ) + { + if( next[0] == '\0' ) + break; + + // eat whitespace + while( isspace( *next ) ) + next++; + + // degenerate check + if( strcmp( next, "*" ) == 0 ) + { + addedAll = true; + filePattern->list.add( allFilesTxt.c_str() ); + patterns.add( "*" ); + next = strtok( NULL, "\t|;" ); + continue; + } + + // extract the patterns from the substring + if( next[0] != '*' ) // starts with description + { + // the pattern starts after the first '(' + start = strchr( next, '(' ); + if( !start ) // error: couldn't find the '(' + { + next = strtok( NULL, "\t|;" ); + continue; + } + start++; // skip the '(' + } + else + start = next; + + if( start[0] != '*' ) + { + next = strtok( NULL, "\t|;" ); + continue; + } + start++; // skip the '*' + + if( start[0] != '.' ) + { + next = strtok( NULL, "\t|;" ); + continue; + } + start++; // skip the '.' + + if( start[0] == '{' ) + { + // the pattern is between '{' and '}' + pattern = start+1; + } + else + pattern = start; + + // remove the last '}' + int brace = pattern.find( '}' ); + if( brace != -1 ) + pattern[brace] = '\0'; + + // remove the last ')' + int paren = pattern.find( ')' ); + if( paren != -1 ) + pattern[paren] = '\0'; + + if( pattern.size() ) + { + // add the whole string to the list + filePattern->list.add( next ); + patterns.add( pattern ); + } + + // advance to the pattern token + next = strtok( NULL, "\t|;" ); + } + + // add all files + if( !addedAll ) + { + filePattern->list.add( allFilesTxt.c_str() ); + patterns.add( "*" ); + } + + // choose the first added item + filePattern->value( filePattern->list.text(1) ); +} + +int Flu_File_Chooser :: handle( int event ) +{ + if( Fl_Double_Window::callback() != _hideCB ) + { + _callback = Fl_Double_Window::callback(); + _userdata = Fl_Double_Window::user_data(); + Fl_Double_Window::callback( _hideCB, this ); + } + + if( Fl_Double_Window::handle( event ) ) + return 1; + else if( event == FL_KEYDOWN && Fl::event_key(FL_Escape) ) + { + cancel.do_callback(); + return 1; + } + else if( event == FL_KEYDOWN && Fl::event_key('a') && Fl::event_state(FL_CTRL) ) + { + select_all(); + return 1; + } + else + return 0; +} + +void Flu_File_Chooser :: newFolderCB() +{ + // start with the name "New Folder". while the name exists, keep appending a number (1..2..etc) + FluSimpleString newName = defaultFolderNameTxt.c_str(), path = currentDir + newName; + int count = 1; + int i; + for(;;) + { + bool found = false; + // see if any entry already has that name + Fl_Group *g = getEntryGroup(); + for( i = 0; i < g->children(); i++ ) + { + if( ((Entry*)g->child(i))->filename == newName ) + { + found = true; + break; + } + } + + // since an entry already exists, change the name and try again + if( found ) + { + char buf[16]; + sprintf( buf, "%d", count++ ); + newName = defaultFolderNameTxt.c_str() + FluSimpleString(buf); + path = currentDir + newName; + } + else + break; + } + + // try to create the folder +#if ( defined WIN32 || defined MINGW ) && !defined CYGWIN + if( mkdir( path.c_str() ) != 0 ) +#else + if( mkdir( path.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH ) != 0 ) +#endif + { + fl_alert( createFolderErrTxt.c_str(), newName.c_str() ); + return; + } + + // create a new entry with the name of the new folder. add to either the list or the details + Entry *entry = new Entry( newName.c_str(), ENTRY_DIR, fileDetailsBtn->value(), this ); + if( !fileDetailsBtn->value() ) + filelist->add( *entry ); + else + filedetails->add( *entry ); + + // switch that entry to input mode and scroll the browser to it + entry->editCB(); + /* + entry->editMode = 2; + entry->value( entry->filename.c_str() ); + entry->take_focus(); + entry->position( 0, entry->filename.size() ); + entry->redraw(); + */ + if( !fileDetailsBtn->value() ) + filelist->scroll_to( entry ); + else + filedetails->scroll_to( entry ); +} + +void Flu_File_Chooser :: recursiveScan( const char *dir, FluStringVector *files ) +{ + dirent **e; + char *name; + FluSimpleString fullpath; + int num = fl_filename_list( dir, &e ); + for( int i = 0; i < num; i++ ) + { + name = e[i]->d_name; + + // if 'name' ends in '/' or '\', remove it + if( name[strlen(name)-1] == '/' || name[strlen(name)-1] == '\\' ) + name[strlen(name)-1] = '\0'; + + // ignore the "." and ".." names + if( strcmp( name, "." ) == 0 || strcmp( name, ".." ) == 0 ) + continue; + + // file or directory? + fullpath = dir; + fullpath += "/"; + fullpath += name; + if( fl_filename_isdir( fullpath.c_str() ) != 0 ) + recursiveScan( fullpath.c_str(), files ); + + files->add( fullpath ); + } + files->add( dir ); +} + +void Flu_File_Chooser :: trashCB( bool recycle ) +{ + // linux doesn't have a recycle bin +#ifndef WIN32 + recycle = false; +#endif + + bool inFavorites = ( currentDir == FAVORITES_UNIQUE_STRING ); + if( inFavorites ) + recycle = false; + + // see how many files are selected + FluSimpleString name; + int selected = 0; + int i; + const char *first = ""; + Fl_Group *g = getEntryGroup(); + for( i = 0; i < g->children(); i++ ) + { + if( ((Entry*)g->child(i))->selected ) + { + if( selected == 0 ) + first = ((Entry*)g->child(i))->filename.c_str(); + selected++; + } + } + + if( selected ) + { + if( selected == 1 ) + { + if( recycle ) + { + if( !fl_ask( "Really send '%s' to the Recycle Bin?", first ) ) + return; + } + else + { + if( !fl_ask( "Really delete '%s'?", first ) ) + return; + } + } + else + { + if( recycle ) + { + if( !fl_ask( "Really send these %d files to the Recycle Bin?", selected ) ) + return; + } + else + { + if( !fl_ask( "Really delete these %d files?", selected ) ) + return; + } + } + + if( inFavorites ) + { + for( i = 0; i < g->children(); ) + { + Entry *e = ((Entry*)g->child(i)); + if( e->selected ) + { + favoritesList->remove(i+1); + g->remove( *e ); + delete e; + } + else + i++; + } + // save the favorites + FILE *f = fopen( configFilename.c_str(), "w" ); + if( f ) + { + for( i = 1; i <= favoritesList->size(); i++ ) + fprintf( f, "%s\n", favoritesList->text(i) ); + fclose( f ); + } + cd( FAVORITES_UNIQUE_STRING ); + return; + } + +#ifdef WIN32 + SHFILEOPSTRUCT fileop; + memset( &fileop, 0, sizeof(SHFILEOPSTRUCT) ); + fileop.fFlags = FOF_SILENT | FOF_NOERRORUI | FOF_NOCONFIRMATION; + if( recycle ) + fileop.fFlags |= FOF_ALLOWUNDO; + fileop.wFunc = FO_DELETE; + fileop.pTo = NULL; +#endif + + for( i = 0; i < g->children(); i++ ) + { + if( ((Entry*)g->child(i))->selected ) + { + int result = 0; + + name = currentDir + ((Entry*)g->child(i))->filename; + + // if directory, recursively remove + if( ((Entry*)g->child(i))->type == ENTRY_DIR ) + { + // if we are recycling in windows, then the recursive part happens automatically +#ifdef WIN32 + if( !recycle ) +#endif + { + Fl_Group::current(0); + Fl_Window *win = new Fl_Window( 200, 100, "Notice" ); + Flu_Label *label = new Flu_Label( 30, 30, 150, 30, "Preparing to delete..." ); + win->end(); + win->show(); + Fl::check(); + // recursively build a list of all files that will be deleted + FluStringVector files; + recursiveScan( name.c_str(), &files ); + // delete all the files + label->label( "Deleting files..." ); + for( unsigned int i = 0; i < files.size(); i++ ) + { + if( ::remove( files[i].c_str() ) != 0 ) + { + win->hide(); + delete win; + cd( "./" ); + return; + } + } + win->hide(); + delete win; + Fl::check(); + continue; + } + } + +#ifdef WIN32 + // this moves files to the recycle bin, depending on the value of 'recycle' + { + int len = name.size(); + char *buf = (char*)malloc( len+2 ); + strcpy( buf, name.c_str() ); + buf[len+1] = '\0'; // have to have 2 '\0' at the end + fileop.pFrom = buf; + result = SHFileOperation( &fileop ); + free( buf ); + } +#else + result = ::remove( name.c_str() ); +#endif + + // if remove fails, report an error + if( result != 0 ) + { + fl_alert( deleteFileErrTxt.c_str(), name.c_str() ); + cd( "./" ); + return; + } + } + } + + // refresh this directory + cd( "./" ); + } +} + +void Flu_File_Chooser :: updateLocationQJ() +{ + const char *path = location->value(); + for( int i = 0; i < locationQuickJump->children(); i++ ) + free( (void*)locationQuickJump->child(i)->label() ); + locationQuickJump->clear(); + fl_font( location->input.textfont(), location->input.textsize() ); + const char *next = path; + const char *slash = strchr( next, '/' ); + char *blank = strdup( path ); + int offset = 0; + while( slash ) + { + memset( blank, 0, strlen(path) ); + slash++; + memcpy( blank, next, slash-next ); + int w = 0, h = 0; + fl_measure( blank, w, h ); + if( blank[0] == '/' ) + w += Fl::box_dx( location->box() ); + memset( blank, 0, strlen(path) ); + memcpy( blank, path, slash-path ); + Fl_Button *b = new Fl_Button( locationQuickJump->x()+offset, locationQuickJump->y(), w, locationQuickJump->h(), strdup(blank) ); + b->labeltype( FL_NO_LABEL ); + b->callback( _locationQJCB, this ); + offset += w; + locationQuickJump->add( b ); + next = slash; + slash = strchr( next, '/' ); + } + Fl_Button *b = new Fl_Button( locationQuickJump->x()+offset, locationQuickJump->y(), 1, locationQuickJump->h(), strdup("") ); + b->box( FL_NO_BOX ); + b->labeltype( FL_NO_LABEL ); + locationQuickJump->add( b ); + locationQuickJump->resizable( b ); + free( blank ); +} + +void Flu_File_Chooser :: favoritesCB() +{ + cd( FAVORITES_UNIQUE_STRING ); +} + +void Flu_File_Chooser :: myComputerCB() +{ + cd( "/" ); +} + +void Flu_File_Chooser :: documentsCB() +{ + cd( userDocs.c_str() ); +} + +Flu_File_Chooser :: FileInput :: FileInput( int x, int y, int w, int h, const char *l, Flu_File_Chooser *c ) + : Fl_Input( x, y, w, h, l ) +{ + chooser = c; +} + +Flu_File_Chooser :: FileInput :: ~FileInput() +{ +} + +int Flu_File_Chooser :: FileInput :: handle( int event ) +{ + if( event == FL_KEYDOWN ) + { + if( Fl::event_key(FL_Tab) ) + { + chooser->filenameTabCallback = true; + FluSimpleString v(value()); +#ifdef WIN32 + // turn "C:" into "C:\" + if( v.size() >= 2 ) + if( v[1] == ':' && v[2] == '\0' ) + { + v += "/"; + value( v.c_str() ); + position( size(), size() ); + } +#endif + chooser->delayedCd = v + "*"; + Fl::add_timeout( 0.0f, Flu_File_Chooser::delayedCdCB, chooser ); + return 1; + } + else if( Fl::event_key(FL_Left) ) + { + if( Fl_Input::position() == 0 ) + return 1; + else + return Fl_Input::handle( event ); + } + else if( Fl::event_key(FL_Right) ) + { + if( Fl_Input::position() == (int)strlen(Fl_Input::value()) ) + return 1; + else + return Fl_Input::handle( event ); + } + else if( Fl::event_key(FL_Up) || Fl::event_key(FL_Down) ) + { + chooser->getEntryContainer()->take_focus(); + if( !chooser->lastSelected ) + { + if( chooser->getEntryGroup()->children() ) + { + Flu_File_Chooser::Entry *e = (Flu_File_Chooser::Entry*)chooser->getEntryGroup()->child(0); + e->selected = true; + chooser->lastSelected = e; + e->redraw(); + } + } + return chooser->getEntryContainer()->handle( event ); + } + } + + return Fl_Input::handle( event ); +} + +Flu_File_Chooser :: PreviewTile :: PreviewTile( int x, int y, int w, int h, Flu_File_Chooser *c ) + : Fl_Tile( x, y, w, h ) +{ + chooser = c; +} + +int Flu_File_Chooser :: PreviewTile :: handle( int event ) +{ + // if we're not in preview mode, then the user isn't allowed to resize the tile + if( !chooser->previewBtn->value() ) + return Fl_Group::handle( event ); + if( event == FL_DRAG ) + { + // the user is probably dragging to resize the columns + // update the sizes for each entry + chooser->updateEntrySizes(); + chooser->redraw(); + } + return Fl_Tile::handle(event); +} + +Flu_File_Chooser :: PreviewWidgetBase :: PreviewWidgetBase() + : Fl_Group( 0, 0, 0, 0 ) +{ +} + +Flu_File_Chooser :: PreviewWidgetBase :: ~PreviewWidgetBase() +{ +} + +Flu_File_Chooser :: PreviewGroup :: PreviewGroup( int x, int y, int w, int h, Flu_File_Chooser *c ) + : Fl_Group( x, y, w, h ) +{ + box( FL_DOWN_BOX ); + align( FL_ALIGN_CENTER | FL_ALIGN_CLIP ); + labelsize( 60 ); + labelfont( FL_HELVETICA ); + chooser = c; + handled = 0; + lastFile = ""; +} + +void Flu_File_Chooser :: PreviewGroup :: draw() +{ + if( !chooser->previewBtn->value() ) + return; + + if( file.size() == 0 ) + return; + + FILE *f = fopen( file.c_str(), "rb" ); + if( !f ) + { + label( "" ); + Fl_Group::draw(); + return; + } + fclose( f ); + + if( lastFile != file ) + { + lastFile = file; + + handled = 0; + PreviewWidgetBase *next; + for( int i = chooser->previewHandlers.size()-1; i >= 0; i-- ) + { + next = chooser->previewHandlers[i]; + next->hide(); + if( !handled ) + { + Fl_Group *p = next->parent(); + Fl_Group::add( next ); + if( next->preview( file.c_str() ) != 0 ) + { + handled = next; + } + Fl_Group::remove( *next ); + if( p ) + p->add( next ); + } + } + } + + if( handled == 0 ) + { + label( "?" ); + Fl_Group::draw(); + } + else + { + label( "" ); + Fl_Group *p = handled->parent(); + handled->show(); + Fl_Group::add( handled ); + handled->resize( x()+Fl::box_dx(box()), y()+Fl::box_dy(box()), + w()-Fl::box_dw(box()), h()-Fl::box_dh(box()) ); + Fl_Group::draw(); + Fl_Group::remove( *handled ); + handled->hide(); + if( p ) + p->add( handled ); + } +} + +// adapted from Fl_File_Chooser2.cxx : update_preview() +int Flu_File_Chooser :: ImgTxtPreview :: preview( const char *filename ) +{ + Fl_Shared_Image *img, // New image + *oldimg; // Old image + int pbw, pbh; // Width and height of preview box + int w, h; // Width and height of preview image + + window()->cursor( FL_CURSOR_WAIT ); + Fl::check(); + + img = Fl_Shared_Image::get( filename ); + if( img ) + { + window()->cursor( FL_CURSOR_DEFAULT ); + Fl::check(); + } + + oldimg = (Fl_Shared_Image*)image(); + if( oldimg ) + oldimg->release(); + image(0); + + if( !img ) + { + // Try reading the first 1k of data for a label... + FILE *f = fopen( filename, "rb" ); + if( f ) + { + int bytes = fread( previewTxt, 1, sizeof(previewTxt) - 1, f ); + previewTxt[bytes] = '\0'; + fclose( f ); + } + else + return 0; + + window()->cursor( FL_CURSOR_DEFAULT ); + Fl::check(); + + // Scan the buffer for printable chars... + unsigned char *ptr; + for( ptr = previewTxt; *ptr && (isprint(*ptr) || isspace(*ptr)); ptr++ ) {} + + if( *ptr || ptr == previewTxt ) + { + // Non-printable file - can't handle + return 0; + } + else + { + // Show the first 1k of text... + label( (const char*)previewTxt ); + align((Fl_Align)(FL_ALIGN_CLIP | FL_ALIGN_INSIDE | FL_ALIGN_LEFT | FL_ALIGN_TOP)); + labelsize( 12 ); + labelfont( FL_COURIER ); + } + } + else if( img->w() > 0 && img->h() > 0 ) + { + + pbw = this->w() - 20; + pbh = this->h() - 20; + pbw = (pbw < 10) ? 10 : pbw; + pbh = (pbh < 10) ? 10 : pbh; + + if( img->w() > pbw || img->h() > pbh ) + { + w = pbw; + h = int(float(w*img->h()) / float(img->w())); + + if( h > pbh ) + { + h = pbh; + w = int(float(h*img->w()) / float(img->h())); + } + + oldimg = (Fl_Shared_Image *)img->copy(w, h); + image((Fl_Image *)oldimg); + + img->release(); + } + else + image((Fl_Image *)img); + + align( FL_ALIGN_CLIP ); + label(0); + } + + redraw(); + + return 1; +} + +void Flu_File_Chooser :: previewCB() +{ + if( previewBtn->value() ) + { + fileGroup->resize( fileGroup->x(), fileGroup->y(), previewTile->last-fileGroup->x(), fileGroup->h() ); + previewGroup->resize( previewTile->last, previewGroup->y(), previewTile->w()-fileGroup->w(), previewGroup->h() ); + previewGroup->show(); + } + else + { + previewTile->last = previewGroup->x(); + fileGroup->resize( fileGroup->x(), fileGroup->y(), previewTile->w(), fileGroup->h() ); + previewGroup->resize( previewTile->x()+previewTile->w(), previewGroup->y(), 0, previewGroup->h() ); + previewGroup->hide(); + } + previewGroup->redraw(); + previewTile->init_sizes(); + fileDetailsGroup->parent()->init_sizes(); + updateEntrySizes(); + redraw(); + if( previewBtn->value() ) + { + Fl::check(); + previewGroup->redraw(); + } +} + +void Flu_File_Chooser :: sortCB( Fl_Widget *w ) +{ + // if the sort method is already selected, toggle the REVERSE bit + if( w == detailNameBtn ) + { + if( sortMethod & SORT_NAME ) + sortMethod ^= SORT_REVERSE; + else + sortMethod = SORT_NAME; + } + else if( w == detailSizeBtn ) + { + if( sortMethod & SORT_SIZE ) + sortMethod ^= SORT_REVERSE; + else + sortMethod = SORT_SIZE; + } + else if( w == detailDateBtn ) + { + if( sortMethod & SORT_DATE ) + sortMethod ^= SORT_REVERSE; + else + sortMethod = SORT_DATE; + } + else if( w == detailTypeBtn ) + { + if( sortMethod & SORT_TYPE ) + sortMethod ^= SORT_REVERSE; + else + sortMethod = SORT_TYPE; + } + + bool reverse = ( sortMethod & SORT_REVERSE ); + detailNameBtn->label( detailTxt[0].c_str() ); + detailSizeBtn->label( detailTxt[1].c_str() ); + detailDateBtn->label( detailTxt[2].c_str() ); + detailTypeBtn->label( detailTxt[3].c_str() ); + switch( sortMethod & ~SORT_REVERSE ) + { + case SORT_NAME: detailNameBtn->label( reverse ? dArrow[0].c_str() : uArrow[0].c_str() ); break; + case SORT_SIZE: detailSizeBtn->label( reverse ? dArrow[1].c_str() : uArrow[1].c_str() ); break; + case SORT_DATE: detailDateBtn->label( reverse ? dArrow[2].c_str() : uArrow[2].c_str() ); break; + case SORT_TYPE: detailTypeBtn->label( reverse ? dArrow[3].c_str() : uArrow[3].c_str() ); break; + } + + filelist->sort(); + filedetails->sort(); +} + +Flu_File_Chooser :: CBTile :: CBTile( int x, int y, int w, int h, Flu_File_Chooser *c ) + : Fl_Tile( x, y, w, h ) +{ + chooser = c; +} + +int Flu_File_Chooser :: CBTile :: handle( int event ) +{ + if( event == FL_DRAG ) + { + // the user is probably dragging to resize the columns + // update the sizes for each entry + chooser->updateEntrySizes(); + chooser->redraw(); + } + return Fl_Tile::handle(event); +} + +Flu_File_Chooser :: FileColumns :: FileColumns( int x, int y, int w, int h, Flu_File_Chooser *c ) + : Fl_Tile( x, y, w, h ) +{ + chooser = c; + + W1 = int(float(w)*0.35f); + W2 = int(float(w)*0.20f); + W3 = int(float(w)*0.15f); + W4 = w-W1-W2-W3; + + Fl_Box *box = new Fl_Box( x+50, y, w-200, h ); + add_resizable( *box ); + c->detailNameBtn = new Flu_Button( x, y, W1, h, detailTxt[0].c_str() ); + c->detailNameBtn->align( FL_ALIGN_CLIP ); + c->detailNameBtn->callback( Flu_File_Chooser::_sortCB, c ); + { + CBTile *tile = new CBTile( x+W1, y, W2+W3+W4, h, c ); + Fl_Box *box = new Fl_Box( tile->x()+50, tile->y(), tile->w()-150, tile->h() ); + tile->add_resizable( *box ); + c->detailTypeBtn = new Flu_Button( x+W1, y, W2, h, detailTxt[3].c_str() ); + c->detailTypeBtn->align( FL_ALIGN_CLIP ); + c->detailTypeBtn->callback( Flu_File_Chooser::_sortCB, c ); + { + CBTile *tile = new CBTile( x+W1+W2, y, W3+W4, h, c ); + Fl_Box *box = new Fl_Box( tile->x()+50, tile->y(), tile->w()-100, tile->h() ); + tile->add_resizable( *box ); + c->detailSizeBtn = new Flu_Button( x+W1+W2, y, W3, h, detailTxt[1].c_str() ); + c->detailSizeBtn->align( FL_ALIGN_CLIP ); + c->detailSizeBtn->callback( Flu_File_Chooser::_sortCB, c ); + c->detailDateBtn = new Flu_Button( x+W1+W2+W3, y, W4, h, detailTxt[2].c_str() ); + c->detailDateBtn->align( FL_ALIGN_CLIP ); + c->detailDateBtn->callback( Flu_File_Chooser::_sortCB, c ); + tile->end(); + } + tile->end(); + } + end(); +} + +Flu_File_Chooser :: FileColumns :: ~FileColumns() +{ +} + +void Flu_File_Chooser :: FileColumns :: resize( int x, int y, int w, int h ) +{ + // TODO resize the buttons/tiles according to their stored relative sizes + Fl_Tile::resize( x, y, w, h ); +} + +int Flu_File_Chooser :: FileColumns :: handle( int event ) +{ + if( event == FL_DRAG ) + { + // the user is probably dragging to resize the columns + // update the sizes for each entry + chooser->updateEntrySizes(); + chooser->redraw(); + } + return Fl_Tile::handle(event); +} + +void Flu_File_Chooser :: filenameCB() +{ + printf( "filenameCB\n" ); + filenameEnterCallback = true; + //cd( filename.value() ); + okCB(); +} + +inline bool _isProbablyAPattern( const char *s ) +{ + return( strpbrk( s, "*;|[]?" ) != NULL ); +} + +void Flu_File_Chooser :: okCB() +{ + // if exactly one directory is selected and we are not choosing directories, + // cd to that directory. + if( !( selectionType & DIRECTORY ) && !( selectionType & STDFILE ) ) + { + Fl_Group *g = getEntryGroup(); + FluSimpleString dir; + int count = 0; + for( int i = 0; i < g->children(); i++ ) + { + if( ((Flu_File_Chooser::Entry*)g->child(i))->selected ) + { + count++; + dir = ((Flu_File_Chooser::Entry*)g->child(i))->filename; + } + } + if( count == 1 ) + { + FluSimpleString path = currentDir + dir; + if( fl_filename_isdir( path.c_str() ) ) + { + cd( dir.c_str() ); + return; + } + } + } + + // only hide if the filename is not blank or the user is choosing directories, + // in which case use the current directory + + if( selectionType & DIRECTORY || + ( (selectionType & STDFILE) && fl_filename_isdir( (currentDir+filename.value()).c_str() ) ) + ) + { +#ifdef WIN32 + if( myComputerTxt == filename.value() ) + { + myComputerCB(); + return; + } +#endif + if( !(selectionType & MULTI ) ) + { + if( strlen( filename.value() ) != 0 ) + cd( filename.value() ); + filename.value( currentDir.c_str() ); + filename.position( filename.size(), filename.size() ); + } + do_callback(); + hide(); + } + else + { + if( strlen( filename.value() ) != 0 ) + { + if( _isProbablyAPattern( filename.value() ) ) + { + cd( filename.value() ); + return; + } +#ifdef WIN32 + if( filename.value()[1] == ':' ) +#else + if( filename.value()[0] == '/' ) +#endif + if( fl_filename_isdir( filename.value() ) ) + { + filename.value( "" ); + return; + } + + // prepend the path + FluSimpleString path = currentDir + filename.value(); + filename.value( path.c_str() ); + filename.position( filename.size(), filename.size() ); + do_callback(); + hide(); + } + } +} + +void Flu_File_Chooser :: homeCB() +{ +#ifdef WIN32 + cd( "/" ); +#else + cd( userHome.c_str() ); +#endif +} + +void Flu_File_Chooser :: desktopCB() +{ + cd( userDesktop.c_str() ); +} + +#define QSCANL( field ) \ + while( ((Flu_File_Chooser::Entry*)array[left])->field < \ + ((Flu_File_Chooser::Entry*)array[pivot])->field ) left++ +#define QSCANR( field ) \ + while( ((Flu_File_Chooser::Entry*)array[right])->field > \ + ((Flu_File_Chooser::Entry*)array[pivot])->field ) right-- + +#define RQSCANL( field ) \ + while( ((Flu_File_Chooser::Entry*)array[left])->field > \ + ((Flu_File_Chooser::Entry*)array[pivot])->field ) left++ +#define RQSCANR( field ) \ + while( ((Flu_File_Chooser::Entry*)array[right])->field < \ + ((Flu_File_Chooser::Entry*)array[pivot])->field ) right-- + +#define CASE_QSCANL( field ) \ + while( casecompare( ((Flu_File_Chooser::Entry*)array[left])->field, \ + ((Flu_File_Chooser::Entry*)array[pivot])->field ) < 0 ) left++ +#define CASE_QSCANR( field ) \ + while( casecompare( ((Flu_File_Chooser::Entry*)array[right])->field, \ + ((Flu_File_Chooser::Entry*)array[pivot])->field ) > 0 ) right-- + +#define CASE_RQSCANL( field ) \ + while( casecompare( ((Flu_File_Chooser::Entry*)array[left])->field, \ + ((Flu_File_Chooser::Entry*)array[pivot])->field ) > 0 ) left++ +#define CASE_RQSCANR( field ) \ + while( casecompare( ((Flu_File_Chooser::Entry*)array[right])->field, \ + ((Flu_File_Chooser::Entry*)array[pivot])->field ) < 0 ) right-- + +#define CUSTOM_QSCANL( field ) \ + while( customSort( ((Flu_File_Chooser::Entry*)array[left])->field, \ + ((Flu_File_Chooser::Entry*)array[pivot])->field ) < 0 ) left++ +#define CUSTOM_QSCANR( field ) \ + while( customSort( ((Flu_File_Chooser::Entry*)array[right])->field, \ + ((Flu_File_Chooser::Entry*)array[pivot])->field ) > 0 ) right-- + +#define CUSTOM_RQSCANL( field ) \ + while( customSort( ((Flu_File_Chooser::Entry*)array[left])->field, \ + ((Flu_File_Chooser::Entry*)array[pivot])->field ) > 0 ) left++ +#define CUSTOM_RQSCANR( field ) \ + while( customSort( ((Flu_File_Chooser::Entry*)array[right])->field, \ + ((Flu_File_Chooser::Entry*)array[pivot])->field ) < 0 ) right-- + +void Flu_File_Chooser :: _qSort( int how, bool caseSort, Fl_Widget **array, int low, int high ) +{ + int left, right, pivot; + Fl_Widget *temp; + bool reverse = ( how & SORT_REVERSE ); + + if( high > low ) + { + left = low; + right = high; + pivot = low; + + while( right >= left ) + { + switch( how & ~SORT_REVERSE ) + { + case SORT_NAME: + if( reverse ) + { + if( customSort ) + { + CUSTOM_RQSCANL( filename.c_str() ); + CUSTOM_RQSCANR( filename.c_str() ); + } + else if( !caseSort ) + { + CASE_RQSCANL( filename ); + CASE_RQSCANR( filename ); + } + else + { + RQSCANL( filename ); + RQSCANR( filename ); + } + } + else + { + if( customSort ) + { + CUSTOM_QSCANL( filename.c_str() ); + CUSTOM_QSCANR( filename.c_str() ); + } + else if( !caseSort ) + { + CASE_QSCANL( filename ); + CASE_QSCANR( filename ); + } + else + { + QSCANL( filename ); + QSCANR( filename ); + } + } + break; + case SORT_SIZE: + if( reverse ) + { + RQSCANL( isize ); + RQSCANR( isize ); + } + else + { + QSCANL( isize ); + QSCANR( isize ); + } + break; + case SORT_DATE: + if( reverse ) + { + RQSCANL( idate ); + RQSCANR( idate ); + } + else + { + QSCANL( idate ); + QSCANR( idate ); + } + break; + case SORT_TYPE: + if( reverse ) + { + RQSCANL( description ); + RQSCANR( description ); + } + else + { + QSCANL( description ); + QSCANR( description ); + } + break; + } + + if( left > right ) + break; + + temp = array[left]; + array[left] = array[right]; + array[right] = temp; + left++; + right--; + } + + _qSort( how, caseSort, array, low, right ); + _qSort( how, caseSort, array, left, high ); + } +} + +Flu_File_Chooser :: FileList :: FileList( int x, int y, int w, int h, Flu_File_Chooser *c ) + : Flu_Wrap_Group( x, y, w, h ) +{ + chooser = c; + numDirs = 0; +} + +Flu_File_Chooser :: FileList :: ~FileList() +{ +} + +void Flu_File_Chooser :: FileList :: sort( int n ) +{ + if( n != -1 ) + numDirs = n; + if( children() == 0 ) + return; + // the directories are already first. sort the directories then the names lexigraphically + Flu_File_Chooser::_qSort( chooser->sortMethod, chooser->caseSort, (Fl_Widget**)array(), 0, numDirs-1 ); + Flu_File_Chooser::_qSort( chooser->sortMethod, chooser->caseSort, (Fl_Widget**)array(), numDirs, children()-1 ); + chooser->redraw(); +} + +int Flu_File_Chooser :: FileList :: handle( int event ) +{ + if( event == FL_FOCUS || event == FL_UNFOCUS ) + return 1; + if( Flu_Wrap_Group::handle( event ) ) + return 1; + // if push on no file, unselect all files and turn off editing mode + if( event == FL_PUSH && !Fl::event_key( FL_SHIFT ) && !Fl::event_key( FL_CTRL ) ) + { + chooser->unselect_all(); + chooser->filename.value( "" ); + chooser->filename.position( chooser->filename.size(), chooser->filename.size() ); + + if( Fl::event_button3() ) + return chooser->popupContextMenu( NULL ); + + return 1; + } + else if( event == FL_KEYDOWN ) + { + if( Fl::event_key( FL_Delete ) ) + { + // recycle by default, unless the shift key is held down + chooser->trashCB( !Fl::event_state( FL_SHIFT ) ); + return 1; + } + + Flu_File_Chooser::Entry *e = chooser->lastSelected; + if( !e ) + { + for( int i = 0; i < children(); i++ ) + if( ((Flu_File_Chooser::Entry*)child(i))->selected ) + { + e = (Flu_File_Chooser::Entry*)child(i); + break; + } + } + if( e ) + { + switch( Fl::event_key() ) + { + case FL_Up: e = (Flu_File_Chooser::Entry*)previous( e ); + if( !e && children() ) e = (Flu_File_Chooser::Entry*)child(0); break; + case FL_Down: e = (Flu_File_Chooser::Entry*)next( e ); + if( !e && children() ) e = (Flu_File_Chooser::Entry*)child(children()-1); break; + case FL_Left: e = (Flu_File_Chooser::Entry*)left( e ); break; + case FL_Right: e = (Flu_File_Chooser::Entry*)right( e ); break; + case FL_Home: if( children() ) e = (Flu_File_Chooser::Entry*)child(0); break; + case FL_End: if( children() ) e = (Flu_File_Chooser::Entry*)child(children()-1); break; + case FL_Enter: + chooser->filenameEnterCallback = true; + //chooser->cd( e->filename.c_str() ); + chooser->okCB(); + return 1; + case ' ': + chooser->cd( e->filename.c_str() ); + return 1; + default: e = 0; break; + } + if( e ) + { + chooser->unselect_all(); + e->selected = true; + chooser->lastSelected = e; + chooser->filename.value( e->filename.c_str() ); + chooser->filename.position( chooser->filename.size(), chooser->filename.size() ); + chooser->redraw(); + if( e->type == ENTRY_FILE ) + chooser->previewGroup->file = chooser->currentDir + e->filename; + scroll_to( e ); + return 1; + } + } + } + + return 0; +} + +Flu_File_Chooser :: FileDetails :: FileDetails( int x, int y, int w, int h, Flu_File_Chooser *c ) + : Fl_Pack( x, y, w, h ) +{ + chooser = c; + numDirs = 0; +} + +Flu_File_Chooser :: FileDetails :: ~FileDetails() +{ +} + +void Flu_File_Chooser :: FileDetails :: scroll_to( Fl_Widget *w ) +{ + // we know all the widgets are the same height + // so just find this widget and scroll to the accumulated height + int H = 0; + for( int i = 0; i < children(); i++ ) + { + if( child(i) == w ) + { + if( H > (int)chooser->filescroll->scrollbar.maximum() ) + H = (int)chooser->filescroll->scrollbar.maximum(); + chooser->filescroll->position( 0, H ); + return; + } + H += w->h(); + } +} + +void Flu_File_Chooser :: FileDetails :: sort( int n ) +{ + if( n != -1 ) + numDirs = n; + if( children() == 0 ) + return; + // the directories are already first. sort the directories then the names lexigraphically + Flu_File_Chooser::_qSort( chooser->sortMethod, chooser->caseSort, (Fl_Widget**)array(), 0, numDirs-1 ); + Flu_File_Chooser::_qSort( chooser->sortMethod, chooser->caseSort, (Fl_Widget**)array(), numDirs, children()-1 ); + chooser->redraw(); +} + +Fl_Widget* Flu_File_Chooser :: FileDetails :: next( Fl_Widget* w ) +{ + for( int i = 0; i < children()-1; i++ ) + { + if( w == child(i) ) + return child(i+1); + } + return NULL; +} + +Fl_Widget* Flu_File_Chooser :: FileDetails :: previous( Fl_Widget* w ) +{ + for( int i = 1; i < children(); i++ ) + { + if( w == child(i) ) + return child(i-1); + } + return NULL; +} + +int Flu_File_Chooser :: FileDetails :: handle( int event ) +{ + if( event == FL_FOCUS || event == FL_UNFOCUS ) + return 1; + if( Fl_Pack::handle( event ) ) + return 1; + else if( event == FL_PUSH ) + return 1; + + else if( event == FL_KEYDOWN ) + { + if( Fl::event_key( FL_Delete ) ) + { + // recycle by default, unless the shift key is held down + chooser->trashCB( !Fl::event_state( FL_SHIFT ) ); + return 1; + } + + Flu_File_Chooser::Entry *e = chooser->lastSelected; + if( !e ) + { + for( int i = 0; i < children(); i++ ) + if( ((Flu_File_Chooser::Entry*)child(i))->selected ) + { + e = (Flu_File_Chooser::Entry*)child(i); + break; + } + } + if( e ) + { + switch( Fl::event_key() ) + { + case FL_Up: e = (Flu_File_Chooser::Entry*)previous( e ); + if( !e && children() ) e = (Flu_File_Chooser::Entry*)child(0); break; + case FL_Down: e = (Flu_File_Chooser::Entry*)next( e ); + if( !e && children() ) e = (Flu_File_Chooser::Entry*)child(children()-1); break; + case FL_Home: if( children() ) e = (Flu_File_Chooser::Entry*)child(0); break; + case FL_End: if( children() ) e = (Flu_File_Chooser::Entry*)child(children()-1); break; + case FL_Enter: + chooser->filenameEnterCallback = true; + //chooser->cd( e->filename.c_str() ); + chooser->okCB(); + return 1; + case ' ': + chooser->cd( e->filename.c_str() ); + return 1; + default: e = 0; break; + } + if( e ) + { + chooser->unselect_all(); + e->selected = true; + chooser->lastSelected = e; + chooser->filename.value( e->filename.c_str() ); + chooser->filename.position( chooser->filename.size(), chooser->filename.size() ); + chooser->redraw(); + scroll_to( e ); + return 1; + } + } + } + + return 0; +} + +Flu_File_Chooser :: Entry :: Entry( const char* name, int t, bool d, Flu_File_Chooser *c ) + : Fl_Input( 0, 0, 0, 0 ) +{ + resize( 0, 0, DEFAULT_ENTRY_WIDTH, 20 ); + textsize( 12 ); + box( FL_BORDER_BOX ); + when( FL_WHEN_RELEASE_ALWAYS | FL_WHEN_ENTER_KEY_ALWAYS ); + callback( _inputCB, this ); + filename = name; + selected = false; + chooser = c; + details = d; + type = t; + icon = NULL; + editMode = 0; + description = ""; + + if( type == ENTRY_FILE && (c->selectionType & DEACTIVATE_FILES) ) + { + textcolor( FL_GRAY ); + deactivate(); + } + + updateSize(); + updateIcon(); +} + +void Flu_File_Chooser :: Entry :: updateIcon() +{ + Flu_File_Chooser::FileTypeInfo *tt = NULL; + if( type==ENTRY_MYCOMPUTER ) + { + icon = &computer; + description = myComputerTxt; + } + else if( type==ENTRY_MYDOCUMENTS ) + { + icon = &documents; + description = myDocumentsTxt; + } + else if( type==ENTRY_DRIVE ) + { + //icon = &disk_drive; + //description = ""; + } + else if( type==ENTRY_DIR || type==ENTRY_FAVORITE ) + tt = Flu_File_Chooser::find_type( NULL ); + else + { + const char *dot = strrchr( filename.c_str(), '.' ); + if( dot ) + { + tt = Flu_File_Chooser::find_type( dot+1 ); + if( !tt ) + description = dot+1; + } + } + if( tt ) + { + icon = tt->icon; + description = tt->type; + } + // if there is no icon, assign a default one + if( !icon && type==ENTRY_FILE && !(chooser->selectionType & DEACTIVATE_FILES) ) + icon = chooser->defaultFileIcon; + if( type==ENTRY_FAVORITE ) + icon = &little_favorites; + + toolTip = detailTxt[0] + ": " + filename; + if( type == ENTRY_FILE ) + toolTip += "\n" + detailTxt[1] +": " + filesize; + toolTip += "\n" + detailTxt[3] + ": " + description; + tooltip( toolTip.c_str() ); + + redraw(); +} + +void Flu_File_Chooser :: resize( int x, int y, int w, int h ) +{ + Fl_Double_Window::resize( x, y, w, h ); + if( fileListWideBtn->value() ) + filelist->scrollbar.linesize( filelist->w() ); + else if( fileListBtn->value() ) + filelist->scrollbar.linesize( DEFAULT_ENTRY_WIDTH+4 ); + // round position to nearest multiple of the linesize + ((Fl_Valuator*)&(filelist->scrollbar))->value( filelist->w()*(filelist->scrollbar.value()/filelist->w()) ); + for( int i = 0; i < filelist->children(); i++ ) + ((Entry*)filelist->child(i))->updateSize(); +} + +void Flu_File_Chooser :: listModeCB() +{ + bool listMode = !fileDetailsBtn->value() || ( currentDir == FAVORITES_UNIQUE_STRING ); + if( listMode ) + { + while( filedetails->children() ) + filelist->add( filedetails->child(0) ); + } + else + { + while( filelist->children() ) + filedetails->add( filelist->child(0) ); + } + + resize( x(), y(), w(), h() ); + updateEntrySizes(); + if( listMode ) + { + fileDetailsGroup->hide(); + filelist->show(); + filelist->redraw(); + filelist->parent()->resizable( filelist ); + } + else + { + filelist->hide(); + fileDetailsGroup->show(); + fileDetailsGroup->parent()->resizable( fileDetailsGroup ); + } + //redraw(); +} + +void Flu_File_Chooser :: Entry :: updateSize() +{ + if( type==ENTRY_FAVORITE || chooser->fileListWideBtn->value() ) + { + resize( x(), y(), chooser->filelist->w()-4, 20 ); + } + else + resize( x(), y(), DEFAULT_ENTRY_WIDTH, 20 ); + + details = chooser->fileDetailsBtn->value() && ( type != ENTRY_FAVORITE ); + + if( details ) + { + nameW = chooser->detailNameBtn->w(); + typeW = chooser->detailTypeBtn->w(); + sizeW = chooser->detailSizeBtn->w(); + dateW = chooser->detailDateBtn->w(); + resize( x(), y(), chooser->filedetails->w(), 20 ); + } + else + nameW = w(); + + // how big is the icon? + int iW = 0, iH = 0; + if( icon ) + { + iW = icon->w()+2; + iH = icon->h(); + } + + fl_font( textfont(), textsize() ); + + // measure the name and see if we need a truncated version + int W = 0, H = 0; + fl_measure( filename.c_str(), W, H ); + if( W > nameW-iW ) + { + // progressively strip characters off the end of the name until + // it fits with "..." at the end + if( altname[0] != '\0' ) + shortname = altname; + else + shortname = filename; + int len = shortname.size(); + while( W > (nameW-iW) && len > 3 ) + { + shortname[len-3] = '.'; + shortname[len-2] = '.'; + shortname[len-1] = '.'; + shortname[len] = '\0'; + len--; + W = 0; + fl_measure( shortname.c_str(), W, H ); + } + } + else + shortname = ""; + + // measure the description and see if we need a truncated version + shortDescription = ""; + if( details ) + { + W = 0; H = 0; + fl_measure( description.c_str(), W, H ); + if( W > typeW-4 ) + { + // progressively strip characters off the end of the description until + // it fits with "..." at the end + shortDescription = description; + int len = shortDescription.size(); + while( W > typeW-4 && len > 3 ) + { + shortDescription[len-3] = '.'; + shortDescription[len-2] = '.'; + shortDescription[len-1] = '.'; + shortDescription[len] = '\0'; + len--; + W = 0; + fl_measure( shortDescription.c_str(), W, H ); + } + } + } + + redraw(); +} + +Flu_File_Chooser :: Entry :: ~Entry() +{ +} + +void Flu_File_Chooser :: Entry :: inputCB() +{ + redraw(); + + // if the user tried to change the string to nothing, restore the original name and turn off edit mode + if( strlen( value() ) == 0 ) + { + editMode = 0; + return; + } + + // if input text is different from filename, try to change the filename + if( strcmp( value(), filename.c_str() ) != 0 ) + { + // build the total old filename and new filename + FluSimpleString oldName = chooser->currentDir + filename, + newName = chooser->currentDir + value(); + // see if new name already exists + struct stat s; + int result = ::stat( newName.c_str(), &s ); + if( result == 0 ) + { + fl_alert( fileExistsErrTxt.c_str(), newName.c_str() ); + return; // leave editing on + } + + if( rename( oldName.c_str(), newName.c_str() ) == -1 ) + { + fl_alert( renameErrTxt.c_str(), oldName.c_str(), newName.c_str() ); + //return; // leave editing on + } + else + { + filename = value(); + updateSize(); + updateIcon(); + } + // QUESTION: should we set the chooser filename to the modified name? + //chooser->filename.value( filename.c_str() ); + } + + // only turn off editing if we have a successful name change + editMode = 0; +} + +Fl_Group* Flu_File_Chooser :: getEntryGroup() +{ + return (!fileDetailsBtn->value() || currentDir == FAVORITES_UNIQUE_STRING ) ? &(filelist->group) : filedetails; +} + +Fl_Group* Flu_File_Chooser :: getEntryContainer() +{ + return (!fileDetailsBtn->value() || currentDir == FAVORITES_UNIQUE_STRING ) ? (Fl_Group*)filelist : filedetails; +} + +int Flu_File_Chooser :: Entry :: handle( int event ) +{ + if( editMode ) + { + // if user hits 'Escape' while in edit mode, restore the original name and turn off edit mode + if( event == FL_KEYDOWN && Fl::event_key( FL_Escape ) ) + { + editMode = 0; + redraw(); + if( selected ) + chooser->trashBtn->activate(); + return 1; + } + return Fl_Input::handle( event ); + } + + if( event == FL_FOCUS || event == FL_UNFOCUS ) + return 1; + + if( event == FL_ENTER || event == FL_LEAVE ) + return 1; + + Fl_Group *g = chooser->getEntryGroup(); + if( event == FL_PUSH ) + { + if( Fl::event_clicks() > 0 ) + { + Fl::event_clicks(0); + // double-clicking a favorite cd's to it + if( type == ENTRY_FAVORITE ) + { + chooser->delayedCd = filename; + Fl::add_timeout( 0.0f, Flu_File_Chooser::delayedCdCB, chooser ); + } + // double-clicking a directory cd's to it + else if( type != ENTRY_FILE ) + { +#ifdef WIN32 + if( filename[1] == ':' ) + chooser->delayedCd = filename; + else +#endif + chooser->delayedCd = chooser->currentDir + filename + "/"; + Fl::add_timeout( 0.0f, Flu_File_Chooser::delayedCdCB, chooser ); + } + // double-clicking a file chooses it if we are in file selection mode + else if( !(chooser->selectionType & DIRECTORY) || (chooser->selectionType & STDFILE) ) + { + Fl::add_timeout( 0.0f, Flu_File_Chooser::selectCB, chooser ); + } + if( selected ) + chooser->trashBtn->activate(); + return 1; + } + + /* + if( selected && !Fl::event_button3() && !Fl::event_state(FL_CTRL) && !Fl::event_state(FL_SHIFT) ) + { + // only allow editing of certain files and directories + if( chooser->fileEditing && ( type == ENTRY_FILE || type == ENTRY_DIR ) ) + { + // if already selected, switch to input mode + Fl::add_timeout( 1.0, _editCB, this ); + return 1; + } + } + + else*/ + if( chooser->selectionType & MULTI ) + { + if( Fl::event_state(FL_CTRL) ) + { + selected = !selected; // toggle this item + chooser->lastSelected = this; + if( type == ENTRY_FILE ) + chooser->previewGroup->file = chooser->currentDir + filename; + chooser->redraw(); + chooser->getEntryContainer()->take_focus(); + } + else if( Fl::event_state(FL_SHIFT) ) + { + // toggle all items from the last selected item to this one + if( chooser->lastSelected == NULL ) + { + selected = true; + chooser->lastSelected = this; + if( type == ENTRY_FILE ) + chooser->previewGroup->file = chooser->currentDir + filename; + chooser->redraw(); + chooser->getEntryContainer()->take_focus(); + } + else + { + // get the index of the last selected item and this item + int lastindex = -1, thisindex = -1; + int i; + for( i = 0; i < g->children(); i++ ) + { + if( g->child(i) == chooser->lastSelected ) + lastindex = i; + if( g->child(i) == this ) + thisindex = i; + if( lastindex >= 0 && thisindex >= 0 ) + break; + } + if( lastindex >= 0 && thisindex >= 0 ) + { + // loop from this item to the last item, toggling each item except the last + int inc; + if( thisindex > lastindex ) + inc = -1; + else + inc = 1; + Entry *e; + for( i = thisindex; i != lastindex; i += inc ) + { + e = (Entry*)g->child(i); + e->selected = !e->selected; + e->redraw(); + } + chooser->lastSelected = this; + if( type == ENTRY_FILE ) + chooser->previewGroup->file = chooser->currentDir + filename; + chooser->redraw(); + chooser->getEntryContainer()->take_focus(); + } + } + } + else + { + chooser->unselect_all(); + selected = true; + chooser->lastSelected = this; + if( type == ENTRY_FILE ) + chooser->previewGroup->file = chooser->currentDir + filename; + chooser->redraw(); + chooser->getEntryContainer()->take_focus(); + } + + + if( !((chooser->selectionType & Flu_File_Chooser::DIRECTORY) || + (chooser->selectionType & Flu_File_Chooser::STDFILE)) && + ( Fl::event_state(FL_CTRL) || Fl::event_state(FL_SHIFT) ) ) + { + // if we are only choosing multiple files, don't allow a directory + // to be selected + Fl_Group *g = chooser->getEntryGroup(); + for( int i = 0; i < g->children(); i++ ) + { + Entry *e = (Entry*)g->child(i); + if( e->type == ENTRY_DIR ) + e->selected = false; + } + } + } + else + { + chooser->unselect_all(); + selected = true; + chooser->lastSelected = this; + if( type == ENTRY_FILE ) + chooser->previewGroup->file = chooser->currentDir + filename; + chooser->redraw(); + chooser->getEntryContainer()->take_focus(); + } + + //g->take_focus(); + + redraw(); + if( selected ) + chooser->trashBtn->activate(); + + if( Fl::event_button3() ) + return chooser->popupContextMenu( this ); + + // don't put the filename into the box if we are a directory but we are not choosing directories + // or if we are in SAVING mode + if( (chooser->selectionType & Flu_File_Chooser::DIRECTORY) || + (chooser->selectionType & Flu_File_Chooser::STDFILE) || + type==ENTRY_FILE ) + chooser->filename.value( filename.c_str() ); + else if( !(chooser->selectionType & Flu_File_Chooser::SAVING ) ) + chooser->filename.value( "" ); + chooser->filename.position( chooser->filename.size(), chooser->filename.size() ); + + return 1; + } + else if( event == FL_DRAG ) + { + if( chooser->selectionType & MULTI ) + { + // toggle all items from the last selected item to this one + if( chooser->lastSelected != NULL ) + { + selected = true; + // get the index of the last selected item and this item + int lastindex = -1, thisindex = -1; + int i; + for( i = 0; i < g->children(); i++ ) + { + if( g->child(i) == chooser->lastSelected ) + lastindex = i; + if( g->child(i) == this ) + thisindex = i; + if( lastindex >= 0 && thisindex >= 0 ) + break; + } + if( lastindex >= 0 && thisindex >= 0 ) + { + // loop from this item to the last item, toggling each item except the last + int inc; + if( thisindex > lastindex ) + inc = -1; + else + inc = 1; + Entry *e; + for( i = thisindex; i != lastindex; i += inc ) + { + e = (Entry*)g->child(i); + e->selected = !e->selected; + e->redraw(); + } + chooser->lastSelected = this; + if( type == ENTRY_FILE ) + chooser->previewGroup->file = chooser->currentDir + filename; + chooser->redraw(); + } + redraw(); + chooser->getEntryContainer()->take_focus(); + if( selected ) + chooser->trashBtn->activate(); + return 1; + } + } + } + return Fl_Widget::handle(event); +} + +void Flu_File_Chooser :: Entry :: editCB() +{ + // if already selected, switch to input mode + editMode = 2; + value( filename.c_str() ); + take_focus(); + // select the text up to but not including the extension + const char *dot = strrchr( filename.c_str(), '.' ); + if( dot ) + position( 0, dot-filename.c_str() ); + else + position( 0, filename.size() ); + chooser->trashBtn->deactivate(); + redraw(); +} + +int Flu_File_Chooser :: popupContextMenu( Entry *entry ) +{ + int type = entry ? entry->type : ENTRY_NONE; + const char *filename = entry ? entry->filename.c_str() : NULL; + char *ext = NULL; + + if( filename ) + ext = strrchr( (char*)filename, '.' ); + if( ext ) + { + ext = strdup( ext+1 ); // skip the '.' + for( unsigned int i = 0; i < strlen(ext); i++ ) + ext[i] = tolower( ext[i] ); + } + + enum { ACTION_NEW_FOLDER = -1, ACTION_RENAME = -2, ACTION_DELETE = -3 }; + + entryPopup.clear(); + switch( type ) + { + case ENTRY_NONE: // right click on nothing + entryPopup.add( contextMenuTxt[0].c_str(), 0, 0, (void*)ACTION_NEW_FOLDER ); + break; + + case ENTRY_DIR: + entryPopup.add( contextMenuTxt[1].c_str(), 0, 0, (void*)ACTION_RENAME ); + entryPopup.add( contextMenuTxt[2].c_str(), 0, 0, (void*)ACTION_DELETE ); + break; + + case ENTRY_FILE: + entryPopup.add( contextMenuTxt[1].c_str(), 0, 0, (void*)ACTION_RENAME ); + entryPopup.add( contextMenuTxt[2].c_str(), 0, 0, (void*)ACTION_DELETE ); + break; + + case ENTRY_FAVORITE: + entryPopup.add( contextMenuTxt[2].c_str(), 0, 0, (void*)ACTION_DELETE ); + break; + + case ENTRY_DRIVE: + break; + + case ENTRY_MYDOCUMENTS: + break; + + case ENTRY_MYCOMPUTER: + break; + } + + // add the programmable context handlers + for( unsigned int i = 0; i < contextHandlers.size(); i++ ) + { + if( !(contextHandlers[i].type & type) ) + continue; + if( type == ENTRY_FILE ) + if( contextHandlers[i].ext.size() && contextHandlers[i].ext != ext ) + continue; + entryPopup.add( contextHandlers[i].name.c_str(), 0, 0, (void*)i ); + } + if( ext ) + free( ext ); + + entryPopup.position( Fl::event_x(), Fl::event_y() ); + const Fl_Menu_Item *selection = entryPopup.popup(); + if( selection ) + { + int handler = (int)selection->user_data(); + switch( handler ) + { + case ACTION_NEW_FOLDER: + newFolderCB(); + break; + case ACTION_RENAME: + entry->editCB(); + /* + entry->editMode = 2; + entry->value( entry->filename.c_str() ); + entry->take_focus(); + entry->position( 0, entry->filename.size() ); + trashBtn->deactivate(); + */ + break; + case ACTION_DELETE: + // recycle by default, unless the shift key is held down + trashCB( !Fl::event_state( FL_SHIFT ) ); + break; + default: + contextHandlers[handler].callback( filename, type, contextHandlers[handler].callbackData ); + break; + } + } + else + return handle( FL_PUSH ); + return 1; +} + +void Flu_File_Chooser :: Entry :: draw() +{ + if( editMode ) + { + if( editMode == 2 ) + { + editMode--; + fl_draw_box( FL_FLAT_BOX, x(), y(), w(), h(), FL_WHITE ); + redraw(); + } + Fl_Input::draw(); + return; + } + + if( selected ) + { + fl_draw_box( FL_FLAT_BOX, x(), y(), w(), h(), FL_SELECTION_COLOR ); + fl_color( FL_WHITE ); + } + else + { + fl_draw_box( FL_FLAT_BOX, x(), y(), w(), h(), FL_WHITE ); + fl_color( FL_BLACK ); + } + + int X = x()+4; + if( icon ) + { + icon->draw( X, y()+h()/2-icon->h()/2 ); + X += icon->w()+2; + } + + fl_font( textfont(), textsize() ); + //fl_color( textcolor() ); + + if( shortname[0] != '\0' ) + fl_draw( shortname.c_str(), X, y(), nameW, h(), FL_ALIGN_LEFT ); + else if( altname[0] != '\0' ) + fl_draw( altname.c_str(), X, y(), nameW, h(), FL_ALIGN_LEFT ); + else + fl_draw( filename.c_str(), X, y(), nameW, h(), FL_ALIGN_LEFT ); + + X = x()+4 + nameW; + + if( details ) + { + if( shortDescription[0] != '\0' ) + fl_draw( shortDescription.c_str(), X, y(), typeW-4, h(), Fl_Align(FL_ALIGN_LEFT | FL_ALIGN_CLIP) ); + else + fl_draw( description.c_str(), X, y(), typeW-4, h(), Fl_Align(FL_ALIGN_LEFT | FL_ALIGN_CLIP) ); + + X += typeW; + + fl_draw( filesize.c_str(), X, y(), sizeW-4, h(), Fl_Align(FL_ALIGN_RIGHT | FL_ALIGN_CLIP) ); + + X += sizeW+4; + + fl_draw( date.c_str(), X, y(), dateW-4, h(), Fl_Align(FL_ALIGN_LEFT | FL_ALIGN_CLIP) ); + } +} + +void Flu_File_Chooser :: unselect_all() +{ + Fl_Group *g = getEntryGroup(); + Entry *e; + for( int i = 0; i < g->children(); i++ ) + { + e = ((Entry*)g->child(i)); + e->selected = false; + e->editMode = 0; + } + lastSelected = 0; + previewGroup->file = ""; + previewGroup->redraw(); + trashBtn->deactivate(); + redraw(); +} + +void Flu_File_Chooser :: select_all() +{ + if( !( selectionType & MULTI ) ) + return; + Fl_Group *g = getEntryGroup(); + Entry *e; + previewGroup->file = ""; + for( int i = 0; i < g->children(); i++ ) + { + e = ((Entry*)g->child(i)); + e->selected = true; + e->editMode = 0; + previewGroup->file = e->filename; + filename.value( e->filename.c_str() ); + } + lastSelected = 0; + previewGroup->redraw(); + trashBtn->deactivate(); + redraw(); +} + +void Flu_File_Chooser :: updateEntrySizes() +{ + filecolumns->W1 = detailNameBtn->w(); + filecolumns->W2 = detailTypeBtn->w(); + filecolumns->W3 = detailSizeBtn->w(); + filecolumns->W4 = detailDateBtn->w(); + + // update the size of each entry because the user changed the size of each column + filedetails->resize( filedetails->x(), filedetails->y(), filescroll->w(), filedetails->h() ); + int i; + for( i = 0; i < filedetails->children(); i++ ) + ((Entry*)filedetails->child(i))->updateSize(); + for( i = 0; i < filelist->children(); i++ ) + ((Entry*)filelist->child(i))->updateSize(); +} + +const char* Flu_File_Chooser :: value() +{ + if( filename.size() == 0 ) + return NULL; + else + { +#ifdef WIN32 + // on windows, be sure the drive letter is lowercase for + // compatibility with fl_filename_relative() + if( filename.size() > 1 && filename.value()[1] == ':' ) + ((char*)(filename.value()))[0] = tolower( filename.value()[0] ); +#endif + return filename.value(); + } +} + +int Flu_File_Chooser :: count() +{ + if( selectionType & MULTI ) + { + int n = 0; + Fl_Group *g = getEntryGroup(); + for( int i = 0; i < g->children(); i++ ) + { +#ifdef WIN32 + if( ((Entry*)g->child(i))->filename == myComputerTxt ) + continue; +#endif + if( ((Entry*)g->child(i))->selected ) + n++; + } + return n; + } + else + return (strlen(filename.value())==0)? 0 : 1; +} + +void Flu_File_Chooser :: value( const char *v ) +{ + cd( v ); + if( !v ) + return; + // try to find the file and select it + const char *slash = strrchr( v, '/' ); + if( slash ) + slash++; + else + { + slash = strrchr( v, '\\' ); + if( slash ) + slash++; + else + slash = v; + } + filename.value( slash ); + filename.position( filename.size(), filename.size() ); + Fl_Group *g = getEntryGroup(); + for( int i = 0; i < g->children(); i++ ) + { + if( ((Entry*)g->child(i))->filename == slash ) + { + ((Entry*)g->child(i))->selected = true; + filelist->scroll_to( (Entry*)g->child(i) ); + filedetails->scroll_to( (Entry*)g->child(i) ); + redraw(); + return; + } + } +} + +const char* Flu_File_Chooser :: value( int n ) +{ + Fl_Group *g = getEntryGroup(); + for( int i = 0; i < g->children(); i++ ) + { +#ifdef WIN32 + if( ((Entry*)g->child(i))->filename == myComputerTxt ) + continue; +#endif + if( ((Entry*)g->child(i))->selected ) + { + n--; + if( n == 0 ) + { + FluSimpleString s = currentDir + ((Entry*)g->child(i))->filename; + filename.value( s.c_str() ); + filename.position( filename.size(), filename.size() ); + return value(); + } + } + } + return ""; +} + +void Flu_File_Chooser :: reloadCB() +{ +#ifdef WIN32 + refreshDrives = true; +#endif + cd( currentDir.c_str() ); +} + +void Flu_File_Chooser :: addToFavoritesCB() +{ + // eliminate duplicates + bool duplicate = false; + for( int i = 1; i <= favoritesList->size(); i++ ) + { + if( streq( currentDir.c_str(), favoritesList->text(i) ) ) + { + duplicate = true; + break; + } + } + if( !duplicate ) + favoritesList->add( currentDir.c_str() ); + + // save the favorites + FILE *f = fopen( configFilename.c_str(), "w" ); + if( f ) + { + for( int i = 1; i <= favoritesList->size(); i++ ) + fprintf( f, "%s\n", favoritesList->text(i) ); + fclose( f ); + } +} + +FluSimpleString Flu_File_Chooser :: formatDate( const char *d ) +{ + if( d == 0 ) + { + FluSimpleString s; + return s; + } + + // convert style "Wed Mar 19 07:23:11 2003" to "MM/DD/YY HH:MM AM|PM" + + int month, day, year, hour, minute, second; + bool pm; + char MM[16], dummy[64]; + + sscanf( d, "%s %s %d %d:%d:%d %d", dummy, MM, &day, &hour, &minute, &second, &year ); + + pm = ( hour >= 12 ); + if( hour == 0 ) + hour = 12; + if( hour >= 13 ) + hour -= 12; + + if( strcmp(MM,"Jan")==0 ) month = 1; + else if( strcmp(MM,"Feb")==0 ) month = 2; + else if( strcmp(MM,"Mar")==0 ) month = 3; + else if( strcmp(MM,"Apr")==0 ) month = 4; + else if( strcmp(MM,"May")==0 ) month = 5; + else if( strcmp(MM,"Jun")==0 ) month = 6; + else if( strcmp(MM,"Jul")==0 ) month = 7; + else if( strcmp(MM,"Aug")==0 ) month = 8; + else if( strcmp(MM,"Sep")==0 ) month = 9; + else if( strcmp(MM,"Oct")==0 ) month = 10; + else if( strcmp(MM,"Nov")==0 ) month = 11; + else month = 12; + + sprintf( dummy, "%d/%d/%02d %d:%02d %s", month, day, year, hour, minute, pm?"PM":"AM" ); + + FluSimpleString formatted = dummy; + + return formatted; +} + +void Flu_File_Chooser :: win2unix( FluSimpleString &s ) +{ + int len = s.size(); + for( int i = 0; i < len; i++ ) + if( s[i] == '\\' ) + s[i] = '/'; +} + +void Flu_File_Chooser :: cleanupPath( FluSimpleString &s ) +{ + // convert all '\' to '/' + win2unix( s ); + + FluSimpleString newS(s.size()+1); + + int oldPos, newPos; + for( oldPos = 0, newPos = 0; oldPos < s.size(); oldPos++ ) + { + // remove "./" + if( s[oldPos] == '.' && s[oldPos+1] == '/' ) + oldPos += 2; + + // convert "//" to "/" + else if( s[oldPos] == '/' && s[oldPos+1] == '/' ) + oldPos++; + +#ifdef WIN32 + // downcase "c:" to "C:" + else if( s[oldPos+1] == ':' ) + s[oldPos] = toupper( s[oldPos] ); +#endif + + // remove "../" by removing everything back to the last "/" + if( oldPos+2 < s.size() ) // bounds check + { + if( s[oldPos] == '.' && s[oldPos+1] == '.' && s[oldPos+2] == '/' && newS != "/" ) + { + // erase the last character, which should be a '/' + newPos--; + newS[newPos] = '\0'; + // look for the previous '/' + char *lastSlash = strrchr( (char*)newS.c_str(), '/' ); + // make the new string position after the slash + newPos = (lastSlash-newS.c_str())+1; + oldPos += 3; + } + } + + newS[newPos] = s[oldPos]; + newPos++; + } + + newS[newPos] = '\0'; + s = newS; +} + +void Flu_File_Chooser :: backCB() +{ + if( !currentHist ) return; + if( currentHist->last ) + { + currentHist = currentHist->last; + walkingHistory = true; + delayedCd = currentHist->path; + Fl::add_timeout( 0.0f, Flu_File_Chooser::delayedCdCB, this ); + } +} + +void Flu_File_Chooser :: forwardCB() +{ + if( !currentHist ) return; + if( currentHist->next ) + { + currentHist = currentHist->next; + walkingHistory = true; + delayedCd = currentHist->path; + Fl::add_timeout( 0.0f, Flu_File_Chooser::delayedCdCB, this ); + } +} + +bool Flu_File_Chooser :: correctPath( FluSimpleString &path ) +{ + // the path may or may not be an alias, needing corrected +#ifdef WIN32 + // point to the correct desktop + if( path == "/"+desktopTxt+"/" ) + { + path = userDesktop; + return true; + } + else if( path == userDesktop ) + return true; + else if( path == "/"+desktopTxt+"/"+myComputerTxt+"/" || + path == userDesktop+myComputerTxt+"/" ) + path = "/"; + else if( path == "/"+desktopTxt+"/"+myDocumentsTxt+"/" || + path == userDesktop+myDocumentsTxt+"/" ) + path = userDocs; +#endif + return false; +} + +void Flu_File_Chooser :: locationCB( const char *path ) +{ +#ifdef WIN32 + FluSimpleString p = path; + if( p == "/"+favoritesTxt+"/" ) + favoritesCB(); + else if( p == "/"+desktopTxt+"/"+myComputerTxt+"/" ) + myComputerCB(); + else if( p == "/"+desktopTxt+"/"+myDocumentsTxt+"/" ) + documentsCB(); + else if( p == "/"+desktopTxt+"/" ) + desktopCB(); + // if the path leads off with "/Desktop/My Computer", then strip that part off and cd + // to the remaining + else + { + FluSimpleString s = "/"+desktopTxt+"/"+myComputerTxt+"/"; + if( strstr( path, s.c_str() ) == path ) + { + // seach for '(' and if present, extract the drive name and cd to it + char *paren = strrchr( path, '(' ); + if( paren ) + { + char drive[] = "A:/"; + drive[0] = toupper(paren[1]); + cd( drive ); + } + else + { + cd( path+21 ); + } + } + } +#else + cd( path ); +#endif + updateLocationQJ(); +} + +void Flu_File_Chooser :: buildLocationCombo() +{ + // add all filesystems + location->tree.clear(); + +#ifdef WIN32 + FluSimpleString s; + char volumeName[1024]; + Flu_Tree_Browser::Node *n; + s = desktopTxt+"/"; + n = location->tree.add( s.c_str() ); n->branch_icon( &little_desktop ); + s = desktopTxt+"/"+myDocumentsTxt+"/"; + n = location->tree.add( s.c_str() ); n->branch_icon( &documents ); + s = desktopTxt+"/"+myComputerTxt+"/"; + n = location->tree.add( s.c_str() ); n->branch_icon( &computer ); + // get the location and add them + { + if( refreshDrives ) + driveMask = GetLogicalDrives(); + DWORD mask = driveMask; + + for( int i = 0; i < 26; i++ ) + { + drives[i] = ""; + driveIcons[i] = &disk_drive; + if( mask & 1 ) + { + s = desktopTxt+"/"+myComputerTxt+"/"; + char drive[] = "A:"; + char windrive[] = "A:\\"; + windrive[0] = drive[0] = 'A' + i; + DWORD type; + if( refreshDrives ) + { + volumeName[0] = '\0'; + type = driveTypes[i] = GetDriveType( windrive ); + if( type != DRIVE_REMOVABLE && type != DRIVE_REMOTE ) + GetVolumeInformation( windrive, volumeName, 1024, NULL, NULL, NULL, NULL, 0 ); + volumeNames[i] = volumeName; + } + else + { + strncpy( volumeName, volumeNames[i].c_str(), 1024 ); + type = driveTypes[i]; + } + + //s += volume + const char *disk = "Disk"; + switch( type ) + { + case DRIVE_REMOVABLE: + disk = strlen(volumeName)?volumeName: ( 1 < 2 ? diskTypesTxt[0].c_str() : diskTypesTxt[1].c_str() ); + driveIcons[i] = &floppy_drive; + break; + case DRIVE_FIXED: + disk = strlen(volumeName)?volumeName:diskTypesTxt[2].c_str(); + //driveIcons[i] = &disk_drive; + break; + case DRIVE_CDROM: + disk = strlen(volumeName)?volumeName:diskTypesTxt[3].c_str(); + driveIcons[i] = &cd_drive; + break; + case DRIVE_REMOTE: + disk = strlen(volumeName)?volumeName:diskTypesTxt[4].c_str(); + driveIcons[i] = &network_drive; + break; + case DRIVE_RAMDISK: + disk = strlen(volumeName)?volumeName:diskTypesTxt[5].c_str(); + driveIcons[i] = &ram_drive; + break; + } + drives[i] = FluSimpleString(disk) + " (" + FluSimpleString(drive) + ")/"; + s += drives[i]; + n = location->tree.add( s.c_str() ); n->branch_icon( driveIcons[i] ); + // erase the trailing '/' to make things look nicer + drives[i][ drives[i].size()-1 ] = '\0'; + } + mask >>= 1; + } + } + s = favoritesTxt+"/"; + n = location->tree.add( s.c_str() ); n->branch_icon( &little_favorites ); + refreshDrives = false; + +#elif defined __APPLE__ + + location->tree.label( "/" ); + + // get all volume mount points and add to the location combobox + dirent **e; + char *name; + int num = fl_filename_list( "/Volumes/", &e ); + if( num > 0 ) + { + int i; + for( i = 0; i < num; i++ ) + { + name = e[i]->d_name; + + // ignore the "." and ".." names + if( strcmp( name, "." ) == 0 || strcmp( name, ".." ) == 0 || + strcmp( name, "./" ) == 0 || strcmp( name, "../" ) == 0 || + strcmp( name, ".\\" ) == 0 || strcmp( name, "..\\" ) == 0 ) + continue; + + // if 'name' ends in '/', remove it + if( name[strlen(name)-1] == '/' ) + name[strlen(name)-1] = '\0'; + + FluSimpleString fullpath = "/Volumes/"; + fullpath += name; + fullpath += "/"; + location->tree.add( fullpath.c_str() ); + } + } + +#else + + location->tree.label( "/" ); + + // get all mount points and add to the location combobox + FILE *fstab; // /etc/mtab or /etc/mnttab file + char dummy[256], mountPoint[256], line[1024]; // Input line + FluSimpleString mount; + + fstab = fopen( "/etc/fstab", "r" ); // Otherwise fallback to full list + if( fstab ) + { + while( fgets( line, 1024, fstab ) ) + { + if( line[0] == '#' || line[0] == '\n' ) + continue; + + // in fstab, mount point is second full string + sscanf( line, "%s %s", dummy, mountPoint ); + mount = mountPoint; + + // cull some stuff + if( mount[0] != '/' ) continue; + if( mount == "/" ) continue; + if( mount == "/boot" ) continue; + if( mount == "/proc" ) continue; + + // now add the mount point + mount += "/"; + location->tree.add( mount.c_str() ); + } + + fclose( fstab ); + } + +#endif +} + +void Flu_File_Chooser :: clear_history() +{ + currentHist = history; + while( currentHist ) + { + History *next = currentHist->next; + delete currentHist; + currentHist = next; + } + currentHist = history = NULL; + backBtn->deactivate(); + forwardBtn->deactivate(); +} + +void Flu_File_Chooser :: addToHistory() +{ + // remember history + // only store this path in the history if it is not the current directory + if( currentDir.size() && !walkingHistory ) + { + if( history == NULL ) + { + history = new History; + currentHist = history; + currentHist->path = currentDir; + } + else if( currentHist->path != currentDir ) + { + // since we are adding a new path, delete everything after this path + History *h = currentHist->next; + while( h ) + { + History *next = h->next; + delete h; + h = next; + } + currentHist->next = new History; + currentHist->next->last = currentHist; + currentHist = currentHist->next; + currentHist->path = currentDir; + } + History * h = history; + while( h ) + h = h->next; + } + walkingHistory = false; + + if( currentHist ) + { + if( currentHist->last ) + backBtn->activate(); + else + backBtn->deactivate(); + if( currentHist->next ) + forwardBtn->activate(); + else + forwardBtn->deactivate(); + } +} + +// treating the string as a '|' or ';' delimited sequence of patterns, strip them out and place in patterns +// return whether it is likely that "s" represents a regexp file-matching pattern +bool Flu_File_Chooser :: stripPatterns( FluSimpleString s, FluStringVector* patterns ) +{ + if( s.size() == 0 ) + return false; + + char *tok = strtok( (char*)s.c_str(), "|;" ); + int tokens = 0; + while( tok ) + { + tokens++; + if( tok[0] == ' ' ) + tok++; // skip whitespace + patterns->add( tok ); + tok = strtok( NULL, "|;" ); + } + + // if there is just a single token and it looks like it's not a pattern, + // then it is probably JUST a filename, in which case it should not be + // treated as a pattern + if( _isProbablyAPattern( s.c_str() ) ) + return true; + else if( tokens == 1 ) + { + patterns->clear(); + return false; + } + else + return true; +} + +void Flu_File_Chooser :: cd( const char *path ) +{ + Entry *entry; + char cwd[1024]; + + if( !path || path[0] == '\0' ) + { + path = getcwd( cwd, 1024 ); + if( !path ) + path = "./"; + } + + if( path[0] == '~' ) + { + if( path[1] == '/' || path[1] == '\\' ) + sprintf( cwd, "%s%s", userHome.c_str(), path+2 ); + else + sprintf( cwd, "%s%s", userHome.c_str(), path+1 ); + path = cwd; + } + + lastSelected = 0; + previewGroup->file = ""; + previewGroup->redraw(); + + filelist->scroll_to_beginning(); + filescroll->position( 0, 0 ); + + bool listMode = !fileDetailsBtn->value() || streq( path, FAVORITES_UNIQUE_STRING ); + +#ifdef WIN32 + // refresh the drives if viewing "My Computer" + if( strcmp( path, "/" ) == 0 ) + refreshDrives = true; +#endif + buildLocationCombo(); + + filename.take_focus(); + + trashBtn->deactivate(); + reloadBtn->activate(); + newDirBtn->activate(); + previewBtn->activate(); + hiddenFiles->activate(); + addFavoriteBtn->activate(); + + resize( x(), y(), w(), h() ); + if( listMode ) + { + //filecolumns->hide(); + //filescroll->hide(); + fileDetailsGroup->hide(); + filelist->show(); + filelist->parent()->resizable( filelist ); + } + else + { + filelist->hide(); + //filecolumns->show(); + //filescroll->show(); + //filescroll->parent()->resizable( filescroll ); + fileDetailsGroup->show(); + fileDetailsGroup->parent()->resizable( fileDetailsGroup ); + //updateEntrySizes(); + } + + FluSimpleString currentFile = filename.value(); + filescroll->position( 0, 0 ); + //Fl::focus( &filename ); + upDirBtn->activate(); + ok.activate(); + + // check for favorites + if( streq( path, FAVORITES_UNIQUE_STRING ) ) + { + currentDir = FAVORITES_UNIQUE_STRING; + addToHistory(); + + newDirBtn->deactivate(); + previewBtn->deactivate(); + reloadBtn->deactivate(); + addFavoriteBtn->deactivate(); + hiddenFiles->deactivate(); + location->input.value( favoritesTxt.c_str() ); + updateLocationQJ(); + + filelist->clear(); + filedetails->clear(); + if( listMode ) + filelist->begin(); + else + filedetails->begin(); + for( int i = 1; i <= favoritesList->size(); i++ ) + { + entry = new Entry( favoritesList->text(i), ENTRY_FAVORITE, false/*fileDetailsBtn->value()*/, this ); + entry->updateSize(); + entry->updateIcon(); + } + if( listMode ) + filelist->end(); + else + filedetails->end(); + + redraw(); + ok.deactivate(); + return; + } + // check for the current directory + else if( streq( path, "." ) || streq( path, "./" ) || streq( path, ".\\" ) ) + { + // do nothing. just rescan this directory + } + // check for parent directory + else if( streq( path, ".." ) || streq( path, "../" ) || streq( path, "..\\" ) ) + { + // if we are viewing the favorites and want to go back a directory, go to the previous directory + if( currentDir == FAVORITES_UNIQUE_STRING ) + { + backCB(); + return; + } +#ifdef WIN32 + // if we are at the desktop already, then we cannot go back any further + //if( currentDir == "/Desktop/" ) + //{ + // do nothing + //} + //else if( currentDir == userHome+"Desktop/" ) + //currentDir = userHome; + // if we are viewing "My Computer" and want to go back a directory, go to the desktop + if( currentDir == "/" ) + { + //currentDir = userDesktop;//userHome + "Desktop"; + // do nothing + } + // if we are at a top level drive, go to "My Computer" (i.e. "/") + else if( currentDir[1] == ':' && currentDir[3] == '\0' ) + currentDir = "/"; + else +#else + // if the current directory is already as far back as we can go, ignore + if( currentDir != "/" ) +#endif + { + // strip everything off the end to the next "/" + int end = currentDir.size()-1; + currentDir[end] = '\0'; + while( currentDir[end] != '/' ) + { + currentDir[end] = '\0'; + end--; + } + } + } + // check for absolute path +#ifdef WIN32 + else if( path[1] == ':' || path[0] == '/' ) +#else + else if( path[0] == '/' ) +#endif + { + currentDir = path; + } + // else relative path + else + { + // concatenate currentDir with path to make an absolute path + currentDir += path; + } + + int numDirs = 0, numFiles = 0; + filelist->clear(); + filedetails->clear(); + + cleanupPath( currentDir ); + +#ifdef WIN32 + bool isTopDesktop = ( currentDir == ("/"+desktopTxt+"/") ); + bool isDesktop = correctPath( currentDir ); + if( isTopDesktop ) + upDirBtn->deactivate(); +#else + if( currentDir == "/" ) + upDirBtn->deactivate(); +#endif + +#ifdef WIN32 + bool root = false; + // check for my computer + if( currentDir == "/" ) + { + ok.deactivate(); + root = true; + if( listMode ) + filelist->begin(); + else + filedetails->begin(); + for( int i = 0; i < 26; i++ ) + { + if( drives[i][0] != '\0' ) + { + char drive[] = "A:/"; + drive[0] = 'A' + i; + entry = new Entry( drive, ENTRY_DRIVE, fileDetailsBtn->value(), this ); + switch( driveTypes[i] ) + { + case DRIVE_REMOVABLE: entry->description = diskTypesTxt[0].c_str(); break; + case DRIVE_FIXED: entry->description = diskTypesTxt[2].c_str(); break; + case DRIVE_CDROM: entry->description = diskTypesTxt[3].c_str(); break; + case DRIVE_REMOTE: entry->description = diskTypesTxt[4].c_str(); break; + case DRIVE_RAMDISK: entry->description = diskTypesTxt[5].c_str(); break; + } + entry->icon = driveIcons[i]; + entry->altname = drives[i]; + entry->updateSize(); + entry->updateIcon(); + } + } + if( listMode ) + filelist->end(); + else + filedetails->end(); + + redraw(); + } + // check for desktop. if so, add My Computer and My Documents + else if( isDesktop ) + { + if( listMode ) + filelist->begin(); + else + filedetails->begin(); + entry = new Entry( myDocumentsTxt.c_str(), ENTRY_MYDOCUMENTS, fileDetailsBtn->value(), this ); + entry->updateSize(); + entry->updateIcon(); + entry = new Entry( myComputerTxt.c_str(), ENTRY_MYCOMPUTER, fileDetailsBtn->value(), this ); + entry->updateSize(); + entry->updateIcon(); + if( listMode ) + filelist->end(); + else + filedetails->end(); + numDirs += 2; + } +#endif + + // see if currentDir is in fact a directory + // if so, make sure there is a trailing "/" and we're done + if( fl_filename_isdir( currentDir.c_str() ) || currentDir=="/" ) + { + if( currentDir[strlen(currentDir.c_str())-1] != '/' ) + currentDir += "/"; +#ifdef WIN32 + if( filename.value()[1] != ':' ) +#else + if( filename.value()[0] != '/' ) +#endif + { + if( !(selectionType & SAVING ) ) + filename.value( "" ); + } + if( !(selectionType & SAVING ) ) + currentFile = ""; + } + + // now we have the current directory and possibly a file at the end + // try to split into path and file + if( currentDir[currentDir.size()-1] != '/' ) + { + char *lastSlash = strrchr( (char*)currentDir.c_str(), '/' ); + if( lastSlash ) + { + currentFile = lastSlash+1; + lastSlash[1] = '\0'; + } + } + // make sure currentDir ends in '/' + if( currentDir[currentDir.size()-1] != '/' ) + currentDir += "/"; + +#ifdef WIN32 + { + FluSimpleString tmp = currentDir; + if( isTopDesktop ) + currentDir = "/"+desktopTxt+"/"; + addToHistory(); + if( isTopDesktop ) + currentDir = tmp; + } +#else + addToHistory(); +#endif + + delayedCd = "./"; + +#ifdef WIN32 + // set the location input value + // check for drives + if( currentDir[1] == ':' && currentDir[3] == '\0' ) + { + location->input.value( currentDir.c_str() ); + } + else if( currentDir == "/" ) + location->input.value( myComputerTxt.c_str() ); + else +#endif + { + location->input.value( currentDir.c_str() ); +#ifdef WIN32 + FluSimpleString treePath = "/"+desktopTxt+"/"+myComputerTxt+"/"+currentDir; + Flu_Tree_Browser::Node *n = location->tree.add( treePath.c_str() ); + if( currentDir == (userHome+desktopTxt+"/") ) + n->branch_icon( &little_desktop ); + if( currentDir == (userHome+myDocumentsTxt+"/") ) + n->branch_icon( &documents ); +#else + location->tree.add( currentDir.c_str() ); +#endif + } + + updateLocationQJ(); + +#ifdef WIN32 + if( root ) + return; +#endif + + FluSimpleString pathbase, fullpath; + bool isDir, isCurrentFile = false; + const char *lastAddedFile = NULL, *lastAddedDir = NULL; + + pathbase = currentDir; + + // take the current pattern and make a list of filter pattern strings + FluStringVector currentPatterns; + { + FluSimpleString pat = patterns[filePattern->list.value()-1]; + while( pat.size() ) + { + int p = pat.find( ',' ); + if( p == -1 ) + { + if( pat != "*" ) + pat = "*." + pat; + currentPatterns.add( pat ); + break; + } + else + { + FluSimpleString s = pat.c_str() + p + 1; + pat[p] = '\0'; + if( pat != "*" ) + pat = "*." + pat; + currentPatterns.add( pat ); + pat = s; + } + } + } + + // add any user-defined patterns + FluStringVector userPatterns; + // if the user just hit but the filename input area is empty, + // then use the current patterns + if( !filenameTabCallback || currentFile != "*" ) + stripPatterns( currentFile, &userPatterns ); + + // read the directory + dirent **e; + char *name; + int num = fl_filename_list( pathbase.c_str(), &e ); + if( num > 0 ) + { + int i; + for( i = 0; i < num; i++ ) + { + name = e[i]->d_name; + + // ignore the "." and ".." names + if( strcmp( name, "." ) == 0 || strcmp( name, ".." ) == 0 || + strcmp( name, "./" ) == 0 || strcmp( name, "../" ) == 0 || + strcmp( name, ".\\" ) == 0 || strcmp( name, "..\\" ) == 0 ) + continue; + + // if 'name' ends in '/', remove it + if( name[strlen(name)-1] == '/' ) + name[strlen(name)-1] = '\0'; + + // file or directory? + fullpath = pathbase + name; + isDir = ( fl_filename_isdir( fullpath.c_str() ) != 0 ); + + // was this file specified explicitly? + isCurrentFile = ( currentFile == name ); + +#ifndef WIN32 + // filter hidden files + if( !isCurrentFile && !hiddenFiles->value() && ( name[0] == '.' ) ) + continue; +#endif + + // only directories? + if( (selectionType & DIRECTORY) && + !isDir && + !(selectionType & STDFILE) && + !(selectionType & DEACTIVATE_FILES) ) + continue; + + //if( !isDir /*!isCurrentFile*/ ) + { + // filter according to the user pattern in the filename input + if( userPatterns.size() ) + { + bool cull = true; + for( unsigned int i = 0; i < userPatterns.size(); i++ ) + { + if( flu_filename_match( name, userPatterns[i].c_str() ) != 0 ) + { + cull = false; + break; + } + } + if( cull ) + { + // only filter directories if someone just hit + if( !isDir || ( isDir && filenameTabCallback ) ) + continue; + } + } + // filter files according to the current pattern + else + { + bool cull = true; + for( unsigned int i = 0; i < currentPatterns.size(); i++ ) + { + if( flu_filename_match( name, currentPatterns[i].c_str() ) != 0 ) + { + cull = false; + break; + } + } + if( cull ) + { + // only filter directories if someone just hit + if( !isDir || ( isDir && filenameTabCallback ) ) + continue; + } + } + } + + // add directories at the beginning, and files at the end + entry = new Entry( name, isDir?ENTRY_DIR:ENTRY_FILE, fileDetailsBtn->value(), this ); + if( isDir ) + { + if( listMode ) + filelist->insert( *entry, 0 ); + else + filedetails->insert( *entry, 0 ); + numDirs++; + lastAddedDir = entry->filename.c_str(); + } + else + { + if( listMode ) + filelist->add( entry ); + else + filedetails->add( entry ); + numFiles++; + lastAddedFile = entry->filename.c_str(); + } + + // get some information about the file + struct stat s; + ::stat( fullpath.c_str(), &s ); + + // store size as human readable and sortable integer + entry->isize = s.st_size; + if( isDir && entry->isize == 0 ) + entry->filesize = ""; + else + { + char buf[32]; + /* + if( (entry->isize >> 40) > 0 ) // terrabytes + { + double TB = double(entry->isize)/double(1<<40); + sprintf( buf, "%.1f TB", TB ); + } + */ + if( (entry->isize >> 30) > 0 ) // gigabytes + { + double GB = double(entry->isize)/double(1<<30); + sprintf( buf, "%.1f GB", GB ); + } + else if( (entry->isize >> 20) > 0 ) // megabytes + { + double MB = double(entry->isize)/double(1<<20); + sprintf( buf, "%.1f MB", MB ); + } + else if( (entry->isize >> 10) > 0 ) // kilabytes + { + double KB = double(entry->isize)/double(1<<10); + sprintf( buf, "%.1f KB", KB ); + } + else // bytes + { + sprintf( buf, "%d bytes", (int)entry->isize ); + } + entry->filesize = buf; + } + + // store date as human readable and sortable integer + entry->date = formatDate( ctime( &s.st_mtime ) );//ctime( &s.st_mtime ); + entry->idate = s.st_mtime; + + // convert the permissions into UNIX style rwx-rwx-rwx (user-group-others) + /* + unsigned int p = s.st_mode; + entry->pU = bool(p&S_IRUSR)<<2 | bool(p&S_IWUSR)<<1 | bool(p&S_IXUSR); + entry->pG = bool(p&S_IRGRP)<<2 | bool(p&S_IWGRP)<<1 | bool(p&S_IXGRP); + entry->pO = bool(p&S_IROTH)<<2 | bool(p&S_IWOTH)<<1 | bool(p&S_IXOTH); + char* perms[8] = { "---", "--x", "-w-", "-wx", "r--", "r-x", "rw-", "rwx" }; + entry->permissions = perms[entry->pU]; + entry->permissions += perms[entry->pG]; + entry->permissions += perms[entry->pO]; + */ + + entry->updateSize(); + entry->updateIcon(); + + if( isCurrentFile ) + { + filename.value( name ); + entry->selected = true; + lastSelected = entry; + if( entry->type == ENTRY_FILE ) + previewGroup->file = currentDir + name; + previewGroup->redraw(); + filelist->scroll_to( entry ); + filedetails->scroll_to( entry ); + //break; + } + } + + for( i = 0; i < num; i++ ) + free((void*)(e[i])); + free((void*)e); + } + + // sort the files: directories first, then files + if( listMode ) + filelist->sort( numDirs ); + else + filedetails->sort( numDirs ); + + // see if the user pushed in the filename input field + if( filenameTabCallback ) + { + filenameTabCallback = false; + + FluSimpleString prefix = commonStr(); + + if( numDirs == 1 && + currentFile == (FluSimpleString(lastAddedDir)+"*") ) + { + delayedCd = lastAddedDir; + Fl::add_timeout( 0.0f, Flu_File_Chooser::delayedCdCB, this ); + } + + if( numDirs == 1 && numFiles == 0 ) + { +#ifdef WIN32 + if( filename.value()[1] == ':' ) +#else + if( filename.value()[0] == '/' ) +#endif + { + FluSimpleString s = currentDir + lastAddedDir + "/"; + filename.value( s.c_str() ); + } + else + filename.value( lastAddedDir ); + } + else if( numFiles == 1 && numDirs == 0 ) + { +#ifdef WIN32 + if( filename.value()[1] == ':' ) +#else + if( filename.value()[0] == '/' ) +#endif + { + FluSimpleString s = currentDir + lastAddedFile; + filename.value( s.c_str() ); + } + else + filename.value( lastAddedFile ); + } + else if( prefix.size() >= currentFile.size() ) + { +#ifdef WIN32 + if( filename.value()[1] == ':' ) +#else + if( filename.value()[0] == '/' ) +#endif + { + FluSimpleString s = currentDir + prefix; + filename.value( s.c_str() ); + } + else + filename.value( prefix.c_str() ); + } + + if( currentFile == "*" && +#ifdef WIN32 + filename.value()[1] != ':' ) +#else + filename.value()[0] != '/' ) +#endif + { + filename.value( "" ); + } + } + + // see if the user pushed in the filename input field + if( filenameEnterCallback ) + { + printf( "filenameEnterCallback\n" ); + filenameEnterCallback = false; + +#ifdef WIN32 + if( filename.value()[1] == ':' ) +#else + if( filename.value()[0] == '/' ) +#endif + filename.value( "" ); + + //if( isCurrentFile && numFiles == 1 ) + if( !_isProbablyAPattern( filename.value() ) ) + okCB(); + } + + if( _isProbablyAPattern( filename.value() ) ) + filename.position( 0, filename.size() ); + else + filename.position( filename.size(), filename.size() ); + filename.take_focus(); + + redraw(); +} + +// find the prefix string that is common to all entries in the list +FluSimpleString Flu_File_Chooser :: commonStr() +{ + FluSimpleString common; + int index = 0; + const char* name; + int len, i; + Fl_Group *g = getEntryGroup(); + for(;;) + { + bool allSkipped = true; + for( i = 0; i < g->children(); i++ ) + { + name = ((Entry*)g->child(i))->filename.c_str(); + len = strlen( name ); + if( index >= len ) + continue; + allSkipped = false; + if( i == 0 ) + common.push_back( name[index] ); + else if( toupper(common[index]) != toupper(name[index]) ) + { + common[index] = '\0'; + return common; + } + } + if( allSkipped ) + break; + index++; + } + return common; +} + +static const char* _flu_file_chooser( const char *message, const char *pattern, const char *filename, int type, + int *count = 0, FluStringVector *filelist = 0 ) +{ + static Flu_File_Chooser *fc = NULL; + static FluSimpleString retname; + + if( !fc ) + { + fc = new Flu_File_Chooser( filename, pattern, type, message ); + } + else + { + fc->type( type ); + fc->clear_history(); + fc->label( message ); + if( !filename || filename[0] == '\0' ) + { + if( (!pattern || !fc->filter() || strcmp(pattern,fc->filter())) && fc->value() ) + { + // if pattern is different, remove name but leave old directory: + retname = fc->value(); + char *p = strrchr( (char*)retname.c_str(), '/' ); + if( p ) + { + // If the filename is "/foo", then the directory will be "/", not "" + if( p == retname.c_str() ) + retname[1] = '\0'; + else + p[1] = '\0'; + } + } + fc->filter( pattern ); + fc->value( retname.c_str() ); + } + else + { + fc->filter( pattern ); + fc->value( filename ); + } + } + + fc->set_modal(); + fc->show(); + + while( fc->shown() ) + Fl::wait( 0.01 ); + + Fl_Group::current(0); + + if( fc->value() ) + { + if( count && filelist ) + { + *count = fc->count(); + for( int i = 1; i <= *count; i++ ) + filelist->add( FluSimpleString(fc->value(i)) ); + } + retname = fc->value(); + return retname.c_str(); + } + else + return 0; +} + +int flu_multi_file_chooser( const char *message, const char *pattern, const char *filename, FluStringVector *filelist ) +{ + int count = 0; + _flu_file_chooser( message, pattern, filename, Flu_File_Chooser::MULTI, &count, filelist ); + return count; +} + +const char* flu_file_chooser( const char *message, const char *pattern, const char *filename ) +{ + return _flu_file_chooser( message, pattern, filename, Flu_File_Chooser::SINGLE ); +} + +const char* flu_save_chooser( const char *message, const char *pattern, const char *filename ) +{ + return _flu_file_chooser( message, pattern, filename, Flu_File_Chooser::SINGLE | Flu_File_Chooser::SAVING ); +} + +const char* flu_dir_chooser( const char *message, const char *filename ) +{ + return _flu_file_chooser( message, "*", filename, Flu_File_Chooser::DIRECTORY ); +} + +const char* flu_dir_chooser( const char *message, const char *filename, bool showFiles ) +{ + if( showFiles ) + return _flu_file_chooser( message, "*", filename, + Flu_File_Chooser::DIRECTORY | Flu_File_Chooser::DEACTIVATE_FILES ); + else + return( flu_dir_chooser( message, filename ) ); +} + +const char* flu_file_and_dir_chooser( const char *message, const char *filename ) +{ + return _flu_file_chooser( message, "*", filename, Flu_File_Chooser::STDFILE ); +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Float_Input.cpp b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Float_Input.cpp new file mode 100644 index 0000000..d3fd307 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Float_Input.cpp @@ -0,0 +1,26 @@ +// $Id: Flu_Float_Input.cpp,v 1.4 2004/03/29 23:13:19 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#include "FLU/Flu_Float_Input.h" + +Flu_Float_Input :: Flu_Float_Input( int X,int Y,int W,int H,const char *l ) + : Fl_Float_Input(X,Y,W,H,l) +{ + format( "%g" ); +} + +Flu_Float_Input :: ~Flu_Float_Input() +{ +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_GL_Canvas.cpp b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_GL_Canvas.cpp new file mode 100644 index 0000000..7ed2aed --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_GL_Canvas.cpp @@ -0,0 +1,36 @@ +// $Id: Flu_GL_Canvas.cpp,v 1.3 2004/09/23 20:16:13 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#include "FLU/Flu_GL_Canvas.h" + +Flu_GL_Canvas :: Flu_GL_Canvas( int x, int y, int w, int h, const char *label ) + : Flu_GL_Window( x, y, w, h, label ) +{ + setInitFunc( _initCB, this ); + setResizeFunc( _reshapeCB, this ); + setDrawFunc( _renderCB, this ); + setMouseWheelFunc( _mouse_wheelCB, this ); + setMouseDownFunc( _mouse_button_downCB, this ); + setMouseUpFunc( _mouse_button_upCB, this ); + setMouseDragFunc( _mouse_dragCB, this ); + setMouseMoveFunc( _mouse_moveCB, this ); + setMouseEnterFunc( _mouse_enterCB, this ); + setMouseExitFunc( _mouse_exitCB, this ); + setKeyboardFunc( _keyboardCB, this ); +} + +Flu_GL_Canvas :: ~Flu_GL_Canvas() +{ +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_GL_Window.cpp b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_GL_Window.cpp new file mode 100644 index 0000000..b9a4101 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_GL_Window.cpp @@ -0,0 +1,197 @@ +// $Id: Flu_GL_Window.cpp,v 1.21 2004/07/27 19:34:29 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#include "FLU/Flu_GL_Window.h" + +Flu_GL_Window::AllInitProto Flu_GL_Window::allInitCB = 0; +void* Flu_GL_Window::allInitCBD = 0; + +Flu_GL_Window :: Flu_GL_Window( int x, int y, int w, int h, const char *label ) + : Fl_Gl_Window( x, y, w, h, label ) +{ + cartesianInput( true ); + _drawCB = NULL; _drawCBD = NULL; + _resizeCB = NULL; _resizeCBD = NULL; + _initCB = NULL; _initCBD = NULL; + _mouseWheelCB = NULL; _mouseWheelCBD = NULL; + _mouseDownCB = NULL; _mouseDownCBD = NULL; + _mouseUpCB = NULL; _mouseUpCBD = NULL; + _mouseDragCB = NULL; _mouseDragCBD = NULL; + _mouseMoveCB = NULL; _mouseMoveCBD = NULL; + _keyboardCB = NULL; _keyboardCBD = NULL; + _enterCB = NULL; _enterCBD = NULL; + _exitCB = NULL; _exitCBD = NULL; + _firstDraw = true; + end(); +} + +Flu_GL_Window :: Flu_GL_Window( int w, int h, const char *label ) + : Fl_Gl_Window( w, h, label ) +{ + cartesianInput( true ); + _drawCB = NULL; _drawCBD = NULL; + _resizeCB = NULL; _resizeCBD = NULL; + _initCB = NULL; _initCBD = NULL; + _mouseWheelCB = NULL; _mouseWheelCBD = NULL; + _mouseDownCB = NULL; _mouseDownCBD = NULL; + _mouseUpCB = NULL; _mouseUpCBD = NULL; + _mouseDragCB = NULL; _mouseDragCBD = NULL; + _mouseMoveCB = NULL; _mouseMoveCBD = NULL; + _keyboardCB = NULL; _keyboardCBD = NULL; + _enterCB = NULL; _enterCBD = NULL; + _exitCB = NULL; _exitCBD = NULL; + _firstDraw = true; + end(); +} + +Flu_GL_Window :: ~Flu_GL_Window() +{ +} + +void Flu_GL_Window :: redraw() +{ + Fl_Gl_Window::redraw(); +} + +int Flu_GL_Window :: handle( int event ) +{ + if( !context() ) + _firstDraw = true; + + if( !context() || !visible() ) + return Fl_Gl_Window::handle( event ); + + int x = Fl::event_x(), y = Fl::event_y(); + + if( _cartesian ) + y = h() - 1 - y; + + switch( event ) + { + case FL_MOVE: + { + // make sure the GL context is current in case the callback needs it + Fl_Group *current = Fl_Group::current(); + make_current(); + if( _mouseMoveCB ) + _mouseMoveCB( x, y, _mouseMoveCBD ); + Fl_Group::current( current ); + return 1; + } + + case FL_DRAG: + { + // make sure the GL context is current in case the callback needs it + Fl_Group *current = Fl_Group::current(); + make_current(); + if( _mouseDragCB ) + _mouseDragCB( x, y, _mouseDragCBD ); + Fl_Group::current( current ); + return 1; + } + + case FL_PUSH: + { + // make sure the GL context is current in case the callback needs it + Fl_Group *current = Fl_Group::current(); + make_current(); + if( _mouseDownCB ) + _mouseDownCB( Fl::event_button(), x, y, _mouseDownCBD ); + Fl_Group::current( current ); + return 1; + } + + case FL_RELEASE: + { + // make sure the GL context is current in case the callback needs it + Fl_Group *current = Fl_Group::current(); + make_current(); + if( _mouseUpCB ) + _mouseUpCB( Fl::event_button(), x, y, _mouseUpCBD ); + Fl_Group::current( current ); + return 1; + } + + case FL_MOUSEWHEEL: + { + // make sure the GL context is current in case the callback needs it + Fl_Group *current = Fl_Group::current(); + make_current(); + if( _mouseWheelCB ) + _mouseWheelCB( Fl::event_dx(), Fl::event_dy(), x, y, _mouseWheelCBD ); + Fl_Group::current( current ); + return 1; + } + + case FL_FOCUS : + case FL_UNFOCUS : + return 1; + + case FL_ENTER: + { + // make sure the GL context is current in case the callback needs it + Fl_Group *current = Fl_Group::current(); + make_current(); + if( _enterCB ) + _enterCB( _enterCBD ); + Fl_Group::current( current ); + return 1; + } + + case FL_LEAVE: + { + // make sure the GL context is current in case the callback needs it + Fl_Group *current = Fl_Group::current(); + make_current(); + if( _exitCB ) + _exitCB( _exitCBD ); + Fl_Group::current( current ); + return 1; + } + + case FL_KEYUP: + // make sure the GL context is current in case the callback needs it + //make_current(); + if( _keyboardCB ) + _keyboardCB( Fl::event_key(), x, y, _keyboardCBD ); + return Fl_Gl_Window::handle( event ); + + default: + // pass other events to the base class... + return Fl_Gl_Window::handle( event ); + } +} + +void Flu_GL_Window :: draw() +{ + if( !context() ) + return; + + if( _firstDraw ) + { + _firstDraw = false; + if( allInitCB ) + allInitCB( allInitCBD ); + if( _initCB ) + _initCB( _initCBD ); + } + if( !valid() ) + { + if( _resizeCB ) + _resizeCB( w(), h(), _resizeCBD ); + } + if( _drawCB ) + _drawCB( _drawCBD ); +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Helpers.cpp b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Helpers.cpp new file mode 100644 index 0000000..8702aa3 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Helpers.cpp @@ -0,0 +1,177 @@ +// $Id: Flu_Helpers.cpp,v 1.4 2003/12/31 16:17:11 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#include "FLU/Flu_Helpers.h" +#include +#include +#include + +#define streq(a,b) (strcmp(a,b)==0) + +static int fl_Full_Find_In_Menu( const Fl_Menu_* menu, const Fl_Menu_Item* items, int &which, const char* fullname ) +{ + if( fullname == NULL ) + return -1; + + if( fullname[0] == '\0' ) + return -1; + + char *name = strdup( fullname ); + bool submenu = false; + + // strip off the first part of the path + char* slash = strchr( name, '/' ); + if( slash ) + { + *slash = '\0'; + submenu = true; // if there is a slash, then the first part is a submenu + } + + // search for the name + for(;;) + { + // if we're at the end, quit searching + if( which >= menu->size() ) + { + return -1; + } + + bool match = false; + if( items[which].label() ) + match = streq( name, items[which].label() ); + else + match = false; + + // see if the name matches the next menu item + if( match ) + { + // if the path indicates this is a submenu... + if( submenu ) + { + // ...but the menu item does not indicate that it is a submenu, then we have a problem + if( !items[which].submenu() ) + { + free(name); + return -1; + } + // ...the menu item agrees that it is a submenu, so recurse on the remaining items and path + else + { + fullname += (slash-name) + 1; + which++; + free(name); + return fl_Full_Find_In_Menu( menu, items, which, fullname ); + } + } + // we have an exact match and the the path indicates the item is not a submenu + else + { + // if the item disagrees, then we have a problem + //if( items[which].submenu() ) + //{ + // free(name); + // return -1; + //} + // otherwise the path and the item are in agreement that this is the actual item + // being searched for, so return it + //else + { + free(name); + return which; + } + } + } + // the name doesn't match, so skip to the next item + else + { + // if the item is a submenu, skip all its children + if( items[which].submenu() ) + { + while( items[which].label() != 0 ) + which++; + which++; // increment one more to eat the end-of-submenu marker + } + // otherwise just skip the item + else + which++; + } + } +} + +int fl_Full_Find_In_Menu( const Fl_Menu_* menu, const char* fullname ) +{ + if( menu == NULL ) + return -1; + if( fullname == NULL ) + return -1; + const Fl_Menu_Item *items = menu->menu(); + + // remove any leading '/' (there shouldn't be one...but just in case) + if( fullname[0] == '/' ) + fullname++; + + // delete any 'flag' characters + char *correctedName = strdup( fullname ); + { + int index = 0; + for( int i = 0; i < (int)strlen( fullname ); i++ ) + { + if( fullname[i] == '&' && fullname[i+1] == '&' ) + correctedName[index++] = '&'; + else if( fullname[i] == '&' ) + continue; + else if( fullname[i] == '_' ) + continue; + else + correctedName[index++] = fullname[i]; + } + correctedName[index] = '\0'; + } + + // find the menu entry + int which = 0; + while( items[which].label() != 0 && which != menu->size() ) + { + int val = fl_Full_Find_In_Menu( menu, items, which, correctedName ); + if( val != -1 ) + { + free( correctedName ); + return val; + } + } + + free( correctedName ); + return -1; +} + +int fl_Find_In_Menu( const Fl_Menu_* menu, const char* name ) +{ + if( menu == NULL ) + return -1; + if( name == NULL ) + return -1; + const Fl_Menu_Item *items = menu->menu(); + + for( int i = 0; i < menu->size(); i++ ) + { + if( items[i].label() == NULL ) + continue; + if( strlen( items[i].label() ) == 0 ) + continue; + if( strcmp( name, items[i].label() ) == 0 ) + return i; + } + return -1; +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Int_Input.cpp b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Int_Input.cpp new file mode 100644 index 0000000..4def607 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Int_Input.cpp @@ -0,0 +1,26 @@ +// $Id: Flu_Int_Input.cpp,v 1.4 2004/03/29 23:13:19 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#include "FLU/Flu_Int_Input.h" + +Flu_Int_Input :: Flu_Int_Input( int X,int Y,int W,int H,const char *l ) + : Fl_Int_Input(X,Y,W,H,l) +{ + format( "%d" ); +} + +Flu_Int_Input :: ~Flu_Int_Input() +{ +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Label.cpp b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Label.cpp new file mode 100644 index 0000000..68a3ed8 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Label.cpp @@ -0,0 +1,65 @@ +// $Id: Flu_Label.cpp,v 1.6 2004/10/21 15:21:07 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#include +#include "FLU/Flu_Label.h" + +Flu_Label :: Flu_Label( int x, int y, int w, int h, const char* l ) + : Fl_Box( x, y, w, h, 0 ) +{ + _autoSize = false; + align( FL_ALIGN_LEFT | FL_ALIGN_WRAP | FL_ALIGN_INSIDE ); + _label = NULL; + label( l ); + box( FL_NO_BOX ); + clear_visible_focus(); +} + +Flu_Label :: ~Flu_Label() +{ + if( _label ) + delete[] _label; +} + +void Flu_Label :: draw() +{ + if( _autoSize ) + { + fl_font( labelfont(), labelsize() ); + int W = 0, H = 0; + fl_measure( label(), W, H ); + if( W != w() || H != h() ) + resize( x(), y(), W, H ); + } + Fl_Box::draw(); +} + +void Flu_Label :: label( const char* l ) +{ + if( _label ) + delete[] _label; + if( l == NULL ) + { + _label = new char[1]; + _label[0] = '\0'; + } + else + { + _label = new char[strlen(l)+1]; + strcpy( _label, l ); + } + Fl_Box::label( _label ); + redraw(); +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Link_Button.cpp b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Link_Button.cpp new file mode 100644 index 0000000..a779959 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Link_Button.cpp @@ -0,0 +1,29 @@ +// $Id: Flu_Link_Button.cpp,v 1.3 2003/10/28 15:36:07 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#include "FLU/Flu_Link_Button.h" + +Flu_Link_Button :: Flu_Link_Button( int X,int Y,int W,int H,const char *l ) + : Flu_Button( X,Y,W,H,l ) +{ + box( FL_FLAT_BOX ); + linkBtn = true; + overLink = false; + labelcolor( FL_BLUE ); +} + +Flu_Link_Button :: ~Flu_Link_Button() +{ +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Output.cpp b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Output.cpp new file mode 100644 index 0000000..b2820e7 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Output.cpp @@ -0,0 +1,26 @@ +// $Id: Flu_Output.cpp,v 1.3 2003/08/20 16:29:46 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#include "FLU/Flu_Output.h" + +Flu_Output :: Flu_Output( int X,int Y,int W,int H,const char *l ) + : Fl_Output(X,Y,W,H,l) +{ + color( FL_GRAY ); +} + +Flu_Output :: ~Flu_Output() +{ +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Progress.cpp b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Progress.cpp new file mode 100644 index 0000000..aa2f775 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Progress.cpp @@ -0,0 +1,94 @@ +// $Id: Flu_Progress.cpp,v 1.12 2004/04/10 22:10:56 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#include +#include +#include +#include +#include +#include +#include + +#include "FLU/Flu_Progress.h" + +class _FlWindowFlush : public Fl_Window +{ +public: + _FlWindowFlush() : Fl_Window(0,0,0,0) {} + inline void flush() { Fl_Window::flush(); } +}; + +class _FlDoubleWindowFlush : public Fl_Double_Window +{ +public: + _FlDoubleWindowFlush() : Fl_Double_Window(0,0,0,0) {} + inline void flush() { Fl_Double_Window::flush(); } +}; + +Flu_Progress :: Flu_Progress( int X, int Y, int W, int H, const char* l ) + : Fl_Valuator( X, Y, W, H, l ) +{ + box( FL_THIN_DOWN_BOX ); + align( FL_ALIGN_LEFT ); + color( FL_WHITE ); + selection_color( FL_BLUE ); + precision( 2 ); + range( 0, 1 ); + Fl_Valuator::value( 0 ); +} + +Flu_Progress :: ~Flu_Progress() +{ +} + +int Flu_Progress :: value( float v ) +{ + int lastPercent = int(100.0 * (value() - minimum()) / (maximum()-minimum()) ); + int thisPercent = int(100.0 * (v - minimum()) / (maximum()-minimum()) ); + int ret = Fl_Valuator::value( v ); + if( thisPercent != lastPercent && window()->shown() ) + Fl::check(); + return ret; +} + +void Flu_Progress :: draw() +{ + int dx = Fl::box_dx( box() ), dy = Fl::box_dy( box() ), + dw = Fl::box_dw( box() ), dh = Fl::box_dh( box() ); + float percent = (value() - minimum()) / (maximum()-minimum()); + int val1 = int( float(w()-dw)*percent ), val2 = w()-dw - val1; + + char buf[8]; + sprintf( buf, "%d%%", int(percent*100.0) ); + + fl_font( FL_HELVETICA_BOLD, h()/2+2 ); + int fW = 0, fH; + fl_measure( buf, fW, fH ); + + fl_draw_box( box(), x(), y(), w(), h(), color() ); + fl_color( active_r() ? selection_color() : fl_inactive(selection_color()) ); + fl_rectf( x()+dx, y()+dy, val1, h()-dh ); + fl_push_clip( x()+dx+val1, y()+dy, val2, h()-dh ); + fl_draw( buf, x()+w()/2-(fW>>1), y()+h()/2-(fH>>1), fW, fH, FL_ALIGN_CENTER ); + fl_pop_clip(); + + fl_color( color() ); + fl_push_clip( x()+dx, y()+dy, val1, h()-dh ); + fl_draw( buf, x()+w()/2-(fW>>1), y()+h()/2-(fH>>1), fW, fH, FL_ALIGN_CENTER ); + fl_pop_clip(); + + // draw the label + draw_label(); +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Progress_Meter.cpp b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Progress_Meter.cpp new file mode 100644 index 0000000..7855c78 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Progress_Meter.cpp @@ -0,0 +1,137 @@ +// $Id: Flu_Progress_Meter.cpp,v 1.16 2004/06/09 19:51:15 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#include "FLU/Flu_Progress_Meter.h" + +#if !defined WIN32 + #define TSCALE (1.0 / 1.0e6) +#else + #define TSCALE (1.0 / CLOCKS_PER_SEC) +#endif + +Flu_Progress_Meter :: Flu_Progress_Meter( const char* t ) + : Fl_Double_Window( Fl::w()/2-350/2, Fl::h()/2-180/2, 350, 180, t ) +{ + _cancelled = false; + _cancelCB = NULL; + _cancelCBD = NULL; + _showETC = true; + + _label = new Flu_Label( 10, 10, 330, 50 ); + _label->align( _label->align() | FL_ALIGN_WRAP ); + etc = new Flu_Label( 10, 60, 330, 30 ); + etc->hide(); + progress = new Flu_Progress( 10, 100, 330, 30 ); + cancel = new Fl_Button( w()/2-30, h()-40, 60, 30, "Cancel" ); + end(); + + Fl_Double_Window::hide(); + + progress->align( FL_ALIGN_TOP | FL_ALIGN_LEFT ); + + cancel->callback( _onCancelCB, this ); +} + +Flu_Progress_Meter :: ~Flu_Progress_Meter() +{ + Fl::remove_timeout( _secondTimerCB, this ); + hide(); +} + +inline void secs2HMS( double secs, int &H, int &M, int &S ) +{ + S = (int)secs; + M = S / 60; S -= M*60; + H = M / 60; M -= H*60; +} + +void Flu_Progress_Meter::reset() +{ + Fl::remove_timeout( _secondTimerCB, this ); + gettimeofday( &startT, 0 ); + Fl::add_timeout( 0.0f, _secondTimerCB, this ); + value(0); +} + +void Flu_Progress_Meter :: secondTimerCB( bool repeatTimer ) +{ + // get the current time and use it to compute the elapsed time, if necessary + timeval now; + gettimeofday( &now, 0 ); + + if( _showETC && shown() ) + { + // compute the elapsed time + double elapsed = (now.tv_sec - startT.tv_sec) + ( (now.tv_usec - startT.tv_usec) * TSCALE ); + // estimate the remaining time based on the elapsed time and the current progress + double remaining = elapsed / this->value() - elapsed + 1.0f; + int es, em, eh, rs, rm, rh; + + secs2HMS( elapsed, eh, em, es ); + //if( elapsed < 1.0 ) + //rh = rm = rs = 0; + //else + secs2HMS( remaining, rh, rm, rs ); + + char buf[128]; + sprintf( buf, "Elapsed Time: %03d:%02d:%02d\n" + "Remaining Time: %03d:%02d:%02d", + eh, em, es, rh, rm, rs ); + etc->label( buf ); + etc->show(); + } + else + etc->hide(); + + if( repeatTimer ) + { + Fl::repeat_timeout( 1.0f, _secondTimerCB, this ); + Fl::check(); + } +} + +bool Flu_Progress_Meter :: value( float v ) +{ + secondTimerCB( false ); + + if( progress ) + progress->value( v ); + + return _cancelled; +} + +void Flu_Progress_Meter :: show( bool cancelBtnVisible ) +{ + gettimeofday( &startT, 0 ); + + _cancelled = false; + if( _cancelCB || cancelBtnVisible ) + cancel->show(); + else + cancel->hide(); + + //set_modal(); + Fl_Double_Window::show(); + + Fl::add_timeout( 0.0f, _secondTimerCB, this ); + Fl::flush(); +} + +void Flu_Progress_Meter :: hide() +{ + Fl::remove_timeout( _secondTimerCB, this ); + Fl_Double_Window::hide(); + Fl::flush(); +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Return_Button.cpp b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Return_Button.cpp new file mode 100644 index 0000000..7edc4a2 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Return_Button.cpp @@ -0,0 +1,26 @@ +// $Id: Flu_Return_Button.cpp,v 1.2 2003/08/20 16:29:47 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#include "FLU/Flu_Return_Button.h" + +Flu_Return_Button :: Flu_Return_Button( int X,int Y,int W,int H,const char *l ) + : Flu_Button( X,Y,W,H,l ) +{ + retBtn = true; +} + +Flu_Return_Button :: ~Flu_Return_Button() +{ +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Separator.cpp b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Separator.cpp new file mode 100644 index 0000000..f05a8bc --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Separator.cpp @@ -0,0 +1,31 @@ +// $Id: Flu_Separator.cpp,v 1.2 2003/08/20 16:29:47 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#include "FLU/Flu_Separator.h" + +Flu_Separator :: Flu_Separator( int X, int Y, int W, int H, const char *l ) + : Fl_Widget( X, Y, W, H, l ) +{ + type( HORIZONTAL ); + box( FL_EMBOSSED_BOX ); +} + +void Flu_Separator :: draw() +{ + if( _type == HORIZONTAL ) + draw_box( box(), x()+3, y()+h()/2, w()-6, 2, color() ); + else + draw_box( box(), x()+w()/2, y()+3, 2, h()-6, color() ); +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Simple_Group.cpp b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Simple_Group.cpp new file mode 100644 index 0000000..186bed7 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Simple_Group.cpp @@ -0,0 +1,64 @@ +// $Id: Flu_Simple_Group.cpp,v 1.5 2004/06/17 14:16:42 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#include "FLU/Flu_Simple_Group.h" +#include +#include + +Flu_Simple_Group :: Flu_Simple_Group( int x, int y, int w, int h, const char *l ) + : Fl_Group( x, y, w, h, l ) +{ + box( FL_EMBOSSED_FRAME ); + align( FL_ALIGN_LEFT | FL_ALIGN_INSIDE ); +} + +void Flu_Simple_Group :: draw() +{ + int lblW = 0, lblH, X; + + if( label() == 0 ) + lblW = lblH = 0; + else if( strlen( label() ) == 0 ) + lblW = lblH = 0; + else + { + measure_label( lblW, lblH ); + lblW += 4; + lblH += 2; + } + + // align the label + if( align() & FL_ALIGN_LEFT ) + X = 4; + else if( align() & FL_ALIGN_RIGHT ) + X = w() - lblW - 8; + else + X = w()/2 - lblW/2 - 2; + + // draw the main group box + if( damage() & ~FL_DAMAGE_CHILD ) + fl_draw_box( box(), x(), y()+lblH/2, w(), h()-lblH/2, color() ); + + // clip and draw the children + fl_clip( x()+2, y()+lblH+1, w()-4, h()-lblH-3 ); + draw_children(); + fl_pop_clip(); + + // clear behind the label and draw it + fl_color( color() ); + fl_rectf( x()+X, y(), lblW+4, lblH ); + fl_color( labelcolor() ); + draw_label( x()+X+2, y(), lblW, lblH, FL_ALIGN_CENTER ); +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Spinner.cpp b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Spinner.cpp new file mode 100644 index 0000000..6000fd5 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Spinner.cpp @@ -0,0 +1,416 @@ +// $Id: Flu_Spinner.cpp,v 1.20 2004/10/22 16:17:45 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#include +#include +#include +#include +#include +#include + +#include "FLU/Flu_Spinner.h" + +#define ABS( x ) ( (x)>0 ? (x) : -(x) ) + +Flu_Spinner :: NoTabInput :: NoTabInput( Flu_Spinner *s, int x, int y, int w, int h, const char *l ) + : Fl_Input( x, y, w, h, l ) +{ + spinner = s; +} + +int Flu_Spinner :: NoTabInput :: handle( int event ) +{ + switch( event ) + { + case FL_KEYDOWN: + { + switch( Fl::event_key() ) + { + case FL_Tab: + redraw(); + return 0; + + case FL_Enter: + case FL_KP_Enter: + Fl_Input::handle( event ); + spinner->value( spinner->clamp( atof( value() ) ) ); + spinner->do_callback(); + return 1; + + case FL_Down: + case FL_Up: + spinner->handle( event ); + return 1; + } + } + break; + + case FL_FOCUS: + case FL_UNFOCUS: + redraw(); + break; + } + + return Fl_Input::handle( event ); +} + +void Flu_Spinner :: NoTabInput :: draw() +{ + if( spinner->active() ) + activate(); + else + deactivate(); + + if( spinner->_dragging ) + { + if( (spinner->align() & FL_ALIGN_INSIDE) || !spinner->editable() ) + position( size() ); + else + position( 0, size() ); + } + + Fl_Input::draw(); + if( Fl::focus() == this && ( (spinner->align() & FL_ALIGN_INSIDE) || !spinner->editable() ) ) + draw_focus( box(), x(), y(), w(), h() ); +} + +Flu_Spinner :: Flu_Spinner( int X, int Y, int W, int H, const char* l ) + : Fl_Valuator( X, Y, W, H, l ), _input( this, X, Y, W, H, 0 ) +{ + // we always want the buttons to be square and half the height of the widget + int wid = W*15/100; + if( wid < H/2 ) + wid = H/2; + + _wrapRange = false; + _dragging = false; + _editable = true; + _totalTime = 0.0f; + _initialDelay = 0.5f; + _repeatTime[0] = 0.1f; + _repeatTime[1] = 0.02f; + _rapidDelay = 2.0f; + _doRepeat = true; + _pushed = false; + _valbox[0] = _valbox[1] = FL_UP_BOX; + + box( FL_DOWN_BOX ); + align( FL_ALIGN_LEFT ); + when( FL_WHEN_CHANGED ); + precision( 2 ); + range( 0, 1 ); + value( 0 ); + + { + _input.callback(input_cb, this); + _input.resize( X, Y, W-wid-1, H ); + _input.color( FL_WHITE, FL_SELECTION_COLOR ); + _input.textfont( FL_HELVETICA ); + _input.textsize( FL_NORMAL_SIZE ); + _input.textcolor( FL_FOREGROUND_COLOR ); + _input.type( FL_FLOAT_INPUT ); + value_damage(); + } +} + +Flu_Spinner::~Flu_Spinner() +{ + Fl::remove_timeout(repeat_callback, this); +} + +// taken from Fl_Counter.cxx +void Flu_Spinner :: input_cb( Fl_Widget*, void* v ) +{ + Flu_Spinner& t = *(Flu_Spinner*)v; + if( t.align() & FL_ALIGN_INSIDE ) + return; + double nv; + if ((t.step() - floor(t.step()))>0.0 || t.step() == 0.0) + nv = strtod(t._input.value(), 0); + else + nv = strtol(t._input.value(), 0, 0); + if( nv != t.value() || t._input.when() & FL_WHEN_NOT_CHANGED) + { + if( nv < t.minimum() ) + { + t.set_value(t.minimum()); + t.value_damage(); + } + else if( nv > t.maximum() ) + { + t.set_value(t.maximum()); + t.value_damage(); + } + else + t.set_value(nv); + + if( t.when() ) + { + t.clear_changed(); + t.do_callback(); + } + else + { + t.set_changed(); + } + } + + t.value_damage(); +} + +void Flu_Spinner :: resize( int X, int Y, int W, int H ) +{ + // we always want the buttons to be square and half the height of the widget + Fl_Valuator::resize( X, Y, W, H ); +} + +void Flu_Spinner :: value_damage() +{ + char *buf; + if( align() & FL_ALIGN_INSIDE ) + { + int len = strlen(label()); + buf = (char*)malloc( len + 128 ); + sprintf( buf, "%s", label() ); + format( buf + len ); + } + else + { + buf = (char*)malloc( 128 ); + format( buf ); + } + _input.value(buf); + + if( align() == FL_ALIGN_INSIDE || !_editable ) + _input.position( _input.size() ); + else + _input.position( 0, _input.size() ); + + free( buf ); +} + +void Flu_Spinner::draw() +{ + int W = w()*15/100; + if( W < h()/2 ) + W = h()/2; + int X = x()+w()-W, Y = y(); + + // fltk 2.0 behavior + bool refresh; + if( step() >= 1.0 ) + { + refresh = ( _input.type() != FL_INT_INPUT ); + _input.type( FL_INT_INPUT ); + } + else + { + refresh = ( _input.type() != FL_FLOAT_INPUT ); + _input.type( FL_FLOAT_INPUT ); + } + if( refresh ) + value_damage(); + + // draw the up/down arrow buttons + fl_draw_box( (Fl_Boxtype)_valbox[0], X, Y, W, h()/2, color() ); + fl_draw_box( (Fl_Boxtype)_valbox[1], X, Y+h()/2, W, h()/2, color() ); + fl_color( active_r() ? FL_FOREGROUND_COLOR : fl_inactive(FL_FOREGROUND_COLOR) ); + fl_polygon( X+4, Y+h()/2-4, X+W/2, Y+4, X+W-4, Y+h()/2-4 ); + Y += h()/2; + fl_polygon( X+4, Y+4, X+W/2, Y+h()/2-4, X+W-4, Y+4 ); + + _input.resize( x(), y(), w()-h()/2-1, h() ); + _input.redraw(); +} + +void Flu_Spinner :: increment_cb() +{ + int oldWhen = when(); + int amt = Fl::event_state( FL_SHIFT | FL_CTRL | FL_ALT ) ? 10 : 1; + if( _up ) + _setvalue(increment(value(),1*amt)); + else + _setvalue(increment(value(),-1*amt)); + when( oldWhen ); + _lastValue = value(); +} + +void Flu_Spinner :: repeat_callback( void* arg ) +{ + Flu_Spinner* c = (Flu_Spinner*)arg; + c->increment_cb(); + + float delay = c->_repeatTime[0]; + if( c->_pushed && c->_totalTime >= c->_rapidDelay ) + delay = c->_repeatTime[1]; + + c->_totalTime += delay; + + Fl::repeat_timeout( delay, repeat_callback, c ); +} + +int Flu_Spinner::handle(int event) +{ + int W = w()*15/100; + if( W < h()/2 ) + W = h()/2; + int X = x()+w()-W, Y = y(); + + if( (align() & FL_ALIGN_INSIDE) || !_editable ) + { + _input.readonly( true ); + _input.cursor_color( FL_WHITE ); + } + else + { + _input.readonly( false ); + _input.cursor_color( FL_BLACK ); + } + + switch( event ) + { + case FL_PUSH: + _dragging = true; + if (Fl::visible_focus() && handle(FL_FOCUS)) Fl::focus(this); + _lastValue = value(); + _lastY = Fl::event_y(); + Fl::remove_timeout( repeat_callback, this ); + if( Fl::event_inside( X, Y, W, h()/2 ) ) // up button + { + _pushed = true; + _valbox[0] = FL_DOWN_BOX; + _up = true; + } + if( Fl::event_inside( X, Y+h()/2, W, h()/2 ) ) // down button + { + _pushed = true; + _valbox[1] = FL_DOWN_BOX; + _up = false; + } + if( _pushed ) + { + increment_cb(); + _totalTime = _initialDelay; + if( _doRepeat ) + Fl::add_timeout( _initialDelay, repeat_callback, this); + handle_push(); + take_focus(); + redraw(); + return 1; + } + break; + + case FL_DRAG: + { + // only do the dragging if the last Y differs from the current Y by more than 3 pixels + if( ABS(_lastY-Fl::event_y()) < 3 ) + break; + _dragging = true; + _pushed = false; + Fl::remove_timeout( repeat_callback, this ); + int oldWhen = when(); + _setvalue(increment(_lastValue,(_lastY-Fl::event_y())*(Fl::event_state(FL_SHIFT|FL_CTRL|FL_ALT)?10:1))); + _valbox[0] = _valbox[1] = FL_DOWN_BOX; + when( oldWhen ); + fl_cursor((Fl_Cursor)22); + _input.redraw(); + redraw(); + } + break; + + case FL_RELEASE: + { + bool doCB = ( ( when() & FL_WHEN_RELEASE ) || ( when() & FL_WHEN_RELEASE_ALWAYS ) ) && + ( _pushed || ( _valbox[0] == FL_DOWN_BOX ^ _valbox[1] == FL_DOWN_BOX ) ); + _pushed = false; + _dragging = false; + Fl::remove_timeout( repeat_callback, this ); + _valbox[0] = _valbox[1] = FL_UP_BOX; + fl_cursor(FL_CURSOR_DEFAULT); + redraw(); + handle_release(); + if( doCB ) + do_callback(); + _input.take_focus(); + } + break; + + case FL_FOCUS: + case FL_UNFOCUS: + redraw(); + _input.take_focus(); + return 0; + + case FL_ENTER: + if( Fl::event_inside( &_input ) ) + return _input.handle(event); + else if( active_r() ) + { + fl_cursor(FL_CURSOR_DEFAULT); + return 1; + } + break; + + case FL_LEAVE: + if( Fl::event_inside( &_input ) ) + return _input.handle(event); + else if( active_r() ) + { + fl_cursor(FL_CURSOR_DEFAULT); + return 1; + } + break; + + case FL_KEYBOARD: + switch( Fl::event_key() ) + { + case FL_Down: + { + int oldWhen = when(); when( FL_WHEN_CHANGED ); + _setvalue(increment(value(),-1*(Fl::event_state(FL_SHIFT|FL_CTRL|FL_ALT)?10:1))); + when( oldWhen ); + redraw(); + return 1; + } + case FL_Up: + { + int oldWhen = when(); when( FL_WHEN_CHANGED ); + _setvalue(increment(value(),1*(Fl::event_state(FL_SHIFT|FL_CTRL|FL_ALT)?10:1))); + when( oldWhen ); + redraw(); + return 1; + } + } + break; + } + + return _input.handle(event); +} + +void Flu_Spinner :: _setvalue( double v ) +{ + if( _wrapRange ) + { + while( v > maximum() ) + v = minimum() + (v - maximum()); + while( v < minimum() ) + v = maximum() - (minimum() - v); + } + else + { + v = clamp(v); + } + handle_drag(v); +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Toggle_Group.cpp b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Toggle_Group.cpp new file mode 100644 index 0000000..9dc0041 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Toggle_Group.cpp @@ -0,0 +1,97 @@ +// $Id: Flu_Toggle_Group.cpp,v 1.10 2004/09/16 01:32:25 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#include "FLU/Flu_Toggle_Group.h" +#include + +Flu_Toggle_Group :: Flu_Toggle_Group( int x, int y, int w, int h, const char *l ) + : Fl_Group( x, y, w, h, l ) +{ + chkBtn = new Fl_Check_Button( 0, 0, 0, 0 ); + chkBtn->callback( _toggleCB, this ); + box( FL_EMBOSSED_FRAME ); + align( FL_ALIGN_LEFT | FL_ALIGN_INSIDE ); +} + +void Flu_Toggle_Group :: toggleCB() +{ + do_callback(); + redraw(); +} + +void Flu_Toggle_Group :: draw() +{ + int lblW = 0, lblH, X, i; + + if( label() == 0 ) + lblW = lblH = 0; + else if( strlen( label() ) == 0 ) + lblW = lblH = 0; + else + { + measure_label( lblW, lblH ); + lblW += 18; + lblH += 2; + } + + // align the label + if( align() & FL_ALIGN_LEFT ) + X = 4; + else if( align() & FL_ALIGN_RIGHT ) + X = w() - lblW - 8; + else + X = w()/2 - lblW/2 - 2; + + // draw the main group box + if( damage() & ~FL_DAMAGE_CHILD ) + fl_draw_box( box(), x(), y()+lblH/2, w(), h()-lblH/2, color() ); + + unsigned char *active = 0; + if( !chkBtn->value() ) + { + active = (unsigned char*)malloc( children() ); + for( i = 1; i < children(); i++ ) + { + active[i-1] = child(i)->active(); + child(i)->deactivate(); + } + } + + // clip and draw the children + chkBtn->resize( chkBtn->x(), chkBtn->y(), 0, 0 ); + fl_clip( x()+2, y()+lblH+1, w()-4, h()-lblH-3 ); + draw_children(); + fl_pop_clip(); + + // clear behind the button and draw it + fl_color( color() ); + fl_rectf( x()+X, y(), lblW+4, lblH ); + fl_color( labelcolor() ); + chkBtn->label( label() ); + chkBtn->resize( x()+X+2, y(), lblW, lblH ); + draw_child( *chkBtn ); + + if( !chkBtn->value() ) + { + for( i = 1; i < children(); i++ ) + { + if( active[i-1] ) + child(i)->activate(); + else + child(i)->deactivate(); + } + free( active ); + } +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Tree_Browser.cpp b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Tree_Browser.cpp new file mode 100644 index 0000000..6bec228 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Tree_Browser.cpp @@ -0,0 +1,3698 @@ +// $Id: Flu_Tree_Browser.cpp,v 1.126 2004/11/05 17:03:20 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#include +#include +#include +#include + +#include "FLU/Flu_Tree_Browser.h" +#include "FLU/flu_pixmaps.h" + +#define MAX( x, y ) ( (x)>(y) ? (x) : (y) ) +#define MIN( x, y ) ( (x)<(y) ? (x) : (y) ) +#define ABS( x ) ( (x)>0 ? (x) : -(x) ) +#define LERP( t, x0, x1 ) ( (x0) + (t)*( (x1) - (x0) ) ) + +bool Flu_Tree_Browser::USE_FLU_WIDGET_CALLBACK = false; + +#ifdef USE_FLU_DND +Flu_Tree_Browser :: DND_Object :: DND_Object() : Flu_DND( "DND_Object" ) +{ +} +#endif + +Flu_Tree_Browser :: IntStack :: IntStack() +{ + _list = NULL; + _size = _bufferSize = 0; +} + +Flu_Tree_Browser :: IntStack :: IntStack( const Flu_Tree_Browser::IntStack& s ) +{ + _list = NULL; + _size = _bufferSize = 0; + *this = s; +} + +Flu_Tree_Browser :: IntStack :: ~IntStack() +{ + clear(); +} + +Flu_Tree_Browser::IntStack& Flu_Tree_Browser :: IntStack :: operator =( const Flu_Tree_Browser::IntStack& s ) +{ + clear(); + if( s._size ) + { + _list = (int*)malloc( s._size*sizeof(int) ); + memcpy( _list, s._list, s._size*sizeof(int) ); + _size = _bufferSize = s._size; + } + return *this; +} + +void Flu_Tree_Browser :: IntStack :: push( int i ) +{ + if( _size == _bufferSize ) + { + // allocate a new list + _bufferSize += 4; + int *newList = (int*)malloc( _bufferSize*sizeof(int) ); + // copy the old list + if( _size > 0 ) + memcpy( newList, _list, _size*sizeof(int) ); + if( _list ) + free( _list ); + _list = newList; + } + // add the new item + _list[_size] = i; + _size++; +} + +int Flu_Tree_Browser :: IntStack :: pop() +{ + if( _size == 0 ) + return 0; + int val = _list[_size]; + _size--; + return val; +} + +void Flu_Tree_Browser :: IntStack :: clear() +{ + if( _list ) + free( _list ); + _list = NULL; + _size = _bufferSize = 0; +} + +Flu_Tree_Browser :: NodeList :: NodeList() +{ + _nodes = NULL; + _nNodes = _size = 0; +} + +Flu_Tree_Browser :: NodeList :: ~NodeList() +{ + clear(); +} + +typedef Flu_Tree_Browser::Node* NodeP; + +bool Flu_Tree_Browser :: NodeList :: search( const char *n, int &index ) +{ + index = _nNodes; + if( _nNodes == 0 ) + return false; + + // we know we have at least one node. so use it to get the RData struct to find out what + // the insertion mode is + int iMode = _nodes[0]->tree->insertion_mode(); + + if( iMode == FLU_INSERT_SORTED || iMode == FLU_INSERT_SORTED_REVERSE ) + return( binSearch( n, index ) ); + else + return( linSearch( n, index ) ); +} + +bool Flu_Tree_Browser :: NodeList :: search( Node *n, int &index ) +{ + index = _nNodes; + if( _nNodes == 0 ) + return false; + + // we know we have at least one node. so use it to get the RData struct to find out what + // the insertion mode is + int iMode = _nodes[0]->tree->insertion_mode(); + + if( iMode == FLU_INSERT_SORTED || iMode == FLU_INSERT_SORTED_REVERSE ) + return( binSearch( n, index ) ); + else + return( linSearch( n, index ) ); +} + +bool Flu_Tree_Browser :: NodeList :: linSearch( const char *n, int &index ) +{ + index = _nNodes; + for( int i = 0; i < _nNodes; i++ ) + { + if( strcmp( n, _nodes[i]->label() ) == 0 ) + { + index = i; + return true; + } + } + return false; +} + +bool Flu_Tree_Browser :: NodeList :: linSearch( Node *n, int &index ) +{ + index = _nNodes; + for( int i = 0; i < _nNodes; i++ ) + { + if( n == _nodes[i] ) + { + index = i; + return true; + } + } + return false; +} + +bool Flu_Tree_Browser :: NodeList :: binSearch( Node *n, int &index ) +{ + if( binSearch( n->label(), index ) ) + { + // the search found the first node with the label. since there are identical entries + // allowed, it may not be the actual node we want. therefore search forward until we find it + for( ; index < _nNodes; index++ ) + if( _nodes[index] == n ) + return true; + return false; + } + else + return false; +} + +bool Flu_Tree_Browser :: NodeList :: binSearch( const char *n, int &index ) +{ + // do a binary search for a child with name == "n" + // return true if the child is found, and store its index in "index" + // return false if the child is not found, and store the index it would + // be in in "index" + + // special case: no nodes + if( _nNodes == 0 ) + { + index = 0; + return false; + } + + // we know we have at least one node. so use it to get the RData struct to find out what + // the insertion mode is + int iMode = _nodes[0]->tree->insertion_mode(); + + // special case: 1 node + if( _nNodes == 1 ) + { + int val = strcmp( n, _nodes[0]->label() ); + if( iMode == FLU_INSERT_SORTED_REVERSE ) + val *= -1; + if( val == 0 ) + { + index = 0; + return true; + } + else if( val < 0 ) + index = 0; + else + index = 1; + return false; + } + + int first = 0, last = _nNodes - 1; + int val1, val2, mVal; + for(;;) + { + // the range is down to 2 nodes + if( last == first + 1 ) + { + val1 = strcmp( n, _nodes[first]->label() ); + if( iMode == FLU_INSERT_SORTED_REVERSE ) + val1 = -val1; + if( val1 < 0 ) + { + index = first; + return false; + } + else if( val1 == 0 ) + { + index = first; + break; + } + val2 = strcmp( n, _nodes[last]->label() ); + if( iMode == FLU_INSERT_SORTED_REVERSE ) + val2 = -val2; + if( val2 < 0 ) + { + index = last; + return false; + } + else if( val2 == 0 ) + { + index = last; + break; + } + else + { + index = last+1; + return false; + } + } + + // pick which half of the array to search next + int midpoint = first + ((last-first)>>1); + mVal = strcmp( n, _nodes[midpoint]->label() ); + if( iMode == FLU_INSERT_SORTED_REVERSE ) + mVal = -mVal; + if( mVal < 0 ) + last = midpoint; + else if( mVal > 0 ) + first = midpoint; + else + { + index = midpoint; + break; + } + } + + // we found *a* node equal to "n", now find the first node equal to "n" + // by searching until we hit a node not equal to "n" + for( first = index; first > 0; first-- ) + if( strcmp( n, _nodes[first-1]->label() ) != 0 ) + break; + index = first; + + return true; +} + +int Flu_Tree_Browser :: NodeList :: compareNodes( const void *arg1, const void* arg2 ) +{ + Flu_Tree_Browser::Node *n1 = *((Flu_Tree_Browser::Node**)arg1), *n2 = *((Flu_Tree_Browser::Node**)arg2); + return strcmp( n1->text.c_str(), n2->text.c_str() ); +} + +int Flu_Tree_Browser :: NodeList :: reverseCompareNodes( const void *arg1, const void* arg2 ) +{ + Flu_Tree_Browser::Node *n1 = *((Flu_Tree_Browser::Node**)arg1), *n2 = *((Flu_Tree_Browser::Node**)arg2); + return( -strcmp( n1->text.c_str(), n2->text.c_str() ) ); +} + +void Flu_Tree_Browser :: NodeList :: sort() +{ + if( _nNodes ) + { + // we know we have at least one node. so use it to get the RData struct to find out what + // the insertion mode is + int iMode = _nodes[0]->tree->insertion_mode(); + if( iMode == FLU_INSERT_SORTED ) + qsort( _nodes, _nNodes, sizeof(Node*), compareNodes ); + else if( iMode == FLU_INSERT_SORTED_REVERSE ) + qsort( _nodes, _nNodes, sizeof(Node*), reverseCompareNodes ); + } +} + +Flu_Tree_Browser::Node* Flu_Tree_Browser :: Node :: insert( const char* fullpath, int pos ) +{ + // insert the new node at the back of the tree + int imode = tree->insertion_mode(); + tree->insertion_mode( FLU_INSERT_BACK ); + Node *n = add( fullpath ); + tree->insertion_mode( imode ); + if( !n ) return NULL; + // find the node at position "pos" and + // move the new node before it, so it takes over position "pos" + if( pos < 0 ) pos = 0; + if( pos >= children() ) pos = children()-1; + move( n, MOVE_BEFORE, child(pos) ); + return n; +} + +Flu_Tree_Browser::Node* Flu_Tree_Browser :: Node :: insert_branch( const char* fullpath, int pos ) +{ + FluSimpleString p( fullpath ); + if( p.size() && p[p.size()-1] != '/' && p[p.size()-1] != '\\' ) p += "/"; + return insert( p.c_str(), pos ); +} + +Flu_Tree_Browser::Node* Flu_Tree_Browser :: Node :: insert_leaf( const char* fullpath, int pos ) +{ + FluSimpleString p( fullpath ); + if( p.size() && ( p[p.size()-1] == '/' || p[p.size()-1] == '\\' ) ) p[p.size()-1] = '\0'; + return insert( p.c_str(), pos ); +} + +bool Flu_Tree_Browser :: Node :: move( int pos ) +{ + // get this node's position + int i = index(); + if( i == -1 ) return false; + // get the node in our parent at index "pos" + if( !parent() ) return false; + if( pos < 0 ) pos = 0; + if( pos >= parent()->children() ) pos = parent()->children()-1; + Node *n = parent()->child( pos ); + // move this node to be before its sibling, so it takes over position "pos" + return move( this, MOVE_BEFORE, n ); +} + +bool Flu_Tree_Browser :: Node :: swap( Node* n1, Node* n2 ) +{ + if( n1->tree != n2->tree ) return false; + Node *p1 = n1->parent(), *p2 = n2->parent(); + if( !p1 || !p2 ) return false; + int i, index1 = -1, index2 = -1; + for( i = 0; i < p1->children(); i++ ) + { + if( p1->child(i) == n1 ) + { + index1 = i; + break; + } + } + if( index1 == -1 ) return false; + for( i = 0; i < p2->children(); i++ ) + { + if( p2->child(i) == n2 ) + { + index2 = i; + break; + } + } + if( index2 == -1 ) return false; + p1->_children._nodes[index1] = n2; + p2->_children._nodes[index2] = n1; + return true; +} + +bool Flu_Tree_Browser :: Node :: move( Node* n1, int where, Node* n2 ) +{ + if( isMoveValid( n1, where, n2 ) ) + return( NodeList::move( n1, where, n2 ) ); + else + return false; +} + +void Flu_Tree_Browser :: Node :: sort() +{ + _children.sort(); + for( int i = 0; i < _children.size(); i++ ) + _children.child(i)->sort(); +} + +bool Flu_Tree_Browser :: Node :: is_ancestor( Node* n ) +{ + Node *p = parent(); + while( p ) + { + if( p == n ) + return true; + else + p = p->parent(); + } + return false; +} + +bool Flu_Tree_Browser :: Node :: is_descendent( Node* n ) +{ + return n->is_ancestor( this ); +} + +bool Flu_Tree_Browser :: NodeList :: move( Node* n1, int where, Node* n2 ) +{ + if( !n1 || !n2 ) + return false; + + if( n1->tree ) + n1->tree->redraw(); + if( n2->tree ) + n2->tree->redraw(); + + // try to move n1 to the first child position of n2 + if( where == MOVE_INSIDE ) + { + if( !n2->is_branch() ) + return false; + // get the parent of n1 + Node* p1 = n1->parent(); + if( p1 ) + // remove n1 from its parent's list + p1->_children.erase( n1 ); + // insert into n2 + int iMode = n1->tree->insertion_mode(); + if( iMode == FLU_INSERT_SORTED || iMode == FLU_INSERT_SORTED_REVERSE ) + n2->_children.add( n1 ); + else + n2->_children.add( n1, 0 ); + // update the parent of n1 + n1->_parent = n2; + return true; + } + + // find the position of n2 in its parent's list + Node* p2 = n2->parent(); + if( !p2 ) + return false; + int index = 0, removed = -1; + if( p2->_children.search( n2, index ) ) + { + // get the parent of n1 + Node* p1 = n1->parent(); + if( p1 ) + // remove n1 from its parent's list. remember the position it was removed from + removed = p1->_children.erase( n1 ); + + // if n1 and n2 have the same parent, and if n1 came before the spot where + // n2 will be inserted, then our indexing is off by one because n1 has been removed + if( p1 == p2 && removed <= index ) + index--; + + if( where == MOVE_AFTER ) + index++; + + // insert n1 at the proper position + p2->_children.add( n1, index ); + + // update the parent of n1 + n1->_parent = p2; + } + + return true; +} + +void Flu_Tree_Browser :: NodeList :: add( Node* n, int position ) +{ + int i, index; + int mode = n->tree->insertion_mode(); + + // if the list is out of room, allocate a new one that's bigger + if( _nNodes == _size ) + { + int newSize = ( _size == 0 ) ? 1 : _size*2; // double the size of the old list (same behavior as STL vector) + // allocate the new list + Node** newNodes = new NodeP[ newSize ]; + // copy the old list to the new list + memcpy( newNodes, _nodes, _nNodes*sizeof(Node*) ); + // delete the old list and replace it with the new list + delete[] _nodes; + //n->tree->rdata.cbNode = NULL; + _nodes = newNodes; + _size = newSize; + } + + if( position >= 0 ) + { + if( position > _nNodes ) + index = _nNodes; + else + index = position; + } + else if( mode == FLU_INSERT_SORTED || mode == FLU_INSERT_SORTED_REVERSE ) + { + // search through the list until we find where to insert the node + binSearch( n->label(), index ); + } + else if( mode == FLU_INSERT_FRONT ) + { + index = 0; + } + else if( mode == FLU_INSERT_BACK ) + { + index = _nNodes; + } + else + return; + + // shift all entries from the new insertion point down one spot + // to make room for the new node + for( i = _nNodes - 1; i >= index; i-- ) + _nodes[i+1] = _nodes[i]; + + // add the new node + _nodes[index] = n; + + _nNodes++; +} + +int Flu_Tree_Browser :: NodeList :: erase( Node *n ) +{ + if( n == NULL ) + return -1; + + int index; + if( search( n, index ) ) + { + // move all the others down one spot to remove the node + for( int i = index; i < _nNodes-1; i++ ) + _nodes[i] = _nodes[i+1]; + _nNodes--; + + return index; + } + return -1; +} + +int Flu_Tree_Browser :: NodeList :: erase( const char* n ) +{ + if( _nNodes == 0 ) + return -1; + + int index; + if( search( n, index ) ) + { + // move all the others down one spot to remove the node + for( int i = index; i < _nNodes-1; i++ ) + _nodes[i] = _nodes[i+1]; + _nNodes--; + return index; + } + return -1; +} + +void Flu_Tree_Browser :: NodeList :: erase( int n ) +{ + // make sure n is in range + if( ( n < 0 ) || ( n >= _nNodes ) ) + return; + + // move all the others down one spot to remove the node + for( int i = n; i < _nNodes-1; i++ ) + _nodes[i] = _nodes[i+1]; + + _nNodes--; +} + +void Flu_Tree_Browser :: NodeList :: clear() +{ + if( _nodes ) + { + //if( _nNodes ) + //if( _nodes[0] ) + // _nodes[0]->tree->rdata.cbNode = NULL; + delete[] _nodes; + } + _nodes = NULL; + _nNodes = _size = 0; +} + +int Flu_Tree_Browser :: NodeList :: findNum( const char *n ) +{ + if( ( _nNodes == 0 ) || ( n == 0 ) ) + return 0; + + // see if there is a first node equal to "n" + int index, last; + if( !search( n, index ) ) + return 0; + + // now search forward until we hit a node not equal to "n" + for( last = index; last < _nNodes-1; last++ ) + if( strcmp( n, _nodes[last+1]->label() ) != 0 ) + break; + + return last - index + 1; +} + +Flu_Tree_Browser::Node* Flu_Tree_Browser :: NodeList :: find( const char* n, int which ) +{ + if( ( _nNodes == 0 ) || ( n == 0 ) || ( which == 0 ) ) + return NULL; + + // see if there is a first node equal to "n" + int index, first; + if( !search( n, first ) ) + return NULL; + + // now search forward and try to find the which'th node named "n" + int total = 0; + for( index = first; index < _nNodes; index++ ) + { + if( strcmp( n, _nodes[index]->label() ) == 0 ) + { + total++; + if( total == which ) + break; + } + else + break; + } + if( total != which ) + return NULL; + + return _nodes[index]; +} + +#define SCROLL_SIZE 15 + +Flu_Tree_Browser :: Flu_Tree_Browser( int x, int y, int w, int h, const char *l ) + : Fl_Group( x, y, w, h ) +#ifdef USE_FLU_DND + , Flu_DND( "Flu_Tree_Browser" ) +#endif +{ + //lastEvent = -1; + autoScrollX = autoScrollY = 0.0f; +#ifdef USE_FLU_DND + dnd_allow_type( "Flu_Tree_Browser" ); + dnd_allow_type( "DND_Object" ); + dnd_allow_text( true ); +#endif + + // add some widgets + _box = new Fl_Group( x, y, w-SCROLL_SIZE, h-SCROLL_SIZE ); + _box->resizable( NULL ); + _box->end(); + //_box->set_output(); + scrollV = new Fl_Scrollbar( x+w-SCROLL_SIZE, y, SCROLL_SIZE, h-SCROLL_SIZE ); + scrollV->type( FL_VERTICAL ); + scrollV->callback( _scrollCB, this ); + scrollV->value( 0, 1, 0, 0 ); + scrollH = new Fl_Scrollbar( x, y+h-SCROLL_SIZE, w-SCROLL_SIZE, SCROLL_SIZE ); + scrollH->type( FL_HORIZONTAL ); + scrollH->callback( _scrollCB, this ); + scrollH->value( 0, 1, 0, 0 ); + scrollBox = new Fl_Group( x+w-SCROLL_SIZE, y+h-SCROLL_SIZE, SCROLL_SIZE, SCROLL_SIZE ); + scrollBox->box( FL_UP_BOX ); + scrollBox->end(); + resizable( _box ); + + // set up the recursive data structure + memset( &rdata, 0, sizeof(rdata) ); + rdata.root = &root; + root.tree = this; + rdata.cbNode = NULL; + rdata.cbReason = FLU_NOTHING; + rdata.tree = this; + rdata.dragging = false; + rdata.forceResize = true; + rdata.shiftSelect = false; + rdata.shiftSelectAll = false; + rdata.nextId = 1; + rdata.searchIndex = 1; + rdata.defaultCollapseIcons[0] = new Fl_Pixmap( (char*const*)plus_xpm ); + rdata.defaultCollapseIcons[1] = new Fl_Pixmap( (char*const*)minus_xpm ); + rdata.defaultBranchIcons[0] = new Fl_Pixmap( (char*const*)folder_closed_xpm ); + rdata.defaultBranchIcons[1] = new Fl_Pixmap( (char*const*)folder_open_xpm ); + + end(); + + // set the default values for the tree + selection_follows_hilight( false ); + select_under_mouse( false ); + open_without_children( true ); + auto_branches( false ); + animate( false ); + collapse_time( 0.1f ); + double_click_opens( true ); + move_only_same_group( false ); + frame_rate( 100.0f ); + allow_leaf_duplication( true ); + shaded_entry_colors( FL_WHITE, FL_WHITE ); + collapse_icons( NULL, NULL ); + //branch_icons( NULL, NULL ); + rdata.branchIcons[0] = rdata.defaultBranchIcons[0]; + rdata.branchIcons[1] = rdata.defaultBranchIcons[1]; + leaf_icon( NULL ); + branch_text( FL_BLACK, FL_HELVETICA_BOLD, 12 ); + leaf_text( FL_BLACK, FL_HELVETICA, 12 ); + //callback( NULL ); + when( FL_WHEN_CHANGED ); + color( FL_WHITE ); + selection_color( FL_SELECTION_COLOR ); + box( FL_FLAT_BOX ); + connector_style( FL_DARK2, FL_DOT ); + selection_mode( FLU_MULTI_SELECT ); + selection_drag_mode( FLU_DRAG_TO_SELECT ); + insertion_mode( FLU_INSERT_SORTED ); + show_connectors( true ); + show_root( true ); + show_leaves( true ); + show_branches( true ); + open_on_select( false ); + //root_always_open( false ); + horizontal_gap( 2 ); + vertical_gap( 0 ); + widget_gap( 2 ); + set_root( l ); + + resize( x, y, w, h ); +} + +Flu_Tree_Browser :: ~Flu_Tree_Browser() +{ + Fl::remove_timeout( _timerRedrawCB, this ); + Fl::remove_timeout( _timerScrollCB, this ); + + delete rdata.defaultCollapseIcons[0]; + delete rdata.defaultCollapseIcons[1]; + + delete rdata.defaultBranchIcons[0]; + delete rdata.defaultBranchIcons[1]; +} + +void Flu_Tree_Browser :: auto_branches( bool b ) +{ + rdata.autoBranches = b; +} + +void Flu_Tree_Browser :: collapse_icons( Fl_Image *closed, Fl_Image *open ) +{ + if( closed ) + rdata.collapseIcons[0] = closed; + else + rdata.collapseIcons[0] = rdata.defaultCollapseIcons[0]; + + if( open ) + rdata.collapseIcons[1] = open; + else + rdata.collapseIcons[1] = rdata.defaultCollapseIcons[1]; +} + +void Flu_Tree_Browser :: branch_icons( Fl_Image *closed, Fl_Image *open ) +{ + //if( closed ) + rdata.branchIcons[0] = closed; + //else + //rdata.branchIcons[0] = rdata.defaultBranchIcons[0]; + + //if( open ) + rdata.branchIcons[1] = open; + //else + //rdata.branchIcons[1] = rdata.defaultBranchIcons[1]; +} + +void Flu_Tree_Browser :: set_default_branch_icons() +{ + rdata.branchIcons[0] = rdata.defaultBranchIcons[0]; + rdata.branchIcons[1] = rdata.defaultBranchIcons[1]; +} + +void Flu_Tree_Browser :: leaf_icon( Fl_Image *icon ) +{ + rdata.leafIcon = icon; +} + +bool Flu_Tree_Browser :: inside_entry_area( int x, int y ) +{ + if( scrollH->visible() && scrollV->visible() ) + return( x > _box->x() && y > _box->y() && + x < (_box->x()+_box->w()-scrollV->w()) && + y < (_box->y()+_box->h()-scrollH->h()) ); + else if( !scrollH->visible() && !scrollV->visible() ) + return( x > _box->x() && y > _box->y() && + x < (_box->x()+_box->w()) && + y < (_box->y()+_box->h()) ); + else if( scrollH->visible() ) + return( x > _box->x() && y > _box->y() && + x < (_box->x()+_box->w()) && + y < (_box->y()+_box->h()-scrollH->h()) ); + else + return( x > _box->x() && y > _box->y() && + x < (_box->x()+_box->w()-scrollV->w()) && + y < (_box->y()+_box->h()) ); +} + +void Flu_Tree_Browser :: resize( int X, int Y, int W, int H ) +{ + Fl_Group::resize( X, Y, W, H ); + + int dx = Fl::box_dx(box()), dy = Fl::box_dy(box()), dw = Fl::box_dw(box()), dh = Fl::box_dh(box()); + + rdata.x = X+dx; rdata.y = Y+dy; rdata.totalW = rdata.x; + root.recurse( rdata, Node::MEASURE ); + rdata.totalW -= X-dx; + rdata.totalH = rdata.y - Y-dy; + + // if the size of the tree is bigger than the window, turn on the scrollbars + bool hOn = false, vOn = false; + if( rdata.totalW > W-dw ) + hOn = true; + if( rdata.totalH > H-dh ) + vOn = true; + + // check if turning on one scrollbar actually forces the other to turn on + if( hOn && ( rdata.totalH > H-SCROLL_SIZE ) ) + vOn = true; + if( vOn && ( rdata.totalW > W-SCROLL_SIZE ) ) + hOn = true; + + // now resize the other kids depending on the state of the scrollbars + + _box->resize( X, Y, W, H ); + if( hOn && vOn ) // both scrollbars on + { + scrollH->resize( X+dx, Y+H-SCROLL_SIZE-dy, W-SCROLL_SIZE-dw, SCROLL_SIZE ); + scrollH->show(); + scrollV->resize( X+W-SCROLL_SIZE-dx, Y+dy, SCROLL_SIZE, H-SCROLL_SIZE-dh ); + scrollV->show(); + scrollBox->resize( X+W-SCROLL_SIZE-dx, Y+H-SCROLL_SIZE-dy, SCROLL_SIZE, SCROLL_SIZE ); + scrollBox->show(); + + // set the scrollbar sizes and values + int hDelta = rdata.totalW - W+dw + SCROLL_SIZE, scrollHW = scrollH->w()-SCROLL_SIZE-SCROLL_SIZE; + hDelta = MAX( hDelta, 0 ); + scrollH->value( MIN( scrollH->value(), hDelta ), 1, 0, hDelta ); + scrollH->slider_size( MAX( (float)SCROLL_SIZE/float(scrollHW), float(scrollHW-hDelta)/float(scrollHW) ) ); + + int vDelta = rdata.totalH - H+dh + SCROLL_SIZE, scrollVH = scrollV->h()-SCROLL_SIZE-SCROLL_SIZE; + vDelta = MAX( vDelta, 0 ); + scrollV->value( MIN( scrollV->value(), vDelta ), 1, 0, vDelta ); + scrollV->slider_size( MAX( (float)SCROLL_SIZE/float(scrollVH), float(scrollVH-vDelta)/float(scrollVH) ) ); + _box->resize( X, Y, W-SCROLL_SIZE, H-SCROLL_SIZE ); + } + else if( !hOn && !vOn ) // neither on + { + scrollH->hide(); + scrollV->hide(); + scrollBox->hide(); + } + else if( hOn ) // just horizontal on + { + scrollH->resize( X+dx, Y+H-SCROLL_SIZE-dy, W-dw, SCROLL_SIZE ); + scrollH->show(); + scrollV->hide(); + scrollBox->hide(); + + // set the scrollbar size and value + int hDelta = rdata.totalW - W+dw, scrollHW = scrollH->w()-SCROLL_SIZE-SCROLL_SIZE; + hDelta = MAX( hDelta, 0 ); + scrollH->value( MIN( scrollH->value(), hDelta ), 1, 0, hDelta ); + scrollH->slider_size( MAX( (float)SCROLL_SIZE/float(scrollHW), float(scrollHW-hDelta)/float(scrollHW) ) ); + _box->resize( X, Y, W, H-SCROLL_SIZE ); + } + else if( vOn ) // just vertical on + { + scrollH->hide(); + scrollV->resize( X+W-SCROLL_SIZE-dx, Y+dy, SCROLL_SIZE, H-dh ); + scrollV->show(); + scrollBox->hide(); + + // set the scrollbar size and value + int vDelta = rdata.totalH - H+dh, scrollVH = scrollV->h()-SCROLL_SIZE-SCROLL_SIZE; + vDelta = MAX( vDelta, 0 ); + scrollV->value( MIN( scrollV->value(), vDelta ), 1, 0, vDelta ); + scrollV->slider_size( MAX( (float)SCROLL_SIZE/float(scrollVH), float(scrollVH-vDelta)/float(scrollVH) ) ); + _box->resize( X, Y, W-SCROLL_SIZE, H ); + } + + rdata.browserX = _box->x() + dx; + rdata.browserY = _box->y() + dy; + rdata.browserW = _box->w() - dw; + rdata.browserH = _box->h() - dh; + + redraw(); + + rdata.forceResize = true; // weird hack to get the scrollbars to turn on right the first time +} + +void Flu_Tree_Browser :: on_dnd_leave() +{ +#ifdef USE_FLU_DND + rdata.isMoveValid = false; + redraw(); + + // X + if( scrollH->visible() ) + { + float max = 0.01f * (scrollH->maximum() - scrollH->minimum()); + if( max < 10.0f ) max = 10.0f; + if( autoScrollX > 0.0f ) + autoScrollX = max; + else + autoScrollX = -max; + } + + // Y + if( scrollV->visible() ) + { + float max = 0.01f * (scrollV->maximum() - scrollV->minimum()); + if( max < 10.0f ) max = 10.0f; + if( autoScrollY > 0.0f ) + autoScrollY = max; + else + autoScrollY = -max; + } +#endif +} + +bool Flu_Tree_Browser :: on_dnd_drag( int X, int Y ) +{ +#ifdef USE_FLU_DND + rdata.dragging = true; + + autoScrollX = autoScrollY = 0.0f; + + if( scrollH->visible() ) + { + // auto-scroll the horizontal scrollbars based on how close to the left or right of the browser the mouse is + float min = 1.0f, max = 0.01f * (scrollH->maximum() - scrollH->minimum()); + if( max < 10.0f ) max = 10.0f; + if( X < (x()+30) ) // left + { + float t = float((x()+30) - X) / 30.0f; + autoScrollX = -LERP( t*t, min, max ); + if( !scrolledTimerOn ) + Fl::add_timeout( 0.0, _timerScrollCB, this ); + } + else if( X > (x()+w()-30) ) // right + { + float t = float(X - (x()+w()-30)) / 30.0f; + autoScrollX = LERP( t*t, min, max ); + if( !scrolledTimerOn ) + Fl::add_timeout( 0.0, _timerScrollCB, this ); + } + } + + if( scrollV->visible() ) + { + // auto-scroll the vertical scrollbars based on how close to the top or bottom of the browser the mouse is + float min = 1.0f, max = 0.01f * (scrollV->maximum() - scrollV->minimum()); + if( max < 10.0f ) max = 10.0f; + if( Y < (y()+30) ) // top + { + float t = float((y()+30) - Y) / 30.0f; + autoScrollY = -LERP( t*t, min, max ); + if( !scrolledTimerOn ) + Fl::add_timeout( 0.0, _timerScrollCB, this ); + } + else if( Y > (y()+h()-30) ) // bottom + { + float t = float(Y - (y()+h()-30)) / 30.0f; + autoScrollY = LERP( t*t, min, max ); + if( !scrolledTimerOn ) + Fl::add_timeout( 0.0, _timerScrollCB, this ); + } + } + + if( autoScrollX == 0.0f && autoScrollY == 0.0f ) + { + Fl::remove_timeout( _timerScrollCB, this ); + scrolledTimerOn = false; + } + + int dx = Fl::box_dx(box()), dy = Fl::box_dy(box()); + rdata.x = x()+dx; rdata.y = y()+dy; + if( scrollH->visible() ) + rdata.x -= scrollH->value(); + if( scrollV->visible() ) + rdata.y -= scrollV->value(); + rdata.delta = 0; + root.recurse( rdata, Node::HANDLE, FL_DND_DRAG ); + rdata.isMoveValid = Fl::event_inside( this ) && Node::isMoveValid( rdata.grabbed, rdata.dragWhere, rdata.dragNode ); + + redraw(); + Fl::flush(); + + if( rdata.isMoveValid ) + return true; + else +#endif + return false; +} + +void Flu_Tree_Browser :: on_dnd_release() +{ +#ifdef USE_FLU_DND + Fl::remove_timeout( _timerScrollCB, this ); + scrolledTimerOn = false; + redraw(); + Fl::flush(); +#endif +} + +void Flu_Tree_Browser :: on_dnd_drop( const Flu_DND_Event *e ) +{ +#ifdef USE_FLU_DND + bool newNode = false; + + if( !rdata.isMoveValid ) + rdata.grabbed = 0; + + else if( e->event_is_text() && rdata.dnd ) + { + // create a new node with the text as the name and make it the grabbed node + rdata.grabbed = new Node( true, e->text(), NULL, rdata, NULL, true ); + if( rdata.grabbed ) + newNode = true; + } + + else + { + if( e->is_data_type( "Flu_Tree_Browser" ) ) + { + if( rdata.moveOnlySameGroup && ( rdata.grabbed->parent() != rdata.dragNode->parent() ) ) + rdata.grabbed = NULL; + } + else if( e->is_data_type( "DND_Object" ) && rdata.dnd ) + { + // create a new node with the text as the name and make it the grabbed node + DND_Object *o = (DND_Object*)e->data(); + rdata.grabbed = new Node( true, o->name(), NULL, rdata, NULL, true ); + if( rdata.grabbed ) + { + rdata.grabbed->user_data( e->data() ); + newNode = true; + } + } + else + rdata.grabbed = NULL; + } + + // select only the new/moved node + root.unselect_all( rdata.grabbed ); + set_hilighted( rdata.grabbed ); + if( rdata.grabbed ) + { + rdata.grabbed->select( true ); + + // move the node + if( NodeList::move( rdata.grabbed, rdata.dragWhere, rdata.dragNode ) ) + { + if( newNode ) + rdata.grabbed->do_callback( FLU_NEW_NODE ); + else + rdata.grabbed->do_callback( FLU_MOVED_NODE ); + } + rdata.forceResize = true; + } + Fl::focus(this); + + rdata.dragging = false; + rdata.grabbed = 0; + rdata.dragNode = 0; + Fl::remove_timeout( _timerScrollCB, this ); + scrolledTimerOn = false; + + redraw(); +#endif +} + +int Flu_Tree_Browser :: handle( int event ) +{ +#ifdef USE_FLU_DND + if( dnd_handle( event ) ) + return 1; +#endif + + if( event == FL_NO_EVENT )//|| event == FL_MOVE ) + return 0; + + if( event == FL_FOCUS )//&& rdata.lastHilighted ) + { + //set_hilighted( rdata.lastHilighted ); + //lastEvent = event; + //Fl_Group::handle( event ); + redraw(); + return 1; + } + + if( event == FL_UNFOCUS ) + { + //if( lastEvent != FL_LEAVE ) + //{ + //rdata.lastHilighted = rdata.hilighted; + //} + //set_hilighted( NULL ); + //lastEvent = event; + Fl_Group::handle( event ); + redraw(); + return 1; + } + + if( !rdata.dragging && !( event == FL_MOVE && rdata.selectUnderMouse ) ) + { + if( ! (event == FL_MOVE || event == FL_ENTER || event == FL_LEAVE ) ) + _box->redraw(); + + if( Fl_Group::handle( event ) ) + { + //if( event == FL_KEYDOWN || event == FL_KEYUP ) + // redraw(); + return 1; + } + //if (scrollV && Fl::event_inside(scrollV) && scrollV->handle(event)) return 1; + //if (scrollH && Fl::event_inside(scrollH) && scrollH->handle(event)) return 1; + } + + if( event == FL_RELEASE ) + { + //Fl::focus(this); + rdata.dragging = false; + rdata.grabbed = 0; + rdata.dragNode = 0; + //redraw(); + } + + int dx = Fl::box_dx(box()), dy = Fl::box_dy(box()); + + // set some initial values for the recursive data structure + // account for the scrollbar positions + rdata.x = x()+dx; rdata.y = y()+dy; + if( scrollH->visible() ) + rdata.x -= scrollH->value(); + if( scrollV->visible() ) + rdata.y -= scrollV->value(); + + rdata.previous = NULL; + rdata.delta = 0; + rdata.visibilityChanged = false; + + // catch cursor keys for moving the hilighted entry or selecting all entries + if( event == FL_KEYDOWN ) + { + // move hilighted entry up + if( Fl::event_key() == FL_Up ) + { + rdata.delta = -1; + Fl::focus(this); + redraw(); + } + + // move hilighted entry down + else if( Fl::event_key() == FL_Down ) + { + rdata.delta = 1; + Fl::focus(this); + redraw(); + } + + // select all + else if( Fl::event_state(FL_CTRL) && Fl::event_key() == 'a' ) + { + select_all(); + Fl::focus(this); + redraw(); + return 1; + } + + // check for the Home key + else if( Fl::event_key() == FL_Home ) + { + // set the hilighted entry to be the first entry + if( rdata.showRoot || ( rdata.root->_children.size() == 0 ) ) + set_hilighted( rdata.root ); + else if( rdata.root->_children.size() > 0 ) + set_hilighted( rdata.root->_children.child(0) ); + redraw(); + } + + // check for the End key + else if( Fl::event_key() == FL_End ) + { + // set the hilighted entry to be the last visible entry + if( rdata.showRoot && ( rdata.root->_children.size() == 0 ) ) + set_hilighted( rdata.root ); + else + { + // find the last node by repeatedly looking for the last child until there are no more branches + Node *n = &root; + while( n->_children.size() && n->open() ) + n = n->_children.child( n->_children.size()-1 ); + set_hilighted( n ); + } + redraw(); + } + } + + // pass the event down the tree + int val = root.recurse( rdata, Node::HANDLE, event ); + if( val ) + { + //redraw(); + if( rdata.visibilityChanged ) + root.determineVisibility(); + if( val == 1 ) + return 1; + } + // special case: if multi-select or single-select and user clicks on no items, unselect all items + else if( (rdata.selectionMode != FLU_NO_SELECT) && (event == FL_PUSH) && (!Fl::event_state(FL_CTRL)) ) + { + unselect_all(); + set_hilighted( NULL ); + rdata.forceResize = true; + redraw(); + + return 1; + } + + if( event == FL_SHOW || event == FL_HIDE ) + root.determineVisibility(); + + return Fl_Group::handle( event ); + //return 0; +} + +void Flu_Tree_Browser :: insertion_mode( int m ) +{ + rdata.insertionMode = m; + root.sort(); +} + +void Flu_Tree_Browser :: set_hilighted( Flu_Tree_Browser::Node* n ) +{ + if( rdata.hilighted == n && when() != FL_WHEN_NOT_CHANGED ) + return; + + if( rdata.hilighted ) + rdata.hilighted->do_callback( FLU_UNHILIGHTED ); + rdata.hilighted = n; + if( rdata.hilighted ) + rdata.hilighted->do_callback( FLU_HILIGHTED ); + + if( rdata.hilighted ) + { + if( rdata.selectionFollowsHilight ) + { + if( rdata.selectionMode == FLU_SINGLE_SELECT ) + unselect_all(); + rdata.hilighted->select( true ); + } + + int extraH = scrollH->visible() ? scrollH->h() : 0; + + // if the hilighted entry is below the visible bounds of the browser, move the vertical scrollbar + // so the hilighted entry is the last visible entry + if( rdata.hilighted->currentY-y()+rdata.hilighted->currentH > scrollV->value()+h()-extraH ) + ((Fl_Valuator*)scrollV)->value( rdata.hilighted->currentY-y() - h()+extraH + rdata.hilighted->currentH ); + + // if the hilighted entry is above the visible bounds of the browser, move the vertical scrollbar + // so the hilighted entry is the first visible entry + if( rdata.hilighted->currentY-y() < scrollV->value() ) + ((Fl_Valuator*)scrollV)->value( rdata.hilighted->currentY-y() ); + } + redraw(); +} + +int Flu_Tree_Browser :: num_selected() +{ + return root.recurse( rdata, Node::COUNT_SELECTED ); +} + +int Flu_Tree_Browser :: Node :: num_selected() +{ + return recurse( tree->rdata, COUNT_SELECTED ); +} + +Flu_Tree_Browser::Node* Flu_Tree_Browser :: get_selected( int index ) +{ + return root.get_selected( index ); +} + +Flu_Tree_Browser::Node* Flu_Tree_Browser :: Node :: get_selected( int index ) +{ + tree->rdata.counter = 0; + tree->rdata.searchIndex = index; + Node *n = modify( 0, GET_SELECTED, tree->rdata ); + tree->rdata.searchIndex = 1; + return n; +} + +Flu_Tree_Browser :: Node :: Node( const char *lbl ) +{ + flags = 0; + userData = 0; + _parent = 0; + _widget = 0; + _group = 0; + SET(ACTIVE); + CLEAR(LEAF); + _id = 0; + CLEAR(ALWAYS_OPEN); + SET(COLLAPSED); + SET(MOVABLE); + SET(DROPPABLE); + currentY = currentH = 0; + totalChildH = 0; + CLEAR(SELECTED); + CLEAR(EXPAND_TO_WIDTH); + SET(SHOW_LABEL); + if( lbl == 0 ) + text = ""; + else + text = lbl; + + cIcon[0] = cIcon[1] = bIcon[0] = bIcon[1] = lIcon = 0; +} + +Flu_Tree_Browser :: Node :: Node( bool l, const char* n, Node *p, RData &rdata, Fl_Widget *w, bool showLbl ) +{ + _group = 0; + flags = 0; + userData = 0; + SET(LEAF,l); + text = n; + _id = 0; + SET(ACTIVE); + _parent = p; + CLEAR(ALWAYS_OPEN); + SET(COLLAPSED); + CLEAR(SELECTED); + CLEAR(EXPAND_TO_WIDTH); + SET(MOVABLE); + SET(DROPPABLE); + _widget = 0; + totalChildH = 0; + currentY = currentH = 0; + cIcon[0] = cIcon[1] = bIcon[0] = bIcon[1] = lIcon = 0; + SET( SHOW_LABEL, showLbl ); + tree = rdata.tree; + + initType(); + + _id = rdata.nextId++; + widget( w ); +} + +void Flu_Tree_Browser :: Node :: initType() +{ + if( is_leaf() ) + { + lIcon = tree->rdata.leafIcon; + textColor = tree->rdata.defLeafColor; + textFont = tree->rdata.defLeafFont; + textSize = tree->rdata.defLeafSize; + } + else + { + cIcon[0] = tree->rdata.collapseIcons[0]; + cIcon[1] = tree->rdata.collapseIcons[1]; + bIcon[0] = tree->rdata.branchIcons[0]; + bIcon[1] = tree->rdata.branchIcons[1]; + textColor = tree->rdata.defBranchColor; + textFont = tree->rdata.defBranchFont; + textSize = tree->rdata.defBranchSize; + } +} + +Flu_Tree_Browser :: Node :: ~Node() +{ + // if this node is in a tree, make sure it isn't holding a reference to us + if( tree ) + { + if( tree->rdata.hilighted == this ) tree->rdata.hilighted = NULL; + //if( tree->rdata.lastHilighted == this ) tree->rdata.lastHilighted = NULL; + if( tree->rdata.grabbed == this ) tree->rdata.grabbed = NULL; + if( tree->rdata.dragNode == this ) tree->rdata.dragNode = NULL; + } + clear(); +} + +Flu_Tree_Browser::Node* Flu_Tree_Browser :: Node :: first() +{ + return this; +} + +Flu_Tree_Browser::Node* Flu_Tree_Browser :: Node :: first_branch() +{ + Node *n = first(); + while( n ) + { + if( n->is_branch() ) + return n; + else + n = n->next(); + } + return NULL; +} + +Flu_Tree_Browser::Node* Flu_Tree_Browser :: Node :: first_leaf() +{ + Node *n = first(); + while( n ) + { + if( n->is_leaf() ) + return n; + else + n = n->next(); + } + return NULL; +} + +Flu_Tree_Browser::Node* Flu_Tree_Browser :: Node :: last() +{ + if( children() == 0 ) + return this; + else + return( child( children() - 1 )->last() ); +} + +Flu_Tree_Browser::Node* Flu_Tree_Browser :: Node :: last_branch() +{ + Node *n = last(); + while( n ) + { + if( n->is_branch() ) + return n; + else + n = n->previous(); + } + return NULL; +} + +Flu_Tree_Browser::Node* Flu_Tree_Browser :: Node :: last_leaf() +{ + Node *n = last(); + while( n ) + { + if( n->is_leaf() ) + return n; + else + n = n->previous(); + } + return NULL; +} + +Flu_Tree_Browser::Node* Flu_Tree_Browser :: Node :: next_sibling() +{ + if( is_root() ) + return NULL; + int index; + for( index = 0; index < _parent->children(); index++ ) + if( _parent->child(index) == this ) + break; + // if we are the last child of our parent, then we have no next sibling + if( index == _parent->children()-1 ) + return NULL; + // otherwise return our next sibling + else + return( _parent->child(index+1) ); +} + +Flu_Tree_Browser::Node* Flu_Tree_Browser :: Node :: previous_sibling() +{ + if( is_root() ) + return NULL; + int index; + for( index = 0; index < _parent->children(); index++ ) + if( _parent->child(index) == this ) + break; + // if we are the first child of our parent, then we have no previous sibling + if( index == 0 ) + return NULL; + // otherwise return our previous sibling + else + return( _parent->child(index-1) ); +} + +int Flu_Tree_Browser :: Node :: index() const +{ + if( is_root() ) + return -1; + int index; + for( index = 0; index < _parent->children(); index++ ) + if( _parent->child(index) == this ) + return index; + return -1; +} + +Flu_Tree_Browser::Node* Flu_Tree_Browser :: Node :: next() +{ + // take care of the root node as a special case + if( is_root() ) + { + if( children() ) + return child(0); + else + return NULL; + } + + // if we are a branch, then the next node is our first child, unless we don't have any children + if( is_branch() && _children.size() ) + return _children.child(0); + else + { + // otherwise, the next node is our next sibling. if there is no next sibling (because we + // are the last child of our parent), then the next node is the next sibling of our parent (and so on...) + Node *p = parent(), *n = next_sibling(); + while( p ) + { + if( n ) + return n; + else + { + n = p->next_sibling(); + p = p->parent(); + } + } + return NULL; + } +} + +Flu_Tree_Browser::Node* Flu_Tree_Browser :: Node :: next_branch() +{ + Node *n = next(); + while( n ) + { + if( n->is_branch() ) + return n; + else + n = n->next(); + } + return NULL; +} + +Flu_Tree_Browser::Node* Flu_Tree_Browser :: Node :: next_leaf() +{ + Node *n = next(); + while( n ) + { + if( n->is_leaf() ) + return n; + else + n = n->next(); + } + return NULL; +} + +Flu_Tree_Browser::Node* Flu_Tree_Browser :: Node :: previous() +{ + // take care of the root node as a special case + if( is_root() ) + return NULL; + + // the previous node is either our parent's + // previous sibling (if that sibling exists and is a leaf or a branch with no children), + // or the last child of our parent's previous sibling (if that sibling exists and is + // a branch with children). if there is no previous sibling, then the previous node + // is our parent + Node *n = previous_sibling(); + if( !n ) + return _parent; + else + { + if( n->is_leaf() ) // is leaf, so that is the previous node + return n; + else if( n->children() ) // is branch with some children, so previous node is last child + return( n->last() ); + else // is branch with no children, so that is the previous node + return n; + } +} + +Flu_Tree_Browser::Node* Flu_Tree_Browser :: Node :: previous_branch() +{ + Node *n = previous(); + while( n ) + { + if( n->is_branch() ) + return n; + else + n = n->previous(); + } + return NULL; +} + +Flu_Tree_Browser::Node* Flu_Tree_Browser :: Node :: previous_leaf() +{ + Node *n = previous(); + while( n ) + { + if( n->is_leaf() ) + return n; + else + n = n->previous(); + } + return NULL; +} + +void Flu_Tree_Browser :: Node :: determineVisibility( bool parentVisible ) +{ + if( _widget ) + { + if( parentVisible ) + _widget->w->show(); + else + _widget->w->hide(); + } + for( int i = 0; i < _children.size(); i++ ) + _children.child(i)->determineVisibility( parentVisible && open() ); +} + +Flu_Tree_Browser::Node* Flu_Tree_Browser :: Node :: child( int i ) const +{ + if( i < 0 || i >= _children.size() ) + return 0; + else + return _children.child(i); +} + +void Flu_Tree_Browser :: Node :: clear() +{ + widget(NULL); + for( int i = 0; i < _children.size(); i++ ) + { + //if( tree->rdata.cbNode == _children.child(i) ) + //tree->rdata.cbNode = NULL; + delete _children.child(i); + } + _children.clear(); + if( _group ) + { + if( _group->parent() ) + _group->parent()->remove( *_group ); + while( _group->children() ) + _group->remove( *_group->child(0) ); + delete _group; + _group = NULL; + } +} + +void Flu_Tree_Browser :: Node :: print( int spaces ) +{ + for( int s = 0; s < spaces; s++ ) + printf( " " ); + if( is_leaf() ) + printf( " %s\n", text.c_str() ); + else + printf( "[%s]\n", text.c_str() ); + + for( int i = 0; i < _children.size(); i++ ) + _children.child(i)->print( spaces+2 ); +} + +void Flu_Tree_Browser :: draw() +{ + if( rdata.forceResize ) + { + resize( x(), y(), w(), h() ); + rdata.forceResize = false; + } + + // draw the background color + //fl_draw_box( _box->box(), _box->x(), _box->y(), _box->w(), _box->h(), _box->color() ); + fl_draw_box( box(), x(), y(), w(), h(), color() ); + + int dx = Fl::box_dx(box()), dy = Fl::box_dy(box()), + dw = Fl::box_dw(box()), dh = Fl::box_dh(box()); + + // set up the recursive data structure + rdata.x = x()+dx; rdata.y = y()+dy; + // account for the positions of the scrollbars + if( scrollH->visible() ) + rdata.x -= scrollH->value(); + if( scrollV->visible() ) + rdata.y -= scrollV->value(); + + rdata.last = true; + rdata.bgColor = _box->color(); + rdata.shadedIndex = 0; + + // pick the connector line and selection colors depending on the active state + if( active() ) + { + rdata.lineColor = rdata.defLineColor; + rdata.selectionColor = rdata.defSelectionColor; + } + else + { + rdata.lineColor = fl_inactive( rdata.defLineColor ); + rdata.selectionColor = fl_inactive( rdata.defSelectionColor ); + } + + // draw the tree + fl_push_clip( x()+dx, y()+dy, w()-dw, h()-dh ); + root.recurse( rdata, Node::DRAW ); + + // if dragging to move, draw a bar showing where the dragged node will be inserted +#ifdef USE_FLU_DND + if( dnd_is_dragging() && rdata.isMoveValid && rdata.dragging ) + { + bool drawLine = false; + if( dnd_event_is_text() ) + drawLine = true; + else if( dnd_is_data_type( "Flu_Tree_Browser" ) ) + { + if( !rdata.moveOnlySameGroup || ( rdata.grabbed->parent() == rdata.dragNode->parent() ) ) + drawLine = true; + } + else if( dnd_is_data_type( "DND_Object" ) ) + drawLine = true; + if( drawLine && rdata.dragWhere != MOVE_INSIDE ) + { + fl_color( FL_RED ); + fl_line_style( FL_SOLID, 2 ); + fl_line( _box->x(), rdata.dragPos, _box->x()+_box->w(), rdata.dragPos ); + fl_line_style( 0 ); + } + } +#endif + + fl_pop_clip(); + + // draw the kids + draw_child( *scrollBox ); + draw_child( *scrollH ); + draw_child( *scrollV ); + + // draw the box last so it's on top + //fl_draw_box( _box->box(), _box->x(), _box->y(), _box->w(), _box->h(), _box->color() ); +} + +inline void draw_T( int x, int y, int w, int h ) +{ + int w2 = w >> 1; + int h2 = h >> 1; + fl_line( x+w2, y, x+w2, y+h ); + fl_line( x+w2, y+h2, x+w, y+h2 ); +} + +inline void draw_L( int x, int y, int w, int h ) +{ + int w2 = w >> 1; + int h2 = h >> 1; + fl_line( x+w2, y, x+w2, y+h2 ); + fl_line( x+w2, y+h2, x+w, y+h2 ); +} + +inline void draw_Lflip( int x, int y, int w, int h ) +{ + int w2 = w >> 1; + int h2 = h >> 1; + fl_line( x+w2, y+h, x+w2, y+h2 ); + fl_line( x+w2, y+h2, x, y+h2 ); +} + +inline void draw_Lflop( int x, int y, int w, int h ) +{ + int w2 = w >> 1; + int h2 = h >> 1; + fl_line( x+w2, y+h, x+w2, y+h2 ); + fl_line( x+w2, y+h2, x+w, y+h2 ); +} + +inline void draw_Ldash( int x, int y, int w, int h ) +{ + w = w >> 1; + h = h >> 1; + fl_line( x, y+h, x+w, y+h ); +} + +inline void draw_vert_dash( int x, int y, int w, int h ) +{ + w = w >> 1; + fl_line( x+w, y+(h>>1), x+w, y+h ); +} + +inline void draw_Rdash( int x, int y, int w, int h ) +{ + h = h >> 1; + fl_line( x+w, y+h, x+(w>>1), y+h ); +} + +void Flu_Tree_Browser :: Node :: draw( RData &rdata, bool measure ) +{ + int which = open(); // i.e. which icon: open or closed? + bool skipCollapser = is_root() && rdata.showRoot && ( CHECK(ALWAYS_OPEN) || rdata.allBranchesAlwaysOpen ); + int halfHGap = rdata.hGap >> 1, halfVGap = rdata.vGap >> 1; + bool doDraw = !measure; + + int X = rdata.x; + int Y = rdata.y; + + Fl_Color bgColor = rdata.shadedColors[rdata.shadedIndex], tColor = textColor, hilightColor = rdata.selectionColor; + + // pick the text color depending on the active state + if( !rdata.tree->active() || !CHECK(ACTIVE)) + tColor = fl_inactive( tColor ); + + if( doDraw ) + { + // draw the background for the entry using the entry background color + fl_draw_box( FL_FLAT_BOX, rdata.browserX, Y, rdata.browserW, currentH, bgColor ); + + // if dragging to the inside of a branch, hilight that branch +#ifdef USE_FLU_DND + if( tree->dnd_is_dragging() && rdata.isMoveValid && rdata.dragWhere == MOVE_INSIDE && rdata.dragNode == this ) + { + bgColor = FL_RED; + tColor = fl_contrast( tColor, bgColor ); + hilightColor = rdata.bgColor; + fl_draw_box( FL_FLAT_BOX, rdata.browserX, Y, rdata.browserW, currentH, bgColor ); + } + // if selected, draw a filled selection box and reverse the normal draw colors + else if( CHECK(SELECTED) ) +#else + if( CHECK(SELECTED) ) +#endif + { + bgColor = rdata.selectionColor; + tColor = fl_contrast( tColor, bgColor ); + hilightColor = rdata.bgColor; + fl_draw_box( FL_FLAT_BOX, rdata.browserX, Y, rdata.browserW, currentH, bgColor ); + } + + fl_color( rdata.lineColor ); + fl_line_style( rdata.lineStyle, rdata.lineWidth ); + } + + if( is_leaf() ) // draw leaves one way... + { + // draw the connectors + if( doDraw && rdata.showConnectors && rdata.showBranches ) + { + if( parent()->is_root() && !rdata.showRoot && rdata.first ) + { + if( rdata.last ) + draw_Rdash( X-halfHGap, Y-halfVGap, rdata.branchIconW+rdata.hGap, currentH+rdata.vGap ); + else + draw_Lflop( X-halfHGap, Y-halfVGap, rdata.branchIconW+rdata.hGap, currentH+rdata.vGap ); + } + else if( rdata.last ) + draw_L( X-halfHGap, Y-halfVGap, rdata.branchIconW+rdata.hGap, currentH+rdata.vGap ); + else + draw_T( X-halfHGap, Y-halfVGap, rdata.branchIconW+rdata.hGap, currentH+rdata.vGap ); + } + + // account for leaf icon spacing + if( rdata.showBranches ) + { + if( lIcon ) + X += rdata.collapseIcons[which]->w() + rdata.hGap; + else + X += rdata.collapseIcons[which]->w() + rdata.wGap; + } + else + X += rdata.wGap; + + // draw some more connectors + if( doDraw && rdata.showConnectors && lIcon && rdata.showBranches ) + draw_Ldash( X-halfHGap, Y-halfVGap, lIcon->w()+rdata.hGap, currentH+rdata.vGap ); + + // draw the leaf icon + if( lIcon && !CHECK(ICON_AT_END) ) + { + if( doDraw ) + lIcon->draw( X, Y+(currentH>>1)-(lIcon->h()>>1) ); + X += lIcon->w() + rdata.wGap; + } + } + else // ...and branches another + { + // force the root to the left if it has no visible children + if( is_root() && !CHECK(SOME_VISIBLE_CHILDREN) ) + { + skipCollapser = true; + which = 0; + } + + if( !CHECK(SOME_VISIBLE_CHILDREN) && !rdata.showLeaves ) + which = 0; + + // draw the connectors + if( doDraw && !skipCollapser && rdata.showConnectors && rdata.showBranches ) + { + if( is_root() ) + { + if( CHECK(SOME_VISIBLE_CHILDREN) ) + draw_Rdash( X-halfHGap, Y-halfVGap, rdata.collapseIcons[which]->w()+4+rdata.hGap, currentH+rdata.vGap ); + } + else if( parent()->is_root() && !rdata.showRoot && rdata.first ) + { + if( rdata.last ) + draw_Rdash( X-halfHGap, Y-halfVGap, rdata.branchIconW+rdata.hGap, currentH+rdata.vGap ); + else + draw_Lflop( X-halfHGap, Y-halfVGap, rdata.branchIconW+rdata.hGap, currentH+rdata.vGap ); + } + else if( rdata.last ) + draw_L( X-halfHGap, Y-halfVGap, rdata.branchIconW+rdata.hGap, currentH+rdata.vGap ); + else + draw_T( X-halfHGap, Y-halfVGap, rdata.branchIconW+rdata.hGap, currentH+rdata.vGap ); + } + + // draw the collapsed icons + if( doDraw && !skipCollapser && !CHECK(ALWAYS_OPEN) && !rdata.allBranchesAlwaysOpen ) + { + if( CHECK(SOME_VISIBLE_CHILDREN) || rdata.showLeaves ) + { + if( !rdata.openWOChildren && !CHECK(SOME_VISIBLE_CHILDREN) ) + which = 0; + if( rdata.openWOChildren || CHECK(SOME_VISIBLE_CHILDREN) ) + { + if( _parent==0 ) + cIcon[which]->draw( X, Y+(currentH>>1)-(cIcon[which]->h()>>1) ); + else + cIcon[which]->draw( X+(rdata.branchIconW>>1)-(cIcon[which]->w()>>1), Y+(currentH>>1)-(cIcon[which]->h()>>1) ); + } + } + } + + if( !skipCollapser ) + { + X += cIcon[which]->w(); + if( bIcon[which] ) + X += rdata.hGap; + else + X += rdata.wGap; + } + + // draw some more connectors + if( doDraw && rdata.showConnectors && rdata.showBranches ) + { + int hGap = rdata.hGap; + if( bIcon[which] ) + hGap += bIcon[which]->w(); + if( skipCollapser && CHECK(SOME_VISIBLE_CHILDREN) ) + draw_vert_dash( X-halfHGap, Y-halfVGap, hGap, currentH+rdata.vGap ); + else if( !which || !CHECK(SOME_VISIBLE_CHILDREN) ) + draw_Ldash( X-halfHGap, Y-halfVGap, hGap, currentH+rdata.vGap ); + else + draw_Lflip( X-halfHGap, Y-halfVGap, hGap, currentH+rdata.vGap ); + } + + // draw the branch icon + if( bIcon[which] ) + { + if( doDraw ) + bIcon[which]->draw( X, Y+(currentH>>1)-(bIcon[which]->h()>>1) ); + X += bIcon[which]->w() + rdata.wGap; + } + else + X += rdata.wGap; + } + + if( doDraw ) + fl_line_style( 0 ); + + // draw the entry + if( CHECK(SHOW_LABEL) && !CHECK(SWAP_LABEL_AND_WIDGET) ) + { + if( doDraw ) + { + fl_draw_box( FL_FLAT_BOX, X, Y+(currentH>>1)-(textH>>1), textW, textH, bgColor ); + fl_color( tColor ); + fl_font( textFont, textSize ); + fl_draw( text.c_str(), X, Y+(currentH>>1)-(textH>>1), textW, textH, FL_ALIGN_LEFT ); + } + X += textW; + } + + if( _widget ) + { + int widgetW = _widget->w->w(); + int widgetH = _widget->w->h(); + if( doDraw ) + { + if( CHECK(AUTO_COLOR) ) + _widget->w->color( bgColor ); + if( CHECK(AUTO_LABEL_COLOR) ) + _widget->w->labelcolor( tColor ); + if( CHECK(AUTO_LABEL) ) + _widget->w->label( text.c_str() ); + _widget->w->redraw(); + _widget->w->position( X, Y+(currentH>>1)-(widgetH>>1) ); + if( CHECK(EXPAND_TO_WIDTH) ) + _widget->w->size( MAX( _widget->defaultW, rdata.browserW - (X-rdata.browserX) ), _widget->w->h() ); + _widget->w->draw(); + } + if( CHECK(EXPAND_TO_WIDTH) ) + { + if( _widget->w->w() == _widget->defaultW ) + X += _widget->defaultW; + } + else + X += widgetW; + } + + if( CHECK(SHOW_LABEL) && CHECK(SWAP_LABEL_AND_WIDGET) ) + { + if( doDraw ) + { + fl_draw_box( FL_FLAT_BOX, X, Y+(currentH>>1)-(textH>>1), textW, textH, bgColor ); + fl_color( tColor ); + fl_font( textFont, textSize ); + fl_draw( text.c_str(), X, Y+(currentH>>1)-(textH>>1), textW, textH, FL_ALIGN_LEFT ); + } + X += textW; + } + + // draw the leaf icon to the right of the label and widget + if( is_leaf() && lIcon && CHECK(ICON_AT_END) ) + { + if( doDraw ) + lIcon->draw( X, Y+(currentH>>1)-(lIcon->h()>>1) ); + X += lIcon->w() + rdata.wGap; + } + + // if hilighted, draw a box outlining the entry + if( Fl::focus() == tree && rdata.hilighted == this && doDraw ) + { + fl_color( hilightColor ); + fl_line_style( FL_DOT, 1 ); + fl_rect( rdata.browserX, Y, rdata.browserW, currentH, hilightColor ); + fl_line_style( 0 ); + } + + rdata.totalW = MAX( rdata.totalW, X ); +} + +void Flu_Tree_Browser :: Node :: select( bool b ) +{ + if( (CHECK(SELECTED)==b) && (tree->when() != FL_WHEN_NOT_CHANGED) ) + return; + SET(SELECTED,b); + tree->redraw(); + if( tree->when() == FL_WHEN_RELEASE ) + return; + if( b ) + do_callback( FLU_SELECTED ); + else + do_callback( FLU_UNSELECTED ); +} + +void Flu_Tree_Browser :: timerScrollCB() +{ + bool doRedraw = false; + + float val = scrollV->value() + autoScrollY; + if( val < 0.0f ) + val = 0.0f; + if( val > scrollV->maximum() ) + val = scrollV->maximum(); + doRedraw |= ( val != scrollV->value() ); + ((Fl_Valuator*)scrollV)->value( val ); + + val = scrollH->value() + autoScrollX; + if( val < 0.0f ) + val = 0.0f; + if( val > scrollH->maximum() ) + val = scrollH->maximum(); + doRedraw |= ( val != scrollH->value() ); + ((Fl_Valuator*)scrollH)->value( val ); + + Fl::repeat_timeout( 0.02, _timerScrollCB, this ); + scrolledTimerOn = true; + if( doRedraw ) + redraw(); +} + +void Flu_Tree_Browser :: timerRedrawCB() +{ + if( rdata.animating ) + Fl::repeat_timeout( 1.0f/rdata.fps, _timerRedrawCB, this ); + redraw(); +} + +void Flu_Tree_Browser :: Node :: open( bool b ) +{ + if( is_leaf() ) + return; + + if( CHECK(ALWAYS_OPEN) || tree->rdata.allBranchesAlwaysOpen ) + return; + + if( (open() == b) && (tree->when() != FL_WHEN_NOT_CHANGED) ) + return; + + tree->rdata.justOpenedClosed = true; + + SET(COLLAPSED,!b); + + if( tree->rdata.animate && _children.size() ) + { + // if we aren't yet animating a node, animate it! + if( !tree->rdata.animating && !tree->rdata.animatedNode ) + { + // if we don't know how high all the children are, find out + // (this only happens once per node, the first time it is opened) + if( totalChildH == 0 ) + { + RData r = tree->rdata; + r.x = r.y = r.totalW = 0; + recurse( r, Node::MEASURE_THIS_OPEN ); + } + // set the initial offset based on whether the branch is open or closed + tree->rdata.animationOffset = b ? -totalChildH : -1; + // the delta is how much to change the offset each frame + tree->rdata.animationDelta = totalChildH / ( tree->rdata.collapseTime * tree->rdata.fps ); + tree->rdata.animationDelta = b ? tree->rdata.animationDelta : -tree->rdata.animationDelta; + tree->rdata.animating = true; + tree->rdata.animatedNode = this; + Fl::add_timeout( 1.0f/tree->rdata.fps, _timerRedrawCB, tree ); + } + // otherwise reverse the direction of the animation, only if we are animating this node + else if( tree->rdata.animating && tree->rdata.animatedNode==this ) + { + if( b ^ (tree->rdata.animationDelta>0) ) + tree->rdata.animationDelta = -tree->rdata.animationDelta; + } + } + + if( open() && (_parent != 0) ) // root node doesn't count as a single open branch + { + if( ( tree->rdata.lastOpenBranch != this ) && tree->rdata.singleBranchOpen ) + tree->rdata.lastOpenBranch->close(); + tree->rdata.lastOpenBranch = this; + } + + tree->rdata.forceResize = true; + tree->rdata.visibilityChanged = true; + if( b ) + do_callback( FLU_OPENED ); + else + do_callback( FLU_CLOSED ); +} + +void Flu_Tree_Browser :: Node :: active( bool b ) +{ + if( CHECK(ACTIVE) == b && tree->when() != FL_WHEN_NOT_CHANGED ) + return; + SET( ACTIVE, b ); + if( _widget ) + { + if( b ) + _widget->w->activate(); + else + _widget->w->deactivate(); + } + if( !CHECK(ACTIVE) ) + { + if( tree->rdata.hilighted == this ) + tree->set_hilighted( NULL ); + select( false ); + open( false ); + } +} + +void Flu_Tree_Browser :: Node :: unselect_all( Node* except ) +{ + if( this != except ) + select( false ); + for( int i = 0; i < _children.size(); i++ ) + _children.child(i)->unselect_all( except ); +} + +void Flu_Tree_Browser :: Node :: select_all() +{ + select( true ); + for( int i = 0; i < _children.size(); i++ ) + _children.child(i)->select_all(); +} + +bool Flu_Tree_Browser :: Node :: isMoveValid( Node* &n1, int &where, Node* &n2 ) +{ + // if n1 is NULL, then check it as if it were a node being moved from another tree + + if( n2 == NULL ) + return false; + + // check the validity of the move: + // 1) the source and destination nodes can't be the same + // 2) you can't move before the root node + // 3) you can't move an unmovable node or move a branch node such that it would become a descendent of itself + // 4) if moving only within the same group, check that the parents are the same + // 5) if moving into a sorted tree, the destination node MUST be a branch + // 6) a move AFTER an OPEN branch is a move BEFORE its first child + // 7) you can't move a node into a non-droppable branch node + + if( n1 == n2 ) + return false; + + if( where==MOVE_BEFORE && n2->is_root() ) + return false; + + if( n1 ) + { + if( !n1->movable() ) + return false; + if( n1->is_branch() ) + if( n1->is_descendent( n2 ) ) + return false; + } + + bool sameGroup = n2->tree->move_only_same_group(); + if( sameGroup && n1 ) + { + if( n1->parent() != n2->parent() || where==MOVE_INSIDE ) + return false; + } + + int iMode = n2->tree->insertion_mode(); + if( iMode == FLU_INSERT_SORTED || iMode == FLU_INSERT_SORTED_REVERSE ) + { + if( n2->is_branch() ) + { + where = MOVE_INSIDE; + return true; + } + else + return false; + } + + if( where==MOVE_AFTER && n2->is_branch() && n2->open() ) + { + // can't move inside a branch if within the same group, unless the first node is dragged + // from outside the tree (in which case n1 is NULL) + if( sameGroup && n1 ) + { + if( n2->_children.size() > 0 ) + return false; + } + else if( n2->_children.size() > 0 ) + { + where = MOVE_BEFORE; + n2 = n2->_children.child(0); + } + else + where = MOVE_INSIDE; + } + + if( where==MOVE_INSIDE ) + { + if( !n2->droppable() ) + return false; + } + else if( n2->parent() ) + if( !n2->parent()->droppable() ) + return false; + + return true; +} + +int Flu_Tree_Browser :: Node :: recurse( RData &rdata, int type, int event ) +{ + int i; + + if( is_root() ) + rdata.first = true; + + if( type == COUNT_SELECTED ) + { + if( is_leaf() ) + return (int)CHECK(SELECTED); + else + { + int total = (int)CHECK(SELECTED); + for( i = 0; i < _children.size(); i++ ) + total += _children.child(i)->recurse( rdata, type, event ); + return total; + } + } + + // see if this entry is even visible + if( rdata.y > rdata.browserY+rdata.browserH ) + { + if( type == DRAW ) + return 1; + else if( type == HANDLE ) + return 0; + } + + int which = open(); + bool skipEntry = ( is_root() && !rdata.showRoot ) || ( is_leaf() && !rdata.showLeaves ) || ( is_branch() && !rdata.showBranches ); + bool skipCollapser = is_root() && rdata.showRoot && ( CHECK(ALWAYS_OPEN) || rdata.allBranchesAlwaysOpen ); + + // find the size of the entry label + if( (type == MEASURE) || (type == MEASURE_THIS_OPEN) ) + { + if( CHECK(SHOW_LABEL) ) + { + int W = 0, H; + fl_font( textFont, textSize ); + fl_measure( text.c_str(), W, H ); + W += 4; H += 4; // hack - it looks better + textW = W; + textH = H; + } + else + { + textW = textH = 0; + } + + // remember vertically where this node is w.r.t the browser + currentY = rdata.y; + + currentH = textH; + + // find the total size of the entry, depending on if there's a widget + if( _widget ) + currentH = MAX( _widget->w->h(), currentH ); + + // find the total height of this entry by taking the max height of the entry and icons + if( is_leaf() ) + { + if( lIcon ) + currentH = MAX( currentH, lIcon->h() ); + } + else + { + currentH = MAX( currentH, cIcon[which]->h() ); + if( bIcon[which] ) + currentH = MAX( currentH, bIcon[which]->h() ); + } + } + + bool skipAhead = (rdata.y + currentH) < rdata.browserY; + + // process the entry + switch( type ) + { + case DRAW: + { + if( skipEntry || skipAhead ) break; + + draw( rdata, false ); + + // draw any vertical connectors connecting our parents, grandparents, etc., + if( rdata.showBranches ) + { + int d = depth()-1; + for( i = 0; i < rdata.branchConnectors.size(); i++ ) + { + if( i != d ) + { + fl_color( rdata.lineColor ); + fl_line_style( rdata.lineStyle, rdata.lineWidth ); + fl_line( rdata.branchConnectors[i], rdata.y, rdata.branchConnectors[i], rdata.y+currentH ); + fl_line_style( 0 ); + } + } + } + + rdata.shadedIndex = 1 - rdata.shadedIndex; // toggle the even/odd entry for shading + } + break; + + case MEASURE: + if( is_leaf() ) + CLEAR( SOME_VISIBLE_CHILDREN ); + else + { + // find out whether the branch has any children that could be visible + bool someVisibleChildren = rdata.showLeaves && ( _children.size() > 0 ); + for( i = 0; i < _children.size(); i++ ) + { + if( _children.child(i)->is_branch() ) + { + someVisibleChildren = true; + break; + } + } + SET( SOME_VISIBLE_CHILDREN, someVisibleChildren ); + } + + case MEASURE_THIS_OPEN: + if( skipEntry ) break; + draw( rdata, true ); + break; + + case HANDLE: + { + if( skipEntry || skipAhead || !CHECK(ACTIVE) ) break; + + if( event != FL_DRAG && event != FL_NO_EVENT ) + rdata.justOpenedClosed = false; + + // if we are trying to select all entries between 2 widgets due to a shift-select... + if( rdata.shiftSelect ) + { + if( (rdata.hilighted == this) || (rdata.grabbed == this) ) + { + if( !rdata.shiftSelectAll ) + { + rdata.shiftSelectAll = true; + select( true ); + if( is_branch() && rdata.openOnSelect ) + { + open( true ); + } + } + else + { + rdata.shiftSelect = false; + rdata.shiftSelectAll = false; + rdata.grabbed = 0; + select( true ); + if( is_branch() && rdata.openOnSelect ) + { + open( true ); + } + } + } + else if( rdata.shiftSelectAll ) + { + select( true ); + if( is_branch() && rdata.openOnSelect ) + { + open( true ); + } + } + break; + } + + // check for the keyboard event + if( event == FL_KEYDOWN ) + { + // check for the spacebar selecting this entry + if( Fl::event_key() == ' ' && rdata.hilighted == this ) + { + if( Fl::event_state(FL_CTRL) ) + select( !CHECK(SELECTED) ); + else + { + rdata.root->unselect_all( this ); + select( true ); + } + if( is_branch() && rdata.openOnSelect ) + { + open( true ); + } + return 1; + } + + // check for the enter key opening/closing this entry + else if( (Fl::event_key() == FL_Enter) && (rdata.hilighted == this) ) + { + open( !open() ); + return 1; + } + + // check for the left/right cursor keys opening/closing this entry + else if( (Fl::event_key() == FL_Left) && (rdata.hilighted == this) ) + { + open( false ); + return 1; + } + else if( (Fl::event_key() == FL_Right) && (rdata.hilighted == this) ) + { + open( true ); + return 1; + } + } + + // check for the "up" cursor key moving the hilighted entry + if( rdata.delta == -1 && rdata.hilighted == this && rdata.previous != NULL ) + { + tree->set_hilighted( rdata.previous ); + rdata.delta = 0; + return 1; + } + + // check for the "down" cursor key moving the hilighted entry + if( rdata.delta == 1 && rdata.hilighted == rdata.previous ) + { + tree->set_hilighted( this ); + rdata.delta = 0; + return 1; + } + + rdata.previous = this; + + // the event is not ours to use + //if( _widget && !rdata.dragging ) + //if( Fl::event_inside( _widget->w ) ) + // return 2; + + bool inExpander = false; + if( is_branch() ) + { + int which = open(); + if( _parent==0 ) + inExpander = Fl::event_inside( rdata.x, rdata.y+(currentH>>1)-(cIcon[which]->h()>>1), + cIcon[which]->w(), cIcon[which]->h() ); + else + inExpander = Fl::event_inside( rdata.x+(rdata.branchIconW>>1)-(cIcon[which]->w()>>1), + rdata.y+(currentH>>1)-(cIcon[which]->h()>>1), + cIcon[which]->w(), cIcon[which]->h() ); + } + + if( event == FL_PUSH ) + { + // check for expand/collapse + if( Fl::event_button() == FL_LEFT_MOUSE && inExpander ) + { + if( rdata.openWOChildren || CHECK(SOME_VISIBLE_CHILDREN) ) + { + open( !open() ); + rdata.dragging = false; + rdata.dragNode = 0; + return 1; + } + } + } + + if( event == FL_DRAG && rdata.justOpenedClosed ) + return 0; + + // if no selections, return + if( rdata.selectionMode == FLU_NO_SELECT ) + break; + + // if the event is not inside us, return + if( !Fl::event_inside( rdata.browserX, rdata.y, rdata.browserW, currentH ) ) + break; + +#ifdef USE_FLU_DND + // check for grabbing of a node for DND + if( event == FL_DRAG && rdata.selectionDragMode == FLU_DRAG_TO_MOVE && !is_root() && rdata.grabbed && + //rdata.insertionMode!=FLU_INSERT_SORTED && rdata.insertionMode!=FLU_INSERT_SORTED_REVERSE && + !tree->dnd_is_dragging() && !rdata.justOpenedClosed && CHECK(MOVABLE) ) + { + tree->dnd_grab( this, "Flu_Tree_Browser" ); + return 1; + } + + // dragging to move a node + if( event == FL_DND_DRAG ) + { + rdata.dragNode = this; // remember which node to move the grabbed node before/after + if( is_root() ) + { + rdata.dragWhere = MOVE_AFTER; + rdata.dragPos = rdata.y + currentH; + } + else + { + // if this is a leaf or an open branch, then can only move before or after + // otherwise can move inside + if( is_branch() && !open() ) + { + int t = MAX( currentH / 3, 1 ); + if( (Fl::event_y()-rdata.y) <= t ) + rdata.dragWhere = MOVE_BEFORE; + else if( (Fl::event_y()-rdata.y) <= (t<<1) ) + rdata.dragWhere = MOVE_INSIDE; + else + rdata.dragWhere = MOVE_AFTER; + } + else + { + if( (Fl::event_y()-rdata.y) <= (currentH>>1) ) + rdata.dragWhere = MOVE_BEFORE; + else + rdata.dragWhere = MOVE_AFTER; + } + + // where to draw the insertion position? + if( rdata.dragWhere == MOVE_BEFORE || rdata.dragWhere == MOVE_INSIDE ) + rdata.dragPos = rdata.y; + else + rdata.dragPos = rdata.y + currentH; + } + return 1; + } +#endif + + //if( _widget && _widget->w && Fl::event_inside(_widget->w) && _widget->w->handle(event)) + //return 1; + + // single selection + if( rdata.selectionMode == FLU_SINGLE_SELECT ) + { + if( event == FL_MOVE && rdata.selectUnderMouse ) + { + //select_only(); + rdata.root->unselect_all( this ); + SET(SELECTED,true); + tree->redraw(); + } + else if( event == FL_PUSH ) + { + //rdata.dragging = true; + rdata.grabbed = this; + + if( rdata.selectUnderMouse ) + rdata.root->unselect_all(); + else + rdata.root->unselect_all( this ); + tree->set_hilighted( this ); + if( Fl::event_state(FL_CTRL) ) + select( !CHECK(SELECTED) ); + else + select( true ); + + if( is_leaf() ) + { + if( Fl::event_clicks() > 0 ) + { + Fl::event_clicks(0); + do_callback( FLU_DOUBLE_CLICK ); + } + } + else + { + if( Fl::event_clicks() > 0 ) + { + Fl::event_clicks(0); + if( rdata.doubleClickToOpen ) + { + if( rdata.openWOChildren || CHECK(SOME_VISIBLE_CHILDREN) ) + open( !open() ); + } + else + do_callback( FLU_DOUBLE_CLICK ); + } + else if( rdata.openOnSelect ) + { + open( true ); + } + } + Fl::focus(tree); + return 1; + } + else if( event == FL_DRAG ) + { + if( rdata.selectionDragMode == FLU_DRAG_IGNORE ) + return 1; + rdata.dragging = true; + //if( ( rdata.selectionDragMode == FLU_DRAG_IGNORE || rdata.selectionDragMode == FLU_DRAG_TO_MOVE) && ( tree->insertion_mode() == FLU_INSERT_FRONT || tree->insertion_mode() == FLU_INSERT_BACK ) ) + //return 1; + rdata.root->unselect_all( this ); + tree->set_hilighted( this ); + select( true ); + return 1; + } + else if( event == FL_RELEASE && tree->when() == FL_WHEN_RELEASE && selected() && !inExpander ) + { + do_callback( FLU_SELECTED ); + return 1; + } + } + + // multiple selection + else if( rdata.selectionMode == FLU_MULTI_SELECT ) + { + if( event == FL_PUSH ) + { + //rdata.dragging = true; + rdata.grabbed = this; + + if( Fl::event_state(FL_CTRL) ) + { + select( !CHECK(SELECTED) ); + tree->set_hilighted( this ); + } + else if( Fl::event_state(FL_SHIFT) ) + { + // select everything from the last selected entry to this one + if( rdata.hilighted == this ) + { + select( true ); + if( is_branch() ) + { + if( Fl::event_clicks() > 0 ) + { + Fl::event_clicks(0); + if( rdata.doubleClickToOpen ) + { + if( rdata.openWOChildren || CHECK(SOME_VISIBLE_CHILDREN) ) + open( !open() ); + } + else + do_callback( FLU_DOUBLE_CLICK ); + } + else if( rdata.openOnSelect ) + { + open( !open() ); + } + } + } + else + { + rdata.shiftSelectAll = false; + rdata.shiftSelect = true; + rdata.grabbed = this; + rdata.root->recurse( rdata, HANDLE, 0 ); + tree->set_hilighted( this ); + } + } + else + { + rdata.root->unselect_all( this ); + select( true ); + if( is_leaf() ) + { + if( Fl::event_clicks() > 0 ) + { + Fl::event_clicks(0); + do_callback( FLU_DOUBLE_CLICK ); + } + } + else + { + if( Fl::event_clicks() > 0 ) + { + Fl::event_clicks(0); + if( rdata.doubleClickToOpen ) + { + if( rdata.openWOChildren || CHECK(SOME_VISIBLE_CHILDREN) ) + open( !open() ); + } + else + do_callback( FLU_DOUBLE_CLICK ); + } + else if( rdata.openOnSelect ) + { + open( true ); + } + } + tree->set_hilighted( this ); + } + Fl::focus(tree); + return 1; + } + else if( event == FL_DRAG ) + { + if( rdata.selectionDragMode == FLU_DRAG_IGNORE ) + return 1; + rdata.dragging = true; + //if( ( rdata.selectionDragMode == FLU_DRAG_IGNORE || rdata.selectionDragMode == FLU_DRAG_TO_MOVE) && ( tree->insertion_mode() == FLU_INSERT_FRONT || tree->insertion_mode() == FLU_INSERT_BACK ) ) + //return 1; + select( true ); + tree->set_hilighted( this ); + return 1; + } + else if( event == FL_RELEASE && tree->when() == FL_WHEN_RELEASE && selected() && !inExpander ) + { + do_callback( FLU_SELECTED ); + return 1; + } + } + } + break; + } + + // advance the counters vertically to the next entry + if( !skipEntry ) + rdata.y += currentH + rdata.vGap; + + if( !is_root() && rdata.first && !skipEntry ) + rdata.first = false; + + // if we're a leaf, no need to process further + if( is_leaf() ) + return 0; + + // should we bail out already if we're done processing? + if( closed() && !skipEntry && !skipCollapser && tree->rdata.animatedNode!=this && ( type != MEASURE_THIS_OPEN ) ) + return 0; + + if( !CHECK(SOME_VISIBLE_CHILDREN) ) + return 0; + + // advance the counters horizontally to the next entry + if( rdata.showBranches ) + { + if( !skipEntry && !skipCollapser ) + rdata.x += cIcon[which]->w() + rdata.hGap; + } + rdata.totalW = MAX( rdata.totalW, rdata.x ); + + // the branchIconW is the width of the branch icon at this level + // it is used to center all children icons under the branch icon + int lastBranchIconW = rdata.branchIconW; + if( rdata.showBranches ) + { + if( bIcon[which] ) + rdata.branchIconW = bIcon[which]->w(); + else + rdata.branchIconW = cIcon[which]->w(); + } + else + rdata.branchIconW = 0; + + // update the animation + if( tree->rdata.animatedNode==this && ( type == DRAW ) ) + { + // check for termination (if opening) + if( (rdata.animationOffset+rdata.animationDelta) >= 0.0f ) + { + tree->rdata.animatedNode = NULL; + rdata.animating = false; + tree->rdata.forceResize = true; + Fl::remove_timeout( _timerRedrawCB, tree ); + } + else + { + // update the offset + rdata.animationOffset += rdata.animationDelta; + fl_push_clip( rdata.browserX, rdata.y, rdata.browserW, rdata.browserH ); + rdata.y += (int)rdata.animationOffset; + } + } + + if( ( type == MEASURE ) || ( type == MEASURE_THIS_OPEN ) ) + totalChildH = rdata.y; + + // process all children + int val; + int tempW = rdata.branchIconW >> 1; + for( i = 0; i < _children.size(); i++ ) + { + // prepare the recursive data structure for the next level + if( i == 0 ) + rdata.first = true; + rdata.last = (i == _children.size()-1 ); + + // if child "i" is not the last child, + // then there is a long connector that needs drawn between this node and the last child. + // push the horizontal position of the connector onto the stack + if( (type == DRAW) && rdata.showConnectors && ( i < _children.size()-1 ) ) + { + rdata.branchConnectors.push( rdata.x+tempW ); + val = _children.child(i)->recurse( rdata, type, event ); + rdata.branchConnectors.pop(); + } + else + val = _children.child(i)->recurse( rdata, type, event ); + + if( val ) + return val; + } + + // set the branch icon width back to what it was before we changed it + rdata.branchIconW = lastBranchIconW; + + if( ( type == MEASURE ) || ( type == MEASURE_THIS_OPEN ) ) + totalChildH = rdata.y - totalChildH; + + // update the animation + if( tree->rdata.animatedNode==this && ( type == DRAW ) ) + { + fl_pop_clip(); + // check for termination (if closing) + if( rdata.animationOffset <= (float)(-totalChildH) ) + { + tree->rdata.animatedNode = NULL; + rdata.animating = false; + tree->rdata.forceResize = true; + Fl::remove_timeout( _timerRedrawCB, tree ); + } + } + + // move back horizontally from the last entry + if( rdata.showBranches ) + { + if( !skipEntry && !skipCollapser ) + rdata.x -= cIcon[which]->w() + rdata.hGap; + } + + return 0; +} + +void Flu_Tree_Browser :: print() +{ + root.print(); +} + +void Flu_Tree_Browser :: clear() +{ + root.clear(); + root.text = ""; + + while( _box->children() ) + _box->remove( *_box->child(0) ); + + rdata.cbNode = NULL; + rdata.cbReason = FLU_NOTHING; + rdata.hilighted = NULL; + rdata.dragging = false; + rdata.forceResize = true; + rdata.lastOpenBranch = NULL; + rdata.shiftSelect = false; + rdata.shiftSelectAll = false; + rdata.nextId = 1; + rdata.searchIndex = 1; +} + +Flu_Tree_Browser::Node* Flu_Tree_Browser :: set_root( const char *label, Fl_Widget *w, bool showLabel ) +{ + if( label == 0 ) + label = ""; + root.text = label; + root.widget( w ); + root.SET(Node::SHOW_LABEL,showLabel); + root.cIcon[0] = rdata.collapseIcons[0]; + root.cIcon[1] = rdata.collapseIcons[1]; + root.bIcon[0] = rdata.branchIcons[0]; + root.bIcon[1] = rdata.branchIcons[1]; + root.textColor = rdata.defBranchColor; + root.textFont = rdata.defBranchFont; + root.textSize = rdata.defBranchSize; + rdata.forceResize = true; + + return &root; +} + +Flu_Tree_Browser::Node* Flu_Tree_Browser :: add( const char* fullpath, Fl_Widget *w, bool showLabel ) +{ + return( root.modify( fullpath, Node::ADD, rdata, w, showLabel ) ); +} + +Flu_Tree_Browser::Node* Flu_Tree_Browser :: add( const char* path, const char* text, Fl_Widget *w, bool showLabel ) +{ + // if the path does not end in '/', add it + FluSimpleString s = path; + if( path[strlen(path)-1] != '/' ) + s += "/"; + s += text; + + return add( s.c_str(), w, showLabel ); +} + +Flu_Tree_Browser::Node* Flu_Tree_Browser :: add_branch( const char* fullpath, Fl_Widget *w, bool showLabel ) +{ + FluSimpleString p( fullpath ); + if( p.size() && p[p.size()-1] != '/' && p[p.size()-1] != '\\' ) p += "/"; + return add( p.c_str(), w, showLabel ); +} + +Flu_Tree_Browser::Node* Flu_Tree_Browser :: add_branch( const char* path, const char* name, Fl_Widget *w, bool showLabel ) +{ + FluSimpleString p( name ); + if( p.size() && p[p.size()-1] != '/' && p[p.size()-1] != '\\' ) p += "/"; + return add( path, p.c_str(), w, showLabel ); +} + +Flu_Tree_Browser::Node* Flu_Tree_Browser :: add_leaf( const char* fullpath, Fl_Widget *w, bool showLabel ) +{ + FluSimpleString p( fullpath ); + if( p.size() && ( p[p.size()-1] == '/' || p[p.size()-1] == '\\' ) ) p[p.size()-1] = '\0'; + return add( p.c_str(), w, showLabel ); +} + +Flu_Tree_Browser::Node* Flu_Tree_Browser :: add_leaf( const char* path, const char* name, Fl_Widget *w, bool showLabel ) +{ + FluSimpleString p( name ); + if( p.size() && ( p[p.size()-1] == '/' || p[p.size()-1] == '\\' ) ) p[p.size()-1] = '\0'; + return add( path, p.c_str(), w, showLabel ); +} + +unsigned int Flu_Tree_Browser :: remove( const char *fullpath ) +{ + return( (unsigned int)root.modify( fullpath, Node::REMOVE, rdata ) ); +} + +unsigned int Flu_Tree_Browser :: remove( const char *path, const char *text ) +{ + // if the path does not end in '/', add it + FluSimpleString s = path; + if( path[strlen(path)-1] != '/' ) + s += "/"; + s += text; + return remove( s.c_str() ); +} + +unsigned int Flu_Tree_Browser :: remove( unsigned int id ) +{ + return root.remove( id ); +} + +unsigned int Flu_Tree_Browser :: Node :: remove( unsigned int id ) +{ + if( id == 0 ) + return 0; + + for( int i = 0; i < _children.size(); i++ ) + { + Node *n = _children.child(i); + if( n->id() == id ) + { + _children.erase( i ); + tree->rdata.forceResize = true; + //if( tree->rdata.cbNode == n ) + //tree->rdata.cbNode = NULL; + delete n; + if( tree->rdata.autoBranches ) + initType(); + tree->redraw(); + return id; + } + else if( n->remove( id ) ) + return id; + } + + return 0; +} + +unsigned int Flu_Tree_Browser :: remove( Fl_Widget *w ) +{ + return root.remove( w ); +} + +unsigned int Flu_Tree_Browser :: Node :: remove( Fl_Widget *w ) +{ + if( !w ) + return 0; + for( int i = 0; i < _children.size(); i++ ) + { + Node *n = _children.child(i); + if( n->_widget ) + { + if( n->_widget->w == w ) + { + int id = n->id(); + _children.erase( i ); + tree->rdata.forceResize = true; + //if( tree->rdata.cbNode == n ) + //tree->rdata.cbNode = NULL; + delete n; + if( tree->rdata.autoBranches ) + initType(); + tree->redraw(); + return id; + } + } + + int id = n->remove( w ); + if( id ) + return id; + } + + return 0; +} + +int Flu_Tree_Browser :: find_number( const char *fullpath ) +{ + rdata.counter = 0; + root.modify( fullpath, Node::FIND_NUMBER, rdata ); + return rdata.counter; +} + +int Flu_Tree_Browser :: find_number( const char *path, const char *text ) +{ + // if the path does not end in '/', add it + FluSimpleString s = path; + if( path[strlen(path)-1] != '/' ) + s += "/"; + s += text; + return find_number( s.c_str() ); +} + +Flu_Tree_Browser::Node* Flu_Tree_Browser :: find_next( const char *fullpath, Node* startNode ) +{ + // degenerate case: root node + if( strcmp( fullpath, "/" ) == 0 ) + return &root; + rdata.previous = startNode; + return( root.modify( fullpath, Node::FIND, rdata ) ); +} + +Flu_Tree_Browser::Node* Flu_Tree_Browser :: find_next( const char *path, const char *text ) +{ + // if the path does not end in '/', add it + FluSimpleString s = path; + if( path[strlen(path)-1] != '/' ) + s += "/"; + s += text; + return find_next( s.c_str() ); +} + +Flu_Tree_Browser::Node* Flu_Tree_Browser :: find( const char *path, const char *text ) +{ + // if the path does not end in '/', add it + FluSimpleString s = path; + if( path[strlen(path)-1] != '/' ) + s += "/"; + s += text; + return find( s.c_str() ); +} + +Flu_Tree_Browser::Node* Flu_Tree_Browser :: find( unsigned int id ) +{ + return root.find( id ); +} + +Flu_Tree_Browser::Node* Flu_Tree_Browser :: Node :: find( unsigned int id ) +{ + if( id == 0 ) + return NULL; + + if( _id == id ) + return this; + + for( int i = 0; i < _children.size(); i++ ) + { + Node *n = _children.child(i)->find( id ); + if( n ) + return n; + } + + return NULL; +} + +Flu_Tree_Browser::Node* Flu_Tree_Browser :: find( Fl_Widget *w ) +{ + return root.find( w ); +} + +Flu_Tree_Browser::Node* Flu_Tree_Browser :: Node :: find( Fl_Widget *w ) +{ + if( _widget ) + if( _widget->w == w ) + return this; + + for( int i = 0; i < _children.size(); i++ ) + { + Node *n = _children.child(i)->find( w ); + if( n ) + return n; + } + + return NULL; +} + + +bool Flu_Tree_Browser :: Node :: findPath( unsigned int id, RData &rdata ) +{ + if( _id == id ) + { + if( is_leaf() ) + rdata.path += text; + else + { + rdata.path += text; + rdata.path += "/"; + } + return true; + } + + if( is_leaf() ) + return false; + + char *oldPath = strdup( rdata.path.c_str() ); + if( _parent != 0 ) + { + rdata.path += text; + rdata.path += "/"; + } + + for( int i = 0; i < _children.size(); i++ ) + { + if( _children.child(i)->findPath( id, rdata ) ) + { + free( oldPath ); + return true; + } + } + + rdata.path = oldPath; + free( oldPath ); + + return false; +} + +bool Flu_Tree_Browser :: Node :: findPath( Fl_Widget *w, RData &rdata ) +{ + if( _widget ) + if( _widget->w == w ) + { + if( is_leaf() ) + rdata.path += text; + else + { + rdata.path += text; + rdata.path += "/"; + } + return true; + } + + if( is_leaf() ) + return false; + + char *oldPath = strdup( rdata.path.c_str() ); + if( _parent != 0 ) + { + rdata.path += text; + rdata.path += "/"; + } + + for( int i = 0; i < _children.size(); i++ ) + { + if( _children.child(i)->findPath( w, rdata ) ) + { + free( oldPath ); + return true; + } + } + + rdata.path = oldPath; + free( oldPath ); + + return false; +} + +const char* Flu_Tree_Browser :: find_path( unsigned int id ) +{ + // degenerate case: the root is always id==0 + if( id == 0 ) + return "/"; + rdata.path = "/"; + if( root.findPath( id, rdata ) ) + return rdata.path.c_str(); + else + return ""; +} + +const char* Flu_Tree_Browser :: find_path( Fl_Widget *w ) +{ + rdata.path = "/"; + if( root.findPath( w, rdata ) ) + return rdata.path.c_str(); + else + return ""; +} + +static char* remove_escape_chars( const char *str ) +{ + // remove any escape characters + char *text = strdup( str ); + int tIndex = 0; + for( int pIndex = 0; pIndex < (int)strlen( str ); pIndex++ ) + { + if( str[pIndex] != '\\' ) + text[tIndex++] = str[pIndex]; + } + text[tIndex] = '\0'; + + return text; +} + +void Flu_Tree_Browser :: Node :: do_callback( int reason ) +{ + //if( tree->rdata.when == FL_WHEN_NEVER ) + if( tree->when() == FL_WHEN_NEVER ) + return; + //if( tree->rdata.cb ) + { + tree->rdata.cbReason = reason; + tree->rdata.cbNode = this; + //tree->rdata.cb( tree, tree->rdata.cbd ); + ((Fl_Widget*)tree)->do_callback(); + } +} + +unsigned short Flu_Tree_Browser :: Node :: depth() const +{ + int d = 0; + Node *p = _parent; + while( p ) + { + d++; + p = p->_parent; + } + return d; +} + +Flu_Tree_Browser::Node* Flu_Tree_Browser :: Node :: add_branch( const char* fullpath, Fl_Widget *w, bool showLabel ) +{ + FluSimpleString p( fullpath ); + if( p.size() && p[p.size()-1] != '/' && p[p.size()-1] != '\\' ) p += "/"; + return add( p.c_str(), w, showLabel ); +} + +Flu_Tree_Browser::Node* Flu_Tree_Browser :: Node :: add_leaf( const char* fullpath, Fl_Widget *w, bool showLabel ) +{ + FluSimpleString p( fullpath ); + if( p.size() && ( p[p.size()-1] == '/' || p[p.size()-1] == '\\' ) ) p[p.size()-1] = '\0'; + return add( p.c_str(), w, showLabel ); +} + +Flu_Tree_Browser::Node* Flu_Tree_Browser :: Node :: add( const char* path, const char* name, Fl_Widget *w, bool showLabel ) +{ + FluSimpleString p( path ); + if( p.size() && p[p.size()-1] != '/' && p[p.size()-1] != '\\' ) p += "/"; + p += name; + return add( p.c_str(), w, showLabel ); +} + +Flu_Tree_Browser::Node* Flu_Tree_Browser :: Node :: add_branch( const char* path, const char* name, Fl_Widget *w, bool showLabel ) +{ + FluSimpleString p( path ); + if( p.size() && p[p.size()-1] != '/' && p[p.size()-1] != '\\' ) p += "/"; + p += name; + return add_branch( p.c_str(), w, showLabel ); +} + +Flu_Tree_Browser::Node* Flu_Tree_Browser :: Node :: add_leaf( const char* path, const char* name, Fl_Widget *w, bool showLabel ) +{ + FluSimpleString p( path ); + if( p.size() && p[p.size()-1] != '/' && p[p.size()-1] != '\\' ) p += "/"; + p += name; + return add_leaf( p.c_str(), w, showLabel ); +} + +Flu_Tree_Browser::Node* Flu_Tree_Browser :: Node :: modify( const char* path, int what, RData &rdata, Fl_Widget *w, bool showLabel ) +{ + // find the selected entry at rdata.searchIndex among all selected entries + if( what == GET_SELECTED ) + { + if( CHECK(SELECTED) ) + { + rdata.counter++; + if( rdata.counter == rdata.searchIndex ) + return this; + } + for( int i = 0; i < _children.size(); i++ ) + { + Node *n = _children.child(i)->modify( path, what, rdata, w ); + if( n ) + return n; + } + return NULL; + } + + // trivial test for a bogus empty path + if( path == 0 ) + return NULL; + + // if the path starts with '/', skip the '/' + if( path[0] == '/' ) + path++; + + // trivial test for a bogus empty path + if( path[0] == '\0' ) + return NULL; + + const char *remainingPath; + char *nodeName; + bool lastNode, branchNode; + Node *retNode = NULL; + + ///////////// extract the next node name from the path /////////////////// + + // find the next '/' that is not preceded by the escape character '\' + const char *slash = strchr( path, '/' ); + for(;;) + { + // find the next '/' + if( slash == NULL ) // there isn't one, so we're done + break; + // test for escape character + else if( slash[-1] == '\\' ) // path[0] can never be '/', so this is a safe test + slash = strchr( slash+1, '/' ); + // we have it + else + break; + } + + // if there is no slash, then the node name is the path and it is a leaf and the last node in the path + if( slash == NULL ) + { + branchNode = false; + char *name = strdup( path ); // copy the path + nodeName = remove_escape_chars( name ); // remove the escape characters + free( name ); + lastNode = true; + remainingPath = NULL; + } + // otherwise the node name is the path up to the slash, it is also a branch and may not be the last node in the path + else + { + branchNode = true; + char *name = (char*)malloc( slash-path+1 ); + strncpy( name, path, slash-path ); + name[slash-path] = '\0'; + nodeName = remove_escape_chars( name ); // remove the escape characters + free( name ); + lastNode = ( slash[1] == '\0' ); // this is the last node if there is nothing after the slash + if( lastNode ) + { + //if( rdata.autoBranches ) + //branchNode = false; + remainingPath = NULL; + } + else + remainingPath = slash+1; + } + + ///////////// process the node /////////////////// + + switch( what ) + { + case ADD: + { + // if the new node is a leaf node, add the string as a leaf and return + if( !branchNode ) + { + // is there already a node with this name? + Node *n = _children.find( nodeName ); + if( n ) + { + // if that node is a branch node, we can't add a new one with the same name + if( n->is_branch() ) + break; + + // if we are not allowed to add multiple nodes with the same name, + // then just return + if( !rdata.allowDuplication ) + break; + } + + // add a new node + retNode = new Node( true, nodeName, this, rdata, w, showLabel ); + _children.add( retNode ); + rdata.forceResize = true; + rdata.visibilityChanged = true; + + if( tree->rdata.autoBranches ) + initType(); + } + // otherwise make sure the node name exists as a branch and recurse on it + else + { + // if there is already a node with this name, just use it + Node *n = NULL; + n = _children.find( nodeName ); + if( n ) + { + // make sure it is a branch + if( n->is_leaf() ) + break; + } + + // else add a new node + if( n == NULL ) + { + // only add the widget for the last node + n = new Node( false, nodeName, this, rdata, lastNode?w:NULL, lastNode?showLabel:true ); + _children.add( n ); + rdata.forceResize = true; + rdata.visibilityChanged = true; + } + + if( tree->rdata.autoBranches ) + initType(); + + // recurse on the remainder of the path, if not the last node + if( lastNode ) + retNode = n; + else + retNode = n->modify( remainingPath, what, rdata, w, showLabel ); + } + } + break; + + case REMOVE: + { + // try to find the indicated node. if we can't find it, just return + Node *n = _children.find( nodeName ); + if( !n ) + break; + + // if this is the last node, remove it. + if( lastNode ) + { + int ID = n->id(); + _children.erase( n ); + //if( tree->rdata.cbNode == n ) + //tree->rdata.cbNode = NULL; + delete n; + retNode = (Node*)ID; // non-null return value means remove was successful + rdata.forceResize = true; + rdata.visibilityChanged = true; + + if( tree->rdata.autoBranches ) + initType(); + tree->redraw(); + } + // otherwise recurse on the remainder of the path + else + retNode = n->modify( remainingPath, what, rdata, w, showLabel ); + } + break; + + case FIND: + { + // if this node equals the starting node for a find_next, + // then by clearing rdata.previous we flag that we are allowed to return the next match + if( rdata.previous == this ) + rdata.previous = NULL; + + Node *n = NULL; + + if( !lastNode ) + { + // if, according to the path, this is not the last node, then just recursively + // search for the named node + n = _children.find( nodeName ); + if( !n ) + break; + retNode = n->modify( remainingPath, what, rdata, w, showLabel ); + } + else + { + // otherwise, according to the path, this is the last node (i.e. a leaf). + // since only leaves can have multiple identical entries, + // try to find the indicated node, accounting for the possibility + // that it may not be the one we're after + int next = 1; + for(;;) + { + // look for the named node + n = _children.find( nodeName, next++ ); + + // if we can't find it, just return, because it's not here + if( !n ) + break; + + // we are only allowed to return a match if the previous node is NULL, + // indicating we have passed the starting node for a find_next + if( rdata.previous == NULL ) + { + retNode = n; + break; + } + + // if the found node equals the starting node for a find_next, + // then by clearing rdata.previous we flag that we are allowed to return the next match + if( rdata.previous == n ) + rdata.previous = NULL; + } + } + } + break; + + case FIND_NUMBER: + { + if( lastNode ) // can only match multiple leaves if the path says this is the last node + { + rdata.counter += _children.findNum( nodeName ); + } + else // otherwise recurse down the remaining path + { + Node *n = _children.find( nodeName ); + n->modify( remainingPath, what, rdata, w, showLabel ); + } + } + break; + } + + free( nodeName ); + + return retNode; +} + +void Flu_Tree_Browser :: Node :: widgetCB() +{ + if( _widget ) + { + if( _widget->CB ) + _widget->CB( _widget->w, _widget->CBData ); + } + do_callback( FLU_WIDGET_CALLBACK ); +} + +void Flu_Tree_Browser :: Node :: widget( Fl_Widget *w ) +{ + tree->rdata.forceResize = true; + + if( _widget ) + { + Fl_Group *p = _widget->w->parent(); + if( p ) + p->remove( *(_widget->w) ); + delete _widget->w; + delete _widget; + _widget = NULL; + } + + if( !w ) + return; + + _widget = new WidgetInfo; + _widget->w = w; + _widget->defaultW = _widget->w->w(); + if( USE_FLU_WIDGET_CALLBACK ) + { + _widget->CB = _widget->w->callback(); + _widget->CBData = _widget->w->user_data(); + _widget->w->callback( _widgetCB, this ); + } + + { + Fl_Group *p = w->parent(); + if( p ) + p->remove( *w ); + } + + if( is_root() ) + tree->_box->add( w ); + else + { + Node *p = parent(); + if( !p->_group ) + { + p->_group = new Fl_Group( tree->_box->x(), tree->_box->y(), tree->_box->w(), tree->_box->h() ); + p->_group->end(); + tree->_box->add( p->_group ); + } + p->_group->add( w ); + } +} + +void Flu_Tree_Browser :: Node :: branch_icons( Fl_Image *closed, Fl_Image *open ) +{ + if( is_branch() ) + { + bIcon[0] = closed; + bIcon[1] = open; + tree->rdata.forceResize = true; + } +} + +void Flu_Tree_Browser :: Node :: collapse_icons( Fl_Image *closed, Fl_Image *open ) +{ + if( is_branch() ) + { + if( !closed || !open ) + { + cIcon[0] = tree->rdata.defaultCollapseIcons[0]; + cIcon[1] = tree->rdata.defaultCollapseIcons[1]; + } + else + { + cIcon[0] = closed; + cIcon[1] = open; + } + tree->rdata.forceResize = true; + } +} + +void Flu_Tree_Browser :: Node :: leaf_icon( Fl_Image *icon ) +{ + if( is_leaf() ) + { + lIcon = icon; + tree->rdata.forceResize = true; + } +} + +bool Flu_Tree_Browser :: Node :: is_branch() const +{ + if( tree->rdata.autoBranches ) + return( _children.size() != 0 ); + else + return !CHECK(LEAF); +} + +bool Flu_Tree_Browser :: Node :: is_leaf() const +{ + if( tree->rdata.autoBranches ) + return( _children.size() == 0 && !is_root() ); + else + return CHECK(LEAF); +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Wrap_Group.cpp b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Wrap_Group.cpp new file mode 100644 index 0000000..74837c6 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/Flu_Wrap_Group.cpp @@ -0,0 +1,412 @@ +// $Id: Flu_Wrap_Group.cpp,v 1.8 2004/01/27 21:44:24 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#include "FLU/Flu_Wrap_Group.h" +#include +#include + +#define MAX( x, y ) ( (x)>(y) ? (x) : (y) ) + +#define SCROLL_SIZE 15 + +Flu_Wrap_Group :: Scrollbar :: Scrollbar( int x, int y, int w, int h, const char *l ) + : Fl_Scrollbar( x, y, w, h, l ) +{ +} + +int Flu_Wrap_Group :: Scrollbar :: handle( int event ) +{ + if( event == FL_MOUSEWHEEL ) + { + handle_drag( clamp( value() + linesize() * Fl::e_dy ) ); + return 1; + } + else + return Fl_Scrollbar::handle( event ); +} + +Flu_Wrap_Group :: Flu_Wrap_Group( int x, int y, int w, int h, const char *l ) + : Fl_Group( x, y, w, h, l ), scrollbar( x+w-SCROLL_SIZE, y, SCROLL_SIZE, h ), group( x, y, w-SCROLL_SIZE, h ) +{ + offset( 0, 0 ); + spacing( 0, 0 ); + _type = FL_VERTICAL; + scrollTo = NULL; + + Fl_Group::add( &scrollbar ); + scrollbar.callback( _scrollCB, this ); + scrollbar.linesize( 10 ); + scrollbar.range( 0, 100 ); + scrollbar.show(); + + Fl_Group::add( &group ); + Fl_Group::resizable( group ); + Fl_Group::end(); + group.begin(); +} + +void Flu_Wrap_Group :: resize( int x, int y, int w, int h ) +{ + group.resizable( NULL ); + Fl_Group::resize( x, y, w, h ); + if( type() == FL_VERTICAL ) + { + scrollbar.resize( x+w-SCROLL_SIZE-Fl::box_dx(box()), y+Fl::box_dy(box()), SCROLL_SIZE, h-Fl::box_dh(box()) ); + group.resize( x, y, w-SCROLL_SIZE-Fl::box_dx(box()), h ); + } + else + { + scrollbar.resize( x+Fl::box_dx(box()), y+h-SCROLL_SIZE-Fl::box_dy(box()), w-Fl::box_dw(box()), SCROLL_SIZE ); + group.resize( x, y, w, h-SCROLL_SIZE-Fl::box_dh(box()) ); + } + Fl_Group::init_sizes(); + redraw(); +} + +void Flu_Wrap_Group :: scroll_to( const Fl_Widget *w ) +{ + scrollTo = w; + redraw(); +} + +void Flu_Wrap_Group :: scroll_to_beginning() +{ + ((Fl_Valuator*)&scrollbar)->value( scrollbar.minimum() ); +} + +void Flu_Wrap_Group :: scroll_to_end() +{ + ((Fl_Valuator*)&scrollbar)->value( scrollbar.maximum() ); +} + +void Flu_Wrap_Group :: type( int t ) +{ + _type = t; + resize( x(), y(), w(), h() ); +} + +Fl_Widget* Flu_Wrap_Group :: next( Fl_Widget* w ) +{ + for( int i = 0; i < group.children()-1; i++ ) + { + if( w == group.child(i) ) + return group.child(i+1); + } + return NULL; +} + +Fl_Widget* Flu_Wrap_Group :: previous( Fl_Widget* w ) +{ + for( int i = 1; i < group.children(); i++ ) + { + if( w == group.child(i) ) + return group.child(i-1); + } + return NULL; +} + +Fl_Widget* Flu_Wrap_Group :: above( Fl_Widget* w ) +{ + for( int i = 0; i < group.children(); i++ ) + { + if( w == group.child(i) ) + { + int measure[2]; + measure[0] = w->x() + w->w()/2; + measure[1] = w->y() - _spacing[1]; + int index = layout( scrollbar.visible(), false, measure ); + if( index >= 0 ) + return group.child(index); + else + return group.child(0); + } + } + return NULL; +} + +Fl_Widget* Flu_Wrap_Group :: below( Fl_Widget* w ) +{ + for( int i = 0; i < group.children(); i++ ) + { + if( w == group.child(i) ) + { + int measure[2]; + measure[0] = w->x() + w->w()/2; + measure[1] = w->y() + w->h() + _spacing[1]; + int index = layout( scrollbar.visible(), false, measure ); + if( index >= 0 ) + return group.child(index); + else + return group.child(group.children()-1); + } + } + return NULL; +} + +Fl_Widget* Flu_Wrap_Group :: left( Fl_Widget* w ) +{ + for( int i = 0; i < group.children(); i++ ) + { + if( w == group.child(i) ) + { + int measure[2]; + measure[0] = w->x() - _spacing[0]; + measure[1] = w->y() + w->h()/2; + int index = layout( scrollbar.visible(), false, measure ); + if( index >= 0 ) + return group.child(index); + else + return group.child(0); + } + } + return NULL; +} + +Fl_Widget* Flu_Wrap_Group :: right( Fl_Widget* w ) +{ + for( int i = 0; i < group.children(); i++ ) + { + if( w == group.child(i) ) + { + int measure[2]; + measure[0] = w->x() + w->w() + _spacing[0] + 1; + measure[1] = w->y() + w->h()/2; + int index = layout( scrollbar.visible(), false, measure ); + if( index >= 0 ) + return group.child(index); + else + return group.child(group.children()-1); + } + } + return NULL; +} + +int Flu_Wrap_Group :: layout( bool sbVisible, bool doScrollTo, int *measure ) +{ + int xx = x()+Fl::box_dx(box()), yy = y()+Fl::box_dy(box()), + ww = w()-Fl::box_dw(box()), hh = h()-Fl::box_dh(box()); + + if( type() == FL_VERTICAL ) + { + int i, X, Y, maxH, H, col, row, maxW, scrollY; + Fl_Widget *c; + + scrollbar.type( FL_VERTICAL ); + + BEGIN_H: + + X = xx+_offset[0]; + Y = yy+_offset[1] - (sbVisible ? scrollbar.value() : 0); + maxH = _offset[1]; + H = 0; + col = 0; + row = 0; + scrollY = 0; + maxW = xx + ww - (sbVisible ? scrollbar.w() : 0); + + for( i = 0; i < group.children(); i++ ) + { + c = group.child(i); + if( !c->visible() ) + continue; + H = MAX( H, c->h() ); + if( col == 0 ) + maxH += H + _spacing[1]; + if( ( X + c->w() ) > maxW ) + { + Y += H + _spacing[1]; + scrollY += H + _spacing[1]; + if( i == group.children()-1 ) + maxH += H + _spacing[1]; + + if( measure ) + { + if( xx+_offset[0] <= measure[0] && measure[0] <= xx+c->w()+_offset[0]+_spacing[0] && + Y <= measure[1] && measure[1] <= Y+c->h()+_spacing[1] ) + return i; + } + else + c->position( xx+_offset[0], Y ); + + col = 0; + row++; + H = 0; + X = xx+c->w() + _offset[0] + _spacing[0]; + } + else + { + if( measure ) + { + if( X <= measure[0] && measure[0] <= X+c->w()+_spacing[0] && + Y <= measure[1] && measure[1] <= Y+c->h()+_spacing[1] ) + return i; + } + else + c->position( X, Y ); + X += c->w() + _spacing[0]; + col++; + } + + if( doScrollTo && (c == scrollTo) ) + { + if( scrollY > scrollbar.maximum() ) + scrollY = (int)scrollbar.maximum(); + ((Fl_Valuator*)&scrollbar)->value( scrollY ); + scrollTo = NULL; + goto BEGIN_H; + } + + // if we exceed the height and the scrollbar is not visible, + // then it will soon become visible so we don't need to process anymore + if( !measure && !sbVisible && maxH > hh ) + return 1; + } + + if( measure ) + return -1; + else if( maxH > hh ) + { + scrollbar.range( 0, maxH-hh ); + scrollbar.slider_size( MAX( float(scrollbar.h()-(maxH-hh))/float(scrollbar.h()), 0.08f ) ); + return 1; + } + else + return 0; + } + else + { + int i, X, Y, W, maxW, maxH, col, row, scrollX; + Fl_Widget *c; + + scrollbar.type( FL_HORIZONTAL ); + + BEGIN_W: + + X = xx+_offset[0] - (sbVisible ? scrollbar.value() : 0); + Y = yy+_offset[1]; + maxW = _offset[0]; + W = 0; + col = 0; + row = 0; + scrollX = 0; + maxH = yy + hh - (sbVisible ? scrollbar.h() : 0); + + for( i = 0; i < group.children(); i++ ) + { + c = group.child(i); + if( !c->visible() ) + continue; + + W = MAX( W, c->w() ); + + if( row == 0 ) + maxW += W + _spacing[0]; + + if( ( Y + c->h() ) > maxH ) + { + X += W + _spacing[0]; + scrollX += W + _spacing[0]; + if( i == group.children()-1 ) + maxW += W + _spacing[0]; + + if( measure ) + { + if( X <= measure[0] && measure[0] <= X+c->w()+_spacing[0] && + yy+_offset[1] <= measure[1] && measure[1] <= yy+c->h()+_offset[1]+_spacing[1] ) + return i; + } + else + c->position( X, yy+_offset[1] ); + + row = 0; + col++; + W = 0; + Y = yy+c->h() + _offset[1] + _spacing[1]; + } + else + { + if( measure ) + { + if( X <= measure[0] && measure[0] <= X+c->w()+_spacing[0] && + Y <= measure[1] && measure[1] <= Y+c->h()+_spacing[1] ) + return i; + } + else + c->position( X, Y ); + Y += c->h() + _spacing[1]; + row++; + } + + if( doScrollTo && (c == scrollTo) ) + { + if( scrollX > scrollbar.maximum() ) + scrollX = (int)scrollbar.maximum(); + ((Fl_Valuator*)&scrollbar)->value( scrollX ); + scrollTo = NULL; + goto BEGIN_W; + } + + // if we exceed the width and the scrollbar is not visible, + // then it will soon become visible so we don't need to process anymore + if( !measure && !sbVisible && maxW > ww ) + return 1; + } + + if( measure ) + return -1; + else if( maxW > ww ) + { + scrollbar.range( 0, maxW-ww ); + scrollbar.slider_size( MAX( float(scrollbar.w()-(maxW-ww))/float(scrollbar.w()), 0.08f ) ); + return 1; + } + else + return 0; + } +} + +void Flu_Wrap_Group :: draw() +{ + // we first try to fit all children assuming no scrollbar. if they do not all fit, + // we have to turn the scrollbar on and try again + if( layout( false, false ) ) + { + scrollbar.show(); + layout( true, false ); + } + else + scrollbar.hide(); + + // hack to look right when resizing smaller + if( scrollbar.value() > scrollbar.maximum() ) + { + ((Fl_Valuator*)&scrollbar)->value( scrollbar.maximum() ); + layout( scrollbar.visible(), scrollTo!=NULL ); + } + else if( scrollTo ) + layout( scrollbar.visible(), true ); + + scrollTo = NULL; + + if( damage() & ~FL_DAMAGE_CHILD) + { + draw_box(); + draw_label(); + } + fl_push_clip( x()+Fl::box_dx(box()), y()+Fl::box_dy(box()), + w()-Fl::box_dw(box()), h()-Fl::box_dh(box()) ); + draw_children(); + fl_pop_clip(); +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/flu_file_chooser_pixmaps.cpp b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/flu_file_chooser_pixmaps.cpp new file mode 100644 index 0000000..2e4c063 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/flu_file_chooser_pixmaps.cpp @@ -0,0 +1,2470 @@ +// $Id: flu_file_chooser_pixmaps.cpp,v 1.8 2003/12/08 16:25:50 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + +char * monalisa_xpm[] = { +"17 21 212 2", +" c None", +". c #565A2E", +"+ c #7A7A43", +"@ c #7E7A47", +"# c #7A723E", +"$ c #76723E", +"% c #767A46", +"& c #767644", +"* c #86824A", +"= c #8A8246", +"- c #8E864A", +"; c #96925A", +"> c #968E56", +", c #5E6236", +"' c #8E824A", +") c #92864E", +"! c #928A4C", +"~ c #8A8A4E", +"{ c #867A42", +"] c #928252", +"^ c #9E8E52", +"/ c #9A8E52", +"( c #AA9A59", +"_ c #A29656", +": c #827E4A", +"< c #666A3E", +"[ c #A69658", +"} c #867A4E", +"| c #524222", +"1 c #2A2A10", +"2 c #1E1E16", +"3 c #625A3A", +"4 c #B29E62", +"5 c #B6A262", +"6 c #B6A664", +"7 c #AE9E5A", +"8 c #BAA662", +"9 c #B6A25C", +"0 c #92764A", +"a c #F6D66E", +"b c #CA9A52", +"c c #322E12", +"d c #121A12", +"e c #928A5A", +"f c #BEAA62", +"g c #C6B66A", +"h c #BAAA62", +"i c #A29252", +"j c #4E522A", +"k c #827E42", +"l c #B2A25E", +"m c #CAB66A", +"n c #8A7A46", +"o c #A67E3A", +"p c #E2C262", +"q c #CA9242", +"r c #6E5A2A", +"s c #12160A", +"t c #3A3E26", +"u c #9E9255", +"v c #CABA66", +"w c #C6B262", +"x c #867E46", +"y c #262E1A", +"z c #5A5E32", +"A c #52562A", +"B c #86864A", +"C c #4E4E2E", +"D c #866A36", +"E c #BA863A", +"F c #A28246", +"G c #7E6236", +"H c #161A0D", +"I c #222A10", +"J c #4E5A32", +"K c #565E2A", +"L c #6A6E3A", +"M c #1A260E", +"N c #364626", +"O c #424E28", +"P c #3A4A22", +"Q c #323E26", +"R c #262A1A", +"S c #9E7636", +"T c #BA8E4A", +"U c #D6A252", +"V c #564616", +"W c #121E10", +"X c #3A4E2E", +"Y c #465632", +"Z c #6A7242", +"` c #5E6632", +" . c #3E4625", +".. c #121A0A", +"+. c #32421F", +"@. c #36421E", +"#. c #363E1E", +"$. c #1E2616", +"%. c #4A3A22", +"&. c #AE823E", +"*. c #927236", +"=. c #363214", +"-. c #1A1A0C", +";. c #161E0D", +">. c #2A3216", +",. c #0E160D", +"'. c #223216", +"). c #3A4622", +"!. c #363A1C", +"~. c #362E12", +"{. c #26260A", +"]. c #12160E", +"^. c #121A0E", +"/. c #4A5232", +"(. c #323218", +"_. c #0E120E", +":. c #3E321A", +"<. c #8A6E36", +"[. c #7E662E", +"}. c #2E260A", +"|. c #3A4226", +"1. c #5E5626", +"2. c #565626", +"3. c #1E1E0D", +"4. c #4A461E", +"5. c #1E2612", +"6. c #0E1A0E", +"7. c #52421D", +"8. c #E2B65A", +"9. c #EAB252", +"0. c #EEB256", +"a. c #5E421A", +"b. c #2E2214", +"c. c #525226", +"d. c #726A2E", +"e. c #262A0F", +"f. c #3A3612", +"g. c #5A5626", +"h. c #524A18", +"i. c #CA9E4A", +"j. c #F6CE6A", +"k. c #5E3E14", +"l. c #4E4A26", +"m. c #6E622E", +"n. c #221E0E", +"o. c #4A421A", +"p. c #12120A", +"q. c #BA964E", +"r. c #E6CA66", +"s. c #FAE67A", +"t. c #CAAA52", +"u. c #2A260A", +"v. c #0A0E02", +"w. c #060E06", +"x. c #121206", +"y. c #3E2E12", +"z. c #423212", +"A. c #120E0A", +"B. c #6A461E", +"C. c #0A160E", +"D. c #222E12", +"E. c #2E2E0A", +"F. c #46421E", +"G. c #0E120A", +"H. c #0E1206", +"I. c #3A2616", +"J. c #26160A", +"K. c #624A22", +"L. c #564222", +"M. c #1A220E", +"N. c #0E0E06", +"O. c #261E0E", +"P. c #1A160C", +"Q. c #3E3A16", +"R. c #0A1209", +"S. c #060A02", +"T. c #0A0E0A", +"U. c #16120C", +"V. c #020A02", +"W. c #020A06", +"X. c #0A0E06", +"Y. c #0A0A0A", +"Z. c #26220E", +"`. c #1A1212", +" + c #060E10", +".+ c #060A06", +"++ c #060606", +"@+ c #020606", +"#+ c #060602", +"$+ c #0E0A06", +"%+ c #060E0A", +"&+ c #664E1E", +"*+ c #96622E", +"=+ c #422E1E", +"-+ c #060A0E", +";+ c #020602", +">+ c #0A0A02", +",+ c #16160A", +"'+ c #6E5226", +")+ c #AE7232", +"!+ c #B27236", +"~+ c #825A2E", +"{+ c #322A0A", +"]+ c #020202", +"^+ c #826232", +"/+ c #664216", +"(+ c #5E3A26", +"_+ c #46261A", +":+ c #0A0602", +"<+ c #4A3A12", +"[+ c #262216", +"}+ c #1E1A0A", +". + + @ # $ % & @ @ * = = - ; > & ", +", ' - ) - ' ! ~ { ] ^ ^ / ^ ( _ : ", +"< _ ( _ [ [ } | 1 2 3 4 ( 5 6 4 ! ", +"< 7 8 9 4 6 0 a b c d e 8 f g h i ", +"j k ( l m n o p q r s t + u v w x ", +"y , z A B C D E F G H I J K w 7 L ", +"M N O P Q R S T U V W M X Y Z ` .", +"..+.@.Q #.$.%.&.*.=.-.;.N N X X >.", +",.'.@.).A !.,.%.~.{.].H N ).+. .>.", +"^.Q O P /.(._.:.<.[.}.H y |.1.2.I ", +"3.!.4.!.5.6.7.8.9.0.a.b.3.c.d.2.e.", +"3.f.g.h.e.{.i.j.j.9.k.7.l.3.C m.h.", +"n.7.V o.p.:.q.r.s.t.4.u.v.w.x.y.z.", +"A.k.B.n.C.D.E.F.F.1 G.$.3.].H.I.J.", +"A.K.L.].C.H H M.M.w.H.5.(.N._.O.P.", +"-.Q.1 H C.H.R.6.R.S.w.-.N.T.T.s U.", +"G.H ^.-.H w.w.s V.W.S.V.X.X.w.N.A.", +"Y.s Z.E.s `. +R..+++@+#+$+S..+%+N.", +".+X.=.=.&+q *+=+-+;+#+V.>+#+S.W.++", +".+.+N.,+Z.'+)+!+~+b.Z.{+U.S.%+.+]+", +";+S.;+.+| ^+/+~+(+_+}.}.P.#+#+V.:+"}; + +char * filedetails_xpm[] = { +"21 21 42 1", +" c None", +". c #000000", +"+ c #3559A0", +"@ c #3B5DA2", +"# c #4062A5", +"$ c #4666A7", +"% c #4B6AAA", +"& c #506FAC", +"* c #5673AF", +"= c #5B78B1", +"- c #607CB4", +"; c #6681B6", +"> c #6B85B9", +", c #7089BB", +"' c #768EBE", +") c #7B92C1", +"! c #8197C3", +"~ c #869BC6", +"{ c #8BA0C8", +"] c #91A4CB", +"^ c #96A8CD", +"/ c #2F549D", +"( c #35589F", +"_ c #3A5DA2", +": c #4061A4", +"< c #4566A7", +"[ c #4A6AA9", +"} c #506EAC", +"| c #5573AE", +"1 c #5A77B1", +"2 c #6580B6", +"3 c #758DBE", +"4 c #7B92C0", +"5 c #8096C3", +"6 c #859BC5", +"7 c #8B9FC8", +"8 c #90A4CA", +"9 c #8E8E8E", +"0 c #474747", +"a c #FFFFFF", +"b c #917D2F", +"c c #EAD264", +" ", +".....................", +".+@#$%&*=-;>,')!~{]^.", +"./(_:<[}|1-2>,345678.", +".....................", +".9999099990999909999.", +".9999099990999909999.", +".0000000000000000000.", +".aaaaaaaaaaaaaaaaaaa.", +".bccba....a....a...a.", +".aaaaaaaaaaaaaaaaaaa.", +".bccba....a....a...a.", +".aaaaaaaaaaaaaaaaaaa.", +"./^^/a....a....a...a.", +".aaaaaaaaaaaaaaaaaaa.", +"./^^/a....a....a...a.", +".aaaaaaaaaaaaaaaaaaa.", +".aaaaaaaaaaaaaaaaaaa.", +".....................", +" ", +" "}; + +char * filelist_xpm[] = { +"21 21 39 1", +" c None", +". c #000000", +"+ c #3559A0", +"@ c #3B5DA2", +"# c #4062A5", +"$ c #4666A7", +"% c #4B6AAA", +"& c #506FAC", +"* c #5673AF", +"= c #5B78B1", +"- c #607CB4", +"; c #6681B6", +"> c #6B85B9", +", c #7089BB", +"' c #768EBE", +") c #7B92C1", +"! c #8197C3", +"~ c #869BC6", +"{ c #8BA0C8", +"] c #91A4CB", +"^ c #96A8CD", +"/ c #2F549D", +"( c #35589F", +"_ c #3A5DA2", +": c #4061A4", +"< c #4566A7", +"[ c #4A6AA9", +"} c #506EAC", +"| c #5573AE", +"1 c #5A77B1", +"2 c #6580B6", +"3 c #758DBE", +"4 c #7B92C0", +"5 c #8096C3", +"6 c #859BC5", +"7 c #8B9FC8", +"8 c #90A4CA", +"9 c #FFFFFF", +"0 c #EAD264", +" ", +".....................", +".+@#$%&*=-;>,')!~{]^.", +"./(_:<[}|1-2>,345678.", +".....................", +".9999999999999999999.", +".9....99999....99999.", +".9.00.9...9.00.9...9.", +".9....99999....99999.", +".9999999999999999999.", +".9....99999....99999.", +".9.00.9...9.00.9...9.", +".9....99999....99999.", +".9999999999999999999.", +".9....99999....99999.", +".9.00.9...9.00.9...9.", +".9....99999....99999.", +".9999999999999999999.", +".....................", +" ", +" "}; + +char * filelistwide_xpm[] = { +"21 21 39 1", +" c None", +". c #000000", +"+ c #3559A0", +"@ c #3B5DA2", +"# c #4062A5", +"$ c #4666A7", +"% c #4B6AAA", +"& c #506FAC", +"* c #5673AF", +"= c #5B78B1", +"- c #607CB4", +"; c #6681B6", +"> c #6B85B9", +", c #7089BB", +"' c #768EBE", +") c #7B92C1", +"! c #8197C3", +"~ c #869BC6", +"{ c #8BA0C8", +"] c #91A4CB", +"^ c #96A8CD", +"/ c #2F549D", +"( c #35589F", +"_ c #3A5DA2", +": c #4061A4", +"< c #4566A7", +"[ c #4A6AA9", +"} c #506EAC", +"| c #5573AE", +"1 c #5A77B1", +"2 c #6580B6", +"3 c #758DBE", +"4 c #7B92C0", +"5 c #8096C3", +"6 c #859BC5", +"7 c #8B9FC8", +"8 c #90A4CA", +"9 c #FFFFFF", +"0 c #EAD264", +" ", +".....................", +".+@#$%&*=-;>,')!~{]^.", +"./(_:<[}|1-2>,345678.", +".....................", +".9999999999999999999.", +".9....99999999999999.", +".9.00.9............9.", +".9....99999999999999.", +".9999999999999999999.", +".9....99999999999999.", +".9.00.9............9.", +".9....99999999999999.", +".9999999999999999999.", +".9....99999999999999.", +".9.00.9............9.", +".9....99999999999999.", +".9999999999999999999.", +".....................", +" ", +" "}; + +// this xpm is a modification of the KDE home desktop icon +/* XPM */ +char * bighome_xpm[] = { +"44 44 98 2", +" c None", +". c #32363A", +"+ c #7E929E", +"@ c #7E8E9E", +"# c #8696A6", +"$ c #8296A2", +"% c #7A8A9A", +"& c #768A96", +"* c #8EA2B2", +"= c #8A9EAE", +"- c #768692", +"; c #524857", +"> c #96A6BA", +", c #92A6BA", +"' c #869AAA", +") c #8292A2", +"! c #82929E", +"~ c #7E8E9A", +"{ c #7A8E9A", +"] c #72828E", +"^ c #6E828A", +"/ c #9EB2C5", +"( c #9AAEBE", +"_ c #92A2B6", +": c #8A9AAA", +"< c #7A8A96", +"[ c #768696", +"} c #6E7E8A", +"| c #8E727A", +"1 c #A2B6CA", +"2 c #96AABE", +"3 c #96AABA", +"4 c #92A6B6", +"5 c #8E9EB1", +"6 c #8296A6", +"7 c #7A626A", +"8 c #525A62", +"9 c #525E62", +"0 c #9AAEC2", +"a c #727E8A", +"b c #565E66", +"c c #4E5A60", +"d c #6E7A86", +"e c #5A666A", +"f c #56626A", +"g c #525E66", +"h c #5A6A70", +"i c #5A666E", +"j c #566266", +"k c #6E7E86", +"l c #564A5A", +"m c #626E76", +"n c #5E6A72", +"o c #768290", +"p c #6A7A86", +"q c #667682", +"r c #4E565A", +"s c #66767E", +"t c #666E7A", +"u c #5E6E76", +"v c #5E6672", +"w c #66727A", +"x c #4E5656", +"y c #4A565C", +"z c #6A7682", +"A c #62727A", +"B c #5A626A", +"C c #6A7A82", +"D c #626E7A", +"E c #4E5256", +"F c #4A5256", +"G c #5E6A76", +"H c #4A525A", +"I c #66727E", +"J c #626A76", +"K c #525A5A", +"L c #4F565E", +"M c #72828A", +"N c #41494E", +"O c #4F5A5E", +"P c #7A8696", +"Q c #383C40", +"R c #A2BACE", +"S c #4A5252", +"T c #4A4E52", +"U c #CEE6FE", +"V c #464E52", +"W c #B6C6DA", +"X c #C2D6EA", +"Y c #464E4E", +"Z c #AABAC6", +"` c #BED2E6", +" . c #4E565E", +".. c #464A4E", +"+. c #AEBECA", +"@. c #3B4043", +"#. c #9AAAB2", +"$. c #363A3E", +" ", +" . . ", +" . . + @ . ", +" . . . # $ @ % & . . . . ", +" . . . * = # # $ + % & - . . ; ; ; . ", +" . . > , * = = ' ) ! ~ { - ] ^ . . . ; . . ", +" . . . / ( > _ * = : ' ) @ % < [ ] } . ; | . | . ", +" . . 1 1 / ( 2 3 4 5 = ' 6 + ) ~ < - ] ^ . 7 ; . 7 . ", +" . 8 9 . 1 0 0 2 , _ 5 = # # ) @ % < - a } . | | . | . ", +" . b 8 8 c . / 2 , 4 * 5 : ' 6 + ~ % [ ] ] d . | 7 . 7 . ", +" . e f g 9 9 c . 2 3 4 * = : 6 ) @ { & [ ] ^ d . | ; . | . ", +" . h i f j g 8 8 8 . > 4 = 5 ' # ) @ % < [ ^ } k . 7 | . l . . ", +" . m n n i e f j 9 c c . _ = : ' $ ) ~ < - o a d p q . | . . 9 r . ", +" . s t m u v i e f g 9 8 8 . = : # $ + @ < [ ] ^ } p q w . . f r x y . ", +" . z q A m m u h i e B j g 8 8 . ' # ) @ % % [ ] } d C s A D h g r E F . . ", +" . k d C z s A m m n h i f j g 8 8 . ) ) ~ { & - ] } p q A D G h 9 H . . - . ", +" . ] ^ a k z z I I D J n n i e f 9 g g . + @ < - ] ^ } p z A A G f K . ! & ] . ", +" . [ - o ^ k a C z I w A u n h i e f b L L . % & [ o a k z q I u u . . $ % - M . ", +" . < - o ] M a k C C I w D m n i i e j j N O . & [ ^ } k C s D u . = # ) < ] d . ", +" . ~ ~ < P ] ] a } C C z s D D u n i i f f L g . ] ] } p q A . . * = 6 { [ ^ p . ", +" . @ @ % < - - M a k C z z s w m u h i e e b b 8 . } p C q . 0 4 5 # ) % o } z . ", +" . ) @ ~ % < - o ] a } C C s w A m m n i f e j g 8 Q d . . / 3 _ = # @ & ^ C s . ", +" . # $ ! @ % % P - o M k d p z s w A D u i i i j g . . R / 0 , 5 ' + S o d q D . ", +" . ' # ) + ! ~ { P - o a a d d z I w A m u h i i j . R 1 / 2 4 = T T U F p I u . ", +" . : ' # ) + @ { < & P ] ] } k p z I w t m n n i e . R 1 0 , 5 V W X U F C D h . ", +" . = : : ' ) ! ! { H F H F M a } d C s s D D n n i . 1 / 2 4 Y Z W X V S A u 8 . ", +" . * = : : # ) ) @ H H H H H F F } d z z s w A m J . 1 / > * Y Z W S U F A h E . ", +" . 4 5 5 = ' ' # + F F V F F H H H } d C z s w m u . / 2 4 = Y Z V ` U Y m g F . ", +" . 3 4 _ 5 5 ' ' 6 V H V H H y y y M } k z z s w A . / > * ' Y Y Z ` U V n y V . ", +" . > 4 4 _ = 5 : # y y y y y .c 9 ] M } } C C s w . 2 4 5 # ..3 +.` V u g T . ", +" . 2 3 3 4 * * = : y y y c 9 c 8 g P o ] a d d z z @.2 * = $ ..#.Z V I n r . ", +" . / 2 3 > 4 _ * = c g g g 8 j j f & < o ] ] k k z . 4 5 # + ..#.V s m f . ", +" . / 0 0 2 > , 4 5 c c g f g f B B < < [ - ] } } d . * = # ~ ....z s u . ", +" . 1 / 0 0 ( > , , f f f f i B i v @ { < [ o o M } . * : + { ] k p u . ", +" . R 1 / 0 0 2 3 > B i i i n n n G ! @ ~ { & - ] ] . : ) @ < ^ p I . ", +" . . . 1 1 / 0 2 3 i i v G G G m t ) ! @ % < P P ] $.' 6 % ] } s . ", +" . . . . / 0 0 G G J J t D D w ' $ $ @ @ < < - $.# + % a d . ", +" . . . J t m w D w w I : # ) $ + @ % < . ) % [ ] . ", +" . . . . t I t t 5 : # ) $ ! @ % . ) & ] . ", +" . . . . = 5 : : # $ ! ! . % - . ", +" . . . : # 6 ) + . < . ", +" . . . . ) . . ", +" . . . ", +" "}; + +/* +char * bighome_xpm[] = { +"44 44 250 2", +" c None", +". c #1262C2", +"+ c #62AAE2", +"@ c #9BD6F7", +"# c #0656BE", +"$ c #AAE2FA", +"% c #A7DEFA", +"& c #023A92", +"* c #A2E2FA", +"= c #A2DEFA", +"- c #9EDEFA", +"; c #9EDAFA", +"> c #022246", +", c #9ADAFA", +"' c #A6E2FA", +") c #96DAF9", +"! c #0252AA", +"~ c #AAE6FA", +"{ c #9ADFFA", +"] c #96D6FA", +"^ c #92D6F9", +"/ c #8ED6FA", +"( c #26528E", +"_ c #023E99", +": c #C2EEFE", +"< c #92DAF9", +"[ c #8BD2F8", +"} c #86D0F2", +"| c #76BAE9", +"1 c #CDF2FE", +"2 c #B0E8FA", +"3 c #A2E6FA", +"4 c #96DEFA", +"5 c #8DDAFA", +"6 c #8AD6F8", +"7 c #82CEF9", +"8 c #75BEE9", +"9 c #D2F2FE", +"0 c #9EE2FA", +"a c #86D6F8", +"b c #86D2F9", +"c c #82D2F7", +"d c #7ECEF6", +"e c #7ACAF3", +"f c #79C2EB", +"g c #024E9E", +"h c #92DFFA", +"i c #76C9F0", +"j c #6EBEEA", +"k c #6ABAE2", +"l c #0E72DA", +"m c #C6EEFE", +"n c #86DAF9", +"o c #70C6EE", +"p c #68C1EC", +"q c #62BDE9", +"r c #268ADF", +"s c #0A66CE", +"t c #0256BE", +"u c #7BD2F5", +"v c #2186DE", +"w c #0B6ACF", +"x c #3A96DE", +"y c #79CEF2", +"z c #BAEAFC", +"A c #44AAEE", +"B c #167AD8", +"C c #0F6ECF", +"D c #0A6ECE", +"E c #0F6ED7", +"F c #7EC2E6", +"G c #5AB4EC", +"H c #3E9EE6", +"I c #288EE0", +"J c #1C7ED8", +"K c #2082D6", +"L c #92D6EE", +"M c #8AD2EE", +"N c #56B6E6", +"O c #4DAEE7", +"P c #46AAE2", +"Q c #36A2DE", +"R c #2A96DA", +"S c #1A84D8", +"T c #167ECE", +"U c #0E76D6", +"V c #1276CE", +"W c #0E72D3", +"X c #4BB2E5", +"Y c #43A5E5", +"Z c #2E86D6", +"` c #0866CA", +" . c #2692D6", +".. c #1B8AD9", +"+. c #5EBEEA", +"@. c #369DE0", +"#. c #1282CE", +"$. c #127AD7", +"%. c #1276D7", +"&. c #1676DA", +"*. c #72C2EE", +"=. c #2A92E2", +"-. c #0A66BE", +";. c #2A8ED6", +">. c #1E86E6", +",. c #167EE2", +"'. c #0A6AC8", +"). c #96DAF2", +"!. c #57BAEB", +"~. c #2E98DD", +"{. c #208EE0", +"]. c #1E86D6", +"^. c #1A82DF", +"/. c #1582D9", +"(. c #167ED7", +"_. c #127ED8", +":. c #248EEF", +"<. c #4CAAEA", +"[. c #1A82EA", +"}. c #62B6E6", +"|. c #0A72D2", +"1. c #0A6AC2", +"2. c #9BDAF2", +"3. c #4AB6EF", +"4. c #1A86DE", +"5. c #1E86EE", +"6. c #1E8AE1", +"7. c #2692DE", +"8. c #3A9EEA", +"9. c #228ADB", +"0. c #5EBAEA", +"a. c #2292DA", +"b. c #46AEEB", +"c. c #3EA2EA", +"d. c #2E9AE7", +"e. c #2692E6", +"f. c #42AEED", +"g. c #37A6EB", +"h. c #2E9EE6", +"i. c #289AE4", +"j. c #2996E4", +"k. c #2292E2", +"l. c #62C2EF", +"m. c #6AC6EE", +"n. c #2896F2", +"o. c #329EEA", +"p. c #1A8ADF", +"q. c #1686D8", +"r. c #1282DE", +"s. c #4AB2ED", +"t. c #1E8EEA", +"u. c #1E92E2", +"v. c #269AEE", +"w. c #289AF2", +"x. c #168ADE", +"y. c #1686DE", +"z. c #3EAEEA", +"A. c #42B2EF", +"B. c #2EA2EB", +"C. c #2A9EF2", +"D. c #29A2EA", +"E. c #3EAAEE", +"F. c #37A2E6", +"G. c #2FA2F6", +"H. c #3EB6F3", +"I. c #36AEF3", +"J. c #1A8EDF", +"K. c #2296E8", +"L. c #52BAEE", +"M. c #55BFEE", +"N. c #30A6EC", +"O. c #32A2EA", +"P. c #30A6F4", +"Q. c #46B2F1", +"R. c #36AAF3", +"S. c #31AAEF", +"T. c #2AA6EA", +"U. c #41BAF6", +"V. c #3AB2F4", +"W. c #32AEEE", +"X. c #1A92E2", +"Y. c #37AAEC", +"Z. c #A2AEFE", +"`. c #0F6EBE", +" + c #0C6ABA", +".+ c #0656AA", +"++ c #0A66BA", +"@+ c #229AE5", +"#+ c #46B6F0", +"$+ c #42B6F4", +"%+ c #3EB2F2", +"&+ c #DAE2FE", +"*+ c #BAC2FE", +"=+ c #96A6FE", +"-+ c #3BAEF1", +";+ c #022E7C", +">+ c #02327E", +",+ c #269EE7", +"'+ c #5EC6F4", +")+ c #53C2F4", +"!+ c #4CBEF3", +"~+ c #47BAF4", +"{+ c #F2F6FE", +"]+ c #CED6FE", +"^+ c #AEBAFE", +"/+ c #023284", +"(+ c #022A75", +"_+ c #02266A", +":+ c #71CAF1", +"<+ c #72CEF4", +"[+ c #5ABEEA", +"}+ c #E6EAFE", +"|+ c #C2CEFE", +"1+ c #3AB2EE", +"2+ c #6ACEF6", +"3+ c #62CAF6", +"4+ c #5AC6F6", +"5+ c #56C6F6", +"6+ c #3EB6FA", +"7+ c #02368B", +"8+ c #72D2F9", +"9+ c #6ACAF6", +"0+ c #62C6F2", +"a+ c #46BEF5", +"b+ c #2492EE", +"c+ c #023A8A", +"d+ c #82DAF9", +"e+ c #76D2F8", +"f+ c #6ED2F8", +"g+ c #66CEF7", +"h+ c #46BAFA", +"i+ c #023785", +"j+ c #4EBAEA", +"k+ c #4EC2F2", +"l+ c #80D6F7", +"m+ c #79D6F9", +"n+ c #8EDEFA", +"o+ c #5ECAF6", +"p+ c #52C2FA", +"q+ c #0242A0", +"r+ c #0246A7", +"s+ c #02429A", +"t+ c #8ADEFA", +"u+ c #024AAB", +"v+ c #6AD2F7", +"w+ c #065ABA", +"x+ c #A6E6FA", +"y+ c #0346A1", +"z+ c #9E9E9E", +"A+ c #2686D6", +" ", +" . . ", +" . . + @ # ", +" . . . @ $ $ % % # & & & ", +" . . . @ * = % = % - - ; # & > > > > ", +" . . , ' * * = = - ; , , @ , ) & ! ! > ! & ", +" . . . ~ ' ' * - - { , , ) ] ^ ^ ] / ( & _ ! & ( ", +" . . : ~ ~ ' ' = - , , , ) < ] ^ / [ } } & ( & ! & & ", +" . | = 1 2 ~ 3 * - - 4 ) 5 / / 6 6 [ [ 7 7 & & ( ! & ( ", +" . 8 ; , * 9 2 ' 0 0 { 4 < < / a [ b c d e f ( & & g ( & ", +" . | , , ^ ) * 9 ~ = { ) h / 6 6 a c d i j k l & ( & g & ( ", +" . 8 ) ^ ^ [ [ [ ' m * { 4 < 5 n c e o p j q r s ( & & ! ( & t ", +" . f ] ^ / / 6 b b b 2 m 0 h 5 b u i o o p q v w s s & ( g & w x t ", +" . 8 / / / [ [ 7 d d e y z z < a c y y i p A B C C D w w & ! w E E x t ", +" . 8 F 7 [ c e G H I r J K r L M N O P Q R S T U V W W D E E l E E E v X # ", +" . f f 8 8 Y Z B l C w w s ` ...L +.@.R ...K T #.$.%.U %.U l l l &.Y *.=.! ", +" -.8 F k H ;.>.,.B &.%.W C '.'.s ` @.).!.@.~. .{.].^./.(._.$.$.%.%.:.o <.,.[.t ", +" . 8 F }.@.=.I >.^.(._.V W |.C D D 1.1.O 2.3.Q ~. .{.{.4.^.^.,.,.^.X p {.,.5.6.# ", +" 7.f }.8.~.=.7.9.>.^._.(.$.U W |.|.|.|.T 0.2.X Q ~.R a.{...6.4.@.e b.,.5.6.:.:.t ", +" 7.}.c.8.d.d.e.{.6.4.4._.$.$.$.U V U U U a.p 2.f.g.h.i.j.a.k.l.m.j.^.:.:.n.n.n.# ", +" 7.<.A Y o.h.d.j.{.p.p.4.q.r._.$._._._._._.g.o L f.Q h.i.3.M s.t.{.u.v.n.n.w.w.t ", +" e.b.A g.g.o.i.j.k.{.{.x.y.q.y.#.r.#.#.#.#.x.X y ).z.A.y i B.j.i.C.D.C.C.C.w.C.# ", +" k.b.b.E.g.F.D.G.H.I.D.k.J.x.x.x.x.x.y.x.x.x.K.L.d ).).M.B.B.B.N.O.G.'.P.P.o.G.t ", +" e.s.Q.E.R.S.O.#.q.T.H.U.V.W.D.u.X.J.X.X.X.X.X.N.M.{ A.z.Y.I.I.I.1.1.Z.s P.P.P.# ", +" k.s.Q.f.E.R.g.`. +.+++q.@+N.H.H.V.S.@+@+@+@+i.@+#+l.3.X $+H.%+-.&+*+=+-.R.R.S.t ", +" e.3.Q.-+-+R.g. +++;+;+;+>+g ++T ,+W.,+,+D.D.T.D.N.'+)+)+!+~+-.{+]+^+-.'.V.I.I.# ", +" k.s.3.A.%+I.Y.`.-./+;+;+(+(+_+;+J.:+T.T.T.T.S.S.W.<+'+[+)+!+-.}+|+` ^+-.%+V.V.t ", +" e.3.$+%+V.V.-+ +-./+/+;+;+(+(+>+J.<+W.S.W.W.1+1+1+<+2+3+4+5+-.&+-.|+Z.'.U.V.6+# ", +" 7.3.#+A.%+V.-+++-.7+7+/+>+;+(+>+J.<+1+1+H.H.H.H.H.u 8+9+0+'+` -.&+*+=+` a+6+6+t ", +" b+3.~+$+H.H.V. +-.& 7+7+/+>+;+c+X.u U.H.#+U.U.a+!+d+e+f+2+g+-.{+]+^+-.a+h+h+t ", +" k.#+U.H.%+H.H. +'._ & 7+7+/+;+i+X.u a+a+j+!+k+!+!+5 l+m+<+g+-.}+|+` )+k+k+t ", +" 7.h+$+$+U.H.H. +-._ _ & 7+7+i+i+..n !+)+k+5+)+5+5+n+n m+m+8+-.&+-.o+5+p+t ", +" 7.~+U.$+H.H.H.-.1._ q+_ & 7+7+i+..n )+5+M.5+5+o+4+h h l+l+m+-.` g+o+o+t ", +" 7.~+~+U.U.U.U.++'.r+_ s+_ & 7+i+..5 o+o+o+o+3+o+3+- h t+d+m+e+f+g+4+t ", +" 7.H.~+U.U.U.a+ +'.r+q+q+s+_ & c+x.5 o+o+o+g+g+g+g+0 4 n+n d+m+e+M.t ", +" k.t ^.B.V.H.~+++'.u+r+r+_ s+& c+J.h 3+g+v+g+g+v+v+3 0 h 5 d+d+j+t ", +" Z t t t C ! w+u+r+u+q+q+_ _ ..{ g+2+<+2+2+f+<+x+0 h n+5 !.t ", +" t # t y+y+r+r+y+y+s+..{ v+2+v+8+f+f+f+x+0 h 5 [+t ", +" t t t t _ _ y+#.4 f+f+f+8+f+m+f+2 3 n 0.t ", +" Z t t .+Z j+m.3+m+8+8+8+~ l+q t ", +" z+.+t t O N L.j+4+y p t ", +" Z t t .+A+k w+ ", +" r t t ", +" "}; +*/ + +char * folder_favorite_xpm[] = { +"20 20 78 1", +" c None", +". c #444444", +"+ c #474747", +"@ c #414141", +"# c #383838", +"$ c #CEC765", +"% c #FFF373", +"& c #FFEF77", +"* c #FFEC78", +"= c #FFE87C", +"- c #B7A569", +"; c #DACD6D", +"> c #FFE97B", +", c #FFE67D", +"' c #FFE182", +") c #FFE082", +"! c #FFDE83", +"~ c #FFDD84", +"{ c #DABE78", +"] c #FFF6AA", +"^ c #FFE79E", +"/ c #FFF1A5", +"( c #FFEFA4", +"_ c #FFDB87", +": c #FFD88A", +"< c #FFD68B", +"[ c #FFD48E", +"} c #FFD48D", +"| c #FFD48C", +"1 c #FFD58B", +"2 c #F6CE88", +"3 c #FFEEA3", +"4 c #FFECA1", +"5 c #DACB8F", +"6 c #FFE89F", +"7 c #FFE69D", +"8 c #FFE49B", +"9 c #FFE39A", +"0 c #FFE29A", +"a c #FFE199", +"b c #FFE098", +"c c #FFDF97", +"d c #FFDE96", +"e c #FFDD95", +"f c #FFDC94", +"g c #FFECA2", +"h c #FFEBA1", +"i c #FF0000", +"j c #FFDC95", +"k c #FFDB94", +"l c #FFEBA0", +"m c #FFE89E", +"n c #FFE79D", +"o c #FFD992", +"p c #FFE99E", +"q c #FFE69C", +"r c #FFE59B", +"s c #FFE299", +"t c #FFD791", +"u c #FFD891", +"v c #FFD68F", +"w c #FFD690", +"x c #FFD790", +"y c #FFE198", +"z c #FFDF96", +"A c #FFDE95", +"B c #FF8357", +"C c #FF8658", +"D c #FFD58F", +"E c #FFDA93", +"F c #FF9262", +"G c #FF8558", +"H c #FFD58E", +"I c #FFDB93", +"J c #FFDA92", +"K c #FF9664", +"L c #FF9060", +"M c #FF895B", +" ", +" .++++@ ", +" #$%&*=-. ", +" ++++++++++;>,')!~{+", +"+]]^^////(+_:<[}|12+", +"+]]^^^33345+++++++++", +"+](3^^^6677890abcde+", +"+((36^^aaaabccddeff+", +"+(gh6^iiidiiijjfkkk+", +"+lmn8iiiiiiiiiooooo+", +"+pqrsiiiiiiiiittuuu+", +"+8sbdiiiiiiiiivvwxx+", +"+yzAfBiiiiiiiCDDvvv+", +"+cejEEFiiiiiGHDDvvv+", +"+IJouuwKiiiL[[HHHHH+", +"+ouuxxvDBiM[[[[[[[[+", +"+HHHHH[[[[[[[[[[[[[+", +" ++++++++++++++++++ ", +" ", +" "}; + +char * bigfavorites_xpm[] = { +"44 44 263 2", +" c None", +". c #DB4848", +"+ c #FF0000", +"@ c #FF9393", +"# c #FF4C4C", +"$ c #FA9191", +"% c #F64F4F", +"& c #F80505", +"* c #FC0808", +"= c #FC9A9A", +"- c #FA6262", +"; c #FC2C2C", +"> c #FC4141", +", c #FF3A3A", +"' c #FF1111", +") c #FE0D0D", +"! c #F92222", +"~ c #FF8181", +"{ c #FFF2F2", +"] c #FF0202", +"^ c #FF0707", +"/ c #EE0808", +"( c #FC2525", +"_ c #FE0000", +": c #C70808", +"< c #B60B0B", +"[ c #BD0A0A", +"} c #591A1A", +"| c #663939", +"1 c #736040", +"2 c #907750", +"3 c #927851", +"4 c #937952", +"5 c #917751", +"6 c #746040", +"7 c #FA0303", +"8 c #F60808", +"9 c #BF0909", +"0 c #A80D0D", +"a c #961010", +"b c #957B52", +"c c #E0B87D", +"d c #9C8157", +"e c #FC1717", +"f c #FA2323", +"g c #FF3F3F", +"h c #E41616", +"i c #E30404", +"j c #BE0A0A", +"k c #9D7272", +"l c #7C6745", +"m c #AF9161", +"n c #836D49", +"o c #DD5454", +"p c #FF5050", +"q c #FF8383", +"r c #FF7070", +"s c #5A1C1B", +"t c #5A1B1B", +"u c #7E4D48", +"v c #E1D0C5", +"w c #C1AD96", +"x c #927951", +"y c #967C53", +"z c #AB8D5F", +"A c #DC4D4D", +"B c #FF2525", +"C c #FF5252", +"D c #D8C8B9", +"E c #E2D3C8", +"F c #DBCBBE", +"G c #B7A489", +"H c #5C1E1C", +"I c #632722", +"J c #5D1E1E", +"K c #7A433F", +"L c #F5DECC", +"M c #E4C290", +"N c #DFB97C", +"O c #B69765", +"P c #EDE19E", +"Q c #F2E5B5", +"R c #F8ECD5", +"S c #F8EBD6", +"T c #F3E3C0", +"U c #E6C78F", +"V c #7A4233", +"W c #60231F", +"X c #622323", +"Y c #804C47", +"Z c #EFD6BA", +"` c #B59564", +" . c #806E4A", +".. c #ECDD9F", +"+. c #F4E5C6", +"@. c #F7E8D4", +"#. c #F3E1C4", +"$. c #E3C385", +"%. c #E1BF81", +"&. c #7E4635", +"*. c #5F211E", +"=. c #9D7068", +"-. c #E5C392", +";. c #CBA770", +">. c #A98D5E", +",. c #B29664", +"'. c #BB9C69", +"). c #BC9D6A", +"!. c #B89A67", +"~. c #8D754E", +"{. c #947F56", +"]. c #EBDC99", +"^. c #E9D795", +"/. c #E8D291", +"(. c #F2DFBF", +"_. c #F6E5D1", +":. c #F1DBBD", +"<. c #72372C", +"[. c #C7A48B", +"}. c #CAA770", +"|. c #A5895C", +"1. c #E2C384", +"2. c #FFDD96", +"3. c #FFDC94", +"4. c #FFDB93", +"5. c #967D54", +"6. c #958057", +"7. c #E6CE8D", +"8. c #E4C889", +"9. c #F2DDC2", +"0. c #F5E2CF", +"a. c #EBCFA9", +"b. c #C9A06C", +"c. c #DCC182", +"d. c #FFE39A", +"e. c #FFE299", +"f. c #FFE098", +"g. c #FFDF97", +"h. c #FFDE96", +"i. c #FFDC95", +"j. c #FFDB94", +"k. c #ECC887", +"l. c #9A8156", +"m. c #E4C48D", +"n. c #F5E0CD", +"o. c #C8A66F", +"p. c #DCC685", +"q. c #FFE99F", +"r. c #FFE79E", +"s. c #FFE69D", +"t. c #FFE59C", +"u. c #FFE39B", +"v. c #FFE198", +"w. c #FFDD95", +"x. c #FFDA93", +"y. c #C0A16C", +"z. c #CBAB73", +"A. c #DDCA8A", +"B. c #FFEEA4", +"C. c #FFEDA3", +"D. c #FFECA1", +"E. c #FFEAA0", +"F. c #FFE89E", +"G. c #FFE49B", +"H. c #FFE29A", +"I. c #FFE199", +"J. c #FFD992", +"K. c #C0A26C", +"L. c #E4D592", +"M. c #FFF4A8", +"N. c #FFF3A7", +"O. c #FFF1A6", +"P. c #FFF0A5", +"Q. c #FFEFA4", +"R. c #FFECA2", +"S. c #FFEBA1", +"T. c #FFE9A0", +"U. c #FFE89F", +"V. c #FFE79D", +"W. c #FFD891", +"X. c #C2A46E", +"Y. c #FFF6A9", +"Z. c #FFF5A9", +"`. c #FFF3A8", +" + c #FFF2A7", +".+ c #FFF1A5", +"++ c #FFEEA3", +"@+ c #FFEDA2", +"#+ c #FFD791", +"$+ c #C2A36E", +"%+ c #CCAE76", +"&+ c #FFE097", +"*+ c #EAC483", +"=+ c #947E55", +"-+ c #FFD790", +";+ c #C0A06B", +">+ c #BFA16C", +",+ c #DECF8D", +"'+ c #FFF4A9", +")+ c #FFF2A6", +"!+ c #FFD892", +"~+ c #FFD68F", +"{+ c #947D54", +"]+ c #FFEFA5", +"^+ c #FFD690", +"/+ c #FFD58F", +"(+ c #C2A26D", +"_+ c #937C54", +":+ c #A68A5C", +"<+ c #FFEBA0", +"[+ c #FFDE97", +"}+ c #FFD48E", +"|+ c #7F6A47", +"1+ c #DBCB8B", +"2+ c #FFE69C", +"3+ c #FFDA92", +"4+ c #E8C181", +"5+ c #9E8358", +"6+ c #FFD58E", +"7+ c #C09F6B", +"8+ c #BFA06B", +"9+ c #DCCC8A", +"0+ c #C2A26C", +"a+ c #A78A5D", +"b+ c #BF9F6B", +"c+ c #BF9F6A", +"d+ c #C2A16C", +"e+ c #E4D390", +"f+ c #ECC886", +"g+ c #C1A36D", +"h+ c #C0A06C", +"i+ c #907850", +"j+ c #CBA86F", +"k+ c #E8C887", +"l+ c #C0A26E", +"m+ c #BFA26D", +"n+ c #C1A46E", +"o+ c #BFA26C", +"p+ c #8A734D", +"q+ c #EDD18C", +"r+ c #C7AC74", +"s+ c #C2A670", +"t+ c #BFA36E", +"u+ c #C0A46E", +"v+ c #89724C", +"w+ c #DAC788", +"x+ c #F2DB95", +"y+ c #C0A570", +"z+ c #BFA570", +"A+ c #C1A771", +"B+ c #C2A771", +"C+ c #C9AF76", +"D+ c #F2DE98", +"E+ c #C0A670", +"F+ c #BFA771", +"G+ c #C1A972", +"H+ c #BFA670", +"I+ c #A2875B", +"J+ c #9A8459", +"K+ c #9C865A", +"L+ c #AF9564", +"M+ c #B39967", +"N+ c #BDA56F", +" ", +" ", +" ", +" ", +" ", +" . . . . ", +" . + + + . . @ + + ", +" . + + # + + . . $ % & + + ", +" . + # @ # + + . * = - ; > , ", +" . + @ # + + + + ' + ) ! # ~ { ", +" . + @ # + + + ] + ^ + + / ( { { { ", +" . + + + + + ] + + + _ : < [ } } } | 1 2 3 4 4 4 5 6 ", +" . + + 7 8 & + + _ 9 0 a } } } } | { { { b c c c c c c d ", +" . * e f ; > g h i j } } | } } } } k { { l m c c c c c c c n ", +" o + ) ! p q @ r } | } s t } u v w x x y m c c c c c c c c z ", +" A + + ^ B C D E F G } | | H } I J K L M N N N N c c c c c c c O ", +" . + + + P P Q R S T } | U V } W X Y Z N N N N N N N N N N N ` ", +" .P . + P P P P ..+.@.#.| $.%.&.} *.} =.-.N N N N N N N N ;.>.,.'.).!.~. ", +" {.P P P P P P ].^./.(._.:.%.N N <.} } } [.N N N }.|.|.|.|.|.|.1.2.3.4.5. ", +" 6.P P P P P ].^./.7.8.9.0.a.N N b.} } } |.|.|.|.|.|.c.d.e.f.g.h.i.j.k.l. ", +" 6.P P P P ].^./.7.8.$.m.n.n.M o.|.|.|.|.|.p.q.r.s.t.u.e.v.g.h.w.j.x.y. ", +" 6.P P P ].^./.7.8.$.z.|.|.|.|.|.A.B.C.D.E.q.F.s.t.G.H.I.f.h.w.3.x.J.K. ", +" 6.P P ].^./.7.|.|.|.|.L.M.N.O.P.Q.C.R.S.T.U.V.t.G.d.I.f.g.2.i.j.J.W.X. ", +" 6.P ].^./.7.8.|.Y.Y.Y.Z.`. +.+Q.++@+S.E.q.r.s.t.d.e.v.g.h.w.j.x.J.#+$+ ", +" {.].^./.7.8.%+|.Y.Y.Z.M. +O.P.B.@+D.E.q.F.s.t.G.H.I.&+h.w.3.x.J.W.*+y. ", +" =+^./.7.8.$.|.|.Y.Z.M.N.O.P.Q.C.R.S.q.F.V.t.G.d.I.f.g.2.3.4.J.W.-+;+>+ ", +" =+/.7.8.$.%.|.,+Y.'+N.)+P.Q.++R.S.E.U.r.s.G.d.e.f.g.h.i.j.x.!+-+~+y. ", +" {+7.8.$.%.;.|.Y.Z.`. +O.]+++@+S.E.q.r.s.t.u.H.v.g.h.w.j.x.J.#+^+/+(+ ", +" _+8.$.%.N :+|.Z.M.N.O.P.Q.C.R.<+q.F.V.t.G.H.I.f.[+w.3.x.J.W.^+/+}+(+ ", +" |+$.%.N N |.1+M.N.)+P.Q.++R.S.E.U.V.2+G.d.e.f.g.h.i.j.3+W.-+~+}+4+;+ ", +" 5+N N }.|.Z.`. +.+Q.++@+S.E.q.r.s.t.d.e.v.g.h.w.j.x.J.#+^+6+}+7+8+ ", +" x N N |.|.M. +O.P.B.C.D.E.q.F.s.t.G.H.I.f.h.w.3.x.J.W.^+/+}+}+;+ ", +" x N N |.9+N.O.P.Q.C.R.S.T.F.V.t.G.d.I.f.g.2.i.4.J.W.-+/+}+}+}+0+ ", +" x N ;.|.`.)+P.Q.++R.S.E.U.r.s.G.d.e.f.g.h.i.j.x.!+-+~+}+}+}+}+;+ ", +" x N a+|. +O.P.++@+D.E.q.F.s.t.G.H.v.&+h.w.3.x.J.W.^+/+4+7+b+c+d+ ", +" x N |.e+O.P.Q.C.R.S.q.F.V.t.G.d.I.f.g.2.3.4.f+y.>+g+(+8+h+ ", +" i+j+|.)+P.Q.++R.S.E.U.r.2+G.d.e.f.g.k+l+m+n+o+g+ ", +" p+|.|.O.Q.++@+S.E.q.r.s.t.u.q+r+s+s+t+u+ ", +" v+|.w+P.B.C.D.E.q.x+y+z+A+B+C+ ", +" v+|.P.Q.C.D+E+F+G+H+E+ ", +" v+I+J+K+L+M+N+ ", +" ", +" ", +" "}; + +char * desktop_xpm[] = { +"46 37 247 2", +" c None", +". c #262626", +"+ c #9BA6BB", +"@ c #94A2B9", +"# c #96A6BD", +"$ c #919EB6", +"% c #8C99B1", +"& c #8697AC", +"* c #3D3D3D", +"= c #FFFFFF", +"- c #9DAABD", +"; c #929AAE", +"> c #A6AEBF", +", c #A3AABD", +"' c #9AA2AE", +") c #99989C", +"! c #969DAB", +"~ c #AAB2C1", +"{ c #9EA6B1", +"] c #848A8B", +"^ c #8A8179", +"/ c #8F8A82", +"( c #7C7269", +"_ c #AAAEBF", +": c #99A0A0", +"< c #AAAAAA", +"[ c #7E8688", +"} c #62615B", +"| c #8A867D", +"1 c #867864", +"2 c #93867D", +"3 c #958774", +"4 c #B4ACAA", +"5 c #7C7667", +"6 c #AEA69E", +"7 c #95908B", +"8 c #A8A09C", +"9 c #AA9B8D", +"0 c #D7CDC3", +"a c #AEB2C2", +"b c #AEB6C3", +"c c #B3B6C1", +"d c #696E68", +"e c #6E6C68", +"f c #726852", +"g c #69625A", +"h c #AF9E91", +"i c #827159", +"j c #C6B4A5", +"k c #736E61", +"l c #868078", +"m c #585C4E", +"n c #293D44", +"o c #7B7E76", +"p c #727A80", +"q c #525B53", +"r c #4D5246", +"s c #4C4E46", +"t c #605D4F", +"u c #B4BAC4", +"v c #BEC0C6", +"w c #AEB2B2", +"x c #79828F", +"y c #9A8F87", +"z c #E1D1C3", +"A c #E3D6CA", +"B c #C4BBB0", +"C c #3F505D", +"D c #585E5D", +"E c #31414C", +"F c #52525A", +"G c #404A41", +"H c #3A3D2E", +"I c #5B5644", +"J c #57563A", +"K c #3C4435", +"L c #434A32", +"M c #4A5662", +"N c #E8E0DA", +"O c #DAD4CA", +"P c #CCC6C4", +"Q c #727E82", +"R c #3D4F4A", +"S c #BAA68E", +"T c #A1917E", +"U c #90806D", +"V c #BCAE9C", +"W c #827A6F", +"X c #BAB4B2", +"Y c #A09992", +"Z c #56626E", +"` c #263538", +" . c #323A46", +".. c #82847E", +"+. c #4A4E2D", +"@. c #7A182D", +"#. c #6C6148", +"$. c #7C6A4E", +"%. c #646969", +"&. c #524F3A", +"*. c #525636", +"=. c #657274", +"-. c #6D7980", +";. c #6E7269", +">. c #B5A89B", +",. c #72665A", +"'. c #D0C0B2", +"). c #4E606C", +"!. c #2F464E", +"~. c #3A4A38", +"{. c #726746", +"]. c #7C7059", +"^. c #0F1A27", +"/. c #2A3436", +"(. c #4A483B", +"_. c #5E5538", +":. c #BEB2AA", +"<. c #E3DAD3", +"[. c #9E8A82", +"}. c #999692", +"|. c #788189", +"1. c #787974", +"2. c #4A3E2E", +"3. c #193625", +"4. c #3C432C", +"5. c #5A5A42", +"6. c #6A6648", +"7. c #887252", +"8. c #5E5A3F", +"9. c #AAA6A4", +"0. c #8A8E8F", +"a. c #787A82", +"b. c #5E6666", +"c. c #6E6B5D", +"d. c #223444", +"e. c #51564D", +"f. c #213A26", +"g. c #2E432E", +"h. c #293F2C", +"i. c #183224", +"j. c #43452C", +"k. c #1A222A", +"l. c #665642", +"m. c #5D6D73", +"n. c #656E77", +"o. c #203A44", +"p. c #324A4C", +"q. c #32423E", +"r. c #3B484A", +"s. c #3D4440", +"t. c #A39788", +"u. c #232D2D", +"v. c #35432F", +"w. c #645D3E", +"x. c #1A3448", +"y. c #132E3D", +"z. c #1B2D37", +"A. c #273A37", +"B. c #1D333E", +"C. c #363D39", +"D. c #4A5250", +"E. c #68695D", +"F. c #132630", +"G. c #263427", +"H. c #92865E", +"I. c #4C513B", +"J. c #313E2B", +"K. c #152E24", +"L. c #32352D", +"M. c #123246", +"N. c #203537", +"O. c #344641", +"P. c #1D2D32", +"Q. c #061627", +"R. c #0A1E2B", +"S. c #152A2F", +"T. c #2A3A32", +"U. c #2E3A36", +"V. c #1B2A29", +"W. c #203332", +"X. c #A28A68", +"Y. c #565E3A", +"Z. c #203625", +"`. c #1F3225", +" + c #2A3827", +".+ c #112637", +"++ c #102234", +"@+ c #0F1E29", +"#+ c #112229", +"$+ c #152627", +"%+ c #1B2E24", +"&+ c #5252EA", +"*+ c #85DD88", +"=+ c #4D563D", +"-+ c #585238", +";+ c #424536", +">+ c #0A1A2A", +",+ c #8E7A58", +"'+ c #193237", +")+ c #152A26", +"!+ c #293E3A", +"~+ c #364A36", +"{+ c #454F3B", +"]+ c #364A3C", +"^+ c #303E3B", +"/+ c #1E2E2C", +"(+ c #6D623E", +"_+ c #1A322D", +":+ c #1E322E", +"<+ c #1A2627", +"[+ c #313A28", +"}+ c #86764C", +"|+ c #4A4930", +"1+ c #4A422A", +"2+ c #504A37", +"3+ c #2E3E42", +"4+ c #991299", +"5+ c #4A5652", +"6+ c #444E47", +"7+ c #AAAD62", +"8+ c #827F74", +"9+ c #62624F", +"0+ c #605D46", +"a+ c #847658", +"b+ c #7E7970", +"c+ c #525144", +"d+ c #5D6259", +"e+ c #8E7E62", +"f+ c #B7A18B", +"g+ c #737266", +"h+ c #676655", +"i+ c #726E56", +"j+ c #897E67", +"k+ c #717873", +"l+ c #61675C", +"m+ c #AAA292", +"n+ c #8A8888", +"o+ c #8E8F8F", +"p+ c #7E8280", +"q+ c #9C8A73", +"r+ c #BEA894", +"s+ c #778181", +"t+ c #868E92", +"u+ c #5A5651", +"v+ c #919191", +"w+ c #4F4F4F", +"x+ c #000000", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". + + @ @ @ @ # # # # @ @ @ @ + # # # # # # # # @ @ @ @ @ @ @ $ $ $ % % % % % % & & & & & . ", +". # * * = + + + # - - - + + + - - - - + # # # # @ # # # # @ @ $ $ $ $ $ $ $ % $ % % ; ; & . ", +". - + = * + - + - + - - - - > - - - - - , - , + - + + ' @ # @ # @ @ @ @ $ $ $ % $ ; % % & . ", +". , - * = - > - > > , , , > > , , > , , > > > , > , , + - - + + + + @ ) ' # @ @ @ ! $ ; % . ", +". > * = * > , , , , > > ~ ~ ~ ~ > > ~ > > > , > , , , > , - ! { ] ^ / ( _ ) , { : ' ; : ! . ", +". _ > _ , > > > ~ ~ ~ ~ ~ > > > > ~ ~ > ~ > > > , < > > { [ } | } 1 2 3 4 5 6 7 / 8 9 0 < . ", +". _ > ~ a , + a ~ ~ ~ ~ ~ b b b c ~ a b ~ ~ ~ > > > , { d e f | g h i j 4 k / l 2 ( 4 m n . ", +". o p q r s t ! u ~ a b a ~ u v u b c a a w ~ _ ~ ) ! x l y z 6 f j h A z z B 9 p C D E F . ", +". G H I J K L t a u @ M ' v N A O P b u b b c w Q C R q y S T T U A z V 5 W X Y Z ` n .... ", +". +.= @.= #.$.I %.! K &.*.N X a A N 0 u c c ~ =.Z -.;.8 j B >.,./ '.z 7 g D -.-.).!.D ( | . ", +". ~.@.@.@.{.$.].^./.(.#._.( ] >.:.N <.8 < _ -.!.D 7 h V h >.[.T 3 '.z }.|.|.Z ). .1.2.( k . ", +". 3.4.@.@.5.6.#.^.K #.7.8.( Y 4 A 9.) 0.a.|.D b.c.} o t ^ ,.t k #.B P [ M p d./.%.s } e e.. ", +". f.g.h.i.f.j.h.k.4.g {.l.8.1 j x m.x n.).o.p.p.q.p.r.s.o ;.W V T t.y |.=.C d.Z e.s.F u.F . ", +". ~.h.j.~.i.3.i.v.H w.{.&.8.7.l !.x.x.C y.z.R A.E B. .E C.D.K E.5 q.u.r.E F.G.G.F s.H s.G.. ", +". H.I.J.v.f.K.i.q.L.&.8.L.l._.D x.M.M.y.y.n z.x.M.N.R q D s.O.u.z.N.P.!.Q.R.S.T./.U.u.V.W.. ", +". X.Y.3.h.Z.K.i.3.`.`.I 2.2.G. +T.x.y.y.y.x.y..+.+++S.V.o.N.F.S.S.@+z.++Q.Q.@+#+$+K.V.%+K.. ", +". X.&+*+i.i.K.i.i.3.f.=+-+K c.{.w.;+z.x.y.p.x..+R.++.+++++#+S.#+R.>+.+Q.Q.^.@+++$+#+$+$+K.. ", +". L.*+i.&+K.i.K.i.i.3.%+K.H 7.,+w.L i.'+!.'+y..+.+++R.>+++++++R.>+Q.Q.Q.Q.>+Q.F.R.R.#+)+)+. ", +". %+&+*+&+K.K.i.K.i.i.i.i.Z.J.v.G.%+Z.i.T.R !+E .+++++.+#+#+R.#+R.>+Q.Q.Q.^.>+#+R.@+@+)+F.. ", +". L *+&+*+g.h.h.h.~+L v.v.~+{+=+{+~.~+O.K R R R O.]+g.!.O.O.O.!.q.^+q.E A.A.W.` /+/+/+%+`.. ", +". 6.v.Z.Z.`.i.3.i.Z.f.v. +4.(+(+-+J._+%+!+]+:+_+.+.+F.#+$+$+$+#+@+@+^.Q.>+>+@+$+$+$+$+<+)+. ", +". {.v.Z.`.%+i.`.`.Z.G.J.[+L (+6.-+J.Z._+q.R A.'+S.)+F.F.$+S.)+$+#+@+@+@+@+@+#+)+$+$+$+V.)+. ", +". }++.Z.G.`.%+`.Z.Z. +|+4.1+w.(+-+v.N.B.o.q.'+z.S.S.S./+W.W./+V.<+k.W.F.^.k.#+<+V.V.<+%+%+. ", +". }++.f.[+`.`.`.G.f.4.J j.2+w.w.L ^+^+` ` A.W.:+z.u.A.U.^+U.T.C.q./.3+u.@+@+$+/+G.u.V.%+V.. ", +". (+4+ +v.G.Z.G. +L.+._.1+_.w.].w.e.D.5+O.O.3+` A.!+G r 6+{+s.(.;+L ;+E u./+V.L.K [+L.[+[+. ", +". _.7+4+7+[+v.G. +4.-+w.2+(+$.U 8+5 t 5+r.q.^+^+q.K r (.9+0+-+f w.9+g 5+E 3+G.C.K C.H K H . ", +". +.7+7+4+|+|+4.G.2.-+w._.{.a+t.3 5 b+e D D q G s c+t 5.c.6.6.a+f ,+W d+D.G U.G r L ;+j.{+. ", +". 4.4+j.|+|+&.+.[+-+5._._.7.e+8 f+h t.1.g+d b.5+q 5.h+6.( 1 i e+i t.t.5 D D 6+(.s |+&.c+c+. ", +". I.-+*.I._._.&.9+d c.w.6.T 9 9 t.T 7 ..o ..%.r 5.E.i+k U U j+i i f+f+5 m e.r 5+s s 2+#.0+. ", +". c+8.9+w.8._.5.9+g+E.f g+t.y 9 S >.Y | / 0.;.D t h+E.W e+H.e+j+}+f+S | c.,.k t s (.(.8.i+. ", +". d+0+I c+w.0+h+k+k+9+l+b+h Y }.m+9.: / n+o+p+k+-.;.k+;.^ T q+,+].r+f+3 ].f ( e D.6+e.2+c.. ", +". h+l+l+k+o s+[ [ p+1.5 1.7 7 y 6 8 ) n+t+t+] p 1.1.5 1 W a+1 3 i j f+T ].j+^ W q C.u+t k . ", +". v+&+v+v+v+4+v+v+*+*+*+v+v+v+v+@.v+v+v+w+v+v+v+v+v+v+w+v+v+v+v+v+v+v+w+v+v+w+v+v+v+v+v+v+. ", +". &+x+x+v+4+4+4+v+*+7+*+v+v+v+@.v+@.v+v+w+v+x+x+v+x+v+w+v+x+x+v+x+x+v+w+v+v+w+v+x+x+v+x+v+. ", +". x+v+&+v+v+4+v+v+*+*+*+v+v+@.v+@.v+@.v+w+v+v+v+v+v+v+w+v+v+v+v+v+v+v+w+v+v+w+v+v+v+v+v+v+. ", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . "}; + +char * bigtemporary_xpm[] = { +"44 44 124 2", +" c None", +". c #726242", +"+ c #927652", +"@ c #927A52", +"# c #766242", +"$ c #967A52", +"% c #DEBA7A", +"& c #967E56", +"* c #7E6646", +"= c #AA8E5E", +"- c #DEBA7E", +"; c #826E4A", +"> c #967E52", +", c #A68A5E", +"' c #E2BE82", +") c #B69666", +"! c #E6CE8E", +"~ c #E6CA8A", +"{ c #E2C686", +"] c #E2BE7E", +"^ c #CAAE76", +"/ c #E2C282", +"( c #CAA672", +"_ c #BA9E6A", +": c #BE9E6A", +"< c #BA9A66", +"[ c #8E764E", +"} c #CAA66E", +"| c #A2865A", +"1 c #A68A5A", +"2 c #FEDA96", +"3 c #AE9A6A", +"4 c #CEBE86", +"5 c #EAD692", +"6 c #E6D292", +"7 c #EAC282", +"8 c #FEDE96", +"9 c #FEE29A", +"0 c #EAC682", +"a c #9A8256", +"b c #DECE8A", +"c c #EADA96", +"d c #FEE69E", +"e c #FEDA92", +"f c #C2A26E", +"g c #A28A5E", +"h c #C2AE7A", +"i c #E2D292", +"j c #EEDE9E", +"k c #EADA9A", +"l c #FEEEA6", +"m c #FEEAA2", +"n c #9A825A", +"o c #BAA672", +"p c #D6C68E", +"q c #EEE29E", +"r c #EADE9E", +"s c #EADE9A", +"t c #EAD696", +"u c #EED28E", +"v c #DEC686", +"w c #FEF2A6", +"x c #FEF2AA", +"y c #FEEEA2", +"z c #FED692", +"A c #C2A66E", +"B c #D2BE86", +"C c #B29666", +"D c #FEEA9E", +"E c #FED68E", +"F c #86724E", +"G c #E2CE92", +"H c #BEAA72", +"I c #E6D692", +"J c #FEE296", +"K c #968256", +"L c #D6C286", +"M c #BEA26A", +"N c #BEA26E", +"O c #A28E62", +"P c #BEA672", +"Q c #B29A66", +"R c #FAEEA2", +"S c #FEF6AA", +"T c #FEE69A", +"U c #C29E6A", +"V c #EEE29A", +"W c #D2BE82", +"X c #C2AE76", +"Y c #CEB67E", +"Z c #F6EAA2", +"` c #9A865A", +" . c #EEDE9A", +".. c #A68E5E", +"+. c #C2A26A", +"@. c #D2BA82", +"#. c #B69E6A", +"$. c #B29E6E", +"%. c #D6BA7E", +"&. c #E2D692", +"*. c #C6AA72", +"=. c #DECA8A", +"-. c #C6B27E", +";. c #A69262", +">. c #DEC282", +",. c #F2E69E", +"'. c #7E6A46", +"). c #C6AE76", +"!. c #EECA86", +"~. c #B29A6A", +"{. c #AE9262", +"]. c #E2D28E", +"^. c #EACA86", +"/. c #C2A672", +"(. c #D2BA7E", +"_. c #9E8256", +":. c #F6DE96", +"<. c #DAC286", +"[. c #B29262", +"}. c #E6D28E", +"|. c #FAE69E", +"1. c #8A724E", +"2. c #BAA26E", +"3. c #AA9666", +" ", +" ", +" ", +" ", +" ", +" ", +" . + @ @ @ @ + # ", +" $ % % % % % % & ", +" * = % - - - % % % ; ", +" @ @ @ > = - - % % % - % - , ", +" @ @ @ @ @ ' - - - % % % % % % - % % ) ", +" ! ~ { ' ] - % % % - ^ % % % % % % ) ", +" # / ' % % % % % - - - % ^ - ( , ) _ : < [ ", +" @ & . . / ' % - ^ % - % % } | | | 1 1 | / 2 2 2 & ", +" 3 4 5 6 ! . . ] - % - - | | | | , , 7 8 8 9 8 8 8 8 0 a ", +" @ @ b c c 6 ! # . ' ( , | | , | 7 d 9 9 9 9 9 9 8 8 8 e e f ", +" @ g h i j k 5 ! ~ . | | { l m m m d m d d 9 9 9 8 8 8 8 e e f ", +" @ n o p q j r s t 6 u v . w x w m y m d m d d 9 d 9 8 9 8 e e z z A ", +" B j q j q q j s 6 ^ C . # y l y m m D d d d 9 9 9 8 8 8 2 e e E f ", +" F b q j q r j s G f H I w . # y m m D d d 9 9 9 9 J 8 8 8 e e E 7 f ", +" K h q r q q q L o , I w w w . . m y y D D d d d 9 8 8 8 8 e e e e e M N ", +" O r q j r P Q v R S w w l # l y y m D d d d T 9 9 9 8 8 2 2 e z z E U ", +" K p V q j W X S S S w w . . m D m m d d 9 9 9 9 9 8 8 8 e e E z z f ", +" o r j s Y , Z x x x y . # m d D d T d 9 9 8 8 8 e e e e z E E f ", +" ` q q .H ..I S w w l y y . # d D d 9 T J 9 8 8 8 e e z E E E 7 +. ", +" K 4 r r @.#.V S S w w l l D m d T T T 9 9 8 8 8 e 2 e E z E E : : ", +" $. .c %.1 Z w w w w y y D . D D D d d 9 9 8 8 8 2 8 e e e E z E E : ", +" & &.k *., =.S S y y y m m d d 9 9 9 8 9 9 8 8 e e z z z E E E f ", +" & -.k @.3 c w w w l l y # d T T 9 8 8 8 e e e e E E E E E E U ", +" ;.5 >.1 ,.w w l y y m . . d 9 9 9 9 8 2 8 2 z z z E ] U U U f ", +" '.).*.= L x w l y m D d D . ; 9 9 8 8 8 e e !.+.U f U U : ", +" ~.{.].w w w y y m D d T v 9 9 8 9 ^.f f A N f ", +" | = V w y l y m m D d T d u ^ A /.N P ", +" ) = (.l w y m y D d d 9 *.^ ", +" _.{.b l l y m m m :.v ", +" , 5 w y y y D 9 <./. ", +" [.[.(.w y m m }.(.P A ", +" @ ..Y l l |.).P ", +" 1.| b y 5 Y 2. ", +" 1.> #.3.g ", +" [ g ", +" ", +" ", +" "}; + +char * bigdocuments_xpm[] = { +"44 44 173 2", +" c None", +". c #746242", +"+ c #927A52", +"@ c #9292C6", +"# c #9292C2", +"$ c #927652", +"% c #929EFE", +"& c #928276", +"* c #A2A2E6", +"= c #B6BEFE", +"- c #AAB2FE", +"; c #B6AAC2", +"> c #DEBA7A", +", c #9E8258", +"' c #96A2FE", +") c #82767A", +"! c #929AE6", +"~ c #BAC2FE", +"{ c #BAC2EA", +"] c #D6DEFE", +"^ c #A2A6EA", +"/ c #C2AEB2", +"( c #826E4A", +"_ c #9AA2FE", +": c #DAE2FE", +"< c #9AA6FE", +"[ c #968A96", +"} c #C2CAFD", +"| c #D2DAFA", +"1 c #525A8E", +"2 c #5E669C", +"3 c #CAD2FE", +"4 c #9A9EF6", +"5 c #CAB2A2", +"6 c #A68A5E", +"7 c #C2CAF0", +"8 c #626EA2", +"9 c #7E86C8", +"0 c #9EA2EA", +"a c #C6CEFE", +"b c #AAB2DA", +"c c #464E86", +"d c #D2DAFE", +"e c #323A76", +"f c #7A82B2", +"g c #969EF2", +"h c #D2B28E", +"i c #BA9A66", +"j c #D6CEB6", +"k c #AEB2E0", +"l c #B2BEFE", +"m c #A6AEDA", +"n c #8A92BE", +"o c #727AAA", +"p c #1A2662", +"q c #AAB2F6", +"r c #A6AEFE", +"s c #CAD6FE", +"t c #626AA0", +"u c #AEB6E3", +"v c #929AC6", +"w c #B6BEEE", +"x c #B29668", +"y c #ECDE9C", +"z c #AAAEE6", +"A c #B2BAFE", +"B c #8E96C6", +"C c #161E5E", +"D c #B2BAE4", +"E c #828EE6", +"F c #AEB6FD", +"G c #C2CAF6", +"H c #9EA6D6", +"I c #767EB6", +"J c #2A3672", +"K c #3A467E", +"L c #6672AA", +"M c #CAA671", +"N c #AA8E5E", +"O c #BA9E6A", +"P c #BE9E6A", +"Q c #8E764E", +"R c #968256", +"S c #EEE29E", +"T c #6E7AB2", +"U c #BEC6F8", +"V c #6A72A8", +"W c #AEBAE6", +"X c #8A96F2", +"Y c #626AA6", +"Z c #C6CEFA", +"` c #A2865A", +" . c #E2C284", +".. c #FEDE96", +"+. c #FEDA92", +"@. c #967E56", +"#. c #CECABE", +"$. c #4E569A", +"%. c #727EC2", +"&. c #DEC282", +"*. c #FEE69A", +"=. c #FEE296", +"-. c #FEDA96", +";. c #EDCA86", +">. c #9A8256", +",. c #AAB6FE", +"'. c #868ECA", +"). c #4E5A96", +"!. c #A2AADA", +"~. c #121A5A", +"{. c #BAC6FE", +"]. c #DCC688", +"^. c #FEE69E", +"/. c #FEE29A", +"(. c #C29E6A", +"_. c #9292BA", +":. c #AEB6F6", +"<. c #B6C2FE", +"[. c #0A1656", +"}. c #222E6E", +"|. c #CAAA70", +"1. c #DCCA8A", +"2. c #FEEEA6", +"3. c #FEEA9E", +"4. c #FED692", +"5. c #BEA26D", +"6. c #968A8A", +"7. c #020E4E", +"8. c #A2AEEE", +"9. c #3A4286", +"0. c #7E8AC2", +"a. c #E6D692", +"b. c #FEF6AA", +"c. c #FEF2A6", +"d. c #FEEEA2", +"e. c #C2A66E", +"f. c #A2AEE6", +"g. c #A6B2FE", +"h. c #565EA2", +"i. c #FEEAA2", +"j. c #FED68E", +"k. c #C2A26E", +"l. c #969EFE", +"m. c #9AA2EA", +"n. c #2E3A7E", +"o. c #C8AE76", +"p. c #EAC282", +"q. c #A6AAEA", +"r. c #A2AEFE", +"s. c #C6BEBA", +"t. c #0A1256", +"u. c #DECE8A", +"v. c #F2DA96", +"w. c #9EAAFE", +"x. c #927E56", +"y. c #EADA96", +"z. c #7E6A46", +"A. c #E6D292", +"B. c #E6CE8E", +"C. c #C2A26A", +"D. c #E6CA8A", +"E. c #E2C686", +"F. c #E6C68A", +"G. c #E2BE82", +"H. c #EAC682", +"I. c #8A724E", +"J. c #EED28E", +"K. c #C2A672", +"L. c #BEA671", +"M. c #F2DE9A", +"N. c #C2AA72", +"O. c #9E865A", +"P. c #B29A66", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" . + @ # + + $ . ", +" % & * = - ; > > , ", +" % ' - % ) ! ~ { ] ^ / > > ( ", +" % _ = ] : < & [ _ } | 1 2 3 4 5 > 6 ", +" + + & # _ = ] 7 8 9 ~ 0 < a b c d e f } g h i ", +" + + + + + + + + j k _ l d m n o m p q r s t u 7 v { b w ~ * x ", +" ( y y y y y y j z < A 3 B b C 3 k D E F G H I J 3 K L D e M N x O P i Q ", +" R S S S S j z < A a T U 2 G V W 9 X F { H Y Z D M 6 6 ` 6 ` 6 .....+.@. ", +" @.y y #.z < A } } } $.L w V Z %.% = } J 6 6 6 6 6 ` &.*.=.=.....-.+.;.>. ", +" R #.z < ,.~ '.Y m ).!.~.{.9 F M ` ` ` 6 6 ].^.^.^././././.......-.-.(. ", +" _._ - :.= <.^ [.A }.|.` 6 6 6 6 1.2.2.3.3.3.3.^.*.^./.........+.+.4.5. ", +" 6.< r 7.8.9.0.6 ` 6 6 a.b.c.c.c.c.d.d.3.^.^.3.^././././...-...-.+.+.e.% ", +" R f.g.$.h.%.$.6 b.b.b.b.c.c.d.d.d.d.i.i.i.3.*.*.*././.......+.+.+.j.k.l. ", +" @.#.< m.n.,.o.6 b.b.c.c.c.c.c.d.i.i.3.3.^.^././././.........+.+.+.p.5. ", +" @.y q.r.^ 9 6 6 b.b.b.b.c.c.d.i.d.d.i.^.^./.^././...=...+.+.+.4.4.k.5. ", +" @.y s.< ! t.6 u.b.c.c.c.2.2.2.i.3.3.3.3.^./.*././.......+.+.+.j.j.(. ", +" @.y v.^ w.|.` b.b.b.c.c.2.d.d.d.i.3.^.*.^.*./.=.......+.-.+.j.4.j.k. ", +" x.y.a.s._ 6 6 c.c.c.c.c.d.d.i.3.^.3.^.*././...........+.+.4.j.j.j.k. ", +" z.a.A.B.^ 6 1.b.c.c.d.d.2.i.3.i.i.^.^./././././...+.+.+.4.+.j.j.p.C. ", +" , B.D.M 6 b.b.c.c.2.d.d.d.3.3.^.*.^.^././.......-.+.+.j.4.j.j.i k. ", +" + D.E.6 ` c.c.c.2.d.d.d.i.i.^.^.^.*./.........-.+.+.4.4.j.j.j.k. ", +" + F.E.6 u.c.c.c.c.d.i.3.3.3.^./././././...-...+.+.+.j.j.j.j.j.(. ", +" + E.M 6 c.c.2.d.d.i.i.i.^.^.*.^./.=./.......+.+.4.j.4.j.j.j.j.k. ", +" + .6 6 c.c.c.d.d.d.3.i.^.^.*.^./...........-.+.4.j.4.G.(.(.i k. ", +" $ G.6 A.c.d.d.i.d.3.3.^.3.^././././.=...+.+.;.(.C.k.(.(.(. ", +" Q M 6 c.c.2.2.i.i.i.3.^.*.^././.....H.k.k.k.5.5. ", +" I.6 ` 2.d.d.d.i.i.^.^.^.^./.J.|.K.K.L.L. ", +" I.6 1.c.d.d.d.3.3.v.e.e.K.e.o. ", +" I.6 d.d.d.M.e.N.N.e.L. ", +" I.` >.O.x P.5. ", +" ", +" ", +" ", +" ", +" ", +" ", +" "}; + +char * mini_folder_favorites_xpm[] = { +"20 16 36 1", +" c None", +". c #A68A5E", +"+ c #54452F", +"@ c #FEE89E", +"# c #FEE59B", +"$ c #FEE298", +"% c #FEDE95", +"& c #FEDB93", +"* c #CEAB75", +"= c #FEF6A9", +"- c #FEF2A7", +"; c #FEEFA4", +"> c #FEECA1", +", c #FEE99E", +"' c #FEE69C", +") c #FEE399", +"! c #FEDF96", +"~ c #FEDC93", +"{ c #FED991", +"] c #FED68E", +"^ c #FEF3A7", +"/ c #FEF0A4", +"( c #FEEDA2", +"_ c #FEE99F", +": c #FEE097", +"< c #FEDD94", +"[ c #FEDA91", +"} c #FED78E", +"| c #FEF0A5", +"1 c #FEEA9F", +"2 c #FEE79D", +"3 c #FF0000", +"4 c #FEEEA3", +"5 c #FEEAA0", +"6 c #FEEBA0", +"7 c #FEE299", +" ", +" .....+ ", +" .@#$%&.+ ", +" ......*******. ", +" .=-;>,')!~{]].+ ", +" .^/(_'):<[}]].+ ", +" .|(1233<33]]].+ ", +" .4523333333]].+ ", +" .6@#$33333]]].+ ", +" .@#7!~333]]]].+ ", +" .')!~{]3]]]]].+ ", +" .):<[}]]]]]]].+ ", +" ..............+ ", +" ++++++++++++++ ", +" ", +" "}; + +char * mini_desktop_xpm[] = { +"20 16 284 2", +" c None", +". c #666F7B", +"+ c #656D7A", +"@ c #676E7A", +"# c #676F7C", +"$ c #666F7C", +"% c #646B79", +"& c #626A77", +"* c #616876", +"= c #606875", +"- c #A0A9B9", +"; c #9DA9BD", +"> c #9FAABD", +", c #9EA9BD", +"' c #A0ABBD", +") c #9FA9BD", +"! c #9FAABE", +"~ c #9CA8BC", +"{ c #9BA6BB", +"] c #97A5BB", +"^ c #96A3BA", +"/ c #95A2B9", +"( c #949FB3", +"_ c #919FB6", +": c #909DB4", +"< c #999CA4", +"[ c #9FA7B6", +"} c #A5ADBE", +"| c #A7AFBF", +"1 c #A8B0C0", +"2 c #A7AFC0", +"3 c #A6ADBF", +"4 c #A5ACBD", +"5 c #A5ABBB", +"6 c #9BA4B3", +"7 c #8A8F94", +"8 c #878380", +"9 c #98928F", +"0 c #9A9BA0", +"a c #989B9F", +"b c #A3A3A7", +"c c #5E6163", +"d c #7E8487", +"e c #767B7C", +"f c #A3A9B5", +"g c #A8B0BF", +"h c #A9B1BF", +"i c #B8BCC5", +"j c #B3B7C2", +"k c #AEB4C2", +"l c #ACB2BE", +"m c #A3AAB8", +"n c #9097A3", +"o c #83817D", +"p c #9C9285", +"q c #9C8E7F", +"r c #C1B2A5", +"s c #A9A196", +"t c #827F7B", +"u c #636767", +"v c #393E41", +"w c #42433A", +"x c #8D6265", +"y c #6F6550", +"z c #696965", +"A c #696F6F", +"B c #858479", +"C c #C0BBB9", +"D c #D9D1CA", +"E c #B8B9BE", +"F c #A8AEBA", +"G c #687378", +"H c #757974", +"I c #B1A497", +"J c #9B8D7E", +"K c #C0B3A5", +"L c #A0988F", +"M c #767A7B", +"N c #59646C", +"O c #4D5251", +"P c #565450", +"Q c #283228", +"R c #522C2C", +"S c #544C38", +"T c #373C35", +"U c #5A5643", +"V c #6C624B", +"W c #A2988E", +"X c #A4A3A4", +"Y c #83888D", +"Z c #5A686E", +"` c #4E5856", +" . c #656862", +".. c #7F7A70", +"+. c #877E70", +"@. c #A99D8F", +"#. c #818689", +"$. c #485661", +"%. c #4C5355", +"&. c #545451", +"*. c #424240", +"=. c #454738", +"-. c #38442F", +";. c #203727", +">. c #25392C", +",. c #4F4D38", +"'. c #56503B", +"). c #6A6454", +"!. c #203A4B", +"~. c #203949", +"{. c #243840", +"]. c #203742", +"^. c #304044", +"/. c #444D4B", +"(. c #424A44", +"_. c #364242", +":. c #2A3A42", +"<. c #182A2F", +"[. c #333D3B", +"}. c #2F3833", +"|. c #262E2B", +"1. c #59544C", +"2. c #476A66", +"3. c #1B332C", +"4. c #183224", +"5. c #263A2A", +"6. c #444433", +"7. c #5A5741", +"8. c #3A443A", +"9. c #18313E", +"0. c #1D3643", +"a. c #102434", +"b. c #112431", +"c. c #152834", +"d. c #12252E", +"e. c #0E1F2C", +"f. c #0A1B2C", +"g. c #0C1A28", +"h. c #12242B", +"i. c #152727", +"j. c #1D2A25", +"k. c #333E3A", +"l. c #648EAB", +"m. c #2A4343", +"n. c #1D3627", +"o. c #253A29", +"p. c #4A5039", +"q. c #33412F", +"r. c #283C32", +"s. c #304442", +"t. c #25383F", +"u. c #1B2E35", +"v. c #1D2F35", +"w. c #1A2D35", +"x. c #172730", +"y. c #142430", +"z. c #14242D", +"A. c #14262D", +"B. c #152629", +"C. c #1E2928", +"D. c #474736", +"E. c #2D4233", +"F. c #1E3526", +"G. c #1D3425", +"H. c #283A28", +"I. c #36402C", +"J. c #655E3E", +"K. c #3D4531", +"L. c #233730", +"M. c #2F423C", +"N. c #192F33", +"O. c #152930", +"P. c #182A2C", +"Q. c #17292A", +"R. c #13212B", +"S. c #0F1F2B", +"T. c #11202A", +"U. c #162828", +"V. c #172727", +"W. c #1E2826", +"X. c #544B39", +"Y. c #363C2F", +"Z. c #223326", +"`. c #223426", +" + c #37412C", +".+ c #4B4830", +"++ c #655D3F", +"@+ c #404839", +"#+ c #2A3B3E", +"$+ c #273A3A", +"%+ c #1D2F33", +"&+ c #253534", +"*+ c #2D3C37", +"=+ c #2C3833", +"-+ c #2B3634", +";+ c #1E2C31", +">+ c #162429", +",+ c #23302A", +"'+ c #202D28", +")+ c #222B26", +"!+ c #4E4836", +"~+ c #8F646C", +"{+ c #454536", +"]+ c #2D3928", +"^+ c #504D34", +"/+ c #5F563A", +"(+ c #83755D", +"_+ c #757162", +":+ c #545A56", +"<+ c #3D4A48", +"[+ c #36423D", +"}+ c #4B4F42", +"|+ c #5B5C49", +"1+ c #625D46", +"2+ c #66604B", +"3+ c #49514F", +"4+ c #2C3A36", +"5+ c #3C4438", +"6+ c #3B4031", +"7+ c #32362C", +"8+ c #3F3934", +"9+ c #614D48", +"0+ c #554E38", +"a+ c #4C4E38", +"b+ c #615E49", +"c+ c #73684C", +"d+ c #A09281", +"e+ c #A59686", +"f+ c #818078", +"g+ c #6B6F6C", +"h+ c #52574B", +"i+ c #686653", +"j+ c #817664", +"k+ c #85765D", +"l+ c #9B8A75", +"m+ c #787467", +"n+ c #4E544D", +"o+ c #4B4E44", +"p+ c #524F3C", +"q+ c #434237", +"r+ c #5F5D4A", +"s+ c #636049", +"t+ c #6A6C5F", +"u+ c #6D6E62", +"v+ c #868074", +"w+ c #9F968D", +"x+ c #ACA399", +"y+ c #908E89", +"z+ c #838684", +"A+ c #696E6A", +"B+ c #717267", +"C+ c #8C816C", +"D+ c #8F7F65", +"E+ c #A7947C", +"F+ c #918573", +"G+ c #776E60", +"H+ c #575952", +"I+ c #4F4F42", +"J+ c #8D578E", +"K+ c #8C7E8F", +"L+ c #87BC7E", +"M+ c #8B9989", +"N+ c #907F80", +"O+ c #907176", +"P+ c #818282", +"Q+ c #757777", +"R+ c #717272", +"S+ c #72706D", +"T+ c #74716C", +"U+ c #77736E", +"V+ c #76716C", +"W+ c #7E7A74", +"X+ c #7A7773", +"Y+ c #696A68", +"Z+ c #635C63", +"`+ c #5E8B5B", +" @ c #616C62", +".@ c #5D4348", +"+@ c #5C3E44", +"@@ c #554A4C", +"#@ c #555555", +"$@ c #585858", +"%@ c #535353", +"&@ c #525252", +"+ + . . + @ # $ $ + + + % & * = + + ", +"+ - ; > , ' > ) ! ~ { ] ^ / ( _ : + ", +" < [ } | 1 2 | | 3 4 5 6 7 8 9 0 a b ", +"c d e f g h i j k l m n o p q r s t u v ", +"w x y z A B C D E F G H I J K L M N O P ", +"Q R S T U V W X Y Z ` ...+.@.#.$.%.&.*.", +"=.-.;.>.,.'.).!.~.{.].^./.(._.:.<.[.}.|.", +"1.2.3.4.5.6.7.8.9.0.a.b.c.d.e.f.g.h.i.j.", +"k.l.m.n.o.5.p.q.r.s.t.u.v.w.x.y.z.A.B.C.", +"D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.", +"X.Y.Z.`. +.+++@+#+$+%+&+*+=+-+;+>+,+'+)+", +"!+~+{+]+^+/+(+_+:+<+[+}+|+1+2+3+4+5+6+7+", +"8+9+0+a+b+c+d+e+f+g+h+i+j+k+l+m+n+o+p+q+", +" r+s+t+u+v+w+x+y+z+A+B+C+D+E+F+G+H+I+ ", +"+ J+K+L+M+N+O+P+Q+R+S+T+U+V+W+X+Y+ + ", +"+ + Z+`+ @.@+@@@#@$@%@#@$@%@&@&@ + + "}; + +char * my_computer_xpm[] = { +"44 32 101 2", +" c None", +". c #1C2028", +"+ c #292F3A", +"@ c #2F3643", +"# c #232830", +"$ c #12141A", +"% c #080A0B", +"& c #030304", +"* c #0C0E12", +"= c #6A7A9F", +"- c #6E7EA3", +"; c #65789C", +"> c #7083A8", +", c #7286B2", +"' c #627293", +") c #55617D", +"! c #495469", +"~ c #394150", +"{ c #3F4AA7", +"] c #565EBA", +"^ c #515DA2", +"/ c #5562A1", +"( c #5A6987", +"_ c #7E90B0", +": c #8696B1", +"< c #768AB6", +"[ c #525C6B", +"} c #8A96A3", +"| c #9EACBD", +"1 c #8E9EB5", +"2 c #5E6774", +"3 c #171A1E", +"4 c #6674F5", +"5 c #7786FA", +"6 c #8291FC", +"7 c #7785F6", +"8 c #5662E6", +"9 c #4A56E2", +"0 c #3A46E5", +"a c #2530B5", +"b c #2830A4", +"c c #2A369E", +"d c #3A469A", +"e c #444C59", +"f c #A6B4C1", +"g c #ADBCC9", +"h c #93A1B5", +"i c #8390A2", +"j c #8B9AB2", +"k c #323A49", +"l c #6272A8", +"m c #6F7EEE", +"n c #92A1FE", +"o c #6472E8", +"p c #424EEF", +"q c #3642F4", +"r c #1F2AE7", +"s c #111AE7", +"t c #0202DA", +"u c #3E49B1", +"v c #798AAC", +"w c #4B535C", +"x c #5F6E8A", +"y c #77859C", +"z c #667385", +"A c #4A56EE", +"B c #2732EA", +"C c #161EE6", +"D c #020ADA", +"E c #4A55AF", +"F c #778392", +"G c #646E78", +"H c #535FF0", +"I c #030CE5", +"J c #6A7890", +"K c #6E7A89", +"L c #7786A8", +"M c #98A6B8", +"N c #3F4655", +"O c #6C7CF6", +"P c #606CF1", +"Q c #323EEA", +"R c #0912E3", +"S c #727E90", +"T c #7C8A9B", +"U c #5E6AAD", +"V c #0B13D3", +"W c #586270", +"X c #8F9BA6", +"Y c #1B25E7", +"Z c #101AB8", +"` c #434E65", +" . c #1A22B2", +".. c #4E5D79", +"+. c #141ECA", +"@. c #5E6E96", +"#. c #4652A2", +"$. c #2E3AC2", +"%. c #6E7A96", +"&. c #B6C6D2", +"*. c #727A85", +" . + + @ + # . $ $ % & ", +" * = = - - ; - > , > - ' ) ! ~ + . % + @ + # . ", +" . ' { ] ^ ^ ^ ^ / ) ( ; , _ : < < ~ . $ # [ } | | | | 1 2 3 ", +" + ( 4 5 6 6 7 4 8 9 0 a b c d ' _ e - _ [ # . [ } f g f g g h } i j e ", +" k l m 6 n n 6 7 o 8 p q r s t u v w j h | x . . 2 } h | g f y [ z : j | w ", +" ~ ; m 6 n n 6 7 4 8 A q B C D E F 2 f f i ~ ( x [ [ e w G w e y h 1 h | e ", +" e l m 6 n n 6 5 4 H p q B C I / J K g f w J L v > ; > L # + | M M M | f N ", +" ! l 4 5 6 6 5 O P H p Q r s R l G S f S N : i y T _ i > # z | M | | f f ~ ", +" [ U P O O m 4 P 8 A 0 B r V V - [ S h [ W 1 M j y S J G + i f | f f g f @ ", +" [ ^ H 8 P P P 8 A p Q B C R V v w = < e G } } } M h } 2 ~ X f f f f | | # ", +" [ { A A H H A A 0 q B Y s R Z i ` - ' e X | f M | h h [ e M f f | | | h 3 ", +" z { Q p p p 0 0 Q B r s R I .i ` - ) e h i i X | X h e [ h | M M h h } * ", +" z d r Q Q Q Q B r Y s R V I a } ` , ..w } X X X T X T w 2 X M h h 1 1 T ", +" , c C Y Y r Y Y C V R R R I d X ` < ! G j T y T F i z [ 2 } 1 j : : : J ", +" y ^ r +.V R R R R R R R R t E X ! < ! x _ T i _ y } [ 2 2 _ j : _ _ _ ) ", +" ) 1 : L @.#.$.+.V D D I I D l } ..< ` @.' ) ( %.F i e z W _ _ v < , < ! ", +" % e : M M M M 1 v / { a Z Z v T .., ! ' > > - - ; > k F w > < > > > < N ", +" $ ..L 1 | | f g f | M } f S ) < ! ' - @.( = ( ; ~ T ` = > > - - , k ", +" % e w + $ & . ! x y X f g g &.&.&.F ) ; k ; > > = - ( l @ i w ; - - - > , @ ", +" 3 *.L G S *.[ ~ . * k z 2 [ 2 2 G *.z W + * & $ ; > ; @.; ( ; ~ i ..; > > = - < + ", +" $ S S ( ' > = > K K W ~ @ ~ ~ k # & $ ; > - > , ( @.k : [ ; - > > , N ", +"% G - ( S i y T y > > > J z 2 N # * * - > - - > ( @.k j ..l > , ; k ", +"~ S 2 ; _ _ y 1 K j i S : > ; ' @.( ! @ . % ; > - - > @.' ~ 1 ! ; > ..3 ", +"+ F } y K ( x F i : i 1 j K J J - = @.( ( ) ~ & ..> , , > ; ; k M ! ..@ & ", +" # 2 i } S ; ' ; - _ T y F T 1 S ; = = e N . & 3 k ..l > ; ~ : # & ", +" @ G y _ z 2 ( ' _ : j 1 T i > ` ~ ..% # ~ 3 & 3 + $ $ ", +" * ~ G , S ( [ ( J z J ' e k w $ w f | ) ~ k + $ ", +" $ e @.= @.! ..( N . . . y f g J F > ( - > ; + ", +" . ! l > ! $ % ~ j | | f W ( @.` ; , ( $ ", +" % + * & % e J h g g h G ( ( , ' $ ", +" 3 e *.} h 1 _ @.3 ", +" % # ~ ` $ "}; diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/flu_pixmaps.cpp b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/flu_pixmaps.cpp new file mode 100644 index 0000000..c9dc810 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/flu_pixmaps.cpp @@ -0,0 +1,1629 @@ +// $Id: flu_pixmaps.cpp,v 1.10 2003/12/06 16:52:43 jbryan Exp $ + +/*************************************************************** + * FLU - FLTK Utility Widgets + * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University + * + * This file and its content is protected by a software license. + * You should have received a copy of this license with this file. + * If not, please contact the Ohio Supercomputer Center immediately: + * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212 + * + ***************************************************************/ + + + +#include "FLU/flu_pixmaps.h" + +/* XPM */ +char * plus_xpm[] = { +"15 15 4 1", +" c None", +". c #444444", +"+ c #FFFFFF", +"@ c #000000", +" ", +" ", +" ........... ", +" .+++++++++. ", +" .++++@++++. ", +" .++++@++++. ", +" .++++@++++. ", +" .+@@@@@@@+. ", +" .++++@++++. ", +" .++++@++++. ", +" .++++@++++. ", +" .+++++++++. ", +" ........... ", +" ", +" "}; + +/* XPM */ +char * minus_xpm[] = { +"15 15 4 1", +" c None", +". c #444444", +"+ c #FFFFFF", +"@ c #000000", +" ", +" ", +" ........... ", +" .+++++++++. ", +" .+++++++++. ", +" .+++++++++. ", +" .+++++++++. ", +" .+@@@@@@@+. ", +" .+++++++++. ", +" .+++++++++. ", +" .+++++++++. ", +" .+++++++++. ", +" ........... ", +" ", +" "}; + +/* XPM */ +char * folder_save_xpm[] = { +"20 20 180 2", +" c None", +". c #000000", +"+ c #FFFFFF", +"@ c #FFF5F6", +"# c #FFF6F7", +"$ c #FFEBEE", +"% c #FFF1F3", +"& c #FFA4B5", +"* c #FFB3C1", +"= c #FFB4C1", +"- c #FFB8C5", +"; c #FFB9C6", +"> c #FFBCC8", +", c #FFBDC9", +"' c #FFBECA", +") c #FFC2CD", +"! c #FFC4CE", +"~ c #FFC4CF", +"{ c #FFC6D0", +"] c #FFC8D2", +"^ c #FFCED7", +"/ c #FFD1D9", +"( c #FFD7DE", +"_ c #FFDCE2", +": c #FFE4E9", +"< c #FFE9ED", +"[ c #FFEDF0", +"} c #FFEEF1", +"| c #FFF9FA", +"1 c #FF9AAD", +"2 c #FF9FB2", +"3 c #FFA1B3", +"4 c #FFA6B7", +"5 c #FFA7B8", +"6 c #FFA8B9", +"7 c #FFABBB", +"8 c #FFACBC", +"9 c #FFADBD", +"0 c #FFAFBE", +"a c #FFB1C0", +"b c #FFB5C3", +"c c #FFB5C4", +"d c #FFB7C5", +"e c #FFBBC8", +"f c #FFBFCB", +"g c #FFC1CD", +"h c #FFC5D0", +"i c #FFC7D2", +"j c #FFC8D3", +"k c #FFC9D4", +"l c #FFCAD4", +"m c #FFCCD6", +"n c #FFCED8", +"o c #FFD2DB", +"p c #FFD4DD", +"q c #FFD5DD", +"r c #FFD7DF", +"s c #FFD9E1", +"t c #FFDAE1", +"u c #FFDBE2", +"v c #FFDDE4", +"w c #FFE0E6", +"x c #FFE1E7", +"y c #FFE2E8", +"z c #FFE6EB", +"A c #FFE7EC", +"B c #FFEFF2", +"C c #FFCBD6", +"D c #FFD0DA", +"E c #FFD5DE", +"F c #FFDEE5", +"G c #FFE8ED", +"H c #FFF2F5", +"I c #FFEAEF", +"J c #C3C2C3", +"K c #C1C0C1", +"L c #979697", +"M c #2106C3", +"N c #2207C3", +"O c #270CC5", +"P c #2B11C6", +"Q c #3118C7", +"R c #3720C9", +"S c #3D26CC", +"T c #3D26CB", +"U c #3F28CB", +"V c #442DCD", +"W c #452ECE", +"X c #432ECD", +"Y c #452FCD", +"Z c #4630CD", +"` c #4A35CF", +" . c #4A35CE", +".. c #4B36CF", +"+. c #4C37D0", +"@. c #4C38D0", +"#. c #4E39D0", +"$. c #513CD1", +"%. c #513DD1", +"&. c #523ED1", +"*. c #533FD1", +"=. c #5440D2", +"-. c #5642D2", +";. c #5744D2", +">. c #5845D3", +",. c #5B48D4", +"'. c #5A47D3", +"). c #5D4AD4", +"!. c #5E4CD5", +"~. c #604ED5", +"{. c #6150D6", +"]. c #6351D6", +"^. c #6452D7", +"/. c #6452D6", +"(. c #6553D6", +"_. c #6756D7", +":. c #6958D8", +"<. c #6A59D8", +"[. c #6A5AD8", +"}. c #6F5EDA", +"|. c #7667DC", +"1. c #7566DB", +"2. c #7B6CDD", +"3. c #7E70DE", +"4. c #7F71DE", +"5. c #877AE1", +"6. c #887BE0", +"7. c #6858D8", +"8. c #6F60DA", +"9. c #7061DA", +"0. c #7668DB", +"a. c #7769DC", +"b. c #7C6FDE", +"c. c #8174DF", +"d. c #8276DF", +"e. c #8578E0", +"f. c #897DE1", +"g. c #8D82E2", +"h. c #8F84E3", +"i. c #8E83E2", +"j. c #9489E4", +"k. c #958BE5", +"l. c #9B92E7", +"m. c #9C93E7", +"n. c #B1AAED", +"o. c #A19AE8", +"p. c #A7A0EA", +"q. c #ADA6EB", +"r. c #B2ACED", +"s. c #7D7D7E", +"t. c #787979", +"u. c #B6B7B7", +"v. c #ACADAD", +"w. c #8C8D8D", +"x. c #767776", +"y. c #8F908F", +"z. c #B9B9B8", +"A. c #ADADAC", +"B. c #6C6B6B", +"C. c #B7B6B6", +"D. c #9E9D9D", +"E. c #C5C5C5", +"F. c #C2C2C2", +"G. c #AAAAAA", +"H. c #A2A2A2", +"I. c #A0A0A0", +"J. c #999999", +"K. c #949494", +"L. c #919191", +"M. c #8A8A8A", +"N. c #888888", +"O. c #858585", +"P. c #828282", +"Q. c #808080", +"R. c #7B7B7B", +"S. c #747474", +"T. c #727272", +"U. c #6E6E6E", +"V. c #6C6C6C", +"W. c #6A6A6A", +" ", +" . . . . . . . . . . . . . . . . . . ", +" . r.. 1 3 5 0 b e g i ^ p u x . F.. ", +" . r.. 2 T.T.T.T.T.T.T.T.T.T.z . . . ", +" . r.. & 7 a d , ! k D ( v : $ . [.. ", +" . r.. 6 T.T.T.T.T.n q _ y G } . ^.. ", +" . n.. 9 = ; f { m o s w A [ H . ).. ", +" . q.. a T.T.~ l T.T.T.T.T.% # . -.. ", +" . p.. c > g j n E _ y < B @ | . #.. ", +" . o.m.. . . . . . . . . . . . @.Z . ", +" . l.k.h.f.d.b.|.8.[.(.!.>.&...Y U . ", +" . j.i.6.c.2.1.}.:./.).;.$.` X S R . ", +" . g.5.. . . . . . . . . . . . . Q . ", +" . e.4.. E.E._.{.,.C.v.H.J.y.O.. P . ", +" . 3.a.. E.E.~.'.=.G.I.L w.P.t.. O . ", +" . 0.9.. E.J >.*.+.D.K.M.Q.x.U.. N . ", +" . 8.<.. K z.%...W L.N.s.S.V.W.. M . ", +" . 7.].. u.A. .V T O.R.T.B.W.W.. M . ", +" . . . . . . . . . . . . . . . . . ", +" "}; + +/* XPM */ +char * folder_load_xpm[] = { +"20 20 42 1", +" c None", +". c #000000", +"+ c #FFF1A5", +"@ c #FFEEA3", +"# c #FFECA1", +"$ c #FFE99F", +"% c #FFE79D", +"& c #FFE49B", +"* c #FFE299", +"= c #FFE097", +"- c #FFDD95", +"; c #FFDB93", +"> c #FFD891", +", c #FFD68F", +"' c #FFD48E", +") c #B59B69", +"! c #B59E6C", +"~ c #B5A26E", +"{ c #B5A571", +"] c #B5A974", +"^ c #B5AA75", +"/ c #B59665", +"( c #B59A68", +"_ c #B59D6B", +": c #B5A16D", +"< c #B5A470", +"[ c #B5A773", +"} c #B59867", +"| c #B59C69", +"1 c #B59F6C", +"2 c #B5A36F", +"3 c #B5A672", +"4 c #B59766", +"5 c #B59E6B", +"6 c #B5A16E", +"7 c #B5A873", +"8 c #B59967", +"9 c #B59C6A", +"0 c #B5A06D", +"a c #B5A370", +"b c #B5A772", +"c c #B59866", +" ", +" .... ", +" . . . ", +" . ... ", +" .... ... ", +".+@#$. .... ", +".@#$%. ", +".#$%&*........ ", +".$%&*=-;>,'''. ", +".%&*=-;>,''''. ", +".&*=-;>.............", +".*=-;>.)!~{]^^^^^^^.", +".=-;>./(_:<[^^^^^^. ", +".-;>.//}|123^^^^^. ", +".;>.///4(56{7^^^. ", +".>./////890ab^^. ", +"..//////c)!~{]. ", +".............. ", +" ", +" "}; + +/* XPM */ +char * reload_xpm[] = { +"20 20 41 1", +" c None", +". c #777777", +"+ c #000000", +"@ c #3439AC", +"# c #1C23A3", +"$ c #080F9A", +"% c #5257B8", +"& c #3A40AF", +"* c #2329A5", +"= c #0C139C", +"- c #585DBB", +"; c #4146B1", +"> c #2A30A8", +", c #5F63BE", +"' c #484DB4", +") c #3036AB", +"! c #666AC0", +"~ c #4E53B7", +"{ c #373DAD", +"] c #555ABA", +"^ c #3E43B0", +"/ c #262DA7", +"( c #5C60BC", +"_ c #444AB3", +": c #2D33A9", +"< c #5E5E5E", +"[ c #4B50B6", +"} c #676767", +"| c #646464", +"1 c #6D6D6D", +"2 c #767676", +"3 c #12199F", +"4 c #616161", +"5 c #6A6A6A", +"6 c #737373", +"7 c #7C7C7C", +"8 c #1920A1", +"9 c #707070", +"0 c #797979", +"a c #808080", +"b c #838383", +" .++++++. ", +" .++@#$$$$++. ", +" .+%&*=++++$$+. ", +" .+-;>++. .++$+.", +" .+,')+. .+++", +" +!~{+. .+", +" .+]^/+ .+. ", +" +(_:+. .+<+. ", +" .+[@#+ .+<<}+. ", +"++%&*=$++ .+<<|12+.", +".+;>3$$+. ++<4567++", +" .+8$$+. +}90+. ", +" .+$+. .+12a+ ", +" .+. +567+. ", +"+. .+90b+ ", +"+++. .+12a+. ", +".+<++. .++567+. ", +" .+<<++++<}90+. ", +" .++<<<<|1++. ", +" .++++++. "}; + +/* XPM */ +char * home_xpm[] = { +"20 20 46 1", +" c None", +". c #000000", +"+ c #1C2F54", +"@ c #4162AD", +"# c #872525", +"$ c #894226", +"% c #875B25", +"& c #DDDA30", +"* c #4665B0", +"= c #6279BF", +"- c #4A68B2", +"; c #697EC3", +"> c #4363AE", +", c #4C69B3", +"' c #556FB8", +") c #5D76BC", +"! c #667CC1", +"~ c #6E81C6", +"{ c #7687CA", +"] c #7989CC", +"^ c #4C6AB3", +"/ c #5570B8", +"( c #5E76BD", +"_ c #677DC2", +": c #7083C7", +"< c #828FD0", +"[ c #F43333", +"} c #ED3030", +"| c #E62E2E", +"1 c #3E60AB", +"2 c #E02C2C", +"3 c #D92A2A", +"4 c #3A5DA9", +"5 c #5A73BB", +"6 c #D22828", +"7 c #CC2626", +"8 c #3559A6", +"9 c #526EB6", +"0 c #C52424", +"a c #BF2222", +"b c #3055A3", +"c c #365AA7", +"d c #3C5EAA", +"e c #4262AD", +"f c #B82020", +"g c #B11D1D", +" ", +" . ", +" .+. .... ", +" .+@+..#$. ", +" .%%%%%.$#. ", +" .%&&%&&%.$. ", +" .+%&&%&&%+.. ", +" .+*%&&%&&%=+. . ", +" .+@-%%%%%%%;=+.+. ", +". .>,')!~{]{~!.+,+. ", +" .>^/(_:]<]:.+/^>+.", +" .>%%%%~{]{~%%%%>. ", +" .@%&&%;[}|;%&&%@. ", +" .1%&&%=|23=%&&%1. ", +" .4%&&%53675%&&%4. ", +" .8%%%%970a9%%%%8. ", +" .bcde*-afg-*edcb. ", +" ................. ", +" ", +" "}; + +/* XPM */ +char * trash_xpm[] = { +"20 20 8 1", +" c None", +". c #000000", +"+ c #B7B7B7", +"@ c #D3D3D3", +"# c #3F3F3F", +"$ c #8E8E8E", +"% c #FFFFFF", +"& c #666666", +" ", +" ........ ", +" ..+@####+$.. ", +" ..$@%#@@@@#@+$.. ", +" .#+@%%%@@@@@+$#. ", +" .+###%%%%@@###&. ", +" .+@%######+$&. ", +" .###@@@@$+###. ", +" .+@%######$&&. ", +" .+@%+@@$++$&&. ", +" .+@%+@@$++$&&. ", +" .+@%+@@$++$&&. ", +" .+@%+@@$++$&&. ", +" .+@%+@@$++$&&. ", +" .+@%+@@$++$&&. ", +" .+@%+@@$++$&&. ", +" .+@%+@@$++$&&. ", +" .+@%+@@$++$&&. ", +" ..%+@@$++$.. ", +" ........ "}; + +/* XPM */ +char * arrow_closed_xpm[] = { +"15 15 3 1", +" c None", +". c #FFFFFF", +"+ c #000000", +" ", +" ", +" ", +" ++ ", +" ++++ ", +" ++++++ ", +" ++++++++ ", +" +++++++++ ", +" ++++++++ ", +" ++++++ ", +" ++++ ", +" ++ ", +" ", +" ", +" "}; + +/* XPM */ +char * arrow_open_xpm[] = { +"15 15 3 1", +" c None", +". c #FFFFFF", +"+ c #000000", +" ", +" ", +" ", +" +++++++++ ", +" +++++++++ ", +" +++++++ ", +" +++++++ ", +" +++++ ", +" +++++ ", +" +++ ", +" +++ ", +" + ", +" ", +" ", +" "}; + +/* XPM */ +char * bluedot_xpm[] = { +"13 13 9 1", +" c None", +". c #D4D4FF", +"+ c #6363FF", +"@ c #1A1AFF", +"# c #0000FF", +"$ c #A8A8FF", +"% c #6060FF", +"& c #EAEAFF", +"* c #FFFFFF", +" ", +" .+@#@+. ", +" $#######$ ", +" .#%&&%####. ", +" +#&**&####+ ", +" @#&**&####@ ", +" ##%&&%##### ", +" @#########@ ", +" +#########+ ", +" .#########. ", +" $#######$ ", +" .+@#@+. ", +" "}; + +/* XPM */ +char * book_xpm[] = { +"18 18 15 1", +" c None", +". c #840084", +"+ c #000000", +"@ c #FF9CFF", +"# c #CE00CE", +"$ c #630063", +"% c #9C009C", +"& c #636363", +"* c #9C9C9C", +"= c #848484", +"- c #C6C6C6", +"; c #ADAD94", +"> c #E7E7D6", +", c #D60094", +"' c #CE63CE", +" ", +" .+ ", +" .@#$+ ", +" .@###%$+ ", +" .@#####..$+ ", +" .@#######..++ ", +" .@########.+. ", +" .@########.+&. ", +" .@########%+&*.+ ", +" ...######%+&*=.+ ", +" .*-..###%+&*;.+ ", +" .*>-;..%+=*-.+ ", +" .,'>>--.*;-.+ ", +" $$,'>>>--.+ ", +" $$,'>-.+ ", +" $$,.+ ", +" $+ ", +" "}; + +/* XPM */ +char * cd_drive_xpm[] = { +"18 16 29 1", +" c None", +". c #737373", +"+ c #9CCE9C", +"@ c #CECE63", +"# c #C6C6C6", +"$ c #319C9C", +"% c #63CE9C", +"& c #B5B5B5", +"* c #313131", +"= c #CECE9C", +"- c #DEDEDE", +"; c #848484", +"> c #319CCE", +", c #639CCE", +"' c #63CECE", +") c #D6D6D6", +"! c #949494", +"~ c #A5A5A5", +"{ c #639C9C", +"] c #000000", +"^ c #CECECE", +"/ c #F7F7F7", +"( c #E7E7E7", +"_ c #EFEFEF", +": c #FFFFFF", +"< c #CEFFFF", +"[ c #009CCE", +"} c #00FF00", +"| c #008400", +" ... ", +" ..+@#.. ", +" .$%+@&##* ", +" .%%$%=#&-&* ", +" ;>,%';&)#&* ", +" .!~{';];~&^^* ", +" .&&^;]/];^^^* ", +" .(/(&;];&_/^* ", +" ;;;;~&~~;$-(:* ", +" ;:::.~~&)=%><&* ", +" ;:###.~&^=+[[] ", +" ;:****;;^=+**] ", +" ;:}|::##***#.] ", +" .;;;;;;;;;;;;] ", +" ]]]]]]]]]]]] ", +" "}; + +/* XPM */ +char * computer_xpm[] = { +"20 20 47 1", +" c None", +". c #FFFFFF", +"+ c #848484", +"@ c #9C9CCE", +"# c #9C9C63", +"$ c #63639C", +"% c #393939", +"& c #FFFFCE", +"* c #FFFFF7", +"= c #CECEFF", +"- c #424242", +"; c #F7F7F7", +"> c #6363CE", +", c #000031", +"' c #003163", +") c #CEEFFF", +"! c #4A4A4A", +"~ c #9CCEFF", +"{ c #63FFFF", +"] c #9CFFFF", +"^ c #63CEFF", +"/ c #319CFF", +"( c #0063FF", +"_ c #B5B5B5", +": c #31CEFF", +"< c #3163CE", +"[ c #639CCE", +"} c #CEFFFF", +"| c #009CFF", +"1 c #313100", +"2 c #292929", +"3 c #ADAD94", +"4 c #DEDEDE", +"5 c #101010", +"6 c #CE9C9C", +"7 c #080808", +"8 c #000000", +"9 c #EFD6C6", +"0 c #CE9CCE", +"a c #636363", +"b c #633131", +"c c #636331", +"d c #848400", +"e c #C6C6C6", +"f c #EFEFEF", +"g c #E7E7D6", +"h c #212121", +" ", +" ", +" +@@@@@@@@@@#$ ", +" %&...&&&&&**.=- ", +" %=;&@>,,,,,,')! ", +" %~=;>{]]]^^/({- ", +" %_=*>]]]{]::<]- ", +" %=_*[{]]{{::<}- ", +" %__.[^]{{^^|<.- ", +" %_=./:::::/|(.- ", +" 11_&^<<<<<<<<.2 ", +" 113=4&&&&&&4@5 ", +" 167888888888752 ", +" 1%90ab%c33b5%a ", +" 1$de9=9f=&3g3=3a ", +" 1$$%=9=ggg=@dd=h ", +" 1$h9=9=&=&=9=9h ", +" chhhhhhhhhhhhh ", +" ", +" "}; + +/* XPM */ +char * ram_drive_xpm[] = { +"18 16 14 1", +" c None", +". c #444444", +"+ c #2D2D2D", +"@ c #000000", +"# c #FFFFFF", +"$ c #737373", +"% c #B5B5B5", +"& c #1C1C1C", +"* c #DEDEDE", +"= c #C6C6C6", +"- c #949494", +"; c #D6D6D6", +"> c #00CE00", +", c #008400", +" ", +" .+++++ ", +" @ +....@ @", +" @@+.#..@@@ ", +" @ +..#.@ @", +" @@+....@@@ ", +" @ +.##.@ @", +" $$$$@@+....@@@ ", +" $%%%@%%+.#..@& @", +" $#####@@+....@@@ ", +" $*%====%@@@@@@& ", +" $*$$$$$$$$$%-$& ", +" $;>,#######%-$& ", +" $$$$$$$$$$$$$& ", +" &&&&&&&&&&&& ", +" "}; + +/* XPM */ +char * network_drive_xpm[] = { +"18 16 15 1", +" c None", +". c #A80525", +"+ c #42000E", +"@ c #1A29A8", +"# c #737373", +"$ c #B5B5B5", +"% c #000000", +"& c #FFFFFF", +"* c #9C9C9C", +"= c #DEDEDE", +"- c #C6C6C6", +"; c #949494", +"> c #D6D6D6", +", c #00CE00", +"' c #008400", +" ", +" .. .. .. .. ", +" ..+ ..+ ..+ ..+ ", +" ..+ ..+ ..+ ..+ ", +" @+ @+ @+ @+ ", +" @@@@@@@@@@@@@@ ", +" @ ", +" ############ ", +" #$$$$$$$$$$$#% ", +" #&&&&&&&&&&&*#% ", +" #=$----$$$$$;#% ", +" #=#########$;#% ", +" #>,'&&&&&&&$;#% ", +" #############% ", +" %%%%%%%%%%%% ", +" "}; + +/* XPM */ +char * floppy_drive_xpm[] = { +"18 16 12 1", +" c None", +". c #858585", +"+ c #737373", +"@ c #9CFFFF", +"# c #000000", +"$ c #FFFFFF", +"% c #CEFDFD", +"& c #CECECE", +"* c #C5C5C5", +"= c #B5B5B5", +"- c #F40000", +"; c #808080", +" ", +" ...... ", +" +@@@@@@# ", +" +$$$$$## ", +" +$$$%%%# ", +" +%%%%%%# ", +" +&*&=*=# ", +" ......+*....*# ", +" .******+&+#+$=# ", +" .$$$$$$$$###### ", +" .*********-*.+# ", +" .***....&***.+# ", +" ;*;.####;.;*;+# ", +" .***$$$$****.+# ", +" ..;...;...;..# ", +" ############ "}; + +/* XPM */ +char * removable_drive_xpm[] = { +"20 12 12 1", +" c None", +". c #858585", +"+ c #B5B5B5", +"@ c #626262", +"# c #000000", +"$ c #FFFFFF", +"% c #808080", +"& c #E7E7D6", +"* c #C5C5C5", +"= c #F40000", +"- c #7B0006", +"; c #CECECE", +" ", +" ............. ", +" .++++++++++++@# ", +" .$$$$$$$$$$$$.@# ", +" %$+&*+*+*+*+*.@# ", +" %.$=-@######@*.@# ", +" .$&+$######$*.@# ", +" .$+&+$$$$$$*;.@# ", +" %$&+***++++++.@# ", +" .$............# ", +" ############# ", +" "}; + +/* XPM */ +char * disk_drive_xpm[] = { +"20 12 12 1", +" c None", +". c #737373", +"+ c #B5B5B5", +"@ c #000000", +"# c #FFFFFF", +"$ c #9C9C9C", +"% c #D6D6D6", +"& c #C6C6C6", +"* c #949494", +"= c #DEDEDE", +"- c #00CE00", +"; c #008400", +" ", +" ", +" ............. ", +" .++++++++++++.@ ", +" .############$.@ ", +" .%&&&&&&&++++*.@ ", +" .=+&&&&&+++++*.@ ", +" .=..........+*.@ ", +" .%-;########+*.@ ", +" ..............@ ", +" @@@@@@@@@@@@@ ", +" "}; + +/* XPM */ +char * filled_folder_xpm[] = { +"18 18 18 1", +" c None", +". c #63639C", +"+ c #CEFFFF", +"@ c #000000", +"# c #848400", +"$ c #FFFFFF", +"% c #CECEFF", +"& c #CECE63", +"* c #319CFF", +"= c #0063FF", +"- c #9CFFFF", +"; c #9C9C00", +"> c #3131CE", +", c #313100", +"' c #31009C", +") c #9C9CFF", +"! c #FFFF9C", +"~ c #FFCE9C", +" ", +" . ", +" .+@ ", +" ###.+$%@ ", +" #&&.+$*+%@ ", +" #&&.+$=-$+%@;; ", +" #&.+$>-$>$+%@&, ", +" #.+%')%')%%%%@, ", +" ;;;;;;;;;;;;)+%@ ", +" ;$!!!!!!~!~&,%%@ ", +" ;$!!!!~!!~!&,)@, ", +" ;$!!!!!~!~~;,;, ", +" ;$!!~!~!~~~&,;, ", +" ;$~!~!~~~~&;,, ", +" ;;;;;;;;;;;;,, ", +" ,,,,,,,,,,,,, ", +" ", +" "}; + +/* XPM */ +char * folder_up_xpm[] = { +"20 18 8 1", +" c None", +". c #9C9C00", +"+ c #000000", +"@ c #F7F7F7", +"# c #FFFFCE", +"$ c #FFFF9C", +"% c #CECE63", +"& c #FFCE9C", +" ", +" ", +" ", +" .....+ ", +" .@##$$.+ ", +" .%%%%%%%...... ", +" .###########$%+ ", +" .#$$$+$$$$$$&%+ ", +" .#$$+++$$&$&$%+ ", +" .#$+++++$$&$&%+ ", +" .#$$$+$&$&$&$%+ ", +" .#$$$+$$&$&$&%+ ", +" .#$$$++++++&&%+ ", +" .#&$&$&$&$&&&%+ ", +" .%%%%%%%%%%%%%+ ", +" ++++++++++++++ ", +" ", +" "}; + +/* XPM */ +char * folder_closed_xpm[] = { +"20 16 44 1", +" c None", +". c #A68A5E", +"+ c #54452F", +"@ c #FEE89E", +"# c #FEE59B", +"$ c #FEE298", +"% c #FEDE95", +"& c #FEDB93", +"* c #CEAB75", +"= c #FEF6A9", +"- c #FEF2A7", +"; c #FEEFA4", +"> c #FEECA1", +", c #FEE99E", +"' c #FEE69C", +") c #FEE399", +"! c #FEDF96", +"~ c #FEDC93", +"{ c #FED991", +"] c #FED68E", +"^ c #FEF3A7", +"/ c #FEF0A4", +"( c #FEEDA2", +"_ c #FEE99F", +": c #FEE097", +"< c #FEDD94", +"[ c #FEDA91", +"} c #FED78E", +"| c #FEF0A5", +"1 c #FEEA9F", +"2 c #FEE79D", +"3 c #FEE49A", +"4 c #FEE197", +"5 c #FEDA92", +"6 c #FED78F", +"7 c #FEEEA3", +"8 c #FEEAA0", +"9 c #FEE198", +"0 c #FEDB92", +"a c #FED88F", +"b c #FEEBA0", +"c c #FED890", +"d c #FEE299", +"e c #FED990", +" ", +" .....+ ", +" .@#$%&.+ ", +" ......*******. ", +" .=-;>,')!~{]].+ ", +" .^/(_'):<[}]].+ ", +" .|(1234<56]]].+ ", +" .78239%0a]]]].+ ", +" .b@#$%&c]]]]].+ ", +" .@#d!~e]]]]]].+ ", +" .')!~{]]]]]]].+ ", +" .):<[}]]]]]]].+ ", +" ..............+ ", +" ++++++++++++++ ", +" ", +" "}; +/* +"20 16 29 1", +" c None", +". c #9E9E02", +"+ c #222202", +"@ c #FEFECE", +"# c #FEF2C2", +"$ c #FEEABA", +"% c #FEDEAE", +"& c #FEDAA6", +"* c #CECE62", +"= c #FEFECA", +"- c #FEFACA", +"; c #FEF6C6", +"> c #FEEEBA", +", c #FEE6B6", +"' c #FEE2B2", +") c #FEDAAA", +"! c #FEEEBE", +"~ c #FEEAB6", +"{ c #FEE6B2", +"] c #FEE2AE", +"^ c #FEDEAA", +"/ c #FEFAC6", +"( c #FEF6C2", +"_ c #FEF2BE", +": c #FED6A2", +"< c #FED6A6", +"[ c #FED2A2", +"} c #FED29E", +"| c #FECE9E", +" ", +" .....+ ", +" .@#$%&.+ ", +" .*******...... ", +" .@@=-;#>$,'%)*+ ", +" .@@-;#!!~{]^)*+ ", +" .@-/(_>$,']^)*+ ", +" .@-;#!$,{')&:*+ ", +" .@/(#!~,]])<:*+ ", +" ./;#!$,'')&<[*+ ", +" .;#_>${]%)<}}*+ ", +" .##!${'%^<:[|*+ ", +" .*************+ ", +" ++++++++++++++ ", +" ", +" "}; +*/ + +char * folder_open_xpm[] = { +"20 16 34 1", +" c None", +". c #A68A5E", +"+ c #FEF3A7", +"@ c #FEECA1", +"# c #FEE49A", +"$ c #FEDD94", +"% c #FED68E", +"& c #FEF6A9", +"* c #FEEEA3", +"= c #FEE79D", +"- c #FEDF96", +"; c #FED890", +"> c #FEF1A5", +", c #FEE99F", +"' c #FEE298", +") c #FEDA92", +"! c #FEF0A5", +"~ c #FEEBA1", +"{ c #FEE69C", +"] c #FEE198", +"^ c #FEDC93", +"/ c #FED78F", +"( c #54452F", +"_ c #FEF2A6", +": c #FEEDA2", +"< c #FEE299", +"[ c #FEE99E", +"} c #FEDE95", +"| c #FED991", +"1 c #FEEFA4", +"2 c #FEEA9F", +"3 c #FEE59B", +"4 c #FEE096", +"5 c #FEDB92", +" ", +" ..... ", +" .+@#$%. ", +" ......&*=-;%%. ", +" .&&&&&>,')%%%. ", +" .&&&&+@#$%%%%. ", +" .&&............ ", +" .&&.&!~{]^/%%%.( ", +" .&&._:=<$;%%%%.( ", +" .&.+*[#}|%%%%.( ", +" .&.12345%%%%%.( ", +" .!~{]^/%%%%.( ", +" ............( ", +" (((((((((((( ", +" ", +" "}; + +/* +"20 16 41 1", +" c None", +". c #9E9E02", +"+ c #FEFECE", +"@ c #FEFACA", +"# c #F6F2C4", +"$ c #F2EABE", +"% c #EEE6B9", +"& c #FAF6C6", +"* c #F2EEBE", +"= c #EADEB2", +"- c #E2D6AA", +"; c #EAE2B6", +"> c #E6DAAE", +", c #E2D2AA", +"' c #DAC69E", +") c #D2C296", +"! c #CEBA92", +"~ c #CAB28A", +"{ c #C2AA82", +"] c #CECE62", +"^ c #222202", +"/ c #FEFECA", +"( c #D6C69A", +"_ c #C2A67E", +": c #FEF2BE", +"< c #FEEABA", +"[ c #FEE6B6", +"} c #FEE2B2", +"| c #FEDEAE", +"1 c #FEDAAA", +"2 c #BA9E7A", +"3 c #FEF6C6", +"4 c #FEF2C2", +"5 c #FEEEBA", +"6 c #FEEAB6", +"7 c #FEDEAA", +"8 c #FED6A4", +"9 c #FEEEBE", +"0 c #FED2A2", +"a c #FEF6C2", +"b c #FECE9E", +" ", +" ..... ", +" .+@#$%. ", +" .++&*%=-...... ", +" .+@#$;>,')!~{]^ ", +" ./&*%=>,()!~{]^ ", +" ............{_]^ ", +" .++@&:<[}|1]^2]^ ", +" .++@3456}|1]^2]^ ", +" ./@4:<[}718.^.^ ", +" .@349<[}1800^.^ ", +" .a:96}|180b.^^ ", +" ............^^ ", +" ^^^^^^^^^^^^^ ", +" ", +" "}; +*/ + +/* XPM */ +char * greendot_xpm[] = { +"13 13 9 1", +" c None", +". c #D4FFD4", +"+ c #63FF63", +"@ c #1AFF1A", +"# c #00FF00", +"$ c #A8FFA8", +"% c #60FF60", +"& c #EAFFEA", +"* c #FFFFFF", +" ", +" .+@#@+. ", +" $#######$ ", +" .#%&&%####. ", +" +#&**&####+ ", +" @#&**&####@ ", +" ##%&&%##### ", +" @#########@ ", +" +#########+ ", +" .#########. ", +" $#######$ ", +" .+@#@+. ", +" "}; + +/* XPM */ +char * purpledot_xpm[] = { +"13 13 9 1", +" c None", +". c #FFD4FF", +"+ c #FF63FF", +"@ c #FF1AFF", +"# c #FF00FF", +"$ c #FFA8FF", +"% c #FF60FF", +"& c #FFEAFF", +"* c #FFFFFF", +" ", +" .+@#@+. ", +" $#######$ ", +" .#%&&%####. ", +" +#&**&####+ ", +" @#&**&####@ ", +" ##%&&%##### ", +" @#########@ ", +" +#########+ ", +" .#########. ", +" $#######$ ", +" .+@#@+. ", +" "}; +/* XPM */ +char * question_book_xpm[] = { +"18 18 19 1", +" c None", +". c #840084", +"+ c #000000", +"@ c #FF9CFF", +"# c #CE00CE", +"$ c #630063", +"% c #9C009C", +"& c #9C6331", +"* c #FFFF00", +"= c #CE9C31", +"- c #FFCE31", +"; c #636363", +"> c #9C9C9C", +", c #848484", +"' c #C6C6C6", +") c #ADAD94", +"! c #E7E7D6", +"~ c #D60094", +"{ c #CE63CE", +" ", +" .+ ", +" .@#$+ ", +" .@###%$+ ", +" .@##&&$..$+ ", +" .@##***=$..++ ", +" .@#####-*$.+. ", +" .@####**-&.+;. ", +" .@###*-&%.%+;>.+ ", +" ...##%%##%+;>,.+ ", +" .>'..###%+;>).+ ", +" .>!')..%+,>'.+ ", +" .~{!!''.>)'.+ ", +" $$~{!!!''.+ ", +" $$~{!'.+ ", +" $$~.+ ", +" $+ ", +" "}; +/* XPM */ +char * reddot_xpm[] = { +"13 13 9 1", +" c None", +". c #FFD4D4", +"+ c #FF6363", +"@ c #FF1A1A", +"# c #FF0000", +"$ c #FFA8A8", +"% c #FF6060", +"& c #FFEAEA", +"* c #FFFFFF", +" ", +" .+@#@+. ", +" $#######$ ", +" .#%&&%####. ", +" +#&**&####+ ", +" @#&**&####@ ", +" ##%&&%##### ", +" @#########@ ", +" +#########+ ", +" .#########. ", +" $#######$ ", +" .+@#@+. ", +" "}; +/* XPM */ +char * tealdot_xpm[] = { +"13 13 9 1", +" c None", +". c #D4FFFF", +"+ c #63FFFF", +"@ c #1AFFFF", +"# c #00FFFF", +"$ c #A8FFFF", +"% c #60FFFF", +"& c #EAFFFF", +"* c #FFFFFF", +" ", +" .+@#@+. ", +" $#######$ ", +" .#%&&%####. ", +" +#&**&####+ ", +" @#&**&####@ ", +" ##%&&%##### ", +" @#########@ ", +" +#########+ ", +" .#########. ", +" $#######$ ", +" .+@#@+. ", +" "}; +/* XPM */ +char * textdoc_xpm[] = { +"15 18 5 1", +" c None", +". c #848484", +"+ c #FFFFFF", +"@ c #C6C6C6", +"# c #000000", +" ", +" .......... ", +" .++++++++@. ", +" .+@......@+. ", +" .++++++++...# ", +" .+@.......+@# ", +" .++++++++++@# ", +" .+@.......+@# ", +" .++++++++++@# ", +" .+@.......+@# ", +" .++++++++++@# ", +" .+@.......+@# ", +" .++++++++++@# ", +" .+@.......+@# ", +" .++++++++++@# ", +" .@@@@@@@@@@@# ", +" ############ ", +" "}; + +/* XPM */ +char * yellowdot_xpm[] = { +"13 13 9 1", +" c None", +". c #FFFFD4", +"+ c #FFFF63", +"@ c #FFFF1A", +"# c #FFFF00", +"$ c #FFFFA8", +"% c #FFFF60", +"& c #FFFFEA", +"* c #FFFFFF", +" ", +" .+@#@+. ", +" $#######$ ", +" .#%&&%####. ", +" +#&**&####+ ", +" @#&**&####@ ", +" ##%&&%##### ", +" @#########@ ", +" +#########+ ", +" .#########. ", +" $#######$ ", +" .+@#@+. ", +" "}; + +/* XPM */ +char * cdrom_xpm[] = { +"22 22 39 1", +" c None", +". c #ADADAD", +"+ c #C67BA5", +"@ c #DEDEDE", +"# c #E7E7E7", +"$ c #E6E6E6", +"% c #7B9CBD", +"& c #CE8CAD", +"* c #DE8CAD", +"= c #FFFFFF", +"- c #6BB58C", +"; c #7BCEBD", +"> c #8CA5D6", +", c #DE9CC6", +"' c #8CD67B", +") c #8CDEB5", +"! c #7BB5D6", +"~ c #9C9CDE", +"{ c #DE94B5", +"] c #FFB1FF", +"^ c #C0C0C0", +"/ c #9CBD63", +"( c #ADD67B", +"_ c #94DEC6", +": c #CEAD73", +"< c #D6C67B", +"[ c #BDD67B", +"} c #94C67B", +"| c #94B5D6", +"1 c #C6A584", +"2 c #DEBD8C", +"3 c #DECE94", +"4 c #9CCE84", +"5 c #7B7B7B", +"6 c #FFD48E", +"7 c #DEDEEF", +"8 c #FFEFEF", +"9 c #6BA5BD", +"0 c #C6849C", +" ", +" ...... ", +" ..+@#$#$.. ", +" ..%&*$$$$===.. ", +" .-;>,*$$$$===$.. ", +" .')!~{]$$$==$=^. ", +" ./('_%,]$$==$=^$$. ", +" .:<[}_|]#@=$=^$$$. ", +" .122234_.55.=^$$$$$. ", +" .$$$666.5555.$$$$$$. ", +" .$$$$$#55 55@$$$$$. ", +" .$$$$$$55 557$$$$$. ", +" .#$$$$$.5555.66688#. ", +" .$$$$$^=$55._}32<21. ", +" .$$$^=$=$#]|_}(<:. ", +" .$$^=$==$$],%_44/. ", +" .^=$===$$]{~!)'. ", +" ..$===$$$8*,>;-. ", +" ..===$$$8*&9.. ", +" ..=$@@#0.. ", +" ...... ", +" "}; + +/* XPM */ +char * big_folder_new_xpm[] = { +"20 20 73 1", +" c None", +". c #000000", +"+ c #FFFFFF", +"@ c #444444", +"# c #474747", +"$ c #353535", +"% c #CEC765", +"& c #FFF373", +"* c #FFEF77", +"= c #FFEC78", +"- c #FFE87C", +"; c #C8B46E", +"> c #3C3C3C", +", c #C0B666", +"' c #FFE97A", +") c #FFE67D", +"! c #FFE182", +"~ c #FFE082", +"{ c #FFDE83", +"] c #FAD982", +"^ c #C1AA70", +"/ c #BFA872", +"( c #FFEFA4", +"_ c #FFDB87", +": c #FFD88A", +"< c #FFD68B", +"[ c #FFD48E", +"} c #FFD48D", +"| c #FFD48C", +"1 c #FFD58B", +"2 c #EFC885", +"3 c #FFEEA3", +"4 c #FFECA1", +"5 c #C8BB86", +"6 c #FFE89F", +"7 c #FFE69D", +"8 c #FFE49B", +"9 c #FFE39A", +"0 c #FFE29A", +"a c #FFE199", +"b c #FFE098", +"c c #FFDF97", +"d c #FFDE96", +"e c #FFDD95", +"f c #FFDC94", +"g c #FFECA2", +"h c #FFEBA1", +"i c #FFE79E", +"j c #FFE299", +"k c #FFDC95", +"l c #FFDB94", +"m c #FFEBA0", +"n c #FFE89E", +"o c #FFE79D", +"p c #FFE097", +"q c #FFD992", +"r c #FFE99E", +"s c #FFE69C", +"t c #FFE59B", +"u c #FFDA93", +"v c #FFD690", +"w c #FFD790", +"x c #FFD791", +"y c #FFD891", +"z c #FFD58E", +"A c #FFD58F", +"B c #FFD68F", +"C c #FFE198", +"D c #FFDF96", +"E c #FFDE95", +"F c #FFDB93", +"G c #FFD991", +"H c #FFDA92", +" ", +" .+ . .+ @##### ", +" .+. .+ $%&*=-;> ", +" ##...+####,')!~{]^#", +"#...+.../(#_:<[}|12#", +"#++...++345#########", +"#/.+.+.+677890abcde#", +"#.+/.+/.+aabccddeff#", +"#(gh6i8jbddeekkflll#", +"#mno89pelqqqqqqqqqq#", +"#rstjbeuqvvvvwxxyyy#", +"#8jbdeuxv[[[zABBvww#", +"#CDEfFGwB[[[[zAABBB#", +"#cekuuyvA[[[[zAABBB#", +"#FHqyyvAz[[[[[zzzzz#", +"#qyywwBA[[[[[[[[[[[#", +"#zzzzz[[[[[[[[[[[[[#", +" ################## ", +" ", +" "}; + +/* XPM */ +char * big_folder_up_xpm[] = { +"20 20 70 1", +" c None", +". c #474747", +"+ c #434343", +"@ c #3B3B3B", +"# c #B9B260", +"$ c #FFF373", +"% c #FFEF77", +"& c #FFEC78", +"* c #FFE87C", +"= c #C8B46E", +"- c #3C3C3C", +"; c #C2B667", +"> c #FFE97B", +", c #FFE67D", +"' c #FFE182", +") c #FFE082", +"! c #FFDE83", +"~ c #FFDD84", +"{ c #D1B775", +"] c #FFF6AA", +"^ c #FFE79E", +"/ c #FFF1A5", +"( c #FFEFA4", +"_ c #484848", +": c #F7D584", +"< c #FFD88A", +"[ c #FFD68B", +"} c #FFD48E", +"| c #FFD48D", +"1 c #FFD48C", +"2 c #FFD58B", +"3 c #FFEEA3", +"4 c #FFECA1", +"5 c #BEB280", +"6 c #BFA872", +"7 c #000000", +"8 c #FFE89F", +"9 c #FFE69D", +"0 c #FFE49B", +"a c #FFE39A", +"b c #FFE29A", +"c c #FFE199", +"d c #FFE098", +"e c #FFDF97", +"f c #FFDE96", +"g c #FFDD95", +"h c #FFDC94", +"i c #FFECA2", +"j c #FFDC95", +"k c #FFDB94", +"l c #FFEBA0", +"m c #FFE89E", +"n c #FFD992", +"o c #FFE99E", +"p c #FFE69C", +"q c #FFE59B", +"r c #FFE299", +"s c #FFDA93", +"t c #FFD690", +"u c #FFD790", +"v c #FFD791", +"w c #FFD891", +"x c #FFD58E", +"y c #FFD58F", +"z c #FFD68F", +"A c #FFE198", +"B c #FFDF96", +"C c #FFDE95", +"D c #FFDB93", +"E c #FFDA92", +" ", +" .....+ ", +" @#$%&*=- ", +" ..........;>,')!~{.", +".]]^^////(_:<[}|122.", +".]]^^^33345.........", +".](3^6768990abcdefg.", +".((367776ccdeeffghh.", +".(i6777776fggjjhkkk.", +".lm7777777nnnnnnnnn.", +".opqr67snttttuvvwww.", +".0rdf67vt}}}xyzztuu.", +".ABCh67666666666zzz.", +".egjs67777777777zzz.", +".DEnwwtyx}}}}}xxxxx.", +".nwwuuzy}}}}}}}}}}}.", +".xxxxx}}}}}}}}}}}}}.", +" .................. ", +" ", +" "}; diff --git a/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/linux_path_info.c b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/linux_path_info.c new file mode 100644 index 0000000..25e5071 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/FLU_src/linux_path_info.c @@ -0,0 +1,218 @@ +/* + This file is not licenced under the GPL like the rest of the code. + Its is under the MIT license, to encourage reuse by cut-and-paste. + + Copyright (c) 2007 Red Hat, inc + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +#include +#include +#include + +/** + * xdg_user_dir_lookup_with_fallback: + * @type: a string specifying the type of directory + * @fallback: value to use if the directory isn't specified by the user + * @returns: a newly allocated absolute pathname + * + * Looks up a XDG user directory of the specified type. + * Example of types are "DESKTOP" and "DOWNLOAD". + * + * In case the user hasn't specified any directory for the specified + * type the value returned is @fallback. + * + * The return value is newly allocated and must be freed with + * free(). The return value is never NULL if @fallback != NULL, unless + * out of memory. + **/ +static char * +xdg_user_dir_lookup_with_fallback (const char *type, const char *fallback) +{ + FILE *file; + char *home_dir, *config_home, *config_file; + char buffer[512]; + char *user_dir; + char *p, *d; + int len; + int relative; + + home_dir = getenv ("HOME"); + + if (home_dir == NULL) + goto error; + + config_home = getenv ("XDG_CONFIG_HOME"); + if (config_home == NULL || config_home[0] == 0) + { + config_file = (char*) malloc (strlen (home_dir) + strlen ("/.config/user-dirs.dirs") + 1); + if (config_file == NULL) + goto error; + + strcpy (config_file, home_dir); + strcat (config_file, "/.config/user-dirs.dirs"); + } + else + { + config_file = (char*) malloc (strlen (config_home) + strlen ("/user-dirs.dirs") + 1); + if (config_file == NULL) + goto error; + + strcpy (config_file, config_home); + strcat (config_file, "/user-dirs.dirs"); + } + + file = fopen (config_file, "r"); + free (config_file); + if (file == NULL) + goto error; + + user_dir = NULL; + while (fgets (buffer, sizeof (buffer), file)) + { + /* Remove newline at end */ + len = strlen (buffer); + if (len > 0 && buffer[len-1] == '\n') + buffer[len-1] = 0; + + p = buffer; + while (*p == ' ' || *p == '\t') + p++; + + if (strncmp (p, "XDG_", 4) != 0) + continue; + p += 4; + if (strncmp (p, type, strlen (type)) != 0) + continue; + p += strlen (type); + if (strncmp (p, "_DIR", 4) != 0) + continue; + p += 4; + + while (*p == ' ' || *p == '\t') + p++; + + if (*p != '=') + continue; + p++; + + while (*p == ' ' || *p == '\t') + p++; + + if (*p != '"') + continue; + p++; + + relative = 0; + if (strncmp (p, "$HOME/", 6) == 0) + { + p += 6; + relative = 1; + } + else if (*p != '/') + continue; + + if (relative) + { + user_dir = (char*) malloc (strlen (home_dir) + 1 + strlen (p) + 1); + if (user_dir == NULL) + goto error2; + + strcpy (user_dir, home_dir); + strcat (user_dir, "/"); + } + else + { + user_dir = (char*) malloc (strlen (p) + 1); + if (user_dir == NULL) + goto error2; + + *user_dir = 0; + } + + d = user_dir + strlen (user_dir); + while (*p && *p != '"') + { + if ((*p == '\\') && (*(p+1) != 0)) + p++; + *d++ = *p++; + } + *d = 0; + } +error2: + fclose (file); + + if (user_dir) + return user_dir; + + error: + if (fallback) + return strdup (fallback); + return NULL; +} + +/** + * xdg_user_dir_lookup: + * @type: a string specifying the type of directory + * @returns: a newly allocated absolute pathname + * + * Looks up a XDG user directory of the specified type. + * Example of types are "DESKTOP" and "DOWNLOAD". + * + * The return value is always != NULL (unless out of memory), + * and if a directory + * for the type is not specified by the user the default + * is the home directory. Except for DESKTOP which defaults + * to ~/Desktop. + * + * The return value is newly allocated and must be freed with + * free(). + **/ +static char * +xdg_user_dir_lookup (const char *type) +{ + char *dir, *home_dir, *user_dir; + + dir = xdg_user_dir_lookup_with_fallback (type, NULL); + if (dir != NULL) + return dir; + + home_dir = getenv ("HOME"); + + if (home_dir == NULL) + return strdup ("/tmp"); + + /* Special case desktop for historical compatibility */ + if (strcmp (type, "DESKTOP") == 0) + { + user_dir = (char*) malloc (strlen (home_dir) + strlen ("/Desktop") + 1); + if (user_dir == NULL) + return NULL; + + strcpy (user_dir, home_dir); + strcat (user_dir, "/Desktop"); + return user_dir; + } + + return strdup (home_dir); +} + diff --git a/mod/maxgui.mod/fltkmaxgui.mod/Flmm/COPYING b/mod/maxgui.mod/fltkmaxgui.mod/Flmm/COPYING new file mode 100644 index 0000000..193b6bf --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/Flmm/COPYING @@ -0,0 +1,528 @@ + FLMM License + November 27, 2004 + +The FLMM library and included programs are provided under the terms +of the GNU Library General Public License (LGPL) with the following +exceptions: + + 1. Modifications to the FLMM configure script, config + header file, and makefiles by themselves to support + a specific platform do not constitute a modified or + derivative work. + + The authors do request that such modifications be + contributed to the FLMM project - send all + contributions to "flmm@matthiasm.com". + + 2. Widgets that are subclassed from FLMM widgets do not + constitute a derivative work. + + 3. Static linking of applications and widgets to the + FLMM library does not constitute a derivative work + and does not require the author to provide source + code for the application or widget, use the shared + FLMM libraries, or link their applications or + widgets against a user-supplied version of FLMM. + + If you link the application or widget to a modified + version of FLMM, then the changes to FLMM must be + provided under the terms of the LGPL in sections + 1, 2, and 4. + + 4. You do not have to provide a copy of the FLMM license + with programs that are linked to the FLMM library, nor + do you have to identify the FLMM license in your + program or documentation as required by section 6 + of the LGPL. + + However, programs must still identify their use of FLMM. + The following example statement can be included in user + documentation to satisfy this requirement: + + [program/widget] is based in part on the work of + the FLMM project (http://www.matthiasm.com/). + +----------------------------------------------------------------------- + + GNU LIBRARY GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + [This is the first released version of the library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if +you distribute copies of the library, or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, so that any problems introduced by others will not reflect on +the original authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + + The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + + GNU LIBRARY GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +General Public License (also called "this License"). Each licensee is +addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also compile or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + c) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + d) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the source code distributed need not include anything that is normally +distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Library General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/mod/maxgui.mod/fltkmaxgui.mod/Flmm/CREDITS b/mod/maxgui.mod/fltkmaxgui.mod/Flmm/CREDITS new file mode 100644 index 0000000..79a7184 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/Flmm/CREDITS @@ -0,0 +1,12 @@ +CREDITS - FLMM, the FLTK extension library Version 1.1.6 +-------------------------------------------------------- + +CORE DEVELOPER + + Matthias Melcher (mm@matthiasm.com) + +I would like to thank the core developers of FLTK and all other contributers. +Special thanks go to Bill Spitzak who started FLTK as "the insane rewrite +of the Forms Library" for beeing a good friend and coworker, and Mike Sweet +for managing FLTK, fltk.org, and the mad developer crowd. + diff --git a/mod/maxgui.mod/fltkmaxgui.mod/Flmm/readme.txt b/mod/maxgui.mod/fltkmaxgui.mod/Flmm/readme.txt new file mode 100644 index 0000000..86c80a8 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/Flmm/readme.txt @@ -0,0 +1,34 @@ + + Flmm_Tabs | Matthias Melcher | mm@matthiasm.com + +Due to popular request, Flmm_Tabs implements tabs with an arbitrary number of children. When the tab row grows too big, a pulldown menu button shows up to the right of the tabs which allows selection of any child. It is also possible to walk through all tabs by clicking the left or right tab at the very outside border. + +Flmm_Tabs is derived from Fl_Tabs and uses precisely the same API. + +REPORTING BUGS + + To report a bug in FLMM, send an email to + "flmm@matthiasm.com". Please include the FLMM version, + operating system & version, and compiler that you are using + when describing the bug or problem. + +COPYRIGHT + + FLMM is copyright 2002-2004 by Matthias Melcher (mm@matthiasm.com) + + This library is free software; you can redistribute it + and/or modify it under the terms of the GNU Library General + Public License as published by the Free Software Foundation; + either version 2 of the License, or (at your option) any + later version. + + This library is distributed in the hope that it will be + useful, but WITHOUT ANY WARRANTY; without even the implied + warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the GNU Library General Public License for + more details. + + You should have received a copy of the GNU Library General + Public License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA. diff --git a/mod/maxgui.mod/fltkmaxgui.mod/README b/mod/maxgui.mod/fltkmaxgui.mod/README new file mode 100644 index 0000000..ba2d90a --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/README @@ -0,0 +1,189 @@ +README - Fast Light Tool Kit (FLTK) Version 1.3.0 +------------------------------------------------- + +WHAT IS FLTK? + + The Fast Light Tool Kit ("FLTK", pronounced "fulltick") is a + a cross-platform C++ GUI toolkit for UNIX(r)/Linux(r) (X11), + Microsoft(r) Windows(r), and MacOS(r) X. FLTK provides + modern GUI functionality without the bloat and supports 3D + graphics via OpenGL(r) and its built-in GLUT emulation. It + was originally developed by Mr. Bill Spitzak and is + currently maintained by a small group of developers across + the world with a central repository in the US. + + +LICENSING + + FLTK comes with complete free source code. FLTK is available + under the terms of the GNU Library General Public License. + Contrary to popular belief, it can be used in commercial + software! (Even Bill Gates could use it.) + + +ON-LINE DOCUMENTATION + + All of the documentation is in HTML in the subdirectory + "documentation". The "index.html" file should be your + starting point. PostScript(tm) and PDF versions of this + documentation is also available from the FLTK web site at: + + http://www.fltk.org/documentation.php + + +BUILDING AND INSTALLING FLTK UNDER UNIX AND MacOS X + + In most cases you can just type "make". This will run + configure with the default (no) options and then compile + everything. + + FLTK uses GNU autoconf to configure itself for your UNIX + platform. The main things that the configure script will + look for are the X11, OpenGL (or Mesa), and JPEG header and + library files. Make sure that they are in the standard + include/library locations. If they aren't you need to + define the CFLAGS, CXXFLAGS, and LDFLAGS environment + variables. + + If you aren't using "gcc", "g++", "c++", or "CC" for your + C++ compiler, you'll also need to set the CXX environment + variable. Similarly, if you aren't using "gcc" or "cc" for + your C compiler you'll need to set the CC environment + variable. + + You can run configure yourself to get the exact setup you + need. Type "./configure ". Options include: + + --enable-cygwin - Enable the Cygwin libraries (WIN32) + --enable-debug - Enable debugging code & symbols + --disable-gl - Disable OpenGL support + --enable-shared - Enable generation of shared libraries + --enable-threads - Enable multithreading support + --enable-xdbe - Enable the X double-buffer extension + --enable-xft - Enable the Xft library (anti-aliased fonts) + + --bindir=/path - Set the location for executables + [default = /usr/local/bin] + --libdir=/path - Set the location for libraries + [default = /usr/local/lib] + --includedir=/path - Set the location for include files. + [default = /usr/local/include] + --prefix=/dir - Set the directory prefix for files + [default = /usr/local] + + When the configure script is done you can just run the + "make" command. This will build the library, FLUID tool, and + all of the test programs. + + To install the library, become root and type "make + install". This will copy the "fluid" executable to + "bindir", the header files to "includedir", and the library + files to "libdir". + + To install additional files and icons to be used by the main + desktop environments such as KDE, GNOME and XFCE, you will also + need to run "make install-desktop" as root. + + +BUILDING FLTK UNDER MICROSOFT WINDOWS + + There are two ways to build FLTK under Microsoft Windows. + The first is to use the Visual C++ project files under the + "ide/" directory. See the file ide/README.IDE for more info. + + The second method is to use a GNU-based development tool + with the files in the "makefiles" directory. To build + with the CygWin tools, use the supplied configure script + as specified in the UNIX section above: + + sh configure ...options... + + To build using other tools simply copy the appropriate + makeinclude and config files to the main directory and do a + make: + + copy makefiles\Makefile. Makefile + make + + +BUILDING FLTK UNDER OS/2 + + The current OS/2 build requires XFree86 for OS/2 to work. A + native Presentation Manager version has not been implemented + yet (volunteers are welcome!). + + To build the XFree86 version of FLTK for OS/2, copy the + appropriate makeinclude and config files to the main + directory and do a make: + + copy makefiles\Makefile.os2x Makefile + make + + +INTERNET RESOURCES + + FLTK is available on the 'net in a bunch of locations: + + - WWW: http://www.fltk.org/ + http://www.fltk.org/str.php [for reporting bugs] + http://www.fltk.org/software.php [source code] + + - FTP: http://ftp.easysw.com/pub/fltk + ftp://ftp.easysw.com/pub/fltk + ftp://ftp2.easysw.com/pub/fltk + ftp://ftp.funet.fi/pub/mirrors/ftp.easysw.com/pub/fltk + ftp://linux.mathematik.tu-darmstadt.de/pub/linux/mirrors/misc/fltk + ftp://gd.tuwien.ac.at/hci/fltk + + - EMail: fltk@fltk.org [see instructions below] + + To send a message to the FLTK mailing list ("fltk@fltk.org") + you must first join the list. Non-member submissions are + blocked to avoid problems with SPAM. + + To join the FLTK mailing list, go the following web page: + + http://lists.easysw.com/listinfo/fltk + + +REPORTING BUGS + + To report a bug in FLTK, use the form at: + + http://www.fltk.org/str.php + + For general support and questions, please use the FLTK + mailing list at "fltk@fltk.org". + + +TRADEMARKS + + Microsoft and Windows are registered trademarks of Microsoft + Corporation. UNIX is a registered trademark of the X/Open + Group, Inc. OpenGL is a registered trademark of Silicon + Graphics, Inc. MacOS is a registered trademark of Apple + Computers, Inc. + + +COPYRIGHT + + FLTK is copyright 1998-2010 by Bill Spitzak + (spitzak@users.sourceforge.net) and others, + see the CREDITS file for more info. + + This library is free software; you can redistribute it + and/or modify it under the terms of the GNU Library General + Public License as published by the Free Software Foundation; + either version 2 of the License, or (at your option) any + later version. + + This library is distributed in the hope that it will be + useful, but WITHOUT ANY WARRANTY; without even the implied + warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the GNU Library General Public License for + more details. + + You should have received a copy of the GNU Library General + Public License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA. diff --git a/mod/maxgui.mod/fltkmaxgui.mod/cocoa_bridge.mm b/mod/maxgui.mod/fltkmaxgui.mod/cocoa_bridge.mm new file mode 100644 index 0000000..c88b412 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/cocoa_bridge.mm @@ -0,0 +1,23 @@ +#include "src/Fl.cxx" + +#import + +extern "C"{ + void* NSContentView(NSWindow*); + void NSUpdateCanvas(NSWindow*); +} + +void* NSContentView(NSWindow* window){ + return [window contentView]; +} + +void NSUpdateCanvas(NSWindow* window){ + NSRect rect = [window frame]; + int style = [window styleMask]; + rect = [window contentRectForFrameRect:rect]; + [window setContentSize:rect.size]; +} + +#include "src/Fl_Printer.cxx" + +#include "src/Fl_Native_File_Chooser.cxx" \ No newline at end of file diff --git a/mod/maxgui.mod/fltkmaxgui.mod/config.h b/mod/maxgui.mod/fltkmaxgui.mod/config.h new file mode 100644 index 0000000..22db91e --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/config.h @@ -0,0 +1,351 @@ +/* config.h. Generated from configh.in by configure. */ +/* + * "$Id: configh.in 6462 2008-10-19 01:42:35Z fabien $" + * + * Configuration file for the Fast Light Tool Kit (FLTK). + * @configure_input@ + * + * Copyright 1998-2007 by Bill Spitzak and others. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems on the following page: + * + * http://www.fltk.org/str.php + */ + +/* + * Where to find files... + */ + +#define FLTK_DATADIR "" +#define FLTK_DOCDIR "" + +/* + * BORDER_WIDTH: + * + * Thickness of FL_UP_BOX and FL_DOWN_BOX. Current 1,2, and 3 are + * supported. + * + * 3 is the historic FLTK look. + * 2 is the default and looks like Microsoft Windows, KDE, and Qt. + * 1 is a plausible future evolution... + * + * Note that this may be simulated at runtime by redefining the boxtypes + * using Fl::set_boxtype(). + */ + +#define BORDER_WIDTH 2 + +/* + * HAVE_GL: + * + * Do you have OpenGL? Set this to 0 if you don't have or plan to use + * OpenGL, and FLTK will be smaller. + */ + +#define HAVE_GL 1 + +/* + * HAVE_GL_GLU_H: + * + * Do you have the OpenGL Utility Library header file? + * (many broken Mesa RPMs do not...) + */ + +#define HAVE_GL_GLU_H 1 + +/* + * HAVE_GLXGETPROCADDRESSARB: + * + * Do you have the OpenGL glXGetProcAddressARB() function? + */ + +#define HAVE_GLXGETPROCADDRESSARB 1 + +/* + * USE_COLORMAP: + * + * Setting this to zero will save a good deal of code (especially for + * fl_draw_image), but FLTK will only work on TrueColor visuals. + */ + +#define USE_COLORMAP 0 + +#if __linux + + /* + * HAVE_XINERAMA + * + * Do we have the Xinerama library to support multi-head displays? + */ + + #define HAVE_XINERAMA 0 + + /* + * USE_XFT + * + * Use the new Xft library to draw anti-aliased text. + */ + + #define USE_XFT 1 + //#undef USE_XFT + + /* + * HAVE_XDBE: + * + * Do we have the X double-buffer extension? + */ + + // seb: Disabled to remedy occasional black flickering on resize. + // skid: TODO: fix clipping of windowclient and reenable + + #define HAVE_XDBE 0 + + /* + * USE_XDBE: + * + * Actually try to use the double-buffer extension? + */ + + #define USE_XDBE HAVE_XDBE + + /* + * USE_QUARTZ: + * + * Use Quartz instead of Quickdraw on Apple Mac OS X machines. + * FLTK was originally ported to Quickdraw which is no longer + * supported by Apple. If USE_QUARTZ is defined, FLTK will be + * compiled using Quartz instead. This flag has no meaning on + * other operating systems. + */ + + /* #undef __APPLE_QUARTZ__ */ + /* #undef __APPLE_QD__ */ + + + /* + * USE_X11 + * + * Should we use X11 for the current platform + * + */ + + #define USE_X11 1 + + /* + * HAVE_OVERLAY: + * + * Use the X overlay extension? FLTK will try to use an overlay + * visual for Fl_Overlay_Window, the Gl_Window overlay, and for the + * menus. Setting this to zero will remove a substantial amount of + * code from FLTK. Overlays have only been tested on SGI servers! + */ + + #define HAVE_OVERLAY 0 + + /* + * HAVE_GL_OVERLAY: + * + * It is possible your GL has an overlay even if X does not. If so, + * set this to 1. + */ + + #define HAVE_GL_OVERLAY HAVE_OVERLAY + + #if defined(__GLIBC_PREREQ) + #if __GLIBC_PREREQ(2, 10) + #define HAVE_SCANDIR_POSIX 1 + #endif + #endif + +#elif __APPLE__ + + #define USE_QUARTZ 1 + #define __APPLE_QUARTZ__ 1 + #define __APPLE_COCOA__ 1 + +#endif + +/* + * WORDS_BIGENDIAN: + * + * Byte order of your machine: 1 = big-endian, 0 = little-endian. + */ + +#define WORDS_BIGENDIAN 0 + +/* + * U16, U32, U64: + * + * Types used by fl_draw_image. One of U32 or U64 must be defined. + * U16 is optional but FLTK will work better with it! + */ + +#define U16 unsigned short +#define U32 unsigned +/* #undef U64 */ + +/* + * HAVE_DIRENT_H, HAVE_SYS_NDIR_H, HAVE_SYS_DIR_H, HAVE_NDIR_H, HAVE_SCANDIR: + * + * Where is (used only by fl_file_chooser and scandir). + */ + +#define HAVE_DIRENT_H 1 +/* #undef HAVE_SYS_NDIR_H */ +/* #undef HAVE_SYS_DIR_H */ +/* #undef HAVE_NDIR_H */ + +#if __linux || __APPLE__ + #define HAVE_SCANDIR 1 +#else + #undef HAVE_SCANDIR +#endif + +/* + * Possibly missing sprintf-style functions: + */ + +#define HAVE_VSNPRINTF 1 +#define HAVE_SNPRINTF 1 + +/* + * String functions and headers... + */ + +#define HAVE_STRINGS_H 1 +#define HAVE_STRCASECMP 1 +/* #undef HAVE_STRLCAT */ +/* #undef HAVE_STRLCPY */ + +/* + * Do we have POSIX locale support? + */ + +#define HAVE_LOCALE_H 1 +#define HAVE_LOCALECONV 1 + +/* + * HAVE_SYS_SELECT_H: + * + * Whether or not select() call has its own header file. + */ + +#define HAVE_SYS_SELECT_H 1 + +/* + * HAVE_SYS_STDTYPES_H: + * + * Whether or not we have the header file. + */ + +/* #undef HAVE_SYS_STDTYPES_H */ + +/* + * USE_POLL: + * + * Use the poll() call provided on Linux and Irix instead of select() + */ + +#define USE_POLL 0 + +/* + * Do we have various image libraries? + */ + +#define HAVE_LIBPNG 1 +#define HAVE_LIBZ 1 +#undef HAVE_LIBJPEG + +/* + * USE_CAIRO + * + * Do we have the cairo library available and want extended cairo use in fltk ? + * will implies to link cairo.lib in all fltk based apps. + */ + +/* #undef USE_CAIRO */ + +/* + * HAVE_CAIRO + * + * Do we have the cairo library available? + */ + +/* #undef HAVE_CAIRO */ + +/* + * Which header file do we include for libpng? + */ + +#define HAVE_PNG_H 1 +/* #undef HAVE_LIBPNG_PNG_H */ + +/* + * Do we have the png_xyz() functions? + */ + +#define HAVE_PNG_GET_VALID 1 +#define HAVE_PNG_SET_TRNS_TO_ALPHA 1 + +/* + * Do we have POSIX threading? + */ + +#define HAVE_PTHREAD 1 +#define HAVE_PTHREAD_H 1 + +/* + * Do we have the ALSA library? + */ + +/* #undef HAVE_ALSA_ASOUNDLIB_H */ + +/* + * Do we have the long long type? + */ + +#define HAVE_LONG_LONG 1 + +#ifdef HAVE_LONG_LONG +# define FLTK_LLFMT "%lld" +# define FLTK_LLCAST (long long) +#else +# define FLTK_LLFMT "%ld" +# define FLTK_LLCAST (long) +#endif /* HAVE_LONG_LONG */ + +/* + * Do we have the strtoll() function? + */ + +#define HAVE_STRTOLL 1 + +#ifndef HAVE_STRTOLL +# define strtoll(nptr,endptr,base) strtol((nptr), (endptr), (base)) +#endif /* !HAVE_STRTOLL */ + +/* + * Do we have the dlsym() function and header? + */ + +#define HAVE_DLFCN_H 1 +#define HAVE_DLSYM 1 + +/* + * End of "$Id: configh.in 6462 2008-10-19 01:42:35Z fabien $". + */ diff --git a/mod/maxgui.mod/fltkmaxgui.mod/doc/intro.bbdoc b/mod/maxgui.mod/fltkmaxgui.mod/doc/intro.bbdoc new file mode 100644 index 0000000..7c17e03 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/doc/intro.bbdoc @@ -0,0 +1,22 @@ +The official Linux MaxGUI module provides a FLTK (pronounced "Full-Tick") based driver for #MaxGUI. + +As of version 1.38, it is now possible to also compile your %Windows MaxGUI applications with the +#MaxGUI.FLTKMaxGUI driver. This could be useful for getting an idea of how your applications will look when +compiled on Linux. To do this, replace your #MaxGUI.Drivers import statement with: + +{{ +?Win32 +Import MaxGUI.FLTKMaxGUI +?Not Win32 +Import MaxGUI.Drivers +? +}} + +Find out more about the FLTK 1.3 library here. + +FLTKMaxGUI also uses the excellent FLU library (FLTK Utility Widgets) and Flmm_Tab. + +Find out more about the FLU Library here. + +More information about MatthiasM's Flmm_Tab drop-in replacement widget can be found +here. diff --git a/mod/maxgui.mod/fltkmaxgui.mod/fltkdecls.bmx b/mod/maxgui.mod/fltkmaxgui.mod/fltkdecls.bmx new file mode 100644 index 0000000..028fa7b --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/fltkdecls.bmx @@ -0,0 +1,541 @@ +'This is *included* by fltkgui.bmx, fltkfont.bmx and fltksystem.bmx - the +'include statements are sandwiched between Private and Public keywords to +'avoid wasting namespaces outside of FLTKMaxGUI. + +Extern "C" + +Function flAddFd(fd,when,callback(fd:Int,user:Byte Ptr),user:Byte Ptr) +Function flReset(xdisplay,callback:Int(event),filter:Int(user:Int),mousehandler:Int(flwidget,user:Int),keyhandler:Int(flwidget,user:Int)) +Function flCountFonts() + +Function flBelowMouse() +Function flSetBelowMouse(widget) + +Function flGetColor( index ) +Function flChooseColor(title$z,r:Byte Ptr,g:Byte Ptr,b:Byte Ptr) + +Function flFontName$z(i) +Function flFontSizes:Int(fontid, sizes Ptr) +Function flFriendlyFontName$z(i) +Function flFriendlyFontAttributes(i) + +Function flRun() +Function flWait(timeout) +Function flFlush() +Function flHandle(xevent:Byte Ptr) + +Function flAddTimeout(t:Double,callback(user:Object),user:Object=Null) +Function flRequest(text$z,flags) +Function flRequestFile$z(message$z,pattern$z,path$z,save) +Function flRequestDir$z(message$z,path$z,relative) + +Function flWidget(x,y,w,h,label:Byte Ptr,fltype) +Function flFreeWidget(widget) +Function flFreePtr(data:Byte Ptr) +Function flUserData(widget) +Function flDelete(pointer:Byte Ptr) + +Function flSetColor(widget,r,g,b) +Function flRemoveColor(widget) +Function flSetLabel(widget,name$z) +Function flSetLabelColor(widget,r,g,b) +Function flSetLabelFont(widget,font) +Function flSetLabelSize(widget,size) +Function flGetLabel$z(widget) +Function flSetBox(widget,boxtype,redrawifneeded) +Function flSetLabelType(widget,labeltype) +Function flSetAlign(widget,aligntype) +Function flAlign(widget) + +Function flSetArea(widget,x,y,w,h) +Function flGetArea(widget,x Ptr,y Ptr,w Ptr,h Ptr) +Function flSetFocus(widget) +Function flGetFocus() +Function flSetWhen(widget,when) +Function flGetWhen(widget) +Function flGetUser:Int(widget) +Function flSetShow(widget,truefalse) +Function flSetCallback(widget,callback(flwidget,user:Int),user:Int=0) +Function flSetToolTip(widget,tip:Byte Ptr) +Function flSetActive(widget,truefalse) +Function flWidgetWindow(widget) + +Function flPushed() +Function flSetPushed(widget) +Function flRedraw(widget) +Function flWidth(widget) +Function flHeight(widget) +Function flVisible(widget) +Function flChanged(widget) +Function flClearChanged(widget) + +Function flShowWindow(window,truefalse) +Function flSetWindowIcon(window,icon:Byte Ptr) +Function flDestroyWindow(window) +Function flSetWindowLabel(window,name$z) +Function flClearBorder(window) +Function flSetMaxWindowSize(window,width,height) +Function flSetMinWindowSize(window,width,height) +Function flSetAcceptsFiles(window,enable) +Function flSetModal(window) +Function flSetNonModal(window) + +Function flBegin(group) +Function flEnd(group) +Function flAddToGroup(group,widget) +Function flRemoveFromGroup(group,widget) + +Function flSetInputChoice(inputchoicewidget,value) +Function flGetInputChoiceMenuWidget(inputchoicewidget) +Function flGetInputChoiceTextWidget(inputchoicewidget) + +Function flSetChoice(choicewidget,value) +Function flGetChoice(choicewidget) + +Function flSetInput(inputwidget,value$z) +Function flGetInput$z(inputwidget) +Function flActivateInput(inputwidget) +Function flSetInputFont(widget,font) +Function flSetInputSize(widget,size) + +' panel + +Function flImage(pix:Byte Ptr,w,h,d,span) +Function flFreeImage( image ) +Function flSetImage(widget,image) +Function flSetPanelColor(panel,r,g,b) +Function flSetPanelImage(panel,image,pixmapflags) +Function flSetPanelActive(panel,yesno=True) +Function flSetPanelEnabled(panel,yesno=True) + +' tabs + +Function flSelectTab(tabber,panel) +Function flGetTabPanel(tabber) +Function flGetTabPanelForEvent(tabber) + +' menubar + +Function flCreateMenu Ptr(maxitems,callback(flwidget,user:Int)) +Function flSetMenuItem(menu Ptr,item,label$z,shortcut,user:Int,flags,fonthandle,pfontsize) +Function flSetMenu(menubar,menu Ptr) +Function flPopupMenu:Int(menu Ptr,nil:Int=0) + +' button + +Function flSetButton(button,value) +Function flGetButton(button) +Function flSetButtonKey(button,key) + +' browser + +Function flClearBrowser(browser) +Function flAddBrowser(browser,label$z,obj:Object=Null,img = 0) +Function flInsertBrowser(browser,index,label$z,obj:Object=Null,img = 0) +Function flShowBrowser(browser,line,show) +Function flSelectBrowser(browser,line) +Function flMultiBrowserSelect(browser,line,seldesel) +Function flMultiBrowserSelected(browser,line) +Function flBrowserValue(browser) +Function flBrowserItem$z(browser,line) +Function flBrowserData:Object(browser,line) +Function flSetBrowserItem(browser,line,text$z,obj:Object=Null,img = 0) +Function flRemoveBrowserItem(browser,line) +Function flSetBrowserTextColor(browser,r,g,b) +Function flSetBrowserTextFont(browser,font) +Function flSetBrowserTextSize(browser,size) +Function flBrowserCount(browser) + +' editor + +Function flCharPosXY(textdisplay,char,x Ptr,y Ptr) + +Function flLinePos(textdisplay,line) +Function flLineStart(textdisplay,pos) +Function flLineCount(textdisplay,pos) +Function flTextLength(textdisplay) + +Function flSetWrapMode(textdisplay,bool,column) + +Function flSetText(textdisplay,text:Byte Ptr) +Function flSetEditTextColor(textdisplay,r,g,b) +Function flSetTextFont(editor,font) +Function flSetTextSize(editor,size) +Function flAddText(textdisplay,text:Byte Ptr) +Function flReplaceText(textdisplay,start,count,text:Byte Ptr) +Function flSelectText(textdisplay,start,count) +Function flFreeTextDisplay(textdisplay) +Function flShowPosition(textdisplay) +Function flRedrawText(textdisplay,start,count) +Function flGetText:Byte Ptr(textdisplay,start=0,count=-1) +Function flSetTextCallback(textdisplay,callback(pos,inserted,deleted,restyled,text:Byte Ptr,obj:Int),user:Int) +Function flSetTextTabs(textdisplay,tabs) + +Function flGetCursorPos(textdisplay) +Function flGetSelectionLen(textdisplay) + +Function flGetTextStyleChar(textdisplay,r,g,b,font,size) +Function flSetTextStyle(textdisplay,text$z) +Function flAddTextStyle(textdisplay,text$z) +Function flReplaceTextStyle(textdisplay,start,count,text$z) +Function flInsertTextStyle(textdisplay,start,text$z) +Function flDeleteTextStyle(textdisplay,start,count) + +Function flActivateText(textdisplay) + +Function flCutText(editor) +Function flCopyText(editor) +Function flPasteText(editor) + +'htmlview + +Function flSetView(view,html$z) +Function flSeekView(view,anchor$z) +Function flRedirectView(view,url$z) +Function flSetLineView(view,line) ' markcw +Function flGetLineView(view) ' markcw +Function flSetPathView(view,path$z) +Function flGetPathView$z(view) +Function flIsLinkView(view) +Function flSetStyleView(view,flag) + +' progbar + +Function flSetProgress(progbar,value#) + +' slider + +Function flSetSliderType(slider,slidertype) + +Function flSliderValue:Double(slider) +Function flSetSliderValue(slider,value:Double) +Function flSetSliderRange(slider,low:Double,hi:Double) + +Function flScrollbarValue(scrollbar) +Function flSetScrollbarValue(scrollbar,value,visible,lowest,total) + +Function flSetSpinnerMin(spinner,minimum:Double) +Function flSetSpinnerMax(spinner,maximum:Double) +Function flSetSpinnerValue(spinner,value:Double) +Function flSpinnerValue:Double(spinner) + +' canvas + +Function flCanvasWindow(canvas) +Function flSetCanvasMode(canvas,mode) + +'Function flBeginPaint(canvas) +'Function flEndPaint(canvas) + +' event + +Function flEvent() +Function flEventKey() +Function flEventdX() +Function flEventdY() +Function flEventX() +Function flEventY() +Function flEventState() +Function flEventKeys(key) +Function flEventButtons() +Function flEventButton() +Function flEventClicks() +Function flEventText$z() +Function flEventURL$z() +Function flCompose(del Ptr) + +Function flDisplayRect(x Ptr,y Ptr,w Ptr,h Ptr) + +' pointer + +Function flSetCursor(shape) + +' nodes + +Function fluRootNode( tree ) +Function fluSelectedNode( tree, index ) +Function fluInsertNode( parent, pos, text:Byte Ptr ) +Function fluAddNode( parent, text:Byte Ptr ) +Function fluRemoveNode( tree, node ) +Function fluSetNode( node, text:Byte Ptr, iconimage ) +Function fluSetNodeUserData( node, user_data ) +Function fluNodeUserData( node ) +Function fluExpandNode( node, collapse ) +Function fluSelectNode( node ) +Function fluCallbackNode( tree ) +Function fluCallbackReason( tree ) + +End Extern + +?MacOS +Extern + Function NSContentView(window) + Function NSUpdateCanvas(window) +EndExtern +? + +Const FL_READ=1 +Const FL_WRITE=4 +Const FL_EXCEPT=8 + +Const FL_FOREGROUND_COLOR = 0 +Const FL_BACKGROUND_COLOR = 49 +Const FL_BACKGROUND2_COLOR = 7 +Const FL_INACTIVE_COLOR = 8 +Const FL_SELECTION_COLOR = 15 + +Const FL_WINDOW=0 +Const FL_MENUBAR=1 +Const FL_BUTTON=2 +Const FL_CHECKBUTTON=3 +Const FL_ROUNDBUTTON=4 +Const FL_TOGGLEBUTTON=5 +Const FL_RADIOPUSHBUTTON=6 +Const FL_RETURNBUTTON=7 +Const FL_PANEL=8 +Const FL_GROUP_PANEL=9 +Const FL_INPUT=10 +Const FL_PASSWORD=11 +Const FL_TABS=12 +Const FL_GROUP=13 +Const FL_PACK=14 +Const FL_BROWSER=15 +Const FL_MULTIBROWSER=16 +Const FL_CHOICE=17 +Const FL_TEXTEDITOR=18 +Const FL_TEXTDISPLAY=19 +Const FL_HELPVIEW=20 +Const FL_BOX=21 +Const FL_TOOLBAR=22 +Const FL_PROGBAR=23 +Const FL_SLIDER=24 +Const FL_SCROLLBAR=25 +Const FL_SPINNER=26 +Const FL_CANVAS=27 +Const FL_INPUTCHOICE=28 +Const FLU_TREEBROWSER=29 +Const FL_REPEATBUTTON=30 +Const FL_MENUITEM=50 +Const FL_DESKTOP=51 +Const FL_TIMER=52 + +Const FL_HELVETICA=0 +Const FL_COURIER=4 +Const FL_TIMES=8 +Const FL_SYMBOL=12 +Const FL_SCREEN=13 +Const FL_SCREEN_BOLD=14 +Const FL_ZAPF_DINGBATS=15 + +Const FL_BOLD=1 +Const FL_ITALIC=2 + +Const FL_MENU_INACTIVE=$1 +Const FL_MENU_TOGGLE= $2 +Const FL_MENU_VALUE=$4 +Const FL_MENU_RADIO=$8 +Const FL_MENU_INVISIBLE=$10 +Const FL_SUBMENU_POINTER=$20 +Const FL_SUBMENU=$40 +Const FL_MENU_DIVIDER=$80 +Const FL_MENU_HORIZONTAL=$100 + +Const FL_NO_EVENT=0 +Const FL_PUSH=1 +Const FL_RELEASE=2 +Const FL_ENTER=3 +Const FL_LEAVE=4 +Const FL_DRAG=5 +Const FL_FOCUS=6 +Const FL_UNFOCUS=7 +Const FL_KEYDOWN=8 +Const FL_KEYUP=9 +Const FL_CLOSE=10 +Const FL_MOVE=11 +Const FL_SHORTCUT=12 +Const FL_DEACTIVATE=13 +Const FL_ACTIVATE=14 +Const FL_HIDE=15 +Const FL_SHOW=16 +Const FL_PASTE=17 +Const FL_SELECTIONCLEAR=18 +Const FL_MOUSEWHEEL=19 +Const FL_DND_ENTER=20 +Const FL_DND_DRAG=21 +Const FL_DND_LEAVE=22 +Const FL_DND_RELEASE=23 + +Const FL_WHEN_NEVER=0 +Const FL_WHEN_CHANGED=1 +Const FL_WHEN_RELEASE=4 +Const FL_WHEN_RELEASE_ALWAYS=6 +Const FL_WHEN_ENTER_KEY=8 +Const FL_WHEN_ENTER_KEY_ALWAYS=10 +Const FL_WHEN_ENTER_KEY_CHANGED=11 +Const FL_WHEN_NOT_CHANGED=2 'modifierbittodisablechanged()test + +' box types + +Const FL_NO_BOX=0 +Const FL_FLAT_BOX=1 +Const FL_UP_BOX=2 +Const FL_DOWN_BOX=3 +Const FL_UP_FRAME=4 +Const FL_DOWN_FRAME=5 +Const FL_THIN_UP_BOX=6 +Const FL_THIN_DOWN_BOX=7 +Const FL_THIN_UP_FRAME=8 +Const FL_THIN_DOWN_FRAME=9 +Const FL_ENGRAVED_BOX=10 +Const FL_EMBOSSED_BOX=11 +Const FL_ENGRAVED_FRAME=12 +Const FL_EMBOSSED_FRAME=13 +Const FL_BORDER_BOX=14 +Const FL_SHADOW_BOX=15 +Const FL_BORDER_FRAME=16 +Const FL_SHADOW_FRAME=17 +Const FL_ROUNDED_BOX=18 +Const FL_RSHADOW_BOX=19 +Const FL_ROUNDED_FRAME=20 +Const FL_RFLAT_BOX=21 +Const FL_ROUND_UP_BOX=22 +Const FL_ROUND_DOWN_BOX=23 +Const FL_DIAMOND_UP_BOX=24 +Const FL_DIAMOND_DOWN_BOX=25 +Const FL_OVAL_BOX=26 +Const FL_OSHADOW_BOX=27 +Const FL_OVAL_FRAME=28 +Const FL_OFLAT_BOX=29 +Const FL_PLASTIC_UP_BOX=30 +Const FL_PLASTIC_DOWN_BOX=31 +Const FL_PLASTIC_UP_FRAME=32 +Const FL_PLASTIC_DOWN_FRAME=33 +Const FL_PLASTIC_THIN_UP_BOX=34 +Const FL_PLASTIC_THIN_DOWN_BOX=35 +Const FL_FREE_BOXTYPE=36 + +' alignment flags + +Const FL_ALIGN_CENTER=0 +Const FL_ALIGN_TOP=1 +Const FL_ALIGN_BOTTOM=2 +Const FL_ALIGN_LEFT=4 +Const FL_ALIGN_RIGHT=8 +Const FL_ALIGN_INSIDE=16 +Const FL_TEXT_OVER_IMAGE=32 +Const FL_IMAGE_OVER_TEXT=0 +Const FL_ALIGN_CLIP=64 +Const FL_ALIGN_WRAP=128 +Const FL_ALIGN_TOP_LEFT = FL_ALIGN_TOP | FL_ALIGN_LEFT +Const FL_ALIGN_TOP_RIGHT = FL_ALIGN_TOP | FL_ALIGN_RIGHT +Const FL_ALIGN_BOTTOM_LEFT = FL_ALIGN_BOTTOM | FL_ALIGN_LEFT +Const FL_ALIGN_BOTTOM_RIGHT = FL_ALIGN_BOTTOM | FL_ALIGN_RIGHT +Const FL_ALIGN_LEFT_TOP = FL_ALIGN_TOP_LEFT +Const FL_ALIGN_RIGHT_TOP = FL_ALIGN_TOP_RIGHT +Const FL_ALIGN_LEFT_BOTTOM = FL_ALIGN_BOTTOM_LEFT +Const FL_ALIGN_RIGHT_BOTTOM = FL_ALIGN_BOTTOM_RIGHT +Const FL_ALIGN_NOWRAP = 0 + +'labeltype flags + +Const FL_NORMAL_LABEL = 0 +Const FL_NO_LABEL = 1 +Const FL_SHADOW_LABEL = 2 +Const FL_ENGRAVED_LABEL = 3 +Const FL_EMBOSSED_LABEL = 4 +Const FL_ICON_LABEL = 5 +Const FL_IMAGE_LABEL = 6 + +' mouse event buttons + +Const FL_LEFT_MOUSE=1 +Const FL_MIDDLE_MOUSE=2 +Const FL_RIGHT_MOUSE=3 + +' event states + +Const FL_SHIFT=$00010000 +Const FL_CAPS_LOCK=$00020000 +Const FL_CTRL=$00040000 +Const FL_ALT=$00080000 +Const FL_NUM_LOCK=$00100000 'mostXserversdothis? +Const FL_META=$00400000 'correctforXFree86 +Const FL_SCROLL_LOCK=$00800000 'correctforXFree86 +Const FL_BUTTON1=$01000000 +Const FL_BUTTON2=$02000000 +Const FL_BUTTON3=$04000000 +Const FL_BUTTONS=$7f000000 'Allpossiblebuttons + +' extended keys + +Const FL_KEY_Button=$fee8 'useFL_KEY_Button+FL_KEY_*_MOUSE +Const FL_KEY_BackSpace=$ff08 +Const FL_KEY_Tab=$ff09 +Const FL_KEY_Enter=$ff0d +Const FL_KEY_Pause=$ff13 +Const FL_KEY_Scroll_Lock=$ff14 +Const FL_KEY_Escape=$ff1b +Const FL_KEY_Home=$ff50 +Const FL_KEY_Left=$ff51 +Const FL_KEY_Up=$ff52 +Const FL_KEY_Right=$ff53 +Const FL_KEY_Down=$ff54 +Const FL_KEY_Page_Up=$ff55 +Const FL_KEY_Page_Down=$ff56 +Const FL_KEY_End=$ff57 +Const FL_KEY_Print=$ff61 +Const FL_KEY_Insert=$ff63 +Const FL_KEY_Menu=$ff67 'the"menu/apps"keyonXFree86 +Const FL_KEY_Help=$ff68 'the'help'keyonMackeyboards +Const FL_KEY_Num_Lock=$ff7f +Const FL_KEY_KP=$ff80 'useFL_KEY_KP+'x'for'x'onnumerickeypad +Const FL_KEY_KP_Enter=$ff8d 'sameasFL_KEY_KP+'\r' +Const FL_KEY_KP_Last=$ffbd 'usetorange-checkkeypad +Const FL_KEY_F=$ffbd 'useFL_KEY_F+nforfunctionkeyn +Const FL_KEY_F_Last=$ffe0 'usetorange-checkfunctionkeys +Const FL_KEY_Shift_L=$ffe1 +Const FL_KEY_Shift_R=$ffe2 +Const FL_KEY_Control_L=$ffe3 +Const FL_KEY_Control_R=$ffe4 +Const FL_KEY_Caps_Lock=$ffe5 +Const FL_KEY_Meta_L=$ffe7 'theleftMSWindowskeyonXFree86 +Const FL_KEY_Meta_R=$ffe8 'therightMSWindowskeyonXFree86 +Const FL_KEY_Alt_L=$ffe9 +Const FL_KEY_Alt_R=$ffea +Const FL_KEY_Delete=$ffff + +' slider types + +Const FL_VERT_SLIDER=0 +Const FL_HOR_SLIDER=1 +Const FL_VERT_FILL_SLIDER=2 +Const FL_HOR_FILL_SLIDER=3 +Const FL_VERT_NICE_SLIDER=4 +Const FL_HOR_NICE_SLIDER=5 + +' flu constants + +Const FLU_NO_SELECT = 0 +Const FLU_SINGLE_SELECT = 1 +Const FLU_MULTI_SELECT = 2 + +Const FLU_INSERT_FRONT = 0 +Const FLU_INSERT_BACK = 1 +Const FLU_INSERT_SORTED = 2 +Const FLU_INSERT_SORTED_REVERSE = 3 + +Const FLU_DRAG_IGNORE = 0 +Const FLU_DRAG_TO_SELECT = 1 +Const FLU_DRAG_TO_MOVE = 2 + +Const FLU_HILIGHTED = 0 +Const FLU_UNHILIGHTED = 1 +Const FLU_SELECTED = 2 +Const FLU_UNSELECTED = 3 +Const FLU_OPENED = 4 +Const FLU_CLOSED = 5 +Const FLU_DOUBLE_CLICK = 6 +Const FLU_WIDGET_CALLBACK = 7 +Const FLU_MOVED_NODE = 8 +Const FLU_NEW_NODE = 9 +Const FLU_NOTHING = 10 diff --git a/mod/maxgui.mod/fltkmaxgui.mod/fltkfonts.bmx b/mod/maxgui.mod/fltkmaxgui.mod/fltkfonts.bmx new file mode 100644 index 0000000..b735b4a --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/fltkfonts.bmx @@ -0,0 +1,382 @@ +Strict + +Import MaxGUI.MaxGUI +Import "fltkimports.bmx" +Private +Include "fltkdecls.bmx" +Public + +Type TFLGUIFont Extends TGUIFont + + Field flfamily:TFLFontFamily + + Function LoadFont:TFLGUIFont( name$,height:Double,flags ) + Local tmpFLGUIFont:TFLGUIFont = New TFLGUIFont.SetFont(name,height,flags) + tmpFLGUIFont.Initialize() + Return tmpFLGUIFont + EndFunction + + Method SetFont:TFLGUIFont( name$,height:Double,flags ) + Self.name = name + Self.style = flags + Self.size = height + Return Self + EndMethod + + Method CharWidth( charcode ) + Return 0 + EndMethod + + Method GetSizeForFl:Double() + ?Win32 + Return size+2 + ?Not Win32 + Return size + ? + EndMethod + + Method Initialize() + flfamily = TFLFontFamily.GetFamily( name ) + handle = flfamily.GetFontID(style) + EndMethod + + 'Sort by family name, then by size and finally by style. + Method Compare( o:Object ) + Local f:TFLGUIFont = TFLGUIFont(o) + If Not f Then Return Super.Compare(o) + Local tmpComparison% = flFamily.Compare(f.flfamily) + If tmpComparison Then Return tmpComparison + If (size = f.size) Then + Return (style-f.style) + Else + Return (size-f.size) + EndIf + EndMethod + +EndType + +Type TFLFontFamily + + Const IDSTYLEMASK% = (FL_BOLD|FL_ITALIC) + + Global arrFamilies:TFLFontFamily[], intLoadedAll% = False + Global defaultSizes:Int[] = [8, 10, 11, 12, 14, 16, 18, 20, 24, 32, 36, 42, 48, 64, 72] + + Global fmyDefault:TFLFontFamily + + Field strName$, strLowName$, intSizes[], intStyles, ids[IDSTYLEMASK+1] + + Function Initialize() + fmyDefault = TFLFontFamily.GetFamily( TFLFontFamily.FriendlyNameFromID( FL_HELVETICA ) ) + EndFunction + + Function GetFamily:TFLFontFamily( name$ ) + Local tmpFamily:TFLFontFamily = LoadFamily( name$ ) + If tmpFamily Then Return tmpFamily Else Return fmyDefault + EndFunction + + Function FindFamily:TFLFontFamily( name$ ) + name = name.ToLower() + For Local tmpFamily:TFLFontFamily = EachIn arrFamilies + If name = tmpFamily.strLowName Then Return tmpFamily + Next + EndFunction + + Function LoadAll:TFLFontFamily[]() + Local tmpLastName$ = "", tmpFamily:TFLFontFamily + If Not intLoadedAll Then intLoadedAll = True Else Return arrFamilies + For Local id=0 Until flCountFonts() + Local f$=FriendlyNameFromID(id) + If f <> tmpLastName Then + tmpFamily = FindFamily( f ) + If Not tmpFamily Then + tmpFamily = FamilyFromSingleID(id) + EndIf + EndIf + Local tmpStyle% = StyleFromID(id) + tmpFamily.intStyles:|tmpStyle + tmpFamily.ids[tmpStyle] = id + tmpLastName = f + Next + + arrFamilies.Sort() + + Return arrFamilies + EndFunction + + Function LoadFamily:TFLFontFamily( name$ ) + + Local tmpFamily:TFLFontFamily = FindFamily( name$ ) + If tmpFamily Then Return tmpFamily + + name = name.ToLower() + + For Local id=0 Until flCountFonts() + Local f$=FriendlyNameFromID(id).ToLower() + If f = name Then + If Not tmpFamily Then tmpFamily = FamilyFromSingleID(id) + Local tmpStyle% = StyleFromID(id) + tmpFamily.intStyles:|tmpStyle + tmpFamily.ids[tmpStyle] = id + EndIf + Next + + arrFamilies.Sort() + + Return tmpFamily + + EndFunction + + Function FamilyFromSingleID:TFLFontFamily(id) + Local tmpFamily:TFLFontFamily = New TFLFontFamily + tmpFamily.strName = FriendlyNameFromID(id) + tmpFamily.strLowName = tmpFamily.strName.ToLower() + Local tmpSizes:Int + For Local i% = 0 Until flFontSizes(id,Varptr tmpSizes) + If i = 0 And Int Ptr(tmpSizes)[i] = 0 Then + tmpFamily.intSizes = defaultSizes + Exit + EndIf + tmpFamily.intSizes:+[Int Ptr(tmpSizes)[i]] + Next + arrFamilies:+[tmpFamily] + Return tmpFamily + EndFunction + + Function NameFromID$(id) + Return flFontName(id) + End Function + + Function FriendlyNameFromID$(id) + Local tmpName$ = flFriendlyFontName(id) + If tmpName.EndsWith(" bold") Then tmpName = tmpName[..tmpName.length-5] + If tmpName.EndsWith(" bold italic") Then tmpName = tmpName[..tmpName.length-12] + If tmpName.EndsWith(" italic") Then tmpName = tmpName[..tmpName.length-7] + Return tmpName + End Function + + Function StyleFromID(id) + Return flFriendlyFontAttributes(id) + EndFunction + + Method GetFontID(style) + style:&IDSTYLEMASK + If (intStyles&style)=style Then Return ids[style] + For Local id = EachIn ids + If id Then Return id + Next + End Method + + Method GetFamilySizes:Int[]() + Return intSizes + EndMethod + + Method Compare( o:Object ) + Local f:TFLFontFamily=TFLFontFamily(o) + If Not f Then Return Super.Compare(o) + Return strLowName.Compare( f.strLowName ) + End Method + +End Type + +Type TFLFontRequest + Field open, currentfont:TFLGUIFont + + Field window:TGadget + Field fontbox:TGadget,stylebox:TGadget,sizebox:TGadget,sizetext:TGadget,samplebox:TGadget + Field ok:TGadget,cancel:TGadget + + Method New() + Initialize() + EndMethod + + Method Refresh(font:TFLGUIFont) + SetFamily( font.flfamily ) + SetStyle( font.style ) + SetSize( Int(font.size) ) + SetGadgetFont samplebox, font + End Method + + Field currentSize% = -1 + + Method GetSize() + If currentSize < 0 Then Return 12 Else Return currentSize + EndMethod + + Method SetSize( size% ) + currentSize = size + SetGadgetText( sizetext, size ) + For Local i% = CountGadgetItems( sizebox )-1 To 0 Step -1 + If Int(GadgetItemText( sizebox, i )) = size Then + SelectGadgetItem sizebox, i + Return + EndIf + Next + If SelectedGadgetItem( sizebox ) > -1 Then DeselectGadgetItem( sizebox, SelectedGadgetItem ( sizebox ) ) + EndMethod + + Field currentStyle% = -1 + + Method GetStyle() + Return Max( currentStyle, FONT_NORMAL ) + EndMethod + + Method SetStyle( style% ) + currentStyle = style + If SelectedGadgetItem( styleBox ) <> currentStyle Then + If currentStyle < 0 Then DeselectGadgetItem( stylebox, SelectedGadgetItem( stylebox ) ) Else SelectGadgetItem( stylebox, Min(currentStyle, CountGadgetItems( stylebox )-1 ) ) + EndIf + EndMethod + + Method GetFont:TFLGUIFont() + Local tmpFamily:TFLFontFamily = GetFamily() + Local tmpFont:TFLGUIFont = New TFLGUIFont.SetFont( tmpFamily.strName, GetSize(), GetStyle() ) + tmpFont.flfamily = tmpFamily;tmpFont.handle = tmpFamily.GetFontID(GetStyle()) + Return tmpFont + End Method + + Method GetFamily:TFLFontFamily() + Local tmpFamily:TFLFontFamily = TFLFontFamily.fmyDefault + If SelectedGadgetItem(fontbox) > -1 Then + tmpFamily = TFLFontFamily ( GadgetItemExtra( fontbox, SelectedGadgetItem( fontbox ) ) ) + EndIf + Return tmpFamily + EndMethod + + Method SetFamily( family:TFLFontFamily ) + For Local i% = 0 Until CountGadgetItems( fontbox ) + Local tmpItemFamily:TFLFontFamily = TFLFontFamily(GadgetItemExtra( fontbox, i )) + If tmpItemFamily = family Then + SelectGadgetItem fontbox, i + + ClearGadgetItems stylebox + AddGadgetItem stylebox, "Regular", 0, -1, "", String(FONT_NORMAL) + If family.intStyles&FONT_BOLD Then AddGadgetItem stylebox, "Bold", 0, -1, "", String(FONT_BOLD) + If family.intStyles&FONT_ITALIC Then AddGadgetItem stylebox, "Italic", 0, -1, "", String(FONT_ITALIC) + If (family.intStyles&(FONT_ITALIC|FONT_BOLD))=FONT_BOLD|FONT_ITALIC Then + AddGadgetItem stylebox, "Bold & Italic", 0, -1, "", String(FONT_BOLD|FONT_ITALIC) + EndIf + currentStyle = Min(currentStyle,family.intStyles) + + ClearGadgetItems sizebox + For Local tmpSize% = EachIn family.intSizes + AddGadgetItem sizebox, tmpSize + Next + + Return + EndIf + Next + EndMethod + + Function RequestHandler:Object(id,data:Object,context:Object) + Local this:TFLFontRequest + Local event:TEvent + event=TEvent(data) + If event + this=TFLFontRequest(context) + If this this.OnEvent event + EndIf + End Function + + Method OnEvent(event:TEvent) + Local item = event.data + Select event.id + Case EVENT_GADGETSELECT, EVENT_GADGETACTION + Select event.source + Case fontbox + SetFamily TFLFontFamily(event.extra) + Refresh(GetFont()) + Case stylebox + If event.data < 0 Then + currentStyle = -1 + Else + currentStyle = Int( String( GadgetItemExtra( stylebox, event.data ) ) ) + EndIf + Refresh(GetFont()) + Case sizebox + If event.data < 0 Then + currentSize = -1 + Else + currentSize = Int( GadgetItemText( sizebox, event.data ) ) + EndIf + Refresh(GetFont()) + Case cancel + currentfont = Null + open=False + Case ok + currentfont = GetFont() + open=False + End Select + Case EVENT_GADGETLOSTFOCUS + Select event.source + Case sizetext + Local tmpText$ = GadgetText(sizetext) + If tmpText Then + Local tmpInt% = Max(Int( tmpText ), 0) + If tmpInt = tmpText Then + currentSize = tmpInt + Refresh(GetFont()) + EndIf + EndIf + End Select + Case EVENT_WINDOWCLOSE + Select event.source + Case window + currentfont = Null + open=False + EndSelect + EndSelect + End Method + + Method Request:TFLGUIFont(font:TFLGUIFont) + open=True;currentfont = Null + AddHook EmitEventHook,RequestHandler,Self,100000 + Local tmpParent:TGadget = ActiveGadget() + While tmpParent And tmpParent.Class() <> GADGET_WINDOW + tmpParent = GadgetGroup(tmpParent) + Wend + If Not tmpParent Then tmpParent = Desktop() + SetGadgetShape( window, GadgetX(tmpParent)+50, GadgetY(tmpParent)+50, ClientWidth(window), ClientHeight(window) ) + ShowGadget window + If font Then Refresh(font) + While open + WaitSystem() + Wend + RemoveHook EmitEventHook,RequestHandler,Self + HideGadget window + Return currentfont + End Method + + Method Initialize() + window=CreateWindow("Choose a font...",0,0,392,284,Null,WINDOW_TITLEBAR|WINDOW_HIDDEN|WINDOW_CLIENTCOORDS|WINDOW_CENTER) + flSetModal(QueryGadget(window,QUERY_FLWIDGET)) + CreateLabel "Font:",4,4,200,24,window + fontbox=CreateListBox(4,28,200,ClientHeight(window)-134,window) + CreateLabel "Style:",214,4,100,24,window + stylebox=CreateListBox(214,28,100,ClientHeight(window)-134,window) + CreateLabel "Size:",324,4,64,24,window + sizetext=CreateTextField(324,28,64,21,window) + sizebox=CreateListBox(324,49,64,ClientHeight(window)-155,window) + SetGadgetFilter(sizetext,NumberFilter) + Local y=ClientHeight(window)-102 + samplebox=CreateLabel("Sample Text",4,y,ClientWidth(window)-8,64,window,LABEL_CENTER|LABEL_SUNKENFRAME) + cancel=CreateButton("Cancel",4,ClientHeight(window)-30,80,26,window,BUTTON_CANCEL) + ok=CreateButton("OK",ClientWidth(window)-4-80,ClientHeight(window)-30,80,26,window,BUTTON_OK) + For Local tmpFamily:TFLFontFamily = EachIn TFLFontFamily.LoadAll() + AddGadgetItem fontbox,tmpFamily.strName, 0, -1, "", tmpFamily + Next + End Method + + Function NumberFilter( event:TEvent, context:Object ) + Select event.id + Case EVENT_KEYCHAR + If (event.data > "9"[0] Or event.data < "0"[0]) And (event.data <> 8) Then + Return False + Else + Return True + EndIf + EndSelect + Return True + EndFunction + +EndType diff --git a/mod/maxgui.mod/fltkmaxgui.mod/fltkglue.cpp b/mod/maxgui.mod/fltkmaxgui.mod/fltkglue.cpp new file mode 100644 index 0000000..117857d --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/fltkglue.cpp @@ -0,0 +1,2056 @@ +//fltkglue.cpp + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#if __linux +#include +#define __usexpm 1 + +#if __usexpm + #include +#endif + +#endif + +enum fltypes +{ + FLWINDOW,FLMENUBAR,FLBUTTON,FLCHECKBUTTON,FLROUNDBUTTON,FLTOGGLEBUTTON,FLRADIOPUSHBUTTON, + FLRETURNBUTTON,FLPANEL,FLGROUPPANEL,FLINPUT,FLPASSWORD, + FLTABS,FLGROUP,FLPACK,FLBROWSER,FLMULTIBROWSER,FLCHOICE, + FLTEXTEDITOR,FLTEXTDISPLAY,FLHELPVIEW,FLBOX,FLTOOLBAR,FLPROGBAR,FLSLIDER,FLSCROLLBAR, + FLSPINNER,FLCANVAS,FLINPUTCHOICE,FLUTREEBROWSER,FLREPEATBUTTON +}; + +class Fl_AWindow; +class Fl_Panel; +class Fl_Canvas; +class Fl_ATabs; + +// system + +const char *event_url = "none"; +char *redirect_url = 0; // init to null - markcw + +int eventid; + +const char *viewcallback(Fl_Widget *view, const char *uri) +{ + free(redirect_url); + redirect_url = 0; + event_url = uri; + view->do_callback(); + event_url = 0; + return (const char *)redirect_url; +} + +extern "C" +{ +void flReset( void *display,int(*eventhandler)(int),int(*textfilter)(void*),int(*mousecallback)(Fl_Widget*,void*),int(*keycallback)(Fl_Widget*,void*)); +void flAddFd( int fd, int when, void (*cb)(int, void*), void* argument = 0){return Fl::add_fd( fd, when, (*cb), argument);} +int flCountFonts(); +int flRun() {return Fl::run();} +void flFlush() {Fl::check();} //Seb was here - we should use check() instead of flush() +unsigned flGetColor( Fl_Color i ){return Fl::get_color( i );} +int flHandle(void *evt) { + #if __linux + return fl_handle(*(XEvent*)evt); + #endif +} +void flWait(int timeout) +{ + if (timeout<0) Fl::wait(); else Fl::wait(.001*timeout); +} + +const char *flFontName(Fl_Font i); +int flFontSizes(int font,int *& size); +const char *flFriendlyFontName(Fl_Font i); +int flFriendlyFontAttributes(Fl_Font i); + +int flChooseColor(const char *title, uchar &r, uchar &g, uchar &b) {return fl_color_chooser(title,r,g,b);} + +void flSetBelowMouse(Fl_Widget* widget); + +// requesters + +int flRequest(const char *text,int flags); +char *flRequestFile(const char * message,const char *pattern,const char *path,int save); +char *flRequestDir(const char* message,const char *path,int relative); + +void flAddTimeout(double t,void(*callback)(void*),void *user); + +// widgets + +Fl_Widget *flWidget(int x,int y,int w,int h,char *name,int type); +void flFreeWidget(Fl_Widget*widget); +void flDelete(void* pointer); +void flFreePtr(void* pointer); +void* flUserData(Fl_Widget*widget); +void flSetArea(Fl_Widget*widget,int x,int y,int w,int h); +void flGetArea(Fl_Widget*widget,int *x,int *y,int *w,int *h); +void flSetLabel(Fl_Widget*widget,char*label); +void flSetLabelColor(Fl_Widget*widget, int r, int g, int b); +void flSetLabelFont(Fl_Widget*widget,Fl_Font s); +void flSetLabelSize(Fl_Widget*widget,Fl_Fontsize s); +void flSetBox(Fl_Widget*widget,int boxtype,int redrawifneeded); +void flSetLabelType(Fl_Widget*widget,Fl_Labeltype labeltype); +const char *flGetLabel(Fl_Widget *widget); +void flSetAlign(Fl_Widget*widget,int aligntype); +int flAlign(Fl_Widget*widget); + +void flSetColor(Fl_Widget*widget,int r,int g,int b); +void flRemoveColor(Fl_Widget*widget); +void flSetFocus(Fl_Widget*widget); +void *flGetFocus(); +void flSetWhen(Fl_Widget*,Fl_When); +Fl_When flGetWhen(Fl_Widget*); +void *flGetUser(Fl_Widget*); +void flSetShow(Fl_Widget*widget,int truefalse); +void flSetCallback(Fl_Widget*,void(*callback)(Fl_Widget*,void*),void *user); +void flSetToolTip(Fl_Widget*widget, char* tip); + +void flSetActive(Fl_Widget*widget,int truefalse); +Fl_Window* flWidgetWindow(Fl_Widget* widget); + +Fl_Widget* flPushed(); +void flSetPushed(Fl_Widget*widget); +void flRedraw(Fl_Widget*widget); +int flWidth(Fl_Widget*widget); +int flHeight(Fl_Widget*widget); +int flVisible(Fl_Widget*widget); +int flChanged(Fl_Widget*widget); +void flClearChanged(Fl_Widget*widget); + +void flSetWindowLabel(Fl_Window*window,char*label); +void flSetWindowIcon(Fl_Window*window, char** icon); +void flClearBorder(Fl_Window*window); +void flShowWindow(Fl_Window*widget,int falsetrueiconize); +void flDestroyWindow(Fl_Window*widget); +void flSetMinWindowSize(Fl_AWindow*window,int w,int h); +void flSetMaxWindowSize(Fl_AWindow*window,int w,int h); +void flSetAcceptsFiles(Fl_AWindow*window, int enable ); +void flSetNonModal(Fl_AWindow*window); +void flSetModal(Fl_AWindow*window); + +void flBegin(Fl_Group*group); +void flEnd(Fl_Group*group); +void flAddToGroup(Fl_Group*group,Fl_Widget*widget); +void flRemoveFromGroup(Fl_Group*group,Fl_Widget*widget); + +void flSetMenu(Fl_Menu_ *,void *menu); +void *flCreateMenu(int n,void(*callback)(Fl_Widget*,void*)); +void flSetMenuItem(Fl_Menu_Item* menu,int item,char *name,int shortcut,void *user,int flags, Fl_Font fonthandle, Fl_Fontsize fontsize); +void *flPopupMenu(Fl_Menu_Item *menuitem,void *n); + +void flSelectTab(Fl_Tabs*,Fl_Widget*); +int flGetTabPanel(Fl_Tabs *tab); +void *flGetTabPanelForEvent(Fl_ATabs *tab); + +void flSetInputChoice(Fl_Input_Choice*,int value); +void *flGetInputChoiceTextWidget(Fl_Input_Choice*); +void *flGetInputChoiceMenuWidget(Fl_Input_Choice*); + +void flSetChoice(Fl_Choice*,int value); +int flGetChoice(Fl_Choice*); + +void flSetButton(Fl_Button*,bool value); +int flGetButton(Fl_Button*); +void flSetButtonKey(Fl_Button*,int key); + +void flSetInput(Fl_Input*,char*value); +const char *flGetInput(Fl_Input*); +void flActivateInput(Fl_Input*); +void flSetInputFont(Fl_Input*input,Fl_Font s); +void flSetInputSize(Fl_Input*input,Fl_Fontsize s); + +void flClearBrowser(Fl_Browser*); +void flAddBrowser(Fl_Browser*,const char *label,void *obj, Fl_Image* icon); +void flInsertBrowser(Fl_Browser*,int index,const char *label,void *obj, Fl_Image* icon); +void flShowBrowser(Fl_Browser*,int line,int show); +void flSelectBrowser(Fl_Hold_Browser*,int line); +void flMultiBrowserSelect(Fl_Multi_Browser *browse,int line,int select); +int flMultiBrowserSelected(Fl_Multi_Browser *browse,int line); +int flBrowserValue(Fl_Hold_Browser*); +void *flBrowserData(Fl_Hold_Browser*,int line); +const char *flBrowserItem(Fl_Hold_Browser*,int line); +void flSetBrowserItem(Fl_Hold_Browser*,int line,char *text,void *obj, Fl_Image* icon); +void flRemoveBrowserItem(Fl_Hold_Browser*,int line); +void flSetBrowserTextColor(Fl_Hold_Browser *browse,int r,int g,int b); +void flSetBrowserTextFont(Fl_Hold_Browser *browse,Fl_Font s); +void flSetBrowserTextSize(Fl_Hold_Browser *browse,Fl_Fontsize s); +int flBrowserCount(Fl_Hold_Browser *browse); + +void flCharPosXY(Fl_Text_Display *textdisplay, int charpos, int *x, int *y); +int flLinePos(Fl_Text_Display *textdisplay,int line); +int flLineStart(Fl_Text_Display *textdisplay,int pos); +int flLineCount(Fl_Text_Display *textdisplay,int pos); +int flTextLength(Fl_Text_Display *textdisplay); +void flSetWrapMode(Fl_Text_Display *textdisplay, int mode, int col); + +void flAddText(Fl_Text_Display *textdisplay,char *text); +void flReplaceText(Fl_Text_Display *textdisplay,int start,int count,char *text); +void flSelectText(Fl_Text_Display *textdisplay,int start,int count); +void flShowPosition(Fl_Text_Display *textdisplay); +void flSetText(Fl_Text_Display *textdisplay,char *text); +char *flGetText(Fl_Text_Display *textdisplay,int start,int count); +void flRedrawText(Fl_Text_Display *textdisplay,int start,int count); + +void flSetEditTextColor(Fl_Text_Display *textdisplay,int r,int g,int b); +void flSetTextFont(Fl_Text_Display *textdisplay,Fl_Font s); +void flSetTextSize(Fl_Text_Display *textdisplay,Fl_Fontsize s); +void flSetTextCallback(Fl_Text_Display *textdisplay,void(*callback)(int,int,int,int,const char*,void*),void *user); +void flSetTextTabs(Fl_Text_Display *textdisplay,int tabs); +void flActivateText(Fl_Text_Display *textdisplay); + +int flGetCursorPos(Fl_Text_Display *textdisplay); +int flGetSelectionLen(Fl_Text_Display *textdisplay); + +int flGetTextStyleChar(Fl_Text_Display *textdisplay,int r,int g,int b,Fl_Font font,Fl_Fontsize size); +void flSetTextStyle(Fl_Text_Display *textdisplay,char *text); +void flAddTextStyle(Fl_Text_Display *textdisplay,char *text); +void flReplaceTextStyle(Fl_Text_Display *textdisplay,int start,int count,char *text); +void flInsertTextStyle(Fl_Text_Display *textdisplay,int start,char *text); +void flDeleteTextStyle(Fl_Text_Display *textdisplay,int start,int count); +void* flFreeTextDisplay(Fl_Text_Display *textdisplay); + +void flCutText(Fl_Text_Editor *editor); +void flCopyText(Fl_Text_Editor *editor); +void flPasteText(Fl_Text_Editor *editor); + +void flSetView(Fl_Help_View *view, const char *html); +void flSeekView(Fl_Help_View *view, const char *anchor); +void flRedirectView(Fl_Help_View *view, char *url); +void flSetLineView(Fl_Help_View *view, int line); +int flGetLineView(Fl_Help_View *view); +void flSetPathView(Fl_Help_View *view, const char *path); +char *flGetPathView(Fl_Help_View *view); +int flIsLinkView(Fl_Help_View *view); +void flSetStyleView(Fl_Help_View *view, int flag); + +void flSetProgress(Fl_Progress*,float val); + +Fl_RGB_Image *flImage(const unsigned char *pix,int w,int h,int d,int ld); +void flSetImage( Fl_Widget *widget, Fl_RGB_Image *image ); +void flFreeImage( Fl_Image *image ); +void flSetPanelColor(Fl_Panel *panel,int r,int g,int b); +void flSetPanelImage(Fl_Panel *panel,Fl_RGB_Image *image,int flags); +void flSetPanelActive(Fl_Panel *panel,int yesno); +void flSetPanelEnabled(Fl_Panel *panel,int yesno); + +void flSetSliderType(Fl_Slider *slider,int type); +double flSliderValue(Fl_Slider *slider); +void flSetSliderValue(Fl_Slider *slider,double value); +void flSetSliderRange(Fl_Slider *slider,double low,double hi); + +int flScrollbarValue(Fl_Scrollbar *scrollbar); +void flSetScrollbarValue(Fl_Scrollbar *scrollbar,int value,int visible,int top, int total); + +void flSetSpinnerMin(Fl_Spinner* spinner, double min); +void flSetSpinnerMax(Fl_Spinner* spinner, double max); +void flSetSpinnerValue(Fl_Spinner* spinner, double value); +double flSpinnerValue(Fl_Spinner* spinner); + +int flEvent() {if (eventid) return eventid;else return Fl::event();} +int flEventKey() {return Fl::event_key();} +int flEventX() {return Fl::event_x();} +int flEventY() {return Fl::event_y();} +int flEventdX() {return Fl::event_dx();} +int flEventdY() {return Fl::event_dy();} +int flEventState() {return Fl::event_state();} +int flEventKeys(int key) {return Fl::event_key(key);} +int flEventButtons() {return Fl::event_buttons()>>24;} +int flEventButton() {return Fl::event_button();} +int flEventClicks() {return Fl::event_clicks();} +const char *flEventText() {return Fl::event_text();} +int flCompose(int &del){return Fl::compose(del);} +const char *flEventURL() {return event_url;} + +void flDisplayRect(int*x,int*y,int*w,int*h); +void flSetCursor(int shape); + +int flCanvasWindow(Fl_Canvas *canvas); +void flSetCanvasMode(Fl_Canvas *canvas,int mode); + +void* fluRootNode( Flu_Tree_Browser* tree ); +void* fluSelectedNode( Flu_Tree_Browser* tree, int index ); +void* fluInsertNode( Flu_Tree_Browser::Node* parent, int pos, const char* text ); +void* fluAddNode( Flu_Tree_Browser::Node* parent, const char* text ); +void fluRemoveNode( Flu_Tree_Browser* tree, Flu_Tree_Browser::Node* node ); +void fluSetNode( Flu_Tree_Browser::Node* node, const char* text, Fl_RGB_Image* iconimage ); +void fluSetNodeUserData( Flu_Tree_Browser::Node* node, void* user_data ); +void* fluNodeUserData( Flu_Tree_Browser::Node* node ); +void fluExpandNode( Flu_Tree_Browser::Node* node, int collapse ); +void fluSelectNode( Flu_Tree_Browser::Node* node ); +void* fluCallbackNode( Flu_Tree_Browser* tree ); +int fluCallbackReason( Flu_Tree_Browser* tree ); + +}; + +void flSetCursor(int shape) +{ + Fl_Cursor cursor=FL_CURSOR_DEFAULT; + switch (shape) + { + case POINTER_ARROW:cursor=FL_CURSOR_ARROW;break; + case POINTER_IBEAM:cursor=FL_CURSOR_INSERT;break; + case POINTER_WAIT:cursor=FL_CURSOR_WAIT;break; + case POINTER_CROSS:cursor=FL_CURSOR_CROSS;break; + case POINTER_UPARROW:cursor=FL_CURSOR_N;break; + case POINTER_SIZENWSE:cursor=FL_CURSOR_NWSE;break; + case POINTER_SIZENESW:cursor=FL_CURSOR_NESW;break; + case POINTER_SIZEWE:cursor=FL_CURSOR_WE;break; + case POINTER_SIZENS:cursor=FL_CURSOR_NS;break; + case POINTER_SIZEALL:cursor=FL_CURSOR_MOVE;break; + case POINTER_NO:cursor=FL_CURSOR_NONE;break; + case POINTER_HAND:cursor=FL_CURSOR_HAND;break; + case POINTER_APPSTARTING:cursor=FL_CURSOR_WAIT;break; + case POINTER_HELP:cursor=FL_CURSOR_HELP;break; + } + fl_cursor(cursor); +} + +char *stringcopy(const char *l) +{ + char *c; + int n; + if (!l) return 0; + n=strlen(l); + c=(char*)malloc(n+1); + strcpy(c,l); + return c; +} + +int maxfonts; + +int(*mousehandler)(Fl_Widget*,void*); +int(*keyhandler)(Fl_Widget*,void*); +int(*syshandler)(int); +int(*textfilter)(void*); + +void flReset(void *display,int(*handler)(int),int(*filter)(void*),int(*msehandler)(Fl_Widget*,void*),int(*kyhandler)(Fl_Widget*,void*)) +{ + Fl::visual(FL_RGB|FL_DOUBLE); + + #if __linux + fl_open_display((Display*)display); + #endif + + //Set default font sizes + FL_NORMAL_SIZE = 12; + fl_message_font( FL_HELVETICA, FL_NORMAL_SIZE ); + Fl_Tooltip::size( FL_NORMAL_SIZE ); + + fl_register_images(); + Fl::scheme("gtk+"); + if (handler) + { + Fl::add_handler(handler); + syshandler=handler; + } + textfilter=filter; + mousehandler = msehandler; + keyhandler = kyhandler; + maxfonts=Fl::set_fonts(0); + Fl::get_system_colors(); +} + +int flCountFonts() {return ((maxfonts < FL_FREE_FONT) ? FL_FREE_FONT-1 : maxfonts);} + +const char *flFontName(Fl_Font i) +{ + if (i<0 || i>=maxfonts) return ""; + return Fl::get_font((Fl_Font)i); +} + +const char *flFriendlyFontName(Fl_Font i) +{ + int attributes; + if (i<0 || i>=maxfonts) return ""; + attributes = 0; + return Fl::get_font_name(i, &attributes); +} + +int flFriendlyFontAttributes(Fl_Font i) +{ + int attributes; + if (i<0 || i>=maxfonts) return 0; + attributes = 0; + Fl::get_font_name(i, &attributes); + return attributes; +} + +int flFontSizes(Fl_Font font,int *& sizes) +{ + return Fl::get_font_sizes(font,*&sizes); +} + +void flSetBelowMouse(Fl_Widget* widget){Fl::belowmouse(widget);}; + +void flDisplayRect(int*x,int*y,int*w,int*h) +{ + *x=Fl::x(); + *y=Fl::y(); + *w=Fl::w(); + *h=Fl::h(); +} + +void flAddTimeout(double t,void(*callback)(void*),void *user) +{ + Fl::add_timeout(t,callback,user); +} + +int flRequest(const char *text,int flags) +{ + switch (flags) + { + case 0: + fl_message(text); + return 0; + case 1: + fl_alert(text); + return 0; + case 2: + return fl_choice(text,"No","Yes",0); //return fl_ask(text); + case 3: + return fl_choice(text,"Cancel","No","Yes"); + } +} + +char *flRequestFile(const char * message,const char *pattern,const char *path,int save) +{ + if(save) return (char*)flu_save_chooser(message,pattern,path); else return (char*)flu_file_chooser(message,pattern,path); +} + +char *flRequestDir(const char* message,const char *path,int relative) +{ + return (char*)flu_dir_chooser(message,path,0); +} + +int isboxaframe( int box ){ + switch(box){ + case FL_NO_BOX: + case FL_UP_FRAME: + case FL_DOWN_FRAME: + case FL_THIN_UP_FRAME: + case FL_THIN_DOWN_FRAME: + case FL_ENGRAVED_FRAME: + case FL_EMBOSSED_FRAME: + case FL_BORDER_FRAME: + case _FL_SHADOW_FRAME: + case _FL_ROUNDED_FRAME: + case _FL_OVAL_FRAME: + case _FL_PLASTIC_UP_FRAME: + case _FL_PLASTIC_DOWN_FRAME: + case FL_FREE_BOXTYPE: + return 1; + } + return 0; +} + +class Fl_Panel:public Fl_Group +{ + Fl_Image *origimage; + Fl_Image *img; + int pixmapflags; + int hascolor; + int active; + int enabled; +public: + Fl_Panel(int x,int y,int w,int h,const char *title):Fl_Group(x,y,w,h,title) + { + box(FL_ENGRAVED_FRAME);align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE); + clip_children(true);resizable(NULL); + img=NULL;origimage=NULL;pixmapflags=0; + hascolor=0;active=0;enabled=1; + } + void setimage(Fl_RGB_Image *i,int flags) + { + pixmapflags = flags; + if(origimage!=i){ + if(origimage) origimage = NULL; + updateImage(); + origimage = i; + } + updateImage(); + redraw(); + } + + void setcolor(Fl_Color c) + { + if(!hascolor){ + hascolor=1; + switch(box()){ + case FL_NO_BOX: + box(FL_FLAT_BOX); + break; + case FL_DOWN_FRAME: + box(FL_DOWN_BOX); + break; + case FL_UP_FRAME: + box(FL_UP_BOX); + break; + } + } + color(c); + } + + void setactive(int yesno){active=yesno;} + + void setenabled(int yesno){ + + if(enabled!=yesno){ + enabled=(yesno ? 1 : 0); + if(img){ + delete img; + img = NULL; + } + updateImage(); + } else { + enabled=(yesno ? 1 : 0); + } + + } + + void updateImage(){ + + if (origimage) { + + double scalew = (double)w()/origimage->w(), scaleh = (double)h()/origimage->h(); + + switch (pixmapflags & (PANELPIXMAP_FIT|PANELPIXMAP_FIT2|PANELPIXMAP_STRETCH)){ + case PANELPIXMAP_FIT: + if (scalew < scaleh) scaleh = scalew; else scalew = scaleh; + break; + case PANELPIXMAP_FIT2: + if (scaleh < scalew) scaleh = scalew; else scalew = scaleh; + break; + case PANELPIXMAP_STRETCH: + break; + default: + scalew = scaleh = 1.0; + } + + int neww = scalew * origimage->w(), newh = scaleh * origimage->h(); + + if (!img || (neww != img->w()) || (newh != img->h())){ + if (img) delete img; + img = origimage->copy(neww,newh); + if (!enabled) img->inactive(); + } + + } else { + if (img) delete img; + img = NULL; + } + + } + + void draw() + { + + int lblW = 0, lblH, X, dx, dy, dw, dh; + uchar* pix; + + if( (label() == 0) ) + lblW = lblH = 0; + else if( strlen( label() ) == 0 ) + lblW = lblH = 0; + else + { + measure_label( lblW, lblH ); + lblW += 4; + lblH += 2; + } + + // align the label + if( align() & FL_ALIGN_LEFT ) + X = 4; + else if( align() & FL_ALIGN_RIGHT ) + X = w() - lblW - 8; + else + X = w()/2 - lblW/2 - 2; + + // save label background to an image in memory + if(lblW && lblH) pix = fl_read_image(NULL,x()+X,y(),lblW+4,lblH,0); else pix = NULL; + + // draw the main group box + if( damage() & ~FL_DAMAGE_CHILD ){ + dx=x();dy=y()+lblH/2;dw=w();dh=h()-lblH/2; + fl_draw_box( box(), dx, dy, dw, dh, color() ); + if (img){ + if ((box()!=FL_NO_BOX) && (box()!=FL_FLAT_BOX)) {dx+=3;dy+=3;dw-=6;dh-=6;} + fl_clip(dx,dy,dw,dh); + switch(pixmapflags){ + case PANELPIXMAP_TILE: + img = new Fl_Tiled_Image(img,dw,dh); + break; + default: + dx = x()+w()/2-img->w()/2;dy = y()+h()/2-img->h()/2; + break; + } + img->draw(dx,dy); + fl_pop_clip(); + } + } + + // clip and draw the children + if((box()!=FL_NO_BOX) && (box()!=FL_FLAT_BOX)) fl_clip( x()+2, y()+lblH+1, w()-4, h()-lblH-3 ); + else fl_clip( x(), y()+lblH, w(), h()-lblH ); + draw_children(); + fl_pop_clip(); + + if(lblW && lblH) { + + // clear behind the label and draw it + if(pix) { + fl_draw_image( pix,x()+X,y(),lblW+4,lblH,3,0); + delete[] pix; + } else { + fl_color( color() ); + fl_rectf( x()+X,y(),lblW+4,lblH ); + } + + fl_color( labelcolor() ); + + draw_label( x()+X+2, y(), lblW, lblH, FL_ALIGN_CENTER ); + + } + + } + +}; + +class Fl_AWindow:public Fl_Double_Window +{ +private: + int minw, minh, maxw, maxh, dragdrop; //Used by setminsize() and setmaxsize() + Fl_Widget* push_override; +public: + Fl_AWindow(int x,int y,int w,int h,const char *title):Fl_Double_Window(w,h,title) + { + minw = 0; minh = 0; maxw = 0; maxh = 0; + push_override = NULL; + dragdrop = 0;position(x,y); + #if __linux + Fl_X::make_xid(this); + #elif defined(WIN32) + icon(LoadIcon(GetModuleHandle(NULL),MAKEINTRESOURCE(101))); + #endif + } + void resize(int x,int y,int w,int h) + { + Fl_Double_Window::resize(x,y,w,h); + do_callback(); + } + void updatesizerange() + { + if ((minw == 0) && (minh == 0)) + { + resizable(0); + size_range(w(),h()); + } + else + { + resizable(this); + size_range(minw,minh,maxw,maxh); + } + } + + void setminsize( int w, int h ) {minw = w;minh = h;updatesizerange();} + void setmaxsize( int w, int h ) {maxw = w;maxh = h;updatesizerange();} + void setdragdrop( int enable ) {dragdrop = enable ? 1 : 0;} + + int handle(int event) + { + int res = 0, shouldignore = 0; + eventid = event; + + switch (event) + { + case FL_DND_ENTER: + case FL_DND_DRAG: + case FL_DND_RELEASE: + case FL_DND_LEAVE: + case FL_PASTE: + if (dragdrop) { + do_callback(); + res = 1; + shouldignore = 1; + } + break; + } + + eventid = 0; + + if(!shouldignore) res = Fl_Double_Window::handle(event); + + return res; + } + + void maximize() { + + // RafaΓ…Β‚ Maj proposed patch here: http://www.mail-archive.com/fltk-dev@easysw.com/msg00872.html + + #ifdef WIN32 + + HWND hWnd = fl_xid(this); + if(hWnd) ShowWindow(hWnd, SW_MAXIMIZE); + + #elif __linux + + XEvent xev; + Atom wm_state = XInternAtom(fl_display, "_NET_WM_STATE", False); + Atom maximizeV = XInternAtom(fl_display, "_NET_WM_STATE_MAXIMIZED_VERT", False); + Atom maximizeH = XInternAtom(fl_display, "_NET_WM_STATE_MAXIMIZED_HORZ", False); + + memset(&xev, 0, sizeof(xev)); + xev.type = ClientMessage; + xev.xclient.window = fl_xid(this); + xev.xclient.message_type = wm_state; + xev.xclient.format = 32; + xev.xclient.data.l[0] = 1; + xev.xclient.data.l[1] = maximizeV; + xev.xclient.data.l[2] = maximizeH; + xev.xclient.data.l[3] = 0; + XSendEvent(fl_display, RootWindow(fl_display, fl_screen), 0, SubstructureNotifyMask|SubstructureRedirectMask, &xev); + + #endif + + } + + void restore() { + + #ifdef WIN32 + + HWND hWnd = fl_xid(this); + if(hWnd) ShowWindow(hWnd, SW_RESTORE); + + #elif __linux + + XEvent xev; + Atom wm_state = XInternAtom(fl_display, "_NET_WM_STATE", False); + + memset(&xev, 0, sizeof(xev)); + xev.type = ClientMessage; + xev.xclient.window = fl_xid(this); + xev.xclient.message_type = wm_state; + xev.xclient.format = 32; + xev.xclient.data.l[0] = 1; + xev.xclient.data.l[1] = 0; + xev.xclient.data.l[2] = 0; + xev.xclient.data.l[3] = 0; + XSendEvent(fl_display, RootWindow(fl_display, fl_screen), 0, SubstructureNotifyMask|SubstructureRedirectMask, &xev); + + #endif + + } + + +}; + + +enum{ + FLAGS_BACKBUFFER= 0x2, + FLAGS_ALPHABUFFER= 0x4, + FLAGS_DEPTHBUFFER= 0x8, + FLAGS_STENCILBUFFER=0x10, + FLAGS_ACCUMBUFFER= 0x20, + FLAGS_FULLSCREEN=0x80000000 +}; + +#if __linux + +XVisualInfo *_chooseXVisual(int flags){ + int glspec[32],*s; + s=glspec; + *s++=GLX_RGBA; + if (flags&FLAGS_BACKBUFFER) *s++=GLX_DOUBLEBUFFER; + if (flags&FLAGS_ALPHABUFFER) {*s++=GLX_ALPHA_SIZE;*s++=1;} + if (flags&FLAGS_DEPTHBUFFER) {*s++=GLX_DEPTH_SIZE;*s++=1;} + if (flags&FLAGS_STENCILBUFFER) {*s++=GLX_STENCIL_SIZE;*s++=1;} + if (flags&FLAGS_ACCUMBUFFER) + { + *s++=GLX_ACCUM_RED_SIZE;*s++=1; + *s++=GLX_ACCUM_GREEN_SIZE;*s++=1; + *s++=GLX_ACCUM_BLUE_SIZE;*s++=1; + *s++=GLX_ACCUM_ALPHA_SIZE;*s++=1; + } + *s++=None; + return glXChooseVisual(fl_display,fl_screen,glspec); //RootWindow(fl_display, +} + + +int glspec2[]={GLX_RGBA,GLX_DOUBLEBUFFER,GLX_DEPTH_SIZE,1,None}; + +#endif + +class Fl_Canvas:public Fl_Window +{ + int enabled, mode; + + #if __linux + XVisualInfo *visual; + Colormap colormap; + #endif + +public: + + Fl_Canvas(int x,int y,int w,int h,const char *title):Fl_Window(x,y,w,h,title) { + enabled=1;mode=0; + #if __linux + visual=0; + #endif + clip_children(true); + } + + void setenabled(int yesno) { + enabled=yesno; + } + + void setmode(int gfxmode) { + mode=gfxmode; + } + + void show() { + #if __linux + if (window() && window()->shown()==0) return; //parent is hidden so must defer + if (shown()) {Fl_Window::show(); return;} // you must do this! + if (!visual) + { + visual=_chooseXVisual(mode); + colormap=XCreateColormap(fl_display,RootWindow(fl_display,fl_screen),visual->visual,AllocNone); + } + Fl_X::make_xid(this,visual,colormap); + #else + Fl_Window::show(); + #endif + } + + int handle(int event) { + switch (event) { + case FL_FOCUS: + return (active_r() ? 1 : 0); + break; + default: + return Fl_Window::handle(event); + } + } + + void draw() { //fltk callback for lowlevel drawing + eventid=FL_ACTIVATE; + do_callback(); + eventid=0; + } +}; + +int flCanvasWindow(Fl_Canvas *canvas) +{ + return (int)fl_xid(canvas); +} + +void flSetCanvasMode(Fl_Canvas *canvas,int mode) { + canvas->setmode(mode); +} + +class Fl_ATabs:public Flmm_Tabs +{ +public: + Fl_ATabs(int x,int y,int w,int h,const char *title=0):Flmm_Tabs(x,y,w,h,title) + { + clip_children(true); + } + + Fl_Widget* which(int event_x, int event_y) { + return Flmm_Tabs::which(event_x,event_y); + } + + int handle(int event) + { + int should_callback, should_ignore, res; + should_callback=0;should_ignore=0; + switch (event) + { + case FL_PUSH: + case FL_RELEASE: + should_callback=1; + case FL_DRAG: + if (which(Fl::event_x(),Fl::event_y()) && (Fl::event_button()!=FL_LEFT_MOUSE)) should_ignore = 1; + } + if (!should_ignore) res=Flmm_Tabs::handle(event); + if (should_callback) do_callback(); + return res; + } +}; + + +static int colwidths[]={14,14,14,14,14,14,14,14,14,14,0}; //16,16,16,16,0}; + +Fl_Widget *flWidget(int x,int y,int w,int h,char *label,int fltype) +{ + Fl_Window *window; + Fl_Group *group; + Fl_Menu_Bar *menu; + Fl_Browser *browser; + Fl_Text_Buffer *text; + Fl_Help_View *help; + Fl_Choice *choice; + Fl_Progress *progbar; + Fl_Panel *panel; + Fl_Slider *slider; + Fl_Spinner *spinner; + Fl_Canvas *canvas; + Flu_Tree_Browser *tree; + + //printf("flWidget %d,%d,%d,%d \"%s\" %d\n",x,y,w,h,label,fltype); + //label=stringcopy(label); + + switch (fltype) + { + case FLWINDOW: + window=new Fl_AWindow(x,y,w,h,label); + window->end(); + return window; + case FLMENUBAR: + menu=new Fl_Menu_Bar(x,y,w,h); + menu->clear(); + return menu; + case FLBUTTON: + return new MaxGUIEventListener< MaxGUIHoverEffect >(x,y,w,h,label); + case FLCHECKBUTTON: + return new MaxGUIEventListener(x,y,w,h,label); + case FLROUNDBUTTON: + return new MaxGUIEventListener< MaxGUIHoverEffect >(x,y,w,h,label); + case FLRADIOPUSHBUTTON: + case FLTOGGLEBUTTON: + return new MaxGUIEventListener(x,y,w,h,label); + case FLRETURNBUTTON: + return new MaxGUIEventListener< MaxGUIHoverEffect >(x,y,w,h,label); + case FLREPEATBUTTON: + return new MaxGUIEventListener< MaxGUIHoverEffect >(x,y,w,h,label); + case FLGROUPPANEL: + case FLPANEL: + panel=new MaxGUIEventListener(x,y,w,h,label); + panel->end(); + return panel; + case FLINPUT: + return new MaxGUIEventListener< MaxGUIKeyFilter >(x,y,w,h,label); + case FLPASSWORD: + return new MaxGUIEventListener< MaxGUIKeyFilter >(x,y,w,h,label); + case FLTABS: + group=new MaxGUIEventListener(x,y,w,h,label); + group->selection_color(fl_color_average(group->selection_color(),FL_SELECTION_COLOR,.80f)); + group->end(); + return group; + case FLGROUP: + group=new MaxGUIEventListener(x,y,w,h,label); + group->clip_children(true); + group->end(); + group->box(FL_NO_BOX); + return group; + case FLPACK: + group=new MaxGUIEventListener(x,y,w,h,label); + group->clip_children(true); + group->end(); + return group; + case FLMULTIBROWSER: + case FLBROWSER: + if(fltype==FLBROWSER) browser=new MaxGUIEventListener(x,y,w,h,label); + else browser=new MaxGUIEventListener(x,y,w,h,label); + browser->column_widths(colwidths); + return browser; + case FLINPUTCHOICE: + group= new MaxGUIEventListener(x,y,w,h,label); + group->end(); + return group; + case FLCHOICE: + return new MaxGUIEventListener< MaxGUIHoverEffect >(x,y,w,h,label); + case FLTEXTEDITOR: + Fl_Text_Editor *edit; + text=new Fl_Text_Buffer; + edit=new MaxGUIEventListener< MaxGUIKeyFilter< MaxGUITextArea > >(x,y,w,h,""); + edit->buffer(text); + edit->remove_key_binding('z',FL_CTRL); + return edit; + case FLTEXTDISPLAY: + Fl_Text_Display *display; + text=new Fl_Text_Buffer; + display=new MaxGUIEventListener< MaxGUIKeyFilter< MaxGUITextArea > >(x,y,w,h,""); + display->buffer(text); + return display; + case FLHELPVIEW: + help=new MaxGUIEventListener(x,y,w,h,label); + help->link(viewcallback); + return help; + case FLBOX: + return new MaxGUIEventListener(x,y,w,h,label); + case FLTOOLBAR: + group=new MaxGUIEventListener(x,y,w,h); + group->clip_children(true); + group->end(); + return group; + case FLPROGBAR: + progbar=new MaxGUIEventListener(x,y,w,h,label); + progbar->minimum(0.0); + progbar->maximum(1.0); + progbar->selection_color(FL_SELECTION_COLOR); + return progbar; + case FLSLIDER: + slider=new MaxGUIEventListener(x,y,w,h); + slider->bounds(0,100); + return slider; + case FLSCROLLBAR: + slider=new MaxGUIEventListener(x,y,w,h); + return slider; + case FLSPINNER: + spinner=new MaxGUIEventListener(x,y,w,h); + spinner->minimum(5); + spinner->maximum(10); + spinner->step(1); + spinner->value(5); + spinner->end(); + return spinner; + case FLCANVAS: + canvas=new MaxGUIEventListener(x,y,w,h,label); + canvas->end(); + return canvas; + case FLUTREEBROWSER: + tree=new MaxGUIEventListener(x,y,w,h,label); + tree->auto_branches(true); + tree->show_root(false); + tree->selection_mode(FLU_SINGLE_SELECT); + tree->insertion_mode(FLU_INSERT_BACK); + tree->selection_drag_mode(FLU_DRAG_IGNORE); + tree->branch_icons(NULL,NULL); + tree->branch_text(FL_BLACK,FL_HELVETICA,12); + tree->double_click_opens(false); + tree->open_on_select(false); + tree->animate(false); + tree->end(); + return tree; + } + return 0; +} + +void flFreeWidget(Fl_Widget*widget) +{ + Fl_Group *parent; + parent=widget->parent(); + if (parent) parent->remove(widget); + Fl::delete_widget(widget); +} + +void flFreePtr( void* pointer ) +{ + if(pointer) free(pointer); +} + +void* flUserData( Fl_Widget* widget ) +{ + if(widget) return widget->user_data(); +} + +void flDelete ( void* pointer ) +{ + delete pointer; +} + +Fl_Widget* flPushed() +{ + return Fl::pushed(); +} + +void flSetPushed(Fl_Widget* widget) +{ + Fl::pushed(widget); +} + +void flRedraw(Fl_Widget*widget) +{ + widget->redraw(); + if((isboxaframe(widget->box())) && (widget->window())) + widget->window()->damage(FL_DAMAGE_ALL,widget->x(),widget->y(),widget->w(),widget->h()); + if(widget->label()) + widget->redraw_label(); +} + +int flWidth(Fl_Widget*widget) +{ + return widget->w(); +} + +int flHeight(Fl_Widget*widget) +{ + return widget->h(); +} + +int flVisible(Fl_Widget*widget) { + return widget->visible(); +} + +int flChanged(Fl_Widget*widget) { + return widget->changed(); +} + +void flClearChanged(Fl_Widget*widget) { + widget->clear_changed(); +} + +void flSetBox(Fl_Widget*widget,int boxtype,int redrawifneeded = 0) +{ + if(widget->box()!=boxtype){ + widget->box((Fl_Boxtype)boxtype); + if(redrawifneeded) flRedraw(widget); + } +} + +void flSetLabelType(Fl_Widget*widget,Fl_Labeltype labeltype) +{ + widget->labeltype(labeltype); +} + +void flSetAlign(Fl_Widget*widget,int aligntype) +{ + widget->align(aligntype); +} + +int flAlign(Fl_Widget*widget) +{ + return widget->align(); +} + +void flRemoveColor(Fl_Widget*widget){ + int rr,gg,bb; + widget->color(FL_BACKGROUND_COLOR); +} + +void flSetColor(Fl_Widget*widget,int r,int g,int b) +{ + int rr,gg,bb; + widget->color(fl_rgb_color(r,g,b)); + widget->selection_color(FL_SELECTION_COLOR); + if(fl_contrast(widget->selection_color(),widget->color())!=widget->selection_color()){ + rr=255-r;gg=255-g;bb=255-b; + if (abs(rr-r)+abs(gg-g)+abs(bb-b)<64) + { + rr=r^0x80;gg=g^0x80;bb=b^0x80; + } + widget->selection_color(fl_rgb_color(rr,gg,bb)); + } +} + +void flSetLabelColor(Fl_Widget*widget,int r,int g,int b) +{ + widget->labelcolor(fl_rgb_color(r,g,b)); +} + +void flSetLabelFont(Fl_Widget*widget,Fl_Font s) +{ + widget->labelfont(s); +} + +void flSetLabelSize(Fl_Widget*widget,Fl_Fontsize s) +{ + widget->labelsize(s); +} + +const char *flGetLabel(Fl_Widget*widget) +{ + return widget->label(); +} + +void flSetFocus(Fl_Widget*widget) +{ + widget->take_focus(); +} + +void *flGetFocus() { + return Fl::focus(); +} + +Fl_When flGetWhen(Fl_Widget* widget) { + return widget->when(); +} + + +void flSetWhen(Fl_Widget* widget, Fl_When when) { + widget->when(when); +} + +void *flGetUser(Fl_Widget*widget) { + return widget->user_data(); +} + +void flSetArea(Fl_Widget*widget,int x,int y,int w,int h) +{ + widget->damage_resize(x,y,w,h); + widget->redraw_label(); +} + +void flGetArea(Fl_Widget*widget,int *x,int *y,int *w,int *h) +{ + *x=widget->x(); + *y=widget->y(); + *w=widget->w(); + *h=widget->h(); +} + +void flSetLabel(Fl_Widget*widget,char*label) +{ + widget->copy_label( label[0] ? label : 0 ); +} + +void flSetShow(Fl_Widget *widget,int truefalse) +{ + if (truefalse) + widget->show(); + else + widget->hide(); +} + +void flSetCallback(Fl_Widget *widget,void(*callback)(Fl_Widget*,void*),void *user) +{ + widget->user_data(user); + widget->callback(callback); +} + +void flSetToolTip(Fl_Widget*widget,char*tip) +{ + widget->tooltip(stringcopy(tip)); +} + +void flSetActive(Fl_Widget *widget,int truefalse) +{ + if (truefalse) widget->activate(); else widget->deactivate(); +} + +Fl_Window* flWidgetWindow(Fl_Widget* widget) +{ + return widget->window(); +} + +void flSetWindowLabel(Fl_Window*window,char*label) +{ + //For some reason Fl_Widget::copy_label() isn't virtual. + window->copy_label(label); +} + + +void flSetWindowIcon(Fl_Window*window,char** icon) +{ + #if __usexpm + Pixmap p, mask; + XpmCreatePixmapFromData(fl_display, DefaultRootWindow(fl_display),icon, &p, &mask, NULL); + window->icon((char *)p); + #endif +} + +void flClearBorder(Fl_Window *window) +{ + window->border(0); +} + +void flShowWindow(Fl_Window *window,int falsetrueiconize){ + switch (falsetrueiconize){ + case 0: + window->hide(); + break; + case 1: + window->show(); + break; + case 2: + window->iconize(); + break; + case 3: + window->show(); + ((Fl_AWindow*)window)->maximize(); + break; + case 4: + window->show(); + ((Fl_AWindow*)window)->restore(); + break; + } +} + +void flDestroyWindow(Fl_Window *window) { + delete window; +} + +void flSetMaxWindowSize(Fl_AWindow*window,int w,int h) +{ + window->setmaxsize(w,h); +} + +void flSetMinWindowSize(Fl_AWindow*window,int w,int h) +{ + window->setminsize(w,h); +} + +void flSetAcceptsFiles(Fl_AWindow*window, int enable ) +{ + window->setdragdrop(enable); +} + +void flSetNonModal(Fl_AWindow*window) +{ + window->set_non_modal(); +} + +void flSetModal(Fl_AWindow*window) +{ + window->set_modal(); +} + +void flBegin(Fl_Group*group) +{ + group->begin(); +} + +void flEnd(Fl_Group*group) +{ + group->end(); +} + +void flAddToGroup(Fl_Group*group,Fl_Widget*child) +{ + if(group) group->add(child); +} + +void flRemoveFromGroup(Fl_Group*group,Fl_Widget*child) +{ + if(group) group->remove(child); +} + +void flSetInputChoice(Fl_Input_Choice *input_choice, int value){ + input_choice->value(value); +} + +void* flGetInputChoiceTextWidget(Fl_Input_Choice *input_choice){ + return input_choice->input(); +} + +void* flGetInputChoiceMenuWidget(Fl_Input_Choice *input_choice){ + return input_choice->menubutton(); +} + +void flSetChoice(Fl_Choice *choice,int value) { + choice->value(value); +} + +int flGetChoice(Fl_Choice* choice) { + return choice->value(); +} + + +void flSetButton(Fl_Button*button,bool value) +{ + button->value(value); +} + +int flGetButton(Fl_Button*button) +{ + return button->value(); +} + +void flSetButtonKey(Fl_Button*button,int key) +{ + button->shortcut(key); +} + +Fl_RGB_Image *flImage(const unsigned char *pix,int w,int h,int d,int span) +{ + return new Fl_RGB_Image(pix,w,h,d,span); +} + +void flSetImage(Fl_Widget *widget,Fl_RGB_Image *image) +{ + Fl_Image* copy; + if(widget->image()) delete widget->image(); + if(widget->deimage()) delete widget->deimage(); + if(image){ + widget->image(image->copy()); + copy = image->copy(); + copy->inactive(); + widget->deimage(copy); + } else { + widget->image(0);widget->deimage(0); + } +} + +void flFreeImage( Fl_Image *image ) +{ + delete image; +} + +void flSetPanelImage(Fl_Panel *panel,Fl_RGB_Image *image,int flags) +{ + panel->setimage(image,flags); +} + +void flSetPanelColor(Fl_Panel *panel,int r,int g,int b) +{ + panel->setcolor(fl_rgb_color(r,g,b)); +} + +void flSetPanelActive(Fl_Panel *panel,int yesno) +{ + panel->setactive(yesno); +} + +void flSetPanelEnabled(Fl_Panel *panel,int yesno) +{ + panel->setenabled(yesno); +} + +void flSetSliderType(Fl_Slider *slider,int type) +{ + slider->type(type); +} + +double flSliderValue(Fl_Slider *slider) +{ + return slider->value(); +} + +void flSetSliderValue(Fl_Slider *slider,double value) +{ + slider->value(value); +} + +void flSetSliderRange(Fl_Slider *slider,double low,double hi) +{ + slider->bounds(low,hi); +} + +int flScrollbarValue(Fl_Scrollbar *scrollbar) +{ + return scrollbar->value(); +} + +void flSetScrollbarValue(Fl_Scrollbar *scrollbar,int value,int visible,int top,int total) +{ + scrollbar->value(value,visible,top,total); +} + +void flSetInput(Fl_Input*input,char*value) +{ + input->value(value); + input->position(0,strlen(value)); +} + +const char *flGetInput(Fl_Input*input) +{ + return input->value(); +} + +void flActivateInput(Fl_Input*input) +{ + input->position(input->size(),0); +} + +void flSetInputFont(Fl_Input*input,Fl_Font s) +{ + input->labelfont(s); +} + +void flSetInputSize(Fl_Input*input,Fl_Fontsize s) +{ + input->labelsize(s); +} + +void flSetSpinnerMin(Fl_Spinner* spinner, double min) +{ + spinner->minimum(min); +} +void flSetSpinnerMax(Fl_Spinner* spinner, double max) +{ + spinner->maximum(max); +} +void flSetSpinnerValue(Fl_Spinner* spinner, double value) +{ + spinner->value(value); +} +double flSpinnerValue(Fl_Spinner* spinner) +{ + return spinner->value(); +} + +void flClearBrowser(Fl_Browser*browse) +{ + browse->clear(); +} + +void flAddBrowser(Fl_Browser*browse,const char *label,void *object, Fl_Image* icon) +{ + browse->add(label,object); + browse->icon(browse->size(), icon); +} + +void flInsertBrowser(Fl_Browser*browse,int index,const char *label,void *object, Fl_Image* icon) +{ + browse->insert(index,label,object); + browse->icon(index,icon); +} + +void flShowBrowser(Fl_Browser*browse,int line,int show) +{ + if (show) + browse->show(line); + else + browse->hide(line); +} + +void flSelectBrowser(Fl_Hold_Browser*browse,int line) +{ + browse->deselect(); + if (line) browse->select(line); +} + +void flMultiBrowserSelect(Fl_Multi_Browser *browse,int line,int select) +{ + if(select) browse->select(line); else browse->deselect(line); +} + +int flMultiBrowserSelected(Fl_Multi_Browser *browse,int line) +{ + return browse->selected(line); +} + +int flBrowserValue(Fl_Hold_Browser *browse) +{ + return browse->value(); +} + +void *flBrowserData(Fl_Hold_Browser *browse,int line) +{ + return browse->data(line); +} + +const char *flBrowserItem(Fl_Hold_Browser *browse,int line) +{ + return browse->text(line); +} + +void flSetBrowserItem(Fl_Hold_Browser *browse,int line,char *text,void *object, Fl_Image* icon) +{ + browse->text(line,text); + browse->data((int)object); + browse->icon(line,icon); +} + +void flRemoveBrowserItem(Fl_Hold_Browser *browse,int line) +{ + browse->remove(line); +} + +void flSetBrowserTextColor(Fl_Hold_Browser *browse,int r,int g,int b) +{ + browse->textcolor(fl_rgb_color(r,g,b)); +} + +void flSetBrowserTextFont(Fl_Hold_Browser *browse,Fl_Font s) +{ + browse->textfont(s); +} + +void flSetBrowserTextSize(Fl_Hold_Browser *browse,Fl_Fontsize s) +{ + browse->textsize(s); +} + +int flBrowserCount(Fl_Hold_Browser *browse) +{ + return browse->size(); +} + +void flSelectTab(Fl_Tabs *tab,Fl_Widget *widget) +{ + tab->value(widget); +} + +int flGetTabPanel(Fl_Tabs *tab) +{ + return (int)tab->value(); +} + +void *flGetTabPanelForEvent(Fl_ATabs *tab) +{ + return tab->which(Fl::event_x(),Fl::event_y()); +} + +void flSetText(Fl_Text_Display *textdisplay,char *text) +{ + Fl_Text_Buffer *buff; + buff=textdisplay->buffer(); + buff->remove(1,buff->length()); + buff->append(text); +} + +void flSetEditTextColor(Fl_Text_Display *textdisplay,int r,int g,int b) +{ + textdisplay->textcolor(fl_rgb_color(r,g,b)); + textdisplay->cursor_color(fl_rgb_color(r,g,b)); +} + +void flRedrawText(Fl_Text_Display *textdisplay,int start,int count) +{ + textdisplay->redisplay_range(start,start+count); +} + +void flAddText(Fl_Text_Display *textdisplay,char *text) +{ + Fl_Text_Buffer *buff; + buff=textdisplay->buffer(); + buff->append(text); +// edit->show_insert_position(); +} + +char *flGetText(Fl_Text_Display *textdisplay,int start,int count) +{ + Fl_Text_Buffer *buff; + buff=textdisplay->buffer(); + if (count<0) count=buff->length()-start; + return buff->text_range(start,start+count); +} + +int flLinePos(Fl_Text_Display *textdisplay,int line) +{ + Fl_Text_Buffer *buff; + buff=textdisplay->buffer(); + return buff->skip_lines(0,line); +} + +int flLineCount(Fl_Text_Display *textdisplay,int pos) +{ + Fl_Text_Buffer *buff; + buff=textdisplay->buffer(); + return buff->count_lines(0,pos); +} + +int flLineStart(Fl_Text_Display *textdisplay,int pos) +{ + Fl_Text_Buffer *buff; + buff=textdisplay->buffer(); + return buff->line_start(pos); +} + +int flTextLength(Fl_Text_Display *textdisplay) +{ + Fl_Text_Buffer *buff; + buff=textdisplay->buffer(); + return buff->length(); +} + +void flCharPosXY(Fl_Text_Display *textdisplay, int charpos, int *x, int *y) +{ + ((MaxGUITextArea< Fl_Text_Display >*)textdisplay)->pos_to_xy(charpos,x,y); +} + +void flSetWrapMode(Fl_Text_Display *textdisplay, int mode, int col) +{ + textdisplay->wrap_mode(mode,col); +} + +void flReplaceText(Fl_Text_Display *textdisplay,int start,int count,char *text) +{ + Fl_Text_Buffer *buff; + buff=textdisplay->buffer(); + if (count<0) count=buff->length()-start; + buff->replace(start,start+count,text); +} + +void flSelectText(Fl_Text_Display *textdisplay,int start,int count) +{ + Fl_Text_Buffer *buff; + buff=textdisplay->buffer(); + if (count<0) count=buff->length()-start; + buff->select(start,start+count); + textdisplay->insert_position(start+count); +} + +void flShowPosition(Fl_Text_Display *textdisplay) +{ + textdisplay->show_insert_position(); +} + +void flSetTextCallback(Fl_Text_Display *textdisplay,void(*callback)(int,int,int,int,const char*,void*),void *user) +{ + Fl_Text_Buffer *buff; + buff=textdisplay->buffer(); + buff->add_modify_callback(callback,user); + textdisplay->when(FL_WHEN_NOT_CHANGED|FL_WHEN_CHANGED|FL_WHEN_ENTER_KEY_ALWAYS|FL_WHEN_RELEASE); +} + +int flGetCursorPos(Fl_Text_Display *textdisplay) +{ + int start,endpos; + Fl_Text_Buffer *buff; + buff=textdisplay->buffer(); + if (buff->selection_position(&start,&endpos)){ + if (endpos>start) return start; + } + return textdisplay->insert_position(); +} + +int flGetSelectionLen(Fl_Text_Display *textdisplay) +{ + int start,endpos; + Fl_Text_Buffer *buff; + buff=textdisplay->buffer(); + if (buff->selection_position(&start,&endpos)){ + return endpos-start; + } + return 0; +} + +void flSetTextTabs(Fl_Text_Display *textdisplay,int tabs) +{ + Fl_Text_Buffer *buff; + buff=textdisplay->buffer(); + buff->tab_distance(tabs); +} + +void flActivateText(Fl_Text_Display *textdisplay) +{ + textdisplay->show_cursor(1); +} + +void flCutText(Fl_Text_Editor *editor) +{ + Fl_Text_Editor::kf_cut(0,editor); +} + +void flCopyText(Fl_Text_Editor *editor) +{ + Fl_Text_Editor::kf_copy(0,editor); +} + +void flPasteText(Fl_Text_Editor *editor) +{ + Fl_Text_Editor::kf_paste(0,editor); +} + +typedef Fl_Text_Display::Style_Table_Entry style; + +#define FLSTYLE_TABLELENGTH 128 + +struct flStyle +{ + flStyle *next; + Fl_Text_Display *owner; + Fl_Text_Buffer *buffer; + int count; + style table[128]; + flStyle *prev; +}; + +static flStyle *stylelist = NULL; + +flStyle *GetStyle(Fl_Text_Display *e) +{ + flStyle *s; + for (s=stylelist;s;s=s->next) + { + if (s->owner==e) return s; + } + if (!s) + { + s=new flStyle; + if(stylelist) stylelist->prev=s; + s->next=stylelist; + stylelist=s; + s->prev = NULL; + s->owner=e; + s->buffer=new Fl_Text_Buffer; + memset(s->table,0,sizeof(s->table)); + s->count=0; + e->highlight_data(s->buffer,s->table,FLSTYLE_TABLELENGTH,'A',0,0); //stylecallback,s); + } + return s; +} + +void* flFreeTextDisplay(Fl_Text_Display *textdisplay) +{ + flStyle *s; + Fl_Text_Buffer* buff; + + for (s=stylelist;s;s=s->next) + { + if (s->owner==textdisplay){ + if(s->prev){ + s->prev->next = s->next; + if(s->next) s->next->prev = s->prev; + } else { + stylelist = s->next; + stylelist->prev = NULL; + } + break; + } + } + + if (s){ + delete s->buffer; + delete s; + } + + return textdisplay->buffer(); +} + +void flSetTextFont(Fl_Text_Display *textdisplay,Fl_Font s) +{ + flStyle *style; + int i; + textdisplay->textfont(s); + style=GetStyle(textdisplay); + for (i=0;itable[i].font=(Fl_Font)s; + } +} + +void flSetTextSize(Fl_Text_Display *textdisplay,Fl_Fontsize s) +{ + flStyle *style; + int i; + textdisplay->textsize(s); + style=GetStyle(textdisplay); + for (i=0;itable[i].size=s; + } +} + +int flGetTextStyleChar(Fl_Text_Display *textdisplay,int r,int g,int b,Fl_Font font,Fl_Fontsize size) +{ + flStyle *s; + style *e; + int i; + Fl_Color rgb; + + s=GetStyle(textdisplay); + rgb=fl_rgb_color(r,g,b); + for (i=0;icount;i++) + { + e=&s->table[i]; + if (e->color==rgb && e->size==size && e->font==font) return 'A'+i; + } + if (s->count==FLSTYLE_TABLELENGTH) return 0; + e=&s->table[s->count]; + e->color=rgb; + e->font=(Fl_Font)font; + e->size=size; + return 'A'+s->count++; +} + +void flSetTextStyle(Fl_Text_Display *textdisplay,char *text) +{ + Fl_Text_Buffer *buff; + flStyle *s; + s=GetStyle(textdisplay); + buff=s->buffer; + buff->remove(0,buff->length()); + buff->append(text); +} + +void flAddTextStyle(Fl_Text_Display *textdisplay,char *text) +{ + Fl_Text_Buffer *buff; + flStyle *s; + s=GetStyle(textdisplay); + buff=s->buffer; + buff->append(text); +} + +void flReplaceTextStyle(Fl_Text_Display *textdisplay,int start,int count,char *text) +{ + Fl_Text_Buffer *buff; + flStyle *s; + s=GetStyle(textdisplay); + buff=s->buffer; + if (count<0) count=buff->length()-start; + buff->replace(start,start+count,text); +} + +void flInsertTextStyle(Fl_Text_Display *textdisplay,int start,char *text) +{ + Fl_Text_Buffer *buff; + flStyle *s; + s=GetStyle(textdisplay); + buff=s->buffer; + if (buff) buff->insert(start,text); +} + +void flDeleteTextStyle(Fl_Text_Display *textdisplay,int start,int count) +{ + Fl_Text_Buffer *buff; + flStyle *s; + s=GetStyle(textdisplay); + buff=s->buffer; + if (buff) + { + if (count<0) count=buff->length()-start; + buff->remove(start,count); + } +} + +void flSetView(Fl_Help_View *view, const char *html) +{ + view->value(html); +} + +void flSeekView(Fl_Help_View *view, const char *anchor) +{ + view->topline(anchor); +} + +void flRedirectView(Fl_Help_View *view, char *url) +{ + redirect_url=stringcopy(url); // Seb was here, not freed by Fl_Help_View +} + +void flSetLineView(Fl_Help_View *view, int line) +{ + view->topline(line); +} + +int flGetLineView(Fl_Help_View *view) +{ + return view->gettopline(); +} + +void flSetPathView(Fl_Help_View *view, const char *path) +{ + view->filepath(path); +} + +char *flGetPathView(Fl_Help_View *view) +{ + return view->filepath(); +} + +int flIsLinkView(Fl_Help_View *view) +{ + return view->fileislink(); +} + +void flSetStyleView(Fl_Help_View *view, int flag) +{ + view->setstyle(flag); +} + +void flSetProgress(Fl_Progress *progbar,float val) +{ + progbar->value(val); +} + +void (*menucallback)(Fl_Widget*,void*); + +void *flCreateMenu(int n,void (*callback)(Fl_Widget*,void*)) +{ + menucallback=callback; + return calloc(n,sizeof(Fl_Menu_Item)); +} + +void flSetMenuItem(Fl_Menu_Item* menu,int item,char *name,int shortcut,void *user,int flags, Fl_Font fonthandle, Fl_Fontsize fontsize) +{ + if((item<0) || (item>=menu->size())) return; + Fl_Menu_Item *p=&menu[item]; + p->text=stringcopy(name); + p->shortcut_=shortcut; + p->callback_=menucallback; + p->user_data_=user; + p->flags=flags; + p->labeltype_=0; + p->labelfont_=fonthandle; + p->labelsize_=fontsize; + p->labelcolor_=0; +} + +void *flPopupMenu(Fl_Menu_Item *menuitem,void *n) +{ + const Fl_Menu_Item *result; + result=menuitem->popup( Fl::event_x(),Fl::event_y() ); + if (result) return result->user_data_; + return n; +} + +void flSetMenu(Fl_Menu_ *menu,void *stack) +{ + menu->copy((Fl_Menu_Item *)stack); + free((Fl_Menu_Item*)stack); +} + +void* fluRootNode( Flu_Tree_Browser* tree ){ + return (void*) tree->get_root(); +} +void* fluSelectedNode( Flu_Tree_Browser* tree, int index ){ + return (void*) tree->get_selected( index ); +} +void* fluCallbackNode( Flu_Tree_Browser* tree ){ + return (void*) tree->callback_node(); +} +int fluCallbackReason( Flu_Tree_Browser* tree ){ + return tree->callback_reason(); +} +void* fluInsertNode( Flu_Tree_Browser::Node* parent, int pos, const char* text ){ + return (void*) parent->insert( text, pos ); +} +void* fluAddNode( Flu_Tree_Browser::Node* parent, const char* text ){ + return (void*) parent->add( text ); +} +void fluRemoveNode( Flu_Tree_Browser* tree, Flu_Tree_Browser::Node* node ){ + tree->remove( node ); +} +void fluSetNode( Flu_Tree_Browser::Node* node, const char* text, Fl_RGB_Image* iconimage ){ + node->label( text );node->leaf_icon( iconimage );node->branch_icon( iconimage ); +} +void fluSetNodeUserData( Flu_Tree_Browser::Node* node, void* user_data ){ + node->user_data( user_data ); +} +void* fluNodeUserData( Flu_Tree_Browser::Node* node ){ + return node->user_data(); +} +void fluExpandNode( Flu_Tree_Browser::Node* node, int collapse ){ + node->open( (collapse ? false:true) ); +} +void fluSelectNode( Flu_Tree_Browser::Node* node ){ + node->select_only(); +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/fltkgui.bmx b/mod/maxgui.mod/fltkmaxgui.mod/fltkgui.bmx new file mode 100644 index 0000000..f80a498 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/fltkgui.bmx @@ -0,0 +1,3152 @@ +Strict + +Import MaxGUI.MaxGUI +Import BRL.Graphics + +Import "fltkfonts.bmx" +Import "fltksystem.bmx" + +Extern "C" +Function bbStringToUTF8String:Byte Ptr ( str$ ) +EndExtern + +Private + + Include "fltkdecls.bmx" + + Global FLDriver:TFLTKGUIDriver = New TFLTKGuiDriver + maxgui_driver = FLDriver + + Type TFLGuiSystemDriver Extends TFLSystemDriver + Field gui:TFLTKGUIDriver + + Method Poll() + gui.RefreshWidgets() + flWait(0.0) + gui.FreePointers() + DispatchGuiEvents() + End Method + + Method Wait() + Poll() + flWait(-1) + End Method + + Function Create:TFLGuiSystemDriver(host:TFLTKGUIDriver) + Local guisystem:TFLGuiSystemDriver = New TFLGuiSystemDriver + guisystem.gui = host + Return guisystem + End Function + End Type + +Public + +Type TFLTKGUIDriver Extends TMaxGUIDriver + + Global fntDefault:TFLGuiFont + + Field RefreshList:TList=New TList, PointerTrash:Byte Ptr[] + Field fontRequester:TFLFontRequest + + ?Linux + Function _FlushAsyncOpsProc( fd,data:Byte Ptr ) "C" nodebug + bbSystemFlushAsyncOps + End Function + ? + + Method UserName$() + End Method + + Method ComputerName$() + End Method + + Method New() + + brl.System.Driver=TFLGuiSystemDriver.Create(Self) + Local display + + ?Linux + display = bbSystemDisplay() + ? + + flReset(display,EventHandler,KeyFilter,TFLWidget.MouseHandler,TFLWidget.KeyHandler) + + ?Linux + flAddFd( bbSystemAsyncFD(),FL_READ,_FlushAsyncOpsProc,Null ) + ? + + 'Initialize FLTK font handler after flReset() call. + TFLFontFamily.Initialize() + fntDefault = TFLGuiFont(LibraryFont( GUIFONT_SYSTEM, 0, FONT_NORMAL )) + + End Method + + Function EventHandler:Int(flevent) "C" nodebug + Local key,state + Local event:TEvent + Select flevent + Case FL_DND_RELEASE + If TFLGadget.getDragDrop() Then flSetBelowMouse(TFLGadget.getDragDrop().WidgetHandle()) + Return 1 + Case FL_SHORTCUT + key=flkeytovkey(flEventKey()) + state=flstatetomodifiers(flEventState()) + event=HotKeyEvent( key,state,flGetFocus() ) + If event Then + event.emit() + Return 1 + EndIf + EndSelect + End Function + + Function KeyFilter(obj:Int) "C" nodebug + Local source:TFLWidget + Local event:TEvent + Local key,mods,text$,i + source=TFLWidget(HandleToObject(obj)) + + If flEventKey()=FL_KEY_Control_R Return 0 + If source And (source.eventfilter<>Null) Then + key=BlitzKeyFromFlConst(flEventKey()) + text$=fleventtext() + mods=flstatetomodifiers(flEventState()) + If key + event=CreateEvent(EVENT_KEYDOWN,source,key,mods) + If Not source.eventfilter(event,source.context) Then Return 0 + 'Unlike the other platforms, text isn't set by FLTK when combining tab with modifier keys + If Not text And key = KEY_TAB Then text="~t" + EndIf + For i=0 Until text.length + key=text[i] + event=CreateEvent(EVENT_KEYCHAR,source,key,mods) + If Not source.eventfilter(event,source.context) Then Return 0 + Next + EndIf + Return 1 + End Function + + Function BlitzKeyFromFlConst( pKey% ) + Select pKey + Case FL_KEY_BackSpace;Return KEY_BACKSPACE + Case FL_KEY_Tab;Return KEY_TAB + Case FL_KEY_Enter;Return KEY_RETURN + Case FL_KEY_Pause + Case FL_KEY_Scroll_Lock + Case FL_KEY_Escape;Return KEY_ESCAPE + Case FL_KEY_Home;Return KEY_HOME + Case FL_KEY_Left;Return KEY_LEFT + Case FL_KEY_Up;Return KEY_UP + Case FL_KEY_Right;Return KEY_RIGHT + Case FL_KEY_Down;Return KEY_DOWN + Case FL_KEY_Page_Up;Return KEY_PAGEUP + Case FL_KEY_Page_Down;Return KEY_PAGEDOWN + Case FL_KEY_End;Return KEY_END + Case FL_KEY_Print;Return KEY_PRINT + Case FL_KEY_Insert;Return KEY_INSERT + Case FL_KEY_Menu + Case FL_KEY_Help + Case FL_KEY_Num_Lock + Case FL_KEY_KP+0;Return KEY_NUM0 + Case FL_KEY_KP+1;Return KEY_NUM1 + Case FL_KEY_KP+2;Return KEY_NUM2 + Case FL_KEY_KP+3;Return KEY_NUM3 + Case FL_KEY_KP+4;Return KEY_NUM4 + Case FL_KEY_KP+5;Return KEY_NUM5 + Case FL_KEY_KP+6;Return KEY_NUM6 + Case FL_KEY_KP+7;Return KEY_NUM7 + Case FL_KEY_KP+8;Return KEY_NUM8 + Case FL_KEY_KP+9;Return KEY_NUM9 + Case FL_KEY_KP_Enter;Return KEY_ENTER + Case FL_KEY_F+1;Return KEY_F1 + Case FL_KEY_F+2;Return KEY_F2 + Case FL_KEY_F+3;Return KEY_F3 + Case FL_KEY_F+4;Return KEY_F4 + Case FL_KEY_F+5;Return KEY_F5 + Case FL_KEY_F+6;Return KEY_F6 + Case FL_KEY_F+7;Return KEY_F7 + Case FL_KEY_F+8;Return KEY_F8 + Case FL_KEY_F+9;Return KEY_F9 + Case FL_KEY_F+10;Return KEY_F10 + Case FL_KEY_F+11;Return KEY_F11 + Case FL_KEY_F+12;Return KEY_F12 + Case FL_KEY_Shift_L;Return KEY_LSHIFT + Case FL_KEY_Shift_R;Return KEY_RSHIFT + Case FL_KEY_Control_L;Return KEY_LCONTROL + Case FL_KEY_Control_R;Return KEY_RCONTROL + Case FL_KEY_Caps_Lock + Case FL_KEY_Meta_L;Return KEY_LSYS + Case FL_KEY_Meta_R;Return KEY_RSYS + Case FL_KEY_Alt_L;Return KEY_LALT + Case FL_KEY_Alt_R;Return KEY_RALT + Case FL_KEY_Delete;Return KEY_DELETE + Default;Return flkeytovkey(pKey) + EndSelect + EndFunction + + Method RefreshWidget( widget:TFLWidget ) + RefreshList.AddLast widget + End Method + + Method QueueFlDelete( pointer:Byte Ptr ) + PointerTrash:+[pointer] + EndMethod + + Method RefreshWidgets() + For Local w:TFLWidget = EachIn RefreshList + w.Redraw() + Next + RefreshList.Clear() + End Method + + Method FreePointers() + For Local pointer:Byte Ptr = EachIn PointerTrash + flDelete(pointer) + Next + PointerTrash = Null + EndMethod + + Method CreateGadget:TGadget(class,name$,x,y,w,h,group:TGadget,style) + + Select class + Case GADGET_DESKTOP + Return New TFLDesktop.CreateDesktop() + Case GADGET_WINDOW + Return New TFLWindow.CreateGadget(name,x,y,w,h,TFLGadget(group),style) + Case GADGET_PANEL + Return New TFLPanel.CreateGadget(name,x,y,w,h,TFLGadget(group),style) + Case GADGET_BUTTON + Return New TFLButton.CreateGadget(name,x,y,w,h,TFLGadget(group),style) + Case GADGET_TEXTFIELD + Return New TFLTextField.CreateGadget(name,x,y,w,h,TFLGadget(group),style) + Case GADGET_TEXTAREA + Return New TFLTextArea.CreateGadget(name,x,y,w,h,TFLGadget(group),style) + Case GADGET_COMBOBOX + Return New TFLComboBox.CreateGadget(name,x,y,w,h,TFLGadget(group),style) + Case GADGET_LISTBOX + Return New TFLListBox.CreateGadget(name,x,y,w,h,TFLGadget(group),style) + Case GADGET_TOOLBAR + Return New TFLToolbar.CreateGadget(name,x,y,w,h,TFLGadget(group),style) + Case GADGET_TABBER + Return New TFLTabber.CreateGadget(name,x,y,w,h,TFLGadget(group),style) + Case GADGET_TREEVIEW + Return New TFLTreeview.CreateGadget(name,x,y,w,h,TFLGadget(group),style) + Case GADGET_HTMLVIEW + Return New TFLHTMLView.CreateGadget(name,x,y,w,h,TFLGadget(group),style) + Case GADGET_LABEL + Return New TFLLabel.CreateGadget(name,x,y,w,h,TFLGadget(group),style) + Case GADGET_SLIDER + Return New TFLSlider.CreateGadget(name,x,y,w,h,TFLGadget(group),style) + Case GADGET_PROGBAR + Return New TFLProgBar.CreateGadget(name,x,y,w,h,TFLGadget(group),style) + Case GADGET_MENUITEM + Return TFLMenu.CreateMenu(name,style,TFLMenu(group)) + Case GADGET_CANVAS + Return New TFLCanvas.CreateGadget(name,x,y,w,h,TFLGadget(group),style) + End Select + + End Method + + Method LoadFont:TGuiFont(name$,size,flags) + Return TFLGUIFont.LoadFont(name,size,flags) + End Method + + Method RequestColor( red,green,blue ) + Local r:Byte = red, g:Byte = green, b:Byte = blue + If flChooseColor( "Choose Color", Varptr r, Varptr g, Varptr b ) + Return $ff000000 | (r Shl 16) | (g Shl 8) | b + EndIf + Return 0 + End Method + + Method RequestFont:TGuiFont(font:TGuiFont) + If Not fontRequester Then fontRequester = New TFLFontRequest + Return fontRequester.Request(TFLGUIFont(font)) + End Method + + Method SetPointer(shape) + flSetCursor(shape) + End Method + + Method ActiveGadget:TGadget() + PollSystem + Local handle:Int = flGetFocus() + If handle Return TFLWidget(HandleToObject(flGetUser(handle))) + End Method + + Method LoadIconStrip:TIconStrip(image:Object) + Return TFLIconStrip.Create(image) + End Method + + Method LookupColor( colorindex:Int, pRed:Byte Var, pGreen:Byte Var, pBlue:Byte Var ) + + Select colorindex + Case GUICOLOR_WINDOWBG + colorindex = FL_BACKGROUND_COLOR + Case GUICOLOR_GADGETBG + colorindex = FL_BACKGROUND2_COLOR + Case GUICOLOR_GADGETFG + colorindex = FL_FOREGROUND_COLOR + Case GUICOLOR_SELECTIONBG + colorindex = FL_SELECTION_COLOR + Default + Return Super.LookupColor( colorindex, pRed, pGreen, pBlue ) + EndSelect + + Local color = flGetColor( colorindex ) + pRed = color Shr 24 + pGreen = (color Shr 16) & $FF + pBlue = (color Shr 8) & $FF + + Return True + + EndMethod + + Method LibraryFont:TGuiFont( pFontType% = GUIFONT_SYSTEM, pFontSize:Double = 0, pFontStyle% = FONT_NORMAL ) + Local tmpFont:TGuiFont + Local tmpFontAttrib% + + ?Win32 + If pFontSize <= 0 Then pFontSize = 10 + ?Not Win32 + If pFontSize <= 0 Then pFontSize = 12 + ? + + Select pFontType + Case GUIFONT_MONOSPACED + Return LoadFontWithDouble( TFLFontFamily.FriendlyNameFromID(FL_COURIER), pFontSize, pFontStyle ) + Case GUIFONT_SANSSERIF + Return LoadFontWithDouble( TFLFontFamily.FriendlyNameFromID(FL_HELVETICA), pFontSize, pFontStyle ) + Case GUIFONT_SERIF + Return LoadFontWithDouble( TFLFontFamily.FriendlyNameFromID(FL_TIMES), pFontSize, pFontStyle ) + Case GUIFONT_SCRIPT + Return LoadFontWithDouble("Comic Sans MS",pFontSize,pFontStyle) + Default 'GUIFONT_SYSTEM + Return LoadFontWithDouble( TFLFontFamily.FriendlyNameFromID(FL_HELVETICA), pFontSize, pFontStyle ) + EndSelect + EndMethod + +End Type + +Type TFLWidget Extends TGadget + + Global initText:Byte Ptr = " ".ToCString() + + Field fltype, flhandle, flkey, tag, tooltip:Byte Ptr + Field originx, originy, client:TFLWidget, dirty, objhandle:Int = HandleFromObject(Self) + + Method CreateWidget:TFLWidget( fltype, text$, x, y, w, h, group:TFLWidget, alignment = -1, boxtype = -1 ) + Self.fltype = fltype + SetRect(x,y,w,h) + parent = group + InitWidget() + If alignment > -1 Then flSetAlign( flhandle, alignment ) + If boxtype > -1 Then flSetBox( flhandle, boxtype, False ) + If text Then SetText(text) + Return Self + EndMethod + + Method WidgetHandle() + ?Debug + Assert flhandle, "Attempt to access a NULL widget." + ? + Return flhandle + EndMethod + + Method InitWidget() + If TFLWidget(parent) Then flBegin( TFLWidget(parent).Query(QUERY_FLWIDGET_CLIENT) ) + flhandle = flWidget(AbsoluteX(),AbsoluteY(),width,height,initText,fltype) + flSetCallback(WidgetHandle(),CallbackHandler,objhandle ) + If TFLWidget(parent) Then + flEnd( TFLWidget(parent).Query(QUERY_FLWIDGET_CLIENT) ) + TFLWidget(parent).AddChild(Self) + Else + LockLayout() + EndIf + If flkey Then flSetButtonKey(WidgetHandle(),flkey) + SetTooltip("") + EndMethod + + Method Rethink() + flSetArea(WidgetHandle(),AbsoluteX(),AbsoluteY(),width,height) + End Method + + Method Redraw() + If flhandle Then + flRedraw(WidgetHandle()) + dirty = False + EndIf + End Method + + Method SetText(text$) + Return flSetLabel(WidgetHandle(),text) + End Method + + Method GetText$() + Return flGetLabel(WidgetHandle()) + End Method + + Method SetToolTip(tip$) + If tooltip Then MemFree tooltip + tooltip = tip.ToCString() + flSetToolTip(WidgetHandle(),tooltip) + End Method + + Method GetToolTip$() + If tooltip Then Return String.FromCString(tooltip) + EndMethod + + Method SetShape(x,y,w,h) + Super.SetShape x,y,w,h + If parent parent.activate ACTIVATE_REDRAW + End Method + + Method SetColor( r,g,b ) + flSetColor(WidgetHandle(),r,g,b) + End Method + + Method RemoveColor() + flRemoveColor(WidgetHandle()) + End Method + + Method SetTextColor( r,g,b ) + flSetLabelColor(WidgetHandle(),r,g,b) + EndMethod + + Method SetShow(truefalse) + flSetShow(WidgetHandle(),truefalse) + End Method + + Method ClientWidth() + Local w + If client Then w=client.width Else w=width-originx + Return Max(w,0) + End Method + + Method ClientHeight() + Local h + If client Then h=client.height Else h=height-originy + Return Max(h,0) + End Method + + Method RemoveChild(child:TFLWidget) + kids.remove child + child.parent=Null + If child.flhandle Then + flRemoveFromGroup Query(QUERY_FLWIDGET_CLIENT),child.flhandle + SetDirty() + EndIf + End Method + + Method AddChild(child:TFLWidget) + If child.parent TFLWidget(child.parent).RemoveChild(child) + child.parent=Self + kids.addlast(child) + If child.flhandle Then + flAddToGroup Query(QUERY_FLWIDGET_CLIENT),child.flhandle + SetDirty() + EndIf + child.LockLayout + child.Rethink() + End Method + + Method SetDirty() + If Not dirty + dirty=True + FLDriver.RefreshWidget Self + EndIf + End Method + + Method Free() + + 'Cleanup any client gadget first. + If client Then + client.CleanUp() + client = Null + EndIf + + 'Then remove ourselves from our parent + If TFLWidget(parent) Then TFLWidget(parent).RemoveChild(Self) + + 'And free our widget in the FLTK toolkit. + If flhandle Then + flSetCallBack( WidgetHandle(), CallbackHandler, 0 ) + If objhandle Then + Release objhandle + objhandle= 0 + EndIf + If fltype=FL_WINDOW Then flDestroyWindow flhandle Else flFreeWidget flhandle + EndIf + + 'Then any tooltip we may have. + If tooltip Then + MemFree tooltip + tooltip = Null + EndIf + + 'And clear the widget handle and parent. + flhandle=0 + parent = Null + + EndMethod + + Method CountKids() + Return kids.count() + End Method + + Method SetOrigin(x,y) + originx=x + originy=y + End Method + + Method AbsoluteX() + Local p:TFLWidget = TFLWidget(parent) + Local x = xpos + While p + x:+p.originx + If p.client And Self <> p.client x:+p.client.xpos+p.client.originx + If p.fltype<>FL_WINDOW x:+p.xpos Else Exit + p=TFLWidget(p.parent) + Wend + Return x + End Method + + Method AbsoluteY() + Local p:TFLWidget = TFLWidget(parent) + Local y = ypos + While p + y:+p.originy + If p.client And Self <> p.client y:+p.client.ypos+p.client.originy + If p.fltype<>FL_WINDOW y:+p.ypos Else Exit + p=TFLWidget(p.parent) + Wend + Return y + End Method + + Method Query(queryid) + Select queryid + Case QUERY_FLWIDGET + Return flhandle + Case QUERY_FLWIDGET_CLIENT + If client Return client.flhandle Else Return flhandle + End Select + End Method + + Method OnCallback() + EndMethod + + Method OnMouse:Int() + EndMethod + + Method OnKey:Int() + EndMethod + + Function CallbackHandler(flwidget,obj:Int) "C" nodebug + Local widget:TFLWidget = TFLWidget(HandleToObject(obj)) + If widget Then widget.OnCallback() + EndFunction + + Function MouseHandler:Int(flwidget,obj:Int) "C" nodebug + Local widget:TFLWidget = TFLWidget(HandleToObject(obj)) + Select flEvent() + Case FL_LEAVE + If TFLGadget.activepanel Then + TFLGadget.activepanel.OnMouseLeave() + TFLGadget.activepanel = Null + EndIf + Case FL_RELEASE + Local tmpButton:Int = flEventButton() + Local tmpX:Int = flEventX(), tmpY:Int = flEventY() + Local tmpDropWidget:TFLWidget = TFLWidget(HandleToObject(flUserData(flWidgetWindow(flwidget)))) + + If tmpDropWidget Then tmpDropWidget = tmpDropWidget.FindChildAtCoords(tmpX,tmpY) + If tmpDropWidget And tmpDropWidget.fltype <> FL_WINDOW Then + tmpX:-tmpDropWidget.AbsoluteX() + tmpY:-tmpDropWidget.AbsoluteY() + EndIf + + If dragGadget[tmpButton-1] Then + PostGuiEvent EVENT_GADGETDROP, tmpDropWidget, tmpButton, flStateToModifiers(flEventState()), tmpX, tmpY, dragGadget[tmpButton-1] + dragGadget[tmpButton-1] = Null + EndIf + + EndSelect + If widget Then Return widget.OnMouse() + EndFunction + + Function KeyHandler:Int(flwidget,obj:Int) "C" nodebug + Local widget:TFLWidget = TFLWidget(HandleToObject(obj)) + If widget Then Return widget.OnKey() + EndFunction + + Function XPMFromPixmap:String[](pPixmap:TPixmap) + + Const charRange:Int = 26 + + Local x:Int, y:Int, i:Int, j:Int, tmpColor:Int, chrctsPerPixel:Int, tmpString$ + Local width:Int = PixmapWidth(pPixmap), height:Int = PixmapHeight(pPixmap) + Local colormap:Int[][] = New Int[][height], colors:Int[], colorstrings:String[] + + For y = 0 Until height + colormap[y] = New Int[width] + For x = 0 Until width + 'Read color from pixel + tmpColor = ReadPixel(pPixmap,x,y) + 'If less than 50% alpha, set a standard transparent color. + If (tmpColor Shr 24) < $80 Then tmpColor = $00000000 + 'Find the color if it has been used before. + For i = 0 Until colors.length + If colors[i] = tmpColor Then Exit + Next + 'If it hasn't been found, add it to the end of the array. + If i = colors.length Then colors:+[tmpColor] + 'And finally, update the colormap with the color index. + colormap[y][x] = i + Next + Next + + chrctsPerPixel = (colors.length / charRange) + 1 + colorstrings = New String[colors.length] + + Local tmpResult:String[] = [width + " " + height + " " + colors.length + " " + chrctsPerPixel] + + For i = 0 Until colors.length + Local tmpI:Int = i + For j = 0 Until chrctsPerPixel + colorstrings[i]:+Chr$("a"[0]+(tmpI Mod charRange)) + tmpI:/charRange + Next + tmpString = colorstrings[i] + "~tc " + If (colors[i] Shr 24) <> $FF Then tmpString:+"None" Else tmpString:+"#"+_RGBHex(colors[i]&$FFFFFF) + tmpResult:+[tmpString] + Next + + For y = 0 Until height + tmpString = "" + For x = 0 Until width + tmpString:+colorstrings[colormap[y][x]] + Next + tmpResult:+[tmpString] + Next + + Return tmpResult + + EndFunction + + Function _RGBHex$( rgb:Int ) + Local buf:Short[6] + For Local k:Int=5 To 0 Step -1 + Local n:Int=(rgb&15)+Asc("0") + If n>Asc("9") n=n+(Asc("A")-Asc("9")-1) + buf[k]=n + rgb:Shr 4 + Next + Return String.FromShorts( buf,buf.length ) + End Function + + Method FindChildAtCoords:TFLWidget( pX, pY ) + If pX > 0 And pX < ClientWidth() And pY > 0 And pY < ClientHeight() Then + For Local tmpChild:TFLWidget = EachIn kids + tmpChild = tmpChild.FindChildAtCoords( pX - tmpChild.xpos, pY - tmpChild.ypos) + If tmpChild Then Return tmpChild + Next + Return Self + EndIf + EndMethod + +EndType + +Type TFLGadget Extends TFLWidget + + Global activepanel:TFLGadget + Global activex, activey, activekey + + Field menu:TFLMenu + Field enabled = True, ignore + Field font:TFLGUIFont + Field pixmap:TPixmap, pixmapflags, image, icons:TFLIconStrip + + Method CreateGadget:TFLGadget(pText$, pX, pY, pW, pH, pGroup:TFLGadget, pStyle) + + style = pStyle + SetRect(pX,pY,pW,pH) + parent = pGroup + InitGadget() + + If (LocalizationMode() & LOCALIZATION_OVERRIDE) Then + LocalizeGadget(Self,pText) + Else + SetText(pText) + EndIf + + SetFont(TFLTKGUIDriver.fntDefault) + Return Self + + EndMethod + + Method InitGadget() + EndMethod + + Method SetHotKey(keycode,modifier) + Local flkey + flkey=flkeyfromvkey(keycode) + If flkey flkey:+flstatefrommodifiers(modifier) + End Method + + Method SetEnabled(truefalse) + enabled=truefalse + flSetActive WidgetHandle(),truefalse + End Method + + Method SetFont( font:TGuiFont ) + Self.font = TFLGUIFont(font) + flSetLabelFont WidgetHandle(),Self.font.handle + flSetLabelSize WidgetHandle(),Self.font.GetSizeForFL() + SetText(GetText()) + Redraw() + End Method + + Method SetText(text$) + Super.SetText(text.Replace("@","@@")) + EndMethod + + Method GetText$() + Return Super.GetText().Replace("@@","@") + EndMethod + + Method State() + Local flags + If Not enabled Then flags:|STATE_DISABLED + If Not flVisible(WidgetHandle()) flags:|STATE_HIDDEN + Return flags + End Method + + Method Activate(cmd) + Select cmd + Case ACTIVATE_FOCUS + flSetFocus(WidgetHandle()) + PollSystem + Case ACTIVATE_REDRAW + Redraw + End Select + End Method + + Method SetPixmap(pPixmap:TPixmap,flags) + Local d + SetFLImage 0 + If pixmap And image Then + flFreeImage( image ) + image = 0 + EndIf + pixmap = Null + If pPixmap Then + Select PixmapFormat(pPixmap) + Case PF_RGB888, PF_BGR888, PF_I8 + d = 3 + pixmap = ConvertPixmap(pPixmap,PF_RGB888) + Case PF_RGBA8888, PF_BGRA8888, PF_A8 + d = 4 + pixmap = ConvertPixmap(pPixmap,PF_RGBA8888) + Default + Return + EndSelect + If pixmap Then + image = flImage(pixmap.pixels,pixmap.width,pixmap.height,d,pixmap.pitch) + EndIf + EndIf + pixmapflags = flags + SetFLImage image + End Method + + Method SetFLImage(image) + End Method + + Method SetIconStrip(iconstrip:TIconStrip) + icons=TFLIconStrip(iconstrip) + End Method + + Method ClearListItems() + For Local i=items.length-1 To 0 Step -1 + RemoveListItem i + Next + End Method + + Method Free() + Super.Free() + pixmap = Null + icons = Null + If image Then flFreeImage(image);image = 0 + End Method + + Method GetMenu:TFLMenu() + If Not menu Then + menu = New TFLMenu + menu.owner = Self + EndIf + Return menu + End Method + + Method OnMouse:Int() + Local x = flEventX()-AbsoluteX(), y = flEventY()-AbsoluteY() + + If activepanel And (activepanel<>Self) Then + activepanel.OnMouseLeave() + activepanel = Null + EndIf + + If GetSensitivity() & SENSITIZE_MOUSE Then + + Select flevent() + Case FL_DRAG, FL_MOVE + Local data, state=flEventState() + + If state&FL_BUTTON1 data=MOUSE_LEFT + If state&FL_BUTTON3 data=MOUSE_RIGHT + If state&FL_BUTTON2 data=MOUSE_MIDDLE + + If (activepanel <> Self) Then + PostGuiEvent(EVENT_MOUSEENTER,Self,data,0,x,y) + activepanel=Self + Else + If (x <> activex) Or (y <> activey) Then + PostGuiEvent(EVENT_MOUSEMOVE,Self,data,0,x,y) + EndIf + EndIf + activex=x;activey=y + + Case FL_PUSH, FL_RELEASE + Local data, button=flEventButton(), id = EVENT_MOUSEDOWN + Select button + Case FL_LEFT_MOUSE data=MOUSE_LEFT + Case FL_RIGHT_MOUSE data=MOUSE_RIGHT + Case FL_MIDDLE_MOUSE data=MOUSE_MIDDLE + EndSelect + If flEvent() = FL_RELEASE Then id = EVENT_MOUSEUP + PostGuiEvent(id,Self,data,0,x,y) + + Case FL_MOUSEWHEEL + PostGuiEvent(EVENT_MOUSEWHEEL,Self,flEventdY(),0,x,y) + EndSelect + Return 1 + EndIf + EndMethod + + Method OnMouseLeave() + If GetSensitivity() & SENSITIZE_MOUSE Then + PostGuiEvent(EVENT_MOUSELEAVE,Self,0,0,activex,activey) + EndIf + EndMethod + + Method OnKey:Int() + Local key, mods + If GetSensitivity() & SENSITIZE_KEYS Then + Select flevent() + Case FL_KEYDOWN + key=TFLTKGUIDriver.BlitzKeyFromFlConst(flEventKey()) + mods=flstatetomodifiers(flEventState()) + If activekey=key + PostGuiEvent(EVENT_KEYREPEAT,Self,key,mods) + Else + PostGuiEvent(EVENT_KEYDOWN,Self,key,mods) + EndIf + activekey=key + Case FL_KEYUP + key=TFLTKGUIDriver.BlitzKeyFromFlConst(flEventKey()) + mods=flstatetomodifiers(flEventState()) + PostGuiEvent(EVENT_KEYUP,Self,key,mods) + activekey=0 + EndSelect + EndIf + EndMethod + + 'For WINDOW_ACCEPTFILES drag n' drop event. + Global _dragDrop:TFLGadget = Null + + Function setDragDrop( pGadget:TFLGadget ) + _dragDrop = pGadget + EndFunction + + Function getDragDrop:TFLGadget() + Return _dragDrop + EndFunction + +EndType + +Type TFLDesktop Extends TFLGadget + + Method Class() + Return GADGET_DESKTOP + EndMethod + + Method InitGadget() + Local x, y, w, h + flDisplayRect( Varptr x, Varptr y, Varptr w, Varptr h ) + SetRect( x, y, w, h ) + EndMethod + + Method CreateDesktop:TFLGadget() + InitGadget() + Return Self + EndMethod + +EndType + +Type TFLWindow Extends TFLGadget + + Const MENU_HEIGHT = 25, STATUSBAR_HEIGHT = 22 + + Global lastactivewindow:TFLWindow + + Field menubar:TFLWidget, statustext:TFLGadget[3] + + Method InitGadget() + Local tmpParent:TGadget = parent;parent = Null + fltype = FL_WINDOW + InitWidget() + If Not (style&WINDOW_TITLEBAR) Then flClearBorder(WidgetHandle()) + CreateWindowClient() + If tmpParent Then + flSetNonModal(WidgetHandle()) + parent = tmpParent + EndIf + Rethink() + If Not (style&WINDOW_HIDDEN) Then SetShow(True) Else SetShow(False) + EndMethod + + Method Class() + Return GADGET_WINDOW + EndMethod + + Method SetText(text$) + flSetWindowLabel(WidgetHandle(),text) + End Method + + Method SetColor(r,g,b) + Super.SetColor(r,g,b) + client.SetColor(r,g,b) + EndMethod + + Method Activate(cmd) + Select cmd + Case ACTIVATE_MINIMIZE + flShowWindow WidgetHandle(), 2 + Case ACTIVATE_MAXIMIZE + flShowWindow WidgetHandle(), 3 + LayoutKids() + Case ACTIVATE_RESTORE + flShowWindow WidgetHandle(), 4 + LayoutKids() + Default + Super.Activate(cmd) + End Select + End Method + + Method SetShow(truefalse) + flShowWindow(WidgetHandle(),truefalse=True) + End Method + + Method SetEnabled(truefalse) + Super.SetEnabled(truefalse) + If client Then flSetActive client.WidgetHandle(),truefalse + If menubar Then flSetActive menubar.WidgetHandle(),truefalse + End Method + + Method OnCallback() + Select flevent() + Case FL_CLOSE + PostGuiEvent EVENT_WINDOWCLOSE,Self + Case FL_FOCUS, FL_ACTIVATE + If lastactivewindow <> Self Then + lastactivewindow = Self + PostGuiEvent EVENT_WINDOWACTIVATE,Self + EndIf + + 'Drag 'n' drop events + Case FL_DND_ENTER + setDragDrop(Self) + Case FL_DND_LEAVE + setDragDrop(Null) + Case FL_PASTE + DropFiles() + setDragDrop(Null) + Default + Local ax,ay,aw,ah,move,size + flGetArea WidgetHandle(),Varptr ax,Varptr ay,Varptr aw,Varptr ah + If (style&WINDOW_CLIENTCOORDS) Then + ax:+originX;ay:+originY + aw:-originX;ah:-originY + If (style&WINDOW_MENU) Then + ay:+MENU_HEIGHT + ah:-MENU_HEIGHT + EndIf + If (style&WINDOW_STATUS) Then ah:-STATUSBAR_HEIGHT + EndIf + If ax<>xpos Or ay<>ypos move=True + If aw<>width Or ah<>height size=True + SetRect ax,ay,aw,ah + If size RethinkWindow() + If move PostGuiEvent(EVENT_WINDOWMOVE,Self,0,0,ax,ay) + If size PostGuiEvent(EVENT_WINDOWSIZE,Self,0,0,aw,ah) + End Select + EndMethod + + Method CreateWindowClient() + + If style&WINDOW_RESIZABLE Then SetMinimumSize(64,64) + If style&WINDOW_ACCEPTFILES Then flSetAcceptsFiles( WidgetHandle(), True ) + + If style&WINDOW_MENU + menubar = New TFLWidget.CreateWidget( FL_MENUBAR, "", -2, 0, width+4, MENU_HEIGHT, Self, -1, FL_THIN_UP_BOX ) + kids.Remove(menubar) + EndIf + + If style&WINDOW_STATUS + statustext[2] = New TFLLabel.CreateGadget("",0,height-STATUSBAR_HEIGHT,width,STATUSBAR_HEIGHT,Self,LABEL_RIGHT) + statustext[1] = New TFLLabel.CreateGadget("",0,height-STATUSBAR_HEIGHT,width,STATUSBAR_HEIGHT,Self,LABEL_CENTER) + statustext[0] = New TFLLabel.CreateGadget("",0,height-STATUSBAR_HEIGHT,width,STATUSBAR_HEIGHT,Self,LABEL_LEFT) + For Local tmpStatusText:TFLGadget = EachIn statustext + If tmpStatusText = statustext[2] Then flSetBox( tmpStatusText.WidgetHandle(), FL_EMBOSSED_BOX, False ) Else flSetBox( tmpStatusText.WidgetHandle(), FL_NO_BOX,False ) + flSetAlign( tmpStatusText.WidgetHandle(), flAlign(tmpStatusText.WidgetHandle())&~FL_ALIGN_WRAP );kids.Remove(tmpStatusText) + Next + EndIf + + client=New TFLPanel.CreateGadget("",0,0,1,1,Self,0) + RemoveChild(client);client.parent = Self + + RethinkWindow() + + End Method + + Method Rethink() + Local tmpX:Int = AbsoluteX(), tmpY:Int = AbsoluteY(), tmpW:Int = width, tmpH:Int = height + If (style&WINDOW_CLIENTCOORDS) Then + tmpX:-originX;tmpY:-originY + tmpW:+originX;tmpH:+originY + If (style&WINDOW_MENU) Then + tmpY:-MENU_HEIGHT + tmpH:+MENU_HEIGHT + EndIf + If (style&WINDOW_STATUS) Then tmpH:+STATUSBAR_HEIGHT + EndIf + flSetArea(WidgetHandle(),tmpX,tmpY,tmpW,tmpH) + RethinkWindow() + EndMethod + + Method RethinkWindow() + Local x,y,w=width,h=height + If menubar Then flSetArea(menubar.WidgetHandle(),-2,0,w+4,MENU_HEIGHT);h:-MENU_HEIGHT;y:+MENU_HEIGHT + If statustext[0] Then + If Not (style&WINDOW_CLIENTCOORDS) Then h:-STATUSBAR_HEIGHT + For Local tmpStatusText:TFLWidget = EachIn statustext;flSetArea(tmpStatusText.WidgetHandle(),0,y+originY+ClientHeight(),w,STATUSBAR_HEIGHT);Next + EndIf + client.SetArea x,y,ClientWidth(),ClientHeight() + LayoutKids() + End Method + + Method DoLayout() + 'Don't do anything! + EndMethod + + Method GetStatusText$() + If statustext[0] Then + Return "~t".Join([statustext[0].GetText(), statustext[1].GetText(), statustext[2].GetText()]) + EndIf + EndMethod + + Method SetStatusText(text$) + If statustext[0] Then + Local tmpAlignments$[] = text.Split("~t") + If tmpAlignments.length > 3 Then tmpAlignments = [tmpAlignments[0], tmpAlignments[1], "~t".Join(tmpAlignments[2..])] + tmpAlignments = tmpAlignments[..3] + For Local i = 0 Until 3 + statustext[i].SetText( tmpAlignments[i] ) + Next + EndIf + End Method + + Method ClientWidth() + If (style&WINDOW_CLIENTCOORDS) Then Return width Else Return (width-originx) + EndMethod + + Method ClientHeight() + Local h:Int = height + If Not(style&WINDOW_CLIENTCOORDS) Then + h:-originY + If menubar Then h:-MENU_HEIGHT + If statustext[0] Then h:-STATUSBAR_HEIGHT + EndIf + Return h + EndMethod + + Method SetMaximumSize( w,h ) + flSetMaxWindowSize(WidgetHandle(),w,h) + End Method + + Method SetMinimumSize( w,h ) + flSetMinWindowSize(WidgetHandle(),w,h) + End Method + + Method UpdateMenu() + Local count,flmenu Ptr + If Not (menubar And menu) Return + count=menu.count(-1) + flmenu=flCreateMenu(count+2,CallbackHandler) + menu.setflmenu(flmenu) + flSetMenu(menubar.WidgetHandle(),flmenu) + End Method + + Method PopupMenu( menu0:TGadget,extra:Object ) + Local menu:TFLMenu + Local count,flmenu Ptr + menu=TFLMenu(menu0) + count=menu.count(-1) + flmenu=flCreateMenu(count+2,CallbackHandler) + menu.setflmenu(flmenu) + menu=TFLMenu(HandleToObject(flPopupMenu(flmenu))) + If menu PostGuiEvent(EVENT_MENUACTION,menu,menu.tag,0,0,0,extra) + End Method + + Method SetPixmap(pPixmap:TPixmap, pFlags) + ?Linux + If (pFlags&GADGETPIXMAP_ICON) Then + + 'Generate the strings which represent the pixmap in XPM format. + Local tmpXPM$[] = XPMFromPixmap(pPixmap) + + 'Create a new array of char* pointers to pass to flSetWindowIcon(). + '+1 is for terminating Null pointer. + Local tmpStringPointers:Byte Ptr[tmpXPM.length+1] + + 'Store char* pointers for each section inside the array. + For Local i:Int = 0 Until tmpXPM.length + tmpStringPointers[i] = tmpXPM[i].ToCString() + Next + + 'And end the array with a Null pointer. + tmpStringPointers[tmpXPM.length] = Null + + 'Set the window icon. + flSetWindowIcon( WidgetHandle(), tmpStringPointers ) + + 'And then free all the char* pointers before we exit. We only need + 'to iterate through tmpXPM.length as tmpStringPointers.length will + 'include the terminating Null pointer array element. + For Local i:Int = 0 Until tmpXPM.length + MemFree tmpStringPointers[i] + Next + + EndIf + ? + EndMethod + + Method DropFiles() + + For Local tmpUrl$ = EachIn flEventText().Replace("file://","").Replace("~r","").Split("~n") + + If tmpUrl[..8].ToLower() = "https://" Then Continue + If tmpUrl[..7].ToLower() = "http://" Then Continue + If tmpUrl[..6].ToLower() = "ftp://" Then Continue + + tmpURL = DecodeURL(tmpURL) + If Not tmpURL Then Continue + + 'Creating and manipulating widgets inside an FL_PASTE event is considered dangerous. + 'Therefore we should queue this event so that it's dispatched safely after a call to + 'Poll/WaitSystem(). + + QueueGuiEvent(EVENT_WINDOWACCEPT,Self,0,0,0,0,tmpURL) + + Next + + End Method + + 'http://www.blitzbasic.com/codearcs/codearcs.php?code=1581 + + Function DecodeURL:String(EncStr:String) + Local Pos:Int = 0 + Local HexVal:String + Local Result:String + + While Pos < EncStr.length + If EncStr[Pos..Pos+1] = "%" Then + HexVal = EncStr[Pos+1..Pos+3] + Result :+ Chr(Int("$"+HexVal)) + Pos:+3 + ElseIf EncStr[Pos..Pos+1] = "+" Then + Result :+ " " + Pos:+1 + Else + Result :+ EncStr[Pos..Pos+1] + Pos:+1 + EndIf + Wend + + Return Result + End Function + +EndType + +Type TFLLabel Extends TFLGadget + + Method InitGadget() + fltype=FL_BOX + InitWidget() + Local tmpAlignment = FL_ALIGN_WRAP|FL_ALIGN_INSIDE|FL_ALIGN_CLIP + Select style&24 + Case LABEL_LEFT tmpAlignment:|FL_ALIGN_LEFT + Case LABEL_CENTER tmpAlignment:|FL_ALIGN_CENTER + Case LABEL_RIGHT tmpAlignment:|FL_ALIGN_RIGHT + EndSelect + flSetAlign WidgetHandle(),tmpAlignment + Local tmpBox + Select style&7 + Case 0 tmpBox = FL_NO_BOX + Case LABEL_FRAME tmpBox = FL_BORDER_BOX + Case LABEL_SUNKENFRAME tmpBox = FL_THIN_DOWN_FRAME + Case LABEL_SEPARATOR tmpBox = FL_EMBOSSED_FRAME + End Select + flSetBox WidgetHandle(),tmpBox,False + EndMethod + + Method Class() + Return GADGET_LABEL + EndMethod + + Method SetColor( r, g, b ) + Local tmpBox = FL_FLAT_BOX + Select style&7 + Case LABEL_FRAME tmpBox = FL_BORDER_BOX + Case LABEL_SUNKENFRAME tmpBox = FL_THIN_DOWN_BOX + Case LABEL_SEPARATOR tmpBox = FL_EMBOSSED_BOX + End Select + flSetBox WidgetHandle(),tmpBox,False + Super.SetColor( r, g, b ) + EndMethod + + Method SetText(text$) + Super.SetText(text) + Redraw() + EndMethod + + Method SetRect(x,y,w,h) + If style&LABEL_SEPARATOR = LABEL_SEPARATOR Then + If w > h Then h = 2 Else w = 2 + EndIf + Super.SetRect(x,y,w,h) + EndMethod + +EndType + +Type TFLButton Extends TFLGadget + + Method InitGadget() + Local tmpAlignment = FL_ALIGN_INSIDE|FL_ALIGN_CLIP|FL_ALIGN_WRAP|FL_ALIGN_CENTER + fltype = FL_BUTTON + Select style&7 + Case 0 + style = BUTTON_PUSH + Case BUTTON_CHECKBOX + If (style&BUTTON_PUSH) Then + fltype = FL_TOGGLEBUTTON + Else + fltype=FL_CHECKBUTTON + tmpAlignment:&~FL_ALIGN_CENTER + tmpAlignment:|FL_ALIGN_LEFT + EndIf + Case BUTTON_RADIO + If (style&BUTTON_PUSH) Then + fltype = FL_RADIOPUSHBUTTON + Else + fltype=FL_ROUNDBUTTON + tmpAlignment:&~FL_ALIGN_CENTER + tmpAlignment:|FL_ALIGN_LEFT + EndIf + Case BUTTON_OK + fltype=FL_RETURNBUTTON + Case BUTTON_CANCEL + flkey=FL_KEY_ESCAPE + End Select + InitWidget() + flSetAlign WidgetHandle(), tmpAlignment + flSetWhen WidgetHandle(), FL_WHEN_RELEASE + EndMethod + + Method Class() + Return GADGET_BUTTON + EndMethod + + Method State() + Local flags = Super.State() + If flGetButton(WidgetHandle()) Then flags:|STATE_SELECTED + Return flags + End Method + + Field currentText$ + + Method SetText(text$) + currentText = text + If Not (pixmapflags&GADGETPIXMAP_NOTEXT) Then Super.SetText(text) + EndMethod + + Method GetText$() + Return currentText + EndMethod + + Method SetFLImage(image) + If Not (pixmapflags&GADGETPIXMAP_NOTEXT) Then Super.SetText(currentText) + If (pixmapflags&GADGETPIXMAP_ICON) And( (Not (style&7)) Or (style&7=BUTTON_CANCEL)) Then + If (pixmapflags&GADGETPIXMAP_NOTEXT) Then Super.SetText("") + flSetImage(WidgetHandle(),image) + EndIf + End Method + + Method SetSelected(bool) + If bool And (style&7=BUTTON_RADIO) Then ExcludeOthers() + flSetButton WidgetHandle(),bool + End Method + + Method SetHotKey(keycode,modifier) + Super.SetHotKey(keycode,modifier) + flSetButtonKey WidgetHandle(),flkey + EndMethod + + Method OnCallback() + If (style&7=BUTTON_RADIO) Then SetButtonState(Self,STATE_SELECTED) + PostGuiEvent(EVENT_GADGETACTION,Self,State()) + EndMethod + + Method ExcludeOthers() + Local w:TFLWidget + For w=EachIn parent.kids + If w<>Self And (w.fltype=FL_ROUNDBUTTON Or w.fltype=FL_RADIOPUSHBUTTON) + flSetButton w.WidgetHandle(),False + EndIf + Next + End Method + +EndType + +Type TFLTextField Extends TFLGadget + + Method InitGadget() + If (style&TEXTFIELD_PASSWORD) Then fltype=FL_PASSWORD Else fltype=FL_INPUT + InitWidget() + flSetWhen( WidgetHandle(), FL_WHEN_CHANGED|FL_WHEN_RELEASE_ALWAYS) + EndMethod + + Method Class() + Return GADGET_TEXTFIELD + EndMethod + + Method GetText$() + Return flGetInput(WidgetHandle()) + End Method + + Method SetText(text$) + flSetInput(WidgetHandle(),text) + End Method + + Method SetFont(font:TGuiFont) + Super.SetFont(font) + flSetInputFont WidgetHandle(),Self.font.handle + flSetInputSize WidgetHandle(),Self.font.GetSizeForFL() + EndMethod + + Method Activate(cmd) + Select cmd + Case ACTIVATE_FOCUS + Super.Activate(cmd) + flActivateInput(WidgetHandle()) + Default + Super.Activate(cmd) + End Select + End Method + + Method OnCallback() + If flChanged(WidgetHandle()) Then + PostGuiEvent(EVENT_GADGETACTION,Self) + flClearChanged(WidgetHandle()) + EndIf + Select flevent() + Case FL_UNFOCUS + PostGuiEvent(EVENT_GADGETLOSTFOCUS,Self) + End Select + EndMethod + +EndType + +Type TFLTextArea Extends TFLGadget + + Field textr,textg,textb + Field locked,lockedpos,lockedlen + + Method InitGadget() + If (style&TEXTAREA_READONLY) Then fltype=FL_TEXTDISPLAY Else fltype=FL_TEXTEDITOR + InitWidget() + flSetBox(WidgetHandle(),FL_THIN_DOWN_BOX,False) + If (style&TEXTAREA_WORDWRAP) Then flSetWrapMode( WidgetHandle(), True, 0 ) + flSetTextCallback(WidgetHandle(),EditHandler,objhandle) + EndMethod + + Method Class() + Return GADGET_TEXTAREA + EndMethod + + Method GetText$() + Return AreaText(0,-1,TEXTAREA_CHARS) + End Method + + Method SetText(text$) + ReplaceText(0,-1,text,TEXTAREA_CHARS) + End Method + + Method Activate(cmd) + Select cmd + Case ACTIVATE_FOCUS + Super.Activate(cmd) + flActivateText(WidgetHandle()) + Case ACTIVATE_CUT + flCutText(WidgetHandle()) + Case ACTIVATE_COPY + flCopyText(WidgetHandle()) + Case ACTIVATE_PASTE + flPasteText(WidgetHandle()) + Default + Super.Activate(cmd) + End Select + End Method + + Method SetTabs(tabs) +''''' flSetTextTabs( WidgetHandle(),tabs ) 'FIXME one of these days... + End Method + + Method CharAt(line) + Return flLinePos(WidgetHandle(),line) + End Method + + Method LineAt(index) + Return flLineCount(WidgetHandle(),index) + End Method + + Method CharX(char) + Local x%, y% + flCharPosXY(WidgetHandle(),char,Varptr x,Varptr y) + If x Then Return x Else Return -1 + EndMethod + + Method CharY(char) + Local x%, y% + flCharPosXY(WidgetHandle(),char,Varptr x,Varptr y) + If y Then Return y Else Return -1 + EndMethod + + Field intLastCursorPos = -1, intLastCursorLen = -1 + + Method CheckCursorPos(pEmitEvent% = True,pOverridePos% = -1) + Local tmpCursorPos + If pOverridePos < 0 Then tmpCursorPos = GetCursorPos(TEXTAREA_CHARS) Else tmpCursorPos = pOverridePos + Local tmpCursorLen = GetSelectionLength(TEXTAREA_CHARS) + If intLastCursorPos <> tmpCursorPos Or intLastCursorLen <> tmpCursorLen Then + intLastCursorPos = tmpCursorPos;intLastCursorLen = tmpCursorLen + If pEmitEvent Then PostGuiEvent(EVENT_GADGETSELECT,Self) + EndIf + EndMethod + + Method LockText() + locked:+1 + If locked=1 + lockedpos=GetCursorPos(TEXTAREA_CHARS) + lockedlen=GetSelectionLength(TEXTAREA_CHARS) + SetSelection(0,-1,TEXTAREA_CHARS) + EndIf + End Method + + Method UnlockText() + If Not locked Return + If locked=1 + SetSelection(lockedpos,lockedlen,TEXTAREA_CHARS) + flRedrawText WidgetHandle(),0,flTextLength(WidgetHandle()) + EndIf + locked:-1 + End Method + + Method flstyle() + Return flGetTextStyleChar(WidgetHandle(),textr,textg,textb,font.handle,font.GetSizeForFL()) + End Method + + Method SetTextColor( r,g,b ) + textr=r;textg=g;textb=b + flSetEditTextColor(WidgetHandle(),r,g,b) + flRedrawText WidgetHandle(),0,flTextLength(WidgetHandle()) + End Method + + Method SetFont( font:TGuiFont ) + Self.font=TFLGUIFont(font) + LockText() + flSetTextSize WidgetHandle(),Self.font.GetSizeForFL() + flSetTextFont WidgetHandle(),Self.font.handle + UnlockText() + End Method + + Method AreaText$(pos,count,units) + If units=TEXTAREA_LINES + count=flLinePos(WidgetHandle(),pos+count) + pos=flLinePos(WidgetHandle(),pos) + count:-pos + EndIf + Local tmpTextPtr:Byte Ptr = flGetText(WidgetHandle(),pos,count) + Local tmpText$ = String.FromCString(tmpTextPtr) + flFreePtr(tmpTextPtr) + Return tmpText + End Method + + Method AreaLen(units) + Local count=flTextLength(WidgetHandle()) + If units=TEXTAREA_LINES count=flLineCount(WidgetHandle(),count) + Return count + End Method + + Method AddText(text$) + ignore:+1 + Local utf8text:Byte Ptr=text.ToUTF8String() + flAddText(WidgetHandle(),utf8text) + MemFree utf8text + flSelectText WidgetHandle(),flTextLength(WidgetHandle()),0 + CheckCursorPos(False) + If Not locked flShowPosition(WidgetHandle()) + End Method + + Method ReplaceText(pos,count,text$,units) + If units=TEXTAREA_LINES + count=flLinePos(WidgetHandle(),pos+count) + pos=flLinePos(WidgetHandle(),pos) + count:-pos + EndIf + ignore:+1 + Local utf8text:Byte Ptr=text.ToUTF8String() + flReplaceText(WidgetHandle(),pos,count,utf8text) + MemFree utf8text + CheckCursorPos(False) + End Method + + Method GetCursorPos(units) + Local pos=flgetcursorpos(WidgetHandle()) + If units=TEXTAREA_LINES pos=flLineCount(WidgetHandle(),pos) + Return pos + End Method + + Method GetSelectionLength(units) + Local n=flgetselectionlen(WidgetHandle()) + If units=TEXTAREA_LINES + n=flLineCount(WidgetHandle(),flgetcursorpos(WidgetHandle())+n-1)+1-GetCursorPos(TEXTAREA_LINES) + EndIf + Return n + End Method + + Method SetStyle(r,g,b,flags,pos,count,units) + Local style,stext$ + + LockText() + style=flGetTextStyleChar(WidgetHandle(),r,g,b,font.flfamily.GetFontID(flags),font.GetSizeForFL()) + If Not style Then RuntimeError "SetStyle failed" + If units=TEXTAREA_LINES + count=flLinePos(WidgetHandle(),pos+count) + pos=flLinePos(WidgetHandle(),pos) + count:-pos + EndIf + If count<0 count=flTextLength(WidgetHandle())-pos + If count<=0 Return + stext=rept$(style,count) + flReplaceTextStyle WidgetHandle(),pos,count,stext + UnlockText() + + End Method + + Method SetSelection(pos,count,units) + If units=TEXTAREA_LINES + count=flLinePos(WidgetHandle(),pos+count) + pos=flLinePos(WidgetHandle(),pos) + count:-pos + If count<0 count=0 + EndIf + If count<0 count=flTextLength(WidgetHandle())-pos + If count<0 Return + intLastCursorPos = pos;intLastCursorLen = count + flSelectText WidgetHandle(),pos,count + CheckCursorPos(False) + If Not locked flShowPosition(WidgetHandle()) + EndMethod + + Method Free() + Local textbuff:Byte Ptr = Byte Ptr(flFreeTextDisplay( WidgetHandle() )) + Super.Free() + If textbuff Then FLDriver.QueueFLDelete(textbuff) + EndMethod + + Method OnCallback() + + Local x = fleventx()-AbsoluteX(), y = fleventy()-AbsoluteY() + + Select flevent() + Case FL_PUSH + If flEventButton()=FL_LEFT_MOUSE Or Not GetSelectionLength(TEXTAREA_CHARS) Then CheckCursorPos() 'EVENT_GADGETSELECT if cursor moved... + Case FL_RELEASE + CheckCursorPos() 'EVENT_GADGETSELECT if cursor moved... + If flEventButton()=FL_RIGHT_MOUSE PostGuiEvent(EVENT_GADGETMENU,Self,0,0,x,y) 'menu button + Case FL_KEYDOWN + If Not (style&TEXTAREA_READONLY) And flChanged(WidgetHandle()) Then + PostGuiEvent(EVENT_GADGETACTION,Self) + EndIf + CheckCursorPos() + Case FL_UNFOCUS + PostGuiEvent(EVENT_GADGETLOSTFOCUS,Self) + End Select + EndMethod + + Function EditHandler(pos,inserted,deleted,restyled,ctext:Byte Ptr,obj:Int) "C" + Local text$=String.FromCString(ctext) + Local textarea:TFLTextArea = TFLTextArea(HandleToObject(obj)) + If textarea Then + If deleted + flDeleteTextStyle textarea.WidgetHandle(),pos,pos+deleted + EndIf + If inserted + flInsertTextStyle textarea.WidgetHandle(),pos,rept$(textarea.flstyle(),inserted) + EndIf + If textarea.ignore Then textarea.ignore:-1;Return + If (inserted Or deleted) + textarea.CheckCursorPos(True,pos+inserted) + PostGuiEvent(EVENT_GADGETACTION,textarea) + EndIf + EndIf + End Function + + Function Rept$(c,n) + Local b:Byte[n] + memset_ b,c,n + Return String.FromBytes(b,n) + End Function + +EndType + +Type TFLListBox Extends TFLGadget + + Field Current = -1 + + Method InitGadget() + If (style&LISTBOX_MULTISELECT) Then fltype=FL_MULTIBROWSER Else fltype=FL_BROWSER + InitWidget() + EndMethod + + Method Class() + Return GADGET_LISTBOX + EndMethod + + Method SetFont(font:TGuiFont) + Self.font = TFLGUIFont(font) + flSetBrowserTextFont WidgetHandle(),Self.font.handle + flSetBrowserTextSize WidgetHandle(),Self.font.GetSizeForFL() + Local tmpItem:TGadgetItem + For Local i% = 0 Until items.length + tmpItem = TGadgetItem(items[i]) + SetListItem(i,tmpItem.text,tmpItem.tip,tmpItem.icon,tmpItem.extra) + Next + EndMethod + + Method InsertListItem(index,text$,tip$,icon,extra:Object) + If icons Then icon = icons.GetFLImage(icon) Else icon = 0 + flInsertBrowser(WidgetHandle(),index+1,BrowserFormatString()+text,extra,icon) + End Method + + Method SetListItem(index,text$,tip$,icon,extra:Object) + If icons Then icon = icons.GetFLImage(icon) Else icon = 0 + flSetBrowserItem(WidgetHandle(),index+1,BrowserFormatString()+text,extra,icon) + End Method + + Method RemoveListItem(index) + flRemoveBrowserItem(WidgetHandle(),index+1) + End Method + + Method SetListItemState(item,state) + If Not(style&LISTBOX_MULTISELECT) Then + If state&STATE_SELECTED + Current=item + flSelectBrowser(WidgetHandle(),item+1) + Else + If Current=item Current=-1 + flSelectBrowser(WidgetHandle(),0) + EndIf + Else + flMultiBrowserSelect(WidgetHandle(),item+1,(state&STATE_SELECTED<>0)) + SelectionChanged() + EndIf + End Method + + Method ListItemState(index) + Local state + If Not(style&LISTBOX_MULTISELECT) Then + If flBrowserValue(WidgetHandle())-1=index state:|STATE_SELECTED + Else + If flMultiBrowserSelected(WidgetHandle(),index+1) state:|STATE_SELECTED + EndIf + Return state + End Method + + Method OnCallback() + Local x = fleventx()-AbsoluteX(), y = fleventy()-AbsoluteY() + Local extra:Object, i + If style&LISTBOX_MULTISELECT <> LISTBOX_MULTISELECT Then + i=SelectedItem() + If i>-1 extra=ItemExtra(i) + If i<>Current + PostGuiEvent(EVENT_GADGETSELECT,Self,i,0,0,0,extra) + Current=i + EndIf + If flEventButton()=FL_RIGHT_MOUSE + PostGuiEvent(EVENT_GADGETMENU,Self,i,0,x,y,extra) + ElseIf flEventButton()=FL_LEFT_MOUSE And flEventClicks() Mod 2 + If i>-1 Then + PostGuiEvent(EVENT_GADGETACTION,Self,i,0,0,0,extra) + EndIf + EndIf + Else + i = SelectionChanged() + If i > -1 Then + extra = ItemExtra(i) + PostGuiEvent(EVENT_GADGETSELECT,Self,i,0,0,0,extra) + ElseIf flEventButton()=FL_LEFT_MOUSE And flEventClicks() Mod 2 Then + i = flBrowserValue(WidgetHandle())-1 + If i > -1 Then PostGuiEvent(EVENT_GADGETACTION,Self,i,0,0,0,ItemExtra(i)) + EndIf + If flEventButton()=FL_RIGHT_MOUSE Then + i = flBrowserValue(WidgetHandle())-1;extra = Null + If i > -1 Then extra = ItemExtra(i) + PostGuiEvent(EVENT_GADGETMENU,Self,i,0,x,y,extra) + EndIf + EndIf + EndMethod + + Method BrowserFormatString$() + Local tmpResult$ + Select fltype + Case FL_BROWSER, FL_MULTIBROWSER + If font.style&FONT_UNDERLINE Then tmpResult:+"@u" + If font.style&FONT_STRIKETHROUGH Then tmpResult:+"@-" + tmpResult:+"@." + EndSelect + Return tmpResult + EndMethod + +EndType + +Type TFLComboBox Extends TFLGadget + + Field _lastchoice = -1 + + Method InitGadget() + If (style&COMBOBOX_EDITABLE) Then fltype=FL_INPUTCHOICE Else fltype=FL_CHOICE + InitWidget() + EndMethod + + Method Class() + Return GADGET_COMBOBOX + EndMethod + + Method GetText$() + If (style&COMBOBOX_EDITABLE) Then + Return flGetInput(flGetInputChoiceTextWidget(WidgetHandle())) + Else + If _lastchoice > -1 Then Return GadgetItemText(Self,_lastchoice) + EndIf + EndMethod + + Method SetText(text$) + If style&COMBOBOX_EDITABLE Then flSetInput(flGetInputChoiceTextWidget(WidgetHandle()),text) + EndMethod + + Method InsertListItem(index,text$,tip$,icon,extra:Object) + Local m:TFLMenu = New TFLMenu + GetMenu() + menu.owner=Self + m.text=text + menu.addmenu m + Local count,flmenu Ptr + count=menu.count(-1) + flmenu=flCreateMenu(count+2,CallbackHandler) + menu.setflmenu(flmenu) + If style&COMBOBOX_EDITABLE Then flSetMenu(flGetInputChoiceMenuWidget(WidgetHandle()),flmenu) Else flSetMenu(WidgetHandle(),flmenu) + End Method + + Method SetListItem(index,text$,tip$,icon,extra:Object) + 'Save current selection + Local selection = SelectedGadgetItem(Self) + GetMenu() + 'Update item + Local m:TFLMenu = menu.mkids[index] + m.text=text + 'Create a new menu + Local count,flmenu Ptr + count=menu.count(-1) + flmenu=flCreateMenu(count+2,CallbackHandler) + menu.setflmenu(flmenu) + 'Apply new menu + If style&COMBOBOX_EDITABLE Then flSetMenu(flGetInputChoiceMenuWidget(WidgetHandle()),flmenu) Else flSetMenu(WidgetHandle(),flmenu) + 'Restore selection + If selection > -1 Then SelectGadgetItem(Self, selection) + End Method + + Method RemoveListItem(index) + Local m:TFLMenu + GetMenu() + menu.owner=Self + menu.removemenu index + Local count,flmenu Ptr + count=menu.count(-1) + flmenu=flCreateMenu(count+2,CallbackHandler) + menu.setflmenu(flmenu) + If style&COMBOBOX_EDITABLE Then flSetMenu(flGetInputChoiceMenuWidget(WidgetHandle()),flmenu) Else flSetMenu(WidgetHandle(),flmenu) + End Method + + Method SetListItemState(item,state) + If Not(style&COMBOBOX_EDITABLE) Then + If state&STATE_SELECTED Then flSetChoice(WidgetHandle(),item) + Else + If state&STATE_SELECTED Then flSetInputChoice(WidgetHandle(),item) + EndIf + End Method + + Method ListItemState(index) + Local state + If Not(Style&COMBOBOX_EDITABLE) Then + If flGetChoice(WidgetHandle())=index state:|STATE_SELECTED + Else + If _lastchoice=index state:|STATE_SELECTED + EndIf + Return state + End Method + + Method OnCallback() + Select flevent() + Case FL_KEYDOWN + Local text$ = fleventtext() + If text Then + _lastchoice = -1 + PostGuiEvent(EVENT_GADGETACTION,Self,_lastchoice) + EndIf + Case FL_UNFOCUS + PostGuiEvent(EVENT_GADGETLOSTFOCUS,Self) + End Select + EndMethod + +EndType + +Type TFLTabber Extends TFLGadget + + Const TABBODY_SPACING = 5 + + Field tabpanels:TFLWidget[] + Field selectedtab = -1 + + 'WARNING: TFLTabber is in a very fragile state in order to acquire the correct positioning + 'of gadgets. + + Method InitGadget() + + fltype = FL_TABS + InitWidget() + + SetOrigin(1,20+TABBODY_SPACING) + + client=New TFLPanel.CreateGadget("",0,0,ClientWidth(),ClientHeight(),Self,0) + client.SetLayout EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED + + RemoveChild(client) + + EndMethod + + Method Class() + Return GADGET_TABBER + EndMethod + + Method ClientWidth() + Return Max(width-originx,0) + EndMethod + + Method ClientHeight() + Return Max(height-originy,0) + EndMethod + + Method OnCallback() + Local selhandle=flGetTabPanel(WidgetHandle()) + Local eventhandle=flGetTabPanelForEvent(WidgetHandle()) + Local x = fleventx()-AbsoluteX(), y = fleventy()-AbsoluteY() + For Local panel:TFLWidget=EachIn tabpanels + If panel.WidgetHandle()=selhandle Then + If panel.tag<>selectedtab + SetListItemState panel.tag, STATE_SELECTED + PostGuiEvent(EVENT_GADGETACTION,Self,panel.tag,0,0,0,ItemExtra(panel.tag)) + EndIf + EndIf + If panel.WidgetHandle()=eventhandle + Select flevent() + Case FL_PUSH + If flEventButton() = FL_RIGHT_MOUSE Then + PostGuiEvent(EVENT_GADGETMENU,Self,panel.tag,0,x,y,ItemExtra(panel.tag)) + EndIf + EndSelect + EndIf + Next + EndMethod + + Method InsertListItem(index,text$,tip$,icon,extra:Object) + Local panel:TFLWidget,x,y,w,h,client:TFLWidget = Self.client + 'Make sure that we attach the tab panel to the tabber (not the client). + Self.client = Null + panel=TFLWidget(New TFLWidget.CreateWidget(FL_GROUP,text,0,-TABBODY_SPACING,ClientWidth(),ClientHeight()+TABBODY_SPACING,Self,-1,FL_NO_BOX)) + 'Make sure tab panels are resized first by LayoutKids(). + 'If we don't do this, and children are added before tab panels, + 'the children don't may not drawn correctly (if at all). + kids.Remove(panel);kids.AddFirst(panel) + 'After creating the tab panel, we can restore the client area for user gadgets. + Self.client = client + 'Set the tabpanel options + If tooltip Then panel.SetTooltip tip$ + panel.SetOrigin(0,TABBODY_SPACING) + panel.SetLayout EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED + panel.tag=index + 'Position the tab panel in the indexed array + tabpanels = tabpanels[..index]+[panel]+tabpanels[index..] + For Local i% = index+1 Until tabpanels.length + tabpanels[i].tag:+1 + Next + 'And update the selected tab if necessary + If selectedtab < 0 Then selectedtab = index ElseIf index < selectedtab Then selectedtab:+1 + Local tmpSelection% = selectedtab + 'Select new tab so that is correctly handled by Fl_Tabs + selectedtab = -1;SetListItemState index,STATE_SELECTED + 'And then restore selection to the previous tab + SetListItemState tmpSelection,STATE_SELECTED + End Method + + Method SetListItemState(index,state) + If state&STATE_SELECTED Then + Local indextab:TFLWidget = tabpanels[index] + If selectedtab<>index + selectedtab=index + indextab.AddChild client + client.SetShape( 0, 0, ClientWidth(), ClientHeight() ) + LayoutKids() + flSelectTab WidgetHandle(),indextab.WidgetHandle() + EndIf + EndIf + End Method + + Method ListItemState(index) + Local tmpState + If index = selectedtab Then tmpState:|STATE_SELECTED + Return tmpState + End Method + + Method SetListItem(index,text$,tip$,icon,extra:Object) + Local indextab:TFLWidget = tabpanels[index] + If indextab Then + indextab.SetText(text) + indextab.SetTooltip(tip) + 'If icon>0 Then + ' indextab.SetPixmap(PixmapFromIconStrip(icons,icon),GADGETPIXMAP_ICON) + 'Else + ' indextab.SetPixmap(Null,GADGETPIXMAP_ICON) + 'EndIf + SetDirty() + EndIf + End Method + + Method RemoveListItem(index) + Local indextab:TFLWidget + Local panels:TFLWidget[] + Local i + indextab=tabpanels[index] + If Not indextab Then Return + If index = selectedtab Then indextab.RemoveChild client + ' free widget + indextab.free() + ' remove from array + panels=tabpanels + tabpanels=tabpanels[..tabpanels.length-1] + For i=index Until tabpanels.length + tabpanels[i]=panels[i+1] + tabpanels[i].tag=i + Next + index=Min(index,tabpanels.length-1) + If index<>-1 SetListItemState index, STATE_SELECTED + If parent RedrawGadget parent 'parent.Redraw'SetDirty + End Method + +EndType + +Type TFLTreeview Extends TFLGadget + + Field root:TFLNode + + Method InitGadget() + fltype = FLU_TREEBROWSER + InitWidget() + EndMethod + + Method Class() + Return GADGET_TREEVIEW + EndMethod + + Method RootNode:TFLNode() + If Not root + root=New TFLNode + root.owner=Self + root.nodehandle = fluRootNode(WidgetHandle()) + kids.AddLast root + EndIf + Return root + End Method + + Method SelectNode(node:TFLNode) + fluSelectNode(node.nodehandle) + End Method + + Method SelectedNode:TGadget() + Local tmpNodeHandle:Int = fluSelectedNode(WidgetHandle(),1) 'Base 1 for some reason + If tmpNodeHandle Then + Local tmpNode:TFLNode = TFLNode.FromHandle(tmpNodeHandle) + If tmpNode <> RootNode() Then Return tmpNode + EndIf + End Method + + Field _lastButtonPressed:Int + + Method OnMouse:Int() + Local tmpButton:Int = flEventButton() + Select flEvent() + Case FL_PUSH + _lastButtonPressed = tmpButton + If tmpButton = FL_RIGHT_MOUSE Then + PostGuiEvent EVENT_GADGETMENU, Self, tmpButton-1, flStateToModifiers(flEventState()), flEventX()-AbsoluteX(), flEventY()-AbsoluteY(), SelectedNode() + EndIf + Case FL_DRAG + If (style&TREEVIEW_DRAGNDROP) And Not dragGadget[_lastButtonPressed-1] Then + dragGadget[_lastButtonPressed-1] = SelectedNode() + PostGuiEvent EVENT_GADGETDRAG, Self, _lastButtonPressed, flStateToModifiers(flEventState()), flEventX()-AbsoluteX(), flEventY()-AbsoluteY(), dragGadget[_lastButtonPressed-1] + EndIf + EndSelect + + Super.OnMouse() + EndMethod + + Method OnCallback() + Local intReason% = fluCallbackReason( WidgetHandle() ) + Local tmpNode:TFLNode = TFLNode.FromHandle(fluCallbackNode( WidgetHandle() )) + Select intReason + Case FLU_OPENED;PostGuiEvent EVENT_GADGETOPEN, Self, 0, 0, 0, 0, tmpNode + Case FLU_CLOSED;PostGuiEvent EVENT_GADGETCLOSE, Self, 0, 0, 0, 0, tmpNode + Case FLU_SELECTED, FLU_DOUBLE_CLICK + If intReason = FLU_SELECTED Then + PostGuiEvent EVENT_GADGETSELECT, Self, 0, 0, 0, 0, tmpNode + Else + PostGuiEvent EVENT_GADGETACTION, Self, 0, 0, 0, 0, tmpNode + EndIf + EndSelect + EndMethod + +EndType + + +Type TFLNode Extends TFLWidget + + Field owner:TFLTreeview, nodehandle% + Field text$, icon = -1, textmem:Byte Ptr + + Method Delete() + Free() + End Method + + Method GetText$() + Return text + End Method + + Method SetText(newtext$) + Local tmpIcon + If textmem Then MemFree textmem;textmem = Null + text = newtext + textmem = text.ToCString() + If icon >= 0 And owner.icons Then tmpIcon = owner.icons.images[icon] Else tmpIcon = 0 + If nodehandle Then fluSetNode( nodehandle, textmem, tmpicon ) + End Method + + Method InsertNode:TGadget(pos,text$,icon) + + Local n:TFLNode, l:TLink + + If pos >= 0 And pos < kids.count() + n=TFLNode(kids.ValueAtIndex(pos)) + l=kids.FindLink(n) + EndIf + + n=New TFLNode + n.parent=Self + n.owner=owner + n.icon=icon + + If l Then + n.nodehandle = fluInsertNode( nodehandle, pos, inittext ) + fluSetNodeUserData( n.nodehandle, n.objhandle ) + kids.InsertBeforeLink n,l + Else + n.nodehandle = fluAddNode( nodehandle, inittext ) + fluSetNodeUserData( n.nodehandle, n.objhandle ) + kids.AddLast n + EndIf + + If LocalizationMode() & LOCALIZATION_OVERRIDE Then + LocalizeGadget(n,text) + Else + n.SetText(text) + EndIf + + Return n + + End Method + + Method Free() + If Not nodehandle Then Return 'Make sure we don't free twice + Super.Free() + fluSetNodeUserData( nodehandle, 0 ) + fluRemoveNode( owner.WidgetHandle(), nodehandle ) + If textmem Then MemFree textmem;textmem = Null + If owner And owner.root <> Self Then 'If not TreeViewRoot() + owner = Null;nodehandle = 0 + EndIf + End Method + + Method ModifyNode(text$,icon) + Self.icon = icon;SetText(text) + End Method + + Method Activate(cmd) + Select cmd + Case ACTIVATE_SELECT + Local tmpParent:TFLNode = TFLNode(parent) + While tmpParent + tmpParent.Activate(ACTIVATE_EXPAND) + tmpParent = TFLNode(tmpParent.parent) + Wend + fluSelectNode( nodehandle ) + Case ACTIVATE_EXPAND + fluExpandNode( nodehandle, False ) + Case ACTIVATE_COLLAPSE + fluExpandNode( nodehandle, True ) + End Select + End Method + + Method Class() + Return GADGET_NODE + EndMethod + + Function FromHandle:TFLNode(nodehandle) + If nodehandle Then Return TFLNode(HandleToObject(fluNodeUserData( nodehandle ))) + EndFunction + + Method SetTooltip(tooltip$) + 'Do nothing - nodes don't support tooltips (yet). + EndMethod + +End Type + + +Type TFLSlider Extends TFLGadget + + 'Spinner controls + Field minimum = 1, maximum = 10 + Field spinval = minimum + Field up:TFLWidget, down:TFLWidget + + Method InitGadget() + If (style&SLIDER_TRACKBAR) = SLIDER_TRACKBAR Then + fltype = FL_SLIDER + ElseIf (style&SLIDER_STEPPER) = SLIDER_STEPPER Then + fltype = FL_GROUP + Else + fltype = FL_SCROLLBAR + EndIf + InitWidget() + If (style&SLIDER_STEPPER) = SLIDER_STEPPER Then + If (style&SLIDER_HORIZONTAL) + up = New TFLSpinButton.CreateWidget(FL_REPEATBUTTON,"@#>",width/2,0,width/2,height,Self) + SetGadgetLayout up,EDGE_RELATIVE,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED + down = New TFLSpinButton.CreateWidget(FL_REPEATBUTTON,"@#<",0,0,width/2,height,Self) + SetGadgetLayout down,EDGE_ALIGNED,EDGE_RELATIVE,EDGE_ALIGNED,EDGE_ALIGNED + Else + up = New TFLSpinButton.CreateWidget(FL_REPEATBUTTON,"@#2<",0,0,width,height/2,Self) + SetGadgetLayout up,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_RELATIVE + down = New TFLSpinButton.CreateWidget(FL_REPEATBUTTON,"@#2>",0,height/2,width,height/2,Self) + SetGadgetLayout down,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_RELATIVE,EDGE_ALIGNED + EndIf + Else + If (style&SLIDER_HORIZONTAL) Then flSetSliderType WidgetHandle(),FL_HOR_SLIDER + EndIf + EndMethod + + Method Class() + Return GADGET_SLIDER + EndMethod + + Method SetRange(small,big) + If (style&SLIDER_STEPPER) = SLIDER_STEPPER Then + minimum = small + maximum = big + SetProp(spinval) + ElseIf fltype=FL_SCROLLBAR Then + flSetScrollbarValue WidgetHandle(), GetProp(), small, 0, big + Else + flSetSliderRange WidgetHandle(),small,big + EndIf + End Method + + Method SetProp(value) + If (style&SLIDER_STEPPER) = SLIDER_STEPPER Then + spinval = Min( Max( value, minimum ), maximum ) + Else + flSetSliderValue WidgetHandle(),value + EndIf + End Method + + Method GetProp() + If (style&SLIDER_STEPPER) = SLIDER_STEPPER Then + Return spinval + Else + Return flSliderValue(WidgetHandle()) + EndIf + End Method + + Method OnSpin(pSource:TFLWidget) + Local tmpNewVal = spinval + Select pSource + Case up;tmpNewVal:+1 + Case down;tmpNewVal:-1 + EndSelect + tmpNewVal = Min( Max( tmpNewVal, minimum ), maximum ) + If tmpNewVal <> spinval Then + spinval = tmpNewVal + OnCallback() + EndIf + EndMethod + + Method OnCallback() + PostGuiEvent(EVENT_GADGETACTION,Self,GetProp()) + EndMethod + +EndType + +Type TFLSpinButton Extends TFLWidget + + Method Class() + Return GADGET_SLIDER + EndMethod + + Method OnCallback() + TFLSlider(parent).OnSpin(Self) + EndMethod + + Const SYMBOL_WIDTH% = 13, SYMBOL_HEIGHT = 7 + + Method Rethink() + 'Attempts to resizes arrow heads in line with dimensions + Local scaletxt$, text$ = GetText()[2..] + 'Strip current size info from arrow label string + If text[..1] = "+" Or text[..1] = "-" Then text = text[2..] + 'Calculate the most suitable scaling + Local scale# = Min( width, height ) + scale:/ Max( SYMBOL_WIDTH, SYMBOL_HEIGHT ) + 'Sort out the sign of the scaling + If Int(scale) < 1 Then + scale = 1/scale + scaletxt = "-" + ElseIf Int(scale) > 1 Then + scale:-1 + scaletxt = "+" + Else + scale = 0 + EndIf + 'And clamp the value to a single digit + scale = Min(scale,9) + 'Then, if we need to scale, lets set the label accordingly + If Int(scale) >= 1 Then text = scaletxt + Int(scale) + text + SetText( "@#"+text ) + Super.Rethink() + EndMethod + +EndType + +Type TFLProgBar Extends TFLGadget + + Method InitGadget() + fltype=FL_PROGBAR + InitWidget() + EndMethod + + Method Class() + Return GADGET_PROGBAR + EndMethod + + Method SetValue(value#) + flSetProgress WidgetHandle(),value + parent.activate ACTIVATE_REDRAW + End Method + +EndType + +Type TFLPanel Extends TFLGadget +'TFLCanvas, TFLToolbar and TFLToolbarItem extend TFLPanel + + Method InitGadget() + fltype = FL_PANEL + InitWidget() + Select style&(PANEL_GROUP|PANEL_SUNKEN|PANEL_RAISED) + Case 0;flSetBox WidgetHandle(), FL_NO_BOX, False + Case PANEL_SUNKEN;flSetBox WidgetHandle(), FL_DOWN_FRAME, False + Case PANEL_RAISED;flSetBox WidgetHandle(), FL_UP_FRAME, False + Default;SetOrigin(4,18) + EndSelect + If (style&PANEL_ACTIVE) Then SetSensitivity(SENSITIZE_ALL) + EndMethod + + Method Class() + Return GADGET_PANEL + EndMethod + + Method SetEnabled(truefalse) + Super.SetEnabled(truefalse) + flSetPanelEnabled WidgetHandle(),truefalse + EndMethod + + Method Rethink() + SetFLImage(image) + Super.Rethink() + EndMethod + + Method SetFLImage(image) + Self.image = image + flSetPanelImage(WidgetHandle(),image,pixmapflags) + End Method + + Method SetColor( r,g,b ) + flSetPanelColor(WidgetHandle(),r,g,b) + Redraw() + End Method + + Method SetSensitivity(pSensitivity%) + Super.SetSensitivity(pSensitivity) + flSetPanelActive WidgetHandle(), (GetSensitivity()<>0) + EndMethod + + Method OnMouse() + Select flevent() + Case FL_PUSH + flSetFocus(Query(QUERY_FLWIDGET_CLIENT)) + EndSelect + Super.OnMouse() + EndMethod + +EndType + +Type TFLCanvas Extends TFLPanel + + Field driver$ + Field canvas:TGraphics + Field canvasflags + + Method InitGadget() + fltype=FL_CANVAS + InitWidget() + flSetCanvasMode WidgetHandle(),DefaultGraphicsFlags() + SetSensitivity(SENSITIZE_ALL) + SetShow(True) + EndMethod + + Method Class() + Return GADGET_CANVAS + EndMethod + + Method SetText(text$) + driver=text + EndMethod + + Method GetText$() + Return driver + EndMethod + + Method AttachGraphics:TGraphics( flags ) + canvasflags=flags + ?MacOS + canvas=brl.Graphics.AttachGraphics( NSContentView(flCanvasWindow(WidgetHandle())),flags ) + ?Not MacOS + canvas=brl.Graphics.AttachGraphics( flCanvasWindow(WidgetHandle()),flags ) + ? + End Method + + Method CanvasGraphics:TGraphics() + Return canvas + End Method + + Method SetShow(truefalse) + flSetShow(WidgetHandle(),truefalse) + End Method + + Method Free() + Super.Free() + If canvas + canvas.Close() + canvas=Null + EndIf + EndMethod + + Method SetFLImage(image) + EndMethod + + Method SetColor(r,g,b) + EndMethod + + Method OnCallback() + Select flevent() + Case FL_ACTIVATE + ?MacOS + NSUpdateCanvas(flCanvasWindow(WidgetHandle())) + ? + PostGuiEvent EVENT_GADGETPAINT,Self + End Select + Super.OnCallback() + EndMethod + +End Type + +Type TFLToolbar Extends TFLGadget + + Method InitGadget() + Local tmpClient:TFLWidget = TFLWidget(parent).client + TFLWidget(parent).client = Null + fltype=FL_TOOLBAR + InitWidget() + TFLWidget(parent).client = tmpClient + flSetBox(WidgetHandle(),FL_NO_BOX,False) + LayoutToolbar() + SetLayout(EDGE_ALIGNED,EDGE_CENTERED,EDGE_ALIGNED,EDGE_CENTERED) + EndMethod + + Method Class() + Return GADGET_TOOLBAR + EndMethod + + Method AbsoluteX() + Local tmpValue:Int = Super.AbsoluteX() + If TFLWidget(parent) Then tmpValue:-TFLWidget(parent).originx + Return tmpValue + End Method + + Method AbsoluteY() + Local tmpValue:Int = Super.AbsoluteY() + If TFLWidget(parent) Then tmpValue:-TFLWidget(parent).originy + Return tmpValue + End Method + + Method SetShow(truefalse) + If truefalse ~ ((State() & STATE_HIDDEN) = 0) Then + Super.SetShow(truefalse) + LayoutToolbar() + EndIf + EndMethod + + Method SetLayout(Left,Right,top,bottom) + Super.SetLayout(EDGE_ALIGNED,EDGE_CENTERED,EDGE_ALIGNED,EDGE_CENTERED) + EndMethod + +' toolbar specific + + Method SetListItemState(index,state) + Local item:TFLToolbarItem = ToolPanel(index) + If item Then + If state&STATE_SELECTED Then item.toggled = True Else item.toggled = False + item.SetEnabled( Not (state&STATE_DISABLED) ) + item.Redraw() + EndIf + End Method + + Method ListItemState(index) + Local state, item:TFLToolbarItem = ToolPanel(index) + If item + If item.State() & STATE_DISABLED Then state:|STATE_DISABLED + If item.toggled Then state:|STATE_SELECTED + EndIf + Return state + End Method + + Method InsertListItem(index,text$,tip$,icon,extra:Object) + ' bump button panel indexes + For Local item:TFLToolbarItem = EachIn kids + If item.tag>=index item.tag:+1 + Next + SetListItem index,text,tip,icon,extra + End Method + + Method RemoveListItem(index) + Local item:TFLToolbarItem = ToolPanel(index) + If item Then + item.CleanUp() + For Local tmpToolPanel:TFLToolbarItem = EachIn kids + If tmpToolPanel.tag > index Then tmpToolPanel.tag:-1 + Next + LayoutToolBar() + EndIf + EndMethod + + Method GetBestHeight() + If icons Then Return icons.pixmap.height+6 + EndMethod + + Method SetListItem(index,text$,tip$,icon,extra:Object) + + Local image, item:TFLToolbarItem = ToolPanel(index) + + If icons Then image = icons.GetFLImage(icon) + + If Not item Then + item=TFLToolbarItem(New TFLToolbarItem.CreateGadget("",0,0,TFLToolbarItem.DIVIDER_WIDTH,GetBestHeight(),Self,PANEL_ACTIVE)) + item.SetLayout EDGE_ALIGNED,EDGE_CENTERED,EDGE_ALIGNED,EDGE_CENTERED + item.tag=index + EndIf + + item.SetFLImage image + item.SetToolTip tip + + If image Then item.MakeIcon() Else item.MakeDivider() + + LayoutToolBar() + + End Method + + Method ToolPanel:TFLToolbarItem(index) + For Local panel:TFLToolbarItem=EachIn kids + If panel.tag=index Return panel + Next + End Method + + Method SetIconStrip( iconstrip:TIconStrip ) + Super.SetIconStrip(iconstrip) + For Local i:Int = 0 Until items.length + ModifyGadgetItem( Self, i, items[i].text, items[i].flags, items[i].icon, items[i].tip, items[i].extra ) + Next + LayoutToolbar() + EndMethod + + Method SetShape(x,y,w,h) + LayoutToolbar() + EndMethod + + Method Free() + SetShow(False) + Super.Free() + EndMethod + + Method LayoutToolBar() + Local item:TGadgetItem + Local x = 4, y= 4, w, h = GetBestHeight(), index + Local panel:TFLToolbarItem + For item=EachIn items + panel=ToolPanel(index) + If panel + w=panel.width + panel.SetShape x+1,y,w,h + x:+w+2 + EndIf + index:+1 + Next + If (State() & STATE_HIDDEN) Then h = 0 Else If items h:+8 + If height <> h Then + TFLWidget(parent).SetOrigin(TFLWidget(parent).originx,TFLWidget(parent).originy-height+h) + parent.Rethink() + EndIf + Super.SetShape 0,0,x+60,h + End Method + +EndType + +Type TFLToolbarItem Extends TFLPanel + + Const DIVIDER_WIDTH:Int = 2 + + Field toggled = False + + Method AbsoluteX() + Return TFLWidget(parent).AbsoluteX() + xpos + End Method + + Method AbsoluteY() + Return TFLWidget(parent).AbsoluteY() + ypos + End Method + + Method Class() + Return GADGET_TOOLBAR + EndMethod + + Method SetEnabled(bool) + Super.SetEnabled(bool) + If Not bool Then flSetBox( WidgetHandle(), FL_NO_BOX, False ) + EndMethod + + Method Free() + 'Stop Super.Free() from deleting an image that belongs to an icon-strip. + image = 0 + 'Now we can safely call Super.Free() + Super.Free() + EndMethod + + Method SetFLImage(image) + pixmapflags = PANELPIXMAP_CENTER + Super.SetFLImage(image) + EndMethod + + Method IsDivider() + Return (width <= DIVIDER_WIDTH) + EndMethod + + Method MakeDivider() + SetRect(xpos,ypos,DIVIDER_WIDTH,height) + flSetBox( WidgetHandle(), FL_EMBOSSED_FRAME, False) + EndMethod + + Method MakeIcon() + SetRect(xpos,ypos,height,height) + flSetBox( WidgetHandle(), FL_NO_BOX, False) + EndMethod + + Method OnMouse() + + Local x = fleventx()-AbsoluteX(), y = fleventy()-AbsoluteY() + + If activepanel And (activepanel<>Self) Then + activepanel.OnMouseLeave() + activepanel = Null + EndIf + + If Not ((State()&STATE_DISABLED) Or IsDivider()) And flEventButton() = FL_LEFT_MOUSE Then 'Not disabled + Select flevent() + Case FL_PUSH + flSetBox( WidgetHandle(), FL_THIN_DOWN_BOX, True ) + Case FL_MOVE + If activepanel <> Self Then + flSetBox( WidgetHandle(), FL_THIN_UP_BOX, True ) + activePanel = Self + EndIf + Case FL_DRAG + If x < width And y < height And x > 0 And y > 0 Then + flSetBox( WidgetHandle(), FL_THIN_DOWN_BOX, True ) + Else + flSetBox( WidgetHandle(), FL_NO_BOX, True ) + EndIf + Case FL_RELEASE + If x < width And y < height And x > 0 And y > 0 Then + Local item=tag&$ffff, flags=parent.ItemFlags(item) + If flags&GADGETITEM_TOGGLE Then parent.SelectItem(item,2) + PostGuiEvent(EVENT_GADGETACTION,parent,item,0,0,0) + EndIf + flSetBox( WidgetHandle(), FL_THIN_UP_BOX, True ) + Default + Return + EndSelect + EndIf + + EndMethod + + Method OnMouseLeave() + flSetBox( WidgetHandle(), FL_NO_BOX, True ) + EndMethod + +EndType + +Type TFLHTMLView Extends TFLGadget + + Field currenturl$ + Field history:TList + Field historylink:TLink + Field hpos:TList + Field hposlink:TLink + + Method InitGadget() + fltype=FL_HELPVIEW + InitWidget() + flSetBox( WidgetHandle(), FL_THIN_DOWN_BOX, False ) + flSetStyleView( WidgetHandle(), style ) + EndMethod + + Method Class() + Return GADGET_HTMLVIEW + EndMethod + + Method GetText$() + Return currenturl$ + EndMethod + + Method SetText(text$) + SetURL(text) + EndMethod + + Method Activate(cmd) + Select cmd + Case ACTIVATE_FORWARD + ForwardURL() + Case ACTIVATE_BACK + BackURL() + Default + Super.Activate(cmd) + End Select + End Method + + Method OnCallback() + RequestURL(flEventURL()) + EndMethod + + Method CleanHTML$(src$) + Return src + End Method + + Method RequestURL(path$) + Local curr$, lpath$ + + If Not path Return + path=path.Replace("\","/") + curr="file:"+CurrentDir() + If path[..curr.length]=curr + path=ExtractDir(currenturl)+path[curr.length..] + EndIf + + lpath = path.ToLower() + + Select ExtractExt$(lpath) + Case "png","jpg","jpeg","gif","bmp" + flRedirectView WidgetHandle(),path + Default + PostGuiEvent(EVENT_GADGETACTION,Self,0,0,0,0,path) + If Not (style & HTMLVIEW_NONAVIGATE) ' markcw + If lpath.StartsWith("ftp:") Or lpath.StartsWith("http:").. + Or lpath.StartsWith("https:") Or lpath.StartsWith("ipp:").. + Or lpath.StartsWith("mailto:") Or lpath.StartsWith("news:") + OpenURL path + EndIf + EndIf + End Select + End Method + + Method BackURL() + If historylink And historylink.PrevLink() + historylink=historylink.PrevLink() + If hposlink + hposlink._value=String(flGetLineView(flhandle)) + If hposlink.PrevLink() hposlink=hposlink.PrevLink() + SetURL String(historylink.Value()),False + EndIf + EndIf + End Method + + Method ForwardURL() + If historylink And historylink.NextLink() + historylink=historylink.NextLink() + If hposlink + hposlink._value=String(flGetLineView(flhandle)) + If hposlink.NextLink() hposlink=hposlink.NextLink() + SetURL String(historylink.Value()),False + EndIf + EndIf + End Method + + Method SetURL(path$,addhistory=True) + Local stream:TStream + Local hash,anchor$ + Local html$,script=0 + + If addhistory + currenturl=flGetPathView(flhandle) + If Not flIsLinkView(flhandle) currenturl=path + If currenturl.find("#")<>-1 path=currenturl + If hposlink hposlink._value=String(flGetLineView(flhandle)) + If currenturl.StartsWith("javascript:history.back()") + If historylink And historylink.PrevLink() + historylink=historylink.PrevLink() + hposlink=hposlink.PrevLink() + EndIf + If historylink path=String(historylink.Value()) + script=1 + ElseIf currenturl.StartsWith("javascript:history.forward()") + If historylink And historylink.NextLink() + historylink=historylink.NextLink() + hposlink=hposlink.NextLink() + EndIf + If historylink path=String(historylink.Value()) + script=1 + ElseIf currenturl.StartsWith("javascript:history.go(") + If currenturl[22..23] = "-" + If historylink And historylink.PrevLink() + historylink=historylink.PrevLink() + hposlink=hposlink.PrevLink() + EndIf + Else + If historylink And historylink.NextLink() + historylink=historylink.NextLink() + hposlink=hposlink.NextLink() + EndIf + EndIf + If historylink path=String(historylink.Value()) + script=1 + EndIf + If Not path Return False + EndIf + + currenturl=path + flSetPathView(flhandle,currenturl) + If path[..5]="file:" path=path[5..] + hash=path.find("#") + If hash<>-1 + anchor=path[hash+1..] + path=path[..hash] + EndIf + stream=ReadStream(path) + If stream + html=LoadString(stream) + CloseStream stream + html=CleanHTML(html) + EndIf + + flSetView(flhandle,html) + If addhistory And (Not script) + If anchor flSeekView(flhandle,anchor) + If Not history history=New TList + While historylink And historylink.NextLink() + historylink.NextLink().Remove + Wend + historylink=history.AddLast(currenturl) + If Not hpos hpos=New TList + While hposlink And hposlink.NextLink() + hposlink.NextLink().Remove + Wend + hposlink=hpos.AddLast(String(flGetLineView(flhandle))) + Else + flSetLineView(flhandle,Int(String(hposlink.Value()))) + EndIf + Return True + End Method + + Function ViewHandler:Byte Ptr(flhandle,uri:Byte Ptr) "C" + Return Null + End Function + +EndType + +Type TFLMenu Extends TFLWidget + + Field text$ + Field owner:TFLGadget + Field mparent:TFLMenu + Field mkids:TFLMenu[] + Field checked,disabled,divider,check + Field index + Field flshortcut + + Method Delete() + Free() + EndMethod + + Method Class() + Return GADGET_MENUITEM + EndMethod + + Function CreateMenu:TFLMenu( text$,tag,parent:TFLMenu ) + Local m:TFLMenu = New TFLMenu + m.text=text + m.tag=tag + If parent + m.parent=parent + parent.AddMenu m + EndIf + If LocalizationMode() & LOCALIZATION_OVERRIDE Then LocalizeGadget(m,text) + Return m + End Function + + Method OnCallback() + Local m:TFLMenu = Self +' choice menu + While (m) + If TFLComboBox(m.owner) + TFLComboBox(m.owner)._lastchoice = index + m.owner.SetText(text) + PostGuiEvent(EVENT_GADGETACTION,m.owner,index) + Return + EndIf + m=m.mparent + Wend +' window menu + If check Then checked = Not checked + PostGuiEvent(EVENT_MENUACTION,Self,tag) + End Method + + Method Free() + Local k:TFLMenu = mparent + If k And k.mkids + For Local i:Int = 0 Until k.mkids.length + If k.mkids[i]=Self + k.mkids=k.mkids[..i] + k.mkids[i+1..] + Exit + EndIf + Next + EndIf + owner = Null;mkids = Null;mparent = Null;parent = Null + If objhandle Then + Release objhandle + objhandle = 0 + EndIf + End Method + + Method count(id) 'recursively assign unique index to each node in tree, skips number for pop + index=id + id:+1 + If mkids + For Local m:TFLMenu = EachIn mkids + id=m.count(id) + Next + id:+1 + EndIf + Return id + End Method + + Method SetFLMenu(flmenu Ptr) 'recursively set hosts menuitem slots + Local m:TFLMenu,mm:TFLMenu + Local flags, pfnthandle, pfntsize + + m=Self + While (m) + If m.owner + pfnthandle = m.owner.font.handle + pfntsize = m.owner.font.GetSizeForFL() + EndIf + m=m.mparent + Wend + + If Not pfnthandle Then pfnthandle = TFLTKGUIDriver.fntDefault.handle + If Not pfntsize Then pfntsize = TFLTKGUIDriver.fntDefault.GetSizeForFL() + + If mkids + If index>-1 flSetMenuItem(flmenu,index,text,flshortcut,objhandle,FL_SUBMENU,pfnthandle,pfntsize) 'message + For m=EachIn mkids + m.divider=False + If m.text="" And mm mm.divider=True + mm=m + Next + For m=EachIn mkids + m.SetFLMenu(flmenu) + Next + Else + flags=0 + If text="" flags:|FL_MENU_INVISIBLE + If divider flags:|FL_MENU_DIVIDER + If check + flags:|FL_MENU_TOGGLE + If checked flags:|FL_MENU_VALUE + EndIf + If disabled flags:|FL_MENU_INACTIVE + If index>-1 flSetMenuItem(flmenu,index,text,flshortcut,objhandle,flags,pfnthandle,pfntsize) 'message + EndIf + End Method + + Method SetHotKey(keycode,modifier) + Local flkey = flkeyfromvkey(keycode) + If flkey flkey:+flstatefrommodifiers(modifier) + flshortcut=flkey + End Method + + Method AddMenu( child:TFLMenu ) + child.mparent=Self + child.owner = owner + mkids:+[child] + End Method + + Method RemoveMenu( index ) + ?debug + Assert index < mkids.length, "FLTK child menu index out of range." + ? + mkids[index].Free() + End Method + + Method State() + Local t + If checked t:|STATE_SELECTED + If disabled t:|STATE_DISABLED + Return t + End Method + + Method SetSelected(truefalse) + check=True + checked=truefalse + End Method + + Method SetEnabled(bool) + disabled=Not bool + End Method + + Method SetText(label$) + text=label + End Method + + Method GetText$() + Return text + End Method + + Method SetTooltip(tooltip$) + 'Do nothing - menus don't support tooltips (yet). + EndMethod + +End Type + + +Type TFLIconStrip Extends TIconStrip + + Field images[] + Field iconpixmaps:TPixmap[] + + Method GetFLImage:Int(index:Int) + If index>=0 And index < images.length Then Return images[index] + EndMethod + + Function IsNotBlank(pixmap:TPixmap) + Local x,y + Local w=pixmap.width + Local h=pixmap.height + Local c=pixmap.ReadPixel(0,0) + For x=0 Until h*h + If pixmap.ReadPixel(x / h,x Mod h)<>c Return True + Next + End Function + + Function RemoveMask(pixmap:TPixmap) + Local x,y,c + If pixmap.format<>( PF_RGBA8888 ) And pixmap.format<>( PF_BGRA8888 ) Return + Local w=pixmap.width + Local h=pixmap.height + For x=0 Until w + For y=0 Until h + c=pixmap.ReadPixel(x,y) + If c>=0 pixmap.WritePixel x,y,-1 + Next + Next + End Function + + Function Create:TFLIconStrip(source:Object) + + Local pixmap:TPixmap,pix:TPixmap,winpix:TPixmap + Local n,d + + pix=TPixmap(source) + If Not pix pix=LoadPixmap(source) + If Not pix Return + n=pix.width/pix.height + If n=0 Return + + Select PixmapFormat(pix) + Case PF_RGB888, PF_BGR888, PF_I8 + d = 3 + pixmap = ConvertPixmap(pix,PF_RGB888) + Case PF_RGBA8888, PF_BGRA8888, PF_A8 + d = 4 + pixmap = ConvertPixmap(pix,PF_RGBA8888) + Default + Return Null + EndSelect + + Local icons:TFLIconStrip = New TFLIconStrip + icons.pixmap=pixmap + icons.count=n + icons.images=New Int[n] + icons.iconpixmaps=New TPixmap[n] + + Local w = pixmap.height, h = w + + For Local x:Int = 0 Until n + winpix=pixmap.Window(x*w,0,w,pixmap.height) + If IsNotBlank(winpix) Then + icons.iconpixmaps[x]=winpix + icons.images[x]=FLImage(icons.iconpixmaps[x].pixels,w,h,d,icons.iconpixmaps[x].pitch) + EndIf + Next + Return icons + End Function + + Method Delete() + For Local tmpImage:Int = EachIn images + flFreeImage(tmpImage) + Next + images = Null;iconpixmaps = Null;pixmap = Null + EndMethod + +End Type + +Private + +Function flkeyfromvkey(k) + If k>=48 And k<58 Return k + If k>=65 And k<95 Return k+32 + If k>=KEY_F1 And k<=KEY_F12 Return 65470+k-KEY_F1 + Select k + Case KEY_OPENBRACKET Return 91 + Case KEY_CLOSEBRACKET Return 93 + Case KEY_BACKSLASH Return 92 + Case KEY_TAB Return FL_KEY_Tab + Case KEY_ENTER Return FL_KEY_Enter + Case KEY_ESCAPE Return FL_KEY_Escape + Case KEY_HOME Return FL_KEY_Home + Case KEY_LEFT Return FL_KEY_Left + Case KEY_UP Return FL_KEY_Up + Case KEY_RIGHT Return FL_KEY_Right + Case KEY_DOWN Return FL_KEY_Down + Case KEY_PAGEUP Return FL_KEY_Page_Up + Case KEY_PAGEDOWN Return FL_KEY_Page_Down + Case KEY_END Return FL_KEY_End + Case KEY_PRINT Return FL_KEY_Print + Case KEY_INSERT Return FL_KEY_Insert + Case KEY_BACKSPACE Return FL_KEY_Backspace + Case KEY_DELETE Return FL_KEY_Delete + End Select + Return k +End Function + +Function flstatefrommodifiers(m) + Local state + If m&MODIFIER_SHIFT state:|FL_SHIFT + If m&MODIFIER_CONTROL state:|FL_CTRL + If m&MODIFIER_OPTION state:|FL_ALT + If m&MODIFIER_SYSTEM state:|FL_META + Return state +End Function + +Function flkeytovkey(k) + If k>=48 And k<58 Return k + If k>=97 And k<127 Return KEY_A+k-97 + If k>=65361 And k<65365 Return KEY_LEFT+k-65361 + If k>=65470 And k<65470+13 Return KEY_F1+k-65470 + If k=65307 Return KEY_ESCAPE + If k=65289 Return KEY_TAB + If k=65056 Return KEY_TAB + If k=91 Return KEY_OPENBRACKET + If k=93 Return KEY_CLOSEBRACKET + If k=92 Return KEY_BACKSLASH + Return k +End Function + +Function flstatetomodifiers(state) + Local m + If (state & FL_SHIFT) m:|MODIFIER_SHIFT + If (state & FL_CTRL) m:|MODIFIER_CONTROL + If (state & FL_ALT) m:|MODIFIER_OPTION + If (state & FL_META) m:|MODIFIER_SYSTEM + Return m +End Function diff --git a/mod/maxgui.mod/fltkmaxgui.mod/fltkimports.bmx b/mod/maxgui.mod/fltkmaxgui.mod/fltkimports.bmx new file mode 100644 index 0000000..ffcaeb2 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/fltkimports.bmx @@ -0,0 +1,240 @@ +' fltkimports.bmx + +Strict + +?Win32 +Import "-lcomctl32" +Import "-lole32" +Import "-lcomdlg32" +Import "-ladvapi32" +Import "-luuid" +?MacOS +Import pub.opengl +Import "-framework Cocoa" +Import "-framework AudioToolbox" +?Linux +Import pub.opengl +Import "-lX11" +Import "-lXxf86vm" +Import "-lfreetype" +Import "-lXft" +Import "-lXpm" +? + +?MacOS +Import "cocoa_bridge.mm" +?Not MacOS +Import "src/Fl.cxx" +Import "src/Fl_Printer.cxx" +Import "src/Fl_Native_File_Chooser.cxx" +Import "src/scandir.c" +? + +Import "fltkglue.cpp" + +Import "src/fl_gtk.cxx" +Import "src/screen_xywh.cxx" +Import "src/fl_dnd.cxx" +Import "src/fl_utf.c" +Import "src/fl_utf8.cxx" +Import "src/xutf8/case.c" +Import "src/xutf8/is_spacing.c" +Import "src/xutf8/is_right2left.c" + +?Linux +Import "src/Fl_x.cxx" + +Import "src/xutf8/utf8Wrap.c" +Import "src/xutf8/utf8Utils.c" +Import "src/xutf8/utf8Input.c" + +Import "src/xutf8/keysym2Ucs.c" +? + +Import "src/numericsort.c" + +Import "src/fl_read_image.cxx" +Import "src/Fl_get_key.cxx" +Import "src/fl_color.cxx" +Import "src/fl_set_fonts.cxx" +Import "src/fl_font.cxx" +Import "src/fl_draw_image.cxx" + +Import "src/Fl_Device.cxx" +Import "src/Fl_Gl_Device_Plugin.cxx" +Import "src/Fl_Preferences.cxx" +Import "src/Fl_Paged_Device.cxx" + +Import "src/ps_image.cxx" + +Import "src/Fl_Tree.cxx" +Import "src/Fl_Tree_Item.cxx" +Import "src/Fl_Tree_Item_Array.cxx" +Import "src/Fl_Tree_Prefs.cxx" + +Import "src/flstring.c" +Import "src/vsnprintf.c" +Import "src/cmap.cxx" +Import "src/filename_absolute.cxx" +Import "src/filename_expand.cxx" +Import "src/filename_ext.cxx" +Import "src/filename_isdir.cxx" +Import "src/filename_list.cxx" +Import "src/filename_match.cxx" +Import "src/filename_setext.cxx" + +Import "src/Fl_abort.cxx" +Import "src/Fl_add_idle.cxx" +'Import "src/fl_open_uri.cxx" + +'Import "src/Fl_Adjuster.cxx" +Import "src/fl_arc.cxx" +Import "src/fl_arci.cxx" +Import "src/Fl_arg.cxx" +Import "src/fl_ask.cxx" +Import "src/Fl_Bitmap.cxx" +Import "src/Fl_BMP_Image.cxx" +Import "src/Fl_Box.cxx" +Import "src/fl_boxtype.cxx" +Import "src/Fl_Browser_.cxx" +Import "src/Fl_Browser.cxx" +Import "src/Fl_Browser_load.cxx" +Import "src/Fl_Button.cxx" +Import "src/Fl_Chart.cxx" +Import "src/Fl_Check_Browser.cxx" +Import "src/Fl_Check_Button.cxx" +Import "src/Fl_Choice.cxx" +Import "src/Fl_Clock.cxx" +Import "src/Fl_Color_Chooser.cxx" +Import "src/Fl_compose.cxx" +Import "src/Fl_Counter.cxx" +Import "src/fl_cursor.cxx" +Import "src/fl_curve.cxx" +Import "src/Fl_Dial.cxx" +'Import "src/fl_diamond_box.cxx" +Import "src/Fl_display.cxx" +Import "src/Fl_Double_Window.cxx" +Import "src/fl_draw.cxx" +Import "src/fl_draw_pixmap.cxx" +Import "src/fl_engraved_label.cxx" +'Import "src/Fl_File_Browser.cxx" +'Import "src/Fl_File_Chooser2.cxx" +'Import "src/Fl_File_Chooser.cxx" +Import "src/fl_file_dir.cxx" +Import "src/Fl_File_Icon2.cxx" +Import "src/Fl_File_Icon.cxx" +Import "src/Fl_File_Input.cxx" +Import "src/Fl_get_system_colors.cxx" +Import "src/Fl_GIF_Image.cxx" +'Import "src/Fl_Gl_Choice.cxx" +Import "src/Fl_Gl_Window.cxx" +Import "src/gl_draw.cxx" +Import "src/Fl_grab.cxx" +Import "src/Fl_Group.cxx" +'Import "src/Fl_Help_Dialog.cxx" +Import "src/Fl_Help_View.cxx" +Import "src/Fl_Image.cxx" +Import "src/fl_images_core.cxx" +Import "src/Fl_Input_.cxx" +Import "src/Fl_Input.cxx" +Import "src/Fl_JPEG_Image.cxx" +Import "src/fl_labeltype.cxx" +Import "src/Fl_Light_Button.cxx" +Import "src/fl_line_style.cxx" +Import "src/Fl_lock.cxx" +Import "src/Fl_Menu_add.cxx" +Import "src/Fl_Menu_Bar.cxx" +Import "src/Fl_Menu_Button.cxx" +Import "src/Fl_Menu_.cxx" +Import "src/Fl_Menu.cxx" +Import "src/Fl_Menu_global.cxx" +Import "src/Fl_Menu_Window.cxx" +Import "src/Fl_Multi_Label.cxx" +'Import "src/fl_oval_box.cxx" +Import "src/fl_overlay.cxx" +'Import "src/fl_overlay_visual.cxx" +Import "src/Fl_Overlay_Window.cxx" +Import "src/Fl_own_colormap.cxx" +Import "src/Fl_Pack.cxx" +Import "src/Fl_Pixmap.cxx" +Import "src/fl_plastic.cxx" +Import "src/Fl_PNG_Image.cxx" +Import "src/Fl_PNM_Image.cxx" +Import "src/Fl_Positioner.cxx" +'Import "src/Fl_Preferences.cxx" +Import "src/Fl_Progress.cxx" +Import "src/fl_rect.cxx" +Import "src/Fl_Repeat_Button.cxx" +Import "src/Fl_Return_Button.cxx" +Import "src/Fl_Roller.cxx" +Import "src/fl_round_box.cxx" +Import "src/Fl_Round_Button.cxx" +'Import "src/fl_rounded_box.cxx" +Import "src/fl_scroll_area.cxx" +Import "src/Fl_Scrollbar.cxx" +Import "src/Fl_Scroll.cxx" +Import "src/fl_set_font.cxx" + +Import "src/fl_shadow_box.cxx" +Import "src/Fl_Shared_Image.cxx" +Import "src/fl_shortcut.cxx" +Import "src/fl_show_colormap.cxx" +Import "src/Fl_Single_Window.cxx" +Import "src/Fl_Slider.cxx" +Import "src/fl_symbols.cxx" +'Import "src/Fl_Sys_Menu_Bar.cxx" +Import "src/Fl_Tabs.cxx" +Import "src/Fl_Text_Buffer.cxx" +Import "src/Fl_Text_Display.cxx" +Import "src/Fl_Text_Editor.cxx" +Import "src/Fl_Tile.cxx" +Import "src/Fl_Tiled_Image.cxx" +Import "src/Fl_Tooltip.cxx" +Import "src/Fl_Valuator.cxx" +Import "src/Fl_Value_Input.cxx" +'Import "src/Fl_Value_Output.cxx" +Import "src/Fl_Value_Slider.cxx" +Import "src/fl_vertex.cxx" +Import "src/Fl_visual.cxx" +Import "src/Fl_Widget.cxx" + +Import "src/Fl_Window.cxx" +Import "src/Fl_Window_fullscreen.cxx" +Import "src/Fl_Window_hotspot.cxx" +Import "src/Fl_Window_iconize.cxx" +'Import "src/Fl_Wizard.cxx" +Import "src/Fl_XBM_Image.cxx" +Import "src/Fl_XPM_Image.cxx" + +'Import "src/forms_bitmap.cxx" +'Import "src/forms_compatability.cxx" +'Import "src/forms_free.cxx" +'Import "src/forms_fselect.cxx" +'Import "src/forms_pixmap.cxx" +Import "src/forms_timer.cxx" + +Import "FLU_src/Flu_Button.cpp" +Import "FLU_src/Flu_Label.cpp" +'Import "FLU_src/Flu_Choice_Group.cpp" +'Import "FLU_src/Flu_Output.cpp" +'Import "FLU_src/Flu_Collapsable_Group.cpp" +Import "FLU_src/flu_pixmaps.cpp" +Import "FLU_src/Flu_Combo_Box.cpp" +'Import "FLU_src/Flu_Progress.cpp" +Import "FLU_src/Flu_Combo_List.cpp" +Import "FLU_src/Flu_Combo_Tree.cpp" +Import "FLU_src/Flu_Return_Button.cpp" +Import "FLU_src/Flu_Separator.cpp" +'Import "FLU_src/Flu_Simple_Group.cpp" +Import "FLU_src/FluSimpleString.cpp" +Import "FLU_src/Flu_File_Chooser.cpp" +Import "FLU_src/Flu_Spinner.cpp" +Import "FLU_src/flu_file_chooser_pixmaps.cpp" +'Import "FLU_src/Flu_Toggle_Group.cpp" +Import "FLU_src/Flu_Float_Input.cpp" +Import "FLU_src/Flu_Tree_Browser.cpp" +'Import "FLU_src/Flu_GL_Canvas.cpp" +Import "FLU_src/Flu_Wrap_Group.cpp" +Import "FLU_src/Flu_Helpers.cpp" + +Import "src/Flmm_Tabs.cxx" diff --git a/mod/maxgui.mod/fltkmaxgui.mod/fltkmaxgui.bmx b/mod/maxgui.mod/fltkmaxgui.mod/fltkmaxgui.bmx new file mode 100644 index 0000000..d21de7f --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/fltkmaxgui.bmx @@ -0,0 +1,23 @@ +Rem +bbdoc: MaxGUI Drivers/FLTKMaxGUI +End Rem +Module MaxGUI.FLTKMaxGUI + +Strict + +Import pub.zlib +Import pub.libpng +'Import pub.libjpeg + +ModuleInfo "Version: 1.60" +ModuleInfo "Author: Simon Armstrong, Seb Hollington" +ModuleInfo "License: zlib/libpng" + +ModuleInfo "Credit: FLTKMaxGUI is based in part on the work of the FLTK project (http://www.fltk.org)." +ModuleInfo "Credit: FLTKMaxGUI also uses the fantastic FLTK Utility Widgets from http://www.osc.edu/archive/FLU/ ." + +?Linux +ModuleInfo "CC_OPTS: `freetype-config --cflags`" + +Import "fltkgui.bmx" +? diff --git a/mod/maxgui.mod/fltkmaxgui.mod/fltksystem.bmx b/mod/maxgui.mod/fltkmaxgui.mod/fltksystem.bmx new file mode 100644 index 0000000..b8738d4 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/fltksystem.bmx @@ -0,0 +1,97 @@ +' fltksystem.bmx + +Strict + +Import BRL.System + +Import "fltkimports.bmx" + +Private +Include "fltkdecls.bmx" +?Win32 +Const NATIVEREQUESTERS=1 +?MacOS +Const NATIVEREQUESTERS=0 +?Linux +Const NATIVEREQUESTERS=0 +? +Public + +Type TFLSystemDriver Extends TSystemDriver + + Field NativeDriver:TSystemDriver + + Method New() + NativeDriver=brl.System.Driver + End Method + + Method Poll() + NativeDriver.Poll() + End Method + + Method Wait() + NativeDriver.Wait() + End Method + + Method Emit( osevent:Byte Ptr,source:Object ) + Throw "simon come here" + End Method + + Method IsFullScreen() + Return False + End Method + + Method SetMouseVisible(bool) + NativeDriver.SetMouseVisible bool + End Method + + Method MoveMouse( x,y ) + NativeDriver.MoveMouse x,y + End Method + + Method Notify( text$,serious ) + If NATIVEREQUESTERS Return NativeDriver.Notify(text,serious) + If IsFullScreen() RuntimeError "Notify currently not supported in fullscreen mode." + If serious serious=1 + flRequest(text,serious) + End Method + + Method Confirm( text$,serious ) + If NATIVEREQUESTERS Return NativeDriver.Confirm(text,serious) + If IsFullScreen() RuntimeError "Confirm currently not supported in fullscreen mode." + Return flRequest(text,2) + End Method + + Method Proceed( text$,serious ) + If NATIVEREQUESTERS Return NativeDriver.Proceed(text,serious) + If IsFullScreen() RuntimeError "Proceed currently not supported in fullscreen mode." + Return flRequest(text,3)-1 'yes/no/cancel -> 1,0,-1 + End Method + + Method RequestFile$( text$,exts$,save,file$ ) + If NATIVEREQUESTERS Return NativeDriver.RequestFile( text$,exts$,save,file$ ) + If IsFullScreen() RuntimeError "RequestFile currently not supported in fullscreen mode." + If exts + If exts.Find(":")<>-1 + exts=exts.Replace(":","(*.{") + exts=exts.Replace(";","})~t") + exts:+"})" + exts=exts.Replace("*.{*}","*") + Else + exts="(*.{"+exts+"})" + EndIf + EndIf + Return flRequestFile(text,exts,file,save) + End Method + + Method RequestDir$( text$,path$ ) + If NATIVEREQUESTERS Return NativeDriver.RequestDir( text$,path$ ) + If IsFullScreen() RuntimeError "RequestFile currently not supported in fullscreen mode." + Return flRequestDir(text,path,0) + End Method + + Method OpenURL( url$ ) + Return NativeDriver.OpenURL(url) + End Method + +End Type diff --git a/mod/maxgui.mod/fltkmaxgui.mod/maxgui_templates.h b/mod/maxgui.mod/fltkmaxgui.mod/maxgui_templates.h new file mode 100644 index 0000000..3b479c6 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/maxgui_templates.h @@ -0,0 +1,174 @@ +// FLTK C++ Templates for MaxGUI +// Sebastian Hollington 2009 + +#include +#include + +// Globals (from fltkglue.cpp) + +extern int eventid; +extern int(*mousehandler)(Fl_Widget*,void*); +extern int(*keyhandler)(Fl_Widget*,void*); +extern int(*textfilter)(void*); + +extern "C" int (flEventButton)(); + +// Wrap around an FLTK widget if you want widget to call mouse/keyhandlers. + +template class MaxGUIEventListener : public FLWidget +{ +public: + MaxGUIEventListener (int x, int y, int w, int h, char *title = 0) : FLWidget(x,y,w,h,title) {}; + int handle(int event){ + + int res = FLWidget::handle(event); + int active = this->active_r(); + + if((!active) || (event==FL_FOCUS)) return active; + + Fl_Widget* blwmouse = Fl::belowmouse(); + Fl_Widget* focus = Fl::focus(); + + // If a non-MaxGUI widget has snatched mouse tracking, snatch it back. + if(!(blwmouse && blwmouse->user_data())){ + blwmouse = this; + Fl::belowmouse(this); + } + + // If a non-MaxGUI widget has keyboard focus, pretend we have it. + if(!(focus && focus->user_data())) focus = this; + + eventid = event; + + switch(event){ + case FL_PUSH: + case FL_ENTER: + case FL_MOVE: + case FL_LEAVE: + case FL_MOUSEWHEEL: + case FL_RELEASE: + case FL_DRAG: + // Only call if child gadget has handled event. + if((blwmouse==this) || !res) mousehandler( this, this->user_data() ); + res = 1; + break; + case FL_KEYUP: + // Return 1 from FL_KEYUP to avoid multiple events firing. + res = 1; + case FL_KEYDOWN: + // Leave default return value for FL_KEYDOWN to allow tab/arrow key focus changing. + if(focus==this) keyhandler( focus, focus->user_data() ); + break; + default: + res = 0; + } + eventid = 0; + + return res; + } + +}; + +// Wrap around an FLTK widget if you want keys to be filtered before handling using textfilter callback. + +template class MaxGUIKeyFilter : public FLWidget +{ +public: + MaxGUIKeyFilter (int x, int y, int w, int h, char *title = 0) : FLWidget(x,y,w,h,title) {}; + int handle(int event) + { + int should_callback = 0; + switch (event){ + case FL_KEYDOWN: + if (textfilter(this->user_data())==0) return 1; + should_callback = 1; + break; + } + int res = FLWidget::handle(event); + if (should_callback) FLWidget::do_callback(); + return res; + } + +}; + +// Wrap around any text display widgets to make them behave more like TextArea's on other platforms + +template class MaxGUITextArea : public FLTextDisplay +{ +public: + MaxGUITextArea(int x,int y,int w,int h,const char *title=0):FLTextDisplay(x,y,w,h,title){} + + void pos_to_xy(int pos, int *x, int *y) + { + FLTextDisplay::position_to_xy(pos,x,y); + } + + int handle(int event) + { + int should_callback = 0, should_ignore = 0, res = 0; + + switch (event) + { + case FL_PUSH: + case FL_RELEASE: + should_callback=1; + if(flEventButton()!=FL_LEFT_MOUSE){should_ignore=1;res=1;} + break; + case FL_UNFOCUS: + should_callback=1; + break; + } + if (!should_ignore) res=FLTextDisplay::handle(event); + if (should_callback) FLTextDisplay::do_callback(); + return res; + } +}; + +// Wrap around an FLTK widget if you want widget background to lighten when hovered over. + +template class MaxGUIHoverEffect : public FLWidget +{ +private: + Fl_Color defaultColor, selectionColor; +public: + MaxGUIHoverEffect (int x, int y, int w, int h, char *title = 0):FLWidget(x,y,w,h,title) + { + defaultColor = FLWidget::color(); + selectionColor = FLWidget::selection_color(); + } + + Fl_Color color() {return defaultColor;} + Fl_Color selection_color() {return selectionColor;} + + int handle(int event) + { + if( !this->active_r() ) + return FLWidget::handle( event ); + + switch (event) + { + case FL_ENTER: + + defaultColor = FLWidget::color(); + FLWidget::color( fl_lighter( defaultColor ) ); + + selectionColor = FLWidget::selection_color(); + FLWidget::selection_color( fl_lighter( selectionColor ) ); + + this->redraw(); + return 1; + break; + + case FL_LEAVE: + + FLWidget::color( defaultColor ); + FLWidget::selection_color( selectionColor ); + + this->redraw(); + return 1; + break; + + } + return FLWidget::handle(event); + } +}; diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/CMakeLists.txt b/mod/maxgui.mod/fltkmaxgui.mod/src/CMakeLists.txt new file mode 100644 index 0000000..3d4d569 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/CMakeLists.txt @@ -0,0 +1,447 @@ +include_regular_expression("[.][cxx|c|h]$") + +set(CPPFILES + Fl.cxx + Fl_Adjuster.cxx + Fl_Bitmap.cxx + Fl_Browser.cxx + Fl_Browser_.cxx + Fl_Browser_load.cxx + Fl_Box.cxx + Fl_Button.cxx + Fl_Chart.cxx + Fl_Check_Browser.cxx + Fl_Check_Button.cxx + Fl_Choice.cxx + Fl_Clock.cxx + Fl_Color_Chooser.cxx + Fl_Counter.cxx + Fl_Device.cxx + Fl_Dial.cxx + Fl_Double_Window.cxx + Fl_File_Browser.cxx + Fl_File_Chooser.cxx + Fl_File_Chooser2.cxx + Fl_File_Icon.cxx + Fl_File_Input.cxx + Fl_Group.cxx + Fl_Help_View.cxx + Fl_Image.cxx + Fl_Input.cxx + Fl_Input_.cxx + Fl_Light_Button.cxx + Fl_Menu.cxx + Fl_Menu_.cxx + Fl_Menu_Bar.cxx + Fl_Sys_Menu_Bar.cxx + Fl_Menu_Button.cxx + Fl_Menu_Window.cxx + Fl_Menu_add.cxx + Fl_Menu_global.cxx + Fl_Multi_Label.cxx + Fl_Native_File_Chooser.cxx + Fl_Overlay_Window.cxx + Fl_Pack.cxx + Fl_Paged_Device.cxx + Fl_Pixmap.cxx + Fl_Positioner.cxx + Fl_Printer.cxx + Fl_Preferences.cxx + Fl_Progress.cxx + Fl_Repeat_Button.cxx + Fl_Return_Button.cxx + Fl_Roller.cxx + Fl_Round_Button.cxx + Fl_Scroll.cxx + Fl_Scrollbar.cxx + Fl_Shared_Image.cxx + Fl_Single_Window.cxx + Fl_Slider.cxx + Fl_Table.cxx + Fl_Table_Row.cxx + Fl_Tabs.cxx + Fl_Text_Buffer.cxx + Fl_Text_Display.cxx + Fl_Text_Editor.cxx + Fl_Tile.cxx + Fl_Tiled_Image.cxx + Fl_Tooltip.cxx + Fl_Tree.cxx + Fl_Tree_Item_Array.cxx + Fl_Tree_Item.cxx + Fl_Tree_Prefs.cxx + Fl_Valuator.cxx + Fl_Value_Input.cxx + Fl_Value_Output.cxx + Fl_Value_Slider.cxx + Fl_Widget.cxx + Fl_Window.cxx + Fl_Window_fullscreen.cxx + Fl_Window_hotspot.cxx + Fl_Window_iconize.cxx + Fl_Wizard.cxx + Fl_XBM_Image.cxx + Fl_XPM_Image.cxx + Fl_abort.cxx + Fl_add_idle.cxx + Fl_arg.cxx + Fl_compose.cxx + Fl_display.cxx + Fl_get_key.cxx + Fl_get_system_colors.cxx + Fl_grab.cxx + Fl_lock.cxx + Fl_own_colormap.cxx + Fl_visual.cxx + Fl_x.cxx + filename_absolute.cxx + filename_expand.cxx + filename_ext.cxx + filename_isdir.cxx + filename_list.cxx + filename_match.cxx + filename_setext.cxx + fl_arc.cxx + fl_arci.cxx + fl_ask.cxx + fl_boxtype.cxx + fl_color.cxx + fl_cursor.cxx + fl_curve.cxx + fl_diamond_box.cxx + fl_dnd.cxx + fl_draw.cxx + fl_draw_image.cxx + fl_draw_pixmap.cxx + fl_engraved_label.cxx + fl_file_dir.cxx + fl_font.cxx + fl_gtk.cxx + fl_labeltype.cxx + fl_line_style.cxx + fl_open_uri.cxx + fl_oval_box.cxx + fl_overlay.cxx + fl_overlay_visual.cxx + fl_plastic.cxx + fl_read_image.cxx + fl_rect.cxx + fl_round_box.cxx + fl_rounded_box.cxx + fl_set_font.cxx + fl_set_fonts.cxx + fl_scroll_area.cxx + fl_shadow_box.cxx + fl_shortcut.cxx + fl_show_colormap.cxx + fl_symbols.cxx + fl_vertex.cxx + ps_image.cxx + screen_xywh.cxx + fl_utf8.cxx + fl_encoding_latin1.cxx + fl_encoding_mac_roman.cxx +) + +set(FLCPPFILES + forms_compatability.cxx + forms_bitmap.cxx + forms_free.cxx + forms_fselect.cxx + forms_pixmap.cxx + forms_timer.cxx +) + +set(GLCPPFILES + Fl_Gl_Choice.cxx + Fl_Gl_Device_Plugin.cxx + Fl_Gl_Overlay.cxx + Fl_Gl_Window.cxx + freeglut_geometry.cxx + freeglut_stroke_mono_roman.cxx + freeglut_stroke_roman.cxx + freeglut_teapot.cxx + gl_draw.cxx + gl_start.cxx + glut_compatability.cxx + glut_font.cxx +) + +set(IMGCPPFILES + fl_images_core.cxx + Fl_BMP_Image.cxx + Fl_File_Icon2.cxx + Fl_GIF_Image.cxx + Fl_Help_Dialog.cxx + Fl_JPEG_Image.cxx + Fl_PNG_Image.cxx + Fl_PNM_Image.cxx +) + +set(CFILES + flstring.c + scandir.c + numericsort.c + vsnprintf.c + xutf8/is_right2left.c + xutf8/is_spacing.c + xutf8/case.c + xutf8/utf8Input.c + xutf8/utf8Utils.c + xutf8/utf8Wrap.c + xutf8/keysym2Ucs.c + fl_utf.c +) + +if(APPLE) + set_source_files_properties( + Fl.cxx Fl_Native_File_Chooser.cxx Fl_Printer.cxx + PROPERTIES COMPILE_FLAGS "-x objective-c++") +endif(APPLE) + +####################################################################### +add_library(fltk STATIC ${CPPFILES} ${CFILES} fl_call_main.c) +set_target_properties(fltk PROPERTIES CLEAN_DIRECT_OUTPUT 1) +if(MSVC) + if(OPTION_LARGE_FILE) + set_target_properties(fltk PROPERTIES LINK_FLAGS /LARGEADDRESSAWARE) + endif() + set_target_properties(fltk + PROPERTIES + OUTPUT_NAME fltk + DEBUG_OUTPUT_NAME fltkd + ) +endif(MSVC) + +if(USE_THREADS) + target_link_libraries(fltk ${CMAKE_THREAD_LIBS_INIT}) +endif(USE_THREADS) + +if(USE_X11) + target_link_libraries(fltk ${X11_LIBRARIES}) +endif(USE_X11) + +if(WIN32) + target_link_libraries(fltk comctl32) +endif(WIN32) + +if(HAVE_CAIRO) + target_link_libraries(fltk fltk_cairo ${PKG_CAIRO_LIBRARIES}) +ENDif(HAVE_CAIRO) + +if(HAVE_XINERAMA) + target_link_libraries(fltk ${X11_Xinerama_LIB}) +endif(HAVE_XINERAMA) + +if(USE_XFT) + target_link_libraries(fltk ${X11_Xft_LIB}) +endif(USE_XFT) + +if(LIB_fontconfig) + target_link_libraries(fltk ${LIB_fontconfig}) +endif(LIB_fontconfig) + +####################################################################### +add_library(fltk_forms STATIC ${FLCPPFILES}) +target_link_libraries(fltk_forms fltk) +set_target_properties(fltk_forms + PROPERTIES CLEAN_DIRECT_OUTPUT 1 +) +if(MSVC) + if(OPTION_LARGE_FILE) + set_target_properties(fltk_forms PROPERTIES LINK_FLAGS /LARGEADDRESSAWARE) + endif() + set_target_properties(fltk_forms + PROPERTIES + OUTPUT_NAME fltkforms + DEBUG_OUTPUT_NAME fltkformsd + ) +endif(MSVC) + +####################################################################### +add_library(fltk_images STATIC ${IMGCPPFILES}) +target_link_libraries(fltk_images fltk ${FLTK_PNG_LIBRARIES} + ${FLTK_JPEG_LIBRARIES} ${FLTK_ZLIB_LIBRARIES}) +set_target_properties(fltk_images PROPERTIES CLEAN_DIRECT_OUTPUT 1) +if(MSVC) + if(OPTION_LARGE_FILE) + set_target_properties(fltk_images PROPERTIES LINK_FLAGS /LARGEADDRESSAWARE) + endif() + set_target_properties(fltk_images + PROPERTIES + OUTPUT_NAME fltkimages + DEBUG_OUTPUT_NAME fltkimagesd + ) +endif(MSVC) + +####################################################################### +install(TARGETS fltk fltk_forms fltk_images + EXPORT fltk-install + DESTINATION ${PREFIX_LIB} +) + +####################################################################### +if(OPENGL_FOUND) + add_library(fltk_gl STATIC ${GLCPPFILES}) + target_link_libraries(fltk_gl fltk ${OPENGL_LIBRARIES}) + set_target_properties(fltk_gl PROPERTIES CLEAN_DIRECT_OUTPUT 1) + if(MSVC) + if(OPTION_LARGE_FILE) + set_target_properties(fltk_gl PROPERTIES LINK_FLAGS /LARGEADDRESSAWARE) + endif() + set_target_properties(fltk_gl + PROPERTIES + OUTPUT_NAME fltkgl + DEBUG_OUTPUT_NAME fltkgld + ) + endif(MSVC) + + install(TARGETS fltk_gl + EXPORT fltk-install + DESTINATION ${PREFIX_LIB} + ) +endif(OPENGL_FOUND) + +####################################################################### +####################################################################### +if(OPTION_BUILD_SHARED_LIBS) + +####################################################################### +add_library(fltk_SHARED SHARED ${CPPFILES} ${CFILES}) +set_target_properties(fltk_SHARED + PROPERTIES CLEAN_DIRECT_OUTPUT 1 + VERSION ${FLTK_VERSION_MAJOR}.${FLTK_VERSION_MINOR} + SOVERSION ${FLTK_VERSION_PATCH} +) +if(MSVC) + set_target_properties(fltk_SHARED + PROPERTIES + OUTPUT_NAME fltkdll + DEBUG_OUTPUT_NAME fltkdlld + COMPILE_DEFINITIONS "FL_DLL;FL_LIBRARY" + ) + if(OPTION_LARGE_FILE) + set_target_properties(fltk_SHARED PROPERTIES LINK_FLAGS /LARGEADDRESSAWARE) + endif(OPTION_LARGE_FILE) +else() + set_target_properties(fltk_SHARED PROPERTIES OUTPUT_NAME fltk) +endif(MSVC) + +if(USE_THREADS) + target_link_libraries(fltk_SHARED ${CMAKE_THREAD_LIBS_INIT}) +endif(USE_THREADS) + +if(USE_X11) + target_link_libraries(fltk_SHARED ${X11_LIBRARIES}) +endif(USE_X11) + +if(WIN32) + target_link_libraries(fltk_SHARED comctl32) +endif(WIN32) + +if(HAVE_CAIRO) + target_link_libraries(fltk_SHARED fltk_cairo ${PKG_CAIRO_LIBRARIES}) +ENDif(HAVE_CAIRO) + +if(HAVE_XINERAMA) + target_link_libraries(fltk_SHARED ${X11_Xinerama_LIB}) +endif(HAVE_XINERAMA) + +if(USE_XFT) + target_link_libraries(fltk_SHARED ${X11_Xft_LIB}) +endif(USE_XFT) + +if(LIB_fontconfig) + target_link_libraries(fltk_SHARED ${LIB_fontconfig}) +endif(LIB_fontconfig) + +####################################################################### +add_library(fltk_forms_SHARED SHARED ${FLCPPFILES}) +target_link_libraries(fltk_forms_SHARED fltk) +set_target_properties(fltk_forms_SHARED + PROPERTIES CLEAN_DIRECT_OUTPUT 1 + VERSION ${FLTK_VERSION_MAJOR}.${FLTK_VERSION_MINOR} + SOVERSION ${FLTK_VERSION_PATCH} +) +if(MSVC) + set_target_properties(fltk_forms_SHARED + PROPERTIES + OUTPUT_NAME fltkformsdll + DEBUG_OUTPUT_NAME fltkformsdlld + COMPILE_DEFINITIONS "FL_DLL;FL_LIBRARY" + ) + if(OPTION_LARGE_FILE) + set_target_properties(fltk_forms_SHARED PROPERTIES LINK_FLAGS /LARGEADDRESSAWARE) + endif(OPTION_LARGE_FILE) +else() + set_target_properties(fltk_forms_SHARED PROPERTIES OUTPUT_NAME fltk_forms) +endif(MSVC) + +if(USE_THREADS) + target_link_libraries(fltk_SHARED ${CMAKE_THREAD_LIBS_INIT}) +endif(USE_THREADS) + +if(USE_X11) + target_link_libraries(fltk_SHARED ${X11_LIBRARIES}) +endif(USE_X11) + +####################################################################### +add_library(fltk_images_SHARED SHARED ${IMGCPPFILES}) +target_link_libraries(fltk_images_SHARED fltk + ${FLTK_PNG_LIBRARIES} ${FLTK_JPEG_LIBRARIES} ${FLTK_ZLIB_LIBRARIES} +) +set_target_properties(fltk_images_SHARED + PROPERTIES CLEAN_DIRECT_OUTPUT 1 + VERSION ${FLTK_VERSION_MAJOR}.${FLTK_VERSION_MINOR} + SOVERSION ${FLTK_VERSION_PATCH} +) +if(MSVC) + set_target_properties(fltk_images_SHARED + PROPERTIES + OUTPUT_NAME fltkimagesdll + DEBUG_OUTPUT_NAME fltkimagesdlld + COMPILE_DEFINITIONS "FL_DLL;FL_LIBRARY" + ) + if(OPTION_LARGE_FILE) + set_target_properties(fltk_images_SHARED PROPERTIES LINK_FLAGS /LARGEADDRESSAWARE) + endif(OPTION_LARGE_FILE) +else() + set_target_properties(fltk_images_SHARED PROPERTIES OUTPUT_NAME fltk_images) +endif(MSVC) + +####################################################################### +install(TARGETS fltk_SHARED fltk_forms_SHARED fltk_images_SHARED + EXPORT fltk-install + DESTINATION ${PREFIX_LIB} +) + +####################################################################### +if(OPENGL_FOUND) + add_library(fltk_gl_SHARED SHARED ${GLCPPFILES}) + target_link_libraries(fltk_gl_SHARED fltk ${OPENGL_LIBRARIES}) + set_target_properties(fltk_gl_SHARED + PROPERTIES CLEAN_DIRECT_OUTPUT 1 + VERSION ${FLTK_VERSION_MAJOR}.${FLTK_VERSION_MINOR} + SOVERSION ${FLTK_VERSION_PATCH} + ) + if(MSVC) + set_target_properties(fltk_gl_SHARED + PROPERTIES + OUTPUT_NAME fltkgldll + DEBUG_OUTPUT_NAME fltkgldlld + COMPILE_DEFINITIONS "FL_DLL;FL_LIBRARY" + ) + if(OPTION_LARGE_FILE) + set_target_properties(fltk_gl_SHARED PROPERTIES LINK_FLAGS /LARGEADDRESSAWARE) + endif(OPTION_LARGE_FILE) + else() + set_target_properties(fltk_gl_SHARED PROPERTIES OUTPUT_NAME fltk_gl) + endif(MSVC) + + install(TARGETS fltk_gl_SHARED + EXPORT fltk-install + DESTINATION ${PREFIX_LIB} + ) +endif(OPENGL_FOUND) + +endif(OPTION_BUILD_SHARED_LIBS) diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl.cxx new file mode 100644 index 0000000..184de3e --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl.cxx @@ -0,0 +1,1806 @@ +// +// "$Id: Fl.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Main event handling code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + + +// warning: the Apple Quartz version still uses some Quickdraw calls, +// mostly to get around the single active context in QD and +// to implement clipping. This should be changed into pure +// Quartz calls in the near future. +#include "config.h" +#include +#include +#include +#include +#include +#include +#include +#include "flstring.h" + +#if defined(__APPLE__) +#import +#endif + +#if defined(DEBUG) || defined(DEBUG_WATCH) +# include +#endif // DEBUG || DEBUG_WATCH + +#ifdef WIN32 +# include +void fl_free_fonts(void); +HBRUSH fl_brush_action(int action); +void fl_cleanup_pens(void); +void fl_release_dc(HWND,HDC); +void fl_cleanup_dc_list(void); +#endif // WIN32 + +// +// Globals... +// +#ifndef FL_DOXYGEN +Fl_Widget *Fl::belowmouse_, + *Fl::pushed_, + *Fl::focus_, + *Fl::selection_owner_; +int Fl::damage_, + Fl::e_number, + Fl::e_x, + Fl::e_y, + Fl::e_x_root, + Fl::e_y_root, + Fl::e_dx, + Fl::e_dy, + Fl::e_state, + Fl::e_clicks, + Fl::e_is_click, + Fl::e_keysym, + Fl::e_original_keysym, + Fl::scrollbar_size_ = 16; + +char *Fl::e_text = (char *)""; +int Fl::e_length; +int Fl::visible_focus_ = 1, + Fl::dnd_text_ops_ = 1; + +unsigned char Fl::options_[] = { 0, 0 }; +unsigned char Fl::options_read_ = 0; + + +Fl_Window *fl_xfocus; // which window X thinks has focus +Fl_Window *fl_xmousewin;// which window X thinks has FL_ENTER +Fl_Window *Fl::grab_; // most recent Fl::grab() +Fl_Window *Fl::modal_; // topmost modal() window + +#endif // FL_DOXYGEN + +// +// 'Fl::version()' - Return the API version number... +// + +double +/** + Returns the compiled-in value of the FL_VERSION constant. This + is useful for checking the version of a shared library. +*/ +Fl::version() { + return FL_VERSION; +} + +/** + Gets the default scrollbar size used by + Fl_Browser_, + Fl_Help_View, + Fl_Scroll, and + Fl_Text_Display widgets. + \returns The default size for widget scrollbars, in pixels. +*/ +int Fl::scrollbar_size() { + return scrollbar_size_; +} + +/** + Sets the default scrollbar size that is used by the + Fl_Browser_, + Fl_Help_View, + Fl_Scroll, and + Fl_Text_Display widgets. + \param[in] W The new default size for widget scrollbars, in pixels. +*/ +void Fl::scrollbar_size(int W) { + scrollbar_size_ = W; +} + + +/** + Returns whether or not the mouse event is inside the given rectangle. + Returns non-zero if the current event_x and event_y + put it inside the widget or inside an arbitrary bounding box. You + should always call this rather than doing your own comparison so you + are consistent about edge effects. +*/ +int Fl::event_inside(int xx,int yy,int ww,int hh) /*const*/ { + int mx = e_x - xx; + int my = e_y - yy; + return (mx >= 0 && mx < ww && my >= 0 && my < hh); +} + +/** Returns whether or not the mouse event is inside the given widget. + Returns non-zero if the current event_x and event_y + put it inside the widget or inside an arbitrary bounding box. You + should always call this rather than doing your own comparison so you + are consistent about edge effects. +*/ +int Fl::event_inside(const Fl_Widget *o) /*const*/ { + int mx = e_x - o->x(); + int my = e_y - o->y(); + return (mx >= 0 && mx < o->w() && my >= 0 && my < o->h()); +} + +// +// +// timer support +// + +#ifdef WIN32 + +/// implementation in Fl_win32.cxx + +#elif defined(__APPLE__) + +/// implementation in Fl_mac.cxx + +#else + +// +// X11 timers +// + + +//////////////////////////////////////////////////////////////// +// Timeouts are stored in a sorted list, so only the first one needs +// to be checked to see if any should be called. + +struct Timeout { + double time; + void (*cb)(void*); + void* arg; + Timeout* next; +}; +static Timeout* first_timeout, *free_timeout; +static int first_timeout_count, free_timeout_count; + +#include + +// I avoid the overhead of getting the current time when we have no +// timeouts by setting this flag instead of getting the time. +// In this case calling elapse_timeouts() does nothing, but records +// the current time, and the next call will actualy elapse time. +static char reset_clock = 1; + +static void elapse_timeouts() { + static struct timeval prevclock; + struct timeval newclock; + gettimeofday(&newclock, NULL); + double elapsed = newclock.tv_sec - prevclock.tv_sec + + (newclock.tv_usec - prevclock.tv_usec)/1000000.0; + prevclock.tv_sec = newclock.tv_sec; + prevclock.tv_usec = newclock.tv_usec; + if (reset_clock) { + reset_clock = 0; + } else if (elapsed > 0) { + for (Timeout* t = first_timeout; t; t = t->next) t->time -= elapsed; + } +} + +// Continuously-adjusted error value, this is a number <= 0 for how late +// we were at calling the last timeout. This appears to make repeat_timeout +// very accurate even when processing takes a significant portion of the +// time interval: +static double missed_timeout_by; + +void Fl::add_timeout(double time, Fl_Timeout_Handler cb, void *argp) { + elapse_timeouts(); + repeat_timeout(time, cb, argp); +} + +void Fl::repeat_timeout(double time, Fl_Timeout_Handler cb, void *argp) { + time += missed_timeout_by; if (time < -.05) time = 0; + Timeout* t = free_timeout; + if (t) { + free_timeout = t->next; + --free_timeout_count; + } else { + t = new Timeout; + } + t->time = time; + t->cb = cb; + t->arg = argp; + // insert-sort the new timeout: + Timeout** p = &first_timeout; + while (*p && (*p)->time <= time) p = &((*p)->next); + t->next = *p; + *p = t; +} + +/** + Returns true if the timeout exists and has not been called yet. +*/ +int Fl::has_timeout(Fl_Timeout_Handler cb, void *argp) { + for (Timeout* t = first_timeout; t; t = t->next) + if (t->cb == cb && t->arg == argp) return 1; + return 0; +} + +/** + Removes a timeout callback. It is harmless to remove a timeout + callback that no longer exists. +*/ +void Fl::remove_timeout(Fl_Timeout_Handler cb, void *argp) { + // This version removes all matching timeouts, not just the first one. + // This may change in the future. + for (Timeout** p = &first_timeout; *p;) { + Timeout* t = *p; + if (t->cb == cb && (t->arg == argp || !argp)) { + *p = t->next; + t->next = free_timeout; + free_timeout = t; + } else { + p = &(t->next); + } + } +} + +#endif + +//////////////////////////////////////////////////////////////// +// Checks are just stored in a list. They are called in the reverse +// order that they were added (this may change in the future). +// This is a bit messy because I want to allow checks to be added, +// removed, and have wait() called from inside them, to do this +// next_check points at the next unprocessed one for the outermost +// call to Fl::wait(). + +struct Check { + void (*cb)(void*); + void* arg; + Check* next; +}; +static Check *first_check, *next_check, *free_check; + +/** + FLTK will call this callback just before it flushes the display and + waits for events. This is different than an idle callback because it + is only called once, then FLTK calls the system and tells it not to + return until an event happens. + + This can be used by code that wants to monitor the + application's state, such as to keep a display up to date. The + advantage of using a check callback is that it is called only when no + events are pending. If events are coming in quickly, whole blocks of + them will be processed before this is called once. This can save + significant time and avoid the application falling behind the events. + + Sample code: + + \code + bool state_changed; // anything that changes the display turns this on + + void callback(void*) { + if (!state_changed) return; + state_changed = false; + do_expensive_calculation(); + widget->redraw(); + } + + main() { + Fl::add_check(callback); + return Fl::run(); + } + \endcode +*/ +void Fl::add_check(Fl_Timeout_Handler cb, void *argp) { + Check* t = free_check; + if (t) free_check = t->next; + else t = new Check; + t->cb = cb; + t->arg = argp; + t->next = first_check; + if (next_check == first_check) next_check = t; + first_check = t; +} + +/** + Removes a check callback. It is harmless to remove a check + callback that no longer exists. +*/ +void Fl::remove_check(Fl_Timeout_Handler cb, void *argp) { + for (Check** p = &first_check; *p;) { + Check* t = *p; + if (t->cb == cb && t->arg == argp) { + if (next_check == t) next_check = t->next; + *p = t->next; + t->next = free_check; + free_check = t; + } else { + p = &(t->next); + } + } +} + +/** + Returns 1 if the check exists and has not been called yet, 0 otherwise. +*/ +int Fl::has_check(Fl_Timeout_Handler cb, void *argp) { + for (Check** p = &first_check; *p;) { + Check* t = *p; + if (t->cb == cb && t->arg == argp) { + return 1; + } else { + p = &(t->next); + } + } + return 0; +} + +static void run_checks() +{ + // checks are a bit messy so that add/remove and wait may be called + // from inside them without causing an infinite loop: + if (next_check == first_check) { + while (next_check) { + Check* checkp = next_check; + next_check = checkp->next; + (checkp->cb)(checkp->arg); + } + next_check = first_check; + } +} + +#ifndef WIN32 +static char in_idle; +#endif + +//////////////////////////////////////////////////////////////// +// wait/run/check/ready: + +void (*Fl::idle)(); // see Fl_add_idle.cxx for the add/remove functions + +extern int fl_ready(); // in Fl_.cxx +extern int fl_wait(double time); // in Fl_.cxx + +/** + See int wait() +*/ +double Fl::wait(double time_to_wait) { + // delete all widgets that were listed during callbacks + do_widget_deletion(); + +#ifdef WIN32 + + return fl_wait(time_to_wait); + +#elif defined(__APPLE__) + + run_checks(); + if (idle) { + if (!in_idle) { + in_idle = 1; + idle(); + in_idle = 0; + } + // the idle function may turn off idle, we can then wait: + if (idle) time_to_wait = 0.0; + } + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + flush(); + if (idle && !in_idle) // 'idle' may have been set within flush() + time_to_wait = 0.0; + double retval = fl_wait(time_to_wait); + [pool release]; + return retval; + +#else + + if (first_timeout) { + elapse_timeouts(); + Timeout *t; + while ((t = first_timeout)) { + if (t->time > 0) break; + // The first timeout in the array has expired. + missed_timeout_by = t->time; + // We must remove timeout from array before doing the callback: + void (*cb)(void*) = t->cb; + void *argp = t->arg; + first_timeout = t->next; + t->next = free_timeout; + free_timeout = t; + ++free_timeout_count; + --first_timeout_count; + // Now it is safe for the callback to do add_timeout: + cb(argp); + } + } else { + reset_clock = 1; // we are not going to check the clock + } + run_checks(); +// if (idle && !fl_ready()) { + if (idle) { + if (!in_idle) { + in_idle = 1; + idle(); + in_idle = 0; + } + // the idle function may turn off idle, we can then wait: + if (idle) time_to_wait = 0.0; + } + if (first_timeout && first_timeout->time < time_to_wait) + time_to_wait = first_timeout->time; + if (time_to_wait <= 0.0) { + // do flush second so that the results of events are visible: + int ret = fl_wait(0.0); + flush(); + return ret; + } else { + // do flush first so that user sees the display: + flush(); + if (idle && !in_idle) // 'idle' may have been set within flush() + time_to_wait = 0.0; + return fl_wait(time_to_wait); + } +#endif +} + +#define FOREVER 1e20 + +/** + As long as any windows are displayed this calls Fl::wait() + repeatedly. When all the windows are closed it returns zero + (supposedly it would return non-zero on any errors, but FLTK calls + exit directly for these). A normal program will end main() + with return Fl::run();. +*/ +int Fl::run() { + while (Fl_X::first) wait(FOREVER); + return 0; +} + +#ifdef WIN32 + +// Function to initialize COM/OLE for usage. This must be done only once. +// We define a flag to register whether we called it: +static char oleInitialized = 0; + +// This calls the Windows function OleInitialize() exactly once. +void fl_OleInitialize() { + if (!oleInitialized) { + OleInitialize(0L); + oleInitialized = 1; + } +} + +// This calls the Windows function OleUninitialize() only, if +// OleInitialize has been called before. +void fl_OleUninitialize() { + if (oleInitialized) { + OleUninitialize(); + oleInitialized = 0; + } +} + +class Fl_Win32_At_Exit { +public: + Fl_Win32_At_Exit() { } + ~Fl_Win32_At_Exit() { + fl_free_fonts(); // do some WIN32 cleanup + fl_cleanup_pens(); + fl_OleUninitialize(); + fl_brush_action(1); + fl_cleanup_dc_list(); + } +}; +static Fl_Win32_At_Exit win32_at_exit; +#endif + + + +/** + Waits until "something happens" and then returns. Call this + repeatedly to "run" your program. You can also check what happened + each time after this returns, which is quite useful for managing + program state. + + What this really does is call all idle callbacks, all elapsed + timeouts, call Fl::flush() to get the screen to update, and + then wait some time (zero if there are idle callbacks, the shortest of + all pending timeouts, or infinity), for any events from the user or + any Fl::add_fd() callbacks. It then handles the events and + calls the callbacks and then returns. + + The return value of the first form is non-zero if there are + any visible windows - this may change in future versions of + FLTK. + + The second form waits a maximum of time + seconds. It can return much sooner if something happens. + + The return value is positive if an event or fd happens before the + time elapsed. It is zero if nothing happens (on Win32 this will only + return zero if time is zero). It is negative if an error + occurs (this will happen on UNIX if a signal happens). +*/ +int Fl::wait() { + if (!Fl_X::first) return 0; + wait(FOREVER); + return Fl_X::first != 0; // return true if there is a window +} + +/** + Same as Fl::wait(0). Calling this during a big calculation + will keep the screen up to date and the interface responsive: + + \code + while (!calculation_done()) { + calculate(); + Fl::check(); + if (user_hit_abort_button()) break; + } + \endcode + + The returns non-zero if any windows are displayed, and 0 if no + windows are displayed (this is likely to change in future versions of + FLTK). +*/ +int Fl::check() { + wait(0.0); + return Fl_X::first != 0; // return true if there is a window +} + +/** + This is similar to Fl::check() except this does \e not + call Fl::flush() or any callbacks, which is useful if your + program is in a state where such callbacks are illegal. This returns + true if Fl::check() would do anything (it will continue to + return true until you call Fl::check() or Fl::wait()). + + \code + while (!calculation_done()) { + calculate(); + if (Fl::ready()) { + do_expensive_cleanup(); + Fl::check(); + if (user_hit_abort_button()) break; + } + } + \endcode +*/ +int Fl::ready() { +#if ! defined( WIN32 ) && ! defined(__APPLE__) + if (first_timeout) { + elapse_timeouts(); + if (first_timeout->time <= 0) return 1; + } else { + reset_clock = 1; + } +#endif + return fl_ready(); +} + +//////////////////////////////////////////////////////////////// +// Window list management: + +#ifndef FL_DOXYGEN +Fl_X* Fl_X::first; +#endif + +Fl_Window* fl_find(Window xid) { + Fl_X *window; + for (Fl_X **pp = &Fl_X::first; (window = *pp); pp = &window->next) +#if defined(WIN32) || defined(USE_X11) + if (window->xid == xid) +#elif defined(__APPLE_QUARTZ__) + if (window->xid == xid && !window->w->window()) +#else +# error unsupported platform +#endif // __APPLE__ + { + if (window != Fl_X::first && !Fl::modal()) { + // make this window be first to speed up searches + // this is not done if modal is true to avoid messing up modal stack + *pp = window->next; + window->next = Fl_X::first; + Fl_X::first = window; + } + return window->w; + } + return 0; +} + +/** + Returns the first top-level window in the list of shown() windows. If + a modal() window is shown this is the top-most modal window, otherwise + it is the most recent window to get an event. + + The second form sets the window that is returned by + first_window. The window is removed from wherever it is in the + list and inserted at the top. This is not done if Fl::modal() + is on or if the window is not shown(). Because the first window + is used to set the "parent" of modal windows, this is often + useful. +*/ +Fl_Window* Fl::first_window() { + Fl_X* i = Fl_X::first; + return i ? i->w : 0; +} + +/** + Returns the next top-level window in the list of shown() windows. You can + use this call to iterate through all the windows that are shown(). +*/ +Fl_Window* Fl::next_window(const Fl_Window* window) { + Fl_X* i = Fl_X::i(window)->next; + return i ? i->w : 0; +} + +/** + See Fl_Window* first_window() +*/ +void Fl::first_window(Fl_Window* window) { + if (!window || !window->shown()) return; + fl_find(fl_xid(window)); +} + +/** + Redraws all widgets. +*/ +void Fl::redraw() { + for (Fl_X* i = Fl_X::first; i; i = i->next) i->w->redraw(); +} + +/** + Causes all the windows that need it to be redrawn and graphics forced + out through the pipes. + + This is what wait() does before looking for events. + + Note: in multi-threaded applications you should only call Fl::flush() + from the main thread. If a child thread needs to trigger a redraw event, + it should instead call Fl::awake() to get the main thread to process the + event queue. +*/ +void Fl::flush() { + if (damage()) { + damage_ = 0; + for (Fl_X* i = Fl_X::first; i; i = i->next) { + if (i->wait_for_expose) {damage_ = 1; continue;} + Fl_Window* wi = i->w; + if (!wi->visible_r()) continue; + if (wi->damage()) {i->flush(); wi->clear_damage();} + // destroy damage regions for windows that don't use them: + if (i->region) {XDestroyRegion(i->region); i->region = 0;} + } + } +#if defined(USE_X11) + if (fl_display) XFlush(fl_display); +#elif defined(WIN32) + GdiFlush(); +#elif defined (__APPLE_QUARTZ__) + if (fl_gc) + CGContextFlush(fl_gc); +#else +# error unsupported platform +#endif +} + +//////////////////////////////////////////////////////////////// +// Event handlers: + +struct handler_link { + int (*handle)(int); + handler_link *next; +}; + +static handler_link *handlers = 0; + +/** + Install a function to parse unrecognized events. If FLTK cannot + figure out what to do with an event, it calls each of these functions + (most recent first) until one of them returns non-zero. If none of + them returns non zero then the event is ignored. Events that cause + this to be called are: + + - FL_SHORTCUT events that are not recognized by any widget. + This lets you provide global shortcut keys. + - System events that FLTK does not recognize. See fl_xevent. + - \e Some other events when the widget FLTK selected returns + zero from its handle() method. Exactly which ones may change + in future versions, however. +*/ +void Fl::add_handler(Fl_Event_Handler ha) { + handler_link *l = new handler_link; + l->handle = ha; + l->next = handlers; + handlers = l; +} + +/** + Removes a previously added event handler. +*/ +void Fl::remove_handler(Fl_Event_Handler ha) { + handler_link *l, *p; + + // Search for the handler in the list... + for (l = handlers, p = 0; l && l->handle != ha; p = l, l = l->next); + + if (l) { + // Found it, so remove it from the list... + if (p) p->next = l->next; + else handlers = l->next; + + // And free the record... + delete l; + } +} + +int (*fl_local_grab)(int); // used by fl_dnd.cxx + +static int send_handlers(int e) { + for (const handler_link *hl = handlers; hl; hl = hl->next) + if (hl->handle(e)) return 1; + return 0; +} + +//////////////////////////////////////////////////////////////// + +Fl_Widget* fl_oldfocus; // kludge for Fl_Group... + +/** + Sets the widget that will receive FL_KEYBOARD events. + + If you change Fl::focus(), the previous widget and all + parents (that don't contain the new widget) are sent FL_UNFOCUS + events. Changing the focus does \e not send FL_FOCUS to + this or any widget, because sending FL_FOCUS is supposed to + \e test if the widget wants the focus (by it returning non-zero from + handle()). + + \sa Fl_Widget::take_focus() +*/ +void Fl::focus(Fl_Widget *o) { + if (o && !o->visible_focus()) return; + if (grab()) return; // don't do anything while grab is on + Fl_Widget *p = focus_; + if (o != p) { + Fl::compose_reset(); + focus_ = o; + // make sure that fl_xfocus is set to the top level window + // of this widget, or fl_fix_focus will clear our focus again + if (o) { + Fl_Window *win = 0, *w1 = o->window(); + while (w1) { win=w1; w1=win->window(); } + if (win) fl_xfocus = win; + } + // take focus from the old focused window + fl_oldfocus = 0; + int old_event = e_number; + e_number = FL_UNFOCUS; + for (; p; p = p->parent()) { + p->handle(FL_UNFOCUS); + fl_oldfocus = p; + } + e_number = old_event; + } +} + +static char dnd_flag = 0; // make 'belowmouse' send DND_LEAVE instead of LEAVE + +/** + Sets the widget that is below the mouse. This is for + highlighting buttons. It is not used to send FL_PUSH or + FL_MOVE directly, for several obscure reasons, but those events + typically go to this widget. This is also the first widget tried for + FL_SHORTCUT events. + + If you change the belowmouse widget, the previous one and all + parents (that don't contain the new widget) are sent FL_LEAVE + events. Changing this does \e not send FL_ENTER to this + or any widget, because sending FL_ENTER is supposed to \e test + if the widget wants the mouse (by it returning non-zero from + handle()). +*/ +void Fl::belowmouse(Fl_Widget *o) { + if (grab()) return; // don't do anything while grab is on + Fl_Widget *p = belowmouse_; + if (o != p) { + belowmouse_ = o; + int old_event = e_number; + e_number = dnd_flag ? FL_DND_LEAVE : FL_LEAVE; + for (; p && !p->contains(o); p = p->parent()) { + p->handle(e_number); + } + e_number = old_event; + } +} + +/** + Sets the widget that is being pushed. FL_DRAG or + FL_RELEASE (and any more FL_PUSH) events will be sent to + this widget. + + If you change the pushed widget, the previous one and all parents + (that don't contain the new widget) are sent FL_RELEASE + events. Changing this does \e not send FL_PUSH to this + or any widget, because sending FL_PUSH is supposed to \e test + if the widget wants the mouse (by it returning non-zero from + handle()). +*/ + void Fl::pushed(Fl_Widget *o) { + pushed_ = o; +} + +static void nothing(Fl_Widget *) {} +void (*Fl_Tooltip::enter)(Fl_Widget *) = nothing; +void (*Fl_Tooltip::exit)(Fl_Widget *) = nothing; + +// Update modal(), focus() and other state according to system state, +// and send FL_ENTER, FL_LEAVE, FL_FOCUS, and/or FL_UNFOCUS events. +// This is the only function that produces these events in response +// to system activity. +// This is called whenever a window is added or hidden, and whenever +// X says the focus or mouse window have changed. + +void fl_fix_focus() { +#ifdef DEBUG + puts("fl_fix_focus();"); +#endif // DEBUG + + if (Fl::grab()) return; // don't do anything while grab is on. + + // set focus based on Fl::modal() and fl_xfocus + Fl_Widget* w = fl_xfocus; + if (w) { + int saved = Fl::e_keysym; + if (Fl::e_keysym < (FL_Button + FL_LEFT_MOUSE) || + Fl::e_keysym > (FL_Button + FL_RIGHT_MOUSE)) + Fl::e_keysym = 0; // make sure widgets don't think a keystroke moved focus + while (w->parent()) w = w->parent(); + if (Fl::modal()) w = Fl::modal(); + if (!w->contains(Fl::focus())) + if (!w->take_focus()) Fl::focus(w); + Fl::e_keysym = saved; + } else + Fl::focus(0); + +// MRS: Originally we checked the button state, but a user reported that it +// broke click-to-focus in FLWM?!? +// if (!(Fl::event_state() & 0x7f00000 /*FL_BUTTONS*/)) { + if (!Fl::pushed()) { + // set belowmouse based on Fl::modal() and fl_xmousewin: + w = fl_xmousewin; + if (w) { + if (Fl::modal()) w = Fl::modal(); + if (!w->contains(Fl::belowmouse())) { + int old_event = Fl::e_number; + w->handle(Fl::e_number = FL_ENTER); + Fl::e_number = old_event; + if (!w->contains(Fl::belowmouse())) Fl::belowmouse(w); + } else { + // send a FL_MOVE event so the enter/leave state is up to date + Fl::e_x = Fl::e_x_root-fl_xmousewin->x(); + Fl::e_y = Fl::e_y_root-fl_xmousewin->y(); + int old_event = Fl::e_number; + w->handle(Fl::e_number = FL_MOVE); + Fl::e_number = old_event; + } + } else { + Fl::belowmouse(0); + Fl_Tooltip::enter(0); + } + } +} + +#ifndef WIN32 +extern Fl_Widget *fl_selection_requestor; // from Fl_x.cxx +#endif + +// This function is called by ~Fl_Widget() and by Fl_Widget::deactivate +// and by Fl_Widget::hide(). It indicates that the widget does not want +// to receive any more events, and also removes all global variables that +// point at the widget. +// I changed this from the 1.0.1 behavior, the older version could send +// FL_LEAVE or FL_UNFOCUS events to the widget. This appears to not be +// desirable behavior and caused flwm to crash. + +void fl_throw_focus(Fl_Widget *o) { +#ifdef DEBUG + printf("fl_throw_focus(o=%p)\n", o); +#endif // DEBUG + + if (o->contains(Fl::pushed())) Fl::pushed_ = 0; +#ifndef WIN32 + if (o->contains(fl_selection_requestor)) fl_selection_requestor = 0; +#endif + if (o->contains(Fl::belowmouse())) Fl::belowmouse_ = 0; + if (o->contains(Fl::focus())) Fl::focus_ = 0; + if (o == fl_xfocus) fl_xfocus = 0; + if (o == Fl_Tooltip::current()) Fl_Tooltip::current(0); + if (o == fl_xmousewin) fl_xmousewin = 0; + Fl_Tooltip::exit(o); + fl_fix_focus(); +} + +//////////////////////////////////////////////////////////////// + +// Call to->handle but first replace the mouse x/y with the correct +// values to account for nested X windows. 'window' is the outermost +// window the event was posted to by X: +static int send(int event, Fl_Widget* to, Fl_Window* window) { + int dx, dy; + int old_event = Fl::e_number; + if (window) { + dx = window->x(); + dy = window->y(); + } else { + dx = dy = 0; + } + for (const Fl_Widget* w = to; w; w = w->parent()) + if (w->type()>=FL_WINDOW) {dx -= w->x(); dy -= w->y();} + int save_x = Fl::e_x; Fl::e_x += dx; + int save_y = Fl::e_y; Fl::e_y += dy; + int ret = to->handle(Fl::e_number = event); + Fl::e_number = old_event; + Fl::e_y = save_y; + Fl::e_x = save_x; + return ret; +} + +int Fl::handle(int e, Fl_Window* window) +/** + Sends the event to a window for processing. Returns non-zero if any + widget uses the event. +*/ +{ + e_number = e; + if (fl_local_grab) return fl_local_grab(e); + + Fl_Widget* wi = window; + + switch (e) { + + case FL_CLOSE: + if ( grab() || (modal() && window != modal()) ) return 0; + wi->do_callback(); + return 1; + + case FL_SHOW: + wi->Fl_Widget::show(); // this calls Fl_Widget::show(), not Fl_Window::show() + return 1; + + case FL_HIDE: + wi->Fl_Widget::hide(); // this calls Fl_Widget::hide(), not Fl_Window::hide() + return 1; + + case FL_PUSH: +#ifdef DEBUG + printf("Fl::handle(e=%d, window=%p);\n", e, window); +#endif // DEBUG + + if (grab()) wi = grab(); + else if (modal() && wi != modal()) return 0; + pushed_ = wi; + Fl_Tooltip::current(wi); + if (send(e, wi, window)) return 1; + // raise windows that are clicked on: + window->show(); + return 1; + + case FL_DND_ENTER: + case FL_DND_DRAG: + dnd_flag = 1; + break; + + case FL_DND_LEAVE: + dnd_flag = 1; + belowmouse(0); + dnd_flag = 0; + return 1; + + case FL_DND_RELEASE: + wi = belowmouse(); + break; + + case FL_MOVE: + case FL_DRAG: + fl_xmousewin = window; // this should already be set, but just in case. + if (pushed()) { + wi = pushed(); + if (grab()) wi = grab(); + e_number = e = FL_DRAG; + break; + } + if (modal() && wi != modal()) wi = 0; + if (grab()) wi = grab(); + {Fl_Widget* pbm = belowmouse(); + int ret = (wi && send(e, wi, window)); + if (pbm != belowmouse()) { +#ifdef DEBUG + printf("Fl::handle(e=%d, window=%p);\n", e, window); +#endif // DEBUG + Fl_Tooltip::enter(belowmouse()); + } + return ret;} + + case FL_RELEASE: { +// printf("FL_RELEASE: window=%p, pushed() = %p, grab() = %p, modal() = %p\n", +// window, pushed(), grab(), modal()); + + if (grab()) { + wi = grab(); + pushed_ = 0; // must be zero before callback is done! + } else if (pushed()) { + wi = pushed(); + pushed_ = 0; // must be zero before callback is done! + } else if (modal() && wi != modal()) return 0; + int r = send(e, wi, window); + fl_fix_focus(); + return r;} + + case FL_UNFOCUS: + window = 0; + case FL_FOCUS: + fl_xfocus = window; + fl_fix_focus(); + return 1; + + case FL_KEYUP: + // Send the key-up to the current focus. This is not + // always the same widget that received the corresponding + // FL_KEYBOARD event because focus may have changed. + // Sending the KEYUP to the right KEYDOWN is possible, but + // would require that we track the KEYDOWN for every possible + // key stroke (users may hold down multiple keys!) and then + // make sure that the widget still exists before sending + // a KEYUP there. I believe that the current solution is + // "close enough". + for (wi = grab() ? grab() : focus(); wi; wi = wi->parent()) + if (send(FL_KEYUP, wi, window)) return 1; + return 0; + + case FL_KEYBOARD: +#ifdef DEBUG + printf("Fl::handle(e=%d, window=%p);\n", e, window); +#endif // DEBUG + + Fl_Tooltip::enter((Fl_Widget*)0); + + fl_xfocus = window; // this should not happen! But maybe it does: + + // Try it as keystroke, sending it to focus and all parents: + for (wi = grab() ? grab() : focus(); wi; wi = wi->parent()) + if (send(FL_KEYBOARD, wi, window)) return 1; + + // recursive call to try shortcut: + if (handle(FL_SHORTCUT, window)) return 1; + + // and then try a shortcut with the case of the text swapped, by + // changing the text and falling through to FL_SHORTCUT case: + {unsigned char* c = (unsigned char*)event_text(); // cast away const + if (!isalpha(*c)) return 0; + *c = isupper(*c) ? tolower(*c) : toupper(*c);} + e_number = e = FL_SHORTCUT; + + case FL_SHORTCUT: + if (grab()) {wi = grab(); break;} // send it to grab window + + // Try it as shortcut, sending to mouse widget and all parents: + wi = belowmouse(); + if (!wi) { + wi = modal(); + if (!wi) wi = window; + } else if (wi->window() != first_window()) { + if (send(FL_SHORTCUT, first_window(), first_window())) return 1; + } + + for (; wi; wi = wi->parent()) { + if (send(FL_SHORTCUT, wi, wi->window())) return 1; + } + + // try using add_handle() functions: + if (send_handlers(FL_SHORTCUT)) return 1; + + // make Escape key close windows: + if (event_key()==FL_Escape) { + wi = modal(); if (!wi) wi = window; + wi->do_callback(); + return 1; + } + + return 0; + + case FL_ENTER: +#ifdef DEBUG + printf("Fl::handle(e=%d, window=%p);\n", e, window); +#endif // DEBUG + + fl_xmousewin = window; + fl_fix_focus(); + Fl_Tooltip::enter(belowmouse()); + return 1; + + case FL_LEAVE: +#ifdef DEBUG + printf("Fl::handle(e=%d, window=%p);\n", e, window); +#endif // DEBUG + + if (!pushed_) { + belowmouse(0); + Fl_Tooltip::enter(0); + } + if (window == fl_xmousewin) {fl_xmousewin = 0; fl_fix_focus();} + return 1; + + case FL_MOUSEWHEEL: + fl_xfocus = window; // this should not happen! But maybe it does: + + // Try sending it to the "grab" first + if (grab() && grab()!=modal() && grab()!=window) { + if (send(FL_MOUSEWHEEL, grab(), window)) return 1; + } + // Now try sending it to the "modal" window + if (modal()) { + send(FL_MOUSEWHEEL, modal(), window); + return 1; + } + // Finally try sending it to the window, the event occured in + if (send(FL_MOUSEWHEEL, window, window)) return 1; + default: + break; + } + if (wi && send(e, wi, window)) { + dnd_flag = 0; + return 1; + } + dnd_flag = 0; + return send_handlers(e); +} + +//////////////////////////////////////////////////////////////// +// hide() destroys the X window, it does not do unmap! + +#if !defined(WIN32) && USE_XFT +extern void fl_destroy_xft_draw(Window); +#endif + +void Fl_Window::hide() { + clear_visible(); + + if (!shown()) return; + + // remove from the list of windows: + Fl_X* ip = i; + Fl_X** pp = &Fl_X::first; + for (; *pp != ip; pp = &(*pp)->next) if (!*pp) return; + *pp = ip->next; +#ifdef __APPLE__ + MacUnlinkWindow(ip); + // MacOS X manages a single pointer per application. Make sure that hiding + // a toplevel window will not leave us with some random pointer shape, or + // worst case, an invisible pointer + if (!parent()) cursor(FL_CURSOR_DEFAULT); +#endif + i = 0; + + // recursively remove any subwindows: + for (Fl_X *wi = Fl_X::first; wi;) { + Fl_Window* W = wi->w; + if (W->window() == this) { + W->hide(); + W->set_visible(); + wi = Fl_X::first; + } else wi = wi->next; + } + + if (this == Fl::modal_) { // we are closing the modal window, find next one: + Fl_Window* W; + for (W = Fl::first_window(); W; W = Fl::next_window(W)) + if (W->modal()) break; + Fl::modal_ = W; + } + + // Make sure no events are sent to this window: + fl_throw_focus(this); + handle(FL_HIDE); + +#if defined(WIN32) + // this little trick keeps the current clipboard alive, even if we are about + // to destroy the window that owns the selection. + if (GetClipboardOwner()==ip->xid) { + Fl_Window *w1 = Fl::first_window(); + if (w1 && OpenClipboard(fl_xid(w1))) { + EmptyClipboard(); + SetClipboardData(CF_TEXT, NULL); + CloseClipboard(); + } + } + // Send a message to myself so that I'll get out of the event loop... + PostMessage(ip->xid, WM_APP, 0, 0); + if (ip->private_dc) fl_release_dc(ip->xid, ip->private_dc); + if (ip->xid == fl_window && fl_gc) { + fl_release_dc(fl_window, fl_gc); + fl_window = (HWND)-1; + fl_gc = 0; +# ifdef USE_CAIRO + if (Fl::cairo_autolink_context()) Fl::cairo_make_current((Fl_Window*) 0); +# endif + } +#elif defined(__APPLE_QUARTZ__) + Fl_X::q_release_context(ip); + if ( ip->xid == fl_window && !parent() ) + fl_window = 0; +#endif + + if (ip->region) XDestroyRegion(ip->region); + +#if defined(USE_X11) +# if USE_XFT + fl_destroy_xft_draw(ip->xid); +# endif + XDestroyWindow(fl_display, ip->xid); +#elif defined(WIN32) + // this little trickery seems to avoid the popup window stacking problem + HWND p = GetForegroundWindow(); + if (p==GetParent(ip->xid)) { + ShowWindow(ip->xid, SW_HIDE); + ShowWindow(p, SW_SHOWNA); + } + XDestroyWindow(fl_display, ip->xid); +#elif defined(__APPLE_QUARTZ__) + MacDestroyWindow(this, ip->xid); +#else +# error unsupported platform +#endif + +#ifdef WIN32 + // Try to stop the annoying "raise another program" behavior + if (non_modal() && Fl::first_window() && Fl::first_window()->shown()) + Fl::first_window()->show(); +#endif + delete ip; +} + +Fl_Window::~Fl_Window() { + hide(); + if (xclass_) { + free(xclass_); + } +} + +// FL_SHOW and FL_HIDE are called whenever the visibility of this widget +// or any parent changes. We must correctly map/unmap the system's window. + +// For top-level windows it is assumed the window has already been +// mapped or unmapped!!! This is because this should only happen when +// Fl_Window::show() or Fl_Window::hide() is called, or in response to +// iconize/deiconize events from the system. + +int Fl_Window::handle(int ev) +{ + if (parent()) { + switch (ev) { + case FL_SHOW: + if (!shown()) show(); + else { +#if defined(USE_X11) || defined(WIN32) + XMapWindow(fl_display, fl_xid(this)); // extra map calls are harmless +#elif defined(__APPLE_QUARTZ__) + MacMapWindow(this, i->xid); +#else +# error unsupported platform +#endif // __APPLE__ + } + break; + case FL_HIDE: + if (shown()) { + // Find what really turned invisible, if is was a parent window + // we do nothing. We need to avoid unnecessary unmap calls + // because they cause the display to blink when the parent is + // remapped. However if this or any intermediate non-window + // widget has really had hide() called directly on it, we must + // unmap because when the parent window is remapped we don't + // want to reappear. + if (visible()) { + Fl_Widget* p = parent(); for (;p->visible();p = p->parent()) {} + if (p->type() >= FL_WINDOW) break; // don't do the unmap + } +#if defined(USE_X11) || defined(WIN32) + XUnmapWindow(fl_display, fl_xid(this)); +#elif defined(__APPLE_QUARTZ__) + MacUnmapWindow(this, i->xid); +#else +# error platform unsupported +#endif + } + break; + } +// } else if (ev == FL_FOCUS || ev == FL_UNFOCUS) { +// Fl_Tooltip::exit(Fl_Tooltip::current()); + } + + return Fl_Group::handle(ev); +} + +//////////////////////////////////////////////////////////////// +// Back compatibility cut & paste functions for fltk 1.1 only: + +/** Back-compatibility only: The single-argument call can be used to + move the selection to another widget or to set the owner to + NULL, without changing the actual text of the + selection. FL_SELECTIONCLEAR is sent to the previous + selection owner, if any. + + Copying the buffer every time the selection is changed is + obviously wasteful, especially for large selections. An interface will + probably be added in a future version to allow the selection to be made + by a callback function. The current interface will be emulated on top + of this. +*/ +void Fl::selection_owner(Fl_Widget *owner) {selection_owner_ = owner;} + +/** + Changes the current selection. The block of text is + copied to an internal buffer by FLTK (be careful if doing this in + response to an FL_PASTE as this \e may be the same buffer + returned by event_text()). The selection_owner() + widget is set to the passed owner. +*/ +void Fl::selection(Fl_Widget &owner, const char* text, int len) { + selection_owner_ = &owner; + Fl::copy(text, len, 0); +} + +/** Backward compatibility only: + Set things up so the receiver widget will be called with an FL_PASTE event some + time in the future for the specified clipboard. The reciever + should be prepared to be called \e directly by this, or for + it to happen \e later, or possibly not at all. This + allows the window system to take as long as necessary to retrieve + the paste buffer (or even to screw up completely) without complex + and error-prone synchronization code in FLTK. + \see Fl::paste(Fl_Widget &receiver, int clipboard) +*/ +void Fl::paste(Fl_Widget &receiver) { + Fl::paste(receiver, 0); +} + +//////////////////////////////////////////////////////////////// + +#include + +void Fl_Widget::redraw() { + damage(FL_DAMAGE_ALL); +} + +void Fl_Widget::redraw_label() { + if (window()) { + if (box() == FL_NO_BOX) { + // Widgets with the FL_NO_BOX boxtype need a parent to + // redraw, since it is responsible for redrawing the + // background... + int X = x() > 0 ? x() - 1 : 0; + int Y = y() > 0 ? y() - 1 : 0; + window()->damage(FL_DAMAGE_ALL, X, Y, w() + 2, h() + 2); + } + + if (align() && !(align() & FL_ALIGN_INSIDE) && window()->shown()) { + // If the label is not inside the widget, compute the location of + // the label and redraw the window within that bounding box... + int W = 0, H = 0; + label_.measure(W, H); + W += 5; // Add a little to the size of the label to cover overflow + H += 5; + + // FIXME: + // This assumes the measure() returns the correct outline, which it does + // not in all possible cases of alignment combinedwith image and symbols. + switch (align() & 0x0f) { + case FL_ALIGN_TOP_LEFT: + window()->damage(FL_DAMAGE_EXPOSE, x(), y()-H, W, H); break; + case FL_ALIGN_TOP: + window()->damage(FL_DAMAGE_EXPOSE, x()+(w()-W)/2, y()-H, W, H); break; + case FL_ALIGN_TOP_RIGHT: + window()->damage(FL_DAMAGE_EXPOSE, x()+w()-W, y()-H, W, H); break; + case FL_ALIGN_LEFT_TOP: + window()->damage(FL_DAMAGE_EXPOSE, x()-W, y(), W, H); break; + case FL_ALIGN_RIGHT_TOP: + window()->damage(FL_DAMAGE_EXPOSE, x()+w(), y(), W, H); break; + case FL_ALIGN_LEFT: + window()->damage(FL_DAMAGE_EXPOSE, x()-W, y()+(h()-H)/2, W, H); break; + case FL_ALIGN_RIGHT: + window()->damage(FL_DAMAGE_EXPOSE, x()+w(), y()+(h()-H)/2, W, H); break; + case FL_ALIGN_LEFT_BOTTOM: + window()->damage(FL_DAMAGE_EXPOSE, x()-W, y()+h()-H, W, H); break; + case FL_ALIGN_RIGHT_BOTTOM: + window()->damage(FL_DAMAGE_EXPOSE, x()+w(), y()+h()-H, W, H); break; + case FL_ALIGN_BOTTOM_LEFT: + window()->damage(FL_DAMAGE_EXPOSE, x(), y()+h(), W, H); break; + case FL_ALIGN_BOTTOM: + window()->damage(FL_DAMAGE_EXPOSE, x()+(w()-W)/2, y()+h(), W, H); break; + case FL_ALIGN_BOTTOM_RIGHT: + window()->damage(FL_DAMAGE_EXPOSE, x()+w()-W, y()+h(), W, H); break; + default: + window()->damage(FL_DAMAGE_ALL); break; + } + } else { + // The label is inside the widget, so just redraw the widget itself... + damage(FL_DAMAGE_ALL); + } + } +} + +void Fl_Widget::damage(uchar fl) { + if (type() < FL_WINDOW) { + // damage only the rectangle covered by a child widget: + damage(fl, x(), y(), w(), h()); + } else { + // damage entire window by deleting the region: + Fl_X* i = Fl_X::i((Fl_Window*)this); + if (!i) return; // window not mapped, so ignore it + if (i->region) {XDestroyRegion(i->region); i->region = 0;} + damage_ |= fl; + Fl::damage(FL_DAMAGE_CHILD); + } +} + +void Fl_Widget::damage(uchar fl, int X, int Y, int W, int H) { + Fl_Widget* wi = this; + // mark all parent widgets between this and window with FL_DAMAGE_CHILD: + while (wi->type() < FL_WINDOW) { + wi->damage_ |= fl; + wi = wi->parent(); + if (!wi) return; + fl = FL_DAMAGE_CHILD; + } + Fl_X* i = Fl_X::i((Fl_Window*)wi); + if (!i) return; // window not mapped, so ignore it + + // clip the damage to the window and quit if none: + if (X < 0) {W += X; X = 0;} + if (Y < 0) {H += Y; Y = 0;} + if (W > wi->w()-X) W = wi->w()-X; + if (H > wi->h()-Y) H = wi->h()-Y; + if (W <= 0 || H <= 0) return; + + if (!X && !Y && W==wi->w() && H==wi->h()) { + // if damage covers entire window delete region: + wi->damage(fl); + return; + } + + if (wi->damage()) { + // if we already have damage we must merge with existing region: + if (i->region) { +#if defined(USE_X11) + XRectangle R; + R.x = X; R.y = Y; R.width = W; R.height = H; + XUnionRectWithRegion(&R, i->region, i->region); +#elif defined(WIN32) + Fl_Region R = XRectangleRegion(X, Y, W, H); + CombineRgn(i->region, i->region, R, RGN_OR); + XDestroyRegion(R); +#elif defined(__APPLE_QUARTZ__) + CGRect arg = fl_cgrectmake_cocoa(X, Y, W, H); + int j; // don't add a rectangle totally inside the Fl_Region + for(j = 0; j < i->region->count; j++) { + if(CGRectContainsRect(i->region->rects[j], arg)) break; + } + if( j >= i->region->count) { + i->region->rects = (CGRect*)realloc(i->region->rects, (++(i->region->count)) * sizeof(CGRect)); + i->region->rects[i->region->count - 1] = arg; + } +#else +# error unsupported platform +#endif + } + wi->damage_ |= fl; + } else { + // create a new region: + if (i->region) XDestroyRegion(i->region); + i->region = XRectangleRegion(X,Y,W,H); + wi->damage_ = fl; + } + Fl::damage(FL_DAMAGE_CHILD); +} +void Fl_Window::flush() { + make_current(); +//if (damage() == FL_DAMAGE_EXPOSE && can_boxcheat(box())) fl_boxcheat = this; + fl_clip_region(i->region); i->region = 0; + draw(); +} + +#ifdef WIN32 +# include "Fl_win32.cxx" +#elif defined(__APPLE__) +# include "Fl_cocoa.mm" +#endif + +// +// The following methods allow callbacks to schedule the deletion of +// widgets at "safe" times. +// + +static int num_dwidgets = 0, alloc_dwidgets = 0; +static Fl_Widget **dwidgets = 0; + +/** + Schedules a widget for deletion at the next call to the event loop. + Use this method to delete a widget inside a callback function. + + To avoid early deletion of widgets, this function should be called + toward the end of a callback and only after any call to the event + loop (Fl::wait(), Fl::flush(), Fl::check(), fl_ask(), etc.). + + When deleting groups or windows, you must only delete the group or + window widget and not the individual child widgets. + + \since FLTK 1.3 it is not necessary to remove widgets from their parent + groups or windows before calling this, because it will be done in the + widget's destructor, but it is not a failure to do this nevertheless. + + \note In FLTK 1.1 you \b must remove widgets from their parent group + (or window) before deleting them. + + \see Fl_Widget::~Fl_Widget() +*/ +void Fl::delete_widget(Fl_Widget *wi) { + if (!wi) return; + + if (num_dwidgets >= alloc_dwidgets) { + Fl_Widget **temp; + + temp = new Fl_Widget *[alloc_dwidgets + 10]; + if (alloc_dwidgets) { + memcpy(temp, dwidgets, alloc_dwidgets * sizeof(Fl_Widget *)); + delete[] dwidgets; + } + + dwidgets = temp; + alloc_dwidgets += 10; + } + + dwidgets[num_dwidgets] = wi; + num_dwidgets ++; +} + +/** + Deletes widgets previously scheduled for deletion. + + This is for internal use only. You should never call this directly. + + Fl::do_widget_deletion() is called from the FLTK event loop or whenever + you call Fl::wait(). The previously scheduled widgets are deleted in the + same order they were scheduled by calling Fl::delete_widget(). + + \see Fl::delete_widget(Fl_Widget *wi) +*/ +void Fl::do_widget_deletion() { + if (!num_dwidgets) return; + + for (int i = 0; i < num_dwidgets; i ++) + delete dwidgets[i]; + + num_dwidgets = 0; +} + +static Fl_Widget ***widget_watch = 0; +static int num_widget_watch = 0; +static int max_widget_watch = 0; + +/** + Adds a widget pointer to the widget watch list. + + \note Internal use only, please use class Fl_Widget_Tracker instead. + + This can be used, if it is possible that a widget might be deleted during + a callback or similar function. The widget pointer must be added to the + watch list before calling the callback. After the callback the widget + pointer can be queried, if it is NULL. \e If it is NULL, then the widget has been + deleted during the callback and must not be accessed anymore. If the widget + pointer is \e not NULL, then the widget has not been deleted and can be accessed + safely. + + After accessing the widget, the widget pointer must be released from the + watch list by calling Fl::release_widget_pointer(). + + Example for a button that is clicked (from its handle() method): + \code + Fl_Widget *wp = this; // save 'this' in a pointer variable + Fl::watch_widget_pointer(wp); // add the pointer to the watch list + set_changed(); // set the changed flag + do_callback(); // call the callback + if (!wp) { // the widget has been deleted + + // DO NOT ACCESS THE DELETED WIDGET ! + + } else { // the widget still exists + clear_changed(); // reset the changed flag + } + + Fl::release_widget_pointer(wp); // remove the pointer from the watch list + \endcode + + This works, because all widgets call Fl::clear_widget_pointer() in their + destructors. + + \see Fl::release_widget_pointer() + \see Fl::clear_widget_pointer() + + An easier and more convenient method to control widget deletion during + callbacks is to use the class Fl_Widget_Tracker with a local (automatic) + variable. + + \see class Fl_Widget_Tracker +*/ +void Fl::watch_widget_pointer(Fl_Widget *&w) +{ + Fl_Widget **wp = &w; + int i; + for (i=0; i %8p\n", + num_widget_watch,num_widget_watch,wp,*wp); + fflush(stdout); +#endif // DEBUG_WATCH +} + +/** + Releases a widget pointer from the watch list. + + This is used to remove a widget pointer that has been added to the watch list + with Fl::watch_widget_pointer(), when it is not needed anymore. + + \note Internal use only, please use class Fl_Widget_Tracker instead. + + \see Fl::watch_widget_pointer() +*/ +void Fl::release_widget_pointer(Fl_Widget *&w) +{ + Fl_Widget **wp = &w; + int i,j=0; + for (i=0; i %8p\n", + i+1,num_widget_watch,wp,*wp); + } +#endif //DEBUG_WATCH + } + num_widget_watch = j; +#ifdef DEBUG_WATCH + printf (" num_widget_watch = %d\n\n",num_widget_watch); + fflush(stdout); +#endif // DEBUG_WATCH + return; +} +/** + Clears a widget pointer \e in the watch list. + + This is called when a widget is destroyed (by its destructor). You should never + call this directly. + + \note Internal use only ! + + This method searches the widget watch list for pointers to the widget and + clears each pointer that points to it. Widget pointers can be added to the + widget watch list by calling Fl::watch_widget_pointer() or by using the + helper class Fl_Widget_Tracker (recommended). + + \see Fl::watch_widget_pointer() + \see class Fl_Widget_Tracker +*/ +void Fl::clear_widget_pointer(Fl_Widget const *w) +{ + if (w==0L) return; + int i; + for (i=0; i=OPTION_LAST) + return false; + return (bool)options_[o]; +} + + +// Helper class Fl_Widget_Tracker + +/** + The constructor adds a widget to the watch list. +*/ +Fl_Widget_Tracker::Fl_Widget_Tracker(Fl_Widget *wi) { + + wp_ = wi; + Fl::watch_widget_pointer(wp_); // add pointer to watch list +} + +/** + The destructor removes a widget from the watch list. +*/ +Fl_Widget_Tracker::~Fl_Widget_Tracker() { + + Fl::release_widget_pointer(wp_); // remove pointer from watch list +} + + +// +// End of "$Id: Fl.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Adjuster.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Adjuster.cxx new file mode 100644 index 0000000..150504f --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Adjuster.cxx @@ -0,0 +1,182 @@ +// +// "$Id: Fl_Adjuster.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Adjuster widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include +#include + +#include "fastarrow.h" +static Fl_Bitmap fastarrow(fastarrow_bits, fastarrow_width, fastarrow_height); +#include "mediumarrow.h" +static Fl_Bitmap mediumarrow(mediumarrow_bits, mediumarrow_width, mediumarrow_height); +#include "slowarrow.h" +static Fl_Bitmap slowarrow(slowarrow_bits, slowarrow_width, slowarrow_height); + +// changing the value does not change the appearance: +void Fl_Adjuster::value_damage() {} + +void Fl_Adjuster::draw() { + int dx, dy, W, H; + if (w()>=h()) { + dx = W = w()/3; + dy = 0; H = h(); + } else { + dx = 0; W = w(); + dy = H = h()/3; + } + draw_box(drag==1?FL_DOWN_BOX:box(), x(), y()+2*dy, W, H, color()); + draw_box(drag==2?FL_DOWN_BOX:box(), x()+dx, y()+dy, W, H, color()); + draw_box(drag==3?FL_DOWN_BOX:box(), x()+2*dx, y(), W, H, color()); + if (active_r()) + fl_color(selection_color()); + else + fl_color(fl_inactive(selection_color())); + fastarrow.draw(x()+(W-fastarrow_width)/2, + y()+2*dy+(H-fastarrow_height)/2, W, H); + mediumarrow.draw(x()+dx+(W-mediumarrow_width)/2, + y()+dy+(H-mediumarrow_height)/2, W, H); + slowarrow.draw(x()+2*dx+(W-slowarrow_width)/2, + y()+(H-slowarrow_width)/2, W, H); + if (Fl::focus() == this) draw_focus(); +} + +int Fl_Adjuster::handle(int event) { + double v; + int delta; + int mx = Fl::event_x(); + // Fl_Widget_Tracker wp(this); + switch (event) { + case FL_PUSH: + if (Fl::visible_focus()) Fl::focus(this); + ix = mx; + if (w()>=h()) + drag = 3*(mx-x())/w() + 1; + else + drag = 3-3*(Fl::event_y()-y()-1)/h(); + { Fl_Widget_Tracker wp(this); + handle_push(); + if (wp.deleted()) return 1; + } + redraw(); + return 1; + case FL_DRAG: + if (w() >= h()) { + delta = x()+(drag-1)*w()/3; // left edge of button + if (mx < delta) + delta = mx-delta; + else if (mx > (delta+w()/3)) // right edge of button + delta = mx-delta-w()/3; + else + delta = 0; + } else { + if (mx < x()) + delta = mx-x(); + else if (mx > (x()+w())) + delta = mx-x()-w(); + else + delta = 0; + } + switch (drag) { + case 3: v = increment(previous_value(), delta); break; + case 2: v = increment(previous_value(), delta*10); break; + default:v = increment(previous_value(), delta*100); break; + } + handle_drag(soft() ? softclamp(v) : clamp(v)); + return 1; + case FL_RELEASE: + if (Fl::event_is_click()) { // detect click but no drag + if (Fl::event_state()&0xF0000) delta = -10; + else delta = 10; + switch (drag) { + case 3: v = increment(previous_value(), delta); break; + case 2: v = increment(previous_value(), delta*10); break; + default:v = increment(previous_value(), delta*100); break; + } + Fl_Widget_Tracker wp(this); + handle_drag(soft() ? softclamp(v) : clamp(v)); + if (wp.deleted()) return 1; + } + drag = 0; + redraw(); + handle_release(); + return 1; + case FL_KEYBOARD : + switch (Fl::event_key()) { + case FL_Up: + if (w() > h()) return 0; + handle_drag(clamp(increment(value(),-1))); + return 1; + case FL_Down: + if (w() > h()) return 0; + handle_drag(clamp(increment(value(),1))); + return 1; + case FL_Left: + if (w() < h()) return 0; + handle_drag(clamp(increment(value(),-1))); + return 1; + case FL_Right: + if (w() < h()) return 0; + handle_drag(clamp(increment(value(),1))); + return 1; + default: + return 0; + } + // break not required because of switch... + + case FL_FOCUS: + case FL_UNFOCUS: + if (Fl::visible_focus()) { + redraw(); + return 1; + } else return 0; + + case FL_ENTER : + case FL_LEAVE : + return 1; + } + return 0; +} + +/** + Creates a new Fl_Adjuster widget using the given position, + size, and label string. It looks best if one of the dimensions is 3 + times the other. +

Inherited destructor destroys the Valuator. +*/ +Fl_Adjuster::Fl_Adjuster(int X, int Y, int W, int H, const char* l) + : Fl_Valuator(X, Y, W, H, l) { + box(FL_UP_BOX); + step(1, 10000); + selection_color(FL_SELECTION_COLOR); + drag = 0; + soft_ = 1; +} + +// +// End of "$Id: Fl_Adjuster.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_BMP_Image.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_BMP_Image.cxx new file mode 100644 index 0000000..65b1237 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_BMP_Image.cxx @@ -0,0 +1,495 @@ +// +// "$Id: Fl_BMP_Image.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Fl_BMP_Image routines. +// +// Copyright 1997-2010 by Easy Software Products. +// Image support by Matthias Melcher, Copyright 2000-2009. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// +// Contents: +// +// Fl_BMP_Image::Fl_BMP_Image() - Load a BMP image file. +// + +// +// Include necessary header files... +// + +#include +#include +#include +#include +#include + + +// +// BMP definitions... +// + +#ifndef BI_RGB +# define BI_RGB 0 // No compression - straight BGR data +# define BI_RLE8 1 // 8-bit run-length compression +# define BI_RLE4 2 // 4-bit run-length compression +# define BI_BITFIELDS 3 // RGB bitmap with RGB masks +#endif // !BI_RGB + + +// +// Local functions... +// + +static int read_long(FILE *fp); +static unsigned short read_word(FILE *fp); +static unsigned int read_dword(FILE *fp); +/** + The constructor loads the named BMP image from the given bmp filename. +

The inherited destructor free all memory and server resources that are used by + the image. +

The destructor free all memory and server resources that are used by + the image +*/ +Fl_BMP_Image::Fl_BMP_Image(const char *bmp) // I - File to read + : Fl_RGB_Image(0,0,0) { + FILE *fp; // File pointer + int info_size, // Size of info header + depth, // Depth of image (bits) + bDepth = 3, // Depth of image (bytes) + compression, // Type of compression + colors_used, // Number of colors used + x, y, // Looping vars + color, // Color of RLE pixel + repcount, // Number of times to repeat + temp, // Temporary color + align, // Alignment bytes + dataSize, // number of bytes in image data set + row_order, // 1 = normal; -1 = flipped row order + start_y, // Beginning Y + end_y; // Ending Y + long offbits; // Offset to image data + uchar bit, // Bit in image + byte; // Byte in image + uchar *ptr; // Pointer into pixels + uchar colormap[256][3];// Colormap + uchar havemask; // Single bit mask follows image data + int use_5_6_5; // Use 5:6:5 for R:G:B channels in 16 bit images + + + // Open the file... + if ((fp = fl_fopen(bmp, "rb")) == NULL) return; + + // Get the header... + byte = (uchar)getc(fp); // Check "BM" sync chars + bit = (uchar)getc(fp); + if (byte != 'B' || bit != 'M') { + fclose(fp); + return; + } + + read_dword(fp); // Skip size + read_word(fp); // Skip reserved stuff + read_word(fp); + offbits = (long)read_dword(fp);// Read offset to image data + + // Then the bitmap information... + info_size = read_dword(fp); + +// printf("offbits = %ld, info_size = %d\n", offbits, info_size); + + havemask = 0; + row_order = -1; + use_5_6_5 = 0; + + if (info_size < 40) { + // Old Windows/OS2 BMP header... + w(read_word(fp)); + h(read_word(fp)); + read_word(fp); + depth = read_word(fp); + compression = BI_RGB; + colors_used = 0; + + repcount = info_size - 12; + } else { + // New BMP header... + w(read_long(fp)); + // If the height is negative, the row order is flipped + temp = read_long(fp); + if (temp < 0) row_order = 1; + h(abs(temp)); + read_word(fp); + depth = read_word(fp); + compression = read_dword(fp); + dataSize = read_dword(fp); + read_long(fp); + read_long(fp); + colors_used = read_dword(fp); + read_dword(fp); + + repcount = info_size - 40; + + if (!compression && depth>=8 && w()>32/depth) { + int Bpp = depth/8; + int maskSize = (((w()*Bpp+3)&~3)*h()) + (((((w()+7)/8)+3)&~3)*h()); + if (maskSize==2*dataSize) { + havemask = 1; + h(h()/2); + bDepth = 4; + } + } + } + +// printf("w() = %d, h() = %d, depth = %d, compression = %d, colors_used = %d, repcount = %d\n", +// w(), h(), depth, compression, colors_used, repcount); + + // Skip remaining header bytes... + while (repcount > 0) { + getc(fp); + repcount --; + } + + // Check header data... + if (!w() || !h() || !depth) { + fclose(fp); + return; + } + + // Get colormap... + if (colors_used == 0 && depth <= 8) + colors_used = 1 << depth; + + for (repcount = 0; repcount < colors_used; repcount ++) { + // Read BGR color... + if (fread(colormap[repcount], 1, 3, fp)==0) { /* ignore */ } + + // Skip pad byte for new BMP files... + if (info_size > 12) getc(fp); + } + + // Read first dword of colormap. It tells us if 5:5:5 or 5:6:5 for 16 bit + if (depth == 16) + use_5_6_5 = (read_dword(fp) == 0xf800); + + // Set byte depth for RGBA images + if (depth == 32) + bDepth=4; + + // Setup image and buffers... + d(bDepth); + if (offbits) fseek(fp, offbits, SEEK_SET); + + array = new uchar[w() * h() * d()]; + alloc_array = 1; + + // Read the image data... + color = 0; + repcount = 0; + align = 0; + byte = 0; + temp = 0; + + if (row_order < 0) { + start_y = h() - 1; + end_y = -1; + } else { + start_y = 0; + end_y = h(); + } + + for (y = start_y; y != end_y; y += row_order) { + ptr = (uchar *)array + y * w() * d(); + + switch (depth) + { + case 1 : // Bitmap + for (x = w(), bit = 128; x > 0; x --) { + if (bit == 128) byte = (uchar)getc(fp); + + if (byte & bit) { + *ptr++ = colormap[1][2]; + *ptr++ = colormap[1][1]; + *ptr++ = colormap[1][0]; + } else { + *ptr++ = colormap[0][2]; + *ptr++ = colormap[0][1]; + *ptr++ = colormap[0][0]; + } + + if (bit > 1) + bit >>= 1; + else + bit = 128; + } + + // Read remaining bytes to align to 32 bits... + for (temp = (w() + 7) / 8; temp & 3; temp ++) { + getc(fp); + } + break; + + case 4 : // 16-color + for (x = w(), bit = 0xf0; x > 0; x --) { + // Get a new repcount as needed... + if (repcount == 0) { + if (compression != BI_RLE4) { + repcount = 2; + color = -1; + } else { + while (align > 0) { + align --; + getc(fp); + } + + if ((repcount = getc(fp)) == 0) { + if ((repcount = getc(fp)) == 0) { + // End of line... + x ++; + continue; + } else if (repcount == 1) { + // End of image... + break; + } else if (repcount == 2) { + // Delta... + repcount = getc(fp) * getc(fp) * w(); + color = 0; + } else { + // Absolute... + color = -1; + align = ((4 - (repcount & 3)) / 2) & 1; + } + } else { + color = getc(fp); + } + } + } + + // Get a new color as needed... + repcount --; + + // Extract the next pixel... + if (bit == 0xf0) { + // Get the next color byte as needed... + if (color < 0) temp = getc(fp); + else temp = color; + + // Copy the color value... + *ptr++ = colormap[(temp >> 4) & 15][2]; + *ptr++ = colormap[(temp >> 4) & 15][1]; + *ptr++ = colormap[(temp >> 4) & 15][0]; + + bit = 0x0f; + } else { + bit = 0xf0; + + // Copy the color value... + *ptr++ = colormap[temp & 15][2]; + *ptr++ = colormap[temp & 15][1]; + *ptr++ = colormap[temp & 15][0]; + } + + } + + if (!compression) { + // Read remaining bytes to align to 32 bits... + for (temp = (w() + 1) / 2; temp & 3; temp ++) { + getc(fp); + } + } + break; + + case 8 : // 256-color + for (x = w(); x > 0; x --) { + // Get a new repcount as needed... + if (compression != BI_RLE8) { + repcount = 1; + color = -1; + } + + if (repcount == 0) { + while (align > 0) { + align --; + getc(fp); + } + + if ((repcount = getc(fp)) == 0) { + if ((repcount = getc(fp)) == 0) { + // End of line... + x ++; + continue; + } else if (repcount == 1) { + // End of image... + break; + } else if (repcount == 2) { + // Delta... + repcount = getc(fp) * getc(fp) * w(); + color = 0; + } else { + // Absolute... + color = -1; + align = (2 - (repcount & 1)) & 1; + } + } else { + color = getc(fp); + } + } + + // Get a new color as needed... + if (color < 0) temp = getc(fp); + else temp = color; + + repcount --; + + // Copy the color value... + *ptr++ = colormap[temp][2]; + *ptr++ = colormap[temp][1]; + *ptr++ = colormap[temp][0]; + if (havemask) ptr++; + } + + if (!compression) { + // Read remaining bytes to align to 32 bits... + for (temp = w(); temp & 3; temp ++) { + getc(fp); + } + } + break; + + case 16 : // 16-bit 5:5:5 or 5:6:5 RGB + for (x = w(); x > 0; x --, ptr += bDepth) { + uchar b = getc(fp), a = getc(fp) ; + if (use_5_6_5) { + ptr[2] = (uchar)(( b << 3 ) & 0xf8); + ptr[1] = (uchar)(((a << 5) & 0xe0) | ((b >> 3) & 0x1c)); + ptr[0] = (uchar)(a & 0xf8); + } else { + ptr[2] = (uchar)((b << 3) & 0xf8); + ptr[1] = (uchar)(((a << 6) & 0xc0) | ((b >> 2) & 0x38)); + ptr[0] = (uchar)((a<<1) & 0xf8); + } + } + + // Read remaining bytes to align to 32 bits... + for (temp = w() * 2; temp & 3; temp ++) { + getc(fp); + } + break; + + case 24 : // 24-bit RGB + for (x = w(); x > 0; x --, ptr += bDepth) { + ptr[2] = (uchar)getc(fp); + ptr[1] = (uchar)getc(fp); + ptr[0] = (uchar)getc(fp); + } + + // Read remaining bytes to align to 32 bits... + for (temp = w() * 3; temp & 3; temp ++) { + getc(fp); + } + break; + + case 32 : // 32-bit RGBA + for (x = w(); x > 0; x --, ptr += bDepth) { + ptr[2] = (uchar)getc(fp); + ptr[1] = (uchar)getc(fp); + ptr[0] = (uchar)getc(fp); + ptr[3] = (uchar)getc(fp); + } + break; + } + } + + if (havemask) { + for (y = h() - 1; y >= 0; y --) { + ptr = (uchar *)array + y * w() * d() + 3; + for (x = w(), bit = 128; x > 0; x --, ptr+=bDepth) { + if (bit == 128) byte = (uchar)getc(fp); + if (byte & bit) + *ptr = 0; + else + *ptr = 255; + if (bit > 1) + bit >>= 1; + else + bit = 128; + } + // Read remaining bytes to align to 32 bits... + for (temp = (w() + 7) / 8; temp & 3; temp ++) + getc(fp); + } + } + + // Close the file and return... + fclose(fp); +} + + +// +// 'read_word()' - Read a 16-bit unsigned integer. +// + +static unsigned short // O - 16-bit unsigned integer +read_word(FILE *fp) { // I - File to read from + unsigned char b0, b1; // Bytes from file + + b0 = (uchar)getc(fp); + b1 = (uchar)getc(fp); + + return ((b1 << 8) | b0); +} + + +// +// 'read_dword()' - Read a 32-bit unsigned integer. +// + +static unsigned int // O - 32-bit unsigned integer +read_dword(FILE *fp) { // I - File to read from + unsigned char b0, b1, b2, b3; // Bytes from file + + b0 = (uchar)getc(fp); + b1 = (uchar)getc(fp); + b2 = (uchar)getc(fp); + b3 = (uchar)getc(fp); + + return ((((((b3 << 8) | b2) << 8) | b1) << 8) | b0); +} + + +// +// 'read_long()' - Read a 32-bit signed integer. +// + +static int // O - 32-bit signed integer +read_long(FILE *fp) { // I - File to read from + unsigned char b0, b1, b2, b3; // Bytes from file + + b0 = (uchar)getc(fp); + b1 = (uchar)getc(fp); + b2 = (uchar)getc(fp); + b3 = (uchar)getc(fp); + + return ((int)(((((b3 << 8) | b2) << 8) | b1) << 8) | b0); +} + + +// +// End of "$Id: Fl_BMP_Image.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Bitmap.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Bitmap.cxx new file mode 100644 index 0000000..3e6eaf7 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Bitmap.cxx @@ -0,0 +1,482 @@ +// +// "$Id: Fl_Bitmap.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Bitmap drawing routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/** \fn Fl_Bitmap::Fl_Bitmap(const char *array, int W, int H) + The constructors create a new bitmap from the specified bitmap data.*/ + +/** \fn Fl_Bitmap::Fl_Bitmap(const unsigned char *array, int W, int H) + The constructors create a new bitmap from the specified bitmap data.*/ + +#include +#include +#include +#include +#include +#include +#include +#include "flstring.h" + +#if defined(__APPLE_QUARTZ__) + + +Fl_Bitmask fl_create_bitmask(int w, int h, const uchar *array) { + static uchar reverse[16] = /* Bit reversal lookup table */ + { 0x00, 0x88, 0x44, 0xcc, 0x22, 0xaa, 0x66, 0xee, + 0x11, 0x99, 0x55, 0xdd, 0x33, 0xbb, 0x77, 0xff }; + int rowBytes = (w+7)>>3 ; + uchar *bmask = (uchar*)malloc(rowBytes*h), *dst = bmask; + const uchar *src = array; + for ( int i=rowBytes*h; i>0; i--,src++ ) { + *dst++ = ((reverse[*src & 0x0f] & 0xf0) | (reverse[(*src >> 4) & 0x0f] & 0x0f))^0xff; + } + CGDataProviderRef srcp = CGDataProviderCreateWithData( 0L, bmask, rowBytes*h, 0L); + CGImageRef id_ = CGImageMaskCreate( w, h, 1, 1, rowBytes, srcp, 0L, false); + CGDataProviderRelease(srcp); + return (Fl_Bitmask)id_; +} +void fl_delete_bitmask(Fl_Bitmask bm) { + if (bm) CGImageRelease((CGImageRef)bm); +} + + +#elif defined(WIN32) // Windows bitmask functions... + + +// 'fl_create_bitmap()' - Create a 1-bit bitmap for drawing... +static Fl_Bitmask fl_create_bitmap(int w, int h, const uchar *data) { + // we need to pad the lines out to words & swap the bits + // in each byte. + int w1 = (w+7)/8; + int w2 = ((w+15)/16)*2; + uchar* newarray = new uchar[w2*h]; + const uchar* src = data; + uchar* dest = newarray; + Fl_Bitmask bm; + static uchar reverse[16] = /* Bit reversal lookup table */ + { 0x00, 0x88, 0x44, 0xcc, 0x22, 0xaa, 0x66, 0xee, + 0x11, 0x99, 0x55, 0xdd, 0x33, 0xbb, 0x77, 0xff }; + + for (int y=0; y < h; y++) { + for (int n = 0; n < w1; n++, src++) + *dest++ = (uchar)((reverse[*src & 0x0f] & 0xf0) | + (reverse[(*src >> 4) & 0x0f] & 0x0f)); + dest += w2-w1; + } + + bm = CreateBitmap(w, h, 1, 1, newarray); + + delete[] newarray; + + return bm; +} + +// 'fl_create_bitmask()' - Create an N-bit bitmap for masking... +Fl_Bitmask fl_create_bitmask(int w, int h, const uchar *data) { + // this won't work when the user changes display mode during run or + // has two screens with differnet depths + Fl_Bitmask bm; + static uchar hiNibble[16] = + { 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, + 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0 }; + static uchar loNibble[16] = + { 0x00, 0x08, 0x04, 0x0c, 0x02, 0x0a, 0x06, 0x0e, + 0x01, 0x09, 0x05, 0x0d, 0x03, 0x0b, 0x07, 0x0f }; + int np = GetDeviceCaps(fl_gc, PLANES); //: was always one on sample machines + int bpp = GetDeviceCaps(fl_gc, BITSPIXEL);//: 1,4,8,16,24,32 and more odd stuff? + int Bpr = (bpp*w+7)/8; //: bytes per row + int pad = Bpr&1, w1 = (w+7)/8, shr = ((w-1)&7)+1; + if (bpp==4) shr = (shr+1)/2; + uchar *newarray = new uchar[(Bpr+pad)*h]; + uchar *dst = newarray; + const uchar *src = data; + + for (int i=0; i0; j--) { + uchar b = *src++; + if (bpp==1) { + *dst++ = (uchar)( hiNibble[b&15] ) | ( loNibble[(b>>4)&15] ); + } else if (bpp==4) { + for (int k=(j==1)?shr:4; k>0; k--) { + *dst++ = (uchar)("\377\360\017\000"[b&3]); + b = b >> 2; + } + } else { + for (int k=(j==1)?shr:8; k>0; k--) { + if (b&1) { + *dst++=0; + if (bpp>8) *dst++=0; + if (bpp>16) *dst++=0; + if (bpp>24) *dst++=0; + } else { + *dst++=0xff; + if (bpp>8) *dst++=0xff; + if (bpp>16) *dst++=0xff; + if (bpp>24) *dst++=0xff; + } + + b = b >> 1; + } + } + } + + dst += pad; + } + + bm = CreateBitmap(w, h, np, bpp, newarray); + delete[] newarray; + + return bm; +} + + +void fl_delete_bitmask(Fl_Bitmask bm) { + DeleteObject((HGDIOBJ)bm); +} + + +#else // X11 bitmask functions + + +Fl_Bitmask fl_create_bitmask(int w, int h, const uchar *data) { + return XCreateBitmapFromData(fl_display, fl_window, (const char *)data, + (w+7)&-8, h); +} + +void fl_delete_bitmask(Fl_Bitmask bm) { + fl_delete_offscreen((Fl_Offscreen)bm); +} + + +#endif // __APPLE__ + + +// Create a 1-bit mask used for alpha blending +Fl_Bitmask fl_create_alphamask(int w, int h, int d, int ld, const uchar *array) { + Fl_Bitmask bm; + int bmw = (w + 7) / 8; + uchar *bitmap = new uchar[bmw * h]; + uchar *bitptr, bit; + const uchar *dataptr; + int x, y; + static uchar dither[16][16] = { // Simple 16x16 Floyd dither + { 0, 128, 32, 160, 8, 136, 40, 168, + 2, 130, 34, 162, 10, 138, 42, 170 }, + { 192, 64, 224, 96, 200, 72, 232, 104, + 194, 66, 226, 98, 202, 74, 234, 106 }, + { 48, 176, 16, 144, 56, 184, 24, 152, + 50, 178, 18, 146, 58, 186, 26, 154 }, + { 240, 112, 208, 80, 248, 120, 216, 88, + 242, 114, 210, 82, 250, 122, 218, 90 }, + { 12, 140, 44, 172, 4, 132, 36, 164, + 14, 142, 46, 174, 6, 134, 38, 166 }, + { 204, 76, 236, 108, 196, 68, 228, 100, + 206, 78, 238, 110, 198, 70, 230, 102 }, + { 60, 188, 28, 156, 52, 180, 20, 148, + 62, 190, 30, 158, 54, 182, 22, 150 }, + { 252, 124, 220, 92, 244, 116, 212, 84, + 254, 126, 222, 94, 246, 118, 214, 86 }, + { 3, 131, 35, 163, 11, 139, 43, 171, + 1, 129, 33, 161, 9, 137, 41, 169 }, + { 195, 67, 227, 99, 203, 75, 235, 107, + 193, 65, 225, 97, 201, 73, 233, 105 }, + { 51, 179, 19, 147, 59, 187, 27, 155, + 49, 177, 17, 145, 57, 185, 25, 153 }, + { 243, 115, 211, 83, 251, 123, 219, 91, + 241, 113, 209, 81, 249, 121, 217, 89 }, + { 15, 143, 47, 175, 7, 135, 39, 167, + 13, 141, 45, 173, 5, 133, 37, 165 }, + { 207, 79, 239, 111, 199, 71, 231, 103, + 205, 77, 237, 109, 197, 69, 229, 101 }, + { 63, 191, 31, 159, 55, 183, 23, 151, + 61, 189, 29, 157, 53, 181, 21, 149 }, + { 254, 127, 223, 95, 247, 119, 215, 87, + 253, 125, 221, 93, 245, 117, 213, 85 } + }; + + // Generate a 1-bit "screen door" alpha mask; not always pretty, but + // definitely fast... In the future we may be able to support things + // like the RENDER extension in XFree86, when available, to provide + // true RGBA-blended rendering. See: + // + // http://www.xfree86.org/~keithp/render/protocol.html + // + // for more info on XRender... + // + // MacOS already provides alpha blending support and has its own + // fl_create_alphamask() function... + memset(bitmap, 0, bmw * h); + + for (dataptr = array + d - 1, y = 0; y < h; y ++, dataptr += ld) + for (bitptr = bitmap + y * bmw, bit = 1, x = 0; x < w; x ++, dataptr += d) { + if (*dataptr > dither[x & 15][y & 15]) + *bitptr |= bit; + if (bit < 128) bit <<= 1; + else { + bit = 1; + bitptr ++; + } + } + + bm = fl_create_bitmask(w, h, bitmap); + delete[] bitmap; + + return (bm); +} + +void Fl_Bitmap::draw(int XP, int YP, int WP, int HP, int cx, int cy) { + fl_graphics_driver->draw(this, XP, YP, WP, HP, cx, cy); +} + +static int start(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int w, int h, int &cx, int &cy, + int &X, int &Y, int &W, int &H) +{ + // account for current clip region (faster on Irix): + fl_clip_box(XP,YP,WP,HP,X,Y,W,H); + cx += X-XP; cy += Y-YP; + // clip the box down to the size of image, quit if empty: + if (cx < 0) {W += cx; X -= cx; cx = 0;} + if (cx+W > w) W = w-cx; + if (W <= 0) return 1; + if (cy < 0) {H += cy; Y -= cy; cy = 0;} + if (cy+H > h) H = h-cy; + if (H <= 0) return 1; + return 0; +} + +#ifdef __APPLE__ +void Fl_Quartz_Graphics_Driver::draw(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy) { + int X, Y, W, H; + if (!bm->array) { + bm->draw_empty(XP, YP); + return; + } + if (start(bm, XP, YP, WP, HP, bm->w(), bm->h(), cx, cy, X, Y, W, H)) { + return; + } + if (!bm->id_) bm->id_ = fl_create_bitmask(bm->w(), bm->h(), bm->array); + if (bm->id_ && fl_gc) { + CGRect rect = { { X, Y }, { W, H } }; + Fl_X::q_begin_image(rect, cx, cy, bm->w(), bm->h()); + CGContextDrawImage(fl_gc, rect, (CGImageRef)bm->id_); + Fl_X::q_end_image(); + } +} + +#elif defined(WIN32) +void Fl_GDI_Graphics_Driver::draw(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy) { + int X, Y, W, H; + if (!bm->array) { + bm->draw_empty(XP, YP); + return; + } + if (start(bm, XP, YP, WP, HP, bm->w(), bm->h(), cx, cy, X, Y, W, H)) { + return; + } + if (!bm->id_) bm->id_ = fl_create_bitmap(bm->w(), bm->h(), bm->array); + + typedef BOOL (WINAPI* fl_transp_func) (HDC,int,int,int,int,HDC,int,int,int,int,UINT); + static fl_transp_func fl_TransparentBlt; + HDC tempdc; + int save; + BOOL use_print_algo = false; + if (fl_surface->type() == Fl_Printer::device_type) { + static HMODULE hMod = NULL; + if (!hMod) { + hMod = LoadLibrary("MSIMG32.DLL"); + if (hMod) fl_TransparentBlt = (fl_transp_func)GetProcAddress(hMod, "TransparentBlt"); + } + if (fl_TransparentBlt) use_print_algo = true; + } + if (use_print_algo) { // algorithm for bitmap output to Fl_GDI_Printer + Fl_Offscreen tmp_id = fl_create_offscreen(W, H); + fl_begin_offscreen(tmp_id); + Fl_Color save_c = fl_color(); // save bitmap's desired color + uchar r, g, b; + Fl::get_color(save_c, r, g, b); + r = 255-r; + g = 255-g; + b = 255-b; + Fl_Color background = fl_rgb_color(r, g, b); // a color very different from the bitmap's + fl_color(background); + fl_rectf(0,0,W,H); // use this color as offscreen background + fl_color(save_c); // back to bitmap's color + tempdc = CreateCompatibleDC(fl_gc); + save = SaveDC(tempdc); + SelectObject(tempdc, (HGDIOBJ)bm->id_); + SelectObject(fl_gc, fl_brush()); // use bitmap's desired color + BitBlt(fl_gc, 0, 0, W, H, tempdc, 0, 0, 0xE20746L); // draw bitmap to offscreen + fl_end_offscreen(); // offscreen data is in tmp_id + SelectObject(tempdc, (HGDIOBJ)tmp_id); // use offscreen data + // draw it to printer context with background color as transparent + fl_TransparentBlt(fl_gc, X,Y,W,H, tempdc, cx, cy, bm->w(), bm->h(), RGB(r, g, b) ); + fl_delete_offscreen(tmp_id); + } + else { // algorithm for bitmap output to display + tempdc = CreateCompatibleDC(fl_gc); + save = SaveDC(tempdc); + SelectObject(tempdc, (HGDIOBJ)bm->id_); + SelectObject(fl_gc, fl_brush()); + // secret bitblt code found in old MSWindows reference manual: + BitBlt(fl_gc, X, Y, W, H, tempdc, cx, cy, 0xE20746L); + } + RestoreDC(tempdc, save); + DeleteDC(tempdc); +} + +#else // Xlib +void Fl_Xlib_Graphics_Driver::draw(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy) { + int X, Y, W, H; + if (!bm->array) { + bm->draw_empty(XP, YP); + return; + } + if (start(bm, XP, YP, WP, HP, bm->w(), bm->h(), cx, cy, X, Y, W, H)) { + return; + } + if (!bm->id_) bm->id_ = fl_create_bitmask(bm->w(), bm->h(), bm->array); + + XSetStipple(fl_display, fl_gc, bm->id_); + int ox = X-cx; if (ox < 0) ox += bm->w(); + int oy = Y-cy; if (oy < 0) oy += bm->h(); + XSetTSOrigin(fl_display, fl_gc, ox, oy); + XSetFillStyle(fl_display, fl_gc, FillStippled); + XFillRectangle(fl_display, fl_window, fl_gc, X, Y, W, H); + XSetFillStyle(fl_display, fl_gc, FillSolid); +} +#endif + +/** + The destructor free all memory and server resources that are used by + the bitmap. +*/ +Fl_Bitmap::~Fl_Bitmap() { + uncache(); + if (alloc_array) delete[] (uchar *)array; +} + +void Fl_Bitmap::uncache() { + if (id_) { +#ifdef __APPLE_QUARTZ__ + fl_delete_bitmask((Fl_Bitmask)id_); +#else + fl_delete_bitmask((Fl_Offscreen)id_); +#endif + id_ = 0; + } +} + +void Fl_Bitmap::label(Fl_Widget* widget) { + widget->image(this); +} + +void Fl_Bitmap::label(Fl_Menu_Item* m) { + Fl::set_labeltype(_FL_IMAGE_LABEL, labeltype, measure); + m->label(_FL_IMAGE_LABEL, (const char*)this); +} + +Fl_Image *Fl_Bitmap::copy(int W, int H) { + Fl_Bitmap *new_image; // New RGB image + uchar *new_array; // New array for image data + + // Optimize the simple copy where the width and height are the same... + if (W == w() && H == h()) { + new_array = new uchar [H * ((W + 7) / 8)]; + memcpy(new_array, array, H * ((W + 7) / 8)); + + new_image = new Fl_Bitmap(new_array, W, H); + new_image->alloc_array = 1; + + return new_image; + } + if (W <= 0 || H <= 0) return 0; + + // OK, need to resize the image data; allocate memory and + uchar *new_ptr, // Pointer into new array + new_bit, // Bit for new array + old_bit; // Bit for old array + const uchar *old_ptr; // Pointer into old array + int sx, sy, // Source coordinates + dx, dy, // Destination coordinates + xerr, yerr, // X & Y errors + xmod, ymod, // X & Y moduli + xstep, ystep; // X & Y step increments + + + // Figure out Bresenheim step/modulus values... + xmod = w() % W; + xstep = w() / W; + ymod = h() % H; + ystep = h() / H; + + // Allocate memory for the new image... + new_array = new uchar [H * ((W + 7) / 8)]; + new_image = new Fl_Bitmap(new_array, W, H); + new_image->alloc_array = 1; + + memset(new_array, 0, H * ((W + 7) / 8)); + + // Scale the image using a nearest-neighbor algorithm... + for (dy = H, sy = 0, yerr = H, new_ptr = new_array; dy > 0; dy --) { + for (dx = W, xerr = W, old_ptr = array + sy * ((w() + 7) / 8), sx = 0, new_bit = 1; + dx > 0; + dx --) { + old_bit = (uchar)(1 << (sx & 7)); + if (old_ptr[sx / 8] & old_bit) *new_ptr |= new_bit; + + if (new_bit < 128) new_bit <<= 1; + else { + new_bit = 1; + new_ptr ++; + } + + sx += xstep; + xerr -= xmod; + + if (xerr <= 0) { + xerr += W; + sx ++; + } + } + + if (new_bit > 1) new_ptr ++; + + sy += ystep; + yerr -= ymod; + if (yerr <= 0) { + yerr += H; + sy ++; + } + } + + return new_image; +} + + +// +// End of "$Id: Fl_Bitmap.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Box.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Box.cxx new file mode 100644 index 0000000..9450cf6 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Box.cxx @@ -0,0 +1,44 @@ +// +// "$Id: Fl_Box.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Box widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include + +void Fl_Box::draw() { + draw_box(); + draw_label(); +} + +int Fl_Box::handle(int event) { + if (event == FL_ENTER || event == FL_LEAVE) return 1; + else return 0; +} + + +// +// End of "$Id: Fl_Box.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Browser.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Browser.cxx new file mode 100644 index 0000000..900c888 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Browser.cxx @@ -0,0 +1,919 @@ +// +// "$Id: Fl_Browser.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Browser widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include +#include "flstring.h" +#include +#include + +// I modified this from the original Forms data to use a linked list +// so that the number of items in the browser and size of those items +// is unlimited. The only problem is that the old browser used an +// index number to identify a line, and it is slow to convert from/to +// a pointer. I use a cache of the last match to try to speed this up. + +// Also added the ability to "hide" a line. This sets its height to +// zero, so the Fl_Browser_ cannot pick it. + +#define SELECTED 1 +#define NOTDISPLAYED 2 + +// WARNING: +// Fl_File_Chooser.cxx also has a definition of this structure (FL_BLINE). +// Changes to FL_BLINE *must* be reflected in Fl_File_Chooser.cxx as well. +// This hack in Fl_File_Chooser should be solved. +// +struct FL_BLINE { // data is in a linked list of these + FL_BLINE* prev; + FL_BLINE* next; + void* data; + Fl_Image* icon; + short length; // sizeof(txt)-1, may be longer than string + char flags; // selected, displayed + char txt[1]; // start of allocated array +}; + +/** + Returns the very first item in the list. + Example of use: + \code + // Walk the browser from beginning to end + for ( void *i=item_first(); i; i=item_next(i) ) { + printf("item label='%s'\n", item_text(i)); + } + \endcode + \returns The first item, or NULL if list is empty. + \see item_first(), item_last(), item_next(), item_prev() +*/ +void* Fl_Browser::item_first() const {return first;} + +/** + Returns the next item after \p item. + \param[in] item The 'current' item + \returns The next item after \p item, or NULL if there are none after this one. + \see item_first(), item_last(), item_next(), item_prev() +*/ +void* Fl_Browser::item_next(void* item) const {return ((FL_BLINE*)item)->next;} + +/** + Returns the previous item before \p item. + \param[in] item The 'current' item + \returns The previous item before \p item, or NULL if there none before this one. + \see item_first(), item_last(), item_next(), item_prev() +*/ +void* Fl_Browser::item_prev(void* item) const {return ((FL_BLINE*)item)->prev;} + +/** + Returns the very last item in the list. + Example of use: + \code + // Walk the browser in reverse, from end to start + for ( void *i=item_last(); i; i=item_prev(i) ) { + printf("item label='%s'\n", item_text(i)); + } + \endcode + \returns The last item, or NULL if list is empty. + \see item_first(), item_last(), item_next(), item_prev() +*/ +void* Fl_Browser::item_last() const {return last;} + +/** + See if \p item is selected. + \param[in] item The item whose selection state is to be checked. + \returns 1 if selected, 0 if not. + \see select(), selected(), value(), item_select(), item_selected() +*/ +int Fl_Browser::item_selected(void* item) const { + return ((FL_BLINE*)item)->flags&SELECTED; +} +/** + Change the selection state of \p item to the value \p val. + \param[in] item The item to be changed. + \param[in] val The new selection state: 1 selects, 0 de-selects. + \see select(), selected(), value(), item_select(), item_selected() +*/ +void Fl_Browser::item_select(void *item, int val) { + if (val) ((FL_BLINE*)item)->flags |= SELECTED; + else ((FL_BLINE*)item)->flags &= ~SELECTED; +} + +/** + Returns the label text for \p item. + \param[in] item The item whose label text is returned. + \returns The item's text string. (Can be NULL) +*/ +const char *Fl_Browser::item_text(void *item) const { + return ((FL_BLINE*)item)->txt; +} + +/** + Returns the item for specified \p line. + + Note: This call is slow. It's fine for e.g. responding to user + clicks, but slow if called often, such as in a tight sorting loop. + Finding an item 'by line' involves a linear lookup on the internal + linked list. The performance hit can be significant if the browser's + contents is large, and the method is called often (e.g. during a sort). + If you're writing a subclass, use the protected methods item_first(), + item_next(), etc. to access the internal linked list more efficiently. + + \param[in] line The line number of the item to return. (1 based) + \retval item that was found. + \retval NULL if line is out of range. + \see item_at(), find_line(), lineno() +*/ +FL_BLINE* Fl_Browser::find_line(int line) const { + int n; FL_BLINE* l; + if (line == cacheline) return cache; + if (cacheline && line > (cacheline/2) && line < ((cacheline+lines)/2)) { + n = cacheline; l = cache; + } else if (line <= (lines/2)) { + n = 1; l = first; + } else { + n = lines; l = last; + } + for (; n < line && l; n++) l = l->next; + for (; n > line && l; n--) l = l->prev; + ((Fl_Browser*)this)->cacheline = line; + ((Fl_Browser*)this)->cache = l; + return l; +} + +/** + Returns line number corresponding to \p item, or zero if not found. + Caveat: See efficiency note in find_line(). + \param[in] item The item to be found + \returns The line number of the item, or 0 if not found. + \see item_at(), find_line(), lineno() +*/ +int Fl_Browser::lineno(void *item) const { + FL_BLINE* l = (FL_BLINE*)item; + if (!l) return 0; + if (l == cache) return cacheline; + if (l == first) return 1; + if (l == last) return lines; + if (!cache) { + ((Fl_Browser*)this)->cache = first; + ((Fl_Browser*)this)->cacheline = 1; + } + // assume it is near cache, search both directions: + FL_BLINE* b = cache->prev; + int bnum = cacheline-1; + FL_BLINE* f = cache->next; + int fnum = cacheline+1; + int n = 0; + for (;;) { + if (b == l) {n = bnum; break;} + if (f == l) {n = fnum; break;} + if (b) {b = b->prev; bnum--;} + if (f) {f = f->next; fnum++;} + } + ((Fl_Browser*)this)->cache = l; + ((Fl_Browser*)this)->cacheline = n; + return n; +} + +/** + Removes the item at the specified \p line. + Caveat: See efficiency note in find_line(). + You must call redraw() to make any changes visible. + \param[in] line The line number to be removed. (1 based) Must be in range! + \returns Pointer to browser item that was removed (and is no longer valid). + \see add(), insert(), remove(), swap(int,int), clear() +*/ +FL_BLINE* Fl_Browser::_remove(int line) { + FL_BLINE* ttt = find_line(line); + deleting(ttt); + + cacheline = line-1; + cache = ttt->prev; + lines--; + full_height_ -= item_height(ttt); + if (ttt->prev) ttt->prev->next = ttt->next; + else first = ttt->next; + if (ttt->next) ttt->next->prev = ttt->prev; + else last = ttt->prev; + + return(ttt); +} + +/** + Remove entry for given \p line number, making the browser one line shorter. + You must call redraw() to make any changes visible. + \param[in] line Line to be removed. (1 based) \n + If \p line is out of range, no action is taken. + \see add(), insert(), remove(), swap(int,int), clear() +*/ +void Fl_Browser::remove(int line) { + if (line < 1 || line > lines) return; + free(_remove(line)); +} + +/** + Insert specified \p item above \p line. + If \p line > size() then the line is added to the end. + + Caveat: See efficiency note in find_line(). + + \param[in] line The new line will be inserted above this line (1 based). + \param[in] item The item to be added. +*/ +void Fl_Browser::insert(int line, FL_BLINE* item) { + if (!first) { + item->prev = item->next = 0; + first = last = item; + } else if (line <= 1) { + inserting(first, item); + item->prev = 0; + item->next = first; + item->next->prev = item; + first = item; + } else if (line > lines) { + item->prev = last; + item->prev->next = item; + item->next = 0; + last = item; + } else { + FL_BLINE* n = find_line(line); + inserting(n, item); + item->next = n; + item->prev = n->prev; + item->prev->next = item; + n->prev = item; + } + cacheline = line; + cache = item; + lines++; + full_height_ += item_height(item); + redraw_line(item); +} + +/** + Insert a new entry whose label is \p newtext \e above given \p line, optional data \p d. + + Text may contain format characters; see format_char() for details. + \p newtext is copied using the strdup() function, and can be NULL to make a blank line. + + The optional void * argument \p d will be the data() of the new item. + + \param[in] line Line position for insert. (1 based) \n + If \p line > size(), the entry will be added at the end. + \param[in] newtext The label text for the new line. + \param[in] d Optional pointer to user data to be associated with the new line. +*/ +void Fl_Browser::insert(int line, const char* newtext, void* d) { + int l = strlen(newtext); + FL_BLINE* t = (FL_BLINE*)malloc(sizeof(FL_BLINE)+l); + t->length = (short)l; + t->flags = 0; + strcpy(t->txt, newtext); + t->data = d; + t->icon = 0; + insert(line, t); +} + +/** + Line \p from is removed and reinserted at \p to. + Note: \p to is calculated \e after line \p from gets removed. + \param[in] to Destination line number (calculated \e after line \p from is removed) + \param[in] from Line number of item to be moved +*/ +void Fl_Browser::move(int to, int from) { + if (from < 1 || from > lines) return; + insert(to, _remove(from)); +} + +/** + Sets the text for the specified \p line to \p newtext. + + Text may contain format characters; see format_char() for details. + \p newtext is copied using the strdup() function, and can be NULL to make a blank line. + + Does nothing if \p line is out of range. + + \param[in] line The line of the item whose text will be changed. (1 based) + \param[in] newtext The new string to be assigned to the item. +*/ +void Fl_Browser::text(int line, const char* newtext) { + if (line < 1 || line > lines) return; + FL_BLINE* t = find_line(line); + int l = strlen(newtext); + if (l > t->length) { + FL_BLINE* n = (FL_BLINE*)malloc(sizeof(FL_BLINE)+l); + replacing(t, n); + cache = n; + n->data = t->data; + n->icon = t->icon; + n->length = (short)l; + n->flags = t->flags; + n->prev = t->prev; + if (n->prev) n->prev->next = n; else first = n; + n->next = t->next; + if (n->next) n->next->prev = n; else last = n; + free(t); + t = n; + } + strcpy(t->txt, newtext); + redraw_line(t); +} + +/** + Sets the user data for specified \p line to \p d. + Does nothing if \p line is out of range. + \param[in] line The line of the item whose data() is to be changed. (1 based) + \param[in] d The new data to be assigned to the item. (can be NULL) +*/ +void Fl_Browser::data(int line, void* d) { + if (line < 1 || line > lines) return; + find_line(line)->data = d; +} + +/** + Returns height of \p item in pixels. + This takes into account embedded \@ codes within the text() label. + \param[in] item The item whose height is returned. + \returns The height of the item in pixels. + \see item_height(), item_width(),\n + incr_height(), full_height() +*/ +int Fl_Browser::item_height(void *item) const { + FL_BLINE* l = (FL_BLINE*)item; + if (l->flags & NOTDISPLAYED) return 0; + + int hmax = 2; // use 2 to insure we don't return a zero! + + if (!l->txt[0]) { + // For blank lines set the height to exactly 1 line! + fl_font(textfont(), textsize()); + int hh = fl_height(); + if (hh > hmax) hmax = hh; + } else { + const int* i = column_widths(); + long int dummy; + // do each column separately as they may all set different fonts: + for (char* str = l->txt; str && *str; str++) { + Fl_Font font = textfont(); // default font + int tsize = textsize(); // default size + while (*str==format_char()) { + str++; + switch (*str++) { + case 'l': case 'L': tsize = 24; break; + case 'm': case 'M': tsize = 18; break; + case 's': tsize = 11; break; + case 'b': font = (Fl_Font)(font|FL_BOLD); break; + case 'i': font = (Fl_Font)(font|FL_ITALIC); break; + case 'f': case 't': font = FL_COURIER; break; + case 'B': + case 'C': dummy = strtol(str, &str, 10); break;// skip a color number + case 'F': font = (Fl_Font)strtol(str,&str,10); break; + case 'S': tsize = strtol(str,&str,10); break; + case 0: case '@': str--; + case '.': goto END_FORMAT; + } + } + END_FORMAT: + char* ptr = str; + if (ptr && *i++) str = strchr(str, column_char()); + else str = NULL; + if((!str && *ptr) || (str && ptr < str)) { + fl_font(font, tsize); int hh = fl_height(); + if (hh > hmax) hmax = hh; + } + if (!str || !*str) break; + } + } + + if (l->icon && (l->icon->h()+2)>hmax) { + hmax = l->icon->h() + 2; // leave 2px above/below + } + return hmax; // previous version returned hmax+2! +} + +/** + Returns width of \p item in pixels. + This takes into account embedded \@ codes within the text() label. + \param[in] item The item whose width is returned. + \returns The width of the item in pixels. + \see item_height(), item_width(),\n + incr_height(), full_height() +*/ +int Fl_Browser::item_width(void *item) const { + FL_BLINE* l=(FL_BLINE*)item; + char* str = l->txt; + const int* i = column_widths(); + int ww = 0; + + while (*i) { // add up all tab-separated fields + char* e; + e = strchr(str, column_char()); + if (!e) break; // last one occupied by text + str = e+1; + ww += *i++; + } + + // OK, we gotta parse the string and find the string width... + int tsize = textsize(); + Fl_Font font = textfont(); + int done = 0; + + while (*str == format_char_ && str[1] && str[1] != format_char_) { + long int dummy; + str ++; + switch (*str++) { + case 'l': case 'L': tsize = 24; break; + case 'm': case 'M': tsize = 18; break; + case 's': tsize = 11; break; + case 'b': font = (Fl_Font)(font|FL_BOLD); break; + case 'i': font = (Fl_Font)(font|FL_ITALIC); break; + case 'f': case 't': font = FL_COURIER; break; + case 'B': + case 'C': dummy = strtol(str, &str, 10); break;// skip a color number + case 'F': font = (Fl_Font)strtol(str, &str, 10); break; + case 'S': tsize = strtol(str, &str, 10); break; + case '.': + done = 1; + break; + case '@': + str--; + done = 1; + } + + if (done) + break; + } + + if (*str == format_char_ && str[1]) + str ++; + + if (ww==0 && l->icon) ww = l->icon->w(); + + fl_font(font, tsize); + return ww + int(fl_width(str)) + 6; +} + +/** + The height of the entire list of all visible() items in pixels. + This returns the accumulated height of *all* the items in the browser + that are not hidden with hide(), including items scrolled off screen. + \returns The accumulated size of all the visible items in pixels. + \see item_height(), item_width(),\n + incr_height(), full_height() +*/ +int Fl_Browser::full_height() const { + return full_height_; +} + +/** + The default 'average' item height (including inter-item spacing) in pixels. + This currently returns textsize() + 2. + \returns The value in pixels. + \see item_height(), item_width(),\n + incr_height(), full_height() +*/ +int Fl_Browser::incr_height() const { + return textsize()+2; +} + +/** + Draws \p item at the position specified by \p X \p Y \p W \p H. + The \p W and \p H values are used for clipping. + Should only be called within the context of an FLTK draw(). + \param[in] item The item to be drawn + \param[in] X,Y,W,H position and size. +*/ +void Fl_Browser::item_draw(void* item, int X, int Y, int W, int H) const { + FL_BLINE* l = (FL_BLINE*)item; + char* str = l->txt; + const int* i = column_widths(); + + bool first = true; // for icon + while (W > 6) { // do each tab-separated field + int w1 = W; // width for this field + char* e = 0; // pointer to end of field or null if none + if (*i) { // find end of field and temporarily replace with 0 + e = strchr(str, column_char()); + if (e) {*e = 0; w1 = *i++;} + } + // Icon drawing code + if (first) { + first = false; + if (l->icon) { + l->icon->draw(X+2,Y+1); // leave 2px left, 1px above + int iconw = l->icon->w()+2; + X += iconw; W -= iconw; w1 -= iconw; + } + } + int tsize = textsize(); + Fl_Font font = textfont(); + Fl_Color lcol = textcolor(); + Fl_Align talign = FL_ALIGN_LEFT; + // check for all the @-lines recognized by XForms: + //#if defined(__GNUC__) + //#warning FIXME This maybe needs to be more UTF8 aware now...? + //#endif /*__GNUC__*/ + while (*str == format_char() && *++str && *str != format_char()) { + long int dummy; + switch (*str++) { + case 'l': case 'L': tsize = 24; break; + case 'm': case 'M': tsize = 18; break; + case 's': tsize = 11; break; + case 'b': font = (Fl_Font)(font|FL_BOLD); break; + case 'i': font = (Fl_Font)(font|FL_ITALIC); break; + case 'f': case 't': font = FL_COURIER; break; + case 'c': talign = FL_ALIGN_CENTER; break; + case 'r': talign = FL_ALIGN_RIGHT; break; + case 'B': + if (!(l->flags & SELECTED)) { + fl_color((Fl_Color)strtol(str, &str, 10)); + fl_rectf(X, Y, w1, H); + } else dummy = strtol(str, &str, 10); + break; + case 'C': + lcol = (Fl_Color)strtol(str, &str, 10); + break; + case 'F': + font = (Fl_Font)strtol(str, &str, 10); + break; + case 'N': + lcol = FL_INACTIVE_COLOR; + break; + case 'S': + tsize = strtol(str, &str, 10); + break; + case '-': + fl_color(FL_DARK3); + fl_line(X+3, Y+H/2, X+w1-3, Y+H/2); + fl_color(FL_LIGHT3); + fl_line(X+3, Y+H/2+1, X+w1-3, Y+H/2+1); + break; + case 'u': + case '_': + fl_color(lcol); + fl_line(X+3, Y+H-1, X+w1-3, Y+H-1); + break; + case '.': + goto BREAK; + case '@': + str--; goto BREAK; + } + } + BREAK: + fl_font(font, tsize); + if (l->flags & SELECTED) + lcol = fl_contrast(lcol, selection_color()); + if (!active_r()) lcol = fl_inactive(lcol); + fl_color(lcol); + fl_draw(str, X+3, Y, w1-6, H, e ? Fl_Align(talign|FL_ALIGN_CLIP) : talign, 0, 0); + if (!e) break; // no more fields... + *e = column_char(); // put the separator back + X += w1; + W -= w1; + str = e+1; + } +} + +static const int no_columns[1] = {0}; + +/** + The constructor makes an empty browser. + \param[in] X,Y,W,H position and size. + \param[in] L label string, may be NULL. +*/ +Fl_Browser::Fl_Browser(int X, int Y, int W, int H, const char *L) +: Fl_Browser_(X, Y, W, H, L) { + column_widths_ = no_columns; + lines = 0; + full_height_ = 0; + cacheline = 0; + format_char_ = '@'; + column_char_ = '\t'; + first = last = cache = 0; +} + +/** + Updates the browser so that \p line is shown at position \p pos. + \param[in] line line number. (1 based) + \param[in] pos position. + \see topline(), middleline(), bottomline() +*/ +void Fl_Browser::lineposition(int line, Fl_Line_Position pos) { + if (line<1) line = 1; + if (line>lines) line = lines; + int p = 0; + + FL_BLINE* l; + for (l=first; l && line>1; l = l->next) { + line--; p += item_height(l); + } + if (l && (pos == BOTTOM)) p += item_height (l); + + int final = p, X, Y, W, H; + bbox(X, Y, W, H); + + switch(pos) { + case TOP: break; + case BOTTOM: final -= H; break; + case MIDDLE: final -= H/2; break; + } + + if (final > (full_height() - H)) final = full_height() -H; + position(final); +} + +/** + Returns the line that is currently visible at the top of the browser. + If there is no vertical scrollbar then this will always return 1. + \returns The lineno() of the top() of the browser. +*/ +int Fl_Browser::topline() const { + return lineno(top()); +} + +/** + Removes all the lines in the browser. + \see add(), insert(), remove(), swap(int,int), clear() +*/ +void Fl_Browser::clear() { + for (FL_BLINE* l = first; l;) { + FL_BLINE* n = l->next; + free(l); + l = n; + } + full_height_ = 0; + first = 0; + last = 0; + lines = 0; + new_list(); +} + +/** + Adds a new line to the end of the browser. + + The text string \p newtext may contain format characters; see format_char() for details. + \p newtext is copied using the strdup() function, and can be NULL to make a blank line. + + The optional void* argument \p d will be the data() for the new item. + + \param[in] newtext The label text used for the added item + \param[in] d Optional user data() for the item (0 if unspecified) + \see add(), insert(), remove(), swap(int,int), clear() +*/ +void Fl_Browser::add(const char* newtext, void* d) { + insert(lines+1, newtext, d); + //Fl_Browser_::display(last); +} + +/** + Returns the label text for the specified \p line. + Return value can be NULL if \p line is out of range or unset. + The parameter \p line is 1 based. + \param[in] line The line number of the item whose text is returned. (1 based) + \returns The text string (can be NULL) +*/ +const char* Fl_Browser::text(int line) const { + if (line < 1 || line > lines) return 0; + return find_line(line)->txt; +} + +/** + Returns the user data() for specified \p line. + Return value can be NULL if \p line is out of range or no user data() was defined. + The parameter \p line is 1 based (1 will be the first item in the list). + \param[in] line The line number of the item whose data() is returned. (1 based) + \returns The user data pointer (can be NULL) + +*/ +void* Fl_Browser::data(int line) const { + if (line < 1 || line > lines) return 0; + return find_line(line)->data; +} + +/** + Sets the selection state of the item at \p line to the value \p val. + If \p val is not specified, the default is 1 (selects the item). + \param[in] line The line number of the item to be changed. (1 based) + \param[in] val The new selection state (1=select, 0=de-select). + \returns 1 if the state changed, 0 if not. + \see select(), selected(), value(), item_select(), item_selected() +*/ +int Fl_Browser::select(int line, int val) { + if (line < 1 || line > lines) return 0; + return Fl_Browser_::select(find_line(line), val); +} + +/** + Returns 1 if specified \p line is selected, 0 if not. + \param[in] line The line being checked (1 based) + \returns 1 if item selected, 0 if not. + \see select(), selected(), value(), item_select(), item_selected() + */ +int Fl_Browser::selected(int line) const { + if (line < 1 || line > lines) return 0; + return find_line(line)->flags & SELECTED; +} + +/** + Makes \p line visible, and available for selection by user. + Opposite of hide(int). + This changes the full_height() if the state was changed. + redraw() is called automatically if a change occurred. + \param[in] line The line to be shown. (1 based) + \see show(int), hide(int), display(), visible(), make_visible() +*/ +void Fl_Browser::show(int line) { + FL_BLINE* t = find_line(line); + if (t->flags & NOTDISPLAYED) { + t->flags &= ~NOTDISPLAYED; + full_height_ += item_height(t); + if (Fl_Browser_::displayed(t)) redraw(); + } +} + +/** + Makes \p line invisible, preventing selection by the user. + The line can still be selected under program control. + This changes the full_height() if the state was changed. + When a line is made invisible, lines below it are moved up in the display. + redraw() is called automatically if a change occurred. + \param[in] line The line to be hidden. (1 based) + \see show(int), hide(int), display(), visible(), make_visible() +*/ +void Fl_Browser::hide(int line) { + FL_BLINE* t = find_line(line); + if (!(t->flags & NOTDISPLAYED)) { + full_height_ -= item_height(t); + t->flags |= NOTDISPLAYED; + if (Fl_Browser_::displayed(t)) redraw(); + } +} + +/** + For back compatibility. + This calls show(line) if \p val is true, and hide(line) otherwise. + If \p val is not specified, the default is 1 (makes the line visible). + \see show(int), hide(int), display(), visible(), make_visible() +*/ +void Fl_Browser::display(int line, int val) { + if (line < 1 || line > lines) return; + if (val) show(line); else hide(line); +} + +/** + Returns non-zero if the specified \p line is visible, 0 if hidden. + Use show(int), hide(int), or make_visible(int) to change an item's visible state. + \param[in] line The line in the browser to be tested. (1 based) + \see show(int), hide(int), display(), visible(), make_visible() +*/ +int Fl_Browser::visible(int line) const { + if (line < 1 || line > lines) return 0; + return !(find_line(line)->flags&NOTDISPLAYED); +} + +/** + Returns the line number of the currently selected line, or 0 if none. + \returns The line number of current selection, or 0 if none selected. + \see select(), selected(), value(), item_select(), item_selected() +*/ +int Fl_Browser::value() const { + return lineno(selection()); +} + +/** + Swap the two items \p a and \p b. + Uses swapping() to ensure list updates correctly. + \param[in] a,b The two items to be swapped. + \see swap(int,int), item_swap() +*/ +void Fl_Browser::swap(FL_BLINE *a, FL_BLINE *b) { + + if ( a == b || !a || !b) return; // nothing to do + swapping(a, b); + FL_BLINE *aprev = a->prev; + FL_BLINE *anext = a->next; + FL_BLINE *bprev = b->prev; + FL_BLINE *bnext = b->next; + if ( b->prev == a ) { // A ADJACENT TO B + if ( aprev ) aprev->next = b; else first = b; + b->next = a; + a->next = bnext; + b->prev = aprev; + a->prev = b; + if ( bnext ) bnext->prev = a; else last = a; + } else if ( a->prev == b ) { // B ADJACENT TO A + if ( bprev ) bprev->next = a; else first = a; + a->next = b; + b->next = anext; + a->prev = bprev; + b->prev = a; + if ( anext ) anext->prev = b; else last = b; + } else { // A AND B NOT ADJACENT + // handle prev's + b->prev = aprev; + if ( anext ) anext->prev = b; else last = b; + a->prev = bprev; + if ( bnext ) bnext->prev = a; else last = a; + // handle next's + if ( aprev ) aprev->next = b; else first = b; + b->next = anext; + if ( bprev ) bprev->next = a; else first = a; + a->next = bnext; + } + // Disable cache -- we played around with positions + cacheline = 0; + cache = 0; +} + +/** + Swaps two browser lines \p a and \p b. + You must call redraw() to make any changes visible. + \param[in] a,b The two lines to be swapped. (both 1 based) + \see swap(int,int), item_swap() +*/ +void Fl_Browser::swap(int a, int b) { + if (a < 1 || a > lines || b < 1 || b > lines) return; + FL_BLINE* ai = find_line(a); + FL_BLINE* bi = find_line(b); + swap(ai,bi); +} + +/** + Set the image icon for \p line to the value \p icon. + Caller is responsible for keeping the icon allocated. + The \p line is automatically redrawn. + \param[in] line The line to be modified. If out of range, nothing is done. + \param[in] icon The image icon to be assigned to the \p line. + If NULL, any previous icon is removed. +*/ +void Fl_Browser::icon(int line, Fl_Image* icon) { + + if (line<1 || line > lines) return; + + FL_BLINE* bl = find_line(line); + + int old_h = bl->icon ? bl->icon->h()+2 : 0; // init with *old* icon height + bl->icon = 0; // remove icon, if any + int th = item_height(bl); // height of text only + int new_h = icon ? icon->h()+2 : 0; // init with *new* icon height + if (th > old_h) old_h = th; + if (th > new_h) new_h = th; + int dh = new_h - old_h; + full_height_ += dh; // do this *always* + + bl->icon = icon; // set new icon + if (dh>0) { + redraw(); // icon larger than item? must redraw widget + } else { + redraw_line(bl); // icon same or smaller? can redraw just this line + } + replacing(bl,bl); // recalc Fl_Browser_::max_width et al +} + +/** + Returns the icon currently defined for \p line. + If no icon is defined, NULL is returned. + \param[in] line The line whose icon is returned. + \returns The icon defined, or NULL if none. +*/ +Fl_Image* Fl_Browser::icon(int line) const { + FL_BLINE* l = find_line(line); + return(l ? l->icon : NULL); +} + +/** + Removes the icon for \p line. + It's ok to remove an icon if none has been defined. + \param[in] line The line whose icon is to be removed. +*/ +void Fl_Browser::remove_icon(int line) { + icon(line,0); +} + +// +// End of "$Id: Fl_Browser.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Browser_.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Browser_.cxx new file mode 100644 index 0000000..1f738b1 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Browser_.cxx @@ -0,0 +1,1107 @@ +// +// "$Id: Fl_Browser_.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Base Browser widget class for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#define DISPLAY_SEARCH_BOTH_WAYS_AT_ONCE + +#include +#include +#include +#include +#include + + +// This is the base class for browsers. To be useful it must be +// subclassed and several virtual functions defined. The +// Forms-compatible browser and the file chooser's browser are +// subclassed off of this. + +// Yes, I know this should be a template... + +// This has been designed so that the subclass has complete control +// over the storage of the data, although because next() and prev() +// functions are used to index, it works best as a linked list or as a +// large block of characters in which the line breaks must be searched +// for. + +// A great deal of work has been done so that the "height" of a data +// object does not need to be determined until it is drawn. This was +// done for the file chooser, because the height requires doing stat() +// to see if the file is a directory, which can be annoyingly slow +// over the network. + +/* redraw bits: + 1 = redraw children (the scrollbar) + 2 = redraw one or two items + 4 = redraw all items +*/ + +static void scrollbar_callback(Fl_Widget* s, void*) { + ((Fl_Browser_*)(s->parent()))->position(int(((Fl_Scrollbar*)s)->value())); +} + +static void hscrollbar_callback(Fl_Widget* s, void*) { + ((Fl_Browser_*)(s->parent()))->hposition(int(((Fl_Scrollbar*)s)->value())); +} + +// return where to draw the actual box: +/** + Returns the bounding box for the interior of the list's display window, inside + the scrollbars. + \param[out] X,Y,W,H The returned bounding box.\n + (The original contents of these parameters are overwritten) +*/ +void Fl_Browser_::bbox(int& X, int& Y, int& W, int& H) const { + int scrollsize = scrollbar_size_ ? scrollbar_size_ : Fl::scrollbar_size(); + Fl_Boxtype b = box() ? box() : FL_DOWN_BOX; + X = x()+Fl::box_dx(b); + Y = y()+Fl::box_dy(b); + W = w()-Fl::box_dw(b); + H = h()-Fl::box_dh(b); + if (scrollbar.visible()) { + W -= scrollsize; + if (scrollbar.align() & FL_ALIGN_LEFT) X += scrollsize; + } + if (W < 0) W = 0; + if (hscrollbar.visible()) { + H -= scrollsize; + if (scrollbar.align() & FL_ALIGN_TOP) Y += scrollsize; + } + if (H < 0) H = 0; +} + +/** + This method returns the X position of the left edge of the list area + after adjusting for the scrollbar and border, if any. + \returns The X position of the left edge of the list, in pixels. + \see Fl_Browser_::bbox() +*/ +int Fl_Browser_::leftedge() const { + int X, Y, W, H; bbox(X, Y, W, H); + return X; +} + +// The scrollbars may be moved again by draw(), since each one's size +// depends on whether the other is visible or not. This skips over +// Fl_Group::resize since it moves the scrollbars uselessly. +/** + Repositions and/or resizes the browser. + \param[in] X,Y,W,H The new position and size for the browser, in pixels. +*/ +void Fl_Browser_::resize(int X, int Y, int W, int H) { + int scrollsize = scrollbar_size_ ? scrollbar_size_ : Fl::scrollbar_size(); + Fl_Widget::resize(X, Y, W, H); + // move the scrollbars so they can respond to events: + bbox(X,Y,W,H); + scrollbar.resize( + scrollbar.align()&FL_ALIGN_LEFT ? X-scrollsize : X+W, + Y, scrollsize, H); + hscrollbar.resize( + X, scrollbar.align()&FL_ALIGN_TOP ? Y-scrollsize : Y+H, + W, scrollsize); +} + +// Cause minimal update to redraw the given item: +/** + This method should be called when the contents of \p item has changed, + but not its height. + \param[in] item The item that needs to be redrawn. + \see redraw_lines(), redraw_line() +*/ +void Fl_Browser_::redraw_line(void* item) { + if (!redraw1 || redraw1 == item) {redraw1 = item; damage(FL_DAMAGE_EXPOSE);} + else if (!redraw2 || redraw2 == item) {redraw2 = item; damage(FL_DAMAGE_EXPOSE);} + else damage(FL_DAMAGE_SCROLL); +} + +// Figure out top() based on position(): +void Fl_Browser_::update_top() { + if (!top_) top_ = item_first(); + if (position_ != real_position_) { + void* l; + int ly; + int yy = position_; + // start from either head or current position, whichever is closer: + if (!top_ || yy <= (real_position_/2)) { + l = item_first(); + ly = 0; + } else { + l = top_; + ly = real_position_-offset_; + } + if (!l) { + top_ = 0; + offset_ = 0; + real_position_ = 0; + } else { + int hh = item_quick_height(l); + // step through list until we find line containing this point: + while (ly > yy) { + void* l1 = item_prev(l); + if (!l1) {ly = 0; break;} // hit the top + l = l1; + hh = item_quick_height(l); + ly -= hh; + } + while ((ly+hh) <= yy) { + void* l1 = item_next(l); + if (!l1) {yy = ly+hh-1; break;} + l = l1; + ly += hh; + hh = item_quick_height(l); + } + // top item must *really* be visible, use slow height: + for (;;) { + hh = item_height(l); + if ((ly+hh) > yy) break; // it is big enough to see + // go up to top of previous item: + void* l1 = item_prev(l); + if (!l1) {ly = yy = 0; break;} // hit the top + l = l1; yy = position_ = ly = ly-item_quick_height(l); + } + // use it: + top_ = l; + offset_ = yy-ly; + real_position_ = yy; + } + damage(FL_DAMAGE_SCROLL); + } +} + +// Change position(), top() will update when update_top() is called +// (probably by draw() or handle()): +/** + Sets the vertical scroll position of the list to pixel position \p pos. + The position is how many pixels of the list are scrolled off the top edge + of the screen. Example: A position of '3' scrolls the top three pixels of + the list off the top edge of the screen. + \param[in] pos The vertical position (in pixels) to scroll the browser to. + \see position(), hposition() +*/ +void Fl_Browser_::position(int pos) { + if (pos < 0) pos = 0; + if (pos == position_) return; + position_ = pos; + if (pos != real_position_) redraw_lines(); +} + +/** + Sets the horizontal scroll position of the list to pixel position \p pos. + The position is how many pixels of the list are scrolled off the left edge + of the screen. Example: A position of '18' scrolls the left 18 pixels of the list + off the left edge of the screen. + \param[in] pos The horizontal position (in pixels) to scroll the browser to. + \see position(), hposition() +*/ +void Fl_Browser_::hposition(int pos) { + if (pos < 0) pos = 0; + if (pos == hposition_) return; + hposition_ = pos; + if (pos != real_hposition_) redraw_lines(); +} + +// Tell whether item is currently displayed: +/** + Returns non-zero if \p item has been scrolled to a position where it is being displayed. + Checks to see if the item's vertical position is within the top and bottom + edges of the display window. This does NOT take into account the hide()/show() + status of the widget or item. + \param[in] item The item to check + \returns 1 if visible, 0 if not visible. + \see display(), displayed() +*/ +int Fl_Browser_::displayed(void* item) const { + int X, Y, W, H; bbox(X, Y, W, H); + int yy = H+offset_; + for (void* l = top_; l && yy > 0; l = item_next(l)) { + if (l == item) return 1; + yy -= item_height(l); + } + return 0; +} + +// Ensure this item is displayed: +// Messy because we have no idea if it is before top or after bottom: +/** + Displays the \p item, scrolling the list as necessary. + \param[in] item The item to be displayed. + \see display(), displayed() +*/ +void Fl_Browser_::display(void* item) { + + // First special case - want to display first item in the list? + update_top(); + if (item == item_first()) {position(0); return;} + + int X, Y, W, H, Yp; bbox(X, Y, W, H); + void* l = top_; + Y = Yp = -offset_; + int h1; + + // 2nd special case - want to display item already displayed at top of browser? + if (l == item) {position(real_position_+Y); return;} // scroll up a bit + + // 3rd special case - want to display item just above top of browser? + void* lp = item_prev(l); + if (lp == item) {position(real_position_+Y-item_quick_height(lp)); return;} + +#ifdef DISPLAY_SEARCH_BOTH_WAYS_AT_ONCE + // search for item. We search both up and down the list at the same time, + // this evens up the execution time for the two cases - the old way was + // much slower for going up than for going down. + while (l || lp) { + if (l) { + h1 = item_quick_height(l); + if (l == item) { + if (Y <= H) { // it is visible or right at bottom + Y = Y+h1-H; // find where bottom edge is + if (Y > 0) position(real_position_+Y); // scroll down a bit + } else { + position(real_position_+Y-(H-h1)/2); // center it + } + return; + } + Y += h1; + l = item_next(l); + } + if (lp) { + h1 = item_quick_height(lp); + Yp -= h1; + if (lp == item) { + if ((Yp + h1) >= 0) position(real_position_+Yp); + else position(real_position_+Yp-(H-h1)/2); + return; + } + lp = item_prev(lp); + } + } +#else + // Old version went forwards and then backwards: + // search forward for it: + l = top_; + for (; l; l = item_next(l)) { + h1 = item_quick_height(l); + if (l == item) { + if (Y <= H) { // it is visible or right at bottom + Y = Y+h1-H; // find where bottom edge is + if (Y > 0) position(real_position_+Y); // scroll down a bit + } else { + position(real_position_+Y-(H-h1)/2); // center it + } + return; + } + Y += h1; + } + // search backward for it, if found center it: + l = lp; + Y = -offset_; + for (; l; l = item_prev(l)) { + h1 = item_quick_height(l); + Y -= h1; + if (l == item) { + if ((Y + h1) >= 0) position(real_position_+Y); + else position(real_position_+Y-(H-h1)/2); + return; + } + } +#endif +} + +// redraw, has side effect of updating top and setting scrollbar: +/** + Draws the list within the normal widget bounding box. +*/ +void Fl_Browser_::draw() { + int drawsquare = 0; + update_top(); + int full_width_ = full_width(); + int full_height_ = full_height(); + int X, Y, W, H; bbox(X, Y, W, H); + int dont_repeat = 0; +J1: + if (damage() & FL_DAMAGE_ALL) { // redraw the box if full redraw + Fl_Boxtype b = box() ? box() : FL_DOWN_BOX; + draw_box(b, x(), y(), w(), h(), color()); + drawsquare = 1; + } + // see if scrollbar needs to be switched on/off: + if ((has_scrollbar_ & VERTICAL) && ( + (has_scrollbar_ & ALWAYS_ON) || position_ || full_height_ > H)) { + if (!scrollbar.visible()) { + scrollbar.set_visible(); + drawsquare = 1; + bbox(X, Y, W, H); + } + } else { + top_ = item_first(); real_position_ = offset_ = 0; + if (scrollbar.visible()) { + scrollbar.clear_visible(); + clear_damage((uchar)(damage()|FL_DAMAGE_SCROLL)); + } + } + + if ((has_scrollbar_ & HORIZONTAL) && ( + (has_scrollbar_ & ALWAYS_ON) || hposition_ || full_width_ > W)) { + if (!hscrollbar.visible()) { + hscrollbar.set_visible(); + drawsquare = 1; + bbox(X, Y, W, H); + } + } else { + real_hposition_ = 0; + if (hscrollbar.visible()) { + hscrollbar.clear_visible(); + clear_damage((uchar)(damage()|FL_DAMAGE_SCROLL)); + } + } + + // Check the vertical scrollbar again, just in case it needs to be drawn + // because the horizontal one is drawn. There should be a cleaner way + // to do this besides copying the same code... + if ((has_scrollbar_ & VERTICAL) && ( + (has_scrollbar_ & ALWAYS_ON) || position_ || full_height_ > H)) { + if (!scrollbar.visible()) { + scrollbar.set_visible(); + drawsquare = 1; + bbox(X, Y, W, H); + } + } else { + top_ = item_first(); real_position_ = offset_ = 0; + if (scrollbar.visible()) { + scrollbar.clear_visible(); + clear_damage((uchar)(damage()|FL_DAMAGE_SCROLL)); + } + } + + bbox(X, Y, W, H); + + fl_push_clip(X, Y, W, H); + // for each line, draw it if full redraw or scrolled. Erase background + // if not a full redraw or if it is selected: + void* l = top(); + int yy = -offset_; + for (; l && yy < H; l = item_next(l)) { + int hh = item_height(l); + if (hh <= 0) continue; + if ((damage()&(FL_DAMAGE_SCROLL|FL_DAMAGE_ALL)) || l == redraw1 || l == redraw2) { + if (item_selected(l)) { + fl_color(active_r() ? selection_color() : fl_inactive(selection_color())); + fl_rectf(X, yy+Y, W, hh); + } else if (!(damage()&FL_DAMAGE_ALL)) { + fl_push_clip(X, yy+Y, W, hh); + draw_box(box() ? box() : FL_DOWN_BOX, x(), y(), w(), h(), color()); + fl_pop_clip(); + } + item_draw(l, X-hposition_, yy+Y, W+hposition_, hh); + if (l == selection_ && Fl::focus() == this) { + draw_box(FL_BORDER_FRAME, X, yy+Y, W, hh, color()); + draw_focus(FL_NO_BOX, X, yy+Y, W+1, hh+1); + } + int ww = item_width(l); + if (ww > max_width) {max_width = ww; max_width_item = l;} + } + yy += hh; + } + // erase the area below last line: + if (!(damage()&FL_DAMAGE_ALL) && yy < H) { + fl_push_clip(X, yy+Y, W, H-yy); + draw_box(box() ? box() : FL_DOWN_BOX, x(), y(), w(), h(), color()); + fl_pop_clip(); + } + fl_pop_clip(); + redraw1 = redraw2 = 0; + + if (!dont_repeat) { + dont_repeat = 1; + // see if changes to full_height caused by calls to slow_height + // caused scrollbar state to change, in which case we have to redraw: + full_height_ = full_height(); + full_width_ = full_width(); + if ((has_scrollbar_ & VERTICAL) && + ((has_scrollbar_ & ALWAYS_ON) || position_ || full_height_>H)) { + if (!scrollbar.visible()) { damage(FL_DAMAGE_ALL); goto J1; } + } else { + if (scrollbar.visible()) { damage(FL_DAMAGE_ALL); goto J1; } + } + if ((has_scrollbar_ & HORIZONTAL) && + ((has_scrollbar_ & ALWAYS_ON) || hposition_ || full_width_>W)) { + if (!hscrollbar.visible()) { damage(FL_DAMAGE_ALL); goto J1; } + } else { + if (hscrollbar.visible()) { damage(FL_DAMAGE_ALL); goto J1; } + } + } + + // update the scrollbars and redraw them: + int scrollsize = scrollbar_size_ ? scrollbar_size_ : Fl::scrollbar_size(); + int dy = top_ ? item_quick_height(top_) : 0; if (dy < 10) dy = 10; + if (scrollbar.visible()) { + scrollbar.damage_resize( + scrollbar.align()&FL_ALIGN_LEFT ? X-scrollsize : X+W, + Y, scrollsize, H); + scrollbar.value(position_, H, 0, full_height_); + scrollbar.linesize(dy); + if (drawsquare) draw_child(scrollbar); + else update_child(scrollbar); + } + if (hscrollbar.visible()) { + hscrollbar.damage_resize( + X, scrollbar.align()&FL_ALIGN_TOP ? Y-scrollsize : Y+H, + W, scrollsize); + hscrollbar.value(hposition_, W, 0, full_width_); + hscrollbar.linesize(dy); + if (drawsquare) draw_child(hscrollbar); + else update_child(hscrollbar); + } + + // draw that little square between the scrollbars: + if (drawsquare && scrollbar.visible() && hscrollbar.visible()) { + fl_color(parent()->color()); + fl_rectf(scrollbar.x(), hscrollbar.y(), scrollsize, scrollsize); + } + + real_hposition_ = hposition_; +} + +// Quick way to delete and reset everything: +/** + This method should be called when the list data is completely replaced + or cleared. It informs the Fl_Browser_ widget that any cached + information it has concerning the items is invalid. + This method does not clear the list, it just handles the follow up + bookkeeping after the list has been cleared. +*/ +void Fl_Browser_::new_list() { + top_ = 0; + position_ = real_position_ = 0; + hposition_ = real_hposition_ = 0; + selection_ = 0; + offset_ = 0; + max_width = 0; + max_width_item = 0; + redraw_lines(); +} + +// Tell it that this item is going away, and that this must remove +// all pointers to it: +/** + This method should be used when \p item is being deleted from the list. + It allows the Fl_Browser_ to discard any cached data it has on the item. + This method does not actually delete the item, but handles the follow up + bookkeeping after the item has just been deleted. + \param[in] item The item being deleted. +*/ +void Fl_Browser_::deleting(void* item) { + if (displayed(item)) { + redraw_lines(); + if (item == top_) { + real_position_ -= offset_; + offset_ = 0; + top_ = item_next(item); + if (!top_) top_ = item_prev(item); + } + } else { + // we don't know where this item is, recalculate top... + real_position_ = 0; + offset_ = 0; + top_ = 0; + } + if (item == selection_) selection_ = 0; + if (item == max_width_item) {max_width_item = 0; max_width = 0;} +} + +/** + This method should be used when item \p a is being replaced by item \p b. + It allows the Fl_Browser_ to update its cache data as needed, + schedules a redraw for the item being changed, and tries to maintain the selection. + This method does not actually replace the item, but handles the follow up + bookkeeping after the item has just been replaced. + \param[in] a Item being replaced + \param[in] b Item to replace 'a' +*/ +void Fl_Browser_::replacing(void* a, void* b) { + redraw_line(a); + if (a == selection_) selection_ = b; + if (a == top_) top_ = b; + if (a == max_width_item) {max_width_item = 0; max_width = 0;} +} + +/** + This method should be used when two items \p a and \p b are being swapped. + It allows the Fl_Browser_ to update its cache data as needed, + schedules a redraw for the two items, and tries to maintain the current selection. + This method does not actually swap items, but handles the follow up + bookkeeping after items have been swapped. + \param[in] a,b Items being swapped. +*/ +void Fl_Browser_::swapping(void* a, void* b) { + redraw_line(a); + redraw_line(b); + if (a == selection_) selection_ = b; + else if (b == selection_) selection_ = a; + if (a == top_) top_ = b; + else if (b == top_) top_ = a; +} + +/** + This method should be used when an item is in the process of + being inserted into the list. + It allows the Fl_Browser_ to update its cache data as needed, + scheduling a redraw for the affected lines. + This method does not actually insert items, but handles the + follow up bookkeeping after items have been inserted. + \param[in] a The starting item position + \param[in] b The new item being inserted +*/ +void Fl_Browser_::inserting(void* a, void* b) { + if (displayed(a)) redraw_lines(); + if (a == top_) top_ = b; +} + +/** + This method returns the item under mouse y position \p ypos. + NULL is returned if no item is displayed at that position. + \param[in] ypos The y position (eg. Fl::event_y()) to find an item under. + \returns The item, or NULL if not found +*/ +void* Fl_Browser_::find_item(int ypos) { + update_top(); + int X, Y, W, H; bbox(X, Y, W, H); + int yy = Y-offset_; + for (void *l = top_; l; l = item_next(l)) { + int hh = item_height(l); if (hh <= 0) continue; + yy += hh; + if (ypos <= yy || yy>=(Y+H)) return l; + } + return 0; +} + +/** + Sets the selection state of \p item to \p val, + and returns 1 if the state changed or 0 if it did not. + + If \p docallbacks is non-zero, select tries to call + the callback function for the widget. + + \param[in] item The item whose selection state is to be changed + \param[in] val The new selection state (1=select, 0=de-select) + \param[in] docallbacks If 1, invokes widget callback if item changed.\n + If 0, doesn't do callback (default). + \returns 1 if state was changed, 0 if not. +*/ +int Fl_Browser_::select(void* item, int val, int docallbacks) { + if (type() == FL_MULTI_BROWSER) { + if (selection_ != item) { + if (selection_) redraw_line(selection_); + selection_ = item; + redraw_line(item); + } + if ((!val)==(!item_selected(item))) return 0; + item_select(item, val); + redraw_line(item); + } else { + if (val && selection_ == item) return 0; + if (!val && selection_ != item) return 0; + if (selection_) { + item_select(selection_, 0); + redraw_line(selection_); + selection_ = 0; + } + if (val) { + item_select(item, 1); + selection_ = item; + redraw_line(item); + display(item); + } + } + if (docallbacks) { + set_changed(); + do_callback(); + } + return 1; +} + +/** + Deselects all items in the list and returns 1 if the state changed + or 0 if it did not. + + If the optional \p docallbacks parameter is non-zero, deselect tries + to call the callback function for the widget. + + \param[in] docallbacks If 1, invokes widget callback if item changed.\n + If 0, doesn't do callback (default). +*/ +int Fl_Browser_::deselect(int docallbacks) { + if (type() == FL_MULTI_BROWSER) { + int change = 0; + for (void* p = item_first(); p; p = item_next(p)) + change |= select(p, 0, docallbacks); + return change; + } else { + if (!selection_) return 0; + item_select(selection_, 0); + redraw_line(selection_); + selection_ = 0; + return 1; + } +} + +/** + Selects \p item and returns 1 if the state changed or 0 if it did not. + Any other items in the list are deselected. + \param[in] item The \p item to select. + \param[in] docallbacks If 1, invokes widget callback if item changed.\n + If 0, doesn't do callback (default). +*/ +int Fl_Browser_::select_only(void* item, int docallbacks) { + if (!item) return deselect(docallbacks); + int change = 0; + Fl_Widget_Tracker wp(this); + if (type() == FL_MULTI_BROWSER) { + for (void* p = item_first(); p; p = item_next(p)) { + if (p != item) change |= select(p, 0, docallbacks); + if (wp.deleted()) return change; + } + } + change |= select(item, 1, docallbacks); + if (wp.deleted()) return change; + display(item); + return change; +} + +/** + Handles the \p event within the normal widget bounding box. + \param[in] event The event to process. + \returns 1 if event was processed, 0 if not. +*/ +int Fl_Browser_::handle(int event) { + + // NOTE: + // We use Fl_Widget_Tracker to test if the user has deleted + // this widget in a callback. Callbacks can be called by: + // - do_callback() + // - select() + // - select_only() + // - deselect() + // Thus we must test wp.deleted() after each of these calls, + // unless we return directly after one of these. + // If wp.deleted() is true, we return 1 because we used the event. + + Fl_Widget_Tracker wp(this); + + // must do shortcuts first or the scrollbar will get them... + if (event == FL_ENTER || event == FL_LEAVE) return 1; + if (event == FL_KEYBOARD && type() >= FL_HOLD_BROWSER) { + void* l1 = selection_; + void* l = l1; if (!l) l = top_; if (!l) l = item_first(); + if (l) { + if (type()==FL_HOLD_BROWSER) { + switch (Fl::event_key()) { + case FL_Down: + while ((l = item_next(l))) + if (item_height(l)>0) {select_only(l, when()); break;} + return 1; + case FL_Up: + while ((l = item_prev(l))) { + if (item_height(l)>0) { + select_only(l, when()); + break; // no need to test wp (return 1) + } + } + return 1; + } + } else { + switch (Fl::event_key()) { + case FL_Enter: + case FL_KP_Enter: + select_only(l, when() & ~FL_WHEN_ENTER_KEY); + if (wp.deleted()) return 1; + if (when() & FL_WHEN_ENTER_KEY) { + set_changed(); + do_callback(); + } + return 1; + case ' ': + selection_ = l; + select(l, !item_selected(l), when() & ~FL_WHEN_ENTER_KEY); + return 1; + case FL_Down: + while ((l = item_next(l))) { + if (Fl::event_state(FL_SHIFT|FL_CTRL)) + select(l, l1 ? item_selected(l1) : 1, when()); + if (wp.deleted()) return 1; + if (item_height(l)>0) goto J1; + } + return 1; + case FL_Up: + while ((l = item_prev(l))) { + if (Fl::event_state(FL_SHIFT|FL_CTRL)) + select(l, l1 ? item_selected(l1) : 1, when()); + if (wp.deleted()) return 1; + if (item_height(l)>0) goto J1; + } + return 1; +J1: + if (selection_) redraw_line(selection_); + selection_ = l; redraw_line(l); + display(l); + return 1; + } + } + } + } + + if (Fl_Group::handle(event)) return 1; + if (wp.deleted()) return 1; + + int X, Y, W, H; bbox(X, Y, W, H); + int my; +// NOTE: +// instead of: +// change = select_only(find_item(my), when() & FL_WHEN_CHANGED) +// we use the construct: +// change = select_only(find_item(my), 0); +// if (change && (when() & FL_WHEN_CHANGED)) { +// set_changed(); +// do_callback(); +// } +// See str #834 +// The first form calls the callback *before* setting change. +// The callback may execute an Fl::wait(), resulting in another +// call of Fl_Browser_::handle() for the same widget. The sequence +// of events can be an FL_PUSH followed by an FL_RELEASE. +// This second call of Fl_Browser_::handle() may result in a - +// somewhat unexpected - second concurrent invocation of the callback. + + static char change; + static char whichway; + static int py; + switch (event) { + case FL_PUSH: + if (!Fl::event_inside(X, Y, W, H)) return 0; + if (Fl::visible_focus()) { + Fl::focus(this); + redraw(); + } + my = py = Fl::event_y(); + change = 0; + if (type() == FL_NORMAL_BROWSER || !top_) + ; + else if (type() != FL_MULTI_BROWSER) { + change = select_only(find_item(my), 0); + if (wp.deleted()) return 1; + if (change && (when() & FL_WHEN_CHANGED)) { + set_changed(); + do_callback(); + if (wp.deleted()) return 1; + } + } else { + void* l = find_item(my); + whichway = 1; + if (Fl::event_state(FL_CTRL)) { // toggle selection: + TOGGLE: + if (l) { + whichway = !item_selected(l); + change = select(l, whichway, 0); + if (wp.deleted()) return 1; + if (change && (when() & FL_WHEN_CHANGED)) { + set_changed(); + do_callback(); + if (wp.deleted()) return 1; + } + } + } else if (Fl::event_state(FL_SHIFT)) { // extend selection: + if (l == selection_) goto TOGGLE; + // state of previous selection determines new value: + whichway = l ? !item_selected(l) : 1; + // see which of the new item or previous selection is earlier, + // by searching from the previous forward for this one: + int down; + if (!l) down = 1; + else {for (void* m = selection_; ; m = item_next(m)) { + if (m == l) {down = 1; break;} + if (!m) {down = 0; break;} + }} + if (down) { + for (void* m = selection_; m != l; m = item_next(m)) { + select(m, whichway, when() & FL_WHEN_CHANGED); + if (wp.deleted()) return 1; + } + } else { + void* e = selection_; + for (void* m = item_next(l); m; m = item_next(m)) { + select(m, whichway, when() & FL_WHEN_CHANGED); + if (wp.deleted()) return 1; + if (m == e) break; + } + } + // do the clicked item last so the select box is around it: + change = 1; + if (l) select(l, whichway, when() & FL_WHEN_CHANGED); + if (wp.deleted()) return 1; + } else { // select only this item + change = select_only(l, 0); + if (wp.deleted()) return 1; + if (change && (when() & FL_WHEN_CHANGED)) { + set_changed(); + do_callback(); + if (wp.deleted()) return 1; + } + } + } + return 1; + case FL_DRAG: + // do the scrolling first: + my = Fl::event_y(); + if (my < Y && my < py) { + int p = real_position_+my-Y; + if (p<0) p = 0; + position(p); + } else if (my > (Y+H) && my > py) { + int p = real_position_+my-(Y+H); + int hh = full_height()-H; if (p > hh) p = hh; + if (p<0) p = 0; + position(p); + } + if (type() == FL_NORMAL_BROWSER || !top_) + ; + else if (type() == FL_MULTI_BROWSER) { + void* l = find_item(my); + void* t; void* b; // this will be the range to change + if (my > py) { // go down + t = selection_ ? item_next(selection_) : 0; + b = l ? item_next(l) : 0; + } else { // go up + t = l; + b = selection_; + } + for (; t && t != b; t = item_next(t)) { + char change_t; + change_t = select(t, whichway, 0); + if (wp.deleted()) return 1; + change |= change_t; + if (change_t && (when() & FL_WHEN_CHANGED)) { + set_changed(); + do_callback(); + if (wp.deleted()) return 1; + } + } + if (l) selection_ = l; + } else { + void* l1 = selection_; + void* l = + (Fl::event_x()x()+w()) ? selection_ : + find_item(my); + change = (l != l1); + select_only(l, when() & FL_WHEN_CHANGED); + if (wp.deleted()) return 1; + } + py = my; + return 1; + case FL_RELEASE: + if (type() == FL_SELECT_BROWSER) { + void* t = selection_; + deselect(); + if (wp.deleted()) return 1; + selection_ = t; + } + if (change) { + set_changed(); + if (when() & FL_WHEN_RELEASE) do_callback(); + } else { + if (when() & FL_WHEN_NOT_CHANGED) do_callback(); + } + if (wp.deleted()) return 1; + + // double click calls the callback: (like Enter Key) + if (Fl::event_clicks() && (when() & FL_WHEN_ENTER_KEY)) { + set_changed(); + do_callback(); + } + return 1; + case FL_FOCUS: + case FL_UNFOCUS: + if (type() >= FL_HOLD_BROWSER && Fl::visible_focus()) { + redraw(); + return 1; + } else return 0; + } + + return 0; +} + +/** + The constructor makes an empty browser. + \param[in] X,Y,W,H position and size. + \param[in] L The label string, may be NULL. +*/ +Fl_Browser_::Fl_Browser_(int X, int Y, int W, int H, const char* L) + : Fl_Group(X, Y, W, H, L), + scrollbar(0, 0, 0, 0, 0), // they will be resized by draw() + hscrollbar(0, 0, 0, 0, 0) +{ + box(FL_NO_BOX); + align(FL_ALIGN_BOTTOM); + position_ = real_position_ = 0; + hposition_ = real_hposition_ = 0; + offset_ = 0; + top_ = 0; + when(FL_WHEN_RELEASE_ALWAYS); + selection_ = 0; + color(FL_BACKGROUND2_COLOR, FL_SELECTION_COLOR); + scrollbar.callback(scrollbar_callback); +//scrollbar.align(FL_ALIGN_LEFT|FL_ALIGN_BOTTOM); // back compatibility? + hscrollbar.callback(hscrollbar_callback); + hscrollbar.type(FL_HORIZONTAL); + textfont_ = FL_HELVETICA; + textsize_ = FL_NORMAL_SIZE; + textcolor_ = FL_FOREGROUND_COLOR; + has_scrollbar_ = BOTH; + max_width = 0; + max_width_item = 0; + scrollbar_size_ = 0; + redraw1 = redraw2 = 0; + end(); +} + +/** + Sort the items in the browser based on \p flags. + item_swap(void*, void*) and item_text(void*) must be implemented for this call. + \param[in] flags FL_SORT_ASCENDING -- sort in ascending order\n + FL_SORT_DESCENDING -- sort in descending order\n + Values other than the above will cause undefined behavior\n + Other flags may appear in the future. + \todo Add a flag to ignore case +*/ +void Fl_Browser_::sort(int flags) { + // + // Simple bubble sort - pure lazyness on my side. + // + int i, j, n = -1, desc = ((flags&FL_SORT_DESCENDING)==FL_SORT_DESCENDING); + void *a =item_first(), *b, *c; + if (!a) return; + while (a) { + a = item_next(a); + n++; + } + for (i=n; i>0; i--) { + char swapped = 0; + a = item_first(); + b = item_next(a); + for (j=0; j0) { + item_swap(a, b); + swapped = 1; + } + } + if (!c) break; + b = c; a = item_prev(b); + } + if (!swapped) + break; + } +} + +// Default versions of some of the virtual functions: + +/** + This method may be provided by the subclass to return the height of the + \p item, in pixels. + Allow for two additional pixels for the list selection box. + This method differs from item_height in that it is only called for + selection and scrolling operations. + The default implementation calls item_height. + \param[in] item The item whose height to return. + \returns The height, in pixels. +*/ +int Fl_Browser_::item_quick_height(void* item) const { + return item_height(item); +} + +/** + This method may be provided to return the average height of all items + to be used for scrolling. + The default implementation uses the height of the first item. + \returns The average height of items, in pixels. +*/ +int Fl_Browser_::incr_height() const { + return item_quick_height(item_first()); +} + +/** + This method may be provided by the subclass to indicate the full height + of the item list, in pixels. + The default implementation computes the full height from the item heights. + Includes the items that are scrolled off screen. + \returns The height of the entire list, in pixels. +*/ +int Fl_Browser_::full_height() const { + int t = 0; + for (void* p = item_first(); p; p = item_next(p)) + t += item_quick_height(p); + return t; +} + +/** + This method may be provided by the subclass to indicate the full width + of the item list, in pixels. + The default implementation computes the full width from the item widths. + \returns The maximum width of all the items, in pixels. +*/ +int Fl_Browser_::full_width() const { + return max_width; +} + +/** + This method must be implemented by the subclass if it supports + multiple selections; sets the selection state to \p val for the \p item. + Sets the selection state for \p item, where optional \p val is 1 (select, the default) + or 0 (de-select). + \param[in] item The item to be selected + \param[in] val The optional selection state; 1=select, 0=de-select.\n + The default is to select the item (1). +*/ +void Fl_Browser_::item_select(void *item, int val) {} + +/** + This method must be implemented by the subclass if it supports + multiple selections; returns the selection state for \p item. + The method should return 1 if \p item is selected, or 0 otherwise. + \param[in] item The item to test. +*/ +int Fl_Browser_::item_selected(void* item) const { return item==selection_ ? 1 : 0; } + +// +// End of "$Id: Fl_Browser_.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Browser_load.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Browser_load.cxx new file mode 100644 index 0000000..d529d2a --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Browser_load.cxx @@ -0,0 +1,70 @@ +// +// "$Id: Fl_Browser_load.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// File loading routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include +#include + +/** + Clears the browser and reads the file, adding each line from the file + to the browser. If the filename is NULL or a zero-length + string then this just clears the browser. This returns zero if there + was any error in opening or reading the file, in which case errno + is set to the system error. The data() of each line is set + to NULL. + \param[in] filename The filename to load + \returns 1 if OK, 0 on error (errno has reason) + \see add() +*/ +int Fl_Browser::load(const char *filename) { +#define MAXFL_BLINE 1024 + char newtext[MAXFL_BLINE]; + int c; + int i; + clear(); + if (!filename || !(filename[0])) return 1; + FILE *fl = fl_fopen(filename,"r"); + if (!fl) return 0; + i = 0; + do { + c = getc(fl); + if (c == '\n' || c <= 0 || i>=(MAXFL_BLINE-1)) { + newtext[i] = 0; + add(newtext); + i = 0; + } else { + newtext[i++] = c; + } + } while (c >= 0); + fclose(fl); + return 1; +} + +// +// End of "$Id: Fl_Browser_load.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Button.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Button.cxx new file mode 100644 index 0000000..7104b44 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Button.cxx @@ -0,0 +1,218 @@ +// +// "$Id: Fl_Button.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Button widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include +#include + + +Fl_Widget_Tracker *Fl_Button::key_release_tracker = 0; + + +// There are a lot of subclasses, named Fl_*_Button. Some of +// them are implemented by setting the type() value and testing it +// here. This includes Fl_Radio_Button and Fl_Toggle_Button + +/** + Sets the current value of the button. + A non-zero value sets the button to 1 (ON), and zero sets it to 0 (OFF). + \param[in] v button value. + \see set(), clear() + */ +int Fl_Button::value(int v) { + v = v ? 1 : 0; + oldval = v; + clear_changed(); + if (value_ != v) { + value_ = v; + if (box()) redraw(); + else redraw_label(); + return 1; + } else { + return 0; + } +} + +/** + Turns on this button and turns off all other radio buttons in the group + (calling \c value(1) or \c set() does not do this). + */ +void Fl_Button::setonly() { // set this radio button on, turn others off + value(1); + Fl_Group* g = parent(); + Fl_Widget*const* a = g->array(); + for (int i = g->children(); i--;) { + Fl_Widget* o = *a++; + if (o != this && o->type()==FL_RADIO_BUTTON) ((Fl_Button*)o)->value(0); + } +} + +void Fl_Button::draw() { + if (type() == FL_HIDDEN_BUTTON) return; + Fl_Color col = value() ? selection_color() : color(); + draw_box(value() ? (down_box()?down_box():fl_down(box())) : box(), col); + draw_backdrop(); + if (labeltype() == FL_NORMAL_LABEL && value()) { + Fl_Color c = labelcolor(); + labelcolor(fl_contrast(c, col)); + draw_label(); + labelcolor(c); + } else draw_label(); + if (Fl::focus() == this) draw_focus(); +} + +int Fl_Button::handle(int event) { + int newval; + switch (event) { + case FL_ENTER: /* FALLTHROUGH */ + case FL_LEAVE: +// if ((value_?selection_color():color())==FL_GRAY) redraw(); + return 1; + case FL_PUSH: + if (Fl::visible_focus() && handle(FL_FOCUS)) Fl::focus(this); + case FL_DRAG: + if (Fl::event_inside(this)) { + if (type() == FL_RADIO_BUTTON) newval = 1; + else newval = !oldval; + } else + { + clear_changed(); + newval = oldval; + } + if (newval != value_) { + value_ = newval; + set_changed(); + redraw(); + if (when() & FL_WHEN_CHANGED) do_callback(); + } + return 1; + case FL_RELEASE: + if (value_ == oldval) { + if (when() & FL_WHEN_NOT_CHANGED) do_callback(); + return 1; + } + set_changed(); + if (type() == FL_RADIO_BUTTON) setonly(); + else if (type() == FL_TOGGLE_BUTTON) oldval = value_; + else { + value(oldval); + set_changed(); + if (when() & FL_WHEN_CHANGED) { + Fl_Widget_Tracker wp(this); + do_callback(); + if (wp.deleted()) return 1; + } + } + if (when() & FL_WHEN_RELEASE) do_callback(); + return 1; + case FL_SHORTCUT: + if (!(shortcut() ? + Fl::test_shortcut(shortcut()) : test_shortcut())) return 0; + if (Fl::visible_focus() && handle(FL_FOCUS)) Fl::focus(this); + goto triggered_by_keyboard; + case FL_FOCUS : /* FALLTHROUGH */ + case FL_UNFOCUS : + if (Fl::visible_focus()) { + if (box() == FL_NO_BOX) { + // Widgets with the FL_NO_BOX boxtype need a parent to + // redraw, since it is responsible for redrawing the + // background... + int X = x() > 0 ? x() - 1 : 0; + int Y = y() > 0 ? y() - 1 : 0; + if (window()) window()->damage(FL_DAMAGE_ALL, X, Y, w() + 2, h() + 2); + } else redraw(); + return 1; + } else return 0; + case FL_KEYBOARD : + if (Fl::focus() == this && Fl::event_key() == ' ' && + !(Fl::event_state() & (FL_SHIFT | FL_CTRL | FL_ALT | FL_META))) { + set_changed(); + triggered_by_keyboard: + Fl_Widget_Tracker wp(this); + if (type() == FL_RADIO_BUTTON && !value_) { + setonly(); + if (when() & FL_WHEN_CHANGED) do_callback(); + } else if (type() == FL_TOGGLE_BUTTON) { + value(!value()); + if (when() & FL_WHEN_CHANGED) do_callback(); + } else { + simulate_key_action(); + } + if (wp.deleted()) return 1; + if (when() & FL_WHEN_RELEASE) do_callback(); + return 1; + } + default: + return 0; + } +} + +void Fl_Button::simulate_key_action() +{ + if (key_release_tracker) { + Fl::remove_timeout(key_release_timeout, key_release_tracker); + key_release_timeout(key_release_tracker); + } + value(1); + redraw(); + key_release_tracker = new Fl_Widget_Tracker(this); + Fl::add_timeout(0.15, key_release_timeout, key_release_tracker); +} + +void Fl_Button::key_release_timeout(void *d) +{ + Fl_Widget_Tracker *wt = (Fl_Widget_Tracker*)d; + if (!wt) + return; + if (wt==key_release_tracker) + key_release_tracker = 0L; + Fl_Button *btn = (Fl_Button*)wt->widget(); + if (btn) { + btn->value(0); + btn->redraw(); + } + delete wt; +} + +/** + The constructor creates the button using the given position, size and label. + \param[in] X, Y, W, H position and size of the widget + \param[in] L widget label, default is no label + */ +Fl_Button::Fl_Button(int X, int Y, int W, int H, const char *L) +: Fl_Widget(X,Y,W,H,L) { + box(FL_UP_BOX); + down_box(FL_NO_BOX); + value_ = oldval = 0; + shortcut_ = 0; + set_flag(SHORTCUT_LABEL); +} + +// +// End of "$Id: Fl_Button.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Chart.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Chart.cxx new file mode 100644 index 0000000..5af4ed2 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Chart.cxx @@ -0,0 +1,436 @@ +// +// "$Id: Fl_Chart.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Forms-compatible chart widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include +#include +#include "flstring.h" +#include + +#define ARCINC (2.0*M_PI/360.0) + +// this function is in fl_boxtype.cxx: +void fl_rectbound(int x,int y,int w,int h, Fl_Color color); + +/* Widget specific information */ + +static void draw_barchart(int x,int y,int w,int h, + int numb, FL_CHART_ENTRY entries[], + double min, double max, int autosize, int maxnumb, + Fl_Color textcolor) +/* Draws a bar chart. x,y,w,h is the bounding box, entries the array of + numb entries and min and max the boundaries. */ +{ + double incr; + int zeroh; + double lh = fl_height(); + if (max == min) incr = h; + else incr = h/(max-min); + if ( (-min*incr) < lh) { + incr = (h - lh + min*incr)/(max-min); + zeroh = int(y+h-lh); + } else { + zeroh = (int)rint(y+h+min * incr); + } + int bwidth = (int)rint(w/double(autosize?numb:maxnumb)); + /* Draw base line */ + fl_color(textcolor); + fl_line(x, zeroh, x+w, zeroh); + if (min == 0.0 && max == 0.0) return; /* Nothing else to draw */ + int i; + /* Draw the bars */ + for (i=0; i 0) + fl_rectbound(x+i*bwidth,zeroh-hh,bwidth+1,hh+1,(Fl_Color)entries[i].col); + } + /* Draw the labels */ + fl_color(textcolor); + for (i=0; i lw) lw = w1; + } + if (lw > 0.0) lw += 4.0; + double incr; + int zeroh; + if (max == min) incr = w; + else incr = w/(max-min); + if ( (-min*incr) < lw) { + incr = (w - lw + min*incr)/(max-min); + zeroh = x+(int)rint(lw); + } else { + zeroh = (int)rint(x-min * incr); + } + int bwidth = (int)rint(h/double(autosize?numb:maxnumb)); + /* Draw base line */ + fl_color(textcolor); + fl_line(zeroh, y, zeroh, y+h); + if (min == 0.0 && max == 0.0) return; /* Nothing else to draw */ + /* Draw the bars */ + for (i=0; i 0) + fl_rectbound(zeroh,y+i*bwidth,ww+1,bwidth+1, (Fl_Color)entries[i].col); + else if (ww < 0) + fl_rectbound(zeroh+ww,y+i*bwidth,-ww+1,bwidth+1,(Fl_Color)entries[i].col); + } + /* Draw the labels */ + fl_color(textcolor); + for (i=0; i0.0)!=(entries[i].val>0.0)) { + double ttt = entries[i-1].val/(entries[i-1].val-entries[i].val); + int xt = x + (int)rint((i-.5+ttt)*bwidth); + fl_polygon(x0,zeroh, x0,yy0, xt,zeroh); + fl_polygon(xt,zeroh, x1,yy1, x1,zeroh); + } else { + fl_polygon(x0,zeroh, x0,yy0, x1,yy1, x1,zeroh); + } + fl_color(textcolor); + fl_line(x0,yy0,x1,yy1); + } + } + /* Draw base line */ + fl_color(textcolor); + fl_line(x,zeroh,x+w,zeroh); + /* Draw the labels */ + for (i=0; i=0 ? FL_ALIGN_BOTTOM : FL_ALIGN_TOP); +} + +static void draw_piechart(int x,int y,int w,int h, + int numb, FL_CHART_ENTRY entries[], int special, + Fl_Color textcolor) +/* Draws a pie chart. x,y,w,h is the bounding box, entries the array of + numb entries */ +{ + int i; + double xc,yc,rad; /* center and radius */ + double tot; /* sum of values */ + double incr; /* increment in angle */ + double curang; /* current angle we are drawing */ + double txc,tyc; /* temporary center */ + double lh = fl_height(); + /* compute center and radius */ + double h_denom = (special ? 2.3 : 2.0); + rad = (h - 2*lh)/h_denom/1.1; + xc = x+w/2.0; yc = y+h-1.1*rad-lh; + /* compute sum of values */ + tot = 0.0; + for (i=0; i 0.0) tot += entries[i].val; + if (tot == 0.0) return; + incr = 360.0/tot; + /* Draw the pie */ + curang = 0.0; + for (i=0; i 0.0) + { + txc = xc; tyc = yc; + /* Correct for special pies */ + if (special && i==0) + { + txc += 0.3*rad*cos(ARCINC*(curang+0.5*incr*entries[i].val)); + tyc -= 0.3*rad*sin(ARCINC*(curang+0.5*incr*entries[i].val)); + } + fl_color((Fl_Color)entries[i].col); + fl_begin_polygon(); fl_vertex(txc,tyc); + fl_arc(txc,tyc,rad,curang, curang+incr*entries[i].val); + fl_end_polygon(); + fl_color(textcolor); + fl_begin_loop(); fl_vertex(txc,tyc); + fl_arc(txc,tyc,rad,curang, curang+incr*entries[i].val); + fl_end_loop(); + curang += 0.5 * incr * entries[i].val; + /* draw the label */ + double xl = txc + 1.1*rad*cos(ARCINC*curang); + fl_draw(entries[i].str, + (int)rint(xl), + (int)rint(tyc - 1.1*rad*sin(ARCINC*curang)), + 0, 0, + xl= max) { + min = max = 0.0; + for (int i=0; i max) max = entries[i].val; + } + } + + fl_font(textfont(),textsize()); + + switch (type()) { + case FL_BAR_CHART: + ww++; // makes the bars fill box correctly + draw_barchart(xx,yy,ww,hh, numb, entries, min, max, + autosize(), maxnumb, textcolor()); + break; + case FL_HORBAR_CHART: + hh++; // makes the bars fill box correctly + draw_horbarchart(xx,yy,ww,hh, numb, entries, min, max, + autosize(), maxnumb, textcolor()); + break; + case FL_PIE_CHART: + draw_piechart(xx,yy,ww,hh,numb,entries,0, textcolor()); + break; + case FL_SPECIALPIE_CHART: + draw_piechart(xx,yy,ww,hh,numb,entries,1,textcolor()); + break; + default: + draw_linechart(type(),xx,yy,ww,hh, numb, entries, min, max, + autosize(), maxnumb, textcolor()); + break; + } + draw_label(); + fl_pop_clip(); +} + +/*------------------------------*/ + +#define FL_CHART_BOXTYPE FL_BORDER_BOX +#define FL_CHART_COL1 FL_COL1 +#define FL_CHART_LCOL FL_LCOL +#define FL_CHART_ALIGN FL_ALIGN_BOTTOM + +/** + Create a new Fl_Chart widget using the given position, size and label string. + The default boxstyle is \c FL_NO_BOX. + \param[in] X, Y, W, H position and size of the widget + \param[in] L widget label, default is no label + */ +Fl_Chart::Fl_Chart(int X, int Y, int W, int H,const char *L) : +Fl_Widget(X,Y,W,H,L) { + box(FL_BORDER_BOX); + align(FL_ALIGN_BOTTOM); + numb = 0; + maxnumb = 0; + sizenumb = FL_CHART_MAX; + autosize_ = 1; + min = max = 0; + textfont_ = FL_HELVETICA; + textsize_ = 10; + textcolor_ = FL_FOREGROUND_COLOR; + entries = (FL_CHART_ENTRY *)calloc(sizeof(FL_CHART_ENTRY), FL_CHART_MAX + 1); +} + +/** + Destroys the Fl_Chart widget and all of its data. + */ +Fl_Chart::~Fl_Chart() { + free(entries); +} + +/** + Removes all values from the chart. + */ +void Fl_Chart::clear() { + numb = 0; + min = max = 0; + redraw(); +} + +/** + Add the data value \p val with optional label \p str and color \p col + to the chart. + \param[in] val data value + \param[in] str optional data label + \param[in] col optional data color + */ +void Fl_Chart::add(double val, const char *str, unsigned col) { + /* Allocate more entries if required */ + if (numb >= sizenumb) { + sizenumb += FL_CHART_MAX; + entries = (FL_CHART_ENTRY *)realloc(entries, sizeof(FL_CHART_ENTRY) * (sizenumb + 1)); + } + // Shift entries as needed + if (numb >= maxnumb && maxnumb > 0) { + memmove(entries, entries + 1, sizeof(FL_CHART_ENTRY) * (numb - 1)); + numb --; + } + entries[numb].val = float(val); + entries[numb].col = col; + if (str) { + strlcpy(entries[numb].str,str,FL_CHART_LABEL_MAX + 1); + } else { + entries[numb].str[0] = 0; + } + numb++; + redraw(); +} + +/** + Inserts a data value \p val at the given position \p ind. + Position 1 is the first data value. + \param[in] ind insertion position + \param[in] val data value + \param[in] str optional data label + \param[in] col optional data color + */ +void Fl_Chart::insert(int ind, double val, const char *str, unsigned col) { + int i; + if (ind < 1 || ind > numb+1) return; + /* Allocate more entries if required */ + if (numb >= sizenumb) { + sizenumb += FL_CHART_MAX; + entries = (FL_CHART_ENTRY *)realloc(entries, sizeof(FL_CHART_ENTRY) * (sizenumb + 1)); + } + // Shift entries as needed + for (i=numb; i >= ind; i--) entries[i] = entries[i-1]; + if (numb < maxnumb || maxnumb == 0) numb++; + /* Fill in the new entry */ + entries[ind-1].val = float(val); + entries[ind-1].col = col; + if (str) { + strlcpy(entries[ind-1].str,str,FL_CHART_LABEL_MAX+1); + } else { + entries[ind-1].str[0] = 0; + } + redraw(); +} + +/** + Replace a data value \p val at the given position \p ind. + Position 1 is the first data value. + \param[in] ind insertion position + \param[in] val data value + \param[in] str optional data label + \param[in] col optional data color + */ +void Fl_Chart::replace(int ind,double val, const char *str, unsigned col) { + if (ind < 1 || ind > numb) return; + entries[ind-1].val = float(val); + entries[ind-1].col = col; + if (str) { + strlcpy(entries[ind-1].str,str,FL_CHART_LABEL_MAX+1); + } else { + entries[ind-1].str[0] = 0; + } + redraw(); +} + +/** + Sets the lower and upper bounds of the chart values. + \param[in] a, b are used to set lower, upper + */ +void Fl_Chart::bounds(double a, double b) { + this->min = a; + this->max = b; + redraw(); +} + +/** + Set the maximum number of data values for a chart. + If you do not call this method then the chart will be allowed to grow + to any size depending on available memory. + \param[in] m maximum number of data values allowed. + */ +void Fl_Chart::maxsize(int m) { + int i; + /* Fill in the new number */ + if (m < 0) return; + maxnumb = m; + /* Shift entries if required */ + if (numb > maxnumb) { + for (i = 0; i +#include +#include "flstring.h" +#include +#include + +/* This uses a cache for faster access when you're scanning the list +either forwards or backwards. */ + +Fl_Check_Browser::cb_item *Fl_Check_Browser::find_item(int n) const { + int i = n; + cb_item *p = first; + + if (n <= 0 || n > nitems_ || p == 0) { + return 0; + } + + if (n == cached_item) { + p = cache; + n = 1; + } else if (n == cached_item + 1) { + p = cache->next; + n = 1; + } else if (n == cached_item - 1) { + p = cache->prev; + n = 1; + } + + while (--n) { + p = p->next; + } + + /* Cast to not const and cache it. */ + + ((Fl_Check_Browser *)this)->cache = p; + ((Fl_Check_Browser *)this)->cached_item = i; + + return p; +} + +int Fl_Check_Browser::lineno(cb_item *p0) const { + cb_item *p = first; + + if (p == 0) { + return 0; + } + + int i = 1; + while (p) { + if (p == p0) { + return i; + } + i++; + p = p->next; + } + + return 0; +} + +Fl_Check_Browser::Fl_Check_Browser(int X, int Y, int W, int H, const char *l) +/** The constructor makes an empty browser.*/ +: Fl_Browser_(X, Y, W, H, l) { + type(FL_SELECT_BROWSER); + when(FL_WHEN_NEVER); + first = last = 0; + nitems_ = nchecked_ = 0; + cached_item = -1; +} + +void *Fl_Check_Browser::item_first() const { + return first; +} + +void *Fl_Check_Browser::item_next(void *l) const { + return ((cb_item *)l)->next; +} + +void *Fl_Check_Browser::item_prev(void *l) const { + return ((cb_item *)l)->prev; +} + +int Fl_Check_Browser::item_height(void *) const { + return textsize() + 2; +} + +#define CHECK_SIZE (textsize()-2) + +int Fl_Check_Browser::item_width(void *v) const { + fl_font(textfont(), textsize()); + return int(fl_width(((cb_item *)v)->text)) + CHECK_SIZE + 8; +} + +void Fl_Check_Browser::item_draw(void *v, int X, int Y, int, int) const { + cb_item *i = (cb_item *)v; + char *s = i->text; + int tsize = textsize(); + Fl_Color col = active_r() ? textcolor() : fl_inactive(textcolor()); + int cy = Y + (tsize + 1 - CHECK_SIZE) / 2; + X += 2; + + fl_color(active_r() ? FL_FOREGROUND_COLOR : fl_inactive(FL_FOREGROUND_COLOR)); + fl_loop(X, cy, X, cy + CHECK_SIZE, + X + CHECK_SIZE, cy + CHECK_SIZE, X + CHECK_SIZE, cy); + if (i->checked) { + int tx = X + 3; + int tw = CHECK_SIZE - 4; + int d1 = tw/3; + int d2 = tw-d1; + int ty = cy + (CHECK_SIZE+d2)/2-d1-2; + for (int n = 0; n < 3; n++, ty++) { + fl_line(tx, ty, tx+d1, ty+d1); + fl_line(tx+d1, ty+d1, tx+tw-1, ty+d1-d2+1); + } + } + fl_font(textfont(), tsize); + if (i->selected) { + col = fl_contrast(col, selection_color()); + } + fl_color(col); + fl_draw(s, X + CHECK_SIZE + 8, Y + tsize - 1); +} + +void Fl_Check_Browser::item_select(void *v, int state) { + cb_item *i = (cb_item *)v; + + if (state) { + if (i->checked) { + i->checked = 0; + nchecked_--; + } else { + i->checked = 1; + nchecked_++; + } + } +} + +int Fl_Check_Browser::item_selected(void *v) const { + cb_item *i = (cb_item *)v; + return i->selected; +} +/** + Add a new unchecked line to the end of the browser. The text is copied + using the strdup() function. It may also be NULL to make + a blank line. The second form can set the item checked. +*/ +int Fl_Check_Browser::add(char *s) { + return (add(s, 0)); +} + +/** See int Fl_Check_Browser::add(char *s) */ +int Fl_Check_Browser::add(char *s, int b) { + cb_item *p = (cb_item *)malloc(sizeof(cb_item)); + p->next = 0; + p->prev = 0; + p->checked = b; + p->selected = 0; + p->text = strdup(s); + + if (b) { + nchecked_++; + } + + if (last == 0) { + first = last = p; + } else { + last->next = p; + p->prev = last; + last = p; + } + nitems_++; + + return (nitems_); +} + +/** + Remove line n and make the browser one line shorter. Returns the + number of lines left in the browser. +*/ +int Fl_Check_Browser::remove(int item) { + cb_item *p = find_item(item); + + // line at item exists + if(p) { + // tell the Browser_ what we will do + deleting(p); + + // fix checked count + if(p->checked) + --nchecked_; + + // remove the node + if (p->prev) + p->prev->next = p->next; + else + first = p->next; + if (p->next) + p->next->prev = p->prev; + else + last = p->prev; + + free(p->text); + free(p); + + --nitems_; + cached_item = -1; + } + + return (nitems_); +} + +/** Remove every item from the browser.*/ +void Fl_Check_Browser::clear() { + cb_item *p = first; + cb_item *next; + + if (p == 0) { + return; + } + + new_list(); + do { + next = p->next; + free(p->text); + free(p); + p = next; + } while (p); + + first = last = 0; + nitems_ = nchecked_ = 0; + cached_item = -1; +} + +/** Gets the current status of item item. */ +int Fl_Check_Browser::checked(int i) const { + cb_item *p = find_item(i); + + if (p) return p->checked; + return 0; +} + +/** Sets the check status of item item to b. */ +void Fl_Check_Browser::checked(int i, int b) { + cb_item *p = find_item(i); + + if (p && (p->checked ^ b)) { + p->checked = b; + if (b) { + nchecked_++; + } else { + nchecked_--; + } + redraw(); + } +} + +/** Returns the index of the currently selected item.*/ +int Fl_Check_Browser::value() const { + return lineno((cb_item *)selection()); +} + +/** Return a pointer to an internal buffer holding item item's text.*/ +char *Fl_Check_Browser::text(int i) const { + cb_item *p = find_item(i); + + if (p) return p->text; + return 0; +} + +/** Sets all the items checked.*/ +void Fl_Check_Browser::check_all() { + cb_item *p; + + nchecked_ = nitems_; + for (p = first; p; p = p->next) { + p->checked = 1; + } + redraw(); +} + +/** Sets all the items unchecked.*/ +void Fl_Check_Browser::check_none() { + cb_item *p; + + nchecked_ = 0; + for (p = first; p; p = p->next) { + p->checked = 0; + } + redraw(); +} + +int Fl_Check_Browser::handle(int event) { + if (event==FL_PUSH) + deselect(); + return Fl_Browser_::handle(event); +} + +// +// End of "$Id: Fl_Check_Browser.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Check_Button.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Check_Button.cxx new file mode 100644 index 0000000..0baeafc --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Check_Button.cxx @@ -0,0 +1,47 @@ +// +// "$Id: Fl_Check_Button.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Check button widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include + +// TODO Correct incorrect Fl_Check_Button comments. +// A subclass of Fl_Button that always draws as a diamond box. This +// diamond is smaller than the widget size and can be surchecked by +// another box type, for compatibility with Forms. + +/** + Creates a new Fl_Check_Button widget using the given position, size and + label string. + \param[in] X, Y, W, H position and size of the widget + \param[in] L widget label, default is no label + */ +Fl_Check_Button::Fl_Check_Button(int X, int Y, int W, int H, const char *L) +: Fl_Light_Button(X, Y, W, H, L) { + box(FL_NO_BOX); + down_box(FL_DOWN_BOX); + selection_color(FL_FOREGROUND_COLOR); +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Choice.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Choice.cxx new file mode 100644 index 0000000..6f3b06f --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Choice.cxx @@ -0,0 +1,213 @@ +// +// "$Id: Fl_Choice.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Choice widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include +#include "flstring.h" + +// Emulates the Forms choice widget. This is almost exactly the same +// as an Fl_Menu_Button. The only difference is the appearance of the +// button: it draws the text of the current pick and a down-arrow. + +void Fl_Choice::draw() { + int dx = Fl::box_dx(FL_DOWN_BOX); + int dy = Fl::box_dy(FL_DOWN_BOX); + int H = h() - 2 * dy; + int W = (H > 20) ? 20 : H; + int X = x() + w() - W - dx; + int Y = y() + dy; + int w1 = (W - 4) / 3; if (w1 < 1) w1 = 1; + int x1 = X + (W - 2 * w1 - 1) / 2; + int y1 = Y + (H - w1 - 1) / 2; + + if (Fl::scheme()) { + draw_box(FL_UP_BOX, color()); + + fl_color(active_r() ? labelcolor() : fl_inactive(labelcolor())); + if (!strcmp(Fl::scheme(), "plastic")) { + // Show larger up/down arrows... + fl_polygon(x1, y1 + 3, x1 + w1, y1 + w1 + 3, x1 + 2 * w1, y1 + 3); + fl_polygon(x1, y1 + 1, x1 + w1, y1 - w1 + 1, x1 + 2 * w1, y1 + 1); + } else { + // Show smaller up/down arrows with a divider... + x1 = x() + w() - 13 - dx; + y1 = y() + h() / 2; + fl_polygon(x1, y1 - 2, x1 + 3, y1 - 5, x1 + 6, y1 - 2); + fl_polygon(x1, y1 + 2, x1 + 3, y1 + 5, x1 + 6, y1 + 2); + + fl_color(fl_darker(color())); + fl_yxline(x1 - 7, y1 - 8, y1 + 8); + + fl_color(fl_lighter(color())); + fl_yxline(x1 - 6, y1 - 8, y1 + 8); + } + } else { + if (fl_contrast(textcolor(), FL_BACKGROUND2_COLOR) == textcolor()) { + draw_box(FL_DOWN_BOX, FL_BACKGROUND2_COLOR); + } else { + draw_box(FL_DOWN_BOX, fl_lighter(color())); + } + draw_box(FL_UP_BOX,X,Y,W,H,color()); + + fl_color(active_r() ? labelcolor() : fl_inactive(labelcolor())); + fl_polygon(x1, y1, x1 + w1, y1 + w1, x1 + 2 * w1, y1); + } + + W += 2 * dx; + + if (mvalue()) { + Fl_Menu_Item m = *mvalue(); + if (active_r()) m.activate(); else m.deactivate(); + + // ERCO + int xx = x() + dx, yy = y() + dy + 1, ww = w() - W, hh = H - 2; + + fl_push_clip(xx, yy, ww, hh); + + if ( Fl::scheme()) { + Fl_Label l; + l.value = m.text; + l.image = 0; + l.deimage = 0; + l.type = m.labeltype_; + l.font = m.labelsize_ || m.labelfont_ ? m.labelfont_ : textfont(); + l.size = m.labelsize_ ? m.labelsize_ : textsize(); + l.color= m.labelcolor_ ? m.labelcolor_ : textcolor(); + if (!m.active()) l.color = fl_inactive((Fl_Color)l.color); + fl_draw_shortcut = 2; // hack value to make '&' disappear + l.draw(xx+3, yy, ww>6 ? ww-6 : 0, hh, FL_ALIGN_LEFT); + fl_draw_shortcut = 0; + if ( Fl::focus() == this ) draw_focus(box(), xx, yy, ww, hh); + } + else { + fl_draw_shortcut = 2; // hack value to make '&' disappear + m.draw(xx, yy, ww, hh, this, Fl::focus() == this); + fl_draw_shortcut = 0; + } + + fl_pop_clip(); + } + + draw_label(); +} + +/** + Create a new Fl_Choice widget using the given position, size and label string. + The default boxtype is \c FL_UP_BOX. + + The constructor sets menu() to NULL. + See Fl_Menu_ for the methods to set or change the menu. + + \param[in] X, Y, W, H position and size of the widget + \param[in] L widget label, default is no label + */ +Fl_Choice::Fl_Choice(int X, int Y, int W, int H, const char *L) +: Fl_Menu_(X,Y,W,H,L) { + align(FL_ALIGN_LEFT); + when(FL_WHEN_RELEASE); + textfont(FL_HELVETICA); + box(FL_FLAT_BOX); + down_box(FL_BORDER_BOX); +} + +/** + Sets the currently selected value using a pointer to menu item. + Changing the selected value causes a redraw(). + \param[in] v pointer to menu item in the menu item array. + \returns non-zero if the new value is different to the old one. + */ +int Fl_Choice::value(const Fl_Menu_Item *v) { + if (!Fl_Menu_::value(v)) return 0; + redraw(); + return 1; +} + +/** + Sets the currently selected value using the index into the menu item array. + Changing the selected value causes a redraw(). + \param[in] v index of value in the menu item array. + \returns non-zero if the new value is different to the old one. + */ +int Fl_Choice::value(int v) { + if (v == -1) return value((const Fl_Menu_Item *)0); + if (v < 0 || v >= (size() - 1)) return 0; + if (!Fl_Menu_::value(v)) return 0; + redraw(); + return 1; +} + +int Fl_Choice::handle(int e) { + if (!menu() || !menu()->text) return 0; + const Fl_Menu_Item* v; + switch (e) { + case FL_ENTER: + case FL_LEAVE: + return 1; + + case FL_KEYBOARD: + if (Fl::event_key() != ' ' || + (Fl::event_state() & (FL_SHIFT | FL_CTRL | FL_ALT | FL_META))) return 0; + case FL_PUSH: + if (Fl::visible_focus()) Fl::focus(this); + J1: + if (Fl::scheme() + || fl_contrast(textcolor(), FL_BACKGROUND2_COLOR) != textcolor()) { + v = menu()->pulldown(x(), y(), w(), h(), mvalue(), this); + } else { + // In order to preserve the old look-n-feel of "white" menus, + // temporarily override the color() of this widget... + Fl_Color c = color(); + color(FL_BACKGROUND2_COLOR); + v = menu()->pulldown(x(), y(), w(), h(), mvalue(), this); + color(c); + } + if (!v || v->submenu()) return 1; + if (v != mvalue()) redraw(); + picked(v); + return 1; + case FL_SHORTCUT: + if (Fl_Widget::test_shortcut()) goto J1; + v = menu()->test_shortcut(); + if (!v) return 0; + if (v != mvalue()) redraw(); + picked(v); + return 1; + case FL_FOCUS: + case FL_UNFOCUS: + if (Fl::visible_focus()) { + redraw(); + return 1; + } else return 0; + default: + return 0; + } +} + +// +// End of "$Id: Fl_Choice.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Clock.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Clock.cxx new file mode 100644 index 0000000..75a757c --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Clock.cxx @@ -0,0 +1,218 @@ +// +// "$Id: Fl_Clock.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Clock widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include +#include +#include +#ifndef WIN32 +# include +#endif /* !WIN32 */ + +// Original clock display written by Paul Haeberli at SGI. +// Modifications by Mark Overmars for Forms +// Further changes by Bill Spitzak for fltk + +const float hourhand[4][2] = {{-0.5f, 0}, {0, 1.5f}, {0.5f, 0}, {0, -7.0f}}; +const float minhand[4][2] = {{-0.5f, 0}, {0, 1.5f}, {0.5f, 0}, {0, -11.5f}}; +const float sechand[4][2] = {{-0.1f, 0}, {0, 2.0f}, {0.1f, 0}, {0, -11.5f}}; + +static void drawhand(double ang,const float v[][2],Fl_Color fill,Fl_Color line) +{ + fl_push_matrix(); + fl_rotate(ang); + fl_color(fill); fl_begin_polygon(); + int i; for (i=0; i<4; i++) fl_vertex(v[i][0],v[i][1]); fl_end_polygon(); + fl_color(line); fl_begin_loop(); + for (i=0; i<4; i++) fl_vertex(v[i][0],v[i][1]); fl_end_loop(); + fl_pop_matrix(); +} + +void Fl_Clock_Output::drawhands(Fl_Color fill, Fl_Color line) { + if (!active_r()) { + fill = fl_inactive(fill); + line = fl_inactive(line); + } + drawhand(-360*(hour()+minute()/60.0)/12, hourhand, fill, line); + drawhand(-360*(minute()+second()/60.0)/60, minhand, fill, line); + drawhand(-360*(second()/60.0), sechand, fill, line); +} + +static void rect(double x, double y, double w, double h) { + double r = x+w; + double t = y+h; + fl_begin_polygon(); + fl_vertex(x, y); + fl_vertex(r, y); + fl_vertex(r, t); + fl_vertex(x, t); + fl_end_polygon(); +} + +/** + Draw clock with the given position and size. + \param[in] X, Y, W, H position and size +*/ +void Fl_Clock_Output::draw(int X, int Y, int W, int H) { + Fl_Color box_color = type()==FL_ROUND_CLOCK ? FL_GRAY : color(); + Fl_Color shadow_color = fl_color_average(box_color, FL_BLACK, 0.5); + draw_box(box(), X, Y, W, H, box_color); + fl_push_matrix(); + fl_translate(X+W/2.0-.5, Y+H/2.0-.5); + fl_scale((W-1)/28.0, (H-1)/28.0); + if (type() == FL_ROUND_CLOCK) { + fl_color(active_r() ? color() : fl_inactive(color())); + fl_begin_polygon(); fl_circle(0,0,14); fl_end_polygon(); + fl_color(active_r() ? FL_FOREGROUND_COLOR : fl_inactive(FL_FOREGROUND_COLOR)); + fl_begin_loop(); fl_circle(0,0,14); fl_end_loop(); + } + // draw the shadows: + fl_push_matrix(); + fl_translate(0.60, 0.60); + drawhands(shadow_color, shadow_color); + fl_pop_matrix(); + // draw the tick marks: + fl_push_matrix(); + fl_color(active_r() ? FL_FOREGROUND_COLOR : fl_inactive(FL_FOREGROUND_COLOR)); + for (int i=0; i<12; i++) { + if (i==6) rect(-0.5, 9, 1, 2); + else if (i==3 || i==0 || i== 9) rect(-0.5, 9.5, 1, 1); + else rect(-0.25, 9.5, .5, 1); + fl_rotate(-30); + } + fl_pop_matrix(); + // draw the hands: + drawhands(selection_color(), FL_FOREGROUND_COLOR); // color was 54 + fl_pop_matrix(); +} + +/** + Draw clock with current position and size. +*/ +void Fl_Clock_Output::draw() { + draw(x(), y(), w(), h()); + draw_label(); +} + +/** + Set the displayed time. + Set the time in hours, minutes, and seconds. + \param[in] H, m, s displayed time + \see hour(), minute(), second() + */ +void Fl_Clock_Output::value(int H, int m, int s) { + if (H!=hour_ || m!=minute_ || s!=second_) { + hour_ = H; minute_ = m; second_ = s; + value_ = (H * 60 + m) * 60 + s; + damage(FL_DAMAGE_CHILD); + } +} + +/** + Set the displayed time. + Set the time in seconds since the UNIX epoch (January 1, 1970). + \param[in] v seconds since epoch + \see value() + */ +void Fl_Clock_Output::value(ulong v) { + value_ = v; + struct tm *timeofday; + // Some platforms, notably Windows, now use a 64-bit time_t value... + time_t vv = (time_t)v; + timeofday = localtime(&vv); + value(timeofday->tm_hour, timeofday->tm_min, timeofday->tm_sec); +} + +/** + Create a new Fl_Clock_Output widget with the given position, size and label. + The default boxtype is \c FL_NO_BOX. + \param[in] X, Y, W, H position and size of the widget + \param[in] L widget label, default is no label + */ +Fl_Clock_Output::Fl_Clock_Output(int X, int Y, int W, int H, const char *L) +: Fl_Widget(X, Y, W, H, L) { + box(FL_UP_BOX); + selection_color(fl_gray_ramp(5)); + align(FL_ALIGN_BOTTOM); + hour_ = 0; + minute_ = 0; + second_ = 0; + value_ = 0; +} + +//////////////////////////////////////////////////////////////// + +/** + Create an Fl_Clock widget using the given position, size, and label string. + The default boxtype is \c FL_NO_BOX. + \param[in] X, Y, W, H position and size of the widget + \param[in] L widget label, default is no label + */ +Fl_Clock::Fl_Clock(int X, int Y, int W, int H, const char *L) + : Fl_Clock_Output(X, Y, W, H, L) {} + +/** + Create an Fl_Clock widget using the given boxtype, position, size, and + label string. + \param[in] t boxtype + \param[in] X, Y, W, H position and size of the widget + \param[in] L widget label, default is no label + */ +Fl_Clock::Fl_Clock(uchar t, int X, int Y, int W, int H, const char *L) + : Fl_Clock_Output(X, Y, W, H, L) { + type(t); + box(t==FL_ROUND_CLOCK ? FL_NO_BOX : FL_UP_BOX); +} + +static void tick(void *v) { + ((Fl_Clock*)v)->value(time(0)); + Fl::add_timeout(1.0, tick, v); +} + +int Fl_Clock::handle(int event) { + switch (event) { + case FL_SHOW: + tick(this); + break; + case FL_HIDE: + Fl::remove_timeout(tick, this); + break; + } + return Fl_Clock_Output::handle(event); +} + +/** + The destructor removes the clock. + */ +Fl_Clock::~Fl_Clock() { + Fl::remove_timeout(tick, this); +} + +// +// End of "$Id: Fl_Clock.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Color_Chooser.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Color_Chooser.cxx new file mode 100644 index 0000000..0c513aa --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Color_Chooser.cxx @@ -0,0 +1,630 @@ +// +// "$Id: Fl_Color_Chooser.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Color chooser for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include +#include +#include + +// Besides being a useful object on it's own, the Fl_Color_Chooser was +// an attempt to make a complex composite object that could be easily +// imbedded into a user interface. If you wish to make complex objects +// of your own, be sure to read this code. + +// The function fl_color_chooser() creates a window containing a color +// chooser and a few buttons and current-color indicators. It is an +// easier interface for simple programs that just need a color. + +// The "hue box" can be a circle or rectilinear. +// You get a circle by defining this: +#define CIRCLE 1 +// And the "hue box" can auto-update when the value changes +// you get this by defining this: +#define UPDATE_HUE_BOX 1 + +/** + This \e static method converts HSV colors to RGB colorspace. + \param[in] H, S, V color components + \param[out] R, G, B color components + */ +void Fl_Color_Chooser::hsv2rgb( + double H, double S, double V, double& R, double& G, double& B) { + if (S < 5.0e-6) { + R = G = B = V; + } else { + int i = (int)H; + double f = H - (float)i; + double p1 = V*(1.0-S); + double p2 = V*(1.0-S*f); + double p3 = V*(1.0-S*(1.0-f)); + switch (i) { + case 0: R = V; G = p3; B = p1; break; + case 1: R = p2; G = V; B = p1; break; + case 2: R = p1; G = V; B = p3; break; + case 3: R = p1; G = p2; B = V; break; + case 4: R = p3; G = p1; B = V; break; + case 5: R = V; G = p1; B = p2; break; + } + } +} + +/** + This \e static method converts RGB colors to HSV colorspace. + \param[in] R, G, B color components + \param[out] H, S, V color components + */ +void Fl_Color_Chooser::rgb2hsv( + double R, double G, double B, double& H, double& S, double& V) { + double maxv = R > G ? R : G; if (B > maxv) maxv = B; + V = maxv; + if (maxv>0) { + double minv = R < G ? R : G; if (B < minv) minv = B; + S = 1.0 - double(minv)/maxv; + if (maxv > minv) { + if (maxv == R) {H = (G-B)/double(maxv-minv); if (H<0) H += 6.0;} + else if (maxv == G) H = 2.0+(B-R)/double(maxv-minv); + else H = 4.0+(R-G)/double(maxv-minv); + } + } +} + +/** Fl_Color_Chooser modes */ +enum { + M_RGB, /**< mode() of Fl_Color_Chooser showing RGB values */ + M_BYTE, /**< mode() of Fl_Color_Chooser showing byte values */ + M_HEX, /**< mode() of Fl_Color_Chooser showing hex values */ + M_HSV /**< mode() of Fl_Color_Chooser showing HSV values */ +}; +static Fl_Menu_Item mode_menu[] = { + {"rgb"}, + {"byte"}, + {"hex"}, + {"hsv"}, + {0} +}; + +#ifndef FL_DOXYGEN +int Flcc_Value_Input::format(char* buf) { + Fl_Color_Chooser* c = (Fl_Color_Chooser*)parent(); + if (c->mode() == M_HEX) return sprintf(buf,"0x%02X", int(value())); + else return Fl_Valuator::format(buf); +} +#endif // !FL_DOXYGEN + +void Fl_Color_Chooser::set_valuators() { + switch (mode()) { + case M_RGB: + rvalue.range(0,1); rvalue.step(1,1000); rvalue.value(r_); + gvalue.range(0,1); gvalue.step(1,1000); gvalue.value(g_); + bvalue.range(0,1); bvalue.step(1,1000); bvalue.value(b_); + break; + case M_BYTE: /* FALLTHROUGH */ + case M_HEX: + rvalue.range(0,255); rvalue.step(1); rvalue.value(int(255*r_+.5)); + gvalue.range(0,255); gvalue.step(1); gvalue.value(int(255*g_+.5)); + bvalue.range(0,255); bvalue.step(1); bvalue.value(int(255*b_+.5)); + break; + case M_HSV: + rvalue.range(0,6); rvalue.step(1,1000); rvalue.value(hue_); + gvalue.range(0,1); gvalue.step(1,1000); gvalue.value(saturation_); + bvalue.range(0,1); bvalue.step(1,1000); bvalue.value(value_); + break; + } +} + +/** + Sets the current rgb color values. + Does not do the callback. Does not clamp (but out of range values will + produce psychedelic effects in the hue selector). + \param[in] R, G, B color components. + \return 1 if a new rgb value was set, 0 if the rgb value was the previous one. + */ +int Fl_Color_Chooser::rgb(double R, double G, double B) { + if (R == r_ && G == g_ && B == b_) return 0; + r_ = R; g_ = G; b_ = B; + double ph = hue_; + double ps = saturation_; + double pv = value_; + rgb2hsv(R,G,B,hue_,saturation_,value_); + set_valuators(); + set_changed(); + if (value_ != pv) { +#ifdef UPDATE_HUE_BOX + huebox.damage(FL_DAMAGE_SCROLL); +#endif + valuebox.damage(FL_DAMAGE_EXPOSE);} + if (hue_ != ph || saturation_ != ps) { + huebox.damage(FL_DAMAGE_EXPOSE); + valuebox.damage(FL_DAMAGE_SCROLL); + } + return 1; +} + +/** + Set the hsv values. + The passed values are clamped (or for hue, modulus 6 is used) to get + legal values. Does not do the callback. + \param[in] H, S, V color components. + \return 1 if a new hsv value was set, 0 if the hsv value was the previous one. +*/ +int Fl_Color_Chooser::hsv(double H, double S, double V) { + H = fmod(H,6.0); if (H < 0.0) H += 6.0; + if (S < 0.0) S = 0.0; else if (S > 1.0) S = 1.0; + if (V < 0.0) V = 0.0; else if (V > 1.0) V = 1.0; + if (H == hue_ && S == saturation_ && V == value_) return 0; + double ph = hue_; + double ps = saturation_; + double pv = value_; + hue_ = H; saturation_ = S; value_ = V; + if (value_ != pv) { +#ifdef UPDATE_HUE_BOX + huebox.damage(FL_DAMAGE_SCROLL); +#endif + valuebox.damage(FL_DAMAGE_EXPOSE);} + if (hue_ != ph || saturation_ != ps) { + huebox.damage(FL_DAMAGE_EXPOSE); + valuebox.damage(FL_DAMAGE_SCROLL); + } + hsv2rgb(H,S,V,r_,g_,b_); + set_valuators(); + set_changed(); + return 1; +} + +//////////////////////////////////////////////////////////////// + +static void tohs(double x, double y, double& h, double& s) { +#ifdef CIRCLE + x = 2*x-1; + y = 1-2*y; + s = sqrt(x*x+y*y); if (s > 1.0) s = 1.0; + h = (3.0/M_PI)*atan2(y,x); + if (h<0) h += 6.0; +#else + h = fmod(6.0*x,6.0); if (h < 0.0) h += 6.0; + s = 1.0-y; if (s < 0.0) s = 0.0; else if (s > 1.0) s = 1.0; +#endif +} + +#ifndef FL_DOXYGEN +int Flcc_HueBox::handle(int e) { + static double ih, is; + Fl_Color_Chooser* c = (Fl_Color_Chooser*)parent(); + switch (e) { + case FL_PUSH: + if (Fl::visible_focus()) { + Fl::focus(this); + redraw(); + } + ih = c->hue(); + is = c->saturation(); + case FL_DRAG: { + double Xf, Yf, H, S; + Xf = (Fl::event_x()-x()-Fl::box_dx(box()))/double(w()-Fl::box_dw(box())); + Yf = (Fl::event_y()-y()-Fl::box_dy(box()))/double(h()-Fl::box_dh(box())); + tohs(Xf, Yf, H, S); + if (fabs(H-ih) < 3*6.0/w()) H = ih; + if (fabs(S-is) < 3*1.0/h()) S = is; + if (Fl::event_state(FL_CTRL)) H = ih; + if (c->hsv(H, S, c->value())) c->do_callback(); + } return 1; + case FL_FOCUS : /* FALLTHROUGH */ + case FL_UNFOCUS : + if (Fl::visible_focus()) { + redraw(); + return 1; + } + else return 1; + case FL_KEYBOARD : + return handle_key(Fl::event_key()); + default: + return 0; + } +} +#endif // !FL_DOXYGEN + +static void generate_image(void* vv, int X, int Y, int W, uchar* buf) { + Flcc_HueBox* v = (Flcc_HueBox*)vv; + int iw = v->w()-Fl::box_dw(v->box()); + double Yf = double(Y)/(v->h()-Fl::box_dh(v->box())); +#ifdef UPDATE_HUE_BOX + const double V = ((Fl_Color_Chooser*)(v->parent()))->value(); +#else + const double V = 1.0; +#endif + for (int x = X; x < X+W; x++) { + double Xf = double(x)/iw; + double H,S; tohs(Xf,Yf,H,S); + double r,g,b; + Fl_Color_Chooser::hsv2rgb(H,S,V,r,g,b); + *buf++ = uchar(255*r+.5); + *buf++ = uchar(255*g+.5); + *buf++ = uchar(255*b+.5); + } +} + +#ifndef FL_DOXYGEN +int Flcc_HueBox::handle_key(int key) { + int w1 = w()-Fl::box_dw(box())-6; + int h1 = h()-Fl::box_dh(box())-6; + Fl_Color_Chooser* c = (Fl_Color_Chooser*)parent(); + +#ifdef CIRCLE + int X = int(.5*(cos(c->hue()*(M_PI/3.0))*c->saturation()+1) * w1); + int Y = int(.5*(1-sin(c->hue()*(M_PI/3.0))*c->saturation()) * h1); +#else + int X = int(c->hue()/6.0*w1); + int Y = int((1-c->saturation())*h1); +#endif + + switch (key) { + case FL_Up : + Y -= 3; + break; + case FL_Down : + Y += 3; + break; + case FL_Left : + X -= 3; + break; + case FL_Right : + X += 3; + break; + default : + return 0; + } + + double Xf, Yf, H, S; + Xf = (double)X/(double)w1; + Yf = (double)Y/(double)h1; + tohs(Xf, Yf, H, S); + if (c->hsv(H, S, c->value())) c->do_callback(); + + return 1; +} +#endif // !FL_DOXYGEN + +#ifndef FL_DOXYGEN +void Flcc_HueBox::draw() { + if (damage()&FL_DAMAGE_ALL) draw_box(); + int x1 = x()+Fl::box_dx(box()); + int yy1 = y()+Fl::box_dy(box()); + int w1 = w()-Fl::box_dw(box()); + int h1 = h()-Fl::box_dh(box()); + if (damage() == FL_DAMAGE_EXPOSE) fl_push_clip(x1+px,yy1+py,6,6); + fl_draw_image(generate_image, this, x1, yy1, w1, h1); + if (damage() == FL_DAMAGE_EXPOSE) fl_pop_clip(); + Fl_Color_Chooser* c = (Fl_Color_Chooser*)parent(); +#ifdef CIRCLE + int X = int(.5*(cos(c->hue()*(M_PI/3.0))*c->saturation()+1) * (w1-6)); + int Y = int(.5*(1-sin(c->hue()*(M_PI/3.0))*c->saturation()) * (h1-6)); +#else + int X = int(c->hue()/6.0*(w1-6)); + int Y = int((1-c->saturation())*(h1-6)); +#endif + if (X < 0) X = 0; else if (X > w1-6) X = w1-6; + if (Y < 0) Y = 0; else if (Y > h1-6) Y = h1-6; + // fl_color(c->value()>.75 ? FL_BLACK : FL_WHITE); + draw_box(FL_UP_BOX,x1+X,yy1+Y,6,6,Fl::focus() == this ? FL_FOREGROUND_COLOR : FL_GRAY); + px = X; py = Y; +} +#endif // !FL_DOXYGEN + +//////////////////////////////////////////////////////////////// + +#ifndef FL_DOXYGEN +int Flcc_ValueBox::handle(int e) { + static double iv; + Fl_Color_Chooser* c = (Fl_Color_Chooser*)parent(); + switch (e) { + case FL_PUSH: + if (Fl::visible_focus()) { + Fl::focus(this); + redraw(); + } + iv = c->value(); + case FL_DRAG: { + double Yf; + Yf = 1-(Fl::event_y()-y()-Fl::box_dy(box()))/double(h()-Fl::box_dh(box())); + if (fabs(Yf-iv)<(3*1.0/h())) Yf = iv; + if (c->hsv(c->hue(),c->saturation(),Yf)) c->do_callback(); + } return 1; + case FL_FOCUS : /* FALLTHROUGH */ + case FL_UNFOCUS : + if (Fl::visible_focus()) { + redraw(); + return 1; + } + else return 1; + case FL_KEYBOARD : + return handle_key(Fl::event_key()); + default: + return 0; + } +} +#endif // !FL_DOXYGEN + +static double tr, tg, tb; +static void generate_vimage(void* vv, int X, int Y, int W, uchar* buf) { + Flcc_ValueBox* v = (Flcc_ValueBox*)vv; + double Yf = 255*(1.0-double(Y)/(v->h()-Fl::box_dh(v->box()))); + uchar r = uchar(tr*Yf+.5); + uchar g = uchar(tg*Yf+.5); + uchar b = uchar(tb*Yf+.5); + for (int x = X; x < X+W; x++) { + *buf++ = r; *buf++ = g; *buf++ = b; + } +} + +#ifndef FL_DOXYGEN +void Flcc_ValueBox::draw() { + if (damage()&FL_DAMAGE_ALL) draw_box(); + Fl_Color_Chooser* c = (Fl_Color_Chooser*)parent(); + c->hsv2rgb(c->hue(),c->saturation(),1.0,tr,tg,tb); + int x1 = x()+Fl::box_dx(box()); + int yy1 = y()+Fl::box_dy(box()); + int w1 = w()-Fl::box_dw(box()); + int h1 = h()-Fl::box_dh(box()); + if (damage() == FL_DAMAGE_EXPOSE) fl_push_clip(x1,yy1+py,w1,6); + fl_draw_image(generate_vimage, this, x1, yy1, w1, h1); + if (damage() == FL_DAMAGE_EXPOSE) fl_pop_clip(); + int Y = int((1-c->value()) * (h1-6)); + if (Y < 0) Y = 0; else if (Y > h1-6) Y = h1-6; + draw_box(FL_UP_BOX,x1,yy1+Y,w1,6,Fl::focus() == this ? FL_FOREGROUND_COLOR : FL_GRAY); + py = Y; +} +#endif // !FL_DOXYGEN + +#ifndef FL_DOXYGEN +int Flcc_ValueBox::handle_key(int key) { + int h1 = h()-Fl::box_dh(box())-6; + Fl_Color_Chooser* c = (Fl_Color_Chooser*)parent(); + + int Y = int((1-c->value()) * h1); + if (Y < 0) Y = 0; else if (Y > h1) Y = h1; + + switch (key) { + case FL_Up : + Y -= 3; + break; + case FL_Down : + Y += 3; + break; + default : + return 0; + } + + double Yf; + Yf = 1-((double)Y/(double)h1); + if (c->hsv(c->hue(),c->saturation(),Yf)) c->do_callback(); + + return 1; +} +#endif // !FL_DOXYGEN + +//////////////////////////////////////////////////////////////// + +void Fl_Color_Chooser::rgb_cb(Fl_Widget* o, void*) { + Fl_Color_Chooser* c = (Fl_Color_Chooser*)(o->parent()); + double R = c->rvalue.value(); + double G = c->gvalue.value(); + double B = c->bvalue.value(); + if (c->mode() == M_HSV) { + if (c->hsv(R,G,B)) c->do_callback(); + return; + } + if (c->mode() != M_RGB) { + R = R/255; + G = G/255; + B = B/255; + } + if (c->rgb(R,G,B)) c->do_callback(); +} + +void Fl_Color_Chooser::mode_cb(Fl_Widget* o, void*) { + Fl_Color_Chooser* c = (Fl_Color_Chooser*)(o->parent()); + // force them to redraw even if value is the same: + c->rvalue.value(-1); + c->gvalue.value(-1); + c->bvalue.value(-1); + c->set_valuators(); +} + +void Fl_Color_Chooser::mode(int newMode) +{ + choice.value(newMode); + choice.do_callback(); +} + + +//////////////////////////////////////////////////////////////// + +/** + Creates a new Fl_Color_Chooser widget using the given position, size, and + label string. + The recommended dimensions are 200x95. The color is initialized to black. + \param[in] X, Y, W, H position and size of the widget + \param[in] L widget label, default is no label + */ +Fl_Color_Chooser::Fl_Color_Chooser(int X, int Y, int W, int H, const char* L) + : Fl_Group(0,0,195,115,L), + huebox(0,0,115,115), + valuebox(115,0,20,115), + choice(140,0,55,25), + rvalue(140,30,55,25), + gvalue(140,60,55,25), + bvalue(140,90,55,25), + resize_box(0,0,115,115) +{ + end(); + resizable(resize_box); + resize(X,Y,W,H); + r_ = g_ = b_ = 0; + hue_ = 0.0; + saturation_ = 0.0; + value_ = 0.0; + huebox.box(FL_DOWN_FRAME); + valuebox.box(FL_DOWN_FRAME); + choice.menu(mode_menu); + set_valuators(); + rvalue.callback(rgb_cb); + gvalue.callback(rgb_cb); + bvalue.callback(rgb_cb); + choice.callback(mode_cb); + choice.box(FL_THIN_UP_BOX); + choice.textfont(FL_HELVETICA_BOLD_ITALIC); +} + +//////////////////////////////////////////////////////////////// +// fl_color_chooser(): + +#include +#include +#include + +class ColorChip : public Fl_Widget { + void draw(); +public: + uchar r,g,b; + ColorChip(int X, int Y, int W, int H) : Fl_Widget(X,Y,W,H) { + box(FL_ENGRAVED_FRAME);} +}; + +void ColorChip::draw() { + if (damage()&FL_DAMAGE_ALL) draw_box(); + fl_rectf(x()+Fl::box_dx(box()), + y()+Fl::box_dy(box()), + w()-Fl::box_dw(box()), + h()-Fl::box_dh(box()),r,g,b); +} + +static void chooser_cb(Fl_Widget* o, void* vv) { + Fl_Color_Chooser* c = (Fl_Color_Chooser*)o; + ColorChip* v = (ColorChip*)vv; + v->r = uchar(255*c->r()+.5); + v->g = uchar(255*c->g()+.5); + v->b = uchar(255*c->b()+.5); + v->damage(FL_DAMAGE_EXPOSE); +} + +extern const char* fl_ok; +extern const char* fl_cancel; + +// fl_color_chooser's callback for ok_button (below) +// [in] o is a pointer to okay_button (below) +// [in] p is a pointer to an int to receive the return value (1) +// closes the fl_color_chooser window +static void cc_ok_cb (Fl_Widget *o, void *p) { + *((int *)p) = 1; // set return value + o->window()->hide(); +} + +// fl_color_chooser's callback for cancel_button and window close +// [in] o is a pointer to cancel_button (below) _or_ the dialog window +// [in] p is a pointer to an int to receive the return value (0) +// closes the fl_color_chooser window +static void cc_cancel_cb (Fl_Widget *o, void *p) { + *((int *)p) = 0; // set return value + if (o->window()) // cancel button + o->window()->hide(); + else // window close + o->hide(); +} + +/** \addtogroup group_comdlg + @{ */ +/** + \brief Pops up a window to let the user pick an arbitrary RGB color. + \image html fl_color_chooser.jpg + \image latex fl_color_chooser.eps "fl_color_chooser" width=8cm + \param[in] name Title label for the window + \param[in,out] r, g, b Color components in the range 0.0 to 1.0. + \param[in] cmode Optional mode for color chooser. See mode(int). Default -1 if none (rgb mode). + \retval 1 if user confirms the selection + \retval 0 if user cancels the dialog + \relates Fl_Color_Chooser + */ +int fl_color_chooser(const char* name, double& r, double& g, double& b, int cmode) { + int ret = 0; + Fl_Window window(215,200,name); + window.callback(cc_cancel_cb,&ret); + Fl_Color_Chooser chooser(10, 10, 195, 115); + ColorChip ok_color(10, 130, 95, 25); + Fl_Return_Button ok_button(10, 165, 95, 25, fl_ok); + ok_button.callback(cc_ok_cb,&ret); + ColorChip cancel_color(110, 130, 95, 25); + cancel_color.r = uchar(255*r+.5); ok_color.r = cancel_color.r; + ok_color.g = cancel_color.g = uchar(255*g+.5); + ok_color.b = cancel_color.b = uchar(255*b+.5); + Fl_Button cancel_button(110, 165, 95, 25, fl_cancel); + cancel_button.callback(cc_cancel_cb,&ret); + window.resizable(chooser); + chooser.rgb(r,g,b); + chooser.callback(chooser_cb, &ok_color); + if (cmode!=-1) chooser.mode(cmode); + window.end(); + window.set_modal(); + window.hotspot(window); + window.show(); + while (window.shown()) Fl::wait(); + if (ret) { // ok_button or Enter + r = chooser.r(); + g = chooser.g(); + b = chooser.b(); + } + return ret; +} + +/** + \brief Pops up a window to let the user pick an arbitrary RGB color. + \image html fl_color_chooser.jpg + \image latex fl_color_chooser.eps "fl_color_chooser" width=8cm + \param[in] name Title label for the window + \param[in,out] r, g, b Color components in the range 0 to 255. + \param[in] cmode Optional mode for color chooser. See mode(int). Default -1 if none (rgb mode). + \retval 1 if user confirms the selection + \retval 0 if user cancels the dialog + \relates Fl_Color_Chooser + */ +int fl_color_chooser(const char* name, uchar& r, uchar& g, uchar& b, int cmode) { + double dr = r/255.0; + double dg = g/255.0; + double db = b/255.0; + if (fl_color_chooser(name,dr,dg,db,cmode)) { + r = uchar(255*dr+.5); + g = uchar(255*dg+.5); + b = uchar(255*db+.5); + return 1; + } + return 0; +} + +/** @} */ +// +// End of "$Id: Fl_Color_Chooser.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Counter.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Counter.cxx new file mode 100644 index 0000000..7f895a7 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Counter.cxx @@ -0,0 +1,211 @@ +// +// "$Id: Fl_Counter.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Counter widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include + +void Fl_Counter::draw() { + int i; Fl_Boxtype boxtype[5]; + Fl_Color selcolor; + + boxtype[0] = box(); + if (boxtype[0] == FL_UP_BOX) boxtype[0] = FL_DOWN_BOX; + if (boxtype[0] == FL_THIN_UP_BOX) boxtype[0] = FL_THIN_DOWN_BOX; + for (i=1; i<5; i++) + if (mouseobj == i) + boxtype[i] = fl_down(box()); + else + boxtype[i] = box(); + + int xx[5], ww[5]; + if (type() == FL_NORMAL_COUNTER) { + int W = w()*15/100; + xx[1] = x(); ww[1] = W; + xx[2] = x()+1*W; ww[2] = W; + xx[0] = x()+2*W; ww[0] = w()-4*W; + xx[3] = x()+w()-2*W; ww[3] = W; + xx[4] = x()+w()-1*W; ww[4] = W; + } else { + int W = w()*20/100; + xx[1] = 0; ww[1] = 0; + xx[2] = x(); ww[2] = W; + xx[0] = x()+W; ww[0] = w()-2*W; + xx[3] = x()+w()-1*W; ww[3] = W; + xx[4] = 0; ww[4] = 0; + } + + draw_box(boxtype[0], xx[0], y(), ww[0], h(), FL_BACKGROUND2_COLOR); + fl_font(textfont(), textsize()); + fl_color(active_r() ? textcolor() : fl_inactive(textcolor())); + char str[128]; format(str); + fl_draw(str, xx[0], y(), ww[0], h(), FL_ALIGN_CENTER); + if (Fl::focus() == this) draw_focus(boxtype[0], xx[0], y(), ww[0], h()); + if (!(damage()&FL_DAMAGE_ALL)) return; // only need to redraw text + + if (active_r()) + selcolor = labelcolor(); + else + selcolor = fl_inactive(labelcolor()); + + if (type() == FL_NORMAL_COUNTER) { + draw_box(boxtype[1], xx[1], y(), ww[1], h(), color()); + fl_draw_symbol("@-4<<", xx[1], y(), ww[1], h(), selcolor); + } + draw_box(boxtype[2], xx[2], y(), ww[2], h(), color()); + fl_draw_symbol("@-4<", xx[2], y(), ww[2], h(), selcolor); + draw_box(boxtype[3], xx[3], y(), ww[3], h(), color()); + fl_draw_symbol("@-4>", xx[3], y(), ww[3], h(), selcolor); + if (type() == FL_NORMAL_COUNTER) { + draw_box(boxtype[4], xx[4], y(), ww[4], h(), color()); + fl_draw_symbol("@-4>>", xx[4], y(), ww[4], h(), selcolor); + } +} + +void Fl_Counter::increment_cb() { + if (!mouseobj) return; + double v = value(); + switch (mouseobj) { + case 1: v -= lstep_; break; + case 2: v = increment(v, -1); break; + case 3: v = increment(v, 1); break; + case 4: v += lstep_; break; + } + handle_drag(clamp(round(v))); +} + +#define INITIALREPEAT .5 +#define REPEAT .1 + +void Fl_Counter::repeat_callback(void* v) { + Fl_Counter* b = (Fl_Counter*)v; + if (b->mouseobj) { + Fl::add_timeout(REPEAT, repeat_callback, b); + b->increment_cb(); + } +} + +int Fl_Counter::calc_mouseobj() { + if (type() == FL_NORMAL_COUNTER) { + int W = w()*15/100; + if (Fl::event_inside(x(), y(), W, h())) return 1; + if (Fl::event_inside(x()+W, y(), W, h())) return 2; + if (Fl::event_inside(x()+w()-2*W, y(), W, h())) return 3; + if (Fl::event_inside(x()+w()-W, y(), W, h())) return 4; + } else { + int W = w()*20/100; + if (Fl::event_inside(x(), y(), W, h())) return 2; + if (Fl::event_inside(x()+w()-W, y(), W, h())) return 3; + } + return -1; +} + +int Fl_Counter::handle(int event) { + int i; + switch (event) { + case FL_RELEASE: + if (mouseobj) { + Fl::remove_timeout(repeat_callback, this); + mouseobj = 0; + redraw(); + } + handle_release(); + return 1; + case FL_PUSH: + if (Fl::visible_focus()) Fl::focus(this); + { Fl_Widget_Tracker wp(this); + handle_push(); + if (wp.deleted()) return 1; + } + case FL_DRAG: + i = calc_mouseobj(); + if (i != mouseobj) { + Fl::remove_timeout(repeat_callback, this); + mouseobj = (uchar)i; + if (i) Fl::add_timeout(INITIALREPEAT, repeat_callback, this); + Fl_Widget_Tracker wp(this); + increment_cb(); + if (wp.deleted()) return 1; + redraw(); + } + return 1; + case FL_KEYBOARD : + switch (Fl::event_key()) { + case FL_Left: + handle_drag(clamp(increment(value(),-1))); + return 1; + case FL_Right: + handle_drag(clamp(increment(value(),1))); + return 1; + default: + return 0; + } + // break not required because of switch... + case FL_FOCUS : /* FALLTHROUGH */ + case FL_UNFOCUS : + if (Fl::visible_focus()) { + redraw(); + return 1; + } else return 0; + case FL_ENTER : /* FALLTHROUGH */ + case FL_LEAVE : + return 1; + default: + return 0; + } +} + +/** + Destroys the valuator. + */ +Fl_Counter::~Fl_Counter() { + Fl::remove_timeout(repeat_callback, this); +} + +/** + Creates a new Fl_Counter widget using the given position, size, and label + string. The default type is FL_NORMAL_COUNTER. + \param[in] X, Y, W, H position and size of the widget + \param[in] L widget label, default is no label + */ +Fl_Counter::Fl_Counter(int X, int Y, int W, int H, const char* L) + : Fl_Valuator(X, Y, W, H, L) { + box(FL_UP_BOX); + selection_color(FL_INACTIVE_COLOR); // was FL_BLUE + align(FL_ALIGN_BOTTOM); + bounds(-1000000.0, 1000000.0); + Fl_Valuator::step(1, 10); + lstep_ = 1.0; + mouseobj = 0; + textfont_ = FL_HELVETICA; + textsize_ = FL_NORMAL_SIZE; + textcolor_ = FL_FOREGROUND_COLOR; +} + +// +// End of "$Id: Fl_Counter.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Device.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Device.cxx new file mode 100644 index 0000000..b37ad5d --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Device.cxx @@ -0,0 +1,56 @@ +// +// "$Id: Fl_Device.cxx 7659 2010-07-01 13:21:32Z manolo $" +// +// implementation of Fl_Device class for the Fast Light Tool Kit (FLTK). +// +// Copyright 2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems to: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include + +const char *Fl_Device::device_type = "Fl_Device"; +const char *Fl_Surface_Device::device_type = "Fl_Surface_Device"; +const char *Fl_Display_Device::device_type = "Fl_Display_Device"; +const char *Fl_Graphics_Driver::device_type = "Fl_Graphics_Driver"; +#if defined(__APPLE__) || defined(FL_DOXYGEN) +const char *Fl_Quartz_Graphics_Driver::device_type = "Fl_Quartz_Graphics_Driver"; +#endif +#if defined(WIN32) || defined(FL_DOXYGEN) +const char *Fl_GDI_Graphics_Driver::device_type = "Fl_GDI_Graphics_Driver"; +#endif +#if !(defined(__APPLE__) || defined(WIN32)) +const char *Fl_Xlib_Graphics_Driver::device_type = "Fl_Xlib_Graphics_Driver"; +#endif + + +/** \brief Use this drawing surface for future graphics requests. */ +void Fl_Surface_Device::set_current(void) +{ + fl_graphics_driver = _driver; + fl_surface = this; +} + +// +// End of "$Id: Fl_Device.cxx 7659 2010-07-01 13:21:32Z manolo $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Dial.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Dial.cxx new file mode 100644 index 0000000..2adaabb --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Dial.cxx @@ -0,0 +1,166 @@ +// +// "$Id: Fl_Dial.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Circular dial widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include +#include +#include + +// All angles are measured with 0 to the right and counter-clockwise +/** + Draws dial at given position and size. + \param[in] X, Y, W, H position and size +*/ +void Fl_Dial::draw(int X, int Y, int W, int H) { + if (damage()&FL_DAMAGE_ALL) draw_box(box(), X, Y, W, H, color()); + X += Fl::box_dx(box()); + Y += Fl::box_dy(box()); + W -= Fl::box_dw(box()); + H -= Fl::box_dh(box()); + double angle = (a2-a1)*(value()-minimum())/(maximum()-minimum()) + a1; + if (type() == FL_FILL_DIAL) { + // foo: draw this nicely in certain round box types + int foo = (box() > _FL_ROUND_UP_BOX && Fl::box_dx(box())); + if (foo) {X--; Y--; W+=2; H+=2;} + if (active_r()) fl_color(color()); + else fl_color(fl_inactive(color())); + fl_pie(X, Y, W, H, 270-a1, angle > a1 ? 360+270-angle : 270-360-angle); + if (active_r()) fl_color(selection_color()); + else fl_color(fl_inactive(selection_color())); + fl_pie(X, Y, W, H, 270-angle, 270-a1); + if (foo) { + if (active_r()) fl_color(FL_FOREGROUND_COLOR); + else fl_color(fl_inactive(FL_FOREGROUND_COLOR)); + fl_arc(X, Y, W, H, 0, 360); + } + return; + } + if (!(damage()&FL_DAMAGE_ALL)) { + if (active_r()) fl_color(color()); + else fl_color(fl_inactive(color())); + fl_pie(X+1, Y+1, W-2, H-2, 0, 360); + } + fl_push_matrix(); + fl_translate(X+W/2-.5, Y+H/2-.5); + fl_scale(W-1, H-1); + fl_rotate(45-angle); + if (active_r()) fl_color(selection_color()); + else fl_color(fl_inactive(selection_color())); + if (type()) { // FL_LINE_DIAL + fl_begin_polygon(); + fl_vertex(0.0, 0.0); + fl_vertex(-0.04, 0.0); + fl_vertex(-0.25, 0.25); + fl_vertex(0.0, 0.04); + fl_end_polygon(); + if (active_r()) fl_color(FL_FOREGROUND_COLOR); + else fl_color(fl_inactive(FL_FOREGROUND_COLOR)); + fl_begin_loop(); + fl_vertex(0.0, 0.0); + fl_vertex(-0.04, 0.0); + fl_vertex(-0.25, 0.25); + fl_vertex(0.0, 0.04); + fl_end_loop(); + } else { + fl_begin_polygon(); fl_circle(-0.20, 0.20, 0.07); fl_end_polygon(); + if (active_r()) fl_color(FL_FOREGROUND_COLOR); + else fl_color(fl_inactive(FL_FOREGROUND_COLOR)); + fl_begin_loop(); fl_circle(-0.20, 0.20, 0.07); fl_end_loop(); + } + fl_pop_matrix(); +} + +/** + Draws dial at current position and size. +*/ +void Fl_Dial::draw() { + draw(x(), y(), w(), h()); + draw_label(); +} + +/** + Allows subclasses to handle event based on given position and size. + \param[in] event, X, Y, W, H event to handle, related position and size. +*/ +int Fl_Dial::handle(int event, int X, int Y, int W, int H) { + switch (event) { + case FL_PUSH: { + Fl_Widget_Tracker wp(this); + handle_push(); + if (wp.deleted()) return 1; } + case FL_DRAG: { + int mx = (Fl::event_x()-X-W/2)*H; + int my = (Fl::event_y()-Y-H/2)*W; + if (!mx && !my) return 1; + double angle = 270-atan2((float)-my, (float)mx)*180/M_PI; + double oldangle = (a2-a1)*(value()-minimum())/(maximum()-minimum()) + a1; + while (angle < oldangle-180) angle += 360; + while (angle > oldangle+180) angle -= 360; + double val; + if ((a1= a1)) { + val = minimum(); + } else if ((a1= a2) : (angle <= a2)) { + val = maximum(); + } else { + val = minimum() + (maximum()-minimum())*(angle-a1)/(a2-a1); + } + handle_drag(clamp(round(val))); + } return 1; + case FL_RELEASE: + handle_release(); + return 1; + case FL_ENTER : /* FALLTHROUGH */ + case FL_LEAVE : + return 1; + default: + return 0; + } +} + +/** + Allow subclasses to handle event based on current position and size. +*/ +int Fl_Dial::handle(int e) { + return handle(e, x(), y(), w(), h()); +} + +Fl_Dial::Fl_Dial(int X, int Y, int W, int H, const char* l) +/** + Creates a new Fl_Dial widget using the given position, size, + and label string. The default type is FL_NORMAL_DIAL. +*/ +: Fl_Valuator(X, Y, W, H, l) { + box(FL_OVAL_BOX); + selection_color(FL_INACTIVE_COLOR); // was 37 + a1 = 45; + a2 = 315; +} + +// +// End of "$Id: Fl_Dial.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Double_Window.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Double_Window.cxx new file mode 100644 index 0000000..a44eac6 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Double_Window.cxx @@ -0,0 +1,461 @@ +// +// "$Id: Fl_Double_Window.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Double-buffered window code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include +#include +#include +#include + +// On systems that support double buffering "naturally" the base +// Fl_Window class will probably do double-buffer and this subclass +// does nothing. + +#if USE_XDBE + +#include + +static int use_xdbe; + +static int can_xdbe() { + static int tried; + if (!tried) { + tried = 1; + int event_base, error_base; + if (!XdbeQueryExtension(fl_display, &event_base, &error_base)) return 0; + Drawable root = RootWindow(fl_display,fl_screen); + int numscreens = 1; + XdbeScreenVisualInfo *a = XdbeGetVisualInfo(fl_display,&root,&numscreens); + if (!a) return 0; + for (int j = 0; j < a->count; j++) + if (a->visinfo[j].visual == fl_visual->visualid + /*&& a->visinfo[j].perflevel > 0*/) {use_xdbe = 1; break;} + XdbeFreeVisualInfo(a); + } + return use_xdbe; +} +#endif + +void Fl_Double_Window::show() { + Fl_Window::show(); +} + +static void fl_copy_offscreen_to_display(int x, int y, int w, int h, Fl_Offscreen pixmap, int srcx, int srcy); + +/** \addtogroup fl_drawings + @{ + */ +/** Copy a rectangular area of the given offscreen buffer into the current drawing destination. + \param x,y position where to draw the copied rectangle + \param w,h size of the copied rectangle + \param pixmap offscreen buffer containing the rectangle to copy + \param srcx,srcy origin in offscreen buffer of rectangle to copy + */ +void fl_copy_offscreen(int x, int y, int w, int h, Fl_Offscreen pixmap, int srcx, int srcy) { + if( fl_graphics_driver == fl_display_device->driver()) { + fl_copy_offscreen_to_display(x, y, w, h, pixmap, srcx, srcy); + } + else { // when copy is not to the display + fl_begin_offscreen(pixmap); + uchar *img = fl_read_image(NULL, srcx, srcy, w, h, 0); + fl_end_offscreen(); + fl_draw_image(img, x, y, w, h, 3, 0); + delete img; + } +} +/** @} */ + +#if defined(USE_X11) + +static void fl_copy_offscreen_to_display(int x, int y, int w, int h, Fl_Offscreen pixmap, int srcx, int srcy) { + XCopyArea(fl_display, pixmap, fl_window, fl_gc, srcx, srcy, w, h, x, y); +} + + +// maybe someone feels inclined to implement alpha blending on X11? +char fl_can_do_alpha_blending() { + return 0; +} +#elif defined(WIN32) + +// Code used to switch output to an off-screen window. See macros in +// win32.H which save the old state in local variables. + +typedef struct { BYTE a; BYTE b; BYTE c; BYTE d; } FL_BLENDFUNCTION; +typedef BOOL (WINAPI* fl_alpha_blend_func) + (HDC,int,int,int,int,HDC,int,int,int,int,FL_BLENDFUNCTION); +static fl_alpha_blend_func fl_alpha_blend = NULL; +static FL_BLENDFUNCTION blendfunc = { 0, 0, 255, 1}; + +/* + * This function checks if the version of MSWindows that we + * curently run on supports alpha blending for bitmap transfers + * and finds the required function if so. + */ +char fl_can_do_alpha_blending() { + static char been_here = 0; + static char can_do = 0; + // do this test only once + if (been_here) return can_do; + been_here = 1; + // load the library that implements alpha blending + HMODULE hMod = LoadLibrary("MSIMG32.DLL"); + // give up if that doesn't exist (Win95?) + if (!hMod) return 0; + // now find the blending function inside that dll + fl_alpha_blend = (fl_alpha_blend_func)GetProcAddress(hMod, "AlphaBlend"); + // give up if we can't find it (Win95) + if (!fl_alpha_blend) return 0; + // we have the call, but does our display support alpha blending? + // get the desktop's device context + HDC dc = GetDC(0L); + if (!dc) return 0; + // check the device capabilities flags. However GetDeviceCaps + // does not return anything useful, so we have to do it manually: + + HBITMAP bm = CreateCompatibleBitmap(dc, 1, 1); + HDC new_gc = CreateCompatibleDC(dc); + int save = SaveDC(new_gc); + SelectObject(new_gc, bm); + /*COLORREF set = */ SetPixel(new_gc, 0, 0, 0x01010101); + BOOL alpha_ok = fl_alpha_blend(dc, 0, 0, 1, 1, new_gc, 0, 0, 1, 1, blendfunc); + RestoreDC(new_gc, save); + DeleteDC(new_gc); + DeleteObject(bm); + ReleaseDC(0L, dc); + + if (alpha_ok) can_do = 1; + return can_do; +} + +HDC fl_makeDC(HBITMAP bitmap) { + HDC new_gc = CreateCompatibleDC(fl_gc); + SetTextAlign(new_gc, TA_BASELINE|TA_LEFT); + SetBkMode(new_gc, TRANSPARENT); +#if USE_COLORMAP + if (fl_palette) SelectPalette(new_gc, fl_palette, FALSE); +#endif + SelectObject(new_gc, bitmap); + return new_gc; +} + +static void fl_copy_offscreen_to_display(int x,int y,int w,int h,HBITMAP bitmap,int srcx,int srcy) { + HDC new_gc = CreateCompatibleDC(fl_gc); + int save = SaveDC(new_gc); + SelectObject(new_gc, bitmap); + BitBlt(fl_gc, x, y, w, h, new_gc, srcx, srcy, SRCCOPY); + RestoreDC(new_gc, save); + DeleteDC(new_gc); +} + +void fl_copy_offscreen_with_alpha(int x,int y,int w,int h,HBITMAP bitmap,int srcx,int srcy) { + HDC new_gc = CreateCompatibleDC(fl_gc); + int save = SaveDC(new_gc); + SelectObject(new_gc, bitmap); + BOOL alpha_ok = 0; + // first try to alpha blend + // if to printer, always try alpha_blend + int to_display = Fl_Surface_Device::surface()->type() == Fl_Display_Device::device_type; // true iff display output + if ( (to_display && fl_can_do_alpha_blending()) || Fl_Surface_Device::surface()->type() == Fl_Printer::device_type) { + alpha_ok = fl_alpha_blend(fl_gc, x, y, w, h, new_gc, srcx, srcy, w, h, blendfunc); + } + // if that failed (it shouldn't), still copy the bitmap over, but now alpha is 1 + if (!alpha_ok) { + BitBlt(fl_gc, x, y, w, h, new_gc, srcx, srcy, SRCCOPY); + } + RestoreDC(new_gc, save); + DeleteDC(new_gc); +} + +extern void fl_restore_clip(); + +#elif defined(__APPLE_QUARTZ__) || defined(FL_DOXYGEN) + +char fl_can_do_alpha_blending() { + return 1; +} + +Fl_Offscreen fl_create_offscreen_with_alpha(int w, int h) { + void *data = calloc(w*h,4); + CGColorSpaceRef lut = CGColorSpaceCreateDeviceRGB(); + CGContextRef ctx = CGBitmapContextCreate( + data, w, h, 8, w*4, lut, kCGImageAlphaPremultipliedLast); + CGColorSpaceRelease(lut); + return (Fl_Offscreen)ctx; +} + +/** \addtogroup fl_drawings + @{ + */ + +/** + Creation of an offscreen graphics buffer. + \param w,h width and height in pixels of the buffer. + \return the created graphics buffer. + */ +Fl_Offscreen fl_create_offscreen(int w, int h) { + void *data = calloc(w*h,4); + CGColorSpaceRef lut = CGColorSpaceCreateDeviceRGB(); + CGContextRef ctx = CGBitmapContextCreate( + data, w, h, 8, w*4, lut, kCGImageAlphaNoneSkipLast); + CGColorSpaceRelease(lut); + return (Fl_Offscreen)ctx; +} + +static void bmProviderRelease (void *src, const void *data, size_t size) +{ + CFIndex count = CFGetRetainCount(src); + CFRelease(src); + if(count == 1) free((void*)data); +} + +static void fl_copy_offscreen_to_display(int x,int y,int w,int h,Fl_Offscreen osrc,int srcx,int srcy) { + CGContextRef src = (CGContextRef)osrc; + void *data = CGBitmapContextGetData(src); + int sw = CGBitmapContextGetWidth(src); + int sh = CGBitmapContextGetHeight(src); + CGImageAlphaInfo alpha = CGBitmapContextGetAlphaInfo(src); + CGColorSpaceRef lut = CGColorSpaceCreateDeviceRGB(); + // when output goes to a Quartz printercontext, release of the bitmap must be + // delayed after the end of the print page + CFRetain(src); + CGDataProviderRef src_bytes = CGDataProviderCreateWithData( src, data, sw*sh*4, bmProviderRelease); + CGImageRef img = CGImageCreate( sw, sh, 8, 4*8, 4*sw, lut, alpha, + src_bytes, 0L, false, kCGRenderingIntentDefault); + // fl_push_clip(); + CGRect rect = { { x, y }, { w, h } }; + Fl_X::q_begin_image(rect, srcx, srcy, sw, sh); + CGContextDrawImage(fl_gc, rect, img); + Fl_X::q_end_image(); + CGImageRelease(img); + CGColorSpaceRelease(lut); + CGDataProviderRelease(src_bytes); +} + +/** Deletion of an offscreen graphics buffer. + \param ctx the buffer to be deleted. + */ +void fl_delete_offscreen(Fl_Offscreen ctx) { + if (!ctx) return; + void *data = CGBitmapContextGetData((CGContextRef)ctx); + CFIndex count = CFGetRetainCount(ctx); + CGContextRelease((CGContextRef)ctx); + if(count == 1) free(data); +} + +const int stack_max = 16; +static int stack_ix = 0; +static CGContextRef stack_gc[stack_max]; +static Window stack_window[stack_max]; +static Fl_Surface_Device *_ss; + +/** Send all subsequent drawing commands to this offscreen buffer. + \param ctx the offscreen buffer. + */ +void fl_begin_offscreen(Fl_Offscreen ctx) { + _ss = fl_surface; + fl_display_device->set_current(); + if (stack_ix0) + stack_ix--; + else + fprintf(stderr, "FLTK CGContext Stack underflow error\n"); + if (stack_ixset_current(); +} + +/** @} */ + +extern void fl_restore_clip(); + +#else +# error unsupported platform +#endif + +/** + Forces the window to be redrawn. +*/ +void Fl_Double_Window::flush() {flush(0);} + +/** + Forces the window to be redrawn. + \param[in] eraseoverlay non-zero to erase overlay, zero to ignore + + Fl_Overlay_Window relies on flush(1) copying the back buffer to the + front everywhere, even if damage() == 0, thus erasing the overlay, + and leaving the clip region set to the entire window. +*/ +void Fl_Double_Window::flush(int eraseoverlay) { + make_current(); // make sure fl_gc is non-zero + Fl_X *myi = Fl_X::i(this); + if (!myi->other_xid) { +#if USE_XDBE + if (can_xdbe()) { + myi->other_xid = + XdbeAllocateBackBufferName(fl_display, fl_xid(this), XdbeCopied); + myi->backbuffer_bad = 1; + } else +#endif +#if defined(USE_X11) || defined(WIN32) + myi->other_xid = fl_create_offscreen(w(), h()); + clear_damage(FL_DAMAGE_ALL); +#elif defined(__APPLE_QUARTZ__) + if (force_doublebuffering_) { + myi->other_xid = fl_create_offscreen(w(), h()); + clear_damage(FL_DAMAGE_ALL); + } +#else +# error unsupported platform +#endif + } +#if USE_XDBE + if (use_xdbe) { + if (myi->backbuffer_bad || eraseoverlay) { + // Make sure we do a complete redraw... + if (myi->region) {XDestroyRegion(myi->region); myi->region = 0;} + clear_damage(FL_DAMAGE_ALL); + myi->backbuffer_bad = 0; + } + + // Redraw as needed... + if (damage()) { + fl_clip_region(myi->region); myi->region = 0; + fl_window = myi->other_xid; + draw(); + fl_window = myi->xid; + } + + // Copy contents of back buffer to window... + XdbeSwapInfo s; + s.swap_window = fl_xid(this); + s.swap_action = XdbeCopied; + XdbeSwapBuffers(fl_display, &s, 1); + return; + } else +#endif + if (damage() & ~FL_DAMAGE_EXPOSE) { + fl_clip_region(myi->region); myi->region = 0; +#ifdef WIN32 + HDC _sgc = fl_gc; + fl_gc = fl_makeDC(myi->other_xid); + int save = SaveDC(fl_gc); + fl_restore_clip(); // duplicate region into new gc + draw(); + RestoreDC(fl_gc, save); + DeleteDC(fl_gc); + fl_gc = _sgc; + //# if defined(USE_CAIRO) + //if Fl::cairo_autolink_context() Fl::cairo_make_current(this); // capture gc changes automatically to update the cairo context adequately + //# endif +#elif defined(__APPLE__) + if ( myi->other_xid ) { + fl_begin_offscreen( myi->other_xid ); + fl_clip_region( 0 ); + draw(); + fl_end_offscreen(); + } else { + draw(); + } +#else // X: + fl_window = myi->other_xid; + draw(); + fl_window = myi->xid; +#endif + } + if (eraseoverlay) fl_clip_region(0); + // on Irix (at least) it is faster to reduce the area copied to + // the current clip region: + int X,Y,W,H; fl_clip_box(0,0,w(),h(),X,Y,W,H); + if (myi->other_xid) fl_copy_offscreen(X, Y, W, H, myi->other_xid, X, Y); +} + +void Fl_Double_Window::resize(int X,int Y,int W,int H) { + int ow = w(); + int oh = h(); + Fl_Window::resize(X,Y,W,H); +#if USE_XDBE + if (use_xdbe) { + Fl_X* myi = Fl_X::i(this); + if (myi && myi->other_xid && (ow < w() || oh < h())) { + // STR #2152: Deallocate the back buffer to force creation of a new one. + XdbeDeallocateBackBufferName(fl_display,myi->other_xid); + myi->other_xid = 0; + } + return; + } +#endif + Fl_X* myi = Fl_X::i(this); + if (myi && myi->other_xid && (ow != w() || oh != h())) { + fl_delete_offscreen(myi->other_xid); + myi->other_xid = 0; + } +} + +void Fl_Double_Window::hide() { + Fl_X* myi = Fl_X::i(this); + if (myi && myi->other_xid) { +#if USE_XDBE + if (!use_xdbe) +#endif + fl_delete_offscreen(myi->other_xid); + } + Fl_Window::hide(); +} + +/** + The destructor also deletes all the children. This allows a + whole tree to be deleted at once, without having to keep a pointer to + all the children in the user code. +*/ +Fl_Double_Window::~Fl_Double_Window() { + hide(); +} + +// +// End of "$Id: Fl_Double_Window.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_File_Browser.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_File_Browser.cxx new file mode 100644 index 0000000..1e52251 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_File_Browser.cxx @@ -0,0 +1,643 @@ +// +// "$Id: Fl_File_Browser.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Fl_File_Browser routines. +// +// Copyright 1999-2010 by Michael Sweet. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// +// Contents: +// +// Fl_File_Browser::full_height() - Return the height of the list. +// Fl_File_Browser::item_height() - Return the height of a list item. +// Fl_File_Browser::item_width() - Return the width of a list item. +// Fl_File_Browser::item_draw() - Draw a list item. +// Fl_File_Browser::Fl_File_Browser() - Create a Fl_File_Browser widget. +// Fl_File_Browser::load() - Load a directory into the browser. +// Fl_File_Browser::filter() - Set the filename filter. +// + +// +// Include necessary header files... +// + +#include +#include +#include +#include // icon +#include +#include +#include "flstring.h" + +#ifdef __CYGWIN__ +# include +#elif defined(WIN32) +# include +# include +// Apparently Borland C++ defines DIRECTORY in , which +// interfers with the Fl_File_Icon enumeration of the same name. +# ifdef DIRECTORY +# undef DIRECTORY +# endif // DIRECTORY +#endif // __CYGWIN__ + +#ifdef __EMX__ +# define INCL_DOS +# define INCL_DOSMISC +# include +#endif // __EMX__ + +#if defined(__APPLE__) +# include +# include +# include +#endif // __APPLE__ + +// +// FL_BLINE definition from "Fl_Browser.cxx"... +// + +#define SELECTED 1 +#define NOTDISPLAYED 2 + +// TODO -- Warning: The definition of FL_BLINE here is a hack. +// Fl_File_Browser should not do this. PLEASE FIX. +// FL_BLINE should be private to Fl_Browser, and not re-defined here. +// For now, make sure this struct is precisely consistent with Fl_Browser.cxx. +// +struct FL_BLINE // data is in a linked list of these +{ + FL_BLINE *prev; // Previous item in list + FL_BLINE *next; // Next item in list + void *data; // Pointer to data (function) + Fl_Image *icon; // Pointer to optional icon + short length; // sizeof(txt)-1, may be longer than string + char flags; // selected, displayed + char txt[1]; // start of allocated array +}; + + +// +// 'Fl_File_Browser::full_height()' - Return the height of the list. +// + +int // O - Height in pixels +Fl_File_Browser::full_height() const +{ + int i, // Looping var + th; // Total height of list. + + + for (i = 0, th = 0; i < size(); i ++) + th += item_height(find_line(i)); + + return (th); +} + + +// +// 'Fl_File_Browser::item_height()' - Return the height of a list item. +// + +int // O - Height in pixels +Fl_File_Browser::item_height(void *p) const // I - List item data +{ + FL_BLINE *line; // Pointer to line + char *t; // Pointer into text + int height; // Width of line + int textheight; // Height of text + + + // Figure out the standard text height... + fl_font(textfont(), textsize()); + textheight = fl_height(); + + // We always have at least 1 line... + height = textheight; + + // Scan for newlines... + line = (FL_BLINE *)p; + + if (line != NULL) + for (t = line->txt; *t != '\0'; t ++) + if (*t == '\n') + height += textheight; + + // If we have enabled icons then add space for them... + if (Fl_File_Icon::first() != NULL && height < iconsize_) + height = iconsize_; + + // Add space for the selection border.. + height += 2; + + // Return the height + return (height); +} + + +// +// 'Fl_File_Browser::item_width()' - Return the width of a list item. +// + +int // O - Width in pixels +Fl_File_Browser::item_width(void *p) const // I - List item data +{ + int i; // Looping var + FL_BLINE *line; // Pointer to line + char *t, // Pointer into text + *ptr, // Pointer into fragment + fragment[10240]; // Fragment of text + int width, // Width of line + tempwidth; // Width of fragment + int column; // Current column + const int *columns; // Columns + + + // Scan for newlines... + line = (FL_BLINE *)p; + columns = column_widths(); + + // Set the font and size... + if (line->txt[strlen(line->txt) - 1] == '/') + fl_font(textfont() | FL_BOLD, textsize()); + else + fl_font(textfont(), textsize()); + + if (strchr(line->txt, '\n') == NULL && + strchr(line->txt, column_char()) == NULL) + { + // Do a fast width calculation... + width = (int)fl_width(line->txt); + } + else + { + // More than 1 line or have columns; find the maximum width... + width = 0; + tempwidth = 0; + column = 0; + + for (t = line->txt, ptr = fragment; *t != '\0'; t ++) + if (*t == '\n') + { + // Newline - nul terminate this fragment and get the width... + *ptr = '\0'; + + tempwidth += (int)fl_width(fragment); + + // Update the max width as needed... + if (tempwidth > width) + width = tempwidth; + + // Point back to the start of the fragment... + ptr = fragment; + tempwidth = 0; + column = 0; + } + else if (*t == column_char()) + { + // Advance to the next column... + column ++; + if (columns) + { + for (i = 0, tempwidth = 0; i < column && columns[i]; i ++) + tempwidth += columns[i]; + } + else + tempwidth = column * (int)(fl_height() * 0.6 * 8.0); + + if (tempwidth > width) + width = tempwidth; + + ptr = fragment; + } + else + *ptr++ = *t; + + if (ptr > fragment) + { + // Nul terminate this fragment and get the width... + *ptr = '\0'; + + tempwidth += (int)fl_width(fragment); + + // Update the max width as needed... + if (tempwidth > width) + width = tempwidth; + } + } + + // If we have enabled icons then add space for them... + if (Fl_File_Icon::first() != NULL) + width += iconsize_ + 8; + + // Add space for the selection border.. + width += 2; + + // Return the width + return (width); +} + + +// +// 'Fl_File_Browser::item_draw()' - Draw a list item. +// + +void +Fl_File_Browser::item_draw(void *p, // I - List item data + int X, // I - Upper-lefthand X coordinate + int Y, // I - Upper-lefthand Y coordinate + int W, // I - Width of item + int) const // I - Height of item +{ + int i; // Looping var + FL_BLINE *line; // Pointer to line + Fl_Color c; // Text color + char *t, // Pointer into text + *ptr, // Pointer into fragment + fragment[10240]; // Fragment of text + int width, // Width of line + height; // Height of line + int column; // Current column + const int *columns; // Columns + + + // Draw the list item text... + line = (FL_BLINE *)p; + + if (line->txt[strlen(line->txt) - 1] == '/') + fl_font(textfont() | FL_BOLD, textsize()); + else + fl_font(textfont(), textsize()); + + if (line->flags & SELECTED) + c = fl_contrast(textcolor(), selection_color()); + else + c = textcolor(); + + if (Fl_File_Icon::first() == NULL) + { + // No icons, just draw the text... + X ++; + W -= 2; + } + else + { + // Draw the icon if it is set... + if (line->data) + ((Fl_File_Icon *)line->data)->draw(X, Y, iconsize_, iconsize_, + (line->flags & SELECTED) ? FL_YELLOW : + FL_LIGHT2, + active_r()); + + // Draw the text offset to the right... + X += iconsize_ + 9; + W -= iconsize_ - 10; + + // Center the text vertically... + height = fl_height(); + + for (t = line->txt; *t != '\0'; t ++) + if (*t == '\n') + height += fl_height(); + + if (height < iconsize_) + Y += (iconsize_ - height) / 2; + } + + // Draw the text... + line = (FL_BLINE *)p; + columns = column_widths(); + width = 0; + column = 0; + + if (active_r()) + fl_color(c); + else + fl_color(fl_inactive(c)); + + for (t = line->txt, ptr = fragment; *t != '\0'; t ++) + if (*t == '\n') + { + // Newline - nul terminate this fragment and draw it... + *ptr = '\0'; + + fl_draw(fragment, X + width, Y, W - width, fl_height(), + (Fl_Align)(FL_ALIGN_LEFT | FL_ALIGN_CLIP), 0, 0); + + // Point back to the start of the fragment... + ptr = fragment; + width = 0; + Y += fl_height(); + column = 0; + } + else if (*t == column_char()) + { + // Tab - nul terminate this fragment and draw it... + *ptr = '\0'; + + int cW = W - width; // Clip width... + + if (columns) + { + // Try clipping inside this column... + for (i = 0; i < column && columns[i]; i ++); + + if (columns[i]) + cW = columns[i]; + } + + fl_draw(fragment, X + width, Y, cW, fl_height(), + (Fl_Align)(FL_ALIGN_LEFT | FL_ALIGN_CLIP), 0, 0); + + // Advance to the next column... + column ++; + if (columns) + { + for (i = 0, width = 0; i < column && columns[i]; i ++) + width += columns[i]; + } + else + width = column * (int)(fl_height() * 0.6 * 8.0); + + ptr = fragment; + } + else + *ptr++ = *t; + + if (ptr > fragment) + { + // Nul terminate this fragment and draw it... + *ptr = '\0'; + + fl_draw(fragment, X + width, Y, W - width, fl_height(), + (Fl_Align)(FL_ALIGN_LEFT | FL_ALIGN_CLIP), 0, 0); + } +} + + +// +// 'Fl_File_Browser::Fl_File_Browser()' - Create a Fl_File_Browser widget. +// + +Fl_File_Browser::Fl_File_Browser(int X, // I - Upper-lefthand X coordinate + int Y, // I - Upper-lefthand Y coordinate + int W, // I - Width in pixels + int H, // I - Height in pixels + const char *l) // I - Label text + : Fl_Browser(X, Y, W, H, l) +{ + // Initialize the filter pattern, current directory, and icon size... + pattern_ = "*"; + directory_ = ""; + iconsize_ = (uchar)(3 * textsize() / 2); + filetype_ = FILES; +} + + +// +// 'Fl_File_Browser::load()' - Load a directory into the browser. +// + +int // O - Number of files loaded +Fl_File_Browser::load(const char *directory,// I - Directory to load + Fl_File_Sort_F *sort) // I - Sort function to use +{ + int i; // Looping var + int num_files; // Number of files in directory + int num_dirs; // Number of directories in list + char filename[4096]; // Current file + Fl_File_Icon *icon; // Icon to use + + +// printf("Fl_File_Browser::load(\"%s\")\n", directory); + + clear(); + + directory_ = directory; + + if (!directory) + return (0); + + if (directory_[0] == '\0') + { + // + // No directory specified; for UNIX list all mount points. For DOS + // list all valid drive letters... + // + + num_files = 0; + if ((icon = Fl_File_Icon::find("any", Fl_File_Icon::DEVICE)) == NULL) + icon = Fl_File_Icon::find("any", Fl_File_Icon::DIRECTORY); + +#ifdef WIN32 +# ifdef __CYGWIN__ + // + // Cygwin provides an implementation of setmntent() to get the list + // of available drives... + // + FILE *m = setmntent("/-not-used-", "r"); + struct mntent *p; + + while ((p = getmntent (m)) != NULL) { + add(p->mnt_dir, icon); + num_files ++; + } + + endmntent(m); +# else + // + // Normal WIN32 code uses drive bits... + // + DWORD drives; // Drive available bits + + drives = GetLogicalDrives(); + for (i = 'A'; i <= 'Z'; i ++, drives >>= 1) + if (drives & 1) + { + sprintf(filename, "%c:/", i); + + if (i < 'C') // see also: GetDriveType and GetVolumeInformation in WIN32 + add(filename, icon); + else + add(filename, icon); + + num_files ++; + } +# endif // __CYGWIN__ +#elif defined(__EMX__) + // + // OS/2 code uses drive bits... + // + ULONG curdrive; // Current drive + ULONG drives; // Drive available bits + int start = 3; // 'C' (MRS - dunno if this is correct!) + + + DosQueryCurrentDisk(&curdrive, &drives); + drives >>= start - 1; + for (i = 'A'; i <= 'Z'; i ++, drives >>= 1) + if (drives & 1) + { + sprintf(filename, "%c:/", i); + add(filename, icon); + + num_files ++; + } +#elif defined(__APPLE__) + // MacOS X and Darwin use getfsstat() system call... + int numfs; // Number of file systems + struct statfs *fs; // Buffer for file system info + + + // We always have the root filesystem. + add("/", icon); + + // Get the mounted filesystems... + numfs = getfsstat(NULL, 0, MNT_NOWAIT); + if (numfs > 0) { + // We have file systems, get them... + fs = new struct statfs[numfs]; + getfsstat(fs, sizeof(struct statfs) * numfs, MNT_NOWAIT); + + // Add filesystems to the list... + for (i = 0; i < numfs; i ++) { + // Ignore "/", "/dev", and "/.vol"... + if (fs[i].f_mntonname[1] && strcmp(fs[i].f_mntonname, "/dev") && + strcmp(fs[i].f_mntonname, "/.vol")) { + snprintf(filename, sizeof(filename), "%s/", fs[i].f_mntonname); + add(filename, icon); + } + num_files ++; + } + + // Free the memory used for the file system info array... + delete[] fs; + } +#else + // + // UNIX code uses /etc/fstab or similar... + // + FILE *mtab; // /etc/mtab or /etc/mnttab file + char line[1024]; // Input line + + // + // Open the file that contains a list of mounted filesystems... + // + + mtab = fl_fopen("/etc/mnttab", "r"); // Fairly standard + if (mtab == NULL) + mtab = fl_fopen("/etc/mtab", "r"); // More standard + if (mtab == NULL) + mtab = fl_fopen("/etc/fstab", "r"); // Otherwise fallback to full list + if (mtab == NULL) + mtab = fl_fopen("/etc/vfstab", "r"); // Alternate full list file + + if (mtab != NULL) + { + while (fgets(line, sizeof(line), mtab) != NULL) + { + if (line[0] == '#' || line[0] == '\n') + continue; + if (sscanf(line, "%*s%4095s", filename) != 1) + continue; + + strlcat(filename, "/", sizeof(filename)); + +// printf("Fl_File_Browser::load() - adding \"%s\" to list...\n", filename); + add(filename, icon); + num_files ++; + } + + fclose(mtab); + } +#endif // WIN32 || __EMX__ + } + else + { + dirent **files; // Files in in directory + + + // + // Build the file list... + // + +#if (defined(WIN32) && !defined(__CYGWIN__)) || defined(__EMX__) + strlcpy(filename, directory_, sizeof(filename)); + i = strlen(filename) - 1; + + if (i == 2 && filename[1] == ':' && + (filename[2] == '/' || filename[2] == '\\')) + filename[2] = '/'; + else if (filename[i] != '/' && filename[i] != '\\') + strlcat(filename, "/", sizeof(filename)); + + num_files = fl_filename_list(filename, &files, sort); +#else + num_files = fl_filename_list(directory_, &files, sort); +#endif /* WIN32 || __EMX__ */ + + if (num_files <= 0) + return (0); + + for (i = 0, num_dirs = 0; i < num_files; i ++) { + if (strcmp(files[i]->d_name, "./")) { + snprintf(filename, sizeof(filename), "%s/%s", directory_, + files[i]->d_name); + + icon = Fl_File_Icon::find(filename); + if ((icon && icon->type() == Fl_File_Icon::DIRECTORY) || + _fl_filename_isdir_quick(filename)) { + num_dirs ++; + insert(num_dirs, files[i]->d_name, icon); + } else if (filetype_ == FILES && + fl_filename_match(files[i]->d_name, pattern_)) { + add(files[i]->d_name, icon); + } + } + + free(files[i]); + } + + free(files); + } + + return (num_files); +} + + +// +// 'Fl_File_Browser::filter()' - Set the filename filter. +// + +void +Fl_File_Browser::filter(const char *pattern) // I - Pattern string +{ + // If pattern is NULL set the pattern to "*"... + if (pattern) + pattern_ = pattern; + else + pattern_ = "*"; +} + + +// +// End of "$Id: Fl_File_Browser.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_File_Chooser.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_File_Chooser.cxx new file mode 100644 index 0000000..6c1475e --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_File_Chooser.cxx @@ -0,0 +1,473 @@ +// +// "$Id: Fl_File_Chooser.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Fl_File_Chooser dialog for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// generated by Fast Light User Interface Designer (fluid) version 1.0300 + +#include "../FL/Fl_File_Chooser.H" +#include + +void Fl_File_Chooser::cb_window_i(Fl_Double_Window*, void*) { + fileName->value(""); +fileList->deselect(); +Fl::remove_timeout((Fl_Timeout_Handler)previewCB, this); +window->hide(); +} +void Fl_File_Chooser::cb_window(Fl_Double_Window* o, void* v) { + ((Fl_File_Chooser*)(o->user_data()))->cb_window_i(o,v); +} + +void Fl_File_Chooser::cb_showChoice_i(Fl_Choice*, void*) { + showChoiceCB(); +} +void Fl_File_Chooser::cb_showChoice(Fl_Choice* o, void* v) { + ((Fl_File_Chooser*)(o->parent()->parent()->user_data()))->cb_showChoice_i(o,v); +} + +void Fl_File_Chooser::cb_favoritesButton_i(Fl_Menu_Button*, void*) { + favoritesButtonCB(); +} +void Fl_File_Chooser::cb_favoritesButton(Fl_Menu_Button* o, void* v) { + ((Fl_File_Chooser*)(o->parent()->parent()->user_data()))->cb_favoritesButton_i(o,v); +} + +void Fl_File_Chooser::cb_newButton_i(Fl_Button*, void*) { + newdir(); +} +void Fl_File_Chooser::cb_newButton(Fl_Button* o, void* v) { + ((Fl_File_Chooser*)(o->parent()->parent()->user_data()))->cb_newButton_i(o,v); +} + +#include +static unsigned char idata_new[] = +{0,0,120,0,132,0,2,1,1,254,1,128,49,128,49,128,253,128,253,128,49,128,49, +128,1,128,1,128,255,255,0,0}; +static Fl_Bitmap image_new(idata_new, 16, 16); + +void Fl_File_Chooser::cb__i(Fl_Tile*, void*) { + update_preview(); +} +void Fl_File_Chooser::cb_(Fl_Tile* o, void* v) { + ((Fl_File_Chooser*)(o->parent()->user_data()))->cb__i(o,v); +} + +void Fl_File_Chooser::cb_fileList_i(Fl_File_Browser*, void*) { + fileListCB(); +} +void Fl_File_Chooser::cb_fileList(Fl_File_Browser* o, void* v) { + ((Fl_File_Chooser*)(o->parent()->parent()->user_data()))->cb_fileList_i(o,v); +} + +void Fl_File_Chooser::cb_previewButton_i(Fl_Check_Button*, void*) { + preview(previewButton->value()); +} +void Fl_File_Chooser::cb_previewButton(Fl_Check_Button* o, void* v) { + ((Fl_File_Chooser*)(o->parent()->parent()->parent()->user_data()))->cb_previewButton_i(o,v); +} + +void Fl_File_Chooser::cb_fileName_i(Fl_File_Input*, void*) { + fileNameCB(); +} +void Fl_File_Chooser::cb_fileName(Fl_File_Input* o, void* v) { + ((Fl_File_Chooser*)(o->parent()->parent()->user_data()))->cb_fileName_i(o,v); +} + +void Fl_File_Chooser::cb_okButton_i(Fl_Return_Button*, void*) { + window->hide(); + +// Do any callback that is registered... +if (callback_) + (*callback_)(this, data_); +} +void Fl_File_Chooser::cb_okButton(Fl_Return_Button* o, void* v) { + ((Fl_File_Chooser*)(o->parent()->parent()->parent()->user_data()))->cb_okButton_i(o,v); +} + +void Fl_File_Chooser::cb_cancelButton_i(Fl_Button*, void*) { + fileName->value(""); +fileList->deselect(); +Fl::remove_timeout((Fl_Timeout_Handler)previewCB, this); +window->hide(); +} +void Fl_File_Chooser::cb_cancelButton(Fl_Button* o, void* v) { + ((Fl_File_Chooser*)(o->parent()->parent()->parent()->user_data()))->cb_cancelButton_i(o,v); +} + +void Fl_File_Chooser::cb_favList_i(Fl_File_Browser*, void*) { + favoritesCB(favList); +} +void Fl_File_Chooser::cb_favList(Fl_File_Browser* o, void* v) { + ((Fl_File_Chooser*)(o->parent()->user_data()))->cb_favList_i(o,v); +} + +void Fl_File_Chooser::cb_favUpButton_i(Fl_Button*, void*) { + favoritesCB(favUpButton); +} +void Fl_File_Chooser::cb_favUpButton(Fl_Button* o, void* v) { + ((Fl_File_Chooser*)(o->parent()->parent()->user_data()))->cb_favUpButton_i(o,v); +} + +void Fl_File_Chooser::cb_favDeleteButton_i(Fl_Button*, void*) { + favoritesCB(favDeleteButton); +} +void Fl_File_Chooser::cb_favDeleteButton(Fl_Button* o, void* v) { + ((Fl_File_Chooser*)(o->parent()->parent()->user_data()))->cb_favDeleteButton_i(o,v); +} + +void Fl_File_Chooser::cb_favDownButton_i(Fl_Button*, void*) { + favoritesCB(favDownButton); +} +void Fl_File_Chooser::cb_favDownButton(Fl_Button* o, void* v) { + ((Fl_File_Chooser*)(o->parent()->parent()->user_data()))->cb_favDownButton_i(o,v); +} + +void Fl_File_Chooser::cb_favCancelButton_i(Fl_Button*, void*) { + favWindow->hide(); +} +void Fl_File_Chooser::cb_favCancelButton(Fl_Button* o, void* v) { + ((Fl_File_Chooser*)(o->parent()->parent()->user_data()))->cb_favCancelButton_i(o,v); +} + +void Fl_File_Chooser::cb_favOkButton_i(Fl_Return_Button*, void*) { + favoritesCB(favOkButton); +} +void Fl_File_Chooser::cb_favOkButton(Fl_Return_Button* o, void* v) { + ((Fl_File_Chooser*)(o->parent()->parent()->user_data()))->cb_favOkButton_i(o,v); +} + +Fl_File_Chooser::Fl_File_Chooser(const char *d, const char *p, int t, const char *title) { + Fl_Group *prev_current = Fl_Group::current(); + { window = new Fl_Double_Window(490, 380, "Choose File"); + window->callback((Fl_Callback*)cb_window, (void*)(this)); + { Fl_Group* o = new Fl_Group(10, 10, 470, 25); + { showChoice = new Fl_Choice(65, 10, 215, 25, "Show:"); + showChoice->down_box(FL_BORDER_BOX); + showChoice->labelfont(1); + showChoice->callback((Fl_Callback*)cb_showChoice); + Fl_Group::current()->resizable(showChoice); + showChoice->label(show_label); + } // Fl_Choice* showChoice + { favoritesButton = new Fl_Menu_Button(290, 10, 155, 25, "Favorites"); + favoritesButton->down_box(FL_BORDER_BOX); + favoritesButton->callback((Fl_Callback*)cb_favoritesButton); + favoritesButton->align(Fl_Align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE)); + favoritesButton->label(favorites_label); + } // Fl_Menu_Button* favoritesButton + { Fl_Button* o = newButton = new Fl_Button(455, 10, 25, 25); + newButton->image(image_new); + newButton->labelsize(8); + newButton->callback((Fl_Callback*)cb_newButton); + o->tooltip(new_directory_tooltip); + } // Fl_Button* newButton + o->end(); + } // Fl_Group* o + { Fl_Tile* o = new Fl_Tile(10, 45, 470, 225); + o->callback((Fl_Callback*)cb_); + { fileList = new Fl_File_Browser(10, 45, 295, 225); + fileList->type(2); + fileList->callback((Fl_Callback*)cb_fileList); + fileList->window()->hotspot(fileList); + } // Fl_File_Browser* fileList + { previewBox = new Fl_Box(305, 45, 175, 225, "?"); + previewBox->box(FL_DOWN_BOX); + previewBox->labelsize(100); + previewBox->align(Fl_Align(FL_ALIGN_CLIP|FL_ALIGN_INSIDE)); + } // Fl_Box* previewBox + o->end(); + Fl_Group::current()->resizable(o); + } // Fl_Tile* o + { Fl_Group* o = new Fl_Group(10, 275, 470, 95); + { Fl_Group* o = new Fl_Group(10, 275, 470, 20); + { previewButton = new Fl_Check_Button(10, 275, 73, 20, "Preview"); + previewButton->shortcut(0x80070); + previewButton->down_box(FL_DOWN_BOX); + previewButton->value(1); + previewButton->callback((Fl_Callback*)cb_previewButton); + previewButton->label(preview_label); + } // Fl_Check_Button* previewButton + { Fl_Box* o = new Fl_Box(115, 275, 365, 20); + Fl_Group::current()->resizable(o); + } // Fl_Box* o + o->end(); + } // Fl_Group* o + { fileName = new Fl_File_Input(115, 300, 365, 35); + fileName->labelfont(1); + fileName->callback((Fl_Callback*)cb_fileName); + fileName->when(FL_WHEN_ENTER_KEY); + Fl_Group::current()->resizable(fileName); + fileName->when(FL_WHEN_CHANGED | FL_WHEN_ENTER_KEY); + } // Fl_File_Input* fileName + { Fl_Box* o = new Fl_Box(10, 310, 105, 25, "Filename:"); + o->labelfont(1); + o->align(Fl_Align(FL_ALIGN_RIGHT|FL_ALIGN_INSIDE)); + o->label(filename_label); + } // Fl_Box* o + { Fl_Group* o = new Fl_Group(10, 345, 470, 25); + { okButton = new Fl_Return_Button(313, 345, 85, 25, "OK"); + okButton->callback((Fl_Callback*)cb_okButton); + okButton->label(fl_ok); + } // Fl_Return_Button* okButton + { Fl_Button* o = cancelButton = new Fl_Button(408, 345, 72, 25, "Cancel"); + cancelButton->callback((Fl_Callback*)cb_cancelButton); + o->label(fl_cancel); + } // Fl_Button* cancelButton + { Fl_Box* o = new Fl_Box(10, 345, 30, 25); + Fl_Group::current()->resizable(o); + } // Fl_Box* o + o->end(); + } // Fl_Group* o + o->end(); + } // Fl_Group* o + if (title) window->label(title); + window->set_modal(); + window->end(); + } // Fl_Double_Window* window + { favWindow = new Fl_Double_Window(355, 150, "Manage Favorites"); + favWindow->user_data((void*)(this)); + { favList = new Fl_File_Browser(10, 10, 300, 95); + favList->type(2); + favList->callback((Fl_Callback*)cb_favList); + Fl_Group::current()->resizable(favList); + } // Fl_File_Browser* favList + { Fl_Group* o = new Fl_Group(320, 10, 25, 95); + { favUpButton = new Fl_Button(320, 10, 25, 25, "@8>"); + favUpButton->callback((Fl_Callback*)cb_favUpButton); + } // Fl_Button* favUpButton + { favDeleteButton = new Fl_Button(320, 45, 25, 25, "X"); + favDeleteButton->labelfont(1); + favDeleteButton->callback((Fl_Callback*)cb_favDeleteButton); + Fl_Group::current()->resizable(favDeleteButton); + } // Fl_Button* favDeleteButton + { favDownButton = new Fl_Button(320, 80, 25, 25, "@2>"); + favDownButton->callback((Fl_Callback*)cb_favDownButton); + } // Fl_Button* favDownButton + o->end(); + } // Fl_Group* o + { Fl_Group* o = new Fl_Group(10, 113, 335, 29); + { favCancelButton = new Fl_Button(273, 115, 72, 25, "Cancel"); + favCancelButton->callback((Fl_Callback*)cb_favCancelButton); + favCancelButton->label(fl_cancel); + } // Fl_Button* favCancelButton + { favOkButton = new Fl_Return_Button(181, 115, 79, 25, "Save"); + favOkButton->callback((Fl_Callback*)cb_favOkButton); + favOkButton->label(save_label); + } // Fl_Return_Button* favOkButton + { Fl_Box* o = new Fl_Box(10, 115, 161, 25); + Fl_Group::current()->resizable(o); + } // Fl_Box* o + o->end(); + } // Fl_Group* o + favWindow->label(manage_favorites_label); + favWindow->set_modal(); + favWindow->size_range(181, 150); + favWindow->end(); + } // Fl_Double_Window* favWindow + callback_ = 0; +data_ = 0; +directory_[0] = 0; +window->size_range(window->w(), window->h(), Fl::w(), Fl::h()); +type(t); +filter(p); +update_favorites(); +value(d); +type(t); +int e; +prefs_.get("preview", e, 1); +preview(e); +Fl_Group::current(prev_current); + ext_group=(Fl_Widget*)0; +} + +Fl_File_Chooser::~Fl_File_Chooser() { + Fl::remove_timeout((Fl_Timeout_Handler)previewCB, this); +if(ext_group)window->remove(ext_group); +delete window; +delete favWindow; +} + +void Fl_File_Chooser::callback(void (*cb)(Fl_File_Chooser *, void *), void *d ) { + callback_ = cb; +data_ = d; +} + +void Fl_File_Chooser::color(Fl_Color c) { + fileList->color(c); +} + +Fl_Color Fl_File_Chooser::color() { + return (fileList->color()); +} + +char * Fl_File_Chooser::directory() { + return directory_; +} + +const char * Fl_File_Chooser::filter() { + return (fileList->filter()); +} + +int Fl_File_Chooser::filter_value() { + return showChoice->value(); +} + +void Fl_File_Chooser::filter_value(int f) { + showChoice->value(f); +showChoiceCB(); +} + +void Fl_File_Chooser::hide() { + window->hide(); +} + +void Fl_File_Chooser::iconsize(uchar s) { + fileList->iconsize(s); +} + +uchar Fl_File_Chooser::iconsize() { + return (fileList->iconsize()); +} + +void Fl_File_Chooser::label(const char *l) { + window->label(l); +} + +const char * Fl_File_Chooser::label() { + return (window->label()); +} + +void Fl_File_Chooser::ok_label(const char *l) { + okButton->label(l); +int w=0, h=0; +okButton->measure_label(w, h); +okButton->resize(cancelButton->x() - 50 - w, cancelButton->y(), + w + 40, 25); +okButton->parent()->init_sizes(); +} + +const char * Fl_File_Chooser::ok_label() { + return (okButton->label()); +} + +void Fl_File_Chooser::show() { + window->hotspot(fileList); +window->show(); +Fl::flush(); +fl_cursor(FL_CURSOR_WAIT); +rescan_keep_filename(); +fl_cursor(FL_CURSOR_DEFAULT); +fileName->take_focus(); +} + +int Fl_File_Chooser::shown() { + return window->shown(); +} + +void Fl_File_Chooser::textcolor(Fl_Color c) { + fileList->textcolor(c); +} + +Fl_Color Fl_File_Chooser::textcolor() { + return (fileList->textcolor()); +} + +void Fl_File_Chooser::textfont(Fl_Font f) { + fileList->textfont(f); +} + +Fl_Font Fl_File_Chooser::textfont() { + return (fileList->textfont()); +} + +void Fl_File_Chooser::textsize(Fl_Fontsize s) { + fileList->textsize(s); +} + +Fl_Fontsize Fl_File_Chooser::textsize() { + return (fileList->textsize()); +} + +void Fl_File_Chooser::type(int t) { + type_ = t; +if (t & MULTI) + fileList->type(FL_MULTI_BROWSER); +else + fileList->type(FL_HOLD_BROWSER); +if (t & CREATE) + newButton->activate(); +else + newButton->deactivate(); +if (t & DIRECTORY) + fileList->filetype(Fl_File_Browser::DIRECTORIES); +else + fileList->filetype(Fl_File_Browser::FILES); +} + +int Fl_File_Chooser::type() { + return (type_); +} + +void * Fl_File_Chooser::user_data() const { + return (data_); +} + +void Fl_File_Chooser::user_data(void *d) { + data_ = d; +} + +int Fl_File_Chooser::visible() { + return window->visible(); +} + +Fl_Widget* Fl_File_Chooser::add_extra(Fl_Widget* gr) { + Fl_Widget* ret=ext_group; + if (gr==ext_group) { + return ret; + } + if (ext_group) { + int sh=ext_group->h()+4; +Fl_Widget* svres=window->resizable(); +window->resizable(NULL); +window->size(window->w(),window->h()-sh); +window->remove(ext_group); +ext_group=NULL; +window->resizable(svres); + } + if (gr) { + int nh=window->h()+gr->h()+4; +Fl_Widget* svres=window->resizable(); +window->resizable(NULL); +window->size(window->w(),nh); +gr->position(2,okButton->y()+okButton->h()+2); +window->add(gr); +ext_group=gr; +window->resizable(svres); + } + return ret; +} + +// +// End of "$Id: Fl_File_Chooser.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_File_Chooser.fl b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_File_Chooser.fl new file mode 100644 index 0000000..8471641 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_File_Chooser.fl @@ -0,0 +1,474 @@ +# data file for the Fltk User Interface Designer (fluid) +version 1.0300 +header_name {../FL/Fl_File_Chooser.H} +code_name {.cxx} +comment {// +// "$Id: Fl_File_Chooser.fl 6678 2009-03-13 23:36:09Z AlbrechtS $" +// +// Fl_File_Chooser dialog for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2009 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// +} {in_source in_header +} + +decl {\#include } {} + +class FL_EXPORT Fl_File_Chooser {open +} { + decl {enum { SINGLE = 0, MULTI = 1, CREATE = 2, DIRECTORY = 4 };} {public + } + decl {static Fl_Preferences prefs_;} {} + decl {void (*callback_)(Fl_File_Chooser*, void *);} {} + decl {void *data_;} {} + decl {char directory_[1024];} {} + decl {char pattern_[1024];} {} + decl {char preview_text_[2048];} {} + decl {int type_;} {} + decl {void favoritesButtonCB();} {} + decl {void favoritesCB(Fl_Widget *w);} {} + decl {void fileListCB();} {} + decl {void fileNameCB();} {} + decl {void newdir();} {} + decl {static void previewCB(Fl_File_Chooser *fc);} {} + decl {void showChoiceCB();} {} + decl {void update_favorites();} {} + decl {void update_preview();} {} + Function {Fl_File_Chooser(const char *d, const char *p, int t, const char *title)} {} { + code {Fl_Group *prev_current = Fl_Group::current();} {} + Fl_Window window { + label {Choose File} + callback {fileName->value(""); +fileList->deselect(); +Fl::remove_timeout((Fl_Timeout_Handler)previewCB, this); +window->hide();} open + private xywh {507 327 490 380} type Double resizable + code0 {if (title) window->label(title);} + code1 {\#include } + code2 {\#include } + code3 {\#include } modal visible + } { + Fl_Group {} {open + private xywh {10 10 470 25} + } { + Fl_Choice showChoice { + label {Show:} + callback {showChoiceCB();} open + private xywh {65 10 215 25} down_box BORDER_BOX labelfont 1 resizable + code0 {showChoice->label(show_label);} + } {} + Fl_Menu_Button favoritesButton { + label Favorites + callback {favoritesButtonCB();} open + private xywh {290 10 155 25} down_box BORDER_BOX align 20 + code0 {favoritesButton->label(favorites_label);} + } {} + Fl_Button newButton { + callback {newdir();} + image {new.xbm} xywh {455 10 25 25} labelsize 8 + code0 {\#include } + code1 {o->tooltip(new_directory_tooltip);} + } + } + Fl_Tile {} { + callback {update_preview();} + private xywh {10 45 470 225} resizable + } { + Fl_File_Browser fileList { + callback {fileListCB();} + private xywh {10 45 295 225} type Hold hotspot + code0 {\#include } + } + Fl_Box previewBox { + label {?} + private xywh {305 45 175 225} box DOWN_BOX labelsize 100 align 80 + } + } + Fl_Group {} {open + private xywh {10 275 470 95} + } { + Fl_Group {} {open + private xywh {10 275 470 20} + } { + Fl_Check_Button previewButton { + label Preview + callback {preview(previewButton->value());} + xywh {10 275 73 20} down_box DOWN_BOX shortcut 0x80070 value 1 + code0 {previewButton->label(preview_label);} + } + Fl_Box {} { + private xywh {115 275 365 20} resizable + } + } + Fl_File_Input fileName { + callback {fileNameCB();} + private xywh {115 300 365 35} labelfont 1 when 8 resizable + code0 {fileName->when(FL_WHEN_CHANGED | FL_WHEN_ENTER_KEY);} + } + Fl_Box {} { + label {Filename:} + private xywh {10 310 105 25} labelfont 1 align 24 + code0 {o->label(filename_label);} + } + Fl_Group {} {open + private xywh {10 345 470 25} + } { + Fl_Return_Button okButton { + label OK + callback {window->hide(); + +// Do any callback that is registered... +if (callback_) + (*callback_)(this, data_);} + private xywh {313 345 85 25} + code0 {\#include } + code1 {okButton->label(fl_ok);} + } + Fl_Button cancelButton { + label Cancel + callback {fileName->value(""); +fileList->deselect(); +Fl::remove_timeout((Fl_Timeout_Handler)previewCB, this); +window->hide();} + private xywh {408 345 72 25} + code0 {o->label(fl_cancel);} + } + Fl_Box {} { + private xywh {10 345 30 25} resizable + } + } + } + } + Fl_Window favWindow { + label {Manage Favorites} + private xywh {413 100 355 150} type Double resizable + code0 {favWindow->label(manage_favorites_label);} modal size_range {181 150 0 0} visible + } { + Fl_File_Browser favList { + callback {favoritesCB(favList);} + private xywh {10 10 300 95} type Hold resizable + } + Fl_Group {} {open + xywh {320 10 25 95} + } { + Fl_Button favUpButton { + label {@8>} + callback {favoritesCB(favUpButton);} + private xywh {320 10 25 25} + } + Fl_Button favDeleteButton { + label X + callback {favoritesCB(favDeleteButton);} + private xywh {320 45 25 25} labelfont 1 resizable + } + Fl_Button favDownButton { + label {@2>} + callback {favoritesCB(favDownButton);} + private xywh {320 80 25 25} + } + } + Fl_Group {} {open + xywh {10 113 335 29} + } { + Fl_Button favCancelButton { + label Cancel + callback {favWindow->hide();} + private xywh {273 115 72 25} + code0 {favCancelButton->label(fl_cancel);} + } + Fl_Return_Button favOkButton { + label Save + callback {favoritesCB(favOkButton);} + private xywh {181 115 79 25} + code0 {\#include } + code1 {favOkButton->label(save_label);} + } + Fl_Box {} { + xywh {10 115 161 25} resizable + } + } + } + code {callback_ = 0; +data_ = 0; +directory_[0] = 0; +window->size_range(window->w(), window->h(), Fl::w(), Fl::h()); +type(t); +filter(p); +update_favorites(); +value(d); +type(t); +int e; +prefs_.get("preview", e, 1); +preview(e); +Fl_Group::current(prev_current);} {} + code {ext_group=(Fl_Widget*)0;} {} + } + Function {~Fl_File_Chooser()} {open + } { + code {Fl::remove_timeout((Fl_Timeout_Handler)previewCB, this); +if(ext_group)window->remove(ext_group); +delete window; +delete favWindow;} {} + } + Function {callback(void (*cb)(Fl_File_Chooser *, void *), void *d = 0)} {return_type void + } { + code {callback_ = cb; +data_ = d;} {} + } + Function {color(Fl_Color c)} {} { + code {fileList->color(c);} {} + } + Function {color()} {return_type Fl_Color + } { + code {return (fileList->color());} {} + } + decl {int count();} {public + } + decl {void directory(const char *d);} {public + } + Function {directory()} {return_type {char *} + } { + code {return directory_;} {} + } + decl {void filter(const char *p);} {public + } + Function {filter()} {return_type {const char *} + } { + code {return (fileList->filter());} {} + } + Function {filter_value()} {return_type int + } { + code {return showChoice->value();} {} + } + Function {filter_value(int f)} {return_type void + } { + code {showChoice->value(f); +showChoiceCB();} {} + } + Function {hide()} {return_type void + } { + code {window->hide();} {} + } + Function {iconsize(uchar s)} {return_type void + } { + code {fileList->iconsize(s);} {} + } + Function {iconsize()} {return_type uchar + } { + code {return (fileList->iconsize());} {} + } + Function {label(const char *l)} {return_type void + } { + code {window->label(l);} {} + } + Function {label()} {return_type {const char *} + } { + code {return (window->label());} {} + } + Function {ok_label(const char *l)} {return_type void + } { + code {okButton->label(l); +int w=0, h=0; +okButton->measure_label(w, h); +okButton->resize(cancelButton->x() - 50 - w, cancelButton->y(), + w + 40, 25); +okButton->parent()->init_sizes();} {} + } + Function {ok_label()} {return_type {const char *} + } { + code {return (okButton->label());} {} + } + decl {void preview(int e);} {public + } + decl {int preview() const { return previewButton->value(); }} {public + } + decl {void rescan();} {public + } + decl {void rescan_keep_filename();} {public + } + Function {show()} {open return_type void + } { + code {window->hotspot(fileList); +window->show(); +Fl::flush(); +fl_cursor(FL_CURSOR_WAIT); +rescan_keep_filename(); +fl_cursor(FL_CURSOR_DEFAULT); +fileName->take_focus();} {} + } + Function {shown()} {return_type int + } { + code {return window->shown();} {} + } + Function {textcolor(Fl_Color c)} {return_type void + } { + code {fileList->textcolor(c);} {} + } + Function {textcolor()} {return_type Fl_Color + } { + code {return (fileList->textcolor());} {} + } + Function {textfont(Fl_Font f)} {return_type void + } { + code {fileList->textfont(f);} {} + } + Function {textfont()} {selected return_type Fl_Font + } { + code {return (fileList->textfont());} {} + } + Function {textsize(Fl_Fontsize s)} {return_type void + } { + code {fileList->textsize(s);} {} + } + Function {textsize()} {return_type Fl_Fontsize + } { + code {return (fileList->textsize());} {} + } + Function {type(int t)} {return_type void + } { + code {type_ = t; +if (t & MULTI) + fileList->type(FL_MULTI_BROWSER); +else + fileList->type(FL_HOLD_BROWSER); +if (t & CREATE) + newButton->activate(); +else + newButton->deactivate(); +if (t & DIRECTORY) + fileList->filetype(Fl_File_Browser::DIRECTORIES); +else + fileList->filetype(Fl_File_Browser::FILES);} {} + } + Function {type()} {return_type int + } { + code {return (type_);} {} + } + Function {user_data() const} {return_type {void *} + } { + code {return (data_);} {} + } + Function {user_data(void *d)} {return_type void + } { + code {data_ = d;} {} + } + decl {const char *value(int f = 1);} {public + } + decl {void value(const char *filename);} {public + } + Function {visible()} {return_type int + } { + code {return window->visible();} {} + } + decl {static const char *add_favorites_label;} { + comment {[standard text may be customized at run-time]} public + } + decl {static const char *all_files_label;} { + comment {[standard text may be customized at run-time]} public + } + decl {static const char *custom_filter_label;} { + comment {[standard text may be customized at run-time]} public + } + decl {static const char *existing_file_label;} { + comment {[standard text may be customized at run-time]} public + } + decl {static const char *favorites_label;} { + comment {[standard text may be customized at run-time]} public + } + decl {static const char *filename_label;} { + comment {[standard text may be customized at run-time]} public + } + decl {static const char *filesystems_label;} { + comment {[standard text may be customized at run-time]} public + } + decl {static const char *manage_favorites_label;} { + comment {[standard text may be customized at run-time]} public + } + decl {static const char *new_directory_label;} { + comment {[standard text may be customized at run-time]} public + } + decl {static const char *new_directory_tooltip;} { + comment {[standard text may be customized at run-time]} public + } + decl {static const char *preview_label;} { + comment {[standard text may be customized at run-time]} public + } + decl {static const char *save_label;} { + comment {[standard text may be customized at run-time]} public + } + decl {static const char *show_label;} { + comment {[standard text may be customized at run-time]} public + } + decl {static Fl_File_Sort_F *sort;} { + comment {the sort function that is used when loading +the contents of a directory.} public + } + decl {Fl_Widget* ext_group;} {} + Function {add_extra(Fl_Widget* gr)} {open return_type {Fl_Widget*} + } { + code {Fl_Widget* ret=ext_group;} {} + codeblock {if (gr==ext_group)} {open + } { + code {return ret;} {} + } + codeblock {if (ext_group)} {open + } { + code {int sh=ext_group->h()+4; +Fl_Widget* svres=window->resizable(); +window->resizable(NULL); +window->size(window->w(),window->h()-sh); +window->remove(ext_group); +ext_group=NULL; +window->resizable(svres);} {} + } + codeblock {if (gr)} {open + } { + code {int nh=window->h()+gr->h()+4; +Fl_Widget* svres=window->resizable(); +window->resizable(NULL); +window->size(window->w(),nh); +gr->position(2,okButton->y()+okButton->h()+2); +window->add(gr); +ext_group=gr; +window->resizable(svres);} {} + } + code {return ret;} {} + } +} + +decl {FL_EXPORT char *fl_dir_chooser(const char *message,const char *fname,int relative=0);} {public +} + +decl {FL_EXPORT char *fl_file_chooser(const char *message,const char *pat,const char *fname,int relative=0);} {public +} + +decl {FL_EXPORT void fl_file_chooser_callback(void (*cb)(const char*));} {public +} + +decl {FL_EXPORT void fl_file_chooser_ok_label(const char*l);} {public +} + +comment { +// +// End of "$Id: Fl_File_Chooser.fl 6678 2009-03-13 23:36:09Z AlbrechtS $". +//} {in_source in_header +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_File_Chooser2.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_File_Chooser2.cxx new file mode 100644 index 0000000..68d79fc --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_File_Chooser2.cxx @@ -0,0 +1,1655 @@ +// +// "$Id: Fl_File_Chooser2.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// More Fl_File_Chooser routines. +// +// Copyright 1999-2010 by Michael Sweet. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// fabien: ATTENTION: Only Out Of Source Gen. because cxx/H files are autogenerated by fluid. +/** \defgroup group_comdlg Common Dialogs classes and functions + @{ +*/ +/** \class Fl_File_Chooser + The Fl_File_Chooser widget displays a standard file selection + dialog that supports various selection modes. + + \image html Fl_File_Chooser.jpg + \image latex Fl_File_Chooser.eps "Fl_File_Chooser" width=12cm + + The Fl_File_Chooser class also exports several static values + that may be used to localize or customize the appearance of all file chooser + dialogs: + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MemberDefault value
add_favorites_label"Add to Favorites"
all_files_label"All Files (*)"
custom_filter_label"Custom Filter"
existing_file_label"Please choose an existing file!"
favorites_label"Favorites"
filename_label"Filename:"
filesystems_label"My Computer" (WIN32)
+ "File Systems" (all others)
manage_favorites_label"Manage Favorites"
new_directory_label"New Directory?"
new_directory_tooltip"Create a new directory."
preview_label"Preview"
save_label"Save"
show_label"Show:"
sortfl_numericsort
+ + The Fl_File_Chooser::sort member specifies the sort function that is + used when loading the contents of a directory and can be customized + at run-time. + + The Fl_File_Chooser class also exports the Fl_File_Chooser::newButton + and Fl_File_Chooser::previewButton widgets so that application developers + can control their appearance and use. For more complex customization, + consider copying the FLTK file chooser code and changing it accordingly. +*/ +/** @} */ + +/** \fn Fl_File_Chooser::Fl_File_Chooser(const char *pathname, const char *pattern, int type, const char *title) + The constructor creates the Fl_File_Chooser dialog shown. + The pathname argument can be a directory name or a + complete file name (in which case the corresponding file is highlighted + in the list and in the filename input field.) + + The pattern argument can be a NULL + string or "*" to list all files, or it can be a + series of descriptions and filter strings separated by tab + characters (\\t). The format of filters is either + "Description text (patterns)" or just "patterns". A file chooser + that provides filters for HTML and image files might look like: + + \code + "HTML Files (*.html)\tImage Files (*.{bmp,gif,jpg,png})" + \endcode + + The file chooser will automatically add the "All Files (*)" + pattern to the end of the string you pass if you do not provide + one. The first filter in the string is the default filter. + + See the FLTK documentation on fl_filename_match() + for the kinds of pattern strings that are supported. + + The type argument can be one of the following: + + \li \c SINGLE - allows the user to select a single, existing file. + \li \c MULTI - allows the user to select one or more existing files. + \li \c CREATE - allows the user to select a single, existing file or + specify a new filename. + \li \c DIRECTORY - allows the user to select a single, existing directory. + + The title argument is used to set the title bar text for the + Fl_File_Chooser window. +*/ + +/** \var Fl_File_Chooser::newButton + The "new directory" button is exported so that application developers + can control the appearance and use. +*/ + +/** \var Fl_File_Chooser::previewButton + The "preview" button is exported so that application developers can + control the appearance and use. +*/ + +/** \fn Fl_File_Chooser::~Fl_File_Chooser() + Destroys the widget and frees all memory used by it.*/ + +/** \fn void Fl_File_Chooser::color(Fl_Color c) + Sets or gets the background color of the Fl_File_Browser list.*/ + +/** \fn Fl_Color Fl_File_Chooser::color() + Sets or gets the background color of the Fl_File_Browser list.*/ + +/** \fn int Fl_File_Chooser::count() + Returns the number of selected files.*/ + +/** \fn void Fl_File_Chooser::directory(const char *pathname) + Sets or gets the current directory.*/ + +/** \fn const char *Fl_File_Chooser::directory() + Sets or gets the current directory.*/ + +/** \fn void Fl_File_Chooser::filter(const char *pattern) + Sets or gets the current filename filter patterns. The filter + patterns use fl_filename_match(). + Multiple patterns can be used by separating them with tabs, like + "*.jpg\t*.png\t*.gif\t*". In addition, you can provide + human-readable labels with the patterns inside parenthesis, like + "JPEG Files (*.jpg)\tPNG Files (*.png)\tGIF Files (*.gif)\tAll Files (*)" + . + + Use filter(NULL) to show all files. +*/ + +/** \fn const char *Fl_File_Chooser::filter() + See void filter(const char *pattern)*/ + +/** \fn void Fl_File_Chooser::filter_value(int f) + Sets or gets the current filename filter selection.*/ + +/** \fn int Fl_File_Chooser::filter_value() + Sets or gets the current filename filter selection.*/ + +/** \fn void Fl_File_Chooser::hide() + Hides the Fl_File_Chooser window.*/ + +/** \fn void Fl_File_Chooser::iconsize(uchar s) + Sets or gets the size of the icons in the Fl_File_Browser. By + default the icon size is set to 1.5 times the textsize(). +*/ + +/** \fn uchar Fl_File_Chooser::iconsize() + Sets or gets the size of the icons in the Fl_File_Browser. By + default the icon size is set to 1.5 times the textsize(). +*/ + +/** \fn void Fl_File_Chooser::label(const char *l) + Sets or gets the title bar text for the Fl_File_Chooser.*/ + +/** \fn const char *Fl_File_Chooser::label() + Sets or gets the title bar text for the Fl_File_Chooser.*/ + +/** \fn void Fl_File_Chooser::ok_label(const char *l) + Sets or gets the label for the "ok" button in the Fl_File_Chooser. +*/ + +/** \fn const char *Fl_File_Chooser::ok_label() + Sets or gets the label for the "ok" button in the Fl_File_Chooser. +*/ + +/** \fn int Fl_File_Chooser::preview() const + Returns the current state of the preview box. */ + +/** \fn void Fl_File_Chooser::rescan() + Reloads the current directory in the Fl_File_Browser.*/ + +/** \fn void Fl_File_Chooser::show() + Shows the Fl_File_Chooser window.*/ + +/** \fn void Fl_File_Chooser::textcolor(Fl_Color c) + Sets or gets the current Fl_File_Browser text color.*/ + +/** \fn Fl_Color Fl_File_Chooser::textcolor() + Sets or gets the current Fl_File_Browser text color.*/ + +/** \fn void Fl_File_Chooser::textfont(Fl_Font f) + Sets or gets the current Fl_File_Browser text font.*/ + +/** \fn Fl_Font Fl_File_Chooser::textfont() + Sets or gets the current Fl_File_Browser text font.*/ + +/** \fn void Fl_File_Chooser::textsize(Fl_Fontsize s) + Sets or gets the current Fl_File_Browser text size.*/ + +/** \fn Fl_Fontsize Fl_File_Chooser::textsize() + Sets or gets the current Fl_File_Browser text size.*/ + +/** \fn void Fl_File_Chooser::type(int t) + Sets or gets the current type of Fl_File_Chooser.*/ + +/** \fn int Fl_File_Chooser::type() + Sets or gets the current type of Fl_File_Chooser.*/ + +/** \fn const char *Fl_File_Chooser::value(const char *pathname) + Sets or gets the current value of the selected file. + + In the second form, \p file is a \c 1-based index into a list of + file names. The number of selected files is returned by + Fl_File_Chooser::count(). + + This sample code loops through all selected files: + \code + // Get list of filenames user selected from a MULTI chooser + for ( int t=1; t<=chooser->count(); t++ ) { + const char *filename = chooser->value(t); + ... + } + \endcode +*/ + +/** \fn const char *Fl_File_Chooser::value(int file) + See const char *value(const char *pathname)*/ + +/** \fn int Fl_File_Chooser::visible() + Returns 1 if the Fl_File_Chooser window is visible.*/ + +/** \fn Fl_Widget* Fl_File_Chooser::add_extra(Fl_Widget*) + Adds extra widget at the bottom of Fl_File_Chooser window. + Returns pointer for previous extra widget or NULL if not set previously. + If argument is NULL only remove previous extra widget. + + \note Fl_File_Chooser does \b not delete extra widget in destructor! + To prevent memory leakage, don't forget to delete unused extra widgets +*/ + /** \fn int Fl_File_Chooser::shown() + Returns non-zero if the file chooser main window show() has been called (but not hide() + see Fl_Window::shown() + */ + + /** \fn void Fl_File_Chooser::callback(void (*cb)(Fl_File_Chooser *, void *), void *d = 0) + Sets the file chooser callback cb and associated data d */ + + /** \fn void Fl_File_Chooser::user_data(void *d) + Sets the file chooser user data d */ + + /** \fn void * Fl_File_Chooser::user_data() const + Gets the file chooser user data d */ + + /** \fn Fl_File_Browser* Fl_File_Chooser::browser() + returns a pointer to the underlying Fl_File_Browser object */ +// *** END OF OUT OF SOURCE DOC *** + +// Contents: +// +// Fl_File_Chooser::count() - Return the number of selected files. +// Fl_File_Chooser::directory() - Set the directory in the file chooser. +// Fl_File_Chooser::filter() - Set the filter(s) for the chooser. +// Fl_File_Chooser::newdir() - Make a new directory. +// Fl_File_Chooser::value() - Return a selected filename. +// Fl_File_Chooser::rescan() - Rescan the current directory. +// Fl_File_Chooser::favoritesButtonCB() - Handle favorites selections. +// Fl_File_Chooser::fileListCB() - Handle clicks (and double-clicks) +// in the Fl_File_Browser. +// Fl_File_Chooser::fileNameCB() - Handle text entry in the FileBrowser. +// Fl_File_Chooser::showChoiceCB() - Handle show selections. +// compare_dirnames() - Compare two directory names. +// quote_pathname() - Quote a pathname for a menu. +// unquote_pathname() - Unquote a pathname from a menu. +// +// Fl_File_Chooser::add_extra() - add extra widget at the bottom, return pointer +// to previous extra widget or NULL if none, +// If argument is NULL extra widget removed. +// NOTE! file chooser does't delete extra widget in +// destructor! To prevent memory leakage don't forget +// delete unused extra widgets by yourself. +// + +// +// Include necessary headers. +// + +#include +#include +#include +#include +#include + +#include +#include +#include "flstring.h" +#include +#include +#include + +#if defined(WIN32) && ! defined (__CYGWIN__) +# include +# include +// Visual C++ 2005 incorrectly displays a warning about the use of POSIX APIs +// on Windows, which is supposed to be POSIX compliant... +# define access _access +# define mkdir _mkdir +// Apparently Borland C++ defines DIRECTORY in , which +// interfers with the Fl_File_Icon enumeration of the same name. +# ifdef DIRECTORY +# undef DIRECTORY +# endif // DIRECTORY +#else +# include +# include +#endif /* WIN32 */ + + +// +// File chooser label strings and sort function... +// + +Fl_Preferences Fl_File_Chooser::prefs_(Fl_Preferences::USER, "fltk.org", "filechooser"); + +const char *Fl_File_Chooser::add_favorites_label = "Add to Favorites"; +const char *Fl_File_Chooser::all_files_label = "All Files (*)"; +const char *Fl_File_Chooser::custom_filter_label = "Custom Filter"; +const char *Fl_File_Chooser::existing_file_label = "Please choose an existing file!"; +const char *Fl_File_Chooser::favorites_label = "Favorites"; +const char *Fl_File_Chooser::filename_label = "Filename:"; +#ifdef WIN32 +const char *Fl_File_Chooser::filesystems_label = "My Computer"; +#else +const char *Fl_File_Chooser::filesystems_label = "File Systems"; +#endif // WIN32 +const char *Fl_File_Chooser::manage_favorites_label = "Manage Favorites"; +const char *Fl_File_Chooser::new_directory_label = "New Directory?"; +const char *Fl_File_Chooser::new_directory_tooltip = "Create a new directory."; +const char *Fl_File_Chooser::preview_label = "Preview"; +const char *Fl_File_Chooser::save_label = "Save"; +const char *Fl_File_Chooser::show_label = "Show:"; +Fl_File_Sort_F *Fl_File_Chooser::sort = fl_numericsort; + + +// +// Local functions... +// + +static int compare_dirnames(const char *a, const char *b); +static void quote_pathname(char *, const char *, int); +static void unquote_pathname(char *, const char *, int); + + +// +// 'Fl_File_Chooser::count()' - Return the number of selected files. +// + +int // O - Number of selected files +Fl_File_Chooser::count() { + int i; // Looping var + int fcount; // Number of selected files + const char *filename; // Filename in input field or list + + + filename = fileName->value(); + + if (!(type_ & MULTI)) { + // Check to see if the file name input field is blank... + if (!filename || !filename[0]) return 0; + else return 1; + } + + for (i = 1, fcount = 0; i <= fileList->size(); i ++) + if (fileList->selected(i)) { + // See if this file is a directory... + // matt: why would we do that? It is perfectly legal to select multiple + // directories in a DIR chooser. They are visually selected and value(i) + // returns all of them as expected + //filename = (char *)fileList->text(i); + + //if (filename[strlen(filename) - 1] != '/') + fcount ++; + } + + if (fcount) return fcount; + else if (!filename || !filename[0]) return 0; + else return 1; +} + + +// +// 'Fl_File_Chooser::directory()' - Set the directory in the file chooser. +// + +void +Fl_File_Chooser::directory(const char *d)// I - Directory to change to +{ + char *dirptr; // Pointer into directory + + +// printf("Fl_File_Chooser::directory(\"%s\")\n", d == NULL ? "(null)" : d); + + // NULL == current directory + if (d == NULL) + d = "."; + +#ifdef WIN32 + // See if the filename contains backslashes... + char *slash; // Pointer to slashes + char fixpath[1024]; // Path with slashes converted + if (strchr(d, '\\')) { + // Convert backslashes to slashes... + strlcpy(fixpath, d, sizeof(fixpath)); + + for (slash = strchr(fixpath, '\\'); slash; slash = strchr(slash + 1, '\\')) + *slash = '/'; + + d = fixpath; + } +#endif // WIN32 + + if (d[0] != '\0') + { + // Make the directory absolute... +#if (defined(WIN32) && ! defined(__CYGWIN__))|| defined(__EMX__) + if (d[0] != '/' && d[0] != '\\' && d[1] != ':') +#else + if (d[0] != '/' && d[0] != '\\') +#endif /* WIN32 || __EMX__ */ + fl_filename_absolute(directory_, d); + else + strlcpy(directory_, d, sizeof(directory_)); + + // Strip any trailing slash... + dirptr = directory_ + strlen(directory_) - 1; + if ((*dirptr == '/' || *dirptr == '\\') && dirptr > directory_) + *dirptr = '\0'; + + // See if we have a trailing .. or . in the filename... + dirptr = directory_ + strlen(directory_) - 3; + if (dirptr >= directory_ && strcmp(dirptr, "/..") == 0) { + // Yes, we have "..", so strip the trailing path... + *dirptr = '\0'; + while (dirptr > directory_) { + if (*dirptr == '/') break; + dirptr --; + } + + if (dirptr >= directory_ && *dirptr == '/') + *dirptr = '\0'; + } else if ((dirptr + 1) >= directory_ && strcmp(dirptr + 1, "/.") == 0) { + // Strip trailing "."... + dirptr[1] = '\0'; + } + } + else + directory_[0] = '\0'; + + if (shown()) { + // Rescan the directory... + rescan(); + } +} + + +// +// 'Fl_File_Chooser::favoritesButtonCB()' - Handle favorites selections. +// + +void +Fl_File_Chooser::favoritesButtonCB() +{ + int v; // Current selection + char pathname[1024], // Pathname + menuname[2048]; // Menu name + + + v = favoritesButton->value(); + + if (!v) { + // Add current directory to favorites... + if (getenv("HOME")) v = favoritesButton->size() - 5; + else v = favoritesButton->size() - 4; + + sprintf(menuname, "favorite%02d", v); + + prefs_.set(menuname, directory_); + prefs_.flush(); + + quote_pathname(menuname, directory_, sizeof(menuname)); + favoritesButton->add(menuname); + + if (favoritesButton->size() > 104) { + ((Fl_Menu_Item *)favoritesButton->menu())[0].deactivate(); + } + } else if (v == 1) { + // Manage favorites... + favoritesCB(0); + } else if (v == 2) { + // Filesystems/My Computer + directory(""); + } else { + unquote_pathname(pathname, favoritesButton->text(v), sizeof(pathname)); + directory(pathname); + } +} + + +// +// 'Fl_File_Chooser::favoritesCB()' - Handle favorites dialog. +// + +void +Fl_File_Chooser::favoritesCB(Fl_Widget *w) + // I - Widget +{ + int i; // Looping var + char name[32], // Preference name + pathname[1024]; // Directory in list + + + if (!w) { + // Load the favorites list... + favList->clear(); + favList->deselect(); + + for (i = 0; i < 100; i ++) { + // Get favorite directory 0 to 99... + sprintf(name, "favorite%02d", i); + + prefs_.get(name, pathname, "", sizeof(pathname)); + + // Stop on the first empty favorite... + if (!pathname[0]) break; + + // Add the favorite to the list... + favList->add(pathname, + Fl_File_Icon::find(pathname, Fl_File_Icon::DIRECTORY)); + } + + favUpButton->deactivate(); + favDeleteButton->deactivate(); + favDownButton->deactivate(); + favOkButton->deactivate(); + + favWindow->hotspot(favList); + favWindow->show(); + } else if (w == favList) { + i = favList->value(); + if (i) { + if (i > 1) favUpButton->activate(); + else favUpButton->deactivate(); + + favDeleteButton->activate(); + + if (i < favList->size()) favDownButton->activate(); + else favDownButton->deactivate(); + } else { + favUpButton->deactivate(); + favDeleteButton->deactivate(); + favDownButton->deactivate(); + } + } else if (w == favUpButton) { + i = favList->value(); + + favList->insert(i - 1, favList->text(i), favList->data(i)); + favList->remove(i + 1); + favList->select(i - 1); + + if (i == 2) favUpButton->deactivate(); + + favDownButton->activate(); + + favOkButton->activate(); + } else if (w == favDeleteButton) { + i = favList->value(); + + favList->remove(i); + + if (i > favList->size()) i --; + favList->select(i); + + if (i < favList->size()) favDownButton->activate(); + else favDownButton->deactivate(); + + if (i > 1) favUpButton->activate(); + else favUpButton->deactivate(); + + if (!i) favDeleteButton->deactivate(); + + favOkButton->activate(); + } else if (w == favDownButton) { + i = favList->value(); + + favList->insert(i + 2, favList->text(i), favList->data(i)); + favList->remove(i); + favList->select(i + 1); + + if ((i + 1) == favList->size()) favDownButton->deactivate(); + + favUpButton->activate(); + + favOkButton->activate(); + } else if (w == favOkButton) { + // Copy the new list over... + for (i = 0; i < favList->size(); i ++) { + // Set favorite directory 0 to 99... + sprintf(name, "favorite%02d", i); + + prefs_.set(name, favList->text(i + 1)); + } + + // Clear old entries as necessary... + for (; i < 100; i ++) { + // Clear favorite directory 0 to 99... + sprintf(name, "favorite%02d", i); + + prefs_.get(name, pathname, "", sizeof(pathname)); + + if (pathname[0]) prefs_.set(name, ""); + else break; + } + + update_favorites(); + prefs_.flush(); + + favWindow->hide(); + } +} + + +// +// 'Fl_File_Chooser::fileListCB()' - Handle clicks (and double-clicks) in the +// Fl_File_Browser. +// + +void +Fl_File_Chooser::fileListCB() +{ + char *filename, // New filename + pathname[1024]; // Full pathname to file + + + filename = (char *)fileList->text(fileList->value()); + if (!filename) + return; + + if (!directory_[0]) { + strlcpy(pathname, filename, sizeof(pathname)); + } else if (strcmp(directory_, "/") == 0) { + snprintf(pathname, sizeof(pathname), "/%s", filename); + } else { + snprintf(pathname, sizeof(pathname), "%s/%s", directory_, filename); + } + + if (Fl::event_clicks()) { +#if (defined(WIN32) && ! defined(__CYGWIN__)) || defined(__EMX__) + if ((strlen(pathname) == 2 && pathname[1] == ':') || + _fl_filename_isdir_quick(pathname)) +#else + if (_fl_filename_isdir_quick(pathname)) +#endif /* WIN32 || __EMX__ */ + { + // Change directories... + directory(pathname); + + // Reset the click count so that a click in the same spot won't + // be treated as a triple-click. We use a value of -1 because + // the next click will increment click count to 0, which is what + // we really want... + Fl::event_clicks(-1); + } + else + { + // Hide the window - picked the file... + window->hide(); + if (callback_) (*callback_)(this, data_); + } + } + else + { + // Check if the user clicks on a directory when picking files; + // if so, make sure only that item is selected... + filename = pathname + strlen(pathname) - 1; + + if ((type_ & MULTI) && !(type_ & DIRECTORY)) { + if (*filename == '/') { + // Clicked on a directory, deselect everything else... + int i = fileList->value(); + fileList->deselect(); + fileList->select(i); + } else { + // Clicked on a file - see if there are other directories selected... + int i; + const char *temp; + for (i = 1; i <= fileList->size(); i ++) { + if (i != fileList->value() && fileList->selected(i)) { + temp = fileList->text(i); + temp += strlen(temp) - 1; + if (*temp == '/') break; // Yes, selected directory + } + } + + if (i <= fileList->size()) { + i = fileList->value(); + fileList->deselect(); + fileList->select(i); + } + } + } + // Strip any trailing slash from the directory name... + if (*filename == '/') *filename = '\0'; + +// puts("Setting fileName from fileListCB..."); + fileName->value(pathname); + + // Update the preview box... + Fl::remove_timeout((Fl_Timeout_Handler)previewCB, this); + Fl::add_timeout(1.0, (Fl_Timeout_Handler)previewCB, this); + + // Do any callback that is registered... + if (callback_) (*callback_)(this, data_); + + // Activate the OK button as needed... + if (!_fl_filename_isdir_quick(pathname) || (type_ & DIRECTORY)) + okButton->activate(); + else + okButton->deactivate(); + } +} + + +// +// 'Fl_File_Chooser::fileNameCB()' - Handle text entry in the FileBrowser. +// + +void +Fl_File_Chooser::fileNameCB() +{ + char *filename, // New filename + *slash, // Pointer to trailing slash + pathname[1024], // Full pathname to file + matchname[256]; // Matching filename + int i, // Looping var + min_match, // Minimum number of matching chars + max_match, // Maximum number of matching chars + num_files, // Number of files in directory + first_line; // First matching line + const char *file; // File from directory + +// puts("fileNameCB()"); +// printf("Event: %s\n", fl_eventnames[Fl::event()]); + + // Get the filename from the text field... + filename = (char *)fileName->value(); + + if (!filename || !filename[0]) { + okButton->deactivate(); + return; + } + + // Expand ~ and $ variables as needed... + if (strchr(filename, '~') || strchr(filename, '$')) { + fl_filename_expand(pathname, sizeof(pathname), filename); + filename = pathname; + value(pathname); + } + + // Make sure we have an absolute path... +#if (defined(WIN32) && !defined(__CYGWIN__)) || defined(__EMX__) + if (directory_[0] != '\0' && filename[0] != '/' && + filename[0] != '\\' && + !(isalpha(filename[0] & 255) && (!filename[1] || filename[1] == ':'))) { +#else + if (directory_[0] != '\0' && filename[0] != '/') { +#endif /* WIN32 || __EMX__ */ + fl_filename_absolute(pathname, sizeof(pathname), filename); + value(pathname); + fileName->mark(fileName->position()); // no selection after expansion + } else if (filename != pathname) { + // Finally, make sure that we have a writable copy... + strlcpy(pathname, filename, sizeof(pathname)); + } + + filename = pathname; + + // Now process things according to the key pressed... + if (Fl::event_key() == FL_Enter || Fl::event_key() == FL_KP_Enter) { + // Enter pressed - select or change directory... +#if (defined(WIN32) && ! defined(__CYGWIN__)) || defined(__EMX__) + if ((isalpha(pathname[0] & 255) && pathname[1] == ':' && !pathname[2]) || + _fl_filename_isdir_quick(pathname) && + compare_dirnames(pathname, directory_)) { +#else + if (_fl_filename_isdir_quick(pathname) && + compare_dirnames(pathname, directory_)) { +#endif /* WIN32 || __EMX__ */ + directory(pathname); + } else if ((type_ & CREATE) || access(pathname, 0) == 0) { + if (!_fl_filename_isdir_quick(pathname) || (type_ & DIRECTORY)) { + // Update the preview box... + update_preview(); + + // Do any callback that is registered... + if (callback_) (*callback_)(this, data_); + + // Hide the window to signal things are done... + window->hide(); + } + } else { + // File doesn't exist, so beep at and alert the user... + fl_alert("%s",existing_file_label); + } + } + else if (Fl::event_key() != FL_Delete && + Fl::event_key() != FL_BackSpace) { + // Check to see if the user has entered a directory... + if ((slash = strrchr(pathname, '/')) == NULL) + slash = strrchr(pathname, '\\'); + + if (!slash) return; + + // Yes, change directories if necessary... + *slash++ = '\0'; + filename = slash; + +#if defined(WIN32) || defined(__EMX__) + if (strcasecmp(pathname, directory_) && + (pathname[0] || strcasecmp("/", directory_))) { +#else + if (strcmp(pathname, directory_) && + (pathname[0] || strcasecmp("/", directory_))) { +#endif // WIN32 || __EMX__ + int p = fileName->position(); + int m = fileName->mark(); + + directory(pathname); + + if (filename[0]) { + char tempname[1024]; + + snprintf(tempname, sizeof(tempname), "%s/%s", directory_, filename); + fileName->value(tempname); + strlcpy(pathname, tempname, sizeof(pathname)); + } + + fileName->position(p, m); + } + + // Other key pressed - do filename completion as possible... + num_files = fileList->size(); + min_match = strlen(filename); + max_match = min_match + 1; + first_line = 0; + + for (i = 1; i <= num_files && max_match > min_match; i ++) { + file = fileList->text(i); + +#if (defined(WIN32) && ! defined(__CYGWIN__)) || defined(__EMX__) + if (strncasecmp(filename, file, min_match) == 0) { +#else + if (strncmp(filename, file, min_match) == 0) { +#endif // WIN32 || __EMX__ + // OK, this one matches; check against the previous match + if (!first_line) { + // First match; copy stuff over... + strlcpy(matchname, file, sizeof(matchname)); + max_match = strlen(matchname); + + // Strip trailing /, if any... + if (matchname[max_match - 1] == '/') { + max_match --; + matchname[max_match] = '\0'; + } + + // And then make sure that the item is visible + fileList->topline(i); + first_line = i; + } else { + // Succeeding match; compare to find maximum string match... + while (max_match > min_match) +#if (defined(WIN32) && ! defined(__CYGWIN__)) || defined(__EMX__) + if (strncasecmp(file, matchname, max_match) == 0) +#else + if (strncmp(file, matchname, max_match) == 0) +#endif // WIN32 || __EMX__ + break; + else + max_match --; + + // Truncate the string as needed... + matchname[max_match] = '\0'; + } + } + } + + // If we have any matches, add them to the input field... + if (first_line > 0 && min_match == max_match && + max_match == (int)strlen(fileList->text(first_line))) { + // This is the only possible match... + fileList->deselect(0); + fileList->select(first_line); + fileList->redraw(); + } else if (max_match > min_match && first_line) { + // Add the matching portion... + fileName->replace(filename - pathname, filename - pathname + min_match, + matchname); + + // Highlight it with the cursor at the end of the selection so + // s/he can press the right arrow to accept the selection + // (Tab and End also do this for both cases.) + fileName->position(filename - pathname + max_match, + filename - pathname + min_match); + } else if (max_match == 0) { + fileList->deselect(0); + fileList->redraw(); + } + + // See if we need to enable the OK button... + if (((type_ & CREATE) || !access(fileName->value(), 0)) && + (!fl_filename_isdir(fileName->value()) || (type_ & DIRECTORY))) { + okButton->activate(); + } else { + okButton->deactivate(); + } + } else { + // FL_Delete or FL_BackSpace + fileList->deselect(0); + fileList->redraw(); + if (((type_ & CREATE) || !access(fileName->value(), 0)) && + (!fl_filename_isdir(fileName->value()) || (type_ & DIRECTORY))) { + okButton->activate(); + } else { + okButton->deactivate(); + } + } +} + + +// +// 'Fl_File_Chooser::filter()' - Set the filter(s) for the chooser. +// + +void +Fl_File_Chooser::filter(const char *p) // I - Pattern(s) +{ + char *copyp, // Copy of pattern + *start, // Start of pattern + *end; // End of pattern + int allfiles; // Do we have a "*" pattern? + char temp[1024]; // Temporary pattern string + + + // Make sure we have a pattern... + if (!p || !*p) p = "*"; + + // Copy the pattern string... + copyp = strdup(p); + + // Separate the pattern string as necessary... + showChoice->clear(); + + for (start = copyp, allfiles = 0; start && *start; start = end) { + end = strchr(start, '\t'); + if (end) *end++ = '\0'; + + if (strcmp(start, "*") == 0) { + showChoice->add(all_files_label); + allfiles = 1; + } else { + quote_pathname(temp, start, sizeof(temp)); + showChoice->add(temp); + if (strstr(start, "(*)") != NULL) allfiles = 1; + } + } + + free(copyp); + + if (!allfiles) showChoice->add(all_files_label); + + showChoice->add(custom_filter_label); + + // TODO: add a menu item to switch hidden files on and off + + showChoice->value(0); + showChoiceCB(); +} + + +// +// 'Fl_File_Chooser::newdir()' - Make a new directory. +// + +void +Fl_File_Chooser::newdir() +{ + const char *dir; // New directory name + char pathname[1024]; // Full path of directory + + + // Get a directory name from the user + if ((dir = fl_input("%s", NULL, new_directory_label)) == NULL) + return; + + // Make it relative to the current directory as needed... +#if (defined(WIN32) && ! defined (__CYGWIN__)) || defined(__EMX__) + if (dir[0] != '/' && dir[0] != '\\' && dir[1] != ':') +#else + if (dir[0] != '/' && dir[0] != '\\') +#endif /* WIN32 || __EMX__ */ + snprintf(pathname, sizeof(pathname), "%s/%s", directory_, dir); + else + strlcpy(pathname, dir, sizeof(pathname)); + + // Create the directory; ignore EEXIST errors... +#if defined(WIN32) && ! defined (__CYGWIN__) + if (mkdir(pathname)) +#else + if (mkdir(pathname, 0777)) +#endif /* WIN32 */ + if (errno != EEXIST) + { + fl_alert("%s", strerror(errno)); + return; + } + + // Show the new directory... + directory(pathname); +} + + + +/** Enable or disable the preview tile. 1 = enable preview, 0 = disable preview. */ +void Fl_File_Chooser::preview(int e) +{ + previewButton->value(e); + prefs_.set("preview", e); + prefs_.flush(); + + Fl_Group *p = previewBox->parent(); + if (e) { + int w = p->w() * 2 / 3; + fileList->resize(fileList->x(), fileList->y(), + w, fileList->h()); + previewBox->resize(fileList->x()+w, previewBox->y(), + p->w()-w, previewBox->h()); + previewBox->show(); + update_preview(); + } else { + fileList->resize(fileList->x(), fileList->y(), + p->w(), fileList->h()); + previewBox->resize(p->x()+p->w(), previewBox->y(), + 0, previewBox->h()); + previewBox->hide(); + } + p->init_sizes(); + + fileList->parent()->redraw(); +} + + +// +// 'Fl_File_Chooser::previewCB()' - Timeout handler for the preview box. +// + +void +Fl_File_Chooser::previewCB(Fl_File_Chooser *fc) { // I - File chooser + fc->update_preview(); +} + + +// +// 'Fl_File_Chooser::rescan()' - Rescan the current directory. +// + +void +Fl_File_Chooser::rescan() +{ + char pathname[1024]; // New pathname for filename field + + + // Clear the current filename + strlcpy(pathname, directory_, sizeof(pathname)); + if (pathname[0] && pathname[strlen(pathname) - 1] != '/') { + strlcat(pathname, "/", sizeof(pathname)); + } +// puts("Setting fileName in rescan()"); + fileName->value(pathname); + + if (type_ & DIRECTORY) + okButton->activate(); + else + okButton->deactivate(); + + // Build the file list... + fileList->load(directory_, sort); + + // Update the preview box... + update_preview(); +} + +// +/** + Rescan the current directory without clearing the filename, + then select the file if it is in the list +*/ +void Fl_File_Chooser::rescan_keep_filename() +{ + // if no filename was set, this is likely a diretory browser + const char *fn = fileName->value(); + if (!fn || !*fn || fn[strlen(fn) - 1]=='/') { + rescan(); + return; + } + + int i; + char pathname[1024]; // New pathname for filename field + strlcpy(pathname, fn, sizeof(pathname)); + + // Build the file list... + fileList->load(directory_, sort); + + // Update the preview box... + update_preview(); + + // and select the chosen file + char found = 0; + char *slash = strrchr(pathname, '/'); + if (slash) + slash++; + else + slash = pathname; + for (i = 1; i <= fileList->size(); i ++) +#if defined(WIN32) || defined(__EMX__) + if (strcasecmp(fileList->text(i), slash) == 0) { +#else + if (strcmp(fileList->text(i), slash) == 0) { +#endif // WIN32 || __EMX__ + fileList->topline(i); + fileList->select(i); + found = 1; + break; + } + + // update OK button activity + if (found || type_ & CREATE) + okButton->activate(); + else + okButton->deactivate(); +} + + +// +// 'Fl_File_Chooser::showChoiceCB()' - Handle show selections. +// + +void +Fl_File_Chooser::showChoiceCB() +{ + const char *item, // Selected item + *patstart; // Start of pattern + char *patend; // End of pattern + char temp[1024]; // Temporary string for pattern + + + item = showChoice->text(showChoice->value()); + + if (strcmp(item, custom_filter_label) == 0) { + if ((item = fl_input("%s", pattern_, custom_filter_label)) != NULL) { + strlcpy(pattern_, item, sizeof(pattern_)); + + quote_pathname(temp, item, sizeof(temp)); + showChoice->add(temp); + showChoice->value(showChoice->size() - 2); + } + } else if ((patstart = strchr(item, '(')) == NULL) { + strlcpy(pattern_, item, sizeof(pattern_)); + } else { + strlcpy(pattern_, patstart + 1, sizeof(pattern_)); + if ((patend = strrchr(pattern_, ')')) != NULL) *patend = '\0'; + } + + fileList->filter(pattern_); + + if (shown()) { + // Rescan the directory... + rescan_keep_filename(); + } +} + + +// +// 'Fl_File_Chooser::update_favorites()' - Update the favorites menu. +// + +void +Fl_File_Chooser::update_favorites() +{ + int i; // Looping var + char pathname[1024], // Pathname + menuname[2048]; // Menu name + const char *home; // Home directory + + + favoritesButton->clear(); + favoritesButton->add("bla"); + favoritesButton->clear(); + favoritesButton->add(add_favorites_label, FL_ALT + 'a', 0); + favoritesButton->add(manage_favorites_label, FL_ALT + 'm', 0, 0, FL_MENU_DIVIDER); + favoritesButton->add(filesystems_label, FL_ALT + 'f', 0); + + if ((home = getenv("HOME")) != NULL) { + quote_pathname(menuname, home, sizeof(menuname)); + favoritesButton->add(menuname, FL_ALT + 'h', 0); + } + + for (i = 0; i < 100; i ++) { + sprintf(menuname, "favorite%02d", i); + prefs_.get(menuname, pathname, "", sizeof(pathname)); + if (!pathname[0]) break; + + quote_pathname(menuname, pathname, sizeof(menuname)); + + if (i < 10) favoritesButton->add(menuname, FL_ALT + '0' + i, 0); + else favoritesButton->add(menuname); + } + + if (i == 100) ((Fl_Menu_Item *)favoritesButton->menu())[0].deactivate(); +} + + +// +// 'Fl_File_Chooser::update_preview()' - Update the preview box... +// + +void +Fl_File_Chooser::update_preview() +{ + const char *filename; // Current filename + const char *newlabel = 0; // New label text + Fl_Shared_Image *image = 0, // New image + *oldimage; // Old image + int pbw, pbh; // Width and height of preview box + int w, h; // Width and height of preview image + int set = 0; // Set this flag as soon as a decent preview is found + + + if (!previewButton->value()) return; + + filename = value(); + if (filename == NULL) { + // no file name at all, so we have an empty preview + set = 1; + } else if (fl_filename_isdir(filename)) { + // filename is a directory, show a folder icon + newlabel = "@fileopen"; + set = 1; + } else { + struct stat s; + if (fl_stat(filename, &s)==0) { + if ((s.st_mode&S_IFMT)!=S_IFREG) { + // this is no regular file, probably some kind of device + newlabel = "@-3refresh"; // a cross + set = 1; + } else if (s.st_size==0) { + // this file is emty + newlabel = ""; + set = 1; + } else { + // if this file is an image, try to load it + window->cursor(FL_CURSOR_WAIT); + Fl::check(); + + image = Fl_Shared_Image::get(filename); + + if (image) { + window->cursor(FL_CURSOR_DEFAULT); + Fl::check(); + set = 1; + } + } + } + } + + oldimage = (Fl_Shared_Image *)previewBox->image(); + + if (oldimage) oldimage->release(); + + previewBox->image(0); + + if (!set) { + FILE *fp; + int bytes; + char *ptr; + + if (filename) fp = fl_fopen(filename, "rb"); + else fp = NULL; + + if (fp != NULL) { + // Try reading the first 1k of data for a label... + bytes = fread(preview_text_, 1, sizeof(preview_text_) - 1, fp); + preview_text_[bytes] = '\0'; + fclose(fp); + } else { + // Assume we can't read any data... + preview_text_[0] = '\0'; + } + + window->cursor(FL_CURSOR_DEFAULT); + Fl::check(); + + // Scan the buffer for printable UTF8 chars... + for (ptr = preview_text_; *ptr; ptr++) { + uchar c = uchar(*ptr); + if ( (c&0x80)==0 ) { + if (!isprint(c&255) && !isspace(c&255)) break; + } else if ( (c&0xe0)==0xc0 ) { + if (ptr[1] && (ptr[1]&0xc0)!=0x80) break; + ptr++; + } else if ( (c&0xf0)==0xe0 ) { + if (ptr[1] && (ptr[1]&0xc0)!=0x80) break; + ptr++; + if (ptr[1] && (ptr[1]&0xc0)!=0x80) break; + ptr++; + } else if ( (c&0xf8)==0xf0 ) { + if (ptr[1] && (ptr[1]&0xc0)!=0x80) break; + ptr++; + if (ptr[1] && (ptr[1]&0xc0)!=0x80) break; + ptr++; + if (ptr[1] && (ptr[1]&0xc0)!=0x80) break; + ptr++; + } + } +// *ptr && (isprint(*ptr & 255) || isspace(*ptr & 255)); +// ptr ++); + + // Scan the buffer for printable characters in 8 bit + if (*ptr || ptr == preview_text_) { + for (ptr = preview_text_; + *ptr && (isprint(*ptr & 255) || isspace(*ptr & 255)); + ptr ++); + } + + if (*ptr || ptr == preview_text_) { + // Non-printable file, just show a big ?... + previewBox->label(filename ? "?" : 0); + previewBox->align(FL_ALIGN_CLIP); + previewBox->labelsize(75); + previewBox->labelfont(FL_HELVETICA); + } else { + // Show the first 1k of text... + int size = previewBox->h() / 20; + if (size < 6) size = 6; + else if (size > 14) size = 14; + + previewBox->label(preview_text_); + previewBox->align((Fl_Align)(FL_ALIGN_CLIP | FL_ALIGN_INSIDE | + FL_ALIGN_LEFT | FL_ALIGN_TOP)); + previewBox->labelsize(size); + previewBox->labelfont(FL_COURIER); + } + } else if (image) { + pbw = previewBox->w() - 20; + pbh = previewBox->h() - 20; + + if (image->w() > pbw || image->h() > pbh) { + w = pbw; + h = w * image->h() / image->w(); + + if (h > pbh) { + h = pbh; + w = h * image->w() / image->h(); + } + + oldimage = (Fl_Shared_Image *)image->copy(w, h); + previewBox->image((Fl_Image *)oldimage); + + image->release(); + } else { + previewBox->image((Fl_Image *)image); + } + + previewBox->align(FL_ALIGN_CLIP); + previewBox->label(0); + } else if (newlabel) { + previewBox->label(newlabel); + previewBox->align(FL_ALIGN_CLIP); + previewBox->labelsize(newlabel[0]=='@'?75:12); + previewBox->labelfont(FL_HELVETICA); + } + + previewBox->redraw(); +} + + +// +// 'Fl_File_Chooser::value()' - Return a selected filename. +// + +const char * // O - Filename or NULL +Fl_File_Chooser::value(int f) // I - File number +{ + int i; // Looping var + int fcount; // Number of selected files + const char *name; // Current filename + static char pathname[1024]; // Filename + directory + + + name = fileName->value(); + + if (!(type_ & MULTI)) { + // Return the filename in the filename field... + if (!name || !name[0]) return NULL; + else return name; + } + + // Return a filename from the list... + for (i = 1, fcount = 0; i <= fileList->size(); i ++) + if (fileList->selected(i)) { + // See if this file is a selected file/directory... + name = fileList->text(i); + + fcount ++; + + if (fcount == f) { + if (directory_[0]) { + snprintf(pathname, sizeof(pathname), "%s/%s", directory_, name); + } else { + strlcpy(pathname, name, sizeof(pathname)); + } + + return pathname; + } + } + + // If nothing is selected, use the filename field... + if (!name || !name[0]) return NULL; + else return name; +} + + +// +// 'Fl_File_Chooser::value()' - Set the current filename. +// + +void +Fl_File_Chooser::value(const char *filename) + // I - Filename + directory +{ + int i, // Looping var + fcount; // Number of items in list + char *slash; // Directory separator + char pathname[1024]; // Local copy of filename + + +// printf("Fl_File_Chooser::value(\"%s\")\n", filename == NULL ? "(null)" : filename); + + // See if the filename is the "My System" directory... + if (filename == NULL || !filename[0]) { + // Yes, just change the current directory... + directory(filename); + fileName->value(""); + okButton->deactivate(); + return; + } + +#ifdef WIN32 + // See if the filename contains backslashes... + char fixpath[1024]; // Path with slashes converted + if (strchr(filename, '\\')) { + // Convert backslashes to slashes... + strlcpy(fixpath, filename, sizeof(fixpath)); + + for (slash = strchr(fixpath, '\\'); slash; slash = strchr(slash + 1, '\\')) + *slash = '/'; + + filename = fixpath; + } +#endif // WIN32 + + // See if there is a directory in there... + fl_filename_absolute(pathname, sizeof(pathname), filename); + + if ((slash = strrchr(pathname, '/')) != NULL) { + // Yes, change the display to the directory... + if (!fl_filename_isdir(pathname)) *slash++ = '\0'; + + directory(pathname); + if (*slash == '/') slash = pathname; + } else { + directory("."); + slash = pathname; + } + + // Set the input field to the absolute path... + if (slash > pathname) slash[-1] = '/'; + + fileName->value(pathname); + fileName->position(0, strlen(pathname)); + okButton->activate(); + + // Then find the file in the file list and select it... + fcount = fileList->size(); + + fileList->deselect(0); + fileList->redraw(); + + for (i = 1; i <= fcount; i ++) +#if defined(WIN32) || defined(__EMX__) + if (strcasecmp(fileList->text(i), slash) == 0) { +#else + if (strcmp(fileList->text(i), slash) == 0) { +#endif // WIN32 || __EMX__ +// printf("Selecting line %d...\n", i); + fileList->topline(i); + fileList->select(i); + break; + } +} + + +// +// 'compare_dirnames()' - Compare two directory names. +// + +static int +compare_dirnames(const char *a, const char *b) { + int alen, blen; + + // Get length of each string... + alen = strlen(a) - 1; + blen = strlen(b) - 1; + + if (alen < 0 || blen < 0) return alen - blen; + + // Check for trailing slashes... + if (a[alen] != '/') alen ++; + if (b[blen] != '/') blen ++; + + // If the lengths aren't the same, then return the difference... + if (alen != blen) return alen - blen; + + // Do a comparison of the first N chars (alen == blen at this point)... +#ifdef WIN32 + return strncasecmp(a, b, alen); +#else + return strncmp(a, b, alen); +#endif // WIN32 +} + + +// +// 'quote_pathname()' - Quote a pathname for a menu. +// + +static void +quote_pathname(char *dst, // O - Destination string + const char *src, // I - Source string + int dstsize) // I - Size of destination string +{ + dstsize --; + + while (*src && dstsize > 1) { + if (*src == '\\') { + // Convert backslash to forward slash... + *dst++ = '\\'; + *dst++ = '/'; + src ++; + } else { + if (*src == '/') *dst++ = '\\'; + + *dst++ = *src++; + } + } + + *dst = '\0'; +} + + +// +// 'unquote_pathname()' - Unquote a pathname from a menu. +// + +static void +unquote_pathname(char *dst, // O - Destination string + const char *src, // I - Source string + int dstsize) // I - Size of destination string +{ + dstsize --; + + while (*src && dstsize > 1) { + if (*src == '\\') src ++; + *dst++ = *src++; + } + + *dst = '\0'; +} + + +// +// End of "$Id: Fl_File_Chooser2.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_File_Icon.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_File_Icon.cxx new file mode 100644 index 0000000..98069dd --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_File_Icon.cxx @@ -0,0 +1,492 @@ +// +// "$Id: Fl_File_Icon.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Fl_File_Icon routines. +// +// KDE icon code donated by Maarten De Boer. +// +// Copyright 1999-2010 by Michael Sweet. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// +// Contents: +// +// Fl_File_Icon::Fl_File_Icon() - Create a new file icon. +// Fl_File_Icon::~Fl_File_Icon() - Remove a file icon. +// Fl_File_Icon::add() - Add data to an icon. +// Fl_File_Icon::find() - Find an icon based upon a given file. +// Fl_File_Icon::draw() - Draw an icon. +// Fl_File_Icon::label() - Set the widgets label to an icon. +// Fl_File_Icon::labeltype() - Draw the icon label. +// + +// +// Include necessary header files... +// + +#include +#include +#include +#include "flstring.h" +#include +#include +#include +#if (defined(WIN32) && ! defined(__CYGWIN__)) || defined(__EMX__) +# include +# define F_OK 0 +#else +# include +#endif /* WIN32 || __EMX__ */ + +#include +#include +#include +#include + + +// +// Define missing POSIX/XPG4 macros as needed... +// + +#ifndef S_ISDIR +# define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK) +# define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) +# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) +# define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) +# define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) +#endif /* !S_ISDIR */ + + +// +// Icon cache... +// + +Fl_File_Icon *Fl_File_Icon::first_ = (Fl_File_Icon *)0; + + +/** + Creates a new Fl_File_Icon with the specified information. + \param[in] p filename pattern + \param[in] t file type + \param[in] nd number of data values + \param[in] d data values +*/ +Fl_File_Icon::Fl_File_Icon(const char *p, /* I - Filename pattern */ + int t, /* I - File type */ + int nd, /* I - Number of data values */ + short *d) /* I - Data values */ +{ + // Initialize the pattern and type... + pattern_ = p; + type_ = t; + + // Copy icon data as needed... + if (nd) + { + num_data_ = nd; + alloc_data_ = nd + 1; + data_ = (short *)calloc(sizeof(short), nd + 1); + memcpy(data_, d, nd * sizeof(short)); + } + else + { + num_data_ = 0; + alloc_data_ = 0; + } + + // And add the icon to the list of icons... + next_ = first_; + first_ = this; +} + + +/** + The destructor destroys the icon and frees all memory that has been + allocated for it. +*/ +Fl_File_Icon::~Fl_File_Icon() { + Fl_File_Icon *current, // Current icon in list + *prev; // Previous icon in list + + + // Find the icon in the list... + for (current = first_, prev = (Fl_File_Icon *)0; + current != this && current != (Fl_File_Icon *)0; + prev = current, current = current->next_); + + // Remove the icon from the list as needed... + if (current) + { + if (prev) + prev->next_ = current->next_; + else + first_ = current->next_; + } + + // Free any memory used... + if (alloc_data_) + free(data_); +} + + +/** + Adds a keyword value to the icon array, returning a pointer to it. + \param[in] d data value +*/ +short * // O - Pointer to new data value +Fl_File_Icon::add(short d) // I - Data to add +{ + short *dptr; // Pointer to new data value + + + // Allocate/reallocate memory as needed + if ((num_data_ + 1) >= alloc_data_) + { + alloc_data_ += 128; + + if (alloc_data_ == 128) + dptr = (short *)malloc(sizeof(short) * alloc_data_); + else + dptr = (short *)realloc(data_, sizeof(short) * alloc_data_); + + if (dptr == NULL) + return (NULL); + + data_ = dptr; + } + + // Store the new data value and return + data_[num_data_++] = d; + data_[num_data_] = END; + + return (data_ + num_data_ - 1); +} + + +/** + Finds an icon that matches the given filename and file type. + \param[in] filename name of file + \param[in] filetype enumerated file type + \return matching file icon or NULL +*/ +Fl_File_Icon * // O - Matching file icon or NULL +Fl_File_Icon::find(const char *filename,// I - Name of file */ + int filetype) // I - Enumerated file type +{ + Fl_File_Icon *current; // Current file in list +#ifndef WIN32 + struct stat fileinfo; // Information on file +#endif // !WIN32 + const char *name; // Base name of filename + + + // Get file information if needed... + if (filetype == ANY) + { +#ifdef WIN32 + if (filename[strlen(filename) - 1] == '/') + filetype = DIRECTORY; + else if (fl_filename_isdir(filename)) + filetype = DIRECTORY; + else + filetype = PLAIN; +#else + if (!fl_stat(filename, &fileinfo)) + { + if (S_ISDIR(fileinfo.st_mode)) + filetype = DIRECTORY; +# ifdef S_IFIFO + else if (S_ISFIFO(fileinfo.st_mode)) + filetype = FIFO; +# endif // S_IFIFO +# if defined(S_ICHR) && defined(S_IBLK) + else if (S_ISCHR(fileinfo.st_mode) || S_ISBLK(fileinfo.st_mode)) + filetype = DEVICE; +# endif // S_ICHR && S_IBLK +# ifdef S_ILNK + else if (S_ISLNK(fileinfo.st_mode)) + filetype = LINK; +# endif // S_ILNK + else + filetype = PLAIN; + } + else + filetype = PLAIN; +#endif // WIN32 + } + + // Look at the base name in the filename + name = fl_filename_name(filename); + + // Loop through the available file types and return any match that + // is found... + for (current = first_; current != (Fl_File_Icon *)0; current = current->next_) + if ((current->type_ == filetype || current->type_ == ANY) && + (fl_filename_match(filename, current->pattern_) || + fl_filename_match(name, current->pattern_))) + break; + + // Return the match (if any)... + return (current); +} + +/** + Draws an icon in the indicated area. + \param[in] x, y, w, h position and size + \param[in] ic icon color + \param[in] active status, default is active [non-zero] +*/ +void +Fl_File_Icon::draw(int x, // I - Upper-lefthand X + int y, // I - Upper-lefthand Y + int w, // I - Width of bounding box + int h, // I - Height of bounding box + Fl_Color ic, // I - Icon color... + int active) // I - Active or inactive? +{ + Fl_Color c, // Current color + oc; // Outline color + short *d, // Pointer to data + *dend; // End of data... + short *prim; // Pointer to start of primitive... + double scale; // Scale of icon + + + // Don't try to draw a NULL array! + if (num_data_ == 0) + return; + + // Setup the transform matrix as needed... + scale = w < h ? w : h; + + fl_push_matrix(); + fl_translate((float)x + 0.5 * ((float)w - scale), + (float)y + 0.5 * ((float)h + scale)); + fl_scale(scale, -scale); + + // Loop through the array until we see an unmatched END... + d = data_; + dend = data_ + num_data_; + prim = NULL; + c = ic; + + if (active) + fl_color(c); + else + fl_color(fl_inactive(c)); + + while (d < dend) + switch (*d) + { + case END : + if (prim) + switch (*prim) + { + case LINE : + fl_end_line(); + break; + + case CLOSEDLINE : + fl_end_loop(); + break; + + case POLYGON : + fl_end_complex_polygon(); + break; + + case OUTLINEPOLYGON : + fl_end_complex_polygon(); + + oc = (Fl_Color)((((unsigned short *)prim)[1] << 16) | + ((unsigned short *)prim)[2]); + if (active) + { + if (oc == FL_ICON_COLOR) + fl_color(ic); + else + fl_color(oc); + } + else + { + if (oc == FL_ICON_COLOR) + fl_color(fl_inactive(ic)); + else + fl_color(fl_inactive(oc)); + } + + fl_begin_loop(); + + prim += 3; + while (*prim == VERTEX) + { + fl_vertex(prim[1] * 0.0001, prim[2] * 0.0001); + prim += 3; + } + + fl_end_loop(); + fl_color(c); + break; + } + + prim = NULL; + d ++; + break; + + case COLOR : + c = (Fl_Color)((((unsigned short *)d)[1] << 16) | + ((unsigned short *)d)[2]); + + if (c == FL_ICON_COLOR) + c = ic; + + if (!active) + c = fl_inactive(c); + + fl_color(c); + d += 3; + break; + + case LINE : + prim = d; + d ++; + fl_begin_line(); + break; + + case CLOSEDLINE : + prim = d; + d ++; + fl_begin_loop(); + break; + + case POLYGON : + prim = d; + d ++; + fl_begin_complex_polygon(); + break; + + case OUTLINEPOLYGON : + prim = d; + d += 3; + fl_begin_complex_polygon(); + break; + + case VERTEX : + if (prim) + fl_vertex(d[1] * 0.0001, d[2] * 0.0001); + d += 3; + break; + + default : // Ignore invalid data... + d ++; + } + + // If we still have an open primitive, close it... + if (prim) + switch (*prim) + { + case LINE : + fl_end_line(); + break; + + case CLOSEDLINE : + fl_end_loop(); + break; + + case POLYGON : + fl_end_polygon(); + break; + + case OUTLINEPOLYGON : + fl_end_polygon(); + + oc = (Fl_Color)((((unsigned short *)prim)[1] << 16) | + ((unsigned short *)prim)[2]); + if (active) + { + if (oc == FL_ICON_COLOR) + fl_color(ic); + else + fl_color(oc); + } + else + { + if (oc == FL_ICON_COLOR) + fl_color(fl_inactive(ic)); + else + fl_color(fl_inactive(oc)); + } + + fl_begin_loop(); + + prim += 3; + while (*prim == VERTEX) + { + fl_vertex(prim[1] * 0.0001, prim[2] * 0.0001); + prim += 3; + } + + fl_end_loop(); + fl_color(c); + break; + } + + // Restore the transform matrix + fl_pop_matrix(); +} + +/** + Applies the icon to the widget, registering the Fl_File_Icon + label type as needed. + \param[in] w widget for which this icon will become the label +*/ +void Fl_File_Icon::label(Fl_Widget *w) // I - Widget to label +{ + Fl::set_labeltype(_FL_ICON_LABEL, labeltype, 0); + w->label(_FL_ICON_LABEL, (const char*)this); +} + + +/** + Draw the icon label. + \param[in] o label data + \param[in] x, y, w, h position and size of label + \param[in] a label alignment [not used] +*/ +void +Fl_File_Icon::labeltype(const Fl_Label *o, // I - Label data + int x, // I - X position of label + int y, // I - Y position of label + int w, // I - Width of label + int h, // I - Height of label + Fl_Align a) // I - Label alignment (not used) +{ + Fl_File_Icon *icon; // Pointer to icon data + + + (void)a; + + icon = (Fl_File_Icon *)(o->value); + if (icon) icon->draw(x, y, w, h, (Fl_Color)(o->color)); +} + + +// +// End of "$Id: Fl_File_Icon.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_File_Icon2.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_File_Icon2.cxx new file mode 100644 index 0000000..de955ca --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_File_Icon2.cxx @@ -0,0 +1,1022 @@ +// +// "$Id: Fl_File_Icon2.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Fl_File_Icon system icon routines. +// +// KDE icon code donated by Maarten De Boer. +// +// Copyright 1999-2010 by Michael Sweet. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// +// Contents: +// +// Fl_File_Icon::load() - Load an icon file... +// Fl_File_Icon::load_fti() - Load an SGI-format FTI file... +// Fl_File_Icon::load_image() - Load an image icon file... +// Fl_File_Icon::load_system_icons() - Load the standard system icons/filetypes. +// load_kde_icons() - Load KDE icon files. +// load_kde_mimelnk() - Load a KDE "mimelnk" file. +// kde_to_fltk_pattern() - Convert a KDE pattern to a FLTK pattern. +// get_kde_val() - Get a KDE value. +// + +// +// Include necessary header files... +// + +#include +#include +#include +#include "flstring.h" +#include +#include +#include +#include +#include +#if defined(WIN32) && !defined(__CYGWIN__) +# include +# define F_OK 0 +// Visual C++ 2005 incorrectly displays a warning about the use of POSIX APIs +// on Windows, which is supposed to be POSIX compliant... +# define access _access +#else +# include +#endif // WIN32 + +#include +#include +#include +#include +#include + + +// +// Define missing POSIX/XPG4 macros as needed... +// + +#ifndef S_ISDIR +# define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK) +# define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) +# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) +# define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) +# define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) +#endif /* !S_ISDIR */ + + +// +// Local functions... +// + +static void load_kde_icons(const char *directory, const char *icondir); +static void load_kde_mimelnk(const char *filename, const char *icondir); +static char *kde_to_fltk_pattern(const char *kdepattern); +static char *get_kde_val(char *str, const char *key); + + +// +// Local globals... +// + +static const char *kdedir = NULL; + + +/** + Loads the specified icon image. The format is deduced from the filename. + \param[in] f filename +*/ +void +Fl_File_Icon::load(const char *f) // I - File to read from +{ + int i; // Load status... + const char *ext; // File extension + + + ext = fl_filename_ext(f); + + if (ext && strcmp(ext, ".fti") == 0) + i = load_fti(f); + else + i = load_image(f); + + if (i) + { + Fl::warning("Fl_File_Icon::load(): Unable to load icon file \"%s\".", f); + return; + } +} + + +/** + Loads an SGI icon file. + \param[in] fti icon filename + \return 0 on success, non-zero on error +*/ +int // O - 0 on success, non-zero on error +Fl_File_Icon::load_fti(const char *fti) // I - File to read from +{ + FILE *fp; // File pointer + int ch; // Current character + char command[255], // Command string ("vertex", etc.) + params[255], // Parameter string ("10.0,20.0", etc.) + *ptr; // Pointer into strings + int outline; // Outline polygon + + + // Try to open the file... + if ((fp = fl_fopen(fti, "rb")) == NULL) + { + Fl::error("Fl_File_Icon::load_fti(): Unable to open \"%s\" - %s", + fti, strerror(errno)); + return -1; + } + + // Read the entire file, adding data as needed... + outline = 0; + + while ((ch = getc(fp)) != EOF) + { + // Skip whitespace + if (isspace(ch)) + continue; + + // Skip comments starting with "#"... + if (ch == '#') + { + while ((ch = getc(fp)) != EOF) + if (ch == '\n') + break; + + if (ch == EOF) + break; + else + continue; + } + + // OK, this character better be a letter... + if (!isalpha(ch)) + { + Fl::error("Fl_File_Icon::load_fti(): Expected a letter at file position %ld (saw '%c')", + ftell(fp) - 1, ch); + break; + } + + // Scan the command name... + ptr = command; + *ptr++ = ch; + + while ((ch = getc(fp)) != EOF) + { + if (ch == '(') + break; + else if (ptr < (command + sizeof(command) - 1)) + *ptr++ = ch; + } + + *ptr++ = '\0'; + + // Make sure we stopped on a parenthesis... + if (ch != '(') + { + Fl::error("Fl_File_Icon::load_fti(): Expected a ( at file position %ld (saw '%c')", + ftell(fp) - 1, ch); + break; + } + + // Scan the parameters... + ptr = params; + + while ((ch = getc(fp)) != EOF) + { + if (ch == ')') + break; + else if (ptr < (params + sizeof(params) - 1)) + *ptr++ = ch; + } + + *ptr++ = '\0'; + + // Make sure we stopped on a parenthesis... + if (ch != ')') + { + Fl::error("Fl_File_Icon::load_fti(): Expected a ) at file position %ld (saw '%c')", + ftell(fp) - 1, ch); + break; + } + + // Make sure the next character is a semicolon... + if ((ch = getc(fp)) != ';') + { + Fl::error("Fl_File_Icon::load_fti(): Expected a ; at file position %ld (saw '%c')", + ftell(fp) - 1, ch); + break; + } + + // Now process the command... + if (strcmp(command, "color") == 0) + { + // Set the color; for negative colors blend the two primaries to + // produce a composite color. Also, the following symbolic color + // names are understood: + // + // name FLTK color + // ------------- ---------- + // iconcolor FL_ICON_COLOR; mapped to the icon color in + // Fl_File_Icon::draw() + // shadowcolor FL_DARK3 + // outlinecolor FL_BLACK + if (strcmp(params, "iconcolor") == 0) + add_color(FL_ICON_COLOR); + else if (strcmp(params, "shadowcolor") == 0) + add_color(FL_DARK3); + else if (strcmp(params, "outlinecolor") == 0) + add_color(FL_BLACK); + else + { + int c = atoi(params); // Color value + + + if (c < 0) + { + // Composite color; compute average... + c = -c; + add_color(fl_color_average((Fl_Color)(c >> 4), + (Fl_Color)(c & 15), 0.5f)); + } + else + add_color((Fl_Color)c); + } + } + else if (strcmp(command, "bgnline") == 0) + add(LINE); + else if (strcmp(command, "bgnclosedline") == 0) + add(CLOSEDLINE); + else if (strcmp(command, "bgnpolygon") == 0) + add(POLYGON); + else if (strcmp(command, "bgnoutlinepolygon") == 0) + { + add(OUTLINEPOLYGON); + outline = add(0) - data_; + add(0); + } + else if (strcmp(command, "endoutlinepolygon") == 0 && outline) + { + unsigned cval; // Color value + + // Set the outline color; see above for valid values... + if (strcmp(params, "iconcolor") == 0) + cval = FL_ICON_COLOR; + else if (strcmp(params, "shadowcolor") == 0) + cval = FL_DARK3; + else if (strcmp(params, "outlinecolor") == 0) + cval = FL_BLACK; + else + { + int c = atoi(params); // Color value + + + if (c < 0) + { + // Composite color; compute average... + c = -c; + cval = fl_color_average((Fl_Color)(c >> 4), (Fl_Color)(c & 15), 0.5f); + } + else + cval = c; + } + + // Store outline color... + data_[outline] = cval >> 16; + data_[outline + 1] = cval; + + outline = 0; + add(END); + } + else if (strncmp(command, "end", 3) == 0) + add(END); + else if (strcmp(command, "vertex") == 0) + { + float x, y; // Coordinates of vertex + + + if (sscanf(params, "%f,%f", &x, &y) != 2) + break; + + add_vertex((short)(int)rint(x * 100.0), (short)(int)rint(y * 100.0)); + } + else + { + Fl::error("Fl_File_Icon::load_fti(): Unknown command \"%s\" at file position %ld.", + command, ftell(fp) - 1); + break; + } + } + + // Close the file and return... + fclose(fp); + +#ifdef DEBUG + printf("Icon File \"%s\":\n", fti); + for (int i = 0; i < num_data_; i ++) + printf(" %d,\n", data_[i]); +#endif /* DEBUG */ + + return 0; +} + + +/** + Load an image icon file from an image filename. + \param[in] ifile image filename + \return 0 on success, non-zero on error +*/ +int Fl_File_Icon::load_image(const char *ifile) // I - File to read from +{ + Fl_Shared_Image *img; // Image file + + + img = Fl_Shared_Image::get(ifile); + if (!img || !img->count() || !img->w() || !img->h()) return -1; + + if (img->count() == 1) { + int x, y; // X & Y in image + int startx; // Starting X coord + Fl_Color c, // Current color + temp; // Temporary color + const uchar *row; // Pointer into image + + + // Loop through grayscale or RGB image... + for (y = 0, row = (const uchar *)(*(img->data())); y < img->h(); y ++, row += img->ld()) + { + for (x = 0, startx = 0, c = (Fl_Color)-1; + x < img->w(); + x ++, row += img->d()) + { + switch (img->d()) + { + case 1 : + temp = fl_rgb_color(row[0], row[0], row[0]); + break; + case 2 : + if (row[1] > 127) + temp = fl_rgb_color(row[0], row[0], row[0]); + else + temp = (Fl_Color)-1; + break; + case 3 : + temp = fl_rgb_color(row[0], row[1], row[2]); + break; + default : + if (row[3] > 127) + temp = fl_rgb_color(row[0], row[1], row[2]); + else + temp = (Fl_Color)-1; + break; + } + + if (temp != c) + { + if (x > startx && c != (Fl_Color)-1) + { + add_color(c); + add(POLYGON); + add_vertex(startx * 9000 / img->w() + 1000, 9500 - y * 9000 / img->h()); + add_vertex(x * 9000 / img->w() + 1000, 9500 - y * 9000 / img->h()); + add_vertex(x * 9000 / img->w() + 1000, 9500 - (y + 1) * 9000 / img->h()); + add_vertex(startx * 9000 / img->w() + 1000, 9500 - (y + 1) * 9000 / img->h()); + add(END); + } + + c = temp; + startx = x; + } + } + + if (x > startx && c != (Fl_Color)-1) + { + add_color(c); + add(POLYGON); + add_vertex(startx * 9000 / img->w() + 1000, 9500 - y * 9000 / img->h()); + add_vertex(x * 9000 / img->w() + 1000, 9500 - y * 9000 / img->h()); + add_vertex(x * 9000 / img->w() + 1000, 9500 - (y + 1) * 9000 / img->h()); + add_vertex(startx * 9000 / img->w() + 1000, 9500 - (y + 1) * 9000 / img->h()); + add(END); + } + } + } else { + int i, j; // Looping vars + int ch; // Current character + int newch; // New character + int bg; // Background color + char val[16]; // Color value + const char *lineptr, // Pointer into line + *const*ptr; // Pointer into data array + int ncolors, // Number of colors + chars_per_color; // Characters per color + Fl_Color *colors; // Colors + int red, green, blue; // Red, green, and blue values + int x, y; // X & Y in image + int startx; // Starting X coord + + + // Get the pixmap data... + ptr = img->data(); + sscanf(*ptr, "%*d%*d%d%d", &ncolors, &chars_per_color); + + colors = new Fl_Color[1 << (chars_per_color * 8)]; + + // Read the colormap... + memset(colors, 0, sizeof(Fl_Color) << (chars_per_color * 8)); + bg = ' '; + + ptr ++; + + if (ncolors < 0) { + // Read compressed colormap... + const uchar *cmapptr; + + ncolors = -ncolors; + + for (i = 0, cmapptr = (const uchar *)*ptr; i < ncolors; i ++, cmapptr += 4) + colors[cmapptr[0]] = fl_rgb_color(cmapptr[1], cmapptr[2], cmapptr[3]); + + ptr ++; + } else { + for (i = 0; i < ncolors; i ++, ptr ++) { + // Get the color's character + lineptr = *ptr; + ch = *lineptr++; + + if (chars_per_color > 1) ch = (ch << 8) | *lineptr++; + + // Get the color value... + if ((lineptr = strstr(lineptr, "c ")) == NULL) { + // No color; make this black... + colors[ch] = FL_BLACK; + } else if (lineptr[2] == '#') { + // Read the RGB triplet... + lineptr += 3; + for (j = 0; j < 12; j ++) + if (!isxdigit(lineptr[j])) + break; + + switch (j) { + case 0 : + bg = ch; + default : + red = green = blue = 0; + break; + + case 3 : + val[0] = lineptr[0]; + val[1] = '\0'; + red = 255 * strtol(val, NULL, 16) / 15; + + val[0] = lineptr[1]; + val[1] = '\0'; + green = 255 * strtol(val, NULL, 16) / 15; + + val[0] = lineptr[2]; + val[1] = '\0'; + blue = 255 * strtol(val, NULL, 16) / 15; + break; + + case 6 : + case 9 : + case 12 : + j /= 3; + + val[0] = lineptr[0]; + val[1] = lineptr[1]; + val[2] = '\0'; + red = strtol(val, NULL, 16); + + val[0] = lineptr[j + 0]; + val[1] = lineptr[j + 1]; + val[2] = '\0'; + green = strtol(val, NULL, 16); + + val[0] = lineptr[2 * j + 0]; + val[1] = lineptr[2 * j + 1]; + val[2] = '\0'; + blue = strtol(val, NULL, 16); + break; + } + + colors[ch] = fl_rgb_color((uchar)red, (uchar)green, (uchar)blue); + } else { + // Read a color name... + if (strncasecmp(lineptr + 2, "white", 5) == 0) colors[ch] = FL_WHITE; + else if (strncasecmp(lineptr + 2, "black", 5) == 0) colors[ch] = FL_BLACK; + else if (strncasecmp(lineptr + 2, "none", 4) == 0) { + colors[ch] = FL_BLACK; + bg = ch; + } else colors[ch] = FL_GRAY; + } + } + } + + // Read the image data... + for (y = 0; y < img->h(); y ++, ptr ++) { + lineptr = *ptr; + startx = 0; + ch = bg; + + for (x = 0; x < img->w(); x ++) { + newch = *lineptr++; + + if (chars_per_color > 1) newch = (newch << 8) | *lineptr++; + + if (newch != ch) { + if (ch != bg) { + add_color(colors[ch]); + add(POLYGON); + add_vertex(startx * 9000 / img->w() + 1000, 9500 - y * 9000 / img->h()); + add_vertex(x * 9000 / img->w() + 1000, 9500 - y * 9000 / img->h()); + add_vertex(x * 9000 / img->w() + 1000, 9500 - (y + 1) * 9000 / img->h()); + add_vertex(startx * 9000 / img->w() + 1000, 9500 - (y + 1) * 9000 / img->h()); + add(END); + } + + ch = newch; + startx = x; + } + } + + if (ch != bg) { + add_color(colors[ch]); + add(POLYGON); + add_vertex(startx * 9000 / img->w() + 1000, 9500 - y * 9000 / img->h()); + add_vertex(x * 9000 / img->w() + 1000, 9500 - y * 9000 / img->h()); + add_vertex(x * 9000 / img->w() + 1000, 9500 - (y + 1) * 9000 / img->h()); + add_vertex(startx * 9000 / img->w() + 1000, 9500 - (y + 1) * 9000 / img->h()); + add(END); + } + } + + // Free the colormap... + delete[] colors; + } + + img->release(); + +#ifdef DEBUG + printf("Icon File \"%s\":\n", xpm); + for (i = 0; i < num_data_; i ++) + printf(" %d,\n", data_[i]); +#endif // DEBUG + + return 0; +} + + +/** + Loads all system-defined icons. This call is useful when using the + FileChooser widget and should be used when the application starts: + + \code + Fl_File_Icon::load_system_icons(); + \endcode +*/ +void +Fl_File_Icon::load_system_icons(void) { + int i; // Looping var + Fl_File_Icon *icon; // New icons + char filename[1024]; // Filename + char icondir[1024]; // Icon directory + static int init = 0; // Have the icons been initialized? + const char * const icondirs[] = { + "Bluecurve", // Icon directories to look for, in order + "crystalsvg", + "default.kde", + "hicolor", + NULL + }; + static short plain[] = { // Plain file icon + COLOR, -1, -1, OUTLINEPOLYGON, 0, FL_GRAY, + VERTEX, 2000, 1000, VERTEX, 2000, 9000, + VERTEX, 6000, 9000, VERTEX, 8000, 7000, + VERTEX, 8000, 1000, END, OUTLINEPOLYGON, 0, FL_GRAY, + VERTEX, 6000, 9000, VERTEX, 6000, 7000, + VERTEX, 8000, 7000, END, + COLOR, 0, FL_BLACK, LINE, VERTEX, 6000, 7000, + VERTEX, 8000, 7000, VERTEX, 8000, 1000, + VERTEX, 2000, 1000, END, LINE, VERTEX, 3000, 7000, + VERTEX, 5000, 7000, END, LINE, VERTEX, 3000, 6000, + VERTEX, 5000, 6000, END, LINE, VERTEX, 3000, 5000, + VERTEX, 7000, 5000, END, LINE, VERTEX, 3000, 4000, + VERTEX, 7000, 4000, END, LINE, VERTEX, 3000, 3000, + VERTEX, 7000, 3000, END, LINE, VERTEX, 3000, 2000, + VERTEX, 7000, 2000, END, + END + }; + static short image[] = { // Image file icon + COLOR, -1, -1, OUTLINEPOLYGON, 0, FL_GRAY, + VERTEX, 2000, 1000, VERTEX, 2000, 9000, + VERTEX, 6000, 9000, VERTEX, 8000, 7000, + VERTEX, 8000, 1000, END, OUTLINEPOLYGON, 0, FL_GRAY, + VERTEX, 6000, 9000, VERTEX, 6000, 7000, + VERTEX, 8000, 7000, END, + COLOR, 0, FL_BLACK, LINE, VERTEX, 6000, 7000, + VERTEX, 8000, 7000, VERTEX, 8000, 1000, + VERTEX, 2000, 1000, END, + COLOR, 0, FL_RED, POLYGON, VERTEX, 3500, 2500, + VERTEX, 3000, 3000, VERTEX, 3000, 4000, + VERTEX, 3500, 4500, VERTEX, 4500, 4500, + VERTEX, 5000, 4000, VERTEX, 5000, 3000, + VERTEX, 4500, 2500, END, + COLOR, 0, FL_GREEN, POLYGON, VERTEX, 5500, 2500, + VERTEX, 5000, 3000, VERTEX, 5000, 4000, + VERTEX, 5500, 4500, VERTEX, 6500, 4500, + VERTEX, 7000, 4000, VERTEX, 7000, 3000, + VERTEX, 6500, 2500, END, + COLOR, 0, FL_BLUE, POLYGON, VERTEX, 4500, 3500, + VERTEX, 4000, 4000, VERTEX, 4000, 5000, + VERTEX, 4500, 5500, VERTEX, 5500, 5500, + VERTEX, 6000, 5000, VERTEX, 6000, 4000, + VERTEX, 5500, 3500, END, + END + }; + static short dir[] = { // Directory icon + COLOR, -1, -1, POLYGON, VERTEX, 1000, 1000, + VERTEX, 1000, 7500, VERTEX, 9000, 7500, + VERTEX, 9000, 1000, END, + POLYGON, VERTEX, 1000, 7500, VERTEX, 2500, 9000, + VERTEX, 5000, 9000, VERTEX, 6500, 7500, END, + COLOR, 0, FL_WHITE, LINE, VERTEX, 1500, 1500, + VERTEX, 1500, 7000, VERTEX, 9000, 7000, END, + COLOR, 0, FL_BLACK, LINE, VERTEX, 9000, 7500, + VERTEX, 9000, 1000, VERTEX, 1000, 1000, END, + COLOR, 0, FL_GRAY, LINE, VERTEX, 1000, 1000, + VERTEX, 1000, 7500, VERTEX, 2500, 9000, + VERTEX, 5000, 9000, VERTEX, 6500, 7500, + VERTEX, 9000, 7500, END, + END + }; + + + // Add symbols if they haven't been added already... + if (!init) { + // This method requires the images library... + fl_register_images(); + + if (!kdedir) { + // Figure out where KDE is installed... + if ((kdedir = getenv("KDEDIR")) == NULL) { + if (!access("/opt/kde", F_OK)) kdedir = "/opt/kde"; + else if (!access("/usr/local/share/mimelnk", F_OK)) kdedir = "/usr/local"; + else kdedir = "/usr"; + } + } + + snprintf(filename, sizeof(filename), "%s/share/mimelnk", kdedir); + + if (!access(filename, F_OK)) { + // Load KDE icons... + icon = new Fl_File_Icon("*", Fl_File_Icon::PLAIN); + + for (i = 0; icondirs[i]; i ++) { + snprintf(icondir, sizeof(icondir), "%s/share/icons/%s", kdedir, + icondirs[i]); + + if (!access(icondir, F_OK)) break; + } + + if (icondirs[i]) { + snprintf(filename, sizeof(filename), "%s/16x16/mimetypes/unknown.png", + icondir); + } else { + snprintf(filename, sizeof(filename), "%s/share/icons/unknown.xpm", + kdedir); + } + + if (!access(filename, F_OK)) icon->load_image(filename); + + icon = new Fl_File_Icon("*", Fl_File_Icon::LINK); + + snprintf(filename, sizeof(filename), "%s/16x16/filesystems/link.png", + icondir); + + if (!access(filename, F_OK)) icon->load_image(filename); + + snprintf(filename, sizeof(filename), "%s/share/mimelnk", kdedir); + load_kde_icons(filename, icondir); + } else if (!access("/usr/share/icons/folder.xpm", F_OK)) { + // Load GNOME icons... + icon = new Fl_File_Icon("*", Fl_File_Icon::PLAIN); + icon->load_image("/usr/share/icons/page.xpm"); + + icon = new Fl_File_Icon("*", Fl_File_Icon::DIRECTORY); + icon->load_image("/usr/share/icons/folder.xpm"); + } else if (!access("/usr/dt/appconfig/icons", F_OK)) { + // Load CDE icons... + icon = new Fl_File_Icon("*", Fl_File_Icon::PLAIN); + icon->load_image("/usr/dt/appconfig/icons/C/Dtdata.m.pm"); + + icon = new Fl_File_Icon("*", Fl_File_Icon::DIRECTORY); + icon->load_image("/usr/dt/appconfig/icons/C/DtdirB.m.pm"); + + icon = new Fl_File_Icon("core", Fl_File_Icon::PLAIN); + icon->load_image("/usr/dt/appconfig/icons/C/Dtcore.m.pm"); + + icon = new Fl_File_Icon("*.{bmp|bw|gif|jpg|pbm|pcd|pgm|ppm|png|ras|rgb|tif|xbm|xpm}", Fl_File_Icon::PLAIN); + icon->load_image("/usr/dt/appconfig/icons/C/Dtimage.m.pm"); + + icon = new Fl_File_Icon("*.{eps|pdf|ps}", Fl_File_Icon::PLAIN); + icon->load_image("/usr/dt/appconfig/icons/C/Dtps.m.pm"); + + icon = new Fl_File_Icon("*.ppd", Fl_File_Icon::PLAIN); + icon->load_image("/usr/dt/appconfig/icons/C/DtPrtpr.m.pm"); + } else if (!access("/usr/lib/filetype", F_OK)) { + // Load SGI icons... + icon = new Fl_File_Icon("*", Fl_File_Icon::PLAIN); + icon->load_fti("/usr/lib/filetype/iconlib/generic.doc.fti"); + + icon = new Fl_File_Icon("*", Fl_File_Icon::DIRECTORY); + icon->load_fti("/usr/lib/filetype/iconlib/generic.folder.closed.fti"); + + icon = new Fl_File_Icon("core", Fl_File_Icon::PLAIN); + icon->load_fti("/usr/lib/filetype/default/iconlib/CoreFile.fti"); + + icon = new Fl_File_Icon("*.{bmp|bw|gif|jpg|pbm|pcd|pgm|ppm|png|ras|rgb|tif|xbm|xpm}", Fl_File_Icon::PLAIN); + icon->load_fti("/usr/lib/filetype/system/iconlib/ImageFile.fti"); + + if (!access("/usr/lib/filetype/install/iconlib/acroread.doc.fti", F_OK)) { + icon = new Fl_File_Icon("*.{eps|ps}", Fl_File_Icon::PLAIN); + icon->load_fti("/usr/lib/filetype/system/iconlib/PostScriptFile.closed.fti"); + + icon = new Fl_File_Icon("*.pdf", Fl_File_Icon::PLAIN); + icon->load_fti("/usr/lib/filetype/install/iconlib/acroread.doc.fti"); + } else { + icon = new Fl_File_Icon("*.{eps|pdf|ps}", Fl_File_Icon::PLAIN); + icon->load_fti("/usr/lib/filetype/system/iconlib/PostScriptFile.closed.fti"); + } + + if (!access("/usr/lib/filetype/install/iconlib/html.fti", F_OK)) { + icon = new Fl_File_Icon("*.{htm|html|shtml}", Fl_File_Icon::PLAIN); + icon->load_fti("/usr/lib/filetype/iconlib/generic.doc.fti"); + icon->load_fti("/usr/lib/filetype/install/iconlib/html.fti"); + } + + if (!access("/usr/lib/filetype/install/iconlib/color.ps.idle.fti", F_OK)) { + icon = new Fl_File_Icon("*.ppd", Fl_File_Icon::PLAIN); + icon->load_fti("/usr/lib/filetype/install/iconlib/color.ps.idle.fti"); + } + } else { + // Create the default icons... + new Fl_File_Icon("*", Fl_File_Icon::PLAIN, sizeof(plain) / sizeof(plain[0]), plain); + new Fl_File_Icon("*.{bm|bmp|bw|gif|jpg|pbm|pcd|pgm|ppm|png|ras|rgb|tif|xbm|xpm}", Fl_File_Icon::PLAIN, + sizeof(image) / sizeof(image[0]), image); + new Fl_File_Icon("*", Fl_File_Icon::DIRECTORY, sizeof(dir) / sizeof(dir[0]), dir); + } + + // Mark things as initialized... + init = 1; + +#ifdef DEBUG + int count; + Fl_File_Icon *temp; + for (count = 0, temp = first_; temp; temp = temp->next_, count ++); + printf("count of Fl_File_Icon's is %d...\n", count); +#endif // DEBUG + } +} + + +// +// 'load_kde_icons()' - Load KDE icon files. +// + +static void +load_kde_icons(const char *directory, // I - Directory to load + const char *icondir) { // I - Location of icons + int i; // Looping var + int n; // Number of entries in directory + dirent **entries; // Entries in directory + char full[1024]; // Full name of file + + + entries = (dirent **)0; + n = fl_filename_list(directory, &entries); + + for (i = 0; i < n; i ++) { + if (entries[i]->d_name[0] != '.') { + snprintf(full, sizeof(full), "%s/%s", directory, entries[i]->d_name); + + if (fl_filename_isdir(full)) load_kde_icons(full, icondir); + else load_kde_mimelnk(full, icondir); + } + + free((void *)entries[i]); + } + + free((void*)entries); +} + + +// +// 'load_kde_mimelnk()' - Load a KDE "mimelnk" file. +// + +static void +load_kde_mimelnk(const char *filename, // I - mimelnk filename + const char *icondir) { // I - Location of icons + FILE *fp; + char tmp[1024]; + char iconfilename[1024]; + char pattern[1024]; + char mimetype[1024]; + char *val; + char full_iconfilename[1024]; + Fl_File_Icon *icon; + + + mimetype[0] = '\0'; + pattern[0] = '\0'; + iconfilename[0] = '\0'; + + if ((fp = fl_fopen(filename, "rb")) != NULL) { + while (fgets(tmp, sizeof(tmp), fp)) { + if ((val = get_kde_val(tmp, "Icon")) != NULL) + strlcpy(iconfilename, val, sizeof(iconfilename)); + else if ((val = get_kde_val(tmp, "MimeType")) != NULL) + strlcpy(mimetype, val, sizeof(mimetype)); + else if ((val = get_kde_val(tmp, "Patterns")) != NULL) + strlcpy(pattern, val, sizeof(pattern)); + } + + fclose(fp); + +#ifdef DEBUG + printf("%s: Icon=\"%s\", MimeType=\"%s\", Patterns=\"%s\"\n", filename, + iconfilename, mimetype, pattern); +#endif // DEBUG + + if (!pattern[0] && strncmp(mimetype, "inode/", 6)) return; + + if (iconfilename[0]) { + if (iconfilename[0] == '/') { + strlcpy(full_iconfilename, iconfilename, sizeof(full_iconfilename)); + } else if (!access(icondir, F_OK)) { + // KDE 3.x and 2.x icons + int i; // Looping var + static const char *paths[] = { // Subdirs to look in... + "16x16/actions", + "16x16/apps", + "16x16/devices", + "16x16/filesystems", + "16x16/mimetypes", +/* + "20x20/actions", + "20x20/apps", + "20x20/devices", + "20x20/filesystems", + "20x20/mimetypes", + + "22x22/actions", + "22x22/apps", + "22x22/devices", + "22x22/filesystems", + "22x22/mimetypes", + + "24x24/actions", + "24x24/apps", + "24x24/devices", + "24x24/filesystems", + "24x24/mimetypes", +*/ + "32x32/actions", + "32x32/apps", + "32x32/devices", + "32x32/filesystems", + "32x32/mimetypes", +/* + "36x36/actions", + "36x36/apps", + "36x36/devices", + "36x36/filesystems", + "36x36/mimetypes", + + "48x48/actions", + "48x48/apps", + "48x48/devices", + "48x48/filesystems", + "48x48/mimetypes", + + "64x64/actions", + "64x64/apps", + "64x64/devices", + "64x64/filesystems", + "64x64/mimetypes", + + "96x96/actions", + "96x96/apps", + "96x96/devices", + "96x96/filesystems", + "96x96/mimetypes" +*/ }; + + for (i = 0; i < (int)(sizeof(paths) / sizeof(paths[0])); i ++) { + snprintf(full_iconfilename, sizeof(full_iconfilename), + "%s/%s/%s.png", icondir, paths[i], iconfilename); + + if (!access(full_iconfilename, F_OK)) break; + } + + if (i >= (int)(sizeof(paths) / sizeof(paths[0]))) return; + } else { + // KDE 1.x icons + snprintf(full_iconfilename, sizeof(full_iconfilename), + "%s/%s", tmp, iconfilename); + + if (access(full_iconfilename, F_OK)) return; + } + + if (strncmp(mimetype, "inode/", 6) == 0) { + if (!strcmp(mimetype + 6, "directory")) + icon = new Fl_File_Icon("*", Fl_File_Icon::DIRECTORY); + else if (!strcmp(mimetype + 6, "blockdevice")) + icon = new Fl_File_Icon("*", Fl_File_Icon::DEVICE); + else if (!strcmp(mimetype + 6, "fifo")) + icon = new Fl_File_Icon("*", Fl_File_Icon::FIFO); + else return; + } else { + icon = new Fl_File_Icon(kde_to_fltk_pattern(pattern), + Fl_File_Icon::PLAIN); + } + + icon->load(full_iconfilename); + } + } +} + + +// +// 'kde_to_fltk_pattern()' - Convert a KDE pattern to a FLTK pattern. +// + +static char * +kde_to_fltk_pattern(const char *kdepattern) { + char *pattern, + *patptr; + + + pattern = (char *)malloc(strlen(kdepattern) + 3); + strcpy(pattern, "{"); + strcpy(pattern + 1, kdepattern); + + if (pattern[strlen(pattern) - 1] == ';') pattern[strlen(pattern) - 1] = '\0'; + + strcat(pattern, "}"); + + for (patptr = pattern; *patptr; patptr ++) { + if (*patptr == ';') *patptr = '|'; + } + + return (pattern); +} + + +// +// 'get_kde_val()' - Get a KDE value. +// + +static char * +get_kde_val(char *str, + const char *key) { + while (*str == *key) { + str ++; + key ++; + } + + if (*key == '\0' && *str == '=') { + if (str[strlen(str) - 1] == '\n') str[strlen(str) - 1] = '\0'; + + return (str + 1); + } + + return ((char *)0); +} + + +// +// End of "$Id: Fl_File_Icon2.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_File_Input.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_File_Input.cxx new file mode 100644 index 0000000..e404120 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_File_Input.cxx @@ -0,0 +1,297 @@ +// +// "$Id: Fl_File_Input.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// File_Input header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// Original version Copyright 1998 by Curtis Edwards. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include +#include +#include +#include "flstring.h" + + +// +// Height of directory buttons... +// + +#define DIR_HEIGHT 10 + + +// +// Redraw bit for directory bar... +// + +#define FL_DAMAGE_BAR 0x10 + + +/** + Creates a new Fl_File_Input widget using the given position, + size, and label string. The default boxtype is FL_DOWN_BOX. + \param[in] X, Y, W, H position and size of the widget + \param[in] L widget label, default is no label +*/ +Fl_File_Input::Fl_File_Input(int X, int Y, int W, int H, const char *L) + : Fl_Input(X, Y, W, H, L) { + buttons_[0] = 0; + errorcolor_ = FL_RED; + ok_entry_ = 1; + pressed_ = -1; + + down_box(FL_UP_BOX); +} + +/** + Draw directory buttons. +*/ +void Fl_File_Input::draw_buttons() { + int i, // Looping var + X; // Current X position + + + if (damage() & (FL_DAMAGE_BAR | FL_DAMAGE_ALL)) { + update_buttons(); + } + + for (X = 0, i = 0; buttons_[i]; i ++) + { + if ((X + buttons_[i]) > xscroll()) { + if (X < xscroll()) { + draw_box(pressed_ == i ? fl_down(down_box()) : down_box(), + x(), y(), X + buttons_[i] - xscroll(), DIR_HEIGHT, FL_GRAY); + } else if ((X + buttons_[i] - xscroll()) > w()) { + draw_box(pressed_ == i ? fl_down(down_box()) : down_box(), + x() + X - xscroll(), y(), w() - X + xscroll(), DIR_HEIGHT, + FL_GRAY); + } else { + draw_box(pressed_ == i ? fl_down(down_box()) : down_box(), + x() + X - xscroll(), y(), buttons_[i], DIR_HEIGHT, FL_GRAY); + } + } + + X += buttons_[i]; + } + + if (X < w()) { + draw_box(pressed_ == i ? fl_down(down_box()) : down_box(), + x() + X - xscroll(), y(), w() - X + xscroll(), DIR_HEIGHT, FL_GRAY); + } +} + +/** + Update the sizes of the directory buttons. +*/ +void Fl_File_Input::update_buttons() { + int i; // Looping var + const char *start, // Start of path component + *end; // End of path component + + +// puts("update_buttons()"); + + // Set the current font & size... + fl_font(textfont(), textsize()); + + // Loop through the value string, setting widths... + for (i = 0, start = value(); + start && i < (int)(sizeof(buttons_) / sizeof(buttons_[0]) - 1); + start = end, i ++) { +// printf(" start = \"%s\"\n", start); + if ((end = strchr(start, '/')) == NULL) +#if defined(WIN32) || defined(__EMX__) + if ((end = strchr(start, '\\')) == NULL) +#endif // WIN32 || __EMX__ + break; + + end ++; + + buttons_[i] = (short)fl_width(start, end - start); + if (!i) buttons_[i] += Fl::box_dx(box()) + 6; + } + +// printf(" found %d components/buttons...\n", i); + + buttons_[i] = 0; +} + + +/** + Sets the value of the widget given a new string value and its length. + Returns non 0 on success. + \param[in] str new string value + \param[in] len lengh of value +*/ +int // O - TRUE on success +Fl_File_Input::value(const char *str, // I - New string value + int len) { // I - Length of value + damage(FL_DAMAGE_BAR); + return Fl_Input::value(str,len); +} + + +/** + Sets the value of the widget given a new string value. + Returns non 0 on success. + \param[in] str new string value +*/ +int // O - TRUE on success +Fl_File_Input::value(const char *str) { // I - New string value + damage(FL_DAMAGE_BAR); + return Fl_Input::value(str); +} + + +/** + Draws the file input widget +*/ +void Fl_File_Input::draw() { + Fl_Boxtype b = box(); + if (damage() & (FL_DAMAGE_BAR | FL_DAMAGE_ALL)) draw_buttons(); + // this flag keeps Fl_Input_::drawtext from drawing a bogus box! + char must_trick_fl_input_ = + Fl::focus()!=this && !size() && !(damage()&FL_DAMAGE_ALL); + if ((damage() & FL_DAMAGE_ALL) || must_trick_fl_input_) + draw_box(b,x(),y()+DIR_HEIGHT,w(),h()-DIR_HEIGHT,color()); + if (!must_trick_fl_input_) + Fl_Input_::drawtext(x()+Fl::box_dx(b)+3, y()+Fl::box_dy(b)+DIR_HEIGHT, + w()-Fl::box_dw(b)-6, h()-Fl::box_dh(b)-DIR_HEIGHT); +} + + + +/** + Handle events in the widget. + Return non zero if event is handled. + \param[in] event +*/ +int // O - TRUE if we handled event +Fl_File_Input::handle(int event) // I - Event +{ +// printf("handle(event = %d)\n", event); + static char inButtonBar = 0; + + switch (event) { + case FL_MOVE : + case FL_ENTER : + if (active_r()) { + if (Fl::event_y() < (y() + DIR_HEIGHT)) + window()->cursor(FL_CURSOR_DEFAULT); + else + window()->cursor(FL_CURSOR_INSERT); + } + + return 1; + + case FL_PUSH : + inButtonBar = (Fl::event_y() < (y() + DIR_HEIGHT)); + case FL_RELEASE : + case FL_DRAG : + if (inButtonBar) + return handle_button(event); + else + return Fl_Input::handle(event); + + default : + { Fl_Widget_Tracker wp(this); + if (Fl_Input::handle(event)) { + if (wp.exists()) + damage(FL_DAMAGE_BAR); + return 1; + } + } + return 0; + } +} + + + +/** + Handles button events in the widget. + Return non zero if event is handled. + \param[in] event +*/ +int // O - TRUE if we handled event +Fl_File_Input::handle_button(int event) // I - Event +{ + int i, // Looping var + X; // Current X position + char *start, // Start of path component + *end; // End of path component + char newvalue[1024]; // New value + + + // Figure out which button is being pressed... + for (X = 0, i = 0; buttons_[i]; i ++) + { + X += buttons_[i]; + + if (X > xscroll() && Fl::event_x() < (x() + X - xscroll())) break; + } + +// printf("handle_button(event = %d), button = %d\n", event, i); + + // Redraw the directory bar... + if (event == FL_RELEASE) pressed_ = -1; + else pressed_ = (short)i; + + window()->make_current(); + draw_buttons(); + + // Return immediately if the user is clicking on the last button or + // has not released the mouse button... + if (!buttons_[i] || event != FL_RELEASE) return 1; + + // Figure out where to truncate the path... + strlcpy(newvalue, value(), sizeof(newvalue)); + + for (start = newvalue, end = start; start && i >= 0; start = end, i --) { +// printf(" start = \"%s\"\n", start); + if ((end = strchr(start, '/')) == NULL) +#if defined(WIN32) || defined(__EMX__) + if ((end = strchr(start, '\\')) == NULL) +#endif // WIN32 || __EMX__ + break; + + end ++; + } + + if (i < 0) { + // Found the end; truncate the value and update the buttons... + *start = '\0'; + value(newvalue, start - newvalue); + + // Then do the callbacks, if necessary... + set_changed(); + if (when() & (FL_WHEN_CHANGED|FL_WHEN_RELEASE) ) do_callback(); + } + + return 1; +} + + +// +// End of "$Id: Fl_File_Input.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Font.H b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Font.H new file mode 100644 index 0000000..4e79b3f --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Font.H @@ -0,0 +1,119 @@ +// +// "$Id: Fl_Font.H 7351 2010-03-29 10:35:00Z matt $" +// +// Font definitions for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2009 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Two internal fltk data structures: +// +// Fl_Fontdesc: an entry into the fl_font() table. There is one of these +// for each fltk font number. +// +#ifndef FL_FONT_ +#define FL_FONT_ + +#include + +# if USE_XFT +typedef struct _XftFont XftFont; +# elif !defined(WIN32) && !defined(__APPLE__) +# include +# endif // USE_XFT + +/** + This a structure for an actual system font, with junk to + help choose it and info on character sizes. Each Fl_Fontdesc has a + linked list of these. These are created the first time each system + font/size combination is used. +*/ +class Fl_Font_Descriptor { +public: + /** linked list for this Fl_Fontdesc */ + Fl_Font_Descriptor *next; +#ifndef FL_DOXYGEN // don't bother with platorm dependant details in the doc. +# ifdef WIN32 + HFONT fid; + int *width[64]; + TEXTMETRIC metr; + int angle; + FL_EXPORT Fl_Font_Descriptor(const char* fontname, Fl_Fontsize size); +# elif defined(__APPLE_QUARTZ__) + FL_EXPORT Fl_Font_Descriptor(const char* fontname, Fl_Fontsize size); + ATSUTextLayout layout; +# if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + CTFontRef fontref; +# endif + ATSUStyle style; + short ascent, descent, q_width; +// short width[256]; +// bool knowWidths; + char *q_name; + int size; +# elif USE_XFT + XftFont* font; + const char* encoding; + Fl_Fontsize size; + int angle; + FL_EXPORT Fl_Font_Descriptor(const char* xfontname); +# else + XUtf8FontStruct* font; // X UTF-8 font information + FL_EXPORT Fl_Font_Descriptor(const char* xfontname); +# endif + Fl_Fontsize minsize; // smallest point size that should use this + Fl_Fontsize maxsize; // largest point size that should use this +# if HAVE_GL + unsigned int listbase;// base of display list, 0 = none + char glok[64]; +# endif + + FL_EXPORT ~Fl_Font_Descriptor(); + +#endif // FL_DOXYGEN +}; + +extern FL_EXPORT Fl_Font_Descriptor *fl_fontsize; // the currently selected one + +struct Fl_Fontdesc { + const char *name; + char fontname[128]; // "Pretty" font name + Fl_Font_Descriptor *first; // linked list of sizes of this style +# ifndef WIN32 + char **xlist; // matched X font names + int n; // size of xlist, negative = don't free xlist! +# endif +}; + +extern FL_EXPORT Fl_Fontdesc *fl_fonts; // the table + +# ifndef WIN32 +// functions for parsing X font names: +FL_EXPORT const char* fl_font_word(const char *p, int n); +FL_EXPORT char *fl_find_fontsize(char *name); +# endif + +#endif + +// +// End of "$Id: Fl_Font.H 7351 2010-03-29 10:35:00Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_GDI_Printer.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_GDI_Printer.cxx new file mode 100644 index 0000000..79c1587 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_GDI_Printer.cxx @@ -0,0 +1,286 @@ +// +// "$Id: Fl_GDI_Printer.cxx 7659 2010-07-01 13:21:32Z manolo $" +// +// Support for WIN32 printing for the Fast Light Tool Kit (FLTK). +// +// Copyright 2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifdef WIN32 +#include + + +#include +#include + +extern HWND fl_window; + +Fl_Printer::Fl_System_Printer(void) : Fl_Paged_Device() { + hPr = NULL; + type_ = device_type; + driver(fl_graphics_driver); +} + +Fl_Printer::~Fl_System_Printer(void) { + if (hPr) end_job(); +} + +static void WIN_SetupPrinterDeviceContext(HDC prHDC) +{ + if ( !prHDC ) return; + + fl_window = 0; + fl_gc = prHDC; + SetGraphicsMode(prHDC, GM_ADVANCED); // to allow for rotations + SetMapMode(prHDC, MM_ANISOTROPIC); + SetTextAlign(prHDC, TA_BASELINE|TA_LEFT); + SetBkMode(prHDC, TRANSPARENT); + // this matches 720 logical units to the number of device units in 10 inches of paper + // thus the logical unit is the point (= 1/72 inch) + SetWindowExtEx(prHDC, 720, 720, NULL); + SetViewportExtEx(prHDC, 10*GetDeviceCaps(prHDC, LOGPIXELSX), 10*GetDeviceCaps(prHDC, LOGPIXELSY), NULL); +} + + +int Fl_Printer::start_job (int pagecount, int *frompage, int *topage) +// returns 0 iff OK +{ + DWORD commdlgerr; + DOCINFO di; + char docName [256]; + int err = 0; + + abortPrint = FALSE; + memset (&pd, 0, sizeof (PRINTDLG)); + pd.lStructSize = sizeof (PRINTDLG); + pd.hwndOwner = GetForegroundWindow(); + pd.Flags = PD_RETURNDC | PD_USEDEVMODECOPIESANDCOLLATE | PD_NOSELECTION; + pd.nMinPage = 1; + pd.nMaxPage = pagecount; + if (PrintDlg (&pd) != 0) { + hPr = pd.hDC; + if (hPr != NULL) { + strcpy (docName, "FLTK"); + memset(&di, 0, sizeof(DOCINFO)); + di.cbSize = sizeof (DOCINFO); + di.lpszDocName = (LPCSTR) docName; + prerr = StartDoc (hPr, &di); + if (prerr < 1) { + abortPrint = TRUE; + //fl_alert ("StartDoc error %d", prerr); + err = 1; + } + } else { + commdlgerr = CommDlgExtendedError (); + fl_alert ("Unable to create print context, error %lu", + (unsigned long) commdlgerr); + err = 1; + } + } else { + err = 1; + } + if(!err) { + if((pd.Flags & PD_PAGENUMS) != 0 ) { + if (frompage) *frompage = pd.nFromPage; + if (topage) *topage = pd.nToPage; + } + else { + if (frompage) *frompage = 1; + if (topage) *topage = pagecount; + } + x_offset = 0; + y_offset = 0; + WIN_SetupPrinterDeviceContext (hPr); + gc = (void *)fl_gc; + this->set_current(); + } + return err; +} + +void Fl_Printer::end_job (void) +{ + Fl_Display_Device::display_device()->set_current(); + if (hPr != NULL) { + if (! abortPrint) { + prerr = EndDoc (hPr); + if (prerr < 0) { + fl_alert ("EndDoc error %d", prerr); + } + } + DeleteDC (hPr); + if (pd.hDevMode != NULL) { + GlobalFree (pd.hDevMode); + } + if (pd.hDevNames != NULL) { + GlobalFree (pd.hDevNames); + } + } + hPr = NULL; +} + +void Fl_Printer::absolute_printable_rect(int *x, int *y, int *w, int *h) +{ + POINT physPageSize; + POINT pixelsPerInch; + + if (hPr == NULL) return; + SetWindowOrgEx(fl_gc, 0, 0, NULL); + + physPageSize.x = GetDeviceCaps(hPr, HORZRES); + physPageSize.y = GetDeviceCaps(hPr, VERTRES); + DPtoLP(hPr, &physPageSize, 1); + *w = physPageSize.x + 1; + *h = physPageSize.y + 1; + pixelsPerInch.x = GetDeviceCaps(hPr, LOGPIXELSX); + pixelsPerInch.y = GetDeviceCaps(hPr, LOGPIXELSY); + DPtoLP(hPr, &pixelsPerInch, 1); + left_margin = (pixelsPerInch.x / 4); + *w -= (pixelsPerInch.x / 2); + top_margin = (pixelsPerInch.y / 4); + *h -= (pixelsPerInch.y / 2); + + *x = left_margin; + *y = top_margin; + origin(x_offset, y_offset); +} + +void Fl_Printer::margins(int *left, int *top, int *right, int *bottom) +{ + int x, y, w, h; + absolute_printable_rect(&x, &y, &w, &h); + if (left) *left = x; + if (top) *top = y; + if (right) *right = x; + if (bottom) *bottom = y; +} + +int Fl_Printer::printable_rect(int *w, int *h) +{ + int x, y; + absolute_printable_rect(&x, &y, w, h); + return 0; +} + +int Fl_Printer::start_page (void) +{ + int rsult, w, h; + + rsult = 0; + if (hPr != NULL) { + WIN_SetupPrinterDeviceContext (hPr); + prerr = StartPage (hPr); + if (prerr < 0) { + fl_alert ("StartPage error %d", prerr); + rsult = 1; + } + printable_rect(&w, &h); + origin(0, 0); + image_list_ = NULL; + fl_clip_region(0); + gc = (void *)fl_gc; + } + return rsult; +} + +void Fl_Printer::origin (int deltax, int deltay) +{ + SetWindowOrgEx(fl_gc, - left_margin - deltax, - top_margin - deltay, NULL); + x_offset = deltax; + y_offset = deltay; +} + +void Fl_Printer::scale (float scalex, float scaley) +{ + int w, h; + SetWindowExtEx(fl_gc, (int)(720 / scalex + 0.5), (int)(720 / scaley + 0.5), NULL); + printable_rect(&w, &h); + origin(0, 0); +} + +void Fl_Printer::rotate (float rot_angle) +{ + XFORM mat; + float angle; + angle = - rot_angle * M_PI / 180.; + mat.eM11 = cos(angle); + mat.eM12 = sin(angle); + mat.eM21 = - mat.eM12; + mat.eM22 = mat.eM11; + mat.eDx = mat.eDy = 0; + SetWorldTransform(fl_gc, &mat); +} + +int Fl_Printer::end_page (void) +{ + int rsult; + + rsult = 0; + if (hPr != NULL) { + prerr = EndPage (hPr); + if (prerr < 0) { + abortPrint = TRUE; + fl_alert ("EndPage error %d", prerr); + rsult = 1; + } + } + gc = NULL; + return rsult; +} + +static int translate_stack_depth = 0; +const int translate_stack_max = 5; +static int translate_stack_x[translate_stack_max]; +static int translate_stack_y[translate_stack_max]; + +static void do_translate(int x, int y) +{ + XFORM tr; + tr.eM11 = tr.eM22 = 1; + tr.eM12 = tr.eM21 = 0; + tr.eDx = x; + tr.eDy = y; + ModifyWorldTransform(fl_gc, &tr, MWT_LEFTMULTIPLY); +} + +void Fl_Printer::translate (int x, int y) +{ + do_translate(x, y); + if (translate_stack_depth < translate_stack_max) { + translate_stack_x[translate_stack_depth] = x; + translate_stack_y[translate_stack_depth] = y; + translate_stack_depth++; + } +} + +void Fl_Printer::untranslate (void) +{ + if (translate_stack_depth > 0) { + translate_stack_depth--; + do_translate( - translate_stack_x[translate_stack_depth], - translate_stack_y[translate_stack_depth] ); + } +} + +#endif // WIN32 + +// +// End of "$Id: Fl_GDI_Printer.cxx 7659 2010-07-01 13:21:32Z manolo $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_GIF_Image.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_GIF_Image.cxx new file mode 100644 index 0000000..c4d5811 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_GIF_Image.cxx @@ -0,0 +1,390 @@ +// +// "$Id: Fl_GIF_Image.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Fl_GIF_Image routines. +// +// Copyright 1997-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// +// Contents: +// +// + +// +// Include necessary header files... +// + +#include +#include +#include +#include +#include +#include "flstring.h" + +// Read a .gif file and convert it to a "xpm" format (actually my +// modified one with compressed colormaps). + +// Extensively modified from original code for gif2ras by +// Patrick J. Naughton of Sun Microsystems. The original +// copyright notice follows: + +/* gif2ras.c - Converts from a Compuserve GIF (tm) image to a Sun Raster image. + * + * Copyright (c) 1988 by Patrick J. Naughton + * + * Author: Patrick J. Naughton + * naughton@wind.sun.com + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation. + * + * This file is provided AS IS with no warranties of any kind. The author + * shall have no liability with respect to the infringement of copyrights, + * trade secrets or any patents by this file or any part thereof. In no + * event will the author be liable for any lost revenue or profits or + * other special, indirect and consequential damages. + * + * Comments and additions should be sent to the author: + * + * Patrick J. Naughton + * Sun Microsystems, Inc. + * 2550 Garcia Ave, MS 14-40 + * Mountain View, CA 94043 + * (415) 336-1080 + */ + +typedef unsigned char uchar; + +#define NEXTBYTE (uchar)getc(GifFile) +#define GETSHORT(var) var = NEXTBYTE; var += NEXTBYTE << 8 + +/** + The constructor loads the named GIF image. +

The inherited destructor free all memory and server resources that are used by + the image. +*/ +Fl_GIF_Image::Fl_GIF_Image(const char *infname) : Fl_Pixmap((char *const*)0) { + FILE *GifFile; // File to read + char **new_data; // Data array + + if ((GifFile = fl_fopen(infname, "rb")) == NULL) { + Fl::error("Fl_GIF_Image: Unable to open %s!", infname); + return; + } + + {char b[6]; + if (fread(b,1,6,GifFile)<6) { + fclose(GifFile); + return; /* quit on eof */ + } + if (b[0]!='G' || b[1]!='I' || b[2] != 'F') { + fclose(GifFile); + Fl::error("Fl_GIF_Image: %s is not a GIF file.\n", infname); + return; + } + if (b[3]!='8' || b[4]>'9' || b[5]!= 'a') + Fl::warning("%s is version %c%c%c.",infname,b[3],b[4],b[5]); + } + + int Width; GETSHORT(Width); + int Height; GETSHORT(Height); + + uchar ch = NEXTBYTE; + char HasColormap = ((ch & 0x80) != 0); + int BitsPerPixel = (ch & 7) + 1; + int ColorMapSize = 1 << BitsPerPixel; + // int OriginalResolution = ((ch>>4)&7)+1; + // int SortedTable = (ch&8)!=0; + ch = NEXTBYTE; // Background Color index + ch = NEXTBYTE; // Aspect ratio is N/64 + + // Read in global colormap: + uchar transparent_pixel = 0; + char has_transparent = 0; + uchar Red[256], Green[256], Blue[256]; /* color map */ + if (HasColormap) { + for (int i=0; i < ColorMapSize; i++) { + Red[i] = NEXTBYTE; + Green[i] = NEXTBYTE; + Blue[i] = NEXTBYTE; + } + } else { + Fl::warning("%s does not have a colormap.", infname); + for (int i = 0; i < ColorMapSize; i++) + Red[i] = Green[i] = Blue[i] = (uchar)(255 * i / (ColorMapSize-1)); + } + + int CodeSize; /* Code size, init from GIF header, increases... */ + char Interlace; + + for (;;) { + + int i = NEXTBYTE; + if (i<0) { + fclose(GifFile); + Fl::error("Fl_GIF_Image: %s - unexpected EOF",infname); + return; + } + int blocklen; + + // if (i == 0x3B) return 0; eof code + + if (i == 0x21) { // a "gif extension" + + ch = NEXTBYTE; + blocklen = NEXTBYTE; + + if (ch==0xF9 && blocklen==4) { // Netscape animation extension + + char bits; + bits = NEXTBYTE; + getc(GifFile); getc(GifFile); // GETSHORT(delay); + transparent_pixel = NEXTBYTE; + if (bits & 1) has_transparent = 1; + blocklen = NEXTBYTE; + + } else if (ch == 0xFF) { // Netscape repeat count + ; + + } else if (ch != 0xFE) { //Gif Comment + Fl::warning("%s: unknown gif extension 0x%02x.", infname, ch); + } + } else if (i == 0x2c) { // an image + + ch = NEXTBYTE; ch = NEXTBYTE; // GETSHORT(x_position); + ch = NEXTBYTE; ch = NEXTBYTE; // GETSHORT(y_position); + GETSHORT(Width); + GETSHORT(Height); + ch = NEXTBYTE; + Interlace = ((ch & 0x40) != 0); + if (ch&0x80) { + // read local color map + int n = 2<<(ch&7); + for (i=0; i < n; i++) { + Red[i] = NEXTBYTE; + Green[i] = NEXTBYTE; + Blue[i] = NEXTBYTE; + } + } + CodeSize = NEXTBYTE+1; + break; // okay, this is the image we want + } else { + Fl::warning("%s: unknown gif code 0x%02x", infname, i); + blocklen = 0; + } + + // skip the data: + while (blocklen>0) {while (blocklen--) {ch = NEXTBYTE;} blocklen=NEXTBYTE;} + } + + if (BitsPerPixel >= CodeSize) + { + // Workaround for broken GIF files... + BitsPerPixel = CodeSize - 1; + ColorMapSize = 1 << BitsPerPixel; + } + + uchar *Image = new uchar[Width*Height]; + + int YC = 0, Pass = 0; /* Used to de-interlace the picture */ + uchar *p = Image; + uchar *eol = p+Width; + + int InitCodeSize = CodeSize; + int ClearCode = (1 << (CodeSize-1)); + int EOFCode = ClearCode + 1; + int FirstFree = ClearCode + 2; + int FinChar = 0; + int ReadMask = (1< 7) { + if (blocklen <= 0) { + blocklen = NEXTBYTE; + if (blocklen <= 0) break; + } + thisbyte = NEXTBYTE; blocklen--; + CurCode |= thisbyte<<8; + } + if (frombit+CodeSize > 15) { + if (blocklen <= 0) { + blocklen = NEXTBYTE; + if (blocklen <= 0) break; + } + thisbyte = NEXTBYTE; blocklen--; + CurCode |= thisbyte<<16; + } + CurCode = (CurCode>>frombit)&ReadMask; + frombit = (frombit+CodeSize)%8; + + if (CurCode == ClearCode) { + CodeSize = InitCodeSize; + ReadMask = (1<= ColorMapSize) {*tp++ = Suffix[i]; i = Prefix[i];} + *tp++ = FinChar = i; + do { + *p++ = *--tp; + if (p >= eol) { + if (!Interlace) YC++; + else switch (Pass) { + case 0: YC += 8; if (YC >= Height) {Pass++; YC = 4;} break; + case 1: YC += 8; if (YC >= Height) {Pass++; YC = 2;} break; + case 2: YC += 4; if (YC >= Height) {Pass++; YC = 1;} break; + case 3: YC += 2; break; + } + if (YC>=Height) YC=0; /* cheap bug fix when excess data */ + p = Image + YC*Width; + eol = p+Width; + } + } while (tp > OutCode); + + if (OldCode != ClearCode) { + Prefix[FreeCode] = (short)OldCode; + Suffix[FreeCode] = FinChar; + FreeCode++; + if (FreeCode > ReadMask) { + if (CodeSize < 12) { + CodeSize++; + ReadMask = (1 << CodeSize) - 1; + } + else FreeCode--; + } + } + OldCode = CurCode; + } + + // We are done reading the file, now convert to xpm: + + // allocate line pointer arrays: + w(Width); + h(Height); + d(1); + new_data = new char*[Height+2]; + + // transparent pixel must be zero, swap if it isn't: + if (has_transparent && transparent_pixel != 0) { + // swap transparent pixel with zero + p = Image+Width*Height; + while (p-- > Image) { + if (*p==transparent_pixel) *p = 0; + else if (!*p) *p = transparent_pixel; + } + uchar t; + t = Red[0]; + Red[0] = Red[transparent_pixel]; + Red[transparent_pixel] = t; + + t = Green[0]; + Green[0] = Green[transparent_pixel]; + Green[transparent_pixel] = t; + + t = Blue[0]; + Blue[0] = Blue[transparent_pixel]; + Blue[transparent_pixel] = t; + } + + // find out what colors are actually used: + uchar used[256]; uchar remap[256]; + int i; + for (i = 0; i < ColorMapSize; i++) used[i] = 0; + p = Image+Width*Height; + while (p-- > Image) used[*p] = 1; + + // remap them to start with printing characters: + int base = has_transparent && used[0] ? ' ' : ' '+1; + int numcolors = 0; + for (i = 0; i < ColorMapSize; i++) if (used[i]) { + remap[i] = (uchar)(base++); + numcolors++; + } + + // write the first line of xpm data (use suffix as temp array): + int length = sprintf((char*)(Suffix), + "%d %d %d %d",Width,Height,-numcolors,1); + new_data[0] = new char[length+1]; + strcpy(new_data[0], (char*)Suffix); + + // write the colormap + new_data[1] = (char*)(p = new uchar[4*numcolors]); + for (i = 0; i < ColorMapSize; i++) if (used[i]) { + *p++ = remap[i]; + *p++ = Red[i]; + *p++ = Green[i]; + *p++ = Blue[i]; + } + + // remap the image data: + p = Image+Width*Height; + while (p-- > Image) *p = remap[*p]; + + // split the image data into lines: + for (i=0; i +# define GLContext HGLRC +#elif defined(__APPLE_QUARTZ__) +// warning: the Quartz version should probably use Core GL (CGL) instead of AGL +# include +# include +# define GLContext AGLContext +#else +# include +# define GLContext GLXContext +#endif + +// Describes crap needed to create a GLContext. +class Fl_Gl_Choice { + int mode; + const int *alist; + Fl_Gl_Choice *next; +public: +#ifdef WIN32 + int pixelformat; // the visual to use + PIXELFORMATDESCRIPTOR pfd; // some wgl calls need this thing +#elif defined(__APPLE_QUARTZ__) + // warning: the Quartz version should probably use Core GL (CGL) instead of AGL + AGLPixelFormat pixelformat; +#else + XVisualInfo *vis; // the visual to use + Colormap colormap; // a colormap for that visual +#endif + // Return one of these structures for a given gl mode. + // The second argument is a glX attribute list, and is used if mode is + // zero. This is not supported on Win32: + static Fl_Gl_Choice *find(int mode, const int *); +}; + +class Fl_Window; + +#ifdef WIN32 + +GLContext fl_create_gl_context(Fl_Window*, const Fl_Gl_Choice*, int layer=0); + +#elif defined(__APPLE_QUARTZ__) +// warning: the Quartz version should probably use Core GL (CGL) instead of AGL + +GLContext fl_create_gl_context(Fl_Window*, const Fl_Gl_Choice*, int layer=0); + +#else + +GLContext fl_create_gl_context(XVisualInfo* vis); + +static inline +GLContext fl_create_gl_context(Fl_Window*, const Fl_Gl_Choice* g) { + return fl_create_gl_context(g->vis); +} + +#endif + +void fl_set_gl_context(Fl_Window*, GLContext); +void fl_no_gl_context(); +void fl_delete_gl_context(GLContext); + +#endif + +// +// End of "$Id: Fl_Gl_Choice.H 7564 2010-04-28 07:21:41Z greg.ercolano $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Gl_Choice.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Gl_Choice.cxx new file mode 100644 index 0000000..59bbd7b --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Gl_Choice.cxx @@ -0,0 +1,416 @@ +// +// "$Id: Fl_Gl_Choice.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// OpenGL visual selection code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#if HAVE_GL + +# include +# include +# include +# include "Fl_Gl_Choice.H" +# include +# include "flstring.h" +# include + +# ifdef __APPLE__ +# include +# include +# endif + +# ifdef WIN32 +void fl_save_dc(HWND, HDC); +# endif + +static Fl_Gl_Choice *first; + +// this assumes one of the two arguments is zero: +// We keep the list system in Win32 to stay compatible and interpret +// the list later... +Fl_Gl_Choice *Fl_Gl_Choice::find(int m, const int *alistp) { + Fl_Gl_Choice *g; + + for (g = first; g; g = g->next) + if (g->mode == m && g->alist == alistp) + return g; + +#if defined(USE_X11) + const int *blist; + int list[32]; + + if (alistp) + blist = alistp; + else { + int n = 0; + if (m & FL_INDEX) { + list[n++] = GLX_BUFFER_SIZE; + list[n++] = 8; // glut tries many sizes, but this should work... + } else { + list[n++] = GLX_RGBA; + list[n++] = GLX_GREEN_SIZE; + list[n++] = (m & FL_RGB8) ? 8 : 1; + if (m & FL_ALPHA) { + list[n++] = GLX_ALPHA_SIZE; + list[n++] = (m & FL_RGB8) ? 8 : 1; + } + if (m & FL_ACCUM) { + list[n++] = GLX_ACCUM_GREEN_SIZE; + list[n++] = 1; + if (m & FL_ALPHA) { + list[n++] = GLX_ACCUM_ALPHA_SIZE; + list[n++] = 1; + } + } + } + if (m & FL_DOUBLE) { + list[n++] = GLX_DOUBLEBUFFER; + } + if (m & FL_DEPTH) { + list[n++] = GLX_DEPTH_SIZE; list[n++] = 1; + } + if (m & FL_STENCIL) { + list[n++] = GLX_STENCIL_SIZE; list[n++] = 1; + } + if (m & FL_STEREO) { + list[n++] = GLX_STEREO; + } +# if defined(GLX_VERSION_1_1) && defined(GLX_SGIS_multisample) + if (m & FL_MULTISAMPLE) { + list[n++] = GLX_SAMPLES_SGIS; + list[n++] = 4; // value Glut uses + } +# endif + list[n] = 0; + blist = list; + } + + fl_open_display(); + XVisualInfo *visp = glXChooseVisual(fl_display, fl_screen, (int *)blist); + if (!visp) { +# if defined(GLX_VERSION_1_1) && defined(GLX_SGIS_multisample) + if (m&FL_MULTISAMPLE) return find(m&~FL_MULTISAMPLE,0); +# endif + return 0; + } + +#elif defined(__APPLE_QUARTZ__) + // warning: the Quartz version should probably use Core GL (CGL) instead of AGL + const int *blist; + int list[32]; + + if (alistp) + blist = alistp; + else { + int n = 0; + if (m & FL_INDEX) { + list[n++] = AGL_BUFFER_SIZE; + list[n++] = 8; // glut tries many sizes, but this should work... + } else { + list[n++] = AGL_RGBA; + list[n++] = AGL_GREEN_SIZE; + list[n++] = (m & FL_RGB8) ? 8 : 1; + if (m & FL_ALPHA) { + list[n++] = AGL_ALPHA_SIZE; + list[n++] = (m & FL_RGB8) ? 8 : 1; + } + if (m & FL_ACCUM) { + list[n++] = AGL_ACCUM_GREEN_SIZE; + list[n++] = 1; + if (m & FL_ALPHA) { + list[n++] = AGL_ACCUM_ALPHA_SIZE; + list[n++] = 1; + } + } + } + if (m & FL_DOUBLE) { + list[n++] = AGL_DOUBLEBUFFER; + } + if (m & FL_DEPTH) { + list[n++] = AGL_DEPTH_SIZE; list[n++] = 24; + } + if (m & FL_STENCIL) { + list[n++] = AGL_STENCIL_SIZE; list[n++] = 1; + } +# ifdef AGL_STEREO + if (m & FL_STEREO) { + list[n++] = AGL_STEREO; + } +# endif + list[n] = AGL_NONE; + blist = list; + } + fl_open_display(); + AGLPixelFormat fmt = aglChoosePixelFormat(NULL, 0, (GLint*)blist); + if (!fmt) return 0; + +#elif defined(WIN32) + + // Replacement for ChoosePixelFormat() that finds one with an overlay + // if possible: + if (!fl_gc) fl_GetDC(0); + int pixelformat = 0; + PIXELFORMATDESCRIPTOR chosen_pfd; + for (int i = 1; ; i++) { + PIXELFORMATDESCRIPTOR pfd; + if (!DescribePixelFormat(fl_gc, i, sizeof(pfd), &pfd)) break; + // continue if it does not satisfy our requirements: + if (~pfd.dwFlags & (PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL)) continue; + if (pfd.iPixelType != ((m&FL_INDEX)?PFD_TYPE_COLORINDEX:PFD_TYPE_RGBA)) continue; + if ((m & FL_ALPHA) && !pfd.cAlphaBits) continue; + if ((m & FL_ACCUM) && !pfd.cAccumBits) continue; + if ((!(m & FL_DOUBLE)) != (!(pfd.dwFlags & PFD_DOUBLEBUFFER))) continue; + if ((!(m & FL_STEREO)) != (!(pfd.dwFlags & PFD_STEREO))) continue; + if ((m & FL_DEPTH) && !pfd.cDepthBits) continue; + if ((m & FL_STENCIL) && !pfd.cStencilBits) continue; + // see if better than the one we have already: + if (pixelformat) { + // offering non-generic rendering is better (read: hardware accelleration) + if (!(chosen_pfd.dwFlags & PFD_GENERIC_FORMAT) && + (pfd.dwFlags & PFD_GENERIC_FORMAT)) continue; + // offering overlay is better: + else if (!(chosen_pfd.bReserved & 15) && (pfd.bReserved & 15)) {} + // otherwise more bit planes is better: + else if (chosen_pfd.cColorBits > pfd.cColorBits) continue; + else if (chosen_pfd.cDepthBits > pfd.cDepthBits) continue; + } + pixelformat = i; + chosen_pfd = pfd; + } + //printf("Chosen pixel format is %d\n", pixelformat); + if (!pixelformat) return 0; +#else +# error platform unsupported +#endif + + g = new Fl_Gl_Choice; + g->mode = m; + g->alist = alistp; + g->next = first; + first = g; + +#if defined(USE_X11) + g->vis = visp; + + if (/*MaxCmapsOfScreen(ScreenOfDisplay(fl_display,fl_screen))==1 && */ + visp->visualid == fl_visual->visualid && + !fl_getenv("MESA_PRIVATE_CMAP")) + g->colormap = fl_colormap; + else + g->colormap = XCreateColormap(fl_display, RootWindow(fl_display,fl_screen), + visp->visual, AllocNone); +# elif defined(WIN32) + g->pixelformat = pixelformat; + g->pfd = chosen_pfd; +# elif defined(__APPLE_QUARTZ__) + // warning: the Quartz version should probably use Core GL (CGL) instead of AGL + g->pixelformat = fmt; +# else +# error unsupported platform +# endif + + return g; +} + +static GLContext *context_list = 0; +static int nContext = 0, NContext = 0; + +static void add_context(GLContext ctx) { + if (!ctx) return; + if (nContext==NContext) { + if (!NContext) NContext = 8; + NContext *= 2; + context_list = (GLContext*)realloc( + context_list, NContext*sizeof(GLContext)); + } + context_list[nContext++] = ctx; +} + +static void del_context(GLContext ctx) { + int i; + for (i=0; iprivate_dc; + if (!hdc) { + hdc = i->private_dc = GetDCEx(i->xid, 0, DCX_CACHE); + fl_save_dc(i->xid, hdc); + SetPixelFormat(hdc, g->pixelformat, (PIXELFORMATDESCRIPTOR*)(&g->pfd)); +# if USE_COLORMAP + if (fl_palette) SelectPalette(hdc, fl_palette, FALSE); +# endif + } + GLContext context = + layer ? wglCreateLayerContext(hdc, layer) : wglCreateContext(hdc); + if (context) { + if (context_list && nContext) + wglShareLists(context_list[0], context); + add_context(context); + } + return context; +} + +# elif defined(__APPLE_QUARTZ__) +// warning: the Quartz version should probably use Core GL (CGL) instead of AGL +GLContext fl_create_gl_context(Fl_Window* window, const Fl_Gl_Choice* g, int layer) { + GLContext context, shared_ctx = 0; + if (context_list && nContext) shared_ctx = context_list[0]; + context = aglCreateContext( g->pixelformat, shared_ctx); + if (!context) return 0; + add_context((GLContext)context); + if ( window->parent() ) { + int H = window->window()->h(); + GLint rect[] = { window->x(), H-window->h()-window->y(), window->w(), window->h() }; + aglSetInteger( (GLContext)context, AGL_BUFFER_RECT, rect ); + aglEnable( (GLContext)context, AGL_BUFFER_RECT ); + } +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 +#if __LP64__ + // 64 bit version + aglSetWindowRef(context, MACwindowRef(window) ); +#else + // 32 bit version >= 10.5 + if (aglSetWindowRef != NULL) + aglSetWindowRef(context, MACwindowRef(window) ); + else + aglSetDrawable( context, GetWindowPort( MACwindowRef(window) ) ); +#endif +#else + // 32 bit version < 10.5 + aglSetDrawable( context, GetWindowPort( MACwindowRef(window) ) ); +#endif + return (context); +} +# else +# error unsupported platform +# endif + +static GLContext cached_context; +static Fl_Window* cached_window; + +void fl_set_gl_context(Fl_Window* w, GLContext context) { + if (context != cached_context || w != cached_window) { + cached_context = context; + cached_window = w; +# if defined(USE_X11) + glXMakeCurrent(fl_display, fl_xid(w), context); +# elif defined(WIN32) + wglMakeCurrent(Fl_X::i(w)->private_dc, context); +# elif defined(__APPLE_QUARTZ__) + // warning: the Quartz version should probably use Core GL (CGL) instead of AGL + if ( w->parent() ) { //: resize our GL buffer rectangle + int H = w->window()->h(); + GLint rect[] = { w->x(), H-w->h()-w->y(), w->w(), w->h() }; + aglSetInteger( context, AGL_BUFFER_RECT, rect ); + aglEnable( context, AGL_BUFFER_RECT ); + } +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 +#if __LP64__ + // 64 bit version + aglSetWindowRef(context, MACwindowRef(w) ); +#else + // 32 bit version >= 10.5 + if (aglSetWindowRef != NULL) + aglSetWindowRef(context, MACwindowRef(w) ); + else + aglSetDrawable( context, GetWindowPort( MACwindowRef(w) ) ); +#endif +#else + // 32 bit version < 10.5 + aglSetDrawable( context, GetWindowPort( MACwindowRef(w) ) ); +#endif + aglSetCurrentContext(context); +# else +# error unsupported platform +# endif + } +} + +void fl_no_gl_context() { + cached_context = 0; + cached_window = 0; +# if defined(USE_X11) + glXMakeCurrent(fl_display, 0, 0); +# elif defined(WIN32) + wglMakeCurrent(0, 0); +# elif defined(__APPLE_QUARTZ__) + // warning: the Quartz version should probably use Core GL (CGL) instead of AGL + AGLContext ctx = aglGetCurrentContext(); +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + if (aglSetWindowRef != NULL) + { if(ctx) aglSetWindowRef(ctx, NULL ); } + else +#endif + if(ctx) aglSetDrawable( ctx, NULL ); + aglSetCurrentContext(0); +# else +# error unsupported platform +# endif +} + +void fl_delete_gl_context(GLContext context) { + if (cached_context == context) fl_no_gl_context(); +# if defined(USE_X11) + glXDestroyContext(fl_display, context); +# elif defined(WIN32) + wglDeleteContext(context); +# elif defined(__APPLE_QUARTZ__) + // warning: the Quartz version should probably use Core GL (CGL) instead of AGL + aglDestroyContext( context ); +# else +# error unsupported platform +# endif + del_context(context); +} + +#endif // HAVE_GL + + +// +// End of "$Id: Fl_Gl_Choice.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Gl_Device_Plugin.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Gl_Device_Plugin.cxx new file mode 100644 index 0000000..c44941f --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Gl_Device_Plugin.cxx @@ -0,0 +1,153 @@ +// +// "$Id: Fl_Gl_Device_Plugin.cxx 7715 2010-10-11 18:10:32Z greg.ercolano $" +// +// implementation of class Fl_Gl_Device_Plugin for the Fast Light Tool Kit (FLTK). +// +// Copyright 2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems to: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include +#include "Fl_Gl_Choice.H" +#include "FL/Fl.H" +#ifndef __APPLE__ +#include "FL/fl_draw.H" +#endif + +#if defined(__APPLE__) +static void imgProviderReleaseData (void *info, const void *data, size_t size) +{ + free((void *)data); +} +#endif + +static void print_gl_window(Fl_Gl_Window *glw, int x, int y, int height) +{ +#ifdef WIN32 + HDC save_gc = fl_gc; + const int bytesperpixel = 3; +#elif defined(__APPLE__) + CGContextRef save_gc = fl_gc; + const int bytesperpixel = 4; +#else + _XGC *save_gc = fl_gc; + const int bytesperpixel = 3; +#endif + fl_gc = NULL; +#ifdef WIN32 + Fl::check(); + Fl_Window *win = (Fl_Window*)glw; + while( win->window() ) win = win->window(); + win->redraw(); + Fl::check(); + glw->make_current(); +#else + glw->make_current(); + glw->redraw(); + glFlush(); + Fl::check(); + glFinish(); +#endif + // Read OpenGL context pixels directly. + // For extra safety, save & restore OpenGL states that are changed + glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT); + glPixelStorei(GL_PACK_ALIGNMENT, 4); /* Force 4-byte alignment */ + glPixelStorei(GL_PACK_ROW_LENGTH, 0); + glPixelStorei(GL_PACK_SKIP_ROWS, 0); + glPixelStorei(GL_PACK_SKIP_PIXELS, 0); + // Read a block of pixels from the frame buffer + int mByteWidth = glw->w() * bytesperpixel; + mByteWidth = (mByteWidth + 3) & ~3; // Align to 4 bytes + uchar *baseAddress = (uchar*)malloc(mByteWidth * glw->h()); + glReadPixels(0, 0, glw->w(), glw->h(), +#ifdef WIN32 + GL_RGB, GL_UNSIGNED_BYTE, +#elif defined(__APPLE__) + GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, +#else // FIXME Linux/Unix + GL_RGB, GL_UNSIGNED_BYTE, +#endif + baseAddress); + glPopClientAttrib(); + fl_gc = save_gc; +#if defined(__APPLE__) +// kCGBitmapByteOrder32Host and CGBitmapInfo are supposed to arrive with 10.4 +// but some 10.4 don't have kCGBitmapByteOrder32Host, so we play a little #define game +#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_4 +#define kCGBitmapByteOrder32Host 0 +#define CGBitmapInfo CGImageAlphaInfo +#elif ! defined(kCGBitmapByteOrder32Host) +#ifdef __BIG_ENDIAN__ +#define kCGBitmapByteOrder32Host (4 << 12) +#else /* Little endian. */ +#define kCGBitmapByteOrder32Host (2 << 12) +#endif +#endif + CGColorSpaceRef cSpace = CGColorSpaceCreateDeviceRGB(); + CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, baseAddress, mByteWidth * glw->h(), imgProviderReleaseData); + CGImageRef image = CGImageCreate(glw->w(), glw->h(), 8, 8*bytesperpixel, mByteWidth, cSpace, + (CGBitmapInfo)(kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host), + provider, NULL, false, kCGRenderingIntentDefault); + if(image == NULL) return; + CGContextSaveGState(fl_gc); + CGContextTranslateCTM(fl_gc, 0, height); + CGContextScaleCTM(fl_gc, 1.0f, -1.0f); + CGRect rect = { { x, height - y - glw->h() }, { glw->w(), glw->h() } }; + Fl_X::q_begin_image(rect, 0, 0, glw->w(), glw->h()); + CGContextDrawImage(fl_gc, rect, image); + Fl_X::q_end_image(); + CGContextRestoreGState(fl_gc); + CGImageRelease(image); + CGColorSpaceRelease(cSpace); + CGDataProviderRelease(provider); +#else + fl_draw_image(baseAddress + (glw->h() - 1) * mByteWidth, x, y , glw->w(), glw->h(), bytesperpixel, - mByteWidth); + free(baseAddress); +#endif // __APPLE__ +} + +/** + This class will make sure that OpenGL printing is available if fltk_gl + was linked to the program. + */ +class Fl_Gl_Device_Plugin : public Fl_Device_Plugin { +public: + Fl_Gl_Device_Plugin() : Fl_Device_Plugin(name()) { } + virtual const char *name() { return "opengl.device.fltk.org"; } + virtual int print(Fl_Widget *w, int x, int y, int height) { + Fl_Gl_Window *glw = w->as_gl_window(); + if (!glw) return 0; + print_gl_window(glw, x, y, height); + return 1; + } +}; + +static Fl_Gl_Device_Plugin Gl_Device_Plugin; + +// The purpose of this variable, used in Fl_Gl_Window.cxx, is only to force this file to be loaded +// whenever Fl_Gl_Window.cxx is loaded, that is, whenever fltk_gl is. +FL_EXPORT int fl_gl_load_plugin = 0; + +// +// End of "$Id: Fl_Gl_Device_Plugin.cxx 7715 2010-10-11 18:10:32Z greg.ercolano $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Gl_Overlay.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Gl_Overlay.cxx new file mode 100644 index 0000000..b9ef2b6 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Gl_Overlay.cxx @@ -0,0 +1,248 @@ +// +// "$Id: Fl_Gl_Overlay.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// OpenGL overlay code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#if HAVE_GL + +#include +#include +#include "Fl_Gl_Choice.H" +#include +#include + +#if !HAVE_GL_OVERLAY + +int Fl_Gl_Window::can_do_overlay() {return 0;} + +void Fl_Gl_Window::make_overlay() {overlay = this;} + +#else + +// Methods on Fl_Gl_Window that create an overlay window. Because +// many programs don't need the overlay, this is separated into this +// source file so it is not linked in if not used. + +// Under X this is done by creating another window, of class _Fl_Gl_Overlay +// which is a subclass of Fl_Gl_Window except it uses the overlay planes. +// A pointer to this is stored in the "overlay" pointer of the Fl_Gl_Window. + +// Under win32 another GLX context is created to draw into the overlay +// and it is stored in the "overlay" pointer. + +// In both cases if overlay hardware is unavailable, the overlay is +// "faked" by drawing into the main layers. This is indicated by +// setting overlay == this. + +#ifndef WIN32 +//////////////////////////////////////////////////////////////// +// X version + +extern XVisualInfo *fl_find_overlay_visual(); +extern XVisualInfo *fl_overlay_visual; +extern Colormap fl_overlay_colormap; +extern unsigned long fl_transparent_pixel; +extern uchar fl_overlay; + +class _Fl_Gl_Overlay : public Fl_Gl_Window { + void flush(); + void draw(); +public: + void show(); + _Fl_Gl_Overlay(int x, int y, int w, int h) : + Fl_Gl_Window(x,y,w,h) { + set_flag(INACTIVE); + } +}; + +void _Fl_Gl_Overlay::flush() { + make_current(); +#ifdef BOXX_BUGS + // The BoXX overlay is broken and you must not call swap-buffers. This + // code will make it work, but we lose because machines that do support + // double-buffered overlays will blink when they don't have to + glDrawBuffer(GL_FRONT); + draw(); +#else + draw(); + swap_buffers(); +#endif + glFlush(); + valid(1); +} + +void _Fl_Gl_Overlay::draw() { + if (!valid()) glClearIndex((GLfloat)fl_transparent_pixel); + if (damage() != FL_DAMAGE_EXPOSE) glClear(GL_COLOR_BUFFER_BIT); + Fl_Gl_Window *w = (Fl_Gl_Window *)parent(); + uchar save_valid = w->valid(); + w->valid(valid()); + fl_overlay = 1; + w->draw_overlay(); + fl_overlay = 0; + valid(w->valid()); + w->valid(save_valid); +} + +void _Fl_Gl_Overlay::show() { + if (!shown()) { + fl_background_pixel = int(fl_transparent_pixel); + Fl_X::make_xid(this, fl_overlay_visual, fl_overlay_colormap); + fl_background_pixel = -1; + // find the outermost window to tell wm about the colormap: + Fl_Window *w = window(); + for (;;) {Fl_Window *w1 = w->window(); if (!w1) break; w = w1;} + XSetWMColormapWindows(fl_display, fl_xid(w), &(Fl_X::i(this)->xid), 1); + context(fl_create_gl_context(fl_overlay_visual), 1); + valid(0); + } + Fl_Gl_Window::show(); +} + +int Fl_Gl_Window::can_do_overlay() { + return fl_find_overlay_visual() != 0; +} + +void Fl_Gl_Window::make_overlay() { + if (overlay) return; + if (can_do_overlay()) { + _Fl_Gl_Overlay* o = new _Fl_Gl_Overlay(0,0,w(),h()); + overlay = o; + add(*o); + o->show(); + } else { + overlay = this; // fake the overlay + } +} + +#else +//////////////////////////////////////////////////////////////// +// WIN32 version: + +//static COLORREF *palette; +extern int fl_overlay_depth; + +void Fl_Gl_Window::make_overlay() { + if (overlay) return; + + GLContext context = fl_create_gl_context(this, g, 1); + if (!context) {overlay = this; return;} // fake the overlay + + HDC hdc = Fl_X::i(this)->private_dc; + overlay = context; + LAYERPLANEDESCRIPTOR pfd; + wglDescribeLayerPlane(hdc, g->pixelformat, 1, sizeof(pfd), &pfd); + if (!pfd.iPixelType) { + ; // full-color overlay + } else { + fl_overlay_depth = pfd.cColorBits; // used by gl_color() + if (fl_overlay_depth > 8) fl_overlay_depth = 8; + COLORREF palette[256]; + int n = (1<pfd.bReserved & 15) != 0; +} + +//////////////////////////////////////////////////////////////// +#endif + +#endif + +void Fl_Gl_Window::redraw_overlay() { + if (!shown()) return; + make_overlay(); +#ifdef __APPLE__ + redraw(); +#else +#ifndef WIN32 + if (overlay != this) + ((Fl_Gl_Window*)overlay)->redraw(); + else +#endif + damage(FL_DAMAGE_OVERLAY); +#endif +} + +void Fl_Gl_Window::make_overlay_current() { + make_overlay(); +#ifdef __APPLE__ + // this is not very useful, but unfortunately, Apple decided + // that front buffer drawing can no longer (OS X 10.4) be + // supported on their platforms. + make_current(); +#else +#if HAVE_GL_OVERLAY + if (overlay != this) { +#ifdef WIN32 + fl_set_gl_context(this, (GLContext)overlay); +// if (fl_overlay_depth) +// wglRealizeLayerPalette(Fl_X::i(this)->private_dc, 1, TRUE); +#else + ((Fl_Gl_Window*)overlay)->make_current(); +#endif + } else +#endif + glDrawBuffer(GL_FRONT); +#endif +} +/** Hides the window if it is not this window, does nothing in WIN32. */ +void Fl_Gl_Window::hide_overlay() { +#if HAVE_GL_OVERLAY +#ifdef WIN32 + // nothing needs to be done? Or should it be erased? +#else + if (overlay && overlay!=this) ((Fl_Gl_Window*)overlay)->hide(); +#endif +#endif +} + +#endif + +// +// End of "$Id: Fl_Gl_Overlay.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Gl_Window.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Gl_Window.cxx new file mode 100644 index 0000000..dafd9f3 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Gl_Window.cxx @@ -0,0 +1,549 @@ +// +// "$Id: Fl_Gl_Window.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// OpenGL window code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include "flstring.h" +#if HAVE_GL + +extern int fl_gl_load_plugin; + +static int temp = fl_gl_load_plugin; + +#include +#include +#include "Fl_Gl_Choice.H" +#include +#include +#include + +//////////////////////////////////////////////////////////////// + +// The symbol SWAP_TYPE defines what is in the back buffer after doing +// a glXSwapBuffers(). + +// The OpenGl documentation says that the contents of the backbuffer +// are "undefined" after glXSwapBuffers(). However, if we know what +// is in the backbuffers then we can save a good deal of time. For +// this reason you can define some symbols to describe what is left in +// the back buffer. + +// Having not found any way to determine this from glx (or wgl) I have +// resorted to letting the user specify it with an environment variable, +// GL_SWAP_TYPE, it should be equal to one of these symbols: + +// contents of back buffer after glXSwapBuffers(): +#define UNDEFINED 1 // anything +#define SWAP 2 // former front buffer (same as unknown) +#define COPY 3 // unchanged +#define NODAMAGE 4 // unchanged even by X expose() events + +static char SWAP_TYPE = 0 ; // 0 = determine it from environment variable + +//////////////////////////////////////////////////////////////// + +/** Returns non-zero if the hardware supports the given or current OpenGL mode. */ +int Fl_Gl_Window::can_do(int a, const int *b) { + return Fl_Gl_Choice::find(a,b) != 0; +} + +void Fl_Gl_Window::show() { +#if defined(__APPLE__) + int need_redraw = 0; +#endif + if (!shown()) { + if (!g) { + g = Fl_Gl_Choice::find(mode_,alist); + + if (!g && (mode_ & FL_DOUBLE) == FL_SINGLE) { + g = Fl_Gl_Choice::find(mode_ | FL_DOUBLE,alist); + if (g) mode_ |= FL_FAKE_SINGLE; + } + + if (!g) { + Fl::error("Insufficient GL support"); + return; + } + } +#if !defined(WIN32) && !defined(__APPLE__) + Fl_X::make_xid(this, g->vis, g->colormap); + if (overlay && overlay != this) ((Fl_Gl_Window*)overlay)->show(); +#elif defined(__APPLE__) + extern void MACsetContainsGLsubwindow(Fl_Window *); + if( ! parent() ) need_redraw=1; + else MACsetContainsGLsubwindow( window() ); +#endif + } + Fl_Window::show(); + +#ifdef __APPLE__ + set_visible(); + if(need_redraw) redraw();//necessary only after creation of a top-level GL window +#endif /* __APPLE__ */ +} + +/** + The invalidate() method turns off valid() and is + equivalent to calling value(0). +*/ +void Fl_Gl_Window::invalidate() { + valid(0); + context_valid(0); +#ifndef WIN32 + if (overlay) { + ((Fl_Gl_Window*)overlay)->valid(0); + ((Fl_Gl_Window*)overlay)->context_valid(0); + } +#endif +} + +/** + See const int Fl_Gl_Window::mode() const +*/ +int Fl_Gl_Window::mode(int m, const int *a) { + if (m == mode_ && a == alist) return 0; +#ifndef __APPLE__ + int oldmode = mode_; +#endif // !__APPLE__ +#if !defined(WIN32) && !defined(__APPLE__) + Fl_Gl_Choice* oldg = g; +#endif // !WIN32 && !__APPLE__ + context(0); + mode_ = m; alist = a; + if (shown()) { + g = Fl_Gl_Choice::find(m, a); + +#if defined(USE_X11) + // under X, if the visual changes we must make a new X window (yuck!): + if (!g || g->vis->visualid!=oldg->vis->visualid || (oldmode^m)&FL_DOUBLE) { + hide(); + show(); + } +#elif defined(WIN32) + if (!g || (oldmode^m)&(FL_DOUBLE|FL_STEREO)) { + hide(); + show(); + } +#elif defined(__APPLE_QUARTZ__) + // warning: the Quartz version should probably use Core GL (CGL) instead of AGL + redraw(); +#else +# error unsupported platform +#endif + } else { + g = 0; + } + return 1; +} + +#define NON_LOCAL_CONTEXT 0x80000000 + +/** + The make_current() method selects the OpenGL context for the + widget. It is called automatically prior to the draw() method + being called and can also be used to implement feedback and/or + selection within the handle() method. +*/ + +void Fl_Gl_Window::make_current() { +// puts("Fl_Gl_Window::make_current()"); +// printf("make_current: context_=%p\n", context_); + if (!context_) { + mode_ &= ~NON_LOCAL_CONTEXT; + context_ = fl_create_gl_context(this, g); + valid(0); + context_valid(0); + } + fl_set_gl_context(this, context_); + +#ifdef __APPLE__ + // Set the buffer rectangle here, since in resize() we won't have the + // correct parent window size to work with... + GLint xywh[4]; + + if (window()) { + xywh[0] = x(); + xywh[1] = window()->h() - y() - h(); + } else { + xywh[0] = 0; + xywh[1] = 0; + } + + xywh[2] = w(); + xywh[3] = h(); + + aglSetInteger(context_, AGL_BUFFER_RECT, xywh); + aglEnable(context_, AGL_BUFFER_RECT); +// printf("make_current: xywh=[%d %d %d %d]\n", xywh[0], xywh[1], xywh[2], xywh[3]); +#endif // __APPLE__ + +#if defined(WIN32) && USE_COLORMAP + if (fl_palette) { + fl_GetDC(fl_xid(this)); + SelectPalette(fl_gc, fl_palette, FALSE); + RealizePalette(fl_gc); + } +#endif // USE_COLORMAP + if (mode_ & FL_FAKE_SINGLE) { + glDrawBuffer(GL_FRONT); + glReadBuffer(GL_FRONT); + } + current_ = this; +} + +/** + Sets the projection so 0,0 is in the lower left of the window and each + pixel is 1 unit wide/tall. If you are drawing 2D images, your + draw() method may want to call this if valid() is false. +*/ +void Fl_Gl_Window::ortho() { +// Alpha NT seems to have a broken OpenGL that does not like negative coords: +#ifdef _M_ALPHA + glLoadIdentity(); + glViewport(0, 0, w(), h()); + glOrtho(0, w(), 0, h(), -1, 1); +#else + GLint v[2]; + glGetIntegerv(GL_MAX_VIEWPORT_DIMS, v); + glLoadIdentity(); + glViewport(w()-v[0], h()-v[1], v[0], v[1]); + glOrtho(w()-v[0], w(), h()-v[1], h(), -1, 1); +#endif +} + +/** + The swap_buffers() method swaps the back and front buffers. + It is called automatically after the draw() method is called. +*/ +void Fl_Gl_Window::swap_buffers() { +#if defined(USE_X11) + glXSwapBuffers(fl_display, fl_xid(this)); +#elif defined(WIN32) +# if HAVE_GL_OVERLAY + // Do not swap the overlay, to match GLX: + BOOL ret = wglSwapLayerBuffers(Fl_X::i(this)->private_dc, WGL_SWAP_MAIN_PLANE); + DWORD err = GetLastError();; +# else + SwapBuffers(Fl_X::i(this)->private_dc); +# endif +#elif defined(__APPLE_QUARTZ__) + if(overlay != NULL) { + //aglSwapBuffers does not work well with overlays under cocoa + glReadBuffer(GL_BACK); + glDrawBuffer(GL_FRONT); + glCopyPixels(0,0,w(),h(),GL_COLOR); + } + else + aglSwapBuffers((AGLContext)context_); +#else +# error unsupported platform +#endif +} + +#if HAVE_GL_OVERLAY && defined(WIN32) +uchar fl_overlay; // changes how fl_color() works +int fl_overlay_depth = 0; +#endif + + +void Fl_Gl_Window::flush() { + uchar save_valid = valid_f_ & 1; +#if HAVE_GL_OVERLAY && defined(WIN32) + uchar save_valid_f = valid_f_; +#endif + +#if defined(__APPLE_QUARTZ__) + // warning: the Quartz version should probably use Core GL (CGL) instead of AGL + //: clear previous clipping in this shared port +#if ! __LP64__ + GrafPtr port = GetWindowPort( MACwindowRef(this) ); + Rect rect; SetRect( &rect, 0, 0, 0x7fff, 0x7fff ); + GrafPtr old; GetPort( &old ); + SetPort( port ); + ClipRect( &rect ); + SetPort( old ); +#endif +#endif + +#if HAVE_GL_OVERLAY && defined(WIN32) + + bool fixcursor = false; // for fixing the SGI 320 bug + + // Draw into hardware overlay planes if they are damaged: + if (overlay && overlay != this + && (damage()&(FL_DAMAGE_OVERLAY|FL_DAMAGE_EXPOSE) || !save_valid)) { + // SGI 320 messes up overlay with user-defined cursors: + if (Fl_X::i(this)->cursor && Fl_X::i(this)->cursor != fl_default_cursor) { + fixcursor = true; // make it restore cursor later + SetCursor(0); + } + fl_set_gl_context(this, (GLContext)overlay); + if (fl_overlay_depth) + wglRealizeLayerPalette(Fl_X::i(this)->private_dc, 1, TRUE); + glDisable(GL_SCISSOR_TEST); + glClear(GL_COLOR_BUFFER_BIT); + fl_overlay = 1; + draw_overlay(); + fl_overlay = 0; + valid_f_ = save_valid_f; + wglSwapLayerBuffers(Fl_X::i(this)->private_dc, WGL_SWAP_OVERLAY1); + // if only the overlay was damaged we are done, leave main layer alone: + if (damage() == FL_DAMAGE_OVERLAY) { + if (fixcursor) SetCursor(Fl_X::i(this)->cursor); + return; + } + } +#endif + + make_current(); + + if (mode_ & FL_DOUBLE) { + + glDrawBuffer(GL_BACK); + + if (!SWAP_TYPE) { +#if defined __APPLE_QUARTZ__ + SWAP_TYPE = COPY; +#else + SWAP_TYPE = UNDEFINED; +#endif + const char* c = fl_getenv("GL_SWAP_TYPE"); + if (c) { + if (!strcmp(c,"COPY")) SWAP_TYPE = COPY; + else if (!strcmp(c, "NODAMAGE")) SWAP_TYPE = NODAMAGE; + else if (!strcmp(c, "SWAP")) SWAP_TYPE = SWAP; + } + } + + if (SWAP_TYPE == NODAMAGE) { + + // don't draw if only overlay damage or expose events: + if ((damage()&~(FL_DAMAGE_OVERLAY|FL_DAMAGE_EXPOSE)) || !save_valid) + draw(); + swap_buffers(); + + } else if (SWAP_TYPE == COPY) { + + // don't draw if only the overlay is damaged: + if (damage() != FL_DAMAGE_OVERLAY || !save_valid) draw(); + swap_buffers(); + + } else { // SWAP_TYPE == UNDEFINED + + // If we are faking the overlay, use CopyPixels to act like + // SWAP_TYPE == COPY. Otherwise overlay redraw is way too slow. + if (overlay == this) { + // don't draw if only the overlay is damaged: + if (damage1_ || damage() != FL_DAMAGE_OVERLAY || !save_valid) draw(); + // we use a separate context for the copy because rasterpos must be 0 + // and depth test needs to be off: + static GLContext ortho_context = 0; + static Fl_Gl_Window* ortho_window = 0; + int orthoinit = !ortho_context; + if (orthoinit) ortho_context = fl_create_gl_context(this, g); + fl_set_gl_context(this, ortho_context); + if (orthoinit || !save_valid || ortho_window != this) { + glDisable(GL_DEPTH_TEST); + glReadBuffer(GL_BACK); + glDrawBuffer(GL_FRONT); + glLoadIdentity(); + glViewport(0, 0, w(), h()); + glOrtho(0, w(), 0, h(), -1, 1); + glRasterPos2i(0,0); + ortho_window = this; + } + glCopyPixels(0,0,w(),h(),GL_COLOR); + make_current(); // set current context back to draw overlay + damage1_ = 0; + + } else { + damage1_ = damage(); + clear_damage(0xff); draw(); + swap_buffers(); + } + + } + + if (overlay==this) { // fake overlay in front buffer + glDrawBuffer(GL_FRONT); + draw_overlay(); + glDrawBuffer(GL_BACK); + glFlush(); + } + + } else { // single-buffered context is simpler: + + draw(); + if (overlay == this) draw_overlay(); + glFlush(); + + } + +#if HAVE_GL_OVERLAY && defined(WIN32) + if (fixcursor) SetCursor(Fl_X::i(this)->cursor); +#endif + valid(1); + context_valid(1); +} + +void Fl_Gl_Window::resize(int X,int Y,int W,int H) { +// printf("Fl_Gl_Window::resize(X=%d, Y=%d, W=%d, H=%d)\n", X, Y, W, H); +// printf("current: x()=%d, y()=%d, w()=%d, h()=%d\n", x(), y(), w(), h()); + + if (W != w() || H != h()) valid(0); + +#ifdef __APPLE__ + if (X != x() || Y != y() || W != w() || H != h()) aglUpdateContext(context_); +#elif !defined(WIN32) + if ((W != w() || H != h()) && !resizable() && overlay && overlay != this) { + ((Fl_Gl_Window*)overlay)->resize(0,0,W,H); + } +#endif + + Fl_Window::resize(X,Y,W,H); +} + +/** + Returns or sets a pointer to the GLContext that this window is + using. This is a system-dependent structure, but it is portable to copy + the context from one window to another. You can also set it to NULL, + which will force FLTK to recreate the context the next time make_current() + is called, this is useful for getting around bugs in OpenGL implementations. + + If destroy_flag is true the context will be destroyed by + fltk when the window is destroyed, or when the mode() is changed, + or the next time context(x) is called. +*/ +void Fl_Gl_Window::context(void* v, int destroy_flag) { + if (context_ && !(mode_&NON_LOCAL_CONTEXT)) fl_delete_gl_context(context_); + context_ = (GLContext)v; + if (destroy_flag) mode_ &= ~NON_LOCAL_CONTEXT; + else mode_ |= NON_LOCAL_CONTEXT; +} + +/** + Hides the window and destroys the OpenGL context. +*/ +void Fl_Gl_Window::hide() { + context(0); +#if HAVE_GL_OVERLAY && defined(WIN32) + if (overlay && overlay != this) { + fl_delete_gl_context((GLContext)overlay); + overlay = 0; + } +#endif + Fl_Window::hide(); +} + +/** + The destructor removes the widget and destroys the OpenGL context + associated with it. +*/ +Fl_Gl_Window::~Fl_Gl_Window() { + hide(); +// delete overlay; this is done by ~Fl_Group +} + +void Fl_Gl_Window::init() { + end(); // we probably don't want any children + box(FL_NO_BOX); + + mode_ = FL_RGB | FL_DEPTH | FL_DOUBLE; + alist = 0; + context_ = 0; + g = 0; + overlay = 0; + valid_f_ = 0; + damage1_ = 0; + +#if 0 // This breaks resizing on Linux/X11 + int H = h(); + h(1); // Make sure we actually do something in resize()... + resize(x(), y(), w(), H); +#endif // 0 +} + +/** + You must implement this virtual function if you want to draw into the + overlay. The overlay is cleared before this is called. You should + draw anything that is not clear using OpenGL. You must use + gl_color(i) to choose colors (it allocates them from the colormap + using system-specific calls), and remember that you are in an indexed + OpenGL mode and drawing anything other than flat-shaded will probably + not work. + + Both this function and Fl_Gl_Window::draw() should check + Fl_Gl_Window::valid() and set the same transformation. If you + don't your code may not work on other systems. Depending on the OS, + and on whether overlays are real or simulated, the OpenGL context may + be the same or different between the overlay and main window. +*/ +void Fl_Gl_Window::draw_overlay() {} + +#endif + + /** + You \e \b must subclass Fl_Gl_Window and provide an implementation for + draw(). You may also provide an implementation of draw_overlay() + if you want to draw into the overlay planes. You can avoid + reinitializing the viewport and lights and other things by checking + valid() at the start of draw() and only doing the + initialization if it is false. + + The draw() method can only use OpenGL calls. Do not + attempt to call X, any of the functions in , or glX + directly. Do not call gl_start() or gl_finish(). + + If double-buffering is enabled in the window, the back and front + buffers are swapped after this function is completed. +*/ +void Fl_Gl_Window::draw() { + Fl::fatal("Fl_Gl_Window::draw() *must* be overriden. Please refer to the documentation."); +} + + +/** + Handle some FLTK events as needed. + */ +int Fl_Gl_Window::handle(int event) +{ +#if (__APPLE_QUARTZ__) + if (event==FL_HIDE) { + // if we are not hidden, just the parent was hidden, so we must throw away the context + if (!visible_r()) + context(0); // remove context wthout setting the hidden flags + } + if (event==FL_SHOW) { + // if we are not hidden, just the parent was shown, so we must create a new context + if (visible_r()) + show(); // + } +#endif + return Fl_Window::handle(event); +} + +// +// End of "$Id: Fl_Gl_Window.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Group.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Group.cxx new file mode 100644 index 0000000..7e0b94d --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Group.cxx @@ -0,0 +1,836 @@ +// +// "$Id: Fl_Group.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Group widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// The Fl_Group is the only defined container type in FLTK. + +// Fl_Window itself is a subclass of this, and most of the event +// handling is designed so windows themselves work correctly. + +#include +#include +#include +#include +#include +#include + +Fl_Group* Fl_Group::current_; + +// Hack: A single child is stored in the pointer to the array, while +// multiple children are stored in an allocated array: + +/** + Returns a pointer to the array of children. This pointer is only + valid until the next time a child is added or removed. +*/ +Fl_Widget*const* Fl_Group::array() const { + return children_ <= 1 ? (Fl_Widget**)(&array_) : array_; +} + +/** + Searches the child array for the widget and returns the index. Returns children() + if the widget is NULL or not found. +*/ +int Fl_Group::find(const Fl_Widget* o) const { + Fl_Widget*const* a = array(); + int i; for (i=0; i < children_; i++) if (*a++ == o) break; + return i; +} + +// Metrowerks CodeWarrior and others can't export the static +// class member: current_, so these methods can't be inlined... + +/** + Sets the current group so you can build the widget + tree by just constructing the widgets. + + begin() is automatically called by the constructor for Fl_Group (and thus for + Fl_Window as well). begin() is exactly the same as current(this). + Don't forget to end() the group or window! +*/ +void Fl_Group::begin() {current_ = this;} + +/** + Exactly the same as current(this->parent()). Any new widgets + added to the widget tree will be added to the parent of the group. +*/ +void Fl_Group::end() {current_ = parent();} + +/** + Returns the currently active group. + + The Fl_Widget constructor automatically does current()->add(widget) if this + is not null. To prevent new widgets from being added to a group, call + Fl_Group::current(0). +*/ +Fl_Group *Fl_Group::current() {return current_;} + +/** + See static Fl_Group *Fl_Group::current() +*/ +void Fl_Group::current(Fl_Group *g) {current_ = g;} + +extern Fl_Widget* fl_oldfocus; // set by Fl::focus + +// For back-compatibility, we must adjust all events sent to child +// windows so they are relative to that window. + +static int send(Fl_Widget* o, int event) { + if (o->type() < FL_WINDOW) return o->handle(event); + switch ( event ) + { + case FL_DND_ENTER: /* FALLTHROUGH */ + case FL_DND_DRAG: + // figure out correct type of event: + event = (o->contains(Fl::belowmouse())) ? FL_DND_DRAG : FL_DND_ENTER; + } + int save_x = Fl::e_x; Fl::e_x -= o->x(); + int save_y = Fl::e_y; Fl::e_y -= o->y(); + int ret = o->handle(event); + Fl::e_y = save_y; + Fl::e_x = save_x; + switch ( event ) + { + case FL_ENTER: /* FALLTHROUGH */ + case FL_DND_ENTER: + // Successful completion of FL_ENTER means the widget is now the + // belowmouse widget, but only call Fl::belowmouse if the child + // widget did not do so: + if (!o->contains(Fl::belowmouse())) Fl::belowmouse(o); + break; + } + return ret; +} + +// translate the current keystroke into up/down/left/right for navigation: +#define ctrl(x) (x^0x40) +static int navkey() { + switch (Fl::event_key()) { + case 0: // not an FL_KEYBOARD/FL_SHORTCUT event + break; + case FL_Tab: + if (!Fl::event_state(FL_SHIFT)) return FL_Right; + return FL_Left; + case FL_Right: + return FL_Right; + case FL_Left: + return FL_Left; + case FL_Up: + return FL_Up; + case FL_Down: + return FL_Down; + } + return 0; +} + +int Fl_Group::handle(int event) { + + Fl_Widget*const* a = array(); + int i; + Fl_Widget* o; + + switch (event) { + + case FL_FOCUS: + switch (navkey()) { + default: + if (savedfocus_ && savedfocus_->take_focus()) return 1; + case FL_Right: + case FL_Down: + for (i = children(); i--;) if ((*a++)->take_focus()) return 1; + break; + case FL_Left: + case FL_Up: + for (i = children(); i--;) if (a[i]->take_focus()) return 1; + break; + } + return 0; + + case FL_UNFOCUS: + savedfocus_ = fl_oldfocus; + return 0; + + case FL_KEYBOARD: + return navigation(navkey()); + + case FL_SHORTCUT: + for (i = children(); i--;) { + o = a[i]; + if (o->takesevents() && Fl::event_inside(o) && send(o,FL_SHORTCUT)) + return 1; + } + for (i = children(); i--;) { + o = a[i]; + if (o->takesevents() && !Fl::event_inside(o) && send(o,FL_SHORTCUT)) + return 1; + } + if ((Fl::event_key() == FL_Enter || Fl::event_key() == FL_KP_Enter)) return navigation(FL_Down); + return 0; + + case FL_ENTER: + case FL_MOVE: + for (i = children(); i--;) { + o = a[i]; + if (o->visible() && Fl::event_inside(o)) { + if (o->contains(Fl::belowmouse())) { + return send(o,FL_MOVE); + } else { + Fl::belowmouse(o); + if (send(o,FL_ENTER)) return 1; + } + } + } + Fl::belowmouse(this); + return 1; + + case FL_DND_ENTER: + case FL_DND_DRAG: + for (i = children(); i--;) { + o = a[i]; + if (o->takesevents() && Fl::event_inside(o)) { + if (o->contains(Fl::belowmouse())) { + return send(o,FL_DND_DRAG); + } else if (send(o,FL_DND_ENTER)) { + if (!o->contains(Fl::belowmouse())) Fl::belowmouse(o); + return 1; + } + } + } + Fl::belowmouse(this); + return 0; + + case FL_PUSH: + for (i = children(); i--;) { + o = a[i]; + if (o->takesevents() && Fl::event_inside(o)) { + Fl_Widget_Tracker wp(o); + if (send(o,FL_PUSH)) { + if (Fl::pushed() && wp.exists() && !o->contains(Fl::pushed())) Fl::pushed(o); + return 1; + } + } + } + return 0; + + case FL_RELEASE: + case FL_DRAG: + o = Fl::pushed(); + if (o == this) return 0; + else if (o) send(o,event); + else { + for (i = children(); i--;) { + o = a[i]; + if (o->takesevents() && Fl::event_inside(o)) { + if (send(o,event)) return 1; + } + } + } + return 0; + + case FL_MOUSEWHEEL: + for (i = children(); i--;) { + o = a[i]; + if (o->takesevents() && Fl::event_inside(o) && send(o,FL_MOUSEWHEEL)) + return 1; + } + for (i = children(); i--;) { + o = a[i]; + if (o->takesevents() && !Fl::event_inside(o) && send(o,FL_MOUSEWHEEL)) + return 1; + } + return 0; + + case FL_DEACTIVATE: + case FL_ACTIVATE: + for (i = children(); i--;) { + o = *a++; + if (o->active()) o->handle(event); + } + return 1; + + case FL_SHOW: + case FL_HIDE: + for (i = children(); i--;) { + o = *a++; + if (event == FL_HIDE && o == Fl::focus()) { + // Give up input focus... + int old_event = Fl::e_number; + o->handle(Fl::e_number = FL_UNFOCUS); + Fl::e_number = old_event; + Fl::focus(0); + } + if (o->visible()) o->handle(event); + } + return 1; + + default: + // For all other events, try to give to each child, starting at focus: + for (i = 0; i < children(); i ++) + if (Fl::focus_ == a[i]) break; + + if (i >= children()) i = 0; + + if (children()) { + for (int j = i;;) { + if (a[j]->takesevents()) if (send(a[j], event)) return 1; + j++; + if (j >= children()) j = 0; + if (j == i) break; + } + } + + return 0; + } +} + +//void Fl_Group::focus(Fl_Widget *o) {Fl::focus(o); o->handle(FL_FOCUS);} + +#if 0 +const char *nameof(Fl_Widget *o) { + if (!o) return "NULL"; + if (!o->label()) return ""; + return o->label(); +} +#endif + +// try to move the focus in response to a keystroke: +int Fl_Group::navigation(int key) { + if (children() <= 1) return 0; + int i; + for (i = 0; ; i++) { + if (i >= children_) return 0; + if (array_[i]->contains(Fl::focus())) break; + } + Fl_Widget *previous = array_[i]; + + for (;;) { + switch (key) { + case FL_Right: + case FL_Down: + i++; + if (i >= children_) { + if (parent()) return 0; + i = 0; + } + break; + case FL_Left: + case FL_Up: + if (i) i--; + else { + if (parent()) return 0; + i = children_-1; + } + break; + default: + return 0; + } + Fl_Widget* o = array_[i]; + if (o == previous) return 0; + switch (key) { + case FL_Down: + case FL_Up: + // for up/down, the widgets have to overlap horizontally: + if (o->x() >= previous->x()+previous->w() || + o->x()+o->w() <= previous->x()) continue; + } + if (o->take_focus()) return 1; + } +} + +//////////////////////////////////////////////////////////////// + +Fl_Group::Fl_Group(int X,int Y,int W,int H,const char *l) +: Fl_Widget(X,Y,W,H,l) { + align(FL_ALIGN_TOP); + children_ = 0; + array_ = 0; + savedfocus_ = 0; + resizable_ = this; + sizes_ = 0; // this is allocated when first resize() is done + // Subclasses may want to construct child objects as part of their + // constructor, so make sure they are add()'d to this object. + // But you must end() the object! + begin(); +} + +/** + Deletes all child widgets from memory recursively. + + This method differs from the remove() method in that it + affects all child widgets and deletes them from memory. +*/ +void Fl_Group::clear() { + savedfocus_ = 0; + resizable_ = this; + init_sizes(); + + // we must change the Fl::pushed() widget, if it is one of + // the group's children. Otherwise fl_fix_focus() would send + // lots of events to children that are about to be deleted + // anyway. + + Fl_Widget *pushed = Fl::pushed(); // save pushed() widget + if (contains(pushed)) pushed = this; // set it to be the group, if it's a child + Fl::pushed(this); // for fl_fix_focus etc. + + // okay, now it is safe to destroy the children: + +#define REVERSE_CHILDREN +#ifdef REVERSE_CHILDREN + // Reverse the order of the children. Doing this and deleting + // always the last child is much faster than the other way around. + if (children_ > 1) { + Fl_Widget *temp; + Fl_Widget **a = (Fl_Widget**)array(); + for (int i=0,j=children_-1; iparent()==this) { // should always be true + if (children_>2) { // optimized removal + w->parent_ = 0; // reset child's parent + children_--; // update counter + } else { // slow removal + remove(idx); + } + delete w; // delete the child + } else { // should never happen + remove(idx); // remove it anyway + } + } + + if (pushed != this) Fl::pushed(pushed); // reset pushed() widget + +} + +/** + The destructor also deletes all the children. This allows a + whole tree to be deleted at once, without having to keep a pointer to + all the children in the user code. + + It is allowed that the Fl_Group and all of its children are automatic + (local) variables, but you must declare the Fl_Group \e first, so that + it is destroyed last. + + If you add static or automatic (local) variables to an Fl_Group, then it + is your responsibility to remove (or delete) all such static or automatic + child widgets \e \b before destroying the group - otherwise the child + widgets' destructors would be called twice! +*/ +Fl_Group::~Fl_Group() { + clear(); +} + +/** + The widget is removed from its current group (if any) and then + inserted into this group. It is put at index n - or at the end, + if n >= children(). This can also be used to rearrange + the widgets inside a group. +*/ +void Fl_Group::insert(Fl_Widget &o, int index) { + if (o.parent()) { + Fl_Group* g = o.parent(); + int n = g->find(o); + if (g == this) { + if (index > n) index--; + if (index == n) return; + } + g->remove(n); + } + o.parent_ = this; + if (children_ == 0) { // use array pointer to point at single child + array_ = (Fl_Widget**)&o; + } else if (children_ == 1) { // go from 1 to 2 children + Fl_Widget* t = (Fl_Widget*)array_; + array_ = (Fl_Widget**)malloc(2*sizeof(Fl_Widget*)); + if (index) {array_[0] = t; array_[1] = &o;} + else {array_[0] = &o; array_[1] = t;} + } else { + if (!(children_ & (children_-1))) // double number of children + array_ = (Fl_Widget**)realloc((void*)array_, + 2*children_*sizeof(Fl_Widget*)); + int j; for (j = children_; j > index; j--) array_[j] = array_[j-1]; + array_[j] = &o; + } + children_++; + init_sizes(); +} + +/** + The widget is removed from its current group (if any) and then added + to the end of this group. +*/ +void Fl_Group::add(Fl_Widget &o) {insert(o, children_);} + +/** + Removes the widget at \p index from the group but does not delete it. + + This method does nothing if \p index is out of bounds. + + This method differs from the clear() method in that it only affects + a single widget and does not delete it from memory. + + \since FLTK 1.3.0 +*/ +void Fl_Group::remove(int index) { + if (index < 0 || index >= children_) return; + Fl_Widget &o = *child(index); + if (&o == savedfocus_) savedfocus_ = 0; + if (o.parent_ == this) { // this should always be true + o.parent_ = 0; + } + + // remove the widget from the group + + children_--; + if (children_ == 1) { // go from 2 to 1 child + Fl_Widget *t = array_[!index]; + free((void*)array_); + array_ = (Fl_Widget**)t; + } else if (children_ > 1) { // delete from array + for (; index < children_; index++) array_[index] = array_[index+1]; + } + init_sizes(); +} + +/** + Removes a widget from the group but does not delete it. + + This method does nothing if the widget is not a child of the group. + + This method differs from the clear() method in that it only affects + a single widget and does not delete it from memory. + + \note If you have the child's index anyway, use remove(int index) + instead, because this doesn't need a child lookup in the group's + table of children. This can be much faster, if there are lots of + children. +*/ +void Fl_Group::remove(Fl_Widget &o) { + if (!children_) return; + int i = find(o); + if (i < children_) remove(i); +} + +//////////////////////////////////////////////////////////////// + +// Rather lame kludge here, I need to detect windows and ignore the +// changes to X,Y, since all children are relative to X,Y. That +// is why I check type(): + +// sizes array stores the initial positions of widgets as +// left,right,top,bottom quads. The first quad is the group, the +// second is the resizable (clipped to the group), and the +// rest are the children. This is a convenient order for the +// algorithm. If you change this be sure to fix Fl_Tile which +// also uses this array! + +/** + Resets the internal array of widget sizes and positions. + + The Fl_Group widget keeps track of the original widget sizes and + positions when resizing occurs so that if you resize a window back to its + original size the widgets will be in the correct places. If you rearrange + the widgets in your group, call this method to register the new arrangement + with the Fl_Group that contains them. + + If you add or remove widgets, this will be done automatically. + + \note The internal array of widget sizes and positions will be allocated and + filled when the next resize() occurs. + + \sa sizes() +*/ +void Fl_Group::init_sizes() { + delete[] sizes_; sizes_ = 0; +} + +/** + Returns the internal array of widget sizes and positions. + + If the sizes() array does not exist, it will be allocated and filled + with the current widget sizes and positions. + + \note You should never need to use this method directly, unless you have + special needs to rearrange the children of a Fl_Group. Fl_Tile uses + this to rearrange its widget positions. + + \sa init_sizes() + + \todo Should the internal representation of the sizes() array be documented? +*/ +int* Fl_Group::sizes() { + if (!sizes_) { + int* p = sizes_ = new int[4*(children_+2)]; + // first thing in sizes array is the group's size: + if (type() < FL_WINDOW) {p[0] = x(); p[2] = y();} else {p[0] = p[2] = 0;} + p[1] = p[0]+w(); p[3] = p[2]+h(); + // next is the resizable's size: + p[4] = p[0]; // init to the group's size + p[5] = p[1]; + p[6] = p[2]; + p[7] = p[3]; + Fl_Widget* r = resizable(); + if (r && r != this) { // then clip the resizable to it + int t; + t = r->x(); if (t > p[0]) p[4] = t; + t +=r->w(); if (t < p[1]) p[5] = t; + t = r->y(); if (t > p[2]) p[6] = t; + t +=r->h(); if (t < p[3]) p[7] = t; + } + // next is all the children's sizes: + p += 8; + Fl_Widget*const* a = array(); + for (int i=children_; i--;) { + Fl_Widget* o = *a++; + *p++ = o->x(); + *p++ = o->x()+o->w(); + *p++ = o->y(); + *p++ = o->y()+o->h(); + } + } + return sizes_; +} + +/** + Resizes the Fl_Group widget and all of its children. + + The Fl_Group widget first resizes itself, and then it moves and resizes + all its children according to the rules documented for + Fl_Group::resizable(Fl_Widget*) + + \sa Fl_Group::resizable(Fl_Widget*) + \sa Fl_Group::resizable() + \sa Fl_Widget::resize(int,int,int,int) +*/ +void Fl_Group::resize(int X, int Y, int W, int H) { + + int dx = X-x(); + int dy = Y-y(); + int dw = W-w(); + int dh = H-h(); + + int *p = sizes(); // save initial sizes and positions + + Fl_Widget::resize(X,Y,W,H); // make new xywh values visible for children + + if (!resizable() || (dw==0 && dh==0) ) { + + if (type() < FL_WINDOW) { + Fl_Widget*const* a = array(); + for (int i=children_; i--;) { + Fl_Widget* o = *a++; + o->resize(o->x()+dx, o->y()+dy, o->w(), o->h()); + } + } + + } else if (children_) { + + // get changes in size/position from the initial size: + dx = X - p[0]; + dw = W - (p[1]-p[0]); + dy = Y - p[2]; + dh = H - (p[3]-p[2]); + if (type() >= FL_WINDOW) dx = dy = 0; + p += 4; + + // get initial size of resizable(): + int IX = *p++; + int IR = *p++; + int IY = *p++; + int IB = *p++; + + Fl_Widget*const* a = array(); + for (int i=children_; i--;) { + Fl_Widget* o = *a++; +#if 1 + int XX = *p++; + if (XX >= IR) XX += dw; + else if (XX > IX) XX = IX+((XX-IX)*(IR+dw-IX)+(IR-IX)/2)/(IR-IX); + int R = *p++; + if (R >= IR) R += dw; + else if (R > IX) R = IX+((R-IX)*(IR+dw-IX)+(IR-IX)/2)/(IR-IX); + + int YY = *p++; + if (YY >= IB) YY += dh; + else if (YY > IY) YY = IY+((YY-IY)*(IB+dh-IY)+(IB-IY)/2)/(IB-IY); + int B = *p++; + if (B >= IB) B += dh; + else if (B > IY) B = IY+((B-IY)*(IB+dh-IY)+(IB-IY)/2)/(IB-IY); +#else // much simpler code from Francois Ostiguy: + int XX = *p++; + if (XX >= IR) XX += dw; + else if (XX > IX) XX += dw * (XX-IX)/(IR-IX); + int R = *p++; + if (R >= IR) R += dw; + else if (R > IX) R = R + dw * (R-IX)/(IR-IX); + + int YY = *p++; + if (YY >= IB) YY += dh; + else if (YY > IY) YY = YY + dh*(YY-IY)/(IB-IY); + int B = *p++; + if (B >= IB) B += dh; + else if (B > IY) B = B + dh*(B-IY)/(IB-IY); +#endif + o->resize(XX+dx, YY+dy, R-XX, B-YY); + } + } +} + +/** + Draws all children of the group. + + This is useful, if you derived a widget from Fl_Group and want to draw a special + border or background. You can call draw_children() from the derived draw() method + after drawing the box, border, or background. +*/ +void Fl_Group::draw_children() { + Fl_Widget*const* a = array(); + + if (clip_children()) { + fl_push_clip(x() + Fl::box_dx(box()), + y() + Fl::box_dy(box()), + w() - Fl::box_dw(box()), + h() - Fl::box_dh(box())); + } + + if (damage() & ~FL_DAMAGE_CHILD) { // redraw the entire thing: + for (int i=children_; i--;) { + Fl_Widget& o = **a++; + draw_child(o); + draw_outside_label(o); + } + } else { // only redraw the children that need it: + for (int i=children_; i--;) update_child(**a++); + } + + if (clip_children()) fl_pop_clip(); +} + +void Fl_Group::draw() { + if (damage() & ~FL_DAMAGE_CHILD) { // redraw the entire thing: + draw_box(); + draw_label(); + } + draw_children(); +} + +/** + Draws a child only if it needs it. + + This draws a child widget, if it is not clipped \em and if any damage() bits + are set. The damage bits are cleared after drawing. + + \sa Fl_Group::draw_child(Fl_Widget& widget) const +*/ +void Fl_Group::update_child(Fl_Widget& widget) const { + if (widget.damage() && widget.visible() && widget.type() < FL_WINDOW && + fl_not_clipped(widget.x(), widget.y(), widget.w(), widget.h())) { + widget.draw(); + widget.clear_damage(); + } +} + +/** + Forces a child to redraw. + + This draws a child widget, if it is not clipped. + The damage bits are cleared after drawing. +*/ +void Fl_Group::draw_child(Fl_Widget& widget) const { + if (widget.visible() && widget.type() < FL_WINDOW && + fl_not_clipped(widget.x(), widget.y(), widget.w(), widget.h())) { + widget.clear_damage(FL_DAMAGE_ALL); + widget.draw(); + widget.clear_damage(); + } +} + +extern char fl_draw_shortcut; + +/** Parents normally call this to draw outside labels of child widgets. */ +void Fl_Group::draw_outside_label(const Fl_Widget& widget) const { + if (!widget.visible()) return; + // skip any labels that are inside the widget: + if (!(widget.align()&15) || (widget.align() & FL_ALIGN_INSIDE)) return; + // invent a box that is outside the widget: + Fl_Align a = widget.align(); + int X = widget.x(); + int Y = widget.y(); + int W = widget.w(); + int H = widget.h(); + int wx, wy; + if (const_cast(this)->as_window()) { + wx = wy = 0; + } else { + wx = x(); wy = y(); + } + if ( (a & 0x0f) == FL_ALIGN_LEFT_TOP ) { + a = (a &~0x0f ) | FL_ALIGN_TOP_RIGHT; + X = wx; + W = widget.x()-X-3; + } else if ( (a & 0x0f) == FL_ALIGN_LEFT_BOTTOM ) { + a = (a &~0x0f ) | FL_ALIGN_BOTTOM_RIGHT; + X = wx; + W = widget.x()-X-3; + } else if ( (a & 0x0f) == FL_ALIGN_RIGHT_TOP ) { + a = (a &~0x0f ) | FL_ALIGN_TOP_LEFT; + X = X+W+3; + W = wx+this->w()-X; + } else if ( (a & 0x0f) == FL_ALIGN_RIGHT_BOTTOM ) { + a = (a &~0x0f ) | FL_ALIGN_BOTTOM_LEFT; + X = X+W+3; + W = wx+this->w()-X; + } else if (a & FL_ALIGN_TOP) { + a ^= (FL_ALIGN_BOTTOM|FL_ALIGN_TOP); + Y = wy; + H = widget.y()-Y; + } else if (a & FL_ALIGN_BOTTOM) { + a ^= (FL_ALIGN_BOTTOM|FL_ALIGN_TOP); + Y = Y+H; + H = wy+h()-Y; + } else if (a & FL_ALIGN_LEFT) { + a ^= (FL_ALIGN_LEFT|FL_ALIGN_RIGHT); + X = wx; + W = widget.x()-X-3; + } else if (a & FL_ALIGN_RIGHT) { + a ^= (FL_ALIGN_LEFT|FL_ALIGN_RIGHT); + X = X+W+3; + W = wx+this->w()-X; + } + widget.draw_label(X,Y,W,H,(Fl_Align)a); +} + +// +// End of "$Id: Fl_Group.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Help_Dialog.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Help_Dialog.cxx new file mode 100644 index 0000000..5511e26 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Help_Dialog.cxx @@ -0,0 +1,301 @@ +// +// "$Id: Fl_Help_Dialog.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Fl_Help_Dialog dialog for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// generated by Fast Light User Interface Designer (fluid) version 1.0108 + +#include "../FL/Fl_Help_Dialog.H" +#include "flstring.h" +#include + +void Fl_Help_Dialog::cb_back__i(Fl_Button*, void*) { + if (index_ > 0) + index_ --; + +if (index_ == 0) + back_->deactivate(); + +forward_->activate(); + +int l = line_[index_]; + +if (strcmp(view_->filename(), file_[index_]) != 0) + view_->load(file_[index_]); + +view_->topline(l); +} +void Fl_Help_Dialog::cb_back_(Fl_Button* o, void* v) { + ((Fl_Help_Dialog*)(o->parent()->parent()->user_data()))->cb_back__i(o,v); +} + +void Fl_Help_Dialog::cb_forward__i(Fl_Button*, void*) { + if (index_ < max_) + index_ ++; + +if (index_ >= max_) + forward_->deactivate(); + +back_->activate(); + +int l = view_->topline(); + +if (strcmp(view_->filename(), file_[index_]) != 0) + view_->load(file_[index_]); + +view_->topline(l); +} +void Fl_Help_Dialog::cb_forward_(Fl_Button* o, void* v) { + ((Fl_Help_Dialog*)(o->parent()->parent()->user_data()))->cb_forward__i(o,v); +} + +void Fl_Help_Dialog::cb_smaller__i(Fl_Button*, void*) { + if (view_->textsize() > 8) + view_->textsize(view_->textsize() - 2); + +if (view_->textsize() <= 8) + smaller_->deactivate(); +larger_->activate(); +} +void Fl_Help_Dialog::cb_smaller_(Fl_Button* o, void* v) { + ((Fl_Help_Dialog*)(o->parent()->parent()->user_data()))->cb_smaller__i(o,v); +} + +void Fl_Help_Dialog::cb_larger__i(Fl_Button*, void*) { + if (view_->textsize() < 18) + view_->textsize(view_->textsize() + 2); + +if (view_->textsize() >= 18) + larger_->deactivate(); +smaller_->activate(); +} +void Fl_Help_Dialog::cb_larger_(Fl_Button* o, void* v) { + ((Fl_Help_Dialog*)(o->parent()->parent()->user_data()))->cb_larger__i(o,v); +} + +void Fl_Help_Dialog::cb_find__i(Fl_Input*, void*) { + find_pos_ = view_->find(find_->value(), find_pos_); +} +void Fl_Help_Dialog::cb_find_(Fl_Input* o, void* v) { + ((Fl_Help_Dialog*)(o->parent()->parent()->parent()->user_data()))->cb_find__i(o,v); +} + +void Fl_Help_Dialog::cb_view__i(Fl_Help_View*, void*) { + if (view_->filename()) +{ + if (view_->changed()) + { + index_ ++; + + if (index_ >= 100) + { + memmove(line_, line_ + 10, sizeof(line_[0]) * 90); + memmove(file_, file_ + 10, sizeof(file_[0]) * 90); + index_ -= 10; + } + + max_ = index_; + + strlcpy(file_[index_], view_->filename(),sizeof(file_[0])); + line_[index_] = view_->topline(); + + if (index_ > 0) + back_->activate(); + else + back_->deactivate(); + + forward_->deactivate(); + window_->label(view_->title()); + } + else // if ! view_->changed() + { + strlcpy(file_[index_], view_->filename(), sizeof(file_[0])); + line_[index_] = view_->topline(); + } +} else { // if ! view_->filename() + index_ = 0; // hitting an internal page will disable the back/fwd buffer + file_[index_][0] = 0; // unnamed internal page + line_[index_] = view_->topline(); + back_->deactivate(); + forward_->deactivate(); +}; +} +void Fl_Help_Dialog::cb_view_(Fl_Help_View* o, void* v) { + ((Fl_Help_Dialog*)(o->parent()->user_data()))->cb_view__i(o,v); +} + +Fl_Help_Dialog::Fl_Help_Dialog() { + { window_ = new Fl_Double_Window(530, 385, "Help Dialog"); + window_->user_data((void*)(this)); + { Fl_Group* o = new Fl_Group(10, 10, 511, 25); + { back_ = new Fl_Button(10, 10, 25, 25, "@<-"); + back_->tooltip("Show the previous help page."); + back_->shortcut(0xff51); + back_->labelcolor((Fl_Color)2); + back_->callback((Fl_Callback*)cb_back_); + } // Fl_Button* back_ + { forward_ = new Fl_Button(45, 10, 25, 25, "@->"); + forward_->tooltip("Show the next help page."); + forward_->shortcut(0xff53); + forward_->labelcolor((Fl_Color)2); + forward_->callback((Fl_Callback*)cb_forward_); + } // Fl_Button* forward_ + { smaller_ = new Fl_Button(80, 10, 25, 25, "F"); + smaller_->tooltip("Make the help text smaller."); + smaller_->labelfont(1); + smaller_->labelsize(10); + smaller_->callback((Fl_Callback*)cb_smaller_); + } // Fl_Button* smaller_ + { larger_ = new Fl_Button(115, 10, 25, 25, "F"); + larger_->tooltip("Make the help text larger."); + larger_->labelfont(1); + larger_->labelsize(16); + larger_->callback((Fl_Callback*)cb_larger_); + } // Fl_Button* larger_ + { Fl_Group* o = new Fl_Group(350, 10, 171, 25); + o->box(FL_DOWN_BOX); + o->color(FL_BACKGROUND2_COLOR); + { find_ = new Fl_Input(375, 12, 143, 21, "@search"); + find_->tooltip("find text in document"); + find_->box(FL_FLAT_BOX); + find_->labelsize(13); + find_->textfont(4); + find_->callback((Fl_Callback*)cb_find_); + find_->when(FL_WHEN_ENTER_KEY_ALWAYS); + } // Fl_Input* find_ + o->end(); + } // Fl_Group* o + { Fl_Box* o = new Fl_Box(150, 10, 190, 25); + Fl_Group::current()->resizable(o); + } // Fl_Box* o + o->end(); + } // Fl_Group* o + { view_ = new Fl_Help_View(10, 45, 510, 330); + view_->box(FL_DOWN_BOX); + view_->callback((Fl_Callback*)cb_view_); + Fl_Group::current()->resizable(view_); + } // Fl_Help_View* view_ + window_->size_range(260, 150); + window_->end(); + } // Fl_Double_Window* window_ + back_->deactivate(); +forward_->deactivate(); + +index_ = -1; +max_ = 0; +find_pos_ = 0; + +fl_register_images(); +} + +Fl_Help_Dialog::~Fl_Help_Dialog() { + delete window_; +} + +int Fl_Help_Dialog::h() { + return (window_->h()); +} + +void Fl_Help_Dialog::hide() { + window_->hide(); +} + +void Fl_Help_Dialog::load(const char *f) { + view_->set_changed(); +view_->load(f); +window_->label(view_->title()); +} + +void Fl_Help_Dialog::position(int xx, int yy) { + window_->position(xx, yy); +} + +void Fl_Help_Dialog::resize(int xx, int yy, int ww, int hh) { + window_->resize(xx, yy, ww, hh); +} + +void Fl_Help_Dialog::show() { + window_->show(); +} + +void Fl_Help_Dialog::show(int argc, char **argv) { + window_->show(argc, argv); +} + +void Fl_Help_Dialog::textsize(Fl_Fontsize s) { + view_->textsize(s); + +if (s <= 8) + smaller_->deactivate(); +else + smaller_->activate(); + +if (s >= 18) + larger_->deactivate(); +else + larger_->activate(); +} + +Fl_Fontsize Fl_Help_Dialog::textsize() { + return (view_->textsize()); +} + +void Fl_Help_Dialog::topline(const char *n) { + view_->topline(n); +} + +void Fl_Help_Dialog::topline(int n) { + view_->topline(n); +} + +void Fl_Help_Dialog::value(const char *f) { + view_->set_changed(); +view_->value(f); +window_->label(view_->title()); +} + +const char * Fl_Help_Dialog::value() const { + return view_->value(); +} + +int Fl_Help_Dialog::visible() { + return (window_->visible()); +} + +int Fl_Help_Dialog::w() { + return (window_->w()); +} + +int Fl_Help_Dialog::x() { + return (window_->x()); +} + +int Fl_Help_Dialog::y() { + return (window_->y()); +} + +// +// End of "$Id: Fl_Help_Dialog.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Help_Dialog.fl b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Help_Dialog.fl new file mode 100644 index 0000000..e1faef0 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Help_Dialog.fl @@ -0,0 +1,265 @@ +# data file for the Fltk User Interface Designer (fluid) +version 1.0108 +header_name {../FL/Fl_Help_Dialog.H} +code_name {.cxx} +comment {// +// "$Id: Fl_Help_Dialog.fl 6616 2009-01-01 21:28:26Z matt $" +// +// Fl_Help_Dialog dialog for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2009 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// +} {in_source in_header +} + +decl {\#include "flstring.h"} {} + +decl {\#include } {} + +class FL_EXPORT Fl_Help_Dialog {open +} { + decl {int index_;} {} + decl {int max_;} {} + decl {int line_[100];} {} + decl {char file_[100][256];} {} + decl {int find_pos_;} {} + Function {Fl_Help_Dialog()} {open + } { + Fl_Window window_ { + label {Help Dialog} open + private xywh {398 64 530 385} type Double resizable size_range {260 150 0 0} visible + } { + Fl_Group {} {open selected + xywh {10 10 511 25} + } { + Fl_Button back_ { + label {@<-} + callback {if (index_ > 0) + index_ --; + +if (index_ == 0) + back_->deactivate(); + +forward_->activate(); + +int l = line_[index_]; + +if (strcmp(view_->filename(), file_[index_]) != 0) + view_->load(file_[index_]); + +view_->topline(l);} + private tooltip {Show the previous help page.} xywh {10 10 25 25} shortcut 0xff51 labelcolor 2 + } + Fl_Button forward_ { + label {@->} + callback {if (index_ < max_) + index_ ++; + +if (index_ >= max_) + forward_->deactivate(); + +back_->activate(); + +int l = view_->topline(); + +if (strcmp(view_->filename(), file_[index_]) != 0) + view_->load(file_[index_]); + +view_->topline(l);} + private tooltip {Show the next help page.} xywh {45 10 25 25} shortcut 0xff53 labelcolor 2 + } + Fl_Button smaller_ { + label F + callback {if (view_->textsize() > 8) + view_->textsize(view_->textsize() - 2); + +if (view_->textsize() <= 8) + smaller_->deactivate(); +larger_->activate();} + private tooltip {Make the help text smaller.} xywh {80 10 25 25} labelfont 1 labelsize 10 + } + Fl_Button larger_ { + label F + callback {if (view_->textsize() < 18) + view_->textsize(view_->textsize() + 2); + +if (view_->textsize() >= 18) + larger_->deactivate(); +smaller_->activate();} + private tooltip {Make the help text larger.} xywh {115 10 25 25} labelfont 1 labelsize 16 + } + Fl_Group {} {open + xywh {350 10 171 25} box DOWN_BOX color 7 + } { + Fl_Input find_ { + label {@search} + callback {find_pos_ = view_->find(find_->value(), find_pos_);} + private tooltip {find text in document} xywh {375 12 143 21} box FLAT_BOX labelsize 13 when 10 textfont 4 + } + } + Fl_Box {} { + xywh {150 10 190 25} resizable + } + } + Fl_Help_View view_ { + callback {if (view_->filename()) +{ + if (view_->changed()) + { + index_ ++; + + if (index_ >= 100) + { + memmove(line_, line_ + 10, sizeof(line_[0]) * 90); + memmove(file_, file_ + 10, sizeof(file_[0]) * 90); + index_ -= 10; + } + + max_ = index_; + + strlcpy(file_[index_], view_->filename(),sizeof(file_[0])); + line_[index_] = view_->topline(); + + if (index_ > 0) + back_->activate(); + else + back_->deactivate(); + + forward_->deactivate(); + window_->label(view_->title()); + } + else // if ! view_->changed() + { + strlcpy(file_[index_], view_->filename(), sizeof(file_[0])); + line_[index_] = view_->topline(); + } +} else { // if ! view_->filename() + index_ = 0; // hitting an internal page will disable the back/fwd buffer + file_[index_][0] = 0; // unnamed internal page + line_[index_] = view_->topline(); + back_->deactivate(); + forward_->deactivate(); +}} + private xywh {10 45 510 330} box DOWN_BOX resizable + } + } + code {back_->deactivate(); +forward_->deactivate(); + +index_ = -1; +max_ = 0; +find_pos_ = 0; + +fl_register_images();} {} + } + Function {~Fl_Help_Dialog()} {} { + code {delete window_;} {} + } + Function {h()} {return_type int + } { + code {return (window_->h());} {} + } + Function {hide()} {return_type void + } { + code {window_->hide();} {} + } + Function {load(const char *f)} {return_type void + } { + code {view_->set_changed(); +view_->load(f); +window_->label(view_->title());} {} + } + Function {position(int xx, int yy)} {return_type void + } { + code {window_->position(xx, yy);} {} + } + Function {resize(int xx, int yy, int ww, int hh)} {return_type void + } { + code {window_->resize(xx, yy, ww, hh);} {} + } + Function {show()} {return_type void + } { + code {window_->show();} {} + } + Function {show(int argc, char **argv)} {return_type void + } { + code {window_->show(argc, argv);} {} + } + Function {textsize(Fl_Fontsize s)} {return_type void + } { + code {view_->textsize(s); + +if (s <= 8) + smaller_->deactivate(); +else + smaller_->activate(); + +if (s >= 18) + larger_->deactivate(); +else + larger_->activate();} {} + } + Function {textsize()} {return_type Fl_Fontsize + } { + code {return (view_->textsize());} {} + } + Function {topline(const char *n)} {return_type void + } { + code {view_->topline(n);} {} + } + Function {topline(int n)} {return_type void + } { + code {view_->topline(n);} {} + } + Function {value(const char *f)} {return_type void + } { + code {view_->set_changed(); +view_->value(f); +window_->label(view_->title());} {} + } + Function {value() const} {return_type {const char *} + } { + code {return view_->value();} {} + } + Function {visible()} {return_type int + } { + code {return (window_->visible());} {} + } + Function {w()} {return_type int + } { + code {return (window_->w());} {} + } + Function {x()} {return_type int + } { + code {return (window_->x());} {} + } + Function {y()} {return_type int + } { + code {return (window_->y());} {} + } +} + +comment { +// +// End of "$Id: Fl_Help_Dialog.fl 6616 2009-01-01 21:28:26Z matt $". +//} {in_source in_header +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Help_Dialog_Dox.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Help_Dialog_Dox.cxx new file mode 100644 index 0000000..91b8323 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Help_Dialog_Dox.cxx @@ -0,0 +1,120 @@ +// +// "$Id: Fl_Help_Dialog_Dox.cxx 6943 2009-11-18 12:43:21Z AlbrechtS $" +// +// Fl_Help_Dialog dialog for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2009 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Fl_Help_Dialog (autogenerated class) doxygen documentation placeholder + +/** \class Fl_Help_Dialog + The Fl_Help_Dialog widget displays a standard help dialog window + using the Fl_Help_View widget. + +

\image html Fl_Help_Dialog.gif

+ \image latex Fl_Help_Dialog.eps "Fl_Help_Dialog" width=8cm +*/ + +/** \fn Fl_Help_Dialog::Fl_Help_Dialog() + The constructor creates the dialog pictured above.*/ + +/** \fn Fl_Help_Dialog::~Fl_Help_Dialog() + The destructor destroys the widget and frees all memory that has been + allocated for the current file. +*/ + +/** \fn void Fl_Help_Dialog::hide() + Hides the Fl_Help_Dialog window.*/ + +/** \fn void Fl_Help_Dialog::load(const char *f) + Loads the specified HTML file into the Fl_Help_View widget. + The filename can also contain a target name ("filename.html#target"). +*/ + +/** \fn void Fl_Help_Dialog::position(int x, int y) + Set the screen position of the dialog.*/ + +/** \fn void Fl_Help_Dialog::resize(int xx, int yy, int ww, int hh) + Change the position and size of the dialog.*/ + +/** \fn void Fl_Help_Dialog::show() + Shows the Fl_Help_Dialog window.*/ + +/** \fn void Fl_Help_Dialog::textsize(Fl_Fontsize s) + Sets or gets the default text size for the help view.*/ + +/** \fn uchar Fl_Help_Dialog::textsize() + Sets or gets the default text size for the help view.*/ + +/** \fn void Fl_Help_Dialog::topline(const char *n) + Sets the top line in the Fl_Help_View widget to the named or + numbered line. +*/ + +/** \fn void Fl_Help_Dialog::topline(int n) + Sets the top line in the Fl_Help_View widget to the named or + numbered line. +*/ + +/** \fn void Fl_Help_Dialog::value(const char *v) + The first form sets the current buffer to the string provided and + reformats the text. It also clears the history of the "back" and + "forward" buttons. The second form returns the current buffer contents. +*/ + +/** \fn const char *Fl_Help_Dialog::value() const + The first form sets the current buffer to the string provided and + reformats the text. It also clears the history of the "back" and + "forward" buttons. The second form returns the current buffer contents. +*/ + +/** \fn int Fl_Help_Dialog::visible() + Returns 1 if the Fl_Help_Dialog window is visible.*/ + +/** \fn int Fl_Help_Dialog::x() + Returns the position and size of the help dialog.*/ + +/** \fn int Fl_Help_Dialog::y() + Returns the position and size of the help dialog.*/ + +/** \fn int Fl_Help_Dialog::w() + Returns the position and size of the help dialog.*/ + +/** \fn int Fl_Help_Dialog::h() + Returns the position and size of the help dialog.*/ + +/** \fn void Fl_Help_Dialog::show() + Shows the main Help Dialog Window + Delegates call to encapsulated window_ void Fl_Window::show() method */ + +/** \fn void Fl_Help_Dialog::show(int argc, char **argv) + Shows the main Help Dialog Window + Delegates call to encapsulated window_ void Fl_Window::show(int argc, char **argv) instance method */ + +/** \fn void Fl_Help_Dialog::textsize(Fl_Fontsize s) + Sets the internal Fl_Help_View instance text size. + Delegates call to encapsulated view_ void Fl_Help_View::textsize(Fl_Fontsize s) instance method */ + +// +// End of "$Id: Fl_Help_Dialog_Dox.cxx 6943 2009-11-18 12:43:21Z AlbrechtS $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Help_View.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Help_View.cxx new file mode 100644 index 0000000..01be24e --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Help_View.cxx @@ -0,0 +1,6306 @@ +// +// "$Id: Fl_Help_View.cxx 6091 2008-04-11 11:12:16Z matt $" +// +// Fl_Help_View widget routines. +// +// Copyright 1997-2007 by Easy Software Products. +// Image support donated by Matthias Melcher, Copyright 2000. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// +// Contents: +// +// Fl_Help_View::Fl_Help_View() - Build a Fl_Help_View widget. +// Fl_Help_View::add_block() - Add a text block to the list. +// Fl_Help_View::add_link() - Add a new link to the list. +// Fl_Help_View::add_target() - Add a new target to the list. +// Fl_Help_View::begin_selection() - Begin text selection. +// Fl_Help_View::clear_global_selection() - Clear text selection. +// Fl_Help_View::clear_selection() - Clear current text selection. +// Fl_Help_View::cmp_targets() - Compare two targets. +// Fl_Help_View::do_align() - Compute alignment for a line in a block. +// Fl_Help_View::draw() - Draw the Fl_Help_View widget. +// Fl_Help_View::end_selection() - End text selection. +// Fl_Help_View::extend_selection()- Extend current text selection. +// Fl_Help_View::fileislink() - Was link clicked or nav button? +// Fl_Help_View::filepath() - Set value file path string. +// Fl_Help_View::filepath() - Get value file path string. +// Fl_Help_View::find() - Find the specified string. +// Fl_Help_View::find_font() - Find a font list index from a name. +// Fl_Help_View::find_link() - Find the link at the given position. +// Fl_Help_View::follow_link() - Follow the specified link. +// Fl_Help_View::font_face() - Get a font face from a list of names. +// Fl_Help_View::font_style() - Get a font style from a font list index. +// Fl_Help_View::format() - Format the help text. +// Fl_Help_View::format_table() - Format a table. +// Fl_Help_View::free_data() - Free memory used for the document. +// Fl_Help_View::get_align() - Get an alignment attribute. +// Fl_Help_View::get_attr() - Get an attribute value from the string. +// Fl_Help_View::get_color() - Get an alignment attribute. +// Fl_Help_View::get_css_value() - Outputs the value of a given css property to buffer. +// Fl_Help_View::get_font_size() - Get a height value for font-size. +// Fl_Help_View::get_image() - Get an inline image. +// Fl_Help_View::get_length() - Get a length value either absolute or %. +// Fl_Help_View::get_length() - Get a length value of a given width. +// Fl_Help_View::gettopline() - Get current topline in document. +// Fl_Help_View::handle() - Handle events in the widget. +// Fl_Help_View::hv_draw() - Draws text. +// Fl_Help_View::initfont() - Initialize font stack. +// Fl_Help_View::leftline() - Set the left line position. +// Fl_Help_View::load() - Load the specified file. +// Fl_Help_View::load_css() - Loads a css file. +// Fl_Help_View::parse_css() - Parses all supported css properties. +// Fl_Help_View::popfont() - Pop from font stack. +// Fl_Help_View::pushfont() - Push to font stack. +// Fl_Help_View::resize() - Resize the help widget. +// Fl_Help_View::select_all() - Select all text. +// Fl_Help_View::setstyle() - - Set the html style flag. +// Fl_Help_View::topline() - Set the top line to the named target. +// Fl_Help_View::topline() - Set the top line by number. +// Fl_Help_View::value() - Set the help text directly. +// Fl_Help_View::~Fl_Help_View() - Destroy a Fl_Help_View widget. +// +// Local: +// +// command() - Convert a command with up to four letters into an uint. +// quote_char() - Return the character code associated with a quoted char. +// hscrollbar_callback() - Callback for the horizontal scrollbar. +// scrollbar_callback() - Callback for the scrollbar. +// + +/* + mark: starting in July 2008 I have heavily modified this file and + it's header. So since I have made so many changes, instead of plonking + my name everywhere I have made original code comments start in + uppercase and my code comments start in lowercase. + + List of currently supported HTML tags/elements with attributes: + + + +
+
+
  1. +
    • + +
      +
      + +
      + +

      + +
      + + + + + +

      +
      
      + 
      + 
      + 
      + 
      + 
      + 
      + 
      + 
      +*/
      +
      +//
      +// Include necessary header files
      +//
      +
      +#include 
      +#include 
      +#include 
      +#include 
      +#include 
      +#include 
      +#include "flstring.h"
      +#include 
      +#include 
      +#include 
      +#include "forms_timer.cxx" // for fl_gettime in resize()
      +
      +#if defined(WIN32) && ! defined(__CYGWIN__)
      +#  include 
      +#  include 
      +// Visual C++ 2005 incorrectly displays a warning about the use of
      +// POSIX APIs on Windows, which is supposed to be POSIX compliant...
      +#  define getcwd _getcwd
      +#else
      +#  include 
      +#endif // WIN32
      +
      +//
      +// Define preprocessor constants and macros
      +//
      +
      +#define HV_64 64 // Columns, was 200 but practically 64 is enough
      +#define HV_32 32 // medium array size
      +#define HV_16 16 // small array size
      +
      +#define HV_DEFAULT 0 // html style flag
      +#define HV_NOCONTEXTMENU 1 // no right-click menu
      +#define HV_NONAVIGATE 2 // no user navigation
      +
      +// 'ENC(ANSI/Unicode, Mac Roman)' - OS character encoding macro
      +
      +#ifdef ENC
      +# undef ENC
      +#endif
      +#ifdef __APPLE__
      +# define ENC(a, b) b
      +#else
      +# define ENC(a, b) a
      +#endif
      +
      +// 'CTRL(char)' - Shortcut key macro, get bits 0..4 of char
      +
      +#define CTRL(x) ((x) & 0x1f)
      +
      +// 'CMD(char[0], char[1], char[2], char[3])' - Fourcc macro, chars to int
      +
      +#define CMD(a, b, c, d) ((a << 24) | (b << 16) | (c << 8) | d)
      +
      +// 'CHR(int, charindex)' - char from int macro, used like a 4-char array
      +
      +#define CHR(a, b) ((a & (255 << ((3-(b & 3)) << 3))) >> ((3-(b & 3)) << 3))
      +
      +// 'MIL(sec, mil, sec2, mil2)' - difference in mil macro, using fl_gettime
      +
      +#define MIL(a, b, c, d) ((c > a || (c == a && d > b)) ? \
      +                         (1000000 * (c - a)) - b + d : \
      +                         (1000000 * (a - c)) - d + b)
      +
      +//
      +// Typedef the C API sort function type the only way I know how...
      +//
      +
      +extern "C" // Compile qsort() in C style to avoid any compiler errors
      +{
      +  typedef int (*compare_func_t)(const void *, const void *);
      +}
      +
      +//
      +// Declare local functions
      +//
      +
      +static unsigned int command(const char *cmdp); // Used in end_selection
      +static int quote_char(const char *qp, int fc = 0); // added fc
      +static void hscrollbar_callback(Fl_Widget *s, void *);
      +static void scrollbar_callback(Fl_Widget *s, void *);
      +
      +//
      +// Broken image
      +//
      +
      +static const char *broken_xpm[] =
      +{
      +  "16 24 4 1",
      +  "@ c #000000", // Black
      +  "  c #ffffff", // White
      +  "+ c none", // Transparent
      +  "x c #ff0000", // Red
      +  // Pixels
      +  "@@@@@@@+++++++++",
      +  "@    @++++++++++",
      +  "@   @+++++++++++",
      +  "@   @++@++++++++",
      +  "@    @@+++++++++",
      +  "@     @+++@+++++",
      +  "@     @++@@++++@",
      +  "@ xxx  @@  @++@@",
      +  "@  xxx    xx@@ @",
      +  "@   xxx  xxx   @",
      +  "@    xxxxxx    @",
      +  "@     xxxx     @",
      +  "@    xxxxxx    @",
      +  "@   xxx  xxx   @",
      +  "@  xxx    xxx  @",
      +  "@ xxx      xxx @",
      +  "@              @",
      +  "@              @",
      +  "@              @",
      +  "@              @",
      +  "@              @",
      +  "@              @",
      +  "@              @",
      +  "@@@@@@@@@@@@@@@@",
      +  0 // nul-terminate - rem'd NULL
      +};
      +static Fl_Pixmap broken_image(broken_xpm);
      +
      +//
      +// Simple margin stack for Fl_Help_View::format()
      +//
      +
      +struct fl_margins
      +{
      +  int depth_; // Array index
      +  int margins_[100]; // Margins stack
      +
      +  fl_margins() {
      +    clear();
      +  }
      +
      +  int clear() { // Init margins
      +//  puts("fl_margins::clear()");
      +
      +    depth_ = 0;
      +    return margins_[0] = 4; // Default indent
      +  }
      +
      +  int current() { // Get current margin
      +    return margins_[depth_];
      +  }
      +
      +  int pop() { // Get last margin
      +
      +//printf("fl_margins::pop(): depth_=%d, xx=%d\n", depth_,
      +//  (depth_ > 0) ? margins_[depth_ - 1] : 4);
      +
      +    if (depth_ > 0) {
      +      depth_ --;
      +      return margins_[depth_];
      +    }
      +    else
      +      return 4; // Default indent
      +  }
      +
      +  int push(int indent) { // Set next margin
      +    int xx;
      +
      +    xx = margins_[depth_] + indent; // New indent
      +
      +//printf("fl_margins::push(indent=%d): depth_=%d, xx=%d\n", indent,
      +//  depth_ + 1, xx);
      +
      +    if (depth_ < 99) {
      +      depth_ ++;
      +      margins_[depth_] = xx;
      +    }
      +
      +    return xx;
      +  }
      +};
      +
      +//
      +// All the stuff needed to implement text selection in Fl_Help_View
      +//
      +
      +/* matt:
      + We are trying to keep binary compatibility with previous versions
      + of FLTK. This means that we are limited to adding static data members
      + only to not enlarge the Fl_Help_View class. Lucky for us, only one
      + text can be selected system wide, so we can remember the selection
      + in a single set of values.
      +
      + Still to do:
      + - &word; style characters mess up our count inside a word boundary
      + - we can only select words, no individual characters
      + - no dragging of the selection into another widget
      + - selection must be cleared if another widget get focus!
      + - write a comment for every new function
      +
      + mark: Static data members don't change the binary size or layout
      + of a class because they are defined externally.
      + For more info on binary compatibility (BC):
      + http://techbase.kde.org/Policies/Binary_Compatibility_Issues_With_C++
      + */
      +
      +/*
      + matt: The following functions are also used to draw stuff and should be
      + replaced with local copies that are much faster when merely counting.
      + fl_color(Fl_Color);
      + fl_rectf(int, int, int, int);
      + fl_push_clip(int, int, int, int);
      + fl_xyline(int, int, int);
      + fl_rect()
      + fl_line()
      + img->draw()
      +
      + mark: local functions more-so static are faster than class functions.
      +*/
      +
      +// Text selection
      +// We don't put the offscreen buffer in the help view class because
      +// we'd need to include x.H in the header...
      +
      +static Fl_Offscreen fl_help_view_buffer;
      +
      +//
      +// Define and zero static data members
      +//
      +
      +int Fl_Help_View::selection_first = 0;
      +int Fl_Help_View::selection_last = 0;
      +int Fl_Help_View::selection_push_first = 0;
      +int Fl_Help_View::selection_push_last = 0;
      +int Fl_Help_View::selection_drag_first = 0;
      +int Fl_Help_View::selection_drag_last = 0;
      +int Fl_Help_View::selected = 0;
      +int Fl_Help_View::draw_mode = 0;
      +int Fl_Help_View::mouse_x = 0;
      +int Fl_Help_View::mouse_y = 0;
      +int Fl_Help_View::current_pos = 0;
      +Fl_Help_View *Fl_Help_View::current_view = 0; // rem'd NULL
      +Fl_Color Fl_Help_View::hv_selection_color;
      +Fl_Color Fl_Help_View::hv_selection_text_color;
      +
      +// new static class variables
      +int Fl_Help_View::serifont_ = 0; // default serif font
      +int Fl_Help_View::sansfont_ = 0; // default sans font
      +int Fl_Help_View::monofont_ = 0; // default monospace font
      +unsigned char Fl_Help_View::fontsize_ = 0; // default font size
      +short Fl_Help_View::face_[250][4]; // font face table [m,b,i,p]
      +unsigned char Fl_Help_View::flet_[30]; // first face for letter table
      +unsigned char Fl_Help_View::fref_[1000]; // face reference table
      +
      +//
      +// Fl_Help_View::Fl_Help_View() - Build a Fl_Help_View widget.
      +//
      +
      +Fl_Help_View::Fl_Help_View(int xx, // I - Left position
      +                           int yy, // I - Top position
      +                           int ww, // I - Width in pixels
      +                           int hh, // I - Height in pixels
      +                           const char *lp) // I - Label pointer, opt
      +: Fl_Group(xx, yy, ww, hh, lp),
      +  scrollbar_(xx + ww - Fl::scrollbar_size(), yy,
      +             Fl::scrollbar_size(), hh - Fl::scrollbar_size()),
      +  hscrollbar_(xx, yy + hh - Fl::scrollbar_size(),
      +              ww - Fl::scrollbar_size(), Fl::scrollbar_size())
      +{
      +  color(FL_WHITE, FL_SELECTION_COLOR); // Set bgcolor and selcolor of widget - rem'd FL_BACKGROUND2_COLOR
      +
      +  title_[0] = '\0'; // Title string
      +  defcolor_ = FL_BLACK; // Default text color - rem'd FL_FOREGROUND_COLOR
      +  bgcolor_ = FL_WHITE; // Background color - rem'd FL_BACKGROUND_COLOR
      +  textcolor_ = defcolor_; // Text color
      +  linkcolor_ = FL_BLUE; // Link color - rem'd FL_SELECTION_COLOR
      +  serifont_ = FL_TIMES; // Default font, was textfont_
      +  fontsize_ = 12; // Default font size, was textsize_
      +  value_ = 0; // HTML text value - rem'd NULL
      +  ablocks_ = 0; // Allocated blocks
      +  nblocks_ = 0; // Number of blocks
      +  blocks_ = (Fl_Help_Block *)0; // Blocks
      +
      +  nfonts_ = 0; // Number of fonts in stack - replaced
      +
      +  link_ = (Fl_Help_Func *)0; // Link transform function
      +
      +  alinks_ = 0; // Allocated links
      +  nlinks_ = 0; // Number of links
      +  links_ = (Fl_Help_Link *)0; // Links
      +
      +  //targets_ = (Fl_Help_Target *)0; // rem'd
      +  atargets_ = 0; // Allocated targets
      +  ntargets_ = 0; // Number of targets
      +
      +  directory_[0] = '\0'; // Directory for current file
      +  filename_[0] = '\0'; // Current filename
      +
      +  topline_ = 0; // Top line in document
      +  leftline_ = 0; // Lefthand position
      +  size_ = 0; // Total document length
      +  hsize_ = 0; // Maximum document width
      +
      +  scrollbar_.value(0, hh, 0, 1);
      +  scrollbar_.step(8.0);
      +  scrollbar_.show();
      +  scrollbar_.callback(scrollbar_callback);
      +  scrollbar_.linesize(32); // vertical scroll size, default is 16
      +
      +  hscrollbar_.value(0, ww, 0, 1); // Set line position, window, top, total
      +  hscrollbar_.step(8.0); // Set mouse step rounding value
      +  hscrollbar_.show(); // Show widget
      +  hscrollbar_.callback(hscrollbar_callback); // Set callback func for widget
      +  hscrollbar_.type(FL_HORIZONTAL); // Set slider type, default is vertical
      +  end(); // End current Fl_Group widgets
      +
      +  d = (Fl_Help_Target *)malloc(sizeof(Fl_Help_Target)); // d-pointer
      +  d->targets = (Fl_Help_Link *)0; // Targets
      +  d->linkp = (Fl_Help_Link *)0; // Currently clicked link
      +  d->ispush = 0; // link is pushed
      +  d->islink = 0; // link clicked
      +  d->resized = 0; // window resized
      +  d->ispath = 0; // is path used
      +  d->nstyle = 0; // navigation style flag
      +  d->isnew = 0; // is new page
      +  d->top = 0; // current topline
      +  d->ltop = 0; // last topline
      +  d->isnav = 0; // is nav link
      +  d->rwidth = w(); // resize width
      +  d->cssurllen = 0; // css url length
      +  d->csswordlen = 0; // css word length
      +  d->cssword = 0; // css word value
      +  d->rtime = 0; // resize time
      +  d->rsec = 0; // resize seconds
      +  d->rmil = 0; // resize millisecs
      +  d->csstextlen = 0; // css text length
      +  d->csstext = 0; // css text value
      +  d->cssurl = 0; // css url value
      +  d->path[0] = '\0'; // current file path
      +  d->lpath[0] = '\0'; // last file path
      +  d->fonts[0][0] = 0; // font stack
      +  d->nfonts = 0; // number of fonts in stack
      +  
      +  build_faces();
      +
      +  // load new default fonts
      +  serifont_ = FL_TIMES; // default/serif font
      +  sansfont_ = FL_HELVETICA; // sans font
      +  monofont_ = FL_COURIER; // monospace font
      +  
      +  resize(xx, yy, ww, hh); // Resize widget
      +
      +} // Fl_Help_View::Fl_Help_View()
      +
      +//
      +// Fl_Help_View::add_block() - replaced, code moved
      +//
      +
      +Fl_Help_Block * // O - Pointer to new block
      +Fl_Help_View::add_block(const char *sp, // I - Pointer to start
      +                        int xx, // I - X position
      +                        int yy, // I - Y position
      +                        int ww, // I - Right margin
      +                        int hh, // I - Height
      +                        unsigned char bc) // I - Draw border, opt
      +{
      +  return 0;
      +
      +} // Fl_Help_View::add_block()
      +
      +//
      +// Fl_Help_View::add_block() - Add a text block to the list.
      +//
      +
      +Fl_Help_Block * // O - Pointer to new block
      +Fl_Help_View::add_block(const Fl_Help_Block &b, // I - block object
      +                        const char *sp, // I - Pointer to start
      +                        int ww) // I - Right margin
      +{
      +  Fl_Help_Block *block; // New block
      +
      +  if (nblocks_ >= ablocks_) {
      +    ablocks_ += 16; // Allocated blocks, 16 blocks per allocation
      +    int size = sizeof(Fl_Help_Block) * ablocks_; // block size
      +    if (ablocks_ == 16) // Memory was freed
      +      blocks_ = (Fl_Help_Block *)malloc(size);
      +    else // First pass or resize resulted in a few new blocks
      +      blocks_ = (Fl_Help_Block *)realloc(blocks_, size);
      +  }
      +
      +  block = blocks_ + nblocks_;
      +  memset(block, 0, sizeof(Fl_Help_Block));
      +
      +  block->start = sp; // Start of text, varies so set by sp
      +  block->end = sp; // End of text, varies so set by sp
      +  block->x = b.x; // Starting X coordinate
      +  block->y = b.y; // Starting Y coordinate
      +  block->w = ww; // Width, varies so set by ww
      +  block->h = 0; // Height, always zero
      +  block->maxh = 0; // max image height
      +  block->imgy = 0; // image y position
      +  block->pre = b.pre; // pre text flag
      +  block->tag = b.tag; // tag/element fourcc int
      +  block->border = b.border; // Draw border?
      +  block->font = b.font; // current font
      +  block->fsize = b.fsize; // current font size
      +  block->bgcolor = b.bgcolor; // Background color
      +  block->cbi = nblocks_; // current block index
      +
      +  nblocks_ ++; // Number of blocks
      +  
      +  return block;
      +
      +} // Fl_Help_View::add_block()
      +
      +//
      +// Fl_Help_View::add_link() - Add a new link to the list.
      +//
      +
      +void Fl_Help_View::add_link(const char *np, // I - Name of link
      +                            int xx, // I - X position of link
      +                            int yy, // I - Y position of link
      +                            int ww, // I - Width of link text
      +                            int hh) // I - Height of link text
      +{
      +  Fl_Help_Link *link; // New link
      +  char *target; // Pointer to target name
      +
      +  if (nlinks_ >= alinks_) {
      +    alinks_ += 16; // Allocated links, 16 blocks per allocation
      +    int size = sizeof(Fl_Help_Link) * alinks_; // block size
      +    if (alinks_ == 16)
      +      links_ = (Fl_Help_Link *)malloc(size);
      +    else
      +      links_ = (Fl_Help_Link *)realloc(links_, size);
      +  }
      +
      +  link = links_ + nlinks_;
      +  link->x = xx; // X offset of link text
      +  link->y = yy; // Y offset of link text
      +  link->w = xx + ww; // Width of link text
      +  link->h = yy + hh; // Height of link text
      +
      +  strlcpy(link->filename, np, sizeof(link->filename)); // nul-terminated
      +
      +  if ((target = strrchr(link->filename, '#'))) { // Last '#' - rem'd != 0
      +    *(target ++) = '\0'; // Remove target from link->filename
      +    strlcpy(link->name, target, sizeof(link->name)); // Link target
      +  }
      +  else
      +    link->name[0] = '\0'; // Blank link target
      +
      +  nlinks_ ++; // Number of links
      +
      +} // Fl_Help_View::add_link()
      +
      +//
      +// Fl_Help_View::add_target() - Add a new target to the list.
      +//
      +
      +void Fl_Help_View::add_target(const char *np, // I - Name of target
      +                              int yy) // I - Y position of target
      +{
      +  Fl_Help_Link *target; // New target
      +
      +  if (ntargets_ >= atargets_) {
      +    atargets_ += 16; // Allocated targets, 16 blocks per allocation
      +    int size = sizeof(Fl_Help_Link) * atargets_; // block size
      +    if (atargets_ == 16)
      +      d->targets = (Fl_Help_Link *)malloc(size);
      +    else
      +      d->targets = (Fl_Help_Link *)realloc(d->targets, size);
      +  }
      +
      +  target = d->targets + ntargets_;
      +  target->y = yy; // Y offset
      +  strlcpy(target->name, np, sizeof(target->name)); // Target name
      +
      +  ntargets_ ++; // Number of targets
      +
      +} // Fl_Help_View::add_target()
      +
      +//
      +// Fl_Help_View::begin_selection() - Begin text selection.
      +//
      +
      +char // O - True if text selected
      +Fl_Help_View::begin_selection()
      +{
      +  clear_global_selection();
      +
      +  if (!fl_help_view_buffer)
      +    fl_help_view_buffer = fl_create_offscreen(1, 1);
      +
      +  mouse_x = Fl::event_x();
      +  mouse_y = Fl::event_y();
      +  draw_mode = 1; // Begin selection mode
      +
      +  current_view = this;
      +  fl_begin_offscreen(fl_help_view_buffer);
      +  draw();
      +  fl_end_offscreen();
      +
      +  draw_mode = 0;
      +
      +  if (selection_push_last)
      +    return 1;
      +  else
      +    return 0;
      +
      +} // Fl_Help_View::begin_selection()
      +
      +//
      +// Fl_Help_View::build_faces() - build font face look-up tables.
      +//
      +
      +unsigned char // O - number of font faces
      +Fl_Help_View::build_faces()
      +{
      +  char buf[100], namebuf[100], tbufs[100][100]; // buffers
      +  const char *namep; // pointer
      +  char *bufp, *namebufp; // r+w pointer
      +  int ti = 0, tj = 0, tk = 0, // temp loop vars
      +    tnum = 0, lnum = 0, fnum = 0, // temp/last/font counters
      +    tfi[100], tf[10],
      +    cbit = 0, fbit = 0, tbit = 0, // bits
      +    nfonts = 0, nfaces = 0, // number of fonts and faces
      +    temp = 0; // lengths
      +
      +  strlcpy(buf, " ", sizeof(buf)); // init buffer
      +  memset(face_, 0, sizeof(face_)); // zero tables
      +  memset(flet_, 0, sizeof(flet_));
      +  memset(fref_, 0, sizeof(fref_));
      +
      +  nfonts = Fl::set_fonts(0); // number of ISO8859-1 fonts in list
      +
      +  for (ti = 0, nfaces = 0; ti < nfonts; ti ++) { // find base fonts
      +    namep = Fl::get_font_name((Fl_Font)ti, &temp); // fltk font name
      +    for (tk = 0; namep[tk] != '\0'; tk ++)
      +      namebuf[tk] = tolower(namep[tk]); // copy chars to lowercase
      +    namebuf[tk] = '\0'; // nul-terminate
      +    if (strstr(namebuf+1, "black") || strstr(namebuf+1, "bold") ||
      +        strstr(namebuf+1, "extra") || strstr(namebuf+1, "heavy") ||
      +        strstr(namebuf+1, "inclined") || strstr(namebuf+1, "italic") ||
      +        strstr(namebuf+1, "light") || strstr(namebuf+1, "oblique") ||
      +        strstr(namebuf+1, "slanted") || strstr(namebuf+1, "wide") ||
      +        strstr(namebuf+1, "ultra"))
      +      continue; // skip font styles
      +    if ((bufp = strstr(namebuf, "-"))) { // full font name
      +      if (strstr(bufp+1, "bd") || strstr(bufp+1, "cond") ||
      +          strstr(bufp+1, "cn") || strstr(bufp+1, "it") ||
      +          strstr(bufp+1, "obl") || strstr(bufp+1, "smbd"))
      +      continue; // skip font styles
      +    }
      +    temp = strlen(namebuf);
      +    if (temp < (int)strlen(buf)) temp = strlen(buf); // use bigger length
      +    if (!strncmp(namebuf, buf, temp)) continue; // same name as last
      +    if (nfaces < (int)sizeof(face_)/8) { // store next face
      +      face_[nfaces][2] = ti; // first font for face
      +      face_[nfaces][3] = (uchar)*namebuf; // first letter for face, a..z
      +      if (face_[nfaces][3] < 97 || face_[nfaces][3] > 123)
      +        face_[nfaces][3] = 123; // illegal char, z
      +      nfaces ++; // next face
      +    }
      +    strlcpy(buf, namebuf, sizeof(buf)); // last name in buffer
      +  }
      +
      +  for (ti = 0, fnum = 0; ti < 27; ti ++) { // sort faces alphabetically
      +    for (tj = 0; tj < nfaces; tj ++) {
      +      tnum = face_[tj][3] - 97; // first letter, a = 0
      +      if (ti == tnum) { // current letter match
      +        face_[fnum][0] = face_[tj][2]; // first font index
      +        face_[fnum][1] = face_[tj][3]; // first letter
      +        fnum ++; // next face
      +      }
      +    }
      +  }
      +
      +  for (ti = 0; ti < nfaces; ti ++) { // store all fonts in face table
      +    fnum = face_[ti][0]; // face index
      +    namep = Fl::get_font_name((Fl_Font)fnum, &temp);
      +    for (tk = 0; namep[tk] != '\0'; tk ++)
      +      buf[tk] = tolower(namep[tk]);
      +    buf[tk] = '\0'; // nul-terminate
      +    if (!(bufp = strstr(buf, "-"))) bufp = buf + tk;
      +    *bufp = '\0'; // shorten full name
      +    strlcpy(tbufs[0], buf, sizeof(tbufs[0]));
      +    face_[ti][1] = face_[ti][2] = face_[ti][3] = 0; // reset
      +    memset(tf, 0, sizeof(tf));
      +
      +    for (tj = 0, tfi[0] = fnum, lnum = 1; tj < nfonts; tj ++) { // get all fonts of face
      +      namep = Fl::get_font_name((Fl_Font)tj, &temp); // fltk font name
      +      for (tk = 0; namep[tk] != '\0'; tk ++)
      +        namebuf[tk] = tolower(namep[tk]); // copy to lowercase
      +      namebuf[tk] = '\0'; // nul-terminate
      +      if (!isalpha(namebuf[0])) continue; // skip foreign chars
      +      if (!(namebufp = strstr(namebuf, "-"))) namebufp = namebuf; // full font name
      +      if (strstr(namebuf, " ") && namebufp == namebuf) { // basic font name
      +        namebufp = strstr(namebuf, " bold");
      +        if (!namebufp) namebufp = strstr(namebuf, " italic");
      +        if (!namebufp) namebufp = strstr(namebuf, " oblique");
      +      }
      +      if (!strncmp(buf, namebuf, bufp-buf) && (namebufp-namebuf == bufp-buf)) { // face name match
      +        strlcpy(tbufs[lnum], namebuf, sizeof(tbufs[lnum]));
      +        tfi[lnum] = tj; // font indexes
      +        lnum ++; // count fonts
      +        if (strstr(namebuf, "-")) { // abbreviations if full name
      +          if (strstr(namebufp+1, "bd")) tf[1] = 1;
      +          if (strstr(namebufp+1, "it")) tf[2] = 1;
      +        }
      +        if (strstr(namebufp+1, "bold")) tf[1] = 1; // set flags of current face
      +        if (strstr(namebufp+1, "italic")) tf[2] = 1;
      +        if (strstr(namebufp+1, "medium")) tf[3] = 1;
      +        if (strstr(namebufp+1, "plain")) tf[4] = 1;
      +        if (strstr(namebufp+1, "regular")) tf[5] = 1;
      +      }
      +    }
      +
      +    for (tj = 0; tj < lnum; tj ++, tk = 0) { // sort fonts styles in face
      +      if (!(namebufp = strstr(tbufs[tj], "-"))) namebufp = tbufs[tj];
      +      if (tf[1] && strstr(namebufp+1, "black")) tk = 1; // favour bold, italic, etc
      +      else if (strstr(namebufp+1, "condensed")) tk = 1;
      +      else if (strstr(namebufp+1, "cond") && namebufp > tbufs[tj]) tk = 1;
      +      else if (strstr(namebufp+1, "cn") && namebufp > tbufs[tj]) tk = 1;
      +      else if (strstr(namebufp+1, "extra")) tk = 1;
      +      else if (tf[1] && strstr(namebufp+1, "heavy")) tk = 1;
      +      else if ((tf[3] || tf[4] || tf[5]) && strstr(namebufp+1, "light")) tk = 1;
      +      else if (tf[2] && strstr(namebufp+1, "light")) tk = 1;
      +      else if (tf[2] && strstr(namebufp+1, "oblique")) tk = 1;
      +      else if (tf[2] && strstr(namebufp+1, "obl") && namebufp > tbufs[tj]) tk = 1;
      +      else if (tf[2] && strstr(namebufp+1, "inclined")) tk = 1;
      +      else if (tf[1] && strstr(namebufp+1, "semibold")) tk = 1;
      +      else if (tf[1] && strstr(namebufp+1, "smbd") && namebufp > tbufs[tj]) tk = 1;
      +      else if (tf[2] && strstr(namebufp+1, "slanted")) tk = 1;
      +      else if (strstr(namebufp+1, "ultra")) tk = 1;
      +      if (lnum > 8 && tf[1] && tf[2]) { // simplify if too many variations
      +        tk = 1;
      +        if (!strncmp(namebufp+1, "bold", 4) && namebufp[5] == '\0') tk = 0;
      +        if (!strncmp(namebufp+1, "italic", 6) && namebufp[7] == '\0') tk = 0;
      +        if (!strncmp(namebufp+1, "bolditalic", 10) && namebufp[11] == '\0') tk = 0;
      +        if (!strncmp(namebufp+1, "medium", 6) && namebufp[7] == '\0') tk = 0;
      +        if (!strncmp(namebufp+1, "regular", 7) && namebufp[8] == '\0') tk = 0;
      +      }
      +      if (tk == 1) continue; // skip font
      +      cbit = fbit = tbit = 0; // set font styles
      +      if (strstr(namebufp+1, "medium") || strstr(namebufp+1, "plain") ||
      +          strstr(namebufp+1, "regular")) cbit = 1;
      +      if (strstr(namebufp+1, "roman") && namebufp > tbufs[tj]) cbit = 1;
      +      if (strstr(namebufp+1, "bold") || strstr(namebufp+1, "italic")) cbit = 0;
      +      if (strstr(namebufp+1, "black") || strstr(namebufp+1, "bold") ||
      +          strstr(namebufp+1, "heavy") || strstr(namebufp+1, "semibold") ||
      +          strstr(namebufp+1, "wide")) fbit = 1;
      +      else if ((strstr(namebufp+1, "bd") || strstr(namebufp+1, "smbd")) &&
      +               namebufp > tbufs[tj]) fbit = 1;
      +      if (strstr(namebufp+1, "oblique") || strstr(namebufp+1, "inclined") ||
      +          strstr(namebufp+1, "italic") || strstr(namebufp+1, "slanted")) tbit = 1;
      +      else if ((strstr(namebufp+1, "it") || strstr(namebufp+1, "obl")) &&
      +               namebufp > tbufs[tj]) tbit = 1;
      +      if (cbit) face_[ti][0] = tfi[tj];
      +      if (fbit && !tbit && !face_[ti][1]) face_[ti][1] = tfi[tj]; // bold
      +      if (!fbit && tbit && !face_[ti][2]) face_[ti][2] = tfi[tj]; // italic
      +      if (fbit && tbit && !face_[ti][3]) face_[ti][3] = tfi[tj]; // plus
      +    }
      +  }
      +
      +  for (ti = 0; ti < nfaces; ti ++) { // remove duplicate fonts
      +    for (tj = ti+1; tj < nfaces; tj ++)
      +      if (face_[ti][1] == face_[tj][1]) face_[tj][1] = 0; // sort face loop does the rest
      +  }
      +
      +  for (ti = 0; ti < nfaces; ti ++) { // sort face table
      +    if (!face_[ti][2]) face_[ti][2] = face_[ti][0]; // no italic
      +    if (!face_[ti][3]) face_[ti][3] = face_[ti][1]; // no plus
      +    if (face_[ti][1]) { // move face
      +      for (tk = 0; tk < ti; tk ++) {
      +        if (!face_[tk][1]) { // first empty face
      +          for (tj = 0; tj <= 3; tj ++) {
      +            face_[tk][tj] = face_[ti][tj];
      +            face_[ti][tj] = 0;
      +          }
      +          break;
      +        }
      +      }
      +    }
      +  }
      +
      +  for (nfaces = 1; nfaces < (int)sizeof(face_)/8; nfaces ++)
      +    if (!face_[nfaces][1]) break; // recount faces
      +
      +  for (ti = 0, lnum = 0; ti < nfaces; ti ++) { // sort letter lut
      +    fnum = face_[ti][0];
      +    namep = Fl::get_font_name((Fl_Font)fnum, &temp);
      +    tnum = (uchar)tolower(*namep) - 97; // current letter, a = 0
      +    if (tnum != lnum && tnum < 27) // first instance of letter a..z
      +      flet_[tnum] = ti; // store face index
      +    lnum = tnum; // last letter
      +  }
      +  flet_[27] = nfaces; // last face index
      +
      +  for (ti = 0; ti < nfaces; ti ++) { // face reference table
      +    for (tj = 0; tj <= 3; tj ++) { // fonts in face
      +      fnum = face_[ti][tj]; // font index
      +      if (fnum < (int)sizeof(fref_)) fref_[fnum] = ti; // store face index
      +    }
      +  }
      +
      +  return nfaces; // we're done
      +
      +} // Fl_Help_View::build_faces()
      +
      +//
      +// Fl_Help_View::clear_global_selection() - Clear text selection.
      +//
      +
      +void Fl_Help_View::clear_global_selection()
      +{
      +  if (selected) redraw(); // Set widget to draw
      +  selection_push_first = selection_push_last = 0;
      +  selection_drag_first = selection_drag_last = 0;
      +  selection_first = selection_last = 0;
      +  selected = 0;
      +
      +} // Fl_Help_View::clear_global_selection()
      +
      +//
      +// Fl_Help_View::clear_selection() - Clear current text selection.
      +//
      +
      +void Fl_Help_View::clear_selection()
      +{
      +  if (current_view == this) clear_global_selection();
      +
      +} // Fl_Help_View::clear_selection()
      +
      +//
      +// Fl_Help_View::cmp_targets() - Compare two targets.
      +//
      +
      +int // O - Result of comparison
      +Fl_Help_View::cmp_targets(const Fl_Help_Link *t0, // I - First target
      +                          const Fl_Help_Link *t1) // I - Second target
      +{
      +  return strcasecmp(t0->name, t1->name); // Target names
      +
      +} // Fl_Help_View::cmp_targets()
      +
      +//
      +// Fl_Help_View::compare_targets() - replaced, struct used for d-pointer
      +//
      +
      +int
      +Fl_Help_View::compare_targets(const Fl_Help_Target *t0,
      +                              const Fl_Help_Target *t1)
      +{
      +  return 0;
      +
      +} // Fl_Help_View::compare_targets()
      +
      +//
      +// Fl_Help_View::do_align() - Compute alignment for a line in a block.
      +//
      +
      +int // O - New line
      +Fl_Help_View::do_align(Fl_Help_Block *b, // I - Block to add to
      +                       int li, // I - Current line - removed
      +                       int xx, // I - Current X position
      +                       int ca, // I - Current alignment
      +                       int &sl) // IO - Starting link
      +{
      +  int offset = 0; // Alignment offset
      +
      +  switch (ca) {
      +    case RIGHT : // Right
      +      offset = b->w - xx;
      +      break;
      +    case CENTER : // Center
      +      offset = (b->w - xx) / 2;
      +      break;
      +    default : // Left
      +      offset = 0;
      +      break;
      +  }
      +
      +  b->line = b->x + offset; // Left starting position for line
      +
      +  //if (li < 31) li ++;
      +
      +  while (sl < nlinks_) {
      +    links_[sl].x += offset; // X offset of link text
      +    links_[sl].w += offset; // Width of link text
      +    sl ++;
      +  }
      +
      +  return li;
      +
      +} // Fl_Help_View::do_align()
      +
      +//
      +// Fl_Help_View::draw() - Draw the Fl_Help_View widget.
      +//
      +
      +void Fl_Help_View::draw()
      +{
      +  char *sp, // Buffer search ptr
      +    //*tp, // temp buffer ptr - symbol font hack
      +    buf[1024], // Text buffer
      +    attr[1024], // Attribute buffer
      +    //tbuf[1024], // temp buffer - symbol font hack
      +    wattr[8], // Width attribute
      +    hattr[8], // Height attribute
      +    tag[4]; // tag/element 4-char buf
      +  const Fl_Help_Block *block; // Pointer to current block
      +  const char *ptr, // Pointer to text in block
      +    *attrptr, // Start of attributes ptr
      +    *tagptr; // Start of tag/element ptr
      +  int ti = 0, // temp loop var
      +    bi = 0, // Main loop var
      +    temp = 0, // temp var
      +    ss = 0, // Scrollbar size
      +    qch = 0, // Quote char
      +    baseh = 0, // baseline offset for images
      +    line = 0, // Current line
      +    xx = 0, yy = 0, ww = 0, hh = 0, // Current positions and sizes
      +    head = 0, // Head/body section flag
      +    pre = 0, // Pre text flag
      +    btag = 0, // tag/element fourcc int
      +    needspace = 0, // Do we need whitespace?
      +    underline = 0, // Underline text?
      +    tx = 0, ty = 0, tw = 0, th = 0, // Table cell positions and sizes
      +    linew = 0, // current line width
      +    imgw = 0, // Image width
      +    imgh = 0, // Image height
      +    brflag = 0, // br flag
      +	font = 0; // Current font
      +  unsigned char fsize; // Current font size
      +    //tfont, tempsize; // symbol font hack, not implemented
      +  Fl_Boxtype bt = (box()) ? box() : FL_DOWN_BOX; // Box to draw
      +  Fl_Shared_Image *img = 0; // Shared image - rem'd NULL
      +
      +  // Draw the scrollbar/s and box first
      +  ww = w();
      +  hh = h();
      +
      +  initfont(font, fsize);
      +
      +  draw_box(bt, x(), y(), ww, hh, bgcolor_);
      +
      +  ss = Fl::scrollbar_size();
      +  if (hscrollbar_.visible()) {
      +    draw_child(hscrollbar_);
      +    hh -= ss;
      +    ti ++;
      +  }
      +  if (scrollbar_.visible()) {
      +    draw_child(scrollbar_);
      +    ww -= ss;
      +    ti ++;
      +  }
      +  if (ti == 2) {
      +    fl_color(FL_GRAY);
      +    fl_rectf(x() + ww - Fl::box_dw(bt) + Fl::box_dx(bt),
      +             y() + hh - Fl::box_dh(bt) + Fl::box_dy(bt), ss, ss);
      +  }
      +
      +  if (!value_) return;
      +
      +  if (current_view == this && selected) {
      +    hv_selection_color = FL_SELECTION_COLOR;
      +    hv_selection_text_color = fl_contrast(textcolor_, FL_SELECTION_COLOR);
      +  }
      +  current_pos = 0;
      +
      +  // Clip the drawing to the inside of the box
      +  fl_push_clip(x() + Fl::box_dx(bt), y() + Fl::box_dy(bt),
      +               ww - Fl::box_dw(bt), hh - Fl::box_dh(bt));
      +  fl_color(textcolor_);
      +
      +//printf("hh=%d ss=%d h()=%d\n",hh,ss,h());
      +
      +  // Draw all visible blocks
      +  for (bi = 0, block = blocks_; bi < nblocks_; bi ++, block ++)
      +    if ((block->y + block->h) >= topline_ && block->y < (topline_ + h()))
      +    {
      +      line = 0;
      +      xx = block->line;
      +      yy = block->y - topline_;
      +      pre = block->pre;
      +      //if (!pre) {
      +      popfont(font, fsize);
      +      font = block->font; // default font for block
      +      fsize = block->fsize;
      +      pushfont(font, fsize);
      +      //}
      +      hh = 0;
      +      needspace = 0;
      +      brflag = 0;
      +      linew = 0;
      +
      +      for (ptr = block->start, sp = buf; ptr < block->end; )
      +      {
      +        if ((*ptr == '<' || isspace((*ptr) & 255)) && sp > buf)
      +        {
      +          if (!head && !pre) // Draw normal text
      +          {
      +            *sp = '\0'; // Nul-terminate
      +            sp = buf;
      +
      +            ww = (int)fl_width(buf); // Width of word in buf
      +            /* symbol font hack
      +            if (ww == 0) ww = (int)fl_width("&"); // pad control chars
      +            */
      +			  if (needspace && xx > block->x)
      +				  xx += 4;//(int)fl_width(" ");
      +
      +            baseh = 0; // add baseh offset for text
      +            if (block->maxh > 0 && block->imgy - topline_ == yy)
      +              baseh = block->maxh - fsize;
      +            //if (block->liney) baseh += block->liney;
      +
      +            /* symbol font hack
      +            tfont = font; // store font
      +
      +            while (sp < buf + strlen(buf)) {
      +            // extended chars use &# markup to change the font
      +
      +              tp = tbuf; // reset tp
      +              while (sp < buf + strlen(buf)) {
      +                if (*sp == '&' && *(sp + 1) == '#') {
      +                  *(tp ++) = (char)atoi(sp + 2); // convert str to int
      +                  sp = strchr(sp, ';') + 1; // skip past semi-colon char
      +                  font = FL_SYMBOL;
      +                  if (!(*sp == '&' && *(sp + 1) == '#'))
      +                    break; // draw tbuf in Symbol font
      +                }
      +                else {
      +                  *(tp ++) = *(sp ++);
      +                  font = tfont;
      +                  if (*sp == '&' && *(sp + 1) == '#')
      +                    break; // draw tbuf in current font
      +                }
      +              }
      +              *tp = '\0'; // Nul-terminate
      +
      +              pushfont(font, fsize); // pushfont
      +
      +              // width of word in tbuf, pad any zero-length control chars
      +              for (ti = 0, ww = 0; ti < strlen(tbuf); ti ++) {
      +                temp = (int)fl_width(tbuf[ti]);
      +                if (temp == 0) temp = (int)fl_width("&"); // pad
      +                ww += temp;
      +              }
      +
      +              hv_draw(tbuf, xx + x() - leftline_, yy + y() + baseh);
      +
      +              popfont(font, fsize); // popfont
      +              */
      +              hv_draw(buf, xx + x() - leftline_, yy + y() + baseh); // replaces hv_draw(tbuf..
      +
      +              if (underline) { // Add width for uline spaces after word
      +                temp = (isspace((*ptr) & 255)) ? (int)fl_width(" ") : 0;
      +                fl_xyline(xx + x() - leftline_, yy + y() + 1 + baseh,
      +                          xx + x() - leftline_ + ww + temp);
      +              }
      +
      +              xx += ww;
      +            /* symbol font hack
      +            }
      +
      +            sp = buf; // Reset sp
      +            font = tfont; // restore font
      +            */
      +            current_pos = ptr - value_;
      +            if ((fsize + 2) > hh) hh = fsize + 2; // Set hh
      +            needspace = 0;
      +
      +          }
      +          else if (!head && pre) // Draw pre text
      +          {
      +            // this code is buggy and conflicts with other stuff
      +            // don't think it's needed but leaving it just in case
      +         /* while (isspace((*ptr) & 255)) {
      +              if (*ptr == '\n') {
      +                *sp = '\0';
      +                sp = buf;
      +                hv_draw("|", xx + x() - leftline_, yy + y());
      +                if (underline)
      +                  fl_xyline(xx + x() - leftline_, yy + y() + 1,
      +                            xx + x() - leftline_ + (int)fl_width(buf));
      +                current_pos = ptr - value_;
      +                //if (line < 31) line ++;
      +                xx = block->line;
      +                yy += hh;
      +                hh = fsize + 2;
      +              }
      +              else if (*ptr == '\t') {
      +                ti = linew / (int)fl_width(" "); // number of chars
      +                temp = 8 - (ti & 7); // number of tabs
      +                for (ti = 0; ti < temp; ti ++) // pre tabs width fix
      +                  *(sp ++) = ' ';
      +              }
      +              else
      +                *(sp ++) = ' ';
      +              if ((fsize + 2) > hh) hh = fsize + 2;
      +              ptr ++;
      +            }
      +            if (sp > buf) { the code below was in here */
      +
      +            *sp = '\0'; // Nul-terminate
      +            sp = buf;
      +
      +            ww = (int)fl_width(buf);
      +
      +//printf("b->x=%d b->w=%d xx=%d ww=%d linew=%d ptr=%c buf=%s\n",
      +//  block->x,block->w,xx,ww,linew,*ptr,buf);
      +
      +            baseh = 0; // add baseh offset for pre text
      +            if (block->maxh > 0 && block->imgy - topline_ == yy)
      +              baseh = block->maxh - fsize;
      +
      +            hv_draw(buf, xx + x() - leftline_, yy + y() + baseh);
      +            if (underline)
      +              fl_xyline(xx + x() - leftline_, yy + y() + 1 + baseh,
      +                        xx + x() - leftline_ + ww);
      +
      +            xx += ww;
      +            linew += ww;
      +            current_pos = ptr - value_;
      +          // } // if (sp > buf)
      +
      +            needspace = 0;
      +          }
      +          else
      +          {
      +            sp = buf;
      +            while (isspace((*ptr) & 255)) ptr ++;
      +            current_pos = ptr - value_;
      +          }
      +
      +          brflag = 0;
      +        }
      +        
      +        if (*ptr == '<')
      +        {
      +          tagptr = ptr; // Start of tag
      +          ptr ++;
      +
      +          if (!strncmp(ptr, "!--", 3)) { // Found "!--"
      +           ptr += 3;
      +           if ((ptr = strstr(ptr, "-->"))) { // Skip comment - rem'd != 0
      +             ptr += 3;
      +             continue;
      +           }
      +           else
      +             break;
      +          }
      +
      +          while (*ptr && *ptr != '>' && !isspace((*ptr) & 255))
      +            if (sp < (buf + sizeof(buf) - 1))
      +              *(sp ++) = *(ptr ++); // added ()
      +            else
      +              ptr ++;
      +
      +          *sp = '\0'; // Nul-terminate
      +          sp = buf;
      +
      +          attrptr = ptr; // Start of attributes
      +          while (*ptr && *ptr != '>') ptr ++;
      +          if (*ptr == '>') ptr ++;
      +
      +          // Set the supposed start of printed eord here
      +          current_pos = ptr - value_;
      +
      +          btag = strlen(buf); // store strlen
      +          if (btag > 4) btag = 4; // limit
      +          for (ti = 0; ti < btag; ti ++) // abbreviate tag, to uppercase
      +            tag[ti] = toupper(buf[ti]);
      +          for (ti = btag; ti < 4; ti ++) // set chars after to nul
      +            tag[ti] = 0;
      +          if (buf[0] != '/' && btag > 3) tag[3] = 0; // eg. HTML=HTM
      +          btag = CMD(tag[0],tag[1],tag[2],tag[3]); // tag fourcc int
      +
      +          // End of command reached
      +          if (btag == CMD('A',0,0,0)) // 'A'
      +          {
      +            if (get_attr(attrptr, "HREF", attr, sizeof(attr))) {
      +              fl_color(linkcolor_);
      +              underline = 1;
      +            }
      +          }
      +          else if (btag == CMD('/','A',0,0)) // '/A'
      +          {
      +            fl_color(textcolor_);
      +            underline = 0;
      +          }
      +          else if (btag == CMD('B',0,0,0) ||
      +                   btag == CMD('S','T','R',0)) // 'B' 'STRONG'
      +          {
      +            font = font_style(font, FL_BOLD);
      +            pushfont(font, fsize);
      +          }
      +          else if (btag == CMD('/','B',0,0) ||
      +                   btag == CMD('/','S','T','R')) // '/B' '/STRONG'
      +          {
      +            popfont(font, fsize);
      +          }
      +          else if (btag == CMD('B','L','O',0) ||
      +                   btag == CMD('D','L',0,0) ||
      +                   btag == CMD('U','L',0,0) ||
      +                   btag == CMD('O','L',0,0) ||
      +                   btag == CMD('D','D',0,0) ||
      +                   btag == CMD('D','T',0,0)) // 'BLOCKQUOTE' 'DL'OL'UL'
      +          {
      +          }
      +          else if (btag == CMD('/','B','L','O') ||
      +                   btag == CMD('/','D','L',0) ||
      +                   btag == CMD('/','O','L',0) ||
      +                   btag == CMD('/','U','L',0)) // '/BLOCKQUOTE' '/DL'/OL'/UL'
      +          {
      +          }
      +          else if (btag == CMD('B','O','D',0)) // 'BODY'
      +          {
      +            head = 0;
      +          }
      +          else if (btag == CMD('B','R',0,0)) // 'BR'
      +          {
      +          }
      +          else if (btag == CMD('C','E','N',0)) // 'CENTER'
      +          {
      +          }
      +          else if (btag == CMD('C','O','D',0) ||
      +                   btag == CMD('T','T',0,0)) // 'CODE' 'TT'
      +          {
      +            font = monofont_;
      +            pushfont(font, fsize);
      +          }
      +          else if (btag == CMD('/','C','O','D') ||
      +                   btag == CMD('/','T','T',0)) // '/CODE' '/TT'
      +          {
      +            popfont(font, fsize);
      +          }
      +          else if (btag == CMD('D','I','V',0)) // 'DIV'
      +          {
      +          }
      +          else if (btag == CMD('F','O','N',0)) // 'FONT'
      +          {
      +            if (get_attr(attrptr, "COLOR", attr, sizeof(attr)))
      +              fl_color(get_color(attr, textcolor_));
      +
      +            if (get_attr(attrptr, "FACE", attr, sizeof(attr)))
      +              font = font_face(attr);
      +
      +            //tempsize = fsize;
      +            if (get_attr(attrptr, "SIZE", attr, sizeof(attr))) {
      +              if (isdigit(attr[0])) // Absolute size
      +                fsize = (int)(fontsize_ * pow(1.2, atof(attr) - 3.0));
      +              else // Relative size
      +                fsize = (int)(fsize * pow(1.2, atof(attr) - 3.0));
      +            }
      +
      +            pushfont(font, fsize);
      +            if (fsize + 2 > hh) hh = fsize + 2; // set hh
      +          }
      +          else if (btag == CMD('/','F','O','N')) // '/FONT'
      +          {
      +            fl_color(textcolor_);
      +            //tempsize = fsize;
      +            popfont(font, fsize);
      +            if (fsize + 2 > hh) hh = fsize + 2; // set hh
      +          }
      +          else if (tag[0] == 'H' && isdigit(tag[1])) // 'H1'
      +          {
      +            if (tag[1] < '7') { // ignore if > h6
      +              font = font_style(font, FL_BOLD);
      +              switch (tag[1]) { // header sizes
      +                case '1' : fsize = 24; break;
      +                case '2' : fsize = 18; break;
      +                case '3' : fsize = 16; break;
      +                case '4' : fsize = 14; break;
      +                case '5' : fsize = 12; break;
      +                case '6' : fsize = 10; break;
      +              }
      +              pushfont(font, fsize);
      +            }
      +          }
      +          else if (btag == CMD('/','H',tag[2],0) && isdigit(tag[2])) // '/H1'
      +          {
      +            if (tag[2] < '7') // ignore if > h6
      +              popfont(font, fsize);
      +          }
      +          else if (btag == CMD('H','E','A',0)) // 'HEAD'
      +          {
      +            head = 1;
      +          }
      +          else if (btag == CMD('/','H','E','A')) // '/HEAD'
      +          {
      +            head = 0;
      +          }
      +          else if (btag == CMD('H','R',0,0)) // 'HR'
      +          { // rem'd new line, added hr shadow
      +            tx = x() - leftline_; // hr x
      +            ty = yy + y() - fsize; // hr y
      +            fl_color(FL_BLACK);
      +            fl_line(block->x + tx, ty, block->w + tx, ty);
      +            fl_color(224, 224, 224); // light grey
      +            fl_line(block->x + tx, ty + 1, block->w + tx, ty + 1); // shadow
      +            fl_color(textcolor_); // reset
      +
      +            hh = fsize + 2; // set hh
      +          }
      +          else if (btag == CMD('H','T','M',0)) // 'HTML'
      +          {
      +          }
      +          else if (btag == CMD('I',0,0,0) ||
      +                   btag == CMD('E','M',0,0)) // 'I' 'EM'
      +          {
      +            font = font_style(font, FL_ITALIC);
      +            pushfont(font, fsize);
      +          }
      +          else if (btag == CMD('/','I',0,0) ||
      +                   btag == CMD('/','E','M',0)) // '/I' '/EM'
      +          {
      +            popfont(font, fsize);
      +          }
      +          else if (btag == CMD('I','M','G',0)) // 'IMG'
      +          {
      +            imgw = imgh = 0; // reset
      +            if (get_attr(attrptr, "WIDTH", wattr, sizeof(wattr)))
      +              imgw = get_length(wattr);
      +            if (get_attr(attrptr, "HEIGHT", hattr, sizeof(hattr)))
      +              imgh = get_length(hattr);
      +
      +            img = 0; // rem'd NULL
      +            if (get_attr(attrptr, "SRC", attr, sizeof(attr))) {
      +              img = get_image(attr, imgw, imgh);
      +              if (!imgw) imgw = img->w();
      +              if (!imgh) imgh = img->h();
      +            }
      +
      +            if (!imgw || !imgh) {
      +              if (!get_attr(attrptr, "ALT", attr, sizeof(attr))) // rem'd == 0
      +                strcpy(attr, "IMG");
      +            }
      +
      +            ww = imgw;
      +            if (needspace && xx > block->x)
      +              xx += (int)fl_width(" ");
      +
      +            if (img) {
      +              baseh = block->maxh - imgh; // add baseh offset
      +              img->draw(xx + x() - leftline_,
      +                        yy + y() - fl_height() + fl_descent() + baseh); // rem'd + 2
      +              // Seb was here - freeing broken_image causes an XServer XFreePixmap crash
      +              if ((void*)img != &broken_image) img->release();
      +            }
      +
      +            xx += ww;
      +            if (imgh + 2 > hh) hh = imgh + 2; // Set img hh
      +            needspace = 0;
      +            brflag = 0;
      +          }
      +          else if (btag == CMD('K','B','D',0)) // 'KBD'
      +          {
      +            font = font_style(monofont_, FL_BOLD);
      +            pushfont(font, fsize);
      +          }
      +          else if (btag == CMD('/','K','B','D')) // '/KBD'
      +          {
      +            popfont(font, fsize);
      +          }
      +          else if (btag == CMD('L','I',0,0)) // 'LI'
      +          {
      +            // rem'd hv_draw and symbol font stuff
      +            tx = xx - fsize + x() - leftline_; // bullet x
      +            ty = yy + y() - 6; // bullet y
      +
      +            get_attr(attrptr, "TYPE", attr, sizeof(attr)); // bullet type
      +            if (!strncasecmp(attr, "disc", 4) ||
      +                !strncasecmp(attr, "disk", 4)) { // li > ul > ul nest
      +              fl_arc(tx, ty, 5, 5, 0, 360);
      +              fl_rectf(tx + 1, ty + 1, 3, 3);
      +            }
      +            else if (!strncasecmp(attr, "circle", 6))
      +              fl_arc(tx, ty, 5, 5, 0, 360);
      +            else if (!strncasecmp(attr, "square", 6))
      +              fl_rectf(tx, ty, 5, 5);
      +            else if (block->type == 1) { // disc/disk
      +              fl_arc(tx, ty, 5, 5, 0, 360);
      +              fl_rectf(tx + 1, ty + 1, 3, 3);
      +            }
      +            else if (block->type == 2) // circle
      +              fl_arc(tx, ty, 5, 5, 0, 360);
      +            else if (block->type >= 3) // square
      +              fl_rectf(tx, ty, 5, 5);
      +            else { // default
      +              fl_arc(tx, ty, 5, 5, 0, 360);
      +              fl_rectf(tx + 1, ty + 1, 3, 3);
      +            }
      +          }
      +          else if (btag == CMD('/','L','I',0)) // '/LI'
      +          {
      +          }
      +          else if (btag == CMD('N','O','S',0)) // 'NOSCRIPT'
      +          { // we don't support scripting so we won't skip this
      +          }
      +          else if (btag == CMD('P',0,0,0)) // 'P'
      +          {
      +          }
      +          else if (btag == CMD('P','R','E',0)) // 'PRE'
      +          {
      +            linew = 0;
      +            pre = 1;
      +            //font = monofont_;
      +            //fsize = fontsize_;
      +            //pushfont(font, fsize);
      +            
      +            tx = block->x - leftline_;
      +            ty = block->y - topline_ - fsize;
      +            tw = block->w - block->x - 2;
      +            th = block->h + fsize + (fsize / 4);
      +
      +            if (tx < 0) {
      +              tw += tx;
      +              tx = 0;
      +            }
      +            if (ty < 0) {
      +              th += ty;
      +              ty = 0;
      +            }
      +            tx += x();
      +            ty += y();
      +            
      +           if (block->bgcolor != bgcolor_) {
      +              fl_color(block->bgcolor);
      +              fl_rectf(tx, ty, tw, th);
      +              fl_color(textcolor_);
      +            }
      +            if (block->border)
      +              fl_rect(tx, ty, tw, th);
      +              
      +          }
      +          else if (btag == CMD('/','P','R','E')) // '/PRE'
      +          {
      +            //popfont(font, fsize);
      +            pre = 0;
      +          }
      +          else if (btag == CMD('S','C','R',0)) // 'SCRIPT'
      +          {
      +            while (ptr) { // skip scripting
      +              ptr = strstr(ptr, "", 9)) break;
      +            }
      +
      +            if (ptr) { // found 
      +              ptr += 9;
      +              continue;
      +            }
      +            else // not found
      +              break;
      +          }
      +          else if (btag == CMD('T','A','B',0)) // 'TABLE'
      +          {
      +          }
      +          else if (btag == CMD('T','D',0,0) ||
      +                   btag == CMD('T','H',0,0)) // 'TD' 'TH'
      +          {
      +            /*if (btag == CMD('T','H',0,0))
      +              font = serifont_ | FL_BOLD;
      +            else
      +              font = serifont_;
      +            fsize = fontsize_;
      +            pushfont(font, fsize);*/
      +
      +            fl_color(textcolor_); // fixes /a td bug
      +            underline = 0;
      +
      +            tx = block->x - 4 - leftline_;
      +            ty = block->y - topline_ - fsize - 3;
      +            tw = block->w - block->x + 7;
      +            th = block->h + fsize - 5;
      +
      +            if (tx < 0) {
      +              tw += tx;
      +              tx = 0;
      +            }
      +            if (ty < 0) {
      +              th += ty;
      +              ty = 0;
      +            }
      +            tx += x();
      +            ty += y();
      +
      +            if (block->bgcolor != bgcolor_) {
      +              fl_color(block->bgcolor);
      +              fl_rectf(tx, ty, tw, th);
      +              fl_color(textcolor_);
      +            }
      +            if (block->border)
      +              fl_rect(tx, ty, tw, th);
      +              
      +          }
      +          else if (btag == CMD('/','T','D',0) ||
      +                   btag == CMD('/','T','H',0)) // '/TD' '/TH'
      +          {
      +            //popfont(font, fsize);
      +          }
      +          else if (btag == CMD('T','I','T',0)) // 'TITLE'
      +          {
      +            head = 1;
      +          }
      +          else if (btag == CMD('T','R',0,0)) // 'TR'
      +          {
      +          }
      +          else if (btag == CMD('U',0,0,0)) // 'U'
      +          {
      +            underline = 1;
      +          }
      +          else if (btag == CMD('/','U',0,0)) // '/U'
      +          {
      +            underline = 0;
      +          }
      +          else if (btag == CMD('V','A','R',0)) // 'VAR'
      +          {
      +            font = font_style(monofont_, FL_ITALIC);
      +            pushfont(font, fsize);
      +          }
      +          else if (btag == CMD('/','V','A','R')) // '/VAR'
      +          {
      +            popfont(font, fsize);
      +          }
      +          else if (btag == CMD('A','B','B',0) || // 'ABBR'
      +                   btag == CMD('A','C','R',0) || // 'ACRONYM'
      +                   btag == CMD('A','D','D',0) || // 'ADDRESS'
      +                   btag == CMD('A','P','P',0) || // 'APPLET'
      +                   btag == CMD('A','R','E',0) || // 'AREA'
      +                   btag == CMD('B','A','S',0) || // 'BASE' 'BASEFONT'
      +                   btag == CMD('B','D','O',0) || // 'BDO'
      +                   btag == CMD('B','G','S',0) || // 'BGSOUND'
      +                   btag == CMD('B','I','G',0) || // 'BIG'
      +                   btag == CMD('B','L','I',0) || // 'BLINK'
      +                   btag == CMD('B','U','T',0) || // 'BUTTON'
      +                   btag == CMD('C','A','P',0) || // 'CAPTION'
      +                   btag == CMD('C','I','T',0) || // 'CITE'
      +                   btag == CMD('C','O','L',0) || // 'COL' 'COLGROUP'
      +                   btag == CMD('D','E','L',0) || // 'DEL'
      +                   btag == CMD('D','F','N',0) || // 'DFN'
      +                   btag == CMD('D','I','R',0) || // 'DIR'
      +                   btag == CMD('E','M','B',0) || // 'EMBED'
      +                   btag == CMD('F','I','E',0) || // 'FIELDSET'
      +                   btag == CMD('F','O','R',0) || // 'FORM'
      +                   btag == CMD('F','R','A',0) || // 'FRAME' 'FRAMESET'
      +                   btag == CMD('I','F','R',0) || // 'IFRAME'
      +                   btag == CMD('I','N','P',0) || // 'INPUT'
      +                   btag == CMD('I','N','S',0) || // 'INS'
      +                   btag == CMD('I','S','I',0) || // 'ISINDEX'
      +                   btag == CMD('L','A','B',0) || // 'LABEL'
      +                   btag == CMD('L','E','G',0) || // 'LEGEND'
      +                   btag == CMD('L','I','N',0) || // 'LINK'
      +                   btag == CMD('M','A','P',0) || // 'MAP'
      +                   btag == CMD('M','A','R',0) || // 'MARQUEE'
      +                   btag == CMD('M','E','N',0) || // 'MENU'
      +                   btag == CMD('M','E','T',0) || // 'META'
      +                   btag == CMD('M','U','L',0) || // 'MULTICOL'
      +                   btag == CMD('N','O','B',0) || // 'NOBR'
      +                   btag == CMD('N','O','F',0) || // 'NOFRAMES'
      +                   btag == CMD('O','B','J',0) || // 'OBJECT'
      +                   btag == CMD('O','P','T',0) || // 'OPTGROUP' 'OPTION'
      +                   btag == CMD('P','A','R',0) || // 'PARAM'
      +                   btag == CMD('Q',0,0,0) || // 'Q'
      +                   btag == CMD('S',0,0,0) || // 'S'
      +                   btag == CMD('S','A','M',0) || // 'SAMP'
      +                   btag == CMD('S','E','L',0) || // 'SELECT'
      +                   btag == CMD('S','M','A',0) || // 'SMALL'
      +                   btag == CMD('S','P','A',0) || // 'SPACER' 'SPAN'
      +                   btag == CMD('S','T','R',0) || // 'STRIKE'
      +                   btag == CMD('S','T','Y',0) || // 'STYLE'
      +                   btag == CMD('S','U','B',0) || // 'SUB'
      +                   btag == CMD('S','U','P',0) || // 'SUP'
      +                   btag == CMD('T','B','O',0) || // 'TBODY'
      +                   btag == CMD('T','E','X',0) || // 'TEXTAREA'
      +                   btag == CMD('T','F','O',0) || // 'TFOOT'
      +                   btag == CMD('T','H','E',0) || // 'THEAD'
      +                   btag == CMD('W','B','R',0) || // 'WBR'
      +                   btag == CMD('X','M','P',0)) // 'XMP'
      +            ; // unsupported tags
      +          else if (tag[0] == '!' && isalpha(tag[1])) // '!DOCTYPE' etc
      +            ;
      +          else if (tag[0] == '?' && isalpha(tag[1])) // '?XMP' etc
      +            ;
      +          else if (tag[0] == '/' && isalpha(tag[1])) // unrecognized end tag
      +            ;
      +          else if (!head) // unrecognized tag so draw it
      +          {
      +            hv_draw("<", xx + x() - leftline_, yy + y()); // draw '<' char
      +            xx += (int)fl_width("<"); // add width of '<' char
      +            linew += (int)fl_width("<");
      +            ptr = tagptr + 1; // start of tag + 1
      +          }
      +          
      +        } // if (*ptr == '<')
      +
      +        else if (*ptr == '\n' && pre) // '\n' char in pre
      +        {
      +          *sp = '\0'; // Nul-terminate
      +          sp = buf;
      +
      +          hv_draw(buf, xx + x() - leftline_, yy + y());
      +
      +          //hh = fsize + 2; // Set hh
      +          linew = 0;
      +          needspace = 0;
      +          ptr ++;
      +          current_pos = ptr - value_;
      +        }
      +        else if (isspace((*ptr) & 255)) // ' ' '\t'\n'\v'\f'\r' chars
      +        {
      +
      +          if (pre) {
      +            if (*ptr == ' ')
      +              *(sp ++) = ' '; // added ()
      +            else if (*ptr == '\t') {
      +              ti = linew / (int)fl_width(" "); // number of chars, monospace
      +              temp = 8 - (ti & 7); // number of tabs 1..8
      +              for (ti = 0; ti < temp; ti ++) // pre tabs width fix
      +                *(sp ++) = ' '; // added ()
      +            }
      +          }
      +
      +          ptr ++;
      +          if (!pre) current_pos = ptr - value_;
      +          needspace = 1; // Set need space flag
      +        }
      +        else if (*ptr == '&') // '&' char ref
      +        {
      +          ptr ++;
      +          qch = quote_char(ptr);
      +          /* symbol font hack
      +          temp = quote_char(ptr, 1); // check font char uses
      +          */
      +          if (qch < 0) // Not char ref
      +            *(sp ++) = '&';
      +          /* symbol font hack
      +          else if (temp == 0) { // current font
      +          */
      +          else { // replaces else if (temp == 0)
      +            *(sp ++) = qch; // added ()
      +            ptr = strchr(ptr, ';') + 1; // skip past semi-colon char
      +          }
      +          /* symbol font hack
      +          else if (temp == 1) { // symbol font
      +            temp = sprintf(wattr, "&#%d", qch); // convert int to str
      +            for (ti = 0; ti < temp; ti ++)
      +              *(sp ++) = wattr[ti]; // set extended char &# markup
      +            ptr = strchr(ptr, ';'); // skip to semi-colon char
      +          }
      +          else
      +            *(sp ++) = '&';
      +          */
      +          if ((fsize + 2) > hh) hh = fsize + 2; // Set hh
      +        }
      +        else
      +        {
      +          *(sp ++) = *(ptr ++); // added ()
      +          if ((fsize + 2) > hh) hh = fsize + 2; // Set hh
      +        }
      +      } // for (ptr = block->start ...)
      +
      +      *sp = '\0'; // Nul-terminate
      +
      +      if (sp > buf) // Still something left to parse
      +      {
      +        ww = (int)fl_width(buf); // Width of word
      +
      +        if (!head && !pre) { // Normal text
      +          if (needspace && xx > block->x)
      +            xx += (int)fl_width(" ");
      +        }
      +
      +        if (!head) { // Draw text
      +          baseh = 0; // add baseh offset for missed text
      +          if (block->maxh > 0 && block->imgy - topline_ == yy)
      +            baseh = block->maxh - fsize;
      +          //if (block->liney) baseh += block->liney;
      +
      +          hv_draw(buf, xx + x() - leftline_, yy + y() + baseh);
      +
      +          if (underline)
      +            fl_xyline(xx + x() - leftline_, yy + y() + 1 + baseh,
      +                      xx + x() - leftline_ + ww);
      +
      +          current_pos = ptr - value_;
      +        }
      +      }
      +
      +    } // for (bi = 0 ...)
      +
      +  fl_pop_clip();
      +
      +} // Fl_Help_View::draw()
      +
      +//
      +// Fl_Help_View::end_selection() - End text selection.
      +//
      +
      +void Fl_Help_View::end_selection(int cb) // I - Set clipboard, opt
      +{
      +  if (!selected || current_view != this) return;
      +
      +  // Convert the select part of our html text into some kind of
      +  // somewhat readable ASCII and store it in the selection buffer
      +  char spacec = 0, pre = 0, tempc = 0, endc = 0;
      +  int len = strlen(value_),
      +    in = 0, xx = 0;
      +  char *text = (char*)malloc(len + 1),
      +    *dp = text;
      +  const char *sp = value_,
      +    *cmdp,
      +    *srcp;
      +
      +  while (true) // was for (;;)
      +  {
      +    tempc = *(sp ++); // added ()
      +    if (tempc == 0) break;
      +    if (tempc == '<') { // Begin of some html command. Skip until we find a '>'
      +      cmdp = sp;
      +      while (true) { // was for (;;)
      +        tempc = *(sp ++); // added ()
      +        if (tempc == 0 || tempc == '>') break;
      +      }
      +      if (tempc == 0) break;
      +      // Do something with this command, the replacement string must
      +      // not be longer that the command itself plus '<' and '>'
      +      srcp = 0; // rem'd NULL
      +      switch (command(cmdp)) {
      +        case CMD('p','r','e', 0 ): pre = 1; break;
      +        case CMD('/','p','r','e'): pre = 0; break;
      +        case CMD('t','d', 0 , 0 ):
      +        case CMD('p', 0 , 0 , 0 ):
      +        case CMD('/','p', 0 , 0 ):
      +        case CMD('b','r', 0 , 0 ): srcp = "\n"; break;
      +        case CMD('l','i', 0 , 0 ): srcp = "\n * "; break;
      +        case CMD('/','h','1', 0 ):
      +        case CMD('/','h','2', 0 ):
      +        case CMD('/','h','3', 0 ):
      +        case CMD('/','h','4', 0 ):
      +        case CMD('/','h','5', 0 ):
      +        case CMD('/','h','6', 0 ): srcp = "\n\n"; break;
      +        case CMD('t','r', 0 , 0 ):
      +        case CMD('h','1', 0 , 0 ):
      +        case CMD('h','2', 0 , 0 ):
      +        case CMD('h','3', 0 , 0 ):
      +        case CMD('h','4', 0 , 0 ):
      +        case CMD('h','5', 0 , 0 ):
      +        case CMD('h','6', 0 , 0 ): srcp = "\n\n"; break;
      +        case CMD('d','t', 0 , 0 ): srcp = "\n "; break;
      +        case CMD('d','d', 0 , 0 ): srcp = "\n - "; break;
      +      }
      +      in = sp - value_;
      +      if (srcp && in > selection_first && in <= selection_last) {
      +        while (*srcp)
      +          *(dp ++) = *(srcp ++); // added ()
      +        tempc = srcp[-1];
      +        spacec = (isspace(tempc & 255)) ? ' ' : tempc;
      +      }
      +      continue;
      +    }
      +
      +    if (tempc == '&') { // Special characters
      +      xx = quote_char(sp);
      +
      +      if (xx >= 0) {
      +        tempc = (char)xx;
      +        while (true) { // was for (;;)
      +          endc = *(sp ++); // added ()
      +          if (!endc || endc == ';') break;
      +        }
      +      }
      +    }
      +
      +    in = sp - value_;
      +    if (in > selection_first && in <= selection_last) {
      +      if (!pre && isspace(tempc & 255)) tempc = ' ';
      +      if (spacec != ' ' || tempc != ' ')
      +        *(dp ++) = tempc; // added ()
      +      spacec = tempc;
      +    }
      +  }
      +
      +  *dp = 0;
      +  Fl::copy(text, strlen(text), cb);
      +  free(text);
      +
      +} // Fl_Help_View::end_selection()
      +
      +//
      +// Fl_Help_View::extend_selection() - Extend current text selection.
      +//
      +
      +char // O - True if text selection changed
      +Fl_Help_View::extend_selection()
      +{
      +  if (Fl::event_is_click()) return 0;
      +
      +//printf("old selection_first=%d, selection_last=%d\n",
      +//  selection_first, selection_last);
      +
      +  int sf = selection_first,
      +    sl = selection_last;
      +
      +  selected = 1;
      +  mouse_x = Fl::event_x();
      +  mouse_y = Fl::event_y();
      +  draw_mode = 2; // End selection mode
      +
      +  fl_begin_offscreen(fl_help_view_buffer);
      +  draw();
      +  fl_end_offscreen();
      +
      +  draw_mode = 0;
      +
      +  if (selection_push_first < selection_drag_first) {
      +    selection_first = selection_push_first;
      +  }
      +  else {
      +    selection_first = selection_drag_first;
      +  }
      +
      +  if (selection_push_last > selection_drag_last) {
      +    selection_last = selection_push_last;
      +  }
      +  else {
      +    selection_last = selection_drag_last;
      +  }
      +
      +//printf("new selection_first=%d, selection_last=%d\n",
      +//  selection_first, selection_last);
      +
      +  if (sf != selection_first || sl != selection_last) { // was ! =
      +//  puts("REDRAW!!!\n");
      +    return 1;
      +  }
      +  else {
      +//  puts("");
      +    return 0;
      +  }
      +
      +} // Fl_Help_View::extend_selection()
      +
      +//
      +// Fl_Help_View::fileislink() - Was link clicked or nav button?
      +//
      +
      +int Fl_Help_View::fileislink() // O - Link clicked
      +{
      +  return d->islink;
      +}
      +
      +//
      +// Fl_Help_View::filepath() - Set value file path string.
      +//
      +
      +void Fl_Help_View::filepath(const char *fp) // I - Current file path
      +{
      +  if (!fp) return; // null
      +  d->ispath = 1; // path is used
      +
      +  if (!d->islink) // nav button
      +    strlcpy(d->lpath, d->path, sizeof(d->lpath)); // set last path
      +  strlcpy(d->path, fp, sizeof(d->path)); // set path
      +}
      +
      +//
      +// Fl_Help_View::filepath() - Get value file path string.
      +//
      +
      +char *Fl_Help_View::filepath() // O - Current file path
      +{
      +  return d->path;
      +}
      +
      +//
      +// Fl_Help_View::find() - Find the specified string.
      +//
      +
      +int // O - Matching position or -1 if not found
      +Fl_Help_View::find(const char *sp, // I - String to find
      +                   int pos) // I - Starting position, opt
      +{
      +  int ti = 0, // Temp looping var
      +    cref = 0; // Current char ref
      +  Fl_Help_Block *block; // Current block
      +  const char *bptr, // Block matching pointer
      +    *cptr, // Start of current comparison pointer
      +    *sptr; // Search string pointer
      +
      +  // Range check input and value
      +  if (!sp || !value_) return -1;
      +
      +  if (pos < 0 || pos >= (int)strlen(value_))
      +    pos = 0;
      +  else if (pos > 0)
      +    pos ++;
      +
      +  // Look for the string
      +  for (ti = nblocks_, block = blocks_; ti > 0; ti --, block ++)
      +  {
      +    if (block->end < (value_ + pos))
      +      continue;
      +
      +    if (block->start < (value_ + pos))
      +      bptr = value_ + pos;
      +    else
      +      bptr = block->start;
      +
      +    for (sptr = sp, cptr = bptr; *sptr && *bptr && bptr < block->end; bptr ++)
      +    {
      +      if (*bptr == '<') { // Skip to end of element
      +        while (*bptr && bptr < block->end && *bptr != '>')
      +          bptr ++;
      +        continue;
      +      }
      +      else if (*bptr == '&') { // Decode HTML entity
      +        cref = quote_char(bptr + 1);
      +
      +        if (cref < 0) // Not char ref
      +          cref = '&';
      +        else
      +          bptr = strchr(bptr + 1, ';') + 1;
      +      }
      +      else
      +        cref = *bptr;
      +
      +      if (tolower(*sptr) == tolower(cref))
      +        sptr ++;
      +      else { // No match, so reset to start of search
      +        sptr = sp;
      +        cptr ++;
      +        bptr = cptr;
      +      }
      +    } // for (sptr = sp ...)
      +
      +    if (!*sptr) { // Found a match!
      +      topline(block->y - block->h);
      +      return (block->end - value_);
      +    }
      +  } // for (ti = nblocks_ ...)
      +
      +  return -1; // No match!
      +
      +} // Fl_Help_View::find()
      +
      +//
      +// Fl_Help_View::find_link() - Find the link at the given position.
      +//
      +
      +Fl_Help_Link * // O - Link pointer
      +Fl_Help_View::find_link(int xx, // I - X position
      +                        int yy) // I - Y position
      +{
      +  int ti = 0;
      +  Fl_Help_Link *linkp;
      +
      +  for (ti = nlinks_, linkp = links_; ti > 0; ti --, linkp ++) {
      +    if (xx >= linkp->x && xx < linkp->w &&
      +        yy >= linkp->y && yy < linkp->h)
      +      break;
      +  }
      +  return (ti) ? linkp : 0; // Was link found? - rem'd NULL
      +
      +} // Fl_Help_View::find_link()
      +
      +//
      +// Fl_Help_View::follow_link() - Follow the specified link.
      +//
      +
      +void Fl_Help_View::follow_link(Fl_Help_Link *lp) // I - Link pointer
      +{
      +  char target[32], // Current target
      +    dir[1024], // Current directory
      +    temp[1024], // Temporary filename
      +    *tptr, *sptr, *dirp; // Pointer into temporary filename
      +  const char *namep = lp->filename; // link filename
      +
      +  strlcpy(target, lp->name, sizeof(target));
      +  clear_selection(); // Clear text selection
      +  set_changed(); // Set widget value was changed
      +
      +//printf(" follow_link namep=(%s)\n",namep);
      +//printf(" follow_link filename_=(%s)\n",filename_);
      +
      +  if (namep[0] && strcmp(namep, filename_)) // Link not same as filename_
      +  {
      +    if (strchr(directory_, ':') && !strchr(namep, ':')) // rem'd != 0 and == 0
      +    { // dir is absolute, lp is relative
      +      if (namep[0] == '/') { // lp is absolute
      +        strlcpy(temp, directory_, sizeof(temp));
      +        if ((tptr = strrchr(strchr(directory_, ':') + 3, '/')) != 0) // ? - get filename
      +          strlcpy(tptr, namep, sizeof(temp)-(tptr - temp)); // ? - add filename
      +        else // ? - dir should never have a filename so why check?
      +          strlcat(temp, namep, sizeof(temp));
      +      }
      +      else // lp just filename
      +        snprintf(temp, sizeof(temp), "%s/%s", directory_, namep);
      +    }
      +    else if (namep[0] != '/' && !strchr(namep, ':')) // rem'd == 0
      +    { // Relative path
      +      if (directory_[0]) // Add filename
      +        snprintf(temp, sizeof(temp), "%s/%s", directory_, namep);
      +      else {
      +        dirp = getcwd(dir, sizeof(dir)); // ? - try cwd, may be wrong..
      +        snprintf(temp, sizeof(temp), "%s/%s", dir, namep); // ?
      +      }
      +    }
      +    else // Use lp
      +      strlcpy(temp, namep, sizeof(temp));
      +
      +    if (d->ispath) { // path is used
      +      strlcpy(temp, d->path, sizeof(temp)); // ?
      +      if (namep[0] == '/' || namep[1] == ':' || // absolute or remote
      +          !strncmp(namep, "ftp:", 4) || !strncmp(namep, "http:", 5) ||
      +          !strncmp(namep, "https:", 6) || !strncmp(namep, "ipp:", 4) ||
      +          !strncmp(namep, "mailto:", 7) || !strncmp(namep, "news:", 5))
      +        strlcpy(temp, namep, sizeof(temp));
      +      else if (!strncasecmp(namep, "javascript:history", 18)) {
      +        strlcpy(temp, namep, sizeof(temp));
      +        if (!(d->nstyle & HV_NONAVIGATE)) { // user navigation
      +          strlcpy(temp, d->lpath, sizeof(temp)); // use last path
      +          if (!d->lpath[0]) // last path empty
      +            strlcpy(temp, d->path, sizeof(temp)); // use path
      +          d->isnav = 1; // set is nav link
      +        }
      +      }
      +      else if ((tptr = strrchr(temp, '/'))) // relative path, add filename
      +          strlcpy(tptr + 1, namep, sizeof(temp)-(tptr + 1 - temp));
      +    }
      +
      +    if (target[0]) { // Add target
      +      strlcat(temp, "#", sizeof(temp)); // was snprintf(temp + strlen..
      +      strlcat(temp, target, sizeof(temp));
      +    }
      +
      +    while ((tptr = strstr(temp, "/.."))) { // remove ../ from path
      +      for (sptr = tptr - 1; sptr > temp; sptr --)
      +        if (*sptr == '/') break; // seek back to last dir
      +      if (sptr == temp) break; // nothing to remove
      +      *sptr = '\0'; // nul-terminate
      +      strlcat(temp, tptr + 3, sizeof(temp)); // add rest of path
      +    }
      +    while ((tptr = strstr(temp, "/./"))) { // remove ./ from path
      +      *tptr = '\0';
      +      strlcat(temp, tptr + 2, sizeof(temp));
      +    }
      +
      +    if (d->ispath) { // path is used
      +      if (!strncasecmp(temp, "javascript:history", 18)) { // store js
      +        strlcpy(d->lpath, d->path, sizeof(d->lpath)); // last path
      +        strlcpy(d->path, temp, sizeof(d->path)); // link for history
      +      }
      +      else if ((tptr = strrchr(temp, '/'))) { // store valid ext
      +        if (strstr(tptr, ".htm") || strstr(tptr, ".txt")) {
      +          strlcpy(d->lpath, d->path, sizeof(d->lpath)); // last path
      +          strlcpy(d->path, temp, sizeof(d->path)); // link for history
      +        }
      +      }
      +    }
      +
      +//printf(" follow_link d->path=(%s)\n",d->path);
      +//printf(" follow_link temp=(%s)\n",temp);
      +
      +    load(temp); // Load filename
      +  }
      +  else if (target[0]) // Target in link
      +  {
      +    if (d->ispath) { // path is used
      +      if ((tptr = strrchr(d->path, '#'))) *tptr = '\0'; // remove target
      +      strlcat(d->path, "#", sizeof(d->path));
      +      strlcat(d->path, target, sizeof(d->path));
      +      load(d->path); // load target for history
      +    }
      +    //topline(target); // rem'd
      +  }
      +  //else topline(0); leftline(0); // rem'd
      +
      +/*printf("\nFl_Help_Target\n");
      +printf(" targets=%s\n",d->targets->filename);
      +printf(" linkp=%s\n",d->linkp->filename);
      +printf(" ispush=%d\n",d->ispush);
      +printf(" islink=%d\n",d->islink);
      +printf(" resized=%d\n",d->resized);
      +printf(" ispath=%d\n",d->ispath);
      +printf(" nstyle=%d\n",d->nstyle);
      +printf(" top=%d\n",d->top);
      +printf(" ltop=%d\n",d->ltop);
      +printf(" isnav=%d\n",d->isnav);
      +printf(" rwidth=%d\n",d->rwidth);
      +printf(" rtime=%d\n",d->rtime);
      +printf(" rsec=%d\n",d->rsec);
      +printf(" rmil=%d\n",d->rmil);
      +printf(" path=%s\n",d->path);
      +printf(" lpath=%s\n",d->lpath);*/
      +
      +} // Fl_Help_View::follow_link()
      +
      +//
      +// Fl_Help_View::font_face() - Get a font face from a list of names.
      +//
      +
      +// Usage: parses a comma-separated string of font names in order of
      +// preference and returns the font face.
      +
      +int // O - font face or base font list index
      +Fl_Help_View::font_face(const char *sp) // I - name of font to find
      +{
      +  char buf[100], namebuf[100]; // buffers
      +  const char *listp, *namep; // pointers
      +  int ti = 0, tj = 0, tk = 0, // temp loop vars
      +    tnum = 0, lnum = 0, fnum = 0, // temp/last/font counters
      +    nfonts = 0, nfaces = 0, // numbers
      +    temp = 0, slen = 0, dfont = 0; // misc
      +  unsigned char flen[10]; // font name lengths
      +
      +  slen = strlen(sp); // string length
      +  if (!slen) return 0; // sp not valid
      +  if (slen > 255) slen = 255; // set max length
      +
      +  for (ti = 0, listp = sp, nfaces = 0; ti < slen; ti ++, listp ++) {
      +    if (ti == slen - 1 || *listp == ',') { // end or ',' char
      +      if (nfaces < 8 && *(listp + 1) != ',') { // skip ",,"
      +        flen[nfaces] = ti; // store positions
      +        if (ti == slen - 1) flen[nfaces] = ti + 1;
      +        nfaces ++; // count faces
      +      }
      +    }
      +  }
      +
      +  for (ti = nfaces - 1; ti > 0; ti --) { // calc string lengths
      +    temp = flen[ti] - flen[ti - 1] - 1;
      +    flen[ti] = temp;
      +  }
      +
      +  nfonts = Fl::set_fonts(0); // get ISO8859-1 fonts, ignore rest
      +
      +  for (ti = 0, listp = sp; ti < nfaces; ti ++) // main loop
      +  {
      +    while (*listp == ',') listp ++; // skip ',' chars
      +    if (flen[ti] > sizeof(buf)-1) flen[ti] = sizeof(buf)-1; // max buffer size
      +
      +	  for (tj = 0, tk = 0; tj < flen[ti]; tj ++) { // remove spaces in font names
      +		  if (isspace(listp[tj])) continue;
      +		  else if (listp[tj] == '-') break;
      +		  buf[tk] = tolower(listp[tj]); // copy char to lowercase
      +		  tk ++;
      +    }
      +    buf[tj] = '\0'; // nul-terminate
      +	  
      +    fnum = (uchar)*buf - 97; // first letter index, a = 0
      +    if (fnum < 0 || fnum > 25) continue; // not a..z, assume font starts with letter
      +    tnum = flet_[fnum]; // current face index, loop start
      +    for (tj = fnum + 1; tj < 27; tj ++) {
      +      if (flet_[tj] > 0) {
      +        lnum = flet_[tj]; break; // last face index, loop end
      +      }
      +    }
      +
      +    slen = strlen(buf); // first word length
      +    for (tj = tnum; tj < lnum; tj ++) { // find current font
      +      fnum = face_[tj][0]; // base font index
      +      namep = Fl::get_font_name((Fl_Font)fnum, &temp); // fltk font name
      +		for (tk = 0, temp = 0; namep[tk] != '\0'; tk ++) { // remove spaces in font name
      +			if (isspace(namep[tk])) continue;
      +			else if (namep[tk] == '-') break;
      +			namebuf[temp] = tolower(namep[tk]); // copy chars to lowercase
      +			temp ++;
      +		}
      +      namebuf[tk] = '\0'; // nul-terminate
      +		if (!strncmp(namebuf, buf, slen)) // found name
      +			return fnum;
      +    }
      +	
      +    if (!dfont) { // check default fonts
      +      if (!strncmp(buf, "courier", 7)) dfont = monofont_;
      +      if (!strncmp(buf, "times", 5)) dfont = serifont_;
      +      if (!strncmp(buf, "helvetica", 9)) dfont = sansfont_;
      +    }
      +  }
      +	return dfont;
      +
      +} // Fl_Help_View::font_face()
      +
      +//
      +// Fl_Help_View::font_style() - Get a font style from a font list index.
      +//
      +
      +// Usage: the font style argument takes the values:
      +// medium as 0, bold as 1, italic as 2, plus as 3.
      +
      +int // O - font list index
      +Fl_Help_View::font_style(int fi, // I - font list index
      +                         unsigned char fs) // I - font style 0..3
      +{
      +  int ti = 0; // temp loop var
      +
      +  if (fs > 3 || fi >= (int)sizeof(fref_)) return 0; // avoid crash
      +  for (ti = 0; ti <= 3; ti ++) // find style
      +    if (fi == face_[fref_[fi]][ti]) break;
      +  ti |= fs; // combine bits
      +  return face_[fref_[fi]][ti];
      +
      +} // Fl_Help_View::font_style()
      +
      +//
      +// Fl_Help_View::format() - Format the help text.
      +//
      +
      +void Fl_Help_View::format()
      +{
      +  char *sp, // Pointer into buffer
      +    *tp, // temp char pointer
      +    *ap, // attribute pointer
      +    buf[1024], // Text buffer
      +    attr[1024], // Attribute buffer
      +    wattr[1024], // Width attribute buffer
      +    hattr[1024], // Height attribute buffer
      +    linkdest[1024], // Link destination
      +    tcss[1024], // temp css
      +    tchar[1024], // temp char buffer
      +    csstag[255], // css tag buffer
      +    tag[4]; // tag/element 4-char buf
      +  const char *ptr, // Pointer into block
      +    *attrptr, // Start of attributes ptr
      +    *tagptr; // Start of tag/element ptr
      +  int ti = 0, tj = 0, // Temp loop var
      +    done = 0, // Are we done yet?
      +    row = 0, // Current table row (block number)
      +    talign = 0, // Current alignment
      +    newalign = 0, // New alignment
      +    head = 0, // Head/body section flag
      +    needspace = 0, // Do we need whitespace?
      +    table_width = 0, // Width of table
      +    table_offset = 0, // Offset of table
      +    column = 0, // Current table column number
      +    line = 0, // Current line in block
      +    links = 0, // Links for current line
      +    trpop = 0, // tr popped flag
      +    pflag = 0, // p flag
      +    brflag = 0, // br flag
      +    liflag = 0, // li flag
      +    listnest = 0, // list nest
      +    tdline = 0, // td line
      +    colspan = 0, // COLSPAN attribute
      +    qch = 0, // Quote char
      +    dx = 0, dy = 0, // Boxtype position offsets
      +    dw = 0, dh = 0, // Boxtype sizes
      +    ss = 0, // Scrollbar size
      +    temph = 0, tempw = 0, // Temp scrollbar sizes
      +    tempx = 0, tempy = 0, // temp positions
      +    linew = 0, // current line width
      +    imgw = 0, // Image width
      +    imgh = 0, // Image height
      +    hwidth = 0, // horizontal window width
      +    ulnest = 0, // ul nest type
      +    ntables = 0, // number of nested tables
      +    fonty = 0;
      +  int columns[HV_64], // Column widths
      +    cells[HV_64], // Cells in the current row
      +    tcolumns[HV_64][HV_16], // nested table column widths
      +    tcells[HV_64][HV_16], // nested table cell blocks
      +    rowdata[3][HV_16], // row data - row,column,block
      +    tfonts[HV_16 + 1], // table fonts - d->nfonts
      +    ultype[HV_16]; // ul type array, 10 nesting levels should do
      +  unsigned char thsize, tfsize; // font sizes
      +  fl_margins margins; // Left margin stack
      +  Fl_Help_Block *block, // Current block
      +    *cell, // Current table cell
      +    b, // current block object
      +    *tempb = 0; // temp block
      +    //*cssb = 0; // current css block - not used
      +  Fl_Color tclr, rclr, // Table/row background color
      +    tbclr[2][HV_16]; // nested table/tr bgcolor
      +  Fl_Boxtype bt = (box()) ? box() : FL_DOWN_BOX; // Box to draw
      +  Fl_Shared_Image *img = 0; // Shared image - rem'd NULL
      +
      +  // zero arrays
      +  memset(columns, 0, sizeof(columns));
      +  memset(cells, 0, sizeof(cells));
      +  memset(rowdata, 0, sizeof(rowdata));
      +  memset(tcolumns, 0, sizeof(tcolumns));
      +  memset(tcells, 0, sizeof(tcells));
      +  memset(tfonts, 0, sizeof(tfonts));
      +  memset(ultype, 0, sizeof(ultype));
      +  memset(tbclr, 0, sizeof(tbclr));
      +
      +  // Reset document width
      +  ss = Fl::scrollbar_size();
      +  hsize_ = w() - ss - Fl::box_dw(bt);
      +  hwidth = hsize_; // used in add_block instead of hsize_
      +
      +//printf("\n FORMAT\n%s",value_);
      +
      +  done = 0;
      +  while (!done)
      +  {
      +  
      +    // Reset state variables
      +    done = 1;
      +    nblocks_ = 0;
      +    nlinks_ = 0;
      +    ntargets_ = 0;
      +    size_ = 0;
      +    bgcolor_ = color();
      +    textcolor_ = textcolor();
      +    linkcolor_ = fl_contrast(FL_BLUE, color());
      +    tclr = rclr = bgcolor_;
      +    for (ti = 0; ti < HV_16; ti ++)
      +      tbclr[0][ti] = tbclr[1][ti] = bgcolor_;
      +    strcpy(title_, "Untitled");
      +
      +    if (!value_) return;
      +
      +    // Setup for formatting
      +    initfont(b.font, b.fsize);
      +    line = 0;
      +    links = 0;
      +    column = 0;
      +    b.x = margins.clear();
      +    b.y = b.fsize + 2;
      +    b.w = 0;
      +    b.h = 0;
      +    b.border = 0;
      +    b.pre = 0;
      +    b.tag = 0;
      +    b.bgcolor = bgcolor_;
      +    block = add_block(b, value_, hwidth);
      +    row = 0;
      +    head = 0;
      +    talign = LEFT;
      +    newalign = LEFT;
      +    needspace = 0;
      +    linkdest[0] = '\0';
      +    table_offset = 0;
      +    trpop = 0;
      +    pflag = 1;
      +    brflag = 0;
      +    liflag = 0;
      +    listnest = 0;
      +    ulnest = 0;
      +    thsize = 0;
      +    tfsize = 0;
      +    ntables = -1;
      +    tdline = 0;
      +    linew = 0;
      +
      +    for (ptr = value_, sp = buf; *ptr; ) // Parse from value_
      +    {
      +      if ((*ptr == '<' || isspace((*ptr) & 255)) && sp > buf)
      +      {
      +        *sp = '\0'; // Nul-terminate
      +        b.w = (int)fl_width(buf); // Get width
      +
      +        if (!head && !b.pre) // Normal text
      +        {
      +          if (b.w > hsize_) { // Reformat
      +            hsize_ = b.w;
      +            done = 0; // rem'd break; in all reformat checks, not needed
      +          }
      +
      +          if (needspace && b.x > block->x)
      +            b.w += (int)fl_width(" ");
      +
      +          // no new line if word too long and no word before it
      +          if (!(b.x < 7 && b.w > block->w) && (b.x + b.w > block->w)) {
      +            block->end = ptr - strlen(buf); // end line on last word
      +            line = do_align(block, 0, b.x, newalign, links);
      +            b.x = block->x;
      +            block->h += b.h;
      +            b.y += b.h; //b.y = block->y + block->h;
      +            b.h = 0;
      +            line = 0;
      +            block = add_block(b, ptr - strlen(buf), (row) ? block->w : hwidth);
      +          }
      +
      +          if (linkdest[0])
      +            add_link(linkdest, b.x, b.y - b.fsize, b.w, b.fsize);
      +
      +          b.x += b.w;
      +          if (b.fsize + 2 > b.h) b.h = b.fsize + 2; // Set b.h
      +          needspace = 0;
      +        }
      +        else if (!head && b.pre) // Pre text
      +        {
      +          if (linkdest[0]) // Add a link as needed
      +            add_link(linkdest, b.x, b.y - b.h, b.w, b.h);
      +            
      +          b.x += b.w;
      +          linew += b.w;
      +          if (b.fsize + 2 > b.h) b.h = b.fsize + 2; // Set b.h
      +          
      +          while (isspace((*ptr) & 255)) // ' ' '\t'\n'\v'\f'\r' chars
      +          {
      +            if (*ptr == '\n') { // '\n' char
      +              if (b.x > hsize_) break;
      +              
      +              block->end = ptr;
      +              line = do_align(block, 0, b.x, newalign, links);
      +              b.x = block->x;
      +              block->h += b.h;
      +              b.y += b.h; //b.y = block->y + block->h;
      +              b.h = 0;
      +              line = 0;
      +              linew = 0;
      +              block = add_block(b, ptr, (row) ? block->w : hwidth);
      +              //b.h = b.fsize + 2; // Set b.h
      +            }
      +            else if (*ptr == '\t') {
      +              ti = linew / (int)fl_width(" "); // number of chars, monospace
      +              tempw = 8 - (ti & 7); // number of tabs 1..8
      +              b.x += tempw * (int)fl_width(" "); // pre tabs width fix
      +              linew += tempw * (int)fl_width(" ");
      +            }
      +            else {
      +              b.x += (int)fl_width(" ");
      +              linew += (int)fl_width(" ");
      +            }
      +
      +            if (b.fsize + 2 > b.h) b.h = b.fsize + 2; // Set b.h
      +            ptr ++;
      +          }
      +
      +          if (b.x > hsize_) { // Reformat
      +            hsize_ = b.x + 4;
      +            done = 0;
      +          }
      +
      +          needspace = 0;
      +        }
      +        else // Handle normal text or stuff in the  section
      +        {
      +          while (isspace((*ptr) & 255)) ptr ++;
      +        }
      +
      +//printf("b->line=%d b.x=%d b.w=%d b->x=%d b->w=%d b->y=%d b->h=%d b.y=%d b.h=%d buf=%s\n",
      +//  block->line, b.x, b.w, block->x, block->w, block->y, block->h, b.y, b.h, buf);
      +
      +        pflag = 0; // reset flags
      +        brflag = 0;
      +        sp = buf;
      +      }
      +
      +      if (*ptr == '<')
      +      {
      +        tagptr = ptr; // Start of tag
      +        ptr ++;
      +
      +        if (!strncmp(ptr, "!--", 3)) { // Found "!--"
      +          ptr += 3;
      +          if ((ptr = strstr(ptr, "-->"))) { // Skip comment - rem'd != 0
      +            ptr += 3;
      +            continue;
      +          }
      +          else
      +            break;
      +        }
      +
      +        while (*ptr && *ptr != '>' && !isspace((*ptr) & 255))
      +          if (sp < (buf + sizeof(buf) - 1))
      +            *(sp ++) = *(ptr ++); // added ()
      +          else
      +            ptr ++;
      +
      +        *sp = '\0'; // Nul-terminate
      +        sp = buf;
      +
      +//  puts(buf);
      +
      +        attrptr = ptr; // Start of attributes
      +        while (*ptr && *ptr != '>') ptr ++;
      +        if (*ptr == '>') ptr ++;
      +        
      +        b.tag = strlen(buf); // store strlen
      +        for (ti = 0; ti < b.tag; ti ++) // set css class tag
      +          csstag[ti] = buf[ti];
      +        csstag[ti] = '\0'; // nul-terminate
      +        if (get_attr(attrptr, "CLASS", tchar, sizeof(tchar))) {
      +          strlcat(csstag, ".", sizeof(csstag));
      +          strlcat(csstag, tchar, sizeof(csstag));
      +        }
      +        
      +        if (b.tag > 4) b.tag = 4; // limit
      +        for (ti = 0; ti < b.tag; ti ++) // set abbreviate tag, uppercase
      +          tag[ti] = toupper(buf[ti]);
      +        for (ti = b.tag; ti < 4; ti ++) // set chars after to nul
      +          tag[ti] = 0;
      +        if (buf[0] != '/' && b.tag > 3) tag[3] = 0; // eg. HTML=HTM
      +        b.tag = CMD(tag[0],tag[1],tag[2],tag[3]); // tag fourcc int
      +
      +//printf("buf=%s len=%d tag=%c%c%c%c, \n",
      +//  buf,strlen(buf),tag[0],tag[1],tag[2],tag[3]);
      +
      +        // End of command reached
      +        if (b.tag == CMD('A',0,0,0)) // 'A'
      +        {
      +          if (get_attr(attrptr, "NAME", attr, sizeof(attr)))
      +            add_target(attr, b.y - b.fsize - 2);
      +
      +          if (get_attr(attrptr, "HREF", attr, sizeof(attr)))
      +            strlcpy(linkdest, attr, sizeof(linkdest));
      +        }
      +        else if (b.tag == CMD('/','A',0,0)) // '/A'
      +        {
      +          linkdest[0] = '\0';
      +        }
      +        else if (b.tag == CMD('B',0,0,0) ||
      +                 b.tag == CMD('S','T','R',0)) // 'B' 'STRONG'
      +        {
      +          b.font = font_style(b.font, FL_BOLD);
      +          pushfont(b.font, b.fsize);
      +        }
      +        else if (b.tag == CMD('/','B',0,0) ||
      +                 b.tag == CMD('/','S','T','R')) // '/B' '/STRONG'
      +        {
      +          popfont(b.font, b.fsize);
      +        }
      +        else if (b.tag == CMD('B','L','O',0) ||
      +                 b.tag == CMD('D','L',0,0) ||
      +                 b.tag == CMD('U','L',0,0) ||
      +                 b.tag == CMD('O','L',0,0) ||
      +                 b.tag == CMD('D','D',0,0) ||
      +                 b.tag == CMD('D','T',0,0)) // 'BLOCKQUOTE' 'DL'OL'UL'
      +        {
      +// todo: dd and dt need their own section, similar to li
      +          block->end = tagptr;
      +          line = do_align(block, line, b.x, newalign, links);
      +          b.x = block->x;
      +          if (liflag) { b.x = margins.pop(); liflag = 0; } // pop li
      +          block->h += b.h;
      +          b.y = block->y + block->h;
      +          newalign = LEFT;
      +
      +          if (b.tag == CMD('U','L',0,0)) { // ul
      +            ulnest ++; // inc ul nest type
      +            if (ulnest < 10) {
      +              get_attr(attrptr, "TYPE", attr, sizeof(attr)); // bullet types
      +              if (!strncasecmp(attr, "disc", 4) ||
      +                  !strncasecmp(attr, "disk", 4))
      +                ultype[ulnest] = 1;
      +              else if (!strncasecmp(attr, "circle", 6))
      +                ultype[ulnest] = 2;
      +              else if (!strncasecmp(attr, "square", 6))
      +                ultype[ulnest] = 3;
      +            }
      +          }
      +
      +          if (b.tag == CMD('B','L','O',0) ||
      +              b.tag == CMD('D','L',0,0) ||
      +              b.tag == CMD('O','L',0,0) ||
      +              b.tag == CMD('U','L',0,0)) { // blockquote, dl, ol, ul
      +            b.x = margins.push(40); // changed 4 * b.fsize
      +            if (!pflag && !listnest) {
      +              b.y += fontsize_ + 2; block->h += fontsize_ + 2; pflag = 1;
      +            }
      +            listnest ++; // inc list nest
      +          }
      +
      +          block = add_block(b, tagptr, (row) ? block->w : hwidth);
      +          b.h = 0;
      +          needspace = 0;
      +          line = 0;
      +          newalign = get_align(attrptr, talign);
      +        }
      +        else if (b.tag == CMD('/','B','L','O') ||
      +                 b.tag == CMD('/','D','L',0) ||
      +                 b.tag == CMD('/','O','L',0) ||
      +                 b.tag == CMD('/','U','L',0)) // '/BLOCKQUOTE' '/DL'/OL'/UL'
      +        {
      +          line = do_align(block, line, b.x, newalign, links);
      +          block->end = ptr;
      +          b.x = block->x;
      +          if (liflag) { b.x = margins.pop(); liflag = 0; } // pop li
      +          block->h += b.h;
      +          b.y += b.h;
      +
      +          if (b.tag == CMD('/','U','L',0)) { // /ul
      +            if (ulnest < 9) ultype[ulnest] = 0; // reset ul type
      +            if (ulnest > 0) ulnest --; // dec ul nest type
      +          }
      +
      +          if (listnest > 0) listnest --; // dec list nest
      +          if (!pflag && !listnest) {
      +            b.y += fontsize_ + 2; block->h += fontsize_ + 2; pflag = 1;
      +          }
      +          b.x = margins.pop();
      +
      +          while (isspace((*ptr) & 255)) ptr ++;
      +          block = add_block(b, ptr, (row) ? block->w : hwidth);
      +          b.h = 0;
      +          needspace = 0;
      +          line = 0;
      +          newalign = talign;
      +        }
      +        else if (b.tag == CMD('B','O','D',0)) // 'BODY'
      +        {
      +          if (get_attr(attrptr, "BGCOLOR", attr, sizeof(attr)))
      +            b.bgcolor = bgcolor_ = get_color(attr, color());
      +
      +          if (get_attr(attrptr, "TEXT", attr, sizeof(attr)))
      +            textcolor_ = get_color(attr, textcolor());
      +
      +          if (get_attr(attrptr, "LINK", attr, sizeof(attr)))
      +            linkcolor_ = get_color(attr, fl_contrast(FL_BLUE, color()));
      +            
      +          parse_css(b, csstag, tchar);
      +          if (b.fsize < fontsize_) b.fsize = fontsize_; // force min size
      +          pushfont(b.font, b.fsize);
      +          serifont_ = b.font; // body overrides default font but not size
      +        }
      +        else if (b.tag == CMD('B','R',0,0)) // 'BR'
      +        {
      +          block->end = tagptr;
      +          line = do_align(block, 0, b.x, newalign, links);
      +          b.x = block->x;
      +          if (liflag) { b.x = margins.pop(); liflag = 0; } // pop li
      +          if (brflag) b.h = b.fsize + 2; // set b.h
      +          block->h += b.h;
      +          b.y = block->y + block->h; //b.y += b.h;
      +          brflag = 1;
      +
      +          block = add_block(b, tagptr, (row) ? block->w : hwidth);
      +          b.h = 0;
      +          needspace = 0;
      +          line = 0;
      +        }
      +        else if (b.tag == CMD('C','E','N',0)) // 'CENTER'
      +        {
      +          block->end = tagptr;
      +          line = do_align(block, line, b.x, newalign, links);
      +          b.x = block->x;
      +          if (liflag) { b.x = margins.pop(); liflag = 0; } // pop li
      +          block->h += b.h;
      +          b.y = block->y + block->h;
      +          newalign = CENTER;
      +
      +          block = add_block(b, tagptr, (row) ? block->w : hwidth);
      +          b.h = 0;
      +          needspace = 0;
      +          line = 0;
      +          newalign = talign = CENTER;
      +        }
      +        else if (b.tag == CMD('/','C','E','N')) // '/CENTER'
      +        {
      +          line = do_align(block, line, b.x, newalign, links);
      +          block->end = ptr;
      +          b.x = block->x;
      +          if (liflag) { b.x = margins.pop(); liflag = 0; } // pop li
      +          block->h += b.h;
      +          b.y += b.h;
      +          talign = LEFT;
      +
      +          while (isspace((*ptr) & 255)) ptr ++;
      +          block = add_block(b, ptr, (row) ? block->w : hwidth);
      +          b.h = 0;
      +          needspace = 0;
      +          line = 0;
      +          newalign = talign;
      +        }
      +        else if (b.tag == CMD('C','O','D',0) ||
      +                 b.tag == CMD('T','T',0,0)) // 'CODE' 'TT'
      +        {
      +          b.font = monofont_;
      +          pushfont(b.font, b.fsize);
      +        }
      +        else if (b.tag == CMD('/','C','O','D') ||
      +                 b.tag == CMD('/','T','T',0)) // '/CODE' '/TT'
      +        {
      +          popfont(b.font, b.fsize);
      +        }
      +        else if (b.tag == CMD('D','I','V',0)) // 'DIV'
      +        {
      +          if (get_attr(attrptr, "ID", attr, sizeof(attr)))
      +            add_target(attr, b.y - b.fsize - 2);
      +
      +          block->end = tagptr;
      +          line = do_align(block, line, b.x, newalign, links);
      +          b.x = block->x;
      +          if (liflag) { b.x = margins.pop(); liflag = 0; } // pop li
      +          block->h += b.h;
      +          b.y = block->y + block->h;
      +          newalign = LEFT;
      +
      +          if (!pflag) {
      +            b.y += fontsize_ + 2; block->h += fontsize_ + 2; pflag = 1;
      +          }
      +
      +          block = add_block(b, tagptr, (row) ? block->w : hwidth);
      +          b.h = 0;
      +          needspace = 0;
      +          line = 0;
      +          newalign = get_align(attrptr, talign);
      +        }
      +        else if (b.tag == CMD('/','D','I','V')) // '/DIV'
      +        {
      +          line = do_align(block, line, b.x, newalign, links);
      +          block->end = ptr;
      +          b.x = block->x;
      +          if (liflag) { b.x = margins.pop(); liflag = 0; } // pop li
      +          block->h += b.h;
      +          b.y += b.h;
      +          talign = LEFT;
      +
      +          while (isspace((*ptr) & 255)) ptr ++;
      +          block = add_block(b, ptr, (row) ? block->w : hwidth);
      +          b.h = 0;
      +          needspace = 0;
      +          line = 0;
      +          newalign = talign;
      +        }
      +        else if (b.tag == CMD('F','O','N',0)) // 'FONT'
      +        {
      +          if (get_attr(attrptr, "FACE", attr, sizeof(attr)))
      +            b.font = font_face(attr);
      +
      +          tfsize = b.fsize; // store b.fsize
      +          if (get_attr(attrptr, "SIZE", attr, sizeof(attr))) {
      +            if (isdigit(attr[0])) // Absolute size
      +              b.fsize = (int)(fontsize_ * pow(1.2, atoi(attr) - 3.0));
      +            else // Relative size
      +              b.fsize = (int)(b.fsize * pow(1.2, atoi(attr)));
      +          }
      +
      +          pushfont(b.font, b.fsize);
      +          //if (fonty != b.y && !block->maxh) {
      +            //block->liney = abs(b.fsize - tfsize);
      +            //b.h = b.fsize + 2; // set b.h
      +          //}
      +          fonty = b.y; // set font y
      +        }
      +        else if (b.tag == CMD('/','F','O','N')) // '/FONT'
      +        {
      +          tfsize = b.fsize; // store b.fsize
      +          popfont(b.font, b.fsize);
      +          //if (fonty != b.y && !block->maxh) {
      +            //block->liney = abs(b.fsize - tfsize);
      +            //b.h = b.fsize + 2; // set b.h
      +          //}
      +          fonty = b.y; // set font y
      +        }
      +        else if (tag[0] == 'H' && isdigit(tag[1])) // 'H1'
      +        {
      +          if (tag[1] < '7') { // ignore if > 6
      +            block->end = tagptr;
      +            line = do_align(block, line, b.x, newalign, links);
      +            b.x = block->x;
      +            if (liflag) { b.x = margins.pop(); liflag = 0; } // pop li
      +            block->h += b.h;
      +            b.y = block->y + block->h;
      +            newalign = LEFT;
      +
      +            thsize = b.fsize; // store b.fsize
      +            b.font = font_style(b.font, FL_BOLD);
      +            switch (tag[1]) { // header sizes
      +              case '1' : b.fsize = 24; break;
      +              case '2' : b.fsize = 18; break;
      +              case '3' : b.fsize = 16; break;
      +              case '4' : b.fsize = 14; break;
      +              case '5' : b.fsize = 12; break;
      +              case '6' : b.fsize = 10; break;
      +            }
      +            pushfont(b.font, b.fsize);
      +
      +            if (!pflag) {
      +              b.y += fontsize_ + 2; block->h += fontsize_ + 2; pflag = 1;
      +            }
      +            b.y += b.fsize - thsize + (thsize / 4); // add offset
      +            block->h += b.fsize - thsize + (thsize / 4);
      +
      +            block = add_block(b, tagptr, (row) ? block->w : hwidth);
      +            b.h = 0;
      +            needspace = 0;
      +            line = 0;
      +            newalign = get_align(attrptr, talign);
      +          }
      +        }
      +        else if (b.tag == CMD('/','H',tag[2],0) && isdigit(tag[2])) // '/H1'
      +        {
      +          if (tag[2] < '7') { // ignore if > 6
      +            line = do_align(block, line, b.x, newalign, links);
      +            block->end = ptr;
      +            b.x = block->x;
      +            if (liflag) { b.x = margins.pop(); liflag = 0; } // pop li
      +            block->h += b.h;
      +            b.y += b.h;
      +
      +            if (!pflag) {
      +              b.y += fontsize_ + 2; block->h += fontsize_ + 2; pflag = 1;
      +            }
      +            b.y -= b.fsize - thsize;// + (thsize / 4); // sub offset
      +            block->h -= b.fsize - thsize;// + (thsize / 4);
      +
      +            popfont(b.font, b.fsize);
      +
      +            while (isspace((*ptr) & 255)) ptr ++;
      +            block = add_block(b, ptr, (row) ? block->w : hwidth);
      +            b.h = 0;
      +            needspace = 0;
      +            line = 0;
      +            newalign = talign;
      +          }
      +        }
      +        else if (b.tag == CMD('H','E','A',0)) // 'HEAD'
      +        {
      +          head = 1;
      +        }
      +        else if (b.tag == CMD('/','H','E','A')) // '/HEAD'
      +        {
      +          head = 0;
      +        }
      +        else if (b.tag == CMD('H','R',0,0)) // 'HR'
      +        {
      +          block->end = tagptr;
      +          line = do_align(block, line, b.x, newalign, links);
      +          b.x = block->x;
      +          if (liflag) { b.x = margins.pop(); liflag = 0; } // pop li
      +          block->h += b.h;
      +          b.y = block->y + block->h;
      +          newalign = LEFT;
      +
      +          if (!pflag) {
      +            b.y += fontsize_ + 2; block->h += fontsize_ + 2; pflag = 1;
      +          }
      +
      +          block = add_block(b, tagptr, (row) ? block->w : hwidth);
      +          //block->y -= (b.fsize / 2); // hr line offset
      +          //b.y += fontsize_ + 2; // end paragraph
      +          //block->h += fontsize_ + 2;
      +          //pflag = 1;
      +          b.h = b.fsize + 2; // set b.h - rem: ??
      +          b.h = 0;
      +          needspace = 0;
      +          line = 0;
      +          newalign = get_align(attrptr, talign);
      +        }
      +        else if (b.tag == CMD('H','T','M',0)) // 'HTML'
      +        {
      +        }
      +        else if (b.tag == CMD('I',0,0,0) ||
      +                 b.tag == CMD('E','M',0,0)) // 'I' 'EM'
      +        {
      +          b.font = font_style(b.font, FL_ITALIC);
      +          pushfont(b.font, b.fsize);
      +        }
      +        else if (b.tag == CMD('/','I',0,0) ||
      +                 b.tag == CMD('/','E','M',0)) // '/I' '/EM'
      +        {
      +          popfont(b.font, b.fsize);
      +        }
      +        else if (b.tag == CMD('I','M','G',0)) // 'IMG'
      +        {
      +          imgw = imgh = 0; // reset
      +          if (get_attr(attrptr, "WIDTH", wattr, sizeof(wattr)))
      +            imgw = get_length(wattr);
      +          if (get_attr(attrptr, "HEIGHT", hattr, sizeof(hattr)))
      +            imgh = get_length(hattr);
      +
      +          img = 0; // rem'd NULL
      +          if (get_attr(attrptr, "SRC", attr, sizeof(attr))) {
      +            img = get_image(attr, imgw, imgh);
      +            imgw = img->w();
      +            imgh = img->h();
      +          }
      +
      +          b.w = imgw;
      +          if (b.w > hsize_) { // Reformat
      +            hsize_ = b.w;
      +            done = 0;
      +          }
      +
      +          if (needspace && b.x > block->x)
      +            b.w += (int)fl_width(" ");
      +
      +          if ((b.x + b.w) > block->w) {
      +            block->end = tagptr;
      +            line = do_align(block, line, b.x, newalign, links);
      +            b.x = block->x;
      +            block->h += b.h;
      +            b.y = block->y + block->h; //b.y += b.h;
      +            line = 0;
      +
      +            block = add_block(b, tagptr, (row) ? block->w : hwidth);
      +            b.h = 0;
      +            needspace = 0;
      +          }
      +
      +          if (linkdest[0])
      +            add_link(linkdest, b.x, b.y - imgh, b.w, imgh);
      +
      +          b.x += b.w;
      +          if ((imgh + 2) > b.h) b.h = imgh + 2; // Set img b.h
      +          needspace = 0;
      +
      +          if (imgh > block->maxh)
      +            block->maxh = imgh; // max image height
      +          block->imgy = b.y; // y position of image
      +          pflag = 0; // reset p flag
      +          brflag = 0;
      +        }
      +        else if (b.tag == CMD('K','B','D',0)) // 'KBD'
      +        {
      +          b.font = font_style(monofont_, FL_BOLD);
      +          pushfont(b.font, b.fsize);
      +        }
      +        else if (b.tag == CMD('/','K','B','D')) // '/KBD'
      +        {
      +          popfont(b.font, b.fsize);
      +        }
      +        else if (b.tag == CMD('L','I',0,0)) // 'LI'
      +        {
      +          block->end = tagptr;
      +          line = do_align(block, line, b.x, newalign, links);
      +          b.x = block->x;
      +          if (!liflag && !listnest) { // push li, if not nested
      +            b.x = margins.push(b.fsize);
      +            liflag = 1;
      +          }
      +          block->h += b.h;
      +          b.y = block->y + block->h;
      +          newalign = LEFT;
      +          block = add_block(b, tagptr, (row) ? block->w : hwidth);
      +
      +          // li > ul > ul nest
      +          if (ulnest > 9) // square if out of bounds
      +            block->type = 3;
      +          else if (ultype[ulnest]) // ul type
      +            block->type = ultype[ulnest];
      +          else if (ulnest > 1) // ul nest type
      +            block->type = ulnest;
      +          else // none or ul nest type disc/disk
      +            block->type = 1;
      +
      +          b.h = 0;
      +          needspace = 0;
      +          line = 0;
      +          newalign = get_align(attrptr, talign);
      +        }
      +        else if (b.tag == CMD('/','L','I',0)) // '/LI'
      +        {
      +          line = do_align(block, line, b.x, newalign, links);
      +          block->end = ptr;
      +          b.x = block->x;
      +          if (liflag) { b.x = margins.pop(); liflag = 0; } // pop li
      +          block->h += b.h;
      +          b.y += b.h;
      +
      +          while (isspace((*ptr) & 255)) ptr ++;
      +          block = add_block(b, ptr, (row) ? block->w : hwidth);
      +          b.h = 0;
      +          needspace = 0;
      +          line = 0;
      +          newalign = talign;
      +        }
      +        else if (b.tag == CMD('L','I','N',0)) // 'LINK'
      +        {
      +          if (get_attr(attrptr, "HREF", tchar, sizeof(tchar)))
      +            strlcpy(tcss, tchar, sizeof(tcss));
      +            
      +          for (ti = 0; tcss[ti] != '\0'; ti ++) // replace '\' chars
      +            if (tcss[ti] == '\\') tcss[ti] = '/';
      +            
      +          if (tcss[0] == '/' || tcss[1] == ':') // absolute
      +            strlcpy(tchar, tcss, sizeof(tchar));
      +          else { // relative
      +            if (d->ispath) { // path is used
      +              strlcpy(tchar, d->path, sizeof(tchar));
      +              if ((tp = strrchr(tchar, '/'))) // replace filename
      +                strlcpy(tp + 1, tcss, sizeof(tchar)-(tp + 1 - tchar));
      +            }
      +            else { // use directory
      +              strlcpy(tchar, directory_, sizeof(tchar));
      +              strlcat(tchar, tcss, sizeof(tchar));
      +            }
      +          }
      +          
      +          while ((tp = strstr(tchar, "/.."))) { // remove ../ from path
      +            for (ap = tp - 1; ap > tchar; ap --)
      +              if (*ap == '/') break; // seek back to last dir
      +            if (ap == tchar) break; // nothing to remove
      +            *ap = '\0'; // nul-terminate
      +            strlcat(tchar, tp + 3, sizeof(tchar)); // add rest of path
      +          }
      +          while ((tp = strstr(tchar, "/./"))) { // remove ./ from path
      +            *tp = '\0';
      +            strlcat(tchar, tp + 2, sizeof(tchar));
      +          }
      +                    
      +          if ((tp = strrchr(tcss, '.'))) { // check valid ext
      +            if (strstr(tp, ".css")) load_css(tchar);
      +          }
      +          tcss[0] = '\0'; // reset
      +        }
      +        else if (b.tag == CMD('N','O','S',0)) // 'NOSCRIPT'
      +        { // we don't support scripting so we won't skip this
      +        }
      +        else if (b.tag == CMD('P',0,0,0)) // 'P'
      +        { // && !b.pre fixme?
      +          block->end = tagptr;
      +          line = do_align(block, line, b.x, newalign, links);
      +          b.x = block->x;
      +          if (liflag) { b.x = margins.pop(); liflag = 0; } // pop li
      +          block->h += b.h;
      +          b.y = block->y + block->h;
      +          newalign = LEFT;
      +
      +          if (!pflag) {
      +            b.y += fontsize_ + 2; block->h += fontsize_ + 2; pflag = 1;
      +          }
      +
      +          block = add_block(b, tagptr, (row) ? block->w : hwidth);
      +          b.h = 0;
      +          needspace = 0;
      +          line = 0;
      +          newalign = get_align(attrptr, talign);
      +        }
      +        else if (b.tag == CMD('/','P',0,0)) // '/P'
      +        {
      +          line = do_align(block, line, b.x, newalign, links);
      +          block->end = ptr;
      +          b.x = block->x;
      +          if (liflag) { b.x = margins.pop(); liflag = 0; } // pop li
      +          block->h += b.h;
      +          b.y = block->y + block->h;
      +
      +          if (!pflag) {
      +            b.y += fontsize_ + 2; block->h += fontsize_ + 2; pflag = 1;
      +          }
      +
      +          while (isspace((*ptr) & 255)) ptr ++;
      +          block = add_block(b, ptr, (row) ? block->w : hwidth);
      +          b.h = 0;
      +          needspace = 0;
      +          line = 0;
      +          newalign = talign;
      +        }
      +        else if (b.tag == CMD('P','R','E',0)) // 'PRE'
      +        {
      +          block->end = tagptr;
      +          line = do_align(block, line, b.x, newalign, links);
      +          b.x = block->x;
      +          if (liflag) { b.x = margins.pop(); liflag = 0; } // pop li
      +          block->h += b.h;
      +          b.y = block->y + block->h;
      +          newalign = LEFT;
      +
      +          linew = 0;
      +          b.pre = 1;
      +          b.font = monofont_;
      +          b.fsize = fontsize_;
      +          parse_css(b, csstag, tchar);
      +          pushfont(b.font, b.fsize);
      +
      +          if (!pflag) {
      +            b.y += fontsize_ + 2; block->h += fontsize_ + 2; pflag = 1;
      +          }
      +
      +          block = add_block(b, tagptr, (row) ? block->w : hwidth);
      +          b.h = 0;
      +          needspace = 0;
      +          line = 0;
      +          newalign = get_align(attrptr, talign);
      +        }
      +        else if (b.tag == CMD('/','P','R','E')) // '/PRE'
      +        {
      +          line = do_align(block, line, b.x, newalign, links);
      +          block->end = ptr;
      +          b.x = block->x;
      +          if (liflag) { b.x = margins.pop(); liflag = 0; } // pop li
      +          block->h += b.h;
      +          b.y += b.h;
      +                    
      +          for (ti = nblocks_ - 1, tj = 0; ti > 0; ti --) { // find start block index
      +            tempb = blocks_ + ti;
      +            if (tempb->tag == CMD('P','R','E',0)) tj = 1; // pre line
      +            if (tj && tempb->tag != CMD('P','R','E',0)) {
      +              tempb = blocks_ + ti + 1; // + 1 gets first pre
      +              break;
      +            }
      +          }
      +          tempb->h = block->y - tempb->y; // recalculate h
      +
      +          if (!pflag) {
      +            b.y += fontsize_ + 2; block->h += fontsize_ + 2; pflag = 1; }
      +
      +          b.pre = 0;
      +          popfont(b.font, b.fsize);
      +
      +          while (isspace((*ptr) & 255)) ptr ++;
      +          block = add_block(b, ptr, (row) ? block->w : hwidth);
      +          b.h = 0;
      +          needspace = 0;
      +          line = 0;
      +          newalign = talign;
      +        }
      +        else if (b.tag == CMD('S','C','R',0)) // 'SCRIPT'
      +        {
      +          while (ptr) { // skip scripting
      +            ptr = strstr(ptr, "", 9)) break;
      +          }
      +
      +          if (ptr) { // found 
      +            ptr += 9;
      +            continue;
      +          }
      +          else // not found
      +            break;
      +        }
      +        else if (b.tag == CMD('T','A','B',0)) // 'TABLE'
      +        {
      +          if (ntables >= 0) { // store row data
      +            rowdata[0][ntables] = row; // row
      +            rowdata[1][ntables] = column; // column
      +            rowdata[2][ntables] = block - blocks_; // block number
      +            tbclr[0][ntables] = tclr; // table bgcolor
      +            tbclr[1][ntables] = rclr; // tr bgcolor
      +            for (ti = 0; ti < HV_64; ti ++) {
      +              tcolumns[ti][ntables] = columns[ti]; // cell columns
      +              tcells[ti][ntables] = cells[ti]; // cell blocks
      +              if (columns[ti] == 0) break;
      +            }
      +          }
      +          if (ntables < HV_16) ntables ++; // max limit
      +          tfonts[ntables] = d->nfonts; // number of fonts
      +
      +          block->end = tagptr;
      +          line = do_align(block, line, b.x, newalign, links);
      +          b.x = block->x;
      +          block->h += b.h + 8; // add tr gap offset, wrong line gaps
      +          b.y = block->y + block->h;
      +          newalign = LEFT;
      +
      +          b.border = 0; // Reset
      +          if (get_attr(attrptr, "BORDER", attr, sizeof(attr)))
      +            b.border = atoi(attr);
      +
      +          get_attr(attrptr, "BGCOLOR", attr, sizeof(attr));
      +          tclr = rclr = get_color(attr, bgcolor_);
      +
      +          memset(columns, 0, sizeof(columns)); // zero for new table
      +          format_table(table_width, columns, tagptr, b.x, 0);
      +
      +          if ((b.x + table_width) > hsize_) { // Reformat
      +          
      +//printf("\nb.x=%d, table_width=%d, hsize_=%d\n\n",
      +//  b.x, table_width, hsize_);
      +
      +            hsize_ = b.x + table_width;
      +            for (ti = 0; ti < HV_64; ti ++)
      +              if (columns[ti] == 0) break; // num columns
      +            hsize_ += 6 * ti; // add internal borders
      +            done = 0;
      +          }
      +
      +          switch (get_align(attrptr, talign)) {
      +            default :
      +              table_offset = 0; break;
      +            case CENTER :
      +              table_offset = ((hsize_ - table_width) / 2) - fontsize_; break;
      +            case RIGHT :
      +              table_offset = hsize_ - table_width - fontsize_; break;
      +          }
      +
      +          block = add_block(b, tagptr, (row) ? block->w : hwidth);
      +          column = 0;
      +          b.h = 0;
      +          needspace = 0;
      +          line = 0;
      +          newalign = get_align(attrptr, talign);
      +        }
      +        else if (b.tag == CMD('/','T','A','B')) // '/TABLE'
      +        {
      +          if (row) { // no /tr
      +            line = do_align(block, line, b.x, newalign, links);
      +            if (tdline) { // td was popped
      +              block->line = tdline; tdline = 0; } // last line in td
      +            block->end = ptr;
      +            block->h += b.h;
      +            talign = LEFT;
      +            if (b.h == 0) b.h = b.fsize + 2; // empty td on end of row
      +            
      +            b.x = blocks_[row].x;
      +            b.y = blocks_[row].y + blocks_[row].h;
      +            
      +            for (cell = blocks_ + row + 1; cell <= block; cell ++)
      +              if (cell->y + cell->h > b.y) b.y = cell->y + cell->h;
      +              
      +            block = blocks_ + row; // current row block ptr
      +            block->h = b.y - block->y + 2;
      +            
      +            for (ti = 0; ti < column; ti ++)
      +              if (cells[ti]) { // cell block exists
      +                cell = blocks_ + cells[ti]; // get cell block ptr
      +                cell->h = block->h;
      +            }
      +            
      +            b.y = block->y + block->h - 4; // tr gap offset between rows
      +            block = add_block(b, ptr, hwidth);
      +            needspace = 0;
      +            row = 0; // reset row block number
      +            line = 0;
      +          }
      +          
      +          line = do_align(block, line, b.x, newalign, links);
      +          if (tdline) { block->line = tdline; tdline = 0; } // td popped
      +          block->end = ptr;
      +          b.x = block->x;
      +          b.h = 0; // reset b.h
      +          block->h += b.h; // may be needed if no /tr
      +          b.y += b.h + 8; // add tr gap offset, wrong line gaps
      +
      +          if (!trpop) { b.x = margins.pop(); row = 0; } // pop tr indent
      +          trpop = 0; // reset tr popped
      +          b.x = margins.current();
      +
      +          while (isspace((*ptr) & 255)) ptr ++;
      +          block = add_block(b, ptr, (row) ? block->w : hwidth);
      +          b.h = 0;
      +          needspace = 0;
      +          line = 0;
      +          newalign = talign;
      +
      +          d->nfonts = tfonts[ntables] + 1; // number of fonts + 1 for pop
      +          popfont(b.font, b.fsize); // tables not popping last font fix
      +
      +          if (ntables >= 0) ntables --; // min limit
      +          if (ntables >= 0) { // restore row data
      +            row = rowdata[0][ntables]; // row
      +            column = rowdata[1][ntables]; // column
      +            cell = blocks_ + rowdata[2][ntables] + 1; // table block
      +            b.x = block->x = cell->x; // nested table popping cell margin fix
      +            block->w = cell->w;
      +            tclr = tbclr[0][ntables]; // table bgcolor
      +            rclr = tbclr[1][ntables]; // tr bgcolor
      +            
      +            for (ti = 0; ti < HV_64; ti ++) {
      +              columns[ti] = tcolumns[ti][ntables]; // cell columns
      +              // nested table overwriting cell heights fix
      +              cells[ti] = tcells[ti][ntables]; // cell blocks
      +              if (tcolumns[ti][ntables] == 0) break;
      +            }
      +            
      +            // nested table drawn below row height fix
      +            cell->y -= 4; // table y offset
      +            tempy = cell->y; // table block y
      +            for (cell = cell; cell <= block; cell ++) // find tr, td, th
      +              if (cell->tag == CMD('T','R',0,0) ||
      +                  cell->tag == CMD('T','D',0,0) ||
      +                  cell->tag == CMD('T','H',0,0)) break;
      +            tempy = cell->y - tempy; // get row height
      +            for (cell = cell; cell <= block; cell ++)
      +              cell->y -= tempy; // move table up
      +            block->h -= 2; // /table h offset
      +          }
      +
      +//printf("/table ntables=%d tempx=%d b.x=%d b->x=%d\n",
      +//  ntables,tempx,b.x,block->x);
      +        }
      +        else if (b.tag == CMD('T','D',0,0) ||
      +                 b.tag == CMD('T','H',0,0)) // 'TD' 'TH'
      +        {
      +          if (!row) { // no tr
      +            block->end = tagptr;
      +            line = do_align(block, line, b.x, newalign, links);
      +            b.x = block->x;
      +            block->h += b.h;
      +            
      +            memset(cells, 0, sizeof(cells)); // zero for new row
      +            b.y = block->y + block->h - 4; // tr gap offset between rows
      +            block = add_block(b, tagptr, hwidth);
      +            row = block - blocks_; // next row block number
      +            column = 0;
      +            b.h = 0;
      +            needspace = 0;
      +            line = 0;
      +            trpop = 0; // reset tr popped
      +          }
      +          
      +          if (row) {
      +            line = do_align(block, line, b.x, newalign, links);
      +            if (tdline) { block->line = tdline; tdline = 0; } // td popped
      +            block->end = tagptr;
      +            block->h += b.h;
      +            b.y = blocks_[row].y;
      +            pflag = 1;
      +
      +            b.x = blocks_[row].x;
      +            if (liflag) { b.x = margins.pop(); liflag = 0; } // pop li
      +            b.x += 3 + table_offset; // rem'd + b.fsize
      +
      +            for (ti = 0; ti < column; ti ++)
      +              b.x += columns[ti] + 6;
      +            margins.push(b.x - margins.current());
      +
      +//printf("td ntables=%d tempx=%d b.x=%d b->x=%d\n",
      +//  ntables,tempx,b.x,block->x);
      +
      +            colspan = 1; // Reset
      +            if (get_attr(attrptr, "COLSPAN", attr, sizeof(attr)))
      +              colspan = atoi(attr);
      +
      +            for (ti = 0, b.w = -6; ti < colspan; ti ++)
      +              b.w += columns[column + ti] + 6;
      +
      +            if (block->end == block->start && nblocks_ > 1) {
      +              nblocks_ --;
      +              block --;
      +            }
      +
      +            if (ntables >= 0)
      +              d->nfonts = tfonts[ntables]; // pop number of fonts
      +
      +            b.font = serifont_;
      +            b.fsize = fontsize_;
      +            parse_css(b, csstag, tchar);
      +            if (b.tag == CMD('T','H',0,0)) // th
      +              b.font = font_style(b.font, FL_BOLD);
      +            pushfont(b.font, b.fsize);
      +            
      +            block = add_block(b, tagptr, b.x + b.w);
      +            b.h = 0;
      +            needspace = 0;
      +            line = 0;
      +            newalign = get_align(attrptr, (tag[1] == 'H') ? CENTER : LEFT);
      +            talign = newalign;
      +            cells[column] = block - blocks_; // set cell block number
      +            column += colspan;
      +            
      +            if (get_attr(attrptr, "BGCOLOR", attr, sizeof(attr)))
      +              block->bgcolor = get_color(attr, rclr);
      +          }
      +        }
      +        else if (b.tag == CMD('/','T','D',0) ||
      +                 b.tag == CMD('/','T','H',0)) // '/TD' '/TH'
      +        {
      +          if (row) {
      +            line = do_align(block, 0, b.x, newalign, links);
      +            talign = LEFT;
      +            //popfont(b.font, b.fsize);
      +            tdline = block->line; // store td line
      +            b.x = margins.pop();
      +            pflag = 0; // reset p flag?
      +
      +//printf("/td ntables=%d tempx=%d b.x=%d b->x=%d\n",
      +//  ntables,tempx,b.x,block->x);
      +          }
      +        }
      +        else if (b.tag == CMD('T','I','T',0)) // 'TITLE'
      +        {
      +          // Copy the title in the document
      +          tp = title_ + sizeof(title_) - 1;
      +          for (sp = title_; *ptr != '<' && *ptr && sp < tp; )
      +            *(sp ++) = *(ptr ++); // added ()
      +          *sp = '\0'; // Nul-terminate
      +          sp = buf;
      +        }
      +        else if (b.tag == CMD('T','R',0,0)) // 'TR'
      +        {
      +          for (ti = nblocks_ - 1; ti > 0; ti --) { // find last block index
      +            tempb = blocks_ + ti;
      +            if (tempb->tag == CMD('T','A','B',0) || tempb->tag == CMD('/','T','A','B') ||
      +                tempb->tag == CMD('T','D',0,0) || tempb->tag == CMD('T','H',0,0) ||
      +                tempb->tag == CMD('T','R',0,0) || tempb->tag == CMD('/','T','R',0))
      +              break; // found table/tr/td tag
      +          }
      +          
      +          tempx = 0; // no /tr flag
      +          if (row && tempb->tag != CMD('T','A','B',0)) { // skip first tr after table
      +            line = do_align(block, line, b.x, newalign, links);
      +            if (tdline) { // td was popped
      +              block->line = tdline; tdline = 0; } // last line in td
      +            block->end = ptr;
      +            block->h += b.h;
      +            talign = LEFT;
      +            if (b.h == 0) b.h = b.fsize + 2; // empty td on end of row
      +            
      +            tempx = b.x;
      +            b.x = blocks_[row].x;
      +            b.y = blocks_[row].y + blocks_[row].h;
      +            
      +            for (cell = blocks_ + row + 1; cell <= block; cell ++)
      +              if (cell->y + cell->h > b.y) b.y = cell->y + cell->h;
      +              
      +            block = blocks_ + row; // current row block ptr
      +            block->h = b.y - block->y + 2;
      +            
      +            for (ti = 0; ti < column; ti ++)
      +              if (cells[ti]) { // cell block exists
      +                cell = blocks_ + cells[ti]; // get cell block ptr
      +                cell->h = block->h;
      +            }
      +            
      +            if (tempx) block->x = tempx;
      +            b.y = block->y + block->h - 4; // tr gap offset between rows
      +            block = add_block(b, ptr, hwidth);
      +            needspace = 0;
      +            row = 0; // reset row block number
      +            line = 0;
      +          }
      +          
      +          block->end = tagptr;
      +          line = do_align(block, line, b.x, newalign, links);
      +          b.x = block->x;
      +          block->h += b.h;
      +
      +          if (row) {
      +            b.y = blocks_[row].y + blocks_[row].h;
      +
      +            for (cell = blocks_ + row + 1; cell <= block; cell ++)
      +              if (cell->y + cell->h > b.y) b.y = cell->y + cell->h;
      +
      +            block = blocks_ + row; // current row block ptr
      +            block->h = b.y - block->y + 2;
      +
      +            for (ti = 0; ti < column; ti ++)
      +              if (cells[ti]) { // cell block exists
      +                cell = blocks_ + cells[ti]; // get cell block ptr
      +                cell->h = block->h;
      +              }
      +          }
      +
      +          memset(cells, 0, sizeof(cells)); // zero for new row
      +          b.y = block->y + block->h - 4; // tr gap offset between rows
      +          block = add_block(b, tagptr, hwidth);
      +          row = block - blocks_; // next row block number
      +          column = 0;
      +          b.h = 0;
      +          needspace = 0;
      +          line = 0;
      +          trpop = 0; // reset tr popped
      +          get_attr(attrptr, "BGCOLOR", attr, sizeof(attr));
      +          rclr = get_color(attr, tclr);
      +        }
      +        else if (b.tag == CMD('/','T','R',0)) // '/TR'
      +        {
      +          if (row) { // tr
      +            line = do_align(block, line, b.x, newalign, links);
      +            if (tdline) { // td was popped
      +              block->line = tdline; tdline = 0; } // last line in td
      +            block->end = ptr;
      +            block->h += b.h;
      +            talign = LEFT;
      +            if (b.h == 0) b.h = b.fsize + 2; // empty td on end of row
      +            
      +            b.x = blocks_[row].x;
      +            b.y = blocks_[row].y + blocks_[row].h;
      +            
      +            for (cell = blocks_ + row + 1; cell <= block; cell ++)
      +              if (cell->y + cell->h > b.y) b.y = cell->y + cell->h;
      +              
      +            block = blocks_ + row; // current row block ptr
      +            block->h = b.y - block->y + 2;
      +            
      +            for (ti = 0; ti < column; ti ++)
      +              if (cells[ti]) { // cell block exists
      +                cell = blocks_ + cells[ti]; // get cell block ptr
      +                cell->h = block->h;
      +            }
      +            
      +            b.y = block->y + block->h - 4; // tr gap offset between rows
      +            
      +//printf("/tr row=%d column=%d b.h=%d b->h=%d b->y=%d b.y=%d\n",
      +//  row,column,b.h,block->h,block->y,b.y);
      +
      +            block = add_block(b, ptr, hwidth);
      +            needspace = 0;
      +            row = 0; // reset row block number
      +            line = 0;
      +          }
      +          else // start margins pop /tr - rem: nested table fix?
      +          {
      +            line = do_align(block, line, b.x, newalign, links);
      +            block->end = ptr;
      +            b.x = block->x;
      +            block->h += b.h;
      +            b.y += b.h;
      +            trpop = 1; // set tr popped
      +            b.x = margins.pop(); // pop tr
      +
      +            while (isspace((*ptr) & 255)) ptr ++;
      +            block = add_block(b, ptr, hwidth);
      +            b.h = 0;
      +            needspace = 0;
      +            line = 0;
      +            newalign = talign;
      +          }
      +        }
      +        else if (b.tag == CMD('U',0,0,0)) // 'U'
      +        {
      +        }
      +        else if (b.tag == CMD('V','A','R',0)) // 'VAR'
      +        {
      +          b.font = font_style(monofont_, FL_ITALIC);
      +          pushfont(b.font, b.fsize);
      +        }
      +        else if (b.tag == CMD('/','V','A','R')) // '/VAR'
      +        {
      +          popfont(b.font, b.fsize);
      +        }
      +        else if (b.tag == CMD('A','B','B',0) || // 'ABBR'
      +                 b.tag == CMD('A','C','R',0) || // 'ACRONYM'
      +                 b.tag == CMD('A','D','D',0) || // 'ADDRESS'
      +                 b.tag == CMD('A','P','P',0) || // 'APPLET'
      +                 b.tag == CMD('A','R','E',0) || // 'AREA'
      +                 b.tag == CMD('B','A','S',0) || // 'BASE' 'BASEFONT'
      +                 b.tag == CMD('B','D','O',0) || // 'BDO'
      +                 b.tag == CMD('B','G','S',0) || // 'BGSOUND'
      +                 b.tag == CMD('B','I','G',0) || // 'BIG'
      +                 b.tag == CMD('B','L','I',0) || // 'BLINK'
      +                 b.tag == CMD('B','U','T',0) || // 'BUTTON'
      +                 b.tag == CMD('C','A','P',0) || // 'CAPTION'
      +                 b.tag == CMD('C','I','T',0) || // 'CITE'
      +                 b.tag == CMD('C','O','L',0) || // 'COL' 'COLGROUP'
      +                 b.tag == CMD('D','E','L',0) || // 'DEL'
      +                 b.tag == CMD('D','F','N',0) || // 'DFN'
      +                 b.tag == CMD('D','I','R',0) || // 'DIR'
      +                 b.tag == CMD('E','M','B',0) || // 'EMBED'
      +                 b.tag == CMD('F','I','E',0) || // 'FIELDSET'
      +                 b.tag == CMD('F','O','R',0) || // 'FORM'
      +                 b.tag == CMD('F','R','A',0) || // 'FRAME' 'FRAMESET'
      +                 b.tag == CMD('I','F','R',0) || // 'IFRAME'
      +                 b.tag == CMD('I','N','P',0) || // 'INPUT'
      +                 b.tag == CMD('I','N','S',0) || // 'INS'
      +                 b.tag == CMD('I','S','I',0) || // 'ISINDEX'
      +                 b.tag == CMD('L','A','B',0) || // 'LABEL'
      +                 b.tag == CMD('L','E','G',0) || // 'LEGEND'
      +                 b.tag == CMD('L','I','N',0) || // 'LINK'
      +                 b.tag == CMD('M','A','P',0) || // 'MAP'
      +                 b.tag == CMD('M','A','R',0) || // 'MARQUEE'
      +                 b.tag == CMD('M','E','N',0) || // 'MENU'
      +                 b.tag == CMD('M','E','T',0) || // 'META'
      +                 b.tag == CMD('M','U','L',0) || // 'MULTICOL'
      +                 b.tag == CMD('N','O','B',0) || // 'NOBR'
      +                 b.tag == CMD('N','O','F',0) || // 'NOFRAMES'
      +                 b.tag == CMD('O','B','J',0) || // 'OBJECT'
      +                 b.tag == CMD('O','P','T',0) || // 'OPTGROUP' 'OPTION'
      +                 b.tag == CMD('P','A','R',0) || // 'PARAM'
      +                 b.tag == CMD('Q',0,0,0) || // 'Q'
      +                 b.tag == CMD('S',0,0,0) || // 'S'
      +                 b.tag == CMD('S','A','M',0) || // 'SAMP'
      +                 b.tag == CMD('S','E','L',0) || // 'SELECT'
      +                 b.tag == CMD('S','M','A',0) || // 'SMALL'
      +                 b.tag == CMD('S','P','A',0) || // 'SPACER' 'SPAN'
      +                 b.tag == CMD('S','T','R',0) || // 'STRIKE'
      +                 b.tag == CMD('S','T','Y',0) || // 'STYLE'
      +                 b.tag == CMD('S','U','B',0) || // 'SUB'
      +                 b.tag == CMD('S','U','P',0) || // 'SUP'
      +                 b.tag == CMD('T','B','O',0) || // 'TBODY'
      +                 b.tag == CMD('T','E','X',0) || // 'TEXTAREA'
      +                 b.tag == CMD('T','F','O',0) || // 'TFOOT'
      +                 b.tag == CMD('T','H','E',0) || // 'THEAD'
      +                 b.tag == CMD('W','B','R',0) || // 'WBR'
      +                 b.tag == CMD('X','M','P',0)) // 'XMP'
      +          ; // unsupported tags
      +        else if (tag[0] == '!' && isalpha(tag[1])) // '!DOCTYPE' etc
      +          ;
      +        else if (tag[0] == '?' && isalpha(tag[1])) // '?XMP' etc
      +          ;
      +        else if (tag[0] == '/' && isalpha(tag[1])) // unrecognized end tag
      +          ;
      +        else if (!head) // unrecognized tag so draw it
      +        {
      +          b.x += (int)fl_width("<"); // add width of '<' char
      +          linew += (int)fl_width("<");
      +          ptr = tagptr + 1; // start of tag + 1
      +        }
      +        
      +      } // if (*ptr == '<')
      +
      +      else if (*ptr == '\n' && b.pre) // '\n' in pre
      +      {
      +        if (linkdest[0])
      +          add_link(linkdest, b.x, b.y - b.h, b.w, b.h);
      +
      +        if (b.x > hsize_) { // Reformat
      +          hsize_ = b.x + 4;
      +          done = 0;
      +        }
      +
      +        block->end = ptr;
      +        line = do_align(block, 0, b.x, newalign, links);
      +        b.x = block->x;
      +        block->h += b.h;
      +        b.y += b.h; //b.y = block->y + block->h;
      +        line = 0;
      +        linew = 0;
      +
      +        block = add_block(b, ptr, (row) ? block->w : hwidth);
      +        b.h = 0;
      +        needspace = 0;
      +        ptr ++;
      +      }
      +      else if (isspace((*ptr) & 255)) // ' ' '\t'\n'\v'\f'\r' chars
      +      {
      +        needspace = 1;
      +        ptr ++;
      +      }
      +      else if (*ptr == '&' && sp < (buf + sizeof(buf) - 1)) // '&' char ref
      +      {
      +        ptr ++;
      +        qch = quote_char(ptr);
      +
      +        if (qch < 0)
      +          *(sp ++) = '&'; // added ()
      +        else {
      +          *(sp ++) = qch; // added ()
      +          ptr = strchr(ptr, ';') + 1;
      +        }
      +
      +        if (b.fsize + 2 > b.h) b.h = b.fsize + 2; // Set b.h
      +      }
      +      else // Other char
      +      {
      +        if (sp < (buf + sizeof(buf) - 1))
      +          *(sp ++) = *(ptr ++); // added ()
      +        else
      +          ptr ++;
      +
      +        if (b.fsize + 2 > b.h) b.h = b.fsize + 2; // Set b.h
      +      }
      +
      +      //if (d->resized && block->y + block->h > topline_ + h())
      +        //break; // if resizing big page skip non-visible region
      +
      +    } // for (ptr = value_ ...)
      +
      +    if (sp > buf) // Still something left to parse
      +    {
      +      if (!head) // Normal text... b.pre fixme?
      +      {
      +        *sp = '\0'; // Nul-terminate
      +        b.w = (int)fl_width(buf);
      +
      +//printf("line = %d, b.x = %d, b.w = %d, block->x = %d, block->w = %d\n",
      +//  line, b.x, b.w, block->x, block->w);
      +
      +        if (b.w > hsize_) { // Reformat
      +          hsize_ = b.w;
      +          done = 0;
      +        }
      +
      +        if (needspace && b.x > block->x)
      +          b.w += (int)fl_width(" ");
      +
      +        // no new line if word too long and no word before it
      +        if (!(b.x < 7 && b.w > block->w) && (b.x + b.w) > block->w) {
      +          block->end = ptr - strlen(buf);
      +          line = do_align(block, 0, b.x, newalign, links);
      +          b.x = block->x;
      +          block->h += b.h;
      +          b.y += b.h; //b.y = block->y + block->h;
      +          b.h = 0;
      +          line = 0;
      +
      +          block = add_block(b, ptr - strlen(buf), (row) ? block->w : hwidth);
      +        }
      +
      +        if (linkdest[0])
      +          add_link(linkdest, b.x, b.y - b.fsize, b.w, b.fsize);
      +
      +        b.x += b.w;
      +      }
      +    }
      +
      +    do_align(block, line, b.x, newalign, links);
      +    block->end = ptr;
      +    size_ = b.y + b.h;
      +
      +    //if (d->resized && block->y + block->h > topline_ + h())
      +      //break; // if resizing big page skip non-visible region
      +
      +  } // while (!done)
      +
      +  d->isnew = 0; // reset - so we know a repeat call to format per page, to stabilize malloc
      +  
      +//printf("margins.depth_=%d\n", margins.depth_);
      +
      +  if (ntargets_ > 1)
      +    qsort(d->targets, ntargets_, sizeof(Fl_Help_Link),
      +          (compare_func_t)cmp_targets);
      +
      +  dx = Fl::box_dw(bt) - Fl::box_dx(bt);
      +  dy = Fl::box_dh(bt) - Fl::box_dy(bt);
      +  ss = Fl::scrollbar_size();
      +  dw = Fl::box_dw(bt) + ss;
      +  dh = Fl::box_dh(bt);
      +
      +  //if (d->resized && block->y + block->h > topline_ + h())
      +    //return; // if resizing big page skip resizing scrollbars
      +
      +  if (hsize_ > (w() - dw))
      +  {
      +    hscrollbar_.show();
      +    dh += ss;
      +
      +    if (size_ < (h() - dh)) {
      +      scrollbar_.hide();
      +      hscrollbar_.resize(x() + Fl::box_dx(bt), y() + h() - ss - dy,
      +                         w() - Fl::box_dw(bt), ss);
      +    }
      +    else {
      +      scrollbar_.show();
      +      scrollbar_.resize(x() + w() - ss - dx, y() + Fl::box_dy(bt),
      +                        ss, h() - ss - Fl::box_dh(bt));
      +      hscrollbar_.resize(x() + Fl::box_dx(bt), y() + h() - ss - dy,
      +                         w() - ss - Fl::box_dw(bt), ss);
      +    }
      +  }
      +  else // If hsize_ <= (w() - dw)
      +  {
      +    hscrollbar_.hide();
      +
      +    if (size_ < (h() - dh))
      +     scrollbar_.hide();
      +    else {
      +      scrollbar_.resize(x() + w() - ss - dx, y() + Fl::box_dy(bt),
      +                        ss, h() - Fl::box_dh(bt));
      +      scrollbar_.show();
      +    }
      +  }
      +
      +  // Reset scrolling if it needs to be
      +  if (scrollbar_.visible()) {
      +    temph = h() - Fl::box_dh(bt);
      +    if (hscrollbar_.visible()) temph -= ss;
      +    if ((topline_ + temph) > size_) topline(size_ - temph);
      +    else topline(topline_);
      +  }
      +  else
      +    topline(0);
      +
      +  if (hscrollbar_.visible()) {
      +    tempw = w() - ss - Fl::box_dw(bt);
      +    if (leftline_ + tempw > hsize_)
      +      leftline(hsize_ - tempw);
      +    else
      +      leftline(leftline_);
      +  }
      +  else
      +    leftline(0);
      +
      +} // Fl_Help_View::format()
      +
      +//
      +// Fl_Help_View::format_table() - replaced, code moved
      +//
      +
      +void Fl_Help_View::format_table(int *tw, // O - Total table width
      +                                int *maxcols, // O - Column widths
      +                                const char *tp) // I - Table start pointer
      +{
      +  return;
      +
      +} // Fl_Help_View::format_table()
      +
      +//
      +// Fl_Help_View::format_table() - Format a table.
      +//
      +
      +const char * // O - table end pointer
      +Fl_Help_View::format_table(int &tw, // O - Total table width
      +                           int *maxcols, // O - Column widths
      +                           const char *tp, // I - Table start pointer
      +                           int xx, // I - x position of table
      +                           int rc) // I - recursive counter
      +{
      +  char *sp, // Pointer into buffer
      +    buf[1024], // Text buffer
      +    attr[1024], // Other attribute
      +    wattr[1024], // WIDTH attribute
      +    hattr[1024], // HEIGHT attribute
      +    tag[4]; // tag/element 4-char buf
      +  const char *ptr, // Pointer into table
      +    *attrptr, // Start of attributes ptr
      +    *tagptr, // Start of tag/element ptr
      +    *endp; // table end pointer
      +  int col = 0, // Current column
      +    numcells = 0, // Number of cells
      +    colspan = 0, // COLSPAN attribute
      +    linew = 0, // Current line width
      +    tempw = 0, // Temporary width
      +    maxlinew = 0, // Maximum width
      +    mincellw = 0, // minimum table width
      +    maxcellw = 0, // total width of cells
      +    colspanw = 0, // colspan width
      +    scalew = 0, // Table scaled width
      +    hwidth = 0, // horizontal window width
      +    tsize = 0, // table size
      +    incell = 0, // In a table cell?
      +    head = 0, // head/body section flag
      +    pre = 0, // Pre text flag
      +    btag = 0, // tag/element fourcc int
      +    needspace = 0, // Do we need whitespace?
      +    ti = 0, // temp loop var
      +    imgw = 0, // Image width
      +    imgh = 0, // Image height
      +    qch = 0, // Quote char
      +    nfonts = 0, // local font stack index
      +	font = 0; // Current font
      +  unsigned char fsize; // Current font size
      +  int mincols[HV_64], // Minimum widths for each column
      +    widths[HV_64], // td width attributes
      +    colspans[HV_64], // min width in colspan cells
      +    columns[HV_64], // nested table column widths
      +    fonts[HV_64][2]; // local font stack
      +  Fl_Shared_Image *img = 0; // Shared image - rem'd NULL
      +  Fl_Boxtype bt = (box()) ? box() : FL_DOWN_BOX; // Box size
      +
      +  tw = 0; // Clear widths
      +  endp = 0; // rem'd NULL
      +
      +  // zero arrays
      +  memset(mincols, 0, sizeof(mincols));
      +  memset(widths, 0, sizeof(widths));
      +  memset(colspans, 0, sizeof(colspans));
      +  memset(columns, 0, sizeof(columns));
      +
      +  hwidth = w() - Fl::scrollbar_size() - Fl::box_dw(bt);
      +
      +  font = fonts[nfonts][0] = serifont_; // initfont
      +  fsize = fonts[nfonts][1] = fontsize_;
      +  fl_font(font, fsize);
      +
      +//printf("\nFORMAT_TABLE %d\n",tp - value_);
      +
      +  col = -1;
      +  linew = 0;
      +  incell = 0;
      +
      +  // Scan the table
      +  for (ptr = tp, sp = buf; *ptr; )
      +  {
      +    if ((*ptr == '<' || isspace((*ptr) & 255)) && sp > buf)
      +    {
      +      if (needspace) { // Check width
      +        *(sp ++) = ' '; // added ()
      +        needspace = 0;
      +      }
      +
      +      *sp = '\0'; // Nul-terminate
      +      sp = buf;
      +
      +      if (incell && !head && !pre) // Normal text
      +      {
      +        tempw = (int)fl_width(buf); // Width of current word
      +        if (tempw > mincols[col] && colspan <= 1)
      +          mincols[col] = tempw; // ignore if colspan > 1
      +
      +        if (tempw > colspans[col] && colspan > 1) {
      +          colspans[col] = tempw; // colspans
      +          colspans[col] -= 6 * (colspan - 1); // sub internal borders
      +          if (colspans[col] < 6 * (colspan - 1))
      +            colspans[col] = tempw; // reset thin cell widths
      +          colspans[col + 1] = colspan;
      +        }
      +
      +        linew += tempw;
      +        if (linew > maxlinew) maxlinew = linew;
      +      }
      +      else if (incell && !head && pre) // pre text
      +      {
      +        tempw = (int)fl_width(buf); // Width of current word
      +        linew += tempw; // pre text in tables not increasing cell width fix
      +        if (linew > maxlinew) maxlinew = linew;
      +
      +//printf("ptr=%c head=%d pre=%d incell=%d tw=%d lw=%d %s\n",
      +//  *ptr,head,pre,incell,tempw,linew,buf);
      +
      +        if (*ptr == '\n') { // newline char
      +          if (linew > mincols[col] && colspan <= 1)
      +            mincols[col] = linew; // ignore if colspan > 1
      +
      +          if (linew > colspans[col] && colspan > 1) {
      +            colspans[col] = linew; // colspans
      +            colspans[col] -= 5 * (colspan - 1); // sub internal borders
      +            if (colspans[col] < 5 * (colspan - 1))
      +              colspans[col] = linew; // reset thin cell widths
      +            colspans[col + 1] = colspan;
      +          }
      +        }
      +        else if (*ptr == '\t') { // tab char
      +          ti = linew / (int)fl_width(" "); // number of chars, monospace
      +          tempw = 7 - (ti & 7); // number of tabs 0..7
      +          if (tempw) // pre tabs width fix
      +            linew += tempw * (int)fl_width(" ");
      +        }
      +      }
      +    }
      +
      +    if (*ptr == '<')
      +    {
      +      tagptr = ptr; // Start of tag
      +      ptr ++; // inc ptr
      +      sp = buf; // reset sp
      +
      +      if (!strncmp(ptr, "!--", 3)) { // Found "!--"
      +        ptr += 3;
      +        if ((ptr = strstr(ptr, "-->"))) { // Skip comment - rem'd != 0
      +          ptr += 3;
      +          continue;
      +        }
      +        else
      +          break;
      +      }
      +
      +      while (*ptr && *ptr != '>' && !isspace((*ptr) & 255)) // was for loop
      +        if (sp < (buf + sizeof(buf) - 1))
      +          *(sp ++) = *(ptr ++); // added ()
      +        else
      +          ptr ++;
      +
      +      *sp = '\0'; // Nul-terminate
      +      sp = buf;
      +
      +      attrptr = ptr; // Start of attributes
      +      while (*ptr && *ptr != '>') ptr ++;
      +      if (*ptr == '>') ptr ++;
      +
      +      btag = strlen(buf); // store strlen
      +      if (btag > 4) btag = 4; // limit
      +      for (ti = 0; ti < btag; ti ++) // abbreviate tag, to uppercase
      +        tag[ti] = toupper(buf[ti]);
      +      for (ti = btag; ti < 4; ti ++) // set chars after to nul
      +        tag[ti] = 0;
      +      if (buf[0] != '/' && btag > 3) tag[3] = 0; // eg. HTML=HTM
      +      btag = CMD(tag[0],tag[1],tag[2],tag[3]); // tag as int
      +
      +      // End of command reached
      +      if (btag == CMD('A',0,0,0)) // 'A'
      +      {
      +      }
      +      else if (btag == CMD('B',0,0,0) ||
      +               btag == CMD('S','T','R',0)) // 'B' 'STRONG'
      +      {
      +        font = font_style(font, FL_BOLD);
      +        if (nfonts < HV_64 - 1) nfonts ++; // pushfont
      +        fl_font(fonts[nfonts][0] = font, fonts[nfonts][1] = fsize);
      +      }
      +      else if (btag == CMD('/','B',0,0) ||
      +               btag == CMD('/','S','T','R')) // '/B' '/STRONG'
      +      {
      +        if (nfonts > 0) nfonts --; // popfont
      +        fl_font(font = fonts[nfonts][0], fsize = fonts[nfonts][1]);
      +      }
      +      else if (btag == CMD('B','L','O',0) ||
      +               btag == CMD('D','L',0,0) ||
      +               btag == CMD('U','L',0,0) ||
      +               btag == CMD('O','L',0,0) ||
      +               btag == CMD('D','D',0,0) ||
      +               btag == CMD('D','T',0,0)) // 'BLOCKQUOTE' 'DL'OL'UL'
      +      {
      +        linew = 0;
      +        needspace = 0;
      +      }
      +      else if (btag == CMD('/','B','L','O') ||
      +               btag == CMD('/','D','L',0) ||
      +               btag == CMD('/','O','L',0) ||
      +               btag == CMD('/','U','L',0)) // '/BLOCKQUOTE' '/DL'/OL'/UL'
      +      {
      +        linew = 0;
      +        needspace = 0;
      +      }
      +      else if (btag == CMD('B','O','D',0)) // 'BODY'
      +      {
      +      }
      +      else if (btag == CMD('B','R',0,0)) // 'BR'
      +      {
      +        linew = 0;
      +        needspace = 0;
      +      }
      +      else if (btag == CMD('C','E','N',0)) // 'CENTER'
      +      {
      +        linew = 0;
      +        needspace = 0;
      +      }
      +      else if (btag == CMD('/','C','E','N')) // '/CENTER'
      +      {
      +        linew = 0;
      +        needspace = 0;
      +      }
      +      else if (btag == CMD('C','O','D',0) ||
      +               btag == CMD('T','T',0,0)) // 'CODE' 'TT'
      +      {
      +        font = monofont_;
      +        if (nfonts < HV_64 - 1) nfonts ++; // pushfont
      +        fl_font(fonts[nfonts][0] = font, fonts[nfonts][1] = fsize);
      +      }
      +      else if (btag == CMD('/','C','O','D') ||
      +               btag == CMD('/','T','T',0)) // '/CODE' '/TT'
      +      {
      +        if (nfonts > 0) nfonts --; // popfont
      +        fl_font(font = fonts[nfonts][0], fsize = fonts[nfonts][1]);
      +      }
      +      else if (btag == CMD('D','I','V',0)) // 'DIV'
      +      {
      +        linew = 0;
      +        needspace = 0;
      +      }
      +      else if (btag == CMD('/','D','I','V')) // '/DIV'
      +      {
      +        linew = 0;
      +        needspace = 0;
      +      }
      +      else if (btag == CMD('F','O','N',0)) // 'FONT'
      +      {
      +        if (get_attr(attrptr, "FACE", attr, sizeof(attr)))
      +          font = font_face(attr);
      +
      +        if (get_attr(attrptr, "SIZE", attr, sizeof(attr))) {
      +          if (isdigit(attr[0])) // Absolute size
      +            fsize = (int)(fontsize_ * pow(1.2, atoi(attr) - 3.0));
      +          else // Relative size
      +            fsize = (int)(fsize * pow(1.2, atoi(attr)));
      +        }
      +
      +        if (nfonts < HV_64 - 1) nfonts ++; // pushfont
      +        fl_font(fonts[nfonts][0] = font, fonts[nfonts][1] = fsize);
      +      }
      +      else if (btag == CMD('/','F','O','N')) // '/FONT'
      +      {
      +        if (nfonts > 0) nfonts --; // popfont
      +        fl_font(font = fonts[nfonts][0], fsize = fonts[nfonts][1]);
      +      }
      +      else if (tag[0] == 'H' && isdigit(tag[1])) // 'H1'
      +      {
      +        linew = 0;
      +        needspace = 0;
      +        font = font_style(font, FL_BOLD);
      +        switch (tag[1]) { // header sizes
      +          case '1' : fsize = 24; break;
      +          case '2' : fsize = 18; break;
      +          case '3' : fsize = 16; break;
      +          case '4' : fsize = 14; break;
      +          case '5' : fsize = 12; break;
      +          case '6' : fsize = 10; break;
      +          default : fsize = fontsize_; font = serifont_; break;
      +        }
      +        if (nfonts < HV_64 - 1) nfonts ++; // pushfont
      +        fl_font(fonts[nfonts][0] = font, fonts[nfonts][1] = fsize);
      +      }
      +      else if (btag == CMD('/','H',tag[2],0) && isdigit(tag[2])) // '/H1'
      +      {
      +        linew = 0;
      +        needspace = 0;
      +        if (nfonts > 0) nfonts --; // popfont
      +        fl_font(font = fonts[nfonts][0], fsize = fonts[nfonts][1]);
      +      }
      +      else if (btag == CMD('H','E','A',0)) // 'HEAD'
      +      {
      +        head = 1;
      +      }
      +      else if (btag == CMD('/','H','E','A')) // '/HEAD'
      +      {
      +        head = 0;
      +      }
      +      else if (btag == CMD('H','R',0,0)) // 'HR'
      +      {
      +        linew = 0;
      +        needspace = 0;
      +      }
      +      else if (btag == CMD('H','T','M',0)) // 'HTML'
      +      {
      +      }
      +      else if (btag == CMD('I',0,0,0) ||
      +               btag == CMD('E','M',0,0)) // 'I' 'EM'
      +      {
      +        font = font_style(font, FL_ITALIC);
      +        if (nfonts < HV_64 - 1) nfonts ++; // pushfont
      +        fl_font(fonts[nfonts][0] = font, fonts[nfonts][1] = fsize);
      +      }
      +      else if (btag == CMD('/','I',0,0) ||
      +               btag == CMD('/','E','M',0)) // '/I' '/EM'
      +      {
      +        if (nfonts > 0) nfonts --; // popfont
      +        fl_font(font = fonts[nfonts][0], fsize = fonts[nfonts][1]);
      +      }
      +      else if (btag == CMD('I','M','G',0)) // 'IMG'
      +      {
      +        if (incell) {
      +          imgw = imgh = 0; // reset
      +          if (get_attr(attrptr, "WIDTH", wattr, sizeof(wattr)))
      +            imgw = get_length(wattr);
      +          if (get_attr(attrptr, "HEIGHT", hattr, sizeof(hattr)))
      +            imgh = get_length(hattr);
      +
      +          img = 0; // rem'd NULL
      +          if (get_attr(attrptr, "SRC", attr, sizeof(attr))) {
      +            img = get_image(attr, imgw, imgh); // Use src values
      +            imgw = img->w();
      +            imgh = img->h();
      +          }
      +
      +          if (imgw > mincols[col]) mincols[col] = imgw;
      +
      +          linew += imgw;
      +          if (needspace) {
      +            linew += (int)fl_width(" ");
      +            needspace = 0;
      +          }
      +          if (linew > maxlinew) maxlinew = linew;
      +        }
      +      }
      +      else if (btag == CMD('K','B','D',0)) // 'KBD'
      +      {
      +        font = font_style(monofont_, FL_BOLD);
      +        if (nfonts < HV_64 - 1) nfonts ++; // pushfont
      +        fl_font(fonts[nfonts][0] = font, fonts[nfonts][1] = fsize);
      +      }
      +      else if (btag == CMD('/','K','B','D')) // '/KBD'
      +      {
      +        if (nfonts > 0) nfonts --; // popfont
      +        fl_font(font = fonts[nfonts][0], fsize = fonts[nfonts][1]);
      +      }
      +      else if (btag == CMD('L','I',0,0)) // 'LI'
      +      {
      +        linew = 0;
      +        needspace = 0;
      +        linew += fsize; // changed 4 * fsize
      +      }
      +      else if (btag == CMD('/','L','I',0)) // '/LI'
      +      {
      +        linew = 0;
      +        needspace = 0;
      +      }
      +      else if (btag == CMD('N','O','S',0)) // 'NOSCRIPT'
      +      { // we don't support scripting so we won't skip this
      +      }
      +      else if (btag == CMD('P',0,0,0)) // 'P'
      +      {
      +        linew = 0;
      +        needspace = 0;
      +      }
      +      else if (btag == CMD('/','P',0,0)) // '/P'
      +      {
      +        linew = 0;
      +        needspace = 0;
      +      }
      +      else if (btag == CMD('P','R','E',0)) // 'PRE'
      +      {
      +        linew = 0;
      +        needspace = 0;
      +        pre = 1;
      +        font = monofont_;
      +        fsize = fontsize_;
      +        if (nfonts < HV_64 - 1) nfonts ++; // pushfont
      +        fl_font(fonts[nfonts][0] = font, fonts[nfonts][1] = fsize);
      +      }
      +      else if (btag == CMD('/','P','R','E')) // '/PRE'
      +      {
      +        linew = 0;
      +        needspace = 0;
      +        pre = 0;
      +        if (nfonts > 0) nfonts --; // popfont
      +        fl_font(font = fonts[nfonts][0], fsize = fonts[nfonts][1]);
      +      }
      +      else if (btag == CMD('S','C','R',0)) // 'SCRIPT'
      +      {
      +        while (ptr) { // skip scripting
      +          ptr = strstr(ptr, "", 9)) break;
      +        }
      +
      +        if (ptr) { // found 
      +          ptr += 9;
      +          continue;
      +        }
      +        else // not found
      +          break;
      +      }
      +      else if (btag == CMD('T','A','B',0)) // 'TABLE'
      +      {
      +        linew = 0; // cell width not reset before nested table fix
      +        needspace = 0;
      +
      +        if (tagptr > tp) { // nested table
      +          if (rc < HV_16) // limit recursive function
      +            endp = format_table(scalew, columns, tagptr, xx, rc + 1);
      +          if (endp) ptr = endp; // to skip nested table
      +
      +          for (ti = 0; ti < HV_64; ti ++)
      +            if (columns[ti] == 0) break; // num columns
      +          scalew += ti * 6; // add internal borders
      +
      +          if (scalew > mincols[col]) // set nested width
      +            mincols[col] = scalew;
      +
      +          linew += scalew;
      +          if (linew > maxlinew) maxlinew = linew;
      +
      +          linew = 0; // cell width not reset after nested table fix
      +          needspace = 0;
      +        }
      +      }
      +      else if (btag == CMD('/','T','A','B')) // '/TABLE'
      +      {
      +
      +//printf("%s col = %d, colspan = %d, numcells = %d\n",
      +//  buf, col, colspan, numcells);
      +
      +        if (col >= 0) { // This is a hack to support COLSPAN
      +          ti = colspan; // ignore if colspan > 1
      +          maxlinew /= colspan;
      +          while (colspan > 0) {
      +            if (maxlinew > maxcols[col] && ti <= 1)
      +              maxcols[col] = maxlinew;
      +            col ++;
      +            colspan --;
      +          }
      +        }
      +        endp = ptr; // store nested table end ptr
      +        break; // exit for (ptr = tp ...) loop
      +      }
      +      else if (btag == CMD('T','D',0,0) ||
      +               btag == CMD('T','H',0,0)) // 'TD' 'TH'
      +      {
      +
      +//printf("BEFORE col = %d, colspan = %d, numcells = %d\n",
      +//  col, colspan, numcells);
      +
      +        if (col >= 0) { // This is a hack to support COLSPAN
      +          ti = colspan; // ignore if colspan > 1
      +          maxlinew /= colspan;
      +          while (colspan > 0) {
      +            if (maxlinew > maxcols[col] && ti <= 1)
      +              maxcols[col] = maxlinew;
      +            col ++;
      +            colspan --;
      +          }
      +        }
      +        else
      +          col ++;
      +
      +        colspan = 1; // Reset
      +        if (get_attr(attrptr, "COLSPAN", attr, sizeof(attr)))
      +          colspan = atoi(attr);
      +
      +//printf("AFTER col = %d, colspan = %d, numcells = %d\n",
      +//  col, colspan, numcells);
      +
      +        if (col + colspan >= numcells)
      +          numcells = col + colspan;
      +
      +        linew = 0;
      +        needspace = 0;
      +        incell = 1;
      +
      +        if (btag == CMD('T','H',0,0)) // th
      +          font = font_style(serifont_, FL_BOLD);
      +        else
      +          font = serifont_;
      +        fsize = fontsize_;
      +
      +        nfonts = 0; // pop all fonts off stack, no need for anything more
      +        if (nfonts < HV_64 - 1) nfonts ++; // pushfont
      +        fl_font(fonts[nfonts][0] = font, fonts[nfonts][1] = fsize);
      +
      +        maxlinew = 0; // Reset
      +        if (get_attr(attrptr, "WIDTH", attr, sizeof(attr))) {
      +          maxlinew = get_length(attr, hsize_ - xx);
      +          if (maxlinew > widths[col])
      +            widths[col] = maxlinew; // store widths
      +        }
      +
      +//printf("maxlinew = %d\n", maxlinew);
      +
      +      }
      +      else if (btag == CMD('/','T','D',0) ||
      +               btag == CMD('/','T','H',0)) // '/TD' '/TH'
      +      {
      +        incell = 0;
      +      }
      +      else if (btag == CMD('T','I','T',0)) // 'TITLE'
      +      {
      +      }
      +      else if (btag == CMD('T','R',0,0)) // 'TR'
      +      {
      +
      +//printf("%s col = %d, colspan = %d, numcells = %d\n",
      +//  buf, col, colspan, numcells);
      +
      +        if (col >= 0) { // This is a hack to support COLSPAN
      +          ti = colspan; // ignore if colspan > 1
      +          maxlinew /= colspan;
      +          while (colspan > 0) {
      +            if (maxlinew > maxcols[col] && ti <= 1)
      +              maxcols[col] = maxlinew;
      +            col ++;
      +            colspan --;
      +          }
      +        }
      +
      +        linew = 0;
      +        needspace = 0;
      +        incell = 0;
      +        col = -1;
      +        maxlinew = 0;
      +      }
      +      else if (btag == CMD('/','T','R',0)) // '/TR'
      +      {
      +
      +//printf("%s col = %d, colspan = %d, numcells = %d\n",
      +//  buf, col, colspan, numcells);
      +
      +        if (col >= 0) { // This is a hack to support COLSPAN
      +          ti = colspan; // ignore if colspan > 1
      +          maxlinew /= colspan;
      +          while (colspan > 0) {
      +            if (maxlinew > maxcols[col] && ti <= 1)
      +              maxcols[col] = maxlinew;
      +            col ++;
      +            colspan --;
      +          }
      +        }
      +
      +        linew = 0;
      +        needspace = 0;
      +        incell = 0;
      +        col = -1;
      +        maxlinew = 0;
      +      }
      +      else if (btag == CMD('U',0,0,0)) // 'U'
      +      {
      +      }
      +      else if (btag == CMD('V','A','R',0)) // 'VAR'
      +      {
      +        font = font_style(monofont_, FL_ITALIC);
      +        if (nfonts < HV_64 - 1) nfonts ++; // pushfont
      +        fl_font(fonts[nfonts][0] = font, fonts[nfonts][1] = fsize);
      +      }
      +      else if (btag == CMD('/','V','A','R')) // '/VAR'
      +      {
      +        if (nfonts > 0) nfonts --; // popfont
      +        fl_font(font = fonts[nfonts][0], fsize = fonts[nfonts][1]);
      +      }
      +      else if (btag == CMD('A','B','B',0) || // 'ABBR'
      +               btag == CMD('A','C','R',0) || // 'ACRONYM'
      +               btag == CMD('A','D','D',0) || // 'ADDRESS'
      +               btag == CMD('A','P','P',0) || // 'APPLET'
      +               btag == CMD('A','R','E',0) || // 'AREA'
      +               btag == CMD('B','A','S',0) || // 'BASE' 'BASEFONT'
      +               btag == CMD('B','D','O',0) || // 'BDO'
      +               btag == CMD('B','G','S',0) || // 'BGSOUND'
      +               btag == CMD('B','I','G',0) || // 'BIG'
      +               btag == CMD('B','L','I',0) || // 'BLINK'
      +               btag == CMD('B','U','T',0) || // 'BUTTON'
      +               btag == CMD('C','A','P',0) || // 'CAPTION'
      +               btag == CMD('C','I','T',0) || // 'CITE'
      +               btag == CMD('C','O','L',0) || // 'COL' 'COLGROUP'
      +               btag == CMD('D','E','L',0) || // 'DEL'
      +               btag == CMD('D','F','N',0) || // 'DFN'
      +               btag == CMD('D','I','R',0) || // 'DIR'
      +               btag == CMD('E','M','B',0) || // 'EMBED'
      +               btag == CMD('F','I','E',0) || // 'FIELDSET'
      +               btag == CMD('F','O','R',0) || // 'FORM'
      +               btag == CMD('F','R','A',0) || // 'FRAME' 'FRAMESET'
      +               btag == CMD('I','F','R',0) || // 'IFRAME'
      +               btag == CMD('I','N','P',0) || // 'INPUT'
      +               btag == CMD('I','N','S',0) || // 'INS'
      +               btag == CMD('I','S','I',0) || // 'ISINDEX'
      +               btag == CMD('L','A','B',0) || // 'LABEL'
      +               btag == CMD('L','E','G',0) || // 'LEGEND'
      +               btag == CMD('L','I','N',0) || // 'LINK'
      +               btag == CMD('M','A','P',0) || // 'MAP'
      +               btag == CMD('M','A','R',0) || // 'MARQUEE'
      +               btag == CMD('M','E','N',0) || // 'MENU'
      +               btag == CMD('M','E','T',0) || // 'META'
      +               btag == CMD('M','U','L',0) || // 'MULTICOL'
      +               btag == CMD('N','O','B',0) || // 'NOBR'
      +               btag == CMD('N','O','F',0) || // 'NOFRAMES'
      +               btag == CMD('O','B','J',0) || // 'OBJECT'
      +               btag == CMD('O','P','T',0) || // 'OPTGROUP' 'OPTION'
      +               btag == CMD('P','A','R',0) || // 'PARAM'
      +               btag == CMD('Q',0,0,0) || // 'Q'
      +               btag == CMD('S',0,0,0) || // 'S'
      +               btag == CMD('S','A','M',0) || // 'SAMP'
      +               btag == CMD('S','E','L',0) || // 'SELECT'
      +               btag == CMD('S','M','A',0) || // 'SMALL'
      +               btag == CMD('S','P','A',0) || // 'SPACER' 'SPAN'
      +               btag == CMD('S','T','R',0) || // 'STRIKE'
      +               btag == CMD('S','T','Y',0) || // 'STYLE'
      +               btag == CMD('S','U','B',0) || // 'SUB'
      +               btag == CMD('S','U','P',0) || // 'SUP'
      +               btag == CMD('T','B','O',0) || // 'TBODY'
      +               btag == CMD('T','E','X',0) || // 'TEXTAREA'
      +               btag == CMD('T','F','O',0) || // 'TFOOT'
      +               btag == CMD('T','H','E',0) || // 'THEAD'
      +               btag == CMD('W','B','R',0) || // 'WBR'
      +               btag == CMD('X','M','P',0)) // 'XMP'
      +          ; // unsupported tags
      +        else if (tag[0] == '!' && isalpha(tag[1])) // '!DOCTYPE' etc
      +          ;
      +        else if (tag[0] == '?' && isalpha(tag[1])) // '?XMP' etc
      +          ;
      +        else if (tag[0] == '/' && isalpha(tag[1])) // unrecognized end tag
      +          ;
      +        else if (!head) // unrecognized tag so draw it
      +        {
      +          linew += (int)fl_width("<"); // add width of '<' char
      +          ptr = tagptr + 1; // start of tag + 1
      +        }
      +    } // if (*ptr == '<')
      +
      +    else if (*ptr == '\n' && pre) // '\n' in pre
      +    {
      +      linew = 0;
      +      needspace = 0;
      +      ptr ++;
      +    }
      +    else if (isspace((*ptr) & 255)) // ' ' '\t'\n'\v'\f'\r' chars
      +    {
      +      needspace = 1;
      +      ptr ++;
      +    }
      +    else if (*ptr == '&' && sp < (buf + sizeof(buf) - 1)) // '&' char ref
      +    {
      +      ptr ++;
      +      qch = quote_char(ptr);
      +
      +      if (qch < 0) // Not char ref
      +        *(sp ++) = '&'; // added ()
      +      else {
      +        *(sp ++) = qch; // added ()
      +        ptr = strchr(ptr, ';') + 1;
      +      }
      +    }
      +    else // Other char
      +    {
      +      if (sp < (buf + sizeof(buf) - 1))
      +        *(sp ++) = *(ptr ++); // added ()
      +      else
      +        ptr ++;
      +    }
      +  } // for (ptr = tp ...)
      +
      +  // Now that we have scanned the entire table,
      +  // adjust the table and cell widths to fit on the screen
      +  if (numcells == 0) return endp;
      +
      +  // colspan widths
      +  for (col = 0; col < numcells; col ++)
      +  {
      +    if (colspans[col] > 0) {  // check width of colspans
      +      colspanw = colspans[col]; // colspan width
      +      colspan = colspans[col + 1]; // colspan
      +
      +      for (ti = col; ti < col + colspan; ti ++)
      +        mincellw += mincols[ti]; // total width of mincols
      +
      +      if (colspans[col] > mincellw) { // pad columns with colspans
      +        for (ti = col, maxcellw = 0; ti < col + colspan; ti ++) {
      +          if (maxcols[ti] == 0) maxcols[ti] = 1; // set min width
      +          maxcellw += maxcols[ti]; // total width of cells
      +          colspanw -= mincols[ti]; // colspans remainder width
      +        }
      +        if (!maxcellw) maxcellw = 1; // avoid divide by zero
      +        for (ti = col; ti < col + colspan; ti ++) {
      +          tempw = (maxcols[ti] * 100) / maxcellw; // as percent
      +          scalew = (colspanw * tempw) / 100; // as value
      +          maxcols[ti] = mincols[ti] + scalew;
      +        }
      +      }
      +      col += colspan - 1; // skip past colspan
      +    }
      +  }
      +
      +  // get min width of table from colspans
      +  for (col = 0, mincellw = 0; col < numcells; col ++) {
      +    if (colspans[col] > 0) {
      +      mincellw += colspans[col]; // min table width
      +      col += colspans[col + 1] - 1; // skip past colspan
      +    }
      +    else
      +      mincellw += mincols[col];
      +  }
      +
      +  if (mincellw > hwidth) { // if table wider than window
      +    tsize = mincellw;
      +    tsize += 6 * numcells;
      +    tsize += xx + 4; // add 4 pixels in case width is hsize_
      +    if (tsize > hsize_) tsize = hsize_;
      +  }
      +  else
      +    tsize = hwidth;
      +
      +  tw = 0; // Reset
      +  if (get_attr(tp + 6, "WIDTH", attr, sizeof(attr)))
      +    tw = get_length(attr, tsize - xx);
      +
      +//printf("numcells = %d, tw = %d, tsize = %d\n", numcells, tw, tsize);
      +
      +  if (tw == 0) // get max table width
      +    maxlinew = tsize - xx;
      +  else
      +    maxlinew = tw;
      +
      +  maxlinew -= 6 * numcells; // sub internal borders
      +  tw -= 6 * numcells;
      +  if (tsize > hwidth) { // if table wider than window sub 4 pixels
      +    maxlinew -= 4; // this is needed
      +    tw -= 4;
      +  }
      +  if (tw < 0) tw = 0;
      +
      +//printf(" tw = %d, maxlinew = %d, xx = %d, hsize_ = %d, mincellw = %d\n",
      +//  tw, maxlinew, xx, hsize_, mincellw);
      +
      +  if (mincellw > maxlinew) // resize if colspans too wide
      +    tw = mincellw + xx;
      +
      +  for (col = 0, linew = 0; col < numcells; col ++)
      +    linew += maxcols[col]; // Add up the widths
      +  if (!linew) linew = 1; // avoid divide by zero
      +
      +//for (col = 0; col < numcells; col ++)
      +//  printf("    maxcols[%d] = %d, mincols[%d] = %d, widths[%d] = %d, colspans[%d] = %d\n",
      +//    col, maxcols[col], col, mincols[col],
      +//    col, widths[col], col, colspans[col]);
      +//printf("linew = %d, w() = %d\n", linew, w());
      +
      +  scalew = tw;
      +  if (tw == 0) { // Adjust the width if needed
      +    if (linew > maxlinew)
      +      scalew = maxlinew;
      +    else
      +      scalew = linew;
      +  }
      +
      +  if (linew < scalew) // Table width is too small
      +  {
      +
      +//printf("Scaling table up to scalew %d from linew %d\n", scalew, linew);
      +
      +    scalew -= linew; // get remainder width
      +
      +//printf("adjusted scalew = %d\n", scalew);
      +
      +    // scale table up
      +    for (col = 0; col < numcells; col ++) {
      +      tempw = (maxcols[col] * 100) / linew; // as percent
      +      maxcols[col] += (tempw * scalew) / 100; // as value
      +    }
      +
      +    // td widths
      +    for (col = 0, ti = 0, tempw = 0; col < numcells; col ++) {
      +      if (widths[col] > 0 && mincols[col] > widths[col]) {
      +        tempw += maxcols[col] - mincols[col]; // remainder
      +        maxcols[col] = mincols[col]; // set to minwidth
      +      }
      +      if (!widths[col]) ti ++; // unspecified widths
      +    }
      +    if (!ti) ti = 1; // avoid divide by zero
      +    for (col = 0; col < numcells; col ++) {
      +      if (!widths[col])
      +        maxcols[col] += tempw / ti; // add remainder fractions
      +    }
      +  }
      +  else if (linew > scalew) // Table width is too big
      +  {
      +
      +//printf("Scaling table down to scalew %d from linew %d\n", scalew, linew);
      +
      +    for (col = 0; col < numcells; col ++) {
      +      linew -= mincols[col];
      +      scalew -= mincols[col];
      +    }
      +    if (!linew) linew = 1; // avoid divide by zero
      +
      +//printf("adjusted linew = %d, scalew = %d\n", linew, scalew);
      +
      +      for (col = 0; col < numcells; col ++) {
      +        maxcols[col] -= mincols[col];
      +        maxcols[col] = scalew * maxcols[col] / linew;
      +        maxcols[col] += mincols[col];
      +      }
      +  }
      +  else if (tw == 0) // Not sure if this is needed
      +    tw = linew;
      +
      +  if (tw == 0) // tw still zero
      +    for (col = 0; col < numcells; col ++)
      +      tw += maxcols[col];
      +
      +  for (col = 0, maxcellw = 0; col < numcells; col ++)
      +    maxcellw += maxcols[col]; // total width of cells
      +
      +  if (tw > maxcellw) { // add remainder to last column
      +    tempw = tw - maxcellw;
      +    maxcols[numcells - 1] += tempw;
      +  }
      +
      +//printf("FINAL tw = %d\n", tw);
      +//for (col = 0; col < numcells; col ++)
      +//  printf("    maxcols[%d] = %d\n", col, maxcols[col]);
      +
      +  return endp; // table end pointer
      +
      +} // Fl_Help_View::format_table()
      +
      +//
      +// Fl_Help_View::free_data() - Free memory used for the document.
      +//
      +
      +void Fl_Help_View::free_data()
      +{
      +  if (value_) // Release all images
      +  {
      +    const char *ptr, // Pointer into block
      +      *attrptr; // Start of attributes ptr
      +    char *sp, // Pointer into buffer
      +      buf[1024], // Text buffer
      +      attr[1024], // Attribute buffer
      +      wattr[1024], // Width attribute buffer
      +      hattr[1024]; // Height attribute buffer
      +    Fl_Shared_Image *img = 0; // Shared image - rem'd NULL
      +    int imgw = 0, // Image width
      +      imgh = 0; // Image height
      +
      +    for (ptr = value_; *ptr; )
      +    {
      +      if (*ptr == '<')
      +      {
      +        ptr ++;
      +
      +        if (!strncmp(ptr, "!--", 3)) { // Found "!--"
      +          ptr += 3;
      +          if ((ptr = strstr(ptr, "-->"))) { // Skip comment - rem'd != 0
      +            ptr += 3;
      +            continue;
      +          }
      +          else
      +            break;
      +        }
      +
      +        sp = buf;
      +
      +        while (*ptr && *ptr != '>' && !isspace((*ptr) & 255))
      +          if (sp < (buf + sizeof(buf) - 1))
      +            *(sp ++) = *(ptr ++); // added ()
      +          else
      +            ptr ++;
      +
      +        *sp = '\0'; // Nul-terminate
      +
      +        attrptr = ptr; // Start of attributes
      +        while (*ptr && *ptr != '>') ptr ++;
      +        if (*ptr == '>') ptr ++;
      +
      +        if (!strcasecmp(buf, "IMG"))
      +        {
      +          imgw = imgh = 0; // reset
      +          if (get_attr(attrptr, "WIDTH", wattr, sizeof(wattr)))
      +            imgw = get_length(wattr);
      +          if (get_attr(attrptr, "HEIGHT", hattr, sizeof(hattr)))
      +            imgh = get_length(hattr);
      +
      +          img = 0; // rem'd NULL
      +          if (get_attr(attrptr, "SRC", attr, sizeof(attr)))
      +          { // Release the image twice to free it from memory
      +            img = get_image(attr, imgw, imgh);
      +            // Seb was here - freeing a broken_image causes an XFreePixmap crash
      +            if((void*)img != &broken_image) {
      +              img->release();
      +              if(img->refcount() > 0) img->release();
      +            }
      +          }
      +        }
      +      } // if (*ptr == '<')
      +      else
      +        ptr ++;
      +    } // for (ptr = value_ ...)
      +
      +    free((void *)value_);
      +    value_ = 0; // reset
      +
      +  } // if (value_)
      +  
      +  if (!d->isnew) { // is new page
      +    free((void *)d->csstext); // values
      +    free((void *)d->cssword);
      +    free((void *)d->cssurl);
      +    d->csstext = 0;
      +    d->cssword = 0;
      +    d->cssurl = 0;
      +    d->cssurllen = 0; // lengths
      +    d->csswordlen = 0;
      +    d->csstextlen = 0;
      +    serifont_ = FL_TIMES; // default font
      +  }
      +  d->isnew = 1; // set
      +  
      +  // Free all of the arrays
      +  if (nblocks_) { // Free blocks
      +    free(blocks_);
      +    ablocks_ = 0;
      +    nblocks_ = 0;
      +    blocks_ = 0;
      +  }
      +
      +  if (nlinks_) { // Free links
      +    free(links_);
      +    alinks_ = 0;
      +    nlinks_ = 0;
      +    links_ = 0;
      +  }
      +
      +  if (ntargets_) { // Free targets
      +    free(d->targets);
      +    atargets_ = 0;
      +    ntargets_ = 0;
      +    d->targets = 0;
      +  }
      +
      +} // Fl_Help_View::free_data()
      +
      +//
      +// Fl_Help_View::get_align() - Get an alignment attribute.
      +//
      +
      +int // O - Alignment
      +Fl_Help_View::get_align(const char *ap, // I - Start of attrs pointer
      +                        int da) // I - Default alignment
      +{
      +  char buf[255]; // Alignment value
      +
      +  if (!get_attr(ap, "ALIGN", buf, sizeof(buf))) // rem'd == 0
      +    return da; // no align attribute
      +
      +  if (!strcasecmp(buf, "CENTER"))
      +    return CENTER; // 0
      +  else if (!strcasecmp(buf, "RIGHT"))
      +    return RIGHT; // -1
      +  else
      +    return LEFT; // 1
      +
      +} // Fl_Help_View::get_align()
      +
      +//
      +// Fl_Help_View::get_attr() - Get an attribute value from the string.
      +//
      +
      +const char * // O - Pointer to buf or NULL
      +Fl_Help_View::get_attr(const char *ap, // I - Start of attributes pointer
      +                       const char *np, // I - Name of attribute
      +                       char *buf, // O - Buffer for attribute value
      +                       int sb) // I - Sizeof buf
      +{
      +  char name[255], // Name from string
      +    *ptr, // Pointer into name or value
      +    quote; // Quote char
      +
      +  buf[0] = '\0';
      +
      +  while (*ap && *ap != '>')
      +  {
      +    while (isspace((*ap) & 255)) ap ++;
      +
      +    if (*ap == '>' || !*ap) return 0; // rem'd NULL
      +
      +    for (ptr = name; *ap && !isspace((*ap) & 255) && *ap != '=' && *ap != '>'; )
      +      if (ptr < (name + sizeof(name) - 1)) // Read in the attribute name
      +        *(ptr ++) = *(ap ++); // added ()
      +      else
      +        ap ++;
      +
      +    *ptr = '\0';
      +
      +    if (isspace((*ap) & 255) || !*ap || *ap == '>')
      +      buf[0] = '\0';
      +    else
      +    {
      +      if (*ap == '=') ap ++;
      +
      +      for (ptr = buf; *ap && !isspace((*ap) & 255) && *ap != '>'; )
      +        if (*ap == '\'' || *ap == '\"') { // Read in the attribute value
      +        quote = *(ap ++); // added () same as quote=*ap;ap++;
      +
      +        while (*ap && *ap != quote)
      +          if ((ptr - buf + 1) < sb) // Sizeof buf
      +            *(ptr ++) = *(ap ++); // added () same as *ptr=*ap;ptr++;ap++;
      +          else
      +            ap ++;
      +
      +        if (*ap == quote) ap ++;
      +      }
      +      else if ((ptr - buf + 1) < sb) // Sizeof buf
      +        *(ptr ++) = *(ap ++); // added ()
      +      else
      +        ap ++;
      +
      +      *ptr = '\0';
      +    }
      +
      +    if (!strcasecmp(np, name)) // Name of attribute matches
      +      return buf;
      +    else
      +      buf[0] = '\0';
      +
      +    if (*ap == '>') return 0; // rem'd NULL
      +  } // while (*ap ...)
      +
      +  return 0; // rem'd NULL
      +
      +} // Fl_Help_View::get_attr()
      +
      +//
      +// Fl_Help_View::get_color() - Get an alignment attribute.
      +//
      +
      +Fl_Color // O - Color value
      +Fl_Help_View::get_color(const char *np, // I - Color name
      +                        Fl_Color dc) // I - Default color value
      +{
      +  int ti = 0, // Looping var
      +    rgb = 0, red = 0, green = 0, blue = 0, // RGB values
      +    temp = 0; // temp var
      +
      +  static const struct { // Color name table
      +    const char *name;
      +    int r, g, b; // Red, green, blue
      +  }
      +  colors[] = {
      +    { "black",   0x00, 0x00, 0x00 },
      +    { "red",     0xff, 0x00, 0x00 },
      +    { "green",   0x00, 0x80, 0x00 },
      +    { "yellow",  0xff, 0xff, 0x00 },
      +    { "blue",    0x00, 0x00, 0xff },
      +    { "magenta", 0xff, 0x00, 0xff },
      +    { "fuchsia", 0xff, 0x00, 0xff },
      +    { "cyan",    0x00, 0xff, 0xff },
      +    { "aqua",    0x00, 0xff, 0xff },
      +    { "white",   0xff, 0xff, 0xff },
      +    { "gray",    0x80, 0x80, 0x80 },
      +    { "grey",    0x80, 0x80, 0x80 },
      +    { "lime",    0x00, 0xff, 0x00 },
      +    { "maroon",  0x80, 0x00, 0x00 },
      +    { "navy",    0x00, 0x00, 0x80 },
      +    { "olive",   0x80, 0x80, 0x00 },
      +    { "purple",  0x80, 0x00, 0x80 },
      +    { "silver",  0xc0, 0xc0, 0xc0 },
      +    { "teal",    0x00, 0x80, 0x80 }
      +  };
      +
      +  if (!np || !np[0]) return dc; // No name
      +
      +  if (np[0] != '#') // check no hash
      +    for (ti = 0, rgb = 0; np[ti] != '\0'; ti ++) {
      +      if (isalpha(np[ti])) rgb |= 1; // name if 1
      +      if (isdigit(np[ti])) rgb |= 2; // decimal if 2
      +      if (rgb == 3) break; // hex with no hash
      +  }
      +
      +  if (np[0] == '#' || rgb == 3) // Do hex color lookup
      +  {
      +    if (rgb == 3) temp = 0; else temp = 1; // set name offset
      +    rgb = strtol(np + temp, 0, 16); // rem'd NULL
      +
      +    if (strlen(np) > 4) { // 24-bit
      +      red = rgb >> 16;
      +      green = (rgb >> 8) & 255;
      +      blue = rgb & 255;
      +    }
      +    else { // 16-bit?
      +      red = (rgb >> 8) * 17;
      +      green = ((rgb >> 4) & 15) * 17;
      +      blue = (rgb & 15) * 17;
      +    }
      +    return fl_rgb_color((uchar)red, (uchar)green, (uchar)blue);
      +  }
      +  else // Do color name lookup
      +  {
      +    temp = sizeof(colors) / sizeof(colors[0]);
      +    for (ti = 0; ti < temp; ti ++)
      +      if (!strcasecmp(np, colors[ti].name)) {
      +        return fl_rgb_color(colors[ti].r, colors[ti].g, colors[ti].b);
      +      }
      +    return dc; // Color not found
      +  }
      +
      +} // Fl_Help_View::get_color()
      +
      +//
      +// Fl_Help_View::get_css_value() - Outputs the value of a given css property to buffer.
      +//
      +
      +int // O - true if value exists, false otherwise
      +Fl_Help_View::get_css_value(const char *sp, // I - selector
      +                          const char *pp, // I - property
      +                          char *vp) // O - value
      +{
      +  int ti = 0, tj = 0, tk = 0, tword = 0, tcount = 0, // temp vars
      +    issel = 0, isblock = 0, isclass = 0, order = 0, // misc vars
      +    si = 0, slen = 0, plen = 0, blen = 0, vlen = 0;
      +  char *tp = 0; // ptr
      +
      +  if (strchr(pp, '-')) blen = strchr(pp, '-') - pp; // base property length
      +  plen = strlen(pp); // property length
      +  slen = strlen(sp); // selector length
      +  if (strstr(sp, ".")) isclass = 1; // class ptr
      +  
      +  while (tk < 2) { // find selector
      +  
      +    for (ti = 0; ti < d->csswordlen; ti ++) { // word loop
      +      tword = *(d->cssword + ti); // word offset
      +      tp = d->csstext + tword; // word ptr
      +      if (isblock && *tp == '}') { issel = 0; isblock = 0; break; } // close block
      +      
      +      if (isblock) {
      +        if (!strncasecmp(tp, pp, plen)) { // full property
      +          for (tj = *(d->cssword + ti + 1); tcount < 255; tj ++) { // value is next word
      +            if (*(d->csstext + tj) == ';') break; // end of value
      +            else {
      +              *(vp + tcount) = *(d->csstext + tj); // copy value
      +              tcount ++; // count word length
      +            }
      +          }
      +          *(vp + tcount) = '\0'; // nul-terminate
      +          return 1; // success
      +        }
      +        else if (blen) { // base property
      +          if (!strncasecmp(tp, pp, blen) && !si) si = ti; // store index
      +        }
      +      }
      +      
      +      if (issel && *tp == '{') isblock = 1; // open block
      +      if (!isblock && !strncasecmp(tp, sp, slen)) {
      +        if (isclass) // source has class
      +          issel = 2; // found match
      +        else if (*(tp + slen) != '.')
      +          issel = 1; // match if target no class
      +      }
      +    }
      +    
      +    if (!issel && isclass) { // class not found, find selector
      +      slen = strstr(sp, ".") - sp; // remove class name
      +      isclass = 0; // reset
      +    }
      +      
      +    tk ++; // second try without class name
      +  }
      +
      +  if (si) { // found base but not full property
      +    for (tj = *(d->cssword + si + 1); tcount < 255; tj ++) { // value is next word
      +      if (*(d->csstext + tj) == ';') break; // end of value
      +      else {
      +        *(vp + tcount) = *(d->csstext + tj); // copy value
      +        if (isspace(*(vp + tcount))) *(vp + tcount) = '\0'; // split words
      +        tcount ++; // count word length
      +      }
      +    }
      +    *(vp + tcount) = '\0'; // nul-terminate
      +    
      +    for (tj = 0, ti = 0; tj < tcount; tj ++) { // shorthand recognition rules
      +      if (*(vp + tj) == '\0') ti = 0; else ti ++;
      +      if (ti == 1) { // first letter of word
      +        vlen = strlen(vp + tj); // word length
      +        if (!strncasecmp(pp, "background", 10)) // background shorthand
      +        {
      +          if (!strncasecmp(vp + tj, "none", 4) ||
      +              !strncasecmp(vp + tj, "left", 4) ||
      +              !strncasecmp(vp + tj, "right", 5) ||
      +              !strncasecmp(vp + tj, "inherit", 7)) order = 0; // nothing
      +          else if (*(vp + tj) == '#' ||
      +                   !strncasecmp(vp + tj, "rgb", 3) ||
      +                   !strncasecmp(vp + tj, "transparent", 11)) order = 1; // color
      +          else if (!strncasecmp(vp + tj, "url", 3)) order = 2; // image
      +          else if (!strncasecmp(vp + tj, "repeat", 6) ||
      +                   !strncasecmp(vp + tj, "no-repeat", 9)) order = 3; // repeat
      +          else if (!strncasecmp(vp + tj, "scroll", 6) ||
      +                   !strncasecmp(vp + tj, "fixed", 5)) order = 4; // attachment
      +          else if (isdigit(*(vp + tj)) ||
      +                   !strncasecmp(vp + tj, "top", 3) ||
      +                   !strncasecmp(vp + tj, "center", 6) ||
      +                   !strncasecmp(vp + tj, "bottom", 6)) { // position
      +            // todo: count words to ; if one then replace \0 with ' ' - or just replace next '\0'
      +            order = 5; }
      +          else if (!strncasecmp(vp + tj, "black", 5) ||
      +                   !strncasecmp(vp + tj, "red", 3) ||
      +                   !strncasecmp(vp + tj, "green", 5) ||
      +                   !strncasecmp(vp + tj, "yellow", 6) ||
      +                   !strncasecmp(vp + tj, "blue", 4) ||
      +                   !strncasecmp(vp + tj, "magenta", 7) ||
      +                   !strncasecmp(vp + tj, "fuchsia", 7) ||
      +                   !strncasecmp(vp + tj, "cyan", 4) ||
      +                   !strncasecmp(vp + tj, "aqua", 4) ||
      +                   !strncasecmp(vp + tj, "white", 5) ||
      +                   !strncasecmp(vp + tj, "gray", 4) ||
      +                   !strncasecmp(vp + tj, "grey", 4) ||
      +                   !strncasecmp(vp + tj, "lime", 4) ||
      +                   !strncasecmp(vp + tj, "maroon", 6) ||
      +                   !strncasecmp(vp + tj, "navy", 4) ||
      +                   !strncasecmp(vp + tj, "olive", 5) ||
      +                   !strncasecmp(vp + tj, "purple", 6) ||
      +                   !strncasecmp(vp + tj, "silver", 6) ||
      +                   !strncasecmp(vp + tj, "teal", 4)) order = 1; // color name
      +          if (!strncmp(pp, "background-color", 16) && order == 1) break;
      +          if (!strncmp(pp, "background-image", 16) && order == 2) break;
      +          if (!strncmp(pp, "background-repeat", 17) && order == 3) break;
      +          if (!strncmp(pp, "background-attachment", 21) && order == 4) break;
      +          if (!strncmp(pp, "background-position", 19) && order == 5) break;
      +          order = 0; // reset
      +        }
      +        else if (!strncasecmp(pp, "border", 6)) // border shorthand
      +        {
      +          // todo: border-width-style-color
      +        }
      +        else if (!strncasecmp(pp, "font", 4)) // font shorthand
      +        {
      +          if (isdigit(*(vp + tj))) { // number
      +            if (vlen == 3 && isdigit(*(vp + tj + 2))) order = 3; // weight
      +            else order = 4; // size
      +          }
      +          else if (isalpha(*(vp + tj))) { // word
      +            if (!strncasecmp(vp + tj, "normal", 6) ||
      +                !strncasecmp(vp + tj, "lighter", 7) || // weight
      +                !strncasecmp(vp + tj, "inherit", 7)) order = 0; // nothing
      +            else if (!strncasecmp(vp + tj, "italic", 6) ||
      +                     !strncasecmp(vp + tj, "oblique", 7)) order = 1; // style
      +            else if (!strncasecmp(vp + tj, "small-caps", 10)) order = 2; // variant
      +            else if (!strncasecmp(vp + tj, "bold", 4)) order = 3; // weight
      +            else if (!strncasecmp(vp + tj, "x-", 2) ||
      +                     !strncasecmp(vp + tj, "xx-", 3) ||
      +                     !strncasecmp(vp + tj, "small", 5) ||
      +                     !strncasecmp(vp + tj, "medium", 6) ||
      +                     !strncasecmp(vp + tj, "large", 5)) order = 4; // size
      +            else order = 5; // family
      +          }
      +          if (!strncmp(pp, "font-style", 10) && order == 1) break;
      +          if (!strncmp(pp, "font-variant", 12) && order == 2) break;
      +          if (!strncmp(pp, "font-weight", 11) && order == 3) break;
      +          if (!strncmp(pp, "font-size", 9) && order == 4) break;
      +          if (!strncmp(pp, "font-family", 11) && order == 5) break;
      +          order = 0; // reset
      +        }
      +        else if (!strncasecmp(pp, "margin", 6) ||
      +                 !strncasecmp(pp, "padding", 7)) // margin/padding shorthand
      +        {
      +          // todo: margin-top-right-bottom-left - padding has same keywords
      +        }
      +        else if (!strncasecmp(pp, "outline", 7)) // outline shorthand
      +        {
      +          // todo: outline-color-style-width
      +        }
      +      }
      +    }
      +    
      +    if (order && tj) { // copy word to start of buffer
      +      for (ti = 0; ti < vlen; ti ++) *(vp + ti) = *(vp + tj + ti);
      +      *(vp + vlen) = '\0'; // nul-terminate
      +    }
      +    return 1; // success
      +  }
      +  
      +  return 0; // failure
      +  
      +} // Fl_Help_View::get_css_value
      +
      +//
      +// Fl_Help_View::get_font_size() - Get a height value for font-size.
      +//
      +
      +int // O - height value
      +Fl_Help_View::get_font_size(const char *hp) // I - height pointer
      +{
      +  int ti = 0, // temp var
      +    upos = 0, // unit position - %,in,cm,mm,em,ex,pt,pc,px
      +    slen = 0, // src length
      +    val = 0; // integer value
      +  char buf[8]; // buffer
      +  
      +  if (!hp || !hp[0]) return 0; // no height
      +
      +  slen = strlen(hp);
      +  if (slen > 8) slen = 8; // max length
      +  for (val = 0; val < slen; val ++) {
      +    if (isalpha(*(hp + val)) || *(hp + val) == '%') {
      +      upos = val;
      +      break; // unit position
      +    }
      +  }
      +  if (!upos) val = slen; // no unit
      +  for (ti = 0; ti < val; ti ++)
      +    buf[ti] = *(hp + ti); // copy value to buffer
      +    
      +  val = atoi(buf); // to int
      +  if (*(hp + upos) == '%') { // percent
      +    if (val > 100) val = 100;
      +    else if (val < 0) val = 0;
      +    val = (val * fontsize_) / 100;
      +  }
      +  else if (!strncmp(hp + upos, "em", 2)) // em
      +    val = val * fontsize_;
      +  else if (!strncasecmp(hp + upos, "ex", 2)) // ex
      +    val = fontsize_ / val;
      +  // note: pt, pica, cm, mm, in are all relative to screen size
      +  // currently they equate to px - http://hsivonen.iki.fi/units
      +  
      +  if (val > 48) val = 48; // max
      +  else if (val < 8) val = 8; // min
      +  return val;
      +  
      +} // Fl_Help_View::get_font_size()
      +
      +//
      +// Fl_Help_View::get_image() - Get an inline image.
      +//
      +
      +Fl_Shared_Image * // O - Image pointer
      +Fl_Help_View::get_image(const char *np, // Image filename
      +                        int iw, // Image width
      +                        int ih) // Image height
      +{
      +  const char *namep; // Local filename
      +  char dir[1024], // Current directory
      +    temp[1024], // Temporary filename
      +    *tptr, *dirp; // Pointer into temporary name
      +  Fl_Shared_Image *imgp; // Image pointer
      +
      +  // See if the image can be found
      +  if (strchr(directory_, ':') && !strchr(np, ':')) // rem'd != 0 and == 0
      +  { // dir has ':' char and np doesn't
      +    if (np[0] == '/') { // Has sub-path
      +      strlcpy(temp, directory_, sizeof(temp));
      +      if ((tptr = strrchr(strchr(temp, ':') + 3, '/')) != 0) // ?
      +        strlcpy(tptr, np, sizeof(temp)-(tptr - temp)); // ?
      +      else // ? - dir shouldn't have a filename..
      +        strlcat(temp, np, sizeof(temp));
      +    }
      +    else // Just filename
      +      snprintf(temp, sizeof(temp), "%s/%s", directory_, np);
      +
      +    if (link_)
      +      namep = (*link_)(this, temp);
      +    else
      +      namep = temp;
      +  }
      +  else if (np[0] != '/' && !strchr(np, ':')) // rem'd == 0
      +  {
      +    if (directory_[0])
      +      snprintf(temp, sizeof(temp), "%s/%s", directory_, np);
      +    else {
      +      dirp = getcwd(dir, sizeof(dir)); // No end '/' char - can be wrong..
      +      snprintf(temp, sizeof(temp), "%s/%s", dir, np);
      +    }
      +
      +    if (link_)
      +      namep = (*link_)(this, temp);
      +    else
      +      namep = temp;
      +  }
      +  else if (link_)
      +    namep = (*link_)(this, np);
      +  else
      +    namep = np;
      +
      +//if (namep) printf(" get_image namep=(%s)\n",namep);
      +//printf(" get_image d->path=(%s)\n",d->path);
      +
      +  if (d->ispath) { // path is used
      +    strlcpy(temp, d->path, sizeof(temp));
      +    if ((tptr = strrchr(temp, '/'))) // tptr valid, add filename
      +      strlcpy(tptr + 1, np, sizeof(temp)-(tptr + 1 - temp));
      +    namep = temp;
      +  }
      +
      +  if (!namep) return 0;
      +
      +  if (!strncmp(namep, "file:", 5)) namep += 5; // Adjust for file:
      +
      +  if (!(imgp = Fl_Shared_Image::get(namep, iw, ih))) // rem'd == 0
      +    imgp = (Fl_Shared_Image *)&broken_image;
      +
      +  return imgp;
      +
      +} // Fl_Help_View::get_image()
      +
      +//
      +// Fl_Help_View::get_length() - Get a length value either absolute or %.
      +//
      +
      +int // O - Length value
      +Fl_Help_View::get_length(const char *lp) // I - Length pointer
      +{
      +  int val = 0; // Integer value
      +
      +  if (!lp || !lp[0]) return 0; // No length
      +
      +  val = atoi(lp);
      +  if (lp[strlen(lp) - 1] == '%') { // Calc percent
      +    if (val > 100) val = 100;
      +    else if (val < 0) val = 0;
      +    val = val * (hsize_ - Fl::scrollbar_size()) / 100; // val from hsize_
      +  }
      +
      +  return val;
      +
      +} // Fl_Help_View::get_length()
      +
      +//
      +// Fl_Help_View::get_length() - Get a length value of a given width.
      +//
      +
      +int // O - Length value
      +Fl_Help_View::get_length(const char *lp, // I - Length pointer
      +                         int hw) // I - horizontal width
      +{
      +  int val = 0; // Integer value
      +
      +  if (!lp || !lp[0]) return 0; // No length
      +
      +  val = atoi(lp);
      +  if (lp[strlen(lp) - 1] == '%') { // Calc percent
      +    if (val > 100) val = 100;
      +    else if (val < 0) val = 0;
      +    val = val * hw / 100; // get value from hw
      +  }
      +
      +  return val;
      +
      +} // Fl_Help_View::get_length()
      +
      +//
      +// Fl_Help_View::gettopline() - Get current topline in document.
      +//
      +
      +int Fl_Help_View::gettopline() // O - Current topline
      +{
      +  return d->top;
      +}
      +
      +//
      +// Fl_Help_View::handle() - Handle events in the widget.
      +//
      +
      +int // O - True if we handled it, false otherwise
      +Fl_Help_View::handle(int event) // I - Event to handle
      +{
      +  int xx = 0, yy = 0, // Mouse positions
      +    hh = 0; // window height
      +  Fl_Boxtype bt = (box()) ? box() : FL_DOWN_BOX; // Box type
      +
      +  xx = Fl::event_x() - x() + leftline_; // Get mouse
      +  yy = Fl::event_y() - y() + topline_;
      +
      +  if (d->resized && !Fl::event_buttons()) { // mouse up outside window
      +    d->resized = 0; // reset d->resized
      +    format(); // make sure text is wrapped to window
      +  }
      +
      +  switch (event)
      +  {
      +    case FL_FOCUS: // Set keyboard focus
      +      redraw(); // Set widget to draw
      +      return 1;
      +
      +    case FL_UNFOCUS: // Reset keyboard focus
      +      clear_selection(); // Clear text selection
      +      redraw(); // Set widget to draw
      +      return 1;
      +
      +    case FL_ENTER : // Mouse pointer entered widget
      +      Fl_Group::handle(event);
      +      return 1;
      +
      +    case FL_LEAVE : // Mouse pointer left widget
      +      d->top = topline(); // set top
      +      fl_cursor(FL_CURSOR_DEFAULT); // Default icon, usually arrow
      +      break;
      +
      +    case FL_MOVE: // Mouse pointer was moved with no button pushed
      +      hh = h() + topline_ - Fl::box_dy(bt); // get bottom of window
      +      if (hscrollbar_.visible()) hh -= Fl::scrollbar_size();
      +      if (yy > hh) hh = -1; // mouse over hscrollbar so no active link
      +      if (find_link(xx, yy) && hh > 0) // mouse y in bounds
      +        fl_cursor(FL_CURSOR_HAND); // Hand icon
      +      else
      +        fl_cursor(FL_CURSOR_DEFAULT);
      +      return 1;
      +
      +    case FL_PUSH: // Mouse button was pushed
      +      if (Fl_Group::handle(event)) return 1;
      +      d->linkp = find_link(xx, yy);
      +      if (d->linkp) {
      +        d->ispush = 1; // set link is pushed
      +        fl_cursor(FL_CURSOR_HAND);
      +        return 1;
      +      }
      +      if (begin_selection()) {
      +        fl_cursor(FL_CURSOR_INSERT); // I-beam icon
      +        return 1;
      +      }
      +      fl_cursor(FL_CURSOR_DEFAULT);
      +      return 1;
      +
      +    case FL_DRAG: // Mouse pointer was moved with button pushed
      +      if (d->ispush) { // link is pushed
      +        if (Fl::event_is_click()) {
      +          fl_cursor(FL_CURSOR_HAND);
      +        } else {
      +          fl_cursor(FL_CURSOR_DEFAULT); // Should be "FL_CURSOR_CANCEL" if we had it
      +        }
      +        return 1;
      +      }
      +      if (current_view == this && selection_push_last) {
      +        if (extend_selection()) redraw(); // Set widget to draw
      +        fl_cursor(FL_CURSOR_INSERT);
      +        return 1;
      +      }
      +      fl_cursor(FL_CURSOR_DEFAULT);
      +      return 1;
      +
      +    case FL_RELEASE: // Mouse button was released
      +      if (d->ispush) { // link is pushed
      +        if (Fl::event_is_click()) {
      +          d->top = topline(); // set top
      +          d->islink = 1; // set islink
      +          follow_link(d->linkp);
      +        }
      +        fl_cursor(FL_CURSOR_DEFAULT);
      +        d->ispush = 0; // reset link is pushed - was d->linkp = 0;
      +        return 1;
      +      }
      +      if (current_view == this && selection_push_last) {
      +        end_selection();
      +        return 1;
      +      }
      +      return 1;
      +
      +    case FL_SHORTCUT: { // Shortcut key was pushed
      +      char ascii = Fl::event_text()[0];
      +      switch (ascii) {
      +        case CTRL('A'): select_all(); redraw(); return 1; // Set widget to draw
      +        case CTRL('C'):
      +        case CTRL('X'): end_selection(1); return 1;
      +      }
      +      break; }
      +  }
      +
      +  return Fl_Group::handle(event);
      +
      +} // Fl_Help_View::handle()
      +
      +//
      +// Fl_Help_View::hv_draw() - Draws text.
      +//
      +// Note: This function must be optimized for speed!
      +
      +void Fl_Help_View::hv_draw(const char *tp, // I - Text to draw
      +                           int xx, // I - X position of text
      +                           int yy) // I - Y position of text
      +{
      +  int width = 0, // Width of text
      +    first = 0, // First selected position
      +    last = 0; // Last selected position
      +
      +  if (selected && current_view == this &&
      +      current_pos < selection_last &&
      +      current_pos >= selection_first) { // Selected text
      +    Fl_Color clr = fl_color();
      +    fl_color(hv_selection_color);
      +    width = (int)fl_width(tp);
      +    if (current_pos + (int)strlen(tp) < selection_last)
      +      width += (int)fl_width(" ");
      +    fl_rectf(xx, yy + fl_descent() - fl_height(), width, fl_height());
      +    fl_color(hv_selection_text_color);
      +    fl_draw(tp, xx, yy);
      +    fl_color(clr);
      +  }
      +  else { // Normal text
      +    fl_draw(tp, xx, yy);
      +  }
      +
      +  if (draw_mode) // Text is being selected
      +  {
      +    width = (int)fl_width(tp);
      +    if (mouse_x >= xx && mouse_x < xx + width) {
      +      if (mouse_y >= yy - fl_height() + fl_descent() &&
      +          mouse_y <= yy + fl_descent()) {
      +        first = current_pos;
      +        // use 'quote_char' to calculate true length of HTML string
      +        last = first + strlen(tp);
      +        if (draw_mode == 1) { // Begin selection mode
      +          selection_push_first = first;
      +          selection_push_last = last;
      +        }
      +        else { // End selection mode
      +          selection_drag_first = first;
      +          selection_drag_last = last;
      +        }
      +      }
      +    }
      +  }
      +
      +} // Fl_Help_View::hv_draw()
      +
      +//
      +// Fl_Help_View::initfont() - Initialize font stack.
      +//
      +
      +void Fl_Help_View::initfont(int &fi, 
      +                            unsigned char &fs) { // reset stack
      +	d->nfonts = 0;
      +	fl_font(fi = d->fonts[0][0] = serifont_, fs = d->fonts[0][1] = fontsize_);
      +}
      +
      +//
      +// Fl_Help_View::leftline() - Set the left line position.
      +//
      +
      +void Fl_Help_View::leftline(int xx) // I - Left line position
      +{
      +  if (!value_) return;
      +
      +  if (hsize_ < w() - Fl::scrollbar_size() || xx < 0)
      +    xx = 0;
      +  else if (xx > hsize_)
      +    xx = hsize_;
      +
      +  leftline_ = xx;
      +  hscrollbar_.value(leftline_, w() - Fl::scrollbar_size(), 0, hsize_);
      +  redraw(); // Set widget to draw
      +
      +} // Fl_Help_View::leftline()
      +
      +//
      +// Fl_Help_View::load() - Load the specified file.
      +//
      +
      +int // O - 0 on success, -1 on error
      +Fl_Help_View::load(const char *fp) // I - File to load, may have target
      +{
      +  FILE *filep; // File to read from
      +  size_t fsize; // file size
      +  long len = 0; // Length of file
      +  char *target, // Target in file
      +    *slash; // Directory separator
      +  const char *namep; // Local filename
      +  char error[1024]; // Error buffer
      +  char newname[1024]; // New filename buffer
      +
      +  clear_selection(); // Clear text selection
      +  strlcpy(newname, fp, sizeof(newname));
      +  if ((target = strrchr(newname, '#'))) // Last '#' char - rem'd != 0
      +    *(target ++) = '\0'; // Remove target - added ()
      +
      +  if (link_)
      +    namep = (*link_)(this, newname); // Link transform
      +  else
      +    namep = filename_; // Current filename
      +
      +//printf(" load namep=(%s) d->nstyle=%d\n",namep,d->nstyle);
      +
      +  if (!(d->nstyle & HV_NONAVIGATE)) // user navigation, continue load
      +    namep = newname;
      +  if (!newname[0]) // avoid error
      +    strlcpy(newname, "(null)", sizeof(newname));
      +
      +  if (!namep) return -1; // No file was loaded, fail
      +
      +  if (!strncmp(newname, "ftp:", 4) || !strncmp(newname, "http:", 5) ||
      +      !strncmp(newname, "https:", 6) || !strncmp(newname, "ipp:", 4) ||
      +      !strncmp(newname, "mailto:", 7) || !strncmp(newname, "news:", 5))
      +    return -1; // last path is remote link, fail
      +
      +  if (!d->ispath) { // path not used
      +    strlcpy(d->lpath, filename_, sizeof(d->lpath)); // last path
      +    strlcpy(filename_, newname, sizeof(filename_)); // dir + filename
      +    strlcpy(directory_, newname, sizeof(directory_)); // dir, no end '/'
      +  }
      +
      +  // Note: We do not support Windows backslashes,
      +  // since they are illegal in URLs
      +  if (!(slash = strrchr(directory_, '/'))) // rem'd == 0
      +    directory_[0] = '\0'; // No '/' char
      +  else if (slash > directory_ && slash[-1] != '/')
      +    *slash = '\0'; // Remove filename, assumes filename exists
      +
      +  //if (value_) { free((void *)value_); value_ = 0; } // rem'd
      +  free_data(); // free last document
      +
      +  if (!strncmp(namep, "ftp:", 4) || !strncmp(namep, "http:", 5) ||
      +      !strncmp(namep, "https:", 6) || !strncmp(namep, "ipp:", 4) ||
      +      !strncmp(namep, "mailto:", 7) || !strncmp(namep, "news:", 5))
      +  { // Remote link
      +    snprintf(error, sizeof(error),
      +             "Error - %s"
      +             "

      Error - %s

      " + "

      Unable to find the address at %s

      " + "

    • No handler exists for this URI scheme
    • ", + strerror(errno), strerror(errno), namep, namep); + value_ = strdup(error); // Duplicate + } + else // Local link + { + if (!strncmp(namep, "file:", 5)) namep += 5; // Adjust for file: + + if ((filep = fopen(namep, "rb"))) { // Binary - rem'd != 0 + fseek(filep, 0, SEEK_END); + len = ftell(filep); + rewind(filep); // like fseek(fp, 0, SEEK_SET) + + value_ = (const char *)calloc(len + 1, 1); // malloc but zero'd + fsize = fread((void *)value_, 1, len, filep); + fclose(filep); + } + else { // File not opened + snprintf(error, sizeof(error), + "Error - File not found" + "

      Error - File not found

      " + "

      Unable to find the file at %s

      " + "

    • Back
    • ", + namep); + value_ = strdup(error); // Duplicate + } + } + +//printf(" load d->ltop=%d d->top=%d topline()=%d\n",d->ltop,d->top,topline()); + + if (!(!(d->nstyle & HV_NONAVIGATE) && d->isnav) && d->islink) + d->ltop = d->top; // leave if user nav and nav link, link clicked + format(); + if (target) // Target in link + topline(target); + else + topline(0); + + if (!(d->nstyle & HV_NONAVIGATE) && d->isnav) { + topline(d->ltop); // user navigation and is nav link + d->isnav = 0; // reset isnav + } + if (!strcmp(d->path, d->lpath)) topline(d->ltop); // remote link + if (d->islink) d->top = topline(); // link clicked, set top + leftline(0); // added + + return 0; // File was loaded, success + +} // Fl_Help_View::load() + +// +// Fl_Help_View::load_css() - Loads a css file. +// + +int // O - 0 if file loaded, -1 if error +Fl_Help_View::load_css(const char *fp) // I - file to load +{ + FILE *filep; // file to read from + size_t fsize; // file size + int ti = 0, tj = 0, + isblock = 0, isstr = 0, + tcount = 0, tstart = 0, + *tpi; // temp vars + long len = 0; // length of file + const char *namep; // local filename + char *tp; // temp ptr + + namep = fp; + if (!namep) return -1; // no file handle, fail + + if (!d->cssurl) { // first url + d->cssurllen = 1; + d->cssurl = (char *)calloc(1024, 1); // init zero'd + strlcpy(d->cssurl, namep, 1024); + } + else { // next url + for (ti = 0; ti < d->cssurllen; ti ++) { + tp = d->cssurl + (ti * 1024); + if (!strcmp(tp, namep)) len = 1; // url match + } + if (len != 1) { // no match, add new url + d->cssurl = (char *)realloc((void *)d->cssurl, (d->cssurllen + 1) * 1024); + tp = d->cssurl + (d->cssurllen * 1024); + strlcpy(tp, namep, 1024); + d->cssurllen ++; + } + } + + if (len == 1) return -1; // url match, fail + + if (!strncmp(namep, "ftp:", 4) || !strncmp(namep, "http:", 5) || + !strncmp(namep, "https:", 6)) + { + return -1; // remote link, fail + } + else // local link + { + if (!strncmp(namep, "file:", 5)) namep += 5; // adjust for file: + + if ((filep = fopen(namep, "rb"))) { // binary - rem'd != 0 + fseek(filep, 0, SEEK_END); + len = ftell(filep); + rewind(filep); // like fseek(fp, 0, SEEK_SET) + + if (!d->csstext) { // first file + d->csstext = (char *)calloc(len + 1, 1); // init zero'd + tp = d->csstext; + d->csstextlen = len; + } + else { // next file + d->csstext = (char *)realloc((void *)d->csstext, d->csstextlen + len + 1); + tp = d->csstext + d->csstextlen; + tstart = d->csstextlen; // start of file + d->csstextlen += len; // total file length + } + + *(tp + len) = '\0'; // nul-terminate file + fsize = fread((void *)tp, 1, len, filep); + fclose(filep); + + for (ti = 0; ti < len; ti ++) { // count words + if (isspace(*(tp + ti))) tj = 0; // no word + else tj ++; // letter count + if (*(tp + ti) == '{') { tj = 1; isblock = 1; } // block + if (*(tp + ti) == '"') { if (isstr) isstr = 0; else isstr = 1; } // string + if (!isblock) { // outside block + if (*(tp + ti) == ',') { // special char + tj = 1; ti ++; + while (isspace(*(tp + ti)) && ti < len) ti ++; // skip space + } + } + else if (!isstr) { // inside block - ignore if in string + if (*(tp + ti) == ':' || *(tp + ti) == ';') { // special char + tj = 1; ti ++; + while (isspace(*(tp + ti)) && ti < len) ti ++; // skip space + } + } + if (*(tp + ti) == '}') { tj = 1; isblock = 0; } // block + if (tj == 1) tcount ++; // next word + if (*(tp + ti) == '{' || *(tp + ti) == '}') tj = 0; // single char word + } + + if (!d->cssword) { // first file + d->cssword = (int *)calloc(tcount + 1, sizeof(int)); // init zero'd + tpi = d->cssword; + d->csswordlen = tcount; + } + else { // next file + d->cssword = (int *)realloc((void *)d->cssword, (d->csswordlen + tcount + 1) * sizeof(int)); + tpi = d->cssword + d->csswordlen; + d->csswordlen += tcount; // total word count + } + *(tpi + tcount) = d->csstextlen; // set last int + + for (ti = 0, isblock = 0, isstr = 0, tcount = 0; ti < len; ti ++) { // store word offsets + if (isspace(*(tp + ti))) tj = 0; // no word + else tj ++; // letter count + if (*(tp + ti) == '{') { tj = 1; isblock = 1; } // block + if (*(tp + ti) == '"') { if (isstr) isstr = 0; else isstr = 1; } // string + if (!isblock) { // outside block + if (*(tp + ti) == ',') { // special char + tj = 1; ti ++; + while (isspace(*(tp + ti)) && ti < len) ti ++; // skip space + } + } + else if (!isstr) { // inside block - ignore if in string + if (*(tp + ti) == ':' || *(tp + ti) == ';') { // special char + tj = 1; ti ++; + while (isspace(*(tp + ti)) && ti < len) ti ++; // skip space + } + } + if (*(tp + ti) == '}') { tj = 1; isblock = 0; } // block + if (tj == 1) { + *(tpi + tcount) = ti + tstart; // word offset + tcount ++; // next word + if (*(tp + ti) == '{' || *(tp + ti) == '}') tj = 0; // single char word + } + } + + } + else + return -1; // file not opened, failure + } + + return 0; // file was loaded, success + +} // Fl_Help_View::load_css() + +// +// Fl_Help_View::parse_css() - Parses all supported css properties. +// + +void Fl_Help_View::parse_css(Fl_Help_Block &b, // O - current block + const char *sp, // I - selector ptr + char *buf) // O - text buffer +{ + if (get_css_value(sp, "background-color", buf)) // background + b.bgcolor = get_color(buf, color()); + // todo: image/repeat/attachment/position + + if (get_css_value(sp, "font-family", buf)) // font + b.font = font_face(buf); // altered by style & weight + if (get_css_value(sp, "font-style", buf)) { + if (!strncasecmp(buf, "italic", 6) || + !strncasecmp(buf, "oblique", 7)) + b.font = font_style(b.font, FL_ITALIC); + } + if (get_css_value(sp, "font-weight", buf)) { + if (!strncasecmp(buf, "bold", 4)) + b.font = font_style(b.font, FL_BOLD); + } + if (get_css_value(sp, "font-size", buf)) { + b.fsize = get_font_size(buf) + 2; + } + return; + +} // Fl_Help_View::parse_css() + +// +// Fl_Help_View::popfont() - Pop from font stack. +// + +void Fl_Help_View::popfont(int &fi, + unsigned char &fs) { // pop font + if (d->nfonts > 0) d->nfonts --; + fl_font(fi = d->fonts[d->nfonts][0], fs = d->fonts[d->nfonts][1]); +} + +// +// Fl_Help_View::pushfont() - Push to font stack. +// + +void Fl_Help_View::pushfont(int fi, + unsigned char fs) { // push font + if (d->nfonts < 99) d->nfonts ++; + fl_font(d->fonts[d->nfonts][0] = fi, d->fonts[d->nfonts][1] = fs); +} + +// +// Fl_Help_View::resize() - Resize the help widget. +// + +void Fl_Help_View::resize(int xx, // I - New left position + int yy, // I - New top position + int ww, // I - New width + int hh) // I - New height +{ + int ss = Fl::scrollbar_size(); // Scrollbar width + long time = 0, sec = 0, mil = 0; // timer vars + Fl_Boxtype bt = (box()) ? box() : FL_DOWN_BOX; // box to draw + + Fl_Widget::resize(xx, yy, ww, hh); // Resize help widget + + scrollbar_.resize(x() + w() - ss - Fl::box_dw(bt) + Fl::box_dx(bt), + y() + Fl::box_dy(bt), ss, h() - ss - Fl::box_dh(bt)); + hscrollbar_.resize(x() + Fl::box_dx(bt), + y() + h() - ss - Fl::box_dh(bt) + Fl::box_dy(bt), + w() - ss - Fl::box_dw(bt), ss); + + // delay calls to format to avoid hangs on very large pages + if (abs(w() - d->rwidth) > 2) { // moved more than 2 pixels + fl_gettime(&sec, &mil); // find how long since last format + time = MIL(d->rsec, d->rmil, sec, mil); + if (time > d->rtime || !d->resized) { // enough time has passed + d->resized = 1; // set d->resized + format(); + fl_gettime(&d->rsec, &d->rmil); // find how long this format took + d->rtime = MIL(d->rsec, d->rmil, sec, mil); + d->rtime /= 2; // wait half the time format took + d->rwidth = w(); // store window width + } + } + +} // Fl_Help_View::resize() + +// +// Fl_Help_View::select_all() - Select all text. +// + +void Fl_Help_View::select_all() +{ + clear_global_selection(); + if (!value_) return; + current_view = this; + selection_drag_last = selection_last = strlen(value_); + selected = 1; + +} // Fl_Help_View::select_all() + +// +// Fl_Help_View::setstyle() - set the html style flag +// + +void Fl_Help_View::setstyle(int flag) // I - style flag to set +{ + d->nstyle = flag; // wasn't working as a method.. +} + +// +// Fl_Help_View::topline() - Set the top line to the named target. +// + +void Fl_Help_View::topline(const char *np) // I - Target name +{ + Fl_Help_Link key, // Target name key + *target; // Pointer to matching target + + if (ntargets_ == 0) return; + + strlcpy(key.name, np, sizeof(key.name)); + + target = (Fl_Help_Link *)bsearch(&key, d->targets, ntargets_, + sizeof(Fl_Help_Link), + (compare_func_t)cmp_targets); + + if (target) topline(target->y); // Target found - rem'd != 0 + +} // Fl_Help_View::topline() + +// +// Fl_Help_View::topline() - Set the top line by number. +// + +void Fl_Help_View::topline(int yy) // I - Top line number +{ + if (!value_) return; + + if (size_ < h() - Fl::scrollbar_size() || yy < 0) + yy = 0; + else if (yy > size_) + yy = size_; + + topline_ = yy; + scrollbar_.value(topline_, h() - Fl::scrollbar_size(), 0, size_); + do_callback(); + redraw(); // Set widget to draw + d->top = topline_; // set top + +} // Fl_Help_View::topline() + +// +// Fl_Help_View::value() - Set the help text directly. +// +// Note: called by nav buttons, also after follow_link + +void Fl_Help_View::value(const char *tp) // I - Text to view +{ + + if (!tp) return; // Null + + char target[32]; // current target + target[0] = '\0'; + + if (d->islink) { // link clicked + if (d->linkp) // link exists + strlcpy(target, d->linkp->name, sizeof(target)); + d->islink = 0; // reset islink + if (!(d->nstyle & HV_NONAVIGATE)) return; // file was loaded + } + + if (!tp[0]) { // text buffer empty + char error[1024]; // error buffer + const char *namep = 0; // local filename + if (d->ispath) namep = d->path; // path is used + else if (filename_[0]) namep = filename_; + if (!namep[0]) namep = "(null)"; + + if (!strncmp(namep, "ftp:", 4) || !strncmp(namep, "http:", 5) || + !strncmp(namep, "https:", 6) || !strncmp(namep, "ipp:", 4) || + !strncmp(namep, "mailto:", 7) || !strncmp(namep, "news:", 5)) { + snprintf(error, sizeof(error), + "Error - Server not found" + "

      Error - Server not found

      " + "

      Unable to find the address at %s

      " + "

    • No handler exists for this URI scheme
    • ", + namep, namep); + } + else { + snprintf(error, sizeof(error), + "Error - File not found" + "

      Error - File not found

      " + "

      Unable to find the file at %s

      ", namep); + if (d->lpath[0]) // last path exists + snprintf(error + strlen(error), sizeof(error) - strlen(error), + "

    • Back

      "); + } + clear_selection(); // clear text selection + set_changed(); // set widget value was changed + free_data(); // free last document + value_ = strdup(error); // duplicate + format(); + topline(0); + leftline(0); + return; // we're done + } + +//printf(" value target=(%s) d->ispath=%d\n",target,d->ispath); +//printf(" value d->path=(%s) d->islink=%d\n",d->path,d->islink); + + clear_selection(); // Clear text selection + set_changed(); // Set widget value was changed + free_data(); // Free last document + value_ = strdup(tp); // Duplicate + if (d->islink) d->ltop = d->top; // link clicked, last top + format(); + + if (target[0]) // new link with target + topline(target); // set position on page + else // no target + topline(0); + + if (d->islink) d->top = topline(); // link clicked, set top + leftline(0); + +} // Fl_Help_View::value() + +// +// Fl_Help_View::~Fl_Help_View() - Destroy a Fl_Help_View widget. +// + +Fl_Help_View::~Fl_Help_View() +{ + clear_selection(); // Clear text selection + free_data(); // Free last document + free(d); // free d-pointer + +} // Fl_Help_View::~Fl_Help_View() + +// +// 'command()' - Convert a command with up to four letters into an uint. +// + +static unsigned int // O - Fourcc int +command(const char *cmdp) // I - Command pointer +{ + unsigned int ret = (tolower(cmdp[0]) << 24); + char cc = cmdp[1]; + + if (cc == '>' || cc == ' ' || cc == 0) return ret; + ret |= (tolower(cc) << 16); + cc = cmdp[2]; + if (cc == '>' || cc == ' ' || cc == 0) return ret; + ret |= (tolower(cc) << 8); + cc = cmdp[3]; + if (cc == '>' || cc == ' ' || cc == 0) return ret; + ret |= tolower(cc); + cc = cmdp[4]; + if (cc == '>' || cc == ' ' || cc == 0) return ret; + return 0; + +} // command() + +// +// 'quote_char()' - Return the character code associated with a quoted char. +// + +static int // O - Code or -1 on error +quote_char(const char *qp, // I - Quoted string + int fc) // I - true to return what font char uses, opt +{ + int ti = 0, // Temp loop var + num = 0, // number of elements + temp = 0; // temp var + + // updated table to HTML 4 + // http://www.alanwood.net/demos/ansi.html + static struct { + const char *name; // str pointer + int namelen; // str length + int cdata; // character reference data + int code; // ANSI/Unicode char code + int mac; // Mac Roman char code + int sym; // what font does char use? 0 = current, 1 = Symbol + } + *namep, // pointer into names array + names[] = { // quoting names + // special escape chars + { "quot;", 5, 34, '\"','\"',ENC(0,0) }, // quotation mark + { "amp;", 4, 38, '&', '&', ENC(0,0) }, // ampersand + { "lt;", 3, 60, '<', '<', ENC(0,0) }, // less-than sign + { "gt;", 3, 62, '>', '>', ENC(0,0) }, // greater-than sign + // reserved chars * means no equivalent in Mac Roman + // 128-159 are control chars in Unicode but are chars in ANSI + { "euro;", 5, 8364, 'C', 219, ENC(0,0) }, // euro sign + { "thinsp;", 7, 8201, ' ', ' ', ENC(0,0) }, // thin space - NA + { "sbquo;", 6, 8218, 130, 226, ENC(0,0) }, // single low-9 quotation mark + { "fnof;", 5, 402, 166, 196, ENC(1,0) }, // Latin small f hook + { "bdquo;", 6, 8222, 132, 227, ENC(0,0) }, // double low-9 quotation mark + { "hellip;", 7, 8230, 188, 201, ENC(1,0) }, // horizontal ellipsis + { "dagger;", 7, 8224, 134, 160, ENC(0,0) }, // dagger + { "Dagger;", 7, 8225, 135, 224, ENC(0,0) }, // double dagger + { "circ;", 5, 710, 136, 246, ENC(0,0) }, // modifier circumflex accent + { "permil;", 7, 8240, 137, 228, ENC(0,0) }, // per mille sign + { "Scaron;", 7, 352, 138, 223, ENC(0,1) }, // Latin capital S caron * + { "lsaquo;", 7, 8249, 225, 220, ENC(1,0) }, // single left angle quotation + { "OElig;", 6, 338, 140, 206, ENC(0,0) }, // Latin capital ligature OE + { "zwnj;", 5, 8204, ' ', ' ', ENC(0,0) }, // nzero width non-joiner - NA + { "zwj;", 4, 8205, ' ', ' ', ENC(0,0) }, // zero width joiner - NA + { "lrm;", 4, 8206, ' ', ' ', ENC(0,0) }, // left-to-right mark - NA + { "rlm;", 4, 8207, ' ', ' ', ENC(0,0) }, // right-to-left mark - NA + { "lsquo;", 6, 8216, 145, 212, ENC(0,0) }, // left single quotation mark + { "rsquo;", 6, 8217, 146, 213, ENC(0,0) }, // right single quotation mark + { "ldquo;", 6, 8220, 147, 210, ENC(0,0) }, // left double quotation mark + { "rdquo;", 6, 8221, 148, 211, ENC(0,0) }, // right double quotation mark + { "bull;", 5, 8226, 183, 165, ENC(1,0) }, // bullet + { "ndash;", 6, 8211, '-', 208, ENC(1,0) }, // en dash + { "mdash;", 6, 8212, 190, 209, ENC(1,0) }, // em dash + { "tilde;", 6, 732, 152, 247, ENC(0,0) }, // small tilde + { "trade;", 6, 8482, 228, 170, ENC(1,0) }, // trade mark sign + { "scaron;", 7, 353, 154, 222, ENC(0,1) }, // Latin small s caron * + { "rsaquo;", 7, 8250, 241, 221, ENC(1,0) }, // single right angle quotation + { "oelig;", 6, 339, 156, 207, ENC(0,0) }, // Latin small ligature oe + { "ensp;", 5, 8194, ' ', ' ', ENC(0,0) }, // en space - NA + { "emsp;", 5, 8195, ' ', ' ', ENC(0,0) }, // em space - NA + { "Yuml;", 5, 376, 159, 217, ENC(0,0) }, // Latin capital Y umlaut + // Latin-1 Supplement + { "nbsp;", 5, 160, ' ', ' ', ENC(0,0) }, // no-break space, 160/202 + { "iexcl;", 6, 161, 161, 193, ENC(0,0) }, // inverted exclamation mark + { "cent;", 5, 162, 162, 162, ENC(0,0) }, // cent sign + { "pound;", 6, 163, 163, 163, ENC(0,0) }, // pound sign + { "curren;", 7, 164, 164, 251, ENC(0,1) }, // currency sign * + { "yen;", 4, 165, 165, 180, ENC(0,0) }, // yen sign + { "brvbar;", 7, 166, 166, 240, ENC(0,1) }, // broken bar * + { "sect;", 5, 167, 167, 164, ENC(0,0) }, // section sign + { "uml;", 4, 168, 168, 172, ENC(0,0) }, // diaeresis/umlaut + { "copy;", 5, 169, 169, 169, ENC(0,0) }, // copyright sign + { "ordf;", 5, 170, 170, 187, ENC(0,0) }, // feminine ordinal indicator + { "laquo;", 6, 171, 171, 199, ENC(0,0) }, // left double angle quotation + { "not;", 4, 172, 172, 194, ENC(0,0) }, // not sign + { "shy;", 4, 173, 173, '-', ENC(0,0) }, // soft hyphen + { "reg;", 4, 174, 174, 168, ENC(0,0) }, // registered sign + { "macr;", 5, 175, 175, 248, ENC(0,0) }, // macron + { "deg;", 4, 176, 176, 161, ENC(0,0) }, // degree sign + { "plusmn;", 7, 177, 177, 177, ENC(0,0) }, // plus-minus sign + { "sup2;", 5, 178, 178, 253, ENC(0,1) }, // superscript two * + { "sup3;", 5, 179, 179, 249, ENC(0,1) }, // superscript three * + { "acute;", 6, 180, 180, 171, ENC(0,0) }, // acute accent + { "micro;", 6, 181, 181, 181, ENC(0,0) }, // micro sign + { "para;", 5, 182, 182, 166, ENC(0,0) }, // pilcrow sign + { "middot;", 7, 183, 183, 225, ENC(0,0) }, // middle dot + { "cedil;", 6, 184, 184, 252, ENC(0,0) }, // cedilla + { "sup1;", 5, 185, 185, 245, ENC(0,1) }, // superscript one * + { "ordm;", 5, 186, 186, 188, ENC(0,0) }, // masculine ordinal indicator + { "raquo;", 6, 187, 187, 200, ENC(0,0) }, // right double angle quotation + { "frac14;", 7, 188, 188, 254, ENC(0,1) }, // vulgar fraction 1/4 * + { "frac12;", 7, 189, 189, 255, ENC(0,1) }, // vulgar fraction 1/2 * + { "frac34;", 7, 190, 190, 250, ENC(0,1) }, // vulgar fraction 3/4 * + { "iquest;", 7, 191, 191, 192, ENC(0,0) }, // inverted question mark + { "Agrave;", 7, 192, 192, 203, ENC(0,0) }, // Latin capital A grave + { "Aacute;", 7, 193, 193, 231, ENC(0,0) }, // Latin capital A acute + { "Acirc;", 6, 194, 194, 229, ENC(0,0) }, // Latin capital A circumflex + { "Atilde;", 7, 195, 195, 204, ENC(0,0) }, // Latin capital A tilde + { "Auml;", 5, 196, 196, 128, ENC(0,0) }, // Latin capital A umlaut + { "Aring;", 6, 197, 197, 129, ENC(0,0) }, // Latin capital A ring above + { "AElig;", 6, 198, 198, 174, ENC(0,0) }, // Latin capital AE + { "Ccedil;", 7, 199, 199, 130, ENC(0,0) }, // Latin capital C cedilla + { "Egrave;", 7, 200, 200, 233, ENC(0,0) }, // Latin capital E grave + { "Eacute;", 7, 201, 201, 131, ENC(0,0) }, // Latin capital E acute + { "Ecirc;", 6, 202, 202, 230, ENC(0,0) }, // Latin capital E circumflex + { "Euml;", 5, 203, 203, 232, ENC(0,0) }, // Latin capital E umlaut + { "Igrave;", 7, 204, 204, 237, ENC(0,0) }, // Latin capital I grave + { "Iacute;", 7, 205, 205, 234, ENC(0,0) }, // Latin capital I acute + { "Icirc;", 6, 206, 206, 235, ENC(0,0) }, // Latin capital I circumflex + { "Iuml;", 5, 207, 207, 236, ENC(0,0) }, // Latin capital I umlaut + { "ETH;", 4, 208, 208, 198, ENC(0,1) }, // Latin capital ETH * + { "Ntilde;", 7, 209, 209, 132, ENC(0,0) }, // Latin capital N tilde + { "Ograve;", 7, 210, 210, 241, ENC(0,0) }, // Latin capital O grave + { "Oacute;", 7, 211, 211, 238, ENC(0,0) }, // Latin capital O acute + { "Ocirc;", 6, 212, 212, 239, ENC(0,0) }, // Latin capital O circumflex + { "Otilde;", 7, 213, 213, 205, ENC(0,0) }, // Latin capital O tilde + { "Ouml;", 5, 214, 214, 133, ENC(0,0) }, // Latin capital O umlaut + { "times;", 6, 215, 215, 'x', ENC(0,0) }, // multiplication sign + { "Oslash;", 7, 216, 216, 175, ENC(0,0) }, // Latin capital O stroke + { "Ugrave;", 7, 217, 217, 244, ENC(0,0) }, // Latin capital U grave + { "Uacute;", 7, 218, 218, 242, ENC(0,0) }, // Latin capital U acute + { "Ucirc;", 6, 219, 219, 243, ENC(0,0) }, // Latin capital U circumflex + { "Uuml;", 5, 220, 220, 134, ENC(0,0) }, // Latin capital U umlaut + { "Yacute;", 7, 221, 221, 217, ENC(0,1) }, // Latin capital Y acute * + { "THORN;", 6, 222, 222, 167, ENC(0,1) }, // Latin capital THORN * + { "szlig;", 6, 223, 223, 167, ENC(0,0) }, // Latin small sharp s + { "agrave;", 7, 224, 224, 136, ENC(0,0) }, // Latin small a grave + { "aacute;", 7, 225, 225, 135, ENC(0,0) }, // Latin small a acute + { "acirc;", 6, 226, 226, 137, ENC(0,0) }, // Latin small a circumflex + { "atilde;", 7, 227, 227, 139, ENC(0,0) }, // Latin small a tilde + { "auml;", 5, 228, 228, 138, ENC(0,0) }, // Latin small a umlaut + { "aring;", 6, 229, 229, 140, ENC(0,0) }, // Latin small a ring above + { "aelig;", 6, 230, 230, 190, ENC(0,0) }, // Latin small ae + { "ccedil;", 7, 231, 231, 141, ENC(0,0) }, // Latin small c cedilla + { "egrave;", 7, 232, 232, 143, ENC(0,0) }, // Latin small e grave + { "eacute;", 7, 233, 233, 142, ENC(0,0) }, // Latin small e acute + { "ecirc;", 6, 234, 234, 144, ENC(0,0) }, // Latin small e circumflex + { "euml;", 5, 235, 235, 145, ENC(0,0) }, // Latin small e umlaut + { "igrave;", 7, 236, 236, 147, ENC(0,0) }, // Latin small i grave + { "iacute;", 7, 237, 237, 146, ENC(0,0) }, // Latin small i acute + { "icirc;", 6, 238, 238, 148, ENC(0,0) }, // Latin small i circumflex + { "iuml;", 5, 239, 239, 149, ENC(0,0) }, // Latin small i umlaut + { "eth;", 4, 240, 240, 182, ENC(0,1) }, // Latin small eth * + { "ntilde;", 7, 241, 241, 150, ENC(0,0) }, // Latin small n tilde + { "ograve;", 7, 242, 242, 152, ENC(0,0) }, // Latin small o grave + { "oacute;", 7, 243, 243, 151, ENC(0,0) }, // Latin small o acute + { "ocirc;", 6, 244, 244, 153, ENC(0,0) }, // Latin small o circumflex + { "otilde;", 7, 245, 245, 155, ENC(0,0) }, // Latin small o tilde + { "ouml;", 5, 246, 246, 154, ENC(0,0) }, // Latin small o umlaut + { "divide;", 7, 247, 247, 214, ENC(0,0) }, // division sign + { "oslash;", 7, 248, 248, 191, ENC(0,0) }, // Latin small o stroke + { "ugrave;", 7, 249, 249, 157, ENC(0,0) }, // Latin small u grave + { "uacute;", 7, 250, 250, 156, ENC(0,0) }, // Latin small u acute + { "ucirc;", 6, 251, 251, 158, ENC(0,0) }, // Latin small u circumflex + { "uuml;", 5, 252, 252, 159, ENC(0,0) }, // Latin small u umlaut + { "yacute;", 7, 253, 253, 216, ENC(0,1) }, // Latin small y acute * + { "thorn;", 6, 254, 254, 164, ENC(0,1) }, // Latin small thorn * + { "yuml;", 5, 255, 255, 216, ENC(0,0) }, // Latin small y umlaut + // Greek # means no equivalent in ANSI/Unicode + { "Alpha;", 6, 913, 'A', 'A', ENC(1,1) }, // Greek capital Alpha + { "Beta;", 5, 914, 'B', 'B', ENC(1,1) }, // Greek capital Beta + { "Gamma;", 6, 915, 'G', 'G', ENC(1,1) }, // Greek capital Gamma + { "Delta;", 6, 916, 'D', 'D', ENC(1,1) }, // Greek capital Delta + { "Epsilon;",8, 917, 'E', 'E', ENC(1,1) }, // Greek capital Epsilon + { "Zeta;", 5, 918, 'Z', 'Z', ENC(1,1) }, // Greek capital Zeta + { "Eta;", 4, 919, 'H', 'H', ENC(1,1) }, // Greek capital Eta + { "Theta;", 6, 920, 'Q', 'Q', ENC(1,1) }, // Greek capital Theta + { "Iota;", 5, 921, 'I', 'I', ENC(1,1) }, // Greek capital Iota + { "Kappa;", 6, 922, 'K', 'K', ENC(1,1) }, // Greek capital Kappa + { "Lambda;", 7, 923, 'L', 'L', ENC(1,1) }, // Greek capital Lambda + { "Mu;", 3, 924, 'M', 'M', ENC(1,1) }, // Greek capital Mu + { "Nu;", 3, 925, 'N', 'N', ENC(1,1) }, // Greek capital Nu + { "Xi;", 3, 926, 'X', 'X', ENC(1,1) }, // Greek capital Xi + { "Omicron;",8, 927, 'O', 'O', ENC(1,1) }, // Greek capital Omicron + { "Pi;", 3, 928, 'P', 'P', ENC(1,1) }, // Greek capital Pi + { "Rho;", 4, 929, 'R', 'R', ENC(1,1) }, // Greek capital Rho + { "Sigma;", 6, 931, 'S', 'S', ENC(1,1) }, // Greek capital Sigma + { "Tau;", 4, 932, 'T', 'T', ENC(1,1) }, // Greek capital Tau + { "Upsilon;",8, 933, 'U', 'U', ENC(1,1) }, // Greek capital Upsilon + { "Phi;", 4, 934, 'F', 'F', ENC(1,1) }, // Greek capital Phi + { "Chi;", 4, 935, 'C', 'C', ENC(1,1) }, // Greek capital Chi + { "Psi;", 4, 936, 'Y', 'Y', ENC(1,1) }, // Greek capital Psi + { "Omega;", 6, 937, 'W', 'W', ENC(1,1) }, // Greek capital Omega # 189 in Mac Roman + { "alpha;", 6, 945, 'a', 'a', ENC(1,1) }, // Greek small alpha + { "beta;", 5, 946, 'b', 'b', ENC(1,1) }, // Greek small beta + { "gamma;", 6, 947, 'g', 'g', ENC(1,1) }, // Greek small gamma + { "delta;", 6, 948, 'd', 'd', ENC(1,1) }, // Greek small delta + { "epsilon;",8, 949, 'e', 'e', ENC(1,1) }, // Greek small epsilon + { "zeta;", 5, 950, 'z', 'z', ENC(1,1) }, // Greek small zeta + { "eta;", 4, 951, 'h', 'h', ENC(1,1) }, // Greek small eta + { "theta;", 6, 952, 'q', 'q', ENC(1,1) }, // Greek small theta + { "iota;", 5, 953, 'i', 'i', ENC(1,1) }, // Greek small iota + { "kappa;", 6, 954, 'k', 'k', ENC(1,1) }, // Greek small kappa + { "lambda;", 7, 955, 'l', 'l', ENC(1,1) }, // Greek small lambda + { "mu;", 3, 956, 'm', 'm', ENC(1,1) }, // Greek small mu + { "nu;", 3, 957, 'n', 'n', ENC(1,1) }, // Greek small nu + { "xi;", 3, 958, 'x', 'x', ENC(1,1) }, // Greek small xi + { "omicron;",8, 959, 'o', 'o', ENC(1,1) }, // Greek small omicron + { "pi;", 3, 960, 'p', 'p', ENC(1,1) }, // Greek small pi # 185 in Mac Roman + { "rho;", 4, 961, 'r', 'r', ENC(1,1) }, // Greek small rho + { "sigma;", 6, 962, 's', 's', ENC(1,1) }, // Greek small sigma + { "sigmaf;", 7, 963, 'V', 'V', ENC(1,1) }, // Greek small sigma final variant + { "tau;", 4, 964, 't', 't', ENC(1,1) }, // Greek small tau + { "upsilon;",8, 965, 'u', 'u', ENC(1,1) }, // Greek small upsilon + { "phi;", 4, 966, 'j', 'j', ENC(1,1) }, // Greek small phi, 'f' is phi variant + { "chi;", 4, 967, 'c', 'c', ENC(1,1) }, // Greek small chi + { "psi;", 4, 968, 'y', 'y', ENC(1,1) }, // Greek small psi + { "omega;", 6, 969, 'w', 'w', ENC(1,1) }, // Greek small omega + { "thetasym;",9, 977,'J', 'J', ENC(1,1) }, // Greek small theta variant + { "upsih;", 6, 978, 161, 111, ENC(1,1) }, // Greek capital upsilon hook variant + { "piv;", 4, 982, 'v', 'v', ENC(1,1) }, // Greek small pi variant + // General Punctuation, Letterlike Symbols and Arrows + { "prime;", 6, 8242, 162, 162, ENC(1,1) }, // prime + { "Prime;", 6, 8243, 178, 178, ENC(1,1) }, // double prime + { "oline;", 6, 8254, '_', '_', ENC(1,1) }, // overline + { "frasl;", 6, 8260, 164, 218, ENC(1,0) }, // fraction slash # + { "weierp;", 7, 8472, 195, 195, ENC(1,1) }, // script capital P, power set + { "image;", 6, 8465, 193, 193, ENC(1,1) }, // blackletter capital I, imaginary part + { "real;", 5, 8476, 194, 194, ENC(1,1) }, // blackletter capital R, real part + { "alefsym;",8, 8501, 192, 192, ENC(1,1) }, // alef symbol + { "larr;", 5, 8592, 172, 172, ENC(1,1) }, // left arrow + { "uarr;", 5, 8593, 173, 173, ENC(1,1) }, // up arrow + { "rarr;", 5, 8594, 174, 174, ENC(1,1) }, // right arrow + { "darr;", 5, 8595, 175, 175, ENC(1,1) }, // down arrow + { "harr;", 5, 8596, 171, 171, ENC(1,1) }, // horizontal arrow + { "crarr;", 6, 8629, 191, 191, ENC(1,1) }, // carriage return arrow + { "lArr;", 5, 8656, 220, 220, ENC(1,1) }, // left double arrow + { "uArr;", 5, 8657, 221, 221, ENC(1,1) }, // up double arrow + { "rArr;", 5, 8658, 222, 222, ENC(1,1) }, // right double arrow + { "dArr;", 5, 8659, 223, 223, ENC(1,1) }, // down double arrow + { "hArr;", 5, 8660, 219, 219, ENC(1,1) }, // horizontal double arrow + // Mathematical Operators + { "forall;", 7, 8704, '\"','\"',ENC(1,1) }, // for all + { "part;", 5, 8706, 182, 182, ENC(1,0) }, // partial differential # + { "exist;", 6, 8707, '$', '$', ENC(1,1) }, // there exists + { "empty;", 6, 8709, 198, 198, ENC(1,1) }, // empty set + { "nabla;", 6, 8711, 209, 209, ENC(1,1) }, // nabla + { "isin;", 5, 8712, 206, 206, ENC(1,1) }, // element of + { "notin;", 6, 8713, 207, 207, ENC(1,1) }, // not an element of + { "ni;", 3, 8715, '\'','\'',ENC(1,1) }, // contains as member + { "prod;", 5, 8719, 213, 184, ENC(1,0) }, // n-ary product # + { "sum;", 4, 8721, 229, 183, ENC(1,0) }, // n-ary summation # + { "minus;", 6, 8722, 190, 190, ENC(1,1) }, // minus sign + { "lowast;", 7, 8727, '*', '*', ENC(1,1) }, // asterisk operator + { "radic;", 6, 8730, 214, 195, ENC(1,0) }, // square root # + { "prop;", 5, 8733, 181, 181, ENC(1,1) }, // proportional to + { "infin;", 6, 8734, 165, 176, ENC(1,0) }, // infinity # + { "ang;", 4, 8736, 208, 208, ENC(1,1) }, // angle + { "and;", 4, 8743, 217, 217, ENC(1,1) }, // logical and + { "or;", 3, 8744, 218, 218, ENC(1,1) }, // logical or + { "cap;", 4, 8745, 199, 199, ENC(1,1) }, // intersection + { "cup;", 4, 8746, 200, 200, ENC(1,1) }, // union + { "int;", 4, 8747, 242, 186, ENC(1,0) }, // integral # + { "there4;", 7, 8756, '\\','\\',ENC(1,1) }, // therefore + { "sim;", 4, 8764, '~', '~', ENC(1,1) }, // tilde operator + { "cong;", 5, 8773, '@', '@', ENC(1,1) }, // approximately equal to + { "asymp;", 6, 8776, 187, 197, ENC(1,0) }, // almost equal to # + { "ne;", 3, 8800, 185, 173, ENC(1,0) }, // not equal to # + { "equiv;", 6, 8801, 186, 186, ENC(1,1) }, // identical to + { "le;", 3, 8804, 163, 178, ENC(1,0) }, // less-than or equal to # + { "ge;", 3, 8805, 179, 179, ENC(1,0) }, // greater-than or equal to # + { "sub;", 4, 8834, 204, 204, ENC(1,1) }, // subset of + { "sup;", 4, 8835, 201, 201, ENC(1,1) }, // superset of + { "nsub;", 5, 8836, 203, 203, ENC(1,1) }, // not a subset of + { "sube;", 5, 8838, 205, 205, ENC(1,1) }, // subset of or equal to + { "supe;", 5, 8839, 202, 202, ENC(1,1) }, // superset of or equal to + { "oplus;", 6, 8853, 197, 197, ENC(1,1) }, // circled plus + { "otimes;", 7, 8855, 196, 196, ENC(1,1) }, // circled times + { "perp;", 5, 8869, '^', '^', ENC(1,1) }, // up tack + // Miscellaneous Technical and Miscellaneous Symbols + { "sdot;", 5, 8901, 215, 215, ENC(1,1) }, // dot operator + { "lceil;", 6, 8968, 233, 233, ENC(1,1) }, // left ceiling + { "rceil;", 6, 8969, 249, 249, ENC(1,1) }, // right ceiling + { "lfloor;", 7, 8970, 235, 235, ENC(1,1) }, // left floor + { "rfloor;", 7, 8971, 251, 251, ENC(1,1) }, // right floor + { "lang;", 5, 9001, 225, 225, ENC(1,1) }, // left-pointing angle bracket + { "rang;", 5, 9002, 241, 241, ENC(1,1) }, // right-pointing angle bracket + { "loz;", 4, 9674, 224, 215, ENC(1,0) }, // lozenge # + { "spades;", 7, 9824, 170, 170, ENC(1,1) }, // black spade suit + { "clubs;", 6, 9827, 167, 167, ENC(1,1) }, // black club suit + { "hearts;", 7, 9829, 169, 169, ENC(1,1) }, // black heart suit + { "diams;", 6, 9830, 168, 168, ENC(1,1) } // black diamond suit + }; + + if (!strchr(qp, ';')) return -1; // No semi-colon char + + num = sizeof(names) / sizeof(names[0]); // array size / element size + + if (*qp == '#') { // Numeric character reference + if (*(qp + 1) == 'x' || *(qp + 1) == 'X') // Hexadecimal number + temp = strtol(qp + 2, 0, 16); // Base-16 str to long - rem'd NULL + else // Decimal number + temp = atoi(qp + 1); // Convert str to int + + if (fc) { // check font char arg + for (ti = num, namep = names; ti > 0; ti --, namep ++) + if (namep->cdata == temp) return namep->sym; + return 0; // cdata not found, use current font + } + return temp; + } + + for (ti = num, namep = names; ti > 0; ti --, namep ++) + if (!strncmp(qp, namep->name, namep->namelen)) { // If qp equals name + if (fc) return namep->sym; + return ENC(namep->code, namep->mac); + } + + return -1; // Entity character reference not found + +} // quote_char() + +// +// 'hscrollbar_callback()' - Callback for the horizontal scrollbar. +// + +static void hscrollbar_callback(Fl_Widget *s, // I - Scrollbar handle + void *) +{ + ((Fl_Help_View *)(s->parent()))->leftline(int(((Fl_Scrollbar*)s)->value())); + +} // hscrollbar_callback() + +// +// 'scrollbar_callback()' - Callback for the scrollbar. +// + +static void scrollbar_callback(Fl_Widget *s, // I - Scrollbar handle + void *) +{ + ((Fl_Help_View *)(s->parent()))->topline(int(((Fl_Scrollbar*)s)->value())); + +} // scrollbar_callback() + +// +// End of "$Id: Fl_Help_View.cxx 6091 2008-04-11 11:12:16Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Image.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Image.cxx new file mode 100644 index 0000000..faee82b --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Image.cxx @@ -0,0 +1,590 @@ +// +// "$Id: Fl_Image.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Image drawing code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include +#include +#include +#include +#include "flstring.h" + +#ifdef WIN32 +void fl_release_dc(HWND, HDC); // from Fl_win32.cxx +#endif + +void fl_restore_clip(); // from fl_rect.cxx + +// +// Base image class... +// + +/** + The destructor is a virtual method that frees all memory used + by the image. +*/ +Fl_Image::~Fl_Image() { +} + +/** + If the image has been cached for display, delete the cache + data. This allows you to change the data used for the image and + then redraw it without recreating an image object. +*/ +void Fl_Image::uncache() { +} + +void Fl_Image::draw(int XP, int YP, int, int, int, int) { + draw_empty(XP, YP); +} + +/** + The protected method draw_empty() draws a box with + an X in it. It can be used to draw any image that lacks image + data. +*/ +void Fl_Image::draw_empty(int X, int Y) { + if (w() > 0 && h() > 0) { + fl_color(FL_FOREGROUND_COLOR); + fl_rect(X, Y, w(), h()); + fl_line(X, Y, X + w() - 1, Y + h() - 1); + fl_line(X, Y + h() - 1, X + w() - 1, Y); + } +} + +/** + The copy() method creates a copy of the specified + image. If the width and height are provided, the image is + resized to the specified size. The image should be deleted (or in + the case of Fl_Shared_Image, released) when you are done + with it. +*/ +Fl_Image *Fl_Image::copy(int W, int H) { + return new Fl_Image(W, H, d()); +} + +/** + The color_average() method averages the colors in + the image with the FLTK color value c. The i + argument specifies the amount of the original image to combine + with the color, so a value of 1.0 results in no color blend, and + a value of 0.0 results in a constant image of the specified + color. The original image data is not altered by this + method. +*/ +void Fl_Image::color_average(Fl_Color, float) { +} + +/** + The desaturate() method converts an image to + grayscale. If the image contains an alpha channel (depth = 4), + the alpha channel is preserved. This method does not alter + the original image data. +*/ +void Fl_Image::desaturate() { +} + +/** + The label() methods are an obsolete way to set the + image attribute of a widget or menu item. Use the + image() or deimage() methods of the + Fl_Widget and Fl_Menu_Item classes + instead. +*/ +void Fl_Image::label(Fl_Widget* widget) { + widget->image(this); +} + +/** + The label() methods are an obsolete way to set the + image attribute of a widget or menu item. Use the + image() or deimage() methods of the + Fl_Widget and Fl_Menu_Item classes + instead. +*/ +void Fl_Image::label(Fl_Menu_Item* m) { + Fl::set_labeltype(_FL_IMAGE_LABEL, labeltype, measure); + m->label(_FL_IMAGE_LABEL, (const char*)this); +} + +void +Fl_Image::labeltype(const Fl_Label *lo, // I - Label + int lx, // I - X position + int ly, // I - Y position + int lw, // I - Width of label + int lh, // I - Height of label + Fl_Align la) { // I - Alignment + Fl_Image *img; // Image pointer + int cx, cy; // Image position + + img = (Fl_Image *)(lo->value); + + if (la & FL_ALIGN_LEFT) cx = 0; + else if (la & FL_ALIGN_RIGHT) cx = img->w() - lw; + else cx = (img->w() - lw) / 2; + + if (la & FL_ALIGN_TOP) cy = 0; + else if (la & FL_ALIGN_BOTTOM) cy = img->h() - lh; + else cy = (img->h() - lh) / 2; + + fl_color((Fl_Color)lo->color); + + img->draw(lx, ly, lw, lh, cx, cy); +} + +void +Fl_Image::measure(const Fl_Label *lo, // I - Label + int &lw, // O - Width of image + int &lh) { // O - Height of image + Fl_Image *img; // Image pointer + + img = (Fl_Image *)(lo->value); + + lw = img->w(); + lh = img->h(); +} + + +// +// RGB image class... +// +/** The destructor free all memory and server resources that are used by the image. */ +Fl_RGB_Image::~Fl_RGB_Image() { + uncache(); + if (alloc_array) delete[] (uchar *)array; +} + +void Fl_RGB_Image::uncache() { +#ifdef __APPLE_QUARTZ__ + if (id_) { + CGImageRelease((CGImageRef)id_); + id_ = 0; + } +#else + if (id_) { + fl_delete_offscreen((Fl_Offscreen)id_); + id_ = 0; + } + + if (mask_) { + fl_delete_bitmask((Fl_Bitmask)mask_); + mask_ = 0; + } +#endif +} + +Fl_Image *Fl_RGB_Image::copy(int W, int H) { + Fl_RGB_Image *new_image; // New RGB image + uchar *new_array; // New array for image data + + // Optimize the simple copy where the width and height are the same, + // or when we are copying an empty image... + if ((W == w() && H == h()) || + !w() || !h() || !d() || !array) { + if (array) { + // Make a copy of the image data and return a new Fl_RGB_Image... + new_array = new uchar[w() * h() * d()]; + if (ld() && ld()!=w()*d()) { + const uchar *src = array; + uchar *dst = new_array; + int dy, dh = h(), wd = w()*d(), wld = ld(); + for (dy=0; dyalloc_array = 1; + + return new_image; + } else return new Fl_RGB_Image(array, w(), h(), d(), ld()); + } + if (W <= 0 || H <= 0) return 0; + + // OK, need to resize the image data; allocate memory and + uchar *new_ptr; // Pointer into new array + const uchar *old_ptr; // Pointer into old array + int c, // Channel number + sy, // Source coordinate + dx, dy, // Destination coordinates + xerr, yerr, // X & Y errors + xmod, ymod, // X & Y moduli + xstep, ystep, // X & Y step increments + line_d; // stride from line to line + + + // Figure out Bresenheim step/modulus values... + xmod = w() % W; + xstep = (w() / W) * d(); + ymod = h() % H; + ystep = h() / H; + line_d = ld() ? ld() : w() * d(); + + // Allocate memory for the new image... + new_array = new uchar [W * H * d()]; + new_image = new Fl_RGB_Image(new_array, W, H, d()); + new_image->alloc_array = 1; + + // Scale the image using a nearest-neighbor algorithm... + for (dy = H, sy = 0, yerr = H, new_ptr = new_array; dy > 0; dy --) { + for (dx = W, xerr = W, old_ptr = array + sy * line_d; dx > 0; dx --) { + for (c = 0; c < d(); c ++) *new_ptr++ = old_ptr[c]; + + old_ptr += xstep; + xerr -= xmod; + + if (xerr <= 0) { + xerr += W; + old_ptr += d(); + } + } + + sy += ystep; + yerr -= ymod; + if (yerr <= 0) { + yerr += H; + sy ++; + } + } + + return new_image; +} + +void Fl_RGB_Image::color_average(Fl_Color c, float i) { + // Don't average an empty image... + if (!w() || !h() || !d() || !array) return; + + // Delete any existing pixmap/mask objects... + uncache(); + + // Allocate memory as needed... + uchar *new_array, + *new_ptr; + + if (!alloc_array) new_array = new uchar[h() * w() * d()]; + else new_array = (uchar *)array; + + // Get the color to blend with... + uchar r, g, b; + unsigned ia, ir, ig, ib; + + Fl::get_color(c, r, g, b); + if (i < 0.0f) i = 0.0f; + else if (i > 1.0f) i = 1.0f; + + ia = (unsigned)(256 * i); + ir = r * (256 - ia); + ig = g * (256 - ia); + ib = b * (256 - ia); + + // Update the image data to do the blend... + const uchar *old_ptr; + int x, y; + int line_i = ld() ? ld() - (w()*d()) : 0; // increment from line end to beginning of next line + + if (d() < 3) { + ig = (r * 31 + g * 61 + b * 8) / 100 * (256 - ia); + + for (new_ptr = new_array, old_ptr = array, y = 0; y < h(); y ++, old_ptr += line_i) + for (x = 0; x < w(); x ++) { + *new_ptr++ = (*old_ptr++ * ia + ig) >> 8; + if (d() > 1) *new_ptr++ = *old_ptr++; + } + } else { + for (new_ptr = new_array, old_ptr = array, y = 0; y < h(); y ++, old_ptr += line_i) + for (x = 0; x < w(); x ++) { + *new_ptr++ = (*old_ptr++ * ia + ir) >> 8; + *new_ptr++ = (*old_ptr++ * ia + ig) >> 8; + *new_ptr++ = (*old_ptr++ * ia + ib) >> 8; + if (d() > 3) *new_ptr++ = *old_ptr++; + } + } + + // Set the new pointers/values as needed... + if (!alloc_array) { + array = new_array; + alloc_array = 1; + + ld(0); + } +} + +void Fl_RGB_Image::desaturate() { + // Don't desaturate an empty image... + if (!w() || !h() || !d() || !array) return; + + // Can only desaturate color images... + if (d() < 3) return; + + // Delete any existing pixmap/mask objects... + uncache(); + + // Allocate memory for a grayscale image... + uchar *new_array, + *new_ptr; + int new_d; + + new_d = d() - 2; + new_array = new uchar[h() * w() * new_d]; + + // Copy the image data, converting to grayscale... + const uchar *old_ptr; + int x, y; + int line_i = ld() ? ld() - (w()*d()) : 0; // increment from line end to beginning of next line + + for (new_ptr = new_array, old_ptr = array, y = 0; y < h(); y ++, old_ptr += line_i) + for (x = 0; x < w(); x ++, old_ptr += d()) { + *new_ptr++ = (uchar)((31 * old_ptr[0] + 61 * old_ptr[1] + 8 * old_ptr[2]) / 100); + if (d() > 3) *new_ptr++ = old_ptr[3]; + } + + // Free the old array as needed, and then set the new pointers/values... + if (alloc_array) delete[] (uchar *)array; + + array = new_array; + alloc_array = 1; + + ld(0); + d(new_d); +} + +#if !defined(WIN32) && !defined(__APPLE_QUARTZ__) +// Composite an image with alpha on systems that don't have accelerated +// alpha compositing... +static void alpha_blend(Fl_RGB_Image *img, int X, int Y, int W, int H, int cx, int cy) { + uchar *srcptr = (uchar*)img->array + img->d() * (img->w() * cy + cx); + int srcskip = img->d() * (img->w() - W); + + uchar *dst = new uchar[W * H * 3]; + uchar *dstptr = dst; + + fl_read_image(dst, X, Y, W, H, 0); + + uchar srcr, srcg, srcb, srca; + uchar dstr, dstg, dstb, dsta; + + if (img->d() == 2) { + // Composite grayscale + alpha over RGB... + // Composite RGBA over RGB... + for (int y = H; y > 0; y--, srcptr+=srcskip) + for (int x = W; x > 0; x--) { + srcg = *srcptr++; + srca = *srcptr++; + + dstr = dstptr[0]; + dstg = dstptr[1]; + dstb = dstptr[2]; + dsta = 255 - srca; + + *dstptr++ = (srcg * srca + dstr * dsta) >> 8; + *dstptr++ = (srcg * srca + dstg * dsta) >> 8; + *dstptr++ = (srcg * srca + dstb * dsta) >> 8; + } + } else { + // Composite RGBA over RGB... + for (int y = H; y > 0; y--, srcptr+=srcskip) + for (int x = W; x > 0; x--) { + srcr = *srcptr++; + srcg = *srcptr++; + srcb = *srcptr++; + srca = *srcptr++; + + dstr = dstptr[0]; + dstg = dstptr[1]; + dstb = dstptr[2]; + dsta = 255 - srca; + + *dstptr++ = (srcr * srca + dstr * dsta) >> 8; + *dstptr++ = (srcg * srca + dstg * dsta) >> 8; + *dstptr++ = (srcb * srca + dstb * dsta) >> 8; + } + } + + fl_draw_image(dst, X, Y, W, H, 3, 0); + + delete[] dst; +} +#endif // !WIN32 && !__APPLE_QUARTZ__ + +void Fl_RGB_Image::draw(int XP, int YP, int WP, int HP, int cx, int cy) { + fl_graphics_driver->draw(this, XP, YP, WP, HP, cx, cy); +} + +static int start(Fl_RGB_Image *img, int XP, int YP, int WP, int HP, int w, int h, int &cx, int &cy, + int &X, int &Y, int &W, int &H) +{ + // account for current clip region (faster on Irix): + fl_clip_box(XP,YP,WP,HP,X,Y,W,H); + cx += X-XP; cy += Y-YP; + // clip the box down to the size of image, quit if empty: + if (cx < 0) {W += cx; X -= cx; cx = 0;} + if (cx+W > w) W = w-cx; + if (W <= 0) return 1; + if (cy < 0) {H += cy; Y -= cy; cy = 0;} + if (cy+H > h) H = h-cy; + if (H <= 0) return 1; + return 0; +} + +#ifdef __APPLE__ +void Fl_Quartz_Graphics_Driver::draw(Fl_RGB_Image *img, int XP, int YP, int WP, int HP, int cx, int cy) { + int X, Y, W, H; + // Don't draw an empty image... + if (!img->d() || !img->array) { + img->draw_empty(XP, YP); + return; + } + if (start(img, XP, YP, WP, HP, img->w(), img->h(), cx, cy, X, Y, W, H)) { + return; + } + if (!img->id_) { + CGColorSpaceRef lut = 0; + if (img->d()<=2) + lut = CGColorSpaceCreateDeviceGray(); + else + lut = CGColorSpaceCreateDeviceRGB(); + CGDataProviderRef src = CGDataProviderCreateWithData( 0L, img->array, img->w()*img->h()*img->d(), 0L); + img->id_ = CGImageCreate( img->w(), img->h(), 8, img->d()*8, img->ld()?img->ld():img->w()*img->d(), + lut, (img->d()&1)?kCGImageAlphaNone:kCGImageAlphaLast, + src, 0L, false, kCGRenderingIntentDefault); + CGColorSpaceRelease(lut); + CGDataProviderRelease(src); + } + if (img->id_ && fl_gc) { + CGRect rect = { { X, Y }, { W, H } }; + Fl_X::q_begin_image(rect, cx, cy, img->w(), img->h()); + CGContextDrawImage(fl_gc, rect, (CGImageRef)img->id_); + Fl_X::q_end_image(); + } +} + +#elif defined(WIN32) +void Fl_GDI_Graphics_Driver::draw(Fl_RGB_Image *img, int XP, int YP, int WP, int HP, int cx, int cy) { + int X, Y, W, H; + // Don't draw an empty image... + if (!img->d() || !img->array) { + img->draw_empty(XP, YP); + return; + } + if (start(img, XP, YP, WP, HP, img->w(), img->h(), cx, cy, X, Y, W, H)) { + return; + } + if (!img->id_) { + img->id_ = fl_create_offscreen(img->w(), img->h()); + if ((img->d() == 2 || img->d() == 4) && fl_can_do_alpha_blending()) { + fl_begin_offscreen((Fl_Offscreen)img->id_); + fl_draw_image(img->array, 0, 0, img->w(), img->h(), img->d()|FL_IMAGE_WITH_ALPHA, img->ld()); + fl_end_offscreen(); + } else { + fl_begin_offscreen((Fl_Offscreen)img->id_); + fl_draw_image(img->array, 0, 0, img->w(), img->h(), img->d(), img->ld()); + fl_end_offscreen(); + if (img->d() == 2 || img->d() == 4) { + img->mask_ = fl_create_alphamask(img->w(), img->h(), img->d(), img->ld(), img->array); + } + } + } + if (img->mask_) { + HDC new_gc = CreateCompatibleDC(fl_gc); + int save = SaveDC(new_gc); + SelectObject(new_gc, (void*)img->mask_); + BitBlt(fl_gc, X, Y, W, H, new_gc, cx, cy, SRCAND); + SelectObject(new_gc, (void*)img->id_); + BitBlt(fl_gc, X, Y, W, H, new_gc, cx, cy, SRCPAINT); + RestoreDC(new_gc,save); + DeleteDC(new_gc); + } else if (img->d()==2 || img->d()==4) { + fl_copy_offscreen_with_alpha(X, Y, W, H, (Fl_Offscreen)img->id_, cx, cy); + } else { + fl_copy_offscreen(X, Y, W, H, (Fl_Offscreen)img->id_, cx, cy); + } +} + +#else +void Fl_Xlib_Graphics_Driver::draw(Fl_RGB_Image *img, int XP, int YP, int WP, int HP, int cx, int cy) { + int X, Y, W, H; + // Don't draw an empty image... + if (!img->d() || !img->array) { + img->draw_empty(XP, YP); + return; + } + if (start(img, XP, YP, WP, HP, img->w(), img->h(), cx, cy, X, Y, W, H)) { + return; + } + if (!img->id_) { + if (img->d() == 1 || img->d() == 3) { + img->id_ = fl_create_offscreen(img->w(), img->h()); + fl_begin_offscreen((Fl_Offscreen)img->id_); + fl_draw_image(img->array, 0, 0, img->w(), img->h(), img->d(), img->ld()); + fl_end_offscreen(); + } + } + if (img->id_) { + if (img->mask_) { + // I can't figure out how to combine a mask with existing region, + // so cut the image down to a clipped rectangle: + int nx, ny; fl_clip_box(X,Y,W,H,nx,ny,W,H); + cx += nx-X; X = nx; + cy += ny-Y; Y = ny; + // make X use the bitmap as a mask: + XSetClipMask(fl_display, fl_gc, img->mask_); + int ox = X-cx; if (ox < 0) ox += img->w(); + int oy = Y-cy; if (oy < 0) oy += img->h(); + XSetClipOrigin(fl_display, fl_gc, X-cx, Y-cy); + } + + fl_copy_offscreen(X, Y, W, H, img->id_, cx, cy); + + if (img->mask_) { + // put the old clip region back + XSetClipOrigin(fl_display, fl_gc, 0, 0); + fl_restore_clip(); + } + } else { + // Composite image with alpha manually each time... + alpha_blend(img, X, Y, W, H, cx, cy); + } +} + +#endif + +void Fl_RGB_Image::label(Fl_Widget* widget) { + widget->image(this); +} + +void Fl_RGB_Image::label(Fl_Menu_Item* m) { + Fl::set_labeltype(_FL_IMAGE_LABEL, labeltype, measure); + m->label(_FL_IMAGE_LABEL, (const char*)this); +} + + +// +// End of "$Id: Fl_Image.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Input.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Input.cxx new file mode 100644 index 0000000..82ca615 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Input.cxx @@ -0,0 +1,663 @@ +// +// "$Id: Fl_Input.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Input widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// This is the "user interface", it decodes user actions into what to +// do to the text. See also Fl_Input_.cxx, where the text is actually +// manipulated (and some ui, in particular the mouse, is done...). +// In theory you can replace this code with another subclass to change +// the keybindings. + +#include +#include +#include +#include +#include +#include +#include +#include "flstring.h" + +#ifdef HAVE_LOCALE_H +# include +#endif + + +void Fl_Input::draw() { + if (input_type() == FL_HIDDEN_INPUT) return; + Fl_Boxtype b = box(); + if (damage() & FL_DAMAGE_ALL) draw_box(b, color()); + Fl_Input_::drawtext(x()+Fl::box_dx(b), y()+Fl::box_dy(b), + w()-Fl::box_dw(b), h()-Fl::box_dh(b)); +} + +// kludge so shift causes selection to extend: +int Fl_Input::shift_position(int p) { + return position(p, Fl::event_state(FL_SHIFT) ? mark() : p); +} + +int Fl_Input::shift_up_down_position(int p) { + return up_down_position(p, Fl::event_state(FL_SHIFT)); +} + +// If you define this symbol as zero you will get the peculiar fltk +// behavior where moving off the end of an input field will move the +// cursor into the next field: +// define it as 1 to prevent cursor movement from going to next field: +#define NORMAL_INPUT_MOVE 0 + +#define ctrl(x) ((x)^0x40) + +// List of characters that are legal in a floating point input field. +// This text string is created at run-time to take the current locale +// into account (for example, continental Europe uses a comma instead +// of a decimal point). For back compatibility reasons, we always +// allow the decimal point. +#ifdef HAVE_LOCALECONV +static const char *standard_fp_chars = ".eE+-"; +static const char *legal_fp_chars = 0L; +#else +static const char *legal_fp_chars = ".eE+-"; +#endif + +int Fl_Input::handle_key() { + + char ascii = Fl::event_text()[0]; + + int repeat_num=1; + + int del; + if (Fl::compose(del)) { + + // Insert characters into numeric fields after checking for legality: + if (input_type() == FL_FLOAT_INPUT || input_type() == FL_INT_INPUT) { + Fl::compose_reset(); // ignore any foreign letters... + + // initialize the list of legal characters inside a floating point number +#ifdef HAVE_LOCALECONV + if (!legal_fp_chars) { + int len = strlen(standard_fp_chars); + struct lconv *lc = localeconv(); + if (lc) { + if (lc->decimal_point) len += strlen(lc->decimal_point); + if (lc->mon_decimal_point) len += strlen(lc->mon_decimal_point); + if (lc->positive_sign) len += strlen(lc->positive_sign); + if (lc->negative_sign) len += strlen(lc->negative_sign); + } + // the following line is not a true memory leak because the array is only + // allocated once if required, and automatically freed when the program quits + char *chars = (char*)malloc(len+1); + legal_fp_chars = chars; + strcpy(chars, standard_fp_chars); + if (lc) { + if (lc->decimal_point) strcat(chars, lc->decimal_point); + if (lc->mon_decimal_point) strcat(chars, lc->mon_decimal_point); + if (lc->positive_sign) strcat(chars, lc->positive_sign); + if (lc->negative_sign) strcat(chars, lc->negative_sign); + } + } +#endif // HAVE_LOCALECONV + + // find the insert position + int ip = position()= '0' && ascii <= '9') + || (ip==1 && index(0)=='0' && (ascii=='x' || ascii == 'X')) + || (ip>1 && index(0)=='0' && (index(1)=='x'||index(1)=='X') + && ((ascii>='A'&& ascii<='F') || (ascii>='a'&& ascii<='f'))) + || (input_type()==FL_FLOAT_INPUT && ascii && strchr(legal_fp_chars, ascii))) + { + if (readonly()) fl_beep(); + else replace(position(), mark(), &ascii, 1); + } + return 1; + } + + if (del || Fl::event_length()) { + if (readonly()) fl_beep(); + else replace(position(), del ? position()-del : mark(), + Fl::event_text(), Fl::event_length()); + } + return 1; + } + + unsigned int mods = Fl::event_state() & (FL_META|FL_CTRL|FL_ALT); + switch (Fl::event_key()) { + case FL_Insert: + if (Fl::event_state() & FL_CTRL) ascii = ctrl('C'); + else if (Fl::event_state() & FL_SHIFT) ascii = ctrl('V'); + break; + case FL_Delete: +#ifdef __APPLE__ + if (mods==0 || mods==FL_CTRL) { // delete next char + ascii = ctrl('D'); + } else if (mods==FL_ALT) { // delete next word + if (mark() != position()) return cut(); + cut(position(), word_end(position())); + return 1; + } else if (mods==FL_META) { // delete to the end of the line + if (mark() != position()) return cut(); + cut(position(), line_end(position())); + return 1; + } else return 1; +#else + if (mods==0) { + ascii = ctrl('D'); + } else if (mods==FL_SHIFT) { + ascii = ctrl('X'); + } else return 1; +#endif + break; + case FL_Left: +#ifdef __APPLE__ + if (mods==0) { // char left + ascii = ctrl('B'); + } else if (mods==FL_ALT) { // word left + shift_position(word_start(position())); + return 1; + } else if (mods==FL_CTRL || mods==FL_META) { // start of line + shift_position(line_start(position())); + return 1; + } else return 1; +#else + if (mods==0) { // char left + ascii = ctrl('B'); + } else if (mods==FL_CTRL) { // word left + shift_position(word_start(position())); + return 1; + } else return 1; +#endif + break; + case FL_Right: +#ifdef __APPLE__ + if (mods==0) { // char right + ascii = ctrl('F'); + } else if (mods==FL_ALT) { // word right + shift_position(word_end(position())); + return 1; + } else if (mods==FL_CTRL || mods==FL_META) { // end of line + shift_position(line_end(position())); + return 1; + } else return 1; +#else + if (mods==0) { // char right + ascii = ctrl('F'); + } else if (mods==FL_CTRL) { // word right + shift_position(word_end(position())); + return 1; + } else return 1; +#endif // __APPLE__ + break; + case FL_Page_Up: +#ifdef __APPLE__ + if (mods==0) { // scroll text one page + // OS X scrolls the view, but does not move the cursor + // Fl_Input has no scroll control, so instead we move the cursor by one page + repeat_num = linesPerPage(); + ascii = ctrl('P'); + } else if (mods==FL_ALT) { // move cursor one page + repeat_num = linesPerPage(); + ascii = ctrl('P'); + } else return 1; + break; +#else + repeat_num = linesPerPage(); + // fall through +#endif + case FL_Up: +#ifdef __APPLE__ + if (mods==0) { // line up + ascii = ctrl('P'); + } else if (mods==FL_CTRL) { // scroll text down one page + // OS X scrolls the view, but does not move the cursor + // Fl_Input has no scroll control, so instead we move the cursor by one page + repeat_num = linesPerPage(); + ascii = ctrl('P'); + } else if (mods==FL_ALT) { // line start and up + if (line_start(position())==position() && position()>0) + return shift_position(line_start(position()-1)) + NORMAL_INPUT_MOVE; + else + return shift_position(line_start(position())) + NORMAL_INPUT_MOVE; + } else if (mods==FL_META) { // start of document + shift_position(0); + return 1; + } else return 1; +#else + if (mods==0) { // line up + ascii = ctrl('P'); + } else if (mods==FL_CTRL) { // scroll text down one line + // Fl_Input has no scroll control, so instead we move the cursor by one page + ascii = ctrl('P'); + } else return 1; +#endif + break; + case FL_Page_Down: +#ifdef __APPLE__ + if (mods==0) { // scroll text one page + // OS X scrolls the view, but does not move the cursor + // Fl_Input has no scroll control, so instead we move the cursor by one page + repeat_num = linesPerPage(); + ascii = ctrl('N'); + } else if (mods==FL_ALT) { // move cursor one page + repeat_num = linesPerPage(); + ascii = ctrl('N'); + } else return 1; + break; +#else + repeat_num = linesPerPage(); + // fall through +#endif + case FL_Down: +#ifdef __APPLE__ + if (mods==0) { // line down + ascii = ctrl('N'); + } else if (mods==FL_CTRL) { + // OS X scrolls the view, but does not move the cursor + // Fl_Input has no scroll control, so instead we move the cursor by one page + repeat_num = linesPerPage(); + ascii = ctrl('N'); + } else if (mods==FL_ALT) { // line end and down + if (line_end(position())==position() && position()=size()) return 0; + i = line_end(position()); + if (i == position() && i < size()) i++; + cut(position(), i); + return copy_cuts(); + case ctrl('N'): // go down one line + i = position(); + if (line_end(i) >= size()) { + if (input_type()==FL_MULTILINE_INPUT && !Fl::option(Fl::OPTION_ARROW_FOCUS)) return 1; + return NORMAL_INPUT_MOVE; + } + while (repeat_num--) { + i = line_end(i); + if (i >= size()) break; + i++; + } + shift_up_down_position(i); + return 1; + case ctrl('P'): // go up one line + i = position(); + if (!line_start(i)) { + if (input_type()==FL_MULTILINE_INPUT && !Fl::option(Fl::OPTION_ARROW_FOCUS)) return 1; + return NORMAL_INPUT_MOVE; + } + while(repeat_num--) { + i = line_start(i); + if (!i) break; + i--; + } + shift_up_down_position(line_start(i)); + return 1; + case ctrl('U'): // clear the whole document? + if (readonly()) { + fl_beep(); + return 1; + } + return cut(0, size()); + case ctrl('V'): // paste text + case ctrl('Y'): + if (readonly()) { + fl_beep(); + return 1; + } + Fl::paste(*this, 1); + return 1; + case ctrl('X'): // cut the selected text + case ctrl('W'): + if (readonly()) { + fl_beep(); + return 1; + } + copy(1); + return cut(); + case ctrl('Z'): // undo + case ctrl('_'): + if (readonly()) { + fl_beep(); + return 1; + } + return undo(); + case ctrl('I'): // insert literal + case ctrl('J'): + case ctrl('L'): + case ctrl('M'): + if (readonly()) { + fl_beep(); + return 1; + } + // insert a few selected control characters literally: + if (input_type() != FL_FLOAT_INPUT && input_type() != FL_INT_INPUT) + return replace(position(), mark(), &ascii, 1); + break; + } + + return 0; +} + +int Fl_Input::handle(int event) { + static int dnd_save_position, dnd_save_mark, drag_start = -1, newpos; + static Fl_Widget *dnd_save_focus; + switch (event) { + case FL_FOCUS: + switch (Fl::event_key()) { + case FL_Right: + position(0); + break; + case FL_Left: + position(size()); + break; + case FL_Down: + up_down_position(0); + break; + case FL_Up: + up_down_position(line_start(size())); + break; + case FL_Tab: + position(size(),0); + break; + default: + position(position(),mark());// turns off the saved up/down arrow position + break; + } + break; + + case FL_KEYBOARD: + if (Fl::event_key() == FL_Tab && mark() != position()) { + // Set the current cursor position to the end of the selection... + if (mark() > position()) + position(mark()); + else + position(position()); + return (1); + } else { + if (active_r() && window() && this == Fl::belowmouse()) + window()->cursor(FL_CURSOR_NONE); + return handle_key(); + } + //NOTREACHED + + case FL_PUSH: + if (Fl::dnd_text_ops()) { + int oldpos = position(), oldmark = mark(); + Fl_Boxtype b = box(); + Fl_Input_::handle_mouse(x()+Fl::box_dx(b), y()+Fl::box_dy(b), + w()-Fl::box_dw(b), h()-Fl::box_dh(b), 0); + newpos = position(); + position( oldpos, oldmark ); + if (Fl::focus()==this && !Fl::event_state(FL_SHIFT) && input_type()!=FL_SECRET_INPUT && + ( (newpos >= mark() && newpos < position()) || + (newpos >= position() && newpos < mark()) ) ) { + // user clicked in the selection, may be trying to drag + drag_start = newpos; + return 1; + } + drag_start = -1; + } + + if (Fl::focus() != this) { + Fl::focus(this); + handle(FL_FOCUS); + } + break; + + case FL_DRAG: + if (Fl::dnd_text_ops()) { + if (drag_start >= 0) { + if (Fl::event_is_click()) return 1; // debounce the mouse + // save the position because sometimes we don't get DND_ENTER: + dnd_save_position = position(); + dnd_save_mark = mark(); + // drag the data: + copy(0); Fl::dnd(); + return 1; + } + } + break; + + case FL_RELEASE: + if (Fl::event_button() == 2) { + Fl::event_is_click(0); // stop double click from picking a word + Fl::paste(*this, 0); + } else if (!Fl::event_is_click()) { + // copy drag-selected text to the clipboard. + copy(0); + } else if (Fl::event_is_click() && drag_start >= 0) { + // user clicked in the field and wants to reset the cursor position... + position(drag_start, drag_start); + drag_start = -1; + } else if (Fl::event_clicks()) { + // user double or triple clicked to select word or whole text + copy(0); + } + + // For output widgets, do the callback so the app knows the user + // did something with the mouse... + if (readonly()) do_callback(); + + return 1; + + case FL_DND_ENTER: + Fl::belowmouse(this); // send the leave events first + dnd_save_position = position(); + dnd_save_mark = mark(); + dnd_save_focus = Fl::focus(); + if (dnd_save_focus != this) { + Fl::focus(this); + handle(FL_FOCUS); + } + // fall through: + case FL_DND_DRAG: + //int p = mouse_position(X, Y, W, H); +#if DND_OUT_XXXX + if (Fl::focus()==this && (p>=dnd_save_position && p<=dnd_save_mark || + p>=dnd_save_mark && p<=dnd_save_position)) { + position(dnd_save_position, dnd_save_mark); + return 0; + } +#endif + { + Fl_Boxtype b = box(); + Fl_Input_::handle_mouse(x()+Fl::box_dx(b), y()+Fl::box_dy(b), + w()-Fl::box_dw(b), h()-Fl::box_dh(b), 0); + } + return 1; + + case FL_DND_LEAVE: + position(dnd_save_position, dnd_save_mark); +#if DND_OUT_XXXX + if (!focused()) +#endif + if (dnd_save_focus != this) { + Fl::focus(dnd_save_focus); + handle(FL_UNFOCUS); + } + return 1; + + case FL_DND_RELEASE: + take_focus(); + return 1; + + /* TODO: this will scroll the area, but stop if the cursor would become invisible. + That clipping happens in drawtext(). Do we change the clipping or should + we move the cursor (ouch)? + case FL_MOUSEWHEEL: + if (Fl::e_dy > 0) { + yscroll( yscroll() - Fl::e_dy*15 ); + } else if (Fl::e_dy < 0) { + yscroll( yscroll() - Fl::e_dy*15 ); + } + return 1; + */ + } + Fl_Boxtype b = box(); + return Fl_Input_::handletext(event, + x()+Fl::box_dx(b), y()+Fl::box_dy(b), + w()-Fl::box_dw(b), h()-Fl::box_dh(b)); +} + +/** + Creates a new Fl_Input widget using the given position, size, + and label string. The default boxtype is FL_DOWN_BOX. + */ +Fl_Input::Fl_Input(int X, int Y, int W, int H, const char *l) +: Fl_Input_(X, Y, W, H, l) { +} + +// +// End of "$Id: Fl_Input.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Input_.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Input_.cxx new file mode 100644 index 0000000..792cc96 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Input_.cxx @@ -0,0 +1,1258 @@ +// +// "$Id: Fl_Input_.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Common input widget routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include +#include +#include +#include +#include +#include "flstring.h" +#include +#include + +#define MAXBUF 1024 + +extern void fl_draw(const char*, int, float, float); + +//////////////////////////////////////////////////////////////// + +/** \internal + Converts a given text segment into the text that will be rendered on screen. + + This copies the text from \p p to \p buf, replacing characters with ^X + and \\nnn as necessary. + + The destination buffer is limited to \c MAXBUF (currently at 1024). All + following text is truncated. + + \param [in] p pointer to source buffer + \param [in] buf pointer to destination buffer + \return pointer to the end of the destination buffer +*/ +const char* Fl_Input_::expand(const char* p, char* buf) const { + char* o = buf; + char* e = buf+(MAXBUF-4); + const char* lastspace = p; + char* lastspace_out = o; + int width_to_lastspace = 0; + int word_count = 0; + int word_wrap; +// const char *pe = p + strlen(p); + + if (input_type()==FL_SECRET_INPUT) { + while (o= 1) *o++ = '*'; + p++; + } + + } else while (o= value_+size_ || isspace(*p & 255))) { + word_wrap = w() - Fl::box_dw(box()) - 2; + width_to_lastspace += (int)fl_width(lastspace_out, o-lastspace_out); + if (p > lastspace+1) { + if (word_count && width_to_lastspace > word_wrap) { + p = lastspace; o = lastspace_out; break; + } + word_count++; + } + lastspace = p; + lastspace_out = o; + } + + if (p >= value_+size_) break; + int c = *p++ & 255; + if (c < ' ' || c == 127) { + if (c=='\n' && input_type()==FL_MULTILINE_INPUT) {p--; break;} + if (c == '\t' && input_type()==FL_MULTILINE_INPUT) { + for (c = fl_utf_nb_char((uchar*)buf, o-buf)%8; c<8 && o= 1) n++; + p++; + } + } else while (p= 1; + p++; + } + if (returnn) *returnn = n; + return fl_width(buf, n); +} + +//////////////////////////////////////////////////////////////// + +/** \internal + Marks a range of characters for update. + + This call marks all characters from \p to the end of the + text buffer for update. At least these characters + will be redrawn in the next update cycle. + + Characters from \p mu_p to end of widget are redrawn. + If \p erase_cursor_only, small part at \p mu_p is redrawn. + Right now minimal update just keeps unchanged characters from + being erased, so they don't blink. + + \param [in] p start of update range +*/ +void Fl_Input_::minimal_update(int p) { + if (damage() & FL_DAMAGE_ALL) return; // don't waste time if it won't be done + if (damage() & FL_DAMAGE_EXPOSE) { + if (p < mu_p) mu_p = p; + } else { + mu_p = p; + } + + damage(FL_DAMAGE_EXPOSE); + erase_cursor_only = 0; +} + +/** \internal + Marks a range of characters for update. + + This call marks a text range for update. At least all characters + from \p p to \p q will be redrawn in the next update cycle. + + \param [in] p start of update range + \param [in] q end of update range +*/ +void Fl_Input_::minimal_update(int p, int q) { + if (q < p) p = q; + minimal_update(p); +} + +//////////////////////////////////////////////////////////////// + +/* Horizontal cursor position in pixels while moving up or down. */ +double Fl_Input_::up_down_pos = 0; + +/* Flag to remember last cursor move. */ +int Fl_Input_::was_up_down = 0; + +/** + Sets the current font and font size. +*/ +void Fl_Input_::setfont() const { + fl_font(textfont(), textsize()); +} + +/** + Draws the text in the passed bounding box. + + If damage() & FL_DAMAGE_ALL is true, this assumes the + area has already been erased to color(). Otherwise it does + minimal update and erases the area itself. + + \param X, Y, W, H area that must be redrawn +*/ +void Fl_Input_::drawtext(int X, int Y, int W, int H) { + int do_mu = !(damage()&FL_DAMAGE_ALL); + + if (Fl::focus()!=this && !size()) { + if (do_mu) { // we have to erase it if cursor was there + draw_box(box(), X-Fl::box_dx(box()), Y-Fl::box_dy(box()), + W+Fl::box_dw(box()), H+Fl::box_dh(box()), color()); + } + return; + } + + int selstart, selend; + if (Fl::focus()!=this && /*Fl::selection_owner()!=this &&*/ Fl::pushed()!=this) + selstart = selend = 0; + else if (position() <= mark()) { + selstart = position(); selend = mark(); + } else { + selend = position(); selstart = mark(); + } + + setfont(); + const char *p, *e; + char buf[MAXBUF]; + + // count how many lines and put the last one into the buffer: + // And figure out where the cursor is: + int height = fl_height(); + int threshold = height/2; + int lines; + int curx, cury; + for (p=value(), curx=cury=lines=0; ;) { + e = expand(p, buf); + if (position() >= p-value() && position() <= e-value()) { + curx = int(expandpos(p, value()+position(), buf, 0)+.5); + if (Fl::focus()==this && !was_up_down) up_down_pos = curx; + cury = lines*height; + int newscroll = xscroll_; + if (curx > newscroll+W-threshold) { + // figure out scrolling so there is space after the cursor: + newscroll = curx+threshold-W; + // figure out the furthest left we ever want to scroll: + int ex = int(expandpos(p, e, buf, 0))+2-W; + // use minimum of both amounts: + if (ex < newscroll) newscroll = ex; + } else if (curx < newscroll+threshold) { + newscroll = curx-threshold; + } + if (newscroll < 0) newscroll = 0; + if (newscroll != xscroll_) { + xscroll_ = newscroll; + mu_p = 0; erase_cursor_only = 0; + } + } + lines++; + if (e >= value_+size_) break; + p = e+1; + } + + // adjust the scrolling: + if (input_type()==FL_MULTILINE_INPUT) { + int newy = yscroll_; + if (cury < newy) newy = cury; + if (cury > newy+H-height) newy = cury-H+height; + if (newy < -1) newy = -1; + if (newy != yscroll_) {yscroll_ = newy; mu_p = 0; erase_cursor_only = 0;} + } else { + yscroll_ = -(H-height)/2; + } + + fl_push_clip(X, Y, W, H); + Fl_Color tc = active_r() ? textcolor() : fl_inactive(textcolor()); + + p = value(); + // visit each line and draw it: + int desc = height-fl_descent(); + float xpos = (float)(X - xscroll_ + 1); + int ypos = -yscroll_; + for (; ypos < H;) { + + // re-expand line unless it is the last one calculated above: + if (lines>1) e = expand(p, buf); + + if (ypos <= -height) goto CONTINUE; // clipped off top + + if (do_mu) { // for minimal update: + const char* pp = value()+mu_p; // pointer to where minimal update starts + if (e < pp) goto CONTINUE2; // this line is before the changes + if (readonly()) erase_cursor_only = 0; // this isn't the most efficient way + if (erase_cursor_only && p > pp) goto CONTINUE2; // this line is after + // calculate area to erase: + float r = (float)(X+W); + float xx; + if (p >= pp) { + xx = (float)X; + if (erase_cursor_only) r = xpos+2; + else if (readonly()) xx -= 3; + } else { + xx = xpos + (float)expandpos(p, pp, buf, 0); + if (erase_cursor_only) r = xx+2; + else if (readonly()) xx -= 3; + } + // clip to and erase it: + fl_push_clip((int)xx-1-height/8, Y+ypos, (int)(r-xx+2+height/4), height); + draw_box(box(), X-Fl::box_dx(box()), Y-Fl::box_dy(box()), + W+Fl::box_dw(box()), H+Fl::box_dh(box()), color()); + // it now draws entire line over it + // this should not draw letters to left of erased area, but + // that is nyi. + } + + // Draw selection area if required: + if (selstart < selend && selstart <= e-value() && selend > p-value()) { + const char* pp = value()+selstart; + float x1 = xpos; + int offset1 = 0; + if (pp > p) { + fl_color(tc); + x1 += (float)expandpos(p, pp, buf, &offset1); + fl_draw(buf, offset1, xpos, (float)(Y+ypos+desc)); + } + pp = value()+selend; + float x2 = (float)(X+W); + int offset2; + if (pp <= e) x2 = xpos + (float)expandpos(p, pp, buf, &offset2); + else offset2 = strlen(buf); + fl_color(selection_color()); + fl_rectf((int)(x1+0.5), Y+ypos, (int)(x2-x1+0.5), height); + fl_color(fl_contrast(textcolor(), selection_color())); + fl_draw(buf+offset1, offset2-offset1, x1, (float)(Y+ypos+desc)); + if (pp < e) { + fl_color(tc); + fl_draw(buf+offset2, strlen(buf+offset2), x2, (float)(Y+ypos+desc)); + } + } else { + // draw unselected text + fl_color(tc); + fl_draw(buf, strlen(buf), xpos, (float)(Y+ypos+desc)); + } + + if (do_mu) fl_pop_clip(); + + CONTINUE2: + // draw the cursor: + if (Fl::focus() == this && selstart == selend && + position() >= p-value() && position() <= e-value()) { + fl_color(cursor_color()); + if (readonly()) { + fl_line((int)(xpos+curx-2.5f), Y+ypos+height-1, + (int)(xpos+curx+0.5f), Y+ypos+height-4, + (int)(xpos+curx+3.5f), Y+ypos+height-1); + } else { + fl_rectf((int)(xpos+curx+0.5), Y+ypos, 2, height); + } + } + + CONTINUE: + ypos += height; + if (e >= value_+size_) break; + if (*e == '\n' || *e == ' ') e++; + p = e; + } + + // for minimal update, erase all lines below last one if necessary: + if (input_type()==FL_MULTILINE_INPUT && do_mu && ypos= size() || !isword(index(i))) +// while (i > 0 && !isword(index(i-1))) i--; + while (i > 0 && !isword(index(i-1))) i--; + while (i > 0 && isword(index(i-1))) i--; + return i; +} + +/** + Finds the end of a line. + + This call calculates the end of a line based on the given + index \p i. + + \param [in] i starting index for the search + \return end of the line +*/ +int Fl_Input_::line_end(int i) const { + if (input_type() != FL_MULTILINE_INPUT) return size(); + + if (wrap()) { + // go to the start of the paragraph: + int j = i; + while (j > 0 && index(j-1) != '\n') j--; + // now measure lines until we get past i, end of that line is real eol: + setfont(); + for (const char* p=value()+j; ;) { + char buf[MAXBUF]; + p = expand(p, buf); + if (p-value() >= i) return p-value(); + p++; + } + } else { + while (i < size() && index(i) != '\n') i++; + return i; + } +} + +/** + Finds the start of a line. + + This call calculates the start of a line based on the given + index \p i. + + \param [in] i starting index for the search + \return start of the line +*/ +int Fl_Input_::line_start(int i) const { + if (input_type() != FL_MULTILINE_INPUT) return 0; + int j = i; + while (j > 0 && index(j-1) != '\n') j--; + if (wrap()) { + // now measure lines until we get past i, start of that line is real eol: + setfont(); + for (const char* p=value()+j; ;) { + char buf[MAXBUF]; + const char* e = expand(p, buf); + if (e-value() >= i) return p-value(); + p = e+1; + } + } else return j; +} + +/** + Handles mouse clicks and mouse moves. + \todo Add comment and parameters +*/ +void Fl_Input_::handle_mouse(int X, int Y, int /*W*/, int /*H*/, int drag) { + was_up_down = 0; + if (!size()) return; + setfont(); + + const char *p, *e; + char buf[MAXBUF]; + + int theline = (input_type()==FL_MULTILINE_INPUT) ? + (Fl::event_y()-Y+yscroll_)/fl_height() : 0; + + int newpos = 0; + for (p=value();; ) { + e = expand(p, buf); + theline--; if (theline < 0) break; + if (e >= value_+size_) break; + p = e+1; + } + const char *l, *r, *t; double f0 = Fl::event_x()-X+xscroll_; + for (l = p, r = e; l 0) { + f1 = X-xscroll_+expandpos(p, l + cw, buf, 0) - Fl::event_x(); + if (f1 < f0) l = l+cw; + } + } + newpos = l-value(); + + int newmark = drag ? mark() : newpos; + if (Fl::event_clicks()) { + if (newpos >= newmark) { + if (newpos == newmark) { + if (newpos < size()) newpos++; + else newmark--; + } + if (Fl::event_clicks() > 1) { + newpos = line_end(newpos); + newmark = line_start(newmark); + } else { + newpos = word_end(newpos); + newmark = word_start(newmark); + } + } else { + if (Fl::event_clicks() > 1) { + newpos = line_start(newpos); + newmark = line_end(newmark); + } else { + newpos = word_start(newpos); + newmark = word_end(newmark); + } + } + // if the multiple click does not increase the selection, revert + // to single-click behavior: + if (!drag && (mark() > position() ? + (newmark >= position() && newpos <= mark()) : + (newmark >= mark() && newpos <= position()))) { + Fl::event_clicks(0); + newmark = newpos = l-value(); + } + } + position(newpos, newmark); +} + +/** + Sets the index for the cursor and mark. + + The input widget maintains two pointers into the string. The + \e position (\c p) is where the cursor is. The + \e mark (\c m) is the other end of the selected text. If they + are equal then there is no selection. Changing this does not + affect the clipboard (use copy() to do that). + + Changing these values causes a redraw(). The new + values are bounds checked. + + \param p index for the cursor position + \param m index for the mark + \return 0 if no positions changed + \see position(int), position(), mark(int) +*/ +int Fl_Input_::position(int p, int m) { + int is_same = 0; + was_up_down = 0; + if (p<0) p = 0; + if (p>size()) p = size(); + if (m<0) m = 0; + if (m>size()) m = size(); + if (p == m) is_same = 1; + + while (p < position_ && p > 0 && (size() - p) > 0 && + (fl_utf8len((char)(value() + p)[0]) < 1)) { p--; } + int ul = fl_utf8len((char)(value() + p)[0]); + while (p < size() && p > position_ && ul < 0) { + p++; + ul = fl_utf8len((char)(value() + p)[0]); + } + + while (m < mark_ && m > 0 && (size() - m) > 0 && + (fl_utf8len((char)(value() + m)[0]) < 1)) { m--; } + ul = fl_utf8len((char)(value() + m)[0]); + while (m < size() && m > mark_ && ul < 0) { + m++; + ul = fl_utf8len((char)(value() + m)[0]); + } + if (is_same) m = p; + if (p == position_ && m == mark_) return 0; + + + //if (Fl::selection_owner() == this) Fl::selection_owner(0); + if (p != m) { + if (p != position_) minimal_update(position_, p); + if (m != mark_) minimal_update(mark_, m); + } else { + // new position is a cursor + if (position_ == mark_) { + // old position was just a cursor + if (Fl::focus() == this && !(damage()&FL_DAMAGE_EXPOSE)) { + minimal_update(position_); erase_cursor_only = 1; + } + } else { // old position was a selection + minimal_update(position_, mark_); + } + } + position_ = p; + mark_ = m; + return 1; +} + +/** + Moves the cursor to the column given by \p up_down_pos. + + This function is helpful when implementing up and down + cursor movement. It moves the cursor from the beginning + of a line to the column indicated by the global variable + \p up_down_pos in pixel units. + + \param [in] i index into the beginning of a line of text + \param [in] keepmark if set, move only the cursor, but not the mark + \return index to new cursor position +*/ +int Fl_Input_::up_down_position(int i, int keepmark) { + // unlike before, i must be at the start of the line already! + + setfont(); + char buf[MAXBUF]; + const char* p = value()+i; + const char* e = expand(p, buf); + const char *l, *r, *t; + for (l = p, r = e; l e) {b = mark(); e = position();} + if (input_type() == FL_SECRET_INPUT) e = b; + Fl::copy(value()+b, e-b, clipboard); + return 1; + } + return 0; +} + +#define MAXFLOATSIZE 40 + +static char* undobuffer; +static int undobufferlength; +static Fl_Input_* undowidget; +static int undoat; // points after insertion +static int undocut; // number of characters deleted there +static int undoinsert; // number of characters inserted +static int yankcut; // length of valid contents of buffer, even if undocut=0 + +static void undobuffersize(int n) { + if (n > undobufferlength) { + if (undobuffer) { + do {undobufferlength *= 2;} while (undobufferlength < n); + undobuffer = (char*)realloc(undobuffer, undobufferlength); + } else { + undobufferlength = n+9; + undobuffer = (char*)malloc(undobufferlength); + } + } +} + +/** + Deletes text from \p b to \p e and inserts the new string \p text. + + All changes to the text buffer go through this function. + It deletes the region between \p a and \p b (either one may be less or + equal to the other), and then inserts the string \p text + at that point and moves the mark() and + position() to the end of the insertion. Does the callback if + when() & FL_WHEN_CHANGED and there is a change. + + Set \p b and \p e equal to not delete anything. + Set \p text to \c NULL to not insert anything. + + \p ilen can be zero or strlen(text), which + saves a tiny bit of time if you happen to already know the + length of the insertion, or can be used to insert a portion of a + string. + + \p b and \p e are clamped to the + 0..size() range, so it is safe to pass any values. + + cut() and insert() are just inline functions that call replace(). + + \param [in] b beginning index of text to be deleted + \param [in] e ending index of text to be deleted and insertion position + \param [in] text string that will be inserted + \param [in] ilen length of \p text or 0 for \c nul terminated strings + \return 0 if nothing changed +*/ +int Fl_Input_::replace(int b, int e, const char* text, int ilen) { + int ul, om, op; + was_up_down = 0; + + if (b<0) b = 0; + if (e<0) e = 0; + if (b>size_) b = size_; + if (e>size_) e = size_; + if (e 0 && (size_ - b) > 0 && + (fl_utf8len((value_ + b)[0]) < 1)) { b--; } + ul = fl_utf8len((char)(value_ + e)[0]); + while (e < size_ && e > 0 && ul < 0) { + e++; + ul = fl_utf8len((char)(value_ + e)[0]); + } + if (text && !ilen) ilen = strlen(text); + if (e<=b && !ilen) return 0; // don't clobber undo for a null operation + if (size_+ilen-(e-b) > maximum_size_) { + ilen = maximum_size_-size_+(e-b); + if (ilen < 0) ilen = 0; + } + + put_in_buffer(size_+ilen); + + if (e>b) { + if (undowidget == this && b == undoat) { + undobuffersize(undocut+(e-b)); + memcpy(undobuffer+undocut, value_+b, e-b); + undocut += e-b; + } else if (undowidget == this && e == undoat && !undoinsert) { + undobuffersize(undocut+(e-b)); + memmove(undobuffer+(e-b), undobuffer, undocut); + memcpy(undobuffer, value_+b, e-b); + undocut += e-b; + } else if (undowidget == this && e == undoat && (e-b) 0 && !isspace(index(b) & 255) && index(b)!='\n') b--; + else + while (b > 0 && index(b)!='\n') b--; + } + + // make sure we redraw the old selection or cursor: + if (om < b) b = om; + if (op < b) b = op; + + minimal_update(b); + + mark_ = position_ = undoat; + + set_changed(); + if (when()&FL_WHEN_CHANGED) do_callback(); + return 1; +} + +/** + Undoes previous changes to the text buffer. + + This call undoes a number of previous calls to replace(). + + \return non-zero if any change was made. +*/ +int Fl_Input_::undo() { + was_up_down = 0; + if ( undowidget != this || (!undocut && !undoinsert) ) return 0; + + int ilen = undocut; + int xlen = undoinsert; + int b = undoat-xlen; + int b1 = b; + + put_in_buffer(size_+ilen); + + if (ilen) { + memmove(buffer+b+ilen, buffer+b, size_-b+1); + memcpy(buffer+b, undobuffer, ilen); + size_ += ilen; + b += ilen; + } + + if (xlen) { + undobuffersize(xlen); + memcpy(undobuffer, buffer+b, xlen); + memmove(buffer+b, buffer+b+xlen, size_-xlen-b+1); + size_ -= xlen; + } + + undocut = xlen; + if (xlen) yankcut = xlen; + undoinsert = ilen; + undoat = b; + mark_ = b /* -ilen */; + position_ = b; + + if (wrap()) + while (b1 > 0 && index(b1)!='\n') b1--; + minimal_update(b1); + set_changed(); + if (when()&FL_WHEN_CHANGED) do_callback(); + return 1; +} + +/** + Copies the \e yank buffer to the clipboard. + + This method copies all the previous contiguous cuts from the undo + information to the clipboard. This function implements + the \c ^K shortcut key. + + \return 0 if the operation did not change the clipboard + \see copy(int), cut() +*/ +int Fl_Input_::copy_cuts() { + // put the yank buffer into the X clipboard + if (!yankcut || input_type()==FL_SECRET_INPUT) return 0; + Fl::copy(undobuffer, yankcut, 1); + return 1; +} + +/** \internal + Checks the when() field and does a callback if indicated. +*/ +void Fl_Input_::maybe_do_callback() { + if (changed() || (when()&FL_WHEN_NOT_CHANGED)) { + do_callback(); + } +} + +/** + Handles all kinds of text field related events. + + This is called by derived classes. + \todo Add comment and parameters +*/ +int Fl_Input_::handletext(int event, int X, int Y, int W, int H) { + switch (event) { + + case FL_ENTER: + case FL_MOVE: + if (active_r() && window()) window()->cursor(FL_CURSOR_INSERT); + return 1; + + case FL_LEAVE: + if (active_r() && window()) window()->cursor(FL_CURSOR_DEFAULT); + return 1; + + case FL_FOCUS: + fl_set_spot(textfont(), textsize(), x(), y(), w(), h(), window()); + if (mark_ == position_) { + minimal_update(size()+1); + } else //if (Fl::selection_owner() != this) + minimal_update(mark_, position_); + return 1; + + case FL_UNFOCUS: + if (active_r() && window()) window()->cursor(FL_CURSOR_DEFAULT); + if (mark_ == position_) { + if (!(damage()&FL_DAMAGE_EXPOSE)) {minimal_update(position_); erase_cursor_only = 1;} + } else //if (Fl::selection_owner() != this) + minimal_update(mark_, position_); + case FL_HIDE: + fl_reset_spot(); + if (!readonly() && (when() & FL_WHEN_RELEASE)) + maybe_do_callback(); + return 1; + + case FL_PUSH: + if (active_r() && window()) window()->cursor(FL_CURSOR_INSERT); + + handle_mouse(X, Y, W, H, Fl::event_state(FL_SHIFT)); + + if (Fl::focus() != this) { + Fl::focus(this); + handle(FL_FOCUS); + } + return 1; + + case FL_DRAG: + handle_mouse(X, Y, W, H, 1); + return 1; + + case FL_RELEASE: + copy(0); + return 1; + + case FL_PASTE: { + // Don't allow pastes into readonly widgets... + if (readonly()) { + fl_beep(FL_BEEP_ERROR); + return 1; + } + + // See if we have anything to paste... + if (!Fl::event_text() || !Fl::event_length()) return 1; + + // strip trailing control characters and spaces before pasting: + const char* t = Fl::event_text(); + const char* e = t+Fl::event_length(); + if (input_type() != FL_MULTILINE_INPUT) while (e > t && isspace(*(e-1) & 255)) e--; + if (!t || e <= t) return 1; // Int/float stuff will crash without this test + if (input_type() == FL_INT_INPUT) { + while (isspace(*t & 255) && t < e) t ++; + const char *p = t; + if (*p == '+' || *p == '-') p ++; + if (strncmp(p, "0x", 2) == 0) { + p += 2; + while (isxdigit(*p & 255) && p < e) p ++; + } else { + while (isdigit(*p & 255) && p < e) p ++; + } + if (p < e) { + fl_beep(FL_BEEP_ERROR); + return 1; + } else return replace(0, size(), t, e - t); + } else if (input_type() == FL_FLOAT_INPUT) { + while (isspace(*t & 255) && t < e) t ++; + const char *p = t; + if (*p == '+' || *p == '-') p ++; + while (isdigit(*p & 255) && p < e) p ++; + if (*p == '.') { + p ++; + while (isdigit(*p & 255) && p < e) p ++; + if (*p == 'e' || *p == 'E') { + p ++; + if (*p == '+' || *p == '-') p ++; + while (isdigit(*p & 255) && p < e) p ++; + } + } + if (p < e) { + fl_beep(FL_BEEP_ERROR); + return 1; + } else return replace(0, size(), t, e - t); + } + return replace(position(), mark(), t, e-t);} + + case FL_SHORTCUT: + if (!(shortcut() ? Fl::test_shortcut(shortcut()) : test_shortcut())) + return 0; + if (Fl::visible_focus() && handle(FL_FOCUS)) { + Fl::focus(this); + return 1; + } // else fall through + + default: + return 0; + } +} + +/*------------------------------*/ + +/** + Creates a new Fl_Input_ widget. + + This function creates a new Fl_Input_ widget and adds it to the current + Fl_Group. The value() is set to \c NULL. + The default boxtype is \c FL_DOWN_BOX. + + \param X, Y, W, H the dimensions of the new widget + \param l an optional label text +*/ +Fl_Input_::Fl_Input_(int X, int Y, int W, int H, const char* l) +: Fl_Widget(X, Y, W, H, l) { + box(FL_DOWN_BOX); + color(FL_BACKGROUND2_COLOR, FL_SELECTION_COLOR); + align(FL_ALIGN_LEFT); + textsize_ = FL_NORMAL_SIZE; + textfont_ = FL_HELVETICA; + textcolor_ = FL_FOREGROUND_COLOR; + cursor_color_ = FL_FOREGROUND_COLOR; // was FL_BLUE + mark_ = position_ = size_ = 0; + bufsize = 0; + buffer = 0; + value_ = ""; + xscroll_ = yscroll_ = 0; + maximum_size_ = 32767; + shortcut_ = 0; + set_flag(SHORTCUT_LABEL); +} + +/** + Copies the value from a possibly static entry into the internal buffer. + + \param [in] len size of the current text +*/ +void Fl_Input_::put_in_buffer(int len) { + if (value_ == buffer && bufsize > len) { + buffer[size_] = 0; + return; + } + if (!bufsize) { + if (len > size_) len += 9; // let a few characters insert before realloc + bufsize = len+1; + buffer = (char*)malloc(bufsize); + } else if (bufsize <= len) { + // we may need to move old value in case it points into buffer: + int moveit = (value_ >= buffer && value_ < buffer+bufsize); + // enlarge current buffer + if (len > size_) { + do {bufsize *= 2;} while (bufsize <= len); + } else { + bufsize = len+1; + } + // Note: the following code is equivalent to: + // + // if (moveit) value_ = value_ - buffer; + // char* nbuffer = (char*)realloc(buffer, bufsize); + // if (moveit) value_ = value_ + nbuffer; + // buffer = nbuffer; + // + // We just optimized the pointer arithmetic for value_... + // + char* nbuffer = (char*)realloc(buffer, bufsize); + if (moveit) value_ += (nbuffer-buffer); + buffer = nbuffer; + } + memmove(buffer, value_, size_); buffer[size_] = 0; + value_ = buffer; +} + +/** + Changes the widget text. + + This function changes the text and sets the mark and the point to + the end of it. The string is \e not copied. If the user edits the + string it is copied to the internal buffer then. This can save a + great deal of time and memory if your program is rapidly + changing the values of text fields, but this will only work if + the passed string remains unchanged until either the + Fl_Input is destroyed or value() is called again. + + You can use the \p len parameter to directly set the length + if you know it already or want to put \c nul characters in the text. + + \param [in] str the new text + \param [in] len the length of the new text + \return non-zero if the new value is different than the current one +*/ +int Fl_Input_::static_value(const char* str, int len) { + clear_changed(); + if (undowidget == this) undowidget = 0; + if (str == value_ && len == size_) return 0; + if (len) { // non-empty new value: + if (xscroll_ || yscroll_) { + xscroll_ = yscroll_ = 0; + minimal_update(0); + } else { + int i = 0; + // find first different character: + if (value_) { + for (; i +#include +#include +#include +#include +#include + + +// Some releases of the Cygwin JPEG libraries don't have a correctly +// updated header file for the INT32 data type; the following define +// from Shane Hill seems to be a usable workaround... + +#if defined(WIN32) && defined(__CYGWIN__) +# define XMD_H +#endif // WIN32 && __CYGWIN__ + + +extern "C" +{ +#ifdef HAVE_LIBJPEG +# include +#endif // HAVE_LIBJPEG +} + + +// +// Custom JPEG error handling structure... +// + +#ifdef HAVE_LIBJPEG +struct fl_jpeg_error_mgr { + jpeg_error_mgr pub_; // Destination manager... + jmp_buf errhand_; // Error handler +}; +#endif // HAVE_LIBJPEG + + +// +// Error handler for JPEG files... +// + +#ifdef HAVE_LIBJPEG +extern "C" { + static void + fl_jpeg_error_handler(j_common_ptr dinfo) { // I - Decompressor info + longjmp(((fl_jpeg_error_mgr *)(dinfo->err))->errhand_, 1); + } + + static void + fl_jpeg_output_handler(j_common_ptr) { // I - Decompressor info (not used) + } +} +#endif // HAVE_LIBJPEG + + +/** + \brief The constructor loads the JPEG image from the given jpeg filename. + + The inherited destructor frees all memory and server resources that are used + by the image. + + There is no error function in this class. If the image has loaded correctly, + w(), h(), and d() should return values greater zero. + + \param filename a full path and name pointing to a valid jpeg file. + */ +Fl_JPEG_Image::Fl_JPEG_Image(const char *filename) // I - File to load +: Fl_RGB_Image(0,0,0) { +#ifdef HAVE_LIBJPEG + FILE *fp; // File pointer + jpeg_decompress_struct dinfo; // Decompressor info + fl_jpeg_error_mgr jerr; // Error handler info + JSAMPROW row; // Sample row pointer + + // the following variables are pointers allocating some private space that + // is not reset by 'setjmp()' + char* max_finish_decompress_err; // count errors and give up afer a while + char* max_destroy_decompress_err; // to avoid recusion and deadlock + + // Clear data... + alloc_array = 0; + array = (uchar *)0; + + // Open the image file... + if ((fp = fl_fopen(filename, "rb")) == NULL) return; + + // Setup the decompressor info and read the header... + dinfo.err = jpeg_std_error((jpeg_error_mgr *)&jerr); + jerr.pub_.error_exit = fl_jpeg_error_handler; + jerr.pub_.output_message = fl_jpeg_output_handler; + + // Setup error loop variables + max_finish_decompress_err = (char*)malloc(1); // allocate space on the frame for error counters + max_destroy_decompress_err = (char*)malloc(1); // otherwise, the variables are reset on the longjmp + *max_finish_decompress_err=10; + *max_destroy_decompress_err=10; + + if (setjmp(jerr.errhand_)) + { + // JPEG error handling... + // if any of the cleanup routines hits another error, we would end up + // in a loop. So instead, we decrement max_err for some upper cleanup limit. + if ( ((*max_finish_decompress_err)-- > 0) && array) + jpeg_finish_decompress(&dinfo); + if ( (*max_destroy_decompress_err)-- > 0) + jpeg_destroy_decompress(&dinfo); + + fclose(fp); + + w(0); + h(0); + d(0); + + if (array) { + delete[] (uchar *)array; + array = 0; + alloc_array = 0; + } + + free(max_destroy_decompress_err); + free(max_finish_decompress_err); + + return; + } + + jpeg_create_decompress(&dinfo); + jpeg_stdio_src(&dinfo, fp); + jpeg_read_header(&dinfo, 1); + + dinfo.quantize_colors = (boolean)FALSE; + dinfo.out_color_space = JCS_RGB; + dinfo.out_color_components = 3; + dinfo.output_components = 3; + + jpeg_calc_output_dimensions(&dinfo); + + w(dinfo.output_width); + h(dinfo.output_height); + d(dinfo.output_components); + + array = new uchar[w() * h() * d()]; + alloc_array = 1; + + jpeg_start_decompress(&dinfo); + + while (dinfo.output_scanline < dinfo.output_height) { + row = (JSAMPROW)(array + + dinfo.output_scanline * dinfo.output_width * + dinfo.output_components); + jpeg_read_scanlines(&dinfo, &row, (JDIMENSION)1); + } + + jpeg_finish_decompress(&dinfo); + jpeg_destroy_decompress(&dinfo); + + free(max_destroy_decompress_err); + free(max_finish_decompress_err); + + fclose(fp); +#endif // HAVE_LIBJPEG +} + + +// data source manager for reading jpegs from memory +// init_source (j_decompress_ptr cinfo) +// fill_input_buffer (j_decompress_ptr cinfo) +// skip_input_data (j_decompress_ptr cinfo, long num_bytes) +// resync_to_restart (j_decompress_ptr cinfo, int desired) +// term_source (j_decompress_ptr cinfo) +// JOCTET * next_output_byte; /* => next byte to write in buffer */ +// size_t free_in_buffer; /* # of byte spaces remaining in buffer */ + +#ifdef HAVE_LIBJPEG +typedef struct { + struct jpeg_source_mgr pub; + const unsigned char *data, *s; + // JOCTET * buffer; /* start of buffer */ + // boolean start_of_file; /* have we gotten any data yet? */ +} my_source_mgr; + +typedef my_source_mgr *my_src_ptr; + + +void init_source (j_decompress_ptr cinfo) { + my_src_ptr src = (my_src_ptr)cinfo->src; + src->s = src->data; +} + +boolean fill_input_buffer(j_decompress_ptr cinfo) { + my_src_ptr src = (my_src_ptr)cinfo->src; + size_t nbytes = 4096; + src->pub.next_input_byte = src->s; + src->pub.bytes_in_buffer = nbytes; + src->s += nbytes; + return TRUE; +} + +void term_source(j_decompress_ptr cinfo) +{ +} + +void skip_input_data(j_decompress_ptr cinfo, long num_bytes) { + my_src_ptr src = (my_src_ptr)cinfo->src; + if (num_bytes > 0) { + while (num_bytes > (long)src->pub.bytes_in_buffer) { + num_bytes -= (long)src->pub.bytes_in_buffer; + fill_input_buffer(cinfo); + } + src->pub.next_input_byte += (size_t) num_bytes; + src->pub.bytes_in_buffer -= (size_t) num_bytes; + } +} + +static void jpeg_mem_src(j_decompress_ptr cinfo, const unsigned char *data) +{ + my_src_ptr src; + cinfo->src = (struct jpeg_source_mgr *)malloc(sizeof(my_source_mgr)); + src = (my_src_ptr)cinfo->src; + src->pub.init_source = init_source; + src->pub.fill_input_buffer = fill_input_buffer; + src->pub.skip_input_data = skip_input_data; + src->pub.resync_to_restart = jpeg_resync_to_restart; + src->pub.term_source = term_source; + src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */ + src->pub.next_input_byte = NULL; /* until buffer loaded */ + src->data = data; + src->s = data; +} +#endif // HAVE_LIBJPEG + + +/** + \brief The constructor loads the JPEG image from memory. + + The inherited destructor frees all memory and server resources that are used + by the image. + + There is no error function in this class. If the image has loaded correctly, + w(), h(), and d() should return values greater zero. + + \param name developer shoud provide a unique name for this image + \param data a pointer to the memorry location of the jpeg image + */ +Fl_JPEG_Image::Fl_JPEG_Image(const char *name, const unsigned char *data) +: Fl_RGB_Image(0,0,0) { +#ifdef HAVE_LIBJPEG + jpeg_decompress_struct dinfo; // Decompressor info + fl_jpeg_error_mgr jerr; // Error handler info + JSAMPROW row; // Sample row pointer + + // the following variables are pointers allocating some private space that + // is not reset by 'setjmp()' + char* max_finish_decompress_err; // count errors and give up afer a while + char* max_destroy_decompress_err; // to avoid recusion and deadlock + + // Clear data... + alloc_array = 0; + array = (uchar *)0; + + // Setup the decompressor info and read the header... + dinfo.err = jpeg_std_error((jpeg_error_mgr *)&jerr); + jerr.pub_.error_exit = fl_jpeg_error_handler; + jerr.pub_.output_message = fl_jpeg_output_handler; + + // Setup error loop variables + max_finish_decompress_err = (char*)malloc(1); // allocate space on the frame for error counters + max_destroy_decompress_err = (char*)malloc(1); // otherwise, the variables are reset on the longjmp + *max_finish_decompress_err=10; + *max_destroy_decompress_err=10; + + if (setjmp(jerr.errhand_)) + { + // JPEG error handling... + // if any of the cleanup routines hits another error, we would end up + // in a loop. So instead, we decrement max_err for some upper cleanup limit. + if ( ((*max_finish_decompress_err)-- > 0) && array) + jpeg_finish_decompress(&dinfo); + if ( (*max_destroy_decompress_err)-- > 0) + jpeg_destroy_decompress(&dinfo); + + w(0); + h(0); + d(0); + + if (array) { + delete[] (uchar *)array; + array = 0; + alloc_array = 0; + } + + free(max_destroy_decompress_err); + free(max_finish_decompress_err); + + return; + } + + jpeg_create_decompress(&dinfo); + jpeg_mem_src(&dinfo, data); + jpeg_read_header(&dinfo, 1); + + dinfo.quantize_colors = (boolean)FALSE; + dinfo.out_color_space = JCS_RGB; + dinfo.out_color_components = 3; + dinfo.output_components = 3; + + jpeg_calc_output_dimensions(&dinfo); + + w(dinfo.output_width); + h(dinfo.output_height); + d(dinfo.output_components); + + array = new uchar[w() * h() * d()]; + alloc_array = 1; + + jpeg_start_decompress(&dinfo); + + while (dinfo.output_scanline < dinfo.output_height) { + row = (JSAMPROW)(array + + dinfo.output_scanline * dinfo.output_width * + dinfo.output_components); + jpeg_read_scanlines(&dinfo, &row, (JDIMENSION)1); + } + + jpeg_finish_decompress(&dinfo); + jpeg_destroy_decompress(&dinfo); + + free(max_destroy_decompress_err); + free(max_finish_decompress_err); +#endif // HAVE_LIBJPEG +} + +// +// End of "$Id: Fl_JPEG_Image.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Light_Button.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Light_Button.cxx new file mode 100644 index 0000000..9025fcf --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Light_Button.cxx @@ -0,0 +1,174 @@ +// +// "$Id: Fl_Light_Button.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Lighted button widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Subclass of Fl_Button where the "box" indicates whether it is +// pushed or not, and the "down box" is drawn small and square on +// the left to indicate the current state. + +// The default down_box of zero draws a rectangle designed to look +// just like Flame's buttons. + +#include +#include +#include +#include "flstring.h" + +void Fl_Light_Button::draw() { + if (box()) draw_box(this==Fl::pushed() ? fl_down(box()) : box(), color()); + Fl_Color col = value() ? (active_r() ? selection_color() : + fl_inactive(selection_color())) : color(); + int W; + int dx, dy; + + W = labelsize(); + dx = Fl::box_dx(box()) + 2; + dy = (h() - W) / 2; + // if (dy < 0) dy = 0; // neg. offset o.k. for vertical centering + + if (down_box()) { + // draw other down_box() styles: + switch (down_box()) { + case FL_DOWN_BOX : + case FL_UP_BOX : + case _FL_PLASTIC_DOWN_BOX : + case _FL_PLASTIC_UP_BOX : + // Check box... + draw_box(down_box(), x()+dx, y()+dy, W, W, FL_BACKGROUND2_COLOR); + if (value()) { + if (Fl::scheme() && !strcmp(Fl::scheme(), "gtk+")) { + fl_color(FL_SELECTION_COLOR); + } else { + fl_color(col); + } + int tx = x() + dx + 3; + int tw = W - 6; + int d1 = tw/3; + int d2 = tw-d1; + int ty = y() + dy + (W+d2)/2-d1-2; + for (int n = 0; n < 3; n++, ty++) { + fl_line(tx, ty, tx+d1, ty+d1); + fl_line(tx+d1, ty+d1, tx+tw-1, ty+d1-d2+1); + } + } + break; + case _FL_ROUND_DOWN_BOX : + case _FL_ROUND_UP_BOX : + // Radio button... + draw_box(down_box(), x()+dx, y()+dy, W, W, FL_BACKGROUND2_COLOR); + if (value()) { + int tW = (W - Fl::box_dw(down_box())) / 2 + 1; + if ((W - tW) & 1) tW++; // Make sure difference is even to center + int tdx = dx + (W - tW) / 2; + int tdy = dy + (W - tW) / 2; + + if (Fl::scheme() && !strcmp(Fl::scheme(), "gtk+")) { + fl_color(FL_SELECTION_COLOR); + tW --; + fl_pie(x() + tdx - 1, y() + tdy - 1, tW + 3, tW + 3, 0.0, 360.0); + fl_arc(x() + tdx - 1, y() + tdy - 1, tW + 3, tW + 3, 0.0, 360.0); + fl_color(fl_color_average(FL_WHITE, FL_SELECTION_COLOR, 0.2f)); + } else fl_color(col); + + switch (tW) { + // Larger circles draw fine... + default : + fl_pie(x() + tdx, y() + tdy, tW, tW, 0.0, 360.0); + break; + + // Small circles don't draw well on many systems... + case 6 : + fl_rectf(x() + tdx + 2, y() + tdy, tW - 4, tW); + fl_rectf(x() + tdx + 1, y() + tdy + 1, tW - 2, tW - 2); + fl_rectf(x() + tdx, y() + tdy + 2, tW, tW - 4); + break; + + case 5 : + case 4 : + case 3 : + fl_rectf(x() + tdx + 1, y() + tdy, tW - 2, tW); + fl_rectf(x() + tdx, y() + tdy + 1, tW, tW - 2); + break; + + case 2 : + case 1 : + fl_rectf(x() + tdx, y() + tdy, tW, tW); + break; + } + + if (Fl::scheme() && !strcmp(Fl::scheme(), "gtk+")) { + fl_color(fl_color_average(FL_WHITE, FL_SELECTION_COLOR, 0.5)); + fl_arc(x() + tdx, y() + tdy, tW + 1, tW + 1, 60.0, 180.0); + } + } + break; + default : + draw_box(down_box(), x()+dx, y()+dy, W, W, col); + break; + } + } else { + // if down_box() is zero, draw light button style: + int hh = h()-2*dy - 2; + int ww = W/2+1; + int xx = dx; + if (w()The destructor deletes the check button. +*/ +Fl_Light_Button::Fl_Light_Button(int X, int Y, int W, int H, const char* l) +: Fl_Button(X, Y, W, H, l) { + type(FL_TOGGLE_BUTTON); + selection_color(FL_YELLOW); + align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE); +} + +// +// End of "$Id: Fl_Light_Button.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Menu.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Menu.cxx new file mode 100644 index 0000000..10aabb4 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Menu.cxx @@ -0,0 +1,1048 @@ +// +// "$Id: Fl_Menu.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Menu code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Warning: this menu code is quite a mess! + +// This file contains code for implementing Fl_Menu_Item, and for +// methods for bringing up popup menu hierarchies without using the +// Fl_Menu_ widget. + +#include +#include +#include +#include +#include +#include "flstring.h" + +#ifdef __APPLE__ +# include +#endif +/** Size of the menu starting from this menu item */ +int Fl_Menu_Item::size() const { + const Fl_Menu_Item* m = this; + int nest = 0; + for (;;) { + if (!m->text) { + if (!nest) return (m-this+1); + nest--; + } else if (m->flags & FL_SUBMENU) { + nest++; + } + m++; + } +} + +/** + Advance a pointer by n items through a menu array, skipping + the contents of submenus and invisible items. There are two calls so + that you can advance through const and non-const data. +*/ +const Fl_Menu_Item* Fl_Menu_Item::next(int n) const { + if (n < 0) return 0; // this is so selected==-1 returns NULL + const Fl_Menu_Item* m = this; + int nest = 0; + if (!m->visible()) n++; + while (n>0) { + if (!m->text) { + if (!nest) return m; + nest--; + } else if (m->flags&FL_SUBMENU) { + nest++; + } + m++; + if (!nest && m->visible()) n--; + } + return m; +} + +// appearance of current menus are pulled from this parent widget: +static const Fl_Menu_* button=0; + +//////////////////////////////////////////////////////////////// + +// tiny window for title of menu: +class menutitle : public Fl_Menu_Window { + void draw(); +public: + const Fl_Menu_Item* menu; + menutitle(int X, int Y, int W, int H, const Fl_Menu_Item*); +}; + +// each vertical menu has one of these: +class menuwindow : public Fl_Menu_Window { + void draw(); + void drawentry(const Fl_Menu_Item*, int i, int erase); +public: + menutitle* title; + int handle(int); +#ifdef __APPLE__ + int early_hide_handle(int); +#endif + int itemheight; // zero == menubar + int numitems; + int selected; + int drawn_selected; // last redraw has this selected + int shortcutWidth; + const Fl_Menu_Item* menu; + menuwindow(const Fl_Menu_Item* m, int X, int Y, int W, int H, + const Fl_Menu_Item* picked, const Fl_Menu_Item* title, + int menubar = 0, int menubar_title = 0, int right_edge = 0); + ~menuwindow(); + void set_selected(int); + int find_selected(int mx, int my); + int titlex(int); + void autoscroll(int); + void position(int x, int y); + int is_inside(int x, int y); +}; + +#define LEADING 4 // extra vertical leading + +extern char fl_draw_shortcut; + +/** + Measures width of label, including effect of & characters. + Optionally, can get height if hp is not NULL. +*/ +int Fl_Menu_Item::measure(int* hp, const Fl_Menu_* m) const { + Fl_Label l; + l.value = text; + l.image = 0; + l.deimage = 0; + l.type = labeltype_; + l.font = labelsize_ || labelfont_ ? labelfont_ : (m ? m->textfont() : FL_HELVETICA); + l.size = labelsize_ ? labelsize_ : m ? m->textsize() : FL_NORMAL_SIZE; + l.color = FL_FOREGROUND_COLOR; // this makes no difference? + fl_draw_shortcut = 1; + int w = 0; int h = 0; + l.measure(w, hp ? *hp : h); + fl_draw_shortcut = 0; + if (flags & (FL_MENU_TOGGLE|FL_MENU_RADIO)) w += 14; + return w; +} + +/** Draws the menu item in bounding box x,y,w,h, optionally selects the item. */ +void Fl_Menu_Item::draw(int x, int y, int w, int h, const Fl_Menu_* m, + int selected) const { + Fl_Label l; + l.value = text; + l.image = 0; + l.deimage = 0; + l.type = labeltype_; + l.font = labelsize_ || labelfont_ ? labelfont_ : (m ? m->textfont() : FL_HELVETICA); + l.size = labelsize_ ? labelsize_ : m ? m->textsize() : FL_NORMAL_SIZE; + l.color = labelcolor_ ? labelcolor_ : m ? m->textcolor() : int(FL_FOREGROUND_COLOR); + if (!active()) l.color = fl_inactive((Fl_Color)l.color); + Fl_Color color = m ? m->color() : FL_GRAY; + if (selected) { + Fl_Color r = m ? m->selection_color() : FL_SELECTION_COLOR; + Fl_Boxtype b = m && m->down_box() ? m->down_box() : FL_FLAT_BOX; + if (fl_contrast(r,color)!=r) { // back compatibility boxtypes + if (selected == 2) { // menu title + r = color; + b = m ? m->box() : FL_UP_BOX; + } else { + r = (Fl_Color)(FL_COLOR_CUBE-1); // white + l.color = fl_contrast((Fl_Color)labelcolor_, r); + } + } else { + l.color = fl_contrast((Fl_Color)labelcolor_, r); + } + if (selected == 2) { // menu title + fl_draw_box(b, x, y, w, h, r); + x += 3; + w -= 8; + } else { + fl_draw_box(b, x+1, y-(LEADING-2)/2, w-2, h+(LEADING-2), r); + } + } + + if (flags & (FL_MENU_TOGGLE|FL_MENU_RADIO)) { + int d = (h - FL_NORMAL_SIZE + 1) / 2; + int W = h - 2 * d; + + if (flags & FL_MENU_RADIO) { + fl_draw_box(FL_ROUND_DOWN_BOX, x+2, y+d, W, W, FL_BACKGROUND2_COLOR); + if (value()) { + int tW = (W - Fl::box_dw(FL_ROUND_DOWN_BOX)) / 2 + 1; + if ((W - tW) & 1) tW++; // Make sure difference is even to center + int td = Fl::box_dx(FL_ROUND_DOWN_BOX) + 1; + if (Fl::scheme()) { + // Offset the radio circle... + td ++; + + if (!strcmp(Fl::scheme(), "gtk+")) { + fl_color(FL_SELECTION_COLOR); + tW --; + fl_pie(x + td + 1, y + d + td - 1, tW + 3, tW + 3, 0.0, 360.0); + fl_arc(x + td + 1, y + d + td - 1, tW + 3, tW + 3, 0.0, 360.0); + fl_color(fl_color_average(FL_WHITE, FL_SELECTION_COLOR, 0.2f)); + } else fl_color(labelcolor_); + } else fl_color(labelcolor_); + + switch (tW) { + // Larger circles draw fine... + default : + fl_pie(x + td + 2, y + d + td, tW, tW, 0.0, 360.0); + break; + + // Small circles don't draw well on many systems... + case 6 : + fl_rectf(x + td + 4, y + d + td, tW - 4, tW); + fl_rectf(x + td + 3, y + d + td + 1, tW - 2, tW - 2); + fl_rectf(x + td + 2, y + d + td + 2, tW, tW - 4); + break; + + case 5 : + case 4 : + case 3 : + fl_rectf(x + td + 3, y + d + td, tW - 2, tW); + fl_rectf(x + td + 2, y + d + td + 1, tW, tW - 2); + break; + + case 2 : + case 1 : + fl_rectf(x + td + 2, y + d + td, tW, tW); + break; + } + + if (Fl::scheme() && !strcmp(Fl::scheme(), "gtk+")) { + fl_color(fl_color_average(FL_WHITE, FL_SELECTION_COLOR, 0.5)); + fl_arc(x + td + 2, y + d + td, tW + 1, tW + 1, 60.0, 180.0); + } + } + } else { + fl_draw_box(FL_DOWN_BOX, x+2, y+d, W, W, FL_BACKGROUND2_COLOR); + if (value()) { + if (Fl::scheme() && !strcmp(Fl::scheme(), "gtk+")) { + fl_color(FL_SELECTION_COLOR); + } else { + fl_color(labelcolor_); + } + int tx = x + 5; + int tw = W - 6; + int d1 = tw/3; + int d2 = tw-d1; + int ty = y + d + (W+d2)/2-d1-2; + for (int n = 0; n < 3; n++, ty++) { + fl_line(tx, ty, tx+d1, ty+d1); + fl_line(tx+d1, ty+d1, tx+tw-1, ty+d1-d2+1); + } + } + } + x += W + 3; + w -= W + 3; + } + + if (!fl_draw_shortcut) fl_draw_shortcut = 1; + l.draw(x+3, y, w>6 ? w-6 : 0, h, FL_ALIGN_LEFT); + fl_draw_shortcut = 0; +} + +menutitle::menutitle(int X, int Y, int W, int H, const Fl_Menu_Item* L) : + Fl_Menu_Window(X, Y, W, H, 0) { + end(); + set_modal(); + clear_border(); + set_menu_window(); + menu = L; + if (L->labelcolor_ || Fl::scheme() || L->labeltype_ > FL_NO_LABEL) clear_overlay(); +} + +menuwindow::menuwindow(const Fl_Menu_Item* m, int X, int Y, int Wp, int Hp, + const Fl_Menu_Item* picked, const Fl_Menu_Item* t, + int menubar, int menubar_title, int right_edge) + : Fl_Menu_Window(X, Y, Wp, Hp, 0) +{ + int scr_x, scr_y, scr_w, scr_h; + int tx = X, ty = Y; + + Fl::screen_xywh(scr_x, scr_y, scr_w, scr_h); + if (!right_edge || right_edge > scr_x+scr_w) right_edge = scr_x+scr_w; + + end(); + set_modal(); + clear_border(); + set_menu_window(); + menu = m; + if (m) m = m->first(); // find the first item that needs to be rendered + drawn_selected = -1; + if (button) { + box(button->box()); + if (box() == FL_NO_BOX || box() == FL_FLAT_BOX) box(FL_UP_BOX); + } else { + box(FL_UP_BOX); + } + color(button && !Fl::scheme() ? button->color() : FL_GRAY); + selected = -1; + { + int j = 0; + if (m) for (const Fl_Menu_Item* m1=m; ; m1 = m1->next(), j++) { + if (picked) { + if (m1 == picked) {selected = j; picked = 0;} + else if (m1 > picked) {selected = j-1; picked = 0; Wp = Hp = 0;} + } + if (!m1->text) break; + } + numitems = j;} + + if (menubar) { + itemheight = 0; + title = 0; + return; + } + + itemheight = 1; + + int hotKeysw = 0; + int hotModsw = 0; + int Wtitle = 0; + int Htitle = 0; + if (t) Wtitle = t->measure(&Htitle, button) + 12; + int W = 0; + if (m) for (; m->text; m = m->next()) { + int hh; + int w1 = m->measure(&hh, button); + if (hh+LEADING>itemheight) itemheight = hh+LEADING; + if (m->flags&(FL_SUBMENU|FL_SUBMENU_POINTER)) w1 += 14; + if (w1 > W) W = w1; + // calculate the maximum width of all shortcuts + if (m->shortcut_) { + // s is a pointerto the utf8 string for the entire shortcut + // k points only to the key part (minus the modifier keys) + const char *k, *s = fl_shortcut_label(m->shortcut_, &k); + if (fl_utf_nb_char((const unsigned char*)k, strlen(k))<=4) { + // a regular shortcut has a right-justified modifier followed by a left-justified key + w1 = int(fl_width(s, k-s)); + if (w1 > hotModsw) hotModsw = w1; + w1 = int(fl_width(k))+4; + if (w1 > hotKeysw) hotKeysw = w1; + } else { + // a shortcut with a long modifier is right-justified to the menu + w1 = int(fl_width(s))+4; + if (w1 > (hotModsw+hotKeysw)) { + hotModsw = w1-hotKeysw; + } + } + } + if (m->labelcolor_ || Fl::scheme() || m->labeltype_ > FL_NO_LABEL) clear_overlay(); + } + shortcutWidth = hotKeysw; + if (selected >= 0 && !Wp) X -= W/2; + int BW = Fl::box_dx(box()); + W += hotKeysw+hotModsw+2*BW+7; + if (Wp > W) W = Wp; + if (Wtitle > W) W = Wtitle; + + if (X < scr_x) X = scr_x; if (X > scr_x+scr_w-W) X = right_edge-W; //X= scr_x+scr_w-W; + x(X); w(W); + h((numitems ? itemheight*numitems-LEADING : 0)+2*BW+3); + if (selected >= 0) { + Y = Y+(Hp-itemheight)/2-selected*itemheight-BW; + } else { + Y = Y+Hp; + // if the menu hits the bottom of the screen, we try to draw + // it above the menubar instead. We will not adjust any menu + // that has a selected item. + if (Y+h()>scr_y+scr_h && Y-h()>=scr_y) { + if (Hp>1) { + // if we know the height of the Fl_Menu_, use it + Y = Y-Hp-h(); + } else if (t) { + // assume that the menubar item height relates to the first + // menuitem as well + Y = Y-itemheight-h()-Fl::box_dh(box()); + } else { + // draw the menu to the right + Y = Y-h()+itemheight+Fl::box_dy(box()); + } + } + } + if (m) y(Y); else {y(Y-2); w(1); h(1);} + + if (t) { + if (menubar_title) { + int dy = Fl::box_dy(button->box())+1; + int ht = button->h()-dy*2; + title = new menutitle(tx, ty-ht-dy, Wtitle, ht, t); + } else { + int dy = 2; + int ht = Htitle+2*BW+3; + title = new menutitle(X, Y-ht-dy, Wtitle, ht, t); + } + } else { + title = 0; + } +} + +menuwindow::~menuwindow() { + hide(); + delete title; +} + +void menuwindow::position(int X, int Y) { + if (title) {title->position(X, title->y()+Y-y());} + Fl_Menu_Window::position(X, Y); + // x(X); y(Y); // don't wait for response from X +} + +// scroll so item i is visible on screen +void menuwindow::autoscroll(int n) { + int scr_x, scr_y, scr_w, scr_h; + int Y = y()+Fl::box_dx(box())+2+n*itemheight; + + Fl::screen_xywh(scr_x, scr_y, scr_w, scr_h); + if (Y <= scr_y) Y = scr_y-Y+10; + else { + Y = Y+itemheight-scr_h-scr_y; + if (Y < 0) return; + Y = -Y-10; + } + Fl_Menu_Window::position(x(), y()+Y); + // y(y()+Y); // don't wait for response from X +} + +//////////////////////////////////////////////////////////////// + +void menuwindow::drawentry(const Fl_Menu_Item* m, int n, int eraseit) { + if (!m) return; // this happens if -1 is selected item and redrawn + + int BW = Fl::box_dx(box()); + int xx = BW; + int W = w(); + int ww = W-2*BW-1; + int yy = BW+1+n*itemheight; + int hh = itemheight - LEADING; + + if (eraseit && n != selected) { + fl_push_clip(xx+1, yy-(LEADING-2)/2, ww-2, hh+(LEADING-2)); + draw_box(box(), 0, 0, w(), h(), button ? button->color() : color()); + fl_pop_clip(); + } + + m->draw(xx, yy, ww, hh, button, n==selected); + + // the shortcuts and arrows assume fl_color() was left set by draw(): + if (m->submenu()) { + int sz = (hh-7)&-2; + int y1 = yy+(hh-sz)/2; + int x1 = xx+ww-sz-3; + fl_polygon(x1+2, y1, x1+2, y1+sz, x1+sz/2+2, y1+sz/2); + } else if (m->shortcut_) { + Fl_Font f = m->labelsize_ || m->labelfont_ ? (Fl_Font)m->labelfont_ : + button ? button->textfont() : FL_HELVETICA; + fl_font(f, m->labelsize_ ? m->labelsize_ : + button ? button->textsize() : FL_NORMAL_SIZE); + const char *k, *s = fl_shortcut_label(m->shortcut_, &k); + if (fl_utf_nb_char((const unsigned char*)k, strlen(k))<=4) { + // righ-align the modifiers and left-align the key + char buf[32]; strcpy(buf, s); buf[k-s] = 0; + fl_draw(buf, xx, yy, ww-shortcutWidth, hh, FL_ALIGN_RIGHT); + fl_draw( k, xx+ww-shortcutWidth, yy, shortcutWidth, hh, FL_ALIGN_LEFT); + } else { + // right-align to the menu + fl_draw(s, xx, yy, ww-4, hh, FL_ALIGN_RIGHT); + } + } + + if (m->flags & FL_MENU_DIVIDER) { + fl_color(FL_DARK3); + fl_xyline(BW-1, yy+hh+(LEADING-2)/2, W-2*BW+2); + fl_color(FL_LIGHT3); + fl_xyline(BW-1, yy+hh+((LEADING-2)/2+1), W-2*BW+2); + } +} + +void menutitle::draw() { + menu->draw(0, 0, w(), h(), button, 2); +} + +void menuwindow::draw() { + if (damage() != FL_DAMAGE_CHILD) { // complete redraw + fl_draw_box(box(), 0, 0, w(), h(), button ? button->color() : color()); + if (menu) { + const Fl_Menu_Item* m; int j; + for (m=menu->first(), j=0; m->text; j++, m = m->next()) drawentry(m, j, 0); + } + } else { + if (damage() & FL_DAMAGE_CHILD && selected!=drawn_selected) { // change selection + drawentry(menu->next(drawn_selected), drawn_selected, 1); + drawentry(menu->next(selected), selected, 1); + } + } + drawn_selected = selected; +} + +void menuwindow::set_selected(int n) { + if (n != selected) {selected = n; damage(FL_DAMAGE_CHILD);} +} + +//////////////////////////////////////////////////////////////// + +int menuwindow::find_selected(int mx, int my) { + if (!menu || !menu->text) return -1; + mx -= x(); + my -= y(); + if (my < 0 || my >= h()) return -1; + if (!itemheight) { // menubar + int xx = 3; int n = 0; + const Fl_Menu_Item* m = menu ? menu->first() : 0; + for (; ; m = m->next(), n++) { + if (!m->text) return -1; + xx += m->measure(0, button) + 16; + if (xx > mx) break; + } + return n; + } + if (mx < Fl::box_dx(box()) || mx >= w()) return -1; + int n = (my-Fl::box_dx(box())-1)/itemheight; + if (n < 0 || n>=numitems) return -1; + return n; +} + +// return horizontal position for item n in a menubar: +int menuwindow::titlex(int n) { + const Fl_Menu_Item* m; + int xx = 3; + for (m=menu->first(); n--; m = m->next()) xx += m->measure(0, button) + 16; + return xx; +} + +// return 1, if the given root coordinates are inside the window +int menuwindow::is_inside(int mx, int my) { + if ( mx < x_root() || mx >= x_root() + w() || + my < y_root() || my >= y_root() + h()) { + return 0; + } + return 1; +} + +//////////////////////////////////////////////////////////////// +// Fl_Menu_Item::popup(...) + +// Because Fl::grab() is done, all events go to one of the menu windows. +// But the handle method needs to look at all of them to find out +// what item the user is pointing at. And it needs a whole lot +// of other state variables to determine what is going on with +// the currently displayed menus. +// So the main loop (handlemenu()) puts all the state in a structure +// and puts a pointer to it in a static location, so the handle() +// on menus can refer to it and alter it. The handle() method +// changes variables in this state to indicate what item is +// picked, but does not actually alter the display, instead the +// main loop does that. This is because the X mapping and unmapping +// of windows is slow, and we don't want to fall behind the events. + +// values for menustate.state: +#define INITIAL_STATE 0 // no mouse up or down since popup() called +#define PUSH_STATE 1 // mouse has been pushed on a normal item +#define DONE_STATE 2 // exit the popup, the current item was picked +#define MENU_PUSH_STATE 3 // mouse has been pushed on a menu title + +struct menustate { + const Fl_Menu_Item* current_item; // what mouse is pointing at + int menu_number; // which menu it is in + int item_number; // which item in that menu, -1 if none + menuwindow* p[20]; // pointers to menus + int nummenus; + int menubar; // if true p[0] is a menubar + int state; + menuwindow* fakemenu; // kludge for buttons in menubar + int is_inside(int mx, int my); +}; +static menustate* p=0; + +// return 1 if the coordinates are inside any of the menuwindows +int menustate::is_inside(int mx, int my) { + int i; + for (i=nummenus-1; i>=0; i--) { + if (p[i]->is_inside(mx, my)) + return 1; + } + return 0; +} + +static inline void setitem(const Fl_Menu_Item* i, int m, int n) { + p->current_item = i; + p->menu_number = m; + p->item_number = n; +} + +static void setitem(int m, int n) { + menustate &pp = *p; + pp.current_item = (n >= 0) ? pp.p[m]->menu->next(n) : 0; + pp.menu_number = m; + pp.item_number = n; +} + +static int forward(int menu) { // go to next item in menu menu if possible + menustate &pp = *p; + // Fl_Menu_Button can geberate menu=-1. This line fixes it and selectes the first item. + if (menu==-1) + menu = 0; + menuwindow &m = *(pp.p[menu]); + int item = (menu == pp.menu_number) ? pp.item_number : m.selected; + while (++item < m.numitems) { + const Fl_Menu_Item* m1 = m.menu->next(item); + if (m1->activevisible()) {setitem(m1, menu, item); return 1;} + } + return 0; +} + +static int backward(int menu) { // previous item in menu menu if possible + menustate &pp = *p; + menuwindow &m = *(pp.p[menu]); + int item = (menu == pp.menu_number) ? pp.item_number : m.selected; + if (item < 0) item = m.numitems; + while (--item >= 0) { + const Fl_Menu_Item* m1 = m.menu->next(item); + if (m1->activevisible()) {setitem(m1, menu, item); return 1;} + } + return 0; +} + +int menuwindow::handle(int e) { +#ifdef __APPLE__ + // This off-route takes care of the "detached menu" bug on OS X. + // Apple event handler requires that we hide all menu windows right + // now, so that Carbon can continue undisturbed with handling window + // manager events, like dragging the application window. + int ret = early_hide_handle(e); + menustate &pp = *p; + if (pp.state == DONE_STATE) { + hide(); + if (pp.fakemenu) { + pp.fakemenu->hide(); + if (pp.fakemenu->title) + pp.fakemenu->title->hide(); + } + int i = pp.nummenus; + while (i>0) { + menuwindow *mw = pp.p[--i]; + if (mw) { + mw->hide(); + if (mw->title) + mw->title->hide(); + } + } + } + return ret; +} + +int menuwindow::early_hide_handle(int e) { +#endif + menustate &pp = *p; + switch (e) { + case FL_KEYBOARD: + switch (Fl::event_key()) { + case FL_BackSpace: + BACKTAB: + if (!backward(pp.menu_number)) {pp.item_number = -1;backward(pp.menu_number);} + return 1; + case FL_Up: + if (pp.menubar && pp.menu_number == 0) { + // Do nothing... + } else if (backward(pp.menu_number)) { + // Do nothing... + } else if (pp.menubar && pp.menu_number==1) { + setitem(0, pp.p[0]->selected); + } + return 1; + case FL_Tab: + if (Fl::event_shift()) goto BACKTAB; + case FL_Down: + if (pp.menu_number || !pp.menubar) { + if (!forward(pp.menu_number) && Fl::event_key()==FL_Tab) { + pp.item_number = -1; + forward(pp.menu_number); + } + } else if (pp.menu_number < pp.nummenus-1) { + forward(pp.menu_number+1); + } + return 1; + case FL_Right: + if (pp.menubar && (pp.menu_number<=0 || (pp.menu_number==1 && pp.nummenus==2))) + forward(0); + else if (pp.menu_number < pp.nummenus-1) forward(pp.menu_number+1); + return 1; + case FL_Left: + if (pp.menubar && pp.menu_number<=1) backward(0); + else if (pp.menu_number>0) + setitem(pp.menu_number-1, pp.p[pp.menu_number-1]->selected); + return 1; + case FL_Enter: + case FL_KP_Enter: + case ' ': + pp.state = DONE_STATE; + return 1; + case FL_Escape: + setitem(0, -1, 0); + pp.state = DONE_STATE; + return 1; + } + break; + case FL_SHORTCUT: + { + for (int mymenu = pp.nummenus; mymenu--;) { + menuwindow &mw = *(pp.p[mymenu]); + int item; const Fl_Menu_Item* m = mw.menu->find_shortcut(&item); + if (m) { + setitem(m, mymenu, item); + if (!m->submenu()) pp.state = DONE_STATE; + return 1; + } + } + } + break; + case FL_ENTER: + case FL_MOVE: + case FL_PUSH: + case FL_DRAG: + { +#ifdef __QNX__ + // STR 704: workaround QNX X11 bug - in QNX a FL_MOVE event is sent + // right after FL_RELEASE... + if (pp.state == DONE_STATE) return 1; +#endif // __QNX__ + int mx = Fl::event_x_root(); + int my = Fl::event_y_root(); + int item=0; int mymenu = pp.nummenus-1; + // Clicking or dragging outside menu cancels it... + if ((!pp.menubar || mymenu) && !pp.is_inside(mx, my)) { + setitem(0, -1, 0); + if (e==FL_PUSH) + pp.state = DONE_STATE; + return 1; + } + for (mymenu = pp.nummenus-1; ; mymenu--) { + item = pp.p[mymenu]->find_selected(mx, my); + if (item >= 0) + break; + if (mymenu <= 0) { + // buttons in menubars must be deselected if we move outside of them! + if (pp.menu_number==-1 && e==FL_PUSH) { + pp.state = DONE_STATE; + return 1; + } + if (pp.current_item && pp.menu_number==0 && !pp.current_item->submenu()) { + if (e==FL_PUSH) + pp.state = DONE_STATE; + setitem(0, -1, 0); + return 1; + } + // all others can stay selected + return 0; + } + } + if (my == 0 && item > 0) setitem(mymenu, item - 1); + else setitem(mymenu, item); + if (e == FL_PUSH) { + if (pp.current_item && pp.current_item->submenu() // this is a menu title + && item != pp.p[mymenu]->selected // and it is not already on + && !pp.current_item->callback_) // and it does not have a callback + pp.state = MENU_PUSH_STATE; + else + pp.state = PUSH_STATE; + } + } + return 1; + case FL_RELEASE: + // Mouse must either be held down/dragged some, or this must be + // the second click (not the one that popped up the menu): + if ( !Fl::event_is_click() + || pp.state == PUSH_STATE + || (pp.menubar && pp.current_item && !pp.current_item->submenu()) // button + ) { +#if 0 // makes the check/radio items leave the menu up + const Fl_Menu_Item* m = pp.current_item; + if (m && button && (m->flags & (FL_MENU_TOGGLE|FL_MENU_RADIO))) { + ((Fl_Menu_*)button)->picked(m); + pp.p[pp.menu_number]->redraw(); + } else +#endif + // do nothing if they try to pick inactive items + if (!pp.current_item || pp.current_item->activevisible()) + pp.state = DONE_STATE; + } + return 1; + } + return Fl_Window::handle(e); +} + +/** + Pulldown() is similar to popup(), but a rectangle is + provided to position the menu. The menu is made at least W + wide, and the picked item is centered over the rectangle + (like Fl_Choice uses). If picked is zero or not + found, the menu is aligned just below the rectangle (like a pulldown + menu). +

      The title and menubar arguments are used + internally by the Fl_Menu_Bar widget. +*/ +const Fl_Menu_Item* Fl_Menu_Item::pulldown( + int X, int Y, int W, int H, + const Fl_Menu_Item* initial_item, + const Fl_Menu_* pbutton, + const Fl_Menu_Item* t, + int menubar) const { + Fl_Group::current(0); // fix possible user error... + + button = pbutton; + if (pbutton) { + for (Fl_Window* w = pbutton->window(); w; w = w->window()) { + X += w->x(); + Y += w->y(); + } + } else { + X += Fl::event_x_root()-Fl::event_x(); + Y += Fl::event_y_root()-Fl::event_y(); + } + menuwindow mw(this, X, Y, W, H, initial_item, t, menubar); + Fl::grab(mw); + menustate pp; p = &pp; + pp.p[0] = &mw; + pp.nummenus = 1; + pp.menubar = menubar; + pp.state = INITIAL_STATE; + pp.fakemenu = 0; // kludge for buttons in menubar + + // preselected item, pop up submenus if necessary: + if (initial_item && mw.selected >= 0) { + setitem(0, mw.selected); + goto STARTUP; + } + + pp.current_item = 0; pp.menu_number = 0; pp.item_number = -1; + if (menubar) { + // find the initial menu + if (!mw.handle(FL_DRAG)) { + Fl::grab(0); + return 0; + } + } + initial_item = pp.current_item; + if (initial_item) goto STARTUP; + + // the main loop, runs until p.state goes to DONE_STATE: + for (;;) { + + // make sure all the menus are shown: + { + for (int k = menubar; k < pp.nummenus; k++) { + if (!pp.p[k]->shown()) { + if (pp.p[k]->title) pp.p[k]->title->show(); + pp.p[k]->show(); + } + } + } + + // get events: + { + const Fl_Menu_Item* oldi = pp.current_item; + Fl::wait(); + if (pp.state == DONE_STATE) break; // done. + if (pp.current_item == oldi) continue; + } + + // only do rest if item changes: + if(pp.fakemenu) {delete pp.fakemenu; pp.fakemenu = 0;} // turn off "menubar button" + + if (!pp.current_item) { // pointing at nothing + // turn off selection in deepest menu, but don't erase other menus: + pp.p[pp.nummenus-1]->set_selected(-1); + continue; + } + + if(pp.fakemenu) {delete pp.fakemenu; pp.fakemenu = 0;} + initial_item = 0; // stop the startup code + pp.p[pp.menu_number]->autoscroll(pp.item_number); + + STARTUP: + menuwindow& cw = *pp.p[pp.menu_number]; + const Fl_Menu_Item* m = pp.current_item; + if (!m->activevisible()) { // pointing at inactive item + cw.set_selected(-1); + initial_item = 0; // turn off startup code + continue; + } + cw.set_selected(pp.item_number); + + if (m==initial_item) initial_item=0; // stop the startup code if item found + if (m->submenu()) { + const Fl_Menu_Item* title = m; + const Fl_Menu_Item* menutable; + if (m->flags&FL_SUBMENU) menutable = m+1; + else menutable = (Fl_Menu_Item*)(m)->user_data_; + // figure out where new menu goes: + int nX, nY; + if (!pp.menu_number && pp.menubar) { // menu off a menubar: + nX = cw.x() + cw.titlex(pp.item_number); + nY = cw.y() + cw.h(); + initial_item = 0; + } else { + nX = cw.x() + cw.w(); + nY = cw.y() + pp.item_number * cw.itemheight; + title = 0; + } + if (initial_item) { // bring up submenu containing initial item: + menuwindow* n = new menuwindow(menutable,X,Y,W,H,initial_item,title,0,0,cw.x()); + pp.p[pp.nummenus++] = n; + // move all earlier menus to line up with this new one: + if (n->selected>=0) { + int dy = n->y()-nY; + int dx = n->x()-nX; + for (int menu = 0; menu <= pp.menu_number; menu++) { + menuwindow* tt = pp.p[menu]; + int nx = tt->x()+dx; if (nx < 0) {nx = 0; dx = -tt->x();} + int ny = tt->y()+dy; if (ny < 0) {ny = 0; dy = -tt->y();} + tt->position(nx, ny); + } + setitem(pp.nummenus-1, n->selected); + goto STARTUP; + } + } else if (pp.nummenus > pp.menu_number+1 && + pp.p[pp.menu_number+1]->menu == menutable) { + // the menu is already up: + while (pp.nummenus > pp.menu_number+2) delete pp.p[--pp.nummenus]; + pp.p[pp.nummenus-1]->set_selected(-1); + } else { + // delete all the old menus and create new one: + while (pp.nummenus > pp.menu_number+1) delete pp.p[--pp.nummenus]; + pp.p[pp.nummenus++]= new menuwindow(menutable, nX, nY, + title?1:0, 0, 0, title, 0, menubar, cw.x()); + } + } else { // !m->submenu(): + while (pp.nummenus > pp.menu_number+1) delete pp.p[--pp.nummenus]; + if (!pp.menu_number && pp.menubar) { + // kludge so "menubar buttons" turn "on" by using menu title: + pp.fakemenu = new menuwindow(0, + cw.x()+cw.titlex(pp.item_number), + cw.y()+cw.h(), 0, 0, + 0, m, 0, 1); + pp.fakemenu->title->show(); + } + } + } + const Fl_Menu_Item* m = pp.current_item; + Fl::grab(0); + delete pp.fakemenu; + while (pp.nummenus>1) delete pp.p[--pp.nummenus]; + mw.hide(); + return m; +} + +/** + This method is called by widgets that want to display menus. + + The menu stays up until the user picks an item or dismisses it. + The selected item (or NULL if none) is returned. This does not + do the callbacks or change the state of check or radio items. + + X,Y is the position of the mouse cursor, relative to the + window that got the most recent event (usually you can pass + Fl::event_x() and Fl::event_y() unchanged here). + + \p title is a character string title for the menu. If + non-zero a small box appears above the menu with the title in it. + + The menu is positioned so the cursor is centered over the item + picked. This will work even if \p picked is in a submenu. + If \p picked is zero or not in the menu item table the menu is + positioned with the cursor in the top-left corner. + + \p button is a pointer to an Fl_Menu_ from which the color and + boxtypes for the menu are pulled. If NULL then defaults are used. +*/ +const Fl_Menu_Item* Fl_Menu_Item::popup( + int X, int Y, + const char* title, + const Fl_Menu_Item* picked, + const Fl_Menu_* button + ) const { + static Fl_Menu_Item dummy; // static so it is all zeros + dummy.text = title; + return pulldown(X, Y, 0, 0, picked, button, title ? &dummy : 0); +} + +/** + Search only the top level menu for a shortcut. + Either &x in the label or the shortcut fields are used. + + This tests the current event, which must be an FL_KEYBOARD or + FL_SHORTCUT, against a shortcut value. + + \param ip returns the index of the item, if \p ip is not NULL. + \param require_alt if true: match only if Alt key is pressed. + + \return found Fl_Menu_Item or NULL +*/ +const Fl_Menu_Item* Fl_Menu_Item::find_shortcut(int* ip, const bool require_alt) const { + const Fl_Menu_Item* m = first(); + if (m) for (int ii = 0; m->text; m = m->next(), ii++) { + if (m->activevisible()) { + if (Fl::test_shortcut(m->shortcut_) + || Fl_Widget::test_shortcut(m->text, require_alt)) { + if (ip) *ip=ii; + return m; + } + } + } + return 0; +} + +// Recursive search of all submenus for anything with this key as a +// shortcut. Only uses the shortcut field, ignores &x in the labels: +/** + This is designed to be called by a widgets handle() method in + response to a FL_SHORTCUT event. If the current event matches + one of the items shortcut, that item is returned. If the keystroke + does not match any shortcuts then NULL is returned. This only + matches the shortcut() fields, not the letters in the title + preceeded by ' +*/ +const Fl_Menu_Item* Fl_Menu_Item::test_shortcut() const { + const Fl_Menu_Item* m = first(); + const Fl_Menu_Item* ret = 0; + if (m) for (; m->text; m = m->next()) { + if (m->activevisible()) { + // return immediately any match of an item in top level menu: + if (Fl::test_shortcut(m->shortcut_)) return m; + // if (Fl_Widget::test_shortcut(m->text)) return m; + // only return matches from lower menu if nothing found in top menu: + if (!ret && m->submenu()) { + const Fl_Menu_Item* s = + (m->flags&FL_SUBMENU) ? m+1:(const Fl_Menu_Item*)m->user_data_; + ret = s->test_shortcut(); + } + } + } + return ret; +} + +// +// End of "$Id: Fl_Menu.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Menu_.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Menu_.cxx new file mode 100644 index 0000000..934430d --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Menu_.cxx @@ -0,0 +1,435 @@ +// +// "$Id: Fl_Menu_.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Common menu code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// +// This is a base class for all items that have a menu: +// Fl_Menu_Bar, Fl_Menu_Button, Fl_Choice +// This provides storage for a menu item, functions to add/modify/delete +// items, and a call for when the user picks a menu item. + +// More code in Fl_Menu_add.cxx + +#include +#include +#include "flstring.h" +#include +#include + +#define SAFE_STRCAT(s) { len += strlen(s); if ( len >= namelen ) { *name='\0'; return(-2); } else strcat(name,(s)); } + +/** Get the menu 'pathname' for the specified menuitem. + + If finditem==NULL, mvalue() is used (the most recently picked menuitem). + + \b Example: + \code + Fl_Menu_Bar *menubar = 0; + void my_menu_callback(Fl_Widget*,void*) { + char name[80]; + if ( menubar->item_pathname(name, sizeof(name)-1) == 0 ) { // recently picked item + if ( strcmp(name, "File/&Open") == 0 ) { .. } // open invoked + if ( strcmp(name, "File/&Save") == 0 ) { .. } // save invoked + if ( strcmp(name, "Edit/&Copy") == 0 ) { .. } // copy invoked + } + } + int main() { + [..] + menubar = new Fl_Menu_Bar(..); + menubar->add("File/&Open", 0, my_menu_callback); + menubar->add("File/&Save", 0, my_menu_callback); + menubar->add("Edit/&Copy", 0, my_menu_callback); + [..] + } + \endcode + + \returns + - 0 : OK (name has menuitem's pathname) + - -1 : item not found (name="") + - -2 : 'name' not large enough (name="") + \see find_item() +*/ +int Fl_Menu_::item_pathname(char *name, int namelen, const Fl_Menu_Item *finditem) const { + int len = 0; + finditem = finditem ? finditem : mvalue(); + name[0] = '\0'; + for ( int t=0; tsubmenu() ) { // submenu? descend + if (*name) SAFE_STRCAT("/"); + if (m->label()) SAFE_STRCAT(m->label()); + if ( m == finditem ) return(0); // found? done. + } else { + if (m->label()) { // menu item? + if ( m == finditem ) { // found? tack on itemname, done. + SAFE_STRCAT("/"); + SAFE_STRCAT(m->label()); + return(0); + } + } else { // end of submenu? pop + char *ss = strrchr(name, '/'); + if ( ss ) { *ss = 0; len = strlen(name); } // "File/Edit" -> "File" + else { name[0] = '\0'; len = 0; } // "File" -> "" + continue; + } + } + } + *name = '\0'; + return(-1); // item not found +} + +/** + Find the menu item for a given menu \p pathname, such as "Edit/Copy". + + This method finds a menu item in the menu array, also traversing submenus, but + not submenu pointers. + + To get the menu item's index, use find_index(const char*) + + \b Example: + \code + Fl_Menu_Bar *menubar = new Fl_Menu_Bar(..); + menubar->add("File/&Open"); + menubar->add("File/&Save"); + menubar->add("Edit/&Copy"); + // [..] + Fl_Menu_Item *item; + if ( ( item = (Fl_Menu_Item*)menubar->find_item("File/&Open") ) != NULL ) { + item->labelcolor(FL_RED); + } + if ( ( item = (Fl_Menu_Item*)menubar->find_item("Edit/&Copy") ) != NULL ) { + item->labelcolor(FL_GREEN); + } + \endcode + + \param pathname The path and name of the menu item + \returns The item found, or NULL if not found + \see find_index(const char*), find_item(Fl_Callback*), item_pathname() +*/ +const Fl_Menu_Item * Fl_Menu_::find_item(const char *pathname) { + int i = find_index(pathname); + return( (i==-1) ? 0 : (const Fl_Menu_Item*)(menu_+i)); +} + +/** + Find the index the menu array for given \p item. + + A way to convert a menu item pointer into an index. + + Current implementation is fast and not expensive. + + \code + // Convert an index-to-item + int index = 12; + const Fl_Menu_Item *item = mymenu->menu() + index; + + // Convert an item-to-index + int index = mymenu->find_index(item); + if ( index == -1 ) { ..error.. } + \endcode + + \param item The *item to be found + \returns The index of the item, or -1 if not found. + \see menu() +*/ +int Fl_Menu_::find_index(const Fl_Menu_Item *item) const { + Fl_Menu_Item *max = menu_+size(); + if (item=max) return(-1); + return(item-menu_); +} + +/** + Find the index into the menu array for a given callback \p cb. + + This method finds a menu item's index position, also traversing submenus, but + not submenu pointers. This is useful if an application uses internationalisation + and a menu item can not be found using its label. This search is also much faster. + + \param cb Find the first item with this callback + \returns The index of the item with the specific callback, or -1 if not found + \see find_index(const char*) + */ +int Fl_Menu_::find_index(Fl_Callback *cb) const { + for ( int t=0; t < size(); t++ ) + if (menu_[t].callback_==cb) + return(t); + return(-1); +} + +/** + Find the menu item index for a given menu \p pathname, such as "Edit/Copy". + + This method finds a menu item's index position for the given menu pathname, + also traversing submenus, but not submenu pointers. + + To get the menu item pointer for a pathname, use find_item() + + \param pathname The path and name of the menu item index to find + \returns The index of the matching item, or -1 if not found. + \see item_pathname() + +*/ +int Fl_Menu_::find_index(const char *pathname) const { + char menupath[1024] = ""; // File/Export + for ( int t=0; t < size(); t++ ) { + Fl_Menu_Item *m = menu_ + t; + if (m->flags&FL_SUBMENU) { + // IT'S A SUBMENU + // we do not support searches through FL_SUBMENU_POINTER links + if (menupath[0]) strlcat(menupath, "/", sizeof(menupath)); + strlcat(menupath, m->label(), sizeof(menupath)); + if (!strcmp(menupath, pathname)) return(t); + } else { + if (!m->label()) { + // END OF SUBMENU? Pop back one level. + char *ss = strrchr(menupath, '/'); + if ( ss ) *ss = 0; + else menupath[0] = '\0'; + continue; + } + // IT'S A MENU ITEM + char itempath[1024]; // eg. Edit/Copy + strcpy(itempath, menupath); + if (itempath[0]) strlcat(itempath, "/", sizeof(itempath)); + strlcat(itempath, m->label(), sizeof(itempath)); + if (!strcmp(itempath, pathname)) return(t); + } + } + return(-1); +} + +/** + Find the menu item for the given callback \p cb. + + This method finds a menu item in a menu array, also traversing submenus, but + not submenu pointers. This is useful if an application uses + internationalisation and a menu item can not be found using its label. This + search is also much faster. + + \param cb find the first item with this callback + \returns The item found, or NULL if not found + \see find_item(const char*) + */ +const Fl_Menu_Item * Fl_Menu_::find_item(Fl_Callback *cb) { + for ( int t=0; t < size(); t++ ) { + const Fl_Menu_Item *m = menu_ + t; + if (m->callback_==cb) { + return m; + } + } + return (const Fl_Menu_Item *)0; +} + +/** + The value is the index into menu() of the last item chosen by + the user. It is zero initially. You can set it as an integer, or set + it with a pointer to a menu item. The set routines return non-zero if + the new value is different than the old one. +*/ +int Fl_Menu_::value(const Fl_Menu_Item* m) { + clear_changed(); + if (value_ != m) {value_ = m; return 1;} + return 0; +} + +/** + When user picks a menu item, call this. It will do the callback. + Unfortunately this also casts away const for the checkboxes, but this + was necessary so non-checkbox menus can really be declared const... +*/ +const Fl_Menu_Item* Fl_Menu_::picked(const Fl_Menu_Item* v) { + if (v) { + if (v->radio()) { + if (!v->value()) { // they are turning on a radio item + set_changed(); + ((Fl_Menu_Item*)v)->setonly(); + } + redraw(); + } else if (v->flags & FL_MENU_TOGGLE) { + set_changed(); + ((Fl_Menu_Item*)v)->flags ^= FL_MENU_VALUE; + redraw(); + } else if (v != value_) { // normal item + set_changed(); + } + value_ = v; + if (when()&(FL_WHEN_CHANGED|FL_WHEN_RELEASE)) { + if (changed() || when()&FL_WHEN_NOT_CHANGED) { + if (value_ && value_->callback_) value_->do_callback((Fl_Widget*)this); + else do_callback(); + } + } + } + return v; +} + +/** Turns the radio item "on" for the menu item and turns off adjacent radio items set. */ +void Fl_Menu_Item::setonly() { + flags |= FL_MENU_RADIO | FL_MENU_VALUE; + Fl_Menu_Item* j; + for (j = this; ; ) { // go down + if (j->flags & FL_MENU_DIVIDER) break; // stop on divider lines + j++; + if (!j->text || !j->radio()) break; // stop after group + j->clear(); + } + for (j = this-1; ; j--) { // go up + if (!j->text || (j->flags&FL_MENU_DIVIDER) || !j->radio()) break; + j->clear(); + } +} + +/** + Creates a new Fl_Menu_ widget using the given position, size, + and label string. menu() is initialized to null. + */ +Fl_Menu_::Fl_Menu_(int X,int Y,int W,int H,const char* l) +: Fl_Widget(X,Y,W,H,l) { + set_flag(SHORTCUT_LABEL); + box(FL_UP_BOX); + when(FL_WHEN_RELEASE_ALWAYS); + value_ = menu_ = 0; + alloc = 0; + selection_color(FL_SELECTION_COLOR); + textfont(FL_HELVETICA); + textsize(FL_NORMAL_SIZE); + textcolor(FL_FOREGROUND_COLOR); + down_box(FL_NO_BOX); +} + +/** + This returns the number of Fl_Menu_Item structures that make up the + menu, correctly counting submenus. This includes the "terminator" + item at the end. To copy a menu array you need to copy + size()*sizeof(Fl_Menu_Item) bytes. If the menu is + NULL this returns zero (an empty menu will return 1). +*/ +int Fl_Menu_::size() const { + if (!menu_) return 0; + return menu_->size(); +} + +/** + Sets the menu array pointer directly. If the old menu is private it is + deleted. NULL is allowed and acts the same as a zero-length + menu. If you try to modify the array (with add(), replace(), or + remove()) a private copy is automatically done. +*/ +void Fl_Menu_::menu(const Fl_Menu_Item* m) { + clear(); + value_ = menu_ = (Fl_Menu_Item*)m; +} + +// this version is ok with new Fl_Menu_add code with fl_menu_array_owner: + +/** + Sets the menu array pointer with a copy of m that will be automatically deleted. + If userdata \p ud is not NULL, then all user data pointers are changed in the menus as well. + See void Fl_Menu_::menu(const Fl_Menu_Item* m). +*/ +void Fl_Menu_::copy(const Fl_Menu_Item* m, void* ud) { + int n = m->size(); + Fl_Menu_Item* newMenu = new Fl_Menu_Item[n]; + memcpy(newMenu, m, n*sizeof(Fl_Menu_Item)); + menu(newMenu); + alloc = 1; // make destructor free array, but not strings + // for convenience, provide way to change all the user data pointers: + if (ud) for (; n--;) { + if (newMenu->callback_) newMenu->user_data_ = ud; + newMenu++; + } +} + +Fl_Menu_::~Fl_Menu_() { + clear(); +} + +// Fl_Menu::add() uses this to indicate the owner of the dynamically- +// expanding array. We must not free this array: +Fl_Menu_* fl_menu_array_owner = 0; + +/** + Same as menu(NULL), set the array pointer to null, indicating + a zero-length menu. + + Menus must not be cleared during a callback to the same menu. +*/ +void Fl_Menu_::clear() { + if (alloc) { + if (alloc>1) for (int i = size(); i--;) + if (menu_[i].text) free((void*)menu_[i].text); + if (this == fl_menu_array_owner) + fl_menu_array_owner = 0; + else + delete[] menu_; + menu_ = 0; + value_ = 0; + alloc = 0; + } +} + +/** + Clears the specified submenu pointed to by \p index of all menu items. + + This method is useful for clearing a submenu so that it can be + re-populated with new items. Example: a "File/Recent Files/..." submenu + that shows the last few files that have been opened. + + The specified \p index must point to a submenu. + + The submenu is cleared with remove(). + If the menu array was directly set with menu(x), then copy() + is done to make a private array. + + \warning Since this method can change the internal menu array, any menu + item pointers or indecies the application may have cached can become + stale, and should be recalculated/refreshed. + + \b Example: + \code + int index = menubar->find_index("File/Recent"); // get index of "File/Recent" submenu + if ( index != -1 ) menubar->clear_submenu(index); // clear the submenu + menubar->add("File/Recent/Aaa"); + menubar->add("File/Recent/Bbb"); + [..] + \endcode + + \param index The index of the submenu to be cleared + \returns 0 on success, -1 if the index is out of range or not a submenu + \see remove(int) + */ +int Fl_Menu_::clear_submenu(int index) { + if ( index < 0 || index >= size() ) return(-1); + if ( ! (menu_[index].flags & FL_SUBMENU) ) return(-1); + ++index; // advance to first item in submenu + while ( index < size() ) { // keep remove()ing top item until end is reached + if ( menu_[index].text == 0 ) break; // end of this submenu? done + remove(index); // remove items/submenus + } + return(0); +} + +// +// End of "$Id: Fl_Menu_.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Menu_Bar.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Menu_Bar.cxx new file mode 100644 index 0000000..8e114e3 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Menu_Bar.cxx @@ -0,0 +1,78 @@ +// +// "$Id: Fl_Menu_Bar.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Menu bar widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include + +void Fl_Menu_Bar::draw() { + draw_box(); + if (!menu() || !menu()->text) return; + const Fl_Menu_Item* m; + int X = x()+6; + for (m=menu()->first(); m->text; m = m->next()) { + int W = m->measure(0,this) + 16; + m->draw(X, y(), W, h(), this); + X += W; + if (m->flags & FL_MENU_DIVIDER) { + int y1 = y() + Fl::box_dy(box()); + int y2 = y1 + h() - Fl::box_dh(box()) - 1; + + // Draw a vertical divider between menus... + fl_color(FL_DARK3); + fl_yxline(X - 6, y1, y2); + fl_color(FL_LIGHT3); + fl_yxline(X - 5, y1, y2); + } + } +} + +int Fl_Menu_Bar::handle(int event) { + const Fl_Menu_Item* v; + if (menu() && menu()->text) switch (event) { + case FL_ENTER: + case FL_LEAVE: + return 1; + case FL_PUSH: + v = 0; + J1: + v = menu()->pulldown(x(), y(), w(), h(), v, this, 0, 1); + picked(v); + return 1; + case FL_SHORTCUT: + if (visible_r()) { + v = menu()->find_shortcut(0, true); + if (v && v->submenu()) goto J1; + } + return test_shortcut() != 0; + } + return 0; +} + +// +// End of "$Id: Fl_Menu_Bar.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Menu_Button.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Menu_Button.cxx new file mode 100644 index 0000000..bfd2207 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Menu_Button.cxx @@ -0,0 +1,122 @@ +// +// "$Id: Fl_Menu_Button.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Menu button widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include + + +static Fl_Menu_Button *pressed_menu_button_ = 0; + +void Fl_Menu_Button::draw() { + if (!box() || type()) return; + draw_box(pressed_menu_button_ == this ? fl_down(box()) : box(), color()); + draw_label(); + if (Fl::focus() == this) draw_focus(); + // ** if (box() == FL_FLAT_BOX) return; // for XForms compatibility + int H = (labelsize()-3)&-2; + int X = x()+w()-H*2; + int Y = y()+(h()-H)/2; + fl_color(active_r() ? FL_DARK3 : fl_inactive(FL_DARK3)); + fl_line(X+H/2, Y+H, X, Y, X+H, Y); + fl_color(active_r() ? FL_LIGHT3 : fl_inactive(FL_LIGHT3)); + fl_line(X+H, Y, X+H/2, Y+H); +} + +/** + Act exactly as though the user clicked the button or typed the + shortcut key. The menu appears, it waits for the user to pick an item, + and if they pick one it sets value() and does the callback or + sets changed() as described above. The menu item is returned + or NULL if the user dismisses the menu. +*/ +const Fl_Menu_Item* Fl_Menu_Button::popup() { + const Fl_Menu_Item* m; + pressed_menu_button_ = this; + redraw(); + Fl_Widget_Tracker mb(this); + if (!box() || type()) { + m = menu()->popup(Fl::event_x(), Fl::event_y(), label(), mvalue(), this); + } else { + m = menu()->pulldown(x(), y(), w(), h(), 0, this); + } + picked(m); + pressed_menu_button_ = 0; + if (mb.exists()) redraw(); + return m; +} + +int Fl_Menu_Button::handle(int e) { + if (!menu() || !menu()->text) return 0; + switch (e) { + case FL_ENTER: /* FALLTHROUGH */ + case FL_LEAVE: + return (box() && !type()) ? 1 : 0; + case FL_PUSH: + if (!box()) { + if (Fl::event_button() != 3) return 0; + } else if (type()) { + if (!(type() & (1 << (Fl::event_button()-1)))) return 0; + } + if (Fl::visible_focus()) Fl::focus(this); + popup(); + return 1; + case FL_KEYBOARD: + if (!box()) return 0; + if (Fl::event_key() == ' ' && + !(Fl::event_state() & (FL_SHIFT | FL_CTRL | FL_ALT | FL_META))) { + popup(); + return 1; + } else return 0; + case FL_SHORTCUT: + if (Fl_Widget::test_shortcut()) {popup(); return 1;} + return test_shortcut() != 0; + case FL_FOCUS: /* FALLTHROUGH */ + case FL_UNFOCUS: + if (box() && Fl::visible_focus()) { + redraw(); + return 1; + } + default: + return 0; + } +} + +/** + Creates a new Fl_Menu_Button widget using the given position, + size, and label string. The default boxtype is FL_UP_BOX. +

      The constructor sets menu() to NULL. See + Fl_Menu_ for the methods to set or change the menu. +*/ +Fl_Menu_Button::Fl_Menu_Button(int X,int Y,int W,int H,const char *l) +: Fl_Menu_(X,Y,W,H,l) { + down_box(FL_NO_BOX); +} + +// +// End of "$Id: Fl_Menu_Button.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Menu_Window.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Menu_Window.cxx new file mode 100644 index 0000000..53a330f --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Menu_Window.cxx @@ -0,0 +1,110 @@ +// +// "$Id: Fl_Menu_Window.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Menu window code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// This is the window type used by Fl_Menu to make the pop-ups. +// It draws in the overlay planes if possible. + +// Also here is the implementation of the mouse & keyboard grab, +// which are used so that clicks outside the program's windows +// can be used to dismiss the menus. + +#include +#include +#include +#include +#include + +// WIN32 note: HAVE_OVERLAY is false +#if HAVE_OVERLAY +extern XVisualInfo *fl_find_overlay_visual(); +extern XVisualInfo *fl_overlay_visual; +extern Colormap fl_overlay_colormap; +extern unsigned long fl_transparent_pixel; +static GC gc; // the GC used by all X windows +extern uchar fl_overlay; // changes how fl_color(x) works +#endif + +#include + +void Fl_Menu_Window::show() { +#if HAVE_OVERLAY + if (!shown() && overlay() && fl_find_overlay_visual()) { + XInstallColormap(fl_display, fl_overlay_colormap); + fl_background_pixel = int(fl_transparent_pixel); + Fl_X::make_xid(this, fl_overlay_visual, fl_overlay_colormap); + fl_background_pixel = -1; + } else +#endif + Fl_Single_Window::show(); +} + +void Fl_Menu_Window::flush() { +#if HAVE_OVERLAY + if (!fl_overlay_visual || !overlay()) {Fl_Single_Window::flush(); return;} + Fl_X *myi = Fl_X::i(this); + fl_window = myi->xid; + if (!gc) { + gc = XCreateGC(fl_display, myi->xid, 0, 0); +# if defined(USE_CAIRO) + if(Fl::autolink_context()) Fl::cairo_make_current(gc); // capture gc changes automatically to update the cairo context adequately +# endif + } + fl_gc = gc; + fl_overlay = 1; + fl_clip_region(myi->region); myi->region = 0; current_ = this; + draw(); + fl_overlay = 0; +#else + Fl_Single_Window::flush(); +#endif +} + +/** Erases the window, does nothing if HAVE_OVERLAY is not defined config.h */ +void Fl_Menu_Window::erase() { +#if HAVE_OVERLAY + if (!gc || !shown()) return; +//XSetForeground(fl_display, gc, 0); +//XFillRectangle(fl_display, fl_xid(this), gc, 0, 0, w(), h()); + XClearWindow(fl_display, fl_xid(this)); +#endif +} + +// Fix the colormap flashing on Maximum Impact Graphics by erasing the +// menu before unmapping it: +void Fl_Menu_Window::hide() { + erase(); + Fl_Single_Window::hide(); +} + +/** Destroys the window and all of its children.*/ +Fl_Menu_Window::~Fl_Menu_Window() { + hide(); +} + +// +// End of "$Id: Fl_Menu_Window.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Menu_add.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Menu_add.cxx new file mode 100644 index 0000000..d18943c --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Menu_add.cxx @@ -0,0 +1,494 @@ +// +// "$Id: Fl_Menu_add.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Menu utilities for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// +// Methods to alter the menu in an Fl_Menu_ widget. + +// These are for Forms emulation and for dynamically changing the +// menus. They are in this source file so they are not linked in if +// not used, which is what will happen if the program only uses +// constant menu tables. + +// Not at all guaranteed to be Forms compatible, especially with any +// string with a % sign in it! + +#include +#include "flstring.h" +#include +#include + +// If the array is this, we will double-reallocate as necessary: +static Fl_Menu_Item* local_array = 0; +static int local_array_alloc = 0; // number allocated +static int local_array_size = 0; // == size(local_array) +extern Fl_Menu_* fl_menu_array_owner; // in Fl_Menu_.cxx + +// For historical reasons there are matching methods that work on a +// user-allocated array of Fl_Menu_Item. These methods are quite +// depreciated and should not be used. These old methods use the +// above pointers to detect if the array belongs to an Fl_Menu_ +// widget, and if so it reallocates as necessary. + + + +// Insert a single Fl_Menu_Item into an array of size at offset n, +// if this is local_array it will be reallocated if needed. +static Fl_Menu_Item* array_insert( + Fl_Menu_Item* array, // array to modify + int size, // size of array + int n, // index of new insert position + const char *text, // text of new item (copy is made) + int flags // flags for new item +) { + if (array == local_array && size >= local_array_alloc) { + local_array_alloc = 2*size; + Fl_Menu_Item* newarray = new Fl_Menu_Item[local_array_alloc]; + memmove(newarray, array, size*sizeof(Fl_Menu_Item)); + delete[] local_array; + local_array = array = newarray; + } + // move all the later items: + memmove(array+n+1, array+n, sizeof(Fl_Menu_Item)*(size-n)); + // create the new item: + Fl_Menu_Item* m = array+n; + m->text = text ? strdup(text) : 0; + m->shortcut_ = 0; + m->callback_ = 0; + m->user_data_ = 0; + m->flags = flags; + m->labeltype_ = m->labelsize_ = m->labelcolor_ = 0; + m->labelfont_ = FL_HELVETICA; + return array; +} + + + +// Comparison that does not care about deleted '&' signs: +static int compare(const char* a, const char* b) { + for (;;) { + int n = *a-*b; + if (n) { + if (*a == '&') a++; + else if (*b == '&') b++; + else return n; + } else if (*a) { + a++; b++; + } else { + return 0; + } + } +} + + + +/** Adds an item. The text is split at '/' characters to automatically + produce submenus (actually a totally unnecessary feature as you can + now add submenu titles directly by setting SUBMENU in the flags): +*/ +int Fl_Menu_Item::add( + const char *mytext, + int sc, + Fl_Callback *cb, + void *data, + int myflags +) { + return(insert(-1,mytext,sc,cb,data,myflags)); // -1: append +} + + + +/** + Inserts an item at position \p index. + + If \p index is -1, the item is added the same way as Fl_Menu_Item::add(). + + If 'mytext' contains any un-escaped front slashes (/), it's assumed + a menu pathname is being specified, and the value of \p index + will be ignored. + + In all other aspects, the behavior of insert() is the same as add(). + + \param index insert new items here + \param mytext new label string, details see above + \param sc keyboard shortcut for new item + \param cb callback function for new item + \param data user data for new item + \param myflags menu flags as described in FL_Menu_Item + \returns the index into the menu() array, where the entry was added +*/ +int Fl_Menu_Item::insert( + int index, + const char *mytext, + int sc, + Fl_Callback *cb, + void *data, + int myflags +) { + Fl_Menu_Item *array = this; + Fl_Menu_Item *m = this; + const char *p; + char *q; + char buf[1024]; + + int msize = array==local_array ? local_array_size : array->size(); + int flags1 = 0; + const char* item; + + // split at slashes to make submenus: + for (;;) { + + // leading slash makes us assume it is a filename: + if (*mytext == '/') {item = mytext; break;} + + // leading underscore causes divider line: + if (*mytext == '_') {mytext++; flags1 = FL_MENU_DIVIDER;} + + // copy to buf, changing \x to x: + q = buf; + for (p=mytext; *p && *p != '/'; *q++ = *p++) if (*p=='\\' && p[1]) p++; + *q = 0; + + item = buf; + if (*p != '/') break; /* not a menu title */ + index = -1; /* any submenu specified overrides insert position */ + mytext = p+1; /* point at item title */ + + /* find a matching menu title: */ + for (; m->text; m = m->next()) + if (m->flags&FL_SUBMENU && !compare(item, m->text)) break; + + if (!m->text) { /* create a new menu */ + int n = (index==-1) ? m-array : index; + array = array_insert(array, msize, n, item, FL_SUBMENU|flags1); + msize++; + array = array_insert(array, msize, n+1, 0, 0); + msize++; + m = array+n; + } + m++; /* go into the submenu */ + flags1 = 0; + } + + /* find a matching menu item: */ + for (; m->text; m = m->next()) + if (!(m->flags&FL_SUBMENU) && !compare(m->text,item)) break; + + if (!m->text) { /* add a new menu item */ + int n = (index==-1) ? m-array : index; + array = array_insert(array, msize, n, item, myflags|flags1); + msize++; + if (myflags & FL_SUBMENU) { // add submenu delimiter + array = array_insert(array, msize, n+1, 0, 0); + msize++; + } + m = array+n; + } + + /* fill it in */ + m->shortcut_ = sc; + m->callback_ = cb; + m->user_data_ = data; + m->flags = myflags|flags1; + + if (array == local_array) local_array_size = msize; + return m-array; +} + + + +/** + Adds a new menu item. + + \param[in] label The text label for the menu item. + \param[in] shortcut Optional keyboard shortcut that can be an int or string; (FL_CTRL+'a') or "^a". Default 0 if none. + \param[in] callback Optional callback invoked when user clicks the item. Default 0 if none. + \param[in] userdata Optional user data passed as an argument to the callback. Default 0 if none. + \param[in] flags Optional flags that control the type of menu item; see below. Default is 0 for none. + \returns The index into the menu() array, where the entry was added. + + \par Description + If the menu array was directly set with menu(x), then copy() is done + to make a private array. + \par + Since this method can change the internal menu array, any menu item + pointers or indecies the application may have cached can become stale, + and should be recalculated/refreshed. + \par + A menu item's callback must not add() items to its parent menu during the callback. + + Detailed Description of Parameters + \par label + The menu item's label. This option is required. + \par + The characters "&", "/", "\", and "_" are treated as special characters in the label string. + The "&" character specifies that the following character is an accelerator and will be underlined. + The "\" character is used to escape the next character in the string. + Labels starting with the "_" character cause a divider to be placed after that menu item. + \par + A label of the form "File/Quit" will create the submenu "File" + with a menu item called "Quit". The "/" character is ignored if it appears + as the first character of the label string, e.g. "/File/Quit". + \par + The label string is copied to new memory and can be freed. + The other arguments (including the shortcut) are copied into the + menu item unchanged. + \par + If an item exists already with that name then it is replaced with + this new one. Otherwise this new one is added to the end of the + correct menu or submenu. The return value is the offset into the array + that the new entry was placed at. + + \par shortcut + The keyboard shortcut for this menu item. + \par + This parameter is optional, and defaults to 0 to indicate no shortcut. + \par + The shortcut can either be a raw integer value (eg. FL_CTRL+'A') + or a string (eg. "^c" or "^97"). + \par + Raw integer shortcuts can be a combination of keyboard chars (eg. 'A') + and optional keyboard modifiers (see Fl::event_state(), e.g. FL_SHIFT, etc). + \par + String shortcuts can be specified in one of two ways: + \par + \verbatim + [#+^] e.g. "97", "^97", "+97", "#97" + [#+^] e.g. "a", "^a", "+a", "#a" + \endverbatim + \par + ..where \ is a decimal value representing an + ascii character (eg. 97 is the ascii code for 'a'), and the optional + prefixes enhance the value that follows. Multiple prefixes must + appear in the above order. + \par + \verbatim + # - Alt + + - Shift + ^ - Control + \endverbatim + \par + Internally, the text shortcuts are converted to integer values using + fl_old_shortcut(const char*). + + \par callback + The callback to invoke when this menu item is selected. + \par + This parameter is optional, and defaults to 0 for no callback. + + \par userdata + The callback's 'user data' that is passed to the callback. + \par + This parameter is optional, and defaults to 0. + + \par flags + These are bit flags to define what kind of menu item this is. + \par + This parameter is optional, and defaults to 0 to define a 'regular' menu item. + \par + These flags can be 'OR'ed together: + \code + FL_MENU_INACTIVE // Deactivate menu item (gray out) + FL_MENU_TOGGLE // Item is a checkbox toggle (shows checkbox for on/off state) + FL_MENU_VALUE // The on/off state for checkbox/radio buttons (if set, state is 'on') + FL_MENU_RADIO // Item is a radio button (one checkbox of many can be on) + FL_MENU_INVISIBLE // Item will not show up (shortcut will work) + FL_SUBMENU_POINTER // Indicates user_data() is a pointer to another menu array + FL_SUBMENU // This item is a submenu to other items + FL_MENU_DIVIDER // Creates divider line below this item. Also ends a group of radio buttons. + \endcode + + \todo Raw integer shortcut needs examples. + Dependent on responses to http://fltk.org/newsgroups.php?gfltk.development+v:10086 and results of STR#2344 + */ +int Fl_Menu_::add(const char *label,int shortcut,Fl_Callback *callback,void *userdata,int flags) { + return(insert(-1,label,shortcut,callback,userdata,flags)); // -1: append +} + + + +/** + Inserts a new menu item at the specified \p index position. + + If \p index is -1, the menu item is appended; same behavior as add(). + + To properly insert a menu item, \p label must be the name of the item (eg. "Quit"), + and not a 'menu pathname' (eg. "File/Quit"). If a menu pathname is specified, + the value of \p index is \em ignored, the new item's position defined by the pathname. + + For more details, see add(). Except for the \p index parameter, add() + has more detailed information on parameters and behavior, and is + functionally equivalent. + + \param[in] index The menu array's index position where the new item + is inserted. If -1, behavior is the same as add(). + \param[in] label The text label for the menu item. If the label + is a menu pathname, \p index is ignored, and the pathname + indicates the position of the new item. + \param[in] shortcut Optional keyboard shortcut. Can be an int (FL_CTRL+'a') + or a string ("^a"). Default is 0. + \param[in] callback Optional callback invoked when user clicks the item. + Default 0 if none. + \param[in] userdata Optional user data passed as an argument to the callback. + Default 0 if none. + \param[in] flags Optional flags that control the type of menu item; + see add() for more info. Default is 0 for none. + \returns The index into the menu() array, where the entry was added. + + \see add() + + */ +int Fl_Menu_::insert( + int index, + const char *label, + int shortcut, + Fl_Callback *callback, + void *userdata, + int flags +) { + // make this widget own the local array: + if (this != fl_menu_array_owner) { + if (fl_menu_array_owner) { + Fl_Menu_* o = fl_menu_array_owner; + // the previous owner get's its own correctly-sized array: + int value_offset = o->value_-local_array; + int n = local_array_size; + Fl_Menu_Item* newMenu = o->menu_ = new Fl_Menu_Item[n]; + memcpy(newMenu, local_array, n*sizeof(Fl_Menu_Item)); + if (o->value_) o->value_ = newMenu+value_offset; + } + if (menu_) { + // this already has a menu array, use it as the local one: + delete[] local_array; + if (!alloc) copy(menu_); // duplicate a user-provided static array + // add to the menu's current array: + local_array_alloc = local_array_size = size(); + local_array = menu_; + } else { + // start with a blank array: + alloc = 2; // indicates that the strings can be freed + if (local_array) { + menu_ = local_array; + } else { + local_array_alloc = 15; + local_array = menu_ = new Fl_Menu_Item[local_array_alloc]; + memset(local_array, 0, sizeof(Fl_Menu_Item) * local_array_alloc); + } + memset(menu_, 0, sizeof(Fl_Menu_Item)); + local_array_size = 1; + } + fl_menu_array_owner = this; + } + int r = menu_->insert(index,label,shortcut,callback,userdata,flags); + // if it rellocated array we must fix the pointer: + int value_offset = value_-menu_; + menu_ = local_array; // in case it reallocated it + if (value_) value_ = menu_+value_offset; + return r; +} + + + +/** + This is a Forms (and SGI GL library) compatible add function, it + adds many menu items, with '|' separating the menu items, and tab + separating the menu item names from an optional shortcut string. + + The passed string is split at any '|' characters and then + add(s,0,0,0,0) is done with each section. This is + often useful if you are just using the value, and is compatible + with Forms and other GL programs. The section strings use the + same special characters as described for the long version of add(). + + No items must be added to a menu during a callback to the same menu. + + \param str string containing multiple menu labels as described above + \returns the index into the menu() array, where the entry was added +*/ +int Fl_Menu_::add(const char *str) { + char buf[1024]; + int r = 0; + while (*str) { + int sc = 0; + char *c; + for (c = buf; c < (buf + sizeof(buf) - 2) && *str && *str != '|'; str++) { + if (*str == '\t') {*c++ = 0; sc = fl_old_shortcut(str);} + else *c++ = *str; + } + *c = 0; + r = add(buf, sc, 0, 0, 0); + if (*str) str++; + } + return r; +} + + + +/** + Changes the text of item \p i. This is the only way to get + slash into an add()'ed menu item. If the menu array was directly set + with menu(x) then copy() is done to make a private array. + + \param i index into menu array + \param str new label for menu item at index i +*/ +void Fl_Menu_::replace(int i, const char *str) { + if (i<0 || i>=size()) return; + if (!alloc) copy(menu_); + if (alloc > 1) { + free((void *)menu_[i].text); + str = strdup(str); + } + menu_[i].text = str; +} + + + +/** + Deletes item \p i from the menu. If the menu array was directly + set with menu(x) then copy() is done to make a private array. + + No items must be removed from a menu during a callback to the same menu. + + \param i index into menu array +*/ +void Fl_Menu_::remove(int i) { + int n = size(); + if (i<0 || i>=n) return; + if (!alloc) copy(menu_); + // find the next item, skipping submenus: + Fl_Menu_Item* item = menu_+i; + const Fl_Menu_Item* next_item = item->next(); + // delete the text only if all items were created with add(): + if (alloc > 1) { + for (Fl_Menu_Item* m = item; m < next_item; m++) + if (m->text) free((void*)(m->text)); + } + // MRS: "n" is the menu size(), which includes the trailing NULL entry... + memmove(item, next_item, (menu_+n-next_item)*sizeof(Fl_Menu_Item)); +} + +// +// End of "$Id: Fl_Menu_add.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Menu_global.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Menu_global.cxx new file mode 100644 index 0000000..c5d5a76 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Menu_global.cxx @@ -0,0 +1,60 @@ +// +// "$Id: Fl_Menu_global.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Global menu shortcut code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Make all the shortcuts in this menu global. +// Currently only one menu at a time and you cannot destruct the menu, +// is this sufficient? + +#include +#include + +static Fl_Menu_* the_widget; + +static int handler(int e) { + if (e != FL_SHORTCUT || Fl::modal()) return 0; + Fl::first_window(the_widget->window()); + return the_widget->handle(e); +} + +/** + Make the shortcuts for this menu work no matter what window has the + focus when you type it. This is done by using + Fl::add_handler(). This Fl_Menu_ widget does not + have to be visible (ie the window it is in can be hidden, or it does + not have to be put in a window at all). +

      Currently there can be only one global()menu. Setting a new + one will replace the old one. There is no way to remove the + global() setting (so don't destroy the widget!) +*/ +void Fl_Menu_::global() { + if (!the_widget) Fl::add_handler(handler); + the_widget = this; +} + +// +// End of "$Id: Fl_Menu_global.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Multi_Label.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Multi_Label.cxx new file mode 100644 index 0000000..df117db --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Multi_Label.cxx @@ -0,0 +1,80 @@ +// +// "$Id: Fl_Multi_Label.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Multi-label widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Allows two labels to be used on a widget (by having one of them +// be one of these it allows an infinte number!) + +#include +#include +#include +#include + +static void multi_labeltype( + const Fl_Label* o, int x, int y, int w, int h, Fl_Align a) +{ + Fl_Multi_Label* b = (Fl_Multi_Label*)(o->value); + Fl_Label local = *o; + local.value = b->labela; + local.type = b->typea; + int W = w; int H = h; local.measure(W, H); + local.draw(x,y,w,h,a); + if (a & FL_ALIGN_BOTTOM) h -= H; + else if (a & FL_ALIGN_TOP) {y += H; h -= H;} + else if (a & FL_ALIGN_RIGHT) w -= W; + else if (a & FL_ALIGN_LEFT) {x += W; w -= W;} + else {int d = (h+H)/2; y += d; h -= d;} + local.value = b->labelb; + local.type = b->typeb; + local.draw(x,y,w,h,a); +} + +// measurement is only correct for left-to-right appending... +static void multi_measure(const Fl_Label* o, int& w, int& h) { + Fl_Multi_Label* b = (Fl_Multi_Label*)(o->value); + Fl_Label local = *o; + local.value = b->labela; + local.type = b->typea; + local.measure(w,h); + local.value = b->labelb; + local.type = b->typeb; + int W = 0; int H = 0; local.measure(W,H); + w += W; if (H>h) h = H; +} + +void Fl_Multi_Label::label(Fl_Widget* o) { + Fl::set_labeltype(_FL_MULTI_LABEL, multi_labeltype, multi_measure); + o->label(_FL_MULTI_LABEL, (const char*)this); +} + +void Fl_Multi_Label::label(Fl_Menu_Item* o) { + Fl::set_labeltype(_FL_MULTI_LABEL, multi_labeltype, multi_measure); + o->label(_FL_MULTI_LABEL, (const char*)this); +} + +// +// End of "$Id: Fl_Multi_Label.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Native_File_Chooser.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Native_File_Chooser.cxx new file mode 100644 index 0000000..2ef6d68 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Native_File_Chooser.cxx @@ -0,0 +1,45 @@ +// "$Id: Fl_Native_File_Chooser.cxx 7904 2010-11-28 21:12:59Z matt $" +// +// FLTK native OS file chooser widget +// +// Copyright 1998-2010 by Bill Spitzak and others. +// Copyright 2004 Greg Ercolano. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems to: +// +// http://www.fltk.org/str.php +// + +// Use Windows' chooser +#ifdef WIN32 +#include "Fl_Native_File_Chooser_WIN32.cxx" +#endif + +// Use Apple's chooser +#ifdef __APPLE__ +#include "Fl_Native_File_Chooser_MAC.cxx" +#endif + +// All else falls back to FLTK's own chooser +#if ! defined(__APPLE__) && !defined(WIN32) +#include "Fl_Native_File_Chooser_FLTK.cxx" +#endif + +// +// End of "$Id: Fl_Native_File_Chooser.cxx 7904 2010-11-28 21:12:59Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Native_File_Chooser_FLTK.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Native_File_Chooser_FLTK.cxx new file mode 100644 index 0000000..7f910a1 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Native_File_Chooser_FLTK.cxx @@ -0,0 +1,504 @@ +// "$Id: Fl_Native_File_Chooser_FLTK.cxx 7015 2010-01-17 17:09:00Z greg.ercolano $" +// +// FLTK native OS file chooser widget +// +// Copyright 1998-2005 by Bill Spitzak and others. +// Copyright 2004 Greg Ercolano. +// API changes + filter improvements by Nathan Vander Wilt 2005 +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems to: +// +// http://www.fltk.org/str.php +// + +#include +#include +#define FLTK_CHOOSER_SINGLE Fl_File_Chooser::SINGLE +#define FLTK_CHOOSER_DIRECTORY Fl_File_Chooser::DIRECTORY +#define FLTK_CHOOSER_MULTI Fl_File_Chooser::MULTI +#define FLTK_CHOOSER_CREATE Fl_File_Chooser::CREATE + +#include "Fl_Native_File_Chooser_common.cxx" +#include +#include + +/** + The constructor. Internally allocates the native widgets. + Optional \p val presets the type of browser this will be, + which can also be changed with type(). +*/ +Fl_Native_File_Chooser::Fl_Native_File_Chooser(int val) { + //// CANT USE THIS -- MESSES UP LINKING/CREATES DEPENDENCY ON fltk_images. + //// Have app call this from main() instead. + //// + //// static int init = 0; // 'first time' initialize flag + //// if ( init == 0 ) { + //// // Initialize when instanced for first time + //// Fl_File_Icon::load_system_icons(); + //// init = 1; + //// } + _btype = val; + _options = NO_OPTIONS; + _filter = NULL; + _filtvalue = 0; + _parsedfilt = NULL; + _preset_file = NULL; + _prevvalue = NULL; + _directory = NULL; + _errmsg = NULL; + _file_chooser = new Fl_File_Chooser(NULL, NULL, 0, NULL); + type(val); // do this after _file_chooser created + _nfilters = 0; + + // Added by MG + Fl_Button *b = _file_chooser->previewButton; + Fl_Window *w = b->window(); + Fl_Group::current(w); // adds a "Show hidden files" check button in _file_chooser's window + show_hidden = new Fl_Check_Button(b->x() + b->w() + 10, b->y(), 145, b->h(), "Show hidden files"); + show_hidden->callback((Fl_Callback*)show_hidden_cb, this); + my_fileList = _file_chooser->browser(); + _old_dir = 0; // to detect directory changes + prev_filtervalue = _file_chooser->filter_value(); // to detect filter changes +} + +/** + Destructor. + Deallocates any resources allocated to this widget. +*/ +Fl_Native_File_Chooser::~Fl_Native_File_Chooser() { + delete _file_chooser; + _filter = strfree(_filter); + _parsedfilt = strfree(_parsedfilt); + _preset_file = strfree(_preset_file); + _prevvalue = strfree(_prevvalue); + _directory = strfree(_directory); + _errmsg = strfree(_errmsg); + _old_dir = strfree(_old_dir); +} + +// PRIVATE: SET ERROR MESSAGE +void Fl_Native_File_Chooser::errmsg(const char *msg) { + _errmsg = strfree(_errmsg); + _errmsg = strnew(msg); +} + +// PRIVATE: translate Native types to Fl_File_Chooser types +int Fl_Native_File_Chooser::type_fl_file(int val) { + switch (val) { + case BROWSE_FILE: + return(FLTK_CHOOSER_SINGLE); + case BROWSE_DIRECTORY: + return(FLTK_CHOOSER_SINGLE | FLTK_CHOOSER_DIRECTORY); + case BROWSE_MULTI_FILE: + return(FLTK_CHOOSER_MULTI); + case BROWSE_MULTI_DIRECTORY: + return(FLTK_CHOOSER_DIRECTORY | FLTK_CHOOSER_MULTI); + case BROWSE_SAVE_FILE: + return(FLTK_CHOOSER_SINGLE | FLTK_CHOOSER_CREATE); + case BROWSE_SAVE_DIRECTORY: + return(FLTK_CHOOSER_DIRECTORY | FLTK_CHOOSER_MULTI | FLTK_CHOOSER_CREATE); + default: + return(FLTK_CHOOSER_SINGLE); + } +} + +/** + Sets the current Fl_Native_File_Chooser::Type of browser. + */ +void Fl_Native_File_Chooser::type(int val) { + _btype = val; + _file_chooser->type(type_fl_file(val)); +} + +/** + Gets the current Fl_Native_File_Chooser::Type of browser. + */ +int Fl_Native_File_Chooser::type() const { + return(_btype); +} + +/** + Sets the platform specific chooser options to \p val. + \p val is expected to be one or more Fl_Native_File_Chooser::Option flags ORed together. + Some platforms have OS-specific functions that can be enabled/disabled via this method. +

      + \code + Flag Description Win Mac Other + -------------- ----------------------------------------------- ------- ------- ------- + NEW_FOLDER Shows the 'New Folder' button. Ignored Used Used + PREVIEW Enables the 'Preview' mode by default. Ignored Ignored Used + SAVEAS_CONFIRM Confirm dialog if BROWSE_SAVE_FILE file exists. Ignored Used Used + \endcode +*/ +void Fl_Native_File_Chooser::options(int val) { + _options = val; +} + +/** + Gets the platform specific Fl_Native_File_Chooser::Option flags. +*/ +int Fl_Native_File_Chooser::options() const { + return(_options); +} + +/** + Post the chooser's dialog. Blocks until dialog has been completed or cancelled. + \returns + - 0 -- user picked a file + - 1 -- user cancelled + - -1 -- failed; errmsg() has reason +*/ +int Fl_Native_File_Chooser::show() { + // FILTER + if ( _parsedfilt ) { + _file_chooser->filter(_parsedfilt); + } + + // FILTER VALUE + // Set this /after/ setting the filter + // + _file_chooser->filter_value(_filtvalue); + + // DIRECTORY + if ( _directory && _directory[0] ) { + _file_chooser->directory(_directory); + } else { + _file_chooser->directory(_prevvalue); + } + + // PRESET FILE + if ( _preset_file ) { + _file_chooser->value(_preset_file); + } + + // OPTIONS: PREVIEW + _file_chooser->preview( (options() & PREVIEW) ? 1 : 0); + + // OPTIONS: NEW FOLDER + if ( options() & NEW_FOLDER ) + _file_chooser->type(_file_chooser->type() | FLTK_CHOOSER_CREATE); // on + + // SHOW + _file_chooser->show(); + + // BLOCK WHILE BROWSER SHOWN + while ( _file_chooser->shown() ) { + if (_old_dir==0 || strcmp(_old_dir, _file_chooser->directory()) != 0) { + _old_dir = strfree(_old_dir); + _old_dir = strnew(_file_chooser->directory()); + if (!show_hidden->value()) remove_hidden_files(my_fileList); + } else if (prev_filtervalue != _file_chooser->filter_value() ) { + prev_filtervalue = _file_chooser->filter_value(); + if (!show_hidden->value() ) remove_hidden_files(my_fileList); + } + Fl::wait(); + } + + if ( _file_chooser->value() && _file_chooser->value()[0] ) { + _prevvalue = strfree(_prevvalue); + _prevvalue = strnew(_file_chooser->value()); + _filtvalue = _file_chooser->filter_value(); // update filter value + + // HANDLE SHOWING 'SaveAs' CONFIRM + if ( options() & SAVEAS_CONFIRM && type() == BROWSE_SAVE_FILE ) { + struct stat buf; + if ( stat(_file_chooser->value(), &buf) != -1 ) { + if ( buf.st_mode & S_IFREG ) { // Regular file + exists? + if ( exist_dialog() == 0 ) { + return(1); + } + } + } + } + } + + if ( _file_chooser->count() ) return(0); + else return(1); +} + +/** + Returns a system dependent error message for the last method that failed. + This message should at least be flagged to the user in a dialog box, or to some kind of error log. + Contents will be valid only for methods that document errmsg() will have info on failures. + */ +const char *Fl_Native_File_Chooser::errmsg() const { + return(_errmsg ? _errmsg : "No error"); +} + +/** + Return the filename the user choose. + Use this if only expecting a single filename. + If more than one filename is expected, use filename(int) instead. + Return value may be "" if no filename was chosen (eg. user cancelled). + */ +const char* Fl_Native_File_Chooser::filename() const { + if ( _file_chooser->count() > 0 ) return(_file_chooser->value()); + return(""); +} + +/** + Return one of the filenames the user selected. + Use count() to determine how many filenames the user selected. +

      + \b Example: + \code + if ( fnfc->show() == 0 ) { + // Print all filenames user selected + for (int n=0; ncount(); n++ ) { + printf("%d) '%s'\n", n, fnfc->filename(n)); + } + } + \endcode + */ +const char* Fl_Native_File_Chooser::filename(int i) const { + if ( i < _file_chooser->count() ) + return(_file_chooser->value(i+1)); // convert fltk 1 based to our 0 based + return(""); +} + +/** + Set the title of the file chooser's dialog window. + Can be NULL if no title desired. + The default title varies according to the platform, so you are advised to set the title explicitly. +*/ +void Fl_Native_File_Chooser::title(const char *val) { + _file_chooser->label(val); +} + +/** + Get the title of the file chooser's dialog window. + Return value may be NULL if no title was set. +*/ +const char *Fl_Native_File_Chooser::title() const { + return(_file_chooser->label()); +} + +/** + Sets the filename filters used for browsing. + The default is NULL, which browses all files. +

      + The filter string can be any of: +

      + - A single wildcard (eg. "*.txt") + - Multiple wildcards (eg. "*.{cxx,h,H}") + - A descriptive name followed by a "\t" and a wildcard (eg. "Text Files\t*.txt") + - A list of separate wildcards with a "\n" between each (eg. "*.{cxx,H}\n*.txt") + - A list of descriptive names and wildcards (eg. "C++ Files\t*.{cxx,H}\nTxt Files\t*.txt") +

      + The format of each filter is a wildcard, or an optional user description + followed by '\\t' and the wildcard. +

      + On most platforms, each filter is available to the user via a pulldown menu + in the file chooser. The 'All Files' option is always available to the user. +*/ +void Fl_Native_File_Chooser::filter(const char *val) { + _filter = strfree(_filter); + _filter = strnew(val); + parse_filter(); +} + +/** + Returns the filter string last set. + Can be NULL if no filter was set. + */ +const char *Fl_Native_File_Chooser::filter() const { + return(_filter); +} + +/** +Gets how many filters were available, not including "All Files" +*/ +int Fl_Native_File_Chooser::filters() const { + return(_nfilters); +} + +/** + Sets which filter will be initially selected. + + The first filter is indexed as 0. + If filter_value()==filters(), then "All Files" was chosen. + If filter_value() > filters(), then a custom filter was set. + */ +void Fl_Native_File_Chooser::filter_value(int val) { + _filtvalue = val; +} + +/** + Returns which filter value was last selected by the user. + This is only valid if the chooser returns success. + */ +int Fl_Native_File_Chooser::filter_value() const { + return(_filtvalue); +} + +/** + Returns the number of filenames (or directory names) the user selected. +

      + \b Example: + \code + if ( fnfc->show() == 0 ) { + // Print all filenames user selected + for (int n=0; ncount(); n++ ) { + printf("%d) '%s'\n", n, fnfc->filename(n)); + } + } + \endcode +*/ +int Fl_Native_File_Chooser::count() const { + return(_file_chooser->count()); +} + +/** + Preset the directory the browser will show when opened. + If \p val is NULL, or no directory is specified, the chooser will attempt + to use the last non-cancelled folder. +*/ +void Fl_Native_File_Chooser::directory(const char *val) { + _directory = strfree(_directory); + _directory = strnew(val); +} + +/** + Returns the current preset directory() value. +*/ +const char *Fl_Native_File_Chooser::directory() const { + return(_directory); +} + +// PRIVATE: Convert our filter format to fltk's chooser format +// FROM TO (FLTK) +// ------------------------- -------------------------- +// "*.cxx" "*.cxx Files(*.cxx)" +// "C Files\t*.{cxx,h}" "C Files(*.{cxx,h})" +// "C Files\t*.{cxx,h}\nText Files\t*.txt" "C Files(*.{cxx,h})\tText Files(*.txt)" +// +// Returns a modified version of the filter that the caller is responsible +// for freeing with strfree(). +// +void Fl_Native_File_Chooser::parse_filter() { + _parsedfilt = strfree(_parsedfilt); // clear previous parsed filter (if any) + _nfilters = 0; + char *in = _filter; + if ( !in ) return; + + int has_name = strchr(in, '\t') ? 1 : 0; + + char mode = has_name ? 'n' : 'w'; // parse mode: n=title, w=wildcard + char wildcard[1024] = ""; // parsed wildcard + char name[1024] = ""; + + // Parse filter user specified + for ( ; 1; in++ ) { + /*** DEBUG + printf("WORKING ON '%c': mode=<%c> name=<%s> wildcard=<%s>\n", + *in, mode, name, wildcard); + ***/ + + switch (*in) { + // FINISHED PARSING NAME? + case '\t': + if ( mode != 'n' ) goto regchar; + mode = 'w'; + break; + // ESCAPE NEXT CHAR + case '\\': + ++in; + goto regchar; + // FINISHED PARSING ONE OF POSSIBLY SEVERAL FILTERS? + case '\r': + case '\n': + case '\0': + // APPEND NEW FILTER TO LIST + if ( wildcard[0] ) { + // OUT: "name(wild)\tname(wild)" + char comp[2048]; + sprintf(comp, "%s%.511s(%.511s)", ((_parsedfilt)?"\t":""), + name, wildcard); + _parsedfilt = strapp(_parsedfilt, comp); + _nfilters++; + //DEBUG printf("DEBUG: PARSED FILT NOW <%s>\n", _parsedfilt); + } + // RESET + wildcard[0] = name[0] = '\0'; + mode = strchr(in, '\t') ? 'n' : 'w'; + // DONE? + if ( *in == '\0' ) return; // done + else continue; // not done yet, more filters + + // Parse all other chars + default: // handle all non-special chars + regchar: // handle regular char + switch ( mode ) { + case 'n': chrcat(name, *in); continue; + case 'w': chrcat(wildcard, *in); continue; + } + break; + } + } + //NOTREACHED +} + +/** + Sets the default filename for the chooser. + Use directory() to set the default directory. + Mainly used to preset the filename for save dialogs, + and on most platforms can be used for opening files as well. + */ +void Fl_Native_File_Chooser::preset_file(const char* val) { + _preset_file = strfree(_preset_file); + _preset_file = strnew(val); +} + +/** + Get the preset filename. + */ +const char* Fl_Native_File_Chooser::preset_file() const { + return(_preset_file); +} + +void Fl_Native_File_Chooser::show_hidden_cb(Fl_Check_Button *o, void *data) +{ + Fl_Native_File_Chooser *mychooser = (Fl_Native_File_Chooser *)data; + if (o->value()) { + mychooser->my_fileList->load(mychooser->_file_chooser->directory()); + } else { + remove_hidden_files(mychooser->my_fileList); + mychooser->my_fileList->redraw(); + } +} + +// PRIVATE: Don't show hidden files +void Fl_Native_File_Chooser::remove_hidden_files(Fl_File_Browser *my_fileList) +{ + int count = my_fileList->size(); + for(int num = count; num >= 1; num--) { + const char *p = my_fileList->text(num); + if (*p == '.' && strcmp(p, "../") != 0) my_fileList->remove(num); + } + my_fileList->topline(1); +} + +// PRIVATE: Don't show hidden files +int Fl_Native_File_Chooser::exist_dialog() { + return(fl_choice("File exists. Are you sure you want to overwrite?", + "Cancel", " OK ", NULL)); +} + +// +// End of "$Id: Fl_Native_File_Chooser_FLTK.cxx 7015 2010-01-17 17:09:00Z greg.ercolano $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Native_File_Chooser_MAC.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Native_File_Chooser_MAC.cxx new file mode 100644 index 0000000..ab8bf70 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Native_File_Chooser_MAC.cxx @@ -0,0 +1,584 @@ +// "$Id: Fl_Native_File_Chooser_MAC.cxx 7689 2010-08-25 17:01:56Z manolo $" +// +// FLTK native OS file chooser widget +// +// Copyright 1998-2005 by Bill Spitzak and others. +// Copyright 2004 Greg Ercolano. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems to: +// +// http://www.fltk.org/str.php +// + +// TODO: +// o When doing 'open file', only dir is preset, not filename. +// Possibly 'preset_file' could be used to select the filename. +// + +#ifndef FL_DOXYGEN // PREVENT DOXYGEN'S USE OF THIS FILE + +#include "Fl_Native_File_Chooser_common.cxx" // strnew/strfree/strapp/chrcat +#include // dirname(3) +#include // stat(2) +#include // stat(2) + + +#include +#include +#include + +// FREE PATHNAMES ARRAY, IF IT HAS ANY CONTENTS +void Fl_Native_File_Chooser::clear_pathnames() { + if ( _pathnames ) { + while ( --_tpathnames >= 0 ) { + _pathnames[_tpathnames] = strfree(_pathnames[_tpathnames]); + } + delete [] _pathnames; + _pathnames = NULL; + } + _tpathnames = 0; +} + +// SET A SINGLE PATHNAME +void Fl_Native_File_Chooser::set_single_pathname(const char *s) { + clear_pathnames(); + _pathnames = new char*[1]; + _pathnames[0] = strnew(s); + _tpathnames = 1; +} + +// CONSTRUCTOR +Fl_Native_File_Chooser::Fl_Native_File_Chooser(int val) { + _btype = val; + _panel = NULL; + _options = NO_OPTIONS; + _pathnames = NULL; + _tpathnames = 0; + _title = NULL; + _filter = NULL; + _filt_names = NULL; + memset(_filt_patt, 0, sizeof(char*) * MAXFILTERS); + _filt_total = 0; + _filt_value = 0; + _directory = NULL; + _preset_file = NULL; + _errmsg = NULL; +} + +// DESTRUCTOR +Fl_Native_File_Chooser::~Fl_Native_File_Chooser() { + // _opts // nothing to manage + // _options // nothing to manage + // _keepstate // nothing to manage + // _tempitem // nothing to manage + clear_pathnames(); + _directory = strfree(_directory); + _title = strfree(_title); + _preset_file = strfree(_preset_file); + _filter = strfree(_filter); + //_filt_names // managed by clear_filters() + //_filt_patt[i] // managed by clear_filters() + //_filt_total // managed by clear_filters() + clear_filters(); + //_filt_value // nothing to manage + _errmsg = strfree(_errmsg); +} + +// GET TYPE OF BROWSER +int Fl_Native_File_Chooser::type() const { + return(_btype); +} + +// SET OPTIONS +void Fl_Native_File_Chooser::options(int val) { + _options = val; +} + +// GET OPTIONS +int Fl_Native_File_Chooser::options() const { + return(_options); +} + +// SHOW THE BROWSER WINDOW +// Returns: +// 0 - user picked a file +// 1 - user cancelled +// -1 - failed; errmsg() has reason +// +int Fl_Native_File_Chooser::show() { + + // Make sure fltk interface updates before posting our dialog + Fl::flush(); + + // POST BROWSER + int err = post(); + + _filt_total = 0; + + return(err); +} + +// SET ERROR MESSAGE +// Internal use only. +// +void Fl_Native_File_Chooser::errmsg(const char *msg) { + _errmsg = strfree(_errmsg); + _errmsg = strnew(msg); +} + +// RETURN ERROR MESSAGE +const char *Fl_Native_File_Chooser::errmsg() const { + return(_errmsg ? _errmsg : "No error"); +} + +// GET FILENAME +const char* Fl_Native_File_Chooser::filename() const { + if ( _pathnames && _tpathnames > 0 ) return(_pathnames[0]); + return(""); +} + +// GET FILENAME FROM LIST OF FILENAMES +const char* Fl_Native_File_Chooser::filename(int i) const { + if ( _pathnames && i < _tpathnames ) return(_pathnames[i]); + return(""); +} + +// GET TOTAL FILENAMES CHOSEN +int Fl_Native_File_Chooser::count() const { + return(_tpathnames); +} + +// PRESET PATHNAME +// Value can be NULL for none. +// +void Fl_Native_File_Chooser::directory(const char *val) { + _directory = strfree(_directory); + _directory = strnew(val); +} + +// GET PRESET PATHNAME +// Returned value can be NULL if none set. +// +const char* Fl_Native_File_Chooser::directory() const { + return(_directory); +} + +// SET TITLE +// Value can be NULL if no title desired. +// +void Fl_Native_File_Chooser::title(const char *val) { + _title = strfree(_title); + _title = strnew(val); +} + +// GET TITLE +// Returned value can be NULL if none set. +// +const char *Fl_Native_File_Chooser::title() const { + return(_title); +} + +// SET FILTER +// Can be NULL if no filter needed +// +void Fl_Native_File_Chooser::filter(const char *val) { + _filter = strfree(_filter); + _filter = strnew(val); + + // Parse filter user specified + // IN: _filter = "C Files\t*.{cxx,h}\nText Files\t*.txt" + // OUT: _filt_names = "C Files\tText Files" + // _filt_patt[0] = "*.{cxx,h}" + // _filt_patt[1] = "*.txt" + // _filt_total = 2 + // + parse_filter(_filter); +} + +// GET FILTER +// Returned value can be NULL if none set. +// +const char *Fl_Native_File_Chooser::filter() const { + return(_filter); +} + +// CLEAR ALL FILTERS +// Internal use only. +// +void Fl_Native_File_Chooser::clear_filters() { + _filt_names = strfree(_filt_names); + for (int i=0; i<_filt_total; i++) { + _filt_patt[i] = strfree(_filt_patt[i]); + } + _filt_total = 0; +} + +// PARSE USER'S FILTER SPEC +// Parses user specified filter ('in'), +// breaks out into _filt_patt[], _filt_names, and _filt_total. +// +// Handles: +// IN: OUT:_filt_names OUT: _filt_patt +// ------------------------------------ ------------------ --------------- +// "*.{ma,mb}" "*.{ma,mb} Files" "*.{ma,mb}" +// "*.[abc]" "*.[abc] Files" "*.[abc]" +// "*.txt" "*.txt Files" "*.c" +// "C Files\t*.[ch]" "C Files" "*.[ch]" +// "C Files\t*.[ch]\nText Files\t*.cxx" "C Files" "*.[ch]" +// +// Parsing Mode: +// IN:"C Files\t*.{cxx,h}" +// ||||||| ||||||||| +// mode: nnnnnnn wwwwwwwww +// \_____/ \_______/ +// Name Wildcard +// +void Fl_Native_File_Chooser::parse_filter(const char *in) { + clear_filters(); + if ( ! in ) return; + int has_name = strchr(in, '\t') ? 1 : 0; + + char mode = has_name ? 'n' : 'w'; // parse mode: n=title, w=wildcard + char wildcard[1024] = ""; // parsed wildcard + char name[1024] = ""; + + // Parse filter user specified + for ( ; 1; in++ ) { + + //// DEBUG + //// printf("WORKING ON '%c': mode=<%c> name=<%s> wildcard=<%s>\n", + //// *in, mode, name, wildcard); + + switch (*in) { + // FINISHED PARSING NAME? + case '\t': + if ( mode != 'n' ) goto regchar; + mode = 'w'; + break; + + // ESCAPE NEXT CHAR + case '\\': + ++in; + goto regchar; + + // FINISHED PARSING ONE OF POSSIBLY SEVERAL FILTERS? + case '\r': + case '\n': + case '\0': + // TITLE + // If user didn't specify a name, make one + // + if ( name[0] == '\0' ) { + sprintf(name, "%.*s Files", (int)sizeof(name)-10, wildcard); + } + // APPEND NEW FILTER TO LIST + if ( wildcard[0] ) { + // Add to filtername list + // Tab delimit if more than one. We later break + // tab delimited string into CFArray with + // CFStringCreateArrayBySeparatingStrings() + // + if ( _filt_total ) { + _filt_names = strapp(_filt_names, "\t"); + } + _filt_names = strapp(_filt_names, name); + + // Add filter to the pattern array + _filt_patt[_filt_total++] = strnew(wildcard); + } + // RESET + wildcard[0] = name[0] = '\0'; + mode = strchr(in, '\t') ? 'n' : 'w'; + // DONE? + if ( *in == '\0' ) return; // done + else continue; // not done yet, more filters + + // Parse all other chars + default: // handle all non-special chars + regchar: // handle regular char + switch ( mode ) { + case 'n': chrcat(name, *in); continue; + case 'w': chrcat(wildcard, *in); continue; + } + break; + } + } + //NOTREACHED +} + +// SET PRESET FILE +// Value can be NULL for none. +// +void Fl_Native_File_Chooser::preset_file(const char* val) { + _preset_file = strfree(_preset_file); + _preset_file = strnew(val); +} + +// PRESET FILE +// Returned value can be NULL if none set. +// +const char* Fl_Native_File_Chooser::preset_file() { + return(_preset_file); +} + +#import +#define UNLIKELYPREFIX "___fl_very_unlikely_prefix_" +#ifndef MAC_OS_X_VERSION_10_6 +#define MAC_OS_X_VERSION_10_6 1060 +#endif + +int Fl_Native_File_Chooser::get_saveas_basename(void) { + char *q = strdup( [[(NSSavePanel*)_panel filename] fileSystemRepresentation] ); + id delegate = [(NSSavePanel*)_panel delegate]; + if (delegate != nil) { + const char *d = [[(NSSavePanel*)_panel directory] fileSystemRepresentation]; + int l = strlen(d) + 1; + int lu = strlen(UNLIKELYPREFIX); + // Remove UNLIKELYPREFIX between directory and filename parts + memmove(q + l, q + l + lu, strlen(q + l + lu) + 1); + } + set_single_pathname( q ); + free(q); + return 0; +} + +// SET THE TYPE OF BROWSER +void Fl_Native_File_Chooser::type(int val) { + _btype = val; + switch (_btype) { + case BROWSE_FILE: + case BROWSE_MULTI_FILE: + case BROWSE_DIRECTORY: + case BROWSE_MULTI_DIRECTORY: + _panel = [NSOpenPanel openPanel]; + break; + case BROWSE_SAVE_DIRECTORY: + case BROWSE_SAVE_FILE: + _panel = [NSSavePanel savePanel]; + break; + } +} + +@interface FLopenDelegate : NSObject +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 + +#endif +{ + NSPopUpButton *nspopup; + char **filter_pattern; +} +- (FLopenDelegate*)setPopup:(NSPopUpButton*)popup filter_pattern:(char**)pattern; +- (BOOL)panel:(id)sender shouldShowFilename:(NSString *)filename; +@end +@implementation FLopenDelegate +- (FLopenDelegate*)setPopup:(NSPopUpButton*)popup filter_pattern:(char**)pattern +{ + nspopup = popup; + filter_pattern = pattern; + return self; +} +- (BOOL)panel:(id)sender shouldShowFilename:(NSString *)filename +{ + if ( [nspopup indexOfSelectedItem] == [nspopup numberOfItems] - 1) return YES; + const char *pathname = [filename fileSystemRepresentation]; + if ( fl_filename_isdir(pathname) ) return YES; + if ( fl_filename_match(pathname, filter_pattern[ [nspopup indexOfSelectedItem] ]) ) return YES; + return NO; +} +@end + +@interface FLsaveDelegate : NSObject +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 + +#endif +{ +} +- (NSString *)panel:(id)sender userEnteredFilename:(NSString *)filename confirmed:(BOOL)okFlag; +@end +@implementation FLsaveDelegate +- (NSString *)panel:(id)sender userEnteredFilename:(NSString *)filename confirmed:(BOOL)okFlag +{ + if (! okFlag) return filename; + // User has clicked save, and no overwrite confirmation should occur. + // To get the latter, we need to change the name we return (hence the prefix): + return [@ UNLIKELYPREFIX stringByAppendingString:filename]; +} +@end + +static NSPopUpButton *createPopupAccessory(NSSavePanel *panel, const char *filter, const char *title, int rank) +{ + NSPopUpButton *popup; + NSRect rectview = NSMakeRect(5, 5, 350, 30 ); + NSView *view = [[[NSView alloc] initWithFrame:rectview] autorelease]; + NSRect rectbox = NSMakeRect(0, 3, 50, 1 ); + NSBox *box = [[[NSBox alloc] initWithFrame:rectbox] autorelease]; + NSRect rectpop = NSMakeRect(60, 0, 250, 30 ); + popup = [[[NSPopUpButton alloc ] initWithFrame:rectpop pullsDown:NO] autorelease]; + [view addSubview:box]; + [view addSubview:popup]; + [box setBorderType:NSNoBorder]; + NSString *nstitle = [[NSString alloc] initWithUTF8String:title]; + [box setTitle:nstitle]; + [nstitle release]; + NSFont *font = [NSFont controlContentFontOfSize:NSRegularControlSize]; + [box setTitleFont:font]; + [box sizeToFit]; + CFStringRef tab = CFSTR("\n"); + CFStringRef tmp_cfs; + tmp_cfs = CFStringCreateWithCString(NULL, filter, kCFStringEncodingASCII); + CFArrayRef array = CFStringCreateArrayBySeparatingStrings(NULL, tmp_cfs, tab); + CFRelease(tmp_cfs); + CFRelease(tab); + [popup addItemsWithTitles:(NSArray*)array]; + NSMenuItem *item = [popup itemWithTitle:@""]; + if (item) [popup removeItemWithTitle:@""]; + CFRelease(array); + [popup selectItemAtIndex:rank]; + [panel setAccessoryView:view]; + return popup; +} + +// POST BROWSER +// Internal use only. +// Assumes '_opts' has been initialized. +// +// Returns: +// 0 - user picked a file +// 1 - user cancelled +// -1 - failed; errmsg() has reason +// +int Fl_Native_File_Chooser::post() { + // INITIALIZE BROWSER + if ( _filt_total == 0 ) { // Make sure they match + _filt_value = 0; // TBD: move to someplace more logical? + } + NSAutoreleasePool *localPool; + localPool = [[NSAutoreleasePool alloc] init]; + int retval; + NSString *nstitle = [NSString stringWithUTF8String: (_title ? _title : "No Title")]; + [(NSSavePanel*)_panel setTitle:nstitle]; + switch (_btype) { + case BROWSE_MULTI_FILE: + [(NSOpenPanel*)_panel setAllowsMultipleSelection:YES]; + break; + case BROWSE_MULTI_DIRECTORY: + [(NSOpenPanel*)_panel setAllowsMultipleSelection:YES]; + case BROWSE_DIRECTORY: + [(NSOpenPanel*)_panel setCanChooseDirectories:YES]; + break; + case BROWSE_SAVE_DIRECTORY: + [(NSSavePanel*)_panel setCanCreateDirectories:YES]; + break; + } + + // SHOW THE DIALOG + if ( [(NSSavePanel*)_panel isKindOfClass:[NSOpenPanel class]] ) { + NSPopUpButton *popup = nil; + if (_filt_total) { + char *p; p = _filter; + char *q; q = new char[strlen(p) + 1]; + char *r, *s, *t; + t = q; + do { // copy to t what is in _filter removing what is between \t and \n, if any + r = strchr(p, '\n'); + if (!r) r = p + strlen(p) - 1; + s = strchr(p, '\t'); + if (s && s < r) { memcpy(q, p, s - p); q += s - p; *(q++) = '\n'; } + else { memcpy(q, p, r - p + 1); q += r - p + 1; } + *q = 0; + p = r + 1; + } while(*p); + popup = createPopupAccessory((NSSavePanel*)_panel, t, "Enable:", 0); + delete t; + [[popup menu] addItem:[NSMenuItem separatorItem]]; + [popup addItemWithTitle:@"All Documents"]; + [popup setAction:@selector(validateVisibleColumns)]; + [popup setTarget:(NSObject*)_panel]; + static FLopenDelegate *openDelegate = nil; + if (openDelegate == nil) { + // not to be ever freed + openDelegate = [[FLopenDelegate alloc] init]; + } + [openDelegate setPopup:popup filter_pattern:_filt_patt]; + [(NSOpenPanel*)_panel setDelegate:openDelegate]; + } + NSString *dir = nil; + NSString *fname = nil; + NSString *preset = nil; + if (_preset_file) { + preset = [[NSString alloc] initWithUTF8String:_preset_file]; + if (strchr(_preset_file, '/') != NULL) + dir = [[NSString alloc] initWithString:[preset stringByDeletingLastPathComponent]]; + fname = [preset lastPathComponent]; + } + if (_directory && !dir) dir = [[NSString alloc] initWithUTF8String:_directory]; + retval = [(NSOpenPanel*)_panel runModalForDirectory:dir file:fname types:nil]; + [dir release]; + [preset release]; + if (_filt_total) { + _filt_value = [popup indexOfSelectedItem]; + } + if ( retval == NSOKButton ) { + clear_pathnames(); + NSArray *array = [(NSOpenPanel*)_panel filenames]; + _tpathnames = [array count]; + _pathnames = new char*[_tpathnames]; + for(int i = 0; i < _tpathnames; i++) { + _pathnames[i] = strnew([(NSString*)[array objectAtIndex:i] fileSystemRepresentation]); + } + } + } + else { + NSString *dir = nil; + NSString *fname = nil; + NSString *preset = nil; + NSPopUpButton *popup = nil; + [(NSSavePanel*)_panel setAllowsOtherFileTypes:YES]; + if ( !(_options & SAVEAS_CONFIRM) ) { + static FLsaveDelegate *saveDelegate = nil; + if (saveDelegate == nil)saveDelegate = [[FLsaveDelegate alloc] init]; // not to be ever freed + [(NSSavePanel*)_panel setDelegate:saveDelegate]; + } + if (_preset_file) { + preset = [[NSString alloc] initWithUTF8String:_preset_file]; + if (strchr(_preset_file, '/') != NULL) { + dir = [[NSString alloc] initWithString:[preset stringByDeletingLastPathComponent]]; + } + fname = [preset lastPathComponent]; + } + if (_directory && !dir) dir = [[NSString alloc] initWithUTF8String:_directory]; + if (_filt_total) { + popup = createPopupAccessory((NSSavePanel*)_panel, _filter, "Format:", _filt_value); + } + retval = [(NSSavePanel*)_panel runModalForDirectory:dir file:fname]; + if (_filt_total) { + _filt_value = [popup indexOfSelectedItem]; + } + [dir release]; + [preset release]; + if ( retval == NSOKButton ) get_saveas_basename(); + } + [localPool release]; + return (retval == NSOKButton ? 0 : 1); +} + +#endif /*!FL_DOXYGEN*/ + +// +// End of "$Id: Fl_Native_File_Chooser_MAC.cxx 7689 2010-08-25 17:01:56Z manolo $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Native_File_Chooser_WIN32.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Native_File_Chooser_WIN32.cxx new file mode 100644 index 0000000..4eec1f9 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Native_File_Chooser_WIN32.cxx @@ -0,0 +1,854 @@ +// "$Id: Fl_Native_File_Chooser_WIN32.cxx 7706 2010-09-27 14:57:53Z AlbrechtS $" +// +// FLTK native OS file chooser widget +// +// Copyright 1998-2005 by Bill Spitzak and others. +// Copyright 2004 Greg Ercolano. +// API changes + filter improvements by Nathan Vander Wilt 2005 +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems to: +// +// http://www.fltk.org/str.php +// + +// Any application to multi-folder implementation: +// http://www.codeproject.com/dialog/selectfolder.asp +// + +#ifndef FL_DOXYGEN // PREVENT DOXYGEN'S USE OF THIS FILE + +#include // debugging +#include //MG +#include "Fl_Native_File_Chooser_common.cxx" // strnew/strfree/strapp/chrcat +typedef const wchar_t *LPCWSTR; //MG +LPCWSTR utf8towchar(const char *in); //MG +char *wchartoutf8(LPCWSTR in); //MG + +#include + +#define LCURLY_CHR '{' +#define RCURLY_CHR '}' +#define LBRACKET_CHR '[' +#define RBRACKET_CHR ']' +#define MAXFILTERS 80 + +void fl_OleInitialize(); // in Fl.cxx (Windows only) + +// STATIC: PRINT WINDOWS 'DOUBLE NULL' STRING (DEBUG) +static void dnullprint(char *wp) { + if ( ! wp ) return; + for ( int t=0; true; t++ ) { + if ( wp[t] == '\0' && wp[t+1] == '\0' ) { + printf("\\0\\0"); + fflush(stdout); + return; + } else if ( wp[t] == '\0' ) { + printf("\\0"); + } else { + printf("%c",wp[t]); + } + } +} + +// RETURN LENGTH OF DOUBLENULL STRING +// Includes single nulls in count, excludes trailing doublenull. +// +// 1234 567 +// |||/\||| +// IN: "one\0two\0\0" +// OUT: 7 +// +static int dnulllen(const char *wp) { + int len = 0; + while ( ! ( *(wp+0) == 0 && *(wp+1) == 0 ) ) { + ++wp; + ++len; + } + return(len); +} + +// STATIC: Append a string to another, leaving terminated with DOUBLE NULL. +// Automatically handles extending length of string. +// wp can be NULL (a new wp will be allocated and initialized). +// string must be NULL terminated. +// The pointer wp may be modified on return. +// +static void dnullcat(char*&wp, const char *string, int n = -1 ) { + //DEBUG printf("DEBUG: dnullcat IN: <"); dnullprint(wp); printf(">\n"); + int inlen = ( n < 0 ) ? strlen(string) : n; + if ( ! wp ) { + wp = new char[inlen + 4]; + *(wp+0) = '\0'; + *(wp+1) = '\0'; + } else { + int wplen = dnulllen(wp); + // Make copy of wp into larger buffer + char *tmp = new char[wplen + inlen + 4]; + memcpy(tmp, wp, wplen+2); // copy of wp plus doublenull + delete [] wp; // delete old wp + wp = tmp; // use new copy + //DEBUG printf("DEBUG: dnullcat COPY: <"); dnullprint(wp); printf("> (wplen=%d)\n", wplen); + } + + // Find end of double null string + // *wp2 is left pointing at second null. + // + char *wp2 = wp; + if ( *(wp2+0) != '\0' && *(wp2+1) != '\0' ) { + for ( ; 1; wp2++ ) { + if ( *(wp2+0) == '\0' && *(wp2+1) == '\0' ) { + wp2++; + break; + } + } + } + + if ( n == -1 ) n = strlen(string); + strncpy(wp2, string, n); + + // Leave string double-null terminated + *(wp2+n+0) = '\0'; + *(wp2+n+1) = '\0'; + //DEBUG printf("DEBUG: dnullcat OUT: <"); dnullprint(wp); printf(">\n\n"); +} + +// CTOR +Fl_Native_File_Chooser::Fl_Native_File_Chooser(int val) { + _btype = val; + _options = NO_OPTIONS; + memset((void*)&_ofn, 0, sizeof(OPENFILENAMEW)); + _ofn.lStructSize = sizeof(OPENFILENAMEW); + _ofn.hwndOwner = NULL; + memset((void*)&_binf, 0, sizeof(BROWSEINFO)); + _pathnames = NULL; + _tpathnames = 0; + _directory = NULL; + _title = NULL; + _filter = NULL; + _parsedfilt = NULL; + _nfilters = 0; + _preset_file = NULL; + _errmsg = NULL; +} + +// DTOR +Fl_Native_File_Chooser::~Fl_Native_File_Chooser() { + //_pathnames // managed by clear_pathnames() + //_tpathnames // managed by clear_pathnames() + _directory = strfree(_directory); + _title = strfree(_title); + _filter = strfree(_filter); + //_parsedfilt // managed by clear_filters() + //_nfilters // managed by clear_filters() + _preset_file = strfree(_preset_file); + _errmsg = strfree(_errmsg); + clear_filters(); + clear_pathnames(); + ClearOFN(); + ClearBINF(); +} + +// SET TYPE OF BROWSER +void Fl_Native_File_Chooser::type(int val) { + _btype = val; +} + +// GET TYPE OF BROWSER +int Fl_Native_File_Chooser::type() const { + return( _btype ); +} + +// SET OPTIONS +void Fl_Native_File_Chooser::options(int val) { + _options = val; +} + +// GET OPTIONS +int Fl_Native_File_Chooser::options() const { + return(_options); +} + +// PRIVATE: SET ERROR MESSAGE +void Fl_Native_File_Chooser::errmsg(const char *val) { + _errmsg = strfree(_errmsg); + _errmsg = strnew(val); +} + +// FREE PATHNAMES ARRAY, IF IT HAS ANY CONTENTS +void Fl_Native_File_Chooser::clear_pathnames() { + if ( _pathnames ) { + while ( --_tpathnames >= 0 ) { + _pathnames[_tpathnames] = strfree(_pathnames[_tpathnames]); + } + delete [] _pathnames; + _pathnames = NULL; + } + _tpathnames = 0; +} + +// SET A SINGLE PATHNAME +void Fl_Native_File_Chooser::set_single_pathname(const char *s) { + clear_pathnames(); + _pathnames = new char*[1]; + _pathnames[0] = strnew(s); + _tpathnames = 1; +} + +// ADD PATHNAME TO EXISTING ARRAY +void Fl_Native_File_Chooser::add_pathname(const char *s) { + if ( ! _pathnames ) { + // Create first element in array + ++_tpathnames; + _pathnames = new char*[_tpathnames]; + } else { + // Grow array by 1 + char **tmp = new char*[_tpathnames+1]; // create new buffer + memcpy((void*)tmp, (void*)_pathnames, + sizeof(char*)*_tpathnames); // copy old + delete [] _pathnames; // delete old + _pathnames = tmp; // use new + ++_tpathnames; + } + _pathnames[_tpathnames-1] = strnew(s); +} + +// FREE A PIDL (Pointer to IDentity List) +void Fl_Native_File_Chooser::FreePIDL(ITEMIDLIST *pidl) { + IMalloc *imalloc = NULL; + if ( SUCCEEDED(SHGetMalloc(&imalloc)) ) { + imalloc->Free(pidl); + imalloc->Release(); + imalloc = NULL; + } +} + +// CLEAR MICROSOFT OFN (OPEN FILE NAME) CLASS +void Fl_Native_File_Chooser::ClearOFN() { + // Free any previously allocated lpstrFile before zeroing out _ofn + if ( _ofn.lpstrFile ) { + delete [] _ofn.lpstrFile; + _ofn.lpstrFile = NULL; + } + if ( _ofn.lpstrInitialDir ) { + delete [] (TCHAR*) _ofn.lpstrInitialDir; //msvc6 compilation fix + _ofn.lpstrInitialDir = NULL; + } + _ofn.lpstrFilter = NULL; // (deleted elsewhere) + int temp = _ofn.nFilterIndex; // keep the filter_value + memset((void*)&_ofn, 0, sizeof(_ofn)); + _ofn.lStructSize = sizeof(OPENFILENAMEW); + _ofn.nFilterIndex = temp; +} + +// CLEAR MICROSOFT BINF (BROWSER INFO) CLASS +void Fl_Native_File_Chooser::ClearBINF() { + if ( _binf.pidlRoot ) { + FreePIDL((ITEMIDLIST*)_binf.pidlRoot); + _binf.pidlRoot = NULL; + } + memset((void*)&_binf, 0, sizeof(_binf)); +} + +// CONVERT WINDOWS BACKSLASHES TO UNIX FRONTSLASHES +void Fl_Native_File_Chooser::Win2Unix(char *s) { + for ( ; *s; s++ ) + if ( *s == '\\' ) *s = '/'; +} + +// CONVERT UNIX FRONTSLASHES TO WINDOWS BACKSLASHES +void Fl_Native_File_Chooser::Unix2Win(char *s) { + for ( ; *s; s++ ) + if ( *s == '/' ) *s = '\\'; +} + +// SHOW FILE BROWSER +int Fl_Native_File_Chooser::showfile() { + ClearOFN(); + clear_pathnames(); + size_t fsize = MAX_PATH; + _ofn.Flags |= OFN_NOVALIDATE; // prevent disabling of front slashes + _ofn.Flags |= OFN_HIDEREADONLY; // hide goofy readonly flag + // USE NEW BROWSER + _ofn.Flags |= OFN_EXPLORER; // use newer explorer windows + _ofn.Flags |= OFN_ENABLESIZING; // allow window to be resized (hey, why not?) + + // XXX: The docs for OFN_NOCHANGEDIR says the flag is 'ineffective' on XP/2K/NT! + // But let's set it anyway.. + // + _ofn.Flags |= OFN_NOCHANGEDIR; // prevent dialog for messing up the cwd + + switch ( _btype ) { + case BROWSE_DIRECTORY: + case BROWSE_MULTI_DIRECTORY: + case BROWSE_SAVE_DIRECTORY: + abort(); // never happens: handled by showdir() + case BROWSE_FILE: + fsize = 65536; // XXX: there must be a better way + break; + case BROWSE_MULTI_FILE: + _ofn.Flags |= OFN_ALLOWMULTISELECT; + fsize = 65536; // XXX: there must be a better way + break; + case BROWSE_SAVE_FILE: + if ( options() & SAVEAS_CONFIRM && type() == BROWSE_SAVE_FILE ) { + _ofn.Flags |= OFN_OVERWRITEPROMPT; + } + break; + } + // SPACE FOR RETURNED FILENAME + _ofn.lpstrFile = new WCHAR[fsize]; + _ofn.nMaxFile = fsize-1; + _ofn.lpstrFile[0] = 0; + _ofn.lpstrFile[1] = 0; // dnull + // PARENT WINDOW + _ofn.hwndOwner = GetForegroundWindow(); + // DIALOG TITLE + if (_title) { + static WCHAR wtitle[200]; + wcscpy(wtitle, utf8towchar(_title)); + _ofn.lpstrTitle = wtitle; + } else { + _ofn.lpstrTitle = NULL; + } + // FILTER + if (_parsedfilt != NULL) { // to convert a null-containing char string into a widechar string + static WCHAR wpattern[MAX_PATH]; + const char *p = _parsedfilt; + while(*(p + strlen(p) + 1) != 0) p += strlen(p) + 1; + p += strlen(p) + 2; + MultiByteToWideChar(CP_UTF8, 0, _parsedfilt, p - _parsedfilt, wpattern, MAX_PATH); + _ofn.lpstrFilter = wpattern; + } else { + _ofn.lpstrFilter = NULL; + } + // PRESET FILE + // If set, supercedes _directory. See KB Q86920 for details + // + if ( _preset_file ) { + size_t len = strlen(_preset_file); + if ( len >= _ofn.nMaxFile ) { + char msg[80]; + sprintf(msg, "preset_file() filename is too long: %ld is >=%ld", (long)len, (long)fsize); + return(-1); + } + wcscpy(_ofn.lpstrFile, utf8towchar(_preset_file)); +// Unix2Win(_ofn.lpstrFile); + len = wcslen(_ofn.lpstrFile); + _ofn.lpstrFile[len+0] = 0; // multiselect needs dnull + _ofn.lpstrFile[len+1] = 0; + } + if ( _directory ) { + // PRESET DIR + // XXX: See KB Q86920 for doc bug: + // http://support.microsoft.com/default.aspx?scid=kb;en-us;86920 + // + _ofn.lpstrInitialDir = new WCHAR[MAX_PATH]; + wcscpy((WCHAR *)_ofn.lpstrInitialDir, utf8towchar(_directory)); + // Unix2Win((char*)_ofn.lpstrInitialDir); + } + // SAVE THE CURRENT DIRECTORY + // XXX: Save the cwd because GetOpenFileName() is probably going to + // change it, in spite of the OFN_NOCHANGEDIR flag, due to its docs + // saying the flag is 'ineffective'. %^( + // + char oldcwd[MAX_PATH]; + GetCurrentDirectory(MAX_PATH, oldcwd); + oldcwd[MAX_PATH-1] = '\0'; + // OPEN THE DIALOG WINDOW + int err; + if ( _btype == BROWSE_SAVE_FILE ) { + err = GetSaveFileNameW(&_ofn); + } else { + err = GetOpenFileNameW(&_ofn); + } + if ( err == 0 ) { + // EXTENDED ERROR CHECK + int err = CommDlgExtendedError(); + // CANCEL? + if ( err == 0 ) return(1); // user hit 'cancel' + // AN ERROR OCCURRED + char msg[80]; + sprintf(msg, "CommDlgExtendedError() code=%d", err); + errmsg(msg); + // XXX: RESTORE CWD + if ( oldcwd[0] ) SetCurrentDirectory(oldcwd); + return(-1); + } + // XXX: RESTORE CWD + if ( oldcwd[0] ) { + SetCurrentDirectory(oldcwd); + } + // PREPARE PATHNAMES FOR RETURN + switch ( _btype ) { + case BROWSE_FILE: + case BROWSE_SAVE_FILE: + set_single_pathname(wchartoutf8(_ofn.lpstrFile)); + // Win2Unix(_pathnames[_tpathnames-1]); + break; + case BROWSE_MULTI_FILE: { + // EXTRACT MULTIPLE FILENAMES + const WCHAR *dirname = _ofn.lpstrFile; + int dirlen = wcslen(dirname); + if ( dirlen > 0 ) { + // WALK STRING SEARCHING FOR 'DOUBLE-NULL' + // eg. "/dir/name\0foo1\0foo2\0foo3\0\0" + // + char pathname[MAX_PATH]; + for ( const WCHAR *s = dirname + dirlen + 1; + *s; s+= (wcslen(s)+1)) { + strcpy(pathname, wchartoutf8(dirname)); + strcat(pathname, "\\"); + strcat(pathname, wchartoutf8(s)); + add_pathname(pathname); + } + } + // XXX + // Work around problem where pasted forward-slash pathname + // into the file browser causes new "Explorer" interface + // not to grok forward slashes, passing back as a 'filename'..! + // + if ( _tpathnames == 0 ) { + add_pathname(wchartoutf8(dirname)); + // Win2Unix(_pathnames[_tpathnames-1]); + } + break; + } + case BROWSE_DIRECTORY: + case BROWSE_MULTI_DIRECTORY: + case BROWSE_SAVE_DIRECTORY: + abort(); // never happens: handled by showdir() + } + return(0); +} + +// Used by SHBrowseForFolder(), sets initial selected dir. +// Ref: Usenet: microsoft.public.vc.mfc, Dec 8 2000, 1:38p David Lowndes +// Subject: How to specify to select an initial folder .." +// +int CALLBACK Fl_Native_File_Chooser::Dir_CB(HWND win, UINT msg, LPARAM param, LPARAM data) { + switch (msg) { + case BFFM_INITIALIZED: + if (data) ::SendMessage(win, BFFM_SETSELECTION, TRUE, data); + break; + case BFFM_SELCHANGED: + TCHAR path[MAX_PATH]; + if ( SHGetPathFromIDList((ITEMIDLIST*)param, path) ) { + ::SendMessage(win, BFFM_ENABLEOK, 0, 1); + } else { + // disable ok button if not a path + ::SendMessage(win, BFFM_ENABLEOK, 0, 0); + } + break; + case BFFM_VALIDATEFAILED: + // we could pop up an annoying message here. + // also needs set ulFlags |= BIF_VALIDATE + break; + default: + break; + } + return(0); +} + +// SHOW DIRECTORY BROWSER +int Fl_Native_File_Chooser::showdir() { + // initialize OLE only once + fl_OleInitialize(); // init needed by BIF_USENEWUI + ClearBINF(); + clear_pathnames(); + // PARENT WINDOW + _binf.hwndOwner = GetForegroundWindow(); + // DIALOG TITLE + _binf.lpszTitle = _title ? _title : NULL; + // FLAGS + _binf.ulFlags = 0; // initialize + + // TBD: make sure matches to runtime system, if need be. + //(what if _WIN32_IE doesn't match system? does the program not run?) + // + // TBD: match all 3 types of directories + // + // NOTE: *Don't* use BIF_SHAREABLE. It /disables/ mapped network shares + // from being visible in BROWSE_DIRECTORY mode. + // See Walter Garm's comments in ./TODO. + +#if defined(BIF_NONEWFOLDERBUTTON) // Version 6.0 + if ( _btype == BROWSE_DIRECTORY ) _binf.ulFlags |= BIF_NONEWFOLDERBUTTON; + _binf.ulFlags |= BIF_USENEWUI | BIF_RETURNONLYFSDIRS; +#elif defined(BIF_USENEWUI) // Version 5.0 + if ( _btype == BROWSE_DIRECTORY ) _binf.ulFlags |= BIF_EDITBOX; + else if ( _btype == BROWSE_SAVE_DIRECTORY ) _binf.ulFlags |= BIF_USENEWUI; + _binf.ulFlags |= BIF_RETURNONLYFSDIRS; +#elif defined(BIF_EDITBOX) // Version 4.71 + _binf.ulFlags |= BIF_RETURNONLYFSDIRS | BIF_EDITBOX; +#else // Version Old + _binf.ulFlags |= BIF_RETURNONLYFSDIRS; +#endif + + // BUFFER + char displayname[MAX_PATH]; + _binf.pszDisplayName = displayname; + // PRESET DIR + char presetname[MAX_PATH]; + if ( _directory ) { + strcpy(presetname, _directory); + // Unix2Win(presetname); + _binf.lParam = (LPARAM)presetname; + } + else _binf.lParam = 0; + _binf.lpfn = Dir_CB; + // OPEN BROWSER + ITEMIDLIST *pidl = SHBrowseForFolder(&_binf); + // CANCEL? + if ( pidl == NULL ) return(1); + + // GET THE PATHNAME(S) THE USER SELECTED + // TBD: expand NetHood shortcuts from this PIDL?? + // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/reference/functions/shbrowseforfolder.asp + + TCHAR path[MAX_PATH]; + if ( SHGetPathFromIDList(pidl, path) ) { + // Win2Unix(path); + add_pathname(path); + } + FreePIDL(pidl); + if ( !strlen(path) ) return(1); // don't return empty pathnames + return(0); +} + +// RETURNS: +// 0 - user picked a file +// 1 - user cancelled +// -1 - failed; errmsg() has reason +// +int Fl_Native_File_Chooser::show() { + if ( _btype == BROWSE_DIRECTORY || + _btype == BROWSE_MULTI_DIRECTORY || + _btype == BROWSE_SAVE_DIRECTORY ) { + return(showdir()); + } else { + return(showfile()); + } +} + +// RETURN ERROR MESSAGE +const char *Fl_Native_File_Chooser::errmsg() const { + return(_errmsg ? _errmsg : "No error"); +} + +// GET FILENAME +const char* Fl_Native_File_Chooser::filename() const { + if ( _pathnames && _tpathnames > 0 ) return(_pathnames[0]); + return(""); +} + +// GET FILENAME FROM LIST OF FILENAMES +const char* Fl_Native_File_Chooser::filename(int i) const { + if ( _pathnames && i < _tpathnames ) return(_pathnames[i]); + return(""); +} + +// GET TOTAL FILENAMES CHOSEN +int Fl_Native_File_Chooser::count() const { + return(_tpathnames); +} + +// PRESET PATHNAME +// Can be NULL if no preset is desired. +// +void Fl_Native_File_Chooser::directory(const char *val) { + _directory = strfree(_directory); + _directory = strnew(val); +} + +// GET PRESET PATHNAME +// Can return NULL if none set. +// +const char *Fl_Native_File_Chooser::directory() const { + return(_directory); +} + +// SET TITLE +// Can be NULL if no title desired. +// +void Fl_Native_File_Chooser::title(const char *val) { + _title = strfree(_title); + _title = strnew(val); +} + +// GET TITLE +// Can return NULL if none set. +// +const char *Fl_Native_File_Chooser::title() const { + return(_title); +} + +// SET FILTER +// Can be NULL if no filter needed +// +void Fl_Native_File_Chooser::filter(const char *val) { + _filter = strfree(_filter); + clear_filters(); + if ( val ) { + _filter = strnew(val); + parse_filter(_filter); + } + add_filter("All Files", "*.*"); // always include 'all files' option + +#ifdef DEBUG + nullprint(_parsedfilt); +#endif /*DEBUG*/ +} + +// GET FILTER +// Can return NULL if none set. +// +const char *Fl_Native_File_Chooser::filter() const { + return(_filter); +} + +// CLEAR FILTERS +void Fl_Native_File_Chooser::clear_filters() { + _nfilters = 0; + _parsedfilt = strfree(_parsedfilt); +} + +// ADD A FILTER +void Fl_Native_File_Chooser::add_filter(const char *name_in, // name of filter (optional: can be null) + const char *winfilter) { // windows style filter (eg. "*.cxx;*.h") + // No name? Make one.. + char name[1024]; + if ( !name_in || name_in[0] == '\0' ) { + sprintf(name, "%.*s Files", sizeof(name)-10, winfilter); + } else { + sprintf(name, "%.*s", sizeof(name)-10, name_in); + } + dnullcat(_parsedfilt, name); + dnullcat(_parsedfilt, winfilter); + _nfilters++; + //DEBUG printf("DEBUG: ADD FILTER name=<%s> winfilter=<%s>\n", name, winfilter); +} + +// CONVERT FLTK STYLE PATTERN MATCHES TO WINDOWS 'DOUBLENULL' PATTERN +// Handles: +// IN OUT +// ----------- ----------------------------- +// *.{ma,mb} "*.{ma,mb} Files\0*.ma;*.mb\0\0" +// *.[abc] "*.[abc] Files\0*.a;*.b;*.c\0\0" +// *.txt "*.txt Files\0*.txt\0\0" +// C Files\t*.[ch] "C Files\0*.c;*.h\0\0" +// +// Example: +// IN: "*.{ma,mb}" +// OUT: "*.ma;*.mb Files\0*.ma;*.mb\0All Files\0*.*\0\0" +// --------------- --------- --------- --- +// | | | | +// Title Wildcards Title Wildcards +// +// Parsing Mode: +// IN:"C Files\t*.{cxx,h}" +// ||||||| ||||||||| +// mode: nnnnnnn ww{{{{{{{ +// \_____/ \_______/ +// Name Wildcard +// +void Fl_Native_File_Chooser::parse_filter(const char *in) { + clear_filters(); + if ( ! in ) return; + + int has_name = strchr(in, '\t') ? 1 : 0; + + char mode = has_name ? 'n' : 'w'; // parse mode: n=name, w=wildcard + int nwildcards = 0; + char wildcards[MAXFILTERS][1024]; // parsed wildcards (can be several) + char wildprefix[512] = ""; + char name[512] = ""; + + // Init + int t; + for ( t=0; t name=<%s> wildprefix=<%s> nwildcards=%d wildcards[n]=<%s>\n", + //// *in, mode, name, wildprefix, nwildcards, wildcards[nwildcards]); + + switch (*in) { + case ',': + case '|': + if ( mode == LCURLY_CHR ) { + // create new wildcard, copy in prefix + strcat(wildcards[nwildcards++], wildprefix); + continue; + } else { + goto regchar; + } + continue; + + // FINISHED PARSING A NAME? + case '\t': + if ( mode != 'n' ) goto regchar; + // finish parsing name? switch to wildcard mode + mode = 'w'; + break; + + // ESCAPE NEXT CHAR + case '\\': + ++in; + goto regchar; + + // FINISHED PARSING ONE OF POSSIBLY SEVERAL FILTERS? + case '\r': + case '\n': + case '\0': + { + if ( mode == 'w' ) { // finished parsing wildcard? + if ( nwildcards == 0 ) { + strcpy(wildcards[nwildcards++], wildprefix); + } + // Append wildcards in Microsoft's "*.one;*.two" format + char comp[4096] = ""; + for ( t=0; t 0 ) { + chrcat(wildcards[nwildcards-1], *in); + } + continue; + + case 'n': + chrcat(name, *in); + continue; + + case 'w': + chrcat(wildprefix, *in); + for ( t=0; t lchar) { + lchar = utf8len; + out = (char *)realloc(out, lchar * sizeof(char)); + } + WideCharToMultiByte(CP_UTF8, 0, in, -1, out, utf8len, NULL, NULL); + return out; +} + +LPCWSTR utf8towchar(const char *in) +{ + static WCHAR *wout = NULL; + static int lwout = 0; + if (in == NULL)return NULL; + int wlen = MultiByteToWideChar(CP_UTF8, 0, in, -1, NULL, 0); + if (wlen > lwout) { + lwout = wlen; + wout = (WCHAR *)realloc(wout, lwout * sizeof(WCHAR)); + } + MultiByteToWideChar(CP_UTF8, 0, in, -1, wout, wlen); + return wout; +} + +#endif /*!FL_DOXYGEN*/ + +// +// End of "$Id: Fl_Native_File_Chooser_WIN32.cxx 7706 2010-09-27 14:57:53Z AlbrechtS $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Native_File_Chooser_common.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Native_File_Chooser_common.cxx new file mode 100644 index 0000000..209c9c7 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Native_File_Chooser_common.cxx @@ -0,0 +1,83 @@ +// "$Id: Fl_Native_File_Chooser_common.cxx 7001 2010-01-14 19:38:23Z ianmacarthur $" +// +// FLTK native OS file chooser widget +// +// Copyright 1998-2005 by Bill Spitzak and others. +// Copyright 2004 Greg Ercolano. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems to: +// +// http://www.fltk.org/str.php +// + +#include +#include + +// COPY A STRING WITH 'new' +// Value can be NULL +// +static char *strnew(const char *val) { + if ( val == NULL ) return(NULL); + char *s = new char[strlen(val)+1]; + strcpy(s, val); + return(s); +} + +// FREE STRING CREATED WITH strnew(), NULLS OUT STRING +// Value can be NULL +// +static char *strfree(char *val) { + if ( val ) delete [] val; + return(NULL); +} + +// 'DYNAMICALLY' APPEND ONE STRING TO ANOTHER +// Returns newly allocated string, or NULL +// if s && val == NULL. +// 's' can be NULL; returns a strnew(val). +// 'val' can be NULL; s is returned unmodified. +// +// Usage: +// char *s = strnew("foo"); // s = "foo" +// s = strapp(s, "bar"); // s = "foobar" +// +static char *strapp(char *s, const char *val) { + if ( ! val ) { + return(s); // Nothing to append? return s + } + if ( ! s ) { + return(strnew(val)); // New string? return copy of val + } + char *news = new char[strlen(s)+strlen(val)+1]; + strcpy(news, s); + strcat(news, val); + delete [] s; // delete old string + return(news); // return new copy +} + +// APPEND A CHARACTER TO A STRING +// This does NOT allocate space for the new character. +// +static void chrcat(char *s, char c) { + char tmp[2] = { c, '\0' }; + strcat(s, tmp); +} + +// +// End of "$Id: Fl_Native_File_Chooser_common.cxx 7001 2010-01-14 19:38:23Z ianmacarthur $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Overlay_Window.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Overlay_Window.cxx new file mode 100644 index 0000000..dda9d3d --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Overlay_Window.cxx @@ -0,0 +1,176 @@ +// +// "$Id: Fl_Overlay_Window.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Overlay window code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/** \fn virtual void Fl_Overlay_Window::draw_overlay() = 0 + You must subclass Fl_Overlay_Window and provide this method. + It is just like a draw() method, except it draws the overlay. + The overlay will have already been "cleared" when this is called. You + can use any of the routines described in <FL/fl_draw.H>. +*/ + +// A window using double-buffering and able to draw an overlay +// on top of that. Uses the hardware to draw the overlay if +// possible, otherwise it just draws in the front buffer. + +#include +#include +#include +#include +#include + +void Fl_Overlay_Window::show() { + Fl_Double_Window::show(); + if (overlay_ && overlay_ != this) overlay_->show(); +} + +void Fl_Overlay_Window::hide() { + Fl_Double_Window::hide(); +} + +void Fl_Overlay_Window::flush() { +#ifdef BOXX_BUGS + if (overlay_ && overlay_ != this && overlay_->shown()) { + // all drawing to windows hidden by overlay windows is ignored, fix this + XUnmapWindow(fl_display, fl_xid(overlay_)); + Fl_Double_Window::flush(0); + XMapWindow(fl_display, fl_xid(overlay_)); + return; + } +#endif + int erase_overlay = (damage()&FL_DAMAGE_OVERLAY) | (overlay_ == this); + clear_damage((uchar)(damage()&~FL_DAMAGE_OVERLAY)); + Fl_Double_Window::flush(erase_overlay); + if (overlay_ == this) draw_overlay(); +} + +void Fl_Overlay_Window::resize(int X, int Y, int W, int H) { + Fl_Double_Window::resize(X,Y,W,H); + if (overlay_ && overlay_!=this) overlay_->resize(0,0,w(),h()); +} + +/** + Destroys the window and all child widgets. +*/ +Fl_Overlay_Window::~Fl_Overlay_Window() { + hide(); +// delete overlay; this is done by ~Fl_Group +} + +#if !HAVE_OVERLAY + +int Fl_Overlay_Window::can_do_overlay() {return 0;} + +/** + Call this to indicate that the overlay data has changed and needs to + be redrawn. The overlay will be clear until the first time this is + called, so if you want an initial display you must call this after + calling show(). +*/ +void Fl_Overlay_Window::redraw_overlay() { + overlay_ = this; + clear_damage((uchar)(damage()|FL_DAMAGE_OVERLAY)); + Fl::damage(FL_DAMAGE_CHILD); +} + +#else + +extern XVisualInfo *fl_find_overlay_visual(); +extern XVisualInfo *fl_overlay_visual; +extern Colormap fl_overlay_colormap; +extern unsigned long fl_transparent_pixel; +static GC gc; // the GC used by all X windows +extern uchar fl_overlay; // changes how fl_color(x) works + +class _Fl_Overlay : public Fl_Window { + friend class Fl_Overlay_Window; + void flush(); + void show(); +public: + _Fl_Overlay(int x, int y, int w, int h) : + Fl_Window(x,y,w,h) {set_flag(INACTIVE);} +}; + +int Fl_Overlay_Window::can_do_overlay() { + return fl_find_overlay_visual() != 0; +} + +void _Fl_Overlay::show() { + if (shown()) {Fl_Window::show(); return;} + fl_background_pixel = int(fl_transparent_pixel); + Fl_X::make_xid(this, fl_overlay_visual, fl_overlay_colormap); + fl_background_pixel = -1; + // find the outermost window to tell wm about the colormap: + Fl_Window *w = window(); + for (;;) {Fl_Window *w1 = w->window(); if (!w1) break; w = w1;} + XSetWMColormapWindows(fl_display, fl_xid(w), &(Fl_X::i(this)->xid), 1); +} + +void _Fl_Overlay::flush() { + fl_window = fl_xid(this); + if (!gc) { + gc = XCreateGC(fl_display, fl_xid(this), 0, 0); + } + fl_gc = gc; +#if defined(USE_CAIRO) + if (Fl::cairo_autolink_context()) Fl::cairo_make_current(this); // capture gc changes automatically to update the cairo context adequately +#endif + fl_overlay = 1; + Fl_Overlay_Window *w = (Fl_Overlay_Window *)parent(); + Fl_X *myi = Fl_X::i(this); + if (damage() != FL_DAMAGE_EXPOSE) XClearWindow(fl_display, fl_xid(this)); + fl_clip_region(myi->region); myi->region = 0; + w->draw_overlay(); + fl_overlay = 0; +} + +void Fl_Overlay_Window::redraw_overlay() { + if (!fl_display) return; // this prevents fluid -c from opening display + if (!overlay_) { + if (can_do_overlay()) { + Fl_Group::current(this); + overlay_ = new _Fl_Overlay(0,0,w(),h()); + Fl_Group::current(0); + } else { + overlay_ = this; // fake the overlay + } + } + if (shown()) { + if (overlay_ == this) { + clear_damage(damage()|FL_DAMAGE_OVERLAY); + Fl::damage(FL_DAMAGE_CHILD); + } else if (!overlay_->shown()) + overlay_->show(); + else + overlay_->redraw(); + } +} + +#endif + +// +// End of "$Id: Fl_Overlay_Window.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_PNG_Image.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_PNG_Image.cxx new file mode 100644 index 0000000..60b20a4 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_PNG_Image.cxx @@ -0,0 +1,160 @@ +// +// "$Id: Fl_PNG_Image.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Fl_PNG_Image routines. +// +// Copyright 1997-2010 by Easy Software Products. +// Image support by Matthias Melcher, Copyright 2000-2009. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// +// Contents: + +// +// Fl_PNG_Image::Fl_PNG_Image() - Load a PNG image file. +// + +// +// Include necessary header files... +// + +#include +#include +#include +#include +#include +#include + +extern "C" +{ +#if defined(HAVE_LIBPNG) && defined(HAVE_LIBZ) +# include +# ifdef HAVE_PNG_H +# include +# else +# include +# endif // HAVE_PNG_H +#endif // HAVE_LIBPNG && HAVE_LIBZ +} + + +/** + The constructor loads the named PNG image from the given png filename. +

      The destructor free all memory and server resources that are used by + the image. +*/ +Fl_PNG_Image::Fl_PNG_Image(const char *png) // I - File to read + : Fl_RGB_Image(0,0,0) { +#if defined(HAVE_LIBPNG) && defined(HAVE_LIBZ) + int i; // Looping var + FILE *fp; // File pointer + int channels; // Number of color channels + png_structp pp; // PNG read pointer + png_infop info; // PNG info pointers + png_bytep *rows; // PNG row pointers + + + // Open the PNG file... + if ((fp = fl_fopen(png, "rb")) == NULL) return; + + // Setup the PNG data structures... + pp = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + info = png_create_info_struct(pp); + + if (setjmp(png_jmpbuf(pp))) + { + Fl::warning("PNG file \"%s\" contains errors!\n", png); + return; + } + + // Initialize the PNG read "engine"... + png_init_io(pp, fp); + + // Get the image dimensions and convert to grayscale or RGB... + png_read_info(pp, info); + + if (png_get_color_type(pp, info) == PNG_COLOR_TYPE_PALETTE) + png_set_expand(pp); + + if (png_get_color_type(pp, info) & PNG_COLOR_MASK_COLOR) + channels = 3; + else + channels = 1; + + int num_trans = 0; + png_get_tRNS(pp, info, 0, &num_trans, 0); + if ((png_get_color_type(pp, info) & PNG_COLOR_MASK_ALPHA) || (num_trans != 0)) + channels ++; + + w((int)(png_get_image_width(pp, info))); + h((int)(png_get_image_height(pp, info))); + d(channels); + + if (png_get_bit_depth(pp, info) < 8) + { + png_set_packing(pp); + png_set_expand(pp); + } + else if (png_get_bit_depth(pp, info) == 16) + png_set_strip_16(pp); + +# if defined(HAVE_PNG_GET_VALID) && defined(HAVE_PNG_SET_TRNS_TO_ALPHA) + // Handle transparency... + if (png_get_valid(pp, info, PNG_INFO_tRNS)) + png_set_tRNS_to_alpha(pp); +# endif // HAVE_PNG_GET_VALID && HAVE_PNG_SET_TRNS_TO_ALPHA + + array = new uchar[w() * h() * d()]; + alloc_array = 1; + + // Allocate pointers... + rows = new png_bytep[h()]; + + for (i = 0; i < h(); i ++) + rows[i] = (png_bytep)(array + i * w() * d()); + + // Read the image, handling interlacing as needed... + for (i = png_set_interlace_handling(pp); i > 0; i --) + png_read_rows(pp, rows, NULL, h()); + +#ifdef WIN32 + // Some Windows graphics drivers don't honor transparency when RGB == white + if (channels == 4) { + // Convert RGB to 0 when alpha == 0... + uchar *ptr = (uchar *)array; + for (i = w() * h(); i > 0; i --, ptr += 4) + if (!ptr[3]) ptr[0] = ptr[1] = ptr[2] = 0; + } +#endif // WIN32 + + // Free memory and return... + delete[] rows; + + png_read_end(pp, info); + png_destroy_read_struct(&pp, &info, NULL); + + fclose(fp); +#endif // HAVE_LIBPNG && HAVE_LIBZ +} + + +// +// End of "$Id: Fl_PNG_Image.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_PNM_Image.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_PNM_Image.cxx new file mode 100644 index 0000000..569d175 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_PNM_Image.cxx @@ -0,0 +1,197 @@ +// +// "$Id: Fl_PNM_Image.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Fl_PNM_Image routines. +// +// Copyright 1997-2010 by Easy Software Products. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// +// Contents: + +// +// Fl_PNM_Image::Fl_PNM_Image() - Load a PNM image... +// + +// +// Include necessary header files... +// + +#include +#include +#include +#include +#include +#include "flstring.h" + + +// +// 'Fl_PNM_Image::Fl_PNM_Image()' - Load a PNM image... +// + +/** + The constructor loads the named PNM image. +

      The inherited destructor free all memory and server resources that are used by the image. +*/ + +Fl_PNM_Image::Fl_PNM_Image(const char *name) // I - File to read + : Fl_RGB_Image(0,0,0) { + FILE *fp; // File pointer + int x, y; // Looping vars + char line[1024], // Input line + *lineptr; // Pointer in line + uchar *ptr, // Pointer to pixel values + byte, // Byte from file + bit; // Bit in pixel + int format, // Format of PNM file + val, // Pixel value + maxval; // Maximum pixel value + + + if ((fp = fl_fopen(name, "rb")) == NULL) return; + + // + // Read the file header in the format: + // + // Pformat + // # comment1 + // # comment2 + // ... + // # commentN + // width + // height + // max sample + // + + lineptr = fgets(line, sizeof(line), fp); + if (!lineptr) { + fclose(fp); + Fl::error("Early end-of-file in PNM file \"%s\"!", name); + return; + } + + lineptr ++; + + format = atoi(lineptr); + while (isdigit(*lineptr)) lineptr ++; + + if (format == 7) lineptr = (char *)""; + + while (lineptr != NULL && w() == 0) { + if (*lineptr == '\0' || *lineptr == '#') { + lineptr = fgets(line, sizeof(line), fp); + } else if (isdigit(*lineptr)) { + w(strtol(lineptr, &lineptr, 10)); + } else lineptr ++; + } + + while (lineptr != NULL && h() == 0) { + if (*lineptr == '\0' || *lineptr == '#') { + lineptr = fgets(line, sizeof(line), fp); + } else if (isdigit(*lineptr)) { + h(strtol(lineptr, &lineptr, 10)); + } else lineptr ++; + } + + if (format != 1 && format != 4) { + maxval = 0; + + while (lineptr != NULL && maxval == 0) { + if (*lineptr == '\0' || *lineptr == '#') { + lineptr = fgets(line, sizeof(line), fp); + } else if (isdigit(*lineptr)) { + maxval = strtol(lineptr, &lineptr, 10); + } else lineptr ++; + } + } else maxval = 1; + + // Allocate memory... + if (format == 1 || format == 2 || format == 4 || format == 5) d(1); + else d(3); + +// printf("%s = %dx%dx%d\n", name, w(), h(), d()); + + array = new uchar[w() * h() * d()]; + alloc_array = 1; + + // Read the image file... + for (y = 0; y < h(); y ++) { + ptr = (uchar *)array + y * w() * d(); + + switch (format) { + case 1 : + case 2 : + for (x = w(); x > 0; x --) + if (fscanf(fp, "%d", &val) == 1) *ptr++ = (uchar)(255 * val / maxval); + break; + + case 3 : + for (x = w(); x > 0; x --) { + if (fscanf(fp, "%d", &val) == 1) *ptr++ = (uchar)(255 * val / maxval); + if (fscanf(fp, "%d", &val) == 1) *ptr++ = (uchar)(255 * val / maxval); + if (fscanf(fp, "%d", &val) == 1) *ptr++ = (uchar)(255 * val / maxval); + } + break; + + case 4 : + for (x = w(), byte = (uchar)getc(fp), bit = 128; x > 0; x --) { + if (byte & bit) *ptr++ = 255; + else *ptr++ = 0; + + if (bit > 1) bit >>= 1; + else { + bit = 128; + byte = (uchar)getc(fp); + } + } + break; + + case 5 : + case 6 : + if (maxval < 256) { + if (fread(ptr, w(), d(), fp)) { /* ignored */ } + } else { + for (x = d() * w(); x > 0; x --) { + val = (uchar)getc(fp); + val = (val<<8)|(uchar)getc(fp); + *ptr++ = (255*val)/maxval; + } + } + break; + + case 7 : /* XV 3:3:2 thumbnail format */ + for (x = w(); x > 0; x --) { + byte = (uchar)getc(fp); + + *ptr++ = (uchar)(255 * ((byte >> 5) & 7) / 7); + *ptr++ = (uchar)(255 * ((byte >> 2) & 7) / 7); + *ptr++ = (uchar)(255 * (byte & 3) / 3); + } + break; + } + } + + fclose(fp); +} + + +// +// End of "$Id: Fl_PNM_Image.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Pack.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Pack.cxx new file mode 100644 index 0000000..5889b9f --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Pack.cxx @@ -0,0 +1,157 @@ +// +// "$Id: Fl_Pack.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Packing widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Based on code by Curtis Edwards +// Group that compresses all it's children together and resizes to surround +// them on each redraw (only if box() is zero) +// Bugs: ? + +#include +#include +#include + +/** + Creates a new Fl_Pack widget using the given position, size, + and label string. The default boxtype is FL_NO_BOX. +

      The destructor also deletes all the children. This allows a + whole tree to be deleted at once, without having to keep a pointer to + all the children in the user code. A kludge has been done so the + Fl_Pack and all of it's children can be automatic (local) + variables, but you must declare the Fl_Packfirst, so + that it is destroyed last. +*/ +Fl_Pack::Fl_Pack(int X, int Y, int W, int H,const char *l) +: Fl_Group(X, Y, W, H, l) { + resizable(0); + spacing_ = 0; + // type(VERTICAL); // already set like this +} + +void Fl_Pack::draw() { + int tx = x()+Fl::box_dx(box()); + int ty = y()+Fl::box_dy(box()); + int tw = w()-Fl::box_dw(box()); + int th = h()-Fl::box_dh(box()); + int rw, rh; + int current_position = horizontal() ? tx : ty; + int maximum_position = current_position; + uchar d = damage(); + Fl_Widget*const* a = array(); + if (horizontal()) { + rw = -spacing_; + rh = th; + + for (int i = children(); i--;) + if (child(i)->visible()) { + if (child(i) != this->resizable()) rw += child(i)->w(); + rw += spacing_; + } + } else { + rw = tw; + rh = -spacing_; + + for (int i = children(); i--;) + if (child(i)->visible()) { + if (child(i) != this->resizable()) rh += child(i)->h(); + rh += spacing_; + } + } + for (int i = children(); i--;) { + Fl_Widget* o = *a++; + if (o->visible()) { + int X,Y,W,H; + if (horizontal()) { + X = current_position; + W = o->w(); + Y = ty; + H = th; + } else { + X = tx; + W = tw; + Y = current_position; + H = o->h(); + } + // Last child, if resizable, takes all remaining room + if(i == 0 && o == this->resizable()) { + if(horizontal()) + W = tw - rw; + else + H = th - rh; + } + if (spacing_ && current_position>maximum_position && box() && + (X != o->x() || Y != o->y() || d&FL_DAMAGE_ALL)) { + fl_color(color()); + if (horizontal()) + fl_rectf(maximum_position, ty, spacing_, th); + else + fl_rectf(tx, maximum_position, tw, spacing_); + } + if (X != o->x() || Y != o->y() || W != o->w() || H != o->h()) { + o->resize(X,Y,W,H); + o->clear_damage(FL_DAMAGE_ALL); + } + if (d&FL_DAMAGE_ALL) { + draw_child(*o); + draw_outside_label(*o); + } else update_child(*o); + // child's draw() can change it's size, so use new size: + current_position += (horizontal() ? o->w() : o->h()); + if (current_position > maximum_position) + maximum_position = current_position; + current_position += spacing_; + } + } + + if (horizontal()) { + if (maximum_position < tx+tw && box()) { + fl_color(color()); + fl_rectf(maximum_position, ty, tx+tw-maximum_position, th); + } + tw = maximum_position-tx; + } else { + if (maximum_position < ty+th && box()) { + fl_color(color()); + fl_rectf(tx, maximum_position, tw, ty+th-maximum_position); + } + th = maximum_position-ty; + } + + tw += Fl::box_dw(box()); if (tw <= 0) tw = 1; + th += Fl::box_dh(box()); if (th <= 0) th = 1; + if (tw != w() || th != h()) { + Fl_Widget::resize(x(),y(),tw,th); + d = FL_DAMAGE_ALL; + } + if (d&FL_DAMAGE_ALL) { + draw_box(); + draw_label(); + } +} + +// +// End of "$Id: Fl_Pack.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Paged_Device.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Paged_Device.cxx new file mode 100644 index 0000000..16822f1 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Paged_Device.cxx @@ -0,0 +1,292 @@ +// +// "$Id: Fl_Paged_Device.cxx 7708 2010-10-01 00:30:08Z greg.ercolano $" +// +// implementation of Fl_Paged_Device class for the Fast Light Tool Kit (FLTK). +// +// Copyright 2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems to: +// +// http://www.fltk.org/str.php +// +/** \file Fl_Paged_Device.cxx + \brief implementation of class Fl_Paged_Device. + */ + +#include +#include + +const char *Fl_Paged_Device::device_type = "Fl_Paged_Device"; + + +/** + @brief Draws the widget on the printed page. + * + The widget's position on the printed page is determined by the last call to origin() + and by the optional delta_x and delta_y arguments. + Its dimensions are in points unless there was a previous call to scale(). + @param[in] widget Any FLTK widget (e.g., standard, custom, window). + @param[in] delta_x Optional horizontal offset for positioning the widget relatively + to the current origin of graphics functions. + @param[in] delta_y Same as above, vertically. + */ +void Fl_Paged_Device::print_widget(Fl_Widget* widget, int delta_x, int delta_y) +{ + int old_x, old_y, new_x, new_y, is_window; + if ( ! widget->visible() ) return; + is_window = (widget->as_window() != NULL); + widget->damage(FL_DAMAGE_ALL); + // set origin to the desired top-left position of the widget + origin(&old_x, &old_y); + new_x = old_x + delta_x; + new_y = old_y + delta_y; + if (!is_window) { + new_x -= widget->x(); + new_y -= widget->y(); + } + if (new_x != old_x || new_y != old_y) { + translate(new_x - old_x, new_y - old_y ); + } + // if widget is a window, clip all drawings to the window area + if (is_window) fl_push_clip(0, 0, widget->w(), widget->h() ); + // we do some trickery to recognize OpenGL windows and draw them via a plugin + int drawn_by_plugin = 0; + if (widget->as_gl_window()) { + Fl_Plugin_Manager pm("fltk:device"); + Fl_Device_Plugin *pi = (Fl_Device_Plugin*)pm.plugin("opengl.device.fltk.org"); + if (pi) { + int width, height; + this->printable_rect(&width, &height); + drawn_by_plugin = pi->print(widget, 0, 0, height); + } + } + if (!drawn_by_plugin) { + widget->draw(); + } + if (is_window) fl_pop_clip(); + // find subwindows of widget and print them + traverse(widget); + // reset origin to where it was + if (new_x != old_x || new_y != old_y) { + untranslate(); + } +} + + +void Fl_Paged_Device::traverse(Fl_Widget *widget) +{ + Fl_Group *g = widget->as_group(); + if (!g) return; + int n = g->children(); + for (int i = 0; i < n; i++) { + Fl_Widget *c = g->child(i); + if ( !c->visible() ) continue; + if ( c->as_window() ) { + print_widget(c, c->x(), c->y()); + } + else traverse(c); + } +} + +/** + @brief Computes the page coordinates of the current origin of graphics functions. + * + @param[out] x If non-null, *x is set to the horizontal page offset of graphics origin. + @param[out] y Same as above, vertically. + */ +void Fl_Paged_Device::origin(int *x, int *y) +{ + if (x) *x = x_offset; + if (y) *y = y_offset; +} + +/** + @brief Prints a rectangular part of an on-screen window. + * + @param win The window from where to capture. + @param x The rectangle left + @param y The rectangle top + @param w The rectangle width + @param h The rectangle height + @param delta_x Optional horizontal offset from current graphics origin where to print the captured rectangle. + @param delta_y As above, vertically. + */ +void Fl_Paged_Device::print_window_part(Fl_Window *win, int x, int y, int w, int h, int delta_x, int delta_y) +{ + int slice, width, offset, count = 0; + Fl_Surface_Device *current = Fl_Surface_Device::surface(); + Fl_Display_Device::display_device()->set_current(); + Fl_Window *save_front = Fl::first_window(); + win->show(); + fl_gc = NULL; + Fl::check(); + win->make_current(); + uchar *image_data[20]; +#ifdef WIN32 // because of bug in StretchDIBits, vertically cut image in pieces of width slice + slice = 500; +#else + slice = w; +#endif + for ( offset = 0; offset < w; offset += slice) { + width = slice; + if (offset + width > w) width = w - offset; + image_data[count++] = fl_read_image(NULL, x + offset, y, width, h); + } + save_front->show(); + current->set_current(); + offset = 0; + for ( int i = 0; i < count; i++, offset += slice) { + width = slice; + if (offset + width > w) width = w - offset; + fl_draw_image(image_data[i], delta_x + offset, delta_y, width, h, 3); +#ifdef __APPLE__ + add_image(NULL, image_data[i]); +#else + delete image_data[i]; +#endif + } +} + +#ifdef __APPLE__ +void Fl_Paged_Device::add_image(Fl_Image *image, const uchar *data) +{ + struct chain_elt *elt = (struct chain_elt *)calloc(sizeof(struct chain_elt), 1); + elt->image = image; + elt->data = data; + if (image_list_) { elt->next = image_list_; } + image_list_ = elt; +} + +void Fl_Paged_Device::delete_image_list() +{ + while(image_list_) { + struct chain_elt *next = image_list_->next; + if(image_list_->image) delete image_list_->image; + if (image_list_->data) delete (uchar*) image_list_->data; // msvc6 compilation fix + free(image_list_); + image_list_ = next; + } +} +#endif + + +/** + @brief Starts a print job. + * + @param[in] pagecount the total number of pages of the job + @param[out] frompage if non-null, *frompage is set to the first page the user wants printed + @param[out] topage if non-null, *topage is set to the last page the user wants printed + @return 0 iff OK + */ +int Fl_Paged_Device::start_job(int pagecount, int *frompage, int *topage) {return 1;} + +/** + @brief Starts a new printed page + * + The page coordinates are initially in points, i.e., 1/72 inch, + and with origin at the top left of the printable page area. + @return 0 iff OK + */ +int Fl_Paged_Device::start_page (void) {return 1;} + +/** + @brief Computes the width and height of the printable area of the page. + * + Values are in the same unit as that used by FLTK drawing functions, + are unchanged by calls to origin(), but are changed by scale() calls. + Values account for the user-selected paper type and print orientation. + @return 0 iff OK. + */ +int Fl_Paged_Device::printable_rect(int *w, int *h) {return 1;} + +/** + @brief Computes the dimensions of margins that lie between the printable page area and + the full page. + * + Values are in the same unit as that used by FLTK drawing functions. They are changed + by scale() calls. + @param[out] left If non-null, *left is set to the left margin size. + @param[out] top If non-null, *top is set to the top margin size. + @param[out] right If non-null, *right is set to the right margin size. + @param[out] bottom If non-null, *bottom is set to the bottom margin size. + */ +void Fl_Paged_Device::margins(int *left, int *top, int *right, int *bottom) {} + +/** + @brief Sets the position in page coordinates of the origin of graphics functions. + * + Arguments should be expressed relatively to the result of a previous printable_rect() call. + That is, printable_rect(&w, &h); origin(w/2, 0); sets the graphics origin at the + top center of the page printable area. + Origin() calls are not affected by rotate() calls. + Successive origin() calls don't combine their effects. + @param[in] x Horizontal position in page coordinates of the desired origin of graphics functions. + @param[in] y Same as above, vertically. + */ +void Fl_Paged_Device::origin(int x, int y) {} + +/** + @brief Changes the scaling of page coordinates. + * + This function also resets the origin of graphics functions at top left of printable page area. + After a scale() call, do a printable_rect() call to get the new dimensions of the printable page area. + Successive scale() calls don't combine their effects. + @param scale_x Horizontal dimensions of plot are multiplied by this quantity. + @param scale_y Same as above, vertically. + */ +void Fl_Paged_Device::scale (float scale_x, float scale_y) {} + +/** + @brief Rotates the graphics operations relatively to paper. + * + The rotation is centered on the current graphics origin. + Successive rotate() calls don't combine their effects. + @param angle Rotation angle in counterclockwise degrees. + */ +void Fl_Paged_Device::rotate(float angle) {} + +/** + @brief To be called at the end of each page. + * + @return 0 iff OK. + */ +int Fl_Paged_Device::end_page (void) {return 1;} + +/** + @brief To be called at the end of a print job. + */ +void Fl_Paged_Device::end_job (void) {} + +/** + @brief Translates the current graphics origin accounting for the current rotation. + * + This function is only useful after a rotate() call. + Each translate() call must be matched by an untranslate() call. + Successive translate() calls add up their effects. + */ +void Fl_Paged_Device::translate(int x, int y) {} + +/** + @brief Undoes the effect of a previous translate() call. + */ +void Fl_Paged_Device::untranslate(void) {} + +// +// End of "$Id: Fl_Paged_Device.cxx 7708 2010-10-01 00:30:08Z greg.ercolano $". +// + diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Pixmap.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Pixmap.cxx new file mode 100644 index 0000000..e2ffcc2 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Pixmap.cxx @@ -0,0 +1,563 @@ +// +// "$Id: Fl_Pixmap.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Pixmap drawing code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/** \fn Fl_Pixmap::Fl_Pixmap(const char **data) + The constructors create a new pixmap from the specified XPM data.*/ + +/** \fn Fl_Pixmap::Fl_Pixmap(const unsigned char * const *data) + The constructors create a new pixmap from the specified XPM data.*/ + +/** \fn Fl_Pixmap::Fl_Pixmap(const unsigned char **data) + The constructors create a new pixmap from the specified XPM data.*/ + +// Draws X pixmap data, keeping it stashed in a server pixmap so it +// redraws fast. + +// See fl_draw_pixmap.cxx for code used to get the actual data into pixmap. +// Implemented without using the xpm library (which I can't use because +// it interferes with the color cube used by fl_draw_image). + +#include +#include +#include +#include +#include +#include +#include + +#include +#include "flstring.h" +#include + +#ifdef WIN32 +extern void fl_release_dc(HWND, HDC); // located in Fl_win32.cxx +#endif + +#ifdef __APPLE_QUARTZ__ +extern Fl_Offscreen fl_create_offscreen_with_alpha(int w, int h); +#endif + +extern uchar **fl_mask_bitmap; // used by fl_draw_pixmap.cxx to store mask +void fl_restore_clip(); // in fl_rect.cxx + +void Fl_Pixmap::measure() { + int W, H; + + // ignore empty or bad pixmap data: + if (w()<0 && data()) { + fl_measure_pixmap(data(), W, H); + w(W); h(H); + } +} + +void Fl_Pixmap::draw(int XP, int YP, int WP, int HP, int cx, int cy) { + fl_graphics_driver->draw(this, XP, YP, WP, HP, cx, cy); +} + +static int start(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int w, int h, int &cx, int &cy, + int &X, int &Y, int &W, int &H) +{ + // ignore empty or bad pixmap data: + if (!pxm->data()) { + return 2; + } + if (WP == -1) { + WP = w; + HP = h; + } + if (!w) { + return 2; + } + // account for current clip region (faster on Irix): + fl_clip_box(XP,YP,WP,HP,X,Y,W,H); + cx += X-XP; cy += Y-YP; + // clip the box down to the size of image, quit if empty: + if (cx < 0) {W += cx; X -= cx; cx = 0;} + if (cx+W > w) W = w-cx; + if (W <= 0) return 1; + if (cy < 0) {H += cy; Y -= cy; cy = 0;} + if (cy+H > h) H = h-cy; + if (H <= 0) return 1; + return 0; +} + +#ifdef __APPLE__ +void Fl_Quartz_Graphics_Driver::draw(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy) { + int X, Y, W, H; + if (pxm->w() < 0) pxm->measure(); + int code = start(pxm, XP, YP, WP, HP, pxm->w(), pxm->h(), cx, cy, X, Y, W, H); + if (code) { + if (code == 2) pxm->draw_empty(XP, YP); + return; + } + if (!pxm->id_) { + pxm->id_ = fl_create_offscreen_with_alpha(pxm->w(), pxm->h()); + fl_begin_offscreen((Fl_Offscreen)pxm->id_); + fl_draw_pixmap(pxm->data(), 0, 0, FL_GREEN); + fl_end_offscreen(); + } + fl_copy_offscreen(X, Y, W, H, (Fl_Offscreen)pxm->id_, cx, cy); +} + +#elif defined(WIN32) +void Fl_GDI_Graphics_Driver::draw(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy) { + int X, Y, W, H; + if (pxm->w() < 0) pxm->measure(); + int code = start(pxm, XP, YP, WP, HP, pxm->w(), pxm->h(), cx, cy, X, Y, W, H); + if (code) { + if (code == 2) pxm->draw_empty(XP, YP); + return; + } + if (!pxm->id_) { + pxm->id_ = fl_create_offscreen(pxm->w(), pxm->h()); + fl_begin_offscreen((Fl_Offscreen)pxm->id_); + uchar *bitmap = 0; + fl_mask_bitmap = &bitmap; + fl_draw_pixmap(pxm->data(), 0, 0, FL_BLACK); + fl_mask_bitmap = 0; + if (bitmap) { + pxm->mask_ = fl_create_bitmask(pxm->w(), pxm->h(), bitmap); + delete[] bitmap; + } + fl_end_offscreen(); + } + if (fl_surface->type() == Fl_Printer::device_type) { + typedef BOOL (WINAPI* fl_transp_func) (HDC,int,int,int,int,HDC,int,int,int,int,UINT); + static HMODULE hMod = NULL; + static fl_transp_func fl_TransparentBlt = NULL; + if (!hMod) { + hMod = LoadLibrary("MSIMG32.DLL"); + if(hMod) fl_TransparentBlt = (fl_transp_func)GetProcAddress(hMod, "TransparentBlt"); + } + if (fl_TransparentBlt) { + Fl_Offscreen tmp_id = fl_create_offscreen(pxm->w(), pxm->h()); + fl_begin_offscreen(tmp_id); + uchar *bitmap = 0; + fl_mask_bitmap = &bitmap; + // draw pixmap to offscreen + fl_draw_pixmap(pxm->data(), 0, 0); + fl_end_offscreen(); + HDC new_gc = CreateCompatibleDC(fl_gc); + int save = SaveDC(new_gc); + SelectObject(new_gc, (void*)tmp_id); + // print all of offscreen but its parts in background color + extern UINT win_pixmap_bg_color; // computed by fl_draw_pixmap() + fl_TransparentBlt(fl_gc, X, Y, W, H, new_gc, cx, cy, pxm->w(), pxm->h(), win_pixmap_bg_color ); + RestoreDC(new_gc,save); + DeleteDC(new_gc); + fl_delete_offscreen(tmp_id); + } + else { + fl_copy_offscreen(X, Y, W, H, (Fl_Offscreen)pxm->id_, cx, cy); + } + } + else if (pxm->mask_) { + HDC new_gc = CreateCompatibleDC(fl_gc); + int save = SaveDC(new_gc); + SelectObject(new_gc, (void*)pxm->mask_); + BitBlt(fl_gc, X, Y, W, H, new_gc, cx, cy, SRCAND); + SelectObject(new_gc, (void*)pxm->id_); + BitBlt(fl_gc, X, Y, W, H, new_gc, cx, cy, SRCPAINT); + RestoreDC(new_gc,save); + DeleteDC(new_gc); + } else { + fl_copy_offscreen(X, Y, W, H, (Fl_Offscreen)pxm->id_, cx, cy); + } +} + +#else // Xlib +void Fl_Xlib_Graphics_Driver::draw(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy) { + int X, Y, W, H; + if (pxm->w() < 0) pxm->measure(); + int code = start(pxm, XP, YP, WP, HP, pxm->w(), pxm->h(), cx, cy, X, Y, W, H); + if (code) { + if (code == 2) pxm->draw_empty(XP, YP); + return; + } + if (!pxm->id_) { + pxm->id_ = fl_create_offscreen(pxm->w(), pxm->h()); + fl_begin_offscreen((Fl_Offscreen)pxm->id_); + uchar *bitmap = 0; + fl_mask_bitmap = &bitmap; + fl_draw_pixmap(pxm->data(), 0, 0, FL_BLACK); + fl_mask_bitmap = 0; + if (bitmap) { + pxm->mask_ = fl_create_bitmask(pxm->w(), pxm->h(), bitmap); + delete[] bitmap; + } + fl_end_offscreen(); + } + if (pxm->mask_) { + // I can't figure out how to combine a mask with existing region, + // so cut the image down to a clipped rectangle: + int nx, ny; fl_clip_box(X,Y,W,H,nx,ny,W,H); + cx += nx-X; X = nx; + cy += ny-Y; Y = ny; + // make X use the bitmap as a mask: + XSetClipMask(fl_display, fl_gc, pxm->mask_); + int ox = X-cx; if (ox < 0) ox += pxm->w(); + int oy = Y-cy; if (oy < 0) oy += pxm->h(); + XSetClipOrigin(fl_display, fl_gc, X-cx, Y-cy); + } + fl_copy_offscreen(X, Y, W, H, pxm->id_, cx, cy); + if (pxm->mask_) { + // put the old clip region back + XSetClipOrigin(fl_display, fl_gc, 0, 0); + fl_restore_clip(); + } +} + +#endif + +/** + The destructor free all memory and server resources that are used by + the pixmap. +*/ +Fl_Pixmap::~Fl_Pixmap() { + uncache(); + delete_data(); +} + +void Fl_Pixmap::uncache() { + if (id_) { + fl_delete_offscreen((Fl_Offscreen)id_); + id_ = 0; + } + + if (mask_) { + fl_delete_bitmask((Fl_Bitmask)mask_); + mask_ = 0; + } +} + +void Fl_Pixmap::label(Fl_Widget* widget) { + widget->image(this); +} + +void Fl_Pixmap::label(Fl_Menu_Item* m) { + Fl::set_labeltype(_FL_IMAGE_LABEL, labeltype, Fl_Image::measure); + m->label(_FL_IMAGE_LABEL, (const char*)this); +} + +void Fl_Pixmap::copy_data() { + if (alloc_data) return; + + char **new_data, // New data array + **new_row; // Current row in image + int i, // Looping var + ncolors, // Number of colors in image + chars_per_pixel,// Characters per color + chars_per_line; // Characters per line + + // Figure out how many colors there are, and how big they are... + sscanf(data()[0],"%*d%*d%d%d", &ncolors, &chars_per_pixel); + chars_per_line = chars_per_pixel * w() + 1; + + // Allocate memory for the new array... + if (ncolors < 0) new_data = new char *[h() + 2]; + else new_data = new char *[h() + ncolors + 1]; + + new_data[0] = new char[strlen(data()[0]) + 1]; + strcpy(new_data[0], data()[0]); + + // Copy colors... + if (ncolors < 0) { + // Copy FLTK colormap values... + ncolors = -ncolors; + new_row = new_data + 1; + *new_row = new char[ncolors * 4]; + memcpy(*new_row, data()[1], ncolors * 4); + ncolors = 1; + new_row ++; + } else { + // Copy standard XPM colormap values... + for (i = 0, new_row = new_data + 1; i < ncolors; i ++, new_row ++) { + *new_row = new char[strlen(data()[i + 1]) + 1]; + strcpy(*new_row, data()[i + 1]); + } + } + + // Copy image data... + for (i = 0; i < h(); i ++, new_row ++) { + *new_row = new char[chars_per_line]; + memcpy(*new_row, data()[i + ncolors + 1], chars_per_line); + } + + // Update pointers... + data((const char **)new_data, h() + ncolors + 1); + alloc_data = 1; +} + +Fl_Image *Fl_Pixmap::copy(int W, int H) { + Fl_Pixmap *new_image; // New pixmap + + // Optimize the simple copy where the width and height are the same... + if (W == w() && H == h()) { + // Make an exact copy of the image and return it... + new_image = new Fl_Pixmap(data()); + new_image->copy_data(); + return new_image; + } + if (W <= 0 || H <= 0) return 0; + + // OK, need to resize the image data; allocate memory and + char **new_data, // New array for image data + **new_row, // Pointer to row in image data + *new_ptr, // Pointer into new array + new_info[255]; // New information line + const char *old_ptr; // Pointer into old array + int i, // Looping var + c, // Channel number + sy, // Source coordinate + dx, dy, // Destination coordinates + xerr, yerr, // X & Y errors + xmod, ymod, // X & Y moduli + xstep, ystep; // X & Y step increments + int ncolors, // Number of colors in image + chars_per_pixel,// Characters per color + chars_per_line; // Characters per line + + // Figure out how many colors there are, and how big they are... + sscanf(data()[0],"%*d%*d%d%d", &ncolors, &chars_per_pixel); + chars_per_line = chars_per_pixel * W + 1; + + sprintf(new_info, "%d %d %d %d", W, H, ncolors, chars_per_pixel); + + // Figure out Bresenheim step/modulus values... + xmod = w() % W; + xstep = (w() / W) * chars_per_pixel; + ymod = h() % H; + ystep = h() / H; + + // Allocate memory for the new array... + if (ncolors < 0) new_data = new char *[H + 2]; + else new_data = new char *[H + ncolors + 1]; + new_data[0] = new char[strlen(new_info) + 1]; + strcpy(new_data[0], new_info); + + // Copy colors... + if (ncolors < 0) { + // Copy FLTK colormap values... + ncolors = -ncolors; + new_row = new_data + 1; + *new_row = new char[ncolors * 4]; + memcpy(*new_row, data()[1], ncolors * 4); + ncolors = 1; + new_row ++; + } else { + // Copy standard XPM colormap values... + for (i = 0, new_row = new_data + 1; i < ncolors; i ++, new_row ++) { + *new_row = new char[strlen(data()[i + 1]) + 1]; + strcpy(*new_row, data()[i + 1]); + } + } + + // Scale the image using a nearest-neighbor algorithm... + for (dy = H, sy = 0, yerr = H; dy > 0; dy --, new_row ++) { + *new_row = new char[chars_per_line]; + new_ptr = *new_row; + + for (dx = W, xerr = W, old_ptr = data()[sy + ncolors + 1]; + dx > 0; + dx --) { + for (c = 0; c < chars_per_pixel; c ++) *new_ptr++ = old_ptr[c]; + + old_ptr += xstep; + xerr -= xmod; + + if (xerr <= 0) { + xerr += W; + old_ptr += chars_per_pixel; + } + } + + *new_ptr = '\0'; + sy += ystep; + yerr -= ymod; + if (yerr <= 0) { + yerr += H; + sy ++; + } + } + + new_image = new Fl_Pixmap((char*const*)new_data); + new_image->alloc_data = 1; + + return new_image; +} + +void Fl_Pixmap::color_average(Fl_Color c, float i) { + // Delete any existing pixmap/mask objects... + uncache(); + + // Allocate memory as needed... + copy_data(); + + // Get the color to blend with... + uchar r, g, b; + unsigned ia, ir, ig, ib; + + Fl::get_color(c, r, g, b); + if (i < 0.0f) i = 0.0f; + else if (i > 1.0f) i = 1.0f; + + ia = (unsigned)(256 * i); + ir = r * (256 - ia); + ig = g * (256 - ia); + ib = b * (256 - ia); + + // Update the colormap to do the blend... + char line[255]; // New colormap line + int color, // Looping var + ncolors, // Number of colors in image + chars_per_pixel;// Characters per color + + + sscanf(data()[0],"%*d%*d%d%d", &ncolors, &chars_per_pixel); + + if (ncolors < 0) { + // Update FLTK colormap... + ncolors = -ncolors; + uchar *cmap = (uchar *)(data()[1]); + for (color = 0; color < ncolors; color ++, cmap += 4) { + cmap[1] = (ia * cmap[1] + ir) >> 8; + cmap[2] = (ia * cmap[2] + ig) >> 8; + cmap[3] = (ia * cmap[3] + ib) >> 8; + } + } else { + // Update standard XPM colormap... + for (color = 0; color < ncolors; color ++) { + // look for "c word", or last word if none: + const char *p = data()[color + 1] + chars_per_pixel + 1; + const char *previous_word = p; + for (;;) { + while (*p && isspace(*p)) p++; + char what = *p++; + while (*p && !isspace(*p)) p++; + while (*p && isspace(*p)) p++; + if (!*p) {p = previous_word; break;} + if (what == 'c') break; + previous_word = p; + while (*p && !isspace(*p)) p++; + } + + if (fl_parse_color(p, r, g, b)) { + r = (ia * r + ir) >> 8; + g = (ia * g + ig) >> 8; + b = (ia * b + ib) >> 8; + + if (chars_per_pixel > 1) sprintf(line, "%c%c c #%02X%02X%02X", + data()[color + 1][0], + data()[color + 1][1], r, g, b); + else sprintf(line, "%c c #%02X%02X%02X", data()[color + 1][0], r, g, b); + + delete[] (char *)data()[color + 1]; + ((char **)data())[color + 1] = new char[strlen(line) + 1]; + strcpy((char *)data()[color + 1], line); + } + } + } +} + +void Fl_Pixmap::delete_data() { + if (alloc_data) { + for (int i = 0; i < count(); i ++) delete[] (char *)data()[i]; + delete[] (char **)data(); + } +} + +void Fl_Pixmap::set_data(const char * const * p) { + int height, // Number of lines in image + ncolors; // Number of colors in image + + if (p) { + sscanf(p[0],"%*d%d%d", &height, &ncolors); + if (ncolors < 0) data(p, height + 2); + else data(p, height + ncolors + 1); + } +} + + +void Fl_Pixmap::desaturate() { + // Delete any existing pixmap/mask objects... + uncache(); + + // Allocate memory as needed... + copy_data(); + + // Update the colormap to grayscale... + char line[255]; // New colormap line + int i, // Looping var + ncolors, // Number of colors in image + chars_per_pixel;// Characters per color + uchar r, g, b; + + sscanf(data()[0],"%*d%*d%d%d", &ncolors, &chars_per_pixel); + + if (ncolors < 0) { + // Update FLTK colormap... + ncolors = -ncolors; + uchar *cmap = (uchar *)(data()[1]); + for (i = 0; i < ncolors; i ++, cmap += 4) { + g = (uchar)((cmap[1] * 31 + cmap[2] * 61 + cmap[3] * 8) / 100); + cmap[1] = cmap[2] = cmap[3] = g; + } + } else { + // Update standard XPM colormap... + for (i = 0; i < ncolors; i ++) { + // look for "c word", or last word if none: + const char *p = data()[i + 1] + chars_per_pixel + 1; + const char *previous_word = p; + for (;;) { + while (*p && isspace(*p)) p++; + char what = *p++; + while (*p && !isspace(*p)) p++; + while (*p && isspace(*p)) p++; + if (!*p) {p = previous_word; break;} + if (what == 'c') break; + previous_word = p; + while (*p && !isspace(*p)) p++; + } + + if (fl_parse_color(p, r, g, b)) { + g = (uchar)((r * 31 + g * 61 + b * 8) / 100); + + if (chars_per_pixel > 1) sprintf(line, "%c%c c #%02X%02X%02X", data()[i + 1][0], + data()[i + 1][1], g, g, g); + else sprintf(line, "%c c #%02X%02X%02X", data()[i + 1][0], g, g, g); + + delete[] (char *)data()[i + 1]; + ((char **)data())[i + 1] = new char[strlen(line) + 1]; + strcpy((char *)data()[i + 1], line); + } + } + } +} + +// +// End of "$Id: Fl_Pixmap.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Positioner.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Positioner.cxx new file mode 100644 index 0000000..1a50630 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Positioner.cxx @@ -0,0 +1,161 @@ +// +// "$Id: Fl_Positioner.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Positioner widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + + +// The positioner widget from Forms, gives 2D input +// Written by: Mark Overmars + +#include +#include +#include + +static double flinear(double val, double smin, double smax, double gmin, double gmax) +{ + if (smin == smax) return gmax; + else return gmin + (gmax - gmin) * (val - smin) / (smax - smin); +} + +void Fl_Positioner::draw(int X, int Y, int W, int H) { + int x1 = X + 4; + int y1 = Y + 4; + int w1 = W - 2 * 4; + int h1 = H - 2 * 4; + int xx = int(flinear(xvalue(), xmin, xmax, x1, x1+w1-1)+.5); + int yy = int(flinear(yvalue(), ymin, ymax, y1, y1+h1-1)+.5); + draw_box(box(), X, Y, W, H, color()); + fl_color(selection_color()); + fl_xyline(x1, yy, x1+w1); + fl_yxline(xx, y1, y1+h1); +} + +void Fl_Positioner::draw() { + draw(x(), y(), w(), h()); + draw_label(); +} + +/** Returns the current position in x and y.*/ +int Fl_Positioner::value(double X, double Y) { + clear_changed(); + if (X == xvalue_ && Y == yvalue_) return 0; + xvalue_ = X; yvalue_ = Y; + redraw(); + return 1; +} + +/** Sets the X axis coordinate.*/ +int Fl_Positioner::xvalue(double X) { + return(value(X, yvalue_)); +} + +/** Sets the Y axis coordinate.*/ +int Fl_Positioner::yvalue(double Y) { + return(value(xvalue_, Y)); +} + +int Fl_Positioner::handle(int event, int X, int Y, int W, int H) { + switch (event) { + case FL_PUSH: + case FL_DRAG: + case FL_RELEASE: { + double x1 = X + 4; + double y1 = Y + 4; + double w1 = W - 2 * 4; + double h1 = H - 2 * 4; + double xx = flinear(Fl::event_x(), x1, x1+w1-1.0, xmin, xmax); + if (xstep_) xx = int(xx/xstep_+0.5) * xstep_; + if (xmin < xmax) { + if (xx < xmin) xx = xmin; + if (xx > xmax) xx = xmax; + } else { + if (xx > xmin) xx = xmin; + if (xx < xmax) xx = xmax; + } + double yy = flinear(Fl::event_y(), y1, y1+h1-1.0, ymin, ymax); + if (ystep_) yy = int(yy/ystep_+0.5) * ystep_; + if (ymin < ymax) { + if (yy < ymin) yy = ymin; + if (yy > ymax) yy = ymax; + } else { + if (yy > ymin) yy = ymin; + if (yy < ymax) yy = ymax; + } + if (xx != xvalue_ || yy != yvalue_) { + xvalue_ = xx; yvalue_ = yy; + set_changed(); + redraw(); + } } + if (!(when() & FL_WHEN_CHANGED || + (when() & FL_WHEN_RELEASE && event == FL_RELEASE))) return 1; + if (changed() || when()&FL_WHEN_NOT_CHANGED) { + if (event == FL_RELEASE) clear_changed(); + do_callback(); + } + return 1; + default: + return 0; + } +} + +int Fl_Positioner::handle(int e) { + return handle(e, x(), y(), w(), h()); +} + +/** + Creates a new Fl_Positioner widget using the given position, + size, and label string. The default boxtype is FL_NO_BOX. +*/ +Fl_Positioner::Fl_Positioner(int X, int Y, int W, int H, const char* l) +: Fl_Widget(X, Y, W, H, l) { + box(FL_DOWN_BOX); + selection_color(FL_RED); + align(FL_ALIGN_BOTTOM); + when(FL_WHEN_CHANGED); + xmin = ymin = 0; + xmax = ymax = 1; + xvalue_ = yvalue_ = .5; + xstep_ = ystep_ = 0; +} + +/** Sets the X axis bounds.*/ +void Fl_Positioner::xbounds(double a, double b) { + if (a != xmin || b != xmax) { + xmin = a; xmax = b; + redraw(); + } +} + +/** Sets the Y axis bounds.*/ +void Fl_Positioner::ybounds(double a, double b) { + if (a != ymin || b != ymax) { + ymin = a; ymax = b; + redraw(); + } +} + +// +// End of "$Id: Fl_Positioner.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_PostScript.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_PostScript.cxx new file mode 100644 index 0000000..bbbebf9 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_PostScript.cxx @@ -0,0 +1,1563 @@ +// +// "$Id: Fl_PostScript.cxx 7886 2010-11-23 13:05:37Z manolo $" +// +// PostScript device support for the Fast Light Tool Kit (FLTK). +// +// Copyright 2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems to: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include +#include +#include +#include + +const char *Fl_PostScript_Graphics_Driver::device_type = "Fl_PostScript_Graphics_Driver"; +const char *Fl_PostScript_File_Device::device_type = "Fl_PostScript_File_Device"; +/** \brief Label of the PostScript file chooser window */ +const char *Fl_PostScript_File_Device::file_chooser_title = "Select a .ps file"; + +/** + @brief The constructor. + */ +Fl_PostScript_Graphics_Driver::Fl_PostScript_Graphics_Driver(void) +{ + close_cmd_ = 0; + //lang_level_ = 3; + lang_level_ = 2; + mask = 0; + ps_filename_ = NULL; + type_ = device_type; + scale_x = scale_y = 1.; + bg_r = bg_g = bg_b = 255; +} + +/** \brief The destructor. */ +Fl_PostScript_Graphics_Driver::~Fl_PostScript_Graphics_Driver() { + if(ps_filename_) free(ps_filename_); +} + +/** + @brief The constructor. + */ +Fl_PostScript_File_Device::Fl_PostScript_File_Device(void) +{ + type_ = device_type; +#ifdef __APPLE__ + gc = fl_gc; // the display context is used by fl_text_extents() +#endif + Fl_Surface_Device::driver( new Fl_PostScript_Graphics_Driver() ); +} + +/** + \brief Returns the PostScript driver of this drawing surface. + */ +Fl_PostScript_Graphics_Driver *Fl_PostScript_File_Device::driver() +{ + return (Fl_PostScript_Graphics_Driver*)Fl_Surface_Device::driver(); +} + + +/** + @brief Begins the session where all graphics requests will go to a local PostScript file. + * + Opens a file dialog entitled with Fl_PostScript_File_Device::file_chooser_title to select an output PostScript file. + @param pagecount The total number of pages to be created. + @param format Desired page format. + @param layout Desired page layout. + @return 0 iff OK, 1 if user cancelled the file dialog, 2 if fopen failed on user-selected output file. + */ +int Fl_PostScript_File_Device::start_job (int pagecount, enum Fl_PostScript_Graphics_Driver::Page_Format format, enum Fl_PostScript_Graphics_Driver::Page_Layout layout) +{ + Fl_Native_File_Chooser fnfc; + fnfc.title(Fl_PostScript_File_Device::file_chooser_title); + fnfc.type(Fl_Native_File_Chooser::BROWSE_SAVE_FILE); + fnfc.options(Fl_Native_File_Chooser::SAVEAS_CONFIRM); + fnfc.filter("PostScript\t*.ps\n"); + // Show native chooser + if ( fnfc.show() ) return 1; + Fl_PostScript_Graphics_Driver *ps = driver(); + ps->output = fopen(fnfc.filename(), "w"); + if(ps->output == NULL) return 2; + ps->ps_filename_ = strdup(fnfc.filename()); + ps->start_postscript(pagecount, format, layout); + this->set_current(); + return 0; +} + +static int dont_close(FILE *f) +{ + return 0; +} + +/** + @brief Begins the session where all graphics requests will go to FILE pointer. + * + @param ps_output A writable FILE pointer that will receive PostScript output and that should not be closed + until after end_job() has been called. + @param pagecount The total number of pages to be created. + @param format Desired page format. + @param layout Desired page layout. + @return always 0. + */ +int Fl_PostScript_File_Device::start_job (FILE *ps_output, int pagecount, enum Fl_PostScript_Graphics_Driver::Page_Format format, enum Fl_PostScript_Graphics_Driver::Page_Layout layout) +{ + Fl_PostScript_Graphics_Driver *ps = driver(); + ps->output = ps_output; + ps->ps_filename_ = NULL; + ps->start_postscript(pagecount, format, layout); + ps->close_command(dont_close); // so that end_job() doesn't close the file + this->set_current(); + return 0; +} + +/** + @brief The destructor. + */ +Fl_PostScript_File_Device::~Fl_PostScript_File_Device() { + Fl_PostScript_Graphics_Driver *ps = driver(); + if (ps) delete ps; +} + +#ifndef FL_DOXYGEN + +#if ! (defined(__APPLE__) || defined(WIN32) ) + #include "print_panel.cxx" +#endif + +const Fl_PostScript_Graphics_Driver::page_format Fl_PostScript_Graphics_Driver::page_formats[NO_PAGE_FORMATS] = { // order of enum Page_Format +// comes from appendix B of 5003.PPD_Spec_v4.3.pdf + + // A* // index(Ai) = i + {2384, 3370, "A0"}, + {1684, 2384, "A1"}, + {1191, 1684, "A2"}, + { 842, 1191, "A3"}, + { 595, 842, "A4"}, + { 420, 595, "A5"}, + { 297, 420, "A6"}, + { 210, 297, "A7"}, + { 148, 210, "A8"}, + { 105, 148, "A9"}, + + // B* // index(Bi) = i+10 + {2920, 4127, "B0"}, + {2064, 2920, "B1"}, + {1460, 2064, "B2"}, + {1032, 1460, "B3"}, + { 729, 1032, "B4"}, + { 516, 729, "B5"}, + { 363, 516, "B6"}, + { 258, 363, "B7"}, + { 181, 258, "B8"}, + { 127, 181, "B9"}, + { 91, 127, "B10"}, + + // others + { 459, 649, "EnvC5"}, // envelope + { 312, 624, "EnvDL"}, // envelope + { 522, 756, "Executive"}, + { 595, 935, "Folio"}, + {1224, 792, "Ledger"}, // landscape + { 612, 1008, "Legal"}, + { 612, 792, "Letter"}, + { 792, 1224, "Tabloid"}, + { 297, 684, "Env10"} // envelope +}; + +// Prolog string + +static const char * prolog = +"%%BeginProlog\n" +"/L { /y2 exch def\n" +"/x2 exch def\n" +"/y1 exch def\n" +"/x1 exch def\n" +"newpath x1 y1 moveto x2 y2 lineto\n" +"stroke}\n" +"bind def\n" + + +"/R { /dy exch def\n" +"/dx exch def\n" +"/y exch def\n" +"/x exch def\n" +"newpath\n" +"x y moveto\n" +"dx 0 rlineto\n" +"0 dy rlineto\n" +"dx neg 0 rlineto\n" +"closepath stroke\n" +"} bind def\n" + +"/CL {\n" +"/dy exch def\n" +"/dx exch def\n" +"/y exch def\n" +"/x exch def\n" +"newpath\n" +"x y moveto\n" +"dx 0 rlineto\n" +"0 dy rlineto\n" +"dx neg 0 rlineto\n" +"closepath\n" +"clip\n" +"} bind def\n" + +"/FR { /dy exch def\n" +"/dx exch def\n" +"/y exch def\n" +"/x exch def\n" +"currentlinewidth 0 setlinewidth newpath\n" +"x y moveto\n" +"dx 0 rlineto\n" +"0 dy rlineto\n" +"dx neg 0 rlineto\n" +"closepath fill setlinewidth\n" +"} bind def\n" + +"/GS { gsave } bind def\n" +"/GR { grestore } bind def\n" + +"/SP { showpage } bind def\n" +"/LW { setlinewidth } bind def\n" +"/CF /Courier def\n" +"/SF { /CF exch def } bind def\n" +"/fsize 12 def\n" +"/FS { /fsize exch def fsize CF findfont exch scalefont setfont }def \n" + + +"/GL { setgray } bind def\n" +"/SRGB { setrgbcolor } bind def\n" + +// color images + +"/CI { GS /py exch def /px exch def /sy exch def /sx exch def\n" +"translate \n" +"sx sy scale px py 8 \n" +"[ px 0 0 py neg 0 py ]\n" +"currentfile /ASCIIHexDecode filter\n false 3" +" colorimage GR\n" +"} bind def\n" + +// gray images + +"/GI { GS /py exch def /px exch def /sy exch def /sx exch def \n" +"translate \n" +"sx sy scale px py 8 \n" + + +"[ px 0 0 py neg 0 py ]\n" +"currentfile /ASCIIHexDecode filter\n" +"image GR\n" +"} bind def\n" + +// single-color bitmask + +"/MI { GS /py exch def /px exch def /sy exch def /sx exch def \n" +"translate \n" +"sx sy scale px py true \n" +"[ px 0 0 py neg 0 py ]\n" +"currentfile /ASCIIHexDecode filter\n" +"imagemask GR\n" +"} bind def\n" + + +// path + +"/BFP { newpath moveto } def\n" +"/BP { newpath } bind def \n" +"/PL { lineto } bind def \n" +"/PM { moveto } bind def \n" +"/MT { moveto } bind def \n" +"/LT { lineto } bind def \n" +"/EFP { closepath fill } bind def\n" //was:stroke +"/ELP { stroke } bind def\n" +"/ECP { closepath stroke } bind def\n" // Closed (loop) +"/LW { setlinewidth } bind def\n" + +// ////////////////////////// misc //////////////// +"/TR { translate } bind def\n" +"/CT { concat } bind def\n" +"/RCT { matrix invertmatrix concat} bind def\n" +"/SC { scale } bind def\n" +//"/GPD { currentpagedevice /PageSize get} def\n" + +// show at position with desired width +// usage: +// width (string) x y show_pos_width +"/show_pos_width {GS moveto dup dup stringwidth pop exch length exch 3 index exch sub exch " +"div 0 2 index 1 -1 scale ashow pop pop GR} bind def\n" // spacing altered to match desired width +//"/show_pos_width {GS moveto dup stringwidth pop 3 2 roll exch div -1 matrix scale concat " +//"show GR } bind def\n" // horizontally scaled text to match desired width + +; + + +static const char * prolog_2 = // prolog relevant only if lang_level >1 + +// color image dictionaries +"/CII {GS /inter exch def /py exch def /px exch def /sy exch def /sx exch def \n" +"translate \n" +"sx sy scale\n" +"/DeviceRGB setcolorspace\n" +"/IDD 8 dict def\n" +"IDD begin\n" +"/ImageType 1 def\n" +"/Width px def\n" +"/Height py def\n" +"/BitsPerComponent 8 def\n" +"/Interpolate inter def\n" +"/DataSource currentfile /ASCIIHexDecode filter def\n" +"/MultipleDataSources false def\n" +"/ImageMatrix [ px 0 0 py neg 0 py ] def\n" +"/Decode [ 0 1 0 1 0 1 ] def\n" +"end\n" +"IDD image GR} bind def\n" + +// gray image dict +"/GII {GS /inter exch def /py exch def /px exch def /sy exch def /sx exch def \n" +"translate \n" +"sx sy scale\n" +"/DeviceGray setcolorspace\n" +"/IDD 8 dict def\n" +"IDD begin\n" +"/ImageType 1 def\n" +"/Width px def\n" +"/Height py def\n" +"/BitsPerComponent 8 def\n" + +"/Interpolate inter def\n" +"/DataSource currentfile /ASCIIHexDecode filter def\n" +"/MultipleDataSources false def\n" +"/ImageMatrix [ px 0 0 py neg 0 py ] def\n" +"/Decode [ 0 1 ] def\n" +"end\n" +"IDD image GR} bind def\n" + +// Create a custom PostScript font derived from PostScript standard text fonts +// The encoding of this custom font is as follows: +// 0000-00FF coincides with Unicode, that is to ASCII + Latin-1 +// 0100-017F coincides with Unicode, that is to Latin Extended-A +// 0180-01A6 encodes miscellaneous characters present in PostScript standard text fonts + +// use ISOLatin1Encoding for all text fonts +"/ToISO { dup findfont dup length dict copy begin /Encoding ISOLatin1Encoding def currentdict end definefont pop } def\n" +"/Helvetica ToISO /Helvetica-Bold ToISO /Helvetica-Oblique ToISO /Helvetica-BoldOblique ToISO \n" +"/Courier ToISO /Courier-Bold ToISO /Courier-Oblique ToISO /Courier-BoldOblique ToISO \n" +"/Times-Roman ToISO /Times-Bold ToISO /Times-Italic ToISO /Times-BoldItalic ToISO \n" + +// define LatinExtA, the encoding of Latin-extended-A + some additional characters +// see http://www.adobe.com/devnet/opentype/archives/glyphlist.txt for their names +"/LatinExtA \n" +"[ " +" /Amacron /amacron /Abreve /abreve /Aogonek /aogonek\n" // begin of Latin Extended-A code page +" /Cacute /cacute /Ccircumflex /ccircumflex /Cdotaccent /cdotaccent /Ccaron /ccaron \n" +" /Dcaron /dcaron /Dcroat /dcroat\n" +" /Emacron /emacron /Ebreve /ebreve /Edotaccent /edotaccent /Eogonek /eogonek /Ecaron /ecaron\n" +" /Gcircumflex /gcircumflex /Gbreve /gbreve /Gdotaccent /gdotaccent /Gcommaaccent /gcommaaccent \n" +" /Hcircumflex /hcircumflex /Hbar /hbar \n" +" /Itilde /itilde /Imacron /imacron /Ibreve /ibreve /Iogonek /iogonek /Idotaccent /dotlessi \n" +" /IJ /ij /Jcircumflex /jcircumflex\n" +" /Kcommaaccent /kcommaaccent /kgreenlandic \n" +" /Lacute /lacute /Lcommaaccent /lcommaaccent /Lcaron /lcaron /Ldotaccent /ldotaccent /Lslash /lslash \n" +" /Nacute /nacute /Ncommaaccent /ncommaaccent /Ncaron /ncaron /napostrophe /Eng /eng \n" +" /Omacron /omacron /Obreve /obreve /Ohungarumlaut /ohungarumlaut /OE /oe \n" +" /Racute /racute /Rcommaaccent /rcommaaccent /Rcaron /rcaron \n" +" /Sacute /sacute /Scircumflex /scircumflex /Scedilla /scedilla /Scaron /scaron \n" +" /Tcommaaccent /tcommaaccent /Tcaron /tcaron /Tbar /tbar \n" +" /Utilde /utilde /Umacron /umacron /Ubreve /ubreve /Uring /uring /Uhungarumlaut /uhungarumlaut /Uogonek /uogonek \n" +" /Wcircumflex /wcircumflex /Ycircumflex /ycircumflex /Ydieresis \n" +" /Zacute /zacute /Zdotaccent /zdotaccent /Zcaron /zcaron \n" +" /longs \n" // end of Latin Extended-A code page +" /florin /circumflex /caron /breve /dotaccent /ring \n" // remaining characters from PostScript standard text fonts +" /ogonek /tilde /hungarumlaut /endash /emdash \n" +" /quoteleft /quoteright /quotesinglbase /quotedblleft /quotedblright \n" +" /quotedblbase /dagger /daggerdbl /bullet /ellipsis \n" +" /perthousand /guilsinglleft /guilsinglright /fraction /Euro \n" +" /trademark /partialdiff /Delta /summation /radical \n" +" /infinity /notequal /lessequal /greaterequal /lozenge \n" +" /fi /fl /apple \n" +" ] def \n" +// deal with alternative PostScript names of some characters +" /mycharstrings /Helvetica findfont /CharStrings get def\n" +" /PSname2 { dup mycharstrings exch known {LatinExtA 3 -1 roll 3 -1 roll put}{pop pop} ifelse } def \n" +" 16#20 /Gdot PSname2 16#21 /gdot PSname2 16#30 /Idot PSname2 16#3F /Ldot PSname2 16#40 /ldot PSname2 16#7F /slong PSname2 \n" + +// proc that gives LatinExtA encoding to a font +"/ToLatinExtA { findfont dup length dict copy begin /Encoding LatinExtA def currentdict end definefont pop } def\n" +// create Ext-versions of standard fonts that use LatinExtA encoding \n" +"/HelveticaExt /Helvetica ToLatinExtA \n" +"/Helvetica-BoldExt /Helvetica-Bold ToLatinExtA /Helvetica-ObliqueExt /Helvetica-Oblique ToLatinExtA \n" +"/Helvetica-BoldObliqueExt /Helvetica-BoldOblique ToLatinExtA \n" +"/CourierExt /Courier ToLatinExtA /Courier-BoldExt /Courier-Bold ToLatinExtA \n" +"/Courier-ObliqueExt /Courier-Oblique ToLatinExtA /Courier-BoldObliqueExt /Courier-BoldOblique ToLatinExtA \n" +"/Times-RomanExt /Times-Roman ToLatinExtA /Times-BoldExt /Times-Bold ToLatinExtA \n" +"/Times-ItalicExt /Times-Italic ToLatinExtA /Times-BoldItalicExt /Times-BoldItalic ToLatinExtA \n" + +// proc to create a Type 0 font with 2-byte encoding +// that merges a text font with ISO encoding + same font with LatinExtA encoding +"/To2byte { 6 dict begin /FontType 0 def \n" +"/FDepVector 3 1 roll findfont exch findfont 2 array astore def \n" +"/FontMatrix [1 0 0 1 0 0] def /FMapType 6 def /Encoding [ 0 1 0 ] def\n" +// 100: Hexa count of ISO array; A7: hexa count of LatinExtA array +"/SubsVector < 01 0100 00A7 > def\n" +"currentdict end definefont pop } def\n" +// create Type 0 versions of standard fonts +"/Helvetica2B /HelveticaExt /Helvetica To2byte \n" +"/Helvetica-Bold2B /Helvetica-BoldExt /Helvetica-Bold To2byte \n" +"/Helvetica-Oblique2B /Helvetica-ObliqueExt /Helvetica-Oblique To2byte \n" +"/Helvetica-BoldOblique2B /Helvetica-BoldObliqueExt /Helvetica-BoldOblique To2byte \n" +"/Courier2B /CourierExt /Courier To2byte \n" +"/Courier-Bold2B /Courier-BoldExt /Courier-Bold To2byte \n" +"/Courier-Oblique2B /Courier-ObliqueExt /Courier-Oblique To2byte \n" +"/Courier-BoldOblique2B /Courier-BoldObliqueExt /Courier-BoldOblique To2byte \n" +"/Times-Roman2B /Times-RomanExt /Times-Roman To2byte \n" +"/Times-Bold2B /Times-BoldExt /Times-Bold To2byte \n" +"/Times-Italic2B /Times-ItalicExt /Times-Italic To2byte \n" +"/Times-BoldItalic2B /Times-BoldItalicExt /Times-BoldItalic To2byte \n" +; + +static const char * prolog_2_pixmap = // prolog relevant only if lang_level == 2 for pixmaps/masked color images +"/pixmap_mat {[ pixmap_sx 0 0 pixmap_sy neg 0 pixmap_sy ]} bind def\n" + +"/pixmap_dict {" +"<< /PatternType 1 " +"/PaintType 1 " +"/TilingType 2 " +"/BBox [0 0 pixmap_sx pixmap_sy] " +"/XStep pixmap_sx " +"/YStep pixmap_sy\n" +"/PaintProc " +"{ begin " +"pixmap_w pixmap_h scale " +"pixmap_sx pixmap_sy 8 " +"pixmap_mat " +"currentfile /ASCIIHexDecode filter " +"false 3 " +"colorimage " +"end " +"} bind " +">>\n" +"} bind def\n" + +"/pixmap_plot {" +"GS " +"/pixmap_sy exch def /pixmap_sx exch def\n" +"/pixmap_h exch def /pixmap_w exch def\n" +"translate\n" +"pixmap_dict matrix makepattern setpattern\n" +"pixmap_w pixmap_h scale\n" +"pixmap_sx pixmap_sy\n" +"true\n" +"pixmap_mat\n" +"currentfile /ASCIIHexDecode filter\n" +"imagemask\n" +"GR\n" +"} bind def\n" +; + +static const char * prolog_3 = // prolog relevant only if lang_level >2 + +// masked color images +"/CIM {GS /inter exch def /my exch def /mx exch def /py exch def /px exch def /sy exch def /sx exch def \n" +"translate \n" +"sx sy scale\n" +"/DeviceRGB setcolorspace\n" + +"/IDD 8 dict def\n" + +"IDD begin\n" +"/ImageType 1 def\n" +"/Width px def\n" +"/Height py def\n" +"/BitsPerComponent 8 def\n" +"/Interpolate inter def\n" +"/DataSource currentfile /ASCIIHexDecode filter def\n" +"/MultipleDataSources false def\n" +"/ImageMatrix [ px 0 0 py neg 0 py ] def\n" + +"/Decode [ 0 1 0 1 0 1 ] def\n" +"end\n" + +"/IMD 8 dict def\n" +"IMD begin\n" +"/ImageType 1 def\n" +"/Width mx def\n" +"/Height my def\n" +"/BitsPerComponent 1 def\n" +// "/Interpolate inter def\n" +"/ImageMatrix [ mx 0 0 my neg 0 my ] def\n" +"/Decode [ 1 0 ] def\n" +"end\n" + +"<<\n" +"/ImageType 3\n" +"/InterleaveType 2\n" +"/MaskDict IMD\n" +"/DataDict IDD\n" +">> image GR\n" +"} bind def\n" + + +// masked gray images +"/GIM {GS /inter exch def /my exch def /mx exch def /py exch def /px exch def /sy exch def /sx exch def \n" +"translate \n" +"sx sy scale\n" +"/DeviceGray setcolorspace\n" + +"/IDD 8 dict def\n" + +"IDD begin\n" +"/ImageType 1 def\n" +"/Width px def\n" +"/Height py def\n" +"/BitsPerComponent 8 def\n" +"/Interpolate inter def\n" +"/DataSource currentfile /ASCIIHexDecode filter def\n" +"/MultipleDataSources false def\n" +"/ImageMatrix [ px 0 0 py neg 0 py ] def\n" + +"/Decode [ 0 1 ] def\n" +"end\n" + +"/IMD 8 dict def\n" + +"IMD begin\n" +"/ImageType 1 def\n" +"/Width mx def\n" +"/Height my def\n" +"/BitsPerComponent 1 def\n" +"/ImageMatrix [ mx 0 0 my neg 0 my ] def\n" +"/Decode [ 1 0 ] def\n" +"end\n" + +"<<\n" +"/ImageType 3\n" +"/InterleaveType 2\n" +"/MaskDict IMD\n" +"/DataDict IDD\n" +">> image GR\n" +"} bind def\n" + + +"\n" +; + +// end prolog + +int Fl_PostScript_Graphics_Driver::start_postscript (int pagecount, enum Fl_PostScript_Graphics_Driver::Page_Format format, enum Fl_PostScript_Graphics_Driver::Page_Layout layout) +//returns 0 iff OK +{ + int w, h, x; + if (format == A4) { + left_margin = 18; + top_margin = 18; + } + else { + left_margin = 12; + top_margin = 12; + } + page_format_ = (enum Page_Format)(format | layout); + + fputs("%!PS-Adobe-3.0\n", output); + fputs("%%Creator: FLTK\n", output); + if (lang_level_>1) + fprintf(output, "%%%%LanguageLevel: %i\n" , lang_level_); + if ((pages_ = pagecount)) + fprintf(output, "%%%%Pages: %i\n", pagecount); + else + fputs("%%Pages: (atend)\n", output); + fprintf(output, "%%%%BeginFeature: *PageSize %s\n", page_formats[format].name ); + w = page_formats[format].width; + h = page_formats[format].height; + if (lang_level_ == 3 && (layout & LANDSCAPE) ) { x = w; w = h; h = x; } + fprintf(output, "<>setpagedevice\n", w, h ); + fputs("%%EndFeature\n", output); + fputs("%%EndComments\n", output); + fputs(prolog, output); + if (lang_level_ > 1) { + fputs(prolog_2, output); + } + if (lang_level_ == 2) { + fputs(prolog_2_pixmap, output); + } + if (lang_level_ > 2) + fputs(prolog_3, output); + if (lang_level_ >= 3) { + fputs("/CS { clipsave } bind def\n", output); + fputs("/CR { cliprestore } bind def\n", output); + } else { + fputs("/CS { GS } bind def\n", output); + fputs("/CR { GR } bind def\n", output); + } + page_policy_ = 1; + + + fputs("%%EndProlog\n",output); + if (lang_level_ >= 2) + fprintf(output,"<< /Policies << /Pagesize 1 >> >> setpagedevice\n"); + + reset(); + nPages=0; + return 0; +} + +void Fl_PostScript_Graphics_Driver::recover(){ + color(cr_,cg_,cb_); + line_style(linestyle_,linewidth_,linedash_); + font(font_,size_); +} + +void Fl_PostScript_Graphics_Driver::reset(){ + gap_=1; + clip_=0; + cr_=cg_=cb_=0; + font_=FL_HELVETICA; + size_=12; + linewidth_=0; + linestyle_=FL_SOLID; + strcpy(linedash_,""); + Clip *c=clip_; ////just not to have memory leaks for badly writen code (forgotten clip popping) + + while(c){ + clip_=clip_->prev; + delete c; + c=clip_; + } + +} + +void Fl_PostScript_Graphics_Driver::page_policy(int p){ + page_policy_ = p; + if(lang_level_>=2) + fprintf(output,"<< /Policies << /Pagesize %i >> >> setpagedevice\n", p); +} + +// //////////////////// paging ////////////////////////////////////////// + + + +void Fl_PostScript_Graphics_Driver::page(double pw, double ph, int media) { + + if (nPages){ + fprintf(output, "CR\nGR\nGR\nGR\nSP\nrestore\n"); + } + ++nPages; + fprintf(output, "%%%%Page: %i %i\n" , nPages , nPages); + if (pw>ph){ + fprintf(output, "%%%%PageOrientation: Landscape\n"); + }else{ + fprintf(output, "%%%%PageOrientation: Portrait\n"); + } + + fprintf(output, "%%%%BeginPageSetup\n"); + if((media & MEDIA) &&(lang_level_>1)){ + int r = media & REVERSED; + if(r) r = 2; + fprintf(output, "<< /PageSize [%i %i] /Orientation %i>> setpagedevice\n", (int)(pw+.5), (int)(ph+.5), r); + } + fprintf(output, "%%%%EndPageSetup\n"); + + pw_ = pw; + ph_ = ph; + reset(); + + fprintf(output, "save\n"); + fprintf(output, "GS\n"); + fprintf(output, "%g %g TR\n", (double)0 /*lm_*/ , ph_ /* - tm_*/); + fprintf(output, "1 -1 SC\n"); + line_style(0); + fprintf(output, "GS\n"); + + if (!((media & MEDIA) &&(lang_level_>1))){ + if (pw > ph) { + if(media & REVERSED) { + fprintf(output, "-90 rotate %i 0 translate\n", int(-pw)); + } + else { + fprintf(output, "90 rotate -%i -%i translate\n", (lang_level_ == 2 ? int(pw - ph) : 0), int(ph)); + } + } + else { + if(media & REVERSED) + fprintf(output, "180 rotate %i %i translate\n", int(-pw), int(-ph)); + } + } + fprintf(output, "GS\nCS\n"); +} + +void Fl_PostScript_Graphics_Driver::page(int format){ + + + if(format & LANDSCAPE){ + ph_=Fl_PostScript_Graphics_Driver::page_formats[format & 0xFF].width; + pw_=Fl_PostScript_Graphics_Driver::page_formats[format & 0xFF].height; + }else{ + pw_=Fl_PostScript_Graphics_Driver::page_formats[format & 0xFF].width; + ph_=Fl_PostScript_Graphics_Driver::page_formats[format & 0xFF].height; + } + page(pw_,ph_,format & 0xFF00);//,orientation only; +} + +void Fl_PostScript_Graphics_Driver::rect(int x, int y, int w, int h) { + // Commented code does not work, i can't find the bug ;-( + // fprintf(output, "GS\n"); + // fprintf(output, "%i, %i, %i, %i R\n", x , y , w, h); + // fprintf(output, "GR\n"); + fprintf(output, "GS\n"); + fprintf(output,"BP\n"); + fprintf(output, "%i %i MT\n", x , y); + fprintf(output, "%i %i LT\n", x+w-1 , y); + fprintf(output, "%i %i LT\n", x+w-1 , y+h-1); + fprintf(output, "%i %i LT\n", x , y+h-1); + fprintf(output, "ECP\n"); + fprintf(output, "GR\n"); +} + +void Fl_PostScript_Graphics_Driver::rectf(int x, int y, int w, int h) { + fprintf(output, "%g %g %i %i FR\n", x-0.5, y-0.5, w, h); +} + +void Fl_PostScript_Graphics_Driver::line(int x1, int y1, int x2, int y2) { + fprintf(output, "GS\n"); + fprintf(output, "%i %i %i %i L\n", x1 , y1, x2 ,y2); + fprintf(output, "GR\n"); +} + +void Fl_PostScript_Graphics_Driver::line(int x0, int y0, int x1, int y1, int x2, int y2) { + fprintf(output, "GS\n"); + fprintf(output,"BP\n"); + fprintf(output, "%i %i MT\n", x0 , y0); + fprintf(output, "%i %i LT\n", x1 , y1); + fprintf(output, "%i %i LT\n", x2 , y2); + fprintf(output, "ELP\n"); + fprintf(output, "GR\n"); +} + +void Fl_PostScript_Graphics_Driver::xyline(int x, int y, int x1, int y2, int x3){ + fprintf(output, "GS\n"); + fprintf(output,"BP\n"); + fprintf(output, "%i %i MT\n", x , y ); + fprintf(output, "%i %i LT\n", x1 , y ); + fprintf(output, "%i %i LT\n", x1 , y2); + fprintf(output,"%i %i LT\n", x3 , y2); + fprintf(output, "ELP\n"); + fprintf(output, "GR\n"); +} + + +void Fl_PostScript_Graphics_Driver::xyline(int x, int y, int x1, int y2){ + + fprintf(output, "GS\n"); + fprintf(output,"BP\n"); + fprintf(output, "%i %i MT\n", x , y); + fprintf(output,"%i %i LT\n", x1 , y); + fprintf(output, "%i %i LT\n", x1 , y2 ); + fprintf(output, "ELP\n"); + fprintf(output, "GR\n"); +} + +void Fl_PostScript_Graphics_Driver::xyline(int x, int y, int x1){ + fprintf(output, "GS\n"); + fprintf(output,"BP\n"); + fprintf(output, "%i %i MT\n", x , y); + fprintf(output, "%i %i LT\n", x1 , y ); + fprintf(output, "ELP\n"); + + fprintf(output, "GR\n"); +} + +void Fl_PostScript_Graphics_Driver::yxline(int x, int y, int y1, int x2, int y3){ + fprintf(output, "GS\n"); + + fprintf(output,"BP\n"); + fprintf(output,"%i %i MT\n", x , y); + fprintf(output, "%i %i LT\n", x , y1 ); + fprintf(output, "%i %i LT\n", x2 , y1 ); + fprintf(output , "%i %i LT\n", x2 , y3); + fprintf(output, "ELP\n"); + fprintf(output, "GR\n"); +} + +void Fl_PostScript_Graphics_Driver::yxline(int x, int y, int y1, int x2){ + fprintf(output, "GS\n"); + fprintf(output,"BP\n"); + fprintf(output, "%i %i MT\n", x , y); + fprintf(output, "%i %i LT\n", x , y1); + fprintf(output, "%i %i LT\n", x2 , y1); + fprintf(output, "ELP\n"); + fprintf(output, "GR\n"); +} + +void Fl_PostScript_Graphics_Driver::yxline(int x, int y, int y1){ + fprintf(output, "GS\n"); + fprintf(output,"BP\n"); + fprintf(output, "%i %i MT\n", x , y); + fprintf(output, "%i %i LT\n", x , y1); + fprintf(output, "ELP\n"); + fprintf(output, "GR\n"); +} + +void Fl_PostScript_Graphics_Driver::loop(int x0, int y0, int x1, int y1, int x2, int y2) { + fprintf(output, "GS\n"); + fprintf(output,"BP\n"); + fprintf(output, "%i %i MT\n", x0 , y0); + fprintf(output, "%i %i LT\n", x1 , y1); + fprintf(output, "%i %i LT\n", x2 , y2); + fprintf(output, "ECP\n"); + fprintf(output, "GR\n"); +} + +void Fl_PostScript_Graphics_Driver::loop(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3) { + fprintf(output, "GS\n"); + fprintf(output,"BP\n"); + fprintf(output, "%i %i MT\n", x0 , y0); + fprintf(output, "%i %i LT\n", x1 , y1); + fprintf(output, "%i %i LT\n", x2 , y2); + fprintf(output, "%i %i LT\n", x3 , y3); + fprintf(output, "ECP\n"); + fprintf(output, "GR\n"); +} + +void Fl_PostScript_Graphics_Driver::polygon(int x0, int y0, int x1, int y1, int x2, int y2) { + fprintf(output, "GS\n"); + fprintf(output,"BP\n"); + fprintf(output, "%i %i MT\n", x0 , y0); + fprintf(output,"%i %i LT\n", x1 , y1); + fprintf(output, "%i %i LT\n", x2 , y2); + fprintf(output, "EFP\n"); + fprintf(output, "GR\n"); +} + +void Fl_PostScript_Graphics_Driver::polygon(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3) { + fprintf(output, "GS\n"); + fprintf(output,"BP\n"); + fprintf(output, "%i %i MT\n", x0 , y0 ); + fprintf(output, "%i %i LT\n", x1 , y1 ); + fprintf(output, "%i %i LT\n", x2 , y2 ); + fprintf(output, "%i %i LT\n", x3 , y3 ); + + fprintf(output, "EFP\n"); + fprintf(output, "GR\n"); +} + +void Fl_PostScript_Graphics_Driver::point(int x, int y){ + rectf(x,y,1,1); +} + +static int dashes_flat[5][7]={ +{-1,0,0,0,0,0,0}, +{3,1,-1,0,0,0,0}, +{1,1,-1,0,0,0,0}, +{3,1,1,1,-1,0,0}, +{3,1,1,1,1,1,-1} +}; + + +//yeah, hack... +static double dashes_cap[5][7]={ +{-1,0,0,0,0,0,0}, +{2,2,-1,0,0,0,0}, +{0.01,1.99,-1,0,0,0,0}, +{2,2,0.01,1.99,-1,0,0}, +{2,2,0.01,1.99,0.01,1.99,-1} +}; + + +void Fl_PostScript_Graphics_Driver::line_style(int style, int width, char* dashes){ + //line_styled_=1; + + linewidth_=width; + linestyle_=style; + //dashes_= dashes; + if(dashes){ + if(dashes != linedash_) + strcpy(linedash_,dashes); + + }else + linedash_[0]=0; + char width0 = 0; + if(!width){ + width=1; //for screen drawing compatability + width0=1; + } + + fprintf(output, "%i setlinewidth\n", width); + + if(!style && (!dashes || !(*dashes)) && width0) //system lines + style = FL_CAP_SQUARE; + + int cap = (style &0xf00) >> 8; + if(cap) cap--; + fprintf(output,"%i setlinecap\n", cap); + + int join = (style & 0xf000) >> 12; + + if(join) join--; + fprintf(output,"%i setlinejoin\n", join); + + + fprintf(output, "["); + if(dashes && *dashes){ + while(*dashes){ + fprintf(output, "%i ", *dashes); + dashes++; + } + }else{ + int * ds; + if(style & 0x200){ // round and square caps, dash length need to be adjusted + double *dt = dashes_cap[style & 0xff]; + while (*dt >= 0){ + fprintf(output, "%g ",width * (*dt)); + dt++; + } + }else{ + + ds = dashes_flat[style & 0xff]; + while (*ds >= 0){ + fprintf(output, "%i ",width * (*ds)); + ds++; + } + } + } + fprintf(output, "] 0 setdash\n"); +} + +static const char *_fontNames[] = { +"Helvetica2B", +"Helvetica-Bold2B", +"Helvetica-Oblique2B", +"Helvetica-BoldOblique2B", +"Courier2B", +"Courier-Bold2B", +"Courier-Oblique2B", +"Courier-BoldOblique2B", +"Times-Roman2B", +"Times-Bold2B", +"Times-Italic2B", +"Times-BoldItalic2B", +"Symbol", +"Courier2B", +"Courier-Bold2B", +"ZapfDingbats" +}; + +void Fl_PostScript_Graphics_Driver::font(int f, int s) { + if (f >= FL_FREE_FONT) + f = FL_COURIER; + fprintf(output, "/%s SF\n" , _fontNames[f]); + fprintf(output,"%i FS\n", s); + Fl_Display_Device::display_device()->driver()->font(f,s); // Use display fonts for font measurement + font_ = f; size_ = s; +} + +void Fl_PostScript_Graphics_Driver::color(Fl_Color c) { + Fl::get_color(c, cr_, cg_, cb_); + color(cr_, cg_, cb_); +} + +void Fl_PostScript_Graphics_Driver::color(unsigned char r, unsigned char g, unsigned char b) { + fl_color_ = fl_rgb_color(r, g, b); + cr_ = r; cg_ = g; cb_ = b; + if (r == g && g == b) { + double gray = r/255.0; + fprintf(output, "%g GL\n", gray); + } else { + double fr, fg, fb; + fr = r/255.0; + fg = g/255.0; + fb = b/255.0; + fprintf(output, "%g %g %g SRGB\n", fr , fg , fb); + } +} + +void Fl_PostScript_Graphics_Driver::draw(int angle, const char *str, int n, int x, int y) +{ + fprintf(output, "GS %d %d translate %d rotate\n", x, y, - angle); + this->transformed_draw(str, n, 0, 0); + fprintf(output, "GR\n"); +} + + +// computes the mask for the RGB image img of all pixels with color != bg +static uchar *calc_mask(uchar *img, int w, int h, Fl_Color bg) +{ + uchar red, green, blue, r, g, b; + uchar bit, byte, *q; + Fl::get_color(bg, red, green, blue); + int W = (w+7)/8; // width of mask + uchar* mask = new uchar[W * h]; + q = mask; + while (h-- > 0) { // for each row + bit = 0x80; // byte with last bit set + byte = 0; // next mask byte to compute + for (int j = 0; j < w; j++) { // for each column + r = *img++; // the pixel color components + g = *img++; + b = *img++; + // if pixel doesn't have bg color, put it in mask + if (r != red || g != green || b != blue) byte |= bit; + bit = bit>>1; // shift bit one step to the right + if (bit == 0) { // single set bit has fallen out + *q++ = byte; // enter byte in mask + byte = 0; // reset next mask byte to zero + bit = 0x80; // and this byte + } + } + if (bit != 0x80) *q++ = byte; // enter last columns' byte in mask + } + return mask; +} + +// write to PostScript a bitmap image of a UTF8 string +static void transformed_draw_extra(const char* str, int n, double x, double y, int w, FILE *output) { + const float scale = 3; // scale for bitmask computation + Fl_Fontsize old_size = fl_size(); + fl_font(fl_font(), (Fl_Fontsize)(scale * old_size) ); + w = (int)(w *scale + 0.5); + int h = fl_height(); + // create an offscreen image of the string + Fl_Color text_color = fl_color(); + Fl_Color bg_color = fl_contrast(FL_WHITE, text_color); + Fl_Offscreen off = fl_create_offscreen(w+2, (int)(h+3*scale) ); + fl_begin_offscreen(off); + fl_color(bg_color); + // color offscreen background with a shade contrasting with the text color + fl_rectf(0, 0, w+2, (int)(h+3*scale) ); + fl_color(text_color); + fl_draw(str, n, 1, (int)(h * 0.8) ); // draw string in offscreen + // read (most of) the offscreen image + uchar *img = fl_read_image(NULL, 1, 1, w, h, 0); + fl_end_offscreen(); + fl_font(fl_font(), old_size); + fl_delete_offscreen(off); + // compute the mask of what is not the background + uchar *mask = calc_mask(img, w, h, bg_color); + delete img; + // write the string image to PostScript as a scaled bitmask + fprintf(output, "%g %g %g %g %d %d MI\n", x, y - h*0.77/scale, w/scale, h/scale, w, h); + uchar *di; + int wmask = (w+7)/8; + for (int j = h - 1; j >= 0; j--){ + di = mask + j * wmask; + for (int i = 0; i < wmask; i++){ + //if (!(i%80)) fprintf(output, "\n"); // don't have lines longer than 255 chars + fprintf(output, "%2.2x", *di ); + di++; + } + fprintf(output,"\n"); + } + fprintf(output,">\n"); + delete mask; +} + +static int is_in_table(unsigned utf) { + unsigned i; + static unsigned extra_table_roman[] = { // unicodes/*names*/ of other characters from PostScript standard fonts + 0x192/*florin*/, 0x2C6/*circumflex*/, 0x2C7/*caron*/, + 0x2D8/*breve*/, 0x2D9/*dotaccent*/, 0x2DA/*ring*/, 0x2DB/*ogonek*/, 0x2DC/*tilde*/, 0x2DD/*hungarumlaut*/, + 0x2013/*endash*/, 0x2014/*emdash*/, 0x2018/*quoteleft*/, 0x2019/*quoteright*/, + 0x201A/*quotesinglbase*/, 0x201C/*quotedblleft*/, 0x201D/*quotedblright*/, 0x201E/*quotedblbase*/, + 0x2020/*dagger*/, 0x2021/*daggerdbl*/, 0x2022/*bullet*/, + 0x2026/*ellipsis*/, 0x2030/*perthousand*/, 0x2039/*guilsinglleft*/, 0x203A/*guilsinglright*/, + 0x2044/*fraction*/, 0x20AC/*Euro*/, 0x2122/*trademark*/, + 0x2202/*partialdiff*/, 0x2206/*Delta*/, 0x2211/*summation*/, 0x221A/*radical*/, + 0x221E/*infinity*/, 0x2260/*notequal*/, 0x2264/*lessequal*/, + 0x2265/*greaterequal*/, + 0x25CA/*lozenge*/, 0xFB01/*fi*/, 0xFB02/*fl*/, + 0xF8FF/*apple*/ + }; + for ( i = 0; i < sizeof(extra_table_roman)/sizeof(int); i++) { + if (extra_table_roman[i] == utf) return i + 0x180; + } + return 0; +} + +// outputs in PostScript a UTF8 string using the same width in points as on display +void Fl_PostScript_Graphics_Driver::transformed_draw(const char* str, int n, double x, double y) { + int len, code; + if (!n || !str || !*str) return; + // compute display width of string + int width = (int)fl_width(str, n); + if (width == 0) return; + fprintf(output, "%d <", width); + // transforms UTF8 encoding to our custom PostScript encoding as follows: + // extract each unicode character + // if unicode <= 0x17F, unicode and PostScript codes are identical + // if unicode is one of the values listed in extra_table_roman above + // its PostScript code is 0x180 + the character's rank in extra_table_roman + // if unicode is something else, draw all string as bitmap image + + const char *last = str + n; + const char *str2 = str; + while (str2 < last) { + // Extract each unicode character of string. + unsigned utf = fl_utf8decode(str2, last, &len); + str2 += len; + if (utf <= 0x17F) { // until Latin Extended-A + ; + } + else if ( (code = is_in_table(utf)) != 0) { // other handled characters + utf = code; + } + else { // unhandled character: draw all string as bitmap image + fprintf(output, "> pop pop\n"); // close and ignore the opened hex string + transformed_draw_extra(str, n, x, y, width, output); + return; + } + fprintf(output, "%4.4X", utf); + } + fprintf(output, "> %g %g show_pos_width\n", x, y); +} + +struct matrix {double a, b, c, d, x, y;}; +extern matrix * fl_matrix; + +void Fl_PostScript_Graphics_Driver::concat(){ + fprintf(output,"[%g %g %g %g %g %g] CT\n", fl_matrix->a , fl_matrix->b , fl_matrix->c , fl_matrix->d , fl_matrix->x , fl_matrix->y); +} + +void Fl_PostScript_Graphics_Driver::reconcat(){ + fprintf(output, "[%g %g %g %g %g %g] RCT\n" , fl_matrix->a , fl_matrix->b , fl_matrix->c , fl_matrix->d , fl_matrix->x , fl_matrix->y); +} + +///////////////// transformed (double) drawings //////////////////////////////// + + +void Fl_PostScript_Graphics_Driver::begin_points(){ + fprintf(output, "GS\n"); + concat(); + + fprintf(output, "BP\n"); + gap_=1; + shape_=POINTS; +} + +void Fl_PostScript_Graphics_Driver::begin_line(){ + fprintf(output, "GS\n"); + concat(); + fprintf(output, "BP\n"); + gap_=1; + shape_=LINE; +} + +void Fl_PostScript_Graphics_Driver::begin_loop(){ + fprintf(output, "GS\n"); + concat(); + fprintf(output, "BP\n"); + gap_=1; + shape_=LOOP; +} + +void Fl_PostScript_Graphics_Driver::begin_polygon(){ + fprintf(output, "GS\n"); + concat(); + fprintf(output, "BP\n"); + gap_=1; + shape_=POLYGON; +} + +void Fl_PostScript_Graphics_Driver::vertex(double x, double y){ + if(shape_==POINTS){ + fprintf(output,"%g %g MT\n", x , y); + gap_=1; + return; + } + if(gap_){ + fprintf(output,"%g %g MT\n", x , y); + gap_=0; + }else + fprintf(output, "%g %g LT\n", x , y); +} + +void Fl_PostScript_Graphics_Driver::curve(double x, double y, double x1, double y1, double x2, double y2, double x3, double y3){ + if(shape_==NONE) return; + if(gap_) + fprintf(output,"%g %g MT\n", x , y); + else + fprintf(output, "%g %g LT\n", x , y); + gap_=0; + + fprintf(output, "%g %g %g %g %g %g curveto \n", x1 , y1 , x2 , y2 , x3 , y3); +} + + +void Fl_PostScript_Graphics_Driver::circle(double x, double y, double r){ + if(shape_==NONE){ + fprintf(output, "GS\n"); + concat(); + // fprintf(output, "BP\n"); + fprintf(output,"%g %g %g 0 360 arc\n", x , y , r); + reconcat(); + // fprintf(output, "ELP\n"); + fprintf(output, "GR\n"); + }else + + fprintf(output, "%g %g %g 0 360 arc\n", x , y , r); + +} + +void Fl_PostScript_Graphics_Driver::arc(double x, double y, double r, double start, double a){ + if(shape_==NONE) return; + gap_=0; + if(start>a) + fprintf(output, "%g %g %g %g %g arc\n", x , y , r , -start, -a); + else + fprintf(output, "%g %g %g %g %g arcn\n", x , y , r , -start, -a); + +} + +void Fl_PostScript_Graphics_Driver::arc(int x, int y, int w, int h, double a1, double a2) { + fprintf(output, "GS\n"); + //fprintf(output, "BP\n"); + begin_line(); + fprintf(output, "%g %g TR\n", x + w/2.0 -0.5 , y + h/2.0 - 0.5); + fprintf(output, "%g %g SC\n", (w-1)/2.0 , (h-1)/2.0 ); + arc(0,0,1,a2,a1); + // fprintf(output, "0 0 1 %g %g arc\n" , -a1 , -a2); + fprintf(output, "%g %g SC\n", 2.0/(w-1) , 2.0/(h-1) ); + fprintf(output, "%g %g TR\n", -x - w/2.0 +0.5 , -y - h/2.0 +0.5); + end_line(); + + // fprintf(output, "%g setlinewidth\n", 2/sqrt(w*h)); + // fprintf(output, "ELP\n"); + // fprintf(output, 2.0/w , 2.0/w , " SC\n"; + // fprintf(output, (-x - w/2.0) , (-y - h/2) , " TR\n"; + fprintf(output, "GR\n"); +} + +void Fl_PostScript_Graphics_Driver::pie(int x, int y, int w, int h, double a1, double a2) { + + fprintf(output, "GS\n"); + fprintf(output, "%g %g TR\n", x + w/2.0 -0.5 , y + h/2.0 - 0.5); + fprintf(output, "%g %g SC\n", (w-1)/2.0 , (h-1)/2.0 ); + begin_polygon(); + vertex(0,0); + arc(0.0,0.0, 1, a2, a1); + end_polygon(); + fprintf(output, "GR\n"); +} + +void Fl_PostScript_Graphics_Driver::end_points(){ + gap_=1; + reconcat(); + fprintf(output, "ELP\n"); //?? + fprintf(output, "GR\n"); + shape_=NONE; +} + +void Fl_PostScript_Graphics_Driver::end_line(){ + gap_=1; + reconcat(); + fprintf(output, "ELP\n"); + fprintf(output, "GR\n"); + shape_=NONE; +} +void Fl_PostScript_Graphics_Driver::end_loop(){ + gap_=1; + reconcat(); + fprintf(output, "ECP\n"); + fprintf(output, "GR\n"); + shape_=NONE; +} + +void Fl_PostScript_Graphics_Driver::end_polygon(){ + + gap_=1; + reconcat(); + fprintf(output, "EFP\n"); + fprintf(output, "GR\n"); + shape_=NONE; +} + +void Fl_PostScript_Graphics_Driver::transformed_vertex(double x, double y){ + reconcat(); + if(gap_){ + fprintf(output, "%g %g MT\n", x , y); + gap_=0; + }else + fprintf(output, "%g %g LT\n", x , y); + concat(); +} + +///////////////////////////// Clipping ///////////////////////////////////////////// + +void Fl_PostScript_Graphics_Driver::push_clip(int x, int y, int w, int h) { + Clip * c=new Clip(); + clip_box(x,y,w,h,c->x,c->y,c->w,c->h); + c->prev=clip_; + clip_=c; + fprintf(output, "CR\nCS\n"); + if(lang_level_<3) + recover(); + fprintf(output, "%g %g %i %i CL\n", clip_->x-0.5 , clip_->y-0.5 , clip_->w , clip_->h); + +} + +void Fl_PostScript_Graphics_Driver::push_no_clip() { + Clip * c = new Clip(); + c->prev=clip_; + clip_=c; + clip_->x = clip_->y = clip_->w = clip_->h = -1; + fprintf(output, "CR\nCS\n"); + if(lang_level_<3) + recover(); +} + +void Fl_PostScript_Graphics_Driver::pop_clip() { + if(!clip_)return; + Clip * c=clip_; + clip_=clip_->prev; + delete c; + fprintf(output, "CR\nCS\n"); + if(clip_ && clip_->w >0) + fprintf(output, "%g %g %i %i CL\n", clip_->x - 0.5, clip_->y - 0.5, clip_->w , clip_->h); + // uh, -0.5 is to match screen clipping, for floats there should be something beter + if(lang_level_<3) + recover(); +} + +int Fl_PostScript_Graphics_Driver::clip_box(int x, int y, int w, int h, int &X, int &Y, int &W, int &H){ + if(!clip_){ + X=x;Y=y;W=w;H=h; + return 1; + } + if(clip_->w < 0){ + X=x;Y=y;W=w;H=h; + return 1; + } + int ret=0; + if (x > (X=clip_->x)) {X=x; ret=1;} + if (y > (Y=clip_->y)) {Y=y; ret=1;} + if ((x+w) < (clip_->x+clip_->w)) { + W=x+w-X; + + ret=1; + + }else + W = clip_->x + clip_->w - X; + if(W<0){ + W=0; + return 1; + } + if ((y+h) < (clip_->y+clip_->h)) { + H=y+h-Y; + ret=1; + }else + H = clip_->y + clip_->h - Y; + if(H<0){ + W=0; + H=0; + return 1; + } + return ret; +} + +int Fl_PostScript_Graphics_Driver::not_clipped(int x, int y, int w, int h){ + if(!clip_) return 1; + if(clip_->w < 0) return 1; + int X, Y, W, H; + clip_box(x, y, w, h, X, Y, W, H); + if(W) return 1; + return 0; +} + + +void Fl_PostScript_File_Device::margins(int *left, int *top, int *right, int *bottom) // to implement +{ + Fl_PostScript_Graphics_Driver *ps = driver(); + if(left) *left = (int)(ps->left_margin / ps->scale_x + .5); + if(right) *right = (int)(ps->left_margin / ps->scale_x + .5); + if(top) *top = (int)(ps->top_margin / ps->scale_y + .5); + if(bottom) *bottom = (int)(ps->top_margin / ps->scale_y + .5); +} + +int Fl_PostScript_File_Device::printable_rect(int *w, int *h) +//returns 0 iff OK +{ + Fl_PostScript_Graphics_Driver *ps = driver(); + if(w) *w = (int)((ps->pw_ - 2 * ps->left_margin) / ps->scale_x + .5); + if(h) *h = (int)((ps->ph_ - 2 * ps->top_margin) / ps->scale_y + .5); + return 0; +} + +void Fl_PostScript_File_Device::origin(int x, int y) +{ + x_offset = x; + y_offset = y; + Fl_PostScript_Graphics_Driver *ps = driver(); + fprintf(ps->output, "GR GR GS %d %d TR %f %f SC %d %d TR %f rotate GS\n", + ps->left_margin, ps->top_margin, ps->scale_x, ps->scale_y, x, y, ps->angle); +} + +void Fl_PostScript_File_Device::scale (float s_x, float s_y) +{ + Fl_PostScript_Graphics_Driver *ps = driver(); + ps->scale_x = s_x; + ps->scale_y = s_y; + fprintf(ps->output, "GR GR GS %d %d TR %f %f SC %f rotate GS\n", + ps->left_margin, ps->top_margin, ps->scale_x, ps->scale_y, ps->angle); +} + +void Fl_PostScript_File_Device::rotate (float rot_angle) +{ + Fl_PostScript_Graphics_Driver *ps = driver(); + ps->angle = - rot_angle; + fprintf(ps->output, "GR GR GS %d %d TR %f %f SC %d %d TR %f rotate GS\n", + ps->left_margin, ps->top_margin, ps->scale_x, ps->scale_y, x_offset, y_offset, ps->angle); +} + +void Fl_PostScript_File_Device::translate(int x, int y) +{ + fprintf(driver()->output, "GS %d %d translate GS\n", x, y); +} + +void Fl_PostScript_File_Device::untranslate(void) +{ + fprintf(driver()->output, "GR GR\n"); +} + +int Fl_PostScript_File_Device::start_page (void) +{ + Fl_PostScript_Graphics_Driver *ps = driver(); + ps->page(ps->page_format_); + x_offset = 0; + y_offset = 0; + ps->scale_x = ps->scale_y = 1.; + ps->angle = 0; + fprintf(ps->output, "GR GR GS %d %d translate GS\n", ps->left_margin, ps->top_margin); + return 0; +} + +int Fl_PostScript_File_Device::end_page (void) +{ + return 0; +} + +void Fl_PostScript_File_Device::end_job (void) +// finishes PostScript & closes file +{ + Fl_PostScript_Graphics_Driver *ps = driver(); + if (ps->nPages) { // for eps nPages is 0 so it is fine .... + fprintf(ps->output, "CR\nGR\nGR\nGR\nSP\n restore\n"); + if (!ps->pages_){ + fprintf(ps->output, "%%%%Trailer\n"); + fprintf(ps->output, "%%%%Pages: %i\n" , ps->nPages); + }; + } else + fprintf(ps->output, "GR\n restore\n"); + fputs("%%EOF",ps->output); + ps->reset(); + fflush(ps->output); + if(ferror(ps->output)) { + fl_alert ("Error during PostScript data output."); + } + if (ps->close_cmd_) { + (*ps->close_cmd_)(ps->output); + } else { + fclose(ps->output); + } + while (ps->clip_){ + Fl_PostScript_Graphics_Driver::Clip * c= ps->clip_; + ps->clip_= ps->clip_->prev; + delete c; + } + Fl_Display_Device::display_device()->set_current(); +} + +#if ! (defined(__APPLE__) || defined(WIN32) ) +int Fl_Printer::start_job(int pages, int *firstpage, int *lastpage) { + enum Fl_PostScript_Graphics_Driver::Page_Format format; + enum Fl_PostScript_Graphics_Driver::Page_Layout layout; + + // first test version for print dialog + if (!print_panel) make_print_panel(); + print_load(); + print_selection->deactivate(); + print_all->setonly(); + print_all->do_callback(); + print_from->value("1"); + { char tmp[10]; snprintf(tmp, sizeof(tmp), "%d", pages); print_to->value(tmp); } + print_panel->show(); // this is modal + while (print_panel->shown()) Fl::wait(); + + if (!print_start) // user clicked cancel + return 1; + + // get options + + format = print_page_size->value() ? Fl_PostScript_Graphics_Driver::A4 : Fl_PostScript_Graphics_Driver::LETTER; + { // page range choice + int from = 1, to = pages; + if (print_pages->value()) { + sscanf(print_from->value(), "%d", &from); + sscanf(print_to->value(), "%d", &to); + } + if (from < 1) from = 1; + if (to > pages) to = pages; + if (to < from) to = from; + if (firstpage) *firstpage = from; + if (lastpage) *lastpage = to; + pages = to - from + 1; + } + + if (print_output_mode[0]->value()) layout = Fl_PostScript_Graphics_Driver::PORTRAIT; + else if (print_output_mode[1]->value()) layout = Fl_PostScript_Graphics_Driver::LANDSCAPE; + else if (print_output_mode[2]->value()) layout = Fl_PostScript_Graphics_Driver::PORTRAIT; + else layout = Fl_PostScript_Graphics_Driver::LANDSCAPE; + + int print_pipe = print_choice->value(); // 0 = print to file, >0 = printer (pipe) + + const char *media = print_page_size->text(print_page_size->value()); + const char *printer = (const char *)print_choice->menu()[print_choice->value()].user_data(); + if (!print_pipe) printer = ""; + + if (!print_pipe) // fall back to file printing + return Fl_PostScript_File_Device::start_job (pages, format, layout); + + // Print: pipe the output into the lp command... + + char command[1024]; + snprintf(command, sizeof(command), "lp -s -d %s -n %d -t '%s' -o media=%s", + printer, print_collate_button->value() ? 1 : (int)(print_copies->value() + 0.5), + "FLTK", media); + + Fl_PostScript_Graphics_Driver *ps = driver(); + ps->output = popen(command, "w"); + if (!ps->output) { + fl_alert("could not run command: %s\n",command); + return 1; + } + ps->close_command(pclose); + this->set_current(); + return ps->start_postscript(pages, format, layout); // start printing +} + +#endif // ! (defined(__APPLE__) || defined(WIN32) ) + +#endif // FL_DOXYGEN + +// +// End of "$Id: Fl_PostScript.cxx 7886 2010-11-23 13:05:37Z manolo $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Preferences.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Preferences.cxx new file mode 100644 index 0000000..1f40b0d --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Preferences.cxx @@ -0,0 +1,1974 @@ +// +// "$Id: Fl_Preferences.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Preferences methods for the Fast Light Tool Kit (FLTK). +// +// Copyright 2002-2010 by Matthias Melcher. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include +#include + +#include +#include +#include +#include +#include "flstring.h" +#include +#include + +#if defined(WIN32) && !defined(__CYGWIN__) +# include +# include +# include +// Visual C++ 2005 incorrectly displays a warning about the use of POSIX APIs +// on Windows, which is supposed to be POSIX compliant... +# define access _access +# define mkdir _mkdir +#elif defined (__APPLE__) +# include +# include +# include +#else +# include +# include +#endif + +#ifdef WIN32 +# include +# include +// function pointer for the UuidCreate Function +// RPC_STATUS RPC_ENTRY UuidCreate(UUID __RPC_FAR *Uuid); +typedef RPC_STATUS (WINAPI* uuid_func)(UUID __RPC_FAR *Uuid); +#else +# include +#endif // WIN32 + +#ifdef __CYGWIN__ +# include +#endif + +char Fl_Preferences::nameBuffer[128]; +char Fl_Preferences::uuidBuffer[40]; +Fl_Preferences *Fl_Preferences::runtimePrefs = 0; + +/** + * Returns a UUID as generated by the system. + * + * A UUID is a "universally unique identifier" which is commonly used in + * configuration files to create identities. A UUID in ASCII looks like this: + * 937C4900-51AA-4C11-8DD3-7AB59944F03E. It has always 36 bytes plus + * a trailing zero. + * + * \return a pointer to a static buffer containing the new UUID in ASCII format. + * The buffer is overwritten during every call to this function! + */ +const char *Fl_Preferences::newUUID() +{ +#ifdef __APPLE__ + CFUUIDRef theUUID = CFUUIDCreate(NULL); + CFUUIDBytes b = CFUUIDGetUUIDBytes(theUUID); + sprintf(uuidBuffer, "%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X", + b.byte0, b.byte1, b.byte2, b.byte3, b.byte4, b.byte5, b.byte6, b.byte7, + b.byte8, b.byte9, b.byte10, b.byte11, b.byte12, b.byte13, b.byte14, b.byte15); + CFRelease(theUUID); +#elif defined (WIN32) + // First try and use the win API function UuidCreate(), but if that is not + // available, fall back to making something up from scratch. + // We do not want to link against the Rpcrt4.dll, as we will rarely use it, + // so we load the DLL dynamically, if it is available, and work from there. + static HMODULE hMod = NULL; + UUID ud; + UUID *pu = &ud; + int got_uuid = 0; + + if(!hMod){ // first time in? + hMod = LoadLibrary("Rpcrt4.dll"); + } + + if(hMod){ // do we have a usable handle to Rpcrt4.dll? + uuid_func uuid_crt = (uuid_func)GetProcAddress(hMod, "UuidCreate"); + if(uuid_crt != NULL) { + RPC_STATUS rpc_res = uuid_crt(pu); + if( // is the return status OK for our needs? + (rpc_res == RPC_S_OK) || // all is well + (rpc_res == RPC_S_UUID_LOCAL_ONLY) || // only unique to this machine + (rpc_res == RPC_S_UUID_NO_ADDRESS) // probably only locally unique + ) { + got_uuid = -1; + sprintf(uuidBuffer, "%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X", + pu->Data1, pu->Data2, pu->Data3, pu->Data4[0], pu->Data4[1], + pu->Data4[2], pu->Data4[3], pu->Data4[4], + pu->Data4[5], pu->Data4[6], pu->Data4[7]); + } + } + } + if(got_uuid == 0) { // did not make a UUID - use fallback logic + unsigned char b[16]; + time_t t = time(0); // first 4 byte + b[0] = (unsigned char)t; + b[1] = (unsigned char)(t>>8); + b[2] = (unsigned char)(t>>16); + b[3] = (unsigned char)(t>>24); + int r = rand(); // four more bytes + b[4] = (unsigned char)r; + b[5] = (unsigned char)(r>>8); + b[6] = (unsigned char)(r>>16); + b[7] = (unsigned char)(r>>24); + // Now we try to find 4 more "random" bytes. We extract the + // lower 4 bytes from the address of t - it is created on the + // stack so *might* be in a different place each time... + // This is now done via a union to make it compile OK on 64-bit systems. + union { void *pv; unsigned char a[sizeof(void*)]; } v; + v.pv = (void *)(&t); + // NOTE: This assume that all WinXX systems are little-endian + b[8] = v.a[0]; + b[9] = v.a[1]; + b[10] = v.a[2]; + b[11] = v.a[3]; + TCHAR name[MAX_COMPUTERNAME_LENGTH + 1]; // only used to make last four bytes + DWORD nSize = MAX_COMPUTERNAME_LENGTH + 1; + // GetComputerName() does not depend on any extra libs, and returns something + // analogous to gethostname() + GetComputerName(name, &nSize); + // use the first 4 TCHAR's of the name to create the last 4 bytes of our UUID + for(int ii = 0; ii < 4; ii++){ + b[12 + ii] = (unsigned char)name[ii]; + } + sprintf(uuidBuffer, "%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X", + b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], + b[8], b[9], b[10], b[11], b[12], b[13], b[14], b[15]); + } +#else + // warning Unix implementation of Fl_Preferences::newUUID() incomplete! + // #include + // void uuid_generate(uuid_t out); + unsigned char b[16]; + time_t t = time(0); // first 4 byte + b[0] = (unsigned char)t; + b[1] = (unsigned char)(t>>8); + b[2] = (unsigned char)(t>>16); + b[3] = (unsigned char)(t>>24); + int r = rand(); // four more bytes + b[4] = (unsigned char)r; + b[5] = (unsigned char)(r>>8); + b[6] = (unsigned char)(r>>16); + b[7] = (unsigned char)(r>>24); + unsigned long a = (unsigned long)&t; // four more bytes + b[8] = (unsigned char)a; + b[9] = (unsigned char)(a>>8); + b[10] = (unsigned char)(a>>16); + b[11] = (unsigned char)(a>>24); + // Now we try to find 4 more "random" bytes. We extract the + // lower 4 bytes from the address of t - it is created on the + // stack so *might* be in a different place each time... + // This is now done via a union to make it compile OK on 64-bit systems. + union { void *pv; unsigned char a[sizeof(void*)]; } v; + v.pv = (void *)(&t); + // NOTE: May need to handle big- or little-endian systems here +# if WORDS_BIGENDIAN + b[8] = v.a[sizeof(void*) - 1]; + b[9] = v.a[sizeof(void*) - 2]; + b[10] = v.a[sizeof(void*) - 3]; + b[11] = v.a[sizeof(void*) - 4]; +# else /* data ordered for a little-endian system */ + b[8] = v.a[0]; + b[9] = v.a[1]; + b[10] = v.a[2]; + b[11] = v.a[3]; +# endif + char name[80]; // last four bytes + gethostname(name, 79); + memcpy(b+12, name, 4); + sprintf(uuidBuffer, "%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X", + b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], + b[8], b[9], b[10], b[11], b[12], b[13], b[14], b[15]); +#endif + + return uuidBuffer; +} + + +/** + The constructor creates a group that manages name/value pairs and + child groups. Groups are ready for reading and writing at any time. + The root argument is either Fl_Preferences::USER + or Fl_Preferences::SYSTEM. + + This constructor creates the base instance for all + following entries and reads existing databases into memory. The + vendor argument is a unique text string identifying the + development team or vendor of an application. A domain name or + an EMail address are great unique names, e.g. + "researchATmatthiasm.com" or "fltk.org". The + application argument can be the working title or final + name of your application. Both vendor and + application must be valid relative UNIX pathnames and + may contain '/'s to create deeper file structures. + + A set of Preferences marked "run-time" exists exactly one per application and + only as long as the application runs. It can be used as a database for + volatile information. FLTK uses it to register plugins at run-time. + + \param[in] root can be \c USER or \c SYSTEM for user specific or system wide + preferences + \param[in] vendor unique text describing the company or author of this file + \param[in] application unique text describing the application +*/ +Fl_Preferences::Fl_Preferences( Root root, const char *vendor, const char *application ) +{ + node = new Node( "." ); + rootNode = new RootNode( this, root, vendor, application ); + node->setRoot(rootNode); +} + + +/** + \brief Use this constructor to create or read a preferences file at an + arbitrary position in the file system. + + The file name is generated in the form + path/application.prefs. If \p application + is \c NULL, \p path must contain the full file name. + + \param[in] path path to the directory that contains the preferences file + \param[in] vendor unique text describing the company or author of this file + \param[in] application unique text describing the application + */ +Fl_Preferences::Fl_Preferences( const char *path, const char *vendor, const char *application ) +{ + node = new Node( "." ); + rootNode = new RootNode( this, path, vendor, application ); + node->setRoot(rootNode); +} + + +/** + \brief Generate or read a new group of entries within another group. + + Use the \p group argument to name the group that you would like to access. + \p Group can also contain a path to a group further down the hierarchy by + separating group names with a forward slash '/'. + + \param[in] parent reference object for the new group + \param[in] group name of the group to access (may contain '/'s) + */ +Fl_Preferences::Fl_Preferences( Fl_Preferences &parent, const char *group ) +{ + rootNode = parent.rootNode; + node = parent.node->addChild( group ); +} + + +/** + \brief Create or access a group of preferences using a name. + \param[in] parent the parameter parent is a pointer to the parent group. + \p Parent may be \p NULL. It then refers to an application internal + database which exists only once, and remains in RAM only until the + application quits. This database is used to manage plugins and other + data indexes by strings. + \param[in] group a group name that is used as a key into the database + \see Fl_Preferences( Fl_Preferences&, const char *group ) + */ +Fl_Preferences::Fl_Preferences( Fl_Preferences *parent, const char *group ) +{ + if (parent==0) { + if (!runtimePrefs) { + runtimePrefs = new Fl_Preferences(); + runtimePrefs->node = new Node( "." ); + runtimePrefs->rootNode = new RootNode( runtimePrefs ); + runtimePrefs->node->setRoot(rootNode); + } + parent = runtimePrefs; + } + rootNode = parent->rootNode; + node = parent->node->addChild( group ); +} + + +/** + \brief Open a child group using a given index. + + Use the \p groupIndex argument to find the group that you would like to access. + If the given index is invalid (negative or too high), a new group is created + with a UUID as a name. + + The index needs to be fixed. It is currently backward. Index 0 points + to the last member in the 'list' of preferences. + + \param[in] parent reference object for the new group + \param[in] groupIndex zero based index into child groups + */ +Fl_Preferences::Fl_Preferences( Fl_Preferences &parent, int groupIndex ) +{ + rootNode = parent.rootNode; + if (groupIndex<0 || groupIndex>=parent.groups()) { + node = parent.node->addChild( newUUID() ); + } else { + node = parent.node->childNode( groupIndex ); + } +} + + +/** + \see Fl_Preferences( Fl_Preferences&, int groupIndex ) + */ +Fl_Preferences::Fl_Preferences( Fl_Preferences *parent, int groupIndex ) +{ + rootNode = parent->rootNode; + if (groupIndex<0 || groupIndex>=parent->groups()) { + node = parent->node->addChild( newUUID() ); + } else { + node = parent->node->childNode( groupIndex ); + } +} + + +/** + Create a new dataset access point using a dataset ID. + + ID's are a great way to remember shortcuts to database entries that are deeply + nested in a preferences database, as long as the database root is not deleted. + An ID can be retrieved from any Fl_Preferences dataset, and can then be used + to create multiple new references to the same dataset. + + ID's can be put very helpful when put into the user_data() field of + widget callbacks. + */ +Fl_Preferences::Fl_Preferences( Fl_Preferences::ID id ) +{ + node = (Node*)id; + rootNode = node->findRoot(); +} + +/** + Create another reference to a Preferences group. + */ +Fl_Preferences::Fl_Preferences(const Fl_Preferences &rhs) +: node(rhs.node), + rootNode(rhs.rootNode) +{ } + +/** + Assign another reference to a Preference group. + */ +Fl_Preferences &Fl_Preferences::operator=(const Fl_Preferences &rhs) { + if (&rhs != this) { + node = rhs.node; + rootNode = rhs.rootNode; + } + return *this; +} + + +/** + The destructor removes allocated resources. When used on the + \em base preferences group, the destructor flushes all + changes to the preferences file and deletes all internal + databases. + + The destructor does not remove any data from the database. It merely + deletes your reference to the database. + */ +Fl_Preferences::~Fl_Preferences() +{ + if (node && !node->parent()) delete rootNode; + // DO NOT delete nodes! The root node will do that after writing the preferences + // zero all pointer to avoid memory errors, even though + // Valgrind does not complain (Cygwind does though) + node = 0L; + rootNode = 0L; +} + + +/** + Returns the number of groups that are contained within a group. + + \return 0 for no groups at all + */ +int Fl_Preferences::groups() +{ + return node->nChildren(); +} + + +/** + Returns the name of the Nth (\p num_group) group. + There is no guaranteed order of group names. The index must + be within the range given by groups(). + + \param[in] num_group number indexing the requested group + \return 'C' string pointer to the group name + */ +const char *Fl_Preferences::group( int num_group ) +{ + return node->child( num_group ); +} + + +/** + Returns non-zero if a group with this name exists. + Group names are relative to the Preferences node and can contain a path. + "." describes the current node, "./" describes the topmost node. + By preceding a groupname with a "./", its path becomes relative to the topmost node. + + \param[in] key name of group that is searched for + \return 0 if no group by that name was found + */ +char Fl_Preferences::groupExists( const char *key ) +{ + return node->search( key ) ? 1 : 0 ; +} + + +/** + Deletes a group. + + Removes a group and all keys and groups within that group + from the database. + + \param[in] group name of the group to delete + \return 0 if call failed + */ +char Fl_Preferences::deleteGroup( const char *group ) +{ + Node *nd = node->search( group ); + if ( nd ) return nd->remove(); + return 0; +} + +/** + Delete all groups. + */ +char Fl_Preferences::deleteAllGroups() +{ + node->deleteAllChildren(); + return 1; +} + +/** + Returns the number of entries (name/value pairs) in a group. + + \return number of entries + */ +int Fl_Preferences::entries() +{ + return node->nEntry(); +} + + +/** + Returns the name of an entry. There is no guaranteed order of + entry names. The index must be within the range given by + entries(). + + \param[in] index number indexing the requested entry + \return pointer to value cstring + */ +const char *Fl_Preferences::entry( int index ) +{ + return node->entry(index).name; +} + + +/** + Returns non-zero if an entry with this name exists. + + \param[in] key name of entry that is searched for + \return 0 if entry was not found + */ +char Fl_Preferences::entryExists( const char *key ) +{ + return node->getEntry( key )>=0 ? 1 : 0 ; +} + + +/** + Deletes a single name/value pair. + + This function removes the entry \p key from the database. + + \param[in] key name of entry to delete + \return 0 if deleting the entry failed + */ +char Fl_Preferences::deleteEntry( const char *key ) +{ + return node->deleteEntry( key ); +} + +/** + Delete all entries. + */ +char Fl_Preferences::deleteAllEntries() +{ + node->deleteAllEntries(); + return 1; +} + +/** + Delete all groups and all entries. + */ +char Fl_Preferences::clear() +{ + char ret1 = deleteAllGroups(); + char ret2 = deleteAllEntries(); + return ret1 & ret2; +} + +/** + Reads an entry from the group. A default value must be + supplied. The return value indicates if the value was available + (non-zero) or the default was used (0). + + \param[in] key name of entry + \param[out] value returned from preferences or default value if none was set + \param[in] defaultValue default value to be used if no preference was set + \return 0 if the default value was used + */ +char Fl_Preferences::get( const char *key, int &value, int defaultValue ) +{ + const char *v = node->get( key ); + value = v ? atoi( v ) : defaultValue; + return ( v != 0 ); +} + + +/** + Sets an entry (name/value pair). The return value indicates if there + was a problem storing the data in memory. However it does not + reflect if the value was actually stored in the preferences + file. + + \param[in] key name of entry + \param[in] value set this entry to \p value + \return 0 if setting the value failed + */ +char Fl_Preferences::set( const char *key, int value ) +{ + sprintf( nameBuffer, "%d", value ); + node->set( key, nameBuffer ); + return 1; +} + + +/** + Reads an entry from the group. A default value must be + supplied. The return value indicates if the value was available + (non-zero) or the default was used (0). + + \param[in] key name of entry + \param[out] value returned from preferences or default value if none was set + \param[in] defaultValue default value to be used if no preference was set + \return 0 if the default value was used + */ +char Fl_Preferences::get( const char *key, float &value, float defaultValue ) +{ + const char *v = node->get( key ); + value = v ? (float)atof( v ) : defaultValue; + return ( v != 0 ); +} + + +/** + Sets an entry (name/value pair). The return value indicates if there + was a problem storing the data in memory. However it does not + reflect if the value was actually stored in the preferences + file. + + \param[in] key name of entry + \param[in] value set this entry to \p value + \return 0 if setting the value failed + */ +char Fl_Preferences::set( const char *key, float value ) +{ + sprintf( nameBuffer, "%g", value ); + node->set( key, nameBuffer ); + return 1; +} + + +/** + Sets an entry (name/value pair). The return value indicates if there + was a problem storing the data in memory. However it does not + reflect if the value was actually stored in the preferences + file. + + \param[in] key name of entry + \param[in] value set this entry to \p value + \param[in] precision number of decimal digits to represent value + \return 0 if setting the value failed + */ +char Fl_Preferences::set( const char *key, float value, int precision ) +{ + sprintf( nameBuffer, "%.*g", precision, value ); + node->set( key, nameBuffer ); + return 1; +} + + +/** + Reads an entry from the group. A default value must be + supplied. The return value indicates if the value was available + (non-zero) or the default was used (0). + + \param[in] key name of entry + \param[out] value returned from preferences or default value if none was set + \param[in] defaultValue default value to be used if no preference was set + \return 0 if the default value was used + */ +char Fl_Preferences::get( const char *key, double &value, double defaultValue ) +{ + const char *v = node->get( key ); + value = v ? atof( v ) : defaultValue; + return ( v != 0 ); +} + + +/** + Sets an entry (name/value pair). The return value indicates if there + was a problem storing the data in memory. However it does not + reflect if the value was actually stored in the preferences + file. + + \param[in] key name of entry + \param[in] value set this entry to \p value + \return 0 if setting the value failed + */ +char Fl_Preferences::set( const char *key, double value ) +{ + sprintf( nameBuffer, "%g", value ); + node->set( key, nameBuffer ); + return 1; +} + + +/** + Sets an entry (name/value pair). The return value indicates if there + was a problem storing the data in memory. However it does not + reflect if the value was actually stored in the preferences + file. + + \param[in] key name of entry + \param[in] value set this entry to \p value + \param[in] precision number of decimal digits to represent value + \return 0 if setting the value failed + */ +char Fl_Preferences::set( const char *key, double value, int precision ) +{ + sprintf( nameBuffer, "%.*g", precision, value ); + node->set( key, nameBuffer ); + return 1; +} + + +// remove control sequences from a string +static char *decodeText( const char *src ) +{ + int len = 0; + const char *s = src; + for ( ; *s; s++, len++ ) + { + if ( *s == '\\' ) { + if ( isdigit( s[1] ) ) { + s+=3; + } else { + s+=1; + } + } + } + char *dst = (char*)malloc( len+1 ), *d = dst; + for ( s = src; *s; s++ ) + { + char c = *s; + if ( c == '\\' ) + { + if ( s[1] == '\\' ) { *d++ = c; s++; } + else if ( s[1] == 'n' ) { *d++ = '\n'; s++; } + else if ( s[1] == 'r' ) { *d++ = '\r'; s++; } + else if ( isdigit( s[1] ) ) { *d++ = ((s[1]-'0')<<6) + ((s[2]-'0')<<3) + (s[3]-'0'); s+=3; } + else s++; // error + } + else + *d++ = c; + } + *d = 0; + return dst; +} + + +/** + Reads an entry from the group. A default value must be + supplied. The return value indicates if the value was available + (non-zero) or the default was used (0). + 'maxSize' is the maximum length of text that will be read. + The text buffer must allow for one additional byte for a trailling zero. + + \param[in] key name of entry + \param[out] text returned from preferences or default value if none was set + \param[in] defaultValue default value to be used if no preference was set + \param[in] maxSize maximum length of value plus one byte for a trailing zero + \return 0 if the default value was used + */ +char Fl_Preferences::get( const char *key, char *text, const char *defaultValue, int maxSize ) +{ + const char *v = node->get( key ); + if ( v && strchr( v, '\\' ) ) { + char *w = decodeText( v ); + strlcpy(text, w, maxSize); + free( w ); + return 1; + } + if ( !v ) v = defaultValue; + if ( v ) strlcpy(text, v, maxSize); + else text = 0; + return ( v != defaultValue ); +} + + +/** + Reads an entry from the group. A default value must be + supplied. The return value indicates if the value was available + (non-zero) or the default was used (0). get() allocates memory of + sufficient size to hold the value. The buffer must be free'd by + the developer using 'free(value)'. + + \param[in] key name of entry + \param[out] text returned from preferences or default value if none was set + \param[in] defaultValue default value to be used if no preference was set + \return 0 if the default value was used + */ +char Fl_Preferences::get( const char *key, char *&text, const char *defaultValue ) +{ + const char *v = node->get( key ); + if ( v && strchr( v, '\\' ) ) + { + text = decodeText( v ); + return 1; + } + if ( !v ) v = defaultValue; + if ( v ) + text = strdup( v ); + else + text = 0; + return ( v != defaultValue ); +} + + + +/** + Sets an entry (name/value pair). The return value indicates if there + was a problem storing the data in memory. However it does not + reflect if the value was actually stored in the preferences + file. + + \param[in] key name of entry + \param[in] text set this entry to \p value + \return 0 if setting the value failed + */ +char Fl_Preferences::set( const char *key, const char *text ) +{ + const char *s = text ? text : ""; + int n=0, ns=0; + for ( ; *s; s++ ) { n++; if ( *s<32 || *s=='\\' || *s==0x7f ) ns+=4; } + if ( ns ) + { + char *buffer = (char*)malloc( n+ns+1 ), *d = buffer; + for ( s=text; *s; ) + { + char c = *s; + if ( c=='\\' ) { *d++ = '\\'; *d++ = '\\'; s++; } + else if ( c=='\n' ) { *d++ = '\\'; *d++ = 'n'; s++; } + else if ( c=='\r' ) { *d++ = '\\'; *d++ = 'r'; s++; } + else if ( c<32 || c==0x7f ) + { *d++ = '\\'; *d++ = '0'+((c>>6)&3); *d++ = '0'+((c>>3)&7); *d++ = '0'+(c&7); s++; } + else *d++ = *s++; + } + *d = 0; + node->set( key, buffer ); + free( buffer ); + } + else + node->set( key, text ); + return 1; +} + + +// convert a hex string to binary data +static void *decodeHex( const char *src, int &size ) +{ + size = strlen( src )/2; + unsigned char *data = (unsigned char*)malloc( size ), *d = data; + const char *s = src; + int i; + + for ( i=size; i>0; i-- ) + { + int v; + char x = tolower(*s++); + if ( x >= 'a' ) v = x-'a'+10; else v = x-'0'; + v = v<<4; + x = tolower(*s++); + if ( x >= 'a' ) v += x-'a'+10; else v += x-'0'; + *d++ = (uchar)v; + } + + return (void*)data; +} + + +/** + Reads an entry from the group. A default value must be + supplied. The return value indicates if the value was available + (non-zero) or the default was used (0). + 'maxSize' is the maximum length of text that will be read. + + \param[in] key name of entry + \param[out] data value returned from preferences or default value if none was set + \param[in] defaultValue default value to be used if no preference was set + \param[in] defaultSize size of default value array + \param[in] maxSize maximum length of value + \return 0 if the default value was used + + \todo maxSize should receive the number of bytes that were read. + */ +char Fl_Preferences::get( const char *key, void *data, const void *defaultValue, int defaultSize, int maxSize ) +{ + const char *v = node->get( key ); + if ( v ) + { + int dsize; + void *w = decodeHex( v, dsize ); + memmove( data, w, dsize>maxSize?maxSize:dsize ); + free( w ); + return 1; + } + if ( defaultValue ) + memmove( data, defaultValue, defaultSize>maxSize?maxSize:defaultSize ); + return 0; +} + + +/** + Reads an entry from the group. A default value must be + supplied. The return value indicates if the value was available + (non-zero) or the default was used (0). get() allocates memory of + sufficient size to hold the value. The buffer must be free'd by + the developer using 'free(value)'. + + \param[in] key name of entry + \param[out] data returned from preferences or default value if none was set + \param[in] defaultValue default value to be used if no preference was set + \param[in] defaultSize size of default value array + \return 0 if the default value was used + */ +char Fl_Preferences::get( const char *key, void *&data, const void *defaultValue, int defaultSize ) +{ + const char *v = node->get( key ); + if ( v ) + { + int dsize; + data = decodeHex( v, dsize ); + return 1; + } + if ( defaultValue ) + { + data = (void*)malloc( defaultSize ); + memmove( data, defaultValue, defaultSize ); + } + else + data = 0; + return 0; +} + + +/** + Sets an entry (name/value pair). The return value indicates if there + was a problem storing the data in memory. However it does not + reflect if the value was actually stored in the preferences + file. + + \param[in] key name of entry + \param[in] data set this entry to \p value + \param[in] dsize size of data array + \return 0 if setting the value failed + */ +char Fl_Preferences::set( const char *key, const void *data, int dsize ) +{ + char *buffer = (char*)malloc( dsize*2+1 ), *d = buffer;; + unsigned char *s = (unsigned char*)data; + for ( ; dsize>0; dsize-- ) + { + static char lu[] = "0123456789abcdef"; + unsigned char v = *s++; + *d++ = lu[v>>4]; + *d++ = lu[v&0xf]; + } + *d = 0; + node->set( key, buffer ); + free( buffer ); + return 1; +} + + +/** + Returns the size of the value part of an entry. + + \param[in] key name of entry + \return size of value + */ +int Fl_Preferences::size( const char *key ) +{ + const char *v = node->get( key ); + return v ? strlen( v ) : 0 ; +} + + +/** + \brief Creates a path that is related to the preferences file and + that is usable for additional application data. + + This function creates a directory that is named after the preferences + database without the \c .prefs extension and located in the same directory. + It then fills the given buffer with the complete path name. + + Exmaple: + \code + Fl_Preferences prefs( USER, "matthiasm.com", "test" ); + char path[FL_PATH_MAX]; + prefs.getUserdataPath( path ); + \endcode + creates the preferences database in (MS Windows): + \code + c:/Documents and Settings/matt/Application Data/matthiasm.com/test.prefs + \endcode + and returns the userdata path: + \code + c:/Documents and Settings/matt/Application Data/matthiasm.com/test/ + \endcode + + \param[out] path buffer for user data path + \param[in] pathlen size of path buffer (should be at least \c FL_PATH_MAX) + \return 0 if path was not created or pathname can't fit into buffer + */ +char Fl_Preferences::getUserdataPath( char *path, int pathlen ) +{ + if ( rootNode ) + return rootNode->getPath( path, pathlen ); + return 0; +} + +/** + Writes all preferences to disk. This function works only with + the base preferences group. This function is rarely used as + deleting the base preferences flushes automatically. + */ +void Fl_Preferences::flush() +{ + if ( rootNode && node->dirty() ) + rootNode->write(); +} + +//----------------------------------------------------------------------------- +// helper class to create dynamic group and entry names on the fly +// + +/** + Creates a group name or entry name on the fly. + + This version creates a simple unsigned integer as an entry name. + + \code + int n, i; + Fl_Preferences prev( appPrefs, "PreviousFiles" ); + prev.get( "n", 0 ); + for ( i=0; inode->dirty() ) + write(); + if ( filename_ ) { + free( filename_ ); + filename_ = 0L; + } + if ( vendor_ ) { + free( vendor_ ); + vendor_ = 0L; + } + if ( application_ ) { + free( application_ ); + application_ = 0L; + } + delete prefs_->node; + prefs_->node = 0L; +} + +// read a preferences file and construct the group tree and with all entry leafs +int Fl_Preferences::RootNode::read() +{ + if (!filename_) // RUNTIME preferences + return -1; + + char buf[1024]; + FILE *f = fl_fopen( filename_, "rb" ); + if ( !f ) + return -1; + + if (fgets( buf, 1024, f )==0) { /* ignore */ } + if (fgets( buf, 1024, f )==0) { /* ignore */ } + if (fgets( buf, 1024, f )==0) { /* ignore */ } + Node *nd = prefs_->node; + for (;;) + { + if ( !fgets( buf, 1024, f ) ) break; // EOF or Error + if ( buf[0]=='[' ) // read a new group + { + int end = strcspn( buf+1, "]\n\r" ); + buf[ end+1 ] = 0; + nd = prefs_->node->find( buf+1 ); + } + else if ( buf[0]=='+' ) // + { // value of previous name/value pair spans multiple lines + int end = strcspn( buf+1, "\n\r" ); + if ( end != 0 ) // if entry is not empty + { + buf[ end+1 ] = 0; + nd->add( buf+1 ); + } + } + else // read a name/value pair + { + int end = strcspn( buf, "\n\r" ); + if ( end != 0 ) // if entry is not empty + { + buf[ end ] = 0; + nd->set( buf ); + } + } + } + fclose( f ); + return 0; +} + +// write the group tree and all entry leafs +int Fl_Preferences::RootNode::write() +{ + if (!filename_) // RUNTIME preferences + return -1; + + fl_make_path_for_file(filename_); + FILE *f = fl_fopen( filename_, "wb" ); + if ( !f ) + return -1; + + fprintf( f, "; FLTK preferences file format 1.0\n" ); + fprintf( f, "; vendor: %s\n", vendor_ ); + fprintf( f, "; application: %s\n", application_ ); + prefs_->node->write( f ); + fclose( f ); + return 0; +} + +// get the path to the preferences directory +char Fl_Preferences::RootNode::getPath( char *path, int pathlen ) +{ + if (!filename_) // RUNTIME preferences + return -1; + + strlcpy( path, filename_, pathlen); + + char *s; + for ( s = path; *s; s++ ) if ( *s == '\\' ) *s = '/'; + s = strrchr( path, '.' ); + if ( !s ) return 0; + *s = 0; + char ret = fl_make_path( path ); + strcpy( s, "/" ); + return ret; +} + +// create a node that represents a group +// - path must be a single word, prferable alnum(), dot and underscore only. Space is ok. +Fl_Preferences::Node::Node( const char *path ) +{ + if ( path ) path_ = strdup( path ); else path_ = 0; + child_ = 0; next_ = 0; parent_ = 0; + entry_ = 0; + nEntry_ = NEntry_ = 0; + dirty_ = 0; + top_ = 0; + indexed_ = 0; + index_ = 0; + nIndex_ = NIndex_ = 0; +} + +void Fl_Preferences::Node::deleteAllChildren() +{ + Node *nx; + for ( Node *nd = child_; nd; nd = nx ) + { + nx = nd->next_; + delete nd; + } + child_ = 0L; + dirty_ = 1; + updateIndex(); +} + +void Fl_Preferences::Node::deleteAllEntries() +{ + if ( entry_ ) + { + for ( int i = 0; i < nEntry_; i++ ) + { + if ( entry_[i].name ) { + free( entry_[i].name ); + entry_[i].name = 0L; + } + if ( entry_[i].value ) { + free( entry_[i].value ); + entry_[i].value = 0L; + } + } + free( entry_ ); + entry_ = 0L; + nEntry_ = 0; + NEntry_ = 0; + } + dirty_ = 1; +} + +// delete this and all depending nodes +Fl_Preferences::Node::~Node() +{ + deleteAllChildren(); + deleteAllEntries(); + deleteIndex(); + if ( path_ ) { + free( path_ ); + path_ = 0L; + } + next_ = 0L; + parent_ = 0L; +} + +// recursively check if any entry is dirty (was changed after loading a fresh prefs file) +char Fl_Preferences::Node::dirty() +{ + if ( dirty_ ) return 1; + if ( next_ && next_->dirty() ) return 1; + if ( child_ && child_->dirty() ) return 1; + return 0; +} + +// write this node (recursively from the last neighbor back to this) +// write all entries +// write all children +int Fl_Preferences::Node::write( FILE *f ) +{ + if ( next_ ) next_->write( f ); + fprintf( f, "\n[%s]\n\n", path_ ); + for ( int i = 0; i < nEntry_; i++ ) + { + char *src = entry_[i].value; + if ( src ) + { // hack it into smaller pieces if needed + fprintf( f, "%s:", entry_[i].name ); + int cnt; + for ( cnt = 0; cnt < 60; cnt++ ) + if ( src[cnt]==0 ) break; + fwrite( src, cnt, 1, f ); + fprintf( f, "\n" ); + src += cnt; + for (;*src;) + { + for ( cnt = 0; cnt < 80; cnt++ ) + if ( src[cnt]==0 ) break; + fputc( '+', f ); + fwrite( src, cnt, 1, f ); + fputc( '\n', f ); + src += cnt; + } + } + else + fprintf( f, "%s\n", entry_[i].name ); + } + if ( child_ ) child_->write( f ); + dirty_ = 0; + return 0; +} + +// set the parent node and create the full path +void Fl_Preferences::Node::setParent( Node *pn ) +{ + parent_ = pn; + next_ = pn->child_; + pn->child_ = this; + sprintf( nameBuffer, "%s/%s", pn->path_, path_ ); + free( path_ ); + path_ = strdup( nameBuffer ); +} + +// find the corresponding root node +Fl_Preferences::RootNode *Fl_Preferences::Node::findRoot() +{ + Node *n = this; + do { + if (n->top_) + return n->root_; + n = n->parent(); + + } while (n); + return 0L; +} + +// add a child to this node and set its path (try to find it first...) +Fl_Preferences::Node *Fl_Preferences::Node::addChild( const char *path ) +{ + sprintf( nameBuffer, "%s/%s", path_, path ); + char *name = strdup( nameBuffer ); + Node *nd = find( name ); + free( name ); + dirty_ = 1; + updateIndex(); + return nd; +} + +// create and set, or change an entry within this node +void Fl_Preferences::Node::set( const char *name, const char *value ) +{ + for ( int i=0; i= sizeof( nameBuffer ) ) + len = sizeof( nameBuffer ); + strlcpy( nameBuffer, line, len ); + set( nameBuffer, c+1 ); + } + else + set( line, "" ); + } + dirty_ = dirt; +} + +// add more data to an existing entry +void Fl_Preferences::Node::add( const char *line ) +{ + if ( lastEntrySet<0 || lastEntrySet>=nEntry_ ) return; + char *&dst = entry_[ lastEntrySet ].value; + int a = strlen( dst ); + int b = strlen( line ); + dst = (char*)realloc( dst, a+b+1 ); + memcpy( dst+a, line, b+1 ); + dirty_ = 1; +} + +// get the value for a name, returns 0 if no such name +const char *Fl_Preferences::Node::get( const char *name ) +{ + int i = getEntry( name ); + return i>=0 ? entry_[i].value : 0 ; +} + +// find the index of an entry, returns -1 if no such entry +int Fl_Preferences::Node::getEntry( const char *name ) +{ + for ( int i=0; inext_ ) + { + Node *nn = nd->find( path ); + if ( nn ) return nn; + } + const char *s = path+len+1; + const char *e = strchr( s, '/' ); + if (e) strlcpy( nameBuffer, s, e-s+1 ); + else strlcpy( nameBuffer, s, sizeof(nameBuffer)); + nd = new Node( nameBuffer ); + nd->setParent( this ); + return nd->find( path ); + } + } + return 0; +} + +// find a group somewhere in the tree starting here +// caller must not set 'offset' argument +// - if the node does not exist, 'search' returns NULL +// - if the pathname is "." (current node) return this node +// - if the pathname is "./" (root node) return the topmost node +// - if the pathname starts with "./", start the search at the root node instead +Fl_Preferences::Node *Fl_Preferences::Node::search( const char *path, int offset ) +{ + + if ( offset == 0 ) + { + if ( path[0] == '.' ) + { + if ( path[1] == 0 ) + { + return this; // user was searching for current node + } + else if ( path[1] == '/' ) + { + Node *nn = this; + while ( nn->parent() ) nn = nn->parent(); + if ( path[2]==0 ) + { // user is searching for root ( "./" ) + return nn; + } + return nn->search( path+2, 2 ); // do a relative search on the root node + } + } + offset = strlen( path_ ) + 1; + } + + int len = strlen( path_ ); + if ( len < offset-1 ) return 0; + len -= offset; + if ( ( len <= 0 ) || ( strncmp( path, path_+offset, len ) == 0 ) ) + { + if ( len > 0 && path[ len ] == 0 ) + return this; + if ( len <= 0 || path[ len ] == '/' ) + { + for ( Node *nd = child_; nd; nd = nd->next_ ) + { + Node *nn = nd->search( path, offset ); + if ( nn ) return nn; + } + return 0; + } + } + return 0; +} + +// return the number of child nodes (groups) +int Fl_Preferences::Node::nChildren() +{ + if (indexed_) { + return nIndex_; + } else { + int cnt = 0; + for ( Node *nd = child_; nd; nd = nd->next_ ) + cnt++; + return cnt; + } +} + +// return the node name +const char *Fl_Preferences::Node::name() +{ + if ( path_ ) + { + char *r = strrchr( path_, '/' ); + return r ? r+1 : path_ ; + } else { + return 0L ; + } +} + +// return the n'th child node's name +const char *Fl_Preferences::Node::child( int ix ) +{ + Node *nd = childNode( ix ); + if ( nd ) + return nd->name(); + else + return 0L ; +} + +// return the n'th child node +Fl_Preferences::Node *Fl_Preferences::Node::childNode( int ix ) +{ + createIndex(); + if (indexed_) { + // usually faster access in correct order, but needing more memory + return index_[ix]; + } else { + // slow access and reverse order + int n = nChildren(); + ix = n - ix -1; + Node *nd; + for ( nd = child_; nd; nd = nd->next_ ) + { + if ( !ix-- ) break; + if ( !nd ) break; + } + return nd; + } +} + +// remove myself from the list and delete me (and all children) +char Fl_Preferences::Node::remove() +{ + Node *nd = 0, *np; + if ( parent() ) + { + nd = parent()->child_; np = 0L; + for ( ; nd; np = nd, nd = nd->next_ ) + { + if ( nd == this ) + { + if ( np ) + np->next_ = nd->next_; + else + parent()->child_ = nd->next_; + break; + } + } + parent()->dirty_ = 1; + parent()->updateIndex(); + } + delete this; + return ( nd != 0 ); +} + +void Fl_Preferences::Node::createIndex() { + if (indexed_) return; + int n = nChildren(); + if (n>NIndex_) { + NIndex_ = n + 16; + index_ = (Node**)realloc(index_, NIndex_*sizeof(Node**)); + } + Node *nd; + int i = 0; + for (nd = child_; nd; nd = nd->next_, i++) { + index_[n-i-1] = nd; + } + nIndex_ = n; + indexed_ = 1; +} + +void Fl_Preferences::Node::updateIndex() { + indexed_ = 0; +} + +void Fl_Preferences::Node::deleteIndex() { + if (index_) free(index_); + NIndex_ = nIndex_ = 0; + index_ = 0; + indexed_ = 0; +} + +/** + * \brief Create a plugin. + * + * \param[in] klass plugins are grouped in classes + * \param[in] name every plugin should have a unique name + */ +Fl_Plugin::Fl_Plugin(const char *klass, const char *name) +: id(0) +{ +#ifdef FL_PLUGIN_VERBOSE + printf("Fl_Plugin: creating a plugin, class \"%s\", name \"%s\"\n", + klass, name); +#endif + Fl_Plugin_Manager pm(klass); + id = pm.addPlugin(name, this); +} + +/** + * \brief Clear the plugin and remove it from the database. + */ +Fl_Plugin::~Fl_Plugin() +{ +#ifdef FL_PLUGIN_VERBOSE + printf("Fl_Plugin: deleting a plugin\n"); +#endif + if (id) + Fl_Plugin_Manager::remove(id); +} + + +/** + * \brief Manage all plugins belonging to one class. + */ +Fl_Plugin_Manager::Fl_Plugin_Manager(const char *klass) +: Fl_Preferences(0, Fl_Preferences::Name("%s/%s", "plugins", klass)) +{ +#ifdef FL_PLUGIN_VERBOSE + printf("Fl_Plugin: creating a plugin manager for class \"%s\"\n", klass); +#endif +} + +/** + * \brief Remove the plugin manager. + * + * Calling this does not remove the database itself or any plugins. It just + * removes the reference to the database. + */ +Fl_Plugin_Manager::~Fl_Plugin_Manager() +{ +#ifdef FL_PLUGIN_VERBOSE + printf("Fl_Plugin: deleting a plugin manager\n"); +#endif +} + +static unsigned char x2i(char hi, char lo) { + return ((hi-'A')<<4) | (lo-'A'); +} + +static void i2x(unsigned char v, char *d) { + d[0] = ((v>>4)&0x0f)+'A'; d[1] = (v&0x0f)+'A'; +} + +static void *a2p(const char *s) { + union { void *ret; unsigned char d[sizeof(void*)]; } v; + v.ret = 0L; + int i=0, n=sizeof(void*); + for (i=0; id_name, pattern)) { + load(Fl_Preferences::Name("%s%s", filepath, e->d_name)); + } + free(e); + } + free(dir); + return 0; +} + + +// +// End of "$Id: Fl_Preferences.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Printer.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Printer.cxx new file mode 100644 index 0000000..1b9ee21 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Printer.cxx @@ -0,0 +1,95 @@ +// +// "$Id: Fl_Printer.cxx 7894 2010-11-26 10:22:40Z manolo $" +// +// Encompasses platform-specific printing-support code and +// PostScript output code for the Fast Light Tool Kit (FLTK). +// +// Copyright 2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems to: +// +// http://www.fltk.org/str.php +// + +#include + +#ifdef __APPLE__ +#include +#elif defined(WIN32) +#include +#endif + +#include + +// print dialog customization strings +/** [this text may be customized at run-time] */ +const char *Fl_Printer::dialog_title = "Print"; +/** [this text may be customized at run-time] */ +const char *Fl_Printer::dialog_printer = "Printer:"; +/** [this text may be customized at run-time] */ +const char *Fl_Printer::dialog_range = "Print Range"; +/** [this text may be customized at run-time] */ +const char *Fl_Printer::dialog_copies = "Copies"; +/** [this text may be customized at run-time] */ +const char *Fl_Printer::dialog_all = "All"; +/** [this text may be customized at run-time] */ +const char *Fl_Printer::dialog_pages = "Pages"; +/** [this text may be customized at run-time] */ +const char *Fl_Printer::dialog_from = "From:"; +/** [this text may be customized at run-time] */ +const char *Fl_Printer::dialog_to = "To:"; +/** [this text may be customized at run-time] */ +const char *Fl_Printer::dialog_properties = "Properties..."; +/** [this text may be customized at run-time] */ +const char *Fl_Printer::dialog_copyNo = "# Copies:"; +/** [this text may be customized at run-time] */ +const char *Fl_Printer::dialog_print_button = "Print"; +/** [this text may be customized at run-time] */ +const char *Fl_Printer::dialog_cancel_button = "Cancel"; +/** [this text may be customized at run-time] */ +const char *Fl_Printer::dialog_print_to_file = "Print To File"; +/** [this text may be customized at run-time] */ +const char *Fl_Printer::property_title = "Printer Properties"; +/** [this text may be customized at run-time] */ +const char *Fl_Printer::property_pagesize = "Page Size:"; +/** [this text may be customized at run-time] */ +const char *Fl_Printer::property_mode = "Output Mode:"; +/** [this text may be customized at run-time] */ +const char *Fl_Printer::property_use = "Use"; +/** [this text may be customized at run-time] */ +const char *Fl_Printer::property_save = "Save"; +/** [this text may be customized at run-time] */ +const char *Fl_Printer::property_cancel = "Cancel"; + +const char *Fl_Printer::device_type = "Fl_Printer"; + +#if defined(__APPLE__) || defined(WIN32) +void Fl_System_Printer::set_current(void) +{ +#ifdef __APPLE__ + fl_gc = (CGContextRef)gc; +#elif defined(WIN32) + fl_gc = (HDC)gc; +#endif + this->Fl_Surface_Device::set_current(); +} +#endif + +// +// End of "$Id: Fl_Printer.cxx 7894 2010-11-26 10:22:40Z manolo $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Progress.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Progress.cxx new file mode 100644 index 0000000..192b38d --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Progress.cxx @@ -0,0 +1,123 @@ +// +// "$Id: Fl_Progress.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Progress bar widget routines. +// +// Copyright 2000-2010 by Michael Sweet. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// +// Contents: + +// +// Fl_Progress::draw() - Draw the check button. +// Fl_Progress::Fl_Progress() - Construct a Fl_Progress widget. +// + +// +// Include necessary header files... +// + +#include +#include +#include + + +// +// Fl_Progress is a progress bar widget based off Fl_Widget that shows a +// standard progress bar... +// + + +// +// 'Fl_Progress::draw()' - Draw the progress bar. +// + +/** Draws the progress bar. */ +void Fl_Progress::draw() +{ + int progress; // Size of progress bar... + int bx, by, bw, bh; // Box areas... + int tx, tw; // Temporary X + width + + + // Get the box borders... + bx = Fl::box_dx(box()); + by = Fl::box_dy(box()); + bw = Fl::box_dw(box()); + bh = Fl::box_dh(box()); + + tx = x() + bx; + tw = w() - bw; + + // Draw the progress bar... + if (maximum_ > minimum_) + progress = (int)(w() * (value_ - minimum_) / (maximum_ - minimum_) + 0.5f); + else + progress = 0; + + // Draw the box and label... + if (progress > 0) { + Fl_Color c = labelcolor(); + labelcolor(fl_contrast(labelcolor(), selection_color())); + + fl_push_clip(x(), y(), progress + bx, h()); + draw_box(box(), x(), y(), w(), h(), active_r() ? selection_color() : fl_inactive(selection_color())); + draw_label(tx, y() + by, tw, h() - bh); + fl_pop_clip(); + + labelcolor(c); + + if (progress + +#include +#include +#include +#import + +extern void fl_quartz_restore_line_style_(); + +Fl_System_Printer::Fl_System_Printer(void) +{ + x_offset = 0; + y_offset = 0; + scale_x = scale_y = 1.; + type_ = device_type; + gc = 0; + driver(fl_graphics_driver); +} + +Fl_System_Printer::~Fl_System_Printer(void) {} + +int Fl_Printer::start_job (int pagecount, int *frompage, int *topage) +//printing using a Quartz graphics context +//returns 0 iff OK +{ + OSStatus status = 0; + Fl_X::q_release_context(); +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + if( [NSPrintPanel instancesRespondToSelector:@selector(runModalWithPrintInfo:)] && + [NSPrintInfo instancesRespondToSelector:@selector(PMPrintSession)] ) { + NSAutoreleasePool *localPool; + localPool = [[NSAutoreleasePool alloc] init]; + NSPrintInfo *info = [NSPrintInfo sharedPrintInfo]; + NSPageLayout *layout = [NSPageLayout pageLayout]; + NSInteger retval = [layout runModal]; + if(retval == NSOKButton) { + NSPrintPanel *panel = [NSPrintPanel printPanel]; + retval = (NSInteger)[panel runModalWithPrintInfo:info];//from 10.5 only + } + if(retval != NSOKButton) { + Fl::first_window()->show(); + [localPool release]; + return 1; + } + printSession = (PMPrintSession)[info PMPrintSession]; + pageFormat = (PMPageFormat)[info PMPageFormat]; + printSettings = (PMPrintSettings)[info PMPrintSettings]; + UInt32 from32, to32; + PMGetFirstPage(printSettings, &from32); + if (frompage) *frompage = (int)from32; + PMGetLastPage(printSettings, &to32); + if (topage) *topage = (int)to32; + if(topage && *topage > pagecount) *topage = pagecount; + status = PMSessionBeginCGDocumentNoDialog(printSession, printSettings, pageFormat); + [localPool release]; + } + else { +#endif + +#if !__LP64__ + Boolean accepted; + status = PMCreateSession(&printSession); + if (status != noErr) return 1; + status = PMCreatePageFormat(&pageFormat); + status = PMSessionDefaultPageFormat(printSession, pageFormat); + if (status != noErr) return 1; + status = PMSessionPageSetupDialog(printSession, pageFormat, &accepted); + if (status != noErr || !accepted) { + Fl::first_window()->show(); + return 1; + } + status = PMCreatePrintSettings(&printSettings); + if (status != noErr || printSettings == kPMNoPrintSettings) return 1; + status = PMSessionDefaultPrintSettings (printSession, printSettings); + if (status != noErr) return 1; + PMSetPageRange(printSettings, 1, (UInt32)kPMPrintAllPages); + status = PMSessionPrintDialog(printSession, printSettings, pageFormat, &accepted); + if (!accepted) status = kPMCancel; + if (status != noErr) { + Fl::first_window()->show(); + return 1; + } + UInt32 from32, to32; + PMGetFirstPage(printSettings, &from32); + if (frompage) *frompage = (int)from32; + PMGetLastPage(printSettings, &to32); + if (topage) *topage = (int)to32; + if(topage && *topage > pagecount) *topage = pagecount; + CFStringRef mystring[1]; + mystring[0] = kPMGraphicsContextCoreGraphics; + CFArrayRef array = CFArrayCreate(NULL, (const void **)mystring, 1, &kCFTypeArrayCallBacks); + status = PMSessionSetDocumentFormatGeneration(printSession, kPMDocumentFormatDefault, array, NULL); + CFRelease(array); + status = PMSessionBeginDocumentNoDialog(printSession, printSettings, pageFormat); +#endif //__LP64__ + +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + } +#endif + if (status != noErr) return 1; + y_offset = x_offset = 0; + this->set_current(); + return 0; +} + +void Fl_Printer::margins(int *left, int *top, int *right, int *bottom) +{ + PMPaper paper; + PMGetPageFormatPaper(pageFormat, &paper); + PMOrientation orientation; + PMGetOrientation(pageFormat, &orientation); + PMPaperMargins margins; + PMPaperGetMargins(paper, &margins); + if(orientation == kPMPortrait) { + if (left) *left = (int)(margins.left / scale_x + 0.5); + if (top) *top = (int)(margins.top / scale_y + 0.5); + if (right) *right = (int)(margins.right / scale_x + 0.5); + if (bottom) *bottom = (int)(margins.bottom / scale_y + 0.5); + } + else { + if (left) *left = (int)(margins.top / scale_x + 0.5); + if (top) *top = (int)(margins.left / scale_y + 0.5); + if (right) *right = (int)(margins.bottom / scale_x + 0.5); + if (bottom) *bottom = (int)(margins.right / scale_y + 0.5); + } +} + +int Fl_Printer::printable_rect(int *w, int *h) +//returns 0 iff OK +{ + OSStatus status; + PMRect pmRect; + int x, y; + + status = PMGetAdjustedPageRect(pageFormat, &pmRect); + if (status != noErr) return 1; + + x = (int)pmRect.left; + y = (int)pmRect.top; + *w = int((int)(pmRect.right - x) / scale_x + 1); + *h = int((int)(pmRect.bottom - y) / scale_y + 1); + return 0; +} + +void Fl_Printer::origin(int x, int y) +{ + x_offset = x; + y_offset = y; + CGContextRestoreGState(fl_gc); + CGContextRestoreGState(fl_gc); + CGContextSaveGState(fl_gc); + CGContextScaleCTM(fl_gc, scale_x, scale_y); + CGContextTranslateCTM(fl_gc, x, y); + CGContextRotateCTM(fl_gc, angle); + CGContextSaveGState(fl_gc); +} + +void Fl_Printer::scale (float s_x, float s_y) +{ + scale_x = s_x; + scale_y = s_y; + CGContextRestoreGState(fl_gc); + CGContextRestoreGState(fl_gc); + CGContextSaveGState(fl_gc); + CGContextScaleCTM(fl_gc, scale_x, scale_y); + CGContextRotateCTM(fl_gc, angle); + x_offset = y_offset = 0; + CGContextSaveGState(fl_gc); +} + +void Fl_Printer::rotate (float rot_angle) +{ + angle = - rot_angle * M_PI / 180.; + CGContextRestoreGState(fl_gc); + CGContextRestoreGState(fl_gc); + CGContextSaveGState(fl_gc); + CGContextScaleCTM(fl_gc, scale_x, scale_y); + CGContextTranslateCTM(fl_gc, x_offset, y_offset); + CGContextRotateCTM(fl_gc, angle); + CGContextSaveGState(fl_gc); +} + +void Fl_Printer::translate(int x, int y) +{ + CGContextSaveGState(fl_gc); + CGContextTranslateCTM(fl_gc, x, y ); + CGContextSaveGState(fl_gc); +} + +void Fl_Printer::untranslate(void) +{ + CGContextRestoreGState(fl_gc); + CGContextRestoreGState(fl_gc); +} + +int Fl_Printer::start_page (void) +{ + OSStatus status = PMSessionBeginPageNoDialog(printSession, pageFormat, NULL); +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 + if ( PMSessionGetCGGraphicsContext != NULL ) { + status = PMSessionGetCGGraphicsContext(printSession, &fl_gc); + } + else { +#endif +#if ! __LP64__ + status = PMSessionGetGraphicsContext(printSession,NULL,(void **)&fl_gc); +#endif +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 + } +#endif + PMRect pmRect; + float win_scale_x, win_scale_y; + + PMPaper paper; + PMGetPageFormatPaper(pageFormat, &paper); + PMPaperMargins margins; + PMPaperGetMargins(paper, &margins); + PMOrientation orientation; + PMGetOrientation(pageFormat, &orientation); + + status = PMGetAdjustedPageRect(pageFormat, &pmRect); + double h = pmRect.bottom - pmRect.top; + x_offset = 0; + y_offset = 0; + angle = 0; + scale_x = scale_y = 1; + win_scale_x = win_scale_y = 1; + image_list_ = NULL; + if(orientation == kPMPortrait) + CGContextTranslateCTM(fl_gc, margins.left, margins.bottom + h); + else + CGContextTranslateCTM(fl_gc, margins.top, margins.right + h); + CGContextScaleCTM(fl_gc, win_scale_x, - win_scale_y); + fl_quartz_restore_line_style_(); + CGContextSetShouldAntialias(fl_gc, false); + CGContextSaveGState(fl_gc); + CGContextSaveGState(fl_gc); + fl_line_style(FL_SOLID); + fl_window = (void *)1; // TODO: something better + fl_clip_region(0); + if( status == noErr) gc = fl_gc; + return status != noErr; +} + +int Fl_Printer::end_page (void) +{ + CGContextFlush(fl_gc); + CGContextRestoreGState(fl_gc); + CGContextRestoreGState(fl_gc); + OSStatus status = PMSessionEndPageNoDialog(printSession); + delete_image_list(); + gc = NULL; + return status != noErr; +} + +void Fl_Printer::end_job (void) +{ + OSStatus status; + + status = PMSessionError(printSession); + if (status != noErr) { + fl_alert ("PM Session error %d", (int)status); + } + PMSessionEndDocumentNoDialog(printSession); + Fl_Display_Device::display_device()->set_current(); + fl_gc = 0; + Fl::first_window()->show(); +} + +#endif // __APPLE__ + +// +// End of "$Id: Fl_Quartz_Printer.mm 7894 2010-11-26 10:22:40Z manolo $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Repeat_Button.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Repeat_Button.cxx new file mode 100644 index 0000000..65ed3ef --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Repeat_Button.cxx @@ -0,0 +1,70 @@ +// +// "$Id: Fl_Repeat_Button.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Repeat button widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include + +#define INITIALREPEAT .5 +#define REPEAT .1 + +void Fl_Repeat_Button::repeat_callback(void *v) { + Fl_Button *b = (Fl_Button*)v; + Fl::add_timeout(REPEAT,repeat_callback,b); + b->do_callback(); +} + +int Fl_Repeat_Button::handle(int event) { + int newval; + switch (event) { + case FL_HIDE: + case FL_DEACTIVATE: + case FL_RELEASE: + newval = 0; goto J1; + case FL_PUSH: + case FL_DRAG: + if (Fl::visible_focus()) Fl::focus(this); + newval = Fl::event_inside(this); + J1: + if (!active()) + newval = 0; + if (value(newval)) { + if (newval) { + Fl::add_timeout(INITIALREPEAT,repeat_callback,this); + do_callback(); + } else { + Fl::remove_timeout(repeat_callback,this); + } + } + return 1; + default: + return Fl_Button::handle(event); + } +} + +// +// End of "$Id: Fl_Repeat_Button.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Return_Button.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Return_Button.cxx new file mode 100644 index 0000000..42db047 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Return_Button.cxx @@ -0,0 +1,73 @@ +// +// "$Id: Fl_Return_Button.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Return button widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include + +int fl_return_arrow(int x, int y, int w, int h) { + int size = w; if (h +#include +#include +#include + +int Fl_Roller::handle(int event) { + static int ipos; + int newpos = horizontal() ? Fl::event_x() : Fl::event_y(); + switch (event) { + case FL_PUSH: + if (Fl::visible_focus()) { + Fl::focus(this); + redraw(); + } + handle_push(); + ipos = newpos; + return 1; + case FL_DRAG: + handle_drag(clamp(round(increment(previous_value(),newpos-ipos)))); + return 1; + case FL_RELEASE: + handle_release(); + return 1; + case FL_KEYBOARD : + switch (Fl::event_key()) { + case FL_Up: + if (horizontal()) return 0; + handle_drag(clamp(increment(value(),-1))); + return 1; + case FL_Down: + if (horizontal()) return 0; + handle_drag(clamp(increment(value(),1))); + return 1; + case FL_Left: + if (!horizontal()) return 0; + handle_drag(clamp(increment(value(),-1))); + return 1; + case FL_Right: + if (!horizontal()) return 0; + handle_drag(clamp(increment(value(),1))); + return 1; + default: + return 0; + } + // break not required because of switch... + case FL_FOCUS : + case FL_UNFOCUS : + if (Fl::visible_focus()) { + redraw(); + return 1; + } else return 0; + case FL_ENTER : + case FL_LEAVE : + return 1; + default: + return 0; + } +} + +void Fl_Roller::draw() { + if (damage()&FL_DAMAGE_ALL) draw_box(); + int X = x()+Fl::box_dx(box()); + int Y = y()+Fl::box_dy(box()); + int W = w()-Fl::box_dw(box())-1; + int H = h()-Fl::box_dh(box())-1; + if (W<=0 || H <=0) return; + int offset = step() ? int(value()/step()) : 0; + const double ARC = 1.5; // 1/2 the number of radians visible + const double delta = .2; // radians per knurl + if (horizontal()) { // horizontal one + // draw shaded ends of wheel: + int h1 = W/4+1; // distance from end that shading starts + fl_color(color()); fl_rectf(X+h1,Y,W-2*h1,H); + for (int i=0; h1; i++) { + fl_color((Fl_Color)(FL_GRAY-i-1)); + int h2 = FL_GRAY-i-1 > FL_DARK3 ? 2*h1/3+1 : 0; + fl_rectf(X+h2,Y,h1-h2,H); + fl_rectf(X+W-h1,Y,h1-h2,H); + h1 = h2; + } + if (active_r()) { + // draw ridges: + double junk; + for (double yy = -ARC+modf(offset*sin(ARC)/(W/2)/delta,&junk)*delta;; + yy += delta) { + int yy1 = int((sin(yy)/sin(ARC)+1)*W/2); + if (yy1 <= 0) continue; else if (yy1 >= W-1) break; + fl_color(FL_DARK3); fl_yxline(X+yy1,Y+1,Y+H-1); + if (yy < 0) yy1--; else yy1++; + fl_color(FL_LIGHT1);fl_yxline(X+yy1,Y+1,Y+H-1); + } + // draw edges: + h1 = W/8+1; // distance from end the color inverts + fl_color(FL_DARK2); + fl_xyline(X+h1,Y+H-1,X+W-h1); + fl_color(FL_DARK3); + fl_yxline(X,Y+H,Y,X+h1); + fl_xyline(X+W-h1,Y,X+W); + fl_color(FL_LIGHT2); + fl_xyline(X+h1,Y-1,X+W-h1); + fl_yxline(X+W,Y,Y+H,X+W-h1); + fl_xyline(X+h1,Y+H,X); + } + } else { // vertical one + // draw shaded ends of wheel: + int h1 = H/4+1; // distance from end that shading starts + fl_color(color()); fl_rectf(X,Y+h1,W,H-2*h1); + for (int i=0; h1; i++) { + fl_color((Fl_Color)(FL_GRAY-i-1)); + int h2 = FL_GRAY-i-1 > FL_DARK3 ? 2*h1/3+1 : 0; + fl_rectf(X,Y+h2,W,h1-h2); + fl_rectf(X,Y+H-h1,W,h1-h2); + h1 = h2; + } + if (active_r()) { + // draw ridges: + double junk; + for (double yy = -ARC+modf(offset*sin(ARC)/(H/2)/delta,&junk)*delta; + ; yy += delta) { + int yy1 = int((sin(yy)/sin(ARC)+1)*H/2); + if (yy1 <= 0) continue; else if (yy1 >= H-1) break; + fl_color(FL_DARK3); fl_xyline(X+1,Y+yy1,X+W-1); + if (yy < 0) yy1--; else yy1++; + fl_color(FL_LIGHT1);fl_xyline(X+1,Y+yy1,X+W-1); + } + // draw edges: + h1 = H/8+1; // distance from end the color inverts + fl_color(FL_DARK2); + fl_yxline(X+W-1,Y+h1,Y+H-h1); + fl_color(FL_DARK3); + fl_xyline(X+W,Y,X,Y+h1); + fl_yxline(X,Y+H-h1,Y+H); + fl_color(FL_LIGHT2); + fl_yxline(X,Y+h1,Y+H-h1); + fl_xyline(X,Y+H,X+W,Y+H-h1); + fl_yxline(X+W,Y+h1,Y); + } + } + + if (Fl::focus() == this) draw_focus(FL_THIN_UP_FRAME, x(), y(), w(), h()); +} + +/** + Creates a new Fl_Roller widget using the given position, + size, and label string. The default boxtype is FL_NO_BOX. +

      Inherited destructor destroys the valuator. +*/ +Fl_Roller::Fl_Roller(int X,int Y,int W,int H,const char* L) + : Fl_Valuator(X,Y,W,H,L) { + box(FL_UP_BOX); + step(1,1000); +} + +// +// End of "$Id: Fl_Roller.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Round_Button.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Round_Button.cxx new file mode 100644 index 0000000..f972076 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Round_Button.cxx @@ -0,0 +1,48 @@ +// +// "$Id: Fl_Round_Button.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Round button for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// A subclass of Fl_Button that always draws as a round circle. This +// circle is smaller than the widget size and can be surrounded by +// another box type, for compatibility with Forms. + +#include +#include + +/** + Creates a new Fl_Round_Button widget using the given + position, size, and label string. +*/ +Fl_Round_Button::Fl_Round_Button(int X,int Y,int W,int H, const char *l) +: Fl_Light_Button(X,Y,W,H,l) { + box(FL_NO_BOX); + down_box(FL_ROUND_DOWN_BOX); + selection_color(FL_FOREGROUND_COLOR); +} + +// +// End of "$Id: Fl_Round_Button.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Scroll.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Scroll.cxx new file mode 100644 index 0000000..681a61c --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Scroll.cxx @@ -0,0 +1,420 @@ +// +// "$Id: Fl_Scroll.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Scroll widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include +#include + +/** Clear all but the scrollbars... */ +void Fl_Scroll::clear() { + // Note: the scrollbars are removed from the group before calling + // Fl_Group::clear() to take advantage of the optimized widget removal + // and deletion. Finally they are added to Fl_Scroll's group again. This + // is MUCH faster than removing the widgets one by one (STR #2409). + + remove(scrollbar); + remove(hscrollbar); + Fl_Group::clear(); + add(hscrollbar); + add(scrollbar); +} + +/** Insure the scrollbars are the last children */ +void Fl_Scroll::fix_scrollbar_order() { + Fl_Widget** a = (Fl_Widget**)array(); + if (a[children()-1] != &scrollbar) { + int i,j; for (i = j = 0; j < children(); j++) + if (a[j] != &hscrollbar && a[j] != &scrollbar) a[i++] = a[j]; + a[i++] = &hscrollbar; + a[i++] = &scrollbar; + } +} + +// Draw widget's background and children within a specific clip region +// So widget can just redraw damaged parts. +// +void Fl_Scroll::draw_clip(void* v,int X, int Y, int W, int H) { + fl_push_clip(X,Y,W,H); + Fl_Scroll* s = (Fl_Scroll*)v; + // erase background as needed... + switch (s->box()) { + case FL_NO_BOX : + case FL_UP_FRAME : + case FL_DOWN_FRAME : + case FL_THIN_UP_FRAME : + case FL_THIN_DOWN_FRAME : + case FL_ENGRAVED_FRAME : + case FL_EMBOSSED_FRAME : + case FL_BORDER_FRAME : + case _FL_SHADOW_FRAME : + case _FL_ROUNDED_FRAME : + case _FL_OVAL_FRAME : + case _FL_PLASTIC_UP_FRAME : + case _FL_PLASTIC_DOWN_FRAME : + if (s->parent() == (Fl_Group *)s->window() && Fl::scheme_bg_) { + Fl::scheme_bg_->draw(X-(X%((Fl_Tiled_Image *)Fl::scheme_bg_)->image()->w()), + Y-(Y%((Fl_Tiled_Image *)Fl::scheme_bg_)->image()->h()), + W+((Fl_Tiled_Image *)Fl::scheme_bg_)->image()->w(), + H+((Fl_Tiled_Image *)Fl::scheme_bg_)->image()->h()); + break; + } + + default : + fl_color(s->color()); + fl_rectf(X,Y,W,H); + break; + } + Fl_Widget*const* a = s->array(); + for (int i=s->children()-2; i--;) { + Fl_Widget& o = **a++; + s->draw_child(o); + s->draw_outside_label(o); + } + fl_pop_clip(); +} + +/** + Calculate visibility/size/position of scrollbars, find children's bounding box. + The \p si paramater will be filled with data from the calculations. + Derived classes can make use of this call to figure out the scrolling area + eg. during resize() handling. + \param[in] si -- ScrollInfo structure + \returns Structure containing the calculated info. +*/ +void Fl_Scroll::recalc_scrollbars(ScrollInfo &si) { + + // inner box of widget (excluding scrollbars) + si.innerbox_x = x()+Fl::box_dx(box()); + si.innerbox_y = y()+Fl::box_dy(box()); + si.innerbox_w = w()-Fl::box_dw(box()); + si.innerbox_h = h()-Fl::box_dh(box()); + + // accumulate a bounding box for all the children + si.child_l = si.innerbox_x; + si.child_r = si.innerbox_x; + si.child_b = si.innerbox_y; + si.child_t = si.innerbox_y; + int first = 1; + Fl_Widget*const* a = array(); + for (int i=children()-2; i--;) { + Fl_Widget* o = *a++; + if ( first ) { + first = 0; + si.child_l = o->x(); + si.child_r = o->x()+o->w(); + si.child_b = o->y()+o->h(); + si.child_t = o->y(); + } else { + if (o->x() < si.child_l) si.child_l = o->x(); + if (o->y() < si.child_t) si.child_t = o->y(); + if (o->x()+o->w() > si.child_r) si.child_r = o->x()+o->w(); + if (o->y()+o->h() > si.child_b) si.child_b = o->y()+o->h(); + } + } + + // Turn the scrollbars on and off as necessary. + // See if children would fit if we had no scrollbars... + { + int X = si.innerbox_x; + int Y = si.innerbox_y; + int W = si.innerbox_w; + int H = si.innerbox_h; + + si.scrollsize = scrollbar_size_ ? scrollbar_size_ : Fl::scrollbar_size(); + si.vneeded = 0; + si.hneeded = 0; + if (type() & VERTICAL) { + if ((type() & ALWAYS_ON) || si.child_t < Y || si.child_b > Y+H) { + si.vneeded = 1; + W -= si.scrollsize; + if (scrollbar.align() & FL_ALIGN_LEFT) X += si.scrollsize; + } + } + if (type() & HORIZONTAL) { + if ((type() & ALWAYS_ON) || si.child_l < X || si.child_r > X+W) { + si.hneeded = 1; + H -= si.scrollsize; + if (scrollbar.align() & FL_ALIGN_TOP) Y += si.scrollsize; + // recheck vertical since we added a horizontal scrollbar + if (!si.vneeded && (type() & VERTICAL)) { + if ((type() & ALWAYS_ON) || si.child_t < Y || si.child_b > Y+H) { + si.vneeded = 1; + W -= si.scrollsize; + if (scrollbar.align() & FL_ALIGN_LEFT) X += si.scrollsize; + } + } + } + } + si.innerchild_x = X; + si.innerchild_y = Y; + si.innerchild_w = W; + si.innerchild_h = H; + } + + // calculate hor scrollbar position + si.hscroll_x = si.innerchild_x; + si.hscroll_y = (scrollbar.align() & FL_ALIGN_TOP) + ? si.innerbox_y + : si.innerbox_y + si.innerbox_h - si.scrollsize; + si.hscroll_w = si.innerchild_w; + si.hscroll_h = si.scrollsize; + + // calculate ver scrollbar position + si.vscroll_x = (scrollbar.align() & FL_ALIGN_LEFT) + ? si.innerbox_x + : si.innerbox_x + si.innerbox_w - si.scrollsize; + si.vscroll_y = si.innerchild_y; + si.vscroll_w = si.scrollsize; + si.vscroll_h = si.innerchild_h; + + // calculate h/v scrollbar values (pos/size/first/total) + si.hpos = si.innerchild_x - si.child_l; + si.hsize = si.innerchild_w; + si.hfirst = 0; + si.htotal = si.child_r - si.child_l; + if ( si.hpos < 0 ) { si.htotal += (-si.hpos); si.hfirst = si.hpos; } + + si.vpos = si.innerchild_y - si.child_t; + si.vsize = si.innerchild_h; + si.vfirst = 0; + si.vtotal = si.child_b - si.child_t; + if ( si.vpos < 0 ) { si.vtotal += (-si.vpos); si.vfirst = si.vpos; } + +// printf("DEBUG --- ScrollInfo ---\n"); +// printf("DEBUG scrollsize: %d\n", si.scrollsize); +// printf("DEBUG hneeded, vneeded: %d %d\n", si.hneeded, si.vneeded); +// printf("DEBUG innerbox xywh: %d %d %d %d\n", si.innerbox_x, si.innerbox_y, si.innerbox_w, si.innerbox_h); +// printf("DEBUG innerchild xywh: %d %d %d %d\n", si.innerchild_x, si.innerchild_y, si.innerchild_w, si.innerchild_h); +// printf("DEBUG child lrbt: %d %d %d %d\n", si.child_l, si.child_r, si.child_b, si.child_t); +// printf("DEBUG hscroll xywh: %d %d %d %d\n", si.hscroll_x, si.hscroll_y, si.hscroll_w, si.hscroll_h); +// printf("DEBUG vscroll xywh: %d %d %d %d\n", si.vscroll_x, si.vscroll_y, si.vscroll_w, si.vscroll_h); +// printf("DEBUG horz scroll vals: %d %d %d %d\n", si.hpos, si.hsize, si.hfirst, si.htotal); +// printf("DEBUG vert scroll vals: %d %d %d %d\n", si.vpos, si.vsize, si.vfirst, si.vtotal); +// printf("DEBUG \n"); +} + +/** + Returns the bounding box for the interior of the scrolling area, inside + the scrollbars. + + Currently this is only reliable after draw(), and before any resizing of + the Fl_Scroll or any child widgets occur. + + \todo The visibility of the scrollbars ought to be checked/calculated + outside of the draw() method (STR #1895). +*/ +void Fl_Scroll::bbox(int& X, int& Y, int& W, int& H) { + X = x()+Fl::box_dx(box()); + Y = y()+Fl::box_dy(box()); + W = w()-Fl::box_dw(box()); + H = h()-Fl::box_dh(box()); + if (scrollbar.visible()) { + W -= scrollbar.w(); + if (scrollbar.align() & FL_ALIGN_LEFT) X += scrollbar.w(); + } + if (hscrollbar.visible()) { + H -= hscrollbar.h(); + if (scrollbar.align() & FL_ALIGN_TOP) Y += hscrollbar.h(); + } +} + +void Fl_Scroll::draw() { + fix_scrollbar_order(); + int X,Y,W,H; bbox(X,Y,W,H); + + uchar d = damage(); + + if (d & FL_DAMAGE_ALL) { // full redraw + draw_box(box(),x(),y(),w(),h(),color()); + draw_clip(this, X, Y, W, H); + } else { + if (d & FL_DAMAGE_SCROLL) { + // scroll the contents: + fl_scroll(X, Y, W, H, oldx-xposition_, oldy-yposition_, draw_clip, this); + + // Erase the background as needed... + Fl_Widget*const* a = array(); + int L, R, T, B; + L = 999999; + R = 0; + T = 999999; + B = 0; + for (int i=children()-2; i--; a++) { + if ((*a)->x() < L) L = (*a)->x(); + if (((*a)->x() + (*a)->w()) > R) R = (*a)->x() + (*a)->w(); + if ((*a)->y() < T) T = (*a)->y(); + if (((*a)->y() + (*a)->h()) > B) B = (*a)->y() + (*a)->h(); + } + if (L > X) draw_clip(this, X, Y, L - X, H); + if (R < (X + W)) draw_clip(this, R, Y, X + W - R, H); + if (T > Y) draw_clip(this, X, Y, W, T - Y); + if (B < (Y + H)) draw_clip(this, X, B, W, Y + H - B); + } + if (d & FL_DAMAGE_CHILD) { // draw damaged children + fl_push_clip(X, Y, W, H); + Fl_Widget*const* a = array(); + for (int i=children()-2; i--;) update_child(**a++); + fl_pop_clip(); + } + } + + // Calculate where scrollbars should go, and draw them + { + ScrollInfo si; + recalc_scrollbars(si); + + // Now that we know what's needed, make it so. + if (si.vneeded && !scrollbar.visible()) { + scrollbar.set_visible(); + d = FL_DAMAGE_ALL; + } + else if (!si.vneeded && scrollbar.visible()) { + scrollbar.clear_visible(); + draw_clip(this, si.vscroll_x, si.vscroll_y, si.vscroll_w, si.vscroll_h); + d = FL_DAMAGE_ALL; + } + if (si.hneeded && !hscrollbar.visible()) { + hscrollbar.set_visible(); + d = FL_DAMAGE_ALL; + } + else if (!si.hneeded && hscrollbar.visible()) { + hscrollbar.clear_visible(); + draw_clip(this, si.hscroll_x, si.hscroll_y, si.hscroll_w, si.hscroll_h); + d = FL_DAMAGE_ALL; + } + else if ( hscrollbar.h() != si.scrollsize || scrollbar.w() != si.scrollsize ) { + // scrollsize changed + d = FL_DAMAGE_ALL; + } + + scrollbar.resize(si.vscroll_x, si.vscroll_y, si.vscroll_w, si.vscroll_h); + oldy = yposition_ = si.vpos; // si.innerchild_y - si.child_t; + scrollbar.value(si.vpos, si.vsize, si.vfirst, si.vtotal); + + hscrollbar.resize(si.hscroll_x, si.hscroll_y, si.hscroll_w, si.hscroll_h); + oldx = xposition_ = si.hpos; // si.innerchild_x - si.child_l; + hscrollbar.value(si.hpos, si.hsize, si.hfirst, si.htotal); + } + + // draw the scrollbars: + if (d & FL_DAMAGE_ALL) { + draw_child(scrollbar); + draw_child(hscrollbar); + if (scrollbar.visible() && hscrollbar.visible()) { + // fill in the little box in the corner + fl_color(color()); + fl_rectf(scrollbar.x(), hscrollbar.y(), scrollbar.w(), hscrollbar.h()); + } + } else { + update_child(scrollbar); + update_child(hscrollbar); + } +} + +void Fl_Scroll::resize(int X, int Y, int W, int H) { + int dx = X-x(), dy = Y-y(); + int dw = W-w(), dh = H-h(); + Fl_Widget::resize(X,Y,W,H); // resize _before_ moving children around + fix_scrollbar_order(); + // move all the children: + Fl_Widget*const* a = array(); + for (int i=children()-2; i--;) { + Fl_Widget* o = *a++; + o->position(o->x()+dx, o->y()+dy); + } + if (dw==0 && dh==0) { + char pad = ( scrollbar.visible() && hscrollbar.visible() ); + char al = ( (scrollbar.align() & FL_ALIGN_LEFT) != 0 ); + char at = ( (scrollbar.align() & FL_ALIGN_TOP) !=0 ); + scrollbar.position(al?X:X+W-scrollbar.w(), (at&&pad)?Y+hscrollbar.h():Y); + hscrollbar.position((al&&pad)?X+scrollbar.w():X, at?Y:Y+H-hscrollbar.h()); + } else { + // FIXME recalculation of scrollbars needs to be moved out fo "draw()" (STR #1895) + redraw(); // need full recalculation of scrollbars + } +} + +/** Moves the contents of the scroll group to a new position.*/ +void Fl_Scroll::scroll_to(int X, int Y) { + int dx = xposition_-X; + int dy = yposition_-Y; + if (!dx && !dy) return; + xposition_ = X; + yposition_ = Y; + Fl_Widget*const* a = array(); + for (int i=children(); i--;) { + Fl_Widget* o = *a++; + if (o == &hscrollbar || o == &scrollbar) continue; + o->position(o->x()+dx, o->y()+dy); + } + if (parent() == (Fl_Group *)window() && Fl::scheme_bg_) damage(FL_DAMAGE_ALL); + else damage(FL_DAMAGE_SCROLL); +} + +void Fl_Scroll::hscrollbar_cb(Fl_Widget* o, void*) { + Fl_Scroll* s = (Fl_Scroll*)(o->parent()); + s->scroll_to(int(((Fl_Scrollbar*)o)->value()), s->yposition()); +} + +void Fl_Scroll::scrollbar_cb(Fl_Widget* o, void*) { + Fl_Scroll* s = (Fl_Scroll*)(o->parent()); + s->scroll_to(s->xposition(), int(((Fl_Scrollbar*)o)->value())); +} +/** + Creates a new Fl_Scroll widget using the given position, + size, and label string. The default boxtype is FL_NO_BOX. +

      The destructor also deletes all the children. This allows a + whole tree to be deleted at once, without having to keep a pointer to + all the children in the user code. A kludge has been done so the + Fl_Scroll and all of it's children can be automatic (local) + variables, but you must declare the Fl_Scrollfirst, so + that it is destroyed last. +*/ +Fl_Scroll::Fl_Scroll(int X,int Y,int W,int H,const char* L) + : Fl_Group(X,Y,W,H,L), + scrollbar(X+W-Fl::scrollbar_size(),Y, + Fl::scrollbar_size(),H-Fl::scrollbar_size()), + hscrollbar(X,Y+H-Fl::scrollbar_size(), + W-Fl::scrollbar_size(),Fl::scrollbar_size()) { + type(BOTH); + xposition_ = oldx = 0; + yposition_ = oldy = 0; + scrollbar_size_ = 0; + hscrollbar.type(FL_HORIZONTAL); + hscrollbar.callback(hscrollbar_cb); + scrollbar.callback(scrollbar_cb); +} + +int Fl_Scroll::handle(int event) { + fix_scrollbar_order(); + return Fl_Group::handle(event); +} + +// +// End of "$Id: Fl_Scroll.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Scrollbar.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Scrollbar.cxx new file mode 100644 index 0000000..263e664 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Scrollbar.cxx @@ -0,0 +1,292 @@ +// +// "$Id: Fl_Scrollbar.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Scroll bar widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + + +#include +#include +#include +#include +#include "flstring.h" + +#define INITIALREPEAT .5 +#define REPEAT .05 + +void Fl_Scrollbar::increment_cb() { + char inv = maximum()-ls) i = -ls; // err + } + break; + case 6: // clicked into the box next to the slider on the right + i = (int((maximum()-minimum())*slider_size()/(1.0-slider_size()))); + if (inv) { + if (i>ls) i = ls; + } else { + if (iincrement_cb(); + Fl::add_timeout(REPEAT, timeout_cb, s); +} + +int Fl_Scrollbar::handle(int event) { + // area of scrollbar: + int area; + int X=x(); int Y=y(); int W=w(); int H=h(); + + // adjust slider area to be inside the arrow buttons: + if (horizontal()) { + if (W >= 3*H) {X += H; W -= 2*H;} + } else { + if (H >= 3*W) {Y += W; H -= 2*W;} + } + + // which widget part is highlighted? + int relx; + int ww; + if (horizontal()) { + relx = Fl::event_x()-X; + ww = W; + } else { + relx = Fl::event_y()-Y; + ww = H; + } + if (relx < 0) area = 1; + else if (relx >= ww) area = 2; + else { + int S = int(slider_size()*ww+.5); + int T = (horizontal() ? H : W)/2+1; + if (type()==FL_VERT_NICE_SLIDER || type()==FL_HOR_NICE_SLIDER) T += 4; + if (S < T) S = T; + double val = + (maximum()-minimum()) ? (value()-minimum())/(maximum()-minimum()) : 0.5; + int sliderx; + if (val >= 1.0) sliderx = ww-S; + else if (val <= 0.0) sliderx = 0; + else sliderx = int(val*(ww-S)+.5); + if (Fl::event_button() == FL_MIDDLE_MOUSE) area = 8; + else if (relx < sliderx) area = 5; + else if (relx >= sliderx+S) area = 6; + else area = 8; + } + + switch (event) { + case FL_ENTER: + case FL_LEAVE: + return 1; + case FL_RELEASE: + damage(FL_DAMAGE_ALL); + if (pushed_) { + Fl::remove_timeout(timeout_cb, this); + pushed_ = 0; + } + handle_release(); + return 1; + case FL_PUSH: + if (pushed_) return 1; + if (area != 8) pushed_ = area; + if (pushed_) { + handle_push(); + Fl::add_timeout(INITIALREPEAT, timeout_cb, this); + increment_cb(); + damage(FL_DAMAGE_ALL); + return 1; + } + return Fl_Slider::handle(event, X,Y,W,H); + case FL_DRAG: + if (pushed_) return 1; + return Fl_Slider::handle(event, X,Y,W,H); + case FL_MOUSEWHEEL : + if (horizontal()) { + if (Fl::e_dx==0) return 0; + int ls = maximum()>=minimum() ? linesize_ : -linesize_; + handle_drag(clamp(value() + ls * Fl::e_dx)); + return 1; + } else { + if (Fl::e_dy==0) return 0; + int ls = maximum()>=minimum() ? linesize_ : -linesize_; + handle_drag(clamp(value() + ls * Fl::e_dy)); + return 1; + } + case FL_SHORTCUT: + case FL_KEYBOARD: { + int v = value(); + int ls = maximum()>=minimum() ? linesize_ : -linesize_; + if (horizontal()) { + switch (Fl::event_key()) { + case FL_Left: + v -= ls; + break; + case FL_Right: + v += ls; + break; + default: + return 0; + } + } else { // vertical + switch (Fl::event_key()) { + case FL_Up: + v -= ls; + break; + case FL_Down: + v += ls; + break; + case FL_Page_Up: + if (slider_size() >= 1.0) return 0; + v -= int((maximum()-minimum())*slider_size()/(1.0-slider_size())); + v += ls; + break; + case FL_Page_Down: + if (slider_size() >= 1.0) return 0; + v += int((maximum()-minimum())*slider_size()/(1.0-slider_size())); + v -= ls; + break; + case FL_Home: + v = int(minimum()); + break; + case FL_End: + v = int(maximum()); + break; + default: + return 0; + } + } + v = int(clamp(v)); + if (v != value()) { + Fl_Slider::value(v); + value_damage(); + set_changed(); + do_callback(); + } + return 1;} + } + return 0; +} + +void Fl_Scrollbar::draw() { + if (damage()&FL_DAMAGE_ALL) draw_box(); + int X = x()+Fl::box_dx(box()); + int Y = y()+Fl::box_dy(box()); + int W = w()-Fl::box_dw(box()); + int H = h()-Fl::box_dh(box()); + if (horizontal()) { + if (W < 3*H) {Fl_Slider::draw(X,Y,W,H); return;} + Fl_Slider::draw(X+H,Y,W-2*H,H); + if (damage()&FL_DAMAGE_ALL) { + draw_box((pushed_==1) ? fl_down(slider()) : slider(), + X, Y, H, H, selection_color()); + draw_box((pushed_==2) ? fl_down(slider()) : slider(), + X+W-H, Y, H, H, selection_color()); + if (active_r()) + fl_color(labelcolor()); + else + fl_color(fl_inactive(labelcolor())); + int w1 = (H-4)/3; if (w1 < 1) w1 = 1; + int x1 = X+(H-w1-1)/2; + int yy1 = Y+(H-2*w1-1)/2; + if (Fl::scheme_ && !strcmp(Fl::scheme_, "gtk+")) { + fl_polygon(x1, yy1+w1, x1+w1, yy1+2*w1, x1+w1-1, yy1+w1, x1+w1, yy1); + x1 += (W-H); + fl_polygon(x1, yy1, x1+1, yy1+w1, x1, yy1+2*w1, x1+w1, yy1+w1); + } else { + fl_polygon(x1, yy1+w1, x1+w1, yy1+2*w1, x1+w1, yy1); + x1 += (W-H); + fl_polygon(x1, yy1, x1, yy1+2*w1, x1+w1, yy1+w1); + } + } + } else { // vertical + if (H < 3*W) {Fl_Slider::draw(X,Y,W,H); return;} + Fl_Slider::draw(X,Y+W,W,H-2*W); + if (damage()&FL_DAMAGE_ALL) { + draw_box((pushed_==1) ? fl_down(slider()) : slider(), + X, Y, W, W, selection_color()); + draw_box((pushed_==2) ? fl_down(slider()) : slider(), + X, Y+H-W, W, W, selection_color()); + if (active_r()) + fl_color(labelcolor()); + else + fl_color(fl_inactive(labelcolor())); + int w1 = (W-4)/3; if (w1 < 1) w1 = 1; + int x1 = X+(W-2*w1-1)/2; + int yy1 = Y+(W-w1-1)/2; + if (Fl::scheme_ && !strcmp(Fl::scheme_, "gtk+")) { + fl_polygon(x1, yy1+w1, x1+w1, yy1+w1-1, x1+2*w1, yy1+w1, x1+w1, yy1); + yy1 += H-W; + fl_polygon(x1, yy1, x1+w1, yy1+1, x1+w1, yy1+w1); + fl_polygon(x1+w1, yy1+1, x1+2*w1, yy1, x1+w1, yy1+w1); + } else { + fl_polygon(x1, yy1+w1, x1+2*w1, yy1+w1, x1+w1, yy1); + yy1 += H-W; + fl_polygon(x1, yy1, x1+w1, yy1+w1, x1+2*w1, yy1); + } + } + } +} + +/** + Creates a new Fl_Scrollbar widget with given position, size, and label. + You need to do type(FL_HORIZONTAL) if you want a horizontal scrollbar. +*/ +Fl_Scrollbar::Fl_Scrollbar(int X, int Y, int W, int H, const char* L) + : Fl_Slider(X, Y, W, H, L) { + box(FL_FLAT_BOX); + color(FL_DARK2); + slider(FL_UP_BOX); + linesize_ = 16; + pushed_ = 0; + step(1); +} + +/** Destroys the Scrollbar. */ +Fl_Scrollbar::~Fl_Scrollbar() { + if (pushed_) + Fl::remove_timeout(timeout_cb, this); +} + + +// +// End of "$Id: Fl_Scrollbar.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Shared_Image.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Shared_Image.cxx new file mode 100644 index 0000000..82c9c70 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Shared_Image.cxx @@ -0,0 +1,463 @@ +// +// "$Id: Fl_Shared_Image.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Shared image code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include +#include "flstring.h" + +#include +#include +#include +#include + + +// +// Global class vars... +// + +Fl_Shared_Image **Fl_Shared_Image::images_ = 0; // Shared images +int Fl_Shared_Image::num_images_ = 0; // Number of shared images +int Fl_Shared_Image::alloc_images_ = 0; // Allocated shared images + +Fl_Shared_Handler *Fl_Shared_Image::handlers_ = 0;// Additional format handlers +int Fl_Shared_Image::num_handlers_ = 0; // Number of format handlers +int Fl_Shared_Image::alloc_handlers_ = 0; // Allocated format handlers + + +// +// Typedef the C API sort function type the only way I know how... +// + +extern "C" { + typedef int (*compare_func_t)(const void *, const void *); +} + + +/** Returns the Fl_Shared_Image* array */ +Fl_Shared_Image **Fl_Shared_Image::images() { + return images_; +} +/** Returns the total number of shared images in the array. */ +int Fl_Shared_Image::num_images() { + return num_images_; +} + + +// +// 'Fl_Shared_Image::compare()' - Compare two shared images... +// + +int +Fl_Shared_Image::compare(Fl_Shared_Image **i0, // I - First image + Fl_Shared_Image **i1) { // I - Second image + int i = strcmp((*i0)->name(), (*i1)->name()); + + if (i) return i; + else if (((*i0)->w() == 0 && (*i1)->original_) || + ((*i1)->w() == 0 && (*i0)->original_)) return 0; + else if ((*i0)->w() != (*i1)->w()) return (*i0)->w() - (*i1)->w(); + else return (*i0)->h() - (*i1)->h(); +} + + +/** + Creates an empty shared image. + The constructors create a new shared image record in the image cache. + +

      The constructors are protected and cannot be used directly + from a program. Use the get() method instead. +*/ +Fl_Shared_Image::Fl_Shared_Image() : Fl_Image(0,0,0) { + name_ = 0; + refcount_ = 1; + original_ = 0; + image_ = 0; + alloc_image_ = 0; +} + + +/** + Creates a shared image from its filename and its corresponding Fl_Image* img. + The constructors create a new shared image record in the image cache. + +

      The constructors are protected and cannot be used directly + from a program. Use the get() method instead. +*/ +Fl_Shared_Image::Fl_Shared_Image(const char *n, // I - Filename + Fl_Image *img) // I - Image + : Fl_Image(0,0,0) { + name_ = new char[strlen(n) + 1]; + strcpy((char *)name_, n); + + refcount_ = 1; + image_ = img; + alloc_image_ = !img; + original_ = 1; + + if (!img) reload(); + else update(); +} + + +// +// 'Fl_Shared_Image::add()' - Add a shared image to the array. +// + +void +Fl_Shared_Image::add() { + Fl_Shared_Image **temp; // New image pointer array... + + if (num_images_ >= alloc_images_) { + // Allocate more memory... + temp = new Fl_Shared_Image *[alloc_images_ + 32]; + + if (alloc_images_) { + memcpy(temp, images_, alloc_images_ * sizeof(Fl_Shared_Image *)); + + delete[] images_; + } + + images_ = temp; + alloc_images_ += 32; + } + + images_[num_images_] = this; + num_images_ ++; + + if (num_images_ > 1) { + qsort(images_, num_images_, sizeof(Fl_Shared_Image *), + (compare_func_t)compare); + } +} + + +// +// 'Fl_Shared_Image::update()' - Update the dimensions of the shared images. +// + +void +Fl_Shared_Image::update() { + if (image_) { + w(image_->w()); + h(image_->h()); + d(image_->d()); + data(image_->data(), image_->count()); + } +} + +/** + The destructor free all memory and server resources that are + used by the image. The destructor is protected and cannot be + used directly from a program. Use the Fl_Shared_Image::release() method + instead. +*/ +Fl_Shared_Image::~Fl_Shared_Image() { + if (name_) delete[] (char *)name_; + if (alloc_image_) delete image_; +} + + +// +/** + Releases and possibly destroys (if refcount <=0) a shared image. + In the latter case, it will reorganize the shared image array so that no hole will occur. +*/ +void Fl_Shared_Image::release() { + int i; // Looping var... + + refcount_ --; + if (refcount_ > 0) return; + + for (i = 0; i < num_images_; i ++) + if (images_[i] == this) { + num_images_ --; + + if (i < num_images_) { + memmove(images_ + i, images_ + i + 1, + (num_images_ - i) * sizeof(Fl_Shared_Image *)); + } + + break; + } + + delete this; + + if (num_images_ == 0 && images_) { + delete[] images_; + + images_ = 0; + alloc_images_ = 0; + } +} + + +// +/** Reloads the shared image from disk */ +void Fl_Shared_Image::reload() { + // Load image from disk... + int i; // Looping var + FILE *fp; // File pointer + uchar header[64]; // Buffer for auto-detecting files + Fl_Image *img; // New image + + if (!name_) return; + + if ((fp = fl_fopen(name_, "rb")) != NULL) { + if (fread(header, 1, sizeof(header), fp)==0) { /* ignore */ } + fclose(fp); + } else { + return; + } + + // Load the image as appropriate... + if (memcmp(header, "#define", 7) == 0) // XBM file + img = new Fl_XBM_Image(name_); + else if (memcmp(header, "/* XPM */", 9) == 0) // XPM file + img = new Fl_XPM_Image(name_); + else { + // Not a standard format; try an image handler... + for (i = 0, img = 0; i < num_handlers_; i ++) { + img = (handlers_[i])(name_, header, sizeof(header)); + + if (img) break; + } + } + + if (img) { + if (alloc_image_) delete image_; + + alloc_image_ = 1; + + if ((img->w() != w() && w()) || (img->h() != h() && h())) { + // Make sure the reloaded image is the same size as the existing one. + Fl_Image *temp = img->copy(w(), h()); + delete img; + image_ = temp; + } else { + image_ = img; + } + + update(); + } +} + + +// +// 'Fl_Shared_Image::copy()' - Copy and resize a shared image... +// + +Fl_Image * +Fl_Shared_Image::copy(int W, int H) { + Fl_Image *temp_image; // New image file + Fl_Shared_Image *temp_shared; // New shared image + + // Make a copy of the image we're sharing... + if (!image_) temp_image = 0; + else temp_image = image_->copy(W, H); + + // Then make a new shared image... + temp_shared = new Fl_Shared_Image(); + + temp_shared->name_ = new char[strlen(name_) + 1]; + strcpy((char *)temp_shared->name_, name_); + + temp_shared->refcount_ = 1; + temp_shared->image_ = temp_image; + temp_shared->alloc_image_ = 1; + + temp_shared->update(); + + return temp_shared; +} + + +// +// 'Fl_Shared_Image::color_average()' - Blend colors... +// + +void +Fl_Shared_Image::color_average(Fl_Color c, // I - Color to blend with + float i) { // I - Blend fraction + if (!image_) return; + + image_->color_average(c, i); + update(); +} + + +// +// 'Fl_Shared_Image::desaturate()' - Convert the image to grayscale... +// + +void +Fl_Shared_Image::desaturate() { + if (!image_) return; + + image_->desaturate(); + update(); +} + + +// +// 'Fl_Shared_Image::draw()' - Draw a shared image... +// + +void +Fl_Shared_Image::draw(int X, int Y, int W, int H, int cx, int cy) { + if (image_) image_->draw(X, Y, W, H, cx, cy); + else Fl_Image::draw(X, Y, W, H, cx, cy); +} + + +// +// 'Fl_Shared_Image::uncache()' - Uncache the shared image... +// + +void Fl_Shared_Image::uncache() +{ + if (image_) image_->uncache(); +} + + + +/** Finds a shared image from its named and size specifications */ +Fl_Shared_Image* Fl_Shared_Image::find(const char *n, int W, int H) { + Fl_Shared_Image *key, // Image key + **match; // Matching image + + if (num_images_) { + key = new Fl_Shared_Image(); + key->name_ = new char[strlen(n) + 1]; + strcpy((char *)key->name_, n); + key->w(W); + key->h(H); + + match = (Fl_Shared_Image **)bsearch(&key, images_, num_images_, + sizeof(Fl_Shared_Image *), + (compare_func_t)compare); + + delete key; + + if (match) { + (*match)->refcount_ ++; + return *match; + } + } + + return 0; +} + + +/** + Gets a shared image, if it exists already ; it will return it. + If it does not exist or if it exist but with other size, + then the existing image is deleted and replaced + by a new image from the n filename of the proper dimension. + If n is not a valid image filename, then get() will return NULL. +*/ +Fl_Shared_Image* Fl_Shared_Image::get(const char *n, int W, int H) { + Fl_Shared_Image *temp; // Image + + if ((temp = find(n, W, H)) != NULL) return temp; + + if ((temp = find(n)) == NULL) { + temp = new Fl_Shared_Image(n); + + if (!temp->image_) { + delete temp; + return NULL; + } + + temp->add(); + } + + if ((temp->w() != W || temp->h() != H) && W && H) { + temp = (Fl_Shared_Image *)temp->copy(W, H); + temp->add(); + } + + return temp; +} + + + +/** Adds a shared image handler, which is basically a test function for adding new formats */ +void Fl_Shared_Image::add_handler(Fl_Shared_Handler f) { + int i; // Looping var... + Fl_Shared_Handler *temp; // New image handler array... + + // First see if we have already added the handler... + for (i = 0; i < num_handlers_; i ++) { + if (handlers_[i] == f) return; + } + + if (num_handlers_ >= alloc_handlers_) { + // Allocate more memory... + temp = new Fl_Shared_Handler [alloc_handlers_ + 32]; + + if (alloc_handlers_) { + memcpy(temp, handlers_, alloc_handlers_ * sizeof(Fl_Shared_Handler)); + + delete[] handlers_; + } + + handlers_ = temp; + alloc_handlers_ += 32; + } + + handlers_[num_handlers_] = f; + num_handlers_ ++; +} + + + +/** Removes a shared image handler */ +void Fl_Shared_Image::remove_handler(Fl_Shared_Handler f) { + int i; // Looping var... + + // First see if the handler has been added... + for (i = 0; i < num_handlers_; i ++) { + if (handlers_[i] == f) break; + } + + if (i >= num_handlers_) return; + + // OK, remove the handler from the array... + num_handlers_ --; + + if (i < num_handlers_) { + // Shift later handlers down 1... + memmove(handlers_ + i, handlers_ + i + 1, + (num_handlers_ - i) * sizeof(Fl_Shared_Handler )); + } +} + + +// +// End of "$Id: Fl_Shared_Image.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Single_Window.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Single_Window.cxx new file mode 100644 index 0000000..054b76d --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Single_Window.cxx @@ -0,0 +1,41 @@ +// +// "$Id: Fl_Single_Window.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Single-buffered window for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// A window with a single-buffered context +// +// This is provided for systems where the base class is double +// buffered. You can turn it off using this subclass in case +// your display looks better without it. + +#include + +void Fl_Single_Window::show() {Fl_Window::show();} +void Fl_Single_Window::flush() {Fl_Window::flush();} + +// +// End of "$Id: Fl_Single_Window.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Slider.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Slider.cxx new file mode 100644 index 0000000..84ecbd9 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Slider.cxx @@ -0,0 +1,369 @@ +// +// "$Id: Fl_Slider.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Slider widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include +#include +#include "flstring.h" + +void Fl_Slider::_Fl_Slider() { + slider_size_ = 0; + slider_ = 0; // FL_UP_BOX; +} + +/** + Creates a new Fl_Slider widget using the given position, + size, and label string. The default boxtype is FL_DOWN_BOX. +*/ +Fl_Slider::Fl_Slider(int X, int Y, int W, int H, const char* L) +: Fl_Valuator(X, Y, W, H, L) { + box(FL_DOWN_BOX); + _Fl_Slider(); +} + +/** + Creates a new Fl_Slider widget using the given box type, position, + size, and label string. +*/ +Fl_Slider::Fl_Slider(uchar t, int X, int Y, int W, int H, const char* L) + : Fl_Valuator(X, Y, W, H, L) { + type(t); + box(t==FL_HOR_NICE_SLIDER || t==FL_VERT_NICE_SLIDER ? + FL_FLAT_BOX : FL_DOWN_BOX); + _Fl_Slider(); +} + +void Fl_Slider::slider_size(double v) { + if (v < 0) v = 0; + if (v > 1) v = 1; + if (slider_size_ != float(v)) { + slider_size_ = float(v); + damage(FL_DAMAGE_EXPOSE); + } +} + +/** + Sets the minimum (a) and maximum (b) values for the valuator widget. + if at least one of the values is changed, a partial redraw is asked. +*/ +void Fl_Slider::bounds(double a, double b) { + if (minimum() != a || maximum() != b) { + Fl_Valuator::bounds(a, b); + damage(FL_DAMAGE_EXPOSE); + } +} + +/** + Sets the size and position of the sliding knob in the box. + \param[in] pos position of first line displayed + \param[in] size size of window in lines + \param[in] first number of first line + \param[in] total total number of lines + Returns Fl_Valuator::value(p) + */ +int Fl_Slider::scrollvalue(int pos, int size, int first, int total) { + step(1, 1); + if (pos+size > first+total) total = pos+size-first; + slider_size(size >= total ? 1.0 : double(size)/double(total)); + bounds(first, total-size+first); + return value(pos); +} + +// All slider interaction is done as though the slider ranges from +// zero to one, and the left (bottom) edge of the slider is at the +// given position. Since when the slider is all the way to the +// right (top) the left (bottom) edge is not all the way over, a +// position on the widget itself covers a wider range than 0-1, +// actually it ranges from 0 to 1/(1-size). + +void Fl_Slider::draw_bg(int X, int Y, int W, int H) { + fl_push_clip(X, Y, W, H); + draw_box(); + fl_pop_clip(); + + Fl_Color black = active_r() ? FL_FOREGROUND_COLOR : FL_INACTIVE_COLOR; + if (type() == FL_VERT_NICE_SLIDER) { + draw_box(FL_THIN_DOWN_BOX, X+W/2-2, Y, 4, H, black); + } else if (type() == FL_HOR_NICE_SLIDER) { + draw_box(FL_THIN_DOWN_BOX, X, Y+H/2-2, W, 4, black); + } +} + +void Fl_Slider::draw(int X, int Y, int W, int H) { + + double val; + if (minimum() == maximum()) + val = 0.5; + else { + val = (value()-minimum())/(maximum()-minimum()); + if (val > 1.0) val = 1.0; + else if (val < 0.0) val = 0.0; + } + + int ww = (horizontal() ? W : H); + int xx, S; + if (type()==FL_HOR_FILL_SLIDER || type() == FL_VERT_FILL_SLIDER) { + S = int(val*ww+.5); + if (minimum()>maximum()) {S = ww-S; xx = ww-S;} + else xx = 0; + } else { + S = int(slider_size_*ww+.5); + int T = (horizontal() ? H : W)/2+1; + if (type()==FL_VERT_NICE_SLIDER || type()==FL_HOR_NICE_SLIDER) T += 4; + if (S < T) S = T; + xx = int(val*(ww-S)+.5); + } + int xsl, ysl, wsl, hsl; + if (horizontal()) { + xsl = X+xx; + wsl = S; + ysl = Y; + hsl = H; + } else { + ysl = Y+xx; + hsl = S; + xsl = X; + wsl = W; + } + + draw_bg(X, Y, W, H); + + Fl_Boxtype box1 = slider(); + if (!box1) {box1 = (Fl_Boxtype)(box()&-2); if (!box1) box1 = FL_UP_BOX;} + if (type() == FL_VERT_NICE_SLIDER) { + draw_box(box1, xsl, ysl, wsl, hsl, FL_GRAY); + int d = (hsl-4)/2; + draw_box(FL_THIN_DOWN_BOX, xsl+2, ysl+d, wsl-4, hsl-2*d,selection_color()); + } else if (type() == FL_HOR_NICE_SLIDER) { + draw_box(box1, xsl, ysl, wsl, hsl, FL_GRAY); + int d = (wsl-4)/2; + draw_box(FL_THIN_DOWN_BOX, xsl+d, ysl+2, wsl-2*d, hsl-4,selection_color()); + } else { + if (wsl>0 && hsl>0) draw_box(box1, xsl, ysl, wsl, hsl, selection_color()); + + if (type()!=FL_HOR_FILL_SLIDER && type() != FL_VERT_FILL_SLIDER && + Fl::scheme_ && !strcmp(Fl::scheme_, "gtk+")) { + if (W>H && wsl>(hsl+8)) { + // Draw horizontal grippers + int yy, hh; + hh = hsl-8; + xx = xsl+(wsl-hsl-4)/2; + yy = ysl+3; + + fl_color(fl_darker(selection_color())); + fl_line(xx, yy+hh, xx+hh, yy); + fl_line(xx+6, yy+hh, xx+hh+6, yy); + fl_line(xx+12, yy+hh, xx+hh+12, yy); + + xx++; + fl_color(fl_lighter(selection_color())); + fl_line(xx, yy+hh, xx+hh, yy); + fl_line(xx+6, yy+hh, xx+hh+6, yy); + fl_line(xx+12, yy+hh, xx+hh+12, yy); + } else if (H>W && hsl>(wsl+8)) { + // Draw vertical grippers + int yy; + xx = xsl+4; + ww = wsl-8; + yy = ysl+(hsl-wsl-4)/2; + + fl_color(fl_darker(selection_color())); + fl_line(xx, yy+ww, xx+ww, yy); + fl_line(xx, yy+ww+6, xx+ww, yy+6); + fl_line(xx, yy+ww+12, xx+ww, yy+12); + + yy++; + fl_color(fl_lighter(selection_color())); + fl_line(xx, yy+ww, xx+ww, yy); + fl_line(xx, yy+ww+6, xx+ww, yy+6); + fl_line(xx, yy+ww+12, xx+ww, yy+12); + } + } + } + + draw_label(xsl, ysl, wsl, hsl); + if (Fl::focus() == this) { + if (type() == FL_HOR_FILL_SLIDER || type() == FL_VERT_FILL_SLIDER) draw_focus(); + else draw_focus(box1, xsl, ysl, wsl, hsl); + } +} + +void Fl_Slider::draw() { + if (damage()&FL_DAMAGE_ALL) draw_box(); + draw(x()+Fl::box_dx(box()), + y()+Fl::box_dy(box()), + w()-Fl::box_dw(box()), + h()-Fl::box_dh(box())); +} + +int Fl_Slider::handle(int event, int X, int Y, int W, int H) { + // Fl_Widget_Tracker wp(this); + switch (event) { + case FL_PUSH: { + Fl_Widget_Tracker wp(this); + if (!Fl::event_inside(X, Y, W, H)) return 0; + handle_push(); + if (wp.deleted()) return 1; } + // fall through ... + case FL_DRAG: { + + double val; + if (minimum() == maximum()) + val = 0.5; + else { + val = (value()-minimum())/(maximum()-minimum()); + if (val > 1.0) val = 1.0; + else if (val < 0.0) val = 0.0; + } + + int ww = (horizontal() ? W : H); + int mx = (horizontal() ? Fl::event_x()-X : Fl::event_y()-Y); + int S; + static int offcenter; + + if (type() == FL_HOR_FILL_SLIDER || type() == FL_VERT_FILL_SLIDER) { + + S = 0; + if (event == FL_PUSH) { + int xx = int(val*ww+.5); + offcenter = mx-xx; + if (offcenter < -10 || offcenter > 10) offcenter = 0; + else return 1; + } + + } else { + + S = int(slider_size_*ww+.5); if (S >= ww) return 0; + int T = (horizontal() ? H : W)/2+1; + if (type()==FL_VERT_NICE_SLIDER || type()==FL_HOR_NICE_SLIDER) T += 4; + if (S < T) S = T; + if (event == FL_PUSH) { + int xx = int(val*(ww-S)+.5); + offcenter = mx-xx; + if (offcenter < 0) offcenter = 0; + else if (offcenter > S) offcenter = S; + else return 1; + } + } + + int xx = mx-offcenter; + double v; + char tryAgain = 1; + while (tryAgain) + { + tryAgain = 0; + if (xx < 0) { + xx = 0; + offcenter = mx; if (offcenter < 0) offcenter = 0; + } else if (xx > (ww-S)) { + xx = ww-S; + offcenter = mx-xx; if (offcenter > S) offcenter = S; + } + v = round(xx*(maximum()-minimum())/(ww-S) + minimum()); + // make sure a click outside the sliderbar moves it: + if (event == FL_PUSH && v == value()) { + offcenter = S/2; + event = FL_DRAG; + tryAgain = 1; + } + } + handle_drag(clamp(v)); + } return 1; + case FL_RELEASE: + handle_release(); + return 1; + case FL_KEYBOARD: + { Fl_Widget_Tracker wp(this); + switch (Fl::event_key()) { + case FL_Up: + if (horizontal()) return 0; + handle_push(); + if (wp.deleted()) return 1; + handle_drag(clamp(increment(value(),-1))); + if (wp.deleted()) return 1; + handle_release(); + return 1; + case FL_Down: + if (horizontal()) return 0; + handle_push(); + if (wp.deleted()) return 1; + handle_drag(clamp(increment(value(),1))); + if (wp.deleted()) return 1; + handle_release(); + return 1; + case FL_Left: + if (!horizontal()) return 0; + handle_push(); + if (wp.deleted()) return 1; + handle_drag(clamp(increment(value(),-1))); + if (wp.deleted()) return 1; + handle_release(); + return 1; + case FL_Right: + if (!horizontal()) return 0; + handle_push(); + if (wp.deleted()) return 1; + handle_drag(clamp(increment(value(),1))); + if (wp.deleted()) return 1; + handle_release(); + return 1; + default: + return 0; + } + } + // break not required because of switch... + case FL_FOCUS : + case FL_UNFOCUS : + if (Fl::visible_focus()) { + redraw(); + return 1; + } else return 0; + case FL_ENTER : + case FL_LEAVE : + return 1; + default: + return 0; + } +} + +int Fl_Slider::handle(int event) { + if (event == FL_PUSH && Fl::visible_focus()) { + Fl::focus(this); + redraw(); + } + + return handle(event, + x()+Fl::box_dx(box()), + y()+Fl::box_dy(box()), + w()-Fl::box_dw(box()), + h()-Fl::box_dh(box())); +} + +// +// End of "$Id: Fl_Slider.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Sys_Menu_Bar.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Sys_Menu_Bar.cxx new file mode 100644 index 0000000..69b47c3 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Sys_Menu_Bar.cxx @@ -0,0 +1,288 @@ +// +// "$Id: Fl_Sys_Menu_Bar.cxx 7518 2010-04-16 19:27:28Z manolo $" +// +// MacOS system menu bar widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/** + * This code is a quick hack! It was written as a proof of concept. + * It has been tested on the "menubar" sample program and provides + * basic functionality. + * + * To use the System Menu Bar, simply replace the main Fl_Menu_Bar + * in an application with Fl_Sys_Menu_Bar. + * + * FLTK features not supported by the Mac System menu + * + * - no invisible menu items + * - no symbolic labels + * - embossed labels will be underlined instead + * - no font sizes + * - Shortcut Characters should be English alphanumeric only, no modifiers yet + * - no disable main menus + * - changes to menubar in run-time don't update! + * (disable, etc. - toggle and radio button do!) + * + * No care was taken to clean up the menu bar after destruction! + * ::menu(bar) should only be called once! + * Many other calls of the parent class don't work. + * Changing the menu items has no effect on the menu bar. + * Starting with OS X 10.5, FLTK applications must be created as + * a bundle for the System Menu Bar (and maybe other features) to work! + */ + +#if defined(__APPLE__) || defined(FL_DOXYGEN) + +#include +#include +#include + +#include "flstring.h" +#include +#include +#include + +#define MenuHandle void * + +typedef const Fl_Menu_Item *pFl_Menu_Item; + + +/* + * Set a shortcut for an Apple menu item using the FLTK shortcut descriptor. + */ +static void setMenuShortcut( MenuHandle mh, int miCnt, const Fl_Menu_Item *m ) +{ + if ( !m->shortcut_ ) + return; + if ( m->flags & FL_SUBMENU ) + return; + if ( m->flags & FL_SUBMENU_POINTER ) + return; + char key = m->shortcut_ & 0xff; + if ( !isalnum( key ) ) + return; + + void *menuItem = Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::itemAtIndex, mh, miCnt); + Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::setKeyEquivalent, menuItem, m->shortcut_ & 0xff ); + Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::setKeyEquivalentModifierMask, menuItem, m->shortcut_ ); +} + + +/* + * Set the Toggle and Radio flag based on FLTK flags + */ +static void setMenuFlags( MenuHandle mh, int miCnt, const Fl_Menu_Item *m ) +{ + if ( m->flags & FL_MENU_TOGGLE ) + { + void *menuItem = Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::itemAtIndex, mh, miCnt); + Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::setState, menuItem, m->flags & FL_MENU_VALUE ); + } + else if ( m->flags & FL_MENU_RADIO ) { + void *menuItem = Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::itemAtIndex, mh, miCnt); + Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::setState, menuItem, m->flags & FL_MENU_VALUE ); + } +} + + +/* + * create a sub menu for a specific menu handle + */ +static void createSubMenu( void * mh, pFl_Menu_Item &mm ) +{ + void *submenu; + int miCnt, flags; + + void *menuItem; + submenu = Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::initWithTitle, mm->text); + int cnt; + Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::numberOfItems, mh, &cnt); + cnt--; + menuItem = Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::itemAtIndex, mh, cnt); + Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::setSubmenu, menuItem, submenu); + if ( mm->flags & FL_MENU_INACTIVE ) { + Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::setEnabled, menuItem, 0); + } + mm++; + + while ( mm->text ) + { + int flRank = mm - fl_sys_menu_bar->Fl_Menu_::menu(); + Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::addNewItem, submenu, flRank, &miCnt); + setMenuFlags( submenu, miCnt, mm ); + setMenuShortcut( submenu, miCnt, mm ); + if ( mm->flags & FL_MENU_INACTIVE ) { + void *item = Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::itemAtIndex, submenu, miCnt); + Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::setEnabled, item, 0); + } + flags = mm->flags; + if ( mm->flags & FL_SUBMENU ) + { + createSubMenu( submenu, mm ); + } + else if ( mm->flags & FL_SUBMENU_POINTER ) + { + const Fl_Menu_Item *smm = (Fl_Menu_Item*)mm->user_data_; + createSubMenu( submenu, smm ); + } + if ( flags & FL_MENU_DIVIDER ) { + Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::addSeparatorItem, submenu); + } + mm++; + } +} + + +/* + * convert a complete Fl_Menu_Item array into a series of menus in the top menu bar + * ALL PREVIOUS SYSTEM MENUS, EXCEPT APPLICATION MENU, ARE REPLACED BY THE NEW DATA + */ +static void convertToMenuBar(const Fl_Menu_Item *mm) +{ + int count;//first, delete all existing system menus + Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::numberOfItems, fl_system_menu, &count); + for(int i = count - 1; i > 0; i--) { + Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::removeItem, fl_system_menu, i); + } + //now convert FLTK stuff into MacOS menus + for (;;) + { + if ( !mm || !mm->text ) + break; + char visible = mm->visible() ? 1 : 0; + int flRank = mm - fl_sys_menu_bar->Fl_Menu_::menu(); + Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::addNewItem, fl_system_menu, flRank, NULL); + + if ( mm->flags & FL_SUBMENU ) + createSubMenu( fl_system_menu, mm ); + else if ( mm->flags & FL_SUBMENU_POINTER ) { + const Fl_Menu_Item *smm = (Fl_Menu_Item*)mm->user_data_; + createSubMenu( fl_system_menu, smm ); + } + if ( visible ) { + // InsertMenu( mh, 0 ); + } + mm++; + } +} + + +/** + * @brief create a system menu bar using the given list of menu structs + * + * \author Matthias Melcher + * + * @param m list of Fl_Menu_Item + */ +void Fl_Sys_Menu_Bar::menu(const Fl_Menu_Item *m) +{ + fl_open_display(); + Fl_Menu_Bar::menu( m ); + convertToMenuBar(m); +} + + +/** + * @brief add to the system menu bar a new menu item + * + * add to the system menu bar a new menu item, with a title string, shortcut int, + * callback, argument to the callback, and flags. + * + * @see Fl_Menu_::add(const char* label, int shortcut, Fl_Callback *cb, void *user_data, int flags) + */ +int Fl_Sys_Menu_Bar::add(const char* label, int shortcut, Fl_Callback *cb, void *user_data, int flags) +{ + fl_open_display(); + int rank = Fl_Menu_::add(label, shortcut, cb, user_data, flags); + convertToMenuBar(Fl_Menu_::menu()); + return rank; +} + +/** + * @brief insert in the system menu bar a new menu item + * + * insert in the system menu bar a new menu item, with a title string, shortcut int, + * callback, argument to the callback, and flags. + * + * @see Fl_Menu_::insert(int index, const char* label, int shortcut, Fl_Callback *cb, void *user_data, int flags) + */ +int Fl_Sys_Menu_Bar::insert(int index, const char* label, int shortcut, Fl_Callback *cb, void *user_data, int flags) +{ + fl_open_display(); + int rank = Fl_Menu_::insert(index, label, shortcut, cb, user_data, flags); + convertToMenuBar(Fl_Menu_::menu()); + return rank; +} + +void Fl_Sys_Menu_Bar::clear() +{ + Fl_Menu_::clear(); + convertToMenuBar(NULL); +} + +int Fl_Sys_Menu_Bar::clear_submenu(int index) +{ + int retval = Fl_Menu_::clear_submenu(index); + if (retval != -1) convertToMenuBar(Fl_Menu_::menu()); + return retval; +} + +/** + * @brief remove an item from the system menu bar + * + * @param rank the rank of the item to remove + */ +void Fl_Sys_Menu_Bar::remove(int rank) +{ + Fl_Menu_::remove(rank); + convertToMenuBar(Fl_Menu_::menu()); +} + + +/** + * @brief rename an item from the system menu bar + * + * @param rank the rank of the item to rename + * @param name the new item name as a UTF8 string + */ +void Fl_Sys_Menu_Bar::replace(int rank, const char *name) +{ + doMenuOrItemOperation(renameItem, rank, name); + fl_sys_menu_bar->Fl_Menu_::replace(rank, name); +} + + +/* + * Draw the menu bar. + * Nothing here because the OS does this for us. + */ +void Fl_Sys_Menu_Bar::draw() { +} + + +#endif /* __APPLE__ */ + +// +// End of "$Id: Fl_Sys_Menu_Bar.cxx 7518 2010-04-16 19:27:28Z manolo $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Tabs.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Tabs.cxx new file mode 100644 index 0000000..fe0352d --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Tabs.cxx @@ -0,0 +1,446 @@ +// +// "$Id: Fl_Tabs.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Tab widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + + +// This is the "file card tabs" interface to allow you to put lots and lots +// of buttons and switches in a panel, as popularized by many toolkits. + +// Each child widget is a card, and its label() is printed on the card tab. +// Clicking the tab makes that card visible. + +#include +#include +#include +#include +#include + +#define BORDER 2 +#define EXTRASPACE 10 + +// return the left edges of each tab (plus a fake left edge for a tab +// past the right-hand one). These position are actually of the left +// edge of the slope. They are either separated by the correct distance +// or by EXTRASPACE or by zero. +// Return value is the index of the selected item. + +int Fl_Tabs::tab_positions(int* p, int* wp) { + int selected = 0; + Fl_Widget*const* a = array(); + int i; + char prev_draw_shortcut = fl_draw_shortcut; + fl_draw_shortcut = 1; + + p[0] = Fl::box_dx(box()); + for (i=0; ivisible()) selected = i; + + int wt = 0; int ht = 0; + o->measure_label(wt,ht); + + wp[i] = wt+EXTRASPACE; + p[i+1] = p[i]+wp[i]+BORDER; + } + fl_draw_shortcut = prev_draw_shortcut; + + int r = w(); + if (p[i] <= r) return selected; + // uh oh, they are too big: + // pack them against right edge: + p[i] = r; + for (i = children(); i--;) { + int l = r-wp[i]; + if (p[i+1] < l) l = p[i+1]; + if (p[i] <= l) break; + p[i] = l; + r -= EXTRASPACE; + } + // pack them against left edge and truncate width if they still don't fit: + for (i = 0; i= i*EXTRASPACE) break; + p[i] = i*EXTRASPACE; + int W = w()-1-EXTRASPACE*(children()-i) - p[i]; + if (wp[i] > W) wp[i] = W; + } + // adjust edges according to visiblity: + for (i = children(); i > selected; i--) { + p[i] = p[i-1]+wp[i-1]; + } + return selected; +} + +// return space needed for tabs. Negative to put them on the bottom: +int Fl_Tabs::tab_height() { + int H = h(); + int H2 = y(); + Fl_Widget*const* a = array(); + for (int i=children(); i--;) { + Fl_Widget* o = *a++; + if (o->y() < y()+H) H = o->y()-y(); + if (o->y()+o->h() > H2) H2 = o->y()+o->h(); + } + H2 = y()+h()-H2; + if (H2 > H) return (H2 <= 0) ? 0 : -H2; + else return (H <= 0) ? 0 : H; +} + +// this is used by fluid to pick tabs: +Fl_Widget *Fl_Tabs::which(int event_x, int event_y) { + int H = tab_height(); + if (H < 0) { + if (event_y > y()+h() || event_y < y()+h()+H) return 0; + } else { + if (event_y > y()+H || event_y < y()) return 0; + } + if (event_x < x()) return 0; + Fl_Widget *ret = 0L; + int nc = children(); + int *p = (int*)malloc((nc+1)*sizeof(int)); + int *wp = (int*)malloc((nc+1)*sizeof(int)); + tab_positions(p, wp); + for (int i=0; i= 0) { + H += Fl::box_dy(box()); + damage(FL_DAMAGE_SCROLL, x(), y(), w(), H); + } else { + H = Fl::box_dy(box()) - H; + damage(FL_DAMAGE_SCROLL, x(), y() + h() - H, w(), H); + } +} + +int Fl_Tabs::handle(int event) { + + Fl_Widget *o; + int i; + + switch (event) { + + case FL_PUSH: { + int H = tab_height(); + if (H >= 0) { + if (Fl::event_y() > y()+H) return Fl_Group::handle(event); + } else { + if (Fl::event_y() < y()+h()+H) return Fl_Group::handle(event); + }} + /* FALLTHROUGH */ + case FL_DRAG: + case FL_RELEASE: + o = which(Fl::event_x(), Fl::event_y()); + if (event == FL_RELEASE) { + push(0); + if (o && Fl::visible_focus() && Fl::focus()!=this) { + Fl::focus(this); + redraw_tabs(); + } + if (o && value(o)) { + Fl_Widget_Tracker wp(o); + set_changed(); + do_callback(); + if (wp.deleted()) return 1; + } + Fl_Tooltip::current(o); + } else { + push(o); + } + return 1; + case FL_MOVE: { + int ret = Fl_Group::handle(event); + Fl_Widget *o = Fl_Tooltip::current(), *n = o; + int H = tab_height(); + if ( (H>=0) && (Fl::event_y()>y()+H) ) + return ret; + else if ( (H<0) && (Fl::event_y() < y()+h()+H) ) + return ret; + else { + n = which(Fl::event_x(), Fl::event_y()); + if (!n) n = this; + } + if (n!=o) + Fl_Tooltip::enter(n); + return ret; } + case FL_FOCUS: + case FL_UNFOCUS: + if (!Fl::visible_focus()) return Fl_Group::handle(event); + if (Fl::event() == FL_RELEASE || + Fl::event() == FL_SHORTCUT || + Fl::event() == FL_KEYBOARD || + Fl::event() == FL_FOCUS || + Fl::event() == FL_UNFOCUS) { + redraw_tabs(); + if (Fl::event() == FL_FOCUS || Fl::event() == FL_UNFOCUS) return 0; + else return 1; + } else return Fl_Group::handle(event); + case FL_KEYBOARD: + switch (Fl::event_key()) { + case FL_Left: + if (child(0)->visible()) return 0; + for (i = 1; i < children(); i ++) + if (child(i)->visible()) break; + value(child(i - 1)); + set_changed(); + do_callback(); + return 1; + case FL_Right: + if (child(children() - 1)->visible()) return 0; + for (i = 0; i < children(); i ++) + if (child(i)->visible()) break; + value(child(i + 1)); + set_changed(); + do_callback(); + return 1; + case FL_Down: + redraw(); + return Fl_Group::handle(FL_FOCUS); + default: + break; + } + return Fl_Group::handle(event); + case FL_SHORTCUT: + for (i = 0; i < children(); ++i) { + Fl_Widget *c = child(i); + if (c->test_shortcut(c->label())) { + char sc = !c->visible(); + value(c); + if (sc) set_changed(); + do_callback(); + return 1; + } + } + return Fl_Group::handle(event); + case FL_SHOW: + value(); // update visibilities and fall through + default: + return Fl_Group::handle(event); + + } +} + +int Fl_Tabs::push(Fl_Widget *o) { + if (push_ == o) return 0; + if ( (push_ && !push_->visible()) || (o && !o->visible()) ) + redraw_tabs(); + push_ = o; + return 1; +} + +/** + Gets the currently visible widget/tab. + The value() is the first visible child (or the last child if none + are visible) and this also hides any other children. + This allows the tabs to be deleted, moved to other groups, and + show()/hide() called without it screwing up. +*/ +Fl_Widget* Fl_Tabs::value() { + Fl_Widget* v = 0; + Fl_Widget*const* a = array(); + for (int i=children(); i--;) { + Fl_Widget* o = *a++; + if (v) o->hide(); + else if (o->visible()) v = o; + else if (!i) {o->show(); v = o;} + } + return v; +} + +/** + Sets the widget to become the current visible widget/tab. + Setting the value hides all other children, and makes this one + visible, if it is really a child. +*/ +int Fl_Tabs::value(Fl_Widget *newvalue) { + Fl_Widget*const* a = array(); + int ret = 0; + for (int i=children(); i--;) { + Fl_Widget* o = *a++; + if (o == newvalue) { + if (!o->visible()) ret = 1; + o->show(); + } else { + o->hide(); + } + } + return ret; +} + +enum {LEFT, RIGHT, SELECTED}; + +void Fl_Tabs::draw() { + Fl_Widget *v = value(); + int H = tab_height(); + + if (damage() & FL_DAMAGE_ALL) { // redraw the entire thing: + Fl_Color c = v ? v->color() : color(); + + draw_box(box(), x(), y()+(H>=0?H:0), w(), h()-(H>=0?H:-H), c); + + if (selection_color() != c) { + // Draw the top 5 lines of the tab pane in the selection color so + // that the user knows which tab is selected... + if (H >= 0) fl_push_clip(x(), y() + H, w(), 5); + else fl_push_clip(x(), y() + h() - H - 4, w(), 5); + + draw_box(box(), x(), y()+(H>=0?H:0), w(), h()-(H>=0?H:-H), + selection_color()); + + fl_pop_clip(); + } + if (v) draw_child(*v); + } else { // redraw the child + if (v) update_child(*v); + } + if (damage() & (FL_DAMAGE_SCROLL|FL_DAMAGE_ALL)) { + int nc = children(); + int *p = (int*)malloc((nc+1)*sizeof(int)); + int *wp = (int*)malloc((nc+1)*sizeof(int)); + int selected = tab_positions(p,wp); + int i; + Fl_Widget*const* a = array(); + for (i=0; i selected; i--) + draw_tab(x()+p[i], x()+p[i+1], wp[i], H, a[i], RIGHT); + if (v) { + i = selected; + draw_tab(x()+p[i], x()+p[i+1], wp[i], H, a[i], SELECTED); + } + free(p); + free(wp); + } +} + +void Fl_Tabs::draw_tab(int x1, int x2, int W, int H, Fl_Widget* o, int what) { + int sel = (what == SELECTED); + int dh = Fl::box_dh(box()); + int dy = Fl::box_dy(box()); + char prev_draw_shortcut = fl_draw_shortcut; + fl_draw_shortcut = 1; + + Fl_Boxtype bt = (o==push_ &&!sel) ? fl_down(box()) : box(); + + // compute offsets to make selected tab look bigger + int yofs = sel ? 0 : BORDER; + + if ((x2 < x1+W) && what == RIGHT) x1 = x2 - W; + + if (H >= 0) { + if (sel) fl_push_clip(x1, y(), x2 - x1, H + dh - dy); + else fl_push_clip(x1, y(), x2 - x1, H); + + H += dh; + + Fl_Color c = sel ? selection_color() : o->selection_color(); + + draw_box(bt, x1, y() + yofs, W, H + 10 - yofs, c); + + // Save the previous label color + Fl_Color oc = o->labelcolor(); + + // Draw the label using the current color... + o->labelcolor(sel ? labelcolor() : o->labelcolor()); + o->draw_label(x1, y() + yofs, W, H - yofs, FL_ALIGN_CENTER); + + // Restore the original label color... + o->labelcolor(oc); + + if (Fl::focus() == this && o->visible()) + draw_focus(box(), x1, y(), W, H); + + fl_pop_clip(); + } else { + H = -H; + + if (sel) fl_push_clip(x1, y() + h() - H - dy, x2 - x1, H + dy); + else fl_push_clip(x1, y() + h() - H, x2 - x1, H); + + H += dh; + + Fl_Color c = sel ? selection_color() : o->selection_color(); + + draw_box(bt, x1, y() + h() - H - 10, W, H + 10 - yofs, c); + + // Save the previous label color + Fl_Color oc = o->labelcolor(); + + // Draw the label using the current color... + o->labelcolor(sel ? labelcolor() : o->labelcolor()); + o->draw_label(x1, y() + h() - H, W, H - yofs, FL_ALIGN_CENTER); + + // Restore the original label color... + o->labelcolor(oc); + + if (Fl::focus() == this && o->visible()) + draw_focus(box(), x1, y() + h() - H, W, H); + + fl_pop_clip(); + } + fl_draw_shortcut = prev_draw_shortcut; +} + +/** + Creates a new Fl_Tabs widget using the given position, size, + and label string. The default boxtype is FL_THIN_UP_BOX. + + Use add(Fl_Widget*) to add each child, which are usually + Fl_Group widgets. The children should be sized to stay + away from the top or bottom edge of the Fl_Tabs widget, + which is where the tabs will be drawn. + + All children of Fl_Tab should have the same size and exactly fit on top of + each other. They should only leave space above or below where that tabs will + go, but not on the sides. If the first child of Fl_Tab is set to + "resizable()", the riders will not resize when the tabs are resized. + + The destructor also deletes all the children. This + allows a whole tree to be deleted at once, without having to + keep a pointer to all the children in the user code. A kludge + has been done so the Fl_Tabs and all of its children + can be automatic (local) variables, but you must declare the + Fl_Tabs widget first so that it is destroyed last. +*/ +Fl_Tabs::Fl_Tabs(int X,int Y,int W, int H, const char *l) : + Fl_Group(X,Y,W,H,l) +{ + box(FL_THIN_UP_BOX); + push_ = 0; +} + +// +// End of "$Id: Fl_Tabs.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Text_Buffer.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Text_Buffer.cxx new file mode 100644 index 0000000..6dbf3d2 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Text_Buffer.cxx @@ -0,0 +1,1637 @@ +// +// "$Id: Fl_Text_Buffer.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Copyright 2001-2010 by Bill Spitzak and others. +// Original code Copyright Mark Edel. Permission to distribute under +// the LGPL for the FLTK library granted by Mark Edel. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include +#include "flstring.h" +#include +#include +#include + + +/* + This file is based on a port of NEdit to FLTK many years ago. NEdit at that + point was already stretched beyond the task it was designed for which explains + why the source code is sometimes pretty convoluted. It still is a very useful + widget for FLTK, and we are thankful that the nedit team allowed us to + integrate their code. + + With the introduction of Unicode and UTF-8, Fl_Text_... has to go into a whole + new generation of code. Originally designed for monspaced fonts only, many + features make les sense in the multibyte and multiwdth world of UTF-8. + + Columns are a good example. There is simply no such thing. The new Fl_Text_... + widget converts columns to pixels by multiplying them with the average + character width for a given font + + Rectangular selections were rearely used (if at all) and make little sense when + using variable width fonts. They have been removed. + + Using multiple spaces to emulate tab stops has been replaced by pixel counting + routines. They are slower, but give the expected result for proportional fonts. + + And constantly recalculating character widths is just much too expensive. Lines + of text are now subdivided into blocks of text which are measured at once + instead of individual characters. + */ + + +#ifndef min + +static int max(int i1, int i2) +{ + return i1 >= i2 ? i1 : i2; +} + +static int min(int i1, int i2) +{ + return i1 <= i2 ? i1 : i2; +} + +#endif + + +static char *undobuffer; +static int undobufferlength; +static Fl_Text_Buffer *undowidget; +static int undoat; // points after insertion +static int undocut; // number of characters deleted there +static int undoinsert; // number of characters inserted +static int undoyankcut; // length of valid contents of buffer, even if undocut=0 + +/* + Resize the undo buffer to match at least the requested size. + */ +static void undobuffersize(int n) +{ + if (n > undobufferlength) { + if (undobuffer) { + do { + undobufferlength *= 2; + } while (undobufferlength < n); + undobuffer = (char *) realloc(undobuffer, undobufferlength); + } else { + undobufferlength = n + 9; + undobuffer = (char *) malloc(undobufferlength); + } + } +} + + +/* + Initialize all variables. + */ +Fl_Text_Buffer::Fl_Text_Buffer(int requestedSize, int preferredGapSize) +{ + mLength = 0; + mPreferredGapSize = preferredGapSize; + mBuf = (char *) malloc(requestedSize + mPreferredGapSize); + mGapStart = 0; + mGapEnd = mPreferredGapSize; + mTabDist = 4; + mPrimary.mSelected = 0; + mPrimary.mStart = mPrimary.mEnd = 0; + mSecondary.mSelected = 0; + mSecondary.mStart = mSecondary.mEnd = 0; + mHighlight.mSelected = 0; + mHighlight.mStart = mHighlight.mEnd = 0; + mModifyProcs = NULL; + mCbArgs = NULL; + mNModifyProcs = 0; + mNPredeleteProcs = 0; + mPredeleteProcs = NULL; + mPredeleteCbArgs = NULL; + mCursorPosHint = 0; + mCanUndo = 1; + } + + +/* + Free all resources. + */ +Fl_Text_Buffer::~Fl_Text_Buffer() +{ + free(mBuf); + if (mNModifyProcs != 0) { + delete[]mModifyProcs; + delete[]mCbArgs; + } + if (mNPredeleteProcs != 0) { + delete[]mPredeleteProcs; + delete[]mPredeleteCbArgs; + } +} + + +/* + This function copies verbose whatever is in front and after the gap into a + single buffer. + */ +char *Fl_Text_Buffer::text() const { + char *t = (char *) malloc(mLength + 1); + memcpy(t, mBuf, mGapStart); + memcpy(t+mGapStart, mBuf+mGapEnd, mLength - mGapStart); + t[mLength] = '\0'; + return t; +} + + +/* + Set the text buffer to a new string. + */ +void Fl_Text_Buffer::text(const char *t) +{ + IS_UTF8_ALIGNED(t) + + call_predelete_callbacks(0, length()); + + /* Save information for redisplay, and get rid of the old buffer */ + const char *deletedText = text(); + int deletedLength = mLength; + free((void *) mBuf); + + /* Start a new buffer with a gap of mPreferredGapSize at the end */ + int insertedLength = strlen(t); + mBuf = (char *) malloc(insertedLength + mPreferredGapSize); + mLength = insertedLength; + mGapStart = insertedLength; + mGapEnd = mGapStart + mPreferredGapSize; + memcpy(mBuf, t, insertedLength); + + /* Zero all of the existing selections */ + update_selections(0, deletedLength, 0); + + /* Call the saved display routine(s) to update the screen */ + call_modify_callbacks(0, deletedLength, insertedLength, 0, deletedText); + free((void *) deletedText); +} + + +/* + Creates a range of text to a new buffer and copies verbose from around the gap. + */ +char *Fl_Text_Buffer::text_range(int start, int end) const { + IS_UTF8_ALIGNED2(this, (start)) + IS_UTF8_ALIGNED2(this, (end)) + + char *s = NULL; + + /* Make sure start and end are ok, and allocate memory for returned string. + If start is bad, return "", if end is bad, adjust it. */ + if (start < 0 || start > mLength) + { + s = (char *) malloc(1); + s[0] = '\0'; + return s; + } + if (end < start) { + int temp = start; + start = end; + end = temp; + } + if (end > mLength) + end = mLength; + int copiedLength = end - start; + s = (char *) malloc(copiedLength + 1); + + /* Copy the text from the buffer to the returned string */ + if (end <= mGapStart) { + memcpy(s, mBuf + start, copiedLength); + } else if (start >= mGapStart) { + memcpy(s, mBuf + start + (mGapEnd - mGapStart), copiedLength); + } else { + int part1Length = mGapStart - start; + memcpy(s, mBuf + start, part1Length); + memcpy(s + part1Length, mBuf + mGapEnd, copiedLength - part1Length); + } + s[copiedLength] = '\0'; + return s; +} + +/* + Return a UCS-4 character at the given index. + Pos must be at a character boundary. + */ +unsigned int Fl_Text_Buffer::char_at(int pos) const { + if (pos < 0 || pos >= mLength) + return '\0'; + + IS_UTF8_ALIGNED2(this, (pos)) + + const char *src = address(pos); + return fl_utf8decode(src, 0, 0); +} + + +/* + Return the raw byte at the given index. + This function ignores all unicode encoding. + */ +char Fl_Text_Buffer::byte_at(int pos) const { + if (pos < 0 || pos >= mLength) + return '\0'; + const char *src = address(pos); + return *src; +} + + +/* + Insert some text at the given index. + Pos must be at a character boundary. +*/ +void Fl_Text_Buffer::insert(int pos, const char *text) +{ + IS_UTF8_ALIGNED2(this, (pos)) + IS_UTF8_ALIGNED(text) + + /* check if there is actually any text */ + if (!text || !*text) + return; + + /* if pos is not contiguous to existing text, make it */ + if (pos > mLength) + pos = mLength; + if (pos < 0) + pos = 0; + + /* Even if nothing is deleted, we must call these callbacks */ + call_predelete_callbacks(pos, 0); + + /* insert and redisplay */ + int nInserted = insert_(pos, text); + mCursorPosHint = pos + nInserted; + IS_UTF8_ALIGNED2(this, (mCursorPosHint)) + call_modify_callbacks(pos, 0, nInserted, 0, NULL); +} + + +/* + Replace a range of text with new text. + Start and end must be at a character boundary. +*/ +void Fl_Text_Buffer::replace(int start, int end, const char *text) +{ + // Range check... + if (!text) + return; + if (start < 0) + start = 0; + if (end > mLength) + end = mLength; + + IS_UTF8_ALIGNED2(this, (start)) + IS_UTF8_ALIGNED2(this, (end)) + IS_UTF8_ALIGNED(text) + + call_predelete_callbacks(start, end - start); + const char *deletedText = text_range(start, end); + remove_(start, end); + int nInserted = insert_(start, text); + mCursorPosHint = start + nInserted; + call_modify_callbacks(start, end - start, nInserted, 0, deletedText); + free((void *) deletedText); +} + + +/* + Remove a range of text. + Start and End must be at a character boundary. +*/ +void Fl_Text_Buffer::remove(int start, int end) +{ + /* Make sure the arguments make sense */ + if (start > end) { + int temp = start; + start = end; + end = temp; + } + if (start > mLength) + start = mLength; + if (start < 0) + start = 0; + if (end > mLength) + end = mLength; + if (end < 0) + end = 0; + + IS_UTF8_ALIGNED2(this, (start)) + IS_UTF8_ALIGNED2(this, (end)) + + if (start == end) + return; + + call_predelete_callbacks(start, end - start); + /* Remove and redisplay */ + const char *deletedText = text_range(start, end); + remove_(start, end); + mCursorPosHint = start; + call_modify_callbacks(start, end - start, 0, 0, deletedText); + free((void *) deletedText); +} + + +/* + Copy a range of text from another text buffer. + FromStart, fromEnd, and toPos must be at a character boundary. + */ +void Fl_Text_Buffer::copy(Fl_Text_Buffer * fromBuf, int fromStart, + int fromEnd, int toPos) +{ + IS_UTF8_ALIGNED2(fromBuf, fromStart) + IS_UTF8_ALIGNED2(fromBuf, fromEnd) + IS_UTF8_ALIGNED2(this, (toPos)) + + int copiedLength = fromEnd - fromStart; + + /* Prepare the buffer to receive the new text. If the new text fits in + the current buffer, just move the gap (if necessary) to where + the text should be inserted. If the new text is too large, reallocate + the buffer with a gap large enough to accomodate the new text and a + gap of mPreferredGapSize */ + if (copiedLength > mGapEnd - mGapStart) + reallocate_with_gap(toPos, copiedLength + mPreferredGapSize); + else if (toPos != mGapStart) + move_gap(toPos); + + /* Insert the new text (toPos now corresponds to the start of the gap) */ + if (fromEnd <= fromBuf->mGapStart) { + memcpy(&mBuf[toPos], &fromBuf->mBuf[fromStart], copiedLength); + } else if (fromStart >= fromBuf->mGapStart) { + memcpy(&mBuf[toPos], + &fromBuf->mBuf[fromStart + (fromBuf->mGapEnd - fromBuf->mGapStart)], + copiedLength); + } else { + int part1Length = fromBuf->mGapStart - fromStart; + memcpy(&mBuf[toPos], &fromBuf->mBuf[fromStart], part1Length); + memcpy(&mBuf[toPos + part1Length], + &fromBuf->mBuf[fromBuf->mGapEnd], copiedLength - part1Length); + } + mGapStart += copiedLength; + mLength += copiedLength; + update_selections(toPos, 0, copiedLength); +} + + +/* + Take the previous changes and undo them. Return the previous + cursor position in cursorPos. Returns 1 if the undo was applied. + CursorPos will be at a character boundary. + */ +int Fl_Text_Buffer::undo(int *cursorPos) +{ + if (undowidget != this || !undocut && !undoinsert && !mCanUndo) + return 0; + + int ilen = undocut; + int xlen = undoinsert; + int b = undoat - xlen; + + if (xlen && undoyankcut && !ilen) { + ilen = undoyankcut; + } + + if (xlen && ilen) { + undobuffersize(ilen + 1); + undobuffer[ilen] = 0; + char *tmp = strdup(undobuffer); + replace(b, undoat, tmp); + if (cursorPos) + *cursorPos = mCursorPosHint; + free(tmp); + } else if (xlen) { + remove(b, undoat); + if (cursorPos) + *cursorPos = mCursorPosHint; + } else if (ilen) { + undobuffersize(ilen + 1); + undobuffer[ilen] = 0; + insert(undoat, undobuffer); + if (cursorPos) + *cursorPos = mCursorPosHint; + undoyankcut = 0; + } + + return 1; +} + + +/* + Set a flag is undo function will work. + */ +void Fl_Text_Buffer::canUndo(char flag) +{ + mCanUndo = flag; + // disabeling undo also clears the last undo operation! + if (!mCanUndo && undowidget==this) + undowidget = 0; +} + + +/* + Change the tab width. This will cause a couple of callbacks and a complete + redisplay. + Matt: I am not entirely sure why we need to trigger callbacks because + tabs are only a graphical hint, not changing any text at all, but I leave + this in here for back compatibility. + */ +void Fl_Text_Buffer::tab_distance(int tabDist) +{ + /* First call the pre-delete callbacks with the previous tab setting + still active. */ + call_predelete_callbacks(0, mLength); + + /* Change the tab setting */ + mTabDist = tabDist; + + /* Force any display routines to redisplay everything (unfortunately, + this means copying the whole buffer contents to provide "deletedText" */ + const char *deletedText = text(); + call_modify_callbacks(0, mLength, mLength, 0, deletedText); + free((void *) deletedText); +} + + +/* + Select a range of text. + Start and End must be at a character boundary. + */ +void Fl_Text_Buffer::select(int start, int end) +{ + IS_UTF8_ALIGNED2(this, (start)) + IS_UTF8_ALIGNED2(this, (end)) + + Fl_Text_Selection oldSelection = mPrimary; + + mPrimary.set(start, end); + redisplay_selection(&oldSelection, &mPrimary); +} + + +/* + Clear the primary selection. + */ +void Fl_Text_Buffer::unselect() +{ + Fl_Text_Selection oldSelection = mPrimary; + + mPrimary.mSelected = 0; + redisplay_selection(&oldSelection, &mPrimary); +} + + +/* + Return the primary selection range. + */ +int Fl_Text_Buffer::selection_position(int *start, int *end) +{ + return mPrimary.position(start, end); +} + + +/* + Return a copy of the selected text. + */ +char *Fl_Text_Buffer::selection_text() +{ + return selection_text_(&mPrimary); +} + + +/* + Remove the selected text. + */ +void Fl_Text_Buffer::remove_selection() +{ + remove_selection_(&mPrimary); +} + + +/* + Replace the selected text. + */ +void Fl_Text_Buffer::replace_selection(const char *text) +{ + replace_selection_(&mPrimary, text); +} + + +/* + Select text. + Start and End must be at a character boundary. + */ +void Fl_Text_Buffer::secondary_select(int start, int end) +{ + Fl_Text_Selection oldSelection = mSecondary; + + mSecondary.set(start, end); + redisplay_selection(&oldSelection, &mSecondary); +} + + +/* + Deselect text. + */ +void Fl_Text_Buffer::secondary_unselect() +{ + Fl_Text_Selection oldSelection = mSecondary; + + mSecondary.mSelected = 0; + redisplay_selection(&oldSelection, &mSecondary); +} + + +/* + Return the selected range. + */ +int Fl_Text_Buffer::secondary_selection_position(int *start, int *end) +{ + return mSecondary.position(start, end); +} + + +/* + Return a copy of the text in this selection. + */ +char *Fl_Text_Buffer::secondary_selection_text() +{ + return selection_text_(&mSecondary); +} + + +/* + Remove the selected text. + */ +void Fl_Text_Buffer::remove_secondary_selection() +{ + remove_selection_(&mSecondary); +} + + +/* + Replace selected text. + */ +void Fl_Text_Buffer::replace_secondary_selection(const char *text) +{ + replace_selection_(&mSecondary, text); +} + + +/* + Highlight a range of text. + Start and End must be at a character boundary. + */ +void Fl_Text_Buffer::highlight(int start, int end) +{ + Fl_Text_Selection oldSelection = mHighlight; + + mHighlight.set(start, end); + redisplay_selection(&oldSelection, &mHighlight); +} + + +/* + Remove text highlighting. + */ +void Fl_Text_Buffer::unhighlight() +{ + Fl_Text_Selection oldSelection = mHighlight; + + mHighlight.mSelected = 0; + redisplay_selection(&oldSelection, &mHighlight); +} + + +/* + Return position of highlight. + */ +int Fl_Text_Buffer::highlight_position(int *start, int *end) +{ + return mHighlight.position(start, end); +} + + +/* + Return a copy of highlighted text. + */ +char *Fl_Text_Buffer::highlight_text() +{ + return selection_text_(&mHighlight); +} + + +/* + Add a callback that is called whenever text is modified. + */ +void Fl_Text_Buffer::add_modify_callback(Fl_Text_Modify_Cb bufModifiedCB, + void *cbArg) +{ + Fl_Text_Modify_Cb *newModifyProcs = + new Fl_Text_Modify_Cb[mNModifyProcs + 1]; + void **newCBArgs = new void *[mNModifyProcs + 1]; + for (int i = 0; i < mNModifyProcs; i++) { + newModifyProcs[i + 1] = mModifyProcs[i]; + newCBArgs[i + 1] = mCbArgs[i]; + } + if (mNModifyProcs != 0) { + delete[]mModifyProcs; + delete[]mCbArgs; + } + newModifyProcs[0] = bufModifiedCB; + newCBArgs[0] = cbArg; + mNModifyProcs++; + mModifyProcs = newModifyProcs; + mCbArgs = newCBArgs; +} + + +/* + Remove a callback. + */ +void Fl_Text_Buffer::remove_modify_callback(Fl_Text_Modify_Cb bufModifiedCB, + void *cbArg) +{ + int i, toRemove = -1; + + /* find the matching callback to remove */ + for (i = 0; i < mNModifyProcs; i++) { + if (mModifyProcs[i] == bufModifiedCB && mCbArgs[i] == cbArg) { + toRemove = i; + break; + } + } + if (toRemove == -1) { + Fl::error + ("Fl_Text_Buffer::remove_modify_callback(): Can't find modify CB to remove"); + return; + } + + /* Allocate new lists for remaining callback procs and args (if + any are left) */ + mNModifyProcs--; + if (mNModifyProcs == 0) { + mNModifyProcs = 0; + delete[]mModifyProcs; + mModifyProcs = NULL; + delete[]mCbArgs; + mCbArgs = NULL; + return; + } + Fl_Text_Modify_Cb *newModifyProcs = new Fl_Text_Modify_Cb[mNModifyProcs]; + void **newCBArgs = new void *[mNModifyProcs]; + + /* copy out the remaining members and free the old lists */ + for (i = 0; i < toRemove; i++) { + newModifyProcs[i] = mModifyProcs[i]; + newCBArgs[i] = mCbArgs[i]; + } + for (; i < mNModifyProcs; i++) { + newModifyProcs[i] = mModifyProcs[i + 1]; + newCBArgs[i] = mCbArgs[i + 1]; + } + delete[]mModifyProcs; + delete[]mCbArgs; + mModifyProcs = newModifyProcs; + mCbArgs = newCBArgs; +} + + +/* + Add a callback that is called before deleting text. + */ +void Fl_Text_Buffer::add_predelete_callback(Fl_Text_Predelete_Cb bufPreDeleteCB, + void *cbArg) +{ + Fl_Text_Predelete_Cb *newPreDeleteProcs = + new Fl_Text_Predelete_Cb[mNPredeleteProcs + 1]; + void **newCBArgs = new void *[mNPredeleteProcs + 1]; + for (int i = 0; i < mNPredeleteProcs; i++) { + newPreDeleteProcs[i + 1] = mPredeleteProcs[i]; + newCBArgs[i + 1] = mPredeleteCbArgs[i]; + } + if (!mNPredeleteProcs != 0) { + delete[]mPredeleteProcs; + delete[]mPredeleteCbArgs; + } + newPreDeleteProcs[0] = bufPreDeleteCB; + newCBArgs[0] = cbArg; + mNPredeleteProcs++; + mPredeleteProcs = newPreDeleteProcs; + mPredeleteCbArgs = newCBArgs; +} + + +/* + Remove a callback. + */ +void Fl_Text_Buffer::remove_predelete_callback(Fl_Text_Predelete_Cb bufPreDeleteCB, void *cbArg) +{ + int i, toRemove = -1; + /* find the matching callback to remove */ + for (i = 0; i < mNPredeleteProcs; i++) { + if (mPredeleteProcs[i] == bufPreDeleteCB && + mPredeleteCbArgs[i] == cbArg) { + toRemove = i; + break; + } + } + if (toRemove == -1) { + Fl::error + ("Fl_Text_Buffer::remove_predelete_callback(): Can't find pre-delete CB to remove"); + return; + } + + /* Allocate new lists for remaining callback procs and args (if + any are left) */ + mNPredeleteProcs--; + if (mNPredeleteProcs == 0) { + mNPredeleteProcs = 0; + delete[]mPredeleteProcs; + mPredeleteProcs = NULL; + delete[]mPredeleteCbArgs; + mPredeleteCbArgs = NULL; + return; + } + Fl_Text_Predelete_Cb *newPreDeleteProcs = + new Fl_Text_Predelete_Cb[mNPredeleteProcs]; + void **newCBArgs = new void *[mNPredeleteProcs]; + + /* copy out the remaining members and free the old lists */ + for (i = 0; i < toRemove; i++) { + newPreDeleteProcs[i] = mPredeleteProcs[i]; + newCBArgs[i] = mPredeleteCbArgs[i]; + } + for (; i < mNPredeleteProcs; i++) { + newPreDeleteProcs[i] = mPredeleteProcs[i + 1]; + newCBArgs[i] = mPredeleteCbArgs[i + 1]; + } + delete[]mPredeleteProcs; + delete[]mPredeleteCbArgs; + mPredeleteProcs = newPreDeleteProcs; + mPredeleteCbArgs = newCBArgs; +} + + +/* + Return a copy of the line that contains a given index. + Pos must be at a character boundary. + */ +char *Fl_Text_Buffer::line_text(int pos) const { + return text_range(line_start(pos), line_end(pos)); +} + + +/* + Find the beginning of the line. + */ +int Fl_Text_Buffer::line_start(int pos) const +{ + if (!findchar_backward(pos, '\n', &pos)) + return 0; + return pos + 1; +} + + +/* + Find the end of the line. + */ +int Fl_Text_Buffer::line_end(int pos) const { + if (!findchar_forward(pos, '\n', &pos)) + pos = mLength; + return pos; +} + + +/* + Find the beginning of a word. + NOT UNICODE SAFE. + */ +int Fl_Text_Buffer::word_start(int pos) const { + // FIXME: character is ucs-4 + while (pos>0 && (isalnum(char_at(pos)) || char_at(pos) == '_')) { + pos = prev_char(pos); + } + // FIXME: character is ucs-4 + if (!(isalnum(char_at(pos)) || char_at(pos) == '_')) + pos = next_char(pos); + return pos; +} + + +/* + Find the end of a word. + NOT UNICODE SAFE. + */ +int Fl_Text_Buffer::word_end(int pos) const { + // FIXME: character is ucs-4 + while (pos < length() && (isalnum(char_at(pos)) || char_at(pos) == '_')) + { + pos = next_char(pos); + } return pos; +} + + +/* + Count the number of characters between two positions. + */ +int Fl_Text_Buffer::count_displayed_characters(int lineStartPos, + int targetPos) const +{ + IS_UTF8_ALIGNED2(this, (lineStartPos)) + IS_UTF8_ALIGNED2(this, (targetPos)) + + int charCount = 0; + + int pos = lineStartPos; + while (pos < targetPos) { + pos = next_char(pos); + charCount++; + } + return charCount; +} + + +/* + Skip ahead a number of characters from a given index. + This function breaks early if it encounters a newline character. + */ +int Fl_Text_Buffer::skip_displayed_characters(int lineStartPos, int nChars) +{ + IS_UTF8_ALIGNED2(this, (lineStartPos)) + + int pos = lineStartPos; + + for (int charCount = 0; charCount < nChars && pos < mLength; charCount++) { + unsigned int c = char_at(pos); + if (c == '\n') + return pos; + pos = next_char(pos); + } + return pos; +} + + +/* + Count the number of newline characters between start and end. + StartPos and endPos must be at a character boundary. + This function is optimized for speed by not using UTF-8 calls. + */ +int Fl_Text_Buffer::count_lines(int startPos, int endPos) const { + IS_UTF8_ALIGNED2(this, (startPos)) + IS_UTF8_ALIGNED2(this, (endPos)) + + int gapLen = mGapEnd - mGapStart; + int lineCount = 0; + + int pos = startPos; + while (pos < mGapStart) + { + if (pos == endPos) + return lineCount; + if (mBuf[pos++] == '\n') + lineCount++; + } + while (pos < mLength) { + if (pos == endPos) + return lineCount; + if (mBuf[pos++ + gapLen] == '\n') + lineCount++; + } + return lineCount; +} + + +/* + Skip to the first character, n lines ahead. + StartPos must be at a character boundary. + This function is optimized for speed by not using UTF-8 calls. + */ +int Fl_Text_Buffer::skip_lines(int startPos, int nLines) +{ + IS_UTF8_ALIGNED2(this, (startPos)) + + if (nLines == 0) + return startPos; + + int gapLen = mGapEnd - mGapStart; + int pos = startPos; + int lineCount = 0; + while (pos < mGapStart) { + if (mBuf[pos++] == '\n') { + lineCount++; + if (lineCount == nLines) { + IS_UTF8_ALIGNED2(this, (pos)) + return pos; + } + } + } + while (pos < mLength) { + if (mBuf[pos++ + gapLen] == '\n') { + lineCount++; + if (lineCount >= nLines) { + IS_UTF8_ALIGNED2(this, (pos)) + return pos; + } + } + } + IS_UTF8_ALIGNED2(this, (pos)) + return pos; +} + + +/* + Skip to the first character, n lines back. + StartPos must be at a character boundary. + This function is optimized for speed by not using UTF-8 calls. + */ +int Fl_Text_Buffer::rewind_lines(int startPos, int nLines) +{ + IS_UTF8_ALIGNED2(this, (startPos)) + + int pos = startPos - 1; + if (pos <= 0) + return 0; + + int gapLen = mGapEnd - mGapStart; + int lineCount = -1; + while (pos >= mGapStart) { + if (mBuf[pos + gapLen] == '\n') { + if (++lineCount >= nLines) { + IS_UTF8_ALIGNED2(this, (pos+1)) + return pos + 1; + } + } + pos--; + } + while (pos >= 0) { + if (mBuf[pos] == '\n') { + if (++lineCount >= nLines) { + IS_UTF8_ALIGNED2(this, (pos+1)) + return pos + 1; + } + } + pos--; + } + return 0; +} + + +/* + Find a matching string in the buffer. + */ +int Fl_Text_Buffer::search_forward(int startPos, const char *searchString, + int *foundPos, int matchCase) const +{ + IS_UTF8_ALIGNED2(this, (startPos)) + IS_UTF8_ALIGNED(searchString) + + if (!searchString) + return 0; + int bp; + const char *sp; + if (matchCase) { + while (startPos < length()) { + bp = startPos; + sp = searchString; + for (;;) { + char c = *sp; + // we reached the end of the "needle", so we found the string! + if (!c) { + *foundPos = startPos; + return 1; + } + int l = fl_utf8len(c); + if (memcmp(sp, address(bp), l)) + break; + sp += l; bp += l; + } + startPos = next_char(startPos); + } + } else { + while (startPos < length()) { + bp = startPos; + sp = searchString; + for (;;) { + // we reached the end of the "needle", so we found the string! + if (!*sp) { + *foundPos = startPos; + return 1; + } + int l; + unsigned int b = char_at(bp); + unsigned int s = fl_utf8decode(sp, 0, &l); + if (fl_tolower(b)!=fl_tolower(s)) + break; + sp += l; + bp = next_char(bp); + } + startPos = next_char(startPos); + } + } + return 0; +} + +int Fl_Text_Buffer::search_backward(int startPos, const char *searchString, + int *foundPos, int matchCase) const +{ + IS_UTF8_ALIGNED2(this, (startPos)) + IS_UTF8_ALIGNED(searchString) + + if (!searchString) + return 0; + int bp; + const char *sp; + if (matchCase) { + while (startPos >= 0) { + bp = startPos; + sp = searchString; + for (;;) { + char c = *sp; + // we reached the end of the "needle", so we found the string! + if (!c) { + *foundPos = startPos; + return 1; + } + int l = fl_utf8len(c); + if (memcmp(sp, address(bp), l)) + break; + sp += l; bp += l; + } + startPos = prev_char(startPos); + } + } else { + while (startPos >= 0) { + bp = startPos; + sp = searchString; + for (;;) { + // we reached the end of the "needle", so we found the string! + if (!*sp) { + *foundPos = startPos; + return 1; + } + int l; + unsigned int b = char_at(bp); + unsigned int s = fl_utf8decode(sp, 0, &l); + if (fl_tolower(b)!=fl_tolower(s)) + break; + sp += l; + bp = next_char(bp); + } + startPos = prev_char(startPos); + } + } + return 0; +} + + + +/* + Insert a string into the buffer. + Pos must be at a character boundary. Text must be a correct utf8 string. + */ +int Fl_Text_Buffer::insert_(int pos, const char *text) +{ + if (!text || !*text) + return 0; + + int insertedLength = strlen(text); + + /* Prepare the buffer to receive the new text. If the new text fits in + the current buffer, just move the gap (if necessary) to where + the text should be inserted. If the new text is too large, reallocate + the buffer with a gap large enough to accomodate the new text and a + gap of mPreferredGapSize */ + if (insertedLength > mGapEnd - mGapStart) + reallocate_with_gap(pos, insertedLength + mPreferredGapSize); + else if (pos != mGapStart) + move_gap(pos); + + /* Insert the new text (pos now corresponds to the start of the gap) */ + memcpy(&mBuf[pos], text, insertedLength); + mGapStart += insertedLength; + mLength += insertedLength; + update_selections(pos, 0, insertedLength); + + if (mCanUndo) { + if (undowidget == this && undoat == pos && undoinsert) { + undoinsert += insertedLength; + } else { + undoinsert = insertedLength; + undoyankcut = (undoat == pos) ? undocut : 0; + } + undoat = pos + insertedLength; + undocut = 0; + undowidget = this; + } + + return insertedLength; +} + + +/* + Remove a string from the buffer. + Unicode safe. Start and end must be at a character boundary. + */ +void Fl_Text_Buffer::remove_(int start, int end) +{ + /* if the gap is not contiguous to the area to remove, move it there */ + + if (mCanUndo) { + if (undowidget == this && undoat == end && undocut) { + undobuffersize(undocut + end - start + 1); + memmove(undobuffer + end - start, undobuffer, undocut); + undocut += end - start; + } else { + undocut = end - start; + undobuffersize(undocut); + } + undoat = start; + undoinsert = 0; + undoyankcut = 0; + undowidget = this; + } + + if (start > mGapStart) { + if (mCanUndo) + memcpy(undobuffer, mBuf + (mGapEnd - mGapStart) + start, + end - start); + move_gap(start); + } else if (end < mGapStart) { + if (mCanUndo) + memcpy(undobuffer, mBuf + start, end - start); + move_gap(end); + } else { + int prelen = mGapStart - start; + if (mCanUndo) { + memcpy(undobuffer, mBuf + start, prelen); + memcpy(undobuffer + prelen, mBuf + mGapEnd, end - start - prelen); + } + } + + /* expand the gap to encompass the deleted characters */ + mGapEnd += end - mGapStart; + mGapStart -= mGapStart - start; + + /* update the length */ + mLength -= end - start; + + /* fix up any selections which might be affected by the change */ + update_selections(start, end - start, 0); +} + + +/* + simple setter. + Unicode safe. Start and end must be at a character boundary. + */ +void Fl_Text_Selection::set(int startpos, int endpos) +{ + mSelected = startpos != endpos; + mStart = min(startpos, endpos); + mEnd = max(startpos, endpos); +} + + +/* + simple getter. + Unicode safe. Start and end will be at a character boundary. + */ +int Fl_Text_Selection::position(int *startpos, int *endpos) const { + if (!mSelected) + return 0; + *startpos = mStart; + *endpos = mEnd; + + return 1; +} + + +/* + Return if a position is inside the eselected area. + Unicode safe. Pos must be at a character boundary. + */ +int Fl_Text_Selection::includes(int pos) const { + return (selected() && pos >= start() && pos < end() ); +} + + +/* + Return a duplicate of the selected text, or an empty string. + Unicode safe. + */ +char *Fl_Text_Buffer::selection_text_(Fl_Text_Selection * sel) const { + int start, end; + + /* If there's no selection, return an allocated empty string */ + if (!sel->position(&start, &end)) + { + char *s = (char *) malloc(1); + *s = '\0'; + return s; + } + + /* Return the selected range */ + return text_range(start, end); +} + + +/* + Remove the selected text. + Unicode safe. + */ +void Fl_Text_Buffer::remove_selection_(Fl_Text_Selection * sel) +{ + int start, end; + + if (!sel->position(&start, &end)) + return; + remove(start, end); + //undoyankcut = undocut; +} + + +/* + Replace selection with text. + Unicode safe. + */ +void Fl_Text_Buffer::replace_selection_(Fl_Text_Selection * sel, + const char *text) +{ + Fl_Text_Selection oldSelection = *sel; + + /* If there's no selection, return */ + int start, end; + if (!sel->position(&start, &end)) + return; + + /* Do the appropriate type of replace */ + replace(start, end, text); + + /* Unselect (happens automatically in BufReplace, but BufReplaceRect + can't detect when the contents of a selection goes away) */ + sel->mSelected = 0; + redisplay_selection(&oldSelection, sel); +} + + +/* + Call all callbacks. + Unicode safe. + */ +void Fl_Text_Buffer::call_modify_callbacks(int pos, int nDeleted, + int nInserted, int nRestyled, + const char *deletedText) const { + IS_UTF8_ALIGNED2(this, pos) + for (int i = 0; i < mNModifyProcs; i++) + (*mModifyProcs[i]) (pos, nInserted, nDeleted, nRestyled, + deletedText, mCbArgs[i]); +} + + +/* + Call all callbacks. + Unicode safe. + */ +void Fl_Text_Buffer::call_predelete_callbacks(int pos, int nDeleted) const { + for (int i = 0; i < mNPredeleteProcs; i++) + (*mPredeleteProcs[i]) (pos, nDeleted, mPredeleteCbArgs[i]); +} + + +/* + Redisplay a new selected area. + Unicode safe. + */ +void Fl_Text_Buffer::redisplay_selection(Fl_Text_Selection * + oldSelection, + Fl_Text_Selection * + newSelection) const +{ + int oldStart, oldEnd, newStart, newEnd, ch1Start, ch1End, ch2Start, + ch2End; + + /* If either selection is rectangular, add an additional character to + the end of the selection to request the redraw routines to wipe out + the parts of the selection beyond the end of the line */ + oldStart = oldSelection->mStart; + newStart = newSelection->mStart; + oldEnd = oldSelection->mEnd; + newEnd = newSelection->mEnd; + + /* If the old or new selection is unselected, just redisplay the + single area that is (was) selected and return */ + if (!oldSelection->mSelected && !newSelection->mSelected) + return; + if (!oldSelection->mSelected) + { + call_modify_callbacks(newStart, 0, 0, newEnd - newStart, NULL); + return; + } + if (!newSelection->mSelected) { + call_modify_callbacks(oldStart, 0, 0, oldEnd - oldStart, NULL); + return; + } + + /* If the selections are non-contiguous, do two separate updates + and return */ + if (oldEnd < newStart || newEnd < oldStart) { + call_modify_callbacks(oldStart, 0, 0, oldEnd - oldStart, NULL); + call_modify_callbacks(newStart, 0, 0, newEnd - newStart, NULL); + return; + } + + /* Otherwise, separate into 3 separate regions: ch1, and ch2 (the two + changed areas), and the unchanged area of their intersection, + and update only the changed area(s) */ + ch1Start = min(oldStart, newStart); + ch2End = max(oldEnd, newEnd); + ch1End = max(oldStart, newStart); + ch2Start = min(oldEnd, newEnd); + if (ch1Start != ch1End) + call_modify_callbacks(ch1Start, 0, 0, ch1End - ch1Start, NULL); + if (ch2Start != ch2End) + call_modify_callbacks(ch2Start, 0, 0, ch2End - ch2Start, NULL); +} + + +/* + Move the gap around without changing buffer content. + Unicode safe. Pos must be at a character boundary. + */ +void Fl_Text_Buffer::move_gap(int pos) +{ + int gapLen = mGapEnd - mGapStart; + + if (pos > mGapStart) + memmove(&mBuf[mGapStart], &mBuf[mGapEnd], pos - mGapStart); + else + memmove(&mBuf[pos + gapLen], &mBuf[pos], mGapStart - pos); + mGapEnd += pos - mGapStart; + mGapStart += pos - mGapStart; +} + + +/* + Create a larger gap. + Unicode safe. Start must be at a character boundary. + */ +void Fl_Text_Buffer::reallocate_with_gap(int newGapStart, int newGapLen) +{ + char *newBuf = (char *) malloc(mLength + newGapLen); + int newGapEnd = newGapStart + newGapLen; + + if (newGapStart <= mGapStart) { + memcpy(newBuf, mBuf, newGapStart); + memcpy(&newBuf[newGapEnd], &mBuf[newGapStart], + mGapStart - newGapStart); + memcpy(&newBuf[newGapEnd + mGapStart - newGapStart], + &mBuf[mGapEnd], mLength - mGapStart); + } else { /* newGapStart > mGapStart */ + memcpy(newBuf, mBuf, mGapStart); + memcpy(&newBuf[mGapStart], &mBuf[mGapEnd], newGapStart - mGapStart); + memcpy(&newBuf[newGapEnd], + &mBuf[mGapEnd + newGapStart - mGapStart], + mLength - newGapStart); + } + free((void *) mBuf); + mBuf = newBuf; + mGapStart = newGapStart; + mGapEnd = newGapEnd; + } + + +/* + Update selection range if characers were inserted. + Unicode safe. Pos must be at a character boundary. + */ +void Fl_Text_Buffer::update_selections(int pos, int nDeleted, + int nInserted) +{ + mPrimary.update(pos, nDeleted, nInserted); + mSecondary.update(pos, nDeleted, nInserted); + mHighlight.update(pos, nDeleted, nInserted); +} + + +// unicode safe, assuming the arguments are on character boundaries +void Fl_Text_Selection::update(int pos, int nDeleted, int nInserted) +{ + if (!mSelected || pos > mEnd) + return; + if (pos + nDeleted <= mStart) { + mStart += nInserted - nDeleted; + mEnd += nInserted - nDeleted; + } else if (pos <= mStart && pos + nDeleted >= mEnd) { + mStart = pos; + mEnd = pos; + mSelected = 0; + } else if (pos <= mStart && pos + nDeleted < mEnd) { + mStart = pos; + mEnd = nInserted + mEnd - nDeleted; + } else if (pos < mEnd) { + mEnd += nInserted - nDeleted; + if (mEnd <= mStart) + mSelected = 0; + } +} + + +/* + Find a UCS-4 character. + StartPos must be at a charcter boundary, searchChar is UCS-4 encoded. + */ +int Fl_Text_Buffer::findchar_forward(int startPos, unsigned searchChar, + int *foundPos) const +{ + if (startPos >= mLength) { + *foundPos = mLength; + return 0; + } + + if (startPos<0) + startPos = 0; + + for ( ; startPos mLength) + startPos = mLength; + + for (startPos = prev_char(startPos); startPos>=0; startPos = prev_char(startPos)) { + if (searchChar == char_at(startPos)) { + *foundPos = startPos; + return 1; + } + } + + *foundPos = 0; + return 0; +} + + +/* + Insert text from a file. + Unicode safe. Inout must be correct utf8! + */ +int Fl_Text_Buffer::insertfile(const char *file, int pos, int buflen) +{ + FILE *fp; + if (!(fp = fl_fopen(file, "r"))) + return 1; + char *buffer = new char[buflen]; + for (int r; (r = fread(buffer, 1, buflen - 1, fp)) > 0; pos += r) { + buffer[r] = (char) 0; + insert(pos, buffer); + } + + int e = ferror(fp) ? 2 : 0; + fclose(fp); + delete[]buffer; + return e; +} + + +/* + Write text to file, + Unicode safe. + */ +int Fl_Text_Buffer::outputfile(const char *file, int start, int end, + int buflen) +{ + FILE *fp; + if (!(fp = fl_fopen(file, "wb"))) + return 1; + for (int n; (n = min(end - start, buflen)); start += n) { + const char *p = text_range(start, start + n); + int r = fwrite(p, 1, n, fp); + free((void *) p); + if (r != n) + break; + } + + int e = ferror(fp) ? 2 : 0; + fclose(fp); + return e; +} + + +/* + Return the previous character position. + Uncode safe. + */ +int Fl_Text_Buffer::prev_char_clipped(int pos) const +{ + if (pos<=0) + return 0; + + IS_UTF8_ALIGNED2(this, (pos)) + + char c; + do { + pos--; + if (pos==0) + return 0; + c = byte_at(pos); + } while ( (c&0xc0) == 0x80); + + IS_UTF8_ALIGNED2(this, (pos)) + return pos; +} + + +/* + Return the previous character poosition. + Returns -1 if the beginning of the buffer is reached. + */ +int Fl_Text_Buffer::prev_char(int pos) const +{ + if (pos==0) return -1; + return prev_char_clipped(pos); +} + + +/* + Return the next character position. + Returns length() if the end of the buffer is reached. + */ +int Fl_Text_Buffer::next_char(int pos) const +{ + IS_UTF8_ALIGNED2(this, (pos)) + int n = fl_utf8len(byte_at(pos)); + pos += n; + if (pos>=mLength) + return mLength; +// IS_UTF8_ALIGNED2(this, (pos)) + return pos; +} + + +/* + Return the next character poosition. + If the end of the buffer is reached, it returns the current position. + */ +int Fl_Text_Buffer::next_char_clipped(int pos) const +{ + return next_char(pos); +} + +/* + Align an index to the current utf8 boundary + */ +int Fl_Text_Buffer::utf8_align(int pos) const +{ + char c = byte_at(pos); + while ( (c&0xc0) == 0x80) { + pos--; + c = byte_at(pos); + } + return pos; +} + +// +// End of "$Id: Fl_Text_Buffer.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Text_Display.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Text_Display.cxx new file mode 100644 index 0000000..b79e79b --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Text_Display.cxx @@ -0,0 +1,3771 @@ +// +// "$Id: Fl_Text_Display.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Copyright 2001-2010 by Bill Spitzak and others. +// Original code Copyright Mark Edel. Permission to distribute under +// the LGPL for the FLTK library granted by Mark Edel. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// TODO: rendering of the "optional hyphen" +// TODO: make line numbering work again + +#include +#include +#include +#include "flstring.h" +#include +#include +#include +#include +#include +#include + +#undef min +#undef max + +// Text area margins. Left & right margins should be at least 3 so that +// there is some room for the overhanging parts of the cursor! +#define TOP_MARGIN 1 +#define BOTTOM_MARGIN 1 +#define LEFT_MARGIN 3 +#define RIGHT_MARGIN 3 + +#define NO_HINT -1 + +/* Masks for text drawing methods. These are or'd together to form an + integer which describes what drawing calls to use to draw a string */ +#define FILL_MASK 0x0100 +#define SECONDARY_MASK 0x0200 +#define PRIMARY_MASK 0x0400 +#define HIGHLIGHT_MASK 0x0800 +#define BG_ONLY_MASK 0x1000 +#define TEXT_ONLY_MASK 0x2000 +#define STYLE_LOOKUP_MASK 0xff + +/* Maximum displayable line length (how many characters will fit across the + widest window). This amount of memory is temporarily allocated from the + stack in the draw_vline() method for drawing strings */ +#define MAX_DISP_LINE_LEN 1000 + +static int max( int i1, int i2 ); +static int min( int i1, int i2 ); +static int countlines( const char *string ); + +/* The variables below are used in a timer event to allow smooth + scrolling of the text area when the pointer has left the area. */ +static int scroll_direction = 0; +static int scroll_amount = 0; +static int scroll_y = 0; +static int scroll_x = 0; + +// CET - FIXME +#define TMPFONTWIDTH 6 + + + +/** + \brief Creates a new text display widget. + + \param X, Y, W, H position and size of widget + \param l label text, defaults to none + */ +Fl_Text_Display::Fl_Text_Display(int X, int Y, int W, int H, const char* l) +: Fl_Group(X, Y, W, H, l) { + int i; + + mMaxsize = 0; + damage_range1_start = damage_range1_end = -1; + damage_range2_start = damage_range2_end = -1; + dragPos = dragging = 0; + dragType = DRAG_NONE; + display_insert_position_hint = 0; + shortcut_ = 0; + + color(FL_BACKGROUND2_COLOR, FL_SELECTION_COLOR); + box(FL_DOWN_FRAME); + textsize(FL_NORMAL_SIZE); + textcolor(FL_FOREGROUND_COLOR); + textfont(FL_HELVETICA); + set_flag(SHORTCUT_LABEL); + + text_area.x = 0; + text_area.y = 0; + text_area.w = 0; + text_area.h = 0; + + mVScrollBar = new Fl_Scrollbar(0,0,1,1); + mVScrollBar->callback((Fl_Callback*)v_scrollbar_cb, this); + mHScrollBar = new Fl_Scrollbar(0,0,1,1); + mHScrollBar->callback((Fl_Callback*)h_scrollbar_cb, this); + mHScrollBar->type(FL_HORIZONTAL); + + end(); + + scrollbar_width(Fl::scrollbar_size()); + scrollbar_align(FL_ALIGN_BOTTOM_RIGHT); + + mCursorOn = 0; + mCursorPos = 0; + mCursorOldY = -100; + mCursorToHint = NO_HINT; + mCursorStyle = NORMAL_CURSOR; + mCursorPreferredXPos = -1; + mBuffer = 0; + mFirstChar = 0; + mLastChar = 0; + mNBufferLines = 0; + mTopLineNum = mTopLineNumHint = 1; + mAbsTopLineNum = 1; + mNeedAbsTopLineNum = 0; + mHorizOffset = mHorizOffsetHint = 0; + + mCursor_color = FL_FOREGROUND_COLOR; + + mStyleBuffer = 0; + mStyleTable = 0; + mNStyles = 0; + mNVisibleLines = 1; + mLineStarts = new int[mNVisibleLines]; + mLineStarts[0] = 0; + for (i=1; iremove_modify_callback(buffer_modified_cb, this); + mBuffer->remove_predelete_callback(buffer_predelete_cb, this); + } + if (mLineStarts) delete[] mLineStarts; +} + + + +/** + Attach a text buffer to display, replacing the current buffer (if any) + \param buf attach this text buffer + */ +void Fl_Text_Display::buffer( Fl_Text_Buffer *buf ) { + /* If the text display is already displaying a buffer, clear it off + of the display and remove our callback from it */ + if ( buf == mBuffer) return; + if ( mBuffer != 0 ) { + // we must provide a copy of the buffer that we are deleting! + char *deletedText = mBuffer->text(); + buffer_modified_cb( 0, 0, mBuffer->length(), 0, deletedText, this ); + free(deletedText); + mNBufferLines = 0; + mBuffer->remove_modify_callback( buffer_modified_cb, this ); + mBuffer->remove_predelete_callback( buffer_predelete_cb, this ); + } + + /* Add the buffer to the display, and attach a callback to the buffer for + receiving modification information when the buffer contents change */ + mBuffer = buf; + if (mBuffer) { + mBuffer->add_modify_callback( buffer_modified_cb, this ); + mBuffer->add_predelete_callback( buffer_predelete_cb, this ); + + /* Update the display */ + buffer_modified_cb( 0, buf->length(), 0, 0, 0, this ); + } + + /* Resize the widget to update the screen... */ + resize(x(), y(), w(), h()); +} + + + +/** + \brief Attach (or remove) highlight information in text display and redisplay. + + Highlighting information consists of a style buffer which parallels the + normal text buffer, but codes font and color information for the display; + a style table which translates style buffer codes (indexed by buffer + character - 'A') into fonts and colors; and a callback mechanism for + as-needed highlighting, triggered by a style buffer entry of + "unfinishedStyle". Style buffer can trigger additional redisplay during + a normal buffer modification if the buffer contains a primary Fl_Text_Selection + (see extendRangeForStyleMods for more information on this protocol). + + Style buffers, tables and their associated memory are managed by the caller. + + Styles are ranged from 65 ('A') to 126. + + \param styleBuffer this buffer works in parallel to the text buffer. For every + character in the text buffer, the stye buffer has a byte at the same offset + that contains an index into an array of possible styles. + \param styleTable a list of styles indexed by the style buffer + \param nStyles number of styles in the style table + \param unfinishedStyle if this style is found, the callback below is called + \param unfinishedHighlightCB if a character with an unfinished style is found, + this callback will be called + \param cbArg and optional argument for the callback above, usuallay a pointer + to the Text Display. + */ +void Fl_Text_Display::highlight_data(Fl_Text_Buffer *styleBuffer, + const Style_Table_Entry *styleTable, + int nStyles, char unfinishedStyle, + Unfinished_Style_Cb unfinishedHighlightCB, + void *cbArg ) { + mStyleBuffer = styleBuffer; + mStyleTable = styleTable; + mNStyles = nStyles; + mUnfinishedStyle = unfinishedStyle; + mUnfinishedHighlightCB = unfinishedHighlightCB; + mHighlightCBArg = cbArg; + mColumnScale = 0; + + mStyleBuffer->canUndo(0); + damage(FL_DAMAGE_EXPOSE); +} + + + +/** + \brief Find the longest line of all visible lines. + \return the width of the longest visible line in pixels + */ +int Fl_Text_Display::longest_vline() const { + int longest = 0; + for (int i = 0; i < mNVisibleLines; i++) + longest = max(longest, measure_vline(i)); + return longest; +} + + + +/** + \brief Change the size of the displayed text area + Calling this function will trigger a recalculation of all lines visible and + of all scrollbar sizes. + \param X, Y, W, H new position and size of this widget + */ +void Fl_Text_Display::resize(int X, int Y, int W, int H) { +#ifdef DEBUG + printf("Fl_Text_Display::resize(X=%d, Y=%d, W=%d, H=%d)\n", X, Y, W, H); +#endif // DEBUG + const int oldWidth = w(); +#ifdef DEBUG + printf(" oldWidth=%d, mContinuousWrap=%d, mWrapMargin=%d\n", oldWidth, mContinuousWrap, mWrapMargin); +#endif // DEBUG + Fl_Widget::resize(X,Y,W,H); + if (!buffer()) return; + X += Fl::box_dx(box()); + Y += Fl::box_dy(box()); + W -= Fl::box_dw(box()); + H -= Fl::box_dh(box()); + + text_area.x = X+LEFT_MARGIN; + text_area.y = Y+TOP_MARGIN; + text_area.w = W-LEFT_MARGIN-RIGHT_MARGIN; + text_area.h = H-TOP_MARGIN-BOTTOM_MARGIN; + int i; + + /* Find the new maximum font height for this text display */ + for (i = 0, mMaxsize = fl_height(textfont(), textsize()); i < mNStyles; i++) + mMaxsize = max(mMaxsize, fl_height(mStyleTable[i].font, mStyleTable[i].size)); + + // did we have scrollbars initially? + unsigned int hscrollbarvisible = mHScrollBar->visible(); + unsigned int vscrollbarvisible = mVScrollBar->visible(); + + // try without scrollbars first + mVScrollBar->clear_visible(); + mHScrollBar->clear_visible(); + + for (int again = 1; again;) { + again = 0; + /* In continuous wrap mode, a change in width affects the total number of + lines in the buffer, and can leave the top line number incorrect, and + the top character no longer pointing at a valid line start */ + if (mContinuousWrap && !mWrapMarginPix && W!=oldWidth) { + int oldFirstChar = mFirstChar; + mNBufferLines = count_lines(0, buffer()->length(), true); + mFirstChar = line_start(mFirstChar); + mTopLineNum = count_lines(0, mFirstChar, true)+1; + absolute_top_line_number(oldFirstChar); +#ifdef DEBUG + printf(" mNBufferLines=%d\n", mNBufferLines); +#endif // DEBUG + } + + /* reallocate and update the line starts array, which may have changed + size and / or contents. */ + int nvlines = (text_area.h + mMaxsize - 1) / mMaxsize; + if (nvlines < 1) nvlines = 1; + if (mNVisibleLines != nvlines) { + mNVisibleLines = nvlines; + if (mLineStarts) delete[] mLineStarts; + mLineStarts = new int [mNVisibleLines]; + } + + calc_line_starts(0, mNVisibleLines); + calc_last_char(); + + // figure the scrollbars + if (scrollbar_width()) { + /* Decide if the vertical scroll bar needs to be visible */ + if (scrollbar_align() & (FL_ALIGN_LEFT|FL_ALIGN_RIGHT) && + mNBufferLines >= mNVisibleLines - 1) + { + mVScrollBar->set_visible(); + if (scrollbar_align() & FL_ALIGN_LEFT) { + text_area.x = X+scrollbar_width()+LEFT_MARGIN; + text_area.w = W-scrollbar_width()-LEFT_MARGIN-RIGHT_MARGIN; + mVScrollBar->resize(X, text_area.y-TOP_MARGIN, scrollbar_width(), + text_area.h+TOP_MARGIN+BOTTOM_MARGIN); + } else { + text_area.x = X+LEFT_MARGIN; + text_area.w = W-scrollbar_width()-LEFT_MARGIN-RIGHT_MARGIN; + mVScrollBar->resize(X+W-scrollbar_width(), text_area.y-TOP_MARGIN, + scrollbar_width(), text_area.h+TOP_MARGIN+BOTTOM_MARGIN); + } + } + + /* + Decide if the horizontal scroll bar needs to be visible. If there + is a vertical scrollbar, a horizontal is always created too. This + is because the alternatives are unatractive: + * Dynamically creating a horizontal scrollbar based on the currently + visible lines is what the original nedit does, but it always wastes + space for the scrollbar even when it's not used. Since the FLTK + widget dynamically allocates the space for the scrollbar and + rearranges the widget to make room for it, this would create a very + visually displeasing "bounce" effect when the vertical scrollbar is + dragged. Trust me, I tried it and it looks really bad. + * The other alternative would be to keep track of what the longest + line in the entire buffer is and base the scrollbar on that. I + didn't do this because I didn't see any easy way to do that using + the nedit code and this could involve a lengthy calculation for + large buffers. If an efficient and non-costly way of doing this + can be found, this might be a way to go. + */ + /* WAS: Suggestion: Try turning the horizontal scrollbar on when + you first see a line that is too wide in the window, but then + don't turn it off (ie mix both of your solutions). */ + if (scrollbar_align() & (FL_ALIGN_TOP|FL_ALIGN_BOTTOM) && + (mVScrollBar->visible() || longest_vline() > text_area.w)) + { + if (!mHScrollBar->visible()) { + mHScrollBar->set_visible(); + again = 1; // loop again to see if we now need vert. & recalc sizes + } + if (scrollbar_align() & FL_ALIGN_TOP) { + text_area.y = Y + scrollbar_width()+TOP_MARGIN; + text_area.h = H - scrollbar_width()-TOP_MARGIN-BOTTOM_MARGIN; + mHScrollBar->resize(text_area.x-LEFT_MARGIN, Y, + text_area.w+LEFT_MARGIN+RIGHT_MARGIN, scrollbar_width()); + } else { + text_area.y = Y+TOP_MARGIN; + text_area.h = H - scrollbar_width()-TOP_MARGIN-BOTTOM_MARGIN; + mHScrollBar->resize(text_area.x-LEFT_MARGIN, Y+H-scrollbar_width(), + text_area.w+LEFT_MARGIN+RIGHT_MARGIN, scrollbar_width()); + } + } + } + } + + // user request to change viewport + if (mTopLineNumHint != mTopLineNum || mHorizOffsetHint != mHorizOffset) + scroll_(mTopLineNumHint, mHorizOffsetHint); + + // everything will fit in the viewport + if (mNBufferLines < mNVisibleLines || mBuffer == NULL || mBuffer->length() == 0) { + scroll_(1, mHorizOffset); + /* if empty lines become visible, there may be an opportunity to + display more text by scrolling down */ + } else { + while ( (mLineStarts[mNVisibleLines-2]==-1) + && scroll_(mTopLineNum-1, mHorizOffset)) + { } + } + + // user request to display insert position + if (display_insert_position_hint) + display_insert(); + + // in case horizontal offset is now greater than longest line + int maxhoffset = max(0, longest_vline()-text_area.w); + if (mHorizOffset > maxhoffset) + scroll_(mTopLineNumHint, maxhoffset); + + mTopLineNumHint = mTopLineNum; + mHorizOffsetHint = mHorizOffset; + display_insert_position_hint = 0; + + if (mContinuousWrap || + hscrollbarvisible != mHScrollBar->visible() || + vscrollbarvisible != mVScrollBar->visible()) + redraw(); + + update_v_scrollbar(); + update_h_scrollbar(); +} + + + +/** + \brief Refresh a rectangle of the text display. + \param left, top are in coordinates of the text drawing window. + \param width, height isze in pixels + */ +void Fl_Text_Display::draw_text( int left, int top, int width, int height ) { + int fontHeight, firstLine, lastLine, line; + + /* find the line number range of the display */ + fontHeight = mMaxsize ? mMaxsize : textsize_; + firstLine = ( top - text_area.y - fontHeight + 1 ) / fontHeight; + lastLine = ( top + height - text_area.y ) / fontHeight + 1; + + fl_push_clip( left, top, width, height ); + + /* draw the lines */ + for ( line = firstLine; line <= lastLine; line++ ) + draw_vline( line, left, left + width, 0, INT_MAX ); + + /* draw the line numbers if exposed area includes them */ + if (mLineNumWidth != 0 && left <= mLineNumLeft + mLineNumWidth) + draw_line_numbers(false); + + fl_pop_clip(); +} + + + +/** + \brief Marks text from start to end as needing a redraw. + This function will trigger a damage event and later a redraw of parts of + the widget. + \param startpos index of first character needing redraw + \param endpos index after last character needing redraw + */ +void Fl_Text_Display::redisplay_range(int startpos, int endpos) { + IS_UTF8_ALIGNED2(buffer(), startpos) + IS_UTF8_ALIGNED2(buffer(), endpos) + + if (damage_range1_start == -1 && damage_range1_end == -1) { + damage_range1_start = startpos; + damage_range1_end = endpos; + } else if ((startpos >= damage_range1_start && startpos <= damage_range1_end) || + (endpos >= damage_range1_start && endpos <= damage_range1_end)) { + damage_range1_start = min(damage_range1_start, startpos); + damage_range1_end = max(damage_range1_end, endpos); + } else if (damage_range2_start == -1 && damage_range2_end == -1) { + damage_range2_start = startpos; + damage_range2_end = endpos; + } else { + damage_range2_start = min(damage_range2_start, startpos); + damage_range2_end = max(damage_range2_end, endpos); + } + damage(FL_DAMAGE_SCROLL); +} + + + +/** + \brief Draw a range of text. + + Refresh all of the text between buffer positions "start" and "end" + not including the character at the position "end". + + If end points beyond the end of the buffer, refresh the whole display + after pos, including blank lines which are not technically part of + any range of characters. + + \param startpos index of first character to draw + \param endpos index after last character to draw + */ +void Fl_Text_Display::draw_range(int startpos, int endpos) { + startpos = buffer()->utf8_align(startpos); + endpos = buffer()->utf8_align(endpos); + + int i, startLine, lastLine, startIndex, endIndex; + + /* If the range is outside of the displayed text, just return */ + if ( endpos < mFirstChar || ( startpos > mLastChar && !empty_vlines() ) ) + return; + + /* Clean up the starting and ending values */ + if ( startpos < 0 ) startpos = 0; + if ( startpos > mBuffer->length() ) startpos = mBuffer->length(); + if ( endpos < 0 ) endpos = 0; + if ( endpos > mBuffer->length() ) endpos = mBuffer->length(); + + /* Get the starting and ending lines */ + if ( startpos < mFirstChar ) + startpos = mFirstChar; + if ( !position_to_line( startpos, &startLine ) ) + startLine = mNVisibleLines - 1; + if ( endpos >= mLastChar ) { + lastLine = mNVisibleLines - 1; + } else { + if ( !position_to_line( endpos, &lastLine ) ) { + /* shouldn't happen */ + lastLine = mNVisibleLines - 1; + } + } + + /* Get the starting and ending positions within the lines */ + startIndex = mLineStarts[ startLine ] == -1 ? 0 : startpos - mLineStarts[ startLine ]; + if ( endpos >= mLastChar ) + endIndex = INT_MAX; + else if ( mLineStarts[ lastLine ] == -1 ) + endIndex = 0; + else + endIndex = endpos - mLineStarts[ lastLine ]; + + /* If the starting and ending lines are the same, redisplay the single + line between "start" and "end" */ + if ( startLine == lastLine ) { + draw_vline( startLine, 0, INT_MAX, startIndex, endIndex ); + return; + } + + /* Redisplay the first line from "start" */ + draw_vline( startLine, 0, INT_MAX, startIndex, INT_MAX ); + + /* Redisplay the lines in between at their full width */ + for ( i = startLine + 1; i < lastLine; i++ ) + draw_vline( i, 0, INT_MAX, 0, INT_MAX ); + + /* Redisplay the last line to "end" */ + draw_vline( lastLine, 0, INT_MAX, 0, endIndex ); +} + + + +/** + \brief Sets the position of the text insertion cursor for text display. + Move the insertion cursor in front of the character at \p newPos. + This function may trigger a redraw. + \param newPos new caret position + */ +void Fl_Text_Display::insert_position( int newPos ) { + IS_UTF8_ALIGNED2(buffer(), newPos) + + /* make sure new position is ok, do nothing if it hasn't changed */ + if ( newPos == mCursorPos ) return; + if ( newPos < 0 ) newPos = 0; + if ( newPos > mBuffer->length() ) newPos = mBuffer->length(); + + /* cursor movement cancels vertical cursor motion column */ + mCursorPreferredXPos = -1; + + /* erase the cursor at it's previous position */ + redisplay_range(buffer()->prev_char_clipped(mCursorPos), buffer()->next_char(mCursorPos)); + + mCursorPos = newPos; + + /* draw cursor at its new position */ + redisplay_range(buffer()->prev_char_clipped(mCursorPos), buffer()->next_char(mCursorPos)); +} + + + +/** + \brief Shows the text cursor. + This function may trigger a redraw. + \param b show(1) or hide(0) the text cursor (caret). + */ +void Fl_Text_Display::show_cursor(int b) { + mCursorOn = b; + redisplay_range(buffer()->prev_char_clipped(mCursorPos), buffer()->next_char(mCursorPos)); +} + + + +/** + \brief Sets the text cursor style. + Sets the text cursor style to one of the following: + + \li Fl_Text_Display::NORMAL_CURSOR - Shows an I beam. + \li Fl_Text_Display::CARET_CURSOR - Shows a caret under the text. + \li Fl_Text_Display::DIM_CURSOR - Shows a dimmed I beam. + \li Fl_Text_Display::BLOCK_CURSOR - Shows an unfilled box around the current + character. + \li Fl_Text_Display::HEAVY_CURSOR - Shows a thick I beam. + + This call also switches the cursor on and may trigger a redraw. + + \param style new cursor style + */ +void Fl_Text_Display::cursor_style(int style) { + mCursorStyle = style; + if (mCursorOn) show_cursor(); +} + + + +/** + \brief Set the new text wrap mode. + + If \p mode is not zero, this call enables automatic word wrapping at column + \p pos. Word-wrapping does not change the text buffer itself, only the way that + the text is displayed. Different Text Displays can have different wrap modes, + even if they share the same Text Buffer. + + \param wrap new wrap mode is WRAP_NONE (don't wrap text at all), WRAP_AT_COLUMN + (wrap text at the given text column), WRAP_AT_PIXEL (wrap text at a pixel + position), or WRAP_AT_BOUNDS (wrap text so that it fits into the + widget width) + \param wrapMargin in WRAP_AT_COLUMN mode, text will wrap at the n'th character. + For variable width fonts, an average character width is calculated. The + column width is calculated using the current textfont or the first style + when this function is called. If the font size changes, this function + must be called again. In WRAP_AT_PIXEL mode, this is the pixel position. + \todo we need new wrap modes to wrap at the window edge and based on pixel width + or average character width. + */ +void Fl_Text_Display::wrap_mode(int wrap, int wrapMargin) { + switch (wrap) { + case WRAP_NONE: + mWrapMarginPix = 0; + mContinuousWrap = 0; + break; + case WRAP_AT_COLUMN: + default: + mWrapMarginPix = int(col_to_x(wrapMargin)); + mContinuousWrap = 1; + break; + case WRAP_AT_PIXEL: + mWrapMarginPix = wrapMargin; + mContinuousWrap = 1; + break; + case WRAP_AT_BOUNDS: + mWrapMarginPix = 0; + mContinuousWrap = 1; + break; + } + + if (buffer()) { + /* wrapping can change the total number of lines, re-count */ + mNBufferLines = count_lines(0, buffer()->length(), true); + + /* changing wrap margins or changing from wrapped mode to non-wrapped + can leave the character at the top no longer at a line start, and/or + change the line number */ + mFirstChar = line_start(mFirstChar); + mTopLineNum = count_lines(0, mFirstChar, true) + 1; + + reset_absolute_top_line_number(); + + /* update the line starts array */ + calc_line_starts(0, mNVisibleLines); + calc_last_char(); + } else { + // No buffer, so just clear the state info for later... + mNBufferLines = 0; + mFirstChar = 0; + mTopLineNum = 1; + mAbsTopLineNum = 0; + } + + resize(x(), y(), w(), h()); +} + + + +/** + \brief Inserts "text" at the current cursor location. + + This has the same effect as inserting the text into the buffer using BufInsert + and then moving the insert position after the newly inserted text, except + that it's optimized to do less redrawing. + + \param text new text in UTF-8 encoding. + */ +void Fl_Text_Display::insert(const char* text) { + IS_UTF8_ALIGNED2(buffer(), mCursorPos) + IS_UTF8_ALIGNED(text) + + int pos = mCursorPos; + + mCursorToHint = pos + strlen( text ); + mBuffer->insert( pos, text ); + mCursorToHint = NO_HINT; +} + + + +/** + \brief Replaces text at the current insert position. + \param text new text in UTF-8 encoding + + \todo Unicode? Find out exactly what we do here and simplify. + */ +void Fl_Text_Display::overstrike(const char* text) { + IS_UTF8_ALIGNED2(buffer(), mCursorPos) + IS_UTF8_ALIGNED(text) + + int startPos = mCursorPos; + Fl_Text_Buffer *buf = mBuffer; + int lineStart = buf->line_start( startPos ); + int textLen = strlen( text ); + int i, p, endPos, indent, startIndent, endIndent; + const char *c; + unsigned int ch; + char *paddedText = NULL; + + /* determine how many displayed character positions are covered */ + startIndent = mBuffer->count_displayed_characters( lineStart, startPos ); + indent = startIndent; + for ( c = text; *c != '\0'; c += fl_utf8len(*c) ) + indent++; + endIndent = indent; + + /* find which characters to remove, and if necessary generate additional + padding to make up for removed control characters at the end */ + indent = startIndent; + for ( p = startPos; ; p=buffer()->next_char(p) ) { + if ( p == buf->length() ) + break; + ch = buf->char_at( p ); + if ( ch == '\n' ) + break; + indent++; + if ( indent == endIndent ) { + p++; + break; + } else if ( indent > endIndent ) { + if ( ch != '\t' ) { + p++; + paddedText = new char [ textLen + FL_TEXT_MAX_EXP_CHAR_LEN + 1 ]; + strcpy( paddedText, text ); + for ( i = 0; i < indent - endIndent; i++ ) + paddedText[ textLen + i ] = ' '; + paddedText[ textLen + i ] = '\0'; + } + break; + } + } + endPos = p; + + mCursorToHint = startPos + textLen; + buf->replace( startPos, endPos, paddedText == NULL ? text : paddedText ); + mCursorToHint = NO_HINT; + if ( paddedText != NULL ) + delete [] paddedText; +} + + + +/** + \brief Convert a character index into a pixel position. + + Translate a buffer text position to the XY location where the top left of the + cursor would be positioned to point to that character. Returns 0 if the + position is not displayed because it is VERTICALLY out of view. If the position + is horizontally out of view, returns the X coordinate where the position would + be if it were visible. + + \param pos character index + \param[out] X, Y pixel position of character on screen + \return 0 if charater vertically out of view, X position otherwise + */ +int Fl_Text_Display::position_to_xy( int pos, int* X, int* Y ) const { + IS_UTF8_ALIGNED2(buffer(), pos) + + int lineStartPos, fontHeight, lineLen; + int visLineNum; + + /* If position is not displayed, return false */ + if (pos < mFirstChar || (pos > mLastChar && !empty_vlines())) { + return 0; + } + + /* Calculate Y coordinate */ + if (!position_to_line(pos, &visLineNum)) { + return 0; + } + if (visLineNum < 0 || visLineNum > mNBufferLines) { + return 0; + } + + fontHeight = mMaxsize; + *Y = text_area.y + visLineNum * fontHeight; + + /* Get the text, length, and buffer position of the line. If the position + is beyond the end of the buffer and should be at the first position on + the first empty line, don't try to get or scan the text */ + lineStartPos = mLineStarts[visLineNum]; + if ( lineStartPos == -1 ) { + *X = text_area.x - mHorizOffset; + return 1; + } + lineLen = vline_length( visLineNum ); + *X = text_area.x + handle_vline(GET_WIDTH, lineStartPos, pos-lineStartPos, 0, 0, 0, 0, 0, 0) - mHorizOffset; + return 1; +} + + + +/** + \brief Find the line and column number of position "pos". + + This only works for displayed lines. If the line is not displayed, the + function returns 0 (without the mLineStarts array it could turn in to very long + calculation involving scanning large amounts of text in the buffer). + If continuous wrap mode is on, returns the absolute line number (as opposed + to the wrapped line number which is used for scrolling). + + \param pos character index + \param[out] lineNum absoluet (unwrapped) line number + \param[out] column character offset to the beginning of the line * + \return 0 if /p pos is off screen, line number otherwise + \todo a column number makes little sense in the UTF-8/variable font width + environment. We will have to further define what exactly we want to return. + Please check teh functions that call this particular function. + */ +int Fl_Text_Display::position_to_linecol( int pos, int* lineNum, int* column ) const { + IS_UTF8_ALIGNED2(buffer(), pos) + + int retVal; + + /* In continuous wrap mode, the absolute (non-wrapped) line count is + maintained separately, as needed. Only return it if we're actually + keeping track of it and pos is in the displayed text */ + if (mContinuousWrap) { + if (!maintaining_absolute_top_line_number() || pos < mFirstChar || pos > mLastChar) + return 0; + *lineNum = mAbsTopLineNum + buffer()->count_lines(mFirstChar, pos); + *column = buffer()->count_displayed_characters(buffer()->line_start(pos), pos); + return 1; + } + + retVal = position_to_line( pos, lineNum ); + if ( retVal ) { + *column = mBuffer->count_displayed_characters( mLineStarts[ *lineNum ], pos ); + *lineNum += mTopLineNum; + } + return retVal; +} + + + +/** + \brief Check if a pixel position is within the primary seection. + \param X, Y pixel position to test + \return 1 if position (X, Y) is inside of the primary Fl_Text_Selection + */ +int Fl_Text_Display::in_selection( int X, int Y ) const { + int pos = xy_to_position( X, Y, CHARACTER_POS ); + IS_UTF8_ALIGNED2(buffer(), pos) + Fl_Text_Buffer *buf = mBuffer; + return buf->primary_selection()->includes(pos); +} + + + +/** + \brief Nobody knows what this function does. + + Correct a column number based on an unconstrained position (as returned by + TextDXYToUnconstrainedPosition) to be relative to the last actual newline + in the buffer before the row and column position given, rather than the + last line start created by line wrapping. This is an adapter + for rectangular selections and code written before continuous wrap mode, + which thinks that the unconstrained column is the number of characters + from the last newline. Obviously this is time consuming, because it + invloves character re-counting. + + \param row + \param column + \return something unknown + \todo What does this do and how is it useful? Column numbers mean little in + this context. Which functions depend on this one? + + \todo Unicode? + */ +int Fl_Text_Display::wrapped_column(int row, int column) const { + int lineStart, dispLineStart; + + if (!mContinuousWrap || row < 0 || row > mNVisibleLines) + return column; + dispLineStart = mLineStarts[row]; + if (dispLineStart == -1) + return column; + lineStart = buffer()->line_start(dispLineStart); + return column + buffer()->count_displayed_characters(lineStart, dispLineStart); +} + + + +/** + \brief Nobody knows what this function does. + + Correct a row number from an unconstrained position (as returned by + TextDXYToUnconstrainedPosition) to a straight number of newlines from the + top line of the display. Because rectangular selections are based on + newlines, rather than display wrapping, and anywhere a rectangular selection + needs a row, it needs it in terms of un-wrapped lines. + + \param row + \param column + \return something unknown + \todo What does this do and how is it useful? Column numbers mean little in + this context. Which functions depend on this one? + */ +int Fl_Text_Display::wrapped_row(int row) const{ + if (!mContinuousWrap || row < 0 || row > mNVisibleLines) + return row; + return buffer()->count_lines(mFirstChar, mLineStarts[row]); +} + + + +/** + \brief Scroll the display to bring insertion cursor into view. + + Note: it would be nice to be able to do this without counting lines twice + (scroll_() counts them too) and/or to count from the most efficient + starting point, but the efficiency of this routine is not as important to + the overall performance of the text display. + + \todo Unicode? + */ +void Fl_Text_Display::display_insert() { + int hOffset, topLine, X, Y; + hOffset = mHorizOffset; + topLine = mTopLineNum; + + if (insert_position() < mFirstChar) { + topLine -= count_lines(insert_position(), mFirstChar, false); + } else if (mLineStarts[mNVisibleLines-2] != -1) { + int lastChar = line_end(mLineStarts[mNVisibleLines-2],true); + if (insert_position() >= lastChar) + topLine += count_lines(lastChar - (wrap_uses_character(mLastChar) ? 0 : 1), + insert_position(), false); + } + + /* Find the new setting for horizontal offset (this is a bit ungraceful). + If the line is visible, just use PositionToXY to get the position + to scroll to, otherwise, do the vertical scrolling first, then the + horizontal */ + if (!position_to_xy( mCursorPos, &X, &Y )) { + scroll_(topLine, hOffset); + if (!position_to_xy( mCursorPos, &X, &Y )) { +#ifdef DEBUG + printf ("*** display_insert/position_to_xy # GIVE UP !\n"); fflush(stdout); +#endif // DEBUG + return; /* Give up, it's not worth it (but why does it fail?) */ + } + } + if (X > text_area.x + text_area.w) + hOffset += X-(text_area.x + text_area.w); + else if (X < text_area.x) + hOffset += X-text_area.x; + + /* Do the scroll */ + if (topLine != mTopLineNum || hOffset != mHorizOffset) + scroll_(topLine, hOffset); +} + + +/** + \brief Scrolls the text buffer to show the current insert position. + This function triggers a complete recalculation, ending in a call to + Fl_Text_Display::display_insert() + */ +void Fl_Text_Display::show_insert_position() { + display_insert_position_hint = 1; + resize(x(), y(), w(), h()); +} + + + +/* + Cursor movement functions + */ + + + +/** + \brief Moves the current insert position right one character. + \return 1 if the cursor moved, 0 if the end of the text was reached + */ +int Fl_Text_Display::move_right() { + if ( mCursorPos >= mBuffer->length() ) + return 0; + int p = insert_position(); + int q = buffer()->next_char(p); + insert_position(q); + return 1; +} + + + +/** + \brief Moves the current insert position left one character. + \return 1 if the cursor moved, 0 if the beginning of the text was reached + */ +int Fl_Text_Display::move_left() { + if ( mCursorPos <= 0 ) + return 0; + int p = insert_position(); + int q = buffer()->prev_char_clipped(p); + insert_position(q); + return 1; +} + + + +/** + \brief Moves the current insert position up one line. + \return 1 if the cursor moved, 0 if the beginning of the text was reached + */ +int Fl_Text_Display::move_up() { + int lineStartPos, xPos, prevLineStartPos, newPos, visLineNum; + + /* Find the position of the start of the line. Use the line starts array + if possible */ + if ( position_to_line( mCursorPos, &visLineNum ) ) + lineStartPos = mLineStarts[ visLineNum ]; + else { + lineStartPos = line_start( mCursorPos ); + visLineNum = -1; + } + if ( lineStartPos == 0 ) + return 0; + + /* Decide what column to move to, if there's a preferred column use that */ + if (mCursorPreferredXPos >= 0) + xPos = mCursorPreferredXPos; + else + xPos = handle_vline(GET_WIDTH, lineStartPos, mCursorPos-lineStartPos, + 0, 0, 0, 0, 0, INT_MAX); + + /* count forward from the start of the previous line to reach the column */ + if ( visLineNum != -1 && visLineNum != 0 ) + prevLineStartPos = mLineStarts[ visLineNum - 1 ]; + else + prevLineStartPos = rewind_lines( lineStartPos, 1 ); + + int lineEnd = line_end(prevLineStartPos, true); + newPos = handle_vline(FIND_INDEX_FROM_ZERO, prevLineStartPos, lineEnd-prevLineStartPos, + 0, 0, 0, 0, 0, xPos); + + /* move the cursor */ + insert_position( newPos ); + + /* if a preferred column wasn't aleady established, establish it */ + mCursorPreferredXPos = xPos; + return 1; +} + + + +/** + \brief Moves the current insert position down one line. + \return 1 if the cursor moved, 0 if the beginning of the text was reached + */ +int Fl_Text_Display::move_down() { + int lineStartPos, xPos, newPos, visLineNum; + + if ( mCursorPos == mBuffer->length() ) + return 0; + + if ( position_to_line( mCursorPos, &visLineNum ) ) + lineStartPos = mLineStarts[ visLineNum ]; + else { + lineStartPos = line_start( mCursorPos ); + visLineNum = -1; + } + if (mCursorPreferredXPos >= 0) { + xPos = mCursorPreferredXPos; + } else { + xPos = handle_vline(GET_WIDTH, lineStartPos, mCursorPos-lineStartPos, + 0, 0, 0, 0, 0, INT_MAX); + } + + int nextLineStartPos = skip_lines( lineStartPos, 1, true ); + int lineEnd = line_end(nextLineStartPos, true); + newPos = handle_vline(FIND_INDEX_FROM_ZERO, nextLineStartPos, lineEnd-nextLineStartPos, + 0, 0, 0, 0, 0, xPos); + + insert_position( newPos ); + mCursorPreferredXPos = xPos; + return 1; +} + + + +/** + \brief Count the number of lines between two positions. + + Same as BufCountLines, but takes in to account wrapping if wrapping is + turned on. If the caller knows that startPos is at a line start, it + can pass "startPosIsLineStart" as True to make the call more efficient + by avoiding the additional step of scanning back to the last newline. + + \param startPos index to forst character + \param endPos index after last character + \param startPosIsLineStart avoid scanning back to the line start + \retun number of lines + */ +int Fl_Text_Display::count_lines(int startPos, int endPos, + bool startPosIsLineStart) const { + IS_UTF8_ALIGNED2(buffer(), startPos) + IS_UTF8_ALIGNED2(buffer(), endPos) + + int retLines, retPos, retLineStart, retLineEnd; + +#ifdef DEBUG + printf("Fl_Text_Display::count_lines(startPos=%d, endPos=%d, startPosIsLineStart=%d\n", + startPos, endPos, startPosIsLineStart); +#endif // DEBUG + + /* If we're not wrapping use simple (and more efficient) BufCountLines */ + if (!mContinuousWrap) + return buffer()->count_lines(startPos, endPos); + + wrapped_line_counter(buffer(), startPos, endPos, INT_MAX, + startPosIsLineStart, 0, &retPos, &retLines, &retLineStart, + &retLineEnd); + +#ifdef DEBUG + printf(" # after WLC: retPos=%d, retLines=%d, retLineStart=%d, retLineEnd=%d\n", + retPos, retLines, retLineStart, retLineEnd); +#endif // DEBUG + + return retLines; +} + + + +/** + \brief Skip a number of lines forward. + + Same as BufCountForwardNLines, but takes in to account line breaks when + wrapping is turned on. If the caller knows that startPos is at a line start, + it can pass "startPosIsLineStart" as True to make the call more efficient + by avoiding the additional step of scanning back to the last newline. + + \param startPos index to starting character + \param nLines number of lines to skip ahead + \param startPosIsLineStart avoid scanning back to the line start + \return new position as index + */ +int Fl_Text_Display::skip_lines(int startPos, int nLines, + bool startPosIsLineStart) { + IS_UTF8_ALIGNED2(buffer(), startPos) + + int retLines, retPos, retLineStart, retLineEnd; + + /* if we're not wrapping use more efficient BufCountForwardNLines */ + if (!mContinuousWrap) + return buffer()->skip_lines(startPos, nLines); + + /* wrappedLineCounter can't handle the 0 lines case */ + if (nLines == 0) + return startPos; + + /* use the common line counting routine to count forward */ + wrapped_line_counter(buffer(), startPos, buffer()->length(), + nLines, startPosIsLineStart, 0, + &retPos, &retLines, &retLineStart, &retLineEnd); + IS_UTF8_ALIGNED2(buffer(), retPos) + return retPos; +} + + + +/** + \brief Return the end of a line. + + Same as BufEndOfLine, but takes in to account line breaks when wrapping + is turned on. If the caller knows that startPos is at a line start, it + can pass "startPosIsLineStart" as True to make the call more efficient + by avoiding the additional step of scanning back to the last newline. + + Note that the definition of the end of a line is less clear when continuous + wrap is on. With continuous wrap off, it's just a pointer to the newline + that ends the line. When it's on, it's the character beyond the last + DISPLAYABLE character on the line, where a whitespace character which has + been "converted" to a newline for wrapping is not considered displayable. + Also note that, a line can be wrapped at a non-whitespace character if the + line had no whitespace. In this case, this routine returns a pointer to + the start of the next line. This is also consistent with the model used by + visLineLength. + + \param startPos index to starting character + \param startPosIsLineStart avoid scanning back to the line start + \retun new position as index + */ +int Fl_Text_Display::line_end(int pos, bool startPosIsLineStart) const { + IS_UTF8_ALIGNED2(buffer(), pos) + + int retLines, retPos, retLineStart, retLineEnd; + + /* If we're not wrapping use more efficien BufEndOfLine */ + if (!mContinuousWrap) + return buffer()->line_end(pos); + + if (pos == buffer()->length()) + return pos; + + wrapped_line_counter(buffer(), pos, buffer()->length(), 1, + startPosIsLineStart, 0, &retPos, &retLines, &retLineStart, + &retLineEnd); + + IS_UTF8_ALIGNED2(buffer(), retLineEnd) + return retLineEnd; +} + + + +/** + \brief Return the beginning of a line. + + Same as BufStartOfLine, but returns the character after last wrap point + rather than the last newline. + + \param pos index to starting character + \return new position as index + */ +int Fl_Text_Display::line_start(int pos) const { + IS_UTF8_ALIGNED2(buffer(), pos) + + int retLines, retPos, retLineStart, retLineEnd; + + /* If we're not wrapping, use the more efficient BufStartOfLine */ + if (!mContinuousWrap) + return buffer()->line_start(pos); + + wrapped_line_counter(buffer(), buffer()->line_start(pos), pos, INT_MAX, true, 0, + &retPos, &retLines, &retLineStart, &retLineEnd); + + IS_UTF8_ALIGNED2(buffer(), retLineStart) + return retLineStart; +} + + + +/** + \brief Skip a number of lines back. + + Same as BufCountBackwardNLines, but takes in to account line breaks when + wrapping is turned on. + + \param startPos index to starting character + \param nLines number of lines to skip back + \return new position as index + */ +int Fl_Text_Display::rewind_lines(int startPos, int nLines) { + IS_UTF8_ALIGNED2(buffer(), startPos) + + Fl_Text_Buffer *buf = buffer(); + int pos, lineStart, retLines, retPos, retLineStart, retLineEnd; + + /* If we're not wrapping, use the more efficient BufCountBackwardNLines */ + if (!mContinuousWrap) + return buf->rewind_lines(startPos, nLines); + + pos = startPos; + for (;;) { + lineStart = buf->line_start(pos); + wrapped_line_counter(buf, lineStart, pos, INT_MAX, true, 0, + &retPos, &retLines, &retLineStart, &retLineEnd, false); + if (retLines > nLines) + return skip_lines(lineStart, retLines-nLines, true); + nLines -= retLines; + pos = lineStart - 1; + if (pos < 0) + return 0; + nLines -= 1; + } +} + + + +static inline int fl_isseparator(unsigned int c) { + // FIXME: this does not take UCS-4 encoding into account + return c != '$' && c != '_' && (isspace(c) || ispunct(c)); +} + + + +/** + \brief Moves the current insert position right one word. + */ +void Fl_Text_Display::next_word() { + int pos = insert_position(); + + while (pos < buffer()->length() && !fl_isseparator(buffer()->char_at(pos))) { + pos = buffer()->next_char(pos); + } + + while (pos < buffer()->length() && fl_isseparator(buffer()->char_at(pos))) { + pos = buffer()->next_char(pos); + } + + insert_position( pos ); +} + + + +/** + \brief Moves the current insert position left one word. + */ +void Fl_Text_Display::previous_word() { + int pos = insert_position(); + if (pos==0) return; + pos = buffer()->prev_char(pos); + + while (pos && fl_isseparator(buffer()->char_at(pos))) { + pos = buffer()->prev_char(pos); + } + + while (pos && !fl_isseparator(buffer()->char_at(pos))) { + pos = buffer()->prev_char(pos); + } + + if (fl_isseparator(buffer()->char_at(pos))) { + pos = buffer()->next_char(pos); + } + + insert_position( pos ); +} + + + +/** + \brief This is called before any characters are deleted. + + Callback attached to the text buffer to receive delete information before + the modifications are actually made. + + \param pos starting index of deletion + \param nDeleted number of bytes we will delete (must be UTF-8 aligned!) + \param cbArg "this" pointer for static callback function + */ +void Fl_Text_Display::buffer_predelete_cb(int pos, int nDeleted, void *cbArg) { + Fl_Text_Display *textD = (Fl_Text_Display *)cbArg; + if (textD->mContinuousWrap) { + /* Note: we must perform this measurement, even if there is not a + single character deleted; the number of "deleted" lines is the + number of visual lines spanned by the real line in which the + modification takes place. + Also, a modification of the tab distance requires the same + kind of calculations in advance, even if the font width is "fixed", + because when the width of the tab characters changes, the layout + of the text may be completely different. */ + IS_UTF8_ALIGNED2(textD->buffer(), pos) + textD->measure_deleted_lines(pos, nDeleted); + } else { + textD->mSuppressResync = 0; /* Probably not needed, but just in case */ + } +} + + + +/** + \brief This is called whenever the buffer is modified. + + Callback attached to the text buffer to receive modification information + + \param pos starting index of modificatiom + \param nInserted number of bytes we inserted (must be UTF-8 aligned!) + \param nDeleted number of bytes deleted (must be UTF-8 aligned!) + \param nRestyled ?? + \param deletedText this is what was removed, must not be NULL if nDeleted is set + \param cbArg "this" pointer for static callback function + */ +void Fl_Text_Display::buffer_modified_cb( int pos, int nInserted, int nDeleted, + int nRestyled, const char *deletedText, void *cbArg ) { + int linesInserted, linesDeleted, startDispPos, endDispPos; + Fl_Text_Display *textD = ( Fl_Text_Display * ) cbArg; + Fl_Text_Buffer *buf = textD->mBuffer; + int oldFirstChar = textD->mFirstChar; + int scrolled, origCursorPos = textD->mCursorPos; + int wrapModStart, wrapModEnd; + + IS_UTF8_ALIGNED2(buf, pos) + IS_UTF8_ALIGNED2(buf, oldFirstChar) + + /* buffer modification cancels vertical cursor motion column */ + if ( nInserted != 0 || nDeleted != 0 ) + textD->mCursorPreferredXPos = -1; + + /* Count the number of lines inserted and deleted, and in the case + of continuous wrap mode, how much has changed */ + if (textD->mContinuousWrap) { + textD->find_wrap_range(deletedText, pos, nInserted, nDeleted, + &wrapModStart, &wrapModEnd, &linesInserted, &linesDeleted); + } else { + linesInserted = nInserted == 0 ? 0 : buf->count_lines( pos, pos + nInserted ); + linesDeleted = nDeleted == 0 ? 0 : countlines( deletedText ); + } + + /* Update the line starts and mTopLineNum */ + if ( nInserted != 0 || nDeleted != 0 ) { + if (textD->mContinuousWrap) { + textD->update_line_starts( wrapModStart, wrapModEnd-wrapModStart, + nDeleted + pos-wrapModStart + (wrapModEnd-(pos+nInserted)), + linesInserted, linesDeleted, &scrolled ); + } else { + textD->update_line_starts( pos, nInserted, nDeleted, linesInserted, + linesDeleted, &scrolled ); + } + } else + scrolled = 0; + + /* If we're counting non-wrapped lines as well, maintain the absolute + (non-wrapped) line number of the text displayed */ + if (textD->maintaining_absolute_top_line_number() && + (nInserted != 0 || nDeleted != 0)) { + if (deletedText && (pos + nDeleted < oldFirstChar)) + textD->mAbsTopLineNum += buf->count_lines(pos, pos + nInserted) - + countlines(deletedText); + else if (pos < oldFirstChar) + textD->reset_absolute_top_line_number(); + } + + /* Update the line count for the whole buffer */ + textD->mNBufferLines += linesInserted - linesDeleted; + + /* Update the cursor position */ + if ( textD->mCursorToHint != NO_HINT ) { + textD->mCursorPos = textD->mCursorToHint; + textD->mCursorToHint = NO_HINT; + } else if ( textD->mCursorPos > pos ) { + if ( textD->mCursorPos < pos + nDeleted ) + textD->mCursorPos = pos; + else + textD->mCursorPos += nInserted - nDeleted; + } + + // refigure scrollbars & stuff + textD->resize(textD->x(), textD->y(), textD->w(), textD->h()); + + // don't need to do anything else if not visible? + if (!textD->visible_r()) return; + + /* If the changes caused scrolling, re-paint everything and we're done. */ + if ( scrolled ) { + textD->damage(FL_DAMAGE_EXPOSE); + if ( textD->mStyleBuffer ) /* See comments in extendRangeForStyleMods */ + textD->mStyleBuffer->primary_selection()->selected(0); + return; + } + + /* If the changes didn't cause scrolling, decide the range of characters + that need to be re-painted. Also if the cursor position moved, be + sure that the redisplay range covers the old cursor position so the + old cursor gets erased, and erase the bits of the cursor which extend + beyond the left and right edges of the text. */ + startDispPos = textD->mContinuousWrap ? wrapModStart : pos; + IS_UTF8_ALIGNED2(buf, startDispPos) + + if ( origCursorPos == startDispPos && textD->mCursorPos != startDispPos ) + startDispPos = min( startDispPos, buf->prev_char_clipped(origCursorPos) ); + IS_UTF8_ALIGNED2(buf, startDispPos) + + if ( linesInserted == linesDeleted ) { + if ( nInserted == 0 && nDeleted == 0 ) + endDispPos = pos + nRestyled; + else { + if (textD->mContinuousWrap) + endDispPos = wrapModEnd; + else + endDispPos = buf->next_char(buf->line_end( pos + nInserted )); + + // CET - FIXME if ( origCursorPos >= startDispPos && + // ( origCursorPos <= endDispPos || endDispPos == buf->length() ) ) + } + + if (linesInserted > 1) textD->draw_line_numbers(false); + } else { + endDispPos = buf->next_char(textD->mLastChar); + // CET - FIXME if ( origCursorPos >= pos ) + /* If more than one line is inserted/deleted, a line break may have + been inserted or removed in between, and the line numbers may + have changed. If only one line is altered, line numbers cannot + be affected (the insertion or removal of a line break always + results in at least two lines being redrawn). */ + textD->draw_line_numbers(false); + } + IS_UTF8_ALIGNED2(buf, startDispPos) + IS_UTF8_ALIGNED2(buf, endDispPos) + + /* If there is a style buffer, check if the modification caused additional + changes that need to be redisplayed. (Redisplaying separately would + cause double-redraw on almost every modification involving styled + text). Extend the redraw range to incorporate style changes */ + if ( textD->mStyleBuffer ) + textD->extend_range_for_styles( &startDispPos, &endDispPos ); + IS_UTF8_ALIGNED2(buf, startDispPos) + IS_UTF8_ALIGNED2(buf, endDispPos) + + /* Redisplay computed range */ + textD->redisplay_range( startDispPos, endDispPos ); +} + + + +/** + \brief Line numbering stuff, currently unused. + + In continuous wrap mode, internal line numbers are calculated after + wrapping. A separate non-wrapped line count is maintained when line + numbering is turned on. There is some performance cost to maintaining this + line count, so normally absolute line numbers are not tracked if line + numbering is off. This routine allows callers to specify that they still + want this line count maintained (for use via TextDPosToLineAndCol). + More specifically, this allows the line number reported in the statistics + line to be calibrated in absolute lines, rather than post-wrapped lines. + */ +void Fl_Text_Display::maintain_absolute_top_line_number(int state) { + mNeedAbsTopLineNum = state; + reset_absolute_top_line_number(); +} + + + +/** + \brief Line numbering stuff, currently unused. + + Returns the absolute (non-wrapped) line number of the first line displayed. + Returns 0 if the absolute top line number is not being maintained. + */ +int Fl_Text_Display::get_absolute_top_line_number() const { + if (!mContinuousWrap) + return mTopLineNum; + if (maintaining_absolute_top_line_number()) + return mAbsTopLineNum; + return 0; +} + + + +/** + \brief Line numbering stuff, currently unused. + + Re-calculate absolute top line number for a change in scroll position. + */ +void Fl_Text_Display::absolute_top_line_number(int oldFirstChar) { + if (maintaining_absolute_top_line_number()) { + if (mFirstChar < oldFirstChar) + mAbsTopLineNum -= buffer()->count_lines(mFirstChar, oldFirstChar); + else + mAbsTopLineNum += buffer()->count_lines(oldFirstChar, mFirstChar); + } +} + + + +/** + \brief Line numbering stuff, currently unused. + + Return true if a separate absolute top line number is being maintained + (for displaying line numbers or showing in the statistics line). + */ +int Fl_Text_Display::maintaining_absolute_top_line_number() const { + return mContinuousWrap && + (mLineNumWidth != 0 || mNeedAbsTopLineNum); +} + + + +/** + \brief Line numbering stuff, probably unused. + + Count lines from the beginning of the buffer to reestablish the + absolute (non-wrapped) top line number. If mode is not continuous wrap, + or the number is not being maintained, does nothing. + */ +void Fl_Text_Display::reset_absolute_top_line_number() { + mAbsTopLineNum = 1; + absolute_top_line_number(0); +} + + + +/** + \brief Conver a position index into a line number offset. + + Find the line number of position "pos" relative to the first line of + displayed text. Returns 0 if the line is not displayed. + + \param pos ?? + \param[out] lineNum ?? + \return ?? + \todo What does this do? + */ +int Fl_Text_Display::position_to_line( int pos, int *lineNum ) const { + IS_UTF8_ALIGNED2(buffer(), pos) + + int i; + + *lineNum = 0; + if ( pos < mFirstChar ) return 0; + if ( pos > mLastChar ) { + if ( empty_vlines() ) { + if ( mLastChar < mBuffer->length() ) { + if ( !position_to_line( mLastChar, lineNum ) ) { + Fl::error("Fl_Text_Display::position_to_line(): Consistency check ptvl failed"); + return 0; + } + return ++( *lineNum ) <= mNVisibleLines - 1; + } else { + position_to_line( buffer()->prev_char_clipped(mLastChar), lineNum ); + return 1; + } + } + return 0; + } + + for ( i = mNVisibleLines - 1; i >= 0; i-- ) { + if ( mLineStarts[ i ] != -1 && pos >= mLineStarts[ i ] ) { + *lineNum = i; + return 1; + } + } + return 0; /* probably never be reached */ +} + + +/** + Universal pixel machine. + + We use a single function that handles all line layout, measuring, and drawing + * draw a text range + * return the width of a text range in pixels + * return the index of a char that is at a pixel position + + \param[in] mode DRAW_LINE, GET_WIDTH, FIND_INDEX + \param[in] lineStartPos index of first character + \param[in] lineLen size of string in bytes + \param[in] leftChar, rightChar + \param[in] Y drawing position + \param[in] bottomClip, leftClip, rightClip stop work when we reach the clipped + area. rightClip is the X position that we serach in FIND_INDEX. + \retval DRAW_LINE index of last drawn character + \retval GET_WIDTH width in pixels of text segment if we would draw it + \retval FIND_INDEX index of character at given x position in window coordinates + \retval FIND_INDEX_FROM_ZERO index of character at given x position without scrolling and widget offsets + \todo we need to handle hidden hyphens and tabs here! + \todo we handle all styles and selections + \todo we must provide code to get pixel positions of the middle of a character as well + */ +int Fl_Text_Display::handle_vline( + int mode, + int lineStartPos, int lineLen, int leftChar, int rightChar, + int Y, int bottomClip, + int leftClip, int rightClip) const +{ + IS_UTF8_ALIGNED2(buffer(), lineStartPos) + + // FIXME: we need to allow two modes for FIND_INDEX: one on the edge of the + // FIXME: character for selection, and one on the character center for cursors. + int i, X, startX, startIndex, style, charStyle; + char *lineStr; + + if ( lineStartPos == -1 ) { + lineStr = NULL; + } else { + lineStr = mBuffer->text_range( lineStartPos, lineStartPos + lineLen ); + } + + if (mode==GET_WIDTH) { + X = 0; + } else if (mode==FIND_INDEX_FROM_ZERO) { + X = 0; + mode = FIND_INDEX; + } else { + X = text_area.x - mHorizOffset; + } + + startX = X; + startIndex = 0; + if (!lineStr) { + // just clear the background + if (mode==DRAW_LINE) { + style = position_style(lineStartPos, lineLen, -1); + draw_string( style|BG_ONLY_MASK, text_area.x, Y, text_area.x+text_area.w, lineStr, lineLen ); + } + if (mode==FIND_INDEX) { + IS_UTF8_ALIGNED2(buffer(), lineStartPos) + return lineStartPos; + } + return 0; + } + + char currChar = 0, prevChar = 0; + // draw the line + style = position_style(lineStartPos, lineLen, 0); + for (i=0; irightClip) { + // find x pos inside block + free(lineStr); + return lineStartPos + startIndex; + } + } else { + // draw a text segment + w = int( string_width( lineStr+startIndex, i-startIndex, style ) ); + if (mode==DRAW_LINE) + draw_string( style, startX, Y, startX+w, lineStr+startIndex, i-startIndex ); + if (mode==FIND_INDEX && startX+w>rightClip) { + // find x pos inside block + int di = find_x(lineStr+startIndex, i-startIndex, style, rightClip-startX); + free(lineStr); + IS_UTF8_ALIGNED2(buffer(), (lineStartPos+startIndex+di)) + return lineStartPos + startIndex + di; + } + } + style = charStyle; + startX += w; + startIndex = i; + } + i += len; + prevChar = currChar; + } + int w = 0; + if (currChar=='\t') { + // draw a single Tab space + int tab = col_to_x(4); + int xAbs = (mode==GET_WIDTH) ? startX : startX+mHorizOffset-text_area.x; + w = (((xAbs/tab)+1)*tab) - xAbs; + if (mode==DRAW_LINE) + draw_string( style|BG_ONLY_MASK, startX, Y, startX+w, 0, 0 ); + if (mode==FIND_INDEX) { + // find x pos inside block + free(lineStr); + return lineStartPos + startIndex + ( rightClip-startX>w ? 1 : 0 ); + } + } else { + w = int( string_width( lineStr+startIndex, i-startIndex, style ) ); + if (mode==DRAW_LINE) + draw_string( style, startX, Y, startX+w, lineStr+startIndex, i-startIndex ); + if (mode==FIND_INDEX) { + // find x pos inside block + int di = find_x(lineStr+startIndex, i-startIndex, style, rightClip-startX); + free(lineStr); + IS_UTF8_ALIGNED2(buffer(), (lineStartPos+startIndex+di)) + return lineStartPos + startIndex + di; + } + } + if (mode==GET_WIDTH) { + free(lineStr); + return startX+w; + } + + // clear the rest of the line + startX += w; + style = position_style(lineStartPos, lineLen, i); + if (mode==DRAW_LINE) + draw_string( style|BG_ONLY_MASK, startX, Y, text_area.x+text_area.w, lineStr, lineLen ); + + free(lineStr); + IS_UTF8_ALIGNED2(buffer(), (lineStartPos+lineLen)) + return lineStartPos + lineLen; +} + + +/** + \brief Finde the index of the charcter that lies at the given x position. + \param s UTF-8 text string + \param len length of string + \param style index into style lookup table + \param x position in pixels + \return index into buffer + */ +int Fl_Text_Display::find_x(const char *s, int len, int style, int x) const { + IS_UTF8_ALIGNED(s) + + // TODO: use binary search which may be quicker. + int i = 0; + while (ix) + return i; + i += cl; + } + return len; +} + + + +/** + \brief Draw a single line of text. + + Draw the text on a single line represented by "visLineNum" (the + number of lines down from the top of the display), limited by + "leftClip" and "rightClip" window coordinates and "leftCharIndex" and + "rightCharIndex" character positions (not including the character at + position "rightCharIndex"). + + \param visLineNum index of line in the visible line number lookup + \param leftClip, rightClip pixel position of clipped area + \param leftCharIndex, rightCharIndex index into line of segment that we want to draw + */ +void Fl_Text_Display::draw_vline(int visLineNum, int leftClip, int rightClip, + int leftCharIndex, int rightCharIndex) { + int Y, lineStartPos, lineLen, fontHeight; + + // printf("draw_vline(visLineNum=%d, leftClip=%d, rightClip=%d, leftCharIndex=%d, rightCharIndex=%d)\n", + // visLineNum, leftClip, rightClip, leftCharIndex, rightCharIndex); + // printf("nNVisibleLines=%d\n", mNVisibleLines); + + /* If line is not displayed, skip it */ + if ( visLineNum < 0 || visLineNum >= mNVisibleLines ) + return; + + /* Calculate Y coordinate of the string to draw */ + fontHeight = mMaxsize; + Y = text_area.y + visLineNum * fontHeight; + + /* Get the text, length, and buffer position of the line to display */ + lineStartPos = mLineStarts[ visLineNum ]; + if ( lineStartPos == -1 ) { + lineLen = 0; + } else { + lineLen = vline_length( visLineNum ); + } + + /* Shrink the clipping range to the active display area */ + leftClip = max( text_area.x, leftClip ); + rightClip = min( rightClip, text_area.x + text_area.w ); + + handle_vline(DRAW_LINE, + lineStartPos, lineLen, leftCharIndex, rightCharIndex, + Y, Y+fontHeight, leftClip, rightClip); + return; +} + + + +/** + \brief Draw a text segment in a single style. + + Draw a string or blank area according to parameter "style", using the + appropriate colors and drawing method for that style, with top left + corner at X, Y. If style says to draw text, use "string" as source of + characters, and draw "nChars", if style is FILL, erase + rectangle where text would have drawn from X to toX and from Y to + the maximum Y extent of the current font(s). + + \param style index into style lookup table + \param X, Y drawing origin + \param toX rightmost position if this is a fill operation + \param string text if this is a drawing operation + \param nChars number of characters to draw + */ +void Fl_Text_Display::draw_string(int style, + int X, int Y, int toX, + const char *string, int nChars) const { + IS_UTF8_ALIGNED(string) + + const Style_Table_Entry * styleRec; + + /* Draw blank area rather than text, if that was the request */ + if ( style & FILL_MASK ) { + if (style & TEXT_ONLY_MASK) return; + clear_rect( style, X, Y, toX - X, mMaxsize ); + return; + } + /* Set font, color, and gc depending on style. For normal text, GCs + for normal drawing, or drawing within a Fl_Text_Selection or highlight are + pre-allocated and pre-configured. For syntax highlighting, GCs are + configured here, on the fly. */ + + Fl_Font font = textfont(); + int fsize = textsize(); + Fl_Color foreground; + Fl_Color background; + + if ( style & STYLE_LOOKUP_MASK ) { + int si = (style & STYLE_LOOKUP_MASK) - 'A'; + if (si < 0) si = 0; + else if (si >= mNStyles) si = mNStyles - 1; + + styleRec = mStyleTable + si; + font = styleRec->font; + fsize = styleRec->size; + + if (style & PRIMARY_MASK) { + if (Fl::focus() == this) background = selection_color(); + else background = fl_color_average(color(), selection_color(), 0.4f); + } else if (style & HIGHLIGHT_MASK) { + if (Fl::focus() == this) background = fl_color_average(color(), selection_color(), 0.5f); + else background = fl_color_average(color(), selection_color(), 0.6f); + } else background = color(); + foreground = fl_contrast(styleRec->color, background); + } else if (style & PRIMARY_MASK) { + if (Fl::focus() == this) background = selection_color(); + else background = fl_color_average(color(), selection_color(), 0.4f); + foreground = fl_contrast(textcolor(), background); + } else if (style & HIGHLIGHT_MASK) { + if (Fl::focus() == this) background = fl_color_average(color(), selection_color(), 0.5f); + else background = fl_color_average(color(), selection_color(), 0.6f); + foreground = fl_contrast(textcolor(), background); + } else { + foreground = textcolor(); + background = color(); + } + + if (!(style & TEXT_ONLY_MASK)) { + fl_color( background ); + fl_rectf( X, Y, toX - X, mMaxsize ); + } + if (!(style & BG_ONLY_MASK)) { + fl_color( foreground ); + fl_font( font, fsize ); + fl_draw( string, nChars, X, Y + mMaxsize - fl_descent()); + } + + // CET - FIXME + /* If any space around the character remains unfilled (due to use of + different sized fonts for highlighting), fill in above or below + to erase previously drawn characters */ + /* + if (fs->ascent < mAscent) + clear_rect( style, X, Y, toX - X, mAscent - fs->ascent); + if (fs->descent < mDescent) + clear_rect( style, X, Y + mAscent + fs->descent, toX - x, + mDescent - fs->descent); + */ + /* Underline if style is secondary Fl_Text_Selection */ + + /* + if (style & SECONDARY_MASK) + XDrawLine(XtDisplay(mW), XtWindow(mW), gc, x, + y + mAscent, toX - 1, Y + fs->ascent); + */ +} + + + +/** + \brief Clear a rectangle with the appropriate background color for "style". + + \param style index into style table + \param X, Y, width, height size and position of background area + */ +void Fl_Text_Display::clear_rect(int style, + int X, int Y, + int width, int height) const { + /* A width of zero means "clear to end of window" to XClearArea */ + if ( width == 0 ) + return; + + if (style & PRIMARY_MASK) { + if (Fl::focus()==this) { + fl_color(selection_color()); + } else { + fl_color(fl_color_average(color(), selection_color(), 0.4f)); + } + } else if (style & HIGHLIGHT_MASK) { + if (Fl::focus()==this) { + fl_color(fl_color_average(color(), selection_color(), 0.5f)); + } else { + fl_color(fl_color_average(color(), selection_color(), 0.6f)); + } + } else { + fl_color( color() ); + } + fl_rectf( X, Y, width, height ); +} + + + +/** + \brief Draw a cursor with top center at X, y. + + \param X, Y cursor position in pixels + */ +void Fl_Text_Display::draw_cursor( int X, int Y ) { + typedef struct { + int x1, y1, x2, y2; + } + Segment; + + Segment segs[ 5 ]; + int left, right, cursorWidth, midY; + // int fontWidth = mFontStruct->min_bounds.width, nSegs = 0; + int fontWidth = TMPFONTWIDTH; // CET - FIXME + int nSegs = 0; + int fontHeight = mMaxsize; + int bot = Y + fontHeight - 1; + + if ( X < text_area.x - 1 || X > text_area.x + text_area.w ) + return; + + /* For cursors other than the block, make them around 2/3 of a character + width, rounded to an even number of pixels so that X will draw an + odd number centered on the stem at x. */ + cursorWidth = 4; //(fontWidth/3) * 2; + left = X - cursorWidth / 2; + right = left + cursorWidth; + + /* Create segments and draw cursor */ + if ( mCursorStyle == CARET_CURSOR ) { + midY = bot - fontHeight / 5; + segs[ 0 ].x1 = left; segs[ 0 ].y1 = bot; segs[ 0 ].x2 = X; segs[ 0 ].y2 = midY; + segs[ 1 ].x1 = X; segs[ 1 ].y1 = midY; segs[ 1 ].x2 = right; segs[ 1 ].y2 = bot; + segs[ 2 ].x1 = left; segs[ 2 ].y1 = bot; segs[ 2 ].x2 = X; segs[ 2 ].y2 = midY - 1; + segs[ 3 ].x1 = X; segs[ 3 ].y1 = midY - 1; segs[ 3 ].x2 = right; segs[ 3 ].y2 = bot; + nSegs = 4; + } else if ( mCursorStyle == NORMAL_CURSOR ) { + segs[ 0 ].x1 = left; segs[ 0 ].y1 = Y; segs[ 0 ].x2 = right; segs[ 0 ].y2 = Y; + segs[ 1 ].x1 = X; segs[ 1 ].y1 = Y; segs[ 1 ].x2 = X; segs[ 1 ].y2 = bot; + segs[ 2 ].x1 = left; segs[ 2 ].y1 = bot; segs[ 2 ].x2 = right; segs[ 2 ].y2 = bot; + nSegs = 3; + } else if ( mCursorStyle == HEAVY_CURSOR ) { + segs[ 0 ].x1 = X - 1; segs[ 0 ].y1 = Y; segs[ 0 ].x2 = X - 1; segs[ 0 ].y2 = bot; + segs[ 1 ].x1 = X; segs[ 1 ].y1 = Y; segs[ 1 ].x2 = X; segs[ 1 ].y2 = bot; + segs[ 2 ].x1 = X + 1; segs[ 2 ].y1 = Y; segs[ 2 ].x2 = X + 1; segs[ 2 ].y2 = bot; + segs[ 3 ].x1 = left; segs[ 3 ].y1 = Y; segs[ 3 ].x2 = right; segs[ 3 ].y2 = Y; + segs[ 4 ].x1 = left; segs[ 4 ].y1 = bot; segs[ 4 ].x2 = right; segs[ 4 ].y2 = bot; + nSegs = 5; + } else if ( mCursorStyle == DIM_CURSOR ) { + midY = Y + fontHeight / 2; + segs[ 0 ].x1 = X; segs[ 0 ].y1 = Y; segs[ 0 ].x2 = X; segs[ 0 ].y2 = Y; + segs[ 1 ].x1 = X; segs[ 1 ].y1 = midY; segs[ 1 ].x2 = X; segs[ 1 ].y2 = midY; + segs[ 2 ].x1 = X; segs[ 2 ].y1 = bot; segs[ 2 ].x2 = X; segs[ 2 ].y2 = bot; + nSegs = 3; + } else if ( mCursorStyle == BLOCK_CURSOR ) { + right = X + fontWidth; + segs[ 0 ].x1 = X; segs[ 0 ].y1 = Y; segs[ 0 ].x2 = right; segs[ 0 ].y2 = Y; + segs[ 1 ].x1 = right; segs[ 1 ].y1 = Y; segs[ 1 ].x2 = right; segs[ 1 ].y2 = bot; + segs[ 2 ].x1 = right; segs[ 2 ].y1 = bot; segs[ 2 ].x2 = X; segs[ 2 ].y2 = bot; + segs[ 3 ].x1 = X; segs[ 3 ].y1 = bot; segs[ 3 ].x2 = X; segs[ 3 ].y2 = Y; + nSegs = 4; + } + fl_color( mCursor_color ); + + for ( int k = 0; k < nSegs; k++ ) { + fl_line( segs[ k ].x1, segs[ k ].y1, segs[ k ].x2, segs[ k ].y2 ); + } +} + + + +/** + \brief Find the correct style for a character., + + Determine the drawing method to use to draw a specific character from "buf". + "lineStartPos" gives the character index where the line begins, "lineIndex", + the number of characters past the beginning of the line, and "dispIndex", + the number of displayed characters past the beginning of the line. Passing + lineStartPos of -1 returns the drawing style for "no text". + + Why not just: position_style(pos)? Because style applies to blank areas + of the window beyond the text boundaries, and because this routine must also + decide whether a position is inside of a rectangular Fl_Text_Selection, and do + so efficiently, without re-counting character positions from the start of the + line. + + Note that style is a somewhat incorrect name, drawing method would + be more appropriate. + + \param lineStartPos beginning of this line + \param lineLen number of bytes in line + \param lineIndex position of character within line + \return style for the given character + */ +int Fl_Text_Display::position_style( int lineStartPos, int lineLen, int lineIndex) const +{ + IS_UTF8_ALIGNED2(buffer(), lineStartPos) + + Fl_Text_Buffer * buf = mBuffer; + Fl_Text_Buffer *styleBuf = mStyleBuffer; + int pos, style = 0; + + if ( lineStartPos == -1 || buf == NULL ) + return FILL_MASK; + + pos = lineStartPos + min( lineIndex, lineLen ); + + if ( lineIndex >= lineLen ) + style = FILL_MASK; + else if ( styleBuf != NULL ) { + style = ( unsigned char ) styleBuf->byte_at( pos ); + if (style == mUnfinishedStyle && mUnfinishedHighlightCB) { + /* encountered "unfinished" style, trigger parsing */ + (mUnfinishedHighlightCB)( pos, mHighlightCBArg); + style = (unsigned char) styleBuf->byte_at( pos); + } + } + if (buf->primary_selection()->includes(pos)) + style |= PRIMARY_MASK; + if (buf->highlight_selection()->includes(pos)) + style |= HIGHLIGHT_MASK; + if (buf->secondary_selection()->includes(pos)) + style |= SECONDARY_MASK; + return style; +} + + + +/** + \brief Find the width of a string in the font of a particular style. + + \param string the text + \param length number of bytes instring + \param style index into style table + \return width of text segemnt in pixels + */ +double Fl_Text_Display::string_width( const char *string, int length, int style ) const { + IS_UTF8_ALIGNED(string) + + Fl_Font font; + Fl_Fontsize fsize; + + if ( mNStyles && (style & STYLE_LOOKUP_MASK) ) { + int si = (style & STYLE_LOOKUP_MASK) - 'A'; + if (si < 0) si = 0; + else if (si >= mNStyles) si = mNStyles - 1; + + font = mStyleTable[si].font; + fsize = mStyleTable[si].size; + } else { + font = textfont(); + fsize = textsize(); + } + fl_font( font, fsize ); + return fl_width( string, length ); +} + + + +/** + \brief Translate a pixel position into a charcter index. + + Translate window coordinates to the nearest (insert cursor or character + cell) text position. The parameter posType specifies how to interpret the + position: CURSOR_POS means translate the coordinates to the nearest cursor + position, and CHARACTER_POS means return the position of the character + closest to (X, Y). + + \param X, Y pixel position + \param posType CURSOR_POS or CHARACTER_POS + \return index into text buffer + */ +int Fl_Text_Display::xy_to_position( int X, int Y, int posType ) const { + int lineStart, lineLen, fontHeight; + int visLineNum; + + /* Find the visible line number corresponding to the Y coordinate */ + fontHeight = mMaxsize; + visLineNum = ( Y - text_area.y ) / fontHeight; + if ( visLineNum < 0 ) + return mFirstChar; + if ( visLineNum >= mNVisibleLines ) + visLineNum = mNVisibleLines - 1; + + /* Find the position at the start of the line */ + lineStart = mLineStarts[ visLineNum ]; + + /* If the line start was empty, return the last position in the buffer */ + if ( lineStart == -1 ) + return mBuffer->length(); + + /* Get the line text and its length */ + lineLen = vline_length( visLineNum ); + + return handle_vline(FIND_INDEX, + lineStart, lineLen, 0, 0, + 0, 0, + text_area.x, X); +} + + + +/** + \brief Translate pixel coordinates into row and column. + + Translate window coordinates to the nearest row and column number for + positioning the cursor. This, of course, makes no sense when the font is + proportional, since there are no absolute columns. The parameter posType + specifies how to interpret the position: CURSOR_POS means translate the + coordinates to the nearest position between characters, and CHARACTER_POS + means translate the position to the nearest character cell. + + \param X, Y pixel coordinates + \param[out] row, column neares row and column + \param posType CURSOR_POS or CHARACTER_POS + */ +void Fl_Text_Display::xy_to_rowcol( int X, int Y, int *row, + int *column, int posType ) const { + int fontHeight = mMaxsize; + int fontWidth = TMPFONTWIDTH; //mFontStruct->max_bounds.width; + + /* Find the visible line number corresponding to the Y coordinate */ + *row = ( Y - text_area.y ) / fontHeight; + if ( *row < 0 ) *row = 0; + if ( *row >= mNVisibleLines ) *row = mNVisibleLines - 1; + + *column = ( ( X - text_area.x ) + mHorizOffset + + ( posType == CURSOR_POS ? fontWidth / 2 : 0 ) ) / fontWidth; + if ( *column < 0 ) * column = 0; +} + + + +/** + \brief Offset line start counters for a new vertical scroll position. + + Offset the line starts array, mTopLineNum, mFirstChar and lastChar, for a new + vertical scroll position given by newTopLineNum. If any currently displayed + lines will still be visible, salvage the line starts values, otherwise, + count lines from the nearest known line start (start or end of buffer, or + the closest value in the mLineStarts array) + + \param newTopLineNum index into buffer + */ +void Fl_Text_Display::offset_line_starts( int newTopLineNum ) { + int oldTopLineNum = mTopLineNum; + int oldFirstChar = mFirstChar; + int lineDelta = newTopLineNum - oldTopLineNum; + int nVisLines = mNVisibleLines; + int *lineStarts = mLineStarts; + int i, lastLineNum; + Fl_Text_Buffer *buf = mBuffer; + + /* If there was no offset, nothing needs to be changed */ + if ( lineDelta == 0 ) + return; + + /* Find the new value for mFirstChar by counting lines from the nearest + known line start (start or end of buffer, or the closest value in the + lineStarts array) */ + lastLineNum = oldTopLineNum + nVisLines - 1; + if ( newTopLineNum < oldTopLineNum && newTopLineNum < -lineDelta ) { + mFirstChar = skip_lines( 0, newTopLineNum - 1, true ); + } else if ( newTopLineNum < oldTopLineNum ) { + mFirstChar = rewind_lines( mFirstChar, -lineDelta ); + } else if ( newTopLineNum < lastLineNum ) { + mFirstChar = lineStarts[ newTopLineNum - oldTopLineNum ]; + } else if ( newTopLineNum - lastLineNum < mNBufferLines - newTopLineNum ) { + mFirstChar = skip_lines( lineStarts[ nVisLines - 1 ], + newTopLineNum - lastLineNum, true ); + } else { + mFirstChar = rewind_lines( buf->length(), mNBufferLines - newTopLineNum + 1 ); + } + + /* Fill in the line starts array */ + if ( lineDelta < 0 && -lineDelta < nVisLines ) { + for ( i = nVisLines - 1; i >= -lineDelta; i-- ) + lineStarts[ i ] = lineStarts[ i + lineDelta ]; + calc_line_starts( 0, -lineDelta ); + } else if ( lineDelta > 0 && lineDelta < nVisLines ) { + for ( i = 0; i < nVisLines - lineDelta; i++ ) + lineStarts[ i ] = lineStarts[ i + lineDelta ]; + calc_line_starts( nVisLines - lineDelta, nVisLines - 1 ); + } else + calc_line_starts( 0, nVisLines ); + + /* Set lastChar and mTopLineNum */ + calc_last_char(); + mTopLineNum = newTopLineNum; + + /* If we're numbering lines or being asked to maintain an absolute line + number, re-calculate the absolute line number */ + absolute_top_line_number(oldFirstChar); +} + + + +/** + \brief Update line start arrays and variables. + + Update the line starts array, mTopLineNum, mFirstChar and lastChar for text + display "textD" after a modification to the text buffer, given by the + position where the change began "pos", and the numbers of characters + and lines inserted and deleted. + + \param pos index into buffer of recent changes + \param charsInserted number of bytes(!) inserted + \param charsDeleted number of bytes(!) deleted + \param linesInserted number of lines + \param linesDeleted number of lines + \param[out] scrolled set to 1 if the text display needs to be scrolled + */ +void Fl_Text_Display::update_line_starts(int pos, int charsInserted, + int charsDeleted, int linesInserted, + int linesDeleted, int *scrolled ) { + IS_UTF8_ALIGNED2(buffer(), pos) + + int *lineStarts = mLineStarts; + int i, lineOfPos, lineOfEnd, nVisLines = mNVisibleLines; + int charDelta = charsInserted - charsDeleted; + int lineDelta = linesInserted - linesDeleted; + + /* If all of the changes were before the displayed text, the display + doesn't change, just update the top line num and offset the line + start entries and first and last characters */ + if ( pos + charsDeleted < mFirstChar ) { + mTopLineNum += lineDelta; + for ( i = 0; i < nVisLines && lineStarts[i] != -1; i++ ) + lineStarts[ i ] += charDelta; + mFirstChar += charDelta; + mLastChar += charDelta; + *scrolled = 0; + return; + } + + /* The change began before the beginning of the displayed text, but + part or all of the displayed text was deleted */ + if ( pos < mFirstChar ) { + /* If some text remains in the window, anchor on that */ + if ( position_to_line( pos + charsDeleted, &lineOfEnd ) && + ++lineOfEnd < nVisLines && lineStarts[ lineOfEnd ] != -1 ) { + mTopLineNum = max( 1, mTopLineNum + lineDelta ); + mFirstChar = rewind_lines(lineStarts[ lineOfEnd ] + charDelta, lineOfEnd ); + /* Otherwise anchor on original line number and recount everything */ + } else { + if ( mTopLineNum > mNBufferLines + lineDelta ) { + mTopLineNum = 1; + mFirstChar = 0; + } else + mFirstChar = skip_lines( 0, mTopLineNum - 1, true ); + } + calc_line_starts( 0, nVisLines - 1 ); + /* calculate lastChar by finding the end of the last displayed line */ + calc_last_char(); + *scrolled = 1; + return; + } + + /* If the change was in the middle of the displayed text (it usually is), + salvage as much of the line starts array as possible by moving and + offsetting the entries after the changed area, and re-counting the + added lines or the lines beyond the salvaged part of the line starts + array */ + if ( pos <= mLastChar ) { + /* find line on which the change began */ + position_to_line( pos, &lineOfPos ); + /* salvage line starts after the changed area */ + if ( lineDelta == 0 ) { + for ( i = lineOfPos + 1; i < nVisLines && lineStarts[ i ] != -1; i++ ) + lineStarts[ i ] += charDelta; + } else if ( lineDelta > 0 ) { + for ( i = nVisLines - 1; i >= lineOfPos + lineDelta + 1; i-- ) + lineStarts[ i ] = lineStarts[ i - lineDelta ] + + ( lineStarts[ i - lineDelta ] == -1 ? 0 : charDelta ); + } else /* (lineDelta < 0) */ { + for ( i = max( 0, lineOfPos + 1 ); i < nVisLines + lineDelta; i++ ) + lineStarts[ i ] = lineStarts[ i - lineDelta ] + + ( lineStarts[ i - lineDelta ] == -1 ? 0 : charDelta ); + } + /* fill in the missing line starts */ + if ( linesInserted >= 0 ) + calc_line_starts( lineOfPos + 1, lineOfPos + linesInserted ); + if ( lineDelta < 0 ) + calc_line_starts( nVisLines + lineDelta, nVisLines ); + /* calculate lastChar by finding the end of the last displayed line */ + calc_last_char(); + *scrolled = 0; + return; + } + + /* Change was past the end of the displayed text, but displayable by virtue + of being an insert at the end of the buffer into visible blank lines */ + if ( empty_vlines() ) { + position_to_line( pos, &lineOfPos ); + calc_line_starts( lineOfPos, lineOfPos + linesInserted ); + calc_last_char(); + *scrolled = 0; + return; + } + + /* Change was beyond the end of the buffer and not visible, do nothing */ + *scrolled = 0; +} + + + +/** + \brief Update the line start arrays. + + Scan through the text in the "textD"'s buffer and recalculate the line + starts array values beginning at index "startLine" and continuing through + (including) "endLine". It assumes that the line starts entry preceding + "startLine" (or mFirstChar if startLine is 0) is good, and re-counts + newlines to fill in the requested entries. Out of range values for + "startLine" and "endLine" are acceptable. + + \param startLine, endLine range of lines to scan as line numbers + */ +void Fl_Text_Display::calc_line_starts( int startLine, int endLine ) { + int startPos, bufLen = mBuffer->length(); + int line, lineEnd, nextLineStart, nVis = mNVisibleLines; + int *lineStarts = mLineStarts; + + /* Clean up (possibly) messy input parameters */ + if ( endLine < 0 ) endLine = 0; + if ( endLine >= nVis ) endLine = nVis - 1; + if ( startLine < 0 ) startLine = 0; + if ( startLine >= nVis ) startLine = nVis - 1; + if ( startLine > endLine ) + return; + + /* Find the last known good line number -> position mapping */ + if ( startLine == 0 ) { + lineStarts[ 0 ] = mFirstChar; + startLine = 1; + } + startPos = lineStarts[ startLine - 1 ]; + + /* If the starting position is already past the end of the text, + fill in -1's (means no text on line) and return */ + if ( startPos == -1 ) { + for ( line = startLine; line <= endLine; line++ ) + lineStarts[ line ] = -1; + return; + } + + /* Loop searching for ends of lines and storing the positions of the + start of the next line in lineStarts */ + for ( line = startLine; line <= endLine; line++ ) { + find_line_end(startPos, true, &lineEnd, &nextLineStart); + startPos = nextLineStart; + if ( startPos >= bufLen ) { + /* If the buffer ends with a newline or line break, put + buf->length() in the next line start position (instead of + a -1 which is the normal marker for an empty line) to + indicate that the cursor may safely be displayed there */ + if ( line == 0 || ( lineStarts[ line - 1 ] != bufLen && + lineEnd != nextLineStart ) ) { + lineStarts[ line ] = bufLen; + line++; + } + break; + } + lineStarts[ line ] = startPos; + } + + /* Set any entries beyond the end of the text to -1 */ + for ( ; line <= endLine; line++ ) + lineStarts[ line ] = -1; +} + + + +/** + \brief Update last display character index. + + Given a Fl_Text_Display with a complete, up-to-date lineStarts array, update + the lastChar entry to point to the last buffer position displayed. + */ +void Fl_Text_Display::calc_last_char() { + int i; + for (i = mNVisibleLines - 1; i >= 0 && mLineStarts[i] == -1; i--) ; + mLastChar = i < 0 ? 0 : line_end(mLineStarts[i], true); +} + + + +/** + \brief Scrolls the current buffer to start at the specified line and column. + \param topLineNum top line number + \param horizOffset column number + \todo Column numbers make little sense here. + */ +void Fl_Text_Display::scroll(int topLineNum, int horizOffset) { + mTopLineNumHint = topLineNum; + mHorizOffsetHint = horizOffset; + resize(x(), y(), w(), h()); +} + + + +/** + \brief Scrolls the current buffer to start at the specified line and column. + \param topLineNum top line number + \param horizOffset in pixels + \return 0 if nothing changed, 1 if we scrolled + */ +int Fl_Text_Display::scroll_(int topLineNum, int horizOffset) { + /* Limit the requested scroll position to allowable values */ + if (topLineNum > mNBufferLines + 3 - mNVisibleLines) + topLineNum = mNBufferLines + 3 - mNVisibleLines; + if (topLineNum < 1) topLineNum = 1; + + if (horizOffset > longest_vline() - text_area.w) + horizOffset = longest_vline() - text_area.w; + if (horizOffset < 0) horizOffset = 0; + + /* Do nothing if scroll position hasn't actually changed or there's no + window to draw in yet */ + if (mHorizOffset == horizOffset && mTopLineNum == topLineNum) + return 0; + + /* If the vertical scroll position has changed, update the line + starts array and related counters in the text display */ + offset_line_starts(topLineNum); + + /* Just setting mHorizOffset is enough information for redisplay */ + mHorizOffset = horizOffset; + + // redraw all text + damage(FL_DAMAGE_EXPOSE); + return 1; +} + + + +/** + \brief Update vertical scroll bar. + + Update the minimum, maximum, slider size, page increment, and value + for vertical scroll bar. + */ +void Fl_Text_Display::update_v_scrollbar() { + /* The Vert. scroll bar value and slider size directly represent the top + line number, and the number of visible lines respectively. The scroll + bar maximum value is chosen to generally represent the size of the whole + buffer, with minor adjustments to keep the scroll bar widget happy */ +#ifdef DEBUG + printf("Fl_Text_Display::update_v_scrollbar():\n" + " mTopLineNum=%d, mNVisibleLines=%d, mNBufferLines=%d\n", + mTopLineNum, mNVisibleLines, mNBufferLines); +#endif // DEBUG + + mVScrollBar->value(mTopLineNum, mNVisibleLines, 1, mNBufferLines+2); + mVScrollBar->linesize(3); +} + + + +/** + \brief Update vertical scroll bar. + + Update the minimum, maximum, slider size, page increment, and value + for the horizontal scroll bar. + */ +void Fl_Text_Display::update_h_scrollbar() { + int sliderMax = max(longest_vline(), text_area.w + mHorizOffset); + mHScrollBar->value( mHorizOffset, text_area.w, 0, sliderMax ); +} + + + +/** + \brief Callbacks for drag or valueChanged on scroll bars. + */ +void Fl_Text_Display::v_scrollbar_cb(Fl_Scrollbar* b, Fl_Text_Display* textD) { + if (b->value() == textD->mTopLineNum) return; + textD->scroll(b->value(), textD->mHorizOffset); +} + + + +/** + \brief Callbacks for drag or valueChanged on scroll bars. + */ +void Fl_Text_Display::h_scrollbar_cb(Fl_Scrollbar* b, Fl_Text_Display* textD) { + if (b->value() == textD->mHorizOffset) return; + textD->scroll(textD->mTopLineNum, b->value()); +} + + + +/** + \brief Refresh the line number area. + + If clearAll is False, writes only over the character cell areas. Setting + clearAll to True will clear out any stray marks outside of the character cell + area, which might have been left from before a resize or font change. + + This function is not used. + */ +void Fl_Text_Display::draw_line_numbers(bool /*clearAll*/) { +#if 0 + int y, line, visLine, nCols, lineStart; + char lineNumString[12]; + int lineHeight = mMaxsize ? mMaxsize : textsize_; + int charWidth = TMPFONTWIDTH; //mFontStruct->max_bounds.width; + + /* Don't draw if mLineNumWidth == 0 (line numbers are hidden), or widget is + not yet realized */ + if (mLineNumWidth == 0 || visible_r()) + return; + + /* GC is allocated on demand, since not everyone will use line numbering */ + if (textD->lineNumGC == NULL) { + XGCValues values; + values.foreground = textD->lineNumFGPixel; + values.background = textD->bgPixel; + values.font = textD->fontStruct->fid; + textD->lineNumGC = XtGetGC(textD->w, + GCFont| GCForeground | GCBackground, &values); + } + + /* Erase the previous contents of the line number area, if requested */ + if (clearAll) + XClearArea(XtDisplay(textD->w), XtWindow(textD->w), textD->lineNumLeft, + textD->top, textD->lineNumWidth, textD->height, False); + + /* Draw the line numbers, aligned to the text */ + nCols = min(11, textD->lineNumWidth / charWidth); + y = textD->top; + line = getAbsTopLineNum(textD); + for (visLine=0; visLine < textD->nVisibleLines; visLine++) { + lineStart = textD->lineStarts[visLine]; + if (lineStart != -1 && (lineStart==0 || + BufGetCharacter(textD->buffer, lineStart-1)=='\n')) { + sprintf(lineNumString, "%*d", nCols, line); + XDrawImageString(XtDisplay(textD->w), XtWindow(textD->w), + textD->lineNumGC, textD->lineNumLeft, y + textD->ascent, + lineNumString, strlen(lineNumString)); + line++; + } else { + XClearArea(XtDisplay(textD->w), XtWindow(textD->w), + textD->lineNumLeft, y, textD->lineNumWidth, + textD->ascent + textD->descent, False); + if (visLine == 0) + line++; + } + y += lineHeight; + } +#endif +} + +static int max( int i1, int i2 ) { + return i1 >= i2 ? i1 : i2; +} + +static int min( int i1, int i2 ) { + return i1 <= i2 ? i1 : i2; +} + + + +/** + Count the number of newlines in a null-terminated text string; + */ +static int countlines( const char *string ) { + IS_UTF8_ALIGNED(string) + + const char * c; + int lineCount = 0; + + if (!string) return 0; + + for ( c = string; *c != '\0'; c++ ) + if ( *c == '\n' ) lineCount++; + return lineCount; +} + + + + +/** + \brief Return the width in pixels of the displayed line pointed to by "visLineNum". + \param index into visible lines array + \return width of line in pixels + */ +int Fl_Text_Display::measure_vline( int visLineNum ) const { + int lineLen = vline_length( visLineNum ); + int lineStartPos = mLineStarts[ visLineNum ]; + if (lineStartPos < 0 || lineLen == 0) return 0; + return handle_vline(GET_WIDTH, lineStartPos, lineLen, 0, 0, 0, 0, 0, 0); +} + + + +/** + \brief Return true if there are lines visible with no corresponding buffer text. + \return 1 if there are empty lines + */ +int Fl_Text_Display::empty_vlines() const { + return (mNVisibleLines > 0) && (mLineStarts[ mNVisibleLines - 1 ] == -1); +} + + + +/** + \brief Count number of bytes in a visible line. + + Return the length of a line (number of bytes) by examining + entries in the line starts array rather than by scanning for newlines. + + \param visLineNum index of line in visible line array + \return number of bytes in this line + */ +int Fl_Text_Display::vline_length( int visLineNum ) const { + int nextLineStart, lineStartPos; + + if (visLineNum < 0 || visLineNum >= mNVisibleLines) + return (0); + + lineStartPos = mLineStarts[ visLineNum ]; + + if ( lineStartPos == -1 ) + return 0; + + if ( visLineNum + 1 >= mNVisibleLines ) + return mLastChar - lineStartPos; + + nextLineStart = mLineStarts[ visLineNum + 1 ]; + if ( nextLineStart == -1 ) + return mLastChar - lineStartPos; + + int nextLineStartMinus1 = buffer()->prev_char(nextLineStart); + if (wrap_uses_character(nextLineStartMinus1)) + return nextLineStartMinus1 - lineStartPos; + + return nextLineStart - lineStartPos; +} + + + +/** + \brief Wrapping calculations. + + When continuous wrap is on, and the user inserts or deletes characters, + wrapping can happen before and beyond the changed position. This routine + finds the extent of the changes, and counts the deleted and inserted lines + over that range. It also attempts to minimize the size of the range to + what has to be counted and re-displayed, so the results can be useful + both for delimiting where the line starts need to be recalculated, and + for deciding what part of the text to redisplay. + + \param deletedText + \param pos + \param nInserted + \param nDeleted + \param modRangeStart + \param modRangeEnd + \param linesInserted + \param linesDeleted + */ +void Fl_Text_Display::find_wrap_range(const char *deletedText, int pos, + int nInserted, int nDeleted, + int *modRangeStart, int *modRangeEnd, + int *linesInserted, int *linesDeleted) { + IS_UTF8_ALIGNED(deletedText) + IS_UTF8_ALIGNED2(buffer(), pos) + + int length, retPos, retLines, retLineStart, retLineEnd; + Fl_Text_Buffer *deletedTextBuf, *buf = buffer(); + int nVisLines = mNVisibleLines; + int *lineStarts = mLineStarts; + int countFrom, countTo, lineStart, adjLineStart, i; + int visLineNum = 0, nLines = 0; + + /* + ** Determine where to begin searching: either the previous newline, or + ** if possible, limit to the start of the (original) previous displayed + ** line, using information from the existing line starts array + */ + if (pos >= mFirstChar && pos <= mLastChar) { + for (i=nVisLines-1; i>0; i--) { + if (lineStarts[i] != -1 && pos >= lineStarts[i]) { + break; + } + } + if (i > 0) { + countFrom = lineStarts[i-1]; + visLineNum = i-1; + } else { + countFrom = buf->line_start(pos); + } + } else { + countFrom = buf->line_start(pos); + } + + IS_UTF8_ALIGNED2(buf, countFrom) + + /* + ** Move forward through the (new) text one line at a time, counting + ** displayed lines, and looking for either a real newline, or for the + ** line starts to re-sync with the original line starts array + */ + lineStart = countFrom; + *modRangeStart = countFrom; + for (;;) { + + /* advance to the next line. If the line ended in a real newline + or the end of the buffer, that's far enough */ + wrapped_line_counter(buf, lineStart, buf->length(), 1, true, 0, + &retPos, &retLines, &retLineStart, &retLineEnd); + if (retPos >= buf->length()) { + countTo = buf->length(); + *modRangeEnd = countTo; + if (retPos != retLineEnd) + nLines++; + break; + } else { + lineStart = retPos; + } + nLines++; + if (lineStart > pos + nInserted && buf->char_at(buf->prev_char(lineStart)) == '\n') { + countTo = lineStart; + *modRangeEnd = lineStart; + break; + } + + /* Don't try to resync in continuous wrap mode with non-fixed font + sizes; it would result in a chicken-and-egg dependency between + the calculations for the inserted and the deleted lines. + If we're in that mode, the number of deleted lines is calculated in + advance, without resynchronization, so we shouldn't resynchronize + for the inserted lines either. */ + if (mSuppressResync) + continue; + + /* check for synchronization with the original line starts array + before pos, if so, the modified range can begin later */ + if (lineStart <= pos) { + while (visLineNumprev_char(lineStarts[visLineNum+1])); + else + *modRangeStart = countFrom; + } else + *modRangeStart = min(*modRangeStart, buf->prev_char(lineStart)); + } + + /* check for synchronization with the original line starts array + after pos, if so, the modified range can end early */ + else if (lineStart > pos + nInserted) { + adjLineStart = lineStart - nInserted + nDeleted; + while (visLineNumcopy(buffer(), countFrom, pos, 0); + if (nDeleted != 0) + deletedTextBuf->insert(pos-countFrom, deletedText); + deletedTextBuf->copy(buffer(), pos+nInserted, countTo, pos-countFrom+nDeleted); + /* Note that we need to take into account an offset for the style buffer: + the deletedTextBuf can be out of sync with the style buffer. */ + wrapped_line_counter(deletedTextBuf, 0, length, INT_MAX, true, countFrom, + &retPos, &retLines, &retLineStart, &retLineEnd, false); + delete deletedTextBuf; + *linesDeleted = retLines; + mSuppressResync = 0; +} + + + +/** + \brief Wrapping calculations. + + This is a stripped-down version of the findWrapRange() function above, + intended to be used to calculate the number of "deleted" lines during + a buffer modification. It is called _before_ the modification takes place. + + This function should only be called in continuous wrap mode with a + non-fixed font width. In that case, it is impossible to calculate + the number of deleted lines, because the necessary style information + is no longer available _after_ the modification. In other cases, we + can still perform the calculation afterwards (possibly even more + efficiently). + + \param pos + \param nDeleted + */ +void Fl_Text_Display::measure_deleted_lines(int pos, int nDeleted) { + IS_UTF8_ALIGNED2(buffer(), pos) + + int retPos, retLines, retLineStart, retLineEnd; + Fl_Text_Buffer *buf = buffer(); + int nVisLines = mNVisibleLines; + int *lineStarts = mLineStarts; + int countFrom, lineStart; + int visLineNum = 0, nLines = 0, i; + /* + ** Determine where to begin searching: either the previous newline, or + ** if possible, limit to the start of the (original) previous displayed + ** line, using information from the existing line starts array + */ + if (pos >= mFirstChar && pos <= mLastChar) { + for (i=nVisLines-1; i>0; i--) + if (lineStarts[i] != -1 && pos >= lineStarts[i]) + break; + if (i > 0) { + countFrom = lineStarts[i-1]; + visLineNum = i-1; + } else + countFrom = buf->line_start(pos); + } else + countFrom = buf->line_start(pos); + + /* + ** Move forward through the (new) text one line at a time, counting + ** displayed lines, and looking for either a real newline, or for the + ** line starts to re-sync with the original line starts array + */ + lineStart = countFrom; + for (;;) { + /* advance to the next line. If the line ended in a real newline + or the end of the buffer, that's far enough */ + wrapped_line_counter(buf, lineStart, buf->length(), 1, true, 0, + &retPos, &retLines, &retLineStart, &retLineEnd); + if (retPos >= buf->length()) { + if (retPos != retLineEnd) + nLines++; + break; + } else + lineStart = retPos; + nLines++; + if (lineStart > pos + nDeleted && buf->char_at(lineStart-1) == '\n') { + break; + } + + /* Unlike in the findWrapRange() function above, we don't try to + resync with the line starts, because we don't know the length + of the inserted text yet, nor the updated style information. + + Because of that, we also shouldn't resync with the line starts + after the modification either, because we must perform the + calculations for the deleted and inserted lines in the same way. + + This can result in some unnecessary recalculation and redrawing + overhead, and therefore we should only use this two-phase mode + of calculation when it's really needed (continuous wrap + variable + font width). */ + } + mNLinesDeleted = nLines; + mSuppressResync = 1; +} + + + +/** + \brief Wrapping calculations. + + Count forward from startPos to either maxPos or maxLines (whichever is + reached first), and return all relevant positions and line count. + The provided textBuffer may differ from the actual text buffer of the + widget. In that case it must be a (partial) copy of the actual text buffer + and the styleBufOffset argument must indicate the starting position of the + copy, to take into account the correct style information. + + \param buf + \param startPos + \param maxPos + \param maxLines + \param startPosIsLineStart + \param styleBufOffset + + \param[out] retPos Position where counting ended. When counting lines, the + position returned is the start of the line "maxLines" lines + beyond "startPos". + \param[out] retLines Number of line breaks counted + \param[out] retLineStart Start of the line where counting ended + \param[out] retLineEnd End position of the last line traversed + \param[out] countLastLineMissingNewLine + */ +void Fl_Text_Display::wrapped_line_counter(Fl_Text_Buffer *buf, int startPos, + int maxPos, int maxLines, bool startPosIsLineStart, int styleBufOffset, + int *retPos, int *retLines, int *retLineStart, int *retLineEnd, + bool countLastLineMissingNewLine) const { + IS_UTF8_ALIGNED2(buf, startPos) + IS_UTF8_ALIGNED2(buf, maxPos) + + int lineStart, newLineStart = 0, b, p, colNum, wrapMarginPix; + int i, foundBreak; + double width; + int nLines = 0; + unsigned int c; + + /* Set the warp margin to the warp column or the view width */ + if (mWrapMarginPix != 0) { + wrapMarginPix = mWrapMarginPix; + } else { + wrapMarginPix = text_area.w; + } + + /* Find the start of the line if the start pos is not marked as a + line start. */ + if (startPosIsLineStart) + lineStart = startPos; + else + lineStart = line_start(startPos); + + /* + ** Loop until position exceeds maxPos or line count exceeds maxLines. + ** (actually, continues beyond maxPos to end of line containing maxPos, + ** in case later characters cause a word wrap back before maxPos) + */ + colNum = 0; + width = 0; + for (p=lineStart; plength(); p=buf->next_char(p)) { + c = buf->char_at(p); // UCS-4 + + /* If the character was a newline, count the line and start over, + otherwise, add it to the width and column counts */ + if (c == '\n') { + if (p >= maxPos) { + *retPos = maxPos; + *retLines = nLines; + *retLineStart = lineStart; + *retLineEnd = maxPos; + return; + } + nLines++; + int p1 = buf->next_char(p); + if (nLines >= maxLines) { + *retPos = p1; + *retLines = nLines; + *retLineStart = p1; + *retLineEnd = p; + return; + } + lineStart = p1; + colNum = 0; + width = 0; + } else { + const char *s = buf->address(p); + colNum++; + // FIXME: it is not a good idea to simply add character widths because on + // some platforms, the width is a floating point value and depends on the + // previous character as well. + width += measure_proportional_character(s, width, p+styleBufOffset); + } + + /* If character exceeded wrap margin, find the break point and wrap there */ + if (width > wrapMarginPix) { + foundBreak = false; + for (b=p; b>=lineStart; b=buf->prev_char(b)) { + c = buf->char_at(b); + if (c == '\t' || c == ' ') { + newLineStart = buf->next_char(b); + colNum = 0; + width = 0; + int iMax = buf->next_char(p); + for (i=buf->next_char(b); inext_char(i)) { + width += measure_proportional_character(buf->address(i), width, + i+styleBufOffset); + colNum++; + } + foundBreak = true; + break; + } + } + if (!foundBreak) { /* no whitespace, just break at margin */ + newLineStart = max(p, buf->next_char(lineStart)); + const char *s = buf->address(b); + colNum++; + width = measure_proportional_character(s, 0, p+styleBufOffset); + } + if (p >= maxPos) { + *retPos = maxPos; + *retLines = maxPos < newLineStart ? nLines : nLines + 1; + *retLineStart = maxPos < newLineStart ? lineStart : newLineStart; + *retLineEnd = maxPos; + return; + } + nLines++; + if (nLines >= maxLines) { + *retPos = foundBreak ? buf->next_char(b) : max(p, buf->next_char(lineStart)); + *retLines = nLines; + *retLineStart = lineStart; + *retLineEnd = foundBreak ? b : p; + return; + } + lineStart = newLineStart; + } + } + + /* reached end of buffer before reaching pos or line target */ + *retPos = buf->length(); + *retLines = nLines; + if (countLastLineMissingNewLine && colNum > 0) + *retLines = buf->next_char(*retLines); + *retLineStart = lineStart; + *retLineEnd = buf->length(); +} + + + +/** + \brief Wrapping calculations. + + Measure the width in pixels of the first character of string "s" at a + particular column "colNum" and buffer position "pos". This is for measuring + characters in proportional or mixed-width highlighting fonts. + + A note about proportional and mixed-width fonts: the mixed width and + proportional font code in nedit does not get much use in general editing, + because nedit doesn't allow per-language-mode fonts, and editing programs + in a proportional font is usually a bad idea, so very few users would + choose a proportional font as a default. There are still probably mixed- + width syntax highlighting cases where things don't redraw properly for + insertion/deletion, though static display and wrapping and resizing + should now be solid because they are now used for online help display. + + \param s text string + \param xPix x pixel position needed for calculating tab widths + \param pos offset within string + \return width of character in pixels + */ +double Fl_Text_Display::measure_proportional_character(const char *s, int xPix, int pos) const { + IS_UTF8_ALIGNED(s) + + if (*s=='\t') { + int tab = col_to_x(4); + return (((xPix/tab)+1)*tab) - xPix; + } + + int charLen = fl_utf8len(*s), style = 0; + if (mStyleBuffer) { + style = mStyleBuffer->byte_at(pos); + } + return string_width(s, charLen, style); +} + + + +/** + \brief Finds both the end of the current line and the start of the next line. + + Why? + In continuous wrap mode, if you need to know both, figuring out one from the + other can be expensive or error prone. The problem comes when there's a + trailing space or tab just before the end of the buffer. To translate an + end of line value to or from the next lines start value, you need to know + whether the trailing space or tab is being used as a line break or just a + normal character, and to find that out would otherwise require counting all + the way back to the beginning of the line. + + \param startPos + \param startPosIsLineStart + \param[out] lineEnd + \param[out] nextLineStart + */ +void Fl_Text_Display::find_line_end(int startPos, bool startPosIsLineStart, + int *lineEnd, int *nextLineStart) const { + IS_UTF8_ALIGNED2(buffer(), startPos) + + int retLines, retLineStart; + + /* if we're not wrapping use more efficient BufEndOfLine */ + if (!mContinuousWrap) { + int le = buffer()->line_end(startPos); + int ls = buffer()->next_char(le); + *lineEnd = le; + *nextLineStart = min(buffer()->length(), ls); + return; + } + + /* use the wrapped line counter routine to count forward one line */ + wrapped_line_counter(buffer(), startPos, buffer()->length(), + 1, startPosIsLineStart, 0, nextLineStart, &retLines, + &retLineStart, lineEnd); +} + + + +/** + \brief Check if the line break is caused by a \\n or by line wrapping. + + Line breaks in continuous wrap mode usually happen at newlines or + whitespace. This line-terminating character is not included in line + width measurements and has a special status as a non-visible character. + However, lines with no whitespace are wrapped without the benefit of a + line terminating character, and this distinction causes endless trouble + with all of the text display code which was originally written without + continuous wrap mode and always expects to wrap at a newline character. + + Given the position of the end of the line, as returned by TextDEndOfLine + or BufEndOfLine, this returns true if there is a line terminating + character, and false if there's not. On the last character in the + buffer, this function can't tell for certain whether a trailing space was + used as a wrap point, and just guesses that it wasn't. So if an exact + accounting is necessary, don't use this function. + + \param lineEndPos index of character where the line wraps + \return 1 if a \\n character causes the line wrap + */ +int Fl_Text_Display::wrap_uses_character(int lineEndPos) const { + IS_UTF8_ALIGNED2(buffer(), lineEndPos) + + unsigned int c; + + if (!mContinuousWrap || lineEndPos == buffer()->length()) + return 1; + + c = buffer()->char_at(lineEndPos); + return c == '\n' || ((c == '\t' || c == ' ') && + lineEndPos + fl_utf8len(c) < buffer()->length()); +} + + + +/** + \brief I don't know what this does! + + Extend the range of a redraw request (from *start to *end) with additional + redraw requests resulting from changes to the attached style buffer (which + contains auxiliary information for coloring or styling text). + + \param startpos ?? + \param endpos ?? + + \todo Unicode? + */ +void Fl_Text_Display::extend_range_for_styles( int *startpos, int *endpos ) { + IS_UTF8_ALIGNED2(buffer(), (*startpos)) + IS_UTF8_ALIGNED2(buffer(), (*endpos)) + + Fl_Text_Selection * sel = mStyleBuffer->primary_selection(); + int extended = 0; + + /* The peculiar protocol used here is that modifications to the style + buffer are marked by selecting them with the buffer's primary Fl_Text_Selection. + The style buffer is usually modified in response to a modify callback on + the text buffer BEFORE Fl_Text_Display.c's modify callback, so that it can keep + the style buffer in step with the text buffer. The style-update + callback can't just call for a redraw, because Fl_Text_Display hasn't processed + the original text changes yet. Anyhow, to minimize redrawing and to + avoid the complexity of scheduling redraws later, this simple protocol + tells the text display's buffer modify callback to extend it's redraw + range to show the text color/and font changes as well. */ + if ( sel->selected() ) { + if ( sel->start() < *startpos ) { + *startpos = sel->start(); + // somewhere while deleting, alignment is lost. We do this just to be sure. + *startpos = buffer()->utf8_align(*startpos); + IS_UTF8_ALIGNED2(buffer(), (*startpos)) + extended = 1; + } + if ( sel->end() > *endpos ) { + *endpos = sel->end(); + *endpos = buffer()->utf8_align(*endpos); + IS_UTF8_ALIGNED2(buffer(), (*endpos)) + extended = 1; + } + } + + /* If the Fl_Text_Selection was extended due to a style change, and some of the + fonts don't match in spacing, extend redraw area to end of line to + redraw characters exposed by possible font size changes */ + if ( extended ) + *endpos = mBuffer->line_end( *endpos ) + 1; + + IS_UTF8_ALIGNED2(buffer(), (*endpos)) +} + + + +/** + \brief Draw the widget. + + This function tries to limit drawing to smaller areas if possible. + */ +void Fl_Text_Display::draw(void) { + // don't even try if there is no associated text buffer! + if (!buffer()) { draw_box(); return; } + + fl_push_clip(x(),y(),w(),h()); // prevent drawing outside widget area + + // draw the non-text, non-scrollbar areas. + if (damage() & FL_DAMAGE_ALL) { + // printf("drawing all (box = %d)\n", box()); + // draw the box() + int W = w(), H = h(); + draw_box(box(), x(), y(), W, H, color()); + + if (mHScrollBar->visible()) + W -= scrollbar_width(); + if (mVScrollBar->visible()) + H -= scrollbar_width(); + + // left margin + fl_rectf(text_area.x-LEFT_MARGIN, text_area.y-TOP_MARGIN, + LEFT_MARGIN, text_area.h+TOP_MARGIN+BOTTOM_MARGIN, + color()); + + // right margin + fl_rectf(text_area.x+text_area.w, text_area.y-TOP_MARGIN, + RIGHT_MARGIN, text_area.h+TOP_MARGIN+BOTTOM_MARGIN, + color()); + + // top margin + fl_rectf(text_area.x, text_area.y-TOP_MARGIN, + text_area.w, TOP_MARGIN, color()); + + // bottom margin + fl_rectf(text_area.x, text_area.y+text_area.h, + text_area.w, BOTTOM_MARGIN, color()); + + // draw that little box in the corner of the scrollbars + if (mVScrollBar->visible() && mHScrollBar->visible()) + fl_rectf(mVScrollBar->x(), mHScrollBar->y(), + mVScrollBar->w(), mHScrollBar->h(), + FL_GRAY); + + // blank the previous cursor protrusions + } + else if (damage() & (FL_DAMAGE_SCROLL | FL_DAMAGE_EXPOSE)) { + // printf("blanking previous cursor extrusions at Y: %d\n", mCursorOldY); + // CET - FIXME - save old cursor position instead and just draw side needed? + fl_push_clip(text_area.x-LEFT_MARGIN, + text_area.y, + text_area.w+LEFT_MARGIN+RIGHT_MARGIN, + text_area.h); + fl_rectf(text_area.x-LEFT_MARGIN, mCursorOldY, + LEFT_MARGIN, mMaxsize, color()); + fl_rectf(text_area.x+text_area.w, mCursorOldY, + RIGHT_MARGIN, mMaxsize, color()); + fl_pop_clip(); + } + + // draw the scrollbars + if (damage() & (FL_DAMAGE_ALL | FL_DAMAGE_CHILD)) { + mVScrollBar->damage(FL_DAMAGE_ALL); + mHScrollBar->damage(FL_DAMAGE_ALL); + } + update_child(*mVScrollBar); + update_child(*mHScrollBar); + + // draw all of the text + if (damage() & (FL_DAMAGE_ALL | FL_DAMAGE_EXPOSE)) { + //printf("drawing all text\n"); + int X, Y, W, H; + if (fl_clip_box(text_area.x, text_area.y, text_area.w, text_area.h, + X, Y, W, H)) { + // Draw text using the intersected clipping box... + // (this sets the clipping internally) + draw_text(X, Y, W, H); + } else { + // Draw the whole area... + draw_text(text_area.x, text_area.y, text_area.w, text_area.h); + } + } + else if (damage() & FL_DAMAGE_SCROLL) { + // draw some lines of text + fl_push_clip(text_area.x, text_area.y, + text_area.w, text_area.h); + //printf("drawing text from %d to %d\n", damage_range1_start, damage_range1_end); + draw_range(damage_range1_start, damage_range1_end); + if (damage_range2_end != -1) { + //printf("drawing text from %d to %d\n", damage_range2_start, damage_range2_end); + draw_range(damage_range2_start, damage_range2_end); + } + damage_range1_start = damage_range1_end = -1; + damage_range2_start = damage_range2_end = -1; + fl_pop_clip(); + } + + // draw the text cursor + if (damage() & (FL_DAMAGE_ALL | FL_DAMAGE_SCROLL | FL_DAMAGE_EXPOSE) + && !buffer()->primary_selection()->selected() && + mCursorOn && Fl::focus() == this ) { + fl_push_clip(text_area.x-LEFT_MARGIN, + text_area.y, + text_area.w+LEFT_MARGIN+RIGHT_MARGIN, + text_area.h); + + int X, Y; + if (position_to_xy(mCursorPos, &X, &Y)) draw_cursor(X, Y); + // else puts("position_to_xy() failed - unable to draw cursor!"); + //printf("drew cursor at pos: %d (%d,%d)\n", mCursorPos, X, Y); + mCursorOldY = Y; + fl_pop_clip(); + } + fl_pop_clip(); +} + + + +// this processes drag events due to mouse for Fl_Text_Display and +// also drags due to cursor movement with shift held down for +// Fl_Text_Editor +void fl_text_drag_me(int pos, Fl_Text_Display* d) { + if (d->dragType == Fl_Text_Display::DRAG_CHAR) { + if (pos >= d->dragPos) { + d->buffer()->select(d->dragPos, pos); + } else { + d->buffer()->select(pos, d->dragPos); + } + d->insert_position(pos); + } else if (d->dragType == Fl_Text_Display::DRAG_WORD) { + if (pos >= d->dragPos) { + d->insert_position(d->word_end(pos)); + d->buffer()->select(d->word_start(d->dragPos), d->word_end(pos)); + } else { + d->insert_position(d->word_start(pos)); + d->buffer()->select(d->word_start(pos), d->word_end(d->dragPos)); + } + } else if (d->dragType == Fl_Text_Display::DRAG_LINE) { + if (pos >= d->dragPos) { + d->insert_position(d->buffer()->line_end(pos)+1); + d->buffer()->select(d->buffer()->line_start(d->dragPos), + d->buffer()->line_end(pos)+1); + } else { + d->insert_position(d->buffer()->line_start(pos)); + d->buffer()->select(d->buffer()->line_start(pos), + d->buffer()->line_end(d->dragPos)+1); + } + } +} + + + +/** + \brief Timer callback for scroll events. + + This timer event scrolls the text view proportionally to + how far the mouse pointer has left the text area. This + allows for smooth scrolling without "wiggeling" the mouse. + */ +void Fl_Text_Display::scroll_timer_cb(void *user_data) { + Fl_Text_Display *w = (Fl_Text_Display*)user_data; + int pos; + switch (scroll_direction) { + case 1: // mouse is to the right, scroll left + w->scroll(w->mTopLineNum, w->mHorizOffset + scroll_amount); + pos = w->xy_to_position(w->text_area.x + w->text_area.w, scroll_y, CURSOR_POS); + break; + case 2: // mouse is to the left, scroll right + w->scroll(w->mTopLineNum, w->mHorizOffset + scroll_amount); + pos = w->xy_to_position(w->text_area.x, scroll_y, CURSOR_POS); + break; + case 3: // mouse is above, scroll down + w->scroll(w->mTopLineNum + scroll_amount, w->mHorizOffset); + pos = w->xy_to_position(scroll_x, w->text_area.y, CURSOR_POS); + break; + case 4: // mouse is below, scroll up + w->scroll(w->mTopLineNum + scroll_amount, w->mHorizOffset); + pos = w->xy_to_position(scroll_x, w->text_area.y + w->text_area.h, CURSOR_POS); + break; + default: + return; + } + fl_text_drag_me(pos, w); + Fl::repeat_timeout(.1, scroll_timer_cb, user_data); +} + + + +/** + \brief Event handling. + */ +int Fl_Text_Display::handle(int event) { + if (!buffer()) return 0; + // This isn't very elegant! + if (!Fl::event_inside(text_area.x, text_area.y, text_area.w, text_area.h) && + !dragging && event != FL_LEAVE && event != FL_ENTER && + event != FL_MOVE && event != FL_FOCUS && event != FL_UNFOCUS && + event != FL_KEYBOARD && event != FL_KEYUP) { + return Fl_Group::handle(event); + } + + switch (event) { + case FL_ENTER: + case FL_MOVE: + if (active_r()) { + if (Fl::event_inside(text_area.x, text_area.y, text_area.w, + text_area.h)) window()->cursor(FL_CURSOR_INSERT); + else window()->cursor(FL_CURSOR_DEFAULT); + return 1; + } else { + return 0; + } + + case FL_LEAVE: + case FL_HIDE: + if (active_r() && window()) { + window()->cursor(FL_CURSOR_DEFAULT); + + return 1; + } else { + return 0; + } + + case FL_PUSH: { + if (active_r() && window()) { + if (Fl::event_inside(text_area.x, text_area.y, text_area.w, + text_area.h)) window()->cursor(FL_CURSOR_INSERT); + else window()->cursor(FL_CURSOR_DEFAULT); + } + + if (Fl::focus() != this) { + Fl::focus(this); + handle(FL_FOCUS); + } + if (Fl_Group::handle(event)) return 1; + if (Fl::event_state()&FL_SHIFT) return handle(FL_DRAG); + dragging = 1; + int pos = xy_to_position(Fl::event_x(), Fl::event_y(), CURSOR_POS); + dragPos = pos; + if (buffer()->primary_selection()->includes(pos)) { + dragType = DRAG_START_DND; + return 1; + } + dragType = Fl::event_clicks(); + if (dragType == DRAG_CHAR) + buffer()->unselect(); + else if (dragType == DRAG_WORD) + buffer()->select(word_start(pos), word_end(pos)); + else if (dragType == DRAG_LINE) + buffer()->select(buffer()->line_start(pos), buffer()->next_char(buffer()->line_end(pos))); + + if (buffer()->primary_selection()->selected()) + insert_position(buffer()->primary_selection()->end()); + else + insert_position(pos); + show_insert_position(); + return 1; + } + + case FL_DRAG: { + if (dragType==DRAG_NONE) + return 1; + if (dragType==DRAG_START_DND) { + if (!Fl::event_is_click()) { + const char* copy = buffer()->selection_text(); + Fl::dnd(); + free((void*)copy); + } + return 1; + } + int X = Fl::event_x(), Y = Fl::event_y(), pos = insert_position(); + // if we leave the text_area, we start a timer event + // that will take care of scrolling and selecting + if (Y < text_area.y) { + scroll_x = X; + scroll_amount = (Y - text_area.y) / 5 - 1; + if (!scroll_direction) { + Fl::add_timeout(.01, scroll_timer_cb, this); + } + scroll_direction = 3; + } else if (Y >= text_area.y+text_area.h) { + scroll_x = X; + scroll_amount = (Y - text_area.y - text_area.h) / 5 + 1; + if (!scroll_direction) { + Fl::add_timeout(.01, scroll_timer_cb, this); + } + scroll_direction = 4; + } else if (X < text_area.x) { + scroll_y = Y; + scroll_amount = (X - text_area.x) / 2 - 1; + if (!scroll_direction) { + Fl::add_timeout(.01, scroll_timer_cb, this); + } + scroll_direction = 2; + } else if (X >= text_area.x+text_area.w) { + scroll_y = Y; + scroll_amount = (X - text_area.x - text_area.w) / 2 + 1; + if (!scroll_direction) { + Fl::add_timeout(.01, scroll_timer_cb, this); + } + scroll_direction = 1; + } else { + if (scroll_direction) { + Fl::remove_timeout(scroll_timer_cb, this); + scroll_direction = 0; + } + pos = xy_to_position(X, Y, CURSOR_POS); + pos = buffer()->next_char(pos); + } + fl_text_drag_me(pos, this); + return 1; + } + + case FL_RELEASE: { + dragging = 0; + if (scroll_direction) { + Fl::remove_timeout(scroll_timer_cb, this); + scroll_direction = 0; + } + + // convert from WORD or LINE selection to CHAR + if (insert_position() >= dragPos) + dragPos = buffer()->primary_selection()->start(); + else + dragPos = buffer()->primary_selection()->end(); + dragType = DRAG_CHAR; + + const char* copy = buffer()->selection_text(); + if (*copy) Fl::copy(copy, strlen(copy), 0); + free((void*)copy); + return 1; + } + + case FL_MOUSEWHEEL: + if (Fl::event_dy()) return mVScrollBar->handle(event); + else return mHScrollBar->handle(event); + + case FL_UNFOCUS: + if (active_r() && window()) window()->cursor(FL_CURSOR_DEFAULT); + case FL_FOCUS: + if (buffer()->selected()) { + int start, end; + if (buffer()->selection_position(&start, &end)) + redisplay_range(start, end); + } + if (buffer()->secondary_selected()) { + int start, end; + if (buffer()->secondary_selection_position(&start, &end)) + redisplay_range(start, end); + } + if (buffer()->highlight()) { + int start, end; + if (buffer()->highlight_position(&start, &end)) + redisplay_range(start, end); + } + return 1; + + case FL_KEYBOARD: + // Copy? + if ((Fl::event_state()&(FL_CTRL|FL_COMMAND)) && Fl::event_key()=='c') { + if (!buffer()->selected()) return 1; + const char *copy = buffer()->selection_text(); + if (*copy) Fl::copy(copy, strlen(copy), 1); + free((void*)copy); + return 1; + } + + // Select all ? + if ((Fl::event_state()&(FL_CTRL|FL_COMMAND)) && Fl::event_key()=='a') { + buffer()->select(0,buffer()->length()); + return 1; + } + + if (mVScrollBar->handle(event)) return 1; + if (mHScrollBar->handle(event)) return 1; + + break; + + case FL_SHORTCUT: + if (!(shortcut() ? Fl::test_shortcut(shortcut()) : test_shortcut())) + return 0; + if (Fl::visible_focus() && handle(FL_FOCUS)) { + Fl::focus(this); + return 1; + } + break; + + } + + return 0; +} + + +/* + Convert an x pixel position into a column number. + */ +double Fl_Text_Display::x_to_col(double y) const +{ + if (!mColumnScale) { + mColumnScale = string_width("Mitg", 4, 'A') / 4.0; + } + return (y/mColumnScale)+0.5; +} + + +/** + Convert a column number into an x pixel position. + */ +double Fl_Text_Display::col_to_x(double col) const +{ + if (!mColumnScale) { + // recalculate column scale value + x_to_col(0); + } + return col*mColumnScale; +} + + + + +// +// End of "$Id: Fl_Text_Display.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Text_Editor.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Text_Editor.cxx new file mode 100644 index 0000000..a356ae3 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Text_Editor.cxx @@ -0,0 +1,637 @@ +// +// "$Id: Fl_Text_Editor.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Copyright 2001-2010 by Bill Spitzak and others. +// Original code Copyright Mark Edel. Permission to distribute under +// the LGPL for the FLTK library granted by Mark E. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include "flstring.h" +#include +#include +#include +#include +#include + + +/* Keyboard Control Matrix + +key\modifier plain Ctrl Alt Meta + left 1/1 13/9 0/13 0/9 + right 2/2 14/10 0/14 0/10 + up 3/19 21/7 0/15 0/17 + down 4/20 22/8 0/16 0/18 + home 9/5 17/0 0/0 0/0 + end 10/6 18/0 0/0 0/0 + page up 11/7 23/0 0/11 0/0 + page down 12/8 24/0 0/12 0/0 + (FLTK action / OS X action) + (adding the shift key extends the selection, all other combinations are no-op) + + 0: no-op + 1: move cursor to the left, at line beginning wrap to end of prev line, at doc start no-op + 2: move cursor to the right, at line end move to beginning of the next line, at doc end no-op + 3: move cursor up, at doc top no-op + 4: move cursor down, at doc bottom no-op + 5: scroll display to top of text (cursor unchanged) + 6: scroll display to end of text (cursor unchanged) + 7: scroll text down one page (cursor unchanged) + 8: scroll text up one page (cursor unchanged) + 9: move cursor to beginning of line + 10: move cursor to end of line + 11: move cursor up one page and scroll down + 12: move cursor down one page and scroll up + 13: move to the beginning of the word or the previous word + 14: move to the end of the word or the next word + 15: if start of line: start of prev line, else start of this line + 16: if end of line: end of next line, else end of this line + 17: move cursor to the beginning of the document + 18: move cursor to the end of the document + 19: move cursor up, at doc top: home, at doc start: no-op) + 20: move cursor down, at doc bot: end, at doc end: no-op) + 21: scroll text down one line (cursor unchanged) + 22: scroll text up one line (cursor unchanged) + 23: move cursor to the beginning of the top of the screen + 24: move cursor to the beginning of the bottom of the window +*/ + +/** The constructor creates a new text editor widget.*/ +Fl_Text_Editor::Fl_Text_Editor(int X, int Y, int W, int H, const char* l) + : Fl_Text_Display(X, Y, W, H, l) { + mCursorOn = 1; + insert_mode_ = 1; + key_bindings = 0; + + // handle the default key bindings + add_default_key_bindings(&key_bindings); + + // handle everything else + default_key_function(kf_default); +} + +#ifndef FL_DOXYGEN +Fl_Text_Editor::Key_Binding* Fl_Text_Editor::global_key_bindings = 0; +#endif + +// These are the default key bindings every widget should start with +static struct { + int key; + int state; + Fl_Text_Editor::Key_Func func; +} default_key_bindings[] = { + { FL_Escape, FL_TEXT_EDITOR_ANY_STATE, Fl_Text_Editor::kf_ignore }, + { FL_Enter, FL_TEXT_EDITOR_ANY_STATE, Fl_Text_Editor::kf_enter }, + { FL_KP_Enter, FL_TEXT_EDITOR_ANY_STATE, Fl_Text_Editor::kf_enter }, + { FL_BackSpace, FL_TEXT_EDITOR_ANY_STATE, Fl_Text_Editor::kf_backspace }, + { FL_Insert, FL_TEXT_EDITOR_ANY_STATE, Fl_Text_Editor::kf_insert }, + { FL_Delete, FL_TEXT_EDITOR_ANY_STATE, Fl_Text_Editor::kf_delete }, + { FL_Home, 0, Fl_Text_Editor::kf_move }, + { FL_End, 0, Fl_Text_Editor::kf_move }, + { FL_Left, 0, Fl_Text_Editor::kf_move }, + { FL_Up, 0, Fl_Text_Editor::kf_move }, + { FL_Right, 0, Fl_Text_Editor::kf_move }, + { FL_Down, 0, Fl_Text_Editor::kf_move }, + { FL_Page_Up, 0, Fl_Text_Editor::kf_move }, + { FL_Page_Down, 0, Fl_Text_Editor::kf_move }, + { FL_Home, FL_SHIFT, Fl_Text_Editor::kf_shift_move }, + { FL_End, FL_SHIFT, Fl_Text_Editor::kf_shift_move }, + { FL_Left, FL_SHIFT, Fl_Text_Editor::kf_shift_move }, + { FL_Up, FL_SHIFT, Fl_Text_Editor::kf_shift_move }, + { FL_Right, FL_SHIFT, Fl_Text_Editor::kf_shift_move }, + { FL_Down, FL_SHIFT, Fl_Text_Editor::kf_shift_move }, + { FL_Page_Up, FL_SHIFT, Fl_Text_Editor::kf_shift_move }, + { FL_Page_Down, FL_SHIFT, Fl_Text_Editor::kf_shift_move }, + { FL_Home, FL_CTRL, Fl_Text_Editor::kf_ctrl_move }, + { FL_End, FL_CTRL, Fl_Text_Editor::kf_ctrl_move }, + { FL_Left, FL_CTRL, Fl_Text_Editor::kf_ctrl_move }, + { FL_Up, FL_CTRL, Fl_Text_Editor::kf_ctrl_move }, + { FL_Right, FL_CTRL, Fl_Text_Editor::kf_ctrl_move }, + { FL_Down, FL_CTRL, Fl_Text_Editor::kf_ctrl_move }, + { FL_Page_Up, FL_CTRL, Fl_Text_Editor::kf_ctrl_move }, + { FL_Page_Down, FL_CTRL, Fl_Text_Editor::kf_ctrl_move }, + { FL_Home, FL_CTRL|FL_SHIFT, Fl_Text_Editor::kf_c_s_move }, + { FL_End, FL_CTRL|FL_SHIFT, Fl_Text_Editor::kf_c_s_move }, + { FL_Left, FL_CTRL|FL_SHIFT, Fl_Text_Editor::kf_c_s_move }, + { FL_Up, FL_CTRL|FL_SHIFT, Fl_Text_Editor::kf_c_s_move }, + { FL_Right, FL_CTRL|FL_SHIFT, Fl_Text_Editor::kf_c_s_move }, + { FL_Down, FL_CTRL|FL_SHIFT, Fl_Text_Editor::kf_c_s_move }, + { FL_Page_Up, FL_CTRL|FL_SHIFT, Fl_Text_Editor::kf_c_s_move }, + { FL_Page_Down, FL_CTRL|FL_SHIFT, Fl_Text_Editor::kf_c_s_move }, +//{ FL_Clear, 0, Fl_Text_Editor::delete_to_eol }, + { 'z', FL_CTRL, Fl_Text_Editor::kf_undo }, + { '/', FL_CTRL, Fl_Text_Editor::kf_undo }, + { 'x', FL_CTRL, Fl_Text_Editor::kf_cut }, + { FL_Delete, FL_SHIFT, Fl_Text_Editor::kf_cut }, + { 'c', FL_CTRL, Fl_Text_Editor::kf_copy }, + { FL_Insert, FL_CTRL, Fl_Text_Editor::kf_copy }, + { 'v', FL_CTRL, Fl_Text_Editor::kf_paste }, + { FL_Insert, FL_SHIFT, Fl_Text_Editor::kf_paste }, + { 'a', FL_CTRL, Fl_Text_Editor::kf_select_all }, + +#ifdef __APPLE__ + // Define CMD+key accelerators... + { 'z', FL_COMMAND, Fl_Text_Editor::kf_undo }, + { 'x', FL_COMMAND, Fl_Text_Editor::kf_cut }, + { 'c', FL_COMMAND, Fl_Text_Editor::kf_copy }, + { 'v', FL_COMMAND, Fl_Text_Editor::kf_paste }, + { 'a', FL_COMMAND, Fl_Text_Editor::kf_select_all }, + { FL_Left, FL_COMMAND, Fl_Text_Editor::kf_meta_move }, + { FL_Right, FL_COMMAND, Fl_Text_Editor::kf_meta_move }, + { FL_Up, FL_COMMAND, Fl_Text_Editor::kf_meta_move }, + { FL_Down, FL_COMMAND, Fl_Text_Editor::kf_meta_move }, + { FL_Left, FL_COMMAND|FL_SHIFT, Fl_Text_Editor::kf_m_s_move }, + { FL_Right, FL_COMMAND|FL_SHIFT, Fl_Text_Editor::kf_m_s_move }, + { FL_Up, FL_COMMAND|FL_SHIFT, Fl_Text_Editor::kf_m_s_move }, + { FL_Down, FL_COMMAND|FL_SHIFT, Fl_Text_Editor::kf_m_s_move }, +#endif // __APPLE__ + + { 0, 0, 0 } +}; + +/** Adds all of the default editor key bindings to the specified key binding list.*/ +void Fl_Text_Editor::add_default_key_bindings(Key_Binding** list) { + for (int i = 0; default_key_bindings[i].key; i++) { + add_key_binding(default_key_bindings[i].key, + default_key_bindings[i].state, + default_key_bindings[i].func, + list); + } +} + +/** Returns the function associated with a key binding.*/ +Fl_Text_Editor::Key_Func Fl_Text_Editor::bound_key_function(int key, int state, Key_Binding* list) { + Key_Binding* cur; + for (cur = list; cur; cur = cur->next) + if (cur->key == key) + if (cur->state == FL_TEXT_EDITOR_ANY_STATE || cur->state == state) + break; + if (!cur) return 0; + return cur->function; +} + +/** Removes all of the key bindings associated with the text editor or list.*/ +void Fl_Text_Editor::remove_all_key_bindings(Key_Binding** list) { + Key_Binding *cur, *next; + for (cur = *list; cur; cur = next) { + next = cur->next; + delete cur; + } + *list = 0; +} + +/** Removes the key binding associated with the key "key" of state "state" */ +void Fl_Text_Editor::remove_key_binding(int key, int state, Key_Binding** list) { + Key_Binding *cur, *last = 0; + for (cur = *list; cur; last = cur, cur = cur->next) + if (cur->key == key && cur->state == state) break; + if (!cur) return; + if (last) last->next = cur->next; + else *list = cur->next; + delete cur; +} +/** Adds a key of state "state" with the function "function" */ +void Fl_Text_Editor::add_key_binding(int key, int state, Key_Func function, + Key_Binding** list) { + Key_Binding* kb = new Key_Binding; + kb->key = key; + kb->state = state; + kb->function = function; + kb->next = *list; + *list = kb; +} + +//////////////////////////////////////////////////////////////// + +#define NORMAL_INPUT_MOVE 0 + +static void kill_selection(Fl_Text_Editor* e) { + if (e->buffer()->selected()) { + e->insert_position(e->buffer()->primary_selection()->start()); + e->buffer()->remove_selection(); + } +} + +/** Inserts the text associated with the key */ +int Fl_Text_Editor::kf_default(int c, Fl_Text_Editor* e) { + // FIXME: this function is a mess! Fix this! + if (!c || (!isprint(c) && c != '\t')) return 0; + char s[2] = "\0"; + s[0] = (char)c; + kill_selection(e); + if (e->insert_mode()) e->insert(s); + else e->overstrike(s); + e->show_insert_position(); + e->set_changed(); + if (e->when()&FL_WHEN_CHANGED) e->do_callback(); + return 1; +} + +/** Ignores the keypress */ +int Fl_Text_Editor::kf_ignore(int, Fl_Text_Editor*) { + return 0; // don't handle +} +/** Does a backspace in the current buffer.*/ +int Fl_Text_Editor::kf_backspace(int, Fl_Text_Editor* e) { + if (!e->buffer()->selected() && e->move_left()) { + int p1 = e->insert_position(); + int p2 = e->buffer()->next_char(p1); + e->buffer()->select(p1, p2); + } + kill_selection(e); + e->show_insert_position(); + e->set_changed(); + if (e->when()&FL_WHEN_CHANGED) e->do_callback(); + return 1; +} + +/** Inserts a newline at the current cursor position */ +int Fl_Text_Editor::kf_enter(int, Fl_Text_Editor* e) { + kill_selection(e); + e->insert("\n"); + e->show_insert_position(); + e->set_changed(); + if (e->when()&FL_WHEN_CHANGED) e->do_callback(); + return 1; +} + +extern void fl_text_drag_me(int pos, Fl_Text_Display* d); +/** Moves the text cursor in the direction indicated by key c.*/ +int Fl_Text_Editor::kf_move(int c, Fl_Text_Editor* e) { + int i; + int selected = e->buffer()->selected(); + if (!selected) + e->dragPos = e->insert_position(); + e->buffer()->unselect(); + switch (c) { + case FL_Home: + e->insert_position(e->buffer()->line_start(e->insert_position())); + break; + case FL_End: + e->insert_position(e->buffer()->line_end(e->insert_position())); + break; + case FL_Left: + e->move_left(); + break; + case FL_Right: + e->move_right(); + break; + case FL_Up: + e->move_up(); + break; + case FL_Down: + e->move_down(); + break; + case FL_Page_Up: + for (i = 0; i < e->mNVisibleLines - 1; i++) e->move_up(); + break; + case FL_Page_Down: + for (i = 0; i < e->mNVisibleLines - 1; i++) e->move_down(); + break; + } + e->show_insert_position(); + return 1; +} + +/** Extends the current selection in the direction of key c.*/ +int Fl_Text_Editor::kf_shift_move(int c, Fl_Text_Editor* e) { + kf_move(c, e); + fl_text_drag_me(e->insert_position(), e); + return 1; +} +/** Moves the current text cursor in the direction indicated by control key */ +int Fl_Text_Editor::kf_ctrl_move(int c, Fl_Text_Editor* e) { + if (!e->buffer()->selected()) + e->dragPos = e->insert_position(); + if (c != FL_Up && c != FL_Down) { + e->buffer()->unselect(); + e->show_insert_position(); + } + switch (c) { + case FL_Home: + e->insert_position(0); + e->scroll(0, 0); + break; + case FL_End: + e->insert_position(e->buffer()->length()); + e->scroll(e->count_lines(0, e->buffer()->length(), 1), 0); + break; + case FL_Left: + e->previous_word(); + break; + case FL_Right: + e->next_word(); + break; + case FL_Up: + e->scroll(e->mTopLineNum-1, e->mHorizOffset); + break; + case FL_Down: + e->scroll(e->mTopLineNum+1, e->mHorizOffset); + break; + case FL_Page_Up: + e->insert_position(e->mLineStarts[0]); + break; + case FL_Page_Down: + e->insert_position(e->mLineStarts[e->mNVisibleLines-2]); + break; + } + return 1; +} + +/** Moves the current text cursor in the direction indicated by meta key */ +int Fl_Text_Editor::kf_meta_move(int c, Fl_Text_Editor* e) { + if (!e->buffer()->selected()) + e->dragPos = e->insert_position(); + if (c != FL_Up && c != FL_Down) { + e->buffer()->unselect(); + e->show_insert_position(); + } + switch (c) { + case FL_Up: // top of buffer + e->insert_position(0); + e->scroll(0, 0); + break; + case FL_Down: // end of buffer + e->insert_position(e->buffer()->length()); + e->scroll(e->count_lines(0, e->buffer()->length(), 1), 0); + break; + case FL_Left: // beginning of line + kf_move(FL_Home, e); + break; + case FL_Right: // end of line + kf_move(FL_End, e); + break; + } + return 1; +} + +/** Extends the current selection in the direction indicated by meta key c. */ +int Fl_Text_Editor::kf_m_s_move(int c, Fl_Text_Editor* e) { + kf_meta_move(c, e); + fl_text_drag_me(e->insert_position(), e); + return 1; +} + +/** Extends the current selection in the direction indicated by control key c. */ +int Fl_Text_Editor::kf_c_s_move(int c, Fl_Text_Editor* e) { + kf_ctrl_move(c, e); + fl_text_drag_me(e->insert_position(), e); + return 1; +} + +/** Moves the text cursor to the beginning of the current line.*/ +int Fl_Text_Editor::kf_home(int, Fl_Text_Editor* e) { + return kf_move(FL_Home, e); +} + +/** Moves the text cursor to the end of the current line.*/ +int Fl_Text_Editor::kf_end(int, Fl_Text_Editor* e) { + return kf_move(FL_End, e); +} + +/** Moves the text cursor one character to the left.*/ +int Fl_Text_Editor::kf_left(int, Fl_Text_Editor* e) { + return kf_move(FL_Left, e); +} + +/** Moves the text cursor one line up.*/ +int Fl_Text_Editor::kf_up(int, Fl_Text_Editor* e) { + return kf_move(FL_Up, e); +} + +/** Moves the text cursor one character to the right.*/ +int Fl_Text_Editor::kf_right(int, Fl_Text_Editor* e) { + return kf_move(FL_Right, e); +} +/** Moves the text cursor one line down.*/ +int Fl_Text_Editor::kf_down(int, Fl_Text_Editor* e) { + return kf_move(FL_Down, e); +} + +/** Moves the text cursor up one page.*/ +int Fl_Text_Editor::kf_page_up(int, Fl_Text_Editor* e) { + return kf_move(FL_Page_Up, e); +} + +/** Moves the text cursor down one page.*/ +int Fl_Text_Editor::kf_page_down(int, Fl_Text_Editor* e) { + return kf_move(FL_Page_Down, e); +} +/** Toggles the insert mode in the text editor.*/ +int Fl_Text_Editor::kf_insert(int, Fl_Text_Editor* e) { + e->insert_mode(e->insert_mode() ? 0 : 1); + return 1; +} + +/** Does a delete of selected text or the current character in the current buffer.*/ +int Fl_Text_Editor::kf_delete(int, Fl_Text_Editor* e) { + if (!e->buffer()->selected()) { + int p1 = e->insert_position(); + int p2 = e->buffer()->next_char(p1); + e->buffer()->select(p1, p2); + } + + kill_selection(e); + e->show_insert_position(); + e->set_changed(); + if (e->when()&FL_WHEN_CHANGED) e->do_callback(); + return 1; +} + +/** Does a copy of selected text or the current character in the current buffer.*/ +int Fl_Text_Editor::kf_copy(int, Fl_Text_Editor* e) { + if (!e->buffer()->selected()) return 1; + const char *copy = e->buffer()->selection_text(); + if (*copy) Fl::copy(copy, strlen(copy), 1); + free((void*)copy); + e->show_insert_position(); + return 1; +} + +/** Does a cut of selected text in the current buffer.*/ +int Fl_Text_Editor::kf_cut(int c, Fl_Text_Editor* e) { + kf_copy(c, e); + kill_selection(e); + e->set_changed(); + if (e->when()&FL_WHEN_CHANGED) e->do_callback(); + return 1; +} + +/** Does a paste of selected text in the current buffer.*/ +int Fl_Text_Editor::kf_paste(int, Fl_Text_Editor* e) { + kill_selection(e); + Fl::paste(*e, 1); + e->show_insert_position(); + e->set_changed(); + if (e->when()&FL_WHEN_CHANGED) e->do_callback(); + return 1; +} + +/** Selects all text in the current buffer.*/ +int Fl_Text_Editor::kf_select_all(int, Fl_Text_Editor* e) { + e->buffer()->select(0, e->buffer()->length()); + return 1; +} +/** Undo last edit in the current buffer. Also deselect previous selection. */ +int Fl_Text_Editor::kf_undo(int , Fl_Text_Editor* e) { + e->buffer()->unselect(); + int crsr; + int ret = e->buffer()->undo(&crsr); + e->insert_position(crsr); + e->show_insert_position(); + e->set_changed(); + if (e->when()&FL_WHEN_CHANGED) e->do_callback(); + return ret; +} + +/** Handles a key press in the editor */ +int Fl_Text_Editor::handle_key() { + // Call FLTK's rules to try to turn this into a printing character. + // This uses the right-hand ctrl key as a "compose prefix" and returns + // the changes that should be made to the text, as a number of + // bytes to delete and a string to insert: + int del = 0; + if (Fl::compose(del)) { + if (del) { + int dp = insert_position(), di = del; + while (di--) dp = buffer()->prev_char_clipped(dp); + buffer()->select(dp, insert_position()); + } + kill_selection(this); + if (Fl::event_length()) { + if (insert_mode()) insert(Fl::event_text()); + else overstrike(Fl::event_text()); + } + show_insert_position(); + set_changed(); + if (when()&FL_WHEN_CHANGED) do_callback(); + return 1; + } + + int key = Fl::event_key(), state = Fl::event_state(), c = Fl::event_text()[0]; + state &= FL_SHIFT|FL_CTRL|FL_ALT|FL_META; // only care about these states + Key_Func f; + f = bound_key_function(key, state, global_key_bindings); + if (!f) f = bound_key_function(key, state, key_bindings); + if (f) return f(key, this); + if (default_key_function_ && !state) return default_key_function_(c, this); + return 0; +} + +/** does or does not a callback according to changed() and when() settings */ +void Fl_Text_Editor::maybe_do_callback() { +// printf("Fl_Text_Editor::maybe_do_callback()\n"); +// printf("changed()=%d, when()=%x\n", changed(), when()); + if (changed() || (when()&FL_WHEN_NOT_CHANGED)) do_callback(); +} + +int Fl_Text_Editor::handle(int event) { + static int dndCursorPos; + + if (!buffer()) return 0; + + switch (event) { + case FL_FOCUS: + show_cursor(mCursorOn); // redraws the cursor + if (buffer()->selected()) redraw(); // Redraw selections... + Fl::focus(this); + return 1; + + case FL_UNFOCUS: + show_cursor(mCursorOn); // redraws the cursor + if (buffer()->selected()) redraw(); // Redraw selections... + case FL_HIDE: + if (when() & FL_WHEN_RELEASE) maybe_do_callback(); + return 1; + + case FL_KEYBOARD: + if (active_r() && window() && this == Fl::belowmouse()) + window()->cursor(FL_CURSOR_NONE); + return handle_key(); + + case FL_PASTE: + if (!Fl::event_text()) { + fl_beep(); + return 1; + } + buffer()->remove_selection(); + if (insert_mode()) insert(Fl::event_text()); + else overstrike(Fl::event_text()); + show_insert_position(); + set_changed(); + if (when()&FL_WHEN_CHANGED) do_callback(); + return 1; + + case FL_ENTER: +// MRS: WIN32 only? Need to test! +// case FL_MOVE: + show_cursor(mCursorOn); + return 1; + + case FL_PUSH: + if (Fl::event_button() == 2) { + // don't let the text_display see this event + if (Fl_Group::handle(event)) return 1; + dragType = DRAG_NONE; + Fl::paste(*this, 0); + Fl::focus(this); + set_changed(); + if (when()&FL_WHEN_CHANGED) do_callback(); + return 1; + } + break; + + case FL_SHORTCUT: + if (!(shortcut() ? Fl::test_shortcut(shortcut()) : test_shortcut())) + return 0; + if (Fl::visible_focus() && handle(FL_FOCUS)) { + Fl::focus(this); + return 1; + } + break; + + // Handle drag'n'drop attempt by the user. This is a simplified + // implementation which allows dnd operations onto the scroll bars. + case FL_DND_ENTER: // save the current cursor position + if (Fl::visible_focus() && handle(FL_FOCUS)) + Fl::focus(this); + show_cursor(mCursorOn); + dndCursorPos = insert_position(); + /* fall through */ + case FL_DND_DRAG: // show a temporary insertion cursor + insert_position(xy_to_position(Fl::event_x(), Fl::event_y(), CURSOR_POS)); + return 1; + case FL_DND_LEAVE: // restore original cursor + insert_position(dndCursorPos); + return 1; + case FL_DND_RELEASE: // keep insertion cursor and wait for the FL_PASTE event + buffer()->unselect(); // FL_PASTE must not destroy current selection! + return 1; + } + + return Fl_Text_Display::handle(event); +} + +// +// End of "$Id: Fl_Text_Editor.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Tile.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Tile.cxx new file mode 100644 index 0000000..0d245db --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Tile.cxx @@ -0,0 +1,214 @@ +// +// "$Id: Fl_Tile.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Tile widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + + +// Group of 2 or 4 "tiles" that can be resized by dragging border +// The size of the first child determines where the resize border is. +// The resizebox is used to limit where the border can be dragged to. + +#include +#include +#include +#include + +// Drag the edges that were initially at oldx,oldy to newx,newy: +// pass zero as oldx or oldy to disable drag in that direction: +/** + Drag the intersection at from_x,from_y to to_x,to_y. + This redraws all the necessary children. +*/ +void Fl_Tile::position(int oix, int oiy, int newx, int newy) { + Fl_Widget*const* a = array(); + int *p = sizes(); + p += 8; // skip group & resizable's saved size + for (int i=children(); i--; p += 4) { + Fl_Widget* o = *a++; + if (o == resizable()) continue; + int X = o->x(); + int R = X+o->w(); + if (oix) { + int t = p[0]; + if (t == oix || (t>oix && Xnewx) ) X = newx; + t = p[1]; + if (t == oix || (t>oix && Rnewx) ) R = newx; + } + int Y = o->y(); + int B = Y+o->h(); + if (oiy) { + int t = p[2]; + if (t == oiy || (t>oiy && Ynewy) ) Y = newy; + t = p[3]; + if (t == oiy || (t>oiy && Bnewy) ) B = newy; + } + o->damage_resize(X,Y,R-X,B-Y); + } +} + +// move the lower-right corner (sort of): +void Fl_Tile::resize(int X,int Y,int W,int H) { + //Fl_Group::resize(X, Y, W, H); + //return; + // remember how much to move the child widgets: + int dx = X-x(); + int dy = Y-y(); + int dw = W-w(); + int dh = H-h(); + int *p = sizes(); + // resize this (skip the Fl_Group resize): + Fl_Widget::resize(X,Y,W,H); + // find bottom-right of resiable: + int OR = p[5]; + int NR = X+W-(p[1]-OR); + int OB = p[7]; + int NB = Y+H-(p[3]-OB); + // move everything to be on correct side of new resizable: + Fl_Widget*const* a = array(); + p += 8; + for (int i=children(); i--;) { + Fl_Widget* o = *a++; + int xx = o->x()+dx; + int R = xx+o->w(); + if (*p++ >= OR) xx += dw; else if (xx > NR) xx = NR; + if (*p++ >= OR) R += dw; else if (R > NR) R = NR; + int yy = o->y()+dy; + int B = yy+o->h(); + if (*p++ >= OB) yy += dh; else if (yy > NB) yy = NB; + if (*p++ >= OB) B += dh; else if (B > NB) B = NB; + o->resize(xx,yy,R-xx,B-yy); + // do *not* call o->redraw() here! If you do, and the tile is inside a + // scroll, it'll set the damage areas wrong for all children! + } +} + +static void set_cursor(Fl_Tile*t, Fl_Cursor c) { + static Fl_Cursor cursor; + if (cursor == c || !t->window()) return; + cursor = c; +#ifdef __sgi + t->window()->cursor(c,FL_RED,FL_WHITE); +#else + t->window()->cursor(c); +#endif +} + +static Fl_Cursor cursors[4] = { + FL_CURSOR_DEFAULT, + FL_CURSOR_WE, + FL_CURSOR_NS, + FL_CURSOR_MOVE}; + +int Fl_Tile::handle(int event) { + static int sdrag; + static int sdx, sdy; + static int sx, sy; +#define DRAGH 1 +#define DRAGV 2 +#define GRABAREA 4 + + int mx = Fl::event_x(); + int my = Fl::event_y(); + + switch (event) { + + case FL_MOVE: + case FL_ENTER: + case FL_PUSH: + // don't potentially change the mouse cursor if inactive: + if (!active()) break; // will cascade inherited handle() + { + int mindx = 100; + int mindy = 100; + int oldx = 0; + int oldy = 0; + Fl_Widget*const* a = array(); + int *q = sizes(); + int *p = q+8; + for (int i=children(); i--; p += 4) { + Fl_Widget* o = *a++; + if (o == resizable()) continue; + if (p[1]y()<=my+GRABAREA && o->y()+o->h()>=my-GRABAREA) { + int t = mx - (o->x()+o->w()); + if (abs(t) < mindx) { + sdx = t; + mindx = abs(t); + oldx = p[1]; + } + } + if (p[3]x()<=mx+GRABAREA && o->x()+o->w()>=mx-GRABAREA) { + int t = my - (o->y()+o->h()); + if (abs(t) < mindy) { + sdy = t; + mindy = abs(t); + oldy = p[3]; + } + } + } + sdrag = 0; sx = sy = 0; + if (mindx <= GRABAREA) {sdrag = DRAGH; sx = oldx;} + if (mindy <= GRABAREA) {sdrag |= DRAGV; sy = oldy;} + set_cursor(this, cursors[sdrag]); + if (sdrag) return 1; + return Fl_Group::handle(event); + } + + case FL_LEAVE: + set_cursor(this, FL_CURSOR_DEFAULT); + break; + + case FL_DRAG: + // This is necessary if CONSOLIDATE_MOTION in Fl_x.cxx is turned off: + // if (damage()) return 1; // don't fall behind + case FL_RELEASE: { + if (!sdrag) return 0; // should not happen + Fl_Widget* r = resizable(); if (!r) r = this; + int newx; + if (sdrag&DRAGH) { + newx = Fl::event_x()-sdx; + if (newx < r->x()) newx = r->x(); + else if (newx > r->x()+r->w()) newx = r->x()+r->w(); + } else + newx = sx; + int newy; + if (sdrag&DRAGV) { + newy = Fl::event_y()-sdy; + if (newy < r->y()) newy = r->y(); + else if (newy > r->y()+r->h()) newy = r->y()+r->h(); + } else + newy = sy; + position(sx,sy,newx,newy); + if (event == FL_DRAG) set_changed(); + do_callback(); + return 1;} + + } + + return Fl_Group::handle(event); +} + +// +// End of "$Id: Fl_Tile.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Tiled_Image.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Tiled_Image.cxx new file mode 100644 index 0000000..1857480 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Tiled_Image.cxx @@ -0,0 +1,135 @@ +// +// "$Id: Fl_Tiled_Image.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Tiled image code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + + +#include +#include +#include + +/** + The constructors create a new tiled image containing the specified image. + Use a width and height of 0 to tile the whole window/widget. +*/ +Fl_Tiled_Image::Fl_Tiled_Image(Fl_Image *i, // I - Image to tile + int W, // I - Width of tiled area + int H) : // I - Height of tiled area + Fl_Image(W,H,0) { + image_ = i; + alloc_image_ = 0; + + if (W == 0) w(Fl::w()); + if (H == 0) h(Fl::h()); +} +/** + The destructor frees all memory and server resources that are used by + the tiled image. +*/ + Fl_Tiled_Image::~Fl_Tiled_Image() { + if (alloc_image_) delete image_; +} + + +// +// 'Fl_Tiled_Image::copy()' - Copy and resize a tiled image... +// + +Fl_Image * // O - New image +Fl_Tiled_Image::copy(int W, // I - New width + int H) { // I - New height + if (W == w() && H == h()) return this; + else return new Fl_Tiled_Image(image_, W, H); +} + + +// +// 'Fl_Tiled_Image::color_average()' - Blend colors... +// + +void +Fl_Tiled_Image::color_average(Fl_Color c, // I - Color to blend with + float i) { // I - Blend fraction + if (!alloc_image_) { + image_ = image_->copy(); + alloc_image_ = 1; + } + + image_->color_average(c, i); +} + + +// +// 'Fl_Tiled_Image::desaturate()' - Convert the image to grayscale... +// + +void +Fl_Tiled_Image::desaturate() { + if (!alloc_image_) { + image_ = image_->copy(); + alloc_image_ = 1; + } + + image_->desaturate(); +} + + +// +// 'Fl_Tiled_Image::draw()' - Draw a shared image... +// + +void +Fl_Tiled_Image::draw(int X, // I - Starting X position + int Y, // I - Starting Y position + int W, // I - Width of area to be filled + int H, // I - Height of area to be filled + int cx, // I - "Source" X position + int cy) { // I - "Source" Y position + if (!image_->w() || !image_->h()) return; + if (W == 0) W = Fl::w(); + if (H == 0) H = Fl::h(); + + fl_push_clip(X, Y, W, H); + + X += cx; + Y += cy; + + X = X - (X % image_->w()); + Y = Y - (Y % image_->h()); + + W += X; + H += Y; + + for (int yy = Y; yy < H; yy += image_->h()) + for (int xx = X; xx < W; xx += image_->w()) + image_->draw(xx, yy); + + fl_pop_clip(); +} + + +// +// End of "$Id: Fl_Tiled_Image.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Tooltip.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Tooltip.cxx new file mode 100644 index 0000000..59d52f2 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Tooltip.cxx @@ -0,0 +1,282 @@ +// +// "$Id: Fl_Tooltip.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Tooltip source file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include + +#include + +float Fl_Tooltip::delay_ = 1.0f; +float Fl_Tooltip::hoverdelay_ = 0.2f; +int Fl_Tooltip::enabled_ = 1; +Fl_Color Fl_Tooltip::color_ = fl_color_cube(FL_NUM_RED - 1, + FL_NUM_GREEN - 1, + FL_NUM_BLUE - 2); +Fl_Color Fl_Tooltip::textcolor_ = FL_BLACK; +Fl_Font Fl_Tooltip::font_ = FL_HELVETICA; +Fl_Fontsize Fl_Tooltip::size_ = FL_NORMAL_SIZE; + +#define MAX_WIDTH 400 + +static const char* tip; +/** + This widget creates a tooltip box window, with no caption. +*/ +class Fl_TooltipBox : public Fl_Menu_Window { +public: + /** Creates the box window */ + Fl_TooltipBox() : Fl_Menu_Window(0, 0) { + set_override(); + set_tooltip_window(); + end(); + } + void draw(); + void layout(); + /** Shows the tooltip windows only if a tooltip text is available. */ + void show() { + if (tip) Fl_Menu_Window::show(); + } +}; + +Fl_Widget* Fl_Tooltip::widget_ = 0; +static Fl_TooltipBox *window = 0; +static int Y,H; + +void Fl_TooltipBox::layout() { + fl_font(Fl_Tooltip::font(), Fl_Tooltip::size()); + int ww, hh; + ww = MAX_WIDTH; + fl_measure(tip, ww, hh, FL_ALIGN_LEFT|FL_ALIGN_WRAP|FL_ALIGN_INSIDE); + ww += 6; hh += 6; + + // find position on the screen of the widget: + int ox = Fl::event_x_root(); + int oy = Y + H+2; + for (Fl_Widget* p = Fl_Tooltip::current(); p; p = p->window()) { + oy += p->y(); + } + int scr_x, scr_y, scr_w, scr_h; + Fl::screen_xywh(scr_x, scr_y, scr_w, scr_h); + if (ox+ww > scr_x+scr_w) ox = scr_x+scr_w - ww; + if (ox < scr_x) ox = scr_x; + if (H > 30) { + oy = Fl::event_y_root()+13; + if (oy+hh > scr_y+scr_h) oy -= 23+hh; + } else { + if (oy+hh > scr_y+scr_h) oy -= (4+hh+H); + } + if (oy < scr_y) oy = scr_y; + + resize(ox, oy, ww, hh); +} + +void Fl_TooltipBox::draw() { + draw_box(FL_BORDER_BOX, 0, 0, w(), h(), Fl_Tooltip::color()); + fl_color(Fl_Tooltip::textcolor()); + fl_font(Fl_Tooltip::font(), Fl_Tooltip::size()); + fl_draw(tip, 3, 3, w()-6, h()-6, Fl_Align(FL_ALIGN_LEFT|FL_ALIGN_WRAP)); +} + +static char recent_tooltip; + +static void recent_timeout(void*) { +#ifdef DEBUG + puts("recent_timeout();"); +#endif // DEBUG + + recent_tooltip = 0; +} + +static char recursion; + +static void tooltip_timeout(void*) { +#ifdef DEBUG + puts("tooltip_timeout();"); +#endif // DEBUG + + if (recursion) return; + recursion = 1; + if (!tip || !*tip) { + if (window) window->hide(); + } else { + //if (Fl::grab()) return; + if (!window) window = new Fl_TooltipBox; + // this cast bypasses the normal Fl_Window label() code: + ((Fl_Widget*)window)->label(tip); + window->layout(); + window->redraw(); +// printf("tooltip_timeout: Showing window %p with tooltip \"%s\"...\n", +// window, tip ? tip : "(null)"); + window->show(); + } + + Fl::remove_timeout(recent_timeout); + recent_tooltip = 1; + recursion = 0; +} + +/** + This method is called when the mouse pointer enters a widget. +

      If this widget or one of it's parents has a tooltip, enter it. This + will do nothing if this is the current widget (even if the mouse moved + out so an exit() was done and then moved back in). If no tooltip can + be found do Fl_Tooltip::exit_(). If you don't want this behavior (for instance + if you want the tooltip to reappear when the mouse moves back in) + call the fancier enter_area() below. +*/ +void Fl_Tooltip::enter_(Fl_Widget* w) { +#ifdef DEBUG + printf("Fl_Tooltip::enter_(w=%p)\n", w); + printf(" window=%p\n", window); +#endif // DEBUG + + // find the enclosing group with a tooltip: + Fl_Widget* tw = w; + for (;;) { + if (!tw) {exit_(0); return;} + if (tw == widget_) return; + if (tw->tooltip()) break; + tw = tw->parent(); + } + enter_area(w, 0, 0, w->w(), w->h(), tw->tooltip()); +} +/** + Sets the current widget target. + Acts as though enter(widget) was done but does not pop up a + tooltip. This is useful to prevent a tooltip from reappearing when + a modal overlapping window is deleted. FLTK does this automatically + when you click the mouse button. +*/ +void Fl_Tooltip::current(Fl_Widget* w) { +#ifdef DEBUG + printf("Fl_Tooltip::current(w=%p)\n", w); +#endif // DEBUG + + exit_(0); + // find the enclosing group with a tooltip: + Fl_Widget* tw = w; + for (;;) { + if (!tw) return; + if (tw->tooltip()) break; + tw = tw->parent(); + } + // act just like Fl_Tooltip::enter_() except we can remember a zero: + widget_ = w; +} + +// Hide any visible tooltip. +/** This method is called when the mouse pointer leaves a widget. */ +void Fl_Tooltip::exit_(Fl_Widget *w) { +#ifdef DEBUG + printf("Fl_Tooltip::exit_(w=%p)\n", w); + printf(" widget=%p, window=%p\n", widget_, window); +#endif // DEBUG + + if (!widget_ || (w && w == window)) return; + widget_ = 0; + Fl::remove_timeout(tooltip_timeout); + Fl::remove_timeout(recent_timeout); + if (window && window->visible()) window->hide(); + if (recent_tooltip) { + if (Fl::event_state() & FL_BUTTONS) recent_tooltip = 0; + else Fl::add_timeout(Fl_Tooltip::hoverdelay(), recent_timeout); + } +} + +// Get ready to display a tooltip. The widget and the xywh box inside +// it define an area the tooltip is for, this along with the current +// mouse position places the tooltip (the mouse is assumed to point +// inside or near the box). +/** + You may be able to use this to provide tooltips for internal pieces + of your widget. Call this after setting Fl::belowmouse() to + your widget (because that calls the above enter() method). Then figure + out what thing the mouse is pointing at, and call this with the widget + (this pointer is used to remove the tooltip if the widget is deleted + or hidden, and to locate the tooltip), the rectangle surrounding the + area, relative to the top-left corner of the widget (used to calculate + where to put the tooltip), and the text of the tooltip (which must be + a pointer to static data as it is not copied). +*/ +void Fl_Tooltip::enter_area(Fl_Widget* wid, int x,int y,int w,int h, const char* t) +{ + (void)x; + (void)w; + +#ifdef DEBUG + printf("Fl_Tooltip::enter_area(wid=%p, x=%d, y=%d, w=%d, h=%d, t=\"%s\")\n", + wid, x, y, w, h, t ? t : "(null)"); + printf(" recursion=%d, window=%p\n", recursion, window); +#endif // DEBUG + + if (recursion) return; + if (!t || !*t || !enabled()) { + exit_(0); + return; + } + // do nothing if it is the same: + if (wid==widget_ /*&& x==X && y==Y && w==W && h==H*/ && t==tip) return; + Fl::remove_timeout(tooltip_timeout); + Fl::remove_timeout(recent_timeout); + // remember it: + widget_ = wid; Y = y; H = h; tip = t; + // popup the tooltip immediately if it was recently up: + if (recent_tooltip) { + if (window) window->hide(); + Fl::add_timeout(Fl_Tooltip::hoverdelay(), tooltip_timeout); + } else if (Fl_Tooltip::delay() < .1) { +#ifdef WIN32 + // possible fix for the Windows titlebar, it seems to want the + // window to be destroyed, moving it messes up the parenting: + if (window && window->visible()) window->hide(); +#endif // WIN32 + tooltip_timeout(0); + } else { + if (window && window->visible()) window->hide(); + Fl::add_timeout(Fl_Tooltip::delay(), tooltip_timeout); + } + +#ifdef DEBUG + printf(" tip=\"%s\", window->shown()=%d\n", tip ? tip : "(null)", + window ? window->shown() : 0); +#endif // DEBUG +} + +void Fl_Widget::tooltip(const char *tt) { + static char beenhere = 0; + if (!beenhere) { + beenhere = 1; + Fl_Tooltip::enter = Fl_Tooltip::enter_; + Fl_Tooltip::exit = Fl_Tooltip::exit_; + } + tooltip_ = tt; +} + +// +// End of "$Id: Fl_Tooltip.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Tree.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Tree.cxx new file mode 100644 index 0000000..e303311 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Tree.cxx @@ -0,0 +1,919 @@ +// +// "$Id: Fl_Tree.cxx 7903 2010-11-28 21:06:39Z matt $" +// + +#include +#include +#include + +#include +#include + +////////////////////// +// Fl_Tree.cxx +////////////////////// +// +// Fl_Tree -- This file is part of the Fl_Tree widget for FLTK +// Copyright (C) 2009-2010 by Greg Ercolano. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// + +// INTERNAL: scroller callback +static void scroll_cb(Fl_Widget*,void *data) { + ((Fl_Tree*)data)->redraw(); +} + +// INTERNAL: Parse elements from path into an array of null terminated strings +// Path="/aa/bb" +// Return: arr[0]="aa", arr[1]="bb", arr[2]=0 +// Caller must call free_path(arr). +// +static char **parse_path(const char *path) { + while ( *path == '/' ) path++; // skip leading '/' + // First pass: identify, null terminate, and count separators + int seps = 1; // separator count (1: first item) + int arrsize = 1; // array size (1: first item) + char *save = strdup(path); // make copy we can modify + char *s = save; + while ( ( s = strchr(s, '/') ) ) { + while ( *s == '/' ) { *s++ = 0; seps++; } + if ( *s ) { arrsize++; } + } + arrsize++; // (room for terminating NULL) + // Second pass: create array, save nonblank elements + char **arr = (char**)malloc(sizeof(char*) * arrsize); + int t = 0; + s = save; + while ( seps-- > 0 ) { + if ( *s ) { arr[t++] = s; } // skips empty fields, eg. '//' + s += (strlen(s) + 1); + } + arr[t] = 0; + return(arr); +} + +// INTERNAL: Free the array returned by parse_path() +static void free_path(char **arr) { + if ( arr ) { + if ( arr[0] ) { free((void*)arr[0]); } + free((void*)arr); + } +} + +// INTERNAL: Recursively descend tree hierarchy, accumulating total child count +static int find_total_children(Fl_Tree_Item *item, int count=0) { + count++; + for ( int t=0; tchildren(); t++ ) { + count = find_total_children(item->child(t), count); + } + return(count); +} + +/// Constructor. +Fl_Tree::Fl_Tree(int X, int Y, int W, int H, const char *L) : Fl_Group(X,Y,W,H,L) { + _root = new Fl_Tree_Item(_prefs); + _root->parent(0); // we are root of tree + _root->label("ROOT"); + _item_focus = 0; + _callback_item = 0; + _callback_reason = FL_TREE_REASON_NONE; + _scrollbar_size = 0; // 0: uses Fl::scrollbar_size() + box(FL_DOWN_BOX); + color(FL_WHITE); + when(FL_WHEN_CHANGED); + _vscroll = new Fl_Scrollbar(0,0,0,0); // will be resized by draw() + _vscroll->hide(); + _vscroll->type(FL_VERTICAL); + _vscroll->step(1); + _vscroll->callback(scroll_cb, (void*)this); + end(); +} + +/// Destructor. +Fl_Tree::~Fl_Tree() { + if ( _root ) { delete _root; _root = 0; } +} + +/// Adds a new item, given a 'menu style' path, eg: "/Parent/Child/item". +/// Any parent nodes that don't already exist are created automatically. +/// Adds the item based on the value of sortorder(). +/// \returns the child item created, or 0 on error. +/// +Fl_Tree_Item* Fl_Tree::add(const char *path) { + if ( ! _root ) { // Create root if none + _root = new Fl_Tree_Item(_prefs); + _root->parent(0); + _root->label("ROOT"); + } + char **arr = parse_path(path); + Fl_Tree_Item *item = _root->add(_prefs, arr); + free_path(arr); + return(item); +} + +/// Inserts a new item above the specified Fl_Tree_Item, with the label set to 'name'. +/// \returns the item that was added, or 0 if 'above' could not be found. +/// +Fl_Tree_Item* Fl_Tree::insert_above(Fl_Tree_Item *above, const char *name) { + return(above->insert_above(_prefs, name)); +} + +/// Insert a new item into a tree-item's children at a specified position. +/// +/// \param[in] item The existing item to insert new child into +/// \param[in] name The label for the new item +/// \param[in] pos The position of the new item in the child list +/// +/// \returns the item that was added. +Fl_Tree_Item* Fl_Tree::insert(Fl_Tree_Item *item, const char *name, int pos) { + return(item->insert(_prefs, name, pos)); +} + +/// Add a new child to a tree-item. +/// +/// \param[in] item The existing item to add new child to +/// \param[in] name The label for the new item +/// +/// \returns the item that was added. +Fl_Tree_Item* Fl_Tree::add(Fl_Tree_Item *item, const char *name) { + return(item->add(_prefs, name)); +} + +/// Find the item, given a menu style path, eg: "/Parent/Child/item". +/// +/// There is both a const and non-const version of this method. +/// Const version allows pure const methods to use this method +/// to do lookups without causing compiler errors. +/// +/// \param[in] path -- the tree item's pathname to be found (eg. "Flintstones/Fred") +/// +/// \returns the item, or 0 if not found. +/// \see item_pathname() +/// +Fl_Tree_Item *Fl_Tree::find_item(const char *path) { + if ( ! _root ) return(0); + char **arr = parse_path(path); + Fl_Tree_Item *item = _root->find_item(arr); + free_path(arr); + return(item); +} + +/// A const version of Fl_Tree::find_item(const char *path) +const Fl_Tree_Item *Fl_Tree::find_item(const char *path) const { + if ( ! _root ) return(0); + char **arr = parse_path(path); + const Fl_Tree_Item *item = _root->find_item(arr); + free_path(arr); + return(item); +} + +// Handle safe 'reverse string concatenation'. +// In the following we build the pathname from right-to-left, +// since we start at the child and work our way up to the root. +// +#define SAFE_RCAT(c) { \ + slen += 1; if ( slen >= pathnamelen ) { pathname[0] = '\0'; return(-2); } \ + *s-- = c; \ + } + +/// Find the pathname for the specified \p item. +/// If \p item is NULL, root() is used. +/// The tree's root will be included in the pathname of showroot() is on. +/// \param[in] pathname The string to use to return the pathname +/// \param[in] pathnamelen The maximum length of the string (including NULL). Must not be zero. +/// \param[in] item The item whose pathname is to be returned. +/// \returns +/// - 0 : OK (\p pathname returns the item's pathname) +/// - -1 : item not found (pathname="") +/// - -2 : pathname not large enough (pathname="") +/// \see find_item() +/// +int Fl_Tree::item_pathname(char *pathname, int pathnamelen, const Fl_Tree_Item *item) const { + pathname[0] = '\0'; + item = item ? item : _root; + if ( !item ) return(-1); + // Build pathname starting at end + char *s = (pathname+pathnamelen-1); + int slen = 0; // length of string compiled so far (including NULL) + SAFE_RCAT('\0'); + while ( item ) { + if ( item->is_root() && showroot() == 0 ) break; // don't include root in path if showroot() off + // Find name of current item + const char *name = item->label() ? item->label() : "???"; // name for this item + int len = strlen(name); + // Add name to end of pathname[] + for ( --len; len>=0; len-- ) { SAFE_RCAT(name[len]); } // rcat name of item + SAFE_RCAT('/'); // rcat leading slash + item = item->parent(); // move up tree (NULL==root) + } + if ( *(++s) == '/' ) ++s; // leave off leading slash from pathname + if ( s != pathname ) memmove(pathname, s, slen); // Shift down right-aligned string + return(0); +} + +/// Standard FLTK draw() method, handles draws the tree widget. +void Fl_Tree::draw() { + // Let group draw box+label but *NOT* children. + // We handle drawing children ourselves by calling each item's draw() + // + // Handle group's bg + Fl_Group::draw_box(); + Fl_Group::draw_label(); + // Handle tree + if ( ! _root ) return; + int cx = x() + Fl::box_dx(box()); + int cy = y() + Fl::box_dy(box()); + int cw = w() - Fl::box_dw(box()); + int ch = h() - Fl::box_dh(box()); + // These values are changed during drawing + // 'Y' will be the lowest point on the tree + int X = cx + _prefs.marginleft(); + int Y = cy + _prefs.margintop() - (_vscroll->visible() ? _vscroll->value() : 0); + int W = cw - _prefs.marginleft(); // - _prefs.marginright(); + int Ysave = Y; + fl_push_clip(cx,cy,cw,ch); + { + fl_font(_prefs.labelfont(), _prefs.labelsize()); + _root->draw(X, Y, W, this, + (Fl::focus()==this)?_item_focus:0, // show focus item ONLY if Fl_Tree has focus + _prefs); + } + fl_pop_clip(); + + // Show vertical scrollbar? + int ydiff = (Y+_prefs.margintop())-Ysave; // ydiff=size of tree + int ytoofar = (cy+ch) - Y; // ytoofar -- scrolled beyond bottom (eg. stow) + + //printf("ydiff=%d ch=%d Ysave=%d ytoofar=%d value=%d\n", + //int(ydiff),int(ch),int(Ysave),int(ytoofar), int(_vscroll->value())); + + if ( ytoofar > 0 ) ydiff += ytoofar; + if ( Ysave ch || int(_vscroll->value()) > 1 ) { + _vscroll->visible(); + + int scrollsize = _scrollbar_size ? _scrollbar_size : Fl::scrollbar_size(); + int sx = x()+w()-Fl::box_dx(box())-scrollsize; + int sy = y()+Fl::box_dy(box()); + int sw = scrollsize; + int sh = h()-Fl::box_dh(box()); + _vscroll->show(); + _vscroll->range(0.0,ydiff-ch); + _vscroll->resize(sx,sy,sw,sh); + _vscroll->slider_size(float(ch)/float(ydiff)); + } else { + _vscroll->Fl_Slider::value(0); + _vscroll->hide(); + } + fl_push_clip(cx,cy,cw,ch); + Fl_Group::draw_children(); // draws any FLTK children set via Fl_Tree::widget() + fl_pop_clip(); +} + +/// Returns next visible item above (dir==Fl_Up) or below (dir==Fl_Down) the specified \p item. +/// If \p item is 0, returns first() if \p dir is Fl_Up, or last() if \p dir is FL_Down. +/// +/// \param[in] item The item above/below which we'll find the next visible item +/// \param[in] dir The direction to search. Can be FL_Up or FL_Down. +/// +/// \returns The item found, or 0 if there's no visible items above/below the specified \p item. +/// +Fl_Tree_Item *Fl_Tree::next_visible_item(Fl_Tree_Item *item, int dir) { + if ( ! item ) { // no start item? + item = ( dir == FL_Up ) ? last() : first(); // start at top or bottom + if ( ! item ) return(0); + if ( item->visible_r() ) return(item); // return first/last visible item + } + switch ( dir ) { + case FL_Up: return(item->prev_displayed(_prefs)); + case FL_Down: return(item->next_displayed(_prefs)); + default: return(item->next_displayed(_prefs)); + } +} + +/// Set the item that currently should have keyboard focus. +/// Handles calling redraw() to update the focus box (if its visible). +/// +/// \param[in] item The item that should take focus. If NULL, none will have focus. +/// +void Fl_Tree::set_item_focus(Fl_Tree_Item *item) { + if ( _item_focus != item ) { // changed? + _item_focus = item; // update + if ( visible_focus() ) redraw(); // redraw to update focus box + } +} + +/// Find the item that was clicked. +/// You should use callback_item() instead, which is fast, +/// and is meant to be used within a callback to determine the item clicked. +/// +/// This method walks the entire tree looking for the first item that is +/// under the mouse (ie. at Fl::event_x()/Fl:event_y(). +/// +/// Use this method /only/ if you've subclassed Fl_Tree, and are receiving +/// events before Fl_Tree has been able to process and update callback_item(). +/// +/// \returns the item clicked, or 0 if no item was under the current event. +/// +const Fl_Tree_Item* Fl_Tree::find_clicked() const { + if ( ! _root ) return(0); + return(_root->find_clicked(_prefs)); +} + +/// Set the item that was last clicked. +/// Should only be used by subclasses needing to change this value. +/// Normally Fl_Tree manages this value. +/// +/// Deprecated: use callback_item() instead. +/// +void Fl_Tree::item_clicked(Fl_Tree_Item* val) { + _callback_item = val; +} + +/// Returns the first item in the tree. +/// +/// Use this to walk the tree in the forward direction, eg: +/// \code +/// for ( Fl_Tree_Item *item = tree->first(); item; item = tree->next() ) { +/// printf("Item: %s\n", item->label()); +/// } +/// \endcode +/// +/// \returns first item in tree, or 0 if none (tree empty). +/// \see first(),next(),last(),prev() +/// +Fl_Tree_Item* Fl_Tree::first() { + return(_root); // first item always root +} + +/// Return the next item after \p item, or 0 if no more items. +/// +/// Use this code to walk the entire tree: +/// \code +/// for ( Fl_Tree_Item *item = tree->first(); item; item = tree->next(item) ) { +/// printf("Item: %s\n", item->label()); +/// } +/// \endcode +/// +/// \param[in] item The item to use to find the next item. If NULL, returns NULL +/// +/// \returns Next item in tree, or 0 if at last item. +/// +/// \see first(),next(),last(),prev() +/// +Fl_Tree_Item *Fl_Tree::next(Fl_Tree_Item *item) { + if ( ! item ) return(0); + return(item->next()); +} + +/// Return the previous item before \p item, or 0 if no more items. +/// +/// This can be used to walk the tree in reverse, eg: +/// +/// \code +/// for ( Fl_Tree_Item *item = tree->first(); item; item = tree->prev(item) ) { +/// printf("Item: %s\n", item->label()); +/// } +/// \endcode +/// +/// \param[in] item The item to use to find the previous item. If NULL, returns NULL +/// +/// \returns Previous item in tree, or 0 if at first item. +/// +/// \see first(),next(),last(),prev() +/// +Fl_Tree_Item *Fl_Tree::prev(Fl_Tree_Item *item) { + if ( ! item ) return(0); + return(item->prev()); +} + +/// Returns the last item in the tree. +/// +/// This can be used to walk the tree in reverse, eg: +/// +/// \code +/// for ( Fl_Tree_Item *item = tree->last(); item; item = tree->prev() ) { +/// printf("Item: %s\n", item->label()); +/// } +/// \endcode +/// +/// \returns last item in the tree, or 0 if none (tree empty). +/// +/// \see first(),next(),last(),prev() +/// +Fl_Tree_Item* Fl_Tree::last() { + if ( ! _root ) return(0); + Fl_Tree_Item *item = _root; + while ( item->has_children() ) { + item = item->child(item->children()-1); + } + return(item); +} + +/// Returns the first selected item in the tree. +/// +/// Use this to walk the tree looking for all the selected items, eg: +/// +/// \code +/// for ( Fl_Tree_Item *item = tree->first_selected_item(); item; item = tree->next_selected_item(item) ) { +/// printf("Item: %s\n", item->label()); +/// } +/// \endcode +/// +/// \returns The next selected item, or 0 if there are no more selected items. +/// +Fl_Tree_Item *Fl_Tree::first_selected_item() { + return(next_selected_item(0)); +} + +/// Returns the next selected item after \p item. +/// If \p item is 0, search starts at the first item (root). +/// +/// Use this to walk the tree looking for all the selected items, eg: +/// \code +/// for ( Fl_Tree_Item *item = tree->first_selected_item(); item; item = tree->next_selected_item(item) ) { +/// printf("Item: %s\n", item->label()); +/// } +/// \endcode +/// +/// \param[in] item The item to use to find the next selected item. If NULL, first() is used. +/// +/// \returns The next selected item, or 0 if there are no more selected items. +/// +Fl_Tree_Item *Fl_Tree::next_selected_item(Fl_Tree_Item *item) { + if ( ! item ) { + if ( ! (item = first()) ) return(0); + if ( item->is_selected() ) return(item); + } + while ( (item = item->next()) ) + if ( item->is_selected() ) + return(item); + return(0); +} + +/// Standard FLTK event handler for this widget. +int Fl_Tree::handle(int e) { + int ret = 0; + // Developer note: Fl_Browser_::handle() used for reference here.. + // #include // for event debugging + // fprintf(stderr, "DEBUG: %s (%d)\n", fl_eventnames[e], e); + if (e == FL_ENTER || e == FL_LEAVE) return(1); + switch (e) { + case FL_FOCUS: { + // FLTK tests if we want focus. + // If a nav key was used to give us focus, and we've got no saved + // focus widget, determine which item gets focus depending on nav key. + // + if ( ! _item_focus ) { // no focus established yet? + switch (Fl::event_key()) { // determine if focus was navigated.. + case FL_Tab: { // received focus via TAB? + if ( Fl::event_state(FL_SHIFT) ) { // SHIFT-TAB similar to FL_Up + set_item_focus(next_visible_item(0, FL_Up)); + } else { // TAB similar to FL_Down + set_item_focus(next_visible_item(0, FL_Down)); + } + break; + } + case FL_Left: // received focus via LEFT or UP? + case FL_Up: { // XK_ISO_Left_Tab + set_item_focus(next_visible_item(0, FL_Up)); + break; + } + case FL_Right: // received focus via RIGHT or DOWN? + case FL_Down: + default: { + set_item_focus(next_visible_item(0, FL_Down)); + break; + } + } + } + if ( visible_focus() ) redraw(); // draw focus change + return(1); + } + case FL_UNFOCUS: { // FLTK telling us some other widget took focus. + if ( visible_focus() ) redraw(); // draw focus change + return(1); + } + case FL_KEYBOARD: { // keyboard shortcut + // Do shortcuts first or scrollbar will get them... + if (_prefs.selectmode() > FL_TREE_SELECT_NONE ) { + if ( !_item_focus ) { + set_item_focus(first()); + } + if ( _item_focus ) { + int ekey = Fl::event_key(); + switch (ekey) { + case FL_Enter: // ENTER: selects current item only + case FL_KP_Enter: + if ( when() & ~FL_WHEN_ENTER_KEY) { + select_only(_item_focus); + show_item(_item_focus); // STR #2426 + return(1); + } + break; + case ' ': // toggle selection state + switch ( _prefs.selectmode() ) { + case FL_TREE_SELECT_NONE: + break; + case FL_TREE_SELECT_SINGLE: + if ( ! _item_focus->is_selected() ) // not selected? + select_only(_item_focus); // select only this + else + deselect_all(); // select nothing + break; + case FL_TREE_SELECT_MULTI: + select_toggle(_item_focus); + break; + } + break; + case FL_Right: // open children (if any) + case FL_Left: { // close children (if any) + if ( _item_focus ) { + if ( ekey == FL_Right && _item_focus->is_close() ) { + // Open closed item + open(_item_focus); + redraw(); + ret = 1; + } else if ( ekey == FL_Left && _item_focus->is_open() ) { + // Close open item + close(_item_focus); + redraw(); + ret = 1; + } + return(1); + } + break; + } + case FL_Up: // next item up + case FL_Down: { // next item down + set_item_focus(next_visible_item(_item_focus, ekey)); // next item up|dn + if ( _item_focus ) { // item in focus? + // Autoscroll + int itemtop = _item_focus->y(); + int itembot = _item_focus->y()+_item_focus->h(); + if ( itemtop < y() ) { show_item_top(_item_focus); } + if ( itembot > y()+h() ) { show_item_bottom(_item_focus); } + // Extend selection + if ( _prefs.selectmode() == FL_TREE_SELECT_MULTI && // multiselect on? + (Fl::event_state() & FL_SHIFT) && // shift key? + ! _item_focus->is_selected() ) { // not already selected? + select(_item_focus); // extend selection.. + } + return(1); + } + break; + } + } + } + } + break; + } + } + + // Let Fl_Group take a shot at handling the event + if (Fl_Group::handle(e)) { + return(1); // handled? don't continue below + } + + // Handle events the child FLTK widgets didn't need + + static Fl_Tree_Item *lastselect = 0; + // fprintf(stderr, "ERCODEBUG: Fl_Tree::handle(): Event was %s (%d)\n", fl_eventnames[e], e); // DEBUGGING + if ( ! _root ) return(ret); + switch ( e ) { + case FL_PUSH: { // clicked on a tree item? + if (Fl::visible_focus() && handle(FL_FOCUS)) { + Fl::focus(this); + } + lastselect = 0; + Fl_Tree_Item *o = _root->find_clicked(_prefs); + if ( ! o ) break; + set_item_focus(o); // becomes new focus widget + redraw(); + ret |= 1; // handled + if ( Fl::event_button() == FL_LEFT_MOUSE ) { + if ( o->event_on_collapse_icon(_prefs) ) { // collapse icon clicked? + open_toggle(o); + } else if ( o->event_on_label(_prefs) && // label clicked? + (!o->widget() || !Fl::event_inside(o->widget())) && // not inside widget + (!_vscroll->visible() || !Fl::event_inside(_vscroll)) ) { // not on scroller + switch ( _prefs.selectmode() ) { + case FL_TREE_SELECT_NONE: + break; + case FL_TREE_SELECT_SINGLE: + select_only(o); + break; + case FL_TREE_SELECT_MULTI: { + if ( Fl::event_state() & FL_SHIFT ) { // SHIFT+PUSH? + select(o); // add to selection + } else if ( Fl::event_state() & FL_CTRL ) { // CTRL+PUSH? + select_toggle(o); // toggle selection state + lastselect = o; // save toggled item (prevent oscillation) + } else { + select_only(o); + } + break; + } + } + } + } + break; + } + case FL_DRAG: { + // do the scrolling first: + int my = Fl::event_y(); + if ( my < y() ) { // above top? + int p = vposition()-(y()-my); + if ( p < 0 ) p = 0; + vposition(p); + } else if ( my > (y()+h()) ) { // below bottom? + int p = vposition()+(my-y()-h()); + if ( p > (int)_vscroll->maximum() ) p = (int)_vscroll->maximum(); + vposition(p); + } + if ( Fl::event_button() != FL_LEFT_MOUSE ) break; + Fl_Tree_Item *o = _root->find_clicked(_prefs); + if ( ! o ) break; + set_item_focus(o); // becomes new focus widget + redraw(); + ret |= 1; + // Item's label clicked? + if ( o->event_on_label(_prefs) && + (!o->widget() || !Fl::event_inside(o->widget())) && + (!_vscroll->visible() || !Fl::event_inside(_vscroll)) ) { + // Handle selection behavior + switch ( _prefs.selectmode() ) { + case FL_TREE_SELECT_NONE: break; // no selection changes + case FL_TREE_SELECT_SINGLE: + select_only(o); + break; + case FL_TREE_SELECT_MULTI: + if ( Fl::event_state() & FL_CTRL && // CTRL-DRAG: toggle? + lastselect != o ) { // not already toggled from last microdrag? + select_toggle(o); // toggle selection + lastselect = o; // save we toggled it (prevents oscillation) + } else { + select(o); // select this + } + break; + } + } + break; + } + } + return(ret); +} + +/// Deselect \p item and all its children. +/// If item is NULL, first() is used. +/// Handles calling redraw() if anything was changed. +/// Invokes the callback depending on the value of optional parameter \p docallback. +/// +/// The callback can use callback_item() and callback_reason() respectively to determine +/// the item changed and the reason the callback was called. +/// +/// \param[in] item The item that will be deselected (along with all its children) +/// \param[in] docallback -- A flag that determines if the callback() is invoked or not: +/// - 0 - the callback() is not invoked +/// - 1 - the callback() is invoked for each item that changed state, +/// callback_reason() will be FL_TREE_REASON_DESELECTED +/// +/// \returns count of how many items were actually changed to the deselected state. +/// +int Fl_Tree::deselect_all(Fl_Tree_Item *item, int docallback) { + item = item ? item : first(); // NULL? use first() + if ( ! item ) return(0); + int count = 0; + for ( ; item; item = next(item) ) { + if ( item->is_selected() ) + if ( deselect(item, docallback) ) + ++count; + } + return(count); +} + +/// Select \p item and all its children. +/// If item is NULL, first() is used. +/// Handles calling redraw() if anything was changed. +/// Invokes the callback depending on the value of optional parameter \p docallback. +/// +/// The callback can use callback_item() and callback_reason() respectively to determine +/// the item changed and the reason the callback was called. +/// +/// \param[in] item The item that will be selected (along with all its children). +/// If NULL, first() is assumed. +/// \param[in] docallback -- A flag that determines if the callback() is invoked or not: +/// - 0 - the callback() is not invoked +/// - 1 - the callback() is invoked for each item that changed state, +/// callback_reason() will be FL_TREE_REASON_SELECTED +/// +/// \returns count of how many items were actually changed to the selected state. +/// +int Fl_Tree::select_all(Fl_Tree_Item *item, int docallback) { + item = item ? item : first(); // NULL? use first() + if ( ! item ) return(0); + int count = 0; + for ( ; item; item = next(item) ) { + if ( !item->is_selected() ) + if ( select(item, docallback) ) + ++count; + } + return(count); +} + +/// Select only the specified \p item, deselecting all others that might be selected. +/// If item is 0, first() is used. +/// Handles calling redraw() if anything was changed. +/// Invokes the callback depending on the value of optional parameter \p docallback. +/// +/// The callback can use callback_item() and callback_reason() respectively to determine +/// the item changed and the reason the callback was called. +/// +/// \param[in] selitem The item to be selected. If NULL, first() is used. +/// \param[in] docallback -- A flag that determines if the callback() is invoked or not: +/// - 0 - the callback() is not invoked +/// - 1 - the callback() is invoked for each item that changed state, +/// callback_reason() will be either FL_TREE_REASON_SELECTED or +/// FL_TREE_REASON_DESELECTED +/// +/// \returns the number of items whose selection states were changed, if any. +/// +int Fl_Tree::select_only(Fl_Tree_Item *selitem, int docallback) { + selitem = selitem ? selitem : first(); // NULL? use first() + if ( ! selitem ) return(0); + int changed = 0; + for ( Fl_Tree_Item *item = first(); item; item = item->next() ) { + if ( item == selitem ) { + if ( item->is_selected() ) continue; // don't count if already selected + select(item, docallback); + ++changed; + } else { + if ( item->is_selected() ) { + deselect(item, docallback); + ++changed; + } + } + } + return(changed); +} + +/// Adjust the vertical scroll bar so that \p item is visible +/// \p yoff pixels from the top of the Fl_Tree widget's display. +/// +/// For instance, yoff=0 will position the item at the top. +/// +/// If yoff is larger than the vertical scrollbar's limit, +/// the value will be clipped. So if yoff=100, but scrollbar's max +/// is 50, then 50 will be used. +/// +/// \see show_item_top(), show_item_middle(), show_item_bottom() +/// +void Fl_Tree::show_item(Fl_Tree_Item *item, int yoff) { + if ( ! item ) return; + int newval = item->y() - y() - yoff + (int)_vscroll->value(); + if ( newval < _vscroll->minimum() ) newval = (int)_vscroll->minimum(); + if ( newval > _vscroll->maximum() ) newval = (int)_vscroll->maximum(); + _vscroll->value(newval); + redraw(); +} + +/// See if \p item is currently displayed on-screen (visible within the widget). +/// This can be used to detect if the item is scrolled off-screen. +/// Checks to see if the item's vertical position is within the top and bottom +/// edges of the display window. This does NOT take into account the hide()/show() +/// status of the item. +/// +int Fl_Tree::displayed(Fl_Tree_Item *item) { + return( (item->y() >= y() && item->y() <= (y()+h()-item->h())) ? 1 : 0); +} + +/// Adjust the vertical scroll bar to show \p item at the top +/// of the display IF it is currently off-screen (eg. show_item_top()). +/// If it is already on-screen, no change is made. +/// +/// \see show_item_top(), show_item_middle(), show_item_bottom() +/// +void Fl_Tree::show_item(Fl_Tree_Item *item) { + if ( displayed(item) ) return; + show_item_top(item); +} + +/// Adjust the vertical scrollbar so that \p item is at the top of the display. +void Fl_Tree::show_item_top(Fl_Tree_Item *item) { + item = item ? item : first(); + if ( ! item ) return; + show_item(item, 0); +} + +/// Adjust the vertical scrollbar so that \p item is in the middle of the display. +void Fl_Tree::show_item_middle(Fl_Tree_Item *item) { + item = item ? item : first(); + if ( ! item ) return; + show_item(item, h()/2 - item->h()/2); +} + +/// Adjust the vertical scrollbar so that \p item is at the bottom of the display. +void Fl_Tree::show_item_bottom(Fl_Tree_Item *item) { + item = item ? item : first(); + if ( ! item ) return; + show_item(item, h() - item->h()); +} + +/// Returns the vertical scroll position as a pixel offset. +/// The position returned is how many pixels of the tree are scrolled off the top edge +/// of the screen. Example: A position of '3' indicates the top 3 pixels of +/// the tree are scrolled off the top edge of the screen. +/// \see vposition(), hposition() +/// +int Fl_Tree::vposition() const { + return((int)_vscroll->value()); +} + +/// Sets the vertical scroll offset to position \p pos. +/// The position is how many pixels of the tree are scrolled off the top edge +/// of the screen. Example: A position of '3' scrolls the top three pixels of +/// the tree off the top edge of the screen. +/// \param[in] pos The vertical position (in pixels) to scroll the browser to. +/// +void Fl_Tree::vposition(int pos) { + if (pos < 0) pos = 0; + if (pos > _vscroll->maximum()) pos = (int)_vscroll->maximum(); + if (pos == _vscroll->value()) return; + _vscroll->value(pos); + redraw(); +} + +/// Displays \p item, scrolling the tree as necessary. +/// \param[in] item The item to be displayed. +/// +void Fl_Tree::display(Fl_Tree_Item *item) { + if ( ! item ) return; + show_item_middle(item); +} + +/** + * Read a preferences database into the tree widget. + * A preferences database is a hierarchical collection of data which can be + * directly loaded into the tree view for inspection. + * \param[in] prefs the Fl_Preferences database + */ +void Fl_Tree::load(Fl_Preferences &prefs) +{ + int i, j, n, pn = strlen(prefs.path()); + char *p; + const char *path = prefs.path(); + if (strcmp(path, ".")==0) + path += 1; // root path is empty + else + path += 2; // child path starts with "./" + n = prefs.groups(); + for (i=0; i +#include +#include +#include +#include +#include + +////////////////////// +// Fl_Tree_Item.cxx +////////////////////// +// +// Fl_Tree -- This file is part of the Fl_Tree widget for FLTK +// Copyright (C) 2009-2010 by Greg Ercolano. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// + +// Was the last event inside the specified xywh? +static int event_inside(const int xywh[4]) { + return(Fl::event_inside(xywh[0],xywh[1],xywh[2],xywh[3])); +} + +/// Constructor. +/// Makes a new instance of Fl_Tree_Item using defaults from 'prefs'. +/// +Fl_Tree_Item::Fl_Tree_Item(const Fl_Tree_Prefs &prefs) { + _label = 0; + _labelfont = prefs.labelfont(); + _labelsize = prefs.labelsize(); + _labelfgcolor = prefs.fgcolor(); + _labelbgcolor = prefs.bgcolor(); + _widget = 0; + _open = 1; + _visible = 1; + _active = 1; + _selected = 0; + _xywh[0] = 0; + _xywh[1] = 0; + _xywh[2] = 0; + _xywh[3] = 0; + _collapse_xywh[0] = 0; + _collapse_xywh[1] = 0; + _collapse_xywh[2] = 0; + _collapse_xywh[3] = 0; + _label_xywh[0] = 0; + _label_xywh[1] = 0; + _label_xywh[2] = 0; + _label_xywh[3] = 0; + _usericon = 0; + _userdata = 0; + _parent = 0; +} + +// DTOR +Fl_Tree_Item::~Fl_Tree_Item() { + if ( _label ) { + free((void*)_label); + _label = 0; + } + _widget = 0; // Fl_Group will handle destruction + _usericon = 0; // user handled allocation + //_children.clear(); // array's destructor handles itself +} + +/// Copy constructor. +Fl_Tree_Item::Fl_Tree_Item(const Fl_Tree_Item *o) { + _label = o->label() ? strdup(o->label()) : 0; + _labelfont = o->labelfont(); + _labelsize = o->labelsize(); + _labelfgcolor = o->labelfgcolor(); + _labelbgcolor = o->labelbgcolor(); + _widget = o->widget(); + _open = o->_open; + _visible = o->_visible; + _active = o->_active; + _selected = o->_selected; + _xywh[0] = o->_xywh[0]; + _xywh[1] = o->_xywh[1]; + _xywh[2] = o->_xywh[2]; + _xywh[3] = o->_xywh[3]; + _collapse_xywh[0] = o->_collapse_xywh[0]; + _collapse_xywh[1] = o->_collapse_xywh[1]; + _collapse_xywh[2] = o->_collapse_xywh[2]; + _collapse_xywh[3] = o->_collapse_xywh[3]; + _label_xywh[0] = o->_label_xywh[0]; + _label_xywh[1] = o->_label_xywh[1]; + _label_xywh[2] = o->_label_xywh[2]; + _label_xywh[3] = o->_label_xywh[3]; + _usericon = o->usericon(); + _userdata = o->user_data(); + _parent = o->_parent; +} + +/// Print the tree as 'ascii art' to stdout. +/// Used mainly for debugging. +/// +void Fl_Tree_Item::show_self(const char *indent) const { + if ( label() ) { + printf("%s-%s (%d children, this=%p, parent=%p depth=%d)\n", + indent,label(),children(),(void*)this, (void*)_parent, depth()); + } + if ( children() ) { + char *i2 = (char*)malloc(strlen(indent) + 2); + strcpy(i2, indent); + strcat(i2, " |"); + for ( int t=0; tshow_self(i2); + } + } + fflush(stdout); +} + +/// Set the label. Makes a copy of the name. +void Fl_Tree_Item::label(const char *name) { + if ( _label ) { free((void*)_label); _label = 0; } + _label = name ? strdup(name) : 0; +} + +/// Return the label. +const char *Fl_Tree_Item::label() const { + return(_label); +} + +/// Return child item for the specified 'index'. +const Fl_Tree_Item *Fl_Tree_Item::child(int index) const { + return(_children[index]); +} + +/// Clear all the children for this item. +void Fl_Tree_Item::clear_children() { + _children.clear(); +} + +/// Return the index of the immediate child of this item that has the label 'name'. +/// +/// \returns index of found item, or -1 if not found. +/// +int Fl_Tree_Item::find_child(const char *name) { + if ( name ) { + for ( int t=0; tlabel() ) { + if ( strcmp(child(t)->label(), name) == 0 ) { + return(t); + } + } + } + } + return(-1); +} + +/// Find child item by descending array of names. Does not include self in search. +/// Only Fl_Tree should need this method. +/// +/// \returns item, or 0 if not found +/// +const Fl_Tree_Item *Fl_Tree_Item::find_child_item(char **arr) const { + for ( int t=0; tlabel() ) { + if ( strcmp(child(t)->label(), *arr) == 0 ) { // match? + if ( *(arr+1) ) { // more in arr? descend + return(_children[t]->find_item(arr+1)); + } else { // end of arr? done + return(_children[t]); + } + } + } + } + return(0); +} + +/// Find child item by descending array of names. Does not include self in search. +/// Only Fl_Tree should need this method. Use Fl_Tree::find_item() instead. +/// +/// \returns item, or 0 if not found +/// +Fl_Tree_Item *Fl_Tree_Item::find_child_item(char **arr) { + for ( int t=0; tlabel() ) { + if ( strcmp(child(t)->label(), *arr) == 0 ) { // match? + if ( *(arr+1) ) { // more in arr? descend + return(_children[t]->find_item(arr+1)); + } else { // end of arr? done + return(_children[t]); + } + } + } + } + return(0); +} + +/// Find item by descending array of \p names. Includes self in search. +/// Only Fl_Tree should need this method. Use Fl_Tree::find_item() instead. +/// +/// \returns item, or 0 if not found +/// +const Fl_Tree_Item *Fl_Tree_Item::find_item(char **names) const { + if ( label() && strcmp(label(), *names) == 0 ) { // match self? + if ( *(names+1) == 0 ) { // end of names, + return(this); // found ourself. + } + } + if ( children() ) { // check children.. + return(find_child_item(names)); + } + return(0); +} + +/// Find item by descending array of \p names. Includes self in search. +/// Only Fl_Tree should need this method. +/// +/// \returns item, or 0 if not found +/// +Fl_Tree_Item *Fl_Tree_Item::find_item(char **names) { + if ( label() && strcmp(label(), *names) == 0 ) { // match self? + if ( *(names+1) == 0 ) { // end of names, + return(this); // found ourself. + } + } + if ( children() ) { // check children.. + return(find_child_item(names)); + } + return(0); +} + +/// Find the index number for the specified 'item' +/// in the current item's list of children. +/// +/// \returns the index, or -1 if not found. +/// +int Fl_Tree_Item::find_child(Fl_Tree_Item *item) { + for ( int t=0; tlabel(new_label); + item->_parent = this; + switch ( prefs.sortorder() ) { + case FL_TREE_SORT_NONE: { + _children.add(item); + return(item); + } + case FL_TREE_SORT_ASCENDING: { + for ( int t=0; t<_children.total(); t++ ) { + Fl_Tree_Item *c = _children[t]; + if ( c->label() && strcmp(c->label(), new_label) > 0 ) { + _children.insert(t, item); + return(item); + } + } + _children.add(item); + return(item); + } + case FL_TREE_SORT_DESCENDING: { + for ( int t=0; t<_children.total(); t++ ) { + Fl_Tree_Item *c = _children[t]; + if ( c->label() && strcmp(c->label(), new_label) < 0 ) { + _children.insert(t, item); + return(item); + } + } + _children.add(item); + return(item); + } + } + return(item); +} + +/// Descend into the path specified by \p arr, and add a new child there. +/// Should be used only by Fl_Tree's internals. +/// Adds the item based on the value of prefs.sortorder(). +/// \returns the item added. +/// +Fl_Tree_Item *Fl_Tree_Item::add(const Fl_Tree_Prefs &prefs, char **arr) { + int t = find_child(*arr); + Fl_Tree_Item *item; + if ( t == -1 ) { + item = (Fl_Tree_Item*)add(prefs, *arr); + } else { + item = (Fl_Tree_Item*)child(t); + } + if ( *(arr+1) ) { // descend? + return(item->add(prefs, arr+1)); + } else { + return(item); // end? done + } +} + +/// Insert a new item into current item's children at a specified position. +/// \returns the new item inserted. +/// +Fl_Tree_Item *Fl_Tree_Item::insert(const Fl_Tree_Prefs &prefs, const char *new_label, int pos) { + Fl_Tree_Item *item = new Fl_Tree_Item(prefs); + item->label(new_label); + item->_parent = this; + _children.insert(pos, item); + return(item); +} + +/// Insert a new item above this item. +/// \returns the new item inserted, or 0 if an error occurred. +/// +Fl_Tree_Item *Fl_Tree_Item::insert_above(const Fl_Tree_Prefs &prefs, const char *new_label) { + Fl_Tree_Item *p = _parent; + if ( ! p ) return(0); + // Walk our parent's children to find ourself + for ( int t=0; tchildren(); t++ ) { + Fl_Tree_Item *c = p->child(t); + if ( this == c ) { + return(p->insert(prefs, new_label, t)); + } + } + return(0); +} + +/// Remove child by item. +/// \returns 0 if removed, -1 if item not an immediate child. +/// +int Fl_Tree_Item::remove_child(Fl_Tree_Item *item) { + for ( int t=0; tclear_children(); + _children.remove(t); + return(0); + } + } + return(-1); +} + +/// Remove immediate child (and its children) by its label 'name'. +/// \returns 0 if removed, -1 if not found. +/// +int Fl_Tree_Item::remove_child(const char *name) { + for ( int t=0; tlabel() ) { + if ( strcmp(child(t)->label(), name) == 0 ) { + _children.remove(t); + return(0); + } + } + } + return(-1); +} + +/// Swap two of our children, given two child index values. +/// Use this eg. for sorting. +/// +/// This method is FAST, and does not involve lookups. +/// +/// No range checking is done on either index value. +/// +/// \returns +/// - 0 : OK +/// - -1 : failed: 'a' or 'b' is not our immediate child +/// +void Fl_Tree_Item::swap_children(int ax, int bx) { + _children.swap(ax, bx); +} + +/// Swap two of our children, given item pointers. +/// Use this eg. for sorting. +/// +/// This method is SLOW because it involves linear lookups. +/// For speed, use swap_children(int,int) instead. +/// +/// \returns +/// - 0 : OK +/// - -1 : failed: 'a' or 'b' is not our immediate child +/// +int Fl_Tree_Item::swap_children(Fl_Tree_Item *a, Fl_Tree_Item *b) { + int ax = -1, bx = -1; + for ( int t=0; tfind_clicked(prefs) ) != NULL) { // check child and its descendents + return(item); // found? + } + } + } + return(0); +} + +/// Non-const version of the above. +/// Find the item that the last event was over. +/// +/// Returns the item if its visible, and mouse is over it. +/// Works even if widget deactivated. +/// Use event_on_collapse_icon() to determine if collapse button was pressed. +/// +/// \returns the visible item under the event if found, or 0 if none. +/// +Fl_Tree_Item *Fl_Tree_Item::find_clicked(const Fl_Tree_Prefs &prefs) { + if ( ! _visible ) return(0); + if ( is_root() && !prefs.showroot() ) { + // skip event check if we're root but root not being shown + } else { + // See if event is over us + if ( event_inside(_xywh) ) { // event within this item? + return(this); // found + } + } + if ( is_open() ) { // open? check children of this item + for ( int t=0; tfind_clicked(prefs) ) != NULL ) { // check child and its descendents + return(item); // found? + } + } + } + return(0); +} + +static void draw_item_focus(Fl_Boxtype B, Fl_Color C, int X, int Y, int W, int H) { + if (!Fl::visible_focus()) return; + switch (B) { + case FL_DOWN_BOX: + case FL_DOWN_FRAME: + case FL_THIN_DOWN_BOX: + case FL_THIN_DOWN_FRAME: + X ++; + Y ++; + default: + break; + } + fl_color(fl_contrast(FL_BLACK, C)); + +#if defined(USE_X11) || defined(__APPLE_QUARTZ__) + fl_line_style(FL_DOT); + fl_rect(X + Fl::box_dx(B), Y + Fl::box_dy(B), + W - Fl::box_dw(B) - 1, H - Fl::box_dh(B) - 1); + fl_line_style(FL_SOLID); +#else + // Some platforms don't implement dotted line style, so draw + // every other pixel around the focus area... + // + // Also, QuickDraw (MacOS) does not support line styles specifically, + // and the hack we use in fl_line_style() will not draw horizontal lines + // on odd-numbered rows... + int i, xx, yy; + + X += Fl::box_dx(B); + Y += Fl::box_dy(B); + W -= Fl::box_dw(B) + 2; + H -= Fl::box_dh(B) + 2; + + for (xx = 0, i = 1; xx < W; xx ++, i ++) if (i & 1) fl_point(X + xx, Y); + for (yy = 0; yy < H; yy ++, i ++) if (i & 1) fl_point(X + W, Y + yy); + for (xx = W; xx > 0; xx --, i ++) if (i & 1) fl_point(X + xx, Y + H); + for (yy = H; yy > 0; yy --, i ++) if (i & 1) fl_point(X, Y + yy); +#endif +} + +/// Draw this item and its children. +void Fl_Tree_Item::draw(int X, int &Y, int W, Fl_Widget *tree, + Fl_Tree_Item *itemfocus, + const Fl_Tree_Prefs &prefs, int lastchild) { + if ( ! _visible ) return; + fl_font(_labelfont, _labelsize); + int H = _labelsize; + if(usericon() && H < usericon()->h()) H = usericon()->h(); + H += prefs.linespacing() + fl_descent(); + // adjust horizontally if we draw no connecting lines + if ( is_root() && prefs.connectorstyle() == FL_TREE_CONNECTOR_NONE ) { + X -= prefs.openicon()->w(); + W += prefs.openicon()->w(); + } + // Colors, fonts + Fl_Color fg = _selected ? prefs.bgcolor() : _labelfgcolor; + Fl_Color bg = _selected ? prefs.selectcolor() : _labelbgcolor; + if ( ! _active ) { + fg = fl_inactive(fg); + if ( _selected ) bg = fl_inactive(bg); + } + // Update the xywh of this item + _xywh[0] = X; + _xywh[1] = Y; + _xywh[2] = W; + _xywh[3] = H; + // Text size + int textw=0, texth=0; + fl_measure(_label, textw, texth, 0); + int textycenter = Y+(H/2); + int &icon_w = _collapse_xywh[2] = prefs.openicon()->w(); + int &icon_x = _collapse_xywh[0] = X + (icon_w + prefs.connectorwidth())/2 - 3; + int &icon_y = _collapse_xywh[1] = textycenter - (prefs.openicon()->h()/2); + _collapse_xywh[3] = prefs.openicon()->h(); + // Horizontal connector values + int hstartx = X+icon_w/2-1; + int hendx = hstartx + prefs.connectorwidth(); + int hcenterx = X + icon_w + ((hendx - (X + icon_w)) / 2); + + // See if we should draw this item + // If this item is root, and showroot() is disabled, don't draw. + // + char drawthis = ( is_root() && prefs.showroot() == 0 ) ? 0 : 1; + if ( drawthis ) { + // Draw connectors + if ( prefs.connectorstyle() != FL_TREE_CONNECTOR_NONE ) { + // Horiz connector between center of icon and text + // if this is root, the connector should not dangle in thin air on the left + if (is_root()) + draw_horizontal_connector(hcenterx, hendx, textycenter, prefs); + else + draw_horizontal_connector(hstartx, hendx, textycenter, prefs); + if ( has_children() && is_open() ) { + // Small vertical line down to children + draw_vertical_connector(hcenterx, textycenter, Y+H, prefs); + } + // Connectors for last child + if ( ! is_root() ) { + if ( lastchild ) { + draw_vertical_connector(hstartx, Y, textycenter, prefs); + } else { + draw_vertical_connector(hstartx, Y, Y+H, prefs); + } + } + } + // Draw collapse icon + if ( has_children() && prefs.showcollapse() ) { + // Draw icon image + if ( is_open() ) { + prefs.closeicon()->draw(icon_x,icon_y); + } else { + prefs.openicon()->draw(icon_x,icon_y); + } + } + // Background for this item + int cw1 = icon_w+prefs.connectorwidth()/2, cw2 = prefs.connectorwidth(); + int cwidth = cw1>cw2 ? cw1 : cw2; + int &bx = _label_xywh[0] = X+(icon_w/2-1+cwidth); + int &by = _label_xywh[1] = Y; + int &bw = _label_xywh[2] = W-(icon_w/2-1+cwidth); + int &bh = _label_xywh[3] = H; + // Draw bg only if different from tree's bg + if ( bg != tree->color() || is_selected() ) { + if ( is_selected() ) { + // Selected? Use selectbox() style + fl_draw_box(prefs.selectbox(), bx, by, bw, bh, bg); + } else { + // Not Selected? use plain filled rectangle + fl_color(bg); + fl_rectf(bx, by, bw, bh); + } + } + // Draw user icon (if any) + int useroff = (icon_w/2-1+cwidth); + if ( usericon() ) { + // Item has user icon? Use it + useroff += prefs.usericonmarginleft(); + icon_y = textycenter - (usericon()->h() >> 1); + usericon()->draw(X+useroff,icon_y); + useroff += usericon()->w(); + } else if ( prefs.usericon() ) { + // Prefs has user icon? Use it + useroff += prefs.usericonmarginleft(); + icon_y = textycenter - (prefs.usericon()->h() >> 1); + prefs.usericon()->draw(X+useroff,icon_y); + useroff += prefs.usericon()->w(); + } + useroff += prefs.labelmarginleft(); + // Draw label + if ( widget() ) { + // Widget? Draw it + int lx = X+useroff; + int ly = by; + int lw = widget()->w(); + int lh = bh; + if ( widget()->x() != lx || widget()->y() != ly || + widget()->w() != lw || widget()->h() != lh ) { + widget()->resize(lx, ly, lw, lh); // fltk will handle drawing this + } + } else { + // No label widget? Draw text label + if ( _label ) { + fl_color(fg); + fl_draw(_label, X+useroff, Y+H-fl_descent()-1); + } + } + if ( this == itemfocus && Fl::visible_focus() && Fl::focus() == tree) { + // Draw focus box around this item + draw_item_focus(FL_NO_BOX,bg,bx+1,by+1,bw-1,bh-1); + } + Y += H; + } // end drawthis + // Draw children + if ( has_children() && is_open() ) { + int child_x = drawthis ? // offset children to right, + (hcenterx - (icon_w/2) + 1) : X; // unless didn't drawthis + int child_w = W - (child_x-X); + int child_y_start = Y; + for ( int t=0; tdraw(child_x, Y, child_w, tree, itemfocus, prefs, lastchild); + } + if ( has_children() && is_open() ) { + Y += prefs.openchild_marginbottom(); // offset below open child tree + } + if ( ! lastchild ) { + draw_vertical_connector(hstartx, child_y_start, Y, prefs); + } + } +} + +/// Was the event on the 'collapse' button? +/// +int Fl_Tree_Item::event_on_collapse_icon(const Fl_Tree_Prefs &prefs) const { + if ( _visible && _active && has_children() && prefs.showcollapse() ) { + return(event_inside(_collapse_xywh) ? 1 : 0); + } else { + return(0); + } +} + +/// Was event on the label()? +/// +int Fl_Tree_Item::event_on_label(const Fl_Tree_Prefs &prefs) const { + if ( _visible && _active ) { + return(event_inside(_label_xywh) ? 1 : 0); + } else { + return(0); + } +} + +/// Internal: Show the FLTK widget() for this item and all children. +/// Used by open() to re-show widgets that were hidden by a previous close() +/// +void Fl_Tree_Item::show_widgets() { + if ( _widget ) _widget->show(); + if ( is_open() ) { + for ( int t=0; t<_children.total(); t++ ) { + _children[t]->show_widgets(); + } + } +} + +/// Internal: Hide the FLTK widget() for this item and all children. +/// Used by close() to hide widgets. +/// +void Fl_Tree_Item::hide_widgets() { + if ( _widget ) _widget->hide(); + for ( int t=0; t<_children.total(); t++ ) { + _children[t]->hide_widgets(); + } +} + +/// Open this item and all its children. +void Fl_Tree_Item::open() { + _open = 1; + // Tell children to show() their widgets + for ( int t=0; t<_children.total(); t++ ) { + _children[t]->show_widgets(); + } +} + +/// Close this item and all its children. +void Fl_Tree_Item::close() { + _open = 0; + // Tell children to hide() their widgets + for ( int t=0; t<_children.total(); t++ ) { + _children[t]->hide_widgets(); + } +} + +/// Returns how many levels deep this item is in the hierarchy. +/// +/// For instance; root has a depth of zero, and its immediate children +/// would have a depth of 1, and so on. +/// +int Fl_Tree_Item::depth() const { + int count = 0; + const Fl_Tree_Item *item = parent(); + while ( item ) { + ++count; + item = item->parent(); + } + return(count); +} + +/// Return the next item in the tree. +/// +/// This method can be used to walk the tree forward. +/// For an example of how to use this method, see Fl_Tree::first(). +/// +/// \returns the next item in the tree, or 0 if there's no more items. +/// +Fl_Tree_Item *Fl_Tree_Item::next() { + Fl_Tree_Item *p, *c = this; + if ( c->has_children() ) { + return(c->child(0)); + } + while ( ( p = c->parent() ) != NULL ) { // loop upwards through parents + int t = p->find_child(c); // find our position in parent's children[] array + if ( ++t < p->children() ) // not last child? + return(p->child(t)); // return next child + c = p; // child becomes parent to move up generation + } // loop: moves up to next parent + return(0); // hit root? done +} + +/// Return the previous item in the tree. +/// +/// This method can be used to walk the tree backwards. +/// For an example of how to use this method, see Fl_Tree::last(). +/// +/// \returns the previous item in the tree, or 0 if there's no item above this one (hit the root). +/// +Fl_Tree_Item *Fl_Tree_Item::prev() { + Fl_Tree_Item *p=parent(); // start with parent + if ( ! p ) return(0); // hit root? done + int t = p->find_child(this); // find our position in parent's children[] array + if ( --t == -1 ) { // are we first child? + return(p); // return immediate parent + } + p = p->child(t); // take parent's previous child + while ( p->has_children() ) { // has children? + p = p->child(p->children()-1); // take last child + } + return(p); +} + +/// Return this item's next sibling. +/// +/// Moves to the next item below us at the same level (sibling). +/// Use this to move down the tree without moving deeper into the tree, +/// effectively skipping over this item's children/descendents. +/// +/// \returns item's next sibling, or 0 if none. +/// +Fl_Tree_Item *Fl_Tree_Item::next_sibling() { + if ( !parent() ) return(0); // No parent (root)? We have no siblings + int index = parent()->find_child(this); // find our position in parent's child() array + if ( index == -1 ) return(0); // parent doesn't know us? weird + if ( (index+1) < parent()->children() ) // is there a next child? + return(parent()->child(index+1)); // return next child if there's one below us + return(0); // no siblings below us +} + +/// Return this item's previous sibling. +/// +/// Moves to the previous item above us at the same level (sibling). +/// Use this to move up the tree without moving deeper into the tree. +/// +/// \returns This item's previous sibling, or 0 if none. +/// +Fl_Tree_Item *Fl_Tree_Item::prev_sibling() { + if ( !parent() ) return(0); // No parent (root)? We have no siblings + int index = parent()->find_child(this); // find next position up in parent's child() array + if ( index == -1 ) return(0); // parent doesn't know us? weird + if ( index > 0 ) return(parent()->child(index-1)); // return previous child if there's one above us + return(0); // no siblings above us +} + +/// Return the next visible item. (If this item has children and is closed, children are skipped) +/// +/// This method can be used to walk the tree forward, skipping items +/// that are not currently visible to the user. +/// +/// \returns the next visible item below us, or 0 if there's no more items. +/// +Fl_Tree_Item *Fl_Tree_Item::next_displayed(Fl_Tree_Prefs &prefs) { + Fl_Tree_Item *c = this; + while ( c ) { + if ( c->is_root() && !prefs.showroot() ) { // on root and can't show it? + c = c->next(); // skip ahead, try again + continue; + } + if ( c->has_children() && c->is_close() ) { // item has children and: invisible or closed? + // Skip children, take next sibling. If none, try parent's sibling, repeat + while ( c ) { + Fl_Tree_Item *sib = c->next_sibling(); // get sibling + if ( sib ) { c = sib; break; } // Found? let outer loop test it + c = c->parent(); // No sibling? move up tree, try parent's sibling + } + } else { // has children and isn't closed, or no children + c = c->next(); // use normal 'next' + } + if ( !c ) return(0); // no more? done + // Check all parents to be sure none are closed. + // If closed, move up to that level and repeat until sure none are closed. + Fl_Tree_Item *p = c->parent(); + while (1) { + if ( !p || p->is_root() ) return(c); // hit top? then we're displayed, return c + if ( p->is_close() ) c = p; // found closed parent? make it current + p = p->parent(); // continue up tree + } + if ( c && c->visible() ) return(c); // item visible? return it + } + return(0); // hit end: no more items +} + +/// Return the previous visible item. (If this item above us has children and is closed, its children are skipped) +/// +/// This method can be used to walk the tree backward, +/// skipping items that are not currently visible to the user. +/// +/// \returns the previous visible item above us, or 0 if there's no more items. +/// +Fl_Tree_Item *Fl_Tree_Item::prev_displayed(Fl_Tree_Prefs &prefs) { + Fl_Tree_Item *c = this; + while ( c ) { + c = c->prev(); // previous item + if ( !c ) break; // no more items? done + if ( c->is_root() ) // root + return((prefs.showroot()&&c->visible()) ? c : 0); // return root if visible + if ( !c->visible() ) continue; // item not visible? skip + // Check all parents to be sure none are closed. + // If closed, move up to that level and repeat until sure none are closed. + Fl_Tree_Item *p = c->parent(); + while (1) { + if ( !p || p->is_root() ) return(c); // hit top? then we're displayed, return c + if ( p->is_close() ) c = p; // found closed parent? make it current + p = p->parent(); // continue up tree + } + } + return(0); // hit end: no more items +} + +/// Returns if item and all its parents are visible. +/// Also takes into consideration if any parent is close()ed. +/// \returns +/// 1 -- item and its parents are visible/open() +/// 0 -- item (or parents) invisible or close()ed. +/// +int Fl_Tree_Item::visible_r() const { + for (const Fl_Tree_Item *p=this; p; p=p->parent()) // move up through parents + if (!p->visible() || p->is_close()) return(0); // any parent not visible or closed? + return(1); +} + +// +// End of "$Id: Fl_Tree_Item.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Tree_Item_Array.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Tree_Item_Array.cxx new file mode 100644 index 0000000..13600bd --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Tree_Item_Array.cxx @@ -0,0 +1,157 @@ +// +// "$Id: Fl_Tree_Item_Array.cxx 7903 2010-11-28 21:06:39Z matt $" +// + +#include +#include +#include + +#include +#include + +////////////////////// +// Fl_Tree_Item_Array.cxx +////////////////////// +// +// Fl_Tree -- This file is part of the Fl_Tree widget for FLTK +// Copyright (C) 2009-2010 by Greg Ercolano. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// + +/// Constructor; creates an empty array. +/// +/// The optional 'chunksize' can be specified to optimize +/// memory allocation for potentially large arrays. Default chunksize is 10. +/// +Fl_Tree_Item_Array::Fl_Tree_Item_Array(int new_chunksize) { + _items = 0; + _total = 0; + _size = 0; + _chunksize = new_chunksize; +} + +/// Destructor. Calls each item's destructor, destroys internal _items array. +Fl_Tree_Item_Array::~Fl_Tree_Item_Array() { + clear(); +} + +/// Copy constructor. Makes new copy of array, with new instances of each item. +Fl_Tree_Item_Array::Fl_Tree_Item_Array(const Fl_Tree_Item_Array* o) { + _items = (Fl_Tree_Item**)malloc(o->_size * sizeof(Fl_Tree_Item*)); + _total = o->_total; + _size = o->_size; + _chunksize = o->_chunksize; + for ( int t=0; t_total; t++ ) { + _items[t] = new Fl_Tree_Item(o->_items[t]); + } +} + +/// Clear the entire array. +/// +/// Each item will be deleted (destructors will be called), +/// and the array will be cleared. total() will return 0. +/// +void Fl_Tree_Item_Array::clear() { + if ( _items ) { + for ( int t=0; t<_total; t++ ) { + delete _items[t]; + _items[t] = 0; + } + free((void*)_items); _items = 0; + } + _total = _size = 0; +} + +// Internal: Enlarge the items array. +// +// Adjusts size/items memory allocation as needed. +// Does NOT change total. +// +void Fl_Tree_Item_Array::enlarge(int count) { + int newtotal = _total + count; // new total + if ( newtotal >= _size ) { // more than we have allocated? + // Increase size of array + int newsize = _size + _chunksize; + Fl_Tree_Item **newitems = (Fl_Tree_Item**)malloc(newsize * sizeof(Fl_Tree_Item*)); + if ( _items ) { + // Copy old array -> new, delete old + memmove(newitems, _items, _size * sizeof(Fl_Tree_Item*)); + free((void*)_items); _items = 0; + } + // Adjust items/sizeitems + _items = newitems; + _size = newsize; + } +} + +/// Insert an item at index position \p pos. +/// +/// Handles enlarging array if needed, total increased by 1. +/// If \p pos == total(), an empty item is appended to the array. +/// +void Fl_Tree_Item_Array::insert(int pos, Fl_Tree_Item *new_item) { + enlarge(1); + // printf("*** POS=%d TOTAL-1=%d NITEMS=%d\n", pos, _total-1, (_total-pos)); + if ( pos <= (_total - 1) ) { // need to move memory around? + int nitems = _total - pos; + memmove(&_items[pos+1], &_items[pos], sizeof(Fl_Tree_Item*) * nitems); + } + _items[pos] = new_item; + _total++; +} + +/// Add an item* to the end of the array. +/// +/// Assumes the item was created with 'new', and will remain +/// allocated.. Fl_Tree_Item_Array will handle calling the +/// item's destructor when the array is cleared or the item remove()'ed. +/// +void Fl_Tree_Item_Array::add(Fl_Tree_Item *val) { + insert(_total, val); +} + +/// Remove the item at \param[in] index from the array. +/// +/// The item will be delete'd (if non-NULL), so its destructor will be called. +/// +void Fl_Tree_Item_Array::remove(int index) { + if ( _items[index] ) { // delete if non-zero + delete _items[index]; + } + _items[index] = 0; + for ( _total--; index<_total; index++ ) { + _items[index] = _items[index+1]; + } +} + +/// Remove the item from the array. +/// +/// \returns 0 if removed, or -1 if the item was not in the array. +/// +int Fl_Tree_Item_Array::remove(Fl_Tree_Item *item) { + for ( int t=0; t<_total; t++ ) { + if ( item == _items[t] ) { + remove(t); + return(0); + } + } + return(-1); +} + +// +// End of "$Id: Fl_Tree_Item_Array.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Tree_Prefs.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Tree_Prefs.cxx new file mode 100644 index 0000000..ef5c3ae --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Tree_Prefs.cxx @@ -0,0 +1,170 @@ +// +// "$Id: Fl_Tree_Prefs.cxx 7903 2010-11-28 21:06:39Z matt $" +// + +#include +#include +#include +#include + +////////////////////// +// Fl_Tree_Prefs.cxx +////////////////////// +// +// Fl_Tree -- This file is part of the Fl_Tree widget for FLTK +// Copyright (C) 2009-2010 by Greg Ercolano. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// + +// INTERNAL: BUILT IN OPEN/STOW XPMS +// These can be replaced via prefs.openicon()/closeicon() +// +static const char *L_open_xpm[] = { +#ifdef __APPLE__ + "11 11 2 1", + ". c None", + "@ c #000000", + "...@.......", + "...@@......", + "...@@@.....", + "...@@@@....", + "...@@@@@...", + "...@@@@@@..", + "...@@@@@...", + "...@@@@....", + "...@@@.....", + "...@@......", + "...@......." +#else + "11 11 3 1", + ". c #fefefe", + "# c #444444", + "@ c #000000", + "###########", + "#.........#", + "#.........#", + "#....@....#", + "#....@....#", + "#..@@@@@..#", + "#....@....#", + "#....@....#", + "#.........#", + "#.........#", + "###########" +#endif +}; +static Fl_Pixmap L_openpixmap(L_open_xpm); + +static const char *L_close_xpm[] = { +#ifdef __APPLE__ + "11 11 2 1", + ". c None", + "@ c #000000", + "...........", + "...........", + "...........", + "...........", + "...........", + "@@@@@@@@@@@", + ".@@@@@@@@@.", + "..@@@@@@@..", + "...@@@@@...", + "....@@@....", + ".....@....." +#else + "11 11 3 1", + ". c #fefefe", + "# c #444444", + "@ c #000000", + "###########", + "#.........#", + "#.........#", + "#.........#", + "#.........#", + "#..@@@@@..#", + "#.........#", + "#.........#", + "#.........#", + "#.........#", + "###########" +#endif +}; +static Fl_Pixmap L_closepixmap(L_close_xpm); + +/// Sets the default icon to be used as the 'open' icon +/// when items are add()ed to the tree. +/// This overrides the built in default '[+]' icon. +/// +/// \param[in] val -- The new image, or zero to use the default [+] icon. +/// +void Fl_Tree_Prefs::openicon(Fl_Image *val) { + _openimage = val ? val : &L_openpixmap; +} + +/// Sets the icon to be used as the 'close' icon. +/// This overrides the built in default '[-]' icon. +/// +/// \param[in] val -- The new image, or zero to use the default [-] icon. +/// +void Fl_Tree_Prefs::closeicon(Fl_Image *val) { + _closeimage = val ? val : &L_closepixmap; +} + +/// Fl_Tree_Prefs constructor +Fl_Tree_Prefs::Fl_Tree_Prefs() { + _labelfont = FL_HELVETICA; + _labelsize = FL_NORMAL_SIZE; + _marginleft = 6; + _margintop = 3; + //_marginright = 3; + //_marginbottom = 3; + _openchild_marginbottom = 0; + _usericonmarginleft = 3; + _labelmarginleft = 3; + _linespacing = 0; + _fgcolor = FL_BLACK; + _bgcolor = FL_WHITE; + _selectcolor = FL_DARK_BLUE; + _inactivecolor = FL_GRAY; + _connectorcolor = Fl_Color(43); +#ifdef __APPLE__ + _connectorstyle = FL_TREE_CONNECTOR_NONE; +#else + _connectorstyle = FL_TREE_CONNECTOR_DOTTED; +#endif + _openimage = &L_openpixmap; + _closeimage = &L_closepixmap; + _userimage = 0; + _showcollapse = 1; + _showroot = 1; + _connectorwidth = 17; + _sortorder = FL_TREE_SORT_NONE; + _selectbox = FL_FLAT_BOX; + _selectmode = FL_TREE_SELECT_SINGLE; + // Let fltk's current 'scheme' affect defaults + if ( Fl::scheme() ) { + if ( strcmp(Fl::scheme(), "gtk+") == 0 ) { + _selectbox = _FL_GTK_THIN_UP_BOX; + } else if ( strcmp(Fl::scheme(), "plastic") == 0 ) { + _selectbox = _FL_PLASTIC_THIN_UP_BOX; + } + } +} + +// +// End of "$Id: Fl_Tree_Prefs.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Valuator.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Valuator.cxx new file mode 100644 index 0000000..cfa4402 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Valuator.cxx @@ -0,0 +1,196 @@ +// +// "$Id: Fl_Valuator.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Valuator widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + + +// Base class for sliders and all other one-value "knobs" + +#include +#include +#include +#include +#include "flstring.h" + +Fl_Valuator::Fl_Valuator(int X, int Y, int W, int H, const char* L) +/** + Creates a new Fl_Valuator widget using the given position, + size, and label string. The default boxtype is FL_NO_BOX. +*/ +: Fl_Widget(X,Y,W,H,L) { + align(FL_ALIGN_BOTTOM); + when(FL_WHEN_CHANGED); + value_ = 0; + previous_value_ = 1; + min = 0; + max = 1; + A = 0.0; + B = 1; +} + +const double epsilon = 4.66e-10; + +/** See double Fl_Valuator::step() const */ +void Fl_Valuator::step(double s) { + if (s < 0) s = -s; + A = rint(s); + B = 1; + while (fabs(s-A/B) > epsilon && B<=(0x7fffffff/10)) {B *= 10; A = rint(s*B);} +} + +/** Sets the step value to 1/10digits.*/ +void Fl_Valuator::precision(int p) { + A = 1.0; + for (B = 1; p--;) B *= 10; +} +/** Asks for partial redraw */ +void Fl_Valuator::value_damage() {damage(FL_DAMAGE_EXPOSE);} // by default do partial-redraw + +/** + Sets the current value. The new value is not + clamped or otherwise changed before storing it. Use + clamp() or round() to modify the value before + calling value(). The widget is redrawn if the new value + is different than the current one. The initial value is zero. +

      changed() will return true if the user has moved the slider, + but it will be turned off by value(x) and just before doing a callback + (the callback can turn it back on if desired). +*/ +int Fl_Valuator::value(double v) { + clear_changed(); + if (v == value_) return 0; + value_ = v; + value_damage(); + return 1; +} +/** Clamps the value, but accepts v if the previous value is not already out of range */ +double Fl_Valuator::softclamp(double v) { + int which = (min<=max); + double p = previous_value_; + if ((vmax)==which && p!=max && (p>max)!=which) return max; + else return v; +} + +// inline void Fl_Valuator::handle_push() {previous_value_ = value_;} +/** Called during a drag operation, after an FL_WHEN_CHANGED event is received and before the callback. */ +void Fl_Valuator::handle_drag(double v) { + if (v != value_) { + value_ = v; + value_damage(); + set_changed(); + if (when() & FL_WHEN_CHANGED) do_callback(); + } +} +/** Called after an FL_WHEN_RELEASE event is received and before the callback. */ +void Fl_Valuator::handle_release() { + if (when()&FL_WHEN_RELEASE) { + // insure changed() is off even if no callback is done. It may have + // been turned on by the drag, and then the slider returned to it's + // initial position: + clear_changed(); + // now do the callback only if slider in new position or always is on: + if (value_ != previous_value_ || when() & FL_WHEN_NOT_CHANGED) { + do_callback(); + } + } +} + +/** + Round the passed value to the nearest step increment. Does + nothing if step is zero. +*/ +double Fl_Valuator::round(double v) { + if (A) return rint(v*B/A)*A/B; + else return v; +} + +/** Clamps the passed value to the valuator range.*/ +double Fl_Valuator::clamp(double v) { + if ((vmax)==(min<=max)) return max; + else return v; +} + +/** + Adds n times the step value to the passed value. If + step was set to zero it uses fabs(maximum() - minimum()) / + 100. +*/ +double Fl_Valuator::increment(double v, int n) { + if (!A) return v+n*(max-min)/100; + if (min > max) n = -n; + return (rint(v*B/A)+n)*A/B; +} + +/** + Uses internal rules to format the fields numerical value into + the character array pointed to by the passed parameter.

      + +

      The actual format used depends on the current step value. If + the step value has been set to zero then a %g format is used. + If the step value is non-zero, then a %.*f format is used, + where the precision is calculated to show sufficient digits + for the current step value. An integer step value, such as 1 + or 1.0, gives a precision of 0, so the formatted value will + appear as an integer.

      + +

      This method is used by the Fl_Value_... group of widgets to + format the current value into a text string. + The return value is the length of the formatted text. + The formatted value is written into in buffer. + buffer should have space for at least 128 bytes.

      + +

      You may override this function to create your own text formatting. +*/ +int Fl_Valuator::format(char* buffer) { + double v = value(); + // MRS: THIS IS A HACK - RECOMMEND ADDING BUFFER SIZE ARGUMENT + if (!A || !B) return snprintf(buffer, 128, "%g", v); + + // Figure out how many digits are required to correctly format the + // value. + int i, c = 0; + char temp[32]; + // output a number with many digits after the decimal point. This + // seems to be needed to get high precission + snprintf(temp, sizeof(temp), "%.12f", A/B); + // strip all trailing 0's + for (i=strlen(temp)-1; i>0; i--) { + if (temp[i]!='0') break; + } + // count digits until we find the decimal point (or comma or whatever + // letter is set in the current locale) + for (; i>0; i--, c++) { + if (!isdigit(temp[i])) break; + } + + // MRS: THIS IS A HACK - RECOMMEND ADDING BUFFER SIZE ARGUMENT + return snprintf(buffer, 128, "%.*f", c, v); +} + +// +// End of "$Id: Fl_Valuator.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Value_Input.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Value_Input.cxx new file mode 100644 index 0000000..f4817d8 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Value_Input.cxx @@ -0,0 +1,149 @@ +// +// "$Id: Fl_Value_Input.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Value input widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// FLTK widget for drag-adjusting a floating point value. +// Warning: this works by making a child Fl_Input object, even +// though this object is *not* an Fl_Group. May be a kludge? + +#include +#include +#include +#include +#include + + +void Fl_Value_Input::input_cb(Fl_Widget*, void* v) { + Fl_Value_Input& t = *(Fl_Value_Input*)v; + double nv; + if ((t.step() - floor(t.step()))>0.0 || t.step() == 0.0) nv = strtod(t.input.value(), 0); + else nv = strtol(t.input.value(), 0, 0); + if (nv != t.value() || t.when() & FL_WHEN_NOT_CHANGED) { + t.set_value(nv); + t.set_changed(); + if (t.when()) t.do_callback(); + } +} + +void Fl_Value_Input::draw() { + if (damage()&~FL_DAMAGE_CHILD) input.clear_damage(FL_DAMAGE_ALL); + input.box(box()); + input.color(color(), selection_color()); + Fl_Widget *i = &input; i->draw(); // calls protected input.draw() + input.clear_damage(); +} + +void Fl_Value_Input::resize(int X, int Y, int W, int H) { + Fl_Valuator::resize(X, Y, W, H); + input.resize(X, Y, W, H); +} + +void Fl_Value_Input::value_damage() { + char buf[128]; + format(buf); + input.value(buf); + input.mark(input.position()); // turn off selection highlight +} + +int Fl_Value_Input::handle(int event) { + double v; + int delta; + int mx = Fl::event_x_root(); + static int ix, drag; + input.when(when()); + switch (event) { + case FL_PUSH: + if (!step()) goto DEFAULT; + ix = mx; + drag = Fl::event_button(); + handle_push(); + return 1; + case FL_DRAG: + if (!step()) goto DEFAULT; + delta = mx-ix; + if (delta > 5) delta -= 5; + else if (delta < -5) delta += 5; + else delta = 0; + switch (drag) { + case 3: v = increment(previous_value(), delta*100); break; + case 2: v = increment(previous_value(), delta*10); break; + default:v = increment(previous_value(), delta); break; + } + v = round(v); + handle_drag(soft()?softclamp(v):clamp(v));; + return 1; + case FL_RELEASE: + if (!step()) goto DEFAULT; + if (value() != previous_value() || !Fl::event_is_click()) + handle_release(); + else { + Fl_Widget_Tracker wp(&input); + input.handle(FL_PUSH); + if (wp.exists()) + input.handle(FL_RELEASE); + } + return 1; + case FL_FOCUS: + return input.take_focus(); + case FL_SHORTCUT: + return input.handle(event); + default: + DEFAULT: + input.type(((step() - floor(step()))>0.0 || step() == 0.0) ? FL_FLOAT_INPUT : FL_INT_INPUT); + return input.handle(event); + } +} + +/** + Creates a new Fl_Value_Input widget using the given + position, size, and label string. The default boxtype is + FL_DOWN_BOX. +*/ +Fl_Value_Input::Fl_Value_Input(int X, int Y, int W, int H, const char* l) +: Fl_Valuator(X, Y, W, H, l), input(X, Y, W, H, 0) { + soft_ = 0; + if (input.parent()) // defeat automatic-add + input.parent()->remove(input); + input.parent((Fl_Group *)this); // kludge! + input.callback(input_cb, this); + input.when(FL_WHEN_CHANGED); + box(input.box()); + color(input.color()); + selection_color(input.selection_color()); + align(FL_ALIGN_LEFT); + value_damage(); + set_flag(SHORTCUT_LABEL); +} + +Fl_Value_Input::~Fl_Value_Input() { + + if (input.parent() == (Fl_Group *)this) + input.parent(0); // *revert* ctor kludge! +} + +// +// End of "$Id: Fl_Value_Input.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Value_Output.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Value_Output.cxx new file mode 100644 index 0000000..7dd3f45 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Value_Output.cxx @@ -0,0 +1,108 @@ +// +// "$Id: Fl_Value_Output.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Value output widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Fltk widget for drag-adjusting a floating point value. +// This is much lighter than Fl_Value_Input because it has no text editor +// If step() is zero then it can be used to display a floating-point value + +#include +#include +#include + +void Fl_Value_Output::draw() { + Fl_Boxtype b = box() ? box() : FL_DOWN_BOX; + int X = x()+Fl::box_dx(b); + int Y = y()+Fl::box_dy(b); + int W = w()-Fl::box_dw(b); + int H = h()-Fl::box_dh(b); + if (damage()&~FL_DAMAGE_CHILD) + draw_box(b, color()); + else { + fl_color(color()); + fl_rectf(X, Y, W, H); + } + char buf[128]; + format(buf); + fl_color(active_r() ? textcolor() : fl_inactive(textcolor())); + fl_font(textfont(), textsize()); + fl_draw(buf,X,Y,W,H,FL_ALIGN_LEFT); +} + +int Fl_Value_Output::handle(int event) { + if (!step()) return 0; + double v; + int delta; + int mx = Fl::event_x(); + static int ix, drag; + switch (event) { + case FL_PUSH: + ix = mx; + drag = Fl::event_button(); + handle_push(); + return 1; + case FL_DRAG: + delta = Fl::event_x()-ix; + if (delta > 5) delta -= 5; + else if (delta < -5) delta += 5; + else delta = 0; + switch (drag) { + case 3: v = increment(previous_value(),delta*100); break; + case 2: v = increment(previous_value(),delta*10); break; + default:v = increment(previous_value(),delta); break; + } + v = round(v); + handle_drag(soft()?softclamp(v):clamp(v));; + return 1; + case FL_RELEASE: + handle_release(); + return 1; + case FL_ENTER : + case FL_LEAVE : + return 1; + default: + return 0; + } +} + +/** + Creates a new Fl_Value_Output widget using the given + position, size, and label string. The default boxtype is FL_NO_BOX. +

      Inherited destructor destroys the Valuator. +*/ +Fl_Value_Output::Fl_Value_Output(int X, int Y, int W, int H,const char *l) +: Fl_Valuator(X,Y,W,H,l) { + box(FL_NO_BOX); + align(FL_ALIGN_LEFT); + textfont_ = FL_HELVETICA; + textsize_ = FL_NORMAL_SIZE; + textcolor_ = FL_FOREGROUND_COLOR; + soft_ = 0; +} + +// +// End of "$Id: Fl_Value_Output.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Value_Slider.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Value_Slider.cxx new file mode 100644 index 0000000..6c5ff22 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Value_Slider.cxx @@ -0,0 +1,86 @@ +// +// "$Id: Fl_Value_Slider.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Value slider widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include +#include + +/** + Creates a new Fl_Value_Slider widget using the given + position, size, and label string. The default boxtype is FL_DOWN_BOX. +*/ +Fl_Value_Slider::Fl_Value_Slider(int X, int Y, int W, int H, const char*l) +: Fl_Slider(X,Y,W,H,l) { + step(1,100); + textfont_ = FL_HELVETICA; + textsize_ = 10; + textcolor_ = FL_FOREGROUND_COLOR; +} + +void Fl_Value_Slider::draw() { + int sxx = x(), syy = y(), sww = w(), shh = h(); + int bxx = x(), byy = y(), bww = w(), bhh = h(); + if (horizontal()) { + bww = 35; sxx += 35; sww -= 35; + } else { + syy += 25; bhh = 25; shh -= 25; + } + if (damage()&FL_DAMAGE_ALL) draw_box(box(),sxx,syy,sww,shh,color()); + Fl_Slider::draw(sxx+Fl::box_dx(box()), + syy+Fl::box_dy(box()), + sww-Fl::box_dw(box()), + shh-Fl::box_dh(box())); + draw_box(box(),bxx,byy,bww,bhh,color()); + char buf[128]; + format(buf); + fl_font(textfont(), textsize()); + fl_color(active_r() ? textcolor() : fl_inactive(textcolor())); + fl_draw(buf, bxx, byy, bww, bhh, FL_ALIGN_CLIP); +} + +int Fl_Value_Slider::handle(int event) { + if (event == FL_PUSH && Fl::visible_focus()) { + Fl::focus(this); + redraw(); + } + int sxx = x(), syy = y(), sww = w(), shh = h(); + if (horizontal()) { + sxx += 35; sww -= 35; + } else { + syy += 25; shh -= 25; + } + return Fl_Slider::handle(event, + sxx+Fl::box_dx(box()), + syy+Fl::box_dy(box()), + sww-Fl::box_dw(box()), + shh-Fl::box_dh(box())); +} + +// +// End of "$Id: Fl_Value_Slider.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Widget.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Widget.cxx new file mode 100644 index 0000000..e519536 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Widget.cxx @@ -0,0 +1,344 @@ +// +// "$Id: Fl_Widget.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Base widget class for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include +#include +#include +#include +#include "flstring.h" + + +//////////////////////////////////////////////////////////////// +// for compatibility with Forms, all widgets without callbacks are +// inserted into a "queue" when they are activated, and the forms +// compatibility interaction functions (fl_do_events, etc.) will +// read one widget at a time from this queue and return it: + +const int QUEUE_SIZE = 20; + +static Fl_Widget *obj_queue[QUEUE_SIZE]; +static int obj_head, obj_tail; + +void Fl_Widget::default_callback(Fl_Widget *o, void * /*v*/) { +#if 0 + // This is necessary for strict forms compatibility but is confusing. + // Use the parent's callback if this widget does not have one. + for (Fl_Widget *p = o->parent(); p; p = p->parent()) + if (p->callback() != default_callback) { + p->do_callback(o,v); + return; + } +#endif + obj_queue[obj_head++] = o; + if (obj_head >= QUEUE_SIZE) obj_head = 0; + if (obj_head == obj_tail) { + obj_tail++; + if (obj_tail >= QUEUE_SIZE) obj_tail = 0; + } +} +/** + All Fl_Widgets that don't have a callback defined use a + default callback that puts a pointer to the widget in this queue, + and this method reads the oldest widget out of this queue. +*/ +Fl_Widget *Fl::readqueue() { + if (obj_tail==obj_head) return 0; + Fl_Widget *o = obj_queue[obj_tail++]; + if (obj_tail >= QUEUE_SIZE) obj_tail = 0; + return o; +} +/* + This static internal function removes all pending callbacks for a + specific widget from the default callback queue (Fl::readqueue()). + It is only called from Fl_Widget's destructor if the widget + doesn't have an own callback. + Note: There's no need to have this in the Fl:: namespace. +*/ +static void cleanup_readqueue(Fl_Widget *w) { + + if (obj_tail==obj_head) return; + + // Read the entire queue and copy over all valid entries. + // The new head will be determined after the last copied entry. + + int old_head = obj_head; // save newest entry + int entry = obj_tail; // oldest entry + obj_head = obj_tail; // new queue start + for (;;) { + Fl_Widget *o = obj_queue[entry++]; + if (entry >= QUEUE_SIZE) entry = 0; + if (o != w) { // valid entry + obj_queue[obj_head++] = o; + if (obj_head >= QUEUE_SIZE) obj_head = 0; + } // valid entry + if (entry == old_head) break; + } + return; +} +//////////////////////////////////////////////////////////////// + +int Fl_Widget::handle(int) { + return 0; +} + +/** Default font size for widgets */ +Fl_Fontsize FL_NORMAL_SIZE = 14; + +Fl_Widget::Fl_Widget(int X, int Y, int W, int H, const char* L) { + + x_ = X; y_ = Y; w_ = W; h_ = H; + + label_.value = L; + label_.image = 0; + label_.deimage = 0; + label_.type = FL_NORMAL_LABEL; + label_.font = FL_HELVETICA; + label_.size = FL_NORMAL_SIZE; + label_.color = FL_FOREGROUND_COLOR; + label_.align_ = FL_ALIGN_CENTER; + tooltip_ = 0; + callback_ = default_callback; + user_data_ = 0; + type_ = 0; + flags_ = VISIBLE_FOCUS; + damage_ = 0; + box_ = FL_NO_BOX; + color_ = FL_GRAY; + color2_ = FL_GRAY; + when_ = FL_WHEN_RELEASE; + + parent_ = 0; + if (Fl_Group::current()) Fl_Group::current()->add(this); +} + +void Fl_Widget::resize(int X, int Y, int W, int H) { + x_ = X; y_ = Y; w_ = W; h_ = H; +} + +// this is useful for parent widgets to call to resize children: +int Fl_Widget::damage_resize(int X, int Y, int W, int H) { + if (x() == X && y() == Y && w() == W && h() == H) return 0; + resize(X, Y, W, H); + redraw(); + return 1; +} + +int Fl_Widget::take_focus() { + if (!takesevents()) return 0; + if (!visible_focus()) return 0; + if (!handle(FL_FOCUS)) return 0; // see if it wants it + if (contains(Fl::focus())) return 1; // it called Fl::focus for us + Fl::focus(this); + return 1; +} + +extern void fl_throw_focus(Fl_Widget*); // in Fl_x.cxx + +/** + Destroys the widget, taking care of throwing focus before if any. + Destruction removes the widget from any parent group! And groups when + destroyed destroy all their children. This is convenient and fast. +*/ +Fl_Widget::~Fl_Widget() { + Fl::clear_widget_pointer(this); + if (flags() & COPIED_LABEL) free((void *)(label_.value)); + // remove from parent group + if (parent_) parent_->remove(this); +#ifdef DEBUG_DELETE + if (parent_) { // this should never happen + printf("*** Fl_Widget: parent_->remove(this) failed [%p,%p]\n",parent_,this); + } +#endif // DEBUG_DELETE + parent_ = 0; // Don't throw focus to a parent widget. + fl_throw_focus(this); + // remove stale entries from default callback queue (Fl::readqueue()) + if (callback_ == default_callback) cleanup_readqueue(this); +} + +/** Draws a focus box for the widget at the given position and size */ +void +Fl_Widget::draw_focus(Fl_Boxtype B, int X, int Y, int W, int H) const { + if (!Fl::visible_focus()) return; + switch (B) { + case FL_DOWN_BOX: + case FL_DOWN_FRAME: + case FL_THIN_DOWN_BOX: + case FL_THIN_DOWN_FRAME: + X ++; + Y ++; + default: + break; + } + + fl_color(fl_contrast(FL_BLACK, color())); + +#if defined(USE_X11) || defined(__APPLE_QUARTZ__) + fl_line_style(FL_DOT); + fl_rect(X + Fl::box_dx(B), Y + Fl::box_dy(B), + W - Fl::box_dw(B) - 1, H - Fl::box_dh(B) - 1); + fl_line_style(FL_SOLID); +#elif defined(WIN32) + // Windows 95/98/ME do not implement the dotted line style, so draw + // every other pixel around the focus area... + // + // Also, QuickDraw (MacOS) does not support line styles specifically, + // and the hack we use in fl_line_style() will not draw horizontal lines + // on odd-numbered rows... + int i, xx, yy; + + X += Fl::box_dx(B); + Y += Fl::box_dy(B); + W -= Fl::box_dw(B) + 2; + H -= Fl::box_dh(B) + 2; + + for (xx = 0, i = 1; xx < W; xx ++, i ++) if (i & 1) fl_point(X + xx, Y); + for (yy = 0; yy < H; yy ++, i ++) if (i & 1) fl_point(X + W, Y + yy); + for (xx = W; xx > 0; xx --, i ++) if (i & 1) fl_point(X + xx, Y + H); + for (yy = H; yy > 0; yy --, i ++) if (i & 1) fl_point(X, Y + yy); +#else +# error unsupported platform +#endif // WIN32 +} + + +void Fl_Widget::activate() { + if (!active()) { + clear_flag(INACTIVE); + if (active_r()) { + redraw(); + redraw_label(); + handle(FL_ACTIVATE); + if (inside(Fl::focus())) Fl::focus()->take_focus(); + } + } +} + +void Fl_Widget::deactivate() { + if (active_r()) { + set_flag(INACTIVE); + redraw(); + redraw_label(); + handle(FL_DEACTIVATE); + fl_throw_focus(this); + } else { + set_flag(INACTIVE); + } +} + +int Fl_Widget::active_r() const { + for (const Fl_Widget* o = this; o; o = o->parent()) + if (!o->active()) return 0; + return 1; +} + +void Fl_Widget::show() { + if (!visible()) { + clear_flag(INVISIBLE); + if (visible_r()) { + redraw(); + redraw_label(); + handle(FL_SHOW); + if (inside(Fl::focus())) Fl::focus()->take_focus(); + } + } +} + +void Fl_Widget::hide() { + if (visible_r()) { + set_flag(INVISIBLE); + for (Fl_Widget *p = parent(); p; p = p->parent()) + if (p->box() || !p->parent()) {p->redraw(); break;} + handle(FL_HIDE); + fl_throw_focus(this); + } else { + set_flag(INVISIBLE); + } +} + +int Fl_Widget::visible_r() const { + for (const Fl_Widget* o = this; o; o = o->parent()) + if (!o->visible()) return 0; + return 1; +} + +// return true if widget is inside (or equal to) this: +// Returns false for null widgets. +int Fl_Widget::contains(const Fl_Widget *o) const { + for (; o; o = o->parent_) if (o == this) return 1; + return 0; +} + + +void +Fl_Widget::label(const char *a) { + if (flags() & COPIED_LABEL) { + // reassigning a copied label remains the same copied label + if (label_.value == a) + return; + free((void *)(label_.value)); + clear_flag(COPIED_LABEL); + } + label_.value=a; + redraw_label(); +} + + +void +Fl_Widget::copy_label(const char *a) { + if (flags() & COPIED_LABEL) free((void *)(label_.value)); + if (a) { + set_flag(COPIED_LABEL); + label_.value=strdup(a); + } else { + clear_flag(COPIED_LABEL); + label_.value=(char *)0; + } + redraw_label(); +} + +/** Calls the widget callback. + + Causes a widget to invoke its callback function with arbitrary arguments. + + \param[in] o call the callback with \p o as the widget argument + \param[in] arg use \p arg as the user data argument + \see callback() +*/ +void +Fl_Widget::do_callback(Fl_Widget* o,void* arg) { + Fl_Widget_Tracker wp(this); + callback_(o,arg); + if (wp.deleted()) return; + if (callback_ != default_callback) + clear_changed(); +} + +// +// End of "$Id: Fl_Widget.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Window.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Window.cxx new file mode 100644 index 0000000..e4d8108 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Window.cxx @@ -0,0 +1,283 @@ +// +// "$Id: Fl_Window.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Window widget class for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// The Fl_Window is a window in the fltk library. +// This is the system-independent portions. The huge amount of +// crap you need to do to communicate with X is in Fl_x.cxx, the +// equivalent (but totally different) crap for MSWindows is in Fl_win32.cxx +#include "config.h" +#include +#include +#include +#include +#include "flstring.h" + +#ifdef __APPLE_QUARTZ__ +#include +#endif + +char *Fl_Window::default_xclass_ = 0L; + +void Fl_Window::_Fl_Window() { + type(FL_WINDOW); + box(FL_FLAT_BOX); + if (Fl::scheme_bg_) { + labeltype(FL_NORMAL_LABEL); + align(FL_ALIGN_CENTER | FL_ALIGN_INSIDE | FL_ALIGN_CLIP); + image(Fl::scheme_bg_); + } else { + labeltype(FL_NO_LABEL); + } + i = 0; + xclass_ = 0; + icon_ = 0; + iconlabel_ = 0; + resizable(0); + size_range_set = 0; + minw = maxw = minh = maxh = 0; + callback((Fl_Callback*)default_callback); +} + +Fl_Window::Fl_Window(int X,int Y,int W, int H, const char *l) +: Fl_Group(X, Y, W, H, l) { + cursor_default = FL_CURSOR_DEFAULT; + cursor_fg = FL_BLACK; + cursor_bg = FL_WHITE; + + _Fl_Window(); + set_flag(FORCE_POSITION); +} + +Fl_Window::Fl_Window(int W, int H, const char *l) +// fix common user error of a missing end() with current(0): + : Fl_Group((Fl_Group::current(0),0), 0, W, H, l) { + cursor_default = FL_CURSOR_DEFAULT; + cursor_fg = FL_BLACK; + cursor_bg = FL_WHITE; + + _Fl_Window(); + clear_visible(); +} + +Fl_Window *Fl_Widget::window() const { + for (Fl_Widget *o = parent(); o; o = o->parent()) + if (o->type() >= FL_WINDOW) return (Fl_Window*)o; + return 0; +} +/** Gets the x position of the window on the screen */ +int Fl_Window::x_root() const { + Fl_Window *p = window(); + if (p) return p->x_root() + x(); + return x(); +} +/** Gets the y position of the window on the screen */ +int Fl_Window::y_root() const { + Fl_Window *p = window(); + if (p) return p->y_root() + y(); + return y(); +} + +void Fl_Window::draw() { + + // The following is similar to Fl_Group::draw(), but ... + // - we draw the box with x=0 and y=0 instead of x() and y() + // - we don't draw a label + + if (damage() & ~FL_DAMAGE_CHILD) { // draw the entire thing + draw_box(box(),0,0,w(),h(),color()); // draw box with x/y = 0 + } + draw_children(); + +#ifdef __APPLE_QUARTZ__ + // on OS X, windows have no frame. To resize a window, we drag the lower right + // corner. This code draws a little ribbed triangle for dragging. + extern CGContextRef fl_gc; + if (fl_gc && !parent() && resizable() && (!size_range_set || minh!=maxh || minw!=maxw)) { + int dx = Fl::box_dw(box())-Fl::box_dx(box()); + int dy = Fl::box_dh(box())-Fl::box_dy(box()); + if (dx<=0) dx = 1; + if (dy<=0) dy = 1; + int x1 = w()-dx-1, x2 = x1, y1 = h()-dx-1, y2 = y1; + Fl_Color c[4] = { + color(), + fl_color_average(color(), FL_WHITE, 0.7f), + fl_color_average(color(), FL_BLACK, 0.6f), + fl_color_average(color(), FL_BLACK, 0.8f), + }; + int i; + for (i=dx; i<12; i++) { + fl_color(c[i&3]); + fl_line(x1--, y1, x2, y2--); + } + } +#endif + +# if defined(USE_CAIRO) + Fl::cairo_make_current(this); // checkout if an update is necessary +# endif +} + +void Fl_Window::label(const char *name) { + label(name, iconlabel()); +} + +void Fl_Window::copy_label(const char *a) { + if (flags() & COPIED_LABEL) { + free((void *)label()); + clear_flag(COPIED_LABEL); + } + if (a) a = strdup(a); + label(a, iconlabel()); + set_flag(COPIED_LABEL); +} + + +void Fl_Window::iconlabel(const char *iname) { + label(label(), iname); +} + +// the Fl::atclose pointer is provided for back compatibility. You +// can now just change the callback for the window instead. + +/** Default callback for window widgets. It hides the window and then calls the default widget callback. */ +void Fl::default_atclose(Fl_Window* window, void* v) { + window->hide(); + Fl_Widget::default_callback(window, v); // put on Fl::read_queue() +} +/** Back compatibility: default window callback handler \see Fl::set_atclose() */ +void (*Fl::atclose)(Fl_Window*, void*) = default_atclose; +/** Back compatibility: Sets the default callback v for win to call on close event */ +void Fl_Window::default_callback(Fl_Window* win, void* v) { + Fl::atclose(win, v); +} + +/** Returns the last window that was made current. \see Fl_Window::make_current() */ +Fl_Window *Fl_Window::current() { + return current_; +} + +/** Returns the default xclass. + + \see Fl_Window::default_xclass(const char *) + + */ +const char *Fl_Window::default_xclass() +{ + if (default_xclass_) { + return default_xclass_; + } else { + return "FLTK"; + } +} + +/** Sets the default window xclass. + + The default xclass is used for all windows that don't have their + own xclass set before show() is called. You can change the default + xclass whenever you want, but this only affects windows that are + created (and shown) after this call. + + The given string \p xc is copied. You can use a local variable or + free the string immediately after this call. + + If you don't call this, the default xclass for all windows will be "FLTK". + You can reset the default xclass by specifying NULL for \p xc. + + If you call Fl_Window::xclass(const char *) for any window, then + this also sets the default xclass, unless it has been set before. + + \param[in] xc default xclass for all windows subsequently created + + \see Fl_Window::xclass(const char *) +*/ +void Fl_Window::default_xclass(const char *xc) +{ + if (default_xclass_) { + free(default_xclass_); + default_xclass_ = 0L; + } + if (xc) { + default_xclass_ = strdup(xc); + } +} + +/** Sets the xclass for this window. + + A string used to tell the system what type of window this is. Mostly + this identifies the picture to draw in the icon. This only works if + called \e before calling show(). + + Under X, this is turned into a XA_WM_CLASS pair by truncating at + the first non-alphanumeric character and capitalizing the first character, + and the second one if the first is 'x'. Thus "foo" turns into "foo, Foo", + and "xprog.1" turns into "xprog, XProg". + + Under Microsoft Windows, this string is used as the name of the + WNDCLASS structure, though it is not clear if this can have any + visible effect. + + \since FLTK 1.3 the passed string is copied. You can use a local + variable or free the string immediately after this call. Note that + FLTK 1.1 stores the \e pointer without copying the string. + + If the default xclass has not yet been set, this also sets the + default xclass for all windows created subsequently. + + \see Fl_Window::default_xclass(const char *) +*/ +void Fl_Window::xclass(const char *xc) +{ + if (xclass_) { + free(xclass_); + xclass_ = 0L; + } + if (xc) { + xclass_ = strdup(xc); + if (!default_xclass_) { + default_xclass(xc); + } + } +} + +/** Returns the xclass for this window, or a default. + + \see Fl_Window::default_xclass(const char *) + \see Fl_Window::xclass(const char *) +*/ +const char *Fl_Window::xclass() const +{ + if (xclass_) { + return xclass_; + } else { + return default_xclass(); + } +} + + +// +// End of "$Id: Fl_Window.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Window_fullscreen.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Window_fullscreen.cxx new file mode 100644 index 0000000..5626847 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Window_fullscreen.cxx @@ -0,0 +1,95 @@ +// +// "$Id: Fl_Window_fullscreen.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Fullscreen window support for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Turning the border on/off by changing the motif_wm_hints property +// works on Irix 4DWM. Does not appear to work for any other window +// manager. Fullscreen still works on some window managers (fvwm is one) +// because they allow the border to be placed off-screen. + +// Unfortunately most X window managers ignore changes to the border +// and refuse to position the border off-screen, so attempting to make +// the window full screen will lose the size of the border off the +// bottom and right. + +#include +#include + +#include + +void Fl_Window::border(int b) { + if (b) { + if (border()) return; + clear_flag(NOBORDER); + } else { + if (!border()) return; + set_flag(NOBORDER); + } +#if defined(USE_X11) + if (shown()) Fl_X::i(this)->sendxjunk(); +#elif defined(WIN32) + // not yet implemented, but it's possible + // for full fullscreen we have to make the window topmost as well +#elif defined(__APPLE_QUARTZ__) + // warning: not implemented in Quartz/Carbon +#else +# error unsupported platform +#endif +} + +void Fl_Window::fullscreen() { +#ifndef WIN32 + //this would clobber the fake wm, since it relies on the border flags to + //determine its thickness + border(0); +#endif +#if defined(__APPLE__) || defined(WIN32) + int sx, sy, sw, sh; + Fl::screen_xywh(sx, sy, sw, sh, x()+w()/2, y()+h()/2); + // if we are on the main screen, we will leave the system menu bar unobstructed + if (Fl::x()>=sx && Fl::y()>=sy && Fl::x()+Fl::w()<=sx+sw && Fl::y()+Fl::h()<=sy+sh) { + sx = Fl::x(); sy = Fl::y(); + sw = Fl::w(); sh = Fl::h(); + } + if (x()==sx) x(sx+1); // make sure that we actually execute the resize + resize(sx, sy, sw, sh); +#else + if (!x()) x(1); // force it to call XResizeWindow() + resize(0,0,Fl::w(),Fl::h()); +#endif +} + +void Fl_Window::fullscreen_off(int X,int Y,int W,int H) { + // this order produces less blinking on IRIX: + resize(X,Y,W,H); +#ifndef WIN32 + border(1); +#endif +} + +// +// End of "$Id: Fl_Window_fullscreen.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Window_hotspot.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Window_hotspot.cxx new file mode 100644 index 0000000..92a298f --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Window_hotspot.cxx @@ -0,0 +1,100 @@ +// +// "$Id: Fl_Window_hotspot.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Common hotspot routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include +#include + +void Fl_Window::hotspot(int X, int Y, int offscreen) { + int mx,my; + + // Update the screen position based on the mouse position. + Fl::get_mouse(mx,my); + X = mx-X; Y = my-Y; + + // If offscreen is 0 (the default), make sure that the window + // stays on the screen, if possible. + if (!offscreen) { + int scr_x, scr_y, scr_w, scr_h; + Fl::screen_xywh(scr_x, scr_y, scr_w, scr_h); + + int top = 0; + int left = 0; + int right = 0; + int bottom = 0; + + if (border()) { +#ifdef WIN32 + if (size_range_set && (maxw != minw || maxh != minh)) { + left = right = GetSystemMetrics(SM_CXSIZEFRAME); + top = bottom = GetSystemMetrics(SM_CYSIZEFRAME); + } else { + left = right = GetSystemMetrics(SM_CXFIXEDFRAME); + top = bottom = GetSystemMetrics(SM_CYFIXEDFRAME); + } + top += GetSystemMetrics(SM_CYCAPTION); +#elif defined(__APPLE__) + top = 24; + left = 2; + right = 2; + bottom = 2; +#else + // Ensure border is on screen; these values are generic enough + // to work with many window managers, and are based on KDE defaults. + top = 20; + left = 4; + right = 4; + bottom = 8; +#endif + } + // now insure contents are on-screen (more important than border): + if (X+w()+right > scr_w-scr_x) X = scr_w-scr_x-right-w(); + if (X-left < scr_x) X = left; + if (Y+h()+bottom > scr_h-scr_y) Y = scr_h-scr_y-bottom-h(); + if (Y-top < scr_y) Y = top; + // make sure that we will force this position + if (X==x()) x(X-1); + } + + position(X,Y); +} + +void Fl_Window::hotspot(const Fl_Widget *o, int offscreen) { + int X = o->w()/2; + int Y = o->h()/2; + while (o != this && o) { + X += o->x(); Y += o->y(); + o = o->window(); + } + hotspot(X,Y,offscreen); +} + + +// +// End of "$Id: Fl_Window_hotspot.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Window_iconize.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Window_iconize.cxx new file mode 100644 index 0000000..4d00b88 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Window_iconize.cxx @@ -0,0 +1,49 @@ +// +// "$Id: Fl_Window_iconize.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Window minification code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include + +extern char fl_show_iconic; // in Fl_x.cxx + +void Fl_Window::iconize() { + if (!shown()) { + fl_show_iconic = 1; + show(); + } else { +#ifdef WIN32 + ShowWindow(i->xid, SW_SHOWMINNOACTIVE); +#elif defined(__APPLE__) + MacCollapseWindow((Window)i->xid); +#else + XIconifyWindow(fl_display, i->xid, fl_screen); +#endif + } +} + +// +// End of "$Id: Fl_Window_iconize.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Wizard.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Wizard.cxx new file mode 100644 index 0000000..3557cfa --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_Wizard.cxx @@ -0,0 +1,195 @@ +// +// "$Id: Fl_Wizard.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Fl_Wizard widget routines. +// +// Copyright 1997-2010 by Easy Software Products. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// +// Contents: + +// +// Fl_Wizard::Fl_Wizard() - Create an Fl_Wizard widget. +// Fl_Wizard::draw() - Draw the wizard border and visible child. +// Fl_Wizard::next() - Show the next child. +// Fl_Wizard::prev() - Show the previous child. +// Fl_Wizard::value() - Return the current visible child. +// Fl_Wizard::value() - Set the visible child. +// + +// +// Include necessary header files... +// + +#include +#include +#include + + +// +// 'Fl_Wizard::Fl_Wizard()' - Create an Fl_Wizard widget. +// + +/** + The constructor creates the Fl_Wizard widget at the specified + position and size. +

      The inherited destructor destroys the widget and its children. +*/ +Fl_Wizard::Fl_Wizard(int xx, // I - Lefthand position + int yy, // I - Upper position + int ww, // I - Width + int hh, // I - Height + const char *l) : // I - Label + Fl_Group(xx, yy, ww, hh, l) +{ + box(FL_THIN_UP_BOX); + + value_ = (Fl_Widget *)0; +} + + +// +/** Draws the wizard border and visible child. */ +void Fl_Wizard::draw() { + Fl_Widget *kid; // Visible child + + + kid = value(); + + if (damage() & FL_DAMAGE_ALL) + { + // Redraw everything... + if (kid) + { + draw_box(box(), x(), y(), w(), h(), kid->color()); + draw_child(*kid); + } + else + draw_box(box(), x(), y(), w(), h(), color()); + + } + else if (kid) + update_child(*kid); +} + + +/** + This method shows the next child of the wizard. If the last child + is already visible, this function does nothing. +*/ +void Fl_Wizard::next() { + int num_kids; + Fl_Widget * const *kids; + + + if ((num_kids = children()) == 0) + return; + + for (kids = array(); num_kids > 0; kids ++, num_kids --) + if ((*kids)->visible()) + break; + + if (num_kids > 1) + value(kids[1]); +} + +/** Shows the previous child.*/ +void Fl_Wizard::prev() +{ + int num_kids; + Fl_Widget * const *kids; + + + if ((num_kids = children()) == 0) + return; + + for (kids = array(); num_kids > 0; kids ++, num_kids --) + if ((*kids)->visible()) + break; + + if (num_kids > 0 && num_kids < children()) + value(kids[-1]); +} + +/** Gets the current visible child widget. */ +Fl_Widget* Fl_Wizard::value() +{ + int num_kids; + Fl_Widget * const *kids; + Fl_Widget *kid; + + + if ((num_kids = children()) == 0) + return ((Fl_Widget *)0); + + for (kids = array(), kid = (Fl_Widget *)0; num_kids > 0; kids ++, num_kids --) + { + if ((*kids)->visible()) + { + if (kid) + (*kids)->hide(); + else + kid = *kids; + } + } + + if (!kid) + { + kids --; + kid = *kids; + kid->show(); + } + + return (kid); +} + +/** Sets the child widget that is visible.*/ +void Fl_Wizard::value(Fl_Widget *kid) +{ + int num_kids; + Fl_Widget * const *kids; + + + if ((num_kids = children()) == 0) + return; + + for (kids = array(); num_kids > 0; kids ++, num_kids --) + { + if (*kids == kid) + { + if (!kid->visible()) + kid->show(); + } + else + (*kids)->hide(); + } + + // This will restore the mouse pointer to the window's default cursor + // whenever the wizard pane is changed. Otherwise text widgets that + // show the next pane may leave the cursor set to the I beam, etc... + if (window()) window()->cursor(FL_CURSOR_DEFAULT); +} + + + +// +// End of "$Id: Fl_Wizard.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_XBM_Image.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_XBM_Image.cxx new file mode 100644 index 0000000..cb35c1b --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_XBM_Image.cxx @@ -0,0 +1,112 @@ +// +// "$Id: Fl_XBM_Image.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Fl_XBM_Image routines. +// +// Copyright 1997-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// +// Contents: +// +// Fl_XBM_Image::Fl_XBM_Image() - Load an XBM file. +// + +// +// Include necessary header files... +// + +#include +#include +#include +#include +#include +#include "flstring.h" + +// +// 'Fl_XBM_Image::Fl_XBM_Image()' - Load an XBM file. +// + +/** + The constructor loads the named XBM file from the given name filename. +

      The destructor free all memory and server resources that are used by + the image. +*/ +Fl_XBM_Image::Fl_XBM_Image(const char *name) : Fl_Bitmap((const char *)0,0,0) { + FILE *f; + uchar *ptr; + + if ((f = fl_fopen(name, "rb")) == NULL) return; + + char buffer[1024]; + char junk[1024]; + int wh[2]; // width and height + int i; + for (i = 0; i<2; i++) { + for (;;) { + if (!fgets(buffer,1024,f)) { + fclose(f); + return; + } + int r = sscanf(buffer,"#define %s %d",junk,&wh[i]); + if (r >= 2) break; + } + } + + // skip to data array: + for (;;) { + if (!fgets(buffer,1024,f)) { + fclose(f); + return; + } + if (!strncmp(buffer,"static ",7)) break; + } + + // Allocate memory... + w(wh[0]); + h(wh[1]); + + int n = ((wh[0]+7)/8)*wh[1]; + array = new uchar[n]; + + // read the data: + for (i = 0, ptr = (uchar *)array; i < n;) { + if (!fgets(buffer,1024,f)) { + fclose(f); + return; + } + const char *a = buffer; + while (*a && i0) { + *ptr++ = (uchar)t; + i ++; + } + while (*a && *a++ != ','); + } + } + + fclose(f); +} + + +// +// End of "$Id: Fl_XBM_Image.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_XColor.H b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_XColor.H new file mode 100644 index 0000000..16cb366 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_XColor.H @@ -0,0 +1,46 @@ +// +// "$Id: Fl_XColor.H 6616 2009-01-01 21:28:26Z matt $" +// +// X-specific color definitions for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2009 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include + +// one of these for each color in fltk's "colormap": +// if overlays are enabled, another one for the overlay +struct Fl_XColor { + unsigned char r,g,b; // actual color used by X + unsigned char mapped; // true when XAllocColor done + unsigned long pixel; // the X pixel to use +}; +extern Fl_XColor fl_xmap[/*overlay*/][256]; + +// mask & shifts to produce xcolor for truecolor visuals: +extern unsigned char fl_redmask, fl_greenmask, fl_bluemask; +extern int fl_redshift, fl_greenshift, fl_blueshift, fl_extrashift; + +// +// End of "$Id: Fl_XColor.H 6616 2009-01-01 21:28:26Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_XPM_Image.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_XPM_Image.cxx new file mode 100644 index 0000000..7f66eff --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_XPM_Image.cxx @@ -0,0 +1,136 @@ +// +// "$Id: Fl_XPM_Image.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Fl_XPM_Image routines. +// +// Copyright 1997-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// +// Contents: +// +// + +// +// Include necessary header files... +// + +#include +#include +#include +#include +#include +#include "flstring.h" + + +// +// 'hexdigit()' - Convert a hex digit to an integer. +// + +static int hexdigit(int x) { // I - Hex digit... + if (isdigit(x)) return x-'0'; + if (isupper(x)) return x-'A'+10; + if (islower(x)) return x-'a'+10; + return 20; +} + +#define MAXSIZE 2048 +#define INITIALLINES 256 +/** + The constructor loads the XPM image from the name filename. +

      The destructor free all memory and server resources that are used by + the image. +*/ +Fl_XPM_Image::Fl_XPM_Image(const char *name) : Fl_Pixmap((char *const*)0) { + FILE *f; + + if ((f = fl_fopen(name, "rb")) == NULL) return; + + // read all the c-strings out of the file: + char** new_data = new char *[INITIALLINES]; + char** temp_data; + int malloc_size = INITIALLINES; + char buffer[MAXSIZE+20]; + int i = 0; + while (fgets(buffer,MAXSIZE+20,f)) { + if (buffer[0] != '\"') continue; + char *myp = buffer; + char *q = buffer+1; + while (*q != '\"' && myp < buffer+MAXSIZE) { + if (*q == '\\') switch (*++q) { + case '\r': + case '\n': + if (!fgets(q,(buffer+MAXSIZE+20)-q,f)) { /* no problem if we hit EOF */ } break; + case 0: + break; + case 'x': { + q++; + int n = 0; + for (int x = 0; x < 3; x++) { + int xd = hexdigit(*q); + if (xd > 15) break; + n = (n<<4)+xd; + q++; + } + *myp++ = n; + } break; + default: { + int c = *q++; + if (c>='0' && c<='7') { + c -= '0'; + for (int x=0; x<2; x++) { + int xd = hexdigit(*q); + if (xd>7) break; + c = (c<<3)+xd; + q++; + } + } + *myp++ = c; + } break; + } else { + *myp++ = *q++; + } + } + *myp++ = 0; + if (i >= malloc_size) { + temp_data = new char *[malloc_size + INITIALLINES]; + memcpy(temp_data, new_data, sizeof(char *) * malloc_size); + delete[] new_data; + new_data = temp_data; + malloc_size += INITIALLINES; + } + new_data[i] = new char[myp-buffer+1]; + memcpy(new_data[i], buffer,myp-buffer); + new_data[i][myp-buffer] = 0; + i++; + } + + fclose(f); + + data((const char **)new_data, i); + alloc_data = 1; + + measure(); +} + + +// +// End of "$Id: Fl_XPM_Image.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_abort.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_abort.cxx new file mode 100644 index 0000000..f854615 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_abort.cxx @@ -0,0 +1,102 @@ +// +// "$Id: Fl_abort.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Warning/error message code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// This method is in its own source file so that stdlib and stdio +// do not need to be included in Fl.cxx: +// You can also override this by redefining all of these. + +#include +#include +#include +#include +#include "flstring.h" + +#ifdef WIN32 +# include + +static void warning(const char *, ...) { + // Show nothing for warnings under WIN32... +} + +static void error(const char *format, ...) { + va_list args; + char buf[1024]; + va_start(args, format); + vsnprintf(buf, 1024, format, args); + va_end(args); + MessageBox(0,buf,"Error",MB_ICONEXCLAMATION|MB_SYSTEMMODAL); +} + +static void fatal(const char *format, ...) { + va_list args; + char buf[1024]; + va_start(args, format); + vsnprintf(buf, 1024, format, args); + va_end(args); + MessageBox(0,buf,"Error",MB_ICONSTOP|MB_SYSTEMMODAL); + ::exit(1); +} + +#else + +static void warning(const char *format, ...) { + va_list args; + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); + fputc('\n', stderr); + fflush(stderr); +} + +static void error(const char *format, ...) { + va_list args; + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); + fputc('\n', stderr); + fflush(stderr); +} + +static void fatal(const char *format, ...) { + va_list args; + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); + fputc('\n', stderr); + fflush(stderr); + ::exit(1); +} + +#endif + +void (*Fl::warning)(const char* format, ...) = ::warning; +void (*Fl::error)(const char* format, ...) = ::error; +void (*Fl::fatal)(const char* format, ...) = ::fatal; + +// +// End of "$Id: Fl_abort.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_add_idle.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_add_idle.cxx new file mode 100644 index 0000000..6059ae1 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_add_idle.cxx @@ -0,0 +1,123 @@ +// +// "$Id: Fl_add_idle.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Idle routine support for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Allows you to manage an arbitrary set of idle() callbacks. +// Replaces the older set_idle() call (which is used to implement this) + +#include + +struct idle_cb { + void (*cb)(void*); + void* data; + idle_cb *next; +}; + +// the callbacks are stored linked in a ring. last points at the one +// just called, first at the next to call. last->next == first. + +static idle_cb* first; +static idle_cb* last; +static idle_cb* freelist; + +static void call_idle() { + idle_cb* p = first; + last = p; first = p->next; + p->cb(p->data); // this may call add_idle() or remove_idle()! +} + +/** + Adds a callback function that is called every time by Fl::wait() and also + makes it act as though the timeout is zero (this makes Fl::wait() return + immediately, so if it is in a loop it is called repeatedly, and thus the + idle fucntion is called repeatedly). The idle function can be used to get + background processing done. + + You can have multiple idle callbacks. To remove an idle callback use + Fl::remove_idle(). + + Fl::wait() and Fl::check() call idle callbacks, but Fl::ready() does not. + + The idle callback can call any FLTK functions, including Fl::wait(), + Fl::check(), and Fl::ready(). + + FLTK will not recursively call the idle callback. +*/ +void Fl::add_idle(Fl_Idle_Handler cb, void* data) { + idle_cb* p = freelist; + if (p) freelist = p->next; + else p = new idle_cb; + p->cb = cb; + p->data = data; + if (first) { + last->next = p; + last = p; + p->next = first; + } else { + first = last = p; + p->next = p; + set_idle(call_idle); + } +} + +/** + Returns true if the specified idle callback is currently installed. +*/ +int Fl::has_idle(Fl_Idle_Handler cb, void* data) { + idle_cb* p = first; + if (!p) return 0; + for (;; p = p->next) { + if (p->cb == cb && p->data == data) return 1; + if (p==last) return 0; + } +} + +/** + Removes the specified idle callback, if it is installed. +*/ +void Fl::remove_idle(Fl_Idle_Handler cb, void* data) { + idle_cb* p = first; + if (!p) return; + idle_cb* l = last; + for (;; p = p->next) { + if (p->cb == cb && p->data == data) break; + if (p==last) return; // not found + l = p; + } + if (l == p) { // only one + first = last = 0; + set_idle(0); + } else { + last = l; + first = l->next = p->next; + } + p->next = freelist; + freelist = p; +} + +// +// End of "$Id: Fl_add_idle.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_arg.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_arg.cxx new file mode 100644 index 0000000..8ebc75f --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_arg.cxx @@ -0,0 +1,550 @@ +// +// "$Id: Fl_arg.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Optional argument initialization code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// OPTIONAL initialization code for a program using fltk. +// You do not need to call this! Feel free to make up your own switches. + +#include +#include +#include +#include +#include +#include +#include +#include "flstring.h" + +#if defined(WIN32) || defined(__APPLE__) +int XParseGeometry(const char*, int*, int*, unsigned int*, unsigned int*); +# define NoValue 0x0000 +# define XValue 0x0001 +# define YValue 0x0002 +# define WidthValue 0x0004 +# define HeightValue 0x0008 +# define AllValues 0x000F +# define XNegative 0x0010 +# define YNegative 0x0020 +#endif + +static int fl_match(const char *a, const char *s, int atleast = 1) { + const char *b = s; + while (*a && (*a == *b || tolower(*a) == *b)) {a++; b++;} + return !*a && b >= s+atleast; +} + +// flags set by previously parsed arguments: +extern char fl_show_iconic; // in Fl_x.cxx +static char arg_called; +static char return_i; +static const char *name; +static const char *geometry; +static const char *title; +// these are in Fl_get_system_colors and are set by the switches: +extern const char *fl_fg; +extern const char *fl_bg; +extern const char *fl_bg2; + +/** + Parse a single switch from \p argv, starting at word \p i. + Returns the number of words eaten (1 or 2, or 0 if it is not + recognized) and adds the same value to \p i. + + This is the default argument handler used internally by Fl::args(...), + but you can use this function if you prefer to step through the + standard FLTK switches yourself. + + All standard FLTK switches except -bg2 may be abbreviated to just + one letter and case is ignored: + + \li -bg color or -background color +
      + Sets the background color using Fl::background(). + + \li -bg2 color or -background2 color +
      + Sets the secondary background color using Fl::background2(). + + \li -display host:n.n +
      + Sets the X display to use; this option is silently + ignored under WIN32 and MacOS. + + \li -dnd and -nodnd +
      + Enables or disables drag and drop text operations + using Fl::dnd_text_ops(). + + \li -fg color or -foreground color +
      + Sets the foreground color using Fl::foreground(). + + \li -geometry WxH+X+Y +
      + Sets the initial window position and size according + to the standard X geometry string. + + \li -iconic +
      + Iconifies the window using Fl_Window::iconize(). + + \li -kbd and -nokbd +
      + Enables or disables visible keyboard focus for + non-text widgets using Fl::visible_focus(). + + \li -name string +
      + Sets the window class using Fl_Window::xclass(). + + \li -scheme string +
      + Sets the widget scheme using Fl::scheme(). + + \li -title string +
      + Sets the window title using Fl_Window::label(). + + \li -tooltips and -notooltips +
      + Enables or disables tooltips using Fl_Tooltip::enable(). + + + If your program requires other switches in addition to the standard + FLTK options, you will need to pass your own argument handler to + Fl::args(int,char**,int&,Fl_Args_Handler) explicitly. +*/ +int Fl::arg(int argc, char **argv, int &i) { + arg_called = 1; + const char *s = argv[i]; + + if (!s) {i++; return 1;} // something removed by calling program? + + // a word that does not start with '-', or a word after a '--', or + // the word '-' by itself all start the "non-switch arguments" to + // a program. Return 0 to indicate that we don't understand the + // word, but set a flag (return_i) so that args() will return at + // that point: + if (s[0] != '-' || s[1] == '-' || !s[1]) {return_i = 1; return 0;} + s++; // point after the dash + + if (fl_match(s, "iconic")) { + fl_show_iconic = 1; + i++; + return 1; + } else if (fl_match(s, "kbd")) { + Fl::visible_focus(1); + i++; + return 1; + } else if (fl_match(s, "nokbd", 3)) { + Fl::visible_focus(0); + i++; + return 1; + } else if (fl_match(s, "dnd", 2)) { + Fl::dnd_text_ops(1); + i++; + return 1; + } else if (fl_match(s, "nodnd", 3)) { + Fl::dnd_text_ops(0); + i++; + return 1; + } else if (fl_match(s, "tooltips", 2)) { + Fl_Tooltip::enable(); + i++; + return 1; + } else if (fl_match(s, "notooltips", 3)) { + Fl_Tooltip::disable(); + i++; + return 1; + } +#ifdef __APPLE__ + // The Finder application in MacOS X passes the "-psn_N_NNNNN" option + // to all apps... + else if (strncmp(s, "psn_", 4) == 0) { + i++; + return 1; + } +#endif // __APPLE__ + + const char *v = argv[i+1]; + if (i >= argc-1 || !v) + return 0; // all the rest need an argument, so if missing it is an error + + if (fl_match(s, "geometry")) { + + int flags, gx, gy; unsigned int gw, gh; + flags = XParseGeometry(v, &gx, &gy, &gw, &gh); + if (!flags) return 0; + geometry = v; + +#if !defined(WIN32) && !defined(__APPLE__) + } else if (fl_match(s, "display", 2)) { + Fl::display(v); +#endif + + } else if (fl_match(s, "title", 2)) { + title = v; + + } else if (fl_match(s, "name", 2)) { + name = v; + + } else if (fl_match(s, "bg2", 3) || fl_match(s, "background2", 11)) { + fl_bg2 = v; + + } else if (fl_match(s, "bg", 2) || fl_match(s, "background", 10)) { + fl_bg = v; + + } else if (fl_match(s, "fg", 2) || fl_match(s, "foreground", 10)) { + fl_fg = v; + + } else if (fl_match(s, "scheme", 1)) { + Fl::scheme(v); + + } else return 0; // unrecognized + + i += 2; + return 2; +} + + +/** + Parse command line switches using the \p cb argument handler. + + Returns 0 on error, or the number of words processed. + + FLTK provides this as an entirely optional command line + switch parser. You don't have to call it if you don't want to. + Everything it can do can be done with other calls to FLTK. + + To use the switch parser, call Fl::args(...) near the start + of your program. This does \b not open the display, instead + switches that need the display open are stashed into static + variables. Then you \b must display your first window by calling + window->show(argc,argv), which will do anything stored + in the static variables. + + Providing an argument handler callback \p cb lets you define + your own switches. It is called with the same \p argc and \p argv, + and with \p i set to the index of the switch to be processed. + The \p cb handler should return zero if the switch is unrecognized, + and not change \p i. It should return non-zero to indicate the + number of words processed if the switch is recognized, i.e. 1 for + just the switch, and more than 1 for the switch plus associated + parameters. \p i should be incremented by the same amount. + + The \p cb handler is called \b before any other tests, so + you can also override any standard FLTK switch + (this is why FLTK can use very short switches instead of + the long ones all other toolkits force you to use). + See Fl::arg() for descriptions of the standard switches. + + On return \p i is set to the index of the first non-switch. + This is either: + + \li The first word that does not start with '-'. + \li The word '-' (used by many programs to name stdin as a file) + \li The first unrecognized switch (return value is 0). + \li \p argc + + The return value is \p i unless an unrecognized switch is found, + in which case it is zero. If your program takes no arguments other + than switches you should produce an error if the return value is less + than \p argc. + + + A usage string is displayed if Fl::args() detects an invalid argument + on the command-line. You can change the message by setting the + Fl::help pointer. + + A very simple command line parser can be found in examples/howto-parse-args.cxx + + The simpler Fl::args(int argc, char **argv) form is useful if your program + does not have command line switches of its own. +*/ + +int Fl::args(int argc, char** argv, int& i, Fl_Args_Handler cb) { + arg_called = 1; + i = 1; // skip argv[0] + while (i < argc) { + if (cb && cb(argc,argv,i)) continue; + if (!arg(argc,argv,i)) return return_i ? i : 0; + } + return i; +} + +// show a main window, use any parsed arguments +void Fl_Window::show(int argc, char **argv) { + if (argc && !arg_called) Fl::args(argc,argv); + + Fl::get_system_colors(); + +#if !defined(WIN32) && !defined(__APPLE__) + // Get defaults for drag-n-drop and focus... + const char *key = 0, *val; + + if (Fl::first_window()) key = Fl::first_window()->xclass(); + if (!key) key = "fltk"; + + val = XGetDefault(fl_display, key, "dndTextOps"); + if (val) Fl::dnd_text_ops(strcasecmp(val, "true") == 0 || + strcasecmp(val, "on") == 0 || + strcasecmp(val, "yes") == 0); + + val = XGetDefault(fl_display, key, "tooltips"); + if (val) Fl_Tooltip::enable(strcasecmp(val, "true") == 0 || + strcasecmp(val, "on") == 0 || + strcasecmp(val, "yes") == 0); + + val = XGetDefault(fl_display, key, "visibleFocus"); + if (val) Fl::visible_focus(strcasecmp(val, "true") == 0 || + strcasecmp(val, "on") == 0 || + strcasecmp(val, "yes") == 0); +#endif // !WIN32 && !__APPLE__ + + // set colors first, so background_pixel is correct: + static char beenhere; + if (!beenhere) { + if (geometry) { + int fl = 0, gx = x(), gy = y(); unsigned int gw = w(), gh = h(); + fl = XParseGeometry(geometry, &gx, &gy, &gw, &gh); + if (fl & XNegative) gx = Fl::w()-w()+gx; + if (fl & YNegative) gy = Fl::h()-h()+gy; + // int mw,mh; minsize(mw,mh); + // if (mw > gw) gw = mw; + // if (mh > gh) gh = mh; + Fl_Widget *r = resizable(); + if (!r) resizable(this); + // for WIN32 we assume window is not mapped yet: + if (fl & (XValue | YValue)) + x(-1), resize(gx,gy,gw,gh); + else + size(gw,gh); + resizable(r); + } + } + + // set the class, which is used by X version of get_system_colors: + if (name) {xclass(name); name = 0;} + else if (!xclass()) xclass(fl_filename_name(argv[0])); + + if (title) {label(title); title = 0;} + else if (!label()) label(xclass()); + + if (!beenhere) { + beenhere = 1; + Fl::scheme(Fl::scheme()); // opens display! May call Fl::fatal() + } + + // Show the window AFTER we have set the colors and scheme. + show(); + +#if !defined(WIN32) && !defined(__APPLE__) + // set the command string, used by state-saving window managers: + int j; + int n=0; for (j=0; jx{+-}{+-}", where + * width, height, xoffset, and yoffset are unsigned integers. + * Example: "=80x24+300-49" + * The equal sign is optional. + * It returns a bitmask that indicates which of the four values + * were actually found in the string. For each value found, + * the corresponding argument is updated; for each value + * not found, the corresponding argument is left unchanged. + */ + +static int ReadInteger(char* string, char** NextString) +{ + register int Result = 0; + int Sign = 1; + + if (*string == '+') + string++; + else if (*string == '-') { + string++; + Sign = -1; + } + for (; (*string >= '0') && (*string <= '9'); string++) { + Result = (Result * 10) + (*string - '0'); + } + *NextString = string; + if (Sign >= 0) + return (Result); + else + return (-Result); +} + +int XParseGeometry(const char* string, int* x, int* y, + unsigned int* width, unsigned int* height) +{ + int mask = NoValue; + register char *strind; + unsigned int tempWidth = 0, tempHeight = 0; + int tempX = 0, tempY = 0; + char *nextCharacter; + + if ( (string == NULL) || (*string == '\0')) return(mask); + if (*string == '=') + string++; /* ignore possible '=' at beg of geometry spec */ + + strind = (char *)string; + if (*strind != '+' && *strind != '-' && *strind != 'x') { + tempWidth = ReadInteger(strind, &nextCharacter); + if (strind == nextCharacter) + return (0); + strind = nextCharacter; + mask |= WidthValue; + } + + if (*strind == 'x' || *strind == 'X') { + strind++; + tempHeight = ReadInteger(strind, &nextCharacter); + if (strind == nextCharacter) + return (0); + strind = nextCharacter; + mask |= HeightValue; + } + + if ((*strind == '+') || (*strind == '-')) { + if (*strind == '-') { + strind++; + tempX = -ReadInteger(strind, &nextCharacter); + if (strind == nextCharacter) + return (0); + strind = nextCharacter; + mask |= XNegative; + + } else { + strind++; + tempX = ReadInteger(strind, &nextCharacter); + if (strind == nextCharacter) + return(0); + strind = nextCharacter; + } + mask |= XValue; + if ((*strind == '+') || (*strind == '-')) { + if (*strind == '-') { + strind++; + tempY = -ReadInteger(strind, &nextCharacter); + if (strind == nextCharacter) + return(0); + strind = nextCharacter; + mask |= YNegative; + + } else { + strind++; + tempY = ReadInteger(strind, &nextCharacter); + if (strind == nextCharacter) + return(0); + strind = nextCharacter; + } + mask |= YValue; + } + } + + /* If strind isn't at the end of the string the it's an invalid + geometry specification. */ + + if (*strind != '\0') return (0); + + if (mask & XValue) + *x = tempX; + if (mask & YValue) + *y = tempY; + if (mask & WidthValue) + *width = tempWidth; + if (mask & HeightValue) + *height = tempHeight; + return (mask); +} + +#endif // ifdef WIN32 + +// +// End of "$Id: Fl_arg.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_cocoa.mm b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_cocoa.mm new file mode 100644 index 0000000..f645c34 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_cocoa.mm @@ -0,0 +1,3281 @@ +// +// "$Id: Fl_cocoa.mm 6971 2009-04-13 07:32:01Z matt $" +// +// MacOS-Cocoa specific code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +//// From the inner edge of a MetroWerks CodeWarrior CD: +// (without permission) +// +// "Three Compiles for 68Ks under the sky, +// Seven Compiles for PPCs in their fragments of code, +// Nine Compiles for Mortal Carbon doomed to die, +// One Compile for Mach-O Cocoa on its Mach-O throne, +// in the Land of MacOS X where the Drop-Shadows lie. +// +// One Compile to link them all, One Compile to merge them, +// One Compile to copy them all and in the bundle bind them, +// in the Land of MacOS X where the Drop-Shadows lie." + +/* + TODO: The following messages point to the last Carbon remainders. We should + really remove these as well, so we can stop linking to Carbon alltogether. + + "_GetKeys", referenced from: + Fl::get_key(int) in Fl_get_key.o (kept only for pre-10.4 runs) + + "_GetEventParameter", referenced from: + carbonTextHandler(OpaqueEventHandlerCallRef*, OpaqueEventRef*, void*) in Fl.o + + "_InstallEventHandler", referenced from: + fl_open_display() in Fl.o + + "_GetEventDispatcherTarget", referenced from: + fl_open_display() in Fl.o +*/ + +#ifndef FL_DOXYGEN + +#define CONSOLIDATE_MOTION 0 +extern "C" { +#include +} + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "flstring.h" +#include +#include + +#import + +#ifndef NSINTEGER_DEFINED // appears with 10.5 in NSObjCRuntime.h +#if defined(__LP64__) && __LP64__ +typedef long NSInteger; +typedef unsigned long NSUInteger; +#else +typedef int NSInteger; +typedef unsigned int NSUInteger; +#endif +#endif + + +// #define DEBUG_SELECT // UNCOMMENT FOR SELECT()/THREAD DEBUGGING +#ifdef DEBUG_SELECT +#include // testing +#define DEBUGMSG(msg) if ( msg ) fprintf(stderr, msg); +#define DEBUGPERRORMSG(msg) if ( msg ) perror(msg) +#define DEBUGTEXT(txt) txt +#else +#define DEBUGMSG(msg) +#define DEBUGPERRORMSG(msg) +#define DEBUGTEXT(txt) NULL +#endif /*DEBUG_SELECT*/ + +// external functions +extern void fl_fix_focus(); +extern Fl_Offscreen fl_create_offscreen_with_alpha(int w, int h); +extern CGContextRef CreateWatchImage(void); +extern CGContextRef CreateHelpImage(void); +extern CGContextRef CreateNESWImage(void); +extern CGContextRef CreateNWSEImage(void); +extern CGContextRef CreateNoneImage(void); + +// forward definition of functions in this file +// converting cr lf converter function +static void convert_crlf(char * string, size_t len); +static void createAppleMenu(void); +static Fl_Region MacRegionMinusRect(Fl_Region r, int x,int y,int w,int h); +static void cocoaMouseHandler(NSEvent *theEvent); + +static Fl_Quartz_Graphics_Driver fl_quartz_driver; +static Fl_Display_Device fl_quartz_display(&fl_quartz_driver); +FL_EXPORT Fl_Display_Device *fl_display_device = (Fl_Display_Device*)&fl_quartz_display; // does not change +FL_EXPORT Fl_Graphics_Driver *fl_graphics_driver = (Fl_Graphics_Driver*)&fl_quartz_driver; // the current target device of graphics operations +FL_EXPORT Fl_Surface_Device *fl_surface = (Fl_Surface_Device*)fl_display_device; // the current target surface of graphics operations + +// public variables +int fl_screen; +CGContextRef fl_gc = 0; +void *fl_system_menu; // this is really a NSMenu* +Fl_Sys_Menu_Bar *fl_sys_menu_bar = 0; +void *fl_default_cursor; // this is really a NSCursor* +void *fl_capture = 0; // (NSWindow*) we need this to compensate for a missing(?) mouse capture +char fl_key_vector[32]; // used by Fl::get_key() +bool fl_show_iconic; // true if called from iconize() - shows the next created window in collapsed state +int fl_disable_transient_for; // secret method of removing TRANSIENT_FOR +Window fl_window; +Fl_Window *Fl_Window::current_; +int fl_mac_os_version = 0; // the version number of the running Mac OS X (e.g., 0x1064 for 10.6.4) + +// forward declarations of variables in this file +static int got_events = 0; +static Fl_Window* resize_from_system; + +#if CONSOLIDATE_MOTION +static Fl_Window* send_motion; +extern Fl_Window* fl_xmousewin; +#endif + +enum { FLTKTimerEvent = 1, FLTKDataReadyEvent }; + + +/* fltk-utf8 placekeepers */ +void fl_reset_spot() +{ +} + +void fl_set_spot(int font, int size, int X, int Y, int W, int H, Fl_Window *win) +{ +} + +void fl_set_status(int x, int y, int w, int h) +{ +} + +/* + * Mac keyboard lookup table + */ +static unsigned short macKeyLookUp[128] = +{ + 'a', 's', 'd', 'f', 'h', 'g', 'z', 'x', + 'c', 'v', '^', 'b', 'q', 'w', 'e', 'r', + + 'y', 't', '1', '2', '3', '4', '6', '5', + '=', '9', '7', '-', '8', '0', ']', 'o', + + 'u', '[', 'i', 'p', FL_Enter, 'l', 'j', '\'', + 'k', ';', '\\', ',', '/', 'n', 'm', '.', + + FL_Tab, ' ', '`', FL_BackSpace, + FL_KP_Enter, FL_Escape, 0, 0/*FL_Meta_L*/, + 0/*FL_Shift_L*/, 0/*FL_Caps_Lock*/, 0/*FL_Alt_L*/, 0/*FL_Control_L*/, + 0/*FL_Shift_R*/, 0/*FL_Alt_R*/, 0/*FL_Control_R*/, 0, + + 0, FL_KP+'.', FL_Right, FL_KP+'*', 0, FL_KP+'+', FL_Left, FL_Num_Lock, + FL_Down, 0, 0, FL_KP+'/', FL_KP_Enter, FL_Up, FL_KP+'-', 0, + + 0, FL_KP+'=', FL_KP+'0', FL_KP+'1', FL_KP+'2', FL_KP+'3', FL_KP+'4', FL_KP+'5', + FL_KP+'6', FL_KP+'7', 0, FL_KP+'8', FL_KP+'9', 0, 0, 0, + + FL_F+5, FL_F+6, FL_F+7, FL_F+3, FL_F+8, FL_F+9, 0, FL_F+11, + 0, 0/*FL_F+13*/, FL_Print, FL_Scroll_Lock, 0, FL_F+10, FL_Menu, FL_F+12, + + 0, FL_Pause, FL_Help, FL_Home, FL_Page_Up, FL_Delete, FL_F+4, FL_End, + FL_F+2, FL_Page_Down, FL_F+1, FL_Left, FL_Right, FL_Down, FL_Up, 0/*FL_Power*/, +}; + +/* + * convert the current mouse chord into the FLTK modifier state + */ +static unsigned int mods_to_e_state( NSUInteger mods ) +{ + long state = 0; + if ( mods & NSNumericPadKeyMask ) state |= FL_NUM_LOCK; + if ( mods & NSCommandKeyMask ) state |= FL_META; + if ( mods & NSAlternateKeyMask ) state |= FL_ALT; + if ( mods & NSControlKeyMask ) state |= FL_CTRL; + if ( mods & NSShiftKeyMask ) state |= FL_SHIFT; + if ( mods & NSAlphaShiftKeyMask ) state |= FL_CAPS_LOCK; + unsigned int ret = ( Fl::e_state & 0xff000000 ) | state; + Fl::e_state = ret; + //printf( "State 0x%08x (%04x)\n", Fl::e_state, mods ); + return ret; +} + + +/* + * convert the current key chord into the FLTK keysym + */ + + static void mods_to_e_keysym( NSUInteger mods ) + { + if ( mods & NSCommandKeyMask ) Fl::e_keysym = FL_Meta_L; + else if ( mods & NSNumericPadKeyMask ) Fl::e_keysym = FL_Num_Lock; + else if ( mods & NSAlternateKeyMask ) Fl::e_keysym = FL_Alt_L; + else if ( mods & NSControlKeyMask ) Fl::e_keysym = FL_Control_L; + else if ( mods & NSShiftKeyMask ) Fl::e_keysym = FL_Shift_L; + else if ( mods & NSAlphaShiftKeyMask ) Fl::e_keysym = FL_Caps_Lock; + else Fl::e_keysym = 0; + //printf( "to sym 0x%08x (%04x)\n", Fl::e_keysym, mods ); + } + +// these pointers are set by the Fl::lock() function: +static void nothing() {} +void (*fl_lock_function)() = nothing; +void (*fl_unlock_function)() = nothing; + +// +// Select interface -- how it's implemented: +// When the user app configures one or more file descriptors to monitor +// with Fl::add_fd(), we start a separate thread to select() the data, +// sending a custom OSX 'FLTK data ready event' to the parent thread's +// RunApplicationLoop(), so that it triggers the data ready callbacks +// in the parent thread. -erco 04/04/04 +// +#define POLLIN 1 +#define POLLOUT 4 +#define POLLERR 8 + +// Class to handle select() 'data ready' +class DataReady +{ + struct FD + { + int fd; + short events; + void (*cb)(int, void*); + void* arg; + }; + int nfds, fd_array_size; + FD *fds; + pthread_t tid; // select()'s thread id + + // Data that needs to be locked (all start with '_') + pthread_mutex_t _datalock; // data lock + fd_set _fdsets[3]; // r/w/x sets user wants to monitor + int _maxfd; // max fd count to monitor + int _cancelpipe[2]; // pipe used to help cancel thread + +public: + DataReady() + { + nfds = 0; + fd_array_size = 0; + fds = 0; + tid = 0; + + pthread_mutex_init(&_datalock, NULL); + FD_ZERO(&_fdsets[0]); FD_ZERO(&_fdsets[1]); FD_ZERO(&_fdsets[2]); + _cancelpipe[0] = _cancelpipe[1] = 0; + _maxfd = 0; + } + + ~DataReady() + { + CancelThread(DEBUGTEXT("DESTRUCTOR\n")); + if (fds) { free(fds); fds = 0; } + nfds = 0; + } + + // Locks + // The convention for locks: volatile vars start with '_', + // and must be locked before use. Locked code is prefixed + // with /*LOCK*/ to make painfully obvious esp. in debuggers. -erco + // + void DataLock() { pthread_mutex_lock(&_datalock); } + void DataUnlock() { pthread_mutex_unlock(&_datalock); } + + // Accessors + int IsThreadRunning() { return(tid ? 1 : 0); } + int GetNfds() { return(nfds); } + int GetCancelPipe(int ix) { return(_cancelpipe[ix]); } + fd_set GetFdset(int ix) { return(_fdsets[ix]); } + + // Methods + void AddFD(int n, int events, void (*cb)(int, void*), void *v); + void RemoveFD(int n, int events); + int CheckData(fd_set& r, fd_set& w, fd_set& x); + void HandleData(fd_set& r, fd_set& w, fd_set& x); + static void* DataReadyThread(void *self); + void StartThread(void); + void CancelThread(const char *reason); +}; + +static DataReady dataready; + +void DataReady::AddFD(int n, int events, void (*cb)(int, void*), void *v) +{ + RemoveFD(n, events); + int i = nfds++; + if (i >= fd_array_size) + { + FD *temp; + fd_array_size = 2*fd_array_size+1; + if (!fds) { temp = (FD*)malloc(fd_array_size*sizeof(FD)); } + else { temp = (FD*)realloc(fds, fd_array_size*sizeof(FD)); } + if (!temp) return; + fds = temp; + } + fds[i].cb = cb; + fds[i].arg = v; + fds[i].fd = n; + fds[i].events = events; + DataLock(); + /*LOCK*/ if (events & POLLIN) FD_SET(n, &_fdsets[0]); + /*LOCK*/ if (events & POLLOUT) FD_SET(n, &_fdsets[1]); + /*LOCK*/ if (events & POLLERR) FD_SET(n, &_fdsets[2]); + /*LOCK*/ if (n > _maxfd) _maxfd = n; + DataUnlock(); +} + +// Remove an FD from the array +void DataReady::RemoveFD(int n, int events) +{ + int i,j; + for (i=j=0; iDataLock(); + /*LOCK*/ int maxfd = self->_maxfd; + /*LOCK*/ fd_set r = self->GetFdset(0); + /*LOCK*/ fd_set w = self->GetFdset(1); + /*LOCK*/ fd_set x = self->GetFdset(2); + /*LOCK*/ int cancelpipe = self->GetCancelPipe(0); + /*LOCK*/ if ( cancelpipe > maxfd ) maxfd = cancelpipe; + /*LOCK*/ FD_SET(cancelpipe, &r); // add cancelpipe to fd's to watch + /*LOCK*/ FD_SET(cancelpipe, &x); + self->DataUnlock(); + // timeval t = { 1000, 0 }; // 1000 seconds; + timeval t = { 2, 0 }; // HACK: 2 secs prevents 'hanging' problem + int ret = ::select(maxfd+1, &r, &w, &x, &t); + pthread_testcancel(); // OSX 10.0.4 and older: needed for parent to cancel + switch ( ret ) { + case 0: // NO DATA + continue; + case -1: // ERROR + { + DEBUGPERRORMSG("CHILD THREAD: select() failed"); + return(NULL); // error? exit thread + } + default: // DATA READY + { + if (FD_ISSET(cancelpipe, &r) || FD_ISSET(cancelpipe, &x)) // cancel? + { return(NULL); } // just exit + DEBUGMSG("CHILD THREAD: DATA IS READY\n"); + NSPoint pt={0,0}; + NSEvent *event = [NSEvent otherEventWithType:NSApplicationDefined location:pt + modifierFlags:0 + timestamp:0 + windowNumber:0 context:NULL + subtype:FLTKDataReadyEvent data1:0 data2:0]; + [NSApp postEvent:event atStart:NO]; + return(NULL); // done with thread + } + } + } +} + +// START 'DATA READY' THREAD RUNNING, CREATE INTER-THREAD PIPE +void DataReady::StartThread(void) +{ + CancelThread(DEBUGTEXT("STARTING NEW THREAD\n")); + DataLock(); + /*LOCK*/ pipe(_cancelpipe); // pipe for sending cancel msg to thread + DataUnlock(); + DEBUGMSG("*** START THREAD\n"); + pthread_create(&tid, NULL, DataReadyThread, (void*)this); +} + +// CANCEL 'DATA READY' THREAD, CLOSE PIPE +void DataReady::CancelThread(const char *reason) +{ + if ( tid ) { + DEBUGMSG("*** CANCEL THREAD: "); + DEBUGMSG(reason); + if ( pthread_cancel(tid) == 0 ) { // cancel first + DataLock(); + /*LOCK*/ write(_cancelpipe[1], "x", 1); // wake thread from select + DataUnlock(); + pthread_join(tid, NULL); // wait for thread to finish + } + tid = 0; + DEBUGMSG("(JOINED) OK\n"); + } + // Close pipe if open + DataLock(); + /*LOCK*/ if ( _cancelpipe[0] ) { close(_cancelpipe[0]); _cancelpipe[0] = 0; } + /*LOCK*/ if ( _cancelpipe[1] ) { close(_cancelpipe[1]); _cancelpipe[1] = 0; } + DataUnlock(); +} + +void Fl::add_fd( int n, int events, void (*cb)(int, void*), void *v ) +{ + dataready.AddFD(n, events, cb, v); +} + +void Fl::add_fd(int fd, void (*cb)(int, void*), void* v) +{ + dataready.AddFD(fd, POLLIN, cb, v); +} + +void Fl::remove_fd(int n, int events) +{ + dataready.RemoveFD(n, events); +} + +void Fl::remove_fd(int n) +{ + dataready.RemoveFD(n, -1); +} + +/* + * Check if there is actually a message pending! + */ +int fl_ready() +{ + NSEvent *retval = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:[NSDate dateWithTimeIntervalSinceNow:0] + inMode:NSDefaultRunLoopMode dequeue:NO]; + return retval != nil; +} + + +static void processFLTKEvent(void) { + dataready.CancelThread(DEBUGTEXT("DATA READY EVENT\n")); + + // CHILD THREAD TELLS US DATA READY + // Check to see what's ready, and invoke user's cb's + // + fd_set r,w,x; + switch(dataready.CheckData(r,w,x)) { + case 0: // NO DATA + break; + case -1: // ERROR + break; + default: // DATA READY + dataready.HandleData(r,w,x); + break; + } + return; +} + + +/* + * break the current event loop + */ +static void breakMacEventLoop() +{ + fl_lock_function(); + + NSPoint pt={0,0}; + NSEvent *event = [NSEvent otherEventWithType:NSApplicationDefined location:pt + modifierFlags:0 + timestamp:0 + windowNumber:0 context:NULL + subtype:FLTKTimerEvent data1:0 data2:0]; + [NSApp postEvent:event atStart:NO]; + fl_unlock_function(); +} + +// +// MacOS X timers +// + +struct MacTimeout { + Fl_Timeout_Handler callback; + void* data; + CFRunLoopTimerRef timer; + char pending; +}; +static MacTimeout* mac_timers; +static int mac_timer_alloc; +static int mac_timer_used; + +static void realloc_timers() +{ + if (mac_timer_alloc == 0) { + mac_timer_alloc = 8; + } + mac_timer_alloc *= 2; + MacTimeout* new_timers = new MacTimeout[mac_timer_alloc]; + memset(new_timers, 0, sizeof(MacTimeout)*mac_timer_alloc); + memcpy(new_timers, mac_timers, sizeof(MacTimeout) * mac_timer_used); + MacTimeout* delete_me = mac_timers; + mac_timers = new_timers; + delete [] delete_me; +} + +static void delete_timer(MacTimeout& t) +{ + if (t.timer) { + CFRunLoopRemoveTimer(CFRunLoopGetCurrent(), + t.timer, + kCFRunLoopDefaultMode); + CFRelease(t.timer); + memset(&t, 0, sizeof(MacTimeout)); + } +} + +static void do_timer(CFRunLoopTimerRef timer, void* data) +{ + for (int i = 0; i < mac_timer_used; ++i) { + MacTimeout& t = mac_timers[i]; + if (t.timer == timer && t.data == data) { + t.pending = 0; + (*t.callback)(data); + if (t.pending==0) + delete_timer(t); + break; + } + } + breakMacEventLoop(); +} + +@interface FLWindow : NSWindow { + Fl_Window *w; + BOOL containsGLsubwindow; +} +- (FLWindow*)initWithFl_W:(Fl_Window *)flw + contentRect:(NSRect)rect + styleMask:(NSUInteger)windowStyle + backing:(NSBackingStoreType)bufferingType + defer:(BOOL)deferCreation; +- (Fl_Window *)getFl_Window; +- (BOOL)windowShouldClose:(FLWindow *)w; +- (BOOL)containsGLsubwindow; +- (void)setContainsGLsubwindow:(BOOL)contains; +@end + +@implementation FLWindow +- (FLWindow*)initWithFl_W:(Fl_Window *)flw + contentRect:(NSRect)rect + styleMask:(NSUInteger)windowStyle + backing:(NSBackingStoreType)bufferingType + defer:(BOOL)deferCreation +{ + self = [super initWithContentRect:rect styleMask:windowStyle backing:bufferingType defer:deferCreation]; + if (self) { + w = flw; + containsGLsubwindow = NO; + } + return self; +} +- (Fl_Window *)getFl_Window; +{ + return w; +} +- (BOOL)windowShouldClose:(FLWindow *)fl +{ + Fl::handle( FL_CLOSE, [fl getFl_Window] ); // this might or might not close the window + if (!Fl_X::first) return YES; + Fl_Window *l = Fl::first_window(); + while( l != NULL && l != [fl getFl_Window]) l = Fl::next_window(l); + return (l == NULL ? YES : NO); +} +- (BOOL)containsGLsubwindow +{ + return containsGLsubwindow; +} +- (void)setContainsGLsubwindow:(BOOL)contains +{ + containsGLsubwindow = contains; +} +@end + +/* + * This function is the central event handler. + * It reads events from the event queue using the given maximum time + * Funny enough, it returns the same time that it got as the argument. + */ +static double do_queued_events( double time = 0.0 ) +{ + got_events = 0; + + // Check for re-entrant condition + if ( dataready.IsThreadRunning() ) { + dataready.CancelThread(DEBUGTEXT("AVOID REENTRY\n")); + } + + // Start thread to watch for data ready + if ( dataready.GetNfds() ) { + dataready.StartThread(); + } + + fl_unlock_function(); + + // necessary so that after closing a non-FLTK window (e.g., Fl_Native_File_Chooser) + // the front window turns key again + NSWindow *nsk = [NSApp keyWindow]; + NSWindow *nsm = [NSApp mainWindow]; + if ([nsm isMemberOfClass:[FLWindow class]] && (nsk == nil || ( ! [nsk isMemberOfClass:[FLWindow class]] && + ! [nsk isVisible] ) ) ) { + [nsm makeKeyAndOrderFront:nil]; + } + NSEvent *event = [NSApp nextEventMatchingMask:NSAnyEventMask + untilDate:[NSDate dateWithTimeIntervalSinceNow:time] + inMode:NSDefaultRunLoopMode dequeue:YES]; + if (event != nil) { + BOOL needSendEvent = YES; + if ([event type] == NSLeftMouseDown) { + Fl_Window *grab = Fl::grab(); + if (grab && grab != [(FLWindow *)[event window] getFl_Window]) { + // a click event out of a menu window, so we should close this menu + // done here to catch also clicks on window title bar/resize box + cocoaMouseHandler(event); + } + } + else if ([event type] == NSApplicationDefined) { + if ([event subtype] == FLTKDataReadyEvent) { + processFLTKEvent(); + } + needSendEvent = NO; + } + if (needSendEvent) [NSApp sendEvent:event]; + } + fl_lock_function(); + +#if CONSOLIDATE_MOTION + if (send_motion && send_motion == fl_xmousewin) { + send_motion = 0; + Fl::handle(FL_MOVE, fl_xmousewin); + } +#endif + + return time; +} + +/* + * This public function handles all events. It wait a maximum of + * 'time' seconds for an event. This version returns 1 if events + * other than the timeout timer were processed. + * + * \todo there is no socket handling in this code whatsoever + */ +int fl_wait( double time ) +{ + do_queued_events( time ); + return (got_events); +} + +// updates Fl::e_x, Fl::e_y, Fl::e_x_root, and Fl::e_y_root +static void update_e_xy_and_e_xy_root(NSWindow *nsw) +{ + NSPoint pt; + pt = [nsw mouseLocationOutsideOfEventStream]; + Fl::e_x = int(pt.x); + Fl::e_y = int([[nsw contentView] frame].size.height - pt.y); + pt = [NSEvent mouseLocation]; + Fl::e_x_root = int(pt.x); + Fl::e_y_root = int([[nsw screen] frame].size.height - pt.y); +} + +/* + * Cocoa Mousewheel handler + */ +void cocoaMouseWheelHandler(NSEvent *theEvent) +{ + // Handle the new "MightyMouse" mouse wheel events. Please, someone explain + // to me why Apple changed the API on this even though the current API + // supports two wheels just fine. Matthias, + fl_lock_function(); + + Fl_Window *window = (Fl_Window*)[(FLWindow*)[theEvent window] getFl_Window]; + if ( !window->shown() ) { + fl_unlock_function(); + return; + } + Fl::first_window(window); + + // Under OSX, single mousewheel increments are 0.1, + // so make sure they show up as at least 1.. + // + float dx = [theEvent deltaX]; if ( fabs(dx) < 1.0 ) dx = (dx > 0) ? 1.0 : -1.0; + float dy = [theEvent deltaY]; if ( fabs(dy) < 1.0 ) dy = (dy > 0) ? 1.0 : -1.0; + if ([theEvent deltaX] != 0) { + Fl::e_dx = (int)-dx; + Fl::e_dy = 0; + if ( Fl::e_dx) Fl::handle( FL_MOUSEWHEEL, window ); + } else if ([theEvent deltaY] != 0) { + Fl::e_dx = 0; + Fl::e_dy = (int)-dy; + if ( Fl::e_dy) Fl::handle( FL_MOUSEWHEEL, window ); + } else { + fl_unlock_function(); + return; + } + + fl_unlock_function(); + + // return noErr; +} + +/* + * Cocoa Mouse Button Handler + */ +static void cocoaMouseHandler(NSEvent *theEvent) +{ + static int keysym[] = { 0, FL_Button+1, FL_Button+3, FL_Button+2 }; + static int px, py; + static char suppressed = 0; + + fl_lock_function(); + + Fl_Window *window = (Fl_Window*)[(FLWindow*)[theEvent window] getFl_Window]; + if ( !window->shown() ) { + fl_unlock_function(); + return; + } + Fl_Window *first = Fl::first_window(); + if (first != window && !(first->modal() || first->non_modal())) Fl::first_window(window); + NSPoint pos = [theEvent locationInWindow]; + pos.y = window->h() - pos.y; + NSInteger btn = [theEvent buttonNumber] + 1; + NSUInteger mods = [theEvent modifierFlags]; + int sendEvent = 0; + + NSEventType etype = [theEvent type]; + if (etype == NSLeftMouseDown || etype == NSRightMouseDown || etype == NSOtherMouseDown) { + if (btn == 1) Fl::e_state |= FL_BUTTON1; + else if (btn == 3) Fl::e_state |= FL_BUTTON2; + else if (btn == 2) Fl::e_state |= FL_BUTTON3; + } + else if (etype == NSLeftMouseUp || etype == NSRightMouseUp || etype == NSOtherMouseUp) { + if (btn == 1) Fl::e_state &= ~FL_BUTTON1; + else if (btn == 3) Fl::e_state &= ~FL_BUTTON2; + else if (btn == 2) Fl::e_state &= ~FL_BUTTON3; + } + + switch ( etype ) { + case NSLeftMouseDown: + case NSRightMouseDown: + case NSOtherMouseDown: + suppressed = 0; + sendEvent = FL_PUSH; + Fl::e_is_click = 1; + px = (int)pos.x; py = (int)pos.y; + if ([theEvent clickCount] > 1) + Fl::e_clicks++; + else + Fl::e_clicks = 0; + // fall through + case NSLeftMouseUp: + case NSRightMouseUp: + case NSOtherMouseUp: + if (suppressed) { + suppressed = 0; + break; + } + if ( !window ) break; + if ( !sendEvent ) { + sendEvent = FL_RELEASE; + } + Fl::e_keysym = keysym[ btn ]; + // fall through + case NSMouseMoved: + suppressed = 0; + if ( !sendEvent ) { + sendEvent = FL_MOVE; + } + // fall through + case NSLeftMouseDragged: + case NSRightMouseDragged: + case NSOtherMouseDragged: { + if (suppressed) break; + if ( !sendEvent ) { + sendEvent = FL_MOVE; // Fl::handle will convert into FL_DRAG + if (fabs(pos.x-px)>5 || fabs(pos.y-py)>5) + Fl::e_is_click = 0; + } + mods_to_e_state( mods ); + update_e_xy_and_e_xy_root([theEvent window]); + Fl::handle( sendEvent, window ); + } + break; + default: + break; + } + + fl_unlock_function(); + + return; +} + + +static void calc_e_text(CFStringRef s, char *buffer, size_t len, unsigned sym) +{ + int i, no_text_key = false; + static unsigned notext[] = { // keys that don't emit text + FL_BackSpace, FL_Print, FL_Scroll_Lock, FL_Pause, + FL_Insert, FL_Home, FL_Page_Up, FL_Delete, FL_End, FL_Page_Down, + FL_Left, FL_Up, FL_Right, FL_Down, + FL_Menu, FL_Num_Lock, FL_Help + }; + int count = sizeof(notext)/sizeof(int); + + if (sym > FL_F && sym <= FL_F_Last) no_text_key = true; + else for (i=0; i < count; i++) { + if (notext[i] == sym) { + no_text_key = true; + break; + } + } + + if (no_text_key) { + buffer[0] = 0; + } else { + CFStringGetCString(s, buffer, len, kCFStringEncodingUTF8); + } +} + + +// this gets called by CJK character palette input +OSStatus carbonTextHandler( EventHandlerCallRef nextHandler, EventRef event, void *unused ) +{ + // make sure the key window is an FLTK window + NSWindow *keywindow = [NSApp keyWindow]; + if (keywindow == nil || ![keywindow isMemberOfClass:[FLWindow class]]) return eventNotHandledErr; + // under 10.5 this gets called only after character palette inputs + // but under 10.6 this gets also called by interpretKeyEvents + // during keyboard input when we don't want to run it + if ([[NSApp currentEvent] type] != NSSystemDefined) return eventNotHandledErr; + Fl_Window *window = [(FLWindow*)keywindow getFl_Window]; + fl_lock_function(); + UniChar ucs[20]; + ByteCount actual_size; + unsigned int i; + GetEventParameter( event, kEventParamTextInputSendText, typeUnicodeText, + NULL, 20, &actual_size, ucs ); + char utf8buf[50], *p; + p = utf8buf; + for(i=0; i < actual_size/2; i++) { + p += fl_utf8encode(ucs[i], p); + } + int len = p - utf8buf; + utf8buf[len]=0; + + Fl::e_length = len; + Fl::e_text = utf8buf; + while (window->parent()) window = window->window(); + Fl::handle(FL_KEYBOARD, window); + fl_unlock_function(); + fl_lock_function(); + Fl::handle(FL_KEYUP, window); + fl_unlock_function(); + // for some reason, the window does not redraw until the next mouse move or button push + // sending a 'redraw()' or 'awake()' does not solve the issue! + Fl::flush(); + return noErr; +} + +OSStatus cocoaKeyboardHandler(NSEvent *theEvent); + +@interface FLTextView : NSTextView +{ + BOOL compose_key; // YES iff entering a character composition + BOOL needKBhandler_val; +} +- (BOOL)needKBhandler; +- (void)needKBhandler:(BOOL)value; +- (BOOL)compose; +- (void)compose:(BOOL)value; +- (void)insertText:(id)aString; +- (void)doCommandBySelector:(SEL)aSelector; +@end +@implementation FLTextView +- (BOOL)needKBhandler +{ + return needKBhandler_val; +} +- (void)needKBhandler:(BOOL)value +{ + needKBhandler_val = value; +} +- (BOOL)compose +{ + return compose_key; +} +- (void)compose:(BOOL)value +{ + compose_key = value; +} +- (void)insertText:(id)aString +{ + cocoaKeyboardHandler([NSApp currentEvent]); +} +- (void)doCommandBySelector:(SEL)aSelector +{ + cocoaKeyboardHandler([NSApp currentEvent]); +} +@end + +/* + * handle cocoa keyboard events +Events during a character composition sequence: + - keydown with deadkey -> [[theEvent characters] length] is 0 + - keyup -> [theEvent characters] contains the deadkey: display it temporarily + - keydown with next key -> [theEvent characters] contains the composed character: + replace the temporary character by this one + - keyup -> [theEvent characters] contains the standard character + */ +OSStatus cocoaKeyboardHandler(NSEvent *theEvent) +{ + static char buffer[32]; + int sendEvent = 0, retval = 0; + Fl_Window *window = (Fl_Window*)[(FLWindow*)[theEvent window] getFl_Window]; + Fl::first_window(window); + NSUInteger mods; + + fl_lock_function(); + // get the modifiers + mods = [theEvent modifierFlags]; + // get the key code + UInt32 keyCode = 0, maskedKeyCode = 0; + unsigned short sym = 0; + keyCode = [theEvent keyCode]; + NSString *s = [theEvent characters]; + FLTextView *edit = (FLTextView*)[[theEvent window] fieldEditor:YES forObject:nil]; + [edit needKBhandler:NO]; + if ( (mods & NSShiftKeyMask) && (mods & NSCommandKeyMask) ) { + s = [s uppercaseString]; // US keyboards return lowercase letter in s if cmd-shift-key is hit + } + // extended keyboards can also send sequences on key-up to generate Kanji etc. codes. + // Some observed prefixes are 0x81 to 0x83, followed by an 8 bit keycode. + // In this mode, there seem to be no key-down codes + // printf("%08x %08x %08x\n", keyCode, mods, key); + maskedKeyCode = keyCode & 0x7f; + switch([theEvent type]) { + case NSKeyDown: + sendEvent = FL_KEYBOARD; + // fall through + case NSKeyUp: + if([edit compose]) sendEvent = FL_KEYBOARD; // when composing, the temporary character appears at KeyUp + if ( !sendEvent ) { + sendEvent = FL_KEYUP; + Fl::e_state &= 0xbfffffff; // clear the deadkey flag + } + mods_to_e_state( mods ); // process modifier keys + sym = macKeyLookUp[maskedKeyCode]; + if (sym < 0xff00) { // a "simple" key + // find the result of this key without modifier + NSString *sim = [theEvent charactersIgnoringModifiers]; + UniChar one; + CFStringGetCharacters((CFStringRef)sim, CFRangeMake(0, 1), &one); + // charactersIgnoringModifiers doesn't ignore shift, remove it when it's on + if(one >= 'A' && one <= 'Z') one += 32; + if (one > 0 && one <= 0x7f && (sym<'0' || sym>'9') ) sym = one; + } + Fl::e_keysym = Fl::e_original_keysym = sym; + // Handle FL_KP_Enter on regular keyboards and on Powerbooks + if ( maskedKeyCode==0x4c || maskedKeyCode==0x34) s = @"\r"; + calc_e_text((CFStringRef)s, buffer, sizeof(buffer), sym); + Fl::e_length = strlen(buffer); + Fl::e_text = buffer; + default: // prevent 'not handled in switch' warnings + break; + } + if (sendEvent) { + retval = Fl::handle(sendEvent,window); + if([edit compose]) { + Fl::compose_state = 1; + [edit compose:NO]; + } + } + fl_unlock_function(); + return retval ? (int)noErr : (int)eventNotHandledErr; // return noErr if FLTK handled the event +} + + +/* + * Open callback function to call... + */ + +static void (*open_cb)(const char *) = 0; + + +/* + * Install an open documents event handler... + */ +@interface FLAppleEventHandler : NSObject +{ +} +- (void)handleAppleEvent:(NSAppleEventDescriptor *)event withReplyEvent: (NSAppleEventDescriptor *)replyEvent; +@end +@implementation FLAppleEventHandler +- (void)handleAppleEvent:(NSAppleEventDescriptor *)event withReplyEvent: (NSAppleEventDescriptor *)replyEvent +{ + NSAppleEventDescriptor *single = [event descriptorAtIndex:1]; + const AEDesc *document = [single aeDesc]; + long i, n; + FSRef fileRef; + AEKeyword keyWd; + DescType typeCd; + Size actSz; + char filename[1024]; + // Lock access to FLTK in this thread... + fl_lock_function(); + + // Open the documents via the callback... + if (AECountItems(document, &n) == noErr) { + for (i = 1; i <= n; i ++) { + AEGetNthPtr(document, i, typeFSRef, &keyWd, &typeCd, + (Ptr)&fileRef, sizeof(fileRef), + (actSz = sizeof(fileRef), &actSz)); + FSRefMakePath( &fileRef, (UInt8*)filename, sizeof(filename) ); + + (*open_cb)(filename); + } + } + // Unlock access to FLTK for all threads... + fl_unlock_function(); +} +@end + +void fl_open_callback(void (*cb)(const char *)) { + static NSAppleEventManager *aeventmgr = nil; + static FLAppleEventHandler *handler; + fl_open_display(); + if (!aeventmgr) { + aeventmgr = [NSAppleEventManager sharedAppleEventManager]; + handler = [[FLAppleEventHandler alloc] init]; + } + + open_cb = cb; + if (cb) { + [aeventmgr setEventHandler:handler andSelector:@selector(handleAppleEvent:withReplyEvent:) + forEventClass:kCoreEventClass andEventID:kAEOpenDocuments]; + } else { + [aeventmgr removeEventHandlerForEventClass:kCoreEventClass andEventID:kAEOpenDocuments]; + } +} + + +/* + * initialize the Mac toolboxes, dock status, and set the default menubar + */ + +extern "C" { + extern OSErr CPSEnableForegroundOperation(ProcessSerialNumber *psn, UInt32 _arg2, + UInt32 _arg3, UInt32 _arg4, UInt32 _arg5); +} + + +@interface FLDelegate : NSObject +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 + +#endif +{ +} +- (void)windowDidMove:(NSNotification *)notif; +- (void)windowDidResize:(NSNotification *)notif; +- (void)windowDidBecomeKey:(NSNotification *)notif; +- (void)windowDidBecomeMain:(NSNotification *)notif; +- (void)windowDidDeminiaturize:(NSNotification *)notif; +- (void)windowDidMiniaturize:(NSNotification *)notif; +- (void)windowWillClose:(NSNotification *)notif; +- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication*)sender; +- (void)applicationDidBecomeActive:(NSNotification *)notify; +- (void)applicationWillResignActive:(NSNotification *)notify; +- (id)windowWillReturnFieldEditor:(NSWindow *)sender toObject:(id)client; +@end +@implementation FLDelegate +- (void)windowDidMove:(NSNotification *)notif +{ + FLWindow *nsw = (FLWindow*)[notif object]; + Fl_Window *window = [nsw getFl_Window]; + NSPoint pt, pt2; + pt.x = 0; + pt.y = [[nsw contentView] frame].size.height; + pt2 = [nsw convertBaseToScreen:pt]; + update_e_xy_and_e_xy_root(nsw); + window->position((int)pt2.x, (int)([[nsw screen] frame].size.height - pt2.y)); + if ([nsw containsGLsubwindow] ) { + [nsw display];// redraw window after moving if it contains OpenGL subwindows + } +} +- (void)windowDidResize:(NSNotification *)notif +{ + FLWindow *nsw = (FLWindow*)[notif object]; + Fl_Window *window = [nsw getFl_Window]; + NSRect r = [[nsw contentView] frame]; + NSPoint pt, pt2; + pt.x = 0; + pt.y = [[nsw contentView] frame].size.height; + pt2 = [nsw convertBaseToScreen:pt]; + resize_from_system = window; + update_e_xy_and_e_xy_root(nsw); + window->resize((int)pt2.x, + (int)([[nsw screen] frame].size.height - pt2.y), + (int)r.size.width, + (int)r.size.height); +} +- (void)windowDidBecomeKey:(NSNotification *)notif +{ + FLWindow *nsw = (FLWindow*)[notif object]; + Fl_Window *window = [nsw getFl_Window]; + Fl::handle( FL_FOCUS, window); +} +- (void)windowDidBecomeMain:(NSNotification *)notif +{ + FLWindow *nsw = (FLWindow*)[notif object]; + Fl_Window *window = [nsw getFl_Window]; + Fl::first_window(window); + update_e_xy_and_e_xy_root(nsw); +} +- (void)windowDidDeminiaturize:(NSNotification *)notif +{ + FLWindow *nsw = (FLWindow*)[notif object]; + Fl_Window *window = [nsw getFl_Window]; + window->set_visible(); + update_e_xy_and_e_xy_root(nsw); +} +- (void)windowDidMiniaturize:(NSNotification *)notif +{ + FLWindow *nsw = (FLWindow*)[notif object]; + Fl_Window *window = [nsw getFl_Window]; + window->clear_visible(); +} +- (void)windowWillClose:(NSNotification *)notif +{ + Fl_Window *w = Fl::first_window(); + if (!w) return; + NSWindow *cw = (NSWindow*)Fl_X::i(w)->xid; + if ( ![cw isMiniaturized] && ([cw styleMask] & NSTitledWindowMask) ) { + if (![cw isKeyWindow]) { // always make Fl::first_window() the key widow + [cw makeKeyAndOrderFront:nil]; + } + if (![cw isMainWindow]) { // always make Fl::first_window() the main widow + [cw makeMainWindow]; + } + } +} +- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication*)sender +{ + fl_lock_function(); + NSApplicationTerminateReply reply = NSTerminateNow; + while ( Fl_X::first ) { + Fl_X *x = Fl_X::first; + Fl::handle( FL_CLOSE, x->w ); + if ( Fl_X::first == x ) { + reply = NSTerminateCancel; // FLTK has not closed all windows, so we return to the main program now + break; + } + } + fl_unlock_function(); + return reply; +} +/** + * Cocoa organizes the Z depth of windows on a global priority. FLTK however + * expects the window manager to organize Z level by application. The trickery + * below will change Z order during activation and deactivation. + */ +- (void)applicationDidBecomeActive:(NSNotification *)notify +{ + Fl_X *x; + FLWindow *top = 0, *topModal = 0, *topNonModal = 0; + for (x = Fl_X::first;x;x = x->next) { + FLWindow *cw = (FLWindow*)x->xid; + Fl_Window *win = x->w; + if (win && cw) { + if (win->modal()) { + [cw setLevel:NSModalPanelWindowLevel]; + if (topModal) + [cw orderWindow:NSWindowBelow relativeTo:[topModal windowNumber]]; + else + topModal = cw; + } else if (win->non_modal()) { + [cw setLevel:NSFloatingWindowLevel]; + if (topNonModal) + [cw orderWindow:NSWindowBelow relativeTo:[topNonModal windowNumber]]; + else + topNonModal = cw; + } else { + if (top) + ; + else + top = cw; + } + } + } +} +- (void)applicationWillResignActive:(NSNotification *)notify +{ + Fl_X *x; + FLWindow *top = 0; + // sort in all regular windows + for (x = Fl_X::first;x;x = x->next) { + FLWindow *cw = (FLWindow*)x->xid; + Fl_Window *win = x->w; + if (win && cw) { + if (win->modal()) { + } else if (win->non_modal()) { + } else { + if (!top) top = cw; + } + } + } + // now sort in all modals + for (x = Fl_X::first;x;x = x->next) { + FLWindow *cw = (FLWindow*)x->xid; + Fl_Window *win = x->w; + if (win && cw) { + if (win->modal()) { + [cw setLevel:NSNormalWindowLevel]; + if (top) [cw orderWindow:NSWindowAbove relativeTo:[top windowNumber]]; + } else if (win->non_modal()) { + } else { + } + } + } + // finally all non-modals + for (x = Fl_X::first;x;x = x->next) { + FLWindow *cw = (FLWindow*)x->xid; + Fl_Window *win = x->w; + if (win && cw) { + if (win->modal()) { + } else if (win->non_modal()) { + [cw setLevel:NSNormalWindowLevel]; + if (top) [cw orderWindow:NSWindowAbove relativeTo:[top windowNumber]]; + } else { + } + } + } +} +- (id)windowWillReturnFieldEditor:(NSWindow *)sender toObject:(id)client +{ + NSRect rect={{0,0},{20,20}}; + static FLTextView *view = nil; + if (!view) { + view = [[FLTextView alloc] initWithFrame:rect]; + [view compose:NO]; + } + return view; +} +@end + +@interface FLApplication : NSApplication +{ +} +- (void)sendEvent:(NSEvent *)theEvent; +@end +@implementation FLApplication +// The default sendEvent turns key downs into performKeyEquivalent when +// modifiers are down, but swallows the key up if the modifiers include +// command. This one makes all modifiers consistent by always sending key ups. +// FLView treats performKeyEquivalent to keyDown, but performKeyEquivalent is +// still needed for the system menu. +- (void)sendEvent:(NSEvent *)theEvent +{ + NSEventType type = [theEvent type]; + NSWindow *key = [self keyWindow]; + if (key && type == NSKeyUp) { + [key sendEvent:theEvent]; + } else { + [super sendEvent:theEvent]; + } +} +@end + +static FLDelegate *mydelegate; + +void fl_open_display() { + static char beenHereDoneThat = 0; + if ( !beenHereDoneThat ) { + beenHereDoneThat = 1; + + [FLApplication sharedApplication]; + NSAutoreleasePool *localPool; + localPool = [[NSAutoreleasePool alloc] init]; + mydelegate = [[FLDelegate alloc] init]; + [NSApp setDelegate:mydelegate]; + //Seb was here + //[NSApp finishLaunching]; + + // empty the event queue but keep system events for drag&drop of files at launch + NSEvent *ign_event; + do ign_event = [NSApp nextEventMatchingMask:(NSAnyEventMask & ~NSSystemDefinedMask) + untilDate:[NSDate dateWithTimeIntervalSinceNow:0] + inMode:NSDefaultRunLoopMode + dequeue:YES]; + while (ign_event); + + fl_default_cursor = [NSCursor arrowCursor]; + SInt32 version; + Gestalt(gestaltSystemVersion, &version); + fl_mac_os_version = (int)version; + + // bring the application into foreground without a 'CARB' resource + Boolean same_psn; + ProcessSerialNumber cur_psn, front_psn; + if ( !GetCurrentProcess( &cur_psn ) && !GetFrontProcess( &front_psn ) && + !SameProcess( &front_psn, &cur_psn, &same_psn ) && !same_psn ) { + // only transform the application type for unbundled apps + CFBundleRef bundle = CFBundleGetMainBundle(); + if ( bundle ) { + FSRef execFs; + CFURLRef execUrl = CFBundleCopyExecutableURL( bundle ); + CFURLGetFSRef( execUrl, &execFs ); + + FSRef bundleFs; + GetProcessBundleLocation( &cur_psn, &bundleFs ); + + if ( !FSCompareFSRefs( &execFs, &bundleFs ) ) + bundle = NULL; + + CFRelease(execUrl); + } + + if ( !bundle ) + { + // Earlier versions of this code tried to use weak linking, however it + // appears that this does not work on 10.2. Since 10.3 and higher provide + // both TransformProcessType and CPSEnableForegroundOperation, the following + // conditional code compiled on 10.2 will still work on newer releases... + OSErr err; +#if __LP64__ + err = TransformProcessType(&cur_psn, kProcessTransformToForegroundApplication); +#else + +#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2 + if (TransformProcessType != NULL) { + err = TransformProcessType(&cur_psn, kProcessTransformToForegroundApplication); + } else +#endif // MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2 + err = CPSEnableForegroundOperation(&cur_psn, 0x03, 0x3C, 0x2C, 0x1103); +#endif // __LP64__ + if (err == noErr) { + SetFrontProcess( &cur_psn ); + } + } + } + + // Removed to prevent clash with BMax's Apple Menu + // createAppleMenu(); + + // Install Carbon Event handler for character palette input + static EventTypeSpec textEvents[] = { + { kEventClassTextInput, kEventTextInputUnicodeForKeyEvent } + }; + EventHandlerUPP textHandler = NewEventHandlerUPP( carbonTextHandler ); + InstallEventHandler(GetEventDispatcherTarget(), textHandler, 1, textEvents, NULL, 0L); + } +} + + +/* + * get rid of allocated resources + */ +void fl_close_display() { +} + + +// Gets the border sizes and the titlebar size +static void get_window_frame_sizes(int &bx, int &by, int &bt) { + fl_open_display(); + NSRect inside = { {20,20}, {100,100} }; + NSRect outside = [NSWindow frameRectForContentRect:inside styleMask:NSTitledWindowMask]; + bx = int(outside.origin.x - inside.origin.x); + by = int(outside.origin.y - inside.origin.y); + bt = int(outside.size.height - inside.size.height - by); +} + +/* + * smallest x ccordinate in screen space + */ +int Fl::x() { + return int([[NSScreen mainScreen] visibleFrame].origin.x); +} + + +/* + * smallest y coordinate in screen space + */ +int Fl::y() { + NSRect all = [[NSScreen mainScreen] frame]; + NSRect visible = [[NSScreen mainScreen] visibleFrame]; + return int(all.size.height - (visible.origin.y + visible.size.height)); +} + + +/* + * screen width + */ +int Fl::w() { + return int([[NSScreen mainScreen] visibleFrame].size.width); +} + + +/* + * screen height + */ +int Fl::h() { + return int([[NSScreen mainScreen] visibleFrame].size.height); +} + + +/* + * get the current mouse pointer world coordinates + */ +void Fl::get_mouse(int &x, int &y) +{ + fl_open_display(); + NSPoint pt = [NSEvent mouseLocation]; + x = int(pt.x); + y = int([[NSScreen mainScreen] frame].size.height - pt.y); +} + + +/* + * Initialize the given port for redraw and call the window's flush() to actually draw the content + */ +void Fl_X::flush() +{ + w->flush(); + if (fl_gc) CGContextFlush(fl_gc); +} + +/* + * Gets called when a window is created, resized, or deminiaturized + */ +static void handleUpdateEvent( Fl_Window *window ) +{ + if ( !window ) return; + Fl_X *i = Fl_X::i( window ); + i->wait_for_expose = 0; + + if ( i->region ) { + XDestroyRegion(i->region); + i->region = 0; + } + + for ( Fl_X *cx = i->xidChildren; cx; cx = cx->xidNext ) { + if ( cx->region ) { + XDestroyRegion(cx->region); + cx->region = 0; + } + cx->w->clear_damage(FL_DAMAGE_ALL); + cx->flush(); + cx->w->clear_damage(); + } + window->clear_damage(FL_DAMAGE_ALL); + i->flush(); + window->clear_damage(); +} + + +int Fl_X::fake_X_wm(const Fl_Window* w,int &X,int &Y, int &bt,int &bx, int &by) { + int W, H, xoff, yoff, dx, dy; + int ret = bx = by = bt = 0; + if (w->border() && !w->parent()) { + if (w->maxw != w->minw || w->maxh != w->minh) { + ret = 2; + get_window_frame_sizes(bx, by, bt); + } else { + ret = 1; + get_window_frame_sizes(bx, by, bt); + } + } + // The coordinates of the whole window, including non-client area + xoff = bx; + yoff = by + bt; + dx = 2*bx; + dy = 2*by + bt; + X = w->x()-xoff; + Y = w->y()-yoff; + W = w->w()+dx; + H = w->h()+dy; + + // Proceed to positioning the window fully inside the screen, if possible + + // let's get a little elaborate here. Mac OS X puts a lot of stuff on the desk + // that we want to avoid when positioning our window, namely the Dock and the + // top menu bar (and even more stuff in 10.4 Tiger). So we will go through the + // list of all available screens and find the one that this window is most + // likely to go to, and then reposition it to fit withing the 'good' area. + // Rect r; + // find the screen, that the center of this window will fall into + int R = X+W, B = Y+H; // right and bottom + int cx = (X+R)/2, cy = (Y+B)/2; // center of window; + NSScreen *gd = NULL; + NSArray *a = [NSScreen screens]; int count = (int)[a count]; NSRect r; int i; + for( i = 0; i < count; i++) { + r = [[a objectAtIndex:i] frame]; + cy = int(r.size.height - cy); + if ( cx >= r.origin.x && cx <= r.origin.x + r.size.width + && cy >= r.origin.y && cy <= r.origin.y + r.size.height) + break; + } + if (i < count) gd = [a objectAtIndex:i]; + + // if the center doesn't fall on a screen, try the top left + if (!gd) { + for( i = 0; i < count; i++) { + r = [[a objectAtIndex:i] frame]; + if ( X >= r.origin.x && X <= r.origin.x + r.size.width + && r.size.height - Y >= r.origin.y && r.size.height - Y <= r.origin.y + r.size.height) + break; + } + if (i < count) gd = [a objectAtIndex:i]; + } + // if that doesn't fall on a screen, try the top right + if (!gd) { + for( i = 0; i < count; i++) { + r = [[a objectAtIndex:i] frame]; + if ( R >= r.origin.x && R <= r.origin.x + r.size.width + && r.size.height - Y >= r.origin.y && r.size.height - Y <= r.origin.y + r.size.height) + break; + } + if (i < count) gd = [a objectAtIndex:i]; + } + // if that doesn't fall on a screen, try the bottom left + if (!gd) { + for( i = 0; i < count; i++) { + r = [[a objectAtIndex:i] frame]; + if ( X >= r.origin.x && X <= r.origin.x + r.size.width + && Y-H >= r.origin.y && Y-H <= r.origin.y + r.size.height) + break; + } + if (i < count) gd = [a objectAtIndex:i]; + } + // last resort, try the bottom right + if (!gd) { + for( i = 0; i < count; i++) { + r = [[a objectAtIndex:i] frame]; + if ( R >= r.origin.x && R <= r.origin.x + r.size.width + && Y-H >= r.origin.y && Y-H <= r.origin.y + r.size.height) + break; + } + if (i < count) gd = [a objectAtIndex:i]; + } + // if we still have not found a screen, we will use the main + // screen, the one that has the application menu bar. + if (!gd) gd = [a objectAtIndex:0]; + if (gd) { + r = [gd visibleFrame]; + int sh = int([gd frame].size.height); + if ( R > r.origin.x + r.size.width ) X -= int(R - (r.origin.x + r.size.width)); + if ( B > sh - r.origin.y ) Y -= int(B - (sh - r.origin.y)); + if ( X < r.origin.x ) X = int(r.origin.x); + if ( Y < sh - (r.origin.y + r.size.height) ) Y = int(sh - (r.origin.y + r.size.height)); + } + + // Return the client area's top left corner in (X,Y) + X+=xoff; + Y+=yoff; + + return ret; +} + + +Fl_Window *fl_dnd_target_window = 0; + +static void q_set_window_title(NSWindow *nsw, const char * name ) { + CFStringRef utf8_title = CFStringCreateWithCString(NULL, (name ? name : ""), kCFStringEncodingUTF8); + [nsw setTitle:(NSString*)utf8_title ]; + CFRelease(utf8_title); +} + + +@interface FLView : NSView { +} +- (void)drawRect:(NSRect)rect; +- (BOOL)acceptsFirstResponder; +- (BOOL)acceptsFirstMouse:(NSEvent*)theEvent; +- (BOOL)performKeyEquivalent:(NSEvent*)theEvent; +- (void)mouseUp:(NSEvent *)theEvent; +- (void)rightMouseUp:(NSEvent *)theEvent; +- (void)otherMouseUp:(NSEvent *)theEvent; +- (void)mouseDown:(NSEvent *)theEvent; +- (void)rightMouseDown:(NSEvent *)theEvent; +- (void)otherMouseDown:(NSEvent *)theEvent; +- (void)mouseDragged:(NSEvent *)theEvent; +- (void)rightMouseDragged:(NSEvent *)theEvent; +- (void)otherMouseDragged:(NSEvent *)theEvent; +- (void)scrollWheel:(NSEvent *)theEvent; +- (void)keyDown:(NSEvent *)theEvent; +- (void)keyUp:(NSEvent *)theEvent; +- (void)flagsChanged:(NSEvent *)theEvent; +- (NSDragOperation)draggingEntered:(id < NSDraggingInfo >)sender; +- (NSDragOperation)draggingUpdated:(id < NSDraggingInfo >)sender; +- (BOOL)performDragOperation:(id )sender; +- (void)draggingExited:(id < NSDraggingInfo >)sender; +- (NSDragOperation)draggingSourceOperationMaskForLocal:(BOOL)isLocal; +@end + +@implementation FLView +- (void)drawRect:(NSRect)rect +{ + FLWindow *cw = (FLWindow*)[self window]; + Fl_Window *w = [cw getFl_Window]; + handleUpdateEvent(w); +} + +- (BOOL)acceptsFirstResponder +{ + return YES; +} +- (BOOL)performKeyEquivalent:(NSEvent*)theEvent +{ + OSStatus err = cocoaKeyboardHandler(theEvent); + return (err ? NO : YES); +} +- (BOOL)acceptsFirstMouse:(NSEvent*)theEvent +{ + Fl_Window *w = [(FLWindow*)[theEvent window] getFl_Window]; + Fl_Window *first = Fl::first_window(); + return (first == w || !first->modal()); +} +- (void)mouseUp:(NSEvent *)theEvent { + cocoaMouseHandler(theEvent); +} +- (void)rightMouseUp:(NSEvent *)theEvent { + cocoaMouseHandler(theEvent); +} +- (void)otherMouseUp:(NSEvent *)theEvent { + cocoaMouseHandler(theEvent); +} +- (void)mouseDown:(NSEvent *)theEvent { + cocoaMouseHandler(theEvent); +} +- (void)rightMouseDown:(NSEvent *)theEvent { + cocoaMouseHandler(theEvent); +} +- (void)otherMouseDown:(NSEvent *)theEvent { + cocoaMouseHandler(theEvent); +} +- (void)mouseMoved:(NSEvent *)theEvent { + cocoaMouseHandler(theEvent); +} +- (void)mouseDragged:(NSEvent *)theEvent { + cocoaMouseHandler(theEvent); +} +- (void)rightMouseDragged:(NSEvent *)theEvent { + cocoaMouseHandler(theEvent); +} +- (void)otherMouseDragged:(NSEvent *)theEvent { + cocoaMouseHandler(theEvent); +} +- (void)scrollWheel:(NSEvent *)theEvent { + cocoaMouseWheelHandler(theEvent); +} +- (void)keyDown:(NSEvent *)theEvent { + FLTextView *edit = (FLTextView*)[[theEvent window] fieldEditor:YES forObject:nil]; + if ([[theEvent characters] length] == 0) [edit compose:YES]; + if (Fl::compose_state) [edit needKBhandler:YES]; + else [edit needKBhandler:NO]; + [edit interpretKeyEvents:[NSArray arrayWithObject:theEvent]]; + // in some cases (e.g., some Greek letters with tonos) interpretKeyEvents does not call insertText + if ([edit needKBhandler]) cocoaKeyboardHandler(theEvent); +} +- (void)keyUp:(NSEvent *)theEvent { + cocoaKeyboardHandler(theEvent); +} +- (void)flagsChanged:(NSEvent *)theEvent { + fl_lock_function(); + static UInt32 prevMods = 0; + NSUInteger mods = [theEvent modifierFlags]; + Fl_Window *window = (Fl_Window*)[(FLWindow*)[theEvent window] getFl_Window]; + UInt32 tMods = prevMods ^ mods; + int sendEvent = 0; + if ( tMods ) + { + mods_to_e_keysym( tMods ); + if ( Fl::e_keysym ) + sendEvent = ( prevModsparent()) window = window->window(); + if (sendEvent) Fl::handle(sendEvent,window); + fl_unlock_function(); +} +- (NSDragOperation)draggingEntered:(id < NSDraggingInfo >)sender +{ + Fl_Window *target = [(FLWindow*)[self window] getFl_Window]; + update_e_xy_and_e_xy_root([self window]); + fl_dnd_target_window = target; + int ret = Fl::handle( FL_DND_ENTER, target ); + breakMacEventLoop(); + return ret ? NSDragOperationCopy : NSDragOperationNone; +} +- (NSDragOperation)draggingUpdated:(id < NSDraggingInfo >)sender +{ + Fl_Window *target = [(FLWindow*)[self window] getFl_Window]; + update_e_xy_and_e_xy_root([self window]); + fl_dnd_target_window = target; + int ret = Fl::handle( FL_DND_DRAG, target ); + breakMacEventLoop(); + return ret ? NSDragOperationCopy : NSDragOperationNone; +} +- (BOOL)performDragOperation:(id )sender +{ + static char *DragData = NULL; + Fl_Window *target = [(FLWindow*)[self window] getFl_Window]; + if ( !Fl::handle( FL_DND_RELEASE, target ) ) { + breakMacEventLoop(); + return NO; + } + NSPasteboard *pboard; + // NSDragOperation sourceDragMask; + // sourceDragMask = [sender draggingSourceOperationMask]; + pboard = [sender draggingPasteboard]; + update_e_xy_and_e_xy_root([self window]); + if (DragData) { free(DragData); DragData = NULL; } + if ( [[pboard types] containsObject:NSFilenamesPboardType] ) { + CFArrayRef files = (CFArrayRef)[pboard propertyListForType:NSFilenamesPboardType]; + CFStringRef all = CFStringCreateByCombiningStrings(NULL, files, CFSTR("\n")); + int l = CFStringGetMaximumSizeForEncoding(CFStringGetLength(all), kCFStringEncodingUTF8); + DragData = (char *)malloc(l + 1); + CFStringGetCString(all, DragData, l + 1, kCFStringEncodingUTF8); + CFRelease(all); + } + else if ( [[pboard types] containsObject:NSStringPboardType] ) { + NSData *data = [pboard dataForType:NSStringPboardType]; + DragData = (char *)malloc([data length] + 1); + [data getBytes:DragData]; + DragData[[data length]] = 0; + convert_crlf(DragData, strlen(DragData)); + } + else { + breakMacEventLoop(); + return NO; + } + Fl::e_text = DragData; + Fl::e_length = strlen(DragData); + int old_event = Fl::e_number; + Fl::belowmouse()->handle(Fl::e_number = FL_PASTE); + Fl::e_number = old_event; + if (DragData) { free(DragData); DragData = NULL; } + Fl::e_text = NULL; + Fl::e_length = 0; + fl_dnd_target_window = NULL; + breakMacEventLoop(); + return YES; +} +- (void)draggingExited:(id < NSDraggingInfo >)sender +{ + if ( fl_dnd_target_window ) { + Fl::handle( FL_DND_LEAVE, fl_dnd_target_window ); + fl_dnd_target_window = 0; + } +} +- (NSDragOperation)draggingSourceOperationMaskForLocal:(BOOL)isLocal +{ + return NSDragOperationGeneric; +} +@end + + +/* + * go ahead, create that (sub)window + * \todo we should make menu windows slightly transparent for the new Mac look + */ +void Fl_X::make(Fl_Window* w) +{ + static int xyPos = 100; + if ( w->parent() ) { // create a subwindow + Fl_Group::current(0); + // our subwindow needs this structure to know about its clipping. + Fl_X* x = new Fl_X; + x->other_xid = 0; + x->region = 0; + x->subRegion = 0; + x->cursor = fl_default_cursor; + x->gc = 0; // stay 0 for Quickdraw; fill with CGContext for Quartz + Fl_Window *win = w->window(); + Fl_X *xo = Fl_X::i(win); + if (xo) { + x->xidNext = xo->xidChildren; + x->xidChildren = 0L; + xo->xidChildren = x; + x->xid = win->i->xid; + x->w = w; w->i = x; + x->wait_for_expose = 0; + { + Fl_X *z = xo->next; // we don't want a subwindow in Fl_X::first + xo->next = x; + x->next = z; + } + int old_event = Fl::e_number; + w->handle(Fl::e_number = FL_SHOW); + Fl::e_number = old_event; + w->redraw(); // force draw to happen + } + fl_show_iconic = 0; + } + else { // create a desktop window + NSAutoreleasePool *localPool; + localPool = [[NSAutoreleasePool alloc] init]; + Fl_Group::current(0); + fl_open_display(); + NSInteger winlevel = NSNormalWindowLevel; + NSUInteger winstyle; + if (w->border()) winstyle = NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask; + else winstyle = NSBorderlessWindowMask; + int xp = w->x(); + int yp = w->y(); + int wp = w->w(); + int hp = w->h(); + if (w->size_range_set) { + if ( w->minh != w->maxh || w->minw != w->maxw) { + winstyle |= NSResizableWindowMask; + } + } else { + if (w->resizable()) { + Fl_Widget *o = w->resizable(); + int minw = o->w(); if (minw > 100) minw = 100; + int minh = o->h(); if (minh > 100) minh = 100; + w->size_range(w->w() - o->w() + minw, w->h() - o->h() + minh, 0, 0); + winstyle |= NSResizableWindowMask; + } else { + w->size_range(w->w(), w->h(), w->w(), w->h()); + } + } + int xwm = xp, ywm = yp, bt, bx, by; + + if (!fake_X_wm(w, xwm, ywm, bt, bx, by)) { + // menu windows and tooltips + if (w->modal()||w->override()) { + winstyle = NSBorderlessWindowMask; + winlevel = NSMainMenuWindowLevel; + } else { + winstyle = NSBorderlessWindowMask; + } + } else if (w->modal()) { + winstyle &= ~NSMiniaturizableWindowMask; + // winstyle &= ~(NSResizableWindowMask | NSMiniaturizableWindowMask); + // winlevel = NSModalPanelWindowLevel; + } + else if (w->non_modal()) { + winlevel = NSFloatingWindowLevel; + } + + if (by+bt) { + wp += 2*bx; + hp += 2*by+bt; + } + if (!(w->flags() & Fl_Window::FORCE_POSITION)) { + // use the Carbon functions below for default window positioning + w->x(xyPos+Fl::x()); + w->y(xyPos+Fl::y()); + xyPos += 25; + if (xyPos>200) xyPos = 100; + } else { + if (!Fl::grab()) { + xp = xwm; yp = ywm; + w->x(xp);w->y(yp); + } + xp -= bx; + yp -= by+bt; + } + + if (w->non_modal() && Fl_X::first && !fl_disable_transient_for) { + // find some other window to be "transient for": + Fl_Window* w = Fl_X::first->w; + while (w->parent()) w = w->window(); // todo: this code does not make any sense! (w!=w??) + } + + const char *name = w->label(); + + Fl_X* x = new Fl_X; + x->other_xid = 0; // room for doublebuffering image map. On OS X this is only used by overlay windows + x->region = 0; + x->subRegion = 0; + x->cursor = fl_default_cursor; + x->xidChildren = 0; + x->xidNext = 0; + x->gc = 0; + + NSRect srect = [[NSScreen mainScreen] frame]; + NSRect crect; + crect.origin.x = w->x(); + crect.origin.y = srect.size.height - (w->y() + w->h()); + crect.size.width=w->w(); + crect.size.height=w->h(); + FLWindow *cw = [[FLWindow alloc] initWithFl_W:w + contentRect:crect + styleMask:winstyle + backing:NSBackingStoreBuffered + defer:NO]; + [cw setAcceptsMouseMovedEvents:YES]; + x->xid = cw; + FLView *myview = [[FLView alloc] init]; + [cw setContentView:myview]; + [cw setLevel:winlevel]; + + q_set_window_title(cw, name); + if (!(w->flags() & Fl_Window::FORCE_POSITION)) { + if (w->modal()) { + [cw center]; + } else if (w->non_modal()) { + [cw center]; + } else { + static NSPoint delta = NSZeroPoint; + delta = [cw cascadeTopLeftFromPoint:delta]; + } + } + x->w = w; w->i = x; + x->wait_for_expose = 1; + x->next = Fl_X::first; + Fl_X::first = x; + // Install DnD handlers + [myview registerForDraggedTypes:[NSArray arrayWithObjects: + NSStringPboardType, NSFilenamesPboardType, nil]]; + if ( ! Fl_X::first->next ) { // if this is the first window, we need to bring the application to the front + ProcessSerialNumber psn; + OSErr err = GetCurrentProcess( &psn ); + if ( err==noErr ) SetFrontProcess( &psn ); + } + + if (w->size_range_set) w->size_range_(); + + if (winlevel != NSMainMenuWindowLevel) { + Fl_Tooltip::enter(0); + } + [cw makeKeyAndOrderFront:nil]; + Fl::first_window(w); + [cw setDelegate:mydelegate]; + if (fl_show_iconic) { + fl_show_iconic = 0; + [cw miniaturize:nil]; + } else { + w->set_visible(); + } + + crect = [[cw contentView] frame]; + w->w(int(crect.size.width)); + w->h(int(crect.size.height)); + crect = [cw frame]; + w->x(int(crect.origin.x)); + srect = [[cw screen] frame]; + w->y(int(srect.size.height - (crect.origin.y + w->h()))); + + int old_event = Fl::e_number; + w->handle(Fl::e_number = FL_SHOW); + Fl::e_number = old_event; + + if (w->modal()) { Fl::modal_ = w; fl_fix_focus(); } + [localPool release]; + } +} + + +/* + * Tell the OS what window sizes we want to allow + */ +void Fl_Window::size_range_() { + int bx, by, bt; + get_window_frame_sizes(bx, by, bt); + size_range_set = 1; + NSSize minSize = { minw, minh + bt }; + NSSize maxSize = { maxw?maxw:32000, maxh?maxh + bt:32000 }; + if (i && i->xid) { + [(NSWindow*)i->xid setMinSize:minSize]; + [(NSWindow*)i->xid setMaxSize:maxSize]; + } +} + + +/* + * returns pointer to the filename, or null if name ends with ':' + */ +const char *fl_filename_name( const char *name ) +{ + const char *p, *q; + if (!name) return (0); + for ( p = q = name ; *p ; ) { + if ( ( p[0] == ':' ) && ( p[1] == ':' ) ) { + q = p+2; + p++; + } + else if (p[0] == '/') { + q = p + 1; + } + p++; + } + return q; +} + + +/* + * set the window title bar + * \todo make the titlebar icon work! + */ +void Fl_Window::label(const char *name,const char */*iname*/) { + Fl_Widget::label(name); + if (shown() || i) { + q_set_window_title((NSWindow*)i->xid, name); + } +} + + +/* + * make a window visible + */ +void Fl_Window::show() { + image(Fl::scheme_bg_); + if (Fl::scheme_bg_) { + labeltype(FL_NORMAL_LABEL); + align(FL_ALIGN_CENTER | FL_ALIGN_INSIDE | FL_ALIGN_CLIP); + } else { + labeltype(FL_NO_LABEL); + } + Fl_Tooltip::exit(this); + if (!shown() || !i) { + Fl_X::make(this); + } else { + if ( !parent() ) { + if ([(NSWindow*)i->xid isMiniaturized]) { + i->w->redraw(); + [(NSWindow*)i->xid deminiaturize:nil]; + } + if (!fl_capture) { + [(NSWindow*)i->xid makeKeyAndOrderFront:nil]; + } + } + } +} + + +/* + * resize a window + */ +void Fl_Window::resize(int X,int Y,int W,int H) { + int bx, by, bt; + if ( ! this->border() ) bt = 0; + else get_window_frame_sizes(bx, by, bt); + if (W<=0) W = 1; // OS X does not like zero width windows + if (H<=0) H = 1; + int is_a_resize = (W != w() || H != h()); + // printf("Fl_Window::resize(X=%d, Y=%d, W=%d, H=%d), is_a_resize=%d, resize_from_system=%p, this=%p\n", + // X, Y, W, H, is_a_resize, resize_from_system, this); + if (X != x() || Y != y()) set_flag(FORCE_POSITION); + else if (!is_a_resize) return; + if ( (resize_from_system!=this) && (!parent()) && shown()) { + if (is_a_resize) { + if (resizable()) { + if (Wmaxw) maxw = W; // over a previously set size_range + if (Hmaxh) maxh = H; + size_range(minw, minh, maxw, maxh); + } else { + size_range(W, H, W, H); + } + NSRect dim; + dim.origin.x = X; + dim.origin.y = [[(NSWindow*)i->xid screen] frame].size.height - (Y + H); + dim.size.width = W; + dim.size.height = H + bt; + [(NSWindow*)i->xid setFrame:dim display:YES]; + } else { + NSPoint pt; + pt.x = X; + pt.y = [[(NSWindow*)i->xid screen] frame].size.height - (Y + h()); + [(NSWindow*)i->xid setFrameOrigin:pt]; + } + } + resize_from_system = 0; + if (is_a_resize) { + Fl_Group::resize(X,Y,W,H); + if (shown()) { + redraw(); + } + } else { + x(X); y(Y); + } +} + + +/* + * make all drawing go into this window (called by subclass flush() impl.) + */ +void Fl_Window::make_current() +{ + Fl_X::q_release_context(); + fl_window = i->xid; + current_ = this; + + int xp = 0, yp = 0; + Fl_Window *win = this; + while ( win ) { + if ( !win->window() ) + break; + xp += win->x(); + yp += win->y(); + win = (Fl_Window*)win->window(); + } + + NSView *current_focus = [NSView focusView]; + // sometimes current_focus is set to a non-FLTK view: don't touch that + if ( [current_focus isKindOfClass:[FLView class]] ) [current_focus unlockFocus]; + [[(NSWindow*)i->xid contentView] lockFocus]; + i->gc = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort]; + fl_gc = i->gc; + Fl_Region fl_window_region = XRectangleRegion(0,0,w(),h()); + if ( ! this->window() ) { + for ( Fl_X *cx = i->xidChildren; cx; cx = cx->xidNext ) { // clip-out all sub-windows + Fl_Window *cw = cx->w; + Fl_Region from = fl_window_region; + fl_window_region = MacRegionMinusRect(from, cw->x(), cw->y(), cw->w(), cw->h() ); + XDestroyRegion(from); + } + } + + // antialiasing must be deactivated because it applies to rectangles too + // and escapes even clipping!!! + // it gets activated when needed (e.g., draw text) + CGContextSetShouldAntialias(fl_gc, false); + CGFloat hgt = [[(NSWindow*)fl_window contentView] frame].size.height; + CGContextTranslateCTM(fl_gc, 0.5, hgt-0.5f); + CGContextScaleCTM(fl_gc, 1.0f, -1.0f); // now 0,0 is top-left point of the window + win = this; + while(win && win->window()) { // translate to subwindow origin if this is a subwindow context + CGContextTranslateCTM(fl_gc, win->x(), win->y()); + win = win->window(); + } + //apply window's clip + CGContextClipToRects(fl_gc, fl_window_region->rects, fl_window_region->count ); + XDestroyRegion(fl_window_region); +// this is the context with origin at top left of (sub)window clipped out of its subwindows if any + CGContextSaveGState(fl_gc); +#if defined(USE_CAIRO) + if (Fl::cairo_autolink_context()) Fl::cairo_make_current(this); // capture gc changes automatically to update the cairo context adequately +#endif + fl_clip_region( 0 ); + +#if defined(USE_CAIRO) + // update the cairo_t context + if (Fl::cairo_autolink_context()) Fl::cairo_make_current(this); +#endif +} + +// helper function to manage the current CGContext fl_gc +extern Fl_Color fl_color_; +extern class Fl_Font_Descriptor *fl_fontsize; +extern void fl_font(class Fl_Font_Descriptor*); +extern void fl_quartz_restore_line_style_(); + +// FLTK has only one global graphics state. This function copies the FLTK state into the +// current Quartz context +void Fl_X::q_fill_context() { + if (!fl_gc) return; + if ( ! fl_window) { // a bitmap context + size_t hgt = CGBitmapContextGetHeight(fl_gc); + CGContextTranslateCTM(fl_gc, 0.5, hgt-0.5f); + CGContextScaleCTM(fl_gc, 1.0f, -1.0f); // now 0,0 is top-left point of the context + } + fl_font(fl_fontsize); + fl_color(fl_color_); + fl_quartz_restore_line_style_(); +} + +// The only way to reset clipping to its original state is to pop the current graphics +// state and restore the global state. +void Fl_X::q_clear_clipping() { + if (!fl_gc) return; + CGContextRestoreGState(fl_gc); + CGContextSaveGState(fl_gc); +} + +// Give the Quartz context back to the system +void Fl_X::q_release_context(Fl_X *x) { + if (x && x->gc!=fl_gc) return; + if (!fl_gc) return; + CGContextRestoreGState(fl_gc); // matches the CGContextSaveGState of make_current + fl_gc = 0; +#if defined(USE_CAIRO) + if (Fl::cairo_autolink_context()) Fl::cairo_make_current((Fl_Window*) 0); // capture gc changes automatically to update the cairo context adequately +#endif +} + +/* the former implementation +void Fl_X::q_begin_image(CGRect &rect, int cx, int cy, int w, int h) { + CGContextSaveGState(fl_gc); + CGAffineTransform mx = CGContextGetCTM(fl_gc); + CGRect r2 = rect; + r2.origin.x -= 0.5f; + r2.origin.y -= 0.5f; + CGContextClipToRect(fl_gc, r2); + mx.d = -1.0; mx.tx = -mx.tx; + CGContextConcatCTM(fl_gc, mx); + rect.origin.x = -(mx.tx+0.5f) + rect.origin.x - cx; + rect.origin.y = (mx.ty+0.5f) - rect.origin.y - h + cy; + rect.size.width = w; + rect.size.height = h; +} +*/ +void Fl_X::q_begin_image(CGRect &rect, int cx, int cy, int w, int h) { + CGContextSaveGState(fl_gc); + CGRect r2 = rect; + r2.origin.x -= 0.5f; + r2.origin.y -= 0.5f; + CGContextClipToRect(fl_gc, r2); + // move graphics context to origin of vertically reversed image + CGContextTranslateCTM(fl_gc, rect.origin.x - cx - 0.5, rect.origin.y - cy + h - 0.5); + CGContextScaleCTM(fl_gc, 1, -1); + rect.origin.x = rect.origin.y = 0; + rect.size.width = w; + rect.size.height = h; +} + +void Fl_X::q_end_image() { + CGContextRestoreGState(fl_gc); +} + + +//////////////////////////////////////////////////////////////// +// Copy & Paste fltk implementation. +//////////////////////////////////////////////////////////////// + +static void convert_crlf(char * s, size_t len) +{ + // turn all \r characters into \n: + for (size_t x = 0; x < len; x++) if (s[x] == '\r') s[x] = '\n'; +} + +// fltk 1.3 clipboard support constant definitions: +const CFStringRef flavorNames[] = { + CFSTR("public.utf16-plain-text"), + CFSTR("public.utf8-plain-text"), + CFSTR("com.apple.traditional-mac-plain-text") }; +const CFStringEncoding encodings[] = { + kCFStringEncodingUnicode, + kCFStringEncodingUTF8, + kCFStringEncodingMacRoman}; +const size_t handledFlavorsCount = sizeof(encodings)/sizeof(CFStringEncoding); + +// clipboard variables definitions : +Fl_Widget *fl_selection_requestor = 0; +char *fl_selection_buffer[2]; +int fl_selection_length[2]; +static int fl_selection_buffer_length[2]; + +static PasteboardRef myPasteboard = 0; +static void allocatePasteboard() { + if (!myPasteboard) + PasteboardCreate(kPasteboardClipboard, &myPasteboard); +} + + +/* + * create a selection + * owner: widget that created the selection + * stuff: pointer to selected data + * size of selected data + */ +void Fl::copy(const char *stuff, int len, int clipboard) { + if (!stuff || len<0) return; + if (len+1 > fl_selection_buffer_length[clipboard]) { + delete[] fl_selection_buffer[clipboard]; + fl_selection_buffer[clipboard] = new char[len+100]; + fl_selection_buffer_length[clipboard] = len+100; + } + memcpy(fl_selection_buffer[clipboard], stuff, len); + fl_selection_buffer[clipboard][len] = 0; // needed for direct paste + fl_selection_length[clipboard] = len; + if (clipboard) { + allocatePasteboard(); + OSStatus err = PasteboardClear(myPasteboard); + if (err!=noErr) return; // clear did not work, maybe not owner of clipboard. + PasteboardSynchronize(myPasteboard); + CFDataRef text = CFDataCreate(kCFAllocatorDefault, (UInt8*)fl_selection_buffer[1], len); + if (text==NULL) return; // there was a pb creating the object, abort. + err=PasteboardPutItemFlavor(myPasteboard, (PasteboardItemID)1, CFSTR("public.utf8-plain-text"), text, 0); + CFRelease(text); + } +} + +// Call this when a "paste" operation happens: +void Fl::paste(Fl_Widget &receiver, int clipboard) { + if (clipboard) { + // see if we own the selection, if not go get it: + fl_selection_length[1] = 0; + OSStatus err = noErr; + Boolean found = false; + CFDataRef flavorData = NULL; + CFStringEncoding encoding = 0; + + allocatePasteboard(); + PasteboardSynchronize(myPasteboard); + ItemCount nFlavor = 0, i, j; + err = PasteboardGetItemCount(myPasteboard, &nFlavor); + if (err==noErr) { + for (i=1; i<=nFlavor; i++) { + PasteboardItemID itemID = 0; + CFArrayRef flavorTypeArray = NULL; + found = false; + err = PasteboardGetItemIdentifier(myPasteboard, i, &itemID); + if (err!=noErr) continue; + err = PasteboardCopyItemFlavors(myPasteboard, itemID, &flavorTypeArray); + if (err!=noErr) { + if (flavorTypeArray) {CFRelease(flavorTypeArray); flavorTypeArray = NULL;} + continue; + } + CFIndex flavorCount = CFArrayGetCount(flavorTypeArray); + for (j = 0; j < handledFlavorsCount; j++) { + for (CFIndex flavorIndex=0; flavorIndex= fl_selection_buffer_length[1] ) { + fl_selection_buffer_length[1] = len; + delete[] fl_selection_buffer[1]; + fl_selection_buffer[1] = new char[len]; + } + CFStringGetCString(mycfs, fl_selection_buffer[1], len, kCFStringEncodingUTF8); + CFRelease(mycfs); + len = strlen(fl_selection_buffer[1]); + fl_selection_length[1] = len; + convert_crlf(fl_selection_buffer[1],len); // turn all \r characters into \n: + } + } + } + Fl::e_text = fl_selection_buffer[clipboard]; + Fl::e_length = fl_selection_length[clipboard]; + if (!Fl::e_text) Fl::e_text = (char *)""; + receiver.handle(FL_PASTE); +} + +void Fl::add_timeout(double time, Fl_Timeout_Handler cb, void* data) +{ + // check, if this timer slot exists already + for (int i = 0; i < mac_timer_used; ++i) { + MacTimeout& t = mac_timers[i]; + // if so, simply change the fire interval + if (t.callback == cb && t.data == data) { + CFRunLoopTimerSetNextFireDate(t.timer, CFAbsoluteTimeGetCurrent() + time ); + t.pending = 1; + return; + } + } + // no existing timer to use. Create a new one: + int timer_id = -1; + // find an empty slot in the timer array + for (int i = 0; i < mac_timer_used; ++i) { + if ( !mac_timers[i].timer ) { + timer_id = i; + break; + } + } + // if there was no empty slot, append a new timer + if (timer_id == -1) { + // make space if needed + if (mac_timer_used == mac_timer_alloc) { + realloc_timers(); + } + timer_id = mac_timer_used++; + } + // now install a brand new timer + MacTimeout& t = mac_timers[timer_id]; + CFRunLoopTimerContext context = {0, data, NULL,NULL,NULL}; + CFRunLoopTimerRef timerRef = CFRunLoopTimerCreate(kCFAllocatorDefault, + CFAbsoluteTimeGetCurrent() + time, + 1E30, + 0, + 0, + do_timer, + &context + ); + if (timerRef) { + CFRunLoopAddTimer(CFRunLoopGetCurrent(), + timerRef, + kCFRunLoopDefaultMode); + t.callback = cb; + t.data = data; + t.timer = timerRef; + t.pending = 1; + } +} + +void Fl::repeat_timeout(double time, Fl_Timeout_Handler cb, void* data) +{ + // currently, repeat_timeout does not subtract the trigger time of the previous timer event as it should. + add_timeout(time, cb, data); +} + +int Fl::has_timeout(Fl_Timeout_Handler cb, void* data) +{ + for (int i = 0; i < mac_timer_used; ++i) { + MacTimeout& t = mac_timers[i]; + if (t.callback == cb && t.data == data && t.pending) { + return 1; + } + } + return 0; +} + +void Fl::remove_timeout(Fl_Timeout_Handler cb, void* data) +{ + for (int i = 0; i < mac_timer_used; ++i) { + MacTimeout& t = mac_timers[i]; + if (t.callback == cb && ( t.data == data || data == NULL)) { + delete_timer(t); + } + } + breakMacEventLoop(); +} + +int MacUnlinkWindow(Fl_X *ip, Fl_X *start) { + if (!ip) return 0; + if (start) { + Fl_X *pc = start; + while (pc) { + if (pc->xidNext == ip) { + pc->xidNext = ip->xidNext; + return 1; + } + if (pc->xidChildren) { + if (pc->xidChildren == ip) { + pc->xidChildren = ip->xidNext; + return 1; + } + if (MacUnlinkWindow(ip, pc->xidChildren)) + return 1; + } + pc = pc->xidNext; + } + } else { + for ( Fl_X *pc = Fl_X::first; pc; pc = pc->next ) { + if (MacUnlinkWindow(ip, pc)) + return 1; + } + } + return 0; +} + +static void MacRelinkWindow(Fl_X *x, Fl_X *p) { + if (!x || !p) return; + // first, check if 'x' is already registered as a child of 'p' + for (Fl_X *i = p->xidChildren; i; i=i->xidNext) { + if (i == x) return; + } + // now add 'x' as the first child of 'p' + x->xidNext = p->xidChildren; + p->xidChildren = x; +} + +void MacDestroyWindow(Fl_Window *w, void *p) { + if (w && !w->parent() && p) { + [[(NSWindow *)p contentView] release]; + [(NSWindow *)p close]; + } +} + +void MacMapWindow(Fl_Window *w, void *p) { + if (w && p) { + [(NSWindow *)p orderFront:nil]; + } + //+ link to window list + if (w && w->parent()) { + MacRelinkWindow(Fl_X::i(w), Fl_X::i(w->window())); + w->redraw(); + } +} + +void MacUnmapWindow(Fl_Window *w, void *p) { + if (w && !w->parent() && p) { + [(NSWindow *)p orderOut:nil]; + } + if (w && Fl_X::i(w)) + MacUnlinkWindow(Fl_X::i(w)); +} + +static Fl_Region MacRegionMinusRect(Fl_Region r, int x,int y,int w,int h) +/* removes x,y,w,h rectangle from region r and returns result as a new Fl_Region + */ +{ + Fl_Region outr = (Fl_Region)malloc(sizeof(*outr)); + outr->rects = (CGRect*)malloc(4 * r->count * sizeof(CGRect)); + outr->count = 0; + CGRect rect = fl_cgrectmake_cocoa(x, y, w, h); + for( int i = 0; i < r->count; i++) { + CGRect A = r->rects[i]; + CGRect test = CGRectIntersection(A, rect); + if (CGRectIsEmpty(test)) { + outr->rects[(outr->count)++] = A; + } + else { + const CGFloat verylarge = 100000.; + CGRect side = CGRectMake(0,0,rect.origin.x,verylarge);// W side + test = CGRectIntersection(A, side); + if ( ! CGRectIsEmpty(test)) { + outr->rects[(outr->count)++] = test; + } + side = CGRectMake(0,rect.origin.y + rect.size.height,verylarge,verylarge);// N side + test = CGRectIntersection(A, side); + if ( ! CGRectIsEmpty(test)) { + outr->rects[(outr->count)++] = test; + } + side = CGRectMake(rect.origin.x + rect.size.width, 0, verylarge, verylarge);// E side + test = CGRectIntersection(A, side); + if ( ! CGRectIsEmpty(test)) { + outr->rects[(outr->count)++] = test; + } + side = CGRectMake(0, 0, verylarge, rect.origin.y);// S side + test = CGRectIntersection(A, side); + if ( ! CGRectIsEmpty(test)) { + outr->rects[(outr->count)++] = test; + } + } + } + if (outr->count == 0) { + free(outr->rects); + free(outr); + outr = XRectangleRegion(0,0,0,0); + } + else outr->rects = (CGRect*)realloc(outr->rects, outr->count * sizeof(CGRect)); + return outr; +} + +Fl_Region MacRectRegionIntersect(Fl_Region current, int x,int y,int w, int h) +/* intersects current and x,y,w,h rectangle and returns result as a new Fl_Region + */ +{ + if (current == NULL) return XRectangleRegion(x,y,w,h); + CGRect r = fl_cgrectmake_cocoa(x, y, w, h); + Fl_Region outr = (Fl_Region)malloc(sizeof(*outr)); + outr->count = current->count; + outr->rects =(CGRect*)malloc(outr->count * sizeof(CGRect)); + int j = 0; + for(int i = 0; i < current->count; i++) { + CGRect test = CGRectIntersection(current->rects[i], r); + if (!CGRectIsEmpty(test)) outr->rects[j++] = test; + } + if (j) { + outr->count = j; + outr->rects = (CGRect*)realloc(outr->rects, outr->count * sizeof(CGRect)); + } + else { + XDestroyRegion(outr); + outr = XRectangleRegion(0,0,0,0); + } + return outr; +} + +void MacCollapseWindow(Window w) +{ + [(NSWindow*)w miniaturize:nil]; +} + +static NSImage *CGBitmapContextToNSImage(CGContextRef c) +// the returned NSImage is autoreleased +{ + unsigned char *pdata = (unsigned char *)CGBitmapContextGetData(c); + NSBitmapImageRep *imagerep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:&pdata + pixelsWide:CGBitmapContextGetWidth(c) + pixelsHigh:CGBitmapContextGetHeight(c) + bitsPerSample:8 + samplesPerPixel:4 + hasAlpha:YES + isPlanar:NO + colorSpaceName:NSDeviceRGBColorSpace + bytesPerRow:CGBitmapContextGetBytesPerRow(c) + bitsPerPixel:CGBitmapContextGetBitsPerPixel(c)]; + NSImage* image = [[NSImage alloc] initWithData: [imagerep TIFFRepresentation]]; + [imagerep release]; + return [image autorelease]; +} + +static NSCursor *PrepareCursor(NSCursor *cursor, CGContextRef (*f)() ) +{ + if (cursor == nil) { + CGContextRef c = f(); + NSImage *image = CGBitmapContextToNSImage(c); + fl_delete_offscreen( (Fl_Offscreen)c ); + NSPoint pt = {[image size].width/2, [image size].height/2}; + cursor = [[NSCursor alloc] initWithImage:image hotSpot:pt]; + } + return cursor; +} + +void *MACSetCursor(Fl_Cursor c) +{ + NSCursor *icrsr; + switch (c) { + case FL_CURSOR_CROSS: icrsr = [NSCursor crosshairCursor]; break; + case FL_CURSOR_WAIT: + static NSCursor *watch = nil; + watch = PrepareCursor(watch, CreateWatchImage); + icrsr = watch; + break; + case FL_CURSOR_INSERT: icrsr = [NSCursor IBeamCursor]; break; + case FL_CURSOR_N: icrsr = [NSCursor resizeUpCursor]; break; + case FL_CURSOR_S: icrsr = [NSCursor resizeDownCursor]; break; + case FL_CURSOR_NS: icrsr = [NSCursor resizeUpDownCursor]; break; + case FL_CURSOR_HELP: + static NSCursor *help = nil; + help = PrepareCursor(help, CreateHelpImage); + icrsr = help; + break; + case FL_CURSOR_HAND: icrsr = [NSCursor pointingHandCursor]; break; + case FL_CURSOR_MOVE: icrsr = [NSCursor openHandCursor]; break; + case FL_CURSOR_NE: + case FL_CURSOR_SW: + case FL_CURSOR_NESW: + static NSCursor *nesw = nil; + nesw = PrepareCursor(nesw, CreateNESWImage); + icrsr = nesw; + break; + case FL_CURSOR_E: icrsr = [NSCursor resizeRightCursor]; break; + case FL_CURSOR_W: icrsr = [NSCursor resizeLeftCursor]; break; + case FL_CURSOR_WE: icrsr = [NSCursor resizeLeftRightCursor]; break; + case FL_CURSOR_SE: + case FL_CURSOR_NW: + case FL_CURSOR_NWSE: + static NSCursor *nwse = nil; + nwse = PrepareCursor(nwse, CreateNWSEImage); + icrsr = nwse; + break; + case FL_CURSOR_NONE: + static NSCursor *none = nil; + none = PrepareCursor(none, CreateNoneImage); + icrsr = none; + break; + case FL_CURSOR_ARROW: + case FL_CURSOR_DEFAULT: + default: icrsr = [NSCursor arrowCursor]; + break; + } + [icrsr set]; + return icrsr; +} + +int MACscreen_init(XRectangle screens[]) +{ + NSAutoreleasePool *localPool; + localPool = [[NSAutoreleasePool alloc] init]; + NSArray *a = [NSScreen screens]; + int count = (int)[a count]; + NSRect r; + int i, num_screens = 0; + for( i = 0; i < count; i++) { + r = [[a objectAtIndex:i] frame]; + screens[num_screens].x = int(r.origin.x); + screens[num_screens].y = int(r.size.height - (r.origin.y + r.size.height)); + screens[num_screens].width = int(r.size.width); + screens[num_screens].height = int(r.size.height); + num_screens ++; + if (num_screens >= 16) break; + } + [localPool release]; + return num_screens; +} + +@interface FLaboutItemTarget : NSObject +{ +} +- (void)showPanel; +- (void)printPanel; +@end +@implementation FLaboutItemTarget +- (void)showPanel +{ + NSDictionary *options; + options = [NSDictionary dictionaryWithObjectsAndKeys: + [NSString stringWithFormat:@" GUI with FLTK %d.%d", FL_MAJOR_VERSION, + FL_MINOR_VERSION ], @"Copyright", + nil]; + [NSApp orderFrontStandardAboutPanelWithOptions:options]; + } +- (void)printPanel +{ + Fl_Printer printer; + //Fl_PostScript_File_Device printer; + int w, h; + Fl_Window *win = Fl::first_window(); + if(!win) return; + if( printer.start_job(1) ) return; + if( printer.start_page() ) return; + // scale the printer device so that the window fits on the page + float scale = 1; + printer.printable_rect(&w, &h); + if (win->w()>w || win->h()>h) { + scale = (float)w/win->w(); + if ((float)h/win->h() < scale) scale = (float)h/win->h(); + printer.scale(scale, scale); + } +#ifdef ROTATE + printer.scale(scale * 0.8, scale * 0.8); + printer.printable_rect(&w, &h); + printer.origin(w/2, h/2 ); + printer.rotate(20.); + printer.print_widget( win, - win->w()/2, - win->h()/2 ); +#else + printer.print_widget( win); + //printer.print_window_part( win, 0,0, win->w(), win->h() ); +#endif + printer.end_page(); + printer.end_job(); +} +@end + +static NSMenu *appleMenu; +static void createAppleMenu(void) +{ + static BOOL donethat = NO; + if (donethat) return; + donethat = YES; + NSMenu *mainmenu, *services; + NSMenuItem *menuItem; + NSString *title; + CFStringRef nsappname; + + ProcessSerialNumber psn; + GetCurrentProcess(&psn); + CopyProcessName(&psn, &nsappname); + appleMenu = [[NSMenu alloc] initWithTitle:@""]; + /* Add menu items */ + title = [@"About " stringByAppendingString:(NSString*)nsappname]; + menuItem = [appleMenu addItemWithTitle:title action:@selector(showPanel) keyEquivalent:@""]; + FLaboutItemTarget *about = [[FLaboutItemTarget alloc] init]; + [menuItem setTarget:about]; + [appleMenu addItem:[NSMenuItem separatorItem]]; + // Print front window + menuItem = [appleMenu addItemWithTitle:@"Print front window" action:@selector(printPanel) keyEquivalent:@""]; + [menuItem setTarget:about]; + [appleMenu setAutoenablesItems:NO]; + [menuItem setEnabled:YES]; + [appleMenu addItem:[NSMenuItem separatorItem]]; + // Services Menu + services = [[NSMenu alloc] init]; + [appleMenu addItemWithTitle:@"Services" action:nil keyEquivalent:@""]; + [appleMenu setSubmenu: services forItem: [appleMenu itemWithTitle: @"Services"]]; + // Hide AppName + title = [@"Hide " stringByAppendingString:(NSString*)nsappname]; + [appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"]; + // Hide Others + menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) + keyEquivalent:@"h"]; + [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)]; + // Show All + [appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""]; + [appleMenu addItem:[NSMenuItem separatorItem]]; + // Quit AppName + title = [@"Quit " stringByAppendingString:(NSString*)nsappname]; + [appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"]; + /* Put menu into the menubar */ + menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""]; + [menuItem setSubmenu:appleMenu]; + mainmenu = [[NSMenu alloc] initWithTitle:@""]; + [mainmenu addItem:menuItem]; + if (fl_mac_os_version < 0x1060) { + // [NSApp setAppleMenu:appleMenu]; + // to avoid compiler warning raised by use of undocumented setAppleMenu : + [NSApp performSelector:@selector(setAppleMenu:) withObject:appleMenu]; + } + [NSApp setServicesMenu:services]; + [NSApp setMainMenu:mainmenu]; + CFRelease(nsappname); + [services release]; + [mainmenu release]; + [appleMenu release]; + [menuItem release]; + fl_system_menu = [NSApp mainMenu]; +} + +@interface FLMenuItem : NSMenuItem { +} +- (void) doCallback:(id)unused; +- (void) directCallback:(id)unused; +@end +@implementation FLMenuItem +- (void) doCallback:(id)unused +{ + int flRank = [self tag]; + const Fl_Menu_Item *items = fl_sys_menu_bar->Fl_Menu_::menu(); + const Fl_Menu_Item *item = items + flRank; + if (item) { + fl_sys_menu_bar->picked(item); + if ( item->flags & FL_MENU_TOGGLE ) { // update the menu toggle symbol + [self setState:(item->value() ? NSOnState : NSOffState)]; + } + else if ( item->flags & FL_MENU_RADIO ) { // update the menu radio symbols + int from = flRank; + while( from > 0 && items[from - 1].label() && (items[from - 1].flags & FL_MENU_RADIO) && + !(items[from - 1].flags & FL_MENU_DIVIDER) ) { + from--; + } + int to = flRank; + while( !(items[to].flags & FL_MENU_DIVIDER) && items[to + 1].label() && + (items[to + 1].flags & FL_MENU_RADIO) ) { + to++; + } + NSMenu *nsmenu = [self menu]; + int nsrank = (int)[nsmenu indexOfItem:self]; + for(int i = from - flRank + nsrank ; i <= to - flRank + nsrank; i++) { + NSMenuItem *nsitem = [nsmenu itemAtIndex:i]; + if (nsitem != self) [nsitem setState:NSOffState]; + else [nsitem setState:(item->value() ? NSOnState : NSOffState) ]; + } + } + } +} +- (void) directCallback:(id)unused +{ + Fl_Menu_Item *item = (Fl_Menu_Item *)[(NSData*)[self representedObject] bytes]; + if ( item && item->callback() ) item->do_callback(NULL); +} +@end + +void fl_mac_set_about( Fl_Callback *cb, void *user_data, int shortcut) +{ + NSAutoreleasePool *localPool; + localPool = [[NSAutoreleasePool alloc] init]; + fl_open_display(); + Fl_Menu_Item aboutItem; + memset(&aboutItem, 0, sizeof(Fl_Menu_Item)); + aboutItem.callback(cb); + aboutItem.user_data(user_data); + aboutItem.shortcut(shortcut); + CFStringRef cfname = CFStringCreateCopy(NULL, (CFStringRef)[[appleMenu itemAtIndex:0] title]); + [appleMenu removeItemAtIndex:0]; + FLMenuItem *item = [[[FLMenuItem alloc] initWithTitle:(NSString*)cfname + action:@selector(directCallback:) + keyEquivalent:@""] autorelease]; + if (aboutItem.shortcut()) { + Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::setKeyEquivalent, item, aboutItem.shortcut() & 0xff); + Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::setKeyEquivalentModifierMask, item, aboutItem.shortcut() ); + } + NSData *pointer = [NSData dataWithBytes:&aboutItem length:sizeof(Fl_Menu_Item)]; + [item setRepresentedObject:pointer]; + [appleMenu insertItem:item atIndex:0]; + CFRelease(cfname); + [item setTarget:item]; + [localPool release]; +} + +static char *remove_ampersand(const char *s) +{ + char *ret = strdup(s); + const char *p = s; + char *q = ret; + while(*p != 0) { + if (p[0]=='&') { + if (p[1]=='&') { + *q++ = '&'; p+=2; + } else { + p++; + } + } else { + *q++ = *p++; + } + } + *q = 0; + return ret; +} + +void *Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::menuOrItemOperation operation, ...) +/* these operations apply to menus, submenus, or menu items + */ +{ + NSAutoreleasePool *localPool; + localPool = [[NSAutoreleasePool alloc] init]; + NSMenu *menu; + NSMenuItem *item; + int value; + void *pter; + void *retval = NULL; + va_list ap; + va_start(ap, operation); + + if (operation == Fl_Sys_Menu_Bar::itemAtIndex) { // arguments: NSMenu*, int. Returns the item + menu = va_arg(ap, NSMenu*); + value = va_arg(ap, int); + retval = (void *)[menu itemAtIndex:value]; + } + else if (operation == Fl_Sys_Menu_Bar::setKeyEquivalent) { // arguments: NSMenuItem*, int + item = va_arg(ap, NSMenuItem*); + value = va_arg(ap, int); + char key = value; + NSString *equiv = [[NSString alloc] initWithBytes:&key length:1 encoding:NSASCIIStringEncoding]; + [item setKeyEquivalent:equiv]; + [equiv release]; + } + else if (operation == Fl_Sys_Menu_Bar::setKeyEquivalentModifierMask) { // arguments: NSMenuItem*, int + item = va_arg(ap, NSMenuItem*); + value = va_arg(ap, int); + NSUInteger macMod = 0; + if ( value & FL_META ) macMod = NSCommandKeyMask; + if ( value & FL_SHIFT || isupper(value) ) macMod |= NSShiftKeyMask; + if ( value & FL_ALT ) macMod |= NSAlternateKeyMask; + if ( value & FL_CTRL ) macMod |= NSControlKeyMask; + [item setKeyEquivalentModifierMask:macMod]; + } + else if (operation == Fl_Sys_Menu_Bar::setState) { // arguments: NSMenuItem*, int + item = va_arg(ap, NSMenuItem*); + value = va_arg(ap, int); + [item setState:(value ? NSOnState : NSOffState)]; + } + else if (operation == Fl_Sys_Menu_Bar::initWithTitle) { // arguments: const char*title. Returns the newly created menu + // creates a new (sub)menu + char *ts = remove_ampersand(va_arg(ap, char *)); + CFStringRef title = CFStringCreateWithCString(NULL, ts, kCFStringEncodingUTF8); + free(ts); + NSMenu *menu = [[NSMenu alloc] initWithTitle:(NSString*)title]; + CFRelease(title); + [menu setAutoenablesItems:NO]; + retval = (void *)menu; + } + else if (operation == Fl_Sys_Menu_Bar::numberOfItems) { // arguments: NSMenu *menu, int *pcount + // upon return, *pcount is set to menu's item count + menu = va_arg(ap, NSMenu*); + pter = va_arg(ap, void *); + *(int*)pter = [menu numberOfItems]; + } + else if (operation == Fl_Sys_Menu_Bar::setSubmenu) { // arguments: NSMenuItem *item, NSMenu *menu + // sets 'menu' as submenu attached to 'item' + item = va_arg(ap, NSMenuItem*); + menu = va_arg(ap, NSMenu*); + [item setSubmenu:menu]; + [menu release]; + } + else if (operation == Fl_Sys_Menu_Bar::setEnabled) { // arguments: NSMenuItem*, int + item = va_arg(ap, NSMenuItem*); + value = va_arg(ap, int); + [item setEnabled:(value ? YES : NO)]; + } + else if (operation == Fl_Sys_Menu_Bar::addSeparatorItem) { // arguments: NSMenu* + menu = va_arg(ap, NSMenu*); + [menu addItem:[NSMenuItem separatorItem]]; + } + else if (operation == Fl_Sys_Menu_Bar::setTitle) { // arguments: NSMenuItem*, const char * + item = va_arg(ap, NSMenuItem*); + char *ts = remove_ampersand(va_arg(ap, char *)); + CFStringRef title = CFStringCreateWithCString(NULL, ts, kCFStringEncodingUTF8); + free(ts); + [item setTitle:(NSString*)title]; + CFRelease(title); + } + else if (operation == Fl_Sys_Menu_Bar::removeItem) { // arguments: NSMenu*, int + menu = va_arg(ap, NSMenu*); + value = va_arg(ap, int); + [menu removeItem:[menu itemAtIndex:value]]; + } + else if (operation == Fl_Sys_Menu_Bar::addNewItem) { // arguments: NSMenu *menu, int flrank, int *prank + // creates a new menu item at the end of 'menu' + // attaches the item of rank flrank (counted in Fl_Menu_) of fl_sys_menu_bar to it + // upon return, puts the rank (counted in NSMenu) of the new item in *prank unless prank is NULL + menu = va_arg(ap, NSMenu*); + int flRank = va_arg(ap, int); + char *name = remove_ampersand( (fl_sys_menu_bar->Fl_Menu_::menu() + flRank)->label()); + int *prank = va_arg(ap, int*); + CFStringRef cfname = CFStringCreateWithCString(NULL, name, kCFStringEncodingUTF8); + free(name); + FLMenuItem *item = [[FLMenuItem alloc] initWithTitle:(NSString*)cfname + action:@selector(doCallback:) + keyEquivalent:@""]; + [item setTag:flRank]; + [menu addItem:item]; + CFRelease(cfname); + [item setTarget:item]; + if (prank != NULL) *prank = [menu indexOfItem:item]; + [item release]; + } + else if (operation == Fl_Sys_Menu_Bar::renameItem) { // arguments: int rank, const char *newname + // renames the system menu item numbered rank in fl_sys_menu_bar->menu() + int rank = va_arg(ap, int); + char *newname = remove_ampersand( va_arg(ap, const char *) ); + int countmenus = [(NSMenu*)fl_system_menu numberOfItems]; + bool found = NO; + NSMenuItem *macitem = 0; + for(int i = 1; (!found) && i < countmenus; i++) { + NSMenuItem *item = [(NSMenu*)fl_system_menu itemAtIndex:i]; + NSMenu *submenu = [item submenu]; + if (submenu == nil) continue; + int countitems = [submenu numberOfItems]; + for(int j = 0; j < countitems; j++) { + macitem = [submenu itemAtIndex:j]; + if ([macitem tag] == rank) { found = YES; break; } + } + } + if (found) { + [macitem setTitle:[[[NSString alloc] initWithUTF8String:newname] autorelease]]; + } + free(newname); + } + va_end(ap); + [localPool release]; + return retval; +} + +void MACsetkeywindow(void *nsw) +{ + [(NSWindow*)nsw makeKeyAndOrderFront:nil]; +} + +static NSImage *imageFromText(const char *text, int *pwidth, int *pheight) +{ + const char *p, *q; + int width = 0, height, w2, ltext = strlen(text); + fl_font(FL_HELVETICA, 10); + p = text; + int nl = 0; + while((q=strchr(p, '\n')) != NULL) { + nl++; + w2 = int(fl_width(p, q - p)); + if (w2 > width) width = w2; + p = q + 1; + } + if (text[ ltext - 1] != '\n') { + nl++; + w2 = int(fl_width(p)); + if (w2 > width) width = w2; + } + height = nl * fl_height() + 3; + width += 6; + Fl_Offscreen off = fl_create_offscreen_with_alpha(width, height); + fl_begin_offscreen(off); + CGContextSetRGBFillColor( (CGContextRef)off, 0,0,0,0); + fl_rectf(0,0,width,height); + fl_color(FL_BLACK); + p = text; + int y = fl_height(); + while(TRUE) { + q = strchr(p, '\n'); + if (q) { + fl_draw(p, q - p, 3, y); + } else { + fl_draw(p, 3, y); + break; + } + y += fl_height(); + p = q + 1; + } + fl_end_offscreen(); + NSImage* image = CGBitmapContextToNSImage( (CGContextRef)off ); + fl_delete_offscreen( off ); + *pwidth = width; + *pheight = height; + return image; +} + +static NSImage *defaultDragImage(int *pwidth, int *pheight) +{ + const int width = 16, height = 16; + Fl_Offscreen off = fl_create_offscreen_with_alpha(width, height); + fl_begin_offscreen(off); + CGContextSetRGBFillColor( (CGContextRef)off, 0,0,0,0); + fl_rectf(0,0,width,height); + CGContextSetRGBStrokeColor( (CGContextRef)off, 0,0,0,0.6); + fl_rect(0,0,width,height); + fl_rect(2,2,width-4,height-4); + fl_end_offscreen(); + NSImage* image = CGBitmapContextToNSImage( (CGContextRef)off ); + fl_delete_offscreen( off ); + *pwidth = width; + *pheight = height; + return image; +} + +int MACpreparedrag(void) +{ + CFDataRef text = CFDataCreate(kCFAllocatorDefault, (UInt8*)fl_selection_buffer[0], fl_selection_length[0]); + if (text==NULL) return false; + NSAutoreleasePool *localPool; + localPool = [[NSAutoreleasePool alloc] init]; + NSPasteboard *mypasteboard = [NSPasteboard pasteboardWithName:NSDragPboard]; + [mypasteboard declareTypes:[NSArray arrayWithObjects:@"public.utf8-plain-text", nil] owner:nil]; + [mypasteboard setData:(NSData*)text forType:@"public.utf8-plain-text"]; + CFRelease(text); + Fl_Widget *w = Fl::pushed(); + Fl_Window *win = w->window(); + if (win == NULL) { + win = (Fl_Window*)w; + } else { + while(win->window()) win = win->window(); + } + NSView *myview = [(NSWindow*)Fl_X::i(win)->xid contentView]; + NSEvent *theEvent = [NSApp currentEvent]; + + int width, height; + NSImage *image; + if ( dynamic_cast(w) != NULL) { + fl_selection_buffer[0][ fl_selection_length[0] ] = 0; + image = imageFromText(fl_selection_buffer[0], &width, &height); + } else { + image = defaultDragImage(&width, &height); + } + + static NSSize offset={0,0}; + NSPoint pt = [theEvent locationInWindow]; + pt.x -= width/2; + pt.y -= height/2; + [myview dragImage:image at:pt offset:offset + event:theEvent pasteboard:mypasteboard + source:myview slideBack:YES]; + if ( w ) { + int old_event = Fl::e_number; + w->handle(Fl::e_number = FL_RELEASE); + Fl::e_number = old_event; + Fl::pushed( 0 ); + } + [localPool release]; + return true; +} + +unsigned char *MACbitmapFromRectOfWindow(Fl_Window *win, int x, int y, int w, int h, int *bytesPerPixel) +// delete the returned pointer after use +{ + while(win->window()) { + x += win->x(); + y += win->y(); + win = win->window(); + } + CGFloat epsilon = 0; + if (fl_mac_os_version >= 0x1060) epsilon = 0.001; + // The epsilon offset is absolutely necessary under 10.6. Without it, the top pixel row and + // left pixel column are not read, and bitmap is read shifted by one pixel in both directions. + // Under 10.5, we want no offset. + NSRect rect = NSMakeRect(x - epsilon, y - epsilon, w, h); + NSBitmapImageRep *bitmap = [[NSBitmapImageRep alloc] initWithFocusedViewRect:rect]; + *bytesPerPixel = [bitmap bitsPerPixel]/8; + int bpp = (int)[bitmap bytesPerPlane]; + int bpr = (int)[bitmap bytesPerRow]; + int hh = bpp/bpr; // sometimes hh = h-1 for unclear reason + int ww = bpr/(*bytesPerPixel); // sometimes ww = w-1 + unsigned char *data = new unsigned char[w * h * *bytesPerPixel]; + if (w == ww) { + memcpy(data, [bitmap bitmapData], w * hh * *bytesPerPixel); + } else { + unsigned char *p = [bitmap bitmapData]; + unsigned char *q = data; + for(int i = 0;i < hh; i++) { + memcpy(q, p, *bytesPerPixel * ww); + p += bpr; + q += w * *bytesPerPixel; + } + } + [bitmap release]; + return data; +} + +void imgProviderReleaseData (void *info, const void *data, size_t size) +{ + delete (unsigned char *)data; +} + +CGImageRef MAC_CGImageFromRectOfWindow(Fl_Window *win, int x, int y, int w, int h) +// CFRelease the returned CGImageRef after use +{ + int bpp; + unsigned char *bitmap = MACbitmapFromRectOfWindow(win, x, y, w, h, &bpp); + CGImageRef img; + CGColorSpaceRef lut = CGColorSpaceCreateDeviceRGB(); + CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, bitmap, w*h*bpp, imgProviderReleaseData); + img = CGImageCreate(w, h, 8, 8*bpp, w*bpp, lut, + bpp == 3 ? kCGImageAlphaNone : kCGImageAlphaLast, + provider, NULL, false, kCGRenderingIntentDefault); + CGColorSpaceRelease(lut); + CGDataProviderRelease(provider); + return img; +} + +void MACsetContainsGLsubwindow(Fl_Window *w) +{ + [(FLWindow*)Fl_X::i(w)->xid setContainsGLsubwindow:YES]; +} + +WindowRef MACwindowRef(Fl_Window *w) +{ + return (WindowRef)[(FLWindow*)Fl_X::i(w)->xid windowRef]; +} + +// so a CGRect matches exactly what is denoted x,y,w,h for clipping purposes +CGRect fl_cgrectmake_cocoa(int x, int y, int w, int h) { + if ( Fl_Surface_Device::surface()->type() == Fl_Printer::device_type ) return CGRectMake(x, y, w-1.5 , h-1.5 ); + return CGRectMake(x, y, w > 0 ? w - 0.9 : 0, h > 0 ? h - 0.9 : 0); +} + +#endif // FL_DOXYGEN + +// +// End of "$Id: Fl_cocoa.mm 6971 2009-04-13 07:32:01Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_compose.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_compose.cxx new file mode 100644 index 0000000..aca4bed --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_compose.cxx @@ -0,0 +1,82 @@ +// +// "$Id: Fl_compose.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Character compose processing for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include + +#ifndef FL_DOXYGEN +// at present, this is effectively used by Mac OS X only +int Fl::compose_state = 0; +#endif + +/** Any text editing widget should call this for each FL_KEYBOARD event. + Use of this function is very simple. + +

      If true is returned, then it has modified the + Fl::event_text() and Fl::event_length() to a set of bytes to + insert (it may be of zero length!). In will also set the "del" + parameter to the number of bytes to the left of the cursor to + delete, this is used to delete the results of the previous call to + Fl::compose(). + +

      If false is returned, the keys should be treated as function + keys, and del is set to zero. You could insert the text anyways, if + you don't know what else to do. + +

      Though the current implementation returns immediately, future + versions may take quite awhile, as they may pop up a window or do + other user-interface things to allow characters to be selected. + */ +int Fl::compose(int& del) { + // character composition is now handled by the OS + del = 0; +#if defined(__APPLE__) + // this stuff is to be treated as a function key + if(Fl::e_length == 0 || Fl::e_keysym == FL_Enter || Fl::e_keysym == FL_KP_Enter || + Fl::e_keysym == FL_Tab || Fl::e_keysym == FL_Escape || Fl::e_state&(FL_META | FL_CTRL) ) { + return 0; + } +#else + unsigned char ascii = (unsigned)e_text[0]; + if ((e_state & (FL_ALT | FL_META)) && !(ascii & 128)) return 0; +#endif + if(Fl::compose_state) { + del = 1; + Fl::compose_state = 0; + } else { +#ifndef __APPLE__ + // Only insert non-control characters: + if (! (ascii & ~31 && ascii!=127)) { return 0; } +#endif + } + return 1; +} + +// +// End of "$Id: Fl_compose.cxx 7903 2010-11-28 21:06:39Z matt $" +// + diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_display.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_display.cxx new file mode 100644 index 0000000..c661d23 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_display.cxx @@ -0,0 +1,60 @@ +// +// "$Id: Fl_display.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Display function for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Startup method to set what display to use. +// Using setenv makes programs that are exec'd use the same display. + +#include +#include +#include "flstring.h" + +/** + Sets the X display to use for all windows. Actually this just sets + the environment variable $DISPLAY to the passed string, so this only + works before you show() the first window or otherwise open the display, + and does nothing useful under WIN32. +*/ +void Fl::display(const char *d) { +#if defined(__APPLE__) || defined(WIN32) + (void)d; +#else + static char e[1024]; + strcpy(e,"DISPLAY="); + strlcat(e,d,sizeof(e)); + for (char *c = e+8; *c!=':'; c++) { + if (!*c) { + strlcat(e,":0.0",sizeof(e)); + break; + } + } + putenv(e); +#endif // __APPLE__ +} + +// +// End of "$Id: Fl_display.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_get_key.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_get_key.cxx new file mode 100644 index 0000000..80bcf91 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_get_key.cxx @@ -0,0 +1,69 @@ +// +// "$Id: Fl_get_key.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Keyboard state routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifdef WIN32 +# include "Fl_get_key_win32.cxx" +#elif defined(__APPLE__) +# include "Fl_get_key_mac.cxx" +#else + +// Return the current state of a key. This is the X version. I identify +// keys (mostly) by the X keysym. So this turns the keysym into a keycode +// and looks it up in the X key bit vector, which Fl_x.cxx keeps track of. + +# include +# include + +extern char fl_key_vector[32]; // in Fl_x.cxx + +int Fl::event_key(int k) { + if (k > FL_Button && k <= FL_Button+8) + return Fl::event_state(8<<(k-FL_Button)); + int i; +# ifdef __sgi + // get some missing PC keyboard keys: + if (k == FL_Meta_L) i = 147; + else if (k == FL_Meta_R) i = 148; + else if (k == FL_Menu) i = 149; + else +# endif + i = XKeysymToKeycode(fl_display, k); + if (i==0) return 0; + return fl_key_vector[i/8] & (1 << (i%8)); +} + +int Fl::get_key(int k) { + fl_open_display(); + XQueryKeymap(fl_display, fl_key_vector); + return event_key(k); +} + +#endif + +// +// End of "$Id: Fl_get_key.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_get_key_mac.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_get_key_mac.cxx new file mode 100644 index 0000000..84f0371 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_get_key_mac.cxx @@ -0,0 +1,118 @@ +// +// "$Id: Fl_get_key_mac.cxx 7725 2010-10-19 12:29:35Z manolo $" +// +// MacOS keyboard state routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2009 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Return the current state of a key. Keys are named by fltk symbols, +// which are actually X keysyms. So this has to translate to macOS +// symbols. + +#include +#include +#include + +// convert an FLTK (X) keysym to a MacOS symbol: +// See also the inverse converter in table macKeyLookUp of Fl_cocoa.mm +// This table is in numeric order by FLTK symbol order for binary search: + +static const struct {unsigned short vk, fltk;} vktab[] = { + { 49, ' ' }, { 39, '\'' }, { 43, ',' }, { 27, '-' }, { 47, '.' }, { 44, '/' }, + { 29, '0' }, { 18, '1' }, { 19, '2' }, { 20, '3' }, + { 21, '4' }, { 23, '5' }, { 22, '6' }, { 26, '7' }, + { 28, '8' }, { 25, '9' }, { 41, ';' }, { 24, '=' }, + { 0, 'A' }, { 11, 'B' }, { 8, 'C' }, { 2, 'D' }, + { 14, 'E' }, { 3, 'F' }, { 5, 'G' }, { 4, 'H' }, + { 34, 'I' }, { 38, 'J' }, { 40, 'K' }, { 37, 'L' }, + { 46, 'M' }, { 45, 'N' }, { 31, 'O' }, { 35, 'P' }, + { 12, 'Q' }, { 15, 'R' }, { 1, 'S' }, { 17, 'T' }, + { 32, 'U' }, { 9, 'V' }, { 13, 'W' }, { 7, 'X' }, + { 16, 'Y' }, { 6, 'Z' }, + { 33, '[' }, { 30, ']' }, { 50, '`' }, { 42, '|' }, + { 51, FL_BackSpace }, { 48, FL_Tab }, { 36, FL_Enter }, { 127, FL_Pause }, + { 107, FL_Scroll_Lock }, { 53, FL_Escape }, { 0x73, FL_Home }, { 123, FL_Left }, + { 126, FL_Up }, { 124, FL_Right }, { 125, FL_Down }, { 0x74, FL_Page_Up }, + { 0x79, FL_Page_Down }, { 119, FL_End }, { 0x71, FL_Print }, { 127, FL_Insert }, + { 0x6e, FL_Menu }, { 114, FL_Help }, { 0x47, FL_Num_Lock }, + { 76, FL_KP_Enter }, { 67, FL_KP+'*' }, { 69, FL_KP+'+'}, { 78, FL_KP+'-' }, { 65, FL_KP+'.' }, { 75, FL_KP+'/' }, + { 82, FL_KP+'0' }, { 83, FL_KP+'1' }, { 84, FL_KP+'2' }, { 85, FL_KP+'3' }, + { 86, FL_KP+'4' }, { 87, FL_KP+'5' }, { 88, FL_KP+'6' }, { 89, FL_KP+'7' }, + { 91, FL_KP+'8' }, { 92, FL_KP+'9' }, { 81, FL_KP+'=' }, + { 0x7a, FL_F+1 }, { 0x78, FL_F+2 }, { 0x63, FL_F+3 }, { 0x76, FL_F+4 }, + { 0x60, FL_F+5 }, { 0x61, FL_F+6 }, { 0x62, FL_F+7 }, { 0x64, FL_F+8 }, + { 0x65, FL_F+9 }, { 0x6D, FL_F+10 }, { 0x67, FL_F+11 }, { 0x6f, FL_F+12 }, + { 56, FL_Shift_L }, { 56, FL_Shift_R }, { 59, FL_Control_L }, { 59, FL_Control_R }, + { 57, FL_Caps_Lock }, { 55, FL_Meta_L }, { 55, FL_Meta_R }, + { 58, FL_Alt_L }, { 58, FL_Alt_R }, { 0x75, FL_Delete }, +}; + +static int fltk2mac(int fltk) { + int a = 0; + int b = sizeof(vktab)/sizeof(*vktab); + while (a < b) { + int c = (a+b)/2; + if (vktab[c].fltk == fltk) return vktab[c].vk; + if (vktab[c].fltk < fltk) a = c+1; else b = c; + } + return 127; +} + +//: returns true, if that key was pressed during the last event +int Fl::event_key(int k) { + return get_key(k); +} + +#include + +//: returns true, if that key is pressed right now +int Fl::get_key(int k) { +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 + if(CGEventSourceKeyState != NULL) { + return (int)CGEventSourceKeyState(kCGEventSourceStateCombinedSessionState, fltk2mac(k) ); + } + else +#endif + { + KeyMap foo; + GetKeys(foo); +#ifdef MAC_TEST_FOR_KEYCODES + static int cnt = 0; + if (cnt++>1024) { + cnt = 0; + printf("%08x %08x %08x %08x\n", (ulong*)(foo)[3], (ulong*)(foo)[2], (ulong*)(foo)[1], (ulong*)(foo)[0]); + } +#endif + unsigned char *b = (unsigned char*)foo; + // KP_Enter can be at different locations for Powerbooks vs. desktop Macs + if (k==FL_KP_Enter) { + return (((b[0x34>>3]>>(0x34&7))&1)||((b[0x4c>>3]>>(0x4c&7))&1)); + } + int i = fltk2mac(k); + return (b[i>>3]>>(i&7))&1; + } +} + +// +// End of "$Id: Fl_get_key_mac.cxx 7725 2010-10-19 12:29:35Z manolo $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_get_key_win32.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_get_key_win32.cxx new file mode 100644 index 0000000..1f14b4c --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_get_key_win32.cxx @@ -0,0 +1,138 @@ +// +// "$Id: Fl_get_key_win32.cxx 6616 2009-01-01 21:28:26Z matt $" +// +// WIN32 keyboard state routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2009 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Return the current state of a key. Keys are named by fltk symbols, +// which are actually X keysyms. So this has to translate to MSWindows +// VK_x symbols. + +#include +#include + +// convert an Fltk (X) keysym to a MSWindows VK symbol: +// See also the inverse converter in Fl_win32.cxx +// This table is in numeric order by Fltk symbol order for binary search: + +static const struct {unsigned short vk, fltk;} vktab[] = { + {VK_SPACE, ' '}, + {'1', '!'}, + {0xde, '\"'}, + {'3', '#'}, + {'4', '$'}, + {'5', '%'}, + {'7', '&'}, + {0xde, '\''}, + {'9', '('}, + {'0', ')'}, + {'8', '*'}, + {0xbb, '+'}, + {0xbc, ','}, + {0xbd, '-'}, + {0xbe, '.'}, + {0xbf, '/'}, + {0xba, ':'}, + {0xba, ';'}, + {0xbc, '<'}, + {0xbb, '='}, + {0xbe, '>'}, + {0xbf, '?'}, + {'2', '@'}, + {0xdb, '['}, + {0xdc, '\\'}, + {0xdd, ']'}, + {'6', '^'}, + {0xbd, '_'}, + {0xc0, '`'}, + {0xdb, '{'}, + {0xdc, '|'}, + {0xdd, '}'}, + {0xc0, '~'}, + {VK_BACK, FL_BackSpace}, + {VK_TAB, FL_Tab}, + {VK_CLEAR, 0xff0b/*XK_Clear*/}, + {VK_RETURN, FL_Enter}, + {VK_PAUSE, FL_Pause}, + {VK_SCROLL, FL_Scroll_Lock}, + {VK_ESCAPE, FL_Escape}, + {VK_HOME, FL_Home}, + {VK_LEFT, FL_Left}, + {VK_UP, FL_Up}, + {VK_RIGHT, FL_Right}, + {VK_DOWN, FL_Down}, + {VK_PRIOR, FL_Page_Up}, + {VK_NEXT, FL_Page_Down}, + {VK_END, FL_End}, + {VK_SNAPSHOT, FL_Print}, + {VK_INSERT, FL_Insert}, + {VK_APPS, FL_Menu}, + {VK_NUMLOCK, FL_Num_Lock}, +//{VK_???, FL_KP_Enter}, + {VK_MULTIPLY, FL_KP+'*'}, + {VK_ADD, FL_KP+'+'}, + {VK_SUBTRACT, FL_KP+'-'}, + {VK_DECIMAL, FL_KP+'.'}, + {VK_DIVIDE, FL_KP+'/'}, + {VK_LSHIFT, FL_Shift_L}, + {VK_RSHIFT, FL_Shift_R}, + {VK_LCONTROL, FL_Control_L}, + {VK_RCONTROL, FL_Control_R}, + {VK_CAPITAL, FL_Caps_Lock}, + {VK_LWIN, FL_Meta_L}, + {VK_RWIN, FL_Meta_R}, + {VK_LMENU, FL_Alt_L}, + {VK_RMENU, FL_Alt_R}, + {VK_DELETE, FL_Delete} +}; + +static int fltk2ms(int fltk) { + if (fltk >= '0' && fltk <= '9') return fltk; + if (fltk >= 'A' && fltk <= 'Z') return fltk; + if (fltk >= 'a' && fltk <= 'z') return fltk-('a'-'A'); + if (fltk > FL_F && fltk <= FL_F+16) return fltk-(FL_F-(VK_F1-1)); + if (fltk >= FL_KP+'0' && fltk<=FL_KP+'9') return fltk-(FL_KP+'0'-VK_NUMPAD0); + int a = 0; + int b = sizeof(vktab)/sizeof(*vktab); + while (a < b) { + int c = (a+b)/2; + if (vktab[c].fltk == fltk) return vktab[c].vk; + if (vktab[c].fltk < fltk) a = c+1; else b = c; + } + return 0; +} + +int Fl::event_key(int k) { + return GetKeyState(fltk2ms(k))&~1; +} + +int Fl::get_key(int k) { + uchar foo[256]; + GetKeyboardState(foo); + return foo[fltk2ms(k)]&~1; +} + +// +// End of "$Id: Fl_get_key_win32.cxx 6616 2009-01-01 21:28:26Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_get_system_colors.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_get_system_colors.cxx new file mode 100644 index 0000000..35e9a9f --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_get_system_colors.cxx @@ -0,0 +1,426 @@ +// +// "$Id: Fl_get_system_colors.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// System color support for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include +#include +#include +#include "flstring.h" +#include +#include +#include +#include +#include "tile.xpm" + +#if defined(WIN32) && !defined(__CYGWIN__) && !defined(__WATCOMC__) +// Visual C++ 2005 incorrectly displays a warning about the use of POSIX APIs +// on Windows, which is supposed to be POSIX compliant... +# define putenv _putenv +#endif // WIN32 && !__CYGWIN__ + +static char fl_bg_set = 0; +static char fl_bg2_set = 0; +static char fl_fg_set = 0; + +/** + Changes fl_color(FL_BACKGROUND_COLOR) to the given color, + and changes the gray ramp from 32 to 56 to black to white. These are + the colors used as backgrounds by almost all widgets and used to draw + the edges of all the boxtypes. +*/ +void Fl::background(uchar r, uchar g, uchar b) { + fl_bg_set = 1; + + // replace the gray ramp so that FL_GRAY is this color + if (!r) r = 1; else if (r==255) r = 254; + double powr = log(r/255.0)/log((FL_GRAY-FL_GRAY_RAMP)/(FL_NUM_GRAY-1.0)); + if (!g) g = 1; else if (g==255) g = 254; + double powg = log(g/255.0)/log((FL_GRAY-FL_GRAY_RAMP)/(FL_NUM_GRAY-1.0)); + if (!b) b = 1; else if (b==255) b = 254; + double powb = log(b/255.0)/log((FL_GRAY-FL_GRAY_RAMP)/(FL_NUM_GRAY-1.0)); + for (int i = 0; i < FL_NUM_GRAY; i++) { + double gray = i/(FL_NUM_GRAY-1.0); + Fl::set_color(fl_gray_ramp(i), + uchar(pow(gray,powr)*255+.5), + uchar(pow(gray,powg)*255+.5), + uchar(pow(gray,powb)*255+.5)); + } +} +/** Changes fl_color(FL_FOREGROUND_COLOR). */ +void Fl::foreground(uchar r, uchar g, uchar b) { + fl_fg_set = 1; + + Fl::set_color(FL_FOREGROUND_COLOR,r,g,b); +} + +/** + Changes the alternative background color. This color is used as a + background by Fl_Input and other text widgets. +

      This call may change fl_color(FL_FOREGROUND_COLOR) if it + does not provide sufficient contrast to FL_BACKGROUND2_COLOR. +*/ +void Fl::background2(uchar r, uchar g, uchar b) { + fl_bg2_set = 1; + + Fl::set_color(FL_BACKGROUND2_COLOR,r,g,b); + Fl::set_color(FL_FOREGROUND_COLOR, + get_color(fl_contrast(FL_FOREGROUND_COLOR,FL_BACKGROUND2_COLOR))); +} + +// these are set by Fl::args() and override any system colors: +const char *fl_fg = NULL; +const char *fl_bg = NULL; +const char *fl_bg2 = NULL; + +static void set_selection_color(uchar r, uchar g, uchar b) { + Fl::set_color(FL_SELECTION_COLOR,r,g,b); +} + +#if defined(WIN32) || defined(__APPLE__) + +# include +// simulation of XParseColor: +int fl_parse_color(const char* p, uchar& r, uchar& g, uchar& b) { + if (*p == '#') p++; + int n = strlen(p); + int m = n/3; + const char *pattern = 0; + switch(m) { + case 1: pattern = "%1x%1x%1x"; break; + case 2: pattern = "%2x%2x%2x"; break; + case 3: pattern = "%3x%3x%3x"; break; + case 4: pattern = "%4x%4x%4x"; break; + default: return 0; + } + int R,G,B; if (sscanf(p,pattern,&R,&G,&B) != 3) return 0; + switch(m) { + case 1: R *= 0x11; G *= 0x11; B *= 0x11; break; + case 3: R >>= 4; G >>= 4; B >>= 4; break; + case 4: R >>= 8; G >>= 8; B >>= 8; break; + } + r = (uchar)R; g = (uchar)G; b = (uchar)B; + return 1; +} +#else +// Wrapper around XParseColor... +int fl_parse_color(const char* p, uchar& r, uchar& g, uchar& b) { + XColor x; + if (!fl_display) fl_open_display(); + if (XParseColor(fl_display, fl_colormap, p, &x)) { + r = (uchar)(x.red>>8); + g = (uchar)(x.green>>8); + b = (uchar)(x.blue>>8); + return 1; + } else return 0; +} +#endif // WIN32 || __APPLE__ +/** \fn Fl::get_system_colors() + Read the user preference colors from the system and use them to call + Fl::foreground(), Fl::background(), and + Fl::background2(). This is done by + Fl_Window::show(argc,argv) before applying the -fg and -bg + switches. + +

      On X this reads some common values from the Xdefaults database. + KDE users can set these values by running the "krdb" program, and + newer versions of KDE set this automatically if you check the "apply + style to other X programs" switch in their control panel. +*/ +#if defined(WIN32) +static void +getsyscolor(int what, const char* arg, void (*func)(uchar,uchar,uchar)) +{ + if (arg) { + uchar r,g,b; + if (!fl_parse_color(arg, r,g,b)) + Fl::error("Unknown color: %s", arg); + else + func(r,g,b); + } else { + DWORD x = GetSysColor(what); + func(uchar(x&255), uchar(x>>8), uchar(x>>16)); + } +} + +void Fl::get_system_colors() { + if (!fl_bg2_set) getsyscolor(COLOR_WINDOW, fl_bg2,Fl::background2); + if (!fl_fg_set) getsyscolor(COLOR_WINDOWTEXT, fl_fg, Fl::foreground); + if (!fl_bg_set) getsyscolor(COLOR_BTNFACE, fl_bg, Fl::background); + getsyscolor(COLOR_HIGHLIGHT, 0, set_selection_color); +} + +#elif defined(__APPLE__) +// MacOS X currently supports two color schemes - Blue and Graphite. +// Since we aren't emulating the Aqua interface (even if Apple would +// let us), we use some defaults that are similar to both. The +// Fl::scheme("plastic") color/box scheme provides a usable Aqua-like +// look-n-feel... +void Fl::get_system_colors() +{ + fl_open_display(); + + if (!fl_bg2_set) background2(0xff, 0xff, 0xff); + if (!fl_fg_set) foreground(0, 0, 0); + if (!fl_bg_set) background(0xd8, 0xd8, 0xd8); + +#if 0 + // this would be the correct code, but it does not run on all versions + // of OS X. Also, setting a bright selection color would require + // some updates in Fl_Adjuster and Fl_Help_Browser + OSStatus err; + RGBColor c; + err = GetThemeBrushAsColor(kThemeBrushPrimaryHighlightColor, 24, true, &c); + if (err) + set_selection_color(0x00, 0x00, 0x80); + else + set_selection_color(c.red, c.green, c.blue); +#else + set_selection_color(0x00, 0x00, 0x80); +#endif +} +#else + +// Read colors that KDE writes to the xrdb database. + +// XGetDefault does not do the expected thing: it does not like +// periods in either word. Therefore it cannot match class.Text.background. +// However *.Text.background is matched by pretending the program is "Text". +// But this will also match *.background if there is no *.Text.background +// entry, requiring users to put in both (unless they want the text fields +// the same color as the windows). + +static void +getsyscolor(const char *key1, const char* key2, const char *arg, const char *defarg, void (*func)(uchar,uchar,uchar)) +{ + if (!arg) { + arg = XGetDefault(fl_display, key1, key2); + if (!arg) arg = defarg; + } + XColor x; + if (!XParseColor(fl_display, fl_colormap, arg, &x)) + Fl::error("Unknown color: %s", arg); + else + func(x.red>>8, x.green>>8, x.blue>>8); +} + +void Fl::get_system_colors() +{ + fl_open_display(); + const char* key1 = 0; + if (Fl::first_window()) key1 = Fl::first_window()->xclass(); + if (!key1) key1 = "fltk"; + if (!fl_bg2_set) getsyscolor("Text","background", fl_bg2, "#ffffff", Fl::background2); + if (!fl_fg_set) getsyscolor(key1, "foreground", fl_fg, "#000000", Fl::foreground); + if (!fl_bg_set) getsyscolor(key1, "background", fl_bg, "#c0c0c0", Fl::background); + getsyscolor("Text", "selectBackground", 0, "#000080", set_selection_color); +} + +#endif + + +//// Simple implementation of 2.0 Fl::scheme() interface... +#define D1 BORDER_WIDTH +#define D2 (BORDER_WIDTH+BORDER_WIDTH) + +extern void fl_up_box(int, int, int, int, Fl_Color); +extern void fl_down_box(int, int, int, int, Fl_Color); +extern void fl_thin_up_box(int, int, int, int, Fl_Color); +extern void fl_thin_down_box(int, int, int, int, Fl_Color); +extern void fl_round_up_box(int, int, int, int, Fl_Color); +extern void fl_round_down_box(int, int, int, int, Fl_Color); + +extern void fl_up_frame(int, int, int, int, Fl_Color); +extern void fl_down_frame(int, int, int, int, Fl_Color); +extern void fl_thin_up_frame(int, int, int, int, Fl_Color); +extern void fl_thin_down_frame(int, int, int, int, Fl_Color); + +#ifndef FL_DOXYGEN +const char *Fl::scheme_ = (const char *)0; // current scheme +Fl_Image *Fl::scheme_bg_ = (Fl_Image *)0; // current background image for the scheme +#endif + +static Fl_Pixmap tile(tile_xpm); + +/** + Gets or sets the current widget scheme. NULL will use + the scheme defined in the FLTK_SCHEME environment + variable or the scheme resource under X11. Otherwise, + any of the following schemes can be used:

      + +
        + +
      • "none" - This is the default look-n-feel which resembles old + Windows (95/98/Me/NT/2000) and old GTK/KDE
      • + +
      • "plastic" - This scheme is inspired by the Aqua user interface + on Mac OS X
      • + +
      • "gtk+" - This scheme is inspired by the Red Hat Bluecurve + theme
      • + +
      +*/ +int Fl::scheme(const char *s) { + if (!s) { + if ((s = getenv("FLTK_SCHEME")) == NULL) { +#if !defined(WIN32) && !defined(__APPLE__) + const char* key = 0; + if (Fl::first_window()) key = Fl::first_window()->xclass(); + if (!key) key = "fltk"; + fl_open_display(); + s = XGetDefault(fl_display, key, "scheme"); +#endif // !WIN32 && !__APPLE__ + } + } + + if (s) { + if (!strcasecmp(s, "none") || !strcasecmp(s, "base") || !*s) s = 0; + else s = strdup(s); + } + if (scheme_) free((void*)scheme_); + scheme_ = s; + + // Save the new scheme in the FLTK_SCHEME env var so that child processes + // inherit it... + static char e[1024]; + strcpy(e,"FLTK_SCHEME="); + if (s) strlcat(e,s,sizeof(e)); + putenv(e); + + // Load the scheme... + return reload_scheme(); +} + +int Fl::reload_scheme() { + Fl_Window *win; + + if (scheme_ && !strcasecmp(scheme_, "plastic")) { + // Update the tile image to match the background color... + uchar r, g, b; + int nr, ng, nb; + int i; +// static uchar levels[3] = { 0xff, 0xef, 0xe8 }; + // OSX 10.3 and higher use a background with less contrast... + static uchar levels[3] = { 0xff, 0xf8, 0xf4 }; + + get_color(FL_GRAY, r, g, b); + +// printf("FL_GRAY = 0x%02x 0x%02x 0x%02x\n", r, g, b); + + for (i = 0; i < 3; i ++) { + nr = levels[i] * r / 0xe8; + if (nr > 255) nr = 255; + + ng = levels[i] * g / 0xe8; + if (ng > 255) ng = 255; + + nb = levels[i] * b / 0xe8; + if (nb > 255) nb = 255; + + sprintf(tile_cmap[i], "%c c #%02x%02x%02x", "Oo."[i], nr, ng, nb); +// puts(tile_cmap[i]); + } + + tile.uncache(); + + if (!scheme_bg_) scheme_bg_ = new Fl_Tiled_Image(&tile, w(), h()); + + // Load plastic buttons, etc... + set_boxtype(FL_UP_FRAME, FL_PLASTIC_UP_FRAME); + set_boxtype(FL_DOWN_FRAME, FL_PLASTIC_DOWN_FRAME); + set_boxtype(FL_THIN_UP_FRAME, FL_PLASTIC_UP_FRAME); + set_boxtype(FL_THIN_DOWN_FRAME, FL_PLASTIC_DOWN_FRAME); + + set_boxtype(FL_UP_BOX, FL_PLASTIC_UP_BOX); + set_boxtype(FL_DOWN_BOX, FL_PLASTIC_DOWN_BOX); + set_boxtype(FL_THIN_UP_BOX, FL_PLASTIC_THIN_UP_BOX); + set_boxtype(FL_THIN_DOWN_BOX, FL_PLASTIC_THIN_DOWN_BOX); + set_boxtype(_FL_ROUND_UP_BOX, FL_PLASTIC_ROUND_UP_BOX); + set_boxtype(_FL_ROUND_DOWN_BOX, FL_PLASTIC_ROUND_DOWN_BOX); + + // Use standard size scrollbars... + Fl::scrollbar_size(16); + } else if (scheme_ && !strcasecmp(scheme_, "gtk+")) { + // Use a GTK+ inspired look-n-feel... + if (scheme_bg_) { + delete scheme_bg_; + scheme_bg_ = (Fl_Image *)0; + } + + set_boxtype(FL_UP_FRAME, FL_GTK_UP_FRAME); + set_boxtype(FL_DOWN_FRAME, FL_GTK_DOWN_FRAME); + set_boxtype(FL_THIN_UP_FRAME, FL_GTK_THIN_UP_FRAME); + set_boxtype(FL_THIN_DOWN_FRAME, FL_GTK_THIN_DOWN_FRAME); + + set_boxtype(FL_UP_BOX, FL_GTK_UP_BOX); + set_boxtype(FL_DOWN_BOX, FL_GTK_DOWN_BOX); + set_boxtype(FL_THIN_UP_BOX, FL_GTK_THIN_UP_BOX); + set_boxtype(FL_THIN_DOWN_BOX, FL_GTK_THIN_DOWN_BOX); + set_boxtype(_FL_ROUND_UP_BOX, FL_GTK_ROUND_UP_BOX); + set_boxtype(_FL_ROUND_DOWN_BOX, FL_GTK_ROUND_DOWN_BOX); + + // Use slightly thinner scrollbars... + Fl::scrollbar_size(15); + } else { + // Use the standard FLTK look-n-feel... + if (scheme_bg_) { + delete scheme_bg_; + scheme_bg_ = (Fl_Image *)0; + } + + set_boxtype(FL_UP_FRAME, fl_up_frame, D1, D1, D2, D2); + set_boxtype(FL_DOWN_FRAME, fl_down_frame, D1, D1, D2, D2); + set_boxtype(FL_THIN_UP_FRAME, fl_thin_up_frame, 1, 1, 2, 2); + set_boxtype(FL_THIN_DOWN_FRAME, fl_thin_down_frame, 1, 1, 2, 2); + + set_boxtype(FL_UP_BOX, fl_up_box, D1, D1, D2, D2); + set_boxtype(FL_DOWN_BOX, fl_down_box, D1, D1, D2, D2); + set_boxtype(FL_THIN_UP_BOX, fl_thin_up_box, 1, 1, 2, 2); + set_boxtype(FL_THIN_DOWN_BOX, fl_thin_down_box, 1, 1, 2, 2); + set_boxtype(_FL_ROUND_UP_BOX, fl_round_up_box, 3, 3, 6, 6); + set_boxtype(_FL_ROUND_DOWN_BOX, fl_round_down_box, 3, 3, 6, 6); + + // Use standard size scrollbars... + Fl::scrollbar_size(16); + } + + // Set (or clear) the background tile for all windows... + for (win = first_window(); win; win = next_window(win)) { + win->labeltype(scheme_bg_ ? FL_NORMAL_LABEL : FL_NO_LABEL); + win->align(FL_ALIGN_CENTER | FL_ALIGN_INSIDE | FL_ALIGN_CLIP); + win->image(scheme_bg_); + win->redraw(); + } + + return 1; +} + + +// +// End of "$Id: Fl_get_system_colors.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_grab.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_grab.cxx new file mode 100644 index 0000000..9873310 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_grab.cxx @@ -0,0 +1,105 @@ +// +// "$Id: Fl_grab.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Grab/release code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include + +//////////////////////////////////////////////////////////////// +// "Grab" is done while menu systems are up. This has several effects: +// Events are all sent to the "grab window", which does not even +// have to be displayed (and in the case of Fl_Menu.cxx it isn't). +// The system is also told to "grab" events and send them to this app. +// This also modifies how Fl_Window::show() works, on X it turns on +// override_redirect, it does similar things on WIN32. + +extern void fl_fix_focus(); // in Fl.cxx + +#ifdef WIN32 +// We have to keep track of whether we have captured the mouse, since +// MSWindows shows little respect for this... Grep for fl_capture to +// see where and how this is used. +extern HWND fl_capture; +#endif + +#ifdef __APPLE__ +extern void MACsetkeywindow(void *nsw); +extern void *fl_capture; +#endif + +void Fl::grab(Fl_Window* win) { + if (win) { + if (!grab_) { +#ifdef WIN32 + SetActiveWindow(fl_capture = fl_xid(first_window())); + SetCapture(fl_capture); +#elif defined(__APPLE__) + fl_capture = Fl_X::i(first_window())->xid; + MACsetkeywindow(fl_capture); +#else + XGrabPointer(fl_display, + fl_xid(first_window()), + 1, + ButtonPressMask|ButtonReleaseMask| + ButtonMotionMask|PointerMotionMask, + GrabModeAsync, + GrabModeAsync, + None, + 0, + fl_event_time); + XGrabKeyboard(fl_display, + fl_xid(first_window()), + 1, + GrabModeAsync, + GrabModeAsync, + fl_event_time); +#endif + } + grab_ = win; + } else { + if (grab_) { +#ifdef WIN32 + fl_capture = 0; + ReleaseCapture(); +#elif defined(__APPLE__) + fl_capture = 0; +#else + XUngrabKeyboard(fl_display, fl_event_time); + XUngrabPointer(fl_display, fl_event_time); + // this flush is done in case the picked menu item goes into + // an infinite loop, so we don't leave the X server locked up: + XFlush(fl_display); +#endif + grab_ = 0; + fl_fix_focus(); + } + } +} + +// +// End of "$Id: Fl_grab.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_lock.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_lock.cxx new file mode 100644 index 0000000..577f198 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_lock.cxx @@ -0,0 +1,403 @@ +// +// "$Id: Fl_lock.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Multi-threading support code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + + +#include +#include + +#include + +/* + From Bill: + + I would prefer that FLTK contain the minimal amount of extra + stuff for doing threads. There are other portable thread + wrapper libraries out there and FLTK should not be providing + another. This file is an attempt to make minimal additions + and make them self-contained in this source file. + + From Mike: + + Starting with 1.1.8, we now have a callback so that you can + process awake() messages as they come in. + + + The API: + + Fl::lock() - recursive lock. You must call this before the + first call to Fl::wait()/run() to initialize the thread + system. The lock is locked all the time except when + Fl::wait() is waiting for events. + + Fl::unlock() - release the recursive lock. + + Fl::awake(void*) - Causes Fl::wait() to return (with the lock + locked) even if there are no events ready. + + Fl::awake(void (*cb)(void *), void*) - Call a function + in the main thread from within another thread of execution. + + Fl::thread_message() - returns an argument sent to an + Fl::awake() call, or returns NULL if none. WARNING: the + current implementation only has a one-entry queue and only + returns the most recent value! +*/ + +#ifndef FL_DOXYGEN +Fl_Awake_Handler *Fl::awake_ring_; +void **Fl::awake_data_; +int Fl::awake_ring_size_; +int Fl::awake_ring_head_; +int Fl::awake_ring_tail_; +#endif + +static const int AWAKE_RING_SIZE = 1024; +static void lock_ring(); +static void unlock_ring(); + + +/** Adds an awake handler for use in awake(). */ +int Fl::add_awake_handler_(Fl_Awake_Handler func, void *data) +{ + int ret = 0; + lock_ring(); + if (!awake_ring_) { + awake_ring_size_ = AWAKE_RING_SIZE; + awake_ring_ = (Fl_Awake_Handler*)malloc(awake_ring_size_*sizeof(Fl_Awake_Handler)); + awake_data_ = (void**)malloc(awake_ring_size_*sizeof(void*)); + } + if (awake_ring_head_==awake_ring_tail_-1 || awake_ring_head_+1==awake_ring_tail_) { + // ring is full. Return -1 as an error indicator. + ret = -1; + } else { + awake_ring_[awake_ring_head_] = func; + awake_data_[awake_ring_head_] = data; + ++awake_ring_head_; + if (awake_ring_head_ == awake_ring_size_) + awake_ring_head_ = 0; + } + unlock_ring(); + return ret; +} +/** Gets the last stored awake handler for use in awake(). */ +int Fl::get_awake_handler_(Fl_Awake_Handler &func, void *&data) +{ + int ret = 0; + lock_ring(); + if (!awake_ring_ || awake_ring_head_ == awake_ring_tail_) { + ret = -1; + } else { + func = awake_ring_[awake_ring_tail_]; + data = awake_data_[awake_ring_tail_]; + ++awake_ring_tail_; + if (awake_ring_tail_ == awake_ring_size_) + awake_ring_tail_ = 0; + } + unlock_ring(); + return ret; +} + +// +/** + Let the main thread know an update is pending + and have it call a specific function + See void awake(void* message=0). +*/ +int Fl::awake(Fl_Awake_Handler func, void *data) { + int ret = add_awake_handler_(func, data); + Fl::awake(); + return ret; +} + +//////////////////////////////////////////////////////////////// +// Windows threading... +/** \fn void Fl::lock() + The lock() method blocks the current thread until it + can safely access FLTK widgets and data. Child threads should + call this method prior to updating any widgets or accessing + data. The main thread must call lock() to initialize + the threading support in FLTK. + + Child threads must call unlock() when they are done + accessing FLTK. + + When the wait() method is waiting + for input or timeouts, child threads are given access to FLTK. + Similarly, when the main thread needs to do processing, it will + wait until all child threads have called unlock() before processing + additional data. + + See also: \ref advanced_multithreading +*/ +/** \fn void Fl::unlock() + The unlock() method releases the lock that was set + using the lock() method. Child + threads should call this method as soon as they are finished + accessing FLTK. + + See also: \ref advanced_multithreading +*/ +/** \fn void Fl::awake(void* msg) + The awake() method sends a message pointer to the main thread, + causing any pending Fl::wait() call to + terminate so that the main thread can retrieve the message and any pending + redraws can be processed. + + Multiple calls to Fl::awake() will queue multiple pointers + for the main thread to process, up to a system-defined (typically several + thousand) depth. The default message handler saves the last message which + can be accessed using the + Fl::thread_message() function. + + The second form of awake() registers a function that will be + called by the main thread during the next message handling cycle. + awake() will return 0 if the callback function was registered, + and -1 if registration failed. Over a thousand awake callbacks can be + registered simultaneously. + + In the context of a threaded application, a call to Fl::awake() with no + argument will trigger event loop handling in the main thread. Since + it is not possible to call Fl::flush() from a subsidiary thread, + Fl::awake() is the best (and only, really) substitute. + + See also: \ref advanced_multithreading +*/ +#ifdef WIN32 +# include +# include +# include + +// These pointers are in Fl_win32.cxx: +extern void (*fl_lock_function)(); +extern void (*fl_unlock_function)(); + +// The main thread's ID +static DWORD main_thread; + +// Microsoft's version of a MUTEX... +CRITICAL_SECTION cs; +CRITICAL_SECTION *cs_ring; + +void unlock_ring() { + LeaveCriticalSection(cs_ring); +} + +void lock_ring() { + if (!cs_ring) { + cs_ring = (CRITICAL_SECTION*)malloc(sizeof(CRITICAL_SECTION)); + InitializeCriticalSection(cs_ring); + } + EnterCriticalSection(cs_ring); +} + +// +// 'unlock_function()' - Release the lock. +// + +static void unlock_function() { + LeaveCriticalSection(&cs); +} + +// +// 'lock_function()' - Get the lock. +// + +static void lock_function() { + EnterCriticalSection(&cs); +} + +void Fl::lock() { + if (!main_thread) InitializeCriticalSection(&cs); + + lock_function(); + + if (!main_thread) { + fl_lock_function = lock_function; + fl_unlock_function = unlock_function; + main_thread = GetCurrentThreadId(); + } +} + +void Fl::unlock() { + unlock_function(); +} + +void Fl::awake(void* msg) { + PostThreadMessage( main_thread, fl_wake_msg, (WPARAM)msg, 0); +} + +//////////////////////////////////////////////////////////////// +// POSIX threading... +#elif HAVE_PTHREAD +# include +# include +# include + +// Pipe for thread messaging via Fl::awake()... +static int thread_filedes[2]; + +// Mutex and state information for Fl::lock() and Fl::unlock()... +static pthread_mutex_t fltk_mutex; +static pthread_t owner; +static int counter; + +static void lock_function_init_std() { + pthread_mutex_init(&fltk_mutex, NULL); +} + +static void lock_function_std() { + if (!counter || owner != pthread_self()) { + pthread_mutex_lock(&fltk_mutex); + owner = pthread_self(); + } + counter++; +} + +static void unlock_function_std() { + if (!--counter) pthread_mutex_unlock(&fltk_mutex); +} + +# ifdef PTHREAD_MUTEX_RECURSIVE +static bool lock_function_init_rec() { + pthread_mutexattr_t attrib; + pthread_mutexattr_init(&attrib); + if (pthread_mutexattr_settype(&attrib, PTHREAD_MUTEX_RECURSIVE)) { + pthread_mutexattr_destroy(&attrib); + return true; + } + + pthread_mutex_init(&fltk_mutex, &attrib); + return false; +} + +static void lock_function_rec() { + pthread_mutex_lock(&fltk_mutex); +} + +static void unlock_function_rec() { + pthread_mutex_unlock(&fltk_mutex); +} +# endif // PTHREAD_MUTEX_RECURSIVE + +void Fl::awake(void* msg) { + if (write(thread_filedes[1], &msg, sizeof(void*))==0) { /* ignore */ } +} + +static void* thread_message_; +void* Fl::thread_message() { + void* r = thread_message_; + thread_message_ = 0; + return r; +} + +static void thread_awake_cb(int fd, void*) { + if (read(fd, &thread_message_, sizeof(void*))==0) { + /* This should never happen */ + } + Fl_Awake_Handler func; + void *data; + while (Fl::get_awake_handler_(func, data)==0) { + (*func)(data); + } +} + +// These pointers are in Fl_x.cxx: +extern void (*fl_lock_function)(); +extern void (*fl_unlock_function)(); + +void Fl::lock() { + if (!thread_filedes[1]) { + // Initialize thread communication pipe to let threads awake FLTK + // from Fl::wait() + if (pipe(thread_filedes)==-1) { + /* this should not happen */ + } + + // Make the write side of the pipe non-blocking to avoid deadlock + // conditions (STR #1537) + fcntl(thread_filedes[1], F_SETFL, + fcntl(thread_filedes[1], F_GETFL) | O_NONBLOCK); + + // Monitor the read side of the pipe so that messages sent via + // Fl::awake() from a thread will "wake up" the main thread in + // Fl::wait(). + Fl::add_fd(thread_filedes[0], FL_READ, thread_awake_cb); + + // Set lock/unlock functions for this system, using a system-supplied + // recursive mutex if supported... +# ifdef PTHREAD_MUTEX_RECURSIVE + if (!lock_function_init_rec()) { + fl_lock_function = lock_function_rec; + fl_unlock_function = unlock_function_rec; + } else { +# endif // PTHREAD_MUTEX_RECURSIVE + lock_function_init_std(); + fl_lock_function = lock_function_std; + fl_unlock_function = unlock_function_std; +# ifdef PTHREAD_MUTEX_RECURSIVE + } +# endif // PTHREAD_MUTEX_RECURSIVE + } + + fl_lock_function(); +} + +void Fl::unlock() { + fl_unlock_function(); +} + +// Mutex code for the awake ring buffer +static pthread_mutex_t *ring_mutex; + +void unlock_ring() { + pthread_mutex_unlock(ring_mutex); +} + +void lock_ring() { + if (!ring_mutex) { + ring_mutex = (pthread_mutex_t*)malloc(sizeof(pthread_mutex_t)); + pthread_mutex_init(ring_mutex, NULL); + } + pthread_mutex_lock(ring_mutex); +} + +#else + +void unlock_ring() { +} + +void lock_ring() { +} + +void Fl::awake(void*) { +} + +#endif // WIN32 + +// +// End of "$Id: Fl_lock.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_mac.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_mac.cxx new file mode 100644 index 0000000..82d9f6a --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_mac.cxx @@ -0,0 +1,2870 @@ +// +// "$Id: Fl_mac.cxx 7351 2010-03-29 10:35:00Z matt $" +// +// MacOS specific code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2009 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +//// From the inner edge of a MetroWerks CodeWarrior CD: +// (without permission) +// +// "Three Compiles for 68Ks under the sky, +// Seven Compiles for PPCs in their fragments of code, +// Nine Compiles for Mortal Carbon doomed to die, +// One Compile for Mach-O Cocoa on its Mach-O throne, +// in the Land of MacOS X where the Drop-Shadows lie. +// +// One Compile to link them all, One Compile to merge them, +// One Compile to copy them all and in the bundle bind them, +// in the Land of MacOS X where the Drop-Shadows lie." + +// warning: the Apple Quartz version still uses some Quickdraw calls, +// mostly to get around the single active context in QD and +// to implement clipping. This should be changed into pure +// Quartz calls in the near future. + +// FIXME moving away from Carbon, I am replacing the Scrap manager calls with Pasteboard +// calls that support utf8 encoding. As soon as these function haven proven working +// the Scrap manager calls should be removed +#define USE_PASTEBOARD 1 + +// we don't need the following definition because we deliver only +// true mouse moves. On very slow systems however, this flag may +// still be useful. +#ifndef FL_DOXYGEN + +#define CONSOLIDATE_MOTION 0 +extern "C" { +#include +} + +#include +#include +#include +#include +#include +#include +#include +#include +#include "flstring.h" +#include + +// #define DEBUG_SELECT // UNCOMMENT FOR SELECT()/THREAD DEBUGGING +#ifdef DEBUG_SELECT +#include // testing +#define DEBUGMSG(msg) if ( msg ) fprintf(stderr, msg); +#define DEBUGPERRORMSG(msg) if ( msg ) perror(msg) +#define DEBUGTEXT(txt) txt +#else +#define DEBUGMSG(msg) +#define DEBUGPERRORMSG(msg) +#define DEBUGTEXT(txt) NULL +#endif /*DEBUG_SELECT*/ + +// external functions +extern Fl_Window* fl_find(Window); +extern void fl_fix_focus(); + +// forward definition of functions in this file +static void handleUpdateEvent( WindowPtr xid ); +//+ int fl_handle(const EventRecord &event); +static int FSSpec2UnixPath( FSSpec *fs, char *dst ); +// converting cr lf converter function +static void convert_crlf(char * string, size_t len); + +// public variables +int fl_screen; +CGContextRef fl_gc = 0; +Handle fl_system_menu; +Fl_Sys_Menu_Bar *fl_sys_menu_bar = 0; +CursHandle fl_default_cursor; +WindowRef fl_capture = 0; // we need this to compensate for a missing(?) mouse capture +ulong fl_event_time; // the last timestamp from an x event +char fl_key_vector[32]; // used by Fl::get_key() +bool fl_show_iconic; // true if called from iconize() - shows the next created window in collapsed state +int fl_disable_transient_for; // secret method of removing TRANSIENT_FOR +const Fl_Window* fl_modal_for; // parent of modal() window +Fl_Region fl_window_region = 0; +Window fl_window; +Fl_Window *Fl_Window::current_; +EventRef fl_os_event; // last (mouse) event + +// forward declarations of variables in this file +static int got_events = 0; +static Fl_Window* resize_from_system; +static CursPtr default_cursor_ptr; +static Cursor default_cursor; +static WindowRef fl_os_capture = 0; // the dispatch handler will redirect mose move and drag events to these windows + +#if CONSOLIDATE_MOTION +static Fl_Window* send_motion; +extern Fl_Window* fl_xmousewin; +#endif + +enum { kEventClassFLTK = 'fltk' }; +enum { kEventFLTKBreakLoop = 1, kEventFLTKDataReady }; + +/* fltk-utf8 placekeepers */ +void fl_reset_spot() +{ +} + +void fl_set_spot(int font, int size, int X, int Y, int W, int H, Fl_Window *win) +{ +} + +void fl_set_status(int x, int y, int w, int h) +{ +} + +/** +* Mac keyboard lookup table + */ +static unsigned short macKeyLookUp[128] = +{ + 'a', 's', 'd', 'f', 'h', 'g', 'z', 'x', + 'c', 'v', '^', 'b', 'q', 'w', 'e', 'r', + + 'y', 't', '1', '2', '3', '4', '6', '5', + '=', '9', '7', '-', '8', '0', ']', 'o', + + 'u', '[', 'i', 'p', FL_Enter, 'l', 'j', '\'', + 'k', ';', '\\', ',', '/', 'n', 'm', '.', + + FL_Tab, ' ', '`', FL_BackSpace, + FL_KP_Enter, FL_Escape, 0, 0/*FL_Meta_L*/, + 0/*FL_Shift_L*/, 0/*FL_Caps_Lock*/, 0/*FL_Alt_L*/, 0/*FL_Control_L*/, + 0/*FL_Shift_R*/, 0/*FL_Alt_R*/, 0/*FL_Control_R*/, 0, + + 0, FL_KP+'.', FL_Right, FL_KP+'*', 0, FL_KP+'+', FL_Left, FL_Delete, + FL_Down, 0, 0, FL_KP+'/', FL_KP_Enter, FL_Up, FL_KP+'-', 0, + + 0, FL_KP+'=', FL_KP+'0', FL_KP+'1', FL_KP+'2', FL_KP+'3', FL_KP+'4', FL_KP+'5', + FL_KP+'6', FL_KP+'7', 0, FL_KP+'8', FL_KP+'9', 0, 0, 0, + + FL_F+5, FL_F+6, FL_F+7, FL_F+3, FL_F+8, FL_F+9, 0, FL_F+11, + 0, 0/*FL_F+13*/, FL_Print, FL_Scroll_Lock, 0, FL_F+10, FL_Menu, FL_F+12, + + 0, FL_Pause, FL_Help, FL_Home, FL_Page_Up, FL_Delete, FL_F+4, FL_End, + FL_F+2, FL_Page_Down, FL_F+1, FL_Left, FL_Right, FL_Down, FL_Up, 0/*FL_Power*/, +}; + +/** + * convert the current mouse chord into the FLTK modifier state + */ +static unsigned int mods_to_e_state( UInt32 mods ) +{ + long state = 0; + if ( mods & kEventKeyModifierNumLockMask ) state |= FL_NUM_LOCK; + if ( mods & cmdKey ) state |= FL_META; + if ( mods & (optionKey|rightOptionKey) ) state |= FL_ALT; + if ( mods & (controlKey|rightControlKey) ) state |= FL_CTRL; + if ( mods & (shiftKey|rightShiftKey) ) state |= FL_SHIFT; + if ( mods & alphaLock ) state |= FL_CAPS_LOCK; + unsigned int ret = ( Fl::e_state & 0xff000000 ) | state; + Fl::e_state = ret; + //printf( "State 0x%08x (%04x)\n", Fl::e_state, mods ); + return ret; +} + + +/** + * convert the current mouse chord into the FLTK keysym + */ +static void mods_to_e_keysym( UInt32 mods ) +{ + if ( mods & cmdKey ) Fl::e_keysym = FL_Meta_L; + else if ( mods & kEventKeyModifierNumLockMask ) Fl::e_keysym = FL_Num_Lock; + else if ( mods & optionKey ) Fl::e_keysym = FL_Alt_L; + else if ( mods & rightOptionKey ) Fl::e_keysym = FL_Alt_R; + else if ( mods & controlKey ) Fl::e_keysym = FL_Control_L; + else if ( mods & rightControlKey ) Fl::e_keysym = FL_Control_R; + else if ( mods & shiftKey ) Fl::e_keysym = FL_Shift_L; + else if ( mods & rightShiftKey ) Fl::e_keysym = FL_Shift_R; + else if ( mods & alphaLock ) Fl::e_keysym = FL_Caps_Lock; + else Fl::e_keysym = 0; + //printf( "to sym 0x%08x (%04x)\n", Fl::e_keysym, mods ); +} +// these pointers are set by the Fl::lock() function: +static void nothing() {} +void (*fl_lock_function)() = nothing; +void (*fl_unlock_function)() = nothing; + +// +// Select interface -- how it's implemented: +// When the user app configures one or more file descriptors to monitor +// with Fl::add_fd(), we start a separate thread to select() the data, +// sending a custom OSX 'FLTK data ready event' to the parent thread's +// RunApplicationLoop(), so that it triggers the data ready callbacks +// in the parent thread. -erco 04/04/04 +// +#define POLLIN 1 +#define POLLOUT 4 +#define POLLERR 8 + +// Class to handle select() 'data ready' +class DataReady +{ + struct FD + { + int fd; + short events; + void (*cb)(int, void*); + void* arg; + }; + int nfds, fd_array_size; + FD *fds; + pthread_t tid; // select()'s thread id + + // Data that needs to be locked (all start with '_') + pthread_mutex_t _datalock; // data lock + fd_set _fdsets[3]; // r/w/x sets user wants to monitor + int _maxfd; // max fd count to monitor + int _cancelpipe[2]; // pipe used to help cancel thread + void *_userdata; // thread's userdata + +public: + DataReady() + { + nfds = 0; + fd_array_size = 0; + fds = 0; + tid = 0; + + pthread_mutex_init(&_datalock, NULL); + FD_ZERO(&_fdsets[0]); FD_ZERO(&_fdsets[1]); FD_ZERO(&_fdsets[2]); + _cancelpipe[0] = _cancelpipe[1] = 0; + _userdata = 0; + _maxfd = 0; + } + + ~DataReady() + { + CancelThread(DEBUGTEXT("DESTRUCTOR\n")); + if (fds) { free(fds); fds = 0; } + nfds = 0; + } + + // Locks + // The convention for locks: volatile vars start with '_', + // and must be locked before use. Locked code is prefixed + // with /*LOCK*/ to make painfully obvious esp. in debuggers. -erco + // + void DataLock() { pthread_mutex_lock(&_datalock); } + void DataUnlock() { pthread_mutex_unlock(&_datalock); } + + // Accessors + int IsThreadRunning() { return(tid ? 1 : 0); } + int GetNfds() { return(nfds); } + int GetCancelPipe(int ix) { return(_cancelpipe[ix]); } + fd_set GetFdset(int ix) { return(_fdsets[ix]); } + + // Methods + void AddFD(int n, int events, void (*cb)(int, void*), void *v); + void RemoveFD(int n, int events); + int CheckData(fd_set& r, fd_set& w, fd_set& x); + void HandleData(fd_set& r, fd_set& w, fd_set& x); + static void* DataReadyThread(void *self); + void StartThread(void *userdata); + void CancelThread(const char *reason); +}; + +static DataReady dataready; + +void DataReady::AddFD(int n, int events, void (*cb)(int, void*), void *v) +{ + RemoveFD(n, events); + int i = nfds++; + if (i >= fd_array_size) + { + FD *temp; + fd_array_size = 2*fd_array_size+1; + if (!fds) { temp = (FD*)malloc(fd_array_size*sizeof(FD)); } + else { temp = (FD*)realloc(fds, fd_array_size*sizeof(FD)); } + if (!temp) return; + fds = temp; + } + fds[i].cb = cb; + fds[i].arg = v; + fds[i].fd = n; + fds[i].events = events; + DataLock(); + /*LOCK*/ if (events & POLLIN) FD_SET(n, &_fdsets[0]); + /*LOCK*/ if (events & POLLOUT) FD_SET(n, &_fdsets[1]); + /*LOCK*/ if (events & POLLERR) FD_SET(n, &_fdsets[2]); + /*LOCK*/ if (n > _maxfd) _maxfd = n; + DataUnlock(); +} + +// Remove an FD from the array +void DataReady::RemoveFD(int n, int events) +{ + int i,j; + for (i=j=0; iDataLock(); + /*LOCK*/ int maxfd = self->_maxfd; + /*LOCK*/ fd_set r = self->GetFdset(0); + /*LOCK*/ fd_set w = self->GetFdset(1); + /*LOCK*/ fd_set x = self->GetFdset(2); + /*LOCK*/ void *userdata = self->_userdata; + /*LOCK*/ int cancelpipe = self->GetCancelPipe(0); + /*LOCK*/ if ( cancelpipe > maxfd ) maxfd = cancelpipe; + /*LOCK*/ FD_SET(cancelpipe, &r); // add cancelpipe to fd's to watch + /*LOCK*/ FD_SET(cancelpipe, &x); + self->DataUnlock(); + // timeval t = { 1000, 0 }; // 1000 seconds; + timeval t = { 2, 0 }; // HACK: 2 secs prevents 'hanging' problem + int ret = ::select(maxfd+1, &r, &w, &x, &t); + pthread_testcancel(); // OSX 10.0.4 and older: needed for parent to cancel + switch ( ret ) + { + case 0: // NO DATA + continue; + case -1: // ERROR + { + DEBUGPERRORMSG("CHILD THREAD: select() failed"); + return(NULL); // error? exit thread + } + default: // DATA READY + { + if (FD_ISSET(cancelpipe, &r) || FD_ISSET(cancelpipe, &x)) // cancel? + { return(NULL); } // just exit + DEBUGMSG("CHILD THREAD: DATA IS READY\n"); + EventRef drEvent; + CreateEvent( 0, kEventClassFLTK, kEventFLTKDataReady, + 0, kEventAttributeUserEvent, &drEvent); + EventQueueRef eventqueue = (EventQueueRef)userdata; + PostEventToQueue(eventqueue, drEvent, kEventPriorityStandard ); + ReleaseEvent( drEvent ); + return(NULL); // done with thread + } + } + } +} + +// START 'DATA READY' THREAD RUNNING, CREATE INTER-THREAD PIPE +void DataReady::StartThread(void *new_userdata) +{ + CancelThread(DEBUGTEXT("STARTING NEW THREAD\n")); + DataLock(); + /*LOCK*/ pipe(_cancelpipe); // pipe for sending cancel msg to thread + /*LOCK*/ _userdata = new_userdata; + DataUnlock(); + DEBUGMSG("*** START THREAD\n"); + pthread_create(&tid, NULL, DataReadyThread, (void*)this); +} + +// CANCEL 'DATA READY' THREAD, CLOSE PIPE +void DataReady::CancelThread(const char *reason) +{ + if ( tid ) + { + DEBUGMSG("*** CANCEL THREAD: "); + DEBUGMSG(reason); + if ( pthread_cancel(tid) == 0 ) // cancel first + { + DataLock(); + /*LOCK*/ write(_cancelpipe[1], "x", 1); // wake thread from select + DataUnlock(); + pthread_join(tid, NULL); // wait for thread to finish + } + tid = 0; + DEBUGMSG("(JOINED) OK\n"); + } + // Close pipe if open + DataLock(); + /*LOCK*/ if ( _cancelpipe[0] ) { close(_cancelpipe[0]); _cancelpipe[0] = 0; } + /*LOCK*/ if ( _cancelpipe[1] ) { close(_cancelpipe[1]); _cancelpipe[1] = 0; } + DataUnlock(); +} + +void Fl::add_fd( int n, int events, void (*cb)(int, void*), void *v ) + { dataready.AddFD(n, events, cb, v); } + +void Fl::add_fd(int fd, void (*cb)(int, void*), void* v) + { dataready.AddFD(fd, POLLIN, cb, v); } + +void Fl::remove_fd(int n, int events) + { dataready.RemoveFD(n, events); } + +void Fl::remove_fd(int n) + { dataready.RemoveFD(n, -1); } + +/** + * Check if there is actually a message pending! + */ +int fl_ready() +{ + EventRef event; + return !ReceiveNextEvent(0, NULL, 0.0, false, &event); +} + +/** + * handle Apple Menu items (can be created using the Fl_Sys_Menu_Bar + * returns eventNotHandledErr if the menu item could not be handled + */ +OSStatus HandleMenu( HICommand *cmd ) +{ + OSStatus ret = eventNotHandledErr; + // attributes, commandIDm menu.menuRef, menu.menuItemIndex + UInt32 ref; + OSErr rrc = GetMenuItemRefCon( cmd->menu.menuRef, cmd->menu.menuItemIndex, &ref ); + //printf( "%d, %08x, %08x, %d, %d, %8x\n", rrc, cmd->attributes, cmd->commandID, cmd->menu.menuRef, cmd->menu.menuItemIndex, rrc ); + if ( rrc==noErr && ref ) + { + Fl_Menu_Item *m = (Fl_Menu_Item*)ref; + //printf( "Menu: %s\n", m->label() ); + fl_sys_menu_bar->picked( m ); + if ( m->flags & FL_MENU_TOGGLE ) // update the menu toggle symbol + SetItemMark( cmd->menu.menuRef, cmd->menu.menuItemIndex, (m->flags & FL_MENU_VALUE ) ? 0x12 : 0 ); + if ( m->flags & FL_MENU_RADIO ) // update all radio buttons in this menu + { + Fl_Menu_Item *j = m; + int i = cmd->menu.menuItemIndex; + for (;;) + { + if ( j->flags & FL_MENU_DIVIDER ) + break; + j++; i++; + if ( !j->text || !j->radio() ) + break; + SetItemMark( cmd->menu.menuRef, i, ( j->flags & FL_MENU_VALUE ) ? 0x13 : 0 ); + } + j = m-1; i = cmd->menu.menuItemIndex-1; + for ( ; i>0; j--, i-- ) + { + if ( !j->text || j->flags&FL_MENU_DIVIDER || !j->radio() ) + break; + SetItemMark( cmd->menu.menuRef, i, ( j->flags & FL_MENU_VALUE ) ? 0x13 : 0 ); + } + SetItemMark( cmd->menu.menuRef, cmd->menu.menuItemIndex, ( m->flags & FL_MENU_VALUE ) ? 0x13 : 0 ); + } + ret = noErr; // done handling this event + } + HiliteMenu(0); + return ret; +} + + +/** + * We can make every event pass through this function + * - mouse events need to be manipulated to use a mouse focus window + * - keyboard, mouse and some window events need to quit the Apple Event Loop + * so FLTK can continue its own management + */ +static pascal OSStatus carbonDispatchHandler( EventHandlerCallRef nextHandler, EventRef event, void *userData ) +{ + OSStatus ret = eventNotHandledErr; + HICommand cmd; + + fl_lock_function(); + + got_events = 1; + + switch ( GetEventClass( event ) ) + { + case kEventClassMouse: + switch ( GetEventKind( event ) ) + { + case kEventMouseUp: + case kEventMouseMoved: + case kEventMouseDragged: + if ( fl_capture ) + ret = SendEventToEventTarget( event, GetWindowEventTarget( fl_capture ) ); + else if ( fl_os_capture ){ + ret = SendEventToEventTarget( event, GetWindowEventTarget( fl_os_capture ) ); + fl_os_capture = 0; + } + break; + } + break; + case kEventClassCommand: + switch (GetEventKind( event ) ) + { + case kEventCommandProcess: + ret = GetEventParameter( event, kEventParamDirectObject, typeHICommand, NULL, sizeof(HICommand), NULL, &cmd ); + if (ret == noErr && (cmd.attributes & kHICommandFromMenu) != 0) + ret = HandleMenu( &cmd ); + else + ret = eventNotHandledErr; + break; + } + break; + case kEventClassFLTK: + switch ( GetEventKind( event ) ) + { + case kEventFLTKBreakLoop: + ret = noErr; + break; + case kEventFLTKDataReady: + { + dataready.CancelThread(DEBUGTEXT("DATA READY EVENT\n")); + + // CHILD THREAD TELLS US DATA READY + // Check to see what's ready, and invoke user's cb's + // + fd_set r,w,x; + switch(dataready.CheckData(r,w,x)) + { + case 0: // NO DATA + break; + case -1: // ERROR + break; + default: // DATA READY + dataready.HandleData(r,w,x); + break; + } + } + ret = noErr; + break; + } + } + if ( ret == eventNotHandledErr ) + ret = CallNextEventHandler( nextHandler, event ); // let the OS handle the activation, but continue to get a click-through effect + + fl_unlock_function(); + + return ret; +} + + +/** + * break the current event loop + */ +static void breakMacEventLoop() +{ + EventRef breakEvent; + + fl_lock_function(); + + CreateEvent( 0, kEventClassFLTK, kEventFLTKBreakLoop, 0, kEventAttributeUserEvent, &breakEvent ); + PostEventToQueue( GetCurrentEventQueue(), breakEvent, kEventPriorityStandard ); + ReleaseEvent( breakEvent ); + + fl_unlock_function(); +} + +// +// MacOS X timers +// + +struct MacTimeout { + Fl_Timeout_Handler callback; + void* data; + EventLoopTimerRef timer; + EventLoopTimerUPP upp; + char pending; +}; +static MacTimeout* mac_timers; +static int mac_timer_alloc; +static int mac_timer_used; + + +static void realloc_timers() +{ + if (mac_timer_alloc == 0) { + mac_timer_alloc = 8; + } + mac_timer_alloc *= 2; + MacTimeout* new_timers = new MacTimeout[mac_timer_alloc]; + memset(new_timers, 0, sizeof(MacTimeout)*mac_timer_alloc); + memcpy(new_timers, mac_timers, sizeof(MacTimeout) * mac_timer_used); + MacTimeout* delete_me = mac_timers; + mac_timers = new_timers; + delete [] delete_me; +} + +static void delete_timer(MacTimeout& t) +{ + if (t.timer) { + RemoveEventLoopTimer(t.timer); + DisposeEventLoopTimerUPP(t.upp); + memset(&t, 0, sizeof(MacTimeout)); + } +} + + +static pascal void do_timer(EventLoopTimerRef timer, void* data) +{ + for (int i = 0; i < mac_timer_used; ++i) { + MacTimeout& t = mac_timers[i]; + if (t.timer == timer && t.data == data) { + t.pending = 0; + (*t.callback)(data); + if (t.pending==0) + delete_timer(t); + break; + } + } + breakMacEventLoop(); +} + +/** + * This function is the central event handler. + * It reads events from the event queue using the given maximum time + * Funny enough, it returns the same time that it got as the argument. + */ +static double do_queued_events( double time = 0.0 ) +{ + static bool been_here = false; + static RgnHandle rgn; + + // initialize events and a region that enables mouse move events + if (!been_here) { + rgn = NewRgn(); + Point mp; + GetMouse(&mp); + SetRectRgn(rgn, mp.h, mp.v, mp.h, mp.v); + SetEventMask(everyEvent); + been_here = true; + } + OSStatus ret; + static EventTargetRef target = 0; + if ( !target ) + { + target = GetEventDispatcherTarget(); + + EventHandlerUPP dispatchHandler = NewEventHandlerUPP( carbonDispatchHandler ); // will not be disposed by Carbon... + static EventTypeSpec dispatchEvents[] = { + { kEventClassWindow, kEventWindowShown }, + { kEventClassWindow, kEventWindowHidden }, + { kEventClassWindow, kEventWindowActivated }, + { kEventClassWindow, kEventWindowDeactivated }, + { kEventClassWindow, kEventWindowClose }, + { kEventClassKeyboard, kEventRawKeyDown }, + { kEventClassKeyboard, kEventRawKeyRepeat }, + { kEventClassKeyboard, kEventRawKeyUp }, + { kEventClassKeyboard, kEventRawKeyModifiersChanged }, + { kEventClassMouse, kEventMouseDown }, + { kEventClassMouse, kEventMouseUp }, + { kEventClassMouse, kEventMouseMoved }, + { kEventClassMouse, 11 }, // MightyMouse wheels + { kEventClassMouse, kEventMouseWheelMoved }, + { kEventClassMouse, kEventMouseDragged }, + { kEventClassFLTK, kEventFLTKBreakLoop }, + { kEventClassFLTK, kEventFLTKDataReady } }; + ret = InstallEventHandler( target, dispatchHandler, GetEventTypeCount(dispatchEvents), dispatchEvents, 0, 0L ); + static EventTypeSpec appEvents[] = { + { kEventClassCommand, kEventCommandProcess } }; + ret = InstallApplicationEventHandler( dispatchHandler, GetEventTypeCount(appEvents), appEvents, 0, 0L ); + } + + got_events = 0; + + // Check for re-entrant condition + if ( dataready.IsThreadRunning() ) + { dataready.CancelThread(DEBUGTEXT("AVOID REENTRY\n")); } + + // Start thread to watch for data ready + if ( dataready.GetNfds() ) + { dataready.StartThread((void*)GetCurrentEventQueue()); } + + fl_unlock_function(); + + EventRef event; + EventTimeout timeout = time; + if (!ReceiveNextEvent(0, NULL, timeout, true, &event)) { + got_events = 1; + OSErr ret = SendEventToEventTarget( event, target ); + if (ret!=noErr) { + EventRecord clevent; + ConvertEventRefToEventRecord(event, &clevent); + if (clevent.what==kHighLevelEvent) { + ret = AEProcessAppleEvent(&clevent); + } + } + if ( ret==eventNotHandledErr + && GetEventClass(event)==kEventClassMouse + && GetEventKind(event)==kEventMouseDown ) { + WindowRef win; Point pos; + GetEventParameter(event, kEventParamMouseLocation, typeQDPoint, + NULL, sizeof(pos), NULL, &pos); + if (MacFindWindow(pos, &win)==inMenuBar) { + MenuSelect(pos); + } + } + ReleaseEvent( event ); + } + + fl_lock_function(); + +#if CONSOLIDATE_MOTION + if (send_motion && send_motion == fl_xmousewin) { + send_motion = 0; + Fl::handle(FL_MOVE, fl_xmousewin); + } +#endif + + return time; +} + + +/** + * This public function handles all events. It wait a maximum of + * 'time' secods for an event. This version returns 1 if events + * other than the timeout timer were processed. + * + * \todo there is no socket handling in this code whatsoever + */ +int fl_wait( double time ) +{ + do_queued_events( time ); + return (got_events); +} + + +/** + * event handler for Apple-Q key combination + * this is also called from the Carbon Window handler after all windows were closed + */ +static OSErr QuitAppleEventHandler( const AppleEvent *appleEvt, AppleEvent* reply, UInt32 refcon ) +{ + fl_lock_function(); + + while ( Fl_X::first ) { + Fl_X *x = Fl_X::first; + Fl::handle( FL_CLOSE, x->w ); + if ( Fl_X::first == x ) { + fl_unlock_function(); + return noErr; // FLTK has not close all windows, so we return to the main program now + } + } + + fl_unlock_function(); + + return noErr; +} + + +/** + * Carbon Window handler + * This needs to be linked into all new window event handlers + */ +static pascal OSStatus carbonWindowHandler( EventHandlerCallRef nextHandler, EventRef event, void *userData ) +{ + UInt32 kind = GetEventKind( event ); + OSStatus ret = eventNotHandledErr; + Fl_Window *window = (Fl_Window*)userData; + Fl::first_window(window); + + Rect currentBounds, originalBounds; + WindowClass winClass; + static Fl_Window *activeWindow = 0; + + fl_lock_function(); + + switch ( kind ) + { + case kEventWindowBoundsChanging: + GetEventParameter( event, kEventParamCurrentBounds, typeQDRectangle, NULL, sizeof(Rect), NULL, ¤tBounds ); + GetEventParameter( event, kEventParamOriginalBounds, typeQDRectangle, NULL, sizeof(Rect), NULL, &originalBounds ); + break; + case kEventWindowDrawContent: + handleUpdateEvent( fl_xid( window ) ); + ret = noErr; + break; + case kEventWindowBoundsChanged: { + GetEventParameter( event, kEventParamCurrentBounds, typeQDRectangle, NULL, sizeof(Rect), NULL, ¤tBounds ); + GetEventParameter( event, kEventParamOriginalBounds, typeQDRectangle, NULL, sizeof(Rect), NULL, &originalBounds ); + int X = currentBounds.left, W = currentBounds.right-X; + int Y = currentBounds.top, H = currentBounds.bottom-Y; + resize_from_system = window; + window->resize( X, Y, W, H ); + if ( ( originalBounds.right - originalBounds.left != W ) + || ( originalBounds.bottom - originalBounds.top != H ) ) + { + if ( window->shown() ) + handleUpdateEvent( fl_xid( window ) ); + } + break; } + case kEventWindowShown: + if ( !window->parent() ) + { + GetWindowClass( fl_xid( window ), &winClass ); + if ( winClass != kHelpWindowClass ) { // help windows can't get the focus! + Fl::handle( FL_FOCUS, window); + activeWindow = window; + } + Fl::handle( FL_SHOW, window); + mods_to_e_state(GetCurrentKeyModifiers()); + } + break; + case kEventWindowHidden: + if ( !window->parent() ) Fl::handle( FL_HIDE, window); + break; + case kEventWindowActivated: + if ( window->shown() && window!=activeWindow ) + { + GetWindowClass( fl_xid( window ), &winClass ); + if ( winClass != kHelpWindowClass ) { // help windows can't get the focus! + Fl::handle( FL_FOCUS, window); + activeWindow = window; + } + } + break; + case kEventWindowDeactivated: + if ( window==activeWindow ) + { + Fl::handle( FL_UNFOCUS, window); + activeWindow = 0; + } + break; + case kEventWindowClose: + Fl::handle( FL_CLOSE, window ); // this might or might not close the window + // if there are no more windows, send a high-level quit event + if (!Fl_X::first) QuitAppleEventHandler( 0, 0, 0 ); + ret = noErr; // returning noErr tells Carbon to stop following up on this event + break; + case kEventWindowCollapsed: + window->clear_visible(); + break; + case kEventWindowExpanded: + window->set_visible(); + break; + } + + fl_unlock_function(); + + return ret; +} + + +/** + * Carbon Mousewheel handler + * This needs to be linked into all new window event handlers + */ +static pascal OSStatus carbonMousewheelHandler( EventHandlerCallRef nextHandler, EventRef event, void *userData ) +{ + // Handle the new "MightyMouse" mouse wheel events. Please, someone explain + // to me why Apple changed the API on this even though the current API + // supports two wheels just fine. Matthias, + fl_lock_function(); + + fl_os_event = event; + Fl_Window *window = (Fl_Window*)userData; + if ( !window->shown() ) + { + fl_unlock_function(); + return noErr; + } + Fl::first_window(window); + + EventMouseWheelAxis axis; + GetEventParameter( event, kEventParamMouseWheelAxis, typeMouseWheelAxis, NULL, sizeof(EventMouseWheelAxis), NULL, &axis ); + long delta; + GetEventParameter( event, kEventParamMouseWheelDelta, typeLongInteger, NULL, sizeof(long), NULL, &delta ); +// fprintf(stderr, "axis=%d, delta=%d\n", axis, delta); + if ( axis == kEventMouseWheelAxisX ) { + Fl::e_dx = -delta; + Fl::e_dy = 0; + if ( Fl::e_dx) Fl::handle( FL_MOUSEWHEEL, window ); + } else if ( axis == kEventMouseWheelAxisY ) { + Fl::e_dx = 0; + Fl::e_dy = -delta; + if ( Fl::e_dy) Fl::handle( FL_MOUSEWHEEL, window ); + } else { + fl_unlock_function(); + + return eventNotHandledErr; + } + + fl_unlock_function(); + + return noErr; +} + + +/** + * convert the current mouse chord into the FLTK modifier state + */ +static void chord_to_e_state( UInt32 chord ) +{ + static ulong state[] = + { + 0, FL_BUTTON1, FL_BUTTON3, FL_BUTTON1|FL_BUTTON3, FL_BUTTON2, + FL_BUTTON2|FL_BUTTON1, FL_BUTTON2|FL_BUTTON3, + FL_BUTTON2|FL_BUTTON1|FL_BUTTON3 + }; + Fl::e_state = ( Fl::e_state & 0xff0000 ) | state[ chord & 0x07 ]; +} + + +/** + * Carbon Mouse Button Handler + */ +static pascal OSStatus carbonMouseHandler( EventHandlerCallRef nextHandler, EventRef event, void *userData ) +{ + static int keysym[] = { 0, FL_Button+1, FL_Button+3, FL_Button+2 }; + static int px, py; + static char suppressed = 0; + + fl_lock_function(); + + fl_os_event = event; + Fl_Window *window = (Fl_Window*)userData; + if ( !window->shown() ) + { + fl_unlock_function(); + return noErr; + } + Fl::first_window(window); + Point pos; + GetEventParameter( event, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(Point), NULL, &pos ); + EventMouseButton btn; + GetEventParameter( event, kEventParamMouseButton, typeMouseButton, NULL, sizeof(EventMouseButton), NULL, &btn ); + UInt32 clickCount; + GetEventParameter( event, kEventParamClickCount, typeUInt32, NULL, sizeof(UInt32), NULL, &clickCount ); + UInt32 chord; + GetEventParameter( event, kEventParamMouseChord, typeUInt32, NULL, sizeof(UInt32), NULL, &chord ); + WindowRef xid = fl_xid(window), tempXid; + int sendEvent = 0, part = 0; + switch ( GetEventKind( event ) ) + { + case kEventMouseDown: + part = FindWindow( pos, &tempXid ); + if (!(Fl::grab() && window!=Fl::grab())) { + if ( part == inGrow ) { + fl_unlock_function(); + suppressed = 1; + Fl_Tooltip::current(0L); + return CallNextEventHandler( nextHandler, event ); // let the OS handle this for us + } + if ( part != inContent ) { + fl_unlock_function(); + suppressed = 1; + Fl_Tooltip::current(0L); + // anything else to here? + return CallNextEventHandler( nextHandler, event ); // let the OS handle this for us + } + } + suppressed = 0; + if (part==inContent && !IsWindowActive( xid ) ) { + CallNextEventHandler( nextHandler, event ); // let the OS handle the activation, but continue to get a click-through effect + } + // normal handling of mouse-down follows + fl_os_capture = xid; + sendEvent = FL_PUSH; + Fl::e_is_click = 1; px = pos.h; py = pos.v; + if (clickCount>1) + Fl::e_clicks++; + else + Fl::e_clicks = 0; + // fall through + case kEventMouseUp: + if (suppressed) { + suppressed = 0; + break; + } + if ( !window ) break; + if ( !sendEvent ) { + sendEvent = FL_RELEASE; + } + Fl::e_keysym = keysym[ btn ]; + // fall through + case kEventMouseMoved: + suppressed = 0; + if ( !sendEvent ) { + sendEvent = FL_MOVE; chord = 0; + } + // fall through + case kEventMouseDragged: + if (suppressed) break; + if ( !sendEvent ) { + sendEvent = FL_MOVE; // Fl::handle will convert into FL_DRAG + if (abs(pos.h-px)>5 || abs(pos.v-py)>5) + Fl::e_is_click = 0; + } + chord_to_e_state( chord ); + GrafPtr oldPort; + GetPort( &oldPort ); + SetPort( GetWindowPort(xid) ); // \todo replace this! There must be some GlobalToLocal call that has a port as an argument + SetOrigin(0, 0); + Fl::e_x_root = pos.h; + Fl::e_y_root = pos.v; + GlobalToLocal( &pos ); + Fl::e_x = pos.h; + Fl::e_y = pos.v; + SetPort( oldPort ); + if (GetEventKind(event)==kEventMouseDown && part!=inContent) { + int used = Fl::handle( sendEvent, window ); + CallNextEventHandler( nextHandler, event ); // let the OS handle this for us + if (!used) + suppressed = 1; + } else { + Fl::handle( sendEvent, window ); + } + break; + } + + fl_unlock_function(); + + return noErr; +} + + +/** + * convert the keyboard return code into the symbol on the keycaps + */ +static unsigned short keycode_to_sym( UInt32 keyCode, UInt32 mods, unsigned short deflt ) +{ + static Ptr map = 0; + UInt32 state = 0; + if (!map) { + map = (Ptr)GetScriptManagerVariable(smKCHRCache); + if (!map) { + long kbID = GetScriptManagerVariable(smKeyScript); + map = *GetResource('KCHR', kbID); + } + } + if (map) + return KeyTranslate(map, keyCode|mods, &state ); + return deflt; +} + +/* + * keycode_function for post-10.5 systems, allows more sophisticated decoding of keys + */ +static int keycodeToUnicode( + char * uniChars, int maxChars, + EventKind eKind, + UInt32 keycode, UInt32 modifiers, + UInt32 * deadKeyStatePtr, + unsigned char, // not used in this function + unsigned short) // not used in this function +{ + // first get the keyboard mapping in a post 10.2 way + + Ptr resource; + TextEncoding encoding; + static TextEncoding lastEncoding = kTextEncodingMacRoman; + int len = 0; + KeyboardLayoutRef currentLayout = NULL; + static KeyboardLayoutRef lastLayout = NULL; + SInt32 currentLayoutId = 0; + static SInt32 lastLayoutId; + int hasLayoutChanged = false; + static Ptr uchr = NULL; + static Ptr KCHR = NULL; + // ScriptCode currentKeyScript; + + KLGetCurrentKeyboardLayout(¤tLayout); + if (currentLayout) { + KLGetKeyboardLayoutProperty(currentLayout, kKLIdentifier, (const void**)¤tLayoutId); + if ( (lastLayout != currentLayout) || (lastLayoutId != currentLayoutId) ) { + lastLayout = currentLayout; + lastLayoutId = currentLayoutId; + uchr = NULL; + KCHR = NULL; + if ((KLGetKeyboardLayoutProperty(currentLayout, kKLuchrData, (const void**)&uchr) == noErr) && (uchr != NULL)) { + // done + } else if ((KLGetKeyboardLayoutProperty(currentLayout, kKLKCHRData, (const void**)&KCHR) == noErr) && (KCHR != NULL)) { + // done + } + // FIXME No Layout property found. Now we have a problem. + } + } + if (hasLayoutChanged) { + //deadKeyStateUp = deadKeyStateDown = 0; + if (KCHR != NULL) { + // FIXME this must not happen + } else if (uchr == NULL) { + KCHR = (Ptr) GetScriptManagerVariable(smKCHRCache); + } + } + if (uchr != NULL) { + // this is what I expect + resource = uchr; + } else { + resource = KCHR; + encoding = lastEncoding; + // this is actually not supported by the following code and will likely crash + } + + // now apply that keyboard mapping to our keycode + + int action; + //OptionBits options = 0; + // not used yet: OptionBits options = kUCKeyTranslateNoDeadKeysMask; + unsigned long keyboardType; + keycode &= 0xFF; + modifiers = (modifiers >> 8) & 0xFF; + keyboardType = LMGetKbdType(); + OSStatus status; + UniCharCount actuallength; + UniChar utext[10]; + + switch(eKind) { + case kEventRawKeyDown: action = kUCKeyActionDown; break; + case kEventRawKeyUp: action = kUCKeyActionUp; break; + case kEventRawKeyRepeat: action = kUCKeyActionAutoKey; break; + default: return 0; + } + + UInt32 deadKeyState = *deadKeyStatePtr; + if ((action==kUCKeyActionUp)&&(*deadKeyStatePtr)) + deadKeyStatePtr = &deadKeyState; + + status = UCKeyTranslate( + (const UCKeyboardLayout *) uchr, + keycode, action, modifiers, keyboardType, + 0, deadKeyStatePtr, + 10, &actuallength, utext); + + if (noErr != status) { + fprintf(stderr,"UCKeyTranslate failed: %d\n", (int) status); + actuallength = 0; + } + + // convert the list of unicode chars into utf8 + // FIXME no bounds check (see maxchars) + unsigned i; + for (i=0; i= FL_KP && sym <= FL_KP_Last) || !(sym & 0xff00) || + sym == FL_Tab || sym == FL_Enter) { + buffer[0] = key; + return 1; + } else { + buffer[0] = 0; + return 0; + } +} /* keycode_wrap_old */ +/* + * Stub pointer to select appropriate keycode_function per operating system version. This function pointer + * is initialised in fl_open_display, based on the runtime identification of the host OS version. This is + * intended to allow us to utilise 10.5 services dynamically to improve Unicode handling, whilst still + * allowing code to run satisfactorily on older systems. + */ +static int (*keycode_function)(char*, int, EventKind, UInt32, UInt32, UInt32*, unsigned char, unsigned short) = keycode_wrap_old; + + +// EXPERIMENTAL! +pascal OSStatus carbonTextHandler( + EventHandlerCallRef nextHandler, EventRef event, void *userData ) +{ + Fl_Window *window = (Fl_Window*)userData; + Fl::first_window(window); + fl_lock_function(); + //int kind = GetEventKind(event); + unsigned short buf[200]; + ByteCount size; + GetEventParameter( event, kEventParamTextInputSendText, typeUnicodeText, + NULL, 100, &size, &buf ); +// printf("TextEvent: %02x %02x %02x %02x\n", buf[0], buf[1], buf[2], buf[3]); + // FIXME: oversimplified! + unsigned ucs = buf[0]; + char utf8buf[20]; + int len = fl_utf8encode(ucs, utf8buf); + Fl::e_length = len; + Fl::e_text = utf8buf; + while (window->parent()) window = window->window(); + Fl::handle(FL_KEYBOARD, window); + fl_unlock_function(); + fl_lock_function(); + Fl::handle(FL_KEYUP, window); + fl_unlock_function(); + // for some reason, the window does not redraw until the next mouse move or button push + // sending a 'redraw()' or 'awake()' does not solve the issue! + Fl::flush(); + return noErr; +} + +/** + * handle carbon keyboard events + */ +pascal OSStatus carbonKeyboardHandler( + EventHandlerCallRef nextHandler, EventRef event, void *userData ) +{ + static char buffer[32]; + int sendEvent = 0; + Fl_Window *window = (Fl_Window*)userData; + Fl::first_window(window); + UInt32 mods; + static UInt32 prevMods = mods_to_e_state( GetCurrentKeyModifiers() ); + + fl_lock_function(); + + int kind = GetEventKind(event); + + // get the modifiers for any of the events + GetEventParameter( event, kEventParamKeyModifiers, typeUInt32, + NULL, sizeof(UInt32), NULL, &mods ); + + // get the key code only for key events + UInt32 keyCode = 0, maskedKeyCode = 0; + unsigned char key = 0; + unsigned short sym = 0; + if (kind!=kEventRawKeyModifiersChanged) { + GetEventParameter( event, kEventParamKeyCode, typeUInt32, + NULL, sizeof(UInt32), NULL, &keyCode ); + GetEventParameter( event, kEventParamKeyMacCharCodes, typeChar, + NULL, sizeof(char), NULL, &key ); + } + // extended keyboards can also send sequences on key-up to generate Kanji etc. codes. + // Some observed prefixes are 0x81 to 0x83, followed by an 8 bit keycode. + // In this mode, there seem to be no key-down codes +// printf("%08x %08x %08x\n", keyCode, mods, key); + maskedKeyCode = keyCode & 0x7f; + /* output a human readable event identifier for debugging + const char *ev = ""; + switch (kind) { + case kEventRawKeyDown: ev = "kEventRawKeyDown"; break; + case kEventRawKeyRepeat: ev = "kEventRawKeyRepeat"; break; + case kEventRawKeyUp: ev = "kEventRawKeyUp"; break; + case kEventRawKeyModifiersChanged: ev = "kEventRawKeyModifiersChanged"; break; + default: ev = "unknown"; + } + printf("%08x %08x %08x '%c' %s \n", mods, keyCode, key, key, ev); + */ + switch (kind) + { + case kEventRawKeyDown: + case kEventRawKeyRepeat: +/* + // FIXME Matt: For 10.5, the keycode_function will handle all this. This is untested for ealier versions of OS X. + // When the user presses a "dead key", no information is send about + // which dead key symbol was created. So we need to trick Carbon into + // giving us the code by sending a "space" after the "dead key". + if (key==0) { + UInt32 ktState = 0; + KeyboardLayoutRef klr; + KLGetCurrentKeyboardLayout(&klr); + const void *kchar = 0; KLGetKeyboardLayoutProperty(klr, kKLKCHRData, &kchar); + KeyTranslate(kchar, (mods&0xff00) | keyCode, &ktState); // send the dead key + key = KeyTranslate(kchar, 0x31, &ktState); // fake a space key press + Fl::e_state |= 0x40000000; // mark this as a dead key + } else { + Fl::e_state &= 0xbfffffff; // clear the deadkey flag + } +*/ + sendEvent = FL_KEYBOARD; + // fall through + case kEventRawKeyUp: + if ( !sendEvent ) { + sendEvent = FL_KEYUP; + Fl::e_state &= 0xbfffffff; // clear the deadkey flag + } + // if the user pressed alt/option, event_key should have the keycap, + // but event_text should generate the international symbol + sym = macKeyLookUp[maskedKeyCode]; + if ( isalpha(key) ) + sym = tolower(key); + else if ( Fl::e_state&FL_CTRL && key<32 && sym<0xff00) + sym = key+96; + else if ( Fl::e_state&FL_ALT && sym<0xff00) // find the keycap of this key + sym = keycode_to_sym( maskedKeyCode, 0, macKeyLookUp[ maskedKeyCode ] ); + Fl::e_keysym = Fl::e_original_keysym = sym; + // Handle FL_KP_Enter on regular keyboards and on Powerbooks + if ( maskedKeyCode==0x4c || maskedKeyCode==0x34) key=0x0d; + // Handle the Delete key on the keypad + // Matt: the Mac has no concept of a NumLock key, or at least not visible + // Matt: to Carbon. The kEventKeyModifierNumLockMask is only set when + // Matt: a numeric keypad key is pressed and does not correspond with + // Matt: the NumLock light in PowerBook keyboards. + + // Matt: attempt to get the correct Unicode character(s) from our keycode + // imm: keycode_function function pointer added to allow us to use different functions + // imm: depending on which OS version we are running on (tested and set in fl_open_display) + static UInt32 deadKeyState = 0; // must be cleared when losing focus + Fl::e_length = (*keycode_function)(buffer, 31, kind, keyCode, mods, &deadKeyState, key, sym); + Fl::e_text = buffer; + buffer[Fl::e_length] = 0; // just in case... + break; + case kEventRawKeyModifiersChanged: { + UInt32 tMods = prevMods ^ mods; + if ( tMods ) + { + mods_to_e_keysym( tMods ); + if ( Fl::e_keysym ) + sendEvent = ( prevModsparent()) window = window->window(); + if (sendEvent && Fl::handle(sendEvent,window)) { + fl_unlock_function(); + return noErr; // return noErr if FLTK handled the event + } else { + fl_unlock_function(); + //return CallNextEventHandler( nextHandler, event );; + // Matt: I had better results (no duplicate events) always returning + // Matt: 'noErr'. System keyboard events still seem to work just fine. + return noErr; + } +} + + + +/** + * Open callback function to call... + */ + +static void (*open_cb)(const char *) = 0; + + +/** + * Event handler for Apple-O key combination and also for file opens + * via the finder... + */ + +static OSErr OpenAppleEventHandler(const AppleEvent *appleEvt, + AppleEvent *reply, + UInt32 refcon) { + OSErr err; + AEDescList documents; + long i, n; + FSSpec fileSpec; + AEKeyword keyWd; + DescType typeCd; + Size actSz; + char filename[1024]; + + if (!open_cb) return noErr; + + // Initialize the document list... + AECreateDesc(typeNull, NULL, 0, &documents); + + // Get the open parameter(s)... + err = AEGetParamDesc(appleEvt, keyDirectObject, typeAEList, &documents); + if (err != noErr) { + AEDisposeDesc(&documents); + return err; + } + + // Lock access to FLTK in this thread... + fl_lock_function(); + + // Open the documents via the callback... + if (AECountItems(&documents, &n) == noErr) { + for (i = 1; i <= n; i ++) { + // Get the next FSSpec record... + AEGetNthPtr(&documents, i, typeFSS, &keyWd, &typeCd, + (Ptr)&fileSpec, sizeof(fileSpec), + (actSz = sizeof(fileSpec), &actSz)); + + // Convert to a UNIX path... + FSSpec2UnixPath(&fileSpec, filename); + + // Call the callback with the filename... + (*open_cb)(filename); + } + } + + // Unlock access to FLTK for all threads... + fl_unlock_function(); + + // Get rid of the document list... + AEDisposeDesc(&documents); + + return noErr; +} + + +/** + * Install an open documents event handler... + */ + +void fl_open_callback(void (*cb)(const char *)) { + open_cb = cb; + if (cb) { + AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, + NewAEEventHandlerUPP((AEEventHandlerProcPtr) + OpenAppleEventHandler), 0, false); + } else { + AERemoveEventHandler(kCoreEventClass, kAEOpenDocuments, + NewAEEventHandlerUPP((AEEventHandlerProcPtr) + OpenAppleEventHandler), false); + } +} + + +/** + * initialize the Mac toolboxes, dock status, and set the default menubar + */ + +extern "C" { + extern OSErr CPSEnableForegroundOperation(ProcessSerialNumber *psn, UInt32 _arg2, + UInt32 _arg3, UInt32 _arg4, UInt32 _arg5); +} + +void fl_open_display() { + static char beenHereDoneThat = 0; + if ( !beenHereDoneThat ) { + beenHereDoneThat = 1; + + FlushEvents(everyEvent,0); + + MoreMasters(); // \todo Carbon suggests MoreMasterPointers() + AEInstallEventHandler( kCoreEventClass, kAEQuitApplication, NewAEEventHandlerUPP((AEEventHandlerProcPtr)QuitAppleEventHandler), 0, false ); + + // create the Mac Handle for the default cursor (a pointer to a pointer) + GetQDGlobalsArrow(&default_cursor); + default_cursor_ptr = &default_cursor; + fl_default_cursor = &default_cursor_ptr; + + ClearMenuBar(); + AppendResMenu( GetMenuHandle( 1 ), 'DRVR' ); + DrawMenuBar(); + + // bring the application into foreground without a 'CARB' resource + Boolean same_psn; + ProcessSerialNumber cur_psn, front_psn; + if( !GetCurrentProcess( &cur_psn ) && !GetFrontProcess( &front_psn ) && + !SameProcess( &front_psn, &cur_psn, &same_psn ) && !same_psn ) + { + // only transform the application type for unbundled apps + CFBundleRef bundle = CFBundleGetMainBundle(); + if( bundle ) + { + FSRef execFs; + CFURLRef execUrl = CFBundleCopyExecutableURL( bundle ); + CFURLGetFSRef( execUrl, &execFs ); + + FSRef bundleFs; + GetProcessBundleLocation( &cur_psn, &bundleFs ); + + if( !FSCompareFSRefs( &execFs, &bundleFs ) ) + bundle = NULL; + + CFRelease(execUrl); + } + + if( !bundle ) + { + // Earlier versions of this code tried to use weak linking, however it + // appears that this does not work on 10.2. Since 10.3 and higher provide + // both TransformProcessType and CPSEnableForegroundOperation, the following + // conditional code compiled on 10.2 will still work on newer releases... + OSErr err; + +#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2 + if (TransformProcessType != NULL) { + err = TransformProcessType(&cur_psn, kProcessTransformToForegroundApplication); + } else +#endif // MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2 + err = CPSEnableForegroundOperation(&cur_psn, 0x03, 0x3C, 0x2C, 0x1103); + + if (err == noErr) { + SetFrontProcess( &cur_psn ); + } + } + } + + // imm: keycode handler stub setting - use Gestalt to determine the running system version, + // then set the keycode_function pointer accordingly + keycode_function = keycode_wrap_old; // default to pre-10.5 mechanism + SInt32 MacVersion; + if (Gestalt(gestaltSystemVersion, &MacVersion) == noErr) + { + if(MacVersion >= 0x1050) { // 10.5.0 or later + keycode_function = keycodeToUnicode; + } + } + } +} + + +/** + * get rid of allocated resources + */ +void fl_close_display() { +} + + +/** + * smallest x ccordinate in screen space + */ +int Fl::x() { + BitMap r; + GetQDGlobalsScreenBits(&r); + return r.bounds.left; +} + + +/** + * smallest y ccordinate in screen space + */ +int Fl::y() { + BitMap r; + GetQDGlobalsScreenBits(&r); + return r.bounds.top + 20; // \todo 20 pixel menu bar? +} + + +/** + * screen width (single monitor!?) + */ +int Fl::w() { + BitMap r; + GetQDGlobalsScreenBits(&r); + return r.bounds.right - r.bounds.left; +} + + +/** + * screen height (single monitor!?) + */ +int Fl::h() { + BitMap r; + GetQDGlobalsScreenBits(&r); + return r.bounds.bottom - r.bounds.top - 20; +} + + +/** + * get the current mouse pointer world coordinates + */ +void Fl::get_mouse(int &x, int &y) +{ + fl_open_display(); + Point loc; + GetMouse( &loc ); + LocalToGlobal( &loc ); + x = loc.h; + y = loc.v; +} + + +/** + * convert Mac keystrokes to FLTK + */ +unsigned short mac2fltk(ulong macKey) +{ + unsigned short cc = macKeyLookUp[(macKey>>8)&0x7f]; + if (cc) return cc; + return macKey&0xff; +} + + +/** + * Initialize the given port for redraw and call the windw's flush() to actually draw the content + */ +void Fl_X::flush() +{ + w->flush(); + if (fl_gc) + CGContextFlush(fl_gc); + SetOrigin( 0, 0 ); +} + + +/** + * Handle all clipping and redraw for the given port + * There are two different callers for this event: + * 1: the OS can request a redraw and provides all clipping itself + * 2: Fl::flush() wants all redraws now + */ +void handleUpdateEvent( WindowPtr xid ) +{ + Fl_Window *window = fl_find( xid ); + if ( !window ) return; + GrafPtr oldPort; + GetPort( &oldPort ); + SetPort( GetWindowPort(xid) ); + Fl_X *i = Fl_X::i( window ); + i->wait_for_expose = 0; + if ( window->damage() ) { + if ( i->region ) { + InvalWindowRgn( xid, i->region ); + } + } + if ( i->region ) { // no region, so the sytem will take the update region from the OS + DisposeRgn( i->region ); + i->region = 0; + } + for ( Fl_X *cx = i->xidChildren; cx; cx = cx->xidNext ) + { + cx->w->clear_damage(window->damage()|FL_DAMAGE_EXPOSE); + cx->flush(); + cx->w->clear_damage(); + } + window->clear_damage(window->damage()|FL_DAMAGE_EXPOSE); + i->flush(); + window->clear_damage(); + SetPort( oldPort ); +} + +// Gets the border sizes and the titlebar size +static void get_window_frame_sizes(int &bx, int &by, int &bt) { +#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2 + static HIRect contentRect = { {50,50}, {100,100} }; // a rect to stand in for the content rect of a real window + static HIThemeWindowDrawInfo metrics= {0, + kThemeStateActive, kThemeDocumentWindow, + kThemeWindowHasFullZoom + kThemeWindowHasCloseBox + + kThemeWindowHasCollapseBox + kThemeWindowHasTitleText, + 0, 0}; + HIShapeRef shape1=0, shape2=0, shape3=0; + HIRect rect1, rect2, rect3; + OSStatus status; + status = HIThemeGetWindowShape(&contentRect, &metrics, kWindowStructureRgn, &shape1); + status |= HIThemeGetWindowShape(&contentRect, &metrics, kWindowContentRgn, &shape2); + status |= HIThemeGetWindowShape(&contentRect, &metrics, kWindowTitleBarRgn, &shape3); + + if (!status) + { + HIShapeGetBounds(shape1, &rect1); + HIShapeGetBounds(shape2, &rect2); + HIShapeGetBounds(shape3, &rect3); + bt = rect3.size.height; + bx = rect2.origin.x - rect1.origin.x; + by = rect2.origin.y - rect1.origin.y - bt; + // fprintf(stderr, "HIThemeGetWindowShape succeeded bx=%d by=%d bt=%d\n", bx, by, bt); + } + else +#endif // MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2 + { + // sets default dimensions + bx = by = 6; + bt = 22; + // fprintf(stderr, "HIThemeGetWindowShape failed, bx=%d by=%d bt=%d\n", bx, by, bt); + } +#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2 + CFRelease(shape1); // we must free HIThemeGetWindowShape() (copied) handles + CFRelease(shape2); + CFRelease(shape3); +#endif // MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2 +} + +/** + * \todo this is a leftover from OS9 times. Please check how much applies to Carbon! + */ +int Fl_X::fake_X_wm(const Fl_Window* w,int &X,int &Y, int &bt,int &bx, int &by) { + int W, H, xoff, yoff, dx, dy; + int ret = bx = by = bt = 0; + if (w->border() && !w->parent()) { + if (w->maxw != w->minw || w->maxh != w->minh) { + ret = 2; + get_window_frame_sizes(bx, by, bt); + /* + bx = 6; // \todo Mac : GetSystemMetrics(SM_CXSIZEFRAME); + by = 6; // \todo Mac : get Mac window frame size GetSystemMetrics(SM_CYSIZEFRAME); + */ + } else { + ret = 1; + get_window_frame_sizes(bx, by, bt); + /* + bx = 6; // \todo Mac : GetSystemMetrics(SM_CXFIXEDFRAME); + by = 6; // \todo Mac : GetSystemMetrics(SM_CYFIXEDFRAME); + */ + } + } + //The coordinates of the whole window, including non-client area + xoff = bx; + yoff = by + bt; + dx = 2*bx; + dy = 2*by + bt; + X = w->x()-xoff; + Y = w->y()-yoff; + W = w->w()+dx; + H = w->h()+dy; + + //Proceed to positioning the window fully inside the screen, if possible + + // let's get a little elaborate here. Mac OS X puts a lot of stuff on the desk + // that we want to avoid when positioning our window, namely the Dock and the + // top menu bar (and even more stuff in 10.4 Tiger). So we will go through the + // list of all available screens and find the one that this window is most + // likely to go to, and then reposition it to fit withing the 'good' area. + Rect r; + // find the screen, that the center of this window will fall into + int R = X+W, B = Y+H; // right and bottom + int cx = (X+R)/2, cy = (Y+B)/2; // center of window; + GDHandle gd = 0L; + for (gd = GetDeviceList(); gd; gd = GetNextDevice(gd)) { + GDPtr gp = *gd; + if ( cx >= gp->gdRect.left && cx <= gp->gdRect.right + && cy >= gp->gdRect.top && cy <= gp->gdRect.bottom) + break; + } + // if the center doesn't fall on a screen, try the top left + if (!gd) { + for (gd = GetDeviceList(); gd; gd = GetNextDevice(gd)) { + GDPtr gp = *gd; + if ( X >= gp->gdRect.left && X <= gp->gdRect.right + && Y >= gp->gdRect.top && Y <= gp->gdRect.bottom) + break; + } + } + // if that doesn't fall on a screen, try the top right + if (!gd) { + for (gd = GetDeviceList(); gd; gd = GetNextDevice(gd)) { + GDPtr gp = *gd; + if ( R >= gp->gdRect.left && R <= gp->gdRect.right + && Y >= gp->gdRect.top && Y <= gp->gdRect.bottom) + break; + } + } + // if that doesn't fall on a screen, try the bottom left + if (!gd) { + for (gd = GetDeviceList(); gd; gd = GetNextDevice(gd)) { + GDPtr gp = *gd; + if ( X >= gp->gdRect.left && X <= gp->gdRect.right + && B >= gp->gdRect.top && B <= gp->gdRect.bottom) + break; + } + } + // last resort, try the bottom right + if (!gd) { + for (gd = GetDeviceList(); gd; gd = GetNextDevice(gd)) { + GDPtr gp = *gd; + if ( R >= gp->gdRect.left && R <= gp->gdRect.right + && B >= gp->gdRect.top && B <= gp->gdRect.bottom) + break; + } + } + // if we still have not found a screen, we will use the main + // screen, the one that has the application menu bar. + if (!gd) gd = GetMainDevice(); + if (gd) { + GetAvailableWindowPositioningBounds(gd, &r); + if ( R > r.right ) X -= R - r.right; + if ( B > r.bottom ) Y -= B - r.bottom; + if ( X < r.left ) X = r.left; + if ( Y < r.top ) Y = r.top; + } + + //Return the client area's top left corner in (X,Y) + X+=xoff; + Y+=yoff; + + return ret; +} + +/** + * convert a Mac FSSpec structure into a Unix filename + */ +static int FSSpec2UnixPath( FSSpec *fs, char *dst ) +{ + FSRef fsRef; + FSpMakeFSRef( fs, &fsRef ); + FSRefMakePath( &fsRef, (UInt8*)dst, 1024 ); + return strlen(dst); +} +static void convert_crlf(char * s, size_t len) +{ + // turn all \r characters into \n: + for (size_t x = 0; x < len; x++) if (s[x] == '\r') s[x] = '\n'; +} + + +static DragReference currDragRef = 0; +static char *currDragData = 0L; +static int currDragSize = 0; +static OSErr currDragErr = noErr; +Fl_Window *fl_dnd_target_window = 0; +#include + +/** + * Fill the currDrag* variables with the current DnD ASCII text. + */ +static OSErr fillCurrentDragData(DragReference dragRef) +{ + OSErr ret = noErr; + char *dst = 0L; + + // shortcut through this whole procedure if this is still the same drag event + if (dragRef==currDragRef) + return currDragErr; + + // clear currDrag* for a new drag event + currDragRef = dragRef; + if (currDragData) free(currDragData); + currDragData = 0; + currDragSize = 0; + + // fill currDRag* with ASCII data, if available + UInt16 i, nItem; + ItemReference itemRef; + FlavorFlags flags; + Size itemSize, size = 0; + CountDragItems( dragRef, &nItem ); + + for ( i = 1; i <= nItem; i++ ) + { + GetDragItemReferenceNumber( dragRef, i, &itemRef ); + ret = GetFlavorFlags( dragRef, itemRef, 'utf8', &flags ); + if ( ret == noErr ) + { + GetFlavorDataSize( dragRef, itemRef, 'utf8', &itemSize ); + size += itemSize; + continue; + } + ret = GetFlavorFlags( dragRef, itemRef, 'utxt', &flags ); + if ( ret == noErr ) + { + GetFlavorDataSize( dragRef, itemRef, 'utxt', &itemSize ); + size += itemSize; + continue; + } + ret = GetFlavorFlags( dragRef, itemRef, 'TEXT', &flags ); + if ( ret == noErr ) + { + GetFlavorDataSize( dragRef, itemRef, 'TEXT', &itemSize ); + size += itemSize; + continue; + } + ret = GetFlavorFlags( dragRef, itemRef, 'hfs ', &flags ); + if ( ret == noErr ) + { + size += 1024; //++ ouch! We should create the full pathname and figure out its length + continue; + } + } + + if ( !size ) + { + currDragErr = userCanceledErr; + return currDragErr; + } + + currDragSize = size + nItem - 1; + currDragData = dst = (char*)malloc( size+nItem );; + + for ( i = 1; i <= nItem; i++ ) + { + GetDragItemReferenceNumber( dragRef, i, &itemRef ); + ret = GetFlavorFlags( dragRef, itemRef, 'utf8', &flags ); + if ( ret == noErr ) + { + GetFlavorDataSize( dragRef, itemRef, 'utf8', &itemSize ); + GetFlavorData( dragRef, itemRef, 'utf8', dst, &itemSize, 0L ); + dst += itemSize; + *dst++ = '\n'; // add our element separator + continue; + } + GetDragItemReferenceNumber( dragRef, i, &itemRef ); + ret = GetFlavorFlags( dragRef, itemRef, 'utxt', &flags ); + if ( ret == noErr ) + { + GetFlavorDataSize( dragRef, itemRef, 'utxt', &itemSize ); + GetFlavorData( dragRef, itemRef, 'utxt', dst, &itemSize, 0L ); + dst += itemSize; + *dst++ = '\n'; // add our element separator + continue; + } + ret = GetFlavorFlags( dragRef, itemRef, 'TEXT', &flags ); + if ( ret == noErr ) + { + GetFlavorDataSize( dragRef, itemRef, 'TEXT', &itemSize ); + GetFlavorData( dragRef, itemRef, 'TEXT', dst, &itemSize, 0L ); + dst += itemSize; + *dst++ = '\n'; // add our element separator + continue; + } + ret = GetFlavorFlags( dragRef, itemRef, 'hfs ', &flags ); + if ( ret == noErr ) + { + HFSFlavor hfs; itemSize = sizeof( hfs ); + GetFlavorData( dragRef, itemRef, 'hfs ', &hfs, &itemSize, 0L ); + itemSize = FSSpec2UnixPath( &hfs.fileSpec, dst ); // return the path name in UTF8 + dst += itemSize; + if ( itemSize>1 && ( hfs.fileType=='fold' || hfs.fileType=='disk' ) ) + *dst++ = '/'; + *dst++ = '\n'; // add our element separator + continue; + } + } + + dst[-1] = 0; + currDragSize = dst - currDragData - 1; + currDragErr = ret; + return ret; +} + +/** + * Drag'n'drop tracking handler + */ +static pascal OSErr dndTrackingHandler( DragTrackingMessage msg, WindowPtr w, void *userData, DragReference dragRef ) +{ + Fl_Window *target = (Fl_Window*)userData; + Fl::first_window(target); + Point mp; + static int px, py; + + fillCurrentDragData(dragRef); + Fl::e_length = currDragSize; + Fl::e_text = currDragData; + + switch ( msg ) + { + case kDragTrackingEnterWindow: + // check if 'TEXT' is available + GetDragMouse( dragRef, &mp, 0 ); + Fl::e_x_root = px = mp.h; + Fl::e_y_root = py = mp.v; + Fl::e_x = px - target->x(); + Fl::e_y = py - target->y(); + fl_dnd_target_window = target; + if ( Fl::handle( FL_DND_ENTER, target ) ) + fl_cursor( FL_CURSOR_HAND ); //ShowDragHilite( ); // modify the mouse cursor?! + else + fl_cursor( FL_CURSOR_DEFAULT ); //HideDragHilite( dragRef ); + breakMacEventLoop(); + return noErr; + case kDragTrackingInWindow: + GetDragMouse( dragRef, &mp, 0 ); + if ( mp.h==px && mp.v==py ) + break; //+ return previous condition for dnd hiliting + Fl::e_x_root = px = mp.h; + Fl::e_y_root = py = mp.v; + Fl::e_x = px - target->x(); + Fl::e_y = py - target->y(); + fl_dnd_target_window = target; + if ( Fl::handle( FL_DND_DRAG, target ) ) + fl_cursor( FL_CURSOR_HAND ); //ShowDragHilite( ); // modify the mouse cursor?! + else + fl_cursor( FL_CURSOR_DEFAULT ); //HideDragHilite( dragRef ); + breakMacEventLoop(); + return noErr; + break; + case kDragTrackingLeaveWindow: + // HideDragHilite() + fl_cursor( FL_CURSOR_DEFAULT ); //HideDragHilite( dragRef ); + if ( fl_dnd_target_window ) + { + Fl::handle( FL_DND_LEAVE, fl_dnd_target_window ); + fl_dnd_target_window = 0; + } + breakMacEventLoop(); + return noErr; + } + return noErr; +} + + +/** + * Drag'n'drop receive handler + */ +static pascal OSErr dndReceiveHandler( WindowPtr w, void *userData, DragReference dragRef ) +{ + Point mp; + OSErr ret; + + Fl_Window *target = fl_dnd_target_window = (Fl_Window*)userData; + Fl::first_window(target); + GetDragMouse( dragRef, &mp, 0 ); + Fl::e_x_root = mp.h; + Fl::e_y_root = mp.v; + Fl::e_x = Fl::e_x_root - target->x(); + Fl::e_y = Fl::e_y_root - target->y(); + if ( !Fl::handle( FL_DND_RELEASE, target ) ) + return userCanceledErr; + + ret = fillCurrentDragData(dragRef); + if (ret==userCanceledErr) + return userCanceledErr; + + Fl::e_length = currDragSize; + Fl::e_text = currDragData; +// printf("Sending following text to widget %p:\n%s\n", Fl::belowmouse(), Fl::e_text); + int old_event = Fl::e_number; + Fl::belowmouse()->handle(Fl::e_number = FL_PASTE); + Fl::e_number = old_event; + + if (currDragData) { + free(currDragData); + } + currDragData = 0L; + currDragRef = 0; + Fl::e_text = 0L; + Fl::e_length = 0; + fl_dnd_target_window = 0L; + + breakMacEventLoop(); + return noErr; +} +// fc: +static void q_set_window_title(Window xid, const char * name ) { +#if 1 + CFStringRef utf8_title = CFStringCreateWithCString(NULL, (name ? name : ""), kCFStringEncodingUTF8); + SetWindowTitleWithCFString(xid, utf8_title); + CFRelease(utf8_title); +#else // old non-utf8 code to remove after new utf8 code approval : + Str255 pTitle; + if (name) { + if (strlen(name) > 255) pTitle[0] = 255; + else pTitle[0] = strlen(name); + memcpy(pTitle+1, name, pTitle[0]); + } + else + pTitle[0] = 0; + SetWTitle(xid, pTitle); +#endif +} + +/** + * go ahead, create that (sub)window + * \todo we should make menu windows slightly transparent for the new Mac look + */ +void Fl_X::make(Fl_Window* w) +{ + static int xyPos = 100; + if ( w->parent() ) // create a subwindow + { + Fl_Group::current(0); + Rect wRect; + wRect.top = w->y(); + wRect.left = w->x(); + wRect.bottom = w->y() + w->h(); if (wRect.bottom<=wRect.top) wRect.bottom = wRect.top+1; + wRect.right = w->x() + w->w(); if (wRect.right<=wRect.left) wRect.right = wRect.left+1; + // our subwindow needs this structure to know about its clipping. + Fl_X* x = new Fl_X; + x->other_xid = 0; + x->region = 0; + x->subRegion = 0; + x->cursor = fl_default_cursor; + x->gc = 0; // stay 0 for Quickdraw; fill with CGContext for Quartz + Fl_Window *win = w->window(); + Fl_X *xo = Fl_X::i(win); + if (xo) { + x->xidNext = xo->xidChildren; + x->xidChildren = 0L; + xo->xidChildren = x; + x->xid = fl_xid(win); + x->w = w; w->i = x; + x->wait_for_expose = 0; + x->next = Fl_X::first; // must be in the list for ::flush() + Fl_X::first = x; + int old_event = Fl::e_number; + w->handle(Fl::e_number = FL_SHOW); + Fl::e_number = old_event; + w->redraw(); // force draw to happen + } + fl_show_iconic = 0; + } + else // create a desktop window + { + Fl_Group::current(0); + fl_open_display(); + int winclass = kDocumentWindowClass; + int winattr = kWindowStandardHandlerAttribute | kWindowCloseBoxAttribute | kWindowCollapseBoxAttribute; + int xp = w->x(); + int yp = w->y(); + int wp = w->w(); + int hp = w->h(); + if (w->size_range_set) { + if ( w->minh != w->maxh || w->minw != w->maxw) + winattr |= kWindowFullZoomAttribute | kWindowResizableAttribute | kWindowLiveResizeAttribute; + } else { + if (w->resizable()) { + Fl_Widget *o = w->resizable(); + int minw = o->w(); if (minw > 100) minw = 100; + int minh = o->h(); if (minh > 100) minh = 100; + w->size_range(w->w() - o->w() + minw, w->h() - o->h() + minh, 0, 0); + winattr |= kWindowFullZoomAttribute | kWindowResizableAttribute | kWindowLiveResizeAttribute; + } else { + w->size_range(w->w(), w->h(), w->w(), w->h()); + } + } + int xwm = xp, ywm = yp, bt, bx, by; + + if (!fake_X_wm(w, xwm, ywm, bt, bx, by)) { + // menu windows and tooltips + if (w->modal()||w->override()) { + winclass = kHelpWindowClass; + winattr = 0; + } else { + winattr = 512; // kWindowNoTitleBarAttribute; + } + } else if (w->modal()) { + winclass = kMovableModalWindowClass; + } + + if (by+bt) { + wp += 2*bx; + hp += 2*by+bt; + } + if (!(w->flags() & Fl_Widget::FORCE_POSITION)) { + // use the Carbon functions below for default window positioning + w->x(xyPos+Fl::x()); + w->y(xyPos+Fl::y()); + xyPos += 25; + if (xyPos>200) xyPos = 100; + } else { + if (!Fl::grab()) { + xp = xwm; yp = ywm; + w->x(xp);w->y(yp); + } + xp -= bx; + yp -= by+bt; + } + + if (w->non_modal() && Fl_X::first && !fl_disable_transient_for) { + // find some other window to be "transient for": + Fl_Window* w = Fl_X::first->w; + while (w->parent()) w = w->window(); // todo: this code does not make any sense! (w!=w??) + } + + Rect wRect; + wRect.top = w->y(); + wRect.left = w->x(); + wRect.bottom = w->y() + w->h(); if (wRect.bottom<=wRect.top) wRect.bottom = wRect.top+1; + wRect.right = w->x() + w->w(); if (wRect.right<=wRect.left) wRect.right = wRect.left+1; + + const char *name = w->label(); + + Fl_X* x = new Fl_X; + x->other_xid = 0; // room for doublebuffering image map. On OS X this is only used by overlay windows + x->region = 0; + x->subRegion = 0; + x->cursor = fl_default_cursor; + x->xidChildren = 0; + x->xidNext = 0; + x->gc = 0; + + winattr &= GetAvailableWindowAttributes( winclass ); // make sure that the window will open + CreateNewWindow( winclass, winattr, &wRect, &(x->xid) ); + q_set_window_title(x->xid, name); + MoveWindow(x->xid, wRect.left, wRect.top, 1); // avoid Carbon Bug on old OS + if (w->non_modal() && !w->modal()) { + // Major kludge: this is to have the regular look, but stay above the document windows + SetWindowClass(x->xid, kFloatingWindowClass); + SetWindowActivationScope(x->xid, kWindowActivationScopeAll); + } + if (!(w->flags() & Fl_Widget::FORCE_POSITION)) + { + WindowRef pw = Fl_X::first ? Fl_X::first->xid : 0 ; + if (w->modal()) { + RepositionWindow(x->xid, pw, kWindowAlertPositionOnParentWindowScreen); + } else if (w->non_modal()) { + RepositionWindow(x->xid, pw, kWindowCenterOnParentWindowScreen); + } else { + RepositionWindow(x->xid, pw, kWindowCascadeOnParentWindowScreen); + } + } + x->w = w; w->i = x; + x->wait_for_expose = 1; + x->next = Fl_X::first; + Fl_X::first = x; + { // Install Carbon Event handlers + OSStatus ret; + EventHandlerUPP mousewheelHandler = NewEventHandlerUPP( carbonMousewheelHandler ); // will not be disposed by Carbon... + static EventTypeSpec mousewheelEvents[] = { + { kEventClassMouse, kEventMouseWheelMoved } }; + ret = InstallWindowEventHandler( x->xid, mousewheelHandler, + (int)(sizeof(mousewheelEvents)/sizeof(mousewheelEvents[0])), + mousewheelEvents, w, 0L ); + EventHandlerUPP mouseHandler = NewEventHandlerUPP( carbonMouseHandler ); // will not be disposed by Carbon... + static EventTypeSpec mouseEvents[] = { + { kEventClassMouse, kEventMouseDown }, + { kEventClassMouse, kEventMouseUp }, + { kEventClassMouse, kEventMouseMoved }, + { kEventClassMouse, kEventMouseDragged } }; + ret = InstallWindowEventHandler( x->xid, mouseHandler, 4, mouseEvents, w, 0L ); + + EventHandlerUPP keyboardHandler = NewEventHandlerUPP( carbonKeyboardHandler ); // will not be disposed by Carbon... + static EventTypeSpec keyboardEvents[] = { + { kEventClassKeyboard, kEventRawKeyDown }, + { kEventClassKeyboard, kEventRawKeyRepeat }, + { kEventClassKeyboard, kEventRawKeyUp }, + { kEventClassKeyboard, kEventRawKeyModifiersChanged } }; + ret = InstallWindowEventHandler( x->xid, keyboardHandler, 4, keyboardEvents, w, 0L ); + + EventHandlerUPP textHandler = NewEventHandlerUPP( carbonTextHandler ); // will not be disposed by Carbon... + static EventTypeSpec textEvents[] = { + { kEventClassTextInput, kEventTextInputUnicodeForKeyEvent } }; + ret = InstallWindowEventHandler( x->xid, textHandler, 1, textEvents, w, 0L ); + + EventHandlerUPP windowHandler = NewEventHandlerUPP( carbonWindowHandler ); // will not be disposed by Carbon... + static EventTypeSpec windowEvents[] = { + { kEventClassWindow, kEventWindowDrawContent }, + { kEventClassWindow, kEventWindowShown }, + { kEventClassWindow, kEventWindowHidden }, + { kEventClassWindow, kEventWindowActivated }, + { kEventClassWindow, kEventWindowDeactivated }, + { kEventClassWindow, kEventWindowClose }, + { kEventClassWindow, kEventWindowCollapsed }, + { kEventClassWindow, kEventWindowExpanded }, + { kEventClassWindow, kEventWindowBoundsChanging }, + { kEventClassWindow, kEventWindowBoundsChanged } }; + ret = InstallWindowEventHandler( x->xid, windowHandler, 10, windowEvents, w, 0L ); + ret = InstallTrackingHandler( dndTrackingHandler, x->xid, w ); + ret = InstallReceiveHandler( dndReceiveHandler, x->xid, w ); + } + + if ( ! Fl_X::first->next ) // if this is the first window, we need to bring the application to the front + { + ProcessSerialNumber psn; + OSErr err = GetCurrentProcess( &psn ); + if ( err==noErr ) SetFrontProcess( &psn ); + } + + if (w->size_range_set) w->size_range_(); + + if (winclass != kHelpWindowClass) { + Fl_Tooltip::enter(0); + } + if (w->size_range_set) w->size_range_(); + ShowWindow(x->xid); + if (fl_show_iconic) { + fl_show_iconic = 0; + CollapseWindow( x->xid, true ); // \todo Mac ; untested + } else { + w->set_visible(); + } + + Rect rect; + GetWindowBounds(x->xid, kWindowContentRgn, &rect); + w->x(rect.left); w->y(rect.top); + w->w(rect.right-rect.left); w->h(rect.bottom-rect.top); + + int old_event = Fl::e_number; + w->handle(Fl::e_number = FL_SHOW); + Fl::e_number = old_event; + w->redraw(); // force draw to happen + + if (w->modal()) { Fl::modal_ = w; fl_fix_focus(); } + } +} + + +/** + * Tell the OS what window sizes we want to allow + */ +void Fl_Window::size_range_() { + size_range_set = 1; + HISize minSize = { minw, minh }; + HISize maxSize = { maxw?maxw:32000, maxh?maxh:32000 }; + if (i && i->xid) + SetWindowResizeLimits(i->xid, &minSize, &maxSize); +} + + +/** + * returns pointer to the filename, or null if name ends with ':' + */ +const char *fl_filename_name( const char *name ) +{ + const char *p, *q; + if (!name) return (0); + for ( p = q = name ; *p ; ) + { + if ( ( p[0] == ':' ) && ( p[1] == ':' ) ) + { + q = p+2; + p++; + } + else if (p[0] == '/') + q = p + 1; + p++; + } + return q; +} + + +/** + * set the window title bar + * \todo make the titlebar icon work! + */ +void Fl_Window::label(const char *name,const char */*iname*/) { + Fl_Widget::label(name); + + if (shown() || i) { + q_set_window_title(fl_xid(this), name); + } +} + + +/** + * make a window visible + */ +void Fl_Window::show() { + image(Fl::scheme_bg_); + if (Fl::scheme_bg_) { + labeltype(FL_NORMAL_LABEL); + align(FL_ALIGN_CENTER | FL_ALIGN_INSIDE | FL_ALIGN_CLIP); + } else { + labeltype(FL_NO_LABEL); + } + Fl_Tooltip::exit(this); + if (!shown() || !i) { + Fl_X::make(this); + } else { + if ( !parent() ) + { + if ( IsWindowCollapsed( i->xid ) ) CollapseWindow( i->xid, false ); + if (!fl_capture) { + BringToFront(i->xid); + SelectWindow(i->xid); + } + } + } +} + + +/** + * resize a window + */ +void Fl_Window::resize(int X,int Y,int W,int H) { + if (W<=0) W = 1; // OS X does not like zero width windows + if (H<=0) H = 1; + int is_a_resize = (W != w() || H != h()); +// printf("Fl_Winodw::resize(X=%d, Y=%d, W=%d, H=%d), is_a_resize=%d, resize_from_system=%p, this=%p\n", +// X, Y, W, H, is_a_resize, resize_from_system, this); + if (X != x() || Y != y()) set_flag(FORCE_POSITION); + else if (!is_a_resize) return; + if ( (resize_from_system!=this) && (!parent()) && shown()) { + if (is_a_resize) { + if (resizable()) { + if (Wmaxw) maxw = W; // over a previously set size_range + if (Hmaxh) maxh = H; + size_range(minw, minh, maxw, maxh); + } else { + size_range(W, H, W, H); + } + Rect dim; dim.left=X; dim.top=Y; dim.right=X+W; dim.bottom=Y+H; + SetWindowBounds(i->xid, kWindowContentRgn, &dim); + Rect all; all.top=-32000; all.bottom=32000; all.left=-32000; all.right=32000; + InvalWindowRect( i->xid, &all ); + } else { + MoveWindow(i->xid, X, Y, 0); + } + } + resize_from_system = 0; + if (is_a_resize) { + Fl_Group::resize(X,Y,W,H); + if (shown()) { + redraw(); + } + } else { + x(X); y(Y); + } +} + + +/** + * make all drawing go into this window (called by subclass flush() impl.) + */ +void Fl_Window::make_current() +{ + OSStatus err; + Fl_X::q_release_context(); + if ( !fl_window_region ) + fl_window_region = NewRgn(); + fl_window = i->xid; + current_ = this; + + SetPort( GetWindowPort(i->xid) ); // \todo check for the handling of doublebuffered windows + + int xp = 0, yp = 0; + Fl_Window *win = this; + while ( win ) + { + if ( !win->window() ) + break; + xp += win->x(); + yp += win->y(); + win = (Fl_Window*)win->window(); + } + SetOrigin( -xp, -yp ); + + SetRectRgn( fl_window_region, 0, 0, w(), h() ); + + // \todo for performance reasons: we don't have to create this unless the child windows moved + for ( Fl_X *cx = i->xidChildren; cx; cx = cx->xidNext ) + { + Fl_Window *cw = cx->w; + if (!cw->visible_r()) continue; + Fl_Region r = NewRgn(); + SetRectRgn( r, cw->x() - xp, cw->y() - yp, + cw->x() + cw->w() - xp, cw->y() + cw->h() - yp ); + DiffRgn( fl_window_region, r, fl_window_region ); + DisposeRgn( r ); + } + + err = QDBeginCGContext(GetWindowPort(i->xid), &i->gc); + if (err!=noErr) + fprintf(stderr, "Error %d in QDBeginCGContext\n", (int)err); + fl_gc = i->gc; + CGContextSaveGState(fl_gc); + Fl_X::q_fill_context(); +#if defined(USE_CAIRO) + if (Fl::cairo_autolink_context()) Fl::cairo_make_current(this); // capture gc changes automatically to update the cairo context adequately +#endif + + fl_clip_region( 0 ); + SetPortClipRegion( GetWindowPort(i->xid), fl_window_region ); + +#if defined(USE_CAIRO) + // update the cairo_t context + if (Fl::cairo_autolink_context()) Fl::cairo_make_current(this); +#endif +} + +// helper function to manage the current CGContext fl_gc +extern Fl_Color fl_color_; +extern class Fl_Font_Descriptor *fl_fontsize; +extern void fl_font(class Fl_Font_Descriptor*); +extern void fl_quartz_restore_line_style_(); + +// FLTK has only one global graphics state. This function copies the FLTK state into the +// current Quartz context +void Fl_X::q_fill_context() { + if (!fl_gc) return; + int hgt = 0; + if (fl_window) { + Rect portRect; + GetPortBounds(GetWindowPort( fl_window ), &portRect); + hgt = portRect.bottom-portRect.top; + } else { + hgt = CGBitmapContextGetHeight(fl_gc); + } + CGContextTranslateCTM(fl_gc, 0.5, hgt-0.5f); + CGContextScaleCTM(fl_gc, 1.0f, -1.0f); + fl_font(fl_fontsize); + fl_color(fl_color_); + fl_quartz_restore_line_style_(); +} + +// The only way to reset clipping to its original state is to pop the current graphics +// state and restore the global state. +void Fl_X::q_clear_clipping() { + if (!fl_gc) return; + CGContextRestoreGState(fl_gc); + CGContextSaveGState(fl_gc); +} + +// Give the Quartz context back to the system +void Fl_X::q_release_context(Fl_X *x) { + if (x && x->gc!=fl_gc) return; + if (!fl_gc) return; + CGContextRestoreGState(fl_gc); + if (fl_window) { + OSStatus err = QDEndCGContext(GetWindowPort(fl_window), &fl_gc); + if (err!=noErr) + fprintf(stderr, "Error %d in QDEndCGContext\n", (int)err); + } + fl_gc = 0; +#if defined(USE_CAIRO) + if (Fl::cairo_autolink_context()) Fl::cairo_make_current((Fl_Window*) 0); // capture gc changes automatically to update the cairo context adequately +#endif +} + +void Fl_X::q_begin_image(CGRect &rect, int cx, int cy, int w, int h) { + CGContextSaveGState(fl_gc); + CGAffineTransform mx = CGContextGetCTM(fl_gc); + CGRect r2 = rect; + r2.origin.x -= 0.5f; + r2.origin.y -= 0.5f; + CGContextClipToRect(fl_gc, r2); + mx.d = -1.0; mx.tx = -mx.tx; + CGContextConcatCTM(fl_gc, mx); + rect.origin.x = -(mx.tx+0.5f) + rect.origin.x - cx; + rect.origin.y = (mx.ty+0.5f) - rect.origin.y - h + cy; + rect.size.width = w; + rect.size.height = h; +} + +void Fl_X::q_end_image() { + CGContextRestoreGState(fl_gc); +} + +//////////////////////////////////////////////////////////////// +// Copy & Paste fltk implementation. +//////////////////////////////////////////////////////////////// + +// fltk 1.3 clipboard support constant definitions: +const CFStringRef flavorNames[] = { + CFSTR("public.utf16-plain-text"), + CFSTR("public.utf8-plain-text"), + CFSTR("com.apple.traditional-mac-plain-text") }; +const CFStringEncoding encodings[] = { + kCFStringEncodingUTF16, + kCFStringEncodingUTF8, + kCFStringEncodingMacRoman}; +const size_t handledFlavorsCount = sizeof(encodings)/sizeof(CFStringEncoding); + +// clipboard variables definitions : +Fl_Widget *fl_selection_requestor = 0; +char *fl_selection_buffer[2]; +int fl_selection_length[2]; +static int fl_selection_buffer_length[2]; + +#ifdef USE_PASTEBOARD +static PasteboardRef myPasteboard = 0; +static void allocatePasteboard() { + if (!myPasteboard) + PasteboardCreate(kPasteboardClipboard, &myPasteboard); +} +#else +#endif + +#ifndef USE_PASTEBOARD +static ScrapRef myScrap = 0; +#endif + +/** + * create a selection + * owner: widget that created the selection + * stuff: pointer to selected data + * size of selected data + */ +void Fl::copy(const char *stuff, int len, int clipboard) { + if (!stuff || len<0) return; + if (len+1 > fl_selection_buffer_length[clipboard]) { + delete[] fl_selection_buffer[clipboard]; + fl_selection_buffer[clipboard] = new char[len+100]; + fl_selection_buffer_length[clipboard] = len+100; + } + memcpy(fl_selection_buffer[clipboard], stuff, len); + fl_selection_buffer[clipboard][len] = 0; // needed for direct paste + fl_selection_length[clipboard] = len; + if (clipboard) { +#ifdef USE_PASTEBOARD + // FIXME no error checking done yet! + allocatePasteboard(); + OSStatus err = PasteboardClear(myPasteboard); + if (err!=noErr) return; // clear did not work, maybe not owner of clipboard. + PasteboardSynchronize(myPasteboard); + CFDataRef text = CFDataCreate(kCFAllocatorDefault, (UInt8*)fl_selection_buffer[1], len); + if (text==NULL) return; // there was a pb creating the object, abort. + err=PasteboardPutItemFlavor(myPasteboard, (PasteboardItemID)1, CFSTR("public.utf8-plain-text"), text, 0); + CFRelease(text); +#else + OSStatus err = ClearCurrentScrap(); // whatever happens we should clear the current scrap. + if(err!=noErr) {myScrap=0; return;} // don't get current scrap if a prev err occured. + err = GetCurrentScrap( &myScrap ); + if ( err != noErr ) { + myScrap = 0; + return; + } + // Previous version changed \n to \r before sending the text, but I would + // prefer to leave the local buffer alone, so a copied buffer may be + // needed. Check to see if this is necessary on OS/X. + PutScrapFlavor( myScrap, kScrapFlavorTypeText, 0, + len, fl_selection_buffer[1] ); +#endif + } +} + +// Call this when a "paste" operation happens: +void Fl::paste(Fl_Widget &receiver, int clipboard) { + if (clipboard) { + // see if we own the selection, if not go get it: + fl_selection_length[1] = 0; +#ifdef USE_PASTEBOARD + OSStatus err = noErr; + Boolean found = false; + CFDataRef flavorData = NULL; + CFStringEncoding encoding = 0; + + allocatePasteboard(); + PasteboardSynchronize(myPasteboard); + ItemCount nFlavor = 0, i, j; + err = PasteboardGetItemCount(myPasteboard, &nFlavor); + if (err==noErr) { + for (i=1; i<=nFlavor; i++) { + PasteboardItemID itemID = 0; + CFArrayRef flavorTypeArray = NULL; + found = false; + err = PasteboardGetItemIdentifier(myPasteboard, i, &itemID); + if (err!=noErr) continue; + err = PasteboardCopyItemFlavors(myPasteboard, itemID, &flavorTypeArray); + if (err!=noErr) { + if (flavorTypeArray) {CFRelease(flavorTypeArray); flavorTypeArray = NULL;} + continue; + } + CFIndex flavorCount = CFArrayGetCount(flavorTypeArray); + for (j = 0; j < handledFlavorsCount; j++) { + for (CFIndex flavorIndex=0; flavorIndex= fl_selection_buffer_length[1] ) { + fl_selection_buffer_length[1] = len; + delete[] fl_selection_buffer[1]; + fl_selection_buffer[1] = new char[len]; + } + CFStringGetCString(mycfs, fl_selection_buffer[1], len, kCFStringEncodingUTF8); + CFRelease(mycfs); + len = strlen(fl_selection_buffer[1]); + fl_selection_length[1] = len; + convert_crlf(fl_selection_buffer[1],len); // turn all \r characters into \n: + } + } +#else + ScrapRef scrap = 0; + if (GetCurrentScrap(&scrap) == noErr && scrap != myScrap && + GetScrapFlavorSize(scrap, kScrapFlavorTypeText, &len) == noErr) { + if ( len >= fl_selection_buffer_length[1] ) { + fl_selection_buffer_length[1] = len + 32; + delete[] fl_selection_buffer[1]; + fl_selection_buffer[1] = new char[len + 32]; + } + fl_selection_length[1] = len; len++; + GetScrapFlavorData( scrap, kScrapFlavorTypeText, &len, + fl_selection_buffer[1] ); + fl_selection_buffer[1][fl_selection_length[1]] = 0; + convert_crlf(fl_selection_buffer[1],len); + } +#endif + } + Fl::e_text = fl_selection_buffer[clipboard]; + Fl::e_length = fl_selection_length[clipboard]; + if (!Fl::e_text) Fl::e_text = (char *)""; + receiver.handle(FL_PASTE); +} + +void Fl::add_timeout(double time, Fl_Timeout_Handler cb, void* data) +{ + // check, if this timer slot exists already + for (int i = 0; i < mac_timer_used; ++i) { + MacTimeout& t = mac_timers[i]; + // if so, simply change the fire interval + if (t.callback == cb && t.data == data) { + SetEventLoopTimerNextFireTime(t.timer, (EventTimerInterval)time); + t.pending = 1; + return; + } + } + // no existing timer to use. Create a new one: + int timer_id = -1; + // find an empty slot in the timer array + for (int i = 0; i < mac_timer_used; ++i) { + if ( !mac_timers[i].timer ) { + timer_id = i; + break; + } + } + // if there was no empty slot, append a new timer + if (timer_id == -1) { + // make space if needed + if (mac_timer_used == mac_timer_alloc) { + realloc_timers(); + } + timer_id = mac_timer_used++; + } + // now install a brand new timer + MacTimeout& t = mac_timers[timer_id]; + EventTimerInterval fireDelay = (EventTimerInterval)time; + EventLoopTimerUPP timerUPP = NewEventLoopTimerUPP(do_timer); + EventLoopTimerRef timerRef = 0; + OSStatus err = InstallEventLoopTimer(GetMainEventLoop(), fireDelay, 0, timerUPP, data, &timerRef); + if (err == noErr) { + t.callback = cb; + t.data = data; + t.timer = timerRef; + t.upp = timerUPP; + t.pending = 1; + } else { + if (timerRef) + RemoveEventLoopTimer(timerRef); + if (timerUPP) + DisposeEventLoopTimerUPP(timerUPP); + } +} + +void Fl::repeat_timeout(double time, Fl_Timeout_Handler cb, void* data) +{ + // currently, repeat_timeout does not subtract the trigger time of the previous timer event as it should. + add_timeout(time, cb, data); +} + +int Fl::has_timeout(Fl_Timeout_Handler cb, void* data) +{ + for (int i = 0; i < mac_timer_used; ++i) { + MacTimeout& t = mac_timers[i]; + if (t.callback == cb && t.data == data && t.pending) { + return 1; + } + } + return 0; +} + +void Fl::remove_timeout(Fl_Timeout_Handler cb, void* data) +{ + for (int i = 0; i < mac_timer_used; ++i) { + MacTimeout& t = mac_timers[i]; + if (t.callback == cb && ( t.data == data || data == NULL)) { + delete_timer(t); + } + } +} + +int MacUnlinkWindow(Fl_X *ip, Fl_X *start) { + if (!ip) return 0; + if (start) { + Fl_X *pc = start; + while (pc) { + if (pc->xidNext == ip) { + pc->xidNext = ip->xidNext; + return 1; + } + if (pc->xidChildren) { + if (pc->xidChildren == ip) { + pc->xidChildren = ip->xidNext; + return 1; + } + if (MacUnlinkWindow(ip, pc->xidChildren)) + return 1; + } + pc = pc->xidNext; + } + } else { + for ( Fl_X *pc = Fl_X::first; pc; pc = pc->next ) { + if (MacUnlinkWindow(ip, pc)) + return 1; + } + } + return 0; +} + +static void MacRelinkWindow(Fl_X *x, Fl_X *p) { + if (!x || !p) return; + // first, check if 'x' is already registered as a child of 'p' + for (Fl_X *i = p->xidChildren; i; i=i->xidNext) { + if (i == x) return; + } + // now add 'x' as the first child of 'p' + x->xidNext = p->xidChildren; + p->xidChildren = x; +} + +void MacDestroyWindow(Fl_Window *w, WindowPtr p) { + MacUnmapWindow(w, p); + if (w && !w->parent() && p) + DisposeWindow(p); +} + +void MacMapWindow(Fl_Window *w, WindowPtr p) { + if (w && p) + ShowWindow(p); + //+ link to window list + if (w && w->parent()) { + MacRelinkWindow(Fl_X::i(w), Fl_X::i(w->window())); + w->redraw(); + } +} + +void MacUnmapWindow(Fl_Window *w, WindowPtr p) { + if (w && !w->parent() && p) + HideWindow(p); + if (w && Fl_X::i(w)) + MacUnlinkWindow(Fl_X::i(w)); +} +#endif // FL_DOXYGEN + +// +// End of "$Id: Fl_mac.cxx 7351 2010-03-29 10:35:00Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_own_colormap.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_own_colormap.cxx new file mode 100644 index 0000000..3a76688 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_own_colormap.cxx @@ -0,0 +1,90 @@ +// +// "$Id: Fl_own_colormap.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Private colormap support for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Using the default system colormap can be a bad idea on PseudoColor +// visuals, since typically every application uses the default colormap and +// you can run out of colormap entries easily. +// +// The solution is to always create a new colormap on PseudoColor displays +// and copy the first 16 colors from the default colormap so that we won't +// get huge color changes when switching windows. + +#include +#include +#include + +/** \fn Fl::own_colormap() + Makes FLTK use its own colormap. This may make FLTK display better + and will reduce conflicts with other programs that want lots of colors. + However the colors may flash as you move the cursor between windows. + +

      This does nothing if the current visual is not colormapped. +*/ +#ifdef WIN32 +// There is probably something relevant to do on MSWindows 8-bit displays +// but I don't know what it is + +void Fl::own_colormap() {} + +#elif defined(__APPLE__) +// MacOS X always provides a TrueColor interface... + +void Fl::own_colormap() {} +#else +// X version + +void Fl::own_colormap() { + fl_open_display(); +#if USE_COLORMAP + switch (fl_visual->c_class) { + case GrayScale : + case PseudoColor : + case DirectColor : + break; + default: + return; // don't do anything for non-colormapped visuals + } + int i; + XColor colors[16]; + // Get the first 16 colors from the default colormap... + for (i = 0; i < 16; i ++) colors[i].pixel = i; + XQueryColors(fl_display, fl_colormap, colors, 16); + // Create a new colormap... + fl_colormap = XCreateColormap(fl_display, + RootWindow(fl_display,fl_screen), + fl_visual->visual, AllocNone); + // Copy those first 16 colors to our own colormap: + for (i = 0; i < 16; i ++) + XAllocColor(fl_display, fl_colormap, colors + i); +#endif +} + +#endif + +// +// End of "$Id: Fl_own_colormap.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_visual.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_visual.cxx new file mode 100644 index 0000000..98c3c3a --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_visual.cxx @@ -0,0 +1,155 @@ +// +// "$Id: Fl_visual.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Visual support for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Set the default visual according to passed switches: + +#include +#include +#include + +/** \fn Fl::visual(int flags) + Selects a visual so that your graphics are drawn correctly. This is + only allowed before you call show() on any windows. This does nothing + if the default visual satisfies the capabilities, or if no visual + satisfies the capabilities, or on systems that don't have such + brain-dead notions. + +

      Only the following combinations do anything useful: + +

        +
      • Fl::visual(FL_RGB) +
        Full/true color (if there are several depths FLTK chooses the + largest). Do this if you use fl_draw_image + for much better (non-dithered) output. +
         
      • +
      • Fl::visual(FL_RGB8) +
        Full color with at least 24 bits of color. FL_RGB will + always pick this if available, but if not it will happily return a + less-than-24 bit deep visual. This call fails if 24 bits are not + available. +
         
      • +
      • Fl::visual(FL_DOUBLE|FL_INDEX) +
        Hardware double buffering. Call this if you are going to use + Fl_Double_Window. +
         
      • +
      • Fl::visual(FL_DOUBLE|FL_RGB)
      • +
      • Fl::visual(FL_DOUBLE|FL_RGB8) +
        Hardware double buffering and full color. +
      + +

      This returns true if the system has the capabilities by default or + FLTK suceeded in turing them on. Your program will still work even if + this returns false (it just won't look as good). +*/ +#ifdef WIN32 +int Fl::visual(int flags) { + fl_GetDC(0); + if (flags & FL_DOUBLE) return 0; + if (!(flags & FL_INDEX) && + GetDeviceCaps(fl_gc,BITSPIXEL) <= 8) return 0; + if ((flags & FL_RGB8) && GetDeviceCaps(fl_gc,BITSPIXEL)<24) return 0; + return 1; +} +#elif defined(__APPLE__) + +// \todo Mac : need to implement Visual flags +int Fl::visual(int flags) { + (void)flags; + return 1; +} + +#else + +#if USE_XDBE +#include +#endif + +static int test_visual(XVisualInfo& v, int flags) { + if (v.screen != fl_screen) return 0; +#if USE_COLORMAP + if (!(flags & FL_INDEX)) { + if (v.c_class != StaticColor && v.c_class != TrueColor) return 0; + if (v.depth <= 8) return 0; // fltk will work better in colormap mode + } + if (flags & FL_RGB8) { + if (v.depth < 24) return 0; + } + // for now, fltk does not like colormaps of more than 8 bits: + if ((v.c_class&1) && v.depth > 8) return 0; +#else + // simpler if we can't use colormapped visuals at all: + if (v.c_class != StaticColor && v.c_class != TrueColor) return 0; +#endif +#if USE_XDBE + if (flags & FL_DOUBLE) { + static XdbeScreenVisualInfo *xdbejunk; + if (!xdbejunk) { + int event_base, error_base; + if (!XdbeQueryExtension(fl_display, &event_base, &error_base)) return 0; + Drawable root = RootWindow(fl_display,fl_screen); + int numscreens = 1; + xdbejunk = XdbeGetVisualInfo(fl_display,&root,&numscreens); + if (!xdbejunk) return 0; + } + for (int j = 0; ; j++) { + if (j >= xdbejunk->count) return 0; + if (xdbejunk->visinfo[j].visual == v.visualid) break; + } + } +#endif + return 1; +} + +int Fl::visual(int flags) { +#if USE_XDBE == 0 + if (flags & FL_DOUBLE) return 0; +#endif + fl_open_display(); + // always use default if possible: + if (test_visual(*fl_visual, flags)) return 1; + // get all the visuals: + XVisualInfo vTemplate; + int num; + XVisualInfo *visualList = XGetVisualInfo(fl_display, 0, &vTemplate, &num); + // find all matches, use the one with greatest depth: + XVisualInfo *found = 0; + for (int i=0; idepth < visualList[i].depth) + found = &visualList[i]; + } + if (!found) {XFree((void*)visualList); return 0;} + fl_visual = found; + fl_colormap = XCreateColormap(fl_display, RootWindow(fl_display,fl_screen), + fl_visual->visual, AllocNone); + return 1; +} + +#endif + +// +// End of "$Id: Fl_visual.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_win32.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_win32.cxx new file mode 100644 index 0000000..327c7c9 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_win32.cxx @@ -0,0 +1,1981 @@ +// +// "$Id: Fl_win32.cxx 7814 2010-11-11 08:38:36Z AlbrechtS $" +// +// WIN32-specific code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2009 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// This file contains win32-specific code for fltk which is always linked +// in. Search other files for "WIN32" or filenames ending in _win32.cxx +// for other system-specific code. + +#ifndef FL_DOXYGEN +#include +#include +#include +#include +#include +#include +#include +#include "flstring.h" +#include "Fl_Font.H" +#include +#include +#include +#include +#ifdef __CYGWIN__ +# include +# include +#else +# if !defined(USE_WSOCK1) +# include +#else +# include +# endif +#endif +#if !defined(USE_WSOCK1) +# define WSCK_DLL_NAME "WS2_32.DLL" +#else +# define WSCK_DLL_NAME "WSOCK32.DLL" +#endif +#include +#include + +#if defined(__GNUC__) +# include +#endif + +# include +# include + +#include "aimm.h" + +// +// USE_ASYNC_SELECT - define it if you have WSAAsyncSelect()... +// USE_ASYNC_SELECT is OBSOLETED in 1.3 for the following reasons: +/* + This feature was supposed to provide an efficient alternative to the current + polling method, but as it has been discussed (Thanks Albrecht!) : + - the async mode would imply to change the socket to non blocking mode. + This can have unexpected side effects for 3rd party apps, especially + if it is set on-the-fly when socket service is really needed, as it is + done today and on purpose, but still the 3rd party developer wouldn't easily + control the sequencing of socket operations. + - Finer granularity of events furthered by the async select is a plus only + for socket 3rd party impl., it is simply not needed for the 'light' fltk + use we make of wsock, so here it would also be a bad point, because of all + the logic add-ons necessary for using this functionality, without a clear + benefit. + + So async mode select would not add benefits to fltk, worse, it can slowdown + fltk because of this finer granularity and instrumentation code to be added + for async mode proper operation, not mentioning the side effects... +*/ + +static Fl_GDI_Graphics_Driver fl_gdi_driver; +static Fl_Display_Device fl_gdi_display(&fl_gdi_driver); +FL_EXPORT Fl_Display_Device *fl_display_device = (Fl_Display_Device*)&fl_gdi_display; // does not change +FL_EXPORT Fl_Graphics_Driver *fl_graphics_driver = (Fl_Graphics_Driver*)&fl_gdi_driver; // the current target driver of graphics operations +FL_EXPORT Fl_Surface_Device *fl_surface = (Fl_Surface_Device*)fl_display_device; // the current target surface of graphics operations + +// dynamic wsock dll handling api: +#if defined(__CYGWIN__) && !defined(SOCKET) +# define SOCKET int +#endif +typedef int (WINAPI* fl_wsk_select_f)(int, fd_set*, fd_set*, fd_set*, const struct timeval*); +typedef int (WINAPI* fl_wsk_fd_is_set_f)(SOCKET, fd_set *); + +static HMODULE s_wsock_mod = 0; +static fl_wsk_select_f s_wsock_select=0; +static fl_wsk_fd_is_set_f fl_wsk_fd_is_set=0; + +static HMODULE get_wsock_mod() { + if (!s_wsock_mod) { + s_wsock_mod = LoadLibrary(WSCK_DLL_NAME); + if (s_wsock_mod==NULL) + Fl::fatal("FLTK Lib Error: %s file not found! Please check your winsock dll accessibility.\n",WSCK_DLL_NAME); + s_wsock_select = (fl_wsk_select_f) GetProcAddress(s_wsock_mod, "select"); + fl_wsk_fd_is_set = (fl_wsk_fd_is_set_f) GetProcAddress(s_wsock_mod, "__WSAFDIsSet"); + } + return s_wsock_mod; +} + +/* + * Dynamic linking of imm32.dll + * This library is only needed for a hand full (four ATM) functions relating to + * international text rendering and locales. Dynamically loading reduces initial + * size and link dependencies. + */ +static HMODULE s_imm_module = 0; +typedef HIMC (WINAPI* flTypeImmGetContext)(HWND); +static flTypeImmGetContext flImmGetContext = 0; +typedef BOOL (WINAPI* flTypeImmSetCompositionWindow)(HIMC, LPCOMPOSITIONFORM); +static flTypeImmSetCompositionWindow flImmSetCompositionWindow = 0; +typedef BOOL (WINAPI* flTypeImmReleaseContext)(HWND, HIMC); +static flTypeImmReleaseContext flImmReleaseContext = 0; +typedef BOOL (WINAPI* flTypeImmIsIME)(HKL); +static flTypeImmIsIME flImmIsIME = 0; + +static HMODULE get_imm_module() { + if (!s_imm_module) { + s_imm_module = LoadLibrary("IMM32.DLL"); + if (!s_imm_module) + Fl::fatal("FLTK Lib Error: IMM32.DLL file not found!\n\n" + "Please check your input method manager library accessibility."); + flImmGetContext = (flTypeImmGetContext)GetProcAddress(s_imm_module, "ImmGetContext"); + flImmSetCompositionWindow = (flTypeImmSetCompositionWindow)GetProcAddress(s_imm_module, "ImmSetCompositionWindow"); + flImmReleaseContext = (flTypeImmReleaseContext)GetProcAddress(s_imm_module, "ImmReleaseContext"); + flImmIsIME = (flTypeImmIsIME)GetProcAddress(s_imm_module, "ImmIsIME"); + } + return s_imm_module; +} + +// USE_TRACK_MOUSE - define NO_TRACK_MOUSE if you don't have +// TrackMouseEvent()... +// +// Now (Dec. 2008) we can assume that current Cygwin/MinGW versions +// support the TrackMouseEvent() function, but WinCE obviously doesn't +// support it (STR 2095). Therefore, USE_TRACK_MOUSE is enabled by +// default, but you can disable it by defining NO_TRACK_MOUSE. +// +// TrackMouseEvent is only used to support window leave notifications +// under Windows. It can be used to get FL_LEAVE events, when the +// mouse leaves the _main_ application window (FLTK detects subwindow +// leave events by using normal move events). +// +// Implementation note: If the mouse cursor leaves one subwindow and +// enters another window, then Windows sends a WM_MOUSEMOVE message to +// the new window before it sends a WM_MOUSELEAVE message to the old +// (just left) window. We save the current mouse window in a static variable, +// and if we get a WM_MOUSELEAVE event for the current mouse window, this +// means that the top level window has been left (otherwise we would have +// got another WM_MOUSEMOVE message before). + +// #define NO_TRACK_MOUSE + +#if !defined(NO_TRACK_MOUSE) +# define USE_TRACK_MOUSE +#endif // NO_TRACK_MOUSE + +static Fl_Window *track_mouse_win=0; // current TrackMouseEvent() window + +// USE_CAPTURE_MOUSE_WIN - this must be defined for TrackMouseEvent to work +// correctly with subwindows - otherwise a single mouse click and release +// (without a move) would generate phantom leave events. +// This defines, if the current mouse window (maybe a subwindow) or the +// main window should get mouse events after pushing (and holding) a mouse +// button, i.e. when dragging the mouse. This is done by calling SetCapture +// (see below). + +#ifdef USE_TRACK_MOUSE +#define USE_CAPTURE_MOUSE_WIN +#endif // USE_TRACK_MOUSE + +// +// WM_SYNCPAINT is an "undocumented" message, which is finally defined in +// VC++ 6.0. +// + +#ifndef WM_SYNCPAINT +# define WM_SYNCPAINT 0x0088 +#endif + +#ifndef WM_MOUSELEAVE +# define WM_MOUSELEAVE 0x02a3 +#endif + +#ifndef WM_MOUSEWHEEL +# define WM_MOUSEWHEEL 0x020a +#endif + +#ifndef WHEEL_DELTA +# define WHEEL_DELTA 120 // according to MSDN. +#endif + + +// +// WM_FLSELECT is the user-defined message that we get when one of +// the sockets has pending data, etc. +// + +#define WM_FLSELECT (WM_APP+1) // WM_APP is used for hide-window + + +//////////////////////////////////////////////////////////////// +// interface to poll/select call: + +// fd's are only implemented for sockets. Microsoft Windows does not +// have a unified IO system, so it doesn't support select() on files, +// devices, or pipes... +// +// Microsoft provides the Berkeley select() call and an asynchronous +// select function that sends a WIN32 message when the select condition +// exists. However, we don't try to use the asynchronous WSAAsyncSelect() +// any more for good reasons (see above). +// +// A.S. Dec 2009: We got reports that current winsock2.h files define +// POLLIN, POLLOUT, and POLLERR with conflicting values WRT what we +// used before (STR #2301). Therefore we must not use these values +// for our internal purposes, but use FL_READ, FL_WRITE, and +// FL_EXCEPT, as defined for use in Fl::add_fd(). +// +static int maxfd = 0; +static fd_set fdsets[3]; + +extern IDropTarget *flIDropTarget; + +static int nfds = 0; +static int fd_array_size = 0; +static struct FD { + int fd; + short events; + void (*cb)(int, void*); + void* arg; +} *fd = 0; + +extern unsigned int fl_codepage; + +void fl_reset_spot() +{ +} + +void fl_set_spot(int font, int size, int X, int Y, int W, int H, Fl_Window *win) +{ + if (!win) return; + Fl_Window* tw = win; + while (tw->parent()) tw = tw->window(); // find top level window + + get_imm_module(); + HIMC himc = flImmGetContext(fl_xid(tw)); + + if (himc) { + COMPOSITIONFORM cfs; + cfs.dwStyle = CFS_POINT; + cfs.ptCurrentPos.x = X; + cfs.ptCurrentPos.y = Y - tw->labelsize(); + MapWindowPoints(fl_xid(win), fl_xid(tw), &cfs.ptCurrentPos, 1); + flImmSetCompositionWindow(himc, &cfs); + flImmReleaseContext(fl_xid(tw), himc); + } +} + +void fl_set_status(int x, int y, int w, int h) +{ +} + +void Fl::add_fd(int n, int events, void (*cb)(int, void*), void *v) { + remove_fd(n,events); + int i = nfds++; + if (i >= fd_array_size) { + fd_array_size = 2*fd_array_size+1; + fd = (FD*)realloc(fd, fd_array_size*sizeof(FD)); + } + fd[i].fd = n; + fd[i].events = (short)events; + fd[i].cb = cb; + fd[i].arg = v; + + if (events & FL_READ) FD_SET((unsigned)n, &fdsets[0]); + if (events & FL_WRITE) FD_SET((unsigned)n, &fdsets[1]); + if (events & FL_EXCEPT) FD_SET((unsigned)n, &fdsets[2]); + if (n > maxfd) maxfd = n; +} + +void Fl::add_fd(int fd, void (*cb)(int, void*), void* v) { + Fl::add_fd(fd, FL_READ, cb, v); +} + +void Fl::remove_fd(int n, int events) { + int i,j; + for (i=j=0; i0 if any callbacks were done. This version only +// returns zero if nothing happens during a 0.0 timeout, otherwise +// it returns 1. +int fl_wait(double time_to_wait) { + int have_message = 0; + + run_checks(); + + // idle processing + static char in_idle; + if (Fl::idle && !in_idle) { + in_idle = 1; + Fl::idle(); + in_idle = 0; + } + + if (nfds) { + // For WIN32 we need to poll for socket input FIRST, since + // the event queue is not something we can select() on... + timeval t; + t.tv_sec = 0; + t.tv_usec = 0; + + fd_set fdt[3]; + memcpy(fdt, fdsets, sizeof fdt); // one shot faster fdt init + if (get_wsock_mod()&& s_wsock_select(maxfd+1,&fdt[0],&fdt[1],&fdt[2],&t)) { + // We got something - do the callback! + for (int i = 0; i < nfds; i ++) { + SOCKET f = fd[i].fd; + short revents = 0; + if (fl_wsk_fd_is_set(f, &fdt[0])) revents |= FL_READ; + if (fl_wsk_fd_is_set(f, &fdt[1])) revents |= FL_WRITE; + if (fl_wsk_fd_is_set(f, &fdt[2])) revents |= FL_EXCEPT; + if (fd[i].events & revents) fd[i].cb(f, fd[i].arg); + } + time_to_wait = 0.0; // just peek for any messages + } else { + // we need to check them periodically, so set a short timeout: + if (time_to_wait > .001) time_to_wait = .001; + } + } + + if (Fl::idle || Fl::damage()) + time_to_wait = 0.0; + + // if there are no more windows and this timer is set + // to FOREVER, continue through or look up indefinitely + if (!Fl::first_window() && time_to_wait==1e20) + time_to_wait = 0.0; + + fl_unlock_function(); + + time_to_wait = (time_to_wait > 10000 ? 10000 : time_to_wait); + int t_msec = (int) (time_to_wait * 1000.0 + 0.5); + MsgWaitForMultipleObjects(0, NULL, FALSE, t_msec, QS_ALLINPUT); + + fl_lock_function(); + + // Execute the message we got, and all other pending messages: + // have_message = PeekMessage(&fl_msg, NULL, 0, 0, PM_REMOVE); + have_message = PeekMessageW(&fl_msg, NULL, 0, 0, PM_REMOVE); + if (have_message > 0) { + while (have_message != 0 && have_message != -1) { + if (fl_msg.message == fl_wake_msg) { + // Used for awaking wait() from another thread + thread_message_ = (void*)fl_msg.wParam; + Fl_Awake_Handler func; + void *data; + while (Fl::get_awake_handler_(func, data)==0) { + func(data); + } + } + + TranslateMessage(&fl_msg); + DispatchMessageW(&fl_msg); + have_message = PeekMessageW(&fl_msg, NULL, 0, 0, PM_REMOVE); + } + } + Fl::flush(); + + // This should return 0 if only timer events were handled: + return 1; +} + +// fl_ready() is just like fl_wait(0.0) except no callbacks are done: +int fl_ready() { + if (PeekMessage(&fl_msg, NULL, 0, 0, PM_NOREMOVE)) return 1; + if (!nfds) return 0; + timeval t; + t.tv_sec = 0; + t.tv_usec = 0; + fd_set fdt[3]; + memcpy(fdt, fdsets, sizeof fdt); + return get_wsock_mod() ? s_wsock_select(0,&fdt[0],&fdt[1],&fdt[2],&t) : 0; +} + +//////////////////////////////////////////////////////////////// + +int Fl::x() +{ + RECT r; + + SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0); + return r.left; +} + +int Fl::y() +{ + RECT r; + + SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0); + return r.top; +} + +int Fl::h() +{ + RECT r; + + SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0); + return r.bottom - r.top; +} + +int Fl::w() +{ + RECT r; + + SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0); + return r.right - r.left; +} + +void Fl::get_mouse(int &x, int &y) { + POINT p; + GetCursorPos(&p); + x = p.x; + y = p.y; +} + +//////////////////////////////////////////////////////////////// +// code used for selections: + +char *fl_selection_buffer[2]; +int fl_selection_length[2]; +int fl_selection_buffer_length[2]; +char fl_i_own_selection[2]; + +UINT fl_get_lcid_codepage(LCID id) +{ + char buf[8]; + buf[GetLocaleInfo(id, LOCALE_IDEFAULTANSICODEPAGE, buf, 8)] = 0; + return atol(buf); +} + +// Convert \n -> \r\n +class Lf2CrlfConvert { + char *out; + int outlen; +public: + Lf2CrlfConvert(const char *in, int inlen) { + outlen = 0; + const char *i; + char *o; + int lencount; + // Predict size of \r\n conversion buffer + for ( i=in, lencount = inlen; lencount--; ) { + if ( *i == '\r' && *(i+1) == '\n' ) // leave \r\n untranslated + { i+=2; outlen+=2; } + else if ( *i == '\n' ) // \n by itself? leave room to insert \r + { i++; outlen+=2; } + else + { ++i; ++outlen; } + } + // Alloc conversion buffer + NULL + out = new char[outlen+1]; + // Handle \n -> \r\n conversion + for ( i=in, o=out, lencount = inlen; lencount--; ) { + if ( *i == '\r' && *(i+1) == '\n' ) // leave \r\n untranslated + { *o++ = *i++; *o++ = *i++; } + else if ( *i == '\n' ) // \n by itself? insert \r + { *o++ = '\r'; *o++ = *i++; } + else + { *o++ = *i++; } + } + *o++ = 0; + } + ~Lf2CrlfConvert() { + delete[] out; + } + int GetLength() const { return(outlen); } + const char* GetValue() const { return(out); } +}; + +// call this when you create a selection: +void Fl::copy(const char *stuff, int len, int clipboard) { + if (!stuff || len<0) return; + + // Convert \n -> \r\n (for old apps like Notepad, DOS) + Lf2CrlfConvert buf(stuff, len); + len = buf.GetLength(); + stuff = buf.GetValue(); + + if (len+1 > fl_selection_buffer_length[clipboard]) { + delete[] fl_selection_buffer[clipboard]; + fl_selection_buffer[clipboard] = new char[len+100]; + fl_selection_buffer_length[clipboard] = len+100; + } + memcpy(fl_selection_buffer[clipboard], stuff, len); + fl_selection_buffer[clipboard][len] = 0; // needed for direct paste + fl_selection_length[clipboard] = len; + if (clipboard) { + // set up for "delayed rendering": + if (OpenClipboard(NULL)) { + // if the system clipboard works, use it + int utf16_len = fl_utf8toUtf16(fl_selection_buffer[clipboard], fl_selection_length[clipboard], 0, 0); + EmptyClipboard(); + HGLOBAL hMem = GlobalAlloc(GHND, utf16_len * 2 + 2); // moveable and zero'ed mem alloc. + LPVOID memLock = GlobalLock(hMem); + fl_utf8toUtf16(fl_selection_buffer[clipboard], fl_selection_length[clipboard], (unsigned short*) memLock, utf16_len * 2); + GlobalUnlock(hMem); + SetClipboardData(CF_UNICODETEXT, hMem); + CloseClipboard(); + GlobalFree(hMem); + fl_i_own_selection[clipboard] = 0; + } else { + // only if it fails, instruct paste() to use the internal buffers + fl_i_own_selection[clipboard] = 1; + } + } +} + +// Call this when a "paste" operation happens: +void Fl::paste(Fl_Widget &receiver, int clipboard) { + if (!clipboard || fl_i_own_selection[clipboard]) { + // We already have it, do it quickly without window server. + // Notice that the text is clobbered if set_selection is + // called in response to FL_PASTE! + + // Convert \r\n -> \n + char *i = fl_selection_buffer[clipboard]; + if (i==0L) { + Fl::e_text = 0; + return; + } + Fl::e_text = new char[fl_selection_length[clipboard]+1]; + char *o = Fl::e_text; + while (*i) { + if ( *i == '\r' && *(i+1) == '\n') i++; + else *o++ = *i++; + } + *o = 0; + Fl::e_length = o - Fl::e_text; + receiver.handle(FL_PASTE); + delete [] Fl::e_text; + Fl::e_text = 0; + } else { + if (!OpenClipboard(NULL)) return; + HANDLE h = GetClipboardData(CF_UNICODETEXT); + if (h) { + wchar_t *memLock = (wchar_t*) GlobalLock(h); + int utf16_len = wcslen(memLock); + Fl::e_text = (char*) malloc (utf16_len * 4 + 1); + int utf8_len = fl_utf8fromwc(Fl::e_text, utf16_len * 4, memLock, utf16_len); + *(Fl::e_text + utf8_len) = 0; + LPSTR a,b; + a = b = Fl::e_text; + while (*a) { // strip the CRLF pairs ($%$#@^) + if (*a == '\r' && a[1] == '\n') a++; + else *b++ = *a++; + } + *b = 0; + Fl::e_length = b - Fl::e_text; + receiver.handle(FL_PASTE); + GlobalUnlock(h); + free(Fl::e_text); + Fl::e_text = 0; + } + CloseClipboard(); + } +} + +//////////////////////////////////////////////////////////////// +char fl_is_ime = 0; +void fl_get_codepage() +{ + HKL hkl = GetKeyboardLayout(0); + TCHAR ld[8]; + + GetLocaleInfo (LOWORD(hkl), LOCALE_IDEFAULTANSICODEPAGE, ld, 6); + DWORD ccp = atol(ld); + fl_is_ime = 0; + + fl_codepage = ccp; + if (fl_aimm) { + fl_aimm->GetCodePageA(GetKeyboardLayout(0), &fl_codepage); + } else if (get_imm_module() && flImmIsIME(hkl)) { + fl_is_ime = 1; + } +} + +HWND fl_capture; + +static int mouse_event(Fl_Window *window, int what, int button, + WPARAM wParam, LPARAM lParam) +{ + static int px, py, pmx, pmy; + POINT pt; + Fl::e_x = pt.x = (signed short)LOWORD(lParam); + Fl::e_y = pt.y = (signed short)HIWORD(lParam); + ClientToScreen(fl_xid(window), &pt); + Fl::e_x_root = pt.x; + Fl::e_y_root = pt.y; +#ifdef USE_CAPTURE_MOUSE_WIN + Fl_Window *mouse_window = window; // save "mouse window" +#endif + while (window->parent()) { + Fl::e_x += window->x(); + Fl::e_y += window->y(); + window = window->window(); + } + + ulong state = Fl::e_state & 0xff0000; // keep shift key states +#if 0 + // mouse event reports some shift flags, perhaps save them? + if (wParam & MK_SHIFT) state |= FL_SHIFT; + if (wParam & MK_CONTROL) state |= FL_CTRL; +#endif + if (wParam & MK_LBUTTON) state |= FL_BUTTON1; + if (wParam & MK_MBUTTON) state |= FL_BUTTON2; + if (wParam & MK_RBUTTON) state |= FL_BUTTON3; + Fl::e_state = state; + + switch (what) { + case 1: // double-click + if (Fl::e_is_click) {Fl::e_clicks++; goto J1;} + case 0: // single-click + Fl::e_clicks = 0; + J1: +#ifdef USE_CAPTURE_MOUSE_WIN + if (!fl_capture) SetCapture(fl_xid(mouse_window)); // use mouse window +#else + if (!fl_capture) SetCapture(fl_xid(window)); // use main window +#endif + Fl::e_keysym = FL_Button + button; + Fl::e_is_click = 1; + px = pmx = Fl::e_x_root; py = pmy = Fl::e_y_root; + return Fl::handle(FL_PUSH,window); + + case 2: // release: + if (!fl_capture) ReleaseCapture(); + Fl::e_keysym = FL_Button + button; + return Fl::handle(FL_RELEASE,window); + + case 3: // move: + default: // avoid compiler warning + // MSWindows produces extra events even if mouse does not move, ignore em: + if (Fl::e_x_root == pmx && Fl::e_y_root == pmy) return 1; + pmx = Fl::e_x_root; pmy = Fl::e_y_root; + if (abs(Fl::e_x_root-px)>5 || abs(Fl::e_y_root-py)>5) Fl::e_is_click = 0; + return Fl::handle(FL_MOVE,window); + + } +} + +// convert a MSWindows VK_x to an Fltk (X) Keysym: +// See also the inverse converter in Fl_get_key_win32.cxx +// This table is in numeric order by VK: +static const struct {unsigned short vk, fltk, extended;} vktab[] = { + {VK_BACK, FL_BackSpace}, + {VK_TAB, FL_Tab}, + {VK_CLEAR, FL_KP+'5', 0xff0b/*XK_Clear*/}, + {VK_RETURN, FL_Enter, FL_KP_Enter}, + {VK_SHIFT, FL_Shift_L, FL_Shift_R}, + {VK_CONTROL, FL_Control_L, FL_Control_R}, + {VK_MENU, FL_Alt_L, FL_Alt_R}, + {VK_PAUSE, FL_Pause}, + {VK_CAPITAL, FL_Caps_Lock}, + {VK_ESCAPE, FL_Escape}, + {VK_SPACE, ' '}, + {VK_PRIOR, FL_KP+'9', FL_Page_Up}, + {VK_NEXT, FL_KP+'3', FL_Page_Down}, + {VK_END, FL_KP+'1', FL_End}, + {VK_HOME, FL_KP+'7', FL_Home}, + {VK_LEFT, FL_KP+'4', FL_Left}, + {VK_UP, FL_KP+'8', FL_Up}, + {VK_RIGHT, FL_KP+'6', FL_Right}, + {VK_DOWN, FL_KP+'2', FL_Down}, + {VK_SNAPSHOT, FL_Print}, // does not work on NT + {VK_INSERT, FL_KP+'0', FL_Insert}, + {VK_DELETE, FL_KP+'.', FL_Delete}, + {VK_LWIN, FL_Meta_L}, + {VK_RWIN, FL_Meta_R}, + {VK_APPS, FL_Menu}, + {VK_MULTIPLY, FL_KP+'*'}, + {VK_ADD, FL_KP+'+'}, + {VK_SUBTRACT, FL_KP+'-'}, + {VK_DECIMAL, FL_KP+'.'}, + {VK_DIVIDE, FL_KP+'/'}, + {VK_NUMLOCK, FL_Num_Lock}, + {VK_SCROLL, FL_Scroll_Lock}, + {0xba, ';'}, + {0xbb, '='}, + {0xbc, ','}, + {0xbd, '-'}, + {0xbe, '.'}, + {0xbf, '/'}, + {0xc0, '`'}, + {0xdb, '['}, + {0xdc, '\\'}, + {0xdd, ']'}, + {0xde, '\''} +}; +static int ms2fltk(int vk, int extended) { + static unsigned short vklut[256]; + static unsigned short extendedlut[256]; + if (!vklut[1]) { // init the table + unsigned int i; + for (i = 0; i < 256; i++) vklut[i] = tolower(i); + for (i=VK_F1; i<=VK_F16; i++) vklut[i] = i+(FL_F-(VK_F1-1)); + for (i=VK_NUMPAD0; i<=VK_NUMPAD9; i++) vklut[i] = i+(FL_KP+'0'-VK_NUMPAD0); + for (i = 0; i < sizeof(vktab)/sizeof(*vktab); i++) { + vklut[vktab[i].vk] = vktab[i].fltk; + extendedlut[vktab[i].vk] = vktab[i].extended; + } + for (i = 0; i < 256; i++) if (!extendedlut[i]) extendedlut[i] = vklut[i]; + } + return extended ? extendedlut[vk] : vklut[vk]; +} + +#if USE_COLORMAP +extern HPALETTE fl_select_palette(void); // in fl_color_win32.cxx +#endif + + +///////////////////////////////////////////////////////////////////////////// +/// Win32 timers +/// + +struct Win32Timer +{ + UINT_PTR handle; + Fl_Timeout_Handler callback; + void *data; +}; +static Win32Timer* win32_timers; +static int win32_timer_alloc; +static int win32_timer_used; +static HWND s_TimerWnd; + +static void realloc_timers() +{ + if (win32_timer_alloc == 0) { + win32_timer_alloc = 8; + } + win32_timer_alloc *= 2; + Win32Timer* new_timers = new Win32Timer[win32_timer_alloc]; + memset(new_timers, 0, sizeof(Win32Timer) * win32_timer_used); + memcpy(new_timers, win32_timers, sizeof(Win32Timer) * win32_timer_used); + Win32Timer* delete_me = win32_timers; + win32_timers = new_timers; + delete [] delete_me; +} + +static void delete_timer(Win32Timer& t) +{ + KillTimer(s_TimerWnd, t.handle); + memset(&t, 0, sizeof(Win32Timer)); +} + +/// END TIMERS +///////////////////////////////////////////////////////////////////////////// + +static Fl_Window* resize_bug_fix; + +extern void fl_save_pen(void); +extern void fl_restore_pen(void); + +static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + // Copy the message to fl_msg so add_handler code can see it, it is + // already there if this is called by DispatchMessage, but not if + // Windows calls this directly. + fl_msg.hwnd = hWnd; + fl_msg.message = uMsg; + fl_msg.wParam = wParam; + fl_msg.lParam = lParam; + //fl_msg.time = ??? + //fl_msg.pt = ??? + //fl_msg.lPrivate = ??? + + Fl_Window *window = fl_find(hWnd); + + if (window) switch (uMsg) { + + case WM_QUIT: // this should not happen? + Fl::fatal("WM_QUIT message"); + + case WM_CLOSE: // user clicked close box + Fl::handle(FL_CLOSE, window); + PostQuitMessage(0); + return 0; + + case WM_SYNCPAINT : + case WM_NCPAINT : + case WM_ERASEBKGND : + // Andreas Weitl - WM_SYNCPAINT needs to be passed to DefWindowProc + // so that Windows can generate the proper paint messages... + // Similarly, WM_NCPAINT and WM_ERASEBKGND need this, too... + break; + + case WM_PAINT: { + Fl_Region R; + Fl_X *i = Fl_X::i(window); + i->wait_for_expose = 0; + char redraw_whole_window = false; + if (!i->region && window->damage()) { + // Redraw the whole window... + i->region = CreateRectRgn(0, 0, window->w(), window->h()); + redraw_whole_window = true; + } + + // We need to merge WIN32's damage into FLTK's damage. + R = CreateRectRgn(0,0,0,0); + int r = GetUpdateRgn(hWnd,R,0); + if (r==NULLREGION && !redraw_whole_window) { + break; + } + + if (i->region) { + // Also tell WIN32 that we are drawing someplace else as well... + CombineRgn(i->region, i->region, R, RGN_OR); + XDestroyRegion(R); + } else { + i->region = R; + } + if (window->type() == FL_DOUBLE_WINDOW) ValidateRgn(hWnd,0); + else ValidateRgn(hWnd,i->region); + + window->clear_damage((uchar)(window->damage()|FL_DAMAGE_EXPOSE)); + // These next two statements should not be here, so that all update + // is deferred until Fl::flush() is called during idle. However WIN32 + // apparently is very unhappy if we don't obey it and draw right now. + // Very annoying! + fl_GetDC(hWnd); // Make sure we have a DC for this window... + fl_save_pen(); + i->flush(); + fl_restore_pen(); + window->clear_damage(); + } return 0; + + case WM_LBUTTONDOWN: mouse_event(window, 0, 1, wParam, lParam); return 0; + case WM_LBUTTONDBLCLK:mouse_event(window, 1, 1, wParam, lParam); return 0; + case WM_LBUTTONUP: mouse_event(window, 2, 1, wParam, lParam); return 0; + case WM_MBUTTONDOWN: mouse_event(window, 0, 2, wParam, lParam); return 0; + case WM_MBUTTONDBLCLK:mouse_event(window, 1, 2, wParam, lParam); return 0; + case WM_MBUTTONUP: mouse_event(window, 2, 2, wParam, lParam); return 0; + case WM_RBUTTONDOWN: mouse_event(window, 0, 3, wParam, lParam); return 0; + case WM_RBUTTONDBLCLK:mouse_event(window, 1, 3, wParam, lParam); return 0; + case WM_RBUTTONUP: mouse_event(window, 2, 3, wParam, lParam); return 0; + + case WM_MOUSEMOVE: +#ifdef USE_TRACK_MOUSE + if (track_mouse_win != window) { + TRACKMOUSEEVENT tme; + tme.cbSize = sizeof(TRACKMOUSEEVENT); + tme.dwFlags = TME_LEAVE; + tme.hwndTrack = hWnd; + _TrackMouseEvent(&tme); + track_mouse_win = window; + } +#endif // USE_TRACK_MOUSE + mouse_event(window, 3, 0, wParam, lParam); + return 0; + + case WM_MOUSELEAVE: + if (track_mouse_win == window) { // we left the top level window ! + Fl_Window *tw = window; + while (tw->parent()) tw = tw->window(); // find top level window + Fl::belowmouse(0); + Fl::handle(FL_LEAVE, tw); + } + track_mouse_win = 0; // force TrackMouseEvent() restart + break; + + case WM_SETFOCUS: + Fl::handle(FL_FOCUS, window); + break; + + case WM_KILLFOCUS: + Fl::handle(FL_UNFOCUS, window); + Fl::flush(); // it never returns to main loop when deactivated... + break; + + case WM_SHOWWINDOW: + if (!window->parent()) { + Fl::handle(wParam ? FL_SHOW : FL_HIDE, window); + } + break; + + case WM_ACTIVATEAPP: + // From eric@vfx.sel.sony.com, we should process WM_ACTIVATEAPP + // messages to restore the correct state of the shift/ctrl/alt/lock + // keys... Added control, shift, alt, and meta keys, and changed + // to use GetAsyncKeyState and do it when wParam is 1 + // (that means we have focus...) + if (wParam) + { + ulong state = 0; + if (GetAsyncKeyState(VK_CAPITAL)) state |= FL_CAPS_LOCK; + if (GetAsyncKeyState(VK_NUMLOCK)) state |= FL_NUM_LOCK; + if (GetAsyncKeyState(VK_SCROLL)) state |= FL_SCROLL_LOCK; + if (GetAsyncKeyState(VK_CONTROL)&~1) state |= FL_CTRL; + if (GetAsyncKeyState(VK_SHIFT)&~1) state |= FL_SHIFT; + if (GetAsyncKeyState(VK_MENU)) state |= FL_ALT; + if ((GetAsyncKeyState(VK_LWIN)|GetAsyncKeyState(VK_RWIN))&~1) state |= FL_META; + Fl::e_state = state; + return 0; + } + break; + + case WM_INPUTLANGCHANGE: + fl_get_codepage(); + break; + case WM_IME_COMPOSITION: +// if (!fl_is_nt4() && lParam & GCS_RESULTCLAUSE) { +// HIMC himc = ImmGetContext(hWnd); +// wlen = ImmGetCompositionStringW(himc, GCS_RESULTSTR, +// wbuf, sizeof(wbuf)) / sizeof(short); +// if (wlen < 0) wlen = 0; +// wbuf[wlen] = 0; +// ImmReleaseContext(hWnd, himc); +// } + break; + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + case WM_KEYUP: + case WM_SYSKEYUP: + // save the keysym until we figure out the characters: + Fl::e_keysym = Fl::e_original_keysym = ms2fltk(wParam,lParam&(1<<24)); + // See if TranslateMessage turned it into a WM_*CHAR message: + if (PeekMessageW(&fl_msg, hWnd, WM_CHAR, WM_SYSDEADCHAR, PM_REMOVE)) + { + uMsg = fl_msg.message; + wParam = fl_msg.wParam; + lParam = fl_msg.lParam; + } + case WM_DEADCHAR: + case WM_SYSDEADCHAR: + case WM_CHAR: + case WM_SYSCHAR: { + ulong state = Fl::e_state & 0xff000000; // keep the mouse button state + // if GetKeyState is expensive we might want to comment some of these out: + if (GetKeyState(VK_SHIFT)&~1) state |= FL_SHIFT; + if (GetKeyState(VK_CAPITAL)) state |= FL_CAPS_LOCK; + if (GetKeyState(VK_CONTROL)&~1) state |= FL_CTRL; + // Alt gets reported for the Alt-GR switch on foreign keyboards. + // so we need to check the event as well to get it right: + if ((lParam&(1<<29)) //same as GetKeyState(VK_MENU) + && uMsg != WM_CHAR) state |= FL_ALT; + if (GetKeyState(VK_NUMLOCK)) state |= FL_NUM_LOCK; + if ((GetKeyState(VK_LWIN)|GetKeyState(VK_RWIN))&~1) { + // WIN32 bug? GetKeyState returns garbage if the user hit the + // meta key to pop up start menu. Sigh. + if ((GetAsyncKeyState(VK_LWIN)|GetAsyncKeyState(VK_RWIN))&~1) + state |= FL_META; + } + if (GetKeyState(VK_SCROLL)) state |= FL_SCROLL_LOCK; + Fl::e_state = state; + static char buffer[1024]; + if (uMsg == WM_CHAR || uMsg == WM_SYSCHAR) { + + xchar u = (xchar) wParam; +// Fl::e_length = fl_unicode2utf(&u, 1, buffer); + Fl::e_length = fl_utf8fromwc(buffer, 1024, &u, 1); + buffer[Fl::e_length] = 0; + + + } else if (Fl::e_keysym >= FL_KP && Fl::e_keysym <= FL_KP_Last) { + if (state & FL_NUM_LOCK) { + // Convert to regular keypress... + buffer[0] = Fl::e_keysym-FL_KP; + Fl::e_length = 1; + } else { + // Convert to special keypress... + buffer[0] = 0; + Fl::e_length = 0; + switch (Fl::e_keysym) { + case FL_KP + '0' : + Fl::e_keysym = FL_Insert; + break; + case FL_KP + '1' : + Fl::e_keysym = FL_End; + break; + case FL_KP + '2' : + Fl::e_keysym = FL_Down; + break; + case FL_KP + '3' : + Fl::e_keysym = FL_Page_Down; + break; + case FL_KP + '4' : + Fl::e_keysym = FL_Left; + break; + case FL_KP + '6' : + Fl::e_keysym = FL_Right; + break; + case FL_KP + '7' : + Fl::e_keysym = FL_Home; + break; + case FL_KP + '8' : + Fl::e_keysym = FL_Up; + break; + case FL_KP + '9' : + Fl::e_keysym = FL_Page_Up; + break; + case FL_KP + '.' : + Fl::e_keysym = FL_Delete; + break; + case FL_KP + '/' : + case FL_KP + '*' : + case FL_KP + '-' : + case FL_KP + '+' : + buffer[0] = Fl::e_keysym-FL_KP; + Fl::e_length = 1; + break; + } + } + } else if ((lParam & (1<<31))==0){ + buffer[0] = 0; + Fl::e_length = 0; + } + Fl::e_text = buffer; + if (lParam & (1<<31)) { // key up events. + if (Fl::handle(FL_KEYUP, window)) return 0; + break; + } + // for (int i = lParam&0xff; i--;) + while (window->parent()) window = window->window(); + if (Fl::handle(FL_KEYBOARD,window)) return 0; + break;} + + case WM_MOUSEWHEEL: { + static int delta = 0; // running total of all motion + delta += (SHORT)(HIWORD(wParam)); + Fl::e_dy = -delta / WHEEL_DELTA; + delta += Fl::e_dy * WHEEL_DELTA; + if (Fl::e_dy) Fl::handle(FL_MOUSEWHEEL, window); + return 0; + } + + case WM_GETMINMAXINFO: + Fl_X::i(window)->set_minmax((LPMINMAXINFO)lParam); + break; + + case WM_SIZE: + if (!window->parent()) { + if (wParam == SIZE_MINIMIZED || wParam == SIZE_MAXHIDE) { + Fl::handle(FL_HIDE, window); + } else { + Fl::handle(FL_SHOW, window); + resize_bug_fix = window; + window->size(LOWORD(lParam), HIWORD(lParam)); + } + } + break; + + case WM_MOVE: { + resize_bug_fix = window; + int nx = LOWORD(lParam); + int ny = HIWORD(lParam); + if (nx & 0x8000) nx -= 65536; + if (ny & 0x8000) ny -= 65536; + window->position(nx, ny); } + break; + + case WM_SETCURSOR: + if (LOWORD(lParam) == HTCLIENT) { + while (window->parent()) window = window->window(); + SetCursor(Fl_X::i(window)->cursor); + return 0; + } + break; + +#if USE_COLORMAP + case WM_QUERYNEWPALETTE : + fl_GetDC(hWnd); + if (fl_select_palette()) InvalidateRect(hWnd, NULL, FALSE); + break; + + case WM_PALETTECHANGED: + fl_GetDC(hWnd); + if ((HWND)wParam != hWnd && fl_select_palette()) UpdateColors(fl_gc); + break; + + case WM_CREATE : + fl_GetDC(hWnd); + fl_select_palette(); + break; +#endif + + case WM_DESTROYCLIPBOARD: + fl_i_own_selection[1] = 0; + return 1; + + case WM_RENDERALLFORMATS: + fl_i_own_selection[1] = 0; + // Windoze seems unhappy unless I do these two steps. Documentation + // seems to vary on whether opening the clipboard is necessary or + // is in fact wrong: + CloseClipboard(); + OpenClipboard(NULL); + // fall through... + case WM_RENDERFORMAT: { + HANDLE h; + +// int l = fl_utf_nb_char((unsigned char*)fl_selection_buffer[1], fl_selection_length[1]); + int l = fl_utf8toUtf16(fl_selection_buffer[1], fl_selection_length[1], NULL, 0); // Pass NULL buffer to query length required + h = GlobalAlloc(GHND, (l+1) * sizeof(unsigned short)); + if (h) { + unsigned short *g = (unsigned short*) GlobalLock(h); +// fl_utf2unicode((unsigned char *)fl_selection_buffer[1], fl_selection_length[1], (xchar*)g); + l = fl_utf8toUtf16(fl_selection_buffer[1], fl_selection_length[1], g, (l+1)); + g[l] = 0; + GlobalUnlock(h); + SetClipboardData(CF_UNICODETEXT, h); + } + + // Windoze also seems unhappy if I don't do this. Documentation very + // unclear on what is correct: + if (fl_msg.message == WM_RENDERALLFORMATS) CloseClipboard(); + return 1;} + + default: + if (Fl::handle(0,0)) return 0; + break; + } + + + return DefWindowProcW(hWnd, uMsg, wParam, lParam); +} + +//////////////////////////////////////////////////////////////// +// This function gets the dimensions of the top/left borders and +// the title bar, if there is one, based on the FL_BORDER, FL_MODAL +// and FL_NONMODAL flags, and on the window's size range. +// It returns the following values: +// +// value | border | title bar +// 0 | none | no +// 1 | fix | yes +// 2 | size | yes + +int Fl_X::fake_X_wm(const Fl_Window* w,int &X,int &Y, int &bt,int &bx, int &by) { + int W, H, xoff, yoff, dx, dy; + int ret = bx = by = bt = 0; + + int fallback = 1; + if (!w->parent()) { + HWND hwnd = fl_xid(w); + if (hwnd) { + // The block below calculates the window borders by requesting the + // required decorated window rectangle for a desired client rectangle. + // If any part of the function above fails, we will drop to a + // fallback to get the best guess which is always available. + HWND hwnd = fl_xid(w); + // request the style flags of this window, as WIN32 sees them + LONG style = GetWindowLong(hwnd, GWL_STYLE); + LONG exstyle = GetWindowLong(hwnd, GWL_EXSTYLE); + RECT r; + r.left = w->x(); + r.top = w->y(); + r.right = w->x()+w->w(); + r.bottom = w->y()+w->h(); + // get the decoration rectangle for the desired client rectangle + BOOL ok = AdjustWindowRectEx(&r, style, FALSE, exstyle); + if (ok) { + X = r.left; + Y = r.top; + W = r.right - r.left; + H = r.bottom - r.top; + bx = w->x() - r.left; + by = r.bottom - w->y() - w->h(); // height of the bootm frame + bt = w->y() - r.top - by; // height of top caption bar + xoff = bx; + yoff = by + bt; + dx = W - w->w(); + dy = H - w->h(); + if (w->size_range_set && (w->maxw != w->minw || w->maxh != w->minh)) + ret = 2; + else + ret = 1; + fallback = 0; + } + } + } + // This is the original (pre 1.1.7) routine to calculate window border sizes. + if (fallback) { + if (w->border() && !w->parent()) { + if (w->size_range_set && (w->maxw != w->minw || w->maxh != w->minh)) { + ret = 2; + bx = GetSystemMetrics(SM_CXSIZEFRAME); + by = GetSystemMetrics(SM_CYSIZEFRAME); + } else { + ret = 1; + bx = GetSystemMetrics(SM_CXFIXEDFRAME); + by = GetSystemMetrics(SM_CYFIXEDFRAME); + } + bt = GetSystemMetrics(SM_CYCAPTION); + } + //The coordinates of the whole window, including non-client area + xoff = bx; + yoff = by + bt; + dx = 2*bx; + dy = 2*by + bt; + X = w->x()-xoff; + Y = w->y()-yoff; + W = w->w()+dx; + H = w->h()+dy; + } + + //Proceed to positioning the window fully inside the screen, if possible + //Make border's lower right corner visible + int scr_x, scr_y, scr_w, scr_h; + Fl::screen_xywh(scr_x, scr_y, scr_w, scr_h, X, Y); + if (scr_x+scr_w < X+W) X = scr_x+scr_w - W; + if (scr_y+scr_h < Y+H) Y = scr_y+scr_h - H; + //Make border's upper left corner visible + if (Xw()) X = scr_x+scr_w - w->w() - dx; + if (scr_y+scr_h < Y+dy+ w->h()) Y = scr_y+scr_h - w->h() - dy; + //Make client area's upper left corner visible + if (X+xoff < scr_x) X = scr_x-xoff; + if (Y+yoff < scr_y) Y = scr_y-yoff; + //Return the client area's top left corner in (X,Y) + X+=xoff; + Y+=yoff; + + return ret; +} + +//////////////////////////////////////////////////////////////// + +void Fl_Window::resize(int X,int Y,int W,int H) { + UINT flags = SWP_NOSENDCHANGING | SWP_NOZORDER + | SWP_NOACTIVATE | SWP_NOOWNERZORDER; + int is_a_resize = (W != w() || H != h()); + int resize_from_program = (this != resize_bug_fix); + if (!resize_from_program) resize_bug_fix = 0; + if (X != x() || Y != y()) { + force_position(1); + } else { + if (!is_a_resize) return; + flags |= SWP_NOMOVE; + } + if (is_a_resize) { + Fl_Group::resize(X,Y,W,H); + if (visible_r()) { + redraw(); + // only wait for exposure if this window has a size - a window + // with no width or height will never get an exposure event + if (i && W>0 && H>0) + i->wait_for_expose = 1; + } + } else { + x(X); y(Y); + flags |= SWP_NOSIZE; + } + if (!border()) flags |= SWP_NOACTIVATE; + if (resize_from_program && shown()) { + if (!resizable()) size_range(w(),h(),w(),h()); + int dummy_x, dummy_y, bt, bx, by; + //Ignore window managing when resizing, so that windows (and more + //specifically menus) can be moved offscreen. + if (Fl_X::fake_X_wm(this, dummy_x, dummy_y, bt, bx, by)) { + X -= bx; + Y -= by+bt; + W += 2*bx; + H += 2*by+bt; + } + // avoid zero size windows. A zero sized window on Win32 + // will cause continouly new redraw events. + if (W<=0) W = 1; + if (H<=0) H = 1; + SetWindowPos(i->xid, 0, X, Y, W, H, flags); + } +} + +//////////////////////////////////////////////////////////////// + +/* + * This silly little class remembers the name of all window classes + * we register to avoid double registration. It has the added bonus + * of freeing everything on application close as well. + */ +class NameList { +public: + NameList() { name = (char**)malloc(sizeof(char**)); NName = 1; nName = 0; } + ~NameList() { + int i; + for (i=0; iparent() && !Fl_X::i(w->window())) { + w->set_visible(); + return 0L; + } + + static NameList class_name_list; + static const char *first_class_name = 0L; + const char *class_name = w->xclass(); + if (!class_name) class_name = first_class_name; // reuse first class name used + if (!class_name) class_name = "FLTK"; // default to create a "FLTK" WNDCLASS + if (!first_class_name) { + first_class_name = class_name; + } + + wchar_t class_namew[100]; // (limited) buffer for Windows class name + + // convert UTF-8 class_name to wchar_t for RegisterClassExW and CreateWindowExW + + fl_utf8toUtf16(class_name,strlen(class_name), // in + (unsigned short*)class_namew, // out + sizeof(class_namew)/sizeof(wchar_t)); // max. size + + if (!class_name_list.has_name(class_name)) { + WNDCLASSEXW wcw; + memset(&wcw, 0, sizeof(wcw)); + wcw.cbSize = sizeof(WNDCLASSEXW); + + // Documentation states a device context consumes about 800 bytes + // of memory... so who cares? If 800 bytes per window is what it + // takes to speed things up, I'm game. + //wc.style = CS_HREDRAW | CS_VREDRAW | CS_CLASSDC | CS_DBLCLKS; + wcw.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_DBLCLKS; + wcw.lpfnWndProc = (WNDPROC)WndProc; + wcw.cbClsExtra = wcw.cbWndExtra = 0; + wcw.hInstance = fl_display; + if (!w->icon()) + w->icon((void *)LoadIcon(NULL, IDI_APPLICATION)); + wcw.hIcon = wcw.hIconSm = (HICON)w->icon(); + wcw.hCursor = fl_default_cursor = LoadCursor(NULL, IDC_ARROW); + //uchar r,g,b; Fl::get_color(FL_GRAY,r,g,b); + //wc.hbrBackground = (HBRUSH)CreateSolidBrush(RGB(r,g,b)); + wcw.hbrBackground = NULL; + wcw.lpszMenuName = NULL; + wcw.lpszClassName = class_namew; + RegisterClassExW(&wcw); + class_name_list.add_name(class_name); + } + + const wchar_t* message_namew = L"FLTK::ThreadWakeup"; + if (!fl_wake_msg) fl_wake_msg = RegisterWindowMessageW(message_namew); + + HWND parent; + DWORD style = WS_CLIPCHILDREN | WS_CLIPSIBLINGS; + DWORD styleEx = WS_EX_LEFT; + + int xp = w->x(); + int yp = w->y(); + int wp = w->w(); + int hp = w->h(); + + int showit = 1; + + if (w->parent()) { + style |= WS_CHILD; + styleEx |= WS_EX_WINDOWEDGE | WS_EX_CONTROLPARENT; + parent = fl_xid(w->window()); + } else { + if (!w->size_range_set) { + if (w->resizable()) { + Fl_Widget *o = w->resizable(); + int minw = o->w(); if (minw > 100) minw = 100; + int minh = o->h(); if (minh > 100) minh = 100; + w->size_range(w->w() - o->w() + minw, w->h() - o->h() + minh, 0, 0); + } else { + w->size_range(w->w(), w->h(), w->w(), w->h()); + } + } + styleEx |= WS_EX_WINDOWEDGE | WS_EX_CONTROLPARENT; + int xwm = xp , ywm = yp , bt, bx, by; + switch (fake_X_wm(w, xwm, ywm, bt, bx, by)) { + // No border (used for menus) + case 0: style |= WS_POPUP; + styleEx |= WS_EX_TOOLWINDOW; + break; + + // Thin border and title bar + case 1: style |= WS_DLGFRAME | WS_CAPTION; break; + + // Thick, resizable border and title bar, with maximize button + case 2: style |= WS_THICKFRAME | WS_MAXIMIZEBOX | WS_CAPTION ; break; + } + if (by+bt) { + if (!w->modal()) style |= WS_SYSMENU | WS_MINIMIZEBOX; + wp += 2*bx; + hp += 2*by+bt; + } + if (!w->force_position()) { + xp = yp = CW_USEDEFAULT; + } else { + if (!Fl::grab()) { + xp = xwm; yp = ywm; + w->x(xp);w->y(yp); + } + xp -= bx; + yp -= by+bt; + } + + parent = 0; + if (w->non_modal() && Fl_X::first && !fl_disable_transient_for) { + // find some other window to be "transient for": + Fl_Window* w = Fl_X::first->w; + while (w->parent()) w = w->window(); + parent = fl_xid(w); + if (!w->visible()) showit = 0; + } else if (Fl::grab()) parent = fl_xid(Fl::grab()); + } + + Fl_X* x = new Fl_X; + x->other_xid = 0; + x->setwindow(w); + x->region = 0; + x->private_dc = 0; + x->cursor = fl_default_cursor; + if (!fl_codepage) fl_get_codepage(); + + WCHAR *lab = NULL; + if (w->label()) { + int l = strlen(w->label()); +// lab = (WCHAR*) malloc((l + 1) * sizeof(short)); +// l = fl_utf2unicode((unsigned char*)w->label(), l, (xchar*)lab); +// lab[l] = 0; + unsigned wlen = fl_utf8toUtf16(w->label(), l, NULL, 0); // Pass NULL to query length + wlen++; + lab = (WCHAR *) malloc(sizeof(WCHAR)*wlen); + wlen = fl_utf8toUtf16(w->label(), l, (unsigned short*)lab, wlen); + lab[wlen] = 0; + } + x->xid = CreateWindowExW( + styleEx, + class_namew, lab, style, + xp, yp, wp, hp, + parent, + NULL, // menu + fl_display, + NULL // creation parameters + ); + if (lab) free(lab); + + x->next = Fl_X::first; + Fl_X::first = x; + + x->wait_for_expose = 1; + if (fl_show_iconic) {showit = 0; fl_show_iconic = 0;} + if (showit) { + w->set_visible(); + int old_event = Fl::e_number; + w->handle(Fl::e_number = FL_SHOW); // get child windows to appear + Fl::e_number = old_event; + w->redraw(); // force draw to happen + } + // If we've captured the mouse, we dont want to activate any + // other windows from the code, or we loose the capture. + ShowWindow(x->xid, !showit ? SW_SHOWMINNOACTIVE : + (Fl::grab() || (style & WS_POPUP)) ? SW_SHOWNOACTIVATE : SW_SHOWNORMAL); + + // Register all windows for potential drag'n'drop operations + fl_OleInitialize(); + RegisterDragDrop(x->xid, flIDropTarget); + + if (!fl_aimm) { + CoCreateInstance(CLSID_CActiveIMM, NULL, CLSCTX_INPROC_SERVER, + IID_IActiveIMMApp, (void**) &fl_aimm); + if (fl_aimm) { + fl_aimm->Activate(TRUE); + } + } + + if (w->modal()) {Fl::modal_ = w; fl_fix_focus();} + return x; +} + + + + +///////////////////////////////////////////////////////////////////////////// +/// Win32 timers +/// + + +static LRESULT CALLBACK s_TimerProc(HWND hwnd, UINT msg, + WPARAM wParam, LPARAM lParam) +{ + switch (msg) { + case WM_TIMER: + { + unsigned int id = wParam - 1; + if (id < (unsigned int)win32_timer_used && win32_timers[id].handle) { + Fl_Timeout_Handler cb = win32_timers[id].callback; + void* data = win32_timers[id].data; + delete_timer(win32_timers[id]); + if (cb) { + (*cb)(data); + } + } + } + return 0; + + default: + break; + } + + return DefWindowProc(hwnd, msg, wParam, lParam); +} + +void Fl::add_timeout(double time, Fl_Timeout_Handler cb, void* data) +{ + repeat_timeout(time, cb, data); +} + +void Fl::repeat_timeout(double time, Fl_Timeout_Handler cb, void* data) +{ + int timer_id = -1; + for (int i = 0; i < win32_timer_used; ++i) { + if ( !win32_timers[i].handle ) { + timer_id = i; + break; + } + } + if (timer_id == -1) { + if (win32_timer_used == win32_timer_alloc) { + realloc_timers(); + } + timer_id = win32_timer_used++; + } + unsigned int elapsed = (unsigned int)(time * 1000); + + if ( !s_TimerWnd ) { + const char* timer_class = "FLTimer"; + WNDCLASSEX wc; + memset(&wc, 0, sizeof(wc)); + wc.cbSize = sizeof (wc); + wc.style = CS_CLASSDC; + wc.lpfnWndProc = (WNDPROC)s_TimerProc; + wc.hInstance = fl_display; + wc.lpszClassName = timer_class; + /*ATOM atom =*/ RegisterClassEx(&wc); + // create a zero size window to handle timer events + s_TimerWnd = CreateWindowEx(WS_EX_LEFT | WS_EX_TOOLWINDOW, + timer_class, "", + WS_POPUP, + 0, 0, 0, 0, + NULL, NULL, fl_display, NULL); + // just in case this OS won't let us create a 0x0 size window: + if (!s_TimerWnd) + s_TimerWnd = CreateWindowEx(WS_EX_LEFT | WS_EX_TOOLWINDOW, + timer_class, "", + WS_POPUP, + 0, 0, 1, 1, + NULL, NULL, fl_display, NULL); + ShowWindow(s_TimerWnd, SW_SHOWNOACTIVATE); + } + + win32_timers[timer_id].callback = cb; + win32_timers[timer_id].data = data; + + win32_timers[timer_id].handle = + SetTimer(s_TimerWnd, timer_id + 1, elapsed, NULL); +} + +int Fl::has_timeout(Fl_Timeout_Handler cb, void* data) +{ + for (int i = 0; i < win32_timer_used; ++i) { + Win32Timer& t = win32_timers[i]; + if (t.handle && t.callback == cb && t.data == data) { + return 1; + } + } + return 0; +} + +void Fl::remove_timeout(Fl_Timeout_Handler cb, void* data) +{ + int i; + for (i = 0; i < win32_timer_used; ++i) { + Win32Timer& t = win32_timers[i]; + if (t.handle && t.callback == cb && + (t.data == data || data == NULL)) { + delete_timer(t); + } + } +} + +/// END TIMERS +///////////////////////////////////////////////////////////////////////////// + + + +//////////////////////////////////////////////////////////////// + +HINSTANCE fl_display = GetModuleHandle(NULL); + +void Fl_Window::size_range_() { + size_range_set = 1; +} + +void Fl_X::set_minmax(LPMINMAXINFO minmax) +{ + int td, wd, hd, dummy_x, dummy_y; + + fake_X_wm(w, dummy_x, dummy_y, td, wd, hd); + wd *= 2; + hd *= 2; + hd += td; + + minmax->ptMinTrackSize.x = w->minw + wd; + minmax->ptMinTrackSize.y = w->minh + hd; + if (w->maxw) { + minmax->ptMaxTrackSize.x = w->maxw + wd; + minmax->ptMaxSize.x = w->maxw + wd; + } + if (w->maxh) { + minmax->ptMaxTrackSize.y = w->maxh + hd; + minmax->ptMaxSize.y = w->maxh + hd; + } +} + +//////////////////////////////////////////////////////////////// + +#include // need so FL_EXPORT fl_filename_name works + +// returns pointer to the filename, or null if name ends with '/' +const char *fl_filename_name(const char *name) { + const char *p,*q; + if (!name) return (0); + q = name; + if (q[0] && q[1]==':') q += 2; // skip leading drive letter + for (p = q; *p; p++) if (*p == '/' || *p == '\\') q = p+1; + return q; +} + +void Fl_Window::label(const char *name,const char *iname) { + Fl_Widget::label(name); + iconlabel_ = iname; + if (shown() && !parent()) { + if (!name) name = ""; + int l = strlen(name); +// WCHAR *lab = (WCHAR*) malloc((l + 1) * sizeof(short)); +// l = fl_utf2unicode((unsigned char*)name, l, (xchar*)lab); + unsigned wlen = fl_utf8toUtf16(name, l, NULL, 0); // Pass NULL to query length + wlen++; + unsigned short * lab = (unsigned short*)malloc(sizeof(unsigned short)*wlen); + wlen = fl_utf8toUtf16(name, l, lab, wlen); + lab[wlen] = 0; + SetWindowTextW(i->xid, (WCHAR *)lab); + free(lab); + } +} + +//////////////////////////////////////////////////////////////// +// Implement the virtual functions for the base Fl_Window class: + +// If the box is a filled rectangle, we can make the redisplay *look* +// faster by using X's background pixel erasing. We can make it +// actually *be* faster by drawing the frame only, this is done by +// setting fl_boxcheat, which is seen by code in fl_drawbox.cxx: +// For WIN32 it looks like all windows share a background color, so +// I use FL_GRAY for this and only do this cheat for windows that are +// that color. +// Actually it is totally disabled. +// Fl_Widget *fl_boxcheat; +//static inline int can_boxcheat(uchar b) {return (b==1 || (b&2) && b<=15);} + +void Fl_Window::show() { + image(Fl::scheme_bg_); + if (Fl::scheme_bg_) { + labeltype(FL_NORMAL_LABEL); + align(FL_ALIGN_CENTER | FL_ALIGN_INSIDE | FL_ALIGN_CLIP); + } else { + labeltype(FL_NO_LABEL); + } + Fl_Tooltip::exit(this); + if (!shown()) { + // if (can_boxcheat(box())) fl_background_pixel = fl_xpixel(color()); + Fl_X::make(this); + } else { + // Once again, we would lose the capture if we activated the window. + if (IsIconic(i->xid)) OpenIcon(i->xid); + if (!fl_capture) BringWindowToTop(i->xid); + //ShowWindow(i->xid,fl_capture?SW_SHOWNOACTIVATE:SW_RESTORE); + } +#ifdef USE_PRINT_BUTTON +void preparePrintFront(void); +preparePrintFront(); +#endif +} + +Fl_Window *Fl_Window::current_; +// the current context +HDC fl_gc = 0; +// the current window handle, initially set to -1 so we can correctly +// allocate fl_GetDC(0) +HWND fl_window = NULL; + +// Here we ensure only one GetDC is ever in place. +HDC fl_GetDC(HWND w) { + if (fl_gc) { + if (w == fl_window && fl_window != NULL) return fl_gc; + if (fl_window) fl_release_dc(fl_window, fl_gc); // ReleaseDC + } + fl_gc = GetDC(w); + fl_save_dc(w, fl_gc); + fl_window = w; + // calling GetDC seems to always reset these: (?) + SetTextAlign(fl_gc, TA_BASELINE|TA_LEFT); + SetBkMode(fl_gc, TRANSPARENT); + + return fl_gc; +} + +// make X drawing go into this window (called by subclass flush() impl.) +void Fl_Window::make_current() { + fl_GetDC(fl_xid(this)); + +#if USE_COLORMAP + // Windows maintains a hardware and software color palette; the + // SelectPalette() call updates the current soft->hard mapping + // for all drawing calls, so we must select it here before any + // code does any drawing... + + fl_select_palette(); +#endif // USE_COLORMAP + + current_ = this; + fl_clip_region(0); + + +} + +/* Make sure that all allocated fonts are released. This works only if + Fl::run() is allowed to exit by closing all windows. Calling 'exit(int)' + will not automatically free any fonts. */ +void fl_free_fonts(void) +{ +// remove the Fl_Font_Descriptor chains + int i; + Fl_Fontdesc * s; + Fl_Font_Descriptor * f; + Fl_Font_Descriptor * ff; + for (i=0; ifirst; f; f=ff) { + ff = f->next; + delete f; + s->first = ff; + } + } +} + + +/////////////////////////////////////////////////////////////////////// +// +// The following routines help fix a problem with the leaking of Windows +// Device Context (DC) objects. The 'proper' protocol is for a program to +// acquire a DC, save its state, do the modifications needed for drawing, +// perform the drawing, restore the initial state, and release the DC. In +// FLTK, the save and restore steps have previously been omitted and DCs are +// not properly released, leading to a great number of DC leaks. As some +// Windows "OSs" will hang when any process exceeds roughly 10,000 GDI objects, +// it is important to control GDI leaks, which are much more important than memory +// leaks. The following struct, global variable, and routines help implement +// the above protocol for those cases where the GetDC and RestoreDC are not in +// the same routine. For each GetDC, fl_save_dc is used to create an entry in +// a linked list that saves the window handle, the DC handle, and the initial +// state. When the DC is to be released, 'fl_release_dc' is called. It restores +// the initial state and releases the DC. When the program exits, 'fl_cleanup_dc_list' +// frees any remaining nodes in the list. + +struct Win_DC_List { // linked list + HWND window; // window handle + HDC dc; // device context handle + int saved_dc; // initial state of DC + Win_DC_List * next; // pointer to next item +}; + +static Win_DC_List * win_DC_list = 0; + +void fl_save_dc( HWND w, HDC dc) { + Win_DC_List * t; + t = new Win_DC_List; + t->window = w; + t->dc = dc; + t->saved_dc = SaveDC(dc); + if (win_DC_list) + t->next = win_DC_list; + else + t->next = NULL; + win_DC_list = t; +} + +void fl_release_dc(HWND w, HDC dc) { + Win_DC_List * t= win_DC_list; + Win_DC_List * prev = 0; + if (!t) + return; + do { + if (t->dc == dc) { + RestoreDC(dc, t->saved_dc); + ReleaseDC(w, dc); + if (!prev) { + win_DC_list = t->next; // delete first item + } else { + prev->next = t->next; // one in the middle + } + delete (t); + return; + } + prev = t; + t = t->next; + } while (t); +} + +void fl_cleanup_dc_list(void) { // clean up the list + Win_DC_List * t = win_DC_list; + if (!t)return; + do { + RestoreDC(t->dc, t->saved_dc); + ReleaseDC(t->window, t->dc); + win_DC_list = t->next; + delete (t); + t = win_DC_list; + } while(t); +} + +Fl_Region XRectangleRegion(int x, int y, int w, int h) { + if (Fl_Surface_Device::surface()->type() == Fl_Display_Device::device_type) return CreateRectRgn(x,y,x+w,y+h); + // because rotation may apply, the rectangle becomes a polygon in device coords + POINT pt[4] = { {x, y}, {x + w, y}, {x + w, y + h}, {x, y + h} }; + LPtoDP(fl_gc, pt, 4); + return CreatePolygonRgn(pt, 4, ALTERNATE); +} + +#ifdef USE_PRINT_BUTTON +// to test the Fl_Printer class creating a "Print front window" button in a separate window +// contains also preparePrintFront call above +#include +#include +void printFront(Fl_Widget *o, void *data) +{ + Fl_Printer printer; + o->window()->hide(); + Fl_Window *win = Fl::first_window(); + if(!win) return; + int w, h; + if( printer.start_job(1) ) { o->window()->show(); return; } + if( printer.start_page() ) { o->window()->show(); return; } + printer.printable_rect(&w,&h); + // scale the printer device so that the window fits on the page + float scale = 1; + if (win->w() > w || win->h() > h) { + scale = (float)w/win->w(); + if ((float)h/win->h() < scale) scale = (float)h/win->h(); + printer.scale(scale, scale); + } +// #define ROTATE 20.0 +#ifdef ROTATE + printer.scale(scale * 0.8, scale * 0.8); + printer.printable_rect(&w, &h); + printer.origin(w/2, h/2 ); + printer.rotate(ROTATE); + printer.print_widget( win, - win->w()/2, - win->h()/2 ); + //printer.print_window_part( win, 0,0, win->w(), win->h(), - win->w()/2, - win->h()/2 ); +#else + printer.print_widget( win ); + //printer.print_window_part( win, 0,0, win->w(), win->h() ); +#endif + printer.end_page(); + printer.end_job(); + o->window()->show(); +} + +void preparePrintFront(void) +{ + static BOOL first=TRUE; + if(!first) return; + first=FALSE; + static Fl_Window w(0,0,120,30); + static Fl_Button b(0,0,w.w(),w.h(), "Print front window"); + b.callback(printFront); + w.end(); + w.show(); +} +#endif // USE_PRINT_BUTTON + +#endif // FL_DOXYGEN + +// +// End of "$Id: Fl_win32.cxx 7814 2010-11-11 08:38:36Z AlbrechtS $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_x.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_x.cxx new file mode 100644 index 0000000..5328bcb --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Fl_x.cxx @@ -0,0 +1,1870 @@ +// +// "$Id: Fl_x.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// X specific code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifdef WIN32 +//# include "Fl_win32.cxx" +#elif defined(__APPLE__) +//# include "Fl_mac.cxx" +#elif !defined(FL_DOXYGEN) + +# define CONSOLIDATE_MOTION 1 +/**** Define this if your keyboard lacks a backspace key... ****/ +/* #define BACKSPACE_HACK 1 */ + +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include "flstring.h" +# include +# include +# include +# include +# include + +static Fl_Xlib_Graphics_Driver fl_xlib_driver; +static Fl_Display_Device fl_xlib_display(&fl_xlib_driver); +FL_EXPORT Fl_Display_Device *fl_display_device = (Fl_Display_Device*)&fl_xlib_display; // does not change +FL_EXPORT Fl_Graphics_Driver *fl_graphics_driver = (Fl_Graphics_Driver*)&fl_xlib_driver; // the current target device of graphics operations +FL_EXPORT Fl_Surface_Device *fl_surface = (Fl_Surface_Device*)fl_display_device; // the current target surface of graphics operations + +//////////////////////////////////////////////////////////////// +// interface to poll/select call: + +# if USE_POLL + +# include +static pollfd *pollfds = 0; + +# else +# if HAVE_SYS_SELECT_H +# include +# endif /* HAVE_SYS_SELECT_H */ + +// The following #define is only needed for HP-UX 9.x and earlier: +//#define select(a,b,c,d,e) select((a),(int *)(b),(int *)(c),(int *)(d),(e)) + +static fd_set fdsets[3]; +static int maxfd; +# define POLLIN 1 +# define POLLOUT 4 +# define POLLERR 8 + +# endif /* USE_POLL */ + +static int nfds = 0; +static int fd_array_size = 0; +struct FD { +# if !USE_POLL + int fd; + short events; +# endif + void (*cb)(int, void*); + void* arg; +}; + +static FD *fd = 0; + +void Fl::add_fd(int n, int events, void (*cb)(int, void*), void *v) { + remove_fd(n,events); + int i = nfds++; + if (i >= fd_array_size) { + FD *temp; + fd_array_size = 2*fd_array_size+1; + + if (!fd) temp = (FD*)malloc(fd_array_size*sizeof(FD)); + else temp = (FD*)realloc(fd, fd_array_size*sizeof(FD)); + + if (!temp) return; + fd = temp; + +# if USE_POLL + pollfd *tpoll; + + if (!pollfds) tpoll = (pollfd*)malloc(fd_array_size*sizeof(pollfd)); + else tpoll = (pollfd*)realloc(pollfds, fd_array_size*sizeof(pollfd)); + + if (!tpoll) return; + pollfds = tpoll; +# endif + } + fd[i].cb = cb; + fd[i].arg = v; +# if USE_POLL + pollfds[i].fd = n; + pollfds[i].events = events; +# else + fd[i].fd = n; + fd[i].events = events; + if (events & POLLIN) FD_SET(n, &fdsets[0]); + if (events & POLLOUT) FD_SET(n, &fdsets[1]); + if (events & POLLERR) FD_SET(n, &fdsets[2]); + if (n > maxfd) maxfd = n; +# endif +} + +void Fl::add_fd(int n, void (*cb)(int, void*), void* v) { + Fl::add_fd(n, POLLIN, cb, v); +} + +void Fl::remove_fd(int n, int events) { + int i,j; +# if !USE_POLL + maxfd = -1; // recalculate maxfd on the fly +# endif + for (i=j=0; i maxfd) maxfd = fd[i].fd; +# endif + // move it down in the array if necessary: + if (j0 if any callbacks were done. +int fl_wait(double time_to_wait) { + + // OpenGL and other broken libraries call XEventsQueued + // unnecessarily and thus cause the file descriptor to not be ready, + // so we must check for already-read events: + if (fl_display && XQLength(fl_display)) {do_queued_events(); return 1;} + +# if !USE_POLL + fd_set fdt[3]; + fdt[0] = fdsets[0]; + fdt[1] = fdsets[1]; + fdt[2] = fdsets[2]; +# endif + int n; + + fl_unlock_function(); + + if (time_to_wait < 2147483.648) { +# if USE_POLL + n = ::poll(pollfds, nfds, int(time_to_wait*1000 + .5)); +# else + timeval t; + t.tv_sec = int(time_to_wait); + t.tv_usec = int(1000000 * (time_to_wait-t.tv_sec)); + n = ::select(maxfd+1,&fdt[0],&fdt[1],&fdt[2],&t); +# endif + } else { +# if USE_POLL + n = ::poll(pollfds, nfds, -1); +# else + n = ::select(maxfd+1,&fdt[0],&fdt[1],&fdt[2],0); +# endif + } + + fl_lock_function(); + + if (n > 0) { + for (int i=0; irequest_code); + XGetErrorDatabaseText(d,"",buf1,buf1,buf2,128); + XGetErrorText(d, e->error_code, buf1, 128); + Fl::warning("%s: %s 0x%lx", buf2, buf1, e->resourceid); + return 0; + } +} + +extern char *fl_get_font_xfld(int fnum, int size); + +void fl_new_ic() +{ + XVaNestedList preedit_attr = NULL; + XVaNestedList status_attr = NULL; + static XFontSet fs = NULL; + char *fnt; + bool must_free_fnt = true; + char **missing_list; + int missing_count; + char *def_string; + static XRectangle spot; + int predit = 0; + int sarea = 0; + XIMStyles* xim_styles = NULL; + +#if USE_XFT + +#if defined(__GNUC__) +// FIXME: warning XFT support here +#endif /*__GNUC__*/ + + if (!fs) { + fnt = NULL;//fl_get_font_xfld(0, 14); + if (!fnt) {fnt = (char*)"-misc-fixed-*";must_free_fnt=false;} + fs = XCreateFontSet(fl_display, fnt, &missing_list, + &missing_count, &def_string); + } +#else + if (!fs) { + fnt = fl_get_font_xfld(0, 14); + if (!fnt) {fnt = (char*)"-misc-fixed-*";must_free_fnt=false;} + fs = XCreateFontSet(fl_display, fnt, &missing_list, + &missing_count, &def_string); + } +#endif + preedit_attr = XVaCreateNestedList(0, + XNSpotLocation, &spot, + XNFontSet, fs, NULL); + status_attr = XVaCreateNestedList(0, + XNAreaNeeded, &status_area, + XNFontSet, fs, NULL); + + if (!XGetIMValues(fl_xim_im, XNQueryInputStyle, + &xim_styles, NULL, NULL)) { + int i; + XIMStyle *style; + for (i = 0, style = xim_styles->supported_styles; + i < xim_styles->count_styles; i++, style++) { + if (*style == (XIMPreeditPosition | XIMStatusArea)) { + sarea = 1; + predit = 1; + } else if (*style == (XIMPreeditPosition | XIMStatusNothing)) { + predit = 1; + } + } + } + XFree(xim_styles); + + if (sarea) { + fl_xim_ic = XCreateIC(fl_xim_im, + XNInputStyle, (XIMPreeditPosition | XIMStatusArea), + XNPreeditAttributes, preedit_attr, + XNStatusAttributes, status_attr, + NULL); + } + + if (!fl_xim_ic && predit) { + fl_xim_ic = XCreateIC(fl_xim_im, + XNInputStyle, (XIMPreeditPosition | XIMStatusNothing), + XNPreeditAttributes, preedit_attr, + NULL); + } + XFree(preedit_attr); + XFree(status_attr); + if (!fl_xim_ic) { + fl_is_over_the_spot = 0; + fl_xim_ic = XCreateIC(fl_xim_im, + XNInputStyle, (XIMPreeditNothing | XIMStatusNothing), + NULL); + } else { + fl_is_over_the_spot = 1; + XVaNestedList status_attr = NULL; + status_attr = XVaCreateNestedList(0, XNAreaNeeded, &status_area, NULL); + + XGetICValues(fl_xim_ic, XNStatusAttributes, status_attr, NULL); + XFree(status_attr); + } +} + + +static XRectangle spot; +static int spotf = -1; +static int spots = -1; + +void fl_reset_spot(void) +{ + spot.x = -1; + spot.y = -1; + //if (fl_xim_ic) XUnsetICFocus(fl_xim_ic); +} + +void fl_set_spot(int font, int size, int X, int Y, int W, int H, Fl_Window *win) +{ + int change = 0; + XVaNestedList preedit_attr; + static XFontSet fs = NULL; + char **missing_list; + int missing_count; + char *def_string; + char *fnt = NULL; + bool must_free_fnt =true; + + static XIC ic = NULL; + + if (!fl_xim_ic || !fl_is_over_the_spot) return; + //XSetICFocus(fl_xim_ic); + if (X != spot.x || Y != spot.y) { + spot.x = X; + spot.y = Y; + spot.height = H; + spot.width = W; + change = 1; + } + if (font != spotf || size != spots) { + spotf = font; + spots = size; + change = 1; + if (fs) { + XFreeFontSet(fl_display, fs); + } +#if USE_XFT + +#if defined(__GNUC__) +// FIXME: warning XFT support here +#endif /*__GNUC__*/ + + fnt = NULL; // fl_get_font_xfld(font, size); + if (!fnt) {fnt = (char*)"-misc-fixed-*";must_free_fnt=false;} + fs = XCreateFontSet(fl_display, fnt, &missing_list, + &missing_count, &def_string); +#else + fnt = fl_get_font_xfld(font, size); + if (!fnt) {fnt = (char*)"-misc-fixed-*";must_free_fnt=false;} + fs = XCreateFontSet(fl_display, fnt, &missing_list, + &missing_count, &def_string); +#endif + } + if (fl_xim_ic != ic) { + ic = fl_xim_ic; + change = 1; + } + + if (fnt && must_free_fnt) free(fnt); + if (!change) return; + + + preedit_attr = XVaCreateNestedList(0, + XNSpotLocation, &spot, + XNFontSet, fs, NULL); + XSetICValues(fl_xim_ic, XNPreeditAttributes, preedit_attr, NULL); + XFree(preedit_attr); +} + +void fl_set_status(int x, int y, int w, int h) +{ + XVaNestedList status_attr; + status_area.x = x; + status_area.y = y; + status_area.width = w; + status_area.height = h; + if (!fl_xim_ic) return; + status_attr = XVaCreateNestedList(0, XNArea, &status_area, NULL); + + XSetICValues(fl_xim_ic, XNStatusAttributes, status_attr, NULL); + XFree(status_attr); +} + +void fl_init_xim() +{ + //XIMStyle *style; + XIMStyles *xim_styles; + if (!fl_display) return; + if (fl_xim_im) return; + + fl_xim_im = XOpenIM(fl_display, NULL, NULL, NULL); + xim_styles = NULL; + fl_xim_ic = NULL; + + if (fl_xim_im) { + XGetIMValues (fl_xim_im, XNQueryInputStyle, + &xim_styles, NULL, NULL); + } else { + Fl::warning("XOpenIM() failed\n"); + return; + } + + if (xim_styles && xim_styles->count_styles) { + fl_new_ic(); + } else { + Fl::warning("No XIM style found\n"); + XCloseIM(fl_xim_im); + fl_xim_im = NULL; + return; + } + if (!fl_xim_ic) { + Fl::warning("XCreateIC() failed\n"); + XCloseIM(fl_xim_im); + XFree(xim_styles); + fl_xim_im = NULL; + } +} + + +void fl_open_display() { + if (fl_display) return; + + setlocale(LC_CTYPE, ""); + XSetLocaleModifiers(""); + + XSetIOErrorHandler(io_error_handler); + XSetErrorHandler(xerror_handler); + + Display *d = XOpenDisplay(0); + if (!d) Fl::fatal("Can't open display: %s",XDisplayName(0)); + + fl_open_display(d); +} + +void fl_open_display(Display* d) { + fl_display = d; + + WM_DELETE_WINDOW = XInternAtom(d, "WM_DELETE_WINDOW", 0); + WM_PROTOCOLS = XInternAtom(d, "WM_PROTOCOLS", 0); + fl_MOTIF_WM_HINTS = XInternAtom(d, "_MOTIF_WM_HINTS", 0); + TARGETS = XInternAtom(d, "TARGETS", 0); + CLIPBOARD = XInternAtom(d, "CLIPBOARD", 0); + fl_XdndAware = XInternAtom(d, "XdndAware", 0); + fl_XdndSelection = XInternAtom(d, "XdndSelection", 0); + fl_XdndEnter = XInternAtom(d, "XdndEnter", 0); + fl_XdndTypeList = XInternAtom(d, "XdndTypeList", 0); + fl_XdndPosition = XInternAtom(d, "XdndPosition", 0); + fl_XdndLeave = XInternAtom(d, "XdndLeave", 0); + fl_XdndDrop = XInternAtom(d, "XdndDrop", 0); + fl_XdndStatus = XInternAtom(d, "XdndStatus", 0); + fl_XdndActionCopy = XInternAtom(d, "XdndActionCopy", 0); + fl_XdndFinished = XInternAtom(d, "XdndFinished", 0); + //fl_XdndProxy = XInternAtom(d, "XdndProxy", 0); + fl_XdndEnter = XInternAtom(d, "XdndEnter", 0); + fl_XdndURIList = XInternAtom(d, "text/uri-list", 0); + fl_XaUtf8String = XInternAtom(d, "UTF8_STRING", 0); + fl_XaTextUriList = XInternAtom(d, "text/uri-list", 0); + + if (sizeof(Atom) < 4) + atom_bits = sizeof(Atom) * 8; + + Fl::add_fd(ConnectionNumber(d), POLLIN, fd_callback); + + fl_screen = DefaultScreen(d); + + fl_message_window = + XCreateSimpleWindow(d, RootWindow(d,fl_screen), 0,0,1,1,0, 0, 0); + +// construct an XVisualInfo that matches the default Visual: + XVisualInfo templt; int num; + templt.visualid = XVisualIDFromVisual(DefaultVisual(d, fl_screen)); + fl_visual = XGetVisualInfo(d, VisualIDMask, &templt, &num); + fl_colormap = DefaultColormap(d, fl_screen); + fl_init_xim(); + +#if !USE_COLORMAP + Fl::visual(FL_RGB); +#endif +} + +void fl_close_display() { + Fl::remove_fd(ConnectionNumber(fl_display)); + XCloseDisplay(fl_display); +} + +static int fl_workarea_xywh[4] = { -1, -1, -1, -1 }; + +static void fl_init_workarea() { + fl_open_display(); + + Atom _NET_WORKAREA = XInternAtom(fl_display, "_NET_WORKAREA", 0); + Atom actual; + unsigned long count, remaining; + int format; + unsigned *xywh; + + if (XGetWindowProperty(fl_display, RootWindow(fl_display, fl_screen), + _NET_WORKAREA, 0, 4 * sizeof(unsigned), False, + XA_CARDINAL, &actual, &format, &count, &remaining, + (unsigned char **)&xywh) || !xywh || !xywh[2] || + !xywh[3]) + { + fl_workarea_xywh[0] = 0; + fl_workarea_xywh[1] = 0; + fl_workarea_xywh[2] = DisplayWidth(fl_display, fl_screen); + fl_workarea_xywh[3] = DisplayHeight(fl_display, fl_screen); + } + else + { + fl_workarea_xywh[0] = (int)xywh[0]; + fl_workarea_xywh[1] = (int)xywh[1]; + fl_workarea_xywh[2] = (int)xywh[2]; + fl_workarea_xywh[3] = (int)xywh[3]; + XFree(xywh); + } +} + +int Fl::x() { + if (fl_workarea_xywh[0] < 0) fl_init_workarea(); + return fl_workarea_xywh[0]; +} + +int Fl::y() { + if (fl_workarea_xywh[0] < 0) fl_init_workarea(); + return fl_workarea_xywh[1]; +} + +int Fl::w() { + if (fl_workarea_xywh[0] < 0) fl_init_workarea(); + return fl_workarea_xywh[2]; +} + +int Fl::h() { + if (fl_workarea_xywh[0] < 0) fl_init_workarea(); + return fl_workarea_xywh[3]; +} + +void Fl::get_mouse(int &xx, int &yy) { + fl_open_display(); + Window root = RootWindow(fl_display, fl_screen); + Window c; int mx,my,cx,cy; unsigned int mask; + XQueryPointer(fl_display,root,&root,&c,&mx,&my,&cx,&cy,&mask); + xx = mx; + yy = my; +} + +//////////////////////////////////////////////////////////////// +// Code used for paste and DnD into the program: + +Fl_Widget *fl_selection_requestor; +char *fl_selection_buffer[2]; +int fl_selection_length[2]; +int fl_selection_buffer_length[2]; +char fl_i_own_selection[2] = {0,0}; + +// Call this when a "paste" operation happens: +void Fl::paste(Fl_Widget &receiver, int clipboard) { + if (fl_i_own_selection[clipboard]) { + // We already have it, do it quickly without window server. + // Notice that the text is clobbered if set_selection is + // called in response to FL_PASTE! + Fl::e_text = fl_selection_buffer[clipboard]; + Fl::e_length = fl_selection_length[clipboard]; + if (!Fl::e_text) Fl::e_text = (char *)""; + receiver.handle(FL_PASTE); + return; + } + // otherwise get the window server to return it: + fl_selection_requestor = &receiver; + Atom property = clipboard ? CLIPBOARD : XA_PRIMARY; + XConvertSelection(fl_display, property, fl_XaUtf8String, property, + fl_xid(Fl::first_window()), fl_event_time); +} + +Window fl_dnd_source_window; +Atom *fl_dnd_source_types; // null-terminated list of data types being supplied +Atom fl_dnd_type; +Atom fl_dnd_source_action; +Atom fl_dnd_action; + +void fl_sendClientMessage(Window window, Atom message, + unsigned long d0, + unsigned long d1=0, + unsigned long d2=0, + unsigned long d3=0, + unsigned long d4=0) +{ + XEvent e; + e.xany.type = ClientMessage; + e.xany.window = window; + e.xclient.message_type = message; + e.xclient.format = 32; + e.xclient.data.l[0] = (long)d0; + e.xclient.data.l[1] = (long)d1; + e.xclient.data.l[2] = (long)d2; + e.xclient.data.l[3] = (long)d3; + e.xclient.data.l[4] = (long)d4; + XSendEvent(fl_display, window, 0, 0, &e); +} + +//////////////////////////////////////////////////////////////// +// Code for copying to clipboard and DnD out of the program: + +void Fl::copy(const char *stuff, int len, int clipboard) { + if (!stuff || len<0) return; + if (len+1 > fl_selection_buffer_length[clipboard]) { + delete[] fl_selection_buffer[clipboard]; + fl_selection_buffer[clipboard] = new char[len+100]; + fl_selection_buffer_length[clipboard] = len+100; + } + memcpy(fl_selection_buffer[clipboard], stuff, len); + fl_selection_buffer[clipboard][len] = 0; // needed for direct paste + fl_selection_length[clipboard] = len; + fl_i_own_selection[clipboard] = 1; + Atom property = clipboard ? CLIPBOARD : XA_PRIMARY; + XSetSelectionOwner(fl_display, property, fl_message_window, fl_event_time); +} + +//////////////////////////////////////////////////////////////// + +const XEvent* fl_xevent; // the current x event +ulong fl_event_time; // the last timestamp from an x event + +char fl_key_vector[32]; // used by Fl::get_key() + +// Record event mouse position and state from an XEvent: + +static int px, py; +static ulong ptime; + +static void set_event_xy() { +# if CONSOLIDATE_MOTION + send_motion = 0; +# endif + Fl::e_x_root = fl_xevent->xbutton.x_root; + Fl::e_x = fl_xevent->xbutton.x; + Fl::e_y_root = fl_xevent->xbutton.y_root; + Fl::e_y = fl_xevent->xbutton.y; + Fl::e_state = fl_xevent->xbutton.state << 16; + fl_event_time = fl_xevent->xbutton.time; +# ifdef __sgi + // get the meta key off PC keyboards: + if (fl_key_vector[18]&0x18) Fl::e_state |= FL_META; +# endif + // turn off is_click if enough time or mouse movement has passed: + if (abs(Fl::e_x_root-px)+abs(Fl::e_y_root-py) > 3 || + fl_event_time >= ptime+1000) + Fl::e_is_click = 0; +} + +// if this is same event as last && is_click, increment click count: +static inline void checkdouble() { + if (Fl::e_is_click == Fl::e_keysym) + Fl::e_clicks++; + else { + Fl::e_clicks = 0; + Fl::e_is_click = Fl::e_keysym; + } + px = Fl::e_x_root; + py = Fl::e_y_root; + ptime = fl_event_time; +} + +static Fl_Window* resize_bug_fix; + +//////////////////////////////////////////////////////////////// + +static char unknown[] = ""; +const int unknown_len = 10; + +extern "C" { + +static int xerror = 0; + +static int ignoreXEvents(Display *display, XErrorEvent *event) { + xerror = 1; + return 0; +} + +static XErrorHandler catchXExceptions() { + xerror = 0; + return ignoreXEvents; +} + +static int wasXExceptionRaised() { + return xerror; +} + +} + + +int fl_handle(const XEvent& thisevent) +{ + XEvent xevent = thisevent; + fl_xevent = &thisevent; + Window xid = xevent.xany.window; + static Window xim_win = 0; + + if (fl_xim_ic && xevent.type == DestroyNotify && + xid != xim_win && !fl_find(xid)) + { + XIM xim_im; + xim_im = XOpenIM(fl_display, NULL, NULL, NULL); + if (!xim_im) { + /* XIM server has crashed */ + XSetLocaleModifiers("@im="); + fl_xim_im = NULL; + fl_init_xim(); + } else { + XCloseIM(xim_im); // see STR 2185 for comment + } + return 0; + } + + if (fl_xim_ic && (xevent.type == FocusIn)) + { +#define POOR_XIM +#ifdef POOR_XIM + if (xim_win != xid) + { + xim_win = xid; + XDestroyIC(fl_xim_ic); + fl_xim_ic = NULL; + fl_new_ic(); + XSetICValues(fl_xim_ic, + XNFocusWindow, xevent.xclient.window, + XNClientWindow, xid, + NULL); + } + fl_set_spot(spotf, spots, spot.x, spot.y, spot.width, spot.height); +#else + if (Fl::first_window() && Fl::first_window()->modal()) { + Window x = fl_xid(Fl::first_window()); + if (x != xim_win) { + xim_win = x; + XSetICValues(fl_xim_ic, + XNFocusWindow, xim_win, + XNClientWindow, xim_win, + NULL); + fl_set_spot(spotf, spots, spot.x, spot.y, spot.width, spot.height); + } + } else if (xim_win != xid && xid) { + xim_win = xid; + XSetICValues(fl_xim_ic, + XNFocusWindow, xevent.xclient.window, + XNClientWindow, xid, + //XNFocusWindow, xim_win, + //XNClientWindow, xim_win, + NULL); + fl_set_spot(spotf, spots, spot.x, spot.y, spot.width, spot.height); + } +#endif + } + + if ( XFilterEvent((XEvent *)&xevent, 0) ) + return(1); + + switch (xevent.type) { + + case KeymapNotify: + memcpy(fl_key_vector, xevent.xkeymap.key_vector, 32); + return 0; + + case MappingNotify: + XRefreshKeyboardMapping((XMappingEvent*)&xevent.xmapping); + return 0; + + case SelectionNotify: { + if (!fl_selection_requestor) return 0; + static unsigned char* buffer = 0; + if (buffer) {XFree(buffer); buffer = 0;} + long bytesread = 0; + if (fl_xevent->xselection.property) for (;;) { + // The Xdnd code pastes 64K chunks together, possibly to avoid + // bugs in X servers, or maybe to avoid an extra round-trip to + // get the property length. I copy this here: + Atom actual; int format; unsigned long count, remaining; + unsigned char* portion; + if (XGetWindowProperty(fl_display, + fl_xevent->xselection.requestor, + fl_xevent->xselection.property, + bytesread/4, 65536, 1, 0, + &actual, &format, &count, &remaining, + &portion)) break; // quit on error + if (bytesread) { // append to the accumulated buffer + buffer = (unsigned char*)realloc(buffer, bytesread+count*format/8+remaining); + memcpy(buffer+bytesread, portion, count*format/8); + XFree(portion); + } else { // Use the first section without moving the memory: + buffer = portion; + } + bytesread += count*format/8; + buffer[bytesread] = 0; + if (!remaining) break; + } + Fl::e_text = buffer ? (char*)buffer : (char *)""; + Fl::e_length = bytesread; + int old_event = Fl::e_number; + fl_selection_requestor->handle(Fl::e_number = FL_PASTE); + Fl::e_number = old_event; + // Detect if this paste is due to Xdnd by the property name (I use + // XA_SECONDARY for that) and send an XdndFinished message. It is not + // clear if this has to be delayed until now or if it can be done + // immediatly after calling XConvertSelection. + if (fl_xevent->xselection.property == XA_SECONDARY && + fl_dnd_source_window) { + fl_sendClientMessage(fl_dnd_source_window, fl_XdndFinished, + fl_xevent->xselection.requestor); + fl_dnd_source_window = 0; // don't send a second time + } + return 1;} + + case SelectionClear: { + int clipboard = fl_xevent->xselectionclear.selection == CLIPBOARD; + fl_i_own_selection[clipboard] = 0; + return 1;} + + case SelectionRequest: { + XSelectionEvent e; + e.type = SelectionNotify; + e.requestor = fl_xevent->xselectionrequest.requestor; + e.selection = fl_xevent->xselectionrequest.selection; + int clipboard = e.selection == CLIPBOARD; + e.target = fl_xevent->xselectionrequest.target; + e.time = fl_xevent->xselectionrequest.time; + e.property = fl_xevent->xselectionrequest.property; + if (e.target == TARGETS) { + Atom a = fl_XaUtf8String; //XA_STRING; + XChangeProperty(fl_display, e.requestor, e.property, + XA_ATOM, atom_bits, 0, (unsigned char*)&a, 1); + } else if (/*e.target == XA_STRING &&*/ fl_selection_length[clipboard]) { + XChangeProperty(fl_display, e.requestor, e.property, + e.target, 8, 0, + (unsigned char *)fl_selection_buffer[clipboard], + fl_selection_length[clipboard]); + } else { +// char* x = XGetAtomName(fl_display,e.target); +// fprintf(stderr,"selection request of %s\n",x); +// XFree(x); + e.property = 0; + } + XSendEvent(fl_display, e.requestor, 0, 0, (XEvent *)&e);} + return 1; + + // events where interesting window id is in a different place: + case CirculateNotify: + case CirculateRequest: + case ConfigureNotify: + case ConfigureRequest: + case CreateNotify: + case DestroyNotify: + case GravityNotify: + case MapNotify: + case MapRequest: + case ReparentNotify: + case UnmapNotify: + xid = xevent.xmaprequest.window; + break; + } + + int event = 0; + Fl_Window* window = fl_find(xid); + + if (window) switch (xevent.type) { + + case ClientMessage: { + Atom message = fl_xevent->xclient.message_type; + const long* data = fl_xevent->xclient.data.l; + if ((Atom)(data[0]) == WM_DELETE_WINDOW) { + event = FL_CLOSE; + } else if (message == fl_XdndEnter) { + fl_xmousewin = window; + in_a_window = true; + fl_dnd_source_window = data[0]; + // version number is data[1]>>24 +// printf("XdndEnter, version %ld\n", data[1] >> 24); + if (data[1]&1) { + // get list of data types: + Atom actual; int format; unsigned long count, remaining; + unsigned char *buffer = 0; + XGetWindowProperty(fl_display, fl_dnd_source_window, fl_XdndTypeList, + 0, 0x8000000L, False, XA_ATOM, &actual, &format, + &count, &remaining, &buffer); + if (actual != XA_ATOM || format != 32 || count<4 || !buffer) + goto FAILED; + delete [] fl_dnd_source_types; + fl_dnd_source_types = new Atom[count+1]; + for (unsigned i = 0; i < count; i++) { + fl_dnd_source_types[i] = ((Atom*)buffer)[i]; + } + fl_dnd_source_types[count] = 0; + } else { + FAILED: + // less than four data types, or if the above messes up: + if (!fl_dnd_source_types) fl_dnd_source_types = new Atom[4]; + fl_dnd_source_types[0] = data[2]; + fl_dnd_source_types[1] = data[3]; + fl_dnd_source_types[2] = data[4]; + fl_dnd_source_types[3] = 0; + } + + // Loop through the source types and pick the first text type... + int i; + + for (i = 0; fl_dnd_source_types[i]; i ++) + { +// printf("fl_dnd_source_types[%d] = %ld (%s)\n", i, +// fl_dnd_source_types[i], +// XGetAtomName(fl_display, fl_dnd_source_types[i])); + + if (!strncmp(XGetAtomName(fl_display, fl_dnd_source_types[i]), + "text/", 5)) + break; + } + + if (fl_dnd_source_types[i]) + fl_dnd_type = fl_dnd_source_types[i]; + else + fl_dnd_type = fl_dnd_source_types[0]; + + event = FL_DND_ENTER; + Fl::e_text = unknown; + Fl::e_length = unknown_len; + break; + + } else if (message == fl_XdndPosition) { + fl_xmousewin = window; + in_a_window = true; + fl_dnd_source_window = data[0]; + Fl::e_x_root = data[2]>>16; + Fl::e_y_root = data[2]&0xFFFF; + if (window) { + Fl::e_x = Fl::e_x_root-window->x(); + Fl::e_y = Fl::e_y_root-window->y(); + } + fl_event_time = data[3]; + fl_dnd_source_action = data[4]; + fl_dnd_action = fl_XdndActionCopy; + Fl::e_text = unknown; + Fl::e_length = unknown_len; + int accept = Fl::handle(FL_DND_DRAG, window); + fl_sendClientMessage(data[0], fl_XdndStatus, + fl_xevent->xclient.window, + accept ? 1 : 0, + 0, // used for xy rectangle to not send position inside + 0, // used for width+height of rectangle + accept ? fl_dnd_action : None); + return 1; + + } else if (message == fl_XdndLeave) { + fl_dnd_source_window = 0; // don't send a finished message to it + event = FL_DND_LEAVE; + Fl::e_text = unknown; + Fl::e_length = unknown_len; + break; + + } else if (message == fl_XdndDrop) { + fl_xmousewin = window; + in_a_window = true; + fl_dnd_source_window = data[0]; + fl_event_time = data[2]; + Window to_window = fl_xevent->xclient.window; + Fl::e_text = unknown; + Fl::e_length = unknown_len; + if (Fl::handle(FL_DND_RELEASE, window)) { + fl_selection_requestor = Fl::belowmouse(); + XConvertSelection(fl_display, fl_XdndSelection, + fl_dnd_type, XA_SECONDARY, + to_window, fl_event_time); + } else { + // Send the finished message if I refuse the drop. + // It is not clear whether I can just send finished always, + // or if I have to wait for the SelectionNotify event as the + // code is currently doing. + fl_sendClientMessage(fl_dnd_source_window, fl_XdndFinished, to_window); + fl_dnd_source_window = 0; + } + return 1; + + } + break;} + + case UnmapNotify: + event = FL_HIDE; + break; + + case Expose: + Fl_X::i(window)->wait_for_expose = 0; +# if 0 + // try to keep windows on top even if WM_TRANSIENT_FOR does not work: + // opaque move/resize window managers do not like this, so I disabled it. + if (Fl::first_window()->non_modal() && window != Fl::first_window()) + Fl::first_window()->show(); +# endif + + case GraphicsExpose: + window->damage(FL_DAMAGE_EXPOSE, xevent.xexpose.x, xevent.xexpose.y, + xevent.xexpose.width, xevent.xexpose.height); + return 1; + + case FocusIn: + if (fl_xim_ic) XSetICFocus(fl_xim_ic); + event = FL_FOCUS; + break; + + case FocusOut: + if (fl_xim_ic) XUnsetICFocus(fl_xim_ic); + event = FL_UNFOCUS; + break; + + case KeyPress: + case KeyRelease: { + KEYPRESS: + int keycode = xevent.xkey.keycode; + fl_key_vector[keycode/8] |= (1 << (keycode%8)); + static char *buffer = NULL; + static int buffer_len = 0; + int len; + KeySym keysym; + if (buffer_len == 0) { + buffer_len = 4096; + buffer = (char*) malloc(buffer_len); + } + if (xevent.type == KeyPress) { + event = FL_KEYDOWN; + int len = 0; + + if (fl_xim_ic) { + Status status; + len = XUtf8LookupString(fl_xim_ic, (XKeyPressedEvent *)&xevent.xkey, + buffer, buffer_len, &keysym, &status); + + while (status == XBufferOverflow && buffer_len < 50000) { + buffer_len = buffer_len * 5 + 1; + buffer = (char*)realloc(buffer, buffer_len); + len = XUtf8LookupString(fl_xim_ic, (XKeyPressedEvent *)&xevent.xkey, + buffer, buffer_len, &keysym, &status); + } + keysym = XKeycodeToKeysym(fl_display, keycode, 0); + } else { + //static XComposeStatus compose; + len = XLookupString((XKeyEvent*)&(xevent.xkey), + buffer, buffer_len, &keysym, 0/*&compose*/); + if (keysym && keysym < 0x400) { // a character in latin-1,2,3,4 sets + // force it to type a character (not sure if this ever is needed): + // if (!len) {buffer[0] = char(keysym); len = 1;} + len = fl_utf8encode(XKeysymToUcs(keysym), buffer); + if (len < 1) len = 1; + // ignore all effects of shift on the keysyms, which makes it a lot + // easier to program shortcuts and is Windoze-compatable: + keysym = XKeycodeToKeysym(fl_display, keycode, 0); + } + } + // MRS: Can't use Fl::event_state(FL_CTRL) since the state is not + // set until set_event_xy() is called later... + if ((xevent.xkey.state & ControlMask) && keysym == '-') buffer[0] = 0x1f; // ^_ + buffer[len] = 0; + Fl::e_text = buffer; + Fl::e_length = len; + } else { + // Stupid X sends fake key-up events when a repeating key is held + // down, probably due to some back compatibility problem. Fortunately + // we can detect this because the repeating KeyPress event is in + // the queue, get it and execute it instead: + + // Bool XkbSetDetectableAutorepeat ( display, detectable, supported_rtrn ) + // Display * display ; + // Bool detectable ; + // Bool * supported_rtrn ; + // ...would be the easy way to corrct this isuue. Unfortunatly, this call is also + // broken on many Unix distros including Ubuntu and Solaris (as of Dec 2009) + + // Bogus KeyUp events are generated by repeated KeyDown events. One + // neccessary condition is an identical key event pending right after + // the bogus KeyUp. + // The new code introduced Dec 2009 differs in that it only check the very + // next event in the queue, not the entire queue of events. + // This function wrongly detects a repeat key if a software keyboard + // sends a burst of events containing two consecutive equal keys. However, + // in every non-gaming situation, this is no problem because both KeyPress + // events will cause the expected behavior. + XEvent peekevent; + if (XPending(fl_display)) { + XPeekEvent(fl_display, &peekevent); + if ( (peekevent.type == KeyPress) // must be a KeyPress event + && (peekevent.xkey.keycode == xevent.xkey.keycode) // must be the same key + && (peekevent.xkey.time == xevent.xkey.time) // must be sent at the exact same time + ) { + XNextEvent(fl_display, &xevent); + goto KEYPRESS; + } + } + + event = FL_KEYUP; + fl_key_vector[keycode/8] &= ~(1 << (keycode%8)); + // keyup events just get the unshifted keysym: + keysym = XKeycodeToKeysym(fl_display, keycode, 0); + } +# ifdef __sgi + // You can plug a microsoft keyboard into an sgi but the extra shift + // keys are not translated. Make them translate like XFree86 does: + if (!keysym) switch(keycode) { + case 147: keysym = FL_Meta_L; break; + case 148: keysym = FL_Meta_R; break; + case 149: keysym = FL_Menu; break; + } +# endif +# if BACKSPACE_HACK + // Attempt to fix keyboards that send "delete" for the key in the + // upper-right corner of the main keyboard. But it appears that + // very few of these remain? + static int got_backspace = 0; + if (!got_backspace) { + if (keysym == FL_Delete) keysym = FL_BackSpace; + else if (keysym == FL_BackSpace) got_backspace = 1; + } +# endif + // We have to get rid of the XK_KP_function keys, because they are + // not produced on Windoze and thus case statements tend not to check + // for them. There are 15 of these in the range 0xff91 ... 0xff9f + if (keysym >= 0xff91 && keysym <= 0xff9f) { + // Map keypad keysym to character or keysym depending on + // numlock state... + unsigned long keysym1 = XKeycodeToKeysym(fl_display, keycode, 1); + if (keysym1 <= 0x7f || (keysym1 > 0xff9f && keysym1 <= FL_KP_Last)) + Fl::e_original_keysym = (int)(keysym1 | FL_KP); + if ((xevent.xkey.state & Mod2Mask) && + (keysym1 <= 0x7f || (keysym1 > 0xff9f && keysym1 <= FL_KP_Last))) { + // Store ASCII numeric keypad value... + keysym = keysym1 | FL_KP; + buffer[0] = char(keysym1) & 0x7F; + len = 1; + } else { + // Map keypad to special key... + static const unsigned short table[15] = { + FL_F+1, FL_F+2, FL_F+3, FL_F+4, + FL_Home, FL_Left, FL_Up, FL_Right, + FL_Down, FL_Page_Up, FL_Page_Down, FL_End, + 0xff0b/*XK_Clear*/, FL_Insert, FL_Delete}; + keysym = table[keysym-0xff91]; + } + } else { + // Store this so we can later know if the KP was used + Fl::e_original_keysym = (int)keysym; + } + Fl::e_keysym = int(keysym); + + // replace XK_ISO_Left_Tab (Shift-TAB) with FL_Tab (modifier flags are set correctly by X11) + if (Fl::e_keysym == 0xfe20) Fl::e_keysym = FL_Tab; + + set_event_xy(); + Fl::e_is_click = 0; + break;} + + case ButtonPress: + Fl::e_keysym = FL_Button + xevent.xbutton.button; + set_event_xy(); + if (xevent.xbutton.button == Button4) { + Fl::e_dy = -1; // Up + event = FL_MOUSEWHEEL; + } else if (xevent.xbutton.button == Button5) { + Fl::e_dy = +1; // Down + event = FL_MOUSEWHEEL; + } else { + Fl::e_state |= (FL_BUTTON1 << (xevent.xbutton.button-1)); + event = FL_PUSH; + checkdouble(); + } + + fl_xmousewin = window; + in_a_window = true; + break; + + case MotionNotify: + set_event_xy(); +# if CONSOLIDATE_MOTION + send_motion = fl_xmousewin = window; + in_a_window = true; + return 0; +# else + event = FL_MOVE; + fl_xmousewin = window; + in_a_window = true; + break; +# endif + + case ButtonRelease: + Fl::e_keysym = FL_Button + xevent.xbutton.button; + set_event_xy(); + Fl::e_state &= ~(FL_BUTTON1 << (xevent.xbutton.button-1)); + if (xevent.xbutton.button == Button4 || + xevent.xbutton.button == Button5) return 0; + event = FL_RELEASE; + + fl_xmousewin = window; + in_a_window = true; + break; + + case EnterNotify: + if (xevent.xcrossing.detail == NotifyInferior) break; + // XInstallColormap(fl_display, Fl_X::i(window)->colormap); + set_event_xy(); + Fl::e_state = xevent.xcrossing.state << 16; + event = FL_ENTER; + + fl_xmousewin = window; + in_a_window = true; + break; + + case LeaveNotify: + if (xevent.xcrossing.detail == NotifyInferior) break; + set_event_xy(); + Fl::e_state = xevent.xcrossing.state << 16; + fl_xmousewin = 0; + in_a_window = false; // make do_queued_events produce FL_LEAVE event + return 0; + + // We cannot rely on the x,y position in the configure notify event. + // I now think this is an unavoidable problem with X: it is impossible + // for a window manager to prevent the "real" notify event from being + // sent when it resizes the contents, even though it can send an + // artificial event with the correct position afterwards (and some + // window managers do not send this fake event anyway) + // So anyway, do a round trip to find the correct x,y: + case MapNotify: + event = FL_SHOW; + + case ConfigureNotify: { + if (window->parent()) break; // ignore child windows + + // figure out where OS really put window + XWindowAttributes actual; + XGetWindowAttributes(fl_display, fl_xid(window), &actual); + Window cr; int X, Y, W = actual.width, H = actual.height; + XTranslateCoordinates(fl_display, fl_xid(window), actual.root, + 0, 0, &X, &Y, &cr); + + // tell Fl_Window about it and set flag to prevent echoing: + resize_bug_fix = window; + window->resize(X, Y, W, H); + break; // allow add_handler to do something too + } + + case ReparentNotify: { + int xpos, ypos; + Window junk; + + // on some systems, the ReparentNotify event is not handled as we would expect. + XErrorHandler oldHandler = XSetErrorHandler(catchXExceptions()); + + //ReparentNotify gives the new position of the window relative to + //the new parent. FLTK cares about the position on the root window. + XTranslateCoordinates(fl_display, xevent.xreparent.parent, + XRootWindow(fl_display, fl_screen), + xevent.xreparent.x, xevent.xreparent.y, + &xpos, &ypos, &junk); + XSetErrorHandler(oldHandler); + + // tell Fl_Window about it and set flag to prevent echoing: + if ( !wasXExceptionRaised() ) { + resize_bug_fix = window; + window->position(xpos, ypos); + } + break; + } + } + + return Fl::handle(event, window); +} + +//////////////////////////////////////////////////////////////// + +void Fl_Window::resize(int X,int Y,int W,int H) { + int is_a_move = (X != x() || Y != y()); + int is_a_resize = (W != w() || H != h()); + int is_a_enlarge = (W > w() || H > h()); + int resize_from_program = (this != resize_bug_fix); + if (!resize_from_program) resize_bug_fix = 0; + if (is_a_move && resize_from_program) set_flag(FORCE_POSITION); + else if (!is_a_resize && !is_a_move) return; + if (is_a_resize) { + Fl_Group::resize(X,Y,W,H); + if (shown()) {redraw(); if(is_a_enlarge) i->wait_for_expose = 1;} + } else { + x(X); y(Y); + } + + if (resize_from_program && is_a_resize && !resizable()) { + size_range(w(), h(), w(), h()); + } + + if (resize_from_program && shown()) { + if (is_a_resize) { + if (!resizable()) size_range(w(),h(),w(),h()); + if (is_a_move) { + XMoveResizeWindow(fl_display, i->xid, X, Y, W>0 ? W : 1, H>0 ? H : 1); + } else { + XResizeWindow(fl_display, i->xid, W>0 ? W : 1, H>0 ? H : 1); + } + } else + XMoveWindow(fl_display, i->xid, X, Y); + } +} + +//////////////////////////////////////////////////////////////// + +// A subclass of Fl_Window may call this to associate an X window it +// creates with the Fl_Window: + +void fl_fix_focus(); // in Fl.cxx + +Fl_X* Fl_X::set_xid(Fl_Window* win, Window winxid) { + Fl_X* xp = new Fl_X; + xp->xid = winxid; + xp->other_xid = 0; + xp->setwindow(win); + xp->next = Fl_X::first; + xp->region = 0; + xp->wait_for_expose = 1; + xp->backbuffer_bad = 1; + Fl_X::first = xp; + if (win->modal()) {Fl::modal_ = win; fl_fix_focus();} + return xp; +} + +// More commonly a subclass calls this, because it hides the really +// ugly parts of X and sets all the stuff for a window that is set +// normally. The global variables like fl_show_iconic are so that +// subclasses of *that* class may change the behavior... + +char fl_show_iconic; // hack for iconize() +int fl_background_pixel = -1; // hack to speed up bg box drawing +int fl_disable_transient_for; // secret method of removing TRANSIENT_FOR + +static const int childEventMask = ExposureMask; + +static const int XEventMask = +ExposureMask|StructureNotifyMask +|KeyPressMask|KeyReleaseMask|KeymapStateMask|FocusChangeMask +|ButtonPressMask|ButtonReleaseMask +|EnterWindowMask|LeaveWindowMask +|PointerMotionMask; + +void Fl_X::make_xid(Fl_Window* win, XVisualInfo *visual, Colormap colormap) +{ + Fl_Group::current(0); // get rid of very common user bug: forgot end() + + int X = win->x(); + int Y = win->y(); + int W = win->w(); + if (W <= 0) W = 1; // X don't like zero... + int H = win->h(); + if (H <= 0) H = 1; // X don't like zero... + if (!win->parent() && !Fl::grab()) { + // center windows in case window manager does not do anything: +#ifdef FL_CENTER_WINDOWS + if (!(win->flags() & Fl_Widget::FORCE_POSITION)) { + win->x(X = scr_x+(scr_w-W)/2); + win->y(Y = scr_y+(scr_h-H)/2); + } +#endif // FL_CENTER_WINDOWS + + // force the window to be on-screen. Usually the X window manager + // does this, but a few don't, so we do it here for consistency: + int scr_x, scr_y, scr_w, scr_h; + Fl::screen_xywh(scr_x, scr_y, scr_w, scr_h, X, Y); + + if (win->border()) { + // ensure border is on screen: + // (assume extremely minimal dimensions for this border) + const int top = 20; + const int left = 1; + const int right = 1; + const int bottom = 1; + if (X+W+right > scr_x+scr_w) X = scr_x+scr_w-right-W; + if (X-left < scr_x) X = scr_x+left; + if (Y+H+bottom > scr_y+scr_h) Y = scr_y+scr_h-bottom-H; + if (Y-top < scr_y) Y = scr_y+top; + } + // now insure contents are on-screen (more important than border): + if (X+W > scr_x+scr_w) X = scr_x+scr_w-W; + if (X < scr_x) X = scr_x; + if (Y+H > scr_y+scr_h) Y = scr_y+scr_h-H; + if (Y < scr_y) Y = scr_y; + } + + // if the window is a subwindow and our parent is not mapped yet, we + // mark this window visible, so that mapping the parent at a later + // point in time will call this function again to finally map the subwindow. + if (win->parent() && !Fl_X::i(win->window())) { + win->set_visible(); + return; + } + + ulong root = win->parent() ? + fl_xid(win->window()) : RootWindow(fl_display, fl_screen); + + XSetWindowAttributes attr; + int mask = CWBorderPixel|CWColormap|CWEventMask|CWBitGravity; + attr.event_mask = win->parent() ? childEventMask : XEventMask; + attr.colormap = colormap; + attr.border_pixel = 0; + attr.bit_gravity = 0; // StaticGravity; + if (win->override()) { + attr.override_redirect = 1; + attr.save_under = 1; + mask |= CWOverrideRedirect | CWSaveUnder; + } else attr.override_redirect = 0; + if (Fl::grab()) { + attr.save_under = 1; mask |= CWSaveUnder; + if (!win->border()) {attr.override_redirect = 1; mask |= CWOverrideRedirect;} + } + if (fl_background_pixel >= 0) { + attr.background_pixel = fl_background_pixel; + fl_background_pixel = -1; + mask |= CWBackPixel; + } + + Fl_X* xp = + set_xid(win, XCreateWindow(fl_display, + root, + X, Y, W, H, + 0, // borderwidth + visual->depth, + InputOutput, + visual->visual, + mask, &attr)); + int showit = 1; + + if (!win->parent() && !attr.override_redirect) { + // Communicate all kinds 'o junk to the X Window Manager: + + win->label(win->label(), win->iconlabel()); + + XChangeProperty(fl_display, xp->xid, WM_PROTOCOLS, + XA_ATOM, 32, 0, (uchar*)&WM_DELETE_WINDOW, 1); + + // send size limits and border: + xp->sendxjunk(); + + // set the class property, which controls the icon used: + if (win->xclass()) { + char buffer[1024]; + char *p; const char *q; + // truncate on any punctuation, because they break XResource lookup: + for (p = buffer, q = win->xclass(); isalnum(*q)||(*q&128);) *p++ = *q++; + *p++ = 0; + // create the capitalized version: + q = buffer; + *p = toupper(*q++); if (*p++ == 'X') *p++ = toupper(*q++); + while ((*p++ = *q++)); + XChangeProperty(fl_display, xp->xid, XA_WM_CLASS, XA_STRING, 8, 0, + (unsigned char *)buffer, p-buffer-1); + } + + if (win->non_modal() && xp->next && !fl_disable_transient_for) { + // find some other window to be "transient for": + Fl_Window* wp = xp->next->w; + while (wp->parent()) wp = wp->window(); + XSetTransientForHint(fl_display, xp->xid, fl_xid(wp)); + if (!wp->visible()) showit = 0; // guess that wm will not show it + } + + // Make sure that borderless windows do not show in the task bar + if (!win->border()) { + Atom net_wm_state = XInternAtom (fl_display, "_NET_WM_STATE", 0); + Atom net_wm_state_skip_taskbar = XInternAtom (fl_display, "_NET_WM_STATE_SKIP_TASKBAR", 0); + XChangeProperty (fl_display, xp->xid, net_wm_state, XA_ATOM, 32, + PropModeAppend, (unsigned char*) &net_wm_state_skip_taskbar, 1); + } + + // Make it receptive to DnD: + long version = 4; + XChangeProperty(fl_display, xp->xid, fl_XdndAware, + XA_ATOM, sizeof(int)*8, 0, (unsigned char*)&version, 1); + + XWMHints *hints = XAllocWMHints(); + hints->input = True; + hints->flags = InputHint; + if (fl_show_iconic) { + hints->flags |= StateHint; + hints->initial_state = IconicState; + fl_show_iconic = 0; + showit = 0; + } + if (win->icon()) { + hints->icon_pixmap = (Pixmap)win->icon(); + hints->flags |= IconPixmapHint; + } + XSetWMHints(fl_display, xp->xid, hints); + XFree(hints); + } + + // set the window type for menu and tooltip windows to avoid animations (compiz) + if (win->menu_window() || win->tooltip_window()) { + Atom net_wm_type = XInternAtom(fl_display, "_NET_WM_WINDOW_TYPE", False); + Atom net_wm_type_kind = XInternAtom(fl_display, "_NET_WM_WINDOW_TYPE_MENU", False); + XChangeProperty(fl_display, xp->xid, net_wm_type, XA_ATOM, 32, PropModeReplace, (unsigned char*)&net_wm_type_kind, 1); + } + + XMapWindow(fl_display, xp->xid); + if (showit) { + win->set_visible(); + int old_event = Fl::e_number; + win->handle(Fl::e_number = FL_SHOW); // get child windows to appear + Fl::e_number = old_event; + win->redraw(); + } +} + +//////////////////////////////////////////////////////////////// +// Send X window stuff that can be changed over time: + +void Fl_X::sendxjunk() { + if (w->parent() || w->override()) return; // it's not a window manager window! + + if (!w->size_range_set) { // default size_range based on resizable(): + if (w->resizable()) { + Fl_Widget *o = w->resizable(); + int minw = o->w(); if (minw > 100) minw = 100; + int minh = o->h(); if (minh > 100) minh = 100; + w->size_range(w->w() - o->w() + minw, w->h() - o->h() + minh, 0, 0); + } else { + w->size_range(w->w(), w->h(), w->w(), w->h()); + } + return; // because this recursively called here + } + + XSizeHints *hints = XAllocSizeHints(); + // memset(&hints, 0, sizeof(hints)); jreiser suggestion to fix purify? + hints->min_width = w->minw; + hints->min_height = w->minh; + hints->max_width = w->maxw; + hints->max_height = w->maxh; + hints->width_inc = w->dw; + hints->height_inc = w->dh; + hints->win_gravity = StaticGravity; + + // see the file /usr/include/X11/Xm/MwmUtil.h: + // fill all fields to avoid bugs in kwm and perhaps other window managers: + // 0, MWM_FUNC_ALL, MWM_DECOR_ALL + long prop[5] = {0, 1, 1, 0, 0}; + + if (hints->min_width != hints->max_width || + hints->min_height != hints->max_height) { // resizable + hints->flags = PMinSize|PWinGravity; + if (hints->max_width >= hints->min_width || + hints->max_height >= hints->min_height) { + hints->flags = PMinSize|PMaxSize|PWinGravity; + // unfortunately we can't set just one maximum size. Guess a + // value for the other one. Some window managers will make the + // window fit on screen when maximized, others will put it off screen: + if (hints->max_width < hints->min_width) hints->max_width = Fl::w(); + if (hints->max_height < hints->min_height) hints->max_height = Fl::h(); + } + if (hints->width_inc && hints->height_inc) hints->flags |= PResizeInc; + if (w->aspect) { + // stupid X! It could insist that the corner go on the + // straight line between min and max... + hints->min_aspect.x = hints->max_aspect.x = hints->min_width; + hints->min_aspect.y = hints->max_aspect.y = hints->min_height; + hints->flags |= PAspect; + } + } else { // not resizable: + hints->flags = PMinSize|PMaxSize|PWinGravity; + prop[0] = 1; // MWM_HINTS_FUNCTIONS + prop[1] = 1|2|16; // MWM_FUNC_ALL | MWM_FUNC_RESIZE | MWM_FUNC_MAXIMIZE + } + + if (w->flags() & Fl_Widget::FORCE_POSITION) { + hints->flags |= USPosition; + hints->x = w->x(); + hints->y = w->y(); + } + + if (!w->border()) { + prop[0] |= 2; // MWM_HINTS_DECORATIONS + prop[2] = 0; // no decorations + } + + XSetWMNormalHints(fl_display, xid, hints); + XChangeProperty(fl_display, xid, + fl_MOTIF_WM_HINTS, fl_MOTIF_WM_HINTS, + 32, 0, (unsigned char *)prop, 5); + XFree(hints); +} + +void Fl_Window::size_range_() { + size_range_set = 1; + if (shown()) i->sendxjunk(); +} + +//////////////////////////////////////////////////////////////// + +// returns pointer to the filename, or null if name ends with '/' +const char *fl_filename_name(const char *name) { + const char *p,*q; + if (!name) return (0); + for (p=q=name; *p;) if (*p++ == '/') q = p; + return q; +} + +void Fl_Window::label(const char *name,const char *iname) { + Fl_Widget::label(name); + iconlabel_ = iname; + if (shown() && !parent()) { + if (!name) name = ""; + XChangeProperty(fl_display, i->xid, XA_WM_NAME, + fl_XaUtf8String, 8, 0, (uchar*)name, strlen(name)); + if (!iname) iname = fl_filename_name(name); + XChangeProperty(fl_display, i->xid, XA_WM_ICON_NAME, + fl_XaUtf8String, 8, 0, (uchar*)iname, strlen(iname)); + } +} + +//////////////////////////////////////////////////////////////// +// Implement the virtual functions for the base Fl_Window class: + +// If the box is a filled rectangle, we can make the redisplay *look* +// faster by using X's background pixel erasing. We can make it +// actually *be* faster by drawing the frame only, this is done by +// setting fl_boxcheat, which is seen by code in fl_drawbox.cxx: +// +// On XFree86 (and prehaps all X's) this has a problem if the window +// is resized while a save-behind window is atop it. The previous +// contents are restored to the area, but this assumes the area +// is cleared to background color. So this is disabled in this version. +// Fl_Window *fl_boxcheat; +static inline int can_boxcheat(uchar b) {return (b==1 || ((b&2) && b<=15));} + +void Fl_Window::show() { + image(Fl::scheme_bg_); + if (Fl::scheme_bg_) { + labeltype(FL_NORMAL_LABEL); + align(FL_ALIGN_CENTER | FL_ALIGN_INSIDE | FL_ALIGN_CLIP); + } else { + labeltype(FL_NO_LABEL); + } + Fl_Tooltip::exit(this); + if (!shown()) { + fl_open_display(); + // Don't set background pixel for double-buffered windows... + if (type() == FL_WINDOW && can_boxcheat(box())) { + fl_background_pixel = int(fl_xpixel(color())); + } + Fl_X::make_xid(this); + } else { + XMapRaised(fl_display, i->xid); + } +#ifdef USE_PRINT_BUTTON +void preparePrintFront(void); +preparePrintFront(); +#endif +} + +Window fl_window; +Fl_Window *Fl_Window::current_; +GC fl_gc; + +// make X drawing go into this window (called by subclass flush() impl.) +void Fl_Window::make_current() { + static GC gc; // the GC used by all X windows + if (!gc) gc = XCreateGC(fl_display, i->xid, 0, 0); + fl_window = i->xid; + fl_gc = gc; + current_ = this; + fl_clip_region(0); + +#ifdef USE_CAIRO + // update the cairo_t context + if (Fl::cairo_autolink_context()) Fl::cairo_make_current(this); +#endif + +} + +#ifdef USE_PRINT_BUTTON +// to test the Fl_Printer class creating a "Print front window" button in a separate window +// contains also preparePrintFront call above +#include +#include +void printFront(Fl_Widget *o, void *data) +{ + Fl_Printer printer; + o->window()->hide(); + Fl_Window *win = Fl::first_window(); + if(!win) return; + int w, h; + if( printer.start_job(1) ) { o->window()->show(); return; } + if( printer.start_page() ) { o->window()->show(); return; } + printer.printable_rect(&w,&h); + // scale the printer device so that the window fits on the page + float scale = 1; + if (win->w() > w || win->h() > h) { + scale = (float)w/win->w(); + if ((float)h/win->h() < scale) scale = (float)h/win->h(); + printer.scale(scale, scale); + } + +// #define ROTATE 20.0 +#ifdef ROTATE + printer.scale(scale * 0.8, scale * 0.8); + printer.printable_rect(&w, &h); + printer.origin(w/2, h/2 ); + printer.rotate(ROTATE); + printer.print_widget( win, - win->w()/2, - win->h()/2 ); + //printer.print_window_part( win, 0,0, win->w(), win->h(), - win->w()/2, - win->h()/2 ); +#else + printer.print_widget( win ); + //printer.print_window_part( win, 0,0,win->w(), win->h() ); +#endif + + printer.end_page(); + printer.end_job(); + o->window()->show(); +} + +void preparePrintFront(void) +{ + static int first=1; + if(!first) return; + first=0; + static Fl_Window w(0,0,150,30); + static Fl_Button b(0,0,w.w(),w.h(), "Print front window"); + b.callback(printFront); + w.end(); + w.show(); +} +#endif // USE_PRINT_BUTTON + +#endif + +// +// End of "$Id: Fl_x.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Flmm_Tabs.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/Flmm_Tabs.cxx new file mode 100644 index 0000000..81582a0 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Flmm_Tabs.cxx @@ -0,0 +1,390 @@ +// +// "$Id:$" +// +// Flmm_Scalebar source file for the FLMM extension to FLTK. +// +// Copyright 2002-2004 by Matthias Melcher. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems to "flmm@matthiasm.com". +// + +/** \class Flmm_Tabs + * Not yet documented. + */ + +#include +#include +#include +#include +#include +#include +#include + + +#define BORDER 2 +#define EXTRASPACE 10 + +enum {LEFT, RIGHT, SELECTED}; + + +Flmm_Tabs::Flmm_Tabs(int x, int y, int w, int h, const char *l) +: Fl_Tabs(x, y, w, h, l) +{ + xoff = 0; + overlapping = 0; + tab_position_array = tab_width_array = 0; + array_size = 0; +} + +Flmm_Tabs::~Flmm_Tabs() +{ + delete[] tab_position_array; + delete[] tab_width_array; +} + +void Flmm_Tabs::allocate_arrays() { + int nc = children()+2; + if (nc= 0) { + if (Fl::event_y() > y()+H) return Fl_Group::handle(event); + } else { + if (Fl::event_y() < y()+h()+H) return Fl_Group::handle(event); + } + if (Fl::event_x()>x()+w()-Habs) { + int bx = x()+w()-Habs+2, by = y()+2, bw = Habs-4, bh = Habs-4; + if (H<0) by = y()+h()-Habs+2; + Fl_Menu_Item *menu, *picked; + if (create_menu(menu, picked)) { + const Fl_Menu_Item *sel = menu->pulldown(bx, by, bw, bh, picked); + delete[] menu; + if (sel) { + Fl_Widget *w = child(sel - menu); + if (value(w)) { + set_changed(); + do_callback(); + if (Fl::visible_focus()) Fl::focus(this); + } + } + } + return 1; + } + } + case FL_DRAG: + case FL_RELEASE: + o = which(Fl::event_x(), Fl::event_y()); + if (event == FL_RELEASE) { + push(0); + if (o && value(o)) { + set_changed(); + do_callback(); + } + } else push(o); + if (Fl::visible_focus() && event == FL_RELEASE) Fl::focus(this); + return 1; + case FL_FOCUS: + case FL_UNFOCUS: + if (!Fl::visible_focus()) return Fl_Group::handle(event); + if (Fl::event() == FL_RELEASE || + Fl::event() == FL_SHORTCUT || + Fl::event() == FL_KEYBOARD || + Fl::event() == FL_FOCUS || + Fl::event() == FL_UNFOCUS) { + int H = tab_height(); + if (H >= 0) { + H += Fl::box_dy(box()); + damage(FL_DAMAGE_SCROLL, x(), y(), w(), H); + } else { + H = Fl::box_dy(box()) - H; + damage(FL_DAMAGE_SCROLL, x(), y() + h() - H, w(), H); + } + if (Fl::event() == FL_FOCUS || Fl::event() == FL_UNFOCUS) return 0; + else return 1; + } else return Fl_Group::handle(event); + case FL_KEYBOARD: + switch (Fl::event_key()) { + case FL_Left: + if (child(0)->visible()) return 0; + for (i = 1; i < children(); i ++) + if (child(i)->visible()) break; + value(child(i - 1)); + set_changed(); + do_callback(); + return 1; + case FL_Right: + if (child(children() - 1)->visible()) return 0; + for (i = 0; i < children(); i ++) + if (child(i)->visible()) break; + value(child(i + 1)); + set_changed(); + do_callback(); + return 1; + case FL_Down: + redraw(); + return Fl_Group::handle(FL_FOCUS); + default: + break; + } + case FL_SHOW: + value(); // update visibilities and fall through + default: + return Fl_Group::handle(event); + + } +} + +void Flmm_Tabs::draw() { + Fl_Widget *v = value(); + int H = tab_height(); + + if (damage() & FL_DAMAGE_ALL) { // redraw the entire thing: + Fl_Color c = v ? v->color() : color(); + + draw_box(box(), x(), y()+(H>=0?H:0), w(), h()-(H>=0?H:-H), c); + + if (selection_color() != c) { + // Draw the top 5 lines of the tab pane in the selection color so + // that the user knows which tab is selected... + if (H >= 0) fl_push_clip(x(), y() + H, w(), 5); + else fl_push_clip(x(), y() + h() - H - 4, w(), 5); + + draw_box(box(), x(), y()+(H>=0?H:0), w(), h()-(H>=0?H:-H), + selection_color()); + + fl_pop_clip(); + } + if (v) draw_child(*v); + } else { // redraw the child + if (v) update_child(*v); + } + if (damage() & (FL_DAMAGE_SCROLL|FL_DAMAGE_ALL)) { + int Habs = (H<0)?-H:H; + fl_clip(x(), y(), w()-Habs, h()); + allocate_arrays(); + int *p = tab_position_array; int *wp = tab_width_array; + int selected = tab_positions(p,wp); + int i; + Fl_Widget*const* a = array(); + for (i=0; i selected; i--) + draw_tab(x()+p[i], x()+p[i+1], wp[i], H, a[i], RIGHT); + if (v) { + i = selected; + draw_tab(x()+p[i], x()+p[i+1], wp[i], H, a[i], SELECTED); + } + fl_pop_clip(); + if (overlapping) { // pulldown menu box + int bx = x()+w()-Habs+2, by = y()+2, bw = Habs-4, bh = Habs-4; + if (H<0) by = y()+h()-Habs+2; + draw_box(box(), bx, by, bw, bh, color()); + bh = bh / 2; + bx = bx + bh/2; + by = by + bh/2; + fl_color(active_r() ? FL_DARK3 : fl_inactive(FL_DARK3)); + fl_line(bx+bh/2, by+bh, bx, by, bx+bh, by); + fl_color(active_r() ? FL_LIGHT3 : fl_inactive(FL_LIGHT3)); + fl_line(bx+bh, by, bx+bh/2, by+bh); + } + } +} + +/* Duplicate of Fl_Tabs since the original ist private. */ +void Flmm_Tabs::draw_tab(int x1, int x2, int W, int H, Fl_Widget* o, int what) { + x1 -= xoff; x2 -= xoff; + int sel = (what == SELECTED); + int dh = Fl::box_dh(box()); + int dy = Fl::box_dy(box()); + + // compute offsets to make selected tab look bigger + int yofs = sel ? 0 : BORDER; + + if ((x2 < x1+W) && what == RIGHT) x1 = x2 - W; + + if (H >= 0) { + if (sel) fl_clip(x1, y(), x2 - x1, H + dh - dy); + else fl_clip(x1, y(), x2 - x1, H); + + H += dh; + + Fl_Color c = sel ? selection_color() : o->selection_color(); + + draw_box(box(), x1, y() + yofs, W, H + 10 - yofs, c); + + // Save the previous label color + Fl_Color oc = o->labelcolor(); + + // Draw the label using the current color... + o->labelcolor(sel ? labelcolor() : o->labelcolor()); + o->draw_label(x1, y() + yofs, W, H - yofs, FL_ALIGN_CENTER); + + // Restore the original label color... + o->labelcolor(oc); + + if (Fl::focus() == this && o->visible()) + draw_focus(box(), x1, y(), W, H); + + fl_pop_clip(); + } else { + H = -H; + + if (sel) fl_clip(x1, y() + h() - H - dy, x2 - x1, H + dy); + else fl_clip(x1, y() + h() - H, x2 - x1, H); + + H += dh; + + Fl_Color c = sel ? selection_color() : o->selection_color(); + + draw_box(box(), x1, y() + h() - H - 10, W, H + 10 - yofs, c); + + // Save the previous label color + Fl_Color oc = o->labelcolor(); + + // Draw the label using the current color... + o->labelcolor(sel ? labelcolor() : o->labelcolor()); + o->draw_label(x1, y() + h() - H, W, H - yofs, FL_ALIGN_CENTER); + + // Restore the original label color... + o->labelcolor(oc); + + if (Fl::focus() == this && o->visible()) + draw_focus(box(), x1, y() + h() - H, W, H); + + fl_pop_clip(); + } +} + +/* Duplicate of Fl_Tabs since the original ist private. */ +int Flmm_Tabs::tab_height() { + int H = h(); + int H2 = y(); + Fl_Widget*const* a = array(); + for (int i=children(); i--;) { + Fl_Widget* o = *a++; + if (o->y() < y()+H) H = o->y()-y(); + if (o->y()+o->h() > H2) H2 = o->y()+o->h(); + } + H2 = y()+h()-H2; + if (H2 > H) return (H2 <= 0) ? 0 : -H2; + else return (H <= 0) ? 0 : H; +} + +int Flmm_Tabs::tab_positions(int* p, int* wp) { + int selected = 0; + Fl_Widget*const* a = array(); + int i, H = tab_height(), Habs = (H<0)?-H:H, r = w()-Habs; + leftmost = 0; + rightmost = children()-1; + p[0] = Fl::box_dx(box()); + for (i=0; ivisible()) selected = i; + + int wt = 0; int ht = 0; + o->measure_label(wt,ht); + + wp[i] = wt+EXTRASPACE; + p[i+1] = p[i]+wp[i]+BORDER; + if (p[i]-xoff<8) leftmost = i+1; + if (p[i+1]-xoff=children()-2) { + // last tab is selected: make last tab right aligned + xoff = p[i]-r+Fl::box_dx(box()); + } else if (selected<=leftmost) { + // selection is to the left of visible tabs: show selection plus half left aligned + xoff = p[selected]-((p[selected]-p[selected-1])/2)-Fl::box_dx(box()); + } else if (selected>rightmost) { + // selection is to the right of visible tabs: show selection plus half right aligned + xoff = p[selected+2]+((p[selected+2]-p[selected+3])/2)+Fl::box_dx(box())-r; + } else { + // selection is currently visible: we are fine + } + return selected; +} + +Fl_Widget *Flmm_Tabs::which(int event_x, int event_y) { + int H = tab_height(); + if (H < 0) { + if (event_y > y()+h() || event_y < y()+h()+H) return 0; + } else { + if (event_y > y()+H || event_y < y()) return 0; + } + if (event_x < x()) return 0; + allocate_arrays(); + int *p = tab_position_array; int *wp = tab_width_array; + tab_positions(p, wp); + for (int i=0; ivisible()) picked = d; + d->label(c->label()); + d->labeltype(c->labeltype()); + d->labelcolor(c->labelcolor()); + d->labelfont(c->labelfont()); + d->labelsize(c->labelsize()); + if (i==rightmost || i==leftmost-1) + d->flags = FL_MENU_DIVIDER; + d++; + } + return 1; +} + +// +// End of "$Id: Fl_Tabs.cxx 4448 2005-07-23 12:21:58Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/Makefile b/mod/maxgui.mod/fltkmaxgui.mod/src/Makefile new file mode 100644 index 0000000..6043d89 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/Makefile @@ -0,0 +1,801 @@ +# +# "$Id: Makefile 7906 2010-11-28 21:28:30Z matt $" +# +# Library makefile for the Fast Light Tool Kit (FLTK). +# +# Copyright 1998-2010 by Bill Spitzak and others. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. +# +# You should have received a copy of the GNU Library General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +# USA. +# +# Please report all bugs and problems on the following page: +# +# http://www.fltk.org/str.php +# + +CPPFILES = \ + Fl.cxx \ + Fl_Adjuster.cxx \ + Fl_Bitmap.cxx \ + Fl_Browser.cxx \ + Fl_Browser_.cxx \ + Fl_Browser_load.cxx \ + Fl_Box.cxx \ + Fl_Button.cxx \ + Fl_Chart.cxx \ + Fl_Check_Browser.cxx \ + Fl_Check_Button.cxx \ + Fl_Choice.cxx \ + Fl_Clock.cxx \ + Fl_Color_Chooser.cxx \ + Fl_Counter.cxx \ + Fl_Dial.cxx \ + Fl_Device.cxx \ + Fl_Double_Window.cxx \ + Fl_File_Browser.cxx \ + Fl_File_Chooser.cxx \ + Fl_File_Chooser2.cxx \ + Fl_File_Icon.cxx \ + Fl_File_Input.cxx \ + Fl_Group.cxx \ + Fl_Help_View.cxx \ + Fl_Image.cxx \ + Fl_Input.cxx \ + Fl_Input_.cxx \ + Fl_Light_Button.cxx \ + Fl_Menu.cxx \ + Fl_Menu_.cxx \ + Fl_Menu_Bar.cxx \ + Fl_Sys_Menu_Bar.cxx \ + Fl_Menu_Button.cxx \ + Fl_Menu_Window.cxx \ + Fl_Menu_add.cxx \ + Fl_Menu_global.cxx \ + Fl_Multi_Label.cxx \ + Fl_Native_File_Chooser.cxx \ + Fl_Overlay_Window.cxx \ + Fl_Pack.cxx \ + Fl_Paged_Device.cxx \ + Fl_Pixmap.cxx \ + Fl_Positioner.cxx \ + Fl_Preferences.cxx \ + Fl_Printer.cxx \ + Fl_Progress.cxx \ + Fl_Repeat_Button.cxx \ + Fl_Return_Button.cxx \ + Fl_Roller.cxx \ + Fl_Round_Button.cxx \ + Fl_Scroll.cxx \ + Fl_Scrollbar.cxx \ + Fl_Shared_Image.cxx \ + Fl_Single_Window.cxx \ + Fl_Slider.cxx \ + Fl_Table.cxx \ + Fl_Table_Row.cxx \ + Fl_Tabs.cxx \ + Fl_Text_Buffer.cxx \ + Fl_Text_Display.cxx \ + Fl_Text_Editor.cxx \ + Fl_Tile.cxx \ + Fl_Tiled_Image.cxx \ + Fl_Tree.cxx \ + Fl_Tree_Item.cxx \ + Fl_Tree_Item_Array.cxx \ + Fl_Tree_Prefs.cxx \ + Fl_Tooltip.cxx \ + Fl_Valuator.cxx \ + Fl_Value_Input.cxx \ + Fl_Value_Output.cxx \ + Fl_Value_Slider.cxx \ + Fl_Widget.cxx \ + Fl_Window.cxx \ + Fl_Window_fullscreen.cxx \ + Fl_Window_hotspot.cxx \ + Fl_Window_iconize.cxx \ + Fl_Wizard.cxx \ + Fl_XBM_Image.cxx \ + Fl_XPM_Image.cxx \ + Fl_abort.cxx \ + Fl_add_idle.cxx \ + Fl_arg.cxx \ + Fl_compose.cxx \ + Fl_display.cxx \ + Fl_get_key.cxx \ + Fl_get_system_colors.cxx \ + Fl_grab.cxx \ + Fl_lock.cxx \ + Fl_own_colormap.cxx \ + Fl_visual.cxx \ + Fl_x.cxx \ + filename_absolute.cxx \ + filename_expand.cxx \ + filename_ext.cxx \ + filename_isdir.cxx \ + filename_list.cxx \ + filename_match.cxx \ + filename_setext.cxx \ + fl_arc.cxx \ + fl_arci.cxx \ + fl_ask.cxx \ + fl_boxtype.cxx \ + fl_color.cxx \ + fl_cursor.cxx \ + fl_curve.cxx \ + fl_diamond_box.cxx \ + fl_dnd.cxx \ + fl_draw.cxx \ + fl_draw_image.cxx \ + fl_draw_pixmap.cxx \ + fl_encoding_latin1.cxx \ + fl_encoding_mac_roman.cxx \ + fl_engraved_label.cxx \ + fl_file_dir.cxx \ + fl_font.cxx \ + fl_gtk.cxx \ + fl_labeltype.cxx \ + fl_line_style.cxx \ + fl_open_uri.cxx \ + fl_oval_box.cxx \ + fl_overlay.cxx \ + fl_overlay_visual.cxx \ + fl_plastic.cxx \ + fl_read_image.cxx \ + fl_rect.cxx \ + fl_round_box.cxx \ + fl_rounded_box.cxx \ + fl_set_font.cxx \ + fl_set_fonts.cxx \ + fl_scroll_area.cxx \ + fl_shadow_box.cxx \ + fl_shortcut.cxx \ + fl_show_colormap.cxx \ + fl_symbols.cxx \ + fl_vertex.cxx \ + screen_xywh.cxx \ + fl_utf8.cxx \ + ps_image.cxx + +FLCPPFILES = \ + forms_compatability.cxx \ + forms_bitmap.cxx \ + forms_free.cxx \ + forms_fselect.cxx \ + forms_pixmap.cxx \ + forms_timer.cxx + +GLCPPFILES = \ + Fl_Gl_Choice.cxx \ + Fl_Gl_Overlay.cxx \ + Fl_Gl_Device_Plugin.cxx \ + Fl_Gl_Window.cxx \ + freeglut_geometry.cxx \ + freeglut_stroke_mono_roman.cxx \ + freeglut_stroke_roman.cxx \ + freeglut_teapot.cxx \ + gl_draw.cxx \ + gl_start.cxx \ + glut_compatability.cxx \ + glut_font.cxx + +IMGCPPFILES = \ + fl_images_core.cxx \ + Fl_BMP_Image.cxx \ + Fl_File_Icon2.cxx \ + Fl_GIF_Image.cxx \ + Fl_Help_Dialog.cxx \ + Fl_JPEG_Image.cxx \ + Fl_PNG_Image.cxx \ + Fl_PNM_Image.cxx + + +CFILES = fl_call_main.c flstring.c scandir.c numericsort.c vsnprintf.c fl_utf.c + +UTF8CFILES = \ + xutf8/case.c \ + xutf8/is_right2left.c \ + xutf8/is_spacing.c \ + xutf8/keysym2Ucs.c \ + xutf8/utf8Input.c \ + xutf8/utf8Utils.c \ + xutf8/utf8Wrap.c + +################################################################ + +include ../makeinclude + +OBJECTS = $(CPPFILES:.cxx=.o) $(CFILES:.c=.o) $(UTF8CFILES:.c=.o) +GLOBJECTS = $(GLCPPFILES:.cxx=.o) +FLOBJECTS = $(FLCPPFILES:.cxx=.o) +IMGOBJECTS = $(IMGCPPFILES:.cxx=.o) + +all: $(LIBNAME) $(DSONAME) \ + $(FLLIBNAME) $(FLDSONAME) \ + $(GLLIBNAME) $(GLDSONAME) \ + $(IMGLIBNAME) $(IMGDSONAME) + +$(LIBNAME): $(OBJECTS) + echo $(LIBCOMMAND) $@ ... + $(RM) $@ + $(LIBCOMMAND) $@ $(OBJECTS) + $(RANLIB) $@ + +libfltk.so.1.3: $(OBJECTS) + echo $(DSOCOMMAND) $@ ... + $(DSOCOMMAND) $@ $(OBJECTS) + $(RM) libfltk.so + $(LN) libfltk.so.1.3 libfltk.so + +libfltk.sl.1.3: $(OBJECTS) + echo $(DSOCOMMAND) $@ ... + $(DSOCOMMAND) $@ $(OBJECTS) + $(RM) libfltk.sl + $(LN) libfltk.sl.1.3 libfltk.sl + +libfltk.1.3.dylib: $(OBJECTS) + echo $(DSOCOMMAND) $@ ... + $(DSOCOMMAND) $@ \ + -install_name $(libdir)/$@ \ + -current_version 1.3.0 \ + -compatibility_version 1.3.0 \ + $(OBJECTS) $(LDLIBS) + $(RM) libfltk.dylib + $(LN) libfltk.1.3.dylib libfltk.dylib + +libfltk_s.a: $(OBJECTS) + echo $(DSOCOMMAND) libfltk_s.o ... + $(DSOCOMMAND) libfltk_s.o $(OBJECTS) $(IMAGELIBS) + echo $(LIBCOMMAND) libfltk_s.a libfltk_s.o + $(RM) $@ + $(LIBCOMMAND) libfltk_s.a libfltk_s.o + $(CHMOD) +x libfltk_s.a + +$(FLLIBNAME): $(FLOBJECTS) + echo $(LIBCOMMAND) $@ ... + $(RM) $@ + $(LIBCOMMAND) $@ $(FLOBJECTS) + $(RANLIB) $@ + +libfltk_forms.so.1.3: $(FLOBJECTS) libfltk.so.1.3 + echo $(DSOCOMMAND) $@ ... + $(DSOCOMMAND) $@ $(FLOBJECTS) -L. -lfltk + $(RM) libfltk_forms.so + $(LN) libfltk_forms.so.1.3 libfltk_forms.so + +libfltk_forms.sl.1.3: $(FLOBJECTS) libfltk.sl.1.3 + echo $(DSOCOMMAND) $@ ... + $(DSOCOMMAND) $@ $(FLOBJECTS) -L. -lfltk + $(RM) libfltk_forms.sl + $(LN) libfltk_forms.sl.1.3 libfltk_forms.sl + +libfltk_forms.1.3.dylib: $(FLOBJECTS) libfltk.1.3.dylib + echo $(DSOCOMMAND) $@ ... + $(DSOCOMMAND) $@ \ + -install_name $(libdir)/$@ \ + -current_version 1.3.0 \ + -compatibility_version 1.3.0 \ + $(FLOBJECTS) -L. $(LDLIBS) -lfltk + $(RM) libfltk_forms.dylib + $(LN) libfltk_forms.1.3.dylib libfltk_forms.dylib + +libfltk_forms_s.a: $(FLOBJECTS) + echo $(DSOCOMMAND) libfltk_forms_s.o ... + $(DSOCOMMAND) libfltk_forms_s.o $(FLOBJECTS) + echo $(LIBCOMMAND) libfltk_forms_s.a libfltk_forms_s.o + $(RM) $@ + $(LIBCOMMAND) libfltk_forms_s.a libfltk_forms_s.o + $(CHMOD) +x libfltk_forms_s.a + +$(GLLIBNAME): $(GLOBJECTS) + echo $(LIBCOMMAND) $@ ... + $(RM) $@ + $(LIBCOMMAND) $@ $(GLOBJECTS) + $(RANLIB) $@ + +libfltk_gl.so.1.3: $(GLOBJECTS) libfltk.so.1.3 + echo $(DSOCOMMAND) $@ ... + $(DSOCOMMAND) $@ $(GLOBJECTS) -L. -lfltk + $(RM) libfltk_gl.so + $(LN) libfltk_gl.so.1.3 libfltk_gl.so + +libfltk_gl.sl.1.3: $(GLOBJECTS) libfltk.sl.1.3 + echo $(DSOCOMMAND) $@ ... + $(DSOCOMMAND) $@ $(GLOBJECTS) -L. -lfltk + $(RM) libfltk_gl.sl + $(LN) libfltk_gl.sl.1.3 libfltk_gl.sl + +libfltk_gl.1.3.dylib: $(GLOBJECTS) libfltk.1.3.dylib + echo $(DSOCOMMAND) $@ ... + $(DSOCOMMAND) $@ \ + -install_name $(libdir)/$@ \ + -current_version 1.3.0 \ + -compatibility_version 1.3.0 \ + $(GLOBJECTS) -L. $(GLDLIBS) -lfltk + $(RM) libfltk_gl.dylib + $(LN) libfltk_gl.1.3.dylib libfltk_gl.dylib + +libfltk_gl_s.a: $(GLOBJECTS) + echo $(DSOCOMMAND) libfltk_gl_s.o ... + $(DSOCOMMAND) libfltk_gl_s.o $(GLOBJECTS) + echo $(LIBCOMMAND) libfltk_gl_s.a libfltk_gl_s.o + $(RM) $@ + $(LIBCOMMAND) libfltk_gl_s.a libfltk_gl_s.o + $(CHMOD) +x libfltk_gl_s.a + +$(IMGLIBNAME): $(IMGOBJECTS) + echo $(LIBCOMMAND) $@ ... + $(RM) $@ + $(LIBCOMMAND) $@ $(IMGOBJECTS) + $(RANLIB) $@ + +libfltk_images.so.1.3: $(IMGOBJECTS) libfltk.so.1.3 + echo $(DSOCOMMAND) $@ ... + $(DSOCOMMAND) $@ $(IMGOBJECTS) -L. $(IMAGELIBS) -lfltk + $(RM) libfltk_images.so + $(LN) libfltk_images.so.1.3 libfltk_images.so + +libfltk_images.sl.1.3: $(IMGOBJECTS) libfltk.sl.1.3 + echo $(DSOCOMMAND) $@ ... + $(DSOCOMMAND) $@ $(IMGOBJECTS) -L. $(IMAGELIBS) -lfltk + $(RM) libfltk_images.sl + $(LN) libfltk_images.sl.1.3 libfltk_images.sl + +libfltk_images.1.3.dylib: $(IMGOBJECTS) libfltk.1.3.dylib + echo $(DSOCOMMAND) $@ ... + $(DSOCOMMAND) $@ \ + -install_name $(libdir)/$@ \ + -current_version 1.3.0 \ + -compatibility_version 1.3.0 \ + $(IMGOBJECTS) -L. $(LDLIBS) $(IMAGELIBS) -lfltk + $(RM) libfltk_images.dylib + $(LN) libfltk_images.1.3.dylib libfltk_images.dylib + +libfltk_images_s.a: $(IMGOBJECTS) + echo $(DSOCOMMAND) libfltk_images_s.o ... + $(DSOCOMMAND) libfltk_images_s.o $(IMGOBJECTS) + echo $(LIBCOMMAND) libfltk_images_s.a libfltk_images_s.o + $(RM) $@ + $(LIBCOMMAND) libfltk_images_s.a libfltk_images_s.o + $(CHMOD) +x libfltk_images_s.a + +#----------------------------------------------------------------- +# - the import libraries libfltk*.dll.a and the .dll files +# are created from the libfltk*.a files. They are built +# into the src dir. +# - The _images, _gl, _forms and dlls must be linked +# against the import libraries in the src dir. +#----------------------------------------------------------------- + +#----------------------------------------------------------------- +# cygwin GDI shared libraries +#----------------------------------------------------------------- + +cygfltknox-1.3.dll: $(LIBNAME) + echo $(DSOCOMMAND) $(LIBNAME) ... + $(DSOCOMMAND) $(LIBNAME) -Wl,--no-whole-archive \ + -Wl,--out-implib=libfltk.dll.a $(LDLIBS) + +cygfltknox_forms-1.3.dll: $(FLLIBNAME) cygfltknox-1.3.dll + echo $(DSOCOMMAND) $(FLLIBNAME) ... + $(DSOCOMMAND) $(FLLIBNAME) -Wl,--no-whole-archive \ + -Wl,--out-implib=libfltk_forms.dll.a \ + -L. -lfltk $(LDLIBS) + +cygfltknox_gl-1.3.dll: $(GLLIBNAME) cygfltknox-1.3.dll + echo $(DSOCOMMAND) $(GLLIBNAME) ... + $(DSOCOMMAND) $(GLLIBNAME) -Wl,--no-whole-archive \ + -Wl,--out-implib=libfltk_gl.dll.a \ + -L. -lfltk $(GLDLIBS) + +cygfltknox_images-1.3.dll: $(IMGLIBNAME) cygfltknox-1.3.dll + echo $(DSOCOMMAND) $(IMGLIBNAME) ... + $(DSOCOMMAND) $(IMGLIBNAME) -Wl,--no-whole-archive \ + -Wl,--out-implib=libfltk_images.dll.a \ + -L. -lfltk -Wl,--exclude-libs -Wl,libfltk_png.a \ + $(IMAGELIBS) $(LDLIBS) + +#----------------------------------------------------------------- +# cygwin X11 shared libraries +#----------------------------------------------------------------- + +cygfltk-1.3.dll: $(LIBNAME) + echo $(DSOCOMMAND) $(LIBNAME) ... + $(DSOCOMMAND) $(LIBNAME) -Wl,--no-whole-archive \ + -Wl,--out-implib=libfltk.dll.a $(LDLIBS) + +cygfltk_forms-1.3.dll: $(FLLIBNAME) cygfltk-1.3.dll + echo $(DSOCOMMAND) $(FLLIBNAME) ... + $(DSOCOMMAND) $(FLLIBNAME) -Wl,--no-whole-archive \ + -Wl,--out-implib=libfltk_forms.dll.a \ + -L. -lfltk $(LDLIBS) + +cygfltk_gl-1.3.dll: $(GLLIBNAME) cygfltk-1.3.dll + echo $(DSOCOMMAND) $(GLLIBNAME) ... + $(DSOCOMMAND) $(GLLIBNAME) -Wl,--no-whole-archive \ + -Wl,--out-implib=libfltk_gl.dll.a \ + -L. -lfltk $(GLDLIBS) + +cygfltk_images-1.3.dll: $(IMGLIBNAME) cygfltk-1.3.dll + echo $(DSOCOMMAND) $(IMGLIBNAME) ... + $(DSOCOMMAND) $(IMGLIBNAME) -Wl,--no-whole-archive \ + -Wl,--out-implib=libfltk_images.dll.a \ + -L. -lfltk -Wl,--exclude-libs -Wl,libfltk_png.a \ + $(IMAGELIBS) $(LDLIBS) + +mgwfltknox-1.3.dll: $(LIBNAME) + echo $(DSOCOMMAND) $(LIBNAME) ... + $(DSOCOMMAND) $(LIBNAME) -Wl,--no-whole-archive \ + -Wl,--out-implib=libfltk.dll.a $(LDLIBS) + +mgwfltknox_forms-1.3.dll: $(FLLIBNAME) mgwfltknox-1.3.dll + echo $(DSOCOMMAND) $(FLLIBNAME) ... + $(DSOCOMMAND) $(FLLIBNAME) -Wl,--no-whole-archive \ + -Wl,--out-implib=libfltk_forms.dll.a \ + -L. -lfltk $(LDLIBS) + +mgwfltknox_gl-1.3.dll: $(GLLIBNAME) mgwfltknox-1.3.dll + echo $(DSOCOMMAND) $(GLLIBNAME) ... + $(DSOCOMMAND) $(GLLIBNAME) -Wl,--no-whole-archive \ + -Wl,--out-implib=libfltk_gl.dll.a \ + -L. -lfltk $(GLDLIBS) + +#----------------------------------------------------- +# See STR #1585 for --exclude-libs +#----------------------------------------------------- + +mgwfltknox_images-1.3.dll: $(IMGLIBNAME) mgwfltknox-1.3.dll + echo $(DSOCOMMAND) $(IMGLIBNAME) ... + $(DSOCOMMAND) $(IMGLIBNAME) -Wl,--no-whole-archive \ + -Wl,--out-implib=libfltk_images.dll.a \ + -L. -lfltk -Wl,--exclude-libs -Wl,libfltk_png.a \ + $(IMAGELIBS) $(LDLIBS) + +clean: + -$(RM) *.o xutf8/*.o *.dll.a core.* *~ *.bak *.bck + -$(RM) $(DSONAME) $(FLDSONAME) $(GLDSONAME) $(IMGDSONAME) \ + $(LIBNAME) $(FLLIBNAME) $(GLLIBNAME) \ + $(IMGLIBNAME) \ + libfltk.so libfltk_forms.so libfltk_gl.so libfltk_images.so \ + libfltk.sl libfltk_forms.sl libfltk_gl.sl libfltk_images.sl \ + libfltk.dylib libfltk_forms.dylib \ + libfltk_gl.dylib libfltk_images.dylib \ + cmap core + +depend: $(CPPFILES) $(FLCPPFILES) $(GLCPPFILES) $(IMGCPPFILES) $(CFILES) $(UTF8CFILES) + makedepend -Y -I.. -f makedepend $(CPPFILES) $(FLCPPFILES) \ + $(GLCPPFILES) $(IMGCPPFILES) $(CFILES) $(UTF8CFILES) + +# Automatically generated dependencies... generated on a Linux/Unix host ! +include makedepend + +# These dependencies aren't part of the makedepend file since +# they are part of the WIN32 and MacOS code base... +# Please add only non-Linux/Unix files or such that are optional +# (like "*xft*") here: +Fl_get_key.o: Fl_get_key_mac.cxx Fl_get_key_win32.cxx +Fl_Native_File_Chooser.o : Fl_Native_File_Chooser_MAC.cxx Fl_Native_File_Chooser_WIN32.cxx +Fl.o: Fl_mac.cxx Fl_win32.cxx Fl_cocoa.mm +fl_color.o: fl_color_mac.cxx fl_color_win32.cxx +fl_dnd.o: fl_dnd_mac.cxx fl_dnd_win32.cxx fl_dnd_x.cxx +fl_draw_image.o: fl_draw_image_mac.cxx fl_draw_image_win32.cxx +fl_font.o: fl_font_mac.cxx fl_font_x.cxx fl_font_xft.cxx fl_font_win32.cxx +fl_read_image.o: fl_read_image_mac.cxx fl_read_image_win32.cxx +fl_set_fonts.o: fl_set_fonts_mac.cxx fl_set_fonts_x.cxx \ + fl_set_fonts_xft.cxx fl_set_fonts_win32.cxx +Fl_Printer.o: Fl_Quartz_Printer.mm Fl_GDI_Printer.cxx Fl_PostScript.cxx +fl_arci.o: ../FL/mac.H ../FL/win32.H +Fl_arg.o: ../FL/mac.H ../FL/win32.H +fl_ask.o: ../FL/mac.H ../FL/win32.H +Fl_Bitmap.o: ../FL/mac.H ../FL/win32.H +fl_color.o: ../FL/mac.H ../FL/win32.H +fl_cursor.o: ../FL/mac.H ../FL/win32.H +fl_dnd.o: ../FL/mac.H ../FL/win32.H +Fl.o: ../FL/mac.H ../FL/win32.H +Fl_Double_Window.o: ../FL/mac.H ../FL/win32.H +fl_draw_image.o: ../FL/mac.H ../FL/win32.H +fl_draw_image_mac.o: ../FL/mac.H ../FL/win32.H +fl_draw_image_win32.o: ../FL/mac.H ../FL/win32.H +fl_draw_pixmap.o: ../FL/mac.H ../FL/win32.H +fl_encoding_latin1.o: ../FL/mac.H ../FL/win32.H +fl_encoding_mac_roman.o: ../FL/mac.H ../FL/win32.H +Fl_File_Chooser2.o: ../FL/mac.H ../FL/win32.H +fl_font.o: ../FL/mac.H ../FL/win32.H +Fl_get_key.o: ../FL/mac.H ../FL/win32.H +Fl_get_system_colors.o: ../FL/mac.H ../FL/win32.H +Fl_Gl_Choice.o: ../FL/mac.H ../FL/win32.H +Fl_Gl_Overlay.o: ../FL/mac.H ../FL/win32.H +Fl_Gl_Window.o: ../FL/mac.H ../FL/win32.H +Fl_grab.o: ../FL/mac.H ../FL/win32.H +Fl_Image.o: ../FL/mac.H ../FL/win32.H +fl_line_style.o: ../FL/mac.H ../FL/win32.H +Fl_Native_File_Chooser.o: ../FL/Fl_Native_File_Chooser_MAC.H ../FL/Fl_Native_File_Chooser_WIN32.H +Fl_Menu_Window.o: ../FL/mac.H ../FL/win32.H +fl_overlay.o: ../FL/mac.H ../FL/win32.H +fl_overlay_visual.o: ../FL/mac.H ../FL/win32.H +Fl_Overlay_Window.o: ../FL/mac.H ../FL/win32.H +Fl_own_colormap.o: ../FL/mac.H ../FL/win32.H +Fl_Pixmap.o: ../FL/mac.H ../FL/win32.H +Fl_Printer.o: ../FL/mac.H ../FL/win32.H +fl_read_image.o: ../FL/mac.H ../FL/win32.H +fl_read_image_mac.o: ../FL/mac.H ../FL/win32.H +fl_read_image_win32.o: ../FL/mac.H ../FL/win32.H +fl_rect.o: ../FL/mac.H ../FL/win32.H +fl_scroll_area.o: ../FL/mac.H ../FL/win32.H +fl_set_font.o: ../FL/mac.H ../FL/win32.H +fl_set_fonts.o: ../FL/mac.H ../FL/win32.H +fl_shortcut.o: ../FL/mac.H ../FL/win32.H +fl_vertex.o: ../FL/mac.H ../FL/win32.H +Fl_visual.o: ../FL/mac.H ../FL/win32.H +Fl_Window_fullscreen.o: ../FL/mac.H ../FL/win32.H +Fl_Window_iconize.o: ../FL/mac.H ../FL/win32.H +Fl_x.o: ../FL/mac.H ../FL/win32.H +gl_draw.o: ../FL/mac.H ../FL/win32.H +gl_start.o: ../FL/mac.H ../FL/win32.H + +################################################################ + +install: $(LIBNAME) $(DSONAME) \ + $(FLLIBNAME) $(FLDSONAME) \ + $(GLLIBNAME) $(GLDSONAME) \ + $(IMGLIBNAME) $(IMGDSONAME) + echo "Installing libraries in $(DESTDIR)$(libdir)..." + -$(INSTALL_DIR) $(DESTDIR)$(libdir) + -$(INSTALL_DIR) $(DESTDIR)$(bindir) + $(RM) $(DESTDIR)$(libdir)/$(LIBBASENAME) + $(INSTALL_LIB) $(LIBNAME) $(DESTDIR)$(libdir) + $(INSTALL_LIB) $(FLLIBNAME) $(DESTDIR)$(libdir) + $(INSTALL_LIB) $(IMGLIBNAME) $(DESTDIR)$(libdir) + $(RANLIB) $(DESTDIR)$(libdir)/$(LIBBASENAME) + $(RANLIB) $(DESTDIR)$(libdir)/$(FLLIBBASENAME) + if test x$(GLLIBNAME) != x; then \ + $(INSTALL_LIB) $(GLLIBNAME) $(DESTDIR)$(libdir); \ + $(RANLIB) $(DESTDIR)$(libdir)/$(GLLIBBASENAME); \ + fi + $(RANLIB) $(DESTDIR)$(libdir)/$(IMGLIBBASENAME) + if test x$(DSONAME) = xlibfltk.so.1.3; then\ + $(RM) $(DESTDIR)$(libdir)/libfltk.so*;\ + $(INSTALL_LIB) libfltk.so.1.3 $(DESTDIR)$(libdir); \ + $(LN) libfltk.so.1.3 $(DESTDIR)$(libdir)/libfltk.so;\ + fi + if test x$(DSONAME) = xlibfltk.sl.1.3; then\ + $(RM) $(DESTDIR)$(libdir)/libfltk.sl*;\ + $(INSTALL_LIB) libfltk.sl.1.3 $(DESTDIR)$(libdir); \ + $(LN) libfltk.sl.1.3 $(DESTDIR)$(libdir)/libfltk.sl;\ + fi + if test x$(DSONAME) = xlibfltk.1.3.dylib; then\ + $(RM) $(DESTDIR)$(libdir)/libfltk.*dylib;\ + $(INSTALL_LIB) libfltk.1.3.dylib $(DESTDIR)$(libdir); \ + $(LN) libfltk.1.3.dylib $(DESTDIR)$(libdir)/libfltk.dylib;\ + fi + if test x$(DSONAME) = xlibfltk_s.a; then\ + $(RM) $(DESTDIR)$(libdir)/libfltk_s.a;\ + $(INSTALL_LIB) libfltk_s.a $(DESTDIR)$(libdir); \ + fi + if test x$(DSONAME) = xcygfltknox-1.3.dll; then\ + $(RM) $(DESTDIR)$(bindir)/$(DSONAME);\ + $(INSTALL_LIB) $(DSONAME) $(DESTDIR)$(bindir); \ + $(RM) $(DESTDIR)$(libdir)/libfltk.dll.a;\ + $(INSTALL_LIB) libfltk.dll.a $(DESTDIR)$(libdir); \ + fi + if test x$(DSONAME) = xmgwfltknox-1.3.dll; then\ + $(RM) $(DESTDIR)$(bindir)/$(DSONAME);\ + $(INSTALL_LIB) $(DSONAME) $(DESTDIR)$(bindir); \ + $(RM) $(DESTDIR)$(libdir)/libfltk.dll.a;\ + $(INSTALL_LIB) libfltk.dll.a $(DESTDIR)$(libdir); \ + fi + if test x$(FLDSONAME) = xlibfltk_forms.so.1.3; then\ + $(RM) $(DESTDIR)$(libdir)/libfltk_forms.so*;\ + $(INSTALL_LIB) libfltk_forms.so.1.3 $(DESTDIR)$(libdir); \ + $(LN) libfltk_forms.so.1.3 $(DESTDIR)$(libdir)/libfltk_forms.so;\ + fi + if test x$(FLDSONAME) = xlibfltk_forms.sl.1.3; then\ + $(RM) $(DESTDIR)$(libdir)/libfltk_forms.sl*;\ + $(INSTALL_LIB) libfltk_forms.sl.1.3 $(DESTDIR)$(libdir); \ + $(LN) libfltk_forms.sl.1.3 $(DESTDIR)$(libdir)/libfltk_forms.sl;\ + fi + if test x$(FLDSONAME) = xlibfltk_forms.1.3.dylib; then\ + $(RM) $(DESTDIR)$(libdir)/libfltk_forms.*dylib;\ + $(INSTALL_LIB) libfltk_forms.1.3.dylib $(DESTDIR)$(libdir); \ + $(LN) libfltk_forms.1.3.dylib $(DESTDIR)$(libdir)/libfltk_forms.dylib;\ + fi + if test x$(FLDSONAME) = xlibfltk_forms_s.a; then\ + $(RM) $(DESTDIR)$(libdir)/libfltk_forms_s.a;\ + $(INSTALL_LIB) libfltk_forms_s.a $(DESTDIR)$(libdir); \ + fi + if test x$(FLDSONAME) = xcygfltknox_forms-1.3.dll; then\ + $(RM) $(DESTDIR)$(bindir)/$(FLDSONAME);\ + $(INSTALL_LIB) $(FLDSONAME) $(DESTDIR)$(bindir); \ + $(RM) $(DESTDIR)$(libdir)/libfltk_forms.dll.a;\ + $(INSTALL_LIB) libfltk_forms.dll.a $(DESTDIR)$(libdir); \ + fi + if test x$(FLDSONAME) = xmgwfltknox_forms-1.3.dll; then\ + $(RM) $(DESTDIR)$(bindir)/$(FLDSONAME);\ + $(INSTALL_LIB) $(FLDSONAME) $(DESTDIR)$(bindir); \ + $(RM) $(DESTDIR)$(libdir)/libfltk_forms.dll.a;\ + $(INSTALL_LIB) libfltk_forms.dll.a $(DESTDIR)$(libdir); \ + fi + if test x$(GLDSONAME) = xlibfltk_gl.so.1.3; then\ + $(RM) $(DESTDIR)$(libdir)/libfltk_gl.so*;\ + $(INSTALL_LIB) libfltk_gl.so.1.3 $(DESTDIR)$(libdir); \ + $(LN) libfltk_gl.so.1.3 $(DESTDIR)$(libdir)/libfltk_gl.so;\ + fi + if test x$(GLDSONAME) = xlibfltk_gl.sl.1.3; then\ + $(RM) $(DESTDIR)$(libdir)/libfltk_gl.sl*;\ + $(INSTALL_LIB) libfltk_gl.sl.1.3 $(DESTDIR)$(libdir); \ + $(LN) libfltk_gl.sl.1.3 $(DESTDIR)$(libdir)/libfltk_gl.sl;\ + fi + if test x$(GLDSONAME) = xlibfltk_gl.1.3.dylib; then\ + $(RM) $(DESTDIR)$(libdir)/libfltk_gl.*dylib;\ + $(INSTALL_LIB) libfltk_gl.1.3.dylib $(DESTDIR)$(libdir); \ + $(LN) libfltk_gl.1.3.dylib $(DESTDIR)$(libdir)/libfltk_gl.dylib;\ + fi + if test x$(GLDSONAME) = xlibfltk_gl_s.a; then\ + $(RM) $(DESTDIR)$(libdir)/libfltk_gl_s.a;\ + $(INSTALL_LIB) libfltk_gl_s.a $(DESTDIR)$(libdir); \ + fi + if test x$(GLDSONAME) = xcygfltknox_gl-1.3.dll; then\ + $(RM) $(DESTDIR)$(bindir)/$(GLDSONAME);\ + $(INSTALL_LIB) $(GLDSONAME) $(DESTDIR)$(bindir); \ + $(RM) $(DESTDIR)$(libdir)/libfltk_gl.dll.a;\ + $(INSTALL_LIB) libfltk_gl.dll.a $(DESTDIR)$(libdir); \ + fi + if test x$(GLDSONAME) = xmgwfltknox_gl-1.3.dll; then\ + $(RM) $(DESTDIR)$(bindir)/$(GLDSONAME);\ + $(INSTALL_LIB) $(GLDSONAME) $(DESTDIR)$(bindir); \ + $(RM) $(DESTDIR)$(libdir)/libfltk_gl.dll.a;\ + $(INSTALL_LIB) libfltk_gl.dll.a $(DESTDIR)$(libdir); \ + fi + if test x$(IMGDSONAME) = xlibfltk_images.so.1.3; then\ + $(RM) $(DESTDIR)$(libdir)/libfltk_images.so*;\ + $(INSTALL_LIB) libfltk_images.so.1.3 $(DESTDIR)$(libdir); \ + $(LN) libfltk_images.so.1.3 $(DESTDIR)$(libdir)/libfltk_images.so;\ + fi + if test x$(IMGDSONAME) = xlibfltk_images.sl.1.3; then\ + $(RM) $(DESTDIR)$(libdir)/libfltk_images.sl*;\ + $(INSTALL_LIB) libfltk_images.sl.1.3 $(DESTDIR)$(libdir); \ + $(LN) libfltk_images.sl.1.3 $(DESTDIR)$(libdir)/libfltk_images.sl;\ + fi + if test x$(IMGDSONAME) = xlibfltk_images.1.3.dylib; then\ + $(RM) $(DESTDIR)$(libdir)/libfltk_images.*dylib;\ + $(INSTALL_LIB) libfltk_images.1.3.dylib $(DESTDIR)$(libdir); \ + $(LN) libfltk_images.1.3.dylib $(DESTDIR)$(libdir)/libfltk_images.dylib;\ + fi + if test x$(IMGDSONAME) = xlibfltk_images_s.a; then\ + $(RM) $(DESTDIR)$(libdir)/libfltk_images_s.a;\ + $(INSTALL_LIB) libfltk_images_s.a $(DESTDIR)$(libdir); \ + fi + if test x$(IMGDSONAME) = xcygfltknox_images-1.3.dll; then\ + $(RM) $(DESTDIR)$(bindir)/$(IMGDSONAME); \ + $(INSTALL_LIB) $(IMGDSONAME) $(DESTDIR)$(bindir); \ + $(RM) $(DESTDIR)$(libdir)/libfltk_images.dll.a;\ + $(INSTALL_LIB) libfltk_images.dll.a $(DESTDIR)$(libdir); \ + fi + if test x$(IMGDSONAME) = xmgwfltknox_images-1.3.dll; then\ + $(RM) $(DESTDIR)$(bindir)/$(IMGDSONAME); \ + $(INSTALL_LIB) $(IMGDSONAME) $(DESTDIR)$(bindir); \ + $(RM) $(DESTDIR)$(libdir)/libfltk_images.dll.a;\ + $(INSTALL_LIB) libfltk_images.dll.a $(DESTDIR)$(libdir); \ + fi + + +uninstall: + echo "Uninstalling libraries..." + $(RM) $(DESTDIR)$(libdir)/$(LIBBASENAME) + if test x$(DSONAME) = xlibfltk.so.1.3; then\ + $(RM) $(DESTDIR)$(libdir)/libfltk.so*;\ + fi + if test x$(DSONAME) = xlibfltk.sl.1.3; then\ + $(RM) $(DESTDIR)$(libdir)/libfltk.sl*;\ + fi + if test x$(DSONAME) = xlibfltk.1.3.dylib; then\ + $(RM) $(DESTDIR)$(libdir)/libfltk.*dylib;\ + fi + if test x$(DSONAME) = xlibfltk_s.a; then\ + $(RM) $(DESTDIR)$(libdir)/libfltk_s.a;\ + fi + if test x$(DSONAME) = xcygfltknox-1.3.dll; then\ + $(RM) $(DESTDIR)$(bindir)/$(DSONAME); \ + $(RM) $(DESTDIR)$(libdir)/libfltk.dll.a;\ + fi + if test x$(DSONAME) = xcygfltk-1.3.dll; then\ + $(RM) $(DESTDIR)$(bindir)/$(DSONAME); \ + $(RM) $(DESTDIR)$(libdir)/libfltk.dll.a;\ + fi + if test x$(DSONAME) = xmgwfltknox-1.3.dll; then\ + $(RM) $(DESTDIR)$(bindir)/$(DSONAME); \ + $(RM) $(DESTDIR)$(libdir)/libfltk.dll.a;\ + fi + $(RM) $(DESTDIR)$(libdir)/$(FLLIBBASENAME); + if test x$(FLDSONAME) = xlibfltk_forms.so.1.3; then\ + $(RM) $(DESTDIR)$(libdir)/libfltk_forms.so*;\ + fi + if test x$(FLDSONAME) = xlibfltk_forms.sl.1.3; then\ + $(RM) $(DESTDIR)$(libdir)/libfltk_forms.sl*;\ + fi + if test x$(FLDSONAME) = xlibfltk_forms.1.3.dylib; then\ + $(RM) $(DESTDIR)$(libdir)/libfltk_forms.*dylib;\ + fi + if test x$(FLDSONAME) = xlibfltk_forms_s.a; then\ + $(RM) $(DESTDIR)$(libdir)/libfltk_forms_s.a;\ + fi + if test x$(FLDSONAME) = xcygfltknox_forms-1.3.dll; then\ + $(RM) $(DESTDIR)$(bindir)/$(FLDSONAME); \ + $(RM) $(DESTDIR)$(libdir)/libfltk_forms.dll.a;\ + fi + if test x$(FLDSONAME) = xcygfltk_forms-1.3.dll; then\ + $(RM) $(DESTDIR)$(bindir)/$(FLDSONAME); \ + $(RM) $(DESTDIR)$(libdir)/libfltk_forms.dll.a;\ + fi + if test x$(FLDSONAME) = xmgwfltknox_forms-1.3.dll; then\ + $(RM) $(DESTDIR)$(bindir)/$(FLDSONAME); \ + $(RM) $(DESTDIR)$(libdir)/libfltk_forms.dll.a;\ + fi + if test x$(GLLIBNAME) != x; then\ + $(RM) $(DESTDIR)$(libdir)/$(GLLIBBASENAME);\ + fi + if test x$(GLDSONAME) = xlibfltk_gl.so.1.3; then\ + $(RM) $(DESTDIR)$(libdir)/libfltk_gl.so*;\ + fi + if test x$(GLDSONAME) = xlibfltk_gl.sl.1.3; then\ + $(RM) $(DESTDIR)$(libdir)/libfltk_gl.sl*;\ + fi + if test x$(GLDSONAME) = xlibfltk_gl.1.3.dylib; then\ + $(RM) $(DESTDIR)$(libdir)/libfltk_gl.*dylib;\ + fi + if test x$(GLDSONAME) = xlibfltk_gl_s.a; then\ + $(RM) $(DESTDIR)$(libdir)/libfltk_gl_s.a;\ + fi + if test x$(GLDSONAME) = xcygfltknox_gl-1.3.dll; then\ + $(RM) $(DESTDIR)$(bindir)/$(GLDSONAME); \ + $(RM) $(DESTDIR)$(libdir)/libfltk_gl.dll.a;\ + fi + if test x$(GLDSONAME) = xcygfltk_gl-1.3.dll; then\ + $(RM) $(DESTDIR)$(bindir)/$(GLDSONAME); \ + $(RM) $(DESTDIR)$(libdir)/libfltk_gl.dll.a;\ + fi + if test x$(GLDSONAME) = xmgwfltknox_gl-1.3.dll; then\ + $(RM) $(DESTDIR)$(bindir)/$(GLDSONAME); \ + $(RM) $(DESTDIR)$(libdir)/libfltk_gl.dll.a;\ + fi + if test x$(IMGLIBNAME) != x; then\ + $(RM) $(DESTDIR)$(libdir)/$(IMGLIBBASENAME);\ + fi + if test x$(IMGDSONAME) = xlibfltk_images.so.1.3; then\ + $(RM) $(DESTDIR)$(libdir)/libfltk_images.so*;\ + fi + if test x$(IMGDSONAME) = xlibfltk_images.sl.1.3; then\ + $(RM) $(DESTDIR)$(libdir)/libfltk_images.sl*;\ + fi + if test x$(IMGDSONAME) = xlibfltk_images.1.3.dylib; then\ + $(RM) $(DESTDIR)$(libdir)/libfltk_images.*dylib;\ + fi + if test x$(IMGDSONAME) = xlibfltk_images_s.a; then\ + $(RM) $(DESTDIR)$(libdir)/libfltk_images_s.a;\ + fi + if test x$(IMGDSONAME) = xcygfltknox_images-1.3.dll; then\ + $(RM) $(DESTDIR)$(bindir)/$(IMGDSONAME); \ + $(RM) $(DESTDIR)$(libdir)/libfltk_images.dll.a;\ + fi + if test x$(IMGDSONAME) = xcygfltk_images-1.3.dll; then\ + $(RM) $(DESTDIR)$(bindir)/$(IMGDSONAME); \ + $(RM) $(DESTDIR)$(libdir)/libfltk_images.dll.a;\ + fi + if test x$(IMGDSONAME) = xmgwfltknox_images-1.3.dll; then\ + $(RM) $(DESTDIR)$(bindir)/$(IMGDSONAME); \ + $(RM) $(DESTDIR)$(libdir)/libfltk_images.dll.a;\ + fi + +# +# End of "$Id: Makefile 7906 2010-11-28 21:28:30Z matt $". +# diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/aimm.h b/mod/maxgui.mod/fltkmaxgui.mod/src/aimm.h new file mode 100644 index 0000000..64ed66f --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/aimm.h @@ -0,0 +1,431 @@ +// +// "$Id: aimm.h 6943 2009-11-18 12:43:21Z AlbrechtS $" +// +// Standard dialog header file for the UTF-8 Fast Light Tool Kit (FLTK-UTF8). +// +// Copyright 2009 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version +// with exceptions that allow sub-classing and static linking in +// non-LGPL compliant software. These exceptions are subject to +// conditions, see the FLTK License for more details. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the FLTK +// License for more details. +// +// You should have received a copy of the FLTK License along with +// this library; if not, write to OksiD Software, Jean-Marc Lienher, +// Rue de la Cheminee 1, CH-2065 Savagnier, Switzerland. +// +// Please report all bugs and problems to "oksid@bluewin.ch". +// + +#ifndef AIMM_H +# define AIMM_H +//# define HANDLE_PTR HANDLE* +//# define DWORD_PTR DWORD* +//# define CLSCTX_INPROC_SERVER 0x1 +const GUID IID_IActiveIMMApp = { 0x8c0e040, 0x62d1, 0x11d1, {0x93, 0x26, 0x00, 0x60, 0xb0, 0x67, 0xb8, 0x6e}}; +const GUID CLSID_CActiveIMM = { 0x4955dd33, 0xb159, 0x11d0, {0x8f, 0xcf, 0x00, 0xaa, 0x00, 0x6b, 0xcc, 0x59}}; +/* + class IUnknown + { + public: + + virtual long __stdcall QueryInterface( + const GUID & riid, + void **ppvObject) = 0; + + virtual ULONG __stdcall AddRef( void) = 0; + + virtual ULONG __stdcall Release( void) = 0; + }; + +extern "C" __declspec(dllimport) long __stdcall CoInitialize(void far *pvReserved); +extern "C" __declspec(dllimport) long __stdcall CoCreateInstance(const GUID & rclsid, IUnknown * pUnkOuter, + DWORD dwClsContext, const GUID & riid, LPVOID FAR* ppv); + +*/ + + class IActiveIMMApp : public IUnknown + { + public: + virtual long __stdcall AssociateContext( + HWND hWnd, + HIMC hIME, + HIMC *phPrev) = 0; + + virtual long __stdcall ConfigureIMEA( + HKL hKL, + HWND hWnd, + DWORD dwMode, + void *pData) = 0; + + virtual long __stdcall ConfigureIMEW( + HKL hKL, + HWND hWnd, + DWORD dwMode, + void *pData) = 0; + + virtual long __stdcall CreateContext( + HIMC *phIMC) = 0; + + virtual long __stdcall DestroyContext( + HIMC hIME) = 0; + + virtual long __stdcall EnumRegisterWordA( + HKL hKL, + LPSTR szReading, + DWORD dwStyle, + LPSTR szRegister, + LPVOID pData, + void **pEnum) = 0; + + virtual long __stdcall EnumRegisterWordW( + HKL hKL, + LPWSTR szReading, + DWORD dwStyle, + LPWSTR szRegister, + LPVOID pData, + void **pEnum) = 0; + + virtual long __stdcall EscapeA( + HKL hKL, + HIMC hIMC, + UINT uEscape, + /* [out][in] */ LPVOID pData, + LRESULT *plResult) = 0; + + virtual long __stdcall EscapeW( + HKL hKL, + HIMC hIMC, + UINT uEscape, + /* [out][in] */ LPVOID pData, + LRESULT *plResult) = 0; + + virtual long __stdcall GetCandidateListA( + HIMC hIMC, + DWORD dwIndex, + UINT uBufLen, + void *pCandList, + UINT *puCopied) = 0; + + virtual long __stdcall GetCandidateListW( + HIMC hIMC, + DWORD dwIndex, + UINT uBufLen, + void *pCandList, + UINT *puCopied) = 0; + + virtual long __stdcall GetCandidateListCountA( + HIMC hIMC, + DWORD *pdwListSize, + DWORD *pdwBufLen) = 0; + + virtual long __stdcall GetCandidateListCountW( + HIMC hIMC, + DWORD *pdwListSize, + DWORD *pdwBufLen) = 0; + + virtual long __stdcall GetCandidateWindow( + HIMC hIMC, + DWORD dwIndex, + void *pCandidate) = 0; + + virtual long __stdcall GetCompositionFontA( + HIMC hIMC, + LOGFONTA *plf) = 0; + + virtual long __stdcall GetCompositionFontW( + HIMC hIMC, + LOGFONTW *plf) = 0; + + virtual long __stdcall GetCompositionStringA( + HIMC hIMC, + DWORD dwIndex, + DWORD dwBufLen, + LONG *plCopied, + LPVOID pBuf) = 0; + + virtual long __stdcall GetCompositionStringW( + HIMC hIMC, + DWORD dwIndex, + DWORD dwBufLen, + LONG *plCopied, + LPVOID pBuf) = 0; + + virtual long __stdcall GetCompositionWindow( + HIMC hIMC, + void *pCompForm) = 0; + + virtual long __stdcall GetContext( + HWND hWnd, + HIMC *phIMC) = 0; + + virtual long __stdcall GetConversionListA( + HKL hKL, + HIMC hIMC, + LPSTR pSrc, + UINT uBufLen, + UINT uFlag, + void *pDst, + UINT *puCopied) = 0; + + virtual long __stdcall GetConversionListW( + HKL hKL, + HIMC hIMC, + LPWSTR pSrc, + UINT uBufLen, + UINT uFlag, + void *pDst, + UINT *puCopied) = 0; + + virtual long __stdcall GetConversionStatus( + HIMC hIMC, + DWORD *pfdwConversion, + DWORD *pfdwSentence) = 0; + + virtual long __stdcall GetDefaultIMEWnd( + HWND hWnd, + HWND *phDefWnd) = 0; + + virtual long __stdcall GetDescriptionA( + HKL hKL, + UINT uBufLen, + LPSTR szDescription, + UINT *puCopied) = 0; + + virtual long __stdcall GetDescriptionW( + HKL hKL, + UINT uBufLen, + LPWSTR szDescription, + UINT *puCopied) = 0; + + virtual long __stdcall GetGuideLineA( + HIMC hIMC, + DWORD dwIndex, + DWORD dwBufLen, + LPSTR pBuf, + DWORD *pdwResult) = 0; + + virtual long __stdcall GetGuideLineW( + HIMC hIMC, + DWORD dwIndex, + DWORD dwBufLen, + LPWSTR pBuf, + DWORD *pdwResult) = 0; + + virtual long __stdcall GetIMEFileNameA( + HKL hKL, + UINT uBufLen, + LPSTR szFileName, + UINT *puCopied) = 0; + + virtual long __stdcall GetIMEFileNameW( + HKL hKL, + UINT uBufLen, + LPWSTR szFileName, + UINT *puCopied) = 0; + + virtual long __stdcall GetOpenStatus( + HIMC hIMC) = 0; + + virtual long __stdcall GetProperty( + HKL hKL, + DWORD fdwIndex, + DWORD *pdwProperty) = 0; + + virtual long __stdcall GetRegisterWordStyleA( + HKL hKL, + UINT nItem, + STYLEBUFA *pStyleBuf, + UINT *puCopied) = 0; + + virtual long __stdcall GetRegisterWordStyleW( + HKL hKL, + UINT nItem, + STYLEBUFW *pStyleBuf, + UINT *puCopied) = 0; + + virtual long __stdcall GetStatusWindowPos( + HIMC hIMC, + POINT *pptPos) = 0; + + virtual long __stdcall GetVirtualKey( + HWND hWnd, + UINT *puVirtualKey) = 0; + + virtual long __stdcall InstallIMEA( + LPSTR szIMEFileName, + LPSTR szLayoutText, + HKL *phKL) = 0; + + virtual long __stdcall InstallIMEW( + LPWSTR szIMEFileName, + LPWSTR szLayoutText, + HKL *phKL) = 0; + + virtual long __stdcall IsIME( + HKL hKL) = 0; + + virtual long __stdcall IsUIMessageA( + HWND hWndIME, + UINT msg, + WPARAM wParam, + LPARAM lParam) = 0; + + virtual long __stdcall IsUIMessageW( + HWND hWndIME, + UINT msg, + WPARAM wParam, + LPARAM lParam) = 0; + + virtual long __stdcall NotifyIME( + HIMC hIMC, + DWORD dwAction, + DWORD dwIndex, + DWORD dwValue) = 0; + + virtual long __stdcall RegisterWordA( + HKL hKL, + LPSTR szReading, + DWORD dwStyle, + LPSTR szRegister) = 0; + + virtual long __stdcall RegisterWordW( + HKL hKL, + LPWSTR szReading, + DWORD dwStyle, + LPWSTR szRegister) = 0; + + virtual long __stdcall ReleaseContext( + HWND hWnd, + HIMC hIMC) = 0; + + virtual long __stdcall SetCandidateWindow( + HIMC hIMC, + void *pCandidate) = 0; + + virtual long __stdcall SetCompositionFontA( + HIMC hIMC, + LOGFONTA *plf) = 0; + + virtual long __stdcall SetCompositionFontW( + HIMC hIMC, + LOGFONTW *plf) = 0; + + virtual long __stdcall SetCompositionStringA( + HIMC hIMC, + DWORD dwIndex, + LPVOID pComp, + DWORD dwCompLen, + LPVOID pRead, + DWORD dwReadLen) = 0; + + virtual long __stdcall SetCompositionStringW( + HIMC hIMC, + DWORD dwIndex, + LPVOID pComp, + DWORD dwCompLen, + LPVOID pRead, + DWORD dwReadLen) = 0; + + virtual long __stdcall SetCompositionWindow( + HIMC hIMC, + void *pCompForm) = 0; + + virtual long __stdcall SetConversionStatus( + HIMC hIMC, + DWORD fdwConversion, + DWORD fdwSentence) = 0; + + virtual long __stdcall SetOpenStatus( + HIMC hIMC, + BOOL fOpen) = 0; + + virtual long __stdcall SetStatusWindowPos( + HIMC hIMC, + POINT *pptPos) = 0; + + virtual long __stdcall SimulateHotKey( + HWND hWnd, + DWORD dwHotKeyID) = 0; + + virtual long __stdcall UnregisterWordA( + HKL hKL, + LPSTR szReading, + DWORD dwStyle, + LPSTR szUnregister) = 0; + + virtual long __stdcall UnregisterWordW( + HKL hKL, + LPWSTR szReading, + DWORD dwStyle, + LPWSTR szUnregister) = 0; + + virtual long __stdcall Activate( + BOOL fRestoreLayout) = 0; + + virtual long __stdcall Deactivate( void) = 0; + + virtual long __stdcall OnDefWindowProc( + HWND hWnd, + UINT Msg, + WPARAM wParam, + LPARAM lParam, + LRESULT *plResult) = 0; + + virtual long __stdcall FilterClientWindows( + ATOM *aaClassList, + UINT uSize) = 0; + + virtual long __stdcall GetCodePageA( + HKL hKL, + UINT *uCodePage) = 0; + + virtual long __stdcall GetLangId( + HKL hKL, + WORD *plid) = 0; + + virtual long __stdcall AssociateContextEx( + HWND hWnd, + HIMC hIMC, + DWORD dwFlags) = 0; + + virtual long __stdcall DisableIME( + DWORD idThread) = 0; + + virtual long __stdcall GetImeMenuItemsA( + HIMC hIMC, + DWORD dwFlags, + DWORD dwType, + void *pImeParentMenu, + void *pImeMenu, + DWORD dwSize, + DWORD *pdwResult) = 0; + + virtual long __stdcall GetImeMenuItemsW( + HIMC hIMC, + DWORD dwFlags, + DWORD dwType, + void *pImeParentMenu, + void *pImeMenu, + DWORD dwSize, + DWORD *pdwResult) = 0; + + virtual long __stdcall EnumInputContext( + DWORD idThread, + void **ppEnum) = 0; + + }; + +#endif + +// +// End of "$Id: aimm.h 6943 2009-11-18 12:43:21Z AlbrechtS $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/allfiles.xbm b/mod/maxgui.mod/fltkmaxgui.mod/src/allfiles.xbm new file mode 100644 index 0000000..26373b6 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/allfiles.xbm @@ -0,0 +1,6 @@ +#define allfiles_width 16 +#define allfiles_height 16 +static unsigned char allfiles_bits[] = { + 0xfc, 0x3f, 0x04, 0x20, 0x04, 0x20, 0x04, 0x20, 0x84, 0x21, 0xa4, 0x25, + 0xc4, 0x23, 0xf4, 0x2f, 0xf4, 0x2f, 0xc4, 0x23, 0xa4, 0x25, 0x84, 0x21, + 0x04, 0x20, 0x04, 0x20, 0x04, 0x20, 0xfc, 0x3f}; diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/cgdebug.h b/mod/maxgui.mod/fltkmaxgui.mod/src/cgdebug.h new file mode 100644 index 0000000..777fcc8 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/cgdebug.h @@ -0,0 +1,215 @@ +// +// "$Id: cgdebug.h 6951 2009-12-06 22:21:55Z matt $" +// +// OS X Core Graphics debugging help for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2009 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// This file allows easier debugging of Mac OS X Core Graphics +// code. This file is normally not included into any FLTK builds, +// but since it has proven to be tremendously useful in debugging +// the FLTK port to "Quartz", I decided to add this file in case +// more bugs show up. +// +// This header is activated by adding the following +// line to "config.h" +// #include "src/cgdebug.h" +// +// Running "./configure" will remove this line from "config.h". +// +// When used erreanously, Core Graphics prints warnings to +// stderr. This is helpful, however it is not possible to +// associate a line number or source file with the warning message. +// This headr file outputs a trace of CG calls, interweaveing +// them with CG warnings. +// +// Matthias + +#ifndef CGDEBUG +#define CGDEBUG + +#include +#include + +//+BitmapContextCreate +//+BitmapContextGetData +// ClipCGContextToRegion +// QDBeginCGContext +// QDEndCGContext + +//+AddArc +//+AddLineToPoint +// ClipToRect +// ClosePath +//+ConcatCTM +//+DrawImage +// FillPath +// FillRect +// Flush +//+GetCTM +// MoveToPoint +//+Release +// RestoreGState +// SaveGState +//+ScaleCTM +//+SetLineCap +//+SetLineDash +//+SetLineJoin +//+SetLineWidth +//+SetRGBFillColor +//+SetRGBStrokeColor +//+SetShouldAntialias +//+SetTextMatrix +//+StrokePath +//+TranslateCTM + +inline OSStatus dbgLocation(const char *file, int line) +{ + fprintf(stderr, "%s:%d ", file, line); + return 0; +} + +inline OSStatus dbgEndl() +{ + fprintf(stderr, "\n"); + return 0; +} + + +inline void dbgCGContextClipToRect(CGContextRef a, CGRect b) +{ + CGContextClipToRect(a, b); +} + +#define CGContextClipToRect(a, b) { \ + fprintf(stderr, "%s:%d ", __FILE__, __LINE__); \ + dbgCGContextClipToRect(a, b); \ + fprintf(stderr, "\n"); } + +inline void dbgCGContextFillRect(CGContextRef a, CGRect b) +{ + CGContextFillRect(a, b); +} + +#define CGContextFillRect(a, b) { \ + fprintf(stderr, "%s:%d ", __FILE__, __LINE__); \ + dbgCGContextFillRect(a, b); \ + fprintf(stderr, "\n"); } + +inline OSStatus dbgQDEndCGContext(CGrafPtr a, CGContextRef *b) +{ + return QDEndCGContext(a, b); +} + +#define QDEndCGContext(a, b) ( \ + dbgLocation(__FILE__, __LINE__) + \ + dbgQDEndCGContext(a, b) + \ + dbgEndl() ) + +inline OSStatus dbgQDBeginCGContext(CGrafPtr a, CGContextRef *b) +{ + return QDBeginCGContext(a, b); +} + +#define QDBeginCGContext(a, b) ( \ + dbgLocation(__FILE__, __LINE__) + \ + dbgQDBeginCGContext(a, b) + \ + dbgEndl() ) + +inline void dbgClipCGContextToRegion(CGContextRef a, const Rect *b, RgnHandle c) +{ + ClipCGContextToRegion(a, b, c); +} + +#define ClipCGContextToRegion(a, b, c) { \ + fprintf(stderr, "%s:%d ", __FILE__, __LINE__); \ + dbgClipCGContextToRegion(a, b, c); \ + fprintf(stderr, "\n"); } + +inline void dbgCGContextMoveToPoint(CGContextRef context, float x, float y) +{ + CGContextMoveToPoint(context, x, y); +} + +#define CGContextMoveToPoint(a, b, c) { \ + fprintf(stderr, "%s:%d ", __FILE__, __LINE__); \ + dbgCGContextMoveToPoint(a, b, c); \ + fprintf(stderr, "\n"); } + +inline void dbgCGContextFillPath(CGContextRef context) +{ + CGContextFillPath(context); +} + +#define CGContextFillPath(a) { \ + fprintf(stderr, "%s:%d ", __FILE__, __LINE__); \ + dbgCGContextFillPath(a); \ + fprintf(stderr, "\n"); } + +inline void dbgCGContextClosePath(CGContextRef context) +{ + CGContextClosePath(context); +} + +#define CGContextClosePath(a) { \ + fprintf(stderr, "%s:%d ", __FILE__, __LINE__); \ + dbgCGContextClosePath(a); \ + fprintf(stderr, "\n"); } + +inline void dbgCGContextFlush(CGContextRef context) +{ + CGContextFlush(context); +} + +#define CGContextFlush(a) { \ + fprintf(stderr, "%s:%d ", __FILE__, __LINE__); \ + dbgCGContextFlush(a); \ + fprintf(stderr, "\n"); } + +inline void dbgCGContextSaveGState(CGContextRef context) +{ + CGContextSaveGState(context); +} + +#define CGContextSaveGState(a) { \ + fprintf(stderr, "%s:%d ", __FILE__, __LINE__); \ + dbgCGContextSaveGState(a); \ + fprintf(stderr, "\n"); } + +inline void dbgCGContextRestoreGState(CGContextRef context) +{ + CGContextRestoreGState(context); +} + +#define CGContextRestoreGState(a) { \ + fprintf(stderr, "%s:%d ", __FILE__, __LINE__); \ + dbgCGContextRestoreGState(a); \ + fprintf(stderr, "\n"); } + + +#endif + +// +// End of "$Id: cgdebug.h 6951 2009-12-06 22:21:55Z matt $". +// + diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/cmap.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/cmap.cxx new file mode 100644 index 0000000..8bd489e --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/cmap.cxx @@ -0,0 +1,181 @@ +// +// "$Id: cmap.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Colormap generation program for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// This program produces the contents of "fl_cmap.h" as stdout + +// #include +#include + +// This table is initialized with color values I got by reading the +// colormap on an IRIX 4.3 machine: + +// "full intensity colors" have been turned down some to make white +// background less intense by default. The hope is that this will make +// fltk programs more friendly on color-adjusted screens. If you want +// pure colors you should get them out of the colormap. + +//#define III 244 // maximum intensity of the basic colors + +// that results in errors and unshared colormap entries, so full intensity: +#define III 255 // maximum intensity of the basic colors + +static short cmap[256][3] = { +// 3-bit colormap: + { 0, 0, 0}, // black + {III, 0, 0}, // red + { 0,III, 0}, // green + {III,III, 0}, // yellow + { 0, 0,III}, // blue + {III, 0,III}, // magenta + { 0,III,III}, // cyan + {III,III,III}, // white +// pastel versions of those colors, from SGI's standard color map: + { 85, 85, 85}, // 1/3 gray + {198,113,113}, // salmon? pale red? + {113,198,113}, // pale green + {142,142, 56}, // khaki + {113,113,198}, // pale blue + {142, 56,142}, // purple, orchid, pale magenta + { 56,142,142}, // cadet blue, aquamarine, pale cyan +// The next location is used for FL_SELECTION_COLOR. It formerly was 2/3 gray +// but this is changed to be the Windows blue color. This allows the default +// behavior on both X and Windows to match: + { 0, 0,128}, +//{170,170,170}, // old 2/3 gray color +// These next 16 are the FL_FREE_COLOR area. In some versions of fltk +// these were filled with random colors that a Irix 5.3 machine placed +// in these locations. Other versions of fltk filled this with the 1/3 +// gray above to discourage their use. This newest version uses colors +// that NewTek has assigned for their GUI: +#if 0 + // The Irix 5.3 colors: + { 16, 16, 16}, + {128, 40,128}, + {198, 30, 30}, + { 66, 30, 30}, + {176,140,140}, + { 0, 20, 20}, + { 20, 10, 10}, + { 40, 20, 20}, + { 60, 30, 30}, + { 0, 80, 80}, + { 0, 40, 40}, + { 20, 20, 0}, + { 40, 40, 0}, + { 80, 80, 10}, + {150,150, 20}, + {160, 10, 10}, +#else + // The NewTek colors: (from George Yohng) + {168,168,152}, + {232,232,216}, + {104,104, 88}, + {152,168,168}, + {216,232,232}, + { 88,104,104}, + {156,156,168}, + {220,220,232}, + { 92, 92,104}, + {156,168,156}, + {220,232,220}, + { 92,104, 92}, + {144,144,144}, + {192,192,192}, + { 80, 80, 80}, + {160,160,160}, +#endif +// The rest of the colormap is a gray ramp and table, filled in below: +}; + +// This is Fl::background from Fl_get_system_colors.cxx, with modifications: + +#define FL_GRAY_RAMP 32 +#define FL_NUM_GRAY 24 +#define FL_GRAY 49 // old value is 47 +typedef unsigned char uchar; +#include + +void background(uchar r, uchar g, uchar b) { + // replace the gray ramp so that color 47 (by default 2/3) is this color + if (!r) r = 1; else if (r==255) r = 254; + double powr = log(r/255.0)/log((FL_GRAY-FL_GRAY_RAMP)/(FL_NUM_GRAY-1.0)); + if (!g) g = 1; else if (g==255) g = 254; + double powg = log(g/255.0)/log((FL_GRAY-FL_GRAY_RAMP)/(FL_NUM_GRAY-1.0)); + if (!b) b = 1; else if (b==255) b = 254; + double powb = log(b/255.0)/log((FL_GRAY-FL_GRAY_RAMP)/(FL_NUM_GRAY-1.0)); + for (int i = 0; i < FL_NUM_GRAY; i++) { + double gray = i/(FL_NUM_GRAY-1.0); + cmap[i+FL_GRAY_RAMP][0] = uchar(pow(gray,powr)*255+.5); + cmap[i+FL_GRAY_RAMP][1] = uchar(pow(gray,powg)*255+.5); + cmap[i+FL_GRAY_RAMP][2] = uchar(pow(gray,powb)*255+.5); + } +} + +int main() { + int i,r,g,b; +#if 0 + /* Read colormap colors into internal table */ + long cmwin; + noport(); + cmwin = winopen("CM"); + for (i=0; i<256; i++) + getmcolor(i,&cmap[i][0],&cmap[i][1],&cmap[i][2]); + winclose(cmwin); +#endif +// overwrite the X allocation area with one color so people are +// discouraged from using it: + //for (i=16; i<32; i++) {cmap[i][0]=cmap[i][1]=cmap[i][2] = 85;} + + // fill in the gray ramp: + background(0xc0, 0xc0, 0xc0); // microsoft colors + // background(170, 170, 170); // old fltk colors + // copy the 1/3 and 2/3 gray to the closest locations in gray ramp: + cmap[39][0] = cmap[39][1] = cmap[39][2] = 85; + cmap[47][0] = cmap[47][1] = cmap[47][2] = 170; + + // fill in the color cube + i = 56; + for (b=0; b<5; b++) + for (r=0; r<5; r++) + for (g=0; g<8; g++) { + cmap[i][0] = r*255/4; + cmap[i][1] = g*255/7; + cmap[i][2] = b*255/4; + i++; + } + + for (i=0; i<256; i++) { + printf("\t0x%02x%02x%02x00",cmap[i][0],cmap[i][1],cmap[i][2]); + if (i < 255) printf(",\n"); + } + printf("\n"); + return 0; +} + +// +// End of "$Id: cmap.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/d1.xbm b/mod/maxgui.mod/fltkmaxgui.mod/src/d1.xbm new file mode 100644 index 0000000..a0e67f0 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/d1.xbm @@ -0,0 +1,6 @@ +#define d1_width 16 +#define d1_height 16 +static unsigned char d1_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x38, 0x00, 0x78, 0x00, + 0xe8, 0x00, 0xc0, 0x01, 0x80, 0x03, 0x00, 0x17, 0x00, 0x1e, 0x00, 0x1c, + 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/d1_mask.xbm b/mod/maxgui.mod/fltkmaxgui.mod/src/d1_mask.xbm new file mode 100644 index 0000000..6b1e14d --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/d1_mask.xbm @@ -0,0 +1,6 @@ +#define d1_mask_width 16 +#define d1_mask_height 16 +static unsigned char d1_mask_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0xfc, 0x00, 0x7c, 0x00, 0xfc, 0x00, + 0xfc, 0x01, 0xec, 0x03, 0xc0, 0x37, 0x80, 0x3f, 0x00, 0x3f, 0x00, 0x3e, + 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00}; diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/dump_compose.c b/mod/maxgui.mod/fltkmaxgui.mod/src/dump_compose.c new file mode 100644 index 0000000..fe41991 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/dump_compose.c @@ -0,0 +1,26 @@ +/* write out the documentation for the compose key */ + +/* copy the string from Fl_Input.C */ +static const char* const compose_pairs = +" ! @ # $ y=| & : c a <<~ - r _ * +-2 3 ' u p . , 1 o >>141234? " +"A`A'A^A~A:A*AEC,E`E'E^E:I`I'I^I:D-N~O`O'O^O~O:x O/U`U'U^U:Y'DDss" +"a`a'a^a~a:a*aec,e`e'e^e:i`i'i^i:d-n~o`o'o^o~o:-:o/u`u'u^u:y'ddy:"; + +#include + +int main() { + int x,y; + for (x = 0; x<16; x++) { + for (y = 0; y<6; y++) { + const char *p = compose_pairs + (16*y+x)*2; + if (p[1] == ' ') + printf("

    • "); + } + return 0; +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/ew.xbm b/mod/maxgui.mod/fltkmaxgui.mod/src/ew.xbm new file mode 100644 index 0000000..1ff835c --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/ew.xbm @@ -0,0 +1,8 @@ +#define ew_width 16 +#define ew_height 16 +#define ew_x_hot 8 +#define ew_y_hot 8 +static unsigned char ew_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, + 0x0c, 0x30, 0xfe, 0x7f, 0xfe, 0x7f, 0x0c, 0x30, 0x08, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/ew_mask.xbm b/mod/maxgui.mod/fltkmaxgui.mod/src/ew_mask.xbm new file mode 100644 index 0000000..49dc1df --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/ew_mask.xbm @@ -0,0 +1,8 @@ +#define ew_mask_width 16 +#define ew_mask_height 16 +#define ew_mask_x_hot 8 +#define ew_mask_y_hot 8 +static unsigned char ew_mask_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x1c, 0x38, + 0xfe, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0x1c, 0x38, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fastarrow.h b/mod/maxgui.mod/fltkmaxgui.mod/src/fastarrow.h new file mode 100644 index 0000000..e381acd --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fastarrow.h @@ -0,0 +1,6 @@ +#define fastarrow_width 16 +#define fastarrow_height 16 +static unsigned char fastarrow_bits[] = { + 0x00, 0x00, 0x00, 0x07, 0xe0, 0x07, 0xfc, 0x03, 0xff, 0xff, 0xfc, 0x03, + 0xe0, 0x07, 0x00, 0x07, 0xe0, 0x00, 0xe0, 0x07, 0xc0, 0x3f, 0xff, 0xff, + 0xc0, 0x3f, 0xe0, 0x07, 0xe0, 0x00, 0x00, 0x00}; diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/filename_absolute.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/filename_absolute.cxx new file mode 100644 index 0000000..8cd8125 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/filename_absolute.cxx @@ -0,0 +1,237 @@ +// +// "$Id: filename_absolute.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Filename expansion routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* expand a file name by prepending current directory, deleting . and + .. (not really correct for symbolic links) between the prepended + current directory. Use $PWD if it exists. + Returns true if any changes were made. +*/ + +#include +#include +#include +#include "flstring.h" +#include +#if defined(WIN32) && !defined(__CYGWIN__) +# include +#else +# include +#endif + +#if defined(WIN32) || defined(__EMX__) && !defined(__CYGWIN__) +inline int isdirsep(char c) {return c=='/' || c=='\\';} +#else +#define isdirsep(c) ((c)=='/') +#endif + +/** Makes a filename absolute from a relative filename. + \code + #include + [..] + chdir("/var/tmp"); + fl_filename_absolute(out, sizeof(out), "foo.txt"); // out="/var/tmp/foo.txt" + fl_filename_absolute(out, sizeof(out), "./foo.txt"); // out="/var/tmp/foo.txt" + fl_filename_absolute(out, sizeof(out), "../log/messages"); // out="/var/log/messages" + \endcode + \param[out] to resulting absolute filename + \param[in] tolen size of the absolute filename buffer + \param[in] from relative filename + \return 0 if no change, non zero otherwise + */ +int fl_filename_absolute(char *to, int tolen, const char *from) { + if (isdirsep(*from) || *from == '|' +#if defined(WIN32) || defined(__EMX__) && !defined(__CYGWIN__) + || from[1]==':' +#endif + ) { + strlcpy(to, from, tolen); + return 0; + } + + char *a; + char *temp = new char[tolen]; + const char *start = from; + + a = fl_getcwd(temp, tolen); + if (!a) { + strlcpy(to, from, tolen); + delete[] temp; + return 0; + } +#if defined(WIN32) || defined(__EMX__) && !defined(__CYGWIN__) + for (a = temp; *a; a++) if (*a=='\\') *a = '/'; // ha ha +#else + a = temp+strlen(temp); +#endif + if (isdirsep(*(a-1))) a--; + /* remove intermediate . and .. names: */ + while (*start == '.') { + if (start[1]=='.' && isdirsep(start[2])) { + char *b; + for (b = a-1; b >= temp && !isdirsep(*b); b--); + if (b < temp) break; + a = b; + start += 3; + } else if (isdirsep(start[1])) { + start += 2; + } else if (!start[1]) { + start ++; // Skip lone "." + break; + } else + break; + } + + *a++ = '/'; + strlcpy(a,start,tolen - (a - temp)); + + strlcpy(to, temp, tolen); + + delete[] temp; + + return 1; +} + +/** Makes a filename relative to the current working directory. + \code + #include + [..] + chdir("/var/tmp/somedir"); // set cwd to /var/tmp/somedir + [..] + char out[1024]; + fl_filename_relative(out, sizeof(out), "/var/tmp/somedir/foo.txt"); // out="foo.txt", return=1 + fl_filename_relative(out, sizeof(out), "/var/tmp/foo.txt"); // out="../foo.txt", return=1 + fl_filename_relative(out, sizeof(out), "foo.txt"); // out="foo.txt", return=0 (no change) + fl_filename_relative(out, sizeof(out), "./foo.txt"); // out="./foo.txt", return=0 (no change) + fl_filename_relative(out, sizeof(out), "../foo.txt"); // out="../foo.txt", return=0 (no change) + \endcode + \param[out] to resulting relative filename + \param[in] tolen size of the relative filename buffer + \param[in] from absolute filename + \return 0 if no change, non zero otherwise + */ +int // O - 0 if no change, 1 if changed +fl_filename_relative(char *to, // O - Relative filename + int tolen, // I - Size of "to" buffer + const char *from) {// I - Absolute filename + char *newslash; // Directory separator + const char *slash; // Directory separator + char cwd_buf[1024]; // Current directory + char *cwd = cwd_buf; + + + // return if "from" is not an absolute path +#if defined(WIN32) || defined(__EMX__) + if (from[0] == '\0' || + (!isdirsep(*from) && !isalpha(*from) && from[1] != ':' && + !isdirsep(from[2]))) { +#else + if (from[0] == '\0' || !isdirsep(*from)) { +#endif // WIN32 || __EMX__ + strlcpy(to, from, tolen); + return 0; + } + + // get the current directory and return if we can't + if (!fl_getcwd(cwd_buf, sizeof(cwd_buf))) { + strlcpy(to, from, tolen); + return 0; + } + +#if defined(WIN32) || defined(__EMX__) + // convert all backslashes into forward slashes + for (newslash = strchr(cwd, '\\'); newslash; newslash = strchr(newslash + 1, '\\')) + *newslash = '/'; + + // test for the exact same string and return "." if so + if (!strcasecmp(from, cwd)) { + strlcpy(to, ".", tolen); + return (1); + } + + // test for the same drive. Return the absolute path if not + if (tolower(*from & 255) != tolower(*cwd & 255)) { + // Not the same drive... + strlcpy(to, from, tolen); + return 0; + } + + // compare the path name without the drive prefix + from += 2; cwd += 2; +#else + // test for the exact same string and return "." if so + if (!strcmp(from, cwd)) { + strlcpy(to, ".", tolen); + return (1); + } +#endif // WIN32 || __EMX__ + + // compare both path names until we find a difference + for (slash = from, newslash = cwd; + *slash != '\0' && *newslash != '\0'; + slash ++, newslash ++) + if (isdirsep(*slash) && isdirsep(*newslash)) continue; +#if defined(WIN32) || defined(__EMX__) || defined(__APPLE__) + else if (tolower(*slash & 255) != tolower(*newslash & 255)) break; +#else + else if (*slash != *newslash) break; +#endif // WIN32 || __EMX__ || __APPLE__ + + // skip over trailing slashes + if ( *newslash == '\0' && *slash != '\0' && !isdirsep(*slash) + &&(newslash==cwd || !isdirsep(newslash[-1])) ) + newslash--; + + // now go back to the first character of the first differing paths segment + while (!isdirsep(*slash) && slash > from) slash --; + if (isdirsep(*slash)) slash ++; + + // do the same for the current dir + if (isdirsep(*newslash)) newslash --; + if (*newslash != '\0') + while (!isdirsep(*newslash) && newslash > cwd) newslash --; + + // prepare the destination buffer + to[0] = '\0'; + to[tolen - 1] = '\0'; + + // now add a "previous dir" sequence for every following slash in the cwd + while (*newslash != '\0') { + if (isdirsep(*newslash)) strlcat(to, "../", tolen); + + newslash ++; + } + + // finally add the differing path from "from" + strlcat(to, slash, tolen); + + return 1; +} + + +// +// End of "$Id: filename_absolute.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/filename_expand.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/filename_expand.cxx new file mode 100644 index 0000000..2591ec4 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/filename_expand.cxx @@ -0,0 +1,134 @@ +// +// "$Id: filename_expand.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Filename expansion routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* expand a file name by substuting environment variables and + home directories. Returns true if any changes were made. + to & from may be the same buffer. +*/ + +#include +#include +#include +#include "flstring.h" +#if defined(WIN32) && !defined(__CYGWIN__) +#include +#else +# include +# include +#endif + +#if defined(WIN32) || defined(__EMX__) && !defined(__CYGWIN__) +static inline int isdirsep(char c) {return c=='/' || c=='\\';} +#else +#define isdirsep(c) ((c)=='/') +#endif + +/** Expands a filename containing shell variables and tilde (~). + Currently handles these variants: + \code + "~username" // if 'username' does not exist, result will be unchanged + "~/file" + "$VARNAME" // does NOT handle ${VARNAME} + \endcode + + \b Examples: + \code + #include + [..] + putenv("TMPDIR=/var/tmp"); + fl_filename_expand(out, sizeof(out), "~fred/.cshrc"); // out="/usr/fred/.cshrc" + fl_filename_expand(out, sizeof(out), "~/.cshrc"); // out="/usr//.cshrc" + fl_filename_expand(out, sizeof(out), "$TMPDIR/foo.txt"); // out="/var/tmp/foo.txt" + \endcode + \param[out] to resulting expanded filename + \param[in] tolen size of the expanded filename buffer + \param[in] from filename containing shell variables + \return 0 if no change, non zero otherwise + */ +int fl_filename_expand(char *to,int tolen, const char *from) { + + char *temp = new char[tolen]; + strlcpy(temp,from, tolen); + char *start = temp; + char *end = temp+strlen(temp); + + int ret = 0; + + for (char *a=temp; apw_dir; +#endif + } + break; + case '$': /* an environment variable */ + {char t = *e; *(char *)e = 0; value = fl_getenv(a+1); *(char *)e = t;} + break; + } + if (value) { + // substitutions that start with slash delete everything before them: + if (isdirsep(value[0])) start = a; +#if defined(WIN32) || defined(__EMX__) && !defined(__CYGWIN__) + // also if it starts with "A:" + if (value[0] && value[1]==':') start = a; +#endif + int t = strlen(value); if (isdirsep(value[t-1])) t--; + if ((end+1-e+t) >= tolen) end += tolen - (end+1-e+t); + memmove(a+t, e, end+1-e); + end = a+t+(end-e); + *end = '\0'; + memcpy(a, value, t); + ret++; + } else { + a = e+1; +#if defined(WIN32) || defined(__EMX__) && !defined(__CYGWIN__) + if (*e == '\\') {*e = '/'; ret++;} // ha ha! +#endif + } + } + + strlcpy(to, start, tolen); + + delete[] temp; + + return ret; +} + + +// +// End of "$Id: filename_expand.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/filename_ext.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/filename_ext.cxx new file mode 100644 index 0000000..f9be104 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/filename_ext.cxx @@ -0,0 +1,58 @@ +// +// "$Id: filename_ext.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Filename extension routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// returns pointer to the last '.' or to the null if none: + +#include + +/** Gets the extensions of a filename. + \code + #include + [..] + const char *out; + out = fl_filename_ext("/some/path/foo.txt"); // result: ".txt" + out = fl_filename_ext("/some/path/foo"); // result: NULL + \endcode + \param[in] buf the filename to be parsed + \return a pointer to the extension (including '.') if any or NULL otherwise + */ +const char *fl_filename_ext(const char *buf) { + const char *q = 0; + const char *p = buf; + for (p=buf; *p; p++) { + if (*p == '/') q = 0; +#if defined(WIN32) || defined(__EMX__) && !defined(__CYGWIN__) + else if (*p == '\\') q = 0; +#endif + else if (*p == '.') q = p; + } + return q ? q : p; +} + +// +// End of "$Id: filename_ext.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/filename_isdir.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/filename_isdir.cxx new file mode 100644 index 0000000..02014ca --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/filename_isdir.cxx @@ -0,0 +1,103 @@ +// +// "$Id: filename_isdir.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Directory detection routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Used by fl_file_chooser + +#include "flstring.h" +#include +#include +#include +#include +#include + + +#if defined(WIN32) || defined(__EMX__) && !defined(__CYGWIN__) +static inline int isdirsep(char c) {return c=='/' || c=='\\';} +#else +#define isdirsep(c) ((c)=='/') +#endif + +int _fl_filename_isdir_quick(const char* n) { + // Do a quick optimization for filenames with a trailing slash... + if (*n && isdirsep(n[strlen(n) - 1])) return 1; + return fl_filename_isdir(n); +} + +/** + Determines if a file exists and is a directory from its filename. + \code + #include + [..] + fl_filename_isdir("/etc"); // returns non-zero + fl_filename_isdir("/etc/hosts"); // returns 0 + \endcode + \param[in] n the filename to parse + \return non zero if file exists and is a directory, zero otherwise +*/ +int fl_filename_isdir(const char* n) { + struct stat s; + char fn[1024]; + int length; + + length = strlen(n); + +#ifdef WIN32 + // This workaround brought to you by the fine folks at Microsoft! + // (read lots of sarcasm in that...) + if (length < (int)(sizeof(fn) - 1)) { + if (length < 4 && isalpha(n[0]) && n[1] == ':' && + (isdirsep(n[2]) || !n[2])) { + // Always use D:/ for drive letters + fn[0] = n[0]; + strcpy(fn + 1, ":/"); + n = fn; + } else if (length > 0 && isdirsep(n[length - 1])) { + // Strip trailing slash from name... + length --; + memcpy(fn, n, length); + fn[length] = '\0'; + n = fn; + } + } +#else + // Matt: Just in case, we strip the slash for other operating + // systems as well, avoid bugs by sloppy implementations + // of "stat". + if (length > 1 && isdirsep(n[length - 1])) { + length --; + memcpy(fn, n, length); + fn[length] = '\0'; + n = fn; + } +#endif + + return !fl_stat(n, &s) && (s.st_mode&0170000)==0040000; +} + +// +// End of "$Id: filename_isdir.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/filename_list.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/filename_list.cxx new file mode 100644 index 0000000..4077704 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/filename_list.cxx @@ -0,0 +1,136 @@ +// +// "$Id: filename_list.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Filename list routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Wrapper for scandir with const-correct function prototypes. + +#include +#include "flstring.h" +#include + + +extern "C" { +#ifndef HAVE_SCANDIR + int fl_scandir (const char *dir, dirent ***namelist, + int (*select)(dirent *), + int (*compar)(dirent **, dirent **)); +# define scandir fl_scandir +#endif +} + +int fl_alphasort(struct dirent **a, struct dirent **b) { + return strcmp((*a)->d_name, (*b)->d_name); +} + +int fl_casealphasort(struct dirent **a, struct dirent **b) { + return strcasecmp((*a)->d_name, (*b)->d_name); +} + + +/** + Portable and const-correct wrapper for the scandir() function. + For each file in that directory a "dirent" structure is created. + The only portable thing about a dirent is that dirent.d_name is the nul-terminated file name. + An pointers array to these dirent's is created and a pointer to the array is returned in *list. + The number of entries is given as a return value. + If there is an error reading the directory a number less than zero is returned, + and errno has the reason; errno does not work under WIN32. + + \b Include: + \code + #include + \endcode + + \param[in] d the name of the directory to list. It does not matter if it has a trailing slash. + \param[out] list table containing the resulting directory listing + \param[in] sort sorting functor: + - fl_alphasort: The files are sorted in ascending alphabetical order; + upper and lowercase letters are compared according to their ASCII ordering uppercase before lowercase. + - fl_casealphasort: The files are sorted in ascending alphabetical order; + upper and lowercase letters are compared equally case is not significant. + - fl_casenumericsort: The files are sorted in ascending "alphanumeric" order, where an attempt is made + to put unpadded numbers in consecutive order; upper and lowercase letters + are compared equally case is not significant. + - fl_numericsort: The files are sorted in ascending "alphanumeric" order, where an attempt is made + to put unpadded numbers in consecutive order; upper and lowercase letters are compared + according to their ASCII ordering - uppercase before lowercase. + \return the number of entries if no error, a negative value otherwise. +*/ +int fl_filename_list(const char *d, dirent ***list, + Fl_File_Sort_F *sort) { +#ifndef HAVE_SCANDIR + int n = scandir(d, list, 0, sort); +#elif defined(HAVE_SCANDIR_POSIX) && !defined(__APPLE__) + // POSIX (2008) defines the comparison function like this: + int n = scandir(d, list, 0, (int(*)(const dirent **, const dirent **))sort); +#elif defined(__osf__) + // OSF, DU 4.0x + int n = scandir(d, list, 0, (int(*)(dirent **, dirent **))sort); +#elif defined(_AIX) + // AIX is almost standard... + int n = scandir(d, list, 0, (int(*)(void*, void*))sort); +#elif !defined(__sgi) + // The vast majority of UNIX systems want the sort function to have this + // prototype, most likely so that it can be passed to qsort without any + // changes: + int n = scandir(d, list, 0, (int(*)(const void*,const void*))sort); +#else + // This version is when we define our own scandir (WIN32 and perhaps + // some Unix systems) and apparently on IRIX: + int n = scandir(d, list, 0, sort); +#endif + +#if defined(WIN32) && !defined(__CYGWIN__) + // we did this already during fl_scandir/win32 +#else + // append a '/' to all filenames that are directories + int i, dirlen = strlen(d); + char *fullname = (char*)malloc(dirlen+FL_PATH_MAX+3); // Add enough extra for two /'s and a nul + // Use memcpy for speed since we already know the length of the string... + memcpy(fullname, d, dirlen+1); + char *name = fullname + dirlen; + if (name!=fullname && name[-1]!='/') *name++ = '/'; + for (i=0; id_name); + if (de->d_name[len-1]=='/' || len>FL_PATH_MAX) continue; + // Use memcpy for speed since we already know the length of the string... + memcpy(name, de->d_name, len+1); + if (fl_filename_isdir(fullname)) { + (*list)[i] = de = (dirent*)realloc(de, de->d_name - (char*)de + len + 2); + char *dst = de->d_name + len; + *dst++ = '/'; + *dst = 0; + } + } + free(fullname); +#endif + return n; +} + +// +// End of "$Id: filename_list.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/filename_match.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/filename_match.cxx new file mode 100644 index 0000000..41e6dfd --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/filename_match.cxx @@ -0,0 +1,128 @@ +// +// "$Id: filename_match.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Pattern matching routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* Adapted from Rich Salz. */ +#include +#include + +/** + Checks if a string \p s matches a pattern \p p. + The following syntax is used for the pattern: + - * matches any sequence of 0 or more characters. + - ? matches any single character. + - [set] matches any character in the set. Set can contain any single characters, or a-z to represent a range. + To match ] or - they must be the first characters. To match ^ or ! they must not be the first characters. + - [^set] or [!set] matches any character not in the set. + - {X|Y|Z} or {X,Y,Z} matches any one of the subexpressions literally. + - \\x quotes the character x so it has no special meaning. + - x all other characters must be matched exactly. + + \b Include: + \code + #include + \endcode + + \param[in] s the string to check for a match + \param[in] p the string pattern + \return non zero if the string matches the pattern +*/ +int fl_filename_match(const char *s, const char *p) { + int matched; + + for (;;) { + switch(*p++) { + + case '?' : // match any single character + if (!*s++) return 0; + break; + + case '*' : // match 0-n of any characters + if (!*p) return 1; // do trailing * quickly + while (!fl_filename_match(s, p)) if (!*s++) return 0; + return 1; + + case '[': { // match one character in set of form [abc-d] or [^a-b] + if (!*s) return 0; + int reverse = (*p=='^' || *p=='!'); if (reverse) p++; + matched = 0; + char last = 0; + while (*p) { + if (*p=='-' && last) { + if (*s <= *++p && *s >= last ) matched = 1; + last = 0; + } else { + if (*s == *p) matched = 1; + } + last = *p++; + if (*p==']') break; + } + if (matched == reverse) return 0; + s++; p++;} + break; + + case '{' : // {pattern1|pattern2|pattern3} + NEXTCASE: + if (fl_filename_match(s,p)) return 1; + for (matched = 0;;) { + switch (*p++) { + case '\\': if (*p) p++; break; + case '{': matched++; break; + case '}': if (!matched--) return 0; break; + case '|': case ',': if (matched==0) goto NEXTCASE; + case 0: return 0; + } + } + case '|': // skip rest of |pattern|pattern} when called recursively + case ',': + for (matched = 0; *p && matched >= 0;) { + switch (*p++) { + case '\\': if (*p) p++; break; + case '{': matched++; break; + case '}': matched--; break; + } + } + break; + case '}': + break; + + case 0: // end of pattern + return !*s; + + case '\\': // quote next character + if (*p) p++; + /* FALLTHROUGH */ + default: + if (tolower(*s) != tolower(*(p-1))) return 0; + s++; + break; + } + } +} + +// +// End of "$Id: filename_match.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/filename_setext.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/filename_setext.cxx new file mode 100644 index 0000000..1f63309 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/filename_setext.cxx @@ -0,0 +1,60 @@ +// +// "$Id: filename_setext.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Filename extension routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Replace .ext with new extension + +#include +#include "flstring.h" + +/** + Replaces the extension in \p buf of max.
      + size \p buflen with the extension in \p ext.
      + If there's no '.' in \p buf, \p ext is appended.
      + If \p ext is NULL, behaves as if it were an empty string (""). + + \b Example + \code + #include + [..] + char buf[1024] = "/path/myfile.cxx"; + fl_filename_setext(buf, sizeof(buf), ".txt"); // buf[] becomes "/path/myfile.txt" + \endcode + + \return buf itself for calling convenience. +*/ +char *fl_filename_setext(char *buf, int buflen, const char *ext) { + char *q = (char *)fl_filename_ext(buf); + if (ext) { + strlcpy(q,ext,buflen - (q - buf)); + } else *q = 0; + return(buf); +} + + +// +// End of "$Id: filename_setext.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_arc.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_arc.cxx new file mode 100644 index 0000000..70b29e7 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_arc.cxx @@ -0,0 +1,91 @@ +// +// "$Id: fl_arc.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Arc functions for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/** + \file fl_arc.cxx + \brief Utility functions for drawing arcs and circles. +*/ + +// Utility for drawing arcs and circles. They are added to +// the current fl_begin/fl_vertex/fl_end path. +// Incremental math implementation: + +#include +#include + +// avoid problems with some platforms that don't +// implement hypot. +static double _fl_hypot(double x, double y) { + return sqrt(x*x + y*y); +} + +void Fl_Graphics_Driver::arc(double x, double y, double r, double start, double end) { + + // draw start point accurately: + + double A = start*(M_PI/180); // Initial angle (radians) + double X = r*cos(A); // Initial displacement, (X,Y) + double Y = -r*sin(A); // from center to initial point + fl_vertex(x+X,y+Y); // Insert initial point + + // Maximum arc length to approximate with chord with error <= 0.125 + + double epsilon; { + double r1 = _fl_hypot(fl_transform_dx(r,0), // Horizontal "radius" + fl_transform_dy(r,0)); + double r2 = _fl_hypot(fl_transform_dx(0,r), // Vertical "radius" + fl_transform_dy(0,r)); + + if (r1 > r2) r1 = r2; // r1 = minimum "radius" + if (r1 < 2.) r1 = 2.; // radius for circa 9 chords/circle + + epsilon = 2*acos(1.0 - 0.125/r1); // Maximum arc angle + } + A = end*(M_PI/180) - A; // Displacement angle (radians) + int i = int(ceil(fabs(A)/epsilon)); // Segments in approximation + + if (i) { + epsilon = A/i; // Arc length for equal-size steps + double cos_e = cos(epsilon); // Rotation coefficients + double sin_e = sin(epsilon); + do { + double Xnew = cos_e*X + sin_e*Y; + Y = -sin_e*X + cos_e*Y; + fl_vertex(x + (X=Xnew), y + Y); + } while (--i); + } +} + +#if 0 // portable version. X-specific one in fl_vertex.cxx +void fl_circle(double x,double y,double r) { + _fl_arc(x, y, r, r, 0, 360); +} +#endif + +// +// End of "$Id: fl_arc.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_arci.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_arci.cxx new file mode 100644 index 0000000..963d62c --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_arci.cxx @@ -0,0 +1,131 @@ +// +// "$Id: fl_arci.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Arc (integer) drawing functions for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/** + \file fl_arci.cxx + \brief Utility functions for drawing circles using integers +*/ + +// "integer" circle drawing functions. These draw the limited +// circle types provided by X and NT graphics. The advantage of +// these is that small ones draw quite nicely (probably due to stored +// hand-drawn bitmaps of small circles!) and may be implemented by +// hardware and thus are fast. + +// Probably should add fl_chord. + +// 3/10/98: created + +#include +#include +#ifdef WIN32 +# include +#endif +#include + +void Fl_Graphics_Driver::arc(int x,int y,int w,int h,double a1,double a2) { + if (w <= 0 || h <= 0) return; + +#if defined(USE_X11) + XDrawArc(fl_display, fl_window, fl_gc, x,y,w-1,h-1, int(a1*64),int((a2-a1)*64)); +#elif defined(WIN32) + int xa = x+w/2+int(w*cos(a1/180.0*M_PI)); + int ya = y+h/2-int(h*sin(a1/180.0*M_PI)); + int xb = x+w/2+int(w*cos(a2/180.0*M_PI)); + int yb = y+h/2-int(h*sin(a2/180.0*M_PI)); + if (fabs(a1 - a2) < 90) { + if (xa == xb && ya == yb) SetPixel(fl_gc, xa, ya, fl_RGB()); + else Arc(fl_gc, x, y, x+w, y+h, xa, ya, xb, yb); + } else Arc(fl_gc, x, y, x+w, y+h, xa, ya, xb, yb); +#elif defined(__APPLE_QUARTZ__) + a1 = (-a1)/180.0f*M_PI; a2 = (-a2)/180.0f*M_PI; + float cx = x + 0.5f*w - 0.5f, cy = y + 0.5f*h - 0.5f; + CGContextSetShouldAntialias(fl_gc, true); + if (w!=h) { + CGContextSaveGState(fl_gc); + CGContextTranslateCTM(fl_gc, cx, cy); + CGContextScaleCTM(fl_gc, w-1.0f, h-1.0f); + CGContextAddArc(fl_gc, 0, 0, 0.5, a1, a2, 1); + CGContextRestoreGState(fl_gc); + } else { + float r = (w+h)*0.25f-0.5f; + CGContextAddArc(fl_gc, cx, cy, r, a1, a2, 1); + } + CGContextStrokePath(fl_gc); + CGContextSetShouldAntialias(fl_gc, false); +#else +# error unsupported platform +#endif +} + +void Fl_Graphics_Driver::pie(int x,int y,int w,int h,double a1,double a2) { + if (w <= 0 || h <= 0) return; + +#if defined(USE_X11) + XFillArc(fl_display, fl_window, fl_gc, x,y,w-1,h-1, int(a1*64),int((a2-a1)*64)); +#elif defined(WIN32) + if (a1 == a2) return; + int xa = x+w/2+int(w*cos(a1/180.0*M_PI)); + int ya = y+h/2-int(h*sin(a1/180.0*M_PI)); + int xb = x+w/2+int(w*cos(a2/180.0*M_PI)); + int yb = y+h/2-int(h*sin(a2/180.0*M_PI)); + SelectObject(fl_gc, fl_brush()); + if (fabs(a1 - a2) < 90) { + if (xa == xb && ya == yb) { + MoveToEx(fl_gc, x+w/2, y+h/2, 0L); + LineTo(fl_gc, xa, ya); + SetPixel(fl_gc, xa, ya, fl_RGB()); + } else Pie(fl_gc, x, y, x+w, y+h, xa, ya, xb, yb); + } else Pie(fl_gc, x, y, x+w, y+h, xa, ya, xb, yb); +#elif defined(__APPLE_QUARTZ__) + a1 = (-a1)/180.0f*M_PI; a2 = (-a2)/180.0f*M_PI; + float cx = x + 0.5f*w - 0.5f, cy = y + 0.5f*h - 0.5f; + CGContextSetShouldAntialias(fl_gc, true); + if (w!=h) { + CGContextSaveGState(fl_gc); + CGContextTranslateCTM(fl_gc, cx, cy); + CGContextScaleCTM(fl_gc, w, h); + CGContextAddArc(fl_gc, 0, 0, 0.5, a1, a2, 1); + CGContextAddLineToPoint(fl_gc, 0, 0); + CGContextClosePath(fl_gc); + CGContextRestoreGState(fl_gc); + } else { + float r = (w+h)*0.25f; + CGContextAddArc(fl_gc, cx, cy, r, a1, a2, 1); + CGContextAddLineToPoint(fl_gc, cx, cy); + CGContextClosePath(fl_gc); + } + CGContextFillPath(fl_gc); + CGContextSetShouldAntialias(fl_gc, false); +#else +# error unsupported platform +#endif +} + +// +// End of "$Id: fl_arci.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_ask.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_ask.cxx new file mode 100644 index 0000000..60ccf04 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_ask.cxx @@ -0,0 +1,496 @@ +// +// "$Id: fl_ask.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Standard dialog functions for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Implementation of fl_message, fl_ask, fl_choice, fl_input +// The three-message fl_show_x functions are for forms compatibility +// mostly. In most cases it is easier to get a multi-line message +// by putting newlines in the message. + +#include +#include +#include "flstring.h" + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __APPLE__ +# if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 +# include +# endif +#endif + +static Fl_Window *message_form; +static Fl_Box *message; +static Fl_Box *icon; +static Fl_Button *button[3]; +static Fl_Input *input; +static int ret_val; +static const char *iconlabel = "?"; +Fl_Font fl_message_font_ = FL_HELVETICA; +Fl_Fontsize fl_message_size_ = 14; + +static char avoidRecursion = 0; + +// Sets the global return value (ret_val) and closes the window. +// Note: this is used for the button callbacks and the window +// callback (closing the window with the close button or menu). +// The first argument (Fl_Widget *) can either be an Fl_Button* +// pointer to one of the buttons or an Fl_Window* pointer to the +// message window (message_form). +static void button_cb(Fl_Widget *, void *val) { + ret_val = (int)(long)val; + message_form->hide(); +} + +static Fl_Window *makeform() { + if (message_form) { + message_form->size(410,103); + return message_form; + } + // make sure that the dialog does not become the child of some + // current group + Fl_Group *previously_current_group = Fl_Group::current(); + Fl_Group::current(0); + // create a new top level window + Fl_Window *w = message_form = new Fl_Window(410,103,""); + message_form->callback(button_cb,(void *)0); + // w->clear_border(); + // w->box(FL_UP_BOX); + (message = new Fl_Box(60, 25, 340, 20)) + ->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE|FL_ALIGN_WRAP); + (input = new Fl_Input(60, 37, 340, 23))->hide(); + {Fl_Box* o = icon = new Fl_Box(10, 10, 50, 50); + o->box(FL_THIN_UP_BOX); + o->labelfont(FL_TIMES_BOLD); + o->labelsize(34); + o->color(FL_WHITE); + o->labelcolor(FL_BLUE); + } + // create the buttons (right to left) + for (int b=0, x=310; b<3; b++, x -= 100) { + if (b==1) + button[b] = new Fl_Return_Button(x, 70, 90, 23); + else + button[b] = new Fl_Button(x, 70, 90, 23); + button[b]->align(FL_ALIGN_INSIDE|FL_ALIGN_WRAP); + button[b]->callback(button_cb,(void *)b); + } + button[0]->shortcut(FL_Escape); + w->resizable(new Fl_Box(60,10,110-60,27)); + w->end(); + w->set_modal(); + Fl_Group::current(previously_current_group); + return w; +} + +/* + * 'resizeform()' - Resize the form and widgets so that they hold everything + * that is asked of them... + */ + +void resizeform() { + int i; + int message_w, message_h; + int text_height; + int button_w[3], button_h[3]; + int x, w, h, max_w, max_h; + const int icon_size = 50; + + fl_font(fl_message_font_, fl_message_size_); + message_w = message_h = 0; + fl_measure(message->label(), message_w, message_h); + + message_w += 10; + message_h += 10; + if (message_w < 340) + message_w = 340; + if (message_h < 30) + message_h = 30; + + fl_font(button[0]->labelfont(), button[0]->labelsize()); + + memset(button_w, 0, sizeof(button_w)); + memset(button_h, 0, sizeof(button_h)); + + for (max_h = 25, i = 0; i < 3; i ++) + if (button[i]->visible()) + { + fl_measure(button[i]->label(), button_w[i], button_h[i]); + + if (i == 1) + button_w[1] += 20; + + button_w[i] += 30; + button_h[i] += 10; + + if (button_h[i] > max_h) + max_h = button_h[i]; + } + + if (input->visible()) text_height = message_h + 25; + else text_height = message_h; + + max_w = message_w + 10 + icon_size; + w = button_w[0] + button_w[1] + button_w[2] - 10; + + if (w > max_w) + max_w = w; + + message_w = max_w - 10 - icon_size; + + w = max_w + 20; + h = max_h + 30 + text_height; + + message_form->size(w, h); + message_form->size_range(w, h, w, h); + + message->resize(20 + icon_size, 10, message_w, message_h); + icon->resize(10, 10, icon_size, icon_size); + icon->labelsize(icon_size - 10); + input->resize(20 + icon_size, 10 + message_h, message_w, 25); + + for (x = w, i = 0; i < 3; i ++) + if (button_w[i]) + { + x -= button_w[i]; + button[i]->resize(x, h - 10 - max_h, button_w[i] - 10, max_h); + +// printf("button %d (%s) is %dx%d+%d,%d\n", i, button[i]->label(), +// button[i]->w(), button[i]->h(), +// button[i]->x(), button[i]->y()); + } +} + +static int innards(const char* fmt, va_list ap, + const char *b0, + const char *b1, + const char *b2) +{ + Fl::pushed(0); // stop dragging (STR #2159) + + avoidRecursion = 1; + + makeform(); + char buffer[1024]; + if (!strcmp(fmt,"%s")) { + message->label(va_arg(ap, const char*)); + } else { + ::vsnprintf(buffer, 1024, fmt, ap); + message->label(buffer); + } + + message->labelfont(fl_message_font_); + message->labelsize(fl_message_size_); + if (b0) {button[0]->show(); button[0]->label(b0); button[1]->position(210,70);} + else {button[0]->hide(); button[1]->position(310,70);} + if (b1) {button[1]->show(); button[1]->label(b1);} + else button[1]->hide(); + if (b2) {button[2]->show(); button[2]->label(b2);} + else button[2]->hide(); + const char* prev_icon_label = icon->label(); + if (!prev_icon_label) icon->label(iconlabel); + + resizeform(); + + if (button[1]->visible() && !input->visible()) + button[1]->take_focus(); + message_form->hotspot(button[0]); + if (b0 && Fl_Widget::label_shortcut(b0)) + button[0]->shortcut(0); + else + button[0]->shortcut(FL_Escape); + + // deactivate Fl::grab(), because it is incompatible with modal windows + Fl_Window* g = Fl::grab(); + if (g) Fl::grab(0); + message_form->show(); + while (message_form->shown()) Fl::wait(); + if (g) // regrab the previous popup menu, if there was one + Fl::grab(g); + icon->label(prev_icon_label); + + avoidRecursion = 0; + return ret_val; +} + + /** \addtogroup group_comdlg + @{ */ + +// pointers you can use to change FLTK to a foreign language: +const char* fl_no = "No"; ///< string pointer used in common dialogs, you can change it to a foreign language +const char* fl_yes= "Yes"; ///< string pointer used in common dialogs, you can change it to a foreign language +const char* fl_ok = "OK"; ///< string pointer used in common dialogs, you can change it to a foreign language +const char* fl_cancel= "Cancel"; ///< string pointer used in common dialogs, you can change it to a foreign language +const char* fl_close= "Close"; ///< string pointer used in common dialogs, you can change it to a foreign language + +// fltk functions: + +/** + Emits a system beep message. + */ +void fl_beep(int type) { +#ifdef WIN32 + switch (type) { + case FL_BEEP_QUESTION : + case FL_BEEP_PASSWORD : + MessageBeep(MB_ICONQUESTION); + break; + case FL_BEEP_MESSAGE : + MessageBeep(MB_ICONASTERISK); + break; + case FL_BEEP_NOTIFICATION : + MessageBeep(MB_ICONASTERISK); + break; + case FL_BEEP_ERROR : + MessageBeep(MB_ICONERROR); + break; + default : + MessageBeep(0xFFFFFFFF); + break; + } +#elif defined(__APPLE__) + switch (type) { + case FL_BEEP_DEFAULT : + case FL_BEEP_ERROR : + // How Apple is not any better than Microsoft: + /* MacOS 8 */ // SysBeep(30); + /* OS X 10.1 */ // AlertSoundPlay(); + /* OS X 10.5 */ // AudioServicesPlayAlertSound(kUserPreferredAlert); + /* OS X 10.6 */ // AudioServicesPlayAlertSound(kSystemSoundID_UserPreferredAlert); +# if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + if (AudioServicesPlayAlertSound!=0L) +# if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 + AudioServicesPlayAlertSound(kSystemSoundID_UserPreferredAlert); +# else + AudioServicesPlayAlertSound(kUserPreferredAlert); +# endif + else +# endif +#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 + AlertSoundPlay(); +#else + { + } +#endif + break; + default : + break; + } +#else + switch (type) { + case FL_BEEP_DEFAULT : + case FL_BEEP_ERROR : + if (!fl_display) fl_open_display(); + + XBell(fl_display, 100); + break; + default : + if (!fl_display) fl_open_display(); + + XBell(fl_display, 50); + break; + } +#endif // WIN32 +} +/** Shows an information message dialog box. + + \note Common dialog boxes are application modal. No more than one common dialog box + can be open at any time. Requests for additional dialog boxes are ignored. + + \param[in] fmt can be used as an sprintf-like format and variables for the message text + */ +void fl_message(const char *fmt, ...) { + + if (avoidRecursion) return; + + va_list ap; + + fl_beep(FL_BEEP_MESSAGE); + + va_start(ap, fmt); + iconlabel = "i"; + innards(fmt, ap, 0, fl_close, 0); + va_end(ap); + iconlabel = "?"; +} + +/** Shows an alert message dialog box + + \note Common dialog boxes are application modal. No more than one common dialog box + can be open at any time. Requests for additional dialog boxes are ignored. + + \param[in] fmt can be used as an sprintf-like format and variables for the message text + */ +void fl_alert(const char *fmt, ...) { + + if (avoidRecursion) return; + + va_list ap; + + fl_beep(FL_BEEP_ERROR); + + va_start(ap, fmt); + iconlabel = "!"; + innards(fmt, ap, 0, fl_close, 0); + va_end(ap); + iconlabel = "?"; +} +/** Shows a dialog displaying the \p fmt message, + this dialog features 2 yes/no buttons + + \note Common dialog boxes are application modal. No more than one common dialog box + can be open at any time. Requests for additional dialog boxes are ignored. + + \param[in] fmt can be used as an sprintf-like format and variables for the message text + \retval 0 if the no button is selected or another dialog box is still open + \retval 1 if yes is selected + */ +int fl_ask(const char *fmt, ...) { + + if (avoidRecursion) return 0; + + va_list ap; + + fl_beep(FL_BEEP_QUESTION); + + va_start(ap, fmt); + int r = innards(fmt, ap, fl_no, fl_yes, 0); + va_end(ap); + + return r; +} + +/** Shows a dialog displaying the \p fmt message, + this dialog features up to 3 customizable choice buttons + + \note Common dialog boxes are application modal. No more than one common dialog box + can be open at any time. Requests for additional dialog boxes are ignored. + + \param[in] fmt can be used as an sprintf-like format and variables for the message text + \param[in] b0 text label of button 0 + \param[in] b1 text label of button 1 + \param[in] b2 text label of button 2 + \retval 0 if the first button with \p b0 text is selected or another dialog box is still open + \retval 1 if the second button with \p b1 text is selected + \retval 2 if the third button with \p b2 text is selected + */ +int fl_choice(const char*fmt,const char *b0,const char *b1,const char *b2,...){ + + if (avoidRecursion) return 0; + + va_list ap; + + fl_beep(FL_BEEP_QUESTION); + + va_start(ap, b2); + int r = innards(fmt, ap, b0, b1, b2); + va_end(ap); + return r; +} +/** Gets the Fl_Box icon container of the current default dialog used in + many common dialogs like fl_message(), fl_alert(), + fl_ask(), fl_choice(), fl_input(), fl_password() +*/ +Fl_Widget *fl_message_icon() {makeform(); return icon;} + +static const char* input_innards(const char* fmt, va_list ap, + const char* defstr, uchar type) { + makeform(); + message->position(60,10); + input->type(type); + input->show(); + input->value(defstr); + input->take_focus(); + + int r = innards(fmt, ap, fl_cancel, fl_ok, 0); + input->hide(); + message->position(60,25); + return r ? input->value() : 0; +} + +/** Shows an input dialog displaying the \p fmt message + + \note Common dialog boxes are application modal. No more than one common dialog box + can be open at any time. Requests for additional dialog boxes are ignored. + + \param[in] fmt can be used as an sprintf-like format and variables for the message text + \param[in] defstr defines the default returned string if no text is entered + \return the user string input if OK was pushed, NULL if Cancel was pushed or another dialog box was still open + */ +const char* fl_input(const char *fmt, const char *defstr, ...) { + + if (avoidRecursion) return 0; + + fl_beep(FL_BEEP_QUESTION); + + va_list ap; + va_start(ap, defstr); + const char* r = input_innards(fmt, ap, defstr, FL_NORMAL_INPUT); + va_end(ap); + return r; +} + +/** Shows an input dialog displaying the \p fmt message. + + Like fl_input() except the input text is not shown, + '*' characters are displayed instead. + + \note Common dialog boxes are application modal. No more than one common dialog box + can be open at any time. Requests for additional dialog boxes are ignored. + + \param[in] fmt can be used as an sprintf-like format and variables for the message text + \param[in] defstr defines the default returned string if no text is entered + \return the user string input if OK was pushed, NULL if Cancel was pushed or aother dialog box was still open + */ +const char *fl_password(const char *fmt, const char *defstr, ...) { + + if (avoidRecursion) return 0; + + fl_beep(FL_BEEP_PASSWORD); + + va_list ap; + va_start(ap, defstr); + const char* r = input_innards(fmt, ap, defstr, FL_SECRET_INPUT); + va_end(ap); + return r; +} + +/** @} */ + +// +// End of "$Id: fl_ask.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_boxtype.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_boxtype.cxx new file mode 100644 index 0000000..ffbc698 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_boxtype.cxx @@ -0,0 +1,429 @@ +// +// "$Id: fl_boxtype.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Box drawing code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/** + \file fl_boxtype.cxx + \brief drawing code for common box types. +*/ + +// Box drawing code for the common box types and the table of +// boxtypes. Other box types are in separate files so they are not +// linked in if not used. + +#include +#include +#include +#include + +//////////////////////////////////////////////////////////////// + +static uchar active_ramp[24] = { + FL_GRAY_RAMP+0, FL_GRAY_RAMP+1, FL_GRAY_RAMP+2, FL_GRAY_RAMP+3, + FL_GRAY_RAMP+4, FL_GRAY_RAMP+5, FL_GRAY_RAMP+6, FL_GRAY_RAMP+7, + FL_GRAY_RAMP+8, FL_GRAY_RAMP+9, FL_GRAY_RAMP+10,FL_GRAY_RAMP+11, + FL_GRAY_RAMP+12,FL_GRAY_RAMP+13,FL_GRAY_RAMP+14,FL_GRAY_RAMP+15, + FL_GRAY_RAMP+16,FL_GRAY_RAMP+17,FL_GRAY_RAMP+18,FL_GRAY_RAMP+19, + FL_GRAY_RAMP+20,FL_GRAY_RAMP+21,FL_GRAY_RAMP+22,FL_GRAY_RAMP+23}; +static uchar inactive_ramp[24] = { + 43, 43, 44, 44, + 44, 45, 45, 46, + 46, 46, 47, 47, + 48, 48, 48, 49, + 49, 49, 50, 50, + 51, 51, 52, 52}; +static int draw_it_active = 1; + +/** + Determines if the current draw box is active or inactive. + If inactive, the box color is changed by the inactive color. +*/ +int Fl::draw_box_active() { return draw_it_active; } + +uchar *fl_gray_ramp() {return (draw_it_active?active_ramp:inactive_ramp)-'A';} + +/** + Draws a series of line segments around the given box. + The string \p s must contain groups of 4 letters which specify one of 24 + standard grayscale values, where 'A' is black and 'X' is white. + The order of each set of 4 characters is: top, left, bottom, right. + The result of calling fl_frame() with a string that is not a multiple + of 4 characters in length is undefined. + The only difference between this function and fl_frame2() is the order + of the line segments. + \param[in] s sets of 4 grayscale values in top, left, bottom, right order + \param[in] x, y, w, h position and size +*/ +void fl_frame(const char* s, int x, int y, int w, int h) { + uchar *g = fl_gray_ramp(); + if (h > 0 && w > 0) for (;*s;) { + // draw top line: + fl_color(g[(int)*s++]); + fl_xyline(x, y, x+w-1); + y++; if (--h <= 0) break; + // draw left line: + fl_color(g[(int)*s++]); + fl_yxline(x, y+h-1, y); + x++; if (--w <= 0) break; + // draw bottom line: + fl_color(g[(int)*s++]); + fl_xyline(x, y+h-1, x+w-1); + if (--h <= 0) break; + // draw right line: + fl_color(g[(int)*s++]); + fl_yxline(x+w-1, y+h-1, y); + if (--w <= 0) break; + } +} + +/** + Draws a series of line segments around the given box. + The string \p s must contain groups of 4 letters which specify one of 24 + standard grayscale values, where 'A' is black and 'X' is white. + The order of each set of 4 characters is: bottom, right, top, left. + The result of calling fl_frame2() with a string that is not a multiple + of 4 characters in length is undefined. + The only difference between this function and fl_frame() is the order + of the line segments. + \param[in] s sets of 4 grayscale values in bottom, right, top, left order + \param[in] x, y, w, h position and size +*/ +void fl_frame2(const char* s, int x, int y, int w, int h) { + uchar *g = fl_gray_ramp(); + if (h > 0 && w > 0) for (;*s;) { + // draw bottom line: + fl_color(g[(int)*s++]); + fl_xyline(x, y+h-1, x+w-1); + if (--h <= 0) break; + // draw right line: + fl_color(g[(int)*s++]); + fl_yxline(x+w-1, y+h-1, y); + if (--w <= 0) break; + // draw top line: + fl_color(g[(int)*s++]); + fl_xyline(x, y, x+w-1); + y++; if (--h <= 0) break; + // draw left line: + fl_color(g[(int)*s++]); + fl_yxline(x, y+h-1, y); + x++; if (--w <= 0) break; + } +} + +/** Draws a box of type FL_NO_BOX */ +void fl_no_box(int, int, int, int, Fl_Color) {} + +/** Draws a frame of type FL_THIN_DOWN_FRAME */ +void fl_thin_down_frame(int x, int y, int w, int h, Fl_Color) { + fl_frame2("WWHH",x,y,w,h); +} + +/** Draws a box of type FL_THIN_DOWN_BOX */ +void fl_thin_down_box(int x, int y, int w, int h, Fl_Color c) { + fl_thin_down_frame(x,y,w,h,c); + fl_color(draw_it_active ? c : fl_inactive(c)); + fl_rectf(x+1, y+1, w-2, h-2); +} + +/** Draws a frame of type FL_THIN_UP_FRAME */ +void fl_thin_up_frame(int x, int y, int w, int h, Fl_Color) { + fl_frame2("HHWW",x,y,w,h); +} + +/** Draws a box of type FL_THIN_UP_BOX */ +void fl_thin_up_box(int x, int y, int w, int h, Fl_Color c) { + fl_thin_up_frame(x,y,w,h,c); + fl_color(draw_it_active ? c : fl_inactive(c)); + fl_rectf(x+1, y+1, w-2, h-2); +} + +/** Draws a frame of type FL_UP_FRAME */ +void fl_up_frame(int x, int y, int w, int h, Fl_Color) { +#if BORDER_WIDTH == 1 + fl_frame2("HHWW",x,y,w,h); +#else +#if BORDER_WIDTH == 2 + fl_frame2("AAWWMMTT",x,y,w,h); +#else + fl_frame("AAAAWWJJUTNN",x,y,w,h); +#endif +#endif +} + +#define D1 BORDER_WIDTH +#define D2 (BORDER_WIDTH+BORDER_WIDTH) + +/** Draws a box of type FL_UP_BOX */ +void fl_up_box(int x, int y, int w, int h, Fl_Color c) { + fl_up_frame(x,y,w,h,c); + fl_color(draw_it_active ? c : fl_inactive(c)); + fl_rectf(x+D1, y+D1, w-D2, h-D2); +} + +/** Draws a frame of type FL_DOWN_FRAME */ +void fl_down_frame(int x, int y, int w, int h, Fl_Color) { +#if BORDER_WIDTH == 1 + fl_frame2("WWHH",x,y,w,h); +#else +#if BORDER_WIDTH == 2 + fl_frame2("WWMMPPAA",x,y,w,h); +#else + fl_frame("NNTUJJWWAAAA",x,y,w,h); +#endif +#endif +} + +/** Draws a box of type FL_DOWN_BOX */ +void fl_down_box(int x, int y, int w, int h, Fl_Color c) { + fl_down_frame(x,y,w,h,c); + fl_color(c); fl_rectf(x+D1, y+D1, w-D2, h-D2); +} + +/** Draws a frame of type FL_ENGRAVED_FRAME */ +void fl_engraved_frame(int x, int y, int w, int h, Fl_Color) { + fl_frame("HHWWWWHH",x,y,w,h); +} + +/** Draws a box of type FL_ENGRAVED_BOX */ +void fl_engraved_box(int x, int y, int w, int h, Fl_Color c) { + fl_engraved_frame(x,y,w,h,c); + fl_color(draw_it_active ? c : fl_inactive(c)); + fl_rectf(x+2, y+2, w-4, h-4); +} + +/** Draws a frame of type FL_EMBOSSED_FRAME */ +void fl_embossed_frame(int x, int y, int w, int h, Fl_Color) { + fl_frame("WWHHHHWW",x,y,w,h); +} + +/** Draws a box of type FL_EMBOSSED_BOX */ +void fl_embossed_box(int x, int y, int w, int h, Fl_Color c) { + fl_embossed_frame(x,y,w,h,c); + fl_color(draw_it_active ? c : fl_inactive(c)); + fl_rectf(x+2, y+2, w-4, h-4); +} + +/** + Draws a bounded rectangle with a given position, size and color. + Equivalent to drawing a box of type FL_BORDER_BOX. +*/ +void fl_rectbound(int x, int y, int w, int h, Fl_Color bgcolor) { + fl_color(draw_it_active ? FL_BLACK : fl_inactive(FL_BLACK)); + fl_rect(x, y, w, h); + fl_color(draw_it_active ? bgcolor : fl_inactive(bgcolor)); + fl_rectf(x+1, y+1, w-2, h-2); +} +#define fl_border_box fl_rectbound /**< allow consistent naming */ + +/** + Draws a frame of type FL_BORDER_FRAME. +*/ +void fl_border_frame(int x, int y, int w, int h, Fl_Color c) { + fl_color(draw_it_active ? c : fl_inactive(c)); + fl_rect(x, y, w, h); +} + +//////////////////////////////////////////////////////////////// + +static struct { + Fl_Box_Draw_F *f; + uchar dx, dy, dw, dh; + int set; +} fl_box_table[256] = { +// must match list in Enumerations.H!!! + {fl_no_box, 0,0,0,0,1}, + {fl_rectf, 0,0,0,0,1}, // FL_FLAT_BOX + {fl_up_box, D1,D1,D2,D2,1}, + {fl_down_box, D1,D1,D2,D2,1}, + {fl_up_frame, D1,D1,D2,D2,1}, + {fl_down_frame, D1,D1,D2,D2,1}, + {fl_thin_up_box, 1,1,2,2,1}, + {fl_thin_down_box, 1,1,2,2,1}, + {fl_thin_up_frame, 1,1,2,2,1}, + {fl_thin_down_frame, 1,1,2,2,1}, + {fl_engraved_box, 2,2,4,4,1}, + {fl_embossed_box, 2,2,4,4,1}, + {fl_engraved_frame, 2,2,4,4,1}, + {fl_embossed_frame, 2,2,4,4,1}, + {fl_border_box, 1,1,2,2,1}, + {fl_border_box, 1,1,5,5,0}, // _FL_SHADOW_BOX, + {fl_border_frame, 1,1,2,2,1}, + {fl_border_frame, 1,1,5,5,0}, // _FL_SHADOW_FRAME, + {fl_border_box, 1,1,2,2,0}, // _FL_ROUNDED_BOX, + {fl_border_box, 1,1,2,2,0}, // _FL_RSHADOW_BOX, + {fl_border_frame, 1,1,2,2,0}, // _FL_ROUNDED_FRAME + {fl_rectf, 0,0,0,0,0}, // _FL_RFLAT_BOX, + {fl_up_box, 3,3,6,6,0}, // _FL_ROUND_UP_BOX + {fl_down_box, 3,3,6,6,0}, // _FL_ROUND_DOWN_BOX, + {fl_up_box, 0,0,0,0,0}, // _FL_DIAMOND_UP_BOX + {fl_down_box, 0,0,0,0,0}, // _FL_DIAMOND_DOWN_BOX + {fl_border_box, 1,1,2,2,0}, // _FL_OVAL_BOX, + {fl_border_box, 1,1,2,2,0}, // _FL_OVAL_SHADOW_BOX, + {fl_border_frame, 1,1,2,2,0}, // _FL_OVAL_FRAME + {fl_rectf, 0,0,0,0,0}, // _FL_OVAL_FLAT_BOX, + {fl_up_box, 4,4,8,8,0}, // _FL_PLASTIC_UP_BOX, + {fl_down_box, 2,2,4,4,0}, // _FL_PLASTIC_DOWN_BOX, + {fl_up_frame, 2,2,4,4,0}, // _FL_PLASTIC_UP_FRAME, + {fl_down_frame, 2,2,4,4,0}, // _FL_PLASTIC_DOWN_FRAME, + {fl_up_box, 2,2,4,4,0}, // _FL_PLASTIC_THIN_UP_BOX, + {fl_down_box, 2,2,4,4,0}, // _FL_PLASTIC_THIN_DOWN_BOX, + {fl_up_box, 2,2,4,4,0}, // _FL_PLASTIC_ROUND_UP_BOX, + {fl_down_box, 2,2,4,4,0}, // _FL_PLASTIC_ROUND_DOWN_BOX, + {fl_up_box, 2,2,4,4,0}, // _FL_GTK_UP_BOX, + {fl_down_box, 2,2,4,4,0}, // _FL_GTK_DOWN_BOX, + {fl_up_frame, 2,2,4,4,0}, // _FL_GTK_UP_FRAME, + {fl_down_frame, 2,2,4,4,0}, // _FL_GTK_DOWN_FRAME, + {fl_up_frame, 1,1,2,2,0}, // _FL_GTK_THIN_UP_FRAME, + {fl_down_frame, 1,1,2,2,0}, // _FL_GTK_THIN_DOWN_FRAME, + {fl_up_box, 1,1,2,2,0}, // _FL_GTK_THIN_ROUND_UP_BOX, + {fl_down_box, 1,1,2,2,0}, // _FL_GTK_THIN_ROUND_DOWN_BOX, + {fl_up_box, 2,2,4,4,0}, // _FL_GTK_ROUND_UP_BOX, + {fl_down_box, 2,2,4,4,0}, // _FL_GTK_ROUND_DOWN_BOX, + {fl_up_box, 3,3,6,6,0}, // FL_FREE_BOX+0 + {fl_down_box, 3,3,6,6,0}, // FL_FREE_BOX+1 + {fl_up_box, 3,3,6,6,0}, // FL_FREE_BOX+2 + {fl_down_box, 3,3,6,6,0}, // FL_FREE_BOX+3 + {fl_up_box, 3,3,6,6,0}, // FL_FREE_BOX+4 + {fl_down_box, 3,3,6,6,0}, // FL_FREE_BOX+5 + {fl_up_box, 3,3,6,6,0}, // FL_FREE_BOX+6 + {fl_down_box, 3,3,6,6,0}, // FL_FREE_BOX+7 +}; + +/** + Returns the X offset for the given boxtype. + \see box_dy() +*/ +int Fl::box_dx(Fl_Boxtype t) {return fl_box_table[t].dx;} + +/** + Returns the Y offset for the given boxtype. + + These functions return the offset values necessary for a given + boxtype, useful for computing the area inside a box's borders, to + prevent overdrawing the borders. + + For instance, in the case of a boxtype like FL_DOWN_BOX + where the border width might be 2 pixels all around, the above + functions would return 2, 2, 4, and 4 for box_dx, + box_dy, box_dw, and box_dh respectively. + + An example to compute the area inside a widget's box(): + \code + int X = yourwidget->x() + Fl::box_dx(yourwidget->box()); + int Y = yourwidget->y() + Fl::box_dy(yourwidget->box()); + int W = yourwidget->w() - Fl::box_dw(yourwidget->box()); + int H = yourwidget->h() - Fl::box_dh(yourwidget->box()); + \endcode + These functions are mainly useful in the draw() code + for deriving custom widgets, where one wants to avoid drawing + over the widget's own border box(). +*/ +int Fl::box_dy(Fl_Boxtype t) {return fl_box_table[t].dy;} + +/** + Returns the width offset for the given boxtype. + \see box_dy(). +*/ +int Fl::box_dw(Fl_Boxtype t) {return fl_box_table[t].dw;} + +/** + Returns the height offset for the given boxtype. + \see box_dy(). +*/ +int Fl::box_dh(Fl_Boxtype t) {return fl_box_table[t].dh;} + +/** + Sets the drawing function for a given box type. + \param[in] t box type + \param[in] f box drawing function +*/ +void fl_internal_boxtype(Fl_Boxtype t, Fl_Box_Draw_F* f) { + if (!fl_box_table[t].set) { + fl_box_table[t].f = f; + fl_box_table[t].set = 1; + } +} + +/** Gets the current box drawing function for the specified box type. */ +Fl_Box_Draw_F *Fl::get_boxtype(Fl_Boxtype t) { + return fl_box_table[t].f; +} +/** Sets the function to call to draw a specific boxtype. */ +void Fl::set_boxtype(Fl_Boxtype t, Fl_Box_Draw_F* f, + uchar a, uchar b, uchar c, uchar d) { + fl_box_table[t].f = f; + fl_box_table[t].set = 1; + fl_box_table[t].dx = a; + fl_box_table[t].dy = b; + fl_box_table[t].dw = c; + fl_box_table[t].dh = d; +} +/** Copies the from boxtype. */ +void Fl::set_boxtype(Fl_Boxtype to, Fl_Boxtype from) { + fl_box_table[to] = fl_box_table[from]; +} + +/** + Draws a box using given type, position, size and color. + \param[in] t box type + \param[in] x, y, w, h position and size + \param[in] c color +*/ +void fl_draw_box(Fl_Boxtype t, int x, int y, int w, int h, Fl_Color c) { + if (t && fl_box_table[t].f) fl_box_table[t].f(x,y,w,h,c); +} + +//extern Fl_Widget *fl_boxcheat; // hack set by Fl_Window.cxx +/** Draws the widget box according its box style */ +void Fl_Widget::draw_box() const { + if (box_) draw_box((Fl_Boxtype)box_, x_, y_, w_, h_, color_); + draw_backdrop(); +} +/** If FL_ALIGN_IMAGE_BACKDROP is set, the image or deimage will be drawn */ +void Fl_Widget::draw_backdrop() const { + if (align() & FL_ALIGN_IMAGE_BACKDROP) { + const Fl_Image *img = image(); + // if there is no image, we will not draw the deimage either + if (img && deimage() && !active_r()) + img = deimage(); + if (img) + ((Fl_Image*)img)->draw(x_+(w_-img->w())/2, y_+(h_-img->h())/2); + } +} +/** Draws a box of type t, of color c at the widget's position and size. */ +void Fl_Widget::draw_box(Fl_Boxtype t, Fl_Color c) const { + draw_box(t, x_, y_, w_, h_, c); +} +/** Draws a box of type t, of color c at the position X,Y and size W,H. */ +void Fl_Widget::draw_box(Fl_Boxtype t, int X, int Y, int W, int H, Fl_Color c) const { + draw_it_active = active_r(); + fl_box_table[t].f(X, Y, W, H, c); + draw_it_active = 1; +} + +// +// End of "$Id: fl_boxtype.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_call_main.c b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_call_main.c new file mode 100644 index 0000000..00f349f --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_call_main.c @@ -0,0 +1,143 @@ +/* + * "$Id: fl_call_main.c 7903 2010-11-28 21:06:39Z matt $" + * + * Copyright 1998-2010 by Bill Spitzak and others. + * + * fl_call_main() calls main() for you Windows people. Needs to be done in C + * because Borland C++ won't let you call main() from C++. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems on the following page: + * + * http://www.fltk.org/str.php + */ + +/* + * This WinMain() function can be overridden by an application and + * is provided for compatibility with programs written for other + * operating systems that conform to the ANSI standard entry point + * "main()". This will allow you to build a WIN32 Application + * without any special settings. + * + * Because of problems with the Microsoft Visual C++ header files + * and/or compiler, you cannot have a WinMain function in a DLL. + * I don't know why. Thus, this nifty feature is only available + * if you link to the static library. + * + * Currently the debug version of this library will create a + * console window for your application so you can put printf() + * statements for debugging or informational purposes. Ultimately + * we want to update this to always use the parent's console, + * but at present we have not identified a function or API in + * Microsoft(r) Windows(r) that allows for it. + */ + +#if defined(WIN32) && !defined(FL_DLL) && !defined (__GNUC__) + +# include +# include +# include +# include + +extern int main(int, char *[]); + +# ifdef BORLAND5 +# define __argc _argc +# define __argv _argv +# endif /* BORLAND5 */ + +/* static int mbcs2utf(const char *s, int l, char *dst, unsigned dstlen) */ +static int mbcs2utf(const char *s, int l, char *dst) +{ + static xchar *mbwbuf; + unsigned dstlen = 0; + if (!s) return 0; + dstlen = (l * 6) + 6; + mbwbuf = (xchar*)malloc(dstlen * sizeof(xchar)); + l = mbstowcs(mbwbuf, s, l); +/* l = fl_unicode2utf(mbwbuf, l, dst); */ + l = fl_utf8fromwc(dst, dstlen, mbwbuf, l); + dst[l] = 0; + free(mbwbuf); + return l; +} + +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, + LPSTR lpCmdLine, int nCmdShow) { + int rc, i; + char **ar; + +# ifdef _DEBUG + /* + * If we are using compiling in debug mode, open a console window so + * we can see any printf's, etc... + * + * While we can detect if the program was run from the command-line - + * look at the CMDLINE environment variable, it will be "WIN" for + * programs started from the GUI - the shell seems to run all WIN32 + * applications in the background anyways... + */ + + AllocConsole(); + freopen("conin$", "r", stdin); + freopen("conout$", "w", stdout); + freopen("conout$", "w", stderr); +# endif /* _DEBUG */ + + ar = (char**) malloc(sizeof(char*) * (__argc + 1)); + i = 0; + while (i < __argc) { + int l; + unsigned dstlen; + if (__wargv ) { + for (l = 0; __wargv[i] && __wargv[i][l]; l++) {}; /* is this just wstrlen??? */ + dstlen = (l * 5) + 1; + ar[i] = (char*) malloc(dstlen); +/* ar[i][fl_unicode2utf(__wargv[i], l, ar[i])] = 0; */ + dstlen = fl_utf8fromwc(ar[i], dstlen, __wargv[i], l); + ar[i][dstlen] = 0; + } else { + for (l = 0; __argv[i] && __argv[i][l]; l++) {}; + dstlen = (l * 5) + 1; + ar[i] = (char*) malloc(dstlen); +/* ar[i][mbcs2utf(__argv[i], l, ar[i], dstlen)] = 0; */ + ar[i][mbcs2utf(__argv[i], l, ar[i])] = 0; + } + i++; + } + ar[__argc] = 0; + /* Run the standard main entry point function... */ + rc = main(__argc, ar); + +# ifdef _DEBUG + fclose(stdin); + fclose(stdout); + fclose(stderr); +# endif /* _DEBUG */ + + return rc; +} + +#elif defined(__hpux) +/* This code to prevent "empty translation unit" or similar warnings... */ +static void dummy(void) {} +#endif /* WIN32 && !FL_DLL && !__GNUC__ */ + +/* + * End of "$Id: fl_call_main.c 7903 2010-11-28 21:06:39Z matt $". + */ + diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_cmap.h b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_cmap.h new file mode 100644 index 0000000..3b05ee7 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_cmap.h @@ -0,0 +1,256 @@ + 0x00000000, + 0xff000000, + 0x00ff0000, + 0xffff0000, + 0x0000ff00, + 0xff00ff00, + 0x00ffff00, + 0xffffff00, + 0x55555500, + 0xc6717100, + 0x71c67100, + 0x8e8e3800, + 0x7171c600, + 0x8e388e00, + 0x388e8e00, + 0x00008000, + 0xa8a89800, + 0xe8e8d800, + 0x68685800, + 0x98a8a800, + 0xd8e8e800, + 0x58686800, + 0x9c9ca800, + 0xdcdce800, + 0x5c5c6800, + 0x9ca89c00, + 0xdce8dc00, + 0x5c685c00, + 0x90909000, + 0xc0c0c000, + 0x50505000, + 0xa0a0a000, + 0x00000000, + 0x0d0d0d00, + 0x1a1a1a00, + 0x26262600, + 0x31313100, + 0x3d3d3d00, + 0x48484800, + 0x55555500, + 0x5f5f5f00, + 0x6a6a6a00, + 0x75757500, + 0x80808000, + 0x8a8a8a00, + 0x95959500, + 0xa0a0a000, + 0xaaaaaa00, + 0xb5b5b500, + 0xc0c0c000, + 0xcbcbcb00, + 0xd5d5d500, + 0xe0e0e000, + 0xeaeaea00, + 0xf5f5f500, + 0xffffff00, + 0x00000000, + 0x00240000, + 0x00480000, + 0x006d0000, + 0x00910000, + 0x00b60000, + 0x00da0000, + 0x00ff0000, + 0x3f000000, + 0x3f240000, + 0x3f480000, + 0x3f6d0000, + 0x3f910000, + 0x3fb60000, + 0x3fda0000, + 0x3fff0000, + 0x7f000000, + 0x7f240000, + 0x7f480000, + 0x7f6d0000, + 0x7f910000, + 0x7fb60000, + 0x7fda0000, + 0x7fff0000, + 0xbf000000, + 0xbf240000, + 0xbf480000, + 0xbf6d0000, + 0xbf910000, + 0xbfb60000, + 0xbfda0000, + 0xbfff0000, + 0xff000000, + 0xff240000, + 0xff480000, + 0xff6d0000, + 0xff910000, + 0xffb60000, + 0xffda0000, + 0xffff0000, + 0x00003f00, + 0x00243f00, + 0x00483f00, + 0x006d3f00, + 0x00913f00, + 0x00b63f00, + 0x00da3f00, + 0x00ff3f00, + 0x3f003f00, + 0x3f243f00, + 0x3f483f00, + 0x3f6d3f00, + 0x3f913f00, + 0x3fb63f00, + 0x3fda3f00, + 0x3fff3f00, + 0x7f003f00, + 0x7f243f00, + 0x7f483f00, + 0x7f6d3f00, + 0x7f913f00, + 0x7fb63f00, + 0x7fda3f00, + 0x7fff3f00, + 0xbf003f00, + 0xbf243f00, + 0xbf483f00, + 0xbf6d3f00, + 0xbf913f00, + 0xbfb63f00, + 0xbfda3f00, + 0xbfff3f00, + 0xff003f00, + 0xff243f00, + 0xff483f00, + 0xff6d3f00, + 0xff913f00, + 0xffb63f00, + 0xffda3f00, + 0xffff3f00, + 0x00007f00, + 0x00247f00, + 0x00487f00, + 0x006d7f00, + 0x00917f00, + 0x00b67f00, + 0x00da7f00, + 0x00ff7f00, + 0x3f007f00, + 0x3f247f00, + 0x3f487f00, + 0x3f6d7f00, + 0x3f917f00, + 0x3fb67f00, + 0x3fda7f00, + 0x3fff7f00, + 0x7f007f00, + 0x7f247f00, + 0x7f487f00, + 0x7f6d7f00, + 0x7f917f00, + 0x7fb67f00, + 0x7fda7f00, + 0x7fff7f00, + 0xbf007f00, + 0xbf247f00, + 0xbf487f00, + 0xbf6d7f00, + 0xbf917f00, + 0xbfb67f00, + 0xbfda7f00, + 0xbfff7f00, + 0xff007f00, + 0xff247f00, + 0xff487f00, + 0xff6d7f00, + 0xff917f00, + 0xffb67f00, + 0xffda7f00, + 0xffff7f00, + 0x0000bf00, + 0x0024bf00, + 0x0048bf00, + 0x006dbf00, + 0x0091bf00, + 0x00b6bf00, + 0x00dabf00, + 0x00ffbf00, + 0x3f00bf00, + 0x3f24bf00, + 0x3f48bf00, + 0x3f6dbf00, + 0x3f91bf00, + 0x3fb6bf00, + 0x3fdabf00, + 0x3fffbf00, + 0x7f00bf00, + 0x7f24bf00, + 0x7f48bf00, + 0x7f6dbf00, + 0x7f91bf00, + 0x7fb6bf00, + 0x7fdabf00, + 0x7fffbf00, + 0xbf00bf00, + 0xbf24bf00, + 0xbf48bf00, + 0xbf6dbf00, + 0xbf91bf00, + 0xbfb6bf00, + 0xbfdabf00, + 0xbfffbf00, + 0xff00bf00, + 0xff24bf00, + 0xff48bf00, + 0xff6dbf00, + 0xff91bf00, + 0xffb6bf00, + 0xffdabf00, + 0xffffbf00, + 0x0000ff00, + 0x0024ff00, + 0x0048ff00, + 0x006dff00, + 0x0091ff00, + 0x00b6ff00, + 0x00daff00, + 0x00ffff00, + 0x3f00ff00, + 0x3f24ff00, + 0x3f48ff00, + 0x3f6dff00, + 0x3f91ff00, + 0x3fb6ff00, + 0x3fdaff00, + 0x3fffff00, + 0x7f00ff00, + 0x7f24ff00, + 0x7f48ff00, + 0x7f6dff00, + 0x7f91ff00, + 0x7fb6ff00, + 0x7fdaff00, + 0x7fffff00, + 0xbf00ff00, + 0xbf24ff00, + 0xbf48ff00, + 0xbf6dff00, + 0xbf91ff00, + 0xbfb6ff00, + 0xbfdaff00, + 0xbfffff00, + 0xff00ff00, + 0xff24ff00, + 0xff48ff00, + 0xff6dff00, + 0xff91ff00, + 0xffb6ff00, + 0xffdaff00, + 0xffffff00 diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_color.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_color.cxx new file mode 100644 index 0000000..9ff91e0 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_color.cxx @@ -0,0 +1,474 @@ +// +// "$Id: fl_color.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Color functions for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/** + \file fl_color.cxx + \brief Color handling +*/ + +// Implementation of fl_color(i), fl_color(r,g,b). + +#ifdef WIN32 +# include "fl_color_win32.cxx" +#elif defined(__APPLE__) +# include "fl_color_mac.cxx" +#else + +// Also code to look at the X visual and figure out the best way to turn +// a color into a pixel value. + +// SGI compiler seems to have problems with unsigned char arguments +// being used to index arrays. So I always copy them to an integer +// before use. + +# include "Fl_XColor.H" +# include +# include +# include + +//////////////////////////////////////////////////////////////// +// figure_out_visual() calculates masks & shifts for generating +// pixels in true-color visuals: + +uchar fl_redmask; /**< color mask used in current color map handling */ +uchar fl_greenmask; /**< color mask used in current color map handling */ +uchar fl_bluemask; /**< color mask used in current color map handling */ + +int fl_redshift; /**< color shift used in current color map handling */ +int fl_greenshift; /**< color shift used in current color map handling */ +int fl_blueshift; /**< color shift used in current color map handling */ +int fl_extrashift; /**< color shift used in current color map handling */ + +static uchar beenhere; + +static void figure_out_visual() { + beenhere = 1; + if (!fl_visual->red_mask || !fl_visual->green_mask || !fl_visual->blue_mask){ +# if USE_COLORMAP + fl_redmask = 0; + return; +# else + Fl::fatal("Requires true color visual"); +# endif + } + + // get the bit masks into a more useful form: + int i,j,m; + + for (i = 0, m = 1; m; i++, m<<=1) if (fl_visual->red_mask & m) break; + for (j = i; m; j++, m<<=1) if (!(fl_visual->red_mask & m)) break; + fl_redshift = j-8; + fl_redmask = (j-i >= 8) ? 0xFF : 0xFF-(255>>(j-i)); + + for (i = 0, m = 1; m; i++, m<<=1) if (fl_visual->green_mask & m) break; + for (j = i; m; j++, m<<=1) if (!(fl_visual->green_mask & m)) break; + fl_greenshift = j-8; + fl_greenmask = (j-i >= 8) ? 0xFF : 0xFF-(255>>(j-i)); + + for (i = 0, m = 1; m; i++, m<<=1) if (fl_visual->blue_mask & m) break; + for (j = i; m; j++, m<<=1) if (!(fl_visual->blue_mask & m)) break; + fl_blueshift = j-8; + fl_bluemask = (j-i >= 8) ? 0xFF : 0xFF-(255>>(j-i)); + + i = fl_redshift; + if (fl_greenshift < i) i = fl_greenshift; + if (fl_blueshift < i) i = fl_blueshift; + if (i < 0) { + fl_extrashift = -i; + fl_redshift -= i; fl_greenshift -= i; fl_blueshift -= i; + } else + fl_extrashift = 0; + +} + +static unsigned fl_cmap[256] = { +#include "fl_cmap.h" // this is a file produced by "cmap.cxx": +}; + +# if HAVE_OVERLAY +/** HAVE_OVERLAY determines whether fl_xmap is one or two planes */ +Fl_XColor fl_xmap[2][256]; +/** HAVE_OVERLAY determines whether fl_overlay is variable or defined as 0 */ +uchar fl_overlay; +Colormap fl_overlay_colormap; +XVisualInfo* fl_overlay_visual; +ulong fl_transparent_pixel; +# else +/** HAVE_OVERLAY determines whether fl_xmap is one or two planes */ +Fl_XColor fl_xmap[1][256]; +/** HAVE_OVERLAY determines whether fl_overlay is variable or defined as 0 */ +# define fl_overlay 0 +# endif + +/** Current color for drawing operations */ +Fl_Color fl_color_; + +void Fl_Graphics_Driver::color(Fl_Color i) { + if (i & 0xffffff00) { + unsigned rgb = (unsigned)i; + fl_color((uchar)(rgb >> 24), (uchar)(rgb >> 16), (uchar)(rgb >> 8)); + } else { + fl_color_ = i; + if(!fl_gc) return; // don't get a default gc if current window is not yet created/valid + XSetForeground(fl_display, fl_gc, fl_xpixel(i)); + } +} + +void Fl_Graphics_Driver::color(uchar r,uchar g,uchar b) { + fl_color_ = fl_rgb_color(r, g, b); + if(!fl_gc) return; // don't get a default gc if current window is not yet created/valid + XSetForeground(fl_display, fl_gc, fl_xpixel(r,g,b)); +} + +/** \addtogroup fl_attributes + @{ */ +//////////////////////////////////////////////////////////////// +// Get an rgb color. This is easy for a truecolor visual. For +// colormapped it picks the closest color out of the cube in the +// fltk colormap. However if this color cube entry has been +// requested before, you will get the earlier requested color, and +// even this may be approximated if the X colormap was full. + +/** + Returns the X pixel number used to draw the given rgb color. + This is the X pixel that fl_color() would use. + \param[in] r,g,b color components + \return X pixel number +*/ +ulong fl_xpixel(uchar r,uchar g,uchar b) { + if (!beenhere) figure_out_visual(); +# if USE_COLORMAP + if (!fl_redmask) { + // find closest entry in the colormap: + Fl_Color i = + fl_color_cube(r*FL_NUM_RED/256,g*FL_NUM_GREEN/256,b*FL_NUM_BLUE/256); + Fl_XColor &xmap = fl_xmap[fl_overlay][i]; + if (xmap.mapped) return xmap.pixel; + // if not black or white, change the entry to be an exact match: + if (i != FL_COLOR_CUBE && i != 0xFF) + fl_cmap[i] = (r<<24)|(g<<16)|(b<<8); + return fl_xpixel(i); // allocate an X color + } +# endif + return + (((r&fl_redmask) << fl_redshift)+ + ((g&fl_greenmask)<> fl_extrashift; +} + +//////////////////////////////////////////////////////////////// +// Get a color out of the fltk colormap. Again for truecolor +// visuals this is easy. For colormap this actually tries to allocate +// an X color, and does a least-squares match to find the closest +// color if X cannot allocate that color. + +// calculate what color is actually on the screen for a mask: +static inline uchar realcolor(uchar color, uchar mask) { +# if 0 + // accurate version if the display has linear gamma, but fl_draw_image + // works better with the simpler version on most screens... + uchar m = mask; + uchar result = color&m; + for (;;) { + while (m&mask) {m>>=1; color>>=1;} + if (!m) break; + mask = m; + result |= color&m; + } + return result; +# else + return (color&mask) | ( (~mask)&(mask>>1) ); +# endif +} + +/** + Returns the X pixel number used to draw the given FLTK color index. + This is the X pixel that fl_color() would use. + \param[in] i color index + \return X pixel number +*/ +ulong fl_xpixel(Fl_Color i) { + if (i & 0xffffff00) { + return fl_xpixel((i >> 24) & 255, (i >> 16) & 255, (i >> 8) & 255); + } + + Fl_XColor &xmap = fl_xmap[fl_overlay][i]; + if (xmap.mapped) return xmap.pixel; + + if (!beenhere) figure_out_visual(); + + uchar r,g,b; + {unsigned c = fl_cmap[i]; r=uchar(c>>24); g=uchar(c>>16); b=uchar(c>>8);} + +# if USE_COLORMAP + Colormap colormap = fl_colormap; +# if HAVE_OVERLAY + if (fl_overlay) colormap = fl_overlay_colormap; else +# endif + if (fl_redmask) { +# endif + // return color for a truecolor visual: + xmap.mapped = 2; // 2 prevents XFreeColor from being called + xmap.r = realcolor(r, fl_redmask); + xmap.g = realcolor(g, fl_greenmask); + xmap.b = realcolor(b, fl_bluemask); + return xmap.pixel = + (((r&fl_redmask) << fl_redshift)+ + ((g&fl_greenmask)<> fl_extrashift; +# if USE_COLORMAP + } +# if HAVE_OVERLAY + static XColor* ac[2]; + XColor*& allcolors = ac[fl_overlay]; + static int nc[2]; + int& numcolors = nc[fl_overlay]; +# else + static XColor *allcolors; + static int numcolors; +# endif + + // I don't try to allocate colors with XAllocColor once it fails + // with any color. It is possible that it will work, since a color + // may have been freed, but some servers are extremely slow and this + // avoids one round trip: + if (!numcolors) { // don't try after a failure + XColor xcol; + xcol.red = r<<8; xcol.green = g<<8; xcol.blue = b<<8; + if (XAllocColor(fl_display, colormap, &xcol)) { + xmap.mapped = 1; + xmap.r = xcol.red>>8; + xmap.g = xcol.green>>8; + xmap.b = xcol.blue>>8; + return xmap.pixel = xcol.pixel; + } + + // I only read the colormap once. Again this is due to the slowness + // of round-trips to the X server, even though other programs may alter + // the colormap after this and make decisions here wrong. +# if HAVE_OVERLAY + if (fl_overlay) numcolors = fl_overlay_visual->colormap_size; else +# endif + numcolors = fl_visual->colormap_size; + if (!allcolors) allcolors = new XColor[numcolors]; + for (int p = numcolors; p--;) allcolors[p].pixel = p; + XQueryColors(fl_display, colormap, allcolors, numcolors); + } + + // find least-squares match: + int mindist = 0x7FFFFFFF; + unsigned int bestmatch = 0; + for (unsigned int n = numcolors; n--;) { +# if HAVE_OVERLAY + if (fl_overlay && n == fl_transparent_pixel) continue; +# endif + XColor &a = allcolors[n]; + int d, t; + t = int(r)-int(a.red>>8); d = t*t; + t = int(g)-int(a.green>>8); d += t*t; + t = int(b)-int(a.blue>>8); d += t*t; + if (d <= mindist) {bestmatch = n; mindist = d;} + } + XColor &p = allcolors[bestmatch]; + + // It appears to "work" to not call this XAllocColor, which will + // avoid another round-trip to the server. But then X does not + // know that this program "owns" this value, and can (and will) + // change it when the program that did allocate it exits: + if (XAllocColor(fl_display, colormap, &p)) { + xmap.mapped = 1; + xmap.pixel = p.pixel; + } else { + // However, if that XAllocColor fails, I have to give up and + // assume the pixel is ok for the duration of the program. This + // is due to bugs (?) in the Solaris X and some X terminals + // where XAllocColor *always* fails when the colormap is full, + // even if we ask for a color already in it... + xmap.mapped = 2; // 2 prevents XFreeColor from being called + xmap.pixel = bestmatch; + } + xmap.r = p.red>>8; + xmap.g = p.green>>8; + xmap.b = p.blue>>8; + return xmap.pixel; +# endif +} + +/** + Free color \p i if used, and clear mapping table entry. + \param[in] i color index + \param[in] overlay 0 for normal, 1 for overlay color +*/ +void Fl::free_color(Fl_Color i, int overlay) { +# if HAVE_OVERLAY +# else + if (overlay) return; +# endif + if (fl_xmap[overlay][i].mapped) { +# if USE_COLORMAP +# if HAVE_OVERLAY + Colormap colormap = overlay ? fl_overlay_colormap : fl_colormap; +# else + Colormap colormap = fl_colormap; +# endif + if (fl_xmap[overlay][i].mapped == 1) + XFreeColors(fl_display, colormap, &(fl_xmap[overlay][i].pixel), 1, 0); +# endif + fl_xmap[overlay][i].mapped = 0; + } +} + +/** + Set color mapping table entry \p i to color \p c + \param[in] i color index + \param[in] c color +*/ +void Fl::set_color(Fl_Color i, unsigned c) { + if (fl_cmap[i] != c) { + free_color(i,0); +# if HAVE_OVERLAY + free_color(i,1); +# endif + fl_cmap[i] = c; + } +} + +#endif // end of X-specific code +/** + Returns the RGB value(s) for the given FLTK color index. + + This form returns the RGB values packed in a 32-bit unsigned + integer with the red value in the upper 8 bits, the green value + in the next 8 bits, and the blue value in bits 8-15. The lower + 8 bits will always be 0. +*/ +unsigned Fl::get_color(Fl_Color i) { + if (i & 0xffffff00) return (i); + else return fl_cmap[i]; +} +/** + Sets an entry in the fl_color index table. You can set it to + any 8-bit RGB color. The color is not allocated until fl_color(i) + is used. +*/ +void Fl::set_color(Fl_Color i, uchar red, uchar green, uchar blue) { + Fl::set_color((Fl_Color)(i & 255), + ((unsigned)red<<24)+((unsigned)green<<16)+((unsigned)blue<<8)); +} +/** + Returns the RGB value(s) for the given FLTK color index. + + This form returns the red, green, and blue values + separately in referenced variables. + + See also unsigned get_color(Fl_Color c) + */ +void Fl::get_color(Fl_Color i, uchar &red, uchar &green, uchar &blue) { + unsigned c; + + if (i & 0xffffff00) c = (unsigned)i; + else c = fl_cmap[i]; + + red = uchar(c>>24); + green = uchar(c>>16); + blue = uchar(c>>8); +} + +/** + Returns the weighted average color between the two given colors. + The red, green and blue values are averages using the following formula: + \code + color = color1 * weight + color2 * (1 - weight) + \endcode + Thus, a \p weight value of 1.0 will return the first color, while a + value of 0.0 will return the second color. + \param[in] color1, color2 boundary colors + \param[in] weight weighting factor +*/ +Fl_Color fl_color_average(Fl_Color color1, Fl_Color color2, float weight) { + unsigned rgb1; + unsigned rgb2; + uchar r, g, b; + + if (color1 & 0xffffff00) rgb1 = color1; + else rgb1 = fl_cmap[color1 & 255]; + + if (color2 & 0xffffff00) rgb2 = color2; + else rgb2 = fl_cmap[color2 & 255]; + + r = (uchar)(((uchar)(rgb1>>24))*weight + ((uchar)(rgb2>>24))*(1-weight)); + g = (uchar)(((uchar)(rgb1>>16))*weight + ((uchar)(rgb2>>16))*(1-weight)); + b = (uchar)(((uchar)(rgb1>>8))*weight + ((uchar)(rgb2>>8))*(1-weight)); + + return fl_rgb_color(r, g, b); +} + +/** + Returns the inactive, dimmed version of the given color +*/ +Fl_Color fl_inactive(Fl_Color c) { + return fl_color_average(c, FL_GRAY, .33f); +} + +/** + Returns a color that contrasts with the background color. + This will be the foreground color if it contrasts sufficiently with the + background color. Otherwise, returns \p FL_WHITE or \p FL_BLACK depending + on which color provides the best contrast. + \param[in] fg,bg foreground and background colors + \return contrasting color +*/ +Fl_Color fl_contrast(Fl_Color fg, Fl_Color bg) { + unsigned c1, c2; // RGB colors + int l1, l2; // Luminosities + + + // Get the RGB values for each color... + if (fg & 0xffffff00) c1 = (unsigned)fg; + else c1 = fl_cmap[fg]; + + if (bg & 0xffffff00) c2 = (unsigned)bg; + else c2 = fl_cmap[bg]; + + // Compute the luminosity... + l1 = ((c1 >> 24) * 30 + ((c1 >> 16) & 255) * 59 + ((c1 >> 8) & 255) * 11) / 100; + l2 = ((c2 >> 24) * 30 + ((c2 >> 16) & 255) * 59 + ((c2 >> 8) & 255) * 11) / 100; + + // Compare and return the contrasting color... + if ((l1 - l2) > 60) return fg; + else if ((l2 - l1) > 60) return fg; + else if (l2 > 127) return FL_BLACK; + else return FL_WHITE; +} +/** + @} +*/ +// +// End of "$Id: fl_color.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_color_mac.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_color_mac.cxx new file mode 100644 index 0000000..def0ae4 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_color_mac.cxx @@ -0,0 +1,94 @@ +// +// "$Id: fl_color_mac.cxx 7617 2010-05-27 17:20:18Z manolo $" +// +// MacOS color functions for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2009 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// The fltk "colormap". This allows ui colors to be stored in 8-bit +// locations, and provides a level of indirection so that global color +// changes can be made. Not to be confused with the X colormap, which +// I try to hide completely. + +// matt: Neither Quartz nor Quickdraw support colormaps in this implementation +// matt: Quartz support done + +#include +#include +#include +#include + +static unsigned fl_cmap[256] = { +#include "fl_cmap.h" // this is a file produced by "cmap.cxx": +}; + +// Translations to mac data structures: +Fl_XMap fl_xmap[256]; + +Fl_XMap* fl_current_xmap; + +Fl_Color fl_color_; + +void Fl_Graphics_Driver::color(Fl_Color i) { + fl_color_ = i; + int index; + uchar r, g, b; + if (i & 0xFFFFFF00) { + // translate rgb colors into color index + r = i>>24; + g = i>>16; + b = i>> 8; + } else { + // translate index into rgb: + index = i; + unsigned c = fl_cmap[i]; + r = c>>24; + g = c>>16; + b = c>> 8; + } + if (!fl_gc) return; // no context yet? We will assign the color later. + float fr = r/255.0f; + float fg = g/255.0f; + float fb = b/255.0f; + CGContextSetRGBFillColor(fl_gc, fr, fg, fb, 1.0f); + CGContextSetRGBStrokeColor(fl_gc, fr, fg, fb, 1.0f); +} + +void Fl_Graphics_Driver::color(uchar r, uchar g, uchar b) { + fl_color_ = fl_rgb_color(r, g, b); + float fr = r/255.0f; + float fg = g/255.0f; + float fb = b/255.0f; + CGContextSetRGBFillColor(fl_gc, fr, fg, fb, 1.0f); + CGContextSetRGBStrokeColor(fl_gc, fr, fg, fb, 1.0f); +} + +void Fl::set_color(Fl_Color i, unsigned c) { + if (fl_cmap[i] != c) { + fl_cmap[i] = c; + } +} + +// +// End of "$Id: fl_color_mac.cxx 7617 2010-05-27 17:20:18Z manolo $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_color_win32.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_color_win32.cxx new file mode 100644 index 0000000..1aab0d7 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_color_win32.cxx @@ -0,0 +1,254 @@ +// +// "$Id: fl_color_win32.cxx 7617 2010-05-27 17:20:18Z manolo $" +// +// WIN32 color functions for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2009 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// The fltk "colormap". This allows ui colors to be stored in 8-bit +// locations, and provides a level of indirection so that global color +// changes can be made. Not to be confused with the X colormap, which +// I try to hide completely. + +// SGI compiler seems to have problems with unsigned char arguments +// being used to index arrays. So I always copy them to an integer +// before use. + +#include +#include +#include +#include + +static unsigned fl_cmap[256] = { +#include "fl_cmap.h" // this is a file produced by "cmap.cxx": +}; + +// Translations to win32 data structures: +Fl_XMap fl_xmap[256]; + +Fl_XMap* fl_current_xmap; + +HPALETTE fl_palette; +static HGDIOBJ tmppen=0; +static HPEN savepen=0; + +void fl_cleanup_pens(void) { + for (int i=0; i<256; i++) { + if (fl_xmap[i].pen) DeleteObject(fl_xmap[i].pen); + } +} + +void fl_save_pen(void) { + if(!tmppen) tmppen = CreatePen(PS_SOLID, 1, 0); + savepen = (HPEN)SelectObject(fl_gc, tmppen); +} + +void fl_restore_pen(void) { + if (savepen) SelectObject(fl_gc, savepen); + DeleteObject(tmppen); + tmppen = 0; + savepen = 0; +} + +static void clear_xmap(Fl_XMap& xmap) { + if (xmap.pen) { + HGDIOBJ tmppen = GetStockObject(BLACK_PEN); + HGDIOBJ oldpen = SelectObject(fl_gc, tmppen); // Push out the current pen of the gc + if(oldpen != xmap.pen) SelectObject(fl_gc, oldpen); // Put it back if it is not the one we are about to delete + DeleteObject((HGDIOBJ)(xmap.pen)); + xmap.pen = 0; + xmap.brush = -1; + } +} + +static void set_xmap(Fl_XMap& xmap, COLORREF c) { + xmap.rgb = c; + if (xmap.pen) { + HGDIOBJ oldpen = SelectObject(fl_gc,GetStockObject(BLACK_PEN)); // replace current pen with safe one + if (oldpen != xmap.pen)SelectObject(fl_gc,oldpen); // if old one not xmap.pen, need to put it back + DeleteObject(xmap.pen); // delete pen + } + xmap.pen = CreatePen(PS_SOLID, 1, xmap.rgb); // get a pen into xmap.pen + xmap.brush = -1; +} + +Fl_Color fl_color_; + +void Fl_Graphics_Driver::color(Fl_Color i) { + if (i & 0xffffff00) { + unsigned rgb = (unsigned)i; + fl_color((uchar)(rgb >> 24), (uchar)(rgb >> 16), (uchar)(rgb >> 8)); + } else { + fl_color_ = i; + Fl_XMap &xmap = fl_xmap[i]; + if (!xmap.pen) { +#if USE_COLORMAP + if (fl_palette) { + set_xmap(xmap, PALETTEINDEX(i)); + } else { +#endif + unsigned c = fl_cmap[i]; + set_xmap(xmap, RGB(uchar(c>>24), uchar(c>>16), uchar(c>>8))); +#if USE_COLORMAP + } +#endif + } + fl_current_xmap = ⟼ + SelectObject(fl_gc, (HGDIOBJ)(xmap.pen)); + } +} + +void Fl_Graphics_Driver::color(uchar r, uchar g, uchar b) { + static Fl_XMap xmap; + COLORREF c = RGB(r,g,b); + fl_color_ = fl_rgb_color(r, g, b); + if (!xmap.pen || c != xmap.rgb) { + clear_xmap(xmap); + set_xmap(xmap, c); + } + fl_current_xmap = ⟼ + SelectObject(fl_gc, (HGDIOBJ)(xmap.pen)); +} + +HBRUSH fl_brush() { + return fl_brush_action(0); +} + +HBRUSH fl_brush_action(int action) { + Fl_XMap *xmap = fl_current_xmap; + // Wonko: we use some statistics to cache only a limited number + // of brushes: +#define FL_N_BRUSH 16 + static struct Fl_Brush { + HBRUSH brush; + unsigned short usage; + Fl_XMap* backref; + } brushes[FL_N_BRUSH]; + + if (action) { + SelectObject(fl_gc, GetStockObject(BLACK_BRUSH)); // Load stock object + for (int i=0; ibrush; // find the associated brush + if (i != -1) { // if the brush was allready allocated + if (brushes[i].brush == NULL) goto CREATE_BRUSH; + if ( (++brushes[i].usage) > 32000 ) { // keep a usage statistic + for (int j=0; j16000) + brushes[j].usage -= 16000; + else + brushes[j].usage = 0; + } + } + return brushes[i].brush; + } else { + int umin = 32000, imin = 0; + for (i=0; ibrush = -1; + } +CREATE_BRUSH: + brushes[i].brush = CreateSolidBrush(xmap->rgb); + brushes[i].usage = 0; + brushes[i].backref = xmap; + xmap->brush = i; + return brushes[i].brush; +} + +void Fl::free_color(Fl_Color i, int overlay) { + if (overlay) return; // do something about GL overlay? + clear_xmap(fl_xmap[i]); +} + +void Fl::set_color(Fl_Color i, unsigned c) { + if (fl_cmap[i] != c) { + clear_xmap(fl_xmap[i]); + fl_cmap[i] = c; + } +} + +#if USE_COLORMAP + +// 'fl_select_palette()' - Make a color palette for 8-bit displays if necessary +// Thanks to Michael Sweet @ Easy Software Products for this + +HPALETTE +fl_select_palette(void) +{ + static char beenhere; + if (!beenhere) { + beenhere = 1; + + //if (GetDeviceCaps(fl_gc, BITSPIXEL) > 8) return NULL; + int nColors = GetDeviceCaps(fl_gc, SIZEPALETTE); + if (nColors <= 0 || nColors > 256) return NULL; + // this will try to work on < 256 color screens, but will probably + // come out quite badly. + + // I lamely try to get this variable-sized object allocated on stack: + ulong foo[(sizeof(LOGPALETTE)+256*sizeof(PALETTEENTRY))/sizeof(ulong)+1]; + LOGPALETTE *pPal = (LOGPALETTE*)foo; + + pPal->palVersion = 0x300; + pPal->palNumEntries = nColors; + + // Build 256 colors from the standard FLTK colormap... + + for (int i = 0; i < nColors; i ++) { + pPal->palPalEntry[i].peRed = (fl_cmap[i] >> 24) & 255; + pPal->palPalEntry[i].peGreen = (fl_cmap[i] >> 16) & 255; + pPal->palPalEntry[i].peBlue = (fl_cmap[i] >> 8) & 255; + pPal->palPalEntry[i].peFlags = 0; + }; + + // Create the palette: + fl_palette = CreatePalette(pPal); + } + if (fl_palette) { + SelectPalette(fl_gc, fl_palette, FALSE); + RealizePalette(fl_gc); + } + return fl_palette; +} + +#endif + +// +// End of "$Id: fl_color_win32.cxx 7617 2010-05-27 17:20:18Z manolo $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_cursor.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_cursor.cxx new file mode 100644 index 0000000..596a23c --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_cursor.cxx @@ -0,0 +1,337 @@ +// +// "$Id: fl_cursor.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Mouse cursor support for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Change the current cursor. +// Under X the cursor is attached to the X window. I tried to hide +// this and pretend that changing the cursor is a drawing function. +// This avoids a field in the Fl_Window, and I suspect is more +// portable to other systems. + +#include +#include +#include +#if !defined(WIN32) && !defined(__APPLE__) +# include +#endif +#include + +/** + Sets the cursor for the current window to the specified shape and colors. + The cursors are defined in the header file. + */ +void fl_cursor(Fl_Cursor c, Fl_Color fg, Fl_Color bg) { + if (Fl::first_window()) Fl::first_window()->cursor(c,fg,bg); +} +/** + Sets the default window cursor as well as its color. + + For back compatibility only. +*/ +void Fl_Window::default_cursor(Fl_Cursor c, Fl_Color fg, Fl_Color bg) { +// if (c == FL_CURSOR_DEFAULT) c = FL_CURSOR_ARROW; + + cursor_default = c; + cursor_fg = fg; + cursor_bg = bg; + + cursor(c, fg, bg); +} + +#ifdef WIN32 + +# ifndef IDC_HAND +# define IDC_HAND MAKEINTRESOURCE(32649) +# endif // !IDC_HAND + +void Fl_Window::cursor(Fl_Cursor c, Fl_Color c1, Fl_Color c2) { + if (!shown()) return; + // the cursor must be set for the top level window, not for subwindows + Fl_Window *w = window(), *toplevel = this; + while (w) { toplevel = w; w = w->window(); } + if (toplevel != this) { toplevel->cursor(c, c1, c2); return; } + // now set the actual cursor + if (c == FL_CURSOR_DEFAULT) { + c = cursor_default; + } + if (c > FL_CURSOR_NESW) { + i->cursor = 0; + } else if (c == FL_CURSOR_DEFAULT) { + i->cursor = fl_default_cursor; + } else { + LPSTR n; + switch (c) { + case FL_CURSOR_ARROW: n = IDC_ARROW; break; + case FL_CURSOR_CROSS: n = IDC_CROSS; break; + case FL_CURSOR_WAIT: n = IDC_WAIT; break; + case FL_CURSOR_INSERT: n = IDC_IBEAM; break; + case FL_CURSOR_HELP: n = IDC_HELP; break; + case FL_CURSOR_HAND: { + OSVERSIONINFO osvi; + + // Get the OS version: Windows 98 and 2000 have a standard + // hand cursor. + memset(&osvi, 0, sizeof(OSVERSIONINFO)); + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&osvi); + + if (osvi.dwMajorVersion > 4 || + (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion > 0 && + osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)) n = IDC_HAND; + else n = IDC_UPARROW; + } break; + case FL_CURSOR_MOVE: n = IDC_SIZEALL; break; + case FL_CURSOR_N: + case FL_CURSOR_S: + case FL_CURSOR_NS: n = IDC_SIZENS; break; + case FL_CURSOR_NE: + case FL_CURSOR_SW: + case FL_CURSOR_NESW: n = IDC_SIZENESW; break; + case FL_CURSOR_E: + case FL_CURSOR_W: + case FL_CURSOR_WE: n = IDC_SIZEWE; break; + case FL_CURSOR_SE: + case FL_CURSOR_NW: + case FL_CURSOR_NWSE: n = IDC_SIZENWSE; break; + default: n = IDC_NO; break; + } + i->cursor = LoadCursor(NULL, n); + } + SetCursor(i->cursor); +} + +#elif defined(__APPLE__) + +#ifdef __BIG_ENDIAN__ +# define E(x) x +#elif defined __LITTLE_ENDIAN__ +// Don't worry. This will be resolved at compile time +# define E(x) (x>>8)|((x<<8)&0xff00) +#else +# error "Either __LITTLE_ENDIAN__ or __BIG_ENDIAN__ must be defined" +#endif + +extern void *MACSetCursor(Fl_Cursor c); +extern Fl_Offscreen fl_create_offscreen_with_alpha(int w, int h); + + +CGContextRef CreateHelpImage(void) +{ + int w = 20, h = 20; + Fl_Offscreen off = fl_create_offscreen_with_alpha(w, h); + fl_begin_offscreen(off); + CGContextSetRGBFillColor( (CGContextRef)off, 0,0,0,0); + fl_rectf(0,0,w,h); + fl_color(FL_BLACK); + fl_font(FL_COURIER_BOLD, 20); + fl_draw("?", 1, h-1); + fl_end_offscreen(); + return (CGContextRef)off; +} + +CGContextRef CreateNoneImage(void) +{ + int w = 20, h = 20; + Fl_Offscreen off = fl_create_offscreen_with_alpha(w, h); + fl_begin_offscreen(off); + CGContextSetRGBFillColor( (CGContextRef)off, 0,0,0,0); + fl_rectf(0,0,w,h); + fl_end_offscreen(); + return (CGContextRef)off; +} + +CGContextRef CreateWatchImage(void) +{ + int w, h, r = 5; + w = 2*r+6; + h = 4*r; + Fl_Offscreen off = fl_create_offscreen_with_alpha(w, h); + fl_begin_offscreen(off); + CGContextSetRGBFillColor( (CGContextRef)off, 0,0,0,0); + fl_rectf(0,0,w,h); + CGContextTranslateCTM( (CGContextRef)off, w/2, h/2); + fl_color(FL_WHITE); + fl_circle(0, 0, r+1); + fl_color(FL_BLACK); + fl_rectf(int(-r*0.7), int(-r*1.7), int(1.4*r), int(3.4*r)); + fl_rectf(r-1, -1, 3, 3); + fl_color(FL_WHITE); + fl_pie(-r, -r, 2*r, 2*r, 0, 360); + fl_color(FL_BLACK); + fl_circle(0,0,r); + fl_xyline(0, 0, int(-r*.7)); + fl_xyline(0, 0, 0, int(-r*.7)); + fl_end_offscreen(); + return (CGContextRef)off; +} + +CGContextRef CreateNESWImage(void) +{ + int c = 7, r = 2*c; + int w = r, h = r; + Fl_Offscreen off = fl_create_offscreen_with_alpha(w, h); + fl_begin_offscreen(off); + CGContextSetRGBFillColor( (CGContextRef)off, 0,0,0,0); + fl_rectf(0,0,w,h); + CGContextTranslateCTM( (CGContextRef)off, 0, h); + CGContextScaleCTM( (CGContextRef)off, 1, -1); + fl_color(FL_BLACK); + fl_polygon(0, 0, c, 0, 0, c); + fl_polygon(r, r, r, r-c, r-c, r); + fl_line_style(FL_SOLID, 2, 0); + fl_line(0,1, r,r+1); + fl_line_style(FL_SOLID, 0, 0); + fl_end_offscreen(); + return (CGContextRef)off; +} + +CGContextRef CreateNWSEImage(void) +{ + int c = 7, r = 2*c; + int w = r, h = r; + Fl_Offscreen off = fl_create_offscreen_with_alpha(w, h); + fl_begin_offscreen(off); + CGContextSetRGBFillColor( (CGContextRef)off, 0,0,0,0); + fl_rectf(0,0,w,h); + CGContextTranslateCTM( (CGContextRef)off, 0, h); + CGContextScaleCTM( (CGContextRef)off, 1, -1); + fl_color(FL_BLACK); + fl_polygon(r-1, 0, r-1, c, r-1-c, 0); + fl_polygon(-1, r, c-1, r, -1, r-c); + fl_line_style(FL_SOLID, 2, 0); + fl_line(r-1,1, -1,r+1); + fl_line_style(FL_SOLID, 0, 0); + fl_end_offscreen(); + return (CGContextRef)off; +} + +void Fl_Window::cursor(Fl_Cursor c, Fl_Color, Fl_Color) { + if (c == FL_CURSOR_DEFAULT) { + c = cursor_default; + } + void *cursor = MACSetCursor( c ); + if (i) { + i->cursor = cursor; + } +} + +#else + +// I like the MSWindows resize cursors, so I duplicate them here: + +#define CURSORSIZE 16 +#define HOTXY 7 +static struct TableEntry { + uchar bits[CURSORSIZE*CURSORSIZE/8]; + uchar mask[CURSORSIZE*CURSORSIZE/8]; + Cursor cursor; +} table[] = { + {{ // FL_CURSOR_NS + 0x00, 0x00, 0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0x80, 0x01, 0x80, 0x01, + 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, + 0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01, 0x00, 0x00}, + { + 0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0xf0, 0x0f, 0xf0, 0x0f, 0xc0, 0x03, + 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xf0, 0x0f, + 0xf0, 0x0f, 0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01}}, + {{ // FL_CURSOR_EW + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, + 0x0c, 0x30, 0xfe, 0x7f, 0xfe, 0x7f, 0x0c, 0x30, 0x08, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x1c, 0x38, + 0xfe, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0x1c, 0x38, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, + {{ // FL_CURSOR_NWSE + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x38, 0x00, 0x78, 0x00, + 0xe8, 0x00, 0xc0, 0x01, 0x80, 0x03, 0x00, 0x17, 0x00, 0x1e, 0x00, 0x1c, + 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + { + 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0xfc, 0x00, 0x7c, 0x00, 0xfc, 0x00, + 0xfc, 0x01, 0xec, 0x03, 0xc0, 0x37, 0x80, 0x3f, 0x00, 0x3f, 0x00, 0x3e, + 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00}}, + {{ // FL_CURSOR_NESW + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x1c, 0x00, 0x1e, + 0x00, 0x17, 0x80, 0x03, 0xc0, 0x01, 0xe8, 0x00, 0x78, 0x00, 0x38, 0x00, + 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3e, 0x00, 0x3f, + 0x80, 0x3f, 0xc0, 0x37, 0xec, 0x03, 0xfc, 0x01, 0xfc, 0x00, 0x7c, 0x00, + 0xfc, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00}}, + {{0}, {0}} // FL_CURSOR_NONE & unknown +}; + +void Fl_Window::cursor(Fl_Cursor c, Fl_Color fg, Fl_Color bg) { + if (!shown()) return; + Cursor xc; + int deleteit = 0; + if (c == FL_CURSOR_DEFAULT) { + c = cursor_default; + fg = cursor_fg; + bg = cursor_bg; + } + + if (!c) { + xc = None; + } else { + if (c >= FL_CURSOR_NS) { + TableEntry *q = (c > FL_CURSOR_NESW) ? table+4 : table+(c-FL_CURSOR_NS); + if (!(q->cursor)) { + XColor dummy = { 0 }; + Pixmap p = XCreateBitmapFromData(fl_display, + RootWindow(fl_display, fl_screen), (const char*)(q->bits), + CURSORSIZE, CURSORSIZE); + Pixmap m = XCreateBitmapFromData(fl_display, + RootWindow(fl_display, fl_screen), (const char*)(q->mask), + CURSORSIZE, CURSORSIZE); + q->cursor = XCreatePixmapCursor(fl_display, p,m,&dummy, &dummy, + HOTXY, HOTXY); + XFreePixmap(fl_display, m); + XFreePixmap(fl_display, p); + } + xc = q->cursor; + } else { + xc = XCreateFontCursor(fl_display, (c-1)*2); + deleteit = 1; + } + XColor fgc; + uchar r,g,b; + Fl::get_color(fg,r,g,b); + fgc.red = r<<8; fgc.green = g<<8; fgc.blue = b<<8; + XColor bgc; + Fl::get_color(bg,r,g,b); + bgc.red = r<<8; bgc.green = g<<8; bgc.blue = b<<8; + XRecolorCursor(fl_display, xc, &fgc, &bgc); + } + XDefineCursor(fl_display, fl_xid(this), xc); + if (deleteit) XFreeCursor(fl_display, xc); +} + +#endif + +// +// End of "$Id: fl_cursor.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_curve.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_curve.cxx new file mode 100644 index 0000000..2f86552 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_curve.cxx @@ -0,0 +1,110 @@ +// +// "$Id: fl_curve.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Bezier curve functions for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/** + \file fl_curve.cxx + \brief Utility for drawing Bezier curves, adding the points to the + current fl_begin/fl_vertex/fl_end path. + + Incremental math implementation: + I very much doubt this is optimal! From Foley/vanDam page 511. + If anybody has a better algorithm, please send it! +*/ + +#include +#include + +void Fl_Graphics_Driver::curve(double X0, double Y0, + double X1, double Y1, + double X2, double Y2, + double X3, double Y3) { + + double x = fl_transform_x(X0,Y0); + double y = fl_transform_y(X0,Y0); + + // draw point 0: + fl_transformed_vertex(x,y); + + double x1 = fl_transform_x(X1,Y1); + double yy1 = fl_transform_y(X1,Y1); + double x2 = fl_transform_x(X2,Y2); + double y2 = fl_transform_y(X2,Y2); + double x3 = fl_transform_x(X3,Y3); + double y3 = fl_transform_y(X3,Y3); + + // find the area: + double a = fabs((x-x2)*(y3-yy1)-(y-y2)*(x3-x1)); + double b = fabs((x-x3)*(y2-yy1)-(y-y3)*(x2-x1)); + if (b > a) a = b; + + // use that to guess at the number of segments: + int n = int(sqrt(a)/4); + if (n > 1) { + if (n > 100) n = 100; // make huge curves not hang forever + + double e = 1.0/n; + + // calculate the coefficients of 3rd order equation: + double xa = (x3-3*x2+3*x1-x); + double xb = 3*(x2-2*x1+x); + double xc = 3*(x1-x); + // calculate the forward differences: + double dx1 = ((xa*e+xb)*e+xc)*e; + double dx3 = 6*xa*e*e*e; + double dx2 = dx3 + 2*xb*e*e; + + // calculate the coefficients of 3rd order equation: + double ya = (y3-3*y2+3*yy1-y); + double yb = 3*(y2-2*yy1+y); + double yc = 3*(yy1-y); + // calculate the forward differences: + double dy1 = ((ya*e+yb)*e+yc)*e; + double dy3 = 6*ya*e*e*e; + double dy2 = dy3 + 2*yb*e*e; + + // draw points 1 .. n-2: + for (int m=2; m +#include + +extern uchar* fl_gray_ramp(); + +static void fl_diamond_up_box(int x,int y,int w,int h,Fl_Color bgcolor) { + w &= -2; + h &= -2; + int x1 = x+w/2; + int y1 = y+h/2; + fl_color(bgcolor); fl_polygon(x+3, y1, x1,y+3, x+w-3,y1, x1,y+h-3); + uchar *g = fl_gray_ramp(); + fl_color(g['W']); fl_line(x+1, y1, x1, y+1, x+w-1, y1); + fl_color(g['U']); fl_line(x+2, y1, x1, y+2, x+w-2, y1); + fl_color(g['S']); fl_line(x+3, y1, x1, y+3, x+w-3, y1); + fl_color(g['P']); fl_line(x+3, y1, x1, y+h-3, x+w-3, y1); + fl_color(g['N']); fl_line(x+2, y1, x1, y+h-2, x+w-2, y1); + fl_color(g['H']); fl_line(x+1, y1, x1, y+h-1, x+w-1, y1); + fl_color(g['A']); fl_loop(x, y1, x1, y, x+w, y1, x1, y+h); +} + +static void fl_diamond_down_box(int x,int y,int w,int h,Fl_Color bgcolor) { + w &= -2; + h &= -2; + int x1 = x+w/2; + int y1 = y+h/2; + uchar *g = fl_gray_ramp(); + fl_color(g['P']); fl_line(x+0, y1, x1, y+0, x+w-0, y1); + fl_color(g['N']); fl_line(x+1, y1, x1, y+1, x+w-1, y1); + fl_color(g['H']); fl_line(x+2, y1, x1, y+2, x+w-2, y1); + fl_color(g['W']); fl_line(x+2, y1, x1, y+h-2, x+w-2, y1); + fl_color(g['U']); fl_line(x+1, y1, x1, y+h-1, x+w-1, y1); + fl_color(g['S']); fl_line(x+0, y1, x1, y+h-0, x+w-0, y1); + fl_color(bgcolor); fl_polygon(x+3, y1, x1,y+3, x+w-3,y1, x1,y+h-3); + fl_color(g['A']); fl_loop(x+3, y1, x1, y+3, x+w-3, y1, x1, y+h-3); +} + +extern void fl_internal_boxtype(Fl_Boxtype, Fl_Box_Draw_F*); +Fl_Boxtype fl_define_FL_DIAMOND_BOX() { + fl_internal_boxtype(_FL_DIAMOND_DOWN_BOX, fl_diamond_down_box); + fl_internal_boxtype(_FL_DIAMOND_UP_BOX,fl_diamond_up_box); + return _FL_DIAMOND_UP_BOX; +} + +// +// End of "$Id: fl_diamond_box.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_dnd.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_dnd.cxx new file mode 100644 index 0000000..b803033 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_dnd.cxx @@ -0,0 +1,38 @@ +// +// "$Id: fl_dnd.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Drag & Drop code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifdef WIN32 +# include "fl_dnd_win32.cxx" +#elif defined(__APPLE__) +# include "fl_dnd_mac.cxx" +#else +# include "fl_dnd_x.cxx" +#endif + +// +// End of "$Id: fl_dnd.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_dnd_mac.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_dnd_mac.cxx new file mode 100644 index 0000000..68fb64f --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_dnd_mac.cxx @@ -0,0 +1,54 @@ +// +// "$Id: fl_dnd_mac.cxx 7892 2010-11-25 18:21:21Z manolo $" +// +// Drag & Drop code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2009 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php + +// This file contains MacOS-specific code for fltk which is always linked +// in. Search other files for "__APPLE__" or filenames ending in _mac.cxx +// for other system-specific code. + +#include +#include +#include +#include + +extern char *fl_selection_buffer; +extern int fl_selection_length; + + +/** + * drag and drop whatever is in the cut-copy-paste buffer + * - create a selection first using: + * Fl::copy(const char *stuff, int len, 0) + */ +int Fl::dnd() +{ + extern int MACpreparedrag(void); + return MACpreparedrag(); +} + + +// +// End of "$Id: fl_dnd_mac.cxx 7892 2010-11-25 18:21:21Z manolo $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_dnd_win32.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_dnd_win32.cxx new file mode 100644 index 0000000..3a2732a --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_dnd_win32.cxx @@ -0,0 +1,522 @@ +// +// "$Id: fl_dnd_win32.cxx 7817 2010-11-11 11:15:18Z AlbrechtS $" +// +// Drag & Drop code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2009 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php + +// This file contains win32-specific code for fltk which is always linked +// in. Search other files for "WIN32" or filenames ending in _win32.cxx +// for other system-specific code. + +#include +#include +#include +#include +#include "flstring.h" +#include +#include +#include +#include +#include +#if defined(__CYGWIN__) +#include +#include +#else +#include +#endif + +extern char *fl_selection_buffer[2]; +extern int fl_selection_length[2]; +extern int fl_selection_buffer_length[2]; +extern char fl_i_own_selection[2]; +extern char *fl_locale2utf8(const char *s, UINT codepage = 0); +extern unsigned int fl_codepage; + +Fl_Window *fl_dnd_target_window = 0; + +#include +#include +#include + + +/** + * subclass the IDropTarget to receive data from DnD operations + */ +class FLDropTarget : public IDropTarget +{ + DWORD m_cRefCount; + DWORD lastEffect; + int px, py; +public: + FLDropTarget() : m_cRefCount(0) { } // initialize + HRESULT STDMETHODCALLTYPE QueryInterface( REFIID riid, LPVOID *ppvObject ) { + if (IID_IUnknown==riid || IID_IDropTarget==riid) + { + *ppvObject=this; + ((LPUNKNOWN)*ppvObject)->AddRef(); + return S_OK; + } + *ppvObject = NULL; + return E_NOINTERFACE; + } + ULONG STDMETHODCALLTYPE AddRef() { return ++m_cRefCount; } + ULONG STDMETHODCALLTYPE Release() { + long nTemp; + nTemp = --m_cRefCount; + if(nTemp==0) + delete this; + return nTemp; + } + HRESULT STDMETHODCALLTYPE DragEnter( IDataObject *pDataObj, DWORD /*grfKeyState*/, POINTL pt, DWORD *pdwEffect) { + if( !pDataObj ) return E_INVALIDARG; + // set e_modifiers here from grfKeyState, set e_x and e_root_x + // check if FLTK handles this drag and return if it can't (i.e. BMP drag without filename) + POINT ppt; + Fl::e_x_root = ppt.x = pt.x; + Fl::e_y_root = ppt.y = pt.y; + HWND hWnd = WindowFromPoint( ppt ); + Fl_Window *target = fl_find( hWnd ); + if (target) { + Fl::e_x = Fl::e_x_root-target->x(); + Fl::e_y = Fl::e_y_root-target->y(); + } + fl_dnd_target_window = target; + px = pt.x; py = pt.y; + if (fillCurrentDragData(pDataObj)) { + // FLTK has no mechanism yet for the different drop effects, so we allow move and copy + if ( target && Fl::handle( FL_DND_ENTER, target ) ) + *pdwEffect = DROPEFFECT_MOVE|DROPEFFECT_COPY; //|DROPEFFECT_LINK; + else + *pdwEffect = DROPEFFECT_NONE; + } else { + *pdwEffect = DROPEFFECT_NONE; + } + lastEffect = *pdwEffect; + return S_OK; + } + HRESULT STDMETHODCALLTYPE DragOver( DWORD /*grfKeyState*/, POINTL pt, DWORD *pdwEffect) { + if ( px==pt.x && py==pt.y ) + { + *pdwEffect = lastEffect; + return S_OK; + } + if ( !fl_dnd_target_window ) + { + *pdwEffect = lastEffect = DROPEFFECT_NONE; + return S_OK; + } + // set e_modifiers here from grfKeyState, set e_x and e_root_x + Fl::e_x_root = pt.x; + Fl::e_y_root = pt.y; + if (fl_dnd_target_window) { + Fl::e_x = Fl::e_x_root-fl_dnd_target_window->x(); + Fl::e_y = Fl::e_y_root-fl_dnd_target_window->y(); + } + if (fillCurrentDragData(0)) { + // Fl_Group will change DND_DRAG into DND_ENTER and DND_LEAVE if needed + if ( Fl::handle( FL_DND_DRAG, fl_dnd_target_window ) ) + *pdwEffect = DROPEFFECT_MOVE|DROPEFFECT_COPY; //|DROPEFFECT_LINK; + else + *pdwEffect = DROPEFFECT_NONE; + } else { + *pdwEffect = DROPEFFECT_NONE; + } + px = pt.x; py = pt.y; + lastEffect = *pdwEffect; + return S_OK; + } + HRESULT STDMETHODCALLTYPE DragLeave() { + if ( fl_dnd_target_window && fillCurrentDragData(0)) + { + Fl::handle( FL_DND_LEAVE, fl_dnd_target_window ); + fl_dnd_target_window = 0; + clearCurrentDragData(); + } + return S_OK; + } + HRESULT STDMETHODCALLTYPE Drop( IDataObject *data, DWORD /*grfKeyState*/, POINTL pt, DWORD* /*pdwEffect*/) { + if ( !fl_dnd_target_window ) + return S_OK; + Fl_Window *target = fl_dnd_target_window; + fl_dnd_target_window = 0; + Fl::e_x_root = pt.x; + Fl::e_y_root = pt.y; + if (target) { + Fl::e_x = Fl::e_x_root-target->x(); + Fl::e_y = Fl::e_y_root-target->y(); + } + // tell FLTK that the user released an object on this widget + if ( !Fl::handle( FL_DND_RELEASE, target ) ) + return S_OK; + + Fl_Widget *w = target; + while (w->parent()) w = w->window(); + HWND hwnd = fl_xid( (Fl_Window*)w ); + if (fillCurrentDragData(data)) { + int old_event = Fl::e_number; + Fl::belowmouse()->handle(Fl::e_number = FL_PASTE); // e_text will be invalid after this call + Fl::e_number = old_event; + SetForegroundWindow( hwnd ); + clearCurrentDragData(); + return S_OK; + } + return S_OK; + } +private: + + static IDataObject *currDragRef; + static char *currDragData; + static int currDragSize; + static char currDragResult; + + static void clearCurrentDragData() { + currDragRef = 0; + if (currDragData) free(currDragData); + currDragData = 0; + currDragSize = 0; + currDragResult = 0; + } + static char fillCurrentDragData(IDataObject *data) { + // shortcut through this whole procedure if there is no fresh data + if (!data) + return currDragResult; + // shortcut through this whole procedure if this is still the same drag event + // (* this is safe, because 'currDragRef' is cleared on Leave and Drop events) + if (data==currDragRef) + return currDragResult; + + // clear currDrag* for a new drag event + clearCurrentDragData(); + + // fill currDrag* with ASCII data, if available + FORMATETC fmt = { 0 }; + STGMEDIUM medium = { 0 }; + fmt.tymed = TYMED_HGLOBAL; + fmt.dwAspect = DVASPECT_CONTENT; + fmt.lindex = -1; + fmt.cfFormat = CF_TEXT; + // if it is ASCII text, return a copy of it + if ( data->GetData( &fmt, &medium )==S_OK ) + { + void *stuff = GlobalLock( medium.hGlobal ); + Fl::e_length = strlen((char*)stuff); + Fl::e_text = strdup((char*)stuff); + GlobalUnlock( medium.hGlobal ); + ReleaseStgMedium( &medium ); + currDragResult = 1; + return currDragResult; + } + // else fill currDrag* with filenames, if possible + memset(&fmt, 0, sizeof(fmt)); + fmt.tymed = TYMED_HGLOBAL; + fmt.dwAspect = DVASPECT_CONTENT; + fmt.lindex = -1; + fmt.cfFormat = CF_HDROP; + // if it is a pathname list, send an FL_PASTE with a \n separated list of filepaths + if ( data->GetData( &fmt, &medium )==S_OK ) + { + HDROP hdrop = (HDROP)medium.hGlobal; + int i, n, nn = 0, nf = DragQueryFileW( hdrop, (UINT)-1, 0, 0 ); + for ( i=0; ihandle(FL_DROP); +// free( Fl::e_text ); + ReleaseStgMedium( &medium ); + currDragResult = 1; + return currDragResult; + } + currDragResult = 0; + return currDragResult; + } +} flDropTarget; + +IDropTarget *flIDropTarget = &flDropTarget; + +IDataObject *FLDropTarget::currDragRef = 0; +char *FLDropTarget::currDragData = 0; +int FLDropTarget::currDragSize = 0; +char FLDropTarget::currDragResult = 0; + +/** + * this class is needed to allow FLTK apps to be a DnD source + */ +class FLDropSource : public IDropSource +{ + DWORD m_cRefCount; +public: + FLDropSource() { m_cRefCount = 0; } + HRESULT STDMETHODCALLTYPE QueryInterface( REFIID riid, LPVOID *ppvObject ) { + if (IID_IUnknown==riid || IID_IDropSource==riid) + { + *ppvObject=this; + ((LPUNKNOWN)*ppvObject)->AddRef(); + return S_OK; + } + *ppvObject = NULL; + return E_NOINTERFACE; + } + ULONG STDMETHODCALLTYPE AddRef() { return ++m_cRefCount; } + ULONG STDMETHODCALLTYPE Release() { + long nTemp; + nTemp = --m_cRefCount; + if(nTemp==0) + delete this; + return nTemp; + } + STDMETHODIMP GiveFeedback( ulong ) { return DRAGDROP_S_USEDEFAULTCURSORS; } + STDMETHODIMP QueryContinueDrag( BOOL esc, DWORD keyState ) { + if ( esc ) + return DRAGDROP_S_CANCEL; + if ( !(keyState & (MK_LBUTTON|MK_MBUTTON|MK_RBUTTON)) ) + return DRAGDROP_S_DROP; + return S_OK; + } +}; +class FLEnum : public IEnumFORMATETC +{ +public: + int n; + LONG m_lRefCount; + + ULONG __stdcall AddRef(void) { + return InterlockedIncrement(&m_lRefCount); + } + + ULONG __stdcall Release(void) { + LONG count = InterlockedDecrement(&m_lRefCount); + if(count == 0) { + delete this; + return 0; + } else { + return count; + } + } + + + HRESULT __stdcall QueryInterface(REFIID iid, void **ppvObject) { + if(iid == IID_IEnumFORMATETC || iid == IID_IUnknown) { + AddRef(); + *ppvObject = this; + return S_OK; + } else { + *ppvObject = 0; + return E_NOINTERFACE; + } + } + + HRESULT __stdcall Next(ULONG celt, FORMATETC * rgelt, ULONG *pceltFetched) { + if (n > 0) return S_FALSE; + for (ULONG i = 0; i < celt; i++) { + n++; + rgelt->cfFormat = CF_HDROP; + rgelt->dwAspect = DVASPECT_CONTENT; + rgelt->lindex = -1; + rgelt->ptd = NULL; + rgelt->tymed = TYMED_HGLOBAL; + } + if (pceltFetched) *pceltFetched = celt; + return S_OK; + } + + HRESULT __stdcall Skip(ULONG celt) { + n += celt; + return (n == 0) ? S_OK : S_FALSE; + } + + HRESULT __stdcall Reset(void) { + n = 0; + return S_OK; + } + + HRESULT __stdcall Clone(IEnumFORMATETC **ppenum){ + *ppenum = new FLEnum(); + return S_OK; + } + + FLEnum(void) { + m_lRefCount = 1; + n = 0; + } + + virtual ~FLEnum(void) { + n = 0; + } +}; + + +/** + This is the actual object that FLTK can drop somewhere. + + The implementation is minimal, but it should work with all decent Win32 drop targets +*/ +class FLDataObject : public IDataObject +{ + DWORD m_cRefCount; + FLEnum *m_EnumF; +public: + FLDataObject() { m_cRefCount = 1; }// m_EnumF = new FLEnum();} + HRESULT STDMETHODCALLTYPE QueryInterface( REFIID riid, LPVOID *ppvObject ) { + if (IID_IUnknown==riid || IID_IDataObject==riid) + { + *ppvObject=this; + ((LPUNKNOWN)*ppvObject)->AddRef(); + return S_OK; + } + *ppvObject = NULL; + return E_NOINTERFACE; + } + ULONG STDMETHODCALLTYPE AddRef() { return ++m_cRefCount; } + ULONG STDMETHODCALLTYPE Release() { + long nTemp; + nTemp = --m_cRefCount; + if(nTemp==0) + delete this; + return nTemp; + } + // GetData currently allows ASCII text through Global Memory only + HRESULT STDMETHODCALLTYPE GetData( FORMATETC *pformatetcIn, STGMEDIUM *pmedium ) { + if ((pformatetcIn->dwAspect & DVASPECT_CONTENT) && + (pformatetcIn->tymed & TYMED_HGLOBAL) && + (pformatetcIn->cfFormat == CF_TEXT)) + { + HGLOBAL gh = GlobalAlloc( GHND, fl_selection_length[0]+1 ); + char *pMem = (char*)GlobalLock( gh ); + memmove( pMem, fl_selection_buffer[0], fl_selection_length[0] ); + pMem[ fl_selection_length[0] ] = 0; +// HGLOBAL gh = GlobalAlloc( GHND| GMEM_SHARE, +// (fl_selection_length[0]+4) * sizeof(short) +// + sizeof(DROPFILES)); +// unsigned char *pMem = (unsigned char*)GlobalLock( gh ); +// if (!pMem) { +// GlobalFree(gh); +// return DV_E_FORMATETC; +// } +// DROPFILES *df =(DROPFILES*) pMem; +// int l; +// df->pFiles = sizeof(DROPFILES); +// df->pt.x = 0; +// df->pt.y = 0; +// df->fNC = FALSE; +// for (int i = 0; i < fl_selection_length[0]; i++) { +// if (fl_selection_buffer[0][i] == '\n') { +// fl_selection_buffer[0][i] = '\0'; +// } +// } +// +// df->fWide = TRUE; +// l = fl_utf2unicode((unsigned char*)fl_selection_buffer[0], +// fl_selection_length[0], (xchar*)(((char*)pMem) +// + sizeof(DROPFILES))); +// +// pMem[l * sizeof(WCHAR) + sizeof(DROPFILES)] = 0; +// pMem[l * sizeof(WCHAR) + 1 + sizeof(DROPFILES)] = 0; +// pMem[l * sizeof(WCHAR) + 2 + sizeof(DROPFILES)] = 0; +// pMem[l * sizeof(WCHAR) + 3 + sizeof(DROPFILES)] = 0; + pmedium->tymed = TYMED_HGLOBAL; + pmedium->hGlobal = gh; + pmedium->pUnkForRelease = NULL; + GlobalUnlock( gh ); + return S_OK; + } + return DV_E_FORMATETC; + } + HRESULT STDMETHODCALLTYPE QueryGetData( FORMATETC *pformatetc ) + { + if ((pformatetc->dwAspect & DVASPECT_CONTENT) && + (pformatetc->tymed & TYMED_HGLOBAL) && + (pformatetc->cfFormat == CF_TEXT)) + return S_OK; + return DV_E_FORMATETC; + } +// HRESULT STDMETHODCALLTYPE EnumFormatEtc( DWORD dir, IEnumFORMATETC** ppenumFormatEtc) { +// *ppenumFormatEtc = m_EnumF; +// return S_OK; +// } + + // all the following methods are not really needed for a DnD object + HRESULT STDMETHODCALLTYPE GetDataHere( FORMATETC* /*pformatetcIn*/, STGMEDIUM* /*pmedium*/) { return E_NOTIMPL; } + HRESULT STDMETHODCALLTYPE GetCanonicalFormatEtc( FORMATETC* /*in*/, FORMATETC* /*out*/) { return E_NOTIMPL; } + HRESULT STDMETHODCALLTYPE SetData( FORMATETC* /*pformatetc*/, STGMEDIUM* /*pmedium*/, BOOL /*fRelease*/) { return E_NOTIMPL; } + HRESULT STDMETHODCALLTYPE EnumFormatEtc( DWORD /*dir*/, IEnumFORMATETC** /*ppenumFormatEtc*/) { return E_NOTIMPL; } +// HRESULT STDMETHODCALLTYPE EnumFormatEtc( DWORD dir, IEnumFORMATETC** ppenumFormatEtc) {*ppenumFormatEtc = m_EnumF; return S_OK;} + HRESULT STDMETHODCALLTYPE DAdvise( FORMATETC* /*pformatetc*/, DWORD /*advf*/, + IAdviseSink* /*pAdvSink*/, DWORD* /*pdwConnection*/) { return E_NOTIMPL; } + HRESULT STDMETHODCALLTYPE DUnadvise( DWORD /*dwConnection*/) { return E_NOTIMPL; } + HRESULT STDMETHODCALLTYPE EnumDAdvise( IEnumSTATDATA** /*ppenumAdvise*/) { return E_NOTIMPL; } +}; + + +/** + Drag and drop whatever is in the cut-copy-paste buffer. + + Create a selection first using: + + Fl::copy(const char *stuff, int len, 0) +*/ +int Fl::dnd() +{ + DWORD dropEffect; + ReleaseCapture(); + + FLDataObject *fdo = new FLDataObject; + fdo->AddRef(); + FLDropSource *fds = new FLDropSource; + fds->AddRef(); + + HRESULT ret = DoDragDrop( fdo, fds, DROPEFFECT_MOVE|DROPEFFECT_LINK|DROPEFFECT_COPY, &dropEffect ); + + fdo->Release(); + fds->Release(); + + Fl_Widget *w = Fl::pushed(); + if ( w ) + { + int old_event = Fl::e_number; + w->handle(Fl::e_number = FL_RELEASE); + Fl::e_number = old_event; + Fl::pushed( 0 ); + } + if ( ret==DRAGDROP_S_DROP ) return 1; // or DD_S_CANCEL + return 0; +} + +// +// End of "$Id: fl_dnd_win32.cxx 7817 2010-11-11 11:15:18Z AlbrechtS $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_dnd_x.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_dnd_x.cxx new file mode 100644 index 0000000..9909616 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_dnd_x.cxx @@ -0,0 +1,201 @@ +// +// "$Id: fl_dnd_x.cxx 6616 2009-01-01 21:28:26Z matt $" +// +// Drag & Drop code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2009 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include +#include "flstring.h" + + +extern Atom fl_XdndAware; +extern Atom fl_XdndSelection; +extern Atom fl_XdndEnter; +extern Atom fl_XdndTypeList; +extern Atom fl_XdndPosition; +extern Atom fl_XdndLeave; +extern Atom fl_XdndDrop; +extern Atom fl_XdndStatus; +extern Atom fl_XdndActionCopy; +extern Atom fl_XdndFinished; +//extern Atom fl_XdndProxy; +extern Atom fl_XdndURIList; + +extern char fl_i_own_selection[2]; +extern char *fl_selection_buffer[2]; + +extern void fl_sendClientMessage(Window window, Atom message, + unsigned long d0, + unsigned long d1=0, + unsigned long d2=0, + unsigned long d3=0, + unsigned long d4=0); + +// return version # of Xdnd this window supports. Also change the +// window to the proxy if it uses a proxy: +static int dnd_aware(Window& window) { + Atom actual; int format; unsigned long count, remaining; + unsigned char *data = 0; + XGetWindowProperty(fl_display, window, fl_XdndAware, + 0, 4, False, XA_ATOM, + &actual, &format, + &count, &remaining, &data); + if (actual == XA_ATOM && format==32 && count && data) + return int(*(Atom*)data); + return 0; +} + +static int grabfunc(int event) { + if (event == FL_RELEASE) Fl::pushed(0); + return 0; +} + +extern int (*fl_local_grab)(int); // in Fl.cxx + +// send an event to an fltk window belonging to this program: +static int local_handle(int event, Fl_Window* window) { + fl_local_grab = 0; + Fl::e_x = Fl::e_x_root-window->x(); + Fl::e_y = Fl::e_y_root-window->y(); + int ret = Fl::handle(event,window); + fl_local_grab = grabfunc; + return ret; +} + +int Fl::dnd() { + Fl_Window *source_fl_win = Fl::first_window(); + Fl::first_window()->cursor((Fl_Cursor)21); + Window source_window = fl_xid(Fl::first_window()); + fl_local_grab = grabfunc; + Window target_window = 0; + Fl_Window* local_window = 0; + int dndversion = 4; int dest_x, dest_y; + XSetSelectionOwner(fl_display, fl_XdndSelection, fl_message_window, fl_event_time); + + while (Fl::pushed()) { + + // figure out what window we are pointing at: + Window new_window = 0; int new_version = 0; + Fl_Window* new_local_window = 0; + for (Window child = RootWindow(fl_display, fl_screen);;) { + Window root; unsigned int junk3; + XQueryPointer(fl_display, child, &root, &child, + &e_x_root, &e_y_root, &dest_x, &dest_y, &junk3); + if (!child) { + if (!new_window && (new_version = dnd_aware(root))) new_window = root; + break; + } + new_window = child; + if ((new_local_window = fl_find(child))) break; + if ((new_version = dnd_aware(new_window))) break; + } + + if (new_window != target_window) { + if (local_window) { + local_handle(FL_DND_LEAVE, local_window); + } else if (dndversion) { + fl_sendClientMessage(target_window, fl_XdndLeave, source_window); + } + dndversion = new_version; + target_window = new_window; + local_window = new_local_window; + if (local_window) { + local_handle(FL_DND_ENTER, local_window); + } else if (dndversion) { + // Send an X-DND message to the target window. In order to + // support dragging of files/URLs as well as arbitrary text, + // we look at the selection buffer - if the buffer starts + // with a common URI scheme, does not contain spaces, and + // contains at least one CR LF, then we flag the data as + // both a URI list (MIME media type "text/uri-list") and + // plain text. Otherwise, we just say it is plain text. + if ((!strncmp(fl_selection_buffer[0], "file:///", 8) || + !strncmp(fl_selection_buffer[0], "ftp://", 6) || + !strncmp(fl_selection_buffer[0], "http://", 7) || + !strncmp(fl_selection_buffer[0], "https://", 8) || + !strncmp(fl_selection_buffer[0], "ipp://", 6) || + !strncmp(fl_selection_buffer[0], "ldap:", 5) || + !strncmp(fl_selection_buffer[0], "mailto:", 7) || + !strncmp(fl_selection_buffer[0], "news:", 5) || + !strncmp(fl_selection_buffer[0], "smb://", 6)) && + !strchr(fl_selection_buffer[0], ' ') && + strstr(fl_selection_buffer[0], "\r\n")) { + // Send file/URI list... + fl_sendClientMessage(target_window, fl_XdndEnter, source_window, + dndversion<<24, fl_XdndURIList, XA_STRING, 0); + } else { + // Send plain text... + fl_sendClientMessage(target_window, fl_XdndEnter, source_window, + dndversion<<24, XA_STRING, 0, 0); + } + } + } + if (local_window) { + local_handle(FL_DND_DRAG, local_window); + } else if (dndversion) { + fl_sendClientMessage(target_window, fl_XdndPosition, source_window, + 0, (e_x_root<<16)|e_y_root, fl_event_time, + fl_XdndActionCopy); + } + Fl::wait(); + } + + if (local_window) { + fl_i_own_selection[0] = 1; + if (local_handle(FL_DND_RELEASE, local_window)) paste(*belowmouse(), 0); + } else if (dndversion) { + fl_sendClientMessage(target_window, fl_XdndDrop, source_window, + 0, fl_event_time); + } else if (target_window) { + // fake a drop by clicking the middle mouse button: + XButtonEvent msg; + msg.type = ButtonPress; + msg.window = target_window; + msg.root = RootWindow(fl_display, fl_screen); + msg.subwindow = 0; + msg.time = fl_event_time+1; + msg.x = dest_x; + msg.y = dest_y; + msg.x_root = Fl::e_x_root; + msg.y_root = Fl::e_y_root; + msg.state = 0x0; + msg.button = Button2; + XSendEvent(fl_display, target_window, False, 0L, (XEvent*)&msg); + msg.time++; + msg.state = 0x200; + msg.type = ButtonRelease; + XSendEvent(fl_display, target_window, False, 0L, (XEvent*)&msg); + } + + fl_local_grab = 0; + source_fl_win->cursor(FL_CURSOR_DEFAULT); + return 1; +} + + +// +// End of "$Id: fl_dnd_x.cxx 6616 2009-01-01 21:28:26Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_draw.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_draw.cxx new file mode 100644 index 0000000..6f691c4 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_draw.cxx @@ -0,0 +1,487 @@ +// +// "$Id: fl_draw.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Label drawing code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Implementation of fl_draw(const char*,int,int,int,int,Fl_Align) +// Used to draw all the labels and text, this routine: +// Word wraps the labels to fit into their bounding box. +// Breaks them into lines at the newlines. +// Expands all unprintable characters to ^X or \nnn notation +// Aligns them against the inside of the box. + +#define min(a,b) ((a)<(b)?(a):(b)) +#include +#include +#include +#include + +#include "flstring.h" +#include +#include + +#define MAXBUF 1024 + +char fl_draw_shortcut; // set by fl_labeltypes.cxx + +static char* underline_at; + +/** + utf8 multibyte char seq. detection an pass-thru routine. + \retval false if no utf8 seq detected, no change made. true if utf8 and d copied with s seq. + note that for n bytes copied dest incremented of n, but s of n-1 for compatible loop use see below. +*/ +#define C_IN(c,a,b) ((c)>=(a) && (c)<=(b)) +#define C_UTF8(c) C_IN(c,0x80,0xBF) + +static bool handle_utf8_seq(const char * &s,char * &d) { + register const unsigned char* p=(const unsigned char*)s; + if (p[0] < 0xc2 || p[0] > 0xf4) + return false; // not adressed in this function + else if ( C_IN(p[0], 0xc2, 0xdf) && C_UTF8(p[1]) ) { + d[0]=s[0]; d[1]=s[1]; + d+=2; s++; + // non-overlong 2-byte + } + else if ( p[0]==0xe0 && C_IN(p[1], 0xa0, 0xbf) && C_UTF8(p[2]) ) { + d[0]=s[0]; d[1]=s[1];d[2]=s[2]; + d+=3; s+=2; + // excluding overlongs + } + else if (p[0]==0xed && C_IN(p[1], 0x80, 0x9f) && C_UTF8(p[2]) ) { + d[0]=s[0]; d[1]=s[1];d[2]=s[2]; + d+=3; s+=2; + // excluding surrogates + } + else if (p[0]!=0xed && C_IN(p[0], 0xe1, 0xef) && C_UTF8(p[1]) && C_UTF8(p[2]) ) { + d[0]=s[0]; d[1]=s[1];d[2]=s[2]; + d+=3; s+=2; + // straight 3-byte + } + else if (p[0]==0xf0 && C_IN(p[1], 0x90, 0xbf) && C_UTF8(p[2]) && C_UTF8(p[3]) ) { + d[0]=s[0]; d[1]=s[1]; d[2]=s[2]; d[3]=s[3]; + d+=4; s+=3; + // planes 1-3 + } + else if (C_IN(p[0], 0xf1, 0xf3) && C_UTF8(p[1]) && C_UTF8(p[2]) && C_UTF8(p[3]) ) { + d[0]=s[0]; d[1]=s[1]; d[2]=s[2]; d[3]=s[3]; + d+=4; s+=3; + // planes 4-15 + } + else if (p[0]==0xf4 && C_IN(p[1], 0x80, 0x8f) && C_UTF8(p[2]) && C_UTF8(p[3]) ) { + d[0]=s[0]; d[1]=s[1]; d[2]=s[2]; d[3]=s[3]; + d+=4; s+=3; + // planes 16 + } else { // non utf8 compliant, maybe CP125x or broken utf8 string + // fprintf(stderr, "Not UTF8 char \n"); + return false; + } + return true; // we did handled and copied the utf8 multibyte char seq. +} + +/** + Copy \p from to \p buf, replacing unprintable characters with ^X and \\nnn. + + Stop at a newline or if MAXBUF characters written to buffer. + Also word-wrap if width exceeds maxw. + Returns a pointer to the start of the next line of characters. + Sets n to the number of characters put into the buffer. + Sets width to the width of the string in the current font. +*/ +const char* +fl_expand_text(const char* from, char* buf, int maxbuf, double maxw, int& n, + double &width, int wrap, int draw_symbols) { + char* o = buf; + char* e = buf+(maxbuf-4); + underline_at = 0; + char* word_end = o; + const char* word_start = from; + double w = 0; + + const char* p = from; + for (;; p++) { + + int c = *p & 255; + + if (!c || c == ' ' || c == '\n') { + // test for word-wrap: + if (word_start < p && wrap) { + double newwidth = w + fl_width(word_end, o-word_end); + if (word_end > buf && newwidth > maxw) { // break before this word + o = word_end; + p = word_start; + break; + } + word_end = o; + w = newwidth; + } + if (!c) break; + else if (c == '\n') {p++; break;} + word_start = p+1; + } + + if (o > e) break; // don't overflow buffer + + if (c == '\t') { + for (c = fl_utf_nb_char((uchar*)buf, o-buf)%8; c<8 && o (str + 1) && p[-1] != '@') { + strlcpy(symbol[1], p, sizeof(symbol[1])); + symwidth[1] = min(w,h); + } + } + + symtotal = symwidth[0] + symwidth[1]; + imgtotal = (img && (align&FL_ALIGN_IMAGE_NEXT_TO_TEXT)) ? img->w() : 0; + + int strw = 0; + int strh; + + if (str) { + for (p = str, lines=0; p;) { + e = fl_expand_text(p, buf, MAXBUF, w - symtotal - imgtotal, buflen, width, + align&FL_ALIGN_WRAP, draw_symbols); + if (strwh() : 0; + int imgw[2] = {0, 0}; + + symoffset = 0; + + if (align & FL_ALIGN_BOTTOM) ypos = y+h-(lines-1)*height-imgh; + else if (align & FL_ALIGN_TOP) ypos = y+height; + else ypos = y+(h-lines*height-imgh)/2+height; + + // draw the image unless the "text over image" alignment flag is set... + if (img && imgvert && !(align & FL_ALIGN_TEXT_OVER_IMAGE)) { + if (img->w() > symoffset) symoffset = img->w(); + + if (align & FL_ALIGN_LEFT) xpos = x + symwidth[0]; + else if (align & FL_ALIGN_RIGHT) xpos = x + w - img->w() - symwidth[1]; + else xpos = x + (w - img->w() - symtotal) / 2 + symwidth[0]; + + img->draw(xpos, ypos - height); + ypos += img->h(); + } + + // draw the image to the side of the text + if (img && !imgvert /* && (align & !FL_ALIGN_TEXT_NEXT_TO_IMAGE)*/ ) { + if (align & FL_ALIGN_TEXT_OVER_IMAGE) { // image is right of text + imgw[1] = img->w(); + if (align & FL_ALIGN_LEFT) xpos = x + symwidth[0] + strw + 1; + else if (align & FL_ALIGN_RIGHT) xpos = x + w - symwidth[1] - imgw[1] + 1; + else xpos = x + (w - strw - symtotal - imgw[1]) / 2 + symwidth[0] + strw + 1; + } else { // image is to the left of the text + imgw[0] = img->w(); + if (align & FL_ALIGN_LEFT) xpos = x + symwidth[0] - 1; + else if (align & FL_ALIGN_RIGHT) xpos = x + w - symwidth[1] - strw - imgw[0] - 1; + else xpos = x + (w - strw - symtotal - imgw[0]) / 2 - 1; + } + int yimg = ypos - height; + if (align & FL_ALIGN_TOP) ; + else if (align & FL_ALIGN_BOTTOM) yimg += strh - img->h() - 1; + else yimg += (strh - img->h() - 1) / 2; + img->draw(xpos, yimg); + } + + // now draw all the lines: + if (str) { + int desc = fl_descent(); + for (p=str; ; ypos += height) { + if (lines>1) e = fl_expand_text(p, buf, MAXBUF, w - symtotal - imgtotal, buflen, + width, align&FL_ALIGN_WRAP, draw_symbols); + else e = ""; + + if (width > symoffset) symoffset = (int)(width + 0.5); + + if (align & FL_ALIGN_LEFT) xpos = x + symwidth[0] + imgw[0]; + else if (align & FL_ALIGN_RIGHT) xpos = x + w - (int)(width + .5) - symwidth[1] - imgw[1]; + else xpos = x + (w - (int)(width + .5) - symtotal - imgw[0] - imgw[1]) / 2 + symwidth[0] + imgw[0]; + + callthis(buf,buflen,xpos,ypos-desc); + + if (underline_at && underline_at >= buf && underline_at < (buf + buflen)) + callthis("_",1,xpos+int(fl_width(buf,underline_at-buf)),ypos-desc); + + if (!*e || (*e == '@' && e[1] != '@')) break; + p = e; + } + } + + // draw the image if the "text over image" alignment flag is set... + if (img && imgvert && (align & FL_ALIGN_TEXT_OVER_IMAGE)) { + if (img->w() > symoffset) symoffset = img->w(); + + if (align & FL_ALIGN_LEFT) xpos = x + symwidth[0]; + else if (align & FL_ALIGN_RIGHT) xpos = x + w - img->w() - symwidth[1]; + else xpos = x + (w - img->w() - symtotal) / 2 + symwidth[0]; + + img->draw(xpos, ypos); + } + + // draw the symbols, if any... + if (symwidth[0]) { + // draw to the left + if (align & FL_ALIGN_LEFT) xpos = x; + else if (align & FL_ALIGN_RIGHT) xpos = x + w - symtotal - symoffset; + else xpos = x + (w - symoffset - symtotal) / 2; + + if (align & FL_ALIGN_BOTTOM) ypos = y + h - symwidth[0]; + else if (align & FL_ALIGN_TOP) ypos = y; + else ypos = y + (h - symwidth[0]) / 2; + + fl_draw_symbol(symbol[0], xpos, ypos, symwidth[0], symwidth[0], fl_color()); + } + + if (symwidth[1]) { + // draw to the right + if (align & FL_ALIGN_LEFT) xpos = x + symoffset + symwidth[0]; + else if (align & FL_ALIGN_RIGHT) xpos = x + w - symwidth[1]; + else xpos = x + (w - symoffset - symtotal) / 2 + symoffset + symwidth[0]; + + if (align & FL_ALIGN_BOTTOM) ypos = y + h - symwidth[1]; + else if (align & FL_ALIGN_TOP) ypos = y; + else ypos = y + (h - symwidth[1]) / 2; + + fl_draw_symbol(symbol[1], xpos, ypos, symwidth[1], symwidth[1], fl_color()); + } +} + +/** + Fancy string drawing function which is used to draw all the labels. + + The string is formatted and aligned inside the passed box. + Handles '\\t' and '\\n', expands all other control characters to '^X', + and aligns inside or against the edges of the box. + See Fl_Widget::align() for values of \p align. The value FL_ALIGN_INSIDE + is ignored, as this function always prints inside the box. + If \p img is provided and is not \p NULL, the image is drawn above or + below the text as specified by the \p align value. + The \p draw_symbols argument specifies whether or not to look for symbol + names starting with the '\@' character' + The text length is limited to 1024 characters per line. +*/ +void fl_draw( + const char* str, + int x, int y, int w, int h, + Fl_Align align, + Fl_Image* img, + int draw_symbols) +{ + if ((!str || !*str) && !img) return; + if (w && h && !fl_not_clipped(x, y, w, h) && (align & FL_ALIGN_INSIDE)) return; + if (align & FL_ALIGN_CLIP) + fl_push_clip(x, y, w, h); + fl_draw(str, x, y, w, h, align, fl_draw, img, draw_symbols); + if (align & FL_ALIGN_CLIP) + fl_pop_clip(); +} + +/** + Measure how wide and tall the string will be when printed by the + fl_draw() function with \p align parameter. If the incoming \p w + is non-zero it will wrap to that width. + \param[in] str nul-terminated string + \param[out] w,h width and height of string in current font + \param[in] draw_symbols non-zero to enable @@symbol handling [default=1] +*/ +void fl_measure(const char* str, int& w, int& h, int draw_symbols) { + if (!str || !*str) {w = 0; h = 0; return;} + h = fl_height(); + const char* p; + const char* e; + char buf[MAXBUF]; + int buflen; + int lines; + double width=0; + int W = 0; + char symbol[2][255], *symptr; + int symwidth[2], symtotal; + + // count how many lines and put the last one into the buffer: + symbol[0][0] = '\0'; + symwidth[0] = 0; + + symbol[1][0] = '\0'; + symwidth[1] = 0; + + if (draw_symbols) { + if (str && str[0] == '@' && str[1] && str[1] != '@') { + // Start with a symbol... + for (symptr = symbol[0]; + *str && !isspace(*str) && symptr < (symbol[0] + sizeof(symbol[0]) - 1); + *symptr++ = *str++); + *symptr = '\0'; + if (isspace(*str)) str++; + symwidth[0] = h; + } + + if (str && (p = strrchr(str, '@')) != NULL && p > (str + 1) && p[-1]!='@') { + strlcpy(symbol[1], p, sizeof(symbol[1])); + symwidth[1] = h; + } + } + + symtotal = symwidth[0] + symwidth[1]; + + for (p = str, lines=0; p;) { +// e = expand(p, buf, w - symtotal, buflen, width, w != 0, draw_symbols); + e = fl_expand_text(p, buf, MAXBUF, w - symtotal, buflen, width, + w != 0, draw_symbols); + if ((int)ceil(width) > W) W = (int)ceil(width); + lines++; + if (!*e || (*e == '@' && draw_symbols)) break; + p = e; + } + + if ((symwidth[0] || symwidth[1]) && lines) { + if (symwidth[0]) symwidth[0] = lines * fl_height(); + if (symwidth[1]) symwidth[1] = lines * fl_height(); + } + + symtotal = symwidth[0] + symwidth[1]; + + w = W + symtotal; + h = lines*h; +} + +/** + This function returns the actual height of the specified \p font + and \p size. Normally the font height should always be 'size', + but with the advent of XFT, there are (currently) complexities + that seem to only be solved by asking the font what its actual + font height is. (See STR#2115) + + This function was originally undocumented in 1.1.x, and was used + only by Fl_Text_Display. We're now documenting it in 1.3.x so that + apps that need precise height info can get it with this function. + + \returns the height of the font in pixels. + + \todo In the future, when the XFT issues are resolved, this function + should simply return the 'size' value. +*/ +int fl_height(int font, int size) { + if ( font == fl_font() && size == fl_size() ) return(fl_height()); + int tf = fl_font(), ts = fl_size(); // save + fl_font(font,size); + int height = fl_height(); + fl_font(tf,ts); // restore + return(height); +} + +// +// End of "$Id: fl_draw.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_draw_image.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_draw_image.cxx new file mode 100644 index 0000000..2f928e7 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_draw_image.cxx @@ -0,0 +1,576 @@ +// +// "$Id: fl_draw_image.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Image drawing routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// I hope a simple and portable method of drawing color and monochrome +// images. To keep this simple, only a single storage type is +// supported: 8 bit unsigned data, byte order RGB, and pixels are +// stored packed into rows with the origin at the top-left. It is +// possible to alter the size of pixels with the "delta" argument, to +// add alpha or other information per pixel. It is also possible to +// change the origin and direction of the image data by messing with +// the "delta" and "linedelta", making them negative, though this may +// defeat some of the shortcuts in translating the image for X. + +#ifdef WIN32 +# include "fl_draw_image_win32.cxx" +#elif defined(__APPLE__) +# include "fl_draw_image_mac.cxx" +#else + +// A list of assumptions made about the X display: + +// bits_per_pixel must be one of 8, 16, 24, 32. + +// scanline_pad must be a power of 2 and greater or equal to 8. + +// PsuedoColor visuals must have 8 bits_per_pixel (although the depth +// may be less than 8). This is the only limitation that affects any +// modern X displays, you can't use 12 or 16 bit colormaps. + +// The mask bits in TrueColor visuals for each color are +// contiguous and have at least one bit of each color. This +// is not checked for. + +// For 24 and 32 bit visuals there must be at least 8 bits of each color. + +//////////////////////////////////////////////////////////////// + +# include +# include +# include +# include "Fl_XColor.H" +# include "flstring.h" + +static XImage xi; // template used to pass info to X +static int bytes_per_pixel; +static int scanline_add; +static int scanline_mask; + +static void (*converter)(const uchar *from, uchar *to, int w, int delta); +static void (*mono_converter)(const uchar *from, uchar *to, int w, int delta); + +static int dir; // direction-alternator +static int ri,gi,bi; // saved error-diffusion value + +# if USE_COLORMAP +//////////////////////////////////////////////////////////////// +// 8-bit converter with error diffusion + +static void color8_converter(const uchar *from, uchar *to, int w, int delta) { + int r=ri, g=gi, b=bi; + int d, td; + if (dir) { + dir = 0; + from = from+(w-1)*delta; + to = to+(w-1); + d = -delta; + td = -1; + } else { + dir = 1; + d = delta; + td = 1; + } + for (; w--; from += d, to += td) { + r += from[0]; if (r < 0) r = 0; else if (r>255) r = 255; + g += from[1]; if (g < 0) g = 0; else if (g>255) g = 255; + b += from[2]; if (b < 0) b = 0; else if (b>255) b = 255; + Fl_Color i = fl_color_cube(r*FL_NUM_RED/256,g*FL_NUM_GREEN/256,b*FL_NUM_BLUE/256); + Fl_XColor& xmap = fl_xmap[0][i]; + if (!xmap.mapped) {if (!fl_redmask) fl_xpixel(r,g,b); else fl_xpixel(i);} + r -= xmap.r; + g -= xmap.g; + b -= xmap.b; + *to = uchar(xmap.pixel); + } + ri = r; gi = g; bi = b; +} + +static void mono8_converter(const uchar *from, uchar *to, int w, int delta) { + int r=ri, g=gi, b=bi; + int d, td; + if (dir) { + dir = 0; + from = from+(w-1)*delta; + to = to+(w-1); + d = -delta; + td = -1; + } else { + dir = 1; + d = delta; + td = 1; + } + for (; w--; from += d, to += td) { + r += from[0]; if (r < 0) r = 0; else if (r>255) r = 255; + g += from[0]; if (g < 0) g = 0; else if (g>255) g = 255; + b += from[0]; if (b < 0) b = 0; else if (b>255) b = 255; + Fl_Color i = fl_color_cube(r*FL_NUM_RED/256,g*FL_NUM_GREEN/256,b*FL_NUM_BLUE/256); + Fl_XColor& xmap = fl_xmap[0][i]; + if (!xmap.mapped) {if (!fl_redmask) fl_xpixel(r,g,b); else fl_xpixel(i);} + r -= xmap.r; + g -= xmap.g; + b -= xmap.b; + *to = uchar(xmap.pixel); + } + ri = r; gi = g; bi = b; +} + +# endif + +//////////////////////////////////////////////////////////////// +// 16 bit TrueColor converters with error diffusion +// Cray computers have no 16-bit type, so we use character pointers +// (which may be slow) + +# ifdef U16 +# define OUTTYPE U16 +# define OUTSIZE 1 +# define OUTASSIGN(v) *t = v +# else +# define OUTTYPE uchar +# define OUTSIZE 2 +# define OUTASSIGN(v) int tt=v; t[0] = uchar(tt>>8); t[1] = uchar(tt) +# endif + +static void color16_converter(const uchar *from, uchar *to, int w, int delta) { + OUTTYPE *t = (OUTTYPE *)to; + int d, td; + if (dir) { + dir = 0; + from = from+(w-1)*delta; + t = t+(w-1)*OUTSIZE; + d = -delta; + td = -OUTSIZE; + } else { + dir = 1; + d = delta; + td = OUTSIZE; + } + int r=ri, g=gi, b=bi; + for (; w--; from += d, t += td) { + r = (r&~fl_redmask) +from[0]; if (r>255) r = 255; + g = (g&~fl_greenmask)+from[1]; if (g>255) g = 255; + b = (b&~fl_bluemask) +from[2]; if (b>255) b = 255; + OUTASSIGN(( + ((r&fl_redmask)<> fl_extrashift); + } + ri = r; gi = g; bi = b; +} + +static void mono16_converter(const uchar *from,uchar *to,int w, int delta) { + OUTTYPE *t = (OUTTYPE *)to; + int d, td; + if (dir) { + dir = 0; + from = from+(w-1)*delta; + t = t+(w-1)*OUTSIZE; + d = -delta; + td = -OUTSIZE; + } else { + dir = 1; + d = delta; + td = OUTSIZE; + } + uchar mask = fl_redmask & fl_greenmask & fl_bluemask; + int r=ri; + for (; w--; from += d, t += td) { + r = (r&~mask) + *from; if (r > 255) r = 255; + uchar m = r&mask; + OUTASSIGN(( + (m<> fl_extrashift); + } + ri = r; +} + +// special-case the 5r6g5b layout used by XFree86: + +static void c565_converter(const uchar *from, uchar *to, int w, int delta) { + OUTTYPE *t = (OUTTYPE *)to; + int d, td; + if (dir) { + dir = 0; + from = from+(w-1)*delta; + t = t+(w-1)*OUTSIZE; + d = -delta; + td = -OUTSIZE; + } else { + dir = 1; + d = delta; + td = OUTSIZE; + } + int r=ri, g=gi, b=bi; + for (; w--; from += d, t += td) { + r = (r&7)+from[0]; if (r>255) r = 255; + g = (g&3)+from[1]; if (g>255) g = 255; + b = (b&7)+from[2]; if (b>255) b = 255; + OUTASSIGN(((r&0xf8)<<8) + ((g&0xfc)<<3) + (b>>3)); + } + ri = r; gi = g; bi = b; +} + +static void m565_converter(const uchar *from,uchar *to,int w, int delta) { + OUTTYPE *t = (OUTTYPE *)to; + int d, td; + if (dir) { + dir = 0; + from = from+(w-1)*delta; + t = t+(w-1)*OUTSIZE; + d = -delta; + td = -OUTSIZE; + } else { + dir = 1; + d = delta; + td = OUTSIZE; + } + int r=ri; + for (; w--; from += d, t += td) { + r = (r&7) + *from; if (r > 255) r = 255; + OUTASSIGN((r>>3) * 0x841); + } + ri = r; +} + +//////////////////////////////////////////////////////////////// +// 24bit TrueColor converters: + +static void rgb_converter(const uchar *from, uchar *to, int w, int delta) { + int d = delta-3; + for (; w--; from += d) { + *to++ = *from++; + *to++ = *from++; + *to++ = *from++; + } +} + +static void bgr_converter(const uchar *from, uchar *to, int w, int delta) { + for (; w--; from += delta) { + uchar r = from[0]; + uchar g = from[1]; + *to++ = from[2]; + *to++ = g; + *to++ = r; + } +} + +static void rrr_converter(const uchar *from, uchar *to, int w, int delta) { + for (; w--; from += delta) { + *to++ = *from; + *to++ = *from; + *to++ = *from; + } +} + +//////////////////////////////////////////////////////////////// +// 32bit TrueColor converters on a 32 or 64-bit machine: + +# ifdef U64 +# define STORETYPE U64 +# if WORDS_BIGENDIAN +# define INNARDS32(f) \ + U64 *t = (U64*)to; \ + int w1 = (w+1)/2; \ + for (; w1--; from += delta) {U64 i = f; from += delta; *t++ = (i<<32)|(f);} +# else +# define INNARDS32(f) \ + U64 *t = (U64*)to; \ + int w1 = (w+1)/2; \ + for (; w1--; from += delta) {U64 i=f; from+= delta; *t++ = ((U64)(f)<<32)|i;} +# endif +# else +# define STORETYPE U32 +# define INNARDS32(f) \ + U32 *t = (U32*)to; for (; w--; from += delta) *t++ = f +# endif + +static void rgbx_converter(const uchar *from, uchar *to, int w, int delta) { + INNARDS32((unsigned(from[0])<<24)+(from[1]<<16)+(from[2]<<8)); +} + +static void xbgr_converter(const uchar *from, uchar *to, int w, int delta) { + INNARDS32((from[0])+(from[1]<<8)+(from[2]<<16)); +} + +static void xrgb_converter(const uchar *from, uchar *to, int w, int delta) { + INNARDS32((from[0]<<16)+(from[1]<<8)+(from[2])); +} + +static void bgrx_converter(const uchar *from, uchar *to, int w, int delta) { + INNARDS32((from[0]<<8)+(from[1]<<16)+(unsigned(from[2])<<24)); +} + +static void rrrx_converter(const uchar *from, uchar *to, int w, int delta) { + INNARDS32(unsigned(*from) * 0x1010100U); +} + +static void xrrr_converter(const uchar *from, uchar *to, int w, int delta) { + INNARDS32(*from * 0x10101U); +} + +static void +color32_converter(const uchar *from, uchar *to, int w, int delta) { + INNARDS32( + (from[0]<depth == fl_visual->depth) break; + xi.format = ZPixmap; + xi.byte_order = ImageByteOrder(fl_display); +//i.bitmap_unit = 8; +//i.bitmap_bit_order = MSBFirst; +//i.bitmap_pad = 8; + xi.depth = fl_visual->depth; + xi.bits_per_pixel = pfv->bits_per_pixel; + + if (xi.bits_per_pixel & 7) bytes_per_pixel = 0; // produce fatal error + else bytes_per_pixel = xi.bits_per_pixel/8; + + unsigned int n = pfv->scanline_pad/8; + if (pfv->scanline_pad & 7 || (n&(n-1))) + Fl::fatal("Can't do scanline_pad of %d",pfv->scanline_pad); + if (n < sizeof(STORETYPE)) n = sizeof(STORETYPE); + scanline_add = n-1; + scanline_mask = -n; + +# if USE_COLORMAP + if (bytes_per_pixel == 1) { + converter = color8_converter; + mono_converter = mono8_converter; + return; + } + if (!fl_visual->red_mask) + Fl::fatal("Can't do %d bits_per_pixel colormap",xi.bits_per_pixel); +# endif + + // otherwise it is a TrueColor visual: + + int rs = fl_redshift; + int gs = fl_greenshift; + int bs = fl_blueshift; + + switch (bytes_per_pixel) { + + case 2: + // All 16-bit TrueColor visuals are supported on any machine with + // 24 or more bits per integer. +# ifdef U16 + xi.byte_order = WORDS_BIGENDIAN; +# else + xi.byte_order = 1; +# endif + if (rs == 11 && gs == 6 && bs == 0 && fl_extrashift == 3) { + converter = c565_converter; + mono_converter = m565_converter; + } else { + converter = color16_converter; + mono_converter = mono16_converter; + } + break; + + case 3: + if (xi.byte_order) {rs = 16-rs; gs = 16-gs; bs = 16-bs;} + if (rs == 0 && gs == 8 && bs == 16) { + converter = rgb_converter; + mono_converter = rrr_converter; + } else if (rs == 16 && gs == 8 && bs == 0) { + converter = bgr_converter; + mono_converter = rrr_converter; + } else { + Fl::fatal("Can't do arbitrary 24bit color"); + } + break; + + case 4: + if ((xi.byte_order!=0) != WORDS_BIGENDIAN) + {rs = 24-rs; gs = 24-gs; bs = 24-bs;} + if (rs == 0 && gs == 8 && bs == 16) { + converter = xbgr_converter; + mono_converter = xrrr_converter; + } else if (rs == 24 && gs == 16 && bs == 8) { + converter = rgbx_converter; + mono_converter = rrrx_converter; + } else if (rs == 8 && gs == 16 && bs == 24) { + converter = bgrx_converter; + mono_converter = rrrx_converter; + } else if (rs == 16 && gs == 8 && bs == 0) { + converter = xrgb_converter; + mono_converter = xrrr_converter; + } else { + xi.byte_order = WORDS_BIGENDIAN; + converter = color32_converter; + mono_converter = mono32_converter; + } + break; + + default: + Fl::fatal("Can't do %d bits_per_pixel",xi.bits_per_pixel); + } + +} + +# define MAXBUFFER 0x40000 // 256k + +static void innards(const uchar *buf, int X, int Y, int W, int H, + int delta, int linedelta, int mono, + Fl_Draw_Image_Cb cb, void* userdata) +{ + if (!linedelta) linedelta = W*delta; + + int dx, dy, w, h; + fl_clip_box(X,Y,W,H,dx,dy,w,h); + if (w<=0 || h<=0) return; + dx -= X; + dy -= Y; + + if (!bytes_per_pixel) figure_out_visual(); + xi.width = w; + xi.height = h; + + void (*conv)(const uchar *from, uchar *to, int w, int delta) = converter; + if (mono) conv = mono_converter; + + // See if the data is already in the right format. Unfortunately + // some 32-bit x servers (XFree86) care about the unknown 8 bits + // and they must be zero. I can't confirm this for user-supplied + // data, so the 32-bit shortcut is disabled... + // This can set bytes_per_line negative if image is bottom-to-top + // I tested it on Linux, but it may fail on other Xlib implementations: + if (buf && ( +# if 0 // set this to 1 to allow 32-bit shortcut + delta == 4 && +# if WORDS_BIGENDIAN + conv == rgbx_converter +# else + conv == xbgr_converter +# endif + || +# endif + conv == rgb_converter && delta==3 + ) && !(linedelta&scanline_add)) { + xi.data = (char *)(buf+delta*dx+linedelta*dy); + xi.bytes_per_line = linedelta; + + } else { + int linesize = ((w*bytes_per_pixel+scanline_add)&scanline_mask)/sizeof(STORETYPE); + int blocking = h; + static STORETYPE *buffer; // our storage, always word aligned + static long buffer_size; + {int size = linesize*h; + if (size > MAXBUFFER) { + size = MAXBUFFER; + blocking = MAXBUFFER/linesize; + } + if (size > buffer_size) { + delete[] buffer; + buffer_size = size; + buffer = new STORETYPE[size]; + }} + xi.data = (char *)buffer; + xi.bytes_per_line = linesize*sizeof(STORETYPE); + if (buf) { + buf += delta*dx+linedelta*dy; + for (int j=0; j-3),0,0); +} +void Fl_Graphics_Driver::draw_image(Fl_Draw_Image_Cb cb, void* data, + int x, int y, int w, int h,int d) { + innards(0,x,y,w,h,d,0,(d<3&&d>-3),cb,data); +} +void Fl_Graphics_Driver::draw_image_mono(const uchar* buf, int x, int y, int w, int h, int d, int l){ + innards(buf,x,y,w,h,d,l,1,0,0); +} +void Fl_Graphics_Driver::draw_image_mono(Fl_Draw_Image_Cb cb, void* data, + int x, int y, int w, int h,int d) { + innards(0,x,y,w,h,d,0,1,cb,data); +} + +void fl_rectf(int x, int y, int w, int h, uchar r, uchar g, uchar b) { + if (fl_visual->depth > 16) { + fl_color(r,g,b); + fl_rectf(x,y,w,h); + } else { + uchar c[3]; + c[0] = r; c[1] = g; c[2] = b; + innards(c,x,y,w,h,0,0,0,0,0); + } +} + +#endif + +// +// End of "$Id: fl_draw_image.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_draw_image_mac.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_draw_image_mac.cxx new file mode 100644 index 0000000..0dc5e25 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_draw_image_mac.cxx @@ -0,0 +1,173 @@ +// +// "$Id: fl_draw_image_mac.cxx 7617 2010-05-27 17:20:18Z manolo $" +// +// MacOS image drawing code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2009 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +//////////////////////////////////////////////////////////////// + +#include +#include +#include +#include + +#define MAXBUFFER 0x40000 // 256k + +static void dataReleaseCB(void *info, const void *data, size_t size) +{ + delete[] (uchar *)data; +} + +/** + * draw an image based on the input parameters + * + * buf: image source data + * X, Y: position (in buffer?!) + * W, H: size of picture (in pixel?) + * delta: distance from pixel to pixel in buf in bytes + * linedelta: distance from line to line in buf in bytes + * mono: if set, pixel is one byte - if zero, pixel is 3 byte + * cb: callback to copy image data into (RGB?) buffer + * buf: pointer to first byte in image source + * x, y: position in buffer + * w: width (in bytes?) + * dst: destination buffer + * userdata: ? + */ +static void innards(const uchar *buf, int X, int Y, int W, int H, + int delta, int linedelta, int mono, + Fl_Draw_Image_Cb cb, void* userdata) +{ + if (!linedelta) linedelta = W*delta; + + const void *array = buf; + uchar *tmpBuf = 0; + if (cb) { + tmpBuf = new uchar[ H*W*delta ]; + for (int i=0; i-3),0,0); +} +void Fl_Graphics_Driver::draw_image(Fl_Draw_Image_Cb cb, void* data, + int x, int y, int w, int h,int d) { + innards(0,x,y,w,h,d,0,(d<3&&d>-3),cb,data); +} +void Fl_Graphics_Driver::draw_image_mono(const uchar* buf, int x, int y, int w, int h, int d, int l){ + innards(buf,x,y,w,h,d,l,1,0,0); +} +void Fl_Graphics_Driver::draw_image_mono(Fl_Draw_Image_Cb cb, void* data, + int x, int y, int w, int h,int d) { + innards(0,x,y,w,h,d,0,1,cb,data); +} + +void fl_rectf(int x, int y, int w, int h, uchar r, uchar g, uchar b) { + fl_color(r,g,b); + fl_rectf(x,y,w,h); +} + +// +// End of "$Id: fl_draw_image_mac.cxx 7617 2010-05-27 17:20:18Z manolo $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_draw_image_win32.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_draw_image_win32.cxx new file mode 100644 index 0000000..e5eb860 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_draw_image_win32.cxx @@ -0,0 +1,341 @@ +// +// "$Id: fl_draw_image_win32.cxx 7617 2010-05-27 17:20:18Z manolo $" +// +// WIN32 image drawing code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2009 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// I hope a simple and portable method of drawing color and monochrome +// images. To keep this simple, only a single storage type is +// supported: 8 bit unsigned data, byte order RGB, and pixels are +// stored packed into rows with the origin at the top-left. It is +// possible to alter the size of pixels with the "delta" argument, to +// add alpha or other information per pixel. It is also possible to +// change the origin and direction of the image data by messing with +// the "delta" and "linedelta", making them negative, though this may +// defeat some of the shortcuts in translating the image for X. + +// Unbelievably (since it conflicts with how most PC software works) +// Micro$oft picked a bottom-up and BGR storage format for their +// DIB images. I'm pretty certain there is a way around this, but +// I can't find any other than the brute-force method of drawing +// each line as a separate image. This may also need to be done +// if the delta is any amount other than 1, 3, or 4. + +//////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include + +#define MAXBUFFER 0x40000 // 256k + +#if USE_COLORMAP + +// error-diffusion dither into the FLTK colormap +static void dither(uchar* to, const uchar* from, int w, int delta) { + static int ri, gi, bi, dir; + int r=ri, g=gi, b=bi; + int d, td; + if (dir) { + dir = 0; + from = from+(w-1)*delta; + to = to+(w-1); + d = -delta; + td = -1; + } else { + dir = 1; + d = delta; + td = 1; + } + for (; w--; from += d, to += td) { + r += from[0]; if (r < 0) r = 0; else if (r>255) r = 255; + int rr = r*FL_NUM_RED/256; + r -= rr*255/(FL_NUM_RED-1); + g += from[1]; if (g < 0) g = 0; else if (g>255) g = 255; + int gg = g*FL_NUM_GREEN/256; + g -= gg*255/(FL_NUM_GREEN-1); + b += from[2]; if (b < 0) b = 0; else if (b>255) b = 255; + int bb = b*FL_NUM_BLUE/256; + b -= bb*255/(FL_NUM_BLUE-1); + *to = uchar(FL_COLOR_CUBE+(bb*FL_NUM_RED+rr)*FL_NUM_GREEN+gg); + } + ri = r; gi = g; bi = b; +} + +// error-diffusion dither into the FLTK colormap +static void monodither(uchar* to, const uchar* from, int w, int delta) { + static int ri,dir; + int r=ri; + int d, td; + if (dir) { + dir = 0; + from = from+(w-1)*delta; + to = to+(w-1); + d = -delta; + td = -1; + } else { + dir = 1; + d = delta; + td = 1; + } + for (; w--; from += d, to += td) { + r += *from; if (r < 0) r = 0; else if (r>255) r = 255; + int rr = r*FL_NUM_GRAY/256; + r -= rr*255/(FL_NUM_GRAY-1); + *to = uchar(FL_GRAY_RAMP+rr); + } + ri = r; +} + +#endif // USE_COLORMAP + +static void innards(const uchar *buf, int X, int Y, int W, int H, + int delta, int linedelta, int depth, + Fl_Draw_Image_Cb cb, void* userdata) +{ + char indexed = 0; + +#if USE_COLORMAP + indexed = (fl_palette != 0); +#endif + + if (depth==0) depth = 3; + if (indexed || !fl_can_do_alpha_blending()) + depth = (depth-1)|1; + + if (!linedelta) linedelta = W*delta; + + int x, y, w, h; + fl_clip_box(X,Y,W,H,x,y,w,h); + if (w<=0 || h<=0) return; + if (buf) buf += (x-X)*delta + (y-Y)*linedelta; + + static U32 bmibuffer[256+12]; + BITMAPINFO &bmi = *((BITMAPINFO*)bmibuffer); + if (!bmi.bmiHeader.biSize) { + bmi.bmiHeader.biSize = sizeof(bmi)-4; // does it use this to determine type? + bmi.bmiHeader.biPlanes = 1; + bmi.bmiHeader.biCompression = BI_RGB; + bmi.bmiHeader.biXPelsPerMeter = 0; + bmi.bmiHeader.biYPelsPerMeter = 0; + bmi.bmiHeader.biClrUsed = 0; + bmi.bmiHeader.biClrImportant = 0; + } +#if USE_COLORMAP + if (indexed) { + for (short i=0; i<256; i++) { + *((short*)(bmi.bmiColors)+i) = i; + } + } else +#endif + if (depth<3) { + for (int i=0; i<256; i++) { + bmi.bmiColors[i].rgbBlue = (uchar)i; + bmi.bmiColors[i].rgbGreen = (uchar)i; + bmi.bmiColors[i].rgbRed = (uchar)i; + bmi.bmiColors[i].rgbReserved = (uchar)0; // must be zero + } + } + bmi.bmiHeader.biWidth = w; +#if USE_COLORMAP + bmi.bmiHeader.biBitCount = indexed ? 8 : depth*8; + int pixelsize = indexed ? 1 : depth; +#else + bmi.bmiHeader.biBitCount = depth*8; + int pixelsize = depth; +#endif + if (depth==2) { // special case: gray with alpha + bmi.bmiHeader.biBitCount = 32; + pixelsize = 4; + } + int linesize = (pixelsize*w+3)&~3; + + static U32* buffer; + int blocking = h; + {int size = linesize*h; + if (size > MAXBUFFER) { + size = MAXBUFFER; + blocking = MAXBUFFER/linesize; + } + static long buffer_size; + if (size > buffer_size) { + delete[] buffer; + buffer_size = size; + buffer = new U32[(size+3)/4]; + }} + bmi.bmiHeader.biHeight = blocking; + static U32* line_buffer; + if (!buf) { + int size = W*delta; + static int line_buf_size; + if (size > line_buf_size) { + delete[] line_buffer; + line_buf_size = size; + line_buffer = new U32[(size+3)/4]; + } + } + for (int j=0; j>8; + to[0] = gray; + to[1] = gray; + to[2] = gray; + to[3] = a; + } + break; + case 3: + for (i=w; i--; from += delta, to += 3) { + uchar r = from[0]; + to[0] = from[2]; + to[1] = from[1]; + to[2] = r; + } + break; + case 4: + for (i=w; i--; from += delta, to += 4) { + uchar a = from[3]; + uchar r = from[0]; + to[0] = (from[2]*a)>>8; + to[1] = (from[1]*a)>>8; + to[2] = (r*a)>>8; + to[3] = from[3]; + } + break; + } + } + } + if(Fl_Surface_Device::surface()->type() == Fl_Printer::device_type) { + // if print context, device and logical units are not equal, so SetDIBitsToDevice + // does not do the expected job, whereas StretchDIBits does it. + StretchDIBits(fl_gc, x, y+j-k, w, k, 0, 0, w, k, + (LPSTR)((uchar*)buffer+(blocking-k)*linesize), + &bmi, +#if USE_COLORMAP + indexed ? DIB_PAL_COLORS : DIB_RGB_COLORS +#else + DIB_RGB_COLORS +#endif + , SRCCOPY ); + } + else { + SetDIBitsToDevice(fl_gc, x, y+j-k, w, k, 0, 0, 0, k, + (LPSTR)((uchar*)buffer+(blocking-k)*linesize), + &bmi, +#if USE_COLORMAP + indexed ? DIB_PAL_COLORS : DIB_RGB_COLORS +#else + DIB_RGB_COLORS +#endif + ); + } + } +} + +static int fl_abs(int v) { return v<0 ? -v : v; } + +void Fl_Graphics_Driver::draw_image(const uchar* buf, int x, int y, int w, int h, int d, int l){ + if (fl_abs(d)&FL_IMAGE_WITH_ALPHA) { + d ^= FL_IMAGE_WITH_ALPHA; + innards(buf,x,y,w,h,d,l,fl_abs(d),0,0); + } else { + innards(buf,x,y,w,h,d,l,(d<3&&d>-3),0,0); + } +} + +void Fl_Graphics_Driver::draw_image(Fl_Draw_Image_Cb cb, void* data, + int x, int y, int w, int h,int d) { + if (fl_abs(d)&FL_IMAGE_WITH_ALPHA) { + d ^= FL_IMAGE_WITH_ALPHA; + innards(0,x,y,w,h,d,0,(d<3&&d>-3),cb,data); + } else { + innards(0,x,y,w,h,d,0,(d<3&&d>-3),cb,data); + } +} + +void Fl_Graphics_Driver::draw_image_mono(const uchar* buf, int x, int y, int w, int h, int d, int l){ + if (fl_abs(d)&FL_IMAGE_WITH_ALPHA) { + d ^= FL_IMAGE_WITH_ALPHA; + innards(buf,x,y,w,h,d,l,1,0,0); + } else { + innards(buf,x,y,w,h,d,l,1,0,0); + } +} + +void Fl_Graphics_Driver::draw_image_mono(Fl_Draw_Image_Cb cb, void* data, + int x, int y, int w, int h,int d) { + if (fl_abs(d)&FL_IMAGE_WITH_ALPHA) { + d ^= FL_IMAGE_WITH_ALPHA; + innards(0,x,y,w,h,d,0,1,cb,data); + } else { + innards(0,x,y,w,h,d,0,1,cb,data); + } +} + +void fl_rectf(int x, int y, int w, int h, uchar r, uchar g, uchar b) { +#if USE_COLORMAP + // use the error diffusion dithering code to produce a much nicer block: + if (fl_palette) { + uchar c[3]; + c[0] = r; c[1] = g; c[2] = b; + innards(c,x,y,w,h,0,0,0,0,0); + return; + } +#endif + fl_color(r,g,b); + fl_rectf(x,y,w,h); +} + +// +// End of "$Id: fl_draw_image_win32.cxx 7617 2010-05-27 17:20:18Z manolo $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_draw_pixmap.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_draw_pixmap.cxx new file mode 100644 index 0000000..c550ff4 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_draw_pixmap.cxx @@ -0,0 +1,429 @@ +// +// "$Id: fl_draw_pixmap.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Pixmap drawing code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Implemented without using the xpm library (which I can't use because +// it interferes with the color cube used by fl_draw_image). +// Current implementation is cheap and slow, and works best on a full-color +// display. Transparency is not handled, and colors are dithered to +// the color cube. Color index is achieved by adding the id +// characters together! Also mallocs a lot of temporary memory! +// Notice that there is no pixmap file interface. This is on purpose, +// as I want to discourage programs that require support files to work. +// All data needed by a program ui should be compiled in!!! + +#include +#include +#include +#include +#include "flstring.h" + +static int ncolors, chars_per_pixel; + +/** + Get the dimensions of a pixmap. + An XPM image contains the dimensions in its data. This function + returns te width and height. + \param[in] data pointer to XPM image data. + \param[out] w,h width and height of image + \returns non-zero if the dimensions were parsed OK + \returns 0 if there were any problems + */ +int fl_measure_pixmap(/*const*/ char* const* data, int &w, int &h) { + return fl_measure_pixmap((const char*const*)data,w,h); +} + +/** + Get the dimensions of a pixmap. + \see fl_measure_pixmap(char* const* data, int &w, int &h) + */ +int fl_measure_pixmap(const char * const *cdata, int &w, int &h) { + int i = sscanf(cdata[0],"%d%d%d%d",&w,&h,&ncolors,&chars_per_pixel); + if (i<4 || w<=0 || h<=0 || + (chars_per_pixel!=1 && chars_per_pixel!=2) ) return w=0; + return 1; +} + +#ifdef U64 + +// The callback from fl_draw_image to get a row of data passes this: +struct pixmap_data { + int w, h; + const uchar*const* data; + union { + U64 colors[256]; + U64* byte1[256]; + }; +}; + +// callback for 1 byte per pixel: +static void cb1(void*v, int x, int y, int w, uchar* buf) { + pixmap_data& d = *(pixmap_data*)v; + const uchar* p = d.data[y]+x; + U64* q = (U64*)buf; + for (int X=w; X>0; X-=2, p += 2) { + if (X>1) { +# if WORDS_BIGENDIAN + *q++ = (d.colors[p[0]]<<32) | d.colors[p[1]]; +# else + *q++ = (d.colors[p[1]]<<32) | d.colors[p[0]]; +# endif + } else { +# if WORDS_BIGENDIAN + *q++ = d.colors[p[0]]<<32; +# else + *q++ = d.colors[p[0]]; +# endif + } + } +} + +// callback for 2 bytes per pixel: +static void cb2(void*v, int x, int y, int w, uchar* buf) { + pixmap_data& d = *(pixmap_data*)v; + const uchar* p = d.data[y]+2*x; + U64* q = (U64*)buf; + for (int X=w; X>0; X-=2) { + U64* colors = d.byte1[*p++]; + int index = *p++; + if (X>1) { + U64* colors1 = d.byte1[*p++]; + int index1 = *p++; +# if WORDS_BIGENDIAN + *q++ = (colors[index]<<32) | colors1[index1]; +# else + *q++ = (colors1[index1]<<32) | colors[index]; +# endif + } else { +# if WORDS_BIGENDIAN + *q++ = colors[index]<<32; +# else + *q++ = colors[index]; +# endif + } + } +} + +#else // U32 + +// The callback from fl_draw_image to get a row of data passes this: +struct pixmap_data { + int w, h; + const uchar*const* data; + union { + U32 colors[256]; + U32* byte1[256]; + }; +}; + +// callback for 1 byte per pixel: +static void cb1(void*v, int x, int y, int w, uchar* buf) { + pixmap_data& d = *(pixmap_data*)v; + const uchar* p = d.data[y]+x; + U32* q = (U32*)buf; + for (int X=w; X--;) *q++ = d.colors[*p++]; +} + +// callback for 2 bytes per pixel: +static void cb2(void*v, int x, int y, int w, uchar* buf) { + pixmap_data& d = *(pixmap_data*)v; + const uchar* p = d.data[y]+2*x; + U32* q = (U32*)buf; + for (int X=w; X--;) { + U32* colors = d.byte1[*p++]; + *q++ = colors[*p++]; + } +} + +#endif // U64 else U32 + +uchar **fl_mask_bitmap; // if non-zero, create bitmap and store pointer here + +/** + Draw XPM image data, with the top-left corner at the given position. + The image is dithered on 8-bit displays so you won't lose color + space for programs displaying both images and pixmaps. + \param[in] data pointer to XPM image data + \param[in] x,y position of top-left corner + \param[in] bg background color + \returns 0 if there was any error decoding the XPM data. + */ +int fl_draw_pixmap(/*const*/ char* const* data, int x,int y,Fl_Color bg) { + return fl_draw_pixmap((const char*const*)data,x,y,bg); +} + +#ifdef WIN32 +// to compute an unused color to be used for the pixmap background +FL_EXPORT UINT win_pixmap_bg_color; // the RGB() of the pixmap background color +static int color_count; // # of non-transparent colors used in pixmap +static uchar *used_colors; // used_colors[3*i+j] j=0,1,2 are the RGB values of the ith used color + +static void make_unused_color(uchar &r, uchar &g, uchar &b) +// makes an RGB triplet different from all the colors used in the pixmap +// and compute win_pixmap_bg_color from this triplet +{ + int i; + r = 2; g = 3; b = 4; + while (1) { + for ( i = 0; i < color_count; i++) { + if(used_colors[3*i] == r && used_colors[3*i+1] == g && used_colors[3*i+2] == b) break; + } + if (i >= color_count) { + free(used_colors); + win_pixmap_bg_color = RGB(r, g, b); + return; + } + if (r < 255) r++; + else { + r = 0; + if (g < 255) g++; + else { + g = 0; + b++; + } + } + } +} +#endif + +/** + Draw XPM image data, with the top-left corner at the given position. + \see fl_draw_pixmap(char* const* data, int x, int y, Fl_Color bg) + */ +int fl_draw_pixmap(const char*const* cdata, int x, int y, Fl_Color bg) { + pixmap_data d; + if (!fl_measure_pixmap(cdata, d.w, d.h)) return 0; + const uchar*const* data = (const uchar*const*)(cdata+1); + int transparent_index = -1; + uchar *transparent_c = (uchar *)0; // such that transparent_c[0,1,2] are the RGB of the transparent color +#ifdef WIN32 + color_count = 0; + used_colors = (uchar *)malloc(abs(ncolors)*3*sizeof(uchar)); +#endif + + if (ncolors < 0) { // FLTK (non standard) compressed colormap + ncolors = -ncolors; + const uchar *p = *data++; + // if first color is ' ' it is transparent (put it later to make + // it not be transparent): + if (*p == ' ') { + uchar* c = (uchar*)&d.colors[(int)' ']; +#ifdef U64 + *(U64*)c = 0; +# if WORDS_BIGENDIAN + c += 4; +# endif +#endif + transparent_index = ' '; + Fl::get_color(bg, c[0], c[1], c[2]); c[3] = 0; + transparent_c = c; + p += 4; + ncolors--; + } + // read all the rest of the colors: + for (int i=0; i < ncolors; i++) { + uchar* c = (uchar*)&d.colors[*p++]; +#ifdef U64 + *(U64*)c = 0; +# if WORDS_BIGENDIAN + c += 4; +# endif +#endif +#ifdef WIN32 + used_colors[3*color_count] = *p; + used_colors[3*color_count+1] = *(p+1); + used_colors[3*color_count+2] = *(p+2); + color_count++; +#endif + *c++ = *p++; + *c++ = *p++; + *c++ = *p++; +#ifdef __APPLE_QUARTZ__ + *c = 255; +#else + *c = 0; +#endif + } + } else { // normal XPM colormap with names + if (chars_per_pixel>1) memset(d.byte1, 0, sizeof(d.byte1)); + for (int i=0; i1) { +#ifdef U64 + U64* colors = d.byte1[ind]; + if (!colors) colors = d.byte1[ind] = new U64[256]; +#else + U32* colors = d.byte1[ind]; + if (!colors) colors = d.byte1[ind] = new U32[256]; +#endif + c = (uchar*)&colors[*p]; + ind = (ind<<8)|*p++; + } else { + c = (uchar *)&d.colors[ind]; + } + // look for "c word", or last word if none: + const uchar *previous_word = p; + for (;;) { + while (*p && isspace(*p)) p++; + uchar what = *p++; + while (*p && !isspace(*p)) p++; + while (*p && isspace(*p)) p++; + if (!*p) {p = previous_word; break;} + if (what == 'c') break; + previous_word = p; + while (*p && !isspace(*p)) p++; + } +#ifdef U64 + *(U64*)c = 0; +# if WORDS_BIGENDIAN + c += 4; +# endif +#endif +#ifdef __APPLE_QUARTZ__ + c[3] = 255; +#endif + int parse = fl_parse_color((const char*)p, c[0], c[1], c[2]); + if (parse) { +#ifdef WIN32 + used_colors[3*color_count] = c[0]; + used_colors[3*color_count+1] = c[1]; + used_colors[3*color_count+2] = c[2]; + color_count++; +#endif + } + else { + // assume "None" or "#transparent" for any errors + // "bg" should be transparent... + Fl::get_color(bg, c[0], c[1], c[2]); +#ifdef __APPLE_QUARTZ__ + c[3] = 0; +#endif + transparent_index = ind; + transparent_c = c; + } + } + } + d.data = data; +#ifdef WIN32 + if (transparent_c) { + make_unused_color(transparent_c[0], transparent_c[1], transparent_c[2]); + } + else { + uchar r, g, b; + make_unused_color(r, g, b); + } +#endif + +#ifdef __APPLE_QUARTZ__ + if (fl_graphics_driver->type() == Fl_Quartz_Graphics_Driver::device_type ) { + bool transparent = (transparent_index>=0); + transparent = true; + U32 *array = new U32[d.w * d.h], *q = array; + for (int Y = 0; Y < d.h; Y++) { + const uchar* p = data[Y]; + if (chars_per_pixel <= 1) { + for (int X = 0; X < d.w; X++) { + *q++ = d.colors[*p++]; + } + } else { + for (int X = 0; X < d.w; X++) { + U32* colors = (U32*)d.byte1[*p++]; + *q++ = colors[*p++]; + } + } + } + CGColorSpaceRef lut = CGColorSpaceCreateDeviceRGB(); + CGDataProviderRef src = CGDataProviderCreateWithData( 0L, array, d.w * d.h * 4, 0L); + CGImageRef img = CGImageCreate(d.w, d.h, 8, 4*8, 4*d.w, + lut, transparent?kCGImageAlphaLast:kCGImageAlphaNoneSkipLast, + src, 0L, false, kCGRenderingIntentDefault); + CGColorSpaceRelease(lut); + CGDataProviderRelease(src); + CGRect rect = { { x, y} , { d.w, d.h } }; + Fl_X::q_begin_image(rect, 0, 0, d.w, d.h); + CGContextDrawImage(fl_gc, rect, img); + Fl_X::q_end_image(); + CGImageRelease(img); + delete array; + } + else { +#endif // __APPLE_QUARTZ__ + + // build the mask bitmap used by Fl_Pixmap: + if (fl_mask_bitmap && transparent_index >= 0) { + int W = (d.w+7)/8; + uchar* bitmap = new uchar[W * d.h]; + *fl_mask_bitmap = bitmap; + for (int Y = 0; Y < d.h; Y++) { + const uchar* p = data[Y]; + if (chars_per_pixel <= 1) { + int dw = d.w; + for (int X = 0; X < W; X++) { + uchar b = (dw-->0 && *p++ != transparent_index); + if (dw-->0 && *p++ != transparent_index) b |= 2; + if (dw-->0 && *p++ != transparent_index) b |= 4; + if (dw-->0 && *p++ != transparent_index) b |= 8; + if (dw-->0 && *p++ != transparent_index) b |= 16; + if (dw-->0 && *p++ != transparent_index) b |= 32; + if (dw-->0 && *p++ != transparent_index) b |= 64; + if (dw-->0 && *p++ != transparent_index) b |= 128; + *bitmap++ = b; + } + } else { + uchar b = 0, bit = 1; + for (int X = 0; X < d.w; X++) { + int ind = *p++; + ind = (ind<<8) | (*p++); + if (ind != transparent_index) b |= bit; + + if (bit < 128) bit <<= 1; + else { + *bitmap++ = b; + b = 0; + bit = 1; + } + } + + if (bit > 1) *bitmap++ = b; + } + } + } + + fl_draw_image(chars_per_pixel==1 ? cb1 : cb2, &d, x, y, d.w, d.h, 4); +#ifdef __APPLE_QUARTZ__ + } +#endif + + if (chars_per_pixel > 1) for (int i = 0; i < 256; i++) delete[] d.byte1[i]; + return 1; +} + +// +// End of "$Id: fl_draw_pixmap.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_encoding_latin1.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_encoding_latin1.cxx new file mode 100644 index 0000000..bac5311 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_encoding_latin1.cxx @@ -0,0 +1,137 @@ +// +// "$Id: fl_encoding_latin1.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Convert MSWindows-1252 (Latin-1) encoded text to the local encoding. +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include +#include "flstring.h" + +#ifdef __APPLE__ + +// These function assume a western code page. If you need to support +// scripts that are not part of this code page, you might want to +// take a look at FLTK2, which uses utf8 for text encoding. +// +// By keeping these conversion tables in their own module, they will not +// be statically linked (by a smart linker) unless actually used. +// +// On MS-Windows, nothing need to be converted. We simply return the +// original pointer. +// +// Most X11 implementations seem to default to Latin-1 as a code since it +// is a superset of ISO 8859-1, the original wetsern codepage on X11. +// +// Apple's OS X however renders text in MacRoman for western settings. The +// lookup tables below will convert all common character codes and replace +// unknown characters with an upsidedown question mark. + +// This table converts MSWindows-1252/Latin 1 into MacRoman encoding +static uchar latin2roman[128] = { +0xdb, 0xc0, 0xe2, 0xc4, 0xe3, 0xc9, 0xa0, 0xe0, 0xf6, 0xe4, 0xc0, 0xdc, 0xce, 0xc0, 0xc0, 0xc0, +0xc0, 0xd4, 0xd5, 0xd2, 0xd3, 0xa5, 0xd0, 0xd1, 0xf7, 0xaa, 0xc0, 0xdd, 0xcf, 0xc0, 0xc0, 0xd9, +0xca, 0xc1, 0xa2, 0xa3, 0xc0, 0xb4, 0xc0, 0xa4, 0xac, 0xa9, 0xbb, 0xc7, 0xc2, 0xc0, 0xa8, 0xf8, +0xa1, 0xb1, 0xc0, 0xc0, 0xab, 0xb5, 0xa6, 0xe1, 0xfc, 0xc0, 0xbc, 0xc8, 0xc0, 0xc0, 0xc0, 0xc0, +0xcb, 0xe7, 0xe5, 0xcc, 0x80, 0x81, 0xae, 0x82, 0xe9, 0x83, 0xe6, 0xe8, 0xed, 0xea, 0xeb, 0xec, +0xc0, 0x84, 0xf1, 0xee, 0xef, 0xcd, 0x85, 0xc0, 0xaf, 0xf4, 0xf2, 0xf3, 0x86, 0xc0, 0xc0, 0xa7, +0x88, 0x87, 0x89, 0x8b, 0x8a, 0x8c, 0xbe, 0x8d, 0x8f, 0x8e, 0x90, 0x91, 0x93, 0x92, 0x94, 0x95, +0xc0, 0x96, 0x98, 0x97, 0x99, 0x9b, 0x9a, 0xd6, 0xbf, 0x9d, 0x9c, 0x9e, 0x9f, 0xc0, 0xc0, 0xd8 +}; + +// This table converts MacRoman into MSWindows-1252/Latin 1 +static uchar roman2latin[128] = { +0xc4, 0xc5, 0xc7, 0xc9, 0xd1, 0xd6, 0xdc, 0xe1, 0xe0, 0xe2, 0xe4, 0xe3, 0xe5, 0xe7, 0xe9, 0xe8, +0xea, 0xeb, 0xed, 0xec, 0xee, 0xef, 0xf1, 0xf3, 0xf2, 0xf4, 0xf6, 0xf5, 0xfa, 0xf9, 0xfb, 0xfc, +0x86, 0xb0, 0xa2, 0xa3, 0xa7, 0x95, 0xb6, 0xdf, 0xae, 0xa9, 0x99, 0xb4, 0xa8, 0xbf, 0xc6, 0xd8, +0xbf, 0xb1, 0xbf, 0xbf, 0xa5, 0xb5, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xaa, 0xba, 0xbf, 0xe6, 0xf8, +0xbf, 0xa1, 0xac, 0xbf, 0x83, 0xbf, 0xbf, 0xab, 0xbb, 0x85, 0xa0, 0xc0, 0xc3, 0xd5, 0x8c, 0x9c, +0x96, 0x97, 0x93, 0x94, 0x91, 0x92, 0xf7, 0xbf, 0xff, 0x9f, 0xbf, 0x80, 0x8b, 0x9b, 0xbf, 0xbf, +0x87, 0xb7, 0x82, 0x84, 0x89, 0xc2, 0xca, 0xc1, 0xcb, 0xc8, 0xcd, 0xce, 0xcf, 0xcc, 0xd3, 0xd4, +0xbf, 0xd2, 0xda, 0xdb, 0xd9, 0xbf, 0x88, 0x98, 0xaf, 0xbf, 0xbf, 0xbf, 0xb8, 0xbf, 0xbf, 0xbf +}; + +static char *buf = 0; +static int n_buf = 0; + +const char *fl_latin1_to_local(const char *t, int n) +{ + if (n==-1) n = strlen(t); + if (n<=n_buf) { + n_buf = (n + 257) & 0x7fffff00; + if (buf) free(buf); + buf = (char*)malloc(n_buf); + } + const uchar *src = (const uchar*)t; + uchar *dst = (uchar*)buf; + for ( ; n>0; n--) { + uchar c = *src++; + if (c>127) + *dst = latin2roman[c-128]; + else + *dst = c; + } + //*dst = 0; // this would be wrong! + return buf; +} + +const char *fl_local_to_latin1(const char *t, int n) +{ + if (n==-1) n = strlen(t); + if (n<=n_buf) { + n_buf = (n + 257) & 0x7fffff00; + if (buf) free(buf); + buf = (char*)malloc(n_buf); + } + const uchar *src = (const uchar*)t; + uchar *dst = (uchar*)buf; + for ( ; n>0; n--) { + uchar c = *src++; + if (c>127) + *dst++ = roman2latin[c-128]; + else + *dst++ = c; + } + //*dst = 0; // this would be wrong + return buf; +} + +#else + +const char *fl_latin1_to_local(const char *t, int) +{ + return t; +} + +const char *fl_local_to_latin1(const char *t, int) +{ + return t; +} + +#endif + +// +// End of "$Id: fl_encoding_latin1.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_encoding_mac_roman.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_encoding_mac_roman.cxx new file mode 100644 index 0000000..45d6115 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_encoding_mac_roman.cxx @@ -0,0 +1,134 @@ +// +// "$Id: fl_encoding_mac_roman.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Convert Mac Roman encoded text to the local encoding. +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include +#include "flstring.h" + +// These function assume a western code page. If you need to support +// scripts that are not part of this code page, you might want to +// take a look at FLTK2, which uses utf8 for text encoding. +// +// By keeping these conversion tables in their own module, they will not +// be statically linked (by a smart linker) unless actually used. +// +// On Mac OS X, nothing need to be converted. We simply return the +// original pointer. +// +// MSWindows and X11 render text in ISO or Latin-1 for western settings. The +// lookup tables below will convert all common character codes and replace +// unknown characters with an upsidedown question mark. + +#ifdef __APPLE__ + +const char *fl_mac_roman_to_local(const char *t, int) +{ + return t; +} + +const char *fl_local_to_mac_roman(const char *t, int) +{ + return t; +} + +#else + +// This table converts MSWindows-1252/Latin 1 into MacRoman encoding +static uchar latin2roman[128] = { +0xdb, 0xc0, 0xe2, 0xc4, 0xe3, 0xc9, 0xa0, 0xe0, 0xf6, 0xe4, 0xc0, 0xdc, 0xce, 0xc0, 0xc0, 0xc0, +0xc0, 0xd4, 0xd5, 0xd2, 0xd3, 0xa5, 0xd0, 0xd1, 0xf7, 0xaa, 0xc0, 0xdd, 0xcf, 0xc0, 0xc0, 0xd9, +0xca, 0xc1, 0xa2, 0xa3, 0xc0, 0xb4, 0xc0, 0xa4, 0xac, 0xa9, 0xbb, 0xc7, 0xc2, 0xc0, 0xa8, 0xf8, +0xa1, 0xb1, 0xc0, 0xc0, 0xab, 0xb5, 0xa6, 0xe1, 0xfc, 0xc0, 0xbc, 0xc8, 0xc0, 0xc0, 0xc0, 0xc0, +0xcb, 0xe7, 0xe5, 0xcc, 0x80, 0x81, 0xae, 0x82, 0xe9, 0x83, 0xe6, 0xe8, 0xed, 0xea, 0xeb, 0xec, +0xc0, 0x84, 0xf1, 0xee, 0xef, 0xcd, 0x85, 0xc0, 0xaf, 0xf4, 0xf2, 0xf3, 0x86, 0xc0, 0xc0, 0xa7, +0x88, 0x87, 0x89, 0x8b, 0x8a, 0x8c, 0xbe, 0x8d, 0x8f, 0x8e, 0x90, 0x91, 0x93, 0x92, 0x94, 0x95, +0xc0, 0x96, 0x98, 0x97, 0x99, 0x9b, 0x9a, 0xd6, 0xbf, 0x9d, 0x9c, 0x9e, 0x9f, 0xc0, 0xc0, 0xd8 +}; + +// This table converts MacRoman into MSWindows-1252/Latin 1 +static uchar roman2latin[128] = { +0xc4, 0xc5, 0xc7, 0xc9, 0xd1, 0xd6, 0xdc, 0xe1, 0xe0, 0xe2, 0xe4, 0xe3, 0xe5, 0xe7, 0xe9, 0xe8, +0xea, 0xeb, 0xed, 0xec, 0xee, 0xef, 0xf1, 0xf3, 0xf2, 0xf4, 0xf6, 0xf5, 0xfa, 0xf9, 0xfb, 0xfc, +0x86, 0xb0, 0xa2, 0xa3, 0xa7, 0x95, 0xb6, 0xdf, 0xae, 0xa9, 0x99, 0xb4, 0xa8, 0xbf, 0xc6, 0xd8, +0xbf, 0xb1, 0xbf, 0xbf, 0xa5, 0xb5, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xaa, 0xba, 0xbf, 0xe6, 0xf8, +0xbf, 0xa1, 0xac, 0xbf, 0x83, 0xbf, 0xbf, 0xab, 0xbb, 0x85, 0xa0, 0xc0, 0xc3, 0xd5, 0x8c, 0x9c, +0x96, 0x97, 0x93, 0x94, 0x91, 0x92, 0xf7, 0xbf, 0xff, 0x9f, 0xbf, 0x80, 0x8b, 0x9b, 0xbf, 0xbf, +0x87, 0xb7, 0x82, 0x84, 0x89, 0xc2, 0xca, 0xc1, 0xcb, 0xc8, 0xcd, 0xce, 0xcf, 0xcc, 0xd3, 0xd4, +0xbf, 0xd2, 0xda, 0xdb, 0xd9, 0xbf, 0x88, 0x98, 0xaf, 0xbf, 0xbf, 0xbf, 0xb8, 0xbf, 0xbf, 0xbf +}; + +static char *buf = 0; +static int n_buf = 0; + +const char *fl_local_to_mac_roman(const char *t, int n) +{ + if (n==-1) n = strlen(t); + if (n<=n_buf) { + n_buf = (n + 257) & 0x7fffff00; + if (buf) free(buf); + buf = (char*)malloc(n_buf); + } + const uchar *src = (const uchar*)t; + uchar *dst = (uchar*)buf; + for ( ; n>0; n--) { + uchar c = *src; + if (c>127) + *dst = latin2roman[c-128]; + else + *dst = c; + } + //*dst = 0; // this would be wrong! + return buf; +} + +const char *fl_mac_roman_to_local(const char *t, int n) +{ + if (n==-1) n = strlen(t); + if (n<=n_buf) { + n_buf = (n + 257) & 0x7fffff00; + if (buf) free(buf); + buf = (char*)malloc(n_buf); + } + const uchar *src = (const uchar*)t; + uchar *dst = (uchar*)buf; + for ( ; n>0; n--) { + uchar c = *src++; + if (c>127) + *dst++ = roman2latin[c-128]; + else + *dst++ = c; + } + //*dst = 0; // this would be wrong + return buf; +} + +#endif + +// +// End of "$Id: fl_encoding_mac_roman.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_engraved_label.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_engraved_label.cxx new file mode 100644 index 0000000..bd0af89 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_engraved_label.cxx @@ -0,0 +1,93 @@ +// +// "$Id: fl_engraved_label.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Engraved label drawing routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Drawing code for XForms style engraved & embossed labels + +#include +#include +#include + +// data[] is dx, dy, color triples + +static void innards( + const Fl_Label* o, int X, int Y, int W, int H, Fl_Align align, + int data[][3], int n) +{ + Fl_Align a1 = align; + if (a1 & FL_ALIGN_CLIP) { + fl_push_clip(X, Y, W, H); a1 = (Fl_Align)(a1&~FL_ALIGN_CLIP);} + fl_font((Fl_Font)o->font, o->size); + for (int i = 0; i < n; i++) { + fl_color((Fl_Color)(i < n-1 ? data[i][2] : o->color)); + fl_draw(o->value, X+data[i][0], Y+data[i][1], W, H, a1); + } + if (align & FL_ALIGN_CLIP) fl_pop_clip(); +} + +static void fl_shadow_label( + const Fl_Label* o, int X, int Y, int W, int H, Fl_Align align) +{ + static int data[2][3] = {{2,2,FL_DARK3},{0,0,0}}; + innards(o, X, Y, W, H, align, data, 2); +} + +static void fl_engraved_label( + const Fl_Label* o, int X, int Y, int W, int H, Fl_Align align) +{ + static int data[7][3] = { + {1,0,FL_LIGHT3},{1,1,FL_LIGHT3},{0,1,FL_LIGHT3}, + {-1,0,FL_DARK3},{-1,-1,FL_DARK3},{0,-1,FL_DARK3}, + {0,0,0}}; + innards(o, X, Y, W, H, align, data, 7); +} + +static void fl_embossed_label( + const Fl_Label* o, int X, int Y, int W, int H, Fl_Align align) +{ + static int data[7][3] = { + {-1,0,FL_LIGHT3},{-1,-1,FL_LIGHT3},{0,-1,FL_LIGHT3}, + {1,0,FL_DARK3},{1,1,FL_DARK3},{0,1,FL_DARK3}, + {0,0,0}}; + innards(o, X, Y, W, H, align, data, 7); +} + +Fl_Labeltype fl_define_FL_SHADOW_LABEL() { + Fl::set_labeltype(_FL_SHADOW_LABEL, fl_shadow_label, 0); + return _FL_SHADOW_LABEL; +} +Fl_Labeltype fl_define_FL_ENGRAVED_LABEL() { + Fl::set_labeltype(_FL_ENGRAVED_LABEL, fl_engraved_label, 0); + return _FL_ENGRAVED_LABEL; +} +Fl_Labeltype fl_define_FL_EMBOSSED_LABEL() { + Fl::set_labeltype(_FL_EMBOSSED_LABEL, fl_embossed_label, 0); + return _FL_EMBOSSED_LABEL; +} + +// +// End of "$Id: fl_engraved_label.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_file_dir.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_file_dir.cxx new file mode 100644 index 0000000..f624014 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_file_dir.cxx @@ -0,0 +1,194 @@ +// +// "$Id: fl_file_dir.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// File chooser widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include "flstring.h" +#include +#include +#include + + +static Fl_File_Chooser *fc = (Fl_File_Chooser *)0; +static void (*current_callback)(const char*) = 0; +static const char *current_label = fl_ok; + + +// Do a file chooser callback... +static void callback(Fl_File_Chooser *, void*) { + if (current_callback && fc->value()) + (*current_callback)(fc->value()); +} + +/** \addtogroup group_comdlg + @{ */ + +/** \relatesalso Fl_File_Chooser + Set the file chooser callback +*/ +void fl_file_chooser_callback(void (*cb)(const char*)) { + current_callback = cb; +} + + +/** \relatesalso Fl_File_Chooser + Set the "OK" button label +*/ +void fl_file_chooser_ok_label(const char *l) { + if (l) current_label = l; + else current_label = fl_ok; +} + +/** \relates Fl_File_Chooser + Shows a file chooser dialog and gets a filename. + \image html Fl_File_Chooser.jpg + \image latex Fl_File_Chooser.eps "Fl_File_Chooser" width=12cm + \param[in] message text in title bar + \param[in] pat filename pattern filter + \param[in] fname initial/default filename selection + \param[in] relative 0 for absolute path name, relative path name otherwise + \return the user selected filename, in absolute or relative format + or NULL if user cancels +*/ +char * // O - Filename or NULL +fl_file_chooser(const char *message, // I - Message in titlebar + const char *pat, // I - Filename pattern + const char *fname, // I - Initial filename selection + int relative) { // I - 0 for absolute path + static char retname[1024]; // Returned filename + + if (!fc) { + if (!fname || !*fname) fname = "."; + + fc = new Fl_File_Chooser(fname, pat, Fl_File_Chooser::CREATE, message); + fc->callback(callback, 0); + } else { + fc->type(Fl_File_Chooser::CREATE); + // see, if we use the same pattern between calls + char same_pattern = 0; + const char *fcf = fc->filter(); + if ( fcf && pat && strcmp(fcf, pat)==0) + same_pattern = 1; + else if ( (fcf==0L || *fcf==0) && (pat==0L || *pat==0) ) + same_pattern = 1; + // now set the pattern to the new pattern (even if they are the same) + fc->filter(pat); + fc->label(message); + + if (!fname) { // null pointer reuses same filename if pattern didn't change + if (!same_pattern && fc->value()) { + // if pattern is different, remove name but leave old directory: + strlcpy(retname, fc->value(), sizeof(retname)); + + char *p = strrchr(retname, '/'); + + if (p) { + // If the filename is "/foo", then the directory will be "/", not + // ""... + if (p == retname) + retname[1] = '\0'; + else + *p = '\0'; + } + // Set the directory... + fc->value(retname); + } else { + // re-use the previously selected name + } + } else if (!*fname) { // empty filename reuses directory with empty name + const char *fcv = fc->value(); + if (fcv) + strlcpy(retname, fc->value(), sizeof(retname)); + else + *retname = 0; + const char *n = fl_filename_name(retname); + if (n) *((char*)n) = 0; + fc->value(""); + fc->directory(retname); + } else { + fc->value(fname); + } + } + + fc->ok_label(current_label); + fc->show(); + + while (fc->shown()) + Fl::wait(); + + if (fc->value() && relative) { + fl_filename_relative(retname, sizeof(retname), fc->value()); + + return retname; + } else if (fc->value()) return (char *)fc->value(); + else return 0; +} + +/** \relates Fl_File_Chooser + Shows a file chooser dialog and gets a directory. + \param[in] message title bar text + \param[in] fname initial/default directory name + \param[in] relative 0 for absolute path return, relative otherwise + \return the directory path string chosen by the user or NULL if user cancels +*/ + +char * // O - Directory or NULL +fl_dir_chooser(const char *message, // I - Message for titlebar + const char *fname, // I - Initial directory name + int relative) // I - 0 for absolute +{ + static char retname[1024]; // Returned directory name + + if (!fc) { + if (!fname || !*fname) fname = "."; + + fc = new Fl_File_Chooser(fname, "*", Fl_File_Chooser::CREATE | + Fl_File_Chooser::DIRECTORY, message); + fc->callback(callback, 0); + } else { + fc->type(Fl_File_Chooser::CREATE | Fl_File_Chooser::DIRECTORY); + fc->filter("*"); + if (fname && *fname) fc->value(fname); + fc->label(message); + } + + fc->show(); + + while (fc->shown()) + Fl::wait(); + + if (fc->value() && relative) { + fl_filename_relative(retname, sizeof(retname), fc->value()); + + return retname; + } else if (fc->value()) return (char *)fc->value(); + else return 0; +} +/** @} */ + + +// +// End of "$Id: fl_file_dir.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_font.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_font.cxx new file mode 100644 index 0000000..9b0cebc --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_font.cxx @@ -0,0 +1,91 @@ +// +// "$Id: fl_font.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Font selection code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifdef WIN32 +#ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +#endif +/* We require Windows 2000 features such as GetGlyphIndices */ +# if !defined(WINVER) || (WINVER < 0x0500) +# define WINVER 0x0500 +# endif +# if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0500) +# define _WIN32_WINNT 0x0500 +# endif +#endif + +// Select fonts from the FLTK font table. +#include "flstring.h" +#include +#include +#include +#include "Fl_Font.H" + +#include +#include + +#ifdef WIN32 +# include "fl_font_win32.cxx" +#elif defined(__APPLE__) +# include "fl_font_mac.cxx" +#elif USE_XFT +# include "fl_font_xft.cxx" +#else +# include "fl_font_x.cxx" +#endif // WIN32 + + +double fl_width(const char* c) { + if (c) return fl_width(c, strlen(c)); + else return 0.0f; +} + +void fl_draw(const char* str, int x, int y) { + fl_draw(str, strlen(str), x, y); +} + +void fl_draw(int angle, const char* str, int x, int y) { + fl_draw(angle, str, strlen(str), x, y);//must be fixed! +} + +void fl_text_extents(const char *c, int &dx, int &dy, int &w, int &h) { + if (c) fl_text_extents(c, strlen(c), dx, dy, w, h); + else { + w = 0; h = 0; + dx = 0; dy = 0; + } +} // fl_text_extents + + +#if !USE_XFT && !__APPLE__ +void fl_draw(const char* str, int l, float x, float y) { + fl_draw(str, l, (int)x, (int)y); +} +#endif +// +// End of "$Id: fl_font.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_font_mac.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_font_mac.cxx new file mode 100644 index 0000000..686aaaf --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_font_mac.cxx @@ -0,0 +1,498 @@ +// +// "$Id: fl_font_mac.cxx 7892 2010-11-25 18:21:21Z manolo $" +// +// MacOS font selection routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2009 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include + +/* from fl_utf.c */ +extern unsigned fl_utf8toUtf16(const char* src, unsigned srclen, unsigned short* dst, unsigned dstlen); + +// if no font has been selected yet by the user, get one. +#define check_default_font() {if (!fl_fontsize) fl_font(0, 12);} + +static const CGAffineTransform font_mx = { 1, 0, 0, -1, 0, 0 }; + +Fl_Font_Descriptor::Fl_Font_Descriptor(const char* name, Fl_Fontsize Size) { + next = 0; +# if HAVE_GL + listbase = 0; +# endif + +// knowWidths = 0; + // OpenGL needs those for its font handling + q_name = strdup(name); + size = Size; + minsize = maxsize = Size; +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 +if(fl_mac_os_version == 0) fl_open_display(); +if(fl_mac_os_version >= 0x1050) {//unfortunately, CTFontCreateWithName != NULL on 10.4 also! + CFStringRef str = CFStringCreateWithCString(NULL, name, kCFStringEncodingUTF8); + fontref = CTFontCreateWithName(str, size, NULL); + CGGlyph glyph[2]; + const UniChar A[2]={'W','.'}; + CTFontGetGlyphsForCharacters(fontref, A, glyph, 2); + CGSize advances[2]; + double w; + CTFontGetAdvancesForGlyphs(fontref, kCTFontHorizontalOrientation, glyph, advances, 2); + w = advances[0].width; + if( abs(advances[0].width - advances[1].width) < 1E-2 ) {//this is a fixed-width font + //slightly rescale fixed-width fonts so the character width has an integral value + CFRelease(fontref); + CGFloat fsize = size / ( w/floor(w + 0.5) ); + fontref = CTFontCreateWithName(str, fsize, NULL); + w = CTFontGetAdvancesForGlyphs(fontref, kCTFontHorizontalOrientation, glyph, NULL, 1); + } + CFRelease(str); + ascent = (short)(CTFontGetAscent(fontref) + 0.5); + descent = (short)(CTFontGetDescent(fontref) + 0.5); + q_width = w + 0.5; + } +else { +#endif +#if ! __LP64__ + OSStatus err; + // fill our structure with a few default values + ascent = Size*3/4; + descent = Size-ascent; + q_width = Size*2/3; + // now use ATS to get the actual Glyph size information + // say that our passed-in name is encoded as UTF-8, since this works for plain ASCII names too... + CFStringRef cfname = CFStringCreateWithCString(0L, name, kCFStringEncodingUTF8); + ATSFontRef font = ATSFontFindFromName(cfname, kATSOptionFlagsDefault); + if (font) { + ATSFontMetrics m = { 0 }; + ATSFontGetHorizontalMetrics(font, kATSOptionFlagsDefault, &m); + if (m.avgAdvanceWidth) q_width = int(m.avgAdvanceWidth*Size); + // playing with the offsets a little to make standard sizes fit + if (m.ascent) ascent = int(m.ascent*Size-0.5f); + if (m.descent) descent = -int(m.descent*Size-1.5f); + } + CFRelease(cfname); + // now we allocate everything needed to render text in this font later + // get us the default layout and style + err = ATSUCreateTextLayout(&layout); + UniChar mTxt[2] = { 65, 0 }; + err = ATSUSetTextPointerLocation(layout, mTxt, kATSUFromTextBeginning, 1, 1); + err = ATSUCreateStyle(&style); + err = ATSUSetRunStyle(layout, style, kATSUFromTextBeginning, kATSUToTextEnd); + // now set the actual font, size and attributes. We also set the font matrix to + // render our font up-side-down, so when rendered through our inverted CGContext, + // text will appear normal again. + Fixed fsize = IntToFixed(Size); +// ATSUFontID fontID = FMGetFontFromATSFontRef(font); + ATSUFontID fontID; + ATSUFindFontFromName(name, strlen(name), kFontFullName, kFontMacintoshPlatform, kFontRomanScript, kFontEnglishLanguage, &fontID); + + // draw the font upside-down... Compensate for fltk/OSX origin differences + static CGAffineTransform font_mx = { 1, 0, 0, -1, 0, 0 }; + ATSUAttributeTag sTag[] = { kATSUFontTag, kATSUSizeTag, kATSUFontMatrixTag }; + ByteCount sBytes[] = { sizeof(ATSUFontID), sizeof(Fixed), sizeof(CGAffineTransform) }; + ATSUAttributeValuePtr sAttr[] = { &fontID, &fsize, &font_mx }; + err = ATSUSetAttributes(style, 3, sTag, sBytes, sAttr); + // next, make sure that Quartz will only render at integer coordinates + ATSLineLayoutOptions llo = kATSLineUseDeviceMetrics | kATSLineDisableAllLayoutOperations; + ATSUAttributeTag aTag[] = { kATSULineLayoutOptionsTag }; + ByteCount aBytes[] = { sizeof(ATSLineLayoutOptions) }; + ATSUAttributeValuePtr aAttr[] = { &llo }; + err = ATSUSetLineControls (layout, kATSUFromTextBeginning, 1, aTag, aBytes, aAttr); + // now we are finally ready to measure some letter to get the bounding box + Fixed bBefore, bAfter, bAscent, bDescent; + err = ATSUGetUnjustifiedBounds(layout, kATSUFromTextBeginning, 1, &bBefore, &bAfter, &bAscent, &bDescent); + // Requesting a certain height font on Mac does not guarantee that ascent+descent + // equal the requested height. fl_height will reflect the actual height that we got. + // The font "Apple Chancery" is a pretty extreme example of overlapping letters. + float fa = -FixedToFloat(bAscent), fd = -FixedToFloat(bDescent); + if (fa>0.0f && fd>0.0f) { + //float f = Size/(fa+fd); + ascent = int(fa); //int(fa*f+0.5f); + descent = int(fd); //Size - ascent; + } + int w = FixedToInt(bAfter); + if (w) + q_width = FixedToInt(bAfter); + +# define ENABLE_TRANSIENT_FONTS 1 + +# ifdef ENABLE_TRANSIENT_FONTS + // Now, by way of experiment, try enabling Transient Font Matching, this will + // cause ATSU to find a suitable font to render any chars the current font can't do... + ATSUSetTransientFontMatching (layout, true); +# endif +#endif//__LP64__ +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + } +#endif +} + +Fl_Font_Descriptor* fl_fontsize = 0L; + +Fl_Font_Descriptor::~Fl_Font_Descriptor() { +/* +#if HAVE_GL + // ++ todo: remove OpenGL font alocations +// Delete list created by gl_draw(). This is not done by this code +// as it will link in GL unnecessarily. There should be some kind +// of "free" routine pointer, or a subclass? +// if (listbase) { +// int base = font->min_char_or_byte2; +// int size = font->max_char_or_byte2-base+1; +// int base = 0; int size = 256; +// glDeleteLists(listbase+base,size); +// } +#endif + */ + if (this == fl_fontsize) fl_fontsize = 0; +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + if(fl_mac_os_version >= 0x1050) CFRelease(fontref); +#else + /* ATSUDisposeTextLayout(layout); + ATSUDisposeStyle(style); */ +#endif +} + +//////////////////////////////////////////////////////////////// + +static Fl_Fontdesc built_in_table[] = { +{"Arial"}, +{"Arial Bold"}, +{"Arial Italic"}, +{"Arial Bold Italic"}, +{"Courier New"}, +{"Courier New Bold"}, +{"Courier New Italic"}, +{"Courier New Bold Italic"}, +{"Times New Roman"}, +{"Times New Roman Bold"}, +{"Times New Roman Italic"}, +{"Times New Roman Bold Italic"}, +{"Symbol"}, +{"Monaco"}, +{"Andale Mono"}, // there is no bold Monaco font on standard Mac +{"Webdings"}, +}; + +static UniChar *utfWbuf = 0; +static unsigned utfWlen = 0; + +static UniChar *mac_Utf8_to_Utf16(const char *txt, int len, int *new_len) +{ + unsigned wlen = fl_utf8toUtf16(txt, len, (unsigned short*)utfWbuf, utfWlen); + if(wlen >= utfWlen) + { + utfWlen = wlen + 100; + if(utfWbuf) free(utfWbuf); + utfWbuf = (UniChar*)malloc((utfWlen)*sizeof(UniChar)); + wlen = fl_utf8toUtf16(txt, len, (unsigned short*)utfWbuf, utfWlen); + } + *new_len = wlen; + return utfWbuf; +} // mac_Utf8_to_Utf16 + +Fl_Fontdesc* fl_fonts = built_in_table; + +void fl_font(Fl_Font_Descriptor* s) { + fl_fontsize = s; + // we will use fl_fontsize later to access the required style and layout +} + +static Fl_Font_Descriptor* find(Fl_Font fnum, Fl_Fontsize size) { + Fl_Fontdesc* s = fl_fonts+fnum; + if (!s->name) s = fl_fonts; // use 0 if fnum undefined + Fl_Font_Descriptor* f; + for (f = s->first; f; f = f->next) + if (f->minsize <= size && f->maxsize >= size) return f; + f = new Fl_Font_Descriptor(s->name, size); + f->next = s->first; + s->first = f; + return f; +} + +//////////////////////////////////////////////////////////////// +// Public interface: + +Fl_Font fl_font_ = 0; +Fl_Fontsize fl_size_ = 0; + + +void Fl_Graphics_Driver::font(Fl_Font fnum, Fl_Fontsize size) { + if (fnum==-1) { + fl_font_ = 0; + fl_size_ = 0; + return; + } + fl_font_ = fnum; + fl_size_ = size; + fl_font(find(fnum, size)); +} + +int fl_height() { + check_default_font(); + if (fl_fontsize) return fl_fontsize->ascent+fl_fontsize->descent; + else return -1; +} + +int fl_descent() { + check_default_font(); + if (fl_fontsize) + return fl_fontsize->descent+1; + else return -1; +} + +double fl_width(const UniChar* txt, int n) { + check_default_font(); + if (!fl_fontsize) { + check_default_font(); // avoid a crash! + if (!fl_fontsize) + return 8*n; // user must select a font first! + } +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 +if(fl_mac_os_version >= 0x1050) { + CTFontRef fontref = fl_fontsize->fontref; + CFStringRef str = CFStringCreateWithBytes(NULL, (const UInt8*)txt, n * sizeof(UniChar), kCFStringEncodingUTF16, false); + CFAttributedStringRef astr = CFAttributedStringCreate(NULL, str, NULL); + CFMutableAttributedStringRef mastr = CFAttributedStringCreateMutableCopy(NULL, 0, astr); + CFRelease(astr); + CFAttributedStringSetAttribute(mastr, CFRangeMake(0, CFStringGetLength(str)), kCTFontAttributeName, fontref); + CFRelease(str); + CTLineRef ctline = CTLineCreateWithAttributedString(mastr); + CFRelease(mastr); + double retval = CTLineGetTypographicBounds(ctline, NULL, NULL, NULL); + CFRelease(ctline); + return retval; + } +else { +#endif +#if ! __LP64__ + OSStatus err; + Fixed bBefore, bAfter, bAscent, bDescent; + ATSUTextLayout layout; + ByteCount iSize; + ATSUAttributeTag iTag; + ATSUAttributeValuePtr iValuePtr; + +// Here's my ATSU text measuring attempt... This seems to do the Right Thing + // now collect our ATSU resources and measure our text string + layout = fl_fontsize->layout; + // activate the current GC + iSize = sizeof(CGContextRef); + iTag = kATSUCGContextTag; + iValuePtr = &fl_gc; + ATSUSetLayoutControls(layout, 1, &iTag, &iSize, &iValuePtr); + // now measure the bounding box + err = ATSUSetTextPointerLocation(layout, txt, kATSUFromTextBeginning, n, n); + err = ATSUGetUnjustifiedBounds(layout, kATSUFromTextBeginning, n, &bBefore, &bAfter, &bAscent, &bDescent); + // If err is OK then return length, else return 0. Or something... + int len = FixedToInt(bAfter); + return len; +#endif +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + } +#endif + return 0; // FIXME: I do not understand the shuffeling of the above ifdef's and why they are here! +} + +double fl_width(const char* txt, int n) { + int wc_len = n; + UniChar *uniStr = mac_Utf8_to_Utf16(txt, n, &wc_len); + return fl_width(uniStr, wc_len); +} + +double fl_width(uchar c) { + return fl_width((const char*)(&c), 1); +} + +double fl_width(unsigned int wc) { + return fl_width((const UniChar*)(&wc), 1); +} + +// text extent calculation +void fl_text_extents(const UniChar* txt, int n, int &dx, int &dy, int &w, int &h) { + if (!fl_fontsize) { + check_default_font(); // avoid a crash! + if (!fl_fontsize) + w = int(8.0 * n); // user must select a font first! + h = int(8.0); + return; + } +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 +if(fl_mac_os_version >= 0x1050) { + CTFontRef fontref = fl_fontsize->fontref; + CFStringRef str16 = CFStringCreateWithBytes(NULL, (const UInt8*)txt, n *sizeof(UniChar), kCFStringEncodingUTF16, false); + CFAttributedStringRef astr = CFAttributedStringCreate(NULL, str16, NULL); + CFMutableAttributedStringRef mastr = CFAttributedStringCreateMutableCopy(NULL, 0, astr); + CFRelease(astr); + CFAttributedStringSetAttribute(mastr, CFRangeMake(0, CFStringGetLength(str16)), kCTFontAttributeName, fontref); + CFRelease(str16); + CTLineRef ctline = CTLineCreateWithAttributedString(mastr); + CFRelease(mastr); + CGContextSetTextPosition(fl_gc, 0, 0); + CGContextSetShouldAntialias(fl_gc, true); + CGRect rect = CTLineGetImageBounds(ctline, fl_gc); + CGContextSetShouldAntialias(fl_gc, false); + CFRelease(ctline); + dx = floor(rect.origin.x + 0.5); + dy = floor(- rect.origin.y - rect.size.height + 0.5); + w = rect.size.width + 0.5; + h = rect.size.height + 0.5; + } +else { +#endif +#if ! __LP64__ + OSStatus err; + ATSUTextLayout layout; + ByteCount iSize; + ATSUAttributeTag iTag; + ATSUAttributeValuePtr iValuePtr; + +// Here's my ATSU text measuring attempt... This seems to do the Right Thing + // now collect our ATSU resources and measure our text string + layout = fl_fontsize->layout; + // activate the current GC + iSize = sizeof(CGContextRef); + iTag = kATSUCGContextTag; + iValuePtr = &fl_gc; + ATSUSetLayoutControls(layout, 1, &iTag, &iSize, &iValuePtr); + // now measure the bounding box + err = ATSUSetTextPointerLocation(layout, txt, kATSUFromTextBeginning, n, n); + Rect bbox; + err = ATSUMeasureTextImage(layout, kATSUFromTextBeginning, n, 0, 0, &bbox); + w = bbox.right - bbox.left; + h = bbox.bottom - bbox.top; + dx = bbox.left; + dy = -bbox.bottom; +//printf("r: %d l: %d t: %d b: %d w: %d h: %d\n", bbox.right, bbox.left, bbox.top, bbox.bottom, w, h); +#endif +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + } +#endif + return; +} // fl_text_extents + +void fl_text_extents(const char *c, int n, int &dx, int &dy, int &w, int &h) { + int wc_len = n; + UniChar *uniStr = mac_Utf8_to_Utf16(c, n, &wc_len); + fl_text_extents(uniStr, wc_len, dx, dy, w, h); +} // fl_text_extents + + +void fl_draw(const char *str, int n, float x, float y); + +void Fl_Graphics_Driver::draw(const char* str, int n, int x, int y) { + fl_draw(str, n, (float)x-0.0f, (float)y+0.5f); +} + + +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 +static CGColorRef flcolortocgcolor(Fl_Color i) +{ + uchar r, g, b; + Fl::get_color(i, r, g, b); + CGFloat components[4] = {r/255.0f, g/255.0f, b/255.0f, 1.}; + static CGColorSpaceRef cspace = NULL; + if(cspace == NULL) { + cspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); + } + return CGColorCreate(cspace, components); +} +#endif + + +void fl_draw(const char *str, int n, float x, float y) { + + if(fl_graphics_driver->type() != Fl_Quartz_Graphics_Driver::device_type) { + fl_graphics_driver->draw(str, n, (int)x, (int)y ); + return; + } + // avoid a crash if no font has been selected by user yet ! + check_default_font(); + // convert to UTF-16 first + UniChar *uniStr = mac_Utf8_to_Utf16(str, n, &n); +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + if(fl_mac_os_version >= 0x1050) { + CFStringRef keys[2]; + CFTypeRef values[2]; + CFStringRef str16 = CFStringCreateWithBytes(NULL, (const UInt8*)uniStr, n * sizeof(UniChar), kCFStringEncodingUTF16, false); + CGColorRef color = flcolortocgcolor(fl_color()); + keys[0] = kCTFontAttributeName; + keys[1] = kCTForegroundColorAttributeName; + values[0] = fl_fontsize->fontref; + values[1] = color; + CFDictionaryRef attributes = CFDictionaryCreate(kCFAllocatorDefault, + (const void**)&keys, + (const void**)&values, + 2, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + CFAttributedStringRef mastr = CFAttributedStringCreate(kCFAllocatorDefault, str16, attributes); + CFRelease(str16); + CFRelease(attributes); + CFRelease(color); + CTLineRef ctline = CTLineCreateWithAttributedString(mastr); + CFRelease(mastr); + CGContextSetTextMatrix(fl_gc, font_mx); + CGContextSetTextPosition(fl_gc, x, y); + CGContextSetShouldAntialias(fl_gc, true); + CTLineDraw(ctline, fl_gc); + CGContextSetShouldAntialias(fl_gc, false); + CFRelease(ctline); + } + else { +#endif +#if ! __LP64__ + OSStatus err; + // now collect our ATSU resources + ATSUTextLayout layout = fl_fontsize->layout; + + ByteCount iSize = sizeof(CGContextRef); + ATSUAttributeTag iTag = kATSUCGContextTag; + ATSUAttributeValuePtr iValuePtr=&fl_gc; + ATSUSetLayoutControls(layout, 1, &iTag, &iSize, &iValuePtr); + + err = ATSUSetTextPointerLocation(layout, uniStr, kATSUFromTextBeginning, n, n); + CGContextSetShouldAntialias(fl_gc, true); + err = ATSUDrawText(layout, kATSUFromTextBeginning, n, FloatToFixed(x), FloatToFixed(y)); + CGContextSetShouldAntialias(fl_gc, false); +#endif +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + } +#endif +} + +void Fl_Graphics_Driver::draw(int angle, const char *str, int n, int x, int y) { + CGContextSaveGState(fl_gc); + CGContextTranslateCTM(fl_gc, x, y); + CGContextRotateCTM(fl_gc, - angle*(M_PI/180) ); + fl_draw(str, n, (float)0., (float)0.); + CGContextRestoreGState(fl_gc); +} + +void Fl_Graphics_Driver::rtl_draw(const char* c, int n, int x, int y) { + draw(c, n, int(x - fl_width(c, n)), y); +} + +// +// End of "$Id: fl_font_mac.cxx 7892 2010-11-25 18:21:21Z manolo $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_font_win32.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_font_win32.cxx new file mode 100644 index 0000000..81a7c01 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_font_win32.cxx @@ -0,0 +1,421 @@ +// +// "$Id: fl_font_win32.cxx 7652 2010-06-21 15:49:45Z manolo $" +// +// WIN32 font selection routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2009 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include + +static int fl_angle_ = 0; + +#ifndef FL_DOXYGEN +Fl_Font_Descriptor::Fl_Font_Descriptor(const char* name, Fl_Fontsize size) { + int weight = FW_NORMAL; + int italic = 0; + switch (*name++) { + case 'I': italic = 1; break; + case 'P': italic = 1; + case 'B': weight = FW_BOLD; break; + case ' ': break; + default: name--; + } + fid = CreateFont( + -size, // negative makes it use "char size" + 0, // logical average character width + fl_angle_*10, // angle of escapement + fl_angle_*10, // base-line orientation angle + weight, + italic, + FALSE, // underline attribute flag + FALSE, // strikeout attribute flag + DEFAULT_CHARSET, // character set identifier + OUT_DEFAULT_PRECIS, // output precision + CLIP_DEFAULT_PRECIS,// clipping precision + DEFAULT_QUALITY, // output quality + DEFAULT_PITCH, // pitch and family + name // pointer to typeface name string + ); + angle = fl_angle_; + if (!fl_gc) fl_GetDC(0); + SelectObject(fl_gc, fid); + GetTextMetrics(fl_gc, &metr); +// BOOL ret = GetCharWidthFloat(fl_gc, metr.tmFirstChar, metr.tmLastChar, font->width+metr.tmFirstChar); +// ...would be the right call, but is not implemented into Window95! (WinNT?) + //GetCharWidth(fl_gc, 0, 255, width); + int i; + for (i = 0; i < 64; i++) width[i] = NULL; +#if HAVE_GL + listbase = 0; + for (i = 0; i < 64; i++) glok[i] = 0; +#endif + minsize = maxsize = size; +} + +Fl_Font_Descriptor* fl_fontsize; + +Fl_Font_Descriptor::~Fl_Font_Descriptor() { +#if HAVE_GL +// Delete list created by gl_draw(). This is not done by this code +// as it will link in GL unnecessarily. There should be some kind +// of "free" routine pointer, or a subclass? +// if (listbase) { +// int base = font->min_char_or_byte2; +// int size = font->max_char_or_byte2-base+1; +// int base = 0; int size = 256; +// glDeleteLists(listbase+base,size); +// } +#endif + if (this == fl_fontsize) fl_fontsize = 0; + DeleteObject(fid); + int i; + for (i = 0; i < 64; i++) free(width[i]); +} + +//////////////////////////////////////////////////////////////// + +// WARNING: if you add to this table, you must redefine FL_FREE_FONT +// in Enumerations.H & recompile!! +static Fl_Fontdesc built_in_table[] = { +{" Arial"}, +{"BArial"}, +{"IArial"}, +{"PArial"}, +{" Courier New"}, +{"BCourier New"}, +{"ICourier New"}, +{"PCourier New"}, +{" Times New Roman"}, +{"BTimes New Roman"}, +{"ITimes New Roman"}, +{"PTimes New Roman"}, +{" Symbol"}, +{" Terminal"}, +{"BTerminal"}, +{" Wingdings"}, +}; + +Fl_Fontdesc* fl_fonts = built_in_table; + +static Fl_Font_Descriptor* find(Fl_Font fnum, Fl_Fontsize size, int angle) { + Fl_Fontdesc* s = fl_fonts+fnum; + if (!s->name) s = fl_fonts; // use 0 if fnum undefined + Fl_Font_Descriptor* f; + for (f = s->first; f; f = f->next) + if (f->minsize <= size && f->maxsize >= size && f->angle == angle) return f; + f = new Fl_Font_Descriptor(s->name, size); + f->next = s->first; + s->first = f; + return f; +} + +//////////////////////////////////////////////////////////////// +// Public interface: + +Fl_Font fl_font_ = 0; +Fl_Fontsize fl_size_ = 0; +//static HDC font_gc; + +void fl_font(Fl_Font fnum, Fl_Fontsize size, int angle) { + if (fnum==-1) { // just make sure that we will load a new font next time + fl_font_ = 0; fl_size_ = 0; fl_angle_ = 0; + return; + } + if (fnum == fl_font_ && size == fl_size_ && angle == fl_angle_) return; + fl_font_ = fnum; fl_size_ = size; fl_angle_ = angle; + fl_fontsize = find(fnum, size, angle); +} + +void Fl_Graphics_Driver::font(Fl_Font fnum, Fl_Fontsize size) { + fl_font(fnum, size, 0); +} + +int fl_height() { + if (fl_fontsize) return (fl_fontsize->metr.tmAscent + fl_fontsize->metr.tmDescent); + else return -1; +} + +int fl_descent() { + if (fl_fontsize) return fl_fontsize->metr.tmDescent; + else return -1; +} + +// Unicode string buffer +static xchar *wstr = NULL; +static int wstr_len = 0; + + +double fl_width(const char* c, int n) { + int i = 0; + if (!fl_fontsize) return -1.0; + double w = 0.0; + char *end = (char *)&c[n]; + while (i < n) { + unsigned int ucs; +// int l = fl_utf2ucs((const unsigned char*)c + i, n - i, &ucs); + int l; + ucs = fl_utf8decode((const char*)(c + i), end, &l); +// if (l < 1) l = 1; + i += l; + if (!fl_nonspacing(ucs)) { + w += fl_width(ucs); + } + } + return w; +} + +double fl_width(unsigned int c) { + unsigned int r; + r = (c & 0xFC00) >> 10; + if (!fl_fontsize->width[r]) { + SelectObject(fl_gc, fl_fontsize->fid); + fl_fontsize->width[r] = (int*) malloc(sizeof(int) * 0x0400); + SIZE s; + unsigned short i = 0, ii = r * 0x400; + // The following code makes a best effort attempt to obtain a valid fl_gc. + // If no fl_gc is available at the time we call fl_width(), then we first + // try to obtain a gc from the first fltk window. + // If that is null then we attempt to obtain the gc from the current screen + // using (GetDC(NULL)). + // This should resolve STR #2086 + HDC gc = fl_gc; + HWND hWnd = 0; + if (!gc) { // We have no valid gc, try and obtain one + // Use our first fltk window, or fallback to using the screen via GetDC(NULL) + hWnd = Fl::first_window() ? fl_xid(Fl::first_window()) : NULL; + gc = GetDC(hWnd); + } + if (!gc) + Fl::fatal("Invalid graphic context: fl_width() failed because no valid HDC was found!"); + for (; i < 0x400; i++) { + GetTextExtentPoint32W(gc, (WCHAR*)&ii, 1, &s); + fl_fontsize->width[r][i] = s.cx; + ii++; + } + if (gc && gc!=fl_gc) ReleaseDC(hWnd, gc); + } + return (double) fl_fontsize->width[r][c & 0x03FF]; +} + +/* Add function pointer to allow us to access GetGlyphIndicesW on systems that have it, + * without crashing on systems that do not. */ +/* DWORD WINAPI GetGlyphIndicesW(HDC,LPCWSTR,int,LPWORD,DWORD) */ +typedef DWORD (WINAPI* fl_GetGlyphIndices_func)(HDC,LPCWSTR,int,LPWORD,DWORD); + +static fl_GetGlyphIndices_func fl_GetGlyphIndices = NULL; // used to hold a proc pointer for GetGlyphIndicesW +static int have_loaded_GetGlyphIndices = 0; // Set this non-zero once we have tried to load GetGlyphIndices + +// Function that tries to dynamically load GetGlyphIndicesW at runtime +static void GetGlyphIndices_init() { + // Since not all versions of Windows include GetGlyphIndicesW support, + // we do a run-time check for the required function. + HMODULE hMod = GetModuleHandle("GDI32.DLL"); + if (hMod) { + // check that GetGlyphIndicesW is available + fl_GetGlyphIndices = (fl_GetGlyphIndices_func)GetProcAddress(hMod, "GetGlyphIndicesW"); + } + have_loaded_GetGlyphIndices = -1; // set this non-zero when we have attempted to load GetGlyphIndicesW +} // GetGlyphIndices_init function + +static void on_printer_extents_update(int &dx, int &dy, int &w, int &h) +// converts text extents from device coords to logical coords +{ + POINT pt[3] = { {0, 0}, {dx, dy}, {dx+w, dy+h} }; + DPtoLP(fl_gc, pt, 3); + w = pt[2].x - pt[1].x; + h = pt[2].y - pt[1].y; + dx = pt[1].x - pt[0].x; + dy = pt[1].y - pt[0].y; +} + +// if printer context, extents shd be converted to logical coords +#define EXTENTS_UPDATE(x,y,w,h) \ + if (Fl_Surface_Device::surface()->type() == Fl_Printer::device_type) { on_printer_extents_update(x,y,w,h); } + +static unsigned short *ext_buff = NULL; // UTF-16 converted version of input UTF-8 string +static unsigned wc_len = 0; // current string buffer dimension +static WORD *gi = NULL; // glyph indices array +// Function to determine the extent of the "inked" area of the glyphs in a string +void fl_text_extents(const char *c, int n, int &dx, int &dy, int &w, int &h) { + if (!fl_fontsize) { + w = 0; h = 0; + dx = dy = 0; + return; + } + static const MAT2 matrix = { { 0, 1 }, { 0, 0 }, { 0, 0 }, { 0, 1 } }; + GLYPHMETRICS metrics; + int maxw = 0, maxh = 0, dh; + int minx = 0, miny = -999999; + unsigned len = 0, idx = 0; + HWND hWnd = 0; + + // Have we loaded the GetGlyphIndicesW function yet? + if (have_loaded_GetGlyphIndices == 0) { + GetGlyphIndices_init(); + } + // Do we have a usable GetGlyphIndices function? + if(!fl_GetGlyphIndices) goto exit_error; // No GetGlyphIndices function, use fallback mechanism instead + + // The following code makes a best effort attempt to obtain a valid fl_gc. + // See description in fl_width() above for an explanation. + if (!fl_gc) { // We have no valid gc, try and obtain one + // Use our first fltk window, or fallback to using the screen via GetDC(NULL) + hWnd = Fl::first_window() ? fl_xid(Fl::first_window()) : NULL; + fl_gc = GetDC(hWnd); + } + if (!fl_gc)goto exit_error; // no valid gc, attempt to use fallback measure + + // now convert the string to WCHAR and measure it + len = fl_utf8toUtf16(c, n, ext_buff, wc_len); + if(len >= wc_len) { + if(ext_buff) {delete [] ext_buff;} + if(gi) {delete [] gi;} + wc_len = len + 64; + ext_buff = new unsigned short[wc_len]; + gi = new WORD[wc_len]; + len = fl_utf8toUtf16(c, n, ext_buff, wc_len); + } + SelectObject(fl_gc, fl_fontsize->fid); + + if (fl_GetGlyphIndices(fl_gc, (WCHAR*)ext_buff, len, gi, 0) == GDI_ERROR) { + // some error occured here - just return fl_measure values? + goto exit_error; + } + + // now we have the glyph array we measure each glyph in turn... + for(idx = 0; idx < len; idx++){ + if (GetGlyphOutlineW (fl_gc, gi[idx], GGO_METRICS | GGO_GLYPH_INDEX, + &metrics, 0, NULL, &matrix) == GDI_ERROR) { + goto exit_error; + } + maxw += metrics.gmCellIncX; + if(idx == 0) minx = metrics.gmptGlyphOrigin.x; + dh = metrics.gmBlackBoxY - metrics.gmptGlyphOrigin.y; + if(dh > maxh) maxh = dh; + if(miny < metrics.gmptGlyphOrigin.y) miny = metrics.gmptGlyphOrigin.y; + } + + // for the last cell, we only want the bounding X-extent, not the glyphs increment step + maxw = maxw - metrics.gmCellIncX + metrics.gmBlackBoxX + metrics.gmptGlyphOrigin.x; + w = maxw - minx; + h = maxh + miny; + dx = minx; + dy = -miny; + EXTENTS_UPDATE(dx, dy, w, h); + return; // normal exit + +exit_error: + // some error here - just return fl_measure values + w = (int)fl_width(c, n); + h = fl_height(); + dx = 0; + dy = fl_descent() - h; + EXTENTS_UPDATE(dx, dy, w, h); + return; +} // fl_text_extents + +void Fl_Graphics_Driver::draw(const char* str, int n, int x, int y) { + int i = 0; + int lx = 0; + char *end = (char *)&str[n]; + COLORREF oldColor = SetTextColor(fl_gc, fl_RGB()); + SelectObject(fl_gc, fl_fontsize->fid); + while (i < n) { + unsigned int u; + unsigned int u1; + unsigned short ucs; +// int l = fl_utf2ucs((const unsigned char*)str + i, n - i, &u); + int l; + u = fl_utf8decode((const char*)(str + i), end, &l); + if (u1 = fl_nonspacing(u)) { + x -= lx; + u = u1; + } else { + lx = (int) fl_width(u); + } + ucs = u; + if (l < 1) l = 1; + i += l; + TextOutW(fl_gc, x, y, (WCHAR*)&ucs, 1); + x += lx; + } + SetTextColor(fl_gc, oldColor); +} + +void Fl_Graphics_Driver::draw(int angle, const char* str, int n, int x, int y) { + fl_font(fl_font_, fl_size_, angle); +// fl_draw(str, n, (int)x, (int)y); + int i = 0, i2=0; + char *end = (char *)&str[n]; + COLORREF oldColor = SetTextColor(fl_gc, fl_RGB()); + SelectObject(fl_gc, fl_fontsize->fid); + //unsigned short ucs[n]; //only GCC, but not MSVC + unsigned short* ucs = new unsigned short[n]; + while (i < n) { + unsigned int u; + int l; + u = fl_utf8decode((const char*)(str + i), end, &l); + ucs[i2] = u; + if (l < 1) l = 1; + i += l; + ++i2; + } + TextOutW(fl_gc, x, y, (WCHAR*)ucs, i2); + delete[] ucs; + SetTextColor(fl_gc, oldColor); + fl_font(fl_font_, fl_size_); +} + +void Fl_Graphics_Driver::rtl_draw(const char* c, int n, int x, int y) { + int wn; + int i = 0; + int lx = 0; +// if (n > wstr_len) { +// wstr = (xchar*) realloc(wstr, sizeof(xchar) * (n + 1)); +// wstr_len = n; +// } +//wn = fl_utf2unicode((const unsigned char *)c, n, wstr); + wn = fl_utf8toUtf16(c, n, (unsigned short*)wstr, wstr_len); + if(wn >= wstr_len) { + wstr = (xchar*) realloc(wstr, sizeof(xchar) * (wn + 1)); + wstr_len = wn + 1; + wn = fl_utf8toUtf16(c, n, (unsigned short*)wstr, wstr_len); + } + + COLORREF oldColor = SetTextColor(fl_gc, fl_RGB()); + SelectObject(fl_gc, fl_fontsize->fid); + while (i < wn) { + lx = (int) fl_width(wstr[i]); + x -= lx; + TextOutW(fl_gc, x, y, (WCHAR*)wstr + i, 1); + if (fl_nonspacing(wstr[i])) { + x += lx; + } + i++; + } + SetTextColor(fl_gc, oldColor); +} +#endif +// +// End of "$Id: fl_font_win32.cxx 7652 2010-06-21 15:49:45Z manolo $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_font_x.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_font_x.cxx new file mode 100644 index 0000000..52f30a3 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_font_x.cxx @@ -0,0 +1,348 @@ +// +// "$Id: fl_font_x.cxx 7652 2010-06-21 15:49:45Z manolo $" +// +// Standard X11 font selection code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2009 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// +#ifndef FL_DOXYGEN + +Fl_Font_Descriptor::Fl_Font_Descriptor(const char* name) { + font = XCreateUtf8FontStruct(fl_display, name); + if (!font) { + Fl::warning("bad font: %s", name); + font = XCreateUtf8FontStruct(fl_display, "fixed"); + } +# if HAVE_GL + listbase = 0; + for (int u = 0; u < 64; u++) glok[u] = 0; +# endif +} + +Fl_Font_Descriptor* fl_fontsize; +Fl_XFont_On_Demand fl_xfont; + +Fl_Font_Descriptor::~Fl_Font_Descriptor() { +# if HAVE_GL +// Delete list created by gl_draw(). This is not done by this code +// as it will link in GL unnecessarily. There should be some kind +// of "free" routine pointer, or a subclass? +// if (listbase) { +// int base = font->min_char_or_byte2; +// int size = font->max_char_or_byte2-base+1; +// int base = 0; int size = 256; +// glDeleteLists(listbase+base,size); +// } +# endif + if (this == fl_fontsize) { + fl_fontsize = 0; + fl_xfont = 0; + } + XFreeUtf8FontStruct(fl_display, font); +} + +//////////////////////////////////////////////////////////////// + +// WARNING: if you add to this table, you must redefine FL_FREE_FONT +// in Enumerations.H & recompile!! +static Fl_Fontdesc built_in_table[] = { +{"-*-helvetica-medium-r-normal--*"}, +{"-*-helvetica-bold-r-normal--*"}, +{"-*-helvetica-medium-o-normal--*"}, +{"-*-helvetica-bold-o-normal--*"}, +{"-*-courier-medium-r-normal--*"}, +{"-*-courier-bold-r-normal--*"}, +{"-*-courier-medium-o-normal--*"}, +{"-*-courier-bold-o-normal--*"}, +{"-*-times-medium-r-normal--*"}, +{"-*-times-bold-r-normal--*"}, +{"-*-times-medium-i-normal--*"}, +{"-*-times-bold-i-normal--*"}, +{"-*-symbol-*"}, +{"-*-lucidatypewriter-medium-r-normal-sans-*"}, +{"-*-lucidatypewriter-bold-r-normal-sans-*"}, +{"-*-*zapf dingbats-*"} +}; + +Fl_Fontdesc* fl_fonts = built_in_table; + +#define MAXSIZE 32767 + +#define current_font (fl_fontsize->font) + +// return dash number N, or pointer to ending null if none: +const char* fl_font_word(const char* p, int n) { + while (*p) {if (*p=='-') {if (!--n) break;} p++;} + return p; +} + +// return a pointer to a number we think is "point size": +char* fl_find_fontsize(char* name) { + char* c = name; + // for standard x font names, try after 7th dash: + if (*c == '-') { + c = (char*)fl_font_word(c,7); + if (*c++ && isdigit(*c)) return c; + return 0; // malformed x font name? + } + char* r = 0; + // find last set of digits: + for (c++;* c; c++) + if (isdigit(*c) && !isdigit(*(c-1))) r = c; + return r; +} + +const char* fl_encoding = "iso8859-1"; + +// return true if this matches fl_encoding: +int fl_correct_encoding(const char* name) { + if (*name != '-') return 0; + const char* c = fl_font_word(name,13); + return (*c++ && !strcmp(c,fl_encoding)); +} + +static const char *find_best_font(const char *fname, int size) { + int cnt; + static char **list = NULL; +// locate or create an Fl_Font_Descriptor for a given Fl_Fontdesc and size: + if (list) XFreeFontNames(list); + list = XListFonts(fl_display, fname, 100, &cnt); + if (!list) return "fixed"; + + // search for largest <= font size: + char* name = list[0]; int ptsize = 0; // best one found so far + int matchedlength = 32767; + char namebuffer[1024]; // holds scalable font name + int found_encoding = 0; + int m = cnt; if (m<0) m = -m; + for (int n=0; n < m; n++) { + char* thisname = list[n]; + if (fl_correct_encoding(thisname)) { + if (!found_encoding) ptsize = 0; // force it to choose this + found_encoding = 1; + } else { + if (found_encoding) continue; + } + char* c = (char*)fl_find_fontsize(thisname); + int thissize = c ? atoi(c) : MAXSIZE; + int thislength = strlen(thisname); + if (thissize == size && thislength < matchedlength) { + // exact match, use it: + name = thisname; + ptsize = size; + matchedlength = thislength; + } else if (!thissize && ptsize!=size) { + // whoa! A scalable font! Use unless exact match found: + int l = c-thisname; + memcpy(namebuffer,thisname,l); + l += sprintf(namebuffer+l,"%d",size); + while (*c == '0') c++; + strcpy(namebuffer+l,c); + name = namebuffer; + ptsize = size; + } else if (!ptsize || // no fonts yet + thissize < ptsize && ptsize > size || // current font too big + thissize > ptsize && thissize <= size // current too small + ) { + name = thisname; + ptsize = thissize; + matchedlength = thislength; + } + } + +// if (ptsize != size) { // see if we already found this unscalable font: +// for (f = s->first; f; f = f->next) { +// if (f->minsize <= ptsize && f->maxsize >= ptsize) { +// if (f->minsize > size) f->minsize = size; +// if (f->maxsize < size) f->maxsize = size; +// return f; +// } +// } +// } +// +// // okay, we definately have some name, make the font: +// f = new Fl_Font_Descriptor(name); +// if (ptsize < size) {f->minsize = ptsize; f->maxsize = size;} +// else {f->minsize = size; f->maxsize = ptsize;} +// f->next = s->first; +// s->first = f; +// return f; + + return name; +} + +static char *put_font_size(const char *n, int size) +{ + int i = 0; + char *buf; + const char *ptr; + const char *f; + char *name; + int nbf = 1; + name = strdup(n); + while (name[i]) { + if (name[i] == ',') {nbf++; name[i] = '\0';} + i++; + } + + buf = (char*) malloc(nbf * 256); + buf[0] = '\0'; + ptr = name; + i = 0; + while (ptr && nbf > 0) { + f = find_best_font(ptr, size); + while (*f) { + buf[i] = *f; + f++; i++; + } + nbf--; + while (*ptr) ptr++; + if (nbf) { + ptr++; + buf[i] = ','; + i++; + } + while(isspace(*ptr)) ptr++; + } + buf[i] = '\0'; + free(name); + return buf; +} + + +char *fl_get_font_xfld(int fnum, int size) { + Fl_Fontdesc* s = fl_fonts+fnum; + if (!s->name) s = fl_fonts; // use font 0 if still undefined + fl_open_display(); + return put_font_size(s->name, size); +} + +// locate or create an Fl_Font_Descriptor for a given Fl_Fontdesc and size: +static Fl_Font_Descriptor* find(int fnum, int size) { + char *name; + Fl_Fontdesc* s = fl_fonts+fnum; + if (!s->name) s = fl_fonts; // use font 0 if still undefined + Fl_Font_Descriptor* f; + for (f = s->first; f; f = f->next) + if (f->minsize <= size && f->maxsize >= size) return f; + fl_open_display(); + + name = put_font_size(s->name, size); + f = new Fl_Font_Descriptor(name); + f->minsize = size; + f->maxsize = size; + f->next = s->first; + s->first = f; + free(name); + return f; +} + + +//////////////////////////////////////////////////////////////// +// Public interface: + +Fl_Font fl_font_ = 0; +Fl_Fontsize fl_size_ = 0; +void *fl_xftfont = 0; +static GC font_gc; + +XFontStruct* Fl_XFont_On_Demand::value() { + return ptr; +} + +void Fl_Graphics_Driver::font(Fl_Font fnum, Fl_Fontsize size) { + if (fnum==-1) { + fl_font_ = 0; fl_size_ = 0; + return; + } + if (fnum == fl_font_ && size == fl_size_) return; + fl_font_ = fnum; fl_size_ = size; + Fl_Font_Descriptor* f = find(fnum, size); + if (f != fl_fontsize) { + fl_fontsize = f; + fl_xfont = current_font->fonts[0]; + font_gc = 0; + } +} + +int fl_height() { + if (current_font) return (current_font->ascent + current_font->descent); + else return -1; +} + +int fl_descent() { + if (current_font) return current_font->descent; + else return -1; +} + +double fl_width(const char* c, int n) { + if (current_font) return (double) XUtf8TextWidth(current_font, c, n); + else return -1; +} + +double fl_width(unsigned int c) { + if (current_font) return (double) XUtf8UcsWidth(current_font, c); + else return -1; +} + + +void fl_text_extents(const char *c, int n, int &dx, int &dy, int &W, int &H) { + +#if defined(__GNUC__) +#warning fl_text_extents is only a test stub in Xlib build at present +#endif /*__GNUC__*/ + + W = 0; H = 0; + fl_measure(c, W, H, 0); + dx = 0; + dy = fl_descent() - H; +} // fl_text_extents + + +void Fl_Graphics_Driver::draw(const char* c, int n, int x, int y) { + if (font_gc != fl_gc) { + if (!current_font) fl_font(FL_HELVETICA, 14); + font_gc = fl_gc; + XSetFont(fl_display, fl_gc, current_font->fid); + } +// XDrawString(fl_display, fl_window, fl_gc, x, y, c, n); + XUtf8DrawString(fl_display, fl_window, current_font, fl_gc, x, y, c, n); +} +void Fl_Graphics_Driver::draw(int angle, const char *str, int n, int x, int y) { + fprintf(stderr,"ROTATING TEXT NOT IMPLIMENTED\n"); + fl_draw(str, n, (int)x, (int)y); +} +//void fl_draw(const char* str, int n, float x, float y) { +// fl_draw(str, n, (int)x, (int)y); +//} + +void Fl_Graphics_Driver::rtl_draw(const char* c, int n, int x, int y) { + if (font_gc != fl_gc) { + if (!current_font) fl_font(FL_HELVETICA, 12); + font_gc = fl_gc; + } + XUtf8DrawRtlString(fl_display, fl_window, current_font, fl_gc, x, y, c, n); +} +#endif // FL_DOXYGEN +// +// End of "$Id: fl_font_x.cxx 7652 2010-06-21 15:49:45Z manolo $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_font_xft.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_font_xft.cxx new file mode 100644 index 0000000..4e118fb --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_font_xft.cxx @@ -0,0 +1,678 @@ +// +// "$Id: fl_font_xft.cxx 7855 2010-11-15 22:13:13Z matt $" +// +// Xft font code for the Fast Light Tool Kit (FLTK). +// +// Copyright 2001-2009 Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// +// Draw fonts using Keith Packard's Xft library to provide anti- +// aliased text. Yow! +// +// Many thanks to Carl for making the original version of this. +// +// This font code only requires libXft to work. Contrary to popular +// belief there is no need to have FreeType, or the Xrender extension +// available to use this code. You will just get normal Xlib fonts +// (Xft calls them "core" fonts) The Xft algorithms for choosing +// these is about as good as the FLTK ones (I hope to fix it so it is +// exactly as good...), plus it can cache its results and share them +// between programs, so using this should be a win in all cases. Also +// it should be obvious by comparing this file and fl_font_x.cxx that +// it is a lot easier to program with Xft than with Xlib. +// +// Also, Xft supports UTF-8 text rendering directly, which will allow +// us to support UTF-8 on all platforms more easily. +// +// To actually get antialiasing you need the following: +// +// 1. You have XFree86 4 +// 2. You have the XRender extension +// 3. Your X device driver supports the render extension +// 4. You have libXft +// 5. Your libXft has FreeType2 support compiled in +// 6. You have the FreeType2 library +// +// Distributions that have XFree86 4.0.3 or later should have all of this... +// +// Unlike some other Xft packages, I tried to keep this simple and not +// to work around the current problems in Xft by making the "patterns" +// complicated. I believe doing this defeats our ability to improve Xft +// itself. You should edit the ~/.xftconfig file to "fix" things, there +// are several web pages of information on how to do this. +// +#ifndef FL_DOXYGEN + +#include + +#include + +// The predefined fonts that FLTK has: +static Fl_Fontdesc built_in_table[] = { +#if 1 +{" sans"}, +{"Bsans"}, +{"Isans"}, +{"Psans"}, +{" mono"}, +{"Bmono"}, +{"Imono"}, +{"Pmono"}, +{" serif"}, +{"Bserif"}, +{"Iserif"}, +{"Pserif"}, +{" symbol"}, +{" screen"}, +{"Bscreen"}, +{" zapf dingbats"}, +#else +{" helvetica"}, +{"Bhelvetica"}, +{"Ihelvetica"}, +{"Phelvetica"}, +{" courier"}, +{"Bcourier"}, +{"Icourier"}, +{"Pcourier"}, +{" times"}, +{"Btimes"}, +{"Itimes"}, +{"Ptimes"}, +{" symbol"}, +{" lucidatypewriter"}, +{"Blucidatypewriter"}, +{" zapf dingbats"}, +#endif +}; + +Fl_Fontdesc* fl_fonts = built_in_table; + +#define current_font (fl_fontsize->font) + +Fl_Font fl_font_ = 0; +Fl_Fontsize fl_size_ = 0; +int fl_angle_ = 0; // internal for rotating text support +Fl_XFont_On_Demand fl_xfont; +void *fl_xftfont = 0; +//const char* fl_encoding_ = "iso8859-1"; +const char* fl_encoding_ = "iso10646-1"; +Fl_Font_Descriptor* fl_fontsize = 0; + + + +void fl_font(Fl_Font fnum, Fl_Fontsize size, int angle) { + if (fnum==-1) { // special case to stop font caching + fl_font_ = 0; fl_size_ = 0; fl_angle_ = 0; + return; + } + if (fnum == fl_font_ && size == fl_size_ && angle == fl_angle_ + && fl_fontsize) +// && !strcasecmp(fl_fontsize->encoding, fl_encoding_)) + return; + fl_font_ = fnum; fl_size_ = size; fl_angle_ = angle; + Fl_Fontdesc *font = fl_fonts + fnum; + Fl_Font_Descriptor* f; + // search the fontsizes we have generated already + for (f = font->first; f; f = f->next) { + if (f->size == size && f->angle == angle)// && !strcasecmp(f->encoding, fl_encoding_)) + break; + } + if (!f) { + f = new Fl_Font_Descriptor(font->name); + f->next = font->first; + font->first = f; + } + fl_fontsize = f; +#if XFT_MAJOR < 2 + fl_xfont = f->font->u.core.font; +#else + fl_xfont = NULL; // invalidate +#endif // XFT_MAJOR < 2 + fl_xftfont = (void*)f->font; +} + +void Fl_Graphics_Driver::font(Fl_Font fnum, Fl_Fontsize size) { + fl_font(fnum,size,0); +} + +static XftFont* fontopen(const char* name, bool core, int angle) { + // Check: does it look like we have been passed an old-school XLFD fontname? + bool is_xlfd = false; + int hyphen_count = 0; + int comma_count = 0; + unsigned len = strlen(name); + if (len > 512) len = 512; // ensure we are not passed an unbounded font name + for(unsigned idx = 0; idx < len; idx++) { + if(name[idx] == '-') hyphen_count++; // check for XLFD hyphens + if(name[idx] == ',') comma_count++; // are there multiple names? + } + if(hyphen_count >= 14) is_xlfd = true; // Not a robust check, but good enough? + + fl_open_display(); + + if(!is_xlfd) { // Not an XLFD - open as a XFT style name + XftFont *the_font; // the font we will return; + XftPattern *fnt_pat = XftPatternCreate(); // the pattern we will use for matching + int slant = XFT_SLANT_ROMAN; + int weight = XFT_WEIGHT_MEDIUM; + + /* This "converts" FLTK-style font names back into "regular" names, extracting + * the BOLD and ITALIC codes as it does so - all FLTK font names are prefixed + * by 'I' (italic) 'B' (bold) 'P' (bold italic) or ' ' (regular) modifiers. + * This gives a fairly limited font selection ability, but is retained for + * compatibility reasons. If you really need a more complex choice, you are best + * calling Fl::set_fonts(*) then selecting the font by font-index rather than by + * name anyway. Probably. + * If you want to load a font who's name does actually begin with I, B or P, you + * MUST use a leading space OR simply use lowercase for the name... + */ + /* This may be efficient, but it is non-obvious. */ + switch (*name++) { + case 'I': slant = XFT_SLANT_ITALIC; break; // italic + case 'P': slant = XFT_SLANT_ITALIC; // bold-italic (falls-through) + case 'B': weight = XFT_WEIGHT_BOLD; break; // bold + case ' ': break; // regular + default: name--; // no prefix, restore name + } + + if(comma_count) { // multiple comma-separated names were passed + char *local_name = strdup(name); // duplicate the full name so we can edit the copy + char *curr = local_name; // points to first name in string + char *nxt; // next name in string + do { + nxt = strchr(curr, ','); // find comma separator + if (nxt) { + *nxt = 0; // terminate first name + nxt++; // first char of next name + } + + // Add the current name to the match pattern + XftPatternAddString(fnt_pat, XFT_FAMILY, curr); + + if(nxt) curr = nxt; // move onto next name (if it exists) + // Now do a cut-down version of the FLTK name conversion. + // NOTE: we only use the slant and weight of the first name, + // subsequent names we ignore this for... But we still need to do the check. + switch (*curr++) { + case 'I': break; // italic + case 'P': // bold-italic (falls-through) + case 'B': break; // bold + case ' ': break; // regular + default: curr--; // no prefix, restore name + } + + comma_count--; // decrement name sections count + } while (comma_count >= 0); + free(local_name); // release our local copy of font names + } + else { // single name was passed - add it directly + XftPatternAddString(fnt_pat, XFT_FAMILY, name); + } + + // Construct a match pattern for the font we want... + XftPatternAddInteger(fnt_pat, XFT_WEIGHT, weight); + XftPatternAddInteger(fnt_pat, XFT_SLANT, slant); + XftPatternAddDouble (fnt_pat, XFT_PIXEL_SIZE, (double)fl_size_); + XftPatternAddString (fnt_pat, XFT_ENCODING, fl_encoding_); + + // rotate font if fl_angle_!=0 + if (fl_angle_ !=0) { + XftMatrix m; + XftMatrixInit(&m); + XftMatrixRotate(&m,cos(M_PI*fl_angle_/180.),sin(M_PI*fl_angle_/180.)); + XftPatternAddMatrix (fnt_pat, XFT_MATRIX,&m); + } + + if (core) { + XftPatternAddBool(fnt_pat, XFT_CORE, FcTrue); + XftPatternAddBool(fnt_pat, XFT_RENDER, FcFalse); + } + + XftPattern *match_pat; // the best available match on the system + XftResult match_result; // the result of our matching attempt + + // query the system to find a match for this font + match_pat = XftFontMatch(fl_display, fl_screen, fnt_pat, &match_result); + +#if 0 // the XftResult never seems to get set to anything... abandon this code? + switch(match_result) { // how good a match is this font for our request? + case XftResultMatch: + puts("Object exists with the specified ID"); + break; + + case XftResultTypeMismatch: + puts("Object exists, but the type does not match"); + break; + + case XftResultNoId: + puts("Object exists, but has fewer values than specified"); + break; + + case FcResultOutOfMemory: + puts("FcResult: Malloc failed"); + break; + + case XftResultNoMatch: + puts("Object does not exist at all"); + break; + + default: + printf("Invalid XftResult status %d \n", match_result); + break; + } +#endif + +#if 0 // diagnostic to print the "full name" of the font we matched. This works. + FcChar8 *picked_name = FcNameUnparse(match_pat); + printf("Match: %s\n", picked_name); + free(picked_name); +#endif + + if (!match_pat) { + // last chance, just open any font in the right size + the_font = XftFontOpen (fl_display, fl_screen, + XFT_FAMILY, XftTypeString, "sans", + XFT_SIZE, XftTypeDouble, (double)fl_size_, + NULL); + XftPatternDestroy(fnt_pat); + if (!the_font) { + Fl::error("Unable to find fonts. Check your FontConfig configuration.\n"); + exit(1); + } + return the_font; + } + + // open the matched font + the_font = XftFontOpenPattern(fl_display, match_pat); + +#if 0 // diagnostic to print the "full name" of the font we actually opened. This works. + FcChar8 *picked_name2 = FcNameUnparse(the_font->pattern); + printf("Open : %s\n", picked_name2); + free(picked_name2); +#endif + + XftPatternDestroy(fnt_pat); +// XftPatternDestroy(match_pat); // FontConfig will destroy this resource for us. We must not! + + return the_font; + } + else { // We were passed a font name in XLFD format + /* OksiD's X font code could handle being passed a comma separated list + * of XLFD's. It then attempted to find which font was "best" from this list. + * But XftFontOpenXlfd can not do this, so if a list is passed, we just + * terminate it at the first comma. + * A "better" solution might be to use XftXlfdParse() on each of the passed + * XLFD's to construct a "super-pattern" that incorporates attributes from all + * XLFD's and use that to perform a XftFontMatch(). Maybe... + */ + char *local_name = strdup(name); + if(comma_count) { // This means we were passed multiple XLFD's + char *pc = strchr(local_name, ','); + *pc = 0; // terminate the XLFD at the first comma + } + XftFont *the_font = XftFontOpenXlfd(fl_display, fl_screen, local_name); + free(local_name); +#if 0 // diagnostic to print the "full name" of the font we actually opened. This works. +puts("Font Opened"); fflush(stdout); + FcChar8 *picked_name2 = FcNameUnparse(the_font->pattern); + printf("Open : %s\n", picked_name2); fflush(stdout); + free(picked_name2); +#endif + return the_font; + } +} // end of fontopen + +Fl_Font_Descriptor::Fl_Font_Descriptor(const char* name) { +// encoding = fl_encoding_; + size = fl_size_; + angle = fl_angle_; +#if HAVE_GL + listbase = 0; +#endif // HAVE_GL + font = fontopen(name, false, angle); +} + +Fl_Font_Descriptor::~Fl_Font_Descriptor() { + if (this == fl_fontsize) fl_fontsize = 0; +// XftFontClose(fl_display, font); +} + +int fl_height() { + if (current_font) return current_font->ascent + current_font->descent; + else return -1; +} + +int fl_descent() { + if (current_font) return current_font->descent; + else return -1; +} + +double fl_width(const char *str, int n) { + if (!current_font) return -1.0; + XGlyphInfo i; + XftTextExtentsUtf8(fl_display, current_font, (XftChar8 *)str, n, &i); + return i.xOff; +} + +double fl_width(uchar c) { + return fl_width((const char *)(&c), 1); +} + +double fl_width(FcChar32 *str, int n) { + if (!current_font) return -1.0; + XGlyphInfo i; + XftTextExtents32(fl_display, current_font, str, n, &i); + return i.xOff; +} + +double fl_width(unsigned int c) { + return fl_width((FcChar32 *)(&c), 1); +} + +void fl_text_extents(const char *c, int n, int &dx, int &dy, int &w, int &h) { + if (!current_font) { + w = h = 0; + dx = dy = 0; + return; + } + XGlyphInfo gi; + XftTextExtentsUtf8(fl_display, current_font, (XftChar8 *)c, n, &gi); + + w = gi.width; + h = gi.height; + dx = -gi.x; + dy = -gi.y; +} // fl_text_extents + + +/* This code is used (mainly by opengl) to get a bitmapped font. The + * original XFT-1 code used XFT's "core" fonts methods to load an XFT + * font that was actually a X-bitmap font, that could then be readily + * used with GL. But XFT-2 does not provide that ability, and there + * is no easy method to use an XFT font directly with GL. So... +*/ + +# if XFT_MAJOR > 1 +// This function attempts, on XFT2 systems, to find a suitable "core" Xfont +// for GL or other bitmap font needs (we dont have an XglUseXftFont(...) function.) +// There's probably a better way to do this. I can't believe it is this hard... +// Anyway... This code attempts to make an XLFD out of the fltk-style font +// name it is passed, then tries to load that font. Surprisingly, this quite +// often works - boxes that have XFT generally also have a fontserver that +// can serve TTF and other fonts to X, and so the font name that fltk makes +// from the XFT name often also "exists" as an "core" X font... +// If this code fails to load the requested font, it falls back through a +// series of tried 'n tested alternatives, ultimately resorting to what the +// original fltk code did. +// NOTE: On my test boxes (FC6, FC7, FC8, ubuntu8.04, 9.04, 9.10) this works +// well for the fltk "built-in" font names. +static XFontStruct* load_xfont_for_xft2(void) { + XFontStruct* xgl_font = 0; + int size = fl_size_; + const char *wt_med = "medium"; + const char *wt_bold = "bold"; + const char *weight = wt_med; // no specifc weight requested - accept any + char slant = 'r'; // regular non-italic by default + char xlfd[128]; // we will put our synthetic XLFD in here + char *pc = strdup(fl_fonts[fl_font_].name); // what font were we asked for? + const char *name = pc; // keep a handle to the original name for freeing later + // Parse the "fltk-name" of the font + switch (*name++) { + case 'I': slant = 'i'; break; // italic + case 'P': slant = 'i'; // bold-italic (falls-through) + case 'B': weight = wt_bold; break; // bold + case ' ': break; // regular + default: name--; // no prefix, restore name + } + + // first, we do a query with no prefered size, to see if the font exists at all + snprintf(xlfd, 128, "-*-%s-%s-%c-*--*-*-*-*-*-*-*-*", name, weight, slant); // make up xlfd style name + xgl_font = XLoadQueryFont(fl_display, xlfd); + if(xgl_font) { // the face exists, but can we get it in a suitable size? + XFreeFont(fl_display, xgl_font); // release the non-sized version + snprintf(xlfd, 128, "-*-%s-%s-%c-*--*-%d-*-*-*-*-*-*", name, weight, slant, (size*10)); + xgl_font = XLoadQueryFont(fl_display, xlfd); // attempt to load the font at the right size + } +//puts(xlfd); + + // try alternative names + if (!xgl_font) { + if (!strcmp(name, "sans")) { + name = "helvetica"; + } else if (!strcmp(name, "mono")) { + name = "courier"; + } else if (!strcmp(name, "serif")) { + name = "times"; + } else if (!strcmp(name, "screen")) { + name = "lucidatypewriter"; + } else if (!strcmp(name, "dingbats")) { + name = "zapf dingbats"; + } + snprintf(xlfd, 128, "-*-*%s*-%s-%c-*--*-%d-*-*-*-*-*-*", name, weight, slant, (size*10)); + xgl_font = XLoadQueryFont(fl_display, xlfd); + } + free(pc); // release our copy of the font name + + // if we have nothing loaded, try a generic proportional font + if(!xgl_font) { + snprintf(xlfd, 128, "-*-helvetica-*-%c-*--*-%d-*-*-*-*-*-*", slant, (size*10)); + xgl_font = XLoadQueryFont(fl_display, xlfd); + } + // If that still didn't work, try this instead + if(!xgl_font) { + snprintf(xlfd, 128, "-*-courier-medium-%c-*--*-%d-*-*-*-*-*-*", slant, (size*10)); + xgl_font = XLoadQueryFont(fl_display, xlfd); + } +//printf("glf: %d\n%s\n%s\n", size, xlfd, fl_fonts[fl_font_].name); +//if(xgl_font) puts("ok"); + + // Last chance fallback - this usually loads something... + if (!xgl_font) xgl_font = XLoadQueryFont(fl_display, "fixed"); + + return xgl_font; +} // end of load_xfont_for_xft2 +# endif + +XFontStruct* fl_xxfont() { +# if XFT_MAJOR > 1 + // kludge! XFT 2 and later does not provide core fonts for us to use with GL + // try to load a bitmap X font instead + static XFontStruct* xgl_font = 0; + static int glsize = 0; + static int glfont = -1; + // Do we need to load a new font? + if ((!xgl_font) || (glsize != fl_size_) || (glfont != fl_font_)) { + // create a dummy XLFD for some font of the appropriate size... + if (xgl_font) XFreeFont(fl_display, xgl_font); // font already loaded, free it - this *might* be a Bad Idea + glsize = fl_size_; // record current font size + glfont = fl_font_; // and face + xgl_font = load_xfont_for_xft2(); + } + return xgl_font; +# else // XFT-1 provides a means to load a "core" font directly + if (current_font->core) return current_font->u.core.font; // is the current font a "core" font? If so, use it. + static XftFont* xftfont; + if (xftfont) XftFontClose (fl_display, xftfont); + xftfont = fontopen(fl_fonts[fl_font_].name, true); // else request XFT to load a suitable "core" font instead. + return xftfont->u.core.font; +# endif // XFT_MAJOR > 1 +} + +XFontStruct* Fl_XFont_On_Demand::value() { + if (!ptr) ptr = fl_xxfont(); + return ptr; +} + +#if USE_OVERLAY +// Currently Xft does not work with colormapped visuals, so this probably +// does not work unless you have a true-color overlay. +extern bool fl_overlay; +extern Colormap fl_overlay_colormap; +extern XVisualInfo* fl_overlay_visual; +#endif + +// For some reason Xft produces errors if you destroy a window whose id +// still exists in an XftDraw structure. It would be nice if this is not +// true, a lot of junk is needed to try to stop this: + +static XftDraw* draw_; +static Window draw_window; +#if USE_OVERLAY +static XftDraw* draw_overlay; +static Window draw_overlay_window; +#endif + +void fl_destroy_xft_draw(Window id) { + if (id == draw_window) + XftDrawChange(draw_, draw_window = fl_message_window); +#if USE_OVERLAY + if (id == draw_overlay_window) + XftDrawChange(draw_overlay, draw_overlay_window = fl_message_window); +#endif +} + +void Fl_Graphics_Driver::draw(const char *str, int n, int x, int y) { + if ( !current_font ) { + fl_font(FL_HELVETICA, 14); + } +#if USE_OVERLAY + XftDraw*& draw_ = fl_overlay ? draw_overlay : ::draw_; + if (fl_overlay) { + if (!draw_) + draw_ = XftDrawCreate(fl_display, draw_overlay_window = fl_window, + fl_overlay_visual->visual, fl_overlay_colormap); + else //if (draw_overlay_window != fl_window) + XftDrawChange(draw_, draw_overlay_window = fl_window); + } else +#endif + if (!draw_) + draw_ = XftDrawCreate(fl_display, draw_window = fl_window, + fl_visual->visual, fl_colormap); + else //if (draw_window != fl_window) + XftDrawChange(draw_, draw_window = fl_window); + + Region region = fl_clip_region(); + if (region && XEmptyRegion(region)) return; + XftDrawSetClip(draw_, region); + + // Use fltk's color allocator, copy the results to match what + // XftCollorAllocValue returns: + XftColor color; + color.pixel = fl_xpixel(fl_color_); + uchar r,g,b; Fl::get_color(fl_color_, r,g,b); + color.color.red = ((int)r)*0x101; + color.color.green = ((int)g)*0x101; + color.color.blue = ((int)b)*0x101; + color.color.alpha = 0xffff; + + XftDrawStringUtf8(draw_, &color, current_font, x, y, (XftChar8 *)str, n); +} + +void Fl_Graphics_Driver::draw(int angle, const char *str, int n, int x, int y) { + fl_font(fl_font_, fl_size_, angle); + fl_draw(str, n, (int)x, (int)y); + fl_font(fl_font_, fl_size_); +} + +void fl_draw(const char* str, int n, float x, float y) { + fl_draw(str, n, (int)x, (int)y); +} + +static void fl_drawUCS4(const FcChar32 *str, int n, int x, int y) { +#if USE_OVERLAY + XftDraw*& draw_ = fl_overlay ? draw_overlay : ::draw_; + if (fl_overlay) { + if (!draw_) + draw_ = XftDrawCreate(fl_display, draw_overlay_window = fl_window, + fl_overlay_visual->visual, fl_overlay_colormap); + else //if (draw_overlay_window != fl_window) + XftDrawChange(draw_, draw_overlay_window = fl_window); + } else +#endif + if (!draw_) + draw_ = XftDrawCreate(fl_display, draw_window = fl_window, + fl_visual->visual, fl_colormap); + else //if (draw_window != fl_window) + XftDrawChange(draw_, draw_window = fl_window); + + Region region = fl_clip_region(); + if (region && XEmptyRegion(region)) return; + XftDrawSetClip(draw_, region); + + // Use fltk's color allocator, copy the results to match what + // XftCollorAllocValue returns: + XftColor color; + color.pixel = fl_xpixel(fl_color_); + uchar r,g,b; Fl::get_color(fl_color_, r,g,b); + color.color.red = ((int)r)*0x101; + color.color.green = ((int)g)*0x101; + color.color.blue = ((int)b)*0x101; + color.color.alpha = 0xffff; + + XftDrawString32(draw_, &color, current_font, x, y, (FcChar32 *)str, n); +} + + +void Fl_Graphics_Driver::rtl_draw(const char* c, int n, int x, int y) { + +#if defined(__GNUC__) +// FIXME: warning Need to improve this XFT right to left draw function +#endif /*__GNUC__*/ + +// This actually draws LtoR, but aligned to R edge with the glyph order reversed... +// but you can't just byte-rev a UTF-8 string, that isn't valid. +// You can reverse a UCS4 string though... + int num_chars, wid, utf_len = strlen(c); + FcChar8 *u8 = (FcChar8 *)c; + FcBool valid = FcUtf8Len(u8, utf_len, &num_chars, &wid); + if (!valid) + { + // badly formed Utf-8 input string + return; + } + if (num_chars < n) n = num_chars; // limit drawing to usable characters in input array + FcChar32 *ucs_txt = new FcChar32[n+1]; + FcChar32* pu; + int in, out, sz; + ucs_txt[n] = 0; + in = 0; out = n-1; + while ((out >= 0) && (utf_len > 0)) + { + pu = &ucs_txt[out]; + sz = FcUtf8ToUcs4(u8, pu, utf_len); + utf_len = utf_len - sz; + u8 = u8 + sz; + out = out - 1; + } + // Now we have a UCS4 version of the input text, reversed, in ucs_txt + int offs = (int)fl_width(ucs_txt, n); + fl_drawUCS4(ucs_txt, n, (x-offs), y); + + delete[] ucs_txt; +} +#endif + +// +// End of "$Id: fl_font_xft.cxx 7855 2010-11-15 22:13:13Z matt $" +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_gtk.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_gtk.cxx new file mode 100644 index 0000000..76cbe4c --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_gtk.cxx @@ -0,0 +1,304 @@ +// +// "$Id: fl_gtk.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// "GTK" drawing routines for the Fast Light Tool Kit (FLTK). +// +// These box types provide a GTK+ look, based on Red Hat's Bluecurve +// theme... +// +// Copyright 2006-2010 by Michael Sweet. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Box drawing code for an obscure box type. +// These box types are in separate files so they are not linked +// in if not used. + +#include +#include + +extern void fl_internal_boxtype(Fl_Boxtype, Fl_Box_Draw_F*); + + +static void gtk_color(Fl_Color c) { + if (Fl::draw_box_active()) fl_color(c); + else fl_color(fl_inactive(c)); +} + + +static void gtk_up_frame(int x, int y, int w, int h, Fl_Color c) { + gtk_color(fl_color_average(FL_WHITE, c, 0.5)); + fl_xyline(x + 2, y + 1, x + w - 3); + fl_yxline(x + 1, y + 2, y + h - 3); + + gtk_color(fl_color_average(FL_BLACK, c, 0.5)); + fl_begin_loop(); + fl_vertex(x, y + 2); + fl_vertex(x + 2, y); + fl_vertex(x + w - 3, y); + fl_vertex(x + w - 1, y + 2); + fl_vertex(x + w - 1, y + h - 3); + fl_vertex(x + w - 3, y + h - 1); + fl_vertex(x + 2, y + h - 1); + fl_vertex(x, y + h - 3); + fl_end_loop(); +} + + +static void gtk_up_box(int x, int y, int w, int h, Fl_Color c) { + gtk_up_frame(x, y, w, h, c); + + gtk_color(fl_color_average(FL_WHITE, c, 0.4f)); + fl_xyline(x + 2, y + 2, x + w - 3); + gtk_color(fl_color_average(FL_WHITE, c, 0.2f)); + fl_xyline(x + 2, y + 3, x + w - 3); + gtk_color(fl_color_average(FL_WHITE, c, 0.1f)); + fl_xyline(x + 2, y + 4, x + w - 3); + gtk_color(c); + fl_rectf(x + 2, y + 5, w - 4, h - 7); + gtk_color(fl_color_average(FL_BLACK, c, 0.025f)); + fl_xyline(x + 2, y + h - 4, x + w - 3); + gtk_color(fl_color_average(FL_BLACK, c, 0.05f)); + fl_xyline(x + 2, y + h - 3, x + w - 3); + gtk_color(fl_color_average(FL_BLACK, c, 0.1f)); + fl_xyline(x + 2, y + h - 2, x + w - 3); + fl_yxline(x + w - 2, y + 2, y + h - 3); +} + + +static void gtk_down_frame(int x, int y, int w, int h, Fl_Color c) { + gtk_color(fl_color_average(FL_BLACK, c, 0.5)); + fl_begin_loop(); + fl_vertex(x, y + 2); + fl_vertex(x + 2, y); + fl_vertex(x + w - 3, y); + fl_vertex(x + w - 1, y + 2); + fl_vertex(x + w - 1, y + h - 3); + fl_vertex(x + w - 3, y + h - 1); + fl_vertex(x + 2, y + h - 1); + fl_vertex(x, y + h - 3); + fl_end_loop(); + + gtk_color(fl_color_average(FL_BLACK, c, 0.1f)); + fl_xyline(x + 2, y + 1, x + w - 3); + fl_yxline(x + 1, y + 2, y + h - 3); + + gtk_color(fl_color_average(FL_BLACK, c, 0.05f)); + fl_yxline(x + 2, y + h - 2, y + 2, x + w - 2); +} + + +static void gtk_down_box(int x, int y, int w, int h, Fl_Color c) { + gtk_down_frame(x, y, w, h, c); + + gtk_color(c); + fl_rectf(x + 3, y + 3, w - 5, h - 4); + fl_yxline(x + w - 2, y + 3, y + h - 3); +} + + +static void gtk_thin_up_frame(int x, int y, int w, int h, Fl_Color c) { + gtk_color(fl_color_average(FL_WHITE, c, 0.6f)); + fl_xyline(x + 1, y, x + w - 2); + fl_yxline(x, y + 1, y + h - 2); + + gtk_color(fl_color_average(FL_BLACK, c, 0.4f)); + fl_xyline(x + 1, y + h - 1, x + w - 2); + fl_yxline(x + w - 1, y + 1, y + h - 2); +} + + +static void gtk_thin_up_box(int x, int y, int w, int h, Fl_Color c) { + gtk_thin_up_frame(x, y, w, h, c); + + gtk_color(fl_color_average(FL_WHITE, c, 0.4f)); + fl_xyline(x + 1, y + 1, x + w - 2); + gtk_color(fl_color_average(FL_WHITE, c, 0.2f)); + fl_xyline(x + 1, y + 2, x + w - 2); + gtk_color(fl_color_average(FL_WHITE, c, 0.1f)); + fl_xyline(x + 1, y + 3, x + w - 2); + gtk_color(c); + fl_rectf(x + 1, y + 4, w - 2, h - 8); + gtk_color(fl_color_average(FL_BLACK, c, 0.025f)); + fl_xyline(x + 1, y + h - 4, x + w - 2); + gtk_color(fl_color_average(FL_BLACK, c, 0.05f)); + fl_xyline(x + 1, y + h - 3, x + w - 2); + gtk_color(fl_color_average(FL_BLACK, c, 0.1f)); + fl_xyline(x + 1, y + h - 2, x + w - 2); +} + + +static void gtk_thin_down_frame(int x, int y, int w, int h, Fl_Color c) { + gtk_color(fl_color_average(FL_BLACK, c, 0.4f)); + fl_xyline(x + 1, y, x + w - 2); + fl_yxline(x, y + 1, y + h - 2); + + gtk_color(fl_color_average(FL_WHITE, c, 0.6f)); + fl_xyline(x + 1, y + h - 1, x + w - 2); + fl_yxline(x + w - 1, y + 1, y + h - 2); +} + + +static void gtk_thin_down_box(int x, int y, int w, int h, Fl_Color c) { + gtk_thin_down_frame(x, y, w, h, c); + + gtk_color(c); + fl_rectf(x + 1, y + 1, w - 2, h - 2); +} + +//------------------------ +// new GTK+ style for round buttons +#if 1 + +static void fl_arc_i(int x,int y,int w,int h,double a1,double a2) { + fl_arc(x,y,w,h,a1,a2); +} + +enum {UPPER_LEFT, LOWER_RIGHT, CLOSED, FILL}; + +static void draw(int which, int x,int y,int w,int h, int inset) +{ + if (inset*2 >= w) inset = (w-1)/2; + if (inset*2 >= h) inset = (h-1)/2; + x += inset; + y += inset; + w -= 2*inset; + h -= 2*inset; + int d = w <= h ? w : h; + if (d <= 1) return; + void (*f)(int,int,int,int,double,double); + f = (which==FILL) ? fl_pie : fl_arc_i; + if (which >= CLOSED) { + f(x+w-d, y, d, d, w<=h ? 0 : -90, w<=h ? 180 : 90); + f(x, y+h-d, d, d, w<=h ? 180 : 90, w<=h ? 360 : 270); + } else if (which == UPPER_LEFT) { + f(x+w-d, y, d, d, 45, w<=h ? 180 : 90); + f(x, y+h-d, d, d, w<=h ? 180 : 90, 225); + } else { // LOWER_RIGHT + f(x, y+h-d, d, d, 225, w<=h ? 360 : 270); + f(x+w-d, y, d, d, w<=h ? 360 : 270, 360+45); + } + if (which == FILL) { + if (w < h) + fl_rectf(x, y+d/2, w, h-(d&-2)); + else if (w > h) + fl_rectf(x+d/2, y, w-(d&-2), h); + } else { + if (w < h) { + if (which != UPPER_LEFT) fl_yxline(x+w-1, y+d/2-1, y+h-d/2+1); + if (which != LOWER_RIGHT) fl_yxline(x, y+d/2-1, y+h-d/2+1); + } else if (w > h) { + if (which != UPPER_LEFT) fl_xyline(x+d/2-1, y+h-1, x+w-d/2+1); + if (which != LOWER_RIGHT) fl_xyline(x+d/2-1, y, x+w-d/2+1); + } + } +} + +void gtk_round_up_box(int x, int y, int w, int h, Fl_Color c) { + fl_color(c); + draw(FILL, x, y, w, h, 2); + + gtk_color(fl_color_average(FL_BLACK, c, 0.025f)); + draw(LOWER_RIGHT, x+1, y, w-2, h, 2); + draw(LOWER_RIGHT, x, y, w, h, 3); + gtk_color(fl_color_average(FL_BLACK, c, 0.05f)); + draw(LOWER_RIGHT, x+1, y, w-2, h, 1); + draw(LOWER_RIGHT, x, y, w, h, 2); + gtk_color(fl_color_average(FL_BLACK, c, 0.1f)); + draw(LOWER_RIGHT, x+1, y, w-2, h, 0); + draw(LOWER_RIGHT, x, y, w, h, 1); + + gtk_color(fl_color_average(FL_WHITE, c, 0.1f)); + draw(UPPER_LEFT, x, y, w, h, 4); + draw(UPPER_LEFT, x+1, y, w-2, h, 3); + gtk_color(fl_color_average(FL_WHITE, c, 0.2f)); + draw(UPPER_LEFT, x, y, w, h, 3); + draw(UPPER_LEFT, x+1, y, w-2, h, 2); + gtk_color(fl_color_average(FL_WHITE, c, 0.4f)); + draw(UPPER_LEFT, x, y, w, h, 2); + draw(UPPER_LEFT, x+1, y, w-2, h, 1); + gtk_color(fl_color_average(FL_WHITE, c, 0.5f)); + draw(UPPER_LEFT, x, y, w, h, 1); + draw(UPPER_LEFT, x+1, y, w-2, h, 0); + + gtk_color(fl_color_average(FL_BLACK, c, 0.5f)); + draw(CLOSED, x, y, w, h, 0); +} + +void gtk_round_down_box(int x, int y, int w, int h, Fl_Color c) { + fl_color(c); + draw(FILL, x, y, w, h, 2); + + gtk_color(fl_color_average(FL_BLACK, c, 0.05f)); + draw(UPPER_LEFT, x, y, w, h, 2); + draw(UPPER_LEFT, x+1, y, w-2, h, 1); + gtk_color(fl_color_average(FL_BLACK, c, 0.1f)); + draw(UPPER_LEFT, x, y, w, h, 1); + draw(UPPER_LEFT, x+1, y, w-2, h, 0); + + gtk_color(fl_color_average(FL_BLACK, c, 0.5f)); + draw(CLOSED, x, y, w, h, 0); +} + +#else + +static void gtk_round_up_box(int x, int y, int w, int h, Fl_Color c) { + gtk_color(c); + fl_pie(x, y, w, h, 0.0, 360.0); + gtk_color(fl_color_average(FL_WHITE, c, 0.5f)); + fl_arc(x, y, w, h, 45.0, 180.0); + gtk_color(fl_color_average(FL_WHITE, c, 0.25f)); + fl_arc(x, y, w, h, 180.0, 405.0); + gtk_color(fl_color_average(FL_BLACK, c, 0.5f)); + fl_arc(x, y, w, h, 225.0, 360.0); +} + + +static void gtk_round_down_box(int x, int y, int w, int h, Fl_Color c) { + gtk_color(c); + fl_pie(x, y, w, h, 0.0, 360.0); + gtk_color(fl_color_average(FL_BLACK, c, 0.2)); + fl_arc(x + 1, y, w, h, 90.0, 210.0); + gtk_color(fl_color_average(FL_BLACK, c, 0.6)); + fl_arc(x, y, w, h, 0.0, 360.0); +} + +#endif + +Fl_Boxtype fl_define_FL_GTK_UP_BOX() { + fl_internal_boxtype(_FL_GTK_UP_BOX, gtk_up_box); + fl_internal_boxtype(_FL_GTK_DOWN_BOX, gtk_down_box); + fl_internal_boxtype(_FL_GTK_UP_FRAME, gtk_up_frame); + fl_internal_boxtype(_FL_GTK_DOWN_FRAME, gtk_down_frame); + fl_internal_boxtype(_FL_GTK_THIN_UP_BOX, gtk_thin_up_box); + fl_internal_boxtype(_FL_GTK_THIN_DOWN_BOX, gtk_thin_down_box); + fl_internal_boxtype(_FL_GTK_THIN_UP_FRAME, gtk_thin_up_frame); + fl_internal_boxtype(_FL_GTK_THIN_DOWN_FRAME, gtk_thin_down_frame); + fl_internal_boxtype(_FL_GTK_ROUND_UP_BOX, gtk_round_up_box); + fl_internal_boxtype(_FL_GTK_ROUND_DOWN_BOX, gtk_round_down_box); + + return _FL_GTK_UP_BOX; +} + + +// +// End of "$Id: fl_gtk.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_images_core.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_images_core.cxx new file mode 100644 index 0000000..0ba10e5 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_images_core.cxx @@ -0,0 +1,106 @@ +// +// "$Id: fl_images_core.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// FLTK images library core. +// +// Copyright 1997-2010 by Easy Software Products. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// +// Contents: +// +// fl_register_images() - Register the image formats. +// fl_check_images() - Check for a supported image format. +// + +// +// Include necessary header files... +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include "flstring.h" + + +// +// Define a simple global image registration function that registers +// the extra image formats that aren't part of the core FLTK library. +// + +static Fl_Image *fl_check_images(const char *name, uchar *header, int headerlen); + + +/** +\brief Register the image formats. + * + This function is provided in the fltk_images library and + registers all of the "extra" image file formats that are not part + of the core FLTK library. +*/ +void fl_register_images() { + Fl_Shared_Image::add_handler(fl_check_images); +} + + +// +// 'fl_check_images()' - Check for a supported image format. +// + +Fl_Image * // O - Image, if found +fl_check_images(const char *name, // I - Filename + uchar *header, // I - Header data from file + int) { // I - Amount of data (not used) + if (memcmp(header, "GIF87a", 6) == 0 || + memcmp(header, "GIF89a", 6) == 0) // GIF file + return new Fl_GIF_Image(name); + + if (memcmp(header, "BM", 2) == 0) // BMP file + return new Fl_BMP_Image(name); + + if (header[0] == 'P' && header[1] >= '1' && header[1] <= '7') + // Portable anymap + return new Fl_PNM_Image(name); + +#ifdef HAVE_LIBPNG + if (memcmp(header, "\211PNG", 4) == 0)// PNG file + return new Fl_PNG_Image(name); +#endif // HAVE_LIBPNG + +#ifdef HAVE_LIBJPEG + if (memcmp(header, "\377\330\377", 3) == 0 && + // Start-of-Image + header[3] >= 0xc0 && header[3] <= 0xef) + // APPn for JPEG file + return new Fl_JPEG_Image(name); +#endif // HAVE_LIBJPEG + + return 0; +} + + +// +// End of "$Id: fl_images_core.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_labeltype.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_labeltype.cxx new file mode 100644 index 0000000..e9d3ae9 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_labeltype.cxx @@ -0,0 +1,144 @@ +// +// "$Id: fl_labeltype.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Label drawing routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Drawing code for the (one) common label types. +// Other label types (symbols) are in their own source files +// to avoid linking if not used. + +#include +#include +#include +#include +#include + +void +fl_no_label(const Fl_Label*,int,int,int,int,Fl_Align) {} + +void +fl_normal_label(const Fl_Label* o, int X, int Y, int W, int H, Fl_Align align) +{ + fl_font(o->font, o->size); + fl_color((Fl_Color)o->color); + fl_draw(o->value, X, Y, W, H, align, o->image); +} + +void +fl_normal_measure(const Fl_Label* o, int& W, int& H) { + fl_font(o->font, o->size); + fl_measure(o->value, W, H); + if (o->image) { + if (o->image->w() > W) W = o->image->w(); + H += o->image->h(); + } +} + +#define MAX_LABELTYPE 16 + +static Fl_Label_Draw_F* table[MAX_LABELTYPE] = { + fl_normal_label, + fl_no_label, + fl_normal_label, // _FL_SHADOW_LABEL, + fl_normal_label, // _FL_ENGRAVED_LABEL, + fl_normal_label, // _FL_EMBOSSED_LABEL, + fl_no_label, // _FL_MULTI_LABEL, + fl_no_label, // _FL_ICON_LABEL, + // FL_FREE_LABELTYPE+n: + fl_no_label, fl_no_label, fl_no_label, + fl_no_label, fl_no_label, fl_no_label, + fl_no_label, fl_no_label, fl_no_label +}; + +static Fl_Label_Measure_F* measure[MAX_LABELTYPE]; + +/** Sets the functions to call to draw and measure a specific labeltype. */ +void Fl::set_labeltype(Fl_Labeltype t,Fl_Label_Draw_F* f,Fl_Label_Measure_F*m) +{ + table[t] = f; measure[t] = m; +} + +//////////////////////////////////////////////////////////////// + +/** Draws a label with arbitrary alignment in an arbitrary box. */ +void Fl_Label::draw(int X, int Y, int W, int H, Fl_Align align) const { + if (!value && !image) return; + table[type](this, X, Y, W, H, align); +} +/** + Measures the size of the label. + \param[in,out] W, H : this is the requested size for the label text plus image; + on return, this will contain the size needed to fit the label +*/ +void Fl_Label::measure(int& W, int& H) const { + if (!value && !image) { + W = H = 0; + return; + } + + Fl_Label_Measure_F* f = ::measure[type]; if (!f) f = fl_normal_measure; + f(this, W, H); +} + +/** Draws the widget's label at the defined label position. + This is the normal call for a widget's draw() method. + */ +void Fl_Widget::draw_label() const { + int X = x_+Fl::box_dx(box()); + int W = w_-Fl::box_dw(box()); + if (W > 11 && align()&(FL_ALIGN_LEFT|FL_ALIGN_RIGHT)) {X += 3; W -= 6;} + draw_label(X, y_+Fl::box_dy(box()), W, h_-Fl::box_dh(box())); +} + +/** Draws the label in an arbitrary bounding box. + draw() can use this instead of draw_label(void) to change the bounding box + */ +void Fl_Widget::draw_label(int X, int Y, int W, int H) const { + // quit if we are not drawing a label inside the widget: + if ((align()&15) && !(align() & FL_ALIGN_INSIDE)) return; + draw_label(X,Y,W,H,align()); +} + +/** Draws the label in an arbitrary bounding box with an arbitrary alignment. + Anybody can call this to force the label to draw anywhere. + */ +void Fl_Widget::draw_label(int X, int Y, int W, int H, Fl_Align a) const { + if (flags()&SHORTCUT_LABEL) fl_draw_shortcut = 1; + Fl_Label l1 = label_; + if (!active_r()) { + l1.color = fl_inactive((Fl_Color)l1.color); + if (l1.deimage) l1.image = l1.deimage; + } + l1.draw(X,Y,W,H,a); + fl_draw_shortcut = 0; +} + +// include these vars here so they can be referenced without including +// Fl_Input_ code: +#include + +// +// End of "$Id: fl_labeltype.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_line_style.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_line_style.cxx new file mode 100644 index 0000000..df47bf7 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_line_style.cxx @@ -0,0 +1,174 @@ +// +// "$Id: fl_line_style.cxx 7888 2010-11-23 17:18:42Z AlbrechtS $" +// +// Line style code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/** + \file fl_line_style.cxx + \brief Line style drawing utility hiding different platforms. +*/ + +#include +#include +#include +#include +#include "flstring.h" +#include + +// We save the current line width (absolute value) here. +// This is currently used only for X11 clipping, see src/fl_rect.cxx. +// FIXME: this would probably better be in class Fl:: +int fl_line_width_ = 0; + +#ifdef __APPLE_QUARTZ__ +float fl_quartz_line_width_ = 1.0f; +static enum CGLineCap fl_quartz_line_cap_ = kCGLineCapButt; +static enum CGLineJoin fl_quartz_line_join_ = kCGLineJoinMiter; +static CGFloat *fl_quartz_line_pattern = 0; +static int fl_quartz_line_pattern_size = 0; +void fl_quartz_restore_line_style_() { + CGContextSetLineWidth(fl_gc, fl_quartz_line_width_); + CGContextSetLineCap(fl_gc, fl_quartz_line_cap_); + CGContextSetLineJoin(fl_gc, fl_quartz_line_join_); + CGContextSetLineDash(fl_gc, 0, fl_quartz_line_pattern, fl_quartz_line_pattern_size); +} +#endif + +void Fl_Graphics_Driver::line_style(int style, int width, char* dashes) { + + // save line width in global variable for X11 clipping + if (width == 0) fl_line_width_ = 1; + else fl_line_width_ = width>0 ? width : -width; + +#if defined(USE_X11) + int ndashes = dashes ? strlen(dashes) : 0; + // emulate the WIN32 dash patterns on X + char buf[7]; + if (!ndashes && (style&0xff)) { + int w = width ? width : 1; + char dash, dot, gap; + // adjust lengths to account for cap: + if (style & 0x200) { + dash = char(2*w); + dot = 1; // unfortunately 0 does not work + gap = char(2*w-1); + } else { + dash = char(3*w); + dot = gap = char(w); + } + char* p = dashes = buf; + switch (style & 0xff) { + case FL_DASH: *p++ = dash; *p++ = gap; break; + case FL_DOT: *p++ = dot; *p++ = gap; break; + case FL_DASHDOT: *p++ = dash; *p++ = gap; *p++ = dot; *p++ = gap; break; + case FL_DASHDOTDOT: *p++ = dash; *p++ = gap; *p++ = dot; *p++ = gap; *p++ = dot; *p++ = gap; break; + } + ndashes = p-buf; + } + static int Cap[4] = {CapButt, CapButt, CapRound, CapProjecting}; + static int Join[4] = {JoinMiter, JoinMiter, JoinRound, JoinBevel}; + XSetLineAttributes(fl_display, fl_gc, width, + ndashes ? LineOnOffDash : LineSolid, + Cap[(style>>8)&3], Join[(style>>12)&3]); + if (ndashes) XSetDashes(fl_display, fl_gc, 0, dashes, ndashes); +#elif defined(WIN32) + // According to Bill, the "default" cap and join should be the + // "fastest" mode supported for the platform. I don't know why + // they should be different (same graphics cards, etc., right?) MRS + static DWORD Cap[4]= {PS_ENDCAP_FLAT, PS_ENDCAP_FLAT, PS_ENDCAP_ROUND, PS_ENDCAP_SQUARE}; + static DWORD Join[4]={PS_JOIN_ROUND, PS_JOIN_MITER, PS_JOIN_ROUND, PS_JOIN_BEVEL}; + int s1 = PS_GEOMETRIC | Cap[(style>>8)&3] | Join[(style>>12)&3]; + DWORD a[16]; int n = 0; + if (dashes && dashes[0]) { + s1 |= PS_USERSTYLE; + for (n = 0; n < 16 && *dashes; n++) a[n] = *dashes++; + } else { + s1 |= style & 0xff; // allow them to pass any low 8 bits for style + } + if ((style || n) && !width) width = 1; // fix cards that do nothing for 0? + LOGBRUSH penbrush = {BS_SOLID,fl_RGB(),0}; // can this be fl_brush()? + HPEN newpen = ExtCreatePen(s1, width, &penbrush, n, n ? a : 0); + if (!newpen) { + Fl::error("fl_line_style(): Could not create GDI pen object."); + return; + } + HPEN oldpen = (HPEN)SelectObject(fl_gc, newpen); + DeleteObject(oldpen); + DeleteObject(fl_current_xmap->pen); + fl_current_xmap->pen = newpen; +#elif defined(__APPLE_QUARTZ__) + static enum CGLineCap Cap[4] = { kCGLineCapButt, kCGLineCapButt, + kCGLineCapRound, kCGLineCapSquare }; + static enum CGLineJoin Join[4] = { kCGLineJoinMiter, kCGLineJoinMiter, + kCGLineJoinRound, kCGLineJoinBevel }; + if (width<1) width = 1; + fl_quartz_line_width_ = (float)width; + fl_quartz_line_cap_ = Cap[(style>>8)&3]; + // when printing kCGLineCapSquare seems better for solid lines + if ( Fl_Surface_Device::surface()->type() == Fl_Printer::device_type && style == FL_SOLID && dashes == NULL ) { + fl_quartz_line_cap_ = kCGLineCapSquare; + } + fl_quartz_line_join_ = Join[(style>>12)&3]; + char *d = dashes; + static CGFloat pattern[16]; + if (d && *d) { + CGFloat *p = pattern; + while (*d) { *p++ = (float)*d++; } + fl_quartz_line_pattern = pattern; + fl_quartz_line_pattern_size = d-dashes; + } else if (style & 0xff) { + char dash, dot, gap; + // adjust lengths to account for cap: + if (style & 0x200) { + dash = char(2*width); + dot = 1; + gap = char(2*width-1); + } else { + dash = char(3*width); + dot = gap = char(width); + } + CGFloat *p = pattern; + switch (style & 0xff) { + case FL_DASH: *p++ = dash; *p++ = gap; break; + case FL_DOT: *p++ = dot; *p++ = gap; break; + case FL_DASHDOT: *p++ = dash; *p++ = gap; *p++ = dot; *p++ = gap; break; + case FL_DASHDOTDOT: *p++ = dash; *p++ = gap; *p++ = dot; *p++ = gap; *p++ = dot; *p++ = gap; break; + } + fl_quartz_line_pattern_size = p-pattern; + fl_quartz_line_pattern = pattern; + } else { + fl_quartz_line_pattern = 0; + fl_quartz_line_pattern_size = 0; + } + fl_quartz_restore_line_style_(); +#else +# error unsupported platform +#endif +} + + +// +// End of "$Id: fl_line_style.cxx 7888 2010-11-23 17:18:42Z AlbrechtS $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_open_uri.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_open_uri.cxx new file mode 100644 index 0000000..7f1c83f --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_open_uri.cxx @@ -0,0 +1,380 @@ +// +// "$Id: fl_open_uri.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// fl_open_uri() code for FLTK. +// +// Test with: +// +// gcc -I/fltk/dir -I/fltk/dir/src -DTEST -o fl_open_uri fl_open_uri.cxx -lfltk +// +// Copyright 2003-2010 by Michael R Sweet +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// + +// +// Include necessary headers... +// + +#include +#include +#include +#include +#include +#include "flstring.h" +#ifdef WIN32 +# include +# include +#else +# include +# include +# include +# include +#endif // WIN32 + + +// +// Local functions... +// + +#if !defined(WIN32) && !defined(__APPLE__) +static char *path_find(const char *program, char *filename, int filesize); +#endif // !WIN32 && !__APPLE__ +#ifndef WIN32 +static int run_program(const char *program, char **argv, char *msg, int msglen); +#endif // !WIN32 + + +/** + * Opens the specified Uniform Resource Identifier (URI). + * Uses an operating-system dependent program or interface. For URIs + * using the "ftp", "http", or "https" schemes, the system default web + * browser is used to open the URI, while "mailto" and "news" URIs are + * typically opened using the system default mail reader and "file" URIs + * are opened using the file system navigator. + * + * On success, the (optional) msg buffer is filled with the command that + * was run to open the URI; on Windows, this will always be "open uri". + * + * On failure, the msg buffer is filled with an English error message. + * + * \b Example + * \code + * #include + * [..] + * char errmsg[512]; + * if ( !fl_open_uri("http://google.com/", errmsg, sizeof(errmsg)) ) { + * char warnmsg[768]; + * sprintf(warnmsg, "Error: %s", errmsg); + * fl_alert(warnmsg); + * } + * \endcode + * + * @param uri The URI to open + * @param msg Optional buffer which contains the command or error message + * @param msglen Length of optional buffer + * @return 1 on success, 0 on failure + */ + +int +fl_open_uri(const char *uri, char *msg, int msglen) { + // Supported URI schemes... + static const char * const schemes[] = { + "file://", + "ftp://", + "http://", + "https://", + "mailto:", + "news://", + NULL + }; + + // Validate the URI scheme... + int i; + for (i = 0; schemes[i]; i ++) + if (!strncmp(uri, schemes[i], strlen(schemes[i]))) + break; + + if (!schemes[i]) { + if (msg) { + char scheme[255]; + if (sscanf(uri, "%254[^:]", scheme) == 1) { + snprintf(msg, msglen, "URI scheme \"%s\" not supported.", scheme); + } else { + snprintf(msg, msglen, "Bad URI \"%s\"", uri); + } + } + + return 0; + } + +#ifdef WIN32 + if (msg) snprintf(msg, msglen, "open %s", uri); + + return (int)ShellExecute(HWND_DESKTOP, "open", uri, NULL, NULL, SW_SHOW) > 32; + +#elif defined(__APPLE__) + char *argv[3]; // Command-line arguments + + argv[0] = (char*)"open"; + argv[1] = (char*)uri; + argv[2] = (char*)0; + + if (msg) snprintf(msg, msglen, "open %s", uri); + + return run_program("/usr/bin/open", argv, msg, msglen) != 0; + +#else // !WIN32 && !__APPLE__ + // Run any of several well-known commands to open the URI. + // + // We give preference to the Portland group's xdg-utils + // programs which run the user's preferred web browser, etc. + // based on the current desktop environment in use. We fall + // back on older standards and then finally test popular programs + // until we find one we can use. + // + // Note that we specifically do not support the MAILER and + // BROWSER environment variables because we have no idea whether + // we need to run the listed commands in a terminal program. + + char command[1024], // Command to run... + *argv[4], // Command-line arguments + remote[1024]; // Remote-mode command... + const char * const *commands; // Array of commands to check... + static const char * const browsers[] = { + "xdg-open", // Portland + "htmlview", // Freedesktop.org + "firefox", + "mozilla", + "netscape", + "konqueror", // KDE + "opera", + "hotjava", // Solaris + "mosaic", + NULL + }; + static const char * const readers[] = { + "xdg-email", // Portland + "thunderbird", + "mozilla", + "netscape", + "evolution", // GNOME + "kmailservice", // KDE + NULL + }; + static const char * const managers[] = { + "xdg-open", // Portland + "fm", // IRIX + "dtaction", // CDE + "nautilus", // GNOME + "konqueror", // KDE + NULL + }; + + // Figure out which commands to check for... + if (!strncmp(uri, "file://", 7)) commands = managers; + else if (!strncmp(uri, "mailto:", 7) || + !strncmp(uri, "news:", 5)) commands = readers; + else commands = browsers; + + // Find the command to run... + for (i = 0; commands[i]; i ++) + if (path_find(commands[i], command, sizeof(command))) break; + + if (!commands[i]) { + if (msg) { + snprintf(msg, msglen, "No helper application found for \"%s\"", uri); + } + + return 0; + } + + // Handle command-specific arguments... + argv[0] = (char *)commands[i]; + + if (!strcmp(commands[i], "firefox") || + !strcmp(commands[i], "mozilla") || + !strcmp(commands[i], "netscape") || + !strcmp(commands[i], "thunderbird")) { + // program -remote openURL(uri) + snprintf(remote, sizeof(remote), "openURL(%s)", uri); + + argv[1] = (char *)"-remote"; + argv[2] = remote; + argv[3] = 0; + } else if (!strcmp(commands[i], "dtaction")) { + // dtaction open uri + argv[1] = (char *)"open"; + argv[2] = (char *)uri; + argv[3] = 0; + } else { + // program uri + argv[1] = (char *)uri; + argv[2] = 0; + } + + if (msg) { + strlcpy(msg, argv[0], msglen); + + for (i = 1; argv[i]; i ++) { + strlcat(msg, " ", msglen); + strlcat(msg, argv[i], msglen); + } + } + + return run_program(command, argv, msg, msglen) != 0; +#endif // WIN32 +} + + +#if !defined(WIN32) && !defined(__APPLE__) +// Find a program in the path... +static char *path_find(const char *program, char *filename, int filesize) { + const char *path; // Search path + char *ptr, // Pointer into filename + *end; // End of filename buffer + + + if ((path = getenv("PATH")) == NULL) path = "/bin:/usr/bin"; + + for (ptr = filename, end = filename + filesize - 1; *path; path ++) { + if (*path == ':') { + if (ptr > filename && ptr[-1] != '/' && ptr < end) *ptr++ = '/'; + + strlcpy(ptr, program, end - ptr + 1); + + if (!access(filename, X_OK)) return filename; + + ptr = filename; + } else if (ptr < end) *ptr++ = *path; + } + + if (ptr > filename) { + if (ptr[-1] != '/' && ptr < end) *ptr++ = '/'; + + strlcpy(ptr, program, end - ptr + 1); + + if (!access(filename, X_OK)) return filename; + } + + return 0; +} +#endif // !WIN32 && !__APPLE__ + + +#ifndef WIN32 +// Run the specified program, returning 1 on success and 0 on failure +static int +run_program(const char *program, char **argv, char *msg, int msglen) { + pid_t pid; // Process ID of first child + int status; // Exit status from first child + sigset_t set, oldset; // Signal masks + + + // Block SIGCHLD while we run the program... + // + // Note that I only use the POSIX signal APIs, however older operating + // systems may either not support POSIX signals or have side effects. + // IRIX, for example, provides three separate and incompatible signal + // APIs, so it is possible that an application setting a signal handler + // via signal() or sigset() will not have its SIGCHLD signals blocked... + + sigemptyset(&set); + sigaddset(&set, SIGCHLD); + sigprocmask(SIG_BLOCK, &set, &oldset); + + // Create child processes that actually run the program for us... + if ((pid = fork()) == 0) { + // First child comes here, fork a second child and exit... + if (!fork()) { + // Second child comes here, redirect stdin/out/err to /dev/null... + close(0); + open("/dev/null", O_RDONLY); + + close(1); + open("/dev/null", O_WRONLY); + + close(2); + open("/dev/null", O_WRONLY); + + // Detach from the current process group... + setsid(); + + // Run the program... + execv(program, argv); + _exit(0); + } else { + // First child gets here, exit immediately... + _exit(0); + } + } else if (pid < 0) { + // Restore signal handling... + sigprocmask(SIG_SETMASK, &oldset, NULL); + + // Return indicating failure... + return 0; + } + + // Wait for the first child to exit... + while (waitpid(pid, &status, 0) < 0) { + if (errno != EINTR) { + // Someone else grabbed the child status... + if (msg) snprintf(msg, msglen, "waitpid(%ld) failed: %s", (long)pid, + strerror(errno)); + + // Restore signal handling... + sigprocmask(SIG_SETMASK, &oldset, NULL); + + // Return indicating failure... + return 0; + } + } + + // Restore signal handling... + sigprocmask(SIG_SETMASK, &oldset, NULL); + + // Return indicating success... + return 1; +} +#endif // !WIN32 + + +#ifdef TEST +// +// Test code... +// + +// Open the URI on the command-line... +int main(int argc, char **argv) { + char msg[1024]; + + + if (argc != 2) { + puts("Usage: fl_open_uri URI"); + return 1; + } + + if (!fl_open_uri(argv[1], msg, sizeof(msg))) { + puts(msg); + return 1; + } else return 0; +} +#endif // TEST + + +// +// End of "$Id: fl_open_uri.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_oval_box.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_oval_box.cxx new file mode 100644 index 0000000..0dad6d7 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_oval_box.cxx @@ -0,0 +1,66 @@ +// +// "$Id: fl_oval_box.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Oval box drawing code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + + +// Less-used box types are in separate files so they are not linked +// in if not used. + +#include +#include + +static void fl_oval_flat_box(int x, int y, int w, int h, Fl_Color c) { + fl_color(c); + fl_pie(x, y, w, h, 0, 360); +} + +static void fl_oval_frame(int x, int y, int w, int h, Fl_Color c) { + fl_color(c); + fl_arc(x, y, w, h, 0, 360); +} + +static void fl_oval_box(int x, int y, int w, int h, Fl_Color c) { + fl_oval_flat_box(x,y,w,h,c); + fl_oval_frame(x,y,w,h,FL_BLACK); +} + +static void fl_oval_shadow_box(int x, int y, int w, int h, Fl_Color c) { + fl_oval_flat_box(x+3,y+3,w,h,FL_DARK3); + fl_oval_box(x,y,w,h,c); +} + +extern void fl_internal_boxtype(Fl_Boxtype, Fl_Box_Draw_F*); +Fl_Boxtype fl_define_FL_OVAL_BOX() { + fl_internal_boxtype(_FL_OSHADOW_BOX,fl_oval_shadow_box); + fl_internal_boxtype(_FL_OVAL_FRAME,fl_oval_frame); + fl_internal_boxtype(_FL_OFLAT_BOX,fl_oval_flat_box); + fl_internal_boxtype(_FL_OVAL_BOX,fl_oval_box); + return _FL_OVAL_BOX; +} + +// +// End of "$Id: fl_oval_box.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_overlay.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_overlay.cxx new file mode 100644 index 0000000..adcd871 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_overlay.cxx @@ -0,0 +1,129 @@ +// +// "$Id: fl_overlay.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Overlay support for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Extremely limited "overlay" support. You can use this to drag out +// a rectangle in response to mouse events. It is your responsibility +// to erase the overlay before drawing anything that might intersect +// it. + +#include +#include +#ifdef __APPLE__ +#include +#endif + +//#define USE_XOR + +static int px,py,pw,ph; + +#ifndef USE_XOR +#include +static uchar *bgN = 0L, *bgS = 0L, *bgE = 0L, *bgW = 0L; +static int bgx, bgy, bgw, bgh; +#endif + +static void draw_current_rect() { +#ifdef USE_XOR +# if defined(USE_X11) + XSetFunction(fl_display, fl_gc, GXxor); + XSetForeground(fl_display, fl_gc, 0xffffffff); + XDrawRectangle(fl_display, fl_window, fl_gc, px, py, pw, ph); + XSetFunction(fl_display, fl_gc, GXcopy); +# elif defined(WIN32) + int old = SetROP2(fl_gc, R2_NOT); + fl_rect(px, py, pw, ph); + SetROP2(fl_gc, old); +# elif defined(__APPLE_QUARTZ__) + // warning: Quartz does not support xor drawing + // Use the Fl_Overlay_Window instead. + fl_color(FL_WHITE); + fl_rect(px, py, pw, ph); +# else +# error unsupported platform +# endif +#else + if (bgN) { free(bgN); bgN = 0L; } + if (bgS) { free(bgS); bgS = 0L; } + if (bgE) { free(bgE); bgE = 0L; } + if (bgW) { free(bgW); bgW = 0L; } + if (pw>0 && ph>0) { + bgE = fl_read_image(0L, px+pw-1, py, 1, ph); + bgW = fl_read_image(0L, px, py, 1, ph); + bgS = fl_read_image(0L, px, py+ph-1, pw, 1); + bgN = fl_read_image(0L, px, py, pw, 1); + bgx = px; bgy = py; + bgw = pw; bgh = ph; + } + fl_color(FL_WHITE); + fl_line_style(FL_SOLID); + fl_rect(px, py, pw, ph); + fl_color(FL_BLACK); + fl_line_style(FL_DOT); + fl_rect(px, py, pw, ph); + fl_line_style(FL_SOLID); +#endif +} + +static void erase_current_rect() { +#ifdef USE_XOR +# ifdef __APPLE_QUARTZ__ + fl_rect(px, py, pw, ph); +# else + draw_current_rect(); +# endif +#else + if (bgN) fl_draw_image(bgN, bgx, bgy, bgw, 1); + if (bgS) fl_draw_image(bgS, bgx, bgy+bgh-1, bgw, 1); + if (bgW) fl_draw_image(bgW, bgx, bgy, 1, bgh); + if (bgE) fl_draw_image(bgE, bgx+bgw-1, bgy, 1, bgh); +#endif +} + +/** + Erase a selection rectangle without drawing a new one + */ +void fl_overlay_clear() { + if (pw > 0) {erase_current_rect(); pw = 0;} +} + +/** + Draws a selection rectangle, erasing a previous one by XOR'ing it first. + */ +void fl_overlay_rect(int x, int y, int w, int h) { + if (w < 0) {x += w; w = -w;} else if (!w) w = 1; + if (h < 0) {y += h; h = -h;} else if (!h) h = 1; + if (pw > 0) { + if (x==px && y==py && w==pw && h==ph) return; + erase_current_rect(); + } + px = x; py = y; pw = w; ph = h; + draw_current_rect(); +} + +// +// End of "$Id: fl_overlay.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_overlay_visual.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_overlay_visual.cxx new file mode 100644 index 0000000..392898f --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_overlay_visual.cxx @@ -0,0 +1,105 @@ +// +// "$Id: fl_overlay_visual.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// X overlay support for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Return an overlay visual, if any. Also allocate a colormap and +// record the depth for fl_color() to use. +// Another disgusting X interface, based on code extracted and +// purified with great difficulty from XLayerUtil.cxx: + +#include +#if HAVE_OVERLAY +#include +#include + +// SERVER_OVERLAY_VISUALS property element: +struct OverlayInfo { + long overlay_visual; + long transparent_type; + long value; + long layer; +}; + +extern Colormap fl_overlay_colormap; +extern XVisualInfo* fl_overlay_visual; +extern ulong fl_transparent_pixel; + +XVisualInfo *fl_find_overlay_visual() { + static char beenhere; + if (beenhere) return fl_overlay_visual; + beenhere = 1; + + fl_open_display(); + Atom overlayVisualsAtom = + XInternAtom(fl_display,"SERVER_OVERLAY_VISUALS",1); + if (!overlayVisualsAtom) return 0; + OverlayInfo *overlayInfo; + ulong sizeData, bytesLeft; + Atom actualType; + int actualFormat; + if (XGetWindowProperty(fl_display, RootWindow(fl_display, fl_screen), + overlayVisualsAtom, 0L, 10000L, False, + overlayVisualsAtom, &actualType, &actualFormat, + &sizeData, &bytesLeft, + (unsigned char **) &overlayInfo)) return 0; + + if (actualType == overlayVisualsAtom && actualFormat == 32) { + int n = int(sizeData/4); + XVisualInfo* v = 0; + // find the greatest depth that has a transparent pixel: + for (int i = 0; i < n; i++) { + if (overlayInfo[i].transparent_type != 1) continue; + if (overlayInfo[i].layer <= 0) continue; + XVisualInfo templt; + templt.visualid = overlayInfo[i].overlay_visual; + int num; + XVisualInfo *v1=XGetVisualInfo(fl_display, VisualIDMask, &templt, &num); + if (v1->screen == fl_screen && v1->c_class == PseudoColor + && (!v || v1->depth > v->depth && v1->depth <= 8)) { + if (v) XFree((char*)v); + v = v1; + fl_transparent_pixel = overlayInfo[i].value; + } else { + XFree((char*)v1); + } + } + if (v) { + fl_overlay_visual = v; + fl_overlay_colormap = + XCreateColormap(fl_display, RootWindow(fl_display, fl_screen), + v->visual, AllocNone); + } + } + XFree((char*)overlayInfo); + //printf("overlay visual %ld selected\n", fl_overlay_visual->visualid); + return fl_overlay_visual; +} + +#endif + +// +// End of "$Id: fl_overlay_visual.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_plastic.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_plastic.cxx new file mode 100644 index 0000000..28a50c7 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_plastic.cxx @@ -0,0 +1,381 @@ +// +// "$Id: fl_plastic.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// "Plastic" drawing routines for the Fast Light Tool Kit (FLTK). +// +// These box types provide a cross between Aqua and KDE buttons; kindof +// like translucent plastic buttons... +// +// Copyright 2001-2010 by Michael Sweet. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Box drawing code for an obscure box type. +// These box types are in separate files so they are not linked +// in if not used. + +#include +#include +#include "flstring.h" + +// +// Uncomment the following line to restore the old plastic box type +// appearance. +// + +//#define USE_OLD_PLASTIC_BOX +#define USE_OLD_PLASTIC_COLOR + +extern uchar *fl_gray_ramp(); + +inline Fl_Color shade_color(uchar gc, Fl_Color bc) { +#ifdef USE_OLD_PLASTIC_COLOR + return fl_color_average((Fl_Color)gc, bc, 0.75f); +#else + unsigned grgb = Fl::get_color((Fl_Color)gc), + brgb = Fl::get_color(bc); + int red, green, blue, gray; + + + gray = ((grgb >> 24) & 255); + red = gray * ((brgb >> 24) & 255) / 255 + gray * gray / 510; + gray = ((grgb >> 16) & 255); + green = gray * ((brgb >> 16) & 255) / 255 + gray * gray / 510; + gray = ((grgb >> 8) & 255); + blue = gray * ((brgb >> 8) & 255) / 255 + gray * gray / 510; + + if (red > 255) + red = 255; + + if (green > 255) + green = 255; + + if (blue > 255) + blue = 255; + + if (Fl::draw_box_active()) + return fl_rgb_color(red, green, blue); + else + return fl_color_average(FL_GRAY, fl_rgb_color(red, green, blue), 0.75f); +#endif // USE_OLD_PLASTIC_COLOR +} + + +static void frame_rect(int x, int y, int w, int h, const char *c, Fl_Color bc) { + uchar *g = fl_gray_ramp(); + int b = strlen(c) / 4 + 1; + + for (x += b, y += b, w -= 2 * b, h -= 2 * b; b > 1; b --) + { + // Draw lines around the perimeter of the button, 4 colors per + // circuit. + fl_color(shade_color(g[(int)*c++], bc)); + fl_line(x, y + h + b, x + w - 1, y + h + b, x + w + b - 1, y + h); + fl_color(shade_color(g[(int)*c++], bc)); + fl_line(x + w + b - 1, y + h, x + w + b - 1, y, x + w - 1, y - b); + fl_color(shade_color(g[(int)*c++], bc)); + fl_line(x + w - 1, y - b, x, y - b, x - b, y); + fl_color(shade_color(g[(int)*c++], bc)); + fl_line(x - b, y, x - b, y + h, x, y + h + b); + } +} + + +static void frame_round(int x, int y, int w, int h, const char *c, Fl_Color bc) { + uchar *g = fl_gray_ramp(); + int b = strlen(c) / 4 + 1; + + if (w==h) { + for (; b > 1; b --, x ++, y ++, w -= 2, h -= 2) + { + fl_color(shade_color(g[(int)*c++], bc)); + fl_arc(x, y, w, h, 45.0, 135.0); + fl_color(shade_color(g[(int)*c++], bc)); + fl_arc(x, y, w, h, 315.0, 405.0); + fl_color(shade_color(g[(int)*c++], bc)); + fl_arc(x, y, w, h, 225.0, 315.0); + fl_color(shade_color(g[(int)*c++], bc)); + fl_arc(x, y, w, h, 135.0, 225.0); + } + } else if (w>h) { + int d = h/2; + for (; b > 1; d--, b --, x ++, y ++, w -= 2, h -= 2) + { + fl_color(shade_color(g[(int)*c++], bc)); + fl_arc(x, y, h, h, 90.0, 135.0); + fl_xyline(x+d, y, x+w-d); + fl_arc(x+w-h, y, h, h, 45.0, 90.0); + fl_color(shade_color(g[(int)*c++], bc)); + fl_arc(x+w-h, y, h, h, 315.0, 405.0); + fl_color(shade_color(g[(int)*c++], bc)); + fl_arc(x+w-h, y, h, h, 270.0, 315.0); + fl_xyline(x+d, y+h-1, x+w-d); + fl_arc(x, y, h, h, 225.0, 270.0); + fl_color(shade_color(g[(int)*c++], bc)); + fl_arc(x, y, h, h, 135.0, 225.0); + } + } else if (w 1; d--, b --, x ++, y ++, w -= 2, h -= 2) + { + fl_color(shade_color(g[(int)*c++], bc)); + fl_arc(x, y, w, w, 45.0, 135.0); + fl_color(shade_color(g[(int)*c++], bc)); + fl_arc(x, y, w, w, 0.0, 45.0); + fl_yxline(x+w-1, y+d, y+h-d); + fl_arc(x, y+h-w, w, w, 315.0, 360.0); + fl_color(shade_color(g[(int)*c++], bc)); + fl_arc(x, y+h-w, w, w, 225.0, 315.0); + fl_color(shade_color(g[(int)*c++], bc)); + fl_arc(x, y+h-w, w, w, 180.0, 225.0); + fl_yxline(x, y+d, y+h-d); + fl_arc(x, y, w, w, 135.0, 180.0); + } + } +} + + +static void shade_rect(int x, int y, int w, int h, const char *c, Fl_Color bc) { + uchar *g = fl_gray_ramp(); + int i, j; + int clen = strlen(c) - 1; + int chalf = clen / 2; + int cstep = 1; + + if (h < (w * 2)) { + // Horizontal shading... + if (clen >= h) cstep = 2; + + for (i = 0, j = 0; j < chalf; i ++, j += cstep) { + // Draw the top line and points... + fl_color(shade_color(g[(int)c[i]], bc)); + fl_xyline(x + 1, y + i, x + w - 2); + + fl_color(shade_color(g[c[i] - 2], bc)); + fl_point(x, y + i + 1); + fl_point(x + w - 1, y + i + 1); + + // Draw the bottom line and points... + fl_color(shade_color(g[(int)c[clen - i]], bc)); + fl_xyline(x + 1, y + h - i, x + w - 2); + + fl_color(shade_color(g[c[clen - i] - 2], bc)); + fl_point(x, y + h - i); + fl_point(x + w - 1, y + h - i); + } + + // Draw the interior and sides... + i = chalf / cstep; + + fl_color(shade_color(g[(int)c[chalf]], bc)); + fl_rectf(x + 1, y + i, w - 2, h - 2 * i + 1); + + fl_color(shade_color(g[c[chalf] - 2], bc)); + fl_yxline(x, y + i, y + h - i); + fl_yxline(x + w - 1, y + i, y + h - i); + } else { + // Vertical shading... + if (clen >= w) cstep = 2; + + for (i = 0, j = 0; j < chalf; i ++, j += cstep) { + // Draw the left line and points... + fl_color(shade_color(g[(int)c[i]], bc)); + fl_yxline(x + i, y + 1, y + h - 1); + + fl_color(shade_color(g[c[i] - 2], bc)); + fl_point(x + i + 1, y); + fl_point(x + i + 1, y + h); + + // Draw the right line and points... + fl_color(shade_color(g[(int)c[clen - i]], bc)); + fl_yxline(x + w - 1 - i, y + 1, y + h - 1); + + fl_color(shade_color(g[c[clen - i] - 2], bc)); + fl_point(x + w - 2 - i, y); + fl_point(x + w - 2 - i, y + h); + } + + // Draw the interior, top, and bottom... + i = chalf / cstep; + + fl_color(shade_color(g[(int)c[chalf]], bc)); + fl_rectf(x + i, y + 1, w - 2 * i, h - 1); + + fl_color(shade_color(g[c[chalf] - 2], bc)); + fl_xyline(x + i, y, x + w - i); + fl_xyline(x + i, y + h, x + w - i); + } +} + +static void shade_round(int x, int y, int w, int h, const char *c, Fl_Color bc) { + uchar *g = fl_gray_ramp(); + int i; + int clen = strlen(c) - 1; + int chalf = clen / 2; + + if (w>h) { + int d = h/2; + const int na = 8; + for (i=0; i 1) { + fl_xyline(x+1, y, x+w-2); + fl_xyline(x+1, y+h-1, x+w-2); + } + if (h > 1) { + fl_yxline(x, y+1, y+h-2); + fl_yxline(x+w-1, y+1, y+h-2); + } +} + + +static void thin_up_box(int x, int y, int w, int h, Fl_Color c) { +#ifdef USE_OLD_PLASTIC_BOX + shade_rect(x + 2, y + 2, w - 4, h - 5, "RVQNOPQRSTUVWVQ", c); + up_frame(x, y, w, h, c); +#else + if (w > 4 && h > 4) { + shade_rect(x + 1, y + 1, w - 2, h - 3, "RQOQSUWQ", c); + frame_rect(x, y, w, h - 1, "IJLM", c); + } else { + narrow_thin_box(x, y, w, h, c); + } +#endif // USE_OLD_PLASTIC_BOX +} + + +static void up_box(int x, int y, int w, int h, Fl_Color c) { +#ifdef USE_OLD_PLASTIC_BOX + shade_rect(x + 2, y + 2, w - 4, h - 5, "RVQNOPQRSTUVWVQ", c); + up_frame(x, y, w, h, c); +#else + if (w > 8 && h > 8) { + shade_rect(x + 1, y + 1, w - 2, h - 3, "RVQNOPQRSTUVWVQ", c); + frame_rect(x, y, w, h - 1, "IJLM", c); + } else { + thin_up_box(x, y, w, h, c); + } +#endif // USE_OLD_PLASTIC_BOX +} + + +static void up_round(int x, int y, int w, int h, Fl_Color c) { + shade_round(x, y, w, h, "RVQNOPQRSTUVWVQ", c); + frame_round(x, y, w, h, "IJLM", c); +} + + +static void down_frame(int x, int y, int w, int h, Fl_Color c) { + frame_rect(x, y, w, h - 1, "LLLLTTRR", c); +} + + +static void down_box(int x, int y, int w, int h, Fl_Color c) { + if (w > 6 && h > 6) { + shade_rect(x + 2, y + 2, w - 4, h - 5, "STUVWWWVT", c); + down_frame(x, y, w, h, c); + } + else { + narrow_thin_box(x, y, w, h, c); + } +} + + +static void down_round(int x, int y, int w, int h, Fl_Color c) { + shade_round(x, y, w, h, "STUVWWWVT", c); + frame_round(x, y, w, h, "IJLM", c); +} + + +extern void fl_internal_boxtype(Fl_Boxtype, Fl_Box_Draw_F*); + + +Fl_Boxtype fl_define_FL_PLASTIC_UP_BOX() { + fl_internal_boxtype(_FL_PLASTIC_UP_BOX, up_box); + fl_internal_boxtype(_FL_PLASTIC_DOWN_BOX, down_box); + fl_internal_boxtype(_FL_PLASTIC_UP_FRAME, up_frame); + fl_internal_boxtype(_FL_PLASTIC_DOWN_FRAME, down_frame); + fl_internal_boxtype(_FL_PLASTIC_THIN_UP_BOX, thin_up_box); + fl_internal_boxtype(_FL_PLASTIC_THIN_DOWN_BOX, down_box); + fl_internal_boxtype(_FL_PLASTIC_ROUND_UP_BOX, up_round); + fl_internal_boxtype(_FL_PLASTIC_ROUND_DOWN_BOX, down_round); + + return _FL_PLASTIC_UP_BOX; +} + + +// +// End of "$Id: fl_plastic.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_read_image.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_read_image.cxx new file mode 100644 index 0000000..2a90b7a --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_read_image.cxx @@ -0,0 +1,503 @@ +// +// "$Id: fl_read_image.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// X11 image reading routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include +#include "flstring.h" + +#ifdef DEBUG +# include +#endif // DEBUG + +#ifdef WIN32 +# include "fl_read_image_win32.cxx" +#elif defined(__APPLE__) +# include "fl_read_image_mac.cxx" +#else +# include +# ifdef __sgi +# include +# else +# include +# endif // __sgi + +// Defined in fl_color.cxx +extern uchar fl_redmask, fl_greenmask, fl_bluemask; +extern int fl_redshift, fl_greenshift, fl_blueshift, fl_extrashift; + +// +// 'fl_subimage_offsets()' - Calculate subimage offsets for an axis +static inline int +fl_subimage_offsets(int a, int aw, int b, int bw, int &obw) +{ + int off; + int ob; + + if (b >= a) { + ob = b; + off = 0; + } else { + ob = a; + off = a - b; + } + + bw -= off; + + if (ob + bw <= a + aw) { + obw = bw; + } else { + obw = (a + aw) - ob; + } + + return off; +} + +// this handler will catch and ignore exceptions during XGetImage +// to avoid an application crash +static int xgetimageerrhandler(Display *display, XErrorEvent *error) { + return 0; +} + +// +// 'fl_read_image()' - Read an image from the current window. +// + +uchar * // O - Pixel buffer or NULL if failed +fl_read_image(uchar *p, // I - Pixel buffer or NULL to allocate + int X, // I - Left position + int Y, // I - Top position + int w, // I - Width of area to read + int h, // I - Height of area to read + int alpha) { // I - Alpha value for image (0 for none) + XImage *image; // Captured image + int i, maxindex; // Looping vars + int x, y; // Current X & Y in image + int d; // Depth of image + unsigned char *line, // Array to hold image row + *line_ptr; // Pointer to current line image + unsigned char *pixel; // Current color value + XColor colors[4096]; // Colors from the colormap... + unsigned char cvals[4096][3]; // Color values from the colormap... + unsigned index_mask, + index_shift, + red_mask, + red_shift, + green_mask, + green_shift, + blue_mask, + blue_shift; + + + // + // Under X11 we have the option of the XGetImage() interface or SGI's + // ReadDisplay extension which does all of the really hard work for + // us... + // + +# ifdef __sgi + if (XReadDisplayQueryExtension(fl_display, &i, &i)) { + image = XReadDisplay(fl_display, fl_window, X, Y, w, h, 0, NULL); + } else +# else + image = 0; +# endif // __sgi + + if (!image) { + // fetch absolute coordinates + int dx, dy, sx, sy, sw, sh; + Window child_win; + Fl_Window *win = fl_find(fl_window); + if (win) { + XTranslateCoordinates(fl_display, fl_window, + RootWindow(fl_display, fl_screen), X, Y, &dx, &dy, &child_win); + // screen dimensions + Fl::screen_xywh(sx, sy, sw, sh, fl_screen); + } + if (!win || (dx >= sx && dy >= sy && dx + w <= sw && dy + h <= sh)) { + // the image is fully contained, we can use the traditional method + // however, if the window is obscured etc. the function will still fail. Make sure we + // catch the error and continue, otherwise an exception will be thrown. + XErrorHandler old_handler = XSetErrorHandler(xgetimageerrhandler); + image = XGetImage(fl_display, fl_window, X, Y, w, h, AllPlanes, ZPixmap); + XSetErrorHandler(old_handler); + } else { + // image is crossing borders, determine visible region + int nw, nh, noffx, noffy; + noffx = fl_subimage_offsets(sx, sw, dx, w, nw); + noffy = fl_subimage_offsets(sy, sh, dy, h, nh); + if (nw <= 0 || nh <= 0) return 0; + + // allocate the image + int bpp = fl_visual->depth + ((fl_visual->depth / 8) % 2) * 8; + char* buf = (char*)malloc(bpp / 8 * w * h); + image = XCreateImage(fl_display, fl_visual->visual, + fl_visual->depth, ZPixmap, 0, buf, w, h, bpp, 0); + if (!image) { + if (buf) free(buf); + return 0; + } + + XErrorHandler old_handler = XSetErrorHandler(xgetimageerrhandler); + XImage *subimg = XGetSubImage(fl_display, fl_window, X + noffx, Y + noffy, + nw, nh, AllPlanes, ZPixmap, image, noffx, noffy); + XSetErrorHandler(old_handler); + if (!subimg) { + XDestroyImage(image); + return 0; + } + } + } + + if (!image) return 0; + +#ifdef DEBUG + printf("width = %d\n", image->width); + printf("height = %d\n", image->height); + printf("xoffset = %d\n", image->xoffset); + printf("format = %d\n", image->format); + printf("data = %p\n", image->data); + printf("byte_order = %d\n", image->byte_order); + printf("bitmap_unit = %d\n", image->bitmap_unit); + printf("bitmap_bit_order = %d\n", image->bitmap_bit_order); + printf("bitmap_pad = %d\n", image->bitmap_pad); + printf("depth = %d\n", image->depth); + printf("bytes_per_line = %d\n", image->bytes_per_line); + printf("bits_per_pixel = %d\n", image->bits_per_pixel); + printf("red_mask = %08x\n", image->red_mask); + printf("green_mask = %08x\n", image->green_mask); + printf("blue_mask = %08x\n", image->blue_mask); + printf("map_entries = %d\n", fl_visual->visual->map_entries); +#endif // DEBUG + + d = alpha ? 4 : 3; + + // Allocate the image data array as needed... + if (!p) p = new uchar[w * h * d]; + + // Initialize the default colors/alpha in the whole image... + memset(p, alpha, w * h * d); + + // Check that we have valid mask/shift values... + if (!image->red_mask && image->bits_per_pixel > 12) { + // Greater than 12 bits must be TrueColor... + image->red_mask = fl_visual->visual->red_mask; + image->green_mask = fl_visual->visual->green_mask; + image->blue_mask = fl_visual->visual->blue_mask; + +#ifdef DEBUG + puts("\n---- UPDATED ----"); + printf("fl_redmask = %08x\n", fl_redmask); + printf("fl_redshift = %d\n", fl_redshift); + printf("fl_greenmask = %08x\n", fl_greenmask); + printf("fl_greenshift = %d\n", fl_greenshift); + printf("fl_bluemask = %08x\n", fl_bluemask); + printf("fl_blueshift = %d\n", fl_blueshift); + printf("red_mask = %08x\n", image->red_mask); + printf("green_mask = %08x\n", image->green_mask); + printf("blue_mask = %08x\n", image->blue_mask); +#endif // DEBUG + } + + // Check if we have colormap image... + if (!image->red_mask) { + // Get the colormap entries for this window... + maxindex = fl_visual->visual->map_entries; + + for (i = 0; i < maxindex; i ++) colors[i].pixel = i; + + XQueryColors(fl_display, fl_colormap, colors, maxindex); + + for (i = 0; i < maxindex; i ++) { + cvals[i][0] = colors[i].red >> 8; + cvals[i][1] = colors[i].green >> 8; + cvals[i][2] = colors[i].blue >> 8; + } + + // Read the pixels and output an RGB image... + for (y = 0; y < image->height; y ++) { + pixel = (unsigned char *)(image->data + y * image->bytes_per_line); + line = p + y * w * d; + + switch (image->bits_per_pixel) { + case 1 : + for (x = image->width, line_ptr = line, index_mask = 128; + x > 0; + x --, line_ptr += d) { + if (*pixel & index_mask) { + line_ptr[0] = cvals[1][0]; + line_ptr[1] = cvals[1][1]; + line_ptr[2] = cvals[1][2]; + } else { + line_ptr[0] = cvals[0][0]; + line_ptr[1] = cvals[0][1]; + line_ptr[2] = cvals[0][2]; + } + + if (index_mask > 1) { + index_mask >>= 1; + } else { + index_mask = 128; + pixel ++; + } + } + break; + + case 2 : + for (x = image->width, line_ptr = line, index_shift = 6; + x > 0; + x --, line_ptr += d) { + i = (*pixel >> index_shift) & 3; + + line_ptr[0] = cvals[i][0]; + line_ptr[1] = cvals[i][1]; + line_ptr[2] = cvals[i][2]; + + if (index_shift > 0) { + index_mask >>= 2; + index_shift -= 2; + } else { + index_mask = 192; + index_shift = 6; + pixel ++; + } + } + break; + + case 4 : + for (x = image->width, line_ptr = line, index_shift = 4; + x > 0; + x --, line_ptr += d) { + if (index_shift == 4) i = (*pixel >> 4) & 15; + else i = *pixel & 15; + + line_ptr[0] = cvals[i][0]; + line_ptr[1] = cvals[i][1]; + line_ptr[2] = cvals[i][2]; + + if (index_shift > 0) { + index_shift = 0; + } else { + index_shift = 4; + pixel ++; + } + } + break; + + case 8 : + for (x = image->width, line_ptr = line; + x > 0; + x --, line_ptr += d, pixel ++) { + line_ptr[0] = cvals[*pixel][0]; + line_ptr[1] = cvals[*pixel][1]; + line_ptr[2] = cvals[*pixel][2]; + } + break; + + case 12 : + for (x = image->width, line_ptr = line, index_shift = 0; + x > 0; + x --, line_ptr += d) { + if (index_shift == 0) { + i = ((pixel[0] << 4) | (pixel[1] >> 4)) & 4095; + } else { + i = ((pixel[1] << 8) | pixel[2]) & 4095; + } + + line_ptr[0] = cvals[i][0]; + line_ptr[1] = cvals[i][1]; + line_ptr[2] = cvals[i][2]; + + if (index_shift == 0) { + index_shift = 4; + } else { + index_shift = 0; + pixel += 3; + } + } + break; + } + } + } else { + // RGB(A) image, so figure out the shifts & masks... + red_mask = image->red_mask; + red_shift = 0; + + while ((red_mask & 1) == 0) { + red_mask >>= 1; + red_shift ++; + } + + green_mask = image->green_mask; + green_shift = 0; + + while ((green_mask & 1) == 0) { + green_mask >>= 1; + green_shift ++; + } + + blue_mask = image->blue_mask; + blue_shift = 0; + + while ((blue_mask & 1) == 0) { + blue_mask >>= 1; + blue_shift ++; + } + + // Read the pixels and output an RGB image... + for (y = 0; y < image->height; y ++) { + pixel = (unsigned char *)(image->data + y * image->bytes_per_line); + line = p + y * w * d; + + switch (image->bits_per_pixel) { + case 8 : + for (x = image->width, line_ptr = line; + x > 0; + x --, line_ptr += d, pixel ++) { + i = *pixel; + + line_ptr[0] = 255 * ((i >> red_shift) & red_mask) / red_mask; + line_ptr[1] = 255 * ((i >> green_shift) & green_mask) / green_mask; + line_ptr[2] = 255 * ((i >> blue_shift) & blue_mask) / blue_mask; + } + break; + + case 12 : + for (x = image->width, line_ptr = line, index_shift = 0; + x > 0; + x --, line_ptr += d) { + if (index_shift == 0) { + i = ((pixel[0] << 4) | (pixel[1] >> 4)) & 4095; + } else { + i = ((pixel[1] << 8) | pixel[2]) & 4095; + } + + line_ptr[0] = 255 * ((i >> red_shift) & red_mask) / red_mask; + line_ptr[1] = 255 * ((i >> green_shift) & green_mask) / green_mask; + line_ptr[2] = 255 * ((i >> blue_shift) & blue_mask) / blue_mask; + + if (index_shift == 0) { + index_shift = 4; + } else { + index_shift = 0; + pixel += 3; + } + } + break; + + case 16 : + if (image->byte_order == LSBFirst) { + // Little-endian... + for (x = image->width, line_ptr = line; + x > 0; + x --, line_ptr += d, pixel += 2) { + i = (pixel[1] << 8) | pixel[0]; + + line_ptr[0] = 255 * ((i >> red_shift) & red_mask) / red_mask; + line_ptr[1] = 255 * ((i >> green_shift) & green_mask) / green_mask; + line_ptr[2] = 255 * ((i >> blue_shift) & blue_mask) / blue_mask; + } + } else { + // Big-endian... + for (x = image->width, line_ptr = line; + x > 0; + x --, line_ptr += d, pixel += 2) { + i = (pixel[0] << 8) | pixel[1]; + + line_ptr[0] = 255 * ((i >> red_shift) & red_mask) / red_mask; + line_ptr[1] = 255 * ((i >> green_shift) & green_mask) / green_mask; + line_ptr[2] = 255 * ((i >> blue_shift) & blue_mask) / blue_mask; + } + } + break; + + case 24 : + if (image->byte_order == LSBFirst) { + // Little-endian... + for (x = image->width, line_ptr = line; + x > 0; + x --, line_ptr += d, pixel += 3) { + i = (((pixel[2] << 8) | pixel[1]) << 8) | pixel[0]; + + line_ptr[0] = 255 * ((i >> red_shift) & red_mask) / red_mask; + line_ptr[1] = 255 * ((i >> green_shift) & green_mask) / green_mask; + line_ptr[2] = 255 * ((i >> blue_shift) & blue_mask) / blue_mask; + } + } else { + // Big-endian... + for (x = image->width, line_ptr = line; + x > 0; + x --, line_ptr += d, pixel += 3) { + i = (((pixel[0] << 8) | pixel[1]) << 8) | pixel[2]; + + line_ptr[0] = 255 * ((i >> red_shift) & red_mask) / red_mask; + line_ptr[1] = 255 * ((i >> green_shift) & green_mask) / green_mask; + line_ptr[2] = 255 * ((i >> blue_shift) & blue_mask) / blue_mask; + } + } + break; + + case 32 : + if (image->byte_order == LSBFirst) { + // Little-endian... + for (x = image->width, line_ptr = line; + x > 0; + x --, line_ptr += d, pixel += 4) { + i = (((((pixel[3] << 8) | pixel[2]) << 8) | pixel[1]) << 8) | pixel[0]; + + line_ptr[0] = 255 * ((i >> red_shift) & red_mask) / red_mask; + line_ptr[1] = 255 * ((i >> green_shift) & green_mask) / green_mask; + line_ptr[2] = 255 * ((i >> blue_shift) & blue_mask) / blue_mask; + } + } else { + // Big-endian... + for (x = image->width, line_ptr = line; + x > 0; + x --, line_ptr += d, pixel += 4) { + i = (((((pixel[0] << 8) | pixel[1]) << 8) | pixel[2]) << 8) | pixel[3]; + + line_ptr[0] = 255 * ((i >> red_shift) & red_mask) / red_mask; + line_ptr[1] = 255 * ((i >> green_shift) & green_mask) / green_mask; + line_ptr[2] = 255 * ((i >> blue_shift) & blue_mask) / blue_mask; + } + } + break; + } + } + } + + // Destroy the X image we've read and return the RGB(A) image... + XDestroyImage(image); + + return p; +} + +#endif + +// +// End of "$Id: fl_read_image.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_read_image_mac.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_read_image_mac.cxx new file mode 100644 index 0000000..00e9a4f --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_read_image_mac.cxx @@ -0,0 +1,83 @@ +// +// "$Id: fl_read_image_mac.cxx 7670 2010-07-09 17:29:35Z manolo $" +// +// WIN32 image reading routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2009 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +extern unsigned char *MACbitmapFromRectOfWindow(Fl_Window *win, int x, int y, int w, int h, int *bytesPerPixel); + +// +// 'fl_read_image()' - Read an image from the current window or off-screen buffer. +// + +uchar * // O - Pixel buffer or NULL if failed +fl_read_image(uchar *p, // I - Pixel buffer or NULL to allocate + int x, // I - Left position + int y, // I - Top position + int w, // I - Width of area to read + int h, // I - Height of area to read + int alpha) { // I - Alpha value for image (0 for none) + uchar *base; + int rowBytes, delta; + if(fl_window == NULL) { // reading from an offscreen buffer + CGContextRef src = (CGContextRef)fl_gc; // get bitmap context + base = (uchar *)CGBitmapContextGetData(src); // get data + if(!base) return NULL; + int sw = CGBitmapContextGetWidth(src); + int sh = CGBitmapContextGetHeight(src); + rowBytes = CGBitmapContextGetBytesPerRow(src); + delta = CGBitmapContextGetBitsPerPixel(src)/8; + if( (sw - x < w) || (sh - y < h) ) return NULL; + } + else { // reading from current window + Fl_Window *window = Fl_Window::current(); + while(window->window()) window = window->window(); + base = MACbitmapFromRectOfWindow(window,x,y,w,h,&delta); + rowBytes = delta*w; + x = y = 0; + } + // Allocate the image data array as needed... + int d = alpha ? 4 : 3; + if (!p) p = new uchar[w * h * d]; + // Initialize the default colors/alpha in the whole image... + memset(p, alpha, w * h * d); + // Copy the image from the off-screen buffer to the memory buffer. + int idx, idy; // Current X & Y in image + uchar *pdst, *psrc; + for (idy = y, pdst = p; idy < h + y; idy ++) { + for (idx = 0, psrc = base + idy * rowBytes + x * delta; idx < w; idx ++, psrc += delta, pdst += d) { + pdst[0] = psrc[0]; // R + pdst[1] = psrc[1]; // G + pdst[2] = psrc[2]; // B + } + } + if(fl_window != NULL) delete base; + return p; +} + + +// +// End of "$Id: fl_read_image_mac.cxx 7670 2010-07-09 17:29:35Z manolo $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_read_image_win32.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_read_image_win32.cxx new file mode 100644 index 0000000..d3ef8ec --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_read_image_win32.cxx @@ -0,0 +1,72 @@ +// +// "$Id: fl_read_image_win32.cxx 6616 2009-01-01 21:28:26Z matt $" +// +// WIN32 image reading routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2009 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// +// 'fl_read_image()' - Read an image from the current window. +// + +uchar * // O - Pixel buffer or NULL if failed +fl_read_image(uchar *p, // I - Pixel buffer or NULL to allocate + int X, // I - Left position + int Y, // I - Top position + int w, // I - Width of area to read + int h, // I - Height of area to read + int alpha) { // I - Alpha value for image (0 for none) + int x, y; // Looping vars + int d; // Depth of image + uchar *ptr; // Pointer in image data + + + // Allocate the image data array as needed... + d = alpha ? 4 : 3; + + if (!p) p = new uchar[w * h * d]; + + // Initialize the default colors/alpha in the whole image... + memset(p, alpha, w * h * d); + + // Grab all of the pixels in the image, one at a time... + // MRS: there has to be a better way than this! + for (y = 0, ptr = p; y < h; y ++) { + for (x = 0; x < w; x ++, ptr += d) { + COLORREF c = GetPixel(fl_gc, X + x, Y + y); + + ptr[0] = (uchar)c; + c >>= 8; + ptr[1] = (uchar)c; + c >>= 8; + ptr[2] = (uchar)c; + } + } + + return p; +} + + +// +// End of "$Id: fl_read_image_win32.cxx 6616 2009-01-01 21:28:26Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_rect.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_rect.cxx new file mode 100644 index 0000000..bcea225 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_rect.cxx @@ -0,0 +1,727 @@ +// +// "$Id: fl_rect.cxx 7889 2010-11-23 17:37:49Z AlbrechtS $" +// +// Rectangle drawing routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/** + \file fl_rect.cxx + \brief Drawing and clipping routines for rectangles. +*/ + +// These routines from fl_draw.H are used by the standard boxtypes +// and thus are always linked into an fltk program. +// Also all fl_clip routines, since they are always linked in so +// that minimal update works. + +#include +#include +#include +#include +#include +#include + +// fl_line_width_ must contain the absolute value of the current +// line width to be used for X11 clipping (see below). +// This is defined in src/fl_line_style.cxx +extern int fl_line_width_; + +#ifdef __APPLE_QUARTZ__ +extern float fl_quartz_line_width_; +#define USINGQUARTZPRINTER (Fl_Surface_Device::surface()->type() == Fl_Printer::device_type) +#endif + +#ifdef USE_X11 + +#ifndef SHRT_MAX +#define SHRT_MAX (32767) +#endif + +/* + We need to check some coordinates for areas for clipping before we + use X functions, because X can't handle coordinates outside the 16-bit + range. Since all windows use relative coordinates > 0, we do also + check for negative values. X11 only, see also STR #2304. + + Note that this is only necessary for large objects, where only a + part of the object is visible. The draw() functions (e.g. box + drawing) must be clipped correctly. This is usually only a matter + for large container widgets. The individual child widgets will be + clipped completely. + + We define the usable X coordinate space as [ -LW : SHRT_MAX - LW ] + where LW = current line width for drawing. This is done so that + horizontal and vertical line drawing works correctly, even in real + border cases, e.g. drawing a rectangle slightly outside the top left + window corner, but with a line width so that a part of the line should + be visible (in this case 2 of 5 pixels): + + fl_line_style (FL_SOLID,5); // line width = 5 + fl_rect (-1,-1,100,100); // top/left: 2 pixels visible + + In this example case, no clipping would be done, because X can + handle it and clip unneeded pixels. + + Todo: Arbitrary line drawings (e.g. polygons) and clip regions + are not yet done. + + Note: + + We could use max. screen coordinates instead of SHRT_MAX, but that + would need more work and would probably be slower. We assume that + all window coordinates are >= 0 and that no window extends up to + 32767 - LW (where LW = current line width). Thus it is safe to clip + all coordinates to this range before calling X functions. If this + is not true, then clip_to_short() and clip_x() must be redefined. + + It would be somewhat easier if we had fl_clip_w and fl_clip_h, as + defined in FLTK 2.0 (for the upper clipping bounds)... +*/ + +/* + clip_to_short() returns 1, if the area is invisible (clipped), + because ... + + (a) w or h are <= 0 i.e. nothing is visible + (b) x+w or y+h are < kmin i.e. left of or above visible area + (c) x or y are > kmax i.e. right of or below visible area + + kmin and kmax are the minimal and maximal X coordinate values, + as defined above. In this case x, y, w, and h are not changed. + + It returns 0, if the area is potentially visible and X can handle + clipping. x, y, w, and h may have been adjusted to fit into the + X coordinate space. + + Use this for clipping rectangles, as used in fl_rect() and + fl_rectf(). +*/ + +static int clip_to_short(int &x, int &y, int &w, int &h) { + + int kmin = -fl_line_width_; + int kmax = SHRT_MAX - fl_line_width_; + + if (w <= 0 || h <= 0) return 1; // (a) + if (x+w < kmin || y+h < kmin) return 1; // (b) + if (x > kmax || y > kmax) return 1; // (c) + + if (x < kmin) { w -= (kmin-x); x = kmin; } + if (y < kmin) { h -= (kmin-y); y = kmin; } + if (x+w > kmax) w = kmax - x; + if (y+h > kmax) h = kmax - y; + + return 0; +} + +/* + clip_x() returns a coordinate value clipped to the 16-bit coordinate + space (see above). This can be used to draw horizontal and vertical + lines that can be handled by X11. Each single coordinate value can + be clipped individually, and the result can be used directly, e.g. + in fl_xyline() and fl_yxline(). Note that this can't be used for + arbitrary lines (not horizontal or vertical). +*/ +static int clip_x (int x) { + + int kmin = -fl_line_width_; + int kmax = SHRT_MAX - fl_line_width_; + + if (x < kmin) + x = kmin; + else if (x > kmax) + x = kmax; + return x; +} + +#endif // USE_X11 + + +void Fl_Graphics_Driver::rect(int x, int y, int w, int h) { + + if (w<=0 || h<=0) return; +#if defined(USE_X11) + if (!clip_to_short(x, y, w, h)) + XDrawRectangle(fl_display, fl_window, fl_gc, x, y, w-1, h-1); +#elif defined(WIN32) + MoveToEx(fl_gc, x, y, 0L); + LineTo(fl_gc, x+w-1, y); + LineTo(fl_gc, x+w-1, y+h-1); + LineTo(fl_gc, x, y+h-1); + LineTo(fl_gc, x, y); +#elif defined(__APPLE_QUARTZ__) + if (USINGQUARTZPRINTER || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, true); + CGRect rect = CGRectMake(x, y, w-1, h-1); + CGContextStrokeRect(fl_gc, rect); + if (USINGQUARTZPRINTER || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, false); +#else +# error unsupported platform +#endif +} + +void Fl_Graphics_Driver::rectf(int x, int y, int w, int h) { + if (w<=0 || h<=0) return; +#if defined(USE_X11) + if (!clip_to_short(x, y, w, h)) + XFillRectangle(fl_display, fl_window, fl_gc, x, y, w, h); +#elif defined(WIN32) + RECT rect; + rect.left = x; rect.top = y; + rect.right = x + w; rect.bottom = y + h; + FillRect(fl_gc, &rect, fl_brush()); +#elif defined(__APPLE_QUARTZ__) + if (USINGQUARTZPRINTER || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, true); + CGRect rect = CGRectMake(x, y, w-1, h-1); + CGContextFillRect(fl_gc, rect); + if (USINGQUARTZPRINTER || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, false); +#else +# error unsupported platform +#endif +} + +void Fl_Graphics_Driver::xyline(int x, int y, int x1) { +#if defined(USE_X11) + XDrawLine(fl_display, fl_window, fl_gc, clip_x(x), clip_x(y), clip_x(x1), clip_x(y)); +#elif defined(WIN32) + MoveToEx(fl_gc, x, y, 0L); LineTo(fl_gc, x1+1, y); +#elif defined(__APPLE_QUARTZ__) + if (USINGQUARTZPRINTER || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, true); + CGContextMoveToPoint(fl_gc, x, y); + CGContextAddLineToPoint(fl_gc, x1, y); + CGContextStrokePath(fl_gc); + if (USINGQUARTZPRINTER || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, false); +#else +# error unsupported platform +#endif +} + +void Fl_Graphics_Driver::xyline(int x, int y, int x1, int y2) { +#if defined (USE_X11) + XPoint p[3]; + p[0].x = clip_x(x); p[0].y = p[1].y = clip_x(y); + p[1].x = p[2].x = clip_x(x1); p[2].y = clip_x(y2); + XDrawLines(fl_display, fl_window, fl_gc, p, 3, 0); +#elif defined(WIN32) + if (y2 < y) y2--; + else y2++; + MoveToEx(fl_gc, x, y, 0L); + LineTo(fl_gc, x1, y); + LineTo(fl_gc, x1, y2); +#elif defined(__APPLE_QUARTZ__) + if (USINGQUARTZPRINTER || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, true); + CGContextMoveToPoint(fl_gc, x, y); + CGContextAddLineToPoint(fl_gc, x1, y); + CGContextAddLineToPoint(fl_gc, x1, y2); + CGContextStrokePath(fl_gc); + if (USINGQUARTZPRINTER || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, false); +#else +#error unsupported platform +#endif +} + +void Fl_Graphics_Driver::xyline(int x, int y, int x1, int y2, int x3) { +#if defined(USE_X11) + XPoint p[4]; + p[0].x = clip_x(x); p[0].y = p[1].y = clip_x(y); + p[1].x = p[2].x = clip_x(x1); p[2].y = p[3].y = clip_x(y2); + p[3].x = clip_x(x3); + XDrawLines(fl_display, fl_window, fl_gc, p, 4, 0); +#elif defined(WIN32) + if(x3 < x1) x3--; + else x3++; + MoveToEx(fl_gc, x, y, 0L); + LineTo(fl_gc, x1, y); + LineTo(fl_gc, x1, y2); + LineTo(fl_gc, x3, y2); +#elif defined(__APPLE_QUARTZ__) + if (USINGQUARTZPRINTER || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, true); + CGContextMoveToPoint(fl_gc, x, y); + CGContextAddLineToPoint(fl_gc, x1, y); + CGContextAddLineToPoint(fl_gc, x1, y2); + CGContextAddLineToPoint(fl_gc, x3, y2); + CGContextStrokePath(fl_gc); + if (USINGQUARTZPRINTER || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, false); +#else +# error unsupported platform +#endif +} + +void Fl_Graphics_Driver::yxline(int x, int y, int y1) { +#if defined(USE_X11) + XDrawLine(fl_display, fl_window, fl_gc, clip_x(x), clip_x(y), clip_x(x), clip_x(y1)); +#elif defined(WIN32) + if (y1 < y) y1--; + else y1++; + MoveToEx(fl_gc, x, y, 0L); LineTo(fl_gc, x, y1); +#elif defined(__APPLE_QUARTZ__) + if (USINGQUARTZPRINTER || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, true); + CGContextMoveToPoint(fl_gc, x, y); + CGContextAddLineToPoint(fl_gc, x, y1); + CGContextStrokePath(fl_gc); + if (USINGQUARTZPRINTER || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, false); +#else +# error unsupported platform +#endif +} + +void Fl_Graphics_Driver::yxline(int x, int y, int y1, int x2) { +#if defined(USE_X11) + XPoint p[3]; + p[0].x = p[1].x = clip_x(x); p[0].y = clip_x(y); + p[1].y = p[2].y = clip_x(y1); p[2].x = clip_x(x2); + XDrawLines(fl_display, fl_window, fl_gc, p, 3, 0); +#elif defined(WIN32) + if (x2 > x) x2++; + else x2--; + MoveToEx(fl_gc, x, y, 0L); + LineTo(fl_gc, x, y1); + LineTo(fl_gc, x2, y1); +#elif defined(__APPLE_QUARTZ__) + if (USINGQUARTZPRINTER || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, true); + CGContextMoveToPoint(fl_gc, x, y); + CGContextAddLineToPoint(fl_gc, x, y1); + CGContextAddLineToPoint(fl_gc, x2, y1); + CGContextStrokePath(fl_gc); + if (USINGQUARTZPRINTER || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, false); +#else +# error unsupported platform +#endif +} + +void Fl_Graphics_Driver::yxline(int x, int y, int y1, int x2, int y3) { +#if defined(USE_X11) + XPoint p[4]; + p[0].x = p[1].x = clip_x(x); p[0].y = clip_x(y); + p[1].y = p[2].y = clip_x(y1); p[2].x = p[3].x = clip_x(x2); + p[3].y = clip_x(y3); + XDrawLines(fl_display, fl_window, fl_gc, p, 4, 0); +#elif defined(WIN32) + if(y3 1.5f) CGContextSetShouldAntialias(fl_gc, true); + CGContextMoveToPoint(fl_gc, x, y); + CGContextAddLineToPoint(fl_gc, x, y1); + CGContextAddLineToPoint(fl_gc, x2, y1); + CGContextAddLineToPoint(fl_gc, x2, y3); + CGContextStrokePath(fl_gc); + if (USINGQUARTZPRINTER || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, false); +#else +# error unsupported platform +#endif +} + +void Fl_Graphics_Driver::line(int x, int y, int x1, int y1) { +#if defined(USE_X11) + XDrawLine(fl_display, fl_window, fl_gc, x, y, x1, y1); +#elif defined(WIN32) + MoveToEx(fl_gc, x, y, 0L); + LineTo(fl_gc, x1, y1); + // Draw the last point *again* because the GDI line drawing + // functions will not draw the last point ("it's a feature!"...) + SetPixel(fl_gc, x1, y1, fl_RGB()); +#elif defined(__APPLE_QUARTZ__) + if (fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, true); + CGContextMoveToPoint(fl_gc, x, y); + CGContextAddLineToPoint(fl_gc, x1, y1); + CGContextStrokePath(fl_gc); + if (fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, false); +#else +# error unsupported platform +#endif +} + +void Fl_Graphics_Driver::line(int x, int y, int x1, int y1, int x2, int y2) { +#if defined(USE_X11) + XPoint p[3]; + p[0].x = x; p[0].y = y; + p[1].x = x1; p[1].y = y1; + p[2].x = x2; p[2].y = y2; + XDrawLines(fl_display, fl_window, fl_gc, p, 3, 0); +#elif defined(WIN32) + MoveToEx(fl_gc, x, y, 0L); + LineTo(fl_gc, x1, y1); + LineTo(fl_gc, x2, y2); + // Draw the last point *again* because the GDI line drawing + // functions will not draw the last point ("it's a feature!"...) + SetPixel(fl_gc, x2, y2, fl_RGB()); +#elif defined(__APPLE_QUARTZ__) + if (fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, true); + CGContextMoveToPoint(fl_gc, x, y); + CGContextAddLineToPoint(fl_gc, x1, y1); + CGContextAddLineToPoint(fl_gc, x2, y2); + CGContextStrokePath(fl_gc); + if (fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, false); +#else +# error unsupported platform +#endif +} + +void Fl_Graphics_Driver::loop(int x, int y, int x1, int y1, int x2, int y2) { +#if defined(USE_X11) + XPoint p[4]; + p[0].x = x; p[0].y = y; + p[1].x = x1; p[1].y = y1; + p[2].x = x2; p[2].y = y2; + p[3].x = x; p[3].y = y; + XDrawLines(fl_display, fl_window, fl_gc, p, 4, 0); +#elif defined(WIN32) + MoveToEx(fl_gc, x, y, 0L); + LineTo(fl_gc, x1, y1); + LineTo(fl_gc, x2, y2); + LineTo(fl_gc, x, y); +#elif defined(__APPLE_QUARTZ__) + CGContextSetShouldAntialias(fl_gc, true); + CGContextMoveToPoint(fl_gc, x, y); + CGContextAddLineToPoint(fl_gc, x1, y1); + CGContextAddLineToPoint(fl_gc, x2, y2); + CGContextClosePath(fl_gc); + CGContextStrokePath(fl_gc); + CGContextSetShouldAntialias(fl_gc, false); +#else +# error unsupported platform +#endif +} + +void Fl_Graphics_Driver::loop(int x, int y, int x1, int y1, int x2, int y2, int x3, int y3) { +#if defined(USE_X11) + XPoint p[5]; + p[0].x = x; p[0].y = y; + p[1].x = x1; p[1].y = y1; + p[2].x = x2; p[2].y = y2; + p[3].x = x3; p[3].y = y3; + p[4].x = x; p[4].y = y; + XDrawLines(fl_display, fl_window, fl_gc, p, 5, 0); +#elif defined(WIN32) + MoveToEx(fl_gc, x, y, 0L); + LineTo(fl_gc, x1, y1); + LineTo(fl_gc, x2, y2); + LineTo(fl_gc, x3, y3); + LineTo(fl_gc, x, y); +#elif defined(__APPLE_QUARTZ__) + CGContextSetShouldAntialias(fl_gc, true); + CGContextMoveToPoint(fl_gc, x, y); + CGContextAddLineToPoint(fl_gc, x1, y1); + CGContextAddLineToPoint(fl_gc, x2, y2); + CGContextAddLineToPoint(fl_gc, x3, y3); + CGContextClosePath(fl_gc); + CGContextStrokePath(fl_gc); + CGContextSetShouldAntialias(fl_gc, false); +#else +# error unsupported platform +#endif +} + +void Fl_Graphics_Driver::polygon(int x, int y, int x1, int y1, int x2, int y2) { + XPoint p[4]; + p[0].x = x; p[0].y = y; + p[1].x = x1; p[1].y = y1; + p[2].x = x2; p[2].y = y2; +#if defined (USE_X11) + p[3].x = x; p[3].y = y; + XFillPolygon(fl_display, fl_window, fl_gc, p, 3, Convex, 0); + XDrawLines(fl_display, fl_window, fl_gc, p, 4, 0); +#elif defined(WIN32) + SelectObject(fl_gc, fl_brush()); + Polygon(fl_gc, p, 3); +#elif defined(__APPLE_QUARTZ__) + CGContextSetShouldAntialias(fl_gc, true); + CGContextMoveToPoint(fl_gc, x, y); + CGContextAddLineToPoint(fl_gc, x1, y1); + CGContextAddLineToPoint(fl_gc, x2, y2); + CGContextClosePath(fl_gc); + CGContextFillPath(fl_gc); + CGContextSetShouldAntialias(fl_gc, false); +#else +# error unsupported platform +#endif +} + +void Fl_Graphics_Driver::polygon(int x, int y, int x1, int y1, int x2, int y2, int x3, int y3) { + XPoint p[5]; + p[0].x = x; p[0].y = y; + p[1].x = x1; p[1].y = y1; + p[2].x = x2; p[2].y = y2; + p[3].x = x3; p[3].y = y3; +#if defined(USE_X11) + p[4].x = x; p[4].y = y; + XFillPolygon(fl_display, fl_window, fl_gc, p, 4, Convex, 0); + XDrawLines(fl_display, fl_window, fl_gc, p, 5, 0); +#elif defined(WIN32) + SelectObject(fl_gc, fl_brush()); + Polygon(fl_gc, p, 4); +#elif defined(__APPLE_QUARTZ__) + CGContextSetShouldAntialias(fl_gc, true); + CGContextMoveToPoint(fl_gc, x, y); + CGContextAddLineToPoint(fl_gc, x1, y1); + CGContextAddLineToPoint(fl_gc, x2, y2); + CGContextAddLineToPoint(fl_gc, x3, y3); + CGContextClosePath(fl_gc); + CGContextFillPath(fl_gc); + CGContextSetShouldAntialias(fl_gc, false); +#else +# error unsupported platform +#endif +} + +void Fl_Graphics_Driver::point(int x, int y) { +#if defined(USE_X11) + XDrawPoint(fl_display, fl_window, fl_gc, clip_x(x), clip_x(y)); +#elif defined(WIN32) + SetPixel(fl_gc, x, y, fl_RGB()); +#elif defined(__APPLE_QUARTZ__) + if (fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, true); + CGContextMoveToPoint(fl_gc, x-.5, y); // Quartz needs a line that is one pixel long, or it will not draw anything + CGContextAddLineToPoint(fl_gc, x+.5, y); + CGContextStrokePath(fl_gc); + if (fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, false); +#else +# error unsupported platform +#endif +} + +//////////////////////////////////////////////////////////////// + +#define STACK_SIZE 64 +#define STACK_MAX (STACK_SIZE - 1) +static Fl_Region rstack[STACK_SIZE]; +static int rstackptr=0; +int fl_clip_state_number=0; // used by gl_begin.cxx to update GL clip + +#if !defined(WIN32) && !defined(__APPLE__) +// Missing X call: (is this the fastest way to init a 1-rectangle region?) +// MSWindows equivalent exists, implemented inline in win32.H +Fl_Region XRectangleRegion(int x, int y, int w, int h) { + XRectangle R; + clip_to_short(x, y, w, h); + R.x = x; R.y = y; R.width = w; R.height = h; + Fl_Region r = XCreateRegion(); + XUnionRectWithRegion(&R, r, r); + return r; +} +#endif + +void fl_restore_clip() { + fl_clip_state_number++; + Fl_Region r = rstack[rstackptr]; +#if defined(USE_X11) + if (r) XSetRegion(fl_display, fl_gc, r); + else XSetClipMask(fl_display, fl_gc, 0); +#elif defined(WIN32) + SelectClipRgn(fl_gc, r); //if r is NULL, clip is automatically cleared +#elif defined(__APPLE_QUARTZ__) + if ( fl_window ) { // clipping for a true window + Fl_X::q_clear_clipping(); + Fl_X::q_fill_context();//flip coords if bitmap context + //apply program clip + if (r) { + CGContextClipToRects(fl_gc, r->rects, r->count); + } + } else if (fl_gc) { // clipping for an offscreen drawing world (CGBitmap) + Fl_X::q_clear_clipping(); + Fl_X::q_fill_context(); + if (r) { + CGContextClipToRects(fl_gc, r->rects, r->count); + } + } +#else +# error unsupported platform +#endif +} + +void fl_clip_region(Fl_Region r) { + Fl_Region oldr = rstack[rstackptr]; + if (oldr) XDestroyRegion(oldr); + rstack[rstackptr] = r; + fl_restore_clip(); +} + +Fl_Region fl_clip_region() { + return rstack[rstackptr]; +} + +void Fl_Graphics_Driver::push_clip(int x, int y, int w, int h) { + Fl_Region r; + if (w > 0 && h > 0) { + r = XRectangleRegion(x,y,w,h); + Fl_Region current = rstack[rstackptr]; + if (current) { +#if defined(USE_X11) + Fl_Region temp = XCreateRegion(); + XIntersectRegion(current, r, temp); + XDestroyRegion(r); + r = temp; +#elif defined(WIN32) + CombineRgn(r,r,current,RGN_AND); +#elif defined(__APPLE_QUARTZ__) + XDestroyRegion(r); + r = MacRectRegionIntersect(current, x,y,w,h); +#else +# error unsupported platform +#endif + } + } else { // make empty clip region: +#if defined(USE_X11) + r = XCreateRegion(); +#elif defined(WIN32) + r = CreateRectRgn(0,0,0,0); +#elif defined(__APPLE_QUARTZ__) + r = XRectangleRegion(0,0,0,0); +#else +# error unsupported platform +#endif + } + if (rstackptr < STACK_MAX) rstack[++rstackptr] = r; + else Fl::warning("fl_push_clip: clip stack overflow!\n"); + fl_restore_clip(); +} + +// make there be no clip (used by fl_begin_offscreen() only!) +void Fl_Graphics_Driver::push_no_clip() { + if (rstackptr < STACK_MAX) rstack[++rstackptr] = 0; + else Fl::warning("fl_push_no_clip: clip stack overflow!\n"); + fl_restore_clip(); +} + +// pop back to previous clip: +void Fl_Graphics_Driver::pop_clip() { + if (rstackptr > 0) { + Fl_Region oldr = rstack[rstackptr--]; + if (oldr) XDestroyRegion(oldr); + } else Fl::warning("fl_pop_clip: clip stack underflow!\n"); + fl_restore_clip(); +} + +int Fl_Graphics_Driver::not_clipped(int x, int y, int w, int h) { + if (x+w <= 0 || y+h <= 0) return 0; + Fl_Region r = rstack[rstackptr]; + if (!r) return 1; +#if defined (USE_X11) + // get rid of coordinates outside the 16-bit range the X calls take. + if (clip_to_short(x,y,w,h)) return 0; // clipped + return XRectInRegion(r, x, y, w, h); +#elif defined(WIN32) + RECT rect; + if (Fl_Surface_Device::surface()->type() == Fl_Printer::device_type) { // in case of print context, convert coords from logical to device + POINT pt[2] = { {x, y}, {x + w, y + h} }; + LPtoDP(fl_gc, pt, 2); + rect.left = pt[0].x; rect.top = pt[0].y; rect.right = pt[1].x; rect.bottom = pt[1].y; + } else { + rect.left = x; rect.top = y; rect.right = x+w; rect.bottom = y+h; + } + return RectInRegion(r,&rect); +#elif defined(__APPLE_QUARTZ__) + CGRect arg = fl_cgrectmake_cocoa(x, y, w, h); + for (int i = 0; i < r->count; i++) { + CGRect test = CGRectIntersection(r->rects[i], arg); + if (!CGRectIsEmpty(test)) return 1; + } + return 0; +#else +# error unsupported platform +#endif +} + +// return rectangle surrounding intersection of this rectangle and clip: +int Fl_Graphics_Driver::clip_box(int x, int y, int w, int h, int& X, int& Y, int& W, int& H){ + X = x; Y = y; W = w; H = h; + Fl_Region r = rstack[rstackptr]; + if (!r) return 0; +#if defined(USE_X11) + switch (XRectInRegion(r, x, y, w, h)) { + case 0: // completely outside + W = H = 0; + return 2; + case 1: // completely inside: + return 0; + default: // partial: + break; + } + Fl_Region rr = XRectangleRegion(x,y,w,h); + Fl_Region temp = XCreateRegion(); + XIntersectRegion(r, rr, temp); + XRectangle rect; + XClipBox(temp, &rect); + X = rect.x; Y = rect.y; W = rect.width; H = rect.height; + XDestroyRegion(temp); + XDestroyRegion(rr); + return 1; +#elif defined(WIN32) +// The win32 API makes no distinction between partial and complete +// intersection, so we have to check for partial intersection ourselves. +// However, given that the regions may be composite, we have to do +// some voodoo stuff... + Fl_Region rr = XRectangleRegion(x,y,w,h); + Fl_Region temp = CreateRectRgn(0,0,0,0); + int ret; + if (CombineRgn(temp, rr, r, RGN_AND) == NULLREGION) { // disjoint + W = H = 0; + ret = 2; + } else if (EqualRgn(temp, rr)) { // complete + ret = 0; + } else { // partial intersection + RECT rect; + GetRgnBox(temp, &rect); + if(Fl_Surface_Device::surface()->type() == Fl_Printer::device_type) { // if print context, convert coords from device to logical + POINT pt[2] = { {rect.left, rect.top}, {rect.right, rect.bottom} }; + DPtoLP(fl_gc, pt, 2); + X = pt[0].x; Y = pt[0].y; W = pt[1].x - X; H = pt[1].y - Y; + } + else { + X = rect.left; Y = rect.top; W = rect.right - X; H = rect.bottom - Y; + } + ret = 1; + } + DeleteObject(temp); + DeleteObject(rr); + return ret; +#elif defined(__APPLE_QUARTZ__) + CGRect arg = fl_cgrectmake_cocoa(x, y, w, h); + CGRect u = CGRectMake(0,0,0,0); + CGRect test; + for(int i = 0; i < r->count; i++) { + test = CGRectIntersection(r->rects[i], arg); + if( ! CGRectIsEmpty(test) ) { + if(CGRectIsEmpty(u)) u = test; + else u = CGRectUnion(u, test); + } + } + X = int(u.origin.x); + Y = int(u.origin.y); + W = int(u.size.width + 1); + H = int(u.size.height + 1); + if(CGRectIsEmpty(u)) W = H = 0; + return ! CGRectEqualToRect(arg, u); +#else +# error unsupported platform +#endif +} + +// +// End of "$Id: fl_rect.cxx 7889 2010-11-23 17:37:49Z AlbrechtS $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_round_box.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_round_box.cxx new file mode 100644 index 0000000..1fb68b4 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_round_box.cxx @@ -0,0 +1,122 @@ +// +// "$Id: fl_round_box.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Round box drawing routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Box drawing code for an obscure box type. +// These box types are in separate files so they are not linked +// in if not used. + +#include +#include + +// A compiler from a certain very large software company will not compile +// the function pointer assignment due to the name conflict with fl_arc. +// This function is to fix that: +void fl_arc_i(int x,int y,int w,int h,double a1,double a2) { + fl_arc(x,y,w,h,a1,a2); +} + +enum {UPPER_LEFT, LOWER_RIGHT, CLOSED, FILL}; + +static void draw(int which, int x,int y,int w,int h, int inset, Fl_Color color) +{ + if (inset*2 >= w) inset = (w-1)/2; + if (inset*2 >= h) inset = (h-1)/2; + x += inset; + y += inset; + w -= 2*inset; + h -= 2*inset; + int d = w <= h ? w : h; + if (d <= 1) return; + fl_color(color); + void (*f)(int,int,int,int,double,double); + f = (which==FILL) ? fl_pie : fl_arc_i; + if (which >= CLOSED) { + f(x+w-d, y, d, d, w<=h ? 0 : -90, w<=h ? 180 : 90); + f(x, y+h-d, d, d, w<=h ? 180 : 90, w<=h ? 360 : 270); + } else if (which == UPPER_LEFT) { + f(x+w-d, y, d, d, 45, w<=h ? 180 : 90); + f(x, y+h-d, d, d, w<=h ? 180 : 90, 225); + } else { // LOWER_RIGHT + f(x, y+h-d, d, d, 225, w<=h ? 360 : 270); + f(x+w-d, y, d, d, w<=h ? 360 : 270, 360+45); + } + if (which == FILL) { + if (w < h) + fl_rectf(x, y+d/2, w, h-(d&-2)); + else if (w > h) + fl_rectf(x+d/2, y, w-(d&-2), h); + } else { + if (w < h) { + if (which != UPPER_LEFT) fl_yxline(x+w-1, y+d/2-1, y+h-d/2+1); + if (which != LOWER_RIGHT) fl_yxline(x, y+d/2-1, y+h-d/2+1); + } else if (w > h) { + if (which != UPPER_LEFT) fl_xyline(x+d/2-1, y+h-1, x+w-d/2+1); + if (which != LOWER_RIGHT) fl_xyline(x+d/2-1, y, x+w-d/2+1); + } + } +} + +extern uchar* fl_gray_ramp(); + +void fl_round_down_box(int x, int y, int w, int h, Fl_Color bgcolor) { + uchar *g = fl_gray_ramp(); + draw(FILL, x, y, w, h, 2, bgcolor); + draw(UPPER_LEFT, x+1, y, w-2, h, 0, (Fl_Color)g['N']); + draw(UPPER_LEFT, x+1, y, w-2, h, 1, (Fl_Color)g['H']); + draw(UPPER_LEFT, x, y, w, h, 0, (Fl_Color)g['N']); + draw(UPPER_LEFT, x, y, w, h, 1, (Fl_Color)g['H']); + draw(LOWER_RIGHT, x, y, w, h, 0, (Fl_Color)g['S']); + draw(LOWER_RIGHT, x+1, y, w-2, h, 0, (Fl_Color)g['U']); + draw(LOWER_RIGHT, x, y, w, h, 1, (Fl_Color)g['U']); + draw(LOWER_RIGHT, x+1, y, w-2, h, 1, (Fl_Color)g['W']); + draw(CLOSED, x, y, w, h, 2, (Fl_Color)g['A']); +} + +void fl_round_up_box(int x, int y, int w, int h, Fl_Color bgcolor) { + uchar *g = fl_gray_ramp(); + draw(FILL, x, y, w, h, 2, bgcolor); + draw(LOWER_RIGHT, x+1, y, w-2, h, 0, (Fl_Color)g['H']); + draw(LOWER_RIGHT, x+1, y, w-2, h, 1, (Fl_Color)g['N']); + draw(LOWER_RIGHT, x, y, w, h, 1, (Fl_Color)g['H']); + draw(LOWER_RIGHT, x, y, w, h, 2, (Fl_Color)g['N']); + draw(UPPER_LEFT, x, y, w, h, 2, (Fl_Color)g['U']); + draw(UPPER_LEFT, x+1, y, w-2, h, 1, (Fl_Color)g['S']); + draw(UPPER_LEFT, x, y, w, h, 1, (Fl_Color)g['W']); + draw(UPPER_LEFT, x+1, y, w-2, h, 0, (Fl_Color)g['U']); + draw(CLOSED, x, y, w, h, 0, (Fl_Color)g['A']); +} + +extern void fl_internal_boxtype(Fl_Boxtype, Fl_Box_Draw_F*); +Fl_Boxtype fl_define_FL_ROUND_UP_BOX() { + fl_internal_boxtype(_FL_ROUND_DOWN_BOX, fl_round_down_box); + fl_internal_boxtype(_FL_ROUND_UP_BOX, fl_round_up_box); + return _FL_ROUND_UP_BOX; +} + +// +// End of "$Id: fl_round_box.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_rounded_box.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_rounded_box.cxx new file mode 100644 index 0000000..ca7f009 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_rounded_box.cxx @@ -0,0 +1,99 @@ +// +// "$Id: fl_rounded_box.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Rounded box drawing routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include + +#define RN 5 +#define RS 15 +#define BW 3 + +static double offset[RN] = { 0.0, 0.07612, 0.29289, 0.61732, 1.0}; + +static void rbox(int fill, int x, int y, int w, int h) { + int i; + int rsx ,rsy, rs; + rsx = w*2/5; rsy = h*2/5; + if (rsx > rsy) rs = rsy; else rs = rsx; + if (rs > RS) rs = RS; + rsx = rs; rsy = rs; + + if (fill) fl_begin_polygon(); else fl_begin_loop(); + for (i=0; i +#include +#include +#include + +// scroll a rectangle and redraw the newly exposed portions: +/** + Scroll a rectangle and draw the newly exposed portions. + \param[in] X,Y position of top-left of rectangle + \param[in] W,H size of rectangle + \param[in] dx,dy pixel offsets for shifting rectangle + \param[in] draw_area callback function to draw rectangular areas + \param[in] data pointer to user data for callback + The contents of the rectangular area is first shifted by \p dx + and \p dy pixels. The \p draw_area callback is then called for + every newly exposed rectangular area. + */ +void fl_scroll(int X, int Y, int W, int H, int dx, int dy, + void (*draw_area)(void*, int,int,int,int), void* data) +{ + if (!dx && !dy) return; + if (dx <= -W || dx >= W || dy <= -H || dy >= H) { + // no intersection of old an new scroll + draw_area(data,X,Y,W,H); + return; + } + int src_x, src_w, dest_x, clip_x, clip_w; + if (dx > 0) { + src_x = X; + dest_x = X+dx; + src_w = W-dx; + clip_x = X; + clip_w = dx; + } else { + src_x = X-dx; + dest_x = X; + src_w = W+dx; + clip_x = X+src_w; + clip_w = W-src_w; + } + int src_y, src_h, dest_y, clip_y, clip_h; + if (dy > 0) { + src_y = Y; + dest_y = Y+dy; + src_h = H-dy; + clip_y = Y; + clip_h = dy; + } else { + src_y = Y-dy; + dest_y = Y; + src_h = H+dy; + clip_y = Y+src_h; + clip_h = H-src_h; + } + +#if defined(USE_X11) + XCopyArea(fl_display, fl_window, fl_window, fl_gc, + src_x, src_y, src_w, src_h, dest_x, dest_y); + // we have to sync the display and get the GraphicsExpose events! (sigh) + for (;;) { + XEvent e; XWindowEvent(fl_display, fl_window, ExposureMask, &e); + if (e.type == NoExpose) break; + // otherwise assume it is a GraphicsExpose event: + draw_area(data, e.xexpose.x, e.xexpose.y, + e.xexpose.width, e.xexpose.height); + if (!e.xgraphicsexpose.count) break; + } +#elif defined(WIN32) + typedef int (WINAPI* fl_GetRandomRgn_func)(HDC, HRGN, INT); + static fl_GetRandomRgn_func fl_GetRandomRgn = 0L; + static char first_time = 1; + + // We will have to do some Region magic now, so let's see if the + // required function is available (and it should be staring w/Win95) + if (first_time) { + HMODULE hMod = GetModuleHandle("GDI32.DLL"); + if (hMod) { + fl_GetRandomRgn = (fl_GetRandomRgn_func)GetProcAddress(hMod, "GetRandomRgn"); + } + first_time = 0; + } + + // Now check if the source scrolling area is fully visible. + // If it is, we will do a quick scroll and just update the + // newly exposed area. If it is not, we go the safe route and + // re-render the full area instead. + // Note 1: we could go and find the areas that are actually + // obscured and recursively call fl_scroll for the newly found + // rectangles. However, this practice would rely on the + // elements of the undocumented Rgn structure. + // Note 2: although this method should take care of most + // multi-screen solutions, it will not solve issues scrolling + // from a different resolution screen onto another. + // Note 3: this has been tested with image maps, too. + if (fl_GetRandomRgn) { + // get the DC region minus all overlapping windows + HRGN sys_rgn = CreateRectRgn(0, 0, 0, 0); + fl_GetRandomRgn(fl_gc, sys_rgn, 4); + // now get the source scrolling rectangle + HRGN src_rgn = CreateRectRgn(src_x, src_y, src_x+src_w, src_y+src_h); + POINT offset = { 0, 0 }; + if (GetDCOrgEx(fl_gc, &offset)) { + OffsetRgn(src_rgn, offset.x, offset.y); + } + // see if all source pixels are available in the system region + // Note: we could be a bit more merciful and subtract the + // scroll destination region as well. + HRGN dst_rgn = CreateRectRgn(0, 0, 0, 0); + int r = CombineRgn(dst_rgn, src_rgn, sys_rgn, RGN_DIFF); + DeleteObject(dst_rgn); + DeleteObject(src_rgn); + DeleteObject(sys_rgn); + if (r!=NULLREGION) { + draw_area(data,X,Y,W,H); + return; + } + } + + // Great, we can do an accelerated scroll instead of re-rendering + BitBlt(fl_gc, dest_x, dest_y, src_w, src_h, fl_gc, src_x, src_y,SRCCOPY); + +#elif defined(__APPLE_QUARTZ__) + extern CGImageRef MAC_CGImageFromRectOfWindow(Fl_Window*, int x, int y, int w, int h); + CGImageRef img = MAC_CGImageFromRectOfWindow(Fl_Window::current(), src_x, src_y, src_w, src_h); + CGRect rect = { { dest_x, dest_y }, { src_w, src_h } }; + Fl_X::q_begin_image(rect, 0, 0, src_w, src_h); + CGContextDrawImage(fl_gc, rect, img); + Fl_X::q_end_image(); + CFRelease(img); +#else +# error unsupported platform +#endif + if (dx) draw_area(data, clip_x, dest_y, clip_w, src_h); + if (dy) draw_area(data, X, clip_y, W, clip_h); +} + +// +// End of "$Id: fl_scroll_area.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_set_font.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_set_font.cxx new file mode 100644 index 0000000..0ae7305 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_set_font.cxx @@ -0,0 +1,97 @@ +// +// "$Id: fl_set_font.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Font utilities for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Add a font to the internal table. +// Also see fl_set_fonts.cxx which adds all possible fonts. + +#include +#include +#include +#include "flstring.h" +#include "Fl_Font.H" +#include + +static int table_size; +/** + Changes a face. The string pointer is simply stored, + the string is not copied, so the string must be in static memory. +*/ +void Fl::set_font(Fl_Font fnum, const char* name) { + while (fnum >= table_size) { + int i = table_size; + if (!i) { // don't realloc the built-in table + table_size = 2*FL_FREE_FONT; + i = FL_FREE_FONT; + Fl_Fontdesc* t = (Fl_Fontdesc*)malloc(table_size*sizeof(Fl_Fontdesc)); + memcpy(t, fl_fonts, FL_FREE_FONT*sizeof(Fl_Fontdesc)); + fl_fonts = t; + } else { + table_size = 2*table_size; + fl_fonts=(Fl_Fontdesc*)realloc(fl_fonts, table_size*sizeof(Fl_Fontdesc)); + } + for (; i < table_size; i++) { + fl_fonts[i].fontname[0] = 0; + fl_fonts[i].name = 0; +#if !defined(WIN32) && !defined(__APPLE__) + fl_fonts[i].xlist = 0; + fl_fonts[i].n = 0; +#endif // !WIN32 && !__APPLE__ + } + } + Fl_Fontdesc* s = fl_fonts+fnum; + if (s->name) { + if (!strcmp(s->name, name)) {s->name = name; return;} +#if !defined(WIN32) && !defined(__APPLE__) + if (s->xlist && s->n >= 0) XFreeFontNames(s->xlist); +#endif + for (Fl_Font_Descriptor* f = s->first; f;) { + Fl_Font_Descriptor* n = f->next; delete f; f = n; + } + s->first = 0; + } + s->name = name; + s->fontname[0] = 0; +#if !defined(WIN32) && !defined(__APPLE__) + s->xlist = 0; +#endif + s->first = 0; + fl_font(-1, 0); +} +/** Copies one face to another. */ +void Fl::set_font(Fl_Font fnum, Fl_Font from) { + Fl::set_font(fnum, get_font(from)); +} +/** + Gets the string for this face. This string is different for each + face. Under X this value is passed to XListFonts to get all the sizes + of this face. +*/ +const char* Fl::get_font(Fl_Font fnum) {return fl_fonts[fnum].name;} + +// +// End of "$Id: fl_set_font.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_set_fonts.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_set_fonts.cxx new file mode 100644 index 0000000..d8973c1 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_set_fonts.cxx @@ -0,0 +1,46 @@ +// +// "$Id: fl_set_fonts.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// More font utilities for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include "Fl_Font.H" +#include "flstring.h" +#include + +#ifdef WIN32 +# include "fl_set_fonts_win32.cxx" +#elif defined(__APPLE__) +# include "fl_set_fonts_mac.cxx" +#elif USE_XFT +# include "fl_set_fonts_xft.cxx" +#else +# include "fl_set_fonts_x.cxx" +#endif // WIN32 + +// +// End of "$Id: fl_set_fonts.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_set_fonts_mac.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_set_fonts_mac.cxx new file mode 100644 index 0000000..37d00db --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_set_fonts_mac.cxx @@ -0,0 +1,152 @@ +// +// "$Id: fl_set_fonts_mac.cxx 7892 2010-11-25 18:21:21Z manolo $" +// +// MacOS font utilities for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2009 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include + +// #inclde + +// This function fills in the fltk font table with all the fonts that +// are found on the X server. It tries to place the fonts into families +// and to sort them so the first 4 in a family are normal, bold, italic, +// and bold italic. + +// Bug: older versions calculated the value for *ap as a side effect of +// making the name, and then forgot about it. To avoid having to change +// the header files I decided to store this value in the last character +// of the font name array. +#define ENDOFBUFFER 127 // sizeof(Fl_Font.fontname)-1 + +// turn a stored font name into a pretty name: +const char* Fl::get_font_name(Fl_Font fnum, int* ap) { + Fl_Fontdesc *f = fl_fonts + fnum; + if (!f->fontname[0]) { + const char* p = f->name; + if (!p || !*p) {if (ap) *ap = 0; return "";} + strlcpy(f->fontname, p, ENDOFBUFFER); + int type = 0; + if (strstr(f->name, "Bold")) type |= FL_BOLD; + if (strstr(f->name, "Italic")) type |= FL_ITALIC; + f->fontname[ENDOFBUFFER] = (char)type; + } + if (ap) *ap = f->fontname[ENDOFBUFFER]; + return f->fontname; +} + +static int fl_free_font = FL_FREE_FONT; + +Fl_Font Fl::set_fonts(const char* xstarname) { +#pragma unused ( xstarname ) +if (fl_free_font > FL_FREE_FONT) return (Fl_Font)fl_free_font; // if already called + +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + if(fl_mac_os_version == 0) fl_open_display(); +if(fl_mac_os_version >= 0x1050) { +//if(CTFontCreateWithFontDescriptor != NULL) {// CTFontCreateWithFontDescriptor != NULL on 10.4 also! + int value[1] = {1}; + CFDictionaryRef dict = CFDictionaryCreate(NULL, + (const void **)kCTFontCollectionRemoveDuplicatesOption, + (const void **)&value, 1, NULL, NULL); + CTFontCollectionRef fcref = CTFontCollectionCreateFromAvailableFonts(dict); + CFRelease(dict); + CFArrayRef arrayref = CTFontCollectionCreateMatchingFontDescriptors(fcref); + CFRelease(fcref); + CFIndex count = CFArrayGetCount(arrayref); + CFIndex i; + for (i = 0; i < count; i++) { + CTFontDescriptorRef fdesc = (CTFontDescriptorRef)CFArrayGetValueAtIndex(arrayref, i); + CTFontRef font = CTFontCreateWithFontDescriptor(fdesc, 0., NULL); + CFStringRef cfname = CTFontCopyPostScriptName(font); + CFRelease(font); + static char fname[100]; + CFStringGetCString(cfname, fname, sizeof(fname), kCFStringEncodingUTF8); + CFRelease(cfname); + Fl::set_font((Fl_Font)(fl_free_font++), strdup(fname)); + } + CFRelease(arrayref); + return (Fl_Font)fl_free_font; +} +else { +#endif +#if ! __LP64__ + ItemCount oFontCount, oCountAgain; + ATSUFontID *oFontIDs; + // How many fonts? + ATSUFontCount (&oFontCount); + // now allocate space for them... + oFontIDs = (ATSUFontID *)malloc((oFontCount+1) * sizeof(ATSUFontID)); + ATSUGetFontIDs (oFontIDs, oFontCount, &oCountAgain); + // Now oFontIDs should contain a list of all the available Unicode fonts + // Iterate through the list to get each font name + for (ItemCount idx = 0; idx < oFontCount; idx++) + { +// ByteCount actualLength = 0; +// Ptr oName; + // How to get the name - Apples docs say call this twice, once to get the length, then again + // to get the actual name... +// ATSUFindFontName (oFontIDs[idx], kFontFullName, kFontMacintoshPlatform, kFontRomanScript, kFontEnglishLanguage, +// 0, NULL, &actualLength, NULL); + // Now actualLength tells us the length of buffer we need +// oName = (Ptr)malloc(actualLength + 8); +// But who's got time for that nonsense? Let's just hard code a fixed buffer (urgh!) + ByteCount actualLength = 511; + char oName[512]; + ATSUFindFontName (oFontIDs[idx], kFontFullName, kFontMacintoshPlatform, kFontRomanScript, kFontEnglishLanguage, + actualLength, oName, &actualLength, &oCountAgain); + // bounds check and terminate the returned name + if(actualLength > 511) + oName[511] = 0; + else + oName[actualLength] = 0; + Fl::set_font((Fl_Font)(fl_free_font++), strdup(oName)); +// free(oName); + } + free(oFontIDs); + return (Fl_Font)fl_free_font; +#endif //__LP64__ +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + } +#endif + return 0; +} + +static int array[128]; +int Fl::get_font_sizes(Fl_Font fnum, int*& sizep) { + Fl_Fontdesc *s = fl_fonts+fnum; + if (!s->name) s = fl_fonts; // empty slot in table, use entry 0 + int cnt = 0; + + // ATS supports all font size + array[0] = 0; + sizep = array; + cnt = 1; + + return cnt; +} + +// +// End of "$Id: fl_set_fonts_mac.cxx 7892 2010-11-25 18:21:21Z manolo $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_set_fonts_win32.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_set_fonts_win32.cxx new file mode 100644 index 0000000..34f2824 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_set_fonts_win32.cxx @@ -0,0 +1,173 @@ +// +// "$Id: fl_set_fonts_win32.cxx 6616 2009-01-01 21:28:26Z matt $" +// +// WIN32 font utilities for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2009 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this7 library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// This function fills in the FLTK font table with all the fonts that +// are found on the X server. It tries to place the fonts into families +// and to sort them so the first 4 in a family are normal, bold, italic, +// and bold italic. +#include +#ifdef __CYGWIN__ +# include +#endif + +// Bug: older versions calculated the value for *ap as a side effect of +// making the name, and then forgot about it. To avoid having to change +// the header files I decided to store this value in the last character +// of the font name array. +#define ENDOFBUFFER 127 // sizeof(Fl_Font.fontname)-1 + +// turn a stored font name into a pretty name: +const char* Fl::get_font_name(Fl_Font fnum, int* ap) { + Fl_Fontdesc *f = fl_fonts + fnum; + if (!f->fontname[0]) { + const char* p = f->name; + if (!p || !*p) {if (ap) *ap = 0; return "";} + int type; + switch (*p) { + case 'B': type = FL_BOLD; break; + case 'I': type = FL_ITALIC; break; + case 'P': type = FL_BOLD | FL_ITALIC; break; + default: type = 0; break; + } + strlcpy(f->fontname, p+1, ENDOFBUFFER); + if (type & FL_BOLD) strlcat(f->fontname, " bold", ENDOFBUFFER); + if (type & FL_ITALIC) strlcat(f->fontname, " italic", ENDOFBUFFER); + f->fontname[ENDOFBUFFER] = (char)type; + } + if (ap) *ap = f->fontname[ENDOFBUFFER]; + return f->fontname; +} + +static int fl_free_font = FL_FREE_FONT; + +static int CALLBACK +enumcbw(CONST LOGFONTW *lpelf, + CONST TEXTMETRICW * /*lpntm*/, + DWORD /*FontType*/, + LPARAM p) { + if (!p && lpelf->lfCharSet != ANSI_CHARSET) return 1; + char *n = NULL; + int l = wcslen(lpelf->lfFaceName); + unsigned dstlen = fl_utf8fromwc(n, 0, (xchar*)lpelf->lfFaceName, l) + 1; // measure the string + n = (char*) malloc(dstlen); +//n[fl_unicode2utf((xchar*)lpelf->lfFaceName, l, n)] = 0; + dstlen = fl_utf8fromwc(n, dstlen, (xchar*)lpelf->lfFaceName, l); // convert the string + n[dstlen] = 0; + for (int i=0; ilfWeight <= 400) + buffer[0] = 'B', Fl::set_font((Fl_Font)(fl_free_font++), strdup(buffer)); + buffer[0] = 'I'; Fl::set_font((Fl_Font)(fl_free_font++), strdup(buffer)); + if (lpelf->lfWeight <= 400) + buffer[0] = 'P', Fl::set_font((Fl_Font)(fl_free_font++), strdup(buffer)); + free(n); + return 1; +} /* enumcbw */ + +Fl_Font Fl::set_fonts(const char* xstarname) { + if (fl_free_font == FL_FREE_FONT) {// if not already been called + if (!fl_gc) fl_GetDC(0); + + EnumFontFamiliesW(fl_gc, NULL, (FONTENUMPROCW)enumcbw, xstarname != 0); + + } + return (Fl_Font)fl_free_font; +} + + +static int nbSize; +static int cyPerInch; +static int sizes[128]; +static int CALLBACK + +EnumSizeCbW(CONST LOGFONTW * /*lpelf*/, + CONST TEXTMETRICW *lpntm, + DWORD fontType, + LPARAM /*p*/) { + if ((fontType & RASTER_FONTTYPE) == 0) { + sizes[0] = 0; + nbSize = 1; + + // Scalable font + return 0; + } + + int add = lpntm->tmHeight - lpntm->tmInternalLeading; + add = MulDiv(add, 72, cyPerInch); + + int start = 0; + while ((start < nbSize) && (sizes[start] < add)) { + start++; + } + + if ((start < nbSize) && (sizes[start] == add)) { + return 1; + } + + for (int i=nbSize; i>start; i--) sizes[i] = sizes[i - 1]; + + sizes[start] = add; + nbSize++; + + // Stop enum if buffer overflow + return nbSize < 128; +} + + +int +Fl::get_font_sizes(Fl_Font fnum, int*& sizep) { + nbSize = 0; + Fl_Fontdesc *s = fl_fonts+fnum; + if (!s->name) s = fl_fonts; // empty slot in table, use entry 0 + + if (!fl_gc) fl_GetDC(0); + cyPerInch = GetDeviceCaps(fl_gc, LOGPIXELSY); + if (cyPerInch < 1) cyPerInch = 1; + +// int l = fl_utf_nb_char((unsigned char*)s->name+1, strlen(s->name+1)); +// unsigned short *b = (unsigned short*) malloc((l + 1) * sizeof(short)); +// fl_utf2unicode((unsigned char*)s->name+1, l, (xchar*)b); + const char *nm = (const char*)s->name+1; + int len = strlen(s->name+1); + int l = fl_utf8toUtf16(nm, len, NULL, 0); // Pass NULL to query length required + unsigned short *b = (unsigned short*) malloc((l + 1) * sizeof(short)); + l = fl_utf8toUtf16(nm, len, b, (l+1)); // Now do the conversion + b[l] = 0; + EnumFontFamiliesW(fl_gc, (WCHAR*)b, (FONTENUMPROCW)EnumSizeCbW, 0); + free(b); + + sizep = sizes; + return nbSize; +} + + +// +// End of "$Id: fl_set_fonts_win32.cxx 6616 2009-01-01 21:28:26Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_set_fonts_x.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_set_fonts_x.cxx new file mode 100644 index 0000000..d21400d --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_set_fonts_x.cxx @@ -0,0 +1,350 @@ +// +// "$Id: fl_set_fonts_x.cxx 6712 2009-03-22 19:21:34Z AlbrechtS $" +// +// X11 font utilities for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2009 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// This function fills in the fltk font table with all the fonts that +// are found on the X server. It tries to place the fonts into families +// and to sort them so the first 4 in a family are normal, bold, italic, +// and bold italic. + +// Standard X fonts are matched by a pattern that is always of +// this form, and this pattern is put in the table: +// "-*-family-weight-slant-width1-style-*-registry-encoding" + +// Non-standard font names (those not starting with '-') are matched +// by a pattern of the form "prefix*suffix", where the '*' is where +// fltk thinks the point size is, or by the actual font name if no +// point size is found. + +// Fltk knows how to pull an "attribute" out of a font name, such as +// bold or italic, by matching known x font field values. All words +// that don't match a known attribute are combined into the "name" +// of the font. Names are compared before attributes for sorting, this +// makes the bold and plain version of a font come out next to each +// other despite the poor X font naming scheme. + +// By default fl_set_fonts() only does iso8859-1 encoded fonts. You can +// do all normal X fonts by passing "-*" or every possible font with "*". + +// Fl::set_font will take strings other than the ones this stores +// and can identify any font on X that way. You may want to write your +// own system of font management and not use this code. + +// turn word N of a X font name into either some attribute bits +// (right now 0, FL_BOLD, or FL_ITALIC), or into -1 indicating that +// the word should be put into the name: + +static int attribute(int n, const char *p) { + // don't put blank things into name: + if (!*p || *p=='-' || *p=='*') return 0; + if (n == 3) { // weight + if (!strncmp(p,"normal",6) || + !strncmp(p,"light",5) || + !strncmp(p,"medium",6) || + !strncmp(p,"book",4)) return 0; + if (!strncmp(p,"bold",4) || !strncmp(p,"demi",4)) return FL_BOLD; + } else if (n == 4) { // slant + if (*p == 'r') return 0; + if (*p == 'i' || *p == 'o') return FL_ITALIC; + } else if (n == 5) { // sWidth + if (!strncmp(p,"normal",6)) return 0; + } + return -1; +} + +// return non-zero if the registry-encoding should be used: +extern const char* fl_encoding; +static int use_registry(const char *p) { + return *p && *p!='*' && strcmp(p,fl_encoding); +} + +// Bug: older versions calculated the value for *ap as a side effect of +// making the name, and then forgot about it. To avoid having to change +// the header files I decided to store this value in the last character +// of the font name array. +#define ENDOFBUFFER 127 // sizeof(Fl_Font.fontname)-1 + +// turn a stored (with *'s) X font name into a pretty name: +const char* Fl::get_font_name(Fl_Font fnum, int* ap) { + Fl_Fontdesc *f = fl_fonts + fnum; + if (!f->fontname[0]) { + int type = 0; + const char* p = f->name; + if (!p) { + if (ap) *ap = 0; + return ""; + } + char *o = f->fontname; + + if (*p != '-') { // non-standard font, just replace * with spaces: + if (strstr(p,"bold")) type = FL_BOLD; + if (strstr(p,"ital")) type |= FL_ITALIC; + for (;*p; p++) { + if (*p == '*' || *p == ' ' || *p == '-') { + do p++; while (*p == '*' || *p == ' ' || *p == '-'); + if (!*p) break; + if (o < (f->fontname + ENDOFBUFFER - 1)) *o++ = ' '; + } + if (o < (f->fontname + ENDOFBUFFER - 1)) *o++ = *p; + } + *o = 0; + + } else { // standard dash-separated font: + + // get the family: + const char *x = fl_font_word(p,2); if (*x) x++; if (*x=='*') x++; + if (!*x) { + if (ap) *ap = 0; + return p; + } + const char *e = fl_font_word(x,1); + if ((e - x) < (int)(ENDOFBUFFER - 1)) { + // MRS: we want strncpy here, not strlcpy... + strncpy(o,x,e-x); + o += e-x; + } else { + strlcpy(f->fontname, x, ENDOFBUFFER); + o = f->fontname+ENDOFBUFFER-1; + } + + // collect all the attribute words: + for (int n = 3; n <= 6; n++) { + // get the next word: + if (*e) e++; x = e; e = fl_font_word(x,1); + int t = attribute(n,x); + if (t < 0) { + if (o < (f->fontname + ENDOFBUFFER - 1)) *o++ = ' '; + if ((e - x) < (int)(ENDOFBUFFER - (o - f->fontname) - 1)) { + // MRS: we want strncpy here, not strlcpy... + strncpy(o,x,e-x); + o += e-x; + } else { + strlcpy(o,x, ENDOFBUFFER - (o - f->fontname) - 1); + o = f->fontname+ENDOFBUFFER-1; + } + } else type |= t; + } + + // skip over the '*' for the size and get the registry-encoding: + x = fl_font_word(e,2); + if (*x) {x++; *o++ = '('; while (*x) *o++ = *x++; *o++ = ')';} + + *o = 0; + if (type & FL_BOLD) strlcat(f->fontname, " bold", ENDOFBUFFER); + if (type & FL_ITALIC) strlcat(f->fontname, " italic", ENDOFBUFFER); + } + f->fontname[ENDOFBUFFER] = (char)type; + } + if (ap) *ap = f->fontname[ENDOFBUFFER]; + return f->fontname; +} + +extern "C" { +// sort raw (non-'*') X font names into perfect order: + +static int ultrasort(const void *aa, const void *bb) { + const char *a = *(char **)aa; + const char *b = *(char **)bb; + + // sort all non x-fonts at the end: + if (*a != '-') { + if (*b == '-') return 1; + // 2 non-x fonts are matched by "numeric sort" + int ret = 0; + for (;;) { + if (isdigit(*a) && isdigit(*b)) { + int na = strtol(a, (char **)&a, 10); + int nb = strtol(b, (char **)&b, 10); + if (!ret) ret = na-nb; + } else if (*a != *b) { + return (*a-*b); + } else if (!*a) { + return ret; + } else { + a++; b++; + } + } + } else { + if (*b != '-') return -1; + } + + // skip the foundry (assume equal): + for (a++; *a && *a++!='-';); + for (b++; *b && *b++!='-';); + + // compare the family and all the attribute words: + int atype = 0; + int btype = 0; + for (int n = 2; n <= 6; n++) { + int at = attribute(n,a); + int bt = attribute(n,b); + if (at < 0) { + if (bt >= 0) return 1; + for (;;) {if (*a!=*b) return *a-*b; b++; if (!*a || *a++=='-') break;} + } else { + if (bt < 0) return -1; + a = fl_font_word(a,1); if (*a) a++; + b = fl_font_word(b,1); if (*b) b++; + atype |= at; btype |= bt; + } + } + + // remember the pixel size: + int asize = atoi(a); + int bsize = atoi(b); + + // compare the registry/encoding: + a = fl_font_word(a,6); if (*a) a++; + b = fl_font_word(b,6); if (*b) b++; + if (use_registry(a)) { + if (!use_registry(b)) return 1; + int r = strcmp(a,b); if (r) return r; + } else { + if (use_registry(b)) return -1; + } + + if (atype != btype) return atype-btype; + if (asize != bsize) return asize-bsize; + + // something wrong, just do a string compare... + return strcmp(*(char**)aa, *(char**)bb); +} +} + +// converts a X font name to a standard starname, returns point size: +static int to_canonical(char *to, const char *from, size_t tolen) { + char* c = fl_find_fontsize((char*)from); + if (!c) return -1; // no point size found... + const char* endptr; + int size = strtol(c,(char**)&endptr,10); + if (from[0] == '-') { + // replace the "foundry" with -*-: + *to++ = '-'; *to++ = '*'; + for (from++; *from && *from != '-'; from++); + // skip to the registry-encoding: + endptr = (char*)fl_font_word(endptr,6); + if (*endptr && !use_registry(endptr+1)) endptr = ""; + } + int n = c-from; + // MRS: we want strncpy here, not strlcpy... + if (n > (int)(tolen - 1)) return -1; + strncpy(to,from,n); + to[n++] = '*'; + strlcpy(to+n,endptr, tolen - n); + return size; +} + +static unsigned int fl_free_font = FL_FREE_FONT; + +Fl_Font Fl::set_fonts(const char* xstarname) { + if (fl_free_font > FL_FREE_FONT) // already been here + return (Fl_Font)fl_free_font; + fl_open_display(); + int xlistsize; + char buf[20]; + if (!xstarname) { + strcpy(buf,"-*-"); strcpy(buf+3,fl_encoding); + xstarname = buf; + } + char **xlist = XListFonts(fl_display, xstarname, 10000, &xlistsize); + if (!xlist) return (Fl_Font)fl_free_font; + qsort(xlist, xlistsize, sizeof(*xlist), ultrasort); + int used_xlist = 0; + for (int i=0; i= 0) { + for (;;) { // find all matching fonts: + if (i >= xlistsize) break; + const char *q = xlist[i]; + char this_canon[1024]; + if (to_canonical(this_canon, q, sizeof(this_canon)) < 0) break; + if (strcmp(canon, this_canon)) break; + i++; + } + /*if (*p=='-' || i > first_xlist+1)*/ p = canon; + } + unsigned int j; + for (j = 0;; j++) { + /*if (j < FL_FREE_FONT) { + // see if it is one of our built-in fonts: + // if so, set the list of x fonts, since we have it anyway + if (fl_fonts[j].name && !strcmp(fl_fonts[j].name, p)) break; + } else */{ + j = fl_free_font++; + if (p == canon) p = strdup(p); else used_xlist = 1; + Fl::set_font((Fl_Font)j, p); + break; + } + } + if (!fl_fonts[j].xlist) { + fl_fonts[j].xlist = xlist+first_xlist; + fl_fonts[j].n = -(i-first_xlist); + used_xlist = 1; + } + } + if (!used_xlist) XFreeFontNames(xlist); + return (Fl_Font)fl_free_font; +} + +int Fl::get_font_sizes(Fl_Font fnum, int*& sizep) { + Fl_Fontdesc *s = fl_fonts+fnum; + if (!s->name) s = fl_fonts; // empty slot in table, use entry 0 + if (!s->xlist) { + fl_open_display(); + s->xlist = XListFonts(fl_display, s->name, 100, &(s->n)); + if (!s->xlist) return 0; + } + int listsize = s->n; if (listsize<0) listsize = -listsize; + static int sizes[128]; + int numsizes = 0; + for (int i = 0; i < listsize; i++) { + char *q = s->xlist[i]; + char *d = fl_find_fontsize(q); + if (!d) continue; + int s = strtol(d,0,10); + if (!numsizes || sizes[numsizes-1] < s) { + sizes[numsizes++] = s; + } else { + // insert-sort the new size into list: + int n; + for (n = numsizes-1; n > 0; n--) if (sizes[n-1] < s) break; + if (sizes[n] != s) { + for (int m = numsizes; m > n; m--) sizes[m] = sizes[m-1]; + sizes[n] = s; + numsizes++; + } + } + } + sizep = sizes; + return numsizes; +} + +// +// End of "$Id: fl_set_fonts_x.cxx 6712 2009-03-22 19:21:34Z AlbrechtS $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_set_fonts_xft.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_set_fonts_xft.cxx new file mode 100644 index 0000000..60aa1f0 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_set_fonts_xft.cxx @@ -0,0 +1,384 @@ +// +// "$Id: fl_set_fonts_xft.cxx 7765 2010-10-28 18:02:20Z matt $" +// +// More font utilities for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2009 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include + +// This function fills in the fltk font table with all the fonts that +// are found on the X server. It tries to place the fonts into families +// and to sort them so the first 4 in a family are normal, bold, italic, +// and bold italic. + +// Bug: older versions calculated the value for *ap as a side effect of +// making the name, and then forgot about it. To avoid having to change +// the header files I decided to store this value in the last character +// of the font name array. +#define ENDOFBUFFER 127 // sizeof(Fl_Font.fontname)-1 + +// turn a stored font name into a pretty name: +const char* Fl::get_font_name(Fl_Font fnum, int* ap) { + Fl_Fontdesc *f = fl_fonts + fnum; + if (!f->fontname[0]) { + const char* p = f->name; + int type; + switch (p[0]) { + case 'B': type = FL_BOLD; break; + case 'I': type = FL_ITALIC; break; + case 'P': type = FL_BOLD | FL_ITALIC; break; + default: type = 0; break; + } + + // NOTE: This can cause duplications in fonts that already have Bold or Italic in + // their "name". Maybe we need to find a cleverer way? + strlcpy(f->fontname, p+1, ENDOFBUFFER); + if (type & FL_BOLD) strlcat(f->fontname, " bold", ENDOFBUFFER); + if (type & FL_ITALIC) strlcat(f->fontname, " italic", ENDOFBUFFER); + f->fontname[ENDOFBUFFER] = (char)type; + } + if (ap) *ap = f->fontname[ENDOFBUFFER]; + return f->fontname; +} + +/////////////////////////////////////////////////////////// +#define LOCAL_RAW_NAME_MAX 256 + +extern "C" { +// sort returned fontconfig font names +static int name_sort(const void *aa, const void *bb) { + // What should we do here? Just do a string compare for now... + // NOTE: This yeilds some oddities - in particular a Blah Bold font will be + // listed before Blah... + // Also - the fontconfig listing returns some faces that are effectively duplicates + // as far as fltk is concerned, e.g. where there are ko or ja variants that we + // can't distinguish (since we are not yet fully UTF-*) - should we strip them here? + return strcasecmp(*(char**)aa, *(char**)bb); +} // end of name_sort +} // end of extern C section + + +// Read the "pretty" name we have derived from fontconfig then convert +// it into the format fltk uses internally for Xft names... +// This is just a mess - I should have tokenised the strings and gone from there, +// but I really thought this would be easier! +static void make_raw_name(char *raw, char *pretty) +{ + // Input name will be "Some Name:style = Bold Italic" or whatever + // The plan is this: + // - the first char in the "raw" name becomes either I, B, P or " " for + // italic, bold, bold italic or normal - this seems to be the fltk way... + + char *style = strchr(pretty, ':'); + char *last = style + strlen(style) - 2; + + if (style) + { + *style = 0; // Terminate "name" string + style ++; // point to start of style section + } + + // It is still possible that the "pretty" name has multiple comma separated entries + // I've seen this often in CJK fonts, for example... Keep only the first one... This + // is not ideal, the CJK fonts often have the name in utf8 in several languages. What + // we ought to do is use fontconfig to query the available languages and pick one... But which? +#if 0 // loop to keep the LAST name entry... + char *nm1 = pretty; + char *nm2 = strchr(nm1, ','); + while(nm2) { + nm1 = nm2 + 1; + nm2 = strchr(nm1, ','); + } + raw[0] = ' '; raw[1] = 0; // Default start of "raw name" text + strncat(raw, nm1, LOCAL_RAW_NAME_MAX); +#else // keep the first remaining name entry + char *nm2 = strchr(pretty, ','); + if(nm2) *nm2 = 0; // terminate name after first entry + raw[0] = ' '; raw[1] = 0; // Default start of "raw name" text + strncat(raw, pretty, LOCAL_RAW_NAME_MAX-1); +#endif + // At this point, the name is "marked" as regular... + if (style) + { +#define PLAIN 0 +#define BOLD 1 +#define ITALIC 2 +#define BITALIC (BOLD | ITALIC) + int mods = PLAIN; + // Now try and parse the style string - look for the "=" sign + style = strchr(style, '='); + while ((style) && (style < last)) + { + int type; + while ((*style == '=') || (*style == ' ') || (*style == '\t')) + { + style++; // Start of Style string + if ((style >= last) || (*style == 0)) continue; + } + type = toupper(style[0]); + switch (type) + { + // Things we might see: Regular Normal Bold Italic Oblique (??what??) Medium + // Roman Light Demi Sans SemiCondensed SuperBold Book... etc... + // Things we actually care about: Bold Italic Oblique SuperBold - Others??? + case 'I': + if (strncasecmp(style, "Italic", 6) == 0) + { + mods |= ITALIC; + } + goto NEXT_STYLE; + + case 'B': + if (strncasecmp(style, "Bold", 4) == 0) + { + mods |= BOLD; + } + goto NEXT_STYLE; + + case 'O': + if (strncasecmp(style, "Oblique", 7) == 0) + { + mods |= ITALIC; + } + goto NEXT_STYLE; + + case 's': + if (strncasecmp(style, "SuperBold", 9) == 0) + { + mods |= BOLD; + } + goto NEXT_STYLE; + + default: // find the next gap + goto NEXT_STYLE; + } // switch end +NEXT_STYLE: + while ((*style != ' ') && (*style != '\t')) + { + style++; + if ((style >= last) || (*style == 0)) goto STYLE_DONE; + } + } +STYLE_DONE: + // Set the "modifier" character in the raw string + switch(mods) + { + case BOLD: raw[0] = 'B'; + break; + case ITALIC: raw[0] = 'I'; + break; + case BITALIC: raw[0] = 'P'; + break; + default: raw[0] = ' '; + break; + } + } +} // make_raw_name + +/////////////////////////////////////////////////////////// + +static int fl_free_font = FL_FREE_FONT; + +// Uses the fontconfig lib to construct a list of all installed fonts. +// I tried using XftListFonts for this, but the API is tricky - and when +// I looked at the XftList* code, it calls the Fc* functions anyway, so... +// +// Also, for now I'm ignoring the "pattern_name" and just getting everything... +// AND I don't try and skip the fonts we've already loaded in the defaults. +// Blimey! What a hack! +Fl_Font Fl::set_fonts(const char* pattern_name) +{ + FcFontSet *fnt_set; // Will hold the list of fonts we find + FcPattern *fnt_pattern; // Holds the generic "match all names" pattern + FcObjectSet *fnt_obj_set = 0; // Holds the generic "match all objects" + + int j; // loop iterator variable + int font_count; // Total number of fonts found to process + char **full_list; // The list of font names we build + + if (fl_free_font > FL_FREE_FONT) // already been here + return (Fl_Font)fl_free_font; + + fl_open_display(); // Just in case... + + // Make sure fontconfig is ready... is this necessary? The docs say it is + // safe to call it multiple times, so just go for it anyway! + if (!FcInit()) + { + // What to do? Just return defaults... + return FL_FREE_FONT; + } + + // Create a search pattern that will match every font name - I think this + // does the Right Thing, but am not certain... + // + // This could possibly be "enhanced" to pay attention to the requested + // "pattern_name"? + fnt_pattern = FcPatternCreate(); + fnt_obj_set = FcObjectSetBuild(FC_FAMILY, FC_STYLE, (void *)0); + + // Hopefully, this is a set of all the fonts... + fnt_set = FcFontList(0, fnt_pattern, fnt_obj_set); + + // We don't need the fnt_pattern any more, release it + FcPatternDestroy(fnt_pattern); + + // Now, if we got any fonts, iterate through them... + if (fnt_set) + { + char *stop; + char *start; + char *first; + + font_count = fnt_set->nfont; // How many fonts? + + // Allocate array of char*'s to hold the name strings + full_list = (char **)malloc(sizeof(char *) * font_count); + + // iterate through all the font patterns and get the names out... + for (j = 0; j < font_count; j++) + { + // NOTE: FcChar8 is a typedef of "unsigned char"... + FcChar8 *font; // String to hold the font's name + + // Convert from fontconfig internal pattern to human readable name + // NOTE: This WILL malloc storage, so we need to free it later... + font = FcNameUnparse(fnt_set->fonts[j]); + + // The returned strings look like this... + // Century Schoolbook:style=Bold Italic,fed kursiv,Fett Kursiv,... + // So the bit we want is up to the first comma - BUT some strings have + // more than one name, separated by, guess what?, a comma... + stop = start = first = 0; + stop = strchr((char *)font, ','); + start = strchr((char *)font, ':'); + if ((stop) && (start) && (stop < start)) + { + first = stop + 1; // discard first version of name + // find first comma *after* the end of the name + stop = strchr((char *)start, ','); + } + else + { + first = (char *)font; // name is just what was returned + } + // Truncate the name after the (english) modifiers description + if (stop) + { + *stop = 0; // Terminate the string at the first comma, if there is one + } + + // Copy the font description into our list + if (first == (char *)font) + { // The listed name is still OK + full_list[j] = (char *)font; + } + else + { // The listed name has been modified + full_list[j] = strdup(first); + // Free the font name storage + free (font); + } + // replace "style=Regular" so strcmp sorts it first + if (start) { + char *reg = strstr(full_list[j], "=Regular"); + if (reg) reg[1]='.'; + } + } + + // Release the fnt_set - we don't need it any more + FcFontSetDestroy(fnt_set); + + // Sort the list into alphabetic order + qsort(full_list, font_count, sizeof(*full_list), name_sort); + + // Now let us add the names we got to fltk's font list... + for (j = 0; j < font_count; j++) + { + if (full_list[j]) + { + char xft_name[LOCAL_RAW_NAME_MAX]; + char *stored_name; + // Parse the strings into FLTK-XFT style.. + make_raw_name(xft_name, full_list[j]); + // NOTE: This just adds on AFTER the default fonts - no attempt is made + // to identify already loaded fonts. Is this bad? + stored_name = strdup(xft_name); + Fl::set_font((Fl_Font)(j + FL_FREE_FONT), stored_name); + fl_free_font ++; + + free(full_list[j]); // release that name from our internal array + } + } + // Now we are done with the list, release it fully + free(full_list); + } + return (Fl_Font)fl_free_font; +} // ::set_fonts +//////////////////////////////////////////////////////////////// + + +extern "C" { +static int int_sort(const void *aa, const void *bb) { + return (*(int*)aa)-(*(int*)bb); +} +} + +//////////////////////////////////////////////////////////////// + +// Return all the point sizes supported by this font: +// Suprisingly enough Xft works exactly like fltk does and returns +// the same list. Except there is no way to tell if the font is scalable. +int Fl::get_font_sizes(Fl_Font fnum, int*& sizep) { + Fl_Fontdesc *s = fl_fonts+fnum; + if (!s->name) s = fl_fonts; // empty slot in table, use entry 0 + + fl_open_display(); + XftFontSet* fs = XftListFonts(fl_display, fl_screen, + XFT_FAMILY, XftTypeString, s->name+1, + (void *)0, + XFT_PIXEL_SIZE, + (void *)0); + static int* array = 0; + static int array_size = 0; + if (fs->nfont >= array_size) { + delete[] array; + array = new int[array_size = fs->nfont+1]; + } + array[0] = 0; int j = 1; // claim all fonts are scalable + for (int i = 0; i < fs->nfont; i++) { + double v; + if (XftPatternGetDouble(fs->fonts[i], XFT_PIXEL_SIZE, 0, &v) == XftResultMatch) { + array[j++] = int(v); + } + } + qsort(array+1, j-1, sizeof(int), int_sort); + XftFontSetDestroy(fs); + sizep = array; + return j; +} + +// +// End of "$Id: fl_set_fonts_xft.cxx 7765 2010-10-28 18:02:20Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_shadow_box.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_shadow_box.cxx new file mode 100644 index 0000000..02cf660 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_shadow_box.cxx @@ -0,0 +1,56 @@ +// +// "$Id: fl_shadow_box.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Shadow box drawing routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include + +#define BW 3 + +static void fl_shadow_frame(int x, int y, int w, int h, Fl_Color c) { + fl_color(FL_DARK3); + fl_rectf(x+BW, y+h-BW, w - BW, BW); + fl_rectf(x+w-BW, y+BW, BW, h - BW); + fl_color(c); + fl_rect(x,y,w-BW,h-BW); +} + +static void fl_shadow_box(int x, int y, int w, int h, Fl_Color c) { + fl_color(c); + fl_rectf(x+1,y+1,w-2-BW,h-2-BW); + fl_shadow_frame(x,y,w,h,FL_GRAY0); +} + +extern void fl_internal_boxtype(Fl_Boxtype, Fl_Box_Draw_F*); +Fl_Boxtype fl_define_FL_SHADOW_BOX() { + fl_internal_boxtype(_FL_SHADOW_FRAME, fl_shadow_frame); + fl_internal_boxtype(_FL_SHADOW_BOX, fl_shadow_box); + return _FL_SHADOW_BOX; +} + +// +// End of "$Id: fl_shadow_box.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_shortcut.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_shortcut.cxx new file mode 100644 index 0000000..4a78b90 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_shortcut.cxx @@ -0,0 +1,375 @@ +// +// "$Id: fl_shortcut.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Shortcut support routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Code to test and parse fltk shortcut numbers. +// +// A shortcut is a keysym or'd with shift flags. In the simplest +// sense a shortcut is matched if the shift state is exactly as +// given and the key returning that keysym is pressed. +// +// To make it easier to match some things it is more complex: +// +// Only FL_META, FL_ALT, FL_SHIFT, and FL_CTRL must be "off". A +// zero in the other shift flags indicates "dont care". +// +// It also checks against the first character of Fl::event_text(), +// and zero for FL_SHIFT means "don't care". +// This allows punctuation shortcuts like "#" to work (rather than +// calling it "shift+3" on a US keyboard) + +#include +#include +#include +#include +#include +#include "flstring.h" +#if !defined(WIN32) && !defined(__APPLE__) +#include +#endif + +/** + Test the current event, which must be an FL_KEYBOARD or + FL_SHORTCUT, against a shortcut value (described in + Fl_Button). + + Not to be confused with Fl_Widget::test_shortcut(). + + \return non-zero if there is a match. +*/ +int Fl::test_shortcut(unsigned int shortcut) { + if (!shortcut) return 0; + + unsigned int v = shortcut & FL_KEY_MASK; + if (((unsigned)fl_tolower(v))!=v) { + shortcut |= FL_SHIFT; + } + + int shift = Fl::event_state(); + // see if any required shift flags are off: + if ((shortcut&shift) != (shortcut&0x7fff0000)) return 0; + // record shift flags that are wrong: + int mismatch = (shortcut^shift)&0x7fff0000; + // these three must always be correct: + if (mismatch&(FL_META|FL_ALT|FL_CTRL)) return 0; + + unsigned int key = shortcut & FL_KEY_MASK; + + // if shift is also correct, check for exactly equal keysyms: + if (!(mismatch&(FL_SHIFT)) && key == (unsigned)Fl::event_key()) return 1; + + // try matching utf8, ignore shift: + unsigned int firstChar = fl_utf8decode(Fl::event_text(), Fl::event_text()+Fl::event_length(), 0); + if (key==firstChar) return 1; + + // kludge so that Ctrl+'_' works (as opposed to Ctrl+'^_'): + if ((shift&FL_CTRL) && key >= 0x3f && key <= 0x5F + && firstChar==(key^0x40)) return 1; // firstChar should be within a-z + return 0; +} + +// This table must be in numeric order by fltk (X) keysym number: +struct Keyname {unsigned int key; const char* name;}; +#if defined(WIN32) +static Keyname table[] = { + {' ', "Space"}, + {FL_BackSpace, "Backspace"}, + {FL_Tab, "Tab"}, + {0xff0b/*XK_Clear*/, "Clear"}, + {FL_Enter, "Enter"}, // X says "Enter" + {FL_Pause, "Pause"}, + {FL_Scroll_Lock, "Scroll_Lock"}, + {FL_Escape, "Escape"}, + {FL_Home, "Home"}, + {FL_Left, "Left"}, + {FL_Up, "Up"}, + {FL_Right, "Right"}, + {FL_Down, "Down"}, + {FL_Page_Up, "Page_Up"}, // X says "Prior" + {FL_Page_Down,"Page_Down"}, // X says "Next" + {FL_End, "End"}, + {FL_Print, "Print"}, + {FL_Insert, "Insert"}, + {FL_Menu, "Menu"}, + {FL_Num_Lock, "Num_Lock"}, + {FL_KP_Enter, "KP_Enter"}, + {FL_Shift_L, "Shift_L"}, + {FL_Shift_R, "Shift_R"}, + {FL_Control_L,"Control_L"}, + {FL_Control_R,"Control_R"}, + {FL_Caps_Lock,"Caps_Lock"}, + {FL_Meta_L, "Meta_L"}, + {FL_Meta_R, "Meta_R"}, + {FL_Alt_L, "Alt_L"}, + {FL_Alt_R, "Alt_R"}, + {FL_Delete, "Delete"} +}; +#elif defined(__APPLE__) +static Keyname table[] = { + // v - this column contains utf8 characters + {' ', "Space"}, + {FL_BackSpace,"\xe2\x8c\xab"}, // erase to the left + {FL_Tab, "\xe2\x87\xa5"}, // rightwards arrow to bar + {0xff0b, "\xe2\x8c\xa6"}, // erase to the right + {FL_Enter, "\xe2\x86\xa9"}, // leftwards arrow with hook + {FL_Pause, "Pause"}, + {FL_Scroll_Lock, "Scroll_Lock"}, + {FL_Escape, "\xe2\x90\x9b"}, + {FL_Home, "\xe2\x86\x96"}, // north west arrow + {FL_Left, "\xe2\x86\x90"}, // leftwards arrow + {FL_Up, "\xe2\x86\x91"}, // upwards arrow + {FL_Right, "\xe2\x86\x92"}, // rightwards arrow + {FL_Down, "\xe2\x86\x93"}, // downwards arrow + {FL_Page_Up, "\xe2\x87\x9e"}, // upwards arrow with double stroke + {FL_Page_Down,"\xe2\x87\x9f"}, // downward arrow with double stroke + {FL_End, "\xe2\x86\x98"}, // south east arrow + {FL_Print, "Print"}, + {FL_Insert, "Insert"}, + {FL_Menu, "Menu"}, + {FL_Num_Lock, "Num_Lock"}, + {FL_KP_Enter, "\xe2\x8c\xa4"}, // up arrow head between two horizontal bars + {FL_Shift_L, "Shift_L"}, + {FL_Shift_R, "Shift_R"}, + {FL_Control_L,"Control_L"}, + {FL_Control_R,"Control_R"}, + {FL_Caps_Lock,"\xe2\x87\xaa"}, // upwards white arrow from bar + {FL_Meta_L, "Meta_L"}, + {FL_Meta_R, "Meta_R"}, + {FL_Alt_L, "Alt_L"}, + {FL_Alt_R, "Alt_R"}, + {FL_Delete, "\xe2\x8c\xa7"} // x in a rectangle box +}; +#endif + +/** + Get a human-readable string from a shortcut value. + + Unparse a shortcut value as used by Fl_Button or Fl_Menu_Item into + a human-readable string like "Alt+N". This only works if the shortcut + is a character key or a numbered function key. If the shortcut is + zero then an empty string is returned. The return value points at + a static buffer that is overwritten with each call. + + \param [in] shortcut the integer value containing the ascii charcter or extended keystroke plus modifiers + \return a pointer to a static buffer containing human readable text for the shortcut + */ +const char* fl_shortcut_label(unsigned int shortcut) { + return fl_shortcut_label(shortcut, 0L); +} + +/** + Get a human-readable string from a shortcut value. + + \param [in] shortcut the integer value containing the ascii charcter or extended keystroke plus modifiers + \param [in] eom if this pointer is set, it will receive a pointer to the end of the modifier text + \return a pointer to a static buffer containing human readable text for the shortcut + \see fl_shortcut_label(unsigned int shortcut) + */ +const char* fl_shortcut_label(unsigned int shortcut, const char **eom) { + static char buf[20]; + char *p = buf; + if (eom) *eom = p; + if (!shortcut) {*p = 0; return buf;} + // fix upper case shortcuts + unsigned int v = shortcut & FL_KEY_MASK; + if (((unsigned)fl_tolower(v))!=v) { + shortcut |= FL_SHIFT; + } +#ifdef __APPLE__ + // this column contains utf8 characters - v + if (shortcut & FL_SHIFT) {strcpy(p,"\xe2\x87\xa7"); p += 3;} // upwards white arrow + if (shortcut & FL_CTRL) {strcpy(p,"\xe2\x8c\x83"); p += 3;} // up arrowhead + if (shortcut & FL_ALT) {strcpy(p,"\xe2\x8c\xa5"); p += 3;} // alternative key symbol + if (shortcut & FL_META) {strcpy(p,"\xe2\x8c\x98"); p += 3;} // place of interest sign +#else + if (shortcut & FL_META) {strcpy(p,"Meta+"); p += 5;} + if (shortcut & FL_ALT) {strcpy(p,"Alt+"); p += 4;} + if (shortcut & FL_SHIFT) {strcpy(p,"Shift+"); p += 6;} + if (shortcut & FL_CTRL) {strcpy(p,"Ctrl+"); p += 5;} +#endif // __APPLE__ + if (eom) *eom = p; + unsigned int key = shortcut & FL_KEY_MASK; +#if defined(WIN32) || defined(__APPLE__) // if not X + if (key >= FL_F && key <= FL_F_Last) { + *p++ = 'F'; + if (key > FL_F+9) *p++ = (key-FL_F)/10+'0'; + *p++ = (key-FL_F)%10 + '0'; + } else { + // binary search the table for a match: + int a = 0; + int b = sizeof(table)/sizeof(*table); + while (a < b) { + int c = (a+b)/2; + if (table[c].key == key) { + if (p > buf) { + strcpy(p,table[c].name); + return buf; + } else { + const char *sp = table[c].name; + if (eom) *eom = sp; + return sp; + } + } + if (table[c].key < key) a = c+1; + else b = c; + } + if (key >= FL_KP && key <= FL_KP_Last) { + // mark keypad keys with KP_ prefix + strcpy(p,"KP_"); p += 3; + *p++ = uchar(key & 127); + } else { + // if none found, use the keystroke as a match: + p += fl_utf8encode(fl_toupper(key), p); + } + } + *p = 0; + return buf; +#else + const char* q; + if (key == FL_Enter || key == '\r') q="Enter"; // don't use Xlib's "Return": + else if (key > 32 && key < 0x100) q = 0; + else q = XKeysymToString(key); + if (!q) { + p += fl_utf8encode(fl_toupper(key), p); + *p = 0; + return buf; + } + if (p > buf) { + strcpy(p,q); + return buf; + } else { + if (eom) *eom = q; + return q; + } +#endif +} + +// Emulation of XForms named shortcuts +#include +/** + Emulation of XForms named shortcuts. + + Converts ascii shortcut specifications (eg. "^c") + into the FLTK integer equivalent (eg. FL_CTRL+'c') + + These ascii characters are used to specify the various keyboard modifier keys: + \verbatim + # - Alt + + - Shift + ^ - Control + \endverbatim +*/ +unsigned int fl_old_shortcut(const char* s) { + if (!s || !*s) return 0; + unsigned int n = 0; + if (*s == '#') {n |= FL_ALT; s++;} + if (*s == '+') {n |= FL_SHIFT; s++;} + if (*s == '^') {n |= FL_CTRL; s++;} + if (*s && s[1]) return n | (int)strtol(s,0,0); // allow 0xf00 to get any key + return n | *s; +} + +// Tests for &x shortcuts in button labels: + +/** Returns the Unicode value of the '&x' shortcut in a given text. + + The given text \p t (usually a widget's label or a menu text) is + searched for a '&x' shortcut label, and if found, the Unicode + value of the '&x' shortcut is returned. + + \param t text or label to search for '&x' shortcut. + + \return Unicode (UCS-4) value of shortcut in \p t or 0. + + \note Internal use only. +*/ +unsigned int Fl_Widget::label_shortcut(const char *t) { + if (!t) return 0; + for (;;) { + if (*t==0) return 0; + if (*t=='&') { + unsigned int s = fl_utf8decode(t+1, 0, 0); + if (s==0) return 0; + else if (s==(unsigned int)'&') t++; + else return s; + } + t++; + } +} + +/** Returns true if the given text \p t contains the entered '&x' shortcut. + + This method must only be called in handle() methods or callbacks after + a keypress event (usually FL_KEYDOWN or FL_SHORTCUT). The given text + \p t (usually a widget's label or menu text) is searched for a '&x' + shortcut, and if found, this is compared with the entered key value. + + Fl::event_text() is used to get the entered key value. + Fl::event_state() is used to get the Alt modifier, if \p require_alt + is true. + + \param t text or label to search for '&x' shortcut. + \param require_alt if true: match only if Alt key is pressed. + + \return true, if the entered text matches the '&x' shortcut in \p t + false (0) otherwise. + + \note Internal use only. +*/ +int Fl_Widget::test_shortcut(const char *t, const bool require_alt) { + if (!t) return 0; + // for menubars etc. shortcuts must work only if the Alt modifier is pressed + if (require_alt && Fl::event_state(FL_ALT)==0) return 0; + unsigned int c = fl_utf8decode(Fl::event_text(), Fl::event_text()+Fl::event_length(), 0); + if (!c) return 0; + if (c == label_shortcut(t)) + return 1; + return 0; +} + +/** Returns true if the widget's label contains the entered '&x' shortcut. + + This method must only be called in handle() methods or callbacks after + a keypress event (usually FL_KEYDOWN or FL_SHORTCUT). + The widget's label is searched for a '&x' + shortcut, and if found, this is compared with the entered key value. + + Fl::event_text() is used to get the entered key value. + + \return true, if the entered text matches the widget's'&x' shortcut, + false (0) otherwise. + + \note Internal use only. +*/ + +int Fl_Widget::test_shortcut() { + if (!(flags()&SHORTCUT_LABEL)) return 0; + return test_shortcut(label()); +} + +// +// End of "$Id: fl_shortcut.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_show_colormap.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_show_colormap.cxx new file mode 100644 index 0000000..b3d705a --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_show_colormap.cxx @@ -0,0 +1,162 @@ +// +// "$Id: fl_show_colormap.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Colormap color selection dialog for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include +#include +#include + +#define BOXSIZE 14 +#define BORDER 4 + +/** + This widget creates a modal window for selecting a color from the colormap. + Pretty much unchanged from Forms. +*/ +class ColorMenu : public Fl_Window { + Fl_Color initial; + Fl_Color which, previous; + int done; + void drawbox(Fl_Color); + void draw(); + int handle(int); +public: + ColorMenu(Fl_Color oldcol); + Fl_Color run(); +}; + +ColorMenu::ColorMenu(Fl_Color oldcol) : + Fl_Window(BOXSIZE*8+1+2*BORDER, BOXSIZE*32+1+2*BORDER) { + clear_border(); + set_modal(); + initial = which = oldcol; +} + +void ColorMenu::drawbox(Fl_Color c) { + if (c < 0 || c > 255) return; + int X = (c%8)*BOXSIZE+BORDER; + int Y = (c/8)*BOXSIZE+BORDER; +#if BORDER_WIDTH < 3 + if (c == which) fl_draw_box(FL_DOWN_BOX, X+1, Y+1, BOXSIZE-1, BOXSIZE-1, c); + else fl_draw_box(FL_BORDER_BOX, X, Y, BOXSIZE+1, BOXSIZE+1, c); +#else + fl_draw_box(c == which ? FL_DOWN_BOX : FL_BORDER_BOX, + X, Y, BOXSIZE+1, BOXSIZE+1, c); +#endif +} + +void ColorMenu::draw() { + if (damage() != FL_DAMAGE_CHILD) { + fl_draw_box(FL_UP_BOX,0,0,w(),h(),color()); + for (int c = 0; c < 256; c++) drawbox((Fl_Color)c); + } else { + drawbox(previous); + drawbox(which); + } + previous = which; +} + +int ColorMenu::handle(int e) { + Fl_Color c = which; + switch (e) { + case FL_PUSH: + case FL_DRAG: { + int X = (Fl::event_x_root() - x() - BORDER); + if (X >= 0) X = X/BOXSIZE; + int Y = (Fl::event_y_root() - y() - BORDER); + if (Y >= 0) Y = Y/BOXSIZE; + if (X >= 0 && X < 8 && Y >= 0 && Y < 32) + c = 8*Y + X; + else + c = initial; + } break; + case FL_RELEASE: + done = 1; + return 1; + case FL_KEYBOARD: + switch (Fl::event_key()) { + case FL_Up: if (c > 7) c -= 8; break; + case FL_Down: if (c < 256-8) c += 8; break; + case FL_Left: if (c > 0) c--; break; + case FL_Right: if (c < 255) c++; break; + case FL_Escape: which = initial; done = 1; return 1; + case FL_KP_Enter: + case FL_Enter: done = 1; return 1; + default: return 0; + } + break; + default: + return 0; + } + if (c != which) { + which = (Fl_Color)c; damage(FL_DAMAGE_CHILD); + int bx = (c%8)*BOXSIZE+BORDER; + int by = (c/8)*BOXSIZE+BORDER; + int px = x(); + int py = y(); + int scr_x, scr_y, scr_w, scr_h; + Fl::screen_xywh(scr_x, scr_y, scr_w, scr_h); + if (px < scr_x) px = scr_x; + if (px+bx+BOXSIZE+BORDER >= scr_x+scr_w) px = scr_x+scr_w-bx-BOXSIZE-BORDER; + if (py < scr_y) py = scr_y; + if (py+by+BOXSIZE+BORDER >= scr_y+scr_h) py = scr_y+scr_h-by-BOXSIZE-BORDER; + if (px+bx < BORDER) px = BORDER-bx; + if (py+by < BORDER) py = BORDER-by; + position(px,py); + } + return 1; +} + +extern char fl_override_redirect; // hack for menus + +#ifdef _MSC_VER +#pragma optimize("a",off) // needed to get the done check to work +#endif +Fl_Color ColorMenu::run() { + if (which < 0 || which > 255) { + position(Fl::event_x_root()-w()/2, Fl::event_y_root()-y()/2); + } else { + position(Fl::event_x_root()-(initial%8)*BOXSIZE-BOXSIZE/2-BORDER, + Fl::event_y_root()-(initial/8)*BOXSIZE-BOXSIZE/2-BORDER); + } + show(); + Fl::grab(*this); + done = 0; + while (!done) Fl::wait(); + Fl::grab(0); + return which; +} + +Fl_Color fl_show_colormap(Fl_Color oldcol) { + ColorMenu m(oldcol); + return m.run(); +} + +// +// End of "$Id: fl_show_colormap.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_symbols.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_symbols.cxx new file mode 100644 index 0000000..a68f39a --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_symbols.cxx @@ -0,0 +1,714 @@ +// +// "$Id: fl_symbols.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Symbol drawing code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// These are small graphics drawn by the normal label-drawing +// code when the string starts with an '@' sign. + +// Adapted from original code written by: + +// Written by Mark Overmars +// Version 2.1 a +// Date: Oct 2, 1992 + +#include +#include +#include +#include "flstring.h" + +typedef struct { + const char *name; + void (*drawit)(Fl_Color); + char scalable; + char notempty; +} SYMBOL; + +#define MAXSYMBOL 211 + /* Maximal number of symbols in table. Only half of them are + used. Should be prime. */ + +static SYMBOL symbols[MAXSYMBOL]; /* The symbols */ +static int symbnumb = -1; /* Their number */ + +static int find(const char *name) { +// returns hash entry if it exists, or first empty slot: + int pos = name[0] ? ( + name[1] ? ( + name[2] ? 71*name[0]+31*name[1]+name[2] : 31*name[0]+name[1] + ) : + name[0] + ) : 0; + pos %= MAXSYMBOL; + int hh2 = name[0] ? ( + (name[1]) ? 51*name[0]+3*name[1] : 3*name[0] + ) : 1; + hh2 %= MAXSYMBOL; if (!hh2) hh2 = 1; + for (;;) { + if (!symbols[pos].notempty) return pos; + if (!strcmp(symbols[pos].name,name)) return pos; + pos = (pos + hh2) % MAXSYMBOL; + } +} + +static void fl_init_symbols(void); + +/**************** The routines seen by the user *************************/ + +/** + Adds a symbol to the system. + \param[in] name name of symbol (without the "@") + \param[in] drawit function to draw symbol + \param[in] scalable set to 1 if \p drawit uses scalable vector drawing + \returns 1 on success, 0 on failure + */ +int fl_add_symbol(const char *name, void (*drawit)(Fl_Color), int scalable) +{ + fl_init_symbols(); + int pos; + if (symbnumb > MAXSYMBOL / 2) return 0; // table is full + pos = find(name); + symbols[pos].name = name; + symbols[pos].drawit = drawit; + symbols[pos].notempty = 1; + symbols[pos].scalable = scalable; + symbnumb++; + return 1; +} + +int fl_return_arrow(int x,int y,int w,int h); + +/** + Draw the named symbol in the given rectangle using the given color + \param[in] label name of symbol + \param[in] x,y position of symbol + \param[in] w,h size of symbol + \param[in] col color of symbox + \returns 1 on success, 0 on failure + */ +// provided for back compatibility: +int fl_draw_symbol(const char *label,int x,int y,int w,int h,Fl_Color col) { + const char *p = label; + if (*p++ != '@') return 0; + fl_init_symbols(); + int equalscale = 0; + if (*p == '#') {equalscale = 1; p++;} + if (*p == '-' && p[1]>='1' && p[1]<='9') { + int n = p[1]-'0'; + x += n; y += n; w -= 2*n; h -= 2*n; + p += 2; + } else if (*p == '+' && p[1]>='1' && p[1]<='9') { + int n = p[1]-'0'; + x -= n; y -= n; w += 2*n; h += 2*n; + p += 2; + } + if (w < 10) {x -= (10-w)/2; w = 10;} + if (h < 10) {y -= (10-h)/2; h = 10;} + w = (w-1)|1; h = (h-1)|1; + char flip_x = 0, flip_y = 0; + if (*p=='$') { + flip_x = 1; + p++; + } + if (*p=='%') { + flip_y = 1; + p++; + } + int rotangle; + switch (*p++) { + case '0': + rotangle = 1000*(p[1]-'0') + 100*(p[2]-'0') + 10*(p[3]-'0'); + p += 4; + break; + case '1': rotangle = 2250; break; + case '2': rotangle = 2700; break; + case '3': rotangle = 3150; break; + case '4': rotangle = 1800; break; + case '5': + case '6': rotangle = 0; break; + case '7': rotangle = 1350; break; + case '8': rotangle = 900; break; + case '9': rotangle = 450; break; + default: rotangle = 0; p--; break; + } + int pos = find(p); + if (!symbols[pos].notempty) return 0; + if (symbols[pos].scalable == 3) { // kludge to detect return arrow + fl_return_arrow(x,y,w,h); + return 1; + } + fl_push_matrix(); + fl_translate(x+w/2,y+h/2); + if (symbols[pos].scalable) { + if (equalscale) {if (w0; i--, a-=da, r-=dr1) { + double ar = a/180.0 * M_PI; + vv(cos(ar)*r, sin(ar)*r); + } + for (i=27; i>=0; a+=da, i--, r-=dr2) { + double ar = a/180.0 * M_PI; + vv(cos(ar)*r, sin(ar)*r); + } + if (j&1) { + EC; + } else { + ECP; + } + } +} + +static void draw_refresh(Fl_Color c) { + draw_round_arrow(c); + fl_rotate(180.0); + draw_round_arrow(c); + fl_rotate(-180.0); +} + +static void draw_reload(Fl_Color c) { + fl_rotate(-135.0); + draw_round_arrow(c, 10); + fl_rotate(135.0); +} + +static void draw_undo(Fl_Color c) { + fl_translate(0.0, 0.2); + fl_scale(1.0, -1.0); + draw_round_arrow(c, 6); + fl_scale(1.0, -1.0); + fl_translate(0.0, -0.2); +} + +static void draw_redo(Fl_Color c) { + fl_scale(-1.0, 1.0); + draw_undo(c); + fl_scale(-1.0, 1.0); +} + +static void fl_init_symbols(void) { + static char beenhere; + if (beenhere) return; + beenhere = 1; + symbnumb = 0; + + fl_add_symbol("", draw_arrow1, 1); + fl_add_symbol("->", draw_arrow1, 1); + fl_add_symbol(">", draw_arrow2, 1); + fl_add_symbol(">>", draw_arrow3, 1); + fl_add_symbol(">|", draw_arrowbar, 1); + fl_add_symbol(">[]", draw_arrowbox, 1); + fl_add_symbol("|>", draw_bararrow, 1); + fl_add_symbol("<-", draw_arrow01, 1); + fl_add_symbol("<", draw_arrow02, 1); + fl_add_symbol("<<", draw_arrow03, 1); + fl_add_symbol("|<", draw_0arrowbar, 1); + fl_add_symbol("[]<", draw_0arrowbox, 1); + fl_add_symbol("<|", draw_0bararrow, 1); + fl_add_symbol("<->", draw_doublearrow, 1); + fl_add_symbol("-->", draw_arrow, 1); + fl_add_symbol("+", draw_plus, 1); + fl_add_symbol("->|", draw_arrow1bar, 1); + fl_add_symbol("arrow", draw_arrow, 1); + fl_add_symbol("returnarrow", 0, 3); + fl_add_symbol("square", draw_square, 1); + fl_add_symbol("circle", draw_circle, 1); + fl_add_symbol("line", draw_line, 1); + fl_add_symbol("plus", draw_plus, 1); + fl_add_symbol("menu", draw_menu, 1); + fl_add_symbol("UpArrow", draw_uparrow, 1); + fl_add_symbol("DnArrow", draw_downarrow, 1); + fl_add_symbol("||", draw_doublebar, 1); + fl_add_symbol("search", draw_search, 1); + fl_add_symbol("FLTK", draw_fltk, 1); + + fl_add_symbol("filenew", draw_filenew, 1); + fl_add_symbol("fileopen", draw_fileopen, 1); + fl_add_symbol("filesave", draw_filesave, 1); + fl_add_symbol("filesaveas", draw_filesaveas, 1); + fl_add_symbol("fileprint", draw_fileprint, 1); + + fl_add_symbol("refresh", draw_refresh, 1); + fl_add_symbol("reload", draw_reload, 1); + fl_add_symbol("undo", draw_undo, 1); + fl_add_symbol("redo", draw_redo, 1); + +// fl_add_symbol("file", draw_file, 1); +} + +// +// End of "$Id: fl_symbols.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_utf.c b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_utf.c new file mode 100644 index 0000000..aeeae5b --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_utf.c @@ -0,0 +1,909 @@ +/* + * "$Id: fl_utf.c 7903 2010-11-28 21:06:39Z matt $" + * + * This is the utf.c file from fltk2 adapted for use in my fltk1.1 port + */ +/* Copyright 2006-2010 by Bill Spitzak and others. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems on the following page: + * + * http://www.fltk.org/str.php + */ + +/* Modified to obey rfc3629, which limits unicode to 0-0x10ffff */ + +#include +#include +#include + +/** \addtogroup fl_unicode + @{ +*/ + + +#if 0 + /** + \defgroup fl_unichar Unicode Character Functions + Global Functions Handling Single Unicode Characters + @{ */ + + /** + Converts a Unicode character into a utf-8 sequence. + \param[in] uc Unicode character + \param[out] text utf-8 sequence will be written here; if this pointer is + \c NULL, only the length of the utf-8 sequence is calculated + \return length of the sequence in bytes + */ + /* FL_EXPORT int fl_unichar_to_utf8(unsigned int uc, char *text); */ + + /** @} */ + + /** + \defgroup fl_utf8 Unicode String Functions + Global Functions Handling Unicode Text + @{ */ + + /** + Calculate the size of a utf-8 sequence for a Unicode character. + \param[in] uc Unicode character + \return length of the sequence in bytes + */ + /* FL_EXPORT int fl_utf8_size(unsigned int uc); */ + + /** @} */ +#endif /* 0 */ + +/*!Set to 1 to turn bad UTF8 bytes into ISO-8859-1. If this is to zero + they are instead turned into the Unicode REPLACEMENT CHARACTER, of + value 0xfffd. + If this is on fl_utf8decode() will correctly map most (perhaps all) + human-readable text that is in ISO-8859-1. This may allow you + to completely ignore character sets in your code because virtually + everything is either ISO-8859-1 or UTF-8. +*/ +#define ERRORS_TO_ISO8859_1 1 + +/*!Set to 1 to turn bad UTF8 bytes in the 0x80-0x9f range into the + Unicode index for Microsoft's CP1252 character set. You should + also set ERRORS_TO_ISO8859_1. With this a huge amount of more + available text (such as all web pages) are correctly converted + to Unicode. +*/ +#define ERRORS_TO_CP1252 1 + +/*!A number of Unicode code points are in fact illegal and should not + be produced by a UTF-8 converter. Turn this on will replace the + bytes in those encodings with errors. If you do this then converting + arbitrary 16-bit data to UTF-8 and then back is not an identity, + which will probably break a lot of software. +*/ +#define STRICT_RFC3629 0 + +#if ERRORS_TO_CP1252 +/* Codes 0x80..0x9f from the Microsoft CP1252 character set, translated + * to Unicode: + */ +static unsigned short cp1252[32] = { + 0x20ac, 0x0081, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, + 0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, 0x008d, 0x017d, 0x008f, + 0x0090, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + 0x02dc, 0x2122, 0x0161, 0x203a, 0x0153, 0x009d, 0x017e, 0x0178 +}; +#endif + +/*! Decode a single UTF-8 encoded character starting at \e p. The + resulting Unicode value (in the range 0-0x10ffff) is returned, + and \e len is set to the number of bytes in the UTF-8 encoding + (adding \e len to \e p will point at the next character). + + If \p p points at an illegal UTF-8 encoding, including one that + would go past \e end, or where a code is uses more bytes than + necessary, then *(unsigned char*)p is translated as though it is + in the Microsoft CP1252 character set and \e len is set to 1. + Treating errors this way allows this to decode almost any + ISO-8859-1 or CP1252 text that has been mistakenly placed where + UTF-8 is expected, and has proven very useful. + + If you want errors to be converted to error characters (as the + standards recommend), adding a test to see if the length is + unexpectedly 1 will work: + + \code + if (*p & 0x80) { // what should be a multibyte encoding + code = fl_utf8decode(p,end,&len); + if (len<2) code = 0xFFFD; // Turn errors into REPLACEMENT CHARACTER + } else { // handle the 1-byte utf8 encoding: + code = *p; + len = 1; + } + \endcode + + Direct testing for the 1-byte case (as shown above) will also + speed up the scanning of strings where the majority of characters + are ASCII. +*/ +unsigned fl_utf8decode(const char* p, const char* end, int* len) +{ + unsigned char c = *(unsigned char*)p; + if (c < 0x80) { + if (len) *len = 1; + return c; +#if ERRORS_TO_CP1252 + } else if (c < 0xa0) { + if (len) *len = 1; + return cp1252[c-0x80]; +#endif + } else if (c < 0xc2) { + goto FAIL; + } + if ( (end && p+1 >= end) || (p[1]&0xc0) != 0x80) goto FAIL; + if (c < 0xe0) { + if (len) *len = 2; + return + ((p[0] & 0x1f) << 6) + + ((p[1] & 0x3f)); + } else if (c == 0xe0) { + if (((unsigned char*)p)[1] < 0xa0) goto FAIL; + goto UTF8_3; +#if STRICT_RFC3629 + } else if (c == 0xed) { + /* RFC 3629 says surrogate chars are illegal. */ + if (((unsigned char*)p)[1] >= 0xa0) goto FAIL; + goto UTF8_3; + } else if (c == 0xef) { + /* 0xfffe and 0xffff are also illegal characters */ + if (((unsigned char*)p)[1]==0xbf && + ((unsigned char*)p)[2]>=0xbe) goto FAIL; + goto UTF8_3; +#endif + } else if (c < 0xf0) { + UTF8_3: + if ( (end && p+2 >= end) || (p[2]&0xc0) != 0x80) goto FAIL; + if (len) *len = 3; + return + ((p[0] & 0x0f) << 12) + + ((p[1] & 0x3f) << 6) + + ((p[2] & 0x3f)); + } else if (c == 0xf0) { + if (((unsigned char*)p)[1] < 0x90) goto FAIL; + goto UTF8_4; + } else if (c < 0xf4) { + UTF8_4: + if ( (end && p+3 >= end) || (p[2]&0xc0) != 0x80 || (p[3]&0xc0) != 0x80) goto FAIL; + if (len) *len = 4; +#if STRICT_RFC3629 + /* RFC 3629 says all codes ending in fffe or ffff are illegal: */ + if ((p[1]&0xf)==0xf && + ((unsigned char*)p)[2] == 0xbf && + ((unsigned char*)p)[3] >= 0xbe) goto FAIL; +#endif + return + ((p[0] & 0x07) << 18) + + ((p[1] & 0x3f) << 12) + + ((p[2] & 0x3f) << 6) + + ((p[3] & 0x3f)); + } else if (c == 0xf4) { + if (((unsigned char*)p)[1] > 0x8f) goto FAIL; /* after 0x10ffff */ + goto UTF8_4; + } else { + FAIL: + if (len) *len = 1; +#if ERRORS_TO_ISO8859_1 + return c; +#else + return 0xfffd; /* Unicode REPLACEMENT CHARACTER */ +#endif + } +} + +/*! Move \p p forward until it points to the start of a UTF-8 + character. If it already points at the start of one then it + is returned unchanged. Any UTF-8 errors are treated as though each + byte of the error is an individual character. + + \e start is the start of the string and is used to limit the + backwards search for the start of a utf8 character. + + \e end is the end of the string and is assumed to be a break + between characters. It is assumed to be greater than p. + + This function is for moving a pointer that was jumped to the + middle of a string, such as when doing a binary search for + a position. You should use either this or fl_utf8back() depending + on which direction your algorithim can handle the pointer + moving. Do not use this to scan strings, use fl_utf8decode() + instead. +*/ +const char* fl_utf8fwd(const char* p, const char* start, const char* end) +{ + const char* a; + int len; + /* if we are not pointing at a continuation character, we are done: */ + if ((*p&0xc0) != 0x80) return p; + /* search backwards for a 0xc0 starting the character: */ + for (a = p-1; ; --a) { + if (a < start) return p; + if (!(a[0]&0x80)) return p; + if ((a[0]&0x40)) break; + } + fl_utf8decode(a,end,&len); + a += len; + if (a > p) return a; + return p; +} + +/*! Move \p p backward until it points to the start of a UTF-8 + character. If it already points at the start of one then it + is returned unchanged. Any UTF-8 errors are treated as though each + byte of the error is an individual character. + + \e start is the start of the string and is used to limit the + backwards search for the start of a UTF-8 character. + + \e end is the end of the string and is assumed to be a break + between characters. It is assumed to be greater than p. + + If you wish to decrement a UTF-8 pointer, pass p-1 to this. +*/ +const char* fl_utf8back(const char* p, const char* start, const char* end) +{ + const char* a; + int len; + /* if we are not pointing at a continuation character, we are done: */ + if ((*p&0xc0) != 0x80) return p; + /* search backwards for a 0xc0 starting the character: */ + for (a = p-1; ; --a) { + if (a < start) return p; + if (!(a[0]&0x80)) return p; + if ((a[0]&0x40)) break; + } + fl_utf8decode(a,end,&len); + if (a+len > p) return a; + return p; +} + +/*! Returns number of bytes that utf8encode() will use to encode the + character \p ucs. */ +int fl_utf8bytes(unsigned ucs) { + if (ucs < 0x000080U) { + return 1; + } else if (ucs < 0x000800U) { + return 2; + } else if (ucs < 0x010000U) { + return 3; + } else if (ucs <= 0x10ffffU) { + return 4; + } else { + return 3; /* length of the illegal character encoding */ + } +} + +/*! Write the UTF-8 encoding of \e ucs into \e buf and return the + number of bytes written. Up to 4 bytes may be written. If you know + that \p ucs is less than 0x10000 then at most 3 bytes will be written. + If you wish to speed this up, remember that anything less than 0x80 + is written as a single byte. + + If ucs is greater than 0x10ffff this is an illegal character + according to RFC 3629. These are converted as though they are + 0xFFFD (REPLACEMENT CHARACTER). + + RFC 3629 also says many other values for \p ucs are illegal (in + the range 0xd800 to 0xdfff, or ending with 0xfffe or + 0xffff). However I encode these as though they are legal, so that + utf8encode/fl_utf8decode will be the identity for all codes between 0 + and 0x10ffff. +*/ +int fl_utf8encode(unsigned ucs, char* buf) { + if (ucs < 0x000080U) { + buf[0] = ucs; + return 1; + } else if (ucs < 0x000800U) { + buf[0] = 0xc0 | (ucs >> 6); + buf[1] = 0x80 | (ucs & 0x3F); + return 2; + } else if (ucs < 0x010000U) { + buf[0] = 0xe0 | (ucs >> 12); + buf[1] = 0x80 | ((ucs >> 6) & 0x3F); + buf[2] = 0x80 | (ucs & 0x3F); + return 3; + } else if (ucs <= 0x0010ffffU) { + buf[0] = 0xf0 | (ucs >> 18); + buf[1] = 0x80 | ((ucs >> 12) & 0x3F); + buf[2] = 0x80 | ((ucs >> 6) & 0x3F); + buf[3] = 0x80 | (ucs & 0x3F); + return 4; + } else { + /* encode 0xfffd: */ + buf[0] = 0xefU; + buf[1] = 0xbfU; + buf[2] = 0xbdU; + return 3; + } +} + +/*! Convert a UTF-8 sequence into an array of wchar_t. These + are used by some system calls, especially on Windows. + + \p src points at the UTF-8, and \p srclen is the number of bytes to + convert. + + \p dst points at an array to write, and \p dstlen is the number of + locations in this array. At most \p dstlen-1 words will be + written there, plus a 0 terminating word. Thus this function + will never overwrite the buffer and will always return a + zero-terminated string. If \p dstlen is zero then \p dst can be + null and no data is written, but the length is returned. + + The return value is the number of words that \e would be written + to \p dst if it were long enough, not counting the terminating + zero. If the return value is greater or equal to \p dstlen it + indicates truncation, you can then allocate a new array of size + return+1 and call this again. + + Errors in the UTF-8 are converted as though each byte in the + erroneous string is in the Microsoft CP1252 encoding. This allows + ISO-8859-1 text mistakenly identified as UTF-8 to be printed + correctly. + + Notice that sizeof(wchar_t) is 2 on Windows and is 4 on Linux + and most other systems. Where wchar_t is 16 bits, Unicode + characters in the range 0x10000 to 0x10ffff are converted to + "surrogate pairs" which take two words each (this is called UTF-16 + encoding). If wchar_t is 32 bits this rather nasty problem is + avoided. +*/ +unsigned fl_utf8toUtf16(const char* src, unsigned srclen, + unsigned short* dst, unsigned dstlen) +{ + const char* p = src; + const char* e = src+srclen; + unsigned count = 0; + if (dstlen) for (;;) { + if (p >= e) {dst[count] = 0; return count;} + if (!(*p & 0x80)) { /* ascii */ + dst[count] = *p++; + } else { + int len; unsigned ucs = fl_utf8decode(p,e,&len); + p += len; + if (ucs < 0x10000) { + dst[count] = ucs; + } else { + /* make a surrogate pair: */ + if (count+2 >= dstlen) {dst[count] = 0; count += 2; break;} + dst[count] = (((ucs-0x10000u)>>10)&0x3ff) | 0xd800; + dst[++count] = (ucs&0x3ff) | 0xdc00; + } + } + if (++count == dstlen) {dst[count-1] = 0; break;} + } + /* we filled dst, measure the rest: */ + while (p < e) { + if (!(*p & 0x80)) p++; + else { + int len; unsigned ucs = fl_utf8decode(p,e,&len); + p += len; + if (ucs >= 0x10000) ++count; + } + ++count; + } + return count; +} + + +/** + Converts a UTF-8 string into a wide character string. + + This function generates 32-bit wchar_t (e.g. "ucs4" as it were) except + on win32 where it returns Utf16 with surrogate pairs where required. + */ +unsigned fl_utf8towc(const char* src, unsigned srclen, + wchar_t* dst, unsigned dstlen) +{ +#ifdef WIN32 + return fl_utf8toUtf16(src, srclen, (unsigned short*)dst, dstlen); +#else + const char* p = src; + const char* e = src+srclen; + unsigned count = 0; + if (dstlen) for (;;) { + if (p >= e) {dst[count] = 0; return count;} + if (!(*p & 0x80)) { /* ascii */ + dst[count] = *p++; + } else { + int len; unsigned ucs = fl_utf8decode(p,e,&len); + p += len; + dst[count] = (wchar_t)ucs; + } + if (++count == dstlen) {dst[count-1] = 0; break;} + } + /* we filled dst, measure the rest: */ + while (p < e) { + if (!(*p & 0x80)) p++; + else { + int len; fl_utf8decode(p,e,&len); + p += len; + } + ++count; + } + return count; +#endif +} + +/*! Convert a UTF-8 sequence into an array of 1-byte characters. + + If the UTF-8 decodes to a character greater than 0xff then it is + replaced with '?'. + + Errors in the UTF-8 are converted as individual bytes, same as + fl_utf8decode() does. This allows ISO-8859-1 text mistakenly identified + as UTF-8 to be printed correctly (and possibly CP1512 on Windows). + + \p src points at the UTF-8, and \p srclen is the number of bytes to + convert. + + Up to \p dstlen bytes are written to \p dst, including a null + terminator. The return value is the number of bytes that would be + written, not counting the null terminator. If greater or equal to + \p dstlen then if you malloc a new array of size n+1 you will have + the space needed for the entire string. If \p dstlen is zero then + nothing is written and this call just measures the storage space + needed. +*/ +unsigned fl_utf8toa(const char* src, unsigned srclen, + char* dst, unsigned dstlen) +{ + const char* p = src; + const char* e = src+srclen; + unsigned count = 0; + if (dstlen) for (;;) { + unsigned char c; + if (p >= e) {dst[count] = 0; return count;} + c = *(unsigned char*)p; + if (c < 0xC2) { /* ascii or bad code */ + dst[count] = c; + p++; + } else { + int len; unsigned ucs = fl_utf8decode(p,e,&len); + p += len; + if (ucs < 0x100) dst[count] = ucs; + else dst[count] = '?'; + } + if (++count >= dstlen) {dst[count-1] = 0; break;} + } + /* we filled dst, measure the rest: */ + while (p < e) { + if (!(*p & 0x80)) p++; + else { + int len; + fl_utf8decode(p,e,&len); + p += len; + } + ++count; + } + return count; +} + +/*! Turn "wide characters" as returned by some system calls + (especially on Windows) into UTF-8. + + Up to \p dstlen bytes are written to \p dst, including a null + terminator. The return value is the number of bytes that would be + written, not counting the null terminator. If greater or equal to + \p dstlen then if you malloc a new array of size n+1 you will have + the space needed for the entire string. If \p dstlen is zero then + nothing is written and this call just measures the storage space + needed. + + \p srclen is the number of words in \p src to convert. On Windows + this is not necessairly the number of characters, due to there + possibly being "surrogate pairs" in the UTF-16 encoding used. + On Unix wchar_t is 32 bits and each location is a character. + + On Unix if a \p src word is greater than 0x10ffff then this is an + illegal character according to RFC 3629. These are converted as + though they are 0xFFFD (REPLACEMENT CHARACTER). Characters in the + range 0xd800 to 0xdfff, or ending with 0xfffe or 0xffff are also + illegal according to RFC 3629. However I encode these as though + they are legal, so that fl_utf8towc will return the original data. + + On Windows "surrogate pairs" are converted to a single character + and UTF-8 encoded (as 4 bytes). Mismatched halves of surrogate + pairs are converted as though they are individual characters. +*/ +unsigned fl_utf8fromwc(char* dst, unsigned dstlen, + const wchar_t* src, unsigned srclen) { + unsigned i = 0; + unsigned count = 0; + if (dstlen) for (;;) { + unsigned ucs; + if (i >= srclen) {dst[count] = 0; return count;} + ucs = src[i++]; + if (ucs < 0x80U) { + dst[count++] = ucs; + if (count >= dstlen) {dst[count-1] = 0; break;} + } else if (ucs < 0x800U) { /* 2 bytes */ + if (count+2 >= dstlen) {dst[count] = 0; count += 2; break;} + dst[count++] = 0xc0 | (ucs >> 6); + dst[count++] = 0x80 | (ucs & 0x3F); +#ifdef WIN32 + } else if (ucs >= 0xd800 && ucs <= 0xdbff && i < srclen && + src[i] >= 0xdc00 && src[i] <= 0xdfff) { + /* surrogate pair */ + unsigned ucs2 = src[i++]; + ucs = 0x10000U + ((ucs&0x3ff)<<10) + (ucs2&0x3ff); + /* all surrogate pairs turn into 4-byte utf8 */ +#else + } else if (ucs >= 0x10000) { + if (ucs > 0x10ffff) { + ucs = 0xfffd; + goto J1; + } +#endif + if (count+4 >= dstlen) {dst[count] = 0; count += 4; break;} + dst[count++] = 0xf0 | (ucs >> 18); + dst[count++] = 0x80 | ((ucs >> 12) & 0x3F); + dst[count++] = 0x80 | ((ucs >> 6) & 0x3F); + dst[count++] = 0x80 | (ucs & 0x3F); + } else { +#ifndef WIN32 + J1: +#endif + /* all others are 3 bytes: */ + if (count+3 >= dstlen) {dst[count] = 0; count += 3; break;} + dst[count++] = 0xe0 | (ucs >> 12); + dst[count++] = 0x80 | ((ucs >> 6) & 0x3F); + dst[count++] = 0x80 | (ucs & 0x3F); + } + } + /* we filled dst, measure the rest: */ + while (i < srclen) { + unsigned ucs = src[i++]; + if (ucs < 0x80U) { + count++; + } else if (ucs < 0x800U) { /* 2 bytes */ + count += 2; +#ifdef WIN32 + } else if (ucs >= 0xd800 && ucs <= 0xdbff && i < srclen-1 && + src[i+1] >= 0xdc00 && src[i+1] <= 0xdfff) { + /* surrogate pair */ + ++i; +#else + } else if (ucs >= 0x10000 && ucs <= 0x10ffff) { +#endif + count += 4; + } else { + count += 3; + } + } + return count; +} + +/*! Convert an ISO-8859-1 (ie normal c-string) byte stream to UTF-8. + + It is possible this should convert Microsoft's CP1252 to UTF-8 + instead. This would translate the codes in the range 0x80-0x9f + to different characters. Currently it does not do this. + + Up to \p dstlen bytes are written to \p dst, including a null + terminator. The return value is the number of bytes that would be + written, not counting the null terminator. If greater or equal to + \p dstlen then if you malloc a new array of size n+1 you will have + the space needed for the entire string. If \p dstlen is zero then + nothing is written and this call just measures the storage space + needed. + + \p srclen is the number of bytes in \p src to convert. + + If the return value equals \p srclen then this indicates that + no conversion is necessary, as only ASCII characters are in the + string. +*/ +unsigned fl_utf8froma(char* dst, unsigned dstlen, + const char* src, unsigned srclen) { + const char* p = src; + const char* e = src+srclen; + unsigned count = 0; + if (dstlen) for (;;) { + unsigned char ucs; + if (p >= e) {dst[count] = 0; return count;} + ucs = *(unsigned char*)p++; + if (ucs < 0x80U) { + dst[count++] = ucs; + if (count >= dstlen) {dst[count-1] = 0; break;} + } else { /* 2 bytes (note that CP1252 translate could make 3 bytes!) */ + if (count+2 >= dstlen) {dst[count] = 0; count += 2; break;} + dst[count++] = 0xc0 | (ucs >> 6); + dst[count++] = 0x80 | (ucs & 0x3F); + } + } + /* we filled dst, measure the rest: */ + while (p < e) { + unsigned char ucs = *(unsigned char*)p++; + if (ucs < 0x80U) { + count++; + } else { + count += 2; + } + } + return count; +} + +#ifdef WIN32 +# include +#endif + +/*! Return true if the "locale" seems to indicate that UTF-8 encoding + is used. If true the fl_utf8to_mb and fl_utf8from_mb don't do anything + useful. + + It is highly recommended that you change your system so this + does return true. On Windows this is done by setting the + "codepage" to CP_UTF8. On Unix this is done by setting $LC_CTYPE + to a string containing the letters "utf" or "UTF" in it, or by + deleting all $LC* and $LANG environment variables. In the future + it is likely that all non-Asian Unix systems will return true, + due to the compatibility of UTF-8 with ISO-8859-1. +*/ +int fl_utf8locale(void) { + static int ret = 2; + if (ret == 2) { +#ifdef WIN32 + ret = GetACP() == CP_UTF8; +#else + char* s; + ret = 1; /* assume UTF-8 if no locale */ + if (((s = getenv("LC_CTYPE")) && *s) || + ((s = getenv("LC_ALL")) && *s) || + ((s = getenv("LANG")) && *s)) { + ret = (strstr(s,"utf") || strstr(s,"UTF")); + } +#endif + } + return ret; +} + +/*! Convert the UTF-8 used by FLTK to the locale-specific encoding + used for filenames (and sometimes used for data in files). + Unfortunately due to stupid design you will have to do this as + needed for filenames. This is a bug on both Unix and Windows. + + Up to \p dstlen bytes are written to \p dst, including a null + terminator. The return value is the number of bytes that would be + written, not counting the null terminator. If greater or equal to + \p dstlen then if you malloc a new array of size n+1 you will have + the space needed for the entire string. If \p dstlen is zero then + nothing is written and this call just measures the storage space + needed. + + If fl_utf8locale() returns true then this does not change the data. + It is copied and truncated as necessary to + the destination buffer and \p srclen is always returned. +*/ +unsigned fl_utf8to_mb(const char* src, unsigned srclen, + char* dst, unsigned dstlen) +{ + if (!fl_utf8locale()) { +#ifdef WIN32 + wchar_t lbuf[1024]; + wchar_t* buf = lbuf; + unsigned length = fl_utf8towc(src, srclen, buf, 1024); + unsigned ret; + if (length >= 1024) { + buf = (wchar_t*)(malloc((length+1)*sizeof(wchar_t))); + fl_utf8towc(src, srclen, buf, length+1); + } + if (dstlen) { + /* apparently this does not null-terminate, even though msdn + * documentation claims it does: + */ + ret = + WideCharToMultiByte(GetACP(), 0, buf, length, dst, dstlen, 0, 0); + dst[ret] = 0; + } + /* if it overflows or measuring length, get the actual length: */ + if (dstlen==0 || ret >= dstlen-1) + ret = + WideCharToMultiByte(GetACP(), 0, buf, length, 0, 0, 0, 0); + if (buf != lbuf) free((void*)buf); + return ret; +#else + wchar_t lbuf[1024]; + wchar_t* buf = lbuf; + unsigned length = fl_utf8towc(src, srclen, buf, 1024); + int ret; + if (length >= 1024) { + buf = (wchar_t*)(malloc((length+1)*sizeof(wchar_t))); + fl_utf8towc(src, srclen, buf, length+1); + } + if (dstlen) { + ret = wcstombs(dst, buf, dstlen); + if (ret >= dstlen-1) ret = wcstombs(0,buf,0); + } else { + ret = wcstombs(0,buf,0); + } + if (buf != lbuf) free((void*)buf); + if (ret >= 0) return (unsigned)ret; + /* on any errors we return the UTF-8 as raw text...*/ +#endif + } + /* identity transform: */ + if (srclen < dstlen) { + memcpy(dst, src, srclen); + dst[srclen] = 0; + } else { + memcpy(dst, src, dstlen-1); + dst[dstlen-1] = 0; + } + return srclen; +} + +/*! Convert a filename from the locale-specific multibyte encoding + used by Windows to UTF-8 as used by FLTK. + + Up to \p dstlen bytes are written to \p dst, including a null + terminator. The return value is the number of bytes that would be + written, not counting the null terminator. If greater or equal to + \p dstlen then if you malloc a new array of size n+1 you will have + the space needed for the entire string. If \p dstlen is zero then + nothing is written and this call just measures the storage space + needed. + + On Unix or on Windows when a UTF-8 locale is in effect, this + does not change the data. It is copied and truncated as necessary to + the destination buffer and \p srclen is always returned. + You may also want to check if fl_utf8test() returns non-zero, so that + the filesystem can store filenames in UTF-8 encoding regardless of + the locale. +*/ +unsigned fl_utf8from_mb(char* dst, unsigned dstlen, + const char* src, unsigned srclen) +{ + if (!fl_utf8locale()) { +#ifdef WIN32 + wchar_t lbuf[1024]; + wchar_t* buf = lbuf; + unsigned length; + unsigned ret; + length = MultiByteToWideChar(GetACP(), 0, src, srclen, buf, 1024); + if ((length == 0)&&(GetLastError()==ERROR_INSUFFICIENT_BUFFER)) { + length = MultiByteToWideChar(GetACP(), 0, src, srclen, 0, 0); + buf = (wchar_t*)(malloc(length*sizeof(wchar_t))); + MultiByteToWideChar(GetACP(), 0, src, srclen, buf, length); + } + ret = fl_utf8fromwc(dst, dstlen, buf, length); + if (buf != lbuf) free((void*)buf); + return ret; +#else + wchar_t lbuf[1024]; + wchar_t* buf = lbuf; + int length; + unsigned ret; + length = mbstowcs(buf, src, 1024); + if (length >= 1024) { + length = mbstowcs(0, src, 0)+1; + buf = (wchar_t*)(malloc(length*sizeof(wchar_t))); + mbstowcs(buf, src, length); + } + if (length >= 0) { + ret = fl_utf8fromwc(dst, dstlen, buf, length); + if (buf != lbuf) free((void*)buf); + return ret; + } + /* errors in conversion return the UTF-8 unchanged */ +#endif + } + /* identity transform: */ + if (srclen < dstlen) { + memcpy(dst, src, srclen); + dst[srclen] = 0; + } else { + memcpy(dst, src, dstlen-1); + dst[dstlen-1] = 0; + } + return srclen; +} + +/*! Examines the first \p srclen bytes in \p src and returns a verdict + on whether it is UTF-8 or not. + - Returns 0 if there is any illegal UTF-8 sequences, using the + same rules as fl_utf8decode(). Note that some UCS values considered + illegal by RFC 3629, such as 0xffff, are considered legal by this. + - Returns 1 if there are only single-byte characters (ie no bytes + have the high bit set). This is legal UTF-8, but also indicates + plain ASCII. It also returns 1 if \p srclen is zero. + - Returns 2 if there are only characters less than 0x800. + - Returns 3 if there are only characters less than 0x10000. + - Returns 4 if there are characters in the 0x10000 to 0x10ffff range. + + Because there are many illegal sequences in UTF-8, it is almost + impossible for a string in another encoding to be confused with + UTF-8. This is very useful for transitioning Unix to UTF-8 + filenames, you can simply test each filename with this to decide + if it is UTF-8 or in the locale encoding. My hope is that if + this is done we will be able to cleanly transition to a locale-less + encoding. +*/ +int fl_utf8test(const char* src, unsigned srclen) { + int ret = 1; + const char* p = src; + const char* e = src+srclen; + while (p < e) { + if (*p & 0x80) { + int len; fl_utf8decode(p,e,&len); + if (len < 2) return 0; + if (len > ret) ret = len; + p += len; + } else { + p++; + } + } + return ret; +} + +/* forward declare mk_wcwidth() as static so the name is not visible. + */ + static int mk_wcwidth(unsigned int ucs); + + /* include the c source directly so it's contents are only visible here + */ +#include "xutf8/mk_wcwidth.c" + +/** wrapper to adapt Markus Kuhn's implementation of wcwidth() for FLTK + \param [in] ucs Unicode character value + \returns width of character in columns + + See http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c for Markus Kuhn's + original implementation of wcwidth() and wcswidth() + (defined in IEEE Std 1002.1-2001) for Unicode. + + \b WARNING: this function returns widths for "raw" Unicode characters. + It does not even try to map C1 control characters (0x80 to 0x9F) to + CP1252, and C0/C1 control characters and DEL will return -1. + You are advised to use fl_width(const char* src) instead. + */ +int fl_wcwidth_(unsigned int ucs) { + return mk_wcwidth(ucs); +} + +/** extended wrapper around fl_wcwidth_(unsigned int ucs) function. + \param[in] src pointer to start of UTF-8 byte sequence + \returns width of character in columns + + Depending on build options, this function may map C1 control + characters (0x80 to 0x9f) to CP1252, and return the width of + that character instead. This is not the same behaviour as + fl_wcwidth_(unsigned int ucs) . + + Note that other control characters and DEL will still return -1, + so if you want different behaviour, you need to test for those + characters before calling fl_wcwidth(), and handle them separately. + */ +int fl_wcwidth(const char* src) { + int len = fl_utf8len(*src); + int ret = 0; + unsigned int ucs = fl_utf8decode(src, src+len, &ret); + int width = fl_wcwidth_(ucs); + return width; +} + +/** @} */ + +/* + * End of "$Id: fl_utf.c 7903 2010-11-28 21:06:39Z matt $". + */ diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_utf8.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_utf8.cxx new file mode 100644 index 0000000..22ad2ea --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_utf8.cxx @@ -0,0 +1,827 @@ +// +// "$Id: fl_utf8.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Unicode to UTF-8 conversion functions. +// +// Author: Jean-Marc Lienher ( http://oksid.ch ) +// Copyright 2000-2010 by O'ksi'D. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php + + +#include +#include +#include + +#if defined(WIN32) && !defined(__CYGWIN__) +# include +# include +# include +# include +# include +#ifdef __CYGWIN__ +#include +#else +#include +#endif +extern "C" { + int XUtf8Tolower(int ucs); + unsigned short XUtf8IsNonSpacing(unsigned int ucs); +}; + +#elif defined(__APPLE__) +# include +# include +//# include +# include +# include +# include +# include +# include +# include + +extern "C" { + int XUtf8Tolower(int ucs); + unsigned short XUtf8IsNonSpacing(unsigned int ucs); +} + +#else // X-windows platform + +# include +# include +# include +# include +# include +#endif // WIN32 + +#include +#include +#include + +#undef fl_open + +/** \addtogroup fl_unicode + @{ +*/ + +/*** NOTE : all functions are LIMITED to 24 bits Unicode values !!! ***/ +/*** but only 16 bits are really used under Linux and win32 ***/ + + +#define NBC 0xFFFF + 1 + +static int +Toupper( + int ucs) +{ + long i; + static unsigned short *table = NULL; + + if (!table) { + table = (unsigned short*) malloc( + sizeof(unsigned short) * (NBC)); + for (i = 0; i < NBC; i++) { + table[i] = (unsigned short) i; + } + for (i = 0; i < NBC; i++) { + int l; + l = XUtf8Tolower(i); + if (l != i) table[l] = (unsigned short) i; + } + + } + if (ucs >= NBC || ucs < 0) return ucs; + return table[ucs]; +} + +/** + return the byte length of the UTF-8 sequence with first byte \p c, + or -1 if \p c is not valid. + */ +int fl_utf8len(char c) +{ + if (!(c & 0x80)) return 1; + if (c & 0x40) { + if (c & 0x20) { + if (c & 0x10) { + if (c & 0x08) { + if (c & 0x04) { + return 6; + } + return 5; + } + return 4; + } + return 3; + } + return 2; + } + return -1; +} // fl_utf8len + + +#if 0 +int fl_utflen( + const unsigned char *buf, + int len) +{ + unsigned int ucs; + return fl_utf2ucs(buf, len, &ucs); +} +#endif + +/** + returns the number of Unicode chars in the UTF-8 string + */ +int +fl_utf_nb_char( + const unsigned char *buf, + int len) +{ + int i = 0; + int nbc = 0; + while (i < len) { + int cl = fl_utf8len((buf+i)[0]);//fl_utflen(buf + i, len - i); + if (cl < 1) cl = 1; + nbc++; + i += cl; + } + return nbc; +} + +/* + * compare only the first n bytes + * return 0 if the strings are equal; + * return 1 if s1 is greater than s2 + * return -1 if s1 is less than s2 + */ +/** + UTF-8 aware strncasecmp - converts to lower case Unicode and tests. + + \todo Correct the incorrect logic where length of strings tested + \todo Clarify whether n means number of bytes, or characters. + */ +int fl_utf_strncasecmp(const char *s1, const char *s2, int n) +{ + int i; + int s1_l; + int s2_l; + char *e1, *e2; // string end pointers + + s1_l = 0; + while (s1_l < n && s1[s1_l]) s1_l++; + s2_l = 0; + while (s2_l < n && s2[s2_l]) s2_l++; + + if (s1_l < s2_l) { + return -1; + } else if (s1_l > s2_l) { + return 1; + } + e1 = (char *)&s1[s1_l]; // last char to test + e2 = (char *)&s2[s2_l]; + for (i = 0; i < n;) { + int l1, l2; + unsigned int u1, u2; + int res; + +// l1 = fl_utf2ucs((unsigned char*)s1 + i, n - i, &u1); + u1 = fl_utf8decode(s1 + i, e1, &l1); +// l2 = fl_utf2ucs((unsigned char*)s2 + i, n - i, &u2); + u2 = fl_utf8decode(s2 + i, e2, &l2); + if (l1 - l2 != 0) return l1 - l2; + res = XUtf8Tolower(u1) - XUtf8Tolower(u2); + if (res != 0) return res; + if (l1 < 1) { + i += 1; + } else { + i += l1; + } + } + return 0; +} + +/* + * return 0 if the strings are equal; + * return 1 if s1 is greater than s2 + * return -1 if s1 is less than s2 + */ +/** + UTF-8 aware strcasecmp - converts to Unicode and tests. + + \todo Correct the incorrect logic where length of strings tested + */ +int fl_utf_strcasecmp(const char *s1, const char *s2) +{ + int s1_l = strlen(s1); + int s2_l = strlen(s2); + + if (s1_l < s2_l) { + return -1; + } else if (s1_l > s2_l) { + return 1; + } + return fl_utf_strncasecmp(s1, s2, s1_l); +} + +/** + return the Unicode lower case value of \p ucs + */ +int fl_tolower(unsigned int ucs) +{ + return XUtf8Tolower(ucs); +} + +/** + return the Unicode upper case value of \p ucs + */ +int fl_toupper(unsigned int ucs) +{ + return Toupper(ucs); +} + +/** + converts the str string to the lower case equivalent into buf. + Warning: to be safe buf length must be at least 3 * len [for 16-bit Unicode] + */ +int fl_utf_tolower(const unsigned char *str, int len, char *buf) +{ + int i; + int l = 0; + char *end = (char *)&str[len]; + for (i = 0; i < len;) { + int l1, l2; + unsigned int u1; + +// l1 = fl_utf2ucs((unsigned char*)str + i, len - i, &u1); + u1 = fl_utf8decode((const char*)(str + i), end, &l1); + l2 = fl_utf8encode((unsigned int) XUtf8Tolower(u1), buf + l); + if (l1 < 1) { + i += 1; + } else { + i += l1; + } + if (l2 < 1) { + l += 1; + } else { + l += l2; + } + + } + return l; +} + +/** + converts the str string to the upper case equivalent into buf. + Warning: to be safe buf length must be at least 3 * len [for 16-bit Unicode] + */ +int fl_utf_toupper(const unsigned char *str, int len, char *buf) +{ + int i; + int l = 0; + char *end = (char *)&str[len]; + for (i = 0; i < len;) { + int l1, l2; + unsigned int u1; + +// l1 = fl_utf2ucs((unsigned char*)str + i, len - i, &u1); + u1 = fl_utf8decode((const char*)(str + i), end, &l1); + l2 = fl_utf8encode((unsigned int) Toupper(u1), buf + l); + if (l1 < 1) { + i += 1; + } else { + i += l1; + } + if (l2 < 1) { + l += 1; + } else { + l += l2; + } + } + return l; +} + +#if 0 // deprecated in favour of FLTK2's fl_utf8toa +/* + * convert UTF-8 str to latin1 + * Warning: buf must be at least len long + */ +int fl_utf2latin1(const unsigned char *str, int len, char *buf) +{ + int i; + int l = 0; + char *end = (char *)&str[len]; + for (i = 0; i < len;) { + unsigned int u1; + int l1; + +// l1 = fl_utf2ucs((unsigned char*)str + i, len - i, &u1); + u1 = fl_utf8decode((const char*)(str + i), end, &l1); + if (u1 > 0xFF) u1 = '?'; + buf[l] = (char) u1; + if (l1 < 1) { + i += 1; + } else { + i += l1; + } + l++; + + } + return l; +} +#endif + +#if 0 // deprecated in favour of FLTK2's fl_utf8froma +/* + * convert latin1 str to UTF-8 + * Warning: buf must be at least 2 * len long + */ +int fl_latin12utf(const unsigned char *str, int len, char *buf) +{ + int i; + int l = 0; + int l1 = 0; + for (i = 0; i < len; i++) { + unsigned int n = (unsigned int) str[i]; + l1 = fl_utf8encode(n, buf + l); + if (l1 < 1) { + l = l + 1; + } else { + l = l + l1; + } + + } + return l; +} +#endif + +/** + returns true if the character is non-spacing. + \todo explain what non-spacing means. + */ +unsigned int fl_nonspacing(unsigned int ucs) +{ +#ifdef __APPLE__ + return (ucs==0x20); // FIXME: what does this really do? +#else + return (unsigned int) XUtf8IsNonSpacing(ucs); +#endif +} + +#if defined(WIN32) && !defined(__CYGWIN__) +static xchar *mbwbuf = NULL; +#endif + +#ifdef WIN32 +unsigned int fl_codepage = 0; +#endif + +#if defined (WIN32) && !defined(__CYGWIN__) + +static char *buf = NULL; +static int buf_len = 0; +static unsigned short *wbufa = NULL; + +char *fl_utf8_to_locale(const char *s, int len, UINT codepage) +{ + if (!s) return ""; + int l = 0; +// if (buf_len < len * 2 + 1) { +// buf_len = len * 2 + 1; +// buf = (char*) realloc(buf, buf_len); +// wbufa = (unsigned short*) realloc(wbufa, buf_len * sizeof(short)); +// } + unsigned wn = fl_utf8toUtf16(s, len, NULL, 0); // Query length + wn = wn * 2 + 1; + if (wn >= (unsigned)buf_len) { + buf_len = wn; + buf = (char*) realloc(buf, buf_len); + wbufa = (unsigned short*) realloc(wbufa, buf_len * sizeof(short)); + } + if (codepage < 1) codepage = fl_codepage; +// l = fl_utf2unicode((const unsigned char *)s, len, (xchar*) wbufa); + l = fl_utf8toUtf16(s, len, wbufa, wn); // Convert string + wbufa[l] = 0; + buf[l] = 0; + l = WideCharToMultiByte(codepage, 0, (WCHAR*)wbufa, l, buf, buf_len, NULL, NULL); + if (l < 0) l = 0; + buf[l] = 0; + return buf; +} + +char *fl_locale_to_utf8(const char *s, int len, UINT codepage) +{ + if (!s) return ""; + int l = 0; + if (buf_len < len * 5 + 1) { + buf_len = len * 5 + 1; + buf = (char*) realloc(buf, buf_len); + wbufa = (unsigned short*) realloc(wbufa, buf_len * sizeof(short)); + } + if (codepage < 1) codepage = fl_codepage; + buf[l] = 0; + + l = MultiByteToWideChar(codepage, 0, s, len, (WCHAR*)wbufa, buf_len); + if (l < 0) l = 0; + wbufa[l] = 0; +// l = fl_unicode2utf((xchar*)wbufa, l, buf); + l = fl_utf8fromwc(buf, buf_len, (xchar*)wbufa, l); + buf[l] = 0; + return buf; +} +#endif + +/** + converts UTF8 to a local multi-byte character string. + */ +char * fl_utf2mbcs(const char *s) +{ + if (!s) return NULL; +#if defined(WIN32) && !defined(__CYGWIN__) + int l = strlen(s); + static char *buf = NULL; + +// mbwbuf = (xchar*)realloc(mbwbuf, (l+6) * sizeof(xchar)); +// l = fl_utf2unicode((unsigned char*)s, l, mbwbuf); +// mbwbuf[l] = 0; + unsigned wn = fl_utf8toUtf16(s, l, NULL, 0) + 7; // Query length + mbwbuf = (xchar*)realloc(mbwbuf, sizeof(xchar)*wn); + l = fl_utf8toUtf16(s, l, (unsigned short *)mbwbuf, wn); // Convert string + mbwbuf[l] = 0; + + buf = (char*)realloc(buf, l * 6 + 1); + l = wcstombs(buf, mbwbuf, l * 6); + buf[l] = 0; + return buf; +#else + return (char*) s; +#endif +} + + +#if 0 // deprecated in favour of FLTK2's fl_utf8from_mb +char * fl_mbcs2utf(const char *s) +{ + if (!s) return NULL; +#if defined(WIN32) + int l = strlen(s); + unsigned dstlen; + static char *buf = NULL; + + mbwbuf = (xchar*)realloc(mbwbuf,(l * 6 + 6) * sizeof(xchar)); + l = mbstowcs(mbwbuf, s, l); + dstlen = l * 6 + 1; + buf = (char*)realloc(buf, dstlen); +// l = fl_unicode2utf(mbwbuf, l, buf); + l = fl_utf8fromwc(buf, dstlen, mbwbuf, l); + buf[l] = 0; + return buf; +#else + return (char*) s; +#endif +} // fl_mbcs2utf +#endif + +#if defined(WIN32) && !defined(__CYGWIN__) +static xchar *wbuf = NULL; +static xchar *wbuf1 = NULL; +#endif + + +char *fl_getenv(const char* v) +{ +#if defined (WIN32) && !defined(__CYGWIN__) + int l = strlen(v); +// static xchar* wbuf = NULL; +// wbuf = (xchar*)realloc(wbuf, sizeof(xchar) * (l+1)); +// wbuf[fl_utf2unicode((const unsigned char*)v, l, wbuf)] = 0; + unsigned wn = fl_utf8toUtf16(v, l, NULL, 0) + 1; // Query length + wbuf = (xchar*)realloc(wbuf, sizeof(xchar)*wn); + wn = fl_utf8toUtf16(v, l, (unsigned short *)wbuf, wn); // Convert string + wbuf[wn] = 0; + xchar *ret = _wgetenv(wbuf); + static char *buf = NULL; + if (ret) { + l = wcslen(ret); + wn = fl_utf8fromwc(NULL, 0, ret, l) + 1; // query length + buf = (char*) realloc(buf, wn); +// buf[fl_unicode2utf(ret, l, buf)] = 0; + wn = fl_utf8fromwc(buf, wn, ret, l); // convert string + buf[wn] = 0; + return buf; + } else { + return NULL; + } +#else + return getenv(v); +#endif +} + +int fl_open(const char* f, int oflags, ...) +{ + int pmode; + va_list ap; + va_start(ap, oflags); + pmode = va_arg (ap, int); + va_end(ap); +#if defined (WIN32) && !defined(__CYGWIN__) + int l = strlen(f); +// wbuf = (xchar*)realloc(wbuf, sizeof(xchar) * (l+1)); +// wbuf[fl_utf2unicode((const unsigned char*)f, l, wbuf)] = 0; + unsigned wn = fl_utf8toUtf16(f, l, NULL, 0) + 1; // Query length + wbuf = (xchar*)realloc(wbuf, sizeof(xchar)*wn); + wn = fl_utf8toUtf16(f, l, (unsigned short *)wbuf, wn); // Convert string + wbuf[wn] = 0; + if (pmode == -1) return _wopen(wbuf, oflags); + else return _wopen(wbuf, oflags, pmode); +#else + if (pmode == -1) return open(f, oflags); + else return open(f, oflags, pmode); +#endif +} + +FILE *fl_fopen(const char* f, const char *mode) +{ +#if defined (WIN32) && !defined(__CYGWIN__) + int l = strlen(f); +// wbuf = (xchar*)realloc(wbuf, sizeof(xchar) * (l+1)); +// wbuf[fl_utf2unicode((const unsigned char*)f, l, wbuf)] = 0; + unsigned wn = fl_utf8toUtf16(f, l, NULL, 0) + 1; // Query length + wbuf = (xchar*)realloc(wbuf, sizeof(xchar)*wn); + wn = fl_utf8toUtf16(f, l, (unsigned short *)wbuf, wn); // Convert string + wbuf[wn] = 0; + l = strlen(mode); +// wbuf1 = (xchar*)realloc(wbuf1, sizeof(xchar) * (l+1)); +// wbuf1[fl_utf2unicode((const unsigned char*)mode, l, wbuf1)] = 0; + wn = fl_utf8toUtf16(mode, l, NULL, 0) + 1; // Query length + wbuf1 = (xchar*)realloc(wbuf1, sizeof(xchar)*wn); + wn = fl_utf8toUtf16(mode, l, (unsigned short *)wbuf1, wn); // Convert string + wbuf1[wn] = 0; + return _wfopen(wbuf, wbuf1); +#else + return fopen(f, mode); +#endif +} + +int fl_system(const char* f) +{ +#if defined (WIN32) && !defined(__CYGWIN__) +# ifdef __MINGW32__ + return system(fl_utf2mbcs(f)); +# else + int l = strlen(f); +// wbuf = (xchar*)realloc(wbuf, sizeof(xchar) * (l+1)); +// wbuf[fl_utf2unicode((const unsigned char*)f, l, wbuf)] = 0; + unsigned wn = fl_utf8toUtf16(f, l, NULL, 0) + 1; // Query length + wbuf = (xchar*)realloc(wbuf, sizeof(xchar)*wn); + wn = fl_utf8toUtf16(f, l, (unsigned short *)wbuf, wn); // Convert string + wbuf[wn] = 0; + return _wsystem(wbuf); +# endif +#else + return system(f); +#endif +} + +int fl_execvp(const char *file, char *const *argv) +{ +#if defined (WIN32) && !defined(__CYGWIN__) +#ifdef __MINGW32__ + return _execvp(fl_utf2mbcs(file), argv); +#else + int l = strlen(file); + int i, n, ret; + xchar **ar; +// wbuf = (xchar*)realloc(wbuf, sizeof(xchar) * (l+1)); +// wbuf[fl_utf2unicode((const unsigned char*)file, l, wbuf)] = 0; + unsigned wn = fl_utf8toUtf16(file, l, NULL, 0) + 1; // Query length + wbuf = (xchar*)realloc(wbuf, sizeof(xchar)*wn); + wn = fl_utf8toUtf16(file, l, (unsigned short *)wbuf, wn); // Convert string + wbuf[wn] = 0; + + i = 0; n = 0; + while (argv[i]) {i++; n++;} + ar = (xchar**) malloc(sizeof(xchar*) * (n + 1)); + i = 0; + while (i <= n) { + unsigned wn; + l = strlen(argv[i]); +// ar[i] = (xchar *)malloc(sizeof(xchar) * (l+1)); +// ar[i][fl_utf2unicode((const unsigned char*)argv[i], l, ar[i])] = 0; + wn = fl_utf8toUtf16(argv[i], l, NULL, 0) + 1; // Query length + ar[i] = (xchar *)malloc(sizeof(xchar)*wn); + wn = fl_utf8toUtf16(argv[i], l, (unsigned short *)ar[i], wn); // Convert string + ar[i][wn] = 0; + i++; + } + ar[n] = NULL; + ret = _wexecvp(wbuf, ar); + i = 0; + while (i <= n) { + free(ar[i]); + i++; + } + free(ar); + return ret; +#endif +#else + return execvp(file, argv); +#endif +} + + + +int fl_chmod(const char* f, int mode) +{ +#if defined (WIN32) && !defined(__CYGWIN__) + int l = strlen(f); +// wbuf = (xchar*)realloc(wbuf, sizeof(xchar) * (l+1)); +// wbuf[fl_utf2unicode((const unsigned char*)f, l, wbuf)] = 0; + unsigned wn = fl_utf8toUtf16(f, l, NULL, 0) + 1; // Query length + wbuf = (xchar*)realloc(wbuf, sizeof(xchar)*wn); + wn = fl_utf8toUtf16(f, l, (unsigned short *)wbuf, wn); // Convert string + wbuf[wn] = 0; + return _wchmod(wbuf, mode); +#else + return chmod(f, mode); +#endif +} + +int fl_access(const char* f, int mode) +{ +#if defined (WIN32) && !defined(__CYGWIN__) + int l = strlen(f); +// wbuf = (xchar*)realloc(wbuf, sizeof(xchar) * (l+1)); +// wbuf[fl_utf2unicode((const unsigned char*)f, l, wbuf)] = 0; + unsigned wn = fl_utf8toUtf16(f, l, NULL, 0) + 1; // Query length + wbuf = (xchar*)realloc(wbuf, sizeof(xchar)*wn); + wn = fl_utf8toUtf16(f, l, (unsigned short *)wbuf, wn); // Convert string + wbuf[wn] = 0; + return _waccess(wbuf, mode); +#else + return access(f, mode); +#endif +} + + +int fl_stat(const char* f, struct stat *b) +{ +#if defined(WIN32) && !defined(__CYGWIN__) + int l = strlen(f); +// wbuf = (xchar*)realloc(wbuf, sizeof(xchar) * (l+1)); +// wbuf[fl_utf2unicode((const unsigned char*)f, l, wbuf)] = 0; + unsigned wn = fl_utf8toUtf16(f, l, NULL, 0) + 1; // Query length + wbuf = (xchar*)realloc(wbuf, sizeof(xchar)*wn); + wn = fl_utf8toUtf16(f, l, (unsigned short *)wbuf, wn); // Convert string + wbuf[wn] = 0; + return _wstat(wbuf, (struct _stat*)b); +#else + return stat(f, b); +#endif +} + +char *fl_getcwd(char* b, int l) +{ + if (b == NULL) { + b = (char*) malloc(l+1); + } +#if defined(WIN32) && !defined(__CYGWIN__) + static xchar *wbuf = NULL; + wbuf = (xchar*)realloc(wbuf, sizeof(xchar) * (l+1)); +// xchar *ret = _wgetcwd(wbuf, l / 5); + xchar *ret = _wgetcwd(wbuf, l); + if (ret) { + unsigned dstlen = l; + l = wcslen(wbuf); +// b[fl_unicode2utf(wbuf, l, b)] = 0; + dstlen = fl_utf8fromwc(b, dstlen, wbuf, l); + b[dstlen] = 0; + return b; + } else { + return NULL; + } +#else + return getcwd(b, l); +#endif +} + + +int fl_unlink(const char* f) +{ +#if defined(WIN32) && !defined(__CYGWIN__) + int l = strlen(f); +// wbuf = (xchar*)realloc(wbuf, sizeof(xchar) * (l+1)); +// wbuf[fl_utf2unicode((const unsigned char*)f, l, wbuf)] = 0; + unsigned wn = fl_utf8toUtf16(f, l, NULL, 0) + 1; // Query length + wbuf = (xchar*)realloc(wbuf, sizeof(xchar)*wn); + wn = fl_utf8toUtf16(f, l, (unsigned short *)wbuf, wn); // Convert string + wbuf[wn] = 0; + return _wunlink(wbuf); +#else + return unlink(f); +#endif +} + +int fl_mkdir(const char* f, int mode) +{ +#if defined(WIN32) && !defined(__CYGWIN__) + int l = strlen(f); +// wbuf = (xchar*)realloc(wbuf, sizeof(short) * (l+1)); +// wbuf[fl_utf2unicode((const unsigned char*)f, l, wbuf)] = 0; + unsigned wn = fl_utf8toUtf16(f, l, NULL, 0) + 1; // Query length + wbuf = (xchar*)realloc(wbuf, sizeof(xchar)*wn); + wn = fl_utf8toUtf16(f, l, (unsigned short *)wbuf, wn); // Convert string + wbuf[wn] = 0; + return _wmkdir(wbuf); +#else + return mkdir(f, mode); +#endif +} + + +int fl_rmdir(const char* f) +{ +#if defined (WIN32) && !defined(__CYGWIN__) + int l = strlen(f); +// wbuf = (xchar*)realloc(wbuf, sizeof(xchar) * (l+1)); +// wbuf[fl_utf2unicode((const unsigned char*)f, l, wbuf)] = 0; + unsigned wn = fl_utf8toUtf16(f, l, NULL, 0) + 1; // Query length + wbuf = (xchar*)realloc(wbuf, sizeof(xchar)*wn); + wn = fl_utf8toUtf16(f, l, (unsigned short *)wbuf, wn); // Convert string + wbuf[wn] = 0; + return _wrmdir(wbuf); +#else + return rmdir(f); +#endif +} + +int fl_rename(const char* f, const char *n) +{ +#if defined (WIN32) && !defined(__CYGWIN__) + int l = strlen(f); + unsigned wn = fl_utf8toUtf16(f, l, NULL, 0) + 1; // Query length + wbuf = (xchar*)realloc(wbuf, sizeof(xchar)*wn); + wn = fl_utf8toUtf16(f, l, (unsigned short *)wbuf, wn); // Convert string + wbuf[wn] = 0; + l = strlen(n); + wn = fl_utf8toUtf16(n, l, NULL, 0) + 1; // Query length + wbuf1 = (xchar*)realloc(wbuf1, sizeof(xchar)*wn); + wn = fl_utf8toUtf16(n, l, (unsigned short *)wbuf1, wn); // Convert string + wbuf1[wn] = 0; + return _wrename(wbuf, wbuf1); +#else + return rename(f, n); +#endif +} + +// recursively create a path in the file system +char fl_make_path( const char *path ) { + if (fl_access(path, 0)) { + const char *s = strrchr( path, '/' ); + if ( !s ) return 0; + int len = s-path; + char *p = (char*)malloc( len+1 ); + memcpy( p, path, len ); + p[len] = 0; + fl_make_path( p ); + free( p ); + fl_mkdir(path, 0700); + } + return 1; +} + +// strip the filename and create a path +void fl_make_path_for_file( const char *path ) +{ + const char *s = strrchr( path, '/' ); + if ( !s ) return; + int len = s-path; + char *p = (char*)malloc( len+1 ); + memcpy( p, path, len ); + p[len] = 0; + fl_make_path( p ); + free( p ); +} + +/** @} */ + +// +// End of "$Id: fl_utf8.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/fl_vertex.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_vertex.cxx new file mode 100644 index 0000000..14f4132 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/fl_vertex.cxx @@ -0,0 +1,372 @@ +// +// "$Id: fl_vertex.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Portable drawing routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/** + \file fl_vertex.cxx + \brief Portable drawing code for drawing arbitrary shapes with + simple 2D transformations. +*/ + +// Portable drawing code for drawing arbitrary shapes with +// simple 2D transformations. See also fl_arc.cxx + +// matt: the Quartz implementation purposely doesn't use the Quartz matrix +// operations for reasons of compatibility and maintainability + +#include +#include +#include +#include +#include +#include + +struct matrix {double a, b, c, d, x, y;}; + +static matrix m = {1, 0, 0, 1, 0, 0}; + +static matrix stack[32]; +matrix * fl_matrix = &m; +static int sptr = 0; + +/** + Saves the current transformation matrix on the stack. + The maximum depth of the stack is 4. +*/ +void fl_push_matrix() { + if (sptr==32) + Fl::error("fl_push_matrix(): matrix stack overflow."); + else + stack[sptr++] = m; +} + +/** + Restores the current transformation matrix from the stack. +*/ +void fl_pop_matrix() { + if (sptr==0) + Fl::error("fl_pop_matrix(): matrix stack underflow."); + else + m = stack[--sptr]; +} + +/** + Concatenates another transformation onto the current one. + + \param[in] a,b,c,d,x,y transformation matrix elements such that + X' = aX + cY + x and Y' = bX +dY + y +*/ +void fl_mult_matrix(double a, double b, double c, double d, double x, double y) { + matrix o; + o.a = a*m.a + b*m.c; + o.b = a*m.b + b*m.d; + o.c = c*m.a + d*m.c; + o.d = c*m.b + d*m.d; + o.x = x*m.a + y*m.c + m.x; + o.y = x*m.b + y*m.d + m.y; + m = o; +} + +/** + Concatenates scaling transformation onto the current one. + \param[in] x,y scale factors in x-direction and y-direction +*/ +void fl_scale(double x,double y) {fl_mult_matrix(x,0,0,y,0,0);} + +/** + Concatenates scaling transformation onto the current one. + \param[in] x scale factor in both x-direction and y-direction +*/ +void fl_scale(double x) {fl_mult_matrix(x,0,0,x,0,0);} + +/** + Concatenates translation transformation onto the current one. + \param[in] x,y translation factor in x-direction and y-direction +*/ +void fl_translate(double x,double y) {fl_mult_matrix(1,0,0,1,x,y);} + +/** + Concatenates rotation transformation onto the current one. + \param[in] d - rotation angle, counter-clockwise in degrees (not radians) +*/ +void fl_rotate(double d) { + if (d) { + double s, c; + if (d == 0) {s = 0; c = 1;} + else if (d == 90) {s = 1; c = 0;} + else if (d == 180) {s = 0; c = -1;} + else if (d == 270 || d == -90) {s = -1; c = 0;} + else {s = sin(d*M_PI/180); c = cos(d*M_PI/180);} + fl_mult_matrix(c,-s,s,c,0,0); + } +} + +// typedef what the x,y fields in a point are: +#ifdef WIN32 +typedef int COORD_T; +# define XPOINT XPoint +#elif defined(__APPLE_QUARTZ__) +typedef float COORD_T; +typedef struct { float x; float y; } QPoint; +# define XPOINT QPoint +extern float fl_quartz_line_width_; +#else +typedef short COORD_T; +# define XPOINT XPoint +#endif + +static XPOINT *p = (XPOINT *)0; + +static int p_size; +static int n; +static int what; +enum {LINE, LOOP, POLYGON, POINT_}; + +void Fl_Graphics_Driver::begin_points() {n = 0; what = POINT_;} + +void Fl_Graphics_Driver::begin_line() {n = 0; what = LINE;} + +void Fl_Graphics_Driver::begin_loop() {n = 0; what = LOOP;} + +void Fl_Graphics_Driver::begin_polygon() {n = 0; what = POLYGON;} + +/** + Transforms coordinate using the current transformation matrix. + \param[in] x,y coordinate +*/ +double fl_transform_x(double x, double y) {return x*m.a + y*m.c + m.x;} + +/** + Transform coordinate using the current transformation matrix. + \param[in] x,y coordinate +*/ +double fl_transform_y(double x, double y) {return x*m.b + y*m.d + m.y;} + +/** + Transforms distance using current transformation matrix. + \param[in] x,y coordinate +*/ +double fl_transform_dx(double x, double y) {return x*m.a + y*m.c;} + +/** + Transforms distance using current transformation matrix. + \param[in] x,y coordinate +*/ +double fl_transform_dy(double x, double y) {return x*m.b + y*m.d;} + +static void fl_transformed_vertex(COORD_T x, COORD_T y) { + if (!n || x != p[n-1].x || y != p[n-1].y) { + if (n >= p_size) { + p_size = p ? 2*p_size : 16; + p = (XPOINT*)realloc((void*)p, p_size*sizeof(*p)); + } + p[n].x = x; + p[n].y = y; + n++; + } +} + +void Fl_Graphics_Driver::transformed_vertex(double xf, double yf) { +#ifdef __APPLE_QUARTZ__ + fl_transformed_vertex(COORD_T(xf), COORD_T(yf)); +#else + fl_transformed_vertex(COORD_T(rint(xf)), COORD_T(rint(yf))); +#endif +} + +void Fl_Graphics_Driver::vertex(double x,double y) { + fl_transformed_vertex(x*m.a + y*m.c + m.x, x*m.b + y*m.d + m.y); +} + +void Fl_Graphics_Driver::end_points() { +#if defined(USE_X11) + if (n>1) XDrawPoints(fl_display, fl_window, fl_gc, p, n, 0); +#elif defined(WIN32) + for (int i=0; i 1.5f) CGContextSetShouldAntialias(fl_gc, true); + for (int i=0; i 1.5f) CGContextSetShouldAntialias(fl_gc, false); +#else +# error unsupported platform +#endif +} + +void Fl_Graphics_Driver::end_line() { + if (n < 2) { + fl_end_points(); + return; + } +#if defined(USE_X11) + if (n>1) XDrawLines(fl_display, fl_window, fl_gc, p, n, 0); +#elif defined(WIN32) + if (n>1) Polyline(fl_gc, p, n); +#elif defined(__APPLE_QUARTZ__) + if (n<=1) return; + CGContextSetShouldAntialias(fl_gc, true); + CGContextMoveToPoint(fl_gc, p[0].x, p[0].y); + for (int i=1; i2 && p[n-1].x == p[0].x && p[n-1].y == p[0].y) n--; +} + +void Fl_Graphics_Driver::end_loop() { + fixloop(); + if (n>2) fl_transformed_vertex((COORD_T)p[0].x, (COORD_T)p[0].y); + fl_end_line(); +} + +void Fl_Graphics_Driver::end_polygon() { + fixloop(); + if (n < 3) { + fl_end_line(); + return; + } +#if defined(USE_X11) + if (n>2) XFillPolygon(fl_display, fl_window, fl_gc, p, n, Convex, 0); +#elif defined(WIN32) + if (n>2) { + SelectObject(fl_gc, fl_brush()); + Polygon(fl_gc, p, n); + } +#elif defined(__APPLE_QUARTZ__) + if (n<=1) return; + CGContextSetShouldAntialias(fl_gc, true); + CGContextMoveToPoint(fl_gc, p[0].x, p[0].y); + for (int i=1; igap_+2 && p[n-1].x == p[gap_].x && p[n-1].y == p[gap_].y) n--; + if (n > gap_+2) { + fl_transformed_vertex((COORD_T)p[gap_].x, (COORD_T)p[gap_].y); +#if defined(WIN32) + counts[numcount++] = n-gap_; +#endif + gap_ = n; + } else { + n = gap_; + } +} + +void Fl_Graphics_Driver::end_complex_polygon() { + fl_gap(); + if (n < 3) { + fl_end_line(); + return; + } +#if defined(USE_X11) + if (n>2) XFillPolygon(fl_display, fl_window, fl_gc, p, n, 0, 0); +#elif defined(WIN32) + if (n>2) { + SelectObject(fl_gc, fl_brush()); + PolyPolygon(fl_gc, p, counts, numcount); + } +#elif defined(__APPLE_QUARTZ__) + if (n<=1) return; + CGContextSetShouldAntialias(fl_gc, true); + CGContextMoveToPoint(fl_gc, p[0].x, p[0].y); + for (int i=1; i size) srclen = size; + + memcpy(dst + dstlen, src, srclen); + dst[dstlen + srclen] = '\0'; + + return (dstlen + srclen); +} + + +/* + * 'fl_strlcpy()' - Safely copy two strings. + */ + +size_t /* O - Length of string */ +fl_strlcpy(char *dst, /* O - Destination string */ + const char *src, /* I - Source string */ + size_t size) { /* I - Size of destination string buffer */ + size_t srclen; /* Length of source string */ + + + /* + * Figure out how much room is needed... + */ + + size --; + + srclen = strlen(src); + + /* + * Copy the appropriate amount... + */ + + if (srclen > size) srclen = size; + + memcpy(dst, src, srclen); + dst[srclen] = '\0'; + + return (srclen); +} + + +/* + * End of "$Id: flstring.c 7903 2010-11-28 21:06:39Z matt $". + */ diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/flstring.h b/mod/maxgui.mod/fltkmaxgui.mod/src/flstring.h new file mode 100644 index 0000000..1ab39d1 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/flstring.h @@ -0,0 +1,104 @@ +/* + * "$Id: flstring.h 7352 2010-03-29 10:47:11Z matt $" + * + * Common string header file for the Fast Light Tool Kit (FLTK). + * + * Copyright 1998-2009 by Bill Spitzak and others. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems on the following page: + * + * http://www.fltk.org/str.php + */ + +#ifndef flstring_h +# define flstring_h + +# include +# include +# include +# include +# include +# ifdef HAVE_STRINGS_H +# include +# endif /* HAVE_STRINGS_H */ +# include + +/* + * Apparently Unixware defines "index" to strchr (!) rather than + * providing a proper entry point or not providing the (obsolete) + * BSD function. Make sure index is not defined... + */ + +# ifdef index +# undef index +# endif /* index */ + +# if defined(WIN32) && !defined(__CYGWIN__) +# define strcasecmp(s,t) _stricmp((s), (t)) +# define strncasecmp(s,t,n) _strnicmp((s), (t), (n)) +/* Visual C++ 2005 incorrectly displays a warning about the use of POSIX APIs + * on Windows, which is supposed to be POSIX compliant... Some of these + * functions are also defined in ISO C99... + */ +# ifndef __WATCOMC__ +# define strdup _strdup +# define unlink _unlink +# endif /* !__WATCOMC__ */ +# elif defined(__EMX__) +# define strcasecmp(s,t) stricmp((s), (t)) +# define strncasecmp(s,t,n) strnicmp((s), (t), (n)) +# endif /* WIN32 */ + +# ifdef __cplusplus +extern "C" { +# endif /* __cplusplus */ + +FL_EXPORT extern int fl_snprintf(char *, size_t, const char *, ...); +# if !HAVE_SNPRINTF +# define snprintf fl_snprintf +# endif /* !HAVE_SNPRINTF */ + +FL_EXPORT extern int fl_vsnprintf(char *, size_t, const char *, va_list ap); +# if !HAVE_VSNPRINTF +# define vsnprintf fl_vsnprintf +# endif /* !HAVE_VSNPRINTF */ + +/* + * strlcpy() and strlcat() are some really useful BSD string functions + * that work the way strncpy() and strncat() *should* have worked. + */ + +FL_EXPORT extern size_t fl_strlcat(char *, const char *, size_t); +# if !HAVE_STRLCAT +# define strlcat fl_strlcat +# endif /* !HAVE_STRLCAT */ + +FL_EXPORT extern size_t fl_strlcpy(char *, const char *, size_t); +# if !HAVE_STRLCPY +# define strlcpy fl_strlcpy +# endif /* !HAVE_STRLCPY */ + +# ifdef __cplusplus +} +# endif /* __cplusplus */ +#endif /* !flstring_h */ + + +/* + * End of "$Id: flstring.h 7352 2010-03-29 10:47:11Z matt $". + */ diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/forms_bitmap.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/forms_bitmap.cxx new file mode 100644 index 0000000..1f81b0c --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/forms_bitmap.cxx @@ -0,0 +1,53 @@ +// +// "$Id: forms_bitmap.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Forms compatible bitmap function for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +/** Creates a bitmap widget from a box type, position, size and optional label specification */ +Fl_FormsBitmap::Fl_FormsBitmap( + Fl_Boxtype t, int X, int Y, int W, int H, const char* l) +: Fl_Widget(X, Y, W, H, l) { + box(t); + b = 0; + color(FL_BLACK); + align(FL_ALIGN_BOTTOM); +} +/** Sets a new bitmap bits with size W,H. Deletes the previous one.*/ +void Fl_FormsBitmap::set(int W, int H, const uchar *bits) { + delete b; + bitmap(new Fl_Bitmap(bits, W, H)); +} + +/** Draws the bitmap and its associated box. */ +void Fl_FormsBitmap::draw() { + draw_box(box(), selection_color()); + if (b) {fl_color(color()); b->draw(x(), y(), w(), h());} + draw_label(); +} + +// +// End of "$Id: forms_bitmap.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/forms_compatability.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/forms_compatability.cxx new file mode 100644 index 0000000..813c2c0 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/forms_compatability.cxx @@ -0,0 +1,213 @@ +// +// "$Id: forms_compatability.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Forms compatibility functions for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Forms library compatibility functions. +// Many more functions are defined as inlines in forms.h! + +#include +#include + +char fl_flip = 2; +void fl_end_form() { + while (Fl_Group::current()) Fl_Group::current()->forms_end(); +} +void Fl_Group::forms_end() { + // set the dimensions of a group to surround contents + if (children() && !w()) { + Fl_Widget*const* a = array(); + Fl_Widget* o = *a++; + int rx = o->x(); + int ry = o->y(); + int rw = rx+o->w(); + int rh = ry+o->h(); + for (int i=children_-1; i--;) { + o = *a++; + if (o->x() < rx) rx = o->x(); + if (o->y() < ry) ry = o->y(); + if (o->x()+o->w() > rw) rw = o->x()+o->w(); + if (o->y()+o->h() > rh) rh = o->y()+o->h(); + } + x(rx); + y(ry); + w(rw-rx); + h(rh-ry); + } + // flip all the children's coordinate systems: + if (fl_flip) { + Fl_Widget* o = (type()>=FL_WINDOW) ? this : window(); + int Y = o->h(); + Fl_Widget*const* a = array(); + for (int i=children(); i--;) { + Fl_Widget* ow = *a++; + int newy = Y-ow->y()-ow->h(); + ow->y(newy); + } + } + end(); +} + +static int initargc; +static char **initargv; + +void fl_initialize(int *argc, char **argv, const char *, FL_CMD_OPT *, int) { + initargc = *argc; + initargv = new char*[*argc+1]; + int i,j; + for (i=0; i<=*argc; i++) initargv[i] = argv[i]; + for (i=j=1; i<*argc; ) { + if (Fl::arg(*argc,argv,i)); + else argv[j++] = argv[i++]; + } + argv[j] = 0; + *argc = j; + if (fl_flip==2) fl_flip = 0; +} + +char fl_modal_next; // set by fl_freeze_forms() + +void fl_show_form(Fl_Window *f,int place,int b,const char *n) { + + f->label(n); + if (!b) f->clear_border(); + if (fl_modal_next || b==FL_TRANSIENT) {f->set_modal(); fl_modal_next = 0;} + + if (place & FL_PLACE_MOUSE) f->hotspot(f); + + if (place & FL_PLACE_CENTER) { + int scr_x, scr_y, scr_w, scr_h; + Fl::screen_xywh(scr_x, scr_y, scr_w, scr_h); + f->position(scr_x+(scr_w-f->w())/2, scr_y+(scr_h-f->h())/2); + } + + if (place & FL_PLACE_FULLSCREEN) + f->fullscreen(); + + if (place & (FL_PLACE_POSITION | FL_PLACE_GEOMETRY)) + f->position( + (f->x() < 0) ? Fl::w()-f->w()+f->x()-1 : f->x(), + (f->y() < 0) ? Fl::h()-f->h()+f->y()-1 : f->y()); + +// if (place & FL_PLACE_ASPECT) { +// this is not yet implemented +// it can be done by setting size_range(). + + if (place == FL_PLACE_FREE || place == FL_PLACE_SIZE) + f->free_position(); + + if (place == FL_PLACE_FREE || place & FL_FREE_SIZE) + if (!f->resizable()) f->resizable(f); + + if (initargc) {f->show(initargc,initargv); initargc = 0;} + else f->show(); +} + +Fl_Widget *fl_do_forms(void) { + Fl_Widget *obj; + while (!(obj = Fl::readqueue())) if (!Fl::wait()) exit(0); + return obj; +} + +Fl_Widget *fl_check_forms() { + Fl::check(); + return Fl::readqueue(); +} + +void fl_set_graphics_mode(int /*r*/,int /*d*/) {} + +#ifndef FL_DOXYGEN // FIXME: suppress doxygen warning +void Fl_FormsText::draw() { + draw_box(); + align(align()|FL_ALIGN_INSIDE); // questionable method of compatibility + draw_label(); +} +#endif + +// Create a forms button by selecting correct fltk subclass: + +#include +#include + +Fl_Button *fl_add_button(uchar t,int x,int y,int w,int h,const char *l) { + Fl_Button *b; + switch (t) { + case FL_RETURN_BUTTON: + case FL_HIDDEN_RET_BUTTON: + b = new Fl_Return_Button(x,y,w,h,l); + break; + case FL_TOUCH_BUTTON: + b = new Fl_Repeat_Button(x,y,w,h,l); + break; + default: + b = new Fl_Button(x,y,w,h,l); + } + switch (t) { + case FL_TOGGLE_BUTTON: + case FL_RADIO_BUTTON: + b->type(t); + break; + case FL_HIDDEN_BUTTON: + case FL_HIDDEN_RET_BUTTON: + b->type(FL_HIDDEN_BUTTON); + break; + case FL_INOUT_BUTTON: + b->when(FL_WHEN_CHANGED); + break; + } + return b; +} + +void fl_show_message(const char *q1,const char *q2,const char *q3) { + fl_message("%s\n%s\n%s", q1?q1:"", q2?q2:"", q3?q3:""); +} + +void fl_show_alert(const char *q1,const char *q2,const char *q3,int) { + fl_alert("%s\n%s\n%s", q1?q1:"", q2?q2:"", q3?q3:""); +} + +int fl_show_question(const char *q1,const char *q2,const char *q3) { + return fl_choice("%s\n%s\n%s", "No", "Yes", 0L, q1?q1:"", q2?q2:"", q3?q3:""); +} + +int fl_show_choice( + const char *q1, + const char *q2, + const char *q3, + int, // number of buttons, ignored + const char *b0, + const char *b1, + const char *b2) { + return fl_choice("%s\n%s\n%s", q1?q1:"", q2?q2:"", q3?q3:"", b0,b1,b2)+1; +} + +char *fl_show_simple_input(const char *str1, const char *defstr) { + const char *r = fl_input("%s", defstr, str1); + return (char *)(r ? r : defstr); +} + +// +// End of "$Id: forms_compatability.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/forms_free.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/forms_free.cxx new file mode 100644 index 0000000..26c651f --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/forms_free.cxx @@ -0,0 +1,114 @@ +// +// "$Id: forms_free.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Forms free widget routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Emulation of the Forms "free" widget. +// This emulation allows the free demo to run, and has allowed +// me to port several other programs, but it is in no way +// complete. + +#include +#include + +void Fl_Free::step(void *v) { + Fl_Free *f = (Fl_Free *)v; + int old_event = Fl::e_number; + f->handle(Fl::e_number == FL_STEP); + Fl::e_number = old_event; + Fl::add_timeout(.01,step,v); +} + +/** + Create a new Fl_Free widget with type, position, size, label and handler. + \param[in] t type + \param[in] X, Y, W, H position and size + \param[in] L widget label + \param[in] hdl handler function + + The constructor takes both the type and the handle function. The handle + function should be declared as follows: + \code + int handle_function(Fl_Widget *w, + int event, + float event_x, + float event_y, + char key) + \endcode + This function is called from the handle() method in response to most + events, and is called by the draw() method. + + The event argument contains the event type: + \code + // old event names for compatibility: + #define FL_MOUSE FL_DRAG + #define FL_DRAW 0 + #define FL_STEP 9 + #define FL_FREEMEM 12 + #define FL_FREEZE FL_UNMAP + #define FL_THAW FL_MAP + \endcode +*/ +Fl_Free::Fl_Free(uchar t,int X, int Y, int W, int H,const char *L, + FL_HANDLEPTR hdl) : +Fl_Widget(X,Y,W,H,L) { + type(t); + hfunc = hdl; + if (t == FL_SLEEPING_FREE) set_flag(INACTIVE); + if (t == FL_CONTINUOUS_FREE || t == FL_ALL_FREE) + Fl::add_timeout(.01,step,this); +} + +/** + The destructor will call the handle function with the event FL_FREE_MEM. +*/ +Fl_Free::~Fl_Free() { + Fl::remove_timeout(step,this); + hfunc(this,FL_FREEMEM,0,0,0); +} + +void Fl_Free::draw() {hfunc(this,FL_DRAW,0,0,0);} + +int Fl_Free::handle(int e) { + char key = Fl::event_key(); + switch (e) { + case FL_FOCUS: + if (type()!=FL_INPUT_FREE && type()!=FL_ALL_FREE) return 0; + break; + case FL_PUSH: + case FL_DRAG: + case FL_RELEASE: + key = 4-Fl::event_button(); + break; + case FL_SHORTCUT: + return 0; + } + if (hfunc(this, e, float(Fl::event_x()), float(Fl::event_y()), key)) do_callback(); + return 1; +} + +// +// End of "$Id: forms_free.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/forms_fselect.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/forms_fselect.cxx new file mode 100644 index 0000000..9345476 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/forms_fselect.cxx @@ -0,0 +1,67 @@ +// +// "$Id: forms_fselect.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Forms file selection routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Emulate the Forms file chooser using the fltk file chooser. + +#include +#include "flstring.h" + +static char fl_directory[1024]; +static const char *fl_pattern; // assumed passed value is static +static char fl_filename[1024]; + +char* fl_show_file_selector(const char *message,const char *dir, + const char *pat,const char *fname) { + if (dir && dir[0]) strlcpy(fl_directory,dir,sizeof(fl_directory)); + if (pat && pat[0]) fl_pattern = pat; + if (fname && fname[0]) strlcpy(fl_filename,fname,sizeof(fl_filename)); + char *p = fl_directory+strlen(fl_directory); + if (p > fl_directory && *(p-1)!='/' +#ifdef WIN32 + && *(p-1)!='\\' && *(p-1)!=':' +#endif + ) *p++ = '/'; + strlcpy(p,fl_filename,sizeof(fl_directory) - (p - fl_directory)); + const char *q = fl_file_chooser(message,fl_pattern,fl_directory); + if (!q) return 0; + strlcpy(fl_directory, q, sizeof(fl_directory)); + p = (char *)fl_filename_name(fl_directory); + strlcpy(fl_filename, p, sizeof(fl_filename)); + if (p > fl_directory+1) p--; + *p = 0; + return (char *)q; +} + +char* fl_get_directory() {return fl_directory;} + +char* fl_get_pattern() {return (char *)fl_pattern;} + +char* fl_get_filename() {return fl_filename;} + +// +// End of "$Id: forms_fselect.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/forms_pixmap.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/forms_pixmap.cxx new file mode 100644 index 0000000..93d7499 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/forms_pixmap.cxx @@ -0,0 +1,63 @@ +// +// "$Id: forms_pixmap.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Forms pixmap drawing routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include + +/** + Creates a new Fl_FormsPixmap widget using the given box type, position, + size and label string. + \param[in] t box type + \param[in] X, Y, W, H position and size + \param[in] L widget label, default is no label +*/ +Fl_FormsPixmap::Fl_FormsPixmap( + Fl_Boxtype t, int X, int Y, int W, int H, const char* L) +: Fl_Widget(X, Y, W, H, L) { + box(t); + b = 0; + color(FL_BLACK); + align(FL_ALIGN_BOTTOM); +} + +/** + Set/create the internal pixmap using raw data. + \param[in] bits raw data +*/ +void Fl_FormsPixmap::set(char*const* bits) { + delete b; + b = new Fl_Pixmap(bits); +} + +void Fl_FormsPixmap::draw() { + draw_box(box(), selection_color()); + if (b) {fl_color(color()); b->draw(x(), y(), w(), h());} + draw_label(); +} + +// +// End of "$Id: forms_pixmap.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/forms_timer.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/forms_timer.cxx new file mode 100644 index 0000000..25f929d --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/forms_timer.cxx @@ -0,0 +1,186 @@ +// +// "$Id: forms_timer.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Forms timer object for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Emulate the Forms Timer object +// You don't want to use this if you just want a timeout, call +// Fl::add_timeout directly! + +#include +#include +#include +#ifdef WIN32 +# ifdef __MWERKS__ +# include +# else +# include +# include +# endif +#else +# include +# include +#endif +#include + +#define FL_TIMER_BLINKRATE 0.2 + +void fl_gettime(long* sec, long* usec) { +#ifdef WIN32 +# ifdef __MWERKS__ + time_t localTime = time(NULL); + struct tm *now = localtime(&localTime); + *sec = now->tm_sec + 60*now->tm_min + 3600*now->tm_hour + 24*3600*now->tm_yday; + *usec = 0; +# else + struct timeb tp; + ftime(&tp); + *sec = tp.time; + *usec = tp.millitm * 1000; +# endif +#else + struct timeval tp; + struct timezone tzp; + gettimeofday(&tp, &tzp); + *sec = tp.tv_sec; + *usec = tp.tv_usec; +#endif +} + +void Fl_Timer::draw() { + int tt; + Fl_Color col; + char str[32]; + if (!on || delay>0.0) + col = color(); + else if ((int) (delay / FL_TIMER_BLINKRATE) % 2) + col = color(); + else + col = selection_color(); + draw_box(box(), col); + if (type() == FL_VALUE_TIMER && delay>0.0) { + double d = direction_ ? total-delay : delay; + if (d < 60.0) + sprintf(str, "%.1f", d); + else { + tt = (int) ((d+0.05) / 60.0); + sprintf(str, "%d:%04.1f", tt, d - 60.0 * tt); + } + fl_font(labelfont(), labelsize()); + fl_color(labelcolor()); + fl_draw(str, x(), y(), w(), h(), FL_ALIGN_CENTER); + } else + draw_label(); +} + +void Fl_Timer::stepcb(void* v) { + ((Fl_Timer*)v)->step(); +} + +void Fl_Timer::step() { + if (!on) return; + double lastdelay = delay; + long sec, usec; fl_gettime(&sec, &usec); + delay -= (double) (sec - lastsec) + (double) (usec - lastusec) / 1000000.0; + lastsec = sec; lastusec = usec; + if (lastdelay > 0.0 && delay <= 0.0) { + if (type() == FL_HIDDEN_TIMER) { + on = 0; + delay = 0; + } else { + redraw(); + Fl::add_timeout(FL_TIMER_BLINKRATE, stepcb, this); + } + set_changed(); + do_callback(); + } else { + if (type() == FL_VALUE_TIMER) redraw(); + Fl::add_timeout(FL_TIMER_BLINKRATE, stepcb, this); + } +} + +int Fl_Timer::handle(int event) { + if (event == FL_RELEASE && delay <= 0) value(0.0); + return 0; +} + +/** + Destroys the timer and removes the timeout. +*/ +Fl_Timer::~Fl_Timer() { + Fl::remove_timeout(stepcb, this); +} + +/** + Creates a new Fl_Timer widget using the given type, position, + size, and label string. The type parameter can be any of the + following symbolic constants: + + \li FL_NORMAL_TIMER - The timer just does the callback and + displays the string "Timer" in the widget. + \li FL_VALUE_TIMER - The timer does the callback and displays + the current timer value in the widget. + \li FL_HIDDEN_TIMER - The timer just does the callback and + does not display anything. +*/ +Fl_Timer::Fl_Timer(uchar t, int X, int Y, int W, int H, const char* l) + +: Fl_Widget(X, Y, W, H, l) { + box(FL_DOWN_BOX); + selection_color(FL_RED); + delay = 0; + on = 0; + direction_ = 0; + type(t); + if (t == FL_HIDDEN_TIMER) clear_visible(); + if (t == FL_VALUE_TIMER) align(FL_ALIGN_LEFT); +} +/** Sets the current timer value */ +void Fl_Timer::value(double d) { + delay = total = d; + on = (d > 0.0); + fl_gettime(&(lastsec), &(lastusec)); + if (type() != FL_HIDDEN_TIMER) redraw(); + Fl::remove_timeout(stepcb, this); + if (on) Fl::add_timeout(FL_TIMER_BLINKRATE, stepcb, this); +} + +/** Gets or sets whether the timer is suspended.*/ +void Fl_Timer::suspended(char d) { + if (!d) { + if (on) return; + on = (delay > 0.0); + fl_gettime(&(lastsec), &(lastusec)); + if (on) Fl::add_timeout(FL_TIMER_BLINKRATE, stepcb, this); + } else { + if (!on) return; + on = 0; + Fl::remove_timeout(stepcb, this); + } +} + +// +// End of "$Id: forms_timer.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/freeglut_geometry.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/freeglut_geometry.cxx new file mode 100644 index 0000000..d11c9ef --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/freeglut_geometry.cxx @@ -0,0 +1,1110 @@ +/* + * freeglut_geometry.c + * + * Freeglut geometry rendering methods. + * + * Copyright (c) 1999-2010 Pawel W. Olszta. All Rights Reserved. + * Written by Pawel W. Olszta, + * Creation date: Fri Dec 3 1999 + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include + +/* + * TODO BEFORE THE STABLE RELEASE: + * + * Following functions have been contributed by Andreas Umbach. + * + * glutWireCube() -- looks OK + * glutSolidCube() -- OK + * + * Those functions have been implemented by John Fay. + * + * glutWireTorus() -- looks OK + * glutSolidTorus() -- looks OK + * glutWireDodecahedron() -- looks OK + * glutSolidDodecahedron() -- looks OK + * glutWireOctahedron() -- looks OK + * glutSolidOctahedron() -- looks OK + * glutWireTetrahedron() -- looks OK + * glutSolidTetrahedron() -- looks OK + * glutWireIcosahedron() -- looks OK + * glutSolidIcosahedron() -- looks OK + * + * The Following functions have been updated by Nigel Stewart, based + * on FreeGLUT 2.0.0 implementations: + * + * glutWireSphere() -- looks OK + * glutSolidSphere() -- looks OK + * glutWireCone() -- looks OK + * glutSolidCone() -- looks OK + */ + + +/* -- INTERFACE FUNCTIONS -------------------------------------------------- */ + +/* + * Draws a wireframed cube. Code contributed by Andreas Umbach + */ +void glutWireCube( GLdouble dSize ) +{ + double size = dSize * 0.5; + +# define V(a,b,c) glVertex3d( a size, b size, c size ); +# define N(a,b,c) glNormal3d( a, b, c ); + + /* PWO: I dared to convert the code to use macros... */ + glBegin( GL_LINE_LOOP ); N( 1.0, 0.0, 0.0); V(+,-,+); V(+,-,-); V(+,+,-); V(+,+,+); glEnd(); + glBegin( GL_LINE_LOOP ); N( 0.0, 1.0, 0.0); V(+,+,+); V(+,+,-); V(-,+,-); V(-,+,+); glEnd(); + glBegin( GL_LINE_LOOP ); N( 0.0, 0.0, 1.0); V(+,+,+); V(-,+,+); V(-,-,+); V(+,-,+); glEnd(); + glBegin( GL_LINE_LOOP ); N(-1.0, 0.0, 0.0); V(-,-,+); V(-,+,+); V(-,+,-); V(-,-,-); glEnd(); + glBegin( GL_LINE_LOOP ); N( 0.0,-1.0, 0.0); V(-,-,+); V(-,-,-); V(+,-,-); V(+,-,+); glEnd(); + glBegin( GL_LINE_LOOP ); N( 0.0, 0.0,-1.0); V(-,-,-); V(-,+,-); V(+,+,-); V(+,-,-); glEnd(); + +# undef V +# undef N +} + +/* + * Draws a solid cube. Code contributed by Andreas Umbach + */ +void glutSolidCube( GLdouble dSize ) +{ + double size = dSize * 0.5; + +# define V(a,b,c) glVertex3d( a size, b size, c size ); +# define N(a,b,c) glNormal3d( a, b, c ); + + /* PWO: Again, I dared to convert the code to use macros... */ + glBegin( GL_QUADS ); + N( 1.0, 0.0, 0.0); V(+,-,+); V(+,-,-); V(+,+,-); V(+,+,+); + N( 0.0, 1.0, 0.0); V(+,+,+); V(+,+,-); V(-,+,-); V(-,+,+); + N( 0.0, 0.0, 1.0); V(+,+,+); V(-,+,+); V(-,-,+); V(+,-,+); + N(-1.0, 0.0, 0.0); V(-,-,+); V(-,+,+); V(-,+,-); V(-,-,-); + N( 0.0,-1.0, 0.0); V(-,-,+); V(-,-,-); V(+,-,-); V(+,-,+); + N( 0.0, 0.0,-1.0); V(-,-,-); V(-,+,-); V(+,+,-); V(+,-,-); + glEnd(); + +# undef V +# undef N +} + +/* + * Compute lookup table of cos and sin values forming a cirle + * + * Notes: + * It is the responsibility of the caller to free these tables + * The size of the table is (n+1) to form a connected loop + * The last entry is exactly the same as the first + * The sign of n can be flipped to get the reverse loop + */ + +static void fghCircleTable(double **sint,double **cost,const int n) +{ + int i; + + /* Table size, the sign of n flips the circle direction */ + + const int size = abs(n); + + /* Determine the angle between samples */ + + const double angle = 2*M_PI/(double)( ( n == 0 ) ? 1 : n ); + + /* Allocate memory for n samples, plus duplicate of first entry at the end */ + + *sint = (double *) calloc(sizeof(double), size+1); + *cost = (double *) calloc(sizeof(double), size+1); + + /* Bail out if memory allocation fails, fgError never returns */ + + if (!(*sint) || !(*cost)) + { + if (*sint) free(*sint); + if (*cost) free(*cost); + return; + } + + /* Compute cos and sin around the circle */ + + (*sint)[0] = 0.0; + (*cost)[0] = 1.0; + + for (i=1; i0)?1:0]; + r0 = 0.0; + r1 = sint2[(stacks>0)?1:0]; + + glBegin(GL_TRIANGLE_FAN); + + glNormal3d(0,0,1); + glVertex3d(0,0,radius); + + for (j=slices; j>=0; j--) + { + glNormal3d(cost1[j]*r1, sint1[j]*r1, z1 ); + glVertex3d(cost1[j]*r1*radius, sint1[j]*r1*radius, z1*radius); + } + + glEnd(); + + /* Cover each stack with a quad strip, except the top and bottom stacks */ + + for( i=1; i 0 ) ? stacks : 1 ); + const double rStep = base / ( ( stacks > 0 ) ? stacks : 1 ); + + /* Scaling factors for vertex normals */ + + const double cosn = ( height / sqrt ( height * height + base * base )); + const double sinn = ( base / sqrt ( height * height + base * base )); + + /* Pre-computed circle */ + + double *sint,*cost; + + fghCircleTable(&sint,&cost,-slices); + + /* Cover the circular base with a triangle fan... */ + + z0 = 0.0; + z1 = zStep; + + r0 = base; + r1 = r0 - rStep; + + glBegin(GL_TRIANGLE_FAN); + + glNormal3d(0.0,0.0,-1.0); + glVertex3d(0.0,0.0, z0 ); + + for (j=0; j<=slices; j++) + glVertex3d(cost[j]*r0, sint[j]*r0, z0); + + glEnd(); + + /* Cover each stack with a quad strip, except the top stack */ + + for( i=0; i 0 ) ? stacks : 1 ); + const double rStep = base / ( ( stacks > 0 ) ? stacks : 1 ); + + /* Scaling factors for vertex normals */ + + const double cosn = ( height / sqrt ( height * height + base * base )); + const double sinn = ( base / sqrt ( height * height + base * base )); + + /* Pre-computed circle */ + + double *sint,*cost; + + fghCircleTable(&sint,&cost,-slices); + + /* Draw the stacks... */ + + for (i=0; i 0 ) ? stacks : 1 ); + + /* Pre-computed circle */ + + double *sint,*cost; + + fghCircleTable(&sint,&cost,-slices); + + /* Cover the base and top */ + + glBegin(GL_TRIANGLE_FAN); + glNormal3d(0.0, 0.0, -1.0 ); + glVertex3d(0.0, 0.0, 0.0 ); + for (j=0; j<=slices; j++) + glVertex3d(cost[j]*radius, sint[j]*radius, 0.0); + glEnd(); + + glBegin(GL_TRIANGLE_FAN); + glNormal3d(0.0, 0.0, 1.0 ); + glVertex3d(0.0, 0.0, height); + for (j=slices; j>=0; j--) + glVertex3d(cost[j]*radius, sint[j]*radius, height); + glEnd(); + + /* Do the stacks */ + + z0 = 0.0; + z1 = zStep; + + for (i=1; i<=stacks; i++) + { + if (i==stacks) + z1 = height; + + glBegin(GL_QUAD_STRIP); + for (j=0; j<=slices; j++ ) + { + glNormal3d(cost[j], sint[j], 0.0 ); + glVertex3d(cost[j]*radius, sint[j]*radius, z0 ); + glVertex3d(cost[j]*radius, sint[j]*radius, z1 ); + } + glEnd(); + + z0 = z1; z1 += zStep; + } + + /* Release sin and cos tables */ + + free(sint); + free(cost); +} + +/* + * Draws a wire cylinder + */ +void glutWireCylinder(GLdouble radius, GLdouble height, GLint slices, GLint stacks) +{ + int i,j; + + /* Step in z and radius as stacks are drawn. */ + + double z = 0.0; + const double zStep = height / ( ( stacks > 0 ) ? stacks : 1 ); + + /* Pre-computed circle */ + + double *sint,*cost; + + fghCircleTable(&sint,&cost,-slices); + + /* Draw the stacks... */ + + for (i=0; i<=stacks; i++) + { + if (i==stacks) + z = height; + + glBegin(GL_LINE_LOOP); + + for( j=0; j + * Creation date: Thu Dec 16 1999 + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +/* This file has been automatically generated by the genstroke utility. */ + +#include + +/* char: 0x20 */ + +static const Fl_Glut_StrokeStrip ch32st[] = +{ + { 0, 0 } +}; + +static const Fl_Glut_StrokeChar ch32 = {104.762f,0,ch32st}; + +/* char: 0x21 */ + +static const Fl_Glut_StrokeVertex ch33st0[] = +{ + {52.381f,100.0f}, + {52.381f,33.3333f} +}; + +static const Fl_Glut_StrokeVertex ch33st1[] = +{ + {52.381f,9.5238f}, + {47.6191f,4.7619f}, + {52.381f,0.0f}, + {57.1429f,4.7619f}, + {52.381f,9.5238f} +}; + +static const Fl_Glut_StrokeStrip ch33st[] = +{ + {2,ch33st0}, + {5,ch33st1} +}; + +static const Fl_Glut_StrokeChar ch33 = {104.762f,2,ch33st}; + +/* char: 0x22 */ + +static const Fl_Glut_StrokeVertex ch34st0[] = +{ + {33.3334f,100.0f}, + {33.3334f,66.6667f} +}; + +static const Fl_Glut_StrokeVertex ch34st1[] = +{ + {71.4286f,100.0f}, + {71.4286f,66.6667f} +}; + +static const Fl_Glut_StrokeStrip ch34st[] = +{ + {2,ch34st0}, + {2,ch34st1} +}; + +static const Fl_Glut_StrokeChar ch34 = {104.762f,2,ch34st}; + +/* char: 0x23 */ + +static const Fl_Glut_StrokeVertex ch35st0[] = +{ + {54.7619f,119.048f}, + {21.4286f,-33.3333f} +}; + +static const Fl_Glut_StrokeVertex ch35st1[] = +{ + {83.3334f,119.048f}, + {50.0f,-33.3333f} +}; + +static const Fl_Glut_StrokeVertex ch35st2[] = +{ + {21.4286f,57.1429f}, + {88.0952f,57.1429f} +}; + +static const Fl_Glut_StrokeVertex ch35st3[] = +{ + {16.6667f,28.5714f}, + {83.3334f,28.5714f} +}; + +static const Fl_Glut_StrokeStrip ch35st[] = +{ + {2,ch35st0}, + {2,ch35st1}, + {2,ch35st2}, + {2,ch35st3} +}; + +static const Fl_Glut_StrokeChar ch35 = {104.762f,4,ch35st}; + +/* char: 0x24 */ + +static const Fl_Glut_StrokeVertex ch36st0[] = +{ + {42.8571f,119.048f}, + {42.8571f,-19.0476f} +}; + +static const Fl_Glut_StrokeVertex ch36st1[] = +{ + {61.9047f,119.048f}, + {61.9047f,-19.0476f} +}; + +static const Fl_Glut_StrokeVertex ch36st2[] = +{ + {85.7143f,85.7143f}, + {76.1905f,95.2381f}, + {61.9047f,100.0f}, + {42.8571f,100.0f}, + {28.5714f,95.2381f}, + {19.0476f,85.7143f}, + {19.0476f,76.1905f}, + {23.8095f,66.6667f}, + {28.5714f,61.9048f}, + {38.0952f,57.1429f}, + {66.6666f,47.619f}, + {76.1905f,42.8571f}, + {80.9524f,38.0952f}, + {85.7143f,28.5714f}, + {85.7143f,14.2857f}, + {76.1905f,4.7619f}, + {61.9047f,0.0f}, + {42.8571f,0.0f}, + {28.5714f,4.7619f}, + {19.0476f,14.2857f} +}; + +static const Fl_Glut_StrokeStrip ch36st[] = +{ + {2,ch36st0}, + {2,ch36st1}, + {20,ch36st2} +}; + +static const Fl_Glut_StrokeChar ch36 = {104.762f,3,ch36st}; + +/* char: 0x25 */ + +static const Fl_Glut_StrokeVertex ch37st0[] = +{ + {95.2381f,100.0f}, + {9.5238f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch37st1[] = +{ + {33.3333f,100.0f}, + {42.8571f,90.4762f}, + {42.8571f,80.9524f}, + {38.0952f,71.4286f}, + {28.5714f,66.6667f}, + {19.0476f,66.6667f}, + {9.5238f,76.1905f}, + {9.5238f,85.7143f}, + {14.2857f,95.2381f}, + {23.8095f,100.0f}, + {33.3333f,100.0f}, + {42.8571f,95.2381f}, + {57.1428f,90.4762f}, + {71.4286f,90.4762f}, + {85.7143f,95.2381f}, + {95.2381f,100.0f} +}; + +static const Fl_Glut_StrokeVertex ch37st2[] = +{ + {76.1905f,33.3333f}, + {66.6667f,28.5714f}, + {61.9048f,19.0476f}, + {61.9048f,9.5238f}, + {71.4286f,0.0f}, + {80.9524f,0.0f}, + {90.4762f,4.7619f}, + {95.2381f,14.2857f}, + {95.2381f,23.8095f}, + {85.7143f,33.3333f}, + {76.1905f,33.3333f} +}; + +static const Fl_Glut_StrokeStrip ch37st[] = +{ + {2,ch37st0}, + {16,ch37st1}, + {11,ch37st2} +}; + +static const Fl_Glut_StrokeChar ch37 = {104.762f,3,ch37st}; + +/* char: 0x26 */ + +static const Fl_Glut_StrokeVertex ch38st0[] = +{ + {100.0f,57.1429f}, + {100.0f,61.9048f}, + {95.2381f,66.6667f}, + {90.4762f,66.6667f}, + {85.7143f,61.9048f}, + {80.9524f,52.381f}, + {71.4286f,28.5714f}, + {61.9048f,14.2857f}, + {52.3809f,4.7619f}, + {42.8571f,0.0f}, + {23.8095f,0.0f}, + {14.2857f,4.7619f}, + {9.5238f,9.5238f}, + {4.7619f,19.0476f}, + {4.7619f,28.5714f}, + {9.5238f,38.0952f}, + {14.2857f,42.8571f}, + {47.619f,61.9048f}, + {52.3809f,66.6667f}, + {57.1429f,76.1905f}, + {57.1429f,85.7143f}, + {52.3809f,95.2381f}, + {42.8571f,100.0f}, + {33.3333f,95.2381f}, + {28.5714f,85.7143f}, + {28.5714f,76.1905f}, + {33.3333f,61.9048f}, + {42.8571f,47.619f}, + {66.6667f,14.2857f}, + {76.1905f,4.7619f}, + {85.7143f,0.0f}, + {95.2381f,0.0f}, + {100.0f,4.7619f}, + {100.0f,9.5238f} +}; + +static const Fl_Glut_StrokeStrip ch38st[] = +{ + {34,ch38st0} +}; + +static const Fl_Glut_StrokeChar ch38 = {104.762f,1,ch38st}; + +/* char: 0x27 */ + +static const Fl_Glut_StrokeVertex ch39st0[] = +{ + {52.381f,100.0f}, + {52.381f,66.6667f} +}; + +static const Fl_Glut_StrokeStrip ch39st[] = +{ + {2,ch39st0} +}; + +static const Fl_Glut_StrokeChar ch39 = {104.762f,1,ch39st}; + +/* char: 0x28 */ + +static const Fl_Glut_StrokeVertex ch40st0[] = +{ + {69.0476f,119.048f}, + {59.5238f,109.524f}, + {50.0f,95.2381f}, + {40.4762f,76.1905f}, + {35.7143f,52.381f}, + {35.7143f,33.3333f}, + {40.4762f,9.5238f}, + {50.0f,-9.5238f}, + {59.5238f,-23.8095f}, + {69.0476f,-33.3333f} +}; + +static const Fl_Glut_StrokeStrip ch40st[] = +{ + {10,ch40st0} +}; + +static const Fl_Glut_StrokeChar ch40 = {104.762f,1,ch40st}; + +/* char: 0x29 */ + +static const Fl_Glut_StrokeVertex ch41st0[] = +{ + {35.7143f,119.048f}, + {45.2381f,109.524f}, + {54.7619f,95.2381f}, + {64.2857f,76.1905f}, + {69.0476f,52.381f}, + {69.0476f,33.3333f}, + {64.2857f,9.5238f}, + {54.7619f,-9.5238f}, + {45.2381f,-23.8095f}, + {35.7143f,-33.3333f} +}; + +static const Fl_Glut_StrokeStrip ch41st[] = +{ + {10,ch41st0} +}; + +static const Fl_Glut_StrokeChar ch41 = {104.762f,1,ch41st}; + +/* char: 0x2a */ + +static const Fl_Glut_StrokeVertex ch42st0[] = +{ + {52.381f,71.4286f}, + {52.381f,14.2857f} +}; + +static const Fl_Glut_StrokeVertex ch42st1[] = +{ + {28.5715f,57.1429f}, + {76.1905f,28.5714f} +}; + +static const Fl_Glut_StrokeVertex ch42st2[] = +{ + {76.1905f,57.1429f}, + {28.5715f,28.5714f} +}; + +static const Fl_Glut_StrokeStrip ch42st[] = +{ + {2,ch42st0}, + {2,ch42st1}, + {2,ch42st2} +}; + +static const Fl_Glut_StrokeChar ch42 = {104.762f,3,ch42st}; + +/* char: 0x2b */ + +static const Fl_Glut_StrokeVertex ch43st0[] = +{ + {52.3809f,85.7143f}, + {52.3809f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch43st1[] = +{ + {9.5238f,42.8571f}, + {95.2381f,42.8571f} +}; + +static const Fl_Glut_StrokeStrip ch43st[] = +{ + {2,ch43st0}, + {2,ch43st1} +}; + +static const Fl_Glut_StrokeChar ch43 = {104.762f,2,ch43st}; + +/* char: 0x2c */ + +static const Fl_Glut_StrokeVertex ch44st0[] = +{ + {57.1429f,4.7619f}, + {52.381f,0.0f}, + {47.6191f,4.7619f}, + {52.381f,9.5238f}, + {57.1429f,4.7619f}, + {57.1429f,-4.7619f}, + {52.381f,-14.2857f}, + {47.6191f,-19.0476f} +}; + +static const Fl_Glut_StrokeStrip ch44st[] = +{ + {8,ch44st0} +}; + +static const Fl_Glut_StrokeChar ch44 = {104.762f,1,ch44st}; + +/* char: 0x2d */ + +static const Fl_Glut_StrokeVertex ch45st0[] = +{ + {9.5238f,42.8571f}, + {95.2381f,42.8571f} +}; + +static const Fl_Glut_StrokeStrip ch45st[] = +{ + {2,ch45st0} +}; + +static const Fl_Glut_StrokeChar ch45 = {104.762f,1,ch45st}; + +/* char: 0x2e */ + +static const Fl_Glut_StrokeVertex ch46st0[] = +{ + {52.381f,9.5238f}, + {47.6191f,4.7619f}, + {52.381f,0.0f}, + {57.1429f,4.7619f}, + {52.381f,9.5238f} +}; + +static const Fl_Glut_StrokeStrip ch46st[] = +{ + {5,ch46st0} +}; + +static const Fl_Glut_StrokeChar ch46 = {104.762f,1,ch46st}; + +/* char: 0x2f */ + +static const Fl_Glut_StrokeVertex ch47st0[] = +{ + {19.0476f,-14.2857f}, + {85.7143f,100.0f} +}; + +static const Fl_Glut_StrokeStrip ch47st[] = +{ + {2,ch47st0} +}; + +static const Fl_Glut_StrokeChar ch47 = {104.762f,1,ch47st}; + +/* char: 0x30 */ + +static const Fl_Glut_StrokeVertex ch48st0[] = +{ + {47.619f,100.0f}, + {33.3333f,95.2381f}, + {23.8095f,80.9524f}, + {19.0476f,57.1429f}, + {19.0476f,42.8571f}, + {23.8095f,19.0476f}, + {33.3333f,4.7619f}, + {47.619f,0.0f}, + {57.1428f,0.0f}, + {71.4286f,4.7619f}, + {80.9524f,19.0476f}, + {85.7143f,42.8571f}, + {85.7143f,57.1429f}, + {80.9524f,80.9524f}, + {71.4286f,95.2381f}, + {57.1428f,100.0f}, + {47.619f,100.0f} +}; + +static const Fl_Glut_StrokeStrip ch48st[] = +{ + {17,ch48st0} +}; + +static const Fl_Glut_StrokeChar ch48 = {104.762f,1,ch48st}; + +/* char: 0x31 */ + +static const Fl_Glut_StrokeVertex ch49st0[] = +{ + {40.4762f,80.9524f}, + {50.0f,85.7143f}, + {64.2857f,100.0f}, + {64.2857f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch49st[] = +{ + {4,ch49st0} +}; + +static const Fl_Glut_StrokeChar ch49 = {104.762f,1,ch49st}; + +/* char: 0x32 */ + +static const Fl_Glut_StrokeVertex ch50st0[] = +{ + {23.8095f,76.1905f}, + {23.8095f,80.9524f}, + {28.5714f,90.4762f}, + {33.3333f,95.2381f}, + {42.8571f,100.0f}, + {61.9047f,100.0f}, + {71.4286f,95.2381f}, + {76.1905f,90.4762f}, + {80.9524f,80.9524f}, + {80.9524f,71.4286f}, + {76.1905f,61.9048f}, + {66.6666f,47.619f}, + {19.0476f,0.0f}, + {85.7143f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch50st[] = +{ + {14,ch50st0} +}; + +static const Fl_Glut_StrokeChar ch50 = {104.762f,1,ch50st}; + +/* char: 0x33 */ + +static const Fl_Glut_StrokeVertex ch51st0[] = +{ + {28.5714f,100.0f}, + {80.9524f,100.0f}, + {52.3809f,61.9048f}, + {66.6666f,61.9048f}, + {76.1905f,57.1429f}, + {80.9524f,52.381f}, + {85.7143f,38.0952f}, + {85.7143f,28.5714f}, + {80.9524f,14.2857f}, + {71.4286f,4.7619f}, + {57.1428f,0.0f}, + {42.8571f,0.0f}, + {28.5714f,4.7619f}, + {23.8095f,9.5238f}, + {19.0476f,19.0476f} +}; + +static const Fl_Glut_StrokeStrip ch51st[] = +{ + {15,ch51st0} +}; + +static const Fl_Glut_StrokeChar ch51 = {104.762f,1,ch51st}; + +/* char: 0x34 */ + +static const Fl_Glut_StrokeVertex ch52st0[] = +{ + {64.2857f,100.0f}, + {16.6667f,33.3333f}, + {88.0952f,33.3333f} +}; + +static const Fl_Glut_StrokeVertex ch52st1[] = +{ + {64.2857f,100.0f}, + {64.2857f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch52st[] = +{ + {3,ch52st0}, + {2,ch52st1} +}; + +static const Fl_Glut_StrokeChar ch52 = {104.762f,2,ch52st}; + +/* char: 0x35 */ + +static const Fl_Glut_StrokeVertex ch53st0[] = +{ + {76.1905f,100.0f}, + {28.5714f,100.0f}, + {23.8095f,57.1429f}, + {28.5714f,61.9048f}, + {42.8571f,66.6667f}, + {57.1428f,66.6667f}, + {71.4286f,61.9048f}, + {80.9524f,52.381f}, + {85.7143f,38.0952f}, + {85.7143f,28.5714f}, + {80.9524f,14.2857f}, + {71.4286f,4.7619f}, + {57.1428f,0.0f}, + {42.8571f,0.0f}, + {28.5714f,4.7619f}, + {23.8095f,9.5238f}, + {19.0476f,19.0476f} +}; + +static const Fl_Glut_StrokeStrip ch53st[] = +{ + {17,ch53st0} +}; + +static const Fl_Glut_StrokeChar ch53 = {104.762f,1,ch53st}; + +/* char: 0x36 */ + +static const Fl_Glut_StrokeVertex ch54st0[] = +{ + {78.5714f,85.7143f}, + {73.8096f,95.2381f}, + {59.5238f,100.0f}, + {50.0f,100.0f}, + {35.7143f,95.2381f}, + {26.1905f,80.9524f}, + {21.4286f,57.1429f}, + {21.4286f,33.3333f}, + {26.1905f,14.2857f}, + {35.7143f,4.7619f}, + {50.0f,0.0f}, + {54.7619f,0.0f}, + {69.0476f,4.7619f}, + {78.5714f,14.2857f}, + {83.3334f,28.5714f}, + {83.3334f,33.3333f}, + {78.5714f,47.619f}, + {69.0476f,57.1429f}, + {54.7619f,61.9048f}, + {50.0f,61.9048f}, + {35.7143f,57.1429f}, + {26.1905f,47.619f}, + {21.4286f,33.3333f} +}; + +static const Fl_Glut_StrokeStrip ch54st[] = +{ + {23,ch54st0} +}; + +static const Fl_Glut_StrokeChar ch54 = {104.762f,1,ch54st}; + +/* char: 0x37 */ + +static const Fl_Glut_StrokeVertex ch55st0[] = +{ + {85.7143f,100.0f}, + {38.0952f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch55st1[] = +{ + {19.0476f,100.0f}, + {85.7143f,100.0f} +}; + +static const Fl_Glut_StrokeStrip ch55st[] = +{ + {2,ch55st0}, + {2,ch55st1} +}; + +static const Fl_Glut_StrokeChar ch55 = {104.762f,2,ch55st}; + +/* char: 0x38 */ + +static const Fl_Glut_StrokeVertex ch56st0[] = +{ + {42.8571f,100.0f}, + {28.5714f,95.2381f}, + {23.8095f,85.7143f}, + {23.8095f,76.1905f}, + {28.5714f,66.6667f}, + {38.0952f,61.9048f}, + {57.1428f,57.1429f}, + {71.4286f,52.381f}, + {80.9524f,42.8571f}, + {85.7143f,33.3333f}, + {85.7143f,19.0476f}, + {80.9524f,9.5238f}, + {76.1905f,4.7619f}, + {61.9047f,0.0f}, + {42.8571f,0.0f}, + {28.5714f,4.7619f}, + {23.8095f,9.5238f}, + {19.0476f,19.0476f}, + {19.0476f,33.3333f}, + {23.8095f,42.8571f}, + {33.3333f,52.381f}, + {47.619f,57.1429f}, + {66.6666f,61.9048f}, + {76.1905f,66.6667f}, + {80.9524f,76.1905f}, + {80.9524f,85.7143f}, + {76.1905f,95.2381f}, + {61.9047f,100.0f}, + {42.8571f,100.0f} +}; + +static const Fl_Glut_StrokeStrip ch56st[] = +{ + {29,ch56st0} +}; + +static const Fl_Glut_StrokeChar ch56 = {104.762f,1,ch56st}; + +/* char: 0x39 */ + +static const Fl_Glut_StrokeVertex ch57st0[] = +{ + {83.3334f,66.6667f}, + {78.5714f,52.381f}, + {69.0476f,42.8571f}, + {54.7619f,38.0952f}, + {50.0f,38.0952f}, + {35.7143f,42.8571f}, + {26.1905f,52.381f}, + {21.4286f,66.6667f}, + {21.4286f,71.4286f}, + {26.1905f,85.7143f}, + {35.7143f,95.2381f}, + {50.0f,100.0f}, + {54.7619f,100.0f}, + {69.0476f,95.2381f}, + {78.5714f,85.7143f}, + {83.3334f,66.6667f}, + {83.3334f,42.8571f}, + {78.5714f,19.0476f}, + {69.0476f,4.7619f}, + {54.7619f,0.0f}, + {45.2381f,0.0f}, + {30.9524f,4.7619f}, + {26.1905f,14.2857f} +}; + +static const Fl_Glut_StrokeStrip ch57st[] = +{ + {23,ch57st0} +}; + +static const Fl_Glut_StrokeChar ch57 = {104.762f,1,ch57st}; + +/* char: 0x3a */ + +static const Fl_Glut_StrokeVertex ch58st0[] = +{ + {52.381f,66.6667f}, + {47.6191f,61.9048f}, + {52.381f,57.1429f}, + {57.1429f,61.9048f}, + {52.381f,66.6667f} +}; + +static const Fl_Glut_StrokeVertex ch58st1[] = +{ + {52.381f,9.5238f}, + {47.6191f,4.7619f}, + {52.381f,0.0f}, + {57.1429f,4.7619f}, + {52.381f,9.5238f} +}; + +static const Fl_Glut_StrokeStrip ch58st[] = +{ + {5,ch58st0}, + {5,ch58st1} +}; + +static const Fl_Glut_StrokeChar ch58 = {104.762f,2,ch58st}; + +/* char: 0x3b */ + +static const Fl_Glut_StrokeVertex ch59st0[] = +{ + {52.381f,66.6667f}, + {47.6191f,61.9048f}, + {52.381f,57.1429f}, + {57.1429f,61.9048f}, + {52.381f,66.6667f} +}; + +static const Fl_Glut_StrokeVertex ch59st1[] = +{ + {57.1429f,4.7619f}, + {52.381f,0.0f}, + {47.6191f,4.7619f}, + {52.381f,9.5238f}, + {57.1429f,4.7619f}, + {57.1429f,-4.7619f}, + {52.381f,-14.2857f}, + {47.6191f,-19.0476f} +}; + +static const Fl_Glut_StrokeStrip ch59st[] = +{ + {5,ch59st0}, + {8,ch59st1} +}; + +static const Fl_Glut_StrokeChar ch59 = {104.762f,2,ch59st}; + +/* char: 0x3c */ + +static const Fl_Glut_StrokeVertex ch60st0[] = +{ + {90.4762f,85.7143f}, + {14.2857f,42.8571f}, + {90.4762f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch60st[] = +{ + {3,ch60st0} +}; + +static const Fl_Glut_StrokeChar ch60 = {104.762f,1,ch60st}; + +/* char: 0x3d */ + +static const Fl_Glut_StrokeVertex ch61st0[] = +{ + {9.5238f,57.1429f}, + {95.2381f,57.1429f} +}; + +static const Fl_Glut_StrokeVertex ch61st1[] = +{ + {9.5238f,28.5714f}, + {95.2381f,28.5714f} +}; + +static const Fl_Glut_StrokeStrip ch61st[] = +{ + {2,ch61st0}, + {2,ch61st1} +}; + +static const Fl_Glut_StrokeChar ch61 = {104.762f,2,ch61st}; + +/* char: 0x3e */ + +static const Fl_Glut_StrokeVertex ch62st0[] = +{ + {14.2857f,85.7143f}, + {90.4762f,42.8571f}, + {14.2857f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch62st[] = +{ + {3,ch62st0} +}; + +static const Fl_Glut_StrokeChar ch62 = {104.762f,1,ch62st}; + +/* char: 0x3f */ + +static const Fl_Glut_StrokeVertex ch63st0[] = +{ + {23.8095f,76.1905f}, + {23.8095f,80.9524f}, + {28.5714f,90.4762f}, + {33.3333f,95.2381f}, + {42.8571f,100.0f}, + {61.9047f,100.0f}, + {71.4285f,95.2381f}, + {76.1905f,90.4762f}, + {80.9524f,80.9524f}, + {80.9524f,71.4286f}, + {76.1905f,61.9048f}, + {71.4285f,57.1429f}, + {52.3809f,47.619f}, + {52.3809f,33.3333f} +}; + +static const Fl_Glut_StrokeVertex ch63st1[] = +{ + {52.3809f,9.5238f}, + {47.619f,4.7619f}, + {52.3809f,0.0f}, + {57.1428f,4.7619f}, + {52.3809f,9.5238f} +}; + +static const Fl_Glut_StrokeStrip ch63st[] = +{ + {14,ch63st0}, + {5,ch63st1} +}; + +static const Fl_Glut_StrokeChar ch63 = {104.762f,2,ch63st}; + +/* char: 0x40 */ + +static const Fl_Glut_StrokeVertex ch64st0[] = +{ + {64.2857f,52.381f}, + {54.7619f,57.1429f}, + {45.2381f,57.1429f}, + {40.4762f,47.619f}, + {40.4762f,42.8571f}, + {45.2381f,33.3333f}, + {54.7619f,33.3333f}, + {64.2857f,38.0952f} +}; + +static const Fl_Glut_StrokeVertex ch64st1[] = +{ + {64.2857f,57.1429f}, + {64.2857f,38.0952f}, + {69.0476f,33.3333f}, + {78.5714f,33.3333f}, + {83.3334f,42.8571f}, + {83.3334f,47.619f}, + {78.5714f,61.9048f}, + {69.0476f,71.4286f}, + {54.7619f,76.1905f}, + {50.0f,76.1905f}, + {35.7143f,71.4286f}, + {26.1905f,61.9048f}, + {21.4286f,47.619f}, + {21.4286f,42.8571f}, + {26.1905f,28.5714f}, + {35.7143f,19.0476f}, + {50.0f,14.2857f}, + {54.7619f,14.2857f}, + {69.0476f,19.0476f} +}; + +static const Fl_Glut_StrokeStrip ch64st[] = +{ + {8,ch64st0}, + {19,ch64st1} +}; + +static const Fl_Glut_StrokeChar ch64 = {104.762f,2,ch64st}; + +/* char: 0x41 */ + +static const Fl_Glut_StrokeVertex ch65st0[] = +{ + {52.3809f,100.0f}, + {14.2857f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch65st1[] = +{ + {52.3809f,100.0f}, + {90.4762f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch65st2[] = +{ + {28.5714f,33.3333f}, + {76.1905f,33.3333f} +}; + +static const Fl_Glut_StrokeStrip ch65st[] = +{ + {2,ch65st0}, + {2,ch65st1}, + {2,ch65st2} +}; + +static const Fl_Glut_StrokeChar ch65 = {104.762f,3,ch65st}; + +/* char: 0x42 */ + +static const Fl_Glut_StrokeVertex ch66st0[] = +{ + {19.0476f,100.0f}, + {19.0476f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch66st1[] = +{ + {19.0476f,100.0f}, + {61.9047f,100.0f}, + {76.1905f,95.2381f}, + {80.9524f,90.4762f}, + {85.7143f,80.9524f}, + {85.7143f,71.4286f}, + {80.9524f,61.9048f}, + {76.1905f,57.1429f}, + {61.9047f,52.381f} +}; + +static const Fl_Glut_StrokeVertex ch66st2[] = +{ + {19.0476f,52.381f}, + {61.9047f,52.381f}, + {76.1905f,47.619f}, + {80.9524f,42.8571f}, + {85.7143f,33.3333f}, + {85.7143f,19.0476f}, + {80.9524f,9.5238f}, + {76.1905f,4.7619f}, + {61.9047f,0.0f}, + {19.0476f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch66st[] = +{ + {2,ch66st0}, + {9,ch66st1}, + {10,ch66st2} +}; + +static const Fl_Glut_StrokeChar ch66 = {104.762f,3,ch66st}; + +/* char: 0x43 */ + +static const Fl_Glut_StrokeVertex ch67st0[] = +{ + {88.0952f,76.1905f}, + {83.3334f,85.7143f}, + {73.8096f,95.2381f}, + {64.2857f,100.0f}, + {45.2381f,100.0f}, + {35.7143f,95.2381f}, + {26.1905f,85.7143f}, + {21.4286f,76.1905f}, + {16.6667f,61.9048f}, + {16.6667f,38.0952f}, + {21.4286f,23.8095f}, + {26.1905f,14.2857f}, + {35.7143f,4.7619f}, + {45.2381f,0.0f}, + {64.2857f,0.0f}, + {73.8096f,4.7619f}, + {83.3334f,14.2857f}, + {88.0952f,23.8095f} +}; + +static const Fl_Glut_StrokeStrip ch67st[] = +{ + {18,ch67st0} +}; + +static const Fl_Glut_StrokeChar ch67 = {104.762f,1,ch67st}; + +/* char: 0x44 */ + +static const Fl_Glut_StrokeVertex ch68st0[] = +{ + {19.0476f,100.0f}, + {19.0476f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch68st1[] = +{ + {19.0476f,100.0f}, + {52.3809f,100.0f}, + {66.6666f,95.2381f}, + {76.1905f,85.7143f}, + {80.9524f,76.1905f}, + {85.7143f,61.9048f}, + {85.7143f,38.0952f}, + {80.9524f,23.8095f}, + {76.1905f,14.2857f}, + {66.6666f,4.7619f}, + {52.3809f,0.0f}, + {19.0476f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch68st[] = +{ + {2,ch68st0}, + {12,ch68st1} +}; + +static const Fl_Glut_StrokeChar ch68 = {104.762f,2,ch68st}; + +/* char: 0x45 */ + +static const Fl_Glut_StrokeVertex ch69st0[] = +{ + {21.4286f,100.0f}, + {21.4286f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch69st1[] = +{ + {21.4286f,100.0f}, + {83.3334f,100.0f} +}; + +static const Fl_Glut_StrokeVertex ch69st2[] = +{ + {21.4286f,52.381f}, + {59.5238f,52.381f} +}; + +static const Fl_Glut_StrokeVertex ch69st3[] = +{ + {21.4286f,0.0f}, + {83.3334f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch69st[] = +{ + {2,ch69st0}, + {2,ch69st1}, + {2,ch69st2}, + {2,ch69st3} +}; + +static const Fl_Glut_StrokeChar ch69 = {104.762f,4,ch69st}; + +/* char: 0x46 */ + +static const Fl_Glut_StrokeVertex ch70st0[] = +{ + {21.4286f,100.0f}, + {21.4286f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch70st1[] = +{ + {21.4286f,100.0f}, + {83.3334f,100.0f} +}; + +static const Fl_Glut_StrokeVertex ch70st2[] = +{ + {21.4286f,52.381f}, + {59.5238f,52.381f} +}; + +static const Fl_Glut_StrokeStrip ch70st[] = +{ + {2,ch70st0}, + {2,ch70st1}, + {2,ch70st2} +}; + +static const Fl_Glut_StrokeChar ch70 = {104.762f,3,ch70st}; + +/* char: 0x47 */ + +static const Fl_Glut_StrokeVertex ch71st0[] = +{ + {88.0952f,76.1905f}, + {83.3334f,85.7143f}, + {73.8096f,95.2381f}, + {64.2857f,100.0f}, + {45.2381f,100.0f}, + {35.7143f,95.2381f}, + {26.1905f,85.7143f}, + {21.4286f,76.1905f}, + {16.6667f,61.9048f}, + {16.6667f,38.0952f}, + {21.4286f,23.8095f}, + {26.1905f,14.2857f}, + {35.7143f,4.7619f}, + {45.2381f,0.0f}, + {64.2857f,0.0f}, + {73.8096f,4.7619f}, + {83.3334f,14.2857f}, + {88.0952f,23.8095f}, + {88.0952f,38.0952f} +}; + +static const Fl_Glut_StrokeVertex ch71st1[] = +{ + {64.2857f,38.0952f}, + {88.0952f,38.0952f} +}; + +static const Fl_Glut_StrokeStrip ch71st[] = +{ + {19,ch71st0}, + {2,ch71st1} +}; + +static const Fl_Glut_StrokeChar ch71 = {104.762f,2,ch71st}; + +/* char: 0x48 */ + +static const Fl_Glut_StrokeVertex ch72st0[] = +{ + {19.0476f,100.0f}, + {19.0476f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch72st1[] = +{ + {85.7143f,100.0f}, + {85.7143f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch72st2[] = +{ + {19.0476f,52.381f}, + {85.7143f,52.381f} +}; + +static const Fl_Glut_StrokeStrip ch72st[] = +{ + {2,ch72st0}, + {2,ch72st1}, + {2,ch72st2} +}; + +static const Fl_Glut_StrokeChar ch72 = {104.762f,3,ch72st}; + +/* char: 0x49 */ + +static const Fl_Glut_StrokeVertex ch73st0[] = +{ + {52.381f,100.0f}, + {52.381f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch73st[] = +{ + {2,ch73st0} +}; + +static const Fl_Glut_StrokeChar ch73 = {104.762f,1,ch73st}; + +/* char: 0x4a */ + +static const Fl_Glut_StrokeVertex ch74st0[] = +{ + {76.1905f,100.0f}, + {76.1905f,23.8095f}, + {71.4286f,9.5238f}, + {66.6667f,4.7619f}, + {57.1429f,0.0f}, + {47.6191f,0.0f}, + {38.0953f,4.7619f}, + {33.3334f,9.5238f}, + {28.5715f,23.8095f}, + {28.5715f,33.3333f} +}; + +static const Fl_Glut_StrokeStrip ch74st[] = +{ + {10,ch74st0} +}; + +static const Fl_Glut_StrokeChar ch74 = {104.762f,1,ch74st}; + +/* char: 0x4b */ + +static const Fl_Glut_StrokeVertex ch75st0[] = +{ + {19.0476f,100.0f}, + {19.0476f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch75st1[] = +{ + {85.7143f,100.0f}, + {19.0476f,33.3333f} +}; + +static const Fl_Glut_StrokeVertex ch75st2[] = +{ + {42.8571f,57.1429f}, + {85.7143f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch75st[] = +{ + {2,ch75st0}, + {2,ch75st1}, + {2,ch75st2} +}; + +static const Fl_Glut_StrokeChar ch75 = {104.762f,3,ch75st}; + +/* char: 0x4c */ + +static const Fl_Glut_StrokeVertex ch76st0[] = +{ + {23.8095f,100.0f}, + {23.8095f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch76st1[] = +{ + {23.8095f,0.0f}, + {80.9524f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch76st[] = +{ + {2,ch76st0}, + {2,ch76st1} +}; + +static const Fl_Glut_StrokeChar ch76 = {104.762f,2,ch76st}; + +/* char: 0x4d */ + +static const Fl_Glut_StrokeVertex ch77st0[] = +{ + {14.2857f,100.0f}, + {14.2857f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch77st1[] = +{ + {14.2857f,100.0f}, + {52.3809f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch77st2[] = +{ + {90.4762f,100.0f}, + {52.3809f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch77st3[] = +{ + {90.4762f,100.0f}, + {90.4762f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch77st[] = +{ + {2,ch77st0}, + {2,ch77st1}, + {2,ch77st2}, + {2,ch77st3} +}; + +static const Fl_Glut_StrokeChar ch77 = {104.762f,4,ch77st}; + +/* char: 0x4e */ + +static const Fl_Glut_StrokeVertex ch78st0[] = +{ + {19.0476f,100.0f}, + {19.0476f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch78st1[] = +{ + {19.0476f,100.0f}, + {85.7143f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch78st2[] = +{ + {85.7143f,100.0f}, + {85.7143f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch78st[] = +{ + {2,ch78st0}, + {2,ch78st1}, + {2,ch78st2} +}; + +static const Fl_Glut_StrokeChar ch78 = {104.762f,3,ch78st}; + +/* char: 0x4f */ + +static const Fl_Glut_StrokeVertex ch79st0[] = +{ + {42.8571f,100.0f}, + {33.3333f,95.2381f}, + {23.8095f,85.7143f}, + {19.0476f,76.1905f}, + {14.2857f,61.9048f}, + {14.2857f,38.0952f}, + {19.0476f,23.8095f}, + {23.8095f,14.2857f}, + {33.3333f,4.7619f}, + {42.8571f,0.0f}, + {61.9047f,0.0f}, + {71.4286f,4.7619f}, + {80.9524f,14.2857f}, + {85.7143f,23.8095f}, + {90.4762f,38.0952f}, + {90.4762f,61.9048f}, + {85.7143f,76.1905f}, + {80.9524f,85.7143f}, + {71.4286f,95.2381f}, + {61.9047f,100.0f}, + {42.8571f,100.0f} +}; + +static const Fl_Glut_StrokeStrip ch79st[] = +{ + {21,ch79st0} +}; + +static const Fl_Glut_StrokeChar ch79 = {104.762f,1,ch79st}; + +/* char: 0x50 */ + +static const Fl_Glut_StrokeVertex ch80st0[] = +{ + {19.0476f,100.0f}, + {19.0476f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch80st1[] = +{ + {19.0476f,100.0f}, + {61.9047f,100.0f}, + {76.1905f,95.2381f}, + {80.9524f,90.4762f}, + {85.7143f,80.9524f}, + {85.7143f,66.6667f}, + {80.9524f,57.1429f}, + {76.1905f,52.381f}, + {61.9047f,47.619f}, + {19.0476f,47.619f} +}; + +static const Fl_Glut_StrokeStrip ch80st[] = +{ + {2,ch80st0}, + {10,ch80st1} +}; + +static const Fl_Glut_StrokeChar ch80 = {104.762f,2,ch80st}; + +/* char: 0x51 */ + +static const Fl_Glut_StrokeVertex ch81st0[] = +{ + {42.8571f,100.0f}, + {33.3333f,95.2381f}, + {23.8095f,85.7143f}, + {19.0476f,76.1905f}, + {14.2857f,61.9048f}, + {14.2857f,38.0952f}, + {19.0476f,23.8095f}, + {23.8095f,14.2857f}, + {33.3333f,4.7619f}, + {42.8571f,0.0f}, + {61.9047f,0.0f}, + {71.4286f,4.7619f}, + {80.9524f,14.2857f}, + {85.7143f,23.8095f}, + {90.4762f,38.0952f}, + {90.4762f,61.9048f}, + {85.7143f,76.1905f}, + {80.9524f,85.7143f}, + {71.4286f,95.2381f}, + {61.9047f,100.0f}, + {42.8571f,100.0f} +}; + +static const Fl_Glut_StrokeVertex ch81st1[] = +{ + {57.1428f,19.0476f}, + {85.7143f,-9.5238f} +}; + +static const Fl_Glut_StrokeStrip ch81st[] = +{ + {21,ch81st0}, + {2,ch81st1} +}; + +static const Fl_Glut_StrokeChar ch81 = {104.762f,2,ch81st}; + +/* char: 0x52 */ + +static const Fl_Glut_StrokeVertex ch82st0[] = +{ + {19.0476f,100.0f}, + {19.0476f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch82st1[] = +{ + {19.0476f,100.0f}, + {61.9047f,100.0f}, + {76.1905f,95.2381f}, + {80.9524f,90.4762f}, + {85.7143f,80.9524f}, + {85.7143f,71.4286f}, + {80.9524f,61.9048f}, + {76.1905f,57.1429f}, + {61.9047f,52.381f}, + {19.0476f,52.381f} +}; + +static const Fl_Glut_StrokeVertex ch82st2[] = +{ + {52.3809f,52.381f}, + {85.7143f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch82st[] = +{ + {2,ch82st0}, + {10,ch82st1}, + {2,ch82st2} +}; + +static const Fl_Glut_StrokeChar ch82 = {104.762f,3,ch82st}; + +/* char: 0x53 */ + +static const Fl_Glut_StrokeVertex ch83st0[] = +{ + {85.7143f,85.7143f}, + {76.1905f,95.2381f}, + {61.9047f,100.0f}, + {42.8571f,100.0f}, + {28.5714f,95.2381f}, + {19.0476f,85.7143f}, + {19.0476f,76.1905f}, + {23.8095f,66.6667f}, + {28.5714f,61.9048f}, + {38.0952f,57.1429f}, + {66.6666f,47.619f}, + {76.1905f,42.8571f}, + {80.9524f,38.0952f}, + {85.7143f,28.5714f}, + {85.7143f,14.2857f}, + {76.1905f,4.7619f}, + {61.9047f,0.0f}, + {42.8571f,0.0f}, + {28.5714f,4.7619f}, + {19.0476f,14.2857f} +}; + +static const Fl_Glut_StrokeStrip ch83st[] = +{ + {20,ch83st0} +}; + +static const Fl_Glut_StrokeChar ch83 = {104.762f,1,ch83st}; + +/* char: 0x54 */ + +static const Fl_Glut_StrokeVertex ch84st0[] = +{ + {52.3809f,100.0f}, + {52.3809f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch84st1[] = +{ + {19.0476f,100.0f}, + {85.7143f,100.0f} +}; + +static const Fl_Glut_StrokeStrip ch84st[] = +{ + {2,ch84st0}, + {2,ch84st1} +}; + +static const Fl_Glut_StrokeChar ch84 = {104.762f,2,ch84st}; + +/* char: 0x55 */ + +static const Fl_Glut_StrokeVertex ch85st0[] = +{ + {19.0476f,100.0f}, + {19.0476f,28.5714f}, + {23.8095f,14.2857f}, + {33.3333f,4.7619f}, + {47.619f,0.0f}, + {57.1428f,0.0f}, + {71.4286f,4.7619f}, + {80.9524f,14.2857f}, + {85.7143f,28.5714f}, + {85.7143f,100.0f} +}; + +static const Fl_Glut_StrokeStrip ch85st[] = +{ + {10,ch85st0} +}; + +static const Fl_Glut_StrokeChar ch85 = {104.762f,1,ch85st}; + +/* char: 0x56 */ + +static const Fl_Glut_StrokeVertex ch86st0[] = +{ + {14.2857f,100.0f}, + {52.3809f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch86st1[] = +{ + {90.4762f,100.0f}, + {52.3809f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch86st[] = +{ + {2,ch86st0}, + {2,ch86st1} +}; + +static const Fl_Glut_StrokeChar ch86 = {104.762f,2,ch86st}; + +/* char: 0x57 */ + +static const Fl_Glut_StrokeVertex ch87st0[] = +{ + {4.7619f,100.0f}, + {28.5714f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch87st1[] = +{ + {52.3809f,100.0f}, + {28.5714f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch87st2[] = +{ + {52.3809f,100.0f}, + {76.1905f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch87st3[] = +{ + {100.0f,100.0f}, + {76.1905f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch87st[] = +{ + {2,ch87st0}, + {2,ch87st1}, + {2,ch87st2}, + {2,ch87st3} +}; + +static const Fl_Glut_StrokeChar ch87 = {104.762f,4,ch87st}; + +/* char: 0x58 */ + +static const Fl_Glut_StrokeVertex ch88st0[] = +{ + {19.0476f,100.0f}, + {85.7143f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch88st1[] = +{ + {85.7143f,100.0f}, + {19.0476f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch88st[] = +{ + {2,ch88st0}, + {2,ch88st1} +}; + +static const Fl_Glut_StrokeChar ch88 = {104.762f,2,ch88st}; + +/* char: 0x59 */ + +static const Fl_Glut_StrokeVertex ch89st0[] = +{ + {14.2857f,100.0f}, + {52.3809f,52.381f}, + {52.3809f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch89st1[] = +{ + {90.4762f,100.0f}, + {52.3809f,52.381f} +}; + +static const Fl_Glut_StrokeStrip ch89st[] = +{ + {3,ch89st0}, + {2,ch89st1} +}; + +static const Fl_Glut_StrokeChar ch89 = {104.762f,2,ch89st}; + +/* char: 0x5a */ + +static const Fl_Glut_StrokeVertex ch90st0[] = +{ + {85.7143f,100.0f}, + {19.0476f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch90st1[] = +{ + {19.0476f,100.0f}, + {85.7143f,100.0f} +}; + +static const Fl_Glut_StrokeVertex ch90st2[] = +{ + {19.0476f,0.0f}, + {85.7143f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch90st[] = +{ + {2,ch90st0}, + {2,ch90st1}, + {2,ch90st2} +}; + +static const Fl_Glut_StrokeChar ch90 = {104.762f,3,ch90st}; + +/* char: 0x5b */ + +static const Fl_Glut_StrokeVertex ch91st0[] = +{ + {35.7143f,119.048f}, + {35.7143f,-33.3333f} +}; + +static const Fl_Glut_StrokeVertex ch91st1[] = +{ + {40.4762f,119.048f}, + {40.4762f,-33.3333f} +}; + +static const Fl_Glut_StrokeVertex ch91st2[] = +{ + {35.7143f,119.048f}, + {69.0476f,119.048f} +}; + +static const Fl_Glut_StrokeVertex ch91st3[] = +{ + {35.7143f,-33.3333f}, + {69.0476f,-33.3333f} +}; + +static const Fl_Glut_StrokeStrip ch91st[] = +{ + {2,ch91st0}, + {2,ch91st1}, + {2,ch91st2}, + {2,ch91st3} +}; + +static const Fl_Glut_StrokeChar ch91 = {104.762f,4,ch91st}; + +/* char: 0x5c */ + +static const Fl_Glut_StrokeVertex ch92st0[] = +{ + {19.0476f,100.0f}, + {85.7143f,-14.2857f} +}; + +static const Fl_Glut_StrokeStrip ch92st[] = +{ + {2,ch92st0} +}; + +static const Fl_Glut_StrokeChar ch92 = {104.762f,1,ch92st}; + +/* char: 0x5d */ + +static const Fl_Glut_StrokeVertex ch93st0[] = +{ + {64.2857f,119.048f}, + {64.2857f,-33.3333f} +}; + +static const Fl_Glut_StrokeVertex ch93st1[] = +{ + {69.0476f,119.048f}, + {69.0476f,-33.3333f} +}; + +static const Fl_Glut_StrokeVertex ch93st2[] = +{ + {35.7143f,119.048f}, + {69.0476f,119.048f} +}; + +static const Fl_Glut_StrokeVertex ch93st3[] = +{ + {35.7143f,-33.3333f}, + {69.0476f,-33.3333f} +}; + +static const Fl_Glut_StrokeStrip ch93st[] = +{ + {2,ch93st0}, + {2,ch93st1}, + {2,ch93st2}, + {2,ch93st3} +}; + +static const Fl_Glut_StrokeChar ch93 = {104.762f,4,ch93st}; + +/* char: 0x5e */ + +static const Fl_Glut_StrokeVertex ch94st0[] = +{ + {52.3809f,109.524f}, + {14.2857f,42.8571f} +}; + +static const Fl_Glut_StrokeVertex ch94st1[] = +{ + {52.3809f,109.524f}, + {90.4762f,42.8571f} +}; + +static const Fl_Glut_StrokeStrip ch94st[] = +{ + {2,ch94st0}, + {2,ch94st1} +}; + +static const Fl_Glut_StrokeChar ch94 = {104.762f,2,ch94st}; + +/* char: 0x5f */ + +static const Fl_Glut_StrokeVertex ch95st0[] = +{ + {0,-33.3333f}, + {104.762f,-33.3333f}, + {104.762f,-28.5714f}, + {0,-28.5714f}, + {0,-33.3333f} +}; + +static const Fl_Glut_StrokeStrip ch95st[] = +{ + {5,ch95st0} +}; + +static const Fl_Glut_StrokeChar ch95 = {104.762f,1,ch95st}; + +/* char: 0x60 */ + +static const Fl_Glut_StrokeVertex ch96st0[] = +{ + {42.8572f,100.0f}, + {66.6667f,71.4286f} +}; + +static const Fl_Glut_StrokeVertex ch96st1[] = +{ + {42.8572f,100.0f}, + {38.0953f,95.2381f}, + {66.6667f,71.4286f} +}; + +static const Fl_Glut_StrokeStrip ch96st[] = +{ + {2,ch96st0}, + {3,ch96st1} +}; + +static const Fl_Glut_StrokeChar ch96 = {104.762f,2,ch96st}; + +/* char: 0x61 */ + +static const Fl_Glut_StrokeVertex ch97st0[] = +{ + {80.9524f,66.6667f}, + {80.9524f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch97st1[] = +{ + {80.9524f,52.381f}, + {71.4285f,61.9048f}, + {61.9047f,66.6667f}, + {47.619f,66.6667f}, + {38.0952f,61.9048f}, + {28.5714f,52.381f}, + {23.8095f,38.0952f}, + {23.8095f,28.5714f}, + {28.5714f,14.2857f}, + {38.0952f,4.7619f}, + {47.619f,0.0f}, + {61.9047f,0.0f}, + {71.4285f,4.7619f}, + {80.9524f,14.2857f} +}; + +static const Fl_Glut_StrokeStrip ch97st[] = +{ + {2,ch97st0}, + {14,ch97st1} +}; + +static const Fl_Glut_StrokeChar ch97 = {104.762f,2,ch97st}; + +/* char: 0x62 */ + +static const Fl_Glut_StrokeVertex ch98st0[] = +{ + {23.8095f,100.0f}, + {23.8095f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch98st1[] = +{ + {23.8095f,52.381f}, + {33.3333f,61.9048f}, + {42.8571f,66.6667f}, + {57.1428f,66.6667f}, + {66.6666f,61.9048f}, + {76.1905f,52.381f}, + {80.9524f,38.0952f}, + {80.9524f,28.5714f}, + {76.1905f,14.2857f}, + {66.6666f,4.7619f}, + {57.1428f,0.0f}, + {42.8571f,0.0f}, + {33.3333f,4.7619f}, + {23.8095f,14.2857f} +}; + +static const Fl_Glut_StrokeStrip ch98st[] = +{ + {2,ch98st0}, + {14,ch98st1} +}; + +static const Fl_Glut_StrokeChar ch98 = {104.762f,2,ch98st}; + +/* char: 0x63 */ + +static const Fl_Glut_StrokeVertex ch99st0[] = +{ + {80.9524f,52.381f}, + {71.4285f,61.9048f}, + {61.9047f,66.6667f}, + {47.619f,66.6667f}, + {38.0952f,61.9048f}, + {28.5714f,52.381f}, + {23.8095f,38.0952f}, + {23.8095f,28.5714f}, + {28.5714f,14.2857f}, + {38.0952f,4.7619f}, + {47.619f,0.0f}, + {61.9047f,0.0f}, + {71.4285f,4.7619f}, + {80.9524f,14.2857f} +}; + +static const Fl_Glut_StrokeStrip ch99st[] = +{ + {14,ch99st0} +}; + +static const Fl_Glut_StrokeChar ch99 = {104.762f,1,ch99st}; + +/* char: 0x64 */ + +static const Fl_Glut_StrokeVertex ch100st0[] = +{ + {80.9524f,100.0f}, + {80.9524f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch100st1[] = +{ + {80.9524f,52.381f}, + {71.4285f,61.9048f}, + {61.9047f,66.6667f}, + {47.619f,66.6667f}, + {38.0952f,61.9048f}, + {28.5714f,52.381f}, + {23.8095f,38.0952f}, + {23.8095f,28.5714f}, + {28.5714f,14.2857f}, + {38.0952f,4.7619f}, + {47.619f,0.0f}, + {61.9047f,0.0f}, + {71.4285f,4.7619f}, + {80.9524f,14.2857f} +}; + +static const Fl_Glut_StrokeStrip ch100st[] = +{ + {2,ch100st0}, + {14,ch100st1} +}; + +static const Fl_Glut_StrokeChar ch100 = {104.762f,2,ch100st}; + +/* char: 0x65 */ + +static const Fl_Glut_StrokeVertex ch101st0[] = +{ + {23.8095f,38.0952f}, + {80.9524f,38.0952f}, + {80.9524f,47.619f}, + {76.1905f,57.1429f}, + {71.4285f,61.9048f}, + {61.9047f,66.6667f}, + {47.619f,66.6667f}, + {38.0952f,61.9048f}, + {28.5714f,52.381f}, + {23.8095f,38.0952f}, + {23.8095f,28.5714f}, + {28.5714f,14.2857f}, + {38.0952f,4.7619f}, + {47.619f,0.0f}, + {61.9047f,0.0f}, + {71.4285f,4.7619f}, + {80.9524f,14.2857f} +}; + +static const Fl_Glut_StrokeStrip ch101st[] = +{ + {17,ch101st0} +}; + +static const Fl_Glut_StrokeChar ch101 = {104.762f,1,ch101st}; + +/* char: 0x66 */ + +static const Fl_Glut_StrokeVertex ch102st0[] = +{ + {71.4286f,100.0f}, + {61.9048f,100.0f}, + {52.381f,95.2381f}, + {47.6191f,80.9524f}, + {47.6191f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch102st1[] = +{ + {33.3334f,66.6667f}, + {66.6667f,66.6667f} +}; + +static const Fl_Glut_StrokeStrip ch102st[] = +{ + {5,ch102st0}, + {2,ch102st1} +}; + +static const Fl_Glut_StrokeChar ch102 = {104.762f,2,ch102st}; + +/* char: 0x67 */ + +static const Fl_Glut_StrokeVertex ch103st0[] = +{ + {80.9524f,66.6667f}, + {80.9524f,-9.5238f}, + {76.1905f,-23.8095f}, + {71.4285f,-28.5714f}, + {61.9047f,-33.3333f}, + {47.619f,-33.3333f}, + {38.0952f,-28.5714f} +}; + +static const Fl_Glut_StrokeVertex ch103st1[] = +{ + {80.9524f,52.381f}, + {71.4285f,61.9048f}, + {61.9047f,66.6667f}, + {47.619f,66.6667f}, + {38.0952f,61.9048f}, + {28.5714f,52.381f}, + {23.8095f,38.0952f}, + {23.8095f,28.5714f}, + {28.5714f,14.2857f}, + {38.0952f,4.7619f}, + {47.619f,0.0f}, + {61.9047f,0.0f}, + {71.4285f,4.7619f}, + {80.9524f,14.2857f} +}; + +static const Fl_Glut_StrokeStrip ch103st[] = +{ + {7,ch103st0}, + {14,ch103st1} +}; + +static const Fl_Glut_StrokeChar ch103 = {104.762f,2,ch103st}; + +/* char: 0x68 */ + +static const Fl_Glut_StrokeVertex ch104st0[] = +{ + {26.1905f,100.0f}, + {26.1905f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch104st1[] = +{ + {26.1905f,47.619f}, + {40.4762f,61.9048f}, + {50.0f,66.6667f}, + {64.2857f,66.6667f}, + {73.8095f,61.9048f}, + {78.5715f,47.619f}, + {78.5715f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch104st[] = +{ + {2,ch104st0}, + {7,ch104st1} +}; + +static const Fl_Glut_StrokeChar ch104 = {104.762f,2,ch104st}; + +/* char: 0x69 */ + +static const Fl_Glut_StrokeVertex ch105st0[] = +{ + {47.6191f,100.0f}, + {52.381f,95.2381f}, + {57.1429f,100.0f}, + {52.381f,104.762f}, + {47.6191f,100.0f} +}; + +static const Fl_Glut_StrokeVertex ch105st1[] = +{ + {52.381f,66.6667f}, + {52.381f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch105st[] = +{ + {5,ch105st0}, + {2,ch105st1} +}; + +static const Fl_Glut_StrokeChar ch105 = {104.762f,2,ch105st}; + +/* char: 0x6a */ + +static const Fl_Glut_StrokeVertex ch106st0[] = +{ + {57.1429f,100.0f}, + {61.9048f,95.2381f}, + {66.6667f,100.0f}, + {61.9048f,104.762f}, + {57.1429f,100.0f} +}; + +static const Fl_Glut_StrokeVertex ch106st1[] = +{ + {61.9048f,66.6667f}, + {61.9048f,-14.2857f}, + {57.1429f,-28.5714f}, + {47.6191f,-33.3333f}, + {38.0953f,-33.3333f} +}; + +static const Fl_Glut_StrokeStrip ch106st[] = +{ + {5,ch106st0}, + {5,ch106st1} +}; + +static const Fl_Glut_StrokeChar ch106 = {104.762f,2,ch106st}; + +/* char: 0x6b */ + +static const Fl_Glut_StrokeVertex ch107st0[] = +{ + {26.1905f,100.0f}, + {26.1905f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch107st1[] = +{ + {73.8095f,66.6667f}, + {26.1905f,19.0476f} +}; + +static const Fl_Glut_StrokeVertex ch107st2[] = +{ + {45.2381f,38.0952f}, + {78.5715f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch107st[] = +{ + {2,ch107st0}, + {2,ch107st1}, + {2,ch107st2} +}; + +static const Fl_Glut_StrokeChar ch107 = {104.762f,3,ch107st}; + +/* char: 0x6c */ + +static const Fl_Glut_StrokeVertex ch108st0[] = +{ + {52.381f,100.0f}, + {52.381f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch108st[] = +{ + {2,ch108st0} +}; + +static const Fl_Glut_StrokeChar ch108 = {104.762f,1,ch108st}; + +/* char: 0x6d */ + +static const Fl_Glut_StrokeVertex ch109st0[] = +{ + {0,66.6667f}, + {0,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch109st1[] = +{ + {0,47.619f}, + {14.2857f,61.9048f}, + {23.8095f,66.6667f}, + {38.0952f,66.6667f}, + {47.619f,61.9048f}, + {52.381f,47.619f}, + {52.381f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch109st2[] = +{ + {52.381f,47.619f}, + {66.6667f,61.9048f}, + {76.1905f,66.6667f}, + {90.4762f,66.6667f}, + {100.0f,61.9048f}, + {104.762f,47.619f}, + {104.762f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch109st[] = +{ + {2,ch109st0}, + {7,ch109st1}, + {7,ch109st2} +}; + +static const Fl_Glut_StrokeChar ch109 = {104.762f,3,ch109st}; + +/* char: 0x6e */ + +static const Fl_Glut_StrokeVertex ch110st0[] = +{ + {26.1905f,66.6667f}, + {26.1905f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch110st1[] = +{ + {26.1905f,47.619f}, + {40.4762f,61.9048f}, + {50.0f,66.6667f}, + {64.2857f,66.6667f}, + {73.8095f,61.9048f}, + {78.5715f,47.619f}, + {78.5715f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch110st[] = +{ + {2,ch110st0}, + {7,ch110st1} +}; + +static const Fl_Glut_StrokeChar ch110 = {104.762f,2,ch110st}; + +/* char: 0x6f */ + +static const Fl_Glut_StrokeVertex ch111st0[] = +{ + {45.2381f,66.6667f}, + {35.7143f,61.9048f}, + {26.1905f,52.381f}, + {21.4286f,38.0952f}, + {21.4286f,28.5714f}, + {26.1905f,14.2857f}, + {35.7143f,4.7619f}, + {45.2381f,0.0f}, + {59.5238f,0.0f}, + {69.0476f,4.7619f}, + {78.5714f,14.2857f}, + {83.3334f,28.5714f}, + {83.3334f,38.0952f}, + {78.5714f,52.381f}, + {69.0476f,61.9048f}, + {59.5238f,66.6667f}, + {45.2381f,66.6667f} +}; + +static const Fl_Glut_StrokeStrip ch111st[] = +{ + {17,ch111st0} +}; + +static const Fl_Glut_StrokeChar ch111 = {104.762f,1,ch111st}; + +/* char: 0x70 */ + +static const Fl_Glut_StrokeVertex ch112st0[] = +{ + {23.8095f,66.6667f}, + {23.8095f,-33.3333f} +}; + +static const Fl_Glut_StrokeVertex ch112st1[] = +{ + {23.8095f,52.381f}, + {33.3333f,61.9048f}, + {42.8571f,66.6667f}, + {57.1428f,66.6667f}, + {66.6666f,61.9048f}, + {76.1905f,52.381f}, + {80.9524f,38.0952f}, + {80.9524f,28.5714f}, + {76.1905f,14.2857f}, + {66.6666f,4.7619f}, + {57.1428f,0.0f}, + {42.8571f,0.0f}, + {33.3333f,4.7619f}, + {23.8095f,14.2857f} +}; + +static const Fl_Glut_StrokeStrip ch112st[] = +{ + {2,ch112st0}, + {14,ch112st1} +}; + +static const Fl_Glut_StrokeChar ch112 = {104.762f,2,ch112st}; + +/* char: 0x71 */ + +static const Fl_Glut_StrokeVertex ch113st0[] = +{ + {80.9524f,66.6667f}, + {80.9524f,-33.3333f} +}; + +static const Fl_Glut_StrokeVertex ch113st1[] = +{ + {80.9524f,52.381f}, + {71.4285f,61.9048f}, + {61.9047f,66.6667f}, + {47.619f,66.6667f}, + {38.0952f,61.9048f}, + {28.5714f,52.381f}, + {23.8095f,38.0952f}, + {23.8095f,28.5714f}, + {28.5714f,14.2857f}, + {38.0952f,4.7619f}, + {47.619f,0.0f}, + {61.9047f,0.0f}, + {71.4285f,4.7619f}, + {80.9524f,14.2857f} +}; + +static const Fl_Glut_StrokeStrip ch113st[] = +{ + {2,ch113st0}, + {14,ch113st1} +}; + +static const Fl_Glut_StrokeChar ch113 = {104.762f,2,ch113st}; + +/* char: 0x72 */ + +static const Fl_Glut_StrokeVertex ch114st0[] = +{ + {33.3334f,66.6667f}, + {33.3334f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch114st1[] = +{ + {33.3334f,38.0952f}, + {38.0953f,52.381f}, + {47.6191f,61.9048f}, + {57.1429f,66.6667f}, + {71.4286f,66.6667f} +}; + +static const Fl_Glut_StrokeStrip ch114st[] = +{ + {2,ch114st0}, + {5,ch114st1} +}; + +static const Fl_Glut_StrokeChar ch114 = {104.762f,2,ch114st}; + +/* char: 0x73 */ + +static const Fl_Glut_StrokeVertex ch115st0[] = +{ + {78.5715f,52.381f}, + {73.8095f,61.9048f}, + {59.5238f,66.6667f}, + {45.2381f,66.6667f}, + {30.9524f,61.9048f}, + {26.1905f,52.381f}, + {30.9524f,42.8571f}, + {40.4762f,38.0952f}, + {64.2857f,33.3333f}, + {73.8095f,28.5714f}, + {78.5715f,19.0476f}, + {78.5715f,14.2857f}, + {73.8095f,4.7619f}, + {59.5238f,0.0f}, + {45.2381f,0.0f}, + {30.9524f,4.7619f}, + {26.1905f,14.2857f} +}; + +static const Fl_Glut_StrokeStrip ch115st[] = +{ + {17,ch115st0} +}; + +static const Fl_Glut_StrokeChar ch115 = {104.762f,1,ch115st}; + +/* char: 0x74 */ + +static const Fl_Glut_StrokeVertex ch116st0[] = +{ + {47.6191f,100.0f}, + {47.6191f,19.0476f}, + {52.381f,4.7619f}, + {61.9048f,0.0f}, + {71.4286f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch116st1[] = +{ + {33.3334f,66.6667f}, + {66.6667f,66.6667f} +}; + +static const Fl_Glut_StrokeStrip ch116st[] = +{ + {5,ch116st0}, + {2,ch116st1} +}; + +static const Fl_Glut_StrokeChar ch116 = {104.762f,2,ch116st}; + +/* char: 0x75 */ + +static const Fl_Glut_StrokeVertex ch117st0[] = +{ + {26.1905f,66.6667f}, + {26.1905f,19.0476f}, + {30.9524f,4.7619f}, + {40.4762f,0.0f}, + {54.7619f,0.0f}, + {64.2857f,4.7619f}, + {78.5715f,19.0476f} +}; + +static const Fl_Glut_StrokeVertex ch117st1[] = +{ + {78.5715f,66.6667f}, + {78.5715f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch117st[] = +{ + {7,ch117st0}, + {2,ch117st1} +}; + +static const Fl_Glut_StrokeChar ch117 = {104.762f,2,ch117st}; + +/* char: 0x76 */ + +static const Fl_Glut_StrokeVertex ch118st0[] = +{ + {23.8095f,66.6667f}, + {52.3809f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch118st1[] = +{ + {80.9524f,66.6667f}, + {52.3809f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch118st[] = +{ + {2,ch118st0}, + {2,ch118st1} +}; + +static const Fl_Glut_StrokeChar ch118 = {104.762f,2,ch118st}; + +/* char: 0x77 */ + +static const Fl_Glut_StrokeVertex ch119st0[] = +{ + {14.2857f,66.6667f}, + {33.3333f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch119st1[] = +{ + {52.3809f,66.6667f}, + {33.3333f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch119st2[] = +{ + {52.3809f,66.6667f}, + {71.4286f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch119st3[] = +{ + {90.4762f,66.6667f}, + {71.4286f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch119st[] = +{ + {2,ch119st0}, + {2,ch119st1}, + {2,ch119st2}, + {2,ch119st3} +}; + +static const Fl_Glut_StrokeChar ch119 = {104.762f,4,ch119st}; + +/* char: 0x78 */ + +static const Fl_Glut_StrokeVertex ch120st0[] = +{ + {26.1905f,66.6667f}, + {78.5715f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch120st1[] = +{ + {78.5715f,66.6667f}, + {26.1905f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch120st[] = +{ + {2,ch120st0}, + {2,ch120st1} +}; + +static const Fl_Glut_StrokeChar ch120 = {104.762f,2,ch120st}; + +/* char: 0x79 */ + +static const Fl_Glut_StrokeVertex ch121st0[] = +{ + {26.1905f,66.6667f}, + {54.7619f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch121st1[] = +{ + {83.3334f,66.6667f}, + {54.7619f,0.0f}, + {45.2381f,-19.0476f}, + {35.7143f,-28.5714f}, + {26.1905f,-33.3333f}, + {21.4286f,-33.3333f} +}; + +static const Fl_Glut_StrokeStrip ch121st[] = +{ + {2,ch121st0}, + {6,ch121st1} +}; + +static const Fl_Glut_StrokeChar ch121 = {104.762f,2,ch121st}; + +/* char: 0x7a */ + +static const Fl_Glut_StrokeVertex ch122st0[] = +{ + {78.5715f,66.6667f}, + {26.1905f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch122st1[] = +{ + {26.1905f,66.6667f}, + {78.5715f,66.6667f} +}; + +static const Fl_Glut_StrokeVertex ch122st2[] = +{ + {26.1905f,0.0f}, + {78.5715f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch122st[] = +{ + {2,ch122st0}, + {2,ch122st1}, + {2,ch122st2} +}; + +static const Fl_Glut_StrokeChar ch122 = {104.762f,3,ch122st}; + +/* char: 0x7b */ + +static const Fl_Glut_StrokeVertex ch123st0[] = +{ + {64.2857f,119.048f}, + {54.7619f,114.286f}, + {50.0f,109.524f}, + {45.2381f,100.0f}, + {45.2381f,90.4762f}, + {50.0f,80.9524f}, + {54.7619f,76.1905f}, + {59.5238f,66.6667f}, + {59.5238f,57.1429f}, + {50.0f,47.619f} +}; + +static const Fl_Glut_StrokeVertex ch123st1[] = +{ + {54.7619f,114.286f}, + {50.0f,104.762f}, + {50.0f,95.2381f}, + {54.7619f,85.7143f}, + {59.5238f,80.9524f}, + {64.2857f,71.4286f}, + {64.2857f,61.9048f}, + {59.5238f,52.381f}, + {40.4762f,42.8571f}, + {59.5238f,33.3333f}, + {64.2857f,23.8095f}, + {64.2857f,14.2857f}, + {59.5238f,4.7619f}, + {54.7619f,0.0f}, + {50.0f,-9.5238f}, + {50.0f,-19.0476f}, + {54.7619f,-28.5714f} +}; + +static const Fl_Glut_StrokeVertex ch123st2[] = +{ + {50.0f,38.0952f}, + {59.5238f,28.5714f}, + {59.5238f,19.0476f}, + {54.7619f,9.5238f}, + {50.0f,4.7619f}, + {45.2381f,-4.7619f}, + {45.2381f,-14.2857f}, + {50.0f,-23.8095f}, + {54.7619f,-28.5714f}, + {64.2857f,-33.3333f} +}; + +static const Fl_Glut_StrokeStrip ch123st[] = +{ + {10,ch123st0}, + {17,ch123st1}, + {10,ch123st2} +}; + +static const Fl_Glut_StrokeChar ch123 = {104.762f,3,ch123st}; + +/* char: 0x7c */ + +static const Fl_Glut_StrokeVertex ch124st0[] = +{ + {52.381f,119.048f}, + {52.381f,-33.3333f} +}; + +static const Fl_Glut_StrokeStrip ch124st[] = +{ + {2,ch124st0} +}; + +static const Fl_Glut_StrokeChar ch124 = {104.762f,1,ch124st}; + +/* char: 0x7d */ + +static const Fl_Glut_StrokeVertex ch125st0[] = +{ + {40.4762f,119.048f}, + {50.0f,114.286f}, + {54.7619f,109.524f}, + {59.5238f,100.0f}, + {59.5238f,90.4762f}, + {54.7619f,80.9524f}, + {50.0f,76.1905f}, + {45.2381f,66.6667f}, + {45.2381f,57.1429f}, + {54.7619f,47.619f} +}; + +static const Fl_Glut_StrokeVertex ch125st1[] = +{ + {50.0f,114.286f}, + {54.7619f,104.762f}, + {54.7619f,95.2381f}, + {50.0f,85.7143f}, + {45.2381f,80.9524f}, + {40.4762f,71.4286f}, + {40.4762f,61.9048f}, + {45.2381f,52.381f}, + {64.2857f,42.8571f}, + {45.2381f,33.3333f}, + {40.4762f,23.8095f}, + {40.4762f,14.2857f}, + {45.2381f,4.7619f}, + {50.0f,0.0f}, + {54.7619f,-9.5238f}, + {54.7619f,-19.0476f}, + {50.0f,-28.5714f} +}; + +static const Fl_Glut_StrokeVertex ch125st2[] = +{ + {54.7619f,38.0952f}, + {45.2381f,28.5714f}, + {45.2381f,19.0476f}, + {50.0f,9.5238f}, + {54.7619f,4.7619f}, + {59.5238f,-4.7619f}, + {59.5238f,-14.2857f}, + {54.7619f,-23.8095f}, + {50.0f,-28.5714f}, + {40.4762f,-33.3333f} +}; + +static const Fl_Glut_StrokeStrip ch125st[] = +{ + {10,ch125st0}, + {17,ch125st1}, + {10,ch125st2} +}; + +static const Fl_Glut_StrokeChar ch125 = {104.762f,3,ch125st}; + +/* char: 0x7e */ + +static const Fl_Glut_StrokeVertex ch126st0[] = +{ + {9.5238f,28.5714f}, + {9.5238f,38.0952f}, + {14.2857f,52.381f}, + {23.8095f,57.1429f}, + {33.3333f,57.1429f}, + {42.8571f,52.381f}, + {61.9048f,38.0952f}, + {71.4286f,33.3333f}, + {80.9524f,33.3333f}, + {90.4762f,38.0952f}, + {95.2381f,47.619f} +}; + +static const Fl_Glut_StrokeVertex ch126st1[] = +{ + {9.5238f,38.0952f}, + {14.2857f,47.619f}, + {23.8095f,52.381f}, + {33.3333f,52.381f}, + {42.8571f,47.619f}, + {61.9048f,33.3333f}, + {71.4286f,28.5714f}, + {80.9524f,28.5714f}, + {90.4762f,33.3333f}, + {95.2381f,47.619f}, + {95.2381f,57.1429f} +}; + +static const Fl_Glut_StrokeStrip ch126st[] = +{ + {11,ch126st0}, + {11,ch126st1} +}; + +static const Fl_Glut_StrokeChar ch126 = {104.762f,2,ch126st}; + +/* char: 0x7f */ + +static const Fl_Glut_StrokeVertex ch127st0[] = +{ + {71.4286f,100.0f}, + {33.3333f,-33.3333f} +}; + +static const Fl_Glut_StrokeVertex ch127st1[] = +{ + {47.619f,66.6667f}, + {33.3333f,61.9048f}, + {23.8095f,52.381f}, + {19.0476f,38.0952f}, + {19.0476f,23.8095f}, + {23.8095f,14.2857f}, + {33.3333f,4.7619f}, + {47.619f,0.0f}, + {57.1428f,0.0f}, + {71.4286f,4.7619f}, + {80.9524f,14.2857f}, + {85.7143f,28.5714f}, + {85.7143f,42.8571f}, + {80.9524f,52.381f}, + {71.4286f,61.9048f}, + {57.1428f,66.6667f}, + {47.619f,66.6667f} +}; + +static const Fl_Glut_StrokeStrip ch127st[] = +{ + {2,ch127st0}, + {17,ch127st1} +}; + +static const Fl_Glut_StrokeChar ch127 = {104.762f,2,ch127st}; + +static const Fl_Glut_StrokeChar *chars[] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + &ch32, &ch33, &ch34, &ch35, &ch36, &ch37, &ch38, &ch39, + &ch40, &ch41, &ch42, &ch43, &ch44, &ch45, &ch46, &ch47, + &ch48, &ch49, &ch50, &ch51, &ch52, &ch53, &ch54, &ch55, + &ch56, &ch57, &ch58, &ch59, &ch60, &ch61, &ch62, &ch63, + &ch64, &ch65, &ch66, &ch67, &ch68, &ch69, &ch70, &ch71, + &ch72, &ch73, &ch74, &ch75, &ch76, &ch77, &ch78, &ch79, + &ch80, &ch81, &ch82, &ch83, &ch84, &ch85, &ch86, &ch87, + &ch88, &ch89, &ch90, &ch91, &ch92, &ch93, &ch94, &ch95, + &ch96, &ch97, &ch98, &ch99, &ch100, &ch101, &ch102, &ch103, + &ch104, &ch105, &ch106, &ch107, &ch108, &ch109, &ch110, &ch111, + &ch112, &ch113, &ch114, &ch115, &ch116, &ch117, &ch118, &ch119, + &ch120, &ch121, &ch122, &ch123, &ch124, &ch125, &ch126, &ch127 +}; + +Fl_Glut_StrokeFont glutStrokeMonoRoman = {(char *)"MonoRoman",128,152.381f,chars}; diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/freeglut_stroke_roman.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/freeglut_stroke_roman.cxx new file mode 100644 index 0000000..deda2d0 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/freeglut_stroke_roman.cxx @@ -0,0 +1,2848 @@ +/* + * freeglut_stroke_roman.c + * + * freeglut Roman stroke font definition + * + * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved. + * Written by Pawel W. Olszta, + * Creation date: Thu Dec 16 1999 + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +/* This file has been automatically generated by the genstroke utility. */ + +#include + +/* char: 0x20 */ + +static const Fl_Glut_StrokeStrip ch32st[] = +{ + { 0, 0 } +}; + +static const Fl_Glut_StrokeChar ch32 = {104.762f,0,ch32st}; + +/* char: 0x21 */ + +static const Fl_Glut_StrokeVertex ch33st0[] = +{ + {13.3819f,100.0f}, + {13.3819f,33.3333f} +}; + +static const Fl_Glut_StrokeVertex ch33st1[] = +{ + {13.3819f,9.5238f}, + {8.62f,4.7619f}, + {13.3819f,0.0f}, + {18.1438f,4.7619f}, + {13.3819f,9.5238f} +}; + +static const Fl_Glut_StrokeStrip ch33st[] = +{ + {2,ch33st0}, + {5,ch33st1} +}; + +static const Fl_Glut_StrokeChar ch33 = {26.6238f,2,ch33st}; + +/* char: 0x22 */ + +static const Fl_Glut_StrokeVertex ch34st0[] = +{ + {4.02f,100.0f}, + {4.02f,66.6667f} +}; + +static const Fl_Glut_StrokeVertex ch34st1[] = +{ + {42.1152f,100.0f}, + {42.1152f,66.6667f} +}; + +static const Fl_Glut_StrokeStrip ch34st[] = +{ + {2,ch34st0}, + {2,ch34st1} +}; + +static const Fl_Glut_StrokeChar ch34 = {51.4352f,2,ch34st}; + +/* char: 0x23 */ + +static const Fl_Glut_StrokeVertex ch35st0[] = +{ + {41.2952f,119.048f}, + {7.9619f,-33.3333f} +}; + +static const Fl_Glut_StrokeVertex ch35st1[] = +{ + {69.8667f,119.048f}, + {36.5333f,-33.3333f} +}; + +static const Fl_Glut_StrokeVertex ch35st2[] = +{ + {7.9619f,57.1429f}, + {74.6286f,57.1429f} +}; + +static const Fl_Glut_StrokeVertex ch35st3[] = +{ + {3.2f,28.5714f}, + {69.8667f,28.5714f} +}; + +static const Fl_Glut_StrokeStrip ch35st[] = +{ + {2,ch35st0}, + {2,ch35st1}, + {2,ch35st2}, + {2,ch35st3} +}; + +static const Fl_Glut_StrokeChar ch35 = {79.4886f,4,ch35st}; + +/* char: 0x24 */ + +static const Fl_Glut_StrokeVertex ch36st0[] = +{ + {28.6295f,119.048f}, + {28.6295f,-19.0476f} +}; + +static const Fl_Glut_StrokeVertex ch36st1[] = +{ + {47.6771f,119.048f}, + {47.6771f,-19.0476f} +}; + +static const Fl_Glut_StrokeVertex ch36st2[] = +{ + {71.4867f,85.7143f}, + {61.9629f,95.2381f}, + {47.6771f,100.0f}, + {28.6295f,100.0f}, + {14.3438f,95.2381f}, + {4.82f,85.7143f}, + {4.82f,76.1905f}, + {9.5819f,66.6667f}, + {14.3438f,61.9048f}, + {23.8676f,57.1429f}, + {52.439f,47.619f}, + {61.9629f,42.8571f}, + {66.7248f,38.0952f}, + {71.4867f,28.5714f}, + {71.4867f,14.2857f}, + {61.9629f,4.7619f}, + {47.6771f,0.0f}, + {28.6295f,0.0f}, + {14.3438f,4.7619f}, + {4.82f,14.2857f} +}; + +static const Fl_Glut_StrokeStrip ch36st[] = +{ + {2,ch36st0}, + {2,ch36st1}, + {20,ch36st2} +}; + +static const Fl_Glut_StrokeChar ch36 = {76.2067f,3,ch36st}; + +/* char: 0x25 */ + +static const Fl_Glut_StrokeVertex ch37st0[] = +{ + {92.0743f,100.0f}, + {6.36f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch37st1[] = +{ + {30.1695f,100.0f}, + {39.6933f,90.4762f}, + {39.6933f,80.9524f}, + {34.9314f,71.4286f}, + {25.4076f,66.6667f}, + {15.8838f,66.6667f}, + {6.36f,76.1905f}, + {6.36f,85.7143f}, + {11.1219f,95.2381f}, + {20.6457f,100.0f}, + {30.1695f,100.0f}, + {39.6933f,95.2381f}, + {53.979f,90.4762f}, + {68.2648f,90.4762f}, + {82.5505f,95.2381f}, + {92.0743f,100.0f} +}; + +static const Fl_Glut_StrokeVertex ch37st2[] = +{ + {73.0267f,33.3333f}, + {63.5029f,28.5714f}, + {58.741f,19.0476f}, + {58.741f,9.5238f}, + {68.2648f,0.0f}, + {77.7886f,0.0f}, + {87.3124f,4.7619f}, + {92.0743f,14.2857f}, + {92.0743f,23.8095f}, + {82.5505f,33.3333f}, + {73.0267f,33.3333f} +}; + +static const Fl_Glut_StrokeStrip ch37st[] = +{ + {2,ch37st0}, + {16,ch37st1}, + {11,ch37st2} +}; + +static const Fl_Glut_StrokeChar ch37 = {96.5743f,3,ch37st}; + +/* char: 0x26 */ + +static const Fl_Glut_StrokeVertex ch38st0[] = +{ + {101.218f,57.1429f}, + {101.218f,61.9048f}, + {96.4562f,66.6667f}, + {91.6943f,66.6667f}, + {86.9324f,61.9048f}, + {82.1705f,52.381f}, + {72.6467f,28.5714f}, + {63.1229f,14.2857f}, + {53.599f,4.7619f}, + {44.0752f,0.0f}, + {25.0276f,0.0f}, + {15.5038f,4.7619f}, + {10.7419f,9.5238f}, + {5.98f,19.0476f}, + {5.98f,28.5714f}, + {10.7419f,38.0952f}, + {15.5038f,42.8571f}, + {48.8371f,61.9048f}, + {53.599f,66.6667f}, + {58.361f,76.1905f}, + {58.361f,85.7143f}, + {53.599f,95.2381f}, + {44.0752f,100.0f}, + {34.5514f,95.2381f}, + {29.7895f,85.7143f}, + {29.7895f,76.1905f}, + {34.5514f,61.9048f}, + {44.0752f,47.619f}, + {67.8848f,14.2857f}, + {77.4086f,4.7619f}, + {86.9324f,0.0f}, + {96.4562f,0.0f}, + {101.218f,4.7619f}, + {101.218f,9.5238f} +}; + +static const Fl_Glut_StrokeStrip ch38st[] = +{ + {34,ch38st0} +}; + +static const Fl_Glut_StrokeChar ch38 = {101.758f,1,ch38st}; + +/* char: 0x27 */ + +static const Fl_Glut_StrokeVertex ch39st0[] = +{ + {4.44f,100.0f}, + {4.44f,66.6667f} +}; + +static const Fl_Glut_StrokeStrip ch39st[] = +{ + {2,ch39st0} +}; + +static const Fl_Glut_StrokeChar ch39 = {13.62f,1,ch39st}; + +/* char: 0x28 */ + +static const Fl_Glut_StrokeVertex ch40st0[] = +{ + {40.9133f,119.048f}, + {31.3895f,109.524f}, + {21.8657f,95.2381f}, + {12.3419f,76.1905f}, + {7.58f,52.381f}, + {7.58f,33.3333f}, + {12.3419f,9.5238f}, + {21.8657f,-9.5238f}, + {31.3895f,-23.8095f}, + {40.9133f,-33.3333f} +}; + +static const Fl_Glut_StrokeStrip ch40st[] = +{ + {10,ch40st0} +}; + +static const Fl_Glut_StrokeChar ch40 = {47.1733f,1,ch40st}; + +/* char: 0x29 */ + +static const Fl_Glut_StrokeVertex ch41st0[] = +{ + {5.28f,119.048f}, + {14.8038f,109.524f}, + {24.3276f,95.2381f}, + {33.8514f,76.1905f}, + {38.6133f,52.381f}, + {38.6133f,33.3333f}, + {33.8514f,9.5238f}, + {24.3276f,-9.5238f}, + {14.8038f,-23.8095f}, + {5.28f,-33.3333f} +}; + +static const Fl_Glut_StrokeStrip ch41st[] = +{ + {10,ch41st0} +}; + +static const Fl_Glut_StrokeChar ch41 = {47.5333f,1,ch41st}; + +/* char: 0x2a */ + +static const Fl_Glut_StrokeVertex ch42st0[] = +{ + {30.7695f,71.4286f}, + {30.7695f,14.2857f} +}; + +static const Fl_Glut_StrokeVertex ch42st1[] = +{ + {6.96f,57.1429f}, + {54.579f,28.5714f} +}; + +static const Fl_Glut_StrokeVertex ch42st2[] = +{ + {54.579f,57.1429f}, + {6.96f,28.5714f} +}; + +static const Fl_Glut_StrokeStrip ch42st[] = +{ + {2,ch42st0}, + {2,ch42st1}, + {2,ch42st2} +}; + +static const Fl_Glut_StrokeChar ch42 = {59.439f,3,ch42st}; + +/* char: 0x2b */ + +static const Fl_Glut_StrokeVertex ch43st0[] = +{ + {48.8371f,85.7143f}, + {48.8371f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch43st1[] = +{ + {5.98f,42.8571f}, + {91.6943f,42.8571f} +}; + +static const Fl_Glut_StrokeStrip ch43st[] = +{ + {2,ch43st0}, + {2,ch43st1} +}; + +static const Fl_Glut_StrokeChar ch43 = {97.2543f,2,ch43st}; + +/* char: 0x2c */ + +static const Fl_Glut_StrokeVertex ch44st0[] = +{ + {18.2838f,4.7619f}, + {13.5219f,0.0f}, + {8.76f,4.7619f}, + {13.5219f,9.5238f}, + {18.2838f,4.7619f}, + {18.2838f,-4.7619f}, + {13.5219f,-14.2857f}, + {8.76f,-19.0476f} +}; + +static const Fl_Glut_StrokeStrip ch44st[] = +{ + {8,ch44st0} +}; + +static const Fl_Glut_StrokeChar ch44 = {26.0638f,1,ch44st}; + +/* char: 0x2d */ + +static const Fl_Glut_StrokeVertex ch45st0[] = +{ + {7.38f,42.8571f}, + {93.0943f,42.8571f} +}; + +static const Fl_Glut_StrokeStrip ch45st[] = +{ + {2,ch45st0} +}; + +static const Fl_Glut_StrokeChar ch45 = {100.754f,1,ch45st}; + +/* char: 0x2e */ + +static const Fl_Glut_StrokeVertex ch46st0[] = +{ + {13.1019f,9.5238f}, + {8.34f,4.7619f}, + {13.1019f,0.0f}, + {17.8638f,4.7619f}, + {13.1019f,9.5238f} +}; + +static const Fl_Glut_StrokeStrip ch46st[] = +{ + {5,ch46st0} +}; + +static const Fl_Glut_StrokeChar ch46 = {26.4838f,1,ch46st}; + +/* char: 0x2f */ + +static const Fl_Glut_StrokeVertex ch47st0[] = +{ + {7.24f,-14.2857f}, + {73.9067f,100.0f} +}; + +static const Fl_Glut_StrokeStrip ch47st[] = +{ + {2,ch47st0} +}; + +static const Fl_Glut_StrokeChar ch47 = {82.1067f,1,ch47st}; + +/* char: 0x30 */ + +static const Fl_Glut_StrokeVertex ch48st0[] = +{ + {33.5514f,100.0f}, + {19.2657f,95.2381f}, + {9.7419f,80.9524f}, + {4.98f,57.1429f}, + {4.98f,42.8571f}, + {9.7419f,19.0476f}, + {19.2657f,4.7619f}, + {33.5514f,0.0f}, + {43.0752f,0.0f}, + {57.361f,4.7619f}, + {66.8848f,19.0476f}, + {71.6467f,42.8571f}, + {71.6467f,57.1429f}, + {66.8848f,80.9524f}, + {57.361f,95.2381f}, + {43.0752f,100.0f}, + {33.5514f,100.0f} +}; + +static const Fl_Glut_StrokeStrip ch48st[] = +{ + {17,ch48st0} +}; + +static const Fl_Glut_StrokeChar ch48 = {77.0667f,1,ch48st}; + +/* char: 0x31 */ + +static const Fl_Glut_StrokeVertex ch49st0[] = +{ + {11.82f,80.9524f}, + {21.3438f,85.7143f}, + {35.6295f,100.0f}, + {35.6295f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch49st[] = +{ + {4,ch49st0} +}; + +static const Fl_Glut_StrokeChar ch49 = {66.5295f,1,ch49st}; + +/* char: 0x32 */ + +static const Fl_Glut_StrokeVertex ch50st0[] = +{ + {10.1819f,76.1905f}, + {10.1819f,80.9524f}, + {14.9438f,90.4762f}, + {19.7057f,95.2381f}, + {29.2295f,100.0f}, + {48.2771f,100.0f}, + {57.801f,95.2381f}, + {62.5629f,90.4762f}, + {67.3248f,80.9524f}, + {67.3248f,71.4286f}, + {62.5629f,61.9048f}, + {53.039f,47.619f}, + {5.42f,0.0f}, + {72.0867f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch50st[] = +{ + {14,ch50st0} +}; + +static const Fl_Glut_StrokeChar ch50 = {77.6467f,1,ch50st}; + +/* char: 0x33 */ + +static const Fl_Glut_StrokeVertex ch51st0[] = +{ + {14.5238f,100.0f}, + {66.9048f,100.0f}, + {38.3333f,61.9048f}, + {52.619f,61.9048f}, + {62.1429f,57.1429f}, + {66.9048f,52.381f}, + {71.6667f,38.0952f}, + {71.6667f,28.5714f}, + {66.9048f,14.2857f}, + {57.381f,4.7619f}, + {43.0952f,0.0f}, + {28.8095f,0.0f}, + {14.5238f,4.7619f}, + {9.7619f,9.5238f}, + {5.0f,19.0476f} +}; + +static const Fl_Glut_StrokeStrip ch51st[] = +{ + {15,ch51st0} +}; + +static const Fl_Glut_StrokeChar ch51 = {77.0467f,1,ch51st}; + +/* char: 0x34 */ + +static const Fl_Glut_StrokeVertex ch52st0[] = +{ + {51.499f,100.0f}, + {3.88f,33.3333f}, + {75.3086f,33.3333f} +}; + +static const Fl_Glut_StrokeVertex ch52st1[] = +{ + {51.499f,100.0f}, + {51.499f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch52st[] = +{ + {3,ch52st0}, + {2,ch52st1} +}; + +static const Fl_Glut_StrokeChar ch52 = {80.1686f,2,ch52st}; + +/* char: 0x35 */ + +static const Fl_Glut_StrokeVertex ch53st0[] = +{ + {62.0029f,100.0f}, + {14.3838f,100.0f}, + {9.6219f,57.1429f}, + {14.3838f,61.9048f}, + {28.6695f,66.6667f}, + {42.9552f,66.6667f}, + {57.241f,61.9048f}, + {66.7648f,52.381f}, + {71.5267f,38.0952f}, + {71.5267f,28.5714f}, + {66.7648f,14.2857f}, + {57.241f,4.7619f}, + {42.9552f,0.0f}, + {28.6695f,0.0f}, + {14.3838f,4.7619f}, + {9.6219f,9.5238f}, + {4.86f,19.0476f} +}; + +static const Fl_Glut_StrokeStrip ch53st[] = +{ + {17,ch53st0} +}; + +static const Fl_Glut_StrokeChar ch53 = {77.6867f,1,ch53st}; + +/* char: 0x36 */ + +static const Fl_Glut_StrokeVertex ch54st0[] = +{ + {62.7229f,85.7143f}, + {57.961f,95.2381f}, + {43.6752f,100.0f}, + {34.1514f,100.0f}, + {19.8657f,95.2381f}, + {10.3419f,80.9524f}, + {5.58f,57.1429f}, + {5.58f,33.3333f}, + {10.3419f,14.2857f}, + {19.8657f,4.7619f}, + {34.1514f,0.0f}, + {38.9133f,0.0f}, + {53.199f,4.7619f}, + {62.7229f,14.2857f}, + {67.4848f,28.5714f}, + {67.4848f,33.3333f}, + {62.7229f,47.619f}, + {53.199f,57.1429f}, + {38.9133f,61.9048f}, + {34.1514f,61.9048f}, + {19.8657f,57.1429f}, + {10.3419f,47.619f}, + {5.58f,33.3333f} +}; + +static const Fl_Glut_StrokeStrip ch54st[] = +{ + {23,ch54st0} +}; + +static const Fl_Glut_StrokeChar ch54 = {73.8048f,1,ch54st}; + +/* char: 0x37 */ + +static const Fl_Glut_StrokeVertex ch55st0[] = +{ + {72.2267f,100.0f}, + {24.6076f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch55st1[] = +{ + {5.56f,100.0f}, + {72.2267f,100.0f} +}; + +static const Fl_Glut_StrokeStrip ch55st[] = +{ + {2,ch55st0}, + {2,ch55st1} +}; + +static const Fl_Glut_StrokeChar ch55 = {77.2267f,2,ch55st}; + +/* char: 0x38 */ + +static const Fl_Glut_StrokeVertex ch56st0[] = +{ + {29.4095f,100.0f}, + {15.1238f,95.2381f}, + {10.3619f,85.7143f}, + {10.3619f,76.1905f}, + {15.1238f,66.6667f}, + {24.6476f,61.9048f}, + {43.6952f,57.1429f}, + {57.981f,52.381f}, + {67.5048f,42.8571f}, + {72.2667f,33.3333f}, + {72.2667f,19.0476f}, + {67.5048f,9.5238f}, + {62.7429f,4.7619f}, + {48.4571f,0.0f}, + {29.4095f,0.0f}, + {15.1238f,4.7619f}, + {10.3619f,9.5238f}, + {5.6f,19.0476f}, + {5.6f,33.3333f}, + {10.3619f,42.8571f}, + {19.8857f,52.381f}, + {34.1714f,57.1429f}, + {53.219f,61.9048f}, + {62.7429f,66.6667f}, + {67.5048f,76.1905f}, + {67.5048f,85.7143f}, + {62.7429f,95.2381f}, + {48.4571f,100.0f}, + {29.4095f,100.0f} +}; + +static const Fl_Glut_StrokeStrip ch56st[] = +{ + {29,ch56st0} +}; + +static const Fl_Glut_StrokeChar ch56 = {77.6667f,1,ch56st}; + +/* char: 0x39 */ + +static const Fl_Glut_StrokeVertex ch57st0[] = +{ + {68.5048f,66.6667f}, + {63.7429f,52.381f}, + {54.219f,42.8571f}, + {39.9333f,38.0952f}, + {35.1714f,38.0952f}, + {20.8857f,42.8571f}, + {11.3619f,52.381f}, + {6.6f,66.6667f}, + {6.6f,71.4286f}, + {11.3619f,85.7143f}, + {20.8857f,95.2381f}, + {35.1714f,100.0f}, + {39.9333f,100.0f}, + {54.219f,95.2381f}, + {63.7429f,85.7143f}, + {68.5048f,66.6667f}, + {68.5048f,42.8571f}, + {63.7429f,19.0476f}, + {54.219f,4.7619f}, + {39.9333f,0.0f}, + {30.4095f,0.0f}, + {16.1238f,4.7619f}, + {11.3619f,14.2857f} +}; + +static const Fl_Glut_StrokeStrip ch57st[] = +{ + {23,ch57st0} +}; + +static const Fl_Glut_StrokeChar ch57 = {74.0648f,1,ch57st}; + +/* char: 0x3a */ + +static const Fl_Glut_StrokeVertex ch58st0[] = +{ + {14.0819f,66.6667f}, + {9.32f,61.9048f}, + {14.0819f,57.1429f}, + {18.8438f,61.9048f}, + {14.0819f,66.6667f} +}; + +static const Fl_Glut_StrokeVertex ch58st1[] = +{ + {14.0819f,9.5238f}, + {9.32f,4.7619f}, + {14.0819f,0.0f}, + {18.8438f,4.7619f}, + {14.0819f,9.5238f} +}; + +static const Fl_Glut_StrokeStrip ch58st[] = +{ + {5,ch58st0}, + {5,ch58st1} +}; + +static const Fl_Glut_StrokeChar ch58 = {26.2238f,2,ch58st}; + +/* char: 0x3b */ + +static const Fl_Glut_StrokeVertex ch59st0[] = +{ + {12.9619f,66.6667f}, + {8.2f,61.9048f}, + {12.9619f,57.1429f}, + {17.7238f,61.9048f}, + {12.9619f,66.6667f} +}; + +static const Fl_Glut_StrokeVertex ch59st1[] = +{ + {17.7238f,4.7619f}, + {12.9619f,0.0f}, + {8.2f,4.7619f}, + {12.9619f,9.5238f}, + {17.7238f,4.7619f}, + {17.7238f,-4.7619f}, + {12.9619f,-14.2857f}, + {8.2f,-19.0476f} +}; + +static const Fl_Glut_StrokeStrip ch59st[] = +{ + {5,ch59st0}, + {8,ch59st1} +}; + +static const Fl_Glut_StrokeChar ch59 = {26.3038f,2,ch59st}; + +/* char: 0x3c */ + +static const Fl_Glut_StrokeVertex ch60st0[] = +{ + {79.2505f,85.7143f}, + {3.06f,42.8571f}, + {79.2505f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch60st[] = +{ + {3,ch60st0} +}; + +static const Fl_Glut_StrokeChar ch60 = {81.6105f,1,ch60st}; + +/* char: 0x3d */ + +static const Fl_Glut_StrokeVertex ch61st0[] = +{ + {5.7f,57.1429f}, + {91.4143f,57.1429f} +}; + +static const Fl_Glut_StrokeVertex ch61st1[] = +{ + {5.7f,28.5714f}, + {91.4143f,28.5714f} +}; + +static const Fl_Glut_StrokeStrip ch61st[] = +{ + {2,ch61st0}, + {2,ch61st1} +}; + +static const Fl_Glut_StrokeChar ch61 = {97.2543f,2,ch61st}; + +/* char: 0x3e */ + +static const Fl_Glut_StrokeVertex ch62st0[] = +{ + {2.78f,85.7143f}, + {78.9705f,42.8571f}, + {2.78f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch62st[] = +{ + {3,ch62st0} +}; + +static const Fl_Glut_StrokeChar ch62 = {81.6105f,1,ch62st}; + +/* char: 0x3f */ + +static const Fl_Glut_StrokeVertex ch63st0[] = +{ + {8.42f,76.1905f}, + {8.42f,80.9524f}, + {13.1819f,90.4762f}, + {17.9438f,95.2381f}, + {27.4676f,100.0f}, + {46.5152f,100.0f}, + {56.039f,95.2381f}, + {60.801f,90.4762f}, + {65.5629f,80.9524f}, + {65.5629f,71.4286f}, + {60.801f,61.9048f}, + {56.039f,57.1429f}, + {36.9914f,47.619f}, + {36.9914f,33.3333f} +}; + +static const Fl_Glut_StrokeVertex ch63st1[] = +{ + {36.9914f,9.5238f}, + {32.2295f,4.7619f}, + {36.9914f,0.0f}, + {41.7533f,4.7619f}, + {36.9914f,9.5238f} +}; + +static const Fl_Glut_StrokeStrip ch63st[] = +{ + {14,ch63st0}, + {5,ch63st1} +}; + +static const Fl_Glut_StrokeChar ch63 = {73.9029f,2,ch63st}; + +/* char: 0x40 */ + +static const Fl_Glut_StrokeVertex ch64st0[] = +{ + {49.2171f,52.381f}, + {39.6933f,57.1429f}, + {30.1695f,57.1429f}, + {25.4076f,47.619f}, + {25.4076f,42.8571f}, + {30.1695f,33.3333f}, + {39.6933f,33.3333f}, + {49.2171f,38.0952f} +}; + +static const Fl_Glut_StrokeVertex ch64st1[] = +{ + {49.2171f,57.1429f}, + {49.2171f,38.0952f}, + {53.979f,33.3333f}, + {63.5029f,33.3333f}, + {68.2648f,42.8571f}, + {68.2648f,47.619f}, + {63.5029f,61.9048f}, + {53.979f,71.4286f}, + {39.6933f,76.1905f}, + {34.9314f,76.1905f}, + {20.6457f,71.4286f}, + {11.1219f,61.9048f}, + {6.36f,47.619f}, + {6.36f,42.8571f}, + {11.1219f,28.5714f}, + {20.6457f,19.0476f}, + {34.9314f,14.2857f}, + {39.6933f,14.2857f}, + {53.979f,19.0476f} +}; + +static const Fl_Glut_StrokeStrip ch64st[] = +{ + {8,ch64st0}, + {19,ch64st1} +}; + +static const Fl_Glut_StrokeChar ch64 = {74.3648f,2,ch64st}; + +/* char: 0x41 */ + +static const Fl_Glut_StrokeVertex ch65st0[] = +{ + {40.5952f,100.0f}, + {2.5f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch65st1[] = +{ + {40.5952f,100.0f}, + {78.6905f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch65st2[] = +{ + {16.7857f,33.3333f}, + {64.4048f,33.3333f} +}; + +static const Fl_Glut_StrokeStrip ch65st[] = +{ + {2,ch65st0}, + {2,ch65st1}, + {2,ch65st2} +}; + +static const Fl_Glut_StrokeChar ch65 = {80.4905f,3,ch65st}; + +/* char: 0x42 */ + +static const Fl_Glut_StrokeVertex ch66st0[] = +{ + {11.42f,100.0f}, + {11.42f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch66st1[] = +{ + {11.42f,100.0f}, + {54.2771f,100.0f}, + {68.5629f,95.2381f}, + {73.3248f,90.4762f}, + {78.0867f,80.9524f}, + {78.0867f,71.4286f}, + {73.3248f,61.9048f}, + {68.5629f,57.1429f}, + {54.2771f,52.381f} +}; + +static const Fl_Glut_StrokeVertex ch66st2[] = +{ + {11.42f,52.381f}, + {54.2771f,52.381f}, + {68.5629f,47.619f}, + {73.3248f,42.8571f}, + {78.0867f,33.3333f}, + {78.0867f,19.0476f}, + {73.3248f,9.5238f}, + {68.5629f,4.7619f}, + {54.2771f,0.0f}, + {11.42f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch66st[] = +{ + {2,ch66st0}, + {9,ch66st1}, + {10,ch66st2} +}; + +static const Fl_Glut_StrokeChar ch66 = {83.6267f,3,ch66st}; + +/* char: 0x43 */ + +static const Fl_Glut_StrokeVertex ch67st0[] = +{ + {78.0886f,76.1905f}, + {73.3267f,85.7143f}, + {63.8029f,95.2381f}, + {54.279f,100.0f}, + {35.2314f,100.0f}, + {25.7076f,95.2381f}, + {16.1838f,85.7143f}, + {11.4219f,76.1905f}, + {6.66f,61.9048f}, + {6.66f,38.0952f}, + {11.4219f,23.8095f}, + {16.1838f,14.2857f}, + {25.7076f,4.7619f}, + {35.2314f,0.0f}, + {54.279f,0.0f}, + {63.8029f,4.7619f}, + {73.3267f,14.2857f}, + {78.0886f,23.8095f} +}; + +static const Fl_Glut_StrokeStrip ch67st[] = +{ + {18,ch67st0} +}; + +static const Fl_Glut_StrokeChar ch67 = {84.4886f,1,ch67st}; + +/* char: 0x44 */ + +static const Fl_Glut_StrokeVertex ch68st0[] = +{ + {11.96f,100.0f}, + {11.96f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch68st1[] = +{ + {11.96f,100.0f}, + {45.2933f,100.0f}, + {59.579f,95.2381f}, + {69.1029f,85.7143f}, + {73.8648f,76.1905f}, + {78.6267f,61.9048f}, + {78.6267f,38.0952f}, + {73.8648f,23.8095f}, + {69.1029f,14.2857f}, + {59.579f,4.7619f}, + {45.2933f,0.0f}, + {11.96f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch68st[] = +{ + {2,ch68st0}, + {12,ch68st1} +}; + +static const Fl_Glut_StrokeChar ch68 = {85.2867f,2,ch68st}; + +/* char: 0x45 */ + +static const Fl_Glut_StrokeVertex ch69st0[] = +{ + {11.42f,100.0f}, + {11.42f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch69st1[] = +{ + {11.42f,100.0f}, + {73.3248f,100.0f} +}; + +static const Fl_Glut_StrokeVertex ch69st2[] = +{ + {11.42f,52.381f}, + {49.5152f,52.381f} +}; + +static const Fl_Glut_StrokeVertex ch69st3[] = +{ + {11.42f,0.0f}, + {73.3248f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch69st[] = +{ + {2,ch69st0}, + {2,ch69st1}, + {2,ch69st2}, + {2,ch69st3} +}; + +static const Fl_Glut_StrokeChar ch69 = {78.1848f,4,ch69st}; + +/* char: 0x46 */ + +static const Fl_Glut_StrokeVertex ch70st0[] = +{ + {11.42f,100.0f}, + {11.42f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch70st1[] = +{ + {11.42f,100.0f}, + {73.3248f,100.0f} +}; + +static const Fl_Glut_StrokeVertex ch70st2[] = +{ + {11.42f,52.381f}, + {49.5152f,52.381f} +}; + +static const Fl_Glut_StrokeStrip ch70st[] = +{ + {2,ch70st0}, + {2,ch70st1}, + {2,ch70st2} +}; + +static const Fl_Glut_StrokeChar ch70 = {78.7448f,3,ch70st}; + +/* char: 0x47 */ + +static const Fl_Glut_StrokeVertex ch71st0[] = +{ + {78.4886f,76.1905f}, + {73.7267f,85.7143f}, + {64.2029f,95.2381f}, + {54.679f,100.0f}, + {35.6314f,100.0f}, + {26.1076f,95.2381f}, + {16.5838f,85.7143f}, + {11.8219f,76.1905f}, + {7.06f,61.9048f}, + {7.06f,38.0952f}, + {11.8219f,23.8095f}, + {16.5838f,14.2857f}, + {26.1076f,4.7619f}, + {35.6314f,0.0f}, + {54.679f,0.0f}, + {64.2029f,4.7619f}, + {73.7267f,14.2857f}, + {78.4886f,23.8095f}, + {78.4886f,38.0952f} +}; + +static const Fl_Glut_StrokeVertex ch71st1[] = +{ + {54.679f,38.0952f}, + {78.4886f,38.0952f} +}; + +static const Fl_Glut_StrokeStrip ch71st[] = +{ + {19,ch71st0}, + {2,ch71st1} +}; + +static const Fl_Glut_StrokeChar ch71 = {89.7686f,2,ch71st}; + +/* char: 0x48 */ + +static const Fl_Glut_StrokeVertex ch72st0[] = +{ + {11.42f,100.0f}, + {11.42f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch72st1[] = +{ + {78.0867f,100.0f}, + {78.0867f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch72st2[] = +{ + {11.42f,52.381f}, + {78.0867f,52.381f} +}; + +static const Fl_Glut_StrokeStrip ch72st[] = +{ + {2,ch72st0}, + {2,ch72st1}, + {2,ch72st2} +}; + +static const Fl_Glut_StrokeChar ch72 = {89.0867f,3,ch72st}; + +/* char: 0x49 */ + +static const Fl_Glut_StrokeVertex ch73st0[] = +{ + {10.86f,100.0f}, + {10.86f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch73st[] = +{ + {2,ch73st0} +}; + +static const Fl_Glut_StrokeChar ch73 = {21.3f,1,ch73st}; + +/* char: 0x4a */ + +static const Fl_Glut_StrokeVertex ch74st0[] = +{ + {50.119f,100.0f}, + {50.119f,23.8095f}, + {45.3571f,9.5238f}, + {40.5952f,4.7619f}, + {31.0714f,0.0f}, + {21.5476f,0.0f}, + {12.0238f,4.7619f}, + {7.2619f,9.5238f}, + {2.5f,23.8095f}, + {2.5f,33.3333f} +}; + +static const Fl_Glut_StrokeStrip ch74st[] = +{ + {10,ch74st0} +}; + +static const Fl_Glut_StrokeChar ch74 = {59.999f,1,ch74st}; + +/* char: 0x4b */ + +static const Fl_Glut_StrokeVertex ch75st0[] = +{ + {11.28f,100.0f}, + {11.28f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch75st1[] = +{ + {77.9467f,100.0f}, + {11.28f,33.3333f} +}; + +static const Fl_Glut_StrokeVertex ch75st2[] = +{ + {35.0895f,57.1429f}, + {77.9467f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch75st[] = +{ + {2,ch75st0}, + {2,ch75st1}, + {2,ch75st2} +}; + +static const Fl_Glut_StrokeChar ch75 = {79.3267f,3,ch75st}; + +/* char: 0x4c */ + +static const Fl_Glut_StrokeVertex ch76st0[] = +{ + {11.68f,100.0f}, + {11.68f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch76st1[] = +{ + {11.68f,0.0f}, + {68.8229f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch76st[] = +{ + {2,ch76st0}, + {2,ch76st1} +}; + +static const Fl_Glut_StrokeChar ch76 = {71.3229f,2,ch76st}; + +/* char: 0x4d */ + +static const Fl_Glut_StrokeVertex ch77st0[] = +{ + {10.86f,100.0f}, + {10.86f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch77st1[] = +{ + {10.86f,100.0f}, + {48.9552f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch77st2[] = +{ + {87.0505f,100.0f}, + {48.9552f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch77st3[] = +{ + {87.0505f,100.0f}, + {87.0505f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch77st[] = +{ + {2,ch77st0}, + {2,ch77st1}, + {2,ch77st2}, + {2,ch77st3} +}; + +static const Fl_Glut_StrokeChar ch77 = {97.2105f,4,ch77st}; + +/* char: 0x4e */ + +static const Fl_Glut_StrokeVertex ch78st0[] = +{ + {11.14f,100.0f}, + {11.14f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch78st1[] = +{ + {11.14f,100.0f}, + {77.8067f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch78st2[] = +{ + {77.8067f,100.0f}, + {77.8067f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch78st[] = +{ + {2,ch78st0}, + {2,ch78st1}, + {2,ch78st2} +}; + +static const Fl_Glut_StrokeChar ch78 = {88.8067f,3,ch78st}; + +/* char: 0x4f */ + +static const Fl_Glut_StrokeVertex ch79st0[] = +{ + {34.8114f,100.0f}, + {25.2876f,95.2381f}, + {15.7638f,85.7143f}, + {11.0019f,76.1905f}, + {6.24f,61.9048f}, + {6.24f,38.0952f}, + {11.0019f,23.8095f}, + {15.7638f,14.2857f}, + {25.2876f,4.7619f}, + {34.8114f,0.0f}, + {53.859f,0.0f}, + {63.3829f,4.7619f}, + {72.9067f,14.2857f}, + {77.6686f,23.8095f}, + {82.4305f,38.0952f}, + {82.4305f,61.9048f}, + {77.6686f,76.1905f}, + {72.9067f,85.7143f}, + {63.3829f,95.2381f}, + {53.859f,100.0f}, + {34.8114f,100.0f} +}; + +static const Fl_Glut_StrokeStrip ch79st[] = +{ + {21,ch79st0} +}; + +static const Fl_Glut_StrokeChar ch79 = {88.8305f,1,ch79st}; + +/* char: 0x50 */ + +static const Fl_Glut_StrokeVertex ch80st0[] = +{ + {12.1f,100.0f}, + {12.1f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch80st1[] = +{ + {12.1f,100.0f}, + {54.9571f,100.0f}, + {69.2429f,95.2381f}, + {74.0048f,90.4762f}, + {78.7667f,80.9524f}, + {78.7667f,66.6667f}, + {74.0048f,57.1429f}, + {69.2429f,52.381f}, + {54.9571f,47.619f}, + {12.1f,47.619f} +}; + +static const Fl_Glut_StrokeStrip ch80st[] = +{ + {2,ch80st0}, + {10,ch80st1} +}; + +static const Fl_Glut_StrokeChar ch80 = {85.6667f,2,ch80st}; + +/* char: 0x51 */ + +static const Fl_Glut_StrokeVertex ch81st0[] = +{ + {33.8714f,100.0f}, + {24.3476f,95.2381f}, + {14.8238f,85.7143f}, + {10.0619f,76.1905f}, + {5.3f,61.9048f}, + {5.3f,38.0952f}, + {10.0619f,23.8095f}, + {14.8238f,14.2857f}, + {24.3476f,4.7619f}, + {33.8714f,0.0f}, + {52.919f,0.0f}, + {62.4429f,4.7619f}, + {71.9667f,14.2857f}, + {76.7286f,23.8095f}, + {81.4905f,38.0952f}, + {81.4905f,61.9048f}, + {76.7286f,76.1905f}, + {71.9667f,85.7143f}, + {62.4429f,95.2381f}, + {52.919f,100.0f}, + {33.8714f,100.0f} +}; + +static const Fl_Glut_StrokeVertex ch81st1[] = +{ + {48.1571f,19.0476f}, + {76.7286f,-9.5238f} +}; + +static const Fl_Glut_StrokeStrip ch81st[] = +{ + {21,ch81st0}, + {2,ch81st1} +}; + +static const Fl_Glut_StrokeChar ch81 = {88.0905f,2,ch81st}; + +/* char: 0x52 */ + +static const Fl_Glut_StrokeVertex ch82st0[] = +{ + {11.68f,100.0f}, + {11.68f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch82st1[] = +{ + {11.68f,100.0f}, + {54.5371f,100.0f}, + {68.8229f,95.2381f}, + {73.5848f,90.4762f}, + {78.3467f,80.9524f}, + {78.3467f,71.4286f}, + {73.5848f,61.9048f}, + {68.8229f,57.1429f}, + {54.5371f,52.381f}, + {11.68f,52.381f} +}; + +static const Fl_Glut_StrokeVertex ch82st2[] = +{ + {45.0133f,52.381f}, + {78.3467f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch82st[] = +{ + {2,ch82st0}, + {10,ch82st1}, + {2,ch82st2} +}; + +static const Fl_Glut_StrokeChar ch82 = {82.3667f,3,ch82st}; + +/* char: 0x53 */ + +static const Fl_Glut_StrokeVertex ch83st0[] = +{ + {74.6667f,85.7143f}, + {65.1429f,95.2381f}, + {50.8571f,100.0f}, + {31.8095f,100.0f}, + {17.5238f,95.2381f}, + {8.0f,85.7143f}, + {8.0f,76.1905f}, + {12.7619f,66.6667f}, + {17.5238f,61.9048f}, + {27.0476f,57.1429f}, + {55.619f,47.619f}, + {65.1429f,42.8571f}, + {69.9048f,38.0952f}, + {74.6667f,28.5714f}, + {74.6667f,14.2857f}, + {65.1429f,4.7619f}, + {50.8571f,0.0f}, + {31.8095f,0.0f}, + {17.5238f,4.7619f}, + {8.0f,14.2857f} +}; + +static const Fl_Glut_StrokeStrip ch83st[] = +{ + {20,ch83st0} +}; + +static const Fl_Glut_StrokeChar ch83 = {80.8267f,1,ch83st}; + +/* char: 0x54 */ + +static const Fl_Glut_StrokeVertex ch84st0[] = +{ + {35.6933f,100.0f}, + {35.6933f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch84st1[] = +{ + {2.36f,100.0f}, + {69.0267f,100.0f} +}; + +static const Fl_Glut_StrokeStrip ch84st[] = +{ + {2,ch84st0}, + {2,ch84st1} +}; + +static const Fl_Glut_StrokeChar ch84 = {71.9467f,2,ch84st}; + +/* char: 0x55 */ + +static const Fl_Glut_StrokeVertex ch85st0[] = +{ + {11.54f,100.0f}, + {11.54f,28.5714f}, + {16.3019f,14.2857f}, + {25.8257f,4.7619f}, + {40.1114f,0.0f}, + {49.6352f,0.0f}, + {63.921f,4.7619f}, + {73.4448f,14.2857f}, + {78.2067f,28.5714f}, + {78.2067f,100.0f} +}; + +static const Fl_Glut_StrokeStrip ch85st[] = +{ + {10,ch85st0} +}; + +static const Fl_Glut_StrokeChar ch85 = {89.4867f,1,ch85st}; + +/* char: 0x56 */ + +static const Fl_Glut_StrokeVertex ch86st0[] = +{ + {2.36f,100.0f}, + {40.4552f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch86st1[] = +{ + {78.5505f,100.0f}, + {40.4552f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch86st[] = +{ + {2,ch86st0}, + {2,ch86st1} +}; + +static const Fl_Glut_StrokeChar ch86 = {81.6105f,2,ch86st}; + +/* char: 0x57 */ + +static const Fl_Glut_StrokeVertex ch87st0[] = +{ + {2.22f,100.0f}, + {26.0295f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch87st1[] = +{ + {49.839f,100.0f}, + {26.0295f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch87st2[] = +{ + {49.839f,100.0f}, + {73.6486f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch87st3[] = +{ + {97.4581f,100.0f}, + {73.6486f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch87st[] = +{ + {2,ch87st0}, + {2,ch87st1}, + {2,ch87st2}, + {2,ch87st3} +}; + +static const Fl_Glut_StrokeChar ch87 = {100.518f,4,ch87st}; + +/* char: 0x58 */ + +static const Fl_Glut_StrokeVertex ch88st0[] = +{ + {2.5f,100.0f}, + {69.1667f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch88st1[] = +{ + {69.1667f,100.0f}, + {2.5f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch88st[] = +{ + {2,ch88st0}, + {2,ch88st1} +}; + +static const Fl_Glut_StrokeChar ch88 = {72.3667f,2,ch88st}; + +/* char: 0x59 */ + +static const Fl_Glut_StrokeVertex ch89st0[] = +{ + {1.52f,100.0f}, + {39.6152f,52.381f}, + {39.6152f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch89st1[] = +{ + {77.7105f,100.0f}, + {39.6152f,52.381f} +}; + +static const Fl_Glut_StrokeStrip ch89st[] = +{ + {3,ch89st0}, + {2,ch89st1} +}; + +static const Fl_Glut_StrokeChar ch89 = {79.6505f,2,ch89st}; + +/* char: 0x5a */ + +static const Fl_Glut_StrokeVertex ch90st0[] = +{ + {69.1667f,100.0f}, + {2.5f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch90st1[] = +{ + {2.5f,100.0f}, + {69.1667f,100.0f} +}; + +static const Fl_Glut_StrokeVertex ch90st2[] = +{ + {2.5f,0.0f}, + {69.1667f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch90st[] = +{ + {2,ch90st0}, + {2,ch90st1}, + {2,ch90st2} +}; + +static const Fl_Glut_StrokeChar ch90 = {73.7467f,3,ch90st}; + +/* char: 0x5b */ + +static const Fl_Glut_StrokeVertex ch91st0[] = +{ + {7.78f,119.048f}, + {7.78f,-33.3333f} +}; + +static const Fl_Glut_StrokeVertex ch91st1[] = +{ + {12.5419f,119.048f}, + {12.5419f,-33.3333f} +}; + +static const Fl_Glut_StrokeVertex ch91st2[] = +{ + {7.78f,119.048f}, + {41.1133f,119.048f} +}; + +static const Fl_Glut_StrokeVertex ch91st3[] = +{ + {7.78f,-33.3333f}, + {41.1133f,-33.3333f} +}; + +static const Fl_Glut_StrokeStrip ch91st[] = +{ + {2,ch91st0}, + {2,ch91st1}, + {2,ch91st2}, + {2,ch91st3} +}; + +static const Fl_Glut_StrokeChar ch91 = {46.1133f,4,ch91st}; + +/* char: 0x5c */ + +static const Fl_Glut_StrokeVertex ch92st0[] = +{ + {5.84f,100.0f}, + {72.5067f,-14.2857f} +}; + +static const Fl_Glut_StrokeStrip ch92st[] = +{ + {2,ch92st0} +}; + +static const Fl_Glut_StrokeChar ch92 = {78.2067f,1,ch92st}; + +/* char: 0x5d */ + +static const Fl_Glut_StrokeVertex ch93st0[] = +{ + {33.0114f,119.048f}, + {33.0114f,-33.3333f} +}; + +static const Fl_Glut_StrokeVertex ch93st1[] = +{ + {37.7733f,119.048f}, + {37.7733f,-33.3333f} +}; + +static const Fl_Glut_StrokeVertex ch93st2[] = +{ + {4.44f,119.048f}, + {37.7733f,119.048f} +}; + +static const Fl_Glut_StrokeVertex ch93st3[] = +{ + {4.44f,-33.3333f}, + {37.7733f,-33.3333f} +}; + +static const Fl_Glut_StrokeStrip ch93st[] = +{ + {2,ch93st0}, + {2,ch93st1}, + {2,ch93st2}, + {2,ch93st3} +}; + +static const Fl_Glut_StrokeChar ch93 = {46.3933f,4,ch93st}; + +/* char: 0x5e */ + +static const Fl_Glut_StrokeVertex ch94st0[] = +{ + {44.0752f,109.524f}, + {5.98f,42.8571f} +}; + +static const Fl_Glut_StrokeVertex ch94st1[] = +{ + {44.0752f,109.524f}, + {82.1705f,42.8571f} +}; + +static const Fl_Glut_StrokeStrip ch94st[] = +{ + {2,ch94st0}, + {2,ch94st1} +}; + +static const Fl_Glut_StrokeChar ch94 = {90.2305f,2,ch94st}; + +/* char: 0x5f */ + +static const Fl_Glut_StrokeVertex ch95st0[] = +{ + {-1.1f,-33.3333f}, + {103.662f,-33.3333f}, + {103.662f,-28.5714f}, + {-1.1f,-28.5714f}, + {-1.1f,-33.3333f} +}; + +static const Fl_Glut_StrokeStrip ch95st[] = +{ + {5,ch95st0} +}; + +static const Fl_Glut_StrokeChar ch95 = {104.062f,1,ch95st}; + +/* char: 0x60 */ + +static const Fl_Glut_StrokeVertex ch96st0[] = +{ + {33.0219f,100.0f}, + {56.8314f,71.4286f} +}; + +static const Fl_Glut_StrokeVertex ch96st1[] = +{ + {33.0219f,100.0f}, + {28.26f,95.2381f}, + {56.8314f,71.4286f} +}; + +static const Fl_Glut_StrokeStrip ch96st[] = +{ + {2,ch96st0}, + {3,ch96st1} +}; + +static const Fl_Glut_StrokeChar ch96 = {83.5714f,2,ch96st}; + +/* char: 0x61 */ + +static const Fl_Glut_StrokeVertex ch97st0[] = +{ + {63.8229f,66.6667f}, + {63.8229f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch97st1[] = +{ + {63.8229f,52.381f}, + {54.299f,61.9048f}, + {44.7752f,66.6667f}, + {30.4895f,66.6667f}, + {20.9657f,61.9048f}, + {11.4419f,52.381f}, + {6.68f,38.0952f}, + {6.68f,28.5714f}, + {11.4419f,14.2857f}, + {20.9657f,4.7619f}, + {30.4895f,0.0f}, + {44.7752f,0.0f}, + {54.299f,4.7619f}, + {63.8229f,14.2857f} +}; + +static const Fl_Glut_StrokeStrip ch97st[] = +{ + {2,ch97st0}, + {14,ch97st1} +}; + +static const Fl_Glut_StrokeChar ch97 = {66.6029f,2,ch97st}; + +/* char: 0x62 */ + +static const Fl_Glut_StrokeVertex ch98st0[] = +{ + {8.76f,100.0f}, + {8.76f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch98st1[] = +{ + {8.76f,52.381f}, + {18.2838f,61.9048f}, + {27.8076f,66.6667f}, + {42.0933f,66.6667f}, + {51.6171f,61.9048f}, + {61.141f,52.381f}, + {65.9029f,38.0952f}, + {65.9029f,28.5714f}, + {61.141f,14.2857f}, + {51.6171f,4.7619f}, + {42.0933f,0.0f}, + {27.8076f,0.0f}, + {18.2838f,4.7619f}, + {8.76f,14.2857f} +}; + +static const Fl_Glut_StrokeStrip ch98st[] = +{ + {2,ch98st0}, + {14,ch98st1} +}; + +static const Fl_Glut_StrokeChar ch98 = {70.4629f,2,ch98st}; + +/* char: 0x63 */ + +static const Fl_Glut_StrokeVertex ch99st0[] = +{ + {62.6629f,52.381f}, + {53.139f,61.9048f}, + {43.6152f,66.6667f}, + {29.3295f,66.6667f}, + {19.8057f,61.9048f}, + {10.2819f,52.381f}, + {5.52f,38.0952f}, + {5.52f,28.5714f}, + {10.2819f,14.2857f}, + {19.8057f,4.7619f}, + {29.3295f,0.0f}, + {43.6152f,0.0f}, + {53.139f,4.7619f}, + {62.6629f,14.2857f} +}; + +static const Fl_Glut_StrokeStrip ch99st[] = +{ + {14,ch99st0} +}; + +static const Fl_Glut_StrokeChar ch99 = {68.9229f,1,ch99st}; + +/* char: 0x64 */ + +static const Fl_Glut_StrokeVertex ch100st0[] = +{ + {61.7829f,100.0f}, + {61.7829f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch100st1[] = +{ + {61.7829f,52.381f}, + {52.259f,61.9048f}, + {42.7352f,66.6667f}, + {28.4495f,66.6667f}, + {18.9257f,61.9048f}, + {9.4019f,52.381f}, + {4.64f,38.0952f}, + {4.64f,28.5714f}, + {9.4019f,14.2857f}, + {18.9257f,4.7619f}, + {28.4495f,0.0f}, + {42.7352f,0.0f}, + {52.259f,4.7619f}, + {61.7829f,14.2857f} +}; + +static const Fl_Glut_StrokeStrip ch100st[] = +{ + {2,ch100st0}, + {14,ch100st1} +}; + +static const Fl_Glut_StrokeChar ch100 = {70.2629f,2,ch100st}; + +/* char: 0x65 */ + +static const Fl_Glut_StrokeVertex ch101st0[] = +{ + {5.72f,38.0952f}, + {62.8629f,38.0952f}, + {62.8629f,47.619f}, + {58.101f,57.1429f}, + {53.339f,61.9048f}, + {43.8152f,66.6667f}, + {29.5295f,66.6667f}, + {20.0057f,61.9048f}, + {10.4819f,52.381f}, + {5.72f,38.0952f}, + {5.72f,28.5714f}, + {10.4819f,14.2857f}, + {20.0057f,4.7619f}, + {29.5295f,0.0f}, + {43.8152f,0.0f}, + {53.339f,4.7619f}, + {62.8629f,14.2857f} +}; + +static const Fl_Glut_StrokeStrip ch101st[] = +{ + {17,ch101st0} +}; + +static const Fl_Glut_StrokeChar ch101 = {68.5229f,1,ch101st}; + +/* char: 0x66 */ + +static const Fl_Glut_StrokeVertex ch102st0[] = +{ + {38.7752f,100.0f}, + {29.2514f,100.0f}, + {19.7276f,95.2381f}, + {14.9657f,80.9524f}, + {14.9657f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch102st1[] = +{ + {0.68f,66.6667f}, + {34.0133f,66.6667f} +}; + +static const Fl_Glut_StrokeStrip ch102st[] = +{ + {5,ch102st0}, + {2,ch102st1} +}; + +static const Fl_Glut_StrokeChar ch102 = {38.6552f,2,ch102st}; + +/* char: 0x67 */ + +static const Fl_Glut_StrokeVertex ch103st0[] = +{ + {62.5029f,66.6667f}, + {62.5029f,-9.5238f}, + {57.741f,-23.8095f}, + {52.979f,-28.5714f}, + {43.4552f,-33.3333f}, + {29.1695f,-33.3333f}, + {19.6457f,-28.5714f} +}; + +static const Fl_Glut_StrokeVertex ch103st1[] = +{ + {62.5029f,52.381f}, + {52.979f,61.9048f}, + {43.4552f,66.6667f}, + {29.1695f,66.6667f}, + {19.6457f,61.9048f}, + {10.1219f,52.381f}, + {5.36f,38.0952f}, + {5.36f,28.5714f}, + {10.1219f,14.2857f}, + {19.6457f,4.7619f}, + {29.1695f,0.0f}, + {43.4552f,0.0f}, + {52.979f,4.7619f}, + {62.5029f,14.2857f} +}; + +static const Fl_Glut_StrokeStrip ch103st[] = +{ + {7,ch103st0}, + {14,ch103st1} +}; + +static const Fl_Glut_StrokeChar ch103 = {70.9829f,2,ch103st}; + +/* char: 0x68 */ + +static const Fl_Glut_StrokeVertex ch104st0[] = +{ + {9.6f,100.0f}, + {9.6f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch104st1[] = +{ + {9.6f,47.619f}, + {23.8857f,61.9048f}, + {33.4095f,66.6667f}, + {47.6952f,66.6667f}, + {57.219f,61.9048f}, + {61.981f,47.619f}, + {61.981f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch104st[] = +{ + {2,ch104st0}, + {7,ch104st1} +}; + +static const Fl_Glut_StrokeChar ch104 = {71.021f,2,ch104st}; + +/* char: 0x69 */ + +static const Fl_Glut_StrokeVertex ch105st0[] = +{ + {10.02f,100.0f}, + {14.7819f,95.2381f}, + {19.5438f,100.0f}, + {14.7819f,104.762f}, + {10.02f,100.0f} +}; + +static const Fl_Glut_StrokeVertex ch105st1[] = +{ + {14.7819f,66.6667f}, + {14.7819f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch105st[] = +{ + {5,ch105st0}, + {2,ch105st1} +}; + +static const Fl_Glut_StrokeChar ch105 = {28.8638f,2,ch105st}; + +/* char: 0x6a */ + +static const Fl_Glut_StrokeVertex ch106st0[] = +{ + {17.3876f,100.0f}, + {22.1495f,95.2381f}, + {26.9114f,100.0f}, + {22.1495f,104.762f}, + {17.3876f,100.0f} +}; + +static const Fl_Glut_StrokeVertex ch106st1[] = +{ + {22.1495f,66.6667f}, + {22.1495f,-14.2857f}, + {17.3876f,-28.5714f}, + {7.8638f,-33.3333f}, + {-1.66f,-33.3333f} +}; + +static const Fl_Glut_StrokeStrip ch106st[] = +{ + {5,ch106st0}, + {5,ch106st1} +}; + +static const Fl_Glut_StrokeChar ch106 = {36.2314f,2,ch106st}; + +/* char: 0x6b */ + +static const Fl_Glut_StrokeVertex ch107st0[] = +{ + {9.6f,100.0f}, + {9.6f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch107st1[] = +{ + {57.219f,66.6667f}, + {9.6f,19.0476f} +}; + +static const Fl_Glut_StrokeVertex ch107st2[] = +{ + {28.6476f,38.0952f}, + {61.981f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch107st[] = +{ + {2,ch107st0}, + {2,ch107st1}, + {2,ch107st2} +}; + +static const Fl_Glut_StrokeChar ch107 = {62.521f,3,ch107st}; + +/* char: 0x6c */ + +static const Fl_Glut_StrokeVertex ch108st0[] = +{ + {10.02f,100.0f}, + {10.02f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch108st[] = +{ + {2,ch108st0} +}; + +static const Fl_Glut_StrokeChar ch108 = {19.34f,1,ch108st}; + +/* char: 0x6d */ + +static const Fl_Glut_StrokeVertex ch109st0[] = +{ + {9.6f,66.6667f}, + {9.6f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch109st1[] = +{ + {9.6f,47.619f}, + {23.8857f,61.9048f}, + {33.4095f,66.6667f}, + {47.6952f,66.6667f}, + {57.219f,61.9048f}, + {61.981f,47.619f}, + {61.981f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch109st2[] = +{ + {61.981f,47.619f}, + {76.2667f,61.9048f}, + {85.7905f,66.6667f}, + {100.076f,66.6667f}, + {109.6f,61.9048f}, + {114.362f,47.619f}, + {114.362f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch109st[] = +{ + {2,ch109st0}, + {7,ch109st1}, + {7,ch109st2} +}; + +static const Fl_Glut_StrokeChar ch109 = {123.962f,3,ch109st}; + +/* char: 0x6e */ + +static const Fl_Glut_StrokeVertex ch110st0[] = +{ + {9.18f,66.6667f}, + {9.18f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch110st1[] = +{ + {9.18f,47.619f}, + {23.4657f,61.9048f}, + {32.9895f,66.6667f}, + {47.2752f,66.6667f}, + {56.799f,61.9048f}, + {61.561f,47.619f}, + {61.561f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch110st[] = +{ + {2,ch110st0}, + {7,ch110st1} +}; + +static const Fl_Glut_StrokeChar ch110 = {70.881f,2,ch110st}; + +/* char: 0x6f */ + +static const Fl_Glut_StrokeVertex ch111st0[] = +{ + {28.7895f,66.6667f}, + {19.2657f,61.9048f}, + {9.7419f,52.381f}, + {4.98f,38.0952f}, + {4.98f,28.5714f}, + {9.7419f,14.2857f}, + {19.2657f,4.7619f}, + {28.7895f,0.0f}, + {43.0752f,0.0f}, + {52.599f,4.7619f}, + {62.1229f,14.2857f}, + {66.8848f,28.5714f}, + {66.8848f,38.0952f}, + {62.1229f,52.381f}, + {52.599f,61.9048f}, + {43.0752f,66.6667f}, + {28.7895f,66.6667f} +}; + +static const Fl_Glut_StrokeStrip ch111st[] = +{ + {17,ch111st0} +}; + +static const Fl_Glut_StrokeChar ch111 = {71.7448f,1,ch111st}; + +/* char: 0x70 */ + +static const Fl_Glut_StrokeVertex ch112st0[] = +{ + {9.46f,66.6667f}, + {9.46f,-33.3333f} +}; + +static const Fl_Glut_StrokeVertex ch112st1[] = +{ + {9.46f,52.381f}, + {18.9838f,61.9048f}, + {28.5076f,66.6667f}, + {42.7933f,66.6667f}, + {52.3171f,61.9048f}, + {61.841f,52.381f}, + {66.6029f,38.0952f}, + {66.6029f,28.5714f}, + {61.841f,14.2857f}, + {52.3171f,4.7619f}, + {42.7933f,0.0f}, + {28.5076f,0.0f}, + {18.9838f,4.7619f}, + {9.46f,14.2857f} +}; + +static const Fl_Glut_StrokeStrip ch112st[] = +{ + {2,ch112st0}, + {14,ch112st1} +}; + +static const Fl_Glut_StrokeChar ch112 = {70.8029f,2,ch112st}; + +/* char: 0x71 */ + +static const Fl_Glut_StrokeVertex ch113st0[] = +{ + {61.9829f,66.6667f}, + {61.9829f,-33.3333f} +}; + +static const Fl_Glut_StrokeVertex ch113st1[] = +{ + {61.9829f,52.381f}, + {52.459f,61.9048f}, + {42.9352f,66.6667f}, + {28.6495f,66.6667f}, + {19.1257f,61.9048f}, + {9.6019f,52.381f}, + {4.84f,38.0952f}, + {4.84f,28.5714f}, + {9.6019f,14.2857f}, + {19.1257f,4.7619f}, + {28.6495f,0.0f}, + {42.9352f,0.0f}, + {52.459f,4.7619f}, + {61.9829f,14.2857f} +}; + +static const Fl_Glut_StrokeStrip ch113st[] = +{ + {2,ch113st0}, + {14,ch113st1} +}; + +static const Fl_Glut_StrokeChar ch113 = {70.7429f,2,ch113st}; + +/* char: 0x72 */ + +static const Fl_Glut_StrokeVertex ch114st0[] = +{ + {9.46f,66.6667f}, + {9.46f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch114st1[] = +{ + {9.46f,38.0952f}, + {14.2219f,52.381f}, + {23.7457f,61.9048f}, + {33.2695f,66.6667f}, + {47.5552f,66.6667f} +}; + +static const Fl_Glut_StrokeStrip ch114st[] = +{ + {2,ch114st0}, + {5,ch114st1} +}; + +static const Fl_Glut_StrokeChar ch114 = {49.4952f,2,ch114st}; + +/* char: 0x73 */ + +static const Fl_Glut_StrokeVertex ch115st0[] = +{ + {57.081f,52.381f}, + {52.319f,61.9048f}, + {38.0333f,66.6667f}, + {23.7476f,66.6667f}, + {9.4619f,61.9048f}, + {4.7f,52.381f}, + {9.4619f,42.8571f}, + {18.9857f,38.0952f}, + {42.7952f,33.3333f}, + {52.319f,28.5714f}, + {57.081f,19.0476f}, + {57.081f,14.2857f}, + {52.319f,4.7619f}, + {38.0333f,0.0f}, + {23.7476f,0.0f}, + {9.4619f,4.7619f}, + {4.7f,14.2857f} +}; + +static const Fl_Glut_StrokeStrip ch115st[] = +{ + {17,ch115st0} +}; + +static const Fl_Glut_StrokeChar ch115 = {62.321f,1,ch115st}; + +/* char: 0x74 */ + +static const Fl_Glut_StrokeVertex ch116st0[] = +{ + {14.8257f,100.0f}, + {14.8257f,19.0476f}, + {19.5876f,4.7619f}, + {29.1114f,0.0f}, + {38.6352f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch116st1[] = +{ + {0.54f,66.6667f}, + {33.8733f,66.6667f} +}; + +static const Fl_Glut_StrokeStrip ch116st[] = +{ + {5,ch116st0}, + {2,ch116st1} +}; + +static const Fl_Glut_StrokeChar ch116 = {39.3152f,2,ch116st}; + +/* char: 0x75 */ + +static const Fl_Glut_StrokeVertex ch117st0[] = +{ + {9.46f,66.6667f}, + {9.46f,19.0476f}, + {14.2219f,4.7619f}, + {23.7457f,0.0f}, + {38.0314f,0.0f}, + {47.5552f,4.7619f}, + {61.841f,19.0476f} +}; + +static const Fl_Glut_StrokeVertex ch117st1[] = +{ + {61.841f,66.6667f}, + {61.841f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch117st[] = +{ + {7,ch117st0}, + {2,ch117st1} +}; + +static const Fl_Glut_StrokeChar ch117 = {71.161f,2,ch117st}; + +/* char: 0x76 */ + +static const Fl_Glut_StrokeVertex ch118st0[] = +{ + {1.8f,66.6667f}, + {30.3714f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch118st1[] = +{ + {58.9429f,66.6667f}, + {30.3714f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch118st[] = +{ + {2,ch118st0}, + {2,ch118st1} +}; + +static const Fl_Glut_StrokeChar ch118 = {60.6029f,2,ch118st}; + +/* char: 0x77 */ + +static const Fl_Glut_StrokeVertex ch119st0[] = +{ + {2.5f,66.6667f}, + {21.5476f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch119st1[] = +{ + {40.5952f,66.6667f}, + {21.5476f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch119st2[] = +{ + {40.5952f,66.6667f}, + {59.6429f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch119st3[] = +{ + {78.6905f,66.6667f}, + {59.6429f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch119st[] = +{ + {2,ch119st0}, + {2,ch119st1}, + {2,ch119st2}, + {2,ch119st3} +}; + +static const Fl_Glut_StrokeChar ch119 = {80.4905f,4,ch119st}; + +/* char: 0x78 */ + +static const Fl_Glut_StrokeVertex ch120st0[] = +{ + {1.66f,66.6667f}, + {54.041f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch120st1[] = +{ + {54.041f,66.6667f}, + {1.66f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch120st[] = +{ + {2,ch120st0}, + {2,ch120st1} +}; + +static const Fl_Glut_StrokeChar ch120 = {56.401f,2,ch120st}; + +/* char: 0x79 */ + +static const Fl_Glut_StrokeVertex ch121st0[] = +{ + {6.5619f,66.6667f}, + {35.1333f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch121st1[] = +{ + {63.7048f,66.6667f}, + {35.1333f,0.0f}, + {25.6095f,-19.0476f}, + {16.0857f,-28.5714f}, + {6.5619f,-33.3333f}, + {1.8f,-33.3333f} +}; + +static const Fl_Glut_StrokeStrip ch121st[] = +{ + {2,ch121st0}, + {6,ch121st1} +}; + +static const Fl_Glut_StrokeChar ch121 = {66.0648f,2,ch121st}; + +/* char: 0x7a */ + +static const Fl_Glut_StrokeVertex ch122st0[] = +{ + {56.821f,66.6667f}, + {4.44f,0.0f} +}; + +static const Fl_Glut_StrokeVertex ch122st1[] = +{ + {4.44f,66.6667f}, + {56.821f,66.6667f} +}; + +static const Fl_Glut_StrokeVertex ch122st2[] = +{ + {4.44f,0.0f}, + {56.821f,0.0f} +}; + +static const Fl_Glut_StrokeStrip ch122st[] = +{ + {2,ch122st0}, + {2,ch122st1}, + {2,ch122st2} +}; + +static const Fl_Glut_StrokeChar ch122 = {61.821f,3,ch122st}; + +/* char: 0x7b */ + +static const Fl_Glut_StrokeVertex ch123st0[] = +{ + {31.1895f,119.048f}, + {21.6657f,114.286f}, + {16.9038f,109.524f}, + {12.1419f,100.0f}, + {12.1419f,90.4762f}, + {16.9038f,80.9524f}, + {21.6657f,76.1905f}, + {26.4276f,66.6667f}, + {26.4276f,57.1429f}, + {16.9038f,47.619f} +}; + +static const Fl_Glut_StrokeVertex ch123st1[] = +{ + {21.6657f,114.286f}, + {16.9038f,104.762f}, + {16.9038f,95.2381f}, + {21.6657f,85.7143f}, + {26.4276f,80.9524f}, + {31.1895f,71.4286f}, + {31.1895f,61.9048f}, + {26.4276f,52.381f}, + {7.38f,42.8571f}, + {26.4276f,33.3333f}, + {31.1895f,23.8095f}, + {31.1895f,14.2857f}, + {26.4276f,4.7619f}, + {21.6657f,0.0f}, + {16.9038f,-9.5238f}, + {16.9038f,-19.0476f}, + {21.6657f,-28.5714f} +}; + +static const Fl_Glut_StrokeVertex ch123st2[] = +{ + {16.9038f,38.0952f}, + {26.4276f,28.5714f}, + {26.4276f,19.0476f}, + {21.6657f,9.5238f}, + {16.9038f,4.7619f}, + {12.1419f,-4.7619f}, + {12.1419f,-14.2857f}, + {16.9038f,-23.8095f}, + {21.6657f,-28.5714f}, + {31.1895f,-33.3333f} +}; + +static const Fl_Glut_StrokeStrip ch123st[] = +{ + {10,ch123st0}, + {17,ch123st1}, + {10,ch123st2} +}; + +static const Fl_Glut_StrokeChar ch123 = {41.6295f,3,ch123st}; + +/* char: 0x7c */ + +static const Fl_Glut_StrokeVertex ch124st0[] = +{ + {11.54f,119.048f}, + {11.54f,-33.3333f} +}; + +static const Fl_Glut_StrokeStrip ch124st[] = +{ + {2,ch124st0} +}; + +static const Fl_Glut_StrokeChar ch124 = {23.78f,1,ch124st}; + +/* char: 0x7d */ + +static const Fl_Glut_StrokeVertex ch125st0[] = +{ + {9.18f,119.048f}, + {18.7038f,114.286f}, + {23.4657f,109.524f}, + {28.2276f,100.0f}, + {28.2276f,90.4762f}, + {23.4657f,80.9524f}, + {18.7038f,76.1905f}, + {13.9419f,66.6667f}, + {13.9419f,57.1429f}, + {23.4657f,47.619f} +}; + +static const Fl_Glut_StrokeVertex ch125st1[] = +{ + {18.7038f,114.286f}, + {23.4657f,104.762f}, + {23.4657f,95.2381f}, + {18.7038f,85.7143f}, + {13.9419f,80.9524f}, + {9.18f,71.4286f}, + {9.18f,61.9048f}, + {13.9419f,52.381f}, + {32.9895f,42.8571f}, + {13.9419f,33.3333f}, + {9.18f,23.8095f}, + {9.18f,14.2857f}, + {13.9419f,4.7619f}, + {18.7038f,0.0f}, + {23.4657f,-9.5238f}, + {23.4657f,-19.0476f}, + {18.7038f,-28.5714f} +}; + +static const Fl_Glut_StrokeVertex ch125st2[] = +{ + {23.4657f,38.0952f}, + {13.9419f,28.5714f}, + {13.9419f,19.0476f}, + {18.7038f,9.5238f}, + {23.4657f,4.7619f}, + {28.2276f,-4.7619f}, + {28.2276f,-14.2857f}, + {23.4657f,-23.8095f}, + {18.7038f,-28.5714f}, + {9.18f,-33.3333f} +}; + +static const Fl_Glut_StrokeStrip ch125st[] = +{ + {10,ch125st0}, + {17,ch125st1}, + {10,ch125st2} +}; + +static const Fl_Glut_StrokeChar ch125 = {41.4695f,3,ch125st}; + +/* char: 0x7e */ + +static const Fl_Glut_StrokeVertex ch126st0[] = +{ + {2.92f,28.5714f}, + {2.92f,38.0952f}, + {7.6819f,52.381f}, + {17.2057f,57.1429f}, + {26.7295f,57.1429f}, + {36.2533f,52.381f}, + {55.301f,38.0952f}, + {64.8248f,33.3333f}, + {74.3486f,33.3333f}, + {83.8724f,38.0952f}, + {88.6343f,47.619f} +}; + +static const Fl_Glut_StrokeVertex ch126st1[] = +{ + {2.92f,38.0952f}, + {7.6819f,47.619f}, + {17.2057f,52.381f}, + {26.7295f,52.381f}, + {36.2533f,47.619f}, + {55.301f,33.3333f}, + {64.8248f,28.5714f}, + {74.3486f,28.5714f}, + {83.8724f,33.3333f}, + {88.6343f,47.619f}, + {88.6343f,57.1429f} +}; + +static const Fl_Glut_StrokeStrip ch126st[] = +{ + {11,ch126st0}, + {11,ch126st1} +}; + +static const Fl_Glut_StrokeChar ch126 = {91.2743f,2,ch126st}; + +/* char: 0x7f */ + +static const Fl_Glut_StrokeVertex ch127st0[] = +{ + {52.381f,100.0f}, + {14.2857f,-33.3333f} +}; + +static const Fl_Glut_StrokeVertex ch127st1[] = +{ + {28.5714f,66.6667f}, + {14.2857f,61.9048f}, + {4.7619f,52.381f}, + {0.0f,38.0952f}, + {0.0f,23.8095f}, + {4.7619f,14.2857f}, + {14.2857f,4.7619f}, + {28.5714f,0.0f}, + {38.0952f,0.0f}, + {52.381f,4.7619f}, + {61.9048f,14.2857f}, + {66.6667f,28.5714f}, + {66.6667f,42.8571f}, + {61.9048f,52.381f}, + {52.381f,61.9048f}, + {38.0952f,66.6667f}, + {28.5714f,66.6667f} +}; + +static const Fl_Glut_StrokeStrip ch127st[] = +{ + {2,ch127st0}, + {17,ch127st1} +}; + +static const Fl_Glut_StrokeChar ch127 = {66.6667f,2,ch127st}; + +static const Fl_Glut_StrokeChar *chars[] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + &ch32, &ch33, &ch34, &ch35, &ch36, &ch37, &ch38, &ch39, + &ch40, &ch41, &ch42, &ch43, &ch44, &ch45, &ch46, &ch47, + &ch48, &ch49, &ch50, &ch51, &ch52, &ch53, &ch54, &ch55, + &ch56, &ch57, &ch58, &ch59, &ch60, &ch61, &ch62, &ch63, + &ch64, &ch65, &ch66, &ch67, &ch68, &ch69, &ch70, &ch71, + &ch72, &ch73, &ch74, &ch75, &ch76, &ch77, &ch78, &ch79, + &ch80, &ch81, &ch82, &ch83, &ch84, &ch85, &ch86, &ch87, + &ch88, &ch89, &ch90, &ch91, &ch92, &ch93, &ch94, &ch95, + &ch96, &ch97, &ch98, &ch99, &ch100, &ch101, &ch102, &ch103, + &ch104, &ch105, &ch106, &ch107, &ch108, &ch109, &ch110, &ch111, + &ch112, &ch113, &ch114, &ch115, &ch116, &ch117, &ch118, &ch119, + &ch120, &ch121, &ch122, &ch123, &ch124, &ch125, &ch126, &ch127 +}; + +Fl_Glut_StrokeFont glutStrokeRoman = {(char *)"Roman",128,152.381f,chars}; diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/freeglut_teapot.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/freeglut_teapot.cxx new file mode 100644 index 0000000..76b4d6c --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/freeglut_teapot.cxx @@ -0,0 +1,164 @@ +/* + * freeglut_teapot.c + * + * Teapot(tm) rendering code. + * + * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved. + * Written by Pawel W. Olszta, + * Creation date: Fri Dec 24 1999 + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * Original teapot code copyright follows: + */ + +/* + * (c) Copyright 1993, Silicon Graphics, Inc. + * + * ALL RIGHTS RESERVED + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation, and that the name of Silicon + * Graphics, Inc. not be used in advertising or publicity + * pertaining to distribution of the software without specific, + * written prior permission. + * + * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU + * "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR + * OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF + * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO + * EVENT SHALL SILICON GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE + * ELSE FOR ANY DIRECT, SPECIAL, INCIDENTAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER, + * INCLUDING WITHOUT LIMITATION, LOSS OF PROFIT, LOSS OF USE, + * SAVINGS OR REVENUE, OR THE CLAIMS OF THIRD PARTIES, WHETHER OR + * NOT SILICON GRAPHICS, INC. HAS BEEN ADVISED OF THE POSSIBILITY + * OF SUCH LOSS, HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * ARISING OUT OF OR IN CONNECTION WITH THE POSSESSION, USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * US Government Users Restricted Rights + * + * Use, duplication, or disclosure by the Government is subject to + * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph + * (c)(1)(ii) of the Rights in Technical Data and Computer + * Software clause at DFARS 252.227-7013 and/or in similar or + * successor clauses in the FAR or the DOD or NASA FAR + * Supplement. Unpublished-- rights reserved under the copyright + * laws of the United States. Contractor/manufacturer is Silicon + * Graphics, Inc., 2011 N. Shoreline Blvd., Mountain View, CA + * 94039-7311. + * + * OpenGL(TM) is a trademark of Silicon Graphics, Inc. + */ + +#include +#include "freeglut_teapot_data.h" + +/* -- PRIVATE FUNCTIONS ---------------------------------------------------- */ + + +static void fghTeapot( GLint grid, GLdouble scale, GLenum type ) +{ + double p[4][4][3], q[4][4][3], r[4][4][3], s[4][4][3]; + long i, j, k, l; + + glPushAttrib( GL_ENABLE_BIT | GL_EVAL_BIT ); + glEnable( GL_AUTO_NORMAL ); + glEnable( GL_NORMALIZE ); + glEnable( GL_MAP2_VERTEX_3 ); + glEnable( GL_MAP2_TEXTURE_COORD_2 ); + + glPushMatrix(); + glRotated( 270.0, 1.0, 0.0, 0.0 ); + glScaled( 0.5 * scale, 0.5 * scale, 0.5 * scale ); + glTranslated( 0.0, 0.0, -1.5 ); + + for (i = 0; i < 10; i++) { + for (j = 0; j < 4; j++) { + for (k = 0; k < 4; k++) { + for (l = 0; l < 3; l++) { + p[j][k][l] = cpdata[patchdata[i][j * 4 + k]][l]; + q[j][k][l] = cpdata[patchdata[i][j * 4 + (3 - k)]][l]; + if (l == 1) + q[j][k][l] *= -1.0; + if (i < 6) { + r[j][k][l] = + cpdata[patchdata[i][j * 4 + (3 - k)]][l]; + if (l == 0) + r[j][k][l] *= -1.0; + s[j][k][l] = cpdata[patchdata[i][j * 4 + k]][l]; + if (l == 0) + s[j][k][l] *= -1.0; + if (l == 1) + s[j][k][l] *= -1.0; + } + } + } + } + + glMap2d(GL_MAP2_TEXTURE_COORD_2, 0.0, 1.0, 2, 2, 0.0, 1.0, 4, 2, + &tex[0][0][0]); + glMap2d(GL_MAP2_VERTEX_3, 0.0, 1.0, 3, 4, 0.0, 1.0, 12, 4, + &p[0][0][0]); + glMapGrid2d(grid, 0.0, 1.0, grid, 0.0, 1.0); + glEvalMesh2(type, 0, grid, 0, grid); + glMap2d(GL_MAP2_VERTEX_3, 0.0, 1.0, 3, 4, 0.0, 1.0, 12, 4, + &q[0][0][0]); + glEvalMesh2(type, 0, grid, 0, grid); + if (i < 6) { + glMap2d(GL_MAP2_VERTEX_3, 0.0, 1.0, 3, 4, 0.0, 1.0, 12, 4, + &r[0][0][0]); + glEvalMesh2(type, 0, grid, 0, grid); + glMap2d(GL_MAP2_VERTEX_3, 0.0, 1.0, 3, 4, 0.0, 1.0, 12, 4, + &s[0][0][0]); + glEvalMesh2(type, 0, grid, 0, grid); + } + } + + glPopMatrix(); + glPopAttrib(); +} + + +/* -- INTERFACE FUNCTIONS -------------------------------------------------- */ + +/* + * Renders a beautiful wired teapot... + */ +void glutWireTeapot( GLdouble size ) +{ + /* We will use the general teapot rendering code */ + fghTeapot( 10, size, GL_LINE ); +} + +/* + * Renders a beautiful filled teapot... + */ +void glutSolidTeapot( GLdouble size ) +{ + /* We will use the general teapot rendering code */ + fghTeapot( 7, size, GL_FILL ); +} + +/*** END OF FILE ***/ diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/freeglut_teapot_data.h b/mod/maxgui.mod/fltkmaxgui.mod/src/freeglut_teapot_data.h new file mode 100644 index 0000000..14e72ee --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/freeglut_teapot_data.h @@ -0,0 +1,145 @@ +/* + * freeglut_teapot_data.h + * + * The freeglut library teapot data include file. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef FREEGLUT_TEAPOT_DATA_H +#define FREEGLUT_TEAPOT_DATA_H + +/* + * Original teapot code copyright follows: + */ + +/* + * (c) Copyright 1993, Silicon Graphics, Inc. + * + * ALL RIGHTS RESERVED + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation, and that the name of Silicon + * Graphics, Inc. not be used in advertising or publicity + * pertaining to distribution of the software without specific, + * written prior permission. + * + * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU + * "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR + * OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF + * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO + * EVENT SHALL SILICON GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE + * ELSE FOR ANY DIRECT, SPECIAL, INCIDENTAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER, + * INCLUDING WITHOUT LIMITATION, LOSS OF PROFIT, LOSS OF USE, + * SAVINGS OR REVENUE, OR THE CLAIMS OF THIRD PARTIES, WHETHER OR + * NOT SILICON GRAPHICS, INC. HAS BEEN ADVISED OF THE POSSIBILITY + * OF SUCH LOSS, HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * ARISING OUT OF OR IN CONNECTION WITH THE POSSESSION, USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * US Government Users Restricted Rights + * + * Use, duplication, or disclosure by the Government is subject to + * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph + * (c)(1)(ii) of the Rights in Technical Data and Computer + * Software clause at DFARS 252.227-7013 and/or in similar or + * successor clauses in the FAR or the DOD or NASA FAR + * Supplement. Unpublished-- rights reserved under the copyright + * laws of the United States. Contractor/manufacturer is Silicon + * Graphics, Inc., 2011 N. Shoreline Blvd., Mountain View, CA + * 94039-7311. + * + * OpenGL(TM) is a trademark of Silicon Graphics, Inc. + */ + +/* + * Rim, body, lid, and bottom data must be reflected in x and y; + * handle and spout data across the y axis only. + */ +static int patchdata[][16] = +{ + { 102, 103, 104, 105, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, /* rim */ + { 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27 }, /* body */ + { 24, 25, 26, 27, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 }, + { 96, 96, 96, 96, 97, 98, 99, 100, 101, 101, 101, 101, 0, 1, 2, 3 }, /* lid */ + { 0, 1, 2, 3, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117 }, + { 118, 118, 118, 118, 124, 122, 119, 121, 123, 126, 125, 120, 40, 39, 38, 37 }, /* bottom */ + { 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56 }, /* handle */ + { 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 28, 65, 66, 67 }, + { 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83 }, /* spout */ + { 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95 } +}; + +static double cpdata[][3] = +{ + {0.2, 0, 2.7}, {0.2, -0.112, 2.7}, {0.112, -0.2, 2.7}, {0, + -0.2, 2.7}, {1.3375, 0, 2.53125}, {1.3375, -0.749, 2.53125}, + {0.749, -1.3375, 2.53125}, {0, -1.3375, 2.53125}, {1.4375, + 0, 2.53125}, {1.4375, -0.805, 2.53125}, {0.805, -1.4375, + 2.53125}, {0, -1.4375, 2.53125}, {1.5, 0, 2.4}, {1.5, -0.84, + 2.4}, {0.84, -1.5, 2.4}, {0, -1.5, 2.4}, {1.75, 0, 1.875}, + {1.75, -0.98, 1.875}, {0.98, -1.75, 1.875}, {0, -1.75, + 1.875}, {2, 0, 1.35}, {2, -1.12, 1.35}, {1.12, -2, 1.35}, + {0, -2, 1.35}, {2, 0, 0.9}, {2, -1.12, 0.9}, {1.12, -2, + 0.9}, {0, -2, 0.9}, {-2, 0, 0.9}, {2, 0, 0.45}, {2, -1.12, + 0.45}, {1.12, -2, 0.45}, {0, -2, 0.45}, {1.5, 0, 0.225}, + {1.5, -0.84, 0.225}, {0.84, -1.5, 0.225}, {0, -1.5, 0.225}, + {1.5, 0, 0.15}, {1.5, -0.84, 0.15}, {0.84, -1.5, 0.15}, {0, + -1.5, 0.15}, {-1.6, 0, 2.025}, {-1.6, -0.3, 2.025}, {-1.5, + -0.3, 2.25}, {-1.5, 0, 2.25}, {-2.3, 0, 2.025}, {-2.3, -0.3, + 2.025}, {-2.5, -0.3, 2.25}, {-2.5, 0, 2.25}, {-2.7, 0, + 2.025}, {-2.7, -0.3, 2.025}, {-3, -0.3, 2.25}, {-3, 0, + 2.25}, {-2.7, 0, 1.8}, {-2.7, -0.3, 1.8}, {-3, -0.3, 1.8}, + {-3, 0, 1.8}, {-2.7, 0, 1.575}, {-2.7, -0.3, 1.575}, {-3, + -0.3, 1.35}, {-3, 0, 1.35}, {-2.5, 0, 1.125}, {-2.5, -0.3, + 1.125}, {-2.65, -0.3, 0.9375}, {-2.65, 0, 0.9375}, {-2, + -0.3, 0.9}, {-1.9, -0.3, 0.6}, {-1.9, 0, 0.6}, {1.7, 0, + 1.425}, {1.7, -0.66, 1.425}, {1.7, -0.66, 0.6}, {1.7, 0, + 0.6}, {2.6, 0, 1.425}, {2.6, -0.66, 1.425}, {3.1, -0.66, + 0.825}, {3.1, 0, 0.825}, {2.3, 0, 2.1}, {2.3, -0.25, 2.1}, + {2.4, -0.25, 2.025}, {2.4, 0, 2.025}, {2.7, 0, 2.4}, {2.7, + -0.25, 2.4}, {3.3, -0.25, 2.4}, {3.3, 0, 2.4}, {2.8, 0, + 2.475}, {2.8, -0.25, 2.475}, {3.525, -0.25, 2.49375}, + {3.525, 0, 2.49375}, {2.9, 0, 2.475}, {2.9, -0.15, 2.475}, + {3.45, -0.15, 2.5125}, {3.45, 0, 2.5125}, {2.8, 0, 2.4}, + {2.8, -0.15, 2.4}, {3.2, -0.15, 2.4}, {3.2, 0, 2.4}, {0, 0, + 3.15}, {0.8, 0, 3.15}, {0.8, -0.45, 3.15}, {0.45, -0.8, + 3.15}, {0, -0.8, 3.15}, {0, 0, 2.85}, {1.4, 0, 2.4}, {1.4, + -0.784, 2.4}, {0.784, -1.4, 2.4}, {0, -1.4, 2.4}, {0.4, 0, + 2.55}, {0.4, -0.224, 2.55}, {0.224, -0.4, 2.55}, {0, -0.4, + 2.55}, {1.3, 0, 2.55}, {1.3, -0.728, 2.55}, {0.728, -1.3, + 2.55}, {0, -1.3, 2.55}, {1.3, 0, 2.4}, {1.3, -0.728, 2.4}, + {0.728, -1.3, 2.4}, {0, -1.3, 2.4}, {0, 0, 0}, {1.425, + -0.798, 0}, {1.5, 0, 0.075}, {1.425, 0, 0}, {0.798, -1.425, + 0}, {0, -1.5, 0.075}, {0, -1.425, 0}, {1.5, -0.84, 0.075}, + {0.84, -1.5, 0.075} +}; + +static double tex[2][2][2] = +{ + { {0.0, 0.0}, {1.0, 0.0} }, + { {0.0, 1.0}, {1.0, 1.0} } +}; + + +#endif /* FREEGLUT_TEAPOT_DATA_H */ + diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/gl_draw.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/gl_draw.cxx new file mode 100644 index 0000000..631ea63 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/gl_draw.cxx @@ -0,0 +1,567 @@ +// +// "$Id: gl_draw.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// OpenGL drawing support routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Functions from +// See also Fl_Gl_Window and gl_start.cxx + +#include "flstring.h" +#if HAVE_GL || defined(FL_DOXYGEN) + +#include +#include +#include +#include +#include "Fl_Gl_Choice.H" +#include "Fl_Font.H" +#include + +#if !defined(WIN32) && !defined(__APPLE__) +#include +#endif + +#if USE_XFT +extern XFontStruct* fl_xxfont(); +#endif // USE_XFT + +/** Returns the current font's height */ +int gl_height() {return fl_height();} +/** Returns the current font's descent */ +int gl_descent() {return fl_descent();} +/** Returns the width of the string in the current fnt */ +double gl_width(const char* s) {return fl_width(s);} +/** Returns the width of n characters of the string in the current font */ +double gl_width(const char* s, int n) {return fl_width(s,n);} +/** Returns the width of the character in the current font */ +double gl_width(uchar c) {return fl_width(c);} + +static Fl_Font_Descriptor *gl_fontsize; + +#define GL_DRAW_USES_TEXTURES (defined(__APPLE__) && !__ppc__) // 1 only for non-PPC OSX +#ifndef __APPLE__ +# define USE_OksiD_style_GL_font_selection 1 // Most hosts except OSX +#else +# undef USE_OksiD_style_GL_font_selection // OSX +#endif + +#if USE_XFT +# undef USE_OksiD_style_GL_font_selection // turn this off for XFT also +#endif + +/** + Sets the current OpenGL font to the same font as calling fl_font() + */ +void gl_font(int fontid, int size) { + fl_font(fontid, size); +#if !GL_DRAW_USES_TEXTURES + if (!fl_fontsize->listbase) { + +#ifdef USE_OksiD_style_GL_font_selection + fl_fontsize->listbase = glGenLists(0x10000); +#else // Fltk-1.1.8 style GL font selection + +#if defined (USE_X11) // X-windows options follow, either XFT or "plain" X +// FIXME: warning Ideally, for XFT, we really need a glXUseXftFont implementation here... +// FIXME: warning GL font selection is basically wrong here +/* OksiD had a fairly sophisticated scheme for storing multiple X fonts in a XUtf8FontStruct, + * then sorting through them at draw time (for normal X rendering) to find which one can + * render the current glyph... But for now, just use the first font in the list for GL... + */ + XFontStruct *font = fl_xfont; + int base = font->min_char_or_byte2; + int count = font->max_char_or_byte2-base+1; + fl_fontsize->listbase = glGenLists(256); + glXUseXFont(font->fid, base, count, fl_fontsize->listbase+base); +# elif defined(WIN32) + // this is unused because USE_OksiD_style_GL_font_selection == 1 + int base = fl_fontsize->metr.tmFirstChar; + int count = fl_fontsize->metr.tmLastChar-base+1; + HFONT oldFid = (HFONT)SelectObject(fl_gc, fl_fontsize->fid); + fl_fontsize->listbase = glGenLists(256); + wglUseFontBitmaps(fl_gc, base, count, fl_fontsize->listbase+base); + SelectObject(fl_gc, oldFid); +# elif defined(__APPLE_QUARTZ__) +//AGL is not supported for use in 64-bit applications: +//http://developer.apple.com/mac/library/documentation/Carbon/Conceptual/Carbon64BitGuide/OtherAPIChanges/OtherAPIChanges.html + short font, face, size; + uchar fn[256]; + fn[0]=strlen(fl_fontsize->q_name); + strcpy((char*)(fn+1), fl_fontsize->q_name); + GetFNum(fn, &font); + face = 0; + size = fl_fontsize->size; + fl_fontsize->listbase = glGenLists(256); + aglUseFont(aglGetCurrentContext(), font, face, + size, 0, 256, fl_fontsize->listbase); +# else +# error unsupported platform +# endif + +#endif // USE_OksiD_style_GL_font_selection + } + glListBase(fl_fontsize->listbase); +#endif // !GL_DRAW_USES_TEXTURES + gl_fontsize = fl_fontsize; +} + +#ifndef __APPLE__ +static void get_list(int r) { + gl_fontsize->glok[r] = 1; +#if defined(USE_X11) +# if USE_XFT +// FIXME +# else + unsigned int ii = r * 0x400; + for (int i = 0; i < 0x400; i++) { + XFontStruct *font = NULL; + unsigned short id; + XGetUtf8FontAndGlyph(gl_fontsize->font, ii, &font, &id); + if (font) glXUseXFont(font->fid, id, 1, gl_fontsize->listbase+ii); + ii++; + } +# endif +#elif defined(WIN32) + unsigned int ii = r * 0x400; + HFONT oldFid = (HFONT)SelectObject(fl_gc, gl_fontsize->fid); + wglUseFontBitmapsW(fl_gc, ii, ii + 0x03ff, gl_fontsize->listbase+ii); + SelectObject(fl_gc, oldFid); +#elif defined(__APPLE_QUARTZ__) +// handled by textures +#else +# error unsupported platform +#endif +} // get_list +#endif + +void gl_remove_displaylist_fonts() +{ +# if HAVE_GL + + // clear variables used mostly in fl_font + fl_font_ = 0; + fl_size_ = 0; + + for (int j = 0 ; j < FL_FREE_FONT ; ++j) + { + Fl_Font_Descriptor* past = 0; + Fl_Fontdesc* s = fl_fonts + j ; + Fl_Font_Descriptor* f = s->first; + while (f != 0) { + if(f->listbase) { + if(f == s->first) { + s->first = f->next; + } + else { + past->next = f->next; + } + + // It would be nice if this next line was in a desctructor somewhere + glDeleteLists(f->listbase, 256); + + Fl_Font_Descriptor* tmp = f; + f = f->next; + delete tmp; + } + else { + past = f; + f = f->next; + } + } + } + +#endif +} + +#if GL_DRAW_USES_TEXTURES +static void gl_draw_textures(const char* str, int n); +#endif + +/** + Draws an array of n characters of the string in the current font + at the current position. + \see On the Mac OS X platform, see gl_texture_pile_height(int) + */ +void gl_draw(const char* str, int n) { +#ifdef __APPLE__ + +#if GL_DRAW_USES_TEXTURES + gl_draw_textures(str, n); +#else + glCallLists(n, GL_UNSIGNED_BYTE, str); +#endif + +#else + static xchar *buf = NULL; + static int l = 0; + int wn = fl_utf8toUtf16(str, n, (unsigned short*)buf, l); + if(wn >= l) { + buf = (xchar*) realloc(buf, sizeof(xchar) * (wn + 1)); + l = wn + 1; + wn = fl_utf8toUtf16(str, n, (unsigned short*)buf, l); + } + n = wn; + + int i; + for (i = 0; i < n; i++) { + unsigned int r; + r = (str[i] & 0xFC00) >> 10; + if (!gl_fontsize->glok[r]) get_list(r); + } + glCallLists(n, GL_UNSIGNED_SHORT, buf); +#endif +} + +/** + Draws n characters of the string in the current font at the given position + \see On the Mac OS X platform, see gl_texture_pile_height(int) + */ +void gl_draw(const char* str, int n, int x, int y) { + glRasterPos2i(x, y); + gl_draw(str, n); +} + +/** + Draws n characters of the string in the current font at the given position + \see On the Mac OS X platform, see gl_texture_pile_height(int) + */ +void gl_draw(const char* str, int n, float x, float y) { + glRasterPos2f(x, y); + gl_draw(str, n); +} + +/** + Draws a nul-terminated string in the current font at the current position + \see On the Mac OS X platform, see gl_texture_pile_height(int) + */ +void gl_draw(const char* str) { + gl_draw(str, strlen(str)); +} + +/** + Draws a nul-terminated string in the current font at the given position + \see On the Mac OS X platform, see gl_texture_pile_height(int) + */ +void gl_draw(const char* str, int x, int y) { + gl_draw(str, strlen(str), x, y); +} + +/** + Draws a nul-terminated string in the current font at the given position + \see On the Mac OS X platform, see gl_texture_pile_height(int) + */ +void gl_draw(const char* str, float x, float y) { + gl_draw(str, strlen(str), x, y); +} + +static void gl_draw_invert(const char* str, int n, int x, int y) { + glRasterPos2i(x, -y); + gl_draw(str, n); +} + +/** + Draws a string formatted into a box, with newlines and tabs expanded, + other control characters changed to ^X. and aligned with the edges or + center. Exactly the same output as fl_draw(). + */ +void gl_draw( + const char* str, // the (multi-line) string + int x, int y, int w, int h, // bounding box + Fl_Align align) { + fl_draw(str, x, -y-h, w, h, align, gl_draw_invert); +} + +/** Measure how wide and tall the string will be when drawn by the gl_draw() function */ +void gl_measure(const char* str, int& x, int& y) {fl_measure(str,x,y);} + +/** + Outlines the given rectangle with the current color. + If Fl_Gl_Window::ortho() has been called, then the rectangle will + exactly fill the given pixel rectangle. + */ +void gl_rect(int x, int y, int w, int h) { + if (w < 0) {w = -w; x = x-w;} + if (h < 0) {h = -h; y = y-h;} + glBegin(GL_LINE_STRIP); + glVertex2i(x+w-1, y+h-1); + glVertex2i(x+w-1, y); + glVertex2i(x, y); + glVertex2i(x, y+h-1); + glVertex2i(x+w, y+h-1); + glEnd(); +} + +#if HAVE_GL_OVERLAY +extern uchar fl_overlay; +extern int fl_overlay_depth; +#endif + +/** + Sets the curent OpenGL color to an FLTK color. + + For color-index modes it will use fl_xpixel(c), which is only + right if the window uses the default colormap! + */ +void gl_color(Fl_Color i) { +#if HAVE_GL_OVERLAY +#if defined(WIN32) + if (fl_overlay && fl_overlay_depth) { + if (fl_overlay_depth < 8) { + // only black & white produce the expected colors. This could + // be improved by fixing the colormap set in Fl_Gl_Overlay.cxx + int size = 1<= size-2) glIndexi(size-1); + else glIndexi(i); + } else { + glIndexi(i ? i : FL_GRAY_RAMP); + } + return; + } +#else + if (fl_overlay) {glIndexi(int(fl_xpixel(i))); return;} +#endif +#endif + uchar red, green, blue; + Fl::get_color(i, red, green, blue); + glColor3ub(red, green, blue); +} + +void gl_draw_image(const uchar* b, int x, int y, int w, int h, int d, int ld) { + if (!ld) ld = w*d; + glPixelStorei(GL_UNPACK_ROW_LENGTH, ld/d); + glRasterPos2i(x,y); + glDrawPixels(w,h,d<4?GL_RGB:GL_RGBA,GL_UNSIGNED_BYTE,(const ulong*)b); +} + +#if GL_DRAW_USES_TEXTURES || defined(FL_DOXYGEN) + +#include + +// manages a fifo pile of pre-computed string textures +class gl_texture_fifo { + friend void gl_draw_textures(const char *, int); +private: + typedef struct { // information for a pre-computed texture + GLuint texName; // its name + char *utf8; //its text + Fl_Font_Descriptor *fdesc; // its font + int width; // its width + int height; // its height + } data; + data *fifo; // array of pile elements + int size_; // pile height + int current; // the oldest texture to have entered the pile + int last; // pile top + int textures_generated; // true iff glGenTextures has been called + void display_texture(int rank); + int compute_texture(const char* str, int n); + int already_known(const char *str, int n); +public: + gl_texture_fifo(int max = 100); // 100 = default height of texture pile + inline int size(void) {return size_; }; + ~gl_texture_fifo(void); +}; + +gl_texture_fifo::gl_texture_fifo(int max) +{ + size_ = max; + last = current = -1; + textures_generated = 0; + fifo = (data*)calloc(size_, sizeof(data)); +} + +gl_texture_fifo::~gl_texture_fifo() +{ + for (int i = 0; i < size_; i++) { + if (fifo[i].utf8) free(fifo[i].utf8); + if (textures_generated) glDeleteTextures(1, &fifo[i].texName); + } + free(fifo); +} + +// displays a pre-computed texture on the GL scene +void gl_texture_fifo::display_texture(int rank) +{ + //setup matrices + GLint matrixMode; + glGetIntegerv (GL_MATRIX_MODE, &matrixMode); + glMatrixMode (GL_PROJECTION); + glPushMatrix(); + glLoadIdentity (); + glMatrixMode (GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity (); + float winw = Fl_Window::current()->w(); + float winh = Fl_Window::current()->h(); + glScalef (2.0f / winw, 2.0f / winh, 1.0f); + glTranslatef (-winw / 2.0f, -winh / 2.0f, 0.0f); + //write the texture on screen + GLfloat pos[4]; + glGetFloatv(GL_CURRENT_RASTER_POSITION, pos); + CGRect bounds = CGRectMake (pos[0], pos[1] - fl_descent(), fifo[rank].width, fifo[rank].height); + + // GL_COLOR_BUFFER_BIT for glBlendFunc, GL_ENABLE_BIT for glEnable / glDisable + glPushAttrib(GL_ENABLE_BIT | GL_TEXTURE_BIT | GL_COLOR_BUFFER_BIT); + glDisable (GL_DEPTH_TEST); // ensure text is not removed by depth buffer test. + glEnable (GL_BLEND); // for text fading + glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA); // ditto + glEnable (GL_TEXTURE_RECTANGLE_EXT); + glDisable(GL_LIGHTING); + glBindTexture (GL_TEXTURE_RECTANGLE_EXT, fifo[rank].texName); + glBegin (GL_QUADS); + glTexCoord2f (0.0f, 0.0f); // draw lower left in world coordinates + glVertex2f (bounds.origin.x, bounds.origin.y); + + glTexCoord2f (0.0f, fifo[rank].height); // draw upper left in world coordinates + glVertex2f (bounds.origin.x, bounds.origin.y + bounds.size.height); + + glTexCoord2f (fifo[rank].width, fifo[rank].height); // draw upper right in world coordinates + glVertex2f (bounds.origin.x + bounds.size.width, bounds.origin.y + bounds.size.height); + + glTexCoord2f (fifo[rank].width, 0.0f); // draw lower right in world coordinates + glVertex2f (bounds.origin.x + bounds.size.width, bounds.origin.y); + glEnd (); + glPopAttrib(); + + // reset original matrices + glPopMatrix(); // GL_MODELVIEW + glMatrixMode (GL_PROJECTION); + glPopMatrix(); + glMatrixMode (matrixMode); + + //set the raster position to end of string + pos[0] += fifo[rank].width; + GLdouble modelmat[16]; + glGetDoublev (GL_MODELVIEW_MATRIX, modelmat); + GLdouble projmat[16]; + glGetDoublev (GL_PROJECTION_MATRIX, projmat); + GLdouble objX, objY, objZ; + GLint viewport[4]; + glGetIntegerv (GL_VIEWPORT, viewport); + gluUnProject(pos[0], pos[1], pos[2], modelmat, projmat, viewport, &objX, &objY, &objZ); + glRasterPos2d(objX, objY); +} + +// pre-computes a string texture +int gl_texture_fifo::compute_texture(const char* str, int n) +{ + current = (current + 1) % size_; + if (current > last) last = current; + //write str to a bitmap just big enough + if ( fifo[current].utf8 ) free(fifo[current].utf8); + fifo[current].utf8 = (char *)malloc(n + 1); + memcpy(fifo[current].utf8, str, n); + fifo[current].utf8[n] = 0; + fifo[current].width = 0, fifo[current].height = 0; + fl_measure(fifo[current].utf8, fifo[current].width, fifo[current].height, 0); + CGColorSpaceRef lut = CGColorSpaceCreateDeviceRGB(); + void *base = calloc(4*fifo[current].width, fifo[current].height); + if (base == NULL) return -1; + fl_gc = CGBitmapContextCreate(base, fifo[current].width, fifo[current].height, 8, fifo[current].width*4, lut, kCGImageAlphaPremultipliedLast); + CGColorSpaceRelease(lut); + fl_fontsize = gl_fontsize; + GLfloat colors[4]; + glGetFloatv(GL_CURRENT_COLOR, colors); + fl_color(colors[0]*255, colors[1]*255, colors[2]*255); + fl_draw(str, n, 0, fifo[current].height - fl_descent()); + //put this bitmap in a texture + glPushAttrib(GL_TEXTURE_BIT); + glBindTexture (GL_TEXTURE_RECTANGLE_EXT, fifo[current].texName); + glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA, fifo[current].width, fifo[current].height, 0, GL_RGBA, GL_UNSIGNED_BYTE, base); + glPopAttrib(); + CGContextRelease(fl_gc); + fl_gc = NULL; + free(base); + fifo[current].fdesc = gl_fontsize; + return current; +} + +// returns rank of pre-computed texture for a string if it exists +int gl_texture_fifo::already_known(const char *str, int n) +{ + int rank; + for ( rank = 0; rank <= last; rank++) { + if ( memcmp(str, fifo[rank].utf8, n) == 0 && fifo[rank].utf8[n] == 0 && + fifo[rank].fdesc == gl_fontsize) return rank; + } + return -1; +} + +static gl_texture_fifo *gl_fifo = NULL; // points to the texture pile class instance + +// draws a utf8 string using pre-computed texture if available +static void gl_draw_textures(const char* str, int n) +{ + if (! gl_fifo) gl_fifo = new gl_texture_fifo(); + if (!gl_fifo->textures_generated) { + for (int i = 0; i < gl_fifo->size_; i++) glGenTextures (1, &(gl_fifo->fifo[i].texName)); + gl_fifo->textures_generated = 1; + } + int rank = gl_fifo->already_known(str, n); + if (rank == -1) { + rank = gl_fifo->compute_texture(str, n); + } + gl_fifo->display_texture(rank); +} + +/** \addtogroup group_macosx + @{ */ + +/** + \brief Returns the current height of the pile of pre-computed string textures + * + The default value is 100 + */ +int gl_texture_pile_height(void) +{ + if (! gl_fifo) gl_fifo = new gl_texture_fifo(); + return gl_fifo->size(); +} + +/** + \brief Changes the height of the pile of pre-computed string textures + * + Strings that are often re-displayed can be processed much faster if + this pile is set high enough to hold all of them. + \param max Height of the texture pile + */ +void gl_texture_pile_height(int max) +{ + if (gl_fifo) delete gl_fifo; + gl_fifo = new gl_texture_fifo(max); +} + +/** @} */ + +#endif // GL_DRAW_USES_TEXTURES + +#endif // HAVE_GL + +// +// End of "$Id: gl_draw.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/gl_start.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/gl_start.cxx new file mode 100644 index 0000000..b4c8c2f --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/gl_start.cxx @@ -0,0 +1,134 @@ +// +// "$Id: gl_start.cxx 6749 2009-04-09 20:44:31Z engelsman $" +// +// OpenGL context routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2009 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// You MUST use gl_visual() to select the default visual before doing +// show() of any windows. Mesa will crash if you try to use a visual +// not returned by glxChooseVisual. + +// This does not work with Fl_Double_Window's! It will try to draw +// into the front buffer. Depending on the system this will either +// crash or do nothing (when pixmaps are being used as back buffer +// and GL is being done by hardware), work correctly (when GL is done +// with software, such as Mesa), or draw into the front buffer and +// be erased when the buffers are swapped (when double buffer hardware +// is being used) + +#include +#if HAVE_GL + +#include +#include +#include +#include +#include "Fl_Gl_Choice.H" + +extern int fl_clip_state_number; // in fl_rect.cxx + +static GLContext context; +static int clip_state_number=-1; +static int pw, ph; + +#ifdef WIN32 +static Fl_Gl_Choice* gl_choice; +#endif + +#ifdef __APPLE__ +static Fl_Gl_Choice* gl_choice; +#endif + +Fl_Region XRectangleRegion(int x, int y, int w, int h); // in fl_rect.cxx + +/** Creates an OpenGL context */ +void gl_start() { + if (!context) { +#if defined(USE_X11) + context = fl_create_gl_context(fl_visual); +#elif defined(WIN32) + if (!gl_choice) Fl::gl_visual(0); + context = fl_create_gl_context(Fl_Window::current(), gl_choice); +#elif defined(__APPLE_QUARTZ__) + // warning: the Quartz version should probably use Core GL (CGL) instead of AGL + context = fl_create_gl_context(Fl_Window::current(), gl_choice); +#else +# error Unsupported platform +#endif + } + fl_set_gl_context(Fl_Window::current(), context); +#if !defined(WIN32) && !defined(__APPLE__) + glXWaitX(); +#endif + if (pw != Fl_Window::current()->w() || ph != Fl_Window::current()->h()) { + pw = Fl_Window::current()->w(); + ph = Fl_Window::current()->h(); + glLoadIdentity(); + glViewport(0, 0, pw, ph); + glOrtho(0, pw, 0, ph, -1, 1); + glDrawBuffer(GL_FRONT); + } + if (clip_state_number != fl_clip_state_number) { + clip_state_number = fl_clip_state_number; + int x, y, w, h; + if (fl_clip_box(0, 0, Fl_Window::current()->w(), Fl_Window::current()->h(), + x, y, w, h)) { + fl_clip_region(XRectangleRegion(x,y,w,h)); + glScissor(x, Fl_Window::current()->h()-(y+h), w, h); + glEnable(GL_SCISSOR_TEST); + } else { + glDisable(GL_SCISSOR_TEST); + } + } +} + +/** Releases an OpenGL context */ +void gl_finish() { + glFlush(); +#if !defined(WIN32) && !defined(__APPLE__) + glXWaitGL(); +#endif +} + +int Fl::gl_visual(int mode, int *alist) { + Fl_Gl_Choice *c = Fl_Gl_Choice::find(mode,alist); + if (!c) return 0; +#if defined(USE_X11) + fl_visual = c->vis; + fl_colormap = c->colormap; +#elif defined(WIN32) + gl_choice = c; +#elif defined(__APPLE_QUARTZ__) + // warning: the Quartz version should probably use Core GL (CGL) instead of AGL + gl_choice = c; +#else +# error Unsupported platform +#endif + return 1; +} +#endif + +// +// End of "$Id: gl_start.cxx 6749 2009-04-09 20:44:31Z engelsman $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/glut_compatability.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/glut_compatability.cxx new file mode 100644 index 0000000..0338675 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/glut_compatability.cxx @@ -0,0 +1,522 @@ +// +// "$Id: glut_compatability.cxx 7818 2010-11-11 18:22:43Z engelsman $" +// +// GLUT emulation routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Emulation of Glut using fltk. + +// GLUT is Copyright (c) Mark J. Kilgard, 1994, 1995, 1996. +// "This program is freely distributable without licensing fees and is +// provided without guarantee or warrantee expressed or implied. This +// program is -not- in the public domain." + +// Although I have copied the GLUT API, none of my code is based on +// any Glut implementation details and is therefore covered by the LGPL. + +#include "flstring.h" +#if HAVE_GL + +# include +# ifdef HAVE_GLXGETPROCADDRESSARB +# define GLX_GLXEXT_LEGACY +# include +# endif // HAVE_GLXGETPROCADDRESSARB +# ifdef HAVE_DLFCN_H +# include +# endif // HAVE_DLFCN_H +# define MAXWINDOWS 32 +static Fl_Glut_Window *windows[MAXWINDOWS+1]; + +static void (*glut_idle_func)() = 0; // global glut idle function + +Fl_Glut_Window *glut_window; +int glut_menu; +void (*glut_menustate_function)(int); +void (*glut_menustatus_function)(int,int,int); + +static void default_reshape(int w, int h) {glViewport(0,0,w,h);} +static void default_display() {} + +void Fl_Glut_Window::make_current() { + glut_window = this; + if (shown()) Fl_Gl_Window::make_current(); +} + +static int indraw; +void Fl_Glut_Window::draw() { + glut_window = this; + indraw = 1; + if (!valid()) {reshape(w(),h()); valid(1);} + display(); + indraw = 0; +} + +void glutSwapBuffers() { + if (!indraw) glut_window->swap_buffers(); +} + +void Fl_Glut_Window::draw_overlay() { + glut_window = this; + if (!valid()) {reshape(w(),h()); valid(1);} + overlaydisplay(); +} + +static void domenu(int, int, int); + +int Fl_Glut_Window::handle(int event) { + make_current(); + int ex = Fl::event_x(); + int ey = Fl::event_y(); + int button; + switch (event) { + + case FL_PUSH: + if (keyboard || special) Fl::focus(this); + button = Fl::event_button()-1; + if (button<0) button = 0; + if (button>2) button = 2; + if (menu[button]) {domenu(menu[button],ex,ey); return 1;} + mouse_down |= 1< 0) {if (mouse) mouse(4,GLUT_DOWN,ex,ey); --button;} + return 1; + + case FL_RELEASE: + for (button = 0; button < 3; button++) if (mouse_down & (1< FL_F && k <= FL_F_Last) k -= FL_F; + special(k,ex,ey); + return 1; + } + break; + } + + case FL_HIDE: + if (visibility) visibility(GLUT_NOT_VISIBLE); + break; + + case FL_SHOW: + if (visibility) visibility(GLUT_VISIBLE); + break; + } + + return Fl_Gl_Window::handle(event); +} + +static int glut_mode = GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH; + +void Fl_Glut_Window::_init() { + for (number=1; numberresizable(W); + if (initargc) { + W->show(initargc,initargv); + initargc = 0; + } else { + W->show(); + } + W->valid(0); + W->context_valid(0); + W->make_current(); + return W->number; +} + +int glutCreateSubWindow(int win, int x, int y, int w, int h) { + Fl_Glut_Window *W = new Fl_Glut_Window(x,y,w,h,0); + windows[win]->add(W); + if (windows[win]->shown()) W->show(); + W->make_current(); + return W->number; +} +/** Destroys the glut window, first unregister it from the glut windows list */ +Fl_Glut_Window::~Fl_Glut_Window() { + if (glut_window == this) glut_window = 0; + windows[number] = 0; +} + +void glutDestroyWindow(int win) { + // should destroy children!!! + delete windows[win]; +} + +void glutPostWindowRedisplay(int win) { + windows[win]->redraw(); +} + +void glutSetWindow(int win) { + windows[win]->make_current(); +} + +//////////////////////////////////////////////////////////////// +#include + +struct menu { + void (*cb)(int); + Fl_Menu_Item *m; + int size; + int alloc; +}; + +#define MAXMENUS 32 +static menu menus[MAXMENUS+1]; + +static void domenu(int n, int ex, int ey) { + glut_menu = n; + menu *m = &menus[n]; + if (glut_menustate_function) glut_menustate_function(1); + if (glut_menustatus_function) glut_menustatus_function(1,ex,ey); + const Fl_Menu_Item* g = m->m->popup(Fl::event_x(), Fl::event_y(), 0); + if (g && g->callback_) ((void (*)(int))(g->callback_))(int(g->argument())); + if (glut_menustatus_function) glut_menustatus_function(0,ex,ey); + if (glut_menustate_function) glut_menustate_function(0); +} + +int glutCreateMenu(void (*cb)(int)) { + int i; + for (i=1; icb = cb; + return glut_menu = i; +} + +void glutDestroyMenu(int n) { + menu *m = &menus[n]; + delete[] m->m; + m->m = 0; + m->cb = 0; + m->size = m->alloc = 0; +} + +static Fl_Menu_Item* additem(menu *m) { + if (m->size+1 >= m->alloc) { + m->alloc = m->size*2+10; + Fl_Menu_Item* nm = new Fl_Menu_Item[m->alloc]; + for (int i=0; isize; i++) nm[i] = m->m[i]; + delete[] m->m; + m->m = nm; + } + int n = m->size++; + m->m[n+1].text = 0; + Fl_Menu_Item* i = &(m->m[n]); + i->shortcut_ = 0; + i->flags = 0; + i->labeltype_ = i->labelfont_ = i->labelsize_ = i->labelcolor_ = 0; + return i; +} + +void glutAddMenuEntry(char *label, int value) { + menu *m = &menus[glut_menu]; + Fl_Menu_Item* i = additem(m); + i->text = label; + i->callback_ = (Fl_Callback*)(m->cb); + i->user_data_ = (void *)value; +} + +void glutAddSubMenu(char *label, int submenu) { + menu *m = &menus[glut_menu]; + Fl_Menu_Item* i = additem(m); + i->text = label; + i->callback_ = 0; + i->user_data_ = (void *)(menus[submenu].m); + i->flags = FL_PUP_SUBMENU; +} + +void glutChangeToMenuEntry(int item, char *label, int value) { + menu *m = &menus[glut_menu]; + Fl_Menu_Item* i = &m->m[item-1]; + i->text = label; + i->callback_ = (Fl_Callback*)(m->cb); + i->user_data_ = (void *)value; + i->flags = 0; +} + +void glutChangeToSubMenu(int item, char *label, int submenu) { + menu *m = &menus[glut_menu]; + Fl_Menu_Item* i = &m->m[item-1]; + i->text = label; + i->callback_ = 0; + i->user_data_ = (void *)(menus[submenu].m); + i->flags = FL_PUP_SUBMENU; +} + +void glutRemoveMenuItem(int item) { + menu *m = &menus[glut_menu]; + if (item > m->size || item < 1) return; + for (int i = item-1; i <= m->size; i++) m->m[i] = m->m[i+1]; + m->size--; +} + +//////////////////////////////////////////////////////////////// + +int glutGet(GLenum type) { + switch (type) { + case GLUT_RETURN_ZERO: return 0; + case GLUT_WINDOW_X: return glut_window->x(); + case GLUT_WINDOW_Y: return glut_window->y(); + case GLUT_WINDOW_WIDTH: return glut_window->w(); + case GLUT_WINDOW_HEIGHT: return glut_window->h(); + case GLUT_WINDOW_PARENT: + if (glut_window->parent()) + return ((Fl_Glut_Window *)(glut_window->parent()))->number; + else + return 0; +//case GLUT_WINDOW_NUM_CHILDREN: +//case GLUT_WINDOW_CURSOR: return + case GLUT_SCREEN_WIDTH: return Fl::w(); + case GLUT_SCREEN_HEIGHT: return Fl::h(); +//case GLUT_SCREEN_WIDTH_MM: +//case GLUT_SCREEN_HEIGHT_MM: + case GLUT_MENU_NUM_ITEMS: return menus[glut_menu].size; + case GLUT_DISPLAY_MODE_POSSIBLE: return Fl_Gl_Window::can_do(glut_mode); + case GLUT_INIT_WINDOW_X: return initx; + case GLUT_INIT_WINDOW_Y: return inity; + case GLUT_INIT_WINDOW_WIDTH: return initw; + case GLUT_INIT_WINDOW_HEIGHT: return inith; + case GLUT_INIT_DISPLAY_MODE: return glut_mode; +//case GLUT_ELAPSED_TIME: + case GLUT_WINDOW_BUFFER_SIZE: + if (glutGet(GLUT_WINDOW_RGBA)) + return glutGet(GLUT_WINDOW_RED_SIZE)+ + glutGet(GLUT_WINDOW_GREEN_SIZE)+ + glutGet(GLUT_WINDOW_BLUE_SIZE)+ + glutGet(GLUT_WINDOW_ALPHA_SIZE); + else + return glutGet(GLUT_WINDOW_COLORMAP_SIZE); + case GLUT_VERSION: return 20400; + default: {GLint p; glGetIntegerv(type, &p); return p;} + } +} + +int glutLayerGet(GLenum type) { + switch (type) { + case GLUT_OVERLAY_POSSIBLE: return glut_window->can_do_overlay(); +//case GLUT_LAYER_IN_USE: +//case GLUT_HAS_OVERLAY: + case GLUT_TRANSPARENT_INDEX: return 0; // true for SGI + case GLUT_NORMAL_DAMAGED: return glut_window->damage(); + case GLUT_OVERLAY_DAMAGED: return 1; // kind of works... + default: return 0; + } +} + +int glutDeviceGet(GLenum type) { + switch (type) { + case GLUT_HAS_KEYBOARD : return 1; + case GLUT_HAS_MOUSE : return 1; + case GLUT_NUM_MOUSE_BUTTONS : return 3; + default : return 0; + } +} + +// Get extension function address... +GLUTproc glutGetProcAddress(const char *procName) { +# ifdef WIN32 + return (GLUTproc)wglGetProcAddress((LPCSTR)procName); + +# elif defined(HAVE_DLSYM) && defined(HAVE_DLFCN_H) + char symbol[1024]; + + snprintf(symbol, sizeof(symbol), "_%s", procName); + +# ifdef RTLD_DEFAULT + return (GLUTproc)dlsym(RTLD_DEFAULT, symbol); + +# else // No RTLD_DEFAULT support, so open the current a.out symbols... + static void *rtld_default = 0; + + if (!rtld_default) rtld_default = dlopen(0, RTLD_LAZY); + + if (rtld_default) return (GLUTproc)dlsym(rtld_default, symbol); + else return 0; + +# endif // RTLD_DEFAULT + +# elif defined(HAVE_GLXGETPROCADDRESSARB) + return (GLUTproc)glXGetProcAddressARB((const GLubyte *)procName); + +# else + return (GLUTproc)0; +# endif // WIN32 +} + +// Parse the GL_EXTENSIONS string to see if the named extension is +// supported. +// +// This code was copied from FreeGLUT 2.4.0 which carries the +// following notice: +// +// Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved. +int glutExtensionSupported( const char* extension ) +{ + if (!extension || strchr(extension, ' ')) return 0; + + const char *extensions, *start; + const int len = strlen( extension ); + + start = extensions = (const char *) glGetString(GL_EXTENSIONS); + + if (!extensions) return 0; + + for (;;) { + const char *p = strstr(extensions, extension); + if (!p) return 0; /* not found */ + /* check that the match isn't a super string */ + if ((p == start || p[-1] == ' ') && + (p[len] == ' ' || p[len] == 0)) return 1; + /* skip the false match and continue */ + extensions = p + len; + } +} + +// Add a mechanism to handle adding/removing the glut idle function +// without depending on the (deprecated) set_idle method. +void glutIdleFunc(void (*f)()) +{ + // no change + if(glut_idle_func == f) return; + // remove current idle + if(glut_idle_func) Fl::remove_idle((void (*)(void *))glut_idle_func); + // install new idle func - if one was passed + if(f) Fl::add_idle((void (*)(void *))f); + // record new idle func - even if it is NULL + glut_idle_func = f; +} // glutIdleFunc + +#endif // HAVE_GL + +// +// End of "$Id: glut_compatability.cxx 7818 2010-11-11 18:22:43Z engelsman $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/glut_font.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/glut_font.cxx new file mode 100644 index 0000000..d2eb65d --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/glut_font.cxx @@ -0,0 +1,198 @@ +// +// "$Id: glut_font.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// GLUT font routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// +// The stroked text code was copied from FreeGLUT 2.4.0 which carries +// the following notice: +// +// Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved. +// + +// (sort of) emulation of Glut's bitmap drawing functions, using FL's +// font stuff. Not all the fonts match! + +#include +#if HAVE_GL +# include + +Fl_Glut_Bitmap_Font glutBitmap9By15 = {FL_SCREEN, 15}; +Fl_Glut_Bitmap_Font glutBitmap8By13 = {FL_SCREEN, 13}; +Fl_Glut_Bitmap_Font glutBitmapTimesRoman10 = {FL_TIMES, 10}; +Fl_Glut_Bitmap_Font glutBitmapTimesRoman24 = {FL_TIMES, 24}; +Fl_Glut_Bitmap_Font glutBitmapHelvetica10 = {FL_HELVETICA, 10}; +Fl_Glut_Bitmap_Font glutBitmapHelvetica12 = {FL_HELVETICA, 12}; +Fl_Glut_Bitmap_Font glutBitmapHelvetica18 = {FL_HELVETICA, 18}; + +void glutBitmapCharacter(void* font, int character) { + gl_font(((Fl_Glut_Bitmap_Font *)font)->font,((Fl_Glut_Bitmap_Font *)font)->size); + char a[1]; a[0] = character; + gl_draw(a,1); +} + +int glutBitmapHeight(void* font) { + gl_font(((Fl_Glut_Bitmap_Font *)font)->font,((Fl_Glut_Bitmap_Font *)font)->size); + return gl_height(); +} + +int glutBitmapLength(void *font, const unsigned char *string) { + gl_font(((Fl_Glut_Bitmap_Font *)font)->font,((Fl_Glut_Bitmap_Font *)font)->size); + const char *s = (const char*)string; + return int(gl_width(s)+.5); +} + +void glutBitmapString(void *font, const unsigned char *string) { + gl_font(((Fl_Glut_Bitmap_Font *)font)->font,((Fl_Glut_Bitmap_Font *)font)->size); + const char *s = (const char*)string; + gl_draw(s); +} + +int glutBitmapWidth(void* font, int character) { + gl_font(((Fl_Glut_Bitmap_Font *)font)->font,((Fl_Glut_Bitmap_Font *)font)->size); + return int(gl_width(character)+.5); +} + + +/* + * Draw a stroke character + */ +void glutStrokeCharacter(void* fontID, int character) { + const Fl_Glut_StrokeChar *schar; + const Fl_Glut_StrokeStrip *strip; + int i, j; + Fl_Glut_StrokeFont* font = (Fl_Glut_StrokeFont *)fontID; + + if (character < 0 || character >= font->Quantity) return; + + schar = font->Characters[character]; + if (!schar) return; + + strip = schar->Strips; + + for (i = 0; i < schar->Number; i++, strip++) + { + glBegin(GL_LINE_STRIP); + for (j = 0; j < strip->Number; j++) + glVertex2f(strip->Vertices[j].X, strip->Vertices[j].Y); + glEnd(); + } + + glTranslatef(schar->Right, 0.0, 0.0); +} + +void glutStrokeString(void* fontID, const unsigned char *string) { + unsigned char c; + int i, j; + float length = 0.0; + Fl_Glut_StrokeFont* font = (Fl_Glut_StrokeFont *)fontID; + + if (!string || ! *string) return; + + /* + * Step through the string, drawing each character. + * A newline will simply translate the next character's insertion + * point back to the start of the line and down one line. + */ + while ((c = *string++) != 0) { + if (c < font->Quantity) { + if (c == '\n') { + glTranslatef(-length, -(float)(font->Height), 0.0); + length = 0.0; + } else { + /* Not an EOL, draw the bitmap character */ + const Fl_Glut_StrokeChar *schar = font->Characters[c]; + if (schar) { + const Fl_Glut_StrokeStrip *strip = schar->Strips; + + for (i = 0; i < schar->Number; i++, strip++) { + glBegin(GL_LINE_STRIP); + for (j = 0; j < strip->Number; j++) + glVertex2f(strip->Vertices[j].X, strip->Vertices[j].Y); + glEnd(); + } + + length += schar->Right; + glTranslatef(schar->Right, 0.0, 0.0); + } + } + } + } +} + +/* + * Return the width in pixels of a stroke character + */ +int glutStrokeWidth( void* fontID, int character ) +{ + const Fl_Glut_StrokeChar *schar; + Fl_Glut_StrokeFont* font = (Fl_Glut_StrokeFont *)fontID; + if (character < 0 || character >= font->Quantity) return 0; + schar = font->Characters[ character ]; + + return schar ? (int)(schar->Right + 0.5) : 0; +} + +/* + * Return the width of a string drawn using a stroke font + */ +int glutStrokeLength(void* fontID, const unsigned char* string) { + unsigned char c; + float length = 0.0; + float this_line_length = 0.0; + Fl_Glut_StrokeFont* font = (Fl_Glut_StrokeFont *)fontID; + + if (!string || ! *string) return 0; + + while ((c = *string++) != 0) { + if (c < font->Quantity) { + if (c == '\n') { + /* EOL; reset the length of this line */ + if (length < this_line_length) length = this_line_length; + this_line_length = 0.0; + } else { + /* Not an EOL, increment the length of this line */ + const Fl_Glut_StrokeChar *schar = font->Characters[c]; + if (schar) this_line_length += schar->Right; + } + } + } + + if (length < this_line_length) length = this_line_length; + + return (int)(length + 0.5); +} + +/* + * Returns the height of a stroke font + */ +GLfloat glutStrokeHeight(void* fontID) { + Fl_Glut_StrokeFont* font = (Fl_Glut_StrokeFont *)fontID; + return font->Height; +} + +#endif // HAVE_GL + +// +// End of "$Id: glut_font.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/makedepend b/mod/maxgui.mod/fltkmaxgui.mod/src/makedepend new file mode 100644 index 0000000..f0e07d1 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/makedepend @@ -0,0 +1,1120 @@ +# DO NOT DELETE THIS LINE -- make depend depends on it. + +Fl.o: ../config.h ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +Fl.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Window.H +Fl.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/x.H ../FL/Fl_Window.H +Fl.o: ../FL/Fl_Tooltip.H ../FL/Fl_Widget.H flstring.h ../FL/Fl_Export.H +Fl.o: ../FL/fl_draw.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H +Fl.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H +Fl.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +Fl_Adjuster.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +Fl_Adjuster.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Adjuster.H +Fl_Adjuster.o: ../FL/Fl_Valuator.H ../FL/Fl_Widget.H ../FL/Fl_Bitmap.H +Fl_Adjuster.o: ../FL/Fl_Image.H ../FL/fl_draw.H ../FL/Fl_Window.H +Fl_Adjuster.o: ../FL/Fl_Device.H ../FL/x.H ../FL/Fl_Plugin.H +Fl_Adjuster.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Pixmap.H +Fl_Adjuster.o: ../FL/Fl_RGB_Image.H fastarrow.h mediumarrow.h slowarrow.h +Fl_Bitmap.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +Fl_Bitmap.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/x.H ../FL/Fl_Window.H +Fl_Bitmap.o: ../FL/fl_draw.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H +Fl_Bitmap.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H +Fl_Bitmap.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +Fl_Bitmap.o: ../FL/Fl_Widget.H ../FL/Fl_Menu_Item.H ../FL/Fl_Widget.H +Fl_Bitmap.o: ../FL/Fl_Printer.H ../FL/Fl_Paged_Device.H ../FL/Fl_Device.H +Fl_Bitmap.o: ../FL/Fl_PostScript.H flstring.h ../FL/Fl_Export.H ../config.h +Fl_Browser.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +Fl_Browser.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Browser.H +Fl_Browser.o: ../FL/Fl_Browser_.H ../FL/Fl_Group.H ../FL/Fl_Widget.H +Fl_Browser.o: ../FL/Fl_Scrollbar.H ../FL/Fl_Slider.H ../FL/Fl_Valuator.H +Fl_Browser.o: ../FL/Fl_Image.H ../FL/fl_draw.H ../FL/Fl_Window.H +Fl_Browser.o: ../FL/Fl_Device.H ../FL/x.H ../FL/Fl_Plugin.H +Fl_Browser.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H +Fl_Browser.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H flstring.h +Fl_Browser.o: ../FL/Fl_Export.H ../config.h +Fl_Browser_.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +Fl_Browser_.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Widget.H +Fl_Browser_.o: ../FL/Fl_Browser_.H ../FL/Fl_Group.H ../FL/Fl_Widget.H +Fl_Browser_.o: ../FL/Fl_Scrollbar.H ../FL/Fl_Slider.H ../FL/Fl_Valuator.H +Fl_Browser_.o: ../FL/fl_draw.H ../FL/Fl_Window.H ../FL/Fl_Device.H ../FL/x.H +Fl_Browser_.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H +Fl_Browser_.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Pixmap.H +Fl_Browser_.o: ../FL/Fl_RGB_Image.H +Fl_Browser_load.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +Fl_Browser_load.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H +Fl_Browser_load.o: ../FL/Fl_Browser.H ../FL/Fl_Browser_.H ../FL/Fl_Group.H +Fl_Browser_load.o: ../FL/Fl_Widget.H ../FL/Fl_Scrollbar.H ../FL/Fl_Slider.H +Fl_Browser_load.o: ../FL/Fl_Valuator.H ../FL/Fl_Image.H ../FL/fl_utf8.h +Fl_Box.o: ../FL/Fl_Widget.H ../FL/Fl_Box.H ../FL/Fl_Widget.H +Fl_Box.o: ../FL/Enumerations.H ../FL/Fl_Export.H ../FL/fl_types.h +Fl_Button.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +Fl_Button.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Button.H +Fl_Button.o: ../FL/Fl_Widget.H ../FL/Fl_Group.H ../FL/Fl_Window.H +Fl_Button.o: ../FL/Fl_Group.H +Fl_Chart.o: ../FL/math.h ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +Fl_Chart.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H +Fl_Chart.o: ../FL/Fl_Chart.H ../FL/Fl_Widget.H ../FL/fl_draw.H +Fl_Chart.o: ../FL/Fl_Window.H ../FL/Fl_Device.H ../FL/x.H ../FL/Fl_Plugin.H +Fl_Chart.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H +Fl_Chart.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +Fl_Chart.o: flstring.h ../FL/Fl_Export.H ../config.h +Fl_Check_Browser.o: flstring.h ../FL/Fl_Export.H ../config.h ../FL/fl_draw.H +Fl_Check_Browser.o: ../FL/Enumerations.H ../FL/Fl_Export.H ../FL/fl_types.h +Fl_Check_Browser.o: ../FL/Fl_Window.H ../FL/Fl_Device.H ../FL/x.H +Fl_Check_Browser.o: ../FL/Xutf8.h ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H +Fl_Check_Browser.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H +Fl_Check_Browser.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +Fl_Check_Browser.o: ../FL/Fl_Check_Browser.H ../FL/Fl.H ../FL/fl_utf8.h +Fl_Check_Browser.o: ../FL/Fl_Browser_.H ../FL/Fl_Group.H ../FL/Fl_Widget.H +Fl_Check_Browser.o: ../FL/Fl_Scrollbar.H ../FL/Fl_Slider.H +Fl_Check_Browser.o: ../FL/Fl_Valuator.H ../FL/Fl.H +Fl_Check_Button.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +Fl_Check_Button.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H +Fl_Check_Button.o: ../FL/Fl_Check_Button.H ../FL/Fl_Light_Button.H +Fl_Check_Button.o: ../FL/Fl_Button.H ../FL/Fl_Widget.H +Fl_Choice.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +Fl_Choice.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Choice.H +Fl_Choice.o: ../FL/Fl_Menu_.H ../FL/Fl_Widget.H ../FL/Fl_Menu_Item.H +Fl_Choice.o: ../FL/Fl_Image.H ../FL/fl_draw.H ../FL/Fl_Window.H +Fl_Choice.o: ../FL/Fl_Device.H ../FL/x.H ../FL/Fl_Plugin.H +Fl_Choice.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H +Fl_Choice.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H flstring.h +Fl_Choice.o: ../FL/Fl_Export.H ../config.h +Fl_Clock.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +Fl_Clock.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Clock.H +Fl_Clock.o: ../FL/Fl_Widget.H ../FL/fl_draw.H ../FL/Fl_Window.H +Fl_Clock.o: ../FL/Fl_Device.H ../FL/x.H ../FL/Fl_Plugin.H +Fl_Clock.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H +Fl_Clock.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +Fl_Color_Chooser.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +Fl_Color_Chooser.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H +Fl_Color_Chooser.o: ../FL/Fl_Color_Chooser.H ../FL/Fl_Group.H ../FL/Fl_Box.H +Fl_Color_Chooser.o: ../FL/Fl_Widget.H ../FL/Fl_Return_Button.H +Fl_Color_Chooser.o: ../FL/Fl_Button.H ../FL/Fl_Choice.H ../FL/Fl_Menu_.H +Fl_Color_Chooser.o: ../FL/Fl_Menu_Item.H ../FL/Fl_Image.H +Fl_Color_Chooser.o: ../FL/Fl_Value_Input.H ../FL/Fl_Valuator.H +Fl_Color_Chooser.o: ../FL/Fl_Input.H ../FL/Fl_Input_.H ../FL/fl_draw.H +Fl_Color_Chooser.o: ../FL/Fl_Window.H ../FL/Fl_Device.H ../FL/x.H +Fl_Color_Chooser.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H +Fl_Color_Chooser.o: ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +Fl_Color_Chooser.o: ../FL/math.h ../FL/Fl_Window.H ../FL/Fl_Group.H +Fl_Counter.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +Fl_Counter.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Counter.H +Fl_Counter.o: ../FL/Fl_Valuator.H ../FL/Fl_Widget.H ../FL/fl_draw.H +Fl_Counter.o: ../FL/Fl_Window.H ../FL/Fl_Device.H ../FL/x.H ../FL/Fl_Plugin.H +Fl_Counter.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H +Fl_Counter.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +Fl_Dial.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +Fl_Dial.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Dial.H +Fl_Dial.o: ../FL/Fl_Valuator.H ../FL/Fl_Widget.H ../FL/fl_draw.H +Fl_Dial.o: ../FL/Fl_Window.H ../FL/Fl_Device.H ../FL/x.H ../FL/Fl_Plugin.H +Fl_Dial.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H +Fl_Dial.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +Fl_Dial.o: ../FL/math.h +Fl_Device.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +Fl_Device.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Device.H +Fl_Device.o: ../FL/Fl_Image.H +Fl_Double_Window.o: ../config.h ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +Fl_Double_Window.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H +Fl_Double_Window.o: ../FL/Fl_Double_Window.H ../FL/Fl_Window.H +Fl_Double_Window.o: ../FL/Fl_Printer.H ../FL/Fl_Paged_Device.H +Fl_Double_Window.o: ../FL/Fl_Device.H ../FL/fl_draw.H ../FL/Fl_Device.H +Fl_Double_Window.o: ../FL/x.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H +Fl_Double_Window.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H +Fl_Double_Window.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +Fl_Double_Window.o: ../FL/Fl_PostScript.H +Fl_File_Browser.o: ../FL/Fl_File_Browser.H ../FL/Fl_Browser.H +Fl_File_Browser.o: ../FL/Fl_Browser_.H ../FL/Fl_Group.H ../FL/Fl_Widget.H +Fl_File_Browser.o: ../FL/Enumerations.H ../FL/Fl_Export.H ../FL/fl_types.h +Fl_File_Browser.o: ../FL/Fl_Scrollbar.H ../FL/Fl_Slider.H ../FL/Fl_Valuator.H +Fl_File_Browser.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Xutf8.h ../FL/Fl_Image.H +Fl_File_Browser.o: ../FL/Fl_File_Icon.H ../FL/Fl.H ../FL/filename.H +Fl_File_Browser.o: ../FL/fl_draw.H ../FL/Fl_Window.H ../FL/Fl_Device.H +Fl_File_Browser.o: ../FL/x.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H +Fl_File_Browser.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H +Fl_File_Browser.o: ../FL/Fl_RGB_Image.H ../FL/filename.H flstring.h +Fl_File_Browser.o: ../FL/Fl_Export.H ../config.h +Fl_File_Chooser.o: ../FL/Fl_File_Chooser.H ../FL/Fl.H ../FL/fl_utf8.h +Fl_File_Chooser.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Xutf8.h +Fl_File_Chooser.o: ../FL/Enumerations.H ../FL/Fl_Double_Window.H +Fl_File_Chooser.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Choice.H +Fl_File_Chooser.o: ../FL/Fl_Menu_.H ../FL/Fl_Widget.H ../FL/Fl_Menu_Item.H +Fl_File_Chooser.o: ../FL/Fl_Image.H ../FL/Fl_Menu_Button.H ../FL/Fl_Button.H +Fl_File_Chooser.o: ../FL/Fl_Preferences.H ../FL/Fl_Tile.H ../FL/Fl_Group.H +Fl_File_Chooser.o: ../FL/Fl_File_Browser.H ../FL/Fl_Browser.H +Fl_File_Chooser.o: ../FL/Fl_Browser_.H ../FL/Fl_Scrollbar.H ../FL/Fl_Slider.H +Fl_File_Chooser.o: ../FL/Fl_Valuator.H ../FL/Fl_File_Icon.H ../FL/Fl.H +Fl_File_Chooser.o: ../FL/filename.H ../FL/Fl_Box.H ../FL/Fl_Check_Button.H +Fl_File_Chooser.o: ../FL/Fl_Light_Button.H ../FL/Fl_Button.H +Fl_File_Chooser.o: ../FL/Fl_File_Input.H ../FL/Fl_Input.H ../FL/Fl_Input_.H +Fl_File_Chooser.o: ../FL/Fl_Return_Button.H ../FL/fl_ask.H ../FL/fl_draw.H +Fl_File_Chooser.o: ../FL/Fl_Device.H ../FL/x.H ../FL/Fl_Plugin.H +Fl_File_Chooser.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H +Fl_File_Chooser.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +Fl_File_Chooser2.o: ../FL/Fl_File_Chooser.H ../FL/Fl.H ../FL/fl_utf8.h +Fl_File_Chooser2.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Xutf8.h +Fl_File_Chooser2.o: ../FL/Enumerations.H ../FL/Fl_Double_Window.H +Fl_File_Chooser2.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Choice.H +Fl_File_Chooser2.o: ../FL/Fl_Menu_.H ../FL/Fl_Widget.H ../FL/Fl_Menu_Item.H +Fl_File_Chooser2.o: ../FL/Fl_Image.H ../FL/Fl_Menu_Button.H ../FL/Fl_Button.H +Fl_File_Chooser2.o: ../FL/Fl_Preferences.H ../FL/Fl_Tile.H ../FL/Fl_Group.H +Fl_File_Chooser2.o: ../FL/Fl_File_Browser.H ../FL/Fl_Browser.H +Fl_File_Chooser2.o: ../FL/Fl_Browser_.H ../FL/Fl_Scrollbar.H +Fl_File_Chooser2.o: ../FL/Fl_Slider.H ../FL/Fl_Valuator.H +Fl_File_Chooser2.o: ../FL/Fl_File_Icon.H ../FL/Fl.H ../FL/filename.H +Fl_File_Chooser2.o: ../FL/Fl_Box.H ../FL/Fl_Check_Button.H +Fl_File_Chooser2.o: ../FL/Fl_Light_Button.H ../FL/Fl_Button.H +Fl_File_Chooser2.o: ../FL/Fl_File_Input.H ../FL/Fl_Input.H ../FL/Fl_Input_.H +Fl_File_Chooser2.o: ../FL/Fl_Return_Button.H ../FL/fl_ask.H ../FL/filename.H +Fl_File_Chooser2.o: ../FL/x.H ../FL/Fl_Shared_Image.H flstring.h +Fl_File_Chooser2.o: ../FL/Fl_Export.H ../config.h +Fl_File_Icon.o: ../FL/fl_utf8.h flstring.h ../FL/Fl_Export.H ../config.h +Fl_File_Icon.o: ../FL/Fl_File_Icon.H ../FL/Fl.H ../FL/fl_utf8.h +Fl_File_Icon.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Xutf8.h +Fl_File_Icon.o: ../FL/Enumerations.H ../FL/Fl_Widget.H ../FL/fl_draw.H +Fl_File_Icon.o: ../FL/Fl_Window.H ../FL/Fl_Device.H ../FL/x.H +Fl_File_Icon.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H +Fl_File_Icon.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Pixmap.H +Fl_File_Icon.o: ../FL/Fl_RGB_Image.H ../FL/filename.H +Fl_File_Input.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +Fl_File_Input.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H +Fl_File_Input.o: ../FL/Fl_File_Input.H ../FL/Fl_Input.H ../FL/Fl_Input_.H +Fl_File_Input.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Widget.H +Fl_File_Input.o: ../FL/fl_draw.H ../FL/Fl_Window.H ../FL/Fl_Device.H +Fl_File_Input.o: ../FL/x.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H +Fl_File_Input.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H +Fl_File_Input.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H flstring.h +Fl_File_Input.o: ../FL/Fl_Export.H ../config.h +Fl_Group.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +Fl_Group.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Group.H +Fl_Group.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Widget.H +Fl_Group.o: ../FL/fl_draw.H ../FL/Fl_Window.H ../FL/Fl_Device.H ../FL/x.H +Fl_Group.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H +Fl_Group.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Pixmap.H +Fl_Group.o: ../FL/Fl_RGB_Image.H +Fl_Help_View.o: ../FL/Fl_Help_View.H ../FL/Fl.H ../FL/fl_utf8.h +Fl_Help_View.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Xutf8.h +Fl_Help_View.o: ../FL/Enumerations.H ../FL/Fl_Group.H ../FL/Fl_Widget.H +Fl_Help_View.o: ../FL/Fl_Scrollbar.H ../FL/Fl_Slider.H ../FL/Fl_Valuator.H +Fl_Help_View.o: ../FL/fl_draw.H ../FL/Fl_Window.H ../FL/Fl_Device.H ../FL/x.H +Fl_Help_View.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H +Fl_Help_View.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Pixmap.H +Fl_Help_View.o: ../FL/Fl_RGB_Image.H ../FL/Fl_Shared_Image.H +Fl_Help_View.o: ../FL/Fl_Window.H ../FL/fl_utf8.h ../FL/filename.H flstring.h +Fl_Help_View.o: ../FL/Fl_Export.H ../config.h +Fl_Image.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +Fl_Image.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/fl_draw.H +Fl_Image.o: ../FL/Fl_Window.H ../FL/Fl_Device.H ../FL/x.H ../FL/Fl_Plugin.H +Fl_Image.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H +Fl_Image.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +Fl_Image.o: ../FL/Fl_Widget.H ../FL/Fl_Menu_Item.H ../FL/Fl_Widget.H +Fl_Image.o: flstring.h ../FL/Fl_Export.H ../config.h +Fl_Input.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +Fl_Input.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Window.H +Fl_Input.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Input.H +Fl_Input.o: ../FL/Fl_Input_.H ../FL/fl_draw.H ../FL/Fl_Window.H +Fl_Input.o: ../FL/Fl_Device.H ../FL/x.H ../FL/Fl_Plugin.H +Fl_Input.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H +Fl_Input.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +Fl_Input.o: ../FL/fl_ask.H flstring.h ../FL/Fl_Export.H ../config.h +Fl_Input_.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +Fl_Input_.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Input_.H +Fl_Input_.o: ../FL/Fl_Widget.H ../FL/Fl_Window.H ../FL/Fl_Group.H +Fl_Input_.o: ../FL/fl_draw.H ../FL/Fl_Window.H ../FL/Fl_Device.H ../FL/x.H +Fl_Input_.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H +Fl_Input_.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Pixmap.H +Fl_Input_.o: ../FL/Fl_RGB_Image.H ../FL/fl_ask.H ../FL/fl_utf8.h flstring.h +Fl_Input_.o: ../FL/Fl_Export.H ../config.h +Fl_Light_Button.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +Fl_Light_Button.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H +Fl_Light_Button.o: ../FL/Fl_Light_Button.H ../FL/Fl_Button.H +Fl_Light_Button.o: ../FL/Fl_Widget.H ../FL/fl_draw.H ../FL/Fl_Window.H +Fl_Light_Button.o: ../FL/Fl_Device.H ../FL/x.H ../FL/Fl_Plugin.H +Fl_Light_Button.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H +Fl_Light_Button.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +Fl_Light_Button.o: flstring.h ../FL/Fl_Export.H ../config.h +Fl_Menu.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +Fl_Menu.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Menu_Window.H +Fl_Menu.o: ../FL/Fl_Single_Window.H ../FL/Fl_Window.H ../FL/Fl_Menu_.H +Fl_Menu.o: ../FL/Fl_Widget.H ../FL/Fl_Menu_Item.H ../FL/Fl_Image.H +Fl_Menu.o: ../FL/fl_draw.H ../FL/Fl_Device.H ../FL/x.H ../FL/Fl_Plugin.H +Fl_Menu.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H +Fl_Menu.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H flstring.h +Fl_Menu.o: ../FL/Fl_Export.H ../config.h +Fl_Menu_.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +Fl_Menu_.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Menu_.H +Fl_Menu_.o: ../FL/Fl_Widget.H ../FL/Fl_Menu_Item.H ../FL/Fl_Image.H +Fl_Menu_.o: flstring.h ../FL/Fl_Export.H ../config.h +Fl_Menu_Bar.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +Fl_Menu_Bar.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Menu_Bar.H +Fl_Menu_Bar.o: ../FL/Fl_Menu_.H ../FL/Fl_Widget.H ../FL/Fl_Menu_Item.H +Fl_Menu_Bar.o: ../FL/Fl_Image.H ../FL/fl_draw.H ../FL/Fl_Window.H +Fl_Menu_Bar.o: ../FL/Fl_Device.H ../FL/x.H ../FL/Fl_Plugin.H +Fl_Menu_Bar.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H +Fl_Menu_Bar.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +Fl_Menu_Button.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +Fl_Menu_Button.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H +Fl_Menu_Button.o: ../FL/Fl_Menu_Button.H ../FL/Fl_Menu_.H ../FL/Fl_Widget.H +Fl_Menu_Button.o: ../FL/Fl_Menu_Item.H ../FL/Fl_Image.H ../FL/fl_draw.H +Fl_Menu_Button.o: ../FL/Fl_Window.H ../FL/Fl_Device.H ../FL/x.H +Fl_Menu_Button.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H +Fl_Menu_Button.o: ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +Fl_Menu_Window.o: ../config.h ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +Fl_Menu_Window.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H +Fl_Menu_Window.o: ../FL/x.H ../FL/Fl_Window.H ../FL/fl_draw.H +Fl_Menu_Window.o: ../FL/Fl_Device.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H +Fl_Menu_Window.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H +Fl_Menu_Window.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +Fl_Menu_Window.o: ../FL/Fl_Menu_Window.H ../FL/Fl_Single_Window.H +Fl_Menu_add.o: ../FL/Fl_Menu_.H ../FL/Fl_Widget.H ../FL/Enumerations.H +Fl_Menu_add.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Fl_Menu_Item.H +Fl_Menu_add.o: ../FL/Fl_Image.H flstring.h ../FL/Fl_Export.H ../config.h +Fl_Menu_global.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +Fl_Menu_global.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H +Fl_Menu_global.o: ../FL/Fl_Menu_.H ../FL/Fl_Widget.H ../FL/Fl_Menu_Item.H +Fl_Menu_global.o: ../FL/Fl_Image.H +Fl_Multi_Label.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +Fl_Multi_Label.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H +Fl_Multi_Label.o: ../FL/Fl_Widget.H ../FL/Fl_Menu_Item.H ../FL/Fl_Widget.H +Fl_Multi_Label.o: ../FL/Fl_Image.H ../FL/Fl_Multi_Label.H +Fl_Native_File_Chooser.o: Fl_Native_File_Chooser_FLTK.cxx +Fl_Native_File_Chooser.o: ../FL/Fl_Native_File_Chooser.H +Fl_Native_File_Chooser.o: ../FL/Fl_Native_File_Chooser_FLTK.H +Fl_Native_File_Chooser.o: ../FL/Fl_File_Chooser.H ../FL/Fl.H ../FL/fl_utf8.h +Fl_Native_File_Chooser.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Xutf8.h +Fl_Native_File_Chooser.o: ../FL/Enumerations.H ../FL/Fl_Double_Window.H +Fl_Native_File_Chooser.o: ../FL/Fl_Window.H ../FL/Fl_Group.H +Fl_Native_File_Chooser.o: ../FL/Fl_Choice.H ../FL/Fl_Menu_.H +Fl_Native_File_Chooser.o: ../FL/Fl_Widget.H ../FL/Fl_Menu_Item.H +Fl_Native_File_Chooser.o: ../FL/Fl_Image.H ../FL/Fl_Menu_Button.H +Fl_Native_File_Chooser.o: ../FL/Fl_Button.H ../FL/Fl_Preferences.H +Fl_Native_File_Chooser.o: ../FL/Fl_Tile.H ../FL/Fl_Group.H +Fl_Native_File_Chooser.o: ../FL/Fl_File_Browser.H ../FL/Fl_Browser.H +Fl_Native_File_Chooser.o: ../FL/Fl_Browser_.H ../FL/Fl_Scrollbar.H +Fl_Native_File_Chooser.o: ../FL/Fl_Slider.H ../FL/Fl_Valuator.H +Fl_Native_File_Chooser.o: ../FL/Fl_File_Icon.H ../FL/Fl.H ../FL/filename.H +Fl_Native_File_Chooser.o: ../FL/Fl_Box.H ../FL/Fl_Check_Button.H +Fl_Native_File_Chooser.o: ../FL/Fl_Light_Button.H ../FL/Fl_Button.H +Fl_Native_File_Chooser.o: ../FL/Fl_File_Input.H ../FL/Fl_Input.H +Fl_Native_File_Chooser.o: ../FL/Fl_Input_.H ../FL/Fl_Return_Button.H +Fl_Native_File_Chooser.o: ../FL/fl_ask.H ../FL/Fl_File_Icon.H +Fl_Native_File_Chooser.o: Fl_Native_File_Chooser_common.cxx +Fl_Native_File_Chooser.o: ../FL/Enumerations.H +Fl_Overlay_Window.o: ../config.h ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +Fl_Overlay_Window.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H +Fl_Overlay_Window.o: ../FL/Fl_Overlay_Window.H ../FL/Fl_Double_Window.H +Fl_Overlay_Window.o: ../FL/Fl_Window.H ../FL/fl_draw.H ../FL/Fl_Device.H +Fl_Overlay_Window.o: ../FL/x.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H +Fl_Overlay_Window.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H +Fl_Overlay_Window.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +Fl_Pack.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +Fl_Pack.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Pack.H +Fl_Pack.o: ../FL/Fl_Group.H ../FL/fl_draw.H ../FL/Fl_Window.H +Fl_Pack.o: ../FL/Fl_Device.H ../FL/x.H ../FL/Fl_Plugin.H +Fl_Pack.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H +Fl_Pack.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +Fl_Paged_Device.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +Fl_Paged_Device.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H +Fl_Paged_Device.o: ../FL/Fl_Printer.H ../FL/Fl_Paged_Device.H +Fl_Paged_Device.o: ../FL/Fl_Device.H ../FL/fl_draw.H ../FL/Fl_Window.H +Fl_Paged_Device.o: ../FL/Fl_Device.H ../FL/x.H ../FL/Fl_Plugin.H +Fl_Paged_Device.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H +Fl_Paged_Device.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +Fl_Paged_Device.o: ../FL/Fl_PostScript.H +Fl_Pixmap.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +Fl_Pixmap.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/fl_draw.H +Fl_Pixmap.o: ../FL/Fl_Window.H ../FL/Fl_Device.H ../FL/x.H ../FL/Fl_Plugin.H +Fl_Pixmap.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H +Fl_Pixmap.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +Fl_Pixmap.o: ../FL/Fl_Widget.H ../FL/Fl_Menu_Item.H ../FL/Fl_Widget.H +Fl_Pixmap.o: ../FL/Fl_Printer.H ../FL/Fl_Paged_Device.H ../FL/Fl_Device.H +Fl_Pixmap.o: ../FL/Fl_PostScript.H flstring.h ../FL/Fl_Export.H ../config.h +Fl_Positioner.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +Fl_Positioner.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H +Fl_Positioner.o: ../FL/Fl_Positioner.H ../FL/Fl_Widget.H ../FL/fl_draw.H +Fl_Positioner.o: ../FL/Fl_Window.H ../FL/Fl_Device.H ../FL/x.H +Fl_Positioner.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H +Fl_Positioner.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Pixmap.H +Fl_Positioner.o: ../FL/Fl_RGB_Image.H +Fl_Preferences.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +Fl_Preferences.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H +Fl_Preferences.o: ../FL/Fl_Preferences.H ../FL/Fl_Plugin.H +Fl_Preferences.o: ../FL/Fl_Preferences.H ../FL/Fl_Tree.H ../FL/Fl_Group.H +Fl_Preferences.o: ../FL/Fl_Scrollbar.H ../FL/Fl_Slider.H ../FL/Fl_Valuator.H +Fl_Preferences.o: ../FL/Fl_Widget.H ../FL/fl_draw.H ../FL/Fl_Window.H +Fl_Preferences.o: ../FL/Fl_Device.H ../FL/x.H ../FL/Fl_Image.H +Fl_Preferences.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Pixmap.H +Fl_Preferences.o: ../FL/Fl_RGB_Image.H ../FL/Fl_Tree_Item.H ../FL/Fl_Widget.H +Fl_Preferences.o: ../FL/Fl_Tree_Item_Array.H ../FL/Fl_Tree_Prefs.H +Fl_Preferences.o: ../FL/filename.H ../FL/fl_utf8.h flstring.h +Fl_Preferences.o: ../FL/Fl_Export.H ../config.h +Fl_Printer.o: ../FL/Fl_Printer.H ../FL/Fl_Paged_Device.H ../FL/Fl_Device.H +Fl_Printer.o: ../FL/fl_draw.H ../FL/Enumerations.H ../FL/Fl_Export.H +Fl_Printer.o: ../FL/fl_types.h ../FL/Fl_Window.H ../FL/Fl_Device.H ../FL/x.H +Fl_Printer.o: ../FL/Xutf8.h ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H +Fl_Printer.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H +Fl_Printer.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H ../FL/Fl_PostScript.H +Fl_Printer.o: ../src/Fl_PostScript.cxx ../FL/Fl.H ../FL/fl_utf8.h +Fl_Printer.o: ../FL/fl_ask.H ../FL/Fl_Native_File_Chooser.H +Fl_Printer.o: ../FL/Fl_Native_File_Chooser_FLTK.H ../FL/Fl_File_Chooser.H +Fl_Printer.o: ../FL/Fl_Double_Window.H ../FL/Fl_Group.H ../FL/Fl_Choice.H +Fl_Printer.o: ../FL/Fl_Menu_.H ../FL/Fl_Widget.H ../FL/Fl_Menu_Item.H +Fl_Printer.o: ../FL/Fl_Menu_Button.H ../FL/Fl_Button.H ../FL/Fl_Preferences.H +Fl_Printer.o: ../FL/Fl_Tile.H ../FL/Fl_Group.H ../FL/Fl_File_Browser.H +Fl_Printer.o: ../FL/Fl_Browser.H ../FL/Fl_Browser_.H ../FL/Fl_Scrollbar.H +Fl_Printer.o: ../FL/Fl_Slider.H ../FL/Fl_Valuator.H ../FL/Fl_File_Icon.H +Fl_Printer.o: ../FL/Fl.H ../FL/filename.H ../FL/Fl_Box.H +Fl_Printer.o: ../FL/Fl_Check_Button.H ../FL/Fl_Light_Button.H +Fl_Printer.o: ../FL/Fl_Button.H ../FL/Fl_File_Input.H ../FL/Fl_Input.H +Fl_Printer.o: ../FL/Fl_Input_.H ../FL/Fl_Return_Button.H print_panel.cxx +Fl_Printer.o: print_panel.h ../FL/Fl_Round_Button.H ../FL/Fl_Spinner.H +Fl_Printer.o: ../FL/Enumerations.H ../FL/Fl_Repeat_Button.H +Fl_Printer.o: ../FL/Fl_Progress.H ../src/flstring.h ../FL/Fl_Export.H +Fl_Printer.o: ../config.h ../FL/Fl_Int_Input.H ../FL/Fl_Input.H +Fl_Progress.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +Fl_Progress.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Progress.H +Fl_Progress.o: ../FL/Fl_Widget.H ../FL/fl_draw.H ../FL/Fl_Window.H +Fl_Progress.o: ../FL/Fl_Device.H ../FL/x.H ../FL/Fl_Plugin.H +Fl_Progress.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H +Fl_Progress.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +Fl_Repeat_Button.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +Fl_Repeat_Button.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H +Fl_Repeat_Button.o: ../FL/Fl_Repeat_Button.H ../FL/Fl.H ../FL/Fl_Button.H +Fl_Repeat_Button.o: ../FL/Fl_Widget.H +Fl_Return_Button.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +Fl_Return_Button.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H +Fl_Return_Button.o: ../FL/Fl_Return_Button.H ../FL/Fl_Button.H +Fl_Return_Button.o: ../FL/Fl_Widget.H ../FL/fl_draw.H ../FL/Fl_Window.H +Fl_Return_Button.o: ../FL/Fl_Device.H ../FL/x.H ../FL/Fl_Plugin.H +Fl_Return_Button.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H +Fl_Return_Button.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +Fl_Roller.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +Fl_Roller.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Roller.H +Fl_Roller.o: ../FL/Fl_Valuator.H ../FL/Fl_Widget.H ../FL/fl_draw.H +Fl_Roller.o: ../FL/Fl_Window.H ../FL/Fl_Device.H ../FL/x.H ../FL/Fl_Plugin.H +Fl_Roller.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H +Fl_Roller.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +Fl_Round_Button.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +Fl_Round_Button.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H +Fl_Round_Button.o: ../FL/Fl_Round_Button.H ../FL/Fl_Light_Button.H +Fl_Round_Button.o: ../FL/Fl_Button.H ../FL/Fl_Widget.H +Fl_Scroll.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +Fl_Scroll.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Tiled_Image.H +Fl_Scroll.o: ../FL/Fl_Image.H ../FL/Fl_Scroll.H ../FL/Fl_Group.H +Fl_Scroll.o: ../FL/Fl_Widget.H ../FL/Fl_Scrollbar.H ../FL/Fl_Slider.H +Fl_Scroll.o: ../FL/Fl_Valuator.H ../FL/fl_draw.H ../FL/Fl_Window.H +Fl_Scroll.o: ../FL/Fl_Device.H ../FL/x.H ../FL/Fl_Plugin.H +Fl_Scroll.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H +Fl_Scroll.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +Fl_Scrollbar.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +Fl_Scrollbar.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Scrollbar.H +Fl_Scrollbar.o: ../FL/Fl_Slider.H ../FL/Fl_Valuator.H ../FL/Fl_Widget.H +Fl_Scrollbar.o: ../FL/fl_draw.H ../FL/Fl_Window.H ../FL/Fl_Device.H ../FL/x.H +Fl_Scrollbar.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H +Fl_Scrollbar.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Pixmap.H +Fl_Scrollbar.o: ../FL/Fl_RGB_Image.H flstring.h ../FL/Fl_Export.H ../config.h +Fl_Shared_Image.o: ../FL/fl_utf8.h flstring.h ../FL/Fl_Export.H ../config.h +Fl_Shared_Image.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +Fl_Shared_Image.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H +Fl_Shared_Image.o: ../FL/Fl_Shared_Image.H ../FL/Fl_Image.H +Fl_Shared_Image.o: ../FL/Fl_XBM_Image.H ../FL/Fl_Bitmap.H +Fl_Shared_Image.o: ../FL/Fl_XPM_Image.H ../FL/Fl_Pixmap.H +Fl_Single_Window.o: ../FL/Fl_Single_Window.H ../FL/Fl_Window.H +Fl_Slider.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +Fl_Slider.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Slider.H +Fl_Slider.o: ../FL/Fl_Valuator.H ../FL/Fl_Widget.H ../FL/fl_draw.H +Fl_Slider.o: ../FL/Fl_Window.H ../FL/Fl_Device.H ../FL/x.H ../FL/Fl_Plugin.H +Fl_Slider.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H +Fl_Slider.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +Fl_Slider.o: flstring.h ../FL/Fl_Export.H ../config.h +Fl_Table.o: ../FL/fl_draw.H ../FL/Enumerations.H ../FL/Fl_Export.H +Fl_Table.o: ../FL/fl_types.h ../FL/Fl_Window.H ../FL/Fl_Device.H ../FL/x.H +Fl_Table.o: ../FL/Xutf8.h ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H +Fl_Table.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H +Fl_Table.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H ../FL/Fl_Table.H +Fl_Table.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Group.H ../FL/Fl_Scroll.H +Fl_Table.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Scrollbar.H +Fl_Table.o: ../FL/Fl_Slider.H ../FL/Fl_Valuator.H ../FL/Fl_Box.H +Fl_Table.o: ../FL/Fl_Scrollbar.H +Fl_Table_Row.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +Fl_Table_Row.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/fl_draw.H +Fl_Table_Row.o: ../FL/Fl_Window.H ../FL/Fl_Device.H ../FL/x.H +Fl_Table_Row.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H +Fl_Table_Row.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Pixmap.H +Fl_Table_Row.o: ../FL/Fl_RGB_Image.H ../FL/Fl_Table_Row.H ../FL/Fl_Table.H +Fl_Table_Row.o: ../FL/Fl_Group.H ../FL/Fl_Scroll.H ../FL/Fl_Group.H +Fl_Table_Row.o: ../FL/Fl_Widget.H ../FL/Fl_Scrollbar.H ../FL/Fl_Slider.H +Fl_Table_Row.o: ../FL/Fl_Valuator.H ../FL/Fl_Box.H ../FL/Fl_Scrollbar.H +Fl_Tabs.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +Fl_Tabs.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Tabs.H +Fl_Tabs.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/fl_draw.H +Fl_Tabs.o: ../FL/Fl_Window.H ../FL/Fl_Device.H ../FL/x.H ../FL/Fl_Plugin.H +Fl_Tabs.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H +Fl_Tabs.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +Fl_Tabs.o: ../FL/Fl_Tooltip.H ../FL/Fl_Widget.H +Fl_Text_Buffer.o: ../FL/fl_utf8.h flstring.h ../FL/Fl_Export.H ../config.h +Fl_Text_Buffer.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +Fl_Text_Buffer.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H +Fl_Text_Buffer.o: ../FL/Fl_Text_Buffer.H +Fl_Text_Display.o: ../FL/fl_utf8.h flstring.h ../FL/Fl_Export.H ../config.h +Fl_Text_Display.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +Fl_Text_Display.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H +Fl_Text_Display.o: ../FL/Fl_Text_Buffer.H ../FL/Fl_Text_Display.H +Fl_Text_Display.o: ../FL/fl_draw.H ../FL/Fl_Window.H ../FL/Fl_Device.H +Fl_Text_Display.o: ../FL/x.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H +Fl_Text_Display.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H +Fl_Text_Display.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H ../FL/Fl_Group.H +Fl_Text_Display.o: ../FL/Fl_Widget.H ../FL/Fl_Scrollbar.H ../FL/Fl_Slider.H +Fl_Text_Display.o: ../FL/Fl_Valuator.H ../FL/Fl_Text_Buffer.H +Fl_Text_Display.o: ../FL/Fl_Window.H +Fl_Text_Editor.o: flstring.h ../FL/Fl_Export.H ../config.h ../FL/Fl.H +Fl_Text_Editor.o: ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +Fl_Text_Editor.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Window.H +Fl_Text_Editor.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Text_Editor.H +Fl_Text_Editor.o: ../FL/Fl_Text_Display.H ../FL/fl_draw.H ../FL/Fl_Window.H +Fl_Text_Editor.o: ../FL/Fl_Device.H ../FL/x.H ../FL/Fl_Plugin.H +Fl_Text_Editor.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H +Fl_Text_Editor.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +Fl_Text_Editor.o: ../FL/Fl_Scrollbar.H ../FL/Fl_Slider.H ../FL/Fl_Valuator.H +Fl_Text_Editor.o: ../FL/Fl_Text_Buffer.H ../FL/fl_ask.H +Fl_Tile.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +Fl_Tile.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Tile.H +Fl_Tile.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Window.H +Fl_Tiled_Image.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +Fl_Tiled_Image.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H +Fl_Tiled_Image.o: ../FL/Fl_Tiled_Image.H ../FL/Fl_Image.H ../FL/fl_draw.H +Fl_Tiled_Image.o: ../FL/Fl_Window.H ../FL/Fl_Device.H ../FL/x.H +Fl_Tiled_Image.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H +Fl_Tiled_Image.o: ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +Fl_Tree.o: ../FL/Fl_Tree.H ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +Fl_Tree.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H +Fl_Tree.o: ../FL/Fl_Group.H ../FL/Fl_Scrollbar.H ../FL/Fl_Slider.H +Fl_Tree.o: ../FL/Fl_Valuator.H ../FL/Fl_Widget.H ../FL/fl_draw.H +Fl_Tree.o: ../FL/Fl_Window.H ../FL/Fl_Device.H ../FL/x.H ../FL/Fl_Plugin.H +Fl_Tree.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H +Fl_Tree.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +Fl_Tree.o: ../FL/Fl_Tree_Item.H ../FL/Fl_Widget.H ../FL/Fl_Tree_Item_Array.H +Fl_Tree.o: ../FL/Fl_Tree_Prefs.H +Fl_Tree_Item.o: ../FL/Fl_Widget.H ../FL/Fl_Tree_Item.H ../FL/Fl.H +Fl_Tree_Item.o: ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +Fl_Tree_Item.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Image.H +Fl_Tree_Item.o: ../FL/fl_draw.H ../FL/Fl_Window.H ../FL/Fl_Device.H ../FL/x.H +Fl_Tree_Item.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Bitmap.H +Fl_Tree_Item.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +Fl_Tree_Item.o: ../FL/Fl_Tree_Item_Array.H ../FL/Fl_Tree_Prefs.H +Fl_Tree_Item_Array.o: ../FL/Fl_Tree_Item_Array.H ../FL/Fl_Tree_Item.H +Fl_Tree_Item_Array.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +Fl_Tree_Item_Array.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H +Fl_Tree_Item_Array.o: ../FL/Fl_Widget.H ../FL/Fl_Image.H ../FL/fl_draw.H +Fl_Tree_Item_Array.o: ../FL/Fl_Window.H ../FL/Fl_Device.H ../FL/x.H +Fl_Tree_Item_Array.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H +Fl_Tree_Item_Array.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Pixmap.H +Fl_Tree_Item_Array.o: ../FL/Fl_RGB_Image.H ../FL/Fl_Tree_Prefs.H +Fl_Tree_Prefs.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +Fl_Tree_Prefs.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H +Fl_Tree_Prefs.o: ../FL/Fl_Pixmap.H ../FL/Fl_Image.H ../FL/Fl_Tree_Prefs.H +Fl_Tooltip.o: ../FL/Fl_Tooltip.H ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +Fl_Tooltip.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H +Fl_Tooltip.o: ../FL/Fl_Widget.H ../FL/fl_draw.H ../FL/Fl_Window.H +Fl_Tooltip.o: ../FL/Fl_Device.H ../FL/x.H ../FL/Fl_Plugin.H +Fl_Tooltip.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H +Fl_Tooltip.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +Fl_Tooltip.o: ../FL/Fl_Menu_Window.H ../FL/Fl_Single_Window.H +Fl_Valuator.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +Fl_Valuator.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Valuator.H +Fl_Valuator.o: ../FL/Fl_Widget.H ../FL/math.h flstring.h ../FL/Fl_Export.H +Fl_Valuator.o: ../config.h +Fl_Value_Input.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +Fl_Value_Input.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H +Fl_Value_Input.o: ../FL/Fl_Value_Input.H ../FL/Fl_Valuator.H +Fl_Value_Input.o: ../FL/Fl_Widget.H ../FL/Fl_Input.H ../FL/Fl_Input_.H +Fl_Value_Input.o: ../FL/Fl_Group.H ../FL/math.h +Fl_Value_Output.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +Fl_Value_Output.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H +Fl_Value_Output.o: ../FL/Fl_Value_Output.H ../FL/Fl_Valuator.H +Fl_Value_Output.o: ../FL/Fl_Widget.H ../FL/fl_draw.H ../FL/Fl_Window.H +Fl_Value_Output.o: ../FL/Fl_Device.H ../FL/x.H ../FL/Fl_Plugin.H +Fl_Value_Output.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H +Fl_Value_Output.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +Fl_Value_Slider.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +Fl_Value_Slider.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H +Fl_Value_Slider.o: ../FL/Fl_Value_Slider.H ../FL/Fl_Slider.H +Fl_Value_Slider.o: ../FL/Fl_Valuator.H ../FL/Fl_Widget.H ../FL/fl_draw.H +Fl_Value_Slider.o: ../FL/Fl_Window.H ../FL/Fl_Device.H ../FL/x.H +Fl_Value_Slider.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H +Fl_Value_Slider.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Pixmap.H +Fl_Value_Slider.o: ../FL/Fl_RGB_Image.H +Fl_Widget.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +Fl_Widget.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Widget.H +Fl_Widget.o: ../FL/Fl_Group.H ../FL/Fl_Tooltip.H ../FL/fl_draw.H +Fl_Widget.o: ../FL/Fl_Window.H ../FL/Fl_Device.H ../FL/x.H ../FL/Fl_Plugin.H +Fl_Widget.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H +Fl_Widget.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +Fl_Widget.o: flstring.h ../FL/Fl_Export.H ../config.h +Fl_Window.o: ../config.h ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +Fl_Window.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H ../FL/x.H +Fl_Window.o: ../FL/Fl_Window.H ../FL/Fl_Window.H ../FL/Fl_Group.H +Fl_Window.o: ../FL/Fl_Widget.H flstring.h ../FL/Fl_Export.H +Fl_Window_fullscreen.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +Fl_Window_fullscreen.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H +Fl_Window_fullscreen.o: ../FL/x.H ../FL/Fl_Window.H ../config.h +Fl_Window_hotspot.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +Fl_Window_hotspot.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H +Fl_Window_hotspot.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Widget.H +Fl_Window_hotspot.o: ../FL/x.H ../FL/Fl_Window.H +Fl_Window_iconize.o: ../FL/x.H ../FL/Enumerations.H ../FL/Fl_Export.H +Fl_Window_iconize.o: ../FL/fl_types.h ../FL/Fl_Window.H ../FL/Xutf8.h +Fl_Wizard.o: ../FL/Fl_Wizard.H ../FL/Fl_Group.H ../FL/Fl_Window.H +Fl_Wizard.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Enumerations.H +Fl_Wizard.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/fl_draw.H +Fl_Wizard.o: ../FL/Fl_Window.H ../FL/Fl_Device.H ../FL/x.H ../FL/Xutf8.h +Fl_Wizard.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H +Fl_Wizard.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Pixmap.H +Fl_Wizard.o: ../FL/Fl_RGB_Image.H +Fl_XBM_Image.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +Fl_XBM_Image.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_XBM_Image.H +Fl_XBM_Image.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/fl_utf8.h flstring.h +Fl_XBM_Image.o: ../FL/Fl_Export.H ../config.h +Fl_XPM_Image.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +Fl_XPM_Image.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_XPM_Image.H +Fl_XPM_Image.o: ../FL/Fl_Pixmap.H ../FL/Fl_Image.H ../FL/fl_utf8.h flstring.h +Fl_XPM_Image.o: ../FL/Fl_Export.H ../config.h +Fl_abort.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +Fl_abort.o: ../FL/Xutf8.h ../FL/Enumerations.H flstring.h ../FL/Fl_Export.H +Fl_abort.o: ../config.h +Fl_add_idle.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +Fl_add_idle.o: ../FL/Xutf8.h ../FL/Enumerations.H +Fl_arg.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +Fl_arg.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/x.H ../FL/Fl_Window.H +Fl_arg.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Widget.H +Fl_arg.o: ../FL/Fl_Tooltip.H ../FL/Fl_Widget.H ../FL/filename.H +Fl_arg.o: ../FL/fl_draw.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H +Fl_arg.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H +Fl_arg.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H flstring.h +Fl_arg.o: ../FL/Fl_Export.H ../config.h +Fl_compose.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +Fl_compose.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/x.H ../FL/Fl_Window.H +Fl_display.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +Fl_display.o: ../FL/Xutf8.h ../FL/Enumerations.H flstring.h ../FL/Fl_Export.H +Fl_display.o: ../config.h +Fl_get_key.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +Fl_get_key.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/x.H ../FL/Fl_Window.H +Fl_get_system_colors.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +Fl_get_system_colors.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H +Fl_get_system_colors.o: ../FL/fl_draw.H ../FL/Fl_Window.H ../FL/Fl_Device.H +Fl_get_system_colors.o: ../FL/x.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H +Fl_get_system_colors.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H +Fl_get_system_colors.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H ../FL/math.h +Fl_get_system_colors.o: ../FL/fl_utf8.h flstring.h ../FL/Fl_Export.H +Fl_get_system_colors.o: ../config.h ../FL/Fl_Tiled_Image.H tile.xpm +Fl_grab.o: ../config.h ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +Fl_grab.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H ../FL/x.H +Fl_grab.o: ../FL/Fl_Window.H +Fl_lock.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +Fl_lock.o: ../FL/Xutf8.h ../FL/Enumerations.H ../config.h +Fl_own_colormap.o: ../config.h ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +Fl_own_colormap.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H +Fl_own_colormap.o: ../FL/x.H ../FL/Fl_Window.H +Fl_visual.o: ../config.h ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +Fl_visual.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H ../FL/x.H +Fl_visual.o: ../FL/Fl_Window.H +Fl_x.o: ../config.h ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +Fl_x.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H ../FL/x.H +Fl_x.o: ../FL/Fl_Window.H ../FL/Fl_Window.H ../FL/Fl_Group.H +Fl_x.o: ../FL/Fl_Widget.H ../FL/fl_utf8.h ../FL/Fl_Tooltip.H +Fl_x.o: ../FL/Fl_Widget.H ../FL/fl_draw.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H +Fl_x.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H +Fl_x.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H flstring.h +Fl_x.o: ../FL/Fl_Export.H +filename_absolute.o: ../FL/filename.H ../FL/fl_utf8.h flstring.h +filename_absolute.o: ../FL/Fl_Export.H ../config.h +filename_expand.o: ../FL/filename.H ../FL/fl_utf8.h flstring.h +filename_expand.o: ../FL/Fl_Export.H ../config.h +filename_ext.o: ../FL/filename.H +filename_isdir.o: flstring.h ../FL/Fl_Export.H ../config.h ../FL/filename.H +filename_isdir.o: ../FL/fl_utf8.h +filename_list.o: ../FL/filename.H flstring.h ../FL/Fl_Export.H ../config.h +filename_match.o: ../FL/filename.H +filename_setext.o: ../FL/filename.H flstring.h ../FL/Fl_Export.H ../config.h +fl_arc.o: ../FL/fl_draw.H ../FL/Enumerations.H ../FL/Fl_Export.H +fl_arc.o: ../FL/fl_types.h ../FL/Fl_Window.H ../FL/Fl_Device.H ../FL/x.H +fl_arc.o: ../FL/Xutf8.h ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H +fl_arc.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H +fl_arc.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H ../FL/math.h +fl_arci.o: ../FL/fl_draw.H ../FL/Enumerations.H ../FL/Fl_Export.H +fl_arci.o: ../FL/fl_types.h ../FL/Fl_Window.H ../FL/Fl_Device.H ../FL/x.H +fl_arci.o: ../FL/Xutf8.h ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H +fl_arci.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H +fl_arci.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H ../config.h +fl_ask.o: flstring.h ../FL/Fl_Export.H ../config.h ../FL/Fl.H ../FL/fl_utf8.h +fl_ask.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Xutf8.h +fl_ask.o: ../FL/Enumerations.H ../FL/fl_ask.H ../FL/Fl_Box.H +fl_ask.o: ../FL/Fl_Widget.H ../FL/Fl_Button.H ../FL/Fl_Return_Button.H +fl_ask.o: ../FL/Fl_Button.H ../FL/Fl_Window.H ../FL/Fl_Group.H +fl_ask.o: ../FL/Fl_Input.H ../FL/Fl_Input_.H ../FL/Fl_Secret_Input.H +fl_ask.o: ../FL/Fl_Input.H ../FL/x.H ../FL/Fl_Window.H ../FL/fl_draw.H +fl_ask.o: ../FL/Fl_Device.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H +fl_ask.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H +fl_ask.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +fl_boxtype.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +fl_boxtype.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Widget.H +fl_boxtype.o: ../FL/fl_draw.H ../FL/Fl_Window.H ../FL/Fl_Device.H ../FL/x.H +fl_boxtype.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H +fl_boxtype.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Pixmap.H +fl_boxtype.o: ../FL/Fl_RGB_Image.H ../config.h +fl_color.o: Fl_XColor.H ../config.h ../FL/Enumerations.H ../FL/Fl.H +fl_color.o: ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Xutf8.h +fl_color.o: ../FL/Enumerations.H ../FL/x.H ../FL/Fl_Window.H ../FL/fl_draw.H +fl_color.o: ../FL/Fl_Device.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H +fl_color.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H +fl_color.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H fl_cmap.h +fl_cursor.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +fl_cursor.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Window.H +fl_cursor.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/x.H ../FL/Fl_Window.H +fl_cursor.o: ../FL/fl_draw.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H +fl_cursor.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H +fl_cursor.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +fl_curve.o: ../FL/fl_draw.H ../FL/Enumerations.H ../FL/Fl_Export.H +fl_curve.o: ../FL/fl_types.h ../FL/Fl_Window.H ../FL/Fl_Device.H ../FL/x.H +fl_curve.o: ../FL/Xutf8.h ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H +fl_curve.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H +fl_curve.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +fl_diamond_box.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +fl_diamond_box.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H +fl_diamond_box.o: ../FL/fl_draw.H ../FL/Fl_Window.H ../FL/Fl_Device.H +fl_diamond_box.o: ../FL/x.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H +fl_diamond_box.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H +fl_diamond_box.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +fl_dnd.o: fl_dnd_x.cxx ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +fl_dnd.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H +fl_dnd.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/x.H +fl_dnd.o: ../FL/Fl_Window.H flstring.h ../FL/Fl_Export.H ../config.h +fl_draw.o: ../FL/fl_utf8.h ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +fl_draw.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H +fl_draw.o: ../FL/fl_draw.H ../FL/Fl_Window.H ../FL/Fl_Device.H ../FL/x.H +fl_draw.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H +fl_draw.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Pixmap.H +fl_draw.o: ../FL/Fl_RGB_Image.H flstring.h ../FL/Fl_Export.H ../config.h +fl_draw_image.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +fl_draw_image.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H +fl_draw_image.o: ../FL/fl_draw.H ../FL/Fl_Window.H ../FL/Fl_Device.H +fl_draw_image.o: ../FL/x.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H +fl_draw_image.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H +fl_draw_image.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H Fl_XColor.H +fl_draw_image.o: ../config.h ../FL/Enumerations.H flstring.h +fl_draw_image.o: ../FL/Fl_Export.H +fl_draw_pixmap.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +fl_draw_pixmap.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H +fl_draw_pixmap.o: ../FL/fl_draw.H ../FL/Fl_Window.H ../FL/Fl_Device.H +fl_draw_pixmap.o: ../FL/x.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H +fl_draw_pixmap.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H +fl_draw_pixmap.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H flstring.h +fl_draw_pixmap.o: ../FL/Fl_Export.H ../config.h +fl_encoding_latin1.o: ../FL/fl_draw.H ../FL/Enumerations.H ../FL/Fl_Export.H +fl_encoding_latin1.o: ../FL/fl_types.h ../FL/Fl_Window.H ../FL/Fl_Device.H +fl_encoding_latin1.o: ../FL/x.H ../FL/Xutf8.h ../FL/Fl_Plugin.H +fl_encoding_latin1.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H +fl_encoding_latin1.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Pixmap.H +fl_encoding_latin1.o: ../FL/Fl_RGB_Image.H ../FL/Enumerations.H flstring.h +fl_encoding_latin1.o: ../FL/Fl_Export.H ../config.h +fl_encoding_mac_roman.o: ../FL/fl_draw.H ../FL/Enumerations.H +fl_encoding_mac_roman.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Fl_Window.H +fl_encoding_mac_roman.o: ../FL/Fl_Device.H ../FL/x.H ../FL/Xutf8.h +fl_encoding_mac_roman.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H +fl_encoding_mac_roman.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H +fl_encoding_mac_roman.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +fl_encoding_mac_roman.o: ../FL/Enumerations.H flstring.h ../FL/Fl_Export.H +fl_encoding_mac_roman.o: ../config.h +fl_engraved_label.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +fl_engraved_label.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H +fl_engraved_label.o: ../FL/Fl_Widget.H ../FL/fl_draw.H ../FL/Fl_Window.H +fl_engraved_label.o: ../FL/Fl_Device.H ../FL/x.H ../FL/Fl_Plugin.H +fl_engraved_label.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H +fl_engraved_label.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Pixmap.H +fl_engraved_label.o: ../FL/Fl_RGB_Image.H +fl_file_dir.o: flstring.h ../FL/Fl_Export.H ../config.h ../FL/filename.H +fl_file_dir.o: ../FL/Fl_File_Chooser.H ../FL/Fl.H ../FL/fl_utf8.h +fl_file_dir.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Xutf8.h +fl_file_dir.o: ../FL/Enumerations.H ../FL/Fl_Double_Window.H +fl_file_dir.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Choice.H +fl_file_dir.o: ../FL/Fl_Menu_.H ../FL/Fl_Widget.H ../FL/Fl_Menu_Item.H +fl_file_dir.o: ../FL/Fl_Image.H ../FL/Fl_Menu_Button.H ../FL/Fl_Button.H +fl_file_dir.o: ../FL/Fl_Preferences.H ../FL/Fl_Tile.H ../FL/Fl_Group.H +fl_file_dir.o: ../FL/Fl_File_Browser.H ../FL/Fl_Browser.H ../FL/Fl_Browser_.H +fl_file_dir.o: ../FL/Fl_Scrollbar.H ../FL/Fl_Slider.H ../FL/Fl_Valuator.H +fl_file_dir.o: ../FL/Fl_File_Icon.H ../FL/Fl.H ../FL/filename.H +fl_file_dir.o: ../FL/Fl_Box.H ../FL/Fl_Check_Button.H ../FL/Fl_Light_Button.H +fl_file_dir.o: ../FL/Fl_Button.H ../FL/Fl_File_Input.H ../FL/Fl_Input.H +fl_file_dir.o: ../FL/Fl_Input_.H ../FL/Fl_Return_Button.H ../FL/fl_ask.H +fl_font.o: flstring.h ../FL/Fl_Export.H ../config.h ../FL/Fl.H +fl_font.o: ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Xutf8.h +fl_font.o: ../FL/Enumerations.H ../FL/fl_draw.H ../FL/Fl_Window.H +fl_font.o: ../FL/Fl_Device.H ../FL/x.H ../FL/Fl_Plugin.H +fl_font.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H +fl_font.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H Fl_Font.H +fl_font.o: fl_font_xft.cxx +fl_gtk.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +fl_gtk.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/fl_draw.H +fl_gtk.o: ../FL/Fl_Window.H ../FL/Fl_Device.H ../FL/x.H ../FL/Fl_Plugin.H +fl_gtk.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H +fl_gtk.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +fl_labeltype.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +fl_labeltype.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Widget.H +fl_labeltype.o: ../FL/Fl_Group.H ../FL/fl_draw.H ../FL/Fl_Window.H +fl_labeltype.o: ../FL/Fl_Device.H ../FL/x.H ../FL/Fl_Plugin.H +fl_labeltype.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H +fl_labeltype.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +fl_labeltype.o: ../FL/Fl_Input_.H ../FL/Fl_Widget.H +fl_line_style.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +fl_line_style.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H +fl_line_style.o: ../FL/fl_draw.H ../FL/Fl_Window.H ../FL/Fl_Device.H +fl_line_style.o: ../FL/x.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H +fl_line_style.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H +fl_line_style.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H ../FL/Fl_Printer.H +fl_line_style.o: ../FL/Fl_Paged_Device.H ../FL/Fl_Device.H +fl_line_style.o: ../FL/Fl_PostScript.H flstring.h ../FL/Fl_Export.H +fl_line_style.o: ../config.h ../FL/fl_ask.H +fl_open_uri.o: ../FL/filename.H flstring.h ../FL/Fl_Export.H ../config.h +fl_oval_box.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +fl_oval_box.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/fl_draw.H +fl_oval_box.o: ../FL/Fl_Window.H ../FL/Fl_Device.H ../FL/x.H +fl_oval_box.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H +fl_oval_box.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Pixmap.H +fl_oval_box.o: ../FL/Fl_RGB_Image.H +fl_overlay.o: ../FL/x.H ../FL/Enumerations.H ../FL/Fl_Export.H +fl_overlay.o: ../FL/fl_types.h ../FL/Fl_Window.H ../FL/Xutf8.h +fl_overlay.o: ../FL/fl_draw.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H +fl_overlay.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H +fl_overlay.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +fl_overlay_visual.o: ../config.h +fl_plastic.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +fl_plastic.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/fl_draw.H +fl_plastic.o: ../FL/Fl_Window.H ../FL/Fl_Device.H ../FL/x.H ../FL/Fl_Plugin.H +fl_plastic.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H +fl_plastic.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +fl_plastic.o: flstring.h ../FL/Fl_Export.H ../config.h +fl_read_image.o: ../FL/x.H ../FL/Enumerations.H ../FL/Fl_Export.H +fl_read_image.o: ../FL/fl_types.h ../FL/Fl_Window.H ../FL/Xutf8.h ../FL/Fl.H +fl_read_image.o: ../FL/fl_utf8.h ../FL/fl_draw.H ../FL/Fl_Device.H +fl_read_image.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H +fl_read_image.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Pixmap.H +fl_read_image.o: ../FL/Fl_RGB_Image.H flstring.h ../FL/Fl_Export.H +fl_read_image.o: ../config.h +fl_rect.o: ../config.h ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +fl_rect.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H +fl_rect.o: ../FL/Fl_Widget.H ../FL/Fl_Printer.H ../FL/Fl_Paged_Device.H +fl_rect.o: ../FL/Fl_Device.H ../FL/fl_draw.H ../FL/Fl_Window.H +fl_rect.o: ../FL/Fl_Device.H ../FL/x.H ../FL/Fl_Plugin.H +fl_rect.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H +fl_rect.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +fl_rect.o: ../FL/Fl_PostScript.H +fl_round_box.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +fl_round_box.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/fl_draw.H +fl_round_box.o: ../FL/Fl_Window.H ../FL/Fl_Device.H ../FL/x.H +fl_round_box.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H +fl_round_box.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Pixmap.H +fl_round_box.o: ../FL/Fl_RGB_Image.H +fl_rounded_box.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +fl_rounded_box.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H +fl_rounded_box.o: ../FL/fl_draw.H ../FL/Fl_Window.H ../FL/Fl_Device.H +fl_rounded_box.o: ../FL/x.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H +fl_rounded_box.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H +fl_rounded_box.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +fl_set_font.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +fl_set_font.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/x.H ../FL/Fl_Window.H +fl_set_font.o: ../FL/fl_draw.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H +fl_set_font.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H +fl_set_font.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +fl_set_font.o: flstring.h ../FL/Fl_Export.H ../config.h Fl_Font.H +fl_set_fonts.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +fl_set_fonts.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/x.H +fl_set_fonts.o: ../FL/Fl_Window.H Fl_Font.H ../config.h flstring.h +fl_set_fonts.o: ../FL/Fl_Export.H fl_set_fonts_xft.cxx +fl_scroll_area.o: ../config.h ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +fl_scroll_area.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H +fl_scroll_area.o: ../FL/x.H ../FL/Fl_Window.H ../FL/fl_draw.H +fl_scroll_area.o: ../FL/Fl_Device.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H +fl_scroll_area.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H +fl_scroll_area.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +fl_shadow_box.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +fl_shadow_box.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H +fl_shadow_box.o: ../FL/fl_draw.H ../FL/Fl_Window.H ../FL/Fl_Device.H +fl_shadow_box.o: ../FL/x.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H +fl_shadow_box.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H +fl_shadow_box.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +fl_shortcut.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +fl_shortcut.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Widget.H +fl_shortcut.o: ../FL/Fl_Button.H ../FL/Fl_Widget.H ../FL/fl_draw.H +fl_shortcut.o: ../FL/Fl_Window.H ../FL/Fl_Device.H ../FL/x.H +fl_shortcut.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H +fl_shortcut.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Pixmap.H +fl_shortcut.o: ../FL/Fl_RGB_Image.H flstring.h ../FL/Fl_Export.H ../config.h +fl_show_colormap.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +fl_show_colormap.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H +fl_show_colormap.o: ../FL/Fl_Single_Window.H ../FL/Fl_Window.H +fl_show_colormap.o: ../FL/fl_draw.H ../FL/Fl_Device.H ../FL/x.H +fl_show_colormap.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H +fl_show_colormap.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Pixmap.H +fl_show_colormap.o: ../FL/Fl_RGB_Image.H ../FL/fl_show_colormap.H ../config.h +fl_symbols.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +fl_symbols.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/fl_draw.H +fl_symbols.o: ../FL/Fl_Window.H ../FL/Fl_Device.H ../FL/x.H ../FL/Fl_Plugin.H +fl_symbols.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H +fl_symbols.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +fl_symbols.o: ../FL/math.h flstring.h ../FL/Fl_Export.H ../config.h +fl_vertex.o: ../config.h ../FL/fl_draw.H ../FL/Enumerations.H +fl_vertex.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Fl_Window.H +fl_vertex.o: ../FL/Fl_Device.H ../FL/x.H ../FL/Xutf8.h ../FL/Fl_Plugin.H +fl_vertex.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H +fl_vertex.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +fl_vertex.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/math.h +screen_xywh.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +screen_xywh.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/x.H ../FL/Fl_Window.H +screen_xywh.o: ../config.h +fl_utf8.o: ../config.h ../FL/filename.H ../FL/Xutf8.h ../FL/fl_utf8.h +ps_image.o: ../FL/Fl_PostScript.H ../FL/Fl_Paged_Device.H ../FL/Fl_Device.H +ps_image.o: ../FL/fl_draw.H ../FL/Enumerations.H ../FL/Fl_Export.H +ps_image.o: ../FL/fl_types.h ../FL/Fl_Window.H ../FL/Fl_Device.H ../FL/x.H +ps_image.o: ../FL/Xutf8.h ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H +ps_image.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H +ps_image.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H ../FL/Fl.H ../FL/fl_utf8.h +forms_compatability.o: ../FL/forms.H ../FL/Fl.H ../FL/fl_utf8.h +forms_compatability.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Xutf8.h +forms_compatability.o: ../FL/Enumerations.H ../FL/Fl_Group.H +forms_compatability.o: ../FL/Fl_Widget.H ../FL/Fl_Window.H ../FL/fl_draw.H +forms_compatability.o: ../FL/Fl_Device.H ../FL/x.H ../FL/Fl_Plugin.H +forms_compatability.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H +forms_compatability.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Pixmap.H +forms_compatability.o: ../FL/Fl_RGB_Image.H ../FL/Fl_FormsBitmap.H +forms_compatability.o: ../FL/Fl_Bitmap.H ../FL/Fl_FormsPixmap.H +forms_compatability.o: ../FL/Fl_Pixmap.H ../FL/Fl_Box.H ../FL/Fl_Browser.H +forms_compatability.o: ../FL/Fl_Browser_.H ../FL/Fl_Scrollbar.H +forms_compatability.o: ../FL/Fl_Slider.H ../FL/Fl_Valuator.H ../FL/Fl.H +forms_compatability.o: ../FL/Fl_Button.H ../FL/Fl_Light_Button.H +forms_compatability.o: ../FL/Fl_Round_Button.H ../FL/Fl_Check_Button.H +forms_compatability.o: ../FL/Fl_Chart.H ../FL/Fl_Choice.H ../FL/Fl_Menu_.H +forms_compatability.o: ../FL/Fl_Menu_Item.H ../FL/Fl_Clock.H +forms_compatability.o: ../FL/Fl_Counter.H ../FL/Fl_Dial.H ../FL/Fl_Free.H +forms_compatability.o: ../FL/fl_ask.H ../FL/fl_show_colormap.H +forms_compatability.o: ../FL/filename.H ../FL/Fl_File_Chooser.H +forms_compatability.o: ../FL/Fl_Double_Window.H ../FL/Fl_Group.H +forms_compatability.o: ../FL/Fl_Choice.H ../FL/Fl_Menu_Button.H +forms_compatability.o: ../FL/Fl_Button.H ../FL/Fl_Preferences.H +forms_compatability.o: ../FL/Fl_Tile.H ../FL/Fl_File_Browser.H +forms_compatability.o: ../FL/Fl_File_Icon.H ../FL/Fl_Box.H +forms_compatability.o: ../FL/Fl_Check_Button.H ../FL/Fl_File_Input.H +forms_compatability.o: ../FL/Fl_Input.H ../FL/Fl_Input_.H +forms_compatability.o: ../FL/Fl_Return_Button.H ../FL/fl_ask.H +forms_compatability.o: ../FL/Fl_Input.H ../FL/Fl_Menu_Button.H +forms_compatability.o: ../FL/Fl_Positioner.H ../FL/Fl_Value_Slider.H +forms_compatability.o: ../FL/Fl_Timer.H ../FL/Fl_Repeat_Button.H +forms_bitmap.o: ../FL/forms.H ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +forms_bitmap.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H +forms_bitmap.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Window.H +forms_bitmap.o: ../FL/fl_draw.H ../FL/Fl_Device.H ../FL/x.H ../FL/Fl_Plugin.H +forms_bitmap.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H +forms_bitmap.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +forms_bitmap.o: ../FL/Fl_FormsBitmap.H ../FL/Fl_Bitmap.H +forms_bitmap.o: ../FL/Fl_FormsPixmap.H ../FL/Fl_Pixmap.H ../FL/Fl_Box.H +forms_bitmap.o: ../FL/Fl_Browser.H ../FL/Fl_Browser_.H ../FL/Fl_Scrollbar.H +forms_bitmap.o: ../FL/Fl_Slider.H ../FL/Fl_Valuator.H ../FL/Fl.H +forms_bitmap.o: ../FL/Fl_Button.H ../FL/Fl_Light_Button.H +forms_bitmap.o: ../FL/Fl_Round_Button.H ../FL/Fl_Check_Button.H +forms_bitmap.o: ../FL/Fl_Chart.H ../FL/Fl_Choice.H ../FL/Fl_Menu_.H +forms_bitmap.o: ../FL/Fl_Menu_Item.H ../FL/Fl_Clock.H ../FL/Fl_Counter.H +forms_bitmap.o: ../FL/Fl_Dial.H ../FL/Fl_Free.H ../FL/fl_ask.H +forms_bitmap.o: ../FL/fl_show_colormap.H ../FL/filename.H +forms_bitmap.o: ../FL/Fl_File_Chooser.H ../FL/Fl_Double_Window.H +forms_bitmap.o: ../FL/Fl_Group.H ../FL/Fl_Choice.H ../FL/Fl_Menu_Button.H +forms_bitmap.o: ../FL/Fl_Button.H ../FL/Fl_Preferences.H ../FL/Fl_Tile.H +forms_bitmap.o: ../FL/Fl_File_Browser.H ../FL/Fl_File_Icon.H ../FL/Fl_Box.H +forms_bitmap.o: ../FL/Fl_Check_Button.H ../FL/Fl_File_Input.H +forms_bitmap.o: ../FL/Fl_Input.H ../FL/Fl_Input_.H ../FL/Fl_Return_Button.H +forms_bitmap.o: ../FL/fl_ask.H ../FL/Fl_Input.H ../FL/Fl_Menu_Button.H +forms_bitmap.o: ../FL/Fl_Positioner.H ../FL/Fl_Value_Slider.H +forms_bitmap.o: ../FL/Fl_Timer.H +forms_free.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +forms_free.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Free.H +forms_free.o: ../FL/Fl_Widget.H +forms_fselect.o: ../FL/forms.H ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +forms_fselect.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H +forms_fselect.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Window.H +forms_fselect.o: ../FL/fl_draw.H ../FL/Fl_Device.H ../FL/x.H +forms_fselect.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H +forms_fselect.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Pixmap.H +forms_fselect.o: ../FL/Fl_RGB_Image.H ../FL/Fl_FormsBitmap.H +forms_fselect.o: ../FL/Fl_Bitmap.H ../FL/Fl_FormsPixmap.H ../FL/Fl_Pixmap.H +forms_fselect.o: ../FL/Fl_Box.H ../FL/Fl_Browser.H ../FL/Fl_Browser_.H +forms_fselect.o: ../FL/Fl_Scrollbar.H ../FL/Fl_Slider.H ../FL/Fl_Valuator.H +forms_fselect.o: ../FL/Fl.H ../FL/Fl_Button.H ../FL/Fl_Light_Button.H +forms_fselect.o: ../FL/Fl_Round_Button.H ../FL/Fl_Check_Button.H +forms_fselect.o: ../FL/Fl_Chart.H ../FL/Fl_Choice.H ../FL/Fl_Menu_.H +forms_fselect.o: ../FL/Fl_Menu_Item.H ../FL/Fl_Clock.H ../FL/Fl_Counter.H +forms_fselect.o: ../FL/Fl_Dial.H ../FL/Fl_Free.H ../FL/fl_ask.H +forms_fselect.o: ../FL/fl_show_colormap.H ../FL/filename.H +forms_fselect.o: ../FL/Fl_File_Chooser.H ../FL/Fl_Double_Window.H +forms_fselect.o: ../FL/Fl_Group.H ../FL/Fl_Choice.H ../FL/Fl_Menu_Button.H +forms_fselect.o: ../FL/Fl_Button.H ../FL/Fl_Preferences.H ../FL/Fl_Tile.H +forms_fselect.o: ../FL/Fl_File_Browser.H ../FL/Fl_File_Icon.H ../FL/Fl_Box.H +forms_fselect.o: ../FL/Fl_Check_Button.H ../FL/Fl_File_Input.H +forms_fselect.o: ../FL/Fl_Input.H ../FL/Fl_Input_.H ../FL/Fl_Return_Button.H +forms_fselect.o: ../FL/fl_ask.H ../FL/Fl_Input.H ../FL/Fl_Menu_Button.H +forms_fselect.o: ../FL/Fl_Positioner.H ../FL/Fl_Value_Slider.H +forms_fselect.o: ../FL/Fl_Timer.H flstring.h ../FL/Fl_Export.H ../config.h +forms_pixmap.o: ../FL/forms.H ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +forms_pixmap.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H +forms_pixmap.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Window.H +forms_pixmap.o: ../FL/fl_draw.H ../FL/Fl_Device.H ../FL/x.H ../FL/Fl_Plugin.H +forms_pixmap.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H +forms_pixmap.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +forms_pixmap.o: ../FL/Fl_FormsBitmap.H ../FL/Fl_Bitmap.H +forms_pixmap.o: ../FL/Fl_FormsPixmap.H ../FL/Fl_Pixmap.H ../FL/Fl_Box.H +forms_pixmap.o: ../FL/Fl_Browser.H ../FL/Fl_Browser_.H ../FL/Fl_Scrollbar.H +forms_pixmap.o: ../FL/Fl_Slider.H ../FL/Fl_Valuator.H ../FL/Fl.H +forms_pixmap.o: ../FL/Fl_Button.H ../FL/Fl_Light_Button.H +forms_pixmap.o: ../FL/Fl_Round_Button.H ../FL/Fl_Check_Button.H +forms_pixmap.o: ../FL/Fl_Chart.H ../FL/Fl_Choice.H ../FL/Fl_Menu_.H +forms_pixmap.o: ../FL/Fl_Menu_Item.H ../FL/Fl_Clock.H ../FL/Fl_Counter.H +forms_pixmap.o: ../FL/Fl_Dial.H ../FL/Fl_Free.H ../FL/fl_ask.H +forms_pixmap.o: ../FL/fl_show_colormap.H ../FL/filename.H +forms_pixmap.o: ../FL/Fl_File_Chooser.H ../FL/Fl_Double_Window.H +forms_pixmap.o: ../FL/Fl_Group.H ../FL/Fl_Choice.H ../FL/Fl_Menu_Button.H +forms_pixmap.o: ../FL/Fl_Button.H ../FL/Fl_Preferences.H ../FL/Fl_Tile.H +forms_pixmap.o: ../FL/Fl_File_Browser.H ../FL/Fl_File_Icon.H ../FL/Fl_Box.H +forms_pixmap.o: ../FL/Fl_Check_Button.H ../FL/Fl_File_Input.H +forms_pixmap.o: ../FL/Fl_Input.H ../FL/Fl_Input_.H ../FL/Fl_Return_Button.H +forms_pixmap.o: ../FL/fl_ask.H ../FL/Fl_Input.H ../FL/Fl_Menu_Button.H +forms_pixmap.o: ../FL/Fl_Positioner.H ../FL/Fl_Value_Slider.H +forms_pixmap.o: ../FL/Fl_Timer.H +forms_timer.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +forms_timer.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Timer.H +forms_timer.o: ../FL/Fl_Widget.H ../FL/fl_draw.H ../FL/Fl_Window.H +forms_timer.o: ../FL/Fl_Device.H ../FL/x.H ../FL/Fl_Plugin.H +forms_timer.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H +forms_timer.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +Fl_Gl_Choice.o: ../config.h ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +Fl_Gl_Choice.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H ../FL/x.H +Fl_Gl_Choice.o: ../FL/Fl_Window.H Fl_Gl_Choice.H ../FL/gl_draw.H ../FL/gl.h +Fl_Gl_Choice.o: flstring.h ../FL/Fl_Export.H ../FL/fl_utf8.h +Fl_Gl_Overlay.o: ../config.h ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +Fl_Gl_Overlay.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H +Fl_Gl_Overlay.o: ../FL/x.H ../FL/Fl_Window.H Fl_Gl_Choice.H +Fl_Gl_Overlay.o: ../FL/Fl_Gl_Window.H +Fl_Gl_Device_Plugin.o: ../FL/Fl_Printer.H ../FL/Fl_Paged_Device.H +Fl_Gl_Device_Plugin.o: ../FL/Fl_Device.H ../FL/fl_draw.H ../FL/Enumerations.H +Fl_Gl_Device_Plugin.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Fl_Window.H +Fl_Gl_Device_Plugin.o: ../FL/Fl_Device.H ../FL/x.H ../FL/Xutf8.h +Fl_Gl_Device_Plugin.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H +Fl_Gl_Device_Plugin.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H +Fl_Gl_Device_Plugin.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +Fl_Gl_Device_Plugin.o: ../FL/Fl_PostScript.H ../FL/Fl_Gl_Window.H +Fl_Gl_Device_Plugin.o: Fl_Gl_Choice.H ../FL/Fl.H ../FL/fl_utf8.h +Fl_Gl_Window.o: flstring.h ../FL/Fl_Export.H ../config.h ../FL/Fl.H +Fl_Gl_Window.o: ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +Fl_Gl_Window.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/x.H +Fl_Gl_Window.o: ../FL/Fl_Window.H Fl_Gl_Choice.H ../FL/Fl_Gl_Window.H +Fl_Gl_Window.o: ../FL/fl_utf8.h +freeglut_geometry.o: ../FL/glut.H ../FL/gl.h ../FL/Enumerations.H +freeglut_geometry.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Fl.H +freeglut_geometry.o: ../FL/fl_utf8.h ../FL/Xutf8.h ../FL/Fl_Gl_Window.H +freeglut_geometry.o: ../FL/Fl_Window.H ../FL/math.h +freeglut_stroke_mono_roman.o: ../FL/glut.H ../FL/gl.h ../FL/Enumerations.H +freeglut_stroke_mono_roman.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Fl.H +freeglut_stroke_mono_roman.o: ../FL/fl_utf8.h ../FL/Xutf8.h +freeglut_stroke_mono_roman.o: ../FL/Fl_Gl_Window.H ../FL/Fl_Window.H +freeglut_stroke_roman.o: ../FL/glut.H ../FL/gl.h ../FL/Enumerations.H +freeglut_stroke_roman.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Fl.H +freeglut_stroke_roman.o: ../FL/fl_utf8.h ../FL/Xutf8.h ../FL/Fl_Gl_Window.H +freeglut_stroke_roman.o: ../FL/Fl_Window.H +freeglut_teapot.o: ../FL/glut.H ../FL/gl.h ../FL/Enumerations.H +freeglut_teapot.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Fl.H +freeglut_teapot.o: ../FL/fl_utf8.h ../FL/Xutf8.h ../FL/Fl_Gl_Window.H +freeglut_teapot.o: ../FL/Fl_Window.H freeglut_teapot_data.h +gl_draw.o: flstring.h ../FL/Fl_Export.H ../config.h ../FL/Fl.H +gl_draw.o: ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Xutf8.h +gl_draw.o: ../FL/Enumerations.H ../FL/gl.h ../FL/x.H ../FL/Fl_Window.H +gl_draw.o: ../FL/fl_draw.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H +gl_draw.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H +gl_draw.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +gl_draw.o: Fl_Gl_Choice.H Fl_Font.H ../FL/fl_utf8.h ../FL/Xutf8.h +gl_start.o: ../config.h ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H +gl_start.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H +gl_start.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/x.H +gl_start.o: ../FL/Fl_Window.H ../FL/fl_draw.H ../FL/Fl_Device.H +gl_start.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H +gl_start.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Pixmap.H +gl_start.o: ../FL/Fl_RGB_Image.H Fl_Gl_Choice.H +glut_compatability.o: flstring.h ../FL/Fl_Export.H ../config.h ../FL/glut.H +glut_compatability.o: ../FL/gl.h ../FL/Enumerations.H ../FL/Fl_Export.H +glut_compatability.o: ../FL/fl_types.h ../FL/Fl.H ../FL/fl_utf8.h +glut_compatability.o: ../FL/Xutf8.h ../FL/Fl_Gl_Window.H ../FL/Fl_Window.H +glut_compatability.o: ../FL/Fl_Menu_Item.H ../FL/Fl_Widget.H ../FL/Fl_Image.H +glut_font.o: ../config.h ../FL/glut.H ../FL/gl.h ../FL/Enumerations.H +glut_font.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Fl.H ../FL/fl_utf8.h +glut_font.o: ../FL/Xutf8.h ../FL/Fl_Gl_Window.H ../FL/Fl_Window.H +fl_images_core.o: ../FL/Fl_Shared_Image.H ../FL/Fl_Image.H +fl_images_core.o: ../FL/Fl_BMP_Image.H ../FL/Fl_GIF_Image.H ../FL/Fl_Pixmap.H +fl_images_core.o: ../FL/Fl_JPEG_Image.H ../FL/Fl_PNG_Image.H +fl_images_core.o: ../FL/Fl_PNM_Image.H flstring.h ../FL/Fl_Export.H +fl_images_core.o: ../config.h +Fl_BMP_Image.o: ../FL/Fl_BMP_Image.H ../FL/Fl_Image.H ../config.h +Fl_File_Icon2.o: ../FL/fl_utf8.h flstring.h ../FL/Fl_Export.H ../config.h +Fl_File_Icon2.o: ../FL/math.h ../FL/Fl_File_Icon.H ../FL/Fl.H ../FL/fl_utf8.h +Fl_File_Icon2.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Xutf8.h +Fl_File_Icon2.o: ../FL/Enumerations.H ../FL/Fl_Shared_Image.H +Fl_File_Icon2.o: ../FL/Fl_Image.H ../FL/Fl_Widget.H ../FL/fl_draw.H +Fl_File_Icon2.o: ../FL/Fl_Window.H ../FL/Fl_Device.H ../FL/x.H +Fl_File_Icon2.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H +Fl_File_Icon2.o: ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +Fl_File_Icon2.o: ../FL/filename.H +Fl_GIF_Image.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +Fl_GIF_Image.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_GIF_Image.H +Fl_GIF_Image.o: ../FL/Fl_Pixmap.H ../FL/Fl_Image.H ../FL/fl_utf8.h flstring.h +Fl_GIF_Image.o: ../FL/Fl_Export.H ../config.h +Fl_Help_Dialog.o: ../FL/Fl_Help_Dialog.H ../FL/Fl.H ../FL/fl_utf8.h +Fl_Help_Dialog.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Xutf8.h +Fl_Help_Dialog.o: ../FL/Enumerations.H ../FL/Fl_Double_Window.H +Fl_Help_Dialog.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Button.H +Fl_Help_Dialog.o: ../FL/Fl_Widget.H ../FL/Fl_Input.H ../FL/Fl_Input_.H +Fl_Help_Dialog.o: ../FL/Fl_Box.H ../FL/Fl_Help_View.H ../FL/Fl.H +Fl_Help_Dialog.o: ../FL/Fl_Group.H ../FL/Fl_Scrollbar.H ../FL/Fl_Slider.H +Fl_Help_Dialog.o: ../FL/Fl_Valuator.H ../FL/fl_draw.H ../FL/Fl_Device.H +Fl_Help_Dialog.o: ../FL/x.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H +Fl_Help_Dialog.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H +Fl_Help_Dialog.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H +Fl_Help_Dialog.o: ../FL/Fl_Shared_Image.H flstring.h ../FL/Fl_Export.H +Fl_Help_Dialog.o: ../config.h ../FL/fl_ask.H +Fl_JPEG_Image.o: ../FL/Fl_JPEG_Image.H ../FL/Fl_Image.H ../config.h +Fl_PNG_Image.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +Fl_PNG_Image.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_PNG_Image.H +Fl_PNG_Image.o: ../FL/Fl_Image.H ../config.h ../FL/fl_utf8.h +Fl_PNM_Image.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h +Fl_PNM_Image.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_PNM_Image.H +Fl_PNM_Image.o: ../FL/Fl_Image.H ../FL/fl_utf8.h flstring.h ../FL/Fl_Export.H +Fl_PNM_Image.o: ../config.h +flstring.o: flstring.h ../FL/Fl_Export.H ../config.h +scandir.o: flstring.h ../FL/Fl_Export.H ../config.h ../FL/fl_utf8.h +numericsort.o: ../config.h ../FL/filename.H +vsnprintf.o: flstring.h ../FL/Fl_Export.H ../config.h +fl_utf.o: ../FL/fl_utf8.h xutf8/mk_wcwidth.c +xutf8/case.o: xutf8/headers/case.h +xutf8/is_spacing.o: xutf8/headers/spacing.h +xutf8/keysym2Ucs.o: ../FL/Xutf8.h xutf8/imKStoUCS.c xutf8/Xlibint.h +xutf8/keysym2Ucs.o: xutf8/Ximint.h +xutf8/utf8Input.o: ../config.h ../FL/Xutf8.h xutf8/lcUniConv/big5.h +xutf8/utf8Input.o: xutf8/lcUniConv/gb2312.h xutf8/lcUniConv/jisx0201.h +xutf8/utf8Input.o: xutf8/lcUniConv/jisx0208.h xutf8/lcUniConv/jisx0212.h +xutf8/utf8Input.o: xutf8/lcUniConv/ksc5601.h +xutf8/utf8Utils.o: ../FL/Xutf8.h +xutf8/utf8Wrap.o: ../FL/Xutf8.h xutf8/ucs2fontmap.c xutf8/lcUniConv/big5.h +xutf8/utf8Wrap.o: xutf8/lcUniConv/gb2312.h xutf8/lcUniConv/iso8859_10.h +xutf8/utf8Wrap.o: xutf8/lcUniConv/iso8859_11.h xutf8/lcUniConv/iso8859_13.h +xutf8/utf8Wrap.o: xutf8/lcUniConv/iso8859_14.h xutf8/lcUniConv/iso8859_15.h +xutf8/utf8Wrap.o: xutf8/lcUniConv/iso8859_2.h xutf8/lcUniConv/iso8859_3.h +xutf8/utf8Wrap.o: xutf8/lcUniConv/iso8859_4.h xutf8/lcUniConv/iso8859_5.h +xutf8/utf8Wrap.o: xutf8/lcUniConv/iso8859_6.h xutf8/lcUniConv/iso8859_7.h +xutf8/utf8Wrap.o: xutf8/lcUniConv/iso8859_8.h xutf8/lcUniConv/iso8859_9.h +xutf8/utf8Wrap.o: xutf8/lcUniConv/jisx0201.h xutf8/lcUniConv/jisx0208.h +xutf8/utf8Wrap.o: xutf8/lcUniConv/jisx0212.h xutf8/lcUniConv/koi8_r.h +xutf8/utf8Wrap.o: xutf8/lcUniConv/koi8_u.h xutf8/lcUniConv/ksc5601.h +xutf8/utf8Wrap.o: xutf8/lcUniConv/cp1251.h xutf8/headers/symbol_.h +xutf8/utf8Wrap.o: xutf8/headers/dingbats_.h diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/makefile.wat b/mod/maxgui.mod/fltkmaxgui.mod/src/makefile.wat new file mode 100644 index 0000000..c70ddf6 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/makefile.wat @@ -0,0 +1,238 @@ +# +# "$Id: makefile.wat 7563 2010-04-28 03:15:47Z greg.ercolano $" +# +# Library makefile for the Fast Light Tool Kit (FLTK). +# +# Copyright 1998-2004 by Bill Spitzak and others. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. +# +# You should have received a copy of the GNU Library General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +# USA. +# +# Please report all bugs and problems on the following page: +# +# http://www.fltk.org/str.php +# + +CPPFILES = & + Fl.obj & + Fl_Adjuster.obj & + Fl_Bitmap.obj & + Fl_Browser.obj & + Fl_Browser_.obj & + Fl_Browser_load.obj & + Fl_Box.obj & + Fl_Button.obj & + Fl_Chart.obj & + Fl_Check_Browser.obj & + Fl_Check_Button.obj & + Fl_Choice.obj & + Fl_Clock.obj & + Fl_Color_Chooser.obj & + Fl_Counter.obj & + Fl_Dial.obj & + Fl_Double_Window.obj & + Fl_File_Browser.obj & + Fl_File_Chooser.obj & + Fl_File_Chooser2.obj & + Fl_File_Icon.obj & + Fl_File_Input.obj & + Fl_Group.obj & + Fl_Help_View.obj & + Fl_Image.obj & + Fl_Input.obj & + Fl_Input_.obj & + Fl_Light_Button.obj & + Fl_Menu.obj & + Fl_Menu_.obj & + Fl_Menu_Bar.obj & + Fl_Sys_Menu_Bar.obj & + Fl_Menu_Button.obj & + Fl_Menu_Window.obj & + Fl_Menu_add.obj & + Fl_Menu_global.obj & + Fl_Multi_Label.obj & + Fl_Native_File_Chooser.obj & + Fl_Overlay_Window.obj & + Fl_Pack.obj & + Fl_Pixmap.obj & + Fl_Positioner.obj & + Fl_Preferences.obj & + Fl_Progress.obj & + Fl_Repeat_Button.obj & + Fl_Return_Button.obj & + Fl_Roller.obj & + Fl_Round_Button.obj & + Fl_Scroll.obj & + Fl_Scrollbar.obj & + Fl_Shared_Image.obj & + Fl_Single_Window.obj & + Fl_Slider.obj & + Fl_Tabs.obj & + Fl_Text_Buffer.obj & + Fl_Text_Display.obj & + Fl_Text_Editor.obj & + Fl_Tile.obj & + Fl_Tiled_Image.obj & + Fl_Tooltip.obj & + Fl_Valuator.obj & + Fl_Value_Input.obj & + Fl_Value_Output.obj & + Fl_Value_Slider.obj & + Fl_Widget.obj & + Fl_Window.obj & + Fl_Window_fullscreen.obj & + Fl_Window_hotspot.obj & + Fl_Window_iconize.obj & + Fl_Wizard.obj & + Fl_XBM_Image.obj & + Fl_XPM_Image.obj & + Fl_abort.obj & + Fl_add_idle.obj & + Fl_arg.obj & + Fl_compose.obj & + Fl_display.obj & + Fl_get_key.obj & + Fl_get_system_colors.obj & + Fl_grab.obj & + Fl_lock.obj & + Fl_own_colormap.obj & + Fl_visual.obj & + Fl_x.obj & + filename_absolute.obj & + filename_expand.obj & + filename_ext.obj & + filename_isdir.obj & + filename_list.obj & + filename_match.obj & + filename_setext.obj & + fl_arc.obj & + fl_arci.obj & + fl_ask.obj & + fl_boxtype.obj & + fl_color.obj & + fl_cursor.obj & + fl_curve.obj & + fl_diamond_box.obj & + fl_dnd.obj & + fl_draw.obj & + fl_draw_image.obj & + fl_draw_pixmap.obj & + fl_encoding_latin1.obj & + fl_encoding_mac_roman.obj & + fl_engraved_label.obj & + fl_file_dir.obj & + fl_font.obj & + fl_gtk.obj & + fl_labeltype.obj & + fl_line_style.obj & + fl_open_uri.obj & + fl_oval_box.obj & + fl_overlay.obj & + fl_overlay_visual.obj & + fl_plastic.obj & + fl_read_image.obj & + fl_rect.obj & + fl_round_box.obj & + fl_rounded_box.obj & + fl_set_font.obj & + fl_set_fonts.obj & + fl_scroll_area.obj & + fl_shadow_box.obj & + fl_shortcut.obj & + fl_show_colormap.obj & + fl_symbols.obj & + fl_vertex.obj & + screen_xywh.obj + +FLCPPFILES = & + forms_compatability.obj & + forms_bitmap.obj & + forms_free.obj & + forms_fselect.obj & + forms_pixmap.obj & + forms_timer.obj + +GLCPPFILES = & + Fl_Gl_Choice.obj & + Fl_Gl_Overlay.obj & + Fl_Gl_Window.obj & + freeglut_geometry.obj & + freeglut_stroke_mono_roman.obj & + freeglut_stroke_roman.obj & + freeglut_teapot.obj & + gl_draw.obj & + gl_start.obj & + glut_compatability.obj & + glut_font.obj + +IMGCPPFILES = & + fl_images_core.obj & + Fl_BMP_Image.obj & + Fl_File_Icon2.obj & + Fl_GIF_Image.obj & + Fl_Help_Dialog.obj & + Fl_JPEG_Image.obj & + Fl_PNG_Image.obj & + Fl_PNM_Image.obj + +CFILES = fl_call_main.obj flstring.obj scandir.obj numericsort.obj vsnprintf.obj + +################################################################ + +!include ../watcom.mif + +OBJECTS = $(CPPFILES) $(CFILES) +FLOBJECTS = $(FLCPPFILES) +GLOBJECTS = $(GLCPPFILES) +IMGOBJECTS = $(IMGCPPFILES) + +# The four basic fltk libraries are defined in ../watcom.mif, so that appliactions +# can also use them. +all: $(LIBNAME) & + $(LIBNAMEFL) & + $(LIBNAMEGL) & + $(LIBNAMEIMG) + +# $(DSONAME) & +# $(FLDSONAME) & +# $(GLDSONAME) & +# $(IMGDSONAME) + + +$(LIBNAME): $(OBJECTS) + $(LIB) $(LIBOPTS) $@ $< + +$(LIBNAMEFL): $(FLOBJECTS) + $(LIB) $(LIBOPTS) $@ $< + +$(LIBNAMEGL): $(GLOBJECTS) + $(LIB) $(LIBOPTS) $@ $< + +$(LIBNAMEIMG): $(IMGOBJECTS) + $(LIB) $(LIBOPTS) $@ $< + +# +# Clean all directories +# +clean : .SYMBOLIC + @echo Cleaning up. +CLEANEXTS = exe map sym obj lk1 + @for %a in ($(CLEANEXTS)) do -rm -f $(ODIR)\*.%a + -rm -f *.err + -rm -f $(LIBNAME) + -rm -f $(LIBNAMEFL) + -rm -f $(LIBNAMEGL) + -rm -f $(LIBNAMEIMG) + diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/mediumarrow.h b/mod/maxgui.mod/fltkmaxgui.mod/src/mediumarrow.h new file mode 100644 index 0000000..8a1fe8c --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/mediumarrow.h @@ -0,0 +1,6 @@ +#define mediumarrow_width 16 +#define mediumarrow_height 16 +static unsigned char mediumarrow_bits[] = { + 0x40, 0x00, 0x60, 0x00, 0x70, 0x00, 0x78, 0x00, 0xfc, 0x3f, 0x78, 0x00, + 0x70, 0x00, 0x60, 0x02, 0x40, 0x06, 0x00, 0x0e, 0x00, 0x1e, 0xfc, 0x3f, + 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x06, 0x00, 0x02}; diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/new.xbm b/mod/maxgui.mod/fltkmaxgui.mod/src/new.xbm new file mode 100644 index 0000000..25a56c5 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/new.xbm @@ -0,0 +1,6 @@ +#define new_width 16 +#define new_height 16 +static unsigned char new_bits[] = { + 0x00, 0x00, 0x78, 0x00, 0x84, 0x00, 0x02, 0x01, 0x01, 0xfe, 0x01, 0x80, + 0x31, 0x80, 0x31, 0x80, 0xfd, 0x80, 0xfd, 0x80, 0x31, 0x80, 0x31, 0x80, + 0x01, 0x80, 0x01, 0x80, 0xff, 0xff, 0x00, 0x00}; diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/ns.xbm b/mod/maxgui.mod/fltkmaxgui.mod/src/ns.xbm new file mode 100644 index 0000000..f1ea18e --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/ns.xbm @@ -0,0 +1,8 @@ +#define ns_width 16 +#define ns_height 16 +#define ns_x_hot 8 +#define ns_y_hot 8 +static unsigned char ns_bits[] = { + 0x00, 0x00, 0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0x80, 0x01, 0x80, 0x01, + 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, + 0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01, 0x00, 0x00}; diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/ns_mask.xbm b/mod/maxgui.mod/fltkmaxgui.mod/src/ns_mask.xbm new file mode 100644 index 0000000..a69f261 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/ns_mask.xbm @@ -0,0 +1,8 @@ +#define ns_mask_width 16 +#define ns_mask_height 16 +#define ns_mask_x_hot 8 +#define ns_mask_y_hot 8 +static unsigned char ns_mask_bits[] = { + 0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0xf0, 0x0f, 0xf0, 0x0f, 0xc0, 0x03, + 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xf0, 0x0f, + 0xf0, 0x0f, 0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01}; diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/numericsort.c b/mod/maxgui.mod/fltkmaxgui.mod/src/numericsort.c new file mode 100644 index 0000000..6f36b89 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/numericsort.c @@ -0,0 +1,111 @@ +/* + * "$Id: numericsort.c 7903 2010-11-28 21:06:39Z matt $" + * + * Numeric sorting routine for the Fast Light Tool Kit (FLTK). + * + * Copyright 1998-2010 by Bill Spitzak and others. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems on the following page: + * + * http://www.fltk.org/str.php + */ + +/* My own scandir sorting function, useful for the film industry where + we have many files with numbers in their names: */ + +#include +#include +#include +#include + +#include + +#if !defined(WIN32) || defined(__CYGWIN__) +# ifdef HAVE_DIRENT_H +# include +# else +# define dirent direct +# if HAVE_SYS_NDIR_H +# include +# endif /* HAVE_SYS_NDIR_H */ +# if HAVE_SYS_DIR_H +# include +# endif /* HAVE_SYS_DIR_H */ +# if HAVE_NDIR_H +# include +# endif /* HAVE_NDIR_H */ +# endif /* HAVE_DIRENT_H */ +#endif /* !WIN32 || __CYGWIN__ */ + +/* + * 'numericsort()' - Compare two directory entries, possibly with + * a case-insensitive comparison... + */ + +static int numericsort(struct dirent **A, struct dirent **B, int cs) { + const char* a = (*A)->d_name; + const char* b = (*B)->d_name; + int ret = 0; + for (;;) { + if (isdigit(*a & 255) && isdigit(*b & 255)) { + int diff,magdiff; + while (*a == '0') a++; + while (*b == '0') b++; + while (isdigit(*a & 255) && *a == *b) {a++; b++;} + diff = (isdigit(*a & 255) && isdigit(*b & 255)) ? *a - *b : 0; + magdiff = 0; + while (isdigit(*a & 255)) {magdiff++; a++;} + while (isdigit(*b & 255)) {magdiff--; b++;} + if (magdiff) {ret = magdiff; break;} /* compare # of significant digits*/ + if (diff) {ret = diff; break;} /* compare first non-zero digit */ + } else { + if (cs) { + /* compare case-sensitive */ + if ((ret = *a-*b)) break; + } else { + /* compare case-insensitve */ + if ((ret = tolower(*a & 255)-tolower(*b & 255))) break; + } + + if (!*a) break; + a++; b++; + } + } + if (!ret) return 0; + else return (ret < 0) ? -1 : 1; +} + +/* + * 'fl_casenumericsort()' - Compare directory entries with case-sensitivity. + */ + +int fl_casenumericsort(struct dirent **A, struct dirent **B) { + return numericsort(A, B, 0); +} + +/* + * 'fl_numericsort()' - Compare directory entries with case-sensitivity. + */ + +int fl_numericsort(struct dirent **A, struct dirent **B) { + return numericsort(A, B, 1); +} + +/* + * End of "$Id: numericsort.c 7903 2010-11-28 21:06:39Z matt $". + */ diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/print_panel.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/print_panel.cxx new file mode 100644 index 0000000..644ebc3 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/print_panel.cxx @@ -0,0 +1,597 @@ +// +// "$Id: print_panel.cxx 7885 2010-11-23 12:13:17Z manolo $" +// +// Print panel for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2009 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// +// This file is "work in progress". The main parts have been copied +// from fluid's print_panel{.fl|.h|.cxx} and hand-edited to produce +// a working version w/o global variables. The intention is to move +// all static variables into an own class, and to name this class +// Fl_Printer_Chooser or similar... +// +// Todo: +// +// - Currently preferences can't be saved, and there are options that +// are not yet used for printing. +// - This file can only be used as an include file in Fl_PS_Printer.cxx +// - The use of static variables should be avoided. +// - Probably much more ... +// + +#include "print_panel.h" +#include +#include +#include "../src/flstring.h" +#include +#include + +static Fl_Preferences print_prefs(Fl_Preferences::USER, "fltk.org", "printers"); +static Fl_Double_Window *print_panel=(Fl_Double_Window *)0; +static Fl_Group *print_panel_controls=(Fl_Group *)0; +static Fl_Choice *print_choice=(Fl_Choice *)0; +static Fl_Button *print_properties=(Fl_Button *)0; +static Fl_Box *print_status=(Fl_Box *)0; +static Fl_Round_Button *print_all=(Fl_Round_Button *)0; +static Fl_Round_Button *print_pages=(Fl_Round_Button *)0; +static Fl_Round_Button *print_selection=(Fl_Round_Button *)0; +static Fl_Check_Button *print_collate_button=(Fl_Check_Button *)0; +static Fl_Group *print_collate_group[2]={(Fl_Group *)0}; +static Fl_Progress *print_progress=(Fl_Progress *)0; +static Fl_Double_Window *print_properties_panel=(Fl_Double_Window *)0; +static Fl_Choice *print_page_size=(Fl_Choice *)0; +static Fl_Int_Input *print_from=(Fl_Int_Input *)0; +static Fl_Int_Input *print_to=(Fl_Int_Input *)0; +static Fl_Spinner *print_copies=(Fl_Spinner *)0; + +static int print_start = 0; // 1 if print_okay has been clicked + +static void cb_print_choice(Fl_Choice*, void*) { + print_update_status(); +} + +static void cb_print_properties(Fl_Button*, void*) { + print_properties_panel->show(); +} + +static void cb_print_all(Fl_Round_Button*, void*) { + print_from->deactivate(); + print_to->deactivate(); +} + +static void cb_print_pages(Fl_Round_Button*, void*) { + print_from->activate(); + print_to->activate(); +} + +static void cb_print_selection(Fl_Round_Button*, void*) { + print_from->deactivate(); + print_to->deactivate(); +} + +static void cb_print_copies(Fl_Spinner*, void*) { + if (print_copies->value() == 1) { + print_collate_button->deactivate(); + print_collate_group[0]->deactivate(); + print_collate_group[1]->deactivate(); + } else { +/* print_collate_button->activate(); // TODO: manage collate options + print_collate_group[0]->activate(); + print_collate_group[1]->activate(); */ + }; +} + +static void cb_print_collate_button(Fl_Check_Button*, void*) { + int i = print_collate_button->value() != 0; + print_collate_group[i]->show(); + print_collate_group[1 - i]->hide(); +} + +static void cb_Cancel(Fl_Button*, void*) { + print_start = 0; + print_panel->hide(); +} + +static void cb_print_properties_panel(Fl_Double_Window*, void*) { + print_properties_panel->hide(); + print_update_status(); +} + +static Fl_Menu_Item menu_print_page_size[] = { + {"Letter", 0, 0, 0, 0, FL_NORMAL_LABEL, 0, 14, 0}, + {"A4", 0, 0, 0, 0, FL_NORMAL_LABEL, 0, 14, 0}, + {0,0,0,0,0,0,0,0,0} +}; + +#include +static const char *idata_print_color[] = { +"24 24 17 1", +" \tc None", +".\tc #FFFF00", +"+\tc #C8FF00", +"@\tc #00FF00", +"#\tc #FFC800", +"$\tc #FF0000", +"%\tc #00FFFF", +"&\tc #000000", +"*\tc #FF00FF", +"=\tc #00FFC8", +"-\tc #FF00C8", +";\tc #00C800", +">\tc #C80000", +",\tc #0000C8", +"\'\tc #0000FF", +")\tc #00C8FF", +"!\tc #C800FF", +" ...... ", +" .......... ", +" ............ ", +" .............. ", +" .............. ", +" ................ ", +" ................ ", +" ................ ", +" +@@@@@@+#$$$$$$# ", +" %@@@@@@@&&$$$$$$$* ", +" %%@@@@@@&&&&$$$$$$** ", +" %%%=@@@@&&&&&&$$$$-*** ", +" %%%%@@@;&&&&&&>$$$**** ", +"%%%%%%@@&&&&&&&&$$******", +"%%%%%%%@&&&&&&&&$*******", +"%%%%%%%%,&&&&&&,********", +"%%%%%%%%\'\'\'\'\'\'\'\'********", +"%%%%%%%%\'\'\'\'\'\'\'\'********", +"%%%%%%%%\'\'\'\'\'\'\'\'********", +" %%%%%%%)\'\'\'\'\'\'!******* ", +" %%%%%%%%\'\'\'\'\'\'******** ", +" %%%%%%%%\'\'\'\'******** ", +" %%%%%%%%\'\'******** ", +" %%%%%% ****** " +}; +static Fl_Pixmap image_print_color(idata_print_color); + +static const char *idata_print_gray[] = { +"24 24 17 1", +" \tc None", +".\tc #E3E3E3", +"+\tc #D2D2D2", +"@\tc #969696", +"#\tc #C2C2C2", +"$\tc #4C4C4C", +"%\tc #B2B2B2", +"&\tc #000000", +"*\tc #696969", +"=\tc #ACACAC", +"-\tc #626262", +";\tc #767676", +">\tc #3C3C3C", +",\tc #161616", +"\'\tc #1C1C1C", +")\tc #929292", +"!\tc #585858", +" ...... ", +" .......... ", +" ............ ", +" .............. ", +" .............. ", +" ................ ", +" ................ ", +" ................ ", +" +@@@@@@+#$$$$$$# ", +" %@@@@@@@&&$$$$$$$* ", +" %%@@@@@@&&&&$$$$$$** ", +" %%%=@@@@&&&&&&$$$$-*** ", +" %%%%@@@;&&&&&&>$$$**** ", +"%%%%%%@@&&&&&&&&$$******", +"%%%%%%%@&&&&&&&&$*******", +"%%%%%%%%,&&&&&&,********", +"%%%%%%%%\'\'\'\'\'\'\'\'********", +"%%%%%%%%\'\'\'\'\'\'\'\'********", +"%%%%%%%%\'\'\'\'\'\'\'\'********", +" %%%%%%%)\'\'\'\'\'\'!******* ", +" %%%%%%%%\'\'\'\'\'\'******** ", +" %%%%%%%%\'\'\'\'******** ", +" %%%%%%%%\'\'******** ", +" %%%%%% ****** " +}; +static Fl_Pixmap image_print_gray(idata_print_gray); + +static Fl_Button *print_output_mode[4]={(Fl_Button *)0}; + +static void cb_Save(Fl_Return_Button*, void*) { + print_properties_panel->hide(); + + char name[1024]; + int val; + const char *printer = (const char *)print_choice->menu()[print_choice->value()].user_data(); + + snprintf(name, sizeof(name), "%s/page_size", printer); + print_prefs.set(name, print_page_size->value()); + + snprintf(name, sizeof(name), "%s/output_mode", printer); + for (val = 0; val < 4; val ++) { + if (print_output_mode[val]->value()) break; + } + print_prefs.set(name, val); +} + +static void cb_Cancel1(Fl_Button*, void*) { + print_properties_panel->hide(); + print_update_status(); +} + +static void cb_Use(Fl_Button*, void*) { + print_properties_panel->hide(); +} + +Fl_Double_Window* make_print_panel() { + { print_panel = new Fl_Double_Window(465, 235, Fl_Printer::dialog_title); + { print_panel_controls = new Fl_Group(10, 10, 447, 216); + { print_choice = new Fl_Choice(133, 10, 181, 25, Fl_Printer::dialog_printer); + print_choice->down_box(FL_BORDER_BOX); + print_choice->labelfont(1); + print_choice->callback((Fl_Callback*)cb_print_choice); + print_choice->when(FL_WHEN_CHANGED); + } // Fl_Choice* print_choice + { print_properties = new Fl_Button(314, 10, 115, 25, Fl_Printer::dialog_properties); + print_properties->callback((Fl_Callback*)cb_print_properties); + } // Fl_Button* print_properties + { print_status = new Fl_Box(0, 41, print_panel_controls->w(), 17, "printer/job status"); + print_status->align(Fl_Align(FL_ALIGN_CLIP|FL_ALIGN_INSIDE|FL_ALIGN_LEFT)); + } // Fl_Box* print_status + { Fl_Group* o = new Fl_Group(10, 86, 227, 105, Fl_Printer::dialog_range); + o->box(FL_THIN_DOWN_BOX); + o->labelfont(1); + o->align(Fl_Align(FL_ALIGN_TOP_LEFT)); + { print_all = new Fl_Round_Button(20, 96, 38, 25, Fl_Printer::dialog_all); + print_all->type(102); + print_all->down_box(FL_ROUND_DOWN_BOX); + print_all->value(1); + print_all->callback((Fl_Callback*)cb_print_all); + } // Fl_Round_Button* print_all + { print_pages = new Fl_Round_Button(20, 126, 64, 25, Fl_Printer::dialog_pages); + print_pages->type(102); + print_pages->down_box(FL_ROUND_DOWN_BOX); + print_pages->callback((Fl_Callback*)cb_print_pages); + } // Fl_Round_Button* print_pages + { print_selection = new Fl_Round_Button(20, 156, 82, 25, "Selection"); + print_selection->type(102); + print_selection->down_box(FL_ROUND_DOWN_BOX); + print_selection->callback((Fl_Callback*)cb_print_selection); + } // Fl_Round_Button* print_selection + { print_from = new Fl_Int_Input(136, 126, 28, 25, Fl_Printer::dialog_from); + print_from->type(2); + print_from->textfont(4); + print_from->deactivate(); + } // Fl_Int_Input* print_from + { print_to = new Fl_Int_Input(199, 126, 28, 25, Fl_Printer::dialog_to); + print_to->type(2); + print_to->textfont(4); + print_to->deactivate(); + } // Fl_Int_Input* print_to + o->end(); + } // Fl_Group* o + { Fl_Group* o = new Fl_Group(247, 86, 210, 105, Fl_Printer::dialog_copies); + o->box(FL_THIN_DOWN_BOX); + o->labelfont(1); + o->align(Fl_Align(FL_ALIGN_TOP_LEFT)); + { print_copies = new Fl_Spinner(321, 96, 45, 25, Fl_Printer::dialog_copyNo); + print_copies->callback((Fl_Callback*)cb_print_copies); + print_copies->when(FL_WHEN_CHANGED); + } // Fl_Spinner* print_copies + { print_collate_button = new Fl_Check_Button(376, 96, 64, 25, "Collate"); + print_collate_button->down_box(FL_DOWN_BOX); + print_collate_button->callback((Fl_Callback*)cb_print_collate_button); + print_collate_button->when(FL_WHEN_CHANGED); + print_collate_button->deactivate(); + } // Fl_Check_Button* print_collate_button + { print_collate_group[0] = new Fl_Group(257, 131, 191, 50); + print_collate_group[0]->deactivate(); + { Fl_Box* o = new Fl_Box(287, 141, 30, 40, "1"); + o->box(FL_BORDER_BOX); + o->color(FL_BACKGROUND2_COLOR); + o->labelsize(11); + o->align(Fl_Align(FL_ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE)); + o->deactivate(); + } // Fl_Box* o + { Fl_Box* o = new Fl_Box(272, 136, 30, 40, "1"); + o->box(FL_BORDER_BOX); + o->color(FL_BACKGROUND2_COLOR); + o->labelsize(11); + o->align(Fl_Align(FL_ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE)); + o->deactivate(); + } // Fl_Box* o + { Fl_Box* o = new Fl_Box(257, 131, 30, 40, "1"); + o->box(FL_BORDER_BOX); + o->color(FL_BACKGROUND2_COLOR); + o->labelsize(11); + o->align(Fl_Align(FL_ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE)); + o->deactivate(); + } // Fl_Box* o + { Fl_Box* o = new Fl_Box(352, 141, 30, 40, "2"); + o->box(FL_BORDER_BOX); + o->color(FL_BACKGROUND2_COLOR); + o->labelsize(11); + o->align(Fl_Align(FL_ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE)); + o->deactivate(); + } // Fl_Box* o + { Fl_Box* o = new Fl_Box(337, 136, 30, 40, "2"); + o->box(FL_BORDER_BOX); + o->color(FL_BACKGROUND2_COLOR); + o->labelsize(11); + o->align(Fl_Align(FL_ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE)); + o->deactivate(); + } // Fl_Box* o + { Fl_Box* o = new Fl_Box(322, 131, 30, 40, "2"); + o->box(FL_BORDER_BOX); + o->color(FL_BACKGROUND2_COLOR); + o->labelsize(11); + o->align(Fl_Align(FL_ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE)); + o->deactivate(); + } // Fl_Box* o + { Fl_Box* o = new Fl_Box(417, 141, 30, 40, "3"); + o->box(FL_BORDER_BOX); + o->color(FL_BACKGROUND2_COLOR); + o->labelsize(11); + o->align(Fl_Align(FL_ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE)); + o->deactivate(); + } // Fl_Box* o + { Fl_Box* o = new Fl_Box(402, 136, 30, 40, "3"); + o->box(FL_BORDER_BOX); + o->color(FL_BACKGROUND2_COLOR); + o->labelsize(11); + o->align(Fl_Align(FL_ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE)); + o->deactivate(); + } // Fl_Box* o + { Fl_Box* o = new Fl_Box(387, 131, 30, 40, "3"); + o->box(FL_BORDER_BOX); + o->color(FL_BACKGROUND2_COLOR); + o->labelsize(11); + o->align(Fl_Align(FL_ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE)); + o->deactivate(); + } // Fl_Box* o + print_collate_group[0]->end(); + } // Fl_Group* print_collate_group[0] + { print_collate_group[1] = new Fl_Group(257, 131, 191, 50); + print_collate_group[1]->hide(); + print_collate_group[1]->deactivate(); + { Fl_Box* o = new Fl_Box(287, 141, 30, 40, "3"); + o->box(FL_BORDER_BOX); + o->color(FL_BACKGROUND2_COLOR); + o->labelsize(11); + o->align(Fl_Align(FL_ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE)); + } // Fl_Box* o + { Fl_Box* o = new Fl_Box(272, 136, 30, 40, "2"); + o->box(FL_BORDER_BOX); + o->color(FL_BACKGROUND2_COLOR); + o->labelsize(11); + o->align(Fl_Align(FL_ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE)); + } // Fl_Box* o + { Fl_Box* o = new Fl_Box(257, 131, 30, 40, "1"); + o->box(FL_BORDER_BOX); + o->color(FL_BACKGROUND2_COLOR); + o->labelsize(11); + o->align(Fl_Align(FL_ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE)); + } // Fl_Box* o + { Fl_Box* o = new Fl_Box(352, 141, 30, 40, "3"); + o->box(FL_BORDER_BOX); + o->color(FL_BACKGROUND2_COLOR); + o->labelsize(11); + o->align(Fl_Align(FL_ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE)); + } // Fl_Box* o + { Fl_Box* o = new Fl_Box(337, 136, 30, 40, "2"); + o->box(FL_BORDER_BOX); + o->color(FL_BACKGROUND2_COLOR); + o->labelsize(11); + o->align(Fl_Align(FL_ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE)); + } // Fl_Box* o + { Fl_Box* o = new Fl_Box(322, 131, 30, 40, "1"); + o->box(FL_BORDER_BOX); + o->color(FL_BACKGROUND2_COLOR); + o->labelsize(11); + o->align(Fl_Align(FL_ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE)); + } // Fl_Box* o + { Fl_Box* o = new Fl_Box(417, 141, 30, 40, "3"); + o->box(FL_BORDER_BOX); + o->color(FL_BACKGROUND2_COLOR); + o->labelsize(11); + o->align(Fl_Align(FL_ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE)); + } // Fl_Box* o + { Fl_Box* o = new Fl_Box(402, 136, 30, 40, "2"); + o->box(FL_BORDER_BOX); + o->color(FL_BACKGROUND2_COLOR); + o->labelsize(11); + o->align(Fl_Align(FL_ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE)); + } // Fl_Box* o + { Fl_Box* o = new Fl_Box(387, 131, 30, 40, "1"); + o->box(FL_BORDER_BOX); + o->color(FL_BACKGROUND2_COLOR); + o->labelsize(11); + o->align(Fl_Align(FL_ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE)); + } // Fl_Box* o + print_collate_group[1]->end(); + } // Fl_Group* print_collate_group[1] + o->end(); + } // Fl_Group* o + { Fl_Return_Button* o = new Fl_Return_Button(279, 201, 100, 25, Fl_Printer::dialog_print_button); + o->callback((Fl_Callback*)print_cb); + } // Fl_Return_Button* o + { Fl_Button* o = new Fl_Button(389, 201, 68, 25, Fl_Printer::dialog_cancel_button); + o->callback((Fl_Callback*)cb_Cancel); + } // Fl_Button* o + print_panel_controls->end(); + } // Fl_Group* print_panel_controls + { print_progress = new Fl_Progress(10, 203, 289, 21); + print_progress->selection_color((Fl_Color)4); + print_progress->hide(); + } // Fl_Progress* print_progress + print_panel->set_modal(); + print_panel->end(); + } // Fl_Double_Window* print_panel + { print_properties_panel = new Fl_Double_Window(290, 130, Fl_Printer::property_title); + print_properties_panel->callback((Fl_Callback*)cb_print_properties_panel); + { print_page_size = new Fl_Choice(150, 10, 80, 25, Fl_Printer::property_pagesize); + print_page_size->down_box(FL_BORDER_BOX); + print_page_size->labelfont(FL_HELVETICA); + print_page_size->menu(menu_print_page_size); + } // Fl_Choice* print_page_size + { Fl_Group* o = new Fl_Group(110, 45, 170, 40, Fl_Printer::property_mode); + o->labelfont(FL_HELVETICA); + o->align(Fl_Align(FL_ALIGN_LEFT)); + { print_output_mode[0] = new Fl_Button(110, 45, 30, 40); + print_output_mode[0]->type(102); + print_output_mode[0]->box(FL_BORDER_BOX); + print_output_mode[0]->down_box(FL_BORDER_BOX); + print_output_mode[0]->value(1); + print_output_mode[0]->color(FL_BACKGROUND2_COLOR); + print_output_mode[0]->selection_color(FL_FOREGROUND_COLOR); + print_output_mode[0]->image(image_print_color); + } // Fl_Button* print_output_mode[0] + { print_output_mode[1] = new Fl_Button(150, 50, 40, 30); + print_output_mode[1]->type(102); + print_output_mode[1]->box(FL_BORDER_BOX); + print_output_mode[1]->down_box(FL_BORDER_BOX); + print_output_mode[1]->color(FL_BACKGROUND2_COLOR); + print_output_mode[1]->selection_color(FL_FOREGROUND_COLOR); + print_output_mode[1]->image(image_print_color); + } // Fl_Button* print_output_mode[1] + { print_output_mode[2] = new Fl_Button(200, 45, 30, 40); + print_output_mode[2]->type(102); + print_output_mode[2]->box(FL_BORDER_BOX); + print_output_mode[2]->down_box(FL_BORDER_BOX); + print_output_mode[2]->color(FL_BACKGROUND2_COLOR); + print_output_mode[2]->selection_color(FL_FOREGROUND_COLOR); + print_output_mode[2]->image(image_print_gray); + } // Fl_Button* print_output_mode[2] + { print_output_mode[3] = new Fl_Button(240, 50, 40, 30); + print_output_mode[3]->type(102); + print_output_mode[3]->box(FL_BORDER_BOX); + print_output_mode[3]->down_box(FL_BORDER_BOX); + print_output_mode[3]->color(FL_BACKGROUND2_COLOR); + print_output_mode[3]->selection_color(FL_FOREGROUND_COLOR); + print_output_mode[3]->image(image_print_gray); + } // Fl_Button* print_output_mode[3] + o->end(); + } // Fl_Group* o + { Fl_Return_Button* o = new Fl_Return_Button(93, 95, 99, 25, Fl_Printer::property_save); + o->callback((Fl_Callback*)cb_Save); + } // Fl_Return_Button* o + { Fl_Button* o = new Fl_Button(202, 95, 78, 25, Fl_Printer::property_cancel); + o->callback((Fl_Callback*)cb_Cancel1); + } // Fl_Button* o + { Fl_Button* o = new Fl_Button(10, 95, 73, 25, Fl_Printer::property_use); + o->callback((Fl_Callback*)cb_Use); + } // Fl_Button* o + print_properties_panel->set_modal(); + print_properties_panel->end(); + } // Fl_Double_Window* print_properties_panel + return print_properties_panel; +} + +void print_cb(Fl_Return_Button *, void *) { + print_start = 1; + print_panel->hide(); +} + +void print_load() { + FILE *lpstat; + char line[1024], name[1024], *nptr, qname[2048], *qptr, defname[1024]; + int i; + + if (print_choice->size() > 1) { + for (i = 1; print_choice->text(i); i ++) { + free(print_choice->menu()[i].user_data()); + } + } + + print_choice->clear(); + print_choice->add(Fl_Printer::dialog_print_to_file, 0, 0, 0, FL_MENU_DIVIDER); + print_choice->value(0); + + print_start = 0; + + defname[0] = '\0'; + + if ((lpstat = popen("LC_MESSAGES=C LANG=C lpstat -p -d", "r")) != NULL) { + while (fgets(line, sizeof(line), lpstat)) { + if (!strncmp(line, "printer ", 8) && + sscanf(line + 8, "%s", name) == 1) { + for (nptr = name, qptr = qname; *nptr; *qptr++ = *nptr++) { + if (*nptr == '/') *qptr++ = '\\'; + } + *qptr = '\0'; + + print_choice->add(qname, 0, 0, (void *)strdup(name), 0); + } else if (!strncmp(line, "system default destination: ", 28)) { + if (sscanf(line + 28, "%s", defname) != 1) defname[0] = '\0'; + } + } + pclose(lpstat); + } + + if (defname[0]) { + for (i = 1; print_choice->text(i); i ++) { + if (!strcmp((char *)print_choice->menu()[i].user_data(), defname)) { + print_choice->value(i); + break; + } + } + } else if (print_choice->size() > 2) print_choice->value(1); + + print_update_status(); + +} // print_load() + +void print_update_status() { + FILE *lpstat; + char command[1024]; + static char status[1024]; + const char *printer = (const char *)print_choice->menu()[print_choice->value()].user_data(); + + if (print_choice->value()) { + snprintf(command, sizeof(command), "lpstat -p '%s'", printer); + if ((lpstat = popen(command, "r")) != NULL) { + if (fgets(status, sizeof(status), lpstat)==0) { /* ignore */ } + pclose(lpstat); + } else strcpy(status, "printer status unavailable"); + } else status[0] = '\0'; + + print_status->label(status); + + char name[1024]; + int val; + + snprintf(name, sizeof(name), "%s/page_size", printer); + print_prefs.get(name, val, 1); + print_page_size->value(val); + + snprintf(name, sizeof(name), "%s/output_mode", printer); + print_prefs.get(name, val, 0); + print_output_mode[val]->setonly(); +} + +// +// End of "$Id: print_panel.cxx 7885 2010-11-23 12:13:17Z manolo $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/print_panel.h b/mod/maxgui.mod/fltkmaxgui.mod/src/print_panel.h new file mode 100644 index 0000000..7c7ae62 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/print_panel.h @@ -0,0 +1,55 @@ +// +// "$Id: print_panel.h 7263 2010-03-14 18:07:24Z AlbrechtS $" +// +// Print panel for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2009 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// +// This is a temporary file. It is only for development and will +// probably be removed later. +// + +#ifndef print_panel_h +#define print_panel_h +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +static Fl_Double_Window* make_print_panel(); +static void print_cb(Fl_Return_Button *, void *); +static void print_load(); +static void print_update_status(); +#endif + +// +// End of "$Id: print_panel.h 7263 2010-03-14 18:07:24Z AlbrechtS $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/ps_image.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/ps_image.cxx new file mode 100644 index 0000000..6d60558 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/ps_image.cxx @@ -0,0 +1,550 @@ +// +// "$Id: image.cxx 4324 2005-05-09 21:47:22Z rokan $" +// +// Postscript image drawing implementation for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef FL_DOXYGEN + +#include +#include +#include + +#include +#include +#include +#include + +int Fl_PostScript_Graphics_Driver::alpha_mask(const uchar * data, int w, int h, int D, int LD){ + + mask = 0; + if ((D/2)*2 != D){ //no mask info + return 0; + } + int xx; + int i,j, k, l; + LD += w*D; + int V255=0; + int V0 =0; + int V_=0; + for (j=0;j127){ + mask[jj*xx+ii/8] |= 1 << (ii % 8); //set mask bit + error = val-255; + }else + error = val; + + ////// error spreading ///// + if (error >0){ + next[ii] += o1 = (error * 3 + 8)/16; + current[ii+2] += o2 = (error * 7 + 8)/16; + next[ii+2] = o3 =(error + 8)/16; // *1 - ok replacing (cleaning) + } else { + next[ii] += o1 = (error * 3 - 8)/16; + current[ii+2] += o2 = (error * 7 - 8)/16; + next[ii+2] = o3 = (error - 8)/16; + } + next[1+ii] += error - o1 - o2 - o3; + } + } + l++; + + ////// backward + + jj = j*4+l; + swap = next; + next = current; + current = swap; + *(next+1) = 0; // must clean the first cell, next are overriden by *1 + + for (i = w-1; i >= 0; i--){ + + for (k=3; k>=0; k--){ // generating 4 x-pixels for 1 RGB + short error, o1, o2, o3; + + int ii = i*4+k; // mask cell index + short val = data[j*LD+D*i+D-1] + current[1+ii]; + if (val>127){ + + mask[jj*xx+ii/8] |= 1 << (ii % 8); //set mask bit + error = val-255; + } else + error = val; + + ////// error spreading ///// + if (error >0){ + next[ii+2] += o1 = (error * 3 + 8)/16; + current[ii] += o2 = (error * 7 + 8)/16; + next[ii] = o3 =(error + 8)/16; // *1 - ok replacing (cleaning) + } else { + next[ii+2] += o1 = (error * 3 - 8)/16; + + current[ii] += o2 = (error * 7 - 8)/16; + next[ii] = o3 = (error - 8)/16; + } + next[1+ii] += error - o1 - o2 - o3; + } + } + l++; + } + } + delete[] errors1; + delete[] errors2; + return 0; +} + +// bitwise inversion of all 4-bit quantities +static const unsigned char swapped[16] = {0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15}; + +// bitwise inversion of a byte +static inline uchar swap_byte(const uchar b) { + return (swapped[b & 0xF] << 4) | swapped[b >> 4]; +} + + +extern uchar **fl_mask_bitmap; + + +void Fl_PostScript_Graphics_Driver::draw_scaled_image(const uchar *data, double x, double y, double w, double h, int iw, int ih, int D, int LD) { + + + if (D<3){ //mono + draw_scaled_image_mono(data, x, y, w, h, iw, ih, D, LD); + return; + } + + + int i,j, k; + + fprintf(output,"save\n"); + + const char * interpol; + if (lang_level_>1){ + if (interpolate_) + interpol="true"; + else + interpol="false"; + if (mask && lang_level_>2) + fprintf(output, "%g %g %g %g %i %i %i %i %s CIM\n", x , y+h , w , -h , iw , ih, mx, my, interpol); + else + fprintf(output, "%g %g %g %g %i %i %s CII\n", x , y+h , w , -h , iw , ih, interpol); + } else + fprintf(output , "%g %g %g %g %i %i CI", x , y+h , w , -h , iw , ih); + + + if (!LD) LD = iw*D; + uchar *curmask=mask; + + for (j=0; j3) { //can do mixing using bg_* colors) + unsigned int a2 = curdata[3]; //must be int + unsigned int a = 255-a2; + r = (a2 * r + bg_r * a)/255; + g = (a2 * g + bg_g * a)/255; + b = (a2 * b + bg_b * a)/255; + } + if (!(i%40)) fprintf(output, "\n"); + fprintf(output, "%.2x%.2x%.2x", r, g, b); + curdata +=D; + } + fprintf(output,"\n"); + + } + + fprintf(output," >\nrestore\n" ); + + +} + +void Fl_PostScript_Graphics_Driver::draw_scaled_image(Fl_Draw_Image_Cb call, void *data, double x, double y, double w, double h, int iw, int ih, int D) { + + int level2_mask = 0; + fprintf(output,"save\n"); + int i,j,k; + const char * interpol; + if (lang_level_ > 1) { + if (interpolate_) interpol="true"; + else interpol="false"; + if (mask && lang_level_ > 2) { + fprintf(output, "%g %g %g %g %i %i %i %i %s CIM\n", x , y+h , w , -h , iw , ih, mx, my, interpol); + } + else if (mask && lang_level_ == 2) { + level2_mask = 1; // use method for drawing masked color image with PostScript level 2 + fprintf(output, " %g %g %g %g %d %d pixmap_plot\n", x, y, w, h, iw, ih); + } + else { + fprintf(output, "%g %g %g %g %i %i %s CII\n", x , y+h , w , -h , iw , ih, interpol); + } + } else { + fprintf(output , "%g %g %g %g %i %i CI", x , y+h , w , -h , iw , ih); + } + + int LD=iw*D; + uchar *rgbdata=new uchar[LD]; + uchar *curmask=mask; + + if (level2_mask) { + for (j = ih - 1; j >= 0; j--) { // output full image data + call(data, 0, j, iw, rgbdata); + uchar *curdata = rgbdata; + for (i=0 ; i\n", output); + for (j = ih - 1; j >= 0; j--) { // output mask data + curmask = mask + j * (my/ih) * ((mx+7)/8); + for (k=0; k < my/ih; k++) { + for (i=0; i < ((mx+7)/8); i++) { + if (!(i%40)) fputs("\n", output); + fprintf(output, "%.2x",swap_byte(*curmask)); + curmask++; + } + fputs("\n", output); + } + } + fputs(">\n", output); + } + else { + for (j=0; j 2) { // InterleaveType 2 mask data + for (k=0; k\n", output); + } + + fprintf(output,"restore\n"); + delete[] rgbdata; +} + +void Fl_PostScript_Graphics_Driver::draw_scaled_image_mono(const uchar *data, double x, double y, double w, double h, int iw, int ih, int D, int LD) { + + fprintf(output,"save\n"); + + int i,j, k; + + const char * interpol; + if (lang_level_>1){ + if (interpolate_) + interpol="true"; + else + interpol="false"; + if (mask && lang_level_>2) + fprintf(output, "%g %g %g %g %i %i %i %i %s GIM\n", x , y+h , w , -h , iw , ih, mx, my, interpol); + else + fprintf(output, "%g %g %g %g %i %i %s GII\n", x , y+h , w , -h , iw , ih, interpol); + }else + fprintf(output , "%g %g %g %g %i %i GI", x , y+h , w , -h , iw , ih); + + + if (!LD) LD = iw*D; + + + int bg = (bg_r + bg_g + bg_b)/3; + + uchar *curmask=mask; + for (j=0; j1) { //can do mixing + + unsigned int a2 = curdata[1]; //must be int + unsigned int a = 255-a2; + r = (a2 * r + bg * a)/255; + } + if (!(i%120)) fprintf(output, "\n"); + fprintf(output, "%.2x", r); + curdata +=D; + } + fprintf(output,"\n"); + + } + + fprintf(output," >\nrestore\n" ); + +} + + + +void Fl_PostScript_Graphics_Driver::draw_scaled_image_mono(Fl_Draw_Image_Cb call, void *data, double x, double y, double w, double h, int iw, int ih, int D) { + + fprintf(output,"save\n"); + int i,j,k; + const char * interpol; + if (lang_level_>1){ + if (interpolate_) interpol="true"; + else interpol="false"; + if (mask && lang_level_>2) + fprintf(output, "%g %g %g %g %i %i %i %i %s GIM\n", x , y+h , w , -h , iw , ih, mx, my, interpol); + else + fprintf(output, "%g %g %g %g %i %i %s GII\n", x , y+h , w , -h , iw , ih, interpol); + } else + fprintf(output , "%g %g %g %g %i %i GI", x , y+h , w , -h , iw , ih); + + int LD=iw*D; + uchar *rgbdata=new uchar[LD]; + uchar *curmask=mask; + for (j=0; j2){ // InterleaveType 2 mask data + for (k=0; k\n"); + fprintf(output,"restore\n"); + delete[] rgbdata; +} + + +////////////////////////////// Image classes ////////////////////// + + +void Fl_PostScript_Graphics_Driver::draw(Fl_Pixmap * pxm,int XP, int YP, int WP, int HP, int cx, int cy){ + const char * const * di =pxm->data(); + int w,h; + if (!fl_measure_pixmap(di, w, h)) return; + mask=0; + fl_mask_bitmap=&mask; + mx = WP; + my = HP; + push_clip(XP, YP, WP, HP); + fl_draw_pixmap(di,XP -cx, YP -cy, FL_BLACK ); + pop_clip(); + delete[] mask; + mask=0; + fl_mask_bitmap=0; +} + +void Fl_PostScript_Graphics_Driver::draw(Fl_RGB_Image * rgb,int XP, int YP, int WP, int HP, int cx, int cy){ + const uchar * di = rgb->array; + int w = rgb->w(); + int h = rgb->h(); + mask=0; + if (lang_level_>2) //when not true, not making alphamask, mixing colors instead... + if (alpha_mask(di, w, h, rgb->d(),rgb->ld())) return; //everthing masked, no need for painting! + push_clip(XP, YP, WP, HP); + draw_scaled_image(di, XP + cx, YP + cy, w, h, w, h, rgb->d(), rgb->ld()); + pop_clip(); + delete[]mask; + mask=0; +} + +void Fl_PostScript_Graphics_Driver::draw(Fl_Bitmap * bitmap,int XP, int YP, int WP, int HP, int cx, int cy){ + const uchar * di = bitmap->array; + int w,h; + int LD=(bitmap->w()+7)/8; + int xx; + + if (WP> bitmap->w() - cx){// to assure that it does not go out of bounds; + w = bitmap->w() - cx; + xx = (bitmap->w()+7)/8 - cx/8; //length of mask in bytes + }else{ + w =WP; + xx = (w+7)/8 - cx/8; + } + if ( HP > bitmap->h()-cy) + h = bitmap->h() - cy; + else + h = HP; + + di += cy*LD + cx/8; + int si = cx % 8; // small shift to be clipped, it is simpler than shifting whole mask + + int i,j; + push_clip(XP, YP, WP, HP); + fprintf(output , "%i %i %i %i %i %i MI", XP - si, YP + HP , WP , -HP , w , h); + + for (j=0; j\n"); + pop_clip(); +} + +#endif // FL_DOXYGEN + +// +// End of "$Id: image.cxx 4324 2005-05-09 21:47:22Z rokan $" +// + + + + + + + + + + + + + + + + + + diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/scandir.c b/mod/maxgui.mod/fltkmaxgui.mod/src/scandir.c new file mode 100644 index 0000000..1a3bd0d --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/scandir.c @@ -0,0 +1,125 @@ +/* Copyright (C) 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +USA. */ + +#if defined(WIN32) && !defined(__CYGWIN__) +# include "scandir_win32.c" +#else + +# include "flstring.h" +# include + +# if !HAVE_SCANDIR +# include +# include +# include + +# if HAVE_DIRENT_H +# include +# define NAMLEN(dirent) strlen((dirent)->d_name) +# else +# define dirent direct +# define NAMLEN(dirent) (dirent)->d_namlen +# if HAVE_SYS_NDIR_H +# include +# endif +# if HAVE_SYS_DIR_H +# include +# endif +# if HAVE_NDIR_H +# include +# endif +# endif + +int +fl_scandir(const char *dir, struct dirent ***namelist, + int (*select)(struct dirent *), + int (*compar)(struct dirent **, struct dirent **)) +{ + DIR *dp = opendir (fl_utf2mbcs(dir)); + struct dirent **v = NULL; + size_t vsize = 0, i; + struct dirent *d; + int save; + + if (dp == NULL) + return -1; + + save = errno; + errno = 0; + + i = 0; + while ((d = readdir (dp)) != NULL) + if (select == NULL || (*select) (d)) + { + size_t dsize; + + if (i == vsize) + { + struct dirent **newv; + if (vsize == 0) + vsize = 10; + else + vsize *= 2; + newv = (struct dirent **) realloc (v, vsize * sizeof (*v)); + if (newv == NULL) + { + lose: + errno = ENOMEM; + break; + } + v = newv; + } + +# define _D_EXACT_NAMLEN(d) (strlen ((d)->d_name)) +# define _D_ALLOC_NAMLEN(d) (sizeof (d)->d_name > 1 ? sizeof (d)->d_name : \ + _D_EXACT_NAMLEN (d) + 1) + + dsize = &d->d_name[_D_ALLOC_NAMLEN (d)] - (char *) d; + v[i] = (struct dirent *) malloc (dsize); + if (v[i] == NULL) + goto lose; + + memcpy (v[i++], d, dsize); + } + + if (errno != 0) + { + save = errno; + (void) closedir (dp); + while (i > 0) + free (v[--i]); + free (v); + errno = save; + return -1; + } + + (void) closedir (dp); + errno = save; + + /* Sort the list if we have a comparison function to sort with. */ + if (compar) qsort (v, i, sizeof (*v), (int (*)(const void *, const void *))compar); + *namelist = v; + return i; +} + +# endif +#endif + +/* + * End of "$Id: scandir.c 6311 2008-09-19 17:40:20Z matt $". + */ diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/scandir_win32.c b/mod/maxgui.mod/fltkmaxgui.mod/src/scandir_win32.c new file mode 100644 index 0000000..63ff712 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/scandir_win32.c @@ -0,0 +1,135 @@ +/* + * "$Id: scandir_win32.c 6687 2009-03-15 03:14:43Z greg.ercolano $" + * + * WIN32 scandir function for the Fast Light Tool Kit (FLTK). + * + * Copyright 1998-2009 by Bill Spitzak and others. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems on the following page: + * + * http://www.fltk.org/str.php + */ + +#ifndef __CYGWIN__ +/* Emulation of posix scandir() call */ +#include +#include +#include "flstring.h" +#include +#include + +int fl_scandir(const char *dirname, struct dirent ***namelist, + int (*select)(struct dirent *), + int (*compar)(struct dirent **, struct dirent **)) { + int len; + char *findIn, *d, is_dir = 0; + WIN32_FIND_DATAW findw; + HANDLE h; + int nDir = 0, NDir = 0; + struct dirent **dir = 0, *selectDir; + unsigned long ret; + + len = strlen(dirname); + findIn = (char *)malloc((size_t)(len+10)); + if (!findIn) return -1; + strcpy(findIn, dirname); + + //#if defined(__GNUC__) + //#warning FIXME This probably needs to be MORE UTF8 aware now + //#endif /*__GNUC__*/ + for (d = findIn; *d; d++) if (*d=='/') *d='\\'; + if ((len==0)) { strcpy(findIn, ".\\*"); } + if ((len==2)&&findIn[1]==':'&&isalpha(findIn[0])) { *d++ = '\\'; *d = 0; } + if ((len==1)&& (d[-1]=='.')) { strcpy(findIn, ".\\*"); is_dir = 1; } + if ((len>0) && (d[-1]=='\\')) { *d++ = '*'; *d = 0; is_dir = 1; } + if ((len>1) && (d[-1]=='.') && (d[-2]=='\\')) { d[-1] = '*'; is_dir = 1; } + if (!is_dir) { /* this file may still be a directory that we need to list */ + DWORD attr = GetFileAttributes(findIn); + if (attr&FILE_ATTRIBUTE_DIRECTORY) + strcpy(d, "\\*"); + } + { /* Create a block to limit the scope while we find the initial "wide" filename */ +// unsigned short * wbuf = (unsigned short*)malloc(sizeof(short) *(len + 10)); +// wbuf[fl_utf2unicode(findIn, strlen(findIn), wbuf)] = 0; + unsigned short *wbuf = NULL; + unsigned wlen = fl_utf8toUtf16(findIn, strlen(findIn), NULL, 0); /* Pass NULL to query length */ + wlen++; /* add a little extra for termination etc. */ + wbuf = (unsigned short*)malloc(sizeof(unsigned short)*wlen); + wlen = fl_utf8toUtf16(findIn, strlen(findIn), wbuf, wlen); /* actually convert the filename */ + wbuf[wlen] = 0; /* NULL terminate the resultant string */ + h = FindFirstFileW(wbuf, &findw); /* get a handle to the first filename in the search */ + free(wbuf); /* release the "wide" buffer before the pointer goes out of scope */ + } + if (h==INVALID_HANDLE_VALUE) { + free(findIn); + ret = GetLastError(); + if (ret != ERROR_NO_MORE_FILES) { + nDir = -1; + } + *namelist = dir; + return nDir; + } + do { + int l = wcslen(findw.cFileName); + int dstlen = l * 5 + 1; + selectDir=(struct dirent*)malloc(sizeof(struct dirent)+dstlen); + +// l = fl_unicode2utf(findw.cFileName, l, selectDir->d_name); + l = fl_utf8fromwc(selectDir->d_name, dstlen, findw.cFileName, l); + + selectDir->d_name[l] = 0; + if (findw.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + /* Append a trailing slash to directory names... */ + strcat(selectDir->d_name, "/"); + } + if (!select || (*select)(selectDir)) { + if (nDir==NDir) { + struct dirent **tempDir = (struct dirent **)calloc(sizeof(struct dirent*), (size_t)(NDir+33)); + if (NDir) memcpy(tempDir, dir, sizeof(struct dirent*)*NDir); + if (dir) free(dir); + dir = tempDir; + NDir += 32; + } + dir[nDir] = selectDir; + nDir++; + dir[nDir] = 0; + } else { + free(selectDir); + } + } while (FindNextFileW(h, &findw)); + ret = GetLastError(); + if (ret != ERROR_NO_MORE_FILES) { + /* don't return an error code, because the dir list may still be valid + up to this point */ + } + FindClose(h); + + free (findIn); + + if (compar) qsort(dir, (size_t)nDir, sizeof(*dir), + (int(*)(const void*, const void*))compar); + + *namelist = dir; + return nDir; +} + +#endif + +/* + * End of "$Id: scandir_win32.c 6687 2009-03-15 03:14:43Z greg.ercolano $". + */ diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/screen_xywh.cxx b/mod/maxgui.mod/fltkmaxgui.mod/src/screen_xywh.cxx new file mode 100644 index 0000000..124764b --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/screen_xywh.cxx @@ -0,0 +1,258 @@ +// +// "$Id: screen_xywh.cxx 7903 2010-11-28 21:06:39Z matt $" +// +// Screen/monitor bounding box API for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + + +#include +#include +#include + + +// Number of screens... +static int num_screens = 0; + +#ifdef WIN32 +# if !defined(HMONITOR_DECLARED) && (_WIN32_WINNT < 0x0500) +# define COMPILE_MULTIMON_STUBS +# include +# endif // !HMONITOR_DECLARED && _WIN32_WINNT < 0x0500 + +// We go the much more difficult route of individually picking some multi-screen +// functions from the USER32.DLL . If these functions are not available, we +// will gracefully fall back to single monitor support. +// +// If we were to insist on the existence of "EnumDisplayMonitors" and +// "GetMonitorInfoA", it would be impossible to use FLTK on Windows 2000 +// before SP2 or earlier. + +// BOOL EnumDisplayMonitors(HDC, LPCRECT, MONITORENUMPROC, LPARAM) +typedef BOOL (WINAPI* fl_edm_func)(HDC, LPCRECT, MONITORENUMPROC, LPARAM); +// BOOL GetMonitorInfo(HMONITOR, LPMONITORINFO) +typedef BOOL (WINAPI* fl_gmi_func)(HMONITOR, LPMONITORINFO); + +static fl_gmi_func fl_gmi = NULL; // used to get a proc pointer for GetMonitorInfoA + +static RECT screens[16]; + +static BOOL CALLBACK screen_cb(HMONITOR mon, HDC, LPRECT r, LPARAM) { + if (num_screens >= 16) return TRUE; + + MONITORINFO mi; + mi.cbSize = sizeof(mi); + +// GetMonitorInfo(mon, &mi); +// (but we use our self-aquired function pointer instead) + if (fl_gmi(mon, &mi)) { + screens[num_screens] = mi.rcWork; + num_screens ++; + } + return TRUE; +} + +static void screen_init() { + // Since not all versions of Windows include multiple monitor support, + // we do a run-time check for the required functions... + HMODULE hMod = GetModuleHandle("USER32.DLL"); + + if (hMod) { + // check that EnumDisplayMonitors is available + fl_edm_func fl_edm = (fl_edm_func)GetProcAddress(hMod, "EnumDisplayMonitors"); + + if (fl_edm) { + // We do have EnumDisplayMonitors, so lets find out how many monitors... + num_screens = GetSystemMetrics(SM_CMONITORS); + + if (num_screens > 1) { + // If there is more than 1 monitor, enumerate them... + fl_gmi = (fl_gmi_func)GetProcAddress(hMod, "GetMonitorInfoA"); + + if (fl_gmi) { + // We have GetMonitorInfoA, enumerate all the screens... + num_screens = 0; +// EnumDisplayMonitors(0,0,screen_cb,0); +// (but we use our self-aquired function pointer instead) + fl_edm(0, 0, screen_cb, 0); + return; + } + } + } + } + + // If we get here, assume we have 1 monitor... + num_screens = 1; +} +#elif defined(__APPLE__) +XRectangle screens[16]; + +extern int MACscreen_init(XRectangle screens[]); +static void screen_init() { + num_screens = MACscreen_init(screens); +} +#elif HAVE_XINERAMA +# include + +// Screen data... +static XineramaScreenInfo *screens; + +static void screen_init() { + if (!fl_display) fl_open_display(); + + if (XineramaIsActive(fl_display)) { + screens = XineramaQueryScreens(fl_display, &num_screens); + } else num_screens = 1; +} +#else +static void screen_init() { + num_screens = 1; +} +#endif // WIN32 + + +/** + Gets the number of available screens. +*/ +int Fl::screen_count() { + if (!num_screens) screen_init(); + + return num_screens; +} + +/** + Gets the bounding box of a screen + that contains the specified screen position \p mx, \p my + \param[out] X,Y,W,H the corresponding screen bounding box + \param[in] mx, my the absolute screen position +*/ +void Fl::screen_xywh(int &X, int &Y, int &W, int &H, int mx, int my) { + if (!num_screens) screen_init(); + +#ifdef WIN32 + if (num_screens > 1) { + int i; + + for (i = 0; i < num_screens; i ++) { + if (mx >= screens[i].left && mx < screens[i].right && + my >= screens[i].top && my < screens[i].bottom) { + X = screens[i].left; + Y = screens[i].top; + W = screens[i].right - screens[i].left; + H = screens[i].bottom - screens[i].top; + return; + } + } + } +#elif defined(__APPLE__) + if (num_screens > 1) { + int i; + + for (i = 0; i < num_screens; i ++) { + if (mx >= screens[i].x && + mx < (screens[i].x + screens[i].width) && + my >= screens[i].y && + my < (screens[i].y + screens[i].height)) { + X = screens[i].x; + Y = screens[i].y; + W = screens[i].width; + H = screens[i].height; + return; + } + } + } +#elif HAVE_XINERAMA + if (num_screens > 1) { + int i; + + for (i = 0; i < num_screens; i ++) { + if (mx >= screens[i].x_org && + mx < (screens[i].x_org + screens[i].width) && + my >= screens[i].y_org && + my < (screens[i].y_org + screens[i].height)) { + X = screens[i].x_org; + Y = screens[i].y_org; + W = screens[i].width; + H = screens[i].height; + return; + } + } + } +#else + (void)mx; + (void)my; +#endif // WIN32 + + X = Fl::x(); + Y = Fl::y(); + W = Fl::w(); + H = Fl::h(); +} + +/** + Gets the screen bounding rect for the given screen. + \param[out] X,Y,W,H the corresponding screen bounding box + \param[in] n the screen number (0 to Fl::screen_count() - 1) + \see void screen_xywh(int &x, int &y, int &w, int &h, int mx, int my) +*/ +void Fl::screen_xywh(int &X, int &Y, int &W, int &H, int n) { + if (!num_screens) screen_init(); + +#ifdef WIN32 + if (num_screens > 1 && n >= 0 && n < num_screens) { + X = screens[n].left; + Y = screens[n].top; + W = screens[n].right - screens[n].left; + H = screens[n].bottom - screens[n].top; + return; + } +#elif defined(__APPLE__) + if (num_screens > 1 && n >= 0 && n < num_screens) { + X = screens[n].x; + Y = screens[n].y; + W = screens[n].width; + H = screens[n].height; + return; + } +#elif HAVE_XINERAMA + if (num_screens > 1 && n >= 0 && n < num_screens) { + X = screens[n].x_org; + Y = screens[n].y_org; + W = screens[n].width; + H = screens[n].height; + return; + } +#else + (void)n; +#endif // WIN32 + + X = Fl::x(); + Y = Fl::y(); + W = Fl::w(); + H = Fl::h(); +} + + +// +// End of "$Id: screen_xywh.cxx 7903 2010-11-28 21:06:39Z matt $". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/slowarrow.h b/mod/maxgui.mod/fltkmaxgui.mod/src/slowarrow.h new file mode 100644 index 0000000..46a572c --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/slowarrow.h @@ -0,0 +1,6 @@ +#define slowarrow_width 16 +#define slowarrow_height 16 +static unsigned char slowarrow_bits[] = { + 0x40, 0x00, 0x40, 0x00, 0x60, 0x00, 0x60, 0x00, 0xf0, 0x0f, 0x60, 0x00, + 0x60, 0x00, 0x40, 0x02, 0x40, 0x02, 0x00, 0x06, 0x00, 0x06, 0xf0, 0x0f, + 0x00, 0x06, 0x00, 0x06, 0x00, 0x02, 0x00, 0x02}; diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/tile.xpm b/mod/maxgui.mod/fltkmaxgui.mod/src/tile.xpm new file mode 100644 index 0000000..872e0f7 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/tile.xpm @@ -0,0 +1,91 @@ +/* XPM */ +static char tile_cmap[3][32] = { +"O c #FFFFFF", +"o c #EFEFEF", +". c #E8E8E8" +}; +static const char * tile_xpm[] = { +"64 64 3 1", +tile_cmap[0], +tile_cmap[1], +tile_cmap[2], + +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"................................................................", +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", + +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"................................................................", +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", + +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"................................................................", +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", + +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"................................................................", +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", + +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"................................................................", +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", + +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"................................................................", +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", + +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"................................................................", +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", + +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"................................................................", +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", + +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"................................................................", +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", + +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"................................................................", +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", + +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"................................................................", +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", + +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"................................................................", +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", + +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"................................................................", +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", + +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"................................................................", +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", + +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"................................................................", +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", + +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"................................................................", +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO"}; diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/up.xbm b/mod/maxgui.mod/fltkmaxgui.mod/src/up.xbm new file mode 100644 index 0000000..1a4f4b7 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/up.xbm @@ -0,0 +1,6 @@ +#define up_width 16 +#define up_height 16 +static unsigned char up_bits[] = { + 0x00, 0x00, 0x78, 0x00, 0x84, 0x00, 0x02, 0x01, 0x31, 0xfe, 0x79, 0x80, + 0xfd, 0x80, 0x31, 0x80, 0x31, 0x80, 0x31, 0x80, 0x31, 0x80, 0x31, 0x80, + 0x01, 0x80, 0x01, 0x80, 0xff, 0xff, 0x00, 0x00}; diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/vsnprintf.c b/mod/maxgui.mod/fltkmaxgui.mod/src/vsnprintf.c new file mode 100644 index 0000000..d479f8a --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/vsnprintf.c @@ -0,0 +1,281 @@ +/* + * "$Id: vsnprintf.c 7903 2010-11-28 21:06:39Z matt $" + * + * snprintf() and vsnprintf() functions for the Fast Light Tool Kit (FLTK). + * + * Copyright 1998-2010 by Bill Spitzak and others. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems on the following page: + * + * http://www.fltk.org/str.php + */ + +#include +#include "flstring.h" + +#ifdef HAVE_SYS_STDTYPES_H +# include +#endif /* HAVE_SYS_STDTYPES_H */ + +#ifdef __cplusplus +extern "C" { +#endif + +int fl_vsnprintf(char* buffer, size_t bufsize, const char* format, va_list ap) { + char *bufptr, /* Pointer to position in buffer */ + *bufend, /* Pointer to end of buffer */ + sign, /* Sign of format width */ + size, /* Size character (h, l, L) */ + type; /* Format type character */ + int width, /* Width of field */ + prec; /* Number of characters of precision */ + char tformat[100], /* Temporary format string for sprintf() */ + *tptr, /* Pointer into temporary format */ + temp[1024]; /* Buffer for formatted numbers */ + char *s; /* Pointer to string */ + int slen; /* Length of string */ + int bytes; /* Total number of bytes needed */ + + + /* + * Loop through the format string, formatting as needed... + */ + + bufptr = buffer; + bufend = buffer + bufsize - 1; + bytes = 0; + + while (*format) { + if (*format == '%') { + tptr = tformat; + *tptr++ = *format++; + + if (*format == '%') { + if (bufptr && bufptr < bufend) *bufptr++ = *format; + bytes ++; + format ++; + continue; + } else if (strchr(" -+#\'", *format)) { + *tptr++ = *format; + sign = *format++; + } else sign = 0; + + if (*format == '*') { + /* Get width from argument... */ + format ++; + width = va_arg(ap, int); + snprintf(tptr, sizeof(tformat) - (tptr - tformat), "%d", width); + tptr += strlen(tptr); + } else { + width = 0; + while (isdigit(*format & 255)) { + if (tptr < (tformat + sizeof(tformat) - 1)) *tptr++ = *format; + width = width * 10 + *format++ - '0'; + } + } + + if (*format == '.') { + if (tptr < (tformat + sizeof(tformat) - 1)) *tptr++ = *format; + format ++; + + if (*format == '*') { + /* Get precision from argument... */ + format ++; + prec = va_arg(ap, int); + snprintf(tptr, sizeof(tformat) - (tptr - tformat), "%d", prec); + tptr += strlen(tptr); + } else { + prec = 0; + while (isdigit(*format & 255)) { + if (tptr < (tformat + sizeof(tformat) - 1)) *tptr++ = *format; + prec = prec * 10 + *format++ - '0'; + } + } + } else prec = -1; + + size = '\0'; + + if (*format == 'l' && format[1] == 'l') { + size = 'L'; + if (tptr < (tformat + sizeof(tformat) - 2)) { + *tptr++ = 'l'; + *tptr++ = 'l'; + } + format += 2; + } else if (*format == 'h' || *format == 'l' || *format == 'L') { + if (tptr < (tformat + sizeof(tformat) - 1)) *tptr++ = *format; + size = *format++; + } + + if (!*format) break; + + if (tptr < (tformat + sizeof(tformat) - 1)) *tptr++ = *format; + type = *format++; + *tptr = '\0'; + + switch (type) { + case 'E' : /* Floating point formats */ + case 'G' : + case 'e' : + case 'f' : + case 'g' : + if ((width + 2) > sizeof(temp)) break; + + sprintf(temp, tformat, va_arg(ap, double)); + + bytes += strlen(temp); + + if (bufptr) { + if ((bufptr + strlen(temp)) > bufend) { + strncpy(bufptr, temp, (size_t)(bufend - bufptr)); + bufptr = bufend; + } else { + strcpy(bufptr, temp); + bufptr += strlen(temp); + } + } + break; + + case 'B' : /* Integer formats */ + case 'X' : + case 'b' : + case 'd' : + case 'i' : + case 'o' : + case 'u' : + case 'x' : + if ((width + 2) > sizeof(temp)) break; + +#ifdef HAVE_LONG_LONG + if (size == 'L') + sprintf(temp, tformat, va_arg(ap, long long)); + else +#endif /* HAVE_LONG_LONG */ + if (size == 'l') + sprintf(temp, tformat, va_arg(ap, long)); + else + sprintf(temp, tformat, va_arg(ap, int)); + + bytes += strlen(temp); + + if (bufptr) { + if ((bufptr + strlen(temp)) > bufend) { + strncpy(bufptr, temp, (size_t)(bufend - bufptr)); + bufptr = bufend; + } else { + strcpy(bufptr, temp); + bufptr += strlen(temp); + } + } + break; + + case 'p' : /* Pointer value */ + if ((width + 2) > sizeof(temp)) break; + + sprintf(temp, tformat, va_arg(ap, void *)); + + bytes += strlen(temp); + + if (bufptr) { + if ((bufptr + strlen(temp)) > bufend) { + strncpy(bufptr, temp, (size_t)(bufend - bufptr)); + bufptr = bufend; + } else { + strcpy(bufptr, temp); + bufptr += strlen(temp); + } + } + break; + + case 'c' : /* Character or character array */ + bytes += width; + + if (bufptr) { + if (width <= 1) *bufptr++ = va_arg(ap, int); + else { + if ((bufptr + width) > bufend) width = bufend - bufptr; + + memcpy(bufptr, va_arg(ap, char *), (size_t)width); + bufptr += width; + } + } + break; + + case 's' : /* String */ + if ((s = va_arg(ap, char *)) == NULL) s = "(null)"; + + slen = strlen(s); + if (slen > width && prec != width) width = slen; + + bytes += width; + + if (bufptr) { + if ((bufptr + width) > bufend) width = bufend - bufptr; + + if (slen > width) slen = width; + + if (sign == '-') { + strncpy(bufptr, s, (size_t)slen); + memset(bufptr + slen, ' ', (size_t)(width - slen)); + } else { + memset(bufptr, ' ', (size_t)(width - slen)); + strncpy(bufptr + width - slen, s, (size_t)slen); + } + + bufptr += width; + } + break; + + case 'n' : /* Output number of chars so far */ + *(va_arg(ap, int *)) = bytes; + break; + } + } else { + bytes ++; + + if (bufptr && bufptr < bufend) *bufptr++ = *format; + format ++; + } + } + + /* + * Nul-terminate the string and return the number of characters needed. + */ + + if (bufptr) *bufptr = '\0'; + + return (bytes); +} + +int fl_snprintf(char* str, size_t size, const char* fmt, ...) { + int ret; + va_list ap; + va_start(ap, fmt); + ret = vsnprintf(str, size, fmt, ap); + va_end(ap); + return ret; +} + +#ifdef __cplusplus +} +#endif + +/* + * End of "$Id: vsnprintf.c 7903 2010-11-28 21:06:39Z matt $". + */ + diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/COPYING b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/COPYING new file mode 100644 index 0000000..04d4a38 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/COPYING @@ -0,0 +1,50 @@ + * Author: Jean-Marc Lienher ( http://oksid.ch ) + * Copyright 2000-2003 by O'ksi'D. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems on the following page: + * + * http://www.fltk.org/str.php + + + lcUniConv directory: + +Copyright (c) 1999-2000 Free Software Foundation, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +FREE SOFTWARE FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the Free Software Foundation +shall not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization from the +Free Software Foundation. + + diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/Makefile b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/Makefile new file mode 100644 index 0000000..abd133f --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/Makefile @@ -0,0 +1,132 @@ +# +# "$Id: Makefile,v 1.1.2.6 2004/09/08 16:04:42 easysw Exp $" +# +# Xutf8 library makefile for the Fast Light Toolkit (FLTK). +# +# Copyright 1997-2005 by Jean-Marc Lienher. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. +# +# You should have received a copy of the GNU Library General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +# USA. +# +# Please report all bugs and problems on the following page: +# +# http://www.fltk.org/str.php +# + +include ../../makeinclude + + +# +# Object files... set this based on the operating system and host +# +UNAME := $(shell uname) + +ifeq '$(OS)' "Windows_NT" +OBJS = case.o is_right2left.o is_spacing.o +endif # end of WIN32 options + +ifeq ($(strip $(UNAME)),Linux) +OBJS = case.o is_right2left.o is_spacing.o \ + keysym2Ucs.o utf8Input.o utf8Utils.o \ + utf8Wrap.o +endif # end of linux options + +ifeq ($(strip $(UNAME)),Darwin) +OBJS = case.o is_right2left.o is_spacing.o +endif # end of OSX options + + + +XUTF8 = ../../lib/libfltk_xutf8$(LIBEXT) + + +# +# Make all targets... +# + +all: $(XUTF8) $(XDSONAME) + + +# +# Clean all targets and object files... +# + +clean: + $(RM) $(OBJS) + $(RM) $(XUTF8) $(XDSONAME) libfltk_xutf8.so + + +# +# Install everything... +# + +install: $(XUTF8) + echo "Installing libfltk_xutf8$(LIBEXT) in $(libdir)..." + -$(MKDIR) $(libdir) + $(RM) $(libdir)/libfltk_xutf8$(LIBEXT) + $(CP) $(XUTF8) $(libdir) + $(RANLIB) $(libdir)/libfltk_xutf8$(LIBEXT) + if test x$(XDSONAME) = xlibfltk_xutf8.so.1.1; then\ + $(RM) $(DESTDIR)$(libdir)/libfltk_xutf8.so*;\ + $(CP) libfltk_xutf8.so.1.1 $(DESTDIR)$(libdir); \ + $(CHMOD) 755 $(DESTDIR)$(libdir)/libfltk_xutf8.so.1.1; \ + $(LN) libfltk_xutf8.so.1.1 $(DESTDIR)$(libdir)/libfltk_xutf8.so;\ + fi + + +# +# Uninstall everything... +# + +uninstall: + echo "Uninstalling libfltk_xutf8$(LIBEXT) in $(libdir)..." + $(RM) $(libdir)/libfltk_xutf8$(LIBEXT) + if test x$(XDSONAME) = xlibfltk_xutf8.so.1.1; then\ + $(RM) $(DESTDIR)$(libdir)/libfltk_xutf8.so*;\ + fi + + +# +# libfltk_xutf8.a +# + +$(XUTF8): $(OBJS) + echo Archiving $@... + $(RM) $@ + $(LIBCOMMAND) $@ $(OBJS) + $(RANLIB) $@ + +libfltk_xutf8.so.1.1: $(OBJS) + echo $(DSOCOMMAND) $@ ... + $(DSOCOMMAND) $@ $(OBJS) + $(RM) libfltk_xutf8.so + $(LN) libfltk_xutf8.so.1.1 libfltk_xutf8.so + +# +# Make dependencies... +# + +depend: $(OBJS:.o=.c) + makedepend -Y -I.. -f makedepend $(OBJS:.o=.c) + +include makedepend + +$(OBJS): ../../makeinclude + + +# +# End of "$Id: Makefile,v 1.1.2.6 2004/09/08 16:04:42 easysw Exp $". +# +# DO NOT DELETE diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/README b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/README new file mode 100644 index 0000000..cc9c51d --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/README @@ -0,0 +1,67 @@ + + + +supported encodings : +--------------------- +iso10646-1 +iso8859-1 +iso8859-2 +iso8859-3 +iso8859-4 +iso8859-5 +iso8859-6 +iso8859-7 +iso8859-8 +iso8859-9 +iso8859-10 +iso8859-11 +iso8859-13 +iso8859-14 +iso8859-15 +koi8-r +koi8-u +big5-0 +gbk +gb2312.1980-0 +jisx0201.1976-0 +jisx0208.1983-0 +jisx0212.1990-0 +ksc5601.1987-0 +symbol +dingbats + + +TIPS: +===== + +You must add "-lXutf8" to the library list in your Makefile. + +When using "GNU autoconf" add these lines to your "configure.in" : + +dnl Test to see if libXutf8 is on this machine: +XUTFLIB= +AC_CHECK_LIB(Xutf8, XUtf8IsNonSpacing, \ + AC_DEFINE(HAVE_XUTF8) XUTFLIB=" -lXutf8", ,\ + -lX11 $X_EXTRA_LIBS) +AC_SUBST(XUTFLIB) + + +ORIGINAL FILES : +================ + +The directory lcUniConv is copied from the xfree project cvs system. +( +export CVS_RSH=ssh +export CVSROOT=anoncvs@anoncvs.xfree86.org:/cvs +cvs checkout xc/lib/X11/lcUniConv +password: anoncvs +) + +The file imKStoUCS.c is copied from the xfree project cvs system. +( +export CVS_RSH=ssh +export CVSROOT=anoncvs@anoncvs.xfree86.org:/cvs +cvs checkout xc/lib/X11 +password: anoncvs +) + diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/Ximint.h b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/Ximint.h new file mode 100644 index 0000000..e69de29 diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/Xlibint.h b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/Xlibint.h new file mode 100644 index 0000000..e69de29 diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/case.c b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/case.c new file mode 100644 index 0000000..6e9ac67 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/case.c @@ -0,0 +1,126 @@ +/* + * "$Id: $" + * + * Author: Jean-Marc Lienher ( http://oksid.ch ) + * Copyright 2000-2010 by O'ksi'D. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems on the following page: + * + * http://www.fltk.org/str.php + */ + +/* + * This file is required on all platforms for utf8 support + */ + +#include "headers/case.h" +#include + +int +XUtf8Tolower(int ucs) { + int ret; + if (ucs <= 0x02B6) { + if (ucs >= 0x0041) { + ret = ucs_table_0041[ucs - 0x0041]; + if (ret > 0) return ret; + } + return ucs; + } + + if (ucs <= 0x0556) { + if (ucs >= 0x0386) { + ret = ucs_table_0386[ucs - 0x0386]; + if (ret > 0) return ret; + } + return ucs; + } + + if (ucs <= 0x10C5) { + if (ucs >= 0x10A0) { + ret = ucs_table_10A0[ucs - 0x10A0]; + if (ret > 0) return ret; + } + return ucs; + } + + if (ucs <= 0x1FFC) { + if (ucs >= 0x1E00) { + ret = ucs_table_1E00[ucs - 0x1E00]; + if (ret > 0) return ret; + } + return ucs; + } + + if (ucs <= 0x2133) { + if (ucs >= 0x2102) { + ret = ucs_table_2102[ucs - 0x2102]; + if (ret > 0) return ret; + } + return ucs; + } + + if (ucs <= 0x24CF) { + if (ucs >= 0x24B6) { + ret = ucs_table_24B6[ucs - 0x24B6]; + if (ret > 0) return ret; + } + return ucs; + } + + if (ucs <= 0x33CE) { + if (ucs >= 0x33CE) { + ret = ucs_table_33CE[ucs - 0x33CE]; + if (ret > 0) return ret; + } + return ucs; + } + + if (ucs <= 0xFF3A) { + if (ucs >= 0xFF21) { + ret = ucs_table_FF21[ucs - 0xFF21]; + if (ret > 0) return ret; + } + return ucs; + } + + return ucs; +} + +int +XUtf8Toupper(int ucs) { + int i; + static unsigned short *table = NULL; + + if (!table) { + table = (unsigned short*) malloc(sizeof(unsigned short) * 0x10000); + for (i = 0; i < 0x10000; i++) { + table[i] = (unsigned short) i; + } + for (i = 0; i < 0x10000; i++) { + int l; + l = XUtf8Tolower(i); + if (l != i) table[l] = (unsigned short) i; + } + } + if (ucs >= 0x10000 || ucs < 0) return ucs; + return table[ucs]; +} + +/* +* End of "$Id$". +*/ diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/headers/case.h b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/headers/case.h new file mode 100644 index 0000000..30ea901 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/headers/case.h @@ -0,0 +1,1770 @@ +/* spacing */ + +static const unsigned short ucs_table_0041[] = { +/* U+0041 */ 0x0061, +/* U+0042 */ 0x0062, +/* U+0043 */ 0x0063, +/* U+0044 */ 0x0064, +/* U+0045 */ 0x0065, +/* U+0046 */ 0x0066, +/* U+0047 */ 0x0067, +/* U+0048 */ 0x0068, +/* U+0049 */ 0x0069, +/* U+004A */ 0x006A, +/* U+004B */ 0x006B, +/* U+004C */ 0x006C, +/* U+004D */ 0x006D, +/* U+004E */ 0x006E, +/* U+004F */ 0x006F, +/* U+0050 */ 0x0070, +/* U+0051 */ 0x0071, +/* U+0052 */ 0x0072, +/* U+0053 */ 0x0073, +/* U+0054 */ 0x0074, +/* U+0055 */ 0x0075, +/* U+0056 */ 0x0076, +/* U+0057 */ 0x0077, +/* U+0058 */ 0x0078, +/* U+0059 */ 0x0079, +/* U+005A */ 0x007A, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+00C0 */ 0x00E0, +/* U+00C1 */ 0x00E1, +/* U+00C2 */ 0x00E2, +/* U+00C3 */ 0x00E3, +/* U+00C4 */ 0x00E4, +/* U+00C5 */ 0x00E5, +/* U+00C6 */ 0x00E6, +/* U+00C7 */ 0x00E7, +/* U+00C8 */ 0x00E8, +/* U+00C9 */ 0x00E9, +/* U+00CA */ 0x00EA, +/* U+00CB */ 0x00EB, +/* U+00CC */ 0x00EC, +/* U+00CD */ 0x00ED, +/* U+00CE */ 0x00EE, +/* U+00CF */ 0x00EF, +/* U+00D0 */ 0x00F0, +/* U+00D1 */ 0x00F1, +/* U+00D2 */ 0x00F2, +/* U+00D3 */ 0x00F3, +/* U+00D4 */ 0x00F4, +/* U+00D5 */ 0x00F5, +/* U+00D6 */ 0x00F6, +0x00, +/* U+00D8 */ 0x00F8, +/* U+00D9 */ 0x00F9, +/* U+00DA */ 0x00FA, +/* U+00DB */ 0x00FB, +/* U+00DC */ 0x00FC, +/* U+00DD */ 0x00FD, +/* U+00DE */ 0x00FE, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+0100 */ 0x0101, +0x00, +/* U+0102 */ 0x0103, +0x00, +/* U+0104 */ 0x0105, +0x00, +/* U+0106 */ 0x0107, +0x00, +/* U+0108 */ 0x0109, +0x00, +/* U+010A */ 0x010B, +0x00, +/* U+010C */ 0x010D, +0x00, +/* U+010E */ 0x010F, +0x00, +/* U+0110 */ 0x0111, +0x00, +/* U+0112 */ 0x0113, +0x00, +/* U+0114 */ 0x0115, +0x00, +/* U+0116 */ 0x0117, +0x00, +/* U+0118 */ 0x0119, +0x00, +/* U+011A */ 0x011B, +0x00, +/* U+011C */ 0x011D, +0x00, +/* U+011E */ 0x011F, +0x00, +/* U+0120 */ 0x0121, +0x00, +/* U+0122 */ 0x0123, +0x00, +/* U+0124 */ 0x0125, +0x00, +/* U+0126 */ 0x0127, +0x00, +/* U+0128 */ 0x0129, +0x00, +/* U+012A */ 0x012B, +0x00, +/* U+012C */ 0x012D, +0x00, +/* U+012E */ 0x012F, +0x00, +/* U+0130 */ 0x0, +0x00, +/* U+0132 */ 0x0133, +0x00, +/* U+0134 */ 0x0135, +0x00, +/* U+0136 */ 0x0137, +0x00, +0x00, +/* U+0139 */ 0x013A, +0x00, +/* U+013B */ 0x013C, +0x00, +/* U+013D */ 0x013E, +0x00, +/* U+013F */ 0x0140, +0x00, +/* U+0141 */ 0x0142, +0x00, +/* U+0143 */ 0x0144, +0x00, +/* U+0145 */ 0x0146, +0x00, +/* U+0147 */ 0x0148, +0x00, +0x00, +/* U+014A */ 0x014B, +0x00, +/* U+014C */ 0x014D, +0x00, +/* U+014E */ 0x014F, +0x00, +/* U+0150 */ 0x0151, +0x00, +/* U+0152 */ 0x0153, +0x00, +/* U+0154 */ 0x0155, +0x00, +/* U+0156 */ 0x0157, +0x00, +/* U+0158 */ 0x0159, +0x00, +/* U+015A */ 0x015B, +0x00, +/* U+015C */ 0x015D, +0x00, +/* U+015E */ 0x015F, +0x00, +/* U+0160 */ 0x0161, +0x00, +/* U+0162 */ 0x0163, +0x00, +/* U+0164 */ 0x0165, +0x00, +/* U+0166 */ 0x0167, +0x00, +/* U+0168 */ 0x0169, +0x00, +/* U+016A */ 0x016B, +0x00, +/* U+016C */ 0x016D, +0x00, +/* U+016E */ 0x016F, +0x00, +/* U+0170 */ 0x0171, +0x00, +/* U+0172 */ 0x0173, +0x00, +/* U+0174 */ 0x0175, +0x00, +/* U+0176 */ 0x0177, +0x00, +/* U+0178 */ 0x00FF, +/* U+0179 */ 0x017A, +0x00, +/* U+017B */ 0x017C, +0x00, +/* U+017D */ 0x017E, +0x00, +0x00, +0x00, +/* U+0181 */ 0x0253, +/* U+0182 */ 0x0183, +0x00, +/* U+0184 */ 0x0185, +0x00, +/* U+0186 */ 0x0254, +/* U+0187 */ 0x0188, +0x00, +/* U+0189 */ 0x0, +/* U+018A */ 0x0257, +/* U+018B */ 0x018C, +0x00, +0x00, +/* U+018E */ 0x0258, +/* U+018F */ 0x0259, +/* U+0190 */ 0x025B, +/* U+0191 */ 0x0192, +0x00, +/* U+0193 */ 0x0260, +/* U+0194 */ 0x0263, +0x00, +/* U+0196 */ 0x0269, +/* U+0197 */ 0x0268, +/* U+0198 */ 0x0199, +0x00, +0x00, +0x00, +/* U+019C */ 0x026F, +/* U+019D */ 0x0272, +0x00, +/* U+019F */ 0x0, +/* U+01A0 */ 0x01A1, +0x00, +/* U+01A2 */ 0x01A3, +0x00, +/* U+01A4 */ 0x01A5, +0x00, +0x00, +/* U+01A7 */ 0x01A8, +0x00, +/* U+01A9 */ 0x0283, +0x00, +0x00, +/* U+01AC */ 0x01AD, +0x00, +/* U+01AE */ 0x0288, +/* U+01AF */ 0x01B0, +0x00, +/* U+01B1 */ 0x028A, +/* U+01B2 */ 0x028B, +/* U+01B3 */ 0x01B4, +0x00, +/* U+01B5 */ 0x01B6, +0x00, +/* U+01B7 */ 0x0292, +/* U+01B8 */ 0x01B9, +0x00, +0x00, +0x00, +/* U+01BC */ 0x01BD, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+01C4 */ 0x01C6, +/* U+01C5 */ 0x0, +0x00, +/* U+01C7 */ 0x01C9, +/* U+01C8 */ 0x0, +0x00, +/* U+01CA */ 0x01CC, +/* U+01CB */ 0x0, +0x00, +/* U+01CD */ 0x01CE, +0x00, +/* U+01CF */ 0x01D0, +0x00, +/* U+01D1 */ 0x01D2, +0x00, +/* U+01D3 */ 0x01D4, +0x00, +/* U+01D5 */ 0x01D6, +0x00, +/* U+01D7 */ 0x01D8, +0x00, +/* U+01D9 */ 0x01DA, +0x00, +/* U+01DB */ 0x01DC, +0x00, +0x00, +/* U+01DE */ 0x01DF, +0x00, +/* U+01E0 */ 0x01E1, +0x00, +/* U+01E2 */ 0x01E3, +0x00, +/* U+01E4 */ 0x01E5, +0x00, +/* U+01E6 */ 0x01E7, +0x00, +/* U+01E8 */ 0x01E9, +0x00, +/* U+01EA */ 0x01EB, +0x00, +/* U+01EC */ 0x01ED, +0x00, +/* U+01EE */ 0x01EF, +0x00, +0x00, +/* U+01F1 */ 0x01F3, +/* U+01F2 */ 0x0, +0x00, +/* U+01F4 */ 0x01F5, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+01FA */ 0x01FB, +0x00, +/* U+01FC */ 0x01FD, +0x00, +/* U+01FE */ 0x01FF, +0x00, +/* U+0200 */ 0x0201, +0x00, +/* U+0202 */ 0x0203, +0x00, +/* U+0204 */ 0x0205, +0x00, +/* U+0206 */ 0x0207, +0x00, +/* U+0208 */ 0x0209, +0x00, +/* U+020A */ 0x020B, +0x00, +/* U+020C */ 0x020D, +0x00, +/* U+020E */ 0x020F, +0x00, +/* U+0210 */ 0x0211, +0x00, +/* U+0212 */ 0x0213, +0x00, +/* U+0214 */ 0x0215, +0x00, +/* U+0216 */ 0x0217, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+0262 */ 0x0, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+026A */ 0x0, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+0274 */ 0x0, +0x00, +/* U+0276 */ 0x0, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+0280 */ 0x0, +/* U+0281 */ 0x0, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+028F */ 0x0, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+0299 */ 0x0, +0x00, +/* U+029B */ 0x0, +/* U+029C */ 0x0, +0x00, +0x00, +/* U+029F */ 0x0, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+02B6 */ 0x0, +}; + +static const unsigned short ucs_table_0386[] = { +/* U+0386 */ 0x03AC, +0x00, +/* U+0388 */ 0x03AD, +/* U+0389 */ 0x03AE, +/* U+038A */ 0x03AF, +0x00, +/* U+038C */ 0x03CC, +0x00, +/* U+038E */ 0x03CD, +/* U+038F */ 0x03CE, +0x00, +/* U+0391 */ 0x03B1, +/* U+0392 */ 0x03B2, +/* U+0393 */ 0x03B3, +/* U+0394 */ 0x03B4, +/* U+0395 */ 0x03B5, +/* U+0396 */ 0x03B6, +/* U+0397 */ 0x03B7, +/* U+0398 */ 0x03B8, +/* U+0399 */ 0x03B9, +/* U+039A */ 0x03BA, +/* U+039B */ 0x03BB, +/* U+039C */ 0x03BC, +/* U+039D */ 0x03BD, +/* U+039E */ 0x03BE, +/* U+039F */ 0x03BF, +/* U+03A0 */ 0x03C0, +/* U+03A1 */ 0x03C1, +0x00, +/* U+03A3 */ 0x03C3, +/* U+03A4 */ 0x03C4, +/* U+03A5 */ 0x03C5, +/* U+03A6 */ 0x03C6, +/* U+03A7 */ 0x03C7, +/* U+03A8 */ 0x03C8, +/* U+03A9 */ 0x03C9, +/* U+03AA */ 0x03CA, +/* U+03AB */ 0x03CB, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+03D2 */ 0x03D2, +/* U+03D3 */ 0x03D3, +/* U+03D4 */ 0x03D4, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+03DA */ 0x03DA, +0x00, +/* U+03DC */ 0x03DC, +0x00, +/* U+03DE */ 0x03DE, +0x00, +/* U+03E0 */ 0x03E0, +0x00, +/* U+03E2 */ 0x03E3, +0x00, +/* U+03E4 */ 0x03E5, +0x00, +/* U+03E6 */ 0x03E7, +0x00, +/* U+03E8 */ 0x03E9, +0x00, +/* U+03EA */ 0x03EB, +0x00, +/* U+03EC */ 0x03ED, +0x00, +/* U+03EE */ 0x03EF, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+0401 */ 0x0451, +/* U+0402 */ 0x0452, +/* U+0403 */ 0x0453, +/* U+0404 */ 0x0454, +/* U+0405 */ 0x0455, +/* U+0406 */ 0x0456, +/* U+0407 */ 0x0457, +/* U+0408 */ 0x0458, +/* U+0409 */ 0x0459, +/* U+040A */ 0x045A, +/* U+040B */ 0x045B, +/* U+040C */ 0x045C, +0x00, +/* U+040E */ 0x045E, +/* U+040F */ 0x045F, +/* U+0410 */ 0x0430, +/* U+0411 */ 0x0431, +/* U+0412 */ 0x0432, +/* U+0413 */ 0x0433, +/* U+0414 */ 0x0434, +/* U+0415 */ 0x0435, +/* U+0416 */ 0x0436, +/* U+0417 */ 0x0437, +/* U+0418 */ 0x0438, +/* U+0419 */ 0x0439, +/* U+041A */ 0x043A, +/* U+041B */ 0x043B, +/* U+041C */ 0x043C, +/* U+041D */ 0x043D, +/* U+041E */ 0x043E, +/* U+041F */ 0x043F, +/* U+0420 */ 0x0440, +/* U+0421 */ 0x0441, +/* U+0422 */ 0x0442, +/* U+0423 */ 0x0443, +/* U+0424 */ 0x0444, +/* U+0425 */ 0x0445, +/* U+0426 */ 0x0446, +/* U+0427 */ 0x0447, +/* U+0428 */ 0x0448, +/* U+0429 */ 0x0449, +/* U+042A */ 0x044A, +/* U+042B */ 0x044B, +/* U+042C */ 0x044C, +/* U+042D */ 0x044D, +/* U+042E */ 0x044E, +/* U+042F */ 0x044F, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+0460 */ 0x0461, +0x00, +/* U+0462 */ 0x0463, +0x00, +/* U+0464 */ 0x0465, +0x00, +/* U+0466 */ 0x0467, +0x00, +/* U+0468 */ 0x0469, +0x00, +/* U+046A */ 0x046B, +0x00, +/* U+046C */ 0x046D, +0x00, +/* U+046E */ 0x046F, +0x00, +/* U+0470 */ 0x0471, +0x00, +/* U+0472 */ 0x0473, +0x00, +/* U+0474 */ 0x0475, +0x00, +/* U+0476 */ 0x0477, +0x00, +/* U+0478 */ 0x0479, +0x00, +/* U+047A */ 0x047B, +0x00, +/* U+047C */ 0x047D, +0x00, +/* U+047E */ 0x047F, +0x00, +/* U+0480 */ 0x0481, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+0490 */ 0x0491, +0x00, +/* U+0492 */ 0x0493, +0x00, +/* U+0494 */ 0x0495, +0x00, +/* U+0496 */ 0x0497, +0x00, +/* U+0498 */ 0x0499, +0x00, +/* U+049A */ 0x049B, +0x00, +/* U+049C */ 0x049D, +0x00, +/* U+049E */ 0x049F, +0x00, +/* U+04A0 */ 0x04A1, +0x00, +/* U+04A2 */ 0x04A3, +0x00, +/* U+04A4 */ 0x04A5, +0x00, +/* U+04A6 */ 0x04A7, +0x00, +/* U+04A8 */ 0x04A9, +0x00, +/* U+04AA */ 0x04AB, +0x00, +/* U+04AC */ 0x04AD, +0x00, +/* U+04AE */ 0x04AF, +0x00, +/* U+04B0 */ 0x04B1, +0x00, +/* U+04B2 */ 0x04B3, +0x00, +/* U+04B4 */ 0x04B5, +0x00, +/* U+04B6 */ 0x04B7, +0x00, +/* U+04B8 */ 0x04B9, +0x00, +/* U+04BA */ 0x04BB, +0x00, +/* U+04BC */ 0x04BD, +0x00, +/* U+04BE */ 0x04BF, +0x00, +0x00, +/* U+04C1 */ 0x04C2, +0x00, +/* U+04C3 */ 0x04C4, +0x00, +0x00, +0x00, +/* U+04C7 */ 0x04C8, +0x00, +0x00, +0x00, +/* U+04CB */ 0x04CC, +0x00, +0x00, +0x00, +0x00, +/* U+04D0 */ 0x04D1, +0x00, +/* U+04D2 */ 0x04D3, +0x00, +/* U+04D4 */ 0x04D5, +0x00, +/* U+04D6 */ 0x04D7, +0x00, +/* U+04D8 */ 0x04D9, +0x00, +/* U+04DA */ 0x04DB, +0x00, +/* U+04DC */ 0x04DD, +0x00, +/* U+04DE */ 0x04DF, +0x00, +/* U+04E0 */ 0x04E1, +0x00, +/* U+04E2 */ 0x04E3, +0x00, +/* U+04E4 */ 0x04E5, +0x00, +/* U+04E6 */ 0x04E7, +0x00, +/* U+04E8 */ 0x04E9, +0x00, +/* U+04EA */ 0x04EB, +0x00, +0x00, +0x00, +/* U+04EE */ 0x04EF, +0x00, +/* U+04F0 */ 0x04F1, +0x00, +/* U+04F2 */ 0x04F3, +0x00, +/* U+04F4 */ 0x04F5, +0x00, +0x00, +0x00, +/* U+04F8 */ 0x04F9, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+0531 */ 0x0561, +/* U+0532 */ 0x0562, +/* U+0533 */ 0x0563, +/* U+0534 */ 0x0564, +/* U+0535 */ 0x0565, +/* U+0536 */ 0x0566, +/* U+0537 */ 0x0567, +/* U+0538 */ 0x0568, +/* U+0539 */ 0x0569, +/* U+053A */ 0x056A, +/* U+053B */ 0x056B, +/* U+053C */ 0x056C, +/* U+053D */ 0x056D, +/* U+053E */ 0x056E, +/* U+053F */ 0x056F, +/* U+0540 */ 0x0570, +/* U+0541 */ 0x0571, +/* U+0542 */ 0x0572, +/* U+0543 */ 0x0573, +/* U+0544 */ 0x0574, +/* U+0545 */ 0x0575, +/* U+0546 */ 0x0576, +/* U+0547 */ 0x0577, +/* U+0548 */ 0x0578, +/* U+0549 */ 0x0579, +/* U+054A */ 0x057A, +/* U+054B */ 0x057B, +/* U+054C */ 0x057C, +/* U+054D */ 0x057D, +/* U+054E */ 0x057E, +/* U+054F */ 0x057F, +/* U+0550 */ 0x0580, +/* U+0551 */ 0x0581, +/* U+0552 */ 0x0582, +/* U+0553 */ 0x0583, +/* U+0554 */ 0x0584, +/* U+0555 */ 0x0585, +/* U+0556 */ 0x0586, +}; + +static const unsigned short ucs_table_10A0[] = { +/* U+10A0 */ 0x10D0, +/* U+10A1 */ 0x10D1, +/* U+10A2 */ 0x10D2, +/* U+10A3 */ 0x10D3, +/* U+10A4 */ 0x10D4, +/* U+10A5 */ 0x10D5, +/* U+10A6 */ 0x10D6, +/* U+10A7 */ 0x10D7, +/* U+10A8 */ 0x10D8, +/* U+10A9 */ 0x10D9, +/* U+10AA */ 0x10DA, +/* U+10AB */ 0x10DB, +/* U+10AC */ 0x10DC, +/* U+10AD */ 0x10DD, +/* U+10AE */ 0x10DE, +/* U+10AF */ 0x10DF, +/* U+10B0 */ 0x10E0, +/* U+10B1 */ 0x10E1, +/* U+10B2 */ 0x10E2, +/* U+10B3 */ 0x10E3, +/* U+10B4 */ 0x10E4, +/* U+10B5 */ 0x10E5, +/* U+10B6 */ 0x10E6, +/* U+10B7 */ 0x10E7, +/* U+10B8 */ 0x10E8, +/* U+10B9 */ 0x10E9, +/* U+10BA */ 0x10EA, +/* U+10BB */ 0x10EB, +/* U+10BC */ 0x10EC, +/* U+10BD */ 0x10ED, +/* U+10BE */ 0x10EE, +/* U+10BF */ 0x10EF, +/* U+10C0 */ 0x10F0, +/* U+10C1 */ 0x10F1, +/* U+10C2 */ 0x10F2, +/* U+10C3 */ 0x10F3, +/* U+10C4 */ 0x10F4, +/* U+10C5 */ 0x10F5, +}; + +static const unsigned short ucs_table_1E00[] = { +/* U+1E00 */ 0x1E01, +0x00, +/* U+1E02 */ 0x1E03, +0x00, +/* U+1E04 */ 0x1E05, +0x00, +/* U+1E06 */ 0x1E07, +0x00, +/* U+1E08 */ 0x1E09, +0x00, +/* U+1E0A */ 0x1E0B, +0x00, +/* U+1E0C */ 0x1E0D, +0x00, +/* U+1E0E */ 0x1E0F, +0x00, +/* U+1E10 */ 0x1E11, +0x00, +/* U+1E12 */ 0x1E13, +0x00, +/* U+1E14 */ 0x1E15, +0x00, +/* U+1E16 */ 0x1E17, +0x00, +/* U+1E18 */ 0x1E19, +0x00, +/* U+1E1A */ 0x1E1B, +0x00, +/* U+1E1C */ 0x1E1D, +0x00, +/* U+1E1E */ 0x1E1F, +0x00, +/* U+1E20 */ 0x1E21, +0x00, +/* U+1E22 */ 0x1E23, +0x00, +/* U+1E24 */ 0x1E25, +0x00, +/* U+1E26 */ 0x1E27, +0x00, +/* U+1E28 */ 0x1E29, +0x00, +/* U+1E2A */ 0x1E2B, +0x00, +/* U+1E2C */ 0x1E2D, +0x00, +/* U+1E2E */ 0x1E2F, +0x00, +/* U+1E30 */ 0x1E31, +0x00, +/* U+1E32 */ 0x1E33, +0x00, +/* U+1E34 */ 0x1E35, +0x00, +/* U+1E36 */ 0x1E37, +0x00, +/* U+1E38 */ 0x1E39, +0x00, +/* U+1E3A */ 0x1E3B, +0x00, +/* U+1E3C */ 0x1E3D, +0x00, +/* U+1E3E */ 0x1E3F, +0x00, +/* U+1E40 */ 0x1E41, +0x00, +/* U+1E42 */ 0x1E43, +0x00, +/* U+1E44 */ 0x1E45, +0x00, +/* U+1E46 */ 0x1E47, +0x00, +/* U+1E48 */ 0x1E49, +0x00, +/* U+1E4A */ 0x1E4B, +0x00, +/* U+1E4C */ 0x1E4D, +0x00, +/* U+1E4E */ 0x1E4F, +0x00, +/* U+1E50 */ 0x1E51, +0x00, +/* U+1E52 */ 0x1E53, +0x00, +/* U+1E54 */ 0x1E55, +0x00, +/* U+1E56 */ 0x1E57, +0x00, +/* U+1E58 */ 0x1E59, +0x00, +/* U+1E5A */ 0x1E5B, +0x00, +/* U+1E5C */ 0x1E5D, +0x00, +/* U+1E5E */ 0x1E5F, +0x00, +/* U+1E60 */ 0x1E61, +0x00, +/* U+1E62 */ 0x1E63, +0x00, +/* U+1E64 */ 0x1E65, +0x00, +/* U+1E66 */ 0x1E67, +0x00, +/* U+1E68 */ 0x1E69, +0x00, +/* U+1E6A */ 0x1E6B, +0x00, +/* U+1E6C */ 0x1E6D, +0x00, +/* U+1E6E */ 0x1E6F, +0x00, +/* U+1E70 */ 0x1E71, +0x00, +/* U+1E72 */ 0x1E73, +0x00, +/* U+1E74 */ 0x1E75, +0x00, +/* U+1E76 */ 0x1E77, +0x00, +/* U+1E78 */ 0x1E79, +0x00, +/* U+1E7A */ 0x1E7B, +0x00, +/* U+1E7C */ 0x1E7D, +0x00, +/* U+1E7E */ 0x1E7F, +0x00, +/* U+1E80 */ 0x1E81, +0x00, +/* U+1E82 */ 0x1E83, +0x00, +/* U+1E84 */ 0x1E85, +0x00, +/* U+1E86 */ 0x1E87, +0x00, +/* U+1E88 */ 0x1E89, +0x00, +/* U+1E8A */ 0x1E8B, +0x00, +/* U+1E8C */ 0x1E8D, +0x00, +/* U+1E8E */ 0x1E8F, +0x00, +/* U+1E90 */ 0x1E91, +0x00, +/* U+1E92 */ 0x1E93, +0x00, +/* U+1E94 */ 0x1E95, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+1EA0 */ 0x1EA1, +0x00, +/* U+1EA2 */ 0x1EA3, +0x00, +/* U+1EA4 */ 0x1EA5, +0x00, +/* U+1EA6 */ 0x1EA7, +0x00, +/* U+1EA8 */ 0x1EA9, +0x00, +/* U+1EAA */ 0x1EAB, +0x00, +/* U+1EAC */ 0x1EAD, +0x00, +/* U+1EAE */ 0x1EAF, +0x00, +/* U+1EB0 */ 0x1EB1, +0x00, +/* U+1EB2 */ 0x1EB3, +0x00, +/* U+1EB4 */ 0x1EB5, +0x00, +/* U+1EB6 */ 0x1EB7, +0x00, +/* U+1EB8 */ 0x1EB9, +0x00, +/* U+1EBA */ 0x1EBB, +0x00, +/* U+1EBC */ 0x1EBD, +0x00, +/* U+1EBE */ 0x1EBF, +0x00, +/* U+1EC0 */ 0x1EC1, +0x00, +/* U+1EC2 */ 0x1EC3, +0x00, +/* U+1EC4 */ 0x1EC5, +0x00, +/* U+1EC6 */ 0x1EC7, +0x00, +/* U+1EC8 */ 0x1EC9, +0x00, +/* U+1ECA */ 0x1ECB, +0x00, +/* U+1ECC */ 0x1ECD, +0x00, +/* U+1ECE */ 0x1ECF, +0x00, +/* U+1ED0 */ 0x1ED1, +0x00, +/* U+1ED2 */ 0x1ED3, +0x00, +/* U+1ED4 */ 0x1ED5, +0x00, +/* U+1ED6 */ 0x1ED7, +0x00, +/* U+1ED8 */ 0x1ED9, +0x00, +/* U+1EDA */ 0x1EDB, +0x00, +/* U+1EDC */ 0x1EDD, +0x00, +/* U+1EDE */ 0x1EDF, +0x00, +/* U+1EE0 */ 0x1EE1, +0x00, +/* U+1EE2 */ 0x1EE3, +0x00, +/* U+1EE4 */ 0x1EE5, +0x00, +/* U+1EE6 */ 0x1EE7, +0x00, +/* U+1EE8 */ 0x1EE9, +0x00, +/* U+1EEA */ 0x1EEB, +0x00, +/* U+1EEC */ 0x1EED, +0x00, +/* U+1EEE */ 0x1EEF, +0x00, +/* U+1EF0 */ 0x1EF1, +0x00, +/* U+1EF2 */ 0x1EF3, +0x00, +/* U+1EF4 */ 0x1EF5, +0x00, +/* U+1EF6 */ 0x1EF7, +0x00, +/* U+1EF8 */ 0x1EF9, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+1F08 */ 0x1F00, +/* U+1F09 */ 0x1F01, +/* U+1F0A */ 0x1F02, +/* U+1F0B */ 0x1F03, +/* U+1F0C */ 0x1F04, +/* U+1F0D */ 0x1F05, +/* U+1F0E */ 0x1F06, +/* U+1F0F */ 0x1F07, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+1F18 */ 0x1F10, +/* U+1F19 */ 0x1F11, +/* U+1F1A */ 0x1F12, +/* U+1F1B */ 0x1F13, +/* U+1F1C */ 0x1F14, +/* U+1F1D */ 0x1F15, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+1F28 */ 0x1F20, +/* U+1F29 */ 0x1F21, +/* U+1F2A */ 0x1F22, +/* U+1F2B */ 0x1F23, +/* U+1F2C */ 0x1F24, +/* U+1F2D */ 0x1F25, +/* U+1F2E */ 0x1F26, +/* U+1F2F */ 0x1F27, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+1F38 */ 0x1F30, +/* U+1F39 */ 0x1F31, +/* U+1F3A */ 0x1F32, +/* U+1F3B */ 0x1F33, +/* U+1F3C */ 0x1F34, +/* U+1F3D */ 0x1F35, +/* U+1F3E */ 0x1F36, +/* U+1F3F */ 0x1F37, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+1F48 */ 0x1F40, +/* U+1F49 */ 0x1F41, +/* U+1F4A */ 0x1F42, +/* U+1F4B */ 0x1F43, +/* U+1F4C */ 0x1F44, +/* U+1F4D */ 0x1F45, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+1F59 */ 0x1F51, +0x00, +/* U+1F5B */ 0x1F53, +0x00, +/* U+1F5D */ 0x1F55, +0x00, +/* U+1F5F */ 0x1F57, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+1F68 */ 0x1F60, +/* U+1F69 */ 0x1F61, +/* U+1F6A */ 0x1F62, +/* U+1F6B */ 0x1F63, +/* U+1F6C */ 0x1F64, +/* U+1F6D */ 0x1F65, +/* U+1F6E */ 0x1F66, +/* U+1F6F */ 0x1F67, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+1F88 */ 0x0, +/* U+1F89 */ 0x0, +/* U+1F8A */ 0x0, +/* U+1F8B */ 0x0, +/* U+1F8C */ 0x0, +/* U+1F8D */ 0x0, +/* U+1F8E */ 0x0, +/* U+1F8F */ 0x0, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+1F98 */ 0x0, +/* U+1F99 */ 0x0, +/* U+1F9A */ 0x0, +/* U+1F9B */ 0x0, +/* U+1F9C */ 0x0, +/* U+1F9D */ 0x0, +/* U+1F9E */ 0x0, +/* U+1F9F */ 0x0, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+1FA8 */ 0x0, +/* U+1FA9 */ 0x0, +/* U+1FAA */ 0x0, +/* U+1FAB */ 0x0, +/* U+1FAC */ 0x0, +/* U+1FAD */ 0x0, +/* U+1FAE */ 0x0, +/* U+1FAF */ 0x0, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+1FB8 */ 0x1FB0, +/* U+1FB9 */ 0x1FB1, +/* U+1FBA */ 0x1F70, +/* U+1FBB */ 0x1F71, +/* U+1FBC */ 0x0, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+1FC8 */ 0x1F72, +/* U+1FC9 */ 0x1F73, +/* U+1FCA */ 0x1F74, +/* U+1FCB */ 0x1F75, +/* U+1FCC */ 0x0, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+1FD8 */ 0x1FD0, +/* U+1FD9 */ 0x1FD1, +/* U+1FDA */ 0x1F76, +/* U+1FDB */ 0x1F77, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+1FE8 */ 0x1FE0, +/* U+1FE9 */ 0x1FE1, +/* U+1FEA */ 0x1F7A, +/* U+1FEB */ 0x1F7B, +/* U+1FEC */ 0x1FE5, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+1FF8 */ 0x1F78, +/* U+1FF9 */ 0x1F79, +/* U+1FFA */ 0x1F7C, +/* U+1FFB */ 0x1F7D, +/* U+1FFC */ 0x0, +}; + +static const unsigned short ucs_table_2102[] = { +/* U+2102 */ 0x0, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+210B */ 0x0, +/* U+210C */ 0x0, +/* U+210D */ 0x0, +0x00, +0x00, +/* U+2110 */ 0x0, +/* U+2111 */ 0x0, +/* U+2112 */ 0x2113, +0x00, +0x00, +/* U+2115 */ 0x0, +0x00, +0x00, +/* U+2118 */ 0x0, +/* U+2119 */ 0x0, +/* U+211A */ 0x0, +/* U+211B */ 0x0, +/* U+211C */ 0x0, +/* U+211D */ 0x0, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+2124 */ 0x0, +0x00, +0x00, +0x00, +/* U+2128 */ 0x0, +0x00, +0x00, +0x00, +/* U+212C */ 0x0, +/* U+212D */ 0x0, +0x00, +0x00, +/* U+2130 */ 0x212F, +/* U+2131 */ 0x0, +/* U+2132 */ 0x0, +/* U+2133 */ 0x0, +}; + +static const unsigned short ucs_table_24B6[] = { +/* U+24B6 */ 0x24D0, +/* U+24B7 */ 0x24D1, +/* U+24B8 */ 0x24D2, +/* U+24B9 */ 0x24D3, +/* U+24BA */ 0x24D4, +/* U+24BB */ 0x24D5, +/* U+24BC */ 0x24D6, +/* U+24BD */ 0x24D7, +/* U+24BE */ 0x24D8, +/* U+24BF */ 0x24D9, +/* U+24C0 */ 0x24DA, +/* U+24C1 */ 0x24DB, +/* U+24C2 */ 0x24DC, +/* U+24C3 */ 0x24DD, +/* U+24C4 */ 0x24DE, +/* U+24C5 */ 0x24DF, +/* U+24C6 */ 0x24E0, +/* U+24C7 */ 0x24E1, +/* U+24C8 */ 0x24E2, +/* U+24C9 */ 0x24E3, +/* U+24CA */ 0x24E4, +/* U+24CB */ 0x24E5, +/* U+24CC */ 0x24E6, +/* U+24CD */ 0x24E7, +/* U+24CE */ 0x24E8, +/* U+24CF */ 0x24E9, +}; + +static const unsigned short ucs_table_33CE[] = { +/* U+33CE */ 0x0, +}; + +static const unsigned short ucs_table_FF21[] = { +/* U+FF21 */ 0xFF41, +/* U+FF22 */ 0xFF42, +/* U+FF23 */ 0xFF43, +/* U+FF24 */ 0xFF44, +/* U+FF25 */ 0xFF45, +/* U+FF26 */ 0xFF46, +/* U+FF27 */ 0xFF47, +/* U+FF28 */ 0xFF48, +/* U+FF29 */ 0xFF49, +/* U+FF2A */ 0xFF4A, +/* U+FF2B */ 0xFF4B, +/* U+FF2C */ 0xFF4C, +/* U+FF2D */ 0xFF4D, +/* U+FF2E */ 0xFF4E, +/* U+FF2F */ 0xFF4F, +/* U+FF30 */ 0xFF50, +/* U+FF31 */ 0xFF51, +/* U+FF32 */ 0xFF52, +/* U+FF33 */ 0xFF53, +/* U+FF34 */ 0xFF54, +/* U+FF35 */ 0xFF55, +/* U+FF36 */ 0xFF56, +/* U+FF37 */ 0xFF57, +/* U+FF38 */ 0xFF58, +/* U+FF39 */ 0xFF59, +/* U+FF3A */ 0xFF5A, +}; diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/headers/case_tbl.txt b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/headers/case_tbl.txt new file mode 100644 index 0000000..2ed45fc --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/headers/case_tbl.txt @@ -0,0 +1,8 @@ +ucs_table_0041[]; /* end: U+02B6 */ +ucs_table_0386[]; /* end: U+0556 */ +ucs_table_10A0[]; /* end: U+10C5 */ +ucs_table_1E00[]; /* end: U+1FFC */ +ucs_table_2102[]; /* end: U+2133 */ +ucs_table_24B6[]; /* end: U+24CF */ +ucs_table_33CE[]; /* end: U+33CE */ +ucs_table_FF21[]; /* end: U+FF3A */ diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/headers/dingbats_.h b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/headers/dingbats_.h new file mode 100644 index 0000000..9f1f225 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/headers/dingbats_.h @@ -0,0 +1,565 @@ +/* dingbats */ + +static const char unicode_to_dingbats_1b_0020[] = { +/* U+0020 */ 0x20, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+00A0 */ 0x20, +}; + +static const char unicode_to_dingbats_1b_2192[] = { +/* U+2192 */ 0xD5, +0x00, +/* U+2194 */ 0xD6, +/* U+2195 */ 0xD7, +}; + +static const char unicode_to_dingbats_1b_2460[] = { +/* U+2460 */ 0xAC, +/* U+2461 */ 0xAD, +/* U+2462 */ 0xAE, +/* U+2463 */ 0xAF, +/* U+2464 */ 0xB0, +/* U+2465 */ 0xB1, +/* U+2466 */ 0xB2, +/* U+2467 */ 0xB3, +/* U+2468 */ 0xB4, +/* U+2469 */ 0xB5, +}; + +static const char unicode_to_dingbats_1b_25A0[] = { +/* U+25A0 */ 0x6E, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+25B2 */ 0x73, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+25BC */ 0x74, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+25C6 */ 0x75, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+25CF */ 0x6C, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+25D7 */ 0x77, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+2605 */ 0x48, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+260E */ 0x25, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+261B */ 0x2A, +0x00, +0x00, +/* U+261E */ 0x2B, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+2660 */ 0xAB, +0x00, +0x00, +/* U+2663 */ 0xA8, +0x00, +/* U+2665 */ 0xAA, +/* U+2666 */ 0xA9, +}; + +static const char unicode_to_dingbats_1b_2701[] = { +/* U+2701 */ 0x21, +/* U+2702 */ 0x22, +/* U+2703 */ 0x23, +/* U+2704 */ 0x24, +0x00, +/* U+2706 */ 0x26, +/* U+2707 */ 0x27, +/* U+2708 */ 0x28, +/* U+2709 */ 0x29, +0x00, +0x00, +/* U+270C */ 0x2C, +/* U+270D */ 0x2D, +/* U+270E */ 0x2E, +/* U+270F */ 0x2F, +/* U+2710 */ 0x30, +/* U+2711 */ 0x31, +/* U+2712 */ 0x32, +/* U+2713 */ 0x33, +/* U+2714 */ 0x34, +/* U+2715 */ 0x35, +/* U+2716 */ 0x36, +/* U+2717 */ 0x37, +/* U+2718 */ 0x38, +/* U+2719 */ 0x39, +/* U+271A */ 0x3A, +/* U+271B */ 0x3B, +/* U+271C */ 0x3C, +/* U+271D */ 0x3D, +/* U+271E */ 0x3E, +/* U+271F */ 0x3F, +/* U+2720 */ 0x40, +/* U+2721 */ 0x41, +/* U+2722 */ 0x42, +/* U+2723 */ 0x43, +/* U+2724 */ 0x44, +/* U+2725 */ 0x45, +/* U+2726 */ 0x46, +/* U+2727 */ 0x47, +0x00, +/* U+2729 */ 0x49, +/* U+272A */ 0x4A, +/* U+272B */ 0x4B, +/* U+272C */ 0x4C, +/* U+272D */ 0x4D, +/* U+272E */ 0x4E, +/* U+272F */ 0x4F, +/* U+2730 */ 0x50, +/* U+2731 */ 0x51, +/* U+2732 */ 0x52, +/* U+2733 */ 0x53, +/* U+2734 */ 0x54, +/* U+2735 */ 0x55, +/* U+2736 */ 0x56, +/* U+2737 */ 0x57, +/* U+2738 */ 0x58, +/* U+2739 */ 0x59, +/* U+273A */ 0x5A, +/* U+273B */ 0x5B, +/* U+273C */ 0x5C, +/* U+273D */ 0x5D, +/* U+273E */ 0x5E, +/* U+273F */ 0x5F, +/* U+2740 */ 0x60, +/* U+2741 */ 0x61, +/* U+2742 */ 0x62, +/* U+2743 */ 0x63, +/* U+2744 */ 0x64, +/* U+2745 */ 0x65, +/* U+2746 */ 0x66, +/* U+2747 */ 0x67, +/* U+2748 */ 0x68, +/* U+2749 */ 0x69, +/* U+274A */ 0x6A, +/* U+274B */ 0x6B, +0x00, +/* U+274D */ 0x6D, +0x00, +/* U+274F */ 0x6F, +/* U+2750 */ 0x70, +/* U+2751 */ 0x71, +/* U+2752 */ 0x72, +0x00, +0x00, +0x00, +/* U+2756 */ 0x76, +0x00, +/* U+2758 */ 0x78, +/* U+2759 */ 0x79, +/* U+275A */ 0x7A, +/* U+275B */ 0x7B, +/* U+275C */ 0x7C, +/* U+275D */ 0x7D, +/* U+275E */ 0x7E, +0x00, +0x00, +/* U+2761 */ 0xA1, +/* U+2762 */ 0xA2, +/* U+2763 */ 0xA3, +/* U+2764 */ 0xA4, +/* U+2765 */ 0xA5, +/* U+2766 */ 0xA6, +/* U+2767 */ 0xA7, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+2776 */ 0xB6, +/* U+2777 */ 0xB7, +/* U+2778 */ 0xB8, +/* U+2779 */ 0xB9, +/* U+277A */ 0xBA, +/* U+277B */ 0xBB, +/* U+277C */ 0xBC, +/* U+277D */ 0xBD, +/* U+277E */ 0xBE, +/* U+277F */ 0xBF, +/* U+2780 */ 0xC0, +/* U+2781 */ 0xC1, +/* U+2782 */ 0xC2, +/* U+2783 */ 0xC3, +/* U+2784 */ 0xC4, +/* U+2785 */ 0xC5, +/* U+2786 */ 0xC6, +/* U+2787 */ 0xC7, +/* U+2788 */ 0xC8, +/* U+2789 */ 0xC9, +/* U+278A */ 0xCA, +/* U+278B */ 0xCB, +/* U+278C */ 0xCC, +/* U+278D */ 0xCD, +/* U+278E */ 0xCE, +/* U+278F */ 0xCF, +/* U+2790 */ 0xD0, +/* U+2791 */ 0xD1, +/* U+2792 */ 0xD2, +/* U+2793 */ 0xD3, +/* U+2794 */ 0xD4, +0x00, +0x00, +0x00, +/* U+2798 */ 0xD8, +/* U+2799 */ 0xD9, +/* U+279A */ 0xDA, +/* U+279B */ 0xDB, +/* U+279C */ 0xDC, +/* U+279D */ 0xDD, +/* U+279E */ 0xDE, +/* U+279F */ 0xDF, +/* U+27A0 */ 0xE0, +/* U+27A1 */ 0xE1, +/* U+27A2 */ 0xE2, +/* U+27A3 */ 0xE3, +/* U+27A4 */ 0xE4, +/* U+27A5 */ 0xE5, +/* U+27A6 */ 0xE6, +/* U+27A7 */ 0xE7, +/* U+27A8 */ 0xE8, +/* U+27A9 */ 0xE9, +/* U+27AA */ 0xEA, +/* U+27AB */ 0xEB, +/* U+27AC */ 0xEC, +/* U+27AD */ 0xED, +/* U+27AE */ 0xEE, +/* U+27AF */ 0xEF, +0x00, +/* U+27B1 */ 0xF1, +/* U+27B2 */ 0xF2, +/* U+27B3 */ 0xF3, +/* U+27B4 */ 0xF4, +/* U+27B5 */ 0xF5, +/* U+27B6 */ 0xF6, +/* U+27B7 */ 0xF7, +/* U+27B8 */ 0xF8, +/* U+27B9 */ 0xF9, +/* U+27BA */ 0xFA, +/* U+27BB */ 0xFB, +/* U+27BC */ 0xFC, +/* U+27BD */ 0xFD, +/* U+27BE */ 0xFE, +}; + +static const char unicode_to_dingbats_1b_F8D7[] = { +/* U+F8D7 */ 0x80, +/* U+F8D8 */ 0x81, +/* U+F8D9 */ 0x82, +/* U+F8DA */ 0x83, +/* U+F8DB */ 0x84, +/* U+F8DC */ 0x85, +/* U+F8DD */ 0x86, +/* U+F8DE */ 0x87, +/* U+F8DF */ 0x88, +/* U+F8E0 */ 0x89, +/* U+F8E1 */ 0x8A, +/* U+F8E2 */ 0x8B, +/* U+F8E3 */ 0x8C, +/* U+F8E4 */ 0x8D, +}; diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/headers/spacing.h b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/headers/spacing.h new file mode 100644 index 0000000..e27f886 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/headers/spacing.h @@ -0,0 +1,1978 @@ +/* spacing */ + +static const unsigned short ucs_table_0300[] = { +/* U+0300 */ 0x0060, +/* U+0301 */ 0x00B4, +/* U+0302 */ 0x005E, +/* U+0303 */ 0x02DC, +/* U+0304 */ 0x00AF, +/* U+0305 */ 0x203E, +/* U+0306 */ 0x02D8, +/* U+0307 */ 0x02D9, +/* U+0308 */ 0x00A8, +/* U+0309 */ 0x0309, +/* U+030A */ 0x02DA, +/* U+030B */ 0x02DD, +/* U+030C */ 0x030C, +/* U+030D */ 0x030D, +/* U+030E */ 0x030E, +/* U+030F */ 0x030F, +/* U+0310 */ 0x0310, +/* U+0311 */ 0x0311, +/* U+0312 */ 0x0312, +/* U+0313 */ 0x1FBD, +/* U+0314 */ 0x1FFE, +/* U+0315 */ 0x0315, +/* U+0316 */ 0x0316, +/* U+0317 */ 0x0317, +/* U+0318 */ 0x0318, +/* U+0319 */ 0x0319, +/* U+031A */ 0x031A, +/* U+031B */ 0x031B, +/* U+031C */ 0x031C, +/* U+031D */ 0x031D, +/* U+031E */ 0x031E, +/* U+031F */ 0x031F, +/* U+0320 */ 0x0320, +/* U+0321 */ 0x0321, +/* U+0322 */ 0x0322, +/* U+0323 */ 0x0323, +/* U+0324 */ 0x0324, +/* U+0325 */ 0x0325, +/* U+0326 */ 0x0326, +/* U+0327 */ 0x00B8, +/* U+0328 */ 0x02DB, +/* U+0329 */ 0x0329, +/* U+032A */ 0x032A, +/* U+032B */ 0x032B, +/* U+032C */ 0x032C, +/* U+032D */ 0x032D, +/* U+032E */ 0x032E, +/* U+032F */ 0x032F, +/* U+0330 */ 0x0330, +/* U+0331 */ 0x0331, +/* U+0332 */ 0x005F, +/* U+0333 */ 0x2017, +/* U+0334 */ 0x0334, +/* U+0335 */ 0x0335, +/* U+0336 */ 0x0336, +/* U+0337 */ 0x0337, +/* U+0338 */ 0x0338, +/* U+0339 */ 0x0339, +/* U+033A */ 0x033A, +/* U+033B */ 0x033B, +/* U+033C */ 0x033C, +/* U+033D */ 0x033D, +/* U+033E */ 0x033E, +/* U+033F */ 0x033F, +/* U+0340 */ 0x0340, +/* U+0341 */ 0x0341, +/* U+0342 */ 0x1FC0, +/* U+0343 */ 0x0343, +/* U+0344 */ 0x0344, +/* U+0345 */ 0x037A, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+0360 */ 0x0360, +/* U+0361 */ 0x0361, +}; + +static const unsigned short ucs_table_0483[] = { +/* U+0483 */ 0x0483, +/* U+0484 */ 0x0484, +/* U+0485 */ 0x0485, +/* U+0486 */ 0x0486, +}; + +static const unsigned short ucs_table_0591[] = { +/* U+0591 */ 0x0591, +/* U+0592 */ 0x0592, +/* U+0593 */ 0x0593, +/* U+0594 */ 0x0594, +/* U+0595 */ 0x0595, +/* U+0596 */ 0x0596, +/* U+0597 */ 0x0597, +/* U+0598 */ 0x0598, +/* U+0599 */ 0x0599, +/* U+059A */ 0x059A, +/* U+059B */ 0x059B, +/* U+059C */ 0x059C, +/* U+059D */ 0x059D, +/* U+059E */ 0x059E, +/* U+059F */ 0x059F, +/* U+05A0 */ 0x05A0, +/* U+05A1 */ 0x05A1, +0x00, +/* U+05A3 */ 0x05A3, +/* U+05A4 */ 0x05A4, +/* U+05A5 */ 0x05A5, +/* U+05A6 */ 0x05A6, +/* U+05A7 */ 0x05A7, +/* U+05A8 */ 0x05A8, +/* U+05A9 */ 0x05A9, +/* U+05AA */ 0x05AA, +/* U+05AB */ 0x05AB, +/* U+05AC */ 0x05AC, +/* U+05AD */ 0x05AD, +/* U+05AE */ 0x05AE, +/* U+05AF */ 0x05AF, +/* U+05B0 */ 0x05B0, +/* U+05B1 */ 0x05B1, +/* U+05B2 */ 0x05B2, +/* U+05B3 */ 0x05B3, +/* U+05B4 */ 0x05B4, +/* U+05B5 */ 0x05B5, +/* U+05B6 */ 0x05B6, +/* U+05B7 */ 0x05B7, +/* U+05B8 */ 0x05B8, +/* U+05B9 */ 0x05B9, +0x00, +/* U+05BB */ 0x05BB, +/* U+05BC */ 0x05BC, +/* U+05BD */ 0x05BD, +0x00, +/* U+05BF */ 0x05BF, +0x00, +/* U+05C1 */ 0x05C1, +/* U+05C2 */ 0x05C2, +0x00, +/* U+05C4 */ 0x05C4, +}; + +static const unsigned short ucs_table_064B[] = { +/* U+064B */ 0xFE70, +/* U+064C */ 0xFE72, +/* U+064D */ 0xFE74, +/* U+064E */ 0xFE76, +/* U+064F */ 0xFE78, +/* U+0650 */ 0xFE7A, +/* U+0651 */ 0xFE7C, +/* U+0652 */ 0xFE7E, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+0670 */ 0x0670, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+06D6 */ 0x06D6, +/* U+06D7 */ 0x06D7, +/* U+06D8 */ 0x06D8, +/* U+06D9 */ 0x06D9, +/* U+06DA */ 0x06DA, +/* U+06DB */ 0x06DB, +/* U+06DC */ 0x06DC, +0x00, +0x00, +/* U+06DF */ 0x06DF, +/* U+06E0 */ 0x06E0, +/* U+06E1 */ 0x06E1, +/* U+06E2 */ 0x06E2, +/* U+06E3 */ 0x06E3, +/* U+06E4 */ 0x06E4, +0x00, +0x00, +/* U+06E7 */ 0x06E7, +/* U+06E8 */ 0x06E8, +0x00, +/* U+06EA */ 0x06EA, +/* U+06EB */ 0x06EB, +/* U+06EC */ 0x06EC, +/* U+06ED */ 0x06ED, +}; + +static const unsigned short ucs_table_0901[] = { +/* U+0901 */ 0x0901, +/* U+0902 */ 0x0902, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+093C */ 0x093C, +0x00, +0x00, +0x00, +0x00, +/* U+0941 */ 0x0941, +/* U+0942 */ 0x0942, +/* U+0943 */ 0x0943, +/* U+0944 */ 0x0944, +/* U+0945 */ 0x0945, +/* U+0946 */ 0x0946, +/* U+0947 */ 0x0947, +/* U+0948 */ 0x0948, +0x00, +0x00, +0x00, +0x00, +/* U+094D */ 0x094D, +0x00, +0x00, +0x00, +/* U+0951 */ 0x0951, +/* U+0952 */ 0x0952, +/* U+0953 */ 0x0953, +/* U+0954 */ 0x0954, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+0962 */ 0x0962, +/* U+0963 */ 0x0963, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+0981 */ 0x0981, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+09BC */ 0x09BC, +0x00, +0x00, +0x00, +0x00, +/* U+09C1 */ 0x09C1, +/* U+09C2 */ 0x09C2, +/* U+09C3 */ 0x09C3, +/* U+09C4 */ 0x09C4, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+09CD */ 0x09CD, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+09E2 */ 0x09E2, +/* U+09E3 */ 0x09E3, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+0A02 */ 0x0A02, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+0A3C */ 0x0A3C, +0x00, +0x00, +0x00, +0x00, +/* U+0A41 */ 0x0A41, +/* U+0A42 */ 0x0A42, +0x00, +0x00, +0x00, +0x00, +/* U+0A47 */ 0x0A47, +/* U+0A48 */ 0x0A48, +0x00, +0x00, +/* U+0A4B */ 0x0A4B, +/* U+0A4C */ 0x0A4C, +/* U+0A4D */ 0x0A4D, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+0A70 */ 0x0A70, +/* U+0A71 */ 0x0A71, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+0A81 */ 0x0A81, +/* U+0A82 */ 0x0A82, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+0ABC */ 0x0ABC, +0x00, +0x00, +0x00, +0x00, +/* U+0AC1 */ 0x0AC1, +/* U+0AC2 */ 0x0AC2, +/* U+0AC3 */ 0x0AC3, +/* U+0AC4 */ 0x0AC4, +/* U+0AC5 */ 0x0AC5, +0x00, +/* U+0AC7 */ 0x0AC7, +/* U+0AC8 */ 0x0AC8, +0x00, +0x00, +0x00, +0x00, +/* U+0ACD */ 0x0ACD, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+0B01 */ 0x0B01, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+0B3C */ 0x0B3C, +0x00, +0x00, +/* U+0B3F */ 0x0B3F, +0x00, +/* U+0B41 */ 0x0B41, +/* U+0B42 */ 0x0B42, +/* U+0B43 */ 0x0B43, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+0B4D */ 0x0B4D, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+0B56 */ 0x0B56, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+0B82 */ 0x0B82, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+0BC0 */ 0x0BC0, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+0BCD */ 0x0BCD, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+0C3E */ 0x0C3E, +/* U+0C3F */ 0x0C3F, +/* U+0C40 */ 0x0C40, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+0C46 */ 0x0C46, +/* U+0C47 */ 0x0C47, +/* U+0C48 */ 0x0C48, +0x00, +/* U+0C4A */ 0x0C4A, +/* U+0C4B */ 0x0C4B, +/* U+0C4C */ 0x0C4C, +/* U+0C4D */ 0x0C4D, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+0C55 */ 0x0C55, +/* U+0C56 */ 0x0C56, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+0CBF */ 0x0CBF, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+0CC6 */ 0x0CC6, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+0CCC */ 0x0CCC, +/* U+0CCD */ 0x0CCD, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+0D41 */ 0x0D41, +/* U+0D42 */ 0x0D42, +/* U+0D43 */ 0x0D43, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+0D4D */ 0x0D4D, +}; + +static const unsigned short ucs_table_0E31[] = { +/* U+0E31 */ 0x0E31, +0x00, +0x00, +/* U+0E34 */ 0x0E34, +/* U+0E35 */ 0x0E35, +/* U+0E36 */ 0x0E36, +/* U+0E37 */ 0x0E37, +/* U+0E38 */ 0x0E38, +/* U+0E39 */ 0x0E39, +/* U+0E3A */ 0x0E3A, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+0E47 */ 0x0E47, +/* U+0E48 */ 0x0E48, +/* U+0E49 */ 0x0E49, +/* U+0E4A */ 0x0E4A, +/* U+0E4B */ 0x0E4B, +/* U+0E4C */ 0x0E4C, +/* U+0E4D */ 0x0E4D, +/* U+0E4E */ 0x0E4E, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+0EB1 */ 0x0EB1, +0x00, +0x00, +/* U+0EB4 */ 0x0EB4, +/* U+0EB5 */ 0x0EB5, +/* U+0EB6 */ 0x0EB6, +/* U+0EB7 */ 0x0EB7, +/* U+0EB8 */ 0x0EB8, +/* U+0EB9 */ 0x0EB9, +0x00, +/* U+0EBB */ 0x0EBB, +/* U+0EBC */ 0x0EBC, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+0EC8 */ 0x0EC8, +/* U+0EC9 */ 0x0EC9, +/* U+0ECA */ 0x0ECA, +/* U+0ECB */ 0x0ECB, +/* U+0ECC */ 0x0ECC, +/* U+0ECD */ 0x0ECD, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+0F18 */ 0x0F18, +/* U+0F19 */ 0x0F19, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+0F35 */ 0x0F35, +0x00, +/* U+0F37 */ 0x0F37, +0x00, +/* U+0F39 */ 0x0F39, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+0F71 */ 0x0F71, +/* U+0F72 */ 0x0F72, +/* U+0F73 */ 0x0F73, +/* U+0F74 */ 0x0F74, +/* U+0F75 */ 0x0F75, +/* U+0F76 */ 0x0F76, +/* U+0F77 */ 0x0F77, +/* U+0F78 */ 0x0F78, +/* U+0F79 */ 0x0F79, +/* U+0F7A */ 0x0F7A, +/* U+0F7B */ 0x0F7B, +/* U+0F7C */ 0x0F7C, +/* U+0F7D */ 0x0F7D, +/* U+0F7E */ 0x0F7E, +0x00, +/* U+0F80 */ 0x0F80, +/* U+0F81 */ 0x0F81, +/* U+0F82 */ 0x0F82, +/* U+0F83 */ 0x0F83, +/* U+0F84 */ 0x0F84, +0x00, +/* U+0F86 */ 0x0F86, +/* U+0F87 */ 0x0F87, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+0F90 */ 0x0F90, +/* U+0F91 */ 0x0F91, +/* U+0F92 */ 0x0F92, +/* U+0F93 */ 0x0F93, +/* U+0F94 */ 0x0F94, +/* U+0F95 */ 0x0F95, +0x00, +/* U+0F97 */ 0x0F97, +0x00, +/* U+0F99 */ 0x0F99, +/* U+0F9A */ 0x0F9A, +/* U+0F9B */ 0x0F9B, +/* U+0F9C */ 0x0F9C, +/* U+0F9D */ 0x0F9D, +/* U+0F9E */ 0x0F9E, +/* U+0F9F */ 0x0F9F, +/* U+0FA0 */ 0x0FA0, +/* U+0FA1 */ 0x0FA1, +/* U+0FA2 */ 0x0FA2, +/* U+0FA3 */ 0x0FA3, +/* U+0FA4 */ 0x0FA4, +/* U+0FA5 */ 0x0FA5, +/* U+0FA6 */ 0x0FA6, +/* U+0FA7 */ 0x0FA7, +/* U+0FA8 */ 0x0FA8, +/* U+0FA9 */ 0x0FA9, +/* U+0FAA */ 0x0FAA, +/* U+0FAB */ 0x0FAB, +/* U+0FAC */ 0x0FAC, +/* U+0FAD */ 0x0FAD, +0x00, +0x00, +0x00, +/* U+0FB1 */ 0x0FB1, +/* U+0FB2 */ 0x0FB2, +/* U+0FB3 */ 0x0FB3, +/* U+0FB4 */ 0x0FB4, +/* U+0FB5 */ 0x0FB5, +/* U+0FB6 */ 0x0FB6, +/* U+0FB7 */ 0x0FB7, +0x00, +/* U+0FB9 */ 0x0FB9, +}; + +static const unsigned short ucs_table_20D0[] = { +/* U+20D0 */ 0x20D0, +/* U+20D1 */ 0x20D1, +/* U+20D2 */ 0x20D2, +/* U+20D3 */ 0x20D3, +/* U+20D4 */ 0x20D4, +/* U+20D5 */ 0x20D5, +/* U+20D6 */ 0x20D6, +/* U+20D7 */ 0x20D7, +/* U+20D8 */ 0x20D8, +/* U+20D9 */ 0x20D9, +/* U+20DA */ 0x20DA, +/* U+20DB */ 0x20DB, +/* U+20DC */ 0x20DC, +0x00, +0x00, +0x00, +0x00, +/* U+20E1 */ 0x20E1, +}; + +static const unsigned short ucs_table_302A[] = { +/* U+302A */ 0x302A, +/* U+302B */ 0x302B, +/* U+302C */ 0x302C, +/* U+302D */ 0x302D, +/* U+302E */ 0x302E, +/* U+302F */ 0x302F, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+3099 */ 0x309B, +/* U+309A */ 0x309C, +}; + +static const unsigned short ucs_table_FB1E[] = { +/* U+FB1E */ 0xFB1E, +}; + +static const unsigned short ucs_table_FE20[] = { +/* U+FE20 */ 0xFE20, +/* U+FE21 */ 0xFE21, +/* U+FE22 */ 0xFE22, +/* U+FE23 */ 0xFE23, +}; diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/headers/spacing_tbl.txt b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/headers/spacing_tbl.txt new file mode 100644 index 0000000..2e3d90c --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/headers/spacing_tbl.txt @@ -0,0 +1,10 @@ +ucs_table_0300[]; /* end: U+0361 */ +ucs_table_0483[]; /* end: U+0486 */ +ucs_table_0591[]; /* end: U+05C4 */ +ucs_table_064B[]; /* end: U+06ED */ +ucs_table_0901[]; /* end: U+0D4D */ +ucs_table_0E31[]; /* end: U+0FB9 */ +ucs_table_20D0[]; /* end: U+20E1 */ +ucs_table_302A[]; /* end: U+309A */ +ucs_table_FB1E[]; /* end: U+FB1E */ +ucs_table_FE20[]; /* end: U+FE23 */ diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/headers/symbol_.h b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/headers/symbol_.h new file mode 100644 index 0000000..a9d8fd3 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/headers/symbol_.h @@ -0,0 +1,1126 @@ +/* symbol */ + +static const char unicode_to_symbol_1b_0020[] = { +/* U+0020 */ 0x20, +/* U+0021 */ 0x21, +0x00, +/* U+0023 */ 0x23, +0x00, +/* U+0025 */ 0x25, +/* U+0026 */ 0x26, +0x00, +/* U+0028 */ 0x28, +/* U+0029 */ 0x29, +0x00, +/* U+002B */ 0x2B, +/* U+002C */ 0x2C, +0x00, +/* U+002E */ 0x2E, +/* U+002F */ 0x2F, +/* U+0030 */ 0x30, +/* U+0031 */ 0x31, +/* U+0032 */ 0x32, +/* U+0033 */ 0x33, +/* U+0034 */ 0x34, +/* U+0035 */ 0x35, +/* U+0036 */ 0x36, +/* U+0037 */ 0x37, +/* U+0038 */ 0x38, +/* U+0039 */ 0x39, +/* U+003A */ 0x3A, +/* U+003B */ 0x3B, +/* U+003C */ 0x3C, +/* U+003D */ 0x3D, +/* U+003E */ 0x3E, +/* U+003F */ 0x3F, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+005B */ 0x5B, +0x00, +/* U+005D */ 0x5D, +0x00, +/* U+005F */ 0x5F, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+007B */ 0x7B, +/* U+007C */ 0x7C, +/* U+007D */ 0x7D, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+00A0 */ 0x20, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+00AC */ 0xD8, +0x00, +0x00, +0x00, +/* U+00B0 */ 0xB0, +/* U+00B1 */ 0xB1, +0x00, +0x00, +0x00, +/* U+00B5 */ 0x6D, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+00D7 */ 0xB4, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+00F7 */ 0xB8, +}; + +static const char unicode_to_symbol_1b_0192[] = { +/* U+0192 */ 0xA6, +}; + +static const char unicode_to_symbol_1b_0391[] = { +/* U+0391 */ 0x41, +/* U+0392 */ 0x42, +/* U+0393 */ 0x47, +/* U+0394 */ 0x44, +/* U+0395 */ 0x45, +/* U+0396 */ 0x5A, +/* U+0397 */ 0x48, +/* U+0398 */ 0x51, +/* U+0399 */ 0x49, +/* U+039A */ 0x4B, +/* U+039B */ 0x4C, +/* U+039C */ 0x4D, +/* U+039D */ 0x4E, +/* U+039E */ 0x58, +/* U+039F */ 0x4F, +/* U+03A0 */ 0x50, +/* U+03A1 */ 0x52, +0x00, +/* U+03A3 */ 0x53, +/* U+03A4 */ 0x54, +/* U+03A5 */ 0x55, +/* U+03A6 */ 0x46, +/* U+03A7 */ 0x43, +/* U+03A8 */ 0x59, +/* U+03A9 */ 0x57, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+03B1 */ 0x61, +/* U+03B2 */ 0x62, +/* U+03B3 */ 0x67, +/* U+03B4 */ 0x64, +/* U+03B5 */ 0x65, +/* U+03B6 */ 0x7A, +/* U+03B7 */ 0x68, +/* U+03B8 */ 0x71, +/* U+03B9 */ 0x69, +/* U+03BA */ 0x6B, +/* U+03BB */ 0x6C, +/* U+03BC */ 0x6D, +/* U+03BD */ 0x6E, +/* U+03BE */ 0x78, +/* U+03BF */ 0x6F, +/* U+03C0 */ 0x70, +/* U+03C1 */ 0x72, +/* U+03C2 */ 0x56, +/* U+03C3 */ 0x73, +/* U+03C4 */ 0x74, +/* U+03C5 */ 0x75, +/* U+03C6 */ 0x66, +/* U+03C7 */ 0x63, +/* U+03C8 */ 0x79, +/* U+03C9 */ 0x77, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+03D1 */ 0x4A, +/* U+03D2 */ 0xA1, +0x00, +0x00, +/* U+03D5 */ 0x6A, +/* U+03D6 */ 0x76, +}; + +static const char unicode_to_symbol_1b_2022[] = { +/* U+2022 */ 0xB7, +0x00, +0x00, +0x00, +/* U+2026 */ 0xBC, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+2032 */ 0xA2, +/* U+2033 */ 0xB2, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+2044 */ 0xA4, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+20AC */ 0xA0, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+2111 */ 0xC1, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+2118 */ 0xC3, +0x00, +0x00, +0x00, +/* U+211C */ 0xC2, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+2126 */ 0x57, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+2135 */ 0xC0, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+2190 */ 0xAC, +/* U+2191 */ 0xAD, +/* U+2192 */ 0xAE, +/* U+2193 */ 0xAF, +/* U+2194 */ 0xAB, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+21B5 */ 0xBF, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+21D0 */ 0xDC, +/* U+21D1 */ 0xDD, +/* U+21D2 */ 0xDE, +/* U+21D3 */ 0xDF, +/* U+21D4 */ 0xDB, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+2200 */ 0x22, +0x00, +/* U+2202 */ 0xB6, +/* U+2203 */ 0x24, +0x00, +/* U+2205 */ 0xC6, +/* U+2206 */ 0x44, +/* U+2207 */ 0xD1, +/* U+2208 */ 0xCE, +/* U+2209 */ 0xCF, +0x00, +/* U+220B */ 0x27, +0x00, +0x00, +0x00, +/* U+220F */ 0xD5, +0x00, +/* U+2211 */ 0xE5, +/* U+2212 */ 0x2D, +0x00, +0x00, +/* U+2215 */ 0xA4, +0x00, +/* U+2217 */ 0x2A, +0x00, +0x00, +/* U+221A */ 0xD6, +0x00, +0x00, +/* U+221D */ 0xB5, +/* U+221E */ 0xA5, +0x00, +/* U+2220 */ 0xD0, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+2227 */ 0xD9, +/* U+2228 */ 0xDA, +/* U+2229 */ 0xC7, +/* U+222A */ 0xC8, +/* U+222B */ 0xF2, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+2234 */ 0x5C, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+223C */ 0x7E, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+2245 */ 0x40, +0x00, +0x00, +/* U+2248 */ 0xBB, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+2260 */ 0xB9, +/* U+2261 */ 0xBA, +0x00, +0x00, +/* U+2264 */ 0xA3, +/* U+2265 */ 0xB3, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+2282 */ 0xCC, +/* U+2283 */ 0xC9, +/* U+2284 */ 0xCB, +0x00, +/* U+2286 */ 0xCD, +/* U+2287 */ 0xCA, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+2295 */ 0xC5, +0x00, +/* U+2297 */ 0xC4, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+22A5 */ 0x5E, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+22C5 */ 0xD7, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+2320 */ 0xF3, +/* U+2321 */ 0xF5, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +/* U+2329 */ 0xE1, +/* U+232A */ 0xF1, +}; + +static const char unicode_to_symbol_1b_25CA[] = { +/* U+25CA */ 0xE0, +}; + +static const char unicode_to_symbol_1b_2660[] = { +/* U+2660 */ 0xAA, +0x00, +0x00, +/* U+2663 */ 0xA7, +0x00, +/* U+2665 */ 0xA9, +/* U+2666 */ 0xA8, +}; + +static const char unicode_to_symbol_1b_F6D9[] = { +/* U+F6D9 */ 0xD3, +/* U+F6DA */ 0xD2, +/* U+F6DB */ 0xD4, +}; + +static const char unicode_to_symbol_1b_F8E5[] = { +/* U+F8E5 */ 0x60, +/* U+F8E6 */ 0xBD, +/* U+F8E7 */ 0xBE, +/* U+F8E8 */ 0xE2, +/* U+F8E9 */ 0xE3, +/* U+F8EA */ 0xE4, +/* U+F8EB */ 0xE6, +/* U+F8EC */ 0xE7, +/* U+F8ED */ 0xE8, +/* U+F8EE */ 0xE9, +/* U+F8EF */ 0xEA, +/* U+F8F0 */ 0xEB, +/* U+F8F1 */ 0xEC, +/* U+F8F2 */ 0xED, +/* U+F8F3 */ 0xEE, +/* U+F8F4 */ 0xEF, +/* U+F8F5 */ 0xF4, +/* U+F8F6 */ 0xF6, +/* U+F8F7 */ 0xF7, +/* U+F8F8 */ 0xF8, +/* U+F8F9 */ 0xF9, +/* U+F8FA */ 0xFA, +/* U+F8FB */ 0xFB, +/* U+F8FC */ 0xFC, +/* U+F8FD */ 0xFD, +/* U+F8FE */ 0xFE, +}; diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/headers/tbl.txt b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/headers/tbl.txt new file mode 100644 index 0000000..ddb2c45 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/headers/tbl.txt @@ -0,0 +1,122 @@ +unicode_to_iso8859_1_1b_0001[]; /* end: U+00FF */ +unicode_to_iso8859_2_1b_0001[]; /* end: U+017E */ +unicode_to_iso8859_2_1b_02C7[]; /* end: U+02DD */ +unicode_to_iso8859_3_1b_0001[]; /* end: U+017C */ +unicode_to_iso8859_3_1b_02D8[]; /* end: U+02D9 */ +unicode_to_iso8859_4_1b_0001[]; /* end: U+017E */ +unicode_to_iso8859_4_1b_02C7[]; /* end: U+02DB */ +unicode_to_iso8859_5_1b_0001[]; /* end: U+00AD */ +unicode_to_iso8859_5_1b_0401[]; /* end: U+045F */ +unicode_to_iso8859_5_1b_2116[]; /* end: U+2116 */ +unicode_to_iso8859_6_1b_0001[]; /* end: U+00AD */ +unicode_to_iso8859_6_1b_060C[]; /* end: U+0652 */ +unicode_to_iso8859_7_1b_0001[]; /* end: U+00BD */ +unicode_to_iso8859_7_1b_0384[]; /* end: U+03CE */ +unicode_to_iso8859_7_1b_2015[]; /* end: U+2019 */ +unicode_to_iso8859_8_1b_0001[]; /* end: U+00F7 */ +unicode_to_iso8859_8_1b_05D0[]; /* end: U+05EA */ +unicode_to_iso8859_8_1b_200E[]; /* end: U+2017 */ +unicode_to_iso8859_9_1b_0001[]; /* end: U+015F */ +unicode_to_iso8859_10_1b_0001[]; /* end: U+017E */ +unicode_to_iso8859_10_1b_2015[]; /* end: U+2015 */ +unicode_to_iso8859_13_1b_0001[]; /* end: U+017E */ +unicode_to_iso8859_13_1b_2019[]; /* end: U+201E */ +unicode_to_iso8859_14_1b_0001[]; /* end: U+0178 */ +unicode_to_iso8859_14_1b_1E02[]; /* end: U+1EF3 */ +unicode_to_iso8859_15_1b_0001[]; /* end: U+017E */ +unicode_to_iso8859_15_1b_20AC[]; /* end: U+20AC */ +unicode_to_koi8_1_1b_0001[]; /* end: U+00F7 */ +unicode_to_koi8_1_1b_0401[]; /* end: U+0451 */ +unicode_to_koi8_1_1b_2219[]; /* end: U+2265 */ +unicode_to_koi8_1_1b_2320[]; /* end: U+2321 */ +unicode_to_koi8_1_1b_2500[]; /* end: U+25A0 */ +unicode_to_big5_0_2b_00A2[]; /* end: U+00F7 */ +unicode_to_big5_0_2b_02C7[]; /* end: U+02D9 */ +unicode_to_big5_0_2b_0391[]; /* end: U+0451 */ +unicode_to_big5_0_2b_2013[]; /* end: U+203E */ +unicode_to_big5_0_2b_2103[]; /* end: U+2199 */ +unicode_to_big5_0_2b_221A[]; /* end: U+22BF */ +unicode_to_big5_0_2b_2460[]; /* end: U+247D */ +unicode_to_big5_0_2b_2500[]; /* end: U+2642 */ +unicode_to_big5_0_2b_3000[]; /* end: U+3129 */ +unicode_to_big5_0_2b_32A3[]; /* end: U+32A3 */ +unicode_to_big5_0_2b_338E[]; /* end: U+33D5 */ +unicode_to_big5_0_2b_4E00[]; /* end: U+7E9C */ +unicode_to_big5_0_2b_7F36[]; /* end: U+8B9F */ +unicode_to_big5_0_2b_8C37[]; /* end: U+9483 */ +unicode_to_big5_0_2b_9577[]; /* end: U+9FA4 */ +unicode_to_big5_0_2b_FA0C[]; /* end: U+FA0D */ +unicode_to_big5_0_2b_FE30[]; /* end: U+FE6B */ +unicode_to_big5_0_2b_FF01[]; /* end: U+FF64 */ +unicode_to_big5_0_2b_FFFD[]; /* end: U+FFFD */ +unicode_to_ksc5601_1987_0_2b_00A1[]; /* end: U+0167 */ +unicode_to_ksc5601_1987_0_2b_02C7[]; /* end: U+02DD */ +unicode_to_ksc5601_1987_0_2b_0391[]; /* end: U+0451 */ +unicode_to_ksc5601_1987_0_2b_2015[]; /* end: U+2312 */ +unicode_to_ksc5601_1987_0_2b_2460[]; /* end: U+266D */ +unicode_to_ksc5601_1987_0_2b_3000[]; /* end: U+327F */ +unicode_to_ksc5601_1987_0_2b_3380[]; /* end: U+33DD */ +unicode_to_ksc5601_1987_0_2b_4E00[]; /* end: U+7E9C */ +unicode_to_ksc5601_1987_0_2b_7F36[]; /* end: U+8B9A */ +unicode_to_ksc5601_1987_0_2b_8C37[]; /* end: U+947F */ +unicode_to_ksc5601_1987_0_2b_9577[]; /* end: U+9C57 */ +unicode_to_ksc5601_1987_0_2b_9CE5[]; /* end: U+9F9C */ +unicode_to_ksc5601_1987_0_2b_AC00[]; /* end: U+D79D */ +unicode_to_ksc5601_1987_0_2b_F900[]; /* end: U+FA0B */ +unicode_to_ksc5601_1987_0_2b_FF01[]; /* end: U+FF5E */ +unicode_to_ksc5601_1987_0_2b_FFE0[]; /* end: U+FFE6 */ +unicode_to_gb2312_1980_0_2b_00A4[]; /* end: U+01DC */ +unicode_to_gb2312_1980_0_2b_02C7[]; /* end: U+02C9 */ +unicode_to_gb2312_1980_0_2b_0391[]; /* end: U+0451 */ +unicode_to_gb2312_1980_0_2b_2015[]; /* end: U+203B */ +unicode_to_gb2312_1980_0_2b_2103[]; /* end: U+2312 */ +unicode_to_gb2312_1980_0_2b_2460[]; /* end: U+2642 */ +unicode_to_gb2312_1980_0_2b_3000[]; /* end: U+3129 */ +unicode_to_gb2312_1980_0_2b_3220[]; /* end: U+3229 */ +unicode_to_gb2312_1980_0_2b_4E00[]; /* end: U+7DAE */ +unicode_to_gb2312_1980_0_2b_7E3B[]; /* end: U+8C98 */ +unicode_to_gb2312_1980_0_2b_8D1D[]; /* end: U+8ECE */ +unicode_to_gb2312_1980_0_2b_8F66[]; /* end: U+91DC */ +unicode_to_gb2312_1980_0_2b_9274[]; /* end: U+99A8 */ +unicode_to_gb2312_1980_0_2b_9A6C[]; /* end: U+9B54 */ +unicode_to_gb2312_1980_0_2b_9C7C[]; /* end: U+9CE2 */ +unicode_to_gb2312_1980_0_2b_9E1F[]; /* end: U+9FA0 */ +unicode_to_gb2312_1980_0_2b_FF01[]; /* end: U+FF5E */ +unicode_to_gb2312_1980_0_2b_FFE0[]; /* end: U+FFE5 */ +unicode_to_jisx0201_1976_0_1b_0020[]; /* end: U+00A5 */ +unicode_to_jisx0201_1976_0_1b_203E[]; /* end: U+203E */ +unicode_to_jisx0201_1976_0_1b_FF61[]; /* end: U+FF9F */ +unicode_to_jisx0208_1983_0_2b_005C[]; /* end: U+00F7 */ +unicode_to_jisx0208_1983_0_2b_0391[]; /* end: U+0451 */ +unicode_to_jisx0208_1983_0_2b_2010[]; /* end: U+203B */ +unicode_to_jisx0208_1983_0_2b_2103[]; /* end: U+2312 */ +unicode_to_jisx0208_1983_0_2b_2500[]; /* end: U+266F */ +unicode_to_jisx0208_1983_0_2b_3000[]; /* end: U+30FE */ +unicode_to_jisx0208_1983_0_2b_4E00[]; /* end: U+7E9C */ +unicode_to_jisx0208_1983_0_2b_7F36[]; /* end: U+8B9A */ +unicode_to_jisx0208_1983_0_2b_8C37[]; /* end: U+9481 */ +unicode_to_jisx0208_1983_0_2b_9577[]; /* end: U+9FA0 */ +unicode_to_jisx0208_1983_0_2b_FF01[]; /* end: U+FF5D */ +unicode_to_jisx0208_1983_0_2b_FFE3[]; /* end: U+FFE5 */ +unicode_to_jisx0212_1990_0_2b_007E[]; /* end: U+01F5 */ +unicode_to_jisx0212_1990_0_2b_02C7[]; /* end: U+02DD */ +unicode_to_jisx0212_1990_0_2b_0384[]; /* end: U+045F */ +unicode_to_jisx0212_1990_0_2b_2116[]; /* end: U+2122 */ +unicode_to_jisx0212_1990_0_2b_4E02[]; /* end: U+7E9E */ +unicode_to_jisx0212_1990_0_2b_7F3B[]; /* end: U+8B9F */ +unicode_to_jisx0212_1990_0_2b_8C38[]; /* end: U+9484 */ +unicode_to_jisx0212_1990_0_2b_9578[]; /* end: U+9FA5 */ +unicode_to_symbol_1b_0020[]; /* end: U+00F7 */ +unicode_to_symbol_1b_0192[]; /* end: U+0192 */ +unicode_to_symbol_1b_0391[]; /* end: U+03D6 */ +unicode_to_symbol_1b_2022[]; /* end: U+232A */ +unicode_to_symbol_1b_25CA[]; /* end: U+25CA */ +unicode_to_symbol_1b_2660[]; /* end: U+2666 */ +unicode_to_symbol_1b_F6D9[]; /* end: U+F6DB */ +unicode_to_symbol_1b_F8E5[]; /* end: U+F8FE */ +unicode_to_dingbats_1b_0020[]; /* end: U+00A0 */ +unicode_to_dingbats_1b_2192[]; /* end: U+2195 */ +unicode_to_dingbats_1b_2460[]; /* end: U+2469 */ +unicode_to_dingbats_1b_25A0[]; /* end: U+2666 */ +unicode_to_dingbats_1b_2701[]; /* end: U+27BE */ +unicode_to_dingbats_1b_F8D7[]; /* end: U+F8E4 */ diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/imKStoUCS.c b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/imKStoUCS.c new file mode 100644 index 0000000..0af9a80 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/imKStoUCS.c @@ -0,0 +1,324 @@ +/* $XFree86: xc/lib/X11/imKStoUCS.c,v 1.5 2003/11/17 22:20:11 dawes Exp $ */ + +#include "Xlibint.h" +#include "Ximint.h" + +static unsigned short const keysym_to_unicode_1a1_1ff[] = { + 0x0104, 0x02d8, 0x0141, 0x0000, 0x013d, 0x015a, 0x0000, /* 0x01a0-0x01a7 */ + 0x0000, 0x0160, 0x015e, 0x0164, 0x0179, 0x0000, 0x017d, 0x017b, /* 0x01a8-0x01af */ + 0x0000, 0x0105, 0x02db, 0x0142, 0x0000, 0x013e, 0x015b, 0x02c7, /* 0x01b0-0x01b7 */ + 0x0000, 0x0161, 0x015f, 0x0165, 0x017a, 0x02dd, 0x017e, 0x017c, /* 0x01b8-0x01bf */ + 0x0154, 0x0000, 0x0000, 0x0102, 0x0000, 0x0139, 0x0106, 0x0000, /* 0x01c0-0x01c7 */ + 0x010c, 0x0000, 0x0118, 0x0000, 0x011a, 0x0000, 0x0000, 0x010e, /* 0x01c8-0x01cf */ + 0x0110, 0x0143, 0x0147, 0x0000, 0x0000, 0x0150, 0x0000, 0x0000, /* 0x01d0-0x01d7 */ + 0x0158, 0x016e, 0x0000, 0x0170, 0x0000, 0x0000, 0x0162, 0x0000, /* 0x01d8-0x01df */ + 0x0155, 0x0000, 0x0000, 0x0103, 0x0000, 0x013a, 0x0107, 0x0000, /* 0x01e0-0x01e7 */ + 0x010d, 0x0000, 0x0119, 0x0000, 0x011b, 0x0000, 0x0000, 0x010f, /* 0x01e8-0x01ef */ + 0x0111, 0x0144, 0x0148, 0x0000, 0x0000, 0x0151, 0x0000, 0x0000, /* 0x01f0-0x01f7 */ + 0x0159, 0x016f, 0x0000, 0x0171, 0x0000, 0x0000, 0x0163, 0x02d9 /* 0x01f8-0x01ff */ +}; + +static unsigned short const keysym_to_unicode_2a1_2fe[] = { + 0x0126, 0x0000, 0x0000, 0x0000, 0x0000, 0x0124, 0x0000, /* 0x02a0-0x02a7 */ + 0x0000, 0x0130, 0x0000, 0x011e, 0x0134, 0x0000, 0x0000, 0x0000, /* 0x02a8-0x02af */ + 0x0000, 0x0127, 0x0000, 0x0000, 0x0000, 0x0000, 0x0125, 0x0000, /* 0x02b0-0x02b7 */ + 0x0000, 0x0131, 0x0000, 0x011f, 0x0135, 0x0000, 0x0000, 0x0000, /* 0x02b8-0x02bf */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x010a, 0x0108, 0x0000, /* 0x02c0-0x02c7 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x02c8-0x02cf */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0120, 0x0000, 0x0000, /* 0x02d0-0x02d7 */ + 0x011c, 0x0000, 0x0000, 0x0000, 0x0000, 0x016c, 0x015c, 0x0000, /* 0x02d8-0x02df */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x010b, 0x0109, 0x0000, /* 0x02e0-0x02e7 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x02e8-0x02ef */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0121, 0x0000, 0x0000, /* 0x02f0-0x02f7 */ + 0x011d, 0x0000, 0x0000, 0x0000, 0x0000, 0x016d, 0x015d /* 0x02f8-0x02ff */ +}; + +static unsigned short const keysym_to_unicode_3a2_3fe[] = { + 0x0138, 0x0156, 0x0000, 0x0128, 0x013b, 0x0000, /* 0x03a0-0x03a7 */ + 0x0000, 0x0000, 0x0112, 0x0122, 0x0166, 0x0000, 0x0000, 0x0000, /* 0x03a8-0x03af */ + 0x0000, 0x0000, 0x0000, 0x0157, 0x0000, 0x0129, 0x013c, 0x0000, /* 0x03b0-0x03b7 */ + 0x0000, 0x0000, 0x0113, 0x0123, 0x0167, 0x014a, 0x0000, 0x014b, /* 0x03b8-0x03bf */ + 0x0100, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x012e, /* 0x03c0-0x03c7 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0116, 0x0000, 0x0000, 0x012a, /* 0x03c8-0x03cf */ + 0x0000, 0x0145, 0x014c, 0x0136, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x03d0-0x03d7 */ + 0x0000, 0x0172, 0x0000, 0x0000, 0x0000, 0x0168, 0x016a, 0x0000, /* 0x03d8-0x03df */ + 0x0101, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x012f, /* 0x03e0-0x03e7 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0117, 0x0000, 0x0000, 0x012b, /* 0x03e8-0x03ef */ + 0x0000, 0x0146, 0x014d, 0x0137, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x03f0-0x03f7 */ + 0x0000, 0x0173, 0x0000, 0x0000, 0x0000, 0x0169, 0x016b /* 0x03f8-0x03ff */ +}; + +static unsigned short const keysym_to_unicode_4a1_4df[] = { + 0x3002, 0x3008, 0x3009, 0x3001, 0x30fb, 0x30f2, 0x30a1, /* 0x04a0-0x04a7 */ + 0x30a3, 0x30a5, 0x30a7, 0x30a9, 0x30e3, 0x30e5, 0x30e7, 0x30c3, /* 0x04a8-0x04af */ + 0x30fc, 0x30a2, 0x30a4, 0x30a6, 0x30a8, 0x30aa, 0x30ab, 0x30ad, /* 0x04b0-0x04b7 */ + 0x30af, 0x30b1, 0x30b3, 0x30b5, 0x30b7, 0x30b9, 0x30bb, 0x30bd, /* 0x04b8-0x04bf */ + 0x30bf, 0x30c1, 0x30c4, 0x30c6, 0x30c8, 0x30ca, 0x30cb, 0x30cc, /* 0x04c0-0x04c7 */ + 0x30cd, 0x30ce, 0x30cf, 0x30d2, 0x30d5, 0x30d8, 0x30db, 0x30de, /* 0x04c8-0x04cf */ + 0x30df, 0x30e0, 0x30e1, 0x30e2, 0x30e4, 0x30e6, 0x30e8, 0x30e9, /* 0x04d0-0x04d7 */ + 0x30ea, 0x30eb, 0x30ec, 0x30ed, 0x30ef, 0x30f3, 0x309b, 0x309c /* 0x04d8-0x04df */ +}; + +static unsigned short const keysym_to_unicode_590_5fe[] = { + 0x06f0, 0x06f1, 0x06f2, 0x06f3, 0x06f4, 0x06f5, 0x06f6, 0x06f7, /* 0x0590-0x0597 */ + 0x06f8, 0x06f9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x0598-0x059f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x066a, 0x0670, 0x0679, /* 0x05a0-0x05a7 */ + + 0x067e, 0x0686, 0x0688, 0x0691, 0x060c, 0x0000, 0x06d4, 0x0000, /* 0x05ac-0x05af */ + 0x0660, 0x0661, 0x0662, 0x0663, 0x0664, 0x0665, 0x0666, 0x0667, /* 0x05b0-0x05b7 */ + 0x0668, 0x0669, 0x0000, 0x061b, 0x0000, 0x0000, 0x0000, 0x061f, /* 0x05b8-0x05bf */ + 0x0000, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, /* 0x05c0-0x05c7 */ + 0x0628, 0x0629, 0x062a, 0x062b, 0x062c, 0x062d, 0x062e, 0x062f, /* 0x05c8-0x05cf */ + 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637, /* 0x05d0-0x05d7 */ + 0x0638, 0x0639, 0x063a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x05d8-0x05df */ + 0x0640, 0x0641, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, /* 0x05e0-0x05e7 */ + 0x0648, 0x0649, 0x064a, 0x064b, 0x064c, 0x064d, 0x064e, 0x064f, /* 0x05e8-0x05ef */ + 0x0650, 0x0651, 0x0652, 0x0653, 0x0654, 0x0655, 0x0698, 0x06a4, /* 0x05f0-0x05f7 */ + 0x06a9, 0x06af, 0x06ba, 0x06be, 0x06cc, 0x06d2, 0x06c1 /* 0x05f8-0x05fe */ +}; + +static unsigned short keysym_to_unicode_680_6ff[] = { + 0x0492, 0x0496, 0x049a, 0x049c, 0x04a2, 0x04ae, 0x04b0, 0x04b2, /* 0x0680-0x0687 */ + 0x04b6, 0x04b8, 0x04ba, 0x0000, 0x04d8, 0x04e2, 0x04e8, 0x04ee, /* 0x0688-0x068f */ + 0x0493, 0x0497, 0x049b, 0x049d, 0x04a3, 0x04af, 0x04b1, 0x04b3, /* 0x0690-0x0697 */ + 0x04b7, 0x04b9, 0x04bb, 0x0000, 0x04d9, 0x04e3, 0x04e9, 0x04ef, /* 0x0698-0x069f */ + 0x0000, 0x0452, 0x0453, 0x0451, 0x0454, 0x0455, 0x0456, 0x0457, /* 0x06a0-0x06a7 */ + 0x0458, 0x0459, 0x045a, 0x045b, 0x045c, 0x0491, 0x045e, 0x045f, /* 0x06a8-0x06af */ + 0x2116, 0x0402, 0x0403, 0x0401, 0x0404, 0x0405, 0x0406, 0x0407, /* 0x06b0-0x06b7 */ + 0x0408, 0x0409, 0x040a, 0x040b, 0x040c, 0x0490, 0x040e, 0x040f, /* 0x06b8-0x06bf */ + 0x044e, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, /* 0x06c0-0x06c7 */ + 0x0445, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, /* 0x06c8-0x06cf */ + 0x043f, 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, /* 0x06d0-0x06d7 */ + 0x044c, 0x044b, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x044a, /* 0x06d8-0x06df */ + 0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, /* 0x06e0-0x06e7 */ + 0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, /* 0x06e8-0x06ef */ + 0x041f, 0x042f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412, /* 0x06f0-0x06f7 */ + 0x042c, 0x042b, 0x0417, 0x0428, 0x042d, 0x0429, 0x0427, 0x042a /* 0x06f8-0x06ff */ +}; + +static unsigned short const keysym_to_unicode_7a1_7f9[] = { + 0x0386, 0x0388, 0x0389, 0x038a, 0x03aa, 0x0000, 0x038c, /* 0x07a0-0x07a7 */ + 0x038e, 0x03ab, 0x0000, 0x038f, 0x0000, 0x0000, 0x0385, 0x2015, /* 0x07a8-0x07af */ + 0x0000, 0x03ac, 0x03ad, 0x03ae, 0x03af, 0x03ca, 0x0390, 0x03cc, /* 0x07b0-0x07b7 */ + 0x03cd, 0x03cb, 0x03b0, 0x03ce, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x07b8-0x07bf */ + 0x0000, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, /* 0x07c0-0x07c7 */ + 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, /* 0x07c8-0x07cf */ + 0x03a0, 0x03a1, 0x03a3, 0x0000, 0x03a4, 0x03a5, 0x03a6, 0x03a7, /* 0x07d0-0x07d7 */ + 0x03a8, 0x03a9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x07d8-0x07df */ + 0x0000, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, /* 0x07e0-0x07e7 */ + 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, /* 0x07e8-0x07ef */ + 0x03c0, 0x03c1, 0x03c3, 0x03c2, 0x03c4, 0x03c5, 0x03c6, 0x03c7, /* 0x07f0-0x07f7 */ + 0x03c8, 0x03c9 /* 0x07f8-0x07ff */ +}; + +static unsigned short const keysym_to_unicode_8a4_8fe[] = { + 0x2320, 0x2321, 0x0000, 0x231c, /* 0x08a0-0x08a7 */ + 0x231d, 0x231e, 0x231f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x08a8-0x08af */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x08b0-0x08b7 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x2264, 0x2260, 0x2265, 0x222b, /* 0x08b8-0x08bf */ + 0x2234, 0x0000, 0x221e, 0x0000, 0x0000, 0x2207, 0x0000, 0x0000, /* 0x08c0-0x08c7 */ + 0x2245, 0x2246, 0x0000, 0x0000, 0x0000, 0x0000, 0x22a2, 0x0000, /* 0x08c8-0x08cf */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x221a, 0x0000, /* 0x08d0-0x08d7 */ + 0x0000, 0x0000, 0x2282, 0x2283, 0x2229, 0x222a, 0x2227, 0x2228, /* 0x08d8-0x08df */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x08e0-0x08e7 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x08e8-0x08ef */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0192, 0x0000, /* 0x08f0-0x08f7 */ + 0x0000, 0x0000, 0x0000, 0x2190, 0x2191, 0x2192, 0x2193 /* 0x08f8-0x08ff */ +}; + +static unsigned short const keysym_to_unicode_9df_9f8[] = { + 0x2422, /* 0x09d8-0x09df */ + 0x2666, 0x25a6, 0x2409, 0x240c, 0x240d, 0x240a, 0x0000, 0x0000, /* 0x09e0-0x09e7 */ + 0x240a, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c, 0x2500, /* 0x09e8-0x09ef */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x251c, 0x2524, 0x2534, 0x252c, /* 0x09f0-0x09f7 */ + 0x2502 /* 0x09f8-0x09ff */ +}; + +static unsigned short const keysym_to_unicode_aa1_afe[] = { + 0x2003, 0x2002, 0x2004, 0x2005, 0x2007, 0x2008, 0x2009, /* 0x0aa0-0x0aa7 */ + 0x200a, 0x2014, 0x2013, 0x0000, 0x0000, 0x0000, 0x2026, 0x2025, /* 0x0aa8-0x0aaf */ + 0x2153, 0x2154, 0x2155, 0x2156, 0x2157, 0x2158, 0x2159, 0x215a, /* 0x0ab0-0x0ab7 */ + 0x2105, 0x0000, 0x0000, 0x2012, 0x2039, 0x2024, 0x203a, 0x0000, /* 0x0ab8-0x0abf */ + 0x0000, 0x0000, 0x0000, 0x215b, 0x215c, 0x215d, 0x215e, 0x0000, /* 0x0ac0-0x0ac7 */ + 0x0000, 0x2122, 0x2120, 0x0000, 0x25c1, 0x25b7, 0x25cb, 0x25ad, /* 0x0ac8-0x0acf */ + 0x2018, 0x2019, 0x201c, 0x201d, 0x211e, 0x0000, 0x2032, 0x2033, /* 0x0ad0-0x0ad7 */ + 0x0000, 0x271d, 0x0000, 0x220e, 0x25c2, 0x2023, 0x25cf, 0x25ac, /* 0x0ad8-0x0adf */ + 0x25e6, 0x25ab, 0x25ae, 0x25b5, 0x25bf, 0x2606, 0x2022, 0x25aa, /* 0x0ae0-0x0ae7 */ + 0x25b4, 0x25be, 0x261a, 0x261b, 0x2663, 0x2666, 0x2665, 0x0000, /* 0x0ae8-0x0aef */ + 0x2720, 0x2020, 0x2021, 0x2713, 0x2612, 0x266f, 0x266d, 0x2642, /* 0x0af0-0x0af7 */ + 0x2640, 0x2121, 0x2315, 0x2117, 0x2038, 0x201a, 0x201e /* 0x0af8-0x0aff */ +}; + +/* none of the APL keysyms match the Unicode characters */ + +static unsigned short const keysym_to_unicode_cdf_cfa[] = { + 0x2017, /* 0x0cd8-0x0cdf */ + 0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, 0x05d6, 0x05d7, /* 0x0ce0-0x0ce7 */ + 0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05dd, 0x05de, 0x05df, /* 0x0ce8-0x0cef */ + 0x05e0, 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5, 0x05e6, 0x05e7, /* 0x0cf0-0x0cf7 */ + 0x05e8, 0x05e9, 0x05ea /* 0x0cf8-0x0cff */ +}; + +static unsigned short const keysym_to_unicode_da1_df9[] = { + 0x0e01, 0x0e02, 0x0e03, 0x0e04, 0x0e05, 0x0e06, 0x0e07, /* 0x0da0-0x0da7 */ + 0x0e08, 0x0e09, 0x0e0a, 0x0e0b, 0x0e0c, 0x0e0d, 0x0e0e, 0x0e0f, /* 0x0da8-0x0daf */ + 0x0e10, 0x0e11, 0x0e12, 0x0e13, 0x0e14, 0x0e15, 0x0e16, 0x0e17, /* 0x0db0-0x0db7 */ + 0x0e18, 0x0e19, 0x0e1a, 0x0e1b, 0x0e1c, 0x0e1d, 0x0e1e, 0x0e1f, /* 0x0db8-0x0dbf */ + 0x0e20, 0x0e21, 0x0e22, 0x0e23, 0x0e24, 0x0e25, 0x0e26, 0x0e27, /* 0x0dc0-0x0dc7 */ + 0x0e28, 0x0e29, 0x0e2a, 0x0e2b, 0x0e2c, 0x0e2d, 0x0e2e, 0x0e2f, /* 0x0dc8-0x0dcf */ + 0x0e30, 0x0e31, 0x0e32, 0x0e33, 0x0e34, 0x0e35, 0x0e36, 0x0e37, /* 0x0dd0-0x0dd7 */ + 0x0e38, 0x0e39, 0x0e3a, 0x0000, 0x0000, 0x0000, 0x0e3e, 0x0e3f, /* 0x0dd8-0x0ddf */ + 0x0e40, 0x0e41, 0x0e42, 0x0e43, 0x0e44, 0x0e45, 0x0e46, 0x0e47, /* 0x0de0-0x0de7 */ + 0x0e48, 0x0e49, 0x0e4a, 0x0e4b, 0x0e4c, 0x0e4d, 0x0000, 0x0000, /* 0x0de8-0x0def */ + 0x0e50, 0x0e51, 0x0e52, 0x0e53, 0x0e54, 0x0e55, 0x0e56, 0x0e57, /* 0x0df0-0x0df7 */ + 0x0e58, 0x0e59 /* 0x0df8-0x0dff */ +}; + +static unsigned short const keysym_to_unicode_ea0_eff[] = { + 0x0000, 0x1101, 0x1101, 0x11aa, 0x1102, 0x11ac, 0x11ad, 0x1103, /* 0x0ea0-0x0ea7 */ + 0x1104, 0x1105, 0x11b0, 0x11b1, 0x11b2, 0x11b3, 0x11b4, 0x11b5, /* 0x0ea8-0x0eaf */ + 0x11b6, 0x1106, 0x1107, 0x1108, 0x11b9, 0x1109, 0x110a, 0x110b, /* 0x0eb0-0x0eb7 */ + 0x110c, 0x110d, 0x110e, 0x110f, 0x1110, 0x1111, 0x1112, 0x1161, /* 0x0eb8-0x0ebf */ + 0x1162, 0x1163, 0x1164, 0x1165, 0x1166, 0x1167, 0x1168, 0x1169, /* 0x0ec0-0x0ec7 */ + 0x116a, 0x116b, 0x116c, 0x116d, 0x116e, 0x116f, 0x1170, 0x1171, /* 0x0ec8-0x0ecf */ + 0x1172, 0x1173, 0x1174, 0x1175, 0x11a8, 0x11a9, 0x11aa, 0x11ab, /* 0x0ed0-0x0ed7 */ + 0x11ac, 0x11ad, 0x11ae, 0x11af, 0x11b0, 0x11b1, 0x11b2, 0x11b3, /* 0x0ed8-0x0edf */ + 0x11b4, 0x11b5, 0x11b6, 0x11b7, 0x11b8, 0x11b9, 0x11ba, 0x11bb, /* 0x0ee0-0x0ee7 */ + 0x11bc, 0x11bd, 0x11be, 0x11bf, 0x11c0, 0x11c1, 0x11c2, 0x0000, /* 0x0ee8-0x0eef */ + 0x0000, 0x0000, 0x1140, 0x0000, 0x0000, 0x1159, 0x119e, 0x0000, /* 0x0ef0-0x0ef7 */ + 0x11eb, 0x0000, 0x11f9, 0x0000, 0x0000, 0x0000, 0x0000, 0x20a9, /* 0x0ef8-0x0eff */ +}; + +static unsigned short keysym_to_unicode_12a1_12fe[] = { + 0x1e02, 0x1e03, 0x0000, 0x0000, 0x0000, 0x1e0a, 0x0000, /* 0x12a0-0x12a7 */ + 0x1e80, 0x0000, 0x1e82, 0x1e0b, 0x1ef2, 0x0000, 0x0000, 0x0000, /* 0x12a8-0x12af */ + 0x1e1e, 0x1e1f, 0x0000, 0x0000, 0x1e40, 0x1e41, 0x0000, 0x1e56, /* 0x12b0-0x12b7 */ + 0x1e81, 0x1e57, 0x1e83, 0x1e60, 0x1ef3, 0x1e84, 0x1e85, 0x1e61, /* 0x12b8-0x12bf */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x12c0-0x12c7 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x12c8-0x12cf */ + 0x0174, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1e6a, /* 0x12d0-0x12d7 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0176, 0x0000, /* 0x12d8-0x12df */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x12e0-0x12e7 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x12e8-0x12ef */ + 0x0175, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1e6b, /* 0x12f0-0x12f7 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0177 /* 0x12f0-0x12ff */ +}; + +static unsigned short const keysym_to_unicode_13bc_13be[] = { + 0x0152, 0x0153, 0x0178 /* 0x13b8-0x13bf */ +}; + +static unsigned short keysym_to_unicode_14a1_14ff[] = { + 0x2741, 0x00a7, 0x0589, 0x0029, 0x0028, 0x00bb, 0x00ab, /* 0x14a0-0x14a7 */ + 0x2014, 0x002e, 0x055d, 0x002c, 0x2013, 0x058a, 0x2026, 0x055c, /* 0x14a8-0x14af */ + 0x055b, 0x055e, 0x0531, 0x0561, 0x0532, 0x0562, 0x0533, 0x0563, /* 0x14b0-0x14b7 */ + 0x0534, 0x0564, 0x0535, 0x0565, 0x0536, 0x0566, 0x0537, 0x0567, /* 0x14b8-0x14bf */ + 0x0538, 0x0568, 0x0539, 0x0569, 0x053a, 0x056a, 0x053b, 0x056b, /* 0x14c0-0x14c7 */ + 0x053c, 0x056c, 0x053d, 0x056d, 0x053e, 0x056e, 0x053f, 0x056f, /* 0x14c8-0x14cf */ + 0x0540, 0x0570, 0x0541, 0x0571, 0x0542, 0x0572, 0x0543, 0x0573, /* 0x14d0-0x14d7 */ + 0x0544, 0x0574, 0x0545, 0x0575, 0x0546, 0x0576, 0x0547, 0x0577, /* 0x14d8-0x14df */ + 0x0548, 0x0578, 0x0549, 0x0579, 0x054a, 0x057a, 0x054b, 0x057b, /* 0x14e0-0x14e7 */ + 0x054c, 0x057c, 0x054d, 0x057d, 0x054e, 0x057e, 0x054f, 0x057f, /* 0x14e8-0x14ef */ + 0x0550, 0x0580, 0x0551, 0x0581, 0x0552, 0x0582, 0x0553, 0x0583, /* 0x14f0-0x14f7 */ + 0x0554, 0x0584, 0x0555, 0x0585, 0x0556, 0x0586, 0x2019, 0x0027, /* 0x14f8-0x14ff */ +}; + +static unsigned short keysym_to_unicode_15d0_15f6[] = { + 0x10d0, 0x10d1, 0x10d2, 0x10d3, 0x10d4, 0x10d5, 0x10d6, 0x10d7, /* 0x15d0-0x15d7 */ + 0x10d8, 0x10d9, 0x10da, 0x10db, 0x10dc, 0x10dd, 0x10de, 0x10df, /* 0x15d8-0x15df */ + 0x10e0, 0x10e1, 0x10e2, 0x10e3, 0x10e4, 0x10e5, 0x10e6, 0x10e7, /* 0x15e0-0x15e7 */ + 0x10e8, 0x10e9, 0x10ea, 0x10eb, 0x10ec, 0x10ed, 0x10ee, 0x10ef, /* 0x15e8-0x15ef */ + 0x10f0, 0x10f1, 0x10f2, 0x10f3, 0x10f4, 0x10f5, 0x10f6 /* 0x15f0-0x15f7 */ +}; + +static unsigned short keysym_to_unicode_16a0_16f6[] = { + 0x0000, 0x0000, 0xf0a2, 0x1e8a, 0x0000, 0xf0a5, 0x012c, 0xf0a7, /* 0x16a0-0x16a7 */ + 0xf0a8, 0x01b5, 0x01e6, 0x0000, 0x0000, 0x0000, 0x0000, 0x019f, /* 0x16a8-0x16af */ + 0x0000, 0x0000, 0xf0b2, 0x1e8b, 0x01d1, 0xf0b5, 0x012d, 0xf0b7, /* 0x16b0-0x16b7 */ + 0xf0b8, 0x01b6, 0x01e7, 0x0000, 0x0000, 0x01d2, 0x0000, 0x0275, /* 0x16b8-0x16bf */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x018f, 0x0000, /* 0x16c0-0x16c7 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x16c8-0x16cf */ + 0x0000, 0x1e36, 0xf0d2, 0xf0d3, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x16d0-0x16d7 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x16d8-0x16df */ + 0x0000, 0x1e37, 0xf0e2, 0xf0e3, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x16e0-0x16e7 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x16e8-0x16ef */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0259 /* 0x16f0-0x16f6 */ +}; + +static unsigned short const keysym_to_unicode_1e9f_1eff[] = { + 0x0303, + 0x1ea0, 0x1ea1, 0x1ea2, 0x1ea3, 0x1ea4, 0x1ea5, 0x1ea6, 0x1ea7, /* 0x1ea0-0x1ea7 */ + 0x1ea8, 0x1ea9, 0x1eaa, 0x1eab, 0x1eac, 0x1ead, 0x1eae, 0x1eaf, /* 0x1ea8-0x1eaf */ + 0x1eb0, 0x1eb1, 0x1eb2, 0x1eb3, 0x1eb4, 0x1eb5, 0x1eb6, 0x1eb7, /* 0x1eb0-0x1eb7 */ + 0x1eb8, 0x1eb9, 0x1eba, 0x1ebb, 0x1ebc, 0x1ebd, 0x1ebe, 0x1ebf, /* 0x1eb8-0x1ebf */ + 0x1ec0, 0x1ec1, 0x1ec2, 0x1ec3, 0x1ec4, 0x1ec5, 0x1ec6, 0x1ec7, /* 0x1ec0-0x1ec7 */ + 0x1ec8, 0x1ec9, 0x1eca, 0x1ecb, 0x1ecc, 0x1ecd, 0x1ece, 0x1ecf, /* 0x1ec8-0x1ecf */ + 0x1ed0, 0x1ed1, 0x1ed2, 0x1ed3, 0x1ed4, 0x1ed5, 0x1ed6, 0x1ed7, /* 0x1ed0-0x1ed7 */ + 0x1ed8, 0x1ed9, 0x1eda, 0x1edb, 0x1edc, 0x1edd, 0x1ede, 0x1edf, /* 0x1ed8-0x1edf */ + 0x1ee0, 0x1ee1, 0x1ee2, 0x1ee3, 0x1ee4, 0x1ee5, 0x1ee6, 0x1ee7, /* 0x1ee0-0x1ee7 */ + 0x1ee8, 0x1ee9, 0x1eea, 0x1eeb, 0x1eec, 0x1eed, 0x1eee, 0x1eef, /* 0x1ee8-0x1eef */ + 0x1ef0, 0x1ef1, 0x0300, 0x0301, 0x1ef4, 0x1ef5, 0x1ef6, 0x1ef7, /* 0x1ef0-0x1ef7 */ + 0x1ef8, 0x1ef9, 0x01a0, 0x01a1, 0x01af, 0x01b0, 0x0309, 0x0323 /* 0x1ef8-0x1eff */ +}; + +static unsigned short const keysym_to_unicode_20a0_20ac[] = { + 0x20a0, 0x20a1, 0x20a2, 0x20a3, 0x20a4, 0x20a5, 0x20a6, 0x20a7, /* 0x20a0-0x20a7 */ + 0x20a8, 0x20a9, 0x20aa, 0x20ab, 0x20ac /* 0x20a8-0x20af */ +}; + +unsigned int +KeySymToUcs4(KeySym keysym) +{ + /* 'Unicode keysym' */ + if ((keysym & 0xff000000) == 0x01000000) + return (keysym & 0x00ffffff); + + if (keysym > 0 && keysym < 0x100) + return keysym; + else if (keysym > 0x1a0 && keysym < 0x200) + return keysym_to_unicode_1a1_1ff[keysym - 0x1a1]; + else if (keysym > 0x2a0 && keysym < 0x2ff) + return keysym_to_unicode_2a1_2fe[keysym - 0x2a1]; + else if (keysym > 0x3a1 && keysym < 0x3ff) + return keysym_to_unicode_3a2_3fe[keysym - 0x3a2]; + else if (keysym > 0x4a0 && keysym < 0x4e0) + return keysym_to_unicode_4a1_4df[keysym - 0x4a1]; + else if (keysym > 0x589 && keysym < 0x5ff) + return keysym_to_unicode_590_5fe[keysym - 0x590]; + else if (keysym > 0x67f && keysym < 0x700) + return keysym_to_unicode_680_6ff[keysym - 0x680]; + else if (keysym > 0x7a0 && keysym < 0x7fa) + return keysym_to_unicode_7a1_7f9[keysym - 0x7a1]; + else if (keysym > 0x8a3 && keysym < 0x8ff) + return keysym_to_unicode_8a4_8fe[keysym - 0x8a4]; + else if (keysym > 0x9de && keysym < 0x9f9) + return keysym_to_unicode_9df_9f8[keysym - 0x9df]; + else if (keysym > 0xaa0 && keysym < 0xaff) + return keysym_to_unicode_aa1_afe[keysym - 0xaa1]; + else if (keysym > 0xcde && keysym < 0xcfb) + return keysym_to_unicode_cdf_cfa[keysym - 0xcdf]; + else if (keysym > 0xda0 && keysym < 0xdfa) + return keysym_to_unicode_da1_df9[keysym - 0xda1]; + else if (keysym > 0xe9f && keysym < 0xf00) + return keysym_to_unicode_ea0_eff[keysym - 0xea0]; + else if (keysym > 0x12a0 && keysym < 0x12ff) + return keysym_to_unicode_12a1_12fe[keysym - 0x12a1]; + else if (keysym > 0x13bb && keysym < 0x13bf) + return keysym_to_unicode_13bc_13be[keysym - 0x13bc]; + else if (keysym > 0x14a0 && keysym < 0x1500) + return keysym_to_unicode_14a1_14ff[keysym - 0x14a1]; + else if (keysym > 0x15cf && keysym < 0x15f7) + return keysym_to_unicode_15d0_15f6[keysym - 0x15d0]; + else if (keysym > 0x169f && keysym < 0x16f7) + return keysym_to_unicode_16a0_16f6[keysym - 0x16a0]; + else if (keysym > 0x1e9e && keysym < 0x1f00) + return keysym_to_unicode_1e9f_1eff[keysym - 0x1e9f]; + else if (keysym > 0x209f && keysym < 0x20ad) + return keysym_to_unicode_20a0_20ac[keysym - 0x20a0]; + else + return 0; +} + +/* + * End of "$Id$". + */ diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/is_right2left.c b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/is_right2left.c new file mode 100644 index 0000000..d823452 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/is_right2left.c @@ -0,0 +1,84 @@ +/* "$Id: $" + * + * Author: Jean-Marc Lienher ( http://oksid.ch ) + * Copyright 2000-2010 by O'ksi'D. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems on the following page: + * + * http://www.fltk.org/str.php + */ + +/* + * This file is required on all platforms for utf8 support + */ + +unsigned short +XUtf8IsRightToLeft(unsigned int ucs) { + +#if 0 + /* for debug only */ + if (ucs <= 0x005A) { + if (ucs >= 0x0041) return 1; + return 0; + } +#endif + + /* HEBREW */ + if (ucs <= 0x05F4) { + if (ucs >= 0x0591) return 1; + return 0; + } + + /* ARABIC */ + if (ucs <= 0x06ED) { + if (ucs >= 0x060C) return 1; + return 0; + } + + if (ucs <= 0x06F9) { + if (ucs >= 0x06F0) return 1; + return 0; + } + + if (ucs == 0x200F) return 1; + + if (ucs == 0x202B) return 1; + + if (ucs == 0x202E) return 1; + + if (ucs <= 0xFB4F) { + if (ucs >= 0xFB1E) return 1; + return 0; + } + + if (ucs <= 0xFDFB) { + if (ucs >= 0xFB50) return 1; + return 0; + } + + if (ucs <= 0xFEFC) { + if (ucs >= 0xFE70) return 1; + return 0; + } + + return 0; +} + +/* + * End of "$Id$". + */ diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/is_spacing.c b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/is_spacing.c new file mode 100644 index 0000000..2035ff7 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/is_spacing.c @@ -0,0 +1,90 @@ +/* "$Id: $" + * + * Author: Jean-Marc Lienher ( http://oksid.ch ) + * Copyright 2000-2010 by O'ksi'D. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems on the following page: + * + * http://www.fltk.org/str.php + */ + +/* + * This file is required on all platforms for utf8 support + */ + +#include "headers/spacing.h" + +unsigned short +XUtf8IsNonSpacing(unsigned int ucs) { + + if (ucs <= 0x0361) { + if (ucs >= 0x0300) return ucs_table_0300[ucs - 0x0300]; + return 0; + } + + if (ucs <= 0x0486) { + if (ucs >= 0x0483) return ucs_table_0483[ucs - 0x0483]; + return 0; + } + + if (ucs <= 0x05C4) { + if (ucs >= 0x0591) return ucs_table_0591[ucs - 0x0591]; + return 0; + } + + if (ucs <= 0x06ED) { + if (ucs >= 0x064B) return ucs_table_064B[ucs - 0x064B]; + return 0; + } + + if (ucs <= 0x0D4D) { + if (ucs >= 0x0901) return ucs_table_0901[ucs - 0x0901]; + return 0; + } + + if (ucs <= 0x0FB9) { + if (ucs >= 0x0E31) return ucs_table_0E31[ucs - 0x0E31]; + return 0; + } + + if (ucs <= 0x20E1) { + if (ucs >= 0x20D0) return ucs_table_20D0[ucs - 0x20D0]; + return 0; + } + + if (ucs <= 0x309A) { + if (ucs >= 0x302A) return ucs_table_302A[ucs - 0x302A]; + return 0; + } + + if (ucs <= 0xFB1E) { + if (ucs >= 0xFB1E) return ucs_table_FB1E[ucs - 0xFB1E]; + return 0; + } + + if (ucs <= 0xFE23) { + if (ucs >= 0xFE20) return ucs_table_FE20[ucs - 0xFE20]; + return 0; + } + + return 0; +} + +/* + * End of "$Id$". + */ diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/keysym2Ucs.c b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/keysym2Ucs.c new file mode 100644 index 0000000..5bf23d1 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/keysym2Ucs.c @@ -0,0 +1,41 @@ +/* "$Id: $" + * + * Author: Jean-Marc Lienher ( http://oksid.ch ) + * Copyright 2000-2003 by O'ksi'D. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems on the following page: + * + * http://www.fltk.org/str.php + */ + +#define KEYSYM2UCS_INCLUDED + +#if !defined(WIN32) && !defined(__APPLE__) + +#include "../../FL/Xutf8.h" +#include "imKStoUCS.c" + +long XKeysymToUcs(KeySym keysym) { + return (long) KeySymToUcs4(keysym); +} + +#endif /* X11 only */ + +/* + * End of "$Id$". + */ diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/8bit_tab_to_h.c b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/8bit_tab_to_h.c new file mode 100644 index 0000000..1d79484 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/8bit_tab_to_h.c @@ -0,0 +1,536 @@ +/* $XFree86: xc/lib/X11/lcUniConv/8bit_tab_to_h.c,v 1.3 2001/02/09 00:02:54 dawes Exp $ */ + +/* + * Generates an 8-bit character set table from a .TXT table as found on + * ftp.unicode.org or from a table containing the 256 Unicode values as + * hexadecimal integers. + * Examples: + * + * ./8bit_tab_to_h ISO-8859-1 iso8859_1 < tab8859_1 + * ./8bit_tab_to_h ISO-8859-2 iso8859_2 < tab8859_2 + * ./8bit_tab_to_h ISO-8859-3 iso8859_3 < tab8859_3 + * ./8bit_tab_to_h ISO-8859-4 iso8859_4 < tab8859_4 + * ./8bit_tab_to_h ISO-8859-5 iso8859_5 < tab8859_5 + * ./8bit_tab_to_h ISO-8859-6 iso8859_6 < tab8859_6 + * ./8bit_tab_to_h ISO-8859-7 iso8859_7 < tab8859_7 + * ./8bit_tab_to_h ISO-8859-8 iso8859_8 < tab8859_8 + * ./8bit_tab_to_h ISO-8859-9 iso8859_9 < tab8859_9 + * ./8bit_tab_to_h ISO-8859-10 iso8859_10 < tab8859_10 + * ./8bit_tab_to_h ISO-8859-14 iso8859_14 < tab8859_14 + * ./8bit_tab_to_h ISO-8859-15 iso8859_15 < tab8859_15 + * ./8bit_tab_to_h JISX0201.1976-0 jisx0201 < jis0201 + * ./8bit_tab_to_h TIS620-0 tis620 < tabtis620 + * ./8bit_tab_to_h KOI8-R koi8_r < tabkoi8_r + * ./8bit_tab_to_h KOI8-U koi8_u < tabkoi8_u + * ./8bit_tab_to_h ARMSCII-8 armscii_8 < tabarmscii_8 + * ./8bit_tab_to_h CP1133 cp1133 < tabibm_cp1133 + * ./8bit_tab_to_h MULELAO-1 mulelao < tabmulelao_1 + * ./8bit_tab_to_h VISCII1.1-1 viscii1 < tabviscii + * ./8bit_tab_to_h TCVN-5712 tcvn < tabtcvn + * ./8bit_tab_to_h GEORGIAN-ACADEMY georgian_ac < tabgeorgian_academy + * ./8bit_tab_to_h GEORGIAN-PS georgian_ps < tabgeorgian_ps + * + * ./8bit_tab_to_h ISO-8859-1 iso8859_1 < 8859-1.TXT + * ./8bit_tab_to_h ISO-8859-2 iso8859_2 < 8859-2.TXT + * ./8bit_tab_to_h ISO-8859-3 iso8859_3 < 8859-3.TXT + * ./8bit_tab_to_h ISO-8859-4 iso8859_4 < 8859-4.TXT + * ./8bit_tab_to_h ISO-8859-5 iso8859_5 < 8859-5.TXT + * ./8bit_tab_to_h ISO-8859-6 iso8859_6 < 8859-6.TXT + * ./8bit_tab_to_h ISO-8859-7 iso8859_7 < 8859-7.TXT + * ./8bit_tab_to_h ISO-8859-8 iso8859_8 < 8859-8.TXT + * ./8bit_tab_to_h ISO-8859-9 iso8859_9 < 8859-9.TXT + * ./8bit_tab_to_h ISO-8859-10 iso8859_10 < 8859-10.TXT + * ./8bit_tab_to_h ISO-8859-14 iso8859_14 < 8859-14.TXT + * ./8bit_tab_to_h ISO-8859-15 iso8859_15 < 8859-15.TXT + * ./8bit_tab_to_h JISX0201.1976-0 jisx0201 < JIS0201.TXT + * ./8bit_tab_to_h KOI8-R koi8_r < KOI8-R.TXT + */ + +#include +#include +#include +#include + +int main (int argc, char *argv[]) +{ + const char* charsetname; + const char* c_charsetname; + const char* filename; + const char* directory; + int charset2uni[0x100]; + + if (argc != 3 && argc != 4 && argc != 5) + exit(1); + charsetname = argv[1]; + c_charsetname = argv[2]; + if (argc > 3) { + filename = argv[3]; + } else { + char* s = (char*) malloc(strlen(c_charsetname)+strlen(".h")+1); + strcpy(s,c_charsetname); strcat(s,".h"); + filename = s; + } + directory = (argc > 4 ? argv[4] : ""); + + fprintf(stderr, "Creating %s%s\n", directory, filename); + + { + int i, c; + c = getc(stdin); + ungetc(c,stdin); + if (c == '#') { + /* Read a unicode.org style .TXT file. */ + for (i = 0; i < 0x100; i++) + charset2uni[i] = 0xfffd; + for (;;) { + c = getc(stdin); + if (c == EOF) + break; + if (c == '\n' || c == ' ' || c == '\t') + continue; + if (c == '#') { + do { c = getc(stdin); } while (!(c == EOF || c == '\n')); + continue; + } + ungetc(c,stdin); + if (scanf("0x%x", &i) != 1 || !(i >= 0 && i < 0x100)) + exit(1); + do { c = getc(stdin); } while (c == ' ' || c == '\t'); + if (c != EOF) + ungetc(c,stdin); + if (c == '\n' || c == '#') + continue; + if (scanf("0x%x", &charset2uni[i]) != 1) + exit(1); + } + } else { + /* Read a table of hexadecimal Unicode values. */ + for (i = 0; i < 0x100; i++) { + if (scanf("%x", &charset2uni[i]) != 1) + exit(1); + if (charset2uni[i] < 0 || charset2uni[i] == 0xffff) + charset2uni[i] = 0xfffd; + } + if (scanf("%x", &i) != EOF) + exit(1); + } + } + + /* Write the output file. */ + { + FILE* f; + + { + char* fname = malloc(strlen(directory)+strlen(filename)+1); + strcpy(fname,directory); strcat(fname,filename); + f = fopen(fname,"w"); + if (f == NULL) + exit(1); + } + + fprintf(f, "\n"); + fprintf(f, "/*\n"); + fprintf(f, " * %s\n", charsetname); + fprintf(f, " */\n"); + fprintf(f, "\n"); + + { + int i, i1, i2, i3; + int line[16]; + int tableno; + struct { int minline; int maxline; } tables[16]; + bool some_invalid; + bool final_ret_reached; + + for (i1 = 0; i1 < 16; i1++) { + bool all_invalid = true; + bool all_identity = true; + for (i2 = 0; i2 < 16; i2++) { + i = 16*i1+i2; + if (charset2uni[i] != 0xfffd) + all_invalid = false; + if (charset2uni[i] != i) + all_identity = false; + } + if (all_invalid) + line[i1] = -2; + else if (all_identity) + line[i1] = -1; + else + line[i1] = 0; + } + tableno = 0; + for (i1 = 0; i1 < 16; i1++) { + if (line[i1] >= 0) { + if (i1 > 0 && tableno > 0 && line[i1-1] == tableno-1) { + line[i1] = tableno-1; + tables[tableno-1].maxline = i1; + } else { + tableno++; + line[i1] = tableno-1; + tables[tableno-1].minline = tables[tableno-1].maxline = i1; + } + } + } + some_invalid = false; + for (i = 0; i < 0x100; i++) + if (charset2uni[i] == 0xfffd) + some_invalid = true; + if (tableno > 0) { + int t; + for (t = 0; t < tableno; t++) { + fprintf(f, "static const unsigned short %s_2uni", c_charsetname); + if (tableno > 1) + fprintf(f, "_%d", t+1); + fprintf(f, "[%d] = {\n", 16*(tables[t].maxline-tables[t].minline+1)); + for (i1 = tables[t].minline; i1 <= tables[t].maxline; i1++) { + fprintf(f, " /* 0x%02x */\n", 16*i1); + for (i2 = 0; i2 < 2; i2++) { + fprintf(f, " "); + for (i3 = 0; i3 < 8; i3++) { + i = 16*i1+8*i2+i3; + fprintf(f, " 0x%04x,", charset2uni[i]); + } + fprintf(f, "\n"); + } + } + fprintf(f, "};\n"); + } + fprintf(f, "\n"); + } + final_ret_reached = false; + fprintf(f, "static int\n%s_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n)\n", c_charsetname); + fprintf(f, "{\n"); + fprintf(f, " unsigned char c = *s;\n"); + if (some_invalid) { + for (i1 = 0; i1 < 16;) { + int t = line[i1]; + const char* indent; + for (i2 = i1; i2 < 16 && line[i2] == t; i2++); + indent = (i1 == 0 && i2 == 16 ? " " : " "); + if (i1 == 0) { + if (i2 == 16) { + } else { + fprintf(f, " if (c < 0x%02x) {\n", 16*i2); + } + } else { + if (i2 == 16) { + fprintf(f, " else {\n"); + } else { + fprintf(f, " else if (c < 0x%02x) {\n", 16*i2); + } + } + if (t == -2) { + final_ret_reached = true; + } else if (t == -1) { + fprintf(f, "%s*pwc = (ucs4_t) c;\n", indent); + fprintf(f, "%sreturn 1;\n", indent); + } else { + fprintf(f, "%s", indent); + some_invalid = false; + for (i = 16*i1; i < 16*i2; i++) + if (charset2uni[i] == 0xfffd) + some_invalid = true; + if (some_invalid) + fprintf(f, "unsigned short wc = "); + else + fprintf(f, "*pwc = (ucs4_t) "); + fprintf(f, "%s_2uni", c_charsetname); + if (tableno > 1) + fprintf(f, "_%d", t+1); + fprintf(f, "[c"); + if (tables[t].minline > 0) + fprintf(f, "-0x%02x", 16*tables[t].minline); + fprintf(f, "];\n"); + if (some_invalid) { + fprintf(f, "%sif (wc != 0xfffd) {\n", indent); + fprintf(f, "%s *pwc = (ucs4_t) wc;\n", indent); + fprintf(f, "%s return 1;\n", indent); + fprintf(f, "%s}\n", indent); + final_ret_reached = true; + } else { + fprintf(f, "%sreturn 1;\n", indent); + } + } + if (!(i1 == 0 && i2 == 16)) + fprintf(f, " }\n"); + i1 = i2; + } + if (final_ret_reached) + fprintf(f, " return RET_ILSEQ;\n"); + } else { + for (i1 = 0; i1 < 16;) { + int t = line[i1]; + for (i2 = i1; i2 < 16 && line[i2] == t; i2++); + if (i1 == 0) { + if (i2 == 16) { + fprintf(f, " "); + } else { + fprintf(f, " if (c < 0x%02x)\n ", 16*i2); + } + } else { + if (i2 == 16) { + fprintf(f, " else\n "); + } else { + fprintf(f, " else if (c < 0x%02x)\n ", 16*i2); + } + } + if (t == -1) + fprintf(f, "*pwc = (ucs4_t) c;\n"); + else { + fprintf(f, "*pwc = (ucs4_t) %s_2uni", c_charsetname); + if (tableno > 1) + fprintf(f, "_%d", t+1); + fprintf(f, "[c"); + if (tables[t].minline > 0) + fprintf(f, "-0x%02x", 16*tables[t].minline); + fprintf(f, "];\n"); + } + i1 = i2; + } + fprintf(f, " return 1;\n"); + } + fprintf(f, "}\n"); + + } + + fprintf(f, "\n"); + + { + int uni2charset[0x10000]; + bool pages[0x100]; + int line[0x2000]; + int tableno; + struct { int minline; int maxline; int usecount; const char* suffix; } tables[0x2000]; + bool need_c; + bool fix_0000; + int i, j, p, j1, j2, t; + + for (j = 0; j < 0x10000; j++) + uni2charset[j] = 0; + for (p = 0; p < 0x100; p++) + pages[p] = false; + for (i = 0; i < 0x100; i++) { + j = charset2uni[i]; + if (j != 0xfffd) { + uni2charset[j] = i; + pages[j>>8] = true; + } + } + for (j1 = 0; j1 < 0x2000; j1++) { + bool all_invalid = true; + bool all_identity = true; + for (j2 = 0; j2 < 8; j2++) { + j = 8*j1+j2; + if (uni2charset[j] != 0) + all_invalid = false; + if (uni2charset[j] != j) + all_identity = false; + } + if (all_invalid) + line[j1] = -2; + else if (all_identity) + line[j1] = -1; + else + line[j1] = 0; + } + tableno = 0; + for (j1 = 0; j1 < 0x2000; j1++) { + if (line[j1] >= 0) { + if (tableno > 0 + && ((j1 > 0 && line[j1-1] == tableno-1) + || ((tables[tableno-1].maxline >> 5) == (j1 >> 5) + && j1 - tables[tableno-1].maxline <= 8))) { + line[j1] = tableno-1; + tables[tableno-1].maxline = j1; + } else { + tableno++; + line[j1] = tableno-1; + tables[tableno-1].minline = tables[tableno-1].maxline = j1; + } + } + } + for (t = 0; t < tableno; t++) { + tables[t].usecount = 0; + j1 = 8*tables[t].minline; + j2 = 8*(tables[t].maxline+1); + for (j = j1; j < j2; j++) + if (uni2charset[j] != 0) + tables[t].usecount++; + } + for (t = 0, p = -1, i = 0; t < tableno; t++) { + if (tables[t].usecount > 1) { + char* s; + if (p == tables[t].minline >> 5) { + s = (char*) malloc(5+1); + sprintf(s, "%02x_%d", p, ++i); + } else { + p = tables[t].minline >> 5; + s = (char*) malloc(2+1); + sprintf(s, "%02x", p); + } + tables[t].suffix = s; + } else + tables[t].suffix = NULL; + } + { + p = -1; + for (t = 0; t < tableno; t++) + if (tables[t].usecount > 1) { + p = 0; + fprintf(f, "static const unsigned char %s_page%s[%d] = {\n", c_charsetname, tables[t].suffix, 8*(tables[t].maxline-tables[t].minline+1)); + for (j1 = tables[t].minline; j1 <= tables[t].maxline; j1++) { + if ((j1 % 0x20) == 0 && j1 > tables[t].minline) + fprintf(f, " /* 0x%04x */\n", 8*j1); + fprintf(f, " "); + for (j2 = 0; j2 < 8; j2++) { + j = 8*j1+j2; + fprintf(f, " 0x%02x,", uni2charset[j]); + } + fprintf(f, " /* 0x%02x-0x%02x */\n", 8*(j1 % 0x20), 8*(j1 % 0x20)+7); + } + fprintf(f, "};\n"); + } + if (p >= 0) + fprintf(f, "\n"); + } + need_c = false; + for (j1 = 0; j1 < 0x2000;) { + t = line[j1]; + for (j2 = j1; j2 < 0x2000 && line[j2] == t; j2++); + if (t >= 0) + j2 = tables[t].maxline+1; + if (!(t == -2 || (t == -1 && j1 == 0))) + need_c = true; + j1 = j2; + } + fix_0000 = false; + fprintf(f, "static int\n%s_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n)\n", c_charsetname); + fprintf(f, "{\n"); + if (need_c) + fprintf(f, " unsigned char c = 0;\n"); + for (j1 = 0; j1 < 0x2000;) { + t = line[j1]; + for (j2 = j1; j2 < 0x2000 && line[j2] == t; j2++); + if (t >= 0) { + if (j1 != tables[t].minline) abort(); + if (j2 > tables[t].maxline+1) abort(); + j2 = tables[t].maxline+1; + } + if (t == -2) { + } else { + if (j1 == 0) + fprintf(f, " "); + else + fprintf(f, " else "); + if (t >= 0 && tables[t].usecount == 0) abort(); + if (t >= 0 && tables[t].usecount == 1) { + if (j2 != j1+1) abort(); + for (j = 8*j1; j < 8*j2; j++) + if (uni2charset[j] != 0) { + fprintf(f, "if (wc == 0x%04x)\n c = 0x%02x;\n", j, uni2charset[j]); + break; + } + } else { + if (j1 == 0) { + fprintf(f, "if (wc < 0x%04x)", 8*j2); + } else { + fprintf(f, "if (wc >= 0x%04x && wc < 0x%04x)", 8*j1, 8*j2); + } + if (t == -1) { + if (j1 == 0) + /* If wc == 0, the function must return 1, not -1. */ + fprintf(f, " {\n *r = wc;\n return 1;\n }\n"); + else + fprintf(f, "\n c = wc;\n"); + } else { + fprintf(f, "\n c = %s_page%s[wc", c_charsetname, tables[t].suffix); + if (tables[t].minline > 0) + fprintf(f, "-0x%04x", 8*j1); + fprintf(f, "];\n"); + if (j1 == 0 && uni2charset[0] == 0) + /* If wc == 0, the function must return 1, not -1. */ + fix_0000 = true; + } + } + } + j1 = j2; + } + if (need_c) { + if (fix_0000) + fprintf(f, " if (c != 0 || wc == 0) {\n"); + else + fprintf(f, " if (c != 0) {\n"); + fprintf(f, " *r = c;\n"); + fprintf(f, " return 1;\n"); + fprintf(f, " }\n"); + } + fprintf(f, " return RET_ILSEQ;\n"); + fprintf(f, "}\n"); + + } + + if (ferror(f) || fclose(f)) + exit(1); + } + +#if 0 + + int i1, i2, i3, i1_min, i1_max, j1, j2; + + i1_min = 16; + i1_max = -1; + for (i1 = 0; i1 < 16; i1++) + for (i2 = 0; i2 < 16; i2++) + if (charset2uni[16*i1+i2] != 0xfffd) { + if (i1_min > i1) i1_min = i1; + if (i1_max < i1) i1_max = i1; + } + printf("static const unsigned short %s_2uni[%d] = {\n", + name, 16*(i1_max-i1_min+1)); + for (i1 = i1_min; i1 <= i1_max; i1++) { + printf(" /""* 0x%02x *""/\n", 16*i1); + for (i2 = 0; i2 < 2; i2++) { + printf(" "); + for (i3 = 0; i3 < 8; i3++) { + if (i3 > 0) printf(" "); + printf("0x%04x,", charset2uni[16*i1+8*i2+i3]); + } + printf("\n"); + } + } + printf("};\n"); + printf("\n"); + + for (p = 0; p < 0x100; p++) + pages[p] = 0; + for (i = 0; i < 0x100; i++) + if (charset2uni[i] != 0xfffd) + pages[charset2uni[i]>>8] = 1; + for (p = 0; p < 0x100; p++) + if (pages[p]) { + int j1_min = 32; + int j1_max = -1; + for (j1 = 0; j1 < 32; j1++) + for (j2 = 0; j2 < 8; j2++) + if (uni2charset[256*p+8*j1+j2] != 0) { + if (j1_min > j1) j1_min = j1; + if (j1_max < j1) j1_max = j1; + } + printf("static const unsigned char %s_page%02x[%d] = {\n", + name, p, 8*(j1_max-j1_min+1)); + for (j1 = j1_min; j1 <= j1_max; j1++) { + printf(" "); + for (j2 = 0; j2 < 8; j2++) + printf("0x%02x, ", uni2charset[256*p+8*j1+j2]); + printf("/""* 0x%02x-0x%02x *""/\n", 8*j1, 8*j1+7); + } + printf("};\n"); + } + printf("\n"); + +} +#endif + + exit(0); +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/COPYRIGHT b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/COPYRIGHT new file mode 100644 index 0000000..ccc1626 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/COPYRIGHT @@ -0,0 +1,39 @@ +This notice applies to the files in this directory. They are taken from +the libiconv-1.1 package, which is covered by the LGPL license. The files +in this directory have been placed under the following copyright, with +permission from the Free Software Foundation. + + +Copyright (c) 1999-2000 Free Software Foundation, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +FREE SOFTWARE FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the Free Software Foundation +shall not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization from the +Free Software Foundation. + + +Notes: + +1. This copyright applies only to the files in this directory, and not to +the remaining files in libiconv. + +2. The Free Software Foundation does not encourage the use of the above +license for newly written software. + diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/README b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/README new file mode 100644 index 0000000..6c0ca93 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/README @@ -0,0 +1,12 @@ +$XFree86: xc/lib/X11/lcUniConv/README,v 1.3 2003/10/24 15:34:01 tsi Exp $ + +The files in this directory are taken from the libiconv-1.1 package. + +The *.h files were generated from tables (mostly from ftp.unicode.org) using +the programs '8bit_tab_to_h.c', 'cjk_tab_to_h.c' and 'gbk_tab_to_h.c'. On some of them, further +optimizations were applied by hand. + +If you find a bug in these files, instead of modifying them in XFree86 +and let it diverge from libiconv, please notify the libiconv maintainer +(currently ) so he can fix both in synch. + diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/armscii_8.h b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/armscii_8.h new file mode 100644 index 0000000..6f8c10c --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/armscii_8.h @@ -0,0 +1,98 @@ +/* $XFree86: xc/lib/X11/lcUniConv/armscii_8.h,v 1.4 2003/07/15 17:33:45 pascal Exp $ */ + +/* + * ARMSCII-8 + */ + +static const unsigned short armscii_8_2uni[96] = { + /* 0xa0 */ + 0x00a0, 0xfffd, 0x0587, 0x0589, 0x0029, 0x0028, 0x00bb, 0x00ab, + 0x2014, 0x002e, 0x055d, 0x002c, 0x002d, 0x058a, 0x2026, 0x055c, + /* 0xb0 */ + 0x055b, 0x055e, 0x0531, 0x0561, 0x0532, 0x0562, 0x0533, 0x0563, + 0x0534, 0x0564, 0x0535, 0x0565, 0x0536, 0x0566, 0x0537, 0x0567, + /* 0xc0 */ + 0x0538, 0x0568, 0x0539, 0x0569, 0x053a, 0x056a, 0x053b, 0x056b, + 0x053c, 0x056c, 0x053d, 0x056d, 0x053e, 0x056e, 0x053f, 0x056f, + /* 0xd0 */ + 0x0540, 0x0570, 0x0541, 0x0571, 0x0542, 0x0572, 0x0543, 0x0573, + 0x0544, 0x0574, 0x0545, 0x0575, 0x0546, 0x0576, 0x0547, 0x0577, + /* 0xe0 */ + 0x0548, 0x0578, 0x0549, 0x0579, 0x054a, 0x057a, 0x054b, 0x057b, + 0x054c, 0x057c, 0x054d, 0x057d, 0x054e, 0x057e, 0x054f, 0x057f, + /* 0xf0 */ + 0x0550, 0x0580, 0x0551, 0x0581, 0x0552, 0x0582, 0x0553, 0x0583, + 0x0554, 0x0584, 0x0555, 0x0585, 0x0556, 0x0586, 0x055a, 0xfffd, +}; + +static int +armscii_8_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0xa0) { + *pwc = (ucs4_t) c; + return 1; + } + else { + unsigned short wc = armscii_8_2uni[c-0xa0]; + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 1; + } + } + return RET_ILSEQ; +} + +static const unsigned char armscii_8_page00[8] = { + 0xa5, 0xa4, 0x2a, 0x2b, 0xab, 0xac, 0xa9, 0x2f, /* 0x28-0x2f */ +}; +static const unsigned char armscii_8_page00_1[32] = { + 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0xa7, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0xa6, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ +}; +static const unsigned char armscii_8_page05[96] = { + 0x00, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe, /* 0x30-0x37 */ + 0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, /* 0x38-0x3f */ + 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde, /* 0x40-0x47 */ + 0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, /* 0x48-0x4f */ + 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0xfe, 0xb0, 0xaf, 0xaa, 0xb1, 0x00, /* 0x58-0x5f */ + 0x00, 0xb3, 0xb5, 0xb7, 0xb9, 0xbb, 0xbd, 0xbf, /* 0x60-0x67 */ + 0xc1, 0xc3, 0xc5, 0xc7, 0xc9, 0xcb, 0xcd, 0xcf, /* 0x68-0x6f */ + 0xd1, 0xd3, 0xd5, 0xd7, 0xd9, 0xdb, 0xdd, 0xdf, /* 0x70-0x77 */ + 0xe1, 0xe3, 0xe5, 0xe7, 0xe9, 0xeb, 0xed, 0xef, /* 0x78-0x7f */ + 0xf1, 0xf3, 0xf5, 0xf7, 0xf9, 0xfb, 0xfd, 0xa2, /* 0x80-0x87 */ + 0x00, 0xa3, 0xad, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ +}; +static const unsigned char armscii_8_page20[24] = { + 0x00, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xae, 0x00, /* 0x20-0x27 */ +}; + +static int +armscii_8_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0028) { + *r = wc; + return 1; + } + else if (wc >= 0x0028 && wc < 0x0030) + c = armscii_8_page00[wc-0x0028]; + else if (wc >= 0x0030 && wc < 0x00a0) + c = wc; + else if (wc >= 0x00a0 && wc < 0x00c0) + c = armscii_8_page00_1[wc-0x00a0]; + else if (wc >= 0x0530 && wc < 0x0590) + c = armscii_8_page05[wc-0x0530]; + else if (wc >= 0x2010 && wc < 0x2028) + c = armscii_8_page20[wc-0x2010]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILSEQ; +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/ascii.h b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/ascii.h new file mode 100644 index 0000000..183de0b --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/ascii.h @@ -0,0 +1,26 @@ +/* $XFree86: xc/lib/X11/lcUniConv/ascii.h,v 1.3 2000/11/29 17:40:28 dawes Exp $ */ + +/* + * ASCII + */ + +static int +ascii_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) { + *pwc = (ucs4_t) c; + return 1; + } + return RET_ILSEQ; +} + +static int +ascii_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (wc < 0x0080) { + *r = wc; + return 1; + } + return RET_ILSEQ; +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/big5.h b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/big5.h new file mode 100644 index 0000000..deff866 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/big5.h @@ -0,0 +1,4142 @@ +/* $XFree86: xc/lib/X11/lcUniConv/big5.h,v 1.2 2003/05/27 22:26:28 tsi Exp $ */ + +/* + * BIG5 + */ + +static const unsigned short big5_2uni_pagea1[6121] = { + /* 0xa1 */ + 0x3000, 0xff0c, 0x3001, 0x3002, 0xff0e, 0x2022, 0xff1b, 0xff1a, + 0xff1f, 0xff01, 0xfe30, 0x2026, 0x2025, 0xfe50, 0xff64, 0xfe52, + 0x00b7, 0xfe54, 0xfe55, 0xfe56, 0xfe57, 0xff5c, 0x2013, 0xfe31, + 0x2014, 0xfe33, 0xfffd, 0xfe34, 0xfe4f, 0xff08, 0xff09, 0xfe35, + 0xfe36, 0xff5b, 0xff5d, 0xfe37, 0xfe38, 0x3014, 0x3015, 0xfe39, + 0xfe3a, 0x3010, 0x3011, 0xfe3b, 0xfe3c, 0x300a, 0x300b, 0xfe3d, + 0xfe3e, 0x3008, 0x3009, 0xfe3f, 0xfe40, 0x300c, 0x300d, 0xfe41, + 0xfe42, 0x300e, 0x300f, 0xfe43, 0xfe44, 0xfe59, 0xfe5a, 0xfe5b, + 0xfe5c, 0xfe5d, 0xfe5e, 0x2018, 0x2019, 0x201c, 0x201d, 0x301d, + 0x301e, 0x2035, 0x2032, 0xff03, 0xff06, 0xff0a, 0x203b, 0x00a7, + 0x3003, 0x25cb, 0x25cf, 0x25b3, 0x25b2, 0x25ce, 0x2606, 0x2605, + 0x25c7, 0x25c6, 0x25a1, 0x25a0, 0x25bd, 0x25bc, 0x32a3, 0x2105, + 0x203e, 0xfffd, 0xff3f, 0xfffd, 0xfe49, 0xfe4a, 0xfe4d, 0xfe4e, + 0xfe4b, 0xfe4c, 0xfe5f, 0xfe60, 0xfe61, 0xff0b, 0xff0d, 0x00d7, + 0x00f7, 0x00b1, 0x221a, 0xff1c, 0xff1e, 0xff1d, 0x2266, 0x2267, + 0x2260, 0x221e, 0x2252, 0x2261, 0xfe62, 0xfe63, 0xfe64, 0xfe65, + 0xfe66, 0x223c, 0x2229, 0x222a, 0x22a5, 0x2220, 0x221f, 0x22bf, + 0x33d2, 0x33d1, 0x222b, 0x222e, 0x2235, 0x2234, 0x2640, 0x2642, + 0x2641, 0x2609, 0x2191, 0x2193, 0x2190, 0x2192, 0x2196, 0x2197, + 0x2199, 0x2198, 0x2225, 0x2223, 0xfffd, + /* 0xa2 */ + 0xfffd, 0xff0f, 0xff3c, 0xff04, 0x00a5, 0x3012, 0x00a2, 0x00a3, + 0xff05, 0xff20, 0x2103, 0x2109, 0xfe69, 0xfe6a, 0xfe6b, 0x33d5, + 0x339c, 0x339d, 0x339e, 0x33ce, 0x33a1, 0x338e, 0x338f, 0x33c4, + 0x00b0, 0x5159, 0x515b, 0x515e, 0x515d, 0x5161, 0x5163, 0x55e7, + 0x74e9, 0x7cce, 0x2581, 0x2582, 0x2583, 0x2584, 0x2585, 0x2586, + 0x2587, 0x2588, 0x258f, 0x258e, 0x258d, 0x258c, 0x258b, 0x258a, + 0x2589, 0x253c, 0x2534, 0x252c, 0x2524, 0x251c, 0x2594, 0x2500, + 0x2502, 0x2595, 0x250c, 0x2510, 0x2514, 0x2518, 0x256d, 0x256e, + 0x2570, 0x256f, 0x2550, 0x255e, 0x256a, 0x2561, 0x25e2, 0x25e3, + 0x25e5, 0x25e4, 0x2571, 0x2572, 0x2573, 0xff10, 0xff11, 0xff12, + 0xff13, 0xff14, 0xff15, 0xff16, 0xff17, 0xff18, 0xff19, 0x2160, + 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, 0x2168, + 0x2169, 0x3021, 0x3022, 0x3023, 0x3024, 0x3025, 0x3026, 0x3027, + 0x3028, 0x3029, 0xfffd, 0x5344, 0xfffd, 0xff21, 0xff22, 0xff23, + 0xff24, 0xff25, 0xff26, 0xff27, 0xff28, 0xff29, 0xff2a, 0xff2b, + 0xff2c, 0xff2d, 0xff2e, 0xff2f, 0xff30, 0xff31, 0xff32, 0xff33, + 0xff34, 0xff35, 0xff36, 0xff37, 0xff38, 0xff39, 0xff3a, 0xff41, + 0xff42, 0xff43, 0xff44, 0xff45, 0xff46, 0xff47, 0xff48, 0xff49, + 0xff4a, 0xff4b, 0xff4c, 0xff4d, 0xff4e, 0xff4f, 0xff50, 0xff51, + 0xff52, 0xff53, 0xff54, 0xff55, 0xff56, + /* 0xa3 */ + 0xff57, 0xff58, 0xff59, 0xff5a, 0x0391, 0x0392, 0x0393, 0x0394, + 0x0395, 0x0396, 0x0397, 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, + 0x039d, 0x039e, 0x039f, 0x03a0, 0x03a1, 0x03a3, 0x03a4, 0x03a5, + 0x03a6, 0x03a7, 0x03a8, 0x03a9, 0x03b1, 0x03b2, 0x03b3, 0x03b4, + 0x03b5, 0x03b6, 0x03b7, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, + 0x03bd, 0x03be, 0x03bf, 0x03c0, 0x03c1, 0x03c3, 0x03c4, 0x03c5, + 0x03c6, 0x03c7, 0x03c8, 0x03c9, 0x3105, 0x3106, 0x3107, 0x3108, + 0x3109, 0x310a, 0x310b, 0x310c, 0x310d, 0x310e, 0x310f, 0x3110, + 0x3111, 0x3112, 0x3113, 0x3114, 0x3115, 0x3116, 0x3117, 0x3118, + 0x3119, 0x311a, 0x311b, 0x311c, 0x311d, 0x311e, 0x311f, 0x3120, + 0x3121, 0x3122, 0x3123, 0x3124, 0x3125, 0x3126, 0x3127, 0x3128, + 0x3129, 0x02d9, 0x02c9, 0x02ca, 0x02c7, 0x02cb, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0xa4 */ + 0x4e00, 0x4e59, 0x4e01, 0x4e03, 0x4e43, 0x4e5d, 0x4e86, 0x4e8c, + 0x4eba, 0x513f, 0x5165, 0x516b, 0x51e0, 0x5200, 0x5201, 0x529b, + 0x5315, 0x5341, 0x535c, 0x53c8, 0x4e09, 0x4e0b, 0x4e08, 0x4e0a, + 0x4e2b, 0x4e38, 0x51e1, 0x4e45, 0x4e48, 0x4e5f, 0x4e5e, 0x4e8e, + 0x4ea1, 0x5140, 0x5203, 0x52fa, 0x5343, 0x53c9, 0x53e3, 0x571f, + 0x58eb, 0x5915, 0x5927, 0x5973, 0x5b50, 0x5b51, 0x5b53, 0x5bf8, + 0x5c0f, 0x5c22, 0x5c38, 0x5c71, 0x5ddd, 0x5de5, 0x5df1, 0x5df2, + 0x5df3, 0x5dfe, 0x5e72, 0x5efe, 0x5f0b, 0x5f13, 0x624d, 0x4e11, + 0x4e10, 0x4e0d, 0x4e2d, 0x4e30, 0x4e39, 0x4e4b, 0x5c39, 0x4e88, + 0x4e91, 0x4e95, 0x4e92, 0x4e94, 0x4ea2, 0x4ec1, 0x4ec0, 0x4ec3, + 0x4ec6, 0x4ec7, 0x4ecd, 0x4eca, 0x4ecb, 0x4ec4, 0x5143, 0x5141, + 0x5167, 0x516d, 0x516e, 0x516c, 0x5197, 0x51f6, 0x5206, 0x5207, + 0x5208, 0x52fb, 0x52fe, 0x52ff, 0x5316, 0x5339, 0x5348, 0x5347, + 0x5345, 0x535e, 0x5384, 0x53cb, 0x53ca, 0x53cd, 0x58ec, 0x5929, + 0x592b, 0x592a, 0x592d, 0x5b54, 0x5c11, 0x5c24, 0x5c3a, 0x5c6f, + 0x5df4, 0x5e7b, 0x5eff, 0x5f14, 0x5f15, 0x5fc3, 0x6208, 0x6236, + 0x624b, 0x624e, 0x652f, 0x6587, 0x6597, 0x65a4, 0x65b9, 0x65e5, + 0x66f0, 0x6708, 0x6728, 0x6b20, 0x6b62, 0x6b79, 0x6bcb, 0x6bd4, + 0x6bdb, 0x6c0f, 0x6c34, 0x706b, 0x722a, 0x7236, 0x723b, 0x7247, + 0x7259, 0x725b, 0x72ac, 0x738b, 0x4e19, + /* 0xa5 */ + 0x4e16, 0x4e15, 0x4e14, 0x4e18, 0x4e3b, 0x4e4d, 0x4e4f, 0x4e4e, + 0x4ee5, 0x4ed8, 0x4ed4, 0x4ed5, 0x4ed6, 0x4ed7, 0x4ee3, 0x4ee4, + 0x4ed9, 0x4ede, 0x5145, 0x5144, 0x5189, 0x518a, 0x51ac, 0x51f9, + 0x51fa, 0x51f8, 0x520a, 0x52a0, 0x529f, 0x5305, 0x5306, 0x5317, + 0x531d, 0x4edf, 0x534a, 0x5349, 0x5361, 0x5360, 0x536f, 0x536e, + 0x53bb, 0x53ef, 0x53e4, 0x53f3, 0x53ec, 0x53ee, 0x53e9, 0x53e8, + 0x53fc, 0x53f8, 0x53f5, 0x53eb, 0x53e6, 0x53ea, 0x53f2, 0x53f1, + 0x53f0, 0x53e5, 0x53ed, 0x53fb, 0x56db, 0x56da, 0x5916, 0x592e, + 0x5931, 0x5974, 0x5976, 0x5b55, 0x5b83, 0x5c3c, 0x5de8, 0x5de7, + 0x5de6, 0x5e02, 0x5e03, 0x5e73, 0x5e7c, 0x5f01, 0x5f18, 0x5f17, + 0x5fc5, 0x620a, 0x6253, 0x6254, 0x6252, 0x6251, 0x65a5, 0x65e6, + 0x672e, 0x672c, 0x672a, 0x672b, 0x672d, 0x6b63, 0x6bcd, 0x6c11, + 0x6c10, 0x6c38, 0x6c41, 0x6c40, 0x6c3e, 0x72af, 0x7384, 0x7389, + 0x74dc, 0x74e6, 0x7518, 0x751f, 0x7528, 0x7529, 0x7530, 0x7531, + 0x7532, 0x7533, 0x758b, 0x767d, 0x76ae, 0x76bf, 0x76ee, 0x77db, + 0x77e2, 0x77f3, 0x793a, 0x79be, 0x7a74, 0x7acb, 0x4e1e, 0x4e1f, + 0x4e52, 0x4e53, 0x4e69, 0x4e99, 0x4ea4, 0x4ea6, 0x4ea5, 0x4eff, + 0x4f09, 0x4f19, 0x4f0a, 0x4f15, 0x4f0d, 0x4f10, 0x4f11, 0x4f0f, + 0x4ef2, 0x4ef6, 0x4efb, 0x4ef0, 0x4ef3, 0x4efd, 0x4f01, 0x4f0b, + 0x5149, 0x5147, 0x5146, 0x5148, 0x5168, + /* 0xa6 */ + 0x5171, 0x518d, 0x51b0, 0x5217, 0x5211, 0x5212, 0x520e, 0x5216, + 0x52a3, 0x5308, 0x5321, 0x5320, 0x5370, 0x5371, 0x5409, 0x540f, + 0x540c, 0x540a, 0x5410, 0x5401, 0x540b, 0x5404, 0x5411, 0x540d, + 0x5408, 0x5403, 0x540e, 0x5406, 0x5412, 0x56e0, 0x56de, 0x56dd, + 0x5733, 0x5730, 0x5728, 0x572d, 0x572c, 0x572f, 0x5729, 0x5919, + 0x591a, 0x5937, 0x5938, 0x5984, 0x5978, 0x5983, 0x597d, 0x5979, + 0x5982, 0x5981, 0x5b57, 0x5b58, 0x5b87, 0x5b88, 0x5b85, 0x5b89, + 0x5bfa, 0x5c16, 0x5c79, 0x5dde, 0x5e06, 0x5e76, 0x5e74, 0x5f0f, + 0x5f1b, 0x5fd9, 0x5fd6, 0x620e, 0x620c, 0x620d, 0x6210, 0x6263, + 0x625b, 0x6258, 0x6536, 0x65e9, 0x65e8, 0x65ec, 0x65ed, 0x66f2, + 0x66f3, 0x6709, 0x673d, 0x6734, 0x6731, 0x6735, 0x6b21, 0x6b64, + 0x6b7b, 0x6c16, 0x6c5d, 0x6c57, 0x6c59, 0x6c5f, 0x6c60, 0x6c50, + 0x6c55, 0x6c61, 0x6c5b, 0x6c4d, 0x6c4e, 0x7070, 0x725f, 0x725d, + 0x767e, 0x7af9, 0x7c73, 0x7cf8, 0x7f36, 0x7f8a, 0x7fbd, 0x8001, + 0x8003, 0x800c, 0x8012, 0x8033, 0x807f, 0x8089, 0x808b, 0x808c, + 0x81e3, 0x81ea, 0x81f3, 0x81fc, 0x820c, 0x821b, 0x821f, 0x826e, + 0x8272, 0x827e, 0x866b, 0x8840, 0x884c, 0x8863, 0x897f, 0x9621, + 0x4e32, 0x4ea8, 0x4f4d, 0x4f4f, 0x4f47, 0x4f57, 0x4f5e, 0x4f34, + 0x4f5b, 0x4f55, 0x4f30, 0x4f50, 0x4f51, 0x4f3d, 0x4f3a, 0x4f38, + 0x4f43, 0x4f54, 0x4f3c, 0x4f46, 0x4f63, + /* 0xa7 */ + 0x4f5c, 0x4f60, 0x4f2f, 0x4f4e, 0x4f36, 0x4f59, 0x4f5d, 0x4f48, + 0x4f5a, 0x514c, 0x514b, 0x514d, 0x5175, 0x51b6, 0x51b7, 0x5225, + 0x5224, 0x5229, 0x522a, 0x5228, 0x52ab, 0x52a9, 0x52aa, 0x52ac, + 0x5323, 0x5373, 0x5375, 0x541d, 0x542d, 0x541e, 0x543e, 0x5426, + 0x544e, 0x5427, 0x5446, 0x5443, 0x5433, 0x5448, 0x5442, 0x541b, + 0x5429, 0x544a, 0x5439, 0x543b, 0x5438, 0x542e, 0x5435, 0x5436, + 0x5420, 0x543c, 0x5440, 0x5431, 0x542b, 0x541f, 0x542c, 0x56ea, + 0x56f0, 0x56e4, 0x56eb, 0x574a, 0x5751, 0x5740, 0x574d, 0x5747, + 0x574e, 0x573e, 0x5750, 0x574f, 0x573b, 0x58ef, 0x593e, 0x599d, + 0x5992, 0x59a8, 0x599e, 0x59a3, 0x5999, 0x5996, 0x598d, 0x59a4, + 0x5993, 0x598a, 0x59a5, 0x5b5d, 0x5b5c, 0x5b5a, 0x5b5b, 0x5b8c, + 0x5b8b, 0x5b8f, 0x5c2c, 0x5c40, 0x5c41, 0x5c3f, 0x5c3e, 0x5c90, + 0x5c91, 0x5c94, 0x5c8c, 0x5deb, 0x5e0c, 0x5e8f, 0x5e87, 0x5e8a, + 0x5ef7, 0x5f04, 0x5f1f, 0x5f64, 0x5f62, 0x5f77, 0x5f79, 0x5fd8, + 0x5fcc, 0x5fd7, 0x5fcd, 0x5ff1, 0x5feb, 0x5ff8, 0x5fea, 0x6212, + 0x6211, 0x6284, 0x6297, 0x6296, 0x6280, 0x6276, 0x6289, 0x626d, + 0x628a, 0x627c, 0x627e, 0x6279, 0x6273, 0x6292, 0x626f, 0x6298, + 0x626e, 0x6295, 0x6293, 0x6291, 0x6286, 0x6539, 0x653b, 0x6538, + 0x65f1, 0x66f4, 0x675f, 0x674e, 0x674f, 0x6750, 0x6751, 0x675c, + 0x6756, 0x675e, 0x6749, 0x6746, 0x6760, + /* 0xa8 */ + 0x6753, 0x6757, 0x6b65, 0x6bcf, 0x6c42, 0x6c5e, 0x6c99, 0x6c81, + 0x6c88, 0x6c89, 0x6c85, 0x6c9b, 0x6c6a, 0x6c7a, 0x6c90, 0x6c70, + 0x6c8c, 0x6c68, 0x6c96, 0x6c92, 0x6c7d, 0x6c83, 0x6c72, 0x6c7e, + 0x6c74, 0x6c86, 0x6c76, 0x6c8d, 0x6c94, 0x6c98, 0x6c82, 0x7076, + 0x707c, 0x707d, 0x7078, 0x7262, 0x7261, 0x7260, 0x72c4, 0x72c2, + 0x7396, 0x752c, 0x752b, 0x7537, 0x7538, 0x7682, 0x76ef, 0x77e3, + 0x79c1, 0x79c0, 0x79bf, 0x7a76, 0x7cfb, 0x7f55, 0x8096, 0x8093, + 0x809d, 0x8098, 0x809b, 0x809a, 0x80b2, 0x826f, 0x8292, 0x828b, + 0x828d, 0x898b, 0x89d2, 0x8a00, 0x8c37, 0x8c46, 0x8c55, 0x8c9d, + 0x8d64, 0x8d70, 0x8db3, 0x8eab, 0x8eca, 0x8f9b, 0x8fb0, 0x8fc2, + 0x8fc6, 0x8fc5, 0x8fc4, 0x5de1, 0x9091, 0x90a2, 0x90aa, 0x90a6, + 0x90a3, 0x9149, 0x91c6, 0x91cc, 0x9632, 0x962e, 0x9631, 0x962a, + 0x962c, 0x4e26, 0x4e56, 0x4e73, 0x4e8b, 0x4e9b, 0x4e9e, 0x4eab, + 0x4eac, 0x4f6f, 0x4f9d, 0x4f8d, 0x4f73, 0x4f7f, 0x4f6c, 0x4f9b, + 0x4f8b, 0x4f86, 0x4f83, 0x4f70, 0x4f75, 0x4f88, 0x4f69, 0x4f7b, + 0x4f96, 0x4f7e, 0x4f8f, 0x4f91, 0x4f7a, 0x5154, 0x5152, 0x5155, + 0x5169, 0x5177, 0x5176, 0x5178, 0x51bd, 0x51fd, 0x523b, 0x5238, + 0x5237, 0x523a, 0x5230, 0x522e, 0x5236, 0x5241, 0x52be, 0x52bb, + 0x5352, 0x5354, 0x5353, 0x5351, 0x5366, 0x5377, 0x5378, 0x5379, + 0x53d6, 0x53d4, 0x53d7, 0x5473, 0x5475, + /* 0xa9 */ + 0x5496, 0x5478, 0x5495, 0x5480, 0x547b, 0x5477, 0x5484, 0x5492, + 0x5486, 0x547c, 0x5490, 0x5471, 0x5476, 0x548c, 0x549a, 0x5462, + 0x5468, 0x548b, 0x547d, 0x548e, 0x56fa, 0x5783, 0x5777, 0x576a, + 0x5769, 0x5761, 0x5766, 0x5764, 0x577c, 0x591c, 0x5949, 0x5947, + 0x5948, 0x5944, 0x5954, 0x59be, 0x59bb, 0x59d4, 0x59b9, 0x59ae, + 0x59d1, 0x59c6, 0x59d0, 0x59cd, 0x59cb, 0x59d3, 0x59ca, 0x59af, + 0x59b3, 0x59d2, 0x59c5, 0x5b5f, 0x5b64, 0x5b63, 0x5b97, 0x5b9a, + 0x5b98, 0x5b9c, 0x5b99, 0x5b9b, 0x5c1a, 0x5c48, 0x5c45, 0x5c46, + 0x5cb7, 0x5ca1, 0x5cb8, 0x5ca9, 0x5cab, 0x5cb1, 0x5cb3, 0x5e18, + 0x5e1a, 0x5e16, 0x5e15, 0x5e1b, 0x5e11, 0x5e78, 0x5e9a, 0x5e97, + 0x5e9c, 0x5e95, 0x5e96, 0x5ef6, 0x5f26, 0x5f27, 0x5f29, 0x5f80, + 0x5f81, 0x5f7f, 0x5f7c, 0x5fdd, 0x5fe0, 0x5ffd, 0x5ff5, 0x5fff, + 0x600f, 0x6014, 0x602f, 0x6035, 0x6016, 0x602a, 0x6015, 0x6021, + 0x6027, 0x6029, 0x602b, 0x601b, 0x6216, 0x6215, 0x623f, 0x623e, + 0x6240, 0x627f, 0x62c9, 0x62cc, 0x62c4, 0x62bf, 0x62c2, 0x62b9, + 0x62d2, 0x62db, 0x62ab, 0x62d3, 0x62d4, 0x62cb, 0x62c8, 0x62a8, + 0x62bd, 0x62bc, 0x62d0, 0x62d9, 0x62c7, 0x62cd, 0x62b5, 0x62da, + 0x62b1, 0x62d8, 0x62d6, 0x62d7, 0x62c6, 0x62ac, 0x62ce, 0x653e, + 0x65a7, 0x65bc, 0x65fa, 0x6614, 0x6613, 0x660c, 0x6606, 0x6602, + 0x660e, 0x6600, 0x660f, 0x6615, 0x660a, + /* 0xaa */ + 0x6607, 0x670d, 0x670b, 0x676d, 0x678b, 0x6795, 0x6771, 0x679c, + 0x6773, 0x6777, 0x6787, 0x679d, 0x6797, 0x676f, 0x6770, 0x677f, + 0x6789, 0x677e, 0x6790, 0x6775, 0x679a, 0x6793, 0x677c, 0x676a, + 0x6772, 0x6b23, 0x6b66, 0x6b67, 0x6b7f, 0x6c13, 0x6c1b, 0x6ce3, + 0x6ce8, 0x6cf3, 0x6cb1, 0x6ccc, 0x6ce5, 0x6cb3, 0x6cbd, 0x6cbe, + 0x6cbc, 0x6ce2, 0x6cab, 0x6cd5, 0x6cd3, 0x6cb8, 0x6cc4, 0x6cb9, + 0x6cc1, 0x6cae, 0x6cd7, 0x6cc5, 0x6cf1, 0x6cbf, 0x6cbb, 0x6ce1, + 0x6cdb, 0x6cca, 0x6cac, 0x6cef, 0x6cdc, 0x6cd6, 0x6ce0, 0x7095, + 0x708e, 0x7092, 0x708a, 0x7099, 0x722c, 0x722d, 0x7238, 0x7248, + 0x7267, 0x7269, 0x72c0, 0x72ce, 0x72d9, 0x72d7, 0x72d0, 0x73a9, + 0x73a8, 0x739f, 0x73ab, 0x73a5, 0x753d, 0x759d, 0x7599, 0x759a, + 0x7684, 0x76c2, 0x76f2, 0x76f4, 0x77e5, 0x77fd, 0x793e, 0x7940, + 0x7941, 0x79c9, 0x79c8, 0x7a7a, 0x7a79, 0x7afa, 0x7cfe, 0x7f54, + 0x7f8c, 0x7f8b, 0x8005, 0x80ba, 0x80a5, 0x80a2, 0x80b1, 0x80a1, + 0x80ab, 0x80a9, 0x80b4, 0x80aa, 0x80af, 0x81e5, 0x81fe, 0x820d, + 0x82b3, 0x829d, 0x8299, 0x82ad, 0x82bd, 0x829f, 0x82b9, 0x82b1, + 0x82ac, 0x82a5, 0x82af, 0x82b8, 0x82a3, 0x82b0, 0x82be, 0x82b7, + 0x864e, 0x8671, 0x521d, 0x8868, 0x8ecb, 0x8fce, 0x8fd4, 0x8fd1, + 0x90b5, 0x90b8, 0x90b1, 0x90b6, 0x91c7, 0x91d1, 0x9577, 0x9580, + 0x961c, 0x9640, 0x963f, 0x963b, 0x9644, + /* 0xab */ + 0x9642, 0x96b9, 0x96e8, 0x9752, 0x975e, 0x4e9f, 0x4ead, 0x4eae, + 0x4fe1, 0x4fb5, 0x4faf, 0x4fbf, 0x4fe0, 0x4fd1, 0x4fcf, 0x4fdd, + 0x4fc3, 0x4fb6, 0x4fd8, 0x4fdf, 0x4fca, 0x4fd7, 0x4fae, 0x4fd0, + 0x4fc4, 0x4fc2, 0x4fda, 0x4fce, 0x4fde, 0x4fb7, 0x5157, 0x5192, + 0x5191, 0x51a0, 0x524e, 0x5243, 0x524a, 0x524d, 0x524c, 0x524b, + 0x5247, 0x52c7, 0x52c9, 0x52c3, 0x52c1, 0x530d, 0x5357, 0x537b, + 0x539a, 0x53db, 0x54ac, 0x54c0, 0x54a8, 0x54ce, 0x54c9, 0x54b8, + 0x54a6, 0x54b3, 0x54c7, 0x54c2, 0x54bd, 0x54aa, 0x54c1, 0x54c4, + 0x54c8, 0x54af, 0x54ab, 0x54b1, 0x54bb, 0x54a9, 0x54a7, 0x54bf, + 0x56ff, 0x5782, 0x578b, 0x57a0, 0x57a3, 0x57a2, 0x57ce, 0x57ae, + 0x5793, 0x5955, 0x5951, 0x594f, 0x594e, 0x5950, 0x59dc, 0x59d8, + 0x59ff, 0x59e3, 0x59e8, 0x5a03, 0x59e5, 0x59ea, 0x59da, 0x59e6, + 0x5a01, 0x59fb, 0x5b69, 0x5ba3, 0x5ba6, 0x5ba4, 0x5ba2, 0x5ba5, + 0x5c01, 0x5c4e, 0x5c4f, 0x5c4d, 0x5c4b, 0x5cd9, 0x5cd2, 0x5df7, + 0x5e1d, 0x5e25, 0x5e1f, 0x5e7d, 0x5ea0, 0x5ea6, 0x5efa, 0x5f08, + 0x5f2d, 0x5f65, 0x5f88, 0x5f85, 0x5f8a, 0x5f8b, 0x5f87, 0x5f8c, + 0x5f89, 0x6012, 0x601d, 0x6020, 0x6025, 0x600e, 0x6028, 0x604d, + 0x6070, 0x6068, 0x6062, 0x6046, 0x6043, 0x606c, 0x606b, 0x606a, + 0x6064, 0x6241, 0x62dc, 0x6316, 0x6309, 0x62fc, 0x62ed, 0x6301, + 0x62ee, 0x62fd, 0x6307, 0x62f1, 0x62f7, + /* 0xac */ + 0x62ef, 0x62ec, 0x62fe, 0x62f4, 0x6311, 0x6302, 0x653f, 0x6545, + 0x65ab, 0x65bd, 0x65e2, 0x6625, 0x662d, 0x6620, 0x6627, 0x662f, + 0x661f, 0x6628, 0x6631, 0x6624, 0x66f7, 0x67ff, 0x67d3, 0x67f1, + 0x67d4, 0x67d0, 0x67ec, 0x67b6, 0x67af, 0x67f5, 0x67e9, 0x67ef, + 0x67c4, 0x67d1, 0x67b4, 0x67da, 0x67e5, 0x67b8, 0x67cf, 0x67de, + 0x67f3, 0x67b0, 0x67d9, 0x67e2, 0x67dd, 0x67d2, 0x6b6a, 0x6b83, + 0x6b86, 0x6bb5, 0x6bd2, 0x6bd7, 0x6c1f, 0x6cc9, 0x6d0b, 0x6d32, + 0x6d2a, 0x6d41, 0x6d25, 0x6d0c, 0x6d31, 0x6d1e, 0x6d17, 0x6d3b, + 0x6d3d, 0x6d3e, 0x6d36, 0x6d1b, 0x6cf5, 0x6d39, 0x6d27, 0x6d38, + 0x6d29, 0x6d2e, 0x6d35, 0x6d0e, 0x6d2b, 0x70ab, 0x70ba, 0x70b3, + 0x70ac, 0x70af, 0x70ad, 0x70b8, 0x70ae, 0x70a4, 0x7230, 0x7272, + 0x726f, 0x7274, 0x72e9, 0x72e0, 0x72e1, 0x73b7, 0x73ca, 0x73bb, + 0x73b2, 0x73cd, 0x73c0, 0x73b3, 0x751a, 0x752d, 0x754f, 0x754c, + 0x754e, 0x754b, 0x75ab, 0x75a4, 0x75a5, 0x75a2, 0x75a3, 0x7678, + 0x7686, 0x7687, 0x7688, 0x76c8, 0x76c6, 0x76c3, 0x76c5, 0x7701, + 0x76f9, 0x76f8, 0x7709, 0x770b, 0x76fe, 0x76fc, 0x7707, 0x77dc, + 0x7802, 0x7814, 0x780c, 0x780d, 0x7946, 0x7949, 0x7948, 0x7947, + 0x79b9, 0x79ba, 0x79d1, 0x79d2, 0x79cb, 0x7a7f, 0x7a81, 0x7aff, + 0x7afd, 0x7c7d, 0x7d02, 0x7d05, 0x7d00, 0x7d09, 0x7d07, 0x7d04, + 0x7d06, 0x7f38, 0x7f8e, 0x7fbf, 0x8004, + /* 0xad */ + 0x8010, 0x800d, 0x8011, 0x8036, 0x80d6, 0x80e5, 0x80da, 0x80c3, + 0x80c4, 0x80cc, 0x80e1, 0x80db, 0x80ce, 0x80de, 0x80e4, 0x80dd, + 0x81f4, 0x8222, 0x82e7, 0x8303, 0x8305, 0x82e3, 0x82db, 0x82e6, + 0x8304, 0x82e5, 0x8302, 0x8309, 0x82d2, 0x82d7, 0x82f1, 0x8301, + 0x82dc, 0x82d4, 0x82d1, 0x82de, 0x82d3, 0x82df, 0x82ef, 0x8306, + 0x8650, 0x8679, 0x867b, 0x867a, 0x884d, 0x886b, 0x8981, 0x89d4, + 0x8a08, 0x8a02, 0x8a03, 0x8c9e, 0x8ca0, 0x8d74, 0x8d73, 0x8db4, + 0x8ecd, 0x8ecc, 0x8ff0, 0x8fe6, 0x8fe2, 0x8fea, 0x8fe5, 0x8fed, + 0x8feb, 0x8fe4, 0x8fe8, 0x90ca, 0x90ce, 0x90c1, 0x90c3, 0x914b, + 0x914a, 0x91cd, 0x9582, 0x9650, 0x964b, 0x964c, 0x964d, 0x9762, + 0x9769, 0x97cb, 0x97ed, 0x97f3, 0x9801, 0x98a8, 0x98db, 0x98df, + 0x9996, 0x9999, 0x4e58, 0x4eb3, 0x500c, 0x500d, 0x5023, 0x4fef, + 0x5026, 0x5025, 0x4ff8, 0x5029, 0x5016, 0x5006, 0x503c, 0x501f, + 0x501a, 0x5012, 0x5011, 0x4ffa, 0x5000, 0x5014, 0x5028, 0x4ff1, + 0x5021, 0x500b, 0x5019, 0x5018, 0x4ff3, 0x4fee, 0x502d, 0x502a, + 0x4ffe, 0x502b, 0x5009, 0x517c, 0x51a4, 0x51a5, 0x51a2, 0x51cd, + 0x51cc, 0x51c6, 0x51cb, 0x5256, 0x525c, 0x5254, 0x525b, 0x525d, + 0x532a, 0x537f, 0x539f, 0x539d, 0x53df, 0x54e8, 0x5510, 0x5501, + 0x5537, 0x54fc, 0x54e5, 0x54f2, 0x5506, 0x54fa, 0x5514, 0x54e9, + 0x54ed, 0x54e1, 0x5509, 0x54ee, 0x54ea, + /* 0xae */ + 0x54e6, 0x5527, 0x5507, 0x54fd, 0x550f, 0x5703, 0x5704, 0x57c2, + 0x57d4, 0x57cb, 0x57c3, 0x5809, 0x590f, 0x5957, 0x5958, 0x595a, + 0x5a11, 0x5a18, 0x5a1c, 0x5a1f, 0x5a1b, 0x5a13, 0x59ec, 0x5a20, + 0x5a23, 0x5a29, 0x5a25, 0x5a0c, 0x5a09, 0x5b6b, 0x5c58, 0x5bb0, + 0x5bb3, 0x5bb6, 0x5bb4, 0x5bae, 0x5bb5, 0x5bb9, 0x5bb8, 0x5c04, + 0x5c51, 0x5c55, 0x5c50, 0x5ced, 0x5cfd, 0x5cfb, 0x5cea, 0x5ce8, + 0x5cf0, 0x5cf6, 0x5d01, 0x5cf4, 0x5dee, 0x5e2d, 0x5e2b, 0x5eab, + 0x5ead, 0x5ea7, 0x5f31, 0x5f92, 0x5f91, 0x5f90, 0x6059, 0x6063, + 0x6065, 0x6050, 0x6055, 0x606d, 0x6069, 0x606f, 0x6084, 0x609f, + 0x609a, 0x608d, 0x6094, 0x608c, 0x6085, 0x6096, 0x6247, 0x62f3, + 0x6308, 0x62ff, 0x634e, 0x633e, 0x632f, 0x6355, 0x6342, 0x6346, + 0x634f, 0x6349, 0x633a, 0x6350, 0x633d, 0x632a, 0x632b, 0x6328, + 0x634d, 0x634c, 0x6548, 0x6549, 0x6599, 0x65c1, 0x65c5, 0x6642, + 0x6649, 0x664f, 0x6643, 0x6652, 0x664c, 0x6645, 0x6641, 0x66f8, + 0x6714, 0x6715, 0x6717, 0x6821, 0x6838, 0x6848, 0x6846, 0x6853, + 0x6839, 0x6842, 0x6854, 0x6829, 0x68b3, 0x6817, 0x684c, 0x6851, + 0x683d, 0x67f4, 0x6850, 0x6840, 0x683c, 0x6843, 0x682a, 0x6845, + 0x6813, 0x6818, 0x6841, 0x6b8a, 0x6b89, 0x6bb7, 0x6c23, 0x6c27, + 0x6c28, 0x6c26, 0x6c24, 0x6cf0, 0x6d6a, 0x6d95, 0x6d88, 0x6d87, + 0x6d66, 0x6d78, 0x6d77, 0x6d59, 0x6d93, + /* 0xaf */ + 0x6d6c, 0x6d89, 0x6d6e, 0x6d5a, 0x6d74, 0x6d69, 0x6d8c, 0x6d8a, + 0x6d79, 0x6d85, 0x6d65, 0x6d94, 0x70ca, 0x70d8, 0x70e4, 0x70d9, + 0x70c8, 0x70cf, 0x7239, 0x7279, 0x72fc, 0x72f9, 0x72fd, 0x72f8, + 0x72f7, 0x7386, 0x73ed, 0x7409, 0x73ee, 0x73e0, 0x73ea, 0x73de, + 0x7554, 0x755d, 0x755c, 0x755a, 0x7559, 0x75be, 0x75c5, 0x75c7, + 0x75b2, 0x75b3, 0x75bd, 0x75bc, 0x75b9, 0x75c2, 0x75b8, 0x768b, + 0x76b0, 0x76ca, 0x76cd, 0x76ce, 0x7729, 0x771f, 0x7720, 0x7728, + 0x77e9, 0x7830, 0x7827, 0x7838, 0x781d, 0x7834, 0x7837, 0x7825, + 0x782d, 0x7820, 0x781f, 0x7832, 0x7955, 0x7950, 0x7960, 0x795f, + 0x7956, 0x795e, 0x795d, 0x7957, 0x795a, 0x79e4, 0x79e3, 0x79e7, + 0x79df, 0x79e6, 0x79e9, 0x79d8, 0x7a84, 0x7a88, 0x7ad9, 0x7b06, + 0x7b11, 0x7c89, 0x7d21, 0x7d17, 0x7d0b, 0x7d0a, 0x7d20, 0x7d22, + 0x7d14, 0x7d10, 0x7d15, 0x7d1a, 0x7d1c, 0x7d0d, 0x7d19, 0x7d1b, + 0x7f3a, 0x7f5f, 0x7f94, 0x7fc5, 0x7fc1, 0x8006, 0x8018, 0x8015, + 0x8019, 0x8017, 0x803d, 0x803f, 0x80f1, 0x8102, 0x80f0, 0x8105, + 0x80ed, 0x80f4, 0x8106, 0x80f8, 0x80f3, 0x8108, 0x80fd, 0x810a, + 0x80fc, 0x80ef, 0x81ed, 0x81ec, 0x8200, 0x8210, 0x822a, 0x822b, + 0x8228, 0x822c, 0x82bb, 0x832b, 0x8352, 0x8354, 0x834a, 0x8338, + 0x8350, 0x8349, 0x8335, 0x8334, 0x834f, 0x8332, 0x8339, 0x8336, + 0x8317, 0x8340, 0x8331, 0x8328, 0x8343, + /* 0xb0 */ + 0x8654, 0x868a, 0x86aa, 0x8693, 0x86a4, 0x86a9, 0x868c, 0x86a3, + 0x869c, 0x8870, 0x8877, 0x8881, 0x8882, 0x887d, 0x8879, 0x8a18, + 0x8a10, 0x8a0e, 0x8a0c, 0x8a15, 0x8a0a, 0x8a17, 0x8a13, 0x8a16, + 0x8a0f, 0x8a11, 0x8c48, 0x8c7a, 0x8c79, 0x8ca1, 0x8ca2, 0x8d77, + 0x8eac, 0x8ed2, 0x8ed4, 0x8ecf, 0x8fb1, 0x9001, 0x9006, 0x8ff7, + 0x9000, 0x8ffa, 0x8ff4, 0x9003, 0x8ffd, 0x9005, 0x8ff8, 0x9095, + 0x90e1, 0x90dd, 0x90e2, 0x9152, 0x914d, 0x914c, 0x91d8, 0x91dd, + 0x91d7, 0x91dc, 0x91d9, 0x9583, 0x9662, 0x9663, 0x9661, 0x965b, + 0x965d, 0x9664, 0x9658, 0x965e, 0x96bb, 0x98e2, 0x99ac, 0x9aa8, + 0x9ad8, 0x9b25, 0x9b32, 0x9b3c, 0x4e7e, 0x507a, 0x507d, 0x505c, + 0x5047, 0x5043, 0x504c, 0x505a, 0x5049, 0x5065, 0x5076, 0x504e, + 0x5055, 0x5075, 0x5074, 0x5077, 0x504f, 0x500f, 0x506f, 0x506d, + 0x515c, 0x5195, 0x51f0, 0x526a, 0x526f, 0x52d2, 0x52d9, 0x52d8, + 0x52d5, 0x5310, 0x530f, 0x5319, 0x533f, 0x5340, 0x533e, 0x53c3, + 0x66fc, 0x5546, 0x556a, 0x5566, 0x5544, 0x555e, 0x5561, 0x5543, + 0x554a, 0x5531, 0x5556, 0x554f, 0x5555, 0x552f, 0x5564, 0x5538, + 0x552e, 0x555c, 0x552c, 0x5563, 0x5533, 0x5541, 0x5557, 0x5708, + 0x570b, 0x5709, 0x57df, 0x5805, 0x580a, 0x5806, 0x57e0, 0x57e4, + 0x57fa, 0x5802, 0x5835, 0x57f7, 0x57f9, 0x5920, 0x5962, 0x5a36, + 0x5a41, 0x5a49, 0x5a66, 0x5a6a, 0x5a40, + /* 0xb1 */ + 0x5a3c, 0x5a62, 0x5a5a, 0x5a46, 0x5a4a, 0x5b70, 0x5bc7, 0x5bc5, + 0x5bc4, 0x5bc2, 0x5bbf, 0x5bc6, 0x5c09, 0x5c08, 0x5c07, 0x5c60, + 0x5c5c, 0x5c5d, 0x5d07, 0x5d06, 0x5d0e, 0x5d1b, 0x5d16, 0x5d22, + 0x5d11, 0x5d29, 0x5d14, 0x5d19, 0x5d24, 0x5d27, 0x5d17, 0x5de2, + 0x5e38, 0x5e36, 0x5e33, 0x5e37, 0x5eb7, 0x5eb8, 0x5eb6, 0x5eb5, + 0x5ebe, 0x5f35, 0x5f37, 0x5f57, 0x5f6c, 0x5f69, 0x5f6b, 0x5f97, + 0x5f99, 0x5f9e, 0x5f98, 0x5fa1, 0x5fa0, 0x5f9c, 0x607f, 0x60a3, + 0x6089, 0x60a0, 0x60a8, 0x60cb, 0x60b4, 0x60e6, 0x60bd, 0x60c5, + 0x60bb, 0x60b5, 0x60dc, 0x60bc, 0x60d8, 0x60d5, 0x60c6, 0x60df, + 0x60b8, 0x60da, 0x60c7, 0x621a, 0x621b, 0x6248, 0x63a0, 0x63a7, + 0x6372, 0x6396, 0x63a2, 0x63a5, 0x6377, 0x6367, 0x6398, 0x63aa, + 0x6371, 0x63a9, 0x6389, 0x6383, 0x639b, 0x636b, 0x63a8, 0x6384, + 0x6388, 0x6399, 0x63a1, 0x63ac, 0x6392, 0x638f, 0x6380, 0x637b, + 0x6369, 0x6368, 0x637a, 0x655d, 0x6556, 0x6551, 0x6559, 0x6557, + 0x555f, 0x654f, 0x6558, 0x6555, 0x6554, 0x659c, 0x659b, 0x65ac, + 0x65cf, 0x65cb, 0x65cc, 0x65ce, 0x665d, 0x665a, 0x6664, 0x6668, + 0x6666, 0x665e, 0x66f9, 0x52d7, 0x671b, 0x6881, 0x68af, 0x68a2, + 0x6893, 0x68b5, 0x687f, 0x6876, 0x68b1, 0x68a7, 0x6897, 0x68b0, + 0x6883, 0x68c4, 0x68ad, 0x6886, 0x6885, 0x6894, 0x689d, 0x68a8, + 0x689f, 0x68a1, 0x6882, 0x6b32, 0x6bba, + /* 0xb2 */ + 0x6beb, 0x6bec, 0x6c2b, 0x6d8e, 0x6dbc, 0x6df3, 0x6dd9, 0x6db2, + 0x6de1, 0x6dcc, 0x6de4, 0x6dfb, 0x6dfa, 0x6e05, 0x6dc7, 0x6dcb, + 0x6daf, 0x6dd1, 0x6dae, 0x6dde, 0x6df9, 0x6db8, 0x6df7, 0x6df5, + 0x6dc5, 0x6dd2, 0x6e1a, 0x6db5, 0x6dda, 0x6deb, 0x6dd8, 0x6dea, + 0x6df1, 0x6dee, 0x6de8, 0x6dc6, 0x6dc4, 0x6daa, 0x6dec, 0x6dbf, + 0x6de6, 0x70f9, 0x7109, 0x710a, 0x70fd, 0x70ef, 0x723d, 0x727d, + 0x7281, 0x731c, 0x731b, 0x7316, 0x7313, 0x7319, 0x7387, 0x7405, + 0x740a, 0x7403, 0x7406, 0x73fe, 0x740d, 0x74e0, 0x74f6, 0x74f7, + 0x751c, 0x7522, 0x7565, 0x7566, 0x7562, 0x7570, 0x758f, 0x75d4, + 0x75d5, 0x75b5, 0x75ca, 0x75cd, 0x768e, 0x76d4, 0x76d2, 0x76db, + 0x7737, 0x773e, 0x773c, 0x7736, 0x7738, 0x773a, 0x786b, 0x7843, + 0x784e, 0x7965, 0x7968, 0x796d, 0x79fb, 0x7a92, 0x7a95, 0x7b20, + 0x7b28, 0x7b1b, 0x7b2c, 0x7b26, 0x7b19, 0x7b1e, 0x7b2e, 0x7c92, + 0x7c97, 0x7c95, 0x7d46, 0x7d43, 0x7d71, 0x7d2e, 0x7d39, 0x7d3c, + 0x7d40, 0x7d30, 0x7d33, 0x7d44, 0x7d2f, 0x7d42, 0x7d32, 0x7d31, + 0x7f3d, 0x7f9e, 0x7f9a, 0x7fcc, 0x7fce, 0x7fd2, 0x801c, 0x804a, + 0x8046, 0x812f, 0x8116, 0x8123, 0x812b, 0x8129, 0x8130, 0x8124, + 0x8202, 0x8235, 0x8237, 0x8236, 0x8239, 0x838e, 0x839e, 0x8398, + 0x8378, 0x83a2, 0x8396, 0x83bd, 0x83ab, 0x8392, 0x838a, 0x8393, + 0x8389, 0x83a0, 0x8377, 0x837b, 0x837c, + /* 0xb3 */ + 0x8386, 0x83a7, 0x8655, 0x5f6a, 0x86c7, 0x86c0, 0x86b6, 0x86c4, + 0x86b5, 0x86c6, 0x86cb, 0x86b1, 0x86af, 0x86c9, 0x8853, 0x889e, + 0x8888, 0x88ab, 0x8892, 0x8896, 0x888d, 0x888b, 0x8993, 0x898f, + 0x8a2a, 0x8a1d, 0x8a23, 0x8a25, 0x8a31, 0x8a2d, 0x8a1f, 0x8a1b, + 0x8a22, 0x8c49, 0x8c5a, 0x8ca9, 0x8cac, 0x8cab, 0x8ca8, 0x8caa, + 0x8ca7, 0x8d67, 0x8d66, 0x8dbe, 0x8dba, 0x8edb, 0x8edf, 0x9019, + 0x900d, 0x901a, 0x9017, 0x9023, 0x901f, 0x901d, 0x9010, 0x9015, + 0x901e, 0x9020, 0x900f, 0x9022, 0x9016, 0x901b, 0x9014, 0x90e8, + 0x90ed, 0x90fd, 0x9157, 0x91ce, 0x91f5, 0x91e6, 0x91e3, 0x91e7, + 0x91ed, 0x91e9, 0x9589, 0x966a, 0x9675, 0x9673, 0x9678, 0x9670, + 0x9674, 0x9676, 0x9677, 0x966c, 0x96c0, 0x96ea, 0x96e9, 0x7ae0, + 0x7adf, 0x9802, 0x9803, 0x9b5a, 0x9ce5, 0x9e75, 0x9e7f, 0x9ea5, + 0x9ebb, 0x50a2, 0x508d, 0x5085, 0x5099, 0x5091, 0x5080, 0x5096, + 0x5098, 0x509a, 0x6700, 0x51f1, 0x5272, 0x5274, 0x5275, 0x5269, + 0x52de, 0x52dd, 0x52db, 0x535a, 0x53a5, 0x557b, 0x5580, 0x55a7, + 0x557c, 0x558a, 0x559d, 0x5598, 0x5582, 0x559c, 0x55aa, 0x5594, + 0x5587, 0x558b, 0x5583, 0x55b3, 0x55ae, 0x559f, 0x553e, 0x55b2, + 0x559a, 0x55bb, 0x55ac, 0x55b1, 0x557e, 0x5589, 0x55ab, 0x5599, + 0x570d, 0x582f, 0x582a, 0x5834, 0x5824, 0x5830, 0x5831, 0x5821, + 0x581d, 0x5820, 0x58f9, 0x58fa, 0x5960, + /* 0xb4 */ + 0x5a77, 0x5a9a, 0x5a7f, 0x5a92, 0x5a9b, 0x5aa7, 0x5b73, 0x5b71, + 0x5bd2, 0x5bcc, 0x5bd3, 0x5bd0, 0x5c0a, 0x5c0b, 0x5c31, 0x5d4c, + 0x5d50, 0x5d34, 0x5d47, 0x5dfd, 0x5e45, 0x5e3d, 0x5e40, 0x5e43, + 0x5e7e, 0x5eca, 0x5ec1, 0x5ec2, 0x5ec4, 0x5f3c, 0x5f6d, 0x5fa9, + 0x5faa, 0x5fa8, 0x60d1, 0x60e1, 0x60b2, 0x60b6, 0x60e0, 0x611c, + 0x6123, 0x60fa, 0x6115, 0x60f0, 0x60fb, 0x60f4, 0x6168, 0x60f1, + 0x610e, 0x60f6, 0x6109, 0x6100, 0x6112, 0x621f, 0x6249, 0x63a3, + 0x638c, 0x63cf, 0x63c0, 0x63e9, 0x63c9, 0x63c6, 0x63cd, 0x63d2, + 0x63e3, 0x63d0, 0x63e1, 0x63d6, 0x63ed, 0x63ee, 0x6376, 0x63f4, + 0x63ea, 0x63db, 0x6452, 0x63da, 0x63f9, 0x655e, 0x6566, 0x6562, + 0x6563, 0x6591, 0x6590, 0x65af, 0x666e, 0x6670, 0x6674, 0x6676, + 0x666f, 0x6691, 0x667a, 0x667e, 0x6677, 0x66fe, 0x66ff, 0x671f, + 0x671d, 0x68fa, 0x68d5, 0x68e0, 0x68d8, 0x68d7, 0x6905, 0x68df, + 0x68f5, 0x68ee, 0x68e7, 0x68f9, 0x68d2, 0x68f2, 0x68e3, 0x68cb, + 0x68cd, 0x690d, 0x6912, 0x690e, 0x68c9, 0x68da, 0x696e, 0x68fb, + 0x6b3e, 0x6b3a, 0x6b3d, 0x6b98, 0x6b96, 0x6bbc, 0x6bef, 0x6c2e, + 0x6c2f, 0x6c2c, 0x6e2f, 0x6e38, 0x6e54, 0x6e21, 0x6e32, 0x6e67, + 0x6e4a, 0x6e20, 0x6e25, 0x6e23, 0x6e1b, 0x6e5b, 0x6e58, 0x6e24, + 0x6e56, 0x6e6e, 0x6e2d, 0x6e26, 0x6e6f, 0x6e34, 0x6e4d, 0x6e3a, + 0x6e2c, 0x6e43, 0x6e1d, 0x6e3e, 0x6ecb, + /* 0xb5 */ + 0x6e89, 0x6e19, 0x6e4e, 0x6e63, 0x6e44, 0x6e72, 0x6e69, 0x6e5f, + 0x7119, 0x711a, 0x7126, 0x7130, 0x7121, 0x7136, 0x716e, 0x711c, + 0x724c, 0x7284, 0x7280, 0x7336, 0x7325, 0x7334, 0x7329, 0x743a, + 0x742a, 0x7433, 0x7422, 0x7425, 0x7435, 0x7436, 0x7434, 0x742f, + 0x741b, 0x7426, 0x7428, 0x7525, 0x7526, 0x756b, 0x756a, 0x75e2, + 0x75db, 0x75e3, 0x75d9, 0x75d8, 0x75de, 0x75e0, 0x767b, 0x767c, + 0x7696, 0x7693, 0x76b4, 0x76dc, 0x774f, 0x77ed, 0x785d, 0x786c, + 0x786f, 0x7a0d, 0x7a08, 0x7a0b, 0x7a05, 0x7a00, 0x7a98, 0x7a97, + 0x7a96, 0x7ae5, 0x7ae3, 0x7b49, 0x7b56, 0x7b46, 0x7b50, 0x7b52, + 0x7b54, 0x7b4d, 0x7b4b, 0x7b4f, 0x7b51, 0x7c9f, 0x7ca5, 0x7d5e, + 0x7d50, 0x7d68, 0x7d55, 0x7d2b, 0x7d6e, 0x7d72, 0x7d61, 0x7d66, + 0x7d62, 0x7d70, 0x7d73, 0x5584, 0x7fd4, 0x7fd5, 0x800b, 0x8052, + 0x8085, 0x8155, 0x8154, 0x814b, 0x8151, 0x814e, 0x8139, 0x8146, + 0x813e, 0x814c, 0x8153, 0x8174, 0x8212, 0x821c, 0x83e9, 0x8403, + 0x83f8, 0x840d, 0x83e0, 0x83c5, 0x840b, 0x83c1, 0x83ef, 0x83f1, + 0x83f4, 0x8457, 0x840a, 0x83f0, 0x840c, 0x83cc, 0x83fd, 0x83f2, + 0x83ca, 0x8438, 0x840e, 0x8404, 0x83dc, 0x8407, 0x83d4, 0x83df, + 0x865b, 0x86df, 0x86d9, 0x86ed, 0x86d4, 0x86db, 0x86e4, 0x86d0, + 0x86de, 0x8857, 0x88c1, 0x88c2, 0x88b1, 0x8983, 0x8996, 0x8a3b, + 0x8a60, 0x8a55, 0x8a5e, 0x8a3c, 0x8a41, + /* 0xb6 */ + 0x8a54, 0x8a5b, 0x8a50, 0x8a46, 0x8a34, 0x8a3a, 0x8a36, 0x8a56, + 0x8c61, 0x8c82, 0x8caf, 0x8cbc, 0x8cb3, 0x8cbd, 0x8cc1, 0x8cbb, + 0x8cc0, 0x8cb4, 0x8cb7, 0x8cb6, 0x8cbf, 0x8cb8, 0x8d8a, 0x8d85, + 0x8d81, 0x8dce, 0x8ddd, 0x8dcb, 0x8dda, 0x8dd1, 0x8dcc, 0x8ddb, + 0x8dc6, 0x8efb, 0x8ef8, 0x8efc, 0x8f9c, 0x902e, 0x9035, 0x9031, + 0x9038, 0x9032, 0x9036, 0x9102, 0x90f5, 0x9109, 0x90fe, 0x9163, + 0x9165, 0x91cf, 0x9214, 0x9215, 0x9223, 0x9209, 0x921e, 0x920d, + 0x9210, 0x9207, 0x9211, 0x9594, 0x958f, 0x958b, 0x9591, 0x9593, + 0x9592, 0x958e, 0x968a, 0x968e, 0x968b, 0x967d, 0x9685, 0x9686, + 0x968d, 0x9672, 0x9684, 0x96c1, 0x96c5, 0x96c4, 0x96c6, 0x96c7, + 0x96ef, 0x96f2, 0x97cc, 0x9805, 0x9806, 0x9808, 0x98e7, 0x98ea, + 0x98ef, 0x98e9, 0x98f2, 0x98ed, 0x99ae, 0x99ad, 0x9ec3, 0x9ecd, + 0x9ed1, 0x4e82, 0x50ad, 0x50b5, 0x50b2, 0x50b3, 0x50c5, 0x50be, + 0x50ac, 0x50b7, 0x50bb, 0x50af, 0x50c7, 0x527f, 0x5277, 0x527d, + 0x52df, 0x52e6, 0x52e4, 0x52e2, 0x52e3, 0x532f, 0x55df, 0x55e8, + 0x55d3, 0x55e6, 0x55ce, 0x55dc, 0x55c7, 0x55d1, 0x55e3, 0x55e4, + 0x55ef, 0x55da, 0x55e1, 0x55c5, 0x55c6, 0x55e5, 0x55c9, 0x5712, + 0x5713, 0x585e, 0x5851, 0x5858, 0x5857, 0x585a, 0x5854, 0x586b, + 0x584c, 0x586d, 0x584a, 0x5862, 0x5852, 0x584b, 0x5967, 0x5ac1, + 0x5ac9, 0x5acc, 0x5abe, 0x5abd, 0x5abc, + /* 0xb7 */ + 0x5ab3, 0x5ac2, 0x5ab2, 0x5d69, 0x5d6f, 0x5e4c, 0x5e79, 0x5ec9, + 0x5ec8, 0x5f12, 0x5f59, 0x5fac, 0x5fae, 0x611a, 0x610f, 0x6148, + 0x611f, 0x60f3, 0x611b, 0x60f9, 0x6101, 0x6108, 0x614e, 0x614c, + 0x6144, 0x614d, 0x613e, 0x6134, 0x6127, 0x610d, 0x6106, 0x6137, + 0x6221, 0x6222, 0x6413, 0x643e, 0x641e, 0x642a, 0x642d, 0x643d, + 0x642c, 0x640f, 0x641c, 0x6414, 0x640d, 0x6436, 0x6416, 0x6417, + 0x6406, 0x656c, 0x659f, 0x65b0, 0x6697, 0x6689, 0x6687, 0x6688, + 0x6696, 0x6684, 0x6698, 0x668d, 0x6703, 0x6994, 0x696d, 0x695a, + 0x6977, 0x6960, 0x6954, 0x6975, 0x6930, 0x6982, 0x694a, 0x6968, + 0x696b, 0x695e, 0x6953, 0x6979, 0x6986, 0x695d, 0x6963, 0x695b, + 0x6b47, 0x6b72, 0x6bc0, 0x6bbf, 0x6bd3, 0x6bfd, 0x6ea2, 0x6eaf, + 0x6ed3, 0x6eb6, 0x6ec2, 0x6e90, 0x6e9d, 0x6ec7, 0x6ec5, 0x6ea5, + 0x6e98, 0x6ebc, 0x6eba, 0x6eab, 0x6ed1, 0x6e96, 0x6e9c, 0x6ec4, + 0x6ed4, 0x6eaa, 0x6ea7, 0x6eb4, 0x714e, 0x7159, 0x7169, 0x7164, + 0x7149, 0x7167, 0x715c, 0x716c, 0x7166, 0x714c, 0x7165, 0x715e, + 0x7146, 0x7168, 0x7156, 0x723a, 0x7252, 0x7337, 0x7345, 0x733f, + 0x733e, 0x746f, 0x745a, 0x7455, 0x745f, 0x745e, 0x7441, 0x743f, + 0x7459, 0x745b, 0x745c, 0x7576, 0x7578, 0x7600, 0x75f0, 0x7601, + 0x75f2, 0x75f1, 0x75fa, 0x75ff, 0x75f4, 0x75f3, 0x76de, 0x76df, + 0x775b, 0x776b, 0x7766, 0x775e, 0x7763, + /* 0xb8 */ + 0x7779, 0x776a, 0x776c, 0x775c, 0x7765, 0x7768, 0x7762, 0x77ee, + 0x788e, 0x78b0, 0x7897, 0x7898, 0x788c, 0x7889, 0x787c, 0x7891, + 0x7893, 0x787f, 0x797a, 0x797f, 0x7981, 0x842c, 0x79bd, 0x7a1c, + 0x7a1a, 0x7a20, 0x7a14, 0x7a1f, 0x7a1e, 0x7a9f, 0x7aa0, 0x7b77, + 0x7bc0, 0x7b60, 0x7b6e, 0x7b67, 0x7cb1, 0x7cb3, 0x7cb5, 0x7d93, + 0x7d79, 0x7d91, 0x7d81, 0x7d8f, 0x7d5b, 0x7f6e, 0x7f69, 0x7f6a, + 0x7f72, 0x7fa9, 0x7fa8, 0x7fa4, 0x8056, 0x8058, 0x8086, 0x8084, + 0x8171, 0x8170, 0x8178, 0x8165, 0x816e, 0x8173, 0x816b, 0x8179, + 0x817a, 0x8166, 0x8205, 0x8247, 0x8482, 0x8477, 0x843d, 0x8431, + 0x8475, 0x8466, 0x846b, 0x8449, 0x846c, 0x845b, 0x843c, 0x8435, + 0x8461, 0x8463, 0x8469, 0x846d, 0x8446, 0x865e, 0x865c, 0x865f, + 0x86f9, 0x8713, 0x8708, 0x8707, 0x8700, 0x86fe, 0x86fb, 0x8702, + 0x8703, 0x8706, 0x870a, 0x8859, 0x88df, 0x88d4, 0x88d9, 0x88dc, + 0x88d8, 0x88dd, 0x88e1, 0x88ca, 0x88d5, 0x88d2, 0x899c, 0x89e3, + 0x8a6b, 0x8a72, 0x8a73, 0x8a66, 0x8a69, 0x8a70, 0x8a87, 0x8a7c, + 0x8a63, 0x8aa0, 0x8a71, 0x8a85, 0x8a6d, 0x8a62, 0x8a6e, 0x8a6c, + 0x8a79, 0x8a7b, 0x8a3e, 0x8a68, 0x8c62, 0x8c8a, 0x8c89, 0x8cca, + 0x8cc7, 0x8cc8, 0x8cc4, 0x8cb2, 0x8cc3, 0x8cc2, 0x8cc5, 0x8de1, + 0x8ddf, 0x8de8, 0x8def, 0x8df3, 0x8dfa, 0x8dea, 0x8de4, 0x8de6, + 0x8eb2, 0x8f03, 0x8f09, 0x8efe, 0x8f0a, + /* 0xb9 */ + 0x8f9f, 0x8fb2, 0x904b, 0x904a, 0x9053, 0x9042, 0x9054, 0x903c, + 0x9055, 0x9050, 0x9047, 0x904f, 0x904e, 0x904d, 0x9051, 0x903e, + 0x9041, 0x9112, 0x9117, 0x916c, 0x916a, 0x9169, 0x91c9, 0x9237, + 0x9257, 0x9238, 0x923d, 0x9240, 0x923e, 0x925b, 0x924b, 0x9264, + 0x9251, 0x9234, 0x9249, 0x924d, 0x9245, 0x9239, 0x923f, 0x925a, + 0x9598, 0x9698, 0x9694, 0x9695, 0x96cd, 0x96cb, 0x96c9, 0x96ca, + 0x96f7, 0x96fb, 0x96f9, 0x96f6, 0x9756, 0x9774, 0x9776, 0x9810, + 0x9811, 0x9813, 0x980a, 0x9812, 0x980c, 0x98fc, 0x98f4, 0x98fd, + 0x98fe, 0x99b3, 0x99b1, 0x99b4, 0x9ae1, 0x9ce9, 0x9e82, 0x9f0e, + 0x9f13, 0x9f20, 0x50e7, 0x50ee, 0x50e5, 0x50d6, 0x50ed, 0x50da, + 0x50d5, 0x50cf, 0x50d1, 0x50f1, 0x50ce, 0x50e9, 0x5162, 0x51f3, + 0x5283, 0x5282, 0x5331, 0x53ad, 0x55fe, 0x5600, 0x561b, 0x5617, + 0x55fd, 0x5614, 0x5606, 0x5609, 0x560d, 0x560e, 0x55f7, 0x5616, + 0x561f, 0x5608, 0x5610, 0x55f6, 0x5718, 0x5716, 0x5875, 0x587e, + 0x5883, 0x5893, 0x588a, 0x5879, 0x5885, 0x587d, 0x58fd, 0x5925, + 0x5922, 0x5924, 0x596a, 0x5969, 0x5ae1, 0x5ae6, 0x5ae9, 0x5ad7, + 0x5ad6, 0x5ad8, 0x5ae3, 0x5b75, 0x5bde, 0x5be7, 0x5be1, 0x5be5, + 0x5be6, 0x5be8, 0x5be2, 0x5be4, 0x5bdf, 0x5c0d, 0x5c62, 0x5d84, + 0x5d87, 0x5e5b, 0x5e63, 0x5e55, 0x5e57, 0x5e54, 0x5ed3, 0x5ed6, + 0x5f0a, 0x5f46, 0x5f70, 0x5fb9, 0x6147, + /* 0xba */ + 0x613f, 0x614b, 0x6177, 0x6162, 0x6163, 0x615f, 0x615a, 0x6158, + 0x6175, 0x622a, 0x6487, 0x6458, 0x6454, 0x64a4, 0x6478, 0x645f, + 0x647a, 0x6451, 0x6467, 0x6434, 0x646d, 0x647b, 0x6572, 0x65a1, + 0x65d7, 0x65d6, 0x66a2, 0x66a8, 0x669d, 0x699c, 0x69a8, 0x6995, + 0x69c1, 0x69ae, 0x69d3, 0x69cb, 0x699b, 0x69b7, 0x69bb, 0x69ab, + 0x69b4, 0x69d0, 0x69cd, 0x69ad, 0x69cc, 0x69a6, 0x69c3, 0x69a3, + 0x6b49, 0x6b4c, 0x6c33, 0x6f33, 0x6f14, 0x6efe, 0x6f13, 0x6ef4, + 0x6f29, 0x6f3e, 0x6f20, 0x6f2c, 0x6f0f, 0x6f02, 0x6f22, 0x6eff, + 0x6eef, 0x6f06, 0x6f31, 0x6f38, 0x6f32, 0x6f23, 0x6f15, 0x6f2b, + 0x6f2f, 0x6f88, 0x6f2a, 0x6eec, 0x6f01, 0x6ef2, 0x6ecc, 0x6ef7, + 0x7194, 0x7199, 0x717d, 0x718a, 0x7184, 0x7192, 0x723e, 0x7292, + 0x7296, 0x7344, 0x7350, 0x7464, 0x7463, 0x746a, 0x7470, 0x746d, + 0x7504, 0x7591, 0x7627, 0x760d, 0x760b, 0x7609, 0x7613, 0x76e1, + 0x76e3, 0x7784, 0x777d, 0x777f, 0x7761, 0x78c1, 0x789f, 0x78a7, + 0x78b3, 0x78a9, 0x78a3, 0x798e, 0x798f, 0x798d, 0x7a2e, 0x7a31, + 0x7aaa, 0x7aa9, 0x7aed, 0x7aef, 0x7ba1, 0x7b95, 0x7b8b, 0x7b75, + 0x7b97, 0x7b9d, 0x7b94, 0x7b8f, 0x7bb8, 0x7b87, 0x7b84, 0x7cb9, + 0x7cbd, 0x7cbe, 0x7dbb, 0x7db0, 0x7d9c, 0x7dbd, 0x7dbe, 0x7da0, + 0x7dca, 0x7db4, 0x7db2, 0x7db1, 0x7dba, 0x7da2, 0x7dbf, 0x7db5, + 0x7db8, 0x7dad, 0x7dd2, 0x7dc7, 0x7dac, + /* 0xbb */ + 0x7f70, 0x7fe0, 0x7fe1, 0x7fdf, 0x805e, 0x805a, 0x8087, 0x8150, + 0x8180, 0x818f, 0x8188, 0x818a, 0x817f, 0x8182, 0x81e7, 0x81fa, + 0x8207, 0x8214, 0x821e, 0x824b, 0x84c9, 0x84bf, 0x84c6, 0x84c4, + 0x8499, 0x849e, 0x84b2, 0x849c, 0x84cb, 0x84b8, 0x84c0, 0x84d3, + 0x8490, 0x84bc, 0x84d1, 0x84ca, 0x873f, 0x871c, 0x873b, 0x8722, + 0x8725, 0x8734, 0x8718, 0x8755, 0x8737, 0x8729, 0x88f3, 0x8902, + 0x88f4, 0x88f9, 0x88f8, 0x88fd, 0x88e8, 0x891a, 0x88ef, 0x8aa6, + 0x8a8c, 0x8a9e, 0x8aa3, 0x8a8d, 0x8aa1, 0x8a93, 0x8aa4, 0x8aaa, + 0x8aa5, 0x8aa8, 0x8a98, 0x8a91, 0x8a9a, 0x8aa7, 0x8c6a, 0x8c8d, + 0x8c8c, 0x8cd3, 0x8cd1, 0x8cd2, 0x8d6b, 0x8d99, 0x8d95, 0x8dfc, + 0x8f14, 0x8f12, 0x8f15, 0x8f13, 0x8fa3, 0x9060, 0x9058, 0x905c, + 0x9063, 0x9059, 0x905e, 0x9062, 0x905d, 0x905b, 0x9119, 0x9118, + 0x911e, 0x9175, 0x9178, 0x9177, 0x9174, 0x9278, 0x9280, 0x9285, + 0x9298, 0x9296, 0x927b, 0x9293, 0x929c, 0x92a8, 0x927c, 0x9291, + 0x95a1, 0x95a8, 0x95a9, 0x95a3, 0x95a5, 0x95a4, 0x9699, 0x969c, + 0x969b, 0x96cc, 0x96d2, 0x9700, 0x977c, 0x9785, 0x97f6, 0x9817, + 0x9818, 0x98af, 0x98b1, 0x9903, 0x9905, 0x990c, 0x9909, 0x99c1, + 0x9aaf, 0x9ab0, 0x9ae6, 0x9b41, 0x9b42, 0x9cf4, 0x9cf6, 0x9cf3, + 0x9ebc, 0x9f3b, 0x9f4a, 0x5104, 0x5100, 0x50fb, 0x50f5, 0x50f9, + 0x5102, 0x5108, 0x5109, 0x5105, 0x51dc, + /* 0xbc */ + 0x5287, 0x5288, 0x5289, 0x528d, 0x528a, 0x52f0, 0x53b2, 0x562e, + 0x563b, 0x5639, 0x5632, 0x563f, 0x5634, 0x5629, 0x5653, 0x564e, + 0x5657, 0x5674, 0x5636, 0x562f, 0x5630, 0x5880, 0x589f, 0x589e, + 0x58b3, 0x589c, 0x58ae, 0x58a9, 0x58a6, 0x596d, 0x5b09, 0x5afb, + 0x5b0b, 0x5af5, 0x5b0c, 0x5b08, 0x5bee, 0x5bec, 0x5be9, 0x5beb, + 0x5c64, 0x5c65, 0x5d9d, 0x5d94, 0x5e62, 0x5e5f, 0x5e61, 0x5ee2, + 0x5eda, 0x5edf, 0x5edd, 0x5ee3, 0x5ee0, 0x5f48, 0x5f71, 0x5fb7, + 0x5fb5, 0x6176, 0x6167, 0x616e, 0x615d, 0x6155, 0x6182, 0x617c, + 0x6170, 0x616b, 0x617e, 0x61a7, 0x6190, 0x61ab, 0x618e, 0x61ac, + 0x619a, 0x61a4, 0x6194, 0x61ae, 0x622e, 0x6469, 0x646f, 0x6479, + 0x649e, 0x64b2, 0x6488, 0x6490, 0x64b0, 0x64a5, 0x6493, 0x6495, + 0x64a9, 0x6492, 0x64ae, 0x64ad, 0x64ab, 0x649a, 0x64ac, 0x6499, + 0x64a2, 0x64b3, 0x6575, 0x6577, 0x6578, 0x66ae, 0x66ab, 0x66b4, + 0x66b1, 0x6a23, 0x6a1f, 0x69e8, 0x6a01, 0x6a1e, 0x6a19, 0x69fd, + 0x6a21, 0x6a13, 0x6a0a, 0x69f3, 0x6a02, 0x6a05, 0x69ed, 0x6a11, + 0x6b50, 0x6b4e, 0x6ba4, 0x6bc5, 0x6bc6, 0x6f3f, 0x6f7c, 0x6f84, + 0x6f51, 0x6f66, 0x6f54, 0x6f86, 0x6f6d, 0x6f5b, 0x6f78, 0x6f6e, + 0x6f8e, 0x6f7a, 0x6f70, 0x6f64, 0x6f97, 0x6f58, 0x6ed5, 0x6f6f, + 0x6f60, 0x6f5f, 0x719f, 0x71ac, 0x71b1, 0x71a8, 0x7256, 0x729b, + 0x734e, 0x7357, 0x7469, 0x748b, 0x7483, + /* 0xbd */ + 0x747e, 0x7480, 0x757f, 0x7620, 0x7629, 0x761f, 0x7624, 0x7626, + 0x7621, 0x7622, 0x769a, 0x76ba, 0x76e4, 0x778e, 0x7787, 0x778c, + 0x7791, 0x778b, 0x78cb, 0x78c5, 0x78ba, 0x78ca, 0x78be, 0x78d5, + 0x78bc, 0x78d0, 0x7a3f, 0x7a3c, 0x7a40, 0x7a3d, 0x7a37, 0x7a3b, + 0x7aaf, 0x7aae, 0x7bad, 0x7bb1, 0x7bc4, 0x7bb4, 0x7bc6, 0x7bc7, + 0x7bc1, 0x7ba0, 0x7bcc, 0x7cca, 0x7de0, 0x7df4, 0x7def, 0x7dfb, + 0x7dd8, 0x7dec, 0x7ddd, 0x7de8, 0x7de3, 0x7dda, 0x7dde, 0x7de9, + 0x7d9e, 0x7dd9, 0x7df2, 0x7df9, 0x7f75, 0x7f77, 0x7faf, 0x7fe9, + 0x8026, 0x819b, 0x819c, 0x819d, 0x81a0, 0x819a, 0x8198, 0x8517, + 0x853d, 0x851a, 0x84ee, 0x852c, 0x852d, 0x8513, 0x8511, 0x8523, + 0x8521, 0x8514, 0x84ec, 0x8525, 0x84ff, 0x8506, 0x8782, 0x8774, + 0x8776, 0x8760, 0x8766, 0x8778, 0x8768, 0x8759, 0x8757, 0x874c, + 0x8753, 0x885b, 0x885d, 0x8910, 0x8907, 0x8912, 0x8913, 0x8915, + 0x890a, 0x8abc, 0x8ad2, 0x8ac7, 0x8ac4, 0x8a95, 0x8acb, 0x8af8, + 0x8ab2, 0x8ac9, 0x8ac2, 0x8abf, 0x8ab0, 0x8ad6, 0x8acd, 0x8ab6, + 0x8ab9, 0x8adb, 0x8c4c, 0x8c4e, 0x8c6c, 0x8ce0, 0x8cde, 0x8ce6, + 0x8ce4, 0x8cec, 0x8ced, 0x8ce2, 0x8ce3, 0x8cdc, 0x8cea, 0x8ce1, + 0x8d6d, 0x8d9f, 0x8da3, 0x8e2b, 0x8e10, 0x8e1d, 0x8e22, 0x8e0f, + 0x8e29, 0x8e1f, 0x8e21, 0x8e1e, 0x8eba, 0x8f1d, 0x8f1b, 0x8f1f, + 0x8f29, 0x8f26, 0x8f2a, 0x8f1c, 0x8f1e, + /* 0xbe */ + 0x8f25, 0x9069, 0x906e, 0x9068, 0x906d, 0x9077, 0x9130, 0x912d, + 0x9127, 0x9131, 0x9187, 0x9189, 0x918b, 0x9183, 0x92c5, 0x92bb, + 0x92b7, 0x92ea, 0x92ac, 0x92e4, 0x92c1, 0x92b3, 0x92bc, 0x92d2, + 0x92c7, 0x92f0, 0x92b2, 0x95ad, 0x95b1, 0x9704, 0x9706, 0x9707, + 0x9709, 0x9760, 0x978d, 0x978b, 0x978f, 0x9821, 0x982b, 0x981c, + 0x98b3, 0x990a, 0x9913, 0x9912, 0x9918, 0x99dd, 0x99d0, 0x99df, + 0x99db, 0x99d1, 0x99d5, 0x99d2, 0x99d9, 0x9ab7, 0x9aee, 0x9aef, + 0x9b27, 0x9b45, 0x9b44, 0x9b77, 0x9b6f, 0x9d06, 0x9d09, 0x9d03, + 0x9ea9, 0x9ebe, 0x9ece, 0x58a8, 0x9f52, 0x5112, 0x5118, 0x5114, + 0x5110, 0x5115, 0x5180, 0x51aa, 0x51dd, 0x5291, 0x5293, 0x52f3, + 0x5659, 0x566b, 0x5679, 0x5669, 0x5664, 0x5678, 0x566a, 0x5668, + 0x5665, 0x5671, 0x566f, 0x566c, 0x5662, 0x5676, 0x58c1, 0x58be, + 0x58c7, 0x58c5, 0x596e, 0x5b1d, 0x5b34, 0x5b78, 0x5bf0, 0x5c0e, + 0x5f4a, 0x61b2, 0x6191, 0x61a9, 0x618a, 0x61cd, 0x61b6, 0x61be, + 0x61ca, 0x61c8, 0x6230, 0x64c5, 0x64c1, 0x64cb, 0x64bb, 0x64bc, + 0x64da, 0x64c4, 0x64c7, 0x64c2, 0x64cd, 0x64bf, 0x64d2, 0x64d4, + 0x64be, 0x6574, 0x66c6, 0x66c9, 0x66b9, 0x66c4, 0x66c7, 0x66b8, + 0x6a3d, 0x6a38, 0x6a3a, 0x6a59, 0x6a6b, 0x6a58, 0x6a39, 0x6a44, + 0x6a62, 0x6a61, 0x6a4b, 0x6a47, 0x6a35, 0x6a5f, 0x6a48, 0x6b59, + 0x6b77, 0x6c05, 0x6fc2, 0x6fb1, 0x6fa1, + /* 0xbf */ + 0x6fc3, 0x6fa4, 0x6fc1, 0x6fa7, 0x6fb3, 0x6fc0, 0x6fb9, 0x6fb6, + 0x6fa6, 0x6fa0, 0x6fb4, 0x71be, 0x71c9, 0x71d0, 0x71d2, 0x71c8, + 0x71d5, 0x71b9, 0x71ce, 0x71d9, 0x71dc, 0x71c3, 0x71c4, 0x7368, + 0x749c, 0x74a3, 0x7498, 0x749f, 0x749e, 0x74e2, 0x750c, 0x750d, + 0x7634, 0x7638, 0x763a, 0x76e7, 0x76e5, 0x77a0, 0x779e, 0x779f, + 0x77a5, 0x78e8, 0x78da, 0x78ec, 0x78e7, 0x79a6, 0x7a4d, 0x7a4e, + 0x7a46, 0x7a4c, 0x7a4b, 0x7aba, 0x7bd9, 0x7c11, 0x7bc9, 0x7be4, + 0x7bdb, 0x7be1, 0x7be9, 0x7be6, 0x7cd5, 0x7cd6, 0x7e0a, 0x7e11, + 0x7e08, 0x7e1b, 0x7e23, 0x7e1e, 0x7e1d, 0x7e09, 0x7e10, 0x7f79, + 0x7fb2, 0x7ff0, 0x7ff1, 0x7fee, 0x8028, 0x81b3, 0x81a9, 0x81a8, + 0x81fb, 0x8208, 0x8258, 0x8259, 0x854a, 0x8559, 0x8548, 0x8568, + 0x8569, 0x8543, 0x8549, 0x856d, 0x856a, 0x855e, 0x8783, 0x879f, + 0x879e, 0x87a2, 0x878d, 0x8861, 0x892a, 0x8932, 0x8925, 0x892b, + 0x8921, 0x89aa, 0x89a6, 0x8ae6, 0x8afa, 0x8aeb, 0x8af1, 0x8b00, + 0x8adc, 0x8ae7, 0x8aee, 0x8afe, 0x8b01, 0x8b02, 0x8af7, 0x8aed, + 0x8af3, 0x8af6, 0x8afc, 0x8c6b, 0x8c6d, 0x8c93, 0x8cf4, 0x8e44, + 0x8e31, 0x8e34, 0x8e42, 0x8e39, 0x8e35, 0x8f3b, 0x8f2f, 0x8f38, + 0x8f33, 0x8fa8, 0x8fa6, 0x9075, 0x9074, 0x9078, 0x9072, 0x907c, + 0x907a, 0x9134, 0x9192, 0x9320, 0x9336, 0x92f8, 0x9333, 0x932f, + 0x9322, 0x92fc, 0x932b, 0x9304, 0x931a, + /* 0xc0 */ + 0x9310, 0x9326, 0x9321, 0x9315, 0x932e, 0x9319, 0x95bb, 0x96a7, + 0x96a8, 0x96aa, 0x96d5, 0x970e, 0x9711, 0x9716, 0x970d, 0x9713, + 0x970f, 0x975b, 0x975c, 0x9766, 0x9798, 0x9830, 0x9838, 0x983b, + 0x9837, 0x982d, 0x9839, 0x9824, 0x9910, 0x9928, 0x991e, 0x991b, + 0x9921, 0x991a, 0x99ed, 0x99e2, 0x99f1, 0x9ab8, 0x9abc, 0x9afb, + 0x9aed, 0x9b28, 0x9b91, 0x9d15, 0x9d23, 0x9d26, 0x9d28, 0x9d12, + 0x9d1b, 0x9ed8, 0x9ed4, 0x9f8d, 0x9f9c, 0x512a, 0x511f, 0x5121, + 0x5132, 0x52f5, 0x568e, 0x5680, 0x5690, 0x5685, 0x5687, 0x568f, + 0x58d5, 0x58d3, 0x58d1, 0x58ce, 0x5b30, 0x5b2a, 0x5b24, 0x5b7a, + 0x5c37, 0x5c68, 0x5dbc, 0x5dba, 0x5dbd, 0x5db8, 0x5e6b, 0x5f4c, + 0x5fbd, 0x61c9, 0x61c2, 0x61c7, 0x61e6, 0x61cb, 0x6232, 0x6234, + 0x64ce, 0x64ca, 0x64d8, 0x64e0, 0x64f0, 0x64e6, 0x64ec, 0x64f1, + 0x64e2, 0x64ed, 0x6582, 0x6583, 0x66d9, 0x66d6, 0x6a80, 0x6a94, + 0x6a84, 0x6aa2, 0x6a9c, 0x6adb, 0x6aa3, 0x6a7e, 0x6a97, 0x6a90, + 0x6aa0, 0x6b5c, 0x6bae, 0x6bda, 0x6c08, 0x6fd8, 0x6ff1, 0x6fdf, + 0x6fe0, 0x6fdb, 0x6fe4, 0x6feb, 0x6fef, 0x6f80, 0x6fec, 0x6fe1, + 0x6fe9, 0x6fd5, 0x6fee, 0x6ff0, 0x71e7, 0x71df, 0x71ee, 0x71e6, + 0x71e5, 0x71ed, 0x71ec, 0x71f4, 0x71e0, 0x7235, 0x7246, 0x7370, + 0x7372, 0x74a9, 0x74b0, 0x74a6, 0x74a8, 0x7646, 0x7642, 0x764c, + 0x76ea, 0x77b3, 0x77aa, 0x77b0, 0x77ac, + /* 0xc1 */ + 0x77a7, 0x77ad, 0x77ef, 0x78f7, 0x78fa, 0x78f4, 0x78ef, 0x7901, + 0x79a7, 0x79aa, 0x7a57, 0x7abf, 0x7c07, 0x7c0d, 0x7bfe, 0x7bf7, + 0x7c0c, 0x7be0, 0x7ce0, 0x7cdc, 0x7cde, 0x7ce2, 0x7cdf, 0x7cd9, + 0x7cdd, 0x7e2e, 0x7e3e, 0x7e46, 0x7e37, 0x7e32, 0x7e43, 0x7e2b, + 0x7e3d, 0x7e31, 0x7e45, 0x7e41, 0x7e34, 0x7e39, 0x7e48, 0x7e35, + 0x7e3f, 0x7e2f, 0x7f44, 0x7ff3, 0x7ffc, 0x8071, 0x8072, 0x8070, + 0x806f, 0x8073, 0x81c6, 0x81c3, 0x81ba, 0x81c2, 0x81c0, 0x81bf, + 0x81bd, 0x81c9, 0x81be, 0x81e8, 0x8209, 0x8271, 0x85aa, 0x8584, + 0x857e, 0x859c, 0x8591, 0x8594, 0x85af, 0x859b, 0x8587, 0x85a8, + 0x858a, 0x8667, 0x87c0, 0x87d1, 0x87b3, 0x87d2, 0x87c6, 0x87ab, + 0x87bb, 0x87ba, 0x87c8, 0x87cb, 0x893b, 0x8936, 0x8944, 0x8938, + 0x893d, 0x89ac, 0x8b0e, 0x8b17, 0x8b19, 0x8b1b, 0x8b0a, 0x8b20, + 0x8b1d, 0x8b04, 0x8b10, 0x8c41, 0x8c3f, 0x8c73, 0x8cfa, 0x8cfd, + 0x8cfc, 0x8cf8, 0x8cfb, 0x8da8, 0x8e49, 0x8e4b, 0x8e48, 0x8e4a, + 0x8f44, 0x8f3e, 0x8f42, 0x8f45, 0x8f3f, 0x907f, 0x907d, 0x9084, + 0x9081, 0x9082, 0x9080, 0x9139, 0x91a3, 0x919e, 0x919c, 0x934d, + 0x9382, 0x9328, 0x9375, 0x934a, 0x9365, 0x934b, 0x9318, 0x937e, + 0x936c, 0x935b, 0x9370, 0x935a, 0x9354, 0x95ca, 0x95cb, 0x95cc, + 0x95c8, 0x95c6, 0x96b1, 0x96b8, 0x96d6, 0x971c, 0x971e, 0x97a0, + 0x97d3, 0x9846, 0x98b6, 0x9935, 0x9a01, + /* 0xc2 */ + 0x99ff, 0x9bae, 0x9bab, 0x9baa, 0x9bad, 0x9d3b, 0x9d3f, 0x9e8b, + 0x9ecf, 0x9ede, 0x9edc, 0x9edd, 0x9edb, 0x9f3e, 0x9f4b, 0x53e2, + 0x5695, 0x56ae, 0x58d9, 0x58d8, 0x5b38, 0x5f5d, 0x61e3, 0x6233, + 0x64f4, 0x64f2, 0x64fe, 0x6506, 0x64fa, 0x64fb, 0x64f7, 0x65b7, + 0x66dc, 0x6726, 0x6ab3, 0x6aac, 0x6ac3, 0x6abb, 0x6ab8, 0x6ac2, + 0x6aae, 0x6aaf, 0x6b5f, 0x6b78, 0x6baf, 0x7009, 0x700b, 0x6ffe, + 0x7006, 0x6ffa, 0x7011, 0x700f, 0x71fb, 0x71fc, 0x71fe, 0x71f8, + 0x7377, 0x7375, 0x74a7, 0x74bf, 0x7515, 0x7656, 0x7658, 0x7652, + 0x77bd, 0x77bf, 0x77bb, 0x77bc, 0x790e, 0x79ae, 0x7a61, 0x7a62, + 0x7a60, 0x7ac4, 0x7ac5, 0x7c2b, 0x7c27, 0x7c2a, 0x7c1e, 0x7c23, + 0x7c21, 0x7ce7, 0x7e54, 0x7e55, 0x7e5e, 0x7e5a, 0x7e61, 0x7e52, + 0x7e59, 0x7f48, 0x7ff9, 0x7ffb, 0x8077, 0x8076, 0x81cd, 0x81cf, + 0x820a, 0x85cf, 0x85a9, 0x85cd, 0x85d0, 0x85c9, 0x85b0, 0x85ba, + 0x85b9, 0x85a6, 0x87ef, 0x87ec, 0x87f2, 0x87e0, 0x8986, 0x89b2, + 0x89f4, 0x8b28, 0x8b39, 0x8b2c, 0x8b2b, 0x8c50, 0x8d05, 0x8e59, + 0x8e63, 0x8e66, 0x8e64, 0x8e5f, 0x8e55, 0x8ec0, 0x8f49, 0x8f4d, + 0x9087, 0x9083, 0x9088, 0x91ab, 0x91ac, 0x91d0, 0x9394, 0x938a, + 0x9396, 0x93a2, 0x93b3, 0x93ae, 0x93ac, 0x93b0, 0x9398, 0x939a, + 0x9397, 0x95d4, 0x95d6, 0x95d0, 0x95d5, 0x96e2, 0x96dc, 0x96d9, + 0x96db, 0x96de, 0x9724, 0x97a3, 0x97a6, + /* 0xc3 */ + 0x97ad, 0x97f9, 0x984d, 0x984f, 0x984c, 0x984e, 0x9853, 0x98ba, + 0x993e, 0x993f, 0x993d, 0x992e, 0x99a5, 0x9a0e, 0x9ac1, 0x9b03, + 0x9b06, 0x9b4f, 0x9b4e, 0x9b4d, 0x9bca, 0x9bc9, 0x9bfd, 0x9bc8, + 0x9bc0, 0x9d51, 0x9d5d, 0x9d60, 0x9ee0, 0x9f15, 0x9f2c, 0x5133, + 0x56a5, 0x58de, 0x58df, 0x58e2, 0x5bf5, 0x9f90, 0x5eec, 0x61f2, + 0x61f7, 0x61f6, 0x61f5, 0x6500, 0x650f, 0x66e0, 0x66dd, 0x6ae5, + 0x6add, 0x6ada, 0x6ad3, 0x701b, 0x701f, 0x7028, 0x701a, 0x701d, + 0x7015, 0x7018, 0x7206, 0x720d, 0x7258, 0x72a2, 0x7378, 0x737a, + 0x74bd, 0x74ca, 0x74e3, 0x7587, 0x7586, 0x765f, 0x7661, 0x77c7, + 0x7919, 0x79b1, 0x7a6b, 0x7a69, 0x7c3e, 0x7c3f, 0x7c38, 0x7c3d, + 0x7c37, 0x7c40, 0x7e6b, 0x7e6d, 0x7e79, 0x7e69, 0x7e6a, 0x7f85, + 0x7e73, 0x7fb6, 0x7fb9, 0x7fb8, 0x81d8, 0x85e9, 0x85dd, 0x85ea, + 0x85d5, 0x85e4, 0x85e5, 0x85f7, 0x87fb, 0x8805, 0x880d, 0x87f9, + 0x87fe, 0x8960, 0x895f, 0x8956, 0x895e, 0x8b41, 0x8b5c, 0x8b58, + 0x8b49, 0x8b5a, 0x8b4e, 0x8b4f, 0x8b46, 0x8b59, 0x8d08, 0x8d0a, + 0x8e7c, 0x8e72, 0x8e87, 0x8e76, 0x8e6c, 0x8e7a, 0x8e74, 0x8f54, + 0x8f4e, 0x8fad, 0x908a, 0x908b, 0x91b1, 0x91ae, 0x93e1, 0x93d1, + 0x93df, 0x93c3, 0x93c8, 0x93dc, 0x93dd, 0x93d6, 0x93e2, 0x93cd, + 0x93d8, 0x93e4, 0x93d7, 0x93e8, 0x95dc, 0x96b4, 0x96e3, 0x972a, + 0x9727, 0x9761, 0x97dc, 0x97fb, 0x985e, + /* 0xc4 */ + 0x9858, 0x985b, 0x98bc, 0x9945, 0x9949, 0x9a16, 0x9a19, 0x9b0d, + 0x9be8, 0x9be7, 0x9bd6, 0x9bdb, 0x9d89, 0x9d61, 0x9d72, 0x9d6a, + 0x9d6c, 0x9e92, 0x9e97, 0x9e93, 0x9eb4, 0x52f8, 0x56a8, 0x56b7, + 0x56b6, 0x56b4, 0x56bc, 0x58e4, 0x5b40, 0x5b43, 0x5b7d, 0x5bf6, + 0x5dc9, 0x61f8, 0x61fa, 0x6518, 0x6514, 0x6519, 0x66e6, 0x6727, + 0x6aec, 0x703e, 0x7030, 0x7032, 0x7210, 0x737b, 0x74cf, 0x7662, + 0x7665, 0x7926, 0x792a, 0x792c, 0x792b, 0x7ac7, 0x7af6, 0x7c4c, + 0x7c43, 0x7c4d, 0x7cef, 0x7cf0, 0x8fae, 0x7e7d, 0x7e7c, 0x7e82, + 0x7f4c, 0x8000, 0x81da, 0x8266, 0x85fb, 0x85f9, 0x8611, 0x85fa, + 0x8606, 0x860b, 0x8607, 0x860a, 0x8814, 0x8815, 0x8964, 0x89ba, + 0x89f8, 0x8b70, 0x8b6c, 0x8b66, 0x8b6f, 0x8b5f, 0x8b6b, 0x8d0f, + 0x8d0d, 0x8e89, 0x8e81, 0x8e85, 0x8e82, 0x91b4, 0x91cb, 0x9418, + 0x9403, 0x93fd, 0x95e1, 0x9730, 0x98c4, 0x9952, 0x9951, 0x99a8, + 0x9a2b, 0x9a30, 0x9a37, 0x9a35, 0x9c13, 0x9c0d, 0x9e79, 0x9eb5, + 0x9ee8, 0x9f2f, 0x9f5f, 0x9f63, 0x9f61, 0x5137, 0x5138, 0x56c1, + 0x56c0, 0x56c2, 0x5914, 0x5c6c, 0x5dcd, 0x61fc, 0x61fe, 0x651d, + 0x651c, 0x6595, 0x66e9, 0x6afb, 0x6b04, 0x6afa, 0x6bb2, 0x704c, + 0x721b, 0x72a7, 0x74d6, 0x74d4, 0x7669, 0x77d3, 0x7c50, 0x7e8f, + 0x7e8c, 0x7fbc, 0x8617, 0x862d, 0x861a, 0x8823, 0x8822, 0x8821, + 0x881f, 0x896a, 0x896c, 0x89bd, 0x8b74, + /* 0xc5 */ + 0x8b77, 0x8b7d, 0x8d13, 0x8e8a, 0x8e8d, 0x8e8b, 0x8f5f, 0x8faf, + 0x91ba, 0x942e, 0x9433, 0x9435, 0x943a, 0x9438, 0x9432, 0x942b, + 0x95e2, 0x9738, 0x9739, 0x9732, 0x97ff, 0x9867, 0x9865, 0x9957, + 0x9a45, 0x9a43, 0x9a40, 0x9a3e, 0x9acf, 0x9b54, 0x9b51, 0x9c2d, + 0x9c25, 0x9daf, 0x9db4, 0x9dc2, 0x9db8, 0x9e9d, 0x9eef, 0x9f19, + 0x9f5c, 0x9f66, 0x9f67, 0x513c, 0x513b, 0x56c8, 0x56ca, 0x56c9, + 0x5b7f, 0x5dd4, 0x5dd2, 0x5f4e, 0x61ff, 0x6524, 0x6b0a, 0x6b61, + 0x7051, 0x7058, 0x7380, 0x74e4, 0x758a, 0x766e, 0x766c, 0x79b3, + 0x7c60, 0x7c5f, 0x807e, 0x807d, 0x81df, 0x8972, 0x896f, 0x89fc, + 0x8b80, 0x8d16, 0x8d17, 0x8e91, 0x8e93, 0x8f61, 0x9148, 0x9444, + 0x9451, 0x9452, 0x973d, 0x973e, 0x97c3, 0x97c1, 0x986b, 0x9955, + 0x9a55, 0x9a4d, 0x9ad2, 0x9b1a, 0x9c49, 0x9c31, 0x9c3e, 0x9c3b, + 0x9dd3, 0x9dd7, 0x9f34, 0x9f6c, 0x9f6a, 0x9f94, 0x56cc, 0x5dd6, + 0x6200, 0x6523, 0x652b, 0x652a, 0x66ec, 0x6b10, 0x74da, 0x7aca, + 0x7c64, 0x7c63, 0x7c65, 0x7e93, 0x7e96, 0x7e94, 0x81e2, 0x8638, + 0x863f, 0x8831, 0x8b8a, 0x9090, 0x908f, 0x9463, 0x9460, 0x9464, + 0x9768, 0x986f, 0x995c, 0x9a5a, 0x9a5b, 0x9a57, 0x9ad3, 0x9ad4, + 0x9ad1, 0x9c54, 0x9c57, 0x9c56, 0x9de5, 0x9e9f, 0x9ef4, 0x56d1, + 0x58e9, 0x652c, 0x705e, 0x7671, 0x7672, 0x77d7, 0x7f50, 0x7f88, + 0x8836, 0x8839, 0x8862, 0x8b93, 0x8b92, + /* 0xc6 */ + 0x8b96, 0x8277, 0x8d1b, 0x91c0, 0x946a, 0x9742, 0x9748, 0x9744, + 0x97c6, 0x9870, 0x9a5f, 0x9b22, 0x9b58, 0x9c5f, 0x9df9, 0x9dfa, + 0x9e7c, 0x9e7d, 0x9f07, 0x9f77, 0x9f72, 0x5ef3, 0x6b16, 0x7063, + 0x7c6c, 0x7c6e, 0x883b, 0x89c0, 0x8ea1, 0x91c1, 0x9472, 0x9470, + 0x9871, 0x995e, 0x9ad6, 0x9b23, 0x9ecc, 0x7064, 0x77da, 0x8b9a, + 0x9477, 0x97c9, 0x9a62, 0x9a65, 0x7e9c, 0x8b9c, 0x8eaa, 0x91c5, + 0x947d, 0x947e, 0x947c, 0x9c77, 0x9c78, 0x9ef7, 0x8c54, 0x947f, + 0x9e1a, 0x7228, 0x9a6a, 0x9b31, 0x9e1b, 0x9e1e, 0x7c72, 0x30fe, + 0x309d, 0x309e, 0x3005, 0x3041, 0x3042, 0x3043, 0x3044, 0x3045, + 0x3046, 0x3047, 0x3048, 0x3049, 0x304a, 0x304b, 0x304c, 0x304d, + 0x304e, 0x304f, 0x3050, 0x3051, 0x3052, 0x3053, 0x3054, 0x3055, + 0x3056, 0x3057, 0x3058, 0x3059, 0x305a, 0x305b, 0x305c, 0x305d, + 0x305e, 0x305f, 0x3060, 0x3061, 0x3062, 0x3063, 0x3064, 0x3065, + 0x3066, 0x3067, 0x3068, 0x3069, 0x306a, 0x306b, 0x306c, 0x306d, + 0x306e, 0x306f, 0x3070, 0x3071, 0x3072, 0x3073, 0x3074, 0x3075, + 0x3076, 0x3077, 0x3078, 0x3079, 0x307a, 0x307b, 0x307c, 0x307d, + 0x307e, 0x307f, 0x3080, 0x3081, 0x3082, 0x3083, 0x3084, 0x3085, + 0x3086, 0x3087, 0x3088, 0x3089, 0x308a, 0x308b, 0x308c, 0x308d, + 0x308e, 0x308f, 0x3090, 0x3091, 0x3092, 0x3093, 0x30a1, 0x30a2, + 0x30a3, 0x30a4, 0x30a5, 0x30a6, 0x30a7, + /* 0xc7 */ + 0x30a8, 0x30a9, 0x30aa, 0x30ab, 0x30ac, 0x30ad, 0x30ae, 0x30af, + 0x30b0, 0x30b1, 0x30b2, 0x30b3, 0x30b4, 0x30b5, 0x30b6, 0x30b7, + 0x30b8, 0x30b9, 0x30ba, 0x30bb, 0x30bc, 0x30bd, 0x30be, 0x30bf, + 0x30c0, 0x30c1, 0x30c2, 0x30c3, 0x30c4, 0x30c5, 0x30c6, 0x30c7, + 0x30c8, 0x30c9, 0x30ca, 0x30cb, 0x30cc, 0x30cd, 0x30ce, 0x30cf, + 0x30d0, 0x30d1, 0x30d2, 0x30d3, 0x30d4, 0x30d5, 0x30d6, 0x30d7, + 0x30d8, 0x30d9, 0x30da, 0x30db, 0x30dc, 0x30dd, 0x30de, 0x30df, + 0x30e0, 0x30e1, 0x30e2, 0x30e3, 0x30e4, 0x30e5, 0x30e6, 0x30e7, + 0x30e8, 0x30e9, 0x30ea, 0x30eb, 0x30ec, 0x30ed, 0x30ee, 0x30ef, + 0x30f0, 0x30f1, 0x30f2, 0x30f3, 0x30f4, 0x30f5, 0x30f6, 0x0414, + 0x0415, 0x0401, 0x0416, 0x0417, 0x0418, 0x0419, 0x041a, 0x041b, + 0x041c, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, + 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, 0x0430, 0x0431, + 0x0432, 0x0433, 0x0434, 0x0435, 0x0451, 0x0436, 0x0437, 0x0438, + 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, 0x0440, + 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, + 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f, 0x2460, + 0x2461, 0x2462, 0x2463, 0x2464, 0x2465, 0x2466, 0x2467, 0x2468, + 0x2469, 0x2474, 0x2475, 0x2476, 0x2477, 0x2478, 0x2479, 0x247a, + 0x247b, 0x247c, 0x247d, +}; +static const unsigned short big5_2uni_pagec9[7652] = { + /* 0xc9 */ + 0x4e42, 0x4e5c, 0x51f5, 0x531a, 0x5382, 0x4e07, 0x4e0c, 0x4e47, + 0x4e8d, 0x56d7, 0xfa0c, 0x5c6e, 0x5f73, 0x4e0f, 0x5187, 0x4e0e, + 0x4e2e, 0x4e93, 0x4ec2, 0x4ec9, 0x4ec8, 0x5198, 0x52fc, 0x536c, + 0x53b9, 0x5720, 0x5903, 0x592c, 0x5c10, 0x5dff, 0x65e1, 0x6bb3, + 0x6bcc, 0x6c14, 0x723f, 0x4e31, 0x4e3c, 0x4ee8, 0x4edc, 0x4ee9, + 0x4ee1, 0x4edd, 0x4eda, 0x520c, 0x531c, 0x534c, 0x5722, 0x5723, + 0x5917, 0x592f, 0x5b81, 0x5b84, 0x5c12, 0x5c3b, 0x5c74, 0x5c73, + 0x5e04, 0x5e80, 0x5e82, 0x5fc9, 0x6209, 0x6250, 0x6c15, 0x6c36, + 0x6c43, 0x6c3f, 0x6c3b, 0x72ae, 0x72b0, 0x738a, 0x79b8, 0x808a, + 0x961e, 0x4f0e, 0x4f18, 0x4f2c, 0x4ef5, 0x4f14, 0x4ef1, 0x4f00, + 0x4ef7, 0x4f08, 0x4f1d, 0x4f02, 0x4f05, 0x4f22, 0x4f13, 0x4f04, + 0x4ef4, 0x4f12, 0x51b1, 0x5213, 0x5209, 0x5210, 0x52a6, 0x5322, + 0x531f, 0x534d, 0x538a, 0x5407, 0x56e1, 0x56df, 0x572e, 0x572a, + 0x5734, 0x593c, 0x5980, 0x597c, 0x5985, 0x597b, 0x597e, 0x5977, + 0x597f, 0x5b56, 0x5c15, 0x5c25, 0x5c7c, 0x5c7a, 0x5c7b, 0x5c7e, + 0x5ddf, 0x5e75, 0x5e84, 0x5f02, 0x5f1a, 0x5f74, 0x5fd5, 0x5fd4, + 0x5fcf, 0x625c, 0x625e, 0x6264, 0x6261, 0x6266, 0x6262, 0x6259, + 0x6260, 0x625a, 0x6265, 0x65ef, 0x65ee, 0x673e, 0x6739, 0x6738, + 0x673b, 0x673a, 0x673f, 0x673c, 0x6733, 0x6c18, 0x6c46, 0x6c52, + 0x6c5c, 0x6c4f, 0x6c4a, 0x6c54, 0x6c4b, + /* 0xca */ + 0x6c4c, 0x7071, 0x725e, 0x72b4, 0x72b5, 0x738e, 0x752a, 0x767f, + 0x7a75, 0x7f51, 0x8278, 0x827c, 0x8280, 0x827d, 0x827f, 0x864d, + 0x897e, 0x9099, 0x9097, 0x9098, 0x909b, 0x9094, 0x9622, 0x9624, + 0x9620, 0x9623, 0x4f56, 0x4f3b, 0x4f62, 0x4f49, 0x4f53, 0x4f64, + 0x4f3e, 0x4f67, 0x4f52, 0x4f5f, 0x4f41, 0x4f58, 0x4f2d, 0x4f33, + 0x4f3f, 0x4f61, 0x518f, 0x51b9, 0x521c, 0x521e, 0x5221, 0x52ad, + 0x52ae, 0x5309, 0x5363, 0x5372, 0x538e, 0x538f, 0x5430, 0x5437, + 0x542a, 0x5454, 0x5445, 0x5419, 0x541c, 0x5425, 0x5418, 0x543d, + 0x544f, 0x5441, 0x5428, 0x5424, 0x5447, 0x56ee, 0x56e7, 0x56e5, + 0x5741, 0x5745, 0x574c, 0x5749, 0x574b, 0x5752, 0x5906, 0x5940, + 0x59a6, 0x5998, 0x59a0, 0x5997, 0x598e, 0x59a2, 0x5990, 0x598f, + 0x59a7, 0x59a1, 0x5b8e, 0x5b92, 0x5c28, 0x5c2a, 0x5c8d, 0x5c8f, + 0x5c88, 0x5c8b, 0x5c89, 0x5c92, 0x5c8a, 0x5c86, 0x5c93, 0x5c95, + 0x5de0, 0x5e0a, 0x5e0e, 0x5e8b, 0x5e89, 0x5e8c, 0x5e88, 0x5e8d, + 0x5f05, 0x5f1d, 0x5f78, 0x5f76, 0x5fd2, 0x5fd1, 0x5fd0, 0x5fed, + 0x5fe8, 0x5fee, 0x5ff3, 0x5fe1, 0x5fe4, 0x5fe3, 0x5ffa, 0x5fef, + 0x5ff7, 0x5ffb, 0x6000, 0x5ff4, 0x623a, 0x6283, 0x628c, 0x628e, + 0x628f, 0x6294, 0x6287, 0x6271, 0x627b, 0x627a, 0x6270, 0x6281, + 0x6288, 0x6277, 0x627d, 0x6272, 0x6274, 0x6537, 0x65f0, 0x65f4, + 0x65f3, 0x65f2, 0x65f5, 0x6745, 0x6747, + /* 0xcb */ + 0x6759, 0x6755, 0x674c, 0x6748, 0x675d, 0x674d, 0x675a, 0x674b, + 0x6bd0, 0x6c19, 0x6c1a, 0x6c78, 0x6c67, 0x6c6b, 0x6c84, 0x6c8b, + 0x6c8f, 0x6c71, 0x6c6f, 0x6c69, 0x6c9a, 0x6c6d, 0x6c87, 0x6c95, + 0x6c9c, 0x6c66, 0x6c73, 0x6c65, 0x6c7b, 0x6c8e, 0x7074, 0x707a, + 0x7263, 0x72bf, 0x72bd, 0x72c3, 0x72c6, 0x72c1, 0x72ba, 0x72c5, + 0x7395, 0x7397, 0x7393, 0x7394, 0x7392, 0x753a, 0x7539, 0x7594, + 0x7595, 0x7681, 0x793d, 0x8034, 0x8095, 0x8099, 0x8090, 0x8092, + 0x809c, 0x8290, 0x828f, 0x8285, 0x828e, 0x8291, 0x8293, 0x828a, + 0x8283, 0x8284, 0x8c78, 0x8fc9, 0x8fbf, 0x909f, 0x90a1, 0x90a5, + 0x909e, 0x90a7, 0x90a0, 0x9630, 0x9628, 0x962f, 0x962d, 0x4e33, + 0x4f98, 0x4f7c, 0x4f85, 0x4f7d, 0x4f80, 0x4f87, 0x4f76, 0x4f74, + 0x4f89, 0x4f84, 0x4f77, 0x4f4c, 0x4f97, 0x4f6a, 0x4f9a, 0x4f79, + 0x4f81, 0x4f78, 0x4f90, 0x4f9c, 0x4f94, 0x4f9e, 0x4f92, 0x4f82, + 0x4f95, 0x4f6b, 0x4f6e, 0x519e, 0x51bc, 0x51be, 0x5235, 0x5232, + 0x5233, 0x5246, 0x5231, 0x52bc, 0x530a, 0x530b, 0x533c, 0x5392, + 0x5394, 0x5487, 0x547f, 0x5481, 0x5491, 0x5482, 0x5488, 0x546b, + 0x547a, 0x547e, 0x5465, 0x546c, 0x5474, 0x5466, 0x548d, 0x546f, + 0x5461, 0x5460, 0x5498, 0x5463, 0x5467, 0x5464, 0x56f7, 0x56f9, + 0x576f, 0x5772, 0x576d, 0x576b, 0x5771, 0x5770, 0x5776, 0x5780, + 0x5775, 0x577b, 0x5773, 0x5774, 0x5762, + /* 0xcc */ + 0x5768, 0x577d, 0x590c, 0x5945, 0x59b5, 0x59ba, 0x59cf, 0x59ce, + 0x59b2, 0x59cc, 0x59c1, 0x59b6, 0x59bc, 0x59c3, 0x59d6, 0x59b1, + 0x59bd, 0x59c0, 0x59c8, 0x59b4, 0x59c7, 0x5b62, 0x5b65, 0x5b93, + 0x5b95, 0x5c44, 0x5c47, 0x5cae, 0x5ca4, 0x5ca0, 0x5cb5, 0x5caf, + 0x5ca8, 0x5cac, 0x5c9f, 0x5ca3, 0x5cad, 0x5ca2, 0x5caa, 0x5ca7, + 0x5c9d, 0x5ca5, 0x5cb6, 0x5cb0, 0x5ca6, 0x5e17, 0x5e14, 0x5e19, + 0x5f28, 0x5f22, 0x5f23, 0x5f24, 0x5f54, 0x5f82, 0x5f7e, 0x5f7d, + 0x5fde, 0x5fe5, 0x602d, 0x6026, 0x6019, 0x6032, 0x600b, 0x6034, + 0x600a, 0x6017, 0x6033, 0x601a, 0x601e, 0x602c, 0x6022, 0x600d, + 0x6010, 0x602e, 0x6013, 0x6011, 0x600c, 0x6009, 0x601c, 0x6214, + 0x623d, 0x62ad, 0x62b4, 0x62d1, 0x62be, 0x62aa, 0x62b6, 0x62ca, + 0x62ae, 0x62b3, 0x62af, 0x62bb, 0x62a9, 0x62b0, 0x62b8, 0x653d, + 0x65a8, 0x65bb, 0x6609, 0x65fc, 0x6604, 0x6612, 0x6608, 0x65fb, + 0x6603, 0x660b, 0x660d, 0x6605, 0x65fd, 0x6611, 0x6610, 0x66f6, + 0x670a, 0x6785, 0x676c, 0x678e, 0x6792, 0x6776, 0x677b, 0x6798, + 0x6786, 0x6784, 0x6774, 0x678d, 0x678c, 0x677a, 0x679f, 0x6791, + 0x6799, 0x6783, 0x677d, 0x6781, 0x6778, 0x6779, 0x6794, 0x6b25, + 0x6b80, 0x6b7e, 0x6bde, 0x6c1d, 0x6c93, 0x6cec, 0x6ceb, 0x6cee, + 0x6cd9, 0x6cb6, 0x6cd4, 0x6cad, 0x6ce7, 0x6cb7, 0x6cd0, 0x6cc2, + 0x6cba, 0x6cc3, 0x6cc6, 0x6ced, 0x6cf2, + /* 0xcd */ + 0x6cd2, 0x6cdd, 0x6cb4, 0x6c8a, 0x6c9d, 0x6c80, 0x6cde, 0x6cc0, + 0x6d30, 0x6ccd, 0x6cc7, 0x6cb0, 0x6cf9, 0x6ccf, 0x6ce9, 0x6cd1, + 0x7094, 0x7098, 0x7085, 0x7093, 0x7086, 0x7084, 0x7091, 0x7096, + 0x7082, 0x709a, 0x7083, 0x726a, 0x72d6, 0x72cb, 0x72d8, 0x72c9, + 0x72dc, 0x72d2, 0x72d4, 0x72da, 0x72cc, 0x72d1, 0x73a4, 0x73a1, + 0x73ad, 0x73a6, 0x73a2, 0x73a0, 0x73ac, 0x739d, 0x74dd, 0x74e8, + 0x753f, 0x7540, 0x753e, 0x758c, 0x7598, 0x76af, 0x76f3, 0x76f1, + 0x76f0, 0x76f5, 0x77f8, 0x77fc, 0x77f9, 0x77fb, 0x77fa, 0x77f7, + 0x7942, 0x793f, 0x79c5, 0x7a78, 0x7a7b, 0x7afb, 0x7c75, 0x7cfd, + 0x8035, 0x808f, 0x80ae, 0x80a3, 0x80b8, 0x80b5, 0x80ad, 0x8220, + 0x82a0, 0x82c0, 0x82ab, 0x829a, 0x8298, 0x829b, 0x82b5, 0x82a7, + 0x82ae, 0x82bc, 0x829e, 0x82ba, 0x82b4, 0x82a8, 0x82a1, 0x82a9, + 0x82c2, 0x82a4, 0x82c3, 0x82b6, 0x82a2, 0x8670, 0x866f, 0x866d, + 0x866e, 0x8c56, 0x8fd2, 0x8fcb, 0x8fd3, 0x8fcd, 0x8fd6, 0x8fd5, + 0x8fd7, 0x90b2, 0x90b4, 0x90af, 0x90b3, 0x90b0, 0x9639, 0x963d, + 0x963c, 0x963a, 0x9643, 0x4fcd, 0x4fc5, 0x4fd3, 0x4fb2, 0x4fc9, + 0x4fcb, 0x4fc1, 0x4fd4, 0x4fdc, 0x4fd9, 0x4fbb, 0x4fb3, 0x4fdb, + 0x4fc7, 0x4fd6, 0x4fba, 0x4fc0, 0x4fb9, 0x4fec, 0x5244, 0x5249, + 0x52c0, 0x52c2, 0x533d, 0x537c, 0x5397, 0x5396, 0x5399, 0x5398, + 0x54ba, 0x54a1, 0x54ad, 0x54a5, 0x54cf, + /* 0xce */ + 0x54c3, 0x830d, 0x54b7, 0x54ae, 0x54d6, 0x54b6, 0x54c5, 0x54c6, + 0x54a0, 0x5470, 0x54bc, 0x54a2, 0x54be, 0x5472, 0x54de, 0x54b0, + 0x57b5, 0x579e, 0x579f, 0x57a4, 0x578c, 0x5797, 0x579d, 0x579b, + 0x5794, 0x5798, 0x578f, 0x5799, 0x57a5, 0x579a, 0x5795, 0x58f4, + 0x590d, 0x5953, 0x59e1, 0x59de, 0x59ee, 0x5a00, 0x59f1, 0x59dd, + 0x59fa, 0x59fd, 0x59fc, 0x59f6, 0x59e4, 0x59f2, 0x59f7, 0x59db, + 0x59e9, 0x59f3, 0x59f5, 0x59e0, 0x59fe, 0x59f4, 0x59ed, 0x5ba8, + 0x5c4c, 0x5cd0, 0x5cd8, 0x5ccc, 0x5cd7, 0x5ccb, 0x5cdb, 0x5cde, + 0x5cda, 0x5cc9, 0x5cc7, 0x5cca, 0x5cd6, 0x5cd3, 0x5cd4, 0x5ccf, + 0x5cc8, 0x5cc6, 0x5cce, 0x5cdf, 0x5cf8, 0x5df9, 0x5e21, 0x5e22, + 0x5e23, 0x5e20, 0x5e24, 0x5eb0, 0x5ea4, 0x5ea2, 0x5e9b, 0x5ea3, + 0x5ea5, 0x5f07, 0x5f2e, 0x5f56, 0x5f86, 0x6037, 0x6039, 0x6054, + 0x6072, 0x605e, 0x6045, 0x6053, 0x6047, 0x6049, 0x605b, 0x604c, + 0x6040, 0x6042, 0x605f, 0x6024, 0x6044, 0x6058, 0x6066, 0x606e, + 0x6242, 0x6243, 0x62cf, 0x630d, 0x630b, 0x62f5, 0x630e, 0x6303, + 0x62eb, 0x62f9, 0x630f, 0x630c, 0x62f8, 0x62f6, 0x6300, 0x6313, + 0x6314, 0x62fa, 0x6315, 0x62fb, 0x62f0, 0x6541, 0x6543, 0x65aa, + 0x65bf, 0x6636, 0x6621, 0x6632, 0x6635, 0x661c, 0x6626, 0x6622, + 0x6633, 0x662b, 0x663a, 0x661d, 0x6634, 0x6639, 0x662e, 0x670f, + 0x6710, 0x67c1, 0x67f2, 0x67c8, 0x67ba, + /* 0xcf */ + 0x67dc, 0x67bb, 0x67f8, 0x67d8, 0x67c0, 0x67b7, 0x67c5, 0x67eb, + 0x67e4, 0x67df, 0x67b5, 0x67cd, 0x67b3, 0x67f7, 0x67f6, 0x67ee, + 0x67e3, 0x67c2, 0x67b9, 0x67ce, 0x67e7, 0x67f0, 0x67b2, 0x67fc, + 0x67c6, 0x67ed, 0x67cc, 0x67ae, 0x67e6, 0x67db, 0x67fa, 0x67c9, + 0x67ca, 0x67c3, 0x67ea, 0x67cb, 0x6b28, 0x6b82, 0x6b84, 0x6bb6, + 0x6bd6, 0x6bd8, 0x6be0, 0x6c20, 0x6c21, 0x6d28, 0x6d34, 0x6d2d, + 0x6d1f, 0x6d3c, 0x6d3f, 0x6d12, 0x6d0a, 0x6cda, 0x6d33, 0x6d04, + 0x6d19, 0x6d3a, 0x6d1a, 0x6d11, 0x6d00, 0x6d1d, 0x6d42, 0x6d01, + 0x6d18, 0x6d37, 0x6d03, 0x6d0f, 0x6d40, 0x6d07, 0x6d20, 0x6d2c, + 0x6d08, 0x6d22, 0x6d09, 0x6d10, 0x70b7, 0x709f, 0x70be, 0x70b1, + 0x70b0, 0x70a1, 0x70b4, 0x70b5, 0x70a9, 0x7241, 0x7249, 0x724a, + 0x726c, 0x7270, 0x7273, 0x726e, 0x72ca, 0x72e4, 0x72e8, 0x72eb, + 0x72df, 0x72ea, 0x72e6, 0x72e3, 0x7385, 0x73cc, 0x73c2, 0x73c8, + 0x73c5, 0x73b9, 0x73b6, 0x73b5, 0x73b4, 0x73eb, 0x73bf, 0x73c7, + 0x73be, 0x73c3, 0x73c6, 0x73b8, 0x73cb, 0x74ec, 0x74ee, 0x752e, + 0x7547, 0x7548, 0x75a7, 0x75aa, 0x7679, 0x76c4, 0x7708, 0x7703, + 0x7704, 0x7705, 0x770a, 0x76f7, 0x76fb, 0x76fa, 0x77e7, 0x77e8, + 0x7806, 0x7811, 0x7812, 0x7805, 0x7810, 0x780f, 0x780e, 0x7809, + 0x7803, 0x7813, 0x794a, 0x794c, 0x794b, 0x7945, 0x7944, 0x79d5, + 0x79cd, 0x79cf, 0x79d6, 0x79ce, 0x7a80, + /* 0xd0 */ + 0x7a7e, 0x7ad1, 0x7b00, 0x7b01, 0x7c7a, 0x7c78, 0x7c79, 0x7c7f, + 0x7c80, 0x7c81, 0x7d03, 0x7d08, 0x7d01, 0x7f58, 0x7f91, 0x7f8d, + 0x7fbe, 0x8007, 0x800e, 0x800f, 0x8014, 0x8037, 0x80d8, 0x80c7, + 0x80e0, 0x80d1, 0x80c8, 0x80c2, 0x80d0, 0x80c5, 0x80e3, 0x80d9, + 0x80dc, 0x80ca, 0x80d5, 0x80c9, 0x80cf, 0x80d7, 0x80e6, 0x80cd, + 0x81ff, 0x8221, 0x8294, 0x82d9, 0x82fe, 0x82f9, 0x8307, 0x82e8, + 0x8300, 0x82d5, 0x833a, 0x82eb, 0x82d6, 0x82f4, 0x82ec, 0x82e1, + 0x82f2, 0x82f5, 0x830c, 0x82fb, 0x82f6, 0x82f0, 0x82ea, 0x82e4, + 0x82e0, 0x82fa, 0x82f3, 0x82ed, 0x8677, 0x8674, 0x867c, 0x8673, + 0x8841, 0x884e, 0x8867, 0x886a, 0x8869, 0x89d3, 0x8a04, 0x8a07, + 0x8d72, 0x8fe3, 0x8fe1, 0x8fee, 0x8fe0, 0x90f1, 0x90bd, 0x90bf, + 0x90d5, 0x90c5, 0x90be, 0x90c7, 0x90cb, 0x90c8, 0x91d4, 0x91d3, + 0x9654, 0x964f, 0x9651, 0x9653, 0x964a, 0x964e, 0x501e, 0x5005, + 0x5007, 0x5013, 0x5022, 0x5030, 0x501b, 0x4ff5, 0x4ff4, 0x5033, + 0x5037, 0x502c, 0x4ff6, 0x4ff7, 0x5017, 0x501c, 0x5020, 0x5027, + 0x5035, 0x502f, 0x5031, 0x500e, 0x515a, 0x5194, 0x5193, 0x51ca, + 0x51c4, 0x51c5, 0x51c8, 0x51ce, 0x5261, 0x525a, 0x5252, 0x525e, + 0x525f, 0x5255, 0x5262, 0x52cd, 0x530e, 0x539e, 0x5526, 0x54e2, + 0x5517, 0x5512, 0x54e7, 0x54f3, 0x54e4, 0x551a, 0x54ff, 0x5504, + 0x5508, 0x54eb, 0x5511, 0x5505, 0x54f1, + /* 0xd1 */ + 0x550a, 0x54fb, 0x54f7, 0x54f8, 0x54e0, 0x550e, 0x5503, 0x550b, + 0x5701, 0x5702, 0x57cc, 0x5832, 0x57d5, 0x57d2, 0x57ba, 0x57c6, + 0x57bd, 0x57bc, 0x57b8, 0x57b6, 0x57bf, 0x57c7, 0x57d0, 0x57b9, + 0x57c1, 0x590e, 0x594a, 0x5a19, 0x5a16, 0x5a2d, 0x5a2e, 0x5a15, + 0x5a0f, 0x5a17, 0x5a0a, 0x5a1e, 0x5a33, 0x5b6c, 0x5ba7, 0x5bad, + 0x5bac, 0x5c03, 0x5c56, 0x5c54, 0x5cec, 0x5cff, 0x5cee, 0x5cf1, + 0x5cf7, 0x5d00, 0x5cf9, 0x5e29, 0x5e28, 0x5ea8, 0x5eae, 0x5eaa, + 0x5eac, 0x5f33, 0x5f30, 0x5f67, 0x605d, 0x605a, 0x6067, 0x6041, + 0x60a2, 0x6088, 0x6080, 0x6092, 0x6081, 0x609d, 0x6083, 0x6095, + 0x609b, 0x6097, 0x6087, 0x609c, 0x608e, 0x6219, 0x6246, 0x62f2, + 0x6310, 0x6356, 0x632c, 0x6344, 0x6345, 0x6336, 0x6343, 0x63e4, + 0x6339, 0x634b, 0x634a, 0x633c, 0x6329, 0x6341, 0x6334, 0x6358, + 0x6354, 0x6359, 0x632d, 0x6347, 0x6333, 0x635a, 0x6351, 0x6338, + 0x6357, 0x6340, 0x6348, 0x654a, 0x6546, 0x65c6, 0x65c3, 0x65c4, + 0x65c2, 0x664a, 0x665f, 0x6647, 0x6651, 0x6712, 0x6713, 0x681f, + 0x681a, 0x6849, 0x6832, 0x6833, 0x683b, 0x684b, 0x684f, 0x6816, + 0x6831, 0x681c, 0x6835, 0x682b, 0x682d, 0x682f, 0x684e, 0x6844, + 0x6834, 0x681d, 0x6812, 0x6814, 0x6826, 0x6828, 0x682e, 0x684d, + 0x683a, 0x6825, 0x6820, 0x6b2c, 0x6b2f, 0x6b2d, 0x6b31, 0x6b34, + 0x6b6d, 0x8082, 0x6b88, 0x6be6, 0x6be4, + /* 0xd2 */ + 0x6be8, 0x6be3, 0x6be2, 0x6be7, 0x6c25, 0x6d7a, 0x6d63, 0x6d64, + 0x6d76, 0x6d0d, 0x6d61, 0x6d92, 0x6d58, 0x6d62, 0x6d6d, 0x6d6f, + 0x6d91, 0x6d8d, 0x6def, 0x6d7f, 0x6d86, 0x6d5e, 0x6d67, 0x6d60, + 0x6d97, 0x6d70, 0x6d7c, 0x6d5f, 0x6d82, 0x6d98, 0x6d2f, 0x6d68, + 0x6d8b, 0x6d7e, 0x6d80, 0x6d84, 0x6d16, 0x6d83, 0x6d7b, 0x6d7d, + 0x6d75, 0x6d90, 0x70dc, 0x70d3, 0x70d1, 0x70dd, 0x70cb, 0x7f39, + 0x70e2, 0x70d7, 0x70d2, 0x70de, 0x70e0, 0x70d4, 0x70cd, 0x70c5, + 0x70c6, 0x70c7, 0x70da, 0x70ce, 0x70e1, 0x7242, 0x7278, 0x7277, + 0x7276, 0x7300, 0x72fa, 0x72f4, 0x72fe, 0x72f6, 0x72f3, 0x72fb, + 0x7301, 0x73d3, 0x73d9, 0x73e5, 0x73d6, 0x73bc, 0x73e7, 0x73e3, + 0x73e9, 0x73dc, 0x73d2, 0x73db, 0x73d4, 0x73dd, 0x73da, 0x73d7, + 0x73d8, 0x73e8, 0x74de, 0x74df, 0x74f4, 0x74f5, 0x7521, 0x755b, + 0x755f, 0x75b0, 0x75c1, 0x75bb, 0x75c4, 0x75c0, 0x75bf, 0x75b6, + 0x75ba, 0x768a, 0x76c9, 0x771d, 0x771b, 0x7710, 0x7713, 0x7712, + 0x7723, 0x7711, 0x7715, 0x7719, 0x771a, 0x7722, 0x7727, 0x7823, + 0x782c, 0x7822, 0x7835, 0x782f, 0x7828, 0x782e, 0x782b, 0x7821, + 0x7829, 0x7833, 0x782a, 0x7831, 0x7954, 0x795b, 0x794f, 0x795c, + 0x7953, 0x7952, 0x7951, 0x79eb, 0x79ec, 0x79e0, 0x79ee, 0x79ed, + 0x79ea, 0x79dc, 0x79de, 0x79dd, 0x7a86, 0x7a89, 0x7a85, 0x7a8b, + 0x7a8c, 0x7a8a, 0x7a87, 0x7ad8, 0x7b10, + /* 0xd3 */ + 0x7b04, 0x7b13, 0x7b05, 0x7b0f, 0x7b08, 0x7b0a, 0x7b0e, 0x7b09, + 0x7b12, 0x7c84, 0x7c91, 0x7c8a, 0x7c8c, 0x7c88, 0x7c8d, 0x7c85, + 0x7d1e, 0x7d1d, 0x7d11, 0x7d0e, 0x7d18, 0x7d16, 0x7d13, 0x7d1f, + 0x7d12, 0x7d0f, 0x7d0c, 0x7f5c, 0x7f61, 0x7f5e, 0x7f60, 0x7f5d, + 0x7f5b, 0x7f96, 0x7f92, 0x7fc3, 0x7fc2, 0x7fc0, 0x8016, 0x803e, + 0x8039, 0x80fa, 0x80f2, 0x80f9, 0x80f5, 0x8101, 0x80fb, 0x8100, + 0x8201, 0x822f, 0x8225, 0x8333, 0x832d, 0x8344, 0x8319, 0x8351, + 0x8325, 0x8356, 0x833f, 0x8341, 0x8326, 0x831c, 0x8322, 0x8342, + 0x834e, 0x831b, 0x832a, 0x8308, 0x833c, 0x834d, 0x8316, 0x8324, + 0x8320, 0x8337, 0x832f, 0x8329, 0x8347, 0x8345, 0x834c, 0x8353, + 0x831e, 0x832c, 0x834b, 0x8327, 0x8348, 0x8653, 0x8652, 0x86a2, + 0x86a8, 0x8696, 0x868d, 0x8691, 0x869e, 0x8687, 0x8697, 0x8686, + 0x868b, 0x869a, 0x8685, 0x86a5, 0x8699, 0x86a1, 0x86a7, 0x8695, + 0x8698, 0x868e, 0x869d, 0x8690, 0x8694, 0x8843, 0x8844, 0x886d, + 0x8875, 0x8876, 0x8872, 0x8880, 0x8871, 0x887f, 0x886f, 0x8883, + 0x887e, 0x8874, 0x887c, 0x8a12, 0x8c47, 0x8c57, 0x8c7b, 0x8ca4, + 0x8ca3, 0x8d76, 0x8d78, 0x8db5, 0x8db7, 0x8db6, 0x8ed1, 0x8ed3, + 0x8ffe, 0x8ff5, 0x9002, 0x8fff, 0x8ffb, 0x9004, 0x8ffc, 0x8ff6, + 0x90d6, 0x90e0, 0x90d9, 0x90da, 0x90e3, 0x90df, 0x90e5, 0x90d8, + 0x90db, 0x90d7, 0x90dc, 0x90e4, 0x9150, + /* 0xd4 */ + 0x914e, 0x914f, 0x91d5, 0x91e2, 0x91da, 0x965c, 0x965f, 0x96bc, + 0x98e3, 0x9adf, 0x9b2f, 0x4e7f, 0x5070, 0x506a, 0x5061, 0x505e, + 0x5060, 0x5053, 0x504b, 0x505d, 0x5072, 0x5048, 0x504d, 0x5041, + 0x505b, 0x504a, 0x5062, 0x5015, 0x5045, 0x505f, 0x5069, 0x506b, + 0x5063, 0x5064, 0x5046, 0x5040, 0x506e, 0x5073, 0x5057, 0x5051, + 0x51d0, 0x526b, 0x526d, 0x526c, 0x526e, 0x52d6, 0x52d3, 0x532d, + 0x539c, 0x5575, 0x5576, 0x553c, 0x554d, 0x5550, 0x5534, 0x552a, + 0x5551, 0x5562, 0x5536, 0x5535, 0x5530, 0x5552, 0x5545, 0x550c, + 0x5532, 0x5565, 0x554e, 0x5539, 0x5548, 0x552d, 0x553b, 0x5540, + 0x554b, 0x570a, 0x5707, 0x57fb, 0x5814, 0x57e2, 0x57f6, 0x57dc, + 0x57f4, 0x5800, 0x57ed, 0x57fd, 0x5808, 0x57f8, 0x580b, 0x57f3, + 0x57cf, 0x5807, 0x57ee, 0x57e3, 0x57f2, 0x57e5, 0x57ec, 0x57e1, + 0x580e, 0x57fc, 0x5810, 0x57e7, 0x5801, 0x580c, 0x57f1, 0x57e9, + 0x57f0, 0x580d, 0x5804, 0x595c, 0x5a60, 0x5a58, 0x5a55, 0x5a67, + 0x5a5e, 0x5a38, 0x5a35, 0x5a6d, 0x5a50, 0x5a5f, 0x5a65, 0x5a6c, + 0x5a53, 0x5a64, 0x5a57, 0x5a43, 0x5a5d, 0x5a52, 0x5a44, 0x5a5b, + 0x5a48, 0x5a8e, 0x5a3e, 0x5a4d, 0x5a39, 0x5a4c, 0x5a70, 0x5a69, + 0x5a47, 0x5a51, 0x5a56, 0x5a42, 0x5a5c, 0x5b72, 0x5b6e, 0x5bc1, + 0x5bc0, 0x5c59, 0x5d1e, 0x5d0b, 0x5d1d, 0x5d1a, 0x5d20, 0x5d0c, + 0x5d28, 0x5d0d, 0x5d26, 0x5d25, 0x5d0f, + /* 0xd5 */ + 0x5d30, 0x5d12, 0x5d23, 0x5d1f, 0x5d2e, 0x5e3e, 0x5e34, 0x5eb1, + 0x5eb4, 0x5eb9, 0x5eb2, 0x5eb3, 0x5f36, 0x5f38, 0x5f9b, 0x5f96, + 0x5f9f, 0x608a, 0x6090, 0x6086, 0x60be, 0x60b0, 0x60ba, 0x60d3, + 0x60d4, 0x60cf, 0x60e4, 0x60d9, 0x60dd, 0x60c8, 0x60b1, 0x60db, + 0x60b7, 0x60ca, 0x60bf, 0x60c3, 0x60cd, 0x60c0, 0x6332, 0x6365, + 0x638a, 0x6382, 0x637d, 0x63bd, 0x639e, 0x63ad, 0x639d, 0x6397, + 0x63ab, 0x638e, 0x636f, 0x6387, 0x6390, 0x636e, 0x63af, 0x6375, + 0x639c, 0x636d, 0x63ae, 0x637c, 0x63a4, 0x633b, 0x639f, 0x6378, + 0x6385, 0x6381, 0x6391, 0x638d, 0x6370, 0x6553, 0x65cd, 0x6665, + 0x6661, 0x665b, 0x6659, 0x665c, 0x6662, 0x6718, 0x6879, 0x6887, + 0x6890, 0x689c, 0x686d, 0x686e, 0x68ae, 0x68ab, 0x6956, 0x686f, + 0x68a3, 0x68ac, 0x68a9, 0x6875, 0x6874, 0x68b2, 0x688f, 0x6877, + 0x6892, 0x687c, 0x686b, 0x6872, 0x68aa, 0x6880, 0x6871, 0x687e, + 0x689b, 0x6896, 0x688b, 0x68a0, 0x6889, 0x68a4, 0x6878, 0x687b, + 0x6891, 0x688c, 0x688a, 0x687d, 0x6b36, 0x6b33, 0x6b37, 0x6b38, + 0x6b91, 0x6b8f, 0x6b8d, 0x6b8e, 0x6b8c, 0x6c2a, 0x6dc0, 0x6dab, + 0x6db4, 0x6db3, 0x6e74, 0x6dac, 0x6de9, 0x6de2, 0x6db7, 0x6df6, + 0x6dd4, 0x6e00, 0x6dc8, 0x6de0, 0x6ddf, 0x6dd6, 0x6dbe, 0x6de5, + 0x6ddc, 0x6ddd, 0x6ddb, 0x6df4, 0x6dca, 0x6dbd, 0x6ded, 0x6df0, + 0x6dba, 0x6dd5, 0x6dc2, 0x6dcf, 0x6dc9, + /* 0xd6 */ + 0x6dd0, 0x6df2, 0x6dd3, 0x6dfd, 0x6dd7, 0x6dcd, 0x6de3, 0x6dbb, + 0x70fa, 0x710d, 0x70f7, 0x7117, 0x70f4, 0x710c, 0x70f0, 0x7104, + 0x70f3, 0x7110, 0x70fc, 0x70ff, 0x7106, 0x7113, 0x7100, 0x70f8, + 0x70f6, 0x710b, 0x7102, 0x710e, 0x727e, 0x727b, 0x727c, 0x727f, + 0x731d, 0x7317, 0x7307, 0x7311, 0x7318, 0x730a, 0x7308, 0x72ff, + 0x730f, 0x731e, 0x7388, 0x73f6, 0x73f8, 0x73f5, 0x7404, 0x7401, + 0x73fd, 0x7407, 0x7400, 0x73fa, 0x73fc, 0x73ff, 0x740c, 0x740b, + 0x73f4, 0x7408, 0x7564, 0x7563, 0x75ce, 0x75d2, 0x75cf, 0x75cb, + 0x75cc, 0x75d1, 0x75d0, 0x768f, 0x7689, 0x76d3, 0x7739, 0x772f, + 0x772d, 0x7731, 0x7732, 0x7734, 0x7733, 0x773d, 0x7725, 0x773b, + 0x7735, 0x7848, 0x7852, 0x7849, 0x784d, 0x784a, 0x784c, 0x7826, + 0x7845, 0x7850, 0x7964, 0x7967, 0x7969, 0x796a, 0x7963, 0x796b, + 0x7961, 0x79bb, 0x79fa, 0x79f8, 0x79f6, 0x79f7, 0x7a8f, 0x7a94, + 0x7a90, 0x7b35, 0x7b47, 0x7b34, 0x7b25, 0x7b30, 0x7b22, 0x7b24, + 0x7b33, 0x7b18, 0x7b2a, 0x7b1d, 0x7b31, 0x7b2b, 0x7b2d, 0x7b2f, + 0x7b32, 0x7b38, 0x7b1a, 0x7b23, 0x7c94, 0x7c98, 0x7c96, 0x7ca3, + 0x7d35, 0x7d3d, 0x7d38, 0x7d36, 0x7d3a, 0x7d45, 0x7d2c, 0x7d29, + 0x7d41, 0x7d47, 0x7d3e, 0x7d3f, 0x7d4a, 0x7d3b, 0x7d28, 0x7f63, + 0x7f95, 0x7f9c, 0x7f9d, 0x7f9b, 0x7fca, 0x7fcb, 0x7fcd, 0x7fd0, + 0x7fd1, 0x7fc7, 0x7fcf, 0x7fc9, 0x801f, + /* 0xd7 */ + 0x801e, 0x801b, 0x8047, 0x8043, 0x8048, 0x8118, 0x8125, 0x8119, + 0x811b, 0x812d, 0x811f, 0x812c, 0x811e, 0x8121, 0x8115, 0x8127, + 0x811d, 0x8122, 0x8211, 0x8238, 0x8233, 0x823a, 0x8234, 0x8232, + 0x8274, 0x8390, 0x83a3, 0x83a8, 0x838d, 0x837a, 0x8373, 0x83a4, + 0x8374, 0x838f, 0x8381, 0x8395, 0x8399, 0x8375, 0x8394, 0x83a9, + 0x837d, 0x8383, 0x838c, 0x839d, 0x839b, 0x83aa, 0x838b, 0x837e, + 0x83a5, 0x83af, 0x8388, 0x8397, 0x83b0, 0x837f, 0x83a6, 0x8387, + 0x83ae, 0x8376, 0x839a, 0x8659, 0x8656, 0x86bf, 0x86b7, 0x86c2, + 0x86c1, 0x86c5, 0x86ba, 0x86b0, 0x86c8, 0x86b9, 0x86b3, 0x86b8, + 0x86cc, 0x86b4, 0x86bb, 0x86bc, 0x86c3, 0x86bd, 0x86be, 0x8852, + 0x8889, 0x8895, 0x88a8, 0x88a2, 0x88aa, 0x889a, 0x8891, 0x88a1, + 0x889f, 0x8898, 0x88a7, 0x8899, 0x889b, 0x8897, 0x88a4, 0x88ac, + 0x888c, 0x8893, 0x888e, 0x8982, 0x89d6, 0x89d9, 0x89d5, 0x8a30, + 0x8a27, 0x8a2c, 0x8a1e, 0x8c39, 0x8c3b, 0x8c5c, 0x8c5d, 0x8c7d, + 0x8ca5, 0x8d7d, 0x8d7b, 0x8d79, 0x8dbc, 0x8dc2, 0x8db9, 0x8dbf, + 0x8dc1, 0x8ed8, 0x8ede, 0x8edd, 0x8edc, 0x8ed7, 0x8ee0, 0x8ee1, + 0x9024, 0x900b, 0x9011, 0x901c, 0x900c, 0x9021, 0x90ef, 0x90ea, + 0x90f0, 0x90f4, 0x90f2, 0x90f3, 0x90d4, 0x90eb, 0x90ec, 0x90e9, + 0x9156, 0x9158, 0x915a, 0x9153, 0x9155, 0x91ec, 0x91f4, 0x91f1, + 0x91f3, 0x91f8, 0x91e4, 0x91f9, 0x91ea, + /* 0xd8 */ + 0x91eb, 0x91f7, 0x91e8, 0x91ee, 0x957a, 0x9586, 0x9588, 0x967c, + 0x966d, 0x966b, 0x9671, 0x966f, 0x96bf, 0x976a, 0x9804, 0x98e5, + 0x9997, 0x509b, 0x5095, 0x5094, 0x509e, 0x508b, 0x50a3, 0x5083, + 0x508c, 0x508e, 0x509d, 0x5068, 0x509c, 0x5092, 0x5082, 0x5087, + 0x515f, 0x51d4, 0x5312, 0x5311, 0x53a4, 0x53a7, 0x5591, 0x55a8, + 0x55a5, 0x55ad, 0x5577, 0x5645, 0x55a2, 0x5593, 0x5588, 0x558f, + 0x55b5, 0x5581, 0x55a3, 0x5592, 0x55a4, 0x557d, 0x558c, 0x55a6, + 0x557f, 0x5595, 0x55a1, 0x558e, 0x570c, 0x5829, 0x5837, 0x5819, + 0x581e, 0x5827, 0x5823, 0x5828, 0x57f5, 0x5848, 0x5825, 0x581c, + 0x581b, 0x5833, 0x583f, 0x5836, 0x582e, 0x5839, 0x5838, 0x582d, + 0x582c, 0x583b, 0x5961, 0x5aaf, 0x5a94, 0x5a9f, 0x5a7a, 0x5aa2, + 0x5a9e, 0x5a78, 0x5aa6, 0x5a7c, 0x5aa5, 0x5aac, 0x5a95, 0x5aae, + 0x5a37, 0x5a84, 0x5a8a, 0x5a97, 0x5a83, 0x5a8b, 0x5aa9, 0x5a7b, + 0x5a7d, 0x5a8c, 0x5a9c, 0x5a8f, 0x5a93, 0x5a9d, 0x5bea, 0x5bcd, + 0x5bcb, 0x5bd4, 0x5bd1, 0x5bca, 0x5bce, 0x5c0c, 0x5c30, 0x5d37, + 0x5d43, 0x5d6b, 0x5d41, 0x5d4b, 0x5d3f, 0x5d35, 0x5d51, 0x5d4e, + 0x5d55, 0x5d33, 0x5d3a, 0x5d52, 0x5d3d, 0x5d31, 0x5d59, 0x5d42, + 0x5d39, 0x5d49, 0x5d38, 0x5d3c, 0x5d32, 0x5d36, 0x5d40, 0x5d45, + 0x5e44, 0x5e41, 0x5f58, 0x5fa6, 0x5fa5, 0x5fab, 0x60c9, 0x60b9, + 0x60cc, 0x60e2, 0x60ce, 0x60c4, 0x6114, + /* 0xd9 */ + 0x60f2, 0x610a, 0x6116, 0x6105, 0x60f5, 0x6113, 0x60f8, 0x60fc, + 0x60fe, 0x60c1, 0x6103, 0x6118, 0x611d, 0x6110, 0x60ff, 0x6104, + 0x610b, 0x624a, 0x6394, 0x63b1, 0x63b0, 0x63ce, 0x63e5, 0x63e8, + 0x63ef, 0x63c3, 0x649d, 0x63f3, 0x63ca, 0x63e0, 0x63f6, 0x63d5, + 0x63f2, 0x63f5, 0x6461, 0x63df, 0x63be, 0x63dd, 0x63dc, 0x63c4, + 0x63d8, 0x63d3, 0x63c2, 0x63c7, 0x63cc, 0x63cb, 0x63c8, 0x63f0, + 0x63d7, 0x63d9, 0x6532, 0x6567, 0x656a, 0x6564, 0x655c, 0x6568, + 0x6565, 0x658c, 0x659d, 0x659e, 0x65ae, 0x65d0, 0x65d2, 0x667c, + 0x666c, 0x667b, 0x6680, 0x6671, 0x6679, 0x666a, 0x6672, 0x6701, + 0x690c, 0x68d3, 0x6904, 0x68dc, 0x692a, 0x68ec, 0x68ea, 0x68f1, + 0x690f, 0x68d6, 0x68f7, 0x68eb, 0x68e4, 0x68f6, 0x6913, 0x6910, + 0x68f3, 0x68e1, 0x6907, 0x68cc, 0x6908, 0x6970, 0x68b4, 0x6911, + 0x68ef, 0x68c6, 0x6914, 0x68f8, 0x68d0, 0x68fd, 0x68fc, 0x68e8, + 0x690b, 0x690a, 0x6917, 0x68ce, 0x68c8, 0x68dd, 0x68de, 0x68e6, + 0x68f4, 0x68d1, 0x6906, 0x68d4, 0x68e9, 0x6915, 0x6925, 0x68c7, + 0x6b39, 0x6b3b, 0x6b3f, 0x6b3c, 0x6b94, 0x6b97, 0x6b99, 0x6b95, + 0x6bbd, 0x6bf0, 0x6bf2, 0x6bf3, 0x6c30, 0x6dfc, 0x6e46, 0x6e47, + 0x6e1f, 0x6e49, 0x6e88, 0x6e3c, 0x6e3d, 0x6e45, 0x6e62, 0x6e2b, + 0x6e3f, 0x6e41, 0x6e5d, 0x6e73, 0x6e1c, 0x6e33, 0x6e4b, 0x6e40, + 0x6e51, 0x6e3b, 0x6e03, 0x6e2e, 0x6e5e, + /* 0xda */ + 0x6e68, 0x6e5c, 0x6e61, 0x6e31, 0x6e28, 0x6e60, 0x6e71, 0x6e6b, + 0x6e39, 0x6e22, 0x6e30, 0x6e53, 0x6e65, 0x6e27, 0x6e78, 0x6e64, + 0x6e77, 0x6e55, 0x6e79, 0x6e52, 0x6e66, 0x6e35, 0x6e36, 0x6e5a, + 0x7120, 0x711e, 0x712f, 0x70fb, 0x712e, 0x7131, 0x7123, 0x7125, + 0x7122, 0x7132, 0x711f, 0x7128, 0x713a, 0x711b, 0x724b, 0x725a, + 0x7288, 0x7289, 0x7286, 0x7285, 0x728b, 0x7312, 0x730b, 0x7330, + 0x7322, 0x7331, 0x7333, 0x7327, 0x7332, 0x732d, 0x7326, 0x7323, + 0x7335, 0x730c, 0x742e, 0x742c, 0x7430, 0x742b, 0x7416, 0x741a, + 0x7421, 0x742d, 0x7431, 0x7424, 0x7423, 0x741d, 0x7429, 0x7420, + 0x7432, 0x74fb, 0x752f, 0x756f, 0x756c, 0x75e7, 0x75da, 0x75e1, + 0x75e6, 0x75dd, 0x75df, 0x75e4, 0x75d7, 0x7695, 0x7692, 0x76da, + 0x7746, 0x7747, 0x7744, 0x774d, 0x7745, 0x774a, 0x774e, 0x774b, + 0x774c, 0x77de, 0x77ec, 0x7860, 0x7864, 0x7865, 0x785c, 0x786d, + 0x7871, 0x786a, 0x786e, 0x7870, 0x7869, 0x7868, 0x785e, 0x7862, + 0x7974, 0x7973, 0x7972, 0x7970, 0x7a02, 0x7a0a, 0x7a03, 0x7a0c, + 0x7a04, 0x7a99, 0x7ae6, 0x7ae4, 0x7b4a, 0x7b3b, 0x7b44, 0x7b48, + 0x7b4c, 0x7b4e, 0x7b40, 0x7b58, 0x7b45, 0x7ca2, 0x7c9e, 0x7ca8, + 0x7ca1, 0x7d58, 0x7d6f, 0x7d63, 0x7d53, 0x7d56, 0x7d67, 0x7d6a, + 0x7d4f, 0x7d6d, 0x7d5c, 0x7d6b, 0x7d52, 0x7d54, 0x7d69, 0x7d51, + 0x7d5f, 0x7d4e, 0x7f3e, 0x7f3f, 0x7f65, + /* 0xdb */ + 0x7f66, 0x7fa2, 0x7fa0, 0x7fa1, 0x7fd7, 0x8051, 0x804f, 0x8050, + 0x80fe, 0x80d4, 0x8143, 0x814a, 0x8152, 0x814f, 0x8147, 0x813d, + 0x814d, 0x813a, 0x81e6, 0x81ee, 0x81f7, 0x81f8, 0x81f9, 0x8204, + 0x823c, 0x823d, 0x823f, 0x8275, 0x833b, 0x83cf, 0x83f9, 0x8423, + 0x83c0, 0x83e8, 0x8412, 0x83e7, 0x83e4, 0x83fc, 0x83f6, 0x8410, + 0x83c6, 0x83c8, 0x83eb, 0x83e3, 0x83bf, 0x8401, 0x83dd, 0x83e5, + 0x83d8, 0x83ff, 0x83e1, 0x83cb, 0x83ce, 0x83d6, 0x83f5, 0x83c9, + 0x8409, 0x840f, 0x83de, 0x8411, 0x8406, 0x83c2, 0x83f3, 0x83d5, + 0x83fa, 0x83c7, 0x83d1, 0x83ea, 0x8413, 0x83c3, 0x83ec, 0x83ee, + 0x83c4, 0x83fb, 0x83d7, 0x83e2, 0x841b, 0x83db, 0x83fe, 0x86d8, + 0x86e2, 0x86e6, 0x86d3, 0x86e3, 0x86da, 0x86ea, 0x86dd, 0x86eb, + 0x86dc, 0x86ec, 0x86e9, 0x86d7, 0x86e8, 0x86d1, 0x8848, 0x8856, + 0x8855, 0x88ba, 0x88d7, 0x88b9, 0x88b8, 0x88c0, 0x88be, 0x88b6, + 0x88bc, 0x88b7, 0x88bd, 0x88b2, 0x8901, 0x88c9, 0x8995, 0x8998, + 0x8997, 0x89dd, 0x89da, 0x89db, 0x8a4e, 0x8a4d, 0x8a39, 0x8a59, + 0x8a40, 0x8a57, 0x8a58, 0x8a44, 0x8a45, 0x8a52, 0x8a48, 0x8a51, + 0x8a4a, 0x8a4c, 0x8a4f, 0x8c5f, 0x8c81, 0x8c80, 0x8cba, 0x8cbe, + 0x8cb0, 0x8cb9, 0x8cb5, 0x8d84, 0x8d80, 0x8d89, 0x8dd8, 0x8dd3, + 0x8dcd, 0x8dc7, 0x8dd6, 0x8ddc, 0x8dcf, 0x8dd5, 0x8dd9, 0x8dc8, + 0x8dd7, 0x8dc5, 0x8eef, 0x8ef7, 0x8efa, + /* 0xdc */ + 0x8ef9, 0x8ee6, 0x8eee, 0x8ee5, 0x8ef5, 0x8ee7, 0x8ee8, 0x8ef6, + 0x8eeb, 0x8ef1, 0x8eec, 0x8ef4, 0x8ee9, 0x902d, 0x9034, 0x902f, + 0x9106, 0x912c, 0x9104, 0x90ff, 0x90fc, 0x9108, 0x90f9, 0x90fb, + 0x9101, 0x9100, 0x9107, 0x9105, 0x9103, 0x9161, 0x9164, 0x915f, + 0x9162, 0x9160, 0x9201, 0x920a, 0x9225, 0x9203, 0x921a, 0x9226, + 0x920f, 0x920c, 0x9200, 0x9212, 0x91ff, 0x91fd, 0x9206, 0x9204, + 0x9227, 0x9202, 0x921c, 0x9224, 0x9219, 0x9217, 0x9205, 0x9216, + 0x957b, 0x958d, 0x958c, 0x9590, 0x9687, 0x967e, 0x9688, 0x9689, + 0x9683, 0x9680, 0x96c2, 0x96c8, 0x96c3, 0x96f1, 0x96f0, 0x976c, + 0x9770, 0x976e, 0x9807, 0x98a9, 0x98eb, 0x9ce6, 0x9ef9, 0x4e83, + 0x4e84, 0x4eb6, 0x50bd, 0x50bf, 0x50c6, 0x50ae, 0x50c4, 0x50ca, + 0x50b4, 0x50c8, 0x50c2, 0x50b0, 0x50c1, 0x50ba, 0x50b1, 0x50cb, + 0x50c9, 0x50b6, 0x50b8, 0x51d7, 0x527a, 0x5278, 0x527b, 0x527c, + 0x55c3, 0x55db, 0x55cc, 0x55d0, 0x55cb, 0x55ca, 0x55dd, 0x55c0, + 0x55d4, 0x55c4, 0x55e9, 0x55bf, 0x55d2, 0x558d, 0x55cf, 0x55d5, + 0x55e2, 0x55d6, 0x55c8, 0x55f2, 0x55cd, 0x55d9, 0x55c2, 0x5714, + 0x5853, 0x5868, 0x5864, 0x584f, 0x584d, 0x5849, 0x586f, 0x5855, + 0x584e, 0x585d, 0x5859, 0x5865, 0x585b, 0x583d, 0x5863, 0x5871, + 0x58fc, 0x5ac7, 0x5ac4, 0x5acb, 0x5aba, 0x5ab8, 0x5ab1, 0x5ab5, + 0x5ab0, 0x5abf, 0x5ac8, 0x5abb, 0x5ac6, + /* 0xdd */ + 0x5ab7, 0x5ac0, 0x5aca, 0x5ab4, 0x5ab6, 0x5acd, 0x5ab9, 0x5a90, + 0x5bd6, 0x5bd8, 0x5bd9, 0x5c1f, 0x5c33, 0x5d71, 0x5d63, 0x5d4a, + 0x5d65, 0x5d72, 0x5d6c, 0x5d5e, 0x5d68, 0x5d67, 0x5d62, 0x5df0, + 0x5e4f, 0x5e4e, 0x5e4a, 0x5e4d, 0x5e4b, 0x5ec5, 0x5ecc, 0x5ec6, + 0x5ecb, 0x5ec7, 0x5f40, 0x5faf, 0x5fad, 0x60f7, 0x6149, 0x614a, + 0x612b, 0x6145, 0x6136, 0x6132, 0x612e, 0x6146, 0x612f, 0x614f, + 0x6129, 0x6140, 0x6220, 0x9168, 0x6223, 0x6225, 0x6224, 0x63c5, + 0x63f1, 0x63eb, 0x6410, 0x6412, 0x6409, 0x6420, 0x6424, 0x6433, + 0x6443, 0x641f, 0x6415, 0x6418, 0x6439, 0x6437, 0x6422, 0x6423, + 0x640c, 0x6426, 0x6430, 0x6428, 0x6441, 0x6435, 0x642f, 0x640a, + 0x641a, 0x6440, 0x6425, 0x6427, 0x640b, 0x63e7, 0x641b, 0x642e, + 0x6421, 0x640e, 0x656f, 0x6592, 0x65d3, 0x6686, 0x668c, 0x6695, + 0x6690, 0x668b, 0x668a, 0x6699, 0x6694, 0x6678, 0x6720, 0x6966, + 0x695f, 0x6938, 0x694e, 0x6962, 0x6971, 0x693f, 0x6945, 0x696a, + 0x6939, 0x6942, 0x6957, 0x6959, 0x697a, 0x6948, 0x6949, 0x6935, + 0x696c, 0x6933, 0x693d, 0x6965, 0x68f0, 0x6978, 0x6934, 0x6969, + 0x6940, 0x696f, 0x6944, 0x6976, 0x6958, 0x6941, 0x6974, 0x694c, + 0x693b, 0x694b, 0x6937, 0x695c, 0x694f, 0x6951, 0x6932, 0x6952, + 0x692f, 0x697b, 0x693c, 0x6b46, 0x6b45, 0x6b43, 0x6b42, 0x6b48, + 0x6b41, 0x6b9b, 0xfa0d, 0x6bfb, 0x6bfc, + /* 0xde */ + 0x6bf9, 0x6bf7, 0x6bf8, 0x6e9b, 0x6ed6, 0x6ec8, 0x6e8f, 0x6ec0, + 0x6e9f, 0x6e93, 0x6e94, 0x6ea0, 0x6eb1, 0x6eb9, 0x6ec6, 0x6ed2, + 0x6ebd, 0x6ec1, 0x6e9e, 0x6ec9, 0x6eb7, 0x6eb0, 0x6ecd, 0x6ea6, + 0x6ecf, 0x6eb2, 0x6ebe, 0x6ec3, 0x6edc, 0x6ed8, 0x6e99, 0x6e92, + 0x6e8e, 0x6e8d, 0x6ea4, 0x6ea1, 0x6ebf, 0x6eb3, 0x6ed0, 0x6eca, + 0x6e97, 0x6eae, 0x6ea3, 0x7147, 0x7154, 0x7152, 0x7163, 0x7160, + 0x7141, 0x715d, 0x7162, 0x7172, 0x7178, 0x716a, 0x7161, 0x7142, + 0x7158, 0x7143, 0x714b, 0x7170, 0x715f, 0x7150, 0x7153, 0x7144, + 0x714d, 0x715a, 0x724f, 0x728d, 0x728c, 0x7291, 0x7290, 0x728e, + 0x733c, 0x7342, 0x733b, 0x733a, 0x7340, 0x734a, 0x7349, 0x7444, + 0x744a, 0x744b, 0x7452, 0x7451, 0x7457, 0x7440, 0x744f, 0x7450, + 0x744e, 0x7442, 0x7446, 0x744d, 0x7454, 0x74e1, 0x74ff, 0x74fe, + 0x74fd, 0x751d, 0x7579, 0x7577, 0x6983, 0x75ef, 0x760f, 0x7603, + 0x75f7, 0x75fe, 0x75fc, 0x75f9, 0x75f8, 0x7610, 0x75fb, 0x75f6, + 0x75ed, 0x75f5, 0x75fd, 0x7699, 0x76b5, 0x76dd, 0x7755, 0x775f, + 0x7760, 0x7752, 0x7756, 0x775a, 0x7769, 0x7767, 0x7754, 0x7759, + 0x776d, 0x77e0, 0x7887, 0x789a, 0x7894, 0x788f, 0x7884, 0x7895, + 0x7885, 0x7886, 0x78a1, 0x7883, 0x7879, 0x7899, 0x7880, 0x7896, + 0x787b, 0x797c, 0x7982, 0x797d, 0x7979, 0x7a11, 0x7a18, 0x7a19, + 0x7a12, 0x7a17, 0x7a15, 0x7a22, 0x7a13, + /* 0xdf */ + 0x7a1b, 0x7a10, 0x7aa3, 0x7aa2, 0x7a9e, 0x7aeb, 0x7b66, 0x7b64, + 0x7b6d, 0x7b74, 0x7b69, 0x7b72, 0x7b65, 0x7b73, 0x7b71, 0x7b70, + 0x7b61, 0x7b78, 0x7b76, 0x7b63, 0x7cb2, 0x7cb4, 0x7caf, 0x7d88, + 0x7d86, 0x7d80, 0x7d8d, 0x7d7f, 0x7d85, 0x7d7a, 0x7d8e, 0x7d7b, + 0x7d83, 0x7d7c, 0x7d8c, 0x7d94, 0x7d84, 0x7d7d, 0x7d92, 0x7f6d, + 0x7f6b, 0x7f67, 0x7f68, 0x7f6c, 0x7fa6, 0x7fa5, 0x7fa7, 0x7fdb, + 0x7fdc, 0x8021, 0x8164, 0x8160, 0x8177, 0x815c, 0x8169, 0x815b, + 0x8162, 0x8172, 0x6721, 0x815e, 0x8176, 0x8167, 0x816f, 0x8144, + 0x8161, 0x821d, 0x8249, 0x8244, 0x8240, 0x8242, 0x8245, 0x84f1, + 0x843f, 0x8456, 0x8476, 0x8479, 0x848f, 0x848d, 0x8465, 0x8451, + 0x8440, 0x8486, 0x8467, 0x8430, 0x844d, 0x847d, 0x845a, 0x8459, + 0x8474, 0x8473, 0x845d, 0x8507, 0x845e, 0x8437, 0x843a, 0x8434, + 0x847a, 0x8443, 0x8478, 0x8432, 0x8445, 0x8429, 0x83d9, 0x844b, + 0x842f, 0x8442, 0x842d, 0x845f, 0x8470, 0x8439, 0x844e, 0x844c, + 0x8452, 0x846f, 0x84c5, 0x848e, 0x843b, 0x8447, 0x8436, 0x8433, + 0x8468, 0x847e, 0x8444, 0x842b, 0x8460, 0x8454, 0x846e, 0x8450, + 0x870b, 0x8704, 0x86f7, 0x870c, 0x86fa, 0x86d6, 0x86f5, 0x874d, + 0x86f8, 0x870e, 0x8709, 0x8701, 0x86f6, 0x870d, 0x8705, 0x88d6, + 0x88cb, 0x88cd, 0x88ce, 0x88de, 0x88db, 0x88da, 0x88cc, 0x88d0, + 0x8985, 0x899b, 0x89df, 0x89e5, 0x89e4, + /* 0xe0 */ + 0x89e1, 0x89e0, 0x89e2, 0x89dc, 0x89e6, 0x8a76, 0x8a86, 0x8a7f, + 0x8a61, 0x8a3f, 0x8a77, 0x8a82, 0x8a84, 0x8a75, 0x8a83, 0x8a81, + 0x8a74, 0x8a7a, 0x8c3c, 0x8c4b, 0x8c4a, 0x8c65, 0x8c64, 0x8c66, + 0x8c86, 0x8c84, 0x8c85, 0x8ccc, 0x8d68, 0x8d69, 0x8d91, 0x8d8c, + 0x8d8e, 0x8d8f, 0x8d8d, 0x8d93, 0x8d94, 0x8d90, 0x8d92, 0x8df0, + 0x8de0, 0x8dec, 0x8df1, 0x8dee, 0x8dd0, 0x8de9, 0x8de3, 0x8de2, + 0x8de7, 0x8df2, 0x8deb, 0x8df4, 0x8f06, 0x8eff, 0x8f01, 0x8f00, + 0x8f05, 0x8f07, 0x8f08, 0x8f02, 0x8f0b, 0x9052, 0x903f, 0x9044, + 0x9049, 0x903d, 0x9110, 0x910d, 0x910f, 0x9111, 0x9116, 0x9114, + 0x910b, 0x910e, 0x916e, 0x916f, 0x9248, 0x9252, 0x9230, 0x923a, + 0x9266, 0x9233, 0x9265, 0x925e, 0x9283, 0x922e, 0x924a, 0x9246, + 0x926d, 0x926c, 0x924f, 0x9260, 0x9267, 0x926f, 0x9236, 0x9261, + 0x9270, 0x9231, 0x9254, 0x9263, 0x9250, 0x9272, 0x924e, 0x9253, + 0x924c, 0x9256, 0x9232, 0x959f, 0x959c, 0x959e, 0x959b, 0x9692, + 0x9693, 0x9691, 0x9697, 0x96ce, 0x96fa, 0x96fd, 0x96f8, 0x96f5, + 0x9773, 0x9777, 0x9778, 0x9772, 0x980f, 0x980d, 0x980e, 0x98ac, + 0x98f6, 0x98f9, 0x99af, 0x99b2, 0x99b0, 0x99b5, 0x9aad, 0x9aab, + 0x9b5b, 0x9cea, 0x9ced, 0x9ce7, 0x9e80, 0x9efd, 0x50e6, 0x50d4, + 0x50d7, 0x50e8, 0x50f3, 0x50db, 0x50ea, 0x50dd, 0x50e4, 0x50d3, + 0x50ec, 0x50f0, 0x50ef, 0x50e3, 0x50e0, + /* 0xe1 */ + 0x51d8, 0x5280, 0x5281, 0x52e9, 0x52eb, 0x5330, 0x53ac, 0x5627, + 0x5615, 0x560c, 0x5612, 0x55fc, 0x560f, 0x561c, 0x5601, 0x5613, + 0x5602, 0x55fa, 0x561d, 0x5604, 0x55ff, 0x55f9, 0x5889, 0x587c, + 0x5890, 0x5898, 0x5886, 0x5881, 0x587f, 0x5874, 0x588b, 0x587a, + 0x5887, 0x5891, 0x588e, 0x5876, 0x5882, 0x5888, 0x587b, 0x5894, + 0x588f, 0x58fe, 0x596b, 0x5adc, 0x5aee, 0x5ae5, 0x5ad5, 0x5aea, + 0x5ada, 0x5aed, 0x5aeb, 0x5af3, 0x5ae2, 0x5ae0, 0x5adb, 0x5aec, + 0x5ade, 0x5add, 0x5ad9, 0x5ae8, 0x5adf, 0x5b77, 0x5be0, 0x5be3, + 0x5c63, 0x5d82, 0x5d80, 0x5d7d, 0x5d86, 0x5d7a, 0x5d81, 0x5d77, + 0x5d8a, 0x5d89, 0x5d88, 0x5d7e, 0x5d7c, 0x5d8d, 0x5d79, 0x5d7f, + 0x5e58, 0x5e59, 0x5e53, 0x5ed8, 0x5ed1, 0x5ed7, 0x5ece, 0x5edc, + 0x5ed5, 0x5ed9, 0x5ed2, 0x5ed4, 0x5f44, 0x5f43, 0x5f6f, 0x5fb6, + 0x612c, 0x6128, 0x6141, 0x615e, 0x6171, 0x6173, 0x6152, 0x6153, + 0x6172, 0x616c, 0x6180, 0x6174, 0x6154, 0x617a, 0x615b, 0x6165, + 0x613b, 0x616a, 0x6161, 0x6156, 0x6229, 0x6227, 0x622b, 0x642b, + 0x644d, 0x645b, 0x645d, 0x6474, 0x6476, 0x6472, 0x6473, 0x647d, + 0x6475, 0x6466, 0x64a6, 0x644e, 0x6482, 0x645e, 0x645c, 0x644b, + 0x6453, 0x6460, 0x6450, 0x647f, 0x643f, 0x646c, 0x646b, 0x6459, + 0x6465, 0x6477, 0x6573, 0x65a0, 0x66a1, 0x66a0, 0x669f, 0x6705, + 0x6704, 0x6722, 0x69b1, 0x69b6, 0x69c9, + /* 0xe2 */ + 0x69a0, 0x69ce, 0x6996, 0x69b0, 0x69ac, 0x69bc, 0x6991, 0x6999, + 0x698e, 0x69a7, 0x698d, 0x69a9, 0x69be, 0x69af, 0x69bf, 0x69c4, + 0x69bd, 0x69a4, 0x69d4, 0x69b9, 0x69ca, 0x699a, 0x69cf, 0x69b3, + 0x6993, 0x69aa, 0x69a1, 0x699e, 0x69d9, 0x6997, 0x6990, 0x69c2, + 0x69b5, 0x69a5, 0x69c6, 0x6b4a, 0x6b4d, 0x6b4b, 0x6b9e, 0x6b9f, + 0x6ba0, 0x6bc3, 0x6bc4, 0x6bfe, 0x6ece, 0x6ef5, 0x6ef1, 0x6f03, + 0x6f25, 0x6ef8, 0x6f37, 0x6efb, 0x6f2e, 0x6f09, 0x6f4e, 0x6f19, + 0x6f1a, 0x6f27, 0x6f18, 0x6f3b, 0x6f12, 0x6eed, 0x6f0a, 0x6f36, + 0x6f73, 0x6ef9, 0x6eee, 0x6f2d, 0x6f40, 0x6f30, 0x6f3c, 0x6f35, + 0x6eeb, 0x6f07, 0x6f0e, 0x6f43, 0x6f05, 0x6efd, 0x6ef6, 0x6f39, + 0x6f1c, 0x6efc, 0x6f3a, 0x6f1f, 0x6f0d, 0x6f1e, 0x6f08, 0x6f21, + 0x7187, 0x7190, 0x7189, 0x7180, 0x7185, 0x7182, 0x718f, 0x717b, + 0x7186, 0x7181, 0x7197, 0x7244, 0x7253, 0x7297, 0x7295, 0x7293, + 0x7343, 0x734d, 0x7351, 0x734c, 0x7462, 0x7473, 0x7471, 0x7475, + 0x7472, 0x7467, 0x746e, 0x7500, 0x7502, 0x7503, 0x757d, 0x7590, + 0x7616, 0x7608, 0x760c, 0x7615, 0x7611, 0x760a, 0x7614, 0x76b8, + 0x7781, 0x777c, 0x7785, 0x7782, 0x776e, 0x7780, 0x776f, 0x777e, + 0x7783, 0x78b2, 0x78aa, 0x78b4, 0x78ad, 0x78a8, 0x787e, 0x78ab, + 0x789e, 0x78a5, 0x78a0, 0x78ac, 0x78a2, 0x78a4, 0x7998, 0x798a, + 0x798b, 0x7996, 0x7995, 0x7994, 0x7993, + /* 0xe3 */ + 0x7997, 0x7988, 0x7992, 0x7990, 0x7a2b, 0x7a4a, 0x7a30, 0x7a2f, + 0x7a28, 0x7a26, 0x7aa8, 0x7aab, 0x7aac, 0x7aee, 0x7b88, 0x7b9c, + 0x7b8a, 0x7b91, 0x7b90, 0x7b96, 0x7b8d, 0x7b8c, 0x7b9b, 0x7b8e, + 0x7b85, 0x7b98, 0x5284, 0x7b99, 0x7ba4, 0x7b82, 0x7cbb, 0x7cbf, + 0x7cbc, 0x7cba, 0x7da7, 0x7db7, 0x7dc2, 0x7da3, 0x7daa, 0x7dc1, + 0x7dc0, 0x7dc5, 0x7d9d, 0x7dce, 0x7dc4, 0x7dc6, 0x7dcb, 0x7dcc, + 0x7daf, 0x7db9, 0x7d96, 0x7dbc, 0x7d9f, 0x7da6, 0x7dae, 0x7da9, + 0x7da1, 0x7dc9, 0x7f73, 0x7fe2, 0x7fe3, 0x7fe5, 0x7fde, 0x8024, + 0x805d, 0x805c, 0x8189, 0x8186, 0x8183, 0x8187, 0x818d, 0x818c, + 0x818b, 0x8215, 0x8497, 0x84a4, 0x84a1, 0x849f, 0x84ba, 0x84ce, + 0x84c2, 0x84ac, 0x84ae, 0x84ab, 0x84b9, 0x84b4, 0x84c1, 0x84cd, + 0x84aa, 0x849a, 0x84b1, 0x84d0, 0x849d, 0x84a7, 0x84bb, 0x84a2, + 0x8494, 0x84c7, 0x84cc, 0x849b, 0x84a9, 0x84af, 0x84a8, 0x84d6, + 0x8498, 0x84b6, 0x84cf, 0x84a0, 0x84d7, 0x84d4, 0x84d2, 0x84db, + 0x84b0, 0x8491, 0x8661, 0x8733, 0x8723, 0x8728, 0x876b, 0x8740, + 0x872e, 0x871e, 0x8721, 0x8719, 0x871b, 0x8743, 0x872c, 0x8741, + 0x873e, 0x8746, 0x8720, 0x8732, 0x872a, 0x872d, 0x873c, 0x8712, + 0x873a, 0x8731, 0x8735, 0x8742, 0x8726, 0x8727, 0x8738, 0x8724, + 0x871a, 0x8730, 0x8711, 0x88f7, 0x88e7, 0x88f1, 0x88f2, 0x88fa, + 0x88fe, 0x88ee, 0x88fc, 0x88f6, 0x88fb, + /* 0xe4 */ + 0x88f0, 0x88ec, 0x88eb, 0x899d, 0x89a1, 0x899f, 0x899e, 0x89e9, + 0x89eb, 0x89e8, 0x8aab, 0x8a99, 0x8a8b, 0x8a92, 0x8a8f, 0x8a96, + 0x8c3d, 0x8c68, 0x8c69, 0x8cd5, 0x8ccf, 0x8cd7, 0x8d96, 0x8e09, + 0x8e02, 0x8dff, 0x8e0d, 0x8dfd, 0x8e0a, 0x8e03, 0x8e07, 0x8e06, + 0x8e05, 0x8dfe, 0x8e00, 0x8e04, 0x8f10, 0x8f11, 0x8f0e, 0x8f0d, + 0x9123, 0x911c, 0x9120, 0x9122, 0x911f, 0x911d, 0x911a, 0x9124, + 0x9121, 0x911b, 0x917a, 0x9172, 0x9179, 0x9173, 0x92a5, 0x92a4, + 0x9276, 0x929b, 0x927a, 0x92a0, 0x9294, 0x92aa, 0x928d, 0x92a6, + 0x929a, 0x92ab, 0x9279, 0x9297, 0x927f, 0x92a3, 0x92ee, 0x928e, + 0x9282, 0x9295, 0x92a2, 0x927d, 0x9288, 0x92a1, 0x928a, 0x9286, + 0x928c, 0x9299, 0x92a7, 0x927e, 0x9287, 0x92a9, 0x929d, 0x928b, + 0x922d, 0x969e, 0x96a1, 0x96ff, 0x9758, 0x977d, 0x977a, 0x977e, + 0x9783, 0x9780, 0x9782, 0x977b, 0x9784, 0x9781, 0x977f, 0x97ce, + 0x97cd, 0x9816, 0x98ad, 0x98ae, 0x9902, 0x9900, 0x9907, 0x999d, + 0x999c, 0x99c3, 0x99b9, 0x99bb, 0x99ba, 0x99c2, 0x99bd, 0x99c7, + 0x9ab1, 0x9ae3, 0x9ae7, 0x9b3e, 0x9b3f, 0x9b60, 0x9b61, 0x9b5f, + 0x9cf1, 0x9cf2, 0x9cf5, 0x9ea7, 0x50ff, 0x5103, 0x5130, 0x50f8, + 0x5106, 0x5107, 0x50f6, 0x50fe, 0x510b, 0x510c, 0x50fd, 0x510a, + 0x528b, 0x528c, 0x52f1, 0x52ef, 0x5648, 0x5642, 0x564c, 0x5635, + 0x5641, 0x564a, 0x5649, 0x5646, 0x5658, + /* 0xe5 */ + 0x565a, 0x5640, 0x5633, 0x563d, 0x562c, 0x563e, 0x5638, 0x562a, + 0x563a, 0x571a, 0x58ab, 0x589d, 0x58b1, 0x58a0, 0x58a3, 0x58af, + 0x58ac, 0x58a5, 0x58a1, 0x58ff, 0x5aff, 0x5af4, 0x5afd, 0x5af7, + 0x5af6, 0x5b03, 0x5af8, 0x5b02, 0x5af9, 0x5b01, 0x5b07, 0x5b05, + 0x5b0f, 0x5c67, 0x5d99, 0x5d97, 0x5d9f, 0x5d92, 0x5da2, 0x5d93, + 0x5d95, 0x5da0, 0x5d9c, 0x5da1, 0x5d9a, 0x5d9e, 0x5e69, 0x5e5d, + 0x5e60, 0x5e5c, 0x7df3, 0x5edb, 0x5ede, 0x5ee1, 0x5f49, 0x5fb2, + 0x618b, 0x6183, 0x6179, 0x61b1, 0x61b0, 0x61a2, 0x6189, 0x619b, + 0x6193, 0x61af, 0x61ad, 0x619f, 0x6192, 0x61aa, 0x61a1, 0x618d, + 0x6166, 0x61b3, 0x622d, 0x646e, 0x6470, 0x6496, 0x64a0, 0x6485, + 0x6497, 0x649c, 0x648f, 0x648b, 0x648a, 0x648c, 0x64a3, 0x649f, + 0x6468, 0x64b1, 0x6498, 0x6576, 0x657a, 0x6579, 0x657b, 0x65b2, + 0x65b3, 0x66b5, 0x66b0, 0x66a9, 0x66b2, 0x66b7, 0x66aa, 0x66af, + 0x6a00, 0x6a06, 0x6a17, 0x69e5, 0x69f8, 0x6a15, 0x69f1, 0x69e4, + 0x6a20, 0x69ff, 0x69ec, 0x69e2, 0x6a1b, 0x6a1d, 0x69fe, 0x6a27, + 0x69f2, 0x69ee, 0x6a14, 0x69f7, 0x69e7, 0x6a40, 0x6a08, 0x69e6, + 0x69fb, 0x6a0d, 0x69fc, 0x69eb, 0x6a09, 0x6a04, 0x6a18, 0x6a25, + 0x6a0f, 0x69f6, 0x6a26, 0x6a07, 0x69f4, 0x6a16, 0x6b51, 0x6ba5, + 0x6ba3, 0x6ba2, 0x6ba6, 0x6c01, 0x6c00, 0x6bff, 0x6c02, 0x6f41, + 0x6f26, 0x6f7e, 0x6f87, 0x6fc6, 0x6f92, + /* 0xe6 */ + 0x6f8d, 0x6f89, 0x6f8c, 0x6f62, 0x6f4f, 0x6f85, 0x6f5a, 0x6f96, + 0x6f76, 0x6f6c, 0x6f82, 0x6f55, 0x6f72, 0x6f52, 0x6f50, 0x6f57, + 0x6f94, 0x6f93, 0x6f5d, 0x6f00, 0x6f61, 0x6f6b, 0x6f7d, 0x6f67, + 0x6f90, 0x6f53, 0x6f8b, 0x6f69, 0x6f7f, 0x6f95, 0x6f63, 0x6f77, + 0x6f6a, 0x6f7b, 0x71b2, 0x71af, 0x719b, 0x71b0, 0x71a0, 0x719a, + 0x71a9, 0x71b5, 0x719d, 0x71a5, 0x719e, 0x71a4, 0x71a1, 0x71aa, + 0x719c, 0x71a7, 0x71b3, 0x7298, 0x729a, 0x7358, 0x7352, 0x735e, + 0x735f, 0x7360, 0x735d, 0x735b, 0x7361, 0x735a, 0x7359, 0x7362, + 0x7487, 0x7489, 0x748a, 0x7486, 0x7481, 0x747d, 0x7485, 0x7488, + 0x747c, 0x7479, 0x7508, 0x7507, 0x757e, 0x7625, 0x761e, 0x7619, + 0x761d, 0x761c, 0x7623, 0x761a, 0x7628, 0x761b, 0x769c, 0x769d, + 0x769e, 0x769b, 0x778d, 0x778f, 0x7789, 0x7788, 0x78cd, 0x78bb, + 0x78cf, 0x78cc, 0x78d1, 0x78ce, 0x78d4, 0x78c8, 0x78c3, 0x78c4, + 0x78c9, 0x799a, 0x79a1, 0x79a0, 0x799c, 0x79a2, 0x799b, 0x6b76, + 0x7a39, 0x7ab2, 0x7ab4, 0x7ab3, 0x7bb7, 0x7bcb, 0x7bbe, 0x7bac, + 0x7bce, 0x7baf, 0x7bb9, 0x7bca, 0x7bb5, 0x7cc5, 0x7cc8, 0x7ccc, + 0x7ccb, 0x7df7, 0x7ddb, 0x7dea, 0x7de7, 0x7dd7, 0x7de1, 0x7e03, + 0x7dfa, 0x7de6, 0x7df6, 0x7df1, 0x7df0, 0x7dee, 0x7ddf, 0x7f76, + 0x7fac, 0x7fb0, 0x7fad, 0x7fed, 0x7feb, 0x7fea, 0x7fec, 0x7fe6, + 0x7fe8, 0x8064, 0x8067, 0x81a3, 0x819f, + /* 0xe7 */ + 0x819e, 0x8195, 0x81a2, 0x8199, 0x8197, 0x8216, 0x824f, 0x8253, + 0x8252, 0x8250, 0x824e, 0x8251, 0x8524, 0x853b, 0x850f, 0x8500, + 0x8529, 0x850e, 0x8509, 0x850d, 0x851f, 0x850a, 0x8527, 0x851c, + 0x84fb, 0x852b, 0x84fa, 0x8508, 0x850c, 0x84f4, 0x852a, 0x84f2, + 0x8515, 0x84f7, 0x84eb, 0x84f3, 0x84fc, 0x8512, 0x84ea, 0x84e9, + 0x8516, 0x84fe, 0x8528, 0x851d, 0x852e, 0x8502, 0x84fd, 0x851e, + 0x84f6, 0x8531, 0x8526, 0x84e7, 0x84e8, 0x84f0, 0x84ef, 0x84f9, + 0x8518, 0x8520, 0x8530, 0x850b, 0x8519, 0x852f, 0x8662, 0x8756, + 0x8763, 0x8764, 0x8777, 0x87e1, 0x8773, 0x8758, 0x8754, 0x875b, + 0x8752, 0x8761, 0x875a, 0x8751, 0x875e, 0x876d, 0x876a, 0x8750, + 0x874e, 0x875f, 0x875d, 0x876f, 0x876c, 0x877a, 0x876e, 0x875c, + 0x8765, 0x874f, 0x877b, 0x8775, 0x8762, 0x8767, 0x8769, 0x885a, + 0x8905, 0x890c, 0x8914, 0x890b, 0x8917, 0x8918, 0x8919, 0x8906, + 0x8916, 0x8911, 0x890e, 0x8909, 0x89a2, 0x89a4, 0x89a3, 0x89ed, + 0x89f0, 0x89ec, 0x8acf, 0x8ac6, 0x8ab8, 0x8ad3, 0x8ad1, 0x8ad4, + 0x8ad5, 0x8abb, 0x8ad7, 0x8abe, 0x8ac0, 0x8ac5, 0x8ad8, 0x8ac3, + 0x8aba, 0x8abd, 0x8ad9, 0x8c3e, 0x8c4d, 0x8c8f, 0x8ce5, 0x8cdf, + 0x8cd9, 0x8ce8, 0x8cda, 0x8cdd, 0x8ce7, 0x8da0, 0x8d9c, 0x8da1, + 0x8d9b, 0x8e20, 0x8e23, 0x8e25, 0x8e24, 0x8e2e, 0x8e15, 0x8e1b, + 0x8e16, 0x8e11, 0x8e19, 0x8e26, 0x8e27, + /* 0xe8 */ + 0x8e14, 0x8e12, 0x8e18, 0x8e13, 0x8e1c, 0x8e17, 0x8e1a, 0x8f2c, + 0x8f24, 0x8f18, 0x8f1a, 0x8f20, 0x8f23, 0x8f16, 0x8f17, 0x9073, + 0x9070, 0x906f, 0x9067, 0x906b, 0x912f, 0x912b, 0x9129, 0x912a, + 0x9132, 0x9126, 0x912e, 0x9185, 0x9186, 0x918a, 0x9181, 0x9182, + 0x9184, 0x9180, 0x92d0, 0x92c3, 0x92c4, 0x92c0, 0x92d9, 0x92b6, + 0x92cf, 0x92f1, 0x92df, 0x92d8, 0x92e9, 0x92d7, 0x92dd, 0x92cc, + 0x92ef, 0x92c2, 0x92e8, 0x92ca, 0x92c8, 0x92ce, 0x92e6, 0x92cd, + 0x92d5, 0x92c9, 0x92e0, 0x92de, 0x92e7, 0x92d1, 0x92d3, 0x92b5, + 0x92e1, 0x92c6, 0x92b4, 0x957c, 0x95ac, 0x95ab, 0x95ae, 0x95b0, + 0x96a4, 0x96a2, 0x96d3, 0x9705, 0x9708, 0x9702, 0x975a, 0x978a, + 0x978e, 0x9788, 0x97d0, 0x97cf, 0x981e, 0x981d, 0x9826, 0x9829, + 0x9828, 0x9820, 0x981b, 0x9827, 0x98b2, 0x9908, 0x98fa, 0x9911, + 0x9914, 0x9916, 0x9917, 0x9915, 0x99dc, 0x99cd, 0x99cf, 0x99d3, + 0x99d4, 0x99ce, 0x99c9, 0x99d6, 0x99d8, 0x99cb, 0x99d7, 0x99cc, + 0x9ab3, 0x9aec, 0x9aeb, 0x9af3, 0x9af2, 0x9af1, 0x9b46, 0x9b43, + 0x9b67, 0x9b74, 0x9b71, 0x9b66, 0x9b76, 0x9b75, 0x9b70, 0x9b68, + 0x9b64, 0x9b6c, 0x9cfc, 0x9cfa, 0x9cfd, 0x9cff, 0x9cf7, 0x9d07, + 0x9d00, 0x9cf9, 0x9cfb, 0x9d08, 0x9d05, 0x9d04, 0x9e83, 0x9ed3, + 0x9f0f, 0x9f10, 0x511c, 0x5113, 0x5117, 0x511a, 0x5111, 0x51de, + 0x5334, 0x53e1, 0x5670, 0x5660, 0x566e, + /* 0xe9 */ + 0x5673, 0x5666, 0x5663, 0x566d, 0x5672, 0x565e, 0x5677, 0x571c, + 0x571b, 0x58c8, 0x58bd, 0x58c9, 0x58bf, 0x58ba, 0x58c2, 0x58bc, + 0x58c6, 0x5b17, 0x5b19, 0x5b1b, 0x5b21, 0x5b14, 0x5b13, 0x5b10, + 0x5b16, 0x5b28, 0x5b1a, 0x5b20, 0x5b1e, 0x5bef, 0x5dac, 0x5db1, + 0x5da9, 0x5da7, 0x5db5, 0x5db0, 0x5dae, 0x5daa, 0x5da8, 0x5db2, + 0x5dad, 0x5daf, 0x5db4, 0x5e67, 0x5e68, 0x5e66, 0x5e6f, 0x5ee9, + 0x5ee7, 0x5ee6, 0x5ee8, 0x5ee5, 0x5f4b, 0x5fbc, 0x619d, 0x61a8, + 0x6196, 0x61c5, 0x61b4, 0x61c6, 0x61c1, 0x61cc, 0x61ba, 0x61bf, + 0x61b8, 0x618c, 0x64d7, 0x64d6, 0x64d0, 0x64cf, 0x64c9, 0x64bd, + 0x6489, 0x64c3, 0x64db, 0x64f3, 0x64d9, 0x6533, 0x657f, 0x657c, + 0x65a2, 0x66c8, 0x66be, 0x66c0, 0x66ca, 0x66cb, 0x66cf, 0x66bd, + 0x66bb, 0x66ba, 0x66cc, 0x6723, 0x6a34, 0x6a66, 0x6a49, 0x6a67, + 0x6a32, 0x6a68, 0x6a3e, 0x6a5d, 0x6a6d, 0x6a76, 0x6a5b, 0x6a51, + 0x6a28, 0x6a5a, 0x6a3b, 0x6a3f, 0x6a41, 0x6a6a, 0x6a64, 0x6a50, + 0x6a4f, 0x6a54, 0x6a6f, 0x6a69, 0x6a60, 0x6a3c, 0x6a5e, 0x6a56, + 0x6a55, 0x6a4d, 0x6a4e, 0x6a46, 0x6b55, 0x6b54, 0x6b56, 0x6ba7, + 0x6baa, 0x6bab, 0x6bc8, 0x6bc7, 0x6c04, 0x6c03, 0x6c06, 0x6fad, + 0x6fcb, 0x6fa3, 0x6fc7, 0x6fbc, 0x6fce, 0x6fc8, 0x6f5e, 0x6fc4, + 0x6fbd, 0x6f9e, 0x6fca, 0x6fa8, 0x7004, 0x6fa5, 0x6fae, 0x6fba, + 0x6fac, 0x6faa, 0x6fcf, 0x6fbf, 0x6fb8, + /* 0xea */ + 0x6fa2, 0x6fc9, 0x6fab, 0x6fcd, 0x6faf, 0x6fb2, 0x6fb0, 0x71c5, + 0x71c2, 0x71bf, 0x71b8, 0x71d6, 0x71c0, 0x71c1, 0x71cb, 0x71d4, + 0x71ca, 0x71c7, 0x71cf, 0x71bd, 0x71d8, 0x71bc, 0x71c6, 0x71da, + 0x71db, 0x729d, 0x729e, 0x7369, 0x7366, 0x7367, 0x736c, 0x7365, + 0x736b, 0x736a, 0x747f, 0x749a, 0x74a0, 0x7494, 0x7492, 0x7495, + 0x74a1, 0x750b, 0x7580, 0x762f, 0x762d, 0x7631, 0x763d, 0x7633, + 0x763c, 0x7635, 0x7632, 0x7630, 0x76bb, 0x76e6, 0x779a, 0x779d, + 0x77a1, 0x779c, 0x779b, 0x77a2, 0x77a3, 0x7795, 0x7799, 0x7797, + 0x78dd, 0x78e9, 0x78e5, 0x78ea, 0x78de, 0x78e3, 0x78db, 0x78e1, + 0x78e2, 0x78ed, 0x78df, 0x78e0, 0x79a4, 0x7a44, 0x7a48, 0x7a47, + 0x7ab6, 0x7ab8, 0x7ab5, 0x7ab1, 0x7ab7, 0x7bde, 0x7be3, 0x7be7, + 0x7bdd, 0x7bd5, 0x7be5, 0x7bda, 0x7be8, 0x7bf9, 0x7bd4, 0x7bea, + 0x7be2, 0x7bdc, 0x7beb, 0x7bd8, 0x7bdf, 0x7cd2, 0x7cd4, 0x7cd7, + 0x7cd0, 0x7cd1, 0x7e12, 0x7e21, 0x7e17, 0x7e0c, 0x7e1f, 0x7e20, + 0x7e13, 0x7e0e, 0x7e1c, 0x7e15, 0x7e1a, 0x7e22, 0x7e0b, 0x7e0f, + 0x7e16, 0x7e0d, 0x7e14, 0x7e25, 0x7e24, 0x7f43, 0x7f7b, 0x7f7c, + 0x7f7a, 0x7fb1, 0x7fef, 0x802a, 0x8029, 0x806c, 0x81b1, 0x81a6, + 0x81ae, 0x81b9, 0x81b5, 0x81ab, 0x81b0, 0x81ac, 0x81b4, 0x81b2, + 0x81b7, 0x81a7, 0x81f2, 0x8255, 0x8256, 0x8257, 0x8556, 0x8545, + 0x856b, 0x854d, 0x8553, 0x8561, 0x8558, + /* 0xeb */ + 0x8540, 0x8546, 0x8564, 0x8541, 0x8562, 0x8544, 0x8551, 0x8547, + 0x8563, 0x853e, 0x855b, 0x8571, 0x854e, 0x856e, 0x8575, 0x8555, + 0x8567, 0x8560, 0x858c, 0x8566, 0x855d, 0x8554, 0x8565, 0x856c, + 0x8663, 0x8665, 0x8664, 0x879b, 0x878f, 0x8797, 0x8793, 0x8792, + 0x8788, 0x8781, 0x8796, 0x8798, 0x8779, 0x8787, 0x87a3, 0x8785, + 0x8790, 0x8791, 0x879d, 0x8784, 0x8794, 0x879c, 0x879a, 0x8789, + 0x891e, 0x8926, 0x8930, 0x892d, 0x892e, 0x8927, 0x8931, 0x8922, + 0x8929, 0x8923, 0x892f, 0x892c, 0x891f, 0x89f1, 0x8ae0, 0x8ae2, + 0x8af2, 0x8af4, 0x8af5, 0x8add, 0x8b14, 0x8ae4, 0x8adf, 0x8af0, + 0x8ac8, 0x8ade, 0x8ae1, 0x8ae8, 0x8aff, 0x8aef, 0x8afb, 0x8c91, + 0x8c92, 0x8c90, 0x8cf5, 0x8cee, 0x8cf1, 0x8cf0, 0x8cf3, 0x8d6c, + 0x8d6e, 0x8da5, 0x8da7, 0x8e33, 0x8e3e, 0x8e38, 0x8e40, 0x8e45, + 0x8e36, 0x8e3c, 0x8e3d, 0x8e41, 0x8e30, 0x8e3f, 0x8ebd, 0x8f36, + 0x8f2e, 0x8f35, 0x8f32, 0x8f39, 0x8f37, 0x8f34, 0x9076, 0x9079, + 0x907b, 0x9086, 0x90fa, 0x9133, 0x9135, 0x9136, 0x9193, 0x9190, + 0x9191, 0x918d, 0x918f, 0x9327, 0x931e, 0x9308, 0x931f, 0x9306, + 0x930f, 0x937a, 0x9338, 0x933c, 0x931b, 0x9323, 0x9312, 0x9301, + 0x9346, 0x932d, 0x930e, 0x930d, 0x92cb, 0x931d, 0x92fa, 0x9325, + 0x9313, 0x92f9, 0x92f7, 0x9334, 0x9302, 0x9324, 0x92ff, 0x9329, + 0x9339, 0x9335, 0x932a, 0x9314, 0x930c, + /* 0xec */ + 0x930b, 0x92fe, 0x9309, 0x9300, 0x92fb, 0x9316, 0x95bc, 0x95cd, + 0x95be, 0x95b9, 0x95ba, 0x95b6, 0x95bf, 0x95b5, 0x95bd, 0x96a9, + 0x96d4, 0x970b, 0x9712, 0x9710, 0x9799, 0x9797, 0x9794, 0x97f0, + 0x97f8, 0x9835, 0x982f, 0x9832, 0x9924, 0x991f, 0x9927, 0x9929, + 0x999e, 0x99ee, 0x99ec, 0x99e5, 0x99e4, 0x99f0, 0x99e3, 0x99ea, + 0x99e9, 0x99e7, 0x9ab9, 0x9abf, 0x9ab4, 0x9abb, 0x9af6, 0x9afa, + 0x9af9, 0x9af7, 0x9b33, 0x9b80, 0x9b85, 0x9b87, 0x9b7c, 0x9b7e, + 0x9b7b, 0x9b82, 0x9b93, 0x9b92, 0x9b90, 0x9b7a, 0x9b95, 0x9b7d, + 0x9b88, 0x9d25, 0x9d17, 0x9d20, 0x9d1e, 0x9d14, 0x9d29, 0x9d1d, + 0x9d18, 0x9d22, 0x9d10, 0x9d19, 0x9d1f, 0x9e88, 0x9e86, 0x9e87, + 0x9eae, 0x9ead, 0x9ed5, 0x9ed6, 0x9efa, 0x9f12, 0x9f3d, 0x5126, + 0x5125, 0x5122, 0x5124, 0x5120, 0x5129, 0x52f4, 0x5693, 0x568c, + 0x568d, 0x5686, 0x5684, 0x5683, 0x567e, 0x5682, 0x567f, 0x5681, + 0x58d6, 0x58d4, 0x58cf, 0x58d2, 0x5b2d, 0x5b25, 0x5b32, 0x5b23, + 0x5b2c, 0x5b27, 0x5b26, 0x5b2f, 0x5b2e, 0x5b7b, 0x5bf1, 0x5bf2, + 0x5db7, 0x5e6c, 0x5e6a, 0x5fbe, 0x5fbb, 0x61c3, 0x61b5, 0x61bc, + 0x61e7, 0x61e0, 0x61e5, 0x61e4, 0x61e8, 0x61de, 0x64ef, 0x64e9, + 0x64e3, 0x64eb, 0x64e4, 0x64e8, 0x6581, 0x6580, 0x65b6, 0x65da, + 0x66d2, 0x6a8d, 0x6a96, 0x6a81, 0x6aa5, 0x6a89, 0x6a9f, 0x6a9b, + 0x6aa1, 0x6a9e, 0x6a87, 0x6a93, 0x6a8e, + /* 0xed */ + 0x6a95, 0x6a83, 0x6aa8, 0x6aa4, 0x6a91, 0x6a7f, 0x6aa6, 0x6a9a, + 0x6a85, 0x6a8c, 0x6a92, 0x6b5b, 0x6bad, 0x6c09, 0x6fcc, 0x6fa9, + 0x6ff4, 0x6fd4, 0x6fe3, 0x6fdc, 0x6fed, 0x6fe7, 0x6fe6, 0x6fde, + 0x6ff2, 0x6fdd, 0x6fe2, 0x6fe8, 0x71e1, 0x71f1, 0x71e8, 0x71f2, + 0x71e4, 0x71f0, 0x71e2, 0x7373, 0x736e, 0x736f, 0x7497, 0x74b2, + 0x74ab, 0x7490, 0x74aa, 0x74ad, 0x74b1, 0x74a5, 0x74af, 0x7510, + 0x7511, 0x7512, 0x750f, 0x7584, 0x7643, 0x7648, 0x7649, 0x7647, + 0x76a4, 0x76e9, 0x77b5, 0x77ab, 0x77b2, 0x77b7, 0x77b6, 0x77b4, + 0x77b1, 0x77a8, 0x77f0, 0x78f3, 0x78fd, 0x7902, 0x78fb, 0x78fc, + 0x78f2, 0x7905, 0x78f9, 0x78fe, 0x7904, 0x79ab, 0x79a8, 0x7a5c, + 0x7a5b, 0x7a56, 0x7a58, 0x7a54, 0x7a5a, 0x7abe, 0x7ac0, 0x7ac1, + 0x7c05, 0x7c0f, 0x7bf2, 0x7c00, 0x7bff, 0x7bfb, 0x7c0e, 0x7bf4, + 0x7c0b, 0x7bf3, 0x7c02, 0x7c09, 0x7c03, 0x7c01, 0x7bf8, 0x7bfd, + 0x7c06, 0x7bf0, 0x7bf1, 0x7c10, 0x7c0a, 0x7ce8, 0x7e2d, 0x7e3c, + 0x7e42, 0x7e33, 0x9848, 0x7e38, 0x7e2a, 0x7e49, 0x7e40, 0x7e47, + 0x7e29, 0x7e4c, 0x7e30, 0x7e3b, 0x7e36, 0x7e44, 0x7e3a, 0x7f45, + 0x7f7f, 0x7f7e, 0x7f7d, 0x7ff4, 0x7ff2, 0x802c, 0x81bb, 0x81c4, + 0x81cc, 0x81ca, 0x81c5, 0x81c7, 0x81bc, 0x81e9, 0x825b, 0x825a, + 0x825c, 0x8583, 0x8580, 0x858f, 0x85a7, 0x8595, 0x85a0, 0x858b, + 0x85a3, 0x857b, 0x85a4, 0x859a, 0x859e, + /* 0xee */ + 0x8577, 0x857c, 0x8589, 0x85a1, 0x857a, 0x8578, 0x8557, 0x858e, + 0x8596, 0x8586, 0x858d, 0x8599, 0x859d, 0x8581, 0x85a2, 0x8582, + 0x8588, 0x8585, 0x8579, 0x8576, 0x8598, 0x8590, 0x859f, 0x8668, + 0x87be, 0x87aa, 0x87ad, 0x87c5, 0x87b0, 0x87ac, 0x87b9, 0x87b5, + 0x87bc, 0x87ae, 0x87c9, 0x87c3, 0x87c2, 0x87cc, 0x87b7, 0x87af, + 0x87c4, 0x87ca, 0x87b4, 0x87b6, 0x87bf, 0x87b8, 0x87bd, 0x87de, + 0x87b2, 0x8935, 0x8933, 0x893c, 0x893e, 0x8941, 0x8952, 0x8937, + 0x8942, 0x89ad, 0x89af, 0x89ae, 0x89f2, 0x89f3, 0x8b1e, 0x8b18, + 0x8b16, 0x8b11, 0x8b05, 0x8b0b, 0x8b22, 0x8b0f, 0x8b12, 0x8b15, + 0x8b07, 0x8b0d, 0x8b08, 0x8b06, 0x8b1c, 0x8b13, 0x8b1a, 0x8c4f, + 0x8c70, 0x8c72, 0x8c71, 0x8c6f, 0x8c95, 0x8c94, 0x8cf9, 0x8d6f, + 0x8e4e, 0x8e4d, 0x8e53, 0x8e50, 0x8e4c, 0x8e47, 0x8f43, 0x8f40, + 0x9085, 0x907e, 0x9138, 0x919a, 0x91a2, 0x919b, 0x9199, 0x919f, + 0x91a1, 0x919d, 0x91a0, 0x93a1, 0x9383, 0x93af, 0x9364, 0x9356, + 0x9347, 0x937c, 0x9358, 0x935c, 0x9376, 0x9349, 0x9350, 0x9351, + 0x9360, 0x936d, 0x938f, 0x934c, 0x936a, 0x9379, 0x9357, 0x9355, + 0x9352, 0x934f, 0x9371, 0x9377, 0x937b, 0x9361, 0x935e, 0x9363, + 0x9367, 0x9380, 0x934e, 0x9359, 0x95c7, 0x95c0, 0x95c9, 0x95c3, + 0x95c5, 0x95b7, 0x96ae, 0x96b0, 0x96ac, 0x9720, 0x971f, 0x9718, + 0x971d, 0x9719, 0x979a, 0x97a1, 0x979c, + /* 0xef */ + 0x979e, 0x979d, 0x97d5, 0x97d4, 0x97f1, 0x9841, 0x9844, 0x984a, + 0x9849, 0x9845, 0x9843, 0x9925, 0x992b, 0x992c, 0x992a, 0x9933, + 0x9932, 0x992f, 0x992d, 0x9931, 0x9930, 0x9998, 0x99a3, 0x99a1, + 0x9a02, 0x99fa, 0x99f4, 0x99f7, 0x99f9, 0x99f8, 0x99f6, 0x99fb, + 0x99fd, 0x99fe, 0x99fc, 0x9a03, 0x9abe, 0x9afe, 0x9afd, 0x9b01, + 0x9afc, 0x9b48, 0x9b9a, 0x9ba8, 0x9b9e, 0x9b9b, 0x9ba6, 0x9ba1, + 0x9ba5, 0x9ba4, 0x9b86, 0x9ba2, 0x9ba0, 0x9baf, 0x9d33, 0x9d41, + 0x9d67, 0x9d36, 0x9d2e, 0x9d2f, 0x9d31, 0x9d38, 0x9d30, 0x9d45, + 0x9d42, 0x9d43, 0x9d3e, 0x9d37, 0x9d40, 0x9d3d, 0x7ff5, 0x9d2d, + 0x9e8a, 0x9e89, 0x9e8d, 0x9eb0, 0x9ec8, 0x9eda, 0x9efb, 0x9eff, + 0x9f24, 0x9f23, 0x9f22, 0x9f54, 0x9fa0, 0x5131, 0x512d, 0x512e, + 0x5698, 0x569c, 0x5697, 0x569a, 0x569d, 0x5699, 0x5970, 0x5b3c, + 0x5c69, 0x5c6a, 0x5dc0, 0x5e6d, 0x5e6e, 0x61d8, 0x61df, 0x61ed, + 0x61ee, 0x61f1, 0x61ea, 0x61f0, 0x61eb, 0x61d6, 0x61e9, 0x64ff, + 0x6504, 0x64fd, 0x64f8, 0x6501, 0x6503, 0x64fc, 0x6594, 0x65db, + 0x66da, 0x66db, 0x66d8, 0x6ac5, 0x6ab9, 0x6abd, 0x6ae1, 0x6ac6, + 0x6aba, 0x6ab6, 0x6ab7, 0x6ac7, 0x6ab4, 0x6aad, 0x6b5e, 0x6bc9, + 0x6c0b, 0x7007, 0x700c, 0x700d, 0x7001, 0x7005, 0x7014, 0x700e, + 0x6fff, 0x7000, 0x6ffb, 0x7026, 0x6ffc, 0x6ff7, 0x700a, 0x7201, + 0x71ff, 0x71f9, 0x7203, 0x71fd, 0x7376, + /* 0xf0 */ + 0x74b8, 0x74c0, 0x74b5, 0x74c1, 0x74be, 0x74b6, 0x74bb, 0x74c2, + 0x7514, 0x7513, 0x765c, 0x7664, 0x7659, 0x7650, 0x7653, 0x7657, + 0x765a, 0x76a6, 0x76bd, 0x76ec, 0x77c2, 0x77ba, 0x78ff, 0x790c, + 0x7913, 0x7914, 0x7909, 0x7910, 0x7912, 0x7911, 0x79ad, 0x79ac, + 0x7a5f, 0x7c1c, 0x7c29, 0x7c19, 0x7c20, 0x7c1f, 0x7c2d, 0x7c1d, + 0x7c26, 0x7c28, 0x7c22, 0x7c25, 0x7c30, 0x7e5c, 0x7e50, 0x7e56, + 0x7e63, 0x7e58, 0x7e62, 0x7e5f, 0x7e51, 0x7e60, 0x7e57, 0x7e53, + 0x7fb5, 0x7fb3, 0x7ff7, 0x7ff8, 0x8075, 0x81d1, 0x81d2, 0x81d0, + 0x825f, 0x825e, 0x85b4, 0x85c6, 0x85c0, 0x85c3, 0x85c2, 0x85b3, + 0x85b5, 0x85bd, 0x85c7, 0x85c4, 0x85bf, 0x85cb, 0x85ce, 0x85c8, + 0x85c5, 0x85b1, 0x85b6, 0x85d2, 0x8624, 0x85b8, 0x85b7, 0x85be, + 0x8669, 0x87e7, 0x87e6, 0x87e2, 0x87db, 0x87eb, 0x87ea, 0x87e5, + 0x87df, 0x87f3, 0x87e4, 0x87d4, 0x87dc, 0x87d3, 0x87ed, 0x87d8, + 0x87e3, 0x87a4, 0x87d7, 0x87d9, 0x8801, 0x87f4, 0x87e8, 0x87dd, + 0x8953, 0x894b, 0x894f, 0x894c, 0x8946, 0x8950, 0x8951, 0x8949, + 0x8b2a, 0x8b27, 0x8b23, 0x8b33, 0x8b30, 0x8b35, 0x8b47, 0x8b2f, + 0x8b3c, 0x8b3e, 0x8b31, 0x8b25, 0x8b37, 0x8b26, 0x8b36, 0x8b2e, + 0x8b24, 0x8b3b, 0x8b3d, 0x8b3a, 0x8c42, 0x8c75, 0x8c99, 0x8c98, + 0x8c97, 0x8cfe, 0x8d04, 0x8d02, 0x8d00, 0x8e5c, 0x8e62, 0x8e60, + 0x8e57, 0x8e56, 0x8e5e, 0x8e65, 0x8e67, + /* 0xf1 */ + 0x8e5b, 0x8e5a, 0x8e61, 0x8e5d, 0x8e69, 0x8e54, 0x8f46, 0x8f47, + 0x8f48, 0x8f4b, 0x9128, 0x913a, 0x913b, 0x913e, 0x91a8, 0x91a5, + 0x91a7, 0x91af, 0x91aa, 0x93b5, 0x938c, 0x9392, 0x93b7, 0x939b, + 0x939d, 0x9389, 0x93a7, 0x938e, 0x93aa, 0x939e, 0x93a6, 0x9395, + 0x9388, 0x9399, 0x939f, 0x938d, 0x93b1, 0x9391, 0x93b2, 0x93a4, + 0x93a8, 0x93b4, 0x93a3, 0x93a5, 0x95d2, 0x95d3, 0x95d1, 0x96b3, + 0x96d7, 0x96da, 0x5dc2, 0x96df, 0x96d8, 0x96dd, 0x9723, 0x9722, + 0x9725, 0x97ac, 0x97ae, 0x97a8, 0x97ab, 0x97a4, 0x97aa, 0x97a2, + 0x97a5, 0x97d7, 0x97d9, 0x97d6, 0x97d8, 0x97fa, 0x9850, 0x9851, + 0x9852, 0x98b8, 0x9941, 0x993c, 0x993a, 0x9a0f, 0x9a0b, 0x9a09, + 0x9a0d, 0x9a04, 0x9a11, 0x9a0a, 0x9a05, 0x9a07, 0x9a06, 0x9ac0, + 0x9adc, 0x9b08, 0x9b04, 0x9b05, 0x9b29, 0x9b35, 0x9b4a, 0x9b4c, + 0x9b4b, 0x9bc7, 0x9bc6, 0x9bc3, 0x9bbf, 0x9bc1, 0x9bb5, 0x9bb8, + 0x9bd3, 0x9bb6, 0x9bc4, 0x9bb9, 0x9bbd, 0x9d5c, 0x9d53, 0x9d4f, + 0x9d4a, 0x9d5b, 0x9d4b, 0x9d59, 0x9d56, 0x9d4c, 0x9d57, 0x9d52, + 0x9d54, 0x9d5f, 0x9d58, 0x9d5a, 0x9e8e, 0x9e8c, 0x9edf, 0x9f01, + 0x9f00, 0x9f16, 0x9f25, 0x9f2b, 0x9f2a, 0x9f29, 0x9f28, 0x9f4c, + 0x9f55, 0x5134, 0x5135, 0x5296, 0x52f7, 0x53b4, 0x56ab, 0x56ad, + 0x56a6, 0x56a7, 0x56aa, 0x56ac, 0x58da, 0x58dd, 0x58db, 0x5912, + 0x5b3d, 0x5b3e, 0x5b3f, 0x5dc3, 0x5e70, + /* 0xf2 */ + 0x5fbf, 0x61fb, 0x6507, 0x6510, 0x650d, 0x6509, 0x650c, 0x650e, + 0x6584, 0x65de, 0x65dd, 0x66de, 0x6ae7, 0x6ae0, 0x6acc, 0x6ad1, + 0x6ad9, 0x6acb, 0x6adf, 0x6adc, 0x6ad0, 0x6aeb, 0x6acf, 0x6acd, + 0x6ade, 0x6b60, 0x6bb0, 0x6c0c, 0x7019, 0x7027, 0x7020, 0x7016, + 0x702b, 0x7021, 0x7022, 0x7023, 0x7029, 0x7017, 0x7024, 0x701c, + 0x702a, 0x720c, 0x720a, 0x7207, 0x7202, 0x7205, 0x72a5, 0x72a6, + 0x72a4, 0x72a3, 0x72a1, 0x74cb, 0x74c5, 0x74b7, 0x74c3, 0x7516, + 0x7660, 0x77c9, 0x77ca, 0x77c4, 0x77f1, 0x791d, 0x791b, 0x7921, + 0x791c, 0x7917, 0x791e, 0x79b0, 0x7a67, 0x7a68, 0x7c33, 0x7c3c, + 0x7c39, 0x7c2c, 0x7c3b, 0x7cec, 0x7cea, 0x7e76, 0x7e75, 0x7e78, + 0x7e70, 0x7e77, 0x7e6f, 0x7e7a, 0x7e72, 0x7e74, 0x7e68, 0x7f4b, + 0x7f4a, 0x7f83, 0x7f86, 0x7fb7, 0x7ffd, 0x7ffe, 0x8078, 0x81d7, + 0x81d5, 0x8264, 0x8261, 0x8263, 0x85eb, 0x85f1, 0x85ed, 0x85d9, + 0x85e1, 0x85e8, 0x85da, 0x85d7, 0x85ec, 0x85f2, 0x85f8, 0x85d8, + 0x85df, 0x85e3, 0x85dc, 0x85d1, 0x85f0, 0x85e6, 0x85ef, 0x85de, + 0x85e2, 0x8800, 0x87fa, 0x8803, 0x87f6, 0x87f7, 0x8809, 0x880c, + 0x880b, 0x8806, 0x87fc, 0x8808, 0x87ff, 0x880a, 0x8802, 0x8962, + 0x895a, 0x895b, 0x8957, 0x8961, 0x895c, 0x8958, 0x895d, 0x8959, + 0x8988, 0x89b7, 0x89b6, 0x89f6, 0x8b50, 0x8b48, 0x8b4a, 0x8b40, + 0x8b53, 0x8b56, 0x8b54, 0x8b4b, 0x8b55, + /* 0xf3 */ + 0x8b51, 0x8b42, 0x8b52, 0x8b57, 0x8c43, 0x8c77, 0x8c76, 0x8c9a, + 0x8d06, 0x8d07, 0x8d09, 0x8dac, 0x8daa, 0x8dad, 0x8dab, 0x8e6d, + 0x8e78, 0x8e73, 0x8e6a, 0x8e6f, 0x8e7b, 0x8ec2, 0x8f52, 0x8f51, + 0x8f4f, 0x8f50, 0x8f53, 0x8fb4, 0x9140, 0x913f, 0x91b0, 0x91ad, + 0x93de, 0x93c7, 0x93cf, 0x93c2, 0x93da, 0x93d0, 0x93f9, 0x93ec, + 0x93cc, 0x93d9, 0x93a9, 0x93e6, 0x93ca, 0x93d4, 0x93ee, 0x93e3, + 0x93d5, 0x93c4, 0x93ce, 0x93c0, 0x93d2, 0x93e7, 0x957d, 0x95da, + 0x95db, 0x96e1, 0x9729, 0x972b, 0x972c, 0x9728, 0x9726, 0x97b3, + 0x97b7, 0x97b6, 0x97dd, 0x97de, 0x97df, 0x985c, 0x9859, 0x985d, + 0x9857, 0x98bf, 0x98bd, 0x98bb, 0x98be, 0x9948, 0x9947, 0x9943, + 0x99a6, 0x99a7, 0x9a1a, 0x9a15, 0x9a25, 0x9a1d, 0x9a24, 0x9a1b, + 0x9a22, 0x9a20, 0x9a27, 0x9a23, 0x9a1e, 0x9a1c, 0x9a14, 0x9ac2, + 0x9b0b, 0x9b0a, 0x9b0e, 0x9b0c, 0x9b37, 0x9bea, 0x9beb, 0x9be0, + 0x9bde, 0x9be4, 0x9be6, 0x9be2, 0x9bf0, 0x9bd4, 0x9bd7, 0x9bec, + 0x9bdc, 0x9bd9, 0x9be5, 0x9bd5, 0x9be1, 0x9bda, 0x9d77, 0x9d81, + 0x9d8a, 0x9d84, 0x9d88, 0x9d71, 0x9d80, 0x9d78, 0x9d86, 0x9d8b, + 0x9d8c, 0x9d7d, 0x9d6b, 0x9d74, 0x9d75, 0x9d70, 0x9d69, 0x9d85, + 0x9d73, 0x9d7b, 0x9d82, 0x9d6f, 0x9d79, 0x9d7f, 0x9d87, 0x9d68, + 0x9e94, 0x9e91, 0x9ec0, 0x9efc, 0x9f2d, 0x9f40, 0x9f41, 0x9f4d, + 0x9f56, 0x9f57, 0x9f58, 0x5337, 0x56b2, + /* 0xf4 */ + 0x56b5, 0x56b3, 0x58e3, 0x5b45, 0x5dc6, 0x5dc7, 0x5eee, 0x5eef, + 0x5fc0, 0x5fc1, 0x61f9, 0x6517, 0x6516, 0x6515, 0x6513, 0x65df, + 0x66e8, 0x66e3, 0x66e4, 0x6af3, 0x6af0, 0x6aea, 0x6ae8, 0x6af9, + 0x6af1, 0x6aee, 0x6aef, 0x703c, 0x7035, 0x702f, 0x7037, 0x7034, + 0x7031, 0x7042, 0x7038, 0x703f, 0x703a, 0x7039, 0x7040, 0x703b, + 0x7033, 0x7041, 0x7213, 0x7214, 0x72a8, 0x737d, 0x737c, 0x74ba, + 0x76ab, 0x76aa, 0x76be, 0x76ed, 0x77cc, 0x77ce, 0x77cf, 0x77cd, + 0x77f2, 0x7925, 0x7923, 0x7927, 0x7928, 0x7924, 0x7929, 0x79b2, + 0x7a6e, 0x7a6c, 0x7a6d, 0x7af7, 0x7c49, 0x7c48, 0x7c4a, 0x7c47, + 0x7c45, 0x7cee, 0x7e7b, 0x7e7e, 0x7e81, 0x7e80, 0x7fba, 0x7fff, + 0x8079, 0x81db, 0x81d9, 0x820b, 0x8268, 0x8269, 0x8622, 0x85ff, + 0x8601, 0x85fe, 0x861b, 0x8600, 0x85f6, 0x8604, 0x8609, 0x8605, + 0x860c, 0x85fd, 0x8819, 0x8810, 0x8811, 0x8817, 0x8813, 0x8816, + 0x8963, 0x8966, 0x89b9, 0x89f7, 0x8b60, 0x8b6a, 0x8b5d, 0x8b68, + 0x8b63, 0x8b65, 0x8b67, 0x8b6d, 0x8dae, 0x8e86, 0x8e88, 0x8e84, + 0x8f59, 0x8f56, 0x8f57, 0x8f55, 0x8f58, 0x8f5a, 0x908d, 0x9143, + 0x9141, 0x91b7, 0x91b5, 0x91b2, 0x91b3, 0x940b, 0x9413, 0x93fb, + 0x9420, 0x940f, 0x9414, 0x93fe, 0x9415, 0x9410, 0x9428, 0x9419, + 0x940d, 0x93f5, 0x9400, 0x93f7, 0x9407, 0x940e, 0x9416, 0x9412, + 0x93fa, 0x9409, 0x93f8, 0x940a, 0x93ff, + /* 0xf5 */ + 0x93fc, 0x940c, 0x93f6, 0x9411, 0x9406, 0x95de, 0x95e0, 0x95df, + 0x972e, 0x972f, 0x97b9, 0x97bb, 0x97fd, 0x97fe, 0x9860, 0x9862, + 0x9863, 0x985f, 0x98c1, 0x98c2, 0x9950, 0x994e, 0x9959, 0x994c, + 0x994b, 0x9953, 0x9a32, 0x9a34, 0x9a31, 0x9a2c, 0x9a2a, 0x9a36, + 0x9a29, 0x9a2e, 0x9a38, 0x9a2d, 0x9ac7, 0x9aca, 0x9ac6, 0x9b10, + 0x9b12, 0x9b11, 0x9c0b, 0x9c08, 0x9bf7, 0x9c05, 0x9c12, 0x9bf8, + 0x9c40, 0x9c07, 0x9c0e, 0x9c06, 0x9c17, 0x9c14, 0x9c09, 0x9d9f, + 0x9d99, 0x9da4, 0x9d9d, 0x9d92, 0x9d98, 0x9d90, 0x9d9b, 0x9da0, + 0x9d94, 0x9d9c, 0x9daa, 0x9d97, 0x9da1, 0x9d9a, 0x9da2, 0x9da8, + 0x9d9e, 0x9da3, 0x9dbf, 0x9da9, 0x9d96, 0x9da6, 0x9da7, 0x9e99, + 0x9e9b, 0x9e9a, 0x9ee5, 0x9ee4, 0x9ee7, 0x9ee6, 0x9f30, 0x9f2e, + 0x9f5b, 0x9f60, 0x9f5e, 0x9f5d, 0x9f59, 0x9f91, 0x513a, 0x5139, + 0x5298, 0x5297, 0x56c3, 0x56bd, 0x56be, 0x5b48, 0x5b47, 0x5dcb, + 0x5dcf, 0x5ef1, 0x61fd, 0x651b, 0x6b02, 0x6afc, 0x6b03, 0x6af8, + 0x6b00, 0x7043, 0x7044, 0x704a, 0x7048, 0x7049, 0x7045, 0x7046, + 0x721d, 0x721a, 0x7219, 0x737e, 0x7517, 0x766a, 0x77d0, 0x792d, + 0x7931, 0x792f, 0x7c54, 0x7c53, 0x7cf2, 0x7e8a, 0x7e87, 0x7e88, + 0x7e8b, 0x7e86, 0x7e8d, 0x7f4d, 0x7fbb, 0x8030, 0x81dd, 0x8618, + 0x862a, 0x8626, 0x861f, 0x8623, 0x861c, 0x8619, 0x8627, 0x862e, + 0x8621, 0x8620, 0x8629, 0x861e, 0x8625, + /* 0xf6 */ + 0x8829, 0x881d, 0x881b, 0x8820, 0x8824, 0x881c, 0x882b, 0x884a, + 0x896d, 0x8969, 0x896e, 0x896b, 0x89fa, 0x8b79, 0x8b78, 0x8b45, + 0x8b7a, 0x8b7b, 0x8d10, 0x8d14, 0x8daf, 0x8e8e, 0x8e8c, 0x8f5e, + 0x8f5b, 0x8f5d, 0x9146, 0x9144, 0x9145, 0x91b9, 0x943f, 0x943b, + 0x9436, 0x9429, 0x943d, 0x943c, 0x9430, 0x9439, 0x942a, 0x9437, + 0x942c, 0x9440, 0x9431, 0x95e5, 0x95e4, 0x95e3, 0x9735, 0x973a, + 0x97bf, 0x97e1, 0x9864, 0x98c9, 0x98c6, 0x98c0, 0x9958, 0x9956, + 0x9a39, 0x9a3d, 0x9a46, 0x9a44, 0x9a42, 0x9a41, 0x9a3a, 0x9a3f, + 0x9acd, 0x9b15, 0x9b17, 0x9b18, 0x9b16, 0x9b3a, 0x9b52, 0x9c2b, + 0x9c1d, 0x9c1c, 0x9c2c, 0x9c23, 0x9c28, 0x9c29, 0x9c24, 0x9c21, + 0x9db7, 0x9db6, 0x9dbc, 0x9dc1, 0x9dc7, 0x9dca, 0x9dcf, 0x9dbe, + 0x9dc5, 0x9dc3, 0x9dbb, 0x9db5, 0x9dce, 0x9db9, 0x9dba, 0x9dac, + 0x9dc8, 0x9db1, 0x9dad, 0x9dcc, 0x9db3, 0x9dcd, 0x9db2, 0x9e7a, + 0x9e9c, 0x9eeb, 0x9eee, 0x9eed, 0x9f1b, 0x9f18, 0x9f1a, 0x9f31, + 0x9f4e, 0x9f65, 0x9f64, 0x9f92, 0x4eb9, 0x56c6, 0x56c5, 0x56cb, + 0x5971, 0x5b4b, 0x5b4c, 0x5dd5, 0x5dd1, 0x5ef2, 0x6521, 0x6520, + 0x6526, 0x6522, 0x6b0b, 0x6b08, 0x6b09, 0x6c0d, 0x7055, 0x7056, + 0x7057, 0x7052, 0x721e, 0x721f, 0x72a9, 0x737f, 0x74d8, 0x74d5, + 0x74d9, 0x74d7, 0x766d, 0x76ad, 0x7935, 0x79b4, 0x7a70, 0x7a71, + 0x7c57, 0x7c5c, 0x7c59, 0x7c5b, 0x7c5a, + /* 0xf7 */ + 0x7cf4, 0x7cf1, 0x7e91, 0x7f4f, 0x7f87, 0x81de, 0x826b, 0x8634, + 0x8635, 0x8633, 0x862c, 0x8632, 0x8636, 0x882c, 0x8828, 0x8826, + 0x882a, 0x8825, 0x8971, 0x89bf, 0x89be, 0x89fb, 0x8b7e, 0x8b84, + 0x8b82, 0x8b86, 0x8b85, 0x8b7f, 0x8d15, 0x8e95, 0x8e94, 0x8e9a, + 0x8e92, 0x8e90, 0x8e96, 0x8e97, 0x8f60, 0x8f62, 0x9147, 0x944c, + 0x9450, 0x944a, 0x944b, 0x944f, 0x9447, 0x9445, 0x9448, 0x9449, + 0x9446, 0x973f, 0x97e3, 0x986a, 0x9869, 0x98cb, 0x9954, 0x995b, + 0x9a4e, 0x9a53, 0x9a54, 0x9a4c, 0x9a4f, 0x9a48, 0x9a4a, 0x9a49, + 0x9a52, 0x9a50, 0x9ad0, 0x9b19, 0x9b2b, 0x9b3b, 0x9b56, 0x9b55, + 0x9c46, 0x9c48, 0x9c3f, 0x9c44, 0x9c39, 0x9c33, 0x9c41, 0x9c3c, + 0x9c37, 0x9c34, 0x9c32, 0x9c3d, 0x9c36, 0x9ddb, 0x9dd2, 0x9dde, + 0x9dda, 0x9dcb, 0x9dd0, 0x9ddc, 0x9dd1, 0x9ddf, 0x9de9, 0x9dd9, + 0x9dd8, 0x9dd6, 0x9df5, 0x9dd5, 0x9ddd, 0x9eb6, 0x9ef0, 0x9f35, + 0x9f33, 0x9f32, 0x9f42, 0x9f6b, 0x9f95, 0x9fa2, 0x513d, 0x5299, + 0x58e8, 0x58e7, 0x5972, 0x5b4d, 0x5dd8, 0x882f, 0x5f4f, 0x6201, + 0x6203, 0x6204, 0x6529, 0x6525, 0x6596, 0x66eb, 0x6b11, 0x6b12, + 0x6b0f, 0x6bca, 0x705b, 0x705a, 0x7222, 0x7382, 0x7381, 0x7383, + 0x7670, 0x77d4, 0x7c67, 0x7c66, 0x7e95, 0x826c, 0x863a, 0x8640, + 0x8639, 0x863c, 0x8631, 0x863b, 0x863e, 0x8830, 0x8832, 0x882e, + 0x8833, 0x8976, 0x8974, 0x8973, 0x89fe, + /* 0xf8 */ + 0x8b8c, 0x8b8e, 0x8b8b, 0x8b88, 0x8c45, 0x8d19, 0x8e98, 0x8f64, + 0x8f63, 0x91bc, 0x9462, 0x9455, 0x945d, 0x9457, 0x945e, 0x97c4, + 0x97c5, 0x9800, 0x9a56, 0x9a59, 0x9b1e, 0x9b1f, 0x9b20, 0x9c52, + 0x9c58, 0x9c50, 0x9c4a, 0x9c4d, 0x9c4b, 0x9c55, 0x9c59, 0x9c4c, + 0x9c4e, 0x9dfb, 0x9df7, 0x9def, 0x9de3, 0x9deb, 0x9df8, 0x9de4, + 0x9df6, 0x9de1, 0x9dee, 0x9de6, 0x9df2, 0x9df0, 0x9de2, 0x9dec, + 0x9df4, 0x9df3, 0x9de8, 0x9ded, 0x9ec2, 0x9ed0, 0x9ef2, 0x9ef3, + 0x9f06, 0x9f1c, 0x9f38, 0x9f37, 0x9f36, 0x9f43, 0x9f4f, 0x9f71, + 0x9f70, 0x9f6e, 0x9f6f, 0x56d3, 0x56cd, 0x5b4e, 0x5c6d, 0x652d, + 0x66ed, 0x66ee, 0x6b13, 0x705f, 0x7061, 0x705d, 0x7060, 0x7223, + 0x74db, 0x74e5, 0x77d5, 0x7938, 0x79b7, 0x79b6, 0x7c6a, 0x7e97, + 0x7f89, 0x826d, 0x8643, 0x8838, 0x8837, 0x8835, 0x884b, 0x8b94, + 0x8b95, 0x8e9e, 0x8e9f, 0x8ea0, 0x8e9d, 0x91be, 0x91bd, 0x91c2, + 0x946b, 0x9468, 0x9469, 0x96e5, 0x9746, 0x9743, 0x9747, 0x97c7, + 0x97e5, 0x9a5e, 0x9ad5, 0x9b59, 0x9c63, 0x9c67, 0x9c66, 0x9c62, + 0x9c5e, 0x9c60, 0x9e02, 0x9dfe, 0x9e07, 0x9e03, 0x9e06, 0x9e05, + 0x9e00, 0x9e01, 0x9e09, 0x9dff, 0x9dfd, 0x9e04, 0x9ea0, 0x9f1e, + 0x9f46, 0x9f74, 0x9f75, 0x9f76, 0x56d4, 0x652e, 0x65b8, 0x6b18, + 0x6b19, 0x6b17, 0x6b1a, 0x7062, 0x7226, 0x72aa, 0x77d8, 0x77d9, + 0x7939, 0x7c69, 0x7c6b, 0x7cf6, 0x7e9a, + /* 0xf9 */ + 0x7e98, 0x7e9b, 0x7e99, 0x81e0, 0x81e1, 0x8646, 0x8647, 0x8648, + 0x8979, 0x897a, 0x897c, 0x897b, 0x89ff, 0x8b98, 0x8b99, 0x8ea5, + 0x8ea4, 0x8ea3, 0x946e, 0x946d, 0x946f, 0x9471, 0x9473, 0x9749, + 0x9872, 0x995f, 0x9c68, 0x9c6e, 0x9c6d, 0x9e0b, 0x9e0d, 0x9e10, + 0x9e0f, 0x9e12, 0x9e11, 0x9ea1, 0x9ef5, 0x9f09, 0x9f47, 0x9f78, + 0x9f7b, 0x9f7a, 0x9f79, 0x571e, 0x7066, 0x7c6f, 0x883c, 0x8db2, + 0x8ea6, 0x91c3, 0x9474, 0x9478, 0x9476, 0x9475, 0x9a60, 0x9c74, + 0x9c73, 0x9c71, 0x9c75, 0x9e14, 0x9e13, 0x9ef6, 0x9f0a, 0x9fa4, + 0x7068, 0x7065, 0x7cf7, 0x866a, 0x883e, 0x883d, 0x883f, 0x8b9e, + 0x8c9c, 0x8ea9, 0x8ec9, 0x974b, 0x9873, 0x9874, 0x98cc, 0x9961, + 0x99ab, 0x9a64, 0x9a66, 0x9a67, 0x9b24, 0x9e15, 0x9e17, 0x9f48, + 0x6207, 0x6b1e, 0x7227, 0x864c, 0x8ea8, 0x9482, 0x9480, 0x9481, + 0x9a69, 0x9a68, 0x9b2e, 0x9e19, 0x7229, 0x864b, 0x8b9f, 0x9483, + 0x9c79, 0x9eb7, 0x7675, 0x9a6b, 0x9c7a, 0x9e1d, 0x7069, 0x706a, + 0x9ea4, 0x9f7e, 0x9f49, 0x9f98, +}; + +static int +big5_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c1 = s[0]; + if ((c1 >= 0xa1 && c1 <= 0xc7) || (c1 >= 0xc9 && c1 <= 0xf9)) { + if (n >= 2) { + unsigned char c2 = s[1]; + if ((c2 >= 0x40 && c2 < 0x7f) || (c2 >= 0xa1 && c2 < 0xff)) { + unsigned int i = 157 * (c1 - 0xa1) + (c2 - (c2 >= 0xa1 ? 0x62 : 0x40)); + unsigned short wc = 0xfffd; + if (i < 6280) { + if (i < 6121) + wc = big5_2uni_pagea1[i]; + } else { + if (i < 13932) + wc = big5_2uni_pagec9[i-6280]; + } + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 2; + } + } + return RET_ILSEQ; + } + return RET_TOOFEW(0); + } + return RET_ILSEQ; +} + +static const unsigned short big5_2charset[13703] = { + 0xa246, 0xa247, 0xa244, 0xa1b1, 0xa258, 0xa1d3, 0xa150, 0xa1d1, + 0xa1d2, 0xa3be, 0xa3bc, 0xa3bd, 0xa3bf, 0xa3bb, 0xa344, 0xa345, + 0xa346, 0xa347, 0xa348, 0xa349, 0xa34a, 0xa34b, 0xa34c, 0xa34d, + 0xa34e, 0xa34f, 0xa350, 0xa351, 0xa352, 0xa353, 0xa354, 0xa355, + 0xa356, 0xa357, 0xa358, 0xa359, 0xa35a, 0xa35b, 0xa35c, 0xa35d, + 0xa35e, 0xa35f, 0xa360, 0xa361, 0xa362, 0xa363, 0xa364, 0xa365, + 0xa366, 0xa367, 0xa368, 0xa369, 0xa36a, 0xa36b, 0xa36c, 0xa36d, + 0xa36e, 0xa36f, 0xa370, 0xa371, 0xa372, 0xa373, 0xc7b3, 0xc7b1, + 0xc7b2, 0xc7b4, 0xc7b5, 0xc7b6, 0xc7b7, 0xc7b8, 0xc7b9, 0xc7ba, + 0xc7bb, 0xc7bc, 0xc7bd, 0xc7be, 0xc7bf, 0xc7c0, 0xc7c1, 0xc7c2, + 0xc7c3, 0xc7c4, 0xc7c5, 0xc7c6, 0xc7c7, 0xc7c8, 0xc7c9, 0xc7ca, + 0xc7cb, 0xc7cc, 0xc7cd, 0xc7cf, 0xc7d0, 0xc7d1, 0xc7d2, 0xc7d3, + 0xc7d4, 0xc7d5, 0xc7d6, 0xc7d7, 0xc7d8, 0xc7d9, 0xc7da, 0xc7db, + 0xc7dc, 0xc7dd, 0xc7de, 0xc7df, 0xc7e0, 0xc7e1, 0xc7e2, 0xc7e3, + 0xc7e4, 0xc7e5, 0xc7e6, 0xc7e7, 0xc7e8, 0xc7ce, 0xa156, 0xa158, + 0xa1a5, 0xa1a6, 0xa1a7, 0xa1a8, 0xa145, 0xa14c, 0xa14b, 0xa1ac, + 0xa1ab, 0xa1b0, 0xa1c2, 0xa24a, 0xa1c1, 0xa24b, 0xa2b9, 0xa2ba, + 0xa2bb, 0xa2bc, 0xa2bd, 0xa2be, 0xa2bf, 0xa2c0, 0xa2c1, 0xa2c2, + 0xa1f6, 0xa1f4, 0xa1f7, 0xa1f5, 0xa1f8, 0xa1f9, 0xa1fb, 0xa1fa, + 0xa1d4, 0xa1db, 0xa1e8, 0xa1e7, 0xa1fd, 0xa1fc, 0xa1e4, 0xa1e5, + 0xa1ec, 0xa1ed, 0xa1ef, 0xa1ee, 0xa1e3, 0xa1dc, 0xa1da, 0xa1dd, + 0xa1d8, 0xa1d9, 0xa1e6, 0xa1e9, 0xc7e9, 0xc7ea, 0xc7eb, 0xc7ec, + 0xc7ed, 0xc7ee, 0xc7ef, 0xc7f0, 0xc7f1, 0xc7f2, 0xc7f3, 0xc7f4, + 0xc7f5, 0xc7f6, 0xc7f7, 0xc7f8, 0xc7f9, 0xc7fa, 0xc7fb, 0xc7fc, + 0xa277, 0xa278, 0xa27a, 0xa27b, 0xa27c, 0xa27d, 0xa275, 0xa274, + 0xa273, 0xa272, 0xa271, 0xa2a4, 0xa2a5, 0xa2a7, 0xa2a6, 0xa27e, + 0xa2a1, 0xa2a3, 0xa2a2, 0xa2ac, 0xa2ad, 0xa2ae, 0xa262, 0xa263, + 0xa264, 0xa265, 0xa266, 0xa267, 0xa268, 0xa269, 0xa270, 0xa26f, + 0xa26e, 0xa26d, 0xa26c, 0xa26b, 0xa26a, 0xa276, 0xa279, 0xa1bd, + 0xa1bc, 0xa1b6, 0xa1b5, 0xa1bf, 0xa1be, 0xa1bb, 0xa1ba, 0xa1b3, + 0xa1b7, 0xa1b4, 0xa2a8, 0xa2a9, 0xa2ab, 0xa2aa, 0xa1b9, 0xa1b8, + 0xa1f3, 0xa1f0, 0xa1f2, 0xa1f1, 0xa140, 0xa142, 0xa143, 0xa1b2, + 0xc6a4, 0xa171, 0xa172, 0xa16d, 0xa16e, 0xa175, 0xa176, 0xa179, + 0xa17a, 0xa169, 0xa16a, 0xa245, 0xa165, 0xa166, 0xa1a9, 0xa1aa, + 0xa2c3, 0xa2c4, 0xa2c5, 0xa2c6, 0xa2c7, 0xa2c8, 0xa2c9, 0xa2ca, + 0xa2cb, 0xc6a5, 0xc6a6, 0xc6a7, 0xc6a8, 0xc6a9, 0xc6aa, 0xc6ab, + 0xc6ac, 0xc6ad, 0xc6ae, 0xc6af, 0xc6b0, 0xc6b1, 0xc6b2, 0xc6b3, + 0xc6b4, 0xc6b5, 0xc6b6, 0xc6b7, 0xc6b8, 0xc6b9, 0xc6ba, 0xc6bb, + 0xc6bc, 0xc6bd, 0xc6be, 0xc6bf, 0xc6c0, 0xc6c1, 0xc6c2, 0xc6c3, + 0xc6c4, 0xc6c5, 0xc6c6, 0xc6c7, 0xc6c8, 0xc6c9, 0xc6ca, 0xc6cb, + 0xc6cc, 0xc6cd, 0xc6ce, 0xc6cf, 0xc6d0, 0xc6d1, 0xc6d2, 0xc6d3, + 0xc6d4, 0xc6d5, 0xc6d6, 0xc6d7, 0xc6d8, 0xc6d9, 0xc6da, 0xc6db, + 0xc6dc, 0xc6dd, 0xc6de, 0xc6df, 0xc6e0, 0xc6e1, 0xc6e2, 0xc6e3, + 0xc6e4, 0xc6e5, 0xc6e6, 0xc6e7, 0xc6e8, 0xc6e9, 0xc6ea, 0xc6eb, + 0xc6ec, 0xc6ed, 0xc6ee, 0xc6ef, 0xc6f0, 0xc6f1, 0xc6f2, 0xc6f3, + 0xc6f4, 0xc6f5, 0xc6f6, 0xc6f7, 0xc6a2, 0xc6a3, 0xc6f8, 0xc6f9, + 0xc6fa, 0xc6fb, 0xc6fc, 0xc6fd, 0xc6fe, 0xc740, 0xc741, 0xc742, + 0xc743, 0xc744, 0xc745, 0xc746, 0xc747, 0xc748, 0xc749, 0xc74a, + 0xc74b, 0xc74c, 0xc74d, 0xc74e, 0xc74f, 0xc750, 0xc751, 0xc752, + 0xc753, 0xc754, 0xc755, 0xc756, 0xc757, 0xc758, 0xc759, 0xc75a, + 0xc75b, 0xc75c, 0xc75d, 0xc75e, 0xc75f, 0xc760, 0xc761, 0xc762, + 0xc763, 0xc764, 0xc765, 0xc766, 0xc767, 0xc768, 0xc769, 0xc76a, + 0xc76b, 0xc76c, 0xc76d, 0xc76e, 0xc76f, 0xc770, 0xc771, 0xc772, + 0xc773, 0xc774, 0xc775, 0xc776, 0xc777, 0xc778, 0xc779, 0xc77a, + 0xc77b, 0xc77c, 0xc77d, 0xc77e, 0xc7a1, 0xc7a2, 0xc7a3, 0xc7a4, + 0xc7a5, 0xc7a6, 0xc7a7, 0xc7a8, 0xc7a9, 0xc7aa, 0xc7ab, 0xc7ac, + 0xc7ad, 0xc7ae, 0xc7af, 0xc7b0, 0xc6a1, 0xa374, 0xa375, 0xa376, + 0xa377, 0xa378, 0xa379, 0xa37a, 0xa37b, 0xa37c, 0xa37d, 0xa37e, + 0xa3a1, 0xa3a2, 0xa3a3, 0xa3a4, 0xa3a5, 0xa3a6, 0xa3a7, 0xa3a8, + 0xa3a9, 0xa3aa, 0xa3ab, 0xa3ac, 0xa3ad, 0xa3ae, 0xa3af, 0xa3b0, + 0xa3b1, 0xa3b2, 0xa3b3, 0xa3b4, 0xa3b5, 0xa3b6, 0xa3b7, 0xa3b8, + 0xa3b9, 0xa3ba, 0xa1c0, 0xa255, 0xa256, 0xa250, 0xa251, 0xa252, + 0xa254, 0xa257, 0xa253, 0xa1eb, 0xa1ea, 0xa24f, 0xa440, 0xa442, + 0xa443, 0xc945, 0xa456, 0xa454, 0xa457, 0xa455, 0xc946, 0xa4a3, + 0xc94f, 0xc94d, 0xa4a2, 0xa4a1, 0xa542, 0xa541, 0xa540, 0xa543, + 0xa4fe, 0xa5e0, 0xa5e1, 0xa8c3, 0xa458, 0xa4a4, 0xc950, 0xa4a5, + 0xc963, 0xa6ea, 0xcbb1, 0xa459, 0xa4a6, 0xa544, 0xc964, 0xc940, + 0xa444, 0xa45b, 0xc947, 0xa45c, 0xa4a7, 0xa545, 0xa547, 0xa546, + 0xa5e2, 0xa5e3, 0xa8c4, 0xadbc, 0xa441, 0xc941, 0xa445, 0xa45e, + 0xa45d, 0xa5e4, 0xa8c5, 0xb0ae, 0xd44b, 0xb6c3, 0xdcb1, 0xdcb2, + 0xa446, 0xa4a9, 0xa8c6, 0xa447, 0xc948, 0xa45f, 0xa4aa, 0xa4ac, + 0xc951, 0xa4ad, 0xa4ab, 0xa5e5, 0xa8c7, 0xa8c8, 0xab45, 0xa460, + 0xa4ae, 0xa5e6, 0xa5e8, 0xa5e7, 0xa6eb, 0xa8c9, 0xa8ca, 0xab46, + 0xab47, 0xadbd, 0xdcb3, 0xf6d6, 0xa448, 0xa4b0, 0xa4af, 0xc952, + 0xa4b1, 0xa4b7, 0xa4b2, 0xa4b3, 0xc954, 0xc953, 0xa4b5, 0xa4b6, + 0xa4b4, 0xa54a, 0xa54b, 0xa54c, 0xa54d, 0xa549, 0xa550, 0xc96a, + 0xc966, 0xc969, 0xa551, 0xa561, 0xc968, 0xa54e, 0xa54f, 0xa548, + 0xc965, 0xc967, 0xa5f5, 0xc9b0, 0xa5f2, 0xa5f6, 0xc9ba, 0xc9ae, + 0xa5f3, 0xc9b2, 0xa5f4, 0xa5f7, 0xa5e9, 0xc9b1, 0xa5f8, 0xc9b5, + 0xc9b9, 0xc9b6, 0xc9b3, 0xa5ea, 0xa5ec, 0xa5f9, 0xa5ee, 0xc9ab, + 0xa5f1, 0xa5ef, 0xa5f0, 0xc9bb, 0xc9b8, 0xc9af, 0xa5ed, 0xc9ac, + 0xa5eb, 0xc9b4, 0xc9b7, 0xc9ad, 0xca66, 0xa742, 0xa6f4, 0xca67, + 0xa6f1, 0xa744, 0xa6f9, 0xa6f8, 0xca5b, 0xa6fc, 0xa6f7, 0xca60, + 0xca68, 0xca64, 0xa6fa, 0xa6fd, 0xa6ee, 0xa747, 0xca5d, 0xcbbd, + 0xa6ec, 0xa743, 0xa6ed, 0xa6f5, 0xa6f6, 0xca62, 0xca5e, 0xa6fb, + 0xa6f3, 0xca5a, 0xa6ef, 0xca65, 0xa745, 0xa748, 0xa6f2, 0xa740, + 0xa746, 0xa6f0, 0xca63, 0xa741, 0xca69, 0xca5c, 0xa6fe, 0xca5f, + 0xca61, 0xa8d8, 0xcbbf, 0xcbcb, 0xa8d0, 0xcbcc, 0xa8cb, 0xa8d5, + 0xa8ce, 0xcbb9, 0xa8d6, 0xcbb8, 0xcbbc, 0xcbc3, 0xcbc1, 0xa8de, + 0xa8d9, 0xcbb3, 0xcbb5, 0xa8db, 0xa8cf, 0xcbb6, 0xcbc2, 0xcbc9, + 0xa8d4, 0xcbbb, 0xcbb4, 0xa8d3, 0xcbb7, 0xa8d7, 0xcbba, 0xa8d2, + 0xa8cd, 0xa8dc, 0xcbc4, 0xa8dd, 0xcbc8, 0xcbc6, 0xcbca, 0xa8da, + 0xcbbe, 0xcbb2, 0xcbc0, 0xa8d1, 0xcbc5, 0xa8cc, 0xcbc7, 0xab56, + 0xab4a, 0xcde0, 0xcde8, 0xab49, 0xab51, 0xab5d, 0xcdee, 0xcdec, + 0xcde7, 0xab4b, 0xcded, 0xcde3, 0xab59, 0xab50, 0xab58, 0xcdde, + 0xcdea, 0xcde1, 0xab54, 0xcde2, 0xcddd, 0xab5b, 0xab4e, 0xab57, + 0xab4d, 0xcddf, 0xcde4, 0xcdeb, 0xab55, 0xab52, 0xcde6, 0xab5a, + 0xcde9, 0xcde5, 0xab4f, 0xab5c, 0xab53, 0xab4c, 0xab48, 0xcdef, + 0xadd7, 0xadc1, 0xadd1, 0xadd6, 0xd0d0, 0xd0cf, 0xd0d4, 0xd0d5, + 0xadc4, 0xadcd, 0xadda, 0xadce, 0xd0c9, 0xadc7, 0xd0ca, 0xaddc, + 0xadd3, 0xadbe, 0xadbf, 0xd0dd, 0xb0bf, 0xadcc, 0xadcb, 0xd0cb, + 0xadcf, 0xd45b, 0xadc6, 0xd0d6, 0xadd5, 0xadd4, 0xadca, 0xd0ce, + 0xd0d7, 0xd0c8, 0xadc9, 0xd0d8, 0xadd2, 0xd0cc, 0xadc0, 0xadc3, + 0xadc2, 0xd0d9, 0xadd0, 0xadc5, 0xadd9, 0xaddb, 0xd0d3, 0xadd8, + 0xd0db, 0xd0cd, 0xd0dc, 0xd0d1, 0xd0da, 0xd0d2, 0xadc8, 0xd463, + 0xd457, 0xb0b3, 0xd45c, 0xd462, 0xb0b2, 0xd455, 0xb0b6, 0xd459, + 0xd452, 0xb0b4, 0xd456, 0xb0b9, 0xb0be, 0xd467, 0xd451, 0xb0ba, + 0xd466, 0xb0b5, 0xd458, 0xb0b1, 0xd453, 0xd44f, 0xd45d, 0xd450, + 0xd44e, 0xd45a, 0xd460, 0xd461, 0xb0b7, 0xd85b, 0xd45e, 0xd44d, + 0xd45f, 0xb0c1, 0xd464, 0xb0c0, 0xd44c, 0xd454, 0xd465, 0xb0bc, + 0xb0bb, 0xb0b8, 0xb0bd, 0xb0af, 0xb0b0, 0xb3c8, 0xd85e, 0xd857, + 0xb3c5, 0xd85f, 0xd855, 0xd858, 0xb3c4, 0xd859, 0xb3c7, 0xd85d, + 0xd853, 0xd852, 0xb3c9, 0xb3ca, 0xb3c6, 0xb3cb, 0xd851, 0xd85c, + 0xd85a, 0xd854, 0xb3c3, 0xd856, 0xb6ca, 0xb6c4, 0xdcb7, 0xb6cd, + 0xdcbd, 0xdcc0, 0xb6c6, 0xb6c7, 0xdcba, 0xb6c5, 0xdcc3, 0xb6cb, + 0xdcc4, 0xdcbf, 0xb6cc, 0xdcb4, 0xb6c9, 0xdcb5, 0xdcbe, 0xdcbc, + 0xdcb8, 0xb6c8, 0xdcb6, 0xb6ce, 0xdcbb, 0xdcc2, 0xdcb9, 0xdcc1, + 0xb9b6, 0xb9b3, 0xb9b4, 0xe0f9, 0xe0f1, 0xb9b2, 0xb9af, 0xe0f2, + 0xb9b1, 0xe0f5, 0xe0f7, 0xe0fe, 0xe0fd, 0xe0f8, 0xb9ae, 0xe0f0, + 0xb9ac, 0xe0f3, 0xb9b7, 0xe0f6, 0xe0fa, 0xb9b0, 0xb9ad, 0xe0fc, + 0xe0fb, 0xb9b5, 0xe0f4, 0xbbf8, 0xe4ec, 0xe4e9, 0xbbf9, 0xbbf7, + 0xe4f0, 0xe4ed, 0xe4e6, 0xbbf6, 0xbbfa, 0xe4e7, 0xbbf5, 0xbbfd, + 0xe4ea, 0xe4eb, 0xbbfb, 0xbbfc, 0xe4f1, 0xe4ee, 0xe4ef, 0xbeaa, + 0xe8f8, 0xbea7, 0xe8f5, 0xbea9, 0xbeab, 0xe8f6, 0xbea8, 0xe8f7, + 0xe8f4, 0xc076, 0xecbd, 0xc077, 0xecbb, 0xecbc, 0xecba, 0xecb9, + 0xecbe, 0xc075, 0xefb8, 0xefb9, 0xe4e8, 0xefb7, 0xc078, 0xc35f, + 0xf1eb, 0xf1ec, 0xc4d7, 0xc4d8, 0xf5c1, 0xf5c0, 0xc56c, 0xc56b, + 0xf7d0, 0xa449, 0xa461, 0xa4b9, 0xa4b8, 0xa553, 0xa552, 0xa5fc, + 0xa5fb, 0xa5fd, 0xa5fa, 0xa74a, 0xa749, 0xa74b, 0xa8e0, 0xa8df, + 0xa8e1, 0xab5e, 0xa259, 0xd0de, 0xa25a, 0xb0c2, 0xa25c, 0xa25b, + 0xd860, 0xa25d, 0xb9b8, 0xa25e, 0xa44a, 0xa4ba, 0xa5fe, 0xa8e2, + 0xa44b, 0xa4bd, 0xa4bb, 0xa4bc, 0xa640, 0xa74c, 0xa8e4, 0xa8e3, + 0xa8e5, 0xaddd, 0xbeac, 0xc94e, 0xa554, 0xa555, 0xa641, 0xca6a, + 0xab60, 0xab5f, 0xd0e0, 0xd0df, 0xb0c3, 0xa4be, 0xc955, 0xcbcd, + 0xab61, 0xade0, 0xadde, 0xaddf, 0xbead, 0xa556, 0xa642, 0xc9bc, + 0xa74d, 0xa74e, 0xca6b, 0xcbce, 0xa8e6, 0xcbcf, 0xd0e2, 0xd0e3, + 0xade3, 0xd0e4, 0xd0e1, 0xade4, 0xade2, 0xade1, 0xd0e5, 0xd468, + 0xd861, 0xdcc5, 0xe140, 0xbbfe, 0xbeae, 0xe8f9, 0xa44c, 0xa45a, + 0xb0c4, 0xb3cd, 0xb9b9, 0xc942, 0xa4bf, 0xa559, 0xa557, 0xa558, + 0xa8e7, 0xa44d, 0xa44e, 0xa462, 0xa4c0, 0xa4c1, 0xa4c2, 0xc9be, + 0xa55a, 0xc96b, 0xa646, 0xc9bf, 0xa644, 0xa645, 0xc9bd, 0xa647, + 0xa643, 0xca6c, 0xaaec, 0xca6d, 0xca6e, 0xa750, 0xa74f, 0xa753, + 0xa751, 0xa752, 0xa8ed, 0xa8ec, 0xcbd4, 0xcbd1, 0xcbd2, 0xcbd0, + 0xa8ee, 0xa8ea, 0xa8e9, 0xa8eb, 0xa8e8, 0xa8ef, 0xab63, 0xcdf0, + 0xcbd3, 0xab68, 0xcdf1, 0xab64, 0xab67, 0xab66, 0xab65, 0xab62, + 0xd0e8, 0xade7, 0xd0eb, 0xade5, 0xd0e7, 0xade8, 0xade6, 0xade9, + 0xd0e9, 0xd0ea, 0xd0e6, 0xd0ec, 0xb3d1, 0xb0c5, 0xd469, 0xd46b, + 0xd46a, 0xd46c, 0xb0c6, 0xb3ce, 0xb3cf, 0xb3d0, 0xb6d0, 0xdcc7, + 0xdcc6, 0xdcc8, 0xdcc9, 0xb6d1, 0xb6cf, 0xe141, 0xe142, 0xb9bb, + 0xb9ba, 0xe35a, 0xbc40, 0xbc41, 0xbc42, 0xbc44, 0xe4f2, 0xe4f3, + 0xbc43, 0xbeaf, 0xbeb0, 0xf1ed, 0xf5c3, 0xf5c2, 0xf7d1, 0xa44f, + 0xa55c, 0xa55b, 0xa648, 0xc9c0, 0xa755, 0xa756, 0xa754, 0xa757, + 0xca6f, 0xca70, 0xa8f1, 0xcbd5, 0xa8f0, 0xcdf2, 0xab6c, 0xcdf3, + 0xab6b, 0xab69, 0xab6a, 0xd0ed, 0xb0c7, 0xd46e, 0xb0ca, 0xd46d, + 0xb1e5, 0xb0c9, 0xb0c8, 0xb3d4, 0xb3d3, 0xb3d2, 0xb6d2, 0xb6d5, + 0xb6d6, 0xb6d4, 0xb6d3, 0xe143, 0xe144, 0xe4f5, 0xbc45, 0xe4f4, + 0xbeb1, 0xecbf, 0xc079, 0xf1ee, 0xc455, 0xa463, 0xa4c3, 0xc956, + 0xa4c4, 0xa4c5, 0xa55d, 0xa55e, 0xa649, 0xca71, 0xcbd6, 0xcbd7, + 0xab6d, 0xd0ee, 0xb0cc, 0xb0cb, 0xd863, 0xd862, 0xa450, 0xa4c6, + 0xa55f, 0xb0cd, 0xc943, 0xc96c, 0xa560, 0xc9c2, 0xa64b, 0xa64a, + 0xc9c1, 0xa758, 0xadea, 0xd46f, 0xb6d7, 0xe145, 0xb9bc, 0xe8fa, + 0xf3fd, 0xa4c7, 0xcbd8, 0xcdf4, 0xb0d0, 0xb0ce, 0xb0cf, 0xa451, + 0xa464, 0xa2cd, 0xa4ca, 0xa4c9, 0xa4c8, 0xa563, 0xa562, 0xc96d, + 0xc9c3, 0xa8f5, 0xa8f2, 0xa8f4, 0xa8f3, 0xab6e, 0xb3d5, 0xa452, + 0xa4cb, 0xa565, 0xa564, 0xca72, 0xa8f6, 0xc957, 0xa567, 0xa566, + 0xa64c, 0xa64d, 0xca73, 0xa759, 0xa75a, 0xa8f7, 0xa8f8, 0xa8f9, + 0xab6f, 0xcdf5, 0xadeb, 0xc944, 0xa4cc, 0xc9c4, 0xca74, 0xca75, + 0xcbd9, 0xcbda, 0xcdf7, 0xcdf6, 0xcdf9, 0xcdf8, 0xab70, 0xd470, + 0xaded, 0xd0ef, 0xadec, 0xd864, 0xb3d6, 0xd865, 0xe146, 0xb9bd, + 0xbc46, 0xf1ef, 0xc958, 0xa568, 0xb0d1, 0xa453, 0xa465, 0xa4ce, + 0xa4cd, 0xa4cf, 0xa8fb, 0xa8fa, 0xa8fc, 0xab71, 0xadee, 0xe8fb, + 0xc24f, 0xa466, 0xa56a, 0xa579, 0xa574, 0xa56f, 0xa56e, 0xa575, + 0xa573, 0xa56c, 0xa57a, 0xa56d, 0xa569, 0xa578, 0xa577, 0xa576, + 0xa56b, 0xa572, 0xa571, 0xa57b, 0xa570, 0xa653, 0xa659, 0xa655, + 0xa65b, 0xc9c5, 0xa658, 0xa64e, 0xa651, 0xa654, 0xa650, 0xa657, + 0xa65a, 0xa64f, 0xa652, 0xa656, 0xa65c, 0xca7e, 0xca7b, 0xa767, + 0xca7c, 0xa75b, 0xa75d, 0xa775, 0xa770, 0xcaa5, 0xca7d, 0xa75f, + 0xa761, 0xcaa4, 0xa768, 0xca78, 0xa774, 0xa776, 0xa75c, 0xa76d, + 0xca76, 0xa773, 0xa764, 0xa76e, 0xa76f, 0xca77, 0xa76c, 0xa76a, + 0xa76b, 0xa771, 0xcaa1, 0xa75e, 0xa772, 0xcaa3, 0xa766, 0xa763, + 0xca7a, 0xa762, 0xcaa6, 0xa765, 0xa769, 0xa760, 0xcaa2, 0xca79, + 0xcbeb, 0xcbea, 0xa94f, 0xcbed, 0xcbef, 0xcbe4, 0xcbe7, 0xcbee, + 0xa950, 0xcbe1, 0xcbe5, 0xcbe9, 0xce49, 0xa94b, 0xce4d, 0xa8fd, + 0xcbe6, 0xa8fe, 0xa94c, 0xa945, 0xa941, 0xcbe2, 0xa944, 0xa949, + 0xa952, 0xcbe3, 0xcbdc, 0xa943, 0xcbdd, 0xcbdf, 0xa946, 0xa948, + 0xcbdb, 0xcbe0, 0xa951, 0xa94d, 0xcbe8, 0xa953, 0xa94a, 0xcbde, + 0xa947, 0xa942, 0xa940, 0xcbec, 0xa94e, 0xce48, 0xcdfb, 0xce4b, + 0xcdfd, 0xab78, 0xaba8, 0xab74, 0xaba7, 0xab7d, 0xaba4, 0xab72, + 0xcdfc, 0xce43, 0xaba3, 0xce4f, 0xaba5, 0xab79, 0xce45, 0xce42, + 0xab77, 0xcdfa, 0xaba6, 0xce4a, 0xab7c, 0xce4c, 0xaba9, 0xab73, + 0xab7e, 0xab7b, 0xce40, 0xaba1, 0xce46, 0xce47, 0xab7a, 0xaba2, + 0xab76, 0xab75, 0xcdfe, 0xce44, 0xce4e, 0xd144, 0xadfb, 0xd0f1, + 0xd0f6, 0xadf4, 0xae40, 0xd0f4, 0xadef, 0xadf9, 0xadfe, 0xd0fb, + 0xadfa, 0xadfd, 0xd0fe, 0xadf5, 0xd0f5, 0xd142, 0xd143, 0xadf7, + 0xd141, 0xadf3, 0xae43, 0xd0f8, 0xadf1, 0xd146, 0xd0f9, 0xd0fd, + 0xadf6, 0xae42, 0xd0fa, 0xadfc, 0xd140, 0xd147, 0xd4a1, 0xd145, + 0xae44, 0xadf0, 0xd0fc, 0xd0f3, 0xadf8, 0xd0f2, 0xd0f7, 0xd0f0, + 0xae41, 0xd477, 0xb0e4, 0xd4a7, 0xb0e2, 0xb0df, 0xd47c, 0xb0db, + 0xd4a2, 0xb0e6, 0xd476, 0xd47b, 0xd47a, 0xadf2, 0xb0e1, 0xd4a5, + 0xd4a8, 0xd473, 0xb3e8, 0xd4a9, 0xb0e7, 0xb0d9, 0xb0d6, 0xd47e, + 0xb0d3, 0xd4a6, 0xb0da, 0xd4aa, 0xd474, 0xd4a4, 0xb0dd, 0xd475, + 0xd478, 0xd47d, 0xb0de, 0xb0dc, 0xb0e8, 0xb0e3, 0xb0d7, 0xb1d2, + 0xb0d8, 0xd479, 0xb0e5, 0xb0e0, 0xd4a3, 0xb0d5, 0xb0d4, 0xd471, + 0xd472, 0xd86a, 0xb3d7, 0xb3da, 0xd875, 0xb3ee, 0xd878, 0xb3d8, + 0xd871, 0xb3de, 0xb3e4, 0xb5bd, 0xb3e2, 0xd86e, 0xb3ef, 0xb3db, + 0xb3e3, 0xd876, 0xdcd7, 0xd87b, 0xd86f, 0xd866, 0xd873, 0xd86d, + 0xb3e1, 0xd879, 0xb3dd, 0xb3f1, 0xb3ea, 0xb3df, 0xb3dc, 0xb3e7, + 0xd87a, 0xd86c, 0xd872, 0xd874, 0xd868, 0xd877, 0xb3d9, 0xd867, + 0xb3e0, 0xb3f0, 0xb3ec, 0xd869, 0xb3e6, 0xb3ed, 0xb3e9, 0xb3e5, + 0xd870, 0xb3eb, 0xdcd5, 0xdcd1, 0xdce0, 0xdcca, 0xdcd3, 0xb6e5, + 0xb6e6, 0xb6de, 0xdcdc, 0xb6e8, 0xdccf, 0xdcce, 0xdccc, 0xdcde, + 0xb6dc, 0xdcd8, 0xdccd, 0xb6df, 0xdcd6, 0xb6da, 0xdcd2, 0xdcd9, + 0xdcdb, 0xdcdf, 0xb6e3, 0xdccb, 0xb6dd, 0xdcd0, 0xb6d8, 0xb6e4, + 0xdcda, 0xb6e0, 0xb6e1, 0xb6e7, 0xb6db, 0xa25f, 0xb6d9, 0xdcd4, + 0xb6e2, 0xdcdd, 0xb9cd, 0xb9c8, 0xe155, 0xe151, 0xe14b, 0xb9c2, + 0xb9be, 0xe154, 0xb9bf, 0xe14e, 0xe150, 0xe153, 0xb9c4, 0xb9cb, + 0xb9c5, 0xe149, 0xb9c6, 0xb9c7, 0xe14c, 0xb9cc, 0xe14a, 0xe14f, + 0xb9c3, 0xe148, 0xb9c9, 0xb9c1, 0xb9c0, 0xe14d, 0xe152, 0xb9ca, + 0xe147, 0xbc4d, 0xe547, 0xe544, 0xbc47, 0xbc53, 0xbc54, 0xbc4a, + 0xe542, 0xbc4c, 0xe4f9, 0xbc52, 0xe546, 0xbc49, 0xe548, 0xbc48, + 0xe543, 0xe545, 0xbc4b, 0xe541, 0xe4fa, 0xe4f7, 0xd86b, 0xe4fd, + 0xe4f6, 0xe4fc, 0xe4fb, 0xe4f8, 0xbc4f, 0xbc4e, 0xbc50, 0xe4fe, + 0xbeb2, 0xe540, 0xe945, 0xe8fd, 0xbebe, 0xe942, 0xbeb6, 0xbeba, + 0xe941, 0xbeb9, 0xbeb5, 0xbeb8, 0xbeb3, 0xbebd, 0xe943, 0xe8fe, + 0xbebc, 0xe8fc, 0xbebb, 0xe944, 0xe940, 0xbc51, 0xbebf, 0xe946, + 0xbeb7, 0xbeb4, 0xecc6, 0xecc8, 0xc07b, 0xecc9, 0xecc7, 0xecc5, + 0xecc4, 0xc07d, 0xecc3, 0xc07e, 0xecc1, 0xecc2, 0xc07a, 0xc0a1, + 0xc07c, 0xecc0, 0xc250, 0xefbc, 0xefba, 0xefbf, 0xefbd, 0xefbb, + 0xefbe, 0xc360, 0xf1f2, 0xf1f3, 0xc456, 0xf1f4, 0xf1f0, 0xf1f5, + 0xf1f1, 0xc251, 0xf3fe, 0xf441, 0xc459, 0xf440, 0xc458, 0xc457, + 0xc45a, 0xf5c5, 0xf5c6, 0xc4da, 0xc4d9, 0xc4db, 0xf5c4, 0xf6d8, + 0xf6d7, 0xc56d, 0xc56f, 0xc56e, 0xf6d9, 0xc5c8, 0xf8a6, 0xc5f1, + 0xf8a5, 0xf8ee, 0xc949, 0xa57d, 0xa57c, 0xa65f, 0xa65e, 0xc9c7, + 0xa65d, 0xc9c6, 0xa779, 0xcaa9, 0xcaa8, 0xa777, 0xa77a, 0xcaa7, + 0xa778, 0xcbf0, 0xcbf1, 0xa954, 0xabaa, 0xd148, 0xd149, 0xae45, + 0xae46, 0xd4ac, 0xb0e9, 0xb0eb, 0xd4ab, 0xb0ea, 0xd87c, 0xb3f2, + 0xb6e9, 0xb6ea, 0xdce1, 0xb9cf, 0xb9ce, 0xe549, 0xe948, 0xe947, + 0xf96b, 0xa467, 0xc959, 0xc96e, 0xc96f, 0xa662, 0xa666, 0xc9c9, + 0xa664, 0xa663, 0xc9c8, 0xa665, 0xa661, 0xa660, 0xc9ca, 0xa7a6, + 0xa7a3, 0xa77d, 0xcaaa, 0xcaab, 0xa7a1, 0xcaad, 0xa77b, 0xcaae, + 0xcaac, 0xa77e, 0xa7a2, 0xa7a5, 0xa7a4, 0xa77c, 0xcaaf, 0xa959, + 0xcbfe, 0xa95b, 0xa95a, 0xcc40, 0xa958, 0xa957, 0xcbf5, 0xcbf4, + 0xcbf2, 0xcbf7, 0xcbf6, 0xcbf3, 0xcbfc, 0xcbfd, 0xcbfa, 0xcbf8, + 0xa956, 0xcbfb, 0xa95c, 0xcc41, 0xcbf9, 0xabab, 0xa955, 0xabac, + 0xce54, 0xce5a, 0xabb2, 0xce58, 0xce5e, 0xce55, 0xce59, 0xce5b, + 0xce5d, 0xce57, 0xce56, 0xce51, 0xce52, 0xabad, 0xabaf, 0xabae, + 0xce53, 0xce5c, 0xabb1, 0xce50, 0xd153, 0xd152, 0xd157, 0xd14e, + 0xd151, 0xd150, 0xd154, 0xd158, 0xae47, 0xae4a, 0xd14f, 0xd155, + 0xae49, 0xd14a, 0xabb0, 0xd4ba, 0xd156, 0xd14d, 0xae48, 0xd14c, + 0xd4b1, 0xb0ec, 0xb0f0, 0xd4c1, 0xd4af, 0xd4bd, 0xb0f1, 0xd4bf, + 0xd4c5, 0xd4c9, 0xd4c0, 0xd4b4, 0xd4bc, 0xd4ca, 0xd4c8, 0xd4be, + 0xd4b9, 0xd4b2, 0xd8a6, 0xd4b0, 0xb0f5, 0xd4b7, 0xb0f6, 0xb0f2, + 0xd4ad, 0xd4c3, 0xd4b5, 0xd4b3, 0xd4c6, 0xb0f3, 0xd4cc, 0xb0ed, + 0xb0ef, 0xd4bb, 0xd4b6, 0xae4b, 0xb0ee, 0xd4b8, 0xd4c7, 0xd4cb, + 0xd4c2, 0xd4c4, 0xd4ae, 0xd8a1, 0xd8aa, 0xd8a9, 0xb3fa, 0xd8a2, + 0xb3fb, 0xb3f9, 0xd8a4, 0xb3f6, 0xd8a8, 0xd8a3, 0xd8a5, 0xd87d, + 0xb3f4, 0xd8b2, 0xd8b1, 0xd8ae, 0xb3f3, 0xb3f7, 0xb3f8, 0xd14b, + 0xd8ab, 0xb3f5, 0xb0f4, 0xd8ad, 0xd87e, 0xd8b0, 0xd8af, 0xd8b3, + 0xdcef, 0xd8ac, 0xd8a7, 0xdce7, 0xb6f4, 0xb6f7, 0xb6f2, 0xdce6, + 0xdcea, 0xdce5, 0xb6ec, 0xb6f6, 0xdce2, 0xb6f0, 0xdce9, 0xb6ee, + 0xb6ed, 0xdcec, 0xb6ef, 0xdcee, 0xdceb, 0xb6eb, 0xb6f5, 0xdcf0, + 0xdce4, 0xdced, 0xdce3, 0xb6f1, 0xb6f3, 0xdce8, 0xdcf1, 0xe15d, + 0xb9d0, 0xe163, 0xb9d5, 0xe15f, 0xe166, 0xe157, 0xb9d7, 0xb9d1, + 0xe15c, 0xbc55, 0xe15b, 0xe164, 0xb9d2, 0xb9d6, 0xe15a, 0xe160, + 0xe165, 0xe156, 0xb9d4, 0xe15e, 0xe162, 0xe168, 0xe158, 0xe161, + 0xb9d3, 0xe167, 0xe159, 0xbc59, 0xe54b, 0xbc57, 0xbc56, 0xe54d, + 0xe552, 0xe54e, 0xe551, 0xbc5c, 0xbea5, 0xbc5b, 0xe54a, 0xe550, + 0xbc5a, 0xe54f, 0xe54c, 0xbc58, 0xe94d, 0xe94f, 0xe94a, 0xbec1, + 0xe94c, 0xbec0, 0xe94e, 0xbec3, 0xe950, 0xbec2, 0xe949, 0xe94b, + 0xc0a5, 0xeccc, 0xc0a4, 0xeccd, 0xc0a3, 0xeccb, 0xc0a2, 0xecca, + 0xc253, 0xc252, 0xf1f6, 0xf1f8, 0xf1f7, 0xc361, 0xc362, 0xc363, + 0xf442, 0xc45b, 0xf7d3, 0xf7d2, 0xc5f2, 0xa468, 0xa4d0, 0xa7a7, + 0xce5f, 0xb3fc, 0xb3fd, 0xdcf2, 0xb9d8, 0xe169, 0xe553, 0xc95a, + 0xcab0, 0xcc42, 0xce60, 0xd159, 0xae4c, 0xf1f9, 0xc4dc, 0xa469, + 0xa57e, 0xc970, 0xa667, 0xa668, 0xa95d, 0xb0f7, 0xb9da, 0xb9db, + 0xb9d9, 0xa46a, 0xa4d1, 0xa4d3, 0xa4d2, 0xc95b, 0xa4d4, 0xa5a1, + 0xc971, 0xa5a2, 0xa669, 0xa66a, 0xc9cb, 0xa7a8, 0xcab1, 0xa961, + 0xcc43, 0xa95f, 0xa960, 0xa95e, 0xd15a, 0xabb6, 0xabb5, 0xabb7, + 0xabb4, 0xce61, 0xa962, 0xabb3, 0xae4d, 0xae4e, 0xae4f, 0xd4cd, + 0xb3fe, 0xd8b4, 0xb0f8, 0xb6f8, 0xb9dd, 0xb9dc, 0xe16a, 0xbc5d, + 0xbec4, 0xefc0, 0xf6da, 0xf7d4, 0xa46b, 0xa5a3, 0xa5a4, 0xc9d1, + 0xa66c, 0xa66f, 0xc9cf, 0xc9cd, 0xa66e, 0xc9d0, 0xc9d2, 0xc9cc, + 0xa671, 0xa670, 0xa66d, 0xa66b, 0xc9ce, 0xa7b3, 0xa7b0, 0xcab6, + 0xcab9, 0xcab8, 0xa7aa, 0xa7b2, 0xa7af, 0xcab5, 0xcab3, 0xa7ae, + 0xa7a9, 0xa7ac, 0xcab4, 0xcabb, 0xcab7, 0xa7ad, 0xa7b1, 0xa7b4, + 0xcab2, 0xcaba, 0xa7ab, 0xa967, 0xa96f, 0xcc4f, 0xcc48, 0xa970, + 0xcc53, 0xcc44, 0xcc4b, 0xa966, 0xcc45, 0xa964, 0xcc4c, 0xcc50, + 0xa963, 0xcc51, 0xcc4a, 0xcc4d, 0xa972, 0xa969, 0xcc54, 0xcc52, + 0xa96e, 0xa96c, 0xcc49, 0xa96b, 0xcc47, 0xcc46, 0xa96a, 0xa968, + 0xa971, 0xa96d, 0xa965, 0xcc4e, 0xabb9, 0xabc0, 0xce6f, 0xabb8, + 0xce67, 0xce63, 0xce73, 0xce62, 0xabbb, 0xce6c, 0xabbe, 0xabc1, + 0xabbc, 0xce70, 0xabbf, 0xae56, 0xce76, 0xce64, 0xce66, 0xce6d, + 0xce71, 0xce75, 0xce72, 0xce6b, 0xce6e, 0xce68, 0xabc3, 0xce6a, + 0xce69, 0xce74, 0xabba, 0xce65, 0xabc2, 0xabbd, 0xae5c, 0xd162, + 0xae5b, 0xd160, 0xae50, 0xae55, 0xd15f, 0xd15c, 0xd161, 0xae51, + 0xd15b, 0xae54, 0xae52, 0xd163, 0xae53, 0xae57, 0xae58, 0xae5a, + 0xae59, 0xd15d, 0xd15e, 0xd164, 0xd4d4, 0xb0f9, 0xd8c2, 0xd4d3, + 0xd4e6, 0xb140, 0xd4e4, 0xb0fe, 0xb0fa, 0xd4ed, 0xd4dd, 0xd4e0, + 0xb143, 0xd4ea, 0xd4e2, 0xb0fb, 0xb144, 0xd4e7, 0xd4e5, 0xd4d6, + 0xd4eb, 0xd4df, 0xd4da, 0xd4d0, 0xd4ec, 0xd4dc, 0xd4cf, 0xb142, + 0xd4e1, 0xd4ee, 0xd4de, 0xd4d2, 0xd4d7, 0xd4ce, 0xb141, 0xd4db, + 0xd4d8, 0xb0fc, 0xd4d1, 0xd4e9, 0xb0fd, 0xd4d9, 0xd4d5, 0xd4e8, + 0xb440, 0xd8bb, 0xd8b8, 0xd8c9, 0xd8bd, 0xd8ca, 0xb442, 0xd8c6, + 0xd8c3, 0xd8c4, 0xd8c7, 0xd8cb, 0xd4e3, 0xd8cd, 0xdd47, 0xb443, + 0xd8ce, 0xd8b6, 0xd8c0, 0xd8c5, 0xb441, 0xb444, 0xd8cc, 0xd8cf, + 0xd8ba, 0xd8b7, 0xd8b9, 0xd8be, 0xd8bc, 0xb445, 0xd8c8, 0xd8bf, + 0xd8c1, 0xd8b5, 0xdcfa, 0xdcf8, 0xb742, 0xb740, 0xdd43, 0xdcf9, + 0xdd44, 0xdd40, 0xdcf7, 0xdd46, 0xdcf6, 0xdcfd, 0xb6fe, 0xb6fd, + 0xb6fc, 0xdcfb, 0xdd41, 0xb6f9, 0xb741, 0xdcf4, 0xdcfe, 0xdcf3, + 0xdcfc, 0xb6fa, 0xdd42, 0xdcf5, 0xb6fb, 0xdd45, 0xe16e, 0xb9e2, + 0xb9e1, 0xb9e3, 0xe17a, 0xe170, 0xe176, 0xe16b, 0xe179, 0xe178, + 0xe17c, 0xe175, 0xb9de, 0xe174, 0xb9e4, 0xe16d, 0xb9df, 0xe17b, + 0xb9e0, 0xe16f, 0xe172, 0xe177, 0xe171, 0xe16c, 0xe173, 0xe555, + 0xbc61, 0xe558, 0xe557, 0xe55a, 0xe55c, 0xbc5f, 0xe556, 0xe554, + 0xe55d, 0xe55b, 0xe559, 0xe55f, 0xe55e, 0xbc63, 0xbc5e, 0xbc60, + 0xbc62, 0xe560, 0xe957, 0xe956, 0xe955, 0xe958, 0xe951, 0xe952, + 0xe95a, 0xe953, 0xbec5, 0xe95c, 0xe95b, 0xe954, 0xecd1, 0xc0a8, + 0xeccf, 0xecd4, 0xecd3, 0xe959, 0xc0a7, 0xecd2, 0xecce, 0xecd6, + 0xecd5, 0xc0a6, 0xecd0, 0xbec6, 0xc254, 0xefc1, 0xf1fa, 0xf1fb, + 0xf1fc, 0xc45c, 0xc45d, 0xf443, 0xf5c8, 0xf5c7, 0xf6db, 0xf6dc, + 0xf7d5, 0xf8a7, 0xa46c, 0xa46d, 0xa46e, 0xa4d5, 0xa5a5, 0xc9d3, + 0xa672, 0xa673, 0xa7b7, 0xa7b8, 0xa7b6, 0xa7b5, 0xa973, 0xcc55, + 0xa975, 0xa974, 0xcc56, 0xabc4, 0xae5d, 0xd165, 0xd4f0, 0xb145, + 0xb447, 0xd4ef, 0xb446, 0xb9e5, 0xe17d, 0xbec7, 0xc0a9, 0xecd7, + 0xc45e, 0xc570, 0xc972, 0xa5a6, 0xc973, 0xa676, 0xa674, 0xa675, + 0xa677, 0xa7ba, 0xa7b9, 0xcabc, 0xa7bb, 0xcabd, 0xcc57, 0xcc58, + 0xa976, 0xa978, 0xa97a, 0xa977, 0xa97b, 0xa979, 0xabc8, 0xabc5, + 0xabc7, 0xabc9, 0xabc6, 0xd166, 0xce77, 0xd168, 0xd167, 0xae63, + 0xae5f, 0xae60, 0xae62, 0xae64, 0xae61, 0xae66, 0xae65, 0xb14a, + 0xd4f2, 0xd4f1, 0xb149, 0xb148, 0xb147, 0xb14b, 0xb146, 0xd8d5, + 0xd8d2, 0xb449, 0xd8d1, 0xd8d6, 0xb44b, 0xd8d4, 0xb448, 0xb44a, + 0xd8d3, 0xdd48, 0xdd49, 0xdd4a, 0xb9e6, 0xb9ee, 0xe17e, 0xb9e8, + 0xb9ec, 0xe1a1, 0xb9ed, 0xb9e9, 0xb9ea, 0xb9e7, 0xb9eb, 0xbc66, + 0xd8d0, 0xbc67, 0xbc65, 0xbc64, 0xe95d, 0xbec8, 0xecd8, 0xecd9, + 0xc364, 0xc45f, 0xa46f, 0xa678, 0xabca, 0xd169, 0xae67, 0xb14e, + 0xb14d, 0xb14c, 0xb44c, 0xb44d, 0xd8d7, 0xb9ef, 0xbec9, 0xa470, + 0xc95c, 0xa4d6, 0xc974, 0xc9d4, 0xa679, 0xa97c, 0xdd4b, 0xa471, + 0xa4d7, 0xc9d5, 0xcabe, 0xcabf, 0xa7bc, 0xd8d8, 0xb44e, 0xdd4c, + 0xc0aa, 0xa472, 0xa4a8, 0xa4d8, 0xc975, 0xa5a7, 0xa7c0, 0xa7bf, + 0xa7bd, 0xa7be, 0xcc59, 0xa97e, 0xa9a1, 0xcc5a, 0xa97d, 0xabce, + 0xce78, 0xabcd, 0xabcb, 0xabcc, 0xae6a, 0xae68, 0xd16b, 0xae69, + 0xd16a, 0xae5e, 0xd4f3, 0xb150, 0xb151, 0xb14f, 0xb9f0, 0xe1a2, + 0xbc68, 0xbc69, 0xe561, 0xc0ab, 0xefc2, 0xefc3, 0xc4dd, 0xf8a8, + 0xc94b, 0xa4d9, 0xa473, 0xc977, 0xc976, 0xa67a, 0xc9d7, 0xc9d8, + 0xc9d6, 0xc9d9, 0xcac7, 0xcac2, 0xcac4, 0xcac6, 0xcac3, 0xa7c4, + 0xcac0, 0xcac1, 0xa7c1, 0xa7c2, 0xcac5, 0xcac8, 0xa7c3, 0xcac9, + 0xcc68, 0xcc62, 0xcc5d, 0xa9a3, 0xcc65, 0xcc63, 0xcc5c, 0xcc69, + 0xcc6c, 0xcc67, 0xcc60, 0xa9a5, 0xcc66, 0xa9a6, 0xcc61, 0xcc64, + 0xcc5b, 0xcc5f, 0xcc6b, 0xa9a7, 0xa9a8, 0xcc5e, 0xcc6a, 0xa9a2, + 0xa9a4, 0xceab, 0xcea4, 0xceaa, 0xcea3, 0xcea5, 0xce7d, 0xce7b, + 0xceac, 0xcea9, 0xce79, 0xabd0, 0xcea7, 0xcea8, 0xcea6, 0xce7c, + 0xce7a, 0xabcf, 0xcea2, 0xce7e, 0xcea1, 0xcead, 0xae6f, 0xae6e, + 0xd16c, 0xae6b, 0xd16e, 0xae70, 0xd16f, 0xae73, 0xae71, 0xd170, + 0xceae, 0xd172, 0xae6d, 0xae6c, 0xd16d, 0xd171, 0xae72, 0xb153, + 0xb152, 0xd4f5, 0xd4f9, 0xd4fb, 0xb154, 0xd4fe, 0xb158, 0xd541, + 0xb15a, 0xb156, 0xb15e, 0xb15b, 0xd4f7, 0xb155, 0xd4f6, 0xd4f4, + 0xd543, 0xd4f8, 0xb157, 0xd542, 0xb15c, 0xd4fd, 0xd4fc, 0xb15d, + 0xd4fa, 0xb159, 0xd544, 0xd540, 0xd8e7, 0xd8ee, 0xd8e3, 0xb451, + 0xd8df, 0xd8ef, 0xd8d9, 0xd8ec, 0xd8ea, 0xd8e4, 0xd8ed, 0xd8e6, + 0xd8de, 0xd8f0, 0xd8dc, 0xd8e9, 0xd8da, 0xd8f1, 0xb452, 0xd8eb, + 0xdd4f, 0xd8dd, 0xb44f, 0xd8e1, 0xb450, 0xd8e0, 0xd8e5, 0xd8e2, + 0xd8e8, 0xdd53, 0xdd56, 0xdd4e, 0xdd50, 0xdd55, 0xdd54, 0xb743, + 0xd8db, 0xdd52, 0xb744, 0xdd4d, 0xdd51, 0xe1a9, 0xe1b0, 0xe1a7, + 0xe1ae, 0xe1a5, 0xe1ad, 0xe1b1, 0xe1a4, 0xe1a8, 0xe1a3, 0xb9f1, + 0xe1a6, 0xb9f2, 0xe1ac, 0xe1ab, 0xe1aa, 0xe1af, 0xe565, 0xe567, + 0xbc6b, 0xe568, 0xe563, 0xe562, 0xe56c, 0xe56a, 0xbc6a, 0xe56d, + 0xe564, 0xe569, 0xe56b, 0xe566, 0xe961, 0xe966, 0xe960, 0xe965, + 0xe95e, 0xe968, 0xe964, 0xe969, 0xe963, 0xe95f, 0xe967, 0xe96a, + 0xe962, 0xecda, 0xc0af, 0xc0ad, 0xc0ac, 0xc0ae, 0xefc4, 0xf172, + 0xf1fd, 0xf444, 0xf445, 0xc460, 0xf5c9, 0xc4de, 0xf5ca, 0xf6de, + 0xc572, 0xc571, 0xf6dd, 0xc5c9, 0xf7d6, 0xa474, 0xa67b, 0xc9da, + 0xcaca, 0xa8b5, 0xb15f, 0xa475, 0xa5aa, 0xa5a9, 0xa5a8, 0xa7c5, + 0xae74, 0xdd57, 0xa476, 0xa477, 0xa478, 0xa4da, 0xabd1, 0xceaf, + 0xb453, 0xa479, 0xc95d, 0xa5ab, 0xa5ac, 0xc978, 0xa67c, 0xcacb, + 0xa7c6, 0xcacc, 0xa9ae, 0xcc6e, 0xa9ac, 0xa9ab, 0xcc6d, 0xa9a9, + 0xcc6f, 0xa9aa, 0xa9ad, 0xabd2, 0xabd4, 0xceb3, 0xceb0, 0xceb1, + 0xceb2, 0xceb4, 0xabd3, 0xd174, 0xd173, 0xae76, 0xae75, 0xb162, + 0xd546, 0xb161, 0xb163, 0xb160, 0xb455, 0xd545, 0xb456, 0xd8f3, + 0xb457, 0xd8f2, 0xb454, 0xdd5a, 0xdd5c, 0xb745, 0xdd5b, 0xdd59, + 0xdd58, 0xe1b4, 0xb9f7, 0xb9f5, 0xb9f6, 0xe1b2, 0xe1b3, 0xb9f3, + 0xe571, 0xe56f, 0xbc6d, 0xe570, 0xbc6e, 0xbc6c, 0xb9f4, 0xe96d, + 0xe96b, 0xe96c, 0xe56e, 0xecdc, 0xc0b0, 0xecdb, 0xefc5, 0xefc6, + 0xe96e, 0xf1fe, 0xa47a, 0xa5ad, 0xa67e, 0xc9db, 0xa67d, 0xa9af, + 0xb746, 0xa4db, 0xa5ae, 0xabd5, 0xb458, 0xc979, 0xc97a, 0xc9dc, + 0xa7c8, 0xcad0, 0xcace, 0xa7c9, 0xcacd, 0xcacf, 0xcad1, 0xa7c7, + 0xa9b3, 0xa9b4, 0xa9b1, 0xa9b0, 0xceb8, 0xa9b2, 0xabd6, 0xceb7, + 0xceb9, 0xceb6, 0xceba, 0xabd7, 0xae79, 0xd175, 0xd177, 0xae77, + 0xd178, 0xae78, 0xd176, 0xceb5, 0xd547, 0xd54a, 0xd54b, 0xd548, + 0xb167, 0xb166, 0xb164, 0xb165, 0xd549, 0xb168, 0xb45a, 0xb45b, + 0xb45c, 0xdd5d, 0xdd5f, 0xdd61, 0xb748, 0xb747, 0xb459, 0xdd60, + 0xdd5e, 0xe1b8, 0xe1b6, 0xe1bc, 0xb9f8, 0xe1bd, 0xe1ba, 0xb9f9, + 0xe1b7, 0xe1b5, 0xe1bb, 0xbc70, 0xe573, 0xe1b9, 0xbc72, 0xe574, + 0xbc71, 0xbc74, 0xe575, 0xbc6f, 0xbc73, 0xe973, 0xe971, 0xe970, + 0xe972, 0xe96f, 0xc366, 0xf446, 0xf447, 0xf5cb, 0xf6df, 0xc655, + 0xa9b5, 0xa7ca, 0xabd8, 0xa47b, 0xa4dc, 0xa5af, 0xc9dd, 0xa7cb, + 0xcad2, 0xcebb, 0xabd9, 0xb9fa, 0xa47c, 0xa6a1, 0xb749, 0xa47d, + 0xa4dd, 0xa4de, 0xa5b1, 0xa5b0, 0xc9de, 0xa6a2, 0xcad3, 0xa7cc, + 0xcc71, 0xcc72, 0xcc73, 0xa9b6, 0xa9b7, 0xcc70, 0xa9b8, 0xabda, + 0xcebc, 0xd17a, 0xae7a, 0xd179, 0xb169, 0xd54c, 0xb16a, 0xd54d, + 0xb45d, 0xdd62, 0xe1bf, 0xe1be, 0xb9fb, 0xbc75, 0xe576, 0xbeca, + 0xe974, 0xc0b1, 0xc573, 0xf7d8, 0xcc74, 0xcebd, 0xb16b, 0xd8f4, + 0xb74a, 0xc255, 0xa7ce, 0xa7cd, 0xabdb, 0xd17b, 0xb16d, 0xb343, + 0xb16e, 0xb16c, 0xb45e, 0xe1c0, 0xb9fc, 0xbc76, 0xc94c, 0xc9df, + 0xcad5, 0xa7cf, 0xcad4, 0xa7d0, 0xa9bc, 0xcc77, 0xcc76, 0xa9bb, + 0xa9b9, 0xa9ba, 0xcc75, 0xabdd, 0xcebe, 0xabe0, 0xabdc, 0xabe2, + 0xabde, 0xabdf, 0xabe1, 0xae7d, 0xae7c, 0xae7b, 0xd54f, 0xb16f, + 0xb172, 0xb170, 0xd54e, 0xb175, 0xb171, 0xd550, 0xb174, 0xb173, + 0xd8f6, 0xd8f5, 0xb461, 0xb45f, 0xb460, 0xd8f7, 0xb74b, 0xdd64, + 0xb74c, 0xdd63, 0xe577, 0xbc78, 0xe1c1, 0xbc77, 0xb9fd, 0xecde, + 0xe975, 0xc0b2, 0xecdd, 0xf240, 0xf448, 0xf449, 0xa4df, 0xa5b2, + 0xc97b, 0xa7d2, 0xa7d4, 0xc9e2, 0xcad8, 0xcad7, 0xcad6, 0xc9e1, + 0xc9e0, 0xa6a4, 0xa7d3, 0xa7d1, 0xa6a3, 0xa9bd, 0xcc78, 0xa9be, + 0xcadd, 0xcadf, 0xcade, 0xcc79, 0xcada, 0xa7d8, 0xa7d6, 0xcad9, + 0xcadb, 0xcae1, 0xa7d5, 0xcadc, 0xcae5, 0xa9c0, 0xcae2, 0xa7d7, + 0xcae0, 0xcae3, 0xa9bf, 0xa9c1, 0xcae4, 0xccaf, 0xcca2, 0xcc7e, + 0xccae, 0xcca9, 0xabe7, 0xa9c2, 0xccaa, 0xccad, 0xabe3, 0xccac, + 0xa9c3, 0xa9c8, 0xa9c6, 0xcca3, 0xcc7c, 0xcca5, 0xa9cd, 0xccb0, + 0xabe4, 0xcca6, 0xabe5, 0xa9c9, 0xcca8, 0xcecd, 0xabe6, 0xcc7b, + 0xa9ca, 0xabe8, 0xa9cb, 0xa9c7, 0xa9cc, 0xcca7, 0xcc7a, 0xccab, + 0xa9c4, 0xcc7d, 0xcca4, 0xcca1, 0xa9c5, 0xcebf, 0xcec0, 0xceca, + 0xd1a1, 0xcecb, 0xabee, 0xcece, 0xcec4, 0xabed, 0xcec6, 0xcec7, + 0xcec9, 0xabe9, 0xaea3, 0xcec5, 0xcec1, 0xaea4, 0xcecf, 0xae7e, + 0xd17d, 0xcec8, 0xd17c, 0xcec3, 0xcecc, 0xabec, 0xaea1, 0xabf2, + 0xaea2, 0xced0, 0xd17e, 0xabeb, 0xaea6, 0xabf1, 0xabf0, 0xabef, + 0xaea5, 0xced1, 0xaea7, 0xabea, 0xcec2, 0xb176, 0xd1a4, 0xd1a6, + 0xd1a8, 0xaea8, 0xaeae, 0xd553, 0xd1ac, 0xd1a3, 0xb178, 0xd551, + 0xaead, 0xaeab, 0xd1ae, 0xd552, 0xd1a5, 0xaeac, 0xd1a9, 0xaeaf, + 0xd1ab, 0xaeaa, 0xd1aa, 0xd1ad, 0xd1a7, 0xaea9, 0xb179, 0xd1a2, + 0xb177, 0xb17a, 0xd555, 0xd55e, 0xb464, 0xb17c, 0xb1a3, 0xb465, + 0xd560, 0xb1aa, 0xd8f9, 0xd556, 0xb1a2, 0xb1a5, 0xb17e, 0xd554, + 0xd562, 0xd565, 0xd949, 0xd563, 0xd8fd, 0xb1a1, 0xb1a8, 0xb1ac, + 0xd55d, 0xd8f8, 0xd561, 0xb17b, 0xd8fa, 0xd564, 0xd8fc, 0xd559, + 0xb462, 0xd557, 0xd558, 0xb1a7, 0xb1a6, 0xd55b, 0xb1ab, 0xd55f, + 0xb1a4, 0xd55c, 0xb1a9, 0xb466, 0xb463, 0xd8fb, 0xd55a, 0xb17d, + 0xb46b, 0xb46f, 0xd940, 0xb751, 0xb46d, 0xd944, 0xb471, 0xdd65, + 0xd946, 0xb753, 0xb469, 0xb46c, 0xd947, 0xd948, 0xd94e, 0xb473, + 0xb754, 0xd94a, 0xd94f, 0xd943, 0xb75e, 0xb755, 0xb472, 0xd941, + 0xd950, 0xb75d, 0xb470, 0xb74e, 0xd94d, 0xb474, 0xd945, 0xd8fe, + 0xb46a, 0xd942, 0xd94b, 0xb74d, 0xb752, 0xb467, 0xd94c, 0xb750, + 0xb468, 0xb75c, 0xe1c3, 0xdd70, 0xdd68, 0xe1c2, 0xdd6c, 0xdd6e, + 0xdd6b, 0xb75b, 0xdd6a, 0xb75f, 0xe1d2, 0xb75a, 0xba40, 0xdd71, + 0xe1c4, 0xb758, 0xdd69, 0xdd6d, 0xb9fe, 0xb74f, 0xdd66, 0xdd67, + 0xba41, 0xb757, 0xb759, 0xb756, 0xdd6f, 0xe1c8, 0xe1c9, 0xe1ce, + 0xbc7d, 0xe1d5, 0xba47, 0xba46, 0xe1d0, 0xbc7c, 0xe1c5, 0xba45, + 0xe1d4, 0xba43, 0xba44, 0xe1d1, 0xe5aa, 0xbc7a, 0xb46e, 0xe1d3, + 0xbca3, 0xe1cb, 0xbc7b, 0xbca2, 0xe1c6, 0xe1ca, 0xe1c7, 0xe1cd, + 0xba48, 0xbc79, 0xba42, 0xe57a, 0xe1cf, 0xbca1, 0xbca4, 0xe1cc, + 0xbc7e, 0xe579, 0xe57e, 0xbece, 0xe578, 0xe9a3, 0xe5a9, 0xbca8, + 0xbca6, 0xbecc, 0xe5a6, 0xe5a2, 0xbcac, 0xe978, 0xbcaa, 0xe5a1, + 0xe976, 0xe5a5, 0xe5a8, 0xe57d, 0xbcab, 0xbca5, 0xe977, 0xbecd, + 0xe5a7, 0xbca7, 0xbca9, 0xe5a4, 0xbcad, 0xe5a3, 0xe57c, 0xe57b, + 0xbecb, 0xe5ab, 0xe97a, 0xece0, 0xbed0, 0xe9a2, 0xe97e, 0xece1, + 0xbed1, 0xe9a1, 0xe97c, 0xc0b4, 0xecdf, 0xe979, 0xe97b, 0xc0b5, + 0xbed3, 0xc0b3, 0xbed2, 0xc0b7, 0xe97d, 0xbecf, 0xefcf, 0xefc7, + 0xece7, 0xefc8, 0xece3, 0xc256, 0xece5, 0xece4, 0xc0b6, 0xece2, + 0xece6, 0xefd0, 0xefcc, 0xefce, 0xefc9, 0xefca, 0xefcd, 0xefcb, + 0xc367, 0xc36a, 0xc369, 0xc368, 0xc461, 0xf44a, 0xc462, 0xf241, + 0xc4df, 0xf5cc, 0xc4e0, 0xc574, 0xc5ca, 0xf7d9, 0xf7da, 0xf7db, + 0xf9ba, 0xa4e0, 0xc97c, 0xa5b3, 0xa6a6, 0xa6a7, 0xa6a5, 0xa6a8, + 0xa7da, 0xa7d9, 0xccb1, 0xa9cf, 0xa9ce, 0xd1af, 0xb1ad, 0xb1ae, + 0xb475, 0xdd72, 0xb760, 0xb761, 0xdd74, 0xdd76, 0xdd75, 0xe1d7, + 0xe1d6, 0xba49, 0xe1d8, 0xe5ac, 0xbcae, 0xbed4, 0xc0b8, 0xc257, + 0xc0b9, 0xa4e1, 0xcae6, 0xccb2, 0xa9d1, 0xa9d0, 0xa9d2, 0xabf3, + 0xced2, 0xced3, 0xd1b0, 0xaeb0, 0xb1af, 0xb476, 0xd951, 0xa4e2, + 0xa47e, 0xa4e3, 0xc97d, 0xa5b7, 0xa5b6, 0xa5b4, 0xa5b5, 0xa6ab, + 0xc9e9, 0xc9eb, 0xa6aa, 0xc9e3, 0xc9e4, 0xc9ea, 0xc9e6, 0xc9e8, + 0xa6a9, 0xc9e5, 0xc9ec, 0xc9e7, 0xa7e1, 0xa7ea, 0xa7e8, 0xcaf0, + 0xcaed, 0xcaf5, 0xa7e6, 0xcaf6, 0xa7df, 0xcaf3, 0xa7e5, 0xcaef, + 0xcaee, 0xa7e3, 0xcaf4, 0xa7e4, 0xa9d3, 0xa7de, 0xcaf1, 0xcae7, + 0xa7db, 0xa7ee, 0xcaec, 0xcaf2, 0xa7e0, 0xa7e2, 0xcae8, 0xcae9, + 0xcaea, 0xa7ed, 0xa7e7, 0xa7ec, 0xcaeb, 0xa7eb, 0xa7dd, 0xa7dc, + 0xa7e9, 0xa9e1, 0xccbe, 0xccb7, 0xa9dc, 0xa9ef, 0xccb3, 0xccba, + 0xccbc, 0xccbf, 0xa9ea, 0xccbb, 0xccb4, 0xa9e8, 0xccb8, 0xccc0, + 0xa9d9, 0xccbd, 0xa9e3, 0xa9e2, 0xccb6, 0xa9d7, 0xa9d8, 0xa9d6, + 0xa9ee, 0xa9e6, 0xa9e0, 0xa9d4, 0xccb9, 0xa9df, 0xa9d5, 0xa9e7, + 0xa9f0, 0xced4, 0xa9e4, 0xccb5, 0xa9da, 0xa9dd, 0xa9de, 0xa9ec, + 0xa9ed, 0xa9eb, 0xa9e5, 0xa9e9, 0xa9db, 0xabf4, 0xceda, 0xac41, + 0xabf8, 0xabfa, 0xac40, 0xcee6, 0xabfd, 0xd1b1, 0xaeb1, 0xac43, + 0xced7, 0xcedf, 0xabfe, 0xcede, 0xcedb, 0xcee3, 0xcee5, 0xabf7, + 0xabfb, 0xac42, 0xaeb3, 0xcee0, 0xabf9, 0xac45, 0xced9, 0xabfc, + 0xaeb2, 0xabf6, 0xced6, 0xcedd, 0xced5, 0xced8, 0xcedc, 0xd1b2, + 0xac44, 0xcee1, 0xcee2, 0xcee4, 0xabf5, 0xaec1, 0xd1be, 0xaebf, + 0xaec0, 0xd1b4, 0xd1c4, 0xaeb6, 0xd566, 0xd1c6, 0xd1c0, 0xd1b7, + 0xd1c9, 0xd1ba, 0xaebc, 0xd57d, 0xd1bd, 0xaebe, 0xaeb5, 0xd1cb, + 0xd1bf, 0xaeb8, 0xd1b8, 0xd1b5, 0xd1b6, 0xaeb9, 0xd1c5, 0xd1cc, + 0xaebb, 0xd1bc, 0xd1bb, 0xaec3, 0xaec2, 0xaeb4, 0xaeba, 0xaebd, + 0xd1c8, 0xd1c2, 0xaeb7, 0xd1b3, 0xd1ca, 0xd1c1, 0xd1c3, 0xd1c7, + 0xd567, 0xb1b7, 0xb1cb, 0xb1ca, 0xb1bf, 0xd579, 0xd575, 0xd572, + 0xd5a6, 0xb1ba, 0xb1b2, 0xd577, 0xb4a8, 0xb1b6, 0xd5a1, 0xb1cc, + 0xb1c9, 0xd57b, 0xd56a, 0xb1c8, 0xd5a3, 0xd569, 0xb1bd, 0xb1c1, + 0xd5a2, 0xd573, 0xb1c2, 0xb1bc, 0xd568, 0xb478, 0xd5a5, 0xd571, + 0xb1c7, 0xd574, 0xd5a4, 0xb1c6, 0xd952, 0xb1b3, 0xd56f, 0xb1b8, + 0xb1c3, 0xb1be, 0xd578, 0xd56e, 0xd56c, 0xd57e, 0xb1b0, 0xb1c4, + 0xb1b4, 0xb477, 0xd57c, 0xb1b5, 0xb1b1, 0xb1c0, 0xb1bb, 0xb1b9, + 0xd570, 0xb1c5, 0xd56d, 0xd57a, 0xd576, 0xd954, 0xd953, 0xd56b, + 0xd964, 0xb47a, 0xd96a, 0xd959, 0xd967, 0xdd77, 0xb47d, 0xd96b, + 0xd96e, 0xb47c, 0xd95c, 0xd96d, 0xd96c, 0xb47e, 0xd955, 0xb479, + 0xb4a3, 0xb4a1, 0xd969, 0xd95f, 0xb4a5, 0xd970, 0xd968, 0xd971, + 0xb4ad, 0xb4ab, 0xd966, 0xd965, 0xd963, 0xd95d, 0xb4a4, 0xb4a2, + 0xd1b9, 0xd956, 0xddb7, 0xd957, 0xb47b, 0xb4aa, 0xdd79, 0xb4a6, + 0xb4a7, 0xd958, 0xd96f, 0xdd78, 0xd960, 0xd95b, 0xb4a9, 0xd961, + 0xd95e, 0xb4ae, 0xb770, 0xdd7c, 0xddb1, 0xddb6, 0xddaa, 0xb76c, + 0xddbb, 0xb769, 0xdd7a, 0xdd7b, 0xb762, 0xb76b, 0xdda4, 0xb76e, + 0xb76f, 0xdda5, 0xddb2, 0xddb8, 0xb76a, 0xb764, 0xdda3, 0xdd7d, + 0xddba, 0xdda8, 0xdda9, 0xdd7e, 0xddb4, 0xddab, 0xddb5, 0xddad, + 0xb765, 0xe1d9, 0xb768, 0xb766, 0xddb9, 0xddb0, 0xddac, 0xdda1, + 0xba53, 0xddaf, 0xb76d, 0xdda7, 0xdda6, 0xb767, 0xb763, 0xe1ee, + 0xddb3, 0xddae, 0xdda2, 0xe1e9, 0xe1da, 0xe1e5, 0xe1ec, 0xba51, + 0xb4ac, 0xe1ea, 0xba4c, 0xba4b, 0xe1f1, 0xe1db, 0xe1e8, 0xe1dc, + 0xe1e7, 0xba4f, 0xe1eb, 0xd962, 0xe1f2, 0xe1e3, 0xba52, 0xe5ba, + 0xbcaf, 0xe1f0, 0xe1ef, 0xba54, 0xe5ad, 0xbcb0, 0xe5ae, 0xe1df, + 0xe1e0, 0xe1dd, 0xe1e2, 0xe1de, 0xe1f3, 0xba4e, 0xbcb1, 0xba50, + 0xba55, 0xe1e1, 0xe1ed, 0xe1e6, 0xe5b1, 0xba4a, 0xbcb4, 0xe9aa, + 0xe5b6, 0xe5b5, 0xe5b7, 0xe5b4, 0xbcb5, 0xbcbb, 0xbcb8, 0xbcb9, + 0xe5af, 0xe5b2, 0xe5bc, 0xbcc1, 0xbcbf, 0xe5b3, 0xd95a, 0xbcb2, + 0xe5b9, 0xe5b0, 0xbcc2, 0xe5b8, 0xba4d, 0xbcb7, 0xe1e4, 0xbcba, + 0xbcbe, 0xbcc0, 0xbcbd, 0xbcbc, 0xbcb6, 0xe5bb, 0xbcb3, 0xbcc3, + 0xbed8, 0xbed9, 0xe9a9, 0xbee2, 0xbedf, 0xbed6, 0xbedd, 0xe9ab, + 0xbedb, 0xbed5, 0xbedc, 0xe9a8, 0xc0bb, 0xbed7, 0xbede, 0xc0ba, + 0xe9a7, 0xe9a6, 0xbee0, 0xbee1, 0xe9a5, 0xe9a4, 0xc0bc, 0xe9ae, + 0xbeda, 0xe9ac, 0xc0bd, 0xc0c2, 0xecea, 0xecec, 0xc0bf, 0xeced, + 0xece9, 0xeceb, 0xc0c0, 0xc0c3, 0xece8, 0xc0be, 0xc0c1, 0xc259, + 0xe9ad, 0xc258, 0xc25e, 0xefd4, 0xc25c, 0xc25d, 0xefd7, 0xefd3, + 0xc25a, 0xefd1, 0xc36b, 0xefd5, 0xefd6, 0xefd2, 0xc25b, 0xf242, + 0xf245, 0xf246, 0xf244, 0xf247, 0xc36c, 0xf243, 0xf44e, 0xc464, + 0xf44d, 0xf44c, 0xf44b, 0xc463, 0xc465, 0xf5cd, 0xc4e2, 0xc4e1, + 0xf6e1, 0xf6e0, 0xf6e3, 0xc5cb, 0xc575, 0xf7dd, 0xf6e2, 0xf7dc, + 0xc5cd, 0xc5cc, 0xc5f3, 0xf8a9, 0xf8ef, 0xa4e4, 0xd972, 0xe9af, + 0xa6ac, 0xcaf7, 0xa7f1, 0xa7ef, 0xa7f0, 0xccc1, 0xa9f1, 0xac46, + 0xcee7, 0xcee8, 0xac47, 0xd1ce, 0xaec4, 0xaec5, 0xd1cd, 0xb1d3, + 0xb1cf, 0xd5a7, 0xb1d6, 0xb1d5, 0xb1ce, 0xb1d1, 0xb1d4, 0xb1d0, + 0xd976, 0xb1cd, 0xb4af, 0xb4b1, 0xb4b2, 0xd975, 0xd978, 0xb4b0, + 0xd973, 0xd977, 0xd974, 0xb771, 0xddbc, 0xba56, 0xe1f4, 0xbee3, + 0xbcc4, 0xe5bd, 0xbcc5, 0xbcc6, 0xe5bf, 0xe5be, 0xe5c0, 0xe9b1, + 0xe9b0, 0xecef, 0xecee, 0xc0c4, 0xc0c5, 0xf248, 0xa4e5, 0xd979, + 0xb4b4, 0xb4b3, 0xddbd, 0xefd8, 0xc4e3, 0xf7de, 0xa4e6, 0xaec6, + 0xb1d8, 0xb1d7, 0xd97a, 0xd97b, 0xb772, 0xe1f5, 0xba57, 0xe9b2, + 0xa4e7, 0xa5b8, 0xa9f2, 0xccc2, 0xcee9, 0xac48, 0xb1d9, 0xd97c, + 0xb4b5, 0xb773, 0xe5c1, 0xe5c2, 0xecf0, 0xc25f, 0xf8f0, 0xa4e8, + 0xccc3, 0xa9f3, 0xac49, 0xceea, 0xaec7, 0xd1d2, 0xd1d0, 0xd1d1, + 0xaec8, 0xd1cf, 0xb1db, 0xb1dc, 0xd5a8, 0xb1dd, 0xb1da, 0xd97d, + 0xd97e, 0xddbe, 0xba59, 0xba58, 0xecf1, 0xefd9, 0xf24a, 0xf249, + 0xf44f, 0xc95e, 0xac4a, 0xa4e9, 0xa5b9, 0xa6ae, 0xa6ad, 0xa6af, + 0xa6b0, 0xc9ee, 0xc9ed, 0xcaf8, 0xa7f2, 0xcafb, 0xcafa, 0xcaf9, + 0xcafc, 0xa9f4, 0xccc9, 0xccc5, 0xccce, 0xa9fb, 0xa9f9, 0xccca, + 0xccc6, 0xcccd, 0xa9f8, 0xaa40, 0xccc8, 0xccc4, 0xa9fe, 0xcccb, + 0xa9f7, 0xcccc, 0xa9fa, 0xa9fc, 0xccd0, 0xcccf, 0xccc7, 0xa9f6, + 0xa9f5, 0xa9fd, 0xceef, 0xcef5, 0xac50, 0xac4d, 0xceec, 0xcef1, + 0xac53, 0xac4b, 0xcef0, 0xac4e, 0xac51, 0xcef3, 0xac4c, 0xcef8, + 0xac4f, 0xac52, 0xceed, 0xcef2, 0xcef6, 0xceee, 0xceeb, 0xcef7, + 0xcef4, 0xaed0, 0xaec9, 0xaecc, 0xaecf, 0xd1d5, 0xaeca, 0xd1d3, + 0xaece, 0xaecb, 0xd1d6, 0xaecd, 0xd5ac, 0xb1df, 0xd5ab, 0xd5ad, + 0xb1de, 0xb1e3, 0xd1d4, 0xd5aa, 0xd5ae, 0xb1e0, 0xd5a9, 0xb1e2, + 0xb1e1, 0xd9a7, 0xd9a2, 0xb4b6, 0xb4ba, 0xb4b7, 0xd9a5, 0xd9a8, + 0xb4b8, 0xb4b9, 0xb4be, 0xddc7, 0xd9a6, 0xb4bc, 0xd9a3, 0xd9a1, + 0xb4bd, 0xd9a4, 0xb779, 0xddbf, 0xb776, 0xb777, 0xb775, 0xddc4, + 0xddc3, 0xddc0, 0xb77b, 0xddc2, 0xb4bb, 0xddc6, 0xddc1, 0xb778, + 0xb774, 0xb77a, 0xddc5, 0xba5c, 0xe1f8, 0xe1f7, 0xe1f6, 0xba5a, + 0xba5b, 0xe5c5, 0xe5c8, 0xbcc8, 0xbcc7, 0xe5c9, 0xe5c4, 0xbcca, + 0xe5c6, 0xbcc9, 0xe5c3, 0xe5c7, 0xbee9, 0xbee6, 0xe9bb, 0xe9ba, + 0xe9b9, 0xe9b4, 0xe9b5, 0xbee7, 0xbee4, 0xbee8, 0xe9b3, 0xbee5, + 0xe9b6, 0xe9b7, 0xe9bc, 0xe9b8, 0xecf2, 0xc0c7, 0xefdc, 0xc0c6, + 0xefda, 0xefdb, 0xc260, 0xc36e, 0xf24b, 0xc36d, 0xf451, 0xf452, + 0xc466, 0xf450, 0xc4e4, 0xf7df, 0xc5ce, 0xf8aa, 0xf8ab, 0xa4ea, + 0xa6b1, 0xa6b2, 0xa7f3, 0xccd1, 0xac54, 0xaed1, 0xb1e4, 0xb0d2, + 0xb4bf, 0xb4c0, 0xb3cc, 0xd9a9, 0xb77c, 0xe1fa, 0xe1f9, 0xa4eb, + 0xa6b3, 0xccd2, 0xaa42, 0xaa41, 0xcef9, 0xcefa, 0xd1d7, 0xd1d8, + 0xaed2, 0xaed3, 0xaed4, 0xd5af, 0xb1e6, 0xb4c2, 0xb4c1, 0xddc8, + 0xdf7a, 0xe1fb, 0xe9bd, 0xc261, 0xc467, 0xa4ec, 0xa5bc, 0xa5bd, + 0xa5bb, 0xa5be, 0xa5ba, 0xa6b6, 0xc9f6, 0xa6b5, 0xa6b7, 0xc9f1, + 0xc9f0, 0xc9f3, 0xc9f2, 0xc9f5, 0xa6b4, 0xc9ef, 0xc9f4, 0xcafd, + 0xa7fd, 0xcafe, 0xcb43, 0xa7fc, 0xcb47, 0xcb42, 0xcb45, 0xa7f5, + 0xa7f6, 0xa7f7, 0xa7f8, 0xa840, 0xcb41, 0xa7fa, 0xa841, 0xcb40, + 0xcb46, 0xa7f9, 0xcb44, 0xa7fb, 0xa7f4, 0xa7fe, 0xaa57, 0xccd4, + 0xaa43, 0xaa4d, 0xaa4e, 0xaa46, 0xaa58, 0xaa48, 0xccdc, 0xaa53, + 0xccd7, 0xaa49, 0xcce6, 0xcce7, 0xccdf, 0xccd8, 0xaa56, 0xcce4, + 0xaa51, 0xaa4f, 0xcce5, 0xcce3, 0xccdb, 0xccd3, 0xccda, 0xaa4a, + 0xaa50, 0xaa44, 0xccde, 0xccdd, 0xccd5, 0xaa52, 0xcce1, 0xccd6, + 0xaa55, 0xcce8, 0xaa45, 0xaa4c, 0xccd9, 0xcce2, 0xaa54, 0xaa47, + 0xaa4b, 0xcce0, 0xcf5b, 0xac5c, 0xac69, 0xcf56, 0xcf4c, 0xac62, + 0xcf4a, 0xac5b, 0xcf45, 0xac65, 0xcf52, 0xcefe, 0xcf41, 0xcf44, + 0xcefb, 0xcf51, 0xcf61, 0xac60, 0xcf46, 0xcf58, 0xcefd, 0xcf5f, + 0xcf60, 0xcf63, 0xcf5a, 0xcf4b, 0xcf53, 0xac66, 0xac59, 0xac61, + 0xac6d, 0xac56, 0xac58, 0xcf43, 0xac6a, 0xac63, 0xcf5d, 0xcf40, + 0xac6c, 0xac67, 0xcf49, 0xac6b, 0xcf50, 0xcf48, 0xac64, 0xcf5c, + 0xcf54, 0xac5e, 0xcf62, 0xcf47, 0xac5a, 0xcf59, 0xcf4f, 0xac5f, + 0xcf55, 0xac57, 0xcefc, 0xac68, 0xaee3, 0xac5d, 0xcf4e, 0xcf4d, + 0xcf42, 0xcf5e, 0xcf57, 0xac55, 0xd1ec, 0xaeea, 0xd1ed, 0xd1e1, + 0xaedf, 0xaeeb, 0xd1da, 0xd1e3, 0xd1eb, 0xd1d9, 0xd1f4, 0xaed5, + 0xd1f3, 0xd1ee, 0xd1ef, 0xaedd, 0xaee8, 0xd1e5, 0xd1e6, 0xd1f0, + 0xd1e7, 0xd1e2, 0xd1dc, 0xd1dd, 0xd1ea, 0xd1e4, 0xaed6, 0xaeda, + 0xd1f2, 0xd1de, 0xaee6, 0xaee2, 0xaee5, 0xaeec, 0xaedb, 0xaee7, + 0xd1e9, 0xaee9, 0xaed8, 0xaed7, 0xd1db, 0xd1df, 0xaee0, 0xd1f1, + 0xd1e8, 0xd1e0, 0xaee4, 0xaee1, 0xaed9, 0xaedc, 0xd5c4, 0xd5b4, + 0xd5b5, 0xd5b9, 0xd5c8, 0xd5c5, 0xd5be, 0xd5bd, 0xb1ed, 0xd5c1, + 0xd5d0, 0xd5b0, 0xd5d1, 0xd5c3, 0xd5d5, 0xd5c9, 0xb1ec, 0xd5c7, + 0xb1e7, 0xb1fc, 0xb1f2, 0xb1f6, 0xb1f5, 0xd5b1, 0xd5ce, 0xd5d4, + 0xd5cc, 0xd5d3, 0xd5c0, 0xd5b2, 0xd5d2, 0xd5c2, 0xb1ea, 0xb1f7, + 0xd5cb, 0xb1f0, 0xd5ca, 0xd5b3, 0xb1f8, 0xb1fa, 0xd5cd, 0xb1fb, + 0xb1e9, 0xd5ba, 0xd5cf, 0xb1ef, 0xb1f9, 0xd5bc, 0xd5c6, 0xd5b7, + 0xd5bb, 0xb1f4, 0xd5b6, 0xb1e8, 0xb1f1, 0xb1ee, 0xd5bf, 0xaede, + 0xd9c0, 0xb1eb, 0xb1f3, 0xd9c3, 0xd9d9, 0xd9ce, 0xb4d6, 0xb4d1, + 0xd9bd, 0xb4d2, 0xd9cd, 0xd9c6, 0xd9d3, 0xb4ce, 0xd9ab, 0xd9d5, + 0xb4c4, 0xd9b3, 0xb4c7, 0xb4c6, 0xb4d7, 0xd9ad, 0xd9cf, 0xd9d0, + 0xb4c9, 0xb4c5, 0xd9bb, 0xb4d0, 0xd9b6, 0xd9d1, 0xb4cc, 0xd9c9, + 0xd9d6, 0xd9b0, 0xd9b5, 0xd9af, 0xb4cb, 0xd9c2, 0xddde, 0xd9b1, + 0xb4cf, 0xd9ba, 0xd9d2, 0xb4ca, 0xd9b7, 0xd9b4, 0xd9c5, 0xb4cd, + 0xb4c3, 0xb4d9, 0xd9c8, 0xd9c7, 0xd9ac, 0xb4c8, 0xd9d4, 0xd9bc, + 0xd9be, 0xd9cb, 0xd9ca, 0xd9aa, 0xb4d3, 0xb4d5, 0xd9b2, 0xd9b9, + 0xd9c1, 0xb4d4, 0xd9b8, 0xd9c4, 0xd9d7, 0xd9cc, 0xd9d8, 0xd9ae, + 0xddf2, 0xb7a6, 0xddf0, 0xdddb, 0xdde0, 0xddd9, 0xddec, 0xddcb, + 0xddd2, 0xddea, 0xddf4, 0xdddc, 0xddcf, 0xdde2, 0xdde7, 0xddd3, + 0xdde4, 0xddd0, 0xddd7, 0xddd8, 0xb7a8, 0xddeb, 0xdde9, 0xddcc, + 0xddee, 0xddef, 0xddf1, 0xb7ac, 0xb7a4, 0xd5b8, 0xddd4, 0xdde6, + 0xddd5, 0xb7a1, 0xb7b1, 0xdded, 0xb7af, 0xb7ab, 0xddca, 0xb7a3, + 0xddcd, 0xb7b0, 0xdddd, 0xddc9, 0xb7a9, 0xdde1, 0xddd1, 0xb7aa, + 0xddda, 0xb77e, 0xb4d8, 0xdde3, 0xd9bf, 0xddce, 0xdde8, 0xb7a5, + 0xdde5, 0xb7a2, 0xdddf, 0xb7ad, 0xddd6, 0xddf3, 0xb7a7, 0xdec6, + 0xb7ae, 0xe24a, 0xe248, 0xe25e, 0xe246, 0xe258, 0xb77d, 0xba5f, + 0xe242, 0xe25d, 0xe247, 0xe255, 0xba64, 0xba5d, 0xe25b, 0xe240, + 0xe25a, 0xba6f, 0xe251, 0xe261, 0xba6d, 0xe249, 0xba5e, 0xe24b, + 0xe259, 0xba67, 0xe244, 0xba6b, 0xba61, 0xe24d, 0xe243, 0xe1fc, + 0xe257, 0xba68, 0xe260, 0xe1fd, 0xba65, 0xe253, 0xba66, 0xe245, + 0xe250, 0xe24c, 0xe24e, 0xba60, 0xe25f, 0xba6e, 0xe24f, 0xe262, + 0xe1fe, 0xe254, 0xba63, 0xba6c, 0xba6a, 0xe241, 0xe256, 0xba69, + 0xba62, 0xe252, 0xe25c, 0xe5d5, 0xe5d1, 0xe5cd, 0xe5e1, 0xe5de, + 0xbccd, 0xe5e5, 0xe5d4, 0xbcd8, 0xe5db, 0xe5d0, 0xe5da, 0xbcd5, + 0xe5ee, 0xe5eb, 0xe5dd, 0xe5ce, 0xe5e2, 0xe5e4, 0xbcd1, 0xe5d8, + 0xe5d3, 0xe5ca, 0xbcce, 0xbcd6, 0xe5e7, 0xbcd7, 0xe5cb, 0xe5ed, + 0xe5e0, 0xe5e6, 0xbcd4, 0xe5e3, 0xe5ea, 0xbcd9, 0xbcd3, 0xe5dc, + 0xe5cf, 0xe5ef, 0xe5cc, 0xe5e8, 0xbcd0, 0xe5d6, 0xe5d7, 0xbccf, + 0xbccc, 0xe5d2, 0xbcd2, 0xbccb, 0xe5e9, 0xe5ec, 0xe5d9, 0xe9ca, + 0xe9c2, 0xe9be, 0xbef6, 0xbeeb, 0xbef0, 0xbeec, 0xe9cc, 0xe9d7, + 0xbeea, 0xe9c4, 0xe9cd, 0xe5df, 0xe9ce, 0xbef1, 0xe9dd, 0xbef5, + 0xbef8, 0xe9c0, 0xbef4, 0xe9db, 0xe9dc, 0xe9d2, 0xe9d1, 0xe9c9, + 0xe9d3, 0xe9da, 0xe9d9, 0xbeef, 0xbeed, 0xe9cb, 0xe9c8, 0xe9c5, + 0xe9d8, 0xbef7, 0xe9d6, 0xbef3, 0xbef2, 0xe9d0, 0xe9bf, 0xe9c1, + 0xe9c3, 0xe9d5, 0xe9cf, 0xbeee, 0xe9c6, 0xe9d4, 0xe9c7, 0xc0cf, + 0xed45, 0xc0c8, 0xecf5, 0xed41, 0xc0ca, 0xed48, 0xecfc, 0xecf7, + 0xed49, 0xecf3, 0xecfe, 0xc0d1, 0xed44, 0xed4a, 0xecfd, 0xc0c9, + 0xed40, 0xecf4, 0xc0d0, 0xed47, 0xecf9, 0xc0cc, 0xecfb, 0xecf8, + 0xc0d2, 0xecfa, 0xc0cb, 0xc0ce, 0xed43, 0xecf6, 0xed46, 0xed42, + 0xc263, 0xefe7, 0xc268, 0xc269, 0xc262, 0xefe6, 0xefe3, 0xefe4, + 0xc266, 0xefde, 0xefe2, 0xc265, 0xefdf, 0xc267, 0xc264, 0xefdd, + 0xefe1, 0xefe5, 0xf251, 0xf24e, 0xf257, 0xf256, 0xf254, 0xf24f, + 0xc372, 0xf250, 0xc371, 0xc0cd, 0xf253, 0xc370, 0xf258, 0xf252, + 0xf24d, 0xefe0, 0xc36f, 0xf24c, 0xf456, 0xf455, 0xf255, 0xc468, + 0xf459, 0xf45a, 0xf454, 0xf458, 0xf453, 0xf5d1, 0xf457, 0xc4e7, + 0xc4e5, 0xf5cf, 0xf5d2, 0xf5ce, 0xf5d0, 0xc4e6, 0xf6e5, 0xf6e6, + 0xc576, 0xf6e4, 0xf7e2, 0xc5cf, 0xf7e0, 0xf7e1, 0xf8ac, 0xc656, + 0xf8f3, 0xf8f1, 0xf8f2, 0xf8f4, 0xf9bb, 0xa4ed, 0xa6b8, 0xaa59, + 0xcce9, 0xcf64, 0xd1f5, 0xd1f7, 0xd1f6, 0xd1f8, 0xb1fd, 0xd5d7, + 0xd1f9, 0xd5d6, 0xd5d8, 0xd5d9, 0xd9da, 0xb4db, 0xd9db, 0xd9dd, + 0xb4dc, 0xb4da, 0xd9dc, 0xddfa, 0xddf8, 0xddf7, 0xddf6, 0xddf5, + 0xb7b2, 0xddf9, 0xba70, 0xe263, 0xe265, 0xba71, 0xe264, 0xbcdb, + 0xbcda, 0xe5f0, 0xe9df, 0xe9de, 0xe9e0, 0xbef9, 0xed4b, 0xc0d3, + 0xefe8, 0xc26a, 0xf259, 0xc577, 0xa4ee, 0xa5bf, 0xa6b9, 0xa842, + 0xaa5a, 0xaa5b, 0xac6e, 0xd1fa, 0xb7b3, 0xe6d1, 0xbefa, 0xc26b, + 0xa4ef, 0xa6ba, 0xcceb, 0xaa5c, 0xccea, 0xcf65, 0xac6f, 0xcf66, + 0xac70, 0xd1fc, 0xaeee, 0xaeed, 0xd5de, 0xd5dc, 0xd5dd, 0xd5db, + 0xd5da, 0xd9de, 0xd9e1, 0xb4de, 0xd9df, 0xb4dd, 0xd9e0, 0xddfb, + 0xe266, 0xe267, 0xe268, 0xe5f3, 0xe5f2, 0xbcdc, 0xe5f1, 0xe5f4, + 0xe9e1, 0xe9e2, 0xe9e3, 0xed4c, 0xc0d4, 0xc26c, 0xf25a, 0xc4e8, + 0xc95f, 0xac71, 0xcf67, 0xaeef, 0xb1fe, 0xb4df, 0xd9e2, 0xb7b5, + 0xb7b4, 0xe269, 0xe26a, 0xbcdd, 0xbcde, 0xe9e5, 0xe9e4, 0xefe9, + 0xf7e3, 0xa4f0, 0xc960, 0xa5c0, 0xa843, 0xcb48, 0xac72, 0xb7b6, + 0xa4f1, 0xcf68, 0xac73, 0xcf69, 0xc0d5, 0xa4f2, 0xccec, 0xcf6a, + 0xd242, 0xd241, 0xd1fe, 0xd1fd, 0xd243, 0xd240, 0xb240, 0xb241, + 0xb4e0, 0xd9e3, 0xd9e4, 0xd9e5, 0xde41, 0xde42, 0xde40, 0xddfd, + 0xddfe, 0xb7b7, 0xe26b, 0xe5f7, 0xe5f6, 0xe5f5, 0xe5f8, 0xe9e7, + 0xe9e6, 0xbefb, 0xe9e8, 0xc0d6, 0xed4d, 0xefea, 0xf25b, 0xf6e7, + 0xa4f3, 0xa5c2, 0xa5c1, 0xaa5d, 0xc961, 0xc97e, 0xa6bb, 0xc9f7, + 0xcb49, 0xcb4a, 0xaa5e, 0xcced, 0xac74, 0xcf6b, 0xcf6c, 0xaef0, + 0xaef4, 0xd244, 0xaef3, 0xaef1, 0xaef2, 0xd5df, 0xb242, 0xb4e3, + 0xb4e1, 0xb4e2, 0xd9e6, 0xba72, 0xa4f4, 0xc9a1, 0xa5c3, 0xc9a4, + 0xa5c6, 0xc9a3, 0xa5c5, 0xa5c4, 0xa844, 0xc9a2, 0xc9f8, 0xc9fc, + 0xc9fe, 0xca40, 0xa6c5, 0xa6c6, 0xc9fb, 0xa6c1, 0xc9f9, 0xc9fd, + 0xa6c2, 0xa6bd, 0xa6be, 0xa6c4, 0xc9fa, 0xa6bc, 0xa845, 0xa6bf, + 0xa6c0, 0xa6c3, 0xcb5b, 0xcb59, 0xcb4c, 0xa851, 0xcb53, 0xa84c, + 0xcb4d, 0xcb55, 0xcb52, 0xa84f, 0xcb51, 0xa856, 0xcb5a, 0xa858, + 0xa85a, 0xcb4b, 0xa84d, 0xcb5c, 0xa854, 0xa857, 0xcd45, 0xa847, + 0xa85e, 0xa855, 0xcb4e, 0xa84a, 0xa859, 0xcb56, 0xa848, 0xa849, + 0xcd43, 0xcb4f, 0xa850, 0xa85b, 0xcb5d, 0xcb50, 0xa84e, 0xa853, + 0xccee, 0xa85c, 0xcb57, 0xa852, 0xa85d, 0xa846, 0xcb54, 0xa84b, + 0xcb58, 0xcd44, 0xaa6a, 0xaa7a, 0xccf5, 0xaa71, 0xcd4b, 0xaa62, + 0xaa65, 0xcd42, 0xccf3, 0xccf7, 0xaa6d, 0xaa6f, 0xccfa, 0xaa76, + 0xaa68, 0xaa66, 0xaa67, 0xaa75, 0xcd47, 0xaa70, 0xccf9, 0xccfb, + 0xaa6e, 0xaa73, 0xccfc, 0xcd4a, 0xac75, 0xaa79, 0xaa63, 0xcd49, + 0xcd4d, 0xccf8, 0xcd4f, 0xcd40, 0xaa6c, 0xccf4, 0xaa6b, 0xaa7d, + 0xaa72, 0xccf2, 0xcf75, 0xaa78, 0xaa7c, 0xcd41, 0xcd46, 0xaa7e, + 0xaa77, 0xaa69, 0xaa5f, 0xaa64, 0xccf6, 0xaa60, 0xcd4e, 0xccf0, + 0xccef, 0xccfd, 0xccf1, 0xaa7b, 0xaef5, 0xaa74, 0xccfe, 0xaa61, + 0xaca6, 0xcd4c, 0xcf7c, 0xcfa1, 0xcfa4, 0xcf77, 0xcfa7, 0xcfaa, + 0xcfac, 0xcf74, 0xac76, 0xac7b, 0xd249, 0xacad, 0xcfa5, 0xcfad, + 0xcf7b, 0xcf73, 0xd264, 0xac7e, 0xcfa2, 0xcf78, 0xcf7a, 0xaca5, + 0xcf7d, 0xac7d, 0xcf70, 0xcfa8, 0xcfab, 0xac7a, 0xaca8, 0xcf6d, + 0xacaa, 0xac78, 0xacae, 0xcfa9, 0xcf6f, 0xacab, 0xd25e, 0xcd48, + 0xac7c, 0xac77, 0xcf76, 0xcf6e, 0xacac, 0xaca4, 0xcfa3, 0xaca9, + 0xaca7, 0xcf79, 0xaca1, 0xcf71, 0xaca2, 0xaca3, 0xcf72, 0xcfa6, + 0xac79, 0xcf7e, 0xd24c, 0xaefd, 0xaf43, 0xd255, 0xd25b, 0xd257, + 0xd24a, 0xd24d, 0xd246, 0xd247, 0xaf4a, 0xaefa, 0xd256, 0xd25f, + 0xaf45, 0xaef6, 0xaf40, 0xd24e, 0xaf42, 0xd24f, 0xd259, 0xaf44, + 0xd268, 0xd248, 0xaefc, 0xaefb, 0xaf48, 0xd245, 0xd266, 0xd25a, + 0xd267, 0xd261, 0xd253, 0xd262, 0xd25c, 0xd265, 0xd263, 0xaf49, + 0xd254, 0xaef9, 0xaef8, 0xaf41, 0xaf47, 0xd260, 0xaf46, 0xd251, + 0xb243, 0xd269, 0xd250, 0xd24b, 0xaefe, 0xaf4b, 0xaef7, 0xd258, + 0xd25d, 0xb265, 0xd5e1, 0xd5e5, 0xb252, 0xb250, 0xb247, 0xd5e3, + 0xd5e2, 0xb25b, 0xd5e8, 0xb255, 0xd5fa, 0xd647, 0xb244, 0xd5f7, + 0xd5f0, 0xb267, 0xd5e0, 0xd5fc, 0xb264, 0xb258, 0xb263, 0xb24e, + 0xd5ec, 0xd5fe, 0xd5f6, 0xb24f, 0xb249, 0xd645, 0xd5fd, 0xd640, + 0xb251, 0xb259, 0xd642, 0xd5ea, 0xd5fb, 0xd5ef, 0xd644, 0xb25e, + 0xb246, 0xb25c, 0xd5f4, 0xd5f2, 0xd5f3, 0xb253, 0xd5ee, 0xd5ed, + 0xb248, 0xd5e7, 0xd646, 0xb24a, 0xd5f1, 0xb268, 0xb262, 0xd5e6, + 0xb25f, 0xb25d, 0xb266, 0xd5f8, 0xb261, 0xd252, 0xd5f9, 0xb260, + 0xd641, 0xb245, 0xd5f5, 0xb257, 0xd5e9, 0xb256, 0xb254, 0xb24c, + 0xb24b, 0xd9e7, 0xd643, 0xd5eb, 0xd9fc, 0xb24d, 0xb541, 0xb25a, + 0xb4ee, 0xd9f6, 0xb4fc, 0xd9ea, 0xb4eb, 0xb4e7, 0xda49, 0xb4ed, + 0xb4f1, 0xb4ec, 0xb4f5, 0xda4d, 0xda44, 0xd9f1, 0xb4fa, 0xb4f4, + 0xd9fd, 0xb4e4, 0xda4a, 0xda43, 0xb4e8, 0xd9f7, 0xb4f7, 0xda55, + 0xda56, 0xb4e5, 0xda48, 0xb4f9, 0xd9fb, 0xd9ed, 0xd9ee, 0xb4fd, + 0xd9f2, 0xd9f9, 0xd9f3, 0xb4fb, 0xb544, 0xd9ef, 0xd9e8, 0xd9e9, + 0xd9eb, 0xb4ea, 0xd9f8, 0xb4f8, 0xb542, 0xd9fa, 0xda53, 0xda4b, + 0xb4e6, 0xda51, 0xb4f2, 0xb4f0, 0xda57, 0xb4ef, 0xda41, 0xd9f4, + 0xd9fe, 0xb547, 0xda45, 0xda42, 0xd9f0, 0xb543, 0xda4f, 0xda4c, + 0xda54, 0xb4e9, 0xda40, 0xb546, 0xda47, 0xb4f3, 0xb4f6, 0xda46, + 0xb545, 0xd9f5, 0xd5e4, 0xda50, 0xda4e, 0xda52, 0xd9ec, 0xb540, + 0xde61, 0xde60, 0xde46, 0xb7bd, 0xde5f, 0xde49, 0xde4a, 0xb7c7, + 0xde68, 0xb7c2, 0xde5e, 0xde43, 0xb7c8, 0xb7be, 0xde52, 0xde48, + 0xde4b, 0xde63, 0xb7b8, 0xde6a, 0xde62, 0xb7c1, 0xde57, 0xb7cc, + 0xb7cb, 0xb7c5, 0xde69, 0xb7b9, 0xde55, 0xde4c, 0xde59, 0xde65, + 0xb7cd, 0xb7bb, 0xde54, 0xde4d, 0xb7c4, 0xb7c3, 0xde50, 0xde5a, + 0xde64, 0xde47, 0xde51, 0xb7bc, 0xde5b, 0xb7c9, 0xb7c0, 0xde4e, + 0xb7bf, 0xde45, 0xde53, 0xde67, 0xb4fe, 0xbab0, 0xde56, 0xe26c, + 0xde58, 0xde66, 0xb7c6, 0xde4f, 0xb7ba, 0xb7ca, 0xbcf0, 0xde44, + 0xde5d, 0xde5c, 0xe2aa, 0xbaad, 0xe27d, 0xe2a4, 0xbaa2, 0xe26e, + 0xbaaf, 0xba77, 0xe26d, 0xe2b0, 0xbab1, 0xe271, 0xe2a3, 0xe273, + 0xe2b3, 0xe2af, 0xba75, 0xbaa1, 0xe653, 0xbaae, 0xba7d, 0xe26f, + 0xe2ae, 0xbaa3, 0xe2ab, 0xe2b8, 0xe275, 0xe27e, 0xe2b6, 0xe2ac, + 0xba7c, 0xe27c, 0xba76, 0xba74, 0xbaa8, 0xe27a, 0xe277, 0xe278, + 0xe2b2, 0xe2b7, 0xe2b5, 0xba7a, 0xe2b9, 0xba7e, 0xbaa7, 0xe270, + 0xe5fa, 0xe279, 0xba78, 0xbaac, 0xbaa9, 0xba7b, 0xe2a5, 0xe274, + 0xbaaa, 0xe2a7, 0xbaa4, 0xbaa6, 0xba73, 0xe2a9, 0xe2a1, 0xe272, + 0xbaa5, 0xe2b1, 0xe2b4, 0xe27b, 0xe2a8, 0xba79, 0xbcdf, 0xe2a6, + 0xe5f9, 0xe2ad, 0xe276, 0xe644, 0xe64e, 0xbce2, 0xe64d, 0xe659, + 0xbce4, 0xe64b, 0xe64f, 0xbcef, 0xe646, 0xbce7, 0xe652, 0xe9f0, + 0xbcf3, 0xbcf2, 0xe654, 0xe643, 0xe65e, 0xbced, 0xbce3, 0xe657, + 0xe65b, 0xe660, 0xe655, 0xe649, 0xbce6, 0xbce9, 0xbcf1, 0xbcec, + 0xe64c, 0xe2a2, 0xe648, 0xe65f, 0xbce8, 0xbceb, 0xe661, 0xbce0, + 0xe656, 0xe5fb, 0xe65c, 0xc0df, 0xe64a, 0xbce1, 0xe645, 0xbce5, + 0xe5fc, 0xbaab, 0xe641, 0xe65a, 0xe642, 0xe640, 0xbcea, 0xe658, + 0xe5fe, 0xe651, 0xe650, 0xe65d, 0xe647, 0xbcee, 0xe9f3, 0xbf49, + 0xbefe, 0xea40, 0xe9eb, 0xbf41, 0xe9f7, 0xbf48, 0xbf43, 0xe9f5, + 0xed4f, 0xe9fb, 0xea42, 0xe9fa, 0xe9e9, 0xe9f8, 0xea44, 0xea46, + 0xbefd, 0xea45, 0xbf44, 0xbf4a, 0xbf47, 0xe9fe, 0xbf46, 0xe9f9, + 0xe9ed, 0xe9f2, 0xe9fd, 0xbf45, 0xbf42, 0xbefc, 0xbf40, 0xe9f1, + 0xe5fd, 0xe9ec, 0xe9ef, 0xea41, 0xe9f4, 0xe9ea, 0xed4e, 0xea43, + 0xe9ee, 0xe9fc, 0xed51, 0xc0e3, 0xc0d7, 0xc0db, 0xed53, 0xed59, + 0xed57, 0xc0d9, 0xc0da, 0xc0e1, 0xed5a, 0xed52, 0xc0dc, 0xed56, + 0xed55, 0xed5b, 0xc0e2, 0xc0dd, 0xc0e0, 0xed54, 0xc0e4, 0xc0de, + 0xc0e5, 0xc0d8, 0xed58, 0xed50, 0xeff7, 0xc271, 0xeff4, 0xeff6, + 0xc26f, 0xeff2, 0xeff3, 0xefee, 0xe9f6, 0xefef, 0xc270, 0xefeb, + 0xc26d, 0xeff8, 0xc26e, 0xefec, 0xefed, 0xeff1, 0xc273, 0xc272, + 0xeff0, 0xc378, 0xf25f, 0xf265, 0xc379, 0xf25c, 0xc376, 0xc373, + 0xf267, 0xc377, 0xc374, 0xf25e, 0xf261, 0xf262, 0xf263, 0xf266, + 0xeff5, 0xf25d, 0xc375, 0xf264, 0xf268, 0xf260, 0xf45d, 0xc46a, + 0xf460, 0xc46b, 0xf468, 0xf45f, 0xf45c, 0xf45e, 0xf462, 0xf465, + 0xf464, 0xf467, 0xf45b, 0xc469, 0xf463, 0xf466, 0xf469, 0xf461, + 0xf5d3, 0xf5d4, 0xf5d8, 0xf5d9, 0xf5d6, 0xf5d7, 0xf5d5, 0xc4e9, + 0xc578, 0xf6eb, 0xf6e8, 0xf6e9, 0xf6ea, 0xc579, 0xf7e5, 0xf7e4, + 0xf8af, 0xc5f4, 0xf8ad, 0xf8b0, 0xf8ae, 0xf8f5, 0xc657, 0xc665, + 0xf9a3, 0xf96c, 0xf9a2, 0xf9d0, 0xf9d1, 0xa4f5, 0xa6c7, 0xca41, + 0xcb5e, 0xa85f, 0xa862, 0xcb5f, 0xa860, 0xa861, 0xcd58, 0xcd5a, + 0xcd55, 0xcd52, 0xcd54, 0xaaa4, 0xaaa2, 0xcd56, 0xaaa3, 0xcd53, + 0xcd50, 0xaaa1, 0xcd57, 0xcd51, 0xaaa5, 0xcd59, 0xcfaf, 0xcfb3, + 0xacb7, 0xcfb6, 0xacaf, 0xacb2, 0xacb4, 0xacb6, 0xacb3, 0xcfb2, + 0xcfb1, 0xacb1, 0xcfb4, 0xcfb5, 0xcfae, 0xacb5, 0xacb0, 0xcfb0, + 0xd277, 0xd278, 0xd279, 0xaf50, 0xaf4c, 0xd26e, 0xd276, 0xd27b, + 0xaf51, 0xd26c, 0xd272, 0xd26b, 0xd275, 0xd271, 0xaf4d, 0xaf4f, + 0xd27a, 0xd26a, 0xd26d, 0xd273, 0xd274, 0xd27c, 0xd270, 0xaf4e, + 0xb26d, 0xd64e, 0xd650, 0xd64c, 0xd658, 0xd64a, 0xd657, 0xb269, + 0xd648, 0xda5b, 0xd652, 0xb26c, 0xd653, 0xd656, 0xd65a, 0xd64f, + 0xd654, 0xb26a, 0xb26b, 0xd659, 0xd64d, 0xd649, 0xd65b, 0xd651, + 0xd655, 0xd64b, 0xb548, 0xb549, 0xda65, 0xb54f, 0xda59, 0xda62, + 0xda58, 0xb54c, 0xda60, 0xda5e, 0xda5f, 0xb54a, 0xda63, 0xda5c, + 0xda5a, 0xb54b, 0xda5d, 0xda61, 0xb54d, 0xda64, 0xde70, 0xde77, + 0xde79, 0xdea1, 0xb7da, 0xde6b, 0xb7d2, 0xde7a, 0xb7d7, 0xdea2, + 0xb7ce, 0xde7d, 0xde6d, 0xde7e, 0xde6c, 0xb7dc, 0xde78, 0xb7cf, + 0xdea3, 0xb7d4, 0xde71, 0xb7d9, 0xde7c, 0xde6f, 0xde76, 0xde72, + 0xde6e, 0xb7d1, 0xb7d8, 0xb7d6, 0xb7d3, 0xb7db, 0xb7d0, 0xde75, + 0xb7d5, 0xb54e, 0xde7b, 0xde73, 0xde74, 0xe2c1, 0xbab4, 0xe2bd, + 0xe2c3, 0xe2bf, 0xbab6, 0xe2be, 0xe2c2, 0xe2ba, 0xe2bc, 0xbab5, + 0xe2c0, 0xe2bb, 0xbab7, 0xbab2, 0xe2c4, 0xbab3, 0xe667, 0xe664, + 0xe670, 0xe66a, 0xe66c, 0xbcf4, 0xe666, 0xe66e, 0xe66d, 0xe66b, + 0xe671, 0xbcf7, 0xe668, 0xe66f, 0xbcf5, 0xe663, 0xe665, 0xbcf6, + 0xe662, 0xe672, 0xe669, 0xea4a, 0xbf51, 0xea55, 0xea53, 0xbf4b, + 0xea49, 0xea4c, 0xea4d, 0xea48, 0xbf55, 0xbf56, 0xea47, 0xea56, + 0xea51, 0xbf4f, 0xbf4c, 0xea50, 0xea4e, 0xbf52, 0xea52, 0xbf4d, + 0xbf4e, 0xea4f, 0xbf50, 0xea4b, 0xea54, 0xbf53, 0xea57, 0xea58, + 0xbf54, 0xc0e7, 0xc0ee, 0xed5c, 0xed62, 0xed60, 0xc0ea, 0xc0e9, + 0xc0e6, 0xed5e, 0xc0ec, 0xc0eb, 0xc0e8, 0xed61, 0xed5d, 0xed5f, + 0xc0ed, 0xc277, 0xeffb, 0xc274, 0xc275, 0xeffd, 0xc276, 0xeffa, + 0xeff9, 0xf26c, 0xeffc, 0xf26d, 0xc37a, 0xf26b, 0xf26a, 0xf269, + 0xc37b, 0xc46c, 0xf46a, 0xf46b, 0xf5dc, 0xf5db, 0xc4ea, 0xf5da, + 0xf6ec, 0xf6ed, 0xf7e6, 0xf8b1, 0xf8f6, 0xf9bc, 0xc679, 0xf9c6, + 0xa4f6, 0xaaa6, 0xaaa7, 0xacb8, 0xc0ef, 0xa4f7, 0xaaa8, 0xaf52, + 0xb7dd, 0xa4f8, 0xb26e, 0xbab8, 0xc962, 0xcfb7, 0xd27d, 0xe2c5, + 0xc0f0, 0xa4f9, 0xaaa9, 0xcfb8, 0xcfb9, 0xda66, 0xb550, 0xdea4, + 0xb7de, 0xe2c6, 0xbcf8, 0xc37c, 0xa4fa, 0xda67, 0xa4fb, 0xa6c9, + 0xca42, 0xa6c8, 0xa865, 0xa864, 0xa863, 0xcb60, 0xaaaa, 0xaaab, + 0xcd5b, 0xcfba, 0xcfbd, 0xacba, 0xcfbb, 0xacb9, 0xcfbc, 0xacbb, + 0xd2a2, 0xd2a1, 0xd27e, 0xaf53, 0xd65d, 0xd65e, 0xb26f, 0xd65c, + 0xd65f, 0xb552, 0xb270, 0xb551, 0xda6b, 0xda6a, 0xda68, 0xda69, + 0xda6c, 0xdea6, 0xdea5, 0xdea9, 0xdea8, 0xdea7, 0xbab9, 0xe2c9, + 0xe2c8, 0xbaba, 0xe2c7, 0xe673, 0xe674, 0xbcf9, 0xea59, 0xea5a, + 0xf272, 0xc37d, 0xf271, 0xf270, 0xf26e, 0xf26f, 0xc4eb, 0xf46c, + 0xf6ee, 0xf8f7, 0xa4fc, 0xc9a5, 0xa5c7, 0xc9a6, 0xca43, 0xca44, + 0xcb66, 0xcb62, 0xcb61, 0xaaac, 0xcb65, 0xa867, 0xcb63, 0xa866, + 0xcb67, 0xcb64, 0xcd5f, 0xcfbe, 0xcd5d, 0xcd64, 0xaaad, 0xaab0, + 0xcd65, 0xcd61, 0xcd62, 0xcd5c, 0xaaaf, 0xcd5e, 0xaaae, 0xcd63, + 0xcd60, 0xcfc2, 0xacbd, 0xacbe, 0xcfc5, 0xcfbf, 0xcfc4, 0xcfc0, + 0xacbc, 0xcfc3, 0xcfc1, 0xd2a8, 0xd2a5, 0xd2a7, 0xaf58, 0xaf57, + 0xaf55, 0xd2a4, 0xd2a9, 0xaf54, 0xaf56, 0xd2a6, 0xd667, 0xd2a3, + 0xd2aa, 0xd662, 0xd666, 0xd665, 0xda6e, 0xda79, 0xd668, 0xd663, + 0xda6d, 0xb274, 0xb273, 0xd661, 0xd664, 0xb275, 0xb272, 0xb271, + 0xd660, 0xd669, 0xda70, 0xda77, 0xb554, 0xda76, 0xda73, 0xb556, + 0xda75, 0xda6f, 0xda71, 0xda74, 0xda72, 0xb555, 0xda78, 0xb553, + 0xb7df, 0xdead, 0xdeac, 0xdeaa, 0xb7e2, 0xb7e1, 0xdeae, 0xdeab, + 0xe2ca, 0xbabb, 0xb7e0, 0xdeb0, 0xdeaf, 0xe2cd, 0xe2cb, 0xbcfa, + 0xbabc, 0xe2cc, 0xe676, 0xbcfb, 0xe675, 0xe67e, 0xe67d, 0xe67b, + 0xe67a, 0xe677, 0xe678, 0xe679, 0xe67c, 0xe6a1, 0xea5f, 0xea5c, + 0xea5d, 0xbf57, 0xea5b, 0xea61, 0xea60, 0xea5e, 0xed64, 0xed65, + 0xc0f1, 0xc0f2, 0xed63, 0xc279, 0xeffe, 0xc278, 0xc37e, 0xc3a1, + 0xc46d, 0xf46e, 0xf46d, 0xf5dd, 0xf6ef, 0xc57a, 0xf7e8, 0xf7e7, + 0xf7e9, 0xa5c8, 0xcfc6, 0xaf59, 0xb276, 0xd66a, 0xa5c9, 0xc9a7, + 0xa4fd, 0xca45, 0xcb6c, 0xcb6a, 0xcb6b, 0xcb68, 0xa868, 0xcb69, + 0xcd6d, 0xaab3, 0xcd6b, 0xcd67, 0xcd6a, 0xcd66, 0xaab5, 0xcd69, + 0xaab2, 0xaab1, 0xaab4, 0xcd6c, 0xcd68, 0xacc2, 0xacc5, 0xcfce, + 0xcfcd, 0xcfcc, 0xacbf, 0xcfd5, 0xcfcb, 0xacc1, 0xd2af, 0xcfd2, + 0xcfd0, 0xacc4, 0xcfc8, 0xcfd3, 0xcfca, 0xcfd4, 0xcfd1, 0xcfc9, + 0xacc0, 0xcfd6, 0xcfc7, 0xacc3, 0xd2b4, 0xd2ab, 0xd2b6, 0xd2ae, + 0xd2b9, 0xd2ba, 0xd2ac, 0xd2b8, 0xd2b5, 0xd2b3, 0xd2b7, 0xaf5f, + 0xaf5d, 0xd2b1, 0xd2ad, 0xd2b0, 0xd2bb, 0xd2b2, 0xaf5e, 0xcfcf, + 0xaf5a, 0xaf5c, 0xd678, 0xd66d, 0xd66b, 0xd66c, 0xd673, 0xd674, + 0xd670, 0xb27b, 0xd675, 0xd672, 0xd66f, 0xb279, 0xd66e, 0xb277, + 0xb27a, 0xd671, 0xd679, 0xaf5b, 0xb278, 0xd677, 0xd676, 0xb27c, + 0xda7e, 0xdaa1, 0xb560, 0xdaa7, 0xdaa9, 0xdaa2, 0xb55a, 0xdaa6, + 0xdaa5, 0xb55b, 0xb561, 0xb562, 0xdaa8, 0xb558, 0xda7d, 0xda7b, + 0xdaa3, 0xda7a, 0xb55f, 0xda7c, 0xdaa4, 0xdaaa, 0xb559, 0xb55e, + 0xb55c, 0xb55d, 0xb557, 0xb7e9, 0xdeb7, 0xb7e8, 0xdebb, 0xdeb1, + 0xdebc, 0xdeb2, 0xdeb3, 0xdebd, 0xdeba, 0xdeb8, 0xdeb9, 0xdeb5, + 0xdeb4, 0xdebe, 0xb7e5, 0xdeb6, 0xb7ea, 0xb7e4, 0xb7eb, 0xb7ec, + 0xb7e7, 0xb7e6, 0xe2ce, 0xbabe, 0xbabd, 0xe2d3, 0xbcfc, 0xbabf, + 0xbac1, 0xe2d4, 0xb7e3, 0xbac0, 0xe2d0, 0xe2d2, 0xe2cf, 0xe2d1, + 0xe6ab, 0xe6aa, 0xe6a7, 0xbd40, 0xea62, 0xbd41, 0xe6a6, 0xbcfe, + 0xe6a8, 0xe6a5, 0xe6a2, 0xe6a9, 0xe6a3, 0xe6a4, 0xbcfd, 0xed69, + 0xea66, 0xea65, 0xea67, 0xed66, 0xbf5a, 0xea63, 0xbf58, 0xbf5c, + 0xbf5b, 0xea64, 0xea68, 0xbf59, 0xed6d, 0xc0f5, 0xc27a, 0xc0f6, + 0xc0f3, 0xed6a, 0xed68, 0xed6b, 0xed6e, 0xc0f4, 0xed6c, 0xed67, + 0xf042, 0xf045, 0xf275, 0xf040, 0xf46f, 0xf046, 0xc3a2, 0xf044, + 0xc27b, 0xf041, 0xf043, 0xf047, 0xf276, 0xf274, 0xc3a3, 0xf273, + 0xc46e, 0xc4ed, 0xf6f1, 0xc4ec, 0xf6f3, 0xf6f0, 0xf6f2, 0xc5d0, + 0xf8b2, 0xa5ca, 0xcd6e, 0xd2bc, 0xd2bd, 0xb27d, 0xdebf, 0xbf5d, + 0xc3a4, 0xc57b, 0xf8b3, 0xa5cb, 0xcd6f, 0xa260, 0xcfd7, 0xcfd8, + 0xd2be, 0xd2bf, 0xb27e, 0xb2a1, 0xdaab, 0xdec2, 0xdec1, 0xdec0, + 0xe2d5, 0xe2d6, 0xe2d7, 0xbac2, 0xe6ad, 0xe6ac, 0xea69, 0xbf5e, + 0xbf5f, 0xed72, 0xed6f, 0xed70, 0xed71, 0xf049, 0xf048, 0xc27c, + 0xf277, 0xf5de, 0xa5cc, 0xacc6, 0xb2a2, 0xdec3, 0xa5cd, 0xd2c0, + 0xb2a3, 0xb563, 0xb564, 0xa5ce, 0xa5cf, 0xca46, 0xa86a, 0xa869, + 0xacc7, 0xcfd9, 0xdaac, 0xa5d0, 0xa5d1, 0xa5d2, 0xa5d3, 0xa86b, + 0xa86c, 0xcb6e, 0xcb6d, 0xaab6, 0xcd72, 0xcd70, 0xcd71, 0xcfda, + 0xcfdb, 0xaccb, 0xacc9, 0xacca, 0xacc8, 0xaf60, 0xaf64, 0xaf63, + 0xd2c1, 0xaf62, 0xaf61, 0xd2c2, 0xb2a6, 0xd67b, 0xd67a, 0xb2a4, + 0xb2a5, 0xb566, 0xb565, 0xdaae, 0xdaad, 0xb2a7, 0xb7ed, 0xdec5, + 0xb7ee, 0xdec4, 0xe2d8, 0xe6ae, 0xbd42, 0xea6a, 0xed73, 0xc3a6, + 0xc3a5, 0xc57c, 0xa5d4, 0xcd73, 0xb2a8, 0xe2d9, 0xbac3, 0xcb6f, + 0xcb70, 0xcd74, 0xaab8, 0xaab9, 0xaab7, 0xaccf, 0xacd0, 0xaccd, + 0xacce, 0xcfdc, 0xcfdd, 0xaccc, 0xd2c3, 0xaf68, 0xaf69, 0xb2ab, + 0xd2c9, 0xaf6e, 0xaf6c, 0xd2ca, 0xd2c5, 0xaf6b, 0xaf6a, 0xaf65, + 0xd2c8, 0xd2c7, 0xd2c4, 0xaf6d, 0xd2c6, 0xaf66, 0xaf67, 0xb2ac, + 0xd6a1, 0xd6a2, 0xb2ad, 0xd67c, 0xd67e, 0xd6a4, 0xd6a3, 0xd67d, + 0xb2a9, 0xb2aa, 0xdab6, 0xb56b, 0xb56a, 0xdab0, 0xb568, 0xdab3, + 0xb56c, 0xdab4, 0xb56d, 0xdab1, 0xb567, 0xb569, 0xdab5, 0xdab2, + 0xdaaf, 0xded2, 0xdec7, 0xb7f0, 0xb7f3, 0xb7f2, 0xb7f7, 0xb7f6, + 0xded3, 0xded1, 0xdeca, 0xdece, 0xdecd, 0xb7f4, 0xded0, 0xdecc, + 0xded4, 0xdecb, 0xb7f5, 0xb7ef, 0xb7f1, 0xdec9, 0xe2db, 0xbac7, + 0xe2df, 0xbac6, 0xe2dc, 0xbac5, 0xdec8, 0xdecf, 0xe2de, 0xbac8, + 0xe2e0, 0xe2dd, 0xe2da, 0xe6b1, 0xe6b5, 0xe6b7, 0xe6b3, 0xe6b2, + 0xe6b0, 0xbd45, 0xbd43, 0xbd48, 0xbd49, 0xe6b4, 0xbd46, 0xe6af, + 0xbd47, 0xbac4, 0xe6b6, 0xbd44, 0xea6c, 0xea6b, 0xea73, 0xea6d, + 0xea72, 0xea6f, 0xbf60, 0xea71, 0xbf61, 0xbf62, 0xea70, 0xea6e, + 0xc0f8, 0xed74, 0xc0f7, 0xed77, 0xed75, 0xed76, 0xc0f9, 0xf04d, + 0xc2a1, 0xf04e, 0xc27d, 0xf04f, 0xc27e, 0xf04c, 0xf050, 0xf04a, + 0xc3a7, 0xf278, 0xc3a8, 0xc46f, 0xf04b, 0xc470, 0xc4ee, 0xf5df, + 0xc57e, 0xf6f4, 0xc57d, 0xf7ea, 0xc5f5, 0xc5f6, 0xf9cc, 0xacd1, + 0xcfde, 0xb56e, 0xb56f, 0xa5d5, 0xa6ca, 0xca47, 0xcb71, 0xa86d, + 0xaaba, 0xacd2, 0xacd3, 0xacd4, 0xd6a6, 0xd2cb, 0xaf6f, 0xb2ae, + 0xd6a5, 0xdab8, 0xb571, 0xdab7, 0xb570, 0xded5, 0xbd4a, 0xe6bb, + 0xe6b8, 0xe6b9, 0xe6ba, 0xed78, 0xf051, 0xf471, 0xf470, 0xf6f5, + 0xa5d6, 0xcd75, 0xaf70, 0xb572, 0xded6, 0xe2e1, 0xbd4b, 0xea74, + 0xf052, 0xf472, 0xa5d7, 0xaabb, 0xacd7, 0xcfdf, 0xacd8, 0xacd6, + 0xacd5, 0xd2cc, 0xaf71, 0xaf72, 0xaf73, 0xb2b0, 0xd6a7, 0xb2af, + 0xdab9, 0xb2b1, 0xb573, 0xded7, 0xb7f8, 0xb7f9, 0xbac9, 0xbaca, + 0xbd4c, 0xbf64, 0xea75, 0xbf63, 0xed79, 0xc0fa, 0xf053, 0xf473, + 0xa5d8, 0xa86e, 0xcd78, 0xcd77, 0xaabc, 0xcd76, 0xaabd, 0xcd79, + 0xcfe5, 0xacdb, 0xacda, 0xcfe7, 0xcfe6, 0xacdf, 0xacde, 0xacd9, + 0xcfe1, 0xcfe2, 0xcfe3, 0xace0, 0xcfe0, 0xacdc, 0xcfe4, 0xacdd, + 0xd2cf, 0xd2d3, 0xd2d1, 0xd2d0, 0xd2d4, 0xd2d5, 0xd2d6, 0xd2ce, + 0xd2cd, 0xaf75, 0xaf76, 0xd2d7, 0xd2d2, 0xd6b0, 0xd2d8, 0xaf77, + 0xaf74, 0xd6aa, 0xd6a9, 0xd6ab, 0xd6ac, 0xd6ae, 0xd6ad, 0xd6b2, + 0xb2b5, 0xb2b2, 0xb2b6, 0xd6a8, 0xb2b7, 0xd6b1, 0xb2b4, 0xd6af, + 0xb2b3, 0xdabc, 0xdabe, 0xdaba, 0xdabb, 0xdabf, 0xdac1, 0xdac2, + 0xdabd, 0xdac0, 0xb574, 0xdedb, 0xdee0, 0xded8, 0xdedc, 0xdee1, + 0xdedd, 0xb7fa, 0xb843, 0xb7fd, 0xded9, 0xdeda, 0xbace, 0xb846, + 0xb7fe, 0xb844, 0xb7fc, 0xdedf, 0xb845, 0xdede, 0xb841, 0xb7fb, + 0xb842, 0xdee2, 0xe2e6, 0xe2e8, 0xb840, 0xe2e3, 0xbacc, 0xe2e9, + 0xbacd, 0xe2e7, 0xe2e2, 0xe2e5, 0xe2ea, 0xbacb, 0xe2e4, 0xbd4e, + 0xe6bf, 0xe6be, 0xbd51, 0xbd4f, 0xe6bc, 0xbd4d, 0xe6bd, 0xbd50, + 0xea7d, 0xeaa1, 0xea7e, 0xea76, 0xea7a, 0xea79, 0xea77, 0xbf66, + 0xbf67, 0xbf65, 0xea78, 0xea7b, 0xea7c, 0xbf68, 0xc140, 0xeda3, + 0xc0fc, 0xed7b, 0xc0fe, 0xc141, 0xc0fd, 0xeda2, 0xed7c, 0xc0fb, + 0xeda1, 0xed7a, 0xed7e, 0xed7d, 0xf055, 0xc2a4, 0xc2a5, 0xc2a2, + 0xc2a3, 0xf054, 0xf27b, 0xc3a9, 0xf279, 0xf27a, 0xf474, 0xf477, + 0xf475, 0xf476, 0xf5e0, 0xc4ef, 0xf7eb, 0xf8b4, 0xc5f7, 0xf8f8, + 0xf8f9, 0xc666, 0xa5d9, 0xace1, 0xdac3, 0xdee3, 0xa5da, 0xa86f, + 0xaabe, 0xcfe8, 0xcfe9, 0xaf78, 0xdac4, 0xb575, 0xb847, 0xc142, + 0xeda4, 0xf27c, 0xf478, 0xa5db, 0xcda1, 0xcd7a, 0xcd7c, 0xcd7e, + 0xcd7d, 0xcd7b, 0xaabf, 0xace2, 0xcff2, 0xcfed, 0xcfea, 0xcff1, + 0xace4, 0xace5, 0xcff0, 0xcfef, 0xcfee, 0xcfeb, 0xcfec, 0xcff3, + 0xace3, 0xaf7c, 0xafa4, 0xafa3, 0xd2e1, 0xd2db, 0xd2d9, 0xafa1, + 0xd6b9, 0xaf7a, 0xd2de, 0xd2e2, 0xd2e4, 0xd2e0, 0xd2da, 0xafa2, + 0xd2df, 0xd2dd, 0xaf79, 0xd2e5, 0xafa5, 0xd2e3, 0xaf7d, 0xd2dc, + 0xaf7e, 0xaf7b, 0xb2b9, 0xd6ba, 0xd6b3, 0xd6b5, 0xd6b7, 0xd6b8, + 0xd6b6, 0xb2ba, 0xd6bb, 0xd6b4, 0xdac8, 0xb576, 0xdad0, 0xdac5, + 0xdad1, 0xdac6, 0xdac7, 0xdacf, 0xdace, 0xdacb, 0xb2b8, 0xb577, + 0xdac9, 0xdacc, 0xb578, 0xdacd, 0xdaca, 0xdeee, 0xdef2, 0xb84e, + 0xe2f0, 0xb851, 0xdef0, 0xdeed, 0xdee8, 0xdeea, 0xdeeb, 0xdee4, + 0xb84d, 0xb84c, 0xb848, 0xdee7, 0xb84f, 0xb850, 0xdee6, 0xdee9, + 0xdef1, 0xb84a, 0xb84b, 0xdeef, 0xdee5, 0xe2f2, 0xbad0, 0xe2f4, + 0xdeec, 0xe2f6, 0xbad4, 0xe2f7, 0xe2f3, 0xbad1, 0xe2ef, 0xbad3, + 0xe2ec, 0xe2f1, 0xe2f5, 0xe2ee, 0xb849, 0xe2eb, 0xbad2, 0xe2ed, + 0xbd54, 0xe6c1, 0xbd58, 0xbd56, 0xbacf, 0xe6c8, 0xe6c9, 0xbd53, + 0xe6c7, 0xe6ca, 0xbd55, 0xbd52, 0xe6c3, 0xe6c0, 0xe6c5, 0xe6c2, + 0xbd59, 0xe6c4, 0xe6c6, 0xbd57, 0xbf6a, 0xeaa8, 0xeaa2, 0xeaa6, + 0xeaac, 0xeaad, 0xeaa9, 0xeaaa, 0xeaa7, 0xeaa4, 0xbf6c, 0xbf69, + 0xeaa3, 0xeaa5, 0xbf6b, 0xeaab, 0xc146, 0xedaa, 0xeda5, 0xc145, + 0xc143, 0xedac, 0xc144, 0xeda8, 0xeda9, 0xeda6, 0xedad, 0xf056, + 0xc147, 0xeda7, 0xedae, 0xedab, 0xf05a, 0xf057, 0xc2a6, 0xf05b, + 0xf05d, 0xf05c, 0xf058, 0xf059, 0xf2a3, 0xc3aa, 0xf27e, 0xf2a2, + 0xf27d, 0xf2a4, 0xf2a1, 0xf47a, 0xf47d, 0xf479, 0xc471, 0xf47b, + 0xf47c, 0xf47e, 0xc472, 0xc474, 0xc473, 0xf5e1, 0xf5e3, 0xf5e2, + 0xf6f6, 0xf8b5, 0xf8fa, 0xa5dc, 0xcb72, 0xaac0, 0xcda3, 0xaac1, + 0xaac2, 0xcda2, 0xcff8, 0xcff7, 0xace6, 0xace9, 0xace8, 0xace7, + 0xcff4, 0xcff6, 0xcff5, 0xd2e8, 0xafa7, 0xd2ec, 0xd2eb, 0xd2ea, + 0xd2e6, 0xafa6, 0xafaa, 0xafad, 0xafae, 0xd2e7, 0xd2e9, 0xafac, + 0xafab, 0xafa9, 0xafa8, 0xd6c2, 0xd6c0, 0xd6bc, 0xb2bb, 0xd6bd, + 0xb2bc, 0xd6be, 0xd6bf, 0xd6c1, 0xb2bd, 0xdad5, 0xdad4, 0xdad3, + 0xdad2, 0xdef6, 0xb852, 0xdef3, 0xdef5, 0xb853, 0xb854, 0xdef4, + 0xe341, 0xe2f9, 0xe2fa, 0xbad7, 0xbad5, 0xbad6, 0xe343, 0xe342, + 0xe2fe, 0xe2fd, 0xe2fc, 0xe2fb, 0xe340, 0xe2f8, 0xe6cb, 0xe6d0, + 0xe6ce, 0xe6cd, 0xe6cc, 0xe6cf, 0xeaae, 0xbf6d, 0xc148, 0xedb0, + 0xc149, 0xedaf, 0xf05f, 0xf05e, 0xc2a7, 0xf2a5, 0xc3ab, 0xf4a1, + 0xc5a1, 0xf6f7, 0xf8b7, 0xf8b6, 0xc9a8, 0xacea, 0xaceb, 0xd6c3, + 0xb856, 0xa5dd, 0xa872, 0xa871, 0xa870, 0xcda4, 0xaac4, 0xaac3, + 0xacee, 0xcffa, 0xcffd, 0xcffb, 0xacec, 0xaced, 0xcff9, 0xcffc, + 0xafb5, 0xd2f3, 0xd2f5, 0xd2f4, 0xafb2, 0xd2ef, 0xafb0, 0xafaf, + 0xafb3, 0xafb1, 0xafb4, 0xd2f2, 0xd2ed, 0xd2ee, 0xd2f1, 0xd2f0, + 0xd6c6, 0xd6c7, 0xd6c5, 0xd6c4, 0xb2be, 0xb57d, 0xdad6, 0xdad8, + 0xdada, 0xb57c, 0xb57a, 0xdad7, 0xb57b, 0xdad9, 0xb579, 0xdf41, + 0xdef7, 0xdefa, 0xdefe, 0xb85a, 0xdefc, 0xdefb, 0xdef8, 0xdef9, + 0xb858, 0xdf40, 0xb857, 0xb85c, 0xb85b, 0xb859, 0xdefd, 0xe349, + 0xe348, 0xe344, 0xbad8, 0xe347, 0xe346, 0xbad9, 0xbd5e, 0xe6d2, + 0xbd5f, 0xbd5b, 0xbd5d, 0xbd5a, 0xbd5c, 0xeaaf, 0xbf70, 0xeab1, + 0xeab0, 0xe345, 0xbf72, 0xbf71, 0xbf6e, 0xbf6f, 0xedb5, 0xedb3, + 0xc14a, 0xedb4, 0xedb6, 0xedb2, 0xedb1, 0xf060, 0xc2aa, 0xc2a8, + 0xc2a9, 0xf2a6, 0xf2a7, 0xc3ad, 0xc3ac, 0xf4a3, 0xf4a4, 0xf4a2, + 0xf6f8, 0xf6f9, 0xa5de, 0xca48, 0xa873, 0xcda5, 0xaac6, 0xaac5, + 0xcda6, 0xd040, 0xacef, 0xcffe, 0xacf0, 0xafb6, 0xd2f8, 0xd2f6, + 0xd2fc, 0xafb7, 0xd2f7, 0xd2fb, 0xd2f9, 0xd2fa, 0xd6c8, 0xd6ca, + 0xb2bf, 0xd6c9, 0xb2c0, 0xb5a2, 0xb5a1, 0xb57e, 0xdadb, 0xdf44, + 0xb85d, 0xb85e, 0xdf43, 0xdf42, 0xe34a, 0xbadb, 0xbada, 0xe34b, + 0xe34c, 0xbd61, 0xbd60, 0xeab5, 0xe6d3, 0xe6d5, 0xe6d4, 0xeab4, + 0xeab2, 0xeab6, 0xeab3, 0xbf73, 0xedb7, 0xc14b, 0xedb8, 0xedb9, + 0xc2ab, 0xc2ac, 0xc475, 0xc5d1, 0xa5df, 0xd041, 0xd2fd, 0xafb8, + 0xb3ba, 0xb3b9, 0xb5a4, 0xdadd, 0xb5a3, 0xdadc, 0xdf45, 0xbadc, + 0xe34d, 0xbadd, 0xc476, 0xf4a5, 0xa6cb, 0xaac7, 0xcda7, 0xacf2, + 0xacf1, 0xd042, 0xd043, 0xd340, 0xd342, 0xafb9, 0xd344, 0xd347, + 0xd345, 0xd346, 0xd343, 0xd2fe, 0xafba, 0xd348, 0xd341, 0xd6d3, + 0xb2c6, 0xd6dc, 0xb2c3, 0xd6d5, 0xb2c7, 0xb2c1, 0xd6d0, 0xd6dd, + 0xd6d1, 0xd6ce, 0xb2c5, 0xb2c2, 0xd6d4, 0xd6d7, 0xb2c4, 0xd6d8, + 0xb2c8, 0xd6d9, 0xd6cf, 0xd6d6, 0xd6da, 0xd6d2, 0xd6cd, 0xd6cb, + 0xd6db, 0xdadf, 0xdae4, 0xdae0, 0xdae6, 0xb5a7, 0xd6cc, 0xdae1, + 0xb5a5, 0xdade, 0xb5ac, 0xdae2, 0xb5ab, 0xdae3, 0xb5ad, 0xb5a8, + 0xb5ae, 0xb5a9, 0xb5aa, 0xb5a6, 0xdae5, 0xb861, 0xdf50, 0xdf53, + 0xdf47, 0xdf4c, 0xdf46, 0xb863, 0xdf4a, 0xdf48, 0xb862, 0xdf4f, + 0xdf4e, 0xdf4b, 0xdf4d, 0xdf49, 0xbae1, 0xdf52, 0xb85f, 0xdf51, + 0xe35d, 0xbae8, 0xe358, 0xbae7, 0xe34e, 0xe350, 0xbae0, 0xe355, + 0xe354, 0xe357, 0xbae5, 0xe352, 0xe351, 0xbae4, 0xbadf, 0xe353, + 0xbae2, 0xe359, 0xe35b, 0xe356, 0xe34f, 0xbae3, 0xbd69, 0xbade, + 0xe35c, 0xe6d9, 0xbd62, 0xe6db, 0xbd63, 0xbd65, 0xe6de, 0xe6d6, + 0xbae6, 0xe6dc, 0xe6d8, 0xb860, 0xbd68, 0xbd64, 0xbd66, 0xbd67, + 0xbf76, 0xe6dd, 0xe6d7, 0xbd6a, 0xe6da, 0xeac0, 0xeabb, 0xeac5, + 0xbf74, 0xeabd, 0xbf78, 0xeac3, 0xeaba, 0xeab7, 0xeac6, 0xc151, + 0xbf79, 0xeac2, 0xeab8, 0xbf77, 0xeabc, 0xbf7b, 0xeab9, 0xeabe, + 0xbf7a, 0xeac1, 0xeac4, 0xedcb, 0xedcc, 0xedbc, 0xedc3, 0xedc1, + 0xc14f, 0xedc8, 0xeabf, 0xedbf, 0xedc9, 0xc14e, 0xedbe, 0xedbd, + 0xedc7, 0xedc4, 0xedc6, 0xedba, 0xedca, 0xc14c, 0xedc5, 0xedce, + 0xedc2, 0xc150, 0xc14d, 0xedc0, 0xedbb, 0xedcd, 0xbf75, 0xf063, + 0xf061, 0xf067, 0xc2b0, 0xf065, 0xf064, 0xc2b2, 0xf06a, 0xc2b1, + 0xf06b, 0xf068, 0xc2ae, 0xf069, 0xf062, 0xc2af, 0xc2ad, 0xf2ab, + 0xf066, 0xf06c, 0xf2a8, 0xc3b2, 0xc3b0, 0xf2aa, 0xf2ac, 0xf2a9, + 0xc3b1, 0xc3ae, 0xc3af, 0xc3b3, 0xc478, 0xf4aa, 0xf4a9, 0xf4a7, + 0xf4a6, 0xf4a8, 0xc477, 0xc479, 0xc4f0, 0xf5e5, 0xf5e4, 0xf6fa, + 0xf6fc, 0xf6fe, 0xf6fd, 0xf6fb, 0xc5a3, 0xc5a2, 0xc5d3, 0xc5d2, + 0xc5d4, 0xf7ed, 0xf7ec, 0xf8fb, 0xf8b8, 0xf8fc, 0xc658, 0xc659, + 0xf96d, 0xc67e, 0xa6cc, 0xcda8, 0xd045, 0xd046, 0xd044, 0xacf3, + 0xd047, 0xd048, 0xd049, 0xd349, 0xd34f, 0xd34d, 0xafbb, 0xd34b, + 0xd34c, 0xd34e, 0xd34a, 0xb2c9, 0xd6de, 0xb2cb, 0xd6e0, 0xb2ca, + 0xd6df, 0xdae8, 0xb5af, 0xdaea, 0xdae7, 0xd6e1, 0xb5b0, 0xdae9, + 0xdf56, 0xb864, 0xdf54, 0xb865, 0xdf55, 0xb866, 0xbae9, 0xe361, + 0xe35e, 0xe360, 0xbaea, 0xbaeb, 0xe35f, 0xe6df, 0xe6e0, 0xbd6b, + 0xe6e2, 0xe6e1, 0xa261, 0xeaca, 0xeacb, 0xeac7, 0xeac8, 0xbf7c, + 0xbf7d, 0xeac9, 0xc157, 0xc153, 0xc158, 0xc154, 0xc156, 0xc152, + 0xc155, 0xc2b3, 0xedcf, 0xf2ae, 0xf2ad, 0xf4ab, 0xc47a, 0xc47b, + 0xf741, 0xf5e6, 0xf740, 0xf8fd, 0xf9a4, 0xa6cd, 0xa874, 0xcda9, + 0xaac8, 0xacf6, 0xd04c, 0xacf4, 0xd04a, 0xacf9, 0xacf5, 0xacfa, + 0xacf8, 0xd04b, 0xacf7, 0xafbf, 0xafbe, 0xd35a, 0xafc7, 0xd353, + 0xd359, 0xafc3, 0xd352, 0xd358, 0xd356, 0xafc2, 0xafc4, 0xd355, + 0xafbd, 0xd354, 0xafc8, 0xafc5, 0xafc9, 0xafc6, 0xd351, 0xd350, + 0xd357, 0xafc0, 0xafbc, 0xafc1, 0xd6f0, 0xd6e9, 0xb5b5, 0xd6e8, + 0xb2cf, 0xb2d6, 0xb2d3, 0xb2d9, 0xb2d8, 0xb2d4, 0xd6e2, 0xd6e5, + 0xd6e4, 0xb2d0, 0xd6e6, 0xd6ef, 0xb2d1, 0xd6e3, 0xd6ec, 0xd6ed, + 0xb2d2, 0xd6ea, 0xb2d7, 0xb2cd, 0xb2d5, 0xd6e7, 0xb2cc, 0xd6eb, + 0xd6ee, 0xdafb, 0xdaf2, 0xb5b2, 0xdaf9, 0xdaf6, 0xdaee, 0xdaf7, + 0xb5b4, 0xdaef, 0xdaeb, 0xb86c, 0xdaf4, 0xb5b1, 0xdafa, 0xb5b8, + 0xb5ba, 0xdaed, 0xb5b9, 0xdaf0, 0xb5b3, 0xdaf8, 0xdaf1, 0xdaf5, + 0xdaf3, 0xb5b6, 0xdaec, 0xb5bb, 0xb2ce, 0xb5b7, 0xb5bc, 0xb868, + 0xdf5d, 0xdf5f, 0xdf61, 0xdf65, 0xdf5b, 0xdf59, 0xb86a, 0xdf60, + 0xdf64, 0xdf5c, 0xdf58, 0xdf57, 0xdf62, 0xdf5a, 0xdf5e, 0xb86b, + 0xb869, 0xdf66, 0xb867, 0xdf63, 0xe372, 0xbaee, 0xe36a, 0xbd78, + 0xe374, 0xbaf1, 0xe378, 0xbaf7, 0xe365, 0xe375, 0xe362, 0xe377, + 0xe366, 0xbafe, 0xbafb, 0xe376, 0xe370, 0xbaed, 0xbaf5, 0xbaf4, + 0xbaf3, 0xbaf9, 0xe363, 0xbafa, 0xe371, 0xbaf6, 0xbaec, 0xe373, + 0xbaef, 0xbaf0, 0xbaf8, 0xe368, 0xe367, 0xe364, 0xe36c, 0xe369, + 0xe36d, 0xbafd, 0xe379, 0xbaf2, 0xe36e, 0xe36f, 0xe36b, 0xbafc, + 0xe6e7, 0xbd70, 0xbd79, 0xbd75, 0xe6e4, 0xbd72, 0xbd76, 0xe6f0, + 0xbd6c, 0xe6e8, 0xbd74, 0xe6eb, 0xe6e6, 0xbd73, 0xbd77, 0xe6e5, + 0xbd71, 0xe6ef, 0xbd6e, 0xe6ee, 0xe6ed, 0xbd7a, 0xe572, 0xbd6d, + 0xe6ec, 0xe6e3, 0xbd7b, 0xe6ea, 0xbd6f, 0xe6e9, 0xbfa2, 0xbfa7, + 0xbf7e, 0xead8, 0xeacf, 0xeadb, 0xead3, 0xead9, 0xbfa8, 0xbfa1, + 0xeacc, 0xead2, 0xeadc, 0xead5, 0xeada, 0xeace, 0xead6, 0xbfa3, + 0xead4, 0xbfa6, 0xbfa5, 0xead0, 0xead1, 0xeacd, 0xead7, 0xbfa4, + 0xeade, 0xeadd, 0xedda, 0xedd6, 0xc15f, 0xedd0, 0xc159, 0xc169, + 0xeddc, 0xc161, 0xc15d, 0xedd3, 0xc164, 0xc167, 0xedde, 0xc15c, + 0xedd5, 0xc165, 0xede0, 0xeddd, 0xedd1, 0xc160, 0xc15a, 0xc168, + 0xedd8, 0xc163, 0xedd2, 0xc15e, 0xeddf, 0xc162, 0xc15b, 0xedd9, + 0xc166, 0xedd7, 0xeddb, 0xf06e, 0xf074, 0xc2b9, 0xf077, 0xc2b4, + 0xc2b5, 0xf06f, 0xf076, 0xf071, 0xc2ba, 0xc2b7, 0xf06d, 0xc2b6, + 0xf073, 0xf075, 0xc2b8, 0xf072, 0xf070, 0xf2b8, 0xc3b7, 0xc3b8, + 0xc3b4, 0xc3b5, 0xf2b4, 0xf2b2, 0xf2b6, 0xc3ba, 0xf2b7, 0xf2b0, + 0xf2af, 0xf2b3, 0xf2b1, 0xc3b6, 0xf2b5, 0xf4ac, 0xc47e, 0xc47d, + 0xf4ad, 0xf4af, 0xf4ae, 0xc4a1, 0xf5eb, 0xf5e8, 0xf5e9, 0xf5e7, + 0xf5ea, 0xc4f2, 0xf5ec, 0xc4f1, 0xf742, 0xc5d5, 0xc5d7, 0xf7ee, + 0xc5d6, 0xf8b9, 0xf940, 0xf942, 0xf8fe, 0xf941, 0xc66c, 0xa6ce, + 0xacfb, 0xd26f, 0xafca, 0xb2da, 0xdafc, 0xdafd, 0xeadf, 0xc16a, + 0xede1, 0xc2bb, 0xf2ba, 0xf2b9, 0xc4a2, 0xf5ed, 0xf743, 0xc5f8, + 0xca49, 0xaac9, 0xa875, 0xd04d, 0xd360, 0xd35b, 0xd35f, 0xd35d, + 0xafcb, 0xd35e, 0xd35c, 0xd6f1, 0xdafe, 0xdb40, 0xdf69, 0xdf6a, + 0xb86e, 0xb86f, 0xdf68, 0xdf6b, 0xdf67, 0xb86d, 0xbb40, 0xb870, + 0xe37a, 0xbd7c, 0xe6f1, 0xbd7d, 0xbfa9, 0xeae2, 0xeae0, 0xeae1, + 0xede4, 0xede3, 0xede2, 0xf2bb, 0xc3b9, 0xf2bc, 0xf744, 0xc5f9, + 0xf8ba, 0xa6cf, 0xaacb, 0xaaca, 0xd04f, 0xacfc, 0xd04e, 0xd362, + 0xafcc, 0xd6f2, 0xd361, 0xb2dc, 0xd6f5, 0xd6f3, 0xd6f4, 0xb2db, + 0xdb42, 0xdb43, 0xdb41, 0xb873, 0xdf6d, 0xdf6c, 0xdf6e, 0xb872, + 0xb871, 0xe6f2, 0xe6f4, 0xbd7e, 0xe6f3, 0xeae3, 0xbfaa, 0xf079, + 0xf078, 0xc3bb, 0xf2bd, 0xc3bd, 0xc3bc, 0xf4b0, 0xf5ee, 0xc4f3, + 0xa6d0, 0xd050, 0xacfd, 0xd365, 0xafce, 0xd364, 0xd363, 0xafcd, + 0xd6fb, 0xd6fd, 0xd6f6, 0xd6f7, 0xb2dd, 0xd6f8, 0xb2de, 0xd6fc, + 0xd6f9, 0xd6fa, 0xb2df, 0xb5be, 0xb5bf, 0xdb44, 0xdf6f, 0xdf70, + 0xe37e, 0xbb43, 0xbb41, 0xbb42, 0xe37b, 0xe37c, 0xe37d, 0xe6f9, + 0xe6fa, 0xbda1, 0xe6f7, 0xe6f6, 0xe6f8, 0xe6f5, 0xbfad, 0xeae4, + 0xbfab, 0xbfac, 0xede6, 0xc16b, 0xede5, 0xefa8, 0xf07a, 0xf07b, + 0xc2bc, 0xc2bd, 0xc16c, 0xf2be, 0xf2bf, 0xf4b1, 0xc4a3, 0xa6d1, + 0xa6d2, 0xacfe, 0xaacc, 0xafcf, 0xd051, 0xb5c0, 0xa6d3, 0xad41, + 0xd052, 0xd053, 0xad40, 0xad42, 0xa6d4, 0xd054, 0xafd1, 0xd366, + 0xafd3, 0xafd0, 0xafd2, 0xd741, 0xb2e0, 0xd740, 0xd6fe, 0xdf71, + 0xe3a1, 0xbda2, 0xbfae, 0xeae6, 0xeae5, 0xede7, 0xf5ef, 0xa6d5, + 0xcb73, 0xcdaa, 0xad43, 0xd055, 0xd368, 0xafd4, 0xd367, 0xafd5, + 0xd743, 0xb2e2, 0xd742, 0xd744, 0xb2e1, 0xdb46, 0xdb47, 0xdb45, + 0xb5c1, 0xb874, 0xb875, 0xbb45, 0xe3a3, 0xe3a2, 0xbb44, 0xe6fb, + 0xe6fc, 0xeae7, 0xc170, 0xc16f, 0xc16d, 0xc16e, 0xc171, 0xf07c, + 0xc2bf, 0xc2be, 0xf2c0, 0xf4b2, 0xc5a5, 0xc5a4, 0xa6d6, 0xd1fb, + 0xb877, 0xb5c2, 0xb876, 0xbb46, 0xa6d7, 0xc9a9, 0xa6d8, 0xa6d9, + 0xcdab, 0xcb76, 0xcb77, 0xa877, 0xcb74, 0xa876, 0xa879, 0xcb75, + 0xa87b, 0xa87a, 0xcb78, 0xa878, 0xaad1, 0xaacf, 0xcdad, 0xaace, + 0xaad3, 0xaad5, 0xaad2, 0xcdb0, 0xcdac, 0xaad6, 0xaad0, 0xa87c, + 0xaad4, 0xcdaf, 0xcdae, 0xaacd, 0xd05b, 0xad47, 0xad48, 0xd05d, + 0xd057, 0xd05a, 0xd063, 0xd061, 0xad49, 0xd067, 0xad4c, 0xd064, + 0xd05c, 0xd059, 0xdb49, 0xd062, 0xad44, 0xd065, 0xd056, 0xd05f, + 0xad46, 0xad4b, 0xd060, 0xad4f, 0xad4d, 0xd058, 0xad4a, 0xd05e, + 0xad4e, 0xad45, 0xd066, 0xafda, 0xafe3, 0xafd8, 0xafd6, 0xd36a, + 0xafde, 0xafdb, 0xd36c, 0xafdd, 0xd36b, 0xd369, 0xd36e, 0xafe2, + 0xafe0, 0xdb48, 0xd36f, 0xd36d, 0xafd7, 0xafd9, 0xafdc, 0xafdf, + 0xafe1, 0xd74e, 0xb2e4, 0xd745, 0xd747, 0xd748, 0xd750, 0xd74c, + 0xd74a, 0xd74d, 0xd751, 0xb2e5, 0xb2e9, 0xd746, 0xd74f, 0xb2e7, + 0xb2e6, 0xd74b, 0xd749, 0xb2e3, 0xb2e8, 0xb5c8, 0xdb51, 0xdb4f, + 0xb5ca, 0xdb4a, 0xdfa1, 0xb5c9, 0xdb4e, 0xdb4b, 0xb5c5, 0xb5cb, + 0xdb50, 0xb5c7, 0xdb4d, 0xbb47, 0xb5c6, 0xdb4c, 0xb5cc, 0xb5c4, + 0xb5c3, 0xdf77, 0xdf75, 0xdf7b, 0xdf73, 0xdfa2, 0xdf78, 0xdf72, + 0xb87b, 0xb8a3, 0xdf7d, 0xdf76, 0xb87e, 0xb87c, 0xdf7e, 0xb879, + 0xb878, 0xdf79, 0xb87d, 0xb5cd, 0xdf7c, 0xdf74, 0xb87a, 0xb8a1, + 0xb8a2, 0xbb4c, 0xbb48, 0xbb4d, 0xe3a6, 0xe3a5, 0xe3a7, 0xbb4a, + 0xe3a4, 0xbb4b, 0xe3aa, 0xe3a9, 0xe3a8, 0xbb49, 0xe741, 0xe744, + 0xbda8, 0xe743, 0xbda7, 0xbda3, 0xbda4, 0xbda5, 0xe740, 0xe6fe, + 0xbda6, 0xe742, 0xe6fd, 0xeae9, 0xeaf3, 0xbfb1, 0xbfb0, 0xeaed, + 0xeaef, 0xeaea, 0xeaee, 0xeae8, 0xeaf1, 0xbfaf, 0xeaf0, 0xeaec, + 0xeaf2, 0xeaeb, 0xc174, 0xede8, 0xedee, 0xc178, 0xc17a, 0xc177, + 0xc176, 0xc175, 0xc173, 0xede9, 0xedec, 0xc172, 0xeded, 0xc179, + 0xedeb, 0xedea, 0xc2c0, 0xc2c1, 0xf0a1, 0xf07d, 0xf07e, 0xf2c2, + 0xf2c1, 0xc3be, 0xf4b4, 0xc4a4, 0xf4b3, 0xf5f0, 0xf745, 0xc5a6, + 0xf943, 0xf944, 0xc5d8, 0xa6da, 0xaad7, 0xdb52, 0xbb4e, 0xc17b, + 0xedef, 0xa6db, 0xafe5, 0xafe4, 0xdb53, 0xeaf4, 0xa6dc, 0xad50, + 0xdb54, 0xdb55, 0xdb56, 0xbb4f, 0xbfb2, 0xa6dd, 0xaad8, 0xd068, + 0xafe6, 0xd370, 0xb2ea, 0xdb57, 0xb8a4, 0xbb50, 0xbfb3, 0xc17c, + 0xc2c2, 0xf4b5, 0xa6de, 0xaad9, 0xafe7, 0xd752, 0xb5ce, 0xbb51, + 0xe3ab, 0xe745, 0xa6df, 0xb5cf, 0xdfa3, 0xbb52, 0xa6e0, 0xcdb1, + 0xd069, 0xad51, 0xd372, 0xafea, 0xafe8, 0xafe9, 0xafeb, 0xd371, + 0xd757, 0xd754, 0xd756, 0xb2eb, 0xb2ed, 0xb2ec, 0xd753, 0xb2ee, + 0xd755, 0xdb58, 0xdb59, 0xdb5a, 0xdfa6, 0xdfa7, 0xdfa5, 0xdfa8, + 0xb8a5, 0xdfa4, 0xbb53, 0xe74a, 0xe746, 0xe749, 0xe74b, 0xe748, + 0xe747, 0xeaf5, 0xeaf6, 0xeaf7, 0xbfb4, 0xbfb5, 0xedf1, 0xedf0, + 0xedf2, 0xf0a3, 0xf0a2, 0xf2c4, 0xf2c5, 0xf2c3, 0xc4a5, 0xf4b6, + 0xf4b7, 0xf746, 0xf7ef, 0xf8bb, 0xa6e1, 0xa87d, 0xc17d, 0xa6e2, + 0xd758, 0xdb5b, 0xc641, 0xca4a, 0xca4b, 0xca4d, 0xa6e3, 0xca4e, + 0xca4c, 0xcba2, 0xcba3, 0xcb7b, 0xcba1, 0xa8a1, 0xa8a2, 0xcb7c, + 0xcb7a, 0xcb79, 0xcb7d, 0xa87e, 0xcb7e, 0xd06a, 0xcdb6, 0xaadc, + 0xcdb5, 0xcdb7, 0xaadb, 0xcdbc, 0xaadf, 0xcdb2, 0xcdc0, 0xcdc6, + 0xaae6, 0xcdc3, 0xaae3, 0xcdb9, 0xcdbf, 0xcdc1, 0xcdb4, 0xaae2, + 0xaadd, 0xcdba, 0xaae4, 0xaae7, 0xaae1, 0xaada, 0xcdbe, 0xcdb8, + 0xcdc5, 0xaae9, 0xaae5, 0xaae0, 0xcdbd, 0xafec, 0xcdbb, 0xaade, + 0xaae8, 0xcdb3, 0xcdc2, 0xcdc4, 0xad62, 0xad5c, 0xad64, 0xad61, + 0xd071, 0xd074, 0xad5d, 0xd06b, 0xad56, 0xad60, 0xad63, 0xad65, + 0xd0a2, 0xd077, 0xad55, 0xd0a1, 0xad59, 0xad57, 0xad52, 0xd06f, + 0xd07e, 0xd073, 0xd076, 0xd0a5, 0xad66, 0xd07d, 0xad5e, 0xd078, + 0xd0a4, 0xd075, 0xd079, 0xd07c, 0xd06d, 0xd0a3, 0xd07b, 0xd06c, + 0xd070, 0xad5f, 0xad5a, 0xad53, 0xad58, 0xad54, 0xad67, 0xd06e, + 0xd3a5, 0xad5b, 0xd07a, 0xce41, 0xd3a8, 0xaffa, 0xd376, 0xd3a3, + 0xd37d, 0xd3b2, 0xd3aa, 0xd37e, 0xd3a9, 0xd378, 0xd37c, 0xd3b5, + 0xaffd, 0xd3ad, 0xd3a4, 0xafed, 0xd3b3, 0xd374, 0xd3ac, 0xaffc, + 0xaff7, 0xd373, 0xaff5, 0xaff4, 0xaff9, 0xd3ab, 0xaff1, 0xaff8, + 0xd072, 0xdb5c, 0xd3a6, 0xd37a, 0xaffb, 0xd37b, 0xd3a1, 0xaffe, + 0xd375, 0xd3af, 0xd3ae, 0xd3b6, 0xaff3, 0xaff0, 0xd3b4, 0xd3b0, + 0xd3a7, 0xd3a2, 0xaff6, 0xaff2, 0xd377, 0xafee, 0xd3b1, 0xafef, + 0xd379, 0xd75e, 0xd760, 0xd765, 0xd779, 0xb2fc, 0xb2f2, 0xd75d, + 0xb2fd, 0xb2fe, 0xd768, 0xd76f, 0xd775, 0xd762, 0xd769, 0xb340, + 0xd777, 0xd772, 0xb2fa, 0xb2f8, 0xd76e, 0xd76a, 0xd75c, 0xb2ef, + 0xd761, 0xd759, 0xb2f7, 0xb2f9, 0xd766, 0xd763, 0xb2f4, 0xd773, + 0xb2f1, 0xd764, 0xd77a, 0xd76c, 0xd76b, 0xb2f0, 0xb2fb, 0xb2f3, + 0xd75a, 0xd75f, 0xd770, 0xd776, 0xb341, 0xd75b, 0xd767, 0xd76d, + 0xb2f6, 0xd778, 0xd771, 0xd774, 0xb2f5, 0xdb6c, 0xdb60, 0xb5d7, + 0xdb7d, 0xdba7, 0xdbaa, 0xb5d5, 0xdb68, 0xdba3, 0xdb69, 0xdb77, + 0xb5e2, 0xdb73, 0xb5df, 0xdb74, 0xdb5d, 0xdba4, 0xb5e8, 0xdba1, + 0xdb75, 0xdbac, 0xdb70, 0xdfc8, 0xdbaf, 0xb5e6, 0xdb6e, 0xdb7a, + 0xb5e9, 0xb5d4, 0xdb72, 0xdbad, 0xdb6b, 0xdb64, 0xdb6f, 0xdb63, + 0xdb61, 0xb5d0, 0xdba5, 0xdb6a, 0xdba8, 0xdba9, 0xb5d8, 0xb5dd, + 0xb5d9, 0xb5e1, 0xdb7e, 0xb5da, 0xdb76, 0xdb66, 0xb5d2, 0xdb5e, + 0xdba2, 0xdbab, 0xdb65, 0xb5e0, 0xdbb0, 0xdb71, 0xdb6d, 0xb5d1, + 0xb5e5, 0xdb7c, 0xb5e7, 0xdb78, 0xb5dc, 0xb5d6, 0xb5de, 0xb5d3, + 0xb5e4, 0xdb79, 0xdb67, 0xdb7b, 0xdb62, 0xdba6, 0xdbae, 0xdb5f, + 0xdfc7, 0xdfdd, 0xb855, 0xdfcc, 0xdfca, 0xdfb5, 0xb8a9, 0xdfc5, + 0xdfd9, 0xdfc1, 0xb8b1, 0xdfd8, 0xdfbf, 0xb5e3, 0xdfcf, 0xdfc0, + 0xdfd6, 0xb8b0, 0xb8a8, 0xdfaa, 0xdfb2, 0xdfcb, 0xdfc3, 0xdfdc, + 0xdfc6, 0xb8b6, 0xdfd7, 0xb8ad, 0xdfc9, 0xdfd1, 0xdfb6, 0xdfd0, + 0xdfe1, 0xdfb1, 0xdfd2, 0xdfdf, 0xdfab, 0xb5db, 0xdfb9, 0xdfb8, + 0xb8af, 0xdfbc, 0xdfbe, 0xdfcd, 0xdfde, 0xb8b2, 0xb8b3, 0xdfb0, + 0xb8ab, 0xdfb4, 0xdfda, 0xb8b4, 0xb8ac, 0xb8ae, 0xb8b5, 0xdfe0, + 0xdfd3, 0xdfce, 0xdfbb, 0xdfba, 0xb8aa, 0xdfac, 0xb8a7, 0xdfc4, + 0xdfad, 0xdfc2, 0xdfb7, 0xdfdb, 0xb8a6, 0xdfb3, 0xdfaf, 0xdfd5, + 0xdfae, 0xbb60, 0xe3d3, 0xe3c2, 0xe3ac, 0xe3ca, 0xbb58, 0xe3bb, + 0xe3c5, 0xbb5b, 0xe3be, 0xbb59, 0xe3af, 0xe3cd, 0xe3ae, 0xe3c1, + 0xe3ad, 0xe3bf, 0xe3c8, 0xe3c6, 0xe3ba, 0xe3b5, 0xe3b3, 0xe3b4, + 0xe3c7, 0xe3d2, 0xe3bc, 0xbb5a, 0xe3b7, 0xe3cb, 0xbb5d, 0xe3b6, + 0xe3b0, 0xe3c0, 0xbb61, 0xbb55, 0xbb5e, 0xe3b8, 0xe3b2, 0xbb57, + 0xdfd4, 0xbb56, 0xe3c3, 0xbb54, 0xbb63, 0xbb5c, 0xe3c4, 0xe3b9, + 0xe3b1, 0xe3cc, 0xe3bd, 0xbb62, 0xe3d0, 0xbb5f, 0xe3cf, 0xe3c9, + 0xe3ce, 0xe3d1, 0xe773, 0xe774, 0xe767, 0xe766, 0xe762, 0xbdb4, + 0xbdac, 0xe776, 0xe775, 0xdfa9, 0xe75f, 0xe763, 0xe75d, 0xe770, + 0xe761, 0xe777, 0xe75a, 0xe758, 0xe764, 0xe76e, 0xe769, 0xbdb6, + 0xe74f, 0xe76d, 0xbdb7, 0xdfbd, 0xe75b, 0xe752, 0xe755, 0xe77b, + 0xe75c, 0xe753, 0xe751, 0xe74e, 0xbdb0, 0xe765, 0xbdaf, 0xbdb3, + 0xe760, 0xe768, 0xbda9, 0xe778, 0xe77c, 0xbdab, 0xe757, 0xe76b, + 0xe76f, 0xe754, 0xe779, 0xbdb2, 0xbdb1, 0xe74c, 0xbdb5, 0xe772, + 0xe756, 0xe76a, 0xe750, 0xe75e, 0xe759, 0xbdad, 0xbdae, 0xe76c, + 0xe77d, 0xe77a, 0xe771, 0xe74d, 0xbdaa, 0xeb49, 0xeb40, 0xeb43, + 0xbfbb, 0xeb45, 0xeaf9, 0xeb41, 0xeb47, 0xbfb8, 0xbfbc, 0xbfb6, + 0xeafb, 0xeb4c, 0xeb46, 0xeafc, 0xeb55, 0xeb4f, 0xeaf8, 0xee46, + 0xeafe, 0xbfb7, 0xeb4a, 0xeb54, 0xbfbf, 0xeb51, 0xeafd, 0xeb44, + 0xeb48, 0xeb42, 0xeb56, 0xeb53, 0xeb50, 0xbfb9, 0xbfba, 0xbfbe, + 0xeafa, 0xeb57, 0xbfbd, 0xeb4d, 0xeb4b, 0xeb4e, 0xee53, 0xee40, + 0xee45, 0xee52, 0xee44, 0xedfb, 0xee41, 0xc1a2, 0xedf4, 0xee4d, + 0xee4f, 0xedf3, 0xc1a1, 0xee51, 0xee49, 0xc1a8, 0xee50, 0xee42, + 0xc1aa, 0xedf9, 0xeb52, 0xee4a, 0xee47, 0xedf5, 0xee55, 0xc1a4, + 0xc1a5, 0xedf7, 0xee48, 0xee54, 0xee4b, 0xedfd, 0xc1a7, 0xc1a3, + 0xee4c, 0xedfe, 0xee56, 0xedf8, 0xee43, 0xee4e, 0xedfa, 0xedfc, + 0xc2cb, 0xedf6, 0xc1a9, 0xc2c4, 0xc17e, 0xc1a6, 0xc2c8, 0xf0b3, + 0xf0a9, 0xf0a4, 0xf0aa, 0xf0b4, 0xf0b8, 0xf0b7, 0xc2ca, 0xc2c9, + 0xf0ab, 0xf0b9, 0xf0ae, 0xf0a6, 0xf0a8, 0xf0a7, 0xf0ad, 0xf0b2, + 0xf0a5, 0xf0ac, 0xf0b1, 0xc2c7, 0xf0af, 0xc2c5, 0xf0b0, 0xc2c3, + 0xc2c6, 0xf2d5, 0xf0b5, 0xc3c2, 0xf2cd, 0xf2d1, 0xf2c9, 0xf2cc, + 0xf2d4, 0xc3c0, 0xf2d9, 0xf2d2, 0xf2ca, 0xf2da, 0xf2d3, 0xc3c3, + 0xc3c4, 0xf2d7, 0xf2cb, 0xc3bf, 0xc3c1, 0xf2c6, 0xf2ce, 0xf2c8, + 0xf2d8, 0xf2d6, 0xf2c7, 0xf2cf, 0xf4be, 0xc3c5, 0xf2d0, 0xc4a7, + 0xc4a9, 0xc4a6, 0xf4c3, 0xf4bb, 0xf4b9, 0xf4bd, 0xf4ba, 0xf4bf, + 0xf4c1, 0xc4aa, 0xc4ac, 0xf4c0, 0xc4ad, 0xc4ab, 0xf4c2, 0xc4a8, + 0xc4f4, 0xf5f1, 0xf5f7, 0xc4f6, 0xf4bc, 0xf5f6, 0xf5fd, 0xf5f4, + 0xf5fb, 0xf5fa, 0xf4b8, 0xf5f5, 0xf0b6, 0xf5fe, 0xf5f3, 0xf5f8, + 0xf5fc, 0xf5f2, 0xf74a, 0xc4f5, 0xf5f9, 0xf7f4, 0xf74b, 0xf749, + 0xf747, 0xf748, 0xf74c, 0xc5d9, 0xf7f2, 0xf7f0, 0xf7f5, 0xf7f3, + 0xf7f6, 0xc5da, 0xf7f1, 0xf8bc, 0xf945, 0xf946, 0xf947, 0xf9c7, + 0xf9bd, 0xca4f, 0xaaea, 0xad68, 0xd3b8, 0xd3b7, 0xb040, 0xb342, + 0xd77c, 0xd77b, 0xb5ea, 0xb8b8, 0xb8b7, 0xb8b9, 0xe3d4, 0xe77e, + 0xeb58, 0xeb5a, 0xeb59, 0xc1ab, 0xee57, 0xf0ba, 0xf9a5, 0xa6e4, + 0xcdc9, 0xcdca, 0xcdc8, 0xcdc7, 0xaaeb, 0xd0a9, 0xd0a7, 0xd0a6, + 0xad69, 0xad6b, 0xad6a, 0xd0a8, 0xd3c4, 0xd3c1, 0xd3bf, 0xb041, + 0xd3c2, 0xb046, 0xd3bc, 0xd3cb, 0xd3cd, 0xd3bd, 0xb043, 0xd3ce, + 0xd3c9, 0xd3bb, 0xd3c0, 0xd3ca, 0xd3c6, 0xd3c3, 0xb048, 0xd3cc, + 0xd3be, 0xd3c7, 0xd3b9, 0xb047, 0xb044, 0xd3c5, 0xd3c8, 0xd3ba, + 0xb045, 0xb042, 0xb34c, 0xd7a5, 0xb34b, 0xd7a8, 0xd7ab, 0xb348, + 0xb346, 0xd77e, 0xd7a9, 0xd7a7, 0xd7a4, 0xd7ac, 0xd7ad, 0xd7af, + 0xd7b0, 0xd77d, 0xb345, 0xd7a2, 0xd7a1, 0xd7ae, 0xb347, 0xd7a3, + 0xb349, 0xb344, 0xd7a6, 0xb34d, 0xb34a, 0xd7aa, 0xb5f1, 0xdbbf, + 0xdbb4, 0xb5ee, 0xdfe7, 0xdbbd, 0xdbb1, 0xb5ec, 0xdbb6, 0xb5ef, + 0xdbba, 0xdbb8, 0xb5f2, 0xb5eb, 0xdbb2, 0xdbb5, 0xb5f0, 0xdbb3, + 0xdbbe, 0xdbbc, 0xdbb7, 0xdbb9, 0xdbbb, 0xb5ed, 0xdfe8, 0xdfee, + 0xdfe4, 0xdfea, 0xb8ba, 0xdfe6, 0xb8c0, 0xb8bf, 0xb8be, 0xdfed, + 0xb8c1, 0xb8c2, 0xdfe3, 0xdff0, 0xb8c3, 0xb8bd, 0xb8bc, 0xdfec, + 0xb8c4, 0xdfe2, 0xdfe5, 0xdfef, 0xdfeb, 0xe3f4, 0xe3e9, 0xb8bb, + 0xbb6a, 0xe3dd, 0xe3f2, 0xe3de, 0xbb65, 0xe3db, 0xe3e4, 0xe3dc, + 0xbb67, 0xe3d6, 0xe3f1, 0xbb68, 0xe3ee, 0xe3ef, 0xe3d7, 0xbb6d, + 0xe3e6, 0xe3e0, 0xe3e7, 0xe3da, 0xe3f3, 0xe3eb, 0xe3e5, 0xe3d5, + 0xbb69, 0xe3ec, 0xbb6c, 0xe3f0, 0xe3ea, 0xbb66, 0xe3e8, 0xe3e2, + 0xbb64, 0xe3d9, 0xe3e1, 0xe3ed, 0xe3df, 0xe3e3, 0xbdc1, 0xdfe9, + 0xe7b2, 0xe7bb, 0xe7b1, 0xe7ad, 0xe7aa, 0xbdc2, 0xe7a8, 0xbb6b, + 0xe7a1, 0xbdc0, 0xe7a7, 0xbdbf, 0xe7ac, 0xe7a9, 0xe7b9, 0xe7b4, + 0xe7ae, 0xe7b3, 0xbdbb, 0xe7ab, 0xe7be, 0xe7a2, 0xe7a3, 0xe7ba, + 0xbdbc, 0xe7bf, 0xbdbe, 0xe7c0, 0xe7b0, 0xe3d8, 0xe7b6, 0xe7af, + 0xe7b8, 0xe7b5, 0xe7a6, 0xbdb9, 0xe7bd, 0xbdba, 0xe7a4, 0xbdbd, + 0xeb64, 0xe7b7, 0xe7bc, 0xeb61, 0xbdb8, 0xbfc0, 0xeb6b, 0xeb67, + 0xeb65, 0xeb60, 0xeb6f, 0xbfc4, 0xeb5c, 0xeb68, 0xeb69, 0xeb5f, + 0xeb5e, 0xeb6c, 0xeb62, 0xeb5d, 0xeb63, 0xeb6e, 0xeb5b, 0xeb6d, + 0xeb6a, 0xbfc2, 0xbfc1, 0xbfc3, 0xeb66, 0xf0cb, 0xee59, 0xc1b1, + 0xee5d, 0xee5a, 0xee61, 0xee67, 0xee5c, 0xee70, 0xc1ae, 0xee6a, + 0xee5f, 0xee6b, 0xee66, 0xee6d, 0xee5e, 0xc1b3, 0xc1b2, 0xee60, + 0xee6e, 0xee58, 0xee6c, 0xc1ac, 0xee64, 0xee63, 0xee68, 0xee5b, + 0xc1b0, 0xc1b4, 0xee62, 0xee69, 0xc1b5, 0xee65, 0xc1ad, 0xc1af, + 0xf0c7, 0xf0c5, 0xf0cc, 0xf0c9, 0xf0cd, 0xf0be, 0xf0c6, 0xf0d1, + 0xee6f, 0xf0c2, 0xc2cf, 0xe7a5, 0xf0bd, 0xf0ca, 0xf0c4, 0xf0c1, + 0xf0bc, 0xf0bb, 0xf0d0, 0xf0c0, 0xf0bf, 0xc2cd, 0xf0c8, 0xc2cc, + 0xc2ce, 0xf0c3, 0xf0cf, 0xf2de, 0xf2df, 0xc3c9, 0xf2dc, 0xc3c6, + 0xf2e4, 0xc3ca, 0xf2e6, 0xf2db, 0xf0ce, 0xf2e8, 0xf2dd, 0xc3c7, + 0xf2e3, 0xf2e5, 0xf2e0, 0xf2e7, 0xf2e2, 0xf2e1, 0xc3c8, 0xf4c5, + 0xf4c6, 0xf4c8, 0xc4ae, 0xc4af, 0xf4c9, 0xf4c7, 0xf4c4, 0xf642, + 0xf645, 0xf641, 0xc4fa, 0xf643, 0xc4f9, 0xc4f8, 0xc4f7, 0xf644, + 0xf751, 0xf74f, 0xf74e, 0xf640, 0xf750, 0xf646, 0xf74d, 0xf7f9, + 0xf7d7, 0xf7f7, 0xc5db, 0xf7f8, 0xf7fa, 0xf8bf, 0xc5fa, 0xf8be, + 0xf8bd, 0xc5fb, 0xc65a, 0xf96e, 0xf9a7, 0xf9a6, 0xf9a8, 0xa6e5, + 0xd0aa, 0xd3cf, 0xd3d0, 0xdbc0, 0xf647, 0xf8c0, 0xa6e6, 0xad6c, + 0xd0ab, 0xd7b1, 0xb34e, 0xdbc2, 0xdbc1, 0xb5f3, 0xb8c5, 0xe7c1, + 0xbdc3, 0xbdc4, 0xbfc5, 0xc5fc, 0xa6e7, 0xd0ac, 0xaaed, 0xd0ae, + 0xd0ad, 0xad6d, 0xd3d1, 0xd3d8, 0xb049, 0xd3d6, 0xd3d4, 0xd3db, + 0xd3d2, 0xd3d3, 0xb04a, 0xb04e, 0xd3dc, 0xb04d, 0xd3da, 0xd3d7, + 0xd3d5, 0xb04b, 0xb04c, 0xd3d9, 0xb350, 0xd7b2, 0xb355, 0xd7c2, + 0xb354, 0xd7c4, 0xd7b8, 0xb352, 0xd7c3, 0xd7b3, 0xb353, 0xd7bf, + 0xd7bb, 0xd7bd, 0xd7b7, 0xd7be, 0xb34f, 0xd7ba, 0xd7b9, 0xd7b5, + 0xd7c0, 0xd7bc, 0xd7b4, 0xd7b6, 0xb351, 0xd7c1, 0xb5f6, 0xdbcd, + 0xdbc9, 0xdbcb, 0xdbc6, 0xdbc5, 0xdbc3, 0xdbca, 0xdbcc, 0xdbc8, + 0xdbc7, 0xb5f4, 0xb5f5, 0xdbcf, 0xb8cd, 0xdff2, 0xdff8, 0xdff3, + 0xdff4, 0xdff9, 0xb8cf, 0xb8c7, 0xb8ce, 0xdff1, 0xdbc4, 0xb8ca, + 0xb8c8, 0xdff7, 0xdff6, 0xb8c9, 0xb8cb, 0xdff5, 0xb8c6, 0xb8cc, + 0xe3f6, 0xbb74, 0xe442, 0xe441, 0xe3fb, 0xbb76, 0xe440, 0xe3f7, + 0xe3f8, 0xbb6e, 0xbb70, 0xe3fd, 0xe3f5, 0xbb72, 0xbb71, 0xe3f9, + 0xe3fe, 0xe3fc, 0xbb73, 0xe3fa, 0xdbce, 0xbb6f, 0xe7c2, 0xe7c9, + 0xbdc6, 0xe7cd, 0xbdca, 0xe7c5, 0xe7c3, 0xe7cc, 0xbdc5, 0xe7cb, + 0xbdc7, 0xbdc8, 0xe7c4, 0xbdc9, 0xe7ca, 0xe7c6, 0xe7c7, 0xe7c8, + 0xbb75, 0xeb70, 0xeb7c, 0xbfca, 0xeb77, 0xeb79, 0xbfc8, 0xeb71, + 0xeb75, 0xeb78, 0xbfc6, 0xbfc9, 0xeb7b, 0xeb73, 0xeb74, 0xeb7a, + 0xeb72, 0xeb76, 0xbfc7, 0xee72, 0xee71, 0xc1b7, 0xee77, 0xc1b9, + 0xc1b6, 0xee73, 0xc1ba, 0xee74, 0xee75, 0xee78, 0xc1b8, 0xf0d6, + 0xf0d9, 0xf0d3, 0xf0d5, 0xf0d4, 0xf0d7, 0xf0d8, 0xee76, 0xf0d2, + 0xc3cd, 0xf2ec, 0xf2ef, 0xf2f1, 0xf2ea, 0xf2eb, 0xf2ee, 0xf2f0, + 0xc3ce, 0xc3cc, 0xc3cb, 0xf2ed, 0xf2e9, 0xf4ca, 0xc4b0, 0xf4cb, + 0xf649, 0xc4fb, 0xf64b, 0xc4fc, 0xf648, 0xf64a, 0xc5a8, 0xf752, + 0xc5a7, 0xf7fd, 0xf7fc, 0xf7fb, 0xf948, 0xf949, 0xf94b, 0xf94a, + 0xca50, 0xa6e8, 0xad6e, 0xd7c5, 0xb5f7, 0xdffa, 0xc2d0, 0xf2f2, + 0xa8a3, 0xb357, 0xb356, 0xdbd0, 0xb5f8, 0xdbd2, 0xdbd1, 0xdffb, + 0xb8d0, 0xe443, 0xe446, 0xe445, 0xe444, 0xe7ce, 0xe7d0, 0xe7cf, + 0xbfcc, 0xbfcb, 0xc1bb, 0xee79, 0xee7b, 0xee7a, 0xc2d1, 0xf2f4, + 0xf2f3, 0xf4cc, 0xc4b1, 0xc4fd, 0xf754, 0xf753, 0xc65b, 0xa8a4, + 0xd0af, 0xad6f, 0xd7c8, 0xd7c6, 0xd7c7, 0xdbd4, 0xdbd5, 0xe043, + 0xdbd3, 0xdffc, 0xe041, 0xe040, 0xe042, 0xb8d1, 0xdffe, 0xdffd, + 0xe044, 0xe449, 0xe447, 0xe448, 0xe7d3, 0xe7d1, 0xe7d2, 0xeb7d, + 0xee7c, 0xee7d, 0xc2d2, 0xf2f5, 0xf4cd, 0xc4b2, 0xf64c, 0xf755, + 0xc5a9, 0xf7fe, 0xf94c, 0xa8a5, 0xad71, 0xad72, 0xd0b0, 0xd0b1, + 0xad70, 0xb054, 0xb052, 0xb051, 0xb058, 0xb050, 0xb059, 0xd3dd, + 0xb056, 0xb053, 0xb057, 0xb055, 0xb04f, 0xb35f, 0xb359, 0xd7cc, + 0xb35e, 0xb360, 0xb35a, 0xb35b, 0xd7ca, 0xb358, 0xd7cb, 0xb35d, + 0xd7c9, 0xb35c, 0xb644, 0xb646, 0xdbd8, 0xb645, 0xb5f9, 0xb5fd, + 0xb8e4, 0xe049, 0xdbda, 0xb5fe, 0xdbdd, 0xdbde, 0xb643, 0xdbe0, + 0xdbe2, 0xdbe3, 0xdbd7, 0xdbd6, 0xdbe4, 0xb642, 0xdbe1, 0xdbdf, + 0xb640, 0xb5fb, 0xb647, 0xdbdb, 0xdbdc, 0xdbd9, 0xb641, 0xb5fc, + 0xb5fa, 0xe048, 0xb8df, 0xb8da, 0xb8d5, 0xb8e5, 0xb8d6, 0xb8d2, + 0xb8e1, 0xb8de, 0xb8e0, 0xb8d7, 0xb8dc, 0xb8d3, 0xb8d4, 0xe050, + 0xe04d, 0xe045, 0xe04a, 0xb8e2, 0xe051, 0xb8e3, 0xb8d9, 0xe047, + 0xe04f, 0xe04b, 0xe04e, 0xe04c, 0xb8dd, 0xe046, 0xb8d8, 0xe44c, + 0xbb78, 0xbb7b, 0xe44e, 0xbba5, 0xe44d, 0xbb7d, 0xbdcf, 0xe44f, + 0xbba4, 0xe44b, 0xbba6, 0xbb79, 0xb8db, 0xbb7c, 0xbb7a, 0xbb7e, + 0xbba2, 0xbb77, 0xbba7, 0xbba3, 0xbba1, 0xe44a, 0xbdd6, 0xbdd2, + 0xbdd9, 0xe7d6, 0xbdda, 0xe7e2, 0xe7db, 0xbdcb, 0xe7e3, 0xe7dd, + 0xbdd5, 0xe7de, 0xbdd4, 0xe7e1, 0xbdce, 0xe7df, 0xe7d5, 0xbdcd, + 0xebaa, 0xbdd3, 0xbdd0, 0xbdd8, 0xe7d4, 0xe7d8, 0xbdcc, 0xe7d7, + 0xe7d9, 0xe7da, 0xbdd7, 0xe7dc, 0xe7e0, 0xe7e4, 0xbddb, 0xbfd2, + 0xeba5, 0xebab, 0xeba8, 0xeb7e, 0xebac, 0xeba1, 0xeba7, 0xbfcd, + 0xbfd3, 0xebad, 0xbfcf, 0xbfd9, 0xbfd4, 0xebaf, 0xeba9, 0xbfd0, + 0xeba2, 0xbfda, 0xeba3, 0xeba4, 0xbfdb, 0xbfd8, 0xbdd1, 0xbfce, + 0xebb0, 0xbfdc, 0xbfd5, 0xebae, 0xbfd1, 0xbfd6, 0xbfd7, 0xc1c3, + 0xeea4, 0xeead, 0xeeaa, 0xeeac, 0xc1c0, 0xeea5, 0xeeab, 0xc1bc, + 0xeea7, 0xc1c4, 0xeea3, 0xeea8, 0xeeaf, 0xeba6, 0xeea9, 0xeea2, + 0xc1bd, 0xeea1, 0xc1be, 0xeeb0, 0xc1bf, 0xeeae, 0xc1c2, 0xee7e, + 0xc1c1, 0xeea6, 0xf0dc, 0xf0ea, 0xf0e5, 0xf0e7, 0xf0db, 0xc2d3, + 0xf0da, 0xc2d6, 0xc2d5, 0xf0e9, 0xf0e1, 0xf0de, 0xf0e4, 0xf0dd, + 0xf0df, 0xf0e8, 0xf0e6, 0xc2d4, 0xf0ed, 0xf0eb, 0xf0e2, 0xf0ec, + 0xf0e3, 0xf2f9, 0xc3cf, 0xf341, 0xf64f, 0xc3d6, 0xf0e0, 0xf2f7, + 0xc3d2, 0xf2f8, 0xf2fd, 0xc3d4, 0xc3d5, 0xf2f6, 0xf340, 0xf342, + 0xf2fa, 0xf2fc, 0xf2fe, 0xf2fb, 0xf343, 0xc3d1, 0xc3d7, 0xc3d3, + 0xc3d0, 0xf4d0, 0xc4b7, 0xf4ce, 0xf4d2, 0xf4d3, 0xc4b5, 0xf4d4, + 0xf4d1, 0xf4cf, 0xc4b8, 0xc4b4, 0xf4d5, 0xc4b6, 0xc4b3, 0xc4fe, + 0xc540, 0xf64e, 0xf64d, 0xf650, 0xf651, 0xc541, 0xf756, 0xf75b, + 0xc5aa, 0xf758, 0xf757, 0xf75a, 0xf759, 0xf843, 0xc5dc, 0xf842, + 0xf840, 0xf841, 0xc5fe, 0xc5fd, 0xf8c1, 0xf8c2, 0xc640, 0xf94d, + 0xf94e, 0xc667, 0xc66d, 0xf9a9, 0xf9c8, 0xa8a6, 0xd7cd, 0xd7ce, + 0xe052, 0xe450, 0xe7e5, 0xc1c6, 0xc1c5, 0xf0ee, 0xf344, 0xf844, + 0xa8a7, 0xd3de, 0xb05a, 0xb361, 0xe054, 0xe053, 0xbddc, 0xe7e6, + 0xbddd, 0xeeb1, 0xc2d7, 0xc676, 0xa8a8, 0xcdcb, 0xd3df, 0xb362, + 0xd7cf, 0xd7d0, 0xdbe5, 0xb648, 0xb8e6, 0xe056, 0xe055, 0xe057, + 0xe451, 0xe452, 0xbba8, 0xbfdd, 0xbdde, 0xbfde, 0xeeb5, 0xeeb2, + 0xeeb4, 0xeeb3, 0xc1c7, 0xf0ef, 0xf346, 0xf345, 0xcba4, 0xb05c, + 0xb05b, 0xd3e0, 0xd7d1, 0xdbe7, 0xdbe6, 0xb649, 0xe059, 0xe05a, + 0xe058, 0xb8e8, 0xb8e7, 0xbbaa, 0xbba9, 0xe7e7, 0xebb3, 0xebb1, + 0xebb2, 0xbfdf, 0xeeb7, 0xeeb6, 0xf0f2, 0xf0f1, 0xf0f0, 0xf347, + 0xf9aa, 0xa8a9, 0xad73, 0xad74, 0xb05d, 0xb05e, 0xd3e2, 0xd3e1, + 0xd7d2, 0xb368, 0xb366, 0xb363, 0xb367, 0xb365, 0xb364, 0xb64a, + 0xdbea, 0xb8ed, 0xb64c, 0xb651, 0xdbec, 0xb653, 0xb652, 0xb655, + 0xdbeb, 0xdbe8, 0xb64f, 0xb64b, 0xb64d, 0xdbe9, 0xb654, 0xb650, + 0xb64e, 0xb8ef, 0xb8ee, 0xb8ec, 0xb8f0, 0xb8ea, 0xb8eb, 0xb8e9, + 0xe05b, 0xe454, 0xbbac, 0xbbad, 0xbbab, 0xe453, 0xe455, 0xe7ea, + 0xe7ec, 0xbde7, 0xe7ed, 0xbde0, 0xe7e9, 0xbddf, 0xbde9, 0xbde5, + 0xbde6, 0xbde2, 0xe7e8, 0xbde1, 0xe7ee, 0xe7eb, 0xbde8, 0xbde3, + 0xbde4, 0xebb5, 0xebb7, 0xebb6, 0xebb8, 0xbfe0, 0xebb4, 0xc1cb, + 0xeeb8, 0xc1c8, 0xc1cc, 0xc1ca, 0xc1c9, 0xf0f3, 0xf0f6, 0xf0f5, + 0xf0f4, 0xc2d8, 0xf348, 0xf349, 0xc3d8, 0xf34a, 0xc3d9, 0xc4ba, + 0xc4b9, 0xf652, 0xc542, 0xf653, 0xf75c, 0xc5ab, 0xc5ac, 0xf845, + 0xc642, 0xa8aa, 0xb36a, 0xb369, 0xe05c, 0xe05d, 0xbbae, 0xebb9, + 0xbdea, 0xebba, 0xeeb9, 0xa8ab, 0xd0b2, 0xad76, 0xad75, 0xd3e3, + 0xb05f, 0xd3e4, 0xd7d5, 0xd7d4, 0xd7d3, 0xdbee, 0xb658, 0xdbed, + 0xb657, 0xdbef, 0xb656, 0xe05f, 0xe062, 0xe060, 0xe061, 0xe065, + 0xe05e, 0xe066, 0xe063, 0xe064, 0xbbb0, 0xe456, 0xbbaf, 0xe7f2, + 0xe7f0, 0xbdeb, 0xe7ef, 0xe7f1, 0xbdec, 0xebbb, 0xebbc, 0xc1cd, + 0xf34c, 0xf34e, 0xf34b, 0xf34d, 0xf4d6, 0xf654, 0xf96f, 0xa8ac, + 0xad77, 0xd3e5, 0xd3e7, 0xd3e6, 0xd7d8, 0xb36c, 0xd7d6, 0xb36b, + 0xd7d9, 0xd7da, 0xd7d7, 0xdbfb, 0xb660, 0xdbf3, 0xdbf9, 0xb65b, + 0xb65e, 0xdbf2, 0xb659, 0xdbf6, 0xe06c, 0xb65d, 0xdbf1, 0xdbf7, + 0xdbf4, 0xdbfa, 0xdbf0, 0xdbf8, 0xb65c, 0xb65f, 0xdbf5, 0xb65a, + 0xb8f2, 0xe068, 0xb8f1, 0xe06f, 0xe06e, 0xb8f8, 0xb8f9, 0xe070, + 0xb8f3, 0xe06d, 0xb8f7, 0xe072, 0xe069, 0xe06b, 0xb8f4, 0xe067, + 0xe06a, 0xe071, 0xb8f5, 0xe073, 0xb8f6, 0xbbb1, 0xe45b, 0xe461, + 0xe459, 0xe462, 0xe458, 0xe45d, 0xe463, 0xe460, 0xe45f, 0xe45e, + 0xe457, 0xe45c, 0xe45a, 0xbdf1, 0xbdee, 0xe7fb, 0xe841, 0xe843, + 0xe840, 0xe7f8, 0xe7fa, 0xe845, 0xe842, 0xe7fc, 0xe846, 0xe7f9, + 0xe844, 0xbdef, 0xbdf5, 0xbdf3, 0xe7f3, 0xbdf4, 0xbdf0, 0xe7f4, + 0xe7f6, 0xe7f5, 0xe7fd, 0xe7fe, 0xbdf2, 0xbded, 0xe7f7, 0xebc6, + 0xbfe2, 0xebbd, 0xbfe3, 0xbfe6, 0xebc2, 0xebbf, 0xbfe5, 0xebc3, + 0xebc4, 0xebbe, 0xebc7, 0xebc0, 0xebc5, 0xbfe4, 0xbfe1, 0xebc1, + 0xeebf, 0xc1d0, 0xc1ce, 0xc1d1, 0xc1cf, 0xeebe, 0xeebb, 0xeeba, + 0xeebd, 0xeebc, 0xf145, 0xc2de, 0xf0fb, 0xf0fa, 0xc2d9, 0xf141, + 0xf140, 0xf0f7, 0xf143, 0xf0fc, 0xc2dd, 0xf0f9, 0xf142, 0xf0f8, + 0xc2da, 0xc2dc, 0xf0fd, 0xc2db, 0xf0fe, 0xf144, 0xf352, 0xc3de, + 0xf34f, 0xf353, 0xc3db, 0xf351, 0xc3e0, 0xc3dd, 0xf350, 0xc3df, + 0xf354, 0xc3da, 0xc4bc, 0xc4be, 0xf4d9, 0xc4bd, 0xf4d7, 0xc3dc, + 0xf4d8, 0xc4bb, 0xc543, 0xc545, 0xf656, 0xc544, 0xf655, 0xf761, + 0xc5ad, 0xf760, 0xc5ae, 0xf75e, 0xf75d, 0xf762, 0xf763, 0xf846, + 0xf75f, 0xf8c6, 0xf8c3, 0xf8c4, 0xf8c5, 0xc65c, 0xf951, 0xf950, + 0xf94f, 0xf970, 0xf9be, 0xf9ab, 0xc66e, 0xa8ad, 0xb060, 0xb8fa, + 0xbdf6, 0xebc8, 0xc2df, 0xf355, 0xf9ac, 0xa8ae, 0xaaee, 0xad79, + 0xad78, 0xb063, 0xd3e8, 0xb061, 0xd3e9, 0xb062, 0xd7df, 0xd7db, + 0xb36d, 0xd7de, 0xd7dd, 0xd7dc, 0xb36e, 0xd7e0, 0xd7e1, 0xdc43, + 0xdc41, 0xdc45, 0xdc46, 0xdc4c, 0xdc48, 0xdc4a, 0xdc42, 0xdbfc, + 0xdc49, 0xdc4b, 0xdc44, 0xdc47, 0xdbfd, 0xb662, 0xdc40, 0xdbfe, + 0xb661, 0xb663, 0xb8fd, 0xe075, 0xe077, 0xe076, 0xe07b, 0xb8fb, + 0xe078, 0xe074, 0xe079, 0xe07a, 0xb8fc, 0xb8fe, 0xe07c, 0xe467, + 0xe466, 0xe464, 0xe465, 0xbbb3, 0xbbb5, 0xbbb2, 0xbbb4, 0xe84d, + 0xe84e, 0xe849, 0xe84a, 0xbdf8, 0xbdfd, 0xbdf7, 0xbdfe, 0xbdf9, + 0xe84b, 0xe84c, 0xe848, 0xbe40, 0xbdfb, 0xbdfa, 0xbdfc, 0xe847, + 0xebca, 0xbfe8, 0xebcc, 0xbfea, 0xebcf, 0xebcb, 0xebc9, 0xebce, + 0xbfe9, 0xebcd, 0xbfe7, 0xc1d3, 0xc1d6, 0xeec1, 0xc1d4, 0xeec0, + 0xc1d2, 0xc1d5, 0xf146, 0xf147, 0xf148, 0xc2e0, 0xf149, 0xc2e1, + 0xc3e2, 0xf358, 0xf359, 0xf357, 0xf356, 0xf35a, 0xc3e1, 0xf4dd, + 0xf4db, 0xf4dc, 0xf4de, 0xf4da, 0xf4df, 0xf658, 0xf659, 0xf657, + 0xc546, 0xf764, 0xc5af, 0xf765, 0xf848, 0xf847, 0xa8af, 0xb664, + 0xb940, 0xbbb6, 0xbfec, 0xbfeb, 0xc3e3, 0xc47c, 0xc547, 0xa8b0, + 0xb064, 0xb941, 0xf35b, 0xcba6, 0xa8b1, 0xa8b4, 0xa8b3, 0xa8b2, + 0xcba5, 0xcdcd, 0xcdcf, 0xaaef, 0xaaf1, 0xcdcc, 0xcdce, 0xaaf0, + 0xcdd1, 0xcdd0, 0xcdd2, 0xd0b6, 0xd0b4, 0xad7c, 0xd0b3, 0xada3, + 0xad7e, 0xad7b, 0xada4, 0xad7d, 0xada2, 0xada1, 0xd0b5, 0xad7a, + 0xb06a, 0xd3eb, 0xd3f1, 0xb067, 0xb06e, 0xb069, 0xd3ee, 0xd3f0, + 0xb06c, 0xd3ea, 0xd3ed, 0xb068, 0xb065, 0xd3ec, 0xb06b, 0xd3ef, + 0xb06d, 0xb066, 0xd7e3, 0xd7e6, 0xb370, 0xb37a, 0xb376, 0xd7e4, + 0xb37e, 0xb377, 0xb37c, 0xb372, 0xb36f, 0xb371, 0xb37d, 0xd7e5, + 0xb375, 0xb378, 0xb374, 0xb379, 0xd7e7, 0xb37b, 0xb373, 0xd7e2, + 0xdc4d, 0xb665, 0xdc4f, 0xb667, 0xb669, 0xdc4e, 0xb666, 0xb66a, + 0xb668, 0xb947, 0xe0a3, 0xb94f, 0xe07e, 0xb950, 0xb945, 0xe0a1, + 0xb94a, 0xe0a2, 0xb943, 0xb942, 0xb94d, 0xb94c, 0xb94b, 0xb949, + 0xb94e, 0xe07d, 0xb944, 0xb946, 0xb948, 0xbbb8, 0xbbbb, 0xbbbf, + 0xbbb9, 0xbbbe, 0xbbbc, 0xbbb7, 0xbbbd, 0xbbba, 0xe852, 0xbe43, + 0xbe41, 0xe853, 0xbe44, 0xbe42, 0xe851, 0xe850, 0xbff0, 0xe84f, + 0xbfee, 0xbfed, 0xebd0, 0xbe45, 0xbfef, 0xebd1, 0xbff2, 0xebd2, + 0xbff1, 0xc1d8, 0xeec3, 0xc1d7, 0xc1dc, 0xc1da, 0xc1db, 0xc2e3, + 0xc1d9, 0xeec2, 0xebd3, 0xc2e2, 0xc2e4, 0xc3e4, 0xc3e5, 0xf4e0, + 0xc5de, 0xc5dd, 0xa8b6, 0xca55, 0xb06f, 0xca52, 0xca53, 0xca51, + 0xca54, 0xcbaa, 0xcba7, 0xcbac, 0xcba8, 0xa8b7, 0xa8ba, 0xcba9, + 0xa8b9, 0xcbab, 0xa8b8, 0xcdd5, 0xcdd7, 0xaaf4, 0xcdd3, 0xcdd6, + 0xcdd4, 0xaaf2, 0xaaf5, 0xaaf3, 0xd0b8, 0xd0bc, 0xd0b9, 0xada7, + 0xada8, 0xd0bb, 0xd0bd, 0xd0bf, 0xada5, 0xd0be, 0xada6, 0xd7ee, + 0xd0ba, 0xd3f2, 0xd3fb, 0xd3f9, 0xd3f4, 0xd3f5, 0xd3fa, 0xd3fc, + 0xb071, 0xd3f7, 0xd3f3, 0xb070, 0xb072, 0xd3f6, 0xd3fd, 0xd3f8, + 0xb3a1, 0xd7f1, 0xd7e9, 0xd7ef, 0xd7f0, 0xb3a2, 0xd7e8, 0xd7ea, + 0xd0b7, 0xd7ec, 0xd7ed, 0xd7eb, 0xb66c, 0xdc56, 0xebd4, 0xdc57, + 0xdc54, 0xb3a3, 0xb66e, 0xdc53, 0xdc59, 0xdc58, 0xb66b, 0xdc5c, + 0xdc52, 0xdc5b, 0xdc50, 0xdc5a, 0xdc55, 0xb66d, 0xe0aa, 0xe0a5, + 0xe0ab, 0xe0a6, 0xe0a4, 0xe0a7, 0xb951, 0xe0a9, 0xe0a8, 0xb952, + 0xbbc1, 0xbbc0, 0xe46e, 0xe471, 0xe469, 0xe46d, 0xbbc2, 0xe46c, + 0xe46a, 0xe470, 0xe46b, 0xe468, 0xe46f, 0xe859, 0xbe48, 0xf14a, + 0xe856, 0xe857, 0xe855, 0xdc51, 0xbe47, 0xe85a, 0xe854, 0xbe46, + 0xbe49, 0xe858, 0xebd5, 0xbff3, 0xebd6, 0xebd7, 0xeec4, 0xc1dd, + 0xf14b, 0xf14c, 0xf14d, 0xf35d, 0xf35c, 0xf4e2, 0xf4e1, 0xf65b, + 0xf65c, 0xf65a, 0xf766, 0xc5b0, 0xa8bb, 0xadaa, 0xada9, 0xb075, + 0xb074, 0xd440, 0xd441, 0xd3fe, 0xb073, 0xd7f5, 0xd7f6, 0xd7f2, + 0xb3a4, 0xd7f3, 0xd7f4, 0xdc5f, 0xdc61, 0xdc5d, 0xdc60, 0xb66f, + 0xdc5e, 0xb670, 0xdd73, 0xb955, 0xb954, 0xb953, 0xe0ac, 0xe0ad, + 0xe473, 0xe475, 0xbbc6, 0xbbc3, 0xbbc5, 0xbbc4, 0xe474, 0xe472, + 0xe861, 0xe85e, 0xe85f, 0xbe4d, 0xe860, 0xe85b, 0xe85c, 0xbe4a, + 0xbe4b, 0xe85d, 0xbe4c, 0xebdb, 0xebdc, 0xebd9, 0xebda, 0xbff4, + 0xebd8, 0xeec8, 0xeec5, 0xeec7, 0xc1e0, 0xeecb, 0xc1df, 0xeec9, + 0xeecc, 0xeeca, 0xeec6, 0xc1de, 0xf14f, 0xf150, 0xf14e, 0xf152, + 0xc2e5, 0xc2e6, 0xf35f, 0xc3e7, 0xf151, 0xf35e, 0xc3e6, 0xf4e5, + 0xf4e6, 0xc4bf, 0xf4e4, 0xf4e3, 0xf65d, 0xc548, 0xf849, 0xf8c8, + 0xf8c7, 0xc643, 0xc65d, 0xf8c9, 0xf971, 0xc66f, 0xa8bc, 0xaaf6, + 0xb956, 0xc4c0, 0xa8bd, 0xadab, 0xb3a5, 0xb671, 0xc2e7, 0xaaf7, + 0xd0c1, 0xd0c0, 0xd442, 0xb078, 0xb076, 0xb07a, 0xd444, 0xb079, + 0xb077, 0xd443, 0xb3a8, 0xd7fc, 0xb3a7, 0xb3a9, 0xd842, 0xb3ab, + 0xd7fe, 0xd840, 0xd7f7, 0xb3aa, 0xd843, 0xd7f9, 0xd7fa, 0xd7f8, + 0xb3a6, 0xd841, 0xd7fb, 0xd7fd, 0xdc6d, 0xdc6c, 0xdc6a, 0xdc62, + 0xdc71, 0xdc65, 0xdc6f, 0xdc76, 0xdc6e, 0xb679, 0xb675, 0xdc63, + 0xdc69, 0xb677, 0xdc68, 0xb678, 0xb67a, 0xdc6b, 0xb672, 0xb673, + 0xdc77, 0xdc75, 0xdc74, 0xdc66, 0xdc72, 0xb676, 0xb674, 0xdc73, + 0xdc64, 0xdc67, 0xdc70, 0xe4ba, 0xe0b7, 0xe0b0, 0xe0c3, 0xe0cc, + 0xe0b3, 0xb961, 0xe0c0, 0xb957, 0xb959, 0xb965, 0xe0b1, 0xb95a, + 0xb95c, 0xb966, 0xb95b, 0xb964, 0xe0b9, 0xe0ae, 0xb962, 0xe0b8, + 0xb95e, 0xe0ca, 0xb963, 0xe0c8, 0xe0bc, 0xe0c6, 0xb960, 0xe0af, + 0xe0c9, 0xe0c4, 0xe0cb, 0xb958, 0xb967, 0xb95d, 0xe0b5, 0xe0bd, + 0xe0c1, 0xe0c5, 0xb95f, 0xe0b4, 0xe0b2, 0xe0be, 0xe0bb, 0xe0ba, + 0xe0bf, 0xe0c2, 0xe0c7, 0xe478, 0xbbc7, 0xe4a4, 0xe47a, 0xbbcc, + 0xbbd0, 0xe4ad, 0xe4b5, 0xe4a6, 0xbbc8, 0xe4aa, 0xe0b6, 0xbbc9, + 0xe4b1, 0xe4b6, 0xe4ae, 0xe4b0, 0xe4b9, 0xe4b2, 0xe47e, 0xe4a9, + 0xbbd1, 0xbbcd, 0xe47c, 0xe4ab, 0xbbcb, 0xe4a5, 0xbbca, 0xe4b3, + 0xe4a2, 0xe479, 0xbbce, 0xe4b8, 0xe47b, 0xe4af, 0xe4ac, 0xe4a7, + 0xe477, 0xe476, 0xe4a1, 0xe4b4, 0xbbcf, 0xe4b7, 0xe47d, 0xe4a3, + 0xbe52, 0xbe5a, 0xbe55, 0xe8a4, 0xe8a1, 0xe867, 0xbe50, 0xbe4f, + 0xbe56, 0xe865, 0xbe54, 0xe871, 0xe863, 0xe864, 0xbe4e, 0xe8a3, + 0xbe58, 0xe874, 0xe879, 0xe873, 0xebee, 0xe86f, 0xe877, 0xe875, + 0xe868, 0xe862, 0xe87d, 0xbe57, 0xe87e, 0xe878, 0xe86d, 0xe86b, + 0xe866, 0xe86e, 0xe87b, 0xe86a, 0xe87a, 0xe8a2, 0xbe53, 0xe876, + 0xe87c, 0xe872, 0xe86c, 0xbe51, 0xe4a8, 0xe870, 0xbe59, 0xe869, + 0xebf4, 0xbff7, 0xebf3, 0xebf0, 0xec44, 0xbffb, 0xec41, 0xebf8, + 0xec43, 0xebe9, 0xebf6, 0xbffd, 0xebe1, 0xebdf, 0xec42, 0xec40, + 0xebfe, 0xebed, 0xebec, 0xebe2, 0xc040, 0xebe8, 0xebf2, 0xebfd, + 0xc043, 0xec45, 0xc1e8, 0xc045, 0xbffe, 0xebe6, 0xebef, 0xebde, + 0xebe0, 0xbff5, 0xc042, 0xbffa, 0xebe7, 0xebf7, 0xebf1, 0xc041, + 0xebdd, 0xc1e3, 0xebf9, 0xebfc, 0xbffc, 0xebeb, 0xc044, 0xbff9, + 0xbff8, 0xebf5, 0xebfb, 0xbff6, 0xebe4, 0xebfa, 0xebe5, 0xebea, + 0xeed2, 0xeed7, 0xc1e5, 0xc1e7, 0xeedd, 0xc1e1, 0xeeec, 0xeee3, + 0xeed8, 0xeed9, 0xeee2, 0xc1ee, 0xeee1, 0xeed1, 0xeee0, 0xeed4, + 0xeeed, 0xc1ed, 0xc1eb, 0xeed5, 0xeee8, 0xeeda, 0xeee7, 0xeee9, + 0xeed0, 0xc1e6, 0xeeea, 0xeede, 0xc1ea, 0xeedb, 0xc1ec, 0xeee4, + 0xc1e4, 0xeed6, 0xeee5, 0xeedf, 0xebe3, 0xeee6, 0xeed3, 0xc1e9, + 0xeeeb, 0xc1e2, 0xeece, 0xf160, 0xf159, 0xc2e9, 0xf154, 0xf163, + 0xf15b, 0xeedc, 0xf165, 0xf155, 0xc2e8, 0xf15f, 0xc2ea, 0xc2f2, + 0xc2f0, 0xf161, 0xc2f1, 0xf157, 0xf158, 0xf15d, 0xf162, 0xeecd, + 0xc2eb, 0xf16a, 0xf167, 0xf16b, 0xf15e, 0xf15a, 0xf168, 0xf36a, + 0xf15c, 0xc2ee, 0xc2ed, 0xeecf, 0xc2ef, 0xf164, 0xf166, 0xc2ec, + 0xf169, 0xf153, 0xf156, 0xf373, 0xf363, 0xc3eb, 0xf371, 0xf361, + 0xc3ec, 0xf36c, 0xf368, 0xc3f1, 0xf372, 0xf362, 0xf365, 0xc3e9, + 0xf374, 0xf36d, 0xf370, 0xc3ef, 0xc3f4, 0xc3f2, 0xf369, 0xf364, + 0xc3ed, 0xc3ee, 0xf360, 0xc3ea, 0xc3e8, 0xc3f0, 0xf36f, 0xc3f3, + 0xf36b, 0xf375, 0xc3f5, 0xf367, 0xf36e, 0xf4f3, 0xf542, 0xf4f5, + 0xf4fc, 0xf366, 0xf4fa, 0xf4e9, 0xf540, 0xc4c3, 0xf4ed, 0xf4fe, + 0xf4f4, 0xc4c2, 0xf544, 0xf4f6, 0xf4fb, 0xf4fd, 0xf4e7, 0xf541, + 0xf4f2, 0xf4f7, 0xf4eb, 0xf4ef, 0xf543, 0xf4f9, 0xf4e8, 0xf4ec, + 0xf4ee, 0xf4f8, 0xc4c1, 0xf4f1, 0xf4ea, 0xf4f0, 0xf661, 0xf666, + 0xc54f, 0xf668, 0xc549, 0xf664, 0xf66a, 0xc54e, 0xc54a, 0xc54b, + 0xf660, 0xf667, 0xc54d, 0xf665, 0xc54c, 0xf65f, 0xf663, 0xf662, + 0xf65e, 0xf669, 0xc5b1, 0xf76d, 0xf770, 0xf76c, 0xf76e, 0xf76f, + 0xf769, 0xf76a, 0xf767, 0xf76b, 0xf768, 0xc5b2, 0xc5b3, 0xf84b, + 0xf84d, 0xf84c, 0xf84e, 0xc5e0, 0xf84a, 0xc5df, 0xc5e1, 0xf8cb, + 0xf8cc, 0xc644, 0xf8ca, 0xf953, 0xf952, 0xf954, 0xc65f, 0xf955, + 0xc65e, 0xf956, 0xf972, 0xf975, 0xf974, 0xc668, 0xf973, 0xc672, + 0xc670, 0xc671, 0xc677, 0xf9c0, 0xf9c1, 0xf9bf, 0xf9c9, 0xaaf8, + 0xd844, 0xdc78, 0xe8a5, 0xf376, 0xaaf9, 0xadac, 0xb07b, 0xd845, + 0xd846, 0xb3ac, 0xb67d, 0xdc7a, 0xdc79, 0xb6a3, 0xb67c, 0xdc7b, + 0xb67e, 0xb6a2, 0xb6a1, 0xb67b, 0xb968, 0xe0d0, 0xe0ce, 0xe0cf, + 0xe0cd, 0xbbd2, 0xbbd5, 0xbbd7, 0xbbd6, 0xbbd3, 0xbbd4, 0xe8a7, + 0xe8a6, 0xbe5b, 0xe8a8, 0xe8a9, 0xbe5c, 0xec4d, 0xec4b, 0xeef3, + 0xec49, 0xec4a, 0xc046, 0xec46, 0xec4e, 0xec48, 0xec4c, 0xeeef, + 0xeef1, 0xeef2, 0xc1f3, 0xeeee, 0xc1f2, 0xeef0, 0xc1ef, 0xc1f0, + 0xc1f1, 0xec47, 0xc2f5, 0xf16e, 0xf16c, 0xf16d, 0xc2f3, 0xc2f6, + 0xc2f4, 0xf377, 0xf378, 0xc3f6, 0xf545, 0xf547, 0xf546, 0xc4c4, + 0xc550, 0xf66d, 0xf66c, 0xf66b, 0xaafa, 0xc9aa, 0xca58, 0xa6e9, + 0xca56, 0xca59, 0xca57, 0xcbae, 0xa8c1, 0xa8c2, 0xcbb0, 0xa8bf, + 0xcbaf, 0xcbad, 0xa8c0, 0xa8be, 0xcdd8, 0xcddb, 0xaafd, 0xcdda, + 0xcdd9, 0xaafc, 0xaafb, 0xab40, 0xcddc, 0xaafe, 0xd0c6, 0xadae, + 0xadaf, 0xadb0, 0xd0c7, 0xd0c3, 0xadad, 0xd0c4, 0xd0c5, 0xd0c2, + 0xb0a4, 0xb0a1, 0xd445, 0xb0a2, 0xb0a5, 0xd446, 0xb07e, 0xb07c, + 0xb07d, 0xb0a3, 0xb3ad, 0xd849, 0xb3b5, 0xd848, 0xd84b, 0xb3b1, + 0xd84a, 0xb6ab, 0xb3af, 0xb3b2, 0xb3ae, 0xb3b3, 0xb3b4, 0xb3b0, + 0xd847, 0xb6a7, 0xdc7d, 0xdca3, 0xdca2, 0xb6ac, 0xb6a8, 0xb6a9, + 0xdc7c, 0xdc7e, 0xdca1, 0xb6a4, 0xb6a6, 0xb6aa, 0xb6a5, 0xe0d3, + 0xe0d1, 0xe0d2, 0xb96a, 0xb96b, 0xe0d4, 0xb969, 0xbbd8, 0xbbda, + 0xbbd9, 0xe4bb, 0xe4bc, 0xe8ab, 0xe8aa, 0xc047, 0xc048, 0xec4f, + 0xc049, 0xeef6, 0xeef4, 0xeef5, 0xc1f4, 0xf16f, 0xc3f7, 0xc1f5, + 0xab41, 0xb0a6, 0xd447, 0xd84c, 0xb3b6, 0xb6ad, 0xdca4, 0xdca6, + 0xb6af, 0xb6ae, 0xb6b0, 0xb6b1, 0xdca5, 0xb96e, 0xb96f, 0xb96d, + 0xbbdb, 0xb96c, 0xe0d5, 0xbbdc, 0xe8ac, 0xec50, 0xc04a, 0xc1f6, + 0xf170, 0xf174, 0xc2f9, 0xf171, 0xc2fa, 0xc2f8, 0xf175, 0xc2fb, + 0xf173, 0xf379, 0xc2f7, 0xc3f8, 0xf8cd, 0xab42, 0xb3b8, 0xb3b7, + 0xb6b2, 0xdca8, 0xdca7, 0xb6b3, 0xe0d9, 0xb973, 0xb970, 0xe0d8, + 0xb972, 0xe0d6, 0xb971, 0xe0d7, 0xe4bd, 0xbbdd, 0xe8af, 0xbe5d, + 0xe8ad, 0xbe5e, 0xbe5f, 0xe8ae, 0xbe60, 0xec51, 0xc04e, 0xc04b, + 0xc050, 0xec53, 0xc04c, 0xec52, 0xc04f, 0xc04d, 0xeef9, 0xeefb, + 0xc1f7, 0xeefa, 0xc1f8, 0xeef8, 0xeef7, 0xf177, 0xf176, 0xc2fc, + 0xf178, 0xf37e, 0xc3fa, 0xf37d, 0xf37a, 0xc3f9, 0xf37b, 0xf37c, + 0xf548, 0xf549, 0xc4c5, 0xc553, 0xf66e, 0xc551, 0xc552, 0xf66f, + 0xc5b4, 0xc5b5, 0xf771, 0xc645, 0xf8cf, 0xc647, 0xf8ce, 0xf8d0, + 0xc646, 0xf957, 0xf9ad, 0xab43, 0xb974, 0xe4be, 0xe8b0, 0xc051, + 0xc052, 0xab44, 0xbe61, 0xc3fb, 0xadb1, 0xc053, 0xc5e2, 0xadb2, + 0xd84d, 0xdca9, 0xdcab, 0xdcaa, 0xe0dd, 0xe0da, 0xb975, 0xb976, + 0xe0db, 0xe0dc, 0xe4c0, 0xe4c5, 0xbbde, 0xe4bf, 0xe4c1, 0xe4c8, + 0xe4c3, 0xe4c7, 0xe4c4, 0xe4c2, 0xe4c6, 0xbbdf, 0xe8b3, 0xe8b1, + 0xbe63, 0xbe62, 0xe8b2, 0xbe64, 0xec56, 0xec55, 0xc054, 0xec54, + 0xeefc, 0xeefe, 0xef41, 0xef40, 0xc1f9, 0xeefd, 0xf1a1, 0xc2fd, + 0xf17d, 0xf1a2, 0xc2fe, 0xf17b, 0xf17e, 0xf17c, 0xf179, 0xc340, + 0xf17a, 0xf3a1, 0xf3a3, 0xf3a2, 0xf54a, 0xf54b, 0xf670, 0xc5b7, + 0xc5b6, 0xf84f, 0xf850, 0xc648, 0xf8d1, 0xc669, 0xadb3, 0xb6b4, + 0xe4ca, 0xe4c9, 0xe8b5, 0xe8b4, 0xc1fa, 0xef43, 0xef42, 0xf1a5, + 0xf1a3, 0xf1a6, 0xf1a4, 0xc3fc, 0xf3a4, 0xf3a5, 0xf3a6, 0xf671, + 0xf772, 0xf8d2, 0xadb4, 0xec57, 0xef44, 0xadb5, 0xbbe0, 0xec58, + 0xc341, 0xf1a7, 0xc3fd, 0xf54c, 0xf54d, 0xc554, 0xf851, 0xadb6, + 0xb3bb, 0xb3bc, 0xd84e, 0xb6b5, 0xb6b6, 0xdcac, 0xb6b7, 0xb97a, + 0xb97c, 0xe0df, 0xe0e0, 0xe0de, 0xb977, 0xb978, 0xb97b, 0xb979, + 0xe4cb, 0xbbe1, 0xbbe2, 0xe8bc, 0xbe67, 0xe8b7, 0xe8b6, 0xe8bb, + 0xbe65, 0xc05b, 0xe8b8, 0xe8bd, 0xe8ba, 0xe8b9, 0xbe66, 0xc059, + 0xec5a, 0xc055, 0xec5b, 0xec59, 0xc058, 0xc056, 0xc05a, 0xc057, + 0xef45, 0xef4a, 0xef46, 0xef49, 0xc1fb, 0xedd4, 0xef48, 0xef47, + 0xc344, 0xc342, 0xc345, 0xc343, 0xf1a8, 0xf1a9, 0xf1aa, 0xc346, + 0xf3aa, 0xc440, 0xf3a8, 0xc441, 0xf3a7, 0xf3a9, 0xc3fe, 0xf551, + 0xf54e, 0xf54f, 0xf550, 0xf672, 0xc556, 0xc555, 0xf774, 0xf773, + 0xc5b8, 0xc5e3, 0xc649, 0xc660, 0xf958, 0xf9ae, 0xf9af, 0xadb7, + 0xdcad, 0xe0e1, 0xe4cc, 0xe4cd, 0xbbe3, 0xbbe4, 0xe8be, 0xbe68, + 0xc1fc, 0xf1ab, 0xc347, 0xf3ad, 0xc442, 0xf3ac, 0xf3ae, 0xf3ab, + 0xf675, 0xf552, 0xf553, 0xc4c6, 0xf674, 0xf673, 0xf775, 0xf9b0, + 0xadb8, 0xadb9, 0xb0a7, 0xd448, 0xd84f, 0xb6b8, 0xb6bb, 0xb6b9, + 0xdcae, 0xb6bd, 0xb6ba, 0xb6bc, 0xb97e, 0xe0e2, 0xe0e3, 0xe8c0, + 0xb97d, 0xb9a1, 0xb9a2, 0xe4cf, 0xe4ce, 0xbbe5, 0xbbe6, 0xe4d0, + 0xe8bf, 0xbbe8, 0xbe69, 0xbbe7, 0xc05c, 0xe8c1, 0xbe6b, 0xbe6a, + 0xe8c2, 0xe8c5, 0xe8c3, 0xe8c4, 0xbe6c, 0xc061, 0xc05f, 0xc05e, + 0xec5d, 0xc060, 0xec5c, 0xef4b, 0xec5e, 0xc05d, 0xec5f, 0xef4e, + 0xef4c, 0xef4d, 0xef52, 0xc34b, 0xef51, 0xef54, 0xef53, 0xef50, + 0xef4f, 0xc1fd, 0xf1ae, 0xf1ad, 0xc34a, 0xc348, 0xc349, 0xf1ac, + 0xf3b1, 0xc443, 0xf3b0, 0xf3af, 0xc444, 0xf558, 0xf557, 0xf555, + 0xf554, 0xc4c8, 0xc4c7, 0xf559, 0xf776, 0xc5b9, 0xf677, 0xc557, + 0xf676, 0xf556, 0xf777, 0xc5e4, 0xc661, 0xf959, 0xf9b1, 0xadba, + 0xd850, 0xef55, 0xadbb, 0xe4d2, 0xe4d1, 0xec60, 0xef57, 0xef56, + 0xc34c, 0xf3b2, 0xf3b3, 0xc4c9, 0xf9b2, 0xb0a8, 0xb6bf, 0xb6be, + 0xe0e4, 0xe0e6, 0xb9a4, 0xe0e5, 0xb9a3, 0xb9a5, 0xe0e7, 0xe4d4, + 0xe4d6, 0xe4d5, 0xe4d8, 0xbbe9, 0xe4d7, 0xe4d3, 0xe4d9, 0xe8cc, + 0xe8cf, 0xe8d1, 0xe8c7, 0xe8cb, 0xe8c8, 0xbe6e, 0xbe71, 0xbe73, + 0xe8c9, 0xe8ca, 0xbe72, 0xe8cd, 0xe8d0, 0xe8ce, 0xbe74, 0xbe70, + 0xe8c6, 0xbe6d, 0xbe6f, 0xc063, 0xec66, 0xec64, 0xec63, 0xec69, + 0xec68, 0xec67, 0xec62, 0xc062, 0xec61, 0xec65, 0xc064, 0xef5a, + 0xef5e, 0xef5b, 0xef5d, 0xef5c, 0xef59, 0xef5f, 0xef62, 0xef60, + 0xef61, 0xc240, 0xc1fe, 0xef58, 0xef63, 0xf1b3, 0xf1b6, 0xf1b8, + 0xf1b7, 0xf1b1, 0xf1b5, 0xf1b0, 0xf1b2, 0xc34d, 0xf1af, 0xf1b4, + 0xf3c0, 0xf3b5, 0xc445, 0xc446, 0xf3b4, 0xf3b9, 0xf3bf, 0xf3b7, + 0xf3be, 0xf3bb, 0xf3ba, 0xf3bd, 0xf3b8, 0xf3b6, 0xf3bc, 0xf560, + 0xf55e, 0xc4ca, 0xf55d, 0xf563, 0xf561, 0xc4cb, 0xf55c, 0xf55a, + 0xf55b, 0xc4cd, 0xf55f, 0xc4cc, 0xf562, 0xf678, 0xf67e, 0xf679, + 0xc55b, 0xf6a1, 0xc55a, 0xf67d, 0xf67c, 0xc559, 0xf67b, 0xc558, + 0xf67a, 0xf77d, 0xf7a1, 0xf77e, 0xf77b, 0xc5bb, 0xf778, 0xf77c, + 0xf7a3, 0xf7a2, 0xf779, 0xf77a, 0xc5ba, 0xf852, 0xc5e7, 0xf853, + 0xc5e5, 0xc5e6, 0xf8d3, 0xc64a, 0xf976, 0xc66a, 0xf9b3, 0xc66b, + 0xf9b4, 0xf9b5, 0xf9c3, 0xf9c2, 0xc67a, 0xf9cd, 0xb0a9, 0xe0e9, + 0xe0e8, 0xbbea, 0xbbeb, 0xe4da, 0xe8d2, 0xec6c, 0xbe75, 0xc065, + 0xec6a, 0xec6d, 0xc066, 0xef64, 0xec6b, 0xf1b9, 0xc34e, 0xf3c1, + 0xf566, 0xf564, 0xf565, 0xf6a2, 0xc55c, 0xf7a4, 0xc5ea, 0xc5bc, + 0xc5e8, 0xc5e9, 0xf8d4, 0xc662, 0xb0aa, 0xf1ba, 0xd449, 0xb9a6, + 0xe4db, 0xbbec, 0xe4dc, 0xe8d4, 0xe8d3, 0xc068, 0xbe76, 0xbe77, + 0xe8d7, 0xe8d6, 0xe8d5, 0xec6e, 0xec71, 0xec70, 0xec6f, 0xc067, + 0xef68, 0xef66, 0xef65, 0xef67, 0xc34f, 0xf1bc, 0xf1bd, 0xc350, + 0xf1bb, 0xf3c3, 0xf3c2, 0xf3c5, 0xc447, 0xf3c4, 0xf567, 0xf569, + 0xf568, 0xf6a3, 0xf6a6, 0xf6a4, 0xf6a5, 0xf7a5, 0xc5bd, 0xf854, + 0xf855, 0xf856, 0xc64b, 0xc663, 0xf9b6, 0xb0ab, 0xbe78, 0xc069, + 0xf1be, 0xf7a6, 0xf9c4, 0xd44a, 0xc67b, 0xb0ac, 0xec72, 0xf1bf, + 0xf3c6, 0xf6a7, 0xf7a7, 0xb0ad, 0xe4dd, 0xe4de, 0xbbed, 0xbbee, + 0xe8d9, 0xbe7a, 0xbe79, 0xe8d8, 0xef69, 0xf1c0, 0xf1c2, 0xf1c1, + 0xc353, 0xc352, 0xc351, 0xc55e, 0xf6a8, 0xc55d, 0xf7a9, 0xf7a8, + 0xc64c, 0xf8d5, 0xb3bd, 0xe0ea, 0xe4e1, 0xe4df, 0xe4e0, 0xe8e2, + 0xe8dd, 0xe8da, 0xe8e1, 0xe8e3, 0xbe7c, 0xe8e0, 0xe8dc, 0xe8db, + 0xe8df, 0xe8de, 0xbe7b, 0xec7d, 0xec78, 0xec76, 0xeca1, 0xec77, + 0xec73, 0xec79, 0xec74, 0xef72, 0xec75, 0xeca2, 0xec7c, 0xc06a, + 0xec7b, 0xec7a, 0xec7e, 0xef6a, 0xef6d, 0xef6c, 0xef74, 0xef6f, + 0xef73, 0xef71, 0xef70, 0xef6e, 0xef6b, 0xc243, 0xc242, 0xc244, + 0xc241, 0xef75, 0xf1c8, 0xf1cb, 0xf1c9, 0xf1cd, 0xf1ce, 0xf1c6, + 0xc358, 0xf1c7, 0xf1c5, 0xf1cc, 0xf1c4, 0xf1c3, 0xc357, 0xc355, + 0xc354, 0xf1ca, 0xf3cf, 0xf3d5, 0xc44a, 0xf3d0, 0xf3d3, 0xf3d7, + 0xc44b, 0xf3d2, 0xf3ca, 0xf3c9, 0xf3d6, 0xf3cd, 0xf3cb, 0xf3d4, + 0xf3cc, 0xc449, 0xc448, 0xf3c7, 0xf3c8, 0xf3d1, 0xf3ce, 0xf56c, + 0xf56f, 0xc356, 0xf56d, 0xf573, 0xf571, 0xf56b, 0xf576, 0xf56a, + 0xc4cf, 0xf572, 0xf56e, 0xc4ce, 0xf575, 0xf574, 0xf6ab, 0xf6aa, + 0xf6b1, 0xf6ad, 0xf6b0, 0xc560, 0xf6ae, 0xf6af, 0xf6a9, 0xf6ac, + 0xc55f, 0xc5bf, 0xf7b4, 0xf7af, 0xf7b3, 0xf7b6, 0xf7b2, 0xf7ae, + 0xc5c1, 0xf7b1, 0xf7b5, 0xc5c0, 0xf7ac, 0xf570, 0xf7b0, 0xf7ad, + 0xf7aa, 0xf7ab, 0xc5be, 0xf85a, 0xf85c, 0xf85f, 0xf85b, 0xf860, + 0xf859, 0xf857, 0xc5eb, 0xf85d, 0xc5ed, 0xc5ec, 0xf858, 0xf85e, + 0xf8da, 0xc64d, 0xf8db, 0xf8d9, 0xf8d6, 0xf8d8, 0xf8d7, 0xf95a, + 0xf95c, 0xf95b, 0xf979, 0xf978, 0xf977, 0xf97a, 0xc673, 0xc674, + 0xf9ca, 0xf9ce, 0xb3be, 0xdcaf, 0xe0ed, 0xb9a7, 0xe0eb, 0xe0ec, + 0xe4e2, 0xe4e3, 0xbbf1, 0xbbef, 0xe4e4, 0xbbf0, 0xe8e8, 0xe8eb, + 0xe8e5, 0xe8ec, 0xe8e4, 0xe8e6, 0xe8e7, 0xe8ea, 0xbea1, 0xe8ef, + 0xe8ee, 0xbe7d, 0xe8e9, 0xe8ed, 0xbe7e, 0xecac, 0xc06f, 0xeca7, + 0xc06b, 0xeca4, 0xecaa, 0xecad, 0xc070, 0xeca9, 0xeca6, 0xecae, + 0xeca5, 0xecab, 0xc06c, 0xeca3, 0xc06d, 0xc06e, 0xeca8, 0xefa9, + 0xef7a, 0xef7b, 0xef7e, 0xef7c, 0xef76, 0xef79, 0xefa5, 0xef7d, + 0xc245, 0xefa7, 0xefa4, 0xc246, 0xefa6, 0xef77, 0xefa2, 0xefa3, + 0xefa1, 0xf1d2, 0xf1d4, 0xf1d7, 0xf1d1, 0xc359, 0xf1d9, 0xf1d0, + 0xf1da, 0xf1d6, 0xf1d8, 0xf1dc, 0xf1d5, 0xf1dd, 0xf1d3, 0xf1cf, + 0xc35a, 0xf1db, 0xc35b, 0xc44d, 0xef78, 0xf3f1, 0xf3e8, 0xc44f, + 0xf3e4, 0xc450, 0xf3ed, 0xf3e7, 0xf3dd, 0xc44e, 0xf3ea, 0xf3e5, + 0xf3e6, 0xf3d8, 0xf3df, 0xf3ee, 0xf3eb, 0xf3e3, 0xf3ef, 0xf3de, + 0xf3d9, 0xf3ec, 0xf3db, 0xf3e9, 0xf3e0, 0xf3f0, 0xf3dc, 0xc44c, + 0xf3da, 0xf3e1, 0xf3e2, 0xf57d, 0xf57b, 0xf5a2, 0xf5ae, 0xf5a5, + 0xf57c, 0xf578, 0xf5a7, 0xf57e, 0xf5a3, 0xf57a, 0xf5aa, 0xf577, + 0xf5a1, 0xf5a6, 0xf5a8, 0xf5ab, 0xf579, 0xf5af, 0xf5b0, 0xf5a9, + 0xf5ad, 0xf5a4, 0xf6c1, 0xf6c4, 0xc561, 0xf6c3, 0xf6c8, 0xf6c6, + 0xc562, 0xf6bd, 0xf6b3, 0xf6b2, 0xc564, 0xf6bf, 0xf6c0, 0xf6bc, + 0xf6b4, 0xf6b9, 0xf5ac, 0xf6b5, 0xc563, 0xf6bb, 0xf6ba, 0xf6b6, + 0xf6c2, 0xf6b7, 0xf7bb, 0xf6c5, 0xf6c7, 0xf6be, 0xf6b8, 0xf7bc, + 0xf7be, 0xf7b8, 0xc5c2, 0xf7c5, 0xf7c3, 0xc5c3, 0xf7c2, 0xf7c1, + 0xf7ba, 0xf7b7, 0xf7bd, 0xf7c6, 0xf7b9, 0xf7bf, 0xf869, 0xf86e, + 0xf864, 0xf867, 0xc5ee, 0xf86b, 0xf872, 0xf7c0, 0xf865, 0xf86f, + 0xf873, 0xf86a, 0xf863, 0xf86d, 0xf86c, 0xf871, 0xf870, 0xf7c4, + 0xf868, 0xf862, 0xf866, 0xc64e, 0xc64f, 0xf861, 0xf8e6, 0xf8dd, + 0xf8e5, 0xf8e2, 0xf8e3, 0xf8dc, 0xf8df, 0xf8e7, 0xf8e1, 0xf8e0, + 0xf8de, 0xf8e4, 0xf95d, 0xf95e, 0xf960, 0xf95f, 0xf962, 0xf961, + 0xf97c, 0xf97b, 0xf9b7, 0xf9b8, 0xf9c5, 0xc678, 0xc67c, 0xf9cf, + 0xc67d, 0xb3bf, 0xc4d0, 0xf6c9, 0xc650, 0xc651, 0xb3c0, 0xe0ee, + 0xb9a8, 0xe8f0, 0xecb0, 0xecb1, 0xecaf, 0xefab, 0xefaa, 0xc247, + 0xf1df, 0xefac, 0xf1de, 0xf3f3, 0xc451, 0xc453, 0xf3f2, 0xc452, + 0xf5b1, 0xf5b3, 0xf5b2, 0xf6ca, 0xc565, 0xc5ef, 0xf8e8, 0xf963, + 0xf9d2, 0xb3c1, 0xe4e5, 0xbea2, 0xecb3, 0xecb2, 0xefad, 0xc454, + 0xc4d1, 0xf7c7, 0xf9cb, 0xb3c2, 0xbbf2, 0xbea3, 0xf3f4, 0xf874, + 0xb6c0, 0xefae, 0xc664, 0xb6c1, 0xbea4, 0xc248, 0xf875, 0xb6c2, + 0xe8f1, 0xc072, 0xecb4, 0xecb5, 0xc071, 0xefaf, 0xc24c, 0xc24a, + 0xc24b, 0xc249, 0xf1e0, 0xc35c, 0xf5b5, 0xf5b4, 0xf5b7, 0xf5b6, + 0xc4d2, 0xf6cb, 0xf6cd, 0xf6cc, 0xc566, 0xf7c8, 0xf876, 0xf877, + 0xc5f0, 0xf964, 0xf97d, 0xc675, 0xdcb0, 0xecb6, 0xefb0, 0xf3f5, + 0xe0ef, 0xefb1, 0xf1e2, 0xf1e1, 0xf878, 0xc652, 0xf965, 0xf97e, + 0xb9a9, 0xe8f2, 0xe8f3, 0xecb7, 0xb9aa, 0xc35d, 0xf1e3, 0xf6cf, + 0xc567, 0xf6d0, 0xf6ce, 0xf879, 0xf8e9, 0xb9ab, 0xefb4, 0xefb3, + 0xefb2, 0xf1e4, 0xf1e8, 0xf1e7, 0xf1e6, 0xf1e5, 0xc35e, 0xf3f6, + 0xf5b9, 0xc4d3, 0xf5b8, 0xf6d1, 0xf7cb, 0xf7ca, 0xc5c4, 0xf7c9, + 0xf87c, 0xf87b, 0xf87a, 0xbbf3, 0xecb8, 0xc24d, 0xf3f7, 0xf3f8, + 0xf7cc, 0xf87d, 0xf8ea, 0xf966, 0xf9b9, 0xf9d4, 0xbbf4, 0xc24e, + 0xf1e9, 0xf3f9, 0xf6d2, 0xf87e, 0xbea6, 0xefb5, 0xf1ea, 0xf3fa, + 0xf3fb, 0xf3fc, 0xf5be, 0xf5ba, 0xc568, 0xf5bd, 0xf5bc, 0xc4d4, + 0xf5bb, 0xc4d6, 0xc4d5, 0xf6d4, 0xf6d3, 0xc569, 0xc56a, 0xc5c6, + 0xf7cd, 0xc5c5, 0xf8a3, 0xf8a4, 0xf8a2, 0xf8a1, 0xc654, 0xf8eb, + 0xf8ec, 0xf8ed, 0xc653, 0xf967, 0xf96a, 0xf969, 0xf968, 0xf9d3, + 0xc073, 0xc365, 0xf5bf, 0xf6d5, 0xc5c7, 0xf7ce, 0xf9d5, 0xc074, + 0xefb6, 0xf7cf, 0xf9a1, 0xc94a, 0xddfc, 0xa14a, 0xa157, 0xa159, + 0xa15b, 0xa15f, 0xa160, 0xa163, 0xa164, 0xa167, 0xa168, 0xa16b, + 0xa16c, 0xa16f, 0xa170, 0xa173, 0xa174, 0xa177, 0xa178, 0xa17b, + 0xa17c, 0xa1c6, 0xa1c7, 0xa1ca, 0xa1cb, 0xa1c8, 0xa1c9, 0xa15c, + 0xa14d, 0xa14f, 0xa151, 0xa152, 0xa153, 0xa154, 0xa17d, 0xa17e, + 0xa1a1, 0xa1a2, 0xa1a3, 0xa1a4, 0xa1cc, 0xa1cd, 0xa1ce, 0xa1de, + 0xa1df, 0xa1e0, 0xa1e1, 0xa1e2, 0xa24c, 0xa24d, 0xa24e, 0xa149, + 0xa1ad, 0xa243, 0xa248, 0xa1ae, 0xa15d, 0xa15e, 0xa1af, 0xa1cf, + 0xa141, 0xa1d0, 0xa144, 0xa241, 0xa2af, 0xa2b0, 0xa2b1, 0xa2b2, + 0xa2b3, 0xa2b4, 0xa2b5, 0xa2b6, 0xa2b7, 0xa2b8, 0xa147, 0xa146, + 0xa1d5, 0xa1d7, 0xa1d6, 0xa148, 0xa249, 0xa2cf, 0xa2d0, 0xa2d1, + 0xa2d2, 0xa2d3, 0xa2d4, 0xa2d5, 0xa2d6, 0xa2d7, 0xa2d8, 0xa2d9, + 0xa2da, 0xa2db, 0xa2dc, 0xa2dd, 0xa2de, 0xa2df, 0xa2e0, 0xa2e1, + 0xa2e2, 0xa2e3, 0xa2e4, 0xa2e5, 0xa2e6, 0xa2e7, 0xa2e8, 0xa242, + 0xa1c4, 0xa2e9, 0xa2ea, 0xa2eb, 0xa2ec, 0xa2ed, 0xa2ee, 0xa2ef, + 0xa2f0, 0xa2f1, 0xa2f2, 0xa2f3, 0xa2f4, 0xa2f5, 0xa2f6, 0xa2f7, + 0xa2f8, 0xa2f9, 0xa2fa, 0xa2fb, 0xa2fc, 0xa2fd, 0xa2fe, 0xa340, + 0xa341, 0xa342, 0xa343, 0xa161, 0xa155, 0xa162, 0xa14e, +}; + +static const Summary16 big5_uni2indx_page00[16] = { + /* 0x0000 */ + { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, + { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, + { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x00ac }, { 4, 0x0083 }, + { 7, 0x0000 }, { 7, 0x0080 }, { 8, 0x0000 }, { 8, 0x0080 }, +}; +static const Summary16 big5_uni2indx_page02[38] = { + /* 0x0200 */ + { 9, 0x0000 }, { 9, 0x0000 }, { 9, 0x0000 }, { 9, 0x0000 }, + { 9, 0x0000 }, { 9, 0x0000 }, { 9, 0x0000 }, { 9, 0x0000 }, + { 9, 0x0000 }, { 9, 0x0000 }, { 9, 0x0000 }, { 9, 0x0000 }, + { 9, 0x0e80 }, { 13, 0x0200 }, { 14, 0x0000 }, { 14, 0x0000 }, + /* 0x0300 */ + { 14, 0x0000 }, { 14, 0x0000 }, { 14, 0x0000 }, { 14, 0x0000 }, + { 14, 0x0000 }, { 14, 0x0000 }, { 14, 0x0000 }, { 14, 0x0000 }, + { 14, 0x0000 }, { 14, 0xfffe }, { 29, 0x03fb }, { 38, 0xfffe }, + { 53, 0x03fb }, { 62, 0x0000 }, { 62, 0x0000 }, { 62, 0x0000 }, + /* 0x0400 */ + { 62, 0x0002 }, { 63, 0x1ff0 }, { 72, 0xfff8 }, { 85, 0xffff }, + { 101, 0xffff }, { 117, 0x0002 }, +}; +static const Summary16 big5_uni2indx_page20[44] = { + /* 0x2000 */ + { 118, 0x0000 }, { 118, 0x3318 }, { 124, 0x0064 }, { 127, 0x4824 }, + { 131, 0x0000 }, { 131, 0x0000 }, { 131, 0x0000 }, { 131, 0x0000 }, + { 131, 0x0000 }, { 131, 0x0000 }, { 131, 0x0000 }, { 131, 0x0000 }, + { 131, 0x0000 }, { 131, 0x0000 }, { 131, 0x0000 }, { 131, 0x0000 }, + /* 0x2100 */ + { 131, 0x0228 }, { 134, 0x0000 }, { 134, 0x0000 }, { 134, 0x0000 }, + { 134, 0x0000 }, { 134, 0x0000 }, { 134, 0x03ff }, { 144, 0x0000 }, + { 144, 0x0000 }, { 144, 0x03cf }, { 152, 0x0000 }, { 152, 0x0000 }, + { 152, 0x0000 }, { 152, 0x0000 }, { 152, 0x0000 }, { 152, 0x0000 }, + /* 0x2200 */ + { 152, 0x0000 }, { 152, 0xc400 }, { 155, 0x4e29 }, { 162, 0x1030 }, + { 165, 0x0000 }, { 165, 0x0004 }, { 166, 0x00c3 }, { 170, 0x0000 }, + { 170, 0x0000 }, { 170, 0x0000 }, { 170, 0x0020 }, { 171, 0x8000 }, +}; +static const Summary16 big5_uni2indx_page24[37] = { + /* 0x2400 */ + { 172, 0x0000 }, { 172, 0x0000 }, { 172, 0x0000 }, { 172, 0x0000 }, + { 172, 0x0000 }, { 172, 0x0000 }, { 172, 0x03ff }, { 182, 0x3ff0 }, + { 192, 0x0000 }, { 192, 0x0000 }, { 192, 0x0000 }, { 192, 0x0000 }, + { 192, 0x0000 }, { 192, 0x0000 }, { 192, 0x0000 }, { 192, 0x0000 }, + /* 0x2500 */ + { 192, 0x1005 }, { 195, 0x1111 }, { 199, 0x1010 }, { 201, 0x1010 }, + { 203, 0x0000 }, { 203, 0x4001 }, { 205, 0xe402 }, { 210, 0x000f }, + { 214, 0xfffe }, { 229, 0x0030 }, { 231, 0x0003 }, { 233, 0x300c }, + { 237, 0xc8c0 }, { 242, 0x0000 }, { 242, 0x003c }, { 246, 0x0000 }, + /* 0x2600 */ + { 246, 0x0260 }, { 249, 0x0000 }, { 249, 0x0000 }, { 249, 0x0000 }, + { 249, 0x0007 }, +}; +static const Summary16 big5_uni2indx_page30[62] = { + /* 0x3000 */ + { 252, 0xff2f }, { 265, 0x6037 }, { 272, 0x03fe }, { 281, 0x0000 }, + { 281, 0xfffe }, { 296, 0xffff }, { 312, 0xffff }, { 328, 0xffff }, + { 344, 0xffff }, { 360, 0x600f }, { 366, 0xfffe }, { 381, 0xffff }, + { 397, 0xffff }, { 413, 0xffff }, { 429, 0xffff }, { 445, 0x407f }, + /* 0x3100 */ + { 453, 0xffe0 }, { 464, 0xffff }, { 480, 0x03ff }, { 490, 0x0000 }, + { 490, 0x0000 }, { 490, 0x0000 }, { 490, 0x0000 }, { 490, 0x0000 }, + { 490, 0x0000 }, { 490, 0x0000 }, { 490, 0x0000 }, { 490, 0x0000 }, + { 490, 0x0000 }, { 490, 0x0000 }, { 490, 0x0000 }, { 490, 0x0000 }, + /* 0x3200 */ + { 490, 0x0000 }, { 490, 0x0000 }, { 490, 0x0000 }, { 490, 0x0000 }, + { 490, 0x0000 }, { 490, 0x0000 }, { 490, 0x0000 }, { 490, 0x0000 }, + { 490, 0x0000 }, { 490, 0x0000 }, { 490, 0x0008 }, { 491, 0x0000 }, + { 491, 0x0000 }, { 491, 0x0000 }, { 491, 0x0000 }, { 491, 0x0000 }, + /* 0x3300 */ + { 491, 0x0000 }, { 491, 0x0000 }, { 491, 0x0000 }, { 491, 0x0000 }, + { 491, 0x0000 }, { 491, 0x0000 }, { 491, 0x0000 }, { 491, 0x0000 }, + { 491, 0xc000 }, { 493, 0x7000 }, { 496, 0x0002 }, { 497, 0x0000 }, + { 497, 0x4010 }, { 499, 0x0026 }, +}; +static const Summary16 big5_uni2indx_page4e[1307] = { + /* 0x4e00 */ + { 502, 0xff8b }, { 514, 0xc373 }, { 523, 0x6840 }, { 527, 0x1b0f }, + { 535, 0xe9ac }, { 544, 0xf34c }, { 553, 0x0200 }, { 554, 0xc008 }, + { 557, 0x795c }, { 566, 0xca3e }, { 575, 0x7976 }, { 585, 0x0648 }, + { 589, 0x2fdf }, { 601, 0xf7f0 }, { 612, 0x033a }, { 618, 0xa8ff }, + /* 0x4f00 */ + { 629, 0xef37 }, { 641, 0x233f }, { 650, 0xb004 }, { 654, 0xfd59 }, + { 665, 0xf3ca }, { 675, 0xffff }, { 691, 0xde9f }, { 703, 0xfff9 }, + { 717, 0xabff }, { 730, 0x7df7 }, { 743, 0xc000 }, { 745, 0x8eec }, + { 754, 0xeebf }, { 767, 0xffdb }, { 781, 0xd003 }, { 786, 0x45fa }, + /* 0x5000 */ + { 795, 0xfae1 }, { 805, 0xdffe }, { 819, 0xbfef }, { 833, 0x10ab }, + { 839, 0xffeb }, { 853, 0xfcaa }, { 863, 0xef3f }, { 876, 0x24fd }, + { 885, 0x78ad }, { 894, 0x7f76 }, { 906, 0xf00c }, { 912, 0xedff }, + { 926, 0xcff6 }, { 938, 0x2cfa }, { 947, 0xf7f9 }, { 960, 0xeb6b }, + /* 0x5100 */ + { 971, 0x1ffd }, { 983, 0x95bf }, { 994, 0x6677 }, { 1004, 0xbfbf }, + { 1018, 0x3bfb }, { 1030, 0xfeb4 }, { 1041, 0x7bae }, { 1052, 0x11e2 }, + { 1058, 0xa681 }, { 1064, 0x41be }, { 1072, 0x1435 }, { 1078, 0x72c3 }, + { 1086, 0x7d70 }, { 1095, 0x7191 }, { 1102, 0x0003 }, { 1104, 0x276b }, + /* 0x5200 */ + { 1113, 0x57cb }, { 1123, 0x70cf }, { 1132, 0x4732 }, { 1139, 0x0def }, + { 1149, 0x7eda }, { 1160, 0xfc74 }, { 1170, 0xfe06 }, { 1179, 0xbdb4 }, + { 1189, 0x3f9f }, { 1201, 0x8bca }, { 1209, 0x7e49 }, { 1218, 0x5800 }, + { 1221, 0x228f }, { 1228, 0xebec }, { 1239, 0x8a5c }, { 1246, 0xddbb }, + /* 0x5300 */ + { 1258, 0xef60 }, { 1267, 0xb6e7 }, { 1278, 0xa40f }, { 1285, 0xf293 }, + { 1294, 0x37bb }, { 1305, 0x549e }, { 1313, 0xd04b }, { 1320, 0x9baf }, + { 1331, 0xc414 }, { 1336, 0xf7d4 }, { 1347, 0x30b0 }, { 1352, 0x0a14 }, + { 1356, 0x2f08 }, { 1362, 0x88d0 }, { 1367, 0xff7e }, { 1381, 0x192f }, + /* 0x5400 */ + { 1389, 0xffda }, { 1402, 0xfb07 }, { 1412, 0x7ff1 }, { 1424, 0x7beb }, + { 1436, 0xc5ef }, { 1447, 0x0010 }, { 1448, 0x99ff }, { 1460, 0xfdff }, + { 1475, 0x79d7 }, { 1486, 0x0567 }, { 1493, 0xffe7 }, { 1507, 0xfdcb }, + { 1519, 0xc3ff }, { 1531, 0x4040 }, { 1533, 0x6ff7 }, { 1546, 0xbd8e }, + /* 0x5500 */ + { 1556, 0xdffa }, { 1569, 0x0497 }, { 1575, 0xf4c0 }, { 1582, 0x5bff }, + { 1595, 0xed7b }, { 1607, 0xd0e7 }, { 1616, 0x047e }, { 1623, 0xf8e0 }, + { 1631, 0xff9f }, { 1645, 0xb73e }, { 1656, 0x7dfe }, { 1669, 0x882e }, + { 1675, 0xfffd }, { 1690, 0xbe7f }, { 1703, 0x83fe }, { 1713, 0xf6c4 }, + /* 0x5600 */ + { 1722, 0xf357 }, { 1733, 0xb8fd }, { 1744, 0xd680 }, { 1750, 0xef7d }, + { 1763, 0x5767 }, { 1773, 0x4788 }, { 1779, 0xff7d }, { 1793, 0xc3df }, + { 1804, 0xf0ff }, { 1816, 0x37a9 }, { 1825, 0x7de0 }, { 1834, 0x70fc }, + { 1843, 0x3f6f }, { 1855, 0xec9a }, { 1864, 0x4cb3 }, { 1872, 0x8681 }, + /* 0x5700 */ + { 1877, 0x3f9e }, { 1888, 0xdd5c }, { 1898, 0xf70d }, { 1908, 0x4819 }, + { 1913, 0xfea3 }, { 1924, 0x0007 }, { 1927, 0xaf56 }, { 1937, 0x38ff }, + { 1948, 0x980d }, { 1954, 0xefb8 }, { 1965, 0x403d }, { 1971, 0xb760 }, + { 1979, 0xd8ce }, { 1988, 0x9035 }, { 1994, 0x72bf }, { 2005, 0x3fff }, + /* 0x5800 */ + { 2019, 0x7ff7 }, { 2033, 0x7a11 }, { 2040, 0xf7bb }, { 2053, 0xabff }, + { 2066, 0xff00 }, { 2074, 0x6fbe }, { 2086, 0xa93c }, { 2094, 0xfe72 }, + { 2105, 0xcfef }, { 2118, 0xf11b }, { 2127, 0xdb6b }, { 2138, 0xf40a }, + { 2145, 0xc3e6 }, { 2154, 0xef7e }, { 2167, 0x9b9c }, { 2176, 0xf610 }, + /* 0x5900 */ + { 2183, 0xf048 }, { 2189, 0x16f4 }, { 2197, 0xfeb5 }, { 2209, 0x5182 }, + { 2214, 0xc7b1 }, { 2223, 0x15bb }, { 2232, 0x6e87 }, { 2241, 0xfbdf }, + { 2255, 0xe43f }, { 2265, 0x63cd }, { 2274, 0xc1ff }, { 2285, 0x7e7e }, + { 2297, 0xfdeb }, { 2310, 0x7d5f }, { 2322, 0x777b }, { 2334, 0xfcfe }, + /* 0x5a00 */ + { 2347, 0x960b }, { 2354, 0xdbea }, { 2365, 0x6229 }, { 2371, 0x53e8 }, + { 2379, 0x37df }, { 2391, 0xfdef }, { 2405, 0x36f5 }, { 2415, 0xbd81 }, + { 2423, 0xdc18 }, { 2430, 0xfcbd }, { 2442, 0xd2e4 }, { 2450, 0xffff }, + { 2466, 0x3fd7 }, { 2478, 0xffe0 }, { 2489, 0x7f6f }, { 2502, 0xabf8 }, + /* 0x5b00 */ + { 2512, 0x9bae }, { 2522, 0x6ed9 }, { 2532, 0xf5fb }, { 2545, 0xf115 }, + { 2553, 0x79a9 }, { 2562, 0xbdfb }, { 2575, 0x5a3c }, { 2583, 0xadaf }, + { 2594, 0xdbba }, { 2605, 0x1fac }, { 2614, 0x71fc }, { 2624, 0x8379 }, + { 2632, 0x7cf7 }, { 2644, 0xc35f }, { 2654, 0xdfff }, { 2669, 0x0567 }, + /* 0x5c00 */ + { 2676, 0xff9a }, { 2688, 0x8467 }, { 2695, 0x1534 }, { 2701, 0xdf8b }, + { 2712, 0xf9f3 }, { 2724, 0x3373 }, { 2733, 0xf7bd }, { 2746, 0x5e1a }, + { 2754, 0xbf40 }, { 2762, 0xa03f }, { 2770, 0xffff }, { 2786, 0x01eb }, + { 2793, 0xdfc0 }, { 2802, 0xcfdd }, { 2814, 0x7500 }, { 2819, 0xabd3 }, + /* 0x5d00 */ + { 2829, 0xf8c3 }, { 2838, 0xeed6 }, { 2849, 0x43fd }, { 2859, 0xb7ff }, + { 2873, 0x5eaf }, { 2884, 0x4227 }, { 2890, 0x9bac }, { 2899, 0xf686 }, + { 2908, 0x27d7 }, { 2918, 0xf6bc }, { 2929, 0xf787 }, { 2940, 0x35b7 }, + { 2950, 0xaacd }, { 2959, 0xe176 }, { 2968, 0x49e7 }, { 2977, 0xe29f }, + /* 0x5e00 */ + { 2987, 0x545c }, { 2994, 0xaff2 }, { 3005, 0x2b3f }, { 3015, 0x61d8 }, + { 3022, 0xfc3b }, { 3033, 0xbbb8 }, { 3043, 0xffcf }, { 3057, 0x7b7d }, + { 3069, 0xbf95 }, { 3080, 0x1ce0 }, { 3086, 0x7dfd }, { 3099, 0x43ff }, + { 3110, 0x5ff6 }, { 3122, 0xfffe }, { 3137, 0xd3ef }, { 3149, 0xc4ce }, + /* 0x5f00 */ + { 3157, 0x8db6 }, { 3166, 0xadbc }, { 3176, 0x63dc }, { 3185, 0x11eb }, + { 3193, 0xdf59 }, { 3204, 0x23d0 }, { 3210, 0xbeb4 }, { 3220, 0xf3db }, + { 3232, 0x1fe7 }, { 3243, 0xdbc7 }, { 3254, 0xff63 }, { 3266, 0xfae4 }, + { 3276, 0xb22b }, { 3284, 0x63f7 }, { 3295, 0xed3b }, { 3306, 0xadba }, + /* 0x6000 */ + { 3316, 0xfe01 }, { 3324, 0x7eff }, { 3338, 0xfff7 }, { 3353, 0x02bc }, + { 3359, 0x32ff }, { 3370, 0xef39 }, { 3381, 0xfffc }, { 3395, 0x8005 }, + { 3398, 0x77fb }, { 3411, 0xbcf5 }, { 3422, 0x010d }, { 3426, 0xfff7 }, + { 3441, 0xfffb }, { 3456, 0xbf3a }, { 3467, 0x0057 }, { 3472, 0xdfff }, + /* 0x6100 */ + { 3487, 0xef7b }, { 3500, 0xbd7d }, { 3512, 0xdb88 }, { 3520, 0xc8d4 }, + { 3527, 0xfff3 }, { 3541, 0xed7c }, { 3552, 0x5dee }, { 3563, 0x56ff }, + { 3575, 0x7e0d }, { 3584, 0xac5f }, { 3594, 0xff96 }, { 3606, 0xd57f }, + { 3618, 0x3fee }, { 3630, 0xc140 }, { 3634, 0x6ff9 }, { 3646, 0xffe7 }, + /* 0x6200 */ + { 3660, 0x779b }, { 3671, 0x8e77 }, { 3681, 0x6ebf }, { 3693, 0xe45d }, + { 3702, 0x6fcf }, { 3714, 0x5f1f }, { 3725, 0xe07f }, { 3735, 0xfedf }, + { 3749, 0xd7db }, { 3761, 0x01fe }, { 3769, 0xff00 }, { 3777, 0xfb7b }, + { 3790, 0xffd4 }, { 3802, 0x1fdf }, { 3814, 0xf800 }, { 3819, 0xffff }, + /* 0x6300 */ + { 3835, 0xfb8f }, { 3847, 0x007b }, { 3853, 0xbf00 }, { 3860, 0x7f5c }, + { 3871, 0xffff }, { 3887, 0x07f3 }, { 3896, 0xeba0 }, { 3904, 0x3de7 }, + { 3915, 0xf7bf }, { 3929, 0xfbd7 }, { 3942, 0xffbf }, { 3957, 0x6003 }, + { 3961, 0xfffd }, { 3976, 0xbfed }, { 3989, 0xefbb }, { 4002, 0x027f }, + /* 0x6400 */ + { 4010, 0xfe40 }, { 4018, 0xddfd }, { 4031, 0xfdff }, { 4046, 0xe2f9 }, + { 4056, 0x680b }, { 4062, 0xfb1f }, { 4074, 0xfbe3 }, { 4086, 0xaffd }, + { 4099, 0x9fa4 }, { 4108, 0xf7ed }, { 4121, 0x7a7d }, { 4132, 0xf80f }, + { 4141, 0xeebe }, { 4153, 0x0fd5 }, { 4162, 0xbb5d }, { 4173, 0xfd9f }, + /* 0x6500 */ + { 4186, 0xf2db }, { 4197, 0x3bf9 }, { 4208, 0xfe7f }, { 4222, 0xebcc }, + { 4232, 0x876a }, { 4240, 0x73fa }, { 4251, 0x95fc }, { 4261, 0x9ffc }, + { 4273, 0x109f }, { 4280, 0xfaf7 }, { 4293, 0xddb7 }, { 4305, 0xbbcd }, + { 4316, 0xf87e }, { 4327, 0xeccd }, { 4337, 0xf366 }, { 4347, 0x3c3f }, + /* 0x6600 */ + { 4357, 0xfffd }, { 4372, 0xb03f }, { 4381, 0xe9f7 }, { 4393, 0x067e }, + { 4401, 0x96ae }, { 4410, 0xfe06 }, { 4419, 0xd576 }, { 4429, 0x5fd7 }, + { 4441, 0x3fd1 }, { 4451, 0xa3f3 }, { 4461, 0xcf07 }, { 4470, 0x6fb7 }, + { 4482, 0x9fd1 }, { 4492, 0x7f44 }, { 4501, 0x7b59 }, { 4511, 0xd3dd }, + /* 0x6700 */ + { 4522, 0xaf3b }, { 4533, 0xa9bd }, { 4543, 0x7dcf }, { 4555, 0xff3a }, + { 4567, 0xfbe0 }, { 4577, 0xf6eb }, { 4589, 0xb401 }, { 4594, 0xffff }, + { 4610, 0x7afa }, { 4621, 0xb7bf }, { 4634, 0xc000 }, { 4636, 0x0ffd }, + { 4647, 0xff7f }, { 4662, 0xff1f }, { 4675, 0xfefc }, { 4688, 0x95ff }, + /* 0x6800 */ + { 4700, 0x0000 }, { 4700, 0xb5dc }, { 4710, 0xef63 }, { 4721, 0x3f3e }, + { 4732, 0xfb7f }, { 4746, 0x001b }, { 4750, 0xe800 }, { 4754, 0xfbf6 }, + { 4767, 0x9eef }, { 4779, 0xb8df }, { 4790, 0xff9f }, { 4804, 0x003f }, + { 4810, 0x7bd0 }, { 4819, 0xf5ff }, { 4833, 0xdfdb }, { 4846, 0x3fff }, + /* 0x6900 */ + { 4860, 0xfdf0 }, { 4871, 0x00bf }, { 4878, 0x8420 }, { 4881, 0xbbbd }, + { 4893, 0xdf37 }, { 4905, 0xffde }, { 4919, 0xff6d }, { 4932, 0x0ff3 }, + { 4942, 0x604c }, { 4947, 0x5efb }, { 4959, 0xfffb }, { 4974, 0xfafb }, + { 4987, 0xfe5e }, { 4999, 0x0219 }, { 5003, 0x79f4 }, { 5013, 0xf9de }, + /* 0x6a00 */ + { 5025, 0xa7f7 }, { 5037, 0xebfa }, { 5049, 0x01eb }, { 5056, 0xff34 }, + { 5067, 0xebd3 }, { 5078, 0xef73 }, { 5090, 0xafd7 }, { 5102, 0xc040 }, + { 5105, 0x72bb }, { 5115, 0xdcff }, { 5128, 0xf17f }, { 5140, 0x2fd8 }, + { 5149, 0xb8ec }, { 5158, 0xfe0b }, { 5168, 0xdda3 }, { 5178, 0x1f0b }, + /* 0x6b00 */ + { 5186, 0x8f1d }, { 5195, 0x47cf }, { 5205, 0xb12b }, { 5213, 0xffde }, + { 5227, 0x7fee }, { 5240, 0xda73 }, { 5250, 0x24ff }, { 5260, 0xcbc4 }, + { 5268, 0xf75d }, { 5280, 0xcbf2 }, { 5290, 0xecfd }, { 5302, 0xb4ed }, + { 5312, 0xbff9 }, { 5325, 0x4ddd }, { 5335, 0x99dd }, { 5345, 0xfb8d }, + /* 0x6c00 */ + { 5356, 0xbb7f }, { 5369, 0xaf7b }, { 5381, 0xddfb }, { 5394, 0xc959 }, + { 5402, 0xfc4f }, { 5413, 0xfab5 }, { 5424, 0xafe3 }, { 5435, 0x6d5f }, + { 5446, 0xffff }, { 5462, 0x3f7d }, { 5474, 0x7800 }, { 5478, 0xffdb }, + { 5492, 0xb6ff }, { 5505, 0x7eff }, { 5519, 0xfbaf }, { 5532, 0x022f }, + /* 0x6d00 */ + { 5538, 0xff9b }, { 5551, 0xefc7 }, { 5563, 0xffa5 }, { 5575, 0xffff }, + { 5591, 0x0007 }, { 5594, 0xc700 }, { 5599, 0xf7ff }, { 5614, 0xfff1 }, + { 5627, 0x7ffd }, { 5641, 0x01bf }, { 5649, 0xdc00 }, { 5654, 0xfdbc }, + { 5666, 0xbff5 }, { 5679, 0xffff }, { 5695, 0xff7f }, { 5710, 0x3eff }, + /* 0x6e00 */ + { 5723, 0x0029 }, { 5726, 0xbe00 }, { 5732, 0xf9ff }, { 5746, 0xff7f }, + { 5761, 0x6efb }, { 5773, 0xfd7e }, { 5786, 0xcbff }, { 5799, 0x039e }, + { 5806, 0xe300 }, { 5811, 0xfbdd }, { 5824, 0xccff }, { 5836, 0xf6df }, + { 5849, 0xffff }, { 5865, 0x117f }, { 5874, 0xf800 }, { 5879, 0xfbf6 }, + /* 0x6f00 */ + { 5892, 0xe7ef }, { 5905, 0xd73c }, { 5915, 0xfeef }, { 5929, 0xdfef }, + { 5943, 0xc00b }, { 5948, 0xedbf }, { 5961, 0xfedf }, { 5975, 0xfdcd }, + { 5987, 0x7bf5 }, { 5999, 0x40fd }, { 6007, 0xffff }, { 6023, 0xb75f }, + { 6035, 0xffdf }, { 6050, 0xf930 }, { 6058, 0xfbdf }, { 6072, 0xdc97 }, + /* 0x7000 */ + { 6082, 0xfef3 }, { 6095, 0xbff2 }, { 6107, 0x8fdf }, { 6119, 0xdfbf }, + { 6133, 0x177f }, { 6144, 0xede6 }, { 6155, 0x0f7f }, { 6166, 0x3553 }, + { 6174, 0x447c }, { 6181, 0x877e }, { 6191, 0xfa12 }, { 6199, 0x45bb }, + { 6208, 0xede0 }, { 6217, 0x779e }, { 6228, 0x8017 }, { 6233, 0xbfd9 }, + /* 0x7100 */ + { 6245, 0x7e55 }, { 6255, 0xde89 }, { 6264, 0xc16f }, { 6273, 0x0447 }, + { 6278, 0x7ade }, { 6289, 0xf75d }, { 6301, 0x57ff }, { 6314, 0x2905 }, + { 6319, 0x86f7 }, { 6329, 0xfe95 }, { 6340, 0x97b3 }, { 6350, 0xf32f }, + { 6361, 0xcfff }, { 6375, 0x9f75 }, { 6386, 0x71f7 }, { 6397, 0xfb17 }, + /* 0x7200 */ + { 6408, 0x34ee }, { 6417, 0xee19 }, { 6426, 0x37cc }, { 6435, 0xef61 }, + { 6445, 0x9fd6 }, { 6456, 0xef4c }, { 6466, 0xd68f }, { 6476, 0xfbdd }, + { 6489, 0x7b73 }, { 6500, 0x6def }, { 6512, 0xd7fe }, { 6525, 0xa431 }, + { 6531, 0x5e7f }, { 6543, 0x97d7 }, { 6554, 0x0f5b }, { 6563, 0xffd8 }, + /* 0x7300 */ + { 6575, 0x9d83 }, { 6583, 0x7bce }, { 6594, 0x22ec }, { 6601, 0xdcff }, + { 6614, 0x763d }, { 6624, 0xef87 }, { 6635, 0xdfe7 }, { 6648, 0xfded }, + { 6661, 0x4fff }, { 6674, 0xa0fc }, { 6682, 0x3b77 }, { 6693, 0xdbfc }, + { 6705, 0x3ded }, { 6716, 0x7fdc }, { 6728, 0x6fa9 }, { 6738, 0xf570 }, + /* 0x7400 */ + { 6747, 0x3ffb }, { 6760, 0x2c40 }, { 6764, 0xff7f }, { 6779, 0x847f }, + { 6788, 0xec57 }, { 6798, 0xdeb7 }, { 6810, 0xe69c }, { 6819, 0xf22f }, + { 6829, 0x0feb }, { 6839, 0xd5b5 }, { 6849, 0xafeb }, { 6861, 0xede7 }, + { 6873, 0x8c2f }, { 6881, 0xfff0 }, { 6893, 0x537f }, { 6904, 0xe8f0 }, + /* 0x7500 */ + { 6912, 0xb99d }, { 6922, 0xb5ff }, { 6935, 0xff66 }, { 6947, 0xe78f }, + { 6958, 0xd981 }, { 6965, 0xbe10 }, { 6972, 0x9c7c }, { 6981, 0xe3c1 }, + { 6989, 0x9cd1 }, { 6997, 0x2733 }, { 7005, 0x0cbc }, { 7012, 0xff6d }, + { 7025, 0xfcb7 }, { 7037, 0xefb7 }, { 7050, 0xa0df }, { 7059, 0xffff }, + /* 0x7600 */ + { 7075, 0xbf0b }, { 7085, 0xfe7b }, { 7098, 0xa3ff }, { 7110, 0x353f }, + { 7120, 0x13cc }, { 7127, 0x97cd }, { 7137, 0x7637 }, { 7147, 0xfb27 }, + { 7158, 0xcfd6 }, { 7169, 0x7e6c }, { 7179, 0xec50 }, { 7186, 0xed31 }, + { 7195, 0x677c }, { 7205, 0xfc1c }, { 7214, 0xf6fa }, { 7226, 0x5fbf }, + /* 0x7700 */ + { 7239, 0x0fba }, { 7248, 0xae2f }, { 7258, 0xa3ad }, { 7267, 0x7ffe }, + { 7281, 0xfcf0 }, { 7291, 0xde74 }, { 7301, 0xffef }, { 7316, 0xf200 }, + { 7321, 0xfbbf }, { 7335, 0xfea2 }, { 7345, 0x3daf }, { 7356, 0xbcff }, + { 7369, 0xf694 }, { 7378, 0x5fb9 }, { 7389, 0xf3ad }, { 7400, 0x3f8f }, + /* 0x7800 */ + { 7411, 0xf26c }, { 7420, 0xa01f }, { 7427, 0xffef }, { 7442, 0x01bf }, + { 7450, 0x7728 }, { 7458, 0x7005 }, { 7463, 0xff35 }, { 7475, 0xda03 }, + { 7482, 0xd2f9 }, { 7492, 0xc7fa }, { 7503, 0x3fbf }, { 7516, 0x5c1d }, + { 7524, 0xff3a }, { 7536, 0xec33 }, { 7545, 0xb7af }, { 7557, 0xfe9c }, + /* 0x7900 */ + { 7568, 0x5236 }, { 7575, 0x7a9f }, { 7586, 0xbffa }, { 7599, 0xe722 }, + { 7607, 0x9ff7 }, { 7620, 0xfcff }, { 7634, 0x2fbb }, { 7645, 0xb61d }, + { 7654, 0xed06 }, { 7662, 0x1dfd }, { 7673, 0x7dd7 }, { 7685, 0xefdf }, + { 7699, 0xeb23 }, { 7708, 0xf166 }, { 7717, 0x7ed9 }, { 7728, 0x0dc0 }, + /* 0x7a00 */ + { 7733, 0x3d3d }, { 7743, 0xdfbf }, { 7757, 0xc945 }, { 7764, 0xba83 }, + { 7772, 0x7dd1 }, { 7782, 0x9dd0 }, { 7790, 0x7b87 }, { 7800, 0xcf73 }, + { 7811, 0x9ff3 }, { 7823, 0xc3f5 }, { 7833, 0xdf0d }, { 7843, 0xc5fe }, + { 7854, 0x0cb3 }, { 7861, 0x8302 }, { 7865, 0xe879 }, { 7874, 0xaec0 }, + /* 0x7b00 */ + { 7881, 0xc773 }, { 7891, 0x6f0f }, { 7901, 0xfd7d }, { 7914, 0x093f }, + { 7922, 0xfff1 }, { 7935, 0x0157 }, { 7941, 0x62fb }, { 7951, 0x01ff }, + { 7960, 0xfdb4 }, { 7971, 0x3bf3 }, { 7982, 0xb013 }, { 7988, 0x43b2 }, + { 7995, 0x5ed3 }, { 8005, 0xff30 }, { 8015, 0x0fff }, { 8027, 0xeb9f }, + /* 0x7c00 */ + { 8039, 0xfeef }, { 8053, 0xf203 }, { 8060, 0x3fef }, { 8073, 0xfb89 }, + { 8083, 0x37a9 }, { 8092, 0x9e99 }, { 8101, 0xdef9 }, { 8113, 0xa72c }, + { 8121, 0x3733 }, { 8130, 0xc1f6 }, { 8139, 0x812e }, { 8145, 0xfe3e }, + { 8157, 0x5d20 }, { 8163, 0xf2f7 }, { 8175, 0xd585 }, { 8183, 0x69d7 }, + /* 0x7d00 */ + { 8193, 0xffff }, { 8209, 0xffff }, { 8225, 0xdb07 }, { 8234, 0xff6f }, + { 8248, 0xc4ff }, { 8259, 0xd97f }, { 8271, 0xefce }, { 8283, 0xbe0f }, + { 8293, 0xf17b }, { 8304, 0xf05e }, { 8313, 0xf6cf }, { 8325, 0xffb7 }, + { 8339, 0x5ef7 }, { 8351, 0xef84 }, { 8360, 0xd7cb }, { 8371, 0x0edf }, + /* 0x7e00 */ + { 8381, 0xff08 }, { 8390, 0xfcff }, { 8404, 0xee3f }, { 8416, 0xffff }, + { 8432, 0x13ff }, { 8443, 0xd7ff }, { 8457, 0xaf0f }, { 8467, 0x7ffd }, + { 8481, 0xbdc7 }, { 8492, 0x1ffa }, { 8503, 0x0000 }, { 8503, 0x0000 }, + { 8503, 0x0000 }, { 8503, 0x0000 }, { 8503, 0x0000 }, { 8503, 0x0000 }, + /* 0x7f00 */ + { 8503, 0x0000 }, { 8503, 0x0000 }, { 8503, 0x0000 }, { 8503, 0xe740 }, + { 8510, 0xbd38 }, { 8519, 0xf933 }, { 8529, 0x7feb }, { 8542, 0xfeed }, + { 8555, 0x7fe8 }, { 8566, 0x7c76 }, { 8576, 0xb3f7 }, { 8588, 0xffef }, + { 8603, 0xfeaf }, { 8616, 0xd8b7 }, { 8626, 0xff6f }, { 8640, 0xfbbf }, + /* 0x8000 */ + { 8654, 0xf8fb }, { 8666, 0xdbf7 }, { 8679, 0x1752 }, { 8686, 0xe2f9 }, + { 8696, 0x85c8 }, { 8702, 0x7547 }, { 8711, 0x9090 }, { 8715, 0xe3ef }, + { 8727, 0x9ef4 }, { 8737, 0x3f6d }, { 8748, 0xee2e }, { 8758, 0x0536 }, + { 8764, 0xf7bc }, { 8776, 0x7ff3 }, { 8789, 0xa07b }, { 8797, 0x7f3f }, + /* 0x8100 */ + { 8810, 0x0567 }, { 8817, 0xeb60 }, { 8825, 0xbabe }, { 8836, 0x6601 }, + { 8841, 0xfcd8 }, { 8851, 0x583f }, { 8860, 0xcaf7 }, { 8871, 0x87df }, + { 8882, 0xbfcd }, { 8894, 0xffa0 }, { 8904, 0x5bcd }, { 8914, 0xfebf }, + { 8928, 0xb6fd }, { 8940, 0xefa7 }, { 8952, 0x77ef }, { 8965, 0xdf9c }, + /* 0x8200 */ + { 8976, 0x3fb7 }, { 8988, 0xf877 }, { 8999, 0x9d27 }, { 9008, 0xb7fc }, + { 9020, 0xcab5 }, { 9029, 0xdfef }, { 9043, 0xfb5a }, { 9054, 0xf1b6 }, + { 9064, 0xec39 }, { 9073, 0xef1f }, { 9085, 0xfbbf }, { 9099, 0x7ffb }, + { 9113, 0x000d }, { 9116, 0xdafe }, { 9128, 0xbdfb }, { 9141, 0x4e7f }, + /* 0x8300 */ + { 9152, 0x33ff }, { 9164, 0x5ac0 }, { 9170, 0xbff5 }, { 9183, 0x9ffe }, + { 9196, 0xffbf }, { 9211, 0x005f }, { 9217, 0x0000 }, { 9217, 0xfdf8 }, + { 9229, 0xffca }, { 9241, 0x6ffd }, { 9254, 0xcffd }, { 9267, 0xa001 }, + { 9270, 0xdfff }, { 9285, 0xfbf2 }, { 9297, 0xdfbf }, { 9311, 0xff7f }, + /* 0x8400 */ + { 9326, 0xfeda }, { 9338, 0x080f }, { 9343, 0xba08 }, { 9349, 0xbfff }, + { 9364, 0x7afd }, { 9376, 0xeed7 }, { 9388, 0xfbeb }, { 9401, 0x67f9 }, + { 9412, 0xe044 }, { 9417, 0xff93 }, { 9429, 0xdf97 }, { 9441, 0x9f57 }, + { 9452, 0xfef7 }, { 9466, 0x08df }, { 9474, 0xdf80 }, { 9482, 0xfedf }, + /* 0x8500 */ + { 9496, 0xffc5 }, { 9508, 0xf7fe }, { 9522, 0xfffb }, { 9537, 0x6803 }, + { 9542, 0x67fb }, { 9554, 0x6bfa }, { 9565, 0x7fff }, { 9580, 0x5fe2 }, + { 9590, 0xffff }, { 9606, 0xff73 }, { 9619, 0x87df }, { 9630, 0xe7fb }, + { 9643, 0xebfd }, { 9656, 0xf7a7 }, { 9668, 0xbf7e }, { 9681, 0xefc7 }, + /* 0x8600 */ + { 9693, 0x1ef3 }, { 9703, 0xdf82 }, { 9712, 0x76ff }, { 9725, 0xdf7e }, + { 9738, 0x79c9 }, { 9747, 0xda7d }, { 9758, 0xefbe }, { 9771, 0x1e9b }, + { 9780, 0x7ce0 }, { 9788, 0x77fb }, { 9801, 0x87be }, { 9811, 0xfffb }, + { 9826, 0x1bff }, { 9838, 0xffdb }, { 9852, 0x3f5c }, { 9862, 0x4fe0 }, + /* 0x8700 */ + { 9870, 0x7fff }, { 9885, 0x5f0e }, { 9894, 0x77ff }, { 9908, 0xddbf }, + { 9921, 0xf04f }, { 9930, 0xffff }, { 9946, 0xffff }, { 9962, 0x0ff8 }, + { 9971, 0xa3be }, { 9981, 0xfddf }, { 9995, 0xfc1c }, { 10004, 0xfffd }, + { 10019, 0x1f7d }, { 10030, 0xfb9e }, { 10042, 0xbdff }, { 10056, 0xdedc }, + /* 0x8800 */ + { 10067, 0x3f6f }, { 10079, 0xbafb }, { 10091, 0xdf7f }, { 10105, 0xfbef }, + { 10119, 0x7d1b }, { 10129, 0x2eec }, { 10138, 0xaf8e }, { 10148, 0xf2f7 }, + { 10160, 0x7b0f }, { 10170, 0xcfee }, { 10182, 0x1d96 }, { 10190, 0x77c6 }, + { 10200, 0x7e07 }, { 10209, 0xfff5 }, { 10223, 0xd982 }, { 10230, 0x7fdf }, + /* 0x8900 */ + { 10244, 0x5ee6 }, { 10254, 0xc7ff }, { 10267, 0xfeee }, { 10280, 0x79ef }, + { 10292, 0x9a56 }, { 10300, 0xffcf }, { 10314, 0xfe5f }, { 10327, 0xde5e }, + { 10338, 0x896e }, { 10346, 0xf9e8 }, { 10356, 0xf45e }, { 10366, 0xe6c4 }, + { 10374, 0x0001 }, { 10375, 0xbe7c }, { 10386, 0x3b7f }, { 10398, 0xdddf }, + /* 0x8a00 */ + { 10411, 0xd59d }, { 10421, 0xe9ef }, { 10433, 0x34ac }, { 10440, 0xde53 }, + { 10450, 0xf573 }, { 10461, 0x4bf7 }, { 10472, 0x7b4f }, { 10483, 0x9eff }, + { 10496, 0xb8fe }, { 10507, 0x476e }, { 10516, 0x0dfb }, { 10526, 0xff45 }, + { 10537, 0xabfd }, { 10549, 0xfbfe }, { 10563, 0xe9d7 }, { 10574, 0xddff }, + /* 0x8b00 */ + { 10588, 0xedf7 }, { 10601, 0x7fff }, { 10616, 0xddfd }, { 10629, 0x7eeb }, + { 10641, 0xcfe7 }, { 10653, 0xb7ff }, { 10667, 0xbde9 }, { 10678, 0xef91 }, + { 10688, 0x5d75 }, { 10698, 0xd77c }, { 10709, 0x0000 }, { 10709, 0x0000 }, + { 10709, 0x0000 }, { 10709, 0x0000 }, { 10709, 0x0000 }, { 10709, 0x0000 }, + /* 0x8c00 */ + { 10709, 0x0000 }, { 10709, 0x0000 }, { 10709, 0x0000 }, { 10709, 0xfa80 }, + { 10716, 0xffee }, { 10730, 0xb4f1 }, { 10739, 0xbf76 }, { 10751, 0x2fef }, + { 10763, 0xb677 }, { 10774, 0x77bf }, { 10787, 0x9fbf }, { 10800, 0xfffd }, + { 10815, 0x95bf }, { 10826, 0xf6ae }, { 10837, 0x75ff }, { 10850, 0x7f3b }, + /* 0x8d00 */ + { 10862, 0xa7f5 }, { 10873, 0x0af9 }, { 10881, 0x0000 }, { 10881, 0x0000 }, + { 10881, 0x0000 }, { 10881, 0x0000 }, { 10881, 0xfbd0 }, { 10891, 0x2bdd }, + { 10901, 0xf633 }, { 10911, 0x9a7f }, { 10922, 0xfdab }, { 10934, 0xd6fc }, + { 10945, 0xf9e6 }, { 10956, 0xbfeb }, { 10969, 0xdfdf }, { 10983, 0xf41f }, + /* 0x8e00 */ + { 10993, 0xa6fd }, { 11004, 0xffff }, { 11020, 0x4aff }, { 11031, 0xf37b }, + { 11043, 0x7fb7 }, { 11056, 0xfef9 }, { 11069, 0xb6ff }, { 11082, 0x1d5c }, + { 11090, 0x7ff6 }, { 11103, 0xe5ff }, { 11116, 0x1f7b }, { 11127, 0x2404 }, + { 11130, 0xbe05 }, { 11138, 0xf99e }, { 11149, 0xdbe3 }, { 11160, 0xdff2 }, + /* 0x8f00 */ + { 11172, 0x6fef }, { 11185, 0xfdff }, { 11200, 0xd679 }, { 11210, 0xcbfc }, + { 11221, 0xebfd }, { 11234, 0xefff }, { 11249, 0x001f }, { 11254, 0x0000 }, + { 11254, 0x0000 }, { 11254, 0x9800 }, { 11257, 0xe148 }, { 11263, 0x8017 }, + { 11268, 0x6a74 }, { 11276, 0x00fe }, { 11283, 0x6d7f }, { 11295, 0xfdf1 }, + /* 0x9000 */ + { 11307, 0xb87f }, { 11318, 0xfef3 }, { 11331, 0xe01f }, { 11339, 0xf176 }, + { 11349, 0xee96 }, { 11359, 0x7b3f }, { 11371, 0xeb8d }, { 11381, 0xfffd }, + { 11396, 0xadff }, { 11409, 0xcbb3 }, { 11419, 0x84ef }, { 11428, 0xe17f }, + { 11439, 0x4daa }, { 11447, 0xbff0 }, { 11458, 0xbf3f }, { 11471, 0xfe3f }, + /* 0x9100 */ + { 11484, 0xebff }, { 11498, 0xffd7 }, { 11512, 0xffdf }, { 11527, 0xcf7f }, + { 11540, 0xfffb }, { 11555, 0x85ed }, { 11564, 0xd73f }, { 11576, 0x07bc }, + { 11584, 0xaeff }, { 11597, 0xfe0f }, { 11608, 0xfdaf }, { 11621, 0x76bf }, + { 11633, 0xfaef }, { 11646, 0x37bb }, { 11657, 0x7fdc }, { 11669, 0xa3ba }, + /* 0x9200 */ + { 11678, 0xb6ff }, { 11691, 0x56f7 }, { 11702, 0x60f8 }, { 11709, 0xe7df }, + { 11722, 0xff61 }, { 11733, 0x4cdf }, { 11743, 0xb0fb }, { 11753, 0xff45 }, + { 11764, 0x7ded }, { 11776, 0x3ffa }, { 11788, 0x1fff }, { 11801, 0x18fc }, + { 11809, 0xffff }, { 11825, 0xe3af }, { 11836, 0xc7d3 }, { 11846, 0xdf83 }, + /* 0x9300 */ + { 11856, 0xfb57 }, { 11868, 0xef7d }, { 11881, 0xefff }, { 11896, 0x1378 }, + { 11903, 0xfec0 }, { 11912, 0x5ff7 }, { 11925, 0x34bb }, { 11934, 0x5ee3 }, + { 11944, 0xf70d }, { 11954, 0xeff6 }, { 11967, 0xd7fe }, { 11980, 0x00bf }, + { 11987, 0xf59d }, { 11998, 0xf7f7 }, { 12012, 0x51de }, { 12021, 0xffe0 }, + /* 0x9400 */ + { 12032, 0xfec9 }, { 12043, 0x037f }, { 12052, 0x5f01 }, { 12059, 0xbfef }, + { 12073, 0x9ff1 }, { 12084, 0x60a7 }, { 12091, 0xef1d }, { 12102, 0xf1ff }, + { 12115, 0x000f }, { 12119, 0x0000 }, { 12119, 0x0000 }, { 12119, 0x0000 }, + { 12119, 0x0000 }, { 12119, 0x0000 }, { 12119, 0x0000 }, { 12119, 0x0000 }, + /* 0x9500 */ + { 12119, 0x0000 }, { 12119, 0x0000 }, { 12119, 0x0000 }, { 12119, 0x0000 }, + { 12119, 0x0000 }, { 12119, 0x0000 }, { 12119, 0x0000 }, { 12119, 0x3c80 }, + { 12124, 0xfb4d }, { 12135, 0xd91f }, { 12145, 0x7b3a }, { 12155, 0xfee3 }, + { 12167, 0x3fe9 }, { 12178, 0xdc7f }, { 12190, 0x003f }, { 12196, 0x0000 }, + /* 0x9600 */ + { 12196, 0x0000 }, { 12196, 0x5000 }, { 12198, 0xf51f }, { 12209, 0xbe07 }, + { 12218, 0xfc1d }, { 12228, 0xf91b }, { 12238, 0xbc1e }, { 12247, 0x71ff }, + { 12259, 0x6ff9 }, { 12271, 0x5bbe }, { 12282, 0x5796 }, { 12291, 0x9b1b }, + { 12300, 0x7fff }, { 12315, 0xfffc }, { 12329, 0x872e }, { 12337, 0xafe7 }, + /* 0x9700 */ + { 12349, 0xebf5 }, { 12361, 0xf34f }, { 12372, 0xdffd }, { 12386, 0xe725 }, + { 12395, 0x0bdc }, { 12403, 0x5d44 }, { 12410, 0x5747 }, { 12419, 0xfddd }, + { 12432, 0xed3f }, { 12444, 0x7790 }, { 12452, 0x7d7f }, { 12465, 0x8ac8 }, + { 12471, 0xfafa }, { 12483, 0xf3f9 }, { 12495, 0x202a }, { 12499, 0xef4b }, + /* 0x9800 */ + { 12510, 0xf5ff }, { 12524, 0x79cf }, { 12535, 0xabd3 }, { 12545, 0x0ba5 }, + { 12552, 0xf77a }, { 12564, 0xfb8f }, { 12576, 0x8ebd }, { 12586, 0x001f }, + { 12591, 0x0000 }, { 12591, 0x0000 }, { 12591, 0xf300 }, { 12597, 0xfd4e }, + { 12608, 0x1a57 }, { 12616, 0x8800 }, { 12618, 0xaeac }, { 12627, 0x7654 }, + /* 0x9900 */ + { 12635, 0x17ad }, { 12644, 0xcdff }, { 12657, 0xffb2 }, { 12669, 0xf42f }, + { 12679, 0x5baa }, { 12688, 0xdbff }, { 12702, 0x0002 }, { 12703, 0x0000 }, + { 12703, 0x0000 }, { 12703, 0x73c0 }, { 12710, 0xf9ea }, { 12721, 0x2e3f }, + { 12731, 0xfa8e }, { 12741, 0xbbff }, { 12755, 0x76bc }, { 12765, 0xffd3 }, + /* 0x9a00 */ + { 12778, 0xeefe }, { 12791, 0x7e72 }, { 12801, 0x7ebd }, { 12813, 0xe7f7 }, + { 12826, 0xf77f }, { 12840, 0xcefd }, { 12852, 0x0ff5 }, { 12862, 0x0000 }, + { 12862, 0x0000 }, { 12862, 0x0000 }, { 12862, 0xa900 }, { 12866, 0xdb9b }, + { 12877, 0xa4c7 }, { 12885, 0x917f }, { 12895, 0xf8ca }, { 12904, 0x7ece }, + /* 0x9b00 */ + { 12915, 0x7d7a }, { 12926, 0xc7e7 }, { 12937, 0xcbbd }, { 12948, 0xdcae }, + { 12958, 0xfd7e }, { 12971, 0x8f76 }, { 12981, 0x91d3 }, { 12989, 0x7cf3 }, + { 13000, 0x01e5 }, { 13006, 0x4c2f }, { 13014, 0xed77 }, { 13026, 0xa360 }, + { 13032, 0x07db }, { 13041, 0x5ef8 }, { 13051, 0x1df7 }, { 13062, 0x2181 }, + /* 0x9c00 */ + { 13066, 0x6be0 }, { 13074, 0x309c }, { 13080, 0x3b3a }, { 13089, 0xfade }, + { 13101, 0x7f53 }, { 13112, 0xc3f5 }, { 13122, 0x61cd }, { 13130, 0x07ba }, + { 13138, 0x0000 }, { 13138, 0x0000 }, { 13138, 0x0000 }, { 13138, 0x0000 }, + { 13138, 0x0000 }, { 13138, 0x0000 }, { 13138, 0x26e0 }, { 13144, 0xbefe }, + /* 0x9d00 */ + { 13157, 0x03f9 }, { 13165, 0xebb5 }, { 13176, 0xe36d }, { 13186, 0xe9cb }, + { 13196, 0x9c2f }, { 13205, 0xbfde }, { 13218, 0x9f83 }, { 13227, 0xabbf }, + { 13239, 0x1ff7 }, { 13251, 0xffd5 }, { 13264, 0xb7df }, { 13277, 0xdffe }, + { 13291, 0xfdae }, { 13303, 0xffef }, { 13318, 0xfb7e }, { 13331, 0xeffd }, + /* 0x9e00 */ + { 13345, 0xaaff }, { 13357, 0x6ebf }, { 13369, 0x0000 }, { 13369, 0x0000 }, + { 13369, 0x0000 }, { 13369, 0x0000 }, { 13369, 0x0000 }, { 13369, 0xb620 }, + { 13375, 0x7fcd }, { 13387, 0xbe9e }, { 13398, 0x62b3 }, { 13406, 0x58f1 }, + { 13414, 0xf10d }, { 13422, 0xfd7b }, { 13435, 0xe9f1 }, { 13445, 0xbefd }, + /* 0x9f00 */ + { 13458, 0xc6c3 }, { 13466, 0x5f6d }, { 13477, 0xff3d }, { 13490, 0x69ff }, + { 13502, 0xffcf }, { 13516, 0xfbf4 }, { 13528, 0xdcfb }, { 13540, 0x4ff7 }, + { 13552, 0x2000 }, { 13553, 0x1137 }, { 13560, 0x0015 }, +}; +static const Summary16 big5_uni2indx_pagefa[1] = { + /* 0xfa00 */ + { 13563, 0x3000 }, +}; +static const Summary16 big5_uni2indx_pagefe[23] = { + /* 0xfe00 */ + { 13565, 0x0000 }, { 13565, 0x0000 }, { 13565, 0x0000 }, { 13565, 0xfffb }, + { 13580, 0xfe1f }, { 13592, 0xfef5 }, { 13605, 0x0e7f }, { 13615, 0x0000 }, + { 13615, 0x0000 }, { 13615, 0x0000 }, { 13615, 0x0000 }, { 13615, 0x0000 }, + { 13615, 0x0000 }, { 13615, 0x0000 }, { 13615, 0x0000 }, { 13615, 0x0000 }, + /* 0xff00 */ + { 13615, 0xff7a }, { 13628, 0xffff }, { 13644, 0xffff }, { 13660, 0x97ff }, + { 13673, 0xfffe }, { 13688, 0x3fff }, { 13702, 0x0010 }, +}; + +static int +big5_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (n >= 2) { + const Summary16 *summary = NULL; + if (wc < 0x0100) + summary = &big5_uni2indx_page00[(wc>>4)]; + else if (wc >= 0x0200 && wc < 0x0460) + summary = &big5_uni2indx_page02[(wc>>4)-0x020]; + else if (wc >= 0x2000 && wc < 0x22c0) + summary = &big5_uni2indx_page20[(wc>>4)-0x200]; + else if (wc >= 0x2400 && wc < 0x2650) + summary = &big5_uni2indx_page24[(wc>>4)-0x240]; + else if (wc >= 0x3000 && wc < 0x33e0) + summary = &big5_uni2indx_page30[(wc>>4)-0x300]; + else if (wc >= 0x4e00 && wc < 0x9fb0) + summary = &big5_uni2indx_page4e[(wc>>4)-0x4e0]; + else if (wc >= 0xfa00 && wc < 0xfa10) + summary = &big5_uni2indx_pagefa[(wc>>4)-0xfa0]; + else if (wc >= 0xfe00 && wc < 0xff70) + summary = &big5_uni2indx_pagefe[(wc>>4)-0xfe0]; + if (summary) { + unsigned short used = summary->used; + unsigned int i = wc & 0x0f; + if (used & ((unsigned short) 1 << i)) { + unsigned short c; + /* Keep in `used' only the bits 0..i-1. */ + used &= ((unsigned short) 1 << i) - 1; + /* Add `summary->indx' and the number of bits set in `used'. */ + used = (used & 0x5555) + ((used & 0xaaaa) >> 1); + used = (used & 0x3333) + ((used & 0xcccc) >> 2); + used = (used & 0x0f0f) + ((used & 0xf0f0) >> 4); + used = (used & 0x00ff) + (used >> 8); + c = big5_2charset[summary->indx + used]; + r[0] = (c >> 8); r[1] = (c & 0xff); + return 2; + } + } + return RET_ILSEQ; + } + return RET_TOOSMALL; +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/big5_emacs.h b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/big5_emacs.h new file mode 100644 index 0000000..9147553 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/big5_emacs.h @@ -0,0 +1,164 @@ +/* $XFree86: xc/lib/X11/lcUniConv/big5_emacs.h,v 1.1 2000/11/28 18:50:06 dawes Exp $ */ + +/* + * BIG5-0 and BIG5-1 + */ + +/* + BIG5 with its 13494 characters doesn't fit in a single 94x94 or 96x96 + block. Therefore Emacs/Mule developers, in a typically Japanese way of + thinking, have developed an alternative encoding of BIG5 in two 94x94 + planes, very similar to the SHIFT_JIS encoding for JISX0208. + + Conversion between BIG5 codes (s1,s2) and BIG5-0 codes (c1,c2): + Example. (s1,s2) = 0xA140, (c1,c2) = 0x2121. + 0xA1 <= s1 <= 0xC7, 0x40 <= s2 <= 0x7E || 0xA1 <= s2 <= 0xFE, + 0x21 <= c1 <= 0x62, 0x21 <= c2 <= 0x7E. + Invariant: + 157*(s1-0xA1) + (s2 < 0x80 ? s2-0x40 : s2-0x62) + = 94*(c1-0x21)+(c2-0x21) + Conversion (s1,s2) -> (c1,c2): + t := 157*(s1-0xA1) + (s2 < 0x80 ? s2-0x40 : s2-0x62) + c1 := (t div 94) + 0x21 + c2 := (t mod 94) + 0x21 + Conversion (c1,c2) -> (s1,s2): + t := 94*(c1-0x21)+(c2-0x21) + t2 := t mod 157 + s1 := (t div 157) + 0xA1 + s2 := (t2 < 0x3F ? t2+0x40 : t2+0x62) + + Conversion between BIG5 codes (s1,s2) and BIG5-1 codes (c1,c2): + Example. (s1,s2) = 0xC940, (c1,c2) = 0x2121. + 0xC9 <= s1 <= 0xF9, 0x40 <= s2 <= 0x7E || 0xA1 <= s2 <= 0xFE, + 0x21 <= c1 <= 0x72, 0x21 <= c2 <= 0x7E. + Invariant: + 157*(s1-0xC9) + (s2 < 0x80 ? s2-0x40 : s2-0x62) + = 94*(c1-0x21)+(c2-0x21) + Conversion (s1,s2) -> (c1,c2): + t := 157*(s1-0xC9) + (s2 < 0x80 ? s2-0x40 : s2-0x62) + c1 := (t div 94) + 0x21 + c2 := (t mod 94) + 0x21 + Conversion (c1,c2) -> (s1,s2): + t := 94*(c1-0x21)+(c2-0x21) + t2 := t mod 157 + s1 := (t div 157) + 0xC9 + s2 := (t2 < 0x3F ? t2+0x40 : t2+0x62) + */ + +static int +big5_0_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c1 = s[0]; + if (c1 >= 0x21 && c1 <= 0x62) { + if (n >= 2) { + unsigned char c2 = s[1]; + if (c2 >= 0x21 && c2 <= 0x7e) { + unsigned int i = 94 * (c1 - 0x21) + (c2 - 0x21); + if (0) { + /* Unoptimized. */ + unsigned char buf[2]; + buf[0] = (i / 157) + 0xa1; + i = i % 157; + buf[1] = i + (i < 0x3f ? 0x40 : 0x62); + return big5_mbtowc(conv,pwc,buf,2); + } else { + /* Inline the implementation of big5_mbtowc. */ + if (i < 6121) { + unsigned short wc = big5_2uni_pagea1[i]; + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 2; + } + } + } + } + return RET_ILSEQ; + } + return RET_TOOFEW(0); + } + return RET_ILSEQ; +} + +static int +big5_1_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c1 = s[0]; + if (c1 >= 0x21 && c1 <= 0x72) { + if (n >= 2) { + unsigned char c2 = s[1]; + if (c2 >= 0x21 && c2 <= 0x7e) { + unsigned int i = 94 * (c1 - 0x21) + (c2 - 0x21); + if (0) { + /* Unoptimized. */ + unsigned char buf[2]; + buf[0] = (i / 157) + 0xc9; + i = i % 157; + buf[1] = i + (i < 0x3f ? 0x40 : 0x62); + return big5_mbtowc(conv,pwc,buf,2); + } else { + /* Inline the implementation of big5_mbtowc. */ + if (i < 7652) { + unsigned short wc = big5_2uni_pagec9[i]; + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 2; + } + } + } + } + return RET_ILSEQ; + } + return RET_TOOFEW(0); + } + return RET_ILSEQ; +} + +static int +big5_0_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (n >= 2) { + unsigned char buf[2]; + int ret = big5_wctomb(conv,buf,wc,2); + if (ret != RET_ILSEQ) { + unsigned char s1, s2; + if (ret != 2) abort(); + s1 = buf[0]; + s2 = buf[1]; + if (!(s1 >= 0xa1)) abort(); + if (!((s2 >= 0x40 && s2 <= 0x7e) || (s2 >= 0xa1 && s2 <= 0xfe))) abort(); + if (s1 < 0xc9) { + unsigned int t = 157 * (s1 - 0xa1) + s2 - (s2 < 0x80 ? 0x40 : 0x62); + r[0] = (t / 94) + 0x21; + r[1] = (t % 94) + 0x21; + return 2; + } + } + return RET_ILSEQ; + } + return RET_TOOSMALL; +} + +static int +big5_1_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (n >= 2) { + unsigned char buf[2]; + int ret = big5_wctomb(conv,buf,wc,2); + if (ret != RET_ILSEQ) { + unsigned char s1, s2; + if (ret != 2) abort(); + s1 = buf[0]; + s2 = buf[1]; + if (!(s1 <= 0xf9)) abort(); + if (!((s2 >= 0x40 && s2 <= 0x7e) || (s2 >= 0xa1 && s2 <= 0xfe))) abort(); + if (s1 >= 0xc9) { + unsigned int t = 157 * (s1 - 0xc9) + s2 - (s2 < 0x80 ? 0x40 : 0x62); + r[0] = (t / 94) + 0x21; + r[1] = (t % 94) + 0x21; + return 2; + } + } + return RET_ILSEQ; + } + return RET_TOOSMALL; +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/cjk_tab_to_h.c b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/cjk_tab_to_h.c new file mode 100644 index 0000000..1335fae --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/cjk_tab_to_h.c @@ -0,0 +1,1025 @@ +/* $XFree86: xc/lib/X11/lcUniConv/cjk_tab_to_h.c,v 1.2 2000/12/04 18:49:31 dawes Exp $ */ + +/* + * Generates a CJK character set table from a .TXT table as found on + * ftp.unicode.org or in the X nls directory. + * Examples: + * + * ./cjk_tab_to_h GB2312.1980-0 gb2312 > gb2312.h < gb2312 + * ./cjk_tab_to_h JISX0208.1983-0 jisx0208 > jisx0208.h < jis0208 + * ./cjk_tab_to_h KSC5601.1987-0 ksc5601 > ksc5601.h < ksc5601 + * + * ./cjk_tab_to_h GB2312.1980-0 gb2312 > gb2312.h < GB2312.TXT + * ./cjk_tab_to_h JISX0208.1983-0 jisx0208 > jisx0208.h < JIS0208.TXT + * ./cjk_tab_to_h JISX0212.1990-0 jisx0212 > jisx0212.h < JIS0212.TXT + * ./cjk_tab_to_h KSC5601.1987-0 ksc5601 > ksc5601.h < KSC5601.TXT + * ./cjk_tab_to_h KSX1001.1992-0 ksc5601 > ksc5601.h < KSX1001.TXT + * + * ./cjk_tab_to_h BIG5 big5 > big5.h < BIG5.TXT + * + * ./cjk_tab_to_h JOHAB johab > johab.h < JOHAB.TXT + */ + +#include +#include +#include +#include + +typedef struct { + int start; + int end; +} Block; + +typedef struct { + int rows; /* number of possible values for the 1st byte */ + int cols; /* number of possible values for the 2nd byte */ + int (*row_byte) (int row); /* returns the 1st byte value for a given row */ + int (*col_byte) (int col); /* returns the 2nd byte value for a given col */ + int (*byte_row) (int byte); /* converts a 1st byte value to a row, else -1 */ + int (*byte_col) (int byte); /* converts a 2nd byte value to a col, else -1 */ + const char* check_row_expr; /* format string for 1st byte value checking */ + const char* check_col_expr; /* format string for 2nd byte value checking */ + const char* byte_row_expr; /* format string for 1st byte value to row */ + const char* byte_col_expr; /* format string for 2nd byte value to col */ + int** charset2uni; /* charset2uni[0..rows-1][0..cols-1] is valid */ + /* You'll understand the terms "row" and "col" when you buy Ken Lunde's book. + Once a row is fixed, choosing a "col" is the same as choosing a "cell". */ + int* charsetpage; /* charsetpage[0..rows]: how large is a page for a row */ + int ncharsetblocks; + Block* charsetblocks; /* blocks[0..nblocks-1] */ + int* uni2charset; /* uni2charset[0x0000..0xffff] */ +} Encoding; + +/* + * Outputs the file title. + */ +static void output_title (const char *charsetname) +{ + printf("\n"); + printf("/*\n"); + printf(" * %s\n", charsetname); + printf(" */\n"); + printf("\n"); +} + +/* + * Reads the charset2uni table from standard input. + */ +static void read_table (Encoding* enc) +{ + int row, col, i, i1, i2, c, j; + + enc->charset2uni = (int**) malloc(enc->rows*sizeof(int*)); + for (row = 0; row < enc->rows; row++) + enc->charset2uni[row] = (int*) malloc(enc->cols*sizeof(int)); + + for (row = 0; row < enc->rows; row++) + for (col = 0; col < enc->cols; col++) + enc->charset2uni[row][col] = 0xfffd; + + c = getc(stdin); + ungetc(c,stdin); + if (c == '#') { + /* Read a unicode.org style .TXT file. */ + for (;;) { + c = getc(stdin); + if (c == EOF) + break; + if (c == '\n' || c == ' ' || c == '\t') + continue; + if (c == '#') { + do { c = getc(stdin); } while (!(c == EOF || c == '\n')); + continue; + } + ungetc(c,stdin); + if (scanf("0x%x", &j) != 1) + exit(1); + i1 = j >> 8; + i2 = j & 0xff; + row = enc->byte_row(i1); + col = enc->byte_col(i2); + if (row < 0 || col < 0) { + fprintf(stderr, "lost entry for %02x %02x\n", i1, i2); + exit(1); + } + if (scanf(" 0x%x", &enc->charset2uni[row][col]) != 1) + exit(1); + } + } else { + /* Read a table of hexadecimal Unicode values. */ + for (i1 = 32; i1 < 132; i1++) + for (i2 = 32; i2 < 132; i2++) { + i = scanf("%x", &j); + if (i == EOF) + goto read_done; + if (i != 1) + exit(1); + if (j < 0 || j == 0xffff) + j = 0xfffd; + if (j != 0xfffd) { + if (enc->byte_row(i1) < 0 || enc->byte_col(i2) < 0) { + fprintf(stderr, "lost entry at %02x %02x\n", i1, i2); + exit (1); + } + enc->charset2uni[enc->byte_row(i1)][enc->byte_col(i2)] = j; + } + } + read_done: ; + } +} + +/* + * Computes the charsetpage[0..rows] array. + */ +static void find_charset2uni_pages (Encoding* enc) +{ + int row, col; + + enc->charsetpage = (int*) malloc((enc->rows+1)*sizeof(int)); + + for (row = 0; row <= enc->rows; row++) + enc->charsetpage[row] = 0; + + for (row = 0; row < enc->rows; row++) { + int used = 0; + for (col = 0; col < enc->cols; col++) + if (enc->charset2uni[row][col] != 0xfffd) + used = col+1; + enc->charsetpage[row] = used; + } +} + +/* + * Fills in nblocks and blocks. + */ +static void find_charset2uni_blocks (Encoding* enc) +{ + int n, row, lastrow; + + enc->charsetblocks = (Block*) malloc(enc->rows*sizeof(Block)); + + n = 0; + for (row = 0; row < enc->rows; row++) + if (enc->charsetpage[row] > 0 && (row == 0 || enc->charsetpage[row-1] == 0)) { + for (lastrow = row; enc->charsetpage[lastrow+1] > 0; lastrow++); + enc->charsetblocks[n].start = row * enc->cols; + enc->charsetblocks[n].end = lastrow * enc->cols + enc->charsetpage[lastrow]; + n++; + } + enc->ncharsetblocks = n; +} + +/* + * Outputs the charset to unicode table and function. + */ +static void output_charset2uni (const char* name, Encoding* enc) +{ + int row, col, lastrow, col_max, i, i1_min, i1_max; + + find_charset2uni_pages(enc); + + find_charset2uni_blocks(enc); + + for (row = 0; row < enc->rows; row++) + if (enc->charsetpage[row] > 0) { + if (row == 0 || enc->charsetpage[row-1] == 0) { + /* Start a new block. */ + for (lastrow = row; enc->charsetpage[lastrow+1] > 0; lastrow++); + printf("static const unsigned short %s_2uni_page%02x[%d] = {\n", + name, enc->row_byte(row), + (lastrow-row) * enc->cols + enc->charsetpage[lastrow]); + } + printf(" /""* 0x%02x *""/\n ", enc->row_byte(row)); + col_max = (enc->charsetpage[row+1] > 0 ? enc->cols : enc->charsetpage[row]); + for (col = 0; col < col_max; col++) { + printf(" 0x%04x,", enc->charset2uni[row][col]); + if ((col % 8) == 7 && (col+1 < col_max)) printf("\n "); + } + printf("\n"); + if (enc->charsetpage[row+1] == 0) { + /* End a block. */ + printf("};\n"); + } + } + printf("\n"); + + printf("static int\n"); + printf("%s_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n)\n", name); + printf("{\n"); + printf(" unsigned char c1 = s[0];\n"); + printf(" if ("); + for (i = 0; i < enc->ncharsetblocks; i++) { + i1_min = enc->row_byte(enc->charsetblocks[i].start / enc->cols); + i1_max = enc->row_byte((enc->charsetblocks[i].end-1) / enc->cols); + if (i > 0) + printf(" || "); + if (i1_min == i1_max) + printf("(c1 == 0x%02x)", i1_min); + else + printf("(c1 >= 0x%02x && c1 <= 0x%02x)", i1_min, i1_max); + } + printf(") {\n"); + printf(" if (n >= 2) {\n"); + printf(" unsigned char c2 = s[1];\n"); + printf(" if ("); + printf(enc->check_col_expr, "c2"); + printf(") {\n"); + printf(" unsigned int i = %d * (", enc->cols); + printf(enc->byte_row_expr, "c1"); + printf(") + ("); + printf(enc->byte_col_expr, "c2"); + printf(");\n"); + printf(" unsigned short wc = 0xfffd;\n"); + for (i = 0; i < enc->ncharsetblocks; i++) { + printf(" "); + if (i > 0) + printf("} else "); + if (i < enc->ncharsetblocks-1) + printf("if (i < %d) ", enc->charsetblocks[i+1].start); + printf("{\n"); + printf(" if (i < %d)\n", enc->charsetblocks[i].end); + printf(" wc = %s_2uni_page%02x[i", name, enc->row_byte(enc->charsetblocks[i].start / enc->cols)); + if (enc->charsetblocks[i].start > 0) + printf("-%d", enc->charsetblocks[i].start); + printf("];\n"); + } + printf(" }\n"); + printf(" if (wc != 0xfffd) {\n"); + printf(" *pwc = (ucs4_t) wc;\n"); + printf(" return 2;\n"); + printf(" }\n"); + printf(" }\n"); + printf(" return RET_ILSEQ;\n"); + printf(" }\n"); + printf(" return RET_TOOFEW(0);\n"); + printf(" }\n"); + printf(" return RET_ILSEQ;\n"); + printf("}\n"); + printf("\n"); +} + +/* + * Computes the uni2charset[0x0000..0xffff] array. + */ +static void invert (Encoding* enc) +{ + int row, col, j; + + enc->uni2charset = (int*) malloc(0x10000*sizeof(int)); + + for (j = 0; j < 0x10000; j++) + enc->uni2charset[j] = 0; + + for (row = 0; row < enc->rows; row++) + for (col = 0; col < enc->cols; col++) { + j = enc->charset2uni[row][col]; + if (j != 0xfffd) + enc->uni2charset[j] = 0x100 * enc->row_byte(row) + enc->col_byte(col); + } +} + +/* + * Outputs the unicode to charset table and function, using a linear array. + * (Suitable if the table is dense.) + */ +static void output_uni2charset_dense (const char* name, Encoding* enc) +{ + /* Like in 8bit_tab_to_h.c */ + bool pages[0x100]; + int line[0x2000]; + int tableno; + struct { int minline; int maxline; int usecount; } tables[0x2000]; + bool first; + int row, col, j, p, j1, j2, t; + + for (p = 0; p < 0x100; p++) + pages[p] = false; + for (row = 0; row < enc->rows; row++) + for (col = 0; col < enc->cols; col++) { + j = enc->charset2uni[row][col]; + if (j != 0xfffd) + pages[j>>8] = true; + } + for (j1 = 0; j1 < 0x2000; j1++) { + bool all_invalid = true; + for (j2 = 0; j2 < 8; j2++) { + j = 8*j1+j2; + if (enc->uni2charset[j] != 0) + all_invalid = false; + } + if (all_invalid) + line[j1] = -1; + else + line[j1] = 0; + } + tableno = 0; + for (j1 = 0; j1 < 0x2000; j1++) { + if (line[j1] >= 0) { + if (tableno > 0 + && ((j1 > 0 && line[j1-1] == tableno-1) + || ((tables[tableno-1].maxline >> 5) == (j1 >> 5) + && j1 - tables[tableno-1].maxline <= 8))) { + line[j1] = tableno-1; + tables[tableno-1].maxline = j1; + } else { + tableno++; + line[j1] = tableno-1; + tables[tableno-1].minline = tables[tableno-1].maxline = j1; + } + } + } + for (t = 0; t < tableno; t++) { + tables[t].usecount = 0; + j1 = 8*tables[t].minline; + j2 = 8*(tables[t].maxline+1); + for (j = j1; j < j2; j++) + if (enc->uni2charset[j] != 0) + tables[t].usecount++; + } + { + p = -1; + for (t = 0; t < tableno; t++) + if (tables[t].usecount > 1) { + p = tables[t].minline >> 5; + printf("static const unsigned short %s_page%02x[%d] = {\n", name, p, 8*(tables[t].maxline-tables[t].minline+1)); + for (j1 = tables[t].minline; j1 <= tables[t].maxline; j1++) { + if ((j1 % 0x20) == 0 && j1 > tables[t].minline) + printf(" /* 0x%04x */\n", 8*j1); + printf(" "); + for (j2 = 0; j2 < 8; j2++) { + j = 8*j1+j2; + printf(" 0x%04x,", enc->uni2charset[j]); + } + printf(" /*0x%02x-0x%02x*/\n", 8*(j1 % 0x20), 8*(j1 % 0x20)+7); + } + printf("};\n"); + } + if (p >= 0) + printf("\n"); + } + printf("static int\n%s_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n)\n", name); + printf("{\n"); + printf(" if (n >= 2) {\n"); + printf(" unsigned short c = 0;\n"); + first = true; + for (j1 = 0; j1 < 0x2000;) { + t = line[j1]; + for (j2 = j1; j2 < 0x2000 && line[j2] == t; j2++); + if (t >= 0) { + if (j1 != tables[t].minline) abort(); + if (j2 > tables[t].maxline+1) abort(); + j2 = tables[t].maxline+1; + if (first) + printf(" "); + else + printf(" else "); + first = false; + if (tables[t].usecount == 0) abort(); + if (tables[t].usecount == 1) { + if (j2 != j1+1) abort(); + for (j = 8*j1; j < 8*j2; j++) + if (enc->uni2charset[j] != 0) { + printf("if (wc == 0x%04x)\n c = 0x%02x;\n", j, enc->uni2charset[j]); + break; + } + } else { + if (j1 == 0) { + printf("if (wc < 0x%04x)", 8*j2); + } else { + printf("if (wc >= 0x%04x && wc < 0x%04x)", 8*j1, 8*j2); + } + printf("\n c = %s_page%02x[wc", name, j1 >> 5); + if (tables[t].minline > 0) + printf("-0x%04x", 8*j1); + printf("];\n"); + } + } + j1 = j2; + } + printf(" if (c != 0) {\n"); + printf(" r[0] = (c >> 8); r[1] = (c & 0xff);\n"); + printf(" return 2;\n"); + printf(" }\n"); + printf(" return RET_ILSEQ;\n"); + printf(" }\n"); + printf(" return RET_TOOSMALL;\n"); + printf("}\n"); +} + +/* + * Outputs the unicode to charset table and function, using a packed array. + * (Suitable if the table is sparse.) + */ +static void output_uni2charset_sparse (const char* name, Encoding* enc) +{ + bool pages[0x100]; + Block pageblocks[0x100]; int npageblocks; + int indx2charset[0x10000]; + int summary_indx[0x1000]; + int summary_used[0x1000]; + int i, row, col, j, p, j1, j2, indx; + + /* Fill pages[0x100]. */ + for (p = 0; p < 0x100; p++) + pages[p] = false; + for (row = 0; row < enc->rows; row++) + for (col = 0; col < enc->cols; col++) { + j = enc->charset2uni[row][col]; + if (j != 0xfffd) + pages[j>>8] = true; + } + +#if 0 + for (p = 0; p < 0x100; p++) + if (pages[p]) { + printf("static const unsigned short %s_page%02x[256] = {\n", name, p); + for (j1 = 0; j1 < 32; j1++) { + printf(" "); + for (j2 = 0; j2 < 8; j2++) + printf("0x%04x, ", enc->uni2charset[256*p+8*j1+j2]); + printf("/""*0x%02x-0x%02x*""/\n", 8*j1, 8*j1+7); + } + printf("};\n"); + } + printf("\n"); +#endif + + /* Fill summary_indx[] and summary_used[]. */ + indx = 0; + for (j1 = 0; j1 < 0x1000; j1++) { + summary_indx[j1] = indx; + summary_used[j1] = 0; + for (j2 = 0; j2 < 16; j2++) { + j = 16*j1+j2; + if (enc->uni2charset[j] != 0) { + indx2charset[indx++] = enc->uni2charset[j]; + summary_used[j1] |= (1 << j2); + } + } + } + + /* Fill npageblocks and pageblocks[]. */ + npageblocks = 0; + for (p = 0; p < 0x100; ) { + if (pages[p] && (p == 0 || !pages[p-1])) { + pageblocks[npageblocks].start = 16*p; + do p++; while (p < 0x100 && pages[p]); + j1 = 16*p; + while (summary_used[j1-1] == 0) j1--; + pageblocks[npageblocks].end = j1; + npageblocks++; + } else + p++; + } + + printf("static const unsigned short %s_2charset[%d] = {\n", name, indx); + for (i = 0; i < indx; ) { + if ((i % 8) == 0) printf(" "); + printf(" 0x%04x,", indx2charset[i]); + i++; + if ((i % 8) == 0 || i == indx) printf("\n"); + } + printf("};\n"); + printf("\n"); + for (i = 0; i < npageblocks; i++) { + printf("static const Summary16 %s_uni2indx_page%02x[%d] = {\n", name, + pageblocks[i].start/16, pageblocks[i].end-pageblocks[i].start); + for (j1 = pageblocks[i].start; j1 < pageblocks[i].end; ) { + if (((16*j1) % 0x100) == 0) printf(" /""* 0x%04x *""/\n", 16*j1); + if ((j1 % 4) == 0) printf(" "); + printf(" { %4d, 0x%04x },", summary_indx[j1], summary_used[j1]); + j1++; + if ((j1 % 4) == 0 || j1 == pageblocks[i].end) printf("\n"); + } + printf("};\n"); + } + printf("\n"); + + printf("static int\n"); + printf("%s_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n)\n", name); + printf("{\n"); + printf(" if (n >= 2) {\n"); + printf(" const Summary16 *summary = NULL;\n"); + for (i = 0; i < npageblocks; i++) { + printf(" "); + if (i > 0) + printf("else "); + printf("if (wc >= 0x%04x && wc < 0x%04x)\n", + 16*pageblocks[i].start, 16*pageblocks[i].end); + printf(" summary = &%s_uni2indx_page%02x[(wc>>4)", name, + pageblocks[i].start/16); + if (pageblocks[i].start > 0) + printf("-0x%03x", pageblocks[i].start); + printf("];\n"); + } + printf(" if (summary) {\n"); + printf(" unsigned short used = summary->used;\n"); + printf(" unsigned int i = wc & 0x0f;\n"); + printf(" if (used & ((unsigned short) 1 << i)) {\n"); + printf(" unsigned short c;\n"); + printf(" /* Keep in `used' only the bits 0..i-1. */\n"); + printf(" used &= ((unsigned short) 1 << i) - 1;\n"); + printf(" /* Add `summary->indx' and the number of bits set in `used'. */\n"); + printf(" used = (used & 0x5555) + ((used & 0xaaaa) >> 1);\n"); + printf(" used = (used & 0x3333) + ((used & 0xcccc) >> 2);\n"); + printf(" used = (used & 0x0f0f) + ((used & 0xf0f0) >> 4);\n"); + printf(" used = (used & 0x00ff) + (used >> 8);\n"); + printf(" c = %s_2charset[summary->indx + used];\n", name); + printf(" r[0] = (c >> 8); r[1] = (c & 0xff);\n"); + printf(" return 2;\n"); + printf(" }\n"); + printf(" }\n"); + printf(" return RET_ILSEQ;\n"); + printf(" }\n"); + printf(" return RET_TOOSMALL;\n"); + printf("}\n"); +} + +/* ISO-2022/EUC specifics */ + +static int row_byte_normal (int row) { return 0x21+row; } +static int col_byte_normal (int col) { return 0x21+col; } +static int byte_row_normal (int byte) { return byte-0x21; } +static int byte_col_normal (int byte) { return byte-0x21; } + +static void do_normal (const char* name) +{ + Encoding enc; + + enc.rows = 94; + enc.cols = 94; + enc.row_byte = row_byte_normal; + enc.col_byte = col_byte_normal; + enc.byte_row = byte_row_normal; + enc.byte_col = byte_col_normal; + enc.check_row_expr = "%1$s >= 0x21 && %1$s < 0x7f"; + enc.check_col_expr = "%1$s >= 0x21 && %1$s < 0x7f"; + enc.byte_row_expr = "%1$s - 0x21"; + enc.byte_col_expr = "%1$s - 0x21"; + + read_table(&enc); + output_charset2uni(name,&enc); + invert(&enc); output_uni2charset_sparse(name,&enc); +} + +/* Note: On first sight, the jisx0212_2charset[] table seems to be in order, + starting from the charset=0x3021/uni=0x4e02 pair. But it's only mostly in + order. There are 75 out-of-order values, scattered all throughout the table. + */ + +static void do_normal_only_charset2uni (const char* name) +{ + Encoding enc; + + enc.rows = 94; + enc.cols = 94; + enc.row_byte = row_byte_normal; + enc.col_byte = col_byte_normal; + enc.byte_row = byte_row_normal; + enc.byte_col = byte_col_normal; + enc.check_row_expr = "%1$s >= 0x21 && %1$s < 0x7f"; + enc.check_col_expr = "%1$s >= 0x21 && %1$s < 0x7f"; + enc.byte_row_expr = "%1$s - 0x21"; + enc.byte_col_expr = "%1$s - 0x21"; + + read_table(&enc); + output_charset2uni(name,&enc); +} + +/* CNS 11643 specifics - trick to put two tables into one */ + +static int row_byte_cns11643 (int row) { + return 0x100 * (row / 94) + (row % 94) + 0x21; +} +static int byte_row_cns11643 (int byte) { + return (byte >= 0x100 && byte < 0x200 ? byte-0x121 : + byte >= 0x200 && byte < 0x300 ? byte-0x221+94 : + byte >= 0x300 && byte < 0x400 ? byte-0x321+2*94 : + -1); +} + +static void do_cns11643_only_uni2charset (const char* name) +{ + Encoding enc; + int j, x; + + enc.rows = 3*94; + enc.cols = 94; + enc.row_byte = row_byte_cns11643; + enc.col_byte = col_byte_normal; + enc.byte_row = byte_row_cns11643; + enc.byte_col = byte_col_normal; + enc.check_row_expr = "%1$s >= 0x21 && %1$s < 0x7f"; + enc.check_col_expr = "%1$s >= 0x21 && %1$s < 0x7f"; + enc.byte_row_expr = "%1$s - 0x21"; + enc.byte_col_expr = "%1$s - 0x21"; + + read_table(&enc); + invert(&enc); + /* Move the 2 plane bits into the unused bits 15 and 7. */ + for (j = 0; j < 0x10000; j++) { + x = enc.uni2charset[j]; + if (x != 0) { + if (x & 0x8080) abort(); + switch (x >> 16) { + case 0: /* plane 1 */ x = (x & 0xffff) | 0x0000; break; + case 1: /* plane 2 */ x = (x & 0xffff) | 0x0080; break; + case 2: /* plane 3 */ x = (x & 0xffff) | 0x8000; break; + default: abort(); + } + enc.uni2charset[j] = x; + } + } + output_uni2charset_sparse(name,&enc); +} + +/* GBK specifics */ + +static int row_byte_gbk1 (int row) { + return 0x81+row; +} +static int col_byte_gbk1 (int col) { + return (col >= 0x3f ? 0x41 : 0x40) + col; +} +static int byte_row_gbk1 (int byte) { + if (byte >= 0x81 && byte < 0xff) + return byte-0x81; + else + return -1; +} +static int byte_col_gbk1 (int byte) { + if (byte >= 0x40 && byte < 0x7f) + return byte-0x40; + else if (byte >= 0x80 && byte < 0xff) + return byte-0x41; + else + return -1; +} + +static void do_gbk1 (const char* name) +{ + Encoding enc; + + enc.rows = 126; + enc.cols = 190; + enc.row_byte = row_byte_gbk1; + enc.col_byte = col_byte_gbk1; + enc.byte_row = byte_row_gbk1; + enc.byte_col = byte_col_gbk1; + enc.check_row_expr = "%1$s >= 0x81 && %1$s < 0xff"; + enc.check_col_expr = "(%1$s >= 0x40 && %1$s < 0x7f) || (%1$s >= 0x80 && %1$s < 0xff)"; + enc.byte_row_expr = "%1$s - 0x81"; + enc.byte_col_expr = "%1$s - (%1$s >= 0x80 ? 0x41 : 0x40)"; + + read_table(&enc); + output_charset2uni(name,&enc); + invert(&enc); output_uni2charset_dense(name,&enc); +} + +static void do_gbk1_only_charset2uni (const char* name) +{ + Encoding enc; + + enc.rows = 126; + enc.cols = 190; + enc.row_byte = row_byte_gbk1; + enc.col_byte = col_byte_gbk1; + enc.byte_row = byte_row_gbk1; + enc.byte_col = byte_col_gbk1; + enc.check_row_expr = "%1$s >= 0x81 && %1$s < 0xff"; + enc.check_col_expr = "(%1$s >= 0x40 && %1$s < 0x7f) || (%1$s >= 0x80 && %1$s < 0xff)"; + enc.byte_row_expr = "%1$s - 0x81"; + enc.byte_col_expr = "%1$s - (%1$s >= 0x80 ? 0x41 : 0x40)"; + + read_table(&enc); + output_charset2uni(name,&enc); +} + +static int row_byte_gbk2 (int row) { + return 0x81+row; +} +static int col_byte_gbk2 (int col) { + return (col >= 0x3f ? 0x41 : 0x40) + col; +} +static int byte_row_gbk2 (int byte) { + if (byte >= 0x81 && byte < 0xff) + return byte-0x81; + else + return -1; +} +static int byte_col_gbk2 (int byte) { + if (byte >= 0x40 && byte < 0x7f) + return byte-0x40; + else if (byte >= 0x80 && byte < 0xa1) + return byte-0x41; + else + return -1; +} + +static void do_gbk2_only_charset2uni (const char* name) +{ + Encoding enc; + + enc.rows = 126; + enc.cols = 96; + enc.row_byte = row_byte_gbk2; + enc.col_byte = col_byte_gbk2; + enc.byte_row = byte_row_gbk2; + enc.byte_col = byte_col_gbk2; + enc.check_row_expr = "%1$s >= 0x81 && %1$s < 0xff"; + enc.check_col_expr = "(%1$s >= 0x40 && %1$s < 0x7f) || (%1$s >= 0x80 && %1$s < 0xa1)"; + enc.byte_row_expr = "%1$s - 0x81"; + enc.byte_col_expr = "%1$s - (%1$s >= 0x80 ? 0x41 : 0x40)"; + + read_table(&enc); + output_charset2uni(name,&enc); +} + +static void do_gbk1_only_uni2charset (const char* name) +{ + Encoding enc; + + enc.rows = 126; + enc.cols = 190; + enc.row_byte = row_byte_gbk1; + enc.col_byte = col_byte_gbk1; + enc.byte_row = byte_row_gbk1; + enc.byte_col = byte_col_gbk1; + enc.check_row_expr = "%1$s >= 0x81 && %1$s < 0xff"; + enc.check_col_expr = "(%1$s >= 0x40 && %1$s < 0x7f) || (%1$s >= 0x80 && %1$s < 0xff)"; + enc.byte_row_expr = "%1$s - 0x81"; + enc.byte_col_expr = "%1$s - (%1$s >= 0x80 ? 0x41 : 0x40)"; + + read_table(&enc); + invert(&enc); output_uni2charset_sparse(name,&enc); +} + +/* KSC 5601 specifics */ + +/* + * Reads the charset2uni table from standard input. + */ +static void read_table_ksc5601 (Encoding* enc) +{ + int row, col, i, i1, i2, c, j; + + enc->charset2uni = (int**) malloc(enc->rows*sizeof(int*)); + for (row = 0; row < enc->rows; row++) + enc->charset2uni[row] = (int*) malloc(enc->cols*sizeof(int)); + + for (row = 0; row < enc->rows; row++) + for (col = 0; col < enc->cols; col++) + enc->charset2uni[row][col] = 0xfffd; + + c = getc(stdin); + ungetc(c,stdin); + if (c == '#') { + /* Read a unicode.org style .TXT file. */ + for (;;) { + c = getc(stdin); + if (c == EOF) + break; + if (c == '\n' || c == ' ' || c == '\t') + continue; + if (c == '#') { + do { c = getc(stdin); } while (!(c == EOF || c == '\n')); + continue; + } + ungetc(c,stdin); + if (scanf("0x%x", &j) != 1) + exit(1); + i1 = j >> 8; + i2 = j & 0xff; + if (scanf(" 0x%x", &j) != 1) + exit(1); + /* Take only the range covered by KS C 5601.1987-0 = KS C 5601.1989-0 + = KS X 1001.1992, ignore the rest. */ + if (!(i1 >= 128+33 && i1 < 128+127 && i2 >= 128+33 && i2 < 128+127)) + continue; /* KSC5601 specific */ + i1 &= 0x7f; /* KSC5601 specific */ + i2 &= 0x7f; /* KSC5601 specific */ + row = enc->byte_row(i1); + col = enc->byte_col(i2); + if (row < 0 || col < 0) { + fprintf(stderr, "lost entry for %02x %02x\n", i1, i2); + exit(1); + } + enc->charset2uni[row][col] = j; + } + } else { + /* Read a table of hexadecimal Unicode values. */ + for (i1 = 33; i1 < 127; i1++) + for (i2 = 33; i2 < 127; i2++) { + i = scanf("%x", &j); + if (i == EOF) + goto read_done; + if (i != 1) + exit(1); + if (j < 0 || j == 0xffff) + j = 0xfffd; + if (j != 0xfffd) { + if (enc->byte_row(i1) < 0 || enc->byte_col(i2) < 0) { + fprintf(stderr, "lost entry at %02x %02x\n", i1, i2); + exit (1); + } + enc->charset2uni[enc->byte_row(i1)][enc->byte_col(i2)] = j; + } + } + read_done: ; + } +} + +static void do_ksc5601 (const char* name) +{ + Encoding enc; + + enc.rows = 94; + enc.cols = 94; + enc.row_byte = row_byte_normal; + enc.col_byte = col_byte_normal; + enc.byte_row = byte_row_normal; + enc.byte_col = byte_col_normal; + enc.check_row_expr = "%1$s >= 0x21 && %1$s < 0x7f"; + enc.check_col_expr = "%1$s >= 0x21 && %1$s < 0x7f"; + enc.byte_row_expr = "%1$s - 0x21"; + enc.byte_col_expr = "%1$s - 0x21"; + + read_table_ksc5601(&enc); + output_charset2uni(name,&enc); + invert(&enc); output_uni2charset_sparse(name,&enc); +} + +/* Big5 specifics */ + +static int row_byte_big5 (int row) { + return 0xa1+row; +} +static int col_byte_big5 (int col) { + return (col >= 0x3f ? 0x62 : 0x40) + col; +} +static int byte_row_big5 (int byte) { + if (byte >= 0xa1 && byte < 0xff) + return byte-0xa1; + else + return -1; +} +static int byte_col_big5 (int byte) { + if (byte >= 0x40 && byte < 0x7f) + return byte-0x40; + else if (byte >= 0xa1 && byte < 0xff) + return byte-0x62; + else + return -1; +} + +static void do_big5 (const char* name) +{ + Encoding enc; + + enc.rows = 94; + enc.cols = 157; + enc.row_byte = row_byte_big5; + enc.col_byte = col_byte_big5; + enc.byte_row = byte_row_big5; + enc.byte_col = byte_col_big5; + enc.check_row_expr = "%1$s >= 0xa1 && %1$s < 0xff"; + enc.check_col_expr = "(%1$s >= 0x40 && %1$s < 0x7f) || (%1$s >= 0xa1 && %1$s < 0xff)"; + enc.byte_row_expr = "%1$s - 0xa1"; + enc.byte_col_expr = "%1$s - (%1$s >= 0xa1 ? 0x62 : 0x40)"; + + read_table(&enc); + output_charset2uni(name,&enc); + invert(&enc); output_uni2charset_sparse(name,&enc); +} + +/* Johab Hangul specifics */ + +static int row_byte_johab_hangul (int row) { + return 0x84+row; +} +static int col_byte_johab_hangul (int col) { + return (col >= 0x3e ? 0x43 : 0x41) + col; +} +static int byte_row_johab_hangul (int byte) { + if (byte >= 0x84 && byte < 0xd4) + return byte-0x84; + else + return -1; +} +static int byte_col_johab_hangul (int byte) { + if (byte >= 0x41 && byte < 0x7f) + return byte-0x41; + else if (byte >= 0x81 && byte < 0xff) + return byte-0x43; + else + return -1; +} + +static void do_johab_hangul (const char* name) +{ + Encoding enc; + + enc.rows = 80; + enc.cols = 188; + enc.row_byte = row_byte_johab_hangul; + enc.col_byte = col_byte_johab_hangul; + enc.byte_row = byte_row_johab_hangul; + enc.byte_col = byte_col_johab_hangul; + enc.check_row_expr = "%1$s >= 0x84 && %1$s < 0xd4"; + enc.check_col_expr = "(%1$s >= 0x41 && %1$s < 0x7f) || (%1$s >= 0x81 && %1$s < 0xff)"; + enc.byte_row_expr = "%1$s - 0x84"; + enc.byte_col_expr = "%1$s - (%1$s >= 0x81 ? 0x43 : 0x41)"; + + read_table(&enc); + output_charset2uni(name,&enc); + invert(&enc); output_uni2charset_dense(name,&enc); +} + +/* SJIS specifics */ + +static int row_byte_sjis (int row) { + return (row >= 0x1f ? 0xc1 : 0x81) + row; +} +static int col_byte_sjis (int col) { + return (col >= 0x3f ? 0x41 : 0x40) + col; +} +static int byte_row_sjis (int byte) { + if (byte >= 0x81 && byte < 0xa0) + return byte-0x81; + else if (byte >= 0xe0) + return byte-0xc1; + else + return -1; +} +static int byte_col_sjis (int byte) { + if (byte >= 0x40 && byte < 0x7f) + return byte-0x40; + else if (byte >= 0x80 && byte < 0xfd) + return byte-0x41; + else + return -1; +} + +static void do_sjis (const char* name) +{ + Encoding enc; + + enc.rows = 94; + enc.cols = 188; + enc.row_byte = row_byte_sjis; + enc.col_byte = col_byte_sjis; + enc.byte_row = byte_row_sjis; + enc.byte_col = byte_col_sjis; + enc.check_row_expr = "(%1$s >= 0x81 && %1$s < 0xa0) || (%1$s >= 0xe0)"; + enc.check_col_expr = "(%1$s >= 0x40 && %1$s < 0x7f) || (%1$s >= 0x80 && %1$s < 0xfd)"; + enc.byte_row_expr = "%1$s - (%1$s >= 0xe0 ? 0xc1 : 0x81)"; + enc.byte_col_expr = "%1$s - (%1$s >= 0x80 ? 0x41 : 0x40)"; + + read_table(&enc); + output_charset2uni(name,&enc); + invert(&enc); output_uni2charset_sparse(name,&enc); +} + +/* Main program */ + +int main (int argc, char *argv[]) +{ + const char* charsetname; + const char* name; + + if (argc != 3) + exit(1); + charsetname = argv[1]; + name = argv[2]; + + output_title(charsetname); + + if (!strcmp(name,"gb2312") || !strcmp(name,"gb12345ext") + || !strcmp(name,"jisx0208") || !strcmp(name,"jisx0212")) + do_normal(name); + else if (!strcmp(name,"cns11643_1") || !strcmp(name,"cns11643_2") + || !strcmp(name,"cns11643_3")) + do_normal_only_charset2uni(name); + else if (!strcmp(name,"cns11643_inv")) + do_cns11643_only_uni2charset(name); + else if (!strcmp(name,"gbkext1")) + do_gbk1_only_charset2uni(name); + else if (!strcmp(name,"gbkext2")) + do_gbk2_only_charset2uni(name); + else if (!strcmp(name,"gbkext_inv")) + do_gbk1_only_uni2charset(name); + else if (!strcmp(name,"cp936ext")) + do_gbk1(name); + else if (!strcmp(name,"ksc5601")) + do_ksc5601(name); + else if (!strcmp(name,"big5") || !strcmp(name,"cp950ext")) + do_big5(name); + else if (!strcmp(name,"johab_hangul")) + do_johab_hangul(name); + else if (!strcmp(name,"cp932ext")) + do_sjis(name); + else + exit(1); + + return 0; +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/cp1133.h b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/cp1133.h new file mode 100644 index 0000000..da7f589 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/cp1133.h @@ -0,0 +1,92 @@ +/* $XFree86: xc/lib/X11/lcUniConv/cp1133.h,v 1.3 2000/11/29 17:40:28 dawes Exp $ */ + +/* + * IBM-CP1133 + */ + +static const unsigned short cp1133_2uni_1[64] = { + /* 0xa0 */ + 0x00a0, 0x0e81, 0x0e82, 0x0e84, 0x0e87, 0x0e88, 0x0eaa, 0x0e8a, + 0x0e8d, 0x0e94, 0x0e95, 0x0e96, 0x0e97, 0x0e99, 0x0e9a, 0x0e9b, + /* 0xb0 */ + 0x0e9c, 0x0e9d, 0x0e9e, 0x0e9f, 0x0ea1, 0x0ea2, 0x0ea3, 0x0ea5, + 0x0ea7, 0x0eab, 0x0ead, 0x0eae, 0xfffd, 0xfffd, 0xfffd, 0x0eaf, + /* 0xc0 */ + 0x0eb0, 0x0eb2, 0x0eb3, 0x0eb4, 0x0eb5, 0x0eb6, 0x0eb7, 0x0eb8, + 0x0eb9, 0x0ebc, 0x0eb1, 0x0ebb, 0x0ebd, 0xfffd, 0xfffd, 0xfffd, + /* 0xd0 */ + 0x0ec0, 0x0ec1, 0x0ec2, 0x0ec3, 0x0ec4, 0x0ec8, 0x0ec9, 0x0eca, + 0x0ecb, 0x0ecc, 0x0ecd, 0x0ec6, 0xfffd, 0x0edc, 0x0edd, 0x20ad, +}; +static const unsigned short cp1133_2uni_2[16] = { + /* 0xf0 */ + 0x0ed0, 0x0ed1, 0x0ed2, 0x0ed3, 0x0ed4, 0x0ed5, 0x0ed6, 0x0ed7, + 0x0ed8, 0x0ed9, 0xfffd, 0xfffd, 0x00a2, 0x00ac, 0x00a6, 0xfffd, +}; + +static int +cp1133_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0xa0) { + *pwc = (ucs4_t) c; + return 1; + } + else if (c < 0xe0) { + unsigned short wc = cp1133_2uni_1[c-0xa0]; + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 1; + } + } + else if (c < 0xf0) { + } + else { + unsigned short wc = cp1133_2uni_2[c-0xf0]; + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 1; + } + } + return RET_ILSEQ; +} + +static const unsigned char cp1133_page00[16] = { + 0xa0, 0x00, 0xfc, 0x00, 0x00, 0x00, 0xfe, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ +}; +static const unsigned char cp1133_page0e[96] = { + 0x00, 0xa1, 0xa2, 0x00, 0xa3, 0x00, 0x00, 0xa4, /* 0x80-0x87 */ + 0xa5, 0x00, 0xa7, 0x00, 0x00, 0xa8, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0xa9, 0xaa, 0xab, 0xac, /* 0x90-0x97 */ + 0x00, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, /* 0x98-0x9f */ + 0x00, 0xb4, 0xb5, 0xb6, 0x00, 0xb7, 0x00, 0xb8, /* 0xa0-0xa7 */ + 0x00, 0x00, 0xa6, 0xb9, 0x00, 0xba, 0xbb, 0xbf, /* 0xa8-0xaf */ + 0xc0, 0xca, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, /* 0xb0-0xb7 */ + 0xc7, 0xc8, 0x00, 0xcb, 0xc9, 0xcc, 0x00, 0x00, /* 0xb8-0xbf */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0x00, 0xdb, 0x00, /* 0xc0-0xc7 */ + 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0x00, 0x00, /* 0xc8-0xcf */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xd0-0xd7 */ + 0xf8, 0xf9, 0x00, 0x00, 0xdd, 0xde, 0x00, 0x00, /* 0xd8-0xdf */ +}; + +static int +cp1133_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x00a0) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x00b0) + c = cp1133_page00[wc-0x00a0]; + else if (wc >= 0x0e80 && wc < 0x0ee0) + c = cp1133_page0e[wc-0x0e80]; + else if (wc == 0x20ad) + c = 0xdf; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILSEQ; +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/cp1251.h b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/cp1251.h new file mode 100644 index 0000000..f3f7577 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/cp1251.h @@ -0,0 +1,113 @@ +/* $XFree86: xc/lib/X11/lcUniConv/cp1251.h,v 1.1 2000/12/04 18:49:32 dawes Exp $ */ + +/* + * CP1251 + */ + +static const unsigned short cp1251_2uni[128] = { + /* 0x80 */ + 0x0402, 0x0403, 0x201a, 0x0453, 0x201e, 0x2026, 0x2020, 0x2021, + 0x20ac, 0x2030, 0x0409, 0x2039, 0x040a, 0x040c, 0x040b, 0x040f, + /* 0x90 */ + 0x0452, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + 0xfffd, 0x2122, 0x0459, 0x203a, 0x045a, 0x045c, 0x045b, 0x045f, + /* 0xa0 */ + 0x00a0, 0x040e, 0x045e, 0x0408, 0x00a4, 0x0490, 0x00a6, 0x00a7, + 0x0401, 0x00a9, 0x0404, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x0407, + /* 0xb0 */ + 0x00b0, 0x00b1, 0x0406, 0x0456, 0x0491, 0x00b5, 0x00b6, 0x00b7, + 0x0451, 0x2116, 0x0454, 0x00bb, 0x0458, 0x0405, 0x0455, 0x0457, + /* 0xc0 */ + 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, + 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f, + /* 0xd0 */ + 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, + 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, + /* 0xe0 */ + 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, + 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, + /* 0xf0 */ + 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, + 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f, +}; + +static int +cp1251_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) { + *pwc = (ucs4_t) c; + return 1; + } + else { + unsigned short wc = cp1251_2uni[c-0x80]; + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 1; + } + } + return RET_ILSEQ; +} + +static const unsigned char cp1251_page00[32] = { + 0xa0, 0x00, 0x00, 0x00, 0xa4, 0x00, 0xa6, 0xa7, /* 0xa0-0xa7 */ + 0x00, 0xa9, 0x00, 0xab, 0xac, 0xad, 0xae, 0x00, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0x00, 0x00, 0x00, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0xbb, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ +}; +static const unsigned char cp1251_page04[152] = { + 0x00, 0xa8, 0x80, 0x81, 0xaa, 0xbd, 0xb2, 0xaf, /* 0x00-0x07 */ + 0xa3, 0x8a, 0x8c, 0x8e, 0x8d, 0x00, 0xa1, 0x8f, /* 0x08-0x0f */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0x10-0x17 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0x18-0x1f */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0x20-0x27 */ + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, /* 0x28-0x2f */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0x30-0x37 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0x38-0x3f */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0x40-0x47 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0x48-0x4f */ + 0x00, 0xb8, 0x90, 0x83, 0xba, 0xbe, 0xb3, 0xbf, /* 0x50-0x57 */ + 0xbc, 0x9a, 0x9c, 0x9e, 0x9d, 0x00, 0xa2, 0x9f, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0xa5, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ +}; +static const unsigned char cp1251_page20[48] = { + 0x00, 0x00, 0x00, 0x96, 0x97, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x91, 0x92, 0x82, 0x00, 0x93, 0x94, 0x84, 0x00, /* 0x18-0x1f */ + 0x86, 0x87, 0x95, 0x00, 0x00, 0x00, 0x85, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x8b, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ +}; + +static int +cp1251_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x00c0) + c = cp1251_page00[wc-0x00a0]; + else if (wc >= 0x0400 && wc < 0x0498) + c = cp1251_page04[wc-0x0400]; + else if (wc >= 0x2010 && wc < 0x2040) + c = cp1251_page20[wc-0x2010]; + else if (wc == 0x20ac) + c = 0x88; + else if (wc == 0x2116) + c = 0xb9; + else if (wc == 0x2122) + c = 0x99; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILSEQ; +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/cp1255.h b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/cp1255.h new file mode 100644 index 0000000..17b843e --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/cp1255.h @@ -0,0 +1,121 @@ +/* $XFree86: xc/lib/X11/lcUniConv/cp1255.h,v 1.1 2000/12/04 18:49:33 dawes Exp $ */ + +/* + * CP1255 + */ + +static const unsigned short cp1255_2uni[128] = { + /* 0x80 */ + 0x20ac, 0xfffd, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, + 0x02c6, 0x2030, 0xfffd, 0x2039, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x90 */ + 0xfffd, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + 0x02dc, 0x2122, 0xfffd, 0x203a, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0xa0 */ + 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x20aa, 0x00a5, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, 0x00d7, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, + /* 0xb0 */ + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, + 0x00b8, 0x00b9, 0x00f7, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, + /* 0xc0 */ + 0x05b0, 0x05b1, 0x05b2, 0x05b3, 0x05b4, 0x05b5, 0x05b6, 0x05b7, + 0x05b8, 0x05b9, 0xfffd, 0x05bb, 0x05bc, 0x05bd, 0x05be, 0x05bf, + /* 0xd0 */ + 0x05c0, 0x05c1, 0x05c2, 0x05c3, 0x05f0, 0x05f1, 0x05f2, 0x05f3, + 0x05f4, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0xe0 */ + 0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, 0x05d6, 0x05d7, + 0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05dd, 0x05de, 0x05df, + /* 0xf0 */ + 0x05e0, 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5, 0x05e6, 0x05e7, + 0x05e8, 0x05e9, 0x05ea, 0xfffd, 0xfffd, 0x200e, 0x200f, 0xfffd, +}; + +static int +cp1255_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) { + *pwc = (ucs4_t) c; + return 1; + } + else { + unsigned short wc = cp1255_2uni[c-0x80]; + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 1; + } + } + return RET_ILSEQ; +} + +static const unsigned char cp1255_page00[88] = { + 0xa0, 0xa1, 0xa2, 0xa3, 0x00, 0xa5, 0xa6, 0xa7, /* 0xa0-0xa7 */ + 0xa8, 0xa9, 0x00, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0xb8, 0xb9, 0x00, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xba, /* 0xf0-0xf7 */ +}; +static const unsigned char cp1255_page02[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ +}; +static const unsigned char cp1255_page05[72] = { + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xb0-0xb7 */ + 0xc8, 0xc9, 0x00, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xb8-0xbf */ + 0xd0, 0xd1, 0xd2, 0xd3, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xd0-0xd7 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xd8-0xdf */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xe0-0xe7 */ + 0xf8, 0xf9, 0xfa, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ +}; +static const unsigned char cp1255_page20[56] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfd, 0xfe, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x96, 0x97, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x91, 0x92, 0x82, 0x00, 0x93, 0x94, 0x84, 0x00, /* 0x18-0x1f */ + 0x86, 0x87, 0x95, 0x00, 0x00, 0x00, 0x85, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x8b, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ +}; + +static int +cp1255_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x00f8) + c = cp1255_page00[wc-0x00a0]; + else if (wc == 0x0192) + c = 0x83; + else if (wc >= 0x02c0 && wc < 0x02e0) + c = cp1255_page02[wc-0x02c0]; + else if (wc >= 0x05b0 && wc < 0x05f8) + c = cp1255_page05[wc-0x05b0]; + else if (wc >= 0x2008 && wc < 0x2040) + c = cp1255_page20[wc-0x2008]; + else if (wc == 0x20aa) + c = 0xa4; + else if (wc == 0x20ac) + c = 0x80; + else if (wc == 0x2122) + c = 0x99; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILSEQ; +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/cp1256.h b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/cp1256.h new file mode 100644 index 0000000..5d4051b --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/cp1256.h @@ -0,0 +1,135 @@ +/* $XFree86: xc/lib/X11/lcUniConv/cp1256.h,v 1.1 2000/12/04 18:49:34 dawes Exp $ */ + +/* + * CP1256 + */ + +static const unsigned short cp1256_2uni[128] = { + /* 0x80 */ + 0x20ac, 0x067e, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, + 0x02c6, 0x2030, 0x0679, 0x2039, 0x0152, 0x0686, 0x0698, 0x0688, + /* 0x90 */ + 0x06af, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + 0x06a9, 0x2122, 0x0691, 0x203a, 0x0153, 0x200c, 0x200d, 0x06ba, + /* 0xa0 */ + 0x00a0, 0x060c, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, 0x06be, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, + /* 0xb0 */ + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, + 0x00b8, 0x00b9, 0x061b, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x061f, + /* 0xc0 */ + 0x06c1, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, + 0x0628, 0x0629, 0x062a, 0x062b, 0x062c, 0x062d, 0x062e, 0x062f, + /* 0xd0 */ + 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x00d7, + 0x0637, 0x0638, 0x0639, 0x063a, 0x0640, 0x0641, 0x0642, 0x0643, + /* 0xe0 */ + 0x00e0, 0x0644, 0x00e2, 0x0645, 0x0646, 0x0647, 0x0648, 0x00e7, + 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x0649, 0x064a, 0x00ee, 0x00ef, + /* 0xf0 */ + 0x064b, 0x064c, 0x064d, 0x064e, 0x00f4, 0x064f, 0x0650, 0x00f7, + 0x0651, 0x00f9, 0x0652, 0x00fb, 0x00fc, 0x200e, 0x200f, 0x06d2, +}; + +static int +cp1256_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) + *pwc = (ucs4_t) c; + else + *pwc = (ucs4_t) cp1256_2uni[c-0x80]; + return 1; +} + +static const unsigned char cp1256_page00[96] = { + 0xa0, 0x00, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0xa0-0xa7 */ + 0xa8, 0xa9, 0x00, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0xb8, 0xb9, 0x00, 0xbb, 0xbc, 0xbd, 0xbe, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd7, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0xe0, 0x00, 0xe2, 0x00, 0x00, 0x00, 0x00, 0xe7, /* 0xe0-0xe7 */ + 0xe8, 0xe9, 0xea, 0xeb, 0x00, 0x00, 0xee, 0xef, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x00, 0xf7, /* 0xf0-0xf7 */ + 0x00, 0xf9, 0x00, 0xfb, 0xfc, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; +static const unsigned char cp1256_page01[72] = { + 0x00, 0x00, 0x8c, 0x9c, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ +}; +static const unsigned char cp1256_page06[208] = { + 0x00, 0x00, 0x00, 0x00, 0xa1, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0xba, 0x00, 0x00, 0x00, 0xbf, /* 0x18-0x1f */ + 0x00, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0x20-0x27 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0x28-0x2f */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd8, /* 0x30-0x37 */ + 0xd9, 0xda, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0xdc, 0xdd, 0xde, 0xdf, 0xe1, 0xe3, 0xe4, 0xe5, /* 0x40-0x47 */ + 0xe6, 0xec, 0xed, 0xf0, 0xf1, 0xf2, 0xf3, 0xf5, /* 0x48-0x4f */ + 0xf6, 0xf8, 0xfa, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x8a, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, /* 0x78-0x7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8d, 0x00, /* 0x80-0x87 */ + 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x8e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x9f, 0x00, 0x00, 0x00, 0xaa, 0x00, /* 0xb8-0xbf */ + 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ +}; +static const unsigned char cp1256_page20[56] = { + 0x00, 0x00, 0x00, 0x00, 0x9d, 0x9e, 0xfd, 0xfe, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x96, 0x97, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x91, 0x92, 0x82, 0x00, 0x93, 0x94, 0x84, 0x00, /* 0x18-0x1f */ + 0x86, 0x87, 0x95, 0x00, 0x00, 0x00, 0x85, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x8b, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ +}; + +static int +cp1256_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x0100) + c = cp1256_page00[wc-0x00a0]; + else if (wc >= 0x0150 && wc < 0x0198) + c = cp1256_page01[wc-0x0150]; + else if (wc == 0x02c6) + c = 0x88; + else if (wc >= 0x0608 && wc < 0x06d8) + c = cp1256_page06[wc-0x0608]; + else if (wc >= 0x2008 && wc < 0x2040) + c = cp1256_page20[wc-0x2008]; + else if (wc == 0x20ac) + c = 0x80; + else if (wc == 0x2122) + c = 0x99; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILSEQ; +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/cp936ext.h b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/cp936ext.h new file mode 100644 index 0000000..9e26d66 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/cp936ext.h @@ -0,0 +1,6250 @@ +// +// "$Id$" +// +// Character encoding support for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#if !defined(WIN32) && !defined(__APPLE__) + +#ifndef CP936 +static int +cp936ext_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + return 0; +} + +static int +cp936ext_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + return 0; +} + +#else +/* + * CP936EXT + */ + +static const unsigned short cp936ext_2uni_page81[23766] = { + /* 0x81 */ + 0x4e02, 0x4e04, 0x4e05, 0x4e06, 0x4e0f, 0x4e12, 0x4e17, 0x4e1f, + 0x4e20, 0x4e21, 0x4e23, 0x4e26, 0x4e29, 0x4e2e, 0x4e2f, 0x4e31, + 0x4e33, 0x4e35, 0x4e37, 0x4e3c, 0x4e40, 0x4e41, 0x4e42, 0x4e44, + 0x4e46, 0x4e4a, 0x4e51, 0x4e55, 0x4e57, 0x4e5a, 0x4e5b, 0x4e62, + 0x4e63, 0x4e64, 0x4e65, 0x4e67, 0x4e68, 0x4e6a, 0x4e6b, 0x4e6c, + 0x4e6d, 0x4e6e, 0x4e6f, 0x4e72, 0x4e74, 0x4e75, 0x4e76, 0x4e77, + 0x4e78, 0x4e79, 0x4e7a, 0x4e7b, 0x4e7c, 0x4e7d, 0x4e7f, 0x4e80, + 0x4e81, 0x4e82, 0x4e83, 0x4e84, 0x4e85, 0x4e87, 0x4e8a, 0x4e90, + 0x4e96, 0x4e97, 0x4e99, 0x4e9c, 0x4e9d, 0x4e9e, 0x4ea3, 0x4eaa, + 0x4eaf, 0x4eb0, 0x4eb1, 0x4eb4, 0x4eb6, 0x4eb7, 0x4eb8, 0x4eb9, + 0x4ebc, 0x4ebd, 0x4ebe, 0x4ec8, 0x4ecc, 0x4ecf, 0x4ed0, 0x4ed2, + 0x4eda, 0x4edb, 0x4edc, 0x4ee0, 0x4ee2, 0x4ee6, 0x4ee7, 0x4ee9, + 0x4eed, 0x4eee, 0x4eef, 0x4ef1, 0x4ef4, 0x4ef8, 0x4ef9, 0x4efa, + 0x4efc, 0x4efe, 0x4f00, 0x4f02, 0x4f03, 0x4f04, 0x4f05, 0x4f06, + 0x4f07, 0x4f08, 0x4f0b, 0x4f0c, 0x4f12, 0x4f13, 0x4f14, 0x4f15, + 0x4f16, 0x4f1c, 0x4f1d, 0x4f21, 0x4f23, 0x4f28, 0x4f29, 0x4f2c, + 0x4f2d, 0x4f2e, 0x4f31, 0x4f33, 0x4f35, 0x4f37, 0x4f39, 0x4f3b, + 0x4f3e, 0x4f3f, 0x4f40, 0x4f41, 0x4f42, 0x4f44, 0x4f45, 0x4f47, + 0x4f48, 0x4f49, 0x4f4a, 0x4f4b, 0x4f4c, 0x4f52, 0x4f54, 0x4f56, + 0x4f61, 0x4f62, 0x4f66, 0x4f68, 0x4f6a, 0x4f6b, 0x4f6d, 0x4f6e, + 0x4f71, 0x4f72, 0x4f75, 0x4f77, 0x4f78, 0x4f79, 0x4f7a, 0x4f7d, + 0x4f80, 0x4f81, 0x4f82, 0x4f85, 0x4f86, 0x4f87, 0x4f8a, 0x4f8c, + 0x4f8e, 0x4f90, 0x4f92, 0x4f93, 0x4f95, 0x4f96, 0x4f98, 0x4f99, + 0x4f9a, 0x4f9c, 0x4f9e, 0x4f9f, 0x4fa1, 0x4fa2, + /* 0x82 */ + 0x4fa4, 0x4fab, 0x4fad, 0x4fb0, 0x4fb1, 0x4fb2, 0x4fb3, 0x4fb4, + 0x4fb6, 0x4fb7, 0x4fb8, 0x4fb9, 0x4fba, 0x4fbb, 0x4fbc, 0x4fbd, + 0x4fbe, 0x4fc0, 0x4fc1, 0x4fc2, 0x4fc6, 0x4fc7, 0x4fc8, 0x4fc9, + 0x4fcb, 0x4fcc, 0x4fcd, 0x4fd2, 0x4fd3, 0x4fd4, 0x4fd5, 0x4fd6, + 0x4fd9, 0x4fdb, 0x4fe0, 0x4fe2, 0x4fe4, 0x4fe5, 0x4fe7, 0x4feb, + 0x4fec, 0x4ff0, 0x4ff2, 0x4ff4, 0x4ff5, 0x4ff6, 0x4ff7, 0x4ff9, + 0x4ffb, 0x4ffc, 0x4ffd, 0x4fff, 0x5000, 0x5001, 0x5002, 0x5003, + 0x5004, 0x5005, 0x5006, 0x5007, 0x5008, 0x5009, 0x500a, 0x500b, + 0x500e, 0x5010, 0x5011, 0x5013, 0x5015, 0x5016, 0x5017, 0x501b, + 0x501d, 0x501e, 0x5020, 0x5022, 0x5023, 0x5024, 0x5027, 0x502b, + 0x502f, 0x5030, 0x5031, 0x5032, 0x5033, 0x5034, 0x5035, 0x5036, + 0x5037, 0x5038, 0x5039, 0x503b, 0x503d, 0x503f, 0x5040, 0x5041, + 0x5042, 0x5044, 0x5045, 0x5046, 0x5049, 0x504a, 0x504b, 0x504d, + 0x5050, 0x5051, 0x5052, 0x5053, 0x5054, 0x5056, 0x5057, 0x5058, + 0x5059, 0x505b, 0x505d, 0x505e, 0x505f, 0x5060, 0x5061, 0x5062, + 0x5063, 0x5064, 0x5066, 0x5067, 0x5068, 0x5069, 0x506a, 0x506b, + 0x506d, 0x506e, 0x506f, 0x5070, 0x5071, 0x5072, 0x5073, 0x5074, + 0x5075, 0x5078, 0x5079, 0x507a, 0x507c, 0x507d, 0x5081, 0x5082, + 0x5083, 0x5084, 0x5086, 0x5087, 0x5089, 0x508a, 0x508b, 0x508c, + 0x508e, 0x508f, 0x5090, 0x5091, 0x5092, 0x5093, 0x5094, 0x5095, + 0x5096, 0x5097, 0x5098, 0x5099, 0x509a, 0x509b, 0x509c, 0x509d, + 0x509e, 0x509f, 0x50a0, 0x50a1, 0x50a2, 0x50a4, 0x50a6, 0x50aa, + 0x50ab, 0x50ad, 0x50ae, 0x50af, 0x50b0, 0x50b1, 0x50b3, 0x50b4, + 0x50b5, 0x50b6, 0x50b7, 0x50b8, 0x50b9, 0x50bc, + /* 0x83 */ + 0x50bd, 0x50be, 0x50bf, 0x50c0, 0x50c1, 0x50c2, 0x50c3, 0x50c4, + 0x50c5, 0x50c6, 0x50c7, 0x50c8, 0x50c9, 0x50ca, 0x50cb, 0x50cc, + 0x50cd, 0x50ce, 0x50d0, 0x50d1, 0x50d2, 0x50d3, 0x50d4, 0x50d5, + 0x50d7, 0x50d8, 0x50d9, 0x50db, 0x50dc, 0x50dd, 0x50de, 0x50df, + 0x50e0, 0x50e1, 0x50e2, 0x50e3, 0x50e4, 0x50e5, 0x50e8, 0x50e9, + 0x50ea, 0x50eb, 0x50ef, 0x50f0, 0x50f1, 0x50f2, 0x50f4, 0x50f6, + 0x50f7, 0x50f8, 0x50f9, 0x50fa, 0x50fc, 0x50fd, 0x50fe, 0x50ff, + 0x5100, 0x5101, 0x5102, 0x5103, 0x5104, 0x5105, 0x5108, 0x5109, + 0x510a, 0x510c, 0x510d, 0x510e, 0x510f, 0x5110, 0x5111, 0x5113, + 0x5114, 0x5115, 0x5116, 0x5117, 0x5118, 0x5119, 0x511a, 0x511b, + 0x511c, 0x511d, 0x511e, 0x511f, 0x5120, 0x5122, 0x5123, 0x5124, + 0x5125, 0x5126, 0x5127, 0x5128, 0x5129, 0x512a, 0x512b, 0x512c, + 0x512d, 0x512e, 0x512f, 0x5130, 0x5131, 0x5132, 0x5133, 0x5134, + 0x5135, 0x5136, 0x5137, 0x5138, 0x5139, 0x513a, 0x513b, 0x513c, + 0x513d, 0x513e, 0x5142, 0x5147, 0x514a, 0x514c, 0x514e, 0x514f, + 0x5150, 0x5152, 0x5153, 0x5157, 0x5158, 0x5159, 0x515b, 0x515d, + 0x515e, 0x515f, 0x5160, 0x5161, 0x5163, 0x5164, 0x5166, 0x5167, + 0x5169, 0x516a, 0x516f, 0x5172, 0x517a, 0x517e, 0x517f, 0x5183, + 0x5184, 0x5186, 0x5187, 0x518a, 0x518b, 0x518e, 0x518f, 0x5190, + 0x5191, 0x5193, 0x5194, 0x5198, 0x519a, 0x519d, 0x519e, 0x519f, + 0x51a1, 0x51a3, 0x51a6, 0x51a7, 0x51a8, 0x51a9, 0x51aa, 0x51ad, + 0x51ae, 0x51b4, 0x51b8, 0x51b9, 0x51ba, 0x51be, 0x51bf, 0x51c1, + 0x51c2, 0x51c3, 0x51c5, 0x51c8, 0x51ca, 0x51cd, 0x51ce, 0x51d0, + 0x51d2, 0x51d3, 0x51d4, 0x51d5, 0x51d6, 0x51d7, + /* 0x84 */ + 0x51d8, 0x51d9, 0x51da, 0x51dc, 0x51de, 0x51df, 0x51e2, 0x51e3, + 0x51e5, 0x51e6, 0x51e7, 0x51e8, 0x51e9, 0x51ea, 0x51ec, 0x51ee, + 0x51f1, 0x51f2, 0x51f4, 0x51f7, 0x51fe, 0x5204, 0x5205, 0x5209, + 0x520b, 0x520c, 0x520f, 0x5210, 0x5213, 0x5214, 0x5215, 0x521c, + 0x521e, 0x521f, 0x5221, 0x5222, 0x5223, 0x5225, 0x5226, 0x5227, + 0x522a, 0x522c, 0x522f, 0x5231, 0x5232, 0x5234, 0x5235, 0x523c, + 0x523e, 0x5244, 0x5245, 0x5246, 0x5247, 0x5248, 0x5249, 0x524b, + 0x524e, 0x524f, 0x5252, 0x5253, 0x5255, 0x5257, 0x5258, 0x5259, + 0x525a, 0x525b, 0x525d, 0x525f, 0x5260, 0x5262, 0x5263, 0x5264, + 0x5266, 0x5268, 0x526b, 0x526c, 0x526d, 0x526e, 0x5270, 0x5271, + 0x5273, 0x5274, 0x5275, 0x5276, 0x5277, 0x5278, 0x5279, 0x527a, + 0x527b, 0x527c, 0x527e, 0x5280, 0x5283, 0x5284, 0x5285, 0x5286, + 0x5287, 0x5289, 0x528a, 0x528b, 0x528c, 0x528d, 0x528e, 0x528f, + 0x5291, 0x5292, 0x5294, 0x5295, 0x5296, 0x5297, 0x5298, 0x5299, + 0x529a, 0x529c, 0x52a4, 0x52a5, 0x52a6, 0x52a7, 0x52ae, 0x52af, + 0x52b0, 0x52b4, 0x52b5, 0x52b6, 0x52b7, 0x52b8, 0x52b9, 0x52ba, + 0x52bb, 0x52bc, 0x52bd, 0x52c0, 0x52c1, 0x52c2, 0x52c4, 0x52c5, + 0x52c6, 0x52c8, 0x52ca, 0x52cc, 0x52cd, 0x52ce, 0x52cf, 0x52d1, + 0x52d3, 0x52d4, 0x52d5, 0x52d7, 0x52d9, 0x52da, 0x52db, 0x52dc, + 0x52dd, 0x52de, 0x52e0, 0x52e1, 0x52e2, 0x52e3, 0x52e5, 0x52e6, + 0x52e7, 0x52e8, 0x52e9, 0x52ea, 0x52eb, 0x52ec, 0x52ed, 0x52ee, + 0x52ef, 0x52f1, 0x52f2, 0x52f3, 0x52f4, 0x52f5, 0x52f6, 0x52f7, + 0x52f8, 0x52fb, 0x52fc, 0x52fd, 0x5301, 0x5302, 0x5303, 0x5304, + 0x5307, 0x5309, 0x530a, 0x530b, 0x530c, 0x530e, + /* 0x85 */ + 0x5311, 0x5312, 0x5313, 0x5314, 0x5318, 0x531b, 0x531c, 0x531e, + 0x531f, 0x5322, 0x5324, 0x5325, 0x5327, 0x5328, 0x5329, 0x532b, + 0x532c, 0x532d, 0x532f, 0x5330, 0x5331, 0x5332, 0x5333, 0x5334, + 0x5335, 0x5336, 0x5337, 0x5338, 0x533c, 0x533d, 0x5340, 0x5342, + 0x5344, 0x5346, 0x534b, 0x534c, 0x534d, 0x5350, 0x5354, 0x5358, + 0x5359, 0x535b, 0x535d, 0x5365, 0x5368, 0x536a, 0x536c, 0x536d, + 0x5372, 0x5376, 0x5379, 0x537b, 0x537c, 0x537d, 0x537e, 0x5380, + 0x5381, 0x5383, 0x5387, 0x5388, 0x538a, 0x538e, 0x538f, 0x5390, + 0x5391, 0x5392, 0x5393, 0x5394, 0x5396, 0x5397, 0x5399, 0x539b, + 0x539c, 0x539e, 0x53a0, 0x53a1, 0x53a4, 0x53a7, 0x53aa, 0x53ab, + 0x53ac, 0x53ad, 0x53af, 0x53b0, 0x53b1, 0x53b2, 0x53b3, 0x53b4, + 0x53b5, 0x53b7, 0x53b8, 0x53b9, 0x53ba, 0x53bc, 0x53bd, 0x53be, + 0x53c0, 0x53c3, 0x53c4, 0x53c5, 0x53c6, 0x53c7, 0x53ce, 0x53cf, + 0x53d0, 0x53d2, 0x53d3, 0x53d5, 0x53da, 0x53dc, 0x53dd, 0x53de, + 0x53e1, 0x53e2, 0x53e7, 0x53f4, 0x53fa, 0x53fe, 0x53ff, 0x5400, + 0x5402, 0x5405, 0x5407, 0x540b, 0x5414, 0x5418, 0x5419, 0x541a, + 0x541c, 0x5422, 0x5424, 0x5425, 0x542a, 0x5430, 0x5433, 0x5436, + 0x5437, 0x543a, 0x543d, 0x543f, 0x5441, 0x5442, 0x5444, 0x5445, + 0x5447, 0x5449, 0x544c, 0x544d, 0x544e, 0x544f, 0x5451, 0x545a, + 0x545d, 0x545e, 0x545f, 0x5460, 0x5461, 0x5463, 0x5465, 0x5467, + 0x5469, 0x546a, 0x546b, 0x546c, 0x546d, 0x546e, 0x546f, 0x5470, + 0x5474, 0x5479, 0x547a, 0x547e, 0x547f, 0x5481, 0x5483, 0x5485, + 0x5487, 0x5488, 0x5489, 0x548a, 0x548d, 0x5491, 0x5493, 0x5497, + 0x5498, 0x549c, 0x549e, 0x549f, 0x54a0, 0x54a1, + /* 0x86 */ + 0x54a2, 0x54a5, 0x54ae, 0x54b0, 0x54b2, 0x54b5, 0x54b6, 0x54b7, + 0x54b9, 0x54ba, 0x54bc, 0x54be, 0x54c3, 0x54c5, 0x54ca, 0x54cb, + 0x54d6, 0x54d8, 0x54db, 0x54e0, 0x54e1, 0x54e2, 0x54e3, 0x54e4, + 0x54eb, 0x54ec, 0x54ef, 0x54f0, 0x54f1, 0x54f4, 0x54f5, 0x54f6, + 0x54f7, 0x54f8, 0x54f9, 0x54fb, 0x54fe, 0x5500, 0x5502, 0x5503, + 0x5504, 0x5505, 0x5508, 0x550a, 0x550b, 0x550c, 0x550d, 0x550e, + 0x5512, 0x5513, 0x5515, 0x5516, 0x5517, 0x5518, 0x5519, 0x551a, + 0x551c, 0x551d, 0x551e, 0x551f, 0x5521, 0x5525, 0x5526, 0x5528, + 0x5529, 0x552b, 0x552d, 0x5532, 0x5534, 0x5535, 0x5536, 0x5538, + 0x5539, 0x553a, 0x553b, 0x553d, 0x5540, 0x5542, 0x5545, 0x5547, + 0x5548, 0x554b, 0x554c, 0x554d, 0x554e, 0x554f, 0x5551, 0x5552, + 0x5553, 0x5554, 0x5557, 0x5558, 0x5559, 0x555a, 0x555b, 0x555d, + 0x555e, 0x555f, 0x5560, 0x5562, 0x5563, 0x5568, 0x5569, 0x556b, + 0x556f, 0x5570, 0x5571, 0x5572, 0x5573, 0x5574, 0x5579, 0x557a, + 0x557d, 0x557f, 0x5585, 0x5586, 0x558c, 0x558d, 0x558e, 0x5590, + 0x5592, 0x5593, 0x5595, 0x5596, 0x5597, 0x559a, 0x559b, 0x559e, + 0x55a0, 0x55a1, 0x55a2, 0x55a3, 0x55a4, 0x55a5, 0x55a6, 0x55a8, + 0x55a9, 0x55aa, 0x55ab, 0x55ac, 0x55ad, 0x55ae, 0x55af, 0x55b0, + 0x55b2, 0x55b4, 0x55b6, 0x55b8, 0x55ba, 0x55bc, 0x55bf, 0x55c0, + 0x55c1, 0x55c2, 0x55c3, 0x55c6, 0x55c7, 0x55c8, 0x55ca, 0x55cb, + 0x55ce, 0x55cf, 0x55d0, 0x55d5, 0x55d7, 0x55d8, 0x55d9, 0x55da, + 0x55db, 0x55de, 0x55e0, 0x55e2, 0x55e7, 0x55e9, 0x55ed, 0x55ee, + 0x55f0, 0x55f1, 0x55f4, 0x55f6, 0x55f8, 0x55f9, 0x55fa, 0x55fb, + 0x55fc, 0x55ff, 0x5602, 0x5603, 0x5604, 0x5605, + /* 0x87 */ + 0x5606, 0x5607, 0x560a, 0x560b, 0x560d, 0x5610, 0x5611, 0x5612, + 0x5613, 0x5614, 0x5615, 0x5616, 0x5617, 0x5619, 0x561a, 0x561c, + 0x561d, 0x5620, 0x5621, 0x5622, 0x5625, 0x5626, 0x5628, 0x5629, + 0x562a, 0x562b, 0x562e, 0x562f, 0x5630, 0x5633, 0x5635, 0x5637, + 0x5638, 0x563a, 0x563c, 0x563d, 0x563e, 0x5640, 0x5641, 0x5642, + 0x5643, 0x5644, 0x5645, 0x5646, 0x5647, 0x5648, 0x5649, 0x564a, + 0x564b, 0x564f, 0x5650, 0x5651, 0x5652, 0x5653, 0x5655, 0x5656, + 0x565a, 0x565b, 0x565d, 0x565e, 0x565f, 0x5660, 0x5661, 0x5663, + 0x5665, 0x5666, 0x5667, 0x566d, 0x566e, 0x566f, 0x5670, 0x5672, + 0x5673, 0x5674, 0x5675, 0x5677, 0x5678, 0x5679, 0x567a, 0x567d, + 0x567e, 0x567f, 0x5680, 0x5681, 0x5682, 0x5683, 0x5684, 0x5687, + 0x5688, 0x5689, 0x568a, 0x568b, 0x568c, 0x568d, 0x5690, 0x5691, + 0x5692, 0x5694, 0x5695, 0x5696, 0x5697, 0x5698, 0x5699, 0x569a, + 0x569b, 0x569c, 0x569d, 0x569e, 0x569f, 0x56a0, 0x56a1, 0x56a2, + 0x56a4, 0x56a5, 0x56a6, 0x56a7, 0x56a8, 0x56a9, 0x56aa, 0x56ab, + 0x56ac, 0x56ad, 0x56ae, 0x56b0, 0x56b1, 0x56b2, 0x56b3, 0x56b4, + 0x56b5, 0x56b6, 0x56b8, 0x56b9, 0x56ba, 0x56bb, 0x56bd, 0x56be, + 0x56bf, 0x56c0, 0x56c1, 0x56c2, 0x56c3, 0x56c4, 0x56c5, 0x56c6, + 0x56c7, 0x56c8, 0x56c9, 0x56cb, 0x56cc, 0x56cd, 0x56ce, 0x56cf, + 0x56d0, 0x56d1, 0x56d2, 0x56d3, 0x56d5, 0x56d6, 0x56d8, 0x56d9, + 0x56dc, 0x56e3, 0x56e5, 0x56e6, 0x56e7, 0x56e8, 0x56e9, 0x56ea, + 0x56ec, 0x56ee, 0x56ef, 0x56f2, 0x56f3, 0x56f6, 0x56f7, 0x56f8, + 0x56fb, 0x56fc, 0x5700, 0x5701, 0x5702, 0x5705, 0x5707, 0x570b, + 0x570c, 0x570d, 0x570e, 0x570f, 0x5710, 0x5711, + /* 0x88 */ + 0x5712, 0x5713, 0x5714, 0x5715, 0x5716, 0x5717, 0x5718, 0x5719, + 0x571a, 0x571b, 0x571d, 0x571e, 0x5720, 0x5721, 0x5722, 0x5724, + 0x5725, 0x5726, 0x5727, 0x572b, 0x5731, 0x5732, 0x5734, 0x5735, + 0x5736, 0x5737, 0x5738, 0x573c, 0x573d, 0x573f, 0x5741, 0x5743, + 0x5744, 0x5745, 0x5746, 0x5748, 0x5749, 0x574b, 0x5752, 0x5753, + 0x5754, 0x5755, 0x5756, 0x5758, 0x5759, 0x5762, 0x5763, 0x5765, + 0x5767, 0x576c, 0x576e, 0x5770, 0x5771, 0x5772, 0x5774, 0x5775, + 0x5778, 0x5779, 0x577a, 0x577d, 0x577e, 0x577f, 0x5780, 0x5781, + 0x5787, 0x5788, 0x5789, 0x578a, 0x578d, 0x578e, 0x578f, 0x5790, + 0x5791, 0x5794, 0x5795, 0x5796, 0x5797, 0x5798, 0x5799, 0x579a, + 0x579c, 0x579d, 0x579e, 0x579f, 0x57a5, 0x57a8, 0x57aa, 0x57ac, + 0x57af, 0x57b0, 0x57b1, 0x57b3, 0x57b5, 0x57b6, 0x57b7, 0x57b9, + 0x57ba, 0x57bb, 0x57bc, 0x57bd, 0x57be, 0x57bf, 0x57c0, 0x57c1, + 0x57c4, 0x57c5, 0x57c6, 0x57c7, 0x57c8, 0x57c9, 0x57ca, 0x57cc, + 0x57cd, 0x57d0, 0x57d1, 0x57d3, 0x57d6, 0x57d7, 0x57db, 0x57dc, + 0x57de, 0x57e1, 0x57e2, 0x57e3, 0x57e5, 0x57e6, 0x57e7, 0x57e8, + 0x57e9, 0x57ea, 0x57eb, 0x57ec, 0x57ee, 0x57f0, 0x57f1, 0x57f2, + 0x57f3, 0x57f5, 0x57f6, 0x57f7, 0x57fb, 0x57fc, 0x57fe, 0x57ff, + 0x5801, 0x5803, 0x5804, 0x5805, 0x5808, 0x5809, 0x580a, 0x580c, + 0x580e, 0x580f, 0x5810, 0x5812, 0x5813, 0x5814, 0x5816, 0x5817, + 0x5818, 0x581a, 0x581b, 0x581c, 0x581d, 0x581f, 0x5822, 0x5823, + 0x5825, 0x5826, 0x5827, 0x5828, 0x5829, 0x582b, 0x582c, 0x582d, + 0x582e, 0x582f, 0x5831, 0x5832, 0x5833, 0x5834, 0x5836, 0x5837, + 0x5838, 0x5839, 0x583a, 0x583b, 0x583c, 0x583d, + /* 0x89 */ + 0x583e, 0x583f, 0x5840, 0x5841, 0x5842, 0x5843, 0x5845, 0x5846, + 0x5847, 0x5848, 0x5849, 0x584a, 0x584b, 0x584e, 0x584f, 0x5850, + 0x5852, 0x5853, 0x5855, 0x5856, 0x5857, 0x5859, 0x585a, 0x585b, + 0x585c, 0x585d, 0x585f, 0x5860, 0x5861, 0x5862, 0x5863, 0x5864, + 0x5866, 0x5867, 0x5868, 0x5869, 0x586a, 0x586d, 0x586e, 0x586f, + 0x5870, 0x5871, 0x5872, 0x5873, 0x5874, 0x5875, 0x5876, 0x5877, + 0x5878, 0x5879, 0x587a, 0x587b, 0x587c, 0x587d, 0x587f, 0x5882, + 0x5884, 0x5886, 0x5887, 0x5888, 0x588a, 0x588b, 0x588c, 0x588d, + 0x588e, 0x588f, 0x5890, 0x5891, 0x5894, 0x5895, 0x5896, 0x5897, + 0x5898, 0x589b, 0x589c, 0x589d, 0x58a0, 0x58a1, 0x58a2, 0x58a3, + 0x58a4, 0x58a5, 0x58a6, 0x58a7, 0x58aa, 0x58ab, 0x58ac, 0x58ad, + 0x58ae, 0x58af, 0x58b0, 0x58b1, 0x58b2, 0x58b3, 0x58b4, 0x58b5, + 0x58b6, 0x58b7, 0x58b8, 0x58b9, 0x58ba, 0x58bb, 0x58bd, 0x58be, + 0x58bf, 0x58c0, 0x58c2, 0x58c3, 0x58c4, 0x58c6, 0x58c7, 0x58c8, + 0x58c9, 0x58ca, 0x58cb, 0x58cc, 0x58cd, 0x58ce, 0x58cf, 0x58d0, + 0x58d2, 0x58d3, 0x58d4, 0x58d6, 0x58d7, 0x58d8, 0x58d9, 0x58da, + 0x58db, 0x58dc, 0x58dd, 0x58de, 0x58df, 0x58e0, 0x58e1, 0x58e2, + 0x58e3, 0x58e5, 0x58e6, 0x58e7, 0x58e8, 0x58e9, 0x58ea, 0x58ed, + 0x58ef, 0x58f1, 0x58f2, 0x58f4, 0x58f5, 0x58f7, 0x58f8, 0x58fa, + 0x58fb, 0x58fc, 0x58fd, 0x58fe, 0x58ff, 0x5900, 0x5901, 0x5903, + 0x5905, 0x5906, 0x5908, 0x5909, 0x590a, 0x590b, 0x590c, 0x590e, + 0x5910, 0x5911, 0x5912, 0x5913, 0x5917, 0x5918, 0x591b, 0x591d, + 0x591e, 0x5920, 0x5921, 0x5922, 0x5923, 0x5926, 0x5928, 0x592c, + 0x5930, 0x5932, 0x5933, 0x5935, 0x5936, 0x593b, + /* 0x8a */ + 0x593d, 0x593e, 0x593f, 0x5940, 0x5943, 0x5945, 0x5946, 0x594a, + 0x594c, 0x594d, 0x5950, 0x5952, 0x5953, 0x5959, 0x595b, 0x595c, + 0x595d, 0x595e, 0x595f, 0x5961, 0x5963, 0x5964, 0x5966, 0x5967, + 0x5968, 0x5969, 0x596a, 0x596b, 0x596c, 0x596d, 0x596e, 0x596f, + 0x5970, 0x5971, 0x5972, 0x5975, 0x5977, 0x597a, 0x597b, 0x597c, + 0x597e, 0x597f, 0x5980, 0x5985, 0x5989, 0x598b, 0x598c, 0x598e, + 0x598f, 0x5990, 0x5991, 0x5994, 0x5995, 0x5998, 0x599a, 0x599b, + 0x599c, 0x599d, 0x599f, 0x59a0, 0x59a1, 0x59a2, 0x59a6, 0x59a7, + 0x59ac, 0x59ad, 0x59b0, 0x59b1, 0x59b3, 0x59b4, 0x59b5, 0x59b6, + 0x59b7, 0x59b8, 0x59ba, 0x59bc, 0x59bd, 0x59bf, 0x59c0, 0x59c1, + 0x59c2, 0x59c3, 0x59c4, 0x59c5, 0x59c7, 0x59c8, 0x59c9, 0x59cc, + 0x59cd, 0x59ce, 0x59cf, 0x59d5, 0x59d6, 0x59d9, 0x59db, 0x59de, + 0x59df, 0x59e0, 0x59e1, 0x59e2, 0x59e4, 0x59e6, 0x59e7, 0x59e9, + 0x59ea, 0x59eb, 0x59ed, 0x59ee, 0x59ef, 0x59f0, 0x59f1, 0x59f2, + 0x59f3, 0x59f4, 0x59f5, 0x59f6, 0x59f7, 0x59f8, 0x59fa, 0x59fc, + 0x59fd, 0x59fe, 0x5a00, 0x5a02, 0x5a0a, 0x5a0b, 0x5a0d, 0x5a0e, + 0x5a0f, 0x5a10, 0x5a12, 0x5a14, 0x5a15, 0x5a16, 0x5a17, 0x5a19, + 0x5a1a, 0x5a1b, 0x5a1d, 0x5a1e, 0x5a21, 0x5a22, 0x5a24, 0x5a26, + 0x5a27, 0x5a28, 0x5a2a, 0x5a2b, 0x5a2c, 0x5a2d, 0x5a2e, 0x5a2f, + 0x5a30, 0x5a33, 0x5a35, 0x5a37, 0x5a38, 0x5a39, 0x5a3a, 0x5a3b, + 0x5a3d, 0x5a3e, 0x5a3f, 0x5a41, 0x5a42, 0x5a43, 0x5a44, 0x5a45, + 0x5a47, 0x5a48, 0x5a4b, 0x5a4c, 0x5a4d, 0x5a4e, 0x5a4f, 0x5a50, + 0x5a51, 0x5a52, 0x5a53, 0x5a54, 0x5a56, 0x5a57, 0x5a58, 0x5a59, + 0x5a5b, 0x5a5c, 0x5a5d, 0x5a5e, 0x5a5f, 0x5a60, + /* 0x8b */ + 0x5a61, 0x5a63, 0x5a64, 0x5a65, 0x5a66, 0x5a68, 0x5a69, 0x5a6b, + 0x5a6c, 0x5a6d, 0x5a6e, 0x5a6f, 0x5a70, 0x5a71, 0x5a72, 0x5a73, + 0x5a78, 0x5a79, 0x5a7b, 0x5a7c, 0x5a7d, 0x5a7e, 0x5a80, 0x5a81, + 0x5a82, 0x5a83, 0x5a84, 0x5a85, 0x5a86, 0x5a87, 0x5a88, 0x5a89, + 0x5a8a, 0x5a8b, 0x5a8c, 0x5a8d, 0x5a8e, 0x5a8f, 0x5a90, 0x5a91, + 0x5a93, 0x5a94, 0x5a95, 0x5a96, 0x5a97, 0x5a98, 0x5a99, 0x5a9c, + 0x5a9d, 0x5a9e, 0x5a9f, 0x5aa0, 0x5aa1, 0x5aa2, 0x5aa3, 0x5aa4, + 0x5aa5, 0x5aa6, 0x5aa7, 0x5aa8, 0x5aa9, 0x5aab, 0x5aac, 0x5aad, + 0x5aae, 0x5aaf, 0x5ab0, 0x5ab1, 0x5ab4, 0x5ab6, 0x5ab7, 0x5ab9, + 0x5aba, 0x5abb, 0x5abc, 0x5abd, 0x5abf, 0x5ac0, 0x5ac3, 0x5ac4, + 0x5ac5, 0x5ac6, 0x5ac7, 0x5ac8, 0x5aca, 0x5acb, 0x5acd, 0x5ace, + 0x5acf, 0x5ad0, 0x5ad1, 0x5ad3, 0x5ad5, 0x5ad7, 0x5ad9, 0x5ada, + 0x5adb, 0x5add, 0x5ade, 0x5adf, 0x5ae2, 0x5ae4, 0x5ae5, 0x5ae7, + 0x5ae8, 0x5aea, 0x5aec, 0x5aed, 0x5aee, 0x5aef, 0x5af0, 0x5af2, + 0x5af3, 0x5af4, 0x5af5, 0x5af6, 0x5af7, 0x5af8, 0x5af9, 0x5afa, + 0x5afb, 0x5afc, 0x5afd, 0x5afe, 0x5aff, 0x5b00, 0x5b01, 0x5b02, + 0x5b03, 0x5b04, 0x5b05, 0x5b06, 0x5b07, 0x5b08, 0x5b0a, 0x5b0b, + 0x5b0c, 0x5b0d, 0x5b0e, 0x5b0f, 0x5b10, 0x5b11, 0x5b12, 0x5b13, + 0x5b14, 0x5b15, 0x5b18, 0x5b19, 0x5b1a, 0x5b1b, 0x5b1c, 0x5b1d, + 0x5b1e, 0x5b1f, 0x5b20, 0x5b21, 0x5b22, 0x5b23, 0x5b24, 0x5b25, + 0x5b26, 0x5b27, 0x5b28, 0x5b29, 0x5b2a, 0x5b2b, 0x5b2c, 0x5b2d, + 0x5b2e, 0x5b2f, 0x5b30, 0x5b31, 0x5b33, 0x5b35, 0x5b36, 0x5b38, + 0x5b39, 0x5b3a, 0x5b3b, 0x5b3c, 0x5b3d, 0x5b3e, 0x5b3f, 0x5b41, + 0x5b42, 0x5b43, 0x5b44, 0x5b45, 0x5b46, 0x5b47, + /* 0x8c */ + 0x5b48, 0x5b49, 0x5b4a, 0x5b4b, 0x5b4c, 0x5b4d, 0x5b4e, 0x5b4f, + 0x5b52, 0x5b56, 0x5b5e, 0x5b60, 0x5b61, 0x5b67, 0x5b68, 0x5b6b, + 0x5b6d, 0x5b6e, 0x5b6f, 0x5b72, 0x5b74, 0x5b76, 0x5b77, 0x5b78, + 0x5b79, 0x5b7b, 0x5b7c, 0x5b7e, 0x5b7f, 0x5b82, 0x5b86, 0x5b8a, + 0x5b8d, 0x5b8e, 0x5b90, 0x5b91, 0x5b92, 0x5b94, 0x5b96, 0x5b9f, + 0x5ba7, 0x5ba8, 0x5ba9, 0x5bac, 0x5bad, 0x5bae, 0x5baf, 0x5bb1, + 0x5bb2, 0x5bb7, 0x5bba, 0x5bbb, 0x5bbc, 0x5bc0, 0x5bc1, 0x5bc3, + 0x5bc8, 0x5bc9, 0x5bca, 0x5bcb, 0x5bcd, 0x5bce, 0x5bcf, 0x5bd1, + 0x5bd4, 0x5bd5, 0x5bd6, 0x5bd7, 0x5bd8, 0x5bd9, 0x5bda, 0x5bdb, + 0x5bdc, 0x5be0, 0x5be2, 0x5be3, 0x5be6, 0x5be7, 0x5be9, 0x5bea, + 0x5beb, 0x5bec, 0x5bed, 0x5bef, 0x5bf1, 0x5bf2, 0x5bf3, 0x5bf4, + 0x5bf5, 0x5bf6, 0x5bf7, 0x5bfd, 0x5bfe, 0x5c00, 0x5c02, 0x5c03, + 0x5c05, 0x5c07, 0x5c08, 0x5c0b, 0x5c0c, 0x5c0d, 0x5c0e, 0x5c10, + 0x5c12, 0x5c13, 0x5c17, 0x5c19, 0x5c1b, 0x5c1e, 0x5c1f, 0x5c20, + 0x5c21, 0x5c23, 0x5c26, 0x5c28, 0x5c29, 0x5c2a, 0x5c2b, 0x5c2d, + 0x5c2e, 0x5c2f, 0x5c30, 0x5c32, 0x5c33, 0x5c35, 0x5c36, 0x5c37, + 0x5c43, 0x5c44, 0x5c46, 0x5c47, 0x5c4c, 0x5c4d, 0x5c52, 0x5c53, + 0x5c54, 0x5c56, 0x5c57, 0x5c58, 0x5c5a, 0x5c5b, 0x5c5c, 0x5c5d, + 0x5c5f, 0x5c62, 0x5c64, 0x5c67, 0x5c68, 0x5c69, 0x5c6a, 0x5c6b, + 0x5c6c, 0x5c6d, 0x5c70, 0x5c72, 0x5c73, 0x5c74, 0x5c75, 0x5c76, + 0x5c77, 0x5c78, 0x5c7b, 0x5c7c, 0x5c7d, 0x5c7e, 0x5c80, 0x5c83, + 0x5c84, 0x5c85, 0x5c86, 0x5c87, 0x5c89, 0x5c8a, 0x5c8b, 0x5c8e, + 0x5c8f, 0x5c92, 0x5c93, 0x5c95, 0x5c9d, 0x5c9e, 0x5c9f, 0x5ca0, + 0x5ca1, 0x5ca4, 0x5ca5, 0x5ca6, 0x5ca7, 0x5ca8, + /* 0x8d */ + 0x5caa, 0x5cae, 0x5caf, 0x5cb0, 0x5cb2, 0x5cb4, 0x5cb6, 0x5cb9, + 0x5cba, 0x5cbb, 0x5cbc, 0x5cbe, 0x5cc0, 0x5cc2, 0x5cc3, 0x5cc5, + 0x5cc6, 0x5cc7, 0x5cc8, 0x5cc9, 0x5cca, 0x5ccc, 0x5ccd, 0x5cce, + 0x5ccf, 0x5cd0, 0x5cd1, 0x5cd3, 0x5cd4, 0x5cd5, 0x5cd6, 0x5cd7, + 0x5cd8, 0x5cda, 0x5cdb, 0x5cdc, 0x5cdd, 0x5cde, 0x5cdf, 0x5ce0, + 0x5ce2, 0x5ce3, 0x5ce7, 0x5ce9, 0x5ceb, 0x5cec, 0x5cee, 0x5cef, + 0x5cf1, 0x5cf2, 0x5cf3, 0x5cf4, 0x5cf5, 0x5cf6, 0x5cf7, 0x5cf8, + 0x5cf9, 0x5cfa, 0x5cfc, 0x5cfd, 0x5cfe, 0x5cff, 0x5d00, 0x5d01, + 0x5d04, 0x5d05, 0x5d08, 0x5d09, 0x5d0a, 0x5d0b, 0x5d0c, 0x5d0d, + 0x5d0f, 0x5d10, 0x5d11, 0x5d12, 0x5d13, 0x5d15, 0x5d17, 0x5d18, + 0x5d19, 0x5d1a, 0x5d1c, 0x5d1d, 0x5d1f, 0x5d20, 0x5d21, 0x5d22, + 0x5d23, 0x5d25, 0x5d28, 0x5d2a, 0x5d2b, 0x5d2c, 0x5d2f, 0x5d30, + 0x5d31, 0x5d32, 0x5d33, 0x5d35, 0x5d36, 0x5d37, 0x5d38, 0x5d39, + 0x5d3a, 0x5d3b, 0x5d3c, 0x5d3f, 0x5d40, 0x5d41, 0x5d42, 0x5d43, + 0x5d44, 0x5d45, 0x5d46, 0x5d48, 0x5d49, 0x5d4d, 0x5d4e, 0x5d4f, + 0x5d50, 0x5d51, 0x5d52, 0x5d53, 0x5d54, 0x5d55, 0x5d56, 0x5d57, + 0x5d59, 0x5d5a, 0x5d5c, 0x5d5e, 0x5d5f, 0x5d60, 0x5d61, 0x5d62, + 0x5d63, 0x5d64, 0x5d65, 0x5d66, 0x5d67, 0x5d68, 0x5d6a, 0x5d6d, + 0x5d6e, 0x5d70, 0x5d71, 0x5d72, 0x5d73, 0x5d75, 0x5d76, 0x5d77, + 0x5d78, 0x5d79, 0x5d7a, 0x5d7b, 0x5d7c, 0x5d7d, 0x5d7e, 0x5d7f, + 0x5d80, 0x5d81, 0x5d83, 0x5d84, 0x5d85, 0x5d86, 0x5d87, 0x5d88, + 0x5d89, 0x5d8a, 0x5d8b, 0x5d8c, 0x5d8d, 0x5d8e, 0x5d8f, 0x5d90, + 0x5d91, 0x5d92, 0x5d93, 0x5d94, 0x5d95, 0x5d96, 0x5d97, 0x5d98, + 0x5d9a, 0x5d9b, 0x5d9c, 0x5d9e, 0x5d9f, 0x5da0, + /* 0x8e */ + 0x5da1, 0x5da2, 0x5da3, 0x5da4, 0x5da5, 0x5da6, 0x5da7, 0x5da8, + 0x5da9, 0x5daa, 0x5dab, 0x5dac, 0x5dad, 0x5dae, 0x5daf, 0x5db0, + 0x5db1, 0x5db2, 0x5db3, 0x5db4, 0x5db5, 0x5db6, 0x5db8, 0x5db9, + 0x5dba, 0x5dbb, 0x5dbc, 0x5dbd, 0x5dbe, 0x5dbf, 0x5dc0, 0x5dc1, + 0x5dc2, 0x5dc3, 0x5dc4, 0x5dc6, 0x5dc7, 0x5dc8, 0x5dc9, 0x5dca, + 0x5dcb, 0x5dcc, 0x5dce, 0x5dcf, 0x5dd0, 0x5dd1, 0x5dd2, 0x5dd3, + 0x5dd4, 0x5dd5, 0x5dd6, 0x5dd7, 0x5dd8, 0x5dd9, 0x5dda, 0x5ddc, + 0x5ddf, 0x5de0, 0x5de3, 0x5de4, 0x5dea, 0x5dec, 0x5ded, 0x5df0, + 0x5df5, 0x5df6, 0x5df8, 0x5df9, 0x5dfa, 0x5dfb, 0x5dfc, 0x5dff, + 0x5e00, 0x5e04, 0x5e07, 0x5e09, 0x5e0a, 0x5e0b, 0x5e0d, 0x5e0e, + 0x5e12, 0x5e13, 0x5e17, 0x5e1e, 0x5e1f, 0x5e20, 0x5e21, 0x5e22, + 0x5e23, 0x5e24, 0x5e25, 0x5e28, 0x5e29, 0x5e2a, 0x5e2b, 0x5e2c, + 0x5e2f, 0x5e30, 0x5e32, 0x5e33, 0x5e34, 0x5e35, 0x5e36, 0x5e39, + 0x5e3a, 0x5e3e, 0x5e3f, 0x5e40, 0x5e41, 0x5e43, 0x5e46, 0x5e47, + 0x5e48, 0x5e49, 0x5e4a, 0x5e4b, 0x5e4d, 0x5e4e, 0x5e4f, 0x5e50, + 0x5e51, 0x5e52, 0x5e53, 0x5e56, 0x5e57, 0x5e58, 0x5e59, 0x5e5a, + 0x5e5c, 0x5e5d, 0x5e5f, 0x5e60, 0x5e63, 0x5e64, 0x5e65, 0x5e66, + 0x5e67, 0x5e68, 0x5e69, 0x5e6a, 0x5e6b, 0x5e6c, 0x5e6d, 0x5e6e, + 0x5e6f, 0x5e70, 0x5e71, 0x5e75, 0x5e77, 0x5e79, 0x5e7e, 0x5e81, + 0x5e82, 0x5e83, 0x5e85, 0x5e88, 0x5e89, 0x5e8c, 0x5e8d, 0x5e8e, + 0x5e92, 0x5e98, 0x5e9b, 0x5e9d, 0x5ea1, 0x5ea2, 0x5ea3, 0x5ea4, + 0x5ea8, 0x5ea9, 0x5eaa, 0x5eab, 0x5eac, 0x5eae, 0x5eaf, 0x5eb0, + 0x5eb1, 0x5eb2, 0x5eb4, 0x5eba, 0x5ebb, 0x5ebc, 0x5ebd, 0x5ebf, + 0x5ec0, 0x5ec1, 0x5ec2, 0x5ec3, 0x5ec4, 0x5ec5, + /* 0x8f */ + 0x5ec6, 0x5ec7, 0x5ec8, 0x5ecb, 0x5ecc, 0x5ecd, 0x5ece, 0x5ecf, + 0x5ed0, 0x5ed4, 0x5ed5, 0x5ed7, 0x5ed8, 0x5ed9, 0x5eda, 0x5edc, + 0x5edd, 0x5ede, 0x5edf, 0x5ee0, 0x5ee1, 0x5ee2, 0x5ee3, 0x5ee4, + 0x5ee5, 0x5ee6, 0x5ee7, 0x5ee9, 0x5eeb, 0x5eec, 0x5eed, 0x5eee, + 0x5eef, 0x5ef0, 0x5ef1, 0x5ef2, 0x5ef3, 0x5ef5, 0x5ef8, 0x5ef9, + 0x5efb, 0x5efc, 0x5efd, 0x5f05, 0x5f06, 0x5f07, 0x5f09, 0x5f0c, + 0x5f0d, 0x5f0e, 0x5f10, 0x5f12, 0x5f14, 0x5f16, 0x5f19, 0x5f1a, + 0x5f1c, 0x5f1d, 0x5f1e, 0x5f21, 0x5f22, 0x5f23, 0x5f24, 0x5f28, + 0x5f2b, 0x5f2c, 0x5f2e, 0x5f30, 0x5f32, 0x5f33, 0x5f34, 0x5f35, + 0x5f36, 0x5f37, 0x5f38, 0x5f3b, 0x5f3d, 0x5f3e, 0x5f3f, 0x5f41, + 0x5f42, 0x5f43, 0x5f44, 0x5f45, 0x5f46, 0x5f47, 0x5f48, 0x5f49, + 0x5f4a, 0x5f4b, 0x5f4c, 0x5f4d, 0x5f4e, 0x5f4f, 0x5f51, 0x5f54, + 0x5f59, 0x5f5a, 0x5f5b, 0x5f5c, 0x5f5e, 0x5f5f, 0x5f60, 0x5f63, + 0x5f65, 0x5f67, 0x5f68, 0x5f6b, 0x5f6e, 0x5f6f, 0x5f72, 0x5f74, + 0x5f75, 0x5f76, 0x5f78, 0x5f7a, 0x5f7d, 0x5f7e, 0x5f7f, 0x5f83, + 0x5f86, 0x5f8d, 0x5f8e, 0x5f8f, 0x5f91, 0x5f93, 0x5f94, 0x5f96, + 0x5f9a, 0x5f9b, 0x5f9d, 0x5f9e, 0x5f9f, 0x5fa0, 0x5fa2, 0x5fa3, + 0x5fa4, 0x5fa5, 0x5fa6, 0x5fa7, 0x5fa9, 0x5fab, 0x5fac, 0x5faf, + 0x5fb0, 0x5fb1, 0x5fb2, 0x5fb3, 0x5fb4, 0x5fb6, 0x5fb8, 0x5fb9, + 0x5fba, 0x5fbb, 0x5fbe, 0x5fbf, 0x5fc0, 0x5fc1, 0x5fc2, 0x5fc7, + 0x5fc8, 0x5fca, 0x5fcb, 0x5fce, 0x5fd3, 0x5fd4, 0x5fd5, 0x5fda, + 0x5fdb, 0x5fdc, 0x5fde, 0x5fdf, 0x5fe2, 0x5fe3, 0x5fe5, 0x5fe6, + 0x5fe8, 0x5fe9, 0x5fec, 0x5fef, 0x5ff0, 0x5ff2, 0x5ff3, 0x5ff4, + 0x5ff6, 0x5ff7, 0x5ff9, 0x5ffa, 0x5ffc, 0x6007, + /* 0x90 */ + 0x6008, 0x6009, 0x600b, 0x600c, 0x6010, 0x6011, 0x6013, 0x6017, + 0x6018, 0x601a, 0x601e, 0x601f, 0x6022, 0x6023, 0x6024, 0x602c, + 0x602d, 0x602e, 0x6030, 0x6031, 0x6032, 0x6033, 0x6034, 0x6036, + 0x6037, 0x6038, 0x6039, 0x603a, 0x603d, 0x603e, 0x6040, 0x6044, + 0x6045, 0x6046, 0x6047, 0x6048, 0x6049, 0x604a, 0x604c, 0x604e, + 0x604f, 0x6051, 0x6053, 0x6054, 0x6056, 0x6057, 0x6058, 0x605b, + 0x605c, 0x605e, 0x605f, 0x6060, 0x6061, 0x6065, 0x6066, 0x606e, + 0x6071, 0x6072, 0x6074, 0x6075, 0x6077, 0x607e, 0x6080, 0x6081, + 0x6082, 0x6085, 0x6086, 0x6087, 0x6088, 0x608a, 0x608b, 0x608e, + 0x608f, 0x6090, 0x6091, 0x6093, 0x6095, 0x6097, 0x6098, 0x6099, + 0x609c, 0x609e, 0x60a1, 0x60a2, 0x60a4, 0x60a5, 0x60a7, 0x60a9, + 0x60aa, 0x60ae, 0x60b0, 0x60b3, 0x60b5, 0x60b6, 0x60b7, 0x60b9, + 0x60ba, 0x60bd, 0x60be, 0x60bf, 0x60c0, 0x60c1, 0x60c2, 0x60c3, + 0x60c4, 0x60c7, 0x60c8, 0x60c9, 0x60cc, 0x60cd, 0x60ce, 0x60cf, + 0x60d0, 0x60d2, 0x60d3, 0x60d4, 0x60d6, 0x60d7, 0x60d9, 0x60db, + 0x60de, 0x60e1, 0x60e2, 0x60e3, 0x60e4, 0x60e5, 0x60ea, 0x60f1, + 0x60f2, 0x60f5, 0x60f7, 0x60f8, 0x60fb, 0x60fc, 0x60fd, 0x60fe, + 0x60ff, 0x6102, 0x6103, 0x6104, 0x6105, 0x6107, 0x610a, 0x610b, + 0x610c, 0x6110, 0x6111, 0x6112, 0x6113, 0x6114, 0x6116, 0x6117, + 0x6118, 0x6119, 0x611b, 0x611c, 0x611d, 0x611e, 0x6121, 0x6122, + 0x6125, 0x6128, 0x6129, 0x612a, 0x612c, 0x612d, 0x612e, 0x612f, + 0x6130, 0x6131, 0x6132, 0x6133, 0x6134, 0x6135, 0x6136, 0x6137, + 0x6138, 0x6139, 0x613a, 0x613b, 0x613c, 0x613d, 0x613e, 0x6140, + 0x6141, 0x6142, 0x6143, 0x6144, 0x6145, 0x6146, + /* 0x91 */ + 0x6147, 0x6149, 0x614b, 0x614d, 0x614f, 0x6150, 0x6152, 0x6153, + 0x6154, 0x6156, 0x6157, 0x6158, 0x6159, 0x615a, 0x615b, 0x615c, + 0x615e, 0x615f, 0x6160, 0x6161, 0x6163, 0x6164, 0x6165, 0x6166, + 0x6169, 0x616a, 0x616b, 0x616c, 0x616d, 0x616e, 0x616f, 0x6171, + 0x6172, 0x6173, 0x6174, 0x6176, 0x6178, 0x6179, 0x617a, 0x617b, + 0x617c, 0x617d, 0x617e, 0x617f, 0x6180, 0x6181, 0x6182, 0x6183, + 0x6184, 0x6185, 0x6186, 0x6187, 0x6188, 0x6189, 0x618a, 0x618c, + 0x618d, 0x618f, 0x6190, 0x6191, 0x6192, 0x6193, 0x6195, 0x6196, + 0x6197, 0x6198, 0x6199, 0x619a, 0x619b, 0x619c, 0x619e, 0x619f, + 0x61a0, 0x61a1, 0x61a2, 0x61a3, 0x61a4, 0x61a5, 0x61a6, 0x61aa, + 0x61ab, 0x61ad, 0x61ae, 0x61af, 0x61b0, 0x61b1, 0x61b2, 0x61b3, + 0x61b4, 0x61b5, 0x61b6, 0x61b8, 0x61b9, 0x61ba, 0x61bb, 0x61bc, + 0x61bd, 0x61bf, 0x61c0, 0x61c1, 0x61c3, 0x61c4, 0x61c5, 0x61c6, + 0x61c7, 0x61c9, 0x61cc, 0x61cd, 0x61ce, 0x61cf, 0x61d0, 0x61d3, + 0x61d5, 0x61d6, 0x61d7, 0x61d8, 0x61d9, 0x61da, 0x61db, 0x61dc, + 0x61dd, 0x61de, 0x61df, 0x61e0, 0x61e1, 0x61e2, 0x61e3, 0x61e4, + 0x61e5, 0x61e7, 0x61e8, 0x61e9, 0x61ea, 0x61eb, 0x61ec, 0x61ed, + 0x61ee, 0x61ef, 0x61f0, 0x61f1, 0x61f2, 0x61f3, 0x61f4, 0x61f6, + 0x61f7, 0x61f8, 0x61f9, 0x61fa, 0x61fb, 0x61fc, 0x61fd, 0x61fe, + 0x6200, 0x6201, 0x6202, 0x6203, 0x6204, 0x6205, 0x6207, 0x6209, + 0x6213, 0x6214, 0x6219, 0x621c, 0x621d, 0x621e, 0x6220, 0x6223, + 0x6226, 0x6227, 0x6228, 0x6229, 0x622b, 0x622d, 0x622f, 0x6230, + 0x6231, 0x6232, 0x6235, 0x6236, 0x6238, 0x6239, 0x623a, 0x623b, + 0x623c, 0x6242, 0x6244, 0x6245, 0x6246, 0x624a, + /* 0x92 */ + 0x624f, 0x6250, 0x6255, 0x6256, 0x6257, 0x6259, 0x625a, 0x625c, + 0x625d, 0x625e, 0x625f, 0x6260, 0x6261, 0x6262, 0x6264, 0x6265, + 0x6268, 0x6271, 0x6272, 0x6274, 0x6275, 0x6277, 0x6278, 0x627a, + 0x627b, 0x627d, 0x6281, 0x6282, 0x6283, 0x6285, 0x6286, 0x6287, + 0x6288, 0x628b, 0x628c, 0x628d, 0x628e, 0x628f, 0x6290, 0x6294, + 0x6299, 0x629c, 0x629d, 0x629e, 0x62a3, 0x62a6, 0x62a7, 0x62a9, + 0x62aa, 0x62ad, 0x62ae, 0x62af, 0x62b0, 0x62b2, 0x62b3, 0x62b4, + 0x62b6, 0x62b7, 0x62b8, 0x62ba, 0x62be, 0x62c0, 0x62c1, 0x62c3, + 0x62cb, 0x62cf, 0x62d1, 0x62d5, 0x62dd, 0x62de, 0x62e0, 0x62e1, + 0x62e4, 0x62ea, 0x62eb, 0x62f0, 0x62f2, 0x62f5, 0x62f8, 0x62f9, + 0x62fa, 0x62fb, 0x6300, 0x6303, 0x6304, 0x6305, 0x6306, 0x630a, + 0x630b, 0x630c, 0x630d, 0x630f, 0x6310, 0x6312, 0x6313, 0x6314, + 0x6315, 0x6317, 0x6318, 0x6319, 0x631c, 0x6326, 0x6327, 0x6329, + 0x632c, 0x632d, 0x632e, 0x6330, 0x6331, 0x6333, 0x6334, 0x6335, + 0x6336, 0x6337, 0x6338, 0x633b, 0x633c, 0x633e, 0x633f, 0x6340, + 0x6341, 0x6344, 0x6347, 0x6348, 0x634a, 0x6351, 0x6352, 0x6353, + 0x6354, 0x6356, 0x6357, 0x6358, 0x6359, 0x635a, 0x635b, 0x635c, + 0x635d, 0x6360, 0x6364, 0x6365, 0x6366, 0x6368, 0x636a, 0x636b, + 0x636c, 0x636f, 0x6370, 0x6372, 0x6373, 0x6374, 0x6375, 0x6378, + 0x6379, 0x637c, 0x637d, 0x637e, 0x637f, 0x6381, 0x6383, 0x6384, + 0x6385, 0x6386, 0x638b, 0x638d, 0x6391, 0x6393, 0x6394, 0x6395, + 0x6397, 0x6399, 0x639a, 0x639b, 0x639c, 0x639d, 0x639e, 0x639f, + 0x63a1, 0x63a4, 0x63a6, 0x63ab, 0x63af, 0x63b1, 0x63b2, 0x63b5, + 0x63b6, 0x63b9, 0x63bb, 0x63bd, 0x63bf, 0x63c0, + /* 0x93 */ + 0x63c1, 0x63c2, 0x63c3, 0x63c5, 0x63c7, 0x63c8, 0x63ca, 0x63cb, + 0x63cc, 0x63d1, 0x63d3, 0x63d4, 0x63d5, 0x63d7, 0x63d8, 0x63d9, + 0x63da, 0x63db, 0x63dc, 0x63dd, 0x63df, 0x63e2, 0x63e4, 0x63e5, + 0x63e6, 0x63e7, 0x63e8, 0x63eb, 0x63ec, 0x63ee, 0x63ef, 0x63f0, + 0x63f1, 0x63f3, 0x63f5, 0x63f7, 0x63f9, 0x63fa, 0x63fb, 0x63fc, + 0x63fe, 0x6403, 0x6404, 0x6406, 0x6407, 0x6408, 0x6409, 0x640a, + 0x640d, 0x640e, 0x6411, 0x6412, 0x6415, 0x6416, 0x6417, 0x6418, + 0x6419, 0x641a, 0x641d, 0x641f, 0x6422, 0x6423, 0x6424, 0x6425, + 0x6427, 0x6428, 0x6429, 0x642b, 0x642e, 0x642f, 0x6430, 0x6431, + 0x6432, 0x6433, 0x6435, 0x6436, 0x6437, 0x6438, 0x6439, 0x643b, + 0x643c, 0x643e, 0x6440, 0x6442, 0x6443, 0x6449, 0x644b, 0x644c, + 0x644d, 0x644e, 0x644f, 0x6450, 0x6451, 0x6453, 0x6455, 0x6456, + 0x6457, 0x6459, 0x645a, 0x645b, 0x645c, 0x645d, 0x645f, 0x6460, + 0x6461, 0x6462, 0x6463, 0x6464, 0x6465, 0x6466, 0x6468, 0x646a, + 0x646b, 0x646c, 0x646e, 0x646f, 0x6470, 0x6471, 0x6472, 0x6473, + 0x6474, 0x6475, 0x6476, 0x6477, 0x647b, 0x647c, 0x647d, 0x647e, + 0x647f, 0x6480, 0x6481, 0x6483, 0x6486, 0x6488, 0x6489, 0x648a, + 0x648b, 0x648c, 0x648d, 0x648e, 0x648f, 0x6490, 0x6493, 0x6494, + 0x6497, 0x6498, 0x649a, 0x649b, 0x649c, 0x649d, 0x649f, 0x64a0, + 0x64a1, 0x64a2, 0x64a3, 0x64a5, 0x64a6, 0x64a7, 0x64a8, 0x64aa, + 0x64ab, 0x64af, 0x64b1, 0x64b2, 0x64b3, 0x64b4, 0x64b6, 0x64b9, + 0x64bb, 0x64bd, 0x64be, 0x64bf, 0x64c1, 0x64c3, 0x64c4, 0x64c6, + 0x64c7, 0x64c8, 0x64c9, 0x64ca, 0x64cb, 0x64cc, 0x64cf, 0x64d1, + 0x64d3, 0x64d4, 0x64d5, 0x64d6, 0x64d9, 0x64da, + /* 0x94 */ + 0x64db, 0x64dc, 0x64dd, 0x64df, 0x64e0, 0x64e1, 0x64e3, 0x64e5, + 0x64e7, 0x64e8, 0x64e9, 0x64ea, 0x64eb, 0x64ec, 0x64ed, 0x64ee, + 0x64ef, 0x64f0, 0x64f1, 0x64f2, 0x64f3, 0x64f4, 0x64f5, 0x64f6, + 0x64f7, 0x64f8, 0x64f9, 0x64fa, 0x64fb, 0x64fc, 0x64fd, 0x64fe, + 0x64ff, 0x6501, 0x6502, 0x6503, 0x6504, 0x6505, 0x6506, 0x6507, + 0x6508, 0x650a, 0x650b, 0x650c, 0x650d, 0x650e, 0x650f, 0x6510, + 0x6511, 0x6513, 0x6514, 0x6515, 0x6516, 0x6517, 0x6519, 0x651a, + 0x651b, 0x651c, 0x651d, 0x651e, 0x651f, 0x6520, 0x6521, 0x6522, + 0x6523, 0x6524, 0x6526, 0x6527, 0x6528, 0x6529, 0x652a, 0x652c, + 0x652d, 0x6530, 0x6531, 0x6532, 0x6533, 0x6537, 0x653a, 0x653c, + 0x653d, 0x6540, 0x6541, 0x6542, 0x6543, 0x6544, 0x6546, 0x6547, + 0x654a, 0x654b, 0x654d, 0x654e, 0x6550, 0x6552, 0x6553, 0x6554, + 0x6557, 0x6558, 0x655a, 0x655c, 0x655f, 0x6560, 0x6561, 0x6564, + 0x6565, 0x6567, 0x6568, 0x6569, 0x656a, 0x656d, 0x656e, 0x656f, + 0x6571, 0x6573, 0x6575, 0x6576, 0x6578, 0x6579, 0x657a, 0x657b, + 0x657c, 0x657d, 0x657e, 0x657f, 0x6580, 0x6581, 0x6582, 0x6583, + 0x6584, 0x6585, 0x6586, 0x6588, 0x6589, 0x658a, 0x658d, 0x658e, + 0x658f, 0x6592, 0x6594, 0x6595, 0x6596, 0x6598, 0x659a, 0x659d, + 0x659e, 0x65a0, 0x65a2, 0x65a3, 0x65a6, 0x65a8, 0x65aa, 0x65ac, + 0x65ae, 0x65b1, 0x65b2, 0x65b3, 0x65b4, 0x65b5, 0x65b6, 0x65b7, + 0x65b8, 0x65ba, 0x65bb, 0x65be, 0x65bf, 0x65c0, 0x65c2, 0x65c7, + 0x65c8, 0x65c9, 0x65ca, 0x65cd, 0x65d0, 0x65d1, 0x65d3, 0x65d4, + 0x65d5, 0x65d8, 0x65d9, 0x65da, 0x65db, 0x65dc, 0x65dd, 0x65de, + 0x65df, 0x65e1, 0x65e3, 0x65e4, 0x65ea, 0x65eb, + /* 0x95 */ + 0x65f2, 0x65f3, 0x65f4, 0x65f5, 0x65f8, 0x65f9, 0x65fb, 0x65fc, + 0x65fd, 0x65fe, 0x65ff, 0x6601, 0x6604, 0x6605, 0x6607, 0x6608, + 0x6609, 0x660b, 0x660d, 0x6610, 0x6611, 0x6612, 0x6616, 0x6617, + 0x6618, 0x661a, 0x661b, 0x661c, 0x661e, 0x6621, 0x6622, 0x6623, + 0x6624, 0x6626, 0x6629, 0x662a, 0x662b, 0x662c, 0x662e, 0x6630, + 0x6632, 0x6633, 0x6637, 0x6638, 0x6639, 0x663a, 0x663b, 0x663d, + 0x663f, 0x6640, 0x6642, 0x6644, 0x6645, 0x6646, 0x6647, 0x6648, + 0x6649, 0x664a, 0x664d, 0x664e, 0x6650, 0x6651, 0x6658, 0x6659, + 0x665b, 0x665c, 0x665d, 0x665e, 0x6660, 0x6662, 0x6663, 0x6665, + 0x6667, 0x6669, 0x666a, 0x666b, 0x666c, 0x666d, 0x6671, 0x6672, + 0x6673, 0x6675, 0x6678, 0x6679, 0x667b, 0x667c, 0x667d, 0x667f, + 0x6680, 0x6681, 0x6683, 0x6685, 0x6686, 0x6688, 0x6689, 0x668a, + 0x668b, 0x668d, 0x668e, 0x668f, 0x6690, 0x6692, 0x6693, 0x6694, + 0x6695, 0x6698, 0x6699, 0x669a, 0x669b, 0x669c, 0x669e, 0x669f, + 0x66a0, 0x66a1, 0x66a2, 0x66a3, 0x66a4, 0x66a5, 0x66a6, 0x66a9, + 0x66aa, 0x66ab, 0x66ac, 0x66ad, 0x66af, 0x66b0, 0x66b1, 0x66b2, + 0x66b3, 0x66b5, 0x66b6, 0x66b7, 0x66b8, 0x66ba, 0x66bb, 0x66bc, + 0x66bd, 0x66bf, 0x66c0, 0x66c1, 0x66c2, 0x66c3, 0x66c4, 0x66c5, + 0x66c6, 0x66c7, 0x66c8, 0x66c9, 0x66ca, 0x66cb, 0x66cc, 0x66cd, + 0x66ce, 0x66cf, 0x66d0, 0x66d1, 0x66d2, 0x66d3, 0x66d4, 0x66d5, + 0x66d6, 0x66d7, 0x66d8, 0x66da, 0x66de, 0x66df, 0x66e0, 0x66e1, + 0x66e2, 0x66e3, 0x66e4, 0x66e5, 0x66e7, 0x66e8, 0x66ea, 0x66eb, + 0x66ec, 0x66ed, 0x66ee, 0x66ef, 0x66f1, 0x66f5, 0x66f6, 0x66f8, + 0x66fa, 0x66fb, 0x66fd, 0x6701, 0x6702, 0x6703, + /* 0x96 */ + 0x6704, 0x6705, 0x6706, 0x6707, 0x670c, 0x670e, 0x670f, 0x6711, + 0x6712, 0x6713, 0x6716, 0x6718, 0x6719, 0x671a, 0x671c, 0x671e, + 0x6720, 0x6721, 0x6722, 0x6723, 0x6724, 0x6725, 0x6727, 0x6729, + 0x672e, 0x6730, 0x6732, 0x6733, 0x6736, 0x6737, 0x6738, 0x6739, + 0x673b, 0x673c, 0x673e, 0x673f, 0x6741, 0x6744, 0x6745, 0x6747, + 0x674a, 0x674b, 0x674d, 0x6752, 0x6754, 0x6755, 0x6757, 0x6758, + 0x6759, 0x675a, 0x675b, 0x675d, 0x6762, 0x6763, 0x6764, 0x6766, + 0x6767, 0x676b, 0x676c, 0x676e, 0x6771, 0x6774, 0x6776, 0x6778, + 0x6779, 0x677a, 0x677b, 0x677d, 0x6780, 0x6782, 0x6783, 0x6785, + 0x6786, 0x6788, 0x678a, 0x678c, 0x678d, 0x678e, 0x678f, 0x6791, + 0x6792, 0x6793, 0x6794, 0x6796, 0x6799, 0x679b, 0x679f, 0x67a0, + 0x67a1, 0x67a4, 0x67a6, 0x67a9, 0x67ac, 0x67ae, 0x67b1, 0x67b2, + 0x67b4, 0x67b9, 0x67ba, 0x67bb, 0x67bc, 0x67bd, 0x67be, 0x67bf, + 0x67c0, 0x67c2, 0x67c5, 0x67c6, 0x67c7, 0x67c8, 0x67c9, 0x67ca, + 0x67cb, 0x67cc, 0x67cd, 0x67ce, 0x67d5, 0x67d6, 0x67d7, 0x67db, + 0x67df, 0x67e1, 0x67e3, 0x67e4, 0x67e6, 0x67e7, 0x67e8, 0x67ea, + 0x67eb, 0x67ed, 0x67ee, 0x67f2, 0x67f5, 0x67f6, 0x67f7, 0x67f8, + 0x67f9, 0x67fa, 0x67fb, 0x67fc, 0x67fe, 0x6801, 0x6802, 0x6803, + 0x6804, 0x6806, 0x680d, 0x6810, 0x6812, 0x6814, 0x6815, 0x6818, + 0x6819, 0x681a, 0x681b, 0x681c, 0x681e, 0x681f, 0x6820, 0x6822, + 0x6823, 0x6824, 0x6825, 0x6826, 0x6827, 0x6828, 0x682b, 0x682c, + 0x682d, 0x682e, 0x682f, 0x6830, 0x6831, 0x6834, 0x6835, 0x6836, + 0x683a, 0x683b, 0x683f, 0x6847, 0x684b, 0x684d, 0x684f, 0x6852, + 0x6856, 0x6857, 0x6858, 0x6859, 0x685a, 0x685b, + /* 0x97 */ + 0x685c, 0x685d, 0x685e, 0x685f, 0x686a, 0x686c, 0x686d, 0x686e, + 0x686f, 0x6870, 0x6871, 0x6872, 0x6873, 0x6875, 0x6878, 0x6879, + 0x687a, 0x687b, 0x687c, 0x687d, 0x687e, 0x687f, 0x6880, 0x6882, + 0x6884, 0x6887, 0x6888, 0x6889, 0x688a, 0x688b, 0x688c, 0x688d, + 0x688e, 0x6890, 0x6891, 0x6892, 0x6894, 0x6895, 0x6896, 0x6898, + 0x6899, 0x689a, 0x689b, 0x689c, 0x689d, 0x689e, 0x689f, 0x68a0, + 0x68a1, 0x68a3, 0x68a4, 0x68a5, 0x68a9, 0x68aa, 0x68ab, 0x68ac, + 0x68ae, 0x68b1, 0x68b2, 0x68b4, 0x68b6, 0x68b7, 0x68b8, 0x68b9, + 0x68ba, 0x68bb, 0x68bc, 0x68bd, 0x68be, 0x68bf, 0x68c1, 0x68c3, + 0x68c4, 0x68c5, 0x68c6, 0x68c7, 0x68c8, 0x68ca, 0x68cc, 0x68ce, + 0x68cf, 0x68d0, 0x68d1, 0x68d3, 0x68d4, 0x68d6, 0x68d7, 0x68d9, + 0x68db, 0x68dc, 0x68dd, 0x68de, 0x68df, 0x68e1, 0x68e2, 0x68e4, + 0x68e5, 0x68e6, 0x68e7, 0x68e8, 0x68e9, 0x68ea, 0x68eb, 0x68ec, + 0x68ed, 0x68ef, 0x68f2, 0x68f3, 0x68f4, 0x68f6, 0x68f7, 0x68f8, + 0x68fb, 0x68fd, 0x68fe, 0x68ff, 0x6900, 0x6902, 0x6903, 0x6904, + 0x6906, 0x6907, 0x6908, 0x6909, 0x690a, 0x690c, 0x690f, 0x6911, + 0x6913, 0x6914, 0x6915, 0x6916, 0x6917, 0x6918, 0x6919, 0x691a, + 0x691b, 0x691c, 0x691d, 0x691e, 0x6921, 0x6922, 0x6923, 0x6925, + 0x6926, 0x6927, 0x6928, 0x6929, 0x692a, 0x692b, 0x692c, 0x692e, + 0x692f, 0x6931, 0x6932, 0x6933, 0x6935, 0x6936, 0x6937, 0x6938, + 0x693a, 0x693b, 0x693c, 0x693e, 0x6940, 0x6941, 0x6943, 0x6944, + 0x6945, 0x6946, 0x6947, 0x6948, 0x6949, 0x694a, 0x694b, 0x694c, + 0x694d, 0x694e, 0x694f, 0x6950, 0x6951, 0x6952, 0x6953, 0x6955, + 0x6956, 0x6958, 0x6959, 0x695b, 0x695c, 0x695f, + /* 0x98 */ + 0x6961, 0x6962, 0x6964, 0x6965, 0x6967, 0x6968, 0x6969, 0x696a, + 0x696c, 0x696d, 0x696f, 0x6970, 0x6972, 0x6973, 0x6974, 0x6975, + 0x6976, 0x697a, 0x697b, 0x697d, 0x697e, 0x697f, 0x6981, 0x6983, + 0x6985, 0x698a, 0x698b, 0x698c, 0x698e, 0x698f, 0x6990, 0x6991, + 0x6992, 0x6993, 0x6996, 0x6997, 0x6999, 0x699a, 0x699d, 0x699e, + 0x699f, 0x69a0, 0x69a1, 0x69a2, 0x69a3, 0x69a4, 0x69a5, 0x69a6, + 0x69a9, 0x69aa, 0x69ac, 0x69ae, 0x69af, 0x69b0, 0x69b2, 0x69b3, + 0x69b5, 0x69b6, 0x69b8, 0x69b9, 0x69ba, 0x69bc, 0x69bd, 0x69be, + 0x69bf, 0x69c0, 0x69c2, 0x69c3, 0x69c4, 0x69c5, 0x69c6, 0x69c7, + 0x69c8, 0x69c9, 0x69cb, 0x69cd, 0x69cf, 0x69d1, 0x69d2, 0x69d3, + 0x69d5, 0x69d6, 0x69d7, 0x69d8, 0x69d9, 0x69da, 0x69dc, 0x69dd, + 0x69de, 0x69e1, 0x69e2, 0x69e3, 0x69e4, 0x69e5, 0x69e6, 0x69e7, + 0x69e8, 0x69e9, 0x69ea, 0x69eb, 0x69ec, 0x69ee, 0x69ef, 0x69f0, + 0x69f1, 0x69f3, 0x69f4, 0x69f5, 0x69f6, 0x69f7, 0x69f8, 0x69f9, + 0x69fa, 0x69fb, 0x69fc, 0x69fe, 0x6a00, 0x6a01, 0x6a02, 0x6a03, + 0x6a04, 0x6a05, 0x6a06, 0x6a07, 0x6a08, 0x6a09, 0x6a0b, 0x6a0c, + 0x6a0d, 0x6a0e, 0x6a0f, 0x6a10, 0x6a11, 0x6a12, 0x6a13, 0x6a14, + 0x6a15, 0x6a16, 0x6a19, 0x6a1a, 0x6a1b, 0x6a1c, 0x6a1d, 0x6a1e, + 0x6a20, 0x6a22, 0x6a23, 0x6a24, 0x6a25, 0x6a26, 0x6a27, 0x6a29, + 0x6a2b, 0x6a2c, 0x6a2d, 0x6a2e, 0x6a30, 0x6a32, 0x6a33, 0x6a34, + 0x6a36, 0x6a37, 0x6a38, 0x6a39, 0x6a3a, 0x6a3b, 0x6a3c, 0x6a3f, + 0x6a40, 0x6a41, 0x6a42, 0x6a43, 0x6a45, 0x6a46, 0x6a48, 0x6a49, + 0x6a4a, 0x6a4b, 0x6a4c, 0x6a4d, 0x6a4e, 0x6a4f, 0x6a51, 0x6a52, + 0x6a53, 0x6a54, 0x6a55, 0x6a56, 0x6a57, 0x6a5a, + /* 0x99 */ + 0x6a5c, 0x6a5d, 0x6a5e, 0x6a5f, 0x6a60, 0x6a62, 0x6a63, 0x6a64, + 0x6a66, 0x6a67, 0x6a68, 0x6a69, 0x6a6a, 0x6a6b, 0x6a6c, 0x6a6d, + 0x6a6e, 0x6a6f, 0x6a70, 0x6a72, 0x6a73, 0x6a74, 0x6a75, 0x6a76, + 0x6a77, 0x6a78, 0x6a7a, 0x6a7b, 0x6a7d, 0x6a7e, 0x6a7f, 0x6a81, + 0x6a82, 0x6a83, 0x6a85, 0x6a86, 0x6a87, 0x6a88, 0x6a89, 0x6a8a, + 0x6a8b, 0x6a8c, 0x6a8d, 0x6a8f, 0x6a92, 0x6a93, 0x6a94, 0x6a95, + 0x6a96, 0x6a98, 0x6a99, 0x6a9a, 0x6a9b, 0x6a9c, 0x6a9d, 0x6a9e, + 0x6a9f, 0x6aa1, 0x6aa2, 0x6aa3, 0x6aa4, 0x6aa5, 0x6aa6, 0x6aa7, + 0x6aa8, 0x6aaa, 0x6aad, 0x6aae, 0x6aaf, 0x6ab0, 0x6ab1, 0x6ab2, + 0x6ab3, 0x6ab4, 0x6ab5, 0x6ab6, 0x6ab7, 0x6ab8, 0x6ab9, 0x6aba, + 0x6abb, 0x6abc, 0x6abd, 0x6abe, 0x6abf, 0x6ac0, 0x6ac1, 0x6ac2, + 0x6ac3, 0x6ac4, 0x6ac5, 0x6ac6, 0x6ac7, 0x6ac8, 0x6ac9, 0x6aca, + 0x6acb, 0x6acc, 0x6acd, 0x6ace, 0x6acf, 0x6ad0, 0x6ad1, 0x6ad2, + 0x6ad3, 0x6ad4, 0x6ad5, 0x6ad6, 0x6ad7, 0x6ad8, 0x6ad9, 0x6ada, + 0x6adb, 0x6adc, 0x6add, 0x6ade, 0x6adf, 0x6ae0, 0x6ae1, 0x6ae2, + 0x6ae3, 0x6ae4, 0x6ae5, 0x6ae6, 0x6ae7, 0x6ae8, 0x6ae9, 0x6aea, + 0x6aeb, 0x6aec, 0x6aed, 0x6aee, 0x6aef, 0x6af0, 0x6af1, 0x6af2, + 0x6af3, 0x6af4, 0x6af5, 0x6af6, 0x6af7, 0x6af8, 0x6af9, 0x6afa, + 0x6afb, 0x6afc, 0x6afd, 0x6afe, 0x6aff, 0x6b00, 0x6b01, 0x6b02, + 0x6b03, 0x6b04, 0x6b05, 0x6b06, 0x6b07, 0x6b08, 0x6b09, 0x6b0a, + 0x6b0b, 0x6b0c, 0x6b0d, 0x6b0e, 0x6b0f, 0x6b10, 0x6b11, 0x6b12, + 0x6b13, 0x6b14, 0x6b15, 0x6b16, 0x6b17, 0x6b18, 0x6b19, 0x6b1a, + 0x6b1b, 0x6b1c, 0x6b1d, 0x6b1e, 0x6b1f, 0x6b25, 0x6b26, 0x6b28, + 0x6b29, 0x6b2a, 0x6b2b, 0x6b2c, 0x6b2d, 0x6b2e, + /* 0x9a */ + 0x6b2f, 0x6b30, 0x6b31, 0x6b33, 0x6b34, 0x6b35, 0x6b36, 0x6b38, + 0x6b3b, 0x6b3c, 0x6b3d, 0x6b3f, 0x6b40, 0x6b41, 0x6b42, 0x6b44, + 0x6b45, 0x6b48, 0x6b4a, 0x6b4b, 0x6b4d, 0x6b4e, 0x6b4f, 0x6b50, + 0x6b51, 0x6b52, 0x6b53, 0x6b54, 0x6b55, 0x6b56, 0x6b57, 0x6b58, + 0x6b5a, 0x6b5b, 0x6b5c, 0x6b5d, 0x6b5e, 0x6b5f, 0x6b60, 0x6b61, + 0x6b68, 0x6b69, 0x6b6b, 0x6b6c, 0x6b6d, 0x6b6e, 0x6b6f, 0x6b70, + 0x6b71, 0x6b72, 0x6b73, 0x6b74, 0x6b75, 0x6b76, 0x6b77, 0x6b78, + 0x6b7a, 0x6b7d, 0x6b7e, 0x6b7f, 0x6b80, 0x6b85, 0x6b88, 0x6b8c, + 0x6b8e, 0x6b8f, 0x6b90, 0x6b91, 0x6b94, 0x6b95, 0x6b97, 0x6b98, + 0x6b99, 0x6b9c, 0x6b9d, 0x6b9e, 0x6b9f, 0x6ba0, 0x6ba2, 0x6ba3, + 0x6ba4, 0x6ba5, 0x6ba6, 0x6ba7, 0x6ba8, 0x6ba9, 0x6bab, 0x6bac, + 0x6bad, 0x6bae, 0x6baf, 0x6bb0, 0x6bb1, 0x6bb2, 0x6bb6, 0x6bb8, + 0x6bb9, 0x6bba, 0x6bbb, 0x6bbc, 0x6bbd, 0x6bbe, 0x6bc0, 0x6bc3, + 0x6bc4, 0x6bc6, 0x6bc7, 0x6bc8, 0x6bc9, 0x6bca, 0x6bcc, 0x6bce, + 0x6bd0, 0x6bd1, 0x6bd8, 0x6bda, 0x6bdc, 0x6bdd, 0x6bde, 0x6bdf, + 0x6be0, 0x6be2, 0x6be3, 0x6be4, 0x6be5, 0x6be6, 0x6be7, 0x6be8, + 0x6be9, 0x6bec, 0x6bed, 0x6bee, 0x6bf0, 0x6bf1, 0x6bf2, 0x6bf4, + 0x6bf6, 0x6bf7, 0x6bf8, 0x6bfa, 0x6bfb, 0x6bfc, 0x6bfe, 0x6bff, + 0x6c00, 0x6c01, 0x6c02, 0x6c03, 0x6c04, 0x6c08, 0x6c09, 0x6c0a, + 0x6c0b, 0x6c0c, 0x6c0e, 0x6c12, 0x6c17, 0x6c1c, 0x6c1d, 0x6c1e, + 0x6c20, 0x6c23, 0x6c25, 0x6c2b, 0x6c2c, 0x6c2d, 0x6c31, 0x6c33, + 0x6c36, 0x6c37, 0x6c39, 0x6c3a, 0x6c3b, 0x6c3c, 0x6c3e, 0x6c3f, + 0x6c43, 0x6c44, 0x6c45, 0x6c48, 0x6c4b, 0x6c4c, 0x6c4d, 0x6c4e, + 0x6c4f, 0x6c51, 0x6c52, 0x6c53, 0x6c56, 0x6c58, + /* 0x9b */ + 0x6c59, 0x6c5a, 0x6c62, 0x6c63, 0x6c65, 0x6c66, 0x6c67, 0x6c6b, + 0x6c6c, 0x6c6d, 0x6c6e, 0x6c6f, 0x6c71, 0x6c73, 0x6c75, 0x6c77, + 0x6c78, 0x6c7a, 0x6c7b, 0x6c7c, 0x6c7f, 0x6c80, 0x6c84, 0x6c87, + 0x6c8a, 0x6c8b, 0x6c8d, 0x6c8e, 0x6c91, 0x6c92, 0x6c95, 0x6c96, + 0x6c97, 0x6c98, 0x6c9a, 0x6c9c, 0x6c9d, 0x6c9e, 0x6ca0, 0x6ca2, + 0x6ca8, 0x6cac, 0x6caf, 0x6cb0, 0x6cb4, 0x6cb5, 0x6cb6, 0x6cb7, + 0x6cba, 0x6cc0, 0x6cc1, 0x6cc2, 0x6cc3, 0x6cc6, 0x6cc7, 0x6cc8, + 0x6ccb, 0x6ccd, 0x6cce, 0x6ccf, 0x6cd1, 0x6cd2, 0x6cd8, 0x6cd9, + 0x6cda, 0x6cdc, 0x6cdd, 0x6cdf, 0x6ce4, 0x6ce6, 0x6ce7, 0x6ce9, + 0x6cec, 0x6ced, 0x6cf2, 0x6cf4, 0x6cf9, 0x6cff, 0x6d00, 0x6d02, + 0x6d03, 0x6d05, 0x6d06, 0x6d08, 0x6d09, 0x6d0a, 0x6d0d, 0x6d0f, + 0x6d10, 0x6d11, 0x6d13, 0x6d14, 0x6d15, 0x6d16, 0x6d18, 0x6d1c, + 0x6d1d, 0x6d1f, 0x6d20, 0x6d21, 0x6d22, 0x6d23, 0x6d24, 0x6d26, + 0x6d28, 0x6d29, 0x6d2c, 0x6d2d, 0x6d2f, 0x6d30, 0x6d34, 0x6d36, + 0x6d37, 0x6d38, 0x6d3a, 0x6d3f, 0x6d40, 0x6d42, 0x6d44, 0x6d49, + 0x6d4c, 0x6d50, 0x6d55, 0x6d56, 0x6d57, 0x6d58, 0x6d5b, 0x6d5d, + 0x6d5f, 0x6d61, 0x6d62, 0x6d64, 0x6d65, 0x6d67, 0x6d68, 0x6d6b, + 0x6d6c, 0x6d6d, 0x6d70, 0x6d71, 0x6d72, 0x6d73, 0x6d75, 0x6d76, + 0x6d79, 0x6d7a, 0x6d7b, 0x6d7d, 0x6d7e, 0x6d7f, 0x6d80, 0x6d81, + 0x6d83, 0x6d84, 0x6d86, 0x6d87, 0x6d8a, 0x6d8b, 0x6d8d, 0x6d8f, + 0x6d90, 0x6d92, 0x6d96, 0x6d97, 0x6d98, 0x6d99, 0x6d9a, 0x6d9c, + 0x6da2, 0x6da5, 0x6dac, 0x6dad, 0x6db0, 0x6db1, 0x6db3, 0x6db4, + 0x6db6, 0x6db7, 0x6db9, 0x6dba, 0x6dbb, 0x6dbc, 0x6dbd, 0x6dbe, + 0x6dc1, 0x6dc2, 0x6dc3, 0x6dc8, 0x6dc9, 0x6dca, + /* 0x9c */ + 0x6dcd, 0x6dce, 0x6dcf, 0x6dd0, 0x6dd2, 0x6dd3, 0x6dd4, 0x6dd5, + 0x6dd7, 0x6dda, 0x6ddb, 0x6ddc, 0x6ddf, 0x6de2, 0x6de3, 0x6de5, + 0x6de7, 0x6de8, 0x6de9, 0x6dea, 0x6ded, 0x6def, 0x6df0, 0x6df2, + 0x6df4, 0x6df5, 0x6df6, 0x6df8, 0x6dfa, 0x6dfd, 0x6dfe, 0x6dff, + 0x6e00, 0x6e01, 0x6e02, 0x6e03, 0x6e04, 0x6e06, 0x6e07, 0x6e08, + 0x6e09, 0x6e0b, 0x6e0f, 0x6e12, 0x6e13, 0x6e15, 0x6e18, 0x6e19, + 0x6e1b, 0x6e1c, 0x6e1e, 0x6e1f, 0x6e22, 0x6e26, 0x6e27, 0x6e28, + 0x6e2a, 0x6e2c, 0x6e2e, 0x6e30, 0x6e31, 0x6e33, 0x6e35, 0x6e36, + 0x6e37, 0x6e39, 0x6e3b, 0x6e3c, 0x6e3d, 0x6e3e, 0x6e3f, 0x6e40, + 0x6e41, 0x6e42, 0x6e45, 0x6e46, 0x6e47, 0x6e48, 0x6e49, 0x6e4a, + 0x6e4b, 0x6e4c, 0x6e4f, 0x6e50, 0x6e51, 0x6e52, 0x6e55, 0x6e57, + 0x6e59, 0x6e5a, 0x6e5c, 0x6e5d, 0x6e5e, 0x6e60, 0x6e61, 0x6e62, + 0x6e63, 0x6e64, 0x6e65, 0x6e66, 0x6e67, 0x6e68, 0x6e69, 0x6e6a, + 0x6e6c, 0x6e6d, 0x6e6f, 0x6e70, 0x6e71, 0x6e72, 0x6e73, 0x6e74, + 0x6e75, 0x6e76, 0x6e77, 0x6e78, 0x6e79, 0x6e7a, 0x6e7b, 0x6e7c, + 0x6e7d, 0x6e80, 0x6e81, 0x6e82, 0x6e84, 0x6e87, 0x6e88, 0x6e8a, + 0x6e8b, 0x6e8c, 0x6e8d, 0x6e8e, 0x6e91, 0x6e92, 0x6e93, 0x6e94, + 0x6e95, 0x6e96, 0x6e97, 0x6e99, 0x6e9a, 0x6e9b, 0x6e9d, 0x6e9e, + 0x6ea0, 0x6ea1, 0x6ea3, 0x6ea4, 0x6ea6, 0x6ea8, 0x6ea9, 0x6eab, + 0x6eac, 0x6ead, 0x6eae, 0x6eb0, 0x6eb3, 0x6eb5, 0x6eb8, 0x6eb9, + 0x6ebc, 0x6ebe, 0x6ebf, 0x6ec0, 0x6ec3, 0x6ec4, 0x6ec5, 0x6ec6, + 0x6ec8, 0x6ec9, 0x6eca, 0x6ecc, 0x6ecd, 0x6ece, 0x6ed0, 0x6ed2, + 0x6ed6, 0x6ed8, 0x6ed9, 0x6edb, 0x6edc, 0x6edd, 0x6ee3, 0x6ee7, + 0x6eea, 0x6eeb, 0x6eec, 0x6eed, 0x6eee, 0x6eef, + /* 0x9d */ + 0x6ef0, 0x6ef1, 0x6ef2, 0x6ef3, 0x6ef5, 0x6ef6, 0x6ef7, 0x6ef8, + 0x6efa, 0x6efb, 0x6efc, 0x6efd, 0x6efe, 0x6eff, 0x6f00, 0x6f01, + 0x6f03, 0x6f04, 0x6f05, 0x6f07, 0x6f08, 0x6f0a, 0x6f0b, 0x6f0c, + 0x6f0d, 0x6f0e, 0x6f10, 0x6f11, 0x6f12, 0x6f16, 0x6f17, 0x6f18, + 0x6f19, 0x6f1a, 0x6f1b, 0x6f1c, 0x6f1d, 0x6f1e, 0x6f1f, 0x6f21, + 0x6f22, 0x6f23, 0x6f25, 0x6f26, 0x6f27, 0x6f28, 0x6f2c, 0x6f2e, + 0x6f30, 0x6f32, 0x6f34, 0x6f35, 0x6f37, 0x6f38, 0x6f39, 0x6f3a, + 0x6f3b, 0x6f3c, 0x6f3d, 0x6f3f, 0x6f40, 0x6f41, 0x6f42, 0x6f43, + 0x6f44, 0x6f45, 0x6f48, 0x6f49, 0x6f4a, 0x6f4c, 0x6f4e, 0x6f4f, + 0x6f50, 0x6f51, 0x6f52, 0x6f53, 0x6f54, 0x6f55, 0x6f56, 0x6f57, + 0x6f59, 0x6f5a, 0x6f5b, 0x6f5d, 0x6f5f, 0x6f60, 0x6f61, 0x6f63, + 0x6f64, 0x6f65, 0x6f67, 0x6f68, 0x6f69, 0x6f6a, 0x6f6b, 0x6f6c, + 0x6f6f, 0x6f70, 0x6f71, 0x6f73, 0x6f75, 0x6f76, 0x6f77, 0x6f79, + 0x6f7b, 0x6f7d, 0x6f7e, 0x6f7f, 0x6f80, 0x6f81, 0x6f82, 0x6f83, + 0x6f85, 0x6f86, 0x6f87, 0x6f8a, 0x6f8b, 0x6f8f, 0x6f90, 0x6f91, + 0x6f92, 0x6f93, 0x6f94, 0x6f95, 0x6f96, 0x6f97, 0x6f98, 0x6f99, + 0x6f9a, 0x6f9b, 0x6f9d, 0x6f9e, 0x6f9f, 0x6fa0, 0x6fa2, 0x6fa3, + 0x6fa4, 0x6fa5, 0x6fa6, 0x6fa8, 0x6fa9, 0x6faa, 0x6fab, 0x6fac, + 0x6fad, 0x6fae, 0x6faf, 0x6fb0, 0x6fb1, 0x6fb2, 0x6fb4, 0x6fb5, + 0x6fb7, 0x6fb8, 0x6fba, 0x6fbb, 0x6fbc, 0x6fbd, 0x6fbe, 0x6fbf, + 0x6fc1, 0x6fc3, 0x6fc4, 0x6fc5, 0x6fc6, 0x6fc7, 0x6fc8, 0x6fca, + 0x6fcb, 0x6fcc, 0x6fcd, 0x6fce, 0x6fcf, 0x6fd0, 0x6fd3, 0x6fd4, + 0x6fd5, 0x6fd6, 0x6fd7, 0x6fd8, 0x6fd9, 0x6fda, 0x6fdb, 0x6fdc, + 0x6fdd, 0x6fdf, 0x6fe2, 0x6fe3, 0x6fe4, 0x6fe5, + /* 0x9e */ + 0x6fe6, 0x6fe7, 0x6fe8, 0x6fe9, 0x6fea, 0x6feb, 0x6fec, 0x6fed, + 0x6ff0, 0x6ff1, 0x6ff2, 0x6ff3, 0x6ff4, 0x6ff5, 0x6ff6, 0x6ff7, + 0x6ff8, 0x6ff9, 0x6ffa, 0x6ffb, 0x6ffc, 0x6ffd, 0x6ffe, 0x6fff, + 0x7000, 0x7001, 0x7002, 0x7003, 0x7004, 0x7005, 0x7006, 0x7007, + 0x7008, 0x7009, 0x700a, 0x700b, 0x700c, 0x700d, 0x700e, 0x700f, + 0x7010, 0x7012, 0x7013, 0x7014, 0x7015, 0x7016, 0x7017, 0x7018, + 0x7019, 0x701c, 0x701d, 0x701e, 0x701f, 0x7020, 0x7021, 0x7022, + 0x7024, 0x7025, 0x7026, 0x7027, 0x7028, 0x7029, 0x702a, 0x702b, + 0x702c, 0x702d, 0x702e, 0x702f, 0x7030, 0x7031, 0x7032, 0x7033, + 0x7034, 0x7036, 0x7037, 0x7038, 0x703a, 0x703b, 0x703c, 0x703d, + 0x703e, 0x703f, 0x7040, 0x7041, 0x7042, 0x7043, 0x7044, 0x7045, + 0x7046, 0x7047, 0x7048, 0x7049, 0x704a, 0x704b, 0x704d, 0x704e, + 0x7050, 0x7051, 0x7052, 0x7053, 0x7054, 0x7055, 0x7056, 0x7057, + 0x7058, 0x7059, 0x705a, 0x705b, 0x705c, 0x705d, 0x705f, 0x7060, + 0x7061, 0x7062, 0x7063, 0x7064, 0x7065, 0x7066, 0x7067, 0x7068, + 0x7069, 0x706a, 0x706e, 0x7071, 0x7072, 0x7073, 0x7074, 0x7077, + 0x7079, 0x707a, 0x707b, 0x707d, 0x7081, 0x7082, 0x7083, 0x7084, + 0x7086, 0x7087, 0x7088, 0x708b, 0x708c, 0x708d, 0x708f, 0x7090, + 0x7091, 0x7093, 0x7097, 0x7098, 0x709a, 0x709b, 0x709e, 0x709f, + 0x70a0, 0x70a1, 0x70a2, 0x70a3, 0x70a4, 0x70a5, 0x70a6, 0x70a7, + 0x70a8, 0x70a9, 0x70aa, 0x70b0, 0x70b2, 0x70b4, 0x70b5, 0x70b6, + 0x70ba, 0x70be, 0x70bf, 0x70c4, 0x70c5, 0x70c6, 0x70c7, 0x70c9, + 0x70cb, 0x70cc, 0x70cd, 0x70ce, 0x70cf, 0x70d0, 0x70d1, 0x70d2, + 0x70d3, 0x70d4, 0x70d5, 0x70d6, 0x70d7, 0x70da, + /* 0x9f */ + 0x70dc, 0x70dd, 0x70de, 0x70e0, 0x70e1, 0x70e2, 0x70e3, 0x70e5, + 0x70ea, 0x70ee, 0x70f0, 0x70f1, 0x70f2, 0x70f3, 0x70f4, 0x70f5, + 0x70f6, 0x70f8, 0x70fa, 0x70fb, 0x70fc, 0x70fe, 0x70ff, 0x7100, + 0x7101, 0x7102, 0x7103, 0x7104, 0x7105, 0x7106, 0x7107, 0x7108, + 0x710b, 0x710c, 0x710d, 0x710e, 0x710f, 0x7111, 0x7112, 0x7114, + 0x7117, 0x711b, 0x711c, 0x711d, 0x711e, 0x711f, 0x7120, 0x7121, + 0x7122, 0x7123, 0x7124, 0x7125, 0x7127, 0x7128, 0x7129, 0x712a, + 0x712b, 0x712c, 0x712d, 0x712e, 0x7132, 0x7133, 0x7134, 0x7135, + 0x7137, 0x7138, 0x7139, 0x713a, 0x713b, 0x713c, 0x713d, 0x713e, + 0x713f, 0x7140, 0x7141, 0x7142, 0x7143, 0x7144, 0x7146, 0x7147, + 0x7148, 0x7149, 0x714b, 0x714d, 0x714f, 0x7150, 0x7151, 0x7152, + 0x7153, 0x7154, 0x7155, 0x7156, 0x7157, 0x7158, 0x7159, 0x715a, + 0x715b, 0x715d, 0x715f, 0x7160, 0x7161, 0x7162, 0x7163, 0x7165, + 0x7169, 0x716a, 0x716b, 0x716c, 0x716d, 0x716f, 0x7170, 0x7171, + 0x7174, 0x7175, 0x7176, 0x7177, 0x7179, 0x717b, 0x717c, 0x717e, + 0x717f, 0x7180, 0x7181, 0x7182, 0x7183, 0x7185, 0x7186, 0x7187, + 0x7188, 0x7189, 0x718b, 0x718c, 0x718d, 0x718e, 0x7190, 0x7191, + 0x7192, 0x7193, 0x7195, 0x7196, 0x7197, 0x719a, 0x719b, 0x719c, + 0x719d, 0x719e, 0x71a1, 0x71a2, 0x71a3, 0x71a4, 0x71a5, 0x71a6, + 0x71a7, 0x71a9, 0x71aa, 0x71ab, 0x71ad, 0x71ae, 0x71af, 0x71b0, + 0x71b1, 0x71b2, 0x71b4, 0x71b6, 0x71b7, 0x71b8, 0x71ba, 0x71bb, + 0x71bc, 0x71bd, 0x71be, 0x71bf, 0x71c0, 0x71c1, 0x71c2, 0x71c4, + 0x71c5, 0x71c6, 0x71c7, 0x71c8, 0x71c9, 0x71ca, 0x71cb, 0x71cc, + 0x71cd, 0x71cf, 0x71d0, 0x71d1, 0x71d2, 0x71d3, + /* 0xa0 */ + 0x71d6, 0x71d7, 0x71d8, 0x71d9, 0x71da, 0x71db, 0x71dc, 0x71dd, + 0x71de, 0x71df, 0x71e1, 0x71e2, 0x71e3, 0x71e4, 0x71e6, 0x71e8, + 0x71e9, 0x71ea, 0x71eb, 0x71ec, 0x71ed, 0x71ef, 0x71f0, 0x71f1, + 0x71f2, 0x71f3, 0x71f4, 0x71f5, 0x71f6, 0x71f7, 0x71f8, 0x71fa, + 0x71fb, 0x71fc, 0x71fd, 0x71fe, 0x71ff, 0x7200, 0x7201, 0x7202, + 0x7203, 0x7204, 0x7205, 0x7207, 0x7208, 0x7209, 0x720a, 0x720b, + 0x720c, 0x720d, 0x720e, 0x720f, 0x7210, 0x7211, 0x7212, 0x7213, + 0x7214, 0x7215, 0x7216, 0x7217, 0x7218, 0x7219, 0x721a, 0x721b, + 0x721c, 0x721e, 0x721f, 0x7220, 0x7221, 0x7222, 0x7223, 0x7224, + 0x7225, 0x7226, 0x7227, 0x7229, 0x722b, 0x722d, 0x722e, 0x722f, + 0x7232, 0x7233, 0x7234, 0x723a, 0x723c, 0x723e, 0x7240, 0x7241, + 0x7242, 0x7243, 0x7244, 0x7245, 0x7246, 0x7249, 0x724a, 0x724b, + 0x724e, 0x724f, 0x7250, 0x7251, 0x7253, 0x7254, 0x7255, 0x7257, + 0x7258, 0x725a, 0x725c, 0x725e, 0x7260, 0x7263, 0x7264, 0x7265, + 0x7268, 0x726a, 0x726b, 0x726c, 0x726d, 0x7270, 0x7271, 0x7273, + 0x7274, 0x7276, 0x7277, 0x7278, 0x727b, 0x727c, 0x727d, 0x7282, + 0x7283, 0x7285, 0x7286, 0x7287, 0x7288, 0x7289, 0x728c, 0x728e, + 0x7290, 0x7291, 0x7293, 0x7294, 0x7295, 0x7296, 0x7297, 0x7298, + 0x7299, 0x729a, 0x729b, 0x729c, 0x729d, 0x729e, 0x72a0, 0x72a1, + 0x72a2, 0x72a3, 0x72a4, 0x72a5, 0x72a6, 0x72a7, 0x72a8, 0x72a9, + 0x72aa, 0x72ab, 0x72ae, 0x72b1, 0x72b2, 0x72b3, 0x72b5, 0x72ba, + 0x72bb, 0x72bc, 0x72bd, 0x72be, 0x72bf, 0x72c0, 0x72c5, 0x72c6, + 0x72c7, 0x72c9, 0x72ca, 0x72cb, 0x72cc, 0x72cf, 0x72d1, 0x72d3, + 0x72d4, 0x72d5, 0x72d6, 0x72d8, 0x72da, 0x72db, + /* 0xa1 */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x3000, 0x3001, 0x3002, 0x00b7, 0x02c9, 0x02c7, 0x00a8, 0x3003, + 0x3005, 0x2014, 0xff5e, 0x2016, 0x2026, 0x2018, 0x2019, 0x201c, + 0x201d, 0x3014, 0x3015, 0x3008, 0x3009, 0x300a, 0x300b, 0x300c, + 0x300d, 0x300e, 0x300f, 0x3016, 0x3017, 0x3010, 0x3011, 0x00b1, + 0x00d7, 0x00f7, 0x2236, 0x2227, 0x2228, 0x2211, 0x220f, 0x222a, + 0x2229, 0x2208, 0x2237, 0x221a, 0x22a5, 0x2225, 0x2220, 0x2312, + 0x2299, 0x222b, 0x222e, 0x2261, 0x224c, 0x2248, 0x223d, 0x221d, + 0x2260, 0x226e, 0x226f, 0x2264, 0x2265, 0x221e, 0x2235, 0x2234, + 0x2642, 0x2640, 0x00b0, 0x2032, 0x2033, 0x2103, 0xff04, 0x00a4, + 0xffe0, 0xffe1, 0x2030, 0x00a7, 0x2116, 0x2606, 0x2605, 0x25cb, + 0x25cf, 0x25ce, 0x25c7, 0x25c6, 0x25a1, 0x25a0, 0x25b3, 0x25b2, + 0x203b, 0x2192, 0x2190, 0x2191, 0x2193, 0x3013, + /* 0xa2 */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, + 0x2178, 0x2179, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x2488, 0x2489, 0x248a, 0x248b, 0x248c, 0x248d, 0x248e, 0x248f, + 0x2490, 0x2491, 0x2492, 0x2493, 0x2494, 0x2495, 0x2496, 0x2497, + 0x2498, 0x2499, 0x249a, 0x249b, 0x2474, 0x2475, 0x2476, 0x2477, + 0x2478, 0x2479, 0x247a, 0x247b, 0x247c, 0x247d, 0x247e, 0x247f, + 0x2480, 0x2481, 0x2482, 0x2483, 0x2484, 0x2485, 0x2486, 0x2487, + 0x2460, 0x2461, 0x2462, 0x2463, 0x2464, 0x2465, 0x2466, 0x2467, + 0x2468, 0x2469, 0xfffd, 0xfffd, 0x3220, 0x3221, 0x3222, 0x3223, + 0x3224, 0x3225, 0x3226, 0x3227, 0x3228, 0x3229, 0xfffd, 0xfffd, + 0x2160, 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, + 0x2168, 0x2169, 0x216a, 0x216b, 0xfffd, 0xfffd, + /* 0xa3 */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xff01, 0xff02, 0xff03, 0xffe5, 0xff05, 0xff06, 0xff07, 0xff08, + 0xff09, 0xff0a, 0xff0b, 0xff0c, 0xff0d, 0xff0e, 0xff0f, 0xff10, + 0xff11, 0xff12, 0xff13, 0xff14, 0xff15, 0xff16, 0xff17, 0xff18, + 0xff19, 0xff1a, 0xff1b, 0xff1c, 0xff1d, 0xff1e, 0xff1f, 0xff20, + 0xff21, 0xff22, 0xff23, 0xff24, 0xff25, 0xff26, 0xff27, 0xff28, + 0xff29, 0xff2a, 0xff2b, 0xff2c, 0xff2d, 0xff2e, 0xff2f, 0xff30, + 0xff31, 0xff32, 0xff33, 0xff34, 0xff35, 0xff36, 0xff37, 0xff38, + 0xff39, 0xff3a, 0xff3b, 0xff3c, 0xff3d, 0xff3e, 0xff3f, 0xff40, + 0xff41, 0xff42, 0xff43, 0xff44, 0xff45, 0xff46, 0xff47, 0xff48, + 0xff49, 0xff4a, 0xff4b, 0xff4c, 0xff4d, 0xff4e, 0xff4f, 0xff50, + 0xff51, 0xff52, 0xff53, 0xff54, 0xff55, 0xff56, 0xff57, 0xff58, + 0xff59, 0xff5a, 0xff5b, 0xff5c, 0xff5d, 0xffe3, + /* 0xa4 */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x3041, 0x3042, 0x3043, 0x3044, 0x3045, 0x3046, 0x3047, 0x3048, + 0x3049, 0x304a, 0x304b, 0x304c, 0x304d, 0x304e, 0x304f, 0x3050, + 0x3051, 0x3052, 0x3053, 0x3054, 0x3055, 0x3056, 0x3057, 0x3058, + 0x3059, 0x305a, 0x305b, 0x305c, 0x305d, 0x305e, 0x305f, 0x3060, + 0x3061, 0x3062, 0x3063, 0x3064, 0x3065, 0x3066, 0x3067, 0x3068, + 0x3069, 0x306a, 0x306b, 0x306c, 0x306d, 0x306e, 0x306f, 0x3070, + 0x3071, 0x3072, 0x3073, 0x3074, 0x3075, 0x3076, 0x3077, 0x3078, + 0x3079, 0x307a, 0x307b, 0x307c, 0x307d, 0x307e, 0x307f, 0x3080, + 0x3081, 0x3082, 0x3083, 0x3084, 0x3085, 0x3086, 0x3087, 0x3088, + 0x3089, 0x308a, 0x308b, 0x308c, 0x308d, 0x308e, 0x308f, 0x3090, + 0x3091, 0x3092, 0x3093, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0xa5 */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x30a1, 0x30a2, 0x30a3, 0x30a4, 0x30a5, 0x30a6, 0x30a7, 0x30a8, + 0x30a9, 0x30aa, 0x30ab, 0x30ac, 0x30ad, 0x30ae, 0x30af, 0x30b0, + 0x30b1, 0x30b2, 0x30b3, 0x30b4, 0x30b5, 0x30b6, 0x30b7, 0x30b8, + 0x30b9, 0x30ba, 0x30bb, 0x30bc, 0x30bd, 0x30be, 0x30bf, 0x30c0, + 0x30c1, 0x30c2, 0x30c3, 0x30c4, 0x30c5, 0x30c6, 0x30c7, 0x30c8, + 0x30c9, 0x30ca, 0x30cb, 0x30cc, 0x30cd, 0x30ce, 0x30cf, 0x30d0, + 0x30d1, 0x30d2, 0x30d3, 0x30d4, 0x30d5, 0x30d6, 0x30d7, 0x30d8, + 0x30d9, 0x30da, 0x30db, 0x30dc, 0x30dd, 0x30de, 0x30df, 0x30e0, + 0x30e1, 0x30e2, 0x30e3, 0x30e4, 0x30e5, 0x30e6, 0x30e7, 0x30e8, + 0x30e9, 0x30ea, 0x30eb, 0x30ec, 0x30ed, 0x30ee, 0x30ef, 0x30f0, + 0x30f1, 0x30f2, 0x30f3, 0x30f4, 0x30f5, 0x30f6, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0xa6 */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, + 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, 0x03a0, + 0x03a1, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7, 0x03a8, 0x03a9, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, 0x03b8, + 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, 0x03c0, + 0x03c1, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, 0x03c8, 0x03c9, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfe35, + 0xfe36, 0xfe39, 0xfe3a, 0xfe3f, 0xfe40, 0xfe3d, 0xfe3e, 0xfe41, + 0xfe42, 0xfe43, 0xfe44, 0xfffd, 0xfffd, 0xfe3b, 0xfe3c, 0xfe37, + 0xfe38, 0xfe31, 0xfffd, 0xfe33, 0xfe34, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0xa7 */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0401, 0x0416, + 0x0417, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, + 0x041f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, + 0x0427, 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, + 0x042f, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0451, 0x0436, + 0x0437, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, + 0x043f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, + 0x0447, 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, + 0x044f, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0xa8 */ + 0x02ca, 0x02cb, 0x02d9, 0x2013, 0x2015, 0x2025, 0x2035, 0x2105, + 0x2109, 0x2196, 0x2197, 0x2198, 0x2199, 0x2215, 0x221f, 0x2223, + 0x2252, 0x2266, 0x2267, 0x22bf, 0x2550, 0x2551, 0x2552, 0x2553, + 0x2554, 0x2555, 0x2556, 0x2557, 0x2558, 0x2559, 0x255a, 0x255b, + 0x255c, 0x255d, 0x255e, 0x255f, 0x2560, 0x2561, 0x2562, 0x2563, + 0x2564, 0x2565, 0x2566, 0x2567, 0x2568, 0x2569, 0x256a, 0x256b, + 0x256c, 0x256d, 0x256e, 0x256f, 0x2570, 0x2571, 0x2572, 0x2573, + 0x2581, 0x2582, 0x2583, 0x2584, 0x2585, 0x2586, 0x2587, 0x2588, + 0x2589, 0x258a, 0x258b, 0x258c, 0x258d, 0x258e, 0x258f, 0x2593, + 0x2594, 0x2595, 0x25bc, 0x25bd, 0x25e2, 0x25e3, 0x25e4, 0x25e5, + 0x2609, 0x2295, 0x3012, 0x301d, 0x301e, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x0101, 0x00e1, 0x01ce, 0x00e0, 0x0113, 0x00e9, 0x011b, 0x00e8, + 0x012b, 0x00ed, 0x01d0, 0x00ec, 0x014d, 0x00f3, 0x01d2, 0x00f2, + 0x016b, 0x00fa, 0x01d4, 0x00f9, 0x01d6, 0x01d8, 0x01da, 0x01dc, + 0x00fc, 0x00ea, 0x0251, 0xfffd, 0x0144, 0x0148, 0xfffd, 0x0261, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x3105, 0x3106, 0x3107, 0x3108, + 0x3109, 0x310a, 0x310b, 0x310c, 0x310d, 0x310e, 0x310f, 0x3110, + 0x3111, 0x3112, 0x3113, 0x3114, 0x3115, 0x3116, 0x3117, 0x3118, + 0x3119, 0x311a, 0x311b, 0x311c, 0x311d, 0x311e, 0x311f, 0x3120, + 0x3121, 0x3122, 0x3123, 0x3124, 0x3125, 0x3126, 0x3127, 0x3128, + 0x3129, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0xa9 */ + 0x3021, 0x3022, 0x3023, 0x3024, 0x3025, 0x3026, 0x3027, 0x3028, + 0x3029, 0x32a3, 0x338e, 0x338f, 0x339c, 0x339d, 0x339e, 0x33a1, + 0x33c4, 0x33ce, 0x33d1, 0x33d2, 0x33d5, 0xfe30, 0xffe2, 0xffe4, + 0xfffd, 0x2121, 0x3231, 0xfffd, 0x2010, 0xfffd, 0xfffd, 0xfffd, + 0x30fc, 0x309b, 0x309c, 0x30fd, 0x30fe, 0x3006, 0x309d, 0x309e, + 0xfe49, 0xfe4a, 0xfe4b, 0xfe4c, 0xfe4d, 0xfe4e, 0xfe4f, 0xfe50, + 0xfe51, 0xfe52, 0xfe54, 0xfe55, 0xfe56, 0xfe57, 0xfe59, 0xfe5a, + 0xfe5b, 0xfe5c, 0xfe5d, 0xfe5e, 0xfe5f, 0xfe60, 0xfe61, 0xfe62, + 0xfe63, 0xfe64, 0xfe65, 0xfe66, 0xfe68, 0xfe69, 0xfe6a, 0xfe6b, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x3007, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x2500, 0x2501, 0x2502, 0x2503, 0x2504, + 0x2505, 0x2506, 0x2507, 0x2508, 0x2509, 0x250a, 0x250b, 0x250c, + 0x250d, 0x250e, 0x250f, 0x2510, 0x2511, 0x2512, 0x2513, 0x2514, + 0x2515, 0x2516, 0x2517, 0x2518, 0x2519, 0x251a, 0x251b, 0x251c, + 0x251d, 0x251e, 0x251f, 0x2520, 0x2521, 0x2522, 0x2523, 0x2524, + 0x2525, 0x2526, 0x2527, 0x2528, 0x2529, 0x252a, 0x252b, 0x252c, + 0x252d, 0x252e, 0x252f, 0x2530, 0x2531, 0x2532, 0x2533, 0x2534, + 0x2535, 0x2536, 0x2537, 0x2538, 0x2539, 0x253a, 0x253b, 0x253c, + 0x253d, 0x253e, 0x253f, 0x2540, 0x2541, 0x2542, 0x2543, 0x2544, + 0x2545, 0x2546, 0x2547, 0x2548, 0x2549, 0x254a, 0x254b, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0xaa */ + 0x72dc, 0x72dd, 0x72df, 0x72e2, 0x72e3, 0x72e4, 0x72e5, 0x72e6, + 0x72e7, 0x72ea, 0x72eb, 0x72f5, 0x72f6, 0x72f9, 0x72fd, 0x72fe, + 0x72ff, 0x7300, 0x7302, 0x7304, 0x7305, 0x7306, 0x7307, 0x7308, + 0x7309, 0x730b, 0x730c, 0x730d, 0x730f, 0x7310, 0x7311, 0x7312, + 0x7314, 0x7318, 0x7319, 0x731a, 0x731f, 0x7320, 0x7323, 0x7324, + 0x7326, 0x7327, 0x7328, 0x732d, 0x732f, 0x7330, 0x7332, 0x7333, + 0x7335, 0x7336, 0x733a, 0x733b, 0x733c, 0x733d, 0x7340, 0x7341, + 0x7342, 0x7343, 0x7344, 0x7345, 0x7346, 0x7347, 0x7348, 0x7349, + 0x734a, 0x734b, 0x734c, 0x734e, 0x734f, 0x7351, 0x7353, 0x7354, + 0x7355, 0x7356, 0x7358, 0x7359, 0x735a, 0x735b, 0x735c, 0x735d, + 0x735e, 0x735f, 0x7361, 0x7362, 0x7363, 0x7364, 0x7365, 0x7366, + 0x7367, 0x7368, 0x7369, 0x736a, 0x736b, 0x736e, 0x7370, 0x7371, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0xab */ + 0x7372, 0x7373, 0x7374, 0x7375, 0x7376, 0x7377, 0x7378, 0x7379, + 0x737a, 0x737b, 0x737c, 0x737d, 0x737f, 0x7380, 0x7381, 0x7382, + 0x7383, 0x7385, 0x7386, 0x7388, 0x738a, 0x738c, 0x738d, 0x738f, + 0x7390, 0x7392, 0x7393, 0x7394, 0x7395, 0x7397, 0x7398, 0x7399, + 0x739a, 0x739c, 0x739d, 0x739e, 0x73a0, 0x73a1, 0x73a3, 0x73a4, + 0x73a5, 0x73a6, 0x73a7, 0x73a8, 0x73aa, 0x73ac, 0x73ad, 0x73b1, + 0x73b4, 0x73b5, 0x73b6, 0x73b8, 0x73b9, 0x73bc, 0x73bd, 0x73be, + 0x73bf, 0x73c1, 0x73c3, 0x73c4, 0x73c5, 0x73c6, 0x73c7, 0x73cb, + 0x73cc, 0x73ce, 0x73d2, 0x73d3, 0x73d4, 0x73d5, 0x73d6, 0x73d7, + 0x73d8, 0x73da, 0x73db, 0x73dc, 0x73dd, 0x73df, 0x73e1, 0x73e2, + 0x73e3, 0x73e4, 0x73e6, 0x73e8, 0x73ea, 0x73eb, 0x73ec, 0x73ee, + 0x73ef, 0x73f0, 0x73f1, 0x73f3, 0x73f4, 0x73f5, 0x73f6, 0x73f7, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0xac */ + 0x73f8, 0x73f9, 0x73fa, 0x73fb, 0x73fc, 0x73fd, 0x73fe, 0x73ff, + 0x7400, 0x7401, 0x7402, 0x7404, 0x7407, 0x7408, 0x740b, 0x740c, + 0x740d, 0x740e, 0x7411, 0x7412, 0x7413, 0x7414, 0x7415, 0x7416, + 0x7417, 0x7418, 0x7419, 0x741c, 0x741d, 0x741e, 0x741f, 0x7420, + 0x7421, 0x7423, 0x7424, 0x7427, 0x7429, 0x742b, 0x742d, 0x742f, + 0x7431, 0x7432, 0x7437, 0x7438, 0x7439, 0x743a, 0x743b, 0x743d, + 0x743e, 0x743f, 0x7440, 0x7442, 0x7443, 0x7444, 0x7445, 0x7446, + 0x7447, 0x7448, 0x7449, 0x744a, 0x744b, 0x744c, 0x744d, 0x744e, + 0x744f, 0x7450, 0x7451, 0x7452, 0x7453, 0x7454, 0x7456, 0x7458, + 0x745d, 0x7460, 0x7461, 0x7462, 0x7463, 0x7464, 0x7465, 0x7466, + 0x7467, 0x7468, 0x7469, 0x746a, 0x746b, 0x746c, 0x746e, 0x746f, + 0x7471, 0x7472, 0x7473, 0x7474, 0x7475, 0x7478, 0x7479, 0x747a, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0xad */ + 0x747b, 0x747c, 0x747d, 0x747f, 0x7482, 0x7484, 0x7485, 0x7486, + 0x7488, 0x7489, 0x748a, 0x748c, 0x748d, 0x748f, 0x7491, 0x7492, + 0x7493, 0x7494, 0x7495, 0x7496, 0x7497, 0x7498, 0x7499, 0x749a, + 0x749b, 0x749d, 0x749f, 0x74a0, 0x74a1, 0x74a2, 0x74a3, 0x74a4, + 0x74a5, 0x74a6, 0x74aa, 0x74ab, 0x74ac, 0x74ad, 0x74ae, 0x74af, + 0x74b0, 0x74b1, 0x74b2, 0x74b3, 0x74b4, 0x74b5, 0x74b6, 0x74b7, + 0x74b8, 0x74b9, 0x74bb, 0x74bc, 0x74bd, 0x74be, 0x74bf, 0x74c0, + 0x74c1, 0x74c2, 0x74c3, 0x74c4, 0x74c5, 0x74c6, 0x74c7, 0x74c8, + 0x74c9, 0x74ca, 0x74cb, 0x74cc, 0x74cd, 0x74ce, 0x74cf, 0x74d0, + 0x74d1, 0x74d3, 0x74d4, 0x74d5, 0x74d6, 0x74d7, 0x74d8, 0x74d9, + 0x74da, 0x74db, 0x74dd, 0x74df, 0x74e1, 0x74e5, 0x74e7, 0x74e8, + 0x74e9, 0x74ea, 0x74eb, 0x74ec, 0x74ed, 0x74f0, 0x74f1, 0x74f2, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0xae */ + 0x74f3, 0x74f5, 0x74f8, 0x74f9, 0x74fa, 0x74fb, 0x74fc, 0x74fd, + 0x74fe, 0x7500, 0x7501, 0x7502, 0x7503, 0x7505, 0x7506, 0x7507, + 0x7508, 0x7509, 0x750a, 0x750b, 0x750c, 0x750e, 0x7510, 0x7512, + 0x7514, 0x7515, 0x7516, 0x7517, 0x751b, 0x751d, 0x751e, 0x7520, + 0x7521, 0x7522, 0x7523, 0x7524, 0x7526, 0x7527, 0x752a, 0x752e, + 0x7534, 0x7536, 0x7539, 0x753c, 0x753d, 0x753f, 0x7541, 0x7542, + 0x7543, 0x7544, 0x7546, 0x7547, 0x7549, 0x754a, 0x754d, 0x7550, + 0x7551, 0x7552, 0x7553, 0x7555, 0x7556, 0x7557, 0x7558, 0x755d, + 0x755e, 0x755f, 0x7560, 0x7561, 0x7562, 0x7563, 0x7564, 0x7567, + 0x7568, 0x7569, 0x756b, 0x756c, 0x756d, 0x756e, 0x756f, 0x7570, + 0x7571, 0x7573, 0x7575, 0x7576, 0x7577, 0x757a, 0x757b, 0x757c, + 0x757d, 0x757e, 0x7580, 0x7581, 0x7582, 0x7584, 0x7585, 0x7587, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0xaf */ + 0x7588, 0x7589, 0x758a, 0x758c, 0x758d, 0x758e, 0x7590, 0x7593, + 0x7595, 0x7598, 0x759b, 0x759c, 0x759e, 0x75a2, 0x75a6, 0x75a7, + 0x75a8, 0x75a9, 0x75aa, 0x75ad, 0x75b6, 0x75b7, 0x75ba, 0x75bb, + 0x75bf, 0x75c0, 0x75c1, 0x75c6, 0x75cb, 0x75cc, 0x75ce, 0x75cf, + 0x75d0, 0x75d1, 0x75d3, 0x75d7, 0x75d9, 0x75da, 0x75dc, 0x75dd, + 0x75df, 0x75e0, 0x75e1, 0x75e5, 0x75e9, 0x75ec, 0x75ed, 0x75ee, + 0x75ef, 0x75f2, 0x75f3, 0x75f5, 0x75f6, 0x75f7, 0x75f8, 0x75fa, + 0x75fb, 0x75fd, 0x75fe, 0x7602, 0x7604, 0x7606, 0x7607, 0x7608, + 0x7609, 0x760b, 0x760d, 0x760e, 0x760f, 0x7611, 0x7612, 0x7613, + 0x7614, 0x7616, 0x761a, 0x761c, 0x761d, 0x761e, 0x7621, 0x7623, + 0x7627, 0x7628, 0x762c, 0x762e, 0x762f, 0x7631, 0x7632, 0x7636, + 0x7637, 0x7639, 0x763a, 0x763b, 0x763d, 0x7641, 0x7642, 0x7644, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0xb0 */ + 0x7645, 0x7646, 0x7647, 0x7648, 0x7649, 0x764a, 0x764b, 0x764e, + 0x764f, 0x7650, 0x7651, 0x7652, 0x7653, 0x7655, 0x7657, 0x7658, + 0x7659, 0x765a, 0x765b, 0x765d, 0x765f, 0x7660, 0x7661, 0x7662, + 0x7664, 0x7665, 0x7666, 0x7667, 0x7668, 0x7669, 0x766a, 0x766c, + 0x766d, 0x766e, 0x7670, 0x7671, 0x7672, 0x7673, 0x7674, 0x7675, + 0x7676, 0x7677, 0x7679, 0x767a, 0x767c, 0x767f, 0x7680, 0x7681, + 0x7683, 0x7685, 0x7689, 0x768a, 0x768c, 0x768d, 0x768f, 0x7690, + 0x7692, 0x7694, 0x7695, 0x7697, 0x7698, 0x769a, 0x769b, 0x769c, + 0x769d, 0x769e, 0x769f, 0x76a0, 0x76a1, 0x76a2, 0x76a3, 0x76a5, + 0x76a6, 0x76a7, 0x76a8, 0x76a9, 0x76aa, 0x76ab, 0x76ac, 0x76ad, + 0x76af, 0x76b0, 0x76b3, 0x76b5, 0x76b6, 0x76b7, 0x76b8, 0x76b9, + 0x76ba, 0x76bb, 0x76bc, 0x76bd, 0x76be, 0x76c0, 0x76c1, 0x76c3, + 0x554a, 0x963f, 0x57c3, 0x6328, 0x54ce, 0x5509, 0x54c0, 0x7691, + 0x764c, 0x853c, 0x77ee, 0x827e, 0x788d, 0x7231, 0x9698, 0x978d, + 0x6c28, 0x5b89, 0x4ffa, 0x6309, 0x6697, 0x5cb8, 0x80fa, 0x6848, + 0x80ae, 0x6602, 0x76ce, 0x51f9, 0x6556, 0x71ac, 0x7ff1, 0x8884, + 0x50b2, 0x5965, 0x61ca, 0x6fb3, 0x82ad, 0x634c, 0x6252, 0x53ed, + 0x5427, 0x7b06, 0x516b, 0x75a4, 0x5df4, 0x62d4, 0x8dcb, 0x9776, + 0x628a, 0x8019, 0x575d, 0x9738, 0x7f62, 0x7238, 0x767d, 0x67cf, + 0x767e, 0x6446, 0x4f70, 0x8d25, 0x62dc, 0x7a17, 0x6591, 0x73ed, + 0x642c, 0x6273, 0x822c, 0x9881, 0x677f, 0x7248, 0x626e, 0x62cc, + 0x4f34, 0x74e3, 0x534a, 0x529e, 0x7eca, 0x90a6, 0x5e2e, 0x6886, + 0x699c, 0x8180, 0x7ed1, 0x68d2, 0x78c5, 0x868c, 0x9551, 0x508d, + 0x8c24, 0x82de, 0x80de, 0x5305, 0x8912, 0x5265, + /* 0xb1 */ + 0x76c4, 0x76c7, 0x76c9, 0x76cb, 0x76cc, 0x76d3, 0x76d5, 0x76d9, + 0x76da, 0x76dc, 0x76dd, 0x76de, 0x76e0, 0x76e1, 0x76e2, 0x76e3, + 0x76e4, 0x76e6, 0x76e7, 0x76e8, 0x76e9, 0x76ea, 0x76eb, 0x76ec, + 0x76ed, 0x76f0, 0x76f3, 0x76f5, 0x76f6, 0x76f7, 0x76fa, 0x76fb, + 0x76fd, 0x76ff, 0x7700, 0x7702, 0x7703, 0x7705, 0x7706, 0x770a, + 0x770c, 0x770e, 0x770f, 0x7710, 0x7711, 0x7712, 0x7713, 0x7714, + 0x7715, 0x7716, 0x7717, 0x7718, 0x771b, 0x771c, 0x771d, 0x771e, + 0x7721, 0x7723, 0x7724, 0x7725, 0x7727, 0x772a, 0x772b, 0x772c, + 0x772e, 0x7730, 0x7731, 0x7732, 0x7733, 0x7734, 0x7739, 0x773b, + 0x773d, 0x773e, 0x773f, 0x7742, 0x7744, 0x7745, 0x7746, 0x7748, + 0x7749, 0x774a, 0x774b, 0x774c, 0x774d, 0x774e, 0x774f, 0x7752, + 0x7753, 0x7754, 0x7755, 0x7756, 0x7757, 0x7758, 0x7759, 0x775c, + 0x8584, 0x96f9, 0x4fdd, 0x5821, 0x9971, 0x5b9d, 0x62b1, 0x62a5, + 0x66b4, 0x8c79, 0x9c8d, 0x7206, 0x676f, 0x7891, 0x60b2, 0x5351, + 0x5317, 0x8f88, 0x80cc, 0x8d1d, 0x94a1, 0x500d, 0x72c8, 0x5907, + 0x60eb, 0x7119, 0x88ab, 0x5954, 0x82ef, 0x672c, 0x7b28, 0x5d29, + 0x7ef7, 0x752d, 0x6cf5, 0x8e66, 0x8ff8, 0x903c, 0x9f3b, 0x6bd4, + 0x9119, 0x7b14, 0x5f7c, 0x78a7, 0x84d6, 0x853d, 0x6bd5, 0x6bd9, + 0x6bd6, 0x5e01, 0x5e87, 0x75f9, 0x95ed, 0x655d, 0x5f0a, 0x5fc5, + 0x8f9f, 0x58c1, 0x81c2, 0x907f, 0x965b, 0x97ad, 0x8fb9, 0x7f16, + 0x8d2c, 0x6241, 0x4fbf, 0x53d8, 0x535e, 0x8fa8, 0x8fa9, 0x8fab, + 0x904d, 0x6807, 0x5f6a, 0x8198, 0x8868, 0x9cd6, 0x618b, 0x522b, + 0x762a, 0x5f6c, 0x658c, 0x6fd2, 0x6ee8, 0x5bbe, 0x6448, 0x5175, + 0x51b0, 0x67c4, 0x4e19, 0x79c9, 0x997c, 0x70b3, + /* 0xb2 */ + 0x775d, 0x775e, 0x775f, 0x7760, 0x7764, 0x7767, 0x7769, 0x776a, + 0x776d, 0x776e, 0x776f, 0x7770, 0x7771, 0x7772, 0x7773, 0x7774, + 0x7775, 0x7776, 0x7777, 0x7778, 0x777a, 0x777b, 0x777c, 0x7781, + 0x7782, 0x7783, 0x7786, 0x7787, 0x7788, 0x7789, 0x778a, 0x778b, + 0x778f, 0x7790, 0x7793, 0x7794, 0x7795, 0x7796, 0x7797, 0x7798, + 0x7799, 0x779a, 0x779b, 0x779c, 0x779d, 0x779e, 0x77a1, 0x77a3, + 0x77a4, 0x77a6, 0x77a8, 0x77ab, 0x77ad, 0x77ae, 0x77af, 0x77b1, + 0x77b2, 0x77b4, 0x77b6, 0x77b7, 0x77b8, 0x77b9, 0x77ba, 0x77bc, + 0x77be, 0x77c0, 0x77c1, 0x77c2, 0x77c3, 0x77c4, 0x77c5, 0x77c6, + 0x77c7, 0x77c8, 0x77c9, 0x77ca, 0x77cb, 0x77cc, 0x77ce, 0x77cf, + 0x77d0, 0x77d1, 0x77d2, 0x77d3, 0x77d4, 0x77d5, 0x77d6, 0x77d8, + 0x77d9, 0x77da, 0x77dd, 0x77de, 0x77df, 0x77e0, 0x77e1, 0x77e4, + 0x75c5, 0x5e76, 0x73bb, 0x83e0, 0x64ad, 0x62e8, 0x94b5, 0x6ce2, + 0x535a, 0x52c3, 0x640f, 0x94c2, 0x7b94, 0x4f2f, 0x5e1b, 0x8236, + 0x8116, 0x818a, 0x6e24, 0x6cca, 0x9a73, 0x6355, 0x535c, 0x54fa, + 0x8865, 0x57e0, 0x4e0d, 0x5e03, 0x6b65, 0x7c3f, 0x90e8, 0x6016, + 0x64e6, 0x731c, 0x88c1, 0x6750, 0x624d, 0x8d22, 0x776c, 0x8e29, + 0x91c7, 0x5f69, 0x83dc, 0x8521, 0x9910, 0x53c2, 0x8695, 0x6b8b, + 0x60ed, 0x60e8, 0x707f, 0x82cd, 0x8231, 0x4ed3, 0x6ca7, 0x85cf, + 0x64cd, 0x7cd9, 0x69fd, 0x66f9, 0x8349, 0x5395, 0x7b56, 0x4fa7, + 0x518c, 0x6d4b, 0x5c42, 0x8e6d, 0x63d2, 0x53c9, 0x832c, 0x8336, + 0x67e5, 0x78b4, 0x643d, 0x5bdf, 0x5c94, 0x5dee, 0x8be7, 0x62c6, + 0x67f4, 0x8c7a, 0x6400, 0x63ba, 0x8749, 0x998b, 0x8c17, 0x7f20, + 0x94f2, 0x4ea7, 0x9610, 0x98a4, 0x660c, 0x7316, + /* 0xb3 */ + 0x77e6, 0x77e8, 0x77ea, 0x77ef, 0x77f0, 0x77f1, 0x77f2, 0x77f4, + 0x77f5, 0x77f7, 0x77f9, 0x77fa, 0x77fb, 0x77fc, 0x7803, 0x7804, + 0x7805, 0x7806, 0x7807, 0x7808, 0x780a, 0x780b, 0x780e, 0x780f, + 0x7810, 0x7813, 0x7815, 0x7819, 0x781b, 0x781e, 0x7820, 0x7821, + 0x7822, 0x7824, 0x7828, 0x782a, 0x782b, 0x782e, 0x782f, 0x7831, + 0x7832, 0x7833, 0x7835, 0x7836, 0x783d, 0x783f, 0x7841, 0x7842, + 0x7843, 0x7844, 0x7846, 0x7848, 0x7849, 0x784a, 0x784b, 0x784d, + 0x784f, 0x7851, 0x7853, 0x7854, 0x7858, 0x7859, 0x785a, 0x785b, + 0x785c, 0x785e, 0x785f, 0x7860, 0x7861, 0x7862, 0x7863, 0x7864, + 0x7865, 0x7866, 0x7867, 0x7868, 0x7869, 0x786f, 0x7870, 0x7871, + 0x7872, 0x7873, 0x7874, 0x7875, 0x7876, 0x7878, 0x7879, 0x787a, + 0x787b, 0x787d, 0x787e, 0x787f, 0x7880, 0x7881, 0x7882, 0x7883, + 0x573a, 0x5c1d, 0x5e38, 0x957f, 0x507f, 0x80a0, 0x5382, 0x655e, + 0x7545, 0x5531, 0x5021, 0x8d85, 0x6284, 0x949e, 0x671d, 0x5632, + 0x6f6e, 0x5de2, 0x5435, 0x7092, 0x8f66, 0x626f, 0x64a4, 0x63a3, + 0x5f7b, 0x6f88, 0x90f4, 0x81e3, 0x8fb0, 0x5c18, 0x6668, 0x5ff1, + 0x6c89, 0x9648, 0x8d81, 0x886c, 0x6491, 0x79f0, 0x57ce, 0x6a59, + 0x6210, 0x5448, 0x4e58, 0x7a0b, 0x60e9, 0x6f84, 0x8bda, 0x627f, + 0x901e, 0x9a8b, 0x79e4, 0x5403, 0x75f4, 0x6301, 0x5319, 0x6c60, + 0x8fdf, 0x5f1b, 0x9a70, 0x803b, 0x9f7f, 0x4f88, 0x5c3a, 0x8d64, + 0x7fc5, 0x65a5, 0x70bd, 0x5145, 0x51b2, 0x866b, 0x5d07, 0x5ba0, + 0x62bd, 0x916c, 0x7574, 0x8e0c, 0x7a20, 0x6101, 0x7b79, 0x4ec7, + 0x7ef8, 0x7785, 0x4e11, 0x81ed, 0x521d, 0x51fa, 0x6a71, 0x53a8, + 0x8e87, 0x9504, 0x96cf, 0x6ec1, 0x9664, 0x695a, + /* 0xb4 */ + 0x7884, 0x7885, 0x7886, 0x7888, 0x788a, 0x788b, 0x788f, 0x7890, + 0x7892, 0x7894, 0x7895, 0x7896, 0x7899, 0x789d, 0x789e, 0x78a0, + 0x78a2, 0x78a4, 0x78a6, 0x78a8, 0x78a9, 0x78aa, 0x78ab, 0x78ac, + 0x78ad, 0x78ae, 0x78af, 0x78b5, 0x78b6, 0x78b7, 0x78b8, 0x78ba, + 0x78bb, 0x78bc, 0x78bd, 0x78bf, 0x78c0, 0x78c2, 0x78c3, 0x78c4, + 0x78c6, 0x78c7, 0x78c8, 0x78cc, 0x78cd, 0x78ce, 0x78cf, 0x78d1, + 0x78d2, 0x78d3, 0x78d6, 0x78d7, 0x78d8, 0x78da, 0x78db, 0x78dc, + 0x78dd, 0x78de, 0x78df, 0x78e0, 0x78e1, 0x78e2, 0x78e3, 0x78e4, + 0x78e5, 0x78e6, 0x78e7, 0x78e9, 0x78ea, 0x78eb, 0x78ed, 0x78ee, + 0x78ef, 0x78f0, 0x78f1, 0x78f3, 0x78f5, 0x78f6, 0x78f8, 0x78f9, + 0x78fb, 0x78fc, 0x78fd, 0x78fe, 0x78ff, 0x7900, 0x7902, 0x7903, + 0x7904, 0x7906, 0x7907, 0x7908, 0x7909, 0x790a, 0x790b, 0x790c, + 0x7840, 0x50a8, 0x77d7, 0x6410, 0x89e6, 0x5904, 0x63e3, 0x5ddd, + 0x7a7f, 0x693d, 0x4f20, 0x8239, 0x5598, 0x4e32, 0x75ae, 0x7a97, + 0x5e62, 0x5e8a, 0x95ef, 0x521b, 0x5439, 0x708a, 0x6376, 0x9524, + 0x5782, 0x6625, 0x693f, 0x9187, 0x5507, 0x6df3, 0x7eaf, 0x8822, + 0x6233, 0x7ef0, 0x75b5, 0x8328, 0x78c1, 0x96cc, 0x8f9e, 0x6148, + 0x74f7, 0x8bcd, 0x6b64, 0x523a, 0x8d50, 0x6b21, 0x806a, 0x8471, + 0x56f1, 0x5306, 0x4ece, 0x4e1b, 0x51d1, 0x7c97, 0x918b, 0x7c07, + 0x4fc3, 0x8e7f, 0x7be1, 0x7a9c, 0x6467, 0x5d14, 0x50ac, 0x8106, + 0x7601, 0x7cb9, 0x6dec, 0x7fe0, 0x6751, 0x5b58, 0x5bf8, 0x78cb, + 0x64ae, 0x6413, 0x63aa, 0x632b, 0x9519, 0x642d, 0x8fbe, 0x7b54, + 0x7629, 0x6253, 0x5927, 0x5446, 0x6b79, 0x50a3, 0x6234, 0x5e26, + 0x6b86, 0x4ee3, 0x8d37, 0x888b, 0x5f85, 0x902e, + /* 0xb5 */ + 0x790d, 0x790e, 0x790f, 0x7910, 0x7911, 0x7912, 0x7914, 0x7915, + 0x7916, 0x7917, 0x7918, 0x7919, 0x791a, 0x791b, 0x791c, 0x791d, + 0x791f, 0x7920, 0x7921, 0x7922, 0x7923, 0x7925, 0x7926, 0x7927, + 0x7928, 0x7929, 0x792a, 0x792b, 0x792c, 0x792d, 0x792e, 0x792f, + 0x7930, 0x7931, 0x7932, 0x7933, 0x7935, 0x7936, 0x7937, 0x7938, + 0x7939, 0x793d, 0x793f, 0x7942, 0x7943, 0x7944, 0x7945, 0x7947, + 0x794a, 0x794b, 0x794c, 0x794d, 0x794e, 0x794f, 0x7950, 0x7951, + 0x7952, 0x7954, 0x7955, 0x7958, 0x7959, 0x7961, 0x7963, 0x7964, + 0x7966, 0x7969, 0x796a, 0x796b, 0x796c, 0x796e, 0x7970, 0x7971, + 0x7972, 0x7973, 0x7974, 0x7975, 0x7976, 0x7979, 0x797b, 0x797c, + 0x797d, 0x797e, 0x797f, 0x7982, 0x7983, 0x7986, 0x7987, 0x7988, + 0x7989, 0x798b, 0x798c, 0x798d, 0x798e, 0x7990, 0x7991, 0x7992, + 0x6020, 0x803d, 0x62c5, 0x4e39, 0x5355, 0x90f8, 0x63b8, 0x80c6, + 0x65e6, 0x6c2e, 0x4f46, 0x60ee, 0x6de1, 0x8bde, 0x5f39, 0x86cb, + 0x5f53, 0x6321, 0x515a, 0x8361, 0x6863, 0x5200, 0x6363, 0x8e48, + 0x5012, 0x5c9b, 0x7977, 0x5bfc, 0x5230, 0x7a3b, 0x60bc, 0x9053, + 0x76d7, 0x5fb7, 0x5f97, 0x7684, 0x8e6c, 0x706f, 0x767b, 0x7b49, + 0x77aa, 0x51f3, 0x9093, 0x5824, 0x4f4e, 0x6ef4, 0x8fea, 0x654c, + 0x7b1b, 0x72c4, 0x6da4, 0x7fdf, 0x5ae1, 0x62b5, 0x5e95, 0x5730, + 0x8482, 0x7b2c, 0x5e1d, 0x5f1f, 0x9012, 0x7f14, 0x98a0, 0x6382, + 0x6ec7, 0x7898, 0x70b9, 0x5178, 0x975b, 0x57ab, 0x7535, 0x4f43, + 0x7538, 0x5e97, 0x60e6, 0x5960, 0x6dc0, 0x6bbf, 0x7889, 0x53fc, + 0x96d5, 0x51cb, 0x5201, 0x6389, 0x540a, 0x9493, 0x8c03, 0x8dcc, + 0x7239, 0x789f, 0x8776, 0x8fed, 0x8c0d, 0x53e0, + /* 0xb6 */ + 0x7993, 0x7994, 0x7995, 0x7996, 0x7997, 0x7998, 0x7999, 0x799b, + 0x799c, 0x799d, 0x799e, 0x799f, 0x79a0, 0x79a1, 0x79a2, 0x79a3, + 0x79a4, 0x79a5, 0x79a6, 0x79a8, 0x79a9, 0x79aa, 0x79ab, 0x79ac, + 0x79ad, 0x79ae, 0x79af, 0x79b0, 0x79b1, 0x79b2, 0x79b4, 0x79b5, + 0x79b6, 0x79b7, 0x79b8, 0x79bc, 0x79bf, 0x79c2, 0x79c4, 0x79c5, + 0x79c7, 0x79c8, 0x79ca, 0x79cc, 0x79ce, 0x79cf, 0x79d0, 0x79d3, + 0x79d4, 0x79d6, 0x79d7, 0x79d9, 0x79da, 0x79db, 0x79dc, 0x79dd, + 0x79de, 0x79e0, 0x79e1, 0x79e2, 0x79e5, 0x79e8, 0x79ea, 0x79ec, + 0x79ee, 0x79f1, 0x79f2, 0x79f3, 0x79f4, 0x79f5, 0x79f6, 0x79f7, + 0x79f9, 0x79fa, 0x79fc, 0x79fe, 0x79ff, 0x7a01, 0x7a04, 0x7a05, + 0x7a07, 0x7a08, 0x7a09, 0x7a0a, 0x7a0c, 0x7a0f, 0x7a10, 0x7a11, + 0x7a12, 0x7a13, 0x7a15, 0x7a16, 0x7a18, 0x7a19, 0x7a1b, 0x7a1c, + 0x4e01, 0x76ef, 0x53ee, 0x9489, 0x9876, 0x9f0e, 0x952d, 0x5b9a, + 0x8ba2, 0x4e22, 0x4e1c, 0x51ac, 0x8463, 0x61c2, 0x52a8, 0x680b, + 0x4f97, 0x606b, 0x51bb, 0x6d1e, 0x515c, 0x6296, 0x6597, 0x9661, + 0x8c46, 0x9017, 0x75d8, 0x90fd, 0x7763, 0x6bd2, 0x728a, 0x72ec, + 0x8bfb, 0x5835, 0x7779, 0x8d4c, 0x675c, 0x9540, 0x809a, 0x5ea6, + 0x6e21, 0x5992, 0x7aef, 0x77ed, 0x953b, 0x6bb5, 0x65ad, 0x7f0e, + 0x5806, 0x5151, 0x961f, 0x5bf9, 0x58a9, 0x5428, 0x8e72, 0x6566, + 0x987f, 0x56e4, 0x949d, 0x76fe, 0x9041, 0x6387, 0x54c6, 0x591a, + 0x593a, 0x579b, 0x8eb2, 0x6735, 0x8dfa, 0x8235, 0x5241, 0x60f0, + 0x5815, 0x86fe, 0x5ce8, 0x9e45, 0x4fc4, 0x989d, 0x8bb9, 0x5a25, + 0x6076, 0x5384, 0x627c, 0x904f, 0x9102, 0x997f, 0x6069, 0x800c, + 0x513f, 0x8033, 0x5c14, 0x9975, 0x6d31, 0x4e8c, + /* 0xb7 */ + 0x7a1d, 0x7a1f, 0x7a21, 0x7a22, 0x7a24, 0x7a25, 0x7a26, 0x7a27, + 0x7a28, 0x7a29, 0x7a2a, 0x7a2b, 0x7a2c, 0x7a2d, 0x7a2e, 0x7a2f, + 0x7a30, 0x7a31, 0x7a32, 0x7a34, 0x7a35, 0x7a36, 0x7a38, 0x7a3a, + 0x7a3e, 0x7a40, 0x7a41, 0x7a42, 0x7a43, 0x7a44, 0x7a45, 0x7a47, + 0x7a48, 0x7a49, 0x7a4a, 0x7a4b, 0x7a4c, 0x7a4d, 0x7a4e, 0x7a4f, + 0x7a50, 0x7a52, 0x7a53, 0x7a54, 0x7a55, 0x7a56, 0x7a58, 0x7a59, + 0x7a5a, 0x7a5b, 0x7a5c, 0x7a5d, 0x7a5e, 0x7a5f, 0x7a60, 0x7a61, + 0x7a62, 0x7a63, 0x7a64, 0x7a65, 0x7a66, 0x7a67, 0x7a68, 0x7a69, + 0x7a6a, 0x7a6b, 0x7a6c, 0x7a6d, 0x7a6e, 0x7a6f, 0x7a71, 0x7a72, + 0x7a73, 0x7a75, 0x7a7b, 0x7a7c, 0x7a7d, 0x7a7e, 0x7a82, 0x7a85, + 0x7a87, 0x7a89, 0x7a8a, 0x7a8b, 0x7a8c, 0x7a8e, 0x7a8f, 0x7a90, + 0x7a93, 0x7a94, 0x7a99, 0x7a9a, 0x7a9b, 0x7a9e, 0x7aa1, 0x7aa2, + 0x8d30, 0x53d1, 0x7f5a, 0x7b4f, 0x4f10, 0x4e4f, 0x9600, 0x6cd5, + 0x73d0, 0x85e9, 0x5e06, 0x756a, 0x7ffb, 0x6a0a, 0x77fe, 0x9492, + 0x7e41, 0x51e1, 0x70e6, 0x53cd, 0x8fd4, 0x8303, 0x8d29, 0x72af, + 0x996d, 0x6cdb, 0x574a, 0x82b3, 0x65b9, 0x80aa, 0x623f, 0x9632, + 0x59a8, 0x4eff, 0x8bbf, 0x7eba, 0x653e, 0x83f2, 0x975e, 0x5561, + 0x98de, 0x80a5, 0x532a, 0x8bfd, 0x5420, 0x80ba, 0x5e9f, 0x6cb8, + 0x8d39, 0x82ac, 0x915a, 0x5429, 0x6c1b, 0x5206, 0x7eb7, 0x575f, + 0x711a, 0x6c7e, 0x7c89, 0x594b, 0x4efd, 0x5fff, 0x6124, 0x7caa, + 0x4e30, 0x5c01, 0x67ab, 0x8702, 0x5cf0, 0x950b, 0x98ce, 0x75af, + 0x70fd, 0x9022, 0x51af, 0x7f1d, 0x8bbd, 0x5949, 0x51e4, 0x4f5b, + 0x5426, 0x592b, 0x6577, 0x80a4, 0x5b75, 0x6276, 0x62c2, 0x8f90, + 0x5e45, 0x6c1f, 0x7b26, 0x4f0f, 0x4fd8, 0x670d, + /* 0xb8 */ + 0x7aa3, 0x7aa4, 0x7aa7, 0x7aa9, 0x7aaa, 0x7aab, 0x7aae, 0x7aaf, + 0x7ab0, 0x7ab1, 0x7ab2, 0x7ab4, 0x7ab5, 0x7ab6, 0x7ab7, 0x7ab8, + 0x7ab9, 0x7aba, 0x7abb, 0x7abc, 0x7abd, 0x7abe, 0x7ac0, 0x7ac1, + 0x7ac2, 0x7ac3, 0x7ac4, 0x7ac5, 0x7ac6, 0x7ac7, 0x7ac8, 0x7ac9, + 0x7aca, 0x7acc, 0x7acd, 0x7ace, 0x7acf, 0x7ad0, 0x7ad1, 0x7ad2, + 0x7ad3, 0x7ad4, 0x7ad5, 0x7ad7, 0x7ad8, 0x7ada, 0x7adb, 0x7adc, + 0x7add, 0x7ae1, 0x7ae2, 0x7ae4, 0x7ae7, 0x7ae8, 0x7ae9, 0x7aea, + 0x7aeb, 0x7aec, 0x7aee, 0x7af0, 0x7af1, 0x7af2, 0x7af3, 0x7af4, + 0x7af5, 0x7af6, 0x7af7, 0x7af8, 0x7afb, 0x7afc, 0x7afe, 0x7b00, + 0x7b01, 0x7b02, 0x7b05, 0x7b07, 0x7b09, 0x7b0c, 0x7b0d, 0x7b0e, + 0x7b10, 0x7b12, 0x7b13, 0x7b16, 0x7b17, 0x7b18, 0x7b1a, 0x7b1c, + 0x7b1d, 0x7b1f, 0x7b21, 0x7b22, 0x7b23, 0x7b27, 0x7b29, 0x7b2d, + 0x6d6e, 0x6daa, 0x798f, 0x88b1, 0x5f17, 0x752b, 0x629a, 0x8f85, + 0x4fef, 0x91dc, 0x65a7, 0x812f, 0x8151, 0x5e9c, 0x8150, 0x8d74, + 0x526f, 0x8986, 0x8d4b, 0x590d, 0x5085, 0x4ed8, 0x961c, 0x7236, + 0x8179, 0x8d1f, 0x5bcc, 0x8ba3, 0x9644, 0x5987, 0x7f1a, 0x5490, + 0x5676, 0x560e, 0x8be5, 0x6539, 0x6982, 0x9499, 0x76d6, 0x6e89, + 0x5e72, 0x7518, 0x6746, 0x67d1, 0x7aff, 0x809d, 0x8d76, 0x611f, + 0x79c6, 0x6562, 0x8d63, 0x5188, 0x521a, 0x94a2, 0x7f38, 0x809b, + 0x7eb2, 0x5c97, 0x6e2f, 0x6760, 0x7bd9, 0x768b, 0x9ad8, 0x818f, + 0x7f94, 0x7cd5, 0x641e, 0x9550, 0x7a3f, 0x544a, 0x54e5, 0x6b4c, + 0x6401, 0x6208, 0x9e3d, 0x80f3, 0x7599, 0x5272, 0x9769, 0x845b, + 0x683c, 0x86e4, 0x9601, 0x9694, 0x94ec, 0x4e2a, 0x5404, 0x7ed9, + 0x6839, 0x8ddf, 0x8015, 0x66f4, 0x5e9a, 0x7fb9, + /* 0xb9 */ + 0x7b2f, 0x7b30, 0x7b32, 0x7b34, 0x7b35, 0x7b36, 0x7b37, 0x7b39, + 0x7b3b, 0x7b3d, 0x7b3f, 0x7b40, 0x7b41, 0x7b42, 0x7b43, 0x7b44, + 0x7b46, 0x7b48, 0x7b4a, 0x7b4d, 0x7b4e, 0x7b53, 0x7b55, 0x7b57, + 0x7b59, 0x7b5c, 0x7b5e, 0x7b5f, 0x7b61, 0x7b63, 0x7b64, 0x7b65, + 0x7b66, 0x7b67, 0x7b68, 0x7b69, 0x7b6a, 0x7b6b, 0x7b6c, 0x7b6d, + 0x7b6f, 0x7b70, 0x7b73, 0x7b74, 0x7b76, 0x7b78, 0x7b7a, 0x7b7c, + 0x7b7d, 0x7b7f, 0x7b81, 0x7b82, 0x7b83, 0x7b84, 0x7b86, 0x7b87, + 0x7b88, 0x7b89, 0x7b8a, 0x7b8b, 0x7b8c, 0x7b8e, 0x7b8f, 0x7b91, + 0x7b92, 0x7b93, 0x7b96, 0x7b98, 0x7b99, 0x7b9a, 0x7b9b, 0x7b9e, + 0x7b9f, 0x7ba0, 0x7ba3, 0x7ba4, 0x7ba5, 0x7bae, 0x7baf, 0x7bb0, + 0x7bb2, 0x7bb3, 0x7bb5, 0x7bb6, 0x7bb7, 0x7bb9, 0x7bba, 0x7bbb, + 0x7bbc, 0x7bbd, 0x7bbe, 0x7bbf, 0x7bc0, 0x7bc2, 0x7bc3, 0x7bc4, + 0x57c2, 0x803f, 0x6897, 0x5de5, 0x653b, 0x529f, 0x606d, 0x9f9a, + 0x4f9b, 0x8eac, 0x516c, 0x5bab, 0x5f13, 0x5de9, 0x6c5e, 0x62f1, + 0x8d21, 0x5171, 0x94a9, 0x52fe, 0x6c9f, 0x82df, 0x72d7, 0x57a2, + 0x6784, 0x8d2d, 0x591f, 0x8f9c, 0x83c7, 0x5495, 0x7b8d, 0x4f30, + 0x6cbd, 0x5b64, 0x59d1, 0x9f13, 0x53e4, 0x86ca, 0x9aa8, 0x8c37, + 0x80a1, 0x6545, 0x987e, 0x56fa, 0x96c7, 0x522e, 0x74dc, 0x5250, + 0x5be1, 0x6302, 0x8902, 0x4e56, 0x62d0, 0x602a, 0x68fa, 0x5173, + 0x5b98, 0x51a0, 0x89c2, 0x7ba1, 0x9986, 0x7f50, 0x60ef, 0x704c, + 0x8d2f, 0x5149, 0x5e7f, 0x901b, 0x7470, 0x89c4, 0x572d, 0x7845, + 0x5f52, 0x9f9f, 0x95fa, 0x8f68, 0x9b3c, 0x8be1, 0x7678, 0x6842, + 0x67dc, 0x8dea, 0x8d35, 0x523d, 0x8f8a, 0x6eda, 0x68cd, 0x9505, + 0x90ed, 0x56fd, 0x679c, 0x88f9, 0x8fc7, 0x54c8, + /* 0xba */ + 0x7bc5, 0x7bc8, 0x7bc9, 0x7bca, 0x7bcb, 0x7bcd, 0x7bce, 0x7bcf, + 0x7bd0, 0x7bd2, 0x7bd4, 0x7bd5, 0x7bd6, 0x7bd7, 0x7bd8, 0x7bdb, + 0x7bdc, 0x7bde, 0x7bdf, 0x7be0, 0x7be2, 0x7be3, 0x7be4, 0x7be7, + 0x7be8, 0x7be9, 0x7beb, 0x7bec, 0x7bed, 0x7bef, 0x7bf0, 0x7bf2, + 0x7bf3, 0x7bf4, 0x7bf5, 0x7bf6, 0x7bf8, 0x7bf9, 0x7bfa, 0x7bfb, + 0x7bfd, 0x7bff, 0x7c00, 0x7c01, 0x7c02, 0x7c03, 0x7c04, 0x7c05, + 0x7c06, 0x7c08, 0x7c09, 0x7c0a, 0x7c0d, 0x7c0e, 0x7c10, 0x7c11, + 0x7c12, 0x7c13, 0x7c14, 0x7c15, 0x7c17, 0x7c18, 0x7c19, 0x7c1a, + 0x7c1b, 0x7c1c, 0x7c1d, 0x7c1e, 0x7c20, 0x7c21, 0x7c22, 0x7c23, + 0x7c24, 0x7c25, 0x7c28, 0x7c29, 0x7c2b, 0x7c2c, 0x7c2d, 0x7c2e, + 0x7c2f, 0x7c30, 0x7c31, 0x7c32, 0x7c33, 0x7c34, 0x7c35, 0x7c36, + 0x7c37, 0x7c39, 0x7c3a, 0x7c3b, 0x7c3c, 0x7c3d, 0x7c3e, 0x7c42, + 0x9ab8, 0x5b69, 0x6d77, 0x6c26, 0x4ea5, 0x5bb3, 0x9a87, 0x9163, + 0x61a8, 0x90af, 0x97e9, 0x542b, 0x6db5, 0x5bd2, 0x51fd, 0x558a, + 0x7f55, 0x7ff0, 0x64bc, 0x634d, 0x65f1, 0x61be, 0x608d, 0x710a, + 0x6c57, 0x6c49, 0x592f, 0x676d, 0x822a, 0x58d5, 0x568e, 0x8c6a, + 0x6beb, 0x90dd, 0x597d, 0x8017, 0x53f7, 0x6d69, 0x5475, 0x559d, + 0x8377, 0x83cf, 0x6838, 0x79be, 0x548c, 0x4f55, 0x5408, 0x76d2, + 0x8c89, 0x9602, 0x6cb3, 0x6db8, 0x8d6b, 0x8910, 0x9e64, 0x8d3a, + 0x563f, 0x9ed1, 0x75d5, 0x5f88, 0x72e0, 0x6068, 0x54fc, 0x4ea8, + 0x6a2a, 0x8861, 0x6052, 0x8f70, 0x54c4, 0x70d8, 0x8679, 0x9e3f, + 0x6d2a, 0x5b8f, 0x5f18, 0x7ea2, 0x5589, 0x4faf, 0x7334, 0x543c, + 0x539a, 0x5019, 0x540e, 0x547c, 0x4e4e, 0x5ffd, 0x745a, 0x58f6, + 0x846b, 0x80e1, 0x8774, 0x72d0, 0x7cca, 0x6e56, + /* 0xbb */ + 0x7c43, 0x7c44, 0x7c45, 0x7c46, 0x7c47, 0x7c48, 0x7c49, 0x7c4a, + 0x7c4b, 0x7c4c, 0x7c4e, 0x7c4f, 0x7c50, 0x7c51, 0x7c52, 0x7c53, + 0x7c54, 0x7c55, 0x7c56, 0x7c57, 0x7c58, 0x7c59, 0x7c5a, 0x7c5b, + 0x7c5c, 0x7c5d, 0x7c5e, 0x7c5f, 0x7c60, 0x7c61, 0x7c62, 0x7c63, + 0x7c64, 0x7c65, 0x7c66, 0x7c67, 0x7c68, 0x7c69, 0x7c6a, 0x7c6b, + 0x7c6c, 0x7c6d, 0x7c6e, 0x7c6f, 0x7c70, 0x7c71, 0x7c72, 0x7c75, + 0x7c76, 0x7c77, 0x7c78, 0x7c79, 0x7c7a, 0x7c7e, 0x7c7f, 0x7c80, + 0x7c81, 0x7c82, 0x7c83, 0x7c84, 0x7c85, 0x7c86, 0x7c87, 0x7c88, + 0x7c8a, 0x7c8b, 0x7c8c, 0x7c8d, 0x7c8e, 0x7c8f, 0x7c90, 0x7c93, + 0x7c94, 0x7c96, 0x7c99, 0x7c9a, 0x7c9b, 0x7ca0, 0x7ca1, 0x7ca3, + 0x7ca6, 0x7ca7, 0x7ca8, 0x7ca9, 0x7cab, 0x7cac, 0x7cad, 0x7caf, + 0x7cb0, 0x7cb4, 0x7cb5, 0x7cb6, 0x7cb7, 0x7cb8, 0x7cba, 0x7cbb, + 0x5f27, 0x864e, 0x552c, 0x62a4, 0x4e92, 0x6caa, 0x6237, 0x82b1, + 0x54d7, 0x534e, 0x733e, 0x6ed1, 0x753b, 0x5212, 0x5316, 0x8bdd, + 0x69d0, 0x5f8a, 0x6000, 0x6dee, 0x574f, 0x6b22, 0x73af, 0x6853, + 0x8fd8, 0x7f13, 0x6362, 0x60a3, 0x5524, 0x75ea, 0x8c62, 0x7115, + 0x6da3, 0x5ba6, 0x5e7b, 0x8352, 0x614c, 0x9ec4, 0x78fa, 0x8757, + 0x7c27, 0x7687, 0x51f0, 0x60f6, 0x714c, 0x6643, 0x5e4c, 0x604d, + 0x8c0e, 0x7070, 0x6325, 0x8f89, 0x5fbd, 0x6062, 0x86d4, 0x56de, + 0x6bc1, 0x6094, 0x6167, 0x5349, 0x60e0, 0x6666, 0x8d3f, 0x79fd, + 0x4f1a, 0x70e9, 0x6c47, 0x8bb3, 0x8bf2, 0x7ed8, 0x8364, 0x660f, + 0x5a5a, 0x9b42, 0x6d51, 0x6df7, 0x8c41, 0x6d3b, 0x4f19, 0x706b, + 0x83b7, 0x6216, 0x60d1, 0x970d, 0x8d27, 0x7978, 0x51fb, 0x573e, + 0x57fa, 0x673a, 0x7578, 0x7a3d, 0x79ef, 0x7b95, + /* 0xbc */ + 0x7cbf, 0x7cc0, 0x7cc2, 0x7cc3, 0x7cc4, 0x7cc6, 0x7cc9, 0x7ccb, + 0x7cce, 0x7ccf, 0x7cd0, 0x7cd1, 0x7cd2, 0x7cd3, 0x7cd4, 0x7cd8, + 0x7cda, 0x7cdb, 0x7cdd, 0x7cde, 0x7ce1, 0x7ce2, 0x7ce3, 0x7ce4, + 0x7ce5, 0x7ce6, 0x7ce7, 0x7ce9, 0x7cea, 0x7ceb, 0x7cec, 0x7ced, + 0x7cee, 0x7cf0, 0x7cf1, 0x7cf2, 0x7cf3, 0x7cf4, 0x7cf5, 0x7cf6, + 0x7cf7, 0x7cf9, 0x7cfa, 0x7cfc, 0x7cfd, 0x7cfe, 0x7cff, 0x7d00, + 0x7d01, 0x7d02, 0x7d03, 0x7d04, 0x7d05, 0x7d06, 0x7d07, 0x7d08, + 0x7d09, 0x7d0b, 0x7d0c, 0x7d0d, 0x7d0e, 0x7d0f, 0x7d10, 0x7d11, + 0x7d12, 0x7d13, 0x7d14, 0x7d15, 0x7d16, 0x7d17, 0x7d18, 0x7d19, + 0x7d1a, 0x7d1b, 0x7d1c, 0x7d1d, 0x7d1e, 0x7d1f, 0x7d21, 0x7d23, + 0x7d24, 0x7d25, 0x7d26, 0x7d28, 0x7d29, 0x7d2a, 0x7d2c, 0x7d2d, + 0x7d2e, 0x7d30, 0x7d31, 0x7d32, 0x7d33, 0x7d34, 0x7d35, 0x7d36, + 0x808c, 0x9965, 0x8ff9, 0x6fc0, 0x8ba5, 0x9e21, 0x59ec, 0x7ee9, + 0x7f09, 0x5409, 0x6781, 0x68d8, 0x8f91, 0x7c4d, 0x96c6, 0x53ca, + 0x6025, 0x75be, 0x6c72, 0x5373, 0x5ac9, 0x7ea7, 0x6324, 0x51e0, + 0x810a, 0x5df1, 0x84df, 0x6280, 0x5180, 0x5b63, 0x4f0e, 0x796d, + 0x5242, 0x60b8, 0x6d4e, 0x5bc4, 0x5bc2, 0x8ba1, 0x8bb0, 0x65e2, + 0x5fcc, 0x9645, 0x5993, 0x7ee7, 0x7eaa, 0x5609, 0x67b7, 0x5939, + 0x4f73, 0x5bb6, 0x52a0, 0x835a, 0x988a, 0x8d3e, 0x7532, 0x94be, + 0x5047, 0x7a3c, 0x4ef7, 0x67b6, 0x9a7e, 0x5ac1, 0x6b7c, 0x76d1, + 0x575a, 0x5c16, 0x7b3a, 0x95f4, 0x714e, 0x517c, 0x80a9, 0x8270, + 0x5978, 0x7f04, 0x8327, 0x68c0, 0x67ec, 0x78b1, 0x7877, 0x62e3, + 0x6361, 0x7b80, 0x4fed, 0x526a, 0x51cf, 0x8350, 0x69db, 0x9274, + 0x8df5, 0x8d31, 0x89c1, 0x952e, 0x7bad, 0x4ef6, + /* 0xbd */ + 0x7d37, 0x7d38, 0x7d39, 0x7d3a, 0x7d3b, 0x7d3c, 0x7d3d, 0x7d3e, + 0x7d3f, 0x7d40, 0x7d41, 0x7d42, 0x7d43, 0x7d44, 0x7d45, 0x7d46, + 0x7d47, 0x7d48, 0x7d49, 0x7d4a, 0x7d4b, 0x7d4c, 0x7d4d, 0x7d4e, + 0x7d4f, 0x7d50, 0x7d51, 0x7d52, 0x7d53, 0x7d54, 0x7d55, 0x7d56, + 0x7d57, 0x7d58, 0x7d59, 0x7d5a, 0x7d5b, 0x7d5c, 0x7d5d, 0x7d5e, + 0x7d5f, 0x7d60, 0x7d61, 0x7d62, 0x7d63, 0x7d64, 0x7d65, 0x7d66, + 0x7d67, 0x7d68, 0x7d69, 0x7d6a, 0x7d6b, 0x7d6c, 0x7d6d, 0x7d6f, + 0x7d70, 0x7d71, 0x7d72, 0x7d73, 0x7d74, 0x7d75, 0x7d76, 0x7d78, + 0x7d79, 0x7d7a, 0x7d7b, 0x7d7c, 0x7d7d, 0x7d7e, 0x7d7f, 0x7d80, + 0x7d81, 0x7d82, 0x7d83, 0x7d84, 0x7d85, 0x7d86, 0x7d87, 0x7d88, + 0x7d89, 0x7d8a, 0x7d8b, 0x7d8c, 0x7d8d, 0x7d8e, 0x7d8f, 0x7d90, + 0x7d91, 0x7d92, 0x7d93, 0x7d94, 0x7d95, 0x7d96, 0x7d97, 0x7d98, + 0x5065, 0x8230, 0x5251, 0x996f, 0x6e10, 0x6e85, 0x6da7, 0x5efa, + 0x50f5, 0x59dc, 0x5c06, 0x6d46, 0x6c5f, 0x7586, 0x848b, 0x6868, + 0x5956, 0x8bb2, 0x5320, 0x9171, 0x964d, 0x8549, 0x6912, 0x7901, + 0x7126, 0x80f6, 0x4ea4, 0x90ca, 0x6d47, 0x9a84, 0x5a07, 0x56bc, + 0x6405, 0x94f0, 0x77eb, 0x4fa5, 0x811a, 0x72e1, 0x89d2, 0x997a, + 0x7f34, 0x7ede, 0x527f, 0x6559, 0x9175, 0x8f7f, 0x8f83, 0x53eb, + 0x7a96, 0x63ed, 0x63a5, 0x7686, 0x79f8, 0x8857, 0x9636, 0x622a, + 0x52ab, 0x8282, 0x6854, 0x6770, 0x6377, 0x776b, 0x7aed, 0x6d01, + 0x7ed3, 0x89e3, 0x59d0, 0x6212, 0x85c9, 0x82a5, 0x754c, 0x501f, + 0x4ecb, 0x75a5, 0x8beb, 0x5c4a, 0x5dfe, 0x7b4b, 0x65a4, 0x91d1, + 0x4eca, 0x6d25, 0x895f, 0x7d27, 0x9526, 0x4ec5, 0x8c28, 0x8fdb, + 0x9773, 0x664b, 0x7981, 0x8fd1, 0x70ec, 0x6d78, + /* 0xbe */ + 0x7d99, 0x7d9a, 0x7d9b, 0x7d9c, 0x7d9d, 0x7d9e, 0x7d9f, 0x7da0, + 0x7da1, 0x7da2, 0x7da3, 0x7da4, 0x7da5, 0x7da7, 0x7da8, 0x7da9, + 0x7daa, 0x7dab, 0x7dac, 0x7dad, 0x7daf, 0x7db0, 0x7db1, 0x7db2, + 0x7db3, 0x7db4, 0x7db5, 0x7db6, 0x7db7, 0x7db8, 0x7db9, 0x7dba, + 0x7dbb, 0x7dbc, 0x7dbd, 0x7dbe, 0x7dbf, 0x7dc0, 0x7dc1, 0x7dc2, + 0x7dc3, 0x7dc4, 0x7dc5, 0x7dc6, 0x7dc7, 0x7dc8, 0x7dc9, 0x7dca, + 0x7dcb, 0x7dcc, 0x7dcd, 0x7dce, 0x7dcf, 0x7dd0, 0x7dd1, 0x7dd2, + 0x7dd3, 0x7dd4, 0x7dd5, 0x7dd6, 0x7dd7, 0x7dd8, 0x7dd9, 0x7dda, + 0x7ddb, 0x7ddc, 0x7ddd, 0x7dde, 0x7ddf, 0x7de0, 0x7de1, 0x7de2, + 0x7de3, 0x7de4, 0x7de5, 0x7de6, 0x7de7, 0x7de8, 0x7de9, 0x7dea, + 0x7deb, 0x7dec, 0x7ded, 0x7dee, 0x7def, 0x7df0, 0x7df1, 0x7df2, + 0x7df3, 0x7df4, 0x7df5, 0x7df6, 0x7df7, 0x7df8, 0x7df9, 0x7dfa, + 0x5c3d, 0x52b2, 0x8346, 0x5162, 0x830e, 0x775b, 0x6676, 0x9cb8, + 0x4eac, 0x60ca, 0x7cbe, 0x7cb3, 0x7ecf, 0x4e95, 0x8b66, 0x666f, + 0x9888, 0x9759, 0x5883, 0x656c, 0x955c, 0x5f84, 0x75c9, 0x9756, + 0x7adf, 0x7ade, 0x51c0, 0x70af, 0x7a98, 0x63ea, 0x7a76, 0x7ea0, + 0x7396, 0x97ed, 0x4e45, 0x7078, 0x4e5d, 0x9152, 0x53a9, 0x6551, + 0x65e7, 0x81fc, 0x8205, 0x548e, 0x5c31, 0x759a, 0x97a0, 0x62d8, + 0x72d9, 0x75bd, 0x5c45, 0x9a79, 0x83ca, 0x5c40, 0x5480, 0x77e9, + 0x4e3e, 0x6cae, 0x805a, 0x62d2, 0x636e, 0x5de8, 0x5177, 0x8ddd, + 0x8e1e, 0x952f, 0x4ff1, 0x53e5, 0x60e7, 0x70ac, 0x5267, 0x6350, + 0x9e43, 0x5a1f, 0x5026, 0x7737, 0x5377, 0x7ee2, 0x6485, 0x652b, + 0x6289, 0x6398, 0x5014, 0x7235, 0x89c9, 0x51b3, 0x8bc0, 0x7edd, + 0x5747, 0x83cc, 0x94a7, 0x519b, 0x541b, 0x5cfb, + /* 0xbf */ + 0x7dfb, 0x7dfc, 0x7dfd, 0x7dfe, 0x7dff, 0x7e00, 0x7e01, 0x7e02, + 0x7e03, 0x7e04, 0x7e05, 0x7e06, 0x7e07, 0x7e08, 0x7e09, 0x7e0a, + 0x7e0b, 0x7e0c, 0x7e0d, 0x7e0e, 0x7e0f, 0x7e10, 0x7e11, 0x7e12, + 0x7e13, 0x7e14, 0x7e15, 0x7e16, 0x7e17, 0x7e18, 0x7e19, 0x7e1a, + 0x7e1b, 0x7e1c, 0x7e1d, 0x7e1e, 0x7e1f, 0x7e20, 0x7e21, 0x7e22, + 0x7e23, 0x7e24, 0x7e25, 0x7e26, 0x7e27, 0x7e28, 0x7e29, 0x7e2a, + 0x7e2b, 0x7e2c, 0x7e2d, 0x7e2e, 0x7e2f, 0x7e30, 0x7e31, 0x7e32, + 0x7e33, 0x7e34, 0x7e35, 0x7e36, 0x7e37, 0x7e38, 0x7e39, 0x7e3a, + 0x7e3c, 0x7e3d, 0x7e3e, 0x7e3f, 0x7e40, 0x7e42, 0x7e43, 0x7e44, + 0x7e45, 0x7e46, 0x7e48, 0x7e49, 0x7e4a, 0x7e4b, 0x7e4c, 0x7e4d, + 0x7e4e, 0x7e4f, 0x7e50, 0x7e51, 0x7e52, 0x7e53, 0x7e54, 0x7e55, + 0x7e56, 0x7e57, 0x7e58, 0x7e59, 0x7e5a, 0x7e5b, 0x7e5c, 0x7e5d, + 0x4fca, 0x7ae3, 0x6d5a, 0x90e1, 0x9a8f, 0x5580, 0x5496, 0x5361, + 0x54af, 0x5f00, 0x63e9, 0x6977, 0x51ef, 0x6168, 0x520a, 0x582a, + 0x52d8, 0x574e, 0x780d, 0x770b, 0x5eb7, 0x6177, 0x7ce0, 0x625b, + 0x6297, 0x4ea2, 0x7095, 0x8003, 0x62f7, 0x70e4, 0x9760, 0x5777, + 0x82db, 0x67ef, 0x68f5, 0x78d5, 0x9897, 0x79d1, 0x58f3, 0x54b3, + 0x53ef, 0x6e34, 0x514b, 0x523b, 0x5ba2, 0x8bfe, 0x80af, 0x5543, + 0x57a6, 0x6073, 0x5751, 0x542d, 0x7a7a, 0x6050, 0x5b54, 0x63a7, + 0x62a0, 0x53e3, 0x6263, 0x5bc7, 0x67af, 0x54ed, 0x7a9f, 0x82e6, + 0x9177, 0x5e93, 0x88e4, 0x5938, 0x57ae, 0x630e, 0x8de8, 0x80ef, + 0x5757, 0x7b77, 0x4fa9, 0x5feb, 0x5bbd, 0x6b3e, 0x5321, 0x7b50, + 0x72c2, 0x6846, 0x77ff, 0x7736, 0x65f7, 0x51b5, 0x4e8f, 0x76d4, + 0x5cbf, 0x7aa5, 0x8475, 0x594e, 0x9b41, 0x5080, + /* 0xc0 */ + 0x7e5e, 0x7e5f, 0x7e60, 0x7e61, 0x7e62, 0x7e63, 0x7e64, 0x7e65, + 0x7e66, 0x7e67, 0x7e68, 0x7e69, 0x7e6a, 0x7e6b, 0x7e6c, 0x7e6d, + 0x7e6e, 0x7e6f, 0x7e70, 0x7e71, 0x7e72, 0x7e73, 0x7e74, 0x7e75, + 0x7e76, 0x7e77, 0x7e78, 0x7e79, 0x7e7a, 0x7e7b, 0x7e7c, 0x7e7d, + 0x7e7e, 0x7e7f, 0x7e80, 0x7e81, 0x7e83, 0x7e84, 0x7e85, 0x7e86, + 0x7e87, 0x7e88, 0x7e89, 0x7e8a, 0x7e8b, 0x7e8c, 0x7e8d, 0x7e8e, + 0x7e8f, 0x7e90, 0x7e91, 0x7e92, 0x7e93, 0x7e94, 0x7e95, 0x7e96, + 0x7e97, 0x7e98, 0x7e99, 0x7e9a, 0x7e9c, 0x7e9d, 0x7e9e, 0x7eae, + 0x7eb4, 0x7ebb, 0x7ebc, 0x7ed6, 0x7ee4, 0x7eec, 0x7ef9, 0x7f0a, + 0x7f10, 0x7f1e, 0x7f37, 0x7f39, 0x7f3b, 0x7f3c, 0x7f3d, 0x7f3e, + 0x7f3f, 0x7f40, 0x7f41, 0x7f43, 0x7f46, 0x7f47, 0x7f48, 0x7f49, + 0x7f4a, 0x7f4b, 0x7f4c, 0x7f4d, 0x7f4e, 0x7f4f, 0x7f52, 0x7f53, + 0x9988, 0x6127, 0x6e83, 0x5764, 0x6606, 0x6346, 0x56f0, 0x62ec, + 0x6269, 0x5ed3, 0x9614, 0x5783, 0x62c9, 0x5587, 0x8721, 0x814a, + 0x8fa3, 0x5566, 0x83b1, 0x6765, 0x8d56, 0x84dd, 0x5a6a, 0x680f, + 0x62e6, 0x7bee, 0x9611, 0x5170, 0x6f9c, 0x8c30, 0x63fd, 0x89c8, + 0x61d2, 0x7f06, 0x70c2, 0x6ee5, 0x7405, 0x6994, 0x72fc, 0x5eca, + 0x90ce, 0x6717, 0x6d6a, 0x635e, 0x52b3, 0x7262, 0x8001, 0x4f6c, + 0x59e5, 0x916a, 0x70d9, 0x6d9d, 0x52d2, 0x4e50, 0x96f7, 0x956d, + 0x857e, 0x78ca, 0x7d2f, 0x5121, 0x5792, 0x64c2, 0x808b, 0x7c7b, + 0x6cea, 0x68f1, 0x695e, 0x51b7, 0x5398, 0x68a8, 0x7281, 0x9ece, + 0x7bf1, 0x72f8, 0x79bb, 0x6f13, 0x7406, 0x674e, 0x91cc, 0x9ca4, + 0x793c, 0x8389, 0x8354, 0x540f, 0x6817, 0x4e3d, 0x5389, 0x52b1, + 0x783e, 0x5386, 0x5229, 0x5088, 0x4f8b, 0x4fd0, + /* 0xc1 */ + 0x7f56, 0x7f59, 0x7f5b, 0x7f5c, 0x7f5d, 0x7f5e, 0x7f60, 0x7f63, + 0x7f64, 0x7f65, 0x7f66, 0x7f67, 0x7f6b, 0x7f6c, 0x7f6d, 0x7f6f, + 0x7f70, 0x7f73, 0x7f75, 0x7f76, 0x7f77, 0x7f78, 0x7f7a, 0x7f7b, + 0x7f7c, 0x7f7d, 0x7f7f, 0x7f80, 0x7f82, 0x7f83, 0x7f84, 0x7f85, + 0x7f86, 0x7f87, 0x7f88, 0x7f89, 0x7f8b, 0x7f8d, 0x7f8f, 0x7f90, + 0x7f91, 0x7f92, 0x7f93, 0x7f95, 0x7f96, 0x7f97, 0x7f98, 0x7f99, + 0x7f9b, 0x7f9c, 0x7fa0, 0x7fa2, 0x7fa3, 0x7fa5, 0x7fa6, 0x7fa8, + 0x7fa9, 0x7faa, 0x7fab, 0x7fac, 0x7fad, 0x7fae, 0x7fb1, 0x7fb3, + 0x7fb4, 0x7fb5, 0x7fb6, 0x7fb7, 0x7fba, 0x7fbb, 0x7fbe, 0x7fc0, + 0x7fc2, 0x7fc3, 0x7fc4, 0x7fc6, 0x7fc7, 0x7fc8, 0x7fc9, 0x7fcb, + 0x7fcd, 0x7fcf, 0x7fd0, 0x7fd1, 0x7fd2, 0x7fd3, 0x7fd6, 0x7fd7, + 0x7fd9, 0x7fda, 0x7fdb, 0x7fdc, 0x7fdd, 0x7fde, 0x7fe2, 0x7fe3, + 0x75e2, 0x7acb, 0x7c92, 0x6ca5, 0x96b6, 0x529b, 0x7483, 0x54e9, + 0x4fe9, 0x8054, 0x83b2, 0x8fde, 0x9570, 0x5ec9, 0x601c, 0x6d9f, + 0x5e18, 0x655b, 0x8138, 0x94fe, 0x604b, 0x70bc, 0x7ec3, 0x7cae, + 0x51c9, 0x6881, 0x7cb1, 0x826f, 0x4e24, 0x8f86, 0x91cf, 0x667e, + 0x4eae, 0x8c05, 0x64a9, 0x804a, 0x50da, 0x7597, 0x71ce, 0x5be5, + 0x8fbd, 0x6f66, 0x4e86, 0x6482, 0x9563, 0x5ed6, 0x6599, 0x5217, + 0x88c2, 0x70c8, 0x52a3, 0x730e, 0x7433, 0x6797, 0x78f7, 0x9716, + 0x4e34, 0x90bb, 0x9cde, 0x6dcb, 0x51db, 0x8d41, 0x541d, 0x62ce, + 0x73b2, 0x83f1, 0x96f6, 0x9f84, 0x94c3, 0x4f36, 0x7f9a, 0x51cc, + 0x7075, 0x9675, 0x5cad, 0x9886, 0x53e6, 0x4ee4, 0x6e9c, 0x7409, + 0x69b4, 0x786b, 0x998f, 0x7559, 0x5218, 0x7624, 0x6d41, 0x67f3, + 0x516d, 0x9f99, 0x804b, 0x5499, 0x7b3c, 0x7abf, + /* 0xc2 */ + 0x7fe4, 0x7fe7, 0x7fe8, 0x7fea, 0x7feb, 0x7fec, 0x7fed, 0x7fef, + 0x7ff2, 0x7ff4, 0x7ff5, 0x7ff6, 0x7ff7, 0x7ff8, 0x7ff9, 0x7ffa, + 0x7ffd, 0x7ffe, 0x7fff, 0x8002, 0x8007, 0x8008, 0x8009, 0x800a, + 0x800e, 0x800f, 0x8011, 0x8013, 0x801a, 0x801b, 0x801d, 0x801e, + 0x801f, 0x8021, 0x8023, 0x8024, 0x802b, 0x802c, 0x802d, 0x802e, + 0x802f, 0x8030, 0x8032, 0x8034, 0x8039, 0x803a, 0x803c, 0x803e, + 0x8040, 0x8041, 0x8044, 0x8045, 0x8047, 0x8048, 0x8049, 0x804e, + 0x804f, 0x8050, 0x8051, 0x8053, 0x8055, 0x8056, 0x8057, 0x8059, + 0x805b, 0x805c, 0x805d, 0x805e, 0x805f, 0x8060, 0x8061, 0x8062, + 0x8063, 0x8064, 0x8065, 0x8066, 0x8067, 0x8068, 0x806b, 0x806c, + 0x806d, 0x806e, 0x806f, 0x8070, 0x8072, 0x8073, 0x8074, 0x8075, + 0x8076, 0x8077, 0x8078, 0x8079, 0x807a, 0x807b, 0x807c, 0x807d, + 0x9686, 0x5784, 0x62e2, 0x9647, 0x697c, 0x5a04, 0x6402, 0x7bd3, + 0x6f0f, 0x964b, 0x82a6, 0x5362, 0x9885, 0x5e90, 0x7089, 0x63b3, + 0x5364, 0x864f, 0x9c81, 0x9e93, 0x788c, 0x9732, 0x8def, 0x8d42, + 0x9e7f, 0x6f5e, 0x7984, 0x5f55, 0x9646, 0x622e, 0x9a74, 0x5415, + 0x94dd, 0x4fa3, 0x65c5, 0x5c65, 0x5c61, 0x7f15, 0x8651, 0x6c2f, + 0x5f8b, 0x7387, 0x6ee4, 0x7eff, 0x5ce6, 0x631b, 0x5b6a, 0x6ee6, + 0x5375, 0x4e71, 0x63a0, 0x7565, 0x62a1, 0x8f6e, 0x4f26, 0x4ed1, + 0x6ca6, 0x7eb6, 0x8bba, 0x841d, 0x87ba, 0x7f57, 0x903b, 0x9523, + 0x7ba9, 0x9aa1, 0x88f8, 0x843d, 0x6d1b, 0x9a86, 0x7edc, 0x5988, + 0x9ebb, 0x739b, 0x7801, 0x8682, 0x9a6c, 0x9a82, 0x561b, 0x5417, + 0x57cb, 0x4e70, 0x9ea6, 0x5356, 0x8fc8, 0x8109, 0x7792, 0x9992, + 0x86ee, 0x6ee1, 0x8513, 0x66fc, 0x6162, 0x6f2b, + /* 0xc3 */ + 0x807e, 0x8081, 0x8082, 0x8085, 0x8088, 0x808a, 0x808d, 0x808e, + 0x808f, 0x8090, 0x8091, 0x8092, 0x8094, 0x8095, 0x8097, 0x8099, + 0x809e, 0x80a3, 0x80a6, 0x80a7, 0x80a8, 0x80ac, 0x80b0, 0x80b3, + 0x80b5, 0x80b6, 0x80b8, 0x80b9, 0x80bb, 0x80c5, 0x80c7, 0x80c8, + 0x80c9, 0x80ca, 0x80cb, 0x80cf, 0x80d0, 0x80d1, 0x80d2, 0x80d3, + 0x80d4, 0x80d5, 0x80d8, 0x80df, 0x80e0, 0x80e2, 0x80e3, 0x80e6, + 0x80ee, 0x80f5, 0x80f7, 0x80f9, 0x80fb, 0x80fe, 0x80ff, 0x8100, + 0x8101, 0x8103, 0x8104, 0x8105, 0x8107, 0x8108, 0x810b, 0x810c, + 0x8115, 0x8117, 0x8119, 0x811b, 0x811c, 0x811d, 0x811f, 0x8120, + 0x8121, 0x8122, 0x8123, 0x8124, 0x8125, 0x8126, 0x8127, 0x8128, + 0x8129, 0x812a, 0x812b, 0x812d, 0x812e, 0x8130, 0x8133, 0x8134, + 0x8135, 0x8137, 0x8139, 0x813a, 0x813b, 0x813c, 0x813d, 0x813f, + 0x8c29, 0x8292, 0x832b, 0x76f2, 0x6c13, 0x5fd9, 0x83bd, 0x732b, + 0x8305, 0x951a, 0x6bdb, 0x77db, 0x94c6, 0x536f, 0x8302, 0x5192, + 0x5e3d, 0x8c8c, 0x8d38, 0x4e48, 0x73ab, 0x679a, 0x6885, 0x9176, + 0x9709, 0x7164, 0x6ca1, 0x7709, 0x5a92, 0x9541, 0x6bcf, 0x7f8e, + 0x6627, 0x5bd0, 0x59b9, 0x5a9a, 0x95e8, 0x95f7, 0x4eec, 0x840c, + 0x8499, 0x6aac, 0x76df, 0x9530, 0x731b, 0x68a6, 0x5b5f, 0x772f, + 0x919a, 0x9761, 0x7cdc, 0x8ff7, 0x8c1c, 0x5f25, 0x7c73, 0x79d8, + 0x89c5, 0x6ccc, 0x871c, 0x5bc6, 0x5e42, 0x68c9, 0x7720, 0x7ef5, + 0x5195, 0x514d, 0x52c9, 0x5a29, 0x7f05, 0x9762, 0x82d7, 0x63cf, + 0x7784, 0x85d0, 0x79d2, 0x6e3a, 0x5e99, 0x5999, 0x8511, 0x706d, + 0x6c11, 0x62bf, 0x76bf, 0x654f, 0x60af, 0x95fd, 0x660e, 0x879f, + 0x9e23, 0x94ed, 0x540d, 0x547d, 0x8c2c, 0x6478, + /* 0xc4 */ + 0x8140, 0x8141, 0x8142, 0x8143, 0x8144, 0x8145, 0x8147, 0x8149, + 0x814d, 0x814e, 0x814f, 0x8152, 0x8156, 0x8157, 0x8158, 0x815b, + 0x815c, 0x815d, 0x815e, 0x815f, 0x8161, 0x8162, 0x8163, 0x8164, + 0x8166, 0x8168, 0x816a, 0x816b, 0x816c, 0x816f, 0x8172, 0x8173, + 0x8175, 0x8176, 0x8177, 0x8178, 0x8181, 0x8183, 0x8184, 0x8185, + 0x8186, 0x8187, 0x8189, 0x818b, 0x818c, 0x818d, 0x818e, 0x8190, + 0x8192, 0x8193, 0x8194, 0x8195, 0x8196, 0x8197, 0x8199, 0x819a, + 0x819e, 0x819f, 0x81a0, 0x81a1, 0x81a2, 0x81a4, 0x81a5, 0x81a7, + 0x81a9, 0x81ab, 0x81ac, 0x81ad, 0x81ae, 0x81af, 0x81b0, 0x81b1, + 0x81b2, 0x81b4, 0x81b5, 0x81b6, 0x81b7, 0x81b8, 0x81b9, 0x81bc, + 0x81bd, 0x81be, 0x81bf, 0x81c4, 0x81c5, 0x81c7, 0x81c8, 0x81c9, + 0x81cb, 0x81cd, 0x81ce, 0x81cf, 0x81d0, 0x81d1, 0x81d2, 0x81d3, + 0x6479, 0x8611, 0x6a21, 0x819c, 0x78e8, 0x6469, 0x9b54, 0x62b9, + 0x672b, 0x83ab, 0x58a8, 0x9ed8, 0x6cab, 0x6f20, 0x5bde, 0x964c, + 0x8c0b, 0x725f, 0x67d0, 0x62c7, 0x7261, 0x4ea9, 0x59c6, 0x6bcd, + 0x5893, 0x66ae, 0x5e55, 0x52df, 0x6155, 0x6728, 0x76ee, 0x7766, + 0x7267, 0x7a46, 0x62ff, 0x54ea, 0x5450, 0x94a0, 0x90a3, 0x5a1c, + 0x7eb3, 0x6c16, 0x4e43, 0x5976, 0x8010, 0x5948, 0x5357, 0x7537, + 0x96be, 0x56ca, 0x6320, 0x8111, 0x607c, 0x95f9, 0x6dd6, 0x5462, + 0x9981, 0x5185, 0x5ae9, 0x80fd, 0x59ae, 0x9713, 0x502a, 0x6ce5, + 0x5c3c, 0x62df, 0x4f60, 0x533f, 0x817b, 0x9006, 0x6eba, 0x852b, + 0x62c8, 0x5e74, 0x78be, 0x64b5, 0x637b, 0x5ff5, 0x5a18, 0x917f, + 0x9e1f, 0x5c3f, 0x634f, 0x8042, 0x5b7d, 0x556e, 0x954a, 0x954d, + 0x6d85, 0x60a8, 0x67e0, 0x72de, 0x51dd, 0x5b81, + /* 0xc5 */ + 0x81d4, 0x81d5, 0x81d6, 0x81d7, 0x81d8, 0x81d9, 0x81da, 0x81db, + 0x81dc, 0x81dd, 0x81de, 0x81df, 0x81e0, 0x81e1, 0x81e2, 0x81e4, + 0x81e5, 0x81e6, 0x81e8, 0x81e9, 0x81eb, 0x81ee, 0x81ef, 0x81f0, + 0x81f1, 0x81f2, 0x81f5, 0x81f6, 0x81f7, 0x81f8, 0x81f9, 0x81fa, + 0x81fd, 0x81ff, 0x8203, 0x8207, 0x8208, 0x8209, 0x820a, 0x820b, + 0x820e, 0x820f, 0x8211, 0x8213, 0x8215, 0x8216, 0x8217, 0x8218, + 0x8219, 0x821a, 0x821d, 0x8220, 0x8224, 0x8225, 0x8226, 0x8227, + 0x8229, 0x822e, 0x8232, 0x823a, 0x823c, 0x823d, 0x823f, 0x8240, + 0x8241, 0x8242, 0x8243, 0x8245, 0x8246, 0x8248, 0x824a, 0x824c, + 0x824d, 0x824e, 0x8250, 0x8251, 0x8252, 0x8253, 0x8254, 0x8255, + 0x8256, 0x8257, 0x8259, 0x825b, 0x825c, 0x825d, 0x825e, 0x8260, + 0x8261, 0x8262, 0x8263, 0x8264, 0x8265, 0x8266, 0x8267, 0x8269, + 0x62e7, 0x6cde, 0x725b, 0x626d, 0x94ae, 0x7ebd, 0x8113, 0x6d53, + 0x519c, 0x5f04, 0x5974, 0x52aa, 0x6012, 0x5973, 0x6696, 0x8650, + 0x759f, 0x632a, 0x61e6, 0x7cef, 0x8bfa, 0x54e6, 0x6b27, 0x9e25, + 0x6bb4, 0x85d5, 0x5455, 0x5076, 0x6ca4, 0x556a, 0x8db4, 0x722c, + 0x5e15, 0x6015, 0x7436, 0x62cd, 0x6392, 0x724c, 0x5f98, 0x6e43, + 0x6d3e, 0x6500, 0x6f58, 0x76d8, 0x78d0, 0x76fc, 0x7554, 0x5224, + 0x53db, 0x4e53, 0x5e9e, 0x65c1, 0x802a, 0x80d6, 0x629b, 0x5486, + 0x5228, 0x70ae, 0x888d, 0x8dd1, 0x6ce1, 0x5478, 0x80da, 0x57f9, + 0x88f4, 0x8d54, 0x966a, 0x914d, 0x4f69, 0x6c9b, 0x55b7, 0x76c6, + 0x7830, 0x62a8, 0x70f9, 0x6f8e, 0x5f6d, 0x84ec, 0x68da, 0x787c, + 0x7bf7, 0x81a8, 0x670b, 0x9e4f, 0x6367, 0x78b0, 0x576f, 0x7812, + 0x9739, 0x6279, 0x62ab, 0x5288, 0x7435, 0x6bd7, + /* 0xc6 */ + 0x826a, 0x826b, 0x826c, 0x826d, 0x8271, 0x8275, 0x8276, 0x8277, + 0x8278, 0x827b, 0x827c, 0x8280, 0x8281, 0x8283, 0x8285, 0x8286, + 0x8287, 0x8289, 0x828c, 0x8290, 0x8293, 0x8294, 0x8295, 0x8296, + 0x829a, 0x829b, 0x829e, 0x82a0, 0x82a2, 0x82a3, 0x82a7, 0x82b2, + 0x82b5, 0x82b6, 0x82ba, 0x82bb, 0x82bc, 0x82bf, 0x82c0, 0x82c2, + 0x82c3, 0x82c5, 0x82c6, 0x82c9, 0x82d0, 0x82d6, 0x82d9, 0x82da, + 0x82dd, 0x82e2, 0x82e7, 0x82e8, 0x82e9, 0x82ea, 0x82ec, 0x82ed, + 0x82ee, 0x82f0, 0x82f2, 0x82f3, 0x82f5, 0x82f6, 0x82f8, 0x82fa, + 0x82fc, 0x82fd, 0x82fe, 0x82ff, 0x8300, 0x830a, 0x830b, 0x830d, + 0x8310, 0x8312, 0x8313, 0x8316, 0x8318, 0x8319, 0x831d, 0x831e, + 0x831f, 0x8320, 0x8321, 0x8322, 0x8323, 0x8324, 0x8325, 0x8326, + 0x8329, 0x832a, 0x832e, 0x8330, 0x8332, 0x8337, 0x833b, 0x833d, + 0x5564, 0x813e, 0x75b2, 0x76ae, 0x5339, 0x75de, 0x50fb, 0x5c41, + 0x8b6c, 0x7bc7, 0x504f, 0x7247, 0x9a97, 0x98d8, 0x6f02, 0x74e2, + 0x7968, 0x6487, 0x77a5, 0x62fc, 0x9891, 0x8d2b, 0x54c1, 0x8058, + 0x4e52, 0x576a, 0x82f9, 0x840d, 0x5e73, 0x51ed, 0x74f6, 0x8bc4, + 0x5c4f, 0x5761, 0x6cfc, 0x9887, 0x5a46, 0x7834, 0x9b44, 0x8feb, + 0x7c95, 0x5256, 0x6251, 0x94fa, 0x4ec6, 0x8386, 0x8461, 0x83e9, + 0x84b2, 0x57d4, 0x6734, 0x5703, 0x666e, 0x6d66, 0x8c31, 0x66dd, + 0x7011, 0x671f, 0x6b3a, 0x6816, 0x621a, 0x59bb, 0x4e03, 0x51c4, + 0x6f06, 0x67d2, 0x6c8f, 0x5176, 0x68cb, 0x5947, 0x6b67, 0x7566, + 0x5d0e, 0x8110, 0x9f50, 0x65d7, 0x7948, 0x7941, 0x9a91, 0x8d77, + 0x5c82, 0x4e5e, 0x4f01, 0x542f, 0x5951, 0x780c, 0x5668, 0x6c14, + 0x8fc4, 0x5f03, 0x6c7d, 0x6ce3, 0x8bab, 0x6390, + /* 0xc7 */ + 0x833e, 0x833f, 0x8341, 0x8342, 0x8344, 0x8345, 0x8348, 0x834a, + 0x834b, 0x834c, 0x834d, 0x834e, 0x8353, 0x8355, 0x8356, 0x8357, + 0x8358, 0x8359, 0x835d, 0x8362, 0x8370, 0x8371, 0x8372, 0x8373, + 0x8374, 0x8375, 0x8376, 0x8379, 0x837a, 0x837e, 0x837f, 0x8380, + 0x8381, 0x8382, 0x8383, 0x8384, 0x8387, 0x8388, 0x838a, 0x838b, + 0x838c, 0x838d, 0x838f, 0x8390, 0x8391, 0x8394, 0x8395, 0x8396, + 0x8397, 0x8399, 0x839a, 0x839d, 0x839f, 0x83a1, 0x83a2, 0x83a3, + 0x83a4, 0x83a5, 0x83a6, 0x83a7, 0x83ac, 0x83ad, 0x83ae, 0x83af, + 0x83b5, 0x83bb, 0x83be, 0x83bf, 0x83c2, 0x83c3, 0x83c4, 0x83c6, + 0x83c8, 0x83c9, 0x83cb, 0x83cd, 0x83ce, 0x83d0, 0x83d1, 0x83d2, + 0x83d3, 0x83d5, 0x83d7, 0x83d9, 0x83da, 0x83db, 0x83de, 0x83e2, + 0x83e3, 0x83e4, 0x83e6, 0x83e7, 0x83e8, 0x83eb, 0x83ec, 0x83ed, + 0x6070, 0x6d3d, 0x7275, 0x6266, 0x948e, 0x94c5, 0x5343, 0x8fc1, + 0x7b7e, 0x4edf, 0x8c26, 0x4e7e, 0x9ed4, 0x94b1, 0x94b3, 0x524d, + 0x6f5c, 0x9063, 0x6d45, 0x8c34, 0x5811, 0x5d4c, 0x6b20, 0x6b49, + 0x67aa, 0x545b, 0x8154, 0x7f8c, 0x5899, 0x8537, 0x5f3a, 0x62a2, + 0x6a47, 0x9539, 0x6572, 0x6084, 0x6865, 0x77a7, 0x4e54, 0x4fa8, + 0x5de7, 0x9798, 0x64ac, 0x7fd8, 0x5ced, 0x4fcf, 0x7a8d, 0x5207, + 0x8304, 0x4e14, 0x602f, 0x7a83, 0x94a6, 0x4fb5, 0x4eb2, 0x79e6, + 0x7434, 0x52e4, 0x82b9, 0x64d2, 0x79bd, 0x5bdd, 0x6c81, 0x9752, + 0x8f7b, 0x6c22, 0x503e, 0x537f, 0x6e05, 0x64ce, 0x6674, 0x6c30, + 0x60c5, 0x9877, 0x8bf7, 0x5e86, 0x743c, 0x7a77, 0x79cb, 0x4e18, + 0x90b1, 0x7403, 0x6c42, 0x56da, 0x914b, 0x6cc5, 0x8d8b, 0x533a, + 0x86c6, 0x66f2, 0x8eaf, 0x5c48, 0x9a71, 0x6e20, + /* 0xc8 */ + 0x83ee, 0x83ef, 0x83f3, 0x83f4, 0x83f5, 0x83f6, 0x83f7, 0x83fa, + 0x83fb, 0x83fc, 0x83fe, 0x83ff, 0x8400, 0x8402, 0x8405, 0x8407, + 0x8408, 0x8409, 0x840a, 0x8410, 0x8412, 0x8413, 0x8414, 0x8415, + 0x8416, 0x8417, 0x8419, 0x841a, 0x841b, 0x841e, 0x841f, 0x8420, + 0x8421, 0x8422, 0x8423, 0x8429, 0x842a, 0x842b, 0x842c, 0x842d, + 0x842e, 0x842f, 0x8430, 0x8432, 0x8433, 0x8434, 0x8435, 0x8436, + 0x8437, 0x8439, 0x843a, 0x843b, 0x843e, 0x843f, 0x8440, 0x8441, + 0x8442, 0x8443, 0x8444, 0x8445, 0x8447, 0x8448, 0x8449, 0x844a, + 0x844b, 0x844c, 0x844d, 0x844e, 0x844f, 0x8450, 0x8452, 0x8453, + 0x8454, 0x8455, 0x8456, 0x8458, 0x845d, 0x845e, 0x845f, 0x8460, + 0x8462, 0x8464, 0x8465, 0x8466, 0x8467, 0x8468, 0x846a, 0x846e, + 0x846f, 0x8470, 0x8472, 0x8474, 0x8477, 0x8479, 0x847b, 0x847c, + 0x53d6, 0x5a36, 0x9f8b, 0x8da3, 0x53bb, 0x5708, 0x98a7, 0x6743, + 0x919b, 0x6cc9, 0x5168, 0x75ca, 0x62f3, 0x72ac, 0x5238, 0x529d, + 0x7f3a, 0x7094, 0x7638, 0x5374, 0x9e4a, 0x69b7, 0x786e, 0x96c0, + 0x88d9, 0x7fa4, 0x7136, 0x71c3, 0x5189, 0x67d3, 0x74e4, 0x58e4, + 0x6518, 0x56b7, 0x8ba9, 0x9976, 0x6270, 0x7ed5, 0x60f9, 0x70ed, + 0x58ec, 0x4ec1, 0x4eba, 0x5fcd, 0x97e7, 0x4efb, 0x8ba4, 0x5203, + 0x598a, 0x7eab, 0x6254, 0x4ecd, 0x65e5, 0x620e, 0x8338, 0x84c9, + 0x8363, 0x878d, 0x7194, 0x6eb6, 0x5bb9, 0x7ed2, 0x5197, 0x63c9, + 0x67d4, 0x8089, 0x8339, 0x8815, 0x5112, 0x5b7a, 0x5982, 0x8fb1, + 0x4e73, 0x6c5d, 0x5165, 0x8925, 0x8f6f, 0x962e, 0x854a, 0x745e, + 0x9510, 0x95f0, 0x6da6, 0x82e5, 0x5f31, 0x6492, 0x6d12, 0x8428, + 0x816e, 0x9cc3, 0x585e, 0x8d5b, 0x4e09, 0x53c1, + /* 0xc9 */ + 0x847d, 0x847e, 0x847f, 0x8480, 0x8481, 0x8483, 0x8484, 0x8485, + 0x8486, 0x848a, 0x848d, 0x848f, 0x8490, 0x8491, 0x8492, 0x8493, + 0x8494, 0x8495, 0x8496, 0x8498, 0x849a, 0x849b, 0x849d, 0x849e, + 0x849f, 0x84a0, 0x84a2, 0x84a3, 0x84a4, 0x84a5, 0x84a6, 0x84a7, + 0x84a8, 0x84a9, 0x84aa, 0x84ab, 0x84ac, 0x84ad, 0x84ae, 0x84b0, + 0x84b1, 0x84b3, 0x84b5, 0x84b6, 0x84b7, 0x84bb, 0x84bc, 0x84be, + 0x84c0, 0x84c2, 0x84c3, 0x84c5, 0x84c6, 0x84c7, 0x84c8, 0x84cb, + 0x84cc, 0x84ce, 0x84cf, 0x84d2, 0x84d4, 0x84d5, 0x84d7, 0x84d8, + 0x84d9, 0x84da, 0x84db, 0x84dc, 0x84de, 0x84e1, 0x84e2, 0x84e4, + 0x84e7, 0x84e8, 0x84e9, 0x84ea, 0x84eb, 0x84ed, 0x84ee, 0x84ef, + 0x84f1, 0x84f2, 0x84f3, 0x84f4, 0x84f5, 0x84f6, 0x84f7, 0x84f8, + 0x84f9, 0x84fa, 0x84fb, 0x84fd, 0x84fe, 0x8500, 0x8501, 0x8502, + 0x4f1e, 0x6563, 0x6851, 0x55d3, 0x4e27, 0x6414, 0x9a9a, 0x626b, + 0x5ac2, 0x745f, 0x8272, 0x6da9, 0x68ee, 0x50e7, 0x838e, 0x7802, + 0x6740, 0x5239, 0x6c99, 0x7eb1, 0x50bb, 0x5565, 0x715e, 0x7b5b, + 0x6652, 0x73ca, 0x82eb, 0x6749, 0x5c71, 0x5220, 0x717d, 0x886b, + 0x95ea, 0x9655, 0x64c5, 0x8d61, 0x81b3, 0x5584, 0x6c55, 0x6247, + 0x7f2e, 0x5892, 0x4f24, 0x5546, 0x8d4f, 0x664c, 0x4e0a, 0x5c1a, + 0x88f3, 0x68a2, 0x634e, 0x7a0d, 0x70e7, 0x828d, 0x52fa, 0x97f6, + 0x5c11, 0x54e8, 0x90b5, 0x7ecd, 0x5962, 0x8d4a, 0x86c7, 0x820c, + 0x820d, 0x8d66, 0x6444, 0x5c04, 0x6151, 0x6d89, 0x793e, 0x8bbe, + 0x7837, 0x7533, 0x547b, 0x4f38, 0x8eab, 0x6df1, 0x5a20, 0x7ec5, + 0x795e, 0x6c88, 0x5ba1, 0x5a76, 0x751a, 0x80be, 0x614e, 0x6e17, + 0x58f0, 0x751f, 0x7525, 0x7272, 0x5347, 0x7ef3, + /* 0xca */ + 0x8503, 0x8504, 0x8505, 0x8506, 0x8507, 0x8508, 0x8509, 0x850a, + 0x850b, 0x850d, 0x850e, 0x850f, 0x8510, 0x8512, 0x8514, 0x8515, + 0x8516, 0x8518, 0x8519, 0x851b, 0x851c, 0x851d, 0x851e, 0x8520, + 0x8522, 0x8523, 0x8524, 0x8525, 0x8526, 0x8527, 0x8528, 0x8529, + 0x852a, 0x852d, 0x852e, 0x852f, 0x8530, 0x8531, 0x8532, 0x8533, + 0x8534, 0x8535, 0x8536, 0x853e, 0x853f, 0x8540, 0x8541, 0x8542, + 0x8544, 0x8545, 0x8546, 0x8547, 0x854b, 0x854c, 0x854d, 0x854e, + 0x854f, 0x8550, 0x8551, 0x8552, 0x8553, 0x8554, 0x8555, 0x8557, + 0x8558, 0x855a, 0x855b, 0x855c, 0x855d, 0x855f, 0x8560, 0x8561, + 0x8562, 0x8563, 0x8565, 0x8566, 0x8567, 0x8569, 0x856a, 0x856b, + 0x856c, 0x856d, 0x856e, 0x856f, 0x8570, 0x8571, 0x8573, 0x8575, + 0x8576, 0x8577, 0x8578, 0x857c, 0x857d, 0x857f, 0x8580, 0x8581, + 0x7701, 0x76db, 0x5269, 0x80dc, 0x5723, 0x5e08, 0x5931, 0x72ee, + 0x65bd, 0x6e7f, 0x8bd7, 0x5c38, 0x8671, 0x5341, 0x77f3, 0x62fe, + 0x65f6, 0x4ec0, 0x98df, 0x8680, 0x5b9e, 0x8bc6, 0x53f2, 0x77e2, + 0x4f7f, 0x5c4e, 0x9a76, 0x59cb, 0x5f0f, 0x793a, 0x58eb, 0x4e16, + 0x67ff, 0x4e8b, 0x62ed, 0x8a93, 0x901d, 0x52bf, 0x662f, 0x55dc, + 0x566c, 0x9002, 0x4ed5, 0x4f8d, 0x91ca, 0x9970, 0x6c0f, 0x5e02, + 0x6043, 0x5ba4, 0x89c6, 0x8bd5, 0x6536, 0x624b, 0x9996, 0x5b88, + 0x5bff, 0x6388, 0x552e, 0x53d7, 0x7626, 0x517d, 0x852c, 0x67a2, + 0x68b3, 0x6b8a, 0x6292, 0x8f93, 0x53d4, 0x8212, 0x6dd1, 0x758f, + 0x4e66, 0x8d4e, 0x5b70, 0x719f, 0x85af, 0x6691, 0x66d9, 0x7f72, + 0x8700, 0x9ecd, 0x9f20, 0x5c5e, 0x672f, 0x8ff0, 0x6811, 0x675f, + 0x620d, 0x7ad6, 0x5885, 0x5eb6, 0x6570, 0x6f31, + /* 0xcb */ + 0x8582, 0x8583, 0x8586, 0x8588, 0x8589, 0x858a, 0x858b, 0x858c, + 0x858d, 0x858e, 0x8590, 0x8591, 0x8592, 0x8593, 0x8594, 0x8595, + 0x8596, 0x8597, 0x8598, 0x8599, 0x859a, 0x859d, 0x859e, 0x859f, + 0x85a0, 0x85a1, 0x85a2, 0x85a3, 0x85a5, 0x85a6, 0x85a7, 0x85a9, + 0x85ab, 0x85ac, 0x85ad, 0x85b1, 0x85b2, 0x85b3, 0x85b4, 0x85b5, + 0x85b6, 0x85b8, 0x85ba, 0x85bb, 0x85bc, 0x85bd, 0x85be, 0x85bf, + 0x85c0, 0x85c2, 0x85c3, 0x85c4, 0x85c5, 0x85c6, 0x85c7, 0x85c8, + 0x85ca, 0x85cb, 0x85cc, 0x85cd, 0x85ce, 0x85d1, 0x85d2, 0x85d4, + 0x85d6, 0x85d7, 0x85d8, 0x85d9, 0x85da, 0x85db, 0x85dd, 0x85de, + 0x85df, 0x85e0, 0x85e1, 0x85e2, 0x85e3, 0x85e5, 0x85e6, 0x85e7, + 0x85e8, 0x85ea, 0x85eb, 0x85ec, 0x85ed, 0x85ee, 0x85ef, 0x85f0, + 0x85f1, 0x85f2, 0x85f3, 0x85f4, 0x85f5, 0x85f6, 0x85f7, 0x85f8, + 0x6055, 0x5237, 0x800d, 0x6454, 0x8870, 0x7529, 0x5e05, 0x6813, + 0x62f4, 0x971c, 0x53cc, 0x723d, 0x8c01, 0x6c34, 0x7761, 0x7a0e, + 0x542e, 0x77ac, 0x987a, 0x821c, 0x8bf4, 0x7855, 0x6714, 0x70c1, + 0x65af, 0x6495, 0x5636, 0x601d, 0x79c1, 0x53f8, 0x4e1d, 0x6b7b, + 0x8086, 0x5bfa, 0x55e3, 0x56db, 0x4f3a, 0x4f3c, 0x9972, 0x5df3, + 0x677e, 0x8038, 0x6002, 0x9882, 0x9001, 0x5b8b, 0x8bbc, 0x8bf5, + 0x641c, 0x8258, 0x64de, 0x55fd, 0x82cf, 0x9165, 0x4fd7, 0x7d20, + 0x901f, 0x7c9f, 0x50f3, 0x5851, 0x6eaf, 0x5bbf, 0x8bc9, 0x8083, + 0x9178, 0x849c, 0x7b97, 0x867d, 0x968b, 0x968f, 0x7ee5, 0x9ad3, + 0x788e, 0x5c81, 0x7a57, 0x9042, 0x96a7, 0x795f, 0x5b59, 0x635f, + 0x7b0b, 0x84d1, 0x68ad, 0x5506, 0x7f29, 0x7410, 0x7d22, 0x9501, + 0x6240, 0x584c, 0x4ed6, 0x5b83, 0x5979, 0x5854, + /* 0xcc */ + 0x85f9, 0x85fa, 0x85fc, 0x85fd, 0x85fe, 0x8600, 0x8601, 0x8602, + 0x8603, 0x8604, 0x8606, 0x8607, 0x8608, 0x8609, 0x860a, 0x860b, + 0x860c, 0x860d, 0x860e, 0x860f, 0x8610, 0x8612, 0x8613, 0x8614, + 0x8615, 0x8617, 0x8618, 0x8619, 0x861a, 0x861b, 0x861c, 0x861d, + 0x861e, 0x861f, 0x8620, 0x8621, 0x8622, 0x8623, 0x8624, 0x8625, + 0x8626, 0x8628, 0x862a, 0x862b, 0x862c, 0x862d, 0x862e, 0x862f, + 0x8630, 0x8631, 0x8632, 0x8633, 0x8634, 0x8635, 0x8636, 0x8637, + 0x8639, 0x863a, 0x863b, 0x863d, 0x863e, 0x863f, 0x8640, 0x8641, + 0x8642, 0x8643, 0x8644, 0x8645, 0x8646, 0x8647, 0x8648, 0x8649, + 0x864a, 0x864b, 0x864c, 0x8652, 0x8653, 0x8655, 0x8656, 0x8657, + 0x8658, 0x8659, 0x865b, 0x865c, 0x865d, 0x865f, 0x8660, 0x8661, + 0x8663, 0x8664, 0x8665, 0x8666, 0x8667, 0x8668, 0x8669, 0x866a, + 0x736d, 0x631e, 0x8e4b, 0x8e0f, 0x80ce, 0x82d4, 0x62ac, 0x53f0, + 0x6cf0, 0x915e, 0x592a, 0x6001, 0x6c70, 0x574d, 0x644a, 0x8d2a, + 0x762b, 0x6ee9, 0x575b, 0x6a80, 0x75f0, 0x6f6d, 0x8c2d, 0x8c08, + 0x5766, 0x6bef, 0x8892, 0x78b3, 0x63a2, 0x53f9, 0x70ad, 0x6c64, + 0x5858, 0x642a, 0x5802, 0x68e0, 0x819b, 0x5510, 0x7cd6, 0x5018, + 0x8eba, 0x6dcc, 0x8d9f, 0x70eb, 0x638f, 0x6d9b, 0x6ed4, 0x7ee6, + 0x8404, 0x6843, 0x9003, 0x6dd8, 0x9676, 0x8ba8, 0x5957, 0x7279, + 0x85e4, 0x817e, 0x75bc, 0x8a8a, 0x68af, 0x5254, 0x8e22, 0x9511, + 0x63d0, 0x9898, 0x8e44, 0x557c, 0x4f53, 0x66ff, 0x568f, 0x60d5, + 0x6d95, 0x5243, 0x5c49, 0x5929, 0x6dfb, 0x586b, 0x7530, 0x751c, + 0x606c, 0x8214, 0x8146, 0x6311, 0x6761, 0x8fe2, 0x773a, 0x8df3, + 0x8d34, 0x94c1, 0x5e16, 0x5385, 0x542c, 0x70c3, + /* 0xcd */ + 0x866d, 0x866f, 0x8670, 0x8672, 0x8673, 0x8674, 0x8675, 0x8676, + 0x8677, 0x8678, 0x8683, 0x8684, 0x8685, 0x8686, 0x8687, 0x8688, + 0x8689, 0x868e, 0x868f, 0x8690, 0x8691, 0x8692, 0x8694, 0x8696, + 0x8697, 0x8698, 0x8699, 0x869a, 0x869b, 0x869e, 0x869f, 0x86a0, + 0x86a1, 0x86a2, 0x86a5, 0x86a6, 0x86ab, 0x86ad, 0x86ae, 0x86b2, + 0x86b3, 0x86b7, 0x86b8, 0x86b9, 0x86bb, 0x86bc, 0x86bd, 0x86be, + 0x86bf, 0x86c1, 0x86c2, 0x86c3, 0x86c5, 0x86c8, 0x86cc, 0x86cd, + 0x86d2, 0x86d3, 0x86d5, 0x86d6, 0x86d7, 0x86da, 0x86dc, 0x86dd, + 0x86e0, 0x86e1, 0x86e2, 0x86e3, 0x86e5, 0x86e6, 0x86e7, 0x86e8, + 0x86ea, 0x86eb, 0x86ec, 0x86ef, 0x86f5, 0x86f6, 0x86f7, 0x86fa, + 0x86fb, 0x86fc, 0x86fd, 0x86ff, 0x8701, 0x8704, 0x8705, 0x8706, + 0x870b, 0x870c, 0x870e, 0x870f, 0x8710, 0x8711, 0x8714, 0x8716, + 0x6c40, 0x5ef7, 0x505c, 0x4ead, 0x5ead, 0x633a, 0x8247, 0x901a, + 0x6850, 0x916e, 0x77b3, 0x540c, 0x94dc, 0x5f64, 0x7ae5, 0x6876, + 0x6345, 0x7b52, 0x7edf, 0x75db, 0x5077, 0x6295, 0x5934, 0x900f, + 0x51f8, 0x79c3, 0x7a81, 0x56fe, 0x5f92, 0x9014, 0x6d82, 0x5c60, + 0x571f, 0x5410, 0x5154, 0x6e4d, 0x56e2, 0x63a8, 0x9893, 0x817f, + 0x8715, 0x892a, 0x9000, 0x541e, 0x5c6f, 0x81c0, 0x62d6, 0x6258, + 0x8131, 0x9e35, 0x9640, 0x9a6e, 0x9a7c, 0x692d, 0x59a5, 0x62d3, + 0x553e, 0x6316, 0x54c7, 0x86d9, 0x6d3c, 0x5a03, 0x74e6, 0x889c, + 0x6b6a, 0x5916, 0x8c4c, 0x5f2f, 0x6e7e, 0x73a9, 0x987d, 0x4e38, + 0x70f7, 0x5b8c, 0x7897, 0x633d, 0x665a, 0x7696, 0x60cb, 0x5b9b, + 0x5a49, 0x4e07, 0x8155, 0x6c6a, 0x738b, 0x4ea1, 0x6789, 0x7f51, + 0x5f80, 0x65fa, 0x671b, 0x5fd8, 0x5984, 0x5a01, + /* 0xce */ + 0x8719, 0x871b, 0x871d, 0x871f, 0x8720, 0x8724, 0x8726, 0x8727, + 0x8728, 0x872a, 0x872b, 0x872c, 0x872d, 0x872f, 0x8730, 0x8732, + 0x8733, 0x8735, 0x8736, 0x8738, 0x8739, 0x873a, 0x873c, 0x873d, + 0x8740, 0x8741, 0x8742, 0x8743, 0x8744, 0x8745, 0x8746, 0x874a, + 0x874b, 0x874d, 0x874f, 0x8750, 0x8751, 0x8752, 0x8754, 0x8755, + 0x8756, 0x8758, 0x875a, 0x875b, 0x875c, 0x875d, 0x875e, 0x875f, + 0x8761, 0x8762, 0x8766, 0x8767, 0x8768, 0x8769, 0x876a, 0x876b, + 0x876c, 0x876d, 0x876f, 0x8771, 0x8772, 0x8773, 0x8775, 0x8777, + 0x8778, 0x8779, 0x877a, 0x877f, 0x8780, 0x8781, 0x8784, 0x8786, + 0x8787, 0x8789, 0x878a, 0x878c, 0x878e, 0x878f, 0x8790, 0x8791, + 0x8792, 0x8794, 0x8795, 0x8796, 0x8798, 0x8799, 0x879a, 0x879b, + 0x879c, 0x879d, 0x879e, 0x87a0, 0x87a1, 0x87a2, 0x87a3, 0x87a4, + 0x5dcd, 0x5fae, 0x5371, 0x97e6, 0x8fdd, 0x6845, 0x56f4, 0x552f, + 0x60df, 0x4e3a, 0x6f4d, 0x7ef4, 0x82c7, 0x840e, 0x59d4, 0x4f1f, + 0x4f2a, 0x5c3e, 0x7eac, 0x672a, 0x851a, 0x5473, 0x754f, 0x80c3, + 0x5582, 0x9b4f, 0x4f4d, 0x6e2d, 0x8c13, 0x5c09, 0x6170, 0x536b, + 0x761f, 0x6e29, 0x868a, 0x6587, 0x95fb, 0x7eb9, 0x543b, 0x7a33, + 0x7d0a, 0x95ee, 0x55e1, 0x7fc1, 0x74ee, 0x631d, 0x8717, 0x6da1, + 0x7a9d, 0x6211, 0x65a1, 0x5367, 0x63e1, 0x6c83, 0x5deb, 0x545c, + 0x94a8, 0x4e4c, 0x6c61, 0x8bec, 0x5c4b, 0x65e0, 0x829c, 0x68a7, + 0x543e, 0x5434, 0x6bcb, 0x6b66, 0x4e94, 0x6342, 0x5348, 0x821e, + 0x4f0d, 0x4fae, 0x575e, 0x620a, 0x96fe, 0x6664, 0x7269, 0x52ff, + 0x52a1, 0x609f, 0x8bef, 0x6614, 0x7199, 0x6790, 0x897f, 0x7852, + 0x77fd, 0x6670, 0x563b, 0x5438, 0x9521, 0x727a, + /* 0xcf */ + 0x87a5, 0x87a6, 0x87a7, 0x87a9, 0x87aa, 0x87ae, 0x87b0, 0x87b1, + 0x87b2, 0x87b4, 0x87b6, 0x87b7, 0x87b8, 0x87b9, 0x87bb, 0x87bc, + 0x87be, 0x87bf, 0x87c1, 0x87c2, 0x87c3, 0x87c4, 0x87c5, 0x87c7, + 0x87c8, 0x87c9, 0x87cc, 0x87cd, 0x87ce, 0x87cf, 0x87d0, 0x87d4, + 0x87d5, 0x87d6, 0x87d7, 0x87d8, 0x87d9, 0x87da, 0x87dc, 0x87dd, + 0x87de, 0x87df, 0x87e1, 0x87e2, 0x87e3, 0x87e4, 0x87e6, 0x87e7, + 0x87e8, 0x87e9, 0x87eb, 0x87ec, 0x87ed, 0x87ef, 0x87f0, 0x87f1, + 0x87f2, 0x87f3, 0x87f4, 0x87f5, 0x87f6, 0x87f7, 0x87f8, 0x87fa, + 0x87fb, 0x87fc, 0x87fd, 0x87ff, 0x8800, 0x8801, 0x8802, 0x8804, + 0x8805, 0x8806, 0x8807, 0x8808, 0x8809, 0x880b, 0x880c, 0x880d, + 0x880e, 0x880f, 0x8810, 0x8811, 0x8812, 0x8814, 0x8817, 0x8818, + 0x8819, 0x881a, 0x881c, 0x881d, 0x881e, 0x881f, 0x8820, 0x8823, + 0x7a00, 0x606f, 0x5e0c, 0x6089, 0x819d, 0x5915, 0x60dc, 0x7184, + 0x70ef, 0x6eaa, 0x6c50, 0x7280, 0x6a84, 0x88ad, 0x5e2d, 0x4e60, + 0x5ab3, 0x559c, 0x94e3, 0x6d17, 0x7cfb, 0x9699, 0x620f, 0x7ec6, + 0x778e, 0x867e, 0x5323, 0x971e, 0x8f96, 0x6687, 0x5ce1, 0x4fa0, + 0x72ed, 0x4e0b, 0x53a6, 0x590f, 0x5413, 0x6380, 0x9528, 0x5148, + 0x4ed9, 0x9c9c, 0x7ea4, 0x54b8, 0x8d24, 0x8854, 0x8237, 0x95f2, + 0x6d8e, 0x5f26, 0x5acc, 0x663e, 0x9669, 0x73b0, 0x732e, 0x53bf, + 0x817a, 0x9985, 0x7fa1, 0x5baa, 0x9677, 0x9650, 0x7ebf, 0x76f8, + 0x53a2, 0x9576, 0x9999, 0x7bb1, 0x8944, 0x6e58, 0x4e61, 0x7fd4, + 0x7965, 0x8be6, 0x60f3, 0x54cd, 0x4eab, 0x9879, 0x5df7, 0x6a61, + 0x50cf, 0x5411, 0x8c61, 0x8427, 0x785d, 0x9704, 0x524a, 0x54ee, + 0x56a3, 0x9500, 0x6d88, 0x5bb5, 0x6dc6, 0x6653, + /* 0xd0 */ + 0x8824, 0x8825, 0x8826, 0x8827, 0x8828, 0x8829, 0x882a, 0x882b, + 0x882c, 0x882d, 0x882e, 0x882f, 0x8830, 0x8831, 0x8833, 0x8834, + 0x8835, 0x8836, 0x8837, 0x8838, 0x883a, 0x883b, 0x883d, 0x883e, + 0x883f, 0x8841, 0x8842, 0x8843, 0x8846, 0x8847, 0x8848, 0x8849, + 0x884a, 0x884b, 0x884e, 0x884f, 0x8850, 0x8851, 0x8852, 0x8853, + 0x8855, 0x8856, 0x8858, 0x885a, 0x885b, 0x885c, 0x885d, 0x885e, + 0x885f, 0x8860, 0x8866, 0x8867, 0x886a, 0x886d, 0x886f, 0x8871, + 0x8873, 0x8874, 0x8875, 0x8876, 0x8878, 0x8879, 0x887a, 0x887b, + 0x887c, 0x8880, 0x8883, 0x8886, 0x8887, 0x8889, 0x888a, 0x888c, + 0x888e, 0x888f, 0x8890, 0x8891, 0x8893, 0x8894, 0x8895, 0x8897, + 0x8898, 0x8899, 0x889a, 0x889b, 0x889d, 0x889e, 0x889f, 0x88a0, + 0x88a1, 0x88a3, 0x88a5, 0x88a6, 0x88a7, 0x88a8, 0x88a9, 0x88aa, + 0x5c0f, 0x5b5d, 0x6821, 0x8096, 0x5578, 0x7b11, 0x6548, 0x6954, + 0x4e9b, 0x6b47, 0x874e, 0x978b, 0x534f, 0x631f, 0x643a, 0x90aa, + 0x659c, 0x80c1, 0x8c10, 0x5199, 0x68b0, 0x5378, 0x87f9, 0x61c8, + 0x6cc4, 0x6cfb, 0x8c22, 0x5c51, 0x85aa, 0x82af, 0x950c, 0x6b23, + 0x8f9b, 0x65b0, 0x5ffb, 0x5fc3, 0x4fe1, 0x8845, 0x661f, 0x8165, + 0x7329, 0x60fa, 0x5174, 0x5211, 0x578b, 0x5f62, 0x90a2, 0x884c, + 0x9192, 0x5e78, 0x674f, 0x6027, 0x59d3, 0x5144, 0x51f6, 0x80f8, + 0x5308, 0x6c79, 0x96c4, 0x718a, 0x4f11, 0x4fee, 0x7f9e, 0x673d, + 0x55c5, 0x9508, 0x79c0, 0x8896, 0x7ee3, 0x589f, 0x620c, 0x9700, + 0x865a, 0x5618, 0x987b, 0x5f90, 0x8bb8, 0x84c4, 0x9157, 0x53d9, + 0x65ed, 0x5e8f, 0x755c, 0x6064, 0x7d6e, 0x5a7f, 0x7eea, 0x7eed, + 0x8f69, 0x55a7, 0x5ba3, 0x60ac, 0x65cb, 0x7384, + /* 0xd1 */ + 0x88ac, 0x88ae, 0x88af, 0x88b0, 0x88b2, 0x88b3, 0x88b4, 0x88b5, + 0x88b6, 0x88b8, 0x88b9, 0x88ba, 0x88bb, 0x88bd, 0x88be, 0x88bf, + 0x88c0, 0x88c3, 0x88c4, 0x88c7, 0x88c8, 0x88ca, 0x88cb, 0x88cc, + 0x88cd, 0x88cf, 0x88d0, 0x88d1, 0x88d3, 0x88d6, 0x88d7, 0x88da, + 0x88db, 0x88dc, 0x88dd, 0x88de, 0x88e0, 0x88e1, 0x88e6, 0x88e7, + 0x88e9, 0x88ea, 0x88eb, 0x88ec, 0x88ed, 0x88ee, 0x88ef, 0x88f2, + 0x88f5, 0x88f6, 0x88f7, 0x88fa, 0x88fb, 0x88fd, 0x88ff, 0x8900, + 0x8901, 0x8903, 0x8904, 0x8905, 0x8906, 0x8907, 0x8908, 0x8909, + 0x890b, 0x890c, 0x890d, 0x890e, 0x890f, 0x8911, 0x8914, 0x8915, + 0x8916, 0x8917, 0x8918, 0x891c, 0x891d, 0x891e, 0x891f, 0x8920, + 0x8922, 0x8923, 0x8924, 0x8926, 0x8927, 0x8928, 0x8929, 0x892c, + 0x892d, 0x892e, 0x892f, 0x8931, 0x8932, 0x8933, 0x8935, 0x8937, + 0x9009, 0x7663, 0x7729, 0x7eda, 0x9774, 0x859b, 0x5b66, 0x7a74, + 0x96ea, 0x8840, 0x52cb, 0x718f, 0x5faa, 0x65ec, 0x8be2, 0x5bfb, + 0x9a6f, 0x5de1, 0x6b89, 0x6c5b, 0x8bad, 0x8baf, 0x900a, 0x8fc5, + 0x538b, 0x62bc, 0x9e26, 0x9e2d, 0x5440, 0x4e2b, 0x82bd, 0x7259, + 0x869c, 0x5d16, 0x8859, 0x6daf, 0x96c5, 0x54d1, 0x4e9a, 0x8bb6, + 0x7109, 0x54bd, 0x9609, 0x70df, 0x6df9, 0x76d0, 0x4e25, 0x7814, + 0x8712, 0x5ca9, 0x5ef6, 0x8a00, 0x989c, 0x960e, 0x708e, 0x6cbf, + 0x5944, 0x63a9, 0x773c, 0x884d, 0x6f14, 0x8273, 0x5830, 0x71d5, + 0x538c, 0x781a, 0x96c1, 0x5501, 0x5f66, 0x7130, 0x5bb4, 0x8c1a, + 0x9a8c, 0x6b83, 0x592e, 0x9e2f, 0x79e7, 0x6768, 0x626c, 0x4f6f, + 0x75a1, 0x7f8a, 0x6d0b, 0x9633, 0x6c27, 0x4ef0, 0x75d2, 0x517b, + 0x6837, 0x6f3e, 0x9080, 0x8170, 0x5996, 0x7476, + /* 0xd2 */ + 0x8938, 0x8939, 0x893a, 0x893b, 0x893c, 0x893d, 0x893e, 0x893f, + 0x8940, 0x8942, 0x8943, 0x8945, 0x8946, 0x8947, 0x8948, 0x8949, + 0x894a, 0x894b, 0x894c, 0x894d, 0x894e, 0x894f, 0x8950, 0x8951, + 0x8952, 0x8953, 0x8954, 0x8955, 0x8956, 0x8957, 0x8958, 0x8959, + 0x895a, 0x895b, 0x895c, 0x895d, 0x8960, 0x8961, 0x8962, 0x8963, + 0x8964, 0x8965, 0x8967, 0x8968, 0x8969, 0x896a, 0x896b, 0x896c, + 0x896d, 0x896e, 0x896f, 0x8970, 0x8971, 0x8972, 0x8973, 0x8974, + 0x8975, 0x8976, 0x8977, 0x8978, 0x8979, 0x897a, 0x897c, 0x897d, + 0x897e, 0x8980, 0x8982, 0x8984, 0x8985, 0x8987, 0x8988, 0x8989, + 0x898a, 0x898b, 0x898c, 0x898d, 0x898e, 0x898f, 0x8990, 0x8991, + 0x8992, 0x8993, 0x8994, 0x8995, 0x8996, 0x8997, 0x8998, 0x8999, + 0x899a, 0x899b, 0x899c, 0x899d, 0x899e, 0x899f, 0x89a0, 0x89a1, + 0x6447, 0x5c27, 0x9065, 0x7a91, 0x8c23, 0x59da, 0x54ac, 0x8200, + 0x836f, 0x8981, 0x8000, 0x6930, 0x564e, 0x8036, 0x7237, 0x91ce, + 0x51b6, 0x4e5f, 0x9875, 0x6396, 0x4e1a, 0x53f6, 0x66f3, 0x814b, + 0x591c, 0x6db2, 0x4e00, 0x58f9, 0x533b, 0x63d6, 0x94f1, 0x4f9d, + 0x4f0a, 0x8863, 0x9890, 0x5937, 0x9057, 0x79fb, 0x4eea, 0x80f0, + 0x7591, 0x6c82, 0x5b9c, 0x59e8, 0x5f5d, 0x6905, 0x8681, 0x501a, + 0x5df2, 0x4e59, 0x77e3, 0x4ee5, 0x827a, 0x6291, 0x6613, 0x9091, + 0x5c79, 0x4ebf, 0x5f79, 0x81c6, 0x9038, 0x8084, 0x75ab, 0x4ea6, + 0x88d4, 0x610f, 0x6bc5, 0x5fc6, 0x4e49, 0x76ca, 0x6ea2, 0x8be3, + 0x8bae, 0x8c0a, 0x8bd1, 0x5f02, 0x7ffc, 0x7fcc, 0x7ece, 0x8335, + 0x836b, 0x56e0, 0x6bb7, 0x97f3, 0x9634, 0x59fb, 0x541f, 0x94f6, + 0x6deb, 0x5bc5, 0x996e, 0x5c39, 0x5f15, 0x9690, + /* 0xd3 */ + 0x89a2, 0x89a3, 0x89a4, 0x89a5, 0x89a6, 0x89a7, 0x89a8, 0x89a9, + 0x89aa, 0x89ab, 0x89ac, 0x89ad, 0x89ae, 0x89af, 0x89b0, 0x89b1, + 0x89b2, 0x89b3, 0x89b4, 0x89b5, 0x89b6, 0x89b7, 0x89b8, 0x89b9, + 0x89ba, 0x89bb, 0x89bc, 0x89bd, 0x89be, 0x89bf, 0x89c0, 0x89c3, + 0x89cd, 0x89d3, 0x89d4, 0x89d5, 0x89d7, 0x89d8, 0x89d9, 0x89db, + 0x89dd, 0x89df, 0x89e0, 0x89e1, 0x89e2, 0x89e4, 0x89e7, 0x89e8, + 0x89e9, 0x89ea, 0x89ec, 0x89ed, 0x89ee, 0x89f0, 0x89f1, 0x89f2, + 0x89f4, 0x89f5, 0x89f6, 0x89f7, 0x89f8, 0x89f9, 0x89fa, 0x89fb, + 0x89fc, 0x89fd, 0x89fe, 0x89ff, 0x8a01, 0x8a02, 0x8a03, 0x8a04, + 0x8a05, 0x8a06, 0x8a08, 0x8a09, 0x8a0a, 0x8a0b, 0x8a0c, 0x8a0d, + 0x8a0e, 0x8a0f, 0x8a10, 0x8a11, 0x8a12, 0x8a13, 0x8a14, 0x8a15, + 0x8a16, 0x8a17, 0x8a18, 0x8a19, 0x8a1a, 0x8a1b, 0x8a1c, 0x8a1d, + 0x5370, 0x82f1, 0x6a31, 0x5a74, 0x9e70, 0x5e94, 0x7f28, 0x83b9, + 0x8424, 0x8425, 0x8367, 0x8747, 0x8fce, 0x8d62, 0x76c8, 0x5f71, + 0x9896, 0x786c, 0x6620, 0x54df, 0x62e5, 0x4f63, 0x81c3, 0x75c8, + 0x5eb8, 0x96cd, 0x8e0a, 0x86f9, 0x548f, 0x6cf3, 0x6d8c, 0x6c38, + 0x607f, 0x52c7, 0x7528, 0x5e7d, 0x4f18, 0x60a0, 0x5fe7, 0x5c24, + 0x7531, 0x90ae, 0x94c0, 0x72b9, 0x6cb9, 0x6e38, 0x9149, 0x6709, + 0x53cb, 0x53f3, 0x4f51, 0x91c9, 0x8bf1, 0x53c8, 0x5e7c, 0x8fc2, + 0x6de4, 0x4e8e, 0x76c2, 0x6986, 0x865e, 0x611a, 0x8206, 0x4f59, + 0x4fde, 0x903e, 0x9c7c, 0x6109, 0x6e1d, 0x6e14, 0x9685, 0x4e88, + 0x5a31, 0x96e8, 0x4e0e, 0x5c7f, 0x79b9, 0x5b87, 0x8bed, 0x7fbd, + 0x7389, 0x57df, 0x828b, 0x90c1, 0x5401, 0x9047, 0x55bb, 0x5cea, + 0x5fa1, 0x6108, 0x6b32, 0x72f1, 0x80b2, 0x8a89, + /* 0xd4 */ + 0x8a1e, 0x8a1f, 0x8a20, 0x8a21, 0x8a22, 0x8a23, 0x8a24, 0x8a25, + 0x8a26, 0x8a27, 0x8a28, 0x8a29, 0x8a2a, 0x8a2b, 0x8a2c, 0x8a2d, + 0x8a2e, 0x8a2f, 0x8a30, 0x8a31, 0x8a32, 0x8a33, 0x8a34, 0x8a35, + 0x8a36, 0x8a37, 0x8a38, 0x8a39, 0x8a3a, 0x8a3b, 0x8a3c, 0x8a3d, + 0x8a3f, 0x8a40, 0x8a41, 0x8a42, 0x8a43, 0x8a44, 0x8a45, 0x8a46, + 0x8a47, 0x8a49, 0x8a4a, 0x8a4b, 0x8a4c, 0x8a4d, 0x8a4e, 0x8a4f, + 0x8a50, 0x8a51, 0x8a52, 0x8a53, 0x8a54, 0x8a55, 0x8a56, 0x8a57, + 0x8a58, 0x8a59, 0x8a5a, 0x8a5b, 0x8a5c, 0x8a5d, 0x8a5e, 0x8a5f, + 0x8a60, 0x8a61, 0x8a62, 0x8a63, 0x8a64, 0x8a65, 0x8a66, 0x8a67, + 0x8a68, 0x8a69, 0x8a6a, 0x8a6b, 0x8a6c, 0x8a6d, 0x8a6e, 0x8a6f, + 0x8a70, 0x8a71, 0x8a72, 0x8a73, 0x8a74, 0x8a75, 0x8a76, 0x8a77, + 0x8a78, 0x8a7a, 0x8a7b, 0x8a7c, 0x8a7d, 0x8a7e, 0x8a7f, 0x8a80, + 0x6d74, 0x5bd3, 0x88d5, 0x9884, 0x8c6b, 0x9a6d, 0x9e33, 0x6e0a, + 0x51a4, 0x5143, 0x57a3, 0x8881, 0x539f, 0x63f4, 0x8f95, 0x56ed, + 0x5458, 0x5706, 0x733f, 0x6e90, 0x7f18, 0x8fdc, 0x82d1, 0x613f, + 0x6028, 0x9662, 0x66f0, 0x7ea6, 0x8d8a, 0x8dc3, 0x94a5, 0x5cb3, + 0x7ca4, 0x6708, 0x60a6, 0x9605, 0x8018, 0x4e91, 0x90e7, 0x5300, + 0x9668, 0x5141, 0x8fd0, 0x8574, 0x915d, 0x6655, 0x97f5, 0x5b55, + 0x531d, 0x7838, 0x6742, 0x683d, 0x54c9, 0x707e, 0x5bb0, 0x8f7d, + 0x518d, 0x5728, 0x54b1, 0x6512, 0x6682, 0x8d5e, 0x8d43, 0x810f, + 0x846c, 0x906d, 0x7cdf, 0x51ff, 0x85fb, 0x67a3, 0x65e9, 0x6fa1, + 0x86a4, 0x8e81, 0x566a, 0x9020, 0x7682, 0x7076, 0x71e5, 0x8d23, + 0x62e9, 0x5219, 0x6cfd, 0x8d3c, 0x600e, 0x589e, 0x618e, 0x66fe, + 0x8d60, 0x624e, 0x55b3, 0x6e23, 0x672d, 0x8f67, + /* 0xd5 */ + 0x8a81, 0x8a82, 0x8a83, 0x8a84, 0x8a85, 0x8a86, 0x8a87, 0x8a88, + 0x8a8b, 0x8a8c, 0x8a8d, 0x8a8e, 0x8a8f, 0x8a90, 0x8a91, 0x8a92, + 0x8a94, 0x8a95, 0x8a96, 0x8a97, 0x8a98, 0x8a99, 0x8a9a, 0x8a9b, + 0x8a9c, 0x8a9d, 0x8a9e, 0x8a9f, 0x8aa0, 0x8aa1, 0x8aa2, 0x8aa3, + 0x8aa4, 0x8aa5, 0x8aa6, 0x8aa7, 0x8aa8, 0x8aa9, 0x8aaa, 0x8aab, + 0x8aac, 0x8aad, 0x8aae, 0x8aaf, 0x8ab0, 0x8ab1, 0x8ab2, 0x8ab3, + 0x8ab4, 0x8ab5, 0x8ab6, 0x8ab7, 0x8ab8, 0x8ab9, 0x8aba, 0x8abb, + 0x8abc, 0x8abd, 0x8abe, 0x8abf, 0x8ac0, 0x8ac1, 0x8ac2, 0x8ac3, + 0x8ac4, 0x8ac5, 0x8ac6, 0x8ac7, 0x8ac8, 0x8ac9, 0x8aca, 0x8acb, + 0x8acc, 0x8acd, 0x8ace, 0x8acf, 0x8ad0, 0x8ad1, 0x8ad2, 0x8ad3, + 0x8ad4, 0x8ad5, 0x8ad6, 0x8ad7, 0x8ad8, 0x8ad9, 0x8ada, 0x8adb, + 0x8adc, 0x8add, 0x8ade, 0x8adf, 0x8ae0, 0x8ae1, 0x8ae2, 0x8ae3, + 0x94e1, 0x95f8, 0x7728, 0x6805, 0x69a8, 0x548b, 0x4e4d, 0x70b8, + 0x8bc8, 0x6458, 0x658b, 0x5b85, 0x7a84, 0x503a, 0x5be8, 0x77bb, + 0x6be1, 0x8a79, 0x7c98, 0x6cbe, 0x76cf, 0x65a9, 0x8f97, 0x5d2d, + 0x5c55, 0x8638, 0x6808, 0x5360, 0x6218, 0x7ad9, 0x6e5b, 0x7efd, + 0x6a1f, 0x7ae0, 0x5f70, 0x6f33, 0x5f20, 0x638c, 0x6da8, 0x6756, + 0x4e08, 0x5e10, 0x8d26, 0x4ed7, 0x80c0, 0x7634, 0x969c, 0x62db, + 0x662d, 0x627e, 0x6cbc, 0x8d75, 0x7167, 0x7f69, 0x5146, 0x8087, + 0x53ec, 0x906e, 0x6298, 0x54f2, 0x86f0, 0x8f99, 0x8005, 0x9517, + 0x8517, 0x8fd9, 0x6d59, 0x73cd, 0x659f, 0x771f, 0x7504, 0x7827, + 0x81fb, 0x8d1e, 0x9488, 0x4fa6, 0x6795, 0x75b9, 0x8bca, 0x9707, + 0x632f, 0x9547, 0x9635, 0x84b8, 0x6323, 0x7741, 0x5f81, 0x72f0, + 0x4e89, 0x6014, 0x6574, 0x62ef, 0x6b63, 0x653f, + /* 0xd6 */ + 0x8ae4, 0x8ae5, 0x8ae6, 0x8ae7, 0x8ae8, 0x8ae9, 0x8aea, 0x8aeb, + 0x8aec, 0x8aed, 0x8aee, 0x8aef, 0x8af0, 0x8af1, 0x8af2, 0x8af3, + 0x8af4, 0x8af5, 0x8af6, 0x8af7, 0x8af8, 0x8af9, 0x8afa, 0x8afb, + 0x8afc, 0x8afd, 0x8afe, 0x8aff, 0x8b00, 0x8b01, 0x8b02, 0x8b03, + 0x8b04, 0x8b05, 0x8b06, 0x8b08, 0x8b09, 0x8b0a, 0x8b0b, 0x8b0c, + 0x8b0d, 0x8b0e, 0x8b0f, 0x8b10, 0x8b11, 0x8b12, 0x8b13, 0x8b14, + 0x8b15, 0x8b16, 0x8b17, 0x8b18, 0x8b19, 0x8b1a, 0x8b1b, 0x8b1c, + 0x8b1d, 0x8b1e, 0x8b1f, 0x8b20, 0x8b21, 0x8b22, 0x8b23, 0x8b24, + 0x8b25, 0x8b27, 0x8b28, 0x8b29, 0x8b2a, 0x8b2b, 0x8b2c, 0x8b2d, + 0x8b2e, 0x8b2f, 0x8b30, 0x8b31, 0x8b32, 0x8b33, 0x8b34, 0x8b35, + 0x8b36, 0x8b37, 0x8b38, 0x8b39, 0x8b3a, 0x8b3b, 0x8b3c, 0x8b3d, + 0x8b3e, 0x8b3f, 0x8b40, 0x8b41, 0x8b42, 0x8b43, 0x8b44, 0x8b45, + 0x5e27, 0x75c7, 0x90d1, 0x8bc1, 0x829d, 0x679d, 0x652f, 0x5431, + 0x8718, 0x77e5, 0x80a2, 0x8102, 0x6c41, 0x4e4b, 0x7ec7, 0x804c, + 0x76f4, 0x690d, 0x6b96, 0x6267, 0x503c, 0x4f84, 0x5740, 0x6307, + 0x6b62, 0x8dbe, 0x53ea, 0x65e8, 0x7eb8, 0x5fd7, 0x631a, 0x63b7, + 0x81f3, 0x81f4, 0x7f6e, 0x5e1c, 0x5cd9, 0x5236, 0x667a, 0x79e9, + 0x7a1a, 0x8d28, 0x7099, 0x75d4, 0x6ede, 0x6cbb, 0x7a92, 0x4e2d, + 0x76c5, 0x5fe0, 0x949f, 0x8877, 0x7ec8, 0x79cd, 0x80bf, 0x91cd, + 0x4ef2, 0x4f17, 0x821f, 0x5468, 0x5dde, 0x6d32, 0x8bcc, 0x7ca5, + 0x8f74, 0x8098, 0x5e1a, 0x5492, 0x76b1, 0x5b99, 0x663c, 0x9aa4, + 0x73e0, 0x682a, 0x86db, 0x6731, 0x732a, 0x8bf8, 0x8bdb, 0x9010, + 0x7af9, 0x70db, 0x716e, 0x62c4, 0x77a9, 0x5631, 0x4e3b, 0x8457, + 0x67f1, 0x52a9, 0x86c0, 0x8d2e, 0x94f8, 0x7b51, + /* 0xd7 */ + 0x8b46, 0x8b47, 0x8b48, 0x8b49, 0x8b4a, 0x8b4b, 0x8b4c, 0x8b4d, + 0x8b4e, 0x8b4f, 0x8b50, 0x8b51, 0x8b52, 0x8b53, 0x8b54, 0x8b55, + 0x8b56, 0x8b57, 0x8b58, 0x8b59, 0x8b5a, 0x8b5b, 0x8b5c, 0x8b5d, + 0x8b5e, 0x8b5f, 0x8b60, 0x8b61, 0x8b62, 0x8b63, 0x8b64, 0x8b65, + 0x8b67, 0x8b68, 0x8b69, 0x8b6a, 0x8b6b, 0x8b6d, 0x8b6e, 0x8b6f, + 0x8b70, 0x8b71, 0x8b72, 0x8b73, 0x8b74, 0x8b75, 0x8b76, 0x8b77, + 0x8b78, 0x8b79, 0x8b7a, 0x8b7b, 0x8b7c, 0x8b7d, 0x8b7e, 0x8b7f, + 0x8b80, 0x8b81, 0x8b82, 0x8b83, 0x8b84, 0x8b85, 0x8b86, 0x8b87, + 0x8b88, 0x8b89, 0x8b8a, 0x8b8b, 0x8b8c, 0x8b8d, 0x8b8e, 0x8b8f, + 0x8b90, 0x8b91, 0x8b92, 0x8b93, 0x8b94, 0x8b95, 0x8b96, 0x8b97, + 0x8b98, 0x8b99, 0x8b9a, 0x8b9b, 0x8b9c, 0x8b9d, 0x8b9e, 0x8b9f, + 0x8bac, 0x8bb1, 0x8bbb, 0x8bc7, 0x8bd0, 0x8bea, 0x8c09, 0x8c1e, + 0x4f4f, 0x6ce8, 0x795d, 0x9a7b, 0x6293, 0x722a, 0x62fd, 0x4e13, + 0x7816, 0x8f6c, 0x64b0, 0x8d5a, 0x7bc6, 0x6869, 0x5e84, 0x88c5, + 0x5986, 0x649e, 0x58ee, 0x72b6, 0x690e, 0x9525, 0x8ffd, 0x8d58, + 0x5760, 0x7f00, 0x8c06, 0x51c6, 0x6349, 0x62d9, 0x5353, 0x684c, + 0x7422, 0x8301, 0x914c, 0x5544, 0x7740, 0x707c, 0x6d4a, 0x5179, + 0x54a8, 0x8d44, 0x59ff, 0x6ecb, 0x6dc4, 0x5b5c, 0x7d2b, 0x4ed4, + 0x7c7d, 0x6ed3, 0x5b50, 0x81ea, 0x6e0d, 0x5b57, 0x9b03, 0x68d5, + 0x8e2a, 0x5b97, 0x7efc, 0x603b, 0x7eb5, 0x90b9, 0x8d70, 0x594f, + 0x63cd, 0x79df, 0x8db3, 0x5352, 0x65cf, 0x7956, 0x8bc5, 0x963b, + 0x7ec4, 0x94bb, 0x7e82, 0x5634, 0x9189, 0x6700, 0x7f6a, 0x5c0a, + 0x9075, 0x6628, 0x5de6, 0x4f50, 0x67de, 0x505a, 0x4f5c, 0x5750, + 0x5ea7, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0xd8 */ + 0x8c38, 0x8c39, 0x8c3a, 0x8c3b, 0x8c3c, 0x8c3d, 0x8c3e, 0x8c3f, + 0x8c40, 0x8c42, 0x8c43, 0x8c44, 0x8c45, 0x8c48, 0x8c4a, 0x8c4b, + 0x8c4d, 0x8c4e, 0x8c4f, 0x8c50, 0x8c51, 0x8c52, 0x8c53, 0x8c54, + 0x8c56, 0x8c57, 0x8c58, 0x8c59, 0x8c5b, 0x8c5c, 0x8c5d, 0x8c5e, + 0x8c5f, 0x8c60, 0x8c63, 0x8c64, 0x8c65, 0x8c66, 0x8c67, 0x8c68, + 0x8c69, 0x8c6c, 0x8c6d, 0x8c6e, 0x8c6f, 0x8c70, 0x8c71, 0x8c72, + 0x8c74, 0x8c75, 0x8c76, 0x8c77, 0x8c7b, 0x8c7c, 0x8c7d, 0x8c7e, + 0x8c7f, 0x8c80, 0x8c81, 0x8c83, 0x8c84, 0x8c86, 0x8c87, 0x8c88, + 0x8c8b, 0x8c8d, 0x8c8e, 0x8c8f, 0x8c90, 0x8c91, 0x8c92, 0x8c93, + 0x8c95, 0x8c96, 0x8c97, 0x8c99, 0x8c9a, 0x8c9b, 0x8c9c, 0x8c9d, + 0x8c9e, 0x8c9f, 0x8ca0, 0x8ca1, 0x8ca2, 0x8ca3, 0x8ca4, 0x8ca5, + 0x8ca6, 0x8ca7, 0x8ca8, 0x8ca9, 0x8caa, 0x8cab, 0x8cac, 0x8cad, + 0x4e8d, 0x4e0c, 0x5140, 0x4e10, 0x5eff, 0x5345, 0x4e15, 0x4e98, + 0x4e1e, 0x9b32, 0x5b6c, 0x5669, 0x4e28, 0x79ba, 0x4e3f, 0x5315, + 0x4e47, 0x592d, 0x723b, 0x536e, 0x6c10, 0x56df, 0x80e4, 0x9997, + 0x6bd3, 0x777e, 0x9f17, 0x4e36, 0x4e9f, 0x9f10, 0x4e5c, 0x4e69, + 0x4e93, 0x8288, 0x5b5b, 0x556c, 0x560f, 0x4ec4, 0x538d, 0x539d, + 0x53a3, 0x53a5, 0x53ae, 0x9765, 0x8d5d, 0x531a, 0x53f5, 0x5326, + 0x532e, 0x533e, 0x8d5c, 0x5366, 0x5363, 0x5202, 0x5208, 0x520e, + 0x522d, 0x5233, 0x523f, 0x5240, 0x524c, 0x525e, 0x5261, 0x525c, + 0x84af, 0x527d, 0x5282, 0x5281, 0x5290, 0x5293, 0x5182, 0x7f54, + 0x4ebb, 0x4ec3, 0x4ec9, 0x4ec2, 0x4ee8, 0x4ee1, 0x4eeb, 0x4ede, + 0x4f1b, 0x4ef3, 0x4f22, 0x4f64, 0x4ef5, 0x4f25, 0x4f27, 0x4f09, + 0x4f2b, 0x4f5e, 0x4f67, 0x6538, 0x4f5a, 0x4f5d, + /* 0xd9 */ + 0x8cae, 0x8caf, 0x8cb0, 0x8cb1, 0x8cb2, 0x8cb3, 0x8cb4, 0x8cb5, + 0x8cb6, 0x8cb7, 0x8cb8, 0x8cb9, 0x8cba, 0x8cbb, 0x8cbc, 0x8cbd, + 0x8cbe, 0x8cbf, 0x8cc0, 0x8cc1, 0x8cc2, 0x8cc3, 0x8cc4, 0x8cc5, + 0x8cc6, 0x8cc7, 0x8cc8, 0x8cc9, 0x8cca, 0x8ccb, 0x8ccc, 0x8ccd, + 0x8cce, 0x8ccf, 0x8cd0, 0x8cd1, 0x8cd2, 0x8cd3, 0x8cd4, 0x8cd5, + 0x8cd6, 0x8cd7, 0x8cd8, 0x8cd9, 0x8cda, 0x8cdb, 0x8cdc, 0x8cdd, + 0x8cde, 0x8cdf, 0x8ce0, 0x8ce1, 0x8ce2, 0x8ce3, 0x8ce4, 0x8ce5, + 0x8ce6, 0x8ce7, 0x8ce8, 0x8ce9, 0x8cea, 0x8ceb, 0x8cec, 0x8ced, + 0x8cee, 0x8cef, 0x8cf0, 0x8cf1, 0x8cf2, 0x8cf3, 0x8cf4, 0x8cf5, + 0x8cf6, 0x8cf7, 0x8cf8, 0x8cf9, 0x8cfa, 0x8cfb, 0x8cfc, 0x8cfd, + 0x8cfe, 0x8cff, 0x8d00, 0x8d01, 0x8d02, 0x8d03, 0x8d04, 0x8d05, + 0x8d06, 0x8d07, 0x8d08, 0x8d09, 0x8d0a, 0x8d0b, 0x8d0c, 0x8d0d, + 0x4f5f, 0x4f57, 0x4f32, 0x4f3d, 0x4f76, 0x4f74, 0x4f91, 0x4f89, + 0x4f83, 0x4f8f, 0x4f7e, 0x4f7b, 0x4faa, 0x4f7c, 0x4fac, 0x4f94, + 0x4fe6, 0x4fe8, 0x4fea, 0x4fc5, 0x4fda, 0x4fe3, 0x4fdc, 0x4fd1, + 0x4fdf, 0x4ff8, 0x5029, 0x504c, 0x4ff3, 0x502c, 0x500f, 0x502e, + 0x502d, 0x4ffe, 0x501c, 0x500c, 0x5025, 0x5028, 0x507e, 0x5043, + 0x5055, 0x5048, 0x504e, 0x506c, 0x507b, 0x50a5, 0x50a7, 0x50a9, + 0x50ba, 0x50d6, 0x5106, 0x50ed, 0x50ec, 0x50e6, 0x50ee, 0x5107, + 0x510b, 0x4edd, 0x6c3d, 0x4f58, 0x4f65, 0x4fce, 0x9fa0, 0x6c46, + 0x7c74, 0x516e, 0x5dfd, 0x9ec9, 0x9998, 0x5181, 0x5914, 0x52f9, + 0x530d, 0x8a07, 0x5310, 0x51eb, 0x5919, 0x5155, 0x4ea0, 0x5156, + 0x4eb3, 0x886e, 0x88a4, 0x4eb5, 0x8114, 0x88d2, 0x7980, 0x5b34, + 0x8803, 0x7fb8, 0x51ab, 0x51b1, 0x51bd, 0x51bc, + /* 0xda */ + 0x8d0e, 0x8d0f, 0x8d10, 0x8d11, 0x8d12, 0x8d13, 0x8d14, 0x8d15, + 0x8d16, 0x8d17, 0x8d18, 0x8d19, 0x8d1a, 0x8d1b, 0x8d1c, 0x8d20, + 0x8d51, 0x8d52, 0x8d57, 0x8d5f, 0x8d65, 0x8d68, 0x8d69, 0x8d6a, + 0x8d6c, 0x8d6e, 0x8d6f, 0x8d71, 0x8d72, 0x8d78, 0x8d79, 0x8d7a, + 0x8d7b, 0x8d7c, 0x8d7d, 0x8d7e, 0x8d7f, 0x8d80, 0x8d82, 0x8d83, + 0x8d86, 0x8d87, 0x8d88, 0x8d89, 0x8d8c, 0x8d8d, 0x8d8e, 0x8d8f, + 0x8d90, 0x8d92, 0x8d93, 0x8d95, 0x8d96, 0x8d97, 0x8d98, 0x8d99, + 0x8d9a, 0x8d9b, 0x8d9c, 0x8d9d, 0x8d9e, 0x8da0, 0x8da1, 0x8da2, + 0x8da4, 0x8da5, 0x8da6, 0x8da7, 0x8da8, 0x8da9, 0x8daa, 0x8dab, + 0x8dac, 0x8dad, 0x8dae, 0x8daf, 0x8db0, 0x8db2, 0x8db6, 0x8db7, + 0x8db9, 0x8dbb, 0x8dbd, 0x8dc0, 0x8dc1, 0x8dc2, 0x8dc5, 0x8dc7, + 0x8dc8, 0x8dc9, 0x8dca, 0x8dcd, 0x8dd0, 0x8dd2, 0x8dd3, 0x8dd4, + 0x51c7, 0x5196, 0x51a2, 0x51a5, 0x8ba0, 0x8ba6, 0x8ba7, 0x8baa, + 0x8bb4, 0x8bb5, 0x8bb7, 0x8bc2, 0x8bc3, 0x8bcb, 0x8bcf, 0x8bce, + 0x8bd2, 0x8bd3, 0x8bd4, 0x8bd6, 0x8bd8, 0x8bd9, 0x8bdc, 0x8bdf, + 0x8be0, 0x8be4, 0x8be8, 0x8be9, 0x8bee, 0x8bf0, 0x8bf3, 0x8bf6, + 0x8bf9, 0x8bfc, 0x8bff, 0x8c00, 0x8c02, 0x8c04, 0x8c07, 0x8c0c, + 0x8c0f, 0x8c11, 0x8c12, 0x8c14, 0x8c15, 0x8c16, 0x8c19, 0x8c1b, + 0x8c18, 0x8c1d, 0x8c1f, 0x8c20, 0x8c21, 0x8c25, 0x8c27, 0x8c2a, + 0x8c2b, 0x8c2e, 0x8c2f, 0x8c32, 0x8c33, 0x8c35, 0x8c36, 0x5369, + 0x537a, 0x961d, 0x9622, 0x9621, 0x9631, 0x962a, 0x963d, 0x963c, + 0x9642, 0x9649, 0x9654, 0x965f, 0x9667, 0x966c, 0x9672, 0x9674, + 0x9688, 0x968d, 0x9697, 0x96b0, 0x9097, 0x909b, 0x909d, 0x9099, + 0x90ac, 0x90a1, 0x90b4, 0x90b3, 0x90b6, 0x90ba, + /* 0xdb */ + 0x8dd5, 0x8dd8, 0x8dd9, 0x8ddc, 0x8de0, 0x8de1, 0x8de2, 0x8de5, + 0x8de6, 0x8de7, 0x8de9, 0x8ded, 0x8dee, 0x8df0, 0x8df1, 0x8df2, + 0x8df4, 0x8df6, 0x8dfc, 0x8dfe, 0x8dff, 0x8e00, 0x8e01, 0x8e02, + 0x8e03, 0x8e04, 0x8e06, 0x8e07, 0x8e08, 0x8e0b, 0x8e0d, 0x8e0e, + 0x8e10, 0x8e11, 0x8e12, 0x8e13, 0x8e15, 0x8e16, 0x8e17, 0x8e18, + 0x8e19, 0x8e1a, 0x8e1b, 0x8e1c, 0x8e20, 0x8e21, 0x8e24, 0x8e25, + 0x8e26, 0x8e27, 0x8e28, 0x8e2b, 0x8e2d, 0x8e30, 0x8e32, 0x8e33, + 0x8e34, 0x8e36, 0x8e37, 0x8e38, 0x8e3b, 0x8e3c, 0x8e3e, 0x8e3f, + 0x8e43, 0x8e45, 0x8e46, 0x8e4c, 0x8e4d, 0x8e4e, 0x8e4f, 0x8e50, + 0x8e53, 0x8e54, 0x8e55, 0x8e56, 0x8e57, 0x8e58, 0x8e5a, 0x8e5b, + 0x8e5c, 0x8e5d, 0x8e5e, 0x8e5f, 0x8e60, 0x8e61, 0x8e62, 0x8e63, + 0x8e64, 0x8e65, 0x8e67, 0x8e68, 0x8e6a, 0x8e6b, 0x8e6e, 0x8e71, + 0x90b8, 0x90b0, 0x90cf, 0x90c5, 0x90be, 0x90d0, 0x90c4, 0x90c7, + 0x90d3, 0x90e6, 0x90e2, 0x90dc, 0x90d7, 0x90db, 0x90eb, 0x90ef, + 0x90fe, 0x9104, 0x9122, 0x911e, 0x9123, 0x9131, 0x912f, 0x9139, + 0x9143, 0x9146, 0x520d, 0x5942, 0x52a2, 0x52ac, 0x52ad, 0x52be, + 0x54ff, 0x52d0, 0x52d6, 0x52f0, 0x53df, 0x71ee, 0x77cd, 0x5ef4, + 0x51f5, 0x51fc, 0x9b2f, 0x53b6, 0x5f01, 0x755a, 0x5def, 0x574c, + 0x57a9, 0x57a1, 0x587e, 0x58bc, 0x58c5, 0x58d1, 0x5729, 0x572c, + 0x572a, 0x5733, 0x5739, 0x572e, 0x572f, 0x575c, 0x573b, 0x5742, + 0x5769, 0x5785, 0x576b, 0x5786, 0x577c, 0x577b, 0x5768, 0x576d, + 0x5776, 0x5773, 0x57ad, 0x57a4, 0x578c, 0x57b2, 0x57cf, 0x57a7, + 0x57b4, 0x5793, 0x57a0, 0x57d5, 0x57d8, 0x57da, 0x57d9, 0x57d2, + 0x57b8, 0x57f4, 0x57ef, 0x57f8, 0x57e4, 0x57dd, + /* 0xdc */ + 0x8e73, 0x8e75, 0x8e77, 0x8e78, 0x8e79, 0x8e7a, 0x8e7b, 0x8e7d, + 0x8e7e, 0x8e80, 0x8e82, 0x8e83, 0x8e84, 0x8e86, 0x8e88, 0x8e89, + 0x8e8a, 0x8e8b, 0x8e8c, 0x8e8d, 0x8e8e, 0x8e91, 0x8e92, 0x8e93, + 0x8e95, 0x8e96, 0x8e97, 0x8e98, 0x8e99, 0x8e9a, 0x8e9b, 0x8e9d, + 0x8e9f, 0x8ea0, 0x8ea1, 0x8ea2, 0x8ea3, 0x8ea4, 0x8ea5, 0x8ea6, + 0x8ea7, 0x8ea8, 0x8ea9, 0x8eaa, 0x8ead, 0x8eae, 0x8eb0, 0x8eb1, + 0x8eb3, 0x8eb4, 0x8eb5, 0x8eb6, 0x8eb7, 0x8eb8, 0x8eb9, 0x8ebb, + 0x8ebc, 0x8ebd, 0x8ebe, 0x8ebf, 0x8ec0, 0x8ec1, 0x8ec2, 0x8ec3, + 0x8ec4, 0x8ec5, 0x8ec6, 0x8ec7, 0x8ec8, 0x8ec9, 0x8eca, 0x8ecb, + 0x8ecc, 0x8ecd, 0x8ecf, 0x8ed0, 0x8ed1, 0x8ed2, 0x8ed3, 0x8ed4, + 0x8ed5, 0x8ed6, 0x8ed7, 0x8ed8, 0x8ed9, 0x8eda, 0x8edb, 0x8edc, + 0x8edd, 0x8ede, 0x8edf, 0x8ee0, 0x8ee1, 0x8ee2, 0x8ee3, 0x8ee4, + 0x580b, 0x580d, 0x57fd, 0x57ed, 0x5800, 0x581e, 0x5819, 0x5844, + 0x5820, 0x5865, 0x586c, 0x5881, 0x5889, 0x589a, 0x5880, 0x99a8, + 0x9f19, 0x61ff, 0x8279, 0x827d, 0x827f, 0x828f, 0x828a, 0x82a8, + 0x8284, 0x828e, 0x8291, 0x8297, 0x8299, 0x82ab, 0x82b8, 0x82be, + 0x82b0, 0x82c8, 0x82ca, 0x82e3, 0x8298, 0x82b7, 0x82ae, 0x82cb, + 0x82cc, 0x82c1, 0x82a9, 0x82b4, 0x82a1, 0x82aa, 0x829f, 0x82c4, + 0x82ce, 0x82a4, 0x82e1, 0x8309, 0x82f7, 0x82e4, 0x830f, 0x8307, + 0x82dc, 0x82f4, 0x82d2, 0x82d8, 0x830c, 0x82fb, 0x82d3, 0x8311, + 0x831a, 0x8306, 0x8314, 0x8315, 0x82e0, 0x82d5, 0x831c, 0x8351, + 0x835b, 0x835c, 0x8308, 0x8392, 0x833c, 0x8334, 0x8331, 0x839b, + 0x835e, 0x832f, 0x834f, 0x8347, 0x8343, 0x835f, 0x8340, 0x8317, + 0x8360, 0x832d, 0x833a, 0x8333, 0x8366, 0x8365, + /* 0xdd */ + 0x8ee5, 0x8ee6, 0x8ee7, 0x8ee8, 0x8ee9, 0x8eea, 0x8eeb, 0x8eec, + 0x8eed, 0x8eee, 0x8eef, 0x8ef0, 0x8ef1, 0x8ef2, 0x8ef3, 0x8ef4, + 0x8ef5, 0x8ef6, 0x8ef7, 0x8ef8, 0x8ef9, 0x8efa, 0x8efb, 0x8efc, + 0x8efd, 0x8efe, 0x8eff, 0x8f00, 0x8f01, 0x8f02, 0x8f03, 0x8f04, + 0x8f05, 0x8f06, 0x8f07, 0x8f08, 0x8f09, 0x8f0a, 0x8f0b, 0x8f0c, + 0x8f0d, 0x8f0e, 0x8f0f, 0x8f10, 0x8f11, 0x8f12, 0x8f13, 0x8f14, + 0x8f15, 0x8f16, 0x8f17, 0x8f18, 0x8f19, 0x8f1a, 0x8f1b, 0x8f1c, + 0x8f1d, 0x8f1e, 0x8f1f, 0x8f20, 0x8f21, 0x8f22, 0x8f23, 0x8f24, + 0x8f25, 0x8f26, 0x8f27, 0x8f28, 0x8f29, 0x8f2a, 0x8f2b, 0x8f2c, + 0x8f2d, 0x8f2e, 0x8f2f, 0x8f30, 0x8f31, 0x8f32, 0x8f33, 0x8f34, + 0x8f35, 0x8f36, 0x8f37, 0x8f38, 0x8f39, 0x8f3a, 0x8f3b, 0x8f3c, + 0x8f3d, 0x8f3e, 0x8f3f, 0x8f40, 0x8f41, 0x8f42, 0x8f43, 0x8f44, + 0x8368, 0x831b, 0x8369, 0x836c, 0x836a, 0x836d, 0x836e, 0x83b0, + 0x8378, 0x83b3, 0x83b4, 0x83a0, 0x83aa, 0x8393, 0x839c, 0x8385, + 0x837c, 0x83b6, 0x83a9, 0x837d, 0x83b8, 0x837b, 0x8398, 0x839e, + 0x83a8, 0x83ba, 0x83bc, 0x83c1, 0x8401, 0x83e5, 0x83d8, 0x5807, + 0x8418, 0x840b, 0x83dd, 0x83fd, 0x83d6, 0x841c, 0x8438, 0x8411, + 0x8406, 0x83d4, 0x83df, 0x840f, 0x8403, 0x83f8, 0x83f9, 0x83ea, + 0x83c5, 0x83c0, 0x8426, 0x83f0, 0x83e1, 0x845c, 0x8451, 0x845a, + 0x8459, 0x8473, 0x8487, 0x8488, 0x847a, 0x8489, 0x8478, 0x843c, + 0x8446, 0x8469, 0x8476, 0x848c, 0x848e, 0x8431, 0x846d, 0x84c1, + 0x84cd, 0x84d0, 0x84e6, 0x84bd, 0x84d3, 0x84ca, 0x84bf, 0x84ba, + 0x84e0, 0x84a1, 0x84b9, 0x84b4, 0x8497, 0x84e5, 0x84e3, 0x850c, + 0x750d, 0x8538, 0x84f0, 0x8539, 0x851f, 0x853a, + /* 0xde */ + 0x8f45, 0x8f46, 0x8f47, 0x8f48, 0x8f49, 0x8f4a, 0x8f4b, 0x8f4c, + 0x8f4d, 0x8f4e, 0x8f4f, 0x8f50, 0x8f51, 0x8f52, 0x8f53, 0x8f54, + 0x8f55, 0x8f56, 0x8f57, 0x8f58, 0x8f59, 0x8f5a, 0x8f5b, 0x8f5c, + 0x8f5d, 0x8f5e, 0x8f5f, 0x8f60, 0x8f61, 0x8f62, 0x8f63, 0x8f64, + 0x8f65, 0x8f6a, 0x8f80, 0x8f8c, 0x8f92, 0x8f9d, 0x8fa0, 0x8fa1, + 0x8fa2, 0x8fa4, 0x8fa5, 0x8fa6, 0x8fa7, 0x8faa, 0x8fac, 0x8fad, + 0x8fae, 0x8faf, 0x8fb2, 0x8fb3, 0x8fb4, 0x8fb5, 0x8fb7, 0x8fb8, + 0x8fba, 0x8fbb, 0x8fbc, 0x8fbf, 0x8fc0, 0x8fc3, 0x8fc6, 0x8fc9, + 0x8fca, 0x8fcb, 0x8fcc, 0x8fcd, 0x8fcf, 0x8fd2, 0x8fd6, 0x8fd7, + 0x8fda, 0x8fe0, 0x8fe1, 0x8fe3, 0x8fe7, 0x8fec, 0x8fef, 0x8ff1, + 0x8ff2, 0x8ff4, 0x8ff5, 0x8ff6, 0x8ffa, 0x8ffb, 0x8ffc, 0x8ffe, + 0x8fff, 0x9007, 0x9008, 0x900c, 0x900e, 0x9013, 0x9015, 0x9018, + 0x8556, 0x853b, 0x84ff, 0x84fc, 0x8559, 0x8548, 0x8568, 0x8564, + 0x855e, 0x857a, 0x77a2, 0x8543, 0x8572, 0x857b, 0x85a4, 0x85a8, + 0x8587, 0x858f, 0x8579, 0x85ae, 0x859c, 0x8585, 0x85b9, 0x85b7, + 0x85b0, 0x85d3, 0x85c1, 0x85dc, 0x85ff, 0x8627, 0x8605, 0x8629, + 0x8616, 0x863c, 0x5efe, 0x5f08, 0x593c, 0x5941, 0x8037, 0x5955, + 0x595a, 0x5958, 0x530f, 0x5c22, 0x5c25, 0x5c2c, 0x5c34, 0x624c, + 0x626a, 0x629f, 0x62bb, 0x62ca, 0x62da, 0x62d7, 0x62ee, 0x6322, + 0x62f6, 0x6339, 0x634b, 0x6343, 0x63ad, 0x63f6, 0x6371, 0x637a, + 0x638e, 0x63b4, 0x636d, 0x63ac, 0x638a, 0x6369, 0x63ae, 0x63bc, + 0x63f2, 0x63f8, 0x63e0, 0x63ff, 0x63c4, 0x63de, 0x63ce, 0x6452, + 0x63c6, 0x63be, 0x6445, 0x6441, 0x640b, 0x641b, 0x6420, 0x640c, + 0x6426, 0x6421, 0x645e, 0x6484, 0x646d, 0x6496, + /* 0xdf */ + 0x9019, 0x901c, 0x9023, 0x9024, 0x9025, 0x9027, 0x9028, 0x9029, + 0x902a, 0x902b, 0x902c, 0x9030, 0x9031, 0x9032, 0x9033, 0x9034, + 0x9037, 0x9039, 0x903a, 0x903d, 0x903f, 0x9040, 0x9043, 0x9045, + 0x9046, 0x9048, 0x9049, 0x904a, 0x904b, 0x904c, 0x904e, 0x9054, + 0x9055, 0x9056, 0x9059, 0x905a, 0x905c, 0x905d, 0x905e, 0x905f, + 0x9060, 0x9061, 0x9064, 0x9066, 0x9067, 0x9069, 0x906a, 0x906b, + 0x906c, 0x906f, 0x9070, 0x9071, 0x9072, 0x9073, 0x9076, 0x9077, + 0x9078, 0x9079, 0x907a, 0x907b, 0x907c, 0x907e, 0x9081, 0x9084, + 0x9085, 0x9086, 0x9087, 0x9089, 0x908a, 0x908c, 0x908d, 0x908e, + 0x908f, 0x9090, 0x9092, 0x9094, 0x9096, 0x9098, 0x909a, 0x909c, + 0x909e, 0x909f, 0x90a0, 0x90a4, 0x90a5, 0x90a7, 0x90a8, 0x90a9, + 0x90ab, 0x90ad, 0x90b2, 0x90b7, 0x90bc, 0x90bd, 0x90bf, 0x90c0, + 0x647a, 0x64b7, 0x64b8, 0x6499, 0x64ba, 0x64c0, 0x64d0, 0x64d7, + 0x64e4, 0x64e2, 0x6509, 0x6525, 0x652e, 0x5f0b, 0x5fd2, 0x7519, + 0x5f11, 0x535f, 0x53f1, 0x53fd, 0x53e9, 0x53e8, 0x53fb, 0x5412, + 0x5416, 0x5406, 0x544b, 0x5452, 0x5453, 0x5454, 0x5456, 0x5443, + 0x5421, 0x5457, 0x5459, 0x5423, 0x5432, 0x5482, 0x5494, 0x5477, + 0x5471, 0x5464, 0x549a, 0x549b, 0x5484, 0x5476, 0x5466, 0x549d, + 0x54d0, 0x54ad, 0x54c2, 0x54b4, 0x54d2, 0x54a7, 0x54a6, 0x54d3, + 0x54d4, 0x5472, 0x54a3, 0x54d5, 0x54bb, 0x54bf, 0x54cc, 0x54d9, + 0x54da, 0x54dc, 0x54a9, 0x54aa, 0x54a4, 0x54dd, 0x54cf, 0x54de, + 0x551b, 0x54e7, 0x5520, 0x54fd, 0x5514, 0x54f3, 0x5522, 0x5523, + 0x550f, 0x5511, 0x5527, 0x552a, 0x5567, 0x558f, 0x55b5, 0x5549, + 0x556d, 0x5541, 0x5555, 0x553f, 0x5550, 0x553c, + /* 0xe0 */ + 0x90c2, 0x90c3, 0x90c6, 0x90c8, 0x90c9, 0x90cb, 0x90cc, 0x90cd, + 0x90d2, 0x90d4, 0x90d5, 0x90d6, 0x90d8, 0x90d9, 0x90da, 0x90de, + 0x90df, 0x90e0, 0x90e3, 0x90e4, 0x90e5, 0x90e9, 0x90ea, 0x90ec, + 0x90ee, 0x90f0, 0x90f1, 0x90f2, 0x90f3, 0x90f5, 0x90f6, 0x90f7, + 0x90f9, 0x90fa, 0x90fb, 0x90fc, 0x90ff, 0x9100, 0x9101, 0x9103, + 0x9105, 0x9106, 0x9107, 0x9108, 0x9109, 0x910a, 0x910b, 0x910c, + 0x910d, 0x910e, 0x910f, 0x9110, 0x9111, 0x9112, 0x9113, 0x9114, + 0x9115, 0x9116, 0x9117, 0x9118, 0x911a, 0x911b, 0x911c, 0x911d, + 0x911f, 0x9120, 0x9121, 0x9124, 0x9125, 0x9126, 0x9127, 0x9128, + 0x9129, 0x912a, 0x912b, 0x912c, 0x912d, 0x912e, 0x9130, 0x9132, + 0x9133, 0x9134, 0x9135, 0x9136, 0x9137, 0x9138, 0x913a, 0x913b, + 0x913c, 0x913d, 0x913e, 0x913f, 0x9140, 0x9141, 0x9142, 0x9144, + 0x5537, 0x5556, 0x5575, 0x5576, 0x5577, 0x5533, 0x5530, 0x555c, + 0x558b, 0x55d2, 0x5583, 0x55b1, 0x55b9, 0x5588, 0x5581, 0x559f, + 0x557e, 0x55d6, 0x5591, 0x557b, 0x55df, 0x55bd, 0x55be, 0x5594, + 0x5599, 0x55ea, 0x55f7, 0x55c9, 0x561f, 0x55d1, 0x55eb, 0x55ec, + 0x55d4, 0x55e6, 0x55dd, 0x55c4, 0x55ef, 0x55e5, 0x55f2, 0x55f3, + 0x55cc, 0x55cd, 0x55e8, 0x55f5, 0x55e4, 0x8f94, 0x561e, 0x5608, + 0x560c, 0x5601, 0x5624, 0x5623, 0x55fe, 0x5600, 0x5627, 0x562d, + 0x5658, 0x5639, 0x5657, 0x562c, 0x564d, 0x5662, 0x5659, 0x565c, + 0x564c, 0x5654, 0x5686, 0x5664, 0x5671, 0x566b, 0x567b, 0x567c, + 0x5685, 0x5693, 0x56af, 0x56d4, 0x56d7, 0x56dd, 0x56e1, 0x56f5, + 0x56eb, 0x56f9, 0x56ff, 0x5704, 0x570a, 0x5709, 0x571c, 0x5e0f, + 0x5e19, 0x5e14, 0x5e11, 0x5e31, 0x5e3b, 0x5e3c, + /* 0xe1 */ + 0x9145, 0x9147, 0x9148, 0x9151, 0x9153, 0x9154, 0x9155, 0x9156, + 0x9158, 0x9159, 0x915b, 0x915c, 0x915f, 0x9160, 0x9166, 0x9167, + 0x9168, 0x916b, 0x916d, 0x9173, 0x917a, 0x917b, 0x917c, 0x9180, + 0x9181, 0x9182, 0x9183, 0x9184, 0x9186, 0x9188, 0x918a, 0x918e, + 0x918f, 0x9193, 0x9194, 0x9195, 0x9196, 0x9197, 0x9198, 0x9199, + 0x919c, 0x919d, 0x919e, 0x919f, 0x91a0, 0x91a1, 0x91a4, 0x91a5, + 0x91a6, 0x91a7, 0x91a8, 0x91a9, 0x91ab, 0x91ac, 0x91b0, 0x91b1, + 0x91b2, 0x91b3, 0x91b6, 0x91b7, 0x91b8, 0x91b9, 0x91bb, 0x91bc, + 0x91bd, 0x91be, 0x91bf, 0x91c0, 0x91c1, 0x91c2, 0x91c3, 0x91c4, + 0x91c5, 0x91c6, 0x91c8, 0x91cb, 0x91d0, 0x91d2, 0x91d3, 0x91d4, + 0x91d5, 0x91d6, 0x91d7, 0x91d8, 0x91d9, 0x91da, 0x91db, 0x91dd, + 0x91de, 0x91df, 0x91e0, 0x91e1, 0x91e2, 0x91e3, 0x91e4, 0x91e5, + 0x5e37, 0x5e44, 0x5e54, 0x5e5b, 0x5e5e, 0x5e61, 0x5c8c, 0x5c7a, + 0x5c8d, 0x5c90, 0x5c96, 0x5c88, 0x5c98, 0x5c99, 0x5c91, 0x5c9a, + 0x5c9c, 0x5cb5, 0x5ca2, 0x5cbd, 0x5cac, 0x5cab, 0x5cb1, 0x5ca3, + 0x5cc1, 0x5cb7, 0x5cc4, 0x5cd2, 0x5ce4, 0x5ccb, 0x5ce5, 0x5d02, + 0x5d03, 0x5d27, 0x5d26, 0x5d2e, 0x5d24, 0x5d1e, 0x5d06, 0x5d1b, + 0x5d58, 0x5d3e, 0x5d34, 0x5d3d, 0x5d6c, 0x5d5b, 0x5d6f, 0x5d5d, + 0x5d6b, 0x5d4b, 0x5d4a, 0x5d69, 0x5d74, 0x5d82, 0x5d99, 0x5d9d, + 0x8c73, 0x5db7, 0x5dc5, 0x5f73, 0x5f77, 0x5f82, 0x5f87, 0x5f89, + 0x5f8c, 0x5f95, 0x5f99, 0x5f9c, 0x5fa8, 0x5fad, 0x5fb5, 0x5fbc, + 0x8862, 0x5f61, 0x72ad, 0x72b0, 0x72b4, 0x72b7, 0x72b8, 0x72c3, + 0x72c1, 0x72ce, 0x72cd, 0x72d2, 0x72e8, 0x72ef, 0x72e9, 0x72f2, + 0x72f4, 0x72f7, 0x7301, 0x72f3, 0x7303, 0x72fa, + /* 0xe2 */ + 0x91e6, 0x91e7, 0x91e8, 0x91e9, 0x91ea, 0x91eb, 0x91ec, 0x91ed, + 0x91ee, 0x91ef, 0x91f0, 0x91f1, 0x91f2, 0x91f3, 0x91f4, 0x91f5, + 0x91f6, 0x91f7, 0x91f8, 0x91f9, 0x91fa, 0x91fb, 0x91fc, 0x91fd, + 0x91fe, 0x91ff, 0x9200, 0x9201, 0x9202, 0x9203, 0x9204, 0x9205, + 0x9206, 0x9207, 0x9208, 0x9209, 0x920a, 0x920b, 0x920c, 0x920d, + 0x920e, 0x920f, 0x9210, 0x9211, 0x9212, 0x9213, 0x9214, 0x9215, + 0x9216, 0x9217, 0x9218, 0x9219, 0x921a, 0x921b, 0x921c, 0x921d, + 0x921e, 0x921f, 0x9220, 0x9221, 0x9222, 0x9223, 0x9224, 0x9225, + 0x9226, 0x9227, 0x9228, 0x9229, 0x922a, 0x922b, 0x922c, 0x922d, + 0x922e, 0x922f, 0x9230, 0x9231, 0x9232, 0x9233, 0x9234, 0x9235, + 0x9236, 0x9237, 0x9238, 0x9239, 0x923a, 0x923b, 0x923c, 0x923d, + 0x923e, 0x923f, 0x9240, 0x9241, 0x9242, 0x9243, 0x9244, 0x9245, + 0x72fb, 0x7317, 0x7313, 0x7321, 0x730a, 0x731e, 0x731d, 0x7315, + 0x7322, 0x7339, 0x7325, 0x732c, 0x7338, 0x7331, 0x7350, 0x734d, + 0x7357, 0x7360, 0x736c, 0x736f, 0x737e, 0x821b, 0x5925, 0x98e7, + 0x5924, 0x5902, 0x9963, 0x9967, 0x9968, 0x9969, 0x996a, 0x996b, + 0x996c, 0x9974, 0x9977, 0x997d, 0x9980, 0x9984, 0x9987, 0x998a, + 0x998d, 0x9990, 0x9991, 0x9993, 0x9994, 0x9995, 0x5e80, 0x5e91, + 0x5e8b, 0x5e96, 0x5ea5, 0x5ea0, 0x5eb9, 0x5eb5, 0x5ebe, 0x5eb3, + 0x8d53, 0x5ed2, 0x5ed1, 0x5edb, 0x5ee8, 0x5eea, 0x81ba, 0x5fc4, + 0x5fc9, 0x5fd6, 0x5fcf, 0x6003, 0x5fee, 0x6004, 0x5fe1, 0x5fe4, + 0x5ffe, 0x6005, 0x6006, 0x5fea, 0x5fed, 0x5ff8, 0x6019, 0x6035, + 0x6026, 0x601b, 0x600f, 0x600d, 0x6029, 0x602b, 0x600a, 0x603f, + 0x6021, 0x6078, 0x6079, 0x607b, 0x607a, 0x6042, + /* 0xe3 */ + 0x9246, 0x9247, 0x9248, 0x9249, 0x924a, 0x924b, 0x924c, 0x924d, + 0x924e, 0x924f, 0x9250, 0x9251, 0x9252, 0x9253, 0x9254, 0x9255, + 0x9256, 0x9257, 0x9258, 0x9259, 0x925a, 0x925b, 0x925c, 0x925d, + 0x925e, 0x925f, 0x9260, 0x9261, 0x9262, 0x9263, 0x9264, 0x9265, + 0x9266, 0x9267, 0x9268, 0x9269, 0x926a, 0x926b, 0x926c, 0x926d, + 0x926e, 0x926f, 0x9270, 0x9271, 0x9272, 0x9273, 0x9275, 0x9276, + 0x9277, 0x9278, 0x9279, 0x927a, 0x927b, 0x927c, 0x927d, 0x927e, + 0x927f, 0x9280, 0x9281, 0x9282, 0x9283, 0x9284, 0x9285, 0x9286, + 0x9287, 0x9288, 0x9289, 0x928a, 0x928b, 0x928c, 0x928d, 0x928f, + 0x9290, 0x9291, 0x9292, 0x9293, 0x9294, 0x9295, 0x9296, 0x9297, + 0x9298, 0x9299, 0x929a, 0x929b, 0x929c, 0x929d, 0x929e, 0x929f, + 0x92a0, 0x92a1, 0x92a2, 0x92a3, 0x92a4, 0x92a5, 0x92a6, 0x92a7, + 0x606a, 0x607d, 0x6096, 0x609a, 0x60ad, 0x609d, 0x6083, 0x6092, + 0x608c, 0x609b, 0x60ec, 0x60bb, 0x60b1, 0x60dd, 0x60d8, 0x60c6, + 0x60da, 0x60b4, 0x6120, 0x6126, 0x6115, 0x6123, 0x60f4, 0x6100, + 0x610e, 0x612b, 0x614a, 0x6175, 0x61ac, 0x6194, 0x61a7, 0x61b7, + 0x61d4, 0x61f5, 0x5fdd, 0x96b3, 0x95e9, 0x95eb, 0x95f1, 0x95f3, + 0x95f5, 0x95f6, 0x95fc, 0x95fe, 0x9603, 0x9604, 0x9606, 0x9608, + 0x960a, 0x960b, 0x960c, 0x960d, 0x960f, 0x9612, 0x9615, 0x9616, + 0x9617, 0x9619, 0x961a, 0x4e2c, 0x723f, 0x6215, 0x6c35, 0x6c54, + 0x6c5c, 0x6c4a, 0x6ca3, 0x6c85, 0x6c90, 0x6c94, 0x6c8c, 0x6c68, + 0x6c69, 0x6c74, 0x6c76, 0x6c86, 0x6ca9, 0x6cd0, 0x6cd4, 0x6cad, + 0x6cf7, 0x6cf8, 0x6cf1, 0x6cd7, 0x6cb2, 0x6ce0, 0x6cd6, 0x6cfa, + 0x6ceb, 0x6cee, 0x6cb1, 0x6cd3, 0x6cef, 0x6cfe, + /* 0xe4 */ + 0x92a8, 0x92a9, 0x92aa, 0x92ab, 0x92ac, 0x92ad, 0x92af, 0x92b0, + 0x92b1, 0x92b2, 0x92b3, 0x92b4, 0x92b5, 0x92b6, 0x92b7, 0x92b8, + 0x92b9, 0x92ba, 0x92bb, 0x92bc, 0x92bd, 0x92be, 0x92bf, 0x92c0, + 0x92c1, 0x92c2, 0x92c3, 0x92c4, 0x92c5, 0x92c6, 0x92c7, 0x92c9, + 0x92ca, 0x92cb, 0x92cc, 0x92cd, 0x92ce, 0x92cf, 0x92d0, 0x92d1, + 0x92d2, 0x92d3, 0x92d4, 0x92d5, 0x92d6, 0x92d7, 0x92d8, 0x92d9, + 0x92da, 0x92db, 0x92dc, 0x92dd, 0x92de, 0x92df, 0x92e0, 0x92e1, + 0x92e2, 0x92e3, 0x92e4, 0x92e5, 0x92e6, 0x92e7, 0x92e8, 0x92e9, + 0x92ea, 0x92eb, 0x92ec, 0x92ed, 0x92ee, 0x92ef, 0x92f0, 0x92f1, + 0x92f2, 0x92f3, 0x92f4, 0x92f5, 0x92f6, 0x92f7, 0x92f8, 0x92f9, + 0x92fa, 0x92fb, 0x92fc, 0x92fd, 0x92fe, 0x92ff, 0x9300, 0x9301, + 0x9302, 0x9303, 0x9304, 0x9305, 0x9306, 0x9307, 0x9308, 0x9309, + 0x6d39, 0x6d27, 0x6d0c, 0x6d43, 0x6d48, 0x6d07, 0x6d04, 0x6d19, + 0x6d0e, 0x6d2b, 0x6d4d, 0x6d2e, 0x6d35, 0x6d1a, 0x6d4f, 0x6d52, + 0x6d54, 0x6d33, 0x6d91, 0x6d6f, 0x6d9e, 0x6da0, 0x6d5e, 0x6d93, + 0x6d94, 0x6d5c, 0x6d60, 0x6d7c, 0x6d63, 0x6e1a, 0x6dc7, 0x6dc5, + 0x6dde, 0x6e0e, 0x6dbf, 0x6de0, 0x6e11, 0x6de6, 0x6ddd, 0x6dd9, + 0x6e16, 0x6dab, 0x6e0c, 0x6dae, 0x6e2b, 0x6e6e, 0x6e4e, 0x6e6b, + 0x6eb2, 0x6e5f, 0x6e86, 0x6e53, 0x6e54, 0x6e32, 0x6e25, 0x6e44, + 0x6edf, 0x6eb1, 0x6e98, 0x6ee0, 0x6f2d, 0x6ee2, 0x6ea5, 0x6ea7, + 0x6ebd, 0x6ebb, 0x6eb7, 0x6ed7, 0x6eb4, 0x6ecf, 0x6e8f, 0x6ec2, + 0x6e9f, 0x6f62, 0x6f46, 0x6f47, 0x6f24, 0x6f15, 0x6ef9, 0x6f2f, + 0x6f36, 0x6f4b, 0x6f74, 0x6f2a, 0x6f09, 0x6f29, 0x6f89, 0x6f8d, + 0x6f8c, 0x6f78, 0x6f72, 0x6f7c, 0x6f7a, 0x6fd1, + /* 0xe5 */ + 0x930a, 0x930b, 0x930c, 0x930d, 0x930e, 0x930f, 0x9310, 0x9311, + 0x9312, 0x9313, 0x9314, 0x9315, 0x9316, 0x9317, 0x9318, 0x9319, + 0x931a, 0x931b, 0x931c, 0x931d, 0x931e, 0x931f, 0x9320, 0x9321, + 0x9322, 0x9323, 0x9324, 0x9325, 0x9326, 0x9327, 0x9328, 0x9329, + 0x932a, 0x932b, 0x932c, 0x932d, 0x932e, 0x932f, 0x9330, 0x9331, + 0x9332, 0x9333, 0x9334, 0x9335, 0x9336, 0x9337, 0x9338, 0x9339, + 0x933a, 0x933b, 0x933c, 0x933d, 0x933f, 0x9340, 0x9341, 0x9342, + 0x9343, 0x9344, 0x9345, 0x9346, 0x9347, 0x9348, 0x9349, 0x934a, + 0x934b, 0x934c, 0x934d, 0x934e, 0x934f, 0x9350, 0x9351, 0x9352, + 0x9353, 0x9354, 0x9355, 0x9356, 0x9357, 0x9358, 0x9359, 0x935a, + 0x935b, 0x935c, 0x935d, 0x935e, 0x935f, 0x9360, 0x9361, 0x9362, + 0x9363, 0x9364, 0x9365, 0x9366, 0x9367, 0x9368, 0x9369, 0x936b, + 0x6fc9, 0x6fa7, 0x6fb9, 0x6fb6, 0x6fc2, 0x6fe1, 0x6fee, 0x6fde, + 0x6fe0, 0x6fef, 0x701a, 0x7023, 0x701b, 0x7039, 0x7035, 0x704f, + 0x705e, 0x5b80, 0x5b84, 0x5b95, 0x5b93, 0x5ba5, 0x5bb8, 0x752f, + 0x9a9e, 0x6434, 0x5be4, 0x5bee, 0x8930, 0x5bf0, 0x8e47, 0x8b07, + 0x8fb6, 0x8fd3, 0x8fd5, 0x8fe5, 0x8fee, 0x8fe4, 0x8fe9, 0x8fe6, + 0x8ff3, 0x8fe8, 0x9005, 0x9004, 0x900b, 0x9026, 0x9011, 0x900d, + 0x9016, 0x9021, 0x9035, 0x9036, 0x902d, 0x902f, 0x9044, 0x9051, + 0x9052, 0x9050, 0x9068, 0x9058, 0x9062, 0x905b, 0x66b9, 0x9074, + 0x907d, 0x9082, 0x9088, 0x9083, 0x908b, 0x5f50, 0x5f57, 0x5f56, + 0x5f58, 0x5c3b, 0x54ab, 0x5c50, 0x5c59, 0x5b71, 0x5c63, 0x5c66, + 0x7fbc, 0x5f2a, 0x5f29, 0x5f2d, 0x8274, 0x5f3c, 0x9b3b, 0x5c6e, + 0x5981, 0x5983, 0x598d, 0x59a9, 0x59aa, 0x59a3, + /* 0xe6 */ + 0x936c, 0x936d, 0x936e, 0x936f, 0x9370, 0x9371, 0x9372, 0x9373, + 0x9374, 0x9375, 0x9376, 0x9377, 0x9378, 0x9379, 0x937a, 0x937b, + 0x937c, 0x937d, 0x937e, 0x937f, 0x9380, 0x9381, 0x9382, 0x9383, + 0x9384, 0x9385, 0x9386, 0x9387, 0x9388, 0x9389, 0x938a, 0x938b, + 0x938c, 0x938d, 0x938e, 0x9390, 0x9391, 0x9392, 0x9393, 0x9394, + 0x9395, 0x9396, 0x9397, 0x9398, 0x9399, 0x939a, 0x939b, 0x939c, + 0x939d, 0x939e, 0x939f, 0x93a0, 0x93a1, 0x93a2, 0x93a3, 0x93a4, + 0x93a5, 0x93a6, 0x93a7, 0x93a8, 0x93a9, 0x93aa, 0x93ab, 0x93ac, + 0x93ad, 0x93ae, 0x93af, 0x93b0, 0x93b1, 0x93b2, 0x93b3, 0x93b4, + 0x93b5, 0x93b6, 0x93b7, 0x93b8, 0x93b9, 0x93ba, 0x93bb, 0x93bc, + 0x93bd, 0x93be, 0x93bf, 0x93c0, 0x93c1, 0x93c2, 0x93c3, 0x93c4, + 0x93c5, 0x93c6, 0x93c7, 0x93c8, 0x93c9, 0x93cb, 0x93cc, 0x93cd, + 0x5997, 0x59ca, 0x59ab, 0x599e, 0x59a4, 0x59d2, 0x59b2, 0x59af, + 0x59d7, 0x59be, 0x5a05, 0x5a06, 0x59dd, 0x5a08, 0x59e3, 0x59d8, + 0x59f9, 0x5a0c, 0x5a09, 0x5a32, 0x5a34, 0x5a11, 0x5a23, 0x5a13, + 0x5a40, 0x5a67, 0x5a4a, 0x5a55, 0x5a3c, 0x5a62, 0x5a75, 0x80ec, + 0x5aaa, 0x5a9b, 0x5a77, 0x5a7a, 0x5abe, 0x5aeb, 0x5ab2, 0x5ad2, + 0x5ad4, 0x5ab8, 0x5ae0, 0x5ae3, 0x5af1, 0x5ad6, 0x5ae6, 0x5ad8, + 0x5adc, 0x5b09, 0x5b17, 0x5b16, 0x5b32, 0x5b37, 0x5b40, 0x5c15, + 0x5c1c, 0x5b5a, 0x5b65, 0x5b73, 0x5b51, 0x5b53, 0x5b62, 0x9a75, + 0x9a77, 0x9a78, 0x9a7a, 0x9a7f, 0x9a7d, 0x9a80, 0x9a81, 0x9a85, + 0x9a88, 0x9a8a, 0x9a90, 0x9a92, 0x9a93, 0x9a96, 0x9a98, 0x9a9b, + 0x9a9c, 0x9a9d, 0x9a9f, 0x9aa0, 0x9aa2, 0x9aa3, 0x9aa5, 0x9aa7, + 0x7e9f, 0x7ea1, 0x7ea3, 0x7ea5, 0x7ea8, 0x7ea9, + /* 0xe7 */ + 0x93ce, 0x93cf, 0x93d0, 0x93d1, 0x93d2, 0x93d3, 0x93d4, 0x93d5, + 0x93d7, 0x93d8, 0x93d9, 0x93da, 0x93db, 0x93dc, 0x93dd, 0x93de, + 0x93df, 0x93e0, 0x93e1, 0x93e2, 0x93e3, 0x93e4, 0x93e5, 0x93e6, + 0x93e7, 0x93e8, 0x93e9, 0x93ea, 0x93eb, 0x93ec, 0x93ed, 0x93ee, + 0x93ef, 0x93f0, 0x93f1, 0x93f2, 0x93f3, 0x93f4, 0x93f5, 0x93f6, + 0x93f7, 0x93f8, 0x93f9, 0x93fa, 0x93fb, 0x93fc, 0x93fd, 0x93fe, + 0x93ff, 0x9400, 0x9401, 0x9402, 0x9403, 0x9404, 0x9405, 0x9406, + 0x9407, 0x9408, 0x9409, 0x940a, 0x940b, 0x940c, 0x940d, 0x940e, + 0x940f, 0x9410, 0x9411, 0x9412, 0x9413, 0x9414, 0x9415, 0x9416, + 0x9417, 0x9418, 0x9419, 0x941a, 0x941b, 0x941c, 0x941d, 0x941e, + 0x941f, 0x9420, 0x9421, 0x9422, 0x9423, 0x9424, 0x9425, 0x9426, + 0x9427, 0x9428, 0x9429, 0x942a, 0x942b, 0x942c, 0x942d, 0x942e, + 0x7ead, 0x7eb0, 0x7ebe, 0x7ec0, 0x7ec1, 0x7ec2, 0x7ec9, 0x7ecb, + 0x7ecc, 0x7ed0, 0x7ed4, 0x7ed7, 0x7edb, 0x7ee0, 0x7ee1, 0x7ee8, + 0x7eeb, 0x7eee, 0x7eef, 0x7ef1, 0x7ef2, 0x7f0d, 0x7ef6, 0x7efa, + 0x7efb, 0x7efe, 0x7f01, 0x7f02, 0x7f03, 0x7f07, 0x7f08, 0x7f0b, + 0x7f0c, 0x7f0f, 0x7f11, 0x7f12, 0x7f17, 0x7f19, 0x7f1c, 0x7f1b, + 0x7f1f, 0x7f21, 0x7f22, 0x7f23, 0x7f24, 0x7f25, 0x7f26, 0x7f27, + 0x7f2a, 0x7f2b, 0x7f2c, 0x7f2d, 0x7f2f, 0x7f30, 0x7f31, 0x7f32, + 0x7f33, 0x7f35, 0x5e7a, 0x757f, 0x5ddb, 0x753e, 0x9095, 0x738e, + 0x7391, 0x73ae, 0x73a2, 0x739f, 0x73cf, 0x73c2, 0x73d1, 0x73b7, + 0x73b3, 0x73c0, 0x73c9, 0x73c8, 0x73e5, 0x73d9, 0x987c, 0x740a, + 0x73e9, 0x73e7, 0x73de, 0x73ba, 0x73f2, 0x740f, 0x742a, 0x745b, + 0x7426, 0x7425, 0x7428, 0x7430, 0x742e, 0x742c, + /* 0xe8 */ + 0x942f, 0x9430, 0x9431, 0x9432, 0x9433, 0x9434, 0x9435, 0x9436, + 0x9437, 0x9438, 0x9439, 0x943a, 0x943b, 0x943c, 0x943d, 0x943f, + 0x9440, 0x9441, 0x9442, 0x9443, 0x9444, 0x9445, 0x9446, 0x9447, + 0x9448, 0x9449, 0x944a, 0x944b, 0x944c, 0x944d, 0x944e, 0x944f, + 0x9450, 0x9451, 0x9452, 0x9453, 0x9454, 0x9455, 0x9456, 0x9457, + 0x9458, 0x9459, 0x945a, 0x945b, 0x945c, 0x945d, 0x945e, 0x945f, + 0x9460, 0x9461, 0x9462, 0x9463, 0x9464, 0x9465, 0x9466, 0x9467, + 0x9468, 0x9469, 0x946a, 0x946c, 0x946d, 0x946e, 0x946f, 0x9470, + 0x9471, 0x9472, 0x9473, 0x9474, 0x9475, 0x9476, 0x9477, 0x9478, + 0x9479, 0x947a, 0x947b, 0x947c, 0x947d, 0x947e, 0x947f, 0x9480, + 0x9481, 0x9482, 0x9483, 0x9484, 0x9491, 0x9496, 0x9498, 0x94c7, + 0x94cf, 0x94d3, 0x94d4, 0x94da, 0x94e6, 0x94fb, 0x951c, 0x9520, + 0x741b, 0x741a, 0x7441, 0x745c, 0x7457, 0x7455, 0x7459, 0x7477, + 0x746d, 0x747e, 0x749c, 0x748e, 0x7480, 0x7481, 0x7487, 0x748b, + 0x749e, 0x74a8, 0x74a9, 0x7490, 0x74a7, 0x74d2, 0x74ba, 0x97ea, + 0x97eb, 0x97ec, 0x674c, 0x6753, 0x675e, 0x6748, 0x6769, 0x67a5, + 0x6787, 0x676a, 0x6773, 0x6798, 0x67a7, 0x6775, 0x67a8, 0x679e, + 0x67ad, 0x678b, 0x6777, 0x677c, 0x67f0, 0x6809, 0x67d8, 0x680a, + 0x67e9, 0x67b0, 0x680c, 0x67d9, 0x67b5, 0x67da, 0x67b3, 0x67dd, + 0x6800, 0x67c3, 0x67b8, 0x67e2, 0x680e, 0x67c1, 0x67fd, 0x6832, + 0x6833, 0x6860, 0x6861, 0x684e, 0x6862, 0x6844, 0x6864, 0x6883, + 0x681d, 0x6855, 0x6866, 0x6841, 0x6867, 0x6840, 0x683e, 0x684a, + 0x6849, 0x6829, 0x68b5, 0x688f, 0x6874, 0x6877, 0x6893, 0x686b, + 0x68c2, 0x696e, 0x68fc, 0x691f, 0x6920, 0x68f9, + /* 0xe9 */ + 0x9527, 0x9533, 0x953d, 0x9543, 0x9548, 0x954b, 0x9555, 0x955a, + 0x9560, 0x956e, 0x9574, 0x9575, 0x9577, 0x9578, 0x9579, 0x957a, + 0x957b, 0x957c, 0x957d, 0x957e, 0x9580, 0x9581, 0x9582, 0x9583, + 0x9584, 0x9585, 0x9586, 0x9587, 0x9588, 0x9589, 0x958a, 0x958b, + 0x958c, 0x958d, 0x958e, 0x958f, 0x9590, 0x9591, 0x9592, 0x9593, + 0x9594, 0x9595, 0x9596, 0x9597, 0x9598, 0x9599, 0x959a, 0x959b, + 0x959c, 0x959d, 0x959e, 0x959f, 0x95a0, 0x95a1, 0x95a2, 0x95a3, + 0x95a4, 0x95a5, 0x95a6, 0x95a7, 0x95a8, 0x95a9, 0x95aa, 0x95ab, + 0x95ac, 0x95ad, 0x95ae, 0x95af, 0x95b0, 0x95b1, 0x95b2, 0x95b3, + 0x95b4, 0x95b5, 0x95b6, 0x95b7, 0x95b8, 0x95b9, 0x95ba, 0x95bb, + 0x95bc, 0x95bd, 0x95be, 0x95bf, 0x95c0, 0x95c1, 0x95c2, 0x95c3, + 0x95c4, 0x95c5, 0x95c6, 0x95c7, 0x95c8, 0x95c9, 0x95ca, 0x95cb, + 0x6924, 0x68f0, 0x690b, 0x6901, 0x6957, 0x68e3, 0x6910, 0x6971, + 0x6939, 0x6960, 0x6942, 0x695d, 0x6984, 0x696b, 0x6980, 0x6998, + 0x6978, 0x6934, 0x69cc, 0x6987, 0x6988, 0x69ce, 0x6989, 0x6966, + 0x6963, 0x6979, 0x699b, 0x69a7, 0x69bb, 0x69ab, 0x69ad, 0x69d4, + 0x69b1, 0x69c1, 0x69ca, 0x69df, 0x6995, 0x69e0, 0x698d, 0x69ff, + 0x6a2f, 0x69ed, 0x6a17, 0x6a18, 0x6a65, 0x69f2, 0x6a44, 0x6a3e, + 0x6aa0, 0x6a50, 0x6a5b, 0x6a35, 0x6a8e, 0x6a79, 0x6a3d, 0x6a28, + 0x6a58, 0x6a7c, 0x6a91, 0x6a90, 0x6aa9, 0x6a97, 0x6aab, 0x7337, + 0x7352, 0x6b81, 0x6b82, 0x6b87, 0x6b84, 0x6b92, 0x6b93, 0x6b8d, + 0x6b9a, 0x6b9b, 0x6ba1, 0x6baa, 0x8f6b, 0x8f6d, 0x8f71, 0x8f72, + 0x8f73, 0x8f75, 0x8f76, 0x8f78, 0x8f77, 0x8f79, 0x8f7a, 0x8f7c, + 0x8f7e, 0x8f81, 0x8f82, 0x8f84, 0x8f87, 0x8f8b, + /* 0xea */ + 0x95cc, 0x95cd, 0x95ce, 0x95cf, 0x95d0, 0x95d1, 0x95d2, 0x95d3, + 0x95d4, 0x95d5, 0x95d6, 0x95d7, 0x95d8, 0x95d9, 0x95da, 0x95db, + 0x95dc, 0x95dd, 0x95de, 0x95df, 0x95e0, 0x95e1, 0x95e2, 0x95e3, + 0x95e4, 0x95e5, 0x95e6, 0x95e7, 0x95ec, 0x95ff, 0x9607, 0x9613, + 0x9618, 0x961b, 0x961e, 0x9620, 0x9623, 0x9624, 0x9625, 0x9626, + 0x9627, 0x9628, 0x9629, 0x962b, 0x962c, 0x962d, 0x962f, 0x9630, + 0x9637, 0x9638, 0x9639, 0x963a, 0x963e, 0x9641, 0x9643, 0x964a, + 0x964e, 0x964f, 0x9651, 0x9652, 0x9653, 0x9656, 0x9657, 0x9658, + 0x9659, 0x965a, 0x965c, 0x965d, 0x965e, 0x9660, 0x9663, 0x9665, + 0x9666, 0x966b, 0x966d, 0x966e, 0x966f, 0x9670, 0x9671, 0x9673, + 0x9678, 0x9679, 0x967a, 0x967b, 0x967c, 0x967d, 0x967e, 0x967f, + 0x9680, 0x9681, 0x9682, 0x9683, 0x9684, 0x9687, 0x9689, 0x968a, + 0x8f8d, 0x8f8e, 0x8f8f, 0x8f98, 0x8f9a, 0x8ece, 0x620b, 0x6217, + 0x621b, 0x621f, 0x6222, 0x6221, 0x6225, 0x6224, 0x622c, 0x81e7, + 0x74ef, 0x74f4, 0x74ff, 0x750f, 0x7511, 0x7513, 0x6534, 0x65ee, + 0x65ef, 0x65f0, 0x660a, 0x6619, 0x6772, 0x6603, 0x6615, 0x6600, + 0x7085, 0x66f7, 0x661d, 0x6634, 0x6631, 0x6636, 0x6635, 0x8006, + 0x665f, 0x6654, 0x6641, 0x664f, 0x6656, 0x6661, 0x6657, 0x6677, + 0x6684, 0x668c, 0x66a7, 0x669d, 0x66be, 0x66db, 0x66dc, 0x66e6, + 0x66e9, 0x8d32, 0x8d33, 0x8d36, 0x8d3b, 0x8d3d, 0x8d40, 0x8d45, + 0x8d46, 0x8d48, 0x8d49, 0x8d47, 0x8d4d, 0x8d55, 0x8d59, 0x89c7, + 0x89ca, 0x89cb, 0x89cc, 0x89ce, 0x89cf, 0x89d0, 0x89d1, 0x726e, + 0x729f, 0x725d, 0x7266, 0x726f, 0x727e, 0x727f, 0x7284, 0x728b, + 0x728d, 0x728f, 0x7292, 0x6308, 0x6332, 0x63b0, + /* 0xeb */ + 0x968c, 0x968e, 0x9691, 0x9692, 0x9693, 0x9695, 0x9696, 0x969a, + 0x969b, 0x969d, 0x969e, 0x969f, 0x96a0, 0x96a1, 0x96a2, 0x96a3, + 0x96a4, 0x96a5, 0x96a6, 0x96a8, 0x96a9, 0x96aa, 0x96ab, 0x96ac, + 0x96ad, 0x96ae, 0x96af, 0x96b1, 0x96b2, 0x96b4, 0x96b5, 0x96b7, + 0x96b8, 0x96ba, 0x96bb, 0x96bf, 0x96c2, 0x96c3, 0x96c8, 0x96ca, + 0x96cb, 0x96d0, 0x96d1, 0x96d3, 0x96d4, 0x96d6, 0x96d7, 0x96d8, + 0x96d9, 0x96da, 0x96db, 0x96dc, 0x96dd, 0x96de, 0x96df, 0x96e1, + 0x96e2, 0x96e3, 0x96e4, 0x96e5, 0x96e6, 0x96e7, 0x96eb, 0x96ec, + 0x96ed, 0x96ee, 0x96f0, 0x96f1, 0x96f2, 0x96f4, 0x96f5, 0x96f8, + 0x96fa, 0x96fb, 0x96fc, 0x96fd, 0x96ff, 0x9702, 0x9703, 0x9705, + 0x970a, 0x970b, 0x970c, 0x9710, 0x9711, 0x9712, 0x9714, 0x9715, + 0x9717, 0x9718, 0x9719, 0x971a, 0x971b, 0x971d, 0x971f, 0x9720, + 0x643f, 0x64d8, 0x8004, 0x6bea, 0x6bf3, 0x6bfd, 0x6bf5, 0x6bf9, + 0x6c05, 0x6c07, 0x6c06, 0x6c0d, 0x6c15, 0x6c18, 0x6c19, 0x6c1a, + 0x6c21, 0x6c29, 0x6c24, 0x6c2a, 0x6c32, 0x6535, 0x6555, 0x656b, + 0x724d, 0x7252, 0x7256, 0x7230, 0x8662, 0x5216, 0x809f, 0x809c, + 0x8093, 0x80bc, 0x670a, 0x80bd, 0x80b1, 0x80ab, 0x80ad, 0x80b4, + 0x80b7, 0x80e7, 0x80e8, 0x80e9, 0x80ea, 0x80db, 0x80c2, 0x80c4, + 0x80d9, 0x80cd, 0x80d7, 0x6710, 0x80dd, 0x80eb, 0x80f1, 0x80f4, + 0x80ed, 0x810d, 0x810e, 0x80f2, 0x80fc, 0x6715, 0x8112, 0x8c5a, + 0x8136, 0x811e, 0x812c, 0x8118, 0x8132, 0x8148, 0x814c, 0x8153, + 0x8174, 0x8159, 0x815a, 0x8171, 0x8160, 0x8169, 0x817c, 0x817d, + 0x816d, 0x8167, 0x584d, 0x5ab5, 0x8188, 0x8182, 0x8191, 0x6ed5, + 0x81a3, 0x81aa, 0x81cc, 0x6726, 0x81ca, 0x81bb, + /* 0xec */ + 0x9721, 0x9722, 0x9723, 0x9724, 0x9725, 0x9726, 0x9727, 0x9728, + 0x9729, 0x972b, 0x972c, 0x972e, 0x972f, 0x9731, 0x9733, 0x9734, + 0x9735, 0x9736, 0x9737, 0x973a, 0x973b, 0x973c, 0x973d, 0x973f, + 0x9740, 0x9741, 0x9742, 0x9743, 0x9744, 0x9745, 0x9746, 0x9747, + 0x9748, 0x9749, 0x974a, 0x974b, 0x974c, 0x974d, 0x974e, 0x974f, + 0x9750, 0x9751, 0x9754, 0x9755, 0x9757, 0x9758, 0x975a, 0x975c, + 0x975d, 0x975f, 0x9763, 0x9764, 0x9766, 0x9767, 0x9768, 0x976a, + 0x976b, 0x976c, 0x976d, 0x976e, 0x976f, 0x9770, 0x9771, 0x9772, + 0x9775, 0x9777, 0x9778, 0x9779, 0x977a, 0x977b, 0x977d, 0x977e, + 0x977f, 0x9780, 0x9781, 0x9782, 0x9783, 0x9784, 0x9786, 0x9787, + 0x9788, 0x9789, 0x978a, 0x978c, 0x978e, 0x978f, 0x9790, 0x9793, + 0x9795, 0x9796, 0x9797, 0x9799, 0x979a, 0x979b, 0x979c, 0x979d, + 0x81c1, 0x81a6, 0x6b24, 0x6b37, 0x6b39, 0x6b43, 0x6b46, 0x6b59, + 0x98d1, 0x98d2, 0x98d3, 0x98d5, 0x98d9, 0x98da, 0x6bb3, 0x5f40, + 0x6bc2, 0x89f3, 0x6590, 0x9f51, 0x6593, 0x65bc, 0x65c6, 0x65c4, + 0x65c3, 0x65cc, 0x65ce, 0x65d2, 0x65d6, 0x7080, 0x709c, 0x7096, + 0x709d, 0x70bb, 0x70c0, 0x70b7, 0x70ab, 0x70b1, 0x70e8, 0x70ca, + 0x7110, 0x7113, 0x7116, 0x712f, 0x7131, 0x7173, 0x715c, 0x7168, + 0x7145, 0x7172, 0x714a, 0x7178, 0x717a, 0x7198, 0x71b3, 0x71b5, + 0x71a8, 0x71a0, 0x71e0, 0x71d4, 0x71e7, 0x71f9, 0x721d, 0x7228, + 0x706c, 0x7118, 0x7166, 0x71b9, 0x623e, 0x623d, 0x6243, 0x6248, + 0x6249, 0x793b, 0x7940, 0x7946, 0x7949, 0x795b, 0x795c, 0x7953, + 0x795a, 0x7962, 0x7957, 0x7960, 0x796f, 0x7967, 0x797a, 0x7985, + 0x798a, 0x799a, 0x79a7, 0x79b3, 0x5fd1, 0x5fd0, + /* 0xed */ + 0x979e, 0x979f, 0x97a1, 0x97a2, 0x97a4, 0x97a5, 0x97a6, 0x97a7, + 0x97a8, 0x97a9, 0x97aa, 0x97ac, 0x97ae, 0x97b0, 0x97b1, 0x97b3, + 0x97b5, 0x97b6, 0x97b7, 0x97b8, 0x97b9, 0x97ba, 0x97bb, 0x97bc, + 0x97bd, 0x97be, 0x97bf, 0x97c0, 0x97c1, 0x97c2, 0x97c3, 0x97c4, + 0x97c5, 0x97c6, 0x97c7, 0x97c8, 0x97c9, 0x97ca, 0x97cb, 0x97cc, + 0x97cd, 0x97ce, 0x97cf, 0x97d0, 0x97d1, 0x97d2, 0x97d3, 0x97d4, + 0x97d5, 0x97d6, 0x97d7, 0x97d8, 0x97d9, 0x97da, 0x97db, 0x97dc, + 0x97dd, 0x97de, 0x97df, 0x97e0, 0x97e1, 0x97e2, 0x97e3, 0x97e4, + 0x97e5, 0x97e8, 0x97ee, 0x97ef, 0x97f0, 0x97f1, 0x97f2, 0x97f4, + 0x97f7, 0x97f8, 0x97f9, 0x97fa, 0x97fb, 0x97fc, 0x97fd, 0x97fe, + 0x97ff, 0x9800, 0x9801, 0x9802, 0x9803, 0x9804, 0x9805, 0x9806, + 0x9807, 0x9808, 0x9809, 0x980a, 0x980b, 0x980c, 0x980d, 0x980e, + 0x603c, 0x605d, 0x605a, 0x6067, 0x6041, 0x6059, 0x6063, 0x60ab, + 0x6106, 0x610d, 0x615d, 0x61a9, 0x619d, 0x61cb, 0x61d1, 0x6206, + 0x8080, 0x807f, 0x6c93, 0x6cf6, 0x6dfc, 0x77f6, 0x77f8, 0x7800, + 0x7809, 0x7817, 0x7818, 0x7811, 0x65ab, 0x782d, 0x781c, 0x781d, + 0x7839, 0x783a, 0x783b, 0x781f, 0x783c, 0x7825, 0x782c, 0x7823, + 0x7829, 0x784e, 0x786d, 0x7856, 0x7857, 0x7826, 0x7850, 0x7847, + 0x784c, 0x786a, 0x789b, 0x7893, 0x789a, 0x7887, 0x789c, 0x78a1, + 0x78a3, 0x78b2, 0x78b9, 0x78a5, 0x78d4, 0x78d9, 0x78c9, 0x78ec, + 0x78f2, 0x7905, 0x78f4, 0x7913, 0x7924, 0x791e, 0x7934, 0x9f9b, + 0x9ef9, 0x9efb, 0x9efc, 0x76f1, 0x7704, 0x770d, 0x76f9, 0x7707, + 0x7708, 0x771a, 0x7722, 0x7719, 0x772d, 0x7726, 0x7735, 0x7738, + 0x7750, 0x7751, 0x7747, 0x7743, 0x775a, 0x7768, + /* 0xee */ + 0x980f, 0x9810, 0x9811, 0x9812, 0x9813, 0x9814, 0x9815, 0x9816, + 0x9817, 0x9818, 0x9819, 0x981a, 0x981b, 0x981c, 0x981d, 0x981e, + 0x981f, 0x9820, 0x9821, 0x9822, 0x9823, 0x9824, 0x9825, 0x9826, + 0x9827, 0x9828, 0x9829, 0x982a, 0x982b, 0x982c, 0x982d, 0x982e, + 0x982f, 0x9830, 0x9831, 0x9832, 0x9833, 0x9834, 0x9835, 0x9836, + 0x9837, 0x9838, 0x9839, 0x983a, 0x983b, 0x983c, 0x983d, 0x983e, + 0x983f, 0x9840, 0x9841, 0x9842, 0x9843, 0x9844, 0x9845, 0x9846, + 0x9847, 0x9848, 0x9849, 0x984a, 0x984b, 0x984c, 0x984d, 0x984e, + 0x984f, 0x9850, 0x9851, 0x9852, 0x9853, 0x9854, 0x9855, 0x9856, + 0x9857, 0x9858, 0x9859, 0x985a, 0x985b, 0x985c, 0x985d, 0x985e, + 0x985f, 0x9860, 0x9861, 0x9862, 0x9863, 0x9864, 0x9865, 0x9866, + 0x9867, 0x9868, 0x9869, 0x986a, 0x986b, 0x986c, 0x986d, 0x986e, + 0x7762, 0x7765, 0x777f, 0x778d, 0x777d, 0x7780, 0x778c, 0x7791, + 0x779f, 0x77a0, 0x77b0, 0x77b5, 0x77bd, 0x753a, 0x7540, 0x754e, + 0x754b, 0x7548, 0x755b, 0x7572, 0x7579, 0x7583, 0x7f58, 0x7f61, + 0x7f5f, 0x8a48, 0x7f68, 0x7f74, 0x7f71, 0x7f79, 0x7f81, 0x7f7e, + 0x76cd, 0x76e5, 0x8832, 0x9485, 0x9486, 0x9487, 0x948b, 0x948a, + 0x948c, 0x948d, 0x948f, 0x9490, 0x9494, 0x9497, 0x9495, 0x949a, + 0x949b, 0x949c, 0x94a3, 0x94a4, 0x94ab, 0x94aa, 0x94ad, 0x94ac, + 0x94af, 0x94b0, 0x94b2, 0x94b4, 0x94b6, 0x94b7, 0x94b8, 0x94b9, + 0x94ba, 0x94bc, 0x94bd, 0x94bf, 0x94c4, 0x94c8, 0x94c9, 0x94ca, + 0x94cb, 0x94cc, 0x94cd, 0x94ce, 0x94d0, 0x94d1, 0x94d2, 0x94d5, + 0x94d6, 0x94d7, 0x94d9, 0x94d8, 0x94db, 0x94de, 0x94df, 0x94e0, + 0x94e2, 0x94e4, 0x94e5, 0x94e7, 0x94e8, 0x94ea, + /* 0xef */ + 0x986f, 0x9870, 0x9871, 0x9872, 0x9873, 0x9874, 0x988b, 0x988e, + 0x9892, 0x9895, 0x9899, 0x98a3, 0x98a8, 0x98a9, 0x98aa, 0x98ab, + 0x98ac, 0x98ad, 0x98ae, 0x98af, 0x98b0, 0x98b1, 0x98b2, 0x98b3, + 0x98b4, 0x98b5, 0x98b6, 0x98b7, 0x98b8, 0x98b9, 0x98ba, 0x98bb, + 0x98bc, 0x98bd, 0x98be, 0x98bf, 0x98c0, 0x98c1, 0x98c2, 0x98c3, + 0x98c4, 0x98c5, 0x98c6, 0x98c7, 0x98c8, 0x98c9, 0x98ca, 0x98cb, + 0x98cc, 0x98cd, 0x98cf, 0x98d0, 0x98d4, 0x98d6, 0x98d7, 0x98db, + 0x98dc, 0x98dd, 0x98e0, 0x98e1, 0x98e2, 0x98e3, 0x98e4, 0x98e5, + 0x98e6, 0x98e9, 0x98ea, 0x98eb, 0x98ec, 0x98ed, 0x98ee, 0x98ef, + 0x98f0, 0x98f1, 0x98f2, 0x98f3, 0x98f4, 0x98f5, 0x98f6, 0x98f7, + 0x98f8, 0x98f9, 0x98fa, 0x98fb, 0x98fc, 0x98fd, 0x98fe, 0x98ff, + 0x9900, 0x9901, 0x9902, 0x9903, 0x9904, 0x9905, 0x9906, 0x9907, + 0x94e9, 0x94eb, 0x94ee, 0x94ef, 0x94f3, 0x94f4, 0x94f5, 0x94f7, + 0x94f9, 0x94fc, 0x94fd, 0x94ff, 0x9503, 0x9502, 0x9506, 0x9507, + 0x9509, 0x950a, 0x950d, 0x950e, 0x950f, 0x9512, 0x9513, 0x9514, + 0x9515, 0x9516, 0x9518, 0x951b, 0x951d, 0x951e, 0x951f, 0x9522, + 0x952a, 0x952b, 0x9529, 0x952c, 0x9531, 0x9532, 0x9534, 0x9536, + 0x9537, 0x9538, 0x953c, 0x953e, 0x953f, 0x9542, 0x9535, 0x9544, + 0x9545, 0x9546, 0x9549, 0x954c, 0x954e, 0x954f, 0x9552, 0x9553, + 0x9554, 0x9556, 0x9557, 0x9558, 0x9559, 0x955b, 0x955e, 0x955f, + 0x955d, 0x9561, 0x9562, 0x9564, 0x9565, 0x9566, 0x9567, 0x9568, + 0x9569, 0x956a, 0x956b, 0x956c, 0x956f, 0x9571, 0x9572, 0x9573, + 0x953a, 0x77e7, 0x77ec, 0x96c9, 0x79d5, 0x79ed, 0x79e3, 0x79eb, + 0x7a06, 0x5d47, 0x7a03, 0x7a02, 0x7a1e, 0x7a14, + /* 0xf0 */ + 0x9908, 0x9909, 0x990a, 0x990b, 0x990c, 0x990e, 0x990f, 0x9911, + 0x9912, 0x9913, 0x9914, 0x9915, 0x9916, 0x9917, 0x9918, 0x9919, + 0x991a, 0x991b, 0x991c, 0x991d, 0x991e, 0x991f, 0x9920, 0x9921, + 0x9922, 0x9923, 0x9924, 0x9925, 0x9926, 0x9927, 0x9928, 0x9929, + 0x992a, 0x992b, 0x992c, 0x992d, 0x992f, 0x9930, 0x9931, 0x9932, + 0x9933, 0x9934, 0x9935, 0x9936, 0x9937, 0x9938, 0x9939, 0x993a, + 0x993b, 0x993c, 0x993d, 0x993e, 0x993f, 0x9940, 0x9941, 0x9942, + 0x9943, 0x9944, 0x9945, 0x9946, 0x9947, 0x9948, 0x9949, 0x994a, + 0x994b, 0x994c, 0x994d, 0x994e, 0x994f, 0x9950, 0x9951, 0x9952, + 0x9953, 0x9956, 0x9957, 0x9958, 0x9959, 0x995a, 0x995b, 0x995c, + 0x995d, 0x995e, 0x995f, 0x9960, 0x9961, 0x9962, 0x9964, 0x9966, + 0x9973, 0x9978, 0x9979, 0x997b, 0x997e, 0x9982, 0x9983, 0x9989, + 0x7a39, 0x7a37, 0x7a51, 0x9ecf, 0x99a5, 0x7a70, 0x7688, 0x768e, + 0x7693, 0x7699, 0x76a4, 0x74de, 0x74e0, 0x752c, 0x9e20, 0x9e22, + 0x9e28, 0x9e29, 0x9e2a, 0x9e2b, 0x9e2c, 0x9e32, 0x9e31, 0x9e36, + 0x9e38, 0x9e37, 0x9e39, 0x9e3a, 0x9e3e, 0x9e41, 0x9e42, 0x9e44, + 0x9e46, 0x9e47, 0x9e48, 0x9e49, 0x9e4b, 0x9e4c, 0x9e4e, 0x9e51, + 0x9e55, 0x9e57, 0x9e5a, 0x9e5b, 0x9e5c, 0x9e5e, 0x9e63, 0x9e66, + 0x9e67, 0x9e68, 0x9e69, 0x9e6a, 0x9e6b, 0x9e6c, 0x9e71, 0x9e6d, + 0x9e73, 0x7592, 0x7594, 0x7596, 0x75a0, 0x759d, 0x75ac, 0x75a3, + 0x75b3, 0x75b4, 0x75b8, 0x75c4, 0x75b1, 0x75b0, 0x75c3, 0x75c2, + 0x75d6, 0x75cd, 0x75e3, 0x75e8, 0x75e6, 0x75e4, 0x75eb, 0x75e7, + 0x7603, 0x75f1, 0x75fc, 0x75ff, 0x7610, 0x7600, 0x7605, 0x760c, + 0x7617, 0x760a, 0x7625, 0x7618, 0x7615, 0x7619, + /* 0xf1 */ + 0x998c, 0x998e, 0x999a, 0x999b, 0x999c, 0x999d, 0x999e, 0x999f, + 0x99a0, 0x99a1, 0x99a2, 0x99a3, 0x99a4, 0x99a6, 0x99a7, 0x99a9, + 0x99aa, 0x99ab, 0x99ac, 0x99ad, 0x99ae, 0x99af, 0x99b0, 0x99b1, + 0x99b2, 0x99b3, 0x99b4, 0x99b5, 0x99b6, 0x99b7, 0x99b8, 0x99b9, + 0x99ba, 0x99bb, 0x99bc, 0x99bd, 0x99be, 0x99bf, 0x99c0, 0x99c1, + 0x99c2, 0x99c3, 0x99c4, 0x99c5, 0x99c6, 0x99c7, 0x99c8, 0x99c9, + 0x99ca, 0x99cb, 0x99cc, 0x99cd, 0x99ce, 0x99cf, 0x99d0, 0x99d1, + 0x99d2, 0x99d3, 0x99d4, 0x99d5, 0x99d6, 0x99d7, 0x99d8, 0x99d9, + 0x99da, 0x99db, 0x99dc, 0x99dd, 0x99de, 0x99df, 0x99e0, 0x99e1, + 0x99e2, 0x99e3, 0x99e4, 0x99e5, 0x99e6, 0x99e7, 0x99e8, 0x99e9, + 0x99ea, 0x99eb, 0x99ec, 0x99ed, 0x99ee, 0x99ef, 0x99f0, 0x99f1, + 0x99f2, 0x99f3, 0x99f4, 0x99f5, 0x99f6, 0x99f7, 0x99f8, 0x99f9, + 0x761b, 0x763c, 0x7622, 0x7620, 0x7640, 0x762d, 0x7630, 0x763f, + 0x7635, 0x7643, 0x763e, 0x7633, 0x764d, 0x765e, 0x7654, 0x765c, + 0x7656, 0x766b, 0x766f, 0x7fca, 0x7ae6, 0x7a78, 0x7a79, 0x7a80, + 0x7a86, 0x7a88, 0x7a95, 0x7aa6, 0x7aa0, 0x7aac, 0x7aa8, 0x7aad, + 0x7ab3, 0x8864, 0x8869, 0x8872, 0x887d, 0x887f, 0x8882, 0x88a2, + 0x88c6, 0x88b7, 0x88bc, 0x88c9, 0x88e2, 0x88ce, 0x88e3, 0x88e5, + 0x88f1, 0x891a, 0x88fc, 0x88e8, 0x88fe, 0x88f0, 0x8921, 0x8919, + 0x8913, 0x891b, 0x890a, 0x8934, 0x892b, 0x8936, 0x8941, 0x8966, + 0x897b, 0x758b, 0x80e5, 0x76b2, 0x76b4, 0x77dc, 0x8012, 0x8014, + 0x8016, 0x801c, 0x8020, 0x8022, 0x8025, 0x8026, 0x8027, 0x8029, + 0x8028, 0x8031, 0x800b, 0x8035, 0x8043, 0x8046, 0x804d, 0x8052, + 0x8069, 0x8071, 0x8983, 0x9878, 0x9880, 0x9883, + /* 0xf2 */ + 0x99fa, 0x99fb, 0x99fc, 0x99fd, 0x99fe, 0x99ff, 0x9a00, 0x9a01, + 0x9a02, 0x9a03, 0x9a04, 0x9a05, 0x9a06, 0x9a07, 0x9a08, 0x9a09, + 0x9a0a, 0x9a0b, 0x9a0c, 0x9a0d, 0x9a0e, 0x9a0f, 0x9a10, 0x9a11, + 0x9a12, 0x9a13, 0x9a14, 0x9a15, 0x9a16, 0x9a17, 0x9a18, 0x9a19, + 0x9a1a, 0x9a1b, 0x9a1c, 0x9a1d, 0x9a1e, 0x9a1f, 0x9a20, 0x9a21, + 0x9a22, 0x9a23, 0x9a24, 0x9a25, 0x9a26, 0x9a27, 0x9a28, 0x9a29, + 0x9a2a, 0x9a2b, 0x9a2c, 0x9a2d, 0x9a2e, 0x9a2f, 0x9a30, 0x9a31, + 0x9a32, 0x9a33, 0x9a34, 0x9a35, 0x9a36, 0x9a37, 0x9a38, 0x9a39, + 0x9a3a, 0x9a3b, 0x9a3c, 0x9a3d, 0x9a3e, 0x9a3f, 0x9a40, 0x9a41, + 0x9a42, 0x9a43, 0x9a44, 0x9a45, 0x9a46, 0x9a47, 0x9a48, 0x9a49, + 0x9a4a, 0x9a4b, 0x9a4c, 0x9a4d, 0x9a4e, 0x9a4f, 0x9a50, 0x9a51, + 0x9a52, 0x9a53, 0x9a54, 0x9a55, 0x9a56, 0x9a57, 0x9a58, 0x9a59, + 0x9889, 0x988c, 0x988d, 0x988f, 0x9894, 0x989a, 0x989b, 0x989e, + 0x989f, 0x98a1, 0x98a2, 0x98a5, 0x98a6, 0x864d, 0x8654, 0x866c, + 0x866e, 0x867f, 0x867a, 0x867c, 0x867b, 0x86a8, 0x868d, 0x868b, + 0x86ac, 0x869d, 0x86a7, 0x86a3, 0x86aa, 0x8693, 0x86a9, 0x86b6, + 0x86c4, 0x86b5, 0x86ce, 0x86b0, 0x86ba, 0x86b1, 0x86af, 0x86c9, + 0x86cf, 0x86b4, 0x86e9, 0x86f1, 0x86f2, 0x86ed, 0x86f3, 0x86d0, + 0x8713, 0x86de, 0x86f4, 0x86df, 0x86d8, 0x86d1, 0x8703, 0x8707, + 0x86f8, 0x8708, 0x870a, 0x870d, 0x8709, 0x8723, 0x873b, 0x871e, + 0x8725, 0x872e, 0x871a, 0x873e, 0x8748, 0x8734, 0x8731, 0x8729, + 0x8737, 0x873f, 0x8782, 0x8722, 0x877d, 0x877e, 0x877b, 0x8760, + 0x8770, 0x874c, 0x876e, 0x878b, 0x8753, 0x8763, 0x877c, 0x8764, + 0x8759, 0x8765, 0x8793, 0x87af, 0x87a8, 0x87d2, + /* 0xf3 */ + 0x9a5a, 0x9a5b, 0x9a5c, 0x9a5d, 0x9a5e, 0x9a5f, 0x9a60, 0x9a61, + 0x9a62, 0x9a63, 0x9a64, 0x9a65, 0x9a66, 0x9a67, 0x9a68, 0x9a69, + 0x9a6a, 0x9a6b, 0x9a72, 0x9a83, 0x9a89, 0x9a8d, 0x9a8e, 0x9a94, + 0x9a95, 0x9a99, 0x9aa6, 0x9aa9, 0x9aaa, 0x9aab, 0x9aac, 0x9aad, + 0x9aae, 0x9aaf, 0x9ab2, 0x9ab3, 0x9ab4, 0x9ab5, 0x9ab9, 0x9abb, + 0x9abd, 0x9abe, 0x9abf, 0x9ac3, 0x9ac4, 0x9ac6, 0x9ac7, 0x9ac8, + 0x9ac9, 0x9aca, 0x9acd, 0x9ace, 0x9acf, 0x9ad0, 0x9ad2, 0x9ad4, + 0x9ad5, 0x9ad6, 0x9ad7, 0x9ad9, 0x9ada, 0x9adb, 0x9adc, 0x9add, + 0x9ade, 0x9ae0, 0x9ae2, 0x9ae3, 0x9ae4, 0x9ae5, 0x9ae7, 0x9ae8, + 0x9ae9, 0x9aea, 0x9aec, 0x9aee, 0x9af0, 0x9af1, 0x9af2, 0x9af3, + 0x9af4, 0x9af5, 0x9af6, 0x9af7, 0x9af8, 0x9afa, 0x9afc, 0x9afd, + 0x9afe, 0x9aff, 0x9b00, 0x9b01, 0x9b02, 0x9b04, 0x9b05, 0x9b06, + 0x87c6, 0x8788, 0x8785, 0x87ad, 0x8797, 0x8783, 0x87ab, 0x87e5, + 0x87ac, 0x87b5, 0x87b3, 0x87cb, 0x87d3, 0x87bd, 0x87d1, 0x87c0, + 0x87ca, 0x87db, 0x87ea, 0x87e0, 0x87ee, 0x8816, 0x8813, 0x87fe, + 0x880a, 0x881b, 0x8821, 0x8839, 0x883c, 0x7f36, 0x7f42, 0x7f44, + 0x7f45, 0x8210, 0x7afa, 0x7afd, 0x7b08, 0x7b03, 0x7b04, 0x7b15, + 0x7b0a, 0x7b2b, 0x7b0f, 0x7b47, 0x7b38, 0x7b2a, 0x7b19, 0x7b2e, + 0x7b31, 0x7b20, 0x7b25, 0x7b24, 0x7b33, 0x7b3e, 0x7b1e, 0x7b58, + 0x7b5a, 0x7b45, 0x7b75, 0x7b4c, 0x7b5d, 0x7b60, 0x7b6e, 0x7b7b, + 0x7b62, 0x7b72, 0x7b71, 0x7b90, 0x7ba6, 0x7ba7, 0x7bb8, 0x7bac, + 0x7b9d, 0x7ba8, 0x7b85, 0x7baa, 0x7b9c, 0x7ba2, 0x7bab, 0x7bb4, + 0x7bd1, 0x7bc1, 0x7bcc, 0x7bdd, 0x7bda, 0x7be5, 0x7be6, 0x7bea, + 0x7c0c, 0x7bfe, 0x7bfc, 0x7c0f, 0x7c16, 0x7c0b, + /* 0xf4 */ + 0x9b07, 0x9b09, 0x9b0a, 0x9b0b, 0x9b0c, 0x9b0d, 0x9b0e, 0x9b10, + 0x9b11, 0x9b12, 0x9b14, 0x9b15, 0x9b16, 0x9b17, 0x9b18, 0x9b19, + 0x9b1a, 0x9b1b, 0x9b1c, 0x9b1d, 0x9b1e, 0x9b20, 0x9b21, 0x9b22, + 0x9b24, 0x9b25, 0x9b26, 0x9b27, 0x9b28, 0x9b29, 0x9b2a, 0x9b2b, + 0x9b2c, 0x9b2d, 0x9b2e, 0x9b30, 0x9b31, 0x9b33, 0x9b34, 0x9b35, + 0x9b36, 0x9b37, 0x9b38, 0x9b39, 0x9b3a, 0x9b3d, 0x9b3e, 0x9b3f, + 0x9b40, 0x9b46, 0x9b4a, 0x9b4b, 0x9b4c, 0x9b4e, 0x9b50, 0x9b52, + 0x9b53, 0x9b55, 0x9b56, 0x9b57, 0x9b58, 0x9b59, 0x9b5a, 0x9b5b, + 0x9b5c, 0x9b5d, 0x9b5e, 0x9b5f, 0x9b60, 0x9b61, 0x9b62, 0x9b63, + 0x9b64, 0x9b65, 0x9b66, 0x9b67, 0x9b68, 0x9b69, 0x9b6a, 0x9b6b, + 0x9b6c, 0x9b6d, 0x9b6e, 0x9b6f, 0x9b70, 0x9b71, 0x9b72, 0x9b73, + 0x9b74, 0x9b75, 0x9b76, 0x9b77, 0x9b78, 0x9b79, 0x9b7a, 0x9b7b, + 0x7c1f, 0x7c2a, 0x7c26, 0x7c38, 0x7c41, 0x7c40, 0x81fe, 0x8201, + 0x8202, 0x8204, 0x81ec, 0x8844, 0x8221, 0x8222, 0x8223, 0x822d, + 0x822f, 0x8228, 0x822b, 0x8238, 0x823b, 0x8233, 0x8234, 0x823e, + 0x8244, 0x8249, 0x824b, 0x824f, 0x825a, 0x825f, 0x8268, 0x887e, + 0x8885, 0x8888, 0x88d8, 0x88df, 0x895e, 0x7f9d, 0x7f9f, 0x7fa7, + 0x7faf, 0x7fb0, 0x7fb2, 0x7c7c, 0x6549, 0x7c91, 0x7c9d, 0x7c9c, + 0x7c9e, 0x7ca2, 0x7cb2, 0x7cbc, 0x7cbd, 0x7cc1, 0x7cc7, 0x7ccc, + 0x7ccd, 0x7cc8, 0x7cc5, 0x7cd7, 0x7ce8, 0x826e, 0x66a8, 0x7fbf, + 0x7fce, 0x7fd5, 0x7fe5, 0x7fe1, 0x7fe6, 0x7fe9, 0x7fee, 0x7ff3, + 0x7cf8, 0x7d77, 0x7da6, 0x7dae, 0x7e47, 0x7e9b, 0x9eb8, 0x9eb4, + 0x8d73, 0x8d84, 0x8d94, 0x8d91, 0x8db1, 0x8d67, 0x8d6d, 0x8c47, + 0x8c49, 0x914a, 0x9150, 0x914e, 0x914f, 0x9164, + /* 0xf5 */ + 0x9b7c, 0x9b7d, 0x9b7e, 0x9b7f, 0x9b80, 0x9b81, 0x9b82, 0x9b83, + 0x9b84, 0x9b85, 0x9b86, 0x9b87, 0x9b88, 0x9b89, 0x9b8a, 0x9b8b, + 0x9b8c, 0x9b8d, 0x9b8e, 0x9b8f, 0x9b90, 0x9b91, 0x9b92, 0x9b93, + 0x9b94, 0x9b95, 0x9b96, 0x9b97, 0x9b98, 0x9b99, 0x9b9a, 0x9b9b, + 0x9b9c, 0x9b9d, 0x9b9e, 0x9b9f, 0x9ba0, 0x9ba1, 0x9ba2, 0x9ba3, + 0x9ba4, 0x9ba5, 0x9ba6, 0x9ba7, 0x9ba8, 0x9ba9, 0x9baa, 0x9bab, + 0x9bac, 0x9bad, 0x9bae, 0x9baf, 0x9bb0, 0x9bb1, 0x9bb2, 0x9bb3, + 0x9bb4, 0x9bb5, 0x9bb6, 0x9bb7, 0x9bb8, 0x9bb9, 0x9bba, 0x9bbb, + 0x9bbc, 0x9bbd, 0x9bbe, 0x9bbf, 0x9bc0, 0x9bc1, 0x9bc2, 0x9bc3, + 0x9bc4, 0x9bc5, 0x9bc6, 0x9bc7, 0x9bc8, 0x9bc9, 0x9bca, 0x9bcb, + 0x9bcc, 0x9bcd, 0x9bce, 0x9bcf, 0x9bd0, 0x9bd1, 0x9bd2, 0x9bd3, + 0x9bd4, 0x9bd5, 0x9bd6, 0x9bd7, 0x9bd8, 0x9bd9, 0x9bda, 0x9bdb, + 0x9162, 0x9161, 0x9170, 0x9169, 0x916f, 0x917d, 0x917e, 0x9172, + 0x9174, 0x9179, 0x918c, 0x9185, 0x9190, 0x918d, 0x9191, 0x91a2, + 0x91a3, 0x91aa, 0x91ad, 0x91ae, 0x91af, 0x91b5, 0x91b4, 0x91ba, + 0x8c55, 0x9e7e, 0x8db8, 0x8deb, 0x8e05, 0x8e59, 0x8e69, 0x8db5, + 0x8dbf, 0x8dbc, 0x8dba, 0x8dc4, 0x8dd6, 0x8dd7, 0x8dda, 0x8dde, + 0x8dce, 0x8dcf, 0x8ddb, 0x8dc6, 0x8dec, 0x8df7, 0x8df8, 0x8de3, + 0x8df9, 0x8dfb, 0x8de4, 0x8e09, 0x8dfd, 0x8e14, 0x8e1d, 0x8e1f, + 0x8e2c, 0x8e2e, 0x8e23, 0x8e2f, 0x8e3a, 0x8e40, 0x8e39, 0x8e35, + 0x8e3d, 0x8e31, 0x8e49, 0x8e41, 0x8e42, 0x8e51, 0x8e52, 0x8e4a, + 0x8e70, 0x8e76, 0x8e7c, 0x8e6f, 0x8e74, 0x8e85, 0x8e8f, 0x8e94, + 0x8e90, 0x8e9c, 0x8e9e, 0x8c78, 0x8c82, 0x8c8a, 0x8c85, 0x8c98, + 0x8c94, 0x659b, 0x89d6, 0x89de, 0x89da, 0x89dc, + /* 0xf6 */ + 0x9bdc, 0x9bdd, 0x9bde, 0x9bdf, 0x9be0, 0x9be1, 0x9be2, 0x9be3, + 0x9be4, 0x9be5, 0x9be6, 0x9be7, 0x9be8, 0x9be9, 0x9bea, 0x9beb, + 0x9bec, 0x9bed, 0x9bee, 0x9bef, 0x9bf0, 0x9bf1, 0x9bf2, 0x9bf3, + 0x9bf4, 0x9bf5, 0x9bf6, 0x9bf7, 0x9bf8, 0x9bf9, 0x9bfa, 0x9bfb, + 0x9bfc, 0x9bfd, 0x9bfe, 0x9bff, 0x9c00, 0x9c01, 0x9c02, 0x9c03, + 0x9c04, 0x9c05, 0x9c06, 0x9c07, 0x9c08, 0x9c09, 0x9c0a, 0x9c0b, + 0x9c0c, 0x9c0d, 0x9c0e, 0x9c0f, 0x9c10, 0x9c11, 0x9c12, 0x9c13, + 0x9c14, 0x9c15, 0x9c16, 0x9c17, 0x9c18, 0x9c19, 0x9c1a, 0x9c1b, + 0x9c1c, 0x9c1d, 0x9c1e, 0x9c1f, 0x9c20, 0x9c21, 0x9c22, 0x9c23, + 0x9c24, 0x9c25, 0x9c26, 0x9c27, 0x9c28, 0x9c29, 0x9c2a, 0x9c2b, + 0x9c2c, 0x9c2d, 0x9c2e, 0x9c2f, 0x9c30, 0x9c31, 0x9c32, 0x9c33, + 0x9c34, 0x9c35, 0x9c36, 0x9c37, 0x9c38, 0x9c39, 0x9c3a, 0x9c3b, + 0x89e5, 0x89eb, 0x89ef, 0x8a3e, 0x8b26, 0x9753, 0x96e9, 0x96f3, + 0x96ef, 0x9706, 0x9701, 0x9708, 0x970f, 0x970e, 0x972a, 0x972d, + 0x9730, 0x973e, 0x9f80, 0x9f83, 0x9f85, 0x9f86, 0x9f87, 0x9f88, + 0x9f89, 0x9f8a, 0x9f8c, 0x9efe, 0x9f0b, 0x9f0d, 0x96b9, 0x96bc, + 0x96bd, 0x96ce, 0x96d2, 0x77bf, 0x96e0, 0x928e, 0x92ae, 0x92c8, + 0x933e, 0x936a, 0x93ca, 0x938f, 0x943e, 0x946b, 0x9c7f, 0x9c82, + 0x9c85, 0x9c86, 0x9c87, 0x9c88, 0x7a23, 0x9c8b, 0x9c8e, 0x9c90, + 0x9c91, 0x9c92, 0x9c94, 0x9c95, 0x9c9a, 0x9c9b, 0x9c9e, 0x9c9f, + 0x9ca0, 0x9ca1, 0x9ca2, 0x9ca3, 0x9ca5, 0x9ca6, 0x9ca7, 0x9ca8, + 0x9ca9, 0x9cab, 0x9cad, 0x9cae, 0x9cb0, 0x9cb1, 0x9cb2, 0x9cb3, + 0x9cb4, 0x9cb5, 0x9cb6, 0x9cb7, 0x9cba, 0x9cbb, 0x9cbc, 0x9cbd, + 0x9cc4, 0x9cc5, 0x9cc6, 0x9cc7, 0x9cca, 0x9ccb, + /* 0xf7 */ + 0x9c3c, 0x9c3d, 0x9c3e, 0x9c3f, 0x9c40, 0x9c41, 0x9c42, 0x9c43, + 0x9c44, 0x9c45, 0x9c46, 0x9c47, 0x9c48, 0x9c49, 0x9c4a, 0x9c4b, + 0x9c4c, 0x9c4d, 0x9c4e, 0x9c4f, 0x9c50, 0x9c51, 0x9c52, 0x9c53, + 0x9c54, 0x9c55, 0x9c56, 0x9c57, 0x9c58, 0x9c59, 0x9c5a, 0x9c5b, + 0x9c5c, 0x9c5d, 0x9c5e, 0x9c5f, 0x9c60, 0x9c61, 0x9c62, 0x9c63, + 0x9c64, 0x9c65, 0x9c66, 0x9c67, 0x9c68, 0x9c69, 0x9c6a, 0x9c6b, + 0x9c6c, 0x9c6d, 0x9c6e, 0x9c6f, 0x9c70, 0x9c71, 0x9c72, 0x9c73, + 0x9c74, 0x9c75, 0x9c76, 0x9c77, 0x9c78, 0x9c79, 0x9c7a, 0x9c7b, + 0x9c7d, 0x9c7e, 0x9c80, 0x9c83, 0x9c84, 0x9c89, 0x9c8a, 0x9c8c, + 0x9c8f, 0x9c93, 0x9c96, 0x9c97, 0x9c98, 0x9c99, 0x9c9d, 0x9caa, + 0x9cac, 0x9caf, 0x9cb9, 0x9cbe, 0x9cbf, 0x9cc0, 0x9cc1, 0x9cc2, + 0x9cc8, 0x9cc9, 0x9cd1, 0x9cd2, 0x9cda, 0x9cdb, 0x9ce0, 0x9ce1, + 0x9ccc, 0x9ccd, 0x9cce, 0x9ccf, 0x9cd0, 0x9cd3, 0x9cd4, 0x9cd5, + 0x9cd7, 0x9cd8, 0x9cd9, 0x9cdc, 0x9cdd, 0x9cdf, 0x9ce2, 0x977c, + 0x9785, 0x9791, 0x9792, 0x9794, 0x97af, 0x97ab, 0x97a3, 0x97b2, + 0x97b4, 0x9ab1, 0x9ab0, 0x9ab7, 0x9e58, 0x9ab6, 0x9aba, 0x9abc, + 0x9ac1, 0x9ac0, 0x9ac5, 0x9ac2, 0x9acb, 0x9acc, 0x9ad1, 0x9b45, + 0x9b43, 0x9b47, 0x9b49, 0x9b48, 0x9b4d, 0x9b51, 0x98e8, 0x990d, + 0x992e, 0x9955, 0x9954, 0x9adf, 0x9ae1, 0x9ae6, 0x9aef, 0x9aeb, + 0x9afb, 0x9aed, 0x9af9, 0x9b08, 0x9b0f, 0x9b13, 0x9b1f, 0x9b23, + 0x9ebd, 0x9ebe, 0x7e3b, 0x9e82, 0x9e87, 0x9e88, 0x9e8b, 0x9e92, + 0x93d6, 0x9e9d, 0x9e9f, 0x9edb, 0x9edc, 0x9edd, 0x9ee0, 0x9edf, + 0x9ee2, 0x9ee9, 0x9ee7, 0x9ee5, 0x9eea, 0x9eef, 0x9f22, 0x9f2c, + 0x9f2f, 0x9f39, 0x9f37, 0x9f3d, 0x9f3e, 0x9f44, + /* 0xf8 */ + 0x9ce3, 0x9ce4, 0x9ce5, 0x9ce6, 0x9ce7, 0x9ce8, 0x9ce9, 0x9cea, + 0x9ceb, 0x9cec, 0x9ced, 0x9cee, 0x9cef, 0x9cf0, 0x9cf1, 0x9cf2, + 0x9cf3, 0x9cf4, 0x9cf5, 0x9cf6, 0x9cf7, 0x9cf8, 0x9cf9, 0x9cfa, + 0x9cfb, 0x9cfc, 0x9cfd, 0x9cfe, 0x9cff, 0x9d00, 0x9d01, 0x9d02, + 0x9d03, 0x9d04, 0x9d05, 0x9d06, 0x9d07, 0x9d08, 0x9d09, 0x9d0a, + 0x9d0b, 0x9d0c, 0x9d0d, 0x9d0e, 0x9d0f, 0x9d10, 0x9d11, 0x9d12, + 0x9d13, 0x9d14, 0x9d15, 0x9d16, 0x9d17, 0x9d18, 0x9d19, 0x9d1a, + 0x9d1b, 0x9d1c, 0x9d1d, 0x9d1e, 0x9d1f, 0x9d20, 0x9d21, 0x9d22, + 0x9d23, 0x9d24, 0x9d25, 0x9d26, 0x9d27, 0x9d28, 0x9d29, 0x9d2a, + 0x9d2b, 0x9d2c, 0x9d2d, 0x9d2e, 0x9d2f, 0x9d30, 0x9d31, 0x9d32, + 0x9d33, 0x9d34, 0x9d35, 0x9d36, 0x9d37, 0x9d38, 0x9d39, 0x9d3a, + 0x9d3b, 0x9d3c, 0x9d3d, 0x9d3e, 0x9d3f, 0x9d40, 0x9d41, 0x9d42, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0xf9 */ + 0x9d43, 0x9d44, 0x9d45, 0x9d46, 0x9d47, 0x9d48, 0x9d49, 0x9d4a, + 0x9d4b, 0x9d4c, 0x9d4d, 0x9d4e, 0x9d4f, 0x9d50, 0x9d51, 0x9d52, + 0x9d53, 0x9d54, 0x9d55, 0x9d56, 0x9d57, 0x9d58, 0x9d59, 0x9d5a, + 0x9d5b, 0x9d5c, 0x9d5d, 0x9d5e, 0x9d5f, 0x9d60, 0x9d61, 0x9d62, + 0x9d63, 0x9d64, 0x9d65, 0x9d66, 0x9d67, 0x9d68, 0x9d69, 0x9d6a, + 0x9d6b, 0x9d6c, 0x9d6d, 0x9d6e, 0x9d6f, 0x9d70, 0x9d71, 0x9d72, + 0x9d73, 0x9d74, 0x9d75, 0x9d76, 0x9d77, 0x9d78, 0x9d79, 0x9d7a, + 0x9d7b, 0x9d7c, 0x9d7d, 0x9d7e, 0x9d7f, 0x9d80, 0x9d81, 0x9d82, + 0x9d83, 0x9d84, 0x9d85, 0x9d86, 0x9d87, 0x9d88, 0x9d89, 0x9d8a, + 0x9d8b, 0x9d8c, 0x9d8d, 0x9d8e, 0x9d8f, 0x9d90, 0x9d91, 0x9d92, + 0x9d93, 0x9d94, 0x9d95, 0x9d96, 0x9d97, 0x9d98, 0x9d99, 0x9d9a, + 0x9d9b, 0x9d9c, 0x9d9d, 0x9d9e, 0x9d9f, 0x9da0, 0x9da1, 0x9da2, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0xfa */ + 0x9da3, 0x9da4, 0x9da5, 0x9da6, 0x9da7, 0x9da8, 0x9da9, 0x9daa, + 0x9dab, 0x9dac, 0x9dad, 0x9dae, 0x9daf, 0x9db0, 0x9db1, 0x9db2, + 0x9db3, 0x9db4, 0x9db5, 0x9db6, 0x9db7, 0x9db8, 0x9db9, 0x9dba, + 0x9dbb, 0x9dbc, 0x9dbd, 0x9dbe, 0x9dbf, 0x9dc0, 0x9dc1, 0x9dc2, + 0x9dc3, 0x9dc4, 0x9dc5, 0x9dc6, 0x9dc7, 0x9dc8, 0x9dc9, 0x9dca, + 0x9dcb, 0x9dcc, 0x9dcd, 0x9dce, 0x9dcf, 0x9dd0, 0x9dd1, 0x9dd2, + 0x9dd3, 0x9dd4, 0x9dd5, 0x9dd6, 0x9dd7, 0x9dd8, 0x9dd9, 0x9dda, + 0x9ddb, 0x9ddc, 0x9ddd, 0x9dde, 0x9ddf, 0x9de0, 0x9de1, 0x9de2, + 0x9de3, 0x9de4, 0x9de5, 0x9de6, 0x9de7, 0x9de8, 0x9de9, 0x9dea, + 0x9deb, 0x9dec, 0x9ded, 0x9dee, 0x9def, 0x9df0, 0x9df1, 0x9df2, + 0x9df3, 0x9df4, 0x9df5, 0x9df6, 0x9df7, 0x9df8, 0x9df9, 0x9dfa, + 0x9dfb, 0x9dfc, 0x9dfd, 0x9dfe, 0x9dff, 0x9e00, 0x9e01, 0x9e02, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0xfb */ + 0x9e03, 0x9e04, 0x9e05, 0x9e06, 0x9e07, 0x9e08, 0x9e09, 0x9e0a, + 0x9e0b, 0x9e0c, 0x9e0d, 0x9e0e, 0x9e0f, 0x9e10, 0x9e11, 0x9e12, + 0x9e13, 0x9e14, 0x9e15, 0x9e16, 0x9e17, 0x9e18, 0x9e19, 0x9e1a, + 0x9e1b, 0x9e1c, 0x9e1d, 0x9e1e, 0x9e24, 0x9e27, 0x9e2e, 0x9e30, + 0x9e34, 0x9e3b, 0x9e3c, 0x9e40, 0x9e4d, 0x9e50, 0x9e52, 0x9e53, + 0x9e54, 0x9e56, 0x9e59, 0x9e5d, 0x9e5f, 0x9e60, 0x9e61, 0x9e62, + 0x9e65, 0x9e6e, 0x9e6f, 0x9e72, 0x9e74, 0x9e75, 0x9e76, 0x9e77, + 0x9e78, 0x9e79, 0x9e7a, 0x9e7b, 0x9e7c, 0x9e7d, 0x9e80, 0x9e81, + 0x9e83, 0x9e84, 0x9e85, 0x9e86, 0x9e89, 0x9e8a, 0x9e8c, 0x9e8d, + 0x9e8e, 0x9e8f, 0x9e90, 0x9e91, 0x9e94, 0x9e95, 0x9e96, 0x9e97, + 0x9e98, 0x9e99, 0x9e9a, 0x9e9b, 0x9e9c, 0x9e9e, 0x9ea0, 0x9ea1, + 0x9ea2, 0x9ea3, 0x9ea4, 0x9ea5, 0x9ea7, 0x9ea8, 0x9ea9, 0x9eaa, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0xfc */ + 0x9eab, 0x9eac, 0x9ead, 0x9eae, 0x9eaf, 0x9eb0, 0x9eb1, 0x9eb2, + 0x9eb3, 0x9eb5, 0x9eb6, 0x9eb7, 0x9eb9, 0x9eba, 0x9ebc, 0x9ebf, + 0x9ec0, 0x9ec1, 0x9ec2, 0x9ec3, 0x9ec5, 0x9ec6, 0x9ec7, 0x9ec8, + 0x9eca, 0x9ecb, 0x9ecc, 0x9ed0, 0x9ed2, 0x9ed3, 0x9ed5, 0x9ed6, + 0x9ed7, 0x9ed9, 0x9eda, 0x9ede, 0x9ee1, 0x9ee3, 0x9ee4, 0x9ee6, + 0x9ee8, 0x9eeb, 0x9eec, 0x9eed, 0x9eee, 0x9ef0, 0x9ef1, 0x9ef2, + 0x9ef3, 0x9ef4, 0x9ef5, 0x9ef6, 0x9ef7, 0x9ef8, 0x9efa, 0x9efd, + 0x9eff, 0x9f00, 0x9f01, 0x9f02, 0x9f03, 0x9f04, 0x9f05, 0x9f06, + 0x9f07, 0x9f08, 0x9f09, 0x9f0a, 0x9f0c, 0x9f0f, 0x9f11, 0x9f12, + 0x9f14, 0x9f15, 0x9f16, 0x9f18, 0x9f1a, 0x9f1b, 0x9f1c, 0x9f1d, + 0x9f1e, 0x9f1f, 0x9f21, 0x9f23, 0x9f24, 0x9f25, 0x9f26, 0x9f27, + 0x9f28, 0x9f29, 0x9f2a, 0x9f2b, 0x9f2d, 0x9f2e, 0x9f30, 0x9f31, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0xfd */ + 0x9f32, 0x9f33, 0x9f34, 0x9f35, 0x9f36, 0x9f38, 0x9f3a, 0x9f3c, + 0x9f3f, 0x9f40, 0x9f41, 0x9f42, 0x9f43, 0x9f45, 0x9f46, 0x9f47, + 0x9f48, 0x9f49, 0x9f4a, 0x9f4b, 0x9f4c, 0x9f4d, 0x9f4e, 0x9f4f, + 0x9f52, 0x9f53, 0x9f54, 0x9f55, 0x9f56, 0x9f57, 0x9f58, 0x9f59, + 0x9f5a, 0x9f5b, 0x9f5c, 0x9f5d, 0x9f5e, 0x9f5f, 0x9f60, 0x9f61, + 0x9f62, 0x9f63, 0x9f64, 0x9f65, 0x9f66, 0x9f67, 0x9f68, 0x9f69, + 0x9f6a, 0x9f6b, 0x9f6c, 0x9f6d, 0x9f6e, 0x9f6f, 0x9f70, 0x9f71, + 0x9f72, 0x9f73, 0x9f74, 0x9f75, 0x9f76, 0x9f77, 0x9f78, 0x9f79, + 0x9f7a, 0x9f7b, 0x9f7c, 0x9f7d, 0x9f7e, 0x9f81, 0x9f82, 0x9f8d, + 0x9f8e, 0x9f8f, 0x9f90, 0x9f91, 0x9f92, 0x9f93, 0x9f94, 0x9f95, + 0x9f96, 0x9f97, 0x9f98, 0x9f9c, 0x9f9d, 0x9f9e, 0x9fa1, 0x9fa2, + 0x9fa3, 0x9fa4, 0x9fa5, 0xf92c, 0xf979, 0xf995, 0xf9e7, 0xf9f1, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0xfe */ + 0xfa0c, 0xfa0d, 0xfa0e, 0xfa0f, 0xfa11, 0xfa13, 0xfa14, 0xfa18, + 0xfa1f, 0xfa20, 0xfa21, 0xfa23, 0xfa24, 0xfa27, 0xfa28, 0xfa29, +}; + +static int +cp936ext_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c1 = s[0]; + if ((c1 >= 0x81 && c1 <= 0xfe)) { + if (n >= 2) { + unsigned char c2 = s[1]; + if ((c2 >= 0x40 && c2 < 0x7f) || (c2 >= 0x80 && c2 < 0xff)) { + unsigned int i = 190 * (c1 - 0x81) + (c2 - (c2 >= 0x80 ? 0x41 : 0x40)); + unsigned short wc = 0xfffd; + { + if (i < 23766) + wc = cp936ext_2uni_page81[i]; + } + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 2; + } + } + return RET_ILSEQ; + } + return RET_TOOFEW(0); + } + return RET_ILSEQ; +} + +static const unsigned short cp936ext_page0014[208] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0xa1e8, 0x0000, 0x0000, 0xa1ec, /*0xa0-0xa7*/ + 0xa1a7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0xa8-0xaf*/ + 0xa1e3, 0xa1c0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa1a4, /*0xb0-0xb7*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0xb8-0xbf*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0xc0-0xc7*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0xc8-0xcf*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa1c1, /*0xd0-0xd7*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0xd8-0xdf*/ + 0xa8a4, 0xa8a2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0xe0-0xe7*/ + 0xa8a8, 0xa8a6, 0xa8ba, 0x0000, 0xa8ac, 0xa8aa, 0x0000, 0x0000, /*0xe8-0xef*/ + 0x0000, 0x0000, 0xa8b0, 0xa8ae, 0x0000, 0x0000, 0x0000, 0xa1c2, /*0xf0-0xf7*/ + 0x0000, 0xa8b4, 0xa8b2, 0x0000, 0xa8b9, 0x0000, 0x0000, 0x0000, /*0xf8-0xff*/ + /* 0x0100 */ + 0x0000, 0xa8a1, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x00-0x07*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x08-0x0f*/ + 0x0000, 0x0000, 0x0000, 0xa8a5, 0x0000, 0x0000, 0x0000, 0x0000, /*0x10-0x17*/ + 0x0000, 0x0000, 0x0000, 0xa8a7, 0x0000, 0x0000, 0x0000, 0x0000, /*0x18-0x1f*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x20-0x27*/ + 0x0000, 0x0000, 0x0000, 0xa8a9, 0x0000, 0x0000, 0x0000, 0x0000, /*0x28-0x2f*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x30-0x37*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x38-0x3f*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0xa8bd, 0x0000, 0x0000, 0x0000, /*0x40-0x47*/ + 0xa8be, 0x0000, 0x0000, 0x0000, 0x0000, 0xa8ad, 0x0000, 0x0000, /*0x48-0x4f*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x50-0x57*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x58-0x5f*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x60-0x67*/ + 0x0000, 0x0000, 0x0000, 0xa8b1, 0x0000, 0x0000, 0x0000, 0x0000, /*0x68-0x6f*/ +}; +static const unsigned short cp936ext_page0039[24] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa8a3, 0x0000, /*0xc8-0xcf*/ + 0xa8ab, 0x0000, 0xa8af, 0x0000, 0xa8b3, 0x0000, 0xa8b5, 0x0000, /*0xd0-0xd7*/ + 0xa8b6, 0x0000, 0xa8b7, 0x0000, 0xa8b8, 0x0000, 0x0000, 0x0000, /*0xd8-0xdf*/ +}; +static const unsigned short cp936ext_page004a[24] = { + 0x0000, 0xa8bb, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x50-0x57*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x58-0x5f*/ + 0x0000, 0xa8c0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x60-0x67*/ +}; +static const unsigned short cp936ext_page0058[32] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa1a6, /*0xc0-0xc7*/ + 0x0000, 0xa1a5, 0xa840, 0xa841, 0x0000, 0x0000, 0x0000, 0x0000, /*0xc8-0xcf*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0xd0-0xd7*/ + 0x0000, 0xa842, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0xd8-0xdf*/ +}; +static const unsigned short cp936ext_page0072[64] = { + 0x0000, 0xa6a1, 0xa6a2, 0xa6a3, 0xa6a4, 0xa6a5, 0xa6a6, 0xa6a7, /*0x90-0x97*/ + 0xa6a8, 0xa6a9, 0xa6aa, 0xa6ab, 0xa6ac, 0xa6ad, 0xa6ae, 0xa6af, /*0x98-0x9f*/ + 0xa6b0, 0xa6b1, 0x0000, 0xa6b2, 0xa6b3, 0xa6b4, 0xa6b5, 0xa6b6, /*0xa0-0xa7*/ + 0xa6b7, 0xa6b8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0xa8-0xaf*/ + 0x0000, 0xa6c1, 0xa6c2, 0xa6c3, 0xa6c4, 0xa6c5, 0xa6c6, 0xa6c7, /*0xb0-0xb7*/ + 0xa6c8, 0xa6c9, 0xa6ca, 0xa6cb, 0xa6cc, 0xa6cd, 0xa6ce, 0xa6cf, /*0xb8-0xbf*/ + 0xa6d0, 0xa6d1, 0x0000, 0xa6d2, 0xa6d3, 0xa6d4, 0xa6d5, 0xa6d6, /*0xc0-0xc7*/ + 0xa6d7, 0xa6d8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0xc8-0xcf*/ +}; +static const unsigned short cp936ext_page0080[88] = { + 0x0000, 0xa7a7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x00-0x07*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x08-0x0f*/ + 0xa7a1, 0xa7a2, 0xa7a3, 0xa7a4, 0xa7a5, 0xa7a6, 0xa7a8, 0xa7a9, /*0x10-0x17*/ + 0xa7aa, 0xa7ab, 0xa7ac, 0xa7ad, 0xa7ae, 0xa7af, 0xa7b0, 0xa7b1, /*0x18-0x1f*/ + 0xa7b2, 0xa7b3, 0xa7b4, 0xa7b5, 0xa7b6, 0xa7b7, 0xa7b8, 0xa7b9, /*0x20-0x27*/ + 0xa7ba, 0xa7bb, 0xa7bc, 0xa7bd, 0xa7be, 0xa7bf, 0xa7c0, 0xa7c1, /*0x28-0x2f*/ + 0xa7d1, 0xa7d2, 0xa7d3, 0xa7d4, 0xa7d5, 0xa7d6, 0xa7d8, 0xa7d9, /*0x30-0x37*/ + 0xa7da, 0xa7db, 0xa7dc, 0xa7dd, 0xa7de, 0xa7df, 0xa7e0, 0xa7e1, /*0x38-0x3f*/ + 0xa7e2, 0xa7e3, 0xa7e4, 0xa7e5, 0xa7e6, 0xa7e7, 0xa7e8, 0xa7e9, /*0x40-0x47*/ + 0xa7ea, 0xa7eb, 0xa7ec, 0xa7ed, 0xa7ee, 0xa7ef, 0xa7f0, 0xa7f1, /*0x48-0x4f*/ + 0x0000, 0xa7d7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x50-0x57*/ +}; +static const unsigned short cp936ext_page0402[48] = { + 0xa95c, 0x0000, 0x0000, 0xa843, 0xa1aa, 0xa844, 0xa1ac, 0x0000, /*0x10-0x17*/ + 0xa1ae, 0xa1af, 0x0000, 0x0000, 0xa1b0, 0xa1b1, 0x0000, 0x0000, /*0x18-0x1f*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa845, 0xa1ad, 0x0000, /*0x20-0x27*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x28-0x2f*/ + 0xa1eb, 0x0000, 0xa1e4, 0xa1e5, 0x0000, 0xa846, 0x0000, 0x0000, /*0x30-0x37*/ + 0x0000, 0x0000, 0x0000, 0xa1f9, 0x0000, 0x0000, 0x0000, 0x0000, /*0x38-0x3f*/ +}; +static const unsigned short cp936ext_page0420[160] = { + 0x0000, 0x0000, 0x0000, 0xa1e6, 0x0000, 0xa847, 0x0000, 0x0000, /*0x00-0x07*/ + 0x0000, 0xa848, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x08-0x0f*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa1ed, 0x0000, /*0x10-0x17*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x18-0x1f*/ + 0x0000, 0xa959, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x20-0x27*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x28-0x2f*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x30-0x37*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x38-0x3f*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x40-0x47*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x48-0x4f*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x50-0x57*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x58-0x5f*/ + 0xa2f1, 0xa2f2, 0xa2f3, 0xa2f4, 0xa2f5, 0xa2f6, 0xa2f7, 0xa2f8, /*0x60-0x67*/ + 0xa2f9, 0xa2fa, 0xa2fb, 0xa2fc, 0x0000, 0x0000, 0x0000, 0x0000, /*0x68-0x6f*/ + 0xa2a1, 0xa2a2, 0xa2a3, 0xa2a4, 0xa2a5, 0xa2a6, 0xa2a7, 0xa2a8, /*0x70-0x77*/ + 0xa2a9, 0xa2aa, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x78-0x7f*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x80-0x87*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x88-0x8f*/ + 0xa1fb, 0xa1fc, 0xa1fa, 0xa1fd, 0x0000, 0x0000, 0xa849, 0xa84a, /*0x90-0x97*/ + 0xa84b, 0xa84c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x98-0x9f*/ +}; +static const unsigned short cp936ext_page0441[184] = { + 0xa1ca, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa1c7, /*0x08-0x0f*/ + 0x0000, 0xa1c6, 0x0000, 0x0000, 0x0000, 0xa84d, 0x0000, 0x0000, /*0x10-0x17*/ + 0x0000, 0x0000, 0xa1cc, 0x0000, 0x0000, 0xa1d8, 0xa1de, 0xa84e, /*0x18-0x1f*/ + 0xa1cf, 0x0000, 0x0000, 0xa84f, 0x0000, 0xa1ce, 0x0000, 0xa1c4, /*0x20-0x27*/ + 0xa1c5, 0xa1c9, 0xa1c8, 0xa1d2, 0x0000, 0x0000, 0xa1d3, 0x0000, /*0x28-0x2f*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0xa1e0, 0xa1df, 0xa1c3, 0xa1cb, /*0x30-0x37*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa1d7, 0x0000, 0x0000, /*0x38-0x3f*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x40-0x47*/ + 0xa1d6, 0x0000, 0x0000, 0x0000, 0xa1d5, 0x0000, 0x0000, 0x0000, /*0x48-0x4f*/ + 0x0000, 0x0000, 0xa850, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x50-0x57*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x58-0x5f*/ + 0xa1d9, 0xa1d4, 0x0000, 0x0000, 0xa1dc, 0xa1dd, 0xa851, 0xa852, /*0x60-0x67*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa1da, 0xa1db, /*0x68-0x6f*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x70-0x77*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x78-0x7f*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x80-0x87*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x88-0x8f*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa892, 0x0000, 0x0000, /*0x90-0x97*/ + 0x0000, 0xa1d1, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x98-0x9f*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa1cd, 0x0000, 0x0000, /*0xa0-0xa7*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0xa8-0xaf*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0xb0-0xb7*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa853, /*0xb8-0xbf*/ +}; +static const unsigned short cp936ext_page048c[64] = { + 0xa2d9, 0xa2da, 0xa2db, 0xa2dc, 0xa2dd, 0xa2de, 0xa2df, 0xa2e0, /*0x60-0x67*/ + 0xa2e1, 0xa2e2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x68-0x6f*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0xa2c5, 0xa2c6, 0xa2c7, 0xa2c8, /*0x70-0x77*/ + 0xa2c9, 0xa2ca, 0xa2cb, 0xa2cc, 0xa2cd, 0xa2ce, 0xa2cf, 0xa2d0, /*0x78-0x7f*/ + 0xa2d1, 0xa2d2, 0xa2d3, 0xa2d4, 0xa2d5, 0xa2d6, 0xa2d7, 0xa2d8, /*0x80-0x87*/ + 0xa2b1, 0xa2b2, 0xa2b3, 0xa2b4, 0xa2b5, 0xa2b6, 0xa2b7, 0xa2b8, /*0x88-0x8f*/ + 0xa2b9, 0xa2ba, 0xa2bb, 0xa2bc, 0xa2bd, 0xa2be, 0xa2bf, 0xa2c0, /*0x90-0x97*/ + 0xa2c1, 0xa2c2, 0xa2c3, 0xa2c4, 0x0000, 0x0000, 0x0000, 0x0000, /*0x98-0x9f*/ +}; +static const unsigned short cp936ext_page04a0[232] = { + 0xa9a4, 0xa9a5, 0xa9a6, 0xa9a7, 0xa9a8, 0xa9a9, 0xa9aa, 0xa9ab, /*0x00-0x07*/ + 0xa9ac, 0xa9ad, 0xa9ae, 0xa9af, 0xa9b0, 0xa9b1, 0xa9b2, 0xa9b3, /*0x08-0x0f*/ + 0xa9b4, 0xa9b5, 0xa9b6, 0xa9b7, 0xa9b8, 0xa9b9, 0xa9ba, 0xa9bb, /*0x10-0x17*/ + 0xa9bc, 0xa9bd, 0xa9be, 0xa9bf, 0xa9c0, 0xa9c1, 0xa9c2, 0xa9c3, /*0x18-0x1f*/ + 0xa9c4, 0xa9c5, 0xa9c6, 0xa9c7, 0xa9c8, 0xa9c9, 0xa9ca, 0xa9cb, /*0x20-0x27*/ + 0xa9cc, 0xa9cd, 0xa9ce, 0xa9cf, 0xa9d0, 0xa9d1, 0xa9d2, 0xa9d3, /*0x28-0x2f*/ + 0xa9d4, 0xa9d5, 0xa9d6, 0xa9d7, 0xa9d8, 0xa9d9, 0xa9da, 0xa9db, /*0x30-0x37*/ + 0xa9dc, 0xa9dd, 0xa9de, 0xa9df, 0xa9e0, 0xa9e1, 0xa9e2, 0xa9e3, /*0x38-0x3f*/ + 0xa9e4, 0xa9e5, 0xa9e6, 0xa9e7, 0xa9e8, 0xa9e9, 0xa9ea, 0xa9eb, /*0x40-0x47*/ + 0xa9ec, 0xa9ed, 0xa9ee, 0xa9ef, 0x0000, 0x0000, 0x0000, 0x0000, /*0x48-0x4f*/ + 0xa854, 0xa855, 0xa856, 0xa857, 0xa858, 0xa859, 0xa85a, 0xa85b, /*0x50-0x57*/ + 0xa85c, 0xa85d, 0xa85e, 0xa85f, 0xa860, 0xa861, 0xa862, 0xa863, /*0x58-0x5f*/ + 0xa864, 0xa865, 0xa866, 0xa867, 0xa868, 0xa869, 0xa86a, 0xa86b, /*0x60-0x67*/ + 0xa86c, 0xa86d, 0xa86e, 0xa86f, 0xa870, 0xa871, 0xa872, 0xa873, /*0x68-0x6f*/ + 0xa874, 0xa875, 0xa876, 0xa877, 0x0000, 0x0000, 0x0000, 0x0000, /*0x70-0x77*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x78-0x7f*/ + 0x0000, 0xa878, 0xa879, 0xa87a, 0xa87b, 0xa87c, 0xa87d, 0xa87e, /*0x80-0x87*/ + 0xa880, 0xa881, 0xa882, 0xa883, 0xa884, 0xa885, 0xa886, 0xa887, /*0x88-0x8f*/ + 0x0000, 0x0000, 0x0000, 0xa888, 0xa889, 0xa88a, 0x0000, 0x0000, /*0x90-0x97*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x98-0x9f*/ + 0xa1f6, 0xa1f5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0xa0-0xa7*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0xa8-0xaf*/ + 0x0000, 0x0000, 0xa1f8, 0xa1f7, 0x0000, 0x0000, 0x0000, 0x0000, /*0xb0-0xb7*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0xa88b, 0xa88c, 0x0000, 0x0000, /*0xb8-0xbf*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa1f4, 0xa1f3, /*0xc0-0xc7*/ + 0x0000, 0x0000, 0x0000, 0xa1f0, 0x0000, 0x0000, 0xa1f2, 0xa1f1, /*0xc8-0xcf*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0xd0-0xd7*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0xd8-0xdf*/ + 0x0000, 0x0000, 0xa88d, 0xa88e, 0xa88f, 0xa890, 0x0000, 0x0000, /*0xe0-0xe7*/ +}; +static const unsigned short cp936ext_page04c0[72] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa1ef, 0xa1ee, 0x0000, /*0x00-0x07*/ + 0x0000, 0xa891, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x08-0x0f*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x10-0x17*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x18-0x1f*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x20-0x27*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x28-0x2f*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x30-0x37*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x38-0x3f*/ + 0xa1e2, 0x0000, 0xa1e1, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x40-0x47*/ +}; +static const unsigned short cp936ext_page0600[304] = { + 0xa1a1, 0xa1a2, 0xa1a3, 0xa1a8, 0x0000, 0xa1a9, 0xa965, 0xa996, /*0x00-0x07*/ + 0xa1b4, 0xa1b5, 0xa1b6, 0xa1b7, 0xa1b8, 0xa1b9, 0xa1ba, 0xa1bb, /*0x08-0x0f*/ + 0xa1be, 0xa1bf, 0xa893, 0xa1fe, 0xa1b2, 0xa1b3, 0xa1bc, 0xa1bd, /*0x10-0x17*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa894, 0xa895, 0x0000, /*0x18-0x1f*/ + 0x0000, 0xa940, 0xa941, 0xa942, 0xa943, 0xa944, 0xa945, 0xa946, /*0x20-0x27*/ + 0xa947, 0xa948, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x28-0x2f*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x30-0x37*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x38-0x3f*/ + 0x0000, 0xa4a1, 0xa4a2, 0xa4a3, 0xa4a4, 0xa4a5, 0xa4a6, 0xa4a7, /*0x40-0x47*/ + 0xa4a8, 0xa4a9, 0xa4aa, 0xa4ab, 0xa4ac, 0xa4ad, 0xa4ae, 0xa4af, /*0x48-0x4f*/ + 0xa4b0, 0xa4b1, 0xa4b2, 0xa4b3, 0xa4b4, 0xa4b5, 0xa4b6, 0xa4b7, /*0x50-0x57*/ + 0xa4b8, 0xa4b9, 0xa4ba, 0xa4bb, 0xa4bc, 0xa4bd, 0xa4be, 0xa4bf, /*0x58-0x5f*/ + 0xa4c0, 0xa4c1, 0xa4c2, 0xa4c3, 0xa4c4, 0xa4c5, 0xa4c6, 0xa4c7, /*0x60-0x67*/ + 0xa4c8, 0xa4c9, 0xa4ca, 0xa4cb, 0xa4cc, 0xa4cd, 0xa4ce, 0xa4cf, /*0x68-0x6f*/ + 0xa4d0, 0xa4d1, 0xa4d2, 0xa4d3, 0xa4d4, 0xa4d5, 0xa4d6, 0xa4d7, /*0x70-0x77*/ + 0xa4d8, 0xa4d9, 0xa4da, 0xa4db, 0xa4dc, 0xa4dd, 0xa4de, 0xa4df, /*0x78-0x7f*/ + 0xa4e0, 0xa4e1, 0xa4e2, 0xa4e3, 0xa4e4, 0xa4e5, 0xa4e6, 0xa4e7, /*0x80-0x87*/ + 0xa4e8, 0xa4e9, 0xa4ea, 0xa4eb, 0xa4ec, 0xa4ed, 0xa4ee, 0xa4ef, /*0x88-0x8f*/ + 0xa4f0, 0xa4f1, 0xa4f2, 0xa4f3, 0x0000, 0x0000, 0x0000, 0x0000, /*0x90-0x97*/ + 0x0000, 0x0000, 0x0000, 0xa961, 0xa962, 0xa966, 0xa967, 0x0000, /*0x98-0x9f*/ + 0x0000, 0xa5a1, 0xa5a2, 0xa5a3, 0xa5a4, 0xa5a5, 0xa5a6, 0xa5a7, /*0xa0-0xa7*/ + 0xa5a8, 0xa5a9, 0xa5aa, 0xa5ab, 0xa5ac, 0xa5ad, 0xa5ae, 0xa5af, /*0xa8-0xaf*/ + 0xa5b0, 0xa5b1, 0xa5b2, 0xa5b3, 0xa5b4, 0xa5b5, 0xa5b6, 0xa5b7, /*0xb0-0xb7*/ + 0xa5b8, 0xa5b9, 0xa5ba, 0xa5bb, 0xa5bc, 0xa5bd, 0xa5be, 0xa5bf, /*0xb8-0xbf*/ + 0xa5c0, 0xa5c1, 0xa5c2, 0xa5c3, 0xa5c4, 0xa5c5, 0xa5c6, 0xa5c7, /*0xc0-0xc7*/ + 0xa5c8, 0xa5c9, 0xa5ca, 0xa5cb, 0xa5cc, 0xa5cd, 0xa5ce, 0xa5cf, /*0xc8-0xcf*/ + 0xa5d0, 0xa5d1, 0xa5d2, 0xa5d3, 0xa5d4, 0xa5d5, 0xa5d6, 0xa5d7, /*0xd0-0xd7*/ + 0xa5d8, 0xa5d9, 0xa5da, 0xa5db, 0xa5dc, 0xa5dd, 0xa5de, 0xa5df, /*0xd8-0xdf*/ + 0xa5e0, 0xa5e1, 0xa5e2, 0xa5e3, 0xa5e4, 0xa5e5, 0xa5e6, 0xa5e7, /*0xe0-0xe7*/ + 0xa5e8, 0xa5e9, 0xa5ea, 0xa5eb, 0xa5ec, 0xa5ed, 0xa5ee, 0xa5ef, /*0xe8-0xef*/ + 0xa5f0, 0xa5f1, 0xa5f2, 0xa5f3, 0xa5f4, 0xa5f5, 0xa5f6, 0x0000, /*0xf0-0xf7*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0xa960, 0xa963, 0xa964, 0x0000, /*0xf8-0xff*/ + /* 0x3100 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa8c5, 0xa8c6, 0xa8c7, /*0x00-0x07*/ + 0xa8c8, 0xa8c9, 0xa8ca, 0xa8cb, 0xa8cc, 0xa8cd, 0xa8ce, 0xa8cf, /*0x08-0x0f*/ + 0xa8d0, 0xa8d1, 0xa8d2, 0xa8d3, 0xa8d4, 0xa8d5, 0xa8d6, 0xa8d7, /*0x10-0x17*/ + 0xa8d8, 0xa8d9, 0xa8da, 0xa8db, 0xa8dc, 0xa8dd, 0xa8de, 0xa8df, /*0x18-0x1f*/ + 0xa8e0, 0xa8e1, 0xa8e2, 0xa8e3, 0xa8e4, 0xa8e5, 0xa8e6, 0xa8e7, /*0x20-0x27*/ + 0xa8e8, 0xa8e9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x28-0x2f*/ +}; +static const unsigned short cp936ext_page0644[24] = { + 0xa2e5, 0xa2e6, 0xa2e7, 0xa2e8, 0xa2e9, 0xa2ea, 0xa2eb, 0xa2ec, /*0x20-0x27*/ + 0xa2ed, 0xa2ee, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x28-0x2f*/ + 0x0000, 0xa95a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x30-0x37*/ +}; +static const unsigned short cp936ext_page0671[80] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa94a, 0xa94b, /*0x88-0x8f*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x90-0x97*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0xa94c, 0xa94d, 0xa94e, 0x0000, /*0x98-0x9f*/ + 0x0000, 0xa94f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0xa0-0xa7*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0xa8-0xaf*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0xb0-0xb7*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0xb8-0xbf*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0xa950, 0x0000, 0x0000, 0x0000, /*0xc0-0xc7*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa951, 0x0000, /*0xc8-0xcf*/ + 0x0000, 0xa952, 0xa953, 0x0000, 0x0000, 0xa954, 0x0000, 0x0000, /*0xd0-0xd7*/ +}; +static const unsigned short cp936ext_page09c0[20904] = { + 0xd2bb, 0xb6a1, 0x8140, 0xc6df, 0x8141, 0x8142, 0x8143, 0xcdf2, /*0x00-0x07*/ + 0xd5c9, 0xc8fd, 0xc9cf, 0xcfc2, 0xd8a2, 0xb2bb, 0xd3eb, 0x8144, /*0x08-0x0f*/ + 0xd8a4, 0xb3f3, 0x8145, 0xd7a8, 0xc7d2, 0xd8a7, 0xcac0, 0x8146, /*0x10-0x17*/ + 0xc7f0, 0xb1fb, 0xd2b5, 0xb4d4, 0xb6ab, 0xcbbf, 0xd8a9, 0x8147, /*0x18-0x1f*/ + 0x8148, 0x8149, 0xb6aa, 0x814a, 0xc1bd, 0xd1cf, 0x814b, 0xc9a5, /*0x20-0x27*/ + 0xd8ad, 0x814c, 0xb8f6, 0xd1be, 0xe3dc, 0xd6d0, 0x814d, 0x814e, /*0x28-0x2f*/ + 0xb7e1, 0x814f, 0xb4ae, 0x8150, 0xc1d9, 0x8151, 0xd8bc, 0x8152, /*0x30-0x37*/ + 0xcde8, 0xb5a4, 0xceaa, 0xd6f7, 0x8153, 0xc0f6, 0xbed9, 0xd8af, /*0x38-0x3f*/ + 0x8154, 0x8155, 0x8156, 0xc4cb, 0x8157, 0xbec3, 0x8158, 0xd8b1, /*0x40-0x47*/ + 0xc3b4, 0xd2e5, 0x8159, 0xd6ae, 0xceda, 0xd5a7, 0xbaf5, 0xb7a6, /*0x48-0x4f*/ + 0xc0d6, 0x815a, 0xc6b9, 0xc5d2, 0xc7c7, 0x815b, 0xb9d4, 0x815c, /*0x50-0x57*/ + 0xb3cb, 0xd2d2, 0x815d, 0x815e, 0xd8bf, 0xbec5, 0xc6f2, 0xd2b2, /*0x58-0x5f*/ + 0xcfb0, 0xcfe7, 0x815f, 0x8160, 0x8161, 0x8162, 0xcae9, 0x8163, /*0x60-0x67*/ + 0x8164, 0xd8c0, 0x8165, 0x8166, 0x8167, 0x8168, 0x8169, 0x816a, /*0x68-0x6f*/ + 0xc2f2, 0xc2d2, 0x816b, 0xc8e9, 0x816c, 0x816d, 0x816e, 0x816f, /*0x70-0x77*/ + 0x8170, 0x8171, 0x8172, 0x8173, 0x8174, 0x8175, 0xc7ac, 0x8176, /*0x78-0x7f*/ + 0x8177, 0x8178, 0x8179, 0x817a, 0x817b, 0x817c, 0xc1cb, 0x817d, /*0x80-0x87*/ + 0xd3e8, 0xd5f9, 0x817e, 0xcac2, 0xb6fe, 0xd8a1, 0xd3da, 0xbff7, /*0x88-0x8f*/ + 0x8180, 0xd4c6, 0xbba5, 0xd8c1, 0xcee5, 0xbeae, 0x8181, 0x8182, /*0x90-0x97*/ + 0xd8a8, 0x8183, 0xd1c7, 0xd0a9, 0x8184, 0x8185, 0x8186, 0xd8bd, /*0x98-0x9f*/ + 0xd9ef, 0xcdf6, 0xbfba, 0x8187, 0xbdbb, 0xbaa5, 0xd2e0, 0xb2fa, /*0xa0-0xa7*/ + 0xbae0, 0xc4b6, 0x8188, 0xcfed, 0xbea9, 0xcda4, 0xc1c1, 0x8189, /*0xa8-0xaf*/ + 0x818a, 0x818b, 0xc7d7, 0xd9f1, 0x818c, 0xd9f4, 0x818d, 0x818e, /*0xb0-0xb7*/ + 0x818f, 0x8190, 0xc8cb, 0xd8e9, 0x8191, 0x8192, 0x8193, 0xd2da, /*0xb8-0xbf*/ + 0xcab2, 0xc8ca, 0xd8ec, 0xd8ea, 0xd8c6, 0xbdf6, 0xc6cd, 0xb3f0, /*0xc0-0xc7*/ + 0x8194, 0xd8eb, 0xbdf1, 0xbde9, 0x8195, 0xc8d4, 0xb4d3, 0x8196, /*0xc8-0xcf*/ + 0x8197, 0xc2d8, 0x8198, 0xb2d6, 0xd7d0, 0xcacb, 0xcbfb, 0xd5cc, /*0xd0-0xd7*/ + 0xb8b6, 0xcfc9, 0x8199, 0x819a, 0x819b, 0xd9da, 0xd8f0, 0xc7aa, /*0xd8-0xdf*/ + 0x819c, 0xd8ee, 0x819d, 0xb4fa, 0xc1ee, 0xd2d4, 0x819e, 0x819f, /*0xe0-0xe7*/ + 0xd8ed, 0x81a0, 0xd2c7, 0xd8ef, 0xc3c7, 0x81a1, 0x81a2, 0x81a3, /*0xe8-0xef*/ + 0xd1f6, 0x81a4, 0xd6d9, 0xd8f2, 0x81a5, 0xd8f5, 0xbcfe, 0xbcdb, /*0xf0-0xf7*/ + 0x81a6, 0x81a7, 0x81a8, 0xc8ce, 0x81a9, 0xb7dd, 0x81aa, 0xb7c2, /*0xf8-0xff*/ + /* 0x4f00 */ + 0x81ab, 0xc6f3, 0x81ac, 0x81ad, 0x81ae, 0x81af, 0x81b0, 0x81b1, /*0x00-0x07*/ + 0x81b2, 0xd8f8, 0xd2c1, 0x81b3, 0x81b4, 0xcee9, 0xbcbf, 0xb7fc, /*0x08-0x0f*/ + 0xb7a5, 0xd0dd, 0x81b5, 0x81b6, 0x81b7, 0x81b8, 0x81b9, 0xd6da, /*0x10-0x17*/ + 0xd3c5, 0xbbef, 0xbbe1, 0xd8f1, 0x81ba, 0x81bb, 0xc9a1, 0xceb0, /*0x18-0x1f*/ + 0xb4ab, 0x81bc, 0xd8f3, 0x81bd, 0xc9cb, 0xd8f6, 0xc2d7, 0xd8f7, /*0x20-0x27*/ + 0x81be, 0x81bf, 0xceb1, 0xd8f9, 0x81c0, 0x81c1, 0x81c2, 0xb2ae, /*0x28-0x2f*/ + 0xb9c0, 0x81c3, 0xd9a3, 0x81c4, 0xb0e9, 0x81c5, 0xc1e6, 0x81c6, /*0x30-0x37*/ + 0xc9ec, 0x81c7, 0xcbc5, 0x81c8, 0xcbc6, 0xd9a4, 0x81c9, 0x81ca, /*0x38-0x3f*/ + 0x81cb, 0x81cc, 0x81cd, 0xb5e8, 0x81ce, 0x81cf, 0xb5ab, 0x81d0, /*0x40-0x47*/ + 0x81d1, 0x81d2, 0x81d3, 0x81d4, 0x81d5, 0xcebb, 0xb5cd, 0xd7a1, /*0x48-0x4f*/ + 0xd7f4, 0xd3d3, 0x81d6, 0xcce5, 0x81d7, 0xbace, 0x81d8, 0xd9a2, /*0x50-0x57*/ + 0xd9dc, 0xd3e0, 0xd8fd, 0xb7f0, 0xd7f7, 0xd8fe, 0xd8fa, 0xd9a1, /*0x58-0x5f*/ + 0xc4e3, 0x81d9, 0x81da, 0xd3b6, 0xd8f4, 0xd9dd, 0x81db, 0xd8fb, /*0x60-0x67*/ + 0x81dc, 0xc5e5, 0x81dd, 0x81de, 0xc0d0, 0x81df, 0x81e0, 0xd1f0, /*0x68-0x6f*/ + 0xb0db, 0x81e1, 0x81e2, 0xbcd1, 0xd9a6, 0x81e3, 0xd9a5, 0x81e4, /*0x70-0x77*/ + 0x81e5, 0x81e6, 0x81e7, 0xd9ac, 0xd9ae, 0x81e8, 0xd9ab, 0xcab9, /*0x78-0x7f*/ + 0x81e9, 0x81ea, 0x81eb, 0xd9a9, 0xd6b6, 0x81ec, 0x81ed, 0x81ee, /*0x80-0x87*/ + 0xb3de, 0xd9a8, 0x81ef, 0xc0fd, 0x81f0, 0xcacc, 0x81f1, 0xd9aa, /*0x88-0x8f*/ + 0x81f2, 0xd9a7, 0x81f3, 0x81f4, 0xd9b0, 0x81f5, 0x81f6, 0xb6b1, /*0x90-0x97*/ + 0x81f7, 0x81f8, 0x81f9, 0xb9a9, 0x81fa, 0xd2c0, 0x81fb, 0x81fc, /*0x98-0x9f*/ + 0xcfc0, 0x81fd, 0x81fe, 0xc2c2, 0x8240, 0xbdc4, 0xd5ec, 0xb2e0, /*0xa0-0xa7*/ + 0xc7c8, 0xbfeb, 0xd9ad, 0x8241, 0xd9af, 0x8242, 0xceea, 0xbaee, /*0xa8-0xaf*/ + 0x8243, 0x8244, 0x8245, 0x8246, 0x8247, 0xc7d6, 0x8248, 0x8249, /*0xb0-0xb7*/ + 0x824a, 0x824b, 0x824c, 0x824d, 0x824e, 0x824f, 0x8250, 0xb1e3, /*0xb8-0xbf*/ + 0x8251, 0x8252, 0x8253, 0xb4d9, 0xb6ed, 0xd9b4, 0x8254, 0x8255, /*0xc0-0xc7*/ + 0x8256, 0x8257, 0xbfa1, 0x8258, 0x8259, 0x825a, 0xd9de, 0xc7ce, /*0xc8-0xcf*/ + 0xc0fe, 0xd9b8, 0x825b, 0x825c, 0x825d, 0x825e, 0x825f, 0xcbd7, /*0xd0-0xd7*/ + 0xb7fd, 0x8260, 0xd9b5, 0x8261, 0xd9b7, 0xb1a3, 0xd3e1, 0xd9b9, /*0xd8-0xdf*/ + 0x8262, 0xd0c5, 0x8263, 0xd9b6, 0x8264, 0x8265, 0xd9b1, 0x8266, /*0xe0-0xe7*/ + 0xd9b2, 0xc1a9, 0xd9b3, 0x8267, 0x8268, 0xbcf3, 0xd0de, 0xb8a9, /*0xe8-0xef*/ + 0x8269, 0xbee3, 0x826a, 0xd9bd, 0x826b, 0x826c, 0x826d, 0x826e, /*0xf0-0xf7*/ + 0xd9ba, 0x826f, 0xb0b3, 0x8270, 0x8271, 0x8272, 0xd9c2, 0x8273, /*0xf8-0xff*/ + /* 0x5000 */ + 0x8274, 0x8275, 0x8276, 0x8277, 0x8278, 0x8279, 0x827a, 0x827b, /*0x00-0x07*/ + 0x827c, 0x827d, 0x827e, 0x8280, 0xd9c4, 0xb1b6, 0x8281, 0xd9bf, /*0x08-0x0f*/ + 0x8282, 0x8283, 0xb5b9, 0x8284, 0xbef3, 0x8285, 0x8286, 0x8287, /*0x10-0x17*/ + 0xccc8, 0xbaf2, 0xd2d0, 0x8288, 0xd9c3, 0x8289, 0x828a, 0xbde8, /*0x18-0x1f*/ + 0x828b, 0xb3ab, 0x828c, 0x828d, 0x828e, 0xd9c5, 0xbeeb, 0x828f, /*0x20-0x27*/ + 0xd9c6, 0xd9bb, 0xc4df, 0x8290, 0xd9be, 0xd9c1, 0xd9c0, 0x8291, /*0x28-0x2f*/ + 0x8292, 0x8293, 0x8294, 0x8295, 0x8296, 0x8297, 0x8298, 0x8299, /*0x30-0x37*/ + 0x829a, 0x829b, 0xd5ae, 0x829c, 0xd6b5, 0x829d, 0xc7e3, 0x829e, /*0x38-0x3f*/ + 0x829f, 0x82a0, 0x82a1, 0xd9c8, 0x82a2, 0x82a3, 0x82a4, 0xbcd9, /*0x40-0x47*/ + 0xd9ca, 0x82a5, 0x82a6, 0x82a7, 0xd9bc, 0x82a8, 0xd9cb, 0xc6ab, /*0x48-0x4f*/ + 0x82a9, 0x82aa, 0x82ab, 0x82ac, 0x82ad, 0xd9c9, 0x82ae, 0x82af, /*0x50-0x57*/ + 0x82b0, 0x82b1, 0xd7f6, 0x82b2, 0xcda3, 0x82b3, 0x82b4, 0x82b5, /*0x58-0x5f*/ + 0x82b6, 0x82b7, 0x82b8, 0x82b9, 0x82ba, 0xbda1, 0x82bb, 0x82bc, /*0x60-0x67*/ + 0x82bd, 0x82be, 0x82bf, 0x82c0, 0xd9cc, 0x82c1, 0x82c2, 0x82c3, /*0x68-0x6f*/ + 0x82c4, 0x82c5, 0x82c6, 0x82c7, 0x82c8, 0x82c9, 0xc5bc, 0xcdb5, /*0x70-0x77*/ + 0x82ca, 0x82cb, 0x82cc, 0xd9cd, 0x82cd, 0x82ce, 0xd9c7, 0xb3a5, /*0x78-0x7f*/ + 0xbffe, 0x82cf, 0x82d0, 0x82d1, 0x82d2, 0xb8b5, 0x82d3, 0x82d4, /*0x80-0x87*/ + 0xc0fc, 0x82d5, 0x82d6, 0x82d7, 0x82d8, 0xb0f8, 0x82d9, 0x82da, /*0x88-0x8f*/ + 0x82db, 0x82dc, 0x82dd, 0x82de, 0x82df, 0x82e0, 0x82e1, 0x82e2, /*0x90-0x97*/ + 0x82e3, 0x82e4, 0x82e5, 0x82e6, 0x82e7, 0x82e8, 0x82e9, 0x82ea, /*0x98-0x9f*/ + 0x82eb, 0x82ec, 0x82ed, 0xb4f6, 0x82ee, 0xd9ce, 0x82ef, 0xd9cf, /*0xa0-0xa7*/ + 0xb4a2, 0xd9d0, 0x82f0, 0x82f1, 0xb4df, 0x82f2, 0x82f3, 0x82f4, /*0xa8-0xaf*/ + 0x82f5, 0x82f6, 0xb0c1, 0x82f7, 0x82f8, 0x82f9, 0x82fa, 0x82fb, /*0xb0-0xb7*/ + 0x82fc, 0x82fd, 0xd9d1, 0xc9b5, 0x82fe, 0x8340, 0x8341, 0x8342, /*0xb8-0xbf*/ + 0x8343, 0x8344, 0x8345, 0x8346, 0x8347, 0x8348, 0x8349, 0x834a, /*0xc0-0xc7*/ + 0x834b, 0x834c, 0x834d, 0x834e, 0x834f, 0x8350, 0x8351, 0xcff1, /*0xc8-0xcf*/ + 0x8352, 0x8353, 0x8354, 0x8355, 0x8356, 0x8357, 0xd9d2, 0x8358, /*0xd0-0xd7*/ + 0x8359, 0x835a, 0xc1c5, 0x835b, 0x835c, 0x835d, 0x835e, 0x835f, /*0xd8-0xdf*/ + 0x8360, 0x8361, 0x8362, 0x8363, 0x8364, 0x8365, 0xd9d6, 0xc9ae, /*0xe0-0xe7*/ + 0x8366, 0x8367, 0x8368, 0x8369, 0xd9d5, 0xd9d4, 0xd9d7, 0x836a, /*0xe8-0xef*/ + 0x836b, 0x836c, 0x836d, 0xcbdb, 0x836e, 0xbda9, 0x836f, 0x8370, /*0xf0-0xf7*/ + 0x8371, 0x8372, 0x8373, 0xc6a7, 0x8374, 0x8375, 0x8376, 0x8377, /*0xf8-0xff*/ + /* 0x5100 */ + 0x8378, 0x8379, 0x837a, 0x837b, 0x837c, 0x837d, 0xd9d3, 0xd9d8, /*0x00-0x07*/ + 0x837e, 0x8380, 0x8381, 0xd9d9, 0x8382, 0x8383, 0x8384, 0x8385, /*0x08-0x0f*/ + 0x8386, 0x8387, 0xc8e5, 0x8388, 0x8389, 0x838a, 0x838b, 0x838c, /*0x10-0x17*/ + 0x838d, 0x838e, 0x838f, 0x8390, 0x8391, 0x8392, 0x8393, 0x8394, /*0x18-0x1f*/ + 0x8395, 0xc0dc, 0x8396, 0x8397, 0x8398, 0x8399, 0x839a, 0x839b, /*0x20-0x27*/ + 0x839c, 0x839d, 0x839e, 0x839f, 0x83a0, 0x83a1, 0x83a2, 0x83a3, /*0x28-0x2f*/ + 0x83a4, 0x83a5, 0x83a6, 0x83a7, 0x83a8, 0x83a9, 0x83aa, 0x83ab, /*0x30-0x37*/ + 0x83ac, 0x83ad, 0x83ae, 0x83af, 0x83b0, 0x83b1, 0x83b2, 0xb6f9, /*0x38-0x3f*/ + 0xd8a3, 0xd4ca, 0x83b3, 0xd4aa, 0xd0d6, 0xb3e4, 0xd5d7, 0x83b4, /*0x40-0x47*/ + 0xcfc8, 0xb9e2, 0x83b5, 0xbfcb, 0x83b6, 0xc3e2, 0x83b7, 0x83b8, /*0x48-0x4f*/ + 0x83b9, 0xb6d2, 0x83ba, 0x83bb, 0xcdc3, 0xd9ee, 0xd9f0, 0x83bc, /*0x50-0x57*/ + 0x83bd, 0x83be, 0xb5b3, 0x83bf, 0xb6b5, 0x83c0, 0x83c1, 0x83c2, /*0x58-0x5f*/ + 0x83c3, 0x83c4, 0xbea4, 0x83c5, 0x83c6, 0xc8eb, 0x83c7, 0x83c8, /*0x60-0x67*/ + 0xc8ab, 0x83c9, 0x83ca, 0xb0cb, 0xb9ab, 0xc1f9, 0xd9e2, 0x83cb, /*0x68-0x6f*/ + 0xc0bc, 0xb9b2, 0x83cc, 0xb9d8, 0xd0cb, 0xb1f8, 0xc6e4, 0xbedf, /*0x70-0x77*/ + 0xb5e4, 0xd7c8, 0x83cd, 0xd1f8, 0xbce6, 0xcade, 0x83ce, 0x83cf, /*0x78-0x7f*/ + 0xbcbd, 0xd9e6, 0xd8e7, 0x83d0, 0x83d1, 0xc4da, 0x83d2, 0x83d3, /*0x80-0x87*/ + 0xb8d4, 0xc8bd, 0x83d4, 0x83d5, 0xb2e1, 0xd4d9, 0x83d6, 0x83d7, /*0x88-0x8f*/ + 0x83d8, 0x83d9, 0xc3b0, 0x83da, 0x83db, 0xc3e1, 0xdaa2, 0xc8df, /*0x90-0x97*/ + 0x83dc, 0xd0b4, 0x83dd, 0xbefc, 0xc5a9, 0x83de, 0x83df, 0x83e0, /*0x98-0x9f*/ + 0xb9da, 0x83e1, 0xdaa3, 0x83e2, 0xd4a9, 0xdaa4, 0x83e3, 0x83e4, /*0xa0-0xa7*/ + 0x83e5, 0x83e6, 0x83e7, 0xd9fb, 0xb6ac, 0x83e8, 0x83e9, 0xb7eb, /*0xa8-0xaf*/ + 0xb1f9, 0xd9fc, 0xb3e5, 0xbef6, 0x83ea, 0xbff6, 0xd2b1, 0xc0e4, /*0xb0-0xb7*/ + 0x83eb, 0x83ec, 0x83ed, 0xb6b3, 0xd9fe, 0xd9fd, 0x83ee, 0x83ef, /*0xb8-0xbf*/ + 0xbebb, 0x83f0, 0x83f1, 0x83f2, 0xc6e0, 0x83f3, 0xd7bc, 0xdaa1, /*0xc0-0xc7*/ + 0x83f4, 0xc1b9, 0x83f5, 0xb5f2, 0xc1e8, 0x83f6, 0x83f7, 0xbcf5, /*0xc8-0xcf*/ + 0x83f8, 0xb4d5, 0x83f9, 0x83fa, 0x83fb, 0x83fc, 0x83fd, 0x83fe, /*0xd0-0xd7*/ + 0x8440, 0x8441, 0x8442, 0xc1dd, 0x8443, 0xc4fd, 0x8444, 0x8445, /*0xd8-0xdf*/ + 0xbcb8, 0xb7b2, 0x8446, 0x8447, 0xb7ef, 0x8448, 0x8449, 0x844a, /*0xe0-0xe7*/ + 0x844b, 0x844c, 0x844d, 0xd9ec, 0x844e, 0xc6be, 0x844f, 0xbfad, /*0xe8-0xef*/ + 0xbbcb, 0x8450, 0x8451, 0xb5ca, 0x8452, 0xdbc9, 0xd0d7, 0x8453, /*0xf0-0xf7*/ + 0xcdb9, 0xb0bc, 0xb3f6, 0xbbf7, 0xdbca, 0xbaaf, 0x8454, 0xd4e4, /*0xf8-0xff*/ + /* 0x5200 */ + 0xb5b6, 0xb5f3, 0xd8d6, 0xc8d0, 0x8455, 0x8456, 0xb7d6, 0xc7d0, /*0x00-0x07*/ + 0xd8d7, 0x8457, 0xbfaf, 0x8458, 0x8459, 0xdbbb, 0xd8d8, 0x845a, /*0x08-0x0f*/ + 0x845b, 0xd0cc, 0xbbae, 0x845c, 0x845d, 0x845e, 0xebbe, 0xc1d0, /*0x10-0x17*/ + 0xc1f5, 0xd4f2, 0xb8d5, 0xb4b4, 0x845f, 0xb3f5, 0x8460, 0x8461, /*0x18-0x1f*/ + 0xc9be, 0x8462, 0x8463, 0x8464, 0xc5d0, 0x8465, 0x8466, 0x8467, /*0x20-0x27*/ + 0xc5d9, 0xc0fb, 0x8468, 0xb1f0, 0x8469, 0xd8d9, 0xb9ce, 0x846a, /*0x28-0x2f*/ + 0xb5bd, 0x846b, 0x846c, 0xd8da, 0x846d, 0x846e, 0xd6c6, 0xcba2, /*0x30-0x37*/ + 0xc8af, 0xc9b2, 0xb4cc, 0xbfcc, 0x846f, 0xb9f4, 0x8470, 0xd8db, /*0x38-0x3f*/ + 0xd8dc, 0xb6e7, 0xbcc1, 0xccea, 0x8471, 0x8472, 0x8473, 0x8474, /*0x40-0x47*/ + 0x8475, 0x8476, 0xcff7, 0x8477, 0xd8dd, 0xc7b0, 0x8478, 0x8479, /*0x48-0x4f*/ + 0xb9d0, 0xbda3, 0x847a, 0x847b, 0xccde, 0x847c, 0xc6ca, 0x847d, /*0x50-0x57*/ + 0x847e, 0x8480, 0x8481, 0x8482, 0xd8e0, 0x8483, 0xd8de, 0x8484, /*0x58-0x5f*/ + 0x8485, 0xd8df, 0x8486, 0x8487, 0x8488, 0xb0fe, 0x8489, 0xbee7, /*0x60-0x67*/ + 0x848a, 0xcaa3, 0xbcf4, 0x848b, 0x848c, 0x848d, 0x848e, 0xb8b1, /*0x68-0x6f*/ + 0x848f, 0x8490, 0xb8ee, 0x8491, 0x8492, 0x8493, 0x8494, 0x8495, /*0x70-0x77*/ + 0x8496, 0x8497, 0x8498, 0x8499, 0x849a, 0xd8e2, 0x849b, 0xbdcb, /*0x78-0x7f*/ + 0x849c, 0xd8e4, 0xd8e3, 0x849d, 0x849e, 0x849f, 0x84a0, 0x84a1, /*0x80-0x87*/ + 0xc5fc, 0x84a2, 0x84a3, 0x84a4, 0x84a5, 0x84a6, 0x84a7, 0x84a8, /*0x88-0x8f*/ + 0xd8e5, 0x84a9, 0x84aa, 0xd8e6, 0x84ab, 0x84ac, 0x84ad, 0x84ae, /*0x90-0x97*/ + 0x84af, 0x84b0, 0x84b1, 0xc1a6, 0x84b2, 0xc8b0, 0xb0ec, 0xb9a6, /*0x98-0x9f*/ + 0xbcd3, 0xcef1, 0xdbbd, 0xc1d3, 0x84b3, 0x84b4, 0x84b5, 0x84b6, /*0xa0-0xa7*/ + 0xb6af, 0xd6fa, 0xc5ac, 0xbdd9, 0xdbbe, 0xdbbf, 0x84b7, 0x84b8, /*0xa8-0xaf*/ + 0x84b9, 0xc0f8, 0xbea2, 0xc0cd, 0x84ba, 0x84bb, 0x84bc, 0x84bd, /*0xb0-0xb7*/ + 0x84be, 0x84bf, 0x84c0, 0x84c1, 0x84c2, 0x84c3, 0xdbc0, 0xcac6, /*0xb8-0xbf*/ + 0x84c4, 0x84c5, 0x84c6, 0xb2aa, 0x84c7, 0x84c8, 0x84c9, 0xd3c2, /*0xc0-0xc7*/ + 0x84ca, 0xc3e3, 0x84cb, 0xd1ab, 0x84cc, 0x84cd, 0x84ce, 0x84cf, /*0xc8-0xcf*/ + 0xdbc2, 0x84d0, 0xc0d5, 0x84d1, 0x84d2, 0x84d3, 0xdbc3, 0x84d4, /*0xd0-0xd7*/ + 0xbfb1, 0x84d5, 0x84d6, 0x84d7, 0x84d8, 0x84d9, 0x84da, 0xc4bc, /*0xd8-0xdf*/ + 0x84db, 0x84dc, 0x84dd, 0x84de, 0xc7da, 0x84df, 0x84e0, 0x84e1, /*0xe0-0xe7*/ + 0x84e2, 0x84e3, 0x84e4, 0x84e5, 0x84e6, 0x84e7, 0x84e8, 0x84e9, /*0xe8-0xef*/ + 0xdbc4, 0x84ea, 0x84eb, 0x84ec, 0x84ed, 0x84ee, 0x84ef, 0x84f0, /*0xf0-0xf7*/ + 0x84f1, 0xd9e8, 0xc9d7, 0x84f2, 0x84f3, 0x84f4, 0xb9b4, 0xcef0, /*0xf8-0xff*/ + /* 0x5300 */ + 0xd4c8, 0x84f5, 0x84f6, 0x84f7, 0x84f8, 0xb0fc, 0xb4d2, 0x84f9, /*0x00-0x07*/ + 0xd0d9, 0x84fa, 0x84fb, 0x84fc, 0x84fd, 0xd9e9, 0x84fe, 0xdecb, /*0x08-0x0f*/ + 0xd9eb, 0x8540, 0x8541, 0x8542, 0x8543, 0xd8b0, 0xbbaf, 0xb1b1, /*0x10-0x17*/ + 0x8544, 0xb3d7, 0xd8ce, 0x8545, 0x8546, 0xd4d1, 0x8547, 0x8548, /*0x18-0x1f*/ + 0xbdb3, 0xbfef, 0x8549, 0xcfbb, 0x854a, 0x854b, 0xd8d0, 0x854c, /*0x20-0x27*/ + 0x854d, 0x854e, 0xb7cb, 0x854f, 0x8550, 0x8551, 0xd8d1, 0x8552, /*0x28-0x2f*/ + 0x8553, 0x8554, 0x8555, 0x8556, 0x8557, 0x8558, 0x8559, 0x855a, /*0x30-0x37*/ + 0x855b, 0xc6a5, 0xc7f8, 0xd2bd, 0x855c, 0x855d, 0xd8d2, 0xc4e4, /*0x38-0x3f*/ + 0x855e, 0xcaae, 0x855f, 0xc7a7, 0x8560, 0xd8a6, 0x8561, 0xc9fd, /*0x40-0x47*/ + 0xcee7, 0xbbdc, 0xb0eb, 0x8562, 0x8563, 0x8564, 0xbbaa, 0xd0ad, /*0x48-0x4f*/ + 0x8565, 0xb1b0, 0xd7e4, 0xd7bf, 0x8566, 0xb5a5, 0xc2f4, 0xc4cf, /*0x50-0x57*/ + 0x8567, 0x8568, 0xb2a9, 0x8569, 0xb2b7, 0x856a, 0xb1e5, 0xdfb2, /*0x58-0x5f*/ + 0xd5bc, 0xbfa8, 0xc2ac, 0xd8d5, 0xc2b1, 0x856b, 0xd8d4, 0xced4, /*0x60-0x67*/ + 0x856c, 0xdae0, 0x856d, 0xcec0, 0x856e, 0x856f, 0xd8b4, 0xc3ae, /*0x68-0x6f*/ + 0xd3a1, 0xcea3, 0x8570, 0xbcb4, 0xc8b4, 0xc2d1, 0x8571, 0xbeed, /*0x70-0x77*/ + 0xd0b6, 0x8572, 0xdae1, 0x8573, 0x8574, 0x8575, 0x8576, 0xc7e4, /*0x78-0x7f*/ + 0x8577, 0x8578, 0xb3a7, 0x8579, 0xb6f2, 0xccfc, 0xc0fa, 0x857a, /*0x80-0x87*/ + 0x857b, 0xc0f7, 0x857c, 0xd1b9, 0xd1e1, 0xd8c7, 0x857d, 0x857e, /*0x88-0x8f*/ + 0x8580, 0x8581, 0x8582, 0x8583, 0x8584, 0xb2de, 0x8585, 0x8586, /*0x90-0x97*/ + 0xc0e5, 0x8587, 0xbaf1, 0x8588, 0x8589, 0xd8c8, 0x858a, 0xd4ad, /*0x98-0x9f*/ + 0x858b, 0x858c, 0xcfe1, 0xd8c9, 0x858d, 0xd8ca, 0xcfc3, 0x858e, /*0xa0-0xa7*/ + 0xb3f8, 0xbec7, 0x858f, 0x8590, 0x8591, 0x8592, 0xd8cb, 0x8593, /*0xa8-0xaf*/ + 0x8594, 0x8595, 0x8596, 0x8597, 0x8598, 0x8599, 0xdbcc, 0x859a, /*0xb0-0xb7*/ + 0x859b, 0x859c, 0x859d, 0xc8a5, 0x859e, 0x859f, 0x85a0, 0xcfd8, /*0xb8-0xbf*/ + 0x85a1, 0xc8fe, 0xb2ce, 0x85a2, 0x85a3, 0x85a4, 0x85a5, 0x85a6, /*0xc0-0xc7*/ + 0xd3d6, 0xb2e6, 0xbcb0, 0xd3d1, 0xcbab, 0xb7b4, 0x85a7, 0x85a8, /*0xc8-0xcf*/ + 0x85a9, 0xb7a2, 0x85aa, 0x85ab, 0xcae5, 0x85ac, 0xc8a1, 0xcadc, /*0xd0-0xd7*/ + 0xb1e4, 0xd0f0, 0x85ad, 0xc5d1, 0x85ae, 0x85af, 0x85b0, 0xdbc5, /*0xd8-0xdf*/ + 0xb5fe, 0x85b1, 0x85b2, 0xbfda, 0xb9c5, 0xbee4, 0xc1ed, 0x85b3, /*0xe0-0xe7*/ + 0xdfb6, 0xdfb5, 0xd6bb, 0xbdd0, 0xd5d9, 0xb0c8, 0xb6a3, 0xbfc9, /*0xe8-0xef*/ + 0xcca8, 0xdfb3, 0xcab7, 0xd3d2, 0x85b4, 0xd8cf, 0xd2b6, 0xbac5, /*0xf0-0xf7*/ + 0xcbbe, 0xccbe, 0x85b5, 0xdfb7, 0xb5f0, 0xdfb4, 0x85b6, 0x85b7, /*0xf8-0xff*/ + /* 0x5400 */ + 0x85b8, 0xd3f5, 0x85b9, 0xb3d4, 0xb8f7, 0x85ba, 0xdfba, 0x85bb, /*0x00-0x07*/ + 0xbacf, 0xbcaa, 0xb5f5, 0x85bc, 0xcdac, 0xc3fb, 0xbaf3, 0xc0f4, /*0x08-0x0f*/ + 0xcdc2, 0xcff2, 0xdfb8, 0xcfc5, 0x85bd, 0xc2c0, 0xdfb9, 0xc2f0, /*0x10-0x17*/ + 0x85be, 0x85bf, 0x85c0, 0xbefd, 0x85c1, 0xc1df, 0xcdcc, 0xd2f7, /*0x18-0x1f*/ + 0xb7cd, 0xdfc1, 0x85c2, 0xdfc4, 0x85c3, 0x85c4, 0xb7f1, 0xb0c9, /*0x20-0x27*/ + 0xb6d6, 0xb7d4, 0x85c5, 0xbaac, 0xccfd, 0xbfd4, 0xcbb1, 0xc6f4, /*0x28-0x2f*/ + 0x85c6, 0xd6a8, 0xdfc5, 0x85c7, 0xcee2, 0xb3b3, 0x85c8, 0x85c9, /*0x30-0x37*/ + 0xcefc, 0xb4b5, 0x85ca, 0xcec7, 0xbaf0, 0x85cb, 0xcee1, 0x85cc, /*0x38-0x3f*/ + 0xd1bd, 0x85cd, 0x85ce, 0xdfc0, 0x85cf, 0x85d0, 0xb4f4, 0x85d1, /*0x40-0x47*/ + 0xb3ca, 0x85d2, 0xb8e6, 0xdfbb, 0x85d3, 0x85d4, 0x85d5, 0x85d6, /*0x48-0x4f*/ + 0xc4c5, 0x85d7, 0xdfbc, 0xdfbd, 0xdfbe, 0xc5bb, 0xdfbf, 0xdfc2, /*0x50-0x57*/ + 0xd4b1, 0xdfc3, 0x85d8, 0xc7ba, 0xced8, 0x85d9, 0x85da, 0x85db, /*0x58-0x5f*/ + 0x85dc, 0x85dd, 0xc4d8, 0x85de, 0xdfca, 0x85df, 0xdfcf, 0x85e0, /*0x60-0x67*/ + 0xd6dc, 0x85e1, 0x85e2, 0x85e3, 0x85e4, 0x85e5, 0x85e6, 0x85e7, /*0x68-0x6f*/ + 0x85e8, 0xdfc9, 0xdfda, 0xceb6, 0x85e9, 0xbac7, 0xdfce, 0xdfc8, /*0x70-0x77*/ + 0xc5de, 0x85ea, 0x85eb, 0xc9eb, 0xbaf4, 0xc3fc, 0x85ec, 0x85ed, /*0x78-0x7f*/ + 0xbed7, 0x85ee, 0xdfc6, 0x85ef, 0xdfcd, 0x85f0, 0xc5d8, 0x85f1, /*0x80-0x87*/ + 0x85f2, 0x85f3, 0x85f4, 0xd5a6, 0xbacd, 0x85f5, 0xbecc, 0xd3bd, /*0x88-0x8f*/ + 0xb8c0, 0x85f6, 0xd6e4, 0x85f7, 0xdfc7, 0xb9be, 0xbfa7, 0x85f8, /*0x90-0x97*/ + 0x85f9, 0xc1fc, 0xdfcb, 0xdfcc, 0x85fa, 0xdfd0, 0x85fb, 0x85fc, /*0x98-0x9f*/ + 0x85fd, 0x85fe, 0x8640, 0xdfdb, 0xdfe5, 0x8641, 0xdfd7, 0xdfd6, /*0xa0-0xa7*/ + 0xd7c9, 0xdfe3, 0xdfe4, 0xe5eb, 0xd2a7, 0xdfd2, 0x8642, 0xbfa9, /*0xa8-0xaf*/ + 0x8643, 0xd4db, 0x8644, 0xbfc8, 0xdfd4, 0x8645, 0x8646, 0x8647, /*0xb0-0xb7*/ + 0xcfcc, 0x8648, 0x8649, 0xdfdd, 0x864a, 0xd1ca, 0x864b, 0xdfde, /*0xb8-0xbf*/ + 0xb0a7, 0xc6b7, 0xdfd3, 0x864c, 0xbae5, 0x864d, 0xb6df, 0xcddb, /*0xc0-0xc7*/ + 0xb9fe, 0xd4d5, 0x864e, 0x864f, 0xdfdf, 0xcfec, 0xb0a5, 0xdfe7, /*0xc8-0xcf*/ + 0xdfd1, 0xd1c6, 0xdfd5, 0xdfd8, 0xdfd9, 0xdfdc, 0x8650, 0xbba9, /*0xd0-0xd7*/ + 0x8651, 0xdfe0, 0xdfe1, 0x8652, 0xdfe2, 0xdfe6, 0xdfe8, 0xd3b4, /*0xd8-0xdf*/ + 0x8653, 0x8654, 0x8655, 0x8656, 0x8657, 0xb8e7, 0xc5b6, 0xdfea, /*0xe0-0xe7*/ + 0xc9da, 0xc1a8, 0xc4c4, 0x8658, 0x8659, 0xbfde, 0xcff8, 0x865a, /*0xe8-0xef*/ + 0x865b, 0x865c, 0xd5dc, 0xdfee, 0x865d, 0x865e, 0x865f, 0x8660, /*0xf0-0xf7*/ + 0x8661, 0x8662, 0xb2b8, 0x8663, 0xbadf, 0xdfec, 0x8664, 0xdbc1, /*0xf8-0xff*/ + /* 0x5500 */ + 0x8665, 0xd1e4, 0x8666, 0x8667, 0x8668, 0x8669, 0xcbf4, 0xb4bd, /*0x00-0x07*/ + 0x866a, 0xb0a6, 0x866b, 0x866c, 0x866d, 0x866e, 0x866f, 0xdff1, /*0x08-0x0f*/ + 0xccc6, 0xdff2, 0x8670, 0x8671, 0xdfed, 0x8672, 0x8673, 0x8674, /*0x10-0x17*/ + 0x8675, 0x8676, 0x8677, 0xdfe9, 0x8678, 0x8679, 0x867a, 0x867b, /*0x18-0x1f*/ + 0xdfeb, 0x867c, 0xdfef, 0xdff0, 0xbbbd, 0x867d, 0x867e, 0xdff3, /*0x20-0x27*/ + 0x8680, 0x8681, 0xdff4, 0x8682, 0xbba3, 0x8683, 0xcadb, 0xcea8, /*0x28-0x2f*/ + 0xe0a7, 0xb3aa, 0x8684, 0xe0a6, 0x8685, 0x8686, 0x8687, 0xe0a1, /*0x30-0x37*/ + 0x8688, 0x8689, 0x868a, 0x868b, 0xdffe, 0x868c, 0xcdd9, 0xdffc, /*0x38-0x3f*/ + 0x868d, 0xdffa, 0x868e, 0xbfd0, 0xd7c4, 0x868f, 0xc9cc, 0x8690, /*0x40-0x47*/ + 0x8691, 0xdff8, 0xb0a1, 0x8692, 0x8693, 0x8694, 0x8695, 0x8696, /*0x48-0x4f*/ + 0xdffd, 0x8697, 0x8698, 0x8699, 0x869a, 0xdffb, 0xe0a2, 0x869b, /*0x50-0x57*/ + 0x869c, 0x869d, 0x869e, 0x869f, 0xe0a8, 0x86a0, 0x86a1, 0x86a2, /*0x58-0x5f*/ + 0x86a3, 0xb7c8, 0x86a4, 0x86a5, 0xc6a1, 0xc9b6, 0xc0b2, 0xdff5, /*0x60-0x67*/ + 0x86a6, 0x86a7, 0xc5be, 0x86a8, 0xd8c4, 0xdff9, 0xc4f6, 0x86a9, /*0x68-0x6f*/ + 0x86aa, 0x86ab, 0x86ac, 0x86ad, 0x86ae, 0xe0a3, 0xe0a4, 0xe0a5, /*0x70-0x77*/ + 0xd0a5, 0x86af, 0x86b0, 0xe0b4, 0xcce4, 0x86b1, 0xe0b1, 0x86b2, /*0x78-0x7f*/ + 0xbfa6, 0xe0af, 0xceb9, 0xe0ab, 0xc9c6, 0x86b3, 0x86b4, 0xc0ae, /*0x80-0x87*/ + 0xe0ae, 0xbaed, 0xbab0, 0xe0a9, 0x86b5, 0x86b6, 0x86b7, 0xdff6, /*0x88-0x8f*/ + 0x86b8, 0xe0b3, 0x86b9, 0x86ba, 0xe0b8, 0x86bb, 0x86bc, 0x86bd, /*0x90-0x97*/ + 0xb4ad, 0xe0b9, 0x86be, 0x86bf, 0xcfb2, 0xbac8, 0x86c0, 0xe0b0, /*0x98-0x9f*/ + 0x86c1, 0x86c2, 0x86c3, 0x86c4, 0x86c5, 0x86c6, 0x86c7, 0xd0fa, /*0xa0-0xa7*/ + 0x86c8, 0x86c9, 0x86ca, 0x86cb, 0x86cc, 0x86cd, 0x86ce, 0x86cf, /*0xa8-0xaf*/ + 0x86d0, 0xe0ac, 0x86d1, 0xd4fb, 0x86d2, 0xdff7, 0x86d3, 0xc5e7, /*0xb0-0xb7*/ + 0x86d4, 0xe0ad, 0x86d5, 0xd3f7, 0x86d6, 0xe0b6, 0xe0b7, 0x86d7, /*0xb8-0xbf*/ + 0x86d8, 0x86d9, 0x86da, 0x86db, 0xe0c4, 0xd0e1, 0x86dc, 0x86dd, /*0xc0-0xc7*/ + 0x86de, 0xe0bc, 0x86df, 0x86e0, 0xe0c9, 0xe0ca, 0x86e1, 0x86e2, /*0xc8-0xcf*/ + 0x86e3, 0xe0be, 0xe0aa, 0xc9a4, 0xe0c1, 0x86e4, 0xe0b2, 0x86e5, /*0xd0-0xd7*/ + 0x86e6, 0x86e7, 0x86e8, 0x86e9, 0xcac8, 0xe0c3, 0x86ea, 0xe0b5, /*0xd8-0xdf*/ + 0x86eb, 0xcecb, 0x86ec, 0xcbc3, 0xe0cd, 0xe0c6, 0xe0c2, 0x86ed, /*0xe0-0xe7*/ + 0xe0cb, 0x86ee, 0xe0ba, 0xe0bf, 0xe0c0, 0x86ef, 0x86f0, 0xe0c5, /*0xe8-0xef*/ + 0x86f1, 0x86f2, 0xe0c7, 0xe0c8, 0x86f3, 0xe0cc, 0x86f4, 0xe0bb, /*0xf0-0xf7*/ + 0x86f5, 0x86f6, 0x86f7, 0x86f8, 0x86f9, 0xcbd4, 0xe0d5, 0x86fa, /*0xf8-0xff*/ + /* 0x5600 */ + 0xe0d6, 0xe0d2, 0x86fb, 0x86fc, 0x86fd, 0x86fe, 0x8740, 0x8741, /*0x00-0x07*/ + 0xe0d0, 0xbcce, 0x8742, 0x8743, 0xe0d1, 0x8744, 0xb8c2, 0xd8c5, /*0x08-0x0f*/ + 0x8745, 0x8746, 0x8747, 0x8748, 0x8749, 0x874a, 0x874b, 0x874c, /*0x10-0x17*/ + 0xd0ea, 0x874d, 0x874e, 0xc2ef, 0x874f, 0x8750, 0xe0cf, 0xe0bd, /*0x18-0x1f*/ + 0x8751, 0x8752, 0x8753, 0xe0d4, 0xe0d3, 0x8754, 0x8755, 0xe0d7, /*0x20-0x27*/ + 0x8756, 0x8757, 0x8758, 0x8759, 0xe0dc, 0xe0d8, 0x875a, 0x875b, /*0x28-0x2f*/ + 0x875c, 0xd6f6, 0xb3b0, 0x875d, 0xd7ec, 0x875e, 0xcbbb, 0x875f, /*0x30-0x37*/ + 0x8760, 0xe0da, 0x8761, 0xcefb, 0x8762, 0x8763, 0x8764, 0xbad9, /*0x38-0x3f*/ + 0x8765, 0x8766, 0x8767, 0x8768, 0x8769, 0x876a, 0x876b, 0x876c, /*0x40-0x47*/ + 0x876d, 0x876e, 0x876f, 0x8770, 0xe0e1, 0xe0dd, 0xd2ad, 0x8771, /*0x48-0x4f*/ + 0x8772, 0x8773, 0x8774, 0x8775, 0xe0e2, 0x8776, 0x8777, 0xe0db, /*0x50-0x57*/ + 0xe0d9, 0xe0df, 0x8778, 0x8779, 0xe0e0, 0x877a, 0x877b, 0x877c, /*0x58-0x5f*/ + 0x877d, 0x877e, 0xe0de, 0x8780, 0xe0e4, 0x8781, 0x8782, 0x8783, /*0x60-0x67*/ + 0xc6f7, 0xd8ac, 0xd4eb, 0xe0e6, 0xcac9, 0x8784, 0x8785, 0x8786, /*0x68-0x6f*/ + 0x8787, 0xe0e5, 0x8788, 0x8789, 0x878a, 0x878b, 0xb8c1, 0x878c, /*0x70-0x77*/ + 0x878d, 0x878e, 0x878f, 0xe0e7, 0xe0e8, 0x8790, 0x8791, 0x8792, /*0x78-0x7f*/ + 0x8793, 0x8794, 0x8795, 0x8796, 0x8797, 0xe0e9, 0xe0e3, 0x8798, /*0x80-0x87*/ + 0x8799, 0x879a, 0x879b, 0x879c, 0x879d, 0x879e, 0xbabf, 0xcce7, /*0x88-0x8f*/ + 0x879f, 0x87a0, 0x87a1, 0xe0ea, 0x87a2, 0x87a3, 0x87a4, 0x87a5, /*0x90-0x97*/ + 0x87a6, 0x87a7, 0x87a8, 0x87a9, 0x87aa, 0x87ab, 0x87ac, 0x87ad, /*0x98-0x9f*/ + 0x87ae, 0x87af, 0x87b0, 0xcff9, 0x87b1, 0x87b2, 0x87b3, 0x87b4, /*0xa0-0xa7*/ + 0x87b5, 0x87b6, 0x87b7, 0x87b8, 0x87b9, 0x87ba, 0x87bb, 0xe0eb, /*0xa8-0xaf*/ + 0x87bc, 0x87bd, 0x87be, 0x87bf, 0x87c0, 0x87c1, 0x87c2, 0xc8c2, /*0xb0-0xb7*/ + 0x87c3, 0x87c4, 0x87c5, 0x87c6, 0xbdc0, 0x87c7, 0x87c8, 0x87c9, /*0xb8-0xbf*/ + 0x87ca, 0x87cb, 0x87cc, 0x87cd, 0x87ce, 0x87cf, 0x87d0, 0x87d1, /*0xc0-0xc7*/ + 0x87d2, 0x87d3, 0xc4d2, 0x87d4, 0x87d5, 0x87d6, 0x87d7, 0x87d8, /*0xc8-0xcf*/ + 0x87d9, 0x87da, 0x87db, 0x87dc, 0xe0ec, 0x87dd, 0x87de, 0xe0ed, /*0xd0-0xd7*/ + 0x87df, 0x87e0, 0xc7f4, 0xcbc4, 0x87e1, 0xe0ee, 0xbbd8, 0xd8b6, /*0xd8-0xdf*/ + 0xd2f2, 0xe0ef, 0xcdc5, 0x87e2, 0xb6da, 0x87e3, 0x87e4, 0x87e5, /*0xe0-0xe7*/ + 0x87e6, 0x87e7, 0x87e8, 0xe0f1, 0x87e9, 0xd4b0, 0x87ea, 0x87eb, /*0xe8-0xef*/ + 0xc0a7, 0xb4d1, 0x87ec, 0x87ed, 0xcea7, 0xe0f0, 0x87ee, 0x87ef, /*0xf0-0xf7*/ + 0x87f0, 0xe0f2, 0xb9cc, 0x87f1, 0x87f2, 0xb9fa, 0xcdbc, 0xe0f3, /*0xf8-0xff*/ + /* 0x5700 */ + 0x87f3, 0x87f4, 0x87f5, 0xc6d4, 0xe0f4, 0x87f6, 0xd4b2, 0x87f7, /*0x00-0x07*/ + 0xc8a6, 0xe0f6, 0xe0f5, 0x87f8, 0x87f9, 0x87fa, 0x87fb, 0x87fc, /*0x08-0x0f*/ + 0x87fd, 0x87fe, 0x8840, 0x8841, 0x8842, 0x8843, 0x8844, 0x8845, /*0x10-0x17*/ + 0x8846, 0x8847, 0x8848, 0x8849, 0xe0f7, 0x884a, 0x884b, 0xcdc1, /*0x18-0x1f*/ + 0x884c, 0x884d, 0x884e, 0xcaa5, 0x884f, 0x8850, 0x8851, 0x8852, /*0x20-0x27*/ + 0xd4da, 0xdbd7, 0xdbd9, 0x8853, 0xdbd8, 0xb9e7, 0xdbdc, 0xdbdd, /*0x28-0x2f*/ + 0xb5d8, 0x8854, 0x8855, 0xdbda, 0x8856, 0x8857, 0x8858, 0x8859, /*0x30-0x37*/ + 0x885a, 0xdbdb, 0xb3a1, 0xdbdf, 0x885b, 0x885c, 0xbbf8, 0x885d, /*0x38-0x3f*/ + 0xd6b7, 0x885e, 0xdbe0, 0x885f, 0x8860, 0x8861, 0x8862, 0xbef9, /*0x40-0x47*/ + 0x8863, 0x8864, 0xb7bb, 0x8865, 0xdbd0, 0xccae, 0xbfb2, 0xbbb5, /*0x48-0x4f*/ + 0xd7f8, 0xbfd3, 0x8866, 0x8867, 0x8868, 0x8869, 0x886a, 0xbfe9, /*0x50-0x57*/ + 0x886b, 0x886c, 0xbce1, 0xccb3, 0xdbde, 0xb0d3, 0xceeb, 0xb7d8, /*0x58-0x5f*/ + 0xd7b9, 0xc6c2, 0x886d, 0x886e, 0xc0a4, 0x886f, 0xccb9, 0x8870, /*0x60-0x67*/ + 0xdbe7, 0xdbe1, 0xc6ba, 0xdbe3, 0x8871, 0xdbe8, 0x8872, 0xc5f7, /*0x68-0x6f*/ + 0x8873, 0x8874, 0x8875, 0xdbea, 0x8876, 0x8877, 0xdbe9, 0xbfc0, /*0x70-0x77*/ + 0x8878, 0x8879, 0x887a, 0xdbe6, 0xdbe5, 0x887b, 0x887c, 0x887d, /*0x78-0x7f*/ + 0x887e, 0x8880, 0xb4b9, 0xc0ac, 0xc2a2, 0xdbe2, 0xdbe4, 0x8881, /*0x80-0x87*/ + 0x8882, 0x8883, 0x8884, 0xd0cd, 0xdbed, 0x8885, 0x8886, 0x8887, /*0x88-0x8f*/ + 0x8888, 0x8889, 0xc0dd, 0xdbf2, 0x888a, 0x888b, 0x888c, 0x888d, /*0x90-0x97*/ + 0x888e, 0x888f, 0x8890, 0xb6e2, 0x8891, 0x8892, 0x8893, 0x8894, /*0x98-0x9f*/ + 0xdbf3, 0xdbd2, 0xb9b8, 0xd4ab, 0xdbec, 0x8895, 0xbfd1, 0xdbf0, /*0xa0-0xa7*/ + 0x8896, 0xdbd1, 0x8897, 0xb5e6, 0x8898, 0xdbeb, 0xbfe5, 0x8899, /*0xa8-0xaf*/ + 0x889a, 0x889b, 0xdbee, 0x889c, 0xdbf1, 0x889d, 0x889e, 0x889f, /*0xb0-0xb7*/ + 0xdbf9, 0x88a0, 0x88a1, 0x88a2, 0x88a3, 0x88a4, 0x88a5, 0x88a6, /*0xb8-0xbf*/ + 0x88a7, 0x88a8, 0xb9a1, 0xb0a3, 0x88a9, 0x88aa, 0x88ab, 0x88ac, /*0xc0-0xc7*/ + 0x88ad, 0x88ae, 0x88af, 0xc2f1, 0x88b0, 0x88b1, 0xb3c7, 0xdbef, /*0xc8-0xcf*/ + 0x88b2, 0x88b3, 0xdbf8, 0x88b4, 0xc6d2, 0xdbf4, 0x88b5, 0x88b6, /*0xd0-0xd7*/ + 0xdbf5, 0xdbf7, 0xdbf6, 0x88b7, 0x88b8, 0xdbfe, 0x88b9, 0xd3f2, /*0xd8-0xdf*/ + 0xb2ba, 0x88ba, 0x88bb, 0x88bc, 0xdbfd, 0x88bd, 0x88be, 0x88bf, /*0xe0-0xe7*/ + 0x88c0, 0x88c1, 0x88c2, 0x88c3, 0x88c4, 0xdca4, 0x88c5, 0xdbfb, /*0xe8-0xef*/ + 0x88c6, 0x88c7, 0x88c8, 0x88c9, 0xdbfa, 0x88ca, 0x88cb, 0x88cc, /*0xf0-0xf7*/ + 0xdbfc, 0xc5e0, 0xbbf9, 0x88cd, 0x88ce, 0xdca3, 0x88cf, 0x88d0, /*0xf8-0xff*/ + /* 0x5800 */ + 0xdca5, 0x88d1, 0xccc3, 0x88d2, 0x88d3, 0x88d4, 0xb6d1, 0xddc0, /*0x00-0x07*/ + 0x88d5, 0x88d6, 0x88d7, 0xdca1, 0x88d8, 0xdca2, 0x88d9, 0x88da, /*0x08-0x0f*/ + 0x88db, 0xc7b5, 0x88dc, 0x88dd, 0x88de, 0xb6e9, 0x88df, 0x88e0, /*0x10-0x17*/ + 0x88e1, 0xdca7, 0x88e2, 0x88e3, 0x88e4, 0x88e5, 0xdca6, 0x88e6, /*0x18-0x1f*/ + 0xdca9, 0xb1a4, 0x88e7, 0x88e8, 0xb5cc, 0x88e9, 0x88ea, 0x88eb, /*0x20-0x27*/ + 0x88ec, 0x88ed, 0xbfb0, 0x88ee, 0x88ef, 0x88f0, 0x88f1, 0x88f2, /*0x28-0x2f*/ + 0xd1df, 0x88f3, 0x88f4, 0x88f5, 0x88f6, 0xb6c2, 0x88f7, 0x88f8, /*0x30-0x37*/ + 0x88f9, 0x88fa, 0x88fb, 0x88fc, 0x88fd, 0x88fe, 0x8940, 0x8941, /*0x38-0x3f*/ + 0x8942, 0x8943, 0x8944, 0x8945, 0xdca8, 0x8946, 0x8947, 0x8948, /*0x40-0x47*/ + 0x8949, 0x894a, 0x894b, 0x894c, 0xcbfa, 0xebf3, 0x894d, 0x894e, /*0x48-0x4f*/ + 0x894f, 0xcbdc, 0x8950, 0x8951, 0xcbfe, 0x8952, 0x8953, 0x8954, /*0x50-0x57*/ + 0xccc1, 0x8955, 0x8956, 0x8957, 0x8958, 0x8959, 0xc8fb, 0x895a, /*0x58-0x5f*/ + 0x895b, 0x895c, 0x895d, 0x895e, 0x895f, 0xdcaa, 0x8960, 0x8961, /*0x60-0x67*/ + 0x8962, 0x8963, 0x8964, 0xccee, 0xdcab, 0x8965, 0x8966, 0x8967, /*0x68-0x6f*/ + 0x8968, 0x8969, 0x896a, 0x896b, 0x896c, 0x896d, 0x896e, 0x896f, /*0x70-0x77*/ + 0x8970, 0x8971, 0x8972, 0x8973, 0x8974, 0x8975, 0xdbd3, 0x8976, /*0x78-0x7f*/ + 0xdcaf, 0xdcac, 0x8977, 0xbeb3, 0x8978, 0xcafb, 0x8979, 0x897a, /*0x80-0x87*/ + 0x897b, 0xdcad, 0x897c, 0x897d, 0x897e, 0x8980, 0x8981, 0x8982, /*0x88-0x8f*/ + 0x8983, 0x8984, 0xc9ca, 0xc4b9, 0x8985, 0x8986, 0x8987, 0x8988, /*0x90-0x97*/ + 0x8989, 0xc7bd, 0xdcae, 0x898a, 0x898b, 0x898c, 0xd4f6, 0xd0e6, /*0x98-0x9f*/ + 0x898d, 0x898e, 0x898f, 0x8990, 0x8991, 0x8992, 0x8993, 0x8994, /*0xa0-0xa7*/ + 0xc4ab, 0xb6d5, 0x8995, 0x8996, 0x8997, 0x8998, 0x8999, 0x899a, /*0xa8-0xaf*/ + 0x899b, 0x899c, 0x899d, 0x899e, 0x899f, 0x89a0, 0x89a1, 0x89a2, /*0xb0-0xb7*/ + 0x89a3, 0x89a4, 0x89a5, 0x89a6, 0xdbd4, 0x89a7, 0x89a8, 0x89a9, /*0xb8-0xbf*/ + 0x89aa, 0xb1da, 0x89ab, 0x89ac, 0x89ad, 0xdbd5, 0x89ae, 0x89af, /*0xc0-0xc7*/ + 0x89b0, 0x89b1, 0x89b2, 0x89b3, 0x89b4, 0x89b5, 0x89b6, 0x89b7, /*0xc8-0xcf*/ + 0x89b8, 0xdbd6, 0x89b9, 0x89ba, 0x89bb, 0xbabe, 0x89bc, 0x89bd, /*0xd0-0xd7*/ + 0x89be, 0x89bf, 0x89c0, 0x89c1, 0x89c2, 0x89c3, 0x89c4, 0x89c5, /*0xd8-0xdf*/ + 0x89c6, 0x89c7, 0x89c8, 0x89c9, 0xc8c0, 0x89ca, 0x89cb, 0x89cc, /*0xe0-0xe7*/ + 0x89cd, 0x89ce, 0x89cf, 0xcabf, 0xc8c9, 0x89d0, 0xd7b3, 0x89d1, /*0xe8-0xef*/ + 0xc9f9, 0x89d2, 0x89d3, 0xbfc7, 0x89d4, 0x89d5, 0xbaf8, 0x89d6, /*0xf0-0xf7*/ + 0x89d7, 0xd2bc, 0x89d8, 0x89d9, 0x89da, 0x89db, 0x89dc, 0x89dd, /*0xf8-0xff*/ + /* 0x5900 */ + 0x89de, 0x89df, 0xe2ba, 0x89e0, 0xb4a6, 0x89e1, 0x89e2, 0xb1b8, /*0x00-0x07*/ + 0x89e3, 0x89e4, 0x89e5, 0x89e6, 0x89e7, 0xb8b4, 0x89e8, 0xcfc4, /*0x08-0x0f*/ + 0x89e9, 0x89ea, 0x89eb, 0x89ec, 0xd9e7, 0xcfa6, 0xcde2, 0x89ed, /*0x10-0x17*/ + 0x89ee, 0xd9ed, 0xb6e0, 0x89ef, 0xd2b9, 0x89f0, 0x89f1, 0xb9bb, /*0x18-0x1f*/ + 0x89f2, 0x89f3, 0x89f4, 0x89f5, 0xe2b9, 0xe2b7, 0x89f6, 0xb4f3, /*0x20-0x27*/ + 0x89f7, 0xccec, 0xccab, 0xb7f2, 0x89f8, 0xd8b2, 0xd1eb, 0xbabb, /*0x28-0x2f*/ + 0x89f9, 0xcaa7, 0x89fa, 0x89fb, 0xcdb7, 0x89fc, 0x89fd, 0xd2c4, /*0x30-0x37*/ + 0xbfe4, 0xbcd0, 0xb6e1, 0x89fe, 0xdec5, 0x8a40, 0x8a41, 0x8a42, /*0x38-0x3f*/ + 0x8a43, 0xdec6, 0xdbbc, 0x8a44, 0xd1d9, 0x8a45, 0x8a46, 0xc6e6, /*0x40-0x47*/ + 0xc4ce, 0xb7ee, 0x8a47, 0xb7dc, 0x8a48, 0x8a49, 0xbffc, 0xd7e0, /*0x48-0x4f*/ + 0x8a4a, 0xc6f5, 0x8a4b, 0x8a4c, 0xb1bc, 0xdec8, 0xbdb1, 0xccd7, /*0x50-0x57*/ + 0xdeca, 0x8a4d, 0xdec9, 0x8a4e, 0x8a4f, 0x8a50, 0x8a51, 0x8a52, /*0x58-0x5f*/ + 0xb5ec, 0x8a53, 0xc9dd, 0x8a54, 0x8a55, 0xb0c2, 0x8a56, 0x8a57, /*0x60-0x67*/ + 0x8a58, 0x8a59, 0x8a5a, 0x8a5b, 0x8a5c, 0x8a5d, 0x8a5e, 0x8a5f, /*0x68-0x6f*/ + 0x8a60, 0x8a61, 0x8a62, 0xc5ae, 0xc5ab, 0x8a63, 0xc4cc, 0x8a64, /*0x70-0x77*/ + 0xbce9, 0xcbfd, 0x8a65, 0x8a66, 0x8a67, 0xbac3, 0x8a68, 0x8a69, /*0x78-0x7f*/ + 0x8a6a, 0xe5f9, 0xc8e7, 0xe5fa, 0xcdfd, 0x8a6b, 0xd7b1, 0xb8be, /*0x80-0x87*/ + 0xc2e8, 0x8a6c, 0xc8d1, 0x8a6d, 0x8a6e, 0xe5fb, 0x8a6f, 0x8a70, /*0x88-0x8f*/ + 0x8a71, 0x8a72, 0xb6ca, 0xbccb, 0x8a73, 0x8a74, 0xd1fd, 0xe6a1, /*0x90-0x97*/ + 0x8a75, 0xc3ee, 0x8a76, 0x8a77, 0x8a78, 0x8a79, 0xe6a4, 0x8a7a, /*0x98-0x9f*/ + 0x8a7b, 0x8a7c, 0x8a7d, 0xe5fe, 0xe6a5, 0xcdd7, 0x8a7e, 0x8a80, /*0xa0-0xa7*/ + 0xb7c1, 0xe5fc, 0xe5fd, 0xe6a3, 0x8a81, 0x8a82, 0xc4dd, 0xe6a8, /*0xa8-0xaf*/ + 0x8a83, 0x8a84, 0xe6a7, 0x8a85, 0x8a86, 0x8a87, 0x8a88, 0x8a89, /*0xb0-0xb7*/ + 0x8a8a, 0xc3c3, 0x8a8b, 0xc6de, 0x8a8c, 0x8a8d, 0xe6aa, 0x8a8e, /*0xb8-0xbf*/ + 0x8a8f, 0x8a90, 0x8a91, 0x8a92, 0x8a93, 0x8a94, 0xc4b7, 0x8a95, /*0xc0-0xc7*/ + 0x8a96, 0x8a97, 0xe6a2, 0xcabc, 0x8a98, 0x8a99, 0x8a9a, 0x8a9b, /*0xc8-0xcf*/ + 0xbde3, 0xb9c3, 0xe6a6, 0xd0d5, 0xceaf, 0x8a9c, 0x8a9d, 0xe6a9, /*0xd0-0xd7*/ + 0xe6b0, 0x8a9e, 0xd2a6, 0x8a9f, 0xbdaa, 0xe6ad, 0x8aa0, 0x8aa1, /*0xd8-0xdf*/ + 0x8aa2, 0x8aa3, 0x8aa4, 0xe6af, 0x8aa5, 0xc0d1, 0x8aa6, 0x8aa7, /*0xe0-0xe7*/ + 0xd2cc, 0x8aa8, 0x8aa9, 0x8aaa, 0xbca7, 0x8aab, 0x8aac, 0x8aad, /*0xe8-0xef*/ + 0x8aae, 0x8aaf, 0x8ab0, 0x8ab1, 0x8ab2, 0x8ab3, 0x8ab4, 0x8ab5, /*0xf0-0xf7*/ + 0x8ab6, 0xe6b1, 0x8ab7, 0xd2f6, 0x8ab8, 0x8ab9, 0x8aba, 0xd7cb, /*0xf8-0xff*/ + /* 0x5a00 */ + 0x8abb, 0xcdfe, 0x8abc, 0xcdde, 0xc2a6, 0xe6ab, 0xe6ac, 0xbdbf, /*0x00-0x07*/ + 0xe6ae, 0xe6b3, 0x8abd, 0x8abe, 0xe6b2, 0x8abf, 0x8ac0, 0x8ac1, /*0x08-0x0f*/ + 0x8ac2, 0xe6b6, 0x8ac3, 0xe6b8, 0x8ac4, 0x8ac5, 0x8ac6, 0x8ac7, /*0x10-0x17*/ + 0xc4ef, 0x8ac8, 0x8ac9, 0x8aca, 0xc4c8, 0x8acb, 0x8acc, 0xbeea, /*0x18-0x1f*/ + 0xc9ef, 0x8acd, 0x8ace, 0xe6b7, 0x8acf, 0xb6f0, 0x8ad0, 0x8ad1, /*0x20-0x27*/ + 0x8ad2, 0xc3e4, 0x8ad3, 0x8ad4, 0x8ad5, 0x8ad6, 0x8ad7, 0x8ad8, /*0x28-0x2f*/ + 0x8ad9, 0xd3e9, 0xe6b4, 0x8ada, 0xe6b5, 0x8adb, 0xc8a2, 0x8adc, /*0x30-0x37*/ + 0x8add, 0x8ade, 0x8adf, 0x8ae0, 0xe6bd, 0x8ae1, 0x8ae2, 0x8ae3, /*0x38-0x3f*/ + 0xe6b9, 0x8ae4, 0x8ae5, 0x8ae6, 0x8ae7, 0x8ae8, 0xc6c5, 0x8ae9, /*0x40-0x47*/ + 0x8aea, 0xcdf1, 0xe6bb, 0x8aeb, 0x8aec, 0x8aed, 0x8aee, 0x8aef, /*0x48-0x4f*/ + 0x8af0, 0x8af1, 0x8af2, 0x8af3, 0x8af4, 0xe6bc, 0x8af5, 0x8af6, /*0x50-0x57*/ + 0x8af7, 0x8af8, 0xbbe9, 0x8af9, 0x8afa, 0x8afb, 0x8afc, 0x8afd, /*0x58-0x5f*/ + 0x8afe, 0x8b40, 0xe6be, 0x8b41, 0x8b42, 0x8b43, 0x8b44, 0xe6ba, /*0x60-0x67*/ + 0x8b45, 0x8b46, 0xc0b7, 0x8b47, 0x8b48, 0x8b49, 0x8b4a, 0x8b4b, /*0x68-0x6f*/ + 0x8b4c, 0x8b4d, 0x8b4e, 0x8b4f, 0xd3a4, 0xe6bf, 0xc9f4, 0xe6c3, /*0x70-0x77*/ + 0x8b50, 0x8b51, 0xe6c4, 0x8b52, 0x8b53, 0x8b54, 0x8b55, 0xd0f6, /*0x78-0x7f*/ + 0x8b56, 0x8b57, 0x8b58, 0x8b59, 0x8b5a, 0x8b5b, 0x8b5c, 0x8b5d, /*0x80-0x87*/ + 0x8b5e, 0x8b5f, 0x8b60, 0x8b61, 0x8b62, 0x8b63, 0x8b64, 0x8b65, /*0x88-0x8f*/ + 0x8b66, 0x8b67, 0xc3bd, 0x8b68, 0x8b69, 0x8b6a, 0x8b6b, 0x8b6c, /*0x90-0x97*/ + 0x8b6d, 0x8b6e, 0xc3c4, 0xe6c2, 0x8b6f, 0x8b70, 0x8b71, 0x8b72, /*0x98-0x9f*/ + 0x8b73, 0x8b74, 0x8b75, 0x8b76, 0x8b77, 0x8b78, 0x8b79, 0x8b7a, /*0xa0-0xa7*/ + 0x8b7b, 0x8b7c, 0xe6c1, 0x8b7d, 0x8b7e, 0x8b80, 0x8b81, 0x8b82, /*0xa8-0xaf*/ + 0x8b83, 0x8b84, 0xe6c7, 0xcfb1, 0x8b85, 0xebf4, 0x8b86, 0x8b87, /*0xb0-0xb7*/ + 0xe6ca, 0x8b88, 0x8b89, 0x8b8a, 0x8b8b, 0x8b8c, 0xe6c5, 0x8b8d, /*0xb8-0xbf*/ + 0x8b8e, 0xbcde, 0xc9a9, 0x8b8f, 0x8b90, 0x8b91, 0x8b92, 0x8b93, /*0xc0-0xc7*/ + 0x8b94, 0xbcb5, 0x8b95, 0x8b96, 0xcfd3, 0x8b97, 0x8b98, 0x8b99, /*0xc8-0xcf*/ + 0x8b9a, 0x8b9b, 0xe6c8, 0x8b9c, 0xe6c9, 0x8b9d, 0xe6ce, 0x8b9e, /*0xd0-0xd7*/ + 0xe6d0, 0x8b9f, 0x8ba0, 0x8ba1, 0xe6d1, 0x8ba2, 0x8ba3, 0x8ba4, /*0xd8-0xdf*/ + 0xe6cb, 0xb5d5, 0x8ba5, 0xe6cc, 0x8ba6, 0x8ba7, 0xe6cf, 0x8ba8, /*0xe0-0xe7*/ + 0x8ba9, 0xc4db, 0x8baa, 0xe6c6, 0x8bab, 0x8bac, 0x8bad, 0x8bae, /*0xe8-0xef*/ + 0x8baf, 0xe6cd, 0x8bb0, 0x8bb1, 0x8bb2, 0x8bb3, 0x8bb4, 0x8bb5, /*0xf0-0xf7*/ + 0x8bb6, 0x8bb7, 0x8bb8, 0x8bb9, 0x8bba, 0x8bbb, 0x8bbc, 0x8bbd, /*0xf8-0xff*/ + /* 0x5b00 */ + 0x8bbe, 0x8bbf, 0x8bc0, 0x8bc1, 0x8bc2, 0x8bc3, 0x8bc4, 0x8bc5, /*0x00-0x07*/ + 0x8bc6, 0xe6d2, 0x8bc7, 0x8bc8, 0x8bc9, 0x8bca, 0x8bcb, 0x8bcc, /*0x08-0x0f*/ + 0x8bcd, 0x8bce, 0x8bcf, 0x8bd0, 0x8bd1, 0x8bd2, 0xe6d4, 0xe6d3, /*0x10-0x17*/ + 0x8bd3, 0x8bd4, 0x8bd5, 0x8bd6, 0x8bd7, 0x8bd8, 0x8bd9, 0x8bda, /*0x18-0x1f*/ + 0x8bdb, 0x8bdc, 0x8bdd, 0x8bde, 0x8bdf, 0x8be0, 0x8be1, 0x8be2, /*0x20-0x27*/ + 0x8be3, 0x8be4, 0x8be5, 0x8be6, 0x8be7, 0x8be8, 0x8be9, 0x8bea, /*0x28-0x2f*/ + 0x8beb, 0x8bec, 0xe6d5, 0x8bed, 0xd9f8, 0x8bee, 0x8bef, 0xe6d6, /*0x30-0x37*/ + 0x8bf0, 0x8bf1, 0x8bf2, 0x8bf3, 0x8bf4, 0x8bf5, 0x8bf6, 0x8bf7, /*0x38-0x3f*/ + 0xe6d7, 0x8bf8, 0x8bf9, 0x8bfa, 0x8bfb, 0x8bfc, 0x8bfd, 0x8bfe, /*0x40-0x47*/ + 0x8c40, 0x8c41, 0x8c42, 0x8c43, 0x8c44, 0x8c45, 0x8c46, 0x8c47, /*0x48-0x4f*/ + 0xd7d3, 0xe6dd, 0x8c48, 0xe6de, 0xbfd7, 0xd4d0, 0x8c49, 0xd7d6, /*0x50-0x57*/ + 0xb4e6, 0xcbef, 0xe6da, 0xd8c3, 0xd7ce, 0xd0a2, 0x8c4a, 0xc3cf, /*0x58-0x5f*/ + 0x8c4b, 0x8c4c, 0xe6df, 0xbcbe, 0xb9c2, 0xe6db, 0xd1a7, 0x8c4d, /*0x60-0x67*/ + 0x8c4e, 0xbaa2, 0xc2cf, 0x8c4f, 0xd8ab, 0x8c50, 0x8c51, 0x8c52, /*0x68-0x6f*/ + 0xcaeb, 0xe5ee, 0x8c53, 0xe6dc, 0x8c54, 0xb7f5, 0x8c55, 0x8c56, /*0x70-0x77*/ + 0x8c57, 0x8c58, 0xc8e6, 0x8c59, 0x8c5a, 0xc4f5, 0x8c5b, 0x8c5c, /*0x78-0x7f*/ + 0xe5b2, 0xc4fe, 0x8c5d, 0xcbfc, 0xe5b3, 0xd5ac, 0x8c5e, 0xd3ee, /*0x80-0x87*/ + 0xcad8, 0xb0b2, 0x8c5f, 0xcbce, 0xcdea, 0x8c60, 0x8c61, 0xbaea, /*0x88-0x8f*/ + 0x8c62, 0x8c63, 0x8c64, 0xe5b5, 0x8c65, 0xe5b4, 0x8c66, 0xd7da, /*0x90-0x97*/ + 0xb9d9, 0xd6e6, 0xb6a8, 0xcdf0, 0xd2cb, 0xb1a6, 0xcab5, 0x8c67, /*0x98-0x9f*/ + 0xb3e8, 0xc9f3, 0xbfcd, 0xd0fb, 0xcad2, 0xe5b6, 0xbbc2, 0x8c68, /*0xa0-0xa7*/ + 0x8c69, 0x8c6a, 0xcfdc, 0xb9ac, 0x8c6b, 0x8c6c, 0x8c6d, 0x8c6e, /*0xa8-0xaf*/ + 0xd4d7, 0x8c6f, 0x8c70, 0xbaa6, 0xd1e7, 0xcffc, 0xbcd2, 0x8c71, /*0xb0-0xb7*/ + 0xe5b7, 0xc8dd, 0x8c72, 0x8c73, 0x8c74, 0xbfed, 0xb1f6, 0xcbde, /*0xb8-0xbf*/ + 0x8c75, 0x8c76, 0xbcc5, 0x8c77, 0xbcc4, 0xd2fa, 0xc3dc, 0xbfdc, /*0xc0-0xc7*/ + 0x8c78, 0x8c79, 0x8c7a, 0x8c7b, 0xb8bb, 0x8c7c, 0x8c7d, 0x8c7e, /*0xc8-0xcf*/ + 0xc3c2, 0x8c80, 0xbaae, 0xd4a2, 0x8c81, 0x8c82, 0x8c83, 0x8c84, /*0xd0-0xd7*/ + 0x8c85, 0x8c86, 0x8c87, 0x8c88, 0x8c89, 0xc7de, 0xc4af, 0xb2ec, /*0xd8-0xdf*/ + 0x8c8a, 0xb9d1, 0x8c8b, 0x8c8c, 0xe5bb, 0xc1c8, 0x8c8d, 0x8c8e, /*0xe0-0xe7*/ + 0xd5af, 0x8c8f, 0x8c90, 0x8c91, 0x8c92, 0x8c93, 0xe5bc, 0x8c94, /*0xe8-0xef*/ + 0xe5be, 0x8c95, 0x8c96, 0x8c97, 0x8c98, 0x8c99, 0x8c9a, 0x8c9b, /*0xf0-0xf7*/ + 0xb4e7, 0xb6d4, 0xcbc2, 0xd1b0, 0xb5bc, 0x8c9c, 0x8c9d, 0xcad9, /*0xf8-0xff*/ + /* 0x5c00 */ + 0x8c9e, 0xb7e2, 0x8c9f, 0x8ca0, 0xc9e4, 0x8ca1, 0xbdab, 0x8ca2, /*0x00-0x07*/ + 0x8ca3, 0xcebe, 0xd7f0, 0x8ca4, 0x8ca5, 0x8ca6, 0x8ca7, 0xd0a1, /*0x08-0x0f*/ + 0x8ca8, 0xc9d9, 0x8ca9, 0x8caa, 0xb6fb, 0xe6d8, 0xbce2, 0x8cab, /*0x10-0x17*/ + 0xb3be, 0x8cac, 0xc9d0, 0x8cad, 0xe6d9, 0xb3a2, 0x8cae, 0x8caf, /*0x18-0x1f*/ + 0x8cb0, 0x8cb1, 0xdecc, 0x8cb2, 0xd3c8, 0xdecd, 0x8cb3, 0xd2a2, /*0x20-0x27*/ + 0x8cb4, 0x8cb5, 0x8cb6, 0x8cb7, 0xdece, 0x8cb8, 0x8cb9, 0x8cba, /*0x28-0x2f*/ + 0x8cbb, 0xbecd, 0x8cbc, 0x8cbd, 0xdecf, 0x8cbe, 0x8cbf, 0x8cc0, /*0x30-0x37*/ + 0xcaac, 0xd2fc, 0xb3df, 0xe5ea, 0xc4e1, 0xbea1, 0xceb2, 0xc4f2, /*0x38-0x3f*/ + 0xbed6, 0xc6a8, 0xb2e3, 0x8cc1, 0x8cc2, 0xbed3, 0x8cc3, 0x8cc4, /*0x40-0x47*/ + 0xc7fc, 0xcceb, 0xbdec, 0xcedd, 0x8cc5, 0x8cc6, 0xcaba, 0xc6c1, /*0x48-0x4f*/ + 0xe5ec, 0xd0bc, 0x8cc7, 0x8cc8, 0x8cc9, 0xd5b9, 0x8cca, 0x8ccb, /*0x50-0x57*/ + 0x8ccc, 0xe5ed, 0x8ccd, 0x8cce, 0x8ccf, 0x8cd0, 0xcaf4, 0x8cd1, /*0x58-0x5f*/ + 0xcdc0, 0xc2c5, 0x8cd2, 0xe5ef, 0x8cd3, 0xc2c4, 0xe5f0, 0x8cd4, /*0x60-0x67*/ + 0x8cd5, 0x8cd6, 0x8cd7, 0x8cd8, 0x8cd9, 0x8cda, 0xe5f8, 0xcdcd, /*0x68-0x6f*/ + 0x8cdb, 0xc9bd, 0x8cdc, 0x8cdd, 0x8cde, 0x8cdf, 0x8ce0, 0x8ce1, /*0x70-0x77*/ + 0x8ce2, 0xd2d9, 0xe1a8, 0x8ce3, 0x8ce4, 0x8ce5, 0x8ce6, 0xd3ec, /*0x78-0x7f*/ + 0x8ce7, 0xcbea, 0xc6f1, 0x8ce8, 0x8ce9, 0x8cea, 0x8ceb, 0x8cec, /*0x80-0x87*/ + 0xe1ac, 0x8ced, 0x8cee, 0x8cef, 0xe1a7, 0xe1a9, 0x8cf0, 0x8cf1, /*0x88-0x8f*/ + 0xe1aa, 0xe1af, 0x8cf2, 0x8cf3, 0xb2ed, 0x8cf4, 0xe1ab, 0xb8da, /*0x90-0x97*/ + 0xe1ad, 0xe1ae, 0xe1b0, 0xb5ba, 0xe1b1, 0x8cf5, 0x8cf6, 0x8cf7, /*0x98-0x9f*/ + 0x8cf8, 0x8cf9, 0xe1b3, 0xe1b8, 0x8cfa, 0x8cfb, 0x8cfc, 0x8cfd, /*0xa0-0xa7*/ + 0x8cfe, 0xd1d2, 0x8d40, 0xe1b6, 0xe1b5, 0xc1eb, 0x8d41, 0x8d42, /*0xa8-0xaf*/ + 0x8d43, 0xe1b7, 0x8d44, 0xd4c0, 0x8d45, 0xe1b2, 0x8d46, 0xe1ba, /*0xb0-0xb7*/ + 0xb0b6, 0x8d47, 0x8d48, 0x8d49, 0x8d4a, 0xe1b4, 0x8d4b, 0xbff9, /*0xb8-0xbf*/ + 0x8d4c, 0xe1b9, 0x8d4d, 0x8d4e, 0xe1bb, 0x8d4f, 0x8d50, 0x8d51, /*0xc0-0xc7*/ + 0x8d52, 0x8d53, 0x8d54, 0xe1be, 0x8d55, 0x8d56, 0x8d57, 0x8d58, /*0xc8-0xcf*/ + 0x8d59, 0x8d5a, 0xe1bc, 0x8d5b, 0x8d5c, 0x8d5d, 0x8d5e, 0x8d5f, /*0xd0-0xd7*/ + 0x8d60, 0xd6c5, 0x8d61, 0x8d62, 0x8d63, 0x8d64, 0x8d65, 0x8d66, /*0xd8-0xdf*/ + 0x8d67, 0xcfbf, 0x8d68, 0x8d69, 0xe1bd, 0xe1bf, 0xc2cd, 0x8d6a, /*0xe0-0xe7*/ + 0xb6eb, 0x8d6b, 0xd3f8, 0x8d6c, 0x8d6d, 0xc7cd, 0x8d6e, 0x8d6f, /*0xe8-0xef*/ + 0xb7e5, 0x8d70, 0x8d71, 0x8d72, 0x8d73, 0x8d74, 0x8d75, 0x8d76, /*0xf0-0xf7*/ + 0x8d77, 0x8d78, 0x8d79, 0xbefe, 0x8d7a, 0x8d7b, 0x8d7c, 0x8d7d, /*0xf8-0xff*/ + /* 0x5d00 */ + 0x8d7e, 0x8d80, 0xe1c0, 0xe1c1, 0x8d81, 0x8d82, 0xe1c7, 0xb3e7, /*0x00-0x07*/ + 0x8d83, 0x8d84, 0x8d85, 0x8d86, 0x8d87, 0x8d88, 0xc6e9, 0x8d89, /*0x08-0x0f*/ + 0x8d8a, 0x8d8b, 0x8d8c, 0x8d8d, 0xb4de, 0x8d8e, 0xd1c2, 0x8d8f, /*0x10-0x17*/ + 0x8d90, 0x8d91, 0x8d92, 0xe1c8, 0x8d93, 0x8d94, 0xe1c6, 0x8d95, /*0x18-0x1f*/ + 0x8d96, 0x8d97, 0x8d98, 0x8d99, 0xe1c5, 0x8d9a, 0xe1c3, 0xe1c2, /*0x20-0x27*/ + 0x8d9b, 0xb1c0, 0x8d9c, 0x8d9d, 0x8d9e, 0xd5b8, 0xe1c4, 0x8d9f, /*0x28-0x2f*/ + 0x8da0, 0x8da1, 0x8da2, 0x8da3, 0xe1cb, 0x8da4, 0x8da5, 0x8da6, /*0x30-0x37*/ + 0x8da7, 0x8da8, 0x8da9, 0x8daa, 0x8dab, 0xe1cc, 0xe1ca, 0x8dac, /*0x38-0x3f*/ + 0x8dad, 0x8dae, 0x8daf, 0x8db0, 0x8db1, 0x8db2, 0x8db3, 0xeffa, /*0x40-0x47*/ + 0x8db4, 0x8db5, 0xe1d3, 0xe1d2, 0xc7b6, 0x8db6, 0x8db7, 0x8db8, /*0x48-0x4f*/ + 0x8db9, 0x8dba, 0x8dbb, 0x8dbc, 0x8dbd, 0x8dbe, 0x8dbf, 0x8dc0, /*0x50-0x57*/ + 0xe1c9, 0x8dc1, 0x8dc2, 0xe1ce, 0x8dc3, 0xe1d0, 0x8dc4, 0x8dc5, /*0x58-0x5f*/ + 0x8dc6, 0x8dc7, 0x8dc8, 0x8dc9, 0x8dca, 0x8dcb, 0x8dcc, 0x8dcd, /*0x60-0x67*/ + 0x8dce, 0xe1d4, 0x8dcf, 0xe1d1, 0xe1cd, 0x8dd0, 0x8dd1, 0xe1cf, /*0x68-0x6f*/ + 0x8dd2, 0x8dd3, 0x8dd4, 0x8dd5, 0xe1d5, 0x8dd6, 0x8dd7, 0x8dd8, /*0x70-0x77*/ + 0x8dd9, 0x8dda, 0x8ddb, 0x8ddc, 0x8ddd, 0x8dde, 0x8ddf, 0x8de0, /*0x78-0x7f*/ + 0x8de1, 0x8de2, 0xe1d6, 0x8de3, 0x8de4, 0x8de5, 0x8de6, 0x8de7, /*0x80-0x87*/ + 0x8de8, 0x8de9, 0x8dea, 0x8deb, 0x8dec, 0x8ded, 0x8dee, 0x8def, /*0x88-0x8f*/ + 0x8df0, 0x8df1, 0x8df2, 0x8df3, 0x8df4, 0x8df5, 0x8df6, 0x8df7, /*0x90-0x97*/ + 0x8df8, 0xe1d7, 0x8df9, 0x8dfa, 0x8dfb, 0xe1d8, 0x8dfc, 0x8dfd, /*0x98-0x9f*/ + 0x8dfe, 0x8e40, 0x8e41, 0x8e42, 0x8e43, 0x8e44, 0x8e45, 0x8e46, /*0xa0-0xa7*/ + 0x8e47, 0x8e48, 0x8e49, 0x8e4a, 0x8e4b, 0x8e4c, 0x8e4d, 0x8e4e, /*0xa8-0xaf*/ + 0x8e4f, 0x8e50, 0x8e51, 0x8e52, 0x8e53, 0x8e54, 0x8e55, 0xe1da, /*0xb0-0xb7*/ + 0x8e56, 0x8e57, 0x8e58, 0x8e59, 0x8e5a, 0x8e5b, 0x8e5c, 0x8e5d, /*0xb8-0xbf*/ + 0x8e5e, 0x8e5f, 0x8e60, 0x8e61, 0x8e62, 0xe1db, 0x8e63, 0x8e64, /*0xc0-0xc7*/ + 0x8e65, 0x8e66, 0x8e67, 0x8e68, 0x8e69, 0xcea1, 0x8e6a, 0x8e6b, /*0xc8-0xcf*/ + 0x8e6c, 0x8e6d, 0x8e6e, 0x8e6f, 0x8e70, 0x8e71, 0x8e72, 0x8e73, /*0xd0-0xd7*/ + 0x8e74, 0x8e75, 0x8e76, 0xe7dd, 0x8e77, 0xb4a8, 0xd6dd, 0x8e78, /*0xd8-0xdf*/ + 0x8e79, 0xd1b2, 0xb3b2, 0x8e7a, 0x8e7b, 0xb9a4, 0xd7f3, 0xc7c9, /*0xe0-0xe7*/ + 0xbede, 0xb9ae, 0x8e7c, 0xced7, 0x8e7d, 0x8e7e, 0xb2ee, 0xdbcf, /*0xe8-0xef*/ + 0x8e80, 0xbcba, 0xd2d1, 0xcbc8, 0xb0cd, 0x8e81, 0x8e82, 0xcfef, /*0xf0-0xf7*/ + 0x8e83, 0x8e84, 0x8e85, 0x8e86, 0x8e87, 0xd9e3, 0xbded, 0x8e88, /*0xf8-0xff*/ + /* 0x5e00 */ + 0x8e89, 0xb1d2, 0xcad0, 0xb2bc, 0x8e8a, 0xcba7, 0xb7ab, 0x8e8b, /*0x00-0x07*/ + 0xcaa6, 0x8e8c, 0x8e8d, 0x8e8e, 0xcfa3, 0x8e8f, 0x8e90, 0xe0f8, /*0x08-0x0f*/ + 0xd5ca, 0xe0fb, 0x8e91, 0x8e92, 0xe0fa, 0xc5c1, 0xccfb, 0x8e93, /*0x10-0x17*/ + 0xc1b1, 0xe0f9, 0xd6e3, 0xb2af, 0xd6c4, 0xb5db, 0x8e94, 0x8e95, /*0x18-0x1f*/ + 0x8e96, 0x8e97, 0x8e98, 0x8e99, 0x8e9a, 0x8e9b, 0xb4f8, 0xd6a1, /*0x20-0x27*/ + 0x8e9c, 0x8e9d, 0x8e9e, 0x8e9f, 0x8ea0, 0xcfaf, 0xb0ef, 0x8ea1, /*0x28-0x2f*/ + 0x8ea2, 0xe0fc, 0x8ea3, 0x8ea4, 0x8ea5, 0x8ea6, 0x8ea7, 0xe1a1, /*0x30-0x37*/ + 0xb3a3, 0x8ea8, 0x8ea9, 0xe0fd, 0xe0fe, 0xc3b1, 0x8eaa, 0x8eab, /*0x38-0x3f*/ + 0x8eac, 0x8ead, 0xc3dd, 0x8eae, 0xe1a2, 0xb7f9, 0x8eaf, 0x8eb0, /*0x40-0x47*/ + 0x8eb1, 0x8eb2, 0x8eb3, 0x8eb4, 0xbbcf, 0x8eb5, 0x8eb6, 0x8eb7, /*0x48-0x4f*/ + 0x8eb8, 0x8eb9, 0x8eba, 0x8ebb, 0xe1a3, 0xc4bb, 0x8ebc, 0x8ebd, /*0x50-0x57*/ + 0x8ebe, 0x8ebf, 0x8ec0, 0xe1a4, 0x8ec1, 0x8ec2, 0xe1a5, 0x8ec3, /*0x58-0x5f*/ + 0x8ec4, 0xe1a6, 0xb4b1, 0x8ec5, 0x8ec6, 0x8ec7, 0x8ec8, 0x8ec9, /*0x60-0x67*/ + 0x8eca, 0x8ecb, 0x8ecc, 0x8ecd, 0x8ece, 0x8ecf, 0x8ed0, 0x8ed1, /*0x68-0x6f*/ + 0x8ed2, 0x8ed3, 0xb8c9, 0xc6bd, 0xc4ea, 0x8ed4, 0xb2a2, 0x8ed5, /*0x70-0x77*/ + 0xd0d2, 0x8ed6, 0xe7db, 0xbbc3, 0xd3d7, 0xd3c4, 0x8ed7, 0xb9e3, /*0x78-0x7f*/ + 0xe2cf, 0x8ed8, 0x8ed9, 0x8eda, 0xd7af, 0x8edb, 0xc7ec, 0xb1d3, /*0x80-0x87*/ + 0x8edc, 0x8edd, 0xb4b2, 0xe2d1, 0x8ede, 0x8edf, 0x8ee0, 0xd0f2, /*0x88-0x8f*/ + 0xc2ae, 0xe2d0, 0x8ee1, 0xbfe2, 0xd3a6, 0xb5d7, 0xe2d2, 0xb5ea, /*0x90-0x97*/ + 0x8ee2, 0xc3ed, 0xb8fd, 0x8ee3, 0xb8ae, 0x8ee4, 0xc5d3, 0xb7cf, /*0x98-0x9f*/ + 0xe2d4, 0x8ee5, 0x8ee6, 0x8ee7, 0x8ee8, 0xe2d3, 0xb6c8, 0xd7f9, /*0xa0-0xa7*/ + 0x8ee9, 0x8eea, 0x8eeb, 0x8eec, 0x8eed, 0xcda5, 0x8eee, 0x8eef, /*0xa8-0xaf*/ + 0x8ef0, 0x8ef1, 0x8ef2, 0xe2d8, 0x8ef3, 0xe2d6, 0xcafc, 0xbfb5, /*0xb0-0xb7*/ + 0xd3b9, 0xe2d5, 0x8ef4, 0x8ef5, 0x8ef6, 0x8ef7, 0xe2d7, 0x8ef8, /*0xb8-0xbf*/ + 0x8ef9, 0x8efa, 0x8efb, 0x8efc, 0x8efd, 0x8efe, 0x8f40, 0x8f41, /*0xc0-0xc7*/ + 0x8f42, 0xc1ae, 0xc0c8, 0x8f43, 0x8f44, 0x8f45, 0x8f46, 0x8f47, /*0xc8-0xcf*/ + 0x8f48, 0xe2db, 0xe2da, 0xc0aa, 0x8f49, 0x8f4a, 0xc1ce, 0x8f4b, /*0xd0-0xd7*/ + 0x8f4c, 0x8f4d, 0x8f4e, 0xe2dc, 0x8f4f, 0x8f50, 0x8f51, 0x8f52, /*0xd8-0xdf*/ + 0x8f53, 0x8f54, 0x8f55, 0x8f56, 0x8f57, 0x8f58, 0x8f59, 0x8f5a, /*0xe0-0xe7*/ + 0xe2dd, 0x8f5b, 0xe2de, 0x8f5c, 0x8f5d, 0x8f5e, 0x8f5f, 0x8f60, /*0xe8-0xef*/ + 0x8f61, 0x8f62, 0x8f63, 0x8f64, 0xdbc8, 0x8f65, 0xd1d3, 0xcda2, /*0xf0-0xf7*/ + 0x8f66, 0x8f67, 0xbda8, 0x8f68, 0x8f69, 0x8f6a, 0xdec3, 0xd8a5, /*0xf8-0xff*/ + /* 0x5f00 */ + 0xbfaa, 0xdbcd, 0xd2ec, 0xc6fa, 0xc5aa, 0x8f6b, 0x8f6c, 0x8f6d, /*0x00-0x07*/ + 0xdec4, 0x8f6e, 0xb1d7, 0xdfae, 0x8f6f, 0x8f70, 0x8f71, 0xcabd, /*0x08-0x0f*/ + 0x8f72, 0xdfb1, 0x8f73, 0xb9ad, 0x8f74, 0xd2fd, 0x8f75, 0xb8a5, /*0x10-0x17*/ + 0xbaeb, 0x8f76, 0x8f77, 0xb3da, 0x8f78, 0x8f79, 0x8f7a, 0xb5dc, /*0x18-0x1f*/ + 0xd5c5, 0x8f7b, 0x8f7c, 0x8f7d, 0x8f7e, 0xc3d6, 0xcfd2, 0xbba1, /*0x20-0x27*/ + 0x8f80, 0xe5f3, 0xe5f2, 0x8f81, 0x8f82, 0xe5f4, 0x8f83, 0xcde4, /*0x28-0x2f*/ + 0x8f84, 0xc8f5, 0x8f85, 0x8f86, 0x8f87, 0x8f88, 0x8f89, 0x8f8a, /*0x30-0x37*/ + 0x8f8b, 0xb5af, 0xc7bf, 0x8f8c, 0xe5f6, 0x8f8d, 0x8f8e, 0x8f8f, /*0x38-0x3f*/ + 0xecb0, 0x8f90, 0x8f91, 0x8f92, 0x8f93, 0x8f94, 0x8f95, 0x8f96, /*0x40-0x47*/ + 0x8f97, 0x8f98, 0x8f99, 0x8f9a, 0x8f9b, 0x8f9c, 0x8f9d, 0x8f9e, /*0x48-0x4f*/ + 0xe5e6, 0x8f9f, 0xb9e9, 0xb5b1, 0x8fa0, 0xc2bc, 0xe5e8, 0xe5e7, /*0x50-0x57*/ + 0xe5e9, 0x8fa1, 0x8fa2, 0x8fa3, 0x8fa4, 0xd2cd, 0x8fa5, 0x8fa6, /*0x58-0x5f*/ + 0x8fa7, 0xe1ea, 0xd0ce, 0x8fa8, 0xcdae, 0x8fa9, 0xd1e5, 0x8faa, /*0x60-0x67*/ + 0x8fab, 0xb2ca, 0xb1eb, 0x8fac, 0xb1f2, 0xc5ed, 0x8fad, 0x8fae, /*0x68-0x6f*/ + 0xd5c3, 0xd3b0, 0x8faf, 0xe1dc, 0x8fb0, 0x8fb1, 0x8fb2, 0xe1dd, /*0x70-0x77*/ + 0x8fb3, 0xd2db, 0x8fb4, 0xb3b9, 0xb1cb, 0x8fb5, 0x8fb6, 0x8fb7, /*0x78-0x7f*/ + 0xcdf9, 0xd5f7, 0xe1de, 0x8fb8, 0xbeb6, 0xb4fd, 0x8fb9, 0xe1df, /*0x80-0x87*/ + 0xbadc, 0xe1e0, 0xbbb2, 0xc2c9, 0xe1e1, 0x8fba, 0x8fbb, 0x8fbc, /*0x88-0x8f*/ + 0xd0ec, 0x8fbd, 0xcdbd, 0x8fbe, 0x8fbf, 0xe1e2, 0x8fc0, 0xb5c3, /*0x90-0x97*/ + 0xc5c7, 0xe1e3, 0x8fc1, 0x8fc2, 0xe1e4, 0x8fc3, 0x8fc4, 0x8fc5, /*0x98-0x9f*/ + 0x8fc6, 0xd3f9, 0x8fc7, 0x8fc8, 0x8fc9, 0x8fca, 0x8fcb, 0x8fcc, /*0xa0-0xa7*/ + 0xe1e5, 0x8fcd, 0xd1ad, 0x8fce, 0x8fcf, 0xe1e6, 0xcea2, 0x8fd0, /*0xa8-0xaf*/ + 0x8fd1, 0x8fd2, 0x8fd3, 0x8fd4, 0x8fd5, 0xe1e7, 0x8fd6, 0xb5c2, /*0xb0-0xb7*/ + 0x8fd7, 0x8fd8, 0x8fd9, 0x8fda, 0xe1e8, 0xbbd5, 0x8fdb, 0x8fdc, /*0xb8-0xbf*/ + 0x8fdd, 0x8fde, 0x8fdf, 0xd0c4, 0xe2e0, 0xb1d8, 0xd2e4, 0x8fe0, /*0xc0-0xc7*/ + 0x8fe1, 0xe2e1, 0x8fe2, 0x8fe3, 0xbcc9, 0xc8cc, 0x8fe4, 0xe2e3, /*0xc8-0xcf*/ + 0xecfe, 0xecfd, 0xdfaf, 0x8fe5, 0x8fe6, 0x8fe7, 0xe2e2, 0xd6be, /*0xd0-0xd7*/ + 0xcdfc, 0xc3a6, 0x8fe8, 0x8fe9, 0x8fea, 0xe3c3, 0x8feb, 0x8fec, /*0xd8-0xdf*/ + 0xd6d2, 0xe2e7, 0x8fed, 0x8fee, 0xe2e8, 0x8fef, 0x8ff0, 0xd3c7, /*0xe0-0xe7*/ + 0x8ff1, 0x8ff2, 0xe2ec, 0xbfec, 0x8ff3, 0xe2ed, 0xe2e5, 0x8ff4, /*0xe8-0xef*/ + 0x8ff5, 0xb3c0, 0x8ff6, 0x8ff7, 0x8ff8, 0xc4ee, 0x8ff9, 0x8ffa, /*0xf0-0xf7*/ + 0xe2ee, 0x8ffb, 0x8ffc, 0xd0c3, 0x8ffd, 0xbaf6, 0xe2e9, 0xb7de, /*0xf8-0xff*/ + /* 0x6000 */ + 0xbbb3, 0xccac, 0xcbcb, 0xe2e4, 0xe2e6, 0xe2ea, 0xe2eb, 0x8ffe, /*0x00-0x07*/ + 0x9040, 0x9041, 0xe2f7, 0x9042, 0x9043, 0xe2f4, 0xd4f5, 0xe2f3, /*0x08-0x0f*/ + 0x9044, 0x9045, 0xc5ad, 0x9046, 0xd5fa, 0xc5c2, 0xb2c0, 0x9047, /*0x10-0x17*/ + 0x9048, 0xe2ef, 0x9049, 0xe2f2, 0xc1af, 0xcbbc, 0x904a, 0x904b, /*0x18-0x1f*/ + 0xb5a1, 0xe2f9, 0x904c, 0x904d, 0x904e, 0xbcb1, 0xe2f1, 0xd0d4, /*0x20-0x27*/ + 0xd4b9, 0xe2f5, 0xb9d6, 0xe2f6, 0x904f, 0x9050, 0x9051, 0xc7d3, /*0x28-0x2f*/ + 0x9052, 0x9053, 0x9054, 0x9055, 0x9056, 0xe2f0, 0x9057, 0x9058, /*0x30-0x37*/ + 0x9059, 0x905a, 0x905b, 0xd7dc, 0xeda1, 0x905c, 0x905d, 0xe2f8, /*0x38-0x3f*/ + 0x905e, 0xeda5, 0xe2fe, 0xcad1, 0x905f, 0x9060, 0x9061, 0x9062, /*0x40-0x47*/ + 0x9063, 0x9064, 0x9065, 0xc1b5, 0x9066, 0xbbd0, 0x9067, 0x9068, /*0x48-0x4f*/ + 0xbfd6, 0x9069, 0xbae3, 0x906a, 0x906b, 0xcba1, 0x906c, 0x906d, /*0x50-0x57*/ + 0x906e, 0xeda6, 0xeda3, 0x906f, 0x9070, 0xeda2, 0x9071, 0x9072, /*0x58-0x5f*/ + 0x9073, 0x9074, 0xbbd6, 0xeda7, 0xd0f4, 0x9075, 0x9076, 0xeda4, /*0x60-0x67*/ + 0xbade, 0xb6f7, 0xe3a1, 0xb6b2, 0xccf1, 0xb9a7, 0x9077, 0xcfa2, /*0x68-0x6f*/ + 0xc7a1, 0x9078, 0x9079, 0xbfd2, 0x907a, 0x907b, 0xb6f1, 0x907c, /*0x70-0x77*/ + 0xe2fa, 0xe2fb, 0xe2fd, 0xe2fc, 0xc4d5, 0xe3a2, 0x907d, 0xd3c1, /*0x78-0x7f*/ + 0x907e, 0x9080, 0x9081, 0xe3a7, 0xc7c4, 0x9082, 0x9083, 0x9084, /*0x80-0x87*/ + 0x9085, 0xcfa4, 0x9086, 0x9087, 0xe3a9, 0xbab7, 0x9088, 0x9089, /*0x88-0x8f*/ + 0x908a, 0x908b, 0xe3a8, 0x908c, 0xbbda, 0x908d, 0xe3a3, 0x908e, /*0x90-0x97*/ + 0x908f, 0x9090, 0xe3a4, 0xe3aa, 0x9091, 0xe3a6, 0x9092, 0xcef2, /*0x98-0x9f*/ + 0xd3c6, 0x9093, 0x9094, 0xbbbc, 0x9095, 0x9096, 0xd4c3, 0x9097, /*0xa0-0xa7*/ + 0xc4fa, 0x9098, 0x9099, 0xeda8, 0xd0fc, 0xe3a5, 0x909a, 0xc3f5, /*0xa8-0xaf*/ + 0x909b, 0xe3ad, 0xb1af, 0x909c, 0xe3b2, 0x909d, 0x909e, 0x909f, /*0xb0-0xb7*/ + 0xbcc2, 0x90a0, 0x90a1, 0xe3ac, 0xb5bf, 0x90a2, 0x90a3, 0x90a4, /*0xb8-0xbf*/ + 0x90a5, 0x90a6, 0x90a7, 0x90a8, 0x90a9, 0xc7e9, 0xe3b0, 0x90aa, /*0xc0-0xc7*/ + 0x90ab, 0x90ac, 0xbeaa, 0xcdef, 0x90ad, 0x90ae, 0x90af, 0x90b0, /*0xc8-0xcf*/ + 0x90b1, 0xbbf3, 0x90b2, 0x90b3, 0x90b4, 0xcce8, 0x90b5, 0x90b6, /*0xd0-0xd7*/ + 0xe3af, 0x90b7, 0xe3b1, 0x90b8, 0xcfa7, 0xe3ae, 0x90b9, 0xcea9, /*0xd8-0xdf*/ + 0xbbdd, 0x90ba, 0x90bb, 0x90bc, 0x90bd, 0x90be, 0xb5eb, 0xbee5, /*0xe0-0xe7*/ + 0xb2d2, 0xb3cd, 0x90bf, 0xb1b9, 0xe3ab, 0xb2d1, 0xb5ac, 0xb9df, /*0xe8-0xef*/ + 0xb6e8, 0x90c0, 0x90c1, 0xcfeb, 0xe3b7, 0x90c2, 0xbbcc, 0x90c3, /*0xf0-0xf7*/ + 0x90c4, 0xc8c7, 0xd0ca, 0x90c5, 0x90c6, 0x90c7, 0x90c8, 0x90c9, /*0xf8-0xff*/ + /* 0x6100 */ + 0xe3b8, 0xb3ee, 0x90ca, 0x90cb, 0x90cc, 0x90cd, 0xeda9, 0x90ce, /*0x00-0x07*/ + 0xd3fa, 0xd3e4, 0x90cf, 0x90d0, 0x90d1, 0xedaa, 0xe3b9, 0xd2e2, /*0x08-0x0f*/ + 0x90d2, 0x90d3, 0x90d4, 0x90d5, 0x90d6, 0xe3b5, 0x90d7, 0x90d8, /*0x10-0x17*/ + 0x90d9, 0x90da, 0xd3de, 0x90db, 0x90dc, 0x90dd, 0x90de, 0xb8d0, /*0x18-0x1f*/ + 0xe3b3, 0x90df, 0x90e0, 0xe3b6, 0xb7df, 0x90e1, 0xe3b4, 0xc0a2, /*0x20-0x27*/ + 0x90e2, 0x90e3, 0x90e4, 0xe3ba, 0x90e5, 0x90e6, 0x90e7, 0x90e8, /*0x28-0x2f*/ + 0x90e9, 0x90ea, 0x90eb, 0x90ec, 0x90ed, 0x90ee, 0x90ef, 0x90f0, /*0x30-0x37*/ + 0x90f1, 0x90f2, 0x90f3, 0x90f4, 0x90f5, 0x90f6, 0x90f7, 0xd4b8, /*0x38-0x3f*/ + 0x90f8, 0x90f9, 0x90fa, 0x90fb, 0x90fc, 0x90fd, 0x90fe, 0x9140, /*0x40-0x47*/ + 0xb4c8, 0x9141, 0xe3bb, 0x9142, 0xbbc5, 0x9143, 0xc9f7, 0x9144, /*0x48-0x4f*/ + 0x9145, 0xc9e5, 0x9146, 0x9147, 0x9148, 0xc4bd, 0x9149, 0x914a, /*0x50-0x57*/ + 0x914b, 0x914c, 0x914d, 0x914e, 0x914f, 0xedab, 0x9150, 0x9151, /*0x58-0x5f*/ + 0x9152, 0x9153, 0xc2fd, 0x9154, 0x9155, 0x9156, 0x9157, 0xbbdb, /*0x60-0x67*/ + 0xbfae, 0x9158, 0x9159, 0x915a, 0x915b, 0x915c, 0x915d, 0x915e, /*0x68-0x6f*/ + 0xcebf, 0x915f, 0x9160, 0x9161, 0x9162, 0xe3bc, 0x9163, 0xbfb6, /*0x70-0x77*/ + 0x9164, 0x9165, 0x9166, 0x9167, 0x9168, 0x9169, 0x916a, 0x916b, /*0x78-0x7f*/ + 0x916c, 0x916d, 0x916e, 0x916f, 0x9170, 0x9171, 0x9172, 0x9173, /*0x80-0x87*/ + 0x9174, 0x9175, 0x9176, 0xb1ef, 0x9177, 0x9178, 0xd4f7, 0x9179, /*0x88-0x8f*/ + 0x917a, 0x917b, 0x917c, 0x917d, 0xe3be, 0x917e, 0x9180, 0x9181, /*0x90-0x97*/ + 0x9182, 0x9183, 0x9184, 0x9185, 0x9186, 0xedad, 0x9187, 0x9188, /*0x98-0x9f*/ + 0x9189, 0x918a, 0x918b, 0x918c, 0x918d, 0x918e, 0x918f, 0xe3bf, /*0xa0-0xa7*/ + 0xbaa9, 0xedac, 0x9190, 0x9191, 0xe3bd, 0x9192, 0x9193, 0x9194, /*0xa8-0xaf*/ + 0x9195, 0x9196, 0x9197, 0x9198, 0x9199, 0x919a, 0x919b, 0xe3c0, /*0xb0-0xb7*/ + 0x919c, 0x919d, 0x919e, 0x919f, 0x91a0, 0x91a1, 0xbab6, 0x91a2, /*0xb8-0xbf*/ + 0x91a3, 0x91a4, 0xb6ae, 0x91a5, 0x91a6, 0x91a7, 0x91a8, 0x91a9, /*0xc0-0xc7*/ + 0xd0b8, 0x91aa, 0xb0c3, 0xedae, 0x91ab, 0x91ac, 0x91ad, 0x91ae, /*0xc8-0xcf*/ + 0x91af, 0xedaf, 0xc0c1, 0x91b0, 0xe3c1, 0x91b1, 0x91b2, 0x91b3, /*0xd0-0xd7*/ + 0x91b4, 0x91b5, 0x91b6, 0x91b7, 0x91b8, 0x91b9, 0x91ba, 0x91bb, /*0xd8-0xdf*/ + 0x91bc, 0x91bd, 0x91be, 0x91bf, 0x91c0, 0x91c1, 0xc5b3, 0x91c2, /*0xe0-0xe7*/ + 0x91c3, 0x91c4, 0x91c5, 0x91c6, 0x91c7, 0x91c8, 0x91c9, 0x91ca, /*0xe8-0xef*/ + 0x91cb, 0x91cc, 0x91cd, 0x91ce, 0x91cf, 0xe3c2, 0x91d0, 0x91d1, /*0xf0-0xf7*/ + 0x91d2, 0x91d3, 0x91d4, 0x91d5, 0x91d6, 0x91d7, 0x91d8, 0xdcb2, /*0xf8-0xff*/ + /* 0x6200 */ + 0x91d9, 0x91da, 0x91db, 0x91dc, 0x91dd, 0x91de, 0xedb0, 0x91df, /*0x00-0x07*/ + 0xb8ea, 0x91e0, 0xceec, 0xeaa7, 0xd0e7, 0xcaf9, 0xc8d6, 0xcfb7, /*0x08-0x0f*/ + 0xb3c9, 0xced2, 0xbde4, 0x91e1, 0x91e2, 0xe3de, 0xbbf2, 0xeaa8, /*0x10-0x17*/ + 0xd5bd, 0x91e3, 0xc6dd, 0xeaa9, 0x91e4, 0x91e5, 0x91e6, 0xeaaa, /*0x18-0x1f*/ + 0x91e7, 0xeaac, 0xeaab, 0x91e8, 0xeaae, 0xeaad, 0x91e9, 0x91ea, /*0x20-0x27*/ + 0x91eb, 0x91ec, 0xbdd8, 0x91ed, 0xeaaf, 0x91ee, 0xc2be, 0x91ef, /*0x28-0x2f*/ + 0x91f0, 0x91f1, 0x91f2, 0xb4c1, 0xb4f7, 0x91f3, 0x91f4, 0xbba7, /*0x30-0x37*/ + 0x91f5, 0x91f6, 0x91f7, 0x91f8, 0x91f9, 0xece6, 0xece5, 0xb7bf, /*0x38-0x3f*/ + 0xcbf9, 0xb1e2, 0x91fa, 0xece7, 0x91fb, 0x91fc, 0x91fd, 0xc9c8, /*0x40-0x47*/ + 0xece8, 0xece9, 0x91fe, 0xcad6, 0xded0, 0xb2c5, 0xd4fa, 0x9240, /*0x48-0x4f*/ + 0x9241, 0xc6cb, 0xb0c7, 0xb4f2, 0xc8d3, 0x9242, 0x9243, 0x9244, /*0x50-0x57*/ + 0xcdd0, 0x9245, 0x9246, 0xbfb8, 0x9247, 0x9248, 0x9249, 0x924a, /*0x58-0x5f*/ + 0x924b, 0x924c, 0x924d, 0xbfdb, 0x924e, 0x924f, 0xc7a4, 0xd6b4, /*0x60-0x67*/ + 0x9250, 0xc0a9, 0xded1, 0xc9a8, 0xd1ef, 0xc5a4, 0xb0e7, 0xb3b6, /*0x68-0x6f*/ + 0xc8c5, 0x9251, 0x9252, 0xb0e2, 0x9253, 0x9254, 0xb7f6, 0x9255, /*0x70-0x77*/ + 0x9256, 0xc5fa, 0x9257, 0x9258, 0xb6f3, 0x9259, 0xd5d2, 0xb3d0, /*0x78-0x7f*/ + 0xbcbc, 0x925a, 0x925b, 0x925c, 0xb3ad, 0x925d, 0x925e, 0x925f, /*0x80-0x87*/ + 0x9260, 0xbef1, 0xb0d1, 0x9261, 0x9262, 0x9263, 0x9264, 0x9265, /*0x88-0x8f*/ + 0x9266, 0xd2d6, 0xcae3, 0xd7a5, 0x9267, 0xcdb6, 0xb6b6, 0xbfb9, /*0x90-0x97*/ + 0xd5db, 0x9268, 0xb8a7, 0xc5d7, 0x9269, 0x926a, 0x926b, 0xded2, /*0x98-0x9f*/ + 0xbfd9, 0xc2d5, 0xc7c0, 0x926c, 0xbba4, 0xb1a8, 0x926d, 0x926e, /*0xa0-0xa7*/ + 0xc5ea, 0x926f, 0x9270, 0xc5fb, 0xcca7, 0x9271, 0x9272, 0x9273, /*0xa8-0xaf*/ + 0x9274, 0xb1a7, 0x9275, 0x9276, 0x9277, 0xb5d6, 0x9278, 0x9279, /*0xb0-0xb7*/ + 0x927a, 0xc4a8, 0x927b, 0xded3, 0xd1ba, 0xb3e9, 0x927c, 0xc3f2, /*0xb8-0xbf*/ + 0x927d, 0x927e, 0xb7f7, 0x9280, 0xd6f4, 0xb5a3, 0xb2f0, 0xc4b4, /*0xc0-0xc7*/ + 0xc4e9, 0xc0ad, 0xded4, 0x9281, 0xb0e8, 0xc5c4, 0xc1e0, 0x9282, /*0xc8-0xcf*/ + 0xb9d5, 0x9283, 0xbedc, 0xcdd8, 0xb0ce, 0x9284, 0xcdcf, 0xded6, /*0xd0-0xd7*/ + 0xbed0, 0xd7be, 0xded5, 0xd5d0, 0xb0dd, 0x9285, 0x9286, 0xc4e2, /*0xd8-0xdf*/ + 0x9287, 0x9288, 0xc2a3, 0xbcf0, 0x9289, 0xd3b5, 0xc0b9, 0xc5a1, /*0xe0-0xe7*/ + 0xb2a6, 0xd4f1, 0x928a, 0x928b, 0xc0a8, 0xcac3, 0xded7, 0xd5fc, /*0xe8-0xef*/ + 0x928c, 0xb9b0, 0x928d, 0xc8ad, 0xcba9, 0x928e, 0xded9, 0xbfbd, /*0xf0-0xf7*/ + 0x928f, 0x9290, 0x9291, 0x9292, 0xc6b4, 0xd7a7, 0xcab0, 0xc4c3, /*0xf8-0xff*/ + /* 0x6300 */ + 0x9293, 0xb3d6, 0xb9d2, 0x9294, 0x9295, 0x9296, 0x9297, 0xd6b8, /*0x00-0x07*/ + 0xeafc, 0xb0b4, 0x9298, 0x9299, 0x929a, 0x929b, 0xbfe6, 0x929c, /*0x08-0x0f*/ + 0x929d, 0xccf4, 0x929e, 0x929f, 0x92a0, 0x92a1, 0xcdda, 0x92a2, /*0x10-0x17*/ + 0x92a3, 0x92a4, 0xd6bf, 0xc2ce, 0x92a5, 0xcece, 0xcca2, 0xd0ae, /*0x18-0x1f*/ + 0xc4d3, 0xb5b2, 0xded8, 0xd5f5, 0xbcb7, 0xbbd3, 0x92a6, 0x92a7, /*0x20-0x27*/ + 0xb0a4, 0x92a8, 0xc5b2, 0xb4ec, 0x92a9, 0x92aa, 0x92ab, 0xd5f1, /*0x28-0x2f*/ + 0x92ac, 0x92ad, 0xeafd, 0x92ae, 0x92af, 0x92b0, 0x92b1, 0x92b2, /*0x30-0x37*/ + 0x92b3, 0xdeda, 0xcda6, 0x92b4, 0x92b5, 0xcdec, 0x92b6, 0x92b7, /*0x38-0x3f*/ + 0x92b8, 0x92b9, 0xcee6, 0xdedc, 0x92ba, 0xcdb1, 0xc0a6, 0x92bb, /*0x40-0x47*/ + 0x92bc, 0xd7bd, 0x92bd, 0xdedb, 0xb0c6, 0xbab4, 0xc9d3, 0xc4f3, /*0x48-0x4f*/ + 0xbee8, 0x92be, 0x92bf, 0x92c0, 0x92c1, 0xb2b6, 0x92c2, 0x92c3, /*0x50-0x57*/ + 0x92c4, 0x92c5, 0x92c6, 0x92c7, 0x92c8, 0x92c9, 0xc0cc, 0xcbf0, /*0x58-0x5f*/ + 0x92ca, 0xbcf1, 0xbbbb, 0xb5b7, 0x92cb, 0x92cc, 0x92cd, 0xc5f5, /*0x60-0x67*/ + 0x92ce, 0xdee6, 0x92cf, 0x92d0, 0x92d1, 0xdee3, 0xbedd, 0x92d2, /*0x68-0x6f*/ + 0x92d3, 0xdedf, 0x92d4, 0x92d5, 0x92d6, 0x92d7, 0xb4b7, 0xbddd, /*0x70-0x77*/ + 0x92d8, 0x92d9, 0xdee0, 0xc4ed, 0x92da, 0x92db, 0x92dc, 0x92dd, /*0x78-0x7f*/ + 0xcfc6, 0x92de, 0xb5e0, 0x92df, 0x92e0, 0x92e1, 0x92e2, 0xb6de, /*0x80-0x87*/ + 0xcada, 0xb5f4, 0xdee5, 0x92e3, 0xd5c6, 0x92e4, 0xdee1, 0xcccd, /*0x88-0x8f*/ + 0xc6fe, 0x92e5, 0xc5c5, 0x92e6, 0x92e7, 0x92e8, 0xd2b4, 0x92e9, /*0x90-0x97*/ + 0xbef2, 0x92ea, 0x92eb, 0x92ec, 0x92ed, 0x92ee, 0x92ef, 0x92f0, /*0x98-0x9f*/ + 0xc2d3, 0x92f1, 0xccbd, 0xb3b8, 0x92f2, 0xbdd3, 0x92f3, 0xbfd8, /*0xa0-0xa7*/ + 0xcdc6, 0xd1da, 0xb4eb, 0x92f4, 0xdee4, 0xdedd, 0xdee7, 0x92f5, /*0xa8-0xaf*/ + 0xeafe, 0x92f6, 0x92f7, 0xc2b0, 0xdee2, 0x92f8, 0x92f9, 0xd6c0, /*0xb0-0xb7*/ + 0xb5a7, 0x92fa, 0xb2f4, 0x92fb, 0xdee8, 0x92fc, 0xdef2, 0x92fd, /*0xb8-0xbf*/ + 0x92fe, 0x9340, 0x9341, 0x9342, 0xdeed, 0x9343, 0xdef1, 0x9344, /*0xc0-0xc7*/ + 0x9345, 0xc8e0, 0x9346, 0x9347, 0x9348, 0xd7e1, 0xdeef, 0xc3e8, /*0xc8-0xcf*/ + 0xcce1, 0x9349, 0xb2e5, 0x934a, 0x934b, 0x934c, 0xd2be, 0x934d, /*0xd0-0xd7*/ + 0x934e, 0x934f, 0x9350, 0x9351, 0x9352, 0x9353, 0xdeee, 0x9354, /*0xd8-0xdf*/ + 0xdeeb, 0xced5, 0x9355, 0xb4a7, 0x9356, 0x9357, 0x9358, 0x9359, /*0xe0-0xe7*/ + 0x935a, 0xbfab, 0xbebe, 0x935b, 0x935c, 0xbdd2, 0x935d, 0x935e, /*0xe8-0xef*/ + 0x935f, 0x9360, 0xdee9, 0x9361, 0xd4ae, 0x9362, 0xdede, 0x9363, /*0xf0-0xf7*/ + 0xdeea, 0x9364, 0x9365, 0x9366, 0x9367, 0xc0bf, 0x9368, 0xdeec, /*0xf8-0xff*/ + /* 0x6400 */ + 0xb2f3, 0xb8e9, 0xc2a7, 0x9369, 0x936a, 0xbdc1, 0x936b, 0x936c, /*0x00-0x07*/ + 0x936d, 0x936e, 0x936f, 0xdef5, 0xdef8, 0x9370, 0x9371, 0xb2ab, /*0x08-0x0f*/ + 0xb4a4, 0x9372, 0x9373, 0xb4ea, 0xc9a6, 0x9374, 0x9375, 0x9376, /*0x10-0x17*/ + 0x9377, 0x9378, 0x9379, 0xdef6, 0xcbd1, 0x937a, 0xb8e3, 0x937b, /*0x18-0x1f*/ + 0xdef7, 0xdefa, 0x937c, 0x937d, 0x937e, 0x9380, 0xdef9, 0x9381, /*0x20-0x27*/ + 0x9382, 0x9383, 0xccc2, 0x9384, 0xb0e1, 0xb4ee, 0x9385, 0x9386, /*0x28-0x2f*/ + 0x9387, 0x9388, 0x9389, 0x938a, 0xe5ba, 0x938b, 0x938c, 0x938d, /*0x30-0x37*/ + 0x938e, 0x938f, 0xd0af, 0x9390, 0x9391, 0xb2eb, 0x9392, 0xeba1, /*0x38-0x3f*/ + 0x9393, 0xdef4, 0x9394, 0x9395, 0xc9e3, 0xdef3, 0xb0da, 0xd2a1, /*0x40-0x47*/ + 0xb1f7, 0x9396, 0xccaf, 0x9397, 0x9398, 0x9399, 0x939a, 0x939b, /*0x48-0x4f*/ + 0x939c, 0x939d, 0xdef0, 0x939e, 0xcba4, 0x939f, 0x93a0, 0x93a1, /*0x50-0x57*/ + 0xd5aa, 0x93a2, 0x93a3, 0x93a4, 0x93a5, 0x93a6, 0xdefb, 0x93a7, /*0x58-0x5f*/ + 0x93a8, 0x93a9, 0x93aa, 0x93ab, 0x93ac, 0x93ad, 0x93ae, 0xb4dd, /*0x60-0x67*/ + 0x93af, 0xc4a6, 0x93b0, 0x93b1, 0x93b2, 0xdefd, 0x93b3, 0x93b4, /*0x68-0x6f*/ + 0x93b5, 0x93b6, 0x93b7, 0x93b8, 0x93b9, 0x93ba, 0x93bb, 0x93bc, /*0x70-0x77*/ + 0xc3fe, 0xc4a1, 0xdfa1, 0x93bd, 0x93be, 0x93bf, 0x93c0, 0x93c1, /*0x78-0x7f*/ + 0x93c2, 0x93c3, 0xc1cc, 0x93c4, 0xdefc, 0xbeef, 0x93c5, 0xc6b2, /*0x80-0x87*/ + 0x93c6, 0x93c7, 0x93c8, 0x93c9, 0x93ca, 0x93cb, 0x93cc, 0x93cd, /*0x88-0x8f*/ + 0x93ce, 0xb3c5, 0xc8f6, 0x93cf, 0x93d0, 0xcbba, 0xdefe, 0x93d1, /*0x90-0x97*/ + 0x93d2, 0xdfa4, 0x93d3, 0x93d4, 0x93d5, 0x93d6, 0xd7b2, 0x93d7, /*0x98-0x9f*/ + 0x93d8, 0x93d9, 0x93da, 0x93db, 0xb3b7, 0x93dc, 0x93dd, 0x93de, /*0xa0-0xa7*/ + 0x93df, 0xc1c3, 0x93e0, 0x93e1, 0xc7cb, 0xb2a5, 0xb4e9, 0x93e2, /*0xa8-0xaf*/ + 0xd7ab, 0x93e3, 0x93e4, 0x93e5, 0x93e6, 0xc4ec, 0x93e7, 0xdfa2, /*0xb0-0xb7*/ + 0xdfa3, 0x93e8, 0xdfa5, 0x93e9, 0xbab3, 0x93ea, 0x93eb, 0x93ec, /*0xb8-0xbf*/ + 0xdfa6, 0x93ed, 0xc0de, 0x93ee, 0x93ef, 0xc9c3, 0x93f0, 0x93f1, /*0xc0-0xc7*/ + 0x93f2, 0x93f3, 0x93f4, 0x93f5, 0x93f6, 0xb2d9, 0xc7e6, 0x93f7, /*0xc8-0xcf*/ + 0xdfa7, 0x93f8, 0xc7dc, 0x93f9, 0x93fa, 0x93fb, 0x93fc, 0xdfa8, /*0xd0-0xd7*/ + 0xeba2, 0x93fd, 0x93fe, 0x9440, 0x9441, 0x9442, 0xcbd3, 0x9443, /*0xd8-0xdf*/ + 0x9444, 0x9445, 0xdfaa, 0x9446, 0xdfa9, 0x9447, 0xb2c1, 0x9448, /*0xe0-0xe7*/ + 0x9449, 0x944a, 0x944b, 0x944c, 0x944d, 0x944e, 0x944f, 0x9450, /*0xe8-0xef*/ + 0x9451, 0x9452, 0x9453, 0x9454, 0x9455, 0x9456, 0x9457, 0x9458, /*0xf0-0xf7*/ + 0x9459, 0x945a, 0x945b, 0x945c, 0x945d, 0x945e, 0x945f, 0x9460, /*0xf8-0xff*/ + /* 0x6500 */ + 0xc5ca, 0x9461, 0x9462, 0x9463, 0x9464, 0x9465, 0x9466, 0x9467, /*0x00-0x07*/ + 0x9468, 0xdfab, 0x9469, 0x946a, 0x946b, 0x946c, 0x946d, 0x946e, /*0x08-0x0f*/ + 0x946f, 0x9470, 0xd4dc, 0x9471, 0x9472, 0x9473, 0x9474, 0x9475, /*0x10-0x17*/ + 0xc8c1, 0x9476, 0x9477, 0x9478, 0x9479, 0x947a, 0x947b, 0x947c, /*0x18-0x1f*/ + 0x947d, 0x947e, 0x9480, 0x9481, 0x9482, 0xdfac, 0x9483, 0x9484, /*0x20-0x27*/ + 0x9485, 0x9486, 0x9487, 0xbef0, 0x9488, 0x9489, 0xdfad, 0xd6a7, /*0x28-0x2f*/ + 0x948a, 0x948b, 0x948c, 0x948d, 0xeab7, 0xebb6, 0xcad5, 0x948e, /*0x30-0x37*/ + 0xd8fc, 0xb8c4, 0x948f, 0xb9a5, 0x9490, 0x9491, 0xb7c5, 0xd5fe, /*0x38-0x3f*/ + 0x9492, 0x9493, 0x9494, 0x9495, 0x9496, 0xb9ca, 0x9497, 0x9498, /*0x40-0x47*/ + 0xd0a7, 0xf4cd, 0x9499, 0x949a, 0xb5d0, 0x949b, 0x949c, 0xc3f4, /*0x48-0x4f*/ + 0x949d, 0xbec8, 0x949e, 0x949f, 0x94a0, 0xebb7, 0xb0bd, 0x94a1, /*0x50-0x57*/ + 0x94a2, 0xbdcc, 0x94a3, 0xc1b2, 0x94a4, 0xb1d6, 0xb3a8, 0x94a5, /*0x58-0x5f*/ + 0x94a6, 0x94a7, 0xb8d2, 0xc9a2, 0x94a8, 0x94a9, 0xb6d8, 0x94aa, /*0x60-0x67*/ + 0x94ab, 0x94ac, 0x94ad, 0xebb8, 0xbeb4, 0x94ae, 0x94af, 0x94b0, /*0x68-0x6f*/ + 0xcafd, 0x94b1, 0xc7c3, 0x94b2, 0xd5fb, 0x94b3, 0x94b4, 0xb7f3, /*0x70-0x77*/ + 0x94b5, 0x94b6, 0x94b7, 0x94b8, 0x94b9, 0x94ba, 0x94bb, 0x94bc, /*0x78-0x7f*/ + 0x94bd, 0x94be, 0x94bf, 0x94c0, 0x94c1, 0x94c2, 0x94c3, 0xcec4, /*0x80-0x87*/ + 0x94c4, 0x94c5, 0x94c6, 0xd5ab, 0xb1f3, 0x94c7, 0x94c8, 0x94c9, /*0x88-0x8f*/ + 0xecb3, 0xb0df, 0x94ca, 0xecb5, 0x94cb, 0x94cc, 0x94cd, 0xb6b7, /*0x90-0x97*/ + 0x94ce, 0xc1cf, 0x94cf, 0xf5fa, 0xd0b1, 0x94d0, 0x94d1, 0xd5e5, /*0x98-0x9f*/ + 0x94d2, 0xced3, 0x94d3, 0x94d4, 0xbdef, 0xb3e2, 0x94d5, 0xb8ab, /*0xa0-0xa7*/ + 0x94d6, 0xd5b6, 0x94d7, 0xedbd, 0x94d8, 0xb6cf, 0x94d9, 0xcbb9, /*0xa8-0xaf*/ + 0xd0c2, 0x94da, 0x94db, 0x94dc, 0x94dd, 0x94de, 0x94df, 0x94e0, /*0xb0-0xb7*/ + 0x94e1, 0xb7bd, 0x94e2, 0x94e3, 0xecb6, 0xcaa9, 0x94e4, 0x94e5, /*0xb8-0xbf*/ + 0x94e6, 0xc5d4, 0x94e7, 0xecb9, 0xecb8, 0xc2c3, 0xecb7, 0x94e8, /*0xc0-0xc7*/ + 0x94e9, 0x94ea, 0x94eb, 0xd0fd, 0xecba, 0x94ec, 0xecbb, 0xd7e5, /*0xc8-0xcf*/ + 0x94ed, 0x94ee, 0xecbc, 0x94ef, 0x94f0, 0x94f1, 0xecbd, 0xc6ec, /*0xd0-0xd7*/ + 0x94f2, 0x94f3, 0x94f4, 0x94f5, 0x94f6, 0x94f7, 0x94f8, 0x94f9, /*0xd8-0xdf*/ + 0xcede, 0x94fa, 0xbcc8, 0x94fb, 0x94fc, 0xc8d5, 0xb5a9, 0xbec9, /*0xe0-0xe7*/ + 0xd6bc, 0xd4e7, 0x94fd, 0x94fe, 0xd1ae, 0xd0f1, 0xeab8, 0xeab9, /*0xe8-0xef*/ + 0xeaba, 0xbab5, 0x9540, 0x9541, 0x9542, 0x9543, 0xcab1, 0xbff5, /*0xf0-0xf7*/ + 0x9544, 0x9545, 0xcdfa, 0x9546, 0x9547, 0x9548, 0x9549, 0x954a, /*0xf8-0xff*/ + /* 0x6600 */ + 0xeac0, 0x954b, 0xb0ba, 0xeabe, 0x954c, 0x954d, 0xc0a5, 0x954e, /*0x00-0x07*/ + 0x954f, 0x9550, 0xeabb, 0x9551, 0xb2fd, 0x9552, 0xc3f7, 0xbbe8, /*0x08-0x0f*/ + 0x9553, 0x9554, 0x9555, 0xd2d7, 0xcef4, 0xeabf, 0x9556, 0x9557, /*0x10-0x17*/ + 0x9558, 0xeabc, 0x9559, 0x955a, 0x955b, 0xeac3, 0x955c, 0xd0c7, /*0x18-0x1f*/ + 0xd3b3, 0x955d, 0x955e, 0x955f, 0x9560, 0xb4ba, 0x9561, 0xc3c1, /*0x20-0x27*/ + 0xd7f2, 0x9562, 0x9563, 0x9564, 0x9565, 0xd5d1, 0x9566, 0xcac7, /*0x28-0x2f*/ + 0x9567, 0xeac5, 0x9568, 0x9569, 0xeac4, 0xeac7, 0xeac6, 0x956a, /*0x30-0x37*/ + 0x956b, 0x956c, 0x956d, 0x956e, 0xd6e7, 0x956f, 0xcfd4, 0x9570, /*0x38-0x3f*/ + 0x9571, 0xeacb, 0x9572, 0xbbce, 0x9573, 0x9574, 0x9575, 0x9576, /*0x40-0x47*/ + 0x9577, 0x9578, 0x9579, 0xbdfa, 0xc9ce, 0x957a, 0x957b, 0xeacc, /*0x48-0x4f*/ + 0x957c, 0x957d, 0xc9b9, 0xcffe, 0xeaca, 0xd4ce, 0xeacd, 0xeacf, /*0x50-0x57*/ + 0x957e, 0x9580, 0xcded, 0x9581, 0x9582, 0x9583, 0x9584, 0xeac9, /*0x58-0x5f*/ + 0x9585, 0xeace, 0x9586, 0x9587, 0xceee, 0x9588, 0xbbde, 0x9589, /*0x60-0x67*/ + 0xb3bf, 0x958a, 0x958b, 0x958c, 0x958d, 0x958e, 0xc6d5, 0xbeb0, /*0x68-0x6f*/ + 0xcefa, 0x958f, 0x9590, 0x9591, 0xc7e7, 0x9592, 0xbea7, 0xead0, /*0x70-0x77*/ + 0x9593, 0x9594, 0xd6c7, 0x9595, 0x9596, 0x9597, 0xc1c0, 0x9598, /*0x78-0x7f*/ + 0x9599, 0x959a, 0xd4dd, 0x959b, 0xead1, 0x959c, 0x959d, 0xcfbe, /*0x80-0x87*/ + 0x959e, 0x959f, 0x95a0, 0x95a1, 0xead2, 0x95a2, 0x95a3, 0x95a4, /*0x88-0x8f*/ + 0x95a5, 0xcaee, 0x95a6, 0x95a7, 0x95a8, 0x95a9, 0xc5af, 0xb0b5, /*0x90-0x97*/ + 0x95aa, 0x95ab, 0x95ac, 0x95ad, 0x95ae, 0xead4, 0x95af, 0x95b0, /*0x98-0x9f*/ + 0x95b1, 0x95b2, 0x95b3, 0x95b4, 0x95b5, 0x95b6, 0x95b7, 0xead3, /*0xa0-0xa7*/ + 0xf4df, 0x95b8, 0x95b9, 0x95ba, 0x95bb, 0x95bc, 0xc4ba, 0x95bd, /*0xa8-0xaf*/ + 0x95be, 0x95bf, 0x95c0, 0x95c1, 0xb1a9, 0x95c2, 0x95c3, 0x95c4, /*0xb0-0xb7*/ + 0x95c5, 0xe5df, 0x95c6, 0x95c7, 0x95c8, 0x95c9, 0xead5, 0x95ca, /*0xb8-0xbf*/ + 0x95cb, 0x95cc, 0x95cd, 0x95ce, 0x95cf, 0x95d0, 0x95d1, 0x95d2, /*0xc0-0xc7*/ + 0x95d3, 0x95d4, 0x95d5, 0x95d6, 0x95d7, 0x95d8, 0x95d9, 0x95da, /*0xc8-0xcf*/ + 0x95db, 0x95dc, 0x95dd, 0x95de, 0x95df, 0x95e0, 0x95e1, 0x95e2, /*0xd0-0xd7*/ + 0x95e3, 0xcaef, 0x95e4, 0xead6, 0xead7, 0xc6d8, 0x95e5, 0x95e6, /*0xd8-0xdf*/ + 0x95e7, 0x95e8, 0x95e9, 0x95ea, 0x95eb, 0x95ec, 0xead8, 0x95ed, /*0xe0-0xe7*/ + 0x95ee, 0xead9, 0x95ef, 0x95f0, 0x95f1, 0x95f2, 0x95f3, 0x95f4, /*0xe8-0xef*/ + 0xd4bb, 0x95f5, 0xc7fa, 0xd2b7, 0xb8fc, 0x95f6, 0x95f7, 0xeac2, /*0xf0-0xf7*/ + 0x95f8, 0xb2dc, 0x95f9, 0x95fa, 0xc2fc, 0x95fb, 0xd4f8, 0xcce6, /*0xf8-0xff*/ + /* 0x6700 */ + 0xd7ee, 0x95fc, 0x95fd, 0x95fe, 0x9640, 0x9641, 0x9642, 0x9643, /*0x00-0x07*/ + 0xd4c2, 0xd3d0, 0xebc3, 0xc5f3, 0x9644, 0xb7fe, 0x9645, 0x9646, /*0x08-0x0f*/ + 0xebd4, 0x9647, 0x9648, 0x9649, 0xcbb7, 0xebde, 0x964a, 0xc0ca, /*0x10-0x17*/ + 0x964b, 0x964c, 0x964d, 0xcdfb, 0x964e, 0xb3af, 0x964f, 0xc6da, /*0x18-0x1f*/ + 0x9650, 0x9651, 0x9652, 0x9653, 0x9654, 0x9655, 0xebfc, 0x9656, /*0x20-0x27*/ + 0xc4be, 0x9657, 0xceb4, 0xc4a9, 0xb1be, 0xd4fd, 0x9658, 0xcaf5, /*0x28-0x2f*/ + 0x9659, 0xd6ec, 0x965a, 0x965b, 0xc6d3, 0xb6e4, 0x965c, 0x965d, /*0x30-0x37*/ + 0x965e, 0x965f, 0xbbfa, 0x9660, 0x9661, 0xd0e0, 0x9662, 0x9663, /*0x38-0x3f*/ + 0xc9b1, 0x9664, 0xd4d3, 0xc8a8, 0x9665, 0x9666, 0xb8cb, 0x9667, /*0x40-0x47*/ + 0xe8be, 0xc9bc, 0x9668, 0x9669, 0xe8bb, 0x966a, 0xc0ee, 0xd0d3, /*0x48-0x4f*/ + 0xb2c4, 0xb4e5, 0x966b, 0xe8bc, 0x966c, 0x966d, 0xd5c8, 0x966e, /*0x50-0x57*/ + 0x966f, 0x9670, 0x9671, 0x9672, 0xb6c5, 0x9673, 0xe8bd, 0xcaf8, /*0x58-0x5f*/ + 0xb8dc, 0xccf5, 0x9674, 0x9675, 0x9676, 0xc0b4, 0x9677, 0x9678, /*0x60-0x67*/ + 0xd1ee, 0xe8bf, 0xe8c2, 0x9679, 0x967a, 0xbabc, 0x967b, 0xb1ad, /*0x68-0x6f*/ + 0xbddc, 0x967c, 0xeabd, 0xe8c3, 0x967d, 0xe8c6, 0x967e, 0xe8cb, /*0x70-0x77*/ + 0x9680, 0x9681, 0x9682, 0x9683, 0xe8cc, 0x9684, 0xcbc9, 0xb0e5, /*0x78-0x7f*/ + 0x9685, 0xbcab, 0x9686, 0x9687, 0xb9b9, 0x9688, 0x9689, 0xe8c1, /*0x80-0x87*/ + 0x968a, 0xcdf7, 0x968b, 0xe8ca, 0x968c, 0x968d, 0x968e, 0x968f, /*0x88-0x8f*/ + 0xcef6, 0x9690, 0x9691, 0x9692, 0x9693, 0xd5ed, 0x9694, 0xc1d6, /*0x90-0x97*/ + 0xe8c4, 0x9695, 0xc3b6, 0x9696, 0xb9fb, 0xd6a6, 0xe8c8, 0x9697, /*0x98-0x9f*/ + 0x9698, 0x9699, 0xcae0, 0xd4e6, 0x969a, 0xe8c0, 0x969b, 0xe8c5, /*0xa0-0xa7*/ + 0xe8c7, 0x969c, 0xc7b9, 0xb7e3, 0x969d, 0xe8c9, 0x969e, 0xbfdd, /*0xa8-0xaf*/ + 0xe8d2, 0x969f, 0x96a0, 0xe8d7, 0x96a1, 0xe8d5, 0xbcdc, 0xbccf, /*0xb0-0xb7*/ + 0xe8db, 0x96a2, 0x96a3, 0x96a4, 0x96a5, 0x96a6, 0x96a7, 0x96a8, /*0xb8-0xbf*/ + 0x96a9, 0xe8de, 0x96aa, 0xe8da, 0xb1fa, 0x96ab, 0x96ac, 0x96ad, /*0xc0-0xc7*/ + 0x96ae, 0x96af, 0x96b0, 0x96b1, 0x96b2, 0x96b3, 0x96b4, 0xb0d8, /*0xc8-0xcf*/ + 0xc4b3, 0xb8cc, 0xc6e2, 0xc8be, 0xc8e1, 0x96b5, 0x96b6, 0x96b7, /*0xd0-0xd7*/ + 0xe8cf, 0xe8d4, 0xe8d6, 0x96b8, 0xb9f1, 0xe8d8, 0xd7f5, 0x96b9, /*0xd8-0xdf*/ + 0xc4fb, 0x96ba, 0xe8dc, 0x96bb, 0x96bc, 0xb2e9, 0x96bd, 0x96be, /*0xe0-0xe7*/ + 0x96bf, 0xe8d1, 0x96c0, 0x96c1, 0xbced, 0x96c2, 0x96c3, 0xbfc2, /*0xe8-0xef*/ + 0xe8cd, 0xd6f9, 0x96c4, 0xc1f8, 0xb2f1, 0x96c5, 0x96c6, 0x96c7, /*0xf0-0xf7*/ + 0x96c8, 0x96c9, 0x96ca, 0x96cb, 0x96cc, 0xe8df, 0x96cd, 0xcac1, /*0xf8-0xff*/ + /* 0x6800 */ + 0xe8d9, 0x96ce, 0x96cf, 0x96d0, 0x96d1, 0xd5a4, 0x96d2, 0xb1ea, /*0x00-0x07*/ + 0xd5bb, 0xe8ce, 0xe8d0, 0xb6b0, 0xe8d3, 0x96d3, 0xe8dd, 0xc0b8, /*0x08-0x0f*/ + 0x96d4, 0xcaf7, 0x96d5, 0xcba8, 0x96d6, 0x96d7, 0xc6dc, 0xc0f5, /*0x10-0x17*/ + 0x96d8, 0x96d9, 0x96da, 0x96db, 0x96dc, 0xe8e9, 0x96dd, 0x96de, /*0x18-0x1f*/ + 0x96df, 0xd0a3, 0x96e0, 0x96e1, 0x96e2, 0x96e3, 0x96e4, 0x96e5, /*0x20-0x27*/ + 0x96e6, 0xe8f2, 0xd6ea, 0x96e7, 0x96e8, 0x96e9, 0x96ea, 0x96eb, /*0x28-0x2f*/ + 0x96ec, 0x96ed, 0xe8e0, 0xe8e1, 0x96ee, 0x96ef, 0x96f0, 0xd1f9, /*0x30-0x37*/ + 0xbacb, 0xb8f9, 0x96f1, 0x96f2, 0xb8f1, 0xd4d4, 0xe8ef, 0x96f3, /*0x38-0x3f*/ + 0xe8ee, 0xe8ec, 0xb9f0, 0xccd2, 0xe8e6, 0xcea6, 0xbff2, 0x96f4, /*0x40-0x47*/ + 0xb0b8, 0xe8f1, 0xe8f0, 0x96f5, 0xd7c0, 0x96f6, 0xe8e4, 0x96f7, /*0x48-0x4f*/ + 0xcda9, 0xc9a3, 0x96f8, 0xbbb8, 0xbddb, 0xe8ea, 0x96f9, 0x96fa, /*0x50-0x57*/ + 0x96fb, 0x96fc, 0x96fd, 0x96fe, 0x9740, 0x9741, 0x9742, 0x9743, /*0x58-0x5f*/ + 0xe8e2, 0xe8e3, 0xe8e5, 0xb5b5, 0xe8e7, 0xc7c5, 0xe8eb, 0xe8ed, /*0x60-0x67*/ + 0xbdb0, 0xd7ae, 0x9744, 0xe8f8, 0x9745, 0x9746, 0x9747, 0x9748, /*0x68-0x6f*/ + 0x9749, 0x974a, 0x974b, 0x974c, 0xe8f5, 0x974d, 0xcdb0, 0xe8f6, /*0x70-0x77*/ + 0x974e, 0x974f, 0x9750, 0x9751, 0x9752, 0x9753, 0x9754, 0x9755, /*0x78-0x7f*/ + 0x9756, 0xc1ba, 0x9757, 0xe8e8, 0x9758, 0xc3b7, 0xb0f0, 0x9759, /*0x80-0x87*/ + 0x975a, 0x975b, 0x975c, 0x975d, 0x975e, 0x975f, 0x9760, 0xe8f4, /*0x88-0x8f*/ + 0x9761, 0x9762, 0x9763, 0xe8f7, 0x9764, 0x9765, 0x9766, 0xb9a3, /*0x90-0x97*/ + 0x9767, 0x9768, 0x9769, 0x976a, 0x976b, 0x976c, 0x976d, 0x976e, /*0x98-0x9f*/ + 0x976f, 0x9770, 0xc9d2, 0x9771, 0x9772, 0x9773, 0xc3ce, 0xcee0, /*0xa0-0xa7*/ + 0xc0e6, 0x9774, 0x9775, 0x9776, 0x9777, 0xcbf3, 0x9778, 0xccdd, /*0xa8-0xaf*/ + 0xd0b5, 0x9779, 0x977a, 0xcae1, 0x977b, 0xe8f3, 0x977c, 0x977d, /*0xb0-0xb7*/ + 0x977e, 0x9780, 0x9781, 0x9782, 0x9783, 0x9784, 0x9785, 0x9786, /*0xb8-0xbf*/ + 0xbcec, 0x9787, 0xe8f9, 0x9788, 0x9789, 0x978a, 0x978b, 0x978c, /*0xc0-0xc7*/ + 0x978d, 0xc3de, 0x978e, 0xc6e5, 0x978f, 0xb9f7, 0x9790, 0x9791, /*0xc8-0xcf*/ + 0x9792, 0x9793, 0xb0f4, 0x9794, 0x9795, 0xd7d8, 0x9796, 0x9797, /*0xd0-0xd7*/ + 0xbcac, 0x9798, 0xc5ef, 0x9799, 0x979a, 0x979b, 0x979c, 0x979d, /*0xd8-0xdf*/ + 0xccc4, 0x979e, 0x979f, 0xe9a6, 0x97a0, 0x97a1, 0x97a2, 0x97a3, /*0xe0-0xe7*/ + 0x97a4, 0x97a5, 0x97a6, 0x97a7, 0x97a8, 0x97a9, 0xc9ad, 0x97aa, /*0xe8-0xef*/ + 0xe9a2, 0xc0e2, 0x97ab, 0x97ac, 0x97ad, 0xbfc3, 0x97ae, 0x97af, /*0xf0-0xf7*/ + 0x97b0, 0xe8fe, 0xb9d7, 0x97b1, 0xe8fb, 0x97b2, 0x97b3, 0x97b4, /*0xf8-0xff*/ + /* 0x6900 */ + 0x97b5, 0xe9a4, 0x97b6, 0x97b7, 0x97b8, 0xd2ce, 0x97b9, 0x97ba, /*0x00-0x07*/ + 0x97bb, 0x97bc, 0x97bd, 0xe9a3, 0x97be, 0xd6b2, 0xd7b5, 0x97bf, /*0x08-0x0f*/ + 0xe9a7, 0x97c0, 0xbdb7, 0x97c1, 0x97c2, 0x97c3, 0x97c4, 0x97c5, /*0x10-0x17*/ + 0x97c6, 0x97c7, 0x97c8, 0x97c9, 0x97ca, 0x97cb, 0x97cc, 0xe8fc, /*0x18-0x1f*/ + 0xe8fd, 0x97cd, 0x97ce, 0x97cf, 0xe9a1, 0x97d0, 0x97d1, 0x97d2, /*0x20-0x27*/ + 0x97d3, 0x97d4, 0x97d5, 0x97d6, 0x97d7, 0xcdd6, 0x97d8, 0x97d9, /*0x28-0x2f*/ + 0xd2ac, 0x97da, 0x97db, 0x97dc, 0xe9b2, 0x97dd, 0x97de, 0x97df, /*0x30-0x37*/ + 0x97e0, 0xe9a9, 0x97e1, 0x97e2, 0x97e3, 0xb4aa, 0x97e4, 0xb4bb, /*0x38-0x3f*/ + 0x97e5, 0x97e6, 0xe9ab, 0x97e7, 0x97e8, 0x97e9, 0x97ea, 0x97eb, /*0x40-0x47*/ + 0x97ec, 0x97ed, 0x97ee, 0x97ef, 0x97f0, 0x97f1, 0x97f2, 0x97f3, /*0x48-0x4f*/ + 0x97f4, 0x97f5, 0x97f6, 0x97f7, 0xd0a8, 0x97f8, 0x97f9, 0xe9a5, /*0x50-0x57*/ + 0x97fa, 0x97fb, 0xb3fe, 0x97fc, 0x97fd, 0xe9ac, 0xc0e3, 0x97fe, /*0x58-0x5f*/ + 0xe9aa, 0x9840, 0x9841, 0xe9b9, 0x9842, 0x9843, 0xe9b8, 0x9844, /*0x60-0x67*/ + 0x9845, 0x9846, 0x9847, 0xe9ae, 0x9848, 0x9849, 0xe8fa, 0x984a, /*0x68-0x6f*/ + 0x984b, 0xe9a8, 0x984c, 0x984d, 0x984e, 0x984f, 0x9850, 0xbfac, /*0x70-0x77*/ + 0xe9b1, 0xe9ba, 0x9851, 0x9852, 0xc2a5, 0x9853, 0x9854, 0x9855, /*0x78-0x7f*/ + 0xe9af, 0x9856, 0xb8c5, 0x9857, 0xe9ad, 0x9858, 0xd3dc, 0xe9b4, /*0x80-0x87*/ + 0xe9b5, 0xe9b7, 0x9859, 0x985a, 0x985b, 0xe9c7, 0x985c, 0x985d, /*0x88-0x8f*/ + 0x985e, 0x985f, 0x9860, 0x9861, 0xc0c6, 0xe9c5, 0x9862, 0x9863, /*0x90-0x97*/ + 0xe9b0, 0x9864, 0x9865, 0xe9bb, 0xb0f1, 0x9866, 0x9867, 0x9868, /*0x98-0x9f*/ + 0x9869, 0x986a, 0x986b, 0x986c, 0x986d, 0x986e, 0x986f, 0xe9bc, /*0xa0-0xa7*/ + 0xd5a5, 0x9870, 0x9871, 0xe9be, 0x9872, 0xe9bf, 0x9873, 0x9874, /*0xa8-0xaf*/ + 0x9875, 0xe9c1, 0x9876, 0x9877, 0xc1f1, 0x9878, 0x9879, 0xc8b6, /*0xb0-0xb7*/ + 0x987a, 0x987b, 0x987c, 0xe9bd, 0x987d, 0x987e, 0x9880, 0x9881, /*0xb8-0xbf*/ + 0x9882, 0xe9c2, 0x9883, 0x9884, 0x9885, 0x9886, 0x9887, 0x9888, /*0xc0-0xc7*/ + 0x9889, 0x988a, 0xe9c3, 0x988b, 0xe9b3, 0x988c, 0xe9b6, 0x988d, /*0xc8-0xcf*/ + 0xbbb1, 0x988e, 0x988f, 0x9890, 0xe9c0, 0x9891, 0x9892, 0x9893, /*0xd0-0xd7*/ + 0x9894, 0x9895, 0x9896, 0xbcf7, 0x9897, 0x9898, 0x9899, 0xe9c4, /*0xd8-0xdf*/ + 0xe9c6, 0x989a, 0x989b, 0x989c, 0x989d, 0x989e, 0x989f, 0x98a0, /*0xe0-0xe7*/ + 0x98a1, 0x98a2, 0x98a3, 0x98a4, 0x98a5, 0xe9ca, 0x98a6, 0x98a7, /*0xe8-0xef*/ + 0x98a8, 0x98a9, 0xe9ce, 0x98aa, 0x98ab, 0x98ac, 0x98ad, 0x98ae, /*0xf0-0xf7*/ + 0x98af, 0x98b0, 0x98b1, 0x98b2, 0x98b3, 0xb2db, 0x98b4, 0xe9c8, /*0xf8-0xff*/ + /* 0x6a00 */ + 0x98b5, 0x98b6, 0x98b7, 0x98b8, 0x98b9, 0x98ba, 0x98bb, 0x98bc, /*0x00-0x07*/ + 0x98bd, 0x98be, 0xb7ae, 0x98bf, 0x98c0, 0x98c1, 0x98c2, 0x98c3, /*0x08-0x0f*/ + 0x98c4, 0x98c5, 0x98c6, 0x98c7, 0x98c8, 0x98c9, 0x98ca, 0xe9cb, /*0x10-0x17*/ + 0xe9cc, 0x98cb, 0x98cc, 0x98cd, 0x98ce, 0x98cf, 0x98d0, 0xd5c1, /*0x18-0x1f*/ + 0x98d1, 0xc4a3, 0x98d2, 0x98d3, 0x98d4, 0x98d5, 0x98d6, 0x98d7, /*0x20-0x27*/ + 0xe9d8, 0x98d8, 0xbae1, 0x98d9, 0x98da, 0x98db, 0x98dc, 0xe9c9, /*0x28-0x2f*/ + 0x98dd, 0xd3a3, 0x98de, 0x98df, 0x98e0, 0xe9d4, 0x98e1, 0x98e2, /*0x30-0x37*/ + 0x98e3, 0x98e4, 0x98e5, 0x98e6, 0x98e7, 0xe9d7, 0xe9d0, 0x98e8, /*0x38-0x3f*/ + 0x98e9, 0x98ea, 0x98eb, 0x98ec, 0xe9cf, 0x98ed, 0x98ee, 0xc7c1, /*0x40-0x47*/ + 0x98ef, 0x98f0, 0x98f1, 0x98f2, 0x98f3, 0x98f4, 0x98f5, 0x98f6, /*0x48-0x4f*/ + 0xe9d2, 0x98f7, 0x98f8, 0x98f9, 0x98fa, 0x98fb, 0x98fc, 0x98fd, /*0x50-0x57*/ + 0xe9d9, 0xb3c8, 0x98fe, 0xe9d3, 0x9940, 0x9941, 0x9942, 0x9943, /*0x58-0x5f*/ + 0x9944, 0xcff0, 0x9945, 0x9946, 0x9947, 0xe9cd, 0x9948, 0x9949, /*0x60-0x67*/ + 0x994a, 0x994b, 0x994c, 0x994d, 0x994e, 0x994f, 0x9950, 0x9951, /*0x68-0x6f*/ + 0x9952, 0xb3f7, 0x9953, 0x9954, 0x9955, 0x9956, 0x9957, 0x9958, /*0x70-0x77*/ + 0x9959, 0xe9d6, 0x995a, 0x995b, 0xe9da, 0x995c, 0x995d, 0x995e, /*0x78-0x7f*/ + 0xccb4, 0x995f, 0x9960, 0x9961, 0xcfad, 0x9962, 0x9963, 0x9964, /*0x80-0x87*/ + 0x9965, 0x9966, 0x9967, 0x9968, 0x9969, 0x996a, 0xe9d5, 0x996b, /*0x88-0x8f*/ + 0xe9dc, 0xe9db, 0x996c, 0x996d, 0x996e, 0x996f, 0x9970, 0xe9de, /*0x90-0x97*/ + 0x9971, 0x9972, 0x9973, 0x9974, 0x9975, 0x9976, 0x9977, 0x9978, /*0x98-0x9f*/ + 0xe9d1, 0x9979, 0x997a, 0x997b, 0x997c, 0x997d, 0x997e, 0x9980, /*0xa0-0xa7*/ + 0x9981, 0xe9dd, 0x9982, 0xe9df, 0xc3ca, 0x9983, 0x9984, 0x9985, /*0xa8-0xaf*/ + 0x9986, 0x9987, 0x9988, 0x9989, 0x998a, 0x998b, 0x998c, 0x998d, /*0xb0-0xb7*/ + 0x998e, 0x998f, 0x9990, 0x9991, 0x9992, 0x9993, 0x9994, 0x9995, /*0xb8-0xbf*/ + 0x9996, 0x9997, 0x9998, 0x9999, 0x999a, 0x999b, 0x999c, 0x999d, /*0xc0-0xc7*/ + 0x999e, 0x999f, 0x99a0, 0x99a1, 0x99a2, 0x99a3, 0x99a4, 0x99a5, /*0xc8-0xcf*/ + 0x99a6, 0x99a7, 0x99a8, 0x99a9, 0x99aa, 0x99ab, 0x99ac, 0x99ad, /*0xd0-0xd7*/ + 0x99ae, 0x99af, 0x99b0, 0x99b1, 0x99b2, 0x99b3, 0x99b4, 0x99b5, /*0xd8-0xdf*/ + 0x99b6, 0x99b7, 0x99b8, 0x99b9, 0x99ba, 0x99bb, 0x99bc, 0x99bd, /*0xe0-0xe7*/ + 0x99be, 0x99bf, 0x99c0, 0x99c1, 0x99c2, 0x99c3, 0x99c4, 0x99c5, /*0xe8-0xef*/ + 0x99c6, 0x99c7, 0x99c8, 0x99c9, 0x99ca, 0x99cb, 0x99cc, 0x99cd, /*0xf0-0xf7*/ + 0x99ce, 0x99cf, 0x99d0, 0x99d1, 0x99d2, 0x99d3, 0x99d4, 0x99d5, /*0xf8-0xff*/ + /* 0x6b00 */ + 0x99d6, 0x99d7, 0x99d8, 0x99d9, 0x99da, 0x99db, 0x99dc, 0x99dd, /*0x00-0x07*/ + 0x99de, 0x99df, 0x99e0, 0x99e1, 0x99e2, 0x99e3, 0x99e4, 0x99e5, /*0x08-0x0f*/ + 0x99e6, 0x99e7, 0x99e8, 0x99e9, 0x99ea, 0x99eb, 0x99ec, 0x99ed, /*0x10-0x17*/ + 0x99ee, 0x99ef, 0x99f0, 0x99f1, 0x99f2, 0x99f3, 0x99f4, 0x99f5, /*0x18-0x1f*/ + 0xc7b7, 0xb4ce, 0xbbb6, 0xd0c0, 0xeca3, 0x99f6, 0x99f7, 0xc5b7, /*0x20-0x27*/ + 0x99f8, 0x99f9, 0x99fa, 0x99fb, 0x99fc, 0x99fd, 0x99fe, 0x9a40, /*0x28-0x2f*/ + 0x9a41, 0x9a42, 0xd3fb, 0x9a43, 0x9a44, 0x9a45, 0x9a46, 0xeca4, /*0x30-0x37*/ + 0x9a47, 0xeca5, 0xc6db, 0x9a48, 0x9a49, 0x9a4a, 0xbfee, 0x9a4b, /*0x38-0x3f*/ + 0x9a4c, 0x9a4d, 0x9a4e, 0xeca6, 0x9a4f, 0x9a50, 0xeca7, 0xd0aa, /*0x40-0x47*/ + 0x9a51, 0xc7b8, 0x9a52, 0x9a53, 0xb8e8, 0x9a54, 0x9a55, 0x9a56, /*0x48-0x4f*/ + 0x9a57, 0x9a58, 0x9a59, 0x9a5a, 0x9a5b, 0x9a5c, 0x9a5d, 0x9a5e, /*0x50-0x57*/ + 0x9a5f, 0xeca8, 0x9a60, 0x9a61, 0x9a62, 0x9a63, 0x9a64, 0x9a65, /*0x58-0x5f*/ + 0x9a66, 0x9a67, 0xd6b9, 0xd5fd, 0xb4cb, 0xb2bd, 0xcee4, 0xc6e7, /*0x60-0x67*/ + 0x9a68, 0x9a69, 0xcde1, 0x9a6a, 0x9a6b, 0x9a6c, 0x9a6d, 0x9a6e, /*0x68-0x6f*/ + 0x9a6f, 0x9a70, 0x9a71, 0x9a72, 0x9a73, 0x9a74, 0x9a75, 0x9a76, /*0x70-0x77*/ + 0x9a77, 0xb4f5, 0x9a78, 0xcbc0, 0xbcdf, 0x9a79, 0x9a7a, 0x9a7b, /*0x78-0x7f*/ + 0x9a7c, 0xe9e2, 0xe9e3, 0xd1ea, 0xe9e5, 0x9a7d, 0xb4f9, 0xe9e4, /*0x80-0x87*/ + 0x9a7e, 0xd1b3, 0xcae2, 0xb2d0, 0x9a80, 0xe9e8, 0x9a81, 0x9a82, /*0x88-0x8f*/ + 0x9a83, 0x9a84, 0xe9e6, 0xe9e7, 0x9a85, 0x9a86, 0xd6b3, 0x9a87, /*0x90-0x97*/ + 0x9a88, 0x9a89, 0xe9e9, 0xe9ea, 0x9a8a, 0x9a8b, 0x9a8c, 0x9a8d, /*0x98-0x9f*/ + 0x9a8e, 0xe9eb, 0x9a8f, 0x9a90, 0x9a91, 0x9a92, 0x9a93, 0x9a94, /*0xa0-0xa7*/ + 0x9a95, 0x9a96, 0xe9ec, 0x9a97, 0x9a98, 0x9a99, 0x9a9a, 0x9a9b, /*0xa8-0xaf*/ + 0x9a9c, 0x9a9d, 0x9a9e, 0xecaf, 0xc5b9, 0xb6ce, 0x9a9f, 0xd2f3, /*0xb0-0xb7*/ + 0x9aa0, 0x9aa1, 0x9aa2, 0x9aa3, 0x9aa4, 0x9aa5, 0x9aa6, 0xb5ee, /*0xb8-0xbf*/ + 0x9aa7, 0xbbd9, 0xecb1, 0x9aa8, 0x9aa9, 0xd2e3, 0x9aaa, 0x9aab, /*0xc0-0xc7*/ + 0x9aac, 0x9aad, 0x9aae, 0xcee3, 0x9aaf, 0xc4b8, 0x9ab0, 0xc3bf, /*0xc8-0xcf*/ + 0x9ab1, 0x9ab2, 0xb6be, 0xd8b9, 0xb1c8, 0xb1cf, 0xb1d1, 0xc5fe, /*0xd0-0xd7*/ + 0x9ab3, 0xb1d0, 0x9ab4, 0xc3ab, 0x9ab5, 0x9ab6, 0x9ab7, 0x9ab8, /*0xd8-0xdf*/ + 0x9ab9, 0xd5b1, 0x9aba, 0x9abb, 0x9abc, 0x9abd, 0x9abe, 0x9abf, /*0xe0-0xe7*/ + 0x9ac0, 0x9ac1, 0xeba4, 0xbac1, 0x9ac2, 0x9ac3, 0x9ac4, 0xccba, /*0xe8-0xef*/ + 0x9ac5, 0x9ac6, 0x9ac7, 0xeba5, 0x9ac8, 0xeba7, 0x9ac9, 0x9aca, /*0xf0-0xf7*/ + 0x9acb, 0xeba8, 0x9acc, 0x9acd, 0x9ace, 0xeba6, 0x9acf, 0x9ad0, /*0xf8-0xff*/ + /* 0x6c00 */ + 0x9ad1, 0x9ad2, 0x9ad3, 0x9ad4, 0x9ad5, 0xeba9, 0xebab, 0xebaa, /*0x00-0x07*/ + 0x9ad6, 0x9ad7, 0x9ad8, 0x9ad9, 0x9ada, 0xebac, 0x9adb, 0xcacf, /*0x08-0x0f*/ + 0xd8b5, 0xc3f1, 0x9adc, 0xc3a5, 0xc6f8, 0xebad, 0xc4ca, 0x9add, /*0x10-0x17*/ + 0xebae, 0xebaf, 0xebb0, 0xb7d5, 0x9ade, 0x9adf, 0x9ae0, 0xb7fa, /*0x18-0x1f*/ + 0x9ae1, 0xebb1, 0xc7e2, 0x9ae2, 0xebb3, 0x9ae3, 0xbaa4, 0xd1f5, /*0x20-0x27*/ + 0xb0b1, 0xebb2, 0xebb4, 0x9ae4, 0x9ae5, 0x9ae6, 0xb5aa, 0xc2c8, /*0x28-0x2f*/ + 0xc7e8, 0x9ae7, 0xebb5, 0x9ae8, 0xcbae, 0xe3df, 0x9ae9, 0x9aea, /*0x30-0x37*/ + 0xd3c0, 0x9aeb, 0x9aec, 0x9aed, 0x9aee, 0xd9db, 0x9aef, 0x9af0, /*0x38-0x3f*/ + 0xcda1, 0xd6ad, 0xc7f3, 0x9af1, 0x9af2, 0x9af3, 0xd9e0, 0xbbe3, /*0x40-0x47*/ + 0x9af4, 0xbaba, 0xe3e2, 0x9af5, 0x9af6, 0x9af7, 0x9af8, 0x9af9, /*0x48-0x4f*/ + 0xcfab, 0x9afa, 0x9afb, 0x9afc, 0xe3e0, 0xc9c7, 0x9afd, 0xbab9, /*0x50-0x57*/ + 0x9afe, 0x9b40, 0x9b41, 0xd1b4, 0xe3e1, 0xc8ea, 0xb9af, 0xbdad, /*0x58-0x5f*/ + 0xb3d8, 0xcedb, 0x9b42, 0x9b43, 0xccc0, 0x9b44, 0x9b45, 0x9b46, /*0x60-0x67*/ + 0xe3e8, 0xe3e9, 0xcdf4, 0x9b47, 0x9b48, 0x9b49, 0x9b4a, 0x9b4b, /*0x68-0x6f*/ + 0xccad, 0x9b4c, 0xbcb3, 0x9b4d, 0xe3ea, 0x9b4e, 0xe3eb, 0x9b4f, /*0x70-0x77*/ + 0x9b50, 0xd0da, 0x9b51, 0x9b52, 0x9b53, 0xc6fb, 0xb7da, 0x9b54, /*0x78-0x7f*/ + 0x9b55, 0xc7df, 0xd2ca, 0xced6, 0x9b56, 0xe3e4, 0xe3ec, 0x9b57, /*0x80-0x87*/ + 0xc9f2, 0xb3c1, 0x9b58, 0x9b59, 0xe3e7, 0x9b5a, 0x9b5b, 0xc6e3, /*0x88-0x8f*/ + 0xe3e5, 0x9b5c, 0x9b5d, 0xedb3, 0xe3e6, 0x9b5e, 0x9b5f, 0x9b60, /*0x90-0x97*/ + 0x9b61, 0xc9b3, 0x9b62, 0xc5e6, 0x9b63, 0x9b64, 0x9b65, 0xb9b5, /*0x98-0x9f*/ + 0x9b66, 0xc3bb, 0x9b67, 0xe3e3, 0xc5bd, 0xc1a4, 0xc2d9, 0xb2d7, /*0xa0-0xa7*/ + 0x9b68, 0xe3ed, 0xbba6, 0xc4ad, 0x9b69, 0xe3f0, 0xbeda, 0x9b6a, /*0xa8-0xaf*/ + 0x9b6b, 0xe3fb, 0xe3f5, 0xbad3, 0x9b6c, 0x9b6d, 0x9b6e, 0x9b6f, /*0xb0-0xb7*/ + 0xb7d0, 0xd3cd, 0x9b70, 0xd6ce, 0xd5d3, 0xb9c1, 0xd5b4, 0xd1d8, /*0xb8-0xbf*/ + 0x9b71, 0x9b72, 0x9b73, 0x9b74, 0xd0b9, 0xc7f6, 0x9b75, 0x9b76, /*0xc0-0xc7*/ + 0x9b77, 0xc8aa, 0xb2b4, 0x9b78, 0xc3da, 0x9b79, 0x9b7a, 0x9b7b, /*0xc8-0xcf*/ + 0xe3ee, 0x9b7c, 0x9b7d, 0xe3fc, 0xe3ef, 0xb7a8, 0xe3f7, 0xe3f4, /*0xd0-0xd7*/ + 0x9b7e, 0x9b80, 0x9b81, 0xb7ba, 0x9b82, 0x9b83, 0xc5a2, 0x9b84, /*0xd8-0xdf*/ + 0xe3f6, 0xc5dd, 0xb2a8, 0xc6fc, 0x9b85, 0xc4e0, 0x9b86, 0x9b87, /*0xe0-0xe7*/ + 0xd7a2, 0x9b88, 0xc0e1, 0xe3f9, 0x9b89, 0x9b8a, 0xe3fa, 0xe3fd, /*0xe8-0xef*/ + 0xcca9, 0xe3f3, 0x9b8b, 0xd3be, 0x9b8c, 0xb1c3, 0xedb4, 0xe3f1, /*0xf0-0xf7*/ + 0xe3f2, 0x9b8d, 0xe3f8, 0xd0ba, 0xc6c3, 0xd4f3, 0xe3fe, 0x9b8e, /*0xf8-0xff*/ + /* 0x6d00 */ + 0x9b8f, 0xbde0, 0x9b90, 0x9b91, 0xe4a7, 0x9b92, 0x9b93, 0xe4a6, /*0x00-0x07*/ + 0x9b94, 0x9b95, 0x9b96, 0xd1f3, 0xe4a3, 0x9b97, 0xe4a9, 0x9b98, /*0x08-0x0f*/ + 0x9b99, 0x9b9a, 0xc8f7, 0x9b9b, 0x9b9c, 0x9b9d, 0x9b9e, 0xcfb4, /*0x10-0x17*/ + 0x9b9f, 0xe4a8, 0xe4ae, 0xc2e5, 0x9ba0, 0x9ba1, 0xb6b4, 0x9ba2, /*0x18-0x1f*/ + 0x9ba3, 0x9ba4, 0x9ba5, 0x9ba6, 0x9ba7, 0xbdf2, 0x9ba8, 0xe4a2, /*0x20-0x27*/ + 0x9ba9, 0x9baa, 0xbae9, 0xe4aa, 0x9bab, 0x9bac, 0xe4ac, 0x9bad, /*0x28-0x2f*/ + 0x9bae, 0xb6fd, 0xd6de, 0xe4b2, 0x9baf, 0xe4ad, 0x9bb0, 0x9bb1, /*0x30-0x37*/ + 0x9bb2, 0xe4a1, 0x9bb3, 0xbbee, 0xcddd, 0xc7a2, 0xc5c9, 0x9bb4, /*0x38-0x3f*/ + 0x9bb5, 0xc1f7, 0x9bb6, 0xe4a4, 0x9bb7, 0xc7b3, 0xbdac, 0xbdbd, /*0x40-0x47*/ + 0xe4a5, 0x9bb8, 0xd7c7, 0xb2e2, 0x9bb9, 0xe4ab, 0xbcc3, 0xe4af, /*0x48-0x4f*/ + 0x9bba, 0xbbeb, 0xe4b0, 0xc5a8, 0xe4b1, 0x9bbb, 0x9bbc, 0x9bbd, /*0x50-0x57*/ + 0x9bbe, 0xd5e3, 0xbfa3, 0x9bbf, 0xe4ba, 0x9bc0, 0xe4b7, 0x9bc1, /*0x58-0x5f*/ + 0xe4bb, 0x9bc2, 0x9bc3, 0xe4bd, 0x9bc4, 0x9bc5, 0xc6d6, 0x9bc6, /*0x60-0x67*/ + 0x9bc7, 0xbac6, 0xc0cb, 0x9bc8, 0x9bc9, 0x9bca, 0xb8a1, 0xe4b4, /*0x68-0x6f*/ + 0x9bcb, 0x9bcc, 0x9bcd, 0x9bce, 0xd4a1, 0x9bcf, 0x9bd0, 0xbaa3, /*0x70-0x77*/ + 0xbdfe, 0x9bd1, 0x9bd2, 0x9bd3, 0xe4bc, 0x9bd4, 0x9bd5, 0x9bd6, /*0x78-0x7f*/ + 0x9bd7, 0x9bd8, 0xcdbf, 0x9bd9, 0x9bda, 0xc4f9, 0x9bdb, 0x9bdc, /*0x80-0x87*/ + 0xcffb, 0xc9e6, 0x9bdd, 0x9bde, 0xd3bf, 0x9bdf, 0xcfd1, 0x9be0, /*0x88-0x8f*/ + 0x9be1, 0xe4b3, 0x9be2, 0xe4b8, 0xe4b9, 0xcce9, 0x9be3, 0x9be4, /*0x90-0x97*/ + 0x9be5, 0x9be6, 0x9be7, 0xccce, 0x9be8, 0xc0d4, 0xe4b5, 0xc1b0, /*0x98-0x9f*/ + 0xe4b6, 0xced0, 0x9be9, 0xbbc1, 0xb5d3, 0x9bea, 0xc8f3, 0xbda7, /*0xa0-0xa7*/ + 0xd5c7, 0xc9ac, 0xb8a2, 0xe4ca, 0x9beb, 0x9bec, 0xe4cc, 0xd1c4, /*0xa8-0xaf*/ + 0x9bed, 0x9bee, 0xd2ba, 0x9bef, 0x9bf0, 0xbaad, 0x9bf1, 0x9bf2, /*0xb0-0xb7*/ + 0xbad4, 0x9bf3, 0x9bf4, 0x9bf5, 0x9bf6, 0x9bf7, 0x9bf8, 0xe4c3, /*0xb8-0xbf*/ + 0xb5ed, 0x9bf9, 0x9bfa, 0x9bfb, 0xd7cd, 0xe4c0, 0xcffd, 0xe4bf, /*0xc0-0xc7*/ + 0x9bfc, 0x9bfd, 0x9bfe, 0xc1dc, 0xccca, 0x9c40, 0x9c41, 0x9c42, /*0xc8-0xcf*/ + 0x9c43, 0xcae7, 0x9c44, 0x9c45, 0x9c46, 0x9c47, 0xc4d7, 0x9c48, /*0xd0-0xd7*/ + 0xccd4, 0xe4c8, 0x9c49, 0x9c4a, 0x9c4b, 0xe4c7, 0xe4c1, 0x9c4c, /*0xd8-0xdf*/ + 0xe4c4, 0xb5ad, 0x9c4d, 0x9c4e, 0xd3d9, 0x9c4f, 0xe4c6, 0x9c50, /*0xe0-0xe7*/ + 0x9c51, 0x9c52, 0x9c53, 0xd2f9, 0xb4e3, 0x9c54, 0xbbb4, 0x9c55, /*0xe8-0xef*/ + 0x9c56, 0xc9ee, 0x9c57, 0xb4be, 0x9c58, 0x9c59, 0x9c5a, 0xbbec, /*0xf0-0xf7*/ + 0x9c5b, 0xd1cd, 0x9c5c, 0xcced, 0xedb5, 0x9c5d, 0x9c5e, 0x9c5f, /*0xf8-0xff*/ + /* 0x6e00 */ + 0x9c60, 0x9c61, 0x9c62, 0x9c63, 0x9c64, 0xc7e5, 0x9c65, 0x9c66, /*0x00-0x07*/ + 0x9c67, 0x9c68, 0xd4a8, 0x9c69, 0xe4cb, 0xd7d5, 0xe4c2, 0x9c6a, /*0x08-0x0f*/ + 0xbda5, 0xe4c5, 0x9c6b, 0x9c6c, 0xd3e6, 0x9c6d, 0xe4c9, 0xc9f8, /*0x10-0x17*/ + 0x9c6e, 0x9c6f, 0xe4be, 0x9c70, 0x9c71, 0xd3e5, 0x9c72, 0x9c73, /*0x18-0x1f*/ + 0xc7fe, 0xb6c9, 0x9c74, 0xd4fc, 0xb2b3, 0xe4d7, 0x9c75, 0x9c76, /*0x20-0x27*/ + 0x9c77, 0xcec2, 0x9c78, 0xe4cd, 0x9c79, 0xcebc, 0x9c7a, 0xb8db, /*0x28-0x2f*/ + 0x9c7b, 0x9c7c, 0xe4d6, 0x9c7d, 0xbfca, 0x9c7e, 0x9c80, 0x9c81, /*0x30-0x37*/ + 0xd3ce, 0x9c82, 0xc3ec, 0x9c83, 0x9c84, 0x9c85, 0x9c86, 0x9c87, /*0x38-0x3f*/ + 0x9c88, 0x9c89, 0x9c8a, 0xc5c8, 0xe4d8, 0x9c8b, 0x9c8c, 0x9c8d, /*0x40-0x47*/ + 0x9c8e, 0x9c8f, 0x9c90, 0x9c91, 0x9c92, 0xcdc4, 0xe4cf, 0x9c93, /*0x48-0x4f*/ + 0x9c94, 0x9c95, 0x9c96, 0xe4d4, 0xe4d5, 0x9c97, 0xbafe, 0x9c98, /*0x50-0x57*/ + 0xcfe6, 0x9c99, 0x9c9a, 0xd5bf, 0x9c9b, 0x9c9c, 0x9c9d, 0xe4d2, /*0x58-0x5f*/ + 0x9c9e, 0x9c9f, 0x9ca0, 0x9ca1, 0x9ca2, 0x9ca3, 0x9ca4, 0x9ca5, /*0x60-0x67*/ + 0x9ca6, 0x9ca7, 0x9ca8, 0xe4d0, 0x9ca9, 0x9caa, 0xe4ce, 0x9cab, /*0x68-0x6f*/ + 0x9cac, 0x9cad, 0x9cae, 0x9caf, 0x9cb0, 0x9cb1, 0x9cb2, 0x9cb3, /*0x70-0x77*/ + 0x9cb4, 0x9cb5, 0x9cb6, 0x9cb7, 0x9cb8, 0x9cb9, 0xcde5, 0xcaaa, /*0x78-0x7f*/ + 0x9cba, 0x9cbb, 0x9cbc, 0xc0a3, 0x9cbd, 0xbda6, 0xe4d3, 0x9cbe, /*0x80-0x87*/ + 0x9cbf, 0xb8c8, 0x9cc0, 0x9cc1, 0x9cc2, 0x9cc3, 0x9cc4, 0xe4e7, /*0x88-0x8f*/ + 0xd4b4, 0x9cc5, 0x9cc6, 0x9cc7, 0x9cc8, 0x9cc9, 0x9cca, 0x9ccb, /*0x90-0x97*/ + 0xe4db, 0x9ccc, 0x9ccd, 0x9cce, 0xc1ef, 0x9ccf, 0x9cd0, 0xe4e9, /*0x98-0x9f*/ + 0x9cd1, 0x9cd2, 0xd2e7, 0x9cd3, 0x9cd4, 0xe4df, 0x9cd5, 0xe4e0, /*0xa0-0xa7*/ + 0x9cd6, 0x9cd7, 0xcfaa, 0x9cd8, 0x9cd9, 0x9cda, 0x9cdb, 0xcbdd, /*0xa8-0xaf*/ + 0x9cdc, 0xe4da, 0xe4d1, 0x9cdd, 0xe4e5, 0x9cde, 0xc8dc, 0xe4e3, /*0xb0-0xb7*/ + 0x9cdf, 0x9ce0, 0xc4e7, 0xe4e2, 0x9ce1, 0xe4e1, 0x9ce2, 0x9ce3, /*0xb8-0xbf*/ + 0x9ce4, 0xb3fc, 0xe4e8, 0x9ce5, 0x9ce6, 0x9ce7, 0x9ce8, 0xb5e1, /*0xc0-0xc7*/ + 0x9ce9, 0x9cea, 0x9ceb, 0xd7cc, 0x9cec, 0x9ced, 0x9cee, 0xe4e6, /*0xc8-0xcf*/ + 0x9cef, 0xbbac, 0x9cf0, 0xd7d2, 0xcccf, 0xebf8, 0x9cf1, 0xe4e4, /*0xd0-0xd7*/ + 0x9cf2, 0x9cf3, 0xb9f6, 0x9cf4, 0x9cf5, 0x9cf6, 0xd6cd, 0xe4d9, /*0xd8-0xdf*/ + 0xe4dc, 0xc2fa, 0xe4de, 0x9cf7, 0xc2cb, 0xc0c4, 0xc2d0, 0x9cf8, /*0xe0-0xe7*/ + 0xb1f5, 0xccb2, 0x9cf9, 0x9cfa, 0x9cfb, 0x9cfc, 0x9cfd, 0x9cfe, /*0xe8-0xef*/ + 0x9d40, 0x9d41, 0x9d42, 0x9d43, 0xb5ce, 0x9d44, 0x9d45, 0x9d46, /*0xf0-0xf7*/ + 0x9d47, 0xe4ef, 0x9d48, 0x9d49, 0x9d4a, 0x9d4b, 0x9d4c, 0x9d4d, /*0xf8-0xff*/ + /* 0x6f00 */ + 0x9d4e, 0x9d4f, 0xc6af, 0x9d50, 0x9d51, 0x9d52, 0xc6e1, 0x9d53, /*0x00-0x07*/ + 0x9d54, 0xe4f5, 0x9d55, 0x9d56, 0x9d57, 0x9d58, 0x9d59, 0xc2a9, /*0x08-0x0f*/ + 0x9d5a, 0x9d5b, 0x9d5c, 0xc0ec, 0xd1dd, 0xe4ee, 0x9d5d, 0x9d5e, /*0x10-0x17*/ + 0x9d5f, 0x9d60, 0x9d61, 0x9d62, 0x9d63, 0x9d64, 0x9d65, 0x9d66, /*0x18-0x1f*/ + 0xc4ae, 0x9d67, 0x9d68, 0x9d69, 0xe4ed, 0x9d6a, 0x9d6b, 0x9d6c, /*0x20-0x27*/ + 0x9d6d, 0xe4f6, 0xe4f4, 0xc2fe, 0x9d6e, 0xe4dd, 0x9d6f, 0xe4f0, /*0x28-0x2f*/ + 0x9d70, 0xcafe, 0x9d71, 0xd5c4, 0x9d72, 0x9d73, 0xe4f1, 0x9d74, /*0x30-0x37*/ + 0x9d75, 0x9d76, 0x9d77, 0x9d78, 0x9d79, 0x9d7a, 0xd1fa, 0x9d7b, /*0x38-0x3f*/ + 0x9d7c, 0x9d7d, 0x9d7e, 0x9d80, 0x9d81, 0x9d82, 0xe4eb, 0xe4ec, /*0x40-0x47*/ + 0x9d83, 0x9d84, 0x9d85, 0xe4f2, 0x9d86, 0xceab, 0x9d87, 0x9d88, /*0x48-0x4f*/ + 0x9d89, 0x9d8a, 0x9d8b, 0x9d8c, 0x9d8d, 0x9d8e, 0x9d8f, 0x9d90, /*0x50-0x57*/ + 0xc5cb, 0x9d91, 0x9d92, 0x9d93, 0xc7b1, 0x9d94, 0xc2ba, 0x9d95, /*0x58-0x5f*/ + 0x9d96, 0x9d97, 0xe4ea, 0x9d98, 0x9d99, 0x9d9a, 0xc1ca, 0x9d9b, /*0x60-0x67*/ + 0x9d9c, 0x9d9d, 0x9d9e, 0x9d9f, 0x9da0, 0xccb6, 0xb3b1, 0x9da1, /*0x68-0x6f*/ + 0x9da2, 0x9da3, 0xe4fb, 0x9da4, 0xe4f3, 0x9da5, 0x9da6, 0x9da7, /*0x70-0x77*/ + 0xe4fa, 0x9da8, 0xe4fd, 0x9da9, 0xe4fc, 0x9daa, 0x9dab, 0x9dac, /*0x78-0x7f*/ + 0x9dad, 0x9dae, 0x9daf, 0x9db0, 0xb3ce, 0x9db1, 0x9db2, 0x9db3, /*0x80-0x87*/ + 0xb3ba, 0xe4f7, 0x9db4, 0x9db5, 0xe4f9, 0xe4f8, 0xc5ec, 0x9db6, /*0x88-0x8f*/ + 0x9db7, 0x9db8, 0x9db9, 0x9dba, 0x9dbb, 0x9dbc, 0x9dbd, 0x9dbe, /*0x90-0x97*/ + 0x9dbf, 0x9dc0, 0x9dc1, 0x9dc2, 0xc0bd, 0x9dc3, 0x9dc4, 0x9dc5, /*0x98-0x9f*/ + 0x9dc6, 0xd4e8, 0x9dc7, 0x9dc8, 0x9dc9, 0x9dca, 0x9dcb, 0xe5a2, /*0xa0-0xa7*/ + 0x9dcc, 0x9dcd, 0x9dce, 0x9dcf, 0x9dd0, 0x9dd1, 0x9dd2, 0x9dd3, /*0xa8-0xaf*/ + 0x9dd4, 0x9dd5, 0x9dd6, 0xb0c4, 0x9dd7, 0x9dd8, 0xe5a4, 0x9dd9, /*0xb0-0xb7*/ + 0x9dda, 0xe5a3, 0x9ddb, 0x9ddc, 0x9ddd, 0x9dde, 0x9ddf, 0x9de0, /*0xb8-0xbf*/ + 0xbca4, 0x9de1, 0xe5a5, 0x9de2, 0x9de3, 0x9de4, 0x9de5, 0x9de6, /*0xc0-0xc7*/ + 0x9de7, 0xe5a1, 0x9de8, 0x9de9, 0x9dea, 0x9deb, 0x9dec, 0x9ded, /*0xc8-0xcf*/ + 0x9dee, 0xe4fe, 0xb1f4, 0x9def, 0x9df0, 0x9df1, 0x9df2, 0x9df3, /*0xd0-0xd7*/ + 0x9df4, 0x9df5, 0x9df6, 0x9df7, 0x9df8, 0x9df9, 0xe5a8, 0x9dfa, /*0xd8-0xdf*/ + 0xe5a9, 0xe5a6, 0x9dfb, 0x9dfc, 0x9dfd, 0x9dfe, 0x9e40, 0x9e41, /*0xe0-0xe7*/ + 0x9e42, 0x9e43, 0x9e44, 0x9e45, 0x9e46, 0x9e47, 0xe5a7, 0xe5aa, /*0xe8-0xef*/ + 0x9e48, 0x9e49, 0x9e4a, 0x9e4b, 0x9e4c, 0x9e4d, 0x9e4e, 0x9e4f, /*0xf0-0xf7*/ + 0x9e50, 0x9e51, 0x9e52, 0x9e53, 0x9e54, 0x9e55, 0x9e56, 0x9e57, /*0xf8-0xff*/ + /* 0x7000 */ + 0x9e58, 0x9e59, 0x9e5a, 0x9e5b, 0x9e5c, 0x9e5d, 0x9e5e, 0x9e5f, /*0x00-0x07*/ + 0x9e60, 0x9e61, 0x9e62, 0x9e63, 0x9e64, 0x9e65, 0x9e66, 0x9e67, /*0x08-0x0f*/ + 0x9e68, 0xc6d9, 0x9e69, 0x9e6a, 0x9e6b, 0x9e6c, 0x9e6d, 0x9e6e, /*0x10-0x17*/ + 0x9e6f, 0x9e70, 0xe5ab, 0xe5ad, 0x9e71, 0x9e72, 0x9e73, 0x9e74, /*0x18-0x1f*/ + 0x9e75, 0x9e76, 0x9e77, 0xe5ac, 0x9e78, 0x9e79, 0x9e7a, 0x9e7b, /*0x20-0x27*/ + 0x9e7c, 0x9e7d, 0x9e7e, 0x9e80, 0x9e81, 0x9e82, 0x9e83, 0x9e84, /*0x28-0x2f*/ + 0x9e85, 0x9e86, 0x9e87, 0x9e88, 0x9e89, 0xe5af, 0x9e8a, 0x9e8b, /*0x30-0x37*/ + 0x9e8c, 0xe5ae, 0x9e8d, 0x9e8e, 0x9e8f, 0x9e90, 0x9e91, 0x9e92, /*0x38-0x3f*/ + 0x9e93, 0x9e94, 0x9e95, 0x9e96, 0x9e97, 0x9e98, 0x9e99, 0x9e9a, /*0x40-0x47*/ + 0x9e9b, 0x9e9c, 0x9e9d, 0x9e9e, 0xb9e0, 0x9e9f, 0x9ea0, 0xe5b0, /*0x48-0x4f*/ + 0x9ea1, 0x9ea2, 0x9ea3, 0x9ea4, 0x9ea5, 0x9ea6, 0x9ea7, 0x9ea8, /*0x50-0x57*/ + 0x9ea9, 0x9eaa, 0x9eab, 0x9eac, 0x9ead, 0x9eae, 0xe5b1, 0x9eaf, /*0x58-0x5f*/ + 0x9eb0, 0x9eb1, 0x9eb2, 0x9eb3, 0x9eb4, 0x9eb5, 0x9eb6, 0x9eb7, /*0x60-0x67*/ + 0x9eb8, 0x9eb9, 0x9eba, 0xbbf0, 0xece1, 0xc3f0, 0x9ebb, 0xb5c6, /*0x68-0x6f*/ + 0xbbd2, 0x9ebc, 0x9ebd, 0x9ebe, 0x9ebf, 0xc1e9, 0xd4ee, 0x9ec0, /*0x70-0x77*/ + 0xbec4, 0x9ec1, 0x9ec2, 0x9ec3, 0xd7c6, 0x9ec4, 0xd4d6, 0xb2d3, /*0x78-0x7f*/ + 0xecbe, 0x9ec5, 0x9ec6, 0x9ec7, 0x9ec8, 0xeac1, 0x9ec9, 0x9eca, /*0x80-0x87*/ + 0x9ecb, 0xc2af, 0xb4b6, 0x9ecc, 0x9ecd, 0x9ece, 0xd1d7, 0x9ecf, /*0x88-0x8f*/ + 0x9ed0, 0x9ed1, 0xb3b4, 0x9ed2, 0xc8b2, 0xbfbb, 0xecc0, 0x9ed3, /*0x90-0x97*/ + 0x9ed4, 0xd6cb, 0x9ed5, 0x9ed6, 0xecbf, 0xecc1, 0x9ed7, 0x9ed8, /*0x98-0x9f*/ + 0x9ed9, 0x9eda, 0x9edb, 0x9edc, 0x9edd, 0x9ede, 0x9edf, 0x9ee0, /*0xa0-0xa7*/ + 0x9ee1, 0x9ee2, 0x9ee3, 0xecc5, 0xbee6, 0xccbf, 0xc5da, 0xbebc, /*0xa8-0xaf*/ + 0x9ee4, 0xecc6, 0x9ee5, 0xb1fe, 0x9ee6, 0x9ee7, 0x9ee8, 0xecc4, /*0xb0-0xb7*/ + 0xd5a8, 0xb5e3, 0x9ee9, 0xecc2, 0xc1b6, 0xb3e3, 0x9eea, 0x9eeb, /*0xb8-0xbf*/ + 0xecc3, 0xcbb8, 0xc0c3, 0xccfe, 0x9eec, 0x9eed, 0x9eee, 0x9eef, /*0xc0-0xc7*/ + 0xc1d2, 0x9ef0, 0xecc8, 0x9ef1, 0x9ef2, 0x9ef3, 0x9ef4, 0x9ef5, /*0xc8-0xcf*/ + 0x9ef6, 0x9ef7, 0x9ef8, 0x9ef9, 0x9efa, 0x9efb, 0x9efc, 0x9efd, /*0xd0-0xd7*/ + 0xbae6, 0xc0d3, 0x9efe, 0xd6f2, 0x9f40, 0x9f41, 0x9f42, 0xd1cc, /*0xd8-0xdf*/ + 0x9f43, 0x9f44, 0x9f45, 0x9f46, 0xbfbe, 0x9f47, 0xb7b3, 0xc9d5, /*0xe0-0xe7*/ + 0xecc7, 0xbbe2, 0x9f48, 0xcccc, 0xbdfd, 0xc8c8, 0x9f49, 0xcfa9, /*0xe8-0xef*/ + 0x9f4a, 0x9f4b, 0x9f4c, 0x9f4d, 0x9f4e, 0x9f4f, 0x9f50, 0xcde9, /*0xf0-0xf7*/ + 0x9f51, 0xc5eb, 0x9f52, 0x9f53, 0x9f54, 0xb7e9, 0x9f55, 0x9f56, /*0xf8-0xff*/ + /* 0x7100 */ + 0x9f57, 0x9f58, 0x9f59, 0x9f5a, 0x9f5b, 0x9f5c, 0x9f5d, 0x9f5e, /*0x00-0x07*/ + 0x9f5f, 0xd1c9, 0xbab8, 0x9f60, 0x9f61, 0x9f62, 0x9f63, 0x9f64, /*0x08-0x0f*/ + 0xecc9, 0x9f65, 0x9f66, 0xecca, 0x9f67, 0xbbc0, 0xeccb, 0x9f68, /*0x10-0x17*/ + 0xece2, 0xb1ba, 0xb7d9, 0x9f69, 0x9f6a, 0x9f6b, 0x9f6c, 0x9f6d, /*0x18-0x1f*/ + 0x9f6e, 0x9f6f, 0x9f70, 0x9f71, 0x9f72, 0x9f73, 0xbdb9, 0x9f74, /*0x20-0x27*/ + 0x9f75, 0x9f76, 0x9f77, 0x9f78, 0x9f79, 0x9f7a, 0x9f7b, 0xeccc, /*0x28-0x2f*/ + 0xd1e6, 0xeccd, 0x9f7c, 0x9f7d, 0x9f7e, 0x9f80, 0xc8bb, 0x9f81, /*0x30-0x37*/ + 0x9f82, 0x9f83, 0x9f84, 0x9f85, 0x9f86, 0x9f87, 0x9f88, 0x9f89, /*0x38-0x3f*/ + 0x9f8a, 0x9f8b, 0x9f8c, 0x9f8d, 0x9f8e, 0xecd1, 0x9f8f, 0x9f90, /*0x40-0x47*/ + 0x9f91, 0x9f92, 0xecd3, 0x9f93, 0xbbcd, 0x9f94, 0xbce5, 0x9f95, /*0x48-0x4f*/ + 0x9f96, 0x9f97, 0x9f98, 0x9f99, 0x9f9a, 0x9f9b, 0x9f9c, 0x9f9d, /*0x50-0x57*/ + 0x9f9e, 0x9f9f, 0x9fa0, 0x9fa1, 0xeccf, 0x9fa2, 0xc9b7, 0x9fa3, /*0x58-0x5f*/ + 0x9fa4, 0x9fa5, 0x9fa6, 0x9fa7, 0xc3ba, 0x9fa8, 0xece3, 0xd5d5, /*0x60-0x67*/ + 0xecd0, 0x9fa9, 0x9faa, 0x9fab, 0x9fac, 0x9fad, 0xd6f3, 0x9fae, /*0x68-0x6f*/ + 0x9faf, 0x9fb0, 0xecd2, 0xecce, 0x9fb1, 0x9fb2, 0x9fb3, 0x9fb4, /*0x70-0x77*/ + 0xecd4, 0x9fb5, 0xecd5, 0x9fb6, 0x9fb7, 0xc9bf, 0x9fb8, 0x9fb9, /*0x78-0x7f*/ + 0x9fba, 0x9fbb, 0x9fbc, 0x9fbd, 0xcfa8, 0x9fbe, 0x9fbf, 0x9fc0, /*0x80-0x87*/ + 0x9fc1, 0x9fc2, 0xd0dc, 0x9fc3, 0x9fc4, 0x9fc5, 0x9fc6, 0xd1ac, /*0x88-0x8f*/ + 0x9fc7, 0x9fc8, 0x9fc9, 0x9fca, 0xc8db, 0x9fcb, 0x9fcc, 0x9fcd, /*0x90-0x97*/ + 0xecd6, 0xcef5, 0x9fce, 0x9fcf, 0x9fd0, 0x9fd1, 0x9fd2, 0xcaec, /*0x98-0x9f*/ + 0xecda, 0x9fd3, 0x9fd4, 0x9fd5, 0x9fd6, 0x9fd7, 0x9fd8, 0x9fd9, /*0xa0-0xa7*/ + 0xecd9, 0x9fda, 0x9fdb, 0x9fdc, 0xb0be, 0x9fdd, 0x9fde, 0x9fdf, /*0xa8-0xaf*/ + 0x9fe0, 0x9fe1, 0x9fe2, 0xecd7, 0x9fe3, 0xecd8, 0x9fe4, 0x9fe5, /*0xb0-0xb7*/ + 0x9fe6, 0xece4, 0x9fe7, 0x9fe8, 0x9fe9, 0x9fea, 0x9feb, 0x9fec, /*0xb8-0xbf*/ + 0x9fed, 0x9fee, 0x9fef, 0xc8bc, 0x9ff0, 0x9ff1, 0x9ff2, 0x9ff3, /*0xc0-0xc7*/ + 0x9ff4, 0x9ff5, 0x9ff6, 0x9ff7, 0x9ff8, 0x9ff9, 0xc1c7, 0x9ffa, /*0xc8-0xcf*/ + 0x9ffb, 0x9ffc, 0x9ffd, 0x9ffe, 0xecdc, 0xd1e0, 0xa040, 0xa041, /*0xd0-0xd7*/ + 0xa042, 0xa043, 0xa044, 0xa045, 0xa046, 0xa047, 0xa048, 0xa049, /*0xd8-0xdf*/ + 0xecdb, 0xa04a, 0xa04b, 0xa04c, 0xa04d, 0xd4ef, 0xa04e, 0xecdd, /*0xe0-0xe7*/ + 0xa04f, 0xa050, 0xa051, 0xa052, 0xa053, 0xa054, 0xdbc6, 0xa055, /*0xe8-0xef*/ + 0xa056, 0xa057, 0xa058, 0xa059, 0xa05a, 0xa05b, 0xa05c, 0xa05d, /*0xf0-0xf7*/ + 0xa05e, 0xecde, 0xa05f, 0xa060, 0xa061, 0xa062, 0xa063, 0xa064, /*0xf8-0xff*/ + /* 0x7200 */ + 0xa065, 0xa066, 0xa067, 0xa068, 0xa069, 0xa06a, 0xb1ac, 0xa06b, /*0x00-0x07*/ + 0xa06c, 0xa06d, 0xa06e, 0xa06f, 0xa070, 0xa071, 0xa072, 0xa073, /*0x08-0x0f*/ + 0xa074, 0xa075, 0xa076, 0xa077, 0xa078, 0xa079, 0xa07a, 0xa07b, /*0x10-0x17*/ + 0xa07c, 0xa07d, 0xa07e, 0xa080, 0xa081, 0xecdf, 0xa082, 0xa083, /*0x18-0x1f*/ + 0xa084, 0xa085, 0xa086, 0xa087, 0xa088, 0xa089, 0xa08a, 0xa08b, /*0x20-0x27*/ + 0xece0, 0xa08c, 0xd7a6, 0xa08d, 0xc5c0, 0xa08e, 0xa08f, 0xa090, /*0x28-0x2f*/ + 0xebbc, 0xb0ae, 0xa091, 0xa092, 0xa093, 0xbef4, 0xb8b8, 0xd2af, /*0x30-0x37*/ + 0xb0d6, 0xb5f9, 0xa094, 0xd8b3, 0xa095, 0xcbac, 0xa096, 0xe3dd, /*0x38-0x3f*/ + 0xa097, 0xa098, 0xa099, 0xa09a, 0xa09b, 0xa09c, 0xa09d, 0xc6ac, /*0x40-0x47*/ + 0xb0e6, 0xa09e, 0xa09f, 0xa0a0, 0xc5c6, 0xebb9, 0xa0a1, 0xa0a2, /*0x48-0x4f*/ + 0xa0a3, 0xa0a4, 0xebba, 0xa0a5, 0xa0a6, 0xa0a7, 0xebbb, 0xa0a8, /*0x50-0x57*/ + 0xa0a9, 0xd1c0, 0xa0aa, 0xc5a3, 0xa0ab, 0xeaf2, 0xa0ac, 0xc4b2, /*0x58-0x5f*/ + 0xa0ad, 0xc4b5, 0xc0ce, 0xa0ae, 0xa0af, 0xa0b0, 0xeaf3, 0xc4c1, /*0x60-0x67*/ + 0xa0b1, 0xceef, 0xa0b2, 0xa0b3, 0xa0b4, 0xa0b5, 0xeaf0, 0xeaf4, /*0x68-0x6f*/ + 0xa0b6, 0xa0b7, 0xc9fc, 0xa0b8, 0xa0b9, 0xc7a3, 0xa0ba, 0xa0bb, /*0x70-0x77*/ + 0xa0bc, 0xccd8, 0xcefe, 0xa0bd, 0xa0be, 0xa0bf, 0xeaf5, 0xeaf6, /*0x78-0x7f*/ + 0xcfac, 0xc0e7, 0xa0c0, 0xa0c1, 0xeaf7, 0xa0c2, 0xa0c3, 0xa0c4, /*0x80-0x87*/ + 0xa0c5, 0xa0c6, 0xb6bf, 0xeaf8, 0xa0c7, 0xeaf9, 0xa0c8, 0xeafa, /*0x88-0x8f*/ + 0xa0c9, 0xa0ca, 0xeafb, 0xa0cb, 0xa0cc, 0xa0cd, 0xa0ce, 0xa0cf, /*0x90-0x97*/ + 0xa0d0, 0xa0d1, 0xa0d2, 0xa0d3, 0xa0d4, 0xa0d5, 0xa0d6, 0xeaf1, /*0x98-0x9f*/ + 0xa0d7, 0xa0d8, 0xa0d9, 0xa0da, 0xa0db, 0xa0dc, 0xa0dd, 0xa0de, /*0xa0-0xa7*/ + 0xa0df, 0xa0e0, 0xa0e1, 0xa0e2, 0xc8ae, 0xe1eb, 0xa0e3, 0xb7b8, /*0xa8-0xaf*/ + 0xe1ec, 0xa0e4, 0xa0e5, 0xa0e6, 0xe1ed, 0xa0e7, 0xd7b4, 0xe1ee, /*0xb0-0xb7*/ + 0xe1ef, 0xd3cc, 0xa0e8, 0xa0e9, 0xa0ea, 0xa0eb, 0xa0ec, 0xa0ed, /*0xb8-0xbf*/ + 0xa0ee, 0xe1f1, 0xbff1, 0xe1f0, 0xb5d2, 0xa0ef, 0xa0f0, 0xa0f1, /*0xc0-0xc7*/ + 0xb1b7, 0xa0f2, 0xa0f3, 0xa0f4, 0xa0f5, 0xe1f3, 0xe1f2, 0xa0f6, /*0xc8-0xcf*/ + 0xbafc, 0xa0f7, 0xe1f4, 0xa0f8, 0xa0f9, 0xa0fa, 0xa0fb, 0xb9b7, /*0xd0-0xd7*/ + 0xa0fc, 0xbed1, 0xa0fd, 0xa0fe, 0xaa40, 0xaa41, 0xc4fc, 0xaa42, /*0xd8-0xdf*/ + 0xbadd, 0xbdc6, 0xaa43, 0xaa44, 0xaa45, 0xaa46, 0xaa47, 0xaa48, /*0xe0-0xe7*/ + 0xe1f5, 0xe1f7, 0xaa49, 0xaa4a, 0xb6c0, 0xcfc1, 0xcaa8, 0xe1f6, /*0xe8-0xef*/ + 0xd5f8, 0xd3fc, 0xe1f8, 0xe1fc, 0xe1f9, 0xaa4b, 0xaa4c, 0xe1fa, /*0xf0-0xf7*/ + 0xc0ea, 0xaa4d, 0xe1fe, 0xe2a1, 0xc0c7, 0xaa4e, 0xaa4f, 0xaa50, /*0xf8-0xff*/ + /* 0x7300 */ + 0xaa51, 0xe1fb, 0xaa52, 0xe1fd, 0xaa53, 0xaa54, 0xaa55, 0xaa56, /*0x00-0x07*/ + 0xaa57, 0xaa58, 0xe2a5, 0xaa59, 0xaa5a, 0xaa5b, 0xc1d4, 0xaa5c, /*0x08-0x0f*/ + 0xaa5d, 0xaa5e, 0xaa5f, 0xe2a3, 0xaa60, 0xe2a8, 0xb2fe, 0xe2a2, /*0x10-0x17*/ + 0xaa61, 0xaa62, 0xaa63, 0xc3cd, 0xb2c2, 0xe2a7, 0xe2a6, 0xaa64, /*0x18-0x1f*/ + 0xaa65, 0xe2a4, 0xe2a9, 0xaa66, 0xaa67, 0xe2ab, 0xaa68, 0xaa69, /*0x20-0x27*/ + 0xaa6a, 0xd0c9, 0xd6ed, 0xc3a8, 0xe2ac, 0xaa6b, 0xcfd7, 0xaa6c, /*0x28-0x2f*/ + 0xaa6d, 0xe2ae, 0xaa6e, 0xaa6f, 0xbaef, 0xaa70, 0xaa71, 0xe9e0, /*0x30-0x37*/ + 0xe2ad, 0xe2aa, 0xaa72, 0xaa73, 0xaa74, 0xaa75, 0xbbab, 0xd4b3, /*0x38-0x3f*/ + 0xaa76, 0xaa77, 0xaa78, 0xaa79, 0xaa7a, 0xaa7b, 0xaa7c, 0xaa7d, /*0x40-0x47*/ + 0xaa7e, 0xaa80, 0xaa81, 0xaa82, 0xaa83, 0xe2b0, 0xaa84, 0xaa85, /*0x48-0x4f*/ + 0xe2af, 0xaa86, 0xe9e1, 0xaa87, 0xaa88, 0xaa89, 0xaa8a, 0xe2b1, /*0x50-0x57*/ + 0xaa8b, 0xaa8c, 0xaa8d, 0xaa8e, 0xaa8f, 0xaa90, 0xaa91, 0xaa92, /*0x58-0x5f*/ + 0xe2b2, 0xaa93, 0xaa94, 0xaa95, 0xaa96, 0xaa97, 0xaa98, 0xaa99, /*0x60-0x67*/ + 0xaa9a, 0xaa9b, 0xaa9c, 0xaa9d, 0xe2b3, 0xcca1, 0xaa9e, 0xe2b4, /*0x68-0x6f*/ + 0xaa9f, 0xaaa0, 0xab40, 0xab41, 0xab42, 0xab43, 0xab44, 0xab45, /*0x70-0x77*/ + 0xab46, 0xab47, 0xab48, 0xab49, 0xab4a, 0xab4b, 0xe2b5, 0xab4c, /*0x78-0x7f*/ + 0xab4d, 0xab4e, 0xab4f, 0xab50, 0xd0fe, 0xab51, 0xab52, 0xc2ca, /*0x80-0x87*/ + 0xab53, 0xd3f1, 0xab54, 0xcdf5, 0xab55, 0xab56, 0xe7e0, 0xab57, /*0x88-0x8f*/ + 0xab58, 0xe7e1, 0xab59, 0xab5a, 0xab5b, 0xab5c, 0xbec1, 0xab5d, /*0x90-0x97*/ + 0xab5e, 0xab5f, 0xab60, 0xc2ea, 0xab61, 0xab62, 0xab63, 0xe7e4, /*0x98-0x9f*/ + 0xab64, 0xab65, 0xe7e3, 0xab66, 0xab67, 0xab68, 0xab69, 0xab6a, /*0xa0-0xa7*/ + 0xab6b, 0xcde6, 0xab6c, 0xc3b5, 0xab6d, 0xab6e, 0xe7e2, 0xbbb7, /*0xa8-0xaf*/ + 0xcfd6, 0xab6f, 0xc1e1, 0xe7e9, 0xab70, 0xab71, 0xab72, 0xe7e8, /*0xb0-0xb7*/ + 0xab73, 0xab74, 0xe7f4, 0xb2a3, 0xab75, 0xab76, 0xab77, 0xab78, /*0xb8-0xbf*/ + 0xe7ea, 0xab79, 0xe7e6, 0xab7a, 0xab7b, 0xab7c, 0xab7d, 0xab7e, /*0xc0-0xc7*/ + 0xe7ec, 0xe7eb, 0xc9ba, 0xab80, 0xab81, 0xd5e4, 0xab82, 0xe7e5, /*0xc8-0xcf*/ + 0xb7a9, 0xe7e7, 0xab83, 0xab84, 0xab85, 0xab86, 0xab87, 0xab88, /*0xd0-0xd7*/ + 0xab89, 0xe7ee, 0xab8a, 0xab8b, 0xab8c, 0xab8d, 0xe7f3, 0xab8e, /*0xd8-0xdf*/ + 0xd6e9, 0xab8f, 0xab90, 0xab91, 0xab92, 0xe7ed, 0xab93, 0xe7f2, /*0xe0-0xe7*/ + 0xab94, 0xe7f1, 0xab95, 0xab96, 0xab97, 0xb0e0, 0xab98, 0xab99, /*0xe8-0xef*/ + 0xab9a, 0xab9b, 0xe7f5, 0xab9c, 0xab9d, 0xab9e, 0xab9f, 0xaba0, /*0xf0-0xf7*/ + 0xac40, 0xac41, 0xac42, 0xac43, 0xac44, 0xac45, 0xac46, 0xac47, /*0xf8-0xff*/ + /* 0x7400 */ + 0xac48, 0xac49, 0xac4a, 0xc7f2, 0xac4b, 0xc0c5, 0xc0ed, 0xac4c, /*0x00-0x07*/ + 0xac4d, 0xc1f0, 0xe7f0, 0xac4e, 0xac4f, 0xac50, 0xac51, 0xe7f6, /*0x08-0x0f*/ + 0xcbf6, 0xac52, 0xac53, 0xac54, 0xac55, 0xac56, 0xac57, 0xac58, /*0x10-0x17*/ + 0xac59, 0xac5a, 0xe8a2, 0xe8a1, 0xac5b, 0xac5c, 0xac5d, 0xac5e, /*0x18-0x1f*/ + 0xac5f, 0xac60, 0xd7c1, 0xac61, 0xac62, 0xe7fa, 0xe7f9, 0xac63, /*0x20-0x27*/ + 0xe7fb, 0xac64, 0xe7f7, 0xac65, 0xe7fe, 0xac66, 0xe7fd, 0xac67, /*0x28-0x2f*/ + 0xe7fc, 0xac68, 0xac69, 0xc1d5, 0xc7d9, 0xc5fd, 0xc5c3, 0xac6a, /*0x30-0x37*/ + 0xac6b, 0xac6c, 0xac6d, 0xac6e, 0xc7ed, 0xac6f, 0xac70, 0xac71, /*0x38-0x3f*/ + 0xac72, 0xe8a3, 0xac73, 0xac74, 0xac75, 0xac76, 0xac77, 0xac78, /*0x40-0x47*/ + 0xac79, 0xac7a, 0xac7b, 0xac7c, 0xac7d, 0xac7e, 0xac80, 0xac81, /*0x48-0x4f*/ + 0xac82, 0xac83, 0xac84, 0xac85, 0xac86, 0xe8a6, 0xac87, 0xe8a5, /*0x50-0x57*/ + 0xac88, 0xe8a7, 0xbaf7, 0xe7f8, 0xe8a4, 0xac89, 0xc8f0, 0xc9aa, /*0x58-0x5f*/ + 0xac8a, 0xac8b, 0xac8c, 0xac8d, 0xac8e, 0xac8f, 0xac90, 0xac91, /*0x60-0x67*/ + 0xac92, 0xac93, 0xac94, 0xac95, 0xac96, 0xe8a9, 0xac97, 0xac98, /*0x68-0x6f*/ + 0xb9e5, 0xac99, 0xac9a, 0xac9b, 0xac9c, 0xac9d, 0xd1fe, 0xe8a8, /*0x70-0x77*/ + 0xac9e, 0xac9f, 0xaca0, 0xad40, 0xad41, 0xad42, 0xe8aa, 0xad43, /*0x78-0x7f*/ + 0xe8ad, 0xe8ae, 0xad44, 0xc1a7, 0xad45, 0xad46, 0xad47, 0xe8af, /*0x80-0x87*/ + 0xad48, 0xad49, 0xad4a, 0xe8b0, 0xad4b, 0xad4c, 0xe8ac, 0xad4d, /*0x88-0x8f*/ + 0xe8b4, 0xad4e, 0xad4f, 0xad50, 0xad51, 0xad52, 0xad53, 0xad54, /*0x90-0x97*/ + 0xad55, 0xad56, 0xad57, 0xad58, 0xe8ab, 0xad59, 0xe8b1, 0xad5a, /*0x98-0x9f*/ + 0xad5b, 0xad5c, 0xad5d, 0xad5e, 0xad5f, 0xad60, 0xad61, 0xe8b5, /*0xa0-0xa7*/ + 0xe8b2, 0xe8b3, 0xad62, 0xad63, 0xad64, 0xad65, 0xad66, 0xad67, /*0xa8-0xaf*/ + 0xad68, 0xad69, 0xad6a, 0xad6b, 0xad6c, 0xad6d, 0xad6e, 0xad6f, /*0xb0-0xb7*/ + 0xad70, 0xad71, 0xe8b7, 0xad72, 0xad73, 0xad74, 0xad75, 0xad76, /*0xb8-0xbf*/ + 0xad77, 0xad78, 0xad79, 0xad7a, 0xad7b, 0xad7c, 0xad7d, 0xad7e, /*0xc0-0xc7*/ + 0xad80, 0xad81, 0xad82, 0xad83, 0xad84, 0xad85, 0xad86, 0xad87, /*0xc8-0xcf*/ + 0xad88, 0xad89, 0xe8b6, 0xad8a, 0xad8b, 0xad8c, 0xad8d, 0xad8e, /*0xd0-0xd7*/ + 0xad8f, 0xad90, 0xad91, 0xad92, 0xb9cf, 0xad93, 0xf0ac, 0xad94, /*0xd8-0xdf*/ + 0xf0ad, 0xad95, 0xc6b0, 0xb0ea, 0xc8bf, 0xad96, 0xcddf, 0xad97, /*0xe0-0xe7*/ + 0xad98, 0xad99, 0xad9a, 0xad9b, 0xad9c, 0xad9d, 0xcecd, 0xeab1, /*0xe8-0xef*/ + 0xad9e, 0xad9f, 0xada0, 0xae40, 0xeab2, 0xae41, 0xc6bf, 0xb4c9, /*0xf0-0xf7*/ + 0xae42, 0xae43, 0xae44, 0xae45, 0xae46, 0xae47, 0xae48, 0xeab3, /*0xf8-0xff*/ + /* 0x7500 */ + 0xae49, 0xae4a, 0xae4b, 0xae4c, 0xd5e7, 0xae4d, 0xae4e, 0xae4f, /*0x00-0x07*/ + 0xae50, 0xae51, 0xae52, 0xae53, 0xae54, 0xddf9, 0xae55, 0xeab4, /*0x08-0x0f*/ + 0xae56, 0xeab5, 0xae57, 0xeab6, 0xae58, 0xae59, 0xae5a, 0xae5b, /*0x10-0x17*/ + 0xb8ca, 0xdfb0, 0xc9f5, 0xae5c, 0xccf0, 0xae5d, 0xae5e, 0xc9fa, /*0x18-0x1f*/ + 0xae5f, 0xae60, 0xae61, 0xae62, 0xae63, 0xc9fb, 0xae64, 0xae65, /*0x20-0x27*/ + 0xd3c3, 0xcba6, 0xae66, 0xb8a6, 0xf0ae, 0xb1c2, 0xae67, 0xe5b8, /*0x28-0x2f*/ + 0xccef, 0xd3c9, 0xbcd7, 0xc9ea, 0xae68, 0xb5e7, 0xae69, 0xc4d0, /*0x30-0x37*/ + 0xb5e9, 0xae6a, 0xeeae, 0xbbad, 0xae6b, 0xae6c, 0xe7de, 0xae6d, /*0x38-0x3f*/ + 0xeeaf, 0xae6e, 0xae6f, 0xae70, 0xae71, 0xb3a9, 0xae72, 0xae73, /*0x40-0x47*/ + 0xeeb2, 0xae74, 0xae75, 0xeeb1, 0xbde7, 0xae76, 0xeeb0, 0xceb7, /*0x48-0x4f*/ + 0xae77, 0xae78, 0xae79, 0xae7a, 0xc5cf, 0xae7b, 0xae7c, 0xae7d, /*0x50-0x57*/ + 0xae7e, 0xc1f4, 0xdbce, 0xeeb3, 0xd0f3, 0xae80, 0xae81, 0xae82, /*0x58-0x5f*/ + 0xae83, 0xae84, 0xae85, 0xae86, 0xae87, 0xc2d4, 0xc6e8, 0xae88, /*0x60-0x67*/ + 0xae89, 0xae8a, 0xb7ac, 0xae8b, 0xae8c, 0xae8d, 0xae8e, 0xae8f, /*0x68-0x6f*/ + 0xae90, 0xae91, 0xeeb4, 0xae92, 0xb3eb, 0xae93, 0xae94, 0xae95, /*0x70-0x77*/ + 0xbbfb, 0xeeb5, 0xae96, 0xae97, 0xae98, 0xae99, 0xae9a, 0xe7dc, /*0x78-0x7f*/ + 0xae9b, 0xae9c, 0xae9d, 0xeeb6, 0xae9e, 0xae9f, 0xbdae, 0xaea0, /*0x80-0x87*/ + 0xaf40, 0xaf41, 0xaf42, 0xf1e2, 0xaf43, 0xaf44, 0xaf45, 0xcae8, /*0x88-0x8f*/ + 0xaf46, 0xd2c9, 0xf0da, 0xaf47, 0xf0db, 0xaf48, 0xf0dc, 0xc1c6, /*0x90-0x97*/ + 0xaf49, 0xb8ed, 0xbece, 0xaf4a, 0xaf4b, 0xf0de, 0xaf4c, 0xc5b1, /*0x98-0x9f*/ + 0xf0dd, 0xd1f1, 0xaf4d, 0xf0e0, 0xb0cc, 0xbdea, 0xaf4e, 0xaf4f, /*0xa0-0xa7*/ + 0xaf50, 0xaf51, 0xaf52, 0xd2df, 0xf0df, 0xaf53, 0xb4af, 0xb7e8, /*0xa8-0xaf*/ + 0xf0e6, 0xf0e5, 0xc6a3, 0xf0e1, 0xf0e2, 0xb4c3, 0xaf54, 0xaf55, /*0xb0-0xb7*/ + 0xf0e3, 0xd5ee, 0xaf56, 0xaf57, 0xccdb, 0xbed2, 0xbcb2, 0xaf58, /*0xb8-0xbf*/ + 0xaf59, 0xaf5a, 0xf0e8, 0xf0e7, 0xf0e4, 0xb2a1, 0xaf5b, 0xd6a2, /*0xc0-0xc7*/ + 0xd3b8, 0xbeb7, 0xc8ac, 0xaf5c, 0xaf5d, 0xf0ea, 0xaf5e, 0xaf5f, /*0xc8-0xcf*/ + 0xaf60, 0xaf61, 0xd1f7, 0xaf62, 0xd6cc, 0xbadb, 0xf0e9, 0xaf63, /*0xd0-0xd7*/ + 0xb6bb, 0xaf64, 0xaf65, 0xcdb4, 0xaf66, 0xaf67, 0xc6a6, 0xaf68, /*0xd8-0xdf*/ + 0xaf69, 0xaf6a, 0xc1a1, 0xf0eb, 0xf0ee, 0xaf6b, 0xf0ed, 0xf0f0, /*0xe0-0xe7*/ + 0xf0ec, 0xaf6c, 0xbbbe, 0xf0ef, 0xaf6d, 0xaf6e, 0xaf6f, 0xaf70, /*0xe8-0xef*/ + 0xccb5, 0xf0f2, 0xaf71, 0xaf72, 0xb3d5, 0xaf73, 0xaf74, 0xaf75, /*0xf0-0xf7*/ + 0xaf76, 0xb1d4, 0xaf77, 0xaf78, 0xf0f3, 0xaf79, 0xaf7a, 0xf0f4, /*0xf8-0xff*/ + /* 0x7600 */ + 0xf0f6, 0xb4e1, 0xaf7b, 0xf0f1, 0xaf7c, 0xf0f7, 0xaf7d, 0xaf7e, /*0x00-0x07*/ + 0xaf80, 0xaf81, 0xf0fa, 0xaf82, 0xf0f8, 0xaf83, 0xaf84, 0xaf85, /*0x08-0x0f*/ + 0xf0f5, 0xaf86, 0xaf87, 0xaf88, 0xaf89, 0xf0fd, 0xaf8a, 0xf0f9, /*0x10-0x17*/ + 0xf0fc, 0xf0fe, 0xaf8b, 0xf1a1, 0xaf8c, 0xaf8d, 0xaf8e, 0xcec1, /*0x18-0x1f*/ + 0xf1a4, 0xaf8f, 0xf1a3, 0xaf90, 0xc1f6, 0xf0fb, 0xcadd, 0xaf91, /*0x20-0x27*/ + 0xaf92, 0xb4f1, 0xb1f1, 0xccb1, 0xaf93, 0xf1a6, 0xaf94, 0xaf95, /*0x28-0x2f*/ + 0xf1a7, 0xaf96, 0xaf97, 0xf1ac, 0xd5ce, 0xf1a9, 0xaf98, 0xaf99, /*0x30-0x37*/ + 0xc8b3, 0xaf9a, 0xaf9b, 0xaf9c, 0xf1a2, 0xaf9d, 0xf1ab, 0xf1a8, /*0x38-0x3f*/ + 0xf1a5, 0xaf9e, 0xaf9f, 0xf1aa, 0xafa0, 0xb040, 0xb041, 0xb042, /*0x40-0x47*/ + 0xb043, 0xb044, 0xb045, 0xb046, 0xb0a9, 0xf1ad, 0xb047, 0xb048, /*0x48-0x4f*/ + 0xb049, 0xb04a, 0xb04b, 0xb04c, 0xf1af, 0xb04d, 0xf1b1, 0xb04e, /*0x50-0x57*/ + 0xb04f, 0xb050, 0xb051, 0xb052, 0xf1b0, 0xb053, 0xf1ae, 0xb054, /*0x58-0x5f*/ + 0xb055, 0xb056, 0xb057, 0xd1a2, 0xb058, 0xb059, 0xb05a, 0xb05b, /*0x60-0x67*/ + 0xb05c, 0xb05d, 0xb05e, 0xf1b2, 0xb05f, 0xb060, 0xb061, 0xf1b3, /*0x68-0x6f*/ + 0xb062, 0xb063, 0xb064, 0xb065, 0xb066, 0xb067, 0xb068, 0xb069, /*0x70-0x77*/ + 0xb9ef, 0xb06a, 0xb06b, 0xb5c7, 0xb06c, 0xb0d7, 0xb0d9, 0xb06d, /*0x78-0x7f*/ + 0xb06e, 0xb06f, 0xd4ed, 0xb070, 0xb5c4, 0xb071, 0xbdd4, 0xbbca, /*0x80-0x87*/ + 0xf0a7, 0xb072, 0xb073, 0xb8de, 0xb074, 0xb075, 0xf0a8, 0xb076, /*0x88-0x8f*/ + 0xb077, 0xb0a8, 0xb078, 0xf0a9, 0xb079, 0xb07a, 0xcdee, 0xb07b, /*0x90-0x97*/ + 0xb07c, 0xf0aa, 0xb07d, 0xb07e, 0xb080, 0xb081, 0xb082, 0xb083, /*0x98-0x9f*/ + 0xb084, 0xb085, 0xb086, 0xb087, 0xf0ab, 0xb088, 0xb089, 0xb08a, /*0xa0-0xa7*/ + 0xb08b, 0xb08c, 0xb08d, 0xb08e, 0xb08f, 0xb090, 0xc6a4, 0xb091, /*0xa8-0xaf*/ + 0xb092, 0xd6e5, 0xf1e4, 0xb093, 0xf1e5, 0xb094, 0xb095, 0xb096, /*0xb0-0xb7*/ + 0xb097, 0xb098, 0xb099, 0xb09a, 0xb09b, 0xb09c, 0xb09d, 0xc3f3, /*0xb8-0xbf*/ + 0xb09e, 0xb09f, 0xd3db, 0xb0a0, 0xb140, 0xd6d1, 0xc5e8, 0xb141, /*0xc0-0xc7*/ + 0xd3af, 0xb142, 0xd2e6, 0xb143, 0xb144, 0xeec1, 0xb0bb, 0xd5b5, /*0xc8-0xcf*/ + 0xd1ce, 0xbce0, 0xbad0, 0xb145, 0xbff8, 0xb146, 0xb8c7, 0xb5c1, /*0xd0-0xd7*/ + 0xc5cc, 0xb147, 0xb148, 0xcaa2, 0xb149, 0xb14a, 0xb14b, 0xc3cb, /*0xd8-0xdf*/ + 0xb14c, 0xb14d, 0xb14e, 0xb14f, 0xb150, 0xeec2, 0xb151, 0xb152, /*0xe0-0xe7*/ + 0xb153, 0xb154, 0xb155, 0xb156, 0xb157, 0xb158, 0xc4bf, 0xb6a2, /*0xe8-0xef*/ + 0xb159, 0xedec, 0xc3a4, 0xb15a, 0xd6b1, 0xb15b, 0xb15c, 0xb15d, /*0xf0-0xf7*/ + 0xcfe0, 0xedef, 0xb15e, 0xb15f, 0xc5ce, 0xb160, 0xb6dc, 0xb161, /*0xf8-0xff*/ + /* 0x7700 */ + 0xb162, 0xcaa1, 0xb163, 0xb164, 0xeded, 0xb165, 0xb166, 0xedf0, /*0x00-0x07*/ + 0xedf1, 0xc3bc, 0xb167, 0xbfb4, 0xb168, 0xedee, 0xb169, 0xb16a, /*0x08-0x0f*/ + 0xb16b, 0xb16c, 0xb16d, 0xb16e, 0xb16f, 0xb170, 0xb171, 0xb172, /*0x10-0x17*/ + 0xb173, 0xedf4, 0xedf2, 0xb174, 0xb175, 0xb176, 0xb177, 0xd5e6, /*0x18-0x1f*/ + 0xc3df, 0xb178, 0xedf3, 0xb179, 0xb17a, 0xb17b, 0xedf6, 0xb17c, /*0x20-0x27*/ + 0xd5a3, 0xd1a3, 0xb17d, 0xb17e, 0xb180, 0xedf5, 0xb181, 0xc3d0, /*0x28-0x2f*/ + 0xb182, 0xb183, 0xb184, 0xb185, 0xb186, 0xedf7, 0xbff4, 0xbeec, /*0x30-0x37*/ + 0xedf8, 0xb187, 0xccf7, 0xb188, 0xd1db, 0xb189, 0xb18a, 0xb18b, /*0x38-0x3f*/ + 0xd7c5, 0xd5f6, 0xb18c, 0xedfc, 0xb18d, 0xb18e, 0xb18f, 0xedfb, /*0x40-0x47*/ + 0xb190, 0xb191, 0xb192, 0xb193, 0xb194, 0xb195, 0xb196, 0xb197, /*0x48-0x4f*/ + 0xedf9, 0xedfa, 0xb198, 0xb199, 0xb19a, 0xb19b, 0xb19c, 0xb19d, /*0x50-0x57*/ + 0xb19e, 0xb19f, 0xedfd, 0xbea6, 0xb1a0, 0xb240, 0xb241, 0xb242, /*0x58-0x5f*/ + 0xb243, 0xcbaf, 0xeea1, 0xb6bd, 0xb244, 0xeea2, 0xc4c0, 0xb245, /*0x60-0x67*/ + 0xedfe, 0xb246, 0xb247, 0xbdde, 0xb2c7, 0xb248, 0xb249, 0xb24a, /*0x68-0x6f*/ + 0xb24b, 0xb24c, 0xb24d, 0xb24e, 0xb24f, 0xb250, 0xb251, 0xb252, /*0x70-0x77*/ + 0xb253, 0xb6c3, 0xb254, 0xb255, 0xb256, 0xeea5, 0xd8ba, 0xeea3, /*0x78-0x7f*/ + 0xeea6, 0xb257, 0xb258, 0xb259, 0xc3e9, 0xb3f2, 0xb25a, 0xb25b, /*0x80-0x87*/ + 0xb25c, 0xb25d, 0xb25e, 0xb25f, 0xeea7, 0xeea4, 0xcfb9, 0xb260, /*0x88-0x8f*/ + 0xb261, 0xeea8, 0xc2f7, 0xb262, 0xb263, 0xb264, 0xb265, 0xb266, /*0x90-0x97*/ + 0xb267, 0xb268, 0xb269, 0xb26a, 0xb26b, 0xb26c, 0xb26d, 0xeea9, /*0x98-0x9f*/ + 0xeeaa, 0xb26e, 0xdeab, 0xb26f, 0xb270, 0xc6b3, 0xb271, 0xc7c6, /*0xa0-0xa7*/ + 0xb272, 0xd6f5, 0xb5c9, 0xb273, 0xcbb2, 0xb274, 0xb275, 0xb276, /*0xa8-0xaf*/ + 0xeeab, 0xb277, 0xb278, 0xcdab, 0xb279, 0xeeac, 0xb27a, 0xb27b, /*0xb0-0xb7*/ + 0xb27c, 0xb27d, 0xb27e, 0xd5b0, 0xb280, 0xeead, 0xb281, 0xf6c4, /*0xb8-0xbf*/ + 0xb282, 0xb283, 0xb284, 0xb285, 0xb286, 0xb287, 0xb288, 0xb289, /*0xc0-0xc7*/ + 0xb28a, 0xb28b, 0xb28c, 0xb28d, 0xb28e, 0xdbc7, 0xb28f, 0xb290, /*0xc8-0xcf*/ + 0xb291, 0xb292, 0xb293, 0xb294, 0xb295, 0xb296, 0xb297, 0xb4a3, /*0xd0-0xd7*/ + 0xb298, 0xb299, 0xb29a, 0xc3ac, 0xf1e6, 0xb29b, 0xb29c, 0xb29d, /*0xd8-0xdf*/ + 0xb29e, 0xb29f, 0xcab8, 0xd2d3, 0xb2a0, 0xd6aa, 0xb340, 0xeff2, /*0xe0-0xe7*/ + 0xb341, 0xbed8, 0xb342, 0xbdc3, 0xeff3, 0xb6cc, 0xb0ab, 0xb343, /*0xe8-0xef*/ + 0xb344, 0xb345, 0xb346, 0xcaaf, 0xb347, 0xb348, 0xedb6, 0xb349, /*0xf0-0xf7*/ + 0xedb7, 0xb34a, 0xb34b, 0xb34c, 0xb34d, 0xcef9, 0xb7af, 0xbff3, /*0xf8-0xff*/ + /* 0x7800 */ + 0xedb8, 0xc2eb, 0xc9b0, 0xb34e, 0xb34f, 0xb350, 0xb351, 0xb352, /*0x00-0x07*/ + 0xb353, 0xedb9, 0xb354, 0xb355, 0xc6f6, 0xbfb3, 0xb356, 0xb357, /*0x08-0x0f*/ + 0xb358, 0xedbc, 0xc5f8, 0xb359, 0xd1d0, 0xb35a, 0xd7a9, 0xedba, /*0x10-0x17*/ + 0xedbb, 0xb35b, 0xd1e2, 0xb35c, 0xedbf, 0xedc0, 0xb35d, 0xedc4, /*0x18-0x1f*/ + 0xb35e, 0xb35f, 0xb360, 0xedc8, 0xb361, 0xedc6, 0xedce, 0xd5e8, /*0x20-0x27*/ + 0xb362, 0xedc9, 0xb363, 0xb364, 0xedc7, 0xedbe, 0xb365, 0xb366, /*0x28-0x2f*/ + 0xc5e9, 0xb367, 0xb368, 0xb369, 0xc6c6, 0xb36a, 0xb36b, 0xc9e9, /*0x30-0x37*/ + 0xd4d2, 0xedc1, 0xedc2, 0xedc3, 0xedc5, 0xb36c, 0xc0f9, 0xb36d, /*0x38-0x3f*/ + 0xb4a1, 0xb36e, 0xb36f, 0xb370, 0xb371, 0xb9e8, 0xb372, 0xedd0, /*0x40-0x47*/ + 0xb373, 0xb374, 0xb375, 0xb376, 0xedd1, 0xb377, 0xedca, 0xb378, /*0x48-0x4f*/ + 0xedcf, 0xb379, 0xcef8, 0xb37a, 0xb37b, 0xcbb6, 0xedcc, 0xedcd, /*0x50-0x57*/ + 0xb37c, 0xb37d, 0xb37e, 0xb380, 0xb381, 0xcff5, 0xb382, 0xb383, /*0x58-0x5f*/ + 0xb384, 0xb385, 0xb386, 0xb387, 0xb388, 0xb389, 0xb38a, 0xb38b, /*0x60-0x67*/ + 0xb38c, 0xb38d, 0xedd2, 0xc1f2, 0xd3b2, 0xedcb, 0xc8b7, 0xb38e, /*0x68-0x6f*/ + 0xb38f, 0xb390, 0xb391, 0xb392, 0xb393, 0xb394, 0xb395, 0xbcef, /*0x70-0x77*/ + 0xb396, 0xb397, 0xb398, 0xb399, 0xc5f0, 0xb39a, 0xb39b, 0xb39c, /*0x78-0x7f*/ + 0xb39d, 0xb39e, 0xb39f, 0xb3a0, 0xb440, 0xb441, 0xb442, 0xedd6, /*0x80-0x87*/ + 0xb443, 0xb5ef, 0xb444, 0xb445, 0xc2b5, 0xb0ad, 0xcbe9, 0xb446, /*0x88-0x8f*/ + 0xb447, 0xb1ae, 0xb448, 0xedd4, 0xb449, 0xb44a, 0xb44b, 0xcdeb, /*0x90-0x97*/ + 0xb5e2, 0xb44c, 0xedd5, 0xedd3, 0xedd7, 0xb44d, 0xb44e, 0xb5fa, /*0x98-0x9f*/ + 0xb44f, 0xedd8, 0xb450, 0xedd9, 0xb451, 0xeddc, 0xb452, 0xb1cc, /*0xa0-0xa7*/ + 0xb453, 0xb454, 0xb455, 0xb456, 0xb457, 0xb458, 0xb459, 0xb45a, /*0xa8-0xaf*/ + 0xc5f6, 0xbcee, 0xedda, 0xccbc, 0xb2ea, 0xb45b, 0xb45c, 0xb45d, /*0xb0-0xb7*/ + 0xb45e, 0xeddb, 0xb45f, 0xb460, 0xb461, 0xb462, 0xc4eb, 0xb463, /*0xb8-0xbf*/ + 0xb464, 0xb4c5, 0xb465, 0xb466, 0xb467, 0xb0f5, 0xb468, 0xb469, /*0xc0-0xc7*/ + 0xb46a, 0xeddf, 0xc0da, 0xb4e8, 0xb46b, 0xb46c, 0xb46d, 0xb46e, /*0xc8-0xcf*/ + 0xc5cd, 0xb46f, 0xb470, 0xb471, 0xeddd, 0xbfc4, 0xb472, 0xb473, /*0xd0-0xd7*/ + 0xb474, 0xedde, 0xb475, 0xb476, 0xb477, 0xb478, 0xb479, 0xb47a, /*0xd8-0xdf*/ + 0xb47b, 0xb47c, 0xb47d, 0xb47e, 0xb480, 0xb481, 0xb482, 0xb483, /*0xe0-0xe7*/ + 0xc4a5, 0xb484, 0xb485, 0xb486, 0xede0, 0xb487, 0xb488, 0xb489, /*0xe8-0xef*/ + 0xb48a, 0xb48b, 0xede1, 0xb48c, 0xede3, 0xb48d, 0xb48e, 0xc1d7, /*0xf0-0xf7*/ + 0xb48f, 0xb490, 0xbbc7, 0xb491, 0xb492, 0xb493, 0xb494, 0xb495, /*0xf8-0xff*/ + /* 0x7900 */ + 0xb496, 0xbdb8, 0xb497, 0xb498, 0xb499, 0xede2, 0xb49a, 0xb49b, /*0x00-0x07*/ + 0xb49c, 0xb49d, 0xb49e, 0xb49f, 0xb4a0, 0xb540, 0xb541, 0xb542, /*0x08-0x0f*/ + 0xb543, 0xb544, 0xb545, 0xede4, 0xb546, 0xb547, 0xb548, 0xb549, /*0x10-0x17*/ + 0xb54a, 0xb54b, 0xb54c, 0xb54d, 0xb54e, 0xb54f, 0xede6, 0xb550, /*0x18-0x1f*/ + 0xb551, 0xb552, 0xb553, 0xb554, 0xede5, 0xb555, 0xb556, 0xb557, /*0x20-0x27*/ + 0xb558, 0xb559, 0xb55a, 0xb55b, 0xb55c, 0xb55d, 0xb55e, 0xb55f, /*0x28-0x2f*/ + 0xb560, 0xb561, 0xb562, 0xb563, 0xede7, 0xb564, 0xb565, 0xb566, /*0x30-0x37*/ + 0xb567, 0xb568, 0xcabe, 0xecea, 0xc0f1, 0xb569, 0xc9e7, 0xb56a, /*0x38-0x3f*/ + 0xeceb, 0xc6ee, 0xb56b, 0xb56c, 0xb56d, 0xb56e, 0xecec, 0xb56f, /*0x40-0x47*/ + 0xc6ed, 0xeced, 0xb570, 0xb571, 0xb572, 0xb573, 0xb574, 0xb575, /*0x48-0x4f*/ + 0xb576, 0xb577, 0xb578, 0xecf0, 0xb579, 0xb57a, 0xd7e6, 0xecf3, /*0x50-0x57*/ + 0xb57b, 0xb57c, 0xecf1, 0xecee, 0xecef, 0xd7a3, 0xc9f1, 0xcbee, /*0x58-0x5f*/ + 0xecf4, 0xb57d, 0xecf2, 0xb57e, 0xb580, 0xcfe9, 0xb581, 0xecf6, /*0x60-0x67*/ + 0xc6b1, 0xb582, 0xb583, 0xb584, 0xb585, 0xbcc0, 0xb586, 0xecf5, /*0x68-0x6f*/ + 0xb587, 0xb588, 0xb589, 0xb58a, 0xb58b, 0xb58c, 0xb58d, 0xb5bb, /*0x70-0x77*/ + 0xbbf6, 0xb58e, 0xecf7, 0xb58f, 0xb590, 0xb591, 0xb592, 0xb593, /*0x78-0x7f*/ + 0xd9f7, 0xbdfb, 0xb594, 0xb595, 0xc2bb, 0xecf8, 0xb596, 0xb597, /*0x80-0x87*/ + 0xb598, 0xb599, 0xecf9, 0xb59a, 0xb59b, 0xb59c, 0xb59d, 0xb8a3, /*0x88-0x8f*/ + 0xb59e, 0xb59f, 0xb5a0, 0xb640, 0xb641, 0xb642, 0xb643, 0xb644, /*0x90-0x97*/ + 0xb645, 0xb646, 0xecfa, 0xb647, 0xb648, 0xb649, 0xb64a, 0xb64b, /*0x98-0x9f*/ + 0xb64c, 0xb64d, 0xb64e, 0xb64f, 0xb650, 0xb651, 0xb652, 0xecfb, /*0xa0-0xa7*/ + 0xb653, 0xb654, 0xb655, 0xb656, 0xb657, 0xb658, 0xb659, 0xb65a, /*0xa8-0xaf*/ + 0xb65b, 0xb65c, 0xb65d, 0xecfc, 0xb65e, 0xb65f, 0xb660, 0xb661, /*0xb0-0xb7*/ + 0xb662, 0xd3ed, 0xd8ae, 0xc0eb, 0xb663, 0xc7dd, 0xbacc, 0xb664, /*0xb8-0xbf*/ + 0xd0e3, 0xcbbd, 0xb665, 0xcdba, 0xb666, 0xb667, 0xb8d1, 0xb668, /*0xc0-0xc7*/ + 0xb669, 0xb1fc, 0xb66a, 0xc7ef, 0xb66b, 0xd6d6, 0xb66c, 0xb66d, /*0xc8-0xcf*/ + 0xb66e, 0xbfc6, 0xc3eb, 0xb66f, 0xb670, 0xeff5, 0xb671, 0xb672, /*0xd0-0xd7*/ + 0xc3d8, 0xb673, 0xb674, 0xb675, 0xb676, 0xb677, 0xb678, 0xd7e2, /*0xd8-0xdf*/ + 0xb679, 0xb67a, 0xb67b, 0xeff7, 0xb3d3, 0xb67c, 0xc7d8, 0xd1ed, /*0xe0-0xe7*/ + 0xb67d, 0xd6c8, 0xb67e, 0xeff8, 0xb680, 0xeff6, 0xb681, 0xbbfd, /*0xe8-0xef*/ + 0xb3c6, 0xb682, 0xb683, 0xb684, 0xb685, 0xb686, 0xb687, 0xb688, /*0xf0-0xf7*/ + 0xbdd5, 0xb689, 0xb68a, 0xd2c6, 0xb68b, 0xbbe0, 0xb68c, 0xb68d, /*0xf8-0xff*/ + /* 0x7a00 */ + 0xcfa1, 0xb68e, 0xeffc, 0xeffb, 0xb68f, 0xb690, 0xeff9, 0xb691, /*0x00-0x07*/ + 0xb692, 0xb693, 0xb694, 0xb3cc, 0xb695, 0xc9d4, 0xcbb0, 0xb696, /*0x08-0x0f*/ + 0xb697, 0xb698, 0xb699, 0xb69a, 0xeffe, 0xb69b, 0xb69c, 0xb0de, /*0x10-0x17*/ + 0xb69d, 0xb69e, 0xd6c9, 0xb69f, 0xb6a0, 0xb740, 0xeffd, 0xb741, /*0x18-0x1f*/ + 0xb3ed, 0xb742, 0xb743, 0xf6d5, 0xb744, 0xb745, 0xb746, 0xb747, /*0x20-0x27*/ + 0xb748, 0xb749, 0xb74a, 0xb74b, 0xb74c, 0xb74d, 0xb74e, 0xb74f, /*0x28-0x2f*/ + 0xb750, 0xb751, 0xb752, 0xcec8, 0xb753, 0xb754, 0xb755, 0xf0a2, /*0x30-0x37*/ + 0xb756, 0xf0a1, 0xb757, 0xb5be, 0xbcda, 0xbbfc, 0xb758, 0xb8e5, /*0x38-0x3f*/ + 0xb759, 0xb75a, 0xb75b, 0xb75c, 0xb75d, 0xb75e, 0xc4c2, 0xb75f, /*0x40-0x47*/ + 0xb760, 0xb761, 0xb762, 0xb763, 0xb764, 0xb765, 0xb766, 0xb767, /*0x48-0x4f*/ + 0xb768, 0xf0a3, 0xb769, 0xb76a, 0xb76b, 0xb76c, 0xb76d, 0xcbeb, /*0x50-0x57*/ + 0xb76e, 0xb76f, 0xb770, 0xb771, 0xb772, 0xb773, 0xb774, 0xb775, /*0x58-0x5f*/ + 0xb776, 0xb777, 0xb778, 0xb779, 0xb77a, 0xb77b, 0xb77c, 0xb77d, /*0x60-0x67*/ + 0xb77e, 0xb780, 0xb781, 0xb782, 0xb783, 0xb784, 0xb785, 0xb786, /*0x68-0x6f*/ + 0xf0a6, 0xb787, 0xb788, 0xb789, 0xd1a8, 0xb78a, 0xbebf, 0xc7ee, /*0x70-0x77*/ + 0xf1b6, 0xf1b7, 0xbfd5, 0xb78b, 0xb78c, 0xb78d, 0xb78e, 0xb4a9, /*0x78-0x7f*/ + 0xf1b8, 0xcdbb, 0xb78f, 0xc7d4, 0xd5ad, 0xb790, 0xf1b9, 0xb791, /*0x80-0x87*/ + 0xf1ba, 0xb792, 0xb793, 0xb794, 0xb795, 0xc7cf, 0xb796, 0xb797, /*0x88-0x8f*/ + 0xb798, 0xd2a4, 0xd6cf, 0xb799, 0xb79a, 0xf1bb, 0xbdd1, 0xb4b0, /*0x90-0x97*/ + 0xbebd, 0xb79b, 0xb79c, 0xb79d, 0xb4dc, 0xced1, 0xb79e, 0xbfdf, /*0x98-0x9f*/ + 0xf1bd, 0xb79f, 0xb7a0, 0xb840, 0xb841, 0xbffa, 0xf1bc, 0xb842, /*0xa0-0xa7*/ + 0xf1bf, 0xb843, 0xb844, 0xb845, 0xf1be, 0xf1c0, 0xb846, 0xb847, /*0xa8-0xaf*/ + 0xb848, 0xb849, 0xb84a, 0xf1c1, 0xb84b, 0xb84c, 0xb84d, 0xb84e, /*0xb0-0xb7*/ + 0xb84f, 0xb850, 0xb851, 0xb852, 0xb853, 0xb854, 0xb855, 0xc1fe, /*0xb8-0xbf*/ + 0xb856, 0xb857, 0xb858, 0xb859, 0xb85a, 0xb85b, 0xb85c, 0xb85d, /*0xc0-0xc7*/ + 0xb85e, 0xb85f, 0xb860, 0xc1a2, 0xb861, 0xb862, 0xb863, 0xb864, /*0xc8-0xcf*/ + 0xb865, 0xb866, 0xb867, 0xb868, 0xb869, 0xb86a, 0xcafa, 0xb86b, /*0xd0-0xd7*/ + 0xb86c, 0xd5be, 0xb86d, 0xb86e, 0xb86f, 0xb870, 0xbeba, 0xbeb9, /*0xd8-0xdf*/ + 0xd5c2, 0xb871, 0xb872, 0xbfa2, 0xb873, 0xcdaf, 0xf1b5, 0xb874, /*0xe0-0xe7*/ + 0xb875, 0xb876, 0xb877, 0xb878, 0xb879, 0xbddf, 0xb87a, 0xb6cb, /*0xe8-0xef*/ + 0xb87b, 0xb87c, 0xb87d, 0xb87e, 0xb880, 0xb881, 0xb882, 0xb883, /*0xf0-0xf7*/ + 0xb884, 0xd6f1, 0xf3c3, 0xb885, 0xb886, 0xf3c4, 0xb887, 0xb8cd, /*0xf8-0xff*/ + /* 0x7b00 */ + 0xb888, 0xb889, 0xb88a, 0xf3c6, 0xf3c7, 0xb88b, 0xb0ca, 0xb88c, /*0x00-0x07*/ + 0xf3c5, 0xb88d, 0xf3c9, 0xcbf1, 0xb88e, 0xb88f, 0xb890, 0xf3cb, /*0x08-0x0f*/ + 0xb891, 0xd0a6, 0xb892, 0xb893, 0xb1ca, 0xf3c8, 0xb894, 0xb895, /*0x10-0x17*/ + 0xb896, 0xf3cf, 0xb897, 0xb5d1, 0xb898, 0xb899, 0xf3d7, 0xb89a, /*0x18-0x1f*/ + 0xf3d2, 0xb89b, 0xb89c, 0xb89d, 0xf3d4, 0xf3d3, 0xb7fb, 0xb89e, /*0x20-0x27*/ + 0xb1bf, 0xb89f, 0xf3ce, 0xf3ca, 0xb5da, 0xb8a0, 0xf3d0, 0xb940, /*0x28-0x2f*/ + 0xb941, 0xf3d1, 0xb942, 0xf3d5, 0xb943, 0xb944, 0xb945, 0xb946, /*0x30-0x37*/ + 0xf3cd, 0xb947, 0xbce3, 0xb948, 0xc1fd, 0xb949, 0xf3d6, 0xb94a, /*0x38-0x3f*/ + 0xb94b, 0xb94c, 0xb94d, 0xb94e, 0xb94f, 0xf3da, 0xb950, 0xf3cc, /*0x40-0x47*/ + 0xb951, 0xb5c8, 0xb952, 0xbdee, 0xf3dc, 0xb953, 0xb954, 0xb7a4, /*0x48-0x4f*/ + 0xbff0, 0xd6fe, 0xcdb2, 0xb955, 0xb4f0, 0xb956, 0xb2df, 0xb957, /*0x50-0x57*/ + 0xf3d8, 0xb958, 0xf3d9, 0xc9b8, 0xb959, 0xf3dd, 0xb95a, 0xb95b, /*0x58-0x5f*/ + 0xf3de, 0xb95c, 0xf3e1, 0xb95d, 0xb95e, 0xb95f, 0xb960, 0xb961, /*0x60-0x67*/ + 0xb962, 0xb963, 0xb964, 0xb965, 0xb966, 0xb967, 0xf3df, 0xb968, /*0x68-0x6f*/ + 0xb969, 0xf3e3, 0xf3e2, 0xb96a, 0xb96b, 0xf3db, 0xb96c, 0xbfea, /*0x70-0x77*/ + 0xb96d, 0xb3ef, 0xb96e, 0xf3e0, 0xb96f, 0xb970, 0xc7a9, 0xb971, /*0x78-0x7f*/ + 0xbcf2, 0xb972, 0xb973, 0xb974, 0xb975, 0xf3eb, 0xb976, 0xb977, /*0x80-0x87*/ + 0xb978, 0xb979, 0xb97a, 0xb97b, 0xb97c, 0xb9bf, 0xb97d, 0xb97e, /*0x88-0x8f*/ + 0xf3e4, 0xb980, 0xb981, 0xb982, 0xb2ad, 0xbbfe, 0xb983, 0xcbe3, /*0x90-0x97*/ + 0xb984, 0xb985, 0xb986, 0xb987, 0xf3ed, 0xf3e9, 0xb988, 0xb989, /*0x98-0x9f*/ + 0xb98a, 0xb9dc, 0xf3ee, 0xb98b, 0xb98c, 0xb98d, 0xf3e5, 0xf3e6, /*0xa0-0xa7*/ + 0xf3ea, 0xc2e1, 0xf3ec, 0xf3ef, 0xf3e8, 0xbcfd, 0xb98e, 0xb98f, /*0xa8-0xaf*/ + 0xb990, 0xcfe4, 0xb991, 0xb992, 0xf3f0, 0xb993, 0xb994, 0xb995, /*0xb0-0xb7*/ + 0xf3e7, 0xb996, 0xb997, 0xb998, 0xb999, 0xb99a, 0xb99b, 0xb99c, /*0xb8-0xbf*/ + 0xb99d, 0xf3f2, 0xb99e, 0xb99f, 0xb9a0, 0xba40, 0xd7ad, 0xc6aa, /*0xc0-0xc7*/ + 0xba41, 0xba42, 0xba43, 0xba44, 0xf3f3, 0xba45, 0xba46, 0xba47, /*0xc8-0xcf*/ + 0xba48, 0xf3f1, 0xba49, 0xc2a8, 0xba4a, 0xba4b, 0xba4c, 0xba4d, /*0xd0-0xd7*/ + 0xba4e, 0xb8dd, 0xf3f5, 0xba4f, 0xba50, 0xf3f4, 0xba51, 0xba52, /*0xd8-0xdf*/ + 0xba53, 0xb4db, 0xba54, 0xba55, 0xba56, 0xf3f6, 0xf3f7, 0xba57, /*0xe0-0xe7*/ + 0xba58, 0xba59, 0xf3f8, 0xba5a, 0xba5b, 0xba5c, 0xc0ba, 0xba5d, /*0xe8-0xef*/ + 0xba5e, 0xc0e9, 0xba5f, 0xba60, 0xba61, 0xba62, 0xba63, 0xc5f1, /*0xf0-0xf7*/ + 0xba64, 0xba65, 0xba66, 0xba67, 0xf3fb, 0xba68, 0xf3fa, 0xba69, /*0xf8-0xff*/ + /* 0x7c00 */ + 0xba6a, 0xba6b, 0xba6c, 0xba6d, 0xba6e, 0xba6f, 0xba70, 0xb4d8, /*0x00-0x07*/ + 0xba71, 0xba72, 0xba73, 0xf3fe, 0xf3f9, 0xba74, 0xba75, 0xf3fc, /*0x08-0x0f*/ + 0xba76, 0xba77, 0xba78, 0xba79, 0xba7a, 0xba7b, 0xf3fd, 0xba7c, /*0x10-0x17*/ + 0xba7d, 0xba7e, 0xba80, 0xba81, 0xba82, 0xba83, 0xba84, 0xf4a1, /*0x18-0x1f*/ + 0xba85, 0xba86, 0xba87, 0xba88, 0xba89, 0xba8a, 0xf4a3, 0xbbc9, /*0x20-0x27*/ + 0xba8b, 0xba8c, 0xf4a2, 0xba8d, 0xba8e, 0xba8f, 0xba90, 0xba91, /*0x28-0x2f*/ + 0xba92, 0xba93, 0xba94, 0xba95, 0xba96, 0xba97, 0xba98, 0xba99, /*0x30-0x37*/ + 0xf4a4, 0xba9a, 0xba9b, 0xba9c, 0xba9d, 0xba9e, 0xba9f, 0xb2be, /*0x38-0x3f*/ + 0xf4a6, 0xf4a5, 0xbaa0, 0xbb40, 0xbb41, 0xbb42, 0xbb43, 0xbb44, /*0x40-0x47*/ + 0xbb45, 0xbb46, 0xbb47, 0xbb48, 0xbb49, 0xbcae, 0xbb4a, 0xbb4b, /*0x48-0x4f*/ + 0xbb4c, 0xbb4d, 0xbb4e, 0xbb4f, 0xbb50, 0xbb51, 0xbb52, 0xbb53, /*0x50-0x57*/ + 0xbb54, 0xbb55, 0xbb56, 0xbb57, 0xbb58, 0xbb59, 0xbb5a, 0xbb5b, /*0x58-0x5f*/ + 0xbb5c, 0xbb5d, 0xbb5e, 0xbb5f, 0xbb60, 0xbb61, 0xbb62, 0xbb63, /*0x60-0x67*/ + 0xbb64, 0xbb65, 0xbb66, 0xbb67, 0xbb68, 0xbb69, 0xbb6a, 0xbb6b, /*0x68-0x6f*/ + 0xbb6c, 0xbb6d, 0xbb6e, 0xc3d7, 0xd9e1, 0xbb6f, 0xbb70, 0xbb71, /*0x70-0x77*/ + 0xbb72, 0xbb73, 0xbb74, 0xc0e0, 0xf4cc, 0xd7d1, 0xbb75, 0xbb76, /*0x78-0x7f*/ + 0xbb77, 0xbb78, 0xbb79, 0xbb7a, 0xbb7b, 0xbb7c, 0xbb7d, 0xbb7e, /*0x80-0x87*/ + 0xbb80, 0xb7db, 0xbb81, 0xbb82, 0xbb83, 0xbb84, 0xbb85, 0xbb86, /*0x88-0x8f*/ + 0xbb87, 0xf4ce, 0xc1a3, 0xbb88, 0xbb89, 0xc6c9, 0xbb8a, 0xb4d6, /*0x90-0x97*/ + 0xd5b3, 0xbb8b, 0xbb8c, 0xbb8d, 0xf4d0, 0xf4cf, 0xf4d1, 0xcbda, /*0x98-0x9f*/ + 0xbb8e, 0xbb8f, 0xf4d2, 0xbb90, 0xd4c1, 0xd6e0, 0xbb91, 0xbb92, /*0xa0-0xa7*/ + 0xbb93, 0xbb94, 0xb7e0, 0xbb95, 0xbb96, 0xbb97, 0xc1b8, 0xbb98, /*0xa8-0xaf*/ + 0xbb99, 0xc1bb, 0xf4d3, 0xbeac, 0xbb9a, 0xbb9b, 0xbb9c, 0xbb9d, /*0xb0-0xb7*/ + 0xbb9e, 0xb4e2, 0xbb9f, 0xbba0, 0xf4d4, 0xf4d5, 0xbeab, 0xbc40, /*0xb8-0xbf*/ + 0xbc41, 0xf4d6, 0xbc42, 0xbc43, 0xbc44, 0xf4db, 0xbc45, 0xf4d7, /*0xc0-0xc7*/ + 0xf4da, 0xbc46, 0xbafd, 0xbc47, 0xf4d8, 0xf4d9, 0xbc48, 0xbc49, /*0xc8-0xcf*/ + 0xbc4a, 0xbc4b, 0xbc4c, 0xbc4d, 0xbc4e, 0xb8e2, 0xccc7, 0xf4dc, /*0xd0-0xd7*/ + 0xbc4f, 0xb2da, 0xbc50, 0xbc51, 0xc3d3, 0xbc52, 0xbc53, 0xd4e3, /*0xd8-0xdf*/ + 0xbfb7, 0xbc54, 0xbc55, 0xbc56, 0xbc57, 0xbc58, 0xbc59, 0xbc5a, /*0xe0-0xe7*/ + 0xf4dd, 0xbc5b, 0xbc5c, 0xbc5d, 0xbc5e, 0xbc5f, 0xbc60, 0xc5b4, /*0xe8-0xef*/ + 0xbc61, 0xbc62, 0xbc63, 0xbc64, 0xbc65, 0xbc66, 0xbc67, 0xbc68, /*0xf0-0xf7*/ + 0xf4e9, 0xbc69, 0xbc6a, 0xcfb5, 0xbc6b, 0xbc6c, 0xbc6d, 0xbc6e, /*0xf8-0xff*/ + /* 0x7d00 */ + 0xbc6f, 0xbc70, 0xbc71, 0xbc72, 0xbc73, 0xbc74, 0xbc75, 0xbc76, /*0x00-0x07*/ + 0xbc77, 0xbc78, 0xcec9, 0xbc79, 0xbc7a, 0xbc7b, 0xbc7c, 0xbc7d, /*0x08-0x0f*/ + 0xbc7e, 0xbc80, 0xbc81, 0xbc82, 0xbc83, 0xbc84, 0xbc85, 0xbc86, /*0x10-0x17*/ + 0xbc87, 0xbc88, 0xbc89, 0xbc8a, 0xbc8b, 0xbc8c, 0xbc8d, 0xbc8e, /*0x18-0x1f*/ + 0xcbd8, 0xbc8f, 0xcbf7, 0xbc90, 0xbc91, 0xbc92, 0xbc93, 0xbdf4, /*0x20-0x27*/ + 0xbc94, 0xbc95, 0xbc96, 0xd7cf, 0xbc97, 0xbc98, 0xbc99, 0xc0db, /*0x28-0x2f*/ + 0xbc9a, 0xbc9b, 0xbc9c, 0xbc9d, 0xbc9e, 0xbc9f, 0xbca0, 0xbd40, /*0x30-0x37*/ + 0xbd41, 0xbd42, 0xbd43, 0xbd44, 0xbd45, 0xbd46, 0xbd47, 0xbd48, /*0x38-0x3f*/ + 0xbd49, 0xbd4a, 0xbd4b, 0xbd4c, 0xbd4d, 0xbd4e, 0xbd4f, 0xbd50, /*0x40-0x47*/ + 0xbd51, 0xbd52, 0xbd53, 0xbd54, 0xbd55, 0xbd56, 0xbd57, 0xbd58, /*0x48-0x4f*/ + 0xbd59, 0xbd5a, 0xbd5b, 0xbd5c, 0xbd5d, 0xbd5e, 0xbd5f, 0xbd60, /*0x50-0x57*/ + 0xbd61, 0xbd62, 0xbd63, 0xbd64, 0xbd65, 0xbd66, 0xbd67, 0xbd68, /*0x58-0x5f*/ + 0xbd69, 0xbd6a, 0xbd6b, 0xbd6c, 0xbd6d, 0xbd6e, 0xbd6f, 0xbd70, /*0x60-0x67*/ + 0xbd71, 0xbd72, 0xbd73, 0xbd74, 0xbd75, 0xbd76, 0xd0f5, 0xbd77, /*0x68-0x6f*/ + 0xbd78, 0xbd79, 0xbd7a, 0xbd7b, 0xbd7c, 0xbd7d, 0xbd7e, 0xf4ea, /*0x70-0x77*/ + 0xbd80, 0xbd81, 0xbd82, 0xbd83, 0xbd84, 0xbd85, 0xbd86, 0xbd87, /*0x78-0x7f*/ + 0xbd88, 0xbd89, 0xbd8a, 0xbd8b, 0xbd8c, 0xbd8d, 0xbd8e, 0xbd8f, /*0x80-0x87*/ + 0xbd90, 0xbd91, 0xbd92, 0xbd93, 0xbd94, 0xbd95, 0xbd96, 0xbd97, /*0x88-0x8f*/ + 0xbd98, 0xbd99, 0xbd9a, 0xbd9b, 0xbd9c, 0xbd9d, 0xbd9e, 0xbd9f, /*0x90-0x97*/ + 0xbda0, 0xbe40, 0xbe41, 0xbe42, 0xbe43, 0xbe44, 0xbe45, 0xbe46, /*0x98-0x9f*/ + 0xbe47, 0xbe48, 0xbe49, 0xbe4a, 0xbe4b, 0xbe4c, 0xf4eb, 0xbe4d, /*0xa0-0xa7*/ + 0xbe4e, 0xbe4f, 0xbe50, 0xbe51, 0xbe52, 0xbe53, 0xf4ec, 0xbe54, /*0xa8-0xaf*/ + 0xbe55, 0xbe56, 0xbe57, 0xbe58, 0xbe59, 0xbe5a, 0xbe5b, 0xbe5c, /*0xb0-0xb7*/ + 0xbe5d, 0xbe5e, 0xbe5f, 0xbe60, 0xbe61, 0xbe62, 0xbe63, 0xbe64, /*0xb8-0xbf*/ + 0xbe65, 0xbe66, 0xbe67, 0xbe68, 0xbe69, 0xbe6a, 0xbe6b, 0xbe6c, /*0xc0-0xc7*/ + 0xbe6d, 0xbe6e, 0xbe6f, 0xbe70, 0xbe71, 0xbe72, 0xbe73, 0xbe74, /*0xc8-0xcf*/ + 0xbe75, 0xbe76, 0xbe77, 0xbe78, 0xbe79, 0xbe7a, 0xbe7b, 0xbe7c, /*0xd0-0xd7*/ + 0xbe7d, 0xbe7e, 0xbe80, 0xbe81, 0xbe82, 0xbe83, 0xbe84, 0xbe85, /*0xd8-0xdf*/ + 0xbe86, 0xbe87, 0xbe88, 0xbe89, 0xbe8a, 0xbe8b, 0xbe8c, 0xbe8d, /*0xe0-0xe7*/ + 0xbe8e, 0xbe8f, 0xbe90, 0xbe91, 0xbe92, 0xbe93, 0xbe94, 0xbe95, /*0xe8-0xef*/ + 0xbe96, 0xbe97, 0xbe98, 0xbe99, 0xbe9a, 0xbe9b, 0xbe9c, 0xbe9d, /*0xf0-0xf7*/ + 0xbe9e, 0xbe9f, 0xbea0, 0xbf40, 0xbf41, 0xbf42, 0xbf43, 0xbf44, /*0xf8-0xff*/ + /* 0x7e00 */ + 0xbf45, 0xbf46, 0xbf47, 0xbf48, 0xbf49, 0xbf4a, 0xbf4b, 0xbf4c, /*0x00-0x07*/ + 0xbf4d, 0xbf4e, 0xbf4f, 0xbf50, 0xbf51, 0xbf52, 0xbf53, 0xbf54, /*0x08-0x0f*/ + 0xbf55, 0xbf56, 0xbf57, 0xbf58, 0xbf59, 0xbf5a, 0xbf5b, 0xbf5c, /*0x10-0x17*/ + 0xbf5d, 0xbf5e, 0xbf5f, 0xbf60, 0xbf61, 0xbf62, 0xbf63, 0xbf64, /*0x18-0x1f*/ + 0xbf65, 0xbf66, 0xbf67, 0xbf68, 0xbf69, 0xbf6a, 0xbf6b, 0xbf6c, /*0x20-0x27*/ + 0xbf6d, 0xbf6e, 0xbf6f, 0xbf70, 0xbf71, 0xbf72, 0xbf73, 0xbf74, /*0x28-0x2f*/ + 0xbf75, 0xbf76, 0xbf77, 0xbf78, 0xbf79, 0xbf7a, 0xbf7b, 0xbf7c, /*0x30-0x37*/ + 0xbf7d, 0xbf7e, 0xbf80, 0xf7e3, 0xbf81, 0xbf82, 0xbf83, 0xbf84, /*0x38-0x3f*/ + 0xbf85, 0xb7b1, 0xbf86, 0xbf87, 0xbf88, 0xbf89, 0xbf8a, 0xf4ed, /*0x40-0x47*/ + 0xbf8b, 0xbf8c, 0xbf8d, 0xbf8e, 0xbf8f, 0xbf90, 0xbf91, 0xbf92, /*0x48-0x4f*/ + 0xbf93, 0xbf94, 0xbf95, 0xbf96, 0xbf97, 0xbf98, 0xbf99, 0xbf9a, /*0x50-0x57*/ + 0xbf9b, 0xbf9c, 0xbf9d, 0xbf9e, 0xbf9f, 0xbfa0, 0xc040, 0xc041, /*0x58-0x5f*/ + 0xc042, 0xc043, 0xc044, 0xc045, 0xc046, 0xc047, 0xc048, 0xc049, /*0x60-0x67*/ + 0xc04a, 0xc04b, 0xc04c, 0xc04d, 0xc04e, 0xc04f, 0xc050, 0xc051, /*0x68-0x6f*/ + 0xc052, 0xc053, 0xc054, 0xc055, 0xc056, 0xc057, 0xc058, 0xc059, /*0x70-0x77*/ + 0xc05a, 0xc05b, 0xc05c, 0xc05d, 0xc05e, 0xc05f, 0xc060, 0xc061, /*0x78-0x7f*/ + 0xc062, 0xc063, 0xd7eb, 0xc064, 0xc065, 0xc066, 0xc067, 0xc068, /*0x80-0x87*/ + 0xc069, 0xc06a, 0xc06b, 0xc06c, 0xc06d, 0xc06e, 0xc06f, 0xc070, /*0x88-0x8f*/ + 0xc071, 0xc072, 0xc073, 0xc074, 0xc075, 0xc076, 0xc077, 0xc078, /*0x90-0x97*/ + 0xc079, 0xc07a, 0xc07b, 0xf4ee, 0xc07c, 0xc07d, 0xc07e, 0xe6f9, /*0x98-0x9f*/ + 0xbec0, 0xe6fa, 0xbaec, 0xe6fb, 0xcfcb, 0xe6fc, 0xd4bc, 0xbcb6, /*0xa0-0xa7*/ + 0xe6fd, 0xe6fe, 0xbccd, 0xc8d2, 0xceb3, 0xe7a1, 0xc080, 0xb4bf, /*0xa8-0xaf*/ + 0xe7a2, 0xc9b4, 0xb8d9, 0xc4c9, 0xc081, 0xd7dd, 0xc2da, 0xb7d7, /*0xb0-0xb7*/ + 0xd6bd, 0xcec6, 0xb7c4, 0xc082, 0xc083, 0xc5a6, 0xe7a3, 0xcfdf, /*0xb8-0xbf*/ + 0xe7a4, 0xe7a5, 0xe7a6, 0xc1b7, 0xd7e9, 0xc9f0, 0xcfb8, 0xd6af, /*0xc0-0xc7*/ + 0xd6d5, 0xe7a7, 0xb0ed, 0xe7a8, 0xe7a9, 0xc9dc, 0xd2ef, 0xbead, /*0xc8-0xcf*/ + 0xe7aa, 0xb0f3, 0xc8de, 0xbde1, 0xe7ab, 0xc8c6, 0xc084, 0xe7ac, /*0xd0-0xd7*/ + 0xbbe6, 0xb8f8, 0xd1a4, 0xe7ad, 0xc2e7, 0xbef8, 0xbdca, 0xcdb3, /*0xd8-0xdf*/ + 0xe7ae, 0xe7af, 0xbeee, 0xd0e5, 0xc085, 0xcbe7, 0xccd0, 0xbccc, /*0xe0-0xe7*/ + 0xe7b0, 0xbca8, 0xd0f7, 0xe7b1, 0xc086, 0xd0f8, 0xe7b2, 0xe7b3, /*0xe8-0xef*/ + 0xb4c2, 0xe7b4, 0xe7b5, 0xc9fe, 0xceac, 0xc3e0, 0xe7b7, 0xb1c1, /*0xf0-0xf7*/ + 0xb3f1, 0xc087, 0xe7b8, 0xe7b9, 0xd7db, 0xd5c0, 0xe7ba, 0xc2cc, /*0xf8-0xff*/ + /* 0x7f00 */ + 0xd7ba, 0xe7bb, 0xe7bc, 0xe7bd, 0xbcea, 0xc3e5, 0xc0c2, 0xe7be, /*0x00-0x07*/ + 0xe7bf, 0xbca9, 0xc088, 0xe7c0, 0xe7c1, 0xe7b6, 0xb6d0, 0xe7c2, /*0x08-0x0f*/ + 0xc089, 0xe7c3, 0xe7c4, 0xbbba, 0xb5de, 0xc2c6, 0xb1e0, 0xe7c5, /*0x10-0x17*/ + 0xd4b5, 0xe7c6, 0xb8bf, 0xe7c8, 0xe7c7, 0xb7ec, 0xc08a, 0xe7c9, /*0x18-0x1f*/ + 0xb2f8, 0xe7ca, 0xe7cb, 0xe7cc, 0xe7cd, 0xe7ce, 0xe7cf, 0xe7d0, /*0x20-0x27*/ + 0xd3a7, 0xcbf5, 0xe7d1, 0xe7d2, 0xe7d3, 0xe7d4, 0xc9c9, 0xe7d5, /*0x28-0x2f*/ + 0xe7d6, 0xe7d7, 0xe7d8, 0xe7d9, 0xbdc9, 0xe7da, 0xf3be, 0xc08b, /*0x30-0x37*/ + 0xb8d7, 0xc08c, 0xc8b1, 0xc08d, 0xc08e, 0xc08f, 0xc090, 0xc091, /*0x38-0x3f*/ + 0xc092, 0xc093, 0xf3bf, 0xc094, 0xf3c0, 0xf3c1, 0xc095, 0xc096, /*0x40-0x47*/ + 0xc097, 0xc098, 0xc099, 0xc09a, 0xc09b, 0xc09c, 0xc09d, 0xc09e, /*0x48-0x4f*/ + 0xb9de, 0xcdf8, 0xc09f, 0xc0a0, 0xd8e8, 0xbab1, 0xc140, 0xc2de, /*0x50-0x57*/ + 0xeeb7, 0xc141, 0xb7a3, 0xc142, 0xc143, 0xc144, 0xc145, 0xeeb9, /*0x58-0x5f*/ + 0xc146, 0xeeb8, 0xb0d5, 0xc147, 0xc148, 0xc149, 0xc14a, 0xc14b, /*0x60-0x67*/ + 0xeebb, 0xd5d6, 0xd7ef, 0xc14c, 0xc14d, 0xc14e, 0xd6c3, 0xc14f, /*0x68-0x6f*/ + 0xc150, 0xeebd, 0xcaf0, 0xc151, 0xeebc, 0xc152, 0xc153, 0xc154, /*0x70-0x77*/ + 0xc155, 0xeebe, 0xc156, 0xc157, 0xc158, 0xc159, 0xeec0, 0xc15a, /*0x78-0x7f*/ + 0xc15b, 0xeebf, 0xc15c, 0xc15d, 0xc15e, 0xc15f, 0xc160, 0xc161, /*0x80-0x87*/ + 0xc162, 0xc163, 0xd1f2, 0xc164, 0xc7bc, 0xc165, 0xc3c0, 0xc166, /*0x88-0x8f*/ + 0xc167, 0xc168, 0xc169, 0xc16a, 0xb8e1, 0xc16b, 0xc16c, 0xc16d, /*0x90-0x97*/ + 0xc16e, 0xc16f, 0xc1e7, 0xc170, 0xc171, 0xf4c6, 0xd0df, 0xf4c7, /*0x98-0x9f*/ + 0xc172, 0xcfdb, 0xc173, 0xc174, 0xc8ba, 0xc175, 0xc176, 0xf4c8, /*0xa0-0xa7*/ + 0xc177, 0xc178, 0xc179, 0xc17a, 0xc17b, 0xc17c, 0xc17d, 0xf4c9, /*0xa8-0xaf*/ + 0xf4ca, 0xc17e, 0xf4cb, 0xc180, 0xc181, 0xc182, 0xc183, 0xc184, /*0xb0-0xb7*/ + 0xd9fa, 0xb8fe, 0xc185, 0xc186, 0xe5f1, 0xd3f0, 0xc187, 0xf4e0, /*0xb8-0xbf*/ + 0xc188, 0xcecc, 0xc189, 0xc18a, 0xc18b, 0xb3e1, 0xc18c, 0xc18d, /*0xc0-0xc7*/ + 0xc18e, 0xc18f, 0xf1b4, 0xc190, 0xd2ee, 0xc191, 0xf4e1, 0xc192, /*0xc8-0xcf*/ + 0xc193, 0xc194, 0xc195, 0xc196, 0xcfe8, 0xf4e2, 0xc197, 0xc198, /*0xd0-0xd7*/ + 0xc7cc, 0xc199, 0xc19a, 0xc19b, 0xc19c, 0xc19d, 0xc19e, 0xb5d4, /*0xd8-0xdf*/ + 0xb4e4, 0xf4e4, 0xc19f, 0xc1a0, 0xc240, 0xf4e3, 0xf4e5, 0xc241, /*0xe0-0xe7*/ + 0xc242, 0xf4e6, 0xc243, 0xc244, 0xc245, 0xc246, 0xf4e7, 0xc247, /*0xe8-0xef*/ + 0xbab2, 0xb0bf, 0xc248, 0xf4e8, 0xc249, 0xc24a, 0xc24b, 0xc24c, /*0xf0-0xf7*/ + 0xc24d, 0xc24e, 0xc24f, 0xb7ad, 0xd2ed, 0xc250, 0xc251, 0xc252, /*0xf8-0xff*/ + /* 0x8000 */ + 0xd2ab, 0xc0cf, 0xc253, 0xbfbc, 0xeba3, 0xd5df, 0xeac8, 0xc254, /*0x00-0x07*/ + 0xc255, 0xc256, 0xc257, 0xf1f3, 0xb6f8, 0xcba3, 0xc258, 0xc259, /*0x08-0x0f*/ + 0xc4cd, 0xc25a, 0xf1e7, 0xc25b, 0xf1e8, 0xb8fb, 0xf1e9, 0xbac4, /*0x10-0x17*/ + 0xd4c5, 0xb0d2, 0xc25c, 0xc25d, 0xf1ea, 0xc25e, 0xc25f, 0xc260, /*0x18-0x1f*/ + 0xf1eb, 0xc261, 0xf1ec, 0xc262, 0xc263, 0xf1ed, 0xf1ee, 0xf1ef, /*0x20-0x27*/ + 0xf1f1, 0xf1f0, 0xc5d5, 0xc264, 0xc265, 0xc266, 0xc267, 0xc268, /*0x28-0x2f*/ + 0xc269, 0xf1f2, 0xc26a, 0xb6fa, 0xc26b, 0xf1f4, 0xd2ae, 0xdec7, /*0x30-0x37*/ + 0xcbca, 0xc26c, 0xc26d, 0xb3dc, 0xc26e, 0xb5a2, 0xc26f, 0xb9a2, /*0x38-0x3f*/ + 0xc270, 0xc271, 0xc4f4, 0xf1f5, 0xc272, 0xc273, 0xf1f6, 0xc274, /*0x40-0x47*/ + 0xc275, 0xc276, 0xc1c4, 0xc1fb, 0xd6b0, 0xf1f7, 0xc277, 0xc278, /*0x48-0x4f*/ + 0xc279, 0xc27a, 0xf1f8, 0xc27b, 0xc1aa, 0xc27c, 0xc27d, 0xc27e, /*0x50-0x57*/ + 0xc6b8, 0xc280, 0xbedb, 0xc281, 0xc282, 0xc283, 0xc284, 0xc285, /*0x58-0x5f*/ + 0xc286, 0xc287, 0xc288, 0xc289, 0xc28a, 0xc28b, 0xc28c, 0xc28d, /*0x60-0x67*/ + 0xc28e, 0xf1f9, 0xb4cf, 0xc28f, 0xc290, 0xc291, 0xc292, 0xc293, /*0x68-0x6f*/ + 0xc294, 0xf1fa, 0xc295, 0xc296, 0xc297, 0xc298, 0xc299, 0xc29a, /*0x70-0x77*/ + 0xc29b, 0xc29c, 0xc29d, 0xc29e, 0xc29f, 0xc2a0, 0xc340, 0xedb2, /*0x78-0x7f*/ + 0xedb1, 0xc341, 0xc342, 0xcbe0, 0xd2de, 0xc343, 0xcbc1, 0xd5d8, /*0x80-0x87*/ + 0xc344, 0xc8e2, 0xc345, 0xc0df, 0xbca1, 0xc346, 0xc347, 0xc348, /*0x88-0x8f*/ + 0xc349, 0xc34a, 0xc34b, 0xebc1, 0xc34c, 0xc34d, 0xd0a4, 0xc34e, /*0x90-0x97*/ + 0xd6e2, 0xc34f, 0xb6c7, 0xb8d8, 0xebc0, 0xb8ce, 0xc350, 0xebbf, /*0x98-0x9f*/ + 0xb3a6, 0xb9c9, 0xd6ab, 0xc351, 0xb7f4, 0xb7ca, 0xc352, 0xc353, /*0xa0-0xa7*/ + 0xc354, 0xbce7, 0xb7be, 0xebc6, 0xc355, 0xebc7, 0xb0b9, 0xbfcf, /*0xa8-0xaf*/ + 0xc356, 0xebc5, 0xd3fd, 0xc357, 0xebc8, 0xc358, 0xc359, 0xebc9, /*0xb0-0xb7*/ + 0xc35a, 0xc35b, 0xb7ce, 0xc35c, 0xebc2, 0xebc4, 0xc9f6, 0xd6d7, /*0xb8-0xbf*/ + 0xd5cd, 0xd0b2, 0xebcf, 0xceb8, 0xebd0, 0xc35d, 0xb5a8, 0xc35e, /*0xc0-0xc7*/ + 0xc35f, 0xc360, 0xc361, 0xc362, 0xb1b3, 0xebd2, 0xcca5, 0xc363, /*0xc8-0xcf*/ + 0xc364, 0xc365, 0xc366, 0xc367, 0xc368, 0xc369, 0xc5d6, 0xebd3, /*0xd0-0xd7*/ + 0xc36a, 0xebd1, 0xc5df, 0xebce, 0xcaa4, 0xebd5, 0xb0fb, 0xc36b, /*0xd8-0xdf*/ + 0xc36c, 0xbafa, 0xc36d, 0xc36e, 0xd8b7, 0xf1e3, 0xc36f, 0xebca, /*0xe0-0xe7*/ + 0xebcb, 0xebcc, 0xebcd, 0xebd6, 0xe6c0, 0xebd9, 0xc370, 0xbfe8, /*0xe8-0xef*/ + 0xd2c8, 0xebd7, 0xebdc, 0xb8ec, 0xebd8, 0xc371, 0xbdba, 0xc372, /*0xf0-0xf7*/ + 0xd0d8, 0xc373, 0xb0b7, 0xc374, 0xebdd, 0xc4dc, 0xc375, 0xc376, /*0xf8-0xff*/ + /* 0x8100 */ + 0xc377, 0xc378, 0xd6ac, 0xc379, 0xc37a, 0xc37b, 0xb4e0, 0xc37c, /*0x00-0x07*/ + 0xc37d, 0xc2f6, 0xbcb9, 0xc37e, 0xc380, 0xebda, 0xebdb, 0xd4e0, /*0x08-0x0f*/ + 0xc6ea, 0xc4d4, 0xebdf, 0xc5a7, 0xd9f5, 0xc381, 0xb2b1, 0xc382, /*0x10-0x17*/ + 0xebe4, 0xc383, 0xbdc5, 0xc384, 0xc385, 0xc386, 0xebe2, 0xc387, /*0x18-0x1f*/ + 0xc388, 0xc389, 0xc38a, 0xc38b, 0xc38c, 0xc38d, 0xc38e, 0xc38f, /*0x20-0x27*/ + 0xc390, 0xc391, 0xc392, 0xc393, 0xebe3, 0xc394, 0xc395, 0xb8ac, /*0x28-0x2f*/ + 0xc396, 0xcdd1, 0xebe5, 0xc397, 0xc398, 0xc399, 0xebe1, 0xc39a, /*0x30-0x37*/ + 0xc1b3, 0xc39b, 0xc39c, 0xc39d, 0xc39e, 0xc39f, 0xc6a2, 0xc3a0, /*0x38-0x3f*/ + 0xc440, 0xc441, 0xc442, 0xc443, 0xc444, 0xc445, 0xccf3, 0xc446, /*0x40-0x47*/ + 0xebe6, 0xc447, 0xc0b0, 0xd2b8, 0xebe7, 0xc448, 0xc449, 0xc44a, /*0x48-0x4f*/ + 0xb8af, 0xb8ad, 0xc44b, 0xebe8, 0xc7bb, 0xcdf3, 0xc44c, 0xc44d, /*0x50-0x57*/ + 0xc44e, 0xebea, 0xebeb, 0xc44f, 0xc450, 0xc451, 0xc452, 0xc453, /*0x58-0x5f*/ + 0xebed, 0xc454, 0xc455, 0xc456, 0xc457, 0xd0c8, 0xc458, 0xebf2, /*0x60-0x67*/ + 0xc459, 0xebee, 0xc45a, 0xc45b, 0xc45c, 0xebf1, 0xc8f9, 0xc45d, /*0x68-0x6f*/ + 0xd1fc, 0xebec, 0xc45e, 0xc45f, 0xebe9, 0xc460, 0xc461, 0xc462, /*0x70-0x77*/ + 0xc463, 0xb8b9, 0xcfd9, 0xc4e5, 0xebef, 0xebf0, 0xccda, 0xcdc8, /*0x78-0x7f*/ + 0xb0f2, 0xc464, 0xebf6, 0xc465, 0xc466, 0xc467, 0xc468, 0xc469, /*0x80-0x87*/ + 0xebf5, 0xc46a, 0xb2b2, 0xc46b, 0xc46c, 0xc46d, 0xc46e, 0xb8e0, /*0x88-0x8f*/ + 0xc46f, 0xebf7, 0xc470, 0xc471, 0xc472, 0xc473, 0xc474, 0xc475, /*0x90-0x97*/ + 0xb1ec, 0xc476, 0xc477, 0xccc5, 0xc4a4, 0xcfa5, 0xc478, 0xc479, /*0x98-0x9f*/ + 0xc47a, 0xc47b, 0xc47c, 0xebf9, 0xc47d, 0xc47e, 0xeca2, 0xc480, /*0xa0-0xa7*/ + 0xc5f2, 0xc481, 0xebfa, 0xc482, 0xc483, 0xc484, 0xc485, 0xc486, /*0xa8-0xaf*/ + 0xc487, 0xc488, 0xc489, 0xc9c5, 0xc48a, 0xc48b, 0xc48c, 0xc48d, /*0xb0-0xb7*/ + 0xc48e, 0xc48f, 0xe2df, 0xebfe, 0xc490, 0xc491, 0xc492, 0xc493, /*0xb8-0xbf*/ + 0xcdce, 0xeca1, 0xb1db, 0xd3b7, 0xc494, 0xc495, 0xd2dc, 0xc496, /*0xc0-0xc7*/ + 0xc497, 0xc498, 0xebfd, 0xc499, 0xebfb, 0xc49a, 0xc49b, 0xc49c, /*0xc8-0xcf*/ + 0xc49d, 0xc49e, 0xc49f, 0xc4a0, 0xc540, 0xc541, 0xc542, 0xc543, /*0xd0-0xd7*/ + 0xc544, 0xc545, 0xc546, 0xc547, 0xc548, 0xc549, 0xc54a, 0xc54b, /*0xd8-0xdf*/ + 0xc54c, 0xc54d, 0xc54e, 0xb3bc, 0xc54f, 0xc550, 0xc551, 0xeab0, /*0xe0-0xe7*/ + 0xc552, 0xc553, 0xd7d4, 0xc554, 0xf4ab, 0xb3f4, 0xc555, 0xc556, /*0xe8-0xef*/ + 0xc557, 0xc558, 0xc559, 0xd6c1, 0xd6c2, 0xc55a, 0xc55b, 0xc55c, /*0xf0-0xf7*/ + 0xc55d, 0xc55e, 0xc55f, 0xd5e9, 0xbeca, 0xc560, 0xf4a7, 0xc561, /*0xf8-0xff*/ + /* 0x8200 */ + 0xd2a8, 0xf4a8, 0xf4a9, 0xc562, 0xf4aa, 0xbecb, 0xd3df, 0xc563, /*0x00-0x07*/ + 0xc564, 0xc565, 0xc566, 0xc567, 0xc9e0, 0xc9e1, 0xc568, 0xc569, /*0x08-0x0f*/ + 0xf3c2, 0xc56a, 0xcae6, 0xc56b, 0xccf2, 0xc56c, 0xc56d, 0xc56e, /*0x10-0x17*/ + 0xc56f, 0xc570, 0xc571, 0xe2b6, 0xcbb4, 0xc572, 0xcee8, 0xd6db, /*0x18-0x1f*/ + 0xc573, 0xf4ad, 0xf4ae, 0xf4af, 0xc574, 0xc575, 0xc576, 0xc577, /*0x20-0x27*/ + 0xf4b2, 0xc578, 0xbabd, 0xf4b3, 0xb0e3, 0xf4b0, 0xc579, 0xf4b1, /*0x28-0x2f*/ + 0xbda2, 0xb2d5, 0xc57a, 0xf4b6, 0xf4b7, 0xb6e6, 0xb2b0, 0xcfcf, /*0x30-0x37*/ + 0xf4b4, 0xb4ac, 0xc57b, 0xf4b5, 0xc57c, 0xc57d, 0xf4b8, 0xc57e, /*0x38-0x3f*/ + 0xc580, 0xc581, 0xc582, 0xc583, 0xf4b9, 0xc584, 0xc585, 0xcda7, /*0x40-0x47*/ + 0xc586, 0xf4ba, 0xc587, 0xf4bb, 0xc588, 0xc589, 0xc58a, 0xf4bc, /*0x48-0x4f*/ + 0xc58b, 0xc58c, 0xc58d, 0xc58e, 0xc58f, 0xc590, 0xc591, 0xc592, /*0x50-0x57*/ + 0xcbd2, 0xc593, 0xf4bd, 0xc594, 0xc595, 0xc596, 0xc597, 0xf4be, /*0x58-0x5f*/ + 0xc598, 0xc599, 0xc59a, 0xc59b, 0xc59c, 0xc59d, 0xc59e, 0xc59f, /*0x60-0x67*/ + 0xf4bf, 0xc5a0, 0xc640, 0xc641, 0xc642, 0xc643, 0xf4de, 0xc1bc, /*0x68-0x6f*/ + 0xbce8, 0xc644, 0xc9ab, 0xd1de, 0xe5f5, 0xc645, 0xc646, 0xc647, /*0x70-0x77*/ + 0xc648, 0xdcb3, 0xd2d5, 0xc649, 0xc64a, 0xdcb4, 0xb0ac, 0xdcb5, /*0x78-0x7f*/ + 0xc64b, 0xc64c, 0xbdda, 0xc64d, 0xdcb9, 0xc64e, 0xc64f, 0xc650, /*0x80-0x87*/ + 0xd8c2, 0xc651, 0xdcb7, 0xd3f3, 0xc652, 0xc9d6, 0xdcba, 0xdcb6, /*0x88-0x8f*/ + 0xc653, 0xdcbb, 0xc3a2, 0xc654, 0xc655, 0xc656, 0xc657, 0xdcbc, /*0x90-0x97*/ + 0xdcc5, 0xdcbd, 0xc658, 0xc659, 0xcedf, 0xd6a5, 0xc65a, 0xdccf, /*0x98-0x9f*/ + 0xc65b, 0xdccd, 0xc65c, 0xc65d, 0xdcd2, 0xbde6, 0xc2ab, 0xc65e, /*0xa0-0xa7*/ + 0xdcb8, 0xdccb, 0xdcce, 0xdcbe, 0xb7d2, 0xb0c5, 0xdcc7, 0xd0be, /*0xa8-0xaf*/ + 0xdcc1, 0xbba8, 0xc65f, 0xb7bc, 0xdccc, 0xc660, 0xc661, 0xdcc6, /*0xb0-0xb7*/ + 0xdcbf, 0xc7db, 0xc662, 0xc663, 0xc664, 0xd1bf, 0xdcc0, 0xc665, /*0xb8-0xbf*/ + 0xc666, 0xdcca, 0xc667, 0xc668, 0xdcd0, 0xc669, 0xc66a, 0xcead, /*0xc0-0xc7*/ + 0xdcc2, 0xc66b, 0xdcc3, 0xdcc8, 0xdcc9, 0xb2d4, 0xdcd1, 0xcbd5, /*0xc8-0xcf*/ + 0xc66c, 0xd4b7, 0xdcdb, 0xdcdf, 0xcca6, 0xdce6, 0xc66d, 0xc3e7, /*0xd0-0xd7*/ + 0xdcdc, 0xc66e, 0xc66f, 0xbfc1, 0xdcd9, 0xc670, 0xb0fa, 0xb9b6, /*0xd8-0xdf*/ + 0xdce5, 0xdcd3, 0xc671, 0xdcc4, 0xdcd6, 0xc8f4, 0xbfe0, 0xc672, /*0xe0-0xe7*/ + 0xc673, 0xc674, 0xc675, 0xc9bb, 0xc676, 0xc677, 0xc678, 0xb1bd, /*0xe8-0xef*/ + 0xc679, 0xd3a2, 0xc67a, 0xc67b, 0xdcda, 0xc67c, 0xc67d, 0xdcd5, /*0xf0-0xf7*/ + 0xc67e, 0xc6bb, 0xc680, 0xdcde, 0xc681, 0xc682, 0xc683, 0xc684, /*0xf8-0xff*/ + /* 0x8300 */ + 0xc685, 0xd7c2, 0xc3af, 0xb7b6, 0xc7d1, 0xc3a9, 0xdce2, 0xdcd8, /*0x00-0x07*/ + 0xdceb, 0xdcd4, 0xc686, 0xc687, 0xdcdd, 0xc688, 0xbea5, 0xdcd7, /*0x08-0x0f*/ + 0xc689, 0xdce0, 0xc68a, 0xc68b, 0xdce3, 0xdce4, 0xc68c, 0xdcf8, /*0x10-0x17*/ + 0xc68d, 0xc68e, 0xdce1, 0xdda2, 0xdce7, 0xc68f, 0xc690, 0xc691, /*0x18-0x1f*/ + 0xc692, 0xc693, 0xc694, 0xc695, 0xc696, 0xc697, 0xc698, 0xbceb, /*0x20-0x27*/ + 0xb4c4, 0xc699, 0xc69a, 0xc3a3, 0xb2e7, 0xdcfa, 0xc69b, 0xdcf2, /*0x28-0x2f*/ + 0xc69c, 0xdcef, 0xc69d, 0xdcfc, 0xdcee, 0xd2f0, 0xb2e8, 0xc69e, /*0x30-0x37*/ + 0xc8d7, 0xc8e3, 0xdcfb, 0xc69f, 0xdced, 0xc6a0, 0xc740, 0xc741, /*0x38-0x3f*/ + 0xdcf7, 0xc742, 0xc743, 0xdcf5, 0xc744, 0xc745, 0xbea3, 0xdcf4, /*0x40-0x47*/ + 0xc746, 0xb2dd, 0xc747, 0xc748, 0xc749, 0xc74a, 0xc74b, 0xdcf3, /*0x48-0x4f*/ + 0xbcf6, 0xdce8, 0xbbc4, 0xc74c, 0xc0f3, 0xc74d, 0xc74e, 0xc74f, /*0x50-0x57*/ + 0xc750, 0xc751, 0xbcd4, 0xdce9, 0xdcea, 0xc752, 0xdcf1, 0xdcf6, /*0x58-0x5f*/ + 0xdcf9, 0xb5b4, 0xc753, 0xc8d9, 0xbbe7, 0xdcfe, 0xdcfd, 0xd3ab, /*0x60-0x67*/ + 0xdda1, 0xdda3, 0xdda5, 0xd2f1, 0xdda4, 0xdda6, 0xdda7, 0xd2a9, /*0x68-0x6f*/ + 0xc754, 0xc755, 0xc756, 0xc757, 0xc758, 0xc759, 0xc75a, 0xbac9, /*0x70-0x77*/ + 0xdda9, 0xc75b, 0xc75c, 0xddb6, 0xddb1, 0xddb4, 0xc75d, 0xc75e, /*0x78-0x7f*/ + 0xc75f, 0xc760, 0xc761, 0xc762, 0xc763, 0xddb0, 0xc6ce, 0xc764, /*0x80-0x87*/ + 0xc765, 0xc0f2, 0xc766, 0xc767, 0xc768, 0xc769, 0xc9af, 0xc76a, /*0x88-0x8f*/ + 0xc76b, 0xc76c, 0xdcec, 0xddae, 0xc76d, 0xc76e, 0xc76f, 0xc770, /*0x90-0x97*/ + 0xddb7, 0xc771, 0xc772, 0xdcf0, 0xddaf, 0xc773, 0xddb8, 0xc774, /*0x98-0x9f*/ + 0xddac, 0xc775, 0xc776, 0xc777, 0xc778, 0xc779, 0xc77a, 0xc77b, /*0xa0-0xa7*/ + 0xddb9, 0xddb3, 0xddad, 0xc4aa, 0xc77c, 0xc77d, 0xc77e, 0xc780, /*0xa8-0xaf*/ + 0xdda8, 0xc0b3, 0xc1ab, 0xddaa, 0xddab, 0xc781, 0xddb2, 0xbbf1, /*0xb0-0xb7*/ + 0xddb5, 0xd3a8, 0xddba, 0xc782, 0xddbb, 0xc3a7, 0xc783, 0xc784, /*0xb8-0xbf*/ + 0xddd2, 0xddbc, 0xc785, 0xc786, 0xc787, 0xddd1, 0xc788, 0xb9bd, /*0xc0-0xc7*/ + 0xc789, 0xc78a, 0xbed5, 0xc78b, 0xbefa, 0xc78c, 0xc78d, 0xbaca, /*0xc8-0xcf*/ + 0xc78e, 0xc78f, 0xc790, 0xc791, 0xddca, 0xc792, 0xddc5, 0xc793, /*0xd0-0xd7*/ + 0xddbf, 0xc794, 0xc795, 0xc796, 0xb2cb, 0xddc3, 0xc797, 0xddcb, /*0xd8-0xdf*/ + 0xb2a4, 0xddd5, 0xc798, 0xc799, 0xc79a, 0xddbe, 0xc79b, 0xc79c, /*0xe0-0xe7*/ + 0xc79d, 0xc6d0, 0xddd0, 0xc79e, 0xc79f, 0xc7a0, 0xc840, 0xc841, /*0xe8-0xef*/ + 0xddd4, 0xc1e2, 0xb7c6, 0xc842, 0xc843, 0xc844, 0xc845, 0xc846, /*0xf0-0xf7*/ + 0xddce, 0xddcf, 0xc847, 0xc848, 0xc849, 0xddc4, 0xc84a, 0xc84b, /*0xf8-0xff*/ + /* 0x8400 */ + 0xc84c, 0xddbd, 0xc84d, 0xddcd, 0xccd1, 0xc84e, 0xddc9, 0xc84f, /*0x00-0x07*/ + 0xc850, 0xc851, 0xc852, 0xddc2, 0xc3c8, 0xc6bc, 0xceae, 0xddcc, /*0x08-0x0f*/ + 0xc853, 0xddc8, 0xc854, 0xc855, 0xc856, 0xc857, 0xc858, 0xc859, /*0x10-0x17*/ + 0xddc1, 0xc85a, 0xc85b, 0xc85c, 0xddc6, 0xc2dc, 0xc85d, 0xc85e, /*0x18-0x1f*/ + 0xc85f, 0xc860, 0xc861, 0xc862, 0xd3a9, 0xd3aa, 0xddd3, 0xcff4, /*0x20-0x27*/ + 0xc8f8, 0xc863, 0xc864, 0xc865, 0xc866, 0xc867, 0xc868, 0xc869, /*0x28-0x2f*/ + 0xc86a, 0xdde6, 0xc86b, 0xc86c, 0xc86d, 0xc86e, 0xc86f, 0xc870, /*0x30-0x37*/ + 0xddc7, 0xc871, 0xc872, 0xc873, 0xdde0, 0xc2e4, 0xc874, 0xc875, /*0x38-0x3f*/ + 0xc876, 0xc877, 0xc878, 0xc879, 0xc87a, 0xc87b, 0xdde1, 0xc87c, /*0x40-0x47*/ + 0xc87d, 0xc87e, 0xc880, 0xc881, 0xc882, 0xc883, 0xc884, 0xc885, /*0x48-0x4f*/ + 0xc886, 0xddd7, 0xc887, 0xc888, 0xc889, 0xc88a, 0xc88b, 0xd6f8, /*0x50-0x57*/ + 0xc88c, 0xddd9, 0xddd8, 0xb8f0, 0xddd6, 0xc88d, 0xc88e, 0xc88f, /*0x58-0x5f*/ + 0xc890, 0xc6cf, 0xc891, 0xb6ad, 0xc892, 0xc893, 0xc894, 0xc895, /*0x60-0x67*/ + 0xc896, 0xdde2, 0xc897, 0xbaf9, 0xd4e1, 0xdde7, 0xc898, 0xc899, /*0x68-0x6f*/ + 0xc89a, 0xb4d0, 0xc89b, 0xddda, 0xc89c, 0xbffb, 0xdde3, 0xc89d, /*0x70-0x77*/ + 0xdddf, 0xc89e, 0xdddd, 0xc89f, 0xc8a0, 0xc940, 0xc941, 0xc942, /*0x78-0x7f*/ + 0xc943, 0xc944, 0xb5d9, 0xc945, 0xc946, 0xc947, 0xc948, 0xdddb, /*0x80-0x87*/ + 0xdddc, 0xddde, 0xc949, 0xbdaf, 0xdde4, 0xc94a, 0xdde5, 0xc94b, /*0x88-0x8f*/ + 0xc94c, 0xc94d, 0xc94e, 0xc94f, 0xc950, 0xc951, 0xc952, 0xddf5, /*0x90-0x97*/ + 0xc953, 0xc3c9, 0xc954, 0xc955, 0xcbe2, 0xc956, 0xc957, 0xc958, /*0x98-0x9f*/ + 0xc959, 0xddf2, 0xc95a, 0xc95b, 0xc95c, 0xc95d, 0xc95e, 0xc95f, /*0xa0-0xa7*/ + 0xc960, 0xc961, 0xc962, 0xc963, 0xc964, 0xc965, 0xc966, 0xd8e1, /*0xa8-0xaf*/ + 0xc967, 0xc968, 0xc6d1, 0xc969, 0xddf4, 0xc96a, 0xc96b, 0xc96c, /*0xb0-0xb7*/ + 0xd5f4, 0xddf3, 0xddf0, 0xc96d, 0xc96e, 0xddec, 0xc96f, 0xddef, /*0xb8-0xbf*/ + 0xc970, 0xdde8, 0xc971, 0xc972, 0xd0ee, 0xc973, 0xc974, 0xc975, /*0xc0-0xc7*/ + 0xc976, 0xc8d8, 0xddee, 0xc977, 0xc978, 0xdde9, 0xc979, 0xc97a, /*0xc8-0xcf*/ + 0xddea, 0xcbf2, 0xc97b, 0xdded, 0xc97c, 0xc97d, 0xb1cd, 0xc97e, /*0xd0-0xd7*/ + 0xc980, 0xc981, 0xc982, 0xc983, 0xc984, 0xc0b6, 0xc985, 0xbcbb, /*0xd8-0xdf*/ + 0xddf1, 0xc986, 0xc987, 0xddf7, 0xc988, 0xddf6, 0xddeb, 0xc989, /*0xe0-0xe7*/ + 0xc98a, 0xc98b, 0xc98c, 0xc98d, 0xc5ee, 0xc98e, 0xc98f, 0xc990, /*0xe8-0xef*/ + 0xddfb, 0xc991, 0xc992, 0xc993, 0xc994, 0xc995, 0xc996, 0xc997, /*0xf0-0xf7*/ + 0xc998, 0xc999, 0xc99a, 0xc99b, 0xdea4, 0xc99c, 0xc99d, 0xdea3, /*0xf8-0xff*/ + /* 0x8500 */ + 0xc99e, 0xc99f, 0xc9a0, 0xca40, 0xca41, 0xca42, 0xca43, 0xca44, /*0x00-0x07*/ + 0xca45, 0xca46, 0xca47, 0xca48, 0xddf8, 0xca49, 0xca4a, 0xca4b, /*0x08-0x0f*/ + 0xca4c, 0xc3ef, 0xca4d, 0xc2fb, 0xca4e, 0xca4f, 0xca50, 0xd5e1, /*0x10-0x17*/ + 0xca51, 0xca52, 0xceb5, 0xca53, 0xca54, 0xca55, 0xca56, 0xddfd, /*0x18-0x1f*/ + 0xca57, 0xb2cc, 0xca58, 0xca59, 0xca5a, 0xca5b, 0xca5c, 0xca5d, /*0x20-0x27*/ + 0xca5e, 0xca5f, 0xca60, 0xc4e8, 0xcadf, 0xca61, 0xca62, 0xca63, /*0x28-0x2f*/ + 0xca64, 0xca65, 0xca66, 0xca67, 0xca68, 0xca69, 0xca6a, 0xc7be, /*0x30-0x37*/ + 0xddfa, 0xddfc, 0xddfe, 0xdea2, 0xb0aa, 0xb1ce, 0xca6b, 0xca6c, /*0x38-0x3f*/ + 0xca6d, 0xca6e, 0xca6f, 0xdeac, 0xca70, 0xca71, 0xca72, 0xca73, /*0x40-0x47*/ + 0xdea6, 0xbdb6, 0xc8ef, 0xca74, 0xca75, 0xca76, 0xca77, 0xca78, /*0x48-0x4f*/ + 0xca79, 0xca7a, 0xca7b, 0xca7c, 0xca7d, 0xca7e, 0xdea1, 0xca80, /*0x50-0x57*/ + 0xca81, 0xdea5, 0xca82, 0xca83, 0xca84, 0xca85, 0xdea9, 0xca86, /*0x58-0x5f*/ + 0xca87, 0xca88, 0xca89, 0xca8a, 0xdea8, 0xca8b, 0xca8c, 0xca8d, /*0x60-0x67*/ + 0xdea7, 0xca8e, 0xca8f, 0xca90, 0xca91, 0xca92, 0xca93, 0xca94, /*0x68-0x6f*/ + 0xca95, 0xca96, 0xdead, 0xca97, 0xd4cc, 0xca98, 0xca99, 0xca9a, /*0x70-0x77*/ + 0xca9b, 0xdeb3, 0xdeaa, 0xdeae, 0xca9c, 0xca9d, 0xc0d9, 0xca9e, /*0x78-0x7f*/ + 0xca9f, 0xcaa0, 0xcb40, 0xcb41, 0xb1a1, 0xdeb6, 0xcb42, 0xdeb1, /*0x80-0x87*/ + 0xcb43, 0xcb44, 0xcb45, 0xcb46, 0xcb47, 0xcb48, 0xcb49, 0xdeb2, /*0x88-0x8f*/ + 0xcb4a, 0xcb4b, 0xcb4c, 0xcb4d, 0xcb4e, 0xcb4f, 0xcb50, 0xcb51, /*0x90-0x97*/ + 0xcb52, 0xcb53, 0xcb54, 0xd1a6, 0xdeb5, 0xcb55, 0xcb56, 0xcb57, /*0x98-0x9f*/ + 0xcb58, 0xcb59, 0xcb5a, 0xcb5b, 0xdeaf, 0xcb5c, 0xcb5d, 0xcb5e, /*0xa0-0xa7*/ + 0xdeb0, 0xcb5f, 0xd0bd, 0xcb60, 0xcb61, 0xcb62, 0xdeb4, 0xcaed, /*0xa8-0xaf*/ + 0xdeb9, 0xcb63, 0xcb64, 0xcb65, 0xcb66, 0xcb67, 0xcb68, 0xdeb8, /*0xb0-0xb7*/ + 0xcb69, 0xdeb7, 0xcb6a, 0xcb6b, 0xcb6c, 0xcb6d, 0xcb6e, 0xcb6f, /*0xb8-0xbf*/ + 0xcb70, 0xdebb, 0xcb71, 0xcb72, 0xcb73, 0xcb74, 0xcb75, 0xcb76, /*0xc0-0xc7*/ + 0xcb77, 0xbde5, 0xcb78, 0xcb79, 0xcb7a, 0xcb7b, 0xcb7c, 0xb2d8, /*0xc8-0xcf*/ + 0xc3ea, 0xcb7d, 0xcb7e, 0xdeba, 0xcb80, 0xc5ba, 0xcb81, 0xcb82, /*0xd0-0xd7*/ + 0xcb83, 0xcb84, 0xcb85, 0xcb86, 0xdebc, 0xcb87, 0xcb88, 0xcb89, /*0xd8-0xdf*/ + 0xcb8a, 0xcb8b, 0xcb8c, 0xcb8d, 0xccd9, 0xcb8e, 0xcb8f, 0xcb90, /*0xe0-0xe7*/ + 0xcb91, 0xb7aa, 0xcb92, 0xcb93, 0xcb94, 0xcb95, 0xcb96, 0xcb97, /*0xe8-0xef*/ + 0xcb98, 0xcb99, 0xcb9a, 0xcb9b, 0xcb9c, 0xcb9d, 0xcb9e, 0xcb9f, /*0xf0-0xf7*/ + 0xcba0, 0xcc40, 0xcc41, 0xd4e5, 0xcc42, 0xcc43, 0xcc44, 0xdebd, /*0xf8-0xff*/ + /* 0x8600 */ + 0xcc45, 0xcc46, 0xcc47, 0xcc48, 0xcc49, 0xdebf, 0xcc4a, 0xcc4b, /*0x00-0x07*/ + 0xcc4c, 0xcc4d, 0xcc4e, 0xcc4f, 0xcc50, 0xcc51, 0xcc52, 0xcc53, /*0x08-0x0f*/ + 0xcc54, 0xc4a2, 0xcc55, 0xcc56, 0xcc57, 0xcc58, 0xdec1, 0xcc59, /*0x10-0x17*/ + 0xcc5a, 0xcc5b, 0xcc5c, 0xcc5d, 0xcc5e, 0xcc5f, 0xcc60, 0xcc61, /*0x18-0x1f*/ + 0xcc62, 0xcc63, 0xcc64, 0xcc65, 0xcc66, 0xcc67, 0xcc68, 0xdebe, /*0x20-0x27*/ + 0xcc69, 0xdec0, 0xcc6a, 0xcc6b, 0xcc6c, 0xcc6d, 0xcc6e, 0xcc6f, /*0x28-0x2f*/ + 0xcc70, 0xcc71, 0xcc72, 0xcc73, 0xcc74, 0xcc75, 0xcc76, 0xcc77, /*0x30-0x37*/ + 0xd5ba, 0xcc78, 0xcc79, 0xcc7a, 0xdec2, 0xcc7b, 0xcc7c, 0xcc7d, /*0x38-0x3f*/ + 0xcc7e, 0xcc80, 0xcc81, 0xcc82, 0xcc83, 0xcc84, 0xcc85, 0xcc86, /*0x40-0x47*/ + 0xcc87, 0xcc88, 0xcc89, 0xcc8a, 0xcc8b, 0xf2ae, 0xbba2, 0xc2b2, /*0x48-0x4f*/ + 0xc5b0, 0xc2c7, 0xcc8c, 0xcc8d, 0xf2af, 0xcc8e, 0xcc8f, 0xcc90, /*0x50-0x57*/ + 0xcc91, 0xcc92, 0xd0e9, 0xcc93, 0xcc94, 0xcc95, 0xd3dd, 0xcc96, /*0x58-0x5f*/ + 0xcc97, 0xcc98, 0xebbd, 0xcc99, 0xcc9a, 0xcc9b, 0xcc9c, 0xcc9d, /*0x60-0x67*/ + 0xcc9e, 0xcc9f, 0xcca0, 0xb3e6, 0xf2b0, 0xcd40, 0xf2b1, 0xcd41, /*0x68-0x6f*/ + 0xcd42, 0xcaad, 0xcd43, 0xcd44, 0xcd45, 0xcd46, 0xcd47, 0xcd48, /*0x70-0x77*/ + 0xcd49, 0xbae7, 0xf2b3, 0xf2b5, 0xf2b4, 0xcbe4, 0xcfba, 0xf2b2, /*0x78-0x7f*/ + 0xcab4, 0xd2cf, 0xc2ec, 0xcd4a, 0xcd4b, 0xcd4c, 0xcd4d, 0xcd4e, /*0x80-0x87*/ + 0xcd4f, 0xcd50, 0xcec3, 0xf2b8, 0xb0f6, 0xf2b7, 0xcd51, 0xcd52, /*0x88-0x8f*/ + 0xcd53, 0xcd54, 0xcd55, 0xf2be, 0xcd56, 0xb2cf, 0xcd57, 0xcd58, /*0x90-0x97*/ + 0xcd59, 0xcd5a, 0xcd5b, 0xcd5c, 0xd1c1, 0xf2ba, 0xcd5d, 0xcd5e, /*0x98-0x9f*/ + 0xcd5f, 0xcd60, 0xcd61, 0xf2bc, 0xd4e9, 0xcd62, 0xcd63, 0xf2bb, /*0xa0-0xa7*/ + 0xf2b6, 0xf2bf, 0xf2bd, 0xcd64, 0xf2b9, 0xcd65, 0xcd66, 0xf2c7, /*0xa8-0xaf*/ + 0xf2c4, 0xf2c6, 0xcd67, 0xcd68, 0xf2ca, 0xf2c2, 0xf2c0, 0xcd69, /*0xb0-0xb7*/ + 0xcd6a, 0xcd6b, 0xf2c5, 0xcd6c, 0xcd6d, 0xcd6e, 0xcd6f, 0xcd70, /*0xb8-0xbf*/ + 0xd6fb, 0xcd71, 0xcd72, 0xcd73, 0xf2c1, 0xcd74, 0xc7f9, 0xc9df, /*0xc0-0xc7*/ + 0xcd75, 0xf2c8, 0xb9c6, 0xb5b0, 0xcd76, 0xcd77, 0xf2c3, 0xf2c9, /*0xc8-0xcf*/ + 0xf2d0, 0xf2d6, 0xcd78, 0xcd79, 0xbbd7, 0xcd7a, 0xcd7b, 0xcd7c, /*0xd0-0xd7*/ + 0xf2d5, 0xcddc, 0xcd7d, 0xd6eb, 0xcd7e, 0xcd80, 0xf2d2, 0xf2d4, /*0xd8-0xdf*/ + 0xcd81, 0xcd82, 0xcd83, 0xcd84, 0xb8f2, 0xcd85, 0xcd86, 0xcd87, /*0xe0-0xe7*/ + 0xcd88, 0xf2cb, 0xcd89, 0xcd8a, 0xcd8b, 0xf2ce, 0xc2f9, 0xcd8c, /*0xe8-0xef*/ + 0xd5dd, 0xf2cc, 0xf2cd, 0xf2cf, 0xf2d3, 0xcd8d, 0xcd8e, 0xcd8f, /*0xf0-0xf7*/ + 0xf2d9, 0xd3bc, 0xcd90, 0xcd91, 0xcd92, 0xcd93, 0xb6ea, 0xcd94, /*0xf8-0xff*/ + /* 0x8700 */ + 0xcaf1, 0xcd95, 0xb7e4, 0xf2d7, 0xcd96, 0xcd97, 0xcd98, 0xf2d8, /*0x00-0x07*/ + 0xf2da, 0xf2dd, 0xf2db, 0xcd99, 0xcd9a, 0xf2dc, 0xcd9b, 0xcd9c, /*0x08-0x0f*/ + 0xcd9d, 0xcd9e, 0xd1d1, 0xf2d1, 0xcd9f, 0xcdc9, 0xcda0, 0xcecf, /*0x10-0x17*/ + 0xd6a9, 0xce40, 0xf2e3, 0xce41, 0xc3db, 0xce42, 0xf2e0, 0xce43, /*0x18-0x1f*/ + 0xce44, 0xc0af, 0xf2ec, 0xf2de, 0xce45, 0xf2e1, 0xce46, 0xce47, /*0x20-0x27*/ + 0xce48, 0xf2e8, 0xce49, 0xce4a, 0xce4b, 0xce4c, 0xf2e2, 0xce4d, /*0x28-0x2f*/ + 0xce4e, 0xf2e7, 0xce4f, 0xce50, 0xf2e6, 0xce51, 0xce52, 0xf2e9, /*0x30-0x37*/ + 0xce53, 0xce54, 0xce55, 0xf2df, 0xce56, 0xce57, 0xf2e4, 0xf2ea, /*0x38-0x3f*/ + 0xce58, 0xce59, 0xce5a, 0xce5b, 0xce5c, 0xce5d, 0xce5e, 0xd3ac, /*0x40-0x47*/ + 0xf2e5, 0xb2f5, 0xce5f, 0xce60, 0xf2f2, 0xce61, 0xd0ab, 0xce62, /*0x48-0x4f*/ + 0xce63, 0xce64, 0xce65, 0xf2f5, 0xce66, 0xce67, 0xce68, 0xbbc8, /*0x50-0x57*/ + 0xce69, 0xf2f9, 0xce6a, 0xce6b, 0xce6c, 0xce6d, 0xce6e, 0xce6f, /*0x58-0x5f*/ + 0xf2f0, 0xce70, 0xce71, 0xf2f6, 0xf2f8, 0xf2fa, 0xce72, 0xce73, /*0x60-0x67*/ + 0xce74, 0xce75, 0xce76, 0xce77, 0xce78, 0xce79, 0xf2f3, 0xce7a, /*0x68-0x6f*/ + 0xf2f1, 0xce7b, 0xce7c, 0xce7d, 0xbafb, 0xce7e, 0xb5fb, 0xce80, /*0x70-0x77*/ + 0xce81, 0xce82, 0xce83, 0xf2ef, 0xf2f7, 0xf2ed, 0xf2ee, 0xce84, /*0x78-0x7f*/ + 0xce85, 0xce86, 0xf2eb, 0xf3a6, 0xce87, 0xf3a3, 0xce88, 0xce89, /*0x80-0x87*/ + 0xf3a2, 0xce8a, 0xce8b, 0xf2f4, 0xce8c, 0xc8da, 0xce8d, 0xce8e, /*0x88-0x8f*/ + 0xce8f, 0xce90, 0xce91, 0xf2fb, 0xce92, 0xce93, 0xce94, 0xf3a5, /*0x90-0x97*/ + 0xce95, 0xce96, 0xce97, 0xce98, 0xce99, 0xce9a, 0xce9b, 0xc3f8, /*0x98-0x9f*/ + 0xce9c, 0xce9d, 0xce9e, 0xce9f, 0xcea0, 0xcf40, 0xcf41, 0xcf42, /*0xa0-0xa7*/ + 0xf2fd, 0xcf43, 0xcf44, 0xf3a7, 0xf3a9, 0xf3a4, 0xcf45, 0xf2fc, /*0xa8-0xaf*/ + 0xcf46, 0xcf47, 0xcf48, 0xf3ab, 0xcf49, 0xf3aa, 0xcf4a, 0xcf4b, /*0xb0-0xb7*/ + 0xcf4c, 0xcf4d, 0xc2dd, 0xcf4e, 0xcf4f, 0xf3ae, 0xcf50, 0xcf51, /*0xb8-0xbf*/ + 0xf3b0, 0xcf52, 0xcf53, 0xcf54, 0xcf55, 0xcf56, 0xf3a1, 0xcf57, /*0xc0-0xc7*/ + 0xcf58, 0xcf59, 0xf3b1, 0xf3ac, 0xcf5a, 0xcf5b, 0xcf5c, 0xcf5d, /*0xc8-0xcf*/ + 0xcf5e, 0xf3af, 0xf2fe, 0xf3ad, 0xcf5f, 0xcf60, 0xcf61, 0xcf62, /*0xd0-0xd7*/ + 0xcf63, 0xcf64, 0xcf65, 0xf3b2, 0xcf66, 0xcf67, 0xcf68, 0xcf69, /*0xd8-0xdf*/ + 0xf3b4, 0xcf6a, 0xcf6b, 0xcf6c, 0xcf6d, 0xf3a8, 0xcf6e, 0xcf6f, /*0xe0-0xe7*/ + 0xcf70, 0xcf71, 0xf3b3, 0xcf72, 0xcf73, 0xcf74, 0xf3b5, 0xcf75, /*0xe8-0xef*/ + 0xcf76, 0xcf77, 0xcf78, 0xcf79, 0xcf7a, 0xcf7b, 0xcf7c, 0xcf7d, /*0xf0-0xf7*/ + 0xcf7e, 0xd0b7, 0xcf80, 0xcf81, 0xcf82, 0xcf83, 0xf3b8, 0xcf84, /*0xf8-0xff*/ + /* 0x8800 */ + 0xcf85, 0xcf86, 0xcf87, 0xd9f9, 0xcf88, 0xcf89, 0xcf8a, 0xcf8b, /*0x00-0x07*/ + 0xcf8c, 0xcf8d, 0xf3b9, 0xcf8e, 0xcf8f, 0xcf90, 0xcf91, 0xcf92, /*0x08-0x0f*/ + 0xcf93, 0xcf94, 0xcf95, 0xf3b7, 0xcf96, 0xc8e4, 0xf3b6, 0xcf97, /*0x10-0x17*/ + 0xcf98, 0xcf99, 0xcf9a, 0xf3ba, 0xcf9b, 0xcf9c, 0xcf9d, 0xcf9e, /*0x18-0x1f*/ + 0xcf9f, 0xf3bb, 0xb4c0, 0xcfa0, 0xd040, 0xd041, 0xd042, 0xd043, /*0x20-0x27*/ + 0xd044, 0xd045, 0xd046, 0xd047, 0xd048, 0xd049, 0xd04a, 0xd04b, /*0x28-0x2f*/ + 0xd04c, 0xd04d, 0xeec3, 0xd04e, 0xd04f, 0xd050, 0xd051, 0xd052, /*0x30-0x37*/ + 0xd053, 0xf3bc, 0xd054, 0xd055, 0xf3bd, 0xd056, 0xd057, 0xd058, /*0x38-0x3f*/ + 0xd1aa, 0xd059, 0xd05a, 0xd05b, 0xf4ac, 0xd0c6, 0xd05c, 0xd05d, /*0x40-0x47*/ + 0xd05e, 0xd05f, 0xd060, 0xd061, 0xd0d0, 0xd1dc, 0xd062, 0xd063, /*0x48-0x4f*/ + 0xd064, 0xd065, 0xd066, 0xd067, 0xcfce, 0xd068, 0xd069, 0xbdd6, /*0x50-0x57*/ + 0xd06a, 0xd1c3, 0xd06b, 0xd06c, 0xd06d, 0xd06e, 0xd06f, 0xd070, /*0x58-0x5f*/ + 0xd071, 0xbae2, 0xe1e9, 0xd2c2, 0xf1c2, 0xb2b9, 0xd072, 0xd073, /*0x60-0x67*/ + 0xb1ed, 0xf1c3, 0xd074, 0xc9c0, 0xb3c4, 0xd075, 0xd9f2, 0xd076, /*0x68-0x6f*/ + 0xcba5, 0xd077, 0xf1c4, 0xd078, 0xd079, 0xd07a, 0xd07b, 0xd6d4, /*0x70-0x77*/ + 0xd07c, 0xd07d, 0xd07e, 0xd080, 0xd081, 0xf1c5, 0xf4c0, 0xf1c6, /*0x78-0x7f*/ + 0xd082, 0xd4ac, 0xf1c7, 0xd083, 0xb0c0, 0xf4c1, 0xd084, 0xd085, /*0x80-0x87*/ + 0xf4c2, 0xd086, 0xd087, 0xb4fc, 0xd088, 0xc5db, 0xd089, 0xd08a, /*0x88-0x8f*/ + 0xd08b, 0xd08c, 0xccbb, 0xd08d, 0xd08e, 0xd08f, 0xd0e4, 0xd090, /*0x90-0x97*/ + 0xd091, 0xd092, 0xd093, 0xd094, 0xcde0, 0xd095, 0xd096, 0xd097, /*0x98-0x9f*/ + 0xd098, 0xd099, 0xf1c8, 0xd09a, 0xd9f3, 0xd09b, 0xd09c, 0xd09d, /*0xa0-0xa7*/ + 0xd09e, 0xd09f, 0xd0a0, 0xb1bb, 0xd140, 0xcfae, 0xd141, 0xd142, /*0xa8-0xaf*/ + 0xd143, 0xb8a4, 0xd144, 0xd145, 0xd146, 0xd147, 0xd148, 0xf1ca, /*0xb0-0xb7*/ + 0xd149, 0xd14a, 0xd14b, 0xd14c, 0xf1cb, 0xd14d, 0xd14e, 0xd14f, /*0xb8-0xbf*/ + 0xd150, 0xb2c3, 0xc1d1, 0xd151, 0xd152, 0xd7b0, 0xf1c9, 0xd153, /*0xc0-0xc7*/ + 0xd154, 0xf1cc, 0xd155, 0xd156, 0xd157, 0xd158, 0xf1ce, 0xd159, /*0xc8-0xcf*/ + 0xd15a, 0xd15b, 0xd9f6, 0xd15c, 0xd2e1, 0xd4a3, 0xd15d, 0xd15e, /*0xd0-0xd7*/ + 0xf4c3, 0xc8b9, 0xd15f, 0xd160, 0xd161, 0xd162, 0xd163, 0xf4c4, /*0xd8-0xdf*/ + 0xd164, 0xd165, 0xf1cd, 0xf1cf, 0xbfe3, 0xf1d0, 0xd166, 0xd167, /*0xe0-0xe7*/ + 0xf1d4, 0xd168, 0xd169, 0xd16a, 0xd16b, 0xd16c, 0xd16d, 0xd16e, /*0xe8-0xef*/ + 0xf1d6, 0xf1d1, 0xd16f, 0xc9d1, 0xc5e1, 0xd170, 0xd171, 0xd172, /*0xf0-0xf7*/ + 0xc2e3, 0xb9fc, 0xd173, 0xd174, 0xf1d3, 0xd175, 0xf1d5, 0xd176, /*0xf8-0xff*/ + /* 0x8900 */ + 0xd177, 0xd178, 0xb9d3, 0xd179, 0xd17a, 0xd17b, 0xd17c, 0xd17d, /*0x00-0x07*/ + 0xd17e, 0xd180, 0xf1db, 0xd181, 0xd182, 0xd183, 0xd184, 0xd185, /*0x08-0x0f*/ + 0xbad6, 0xd186, 0xb0fd, 0xf1d9, 0xd187, 0xd188, 0xd189, 0xd18a, /*0x10-0x17*/ + 0xd18b, 0xf1d8, 0xf1d2, 0xf1da, 0xd18c, 0xd18d, 0xd18e, 0xd18f, /*0x18-0x1f*/ + 0xd190, 0xf1d7, 0xd191, 0xd192, 0xd193, 0xc8ec, 0xd194, 0xd195, /*0x20-0x27*/ + 0xd196, 0xd197, 0xcdca, 0xf1dd, 0xd198, 0xd199, 0xd19a, 0xd19b, /*0x28-0x2f*/ + 0xe5bd, 0xd19c, 0xd19d, 0xd19e, 0xf1dc, 0xd19f, 0xf1de, 0xd1a0, /*0x30-0x37*/ + 0xd240, 0xd241, 0xd242, 0xd243, 0xd244, 0xd245, 0xd246, 0xd247, /*0x38-0x3f*/ + 0xd248, 0xf1df, 0xd249, 0xd24a, 0xcfe5, 0xd24b, 0xd24c, 0xd24d, /*0x40-0x47*/ + 0xd24e, 0xd24f, 0xd250, 0xd251, 0xd252, 0xd253, 0xd254, 0xd255, /*0x48-0x4f*/ + 0xd256, 0xd257, 0xd258, 0xd259, 0xd25a, 0xd25b, 0xd25c, 0xd25d, /*0x50-0x57*/ + 0xd25e, 0xd25f, 0xd260, 0xd261, 0xd262, 0xd263, 0xf4c5, 0xbdf3, /*0x58-0x5f*/ + 0xd264, 0xd265, 0xd266, 0xd267, 0xd268, 0xd269, 0xf1e0, 0xd26a, /*0x60-0x67*/ + 0xd26b, 0xd26c, 0xd26d, 0xd26e, 0xd26f, 0xd270, 0xd271, 0xd272, /*0x68-0x6f*/ + 0xd273, 0xd274, 0xd275, 0xd276, 0xd277, 0xd278, 0xd279, 0xd27a, /*0x70-0x77*/ + 0xd27b, 0xd27c, 0xd27d, 0xf1e1, 0xd27e, 0xd280, 0xd281, 0xcef7, /*0x78-0x7f*/ + 0xd282, 0xd2aa, 0xd283, 0xf1fb, 0xd284, 0xd285, 0xb8b2, 0xd286, /*0x80-0x87*/ + 0xd287, 0xd288, 0xd289, 0xd28a, 0xd28b, 0xd28c, 0xd28d, 0xd28e, /*0x88-0x8f*/ + 0xd28f, 0xd290, 0xd291, 0xd292, 0xd293, 0xd294, 0xd295, 0xd296, /*0x90-0x97*/ + 0xd297, 0xd298, 0xd299, 0xd29a, 0xd29b, 0xd29c, 0xd29d, 0xd29e, /*0x98-0x9f*/ + 0xd29f, 0xd2a0, 0xd340, 0xd341, 0xd342, 0xd343, 0xd344, 0xd345, /*0xa0-0xa7*/ + 0xd346, 0xd347, 0xd348, 0xd349, 0xd34a, 0xd34b, 0xd34c, 0xd34d, /*0xa8-0xaf*/ + 0xd34e, 0xd34f, 0xd350, 0xd351, 0xd352, 0xd353, 0xd354, 0xd355, /*0xb0-0xb7*/ + 0xd356, 0xd357, 0xd358, 0xd359, 0xd35a, 0xd35b, 0xd35c, 0xd35d, /*0xb8-0xbf*/ + 0xd35e, 0xbcfb, 0xb9db, 0xd35f, 0xb9e6, 0xc3d9, 0xcad3, 0xeae8, /*0xc0-0xc7*/ + 0xc0c0, 0xbef5, 0xeae9, 0xeaea, 0xeaeb, 0xd360, 0xeaec, 0xeaed, /*0xc8-0xcf*/ + 0xeaee, 0xeaef, 0xbdc7, 0xd361, 0xd362, 0xd363, 0xf5fb, 0xd364, /*0xd0-0xd7*/ + 0xd365, 0xd366, 0xf5fd, 0xd367, 0xf5fe, 0xd368, 0xf5fc, 0xd369, /*0xd8-0xdf*/ + 0xd36a, 0xd36b, 0xd36c, 0xbde2, 0xd36d, 0xf6a1, 0xb4a5, 0xd36e, /*0xe0-0xe7*/ + 0xd36f, 0xd370, 0xd371, 0xf6a2, 0xd372, 0xd373, 0xd374, 0xf6a3, /*0xe8-0xef*/ + 0xd375, 0xd376, 0xd377, 0xecb2, 0xd378, 0xd379, 0xd37a, 0xd37b, /*0xf0-0xf7*/ + 0xd37c, 0xd37d, 0xd37e, 0xd380, 0xd381, 0xd382, 0xd383, 0xd384, /*0xf8-0xff*/ + /* 0x8a00 */ + 0xd1d4, 0xd385, 0xd386, 0xd387, 0xd388, 0xd389, 0xd38a, 0xd9ea, /*0x00-0x07*/ + 0xd38b, 0xd38c, 0xd38d, 0xd38e, 0xd38f, 0xd390, 0xd391, 0xd392, /*0x08-0x0f*/ + 0xd393, 0xd394, 0xd395, 0xd396, 0xd397, 0xd398, 0xd399, 0xd39a, /*0x10-0x17*/ + 0xd39b, 0xd39c, 0xd39d, 0xd39e, 0xd39f, 0xd3a0, 0xd440, 0xd441, /*0x18-0x1f*/ + 0xd442, 0xd443, 0xd444, 0xd445, 0xd446, 0xd447, 0xd448, 0xd449, /*0x20-0x27*/ + 0xd44a, 0xd44b, 0xd44c, 0xd44d, 0xd44e, 0xd44f, 0xd450, 0xd451, /*0x28-0x2f*/ + 0xd452, 0xd453, 0xd454, 0xd455, 0xd456, 0xd457, 0xd458, 0xd459, /*0x30-0x37*/ + 0xd45a, 0xd45b, 0xd45c, 0xd45d, 0xd45e, 0xd45f, 0xf6a4, 0xd460, /*0x38-0x3f*/ + 0xd461, 0xd462, 0xd463, 0xd464, 0xd465, 0xd466, 0xd467, 0xd468, /*0x40-0x47*/ + 0xeeba, 0xd469, 0xd46a, 0xd46b, 0xd46c, 0xd46d, 0xd46e, 0xd46f, /*0x48-0x4f*/ + 0xd470, 0xd471, 0xd472, 0xd473, 0xd474, 0xd475, 0xd476, 0xd477, /*0x50-0x57*/ + 0xd478, 0xd479, 0xd47a, 0xd47b, 0xd47c, 0xd47d, 0xd47e, 0xd480, /*0x58-0x5f*/ + 0xd481, 0xd482, 0xd483, 0xd484, 0xd485, 0xd486, 0xd487, 0xd488, /*0x60-0x67*/ + 0xd489, 0xd48a, 0xd48b, 0xd48c, 0xd48d, 0xd48e, 0xd48f, 0xd490, /*0x68-0x6f*/ + 0xd491, 0xd492, 0xd493, 0xd494, 0xd495, 0xd496, 0xd497, 0xd498, /*0x70-0x77*/ + 0xd499, 0xd5b2, 0xd49a, 0xd49b, 0xd49c, 0xd49d, 0xd49e, 0xd49f, /*0x78-0x7f*/ + 0xd4a0, 0xd540, 0xd541, 0xd542, 0xd543, 0xd544, 0xd545, 0xd546, /*0x80-0x87*/ + 0xd547, 0xd3fe, 0xccdc, 0xd548, 0xd549, 0xd54a, 0xd54b, 0xd54c, /*0x88-0x8f*/ + 0xd54d, 0xd54e, 0xd54f, 0xcac4, 0xd550, 0xd551, 0xd552, 0xd553, /*0x90-0x97*/ + 0xd554, 0xd555, 0xd556, 0xd557, 0xd558, 0xd559, 0xd55a, 0xd55b, /*0x98-0x9f*/ + 0xd55c, 0xd55d, 0xd55e, 0xd55f, 0xd560, 0xd561, 0xd562, 0xd563, /*0xa0-0xa7*/ + 0xd564, 0xd565, 0xd566, 0xd567, 0xd568, 0xd569, 0xd56a, 0xd56b, /*0xa8-0xaf*/ + 0xd56c, 0xd56d, 0xd56e, 0xd56f, 0xd570, 0xd571, 0xd572, 0xd573, /*0xb0-0xb7*/ + 0xd574, 0xd575, 0xd576, 0xd577, 0xd578, 0xd579, 0xd57a, 0xd57b, /*0xb8-0xbf*/ + 0xd57c, 0xd57d, 0xd57e, 0xd580, 0xd581, 0xd582, 0xd583, 0xd584, /*0xc0-0xc7*/ + 0xd585, 0xd586, 0xd587, 0xd588, 0xd589, 0xd58a, 0xd58b, 0xd58c, /*0xc8-0xcf*/ + 0xd58d, 0xd58e, 0xd58f, 0xd590, 0xd591, 0xd592, 0xd593, 0xd594, /*0xd0-0xd7*/ + 0xd595, 0xd596, 0xd597, 0xd598, 0xd599, 0xd59a, 0xd59b, 0xd59c, /*0xd8-0xdf*/ + 0xd59d, 0xd59e, 0xd59f, 0xd5a0, 0xd640, 0xd641, 0xd642, 0xd643, /*0xe0-0xe7*/ + 0xd644, 0xd645, 0xd646, 0xd647, 0xd648, 0xd649, 0xd64a, 0xd64b, /*0xe8-0xef*/ + 0xd64c, 0xd64d, 0xd64e, 0xd64f, 0xd650, 0xd651, 0xd652, 0xd653, /*0xf0-0xf7*/ + 0xd654, 0xd655, 0xd656, 0xd657, 0xd658, 0xd659, 0xd65a, 0xd65b, /*0xf8-0xff*/ + /* 0x8b00 */ + 0xd65c, 0xd65d, 0xd65e, 0xd65f, 0xd660, 0xd661, 0xd662, 0xe5c0, /*0x00-0x07*/ + 0xd663, 0xd664, 0xd665, 0xd666, 0xd667, 0xd668, 0xd669, 0xd66a, /*0x08-0x0f*/ + 0xd66b, 0xd66c, 0xd66d, 0xd66e, 0xd66f, 0xd670, 0xd671, 0xd672, /*0x10-0x17*/ + 0xd673, 0xd674, 0xd675, 0xd676, 0xd677, 0xd678, 0xd679, 0xd67a, /*0x18-0x1f*/ + 0xd67b, 0xd67c, 0xd67d, 0xd67e, 0xd680, 0xd681, 0xf6a5, 0xd682, /*0x20-0x27*/ + 0xd683, 0xd684, 0xd685, 0xd686, 0xd687, 0xd688, 0xd689, 0xd68a, /*0x28-0x2f*/ + 0xd68b, 0xd68c, 0xd68d, 0xd68e, 0xd68f, 0xd690, 0xd691, 0xd692, /*0x30-0x37*/ + 0xd693, 0xd694, 0xd695, 0xd696, 0xd697, 0xd698, 0xd699, 0xd69a, /*0x38-0x3f*/ + 0xd69b, 0xd69c, 0xd69d, 0xd69e, 0xd69f, 0xd6a0, 0xd740, 0xd741, /*0x40-0x47*/ + 0xd742, 0xd743, 0xd744, 0xd745, 0xd746, 0xd747, 0xd748, 0xd749, /*0x48-0x4f*/ + 0xd74a, 0xd74b, 0xd74c, 0xd74d, 0xd74e, 0xd74f, 0xd750, 0xd751, /*0x50-0x57*/ + 0xd752, 0xd753, 0xd754, 0xd755, 0xd756, 0xd757, 0xd758, 0xd759, /*0x58-0x5f*/ + 0xd75a, 0xd75b, 0xd75c, 0xd75d, 0xd75e, 0xd75f, 0xbeaf, 0xd760, /*0x60-0x67*/ + 0xd761, 0xd762, 0xd763, 0xd764, 0xc6a9, 0xd765, 0xd766, 0xd767, /*0x68-0x6f*/ + 0xd768, 0xd769, 0xd76a, 0xd76b, 0xd76c, 0xd76d, 0xd76e, 0xd76f, /*0x70-0x77*/ + 0xd770, 0xd771, 0xd772, 0xd773, 0xd774, 0xd775, 0xd776, 0xd777, /*0x78-0x7f*/ + 0xd778, 0xd779, 0xd77a, 0xd77b, 0xd77c, 0xd77d, 0xd77e, 0xd780, /*0x80-0x87*/ + 0xd781, 0xd782, 0xd783, 0xd784, 0xd785, 0xd786, 0xd787, 0xd788, /*0x88-0x8f*/ + 0xd789, 0xd78a, 0xd78b, 0xd78c, 0xd78d, 0xd78e, 0xd78f, 0xd790, /*0x90-0x97*/ + 0xd791, 0xd792, 0xd793, 0xd794, 0xd795, 0xd796, 0xd797, 0xd798, /*0x98-0x9f*/ + 0xdaa5, 0xbcc6, 0xb6a9, 0xb8bc, 0xc8cf, 0xbca5, 0xdaa6, 0xdaa7, /*0xa0-0xa7*/ + 0xccd6, 0xc8c3, 0xdaa8, 0xc6fd, 0xd799, 0xd1b5, 0xd2e9, 0xd1b6, /*0xa8-0xaf*/ + 0xbcc7, 0xd79a, 0xbdb2, 0xbbe4, 0xdaa9, 0xdaaa, 0xd1c8, 0xdaab, /*0xb0-0xb7*/ + 0xd0ed, 0xb6ef, 0xc2db, 0xd79b, 0xcbcf, 0xb7ed, 0xc9e8, 0xb7c3, /*0xb8-0xbf*/ + 0xbef7, 0xd6a4, 0xdaac, 0xdaad, 0xc6c0, 0xd7e7, 0xcab6, 0xd79c, /*0xc0-0xc7*/ + 0xd5a9, 0xcbdf, 0xd5ef, 0xdaae, 0xd6df, 0xb4ca, 0xdab0, 0xdaaf, /*0xc8-0xcf*/ + 0xd79d, 0xd2eb, 0xdab1, 0xdab2, 0xdab3, 0xcad4, 0xdab4, 0xcaab, /*0xd0-0xd7*/ + 0xdab5, 0xdab6, 0xb3cf, 0xd6ef, 0xdab7, 0xbbb0, 0xb5ae, 0xdab8, /*0xd8-0xdf*/ + 0xdab9, 0xb9ee, 0xd1af, 0xd2e8, 0xdaba, 0xb8c3, 0xcfea, 0xb2ef, /*0xe0-0xe7*/ + 0xdabb, 0xdabc, 0xd79e, 0xbdeb, 0xcedc, 0xd3ef, 0xdabd, 0xcef3, /*0xe8-0xef*/ + 0xdabe, 0xd3d5, 0xbbe5, 0xdabf, 0xcbb5, 0xcbd0, 0xdac0, 0xc7eb, /*0xf0-0xf7*/ + 0xd6ee, 0xdac1, 0xc5b5, 0xb6c1, 0xdac2, 0xb7cc, 0xbfce, 0xdac3, /*0xf8-0xff*/ + /* 0x8c00 */ + 0xdac4, 0xcbad, 0xdac5, 0xb5f7, 0xdac6, 0xc1c2, 0xd7bb, 0xdac7, /*0x00-0x07*/ + 0xccb8, 0xd79f, 0xd2ea, 0xc4b1, 0xdac8, 0xb5fd, 0xbbd1, 0xdac9, /*0x08-0x0f*/ + 0xd0b3, 0xdaca, 0xdacb, 0xcebd, 0xdacc, 0xdacd, 0xdace, 0xb2f7, /*0x10-0x17*/ + 0xdad1, 0xdacf, 0xd1e8, 0xdad0, 0xc3d5, 0xdad2, 0xd7a0, 0xdad3, /*0x18-0x1f*/ + 0xdad4, 0xdad5, 0xd0bb, 0xd2a5, 0xb0f9, 0xdad6, 0xc7ab, 0xdad7, /*0x20-0x27*/ + 0xbdf7, 0xc3a1, 0xdad8, 0xdad9, 0xc3fd, 0xccb7, 0xdada, 0xdadb, /*0x28-0x2f*/ + 0xc0be, 0xc6d7, 0xdadc, 0xdadd, 0xc7b4, 0xdade, 0xdadf, 0xb9c8, /*0x30-0x37*/ + 0xd840, 0xd841, 0xd842, 0xd843, 0xd844, 0xd845, 0xd846, 0xd847, /*0x38-0x3f*/ + 0xd848, 0xbbed, 0xd849, 0xd84a, 0xd84b, 0xd84c, 0xb6b9, 0xf4f8, /*0x40-0x47*/ + 0xd84d, 0xf4f9, 0xd84e, 0xd84f, 0xcde3, 0xd850, 0xd851, 0xd852, /*0x48-0x4f*/ + 0xd853, 0xd854, 0xd855, 0xd856, 0xd857, 0xf5b9, 0xd858, 0xd859, /*0x50-0x57*/ + 0xd85a, 0xd85b, 0xebe0, 0xd85c, 0xd85d, 0xd85e, 0xd85f, 0xd860, /*0x58-0x5f*/ + 0xd861, 0xcff3, 0xbbbf, 0xd862, 0xd863, 0xd864, 0xd865, 0xd866, /*0x60-0x67*/ + 0xd867, 0xd868, 0xbac0, 0xd4a5, 0xd869, 0xd86a, 0xd86b, 0xd86c, /*0x68-0x6f*/ + 0xd86d, 0xd86e, 0xd86f, 0xe1d9, 0xd870, 0xd871, 0xd872, 0xd873, /*0x70-0x77*/ + 0xf5f4, 0xb1aa, 0xb2f2, 0xd874, 0xd875, 0xd876, 0xd877, 0xd878, /*0x78-0x7f*/ + 0xd879, 0xd87a, 0xf5f5, 0xd87b, 0xd87c, 0xf5f7, 0xd87d, 0xd87e, /*0x80-0x87*/ + 0xd880, 0xbad1, 0xf5f6, 0xd881, 0xc3b2, 0xd882, 0xd883, 0xd884, /*0x88-0x8f*/ + 0xd885, 0xd886, 0xd887, 0xd888, 0xf5f9, 0xd889, 0xd88a, 0xd88b, /*0x90-0x97*/ + 0xf5f8, 0xd88c, 0xd88d, 0xd88e, 0xd88f, 0xd890, 0xd891, 0xd892, /*0x98-0x9f*/ + 0xd893, 0xd894, 0xd895, 0xd896, 0xd897, 0xd898, 0xd899, 0xd89a, /*0xa0-0xa7*/ + 0xd89b, 0xd89c, 0xd89d, 0xd89e, 0xd89f, 0xd8a0, 0xd940, 0xd941, /*0xa8-0xaf*/ + 0xd942, 0xd943, 0xd944, 0xd945, 0xd946, 0xd947, 0xd948, 0xd949, /*0xb0-0xb7*/ + 0xd94a, 0xd94b, 0xd94c, 0xd94d, 0xd94e, 0xd94f, 0xd950, 0xd951, /*0xb8-0xbf*/ + 0xd952, 0xd953, 0xd954, 0xd955, 0xd956, 0xd957, 0xd958, 0xd959, /*0xc0-0xc7*/ + 0xd95a, 0xd95b, 0xd95c, 0xd95d, 0xd95e, 0xd95f, 0xd960, 0xd961, /*0xc8-0xcf*/ + 0xd962, 0xd963, 0xd964, 0xd965, 0xd966, 0xd967, 0xd968, 0xd969, /*0xd0-0xd7*/ + 0xd96a, 0xd96b, 0xd96c, 0xd96d, 0xd96e, 0xd96f, 0xd970, 0xd971, /*0xd8-0xdf*/ + 0xd972, 0xd973, 0xd974, 0xd975, 0xd976, 0xd977, 0xd978, 0xd979, /*0xe0-0xe7*/ + 0xd97a, 0xd97b, 0xd97c, 0xd97d, 0xd97e, 0xd980, 0xd981, 0xd982, /*0xe8-0xef*/ + 0xd983, 0xd984, 0xd985, 0xd986, 0xd987, 0xd988, 0xd989, 0xd98a, /*0xf0-0xf7*/ + 0xd98b, 0xd98c, 0xd98d, 0xd98e, 0xd98f, 0xd990, 0xd991, 0xd992, /*0xf8-0xff*/ + /* 0x8d00 */ + 0xd993, 0xd994, 0xd995, 0xd996, 0xd997, 0xd998, 0xd999, 0xd99a, /*0x00-0x07*/ + 0xd99b, 0xd99c, 0xd99d, 0xd99e, 0xd99f, 0xd9a0, 0xda40, 0xda41, /*0x08-0x0f*/ + 0xda42, 0xda43, 0xda44, 0xda45, 0xda46, 0xda47, 0xda48, 0xda49, /*0x10-0x17*/ + 0xda4a, 0xda4b, 0xda4c, 0xda4d, 0xda4e, 0xb1b4, 0xd5ea, 0xb8ba, /*0x18-0x1f*/ + 0xda4f, 0xb9b1, 0xb2c6, 0xd4f0, 0xcfcd, 0xb0dc, 0xd5cb, 0xbbf5, /*0x20-0x27*/ + 0xd6ca, 0xb7b7, 0xccb0, 0xc6b6, 0xb1e1, 0xb9ba, 0xd6fc, 0xb9e1, /*0x28-0x2f*/ + 0xb7a1, 0xbcfa, 0xeada, 0xeadb, 0xccf9, 0xb9f3, 0xeadc, 0xb4fb, /*0x30-0x37*/ + 0xc3b3, 0xb7d1, 0xbad8, 0xeadd, 0xd4f4, 0xeade, 0xbcd6, 0xbbdf, /*0x38-0x3f*/ + 0xeadf, 0xc1de, 0xc2b8, 0xd4df, 0xd7ca, 0xeae0, 0xeae1, 0xeae4, /*0x40-0x47*/ + 0xeae2, 0xeae3, 0xc9de, 0xb8b3, 0xb6c4, 0xeae5, 0xcaea, 0xc9cd, /*0x48-0x4f*/ + 0xb4cd, 0xda50, 0xda51, 0xe2d9, 0xc5e2, 0xeae6, 0xc0b5, 0xda52, /*0x50-0x57*/ + 0xd7b8, 0xeae7, 0xd7ac, 0xc8fc, 0xd8d3, 0xd8cd, 0xd4de, 0xda53, /*0x58-0x5f*/ + 0xd4f9, 0xc9c4, 0xd3ae, 0xb8d3, 0xb3e0, 0xda54, 0xc9e2, 0xf4f6, /*0x60-0x67*/ + 0xda55, 0xda56, 0xda57, 0xbad5, 0xda58, 0xf4f7, 0xda59, 0xda5a, /*0x68-0x6f*/ + 0xd7df, 0xda5b, 0xda5c, 0xf4f1, 0xb8b0, 0xd5d4, 0xb8cf, 0xc6f0, /*0x70-0x77*/ + 0xda5d, 0xda5e, 0xda5f, 0xda60, 0xda61, 0xda62, 0xda63, 0xda64, /*0x78-0x7f*/ + 0xda65, 0xb3c3, 0xda66, 0xda67, 0xf4f2, 0xb3ac, 0xda68, 0xda69, /*0x80-0x87*/ + 0xda6a, 0xda6b, 0xd4bd, 0xc7f7, 0xda6c, 0xda6d, 0xda6e, 0xda6f, /*0x88-0x8f*/ + 0xda70, 0xf4f4, 0xda71, 0xda72, 0xf4f3, 0xda73, 0xda74, 0xda75, /*0x90-0x97*/ + 0xda76, 0xda77, 0xda78, 0xda79, 0xda7a, 0xda7b, 0xda7c, 0xcccb, /*0x98-0x9f*/ + 0xda7d, 0xda7e, 0xda80, 0xc8a4, 0xda81, 0xda82, 0xda83, 0xda84, /*0xa0-0xa7*/ + 0xda85, 0xda86, 0xda87, 0xda88, 0xda89, 0xda8a, 0xda8b, 0xda8c, /*0xa8-0xaf*/ + 0xda8d, 0xf4f5, 0xda8e, 0xd7e3, 0xc5bf, 0xf5c0, 0xda8f, 0xda90, /*0xb0-0xb7*/ + 0xf5bb, 0xda91, 0xf5c3, 0xda92, 0xf5c2, 0xda93, 0xd6ba, 0xf5c1, /*0xb8-0xbf*/ + 0xda94, 0xda95, 0xda96, 0xd4be, 0xf5c4, 0xda97, 0xf5cc, 0xda98, /*0xc0-0xc7*/ + 0xda99, 0xda9a, 0xda9b, 0xb0cf, 0xb5f8, 0xda9c, 0xf5c9, 0xf5ca, /*0xc8-0xcf*/ + 0xda9d, 0xc5dc, 0xda9e, 0xda9f, 0xdaa0, 0xdb40, 0xf5c5, 0xf5c6, /*0xd0-0xd7*/ + 0xdb41, 0xdb42, 0xf5c7, 0xf5cb, 0xdb43, 0xbee0, 0xf5c8, 0xb8fa, /*0xd8-0xdf*/ + 0xdb44, 0xdb45, 0xdb46, 0xf5d0, 0xf5d3, 0xdb47, 0xdb48, 0xdb49, /*0xe0-0xe7*/ + 0xbfe7, 0xdb4a, 0xb9f2, 0xf5bc, 0xf5cd, 0xdb4b, 0xdb4c, 0xc2b7, /*0xe8-0xef*/ + 0xdb4d, 0xdb4e, 0xdb4f, 0xccf8, 0xdb50, 0xbcf9, 0xdb51, 0xf5ce, /*0xf0-0xf7*/ + 0xf5cf, 0xf5d1, 0xb6e5, 0xf5d2, 0xdb52, 0xf5d5, 0xdb53, 0xdb54, /*0xf8-0xff*/ + /* 0x8e00 */ + 0xdb55, 0xdb56, 0xdb57, 0xdb58, 0xdb59, 0xf5bd, 0xdb5a, 0xdb5b, /*0x00-0x07*/ + 0xdb5c, 0xf5d4, 0xd3bb, 0xdb5d, 0xb3ec, 0xdb5e, 0xdb5f, 0xcca4, /*0x08-0x0f*/ + 0xdb60, 0xdb61, 0xdb62, 0xdb63, 0xf5d6, 0xdb64, 0xdb65, 0xdb66, /*0x10-0x17*/ + 0xdb67, 0xdb68, 0xdb69, 0xdb6a, 0xdb6b, 0xf5d7, 0xbee1, 0xf5d8, /*0x18-0x1f*/ + 0xdb6c, 0xdb6d, 0xccdf, 0xf5db, 0xdb6e, 0xdb6f, 0xdb70, 0xdb71, /*0x20-0x27*/ + 0xdb72, 0xb2c8, 0xd7d9, 0xdb73, 0xf5d9, 0xdb74, 0xf5da, 0xf5dc, /*0x28-0x2f*/ + 0xdb75, 0xf5e2, 0xdb76, 0xdb77, 0xdb78, 0xf5e0, 0xdb79, 0xdb7a, /*0x30-0x37*/ + 0xdb7b, 0xf5df, 0xf5dd, 0xdb7c, 0xdb7d, 0xf5e1, 0xdb7e, 0xdb80, /*0x38-0x3f*/ + 0xf5de, 0xf5e4, 0xf5e5, 0xdb81, 0xcce3, 0xdb82, 0xdb83, 0xe5bf, /*0x40-0x47*/ + 0xb5b8, 0xf5e3, 0xf5e8, 0xcca3, 0xdb84, 0xdb85, 0xdb86, 0xdb87, /*0x48-0x4f*/ + 0xdb88, 0xf5e6, 0xf5e7, 0xdb89, 0xdb8a, 0xdb8b, 0xdb8c, 0xdb8d, /*0x50-0x57*/ + 0xdb8e, 0xf5be, 0xdb8f, 0xdb90, 0xdb91, 0xdb92, 0xdb93, 0xdb94, /*0x58-0x5f*/ + 0xdb95, 0xdb96, 0xdb97, 0xdb98, 0xdb99, 0xdb9a, 0xb1c4, 0xdb9b, /*0x60-0x67*/ + 0xdb9c, 0xf5bf, 0xdb9d, 0xdb9e, 0xb5c5, 0xb2e4, 0xdb9f, 0xf5ec, /*0x68-0x6f*/ + 0xf5e9, 0xdba0, 0xb6d7, 0xdc40, 0xf5ed, 0xdc41, 0xf5ea, 0xdc42, /*0x70-0x77*/ + 0xdc43, 0xdc44, 0xdc45, 0xdc46, 0xf5eb, 0xdc47, 0xdc48, 0xb4da, /*0x78-0x7f*/ + 0xdc49, 0xd4ea, 0xdc4a, 0xdc4b, 0xdc4c, 0xf5ee, 0xdc4d, 0xb3f9, /*0x80-0x87*/ + 0xdc4e, 0xdc4f, 0xdc50, 0xdc51, 0xdc52, 0xdc53, 0xdc54, 0xf5ef, /*0x88-0x8f*/ + 0xf5f1, 0xdc55, 0xdc56, 0xdc57, 0xf5f0, 0xdc58, 0xdc59, 0xdc5a, /*0x90-0x97*/ + 0xdc5b, 0xdc5c, 0xdc5d, 0xdc5e, 0xf5f2, 0xdc5f, 0xf5f3, 0xdc60, /*0x98-0x9f*/ + 0xdc61, 0xdc62, 0xdc63, 0xdc64, 0xdc65, 0xdc66, 0xdc67, 0xdc68, /*0xa0-0xa7*/ + 0xdc69, 0xdc6a, 0xdc6b, 0xc9ed, 0xb9aa, 0xdc6c, 0xdc6d, 0xc7fb, /*0xa8-0xaf*/ + 0xdc6e, 0xdc6f, 0xb6e3, 0xdc70, 0xdc71, 0xdc72, 0xdc73, 0xdc74, /*0xb0-0xb7*/ + 0xdc75, 0xdc76, 0xccc9, 0xdc77, 0xdc78, 0xdc79, 0xdc7a, 0xdc7b, /*0xb8-0xbf*/ + 0xdc7c, 0xdc7d, 0xdc7e, 0xdc80, 0xdc81, 0xdc82, 0xdc83, 0xdc84, /*0xc0-0xc7*/ + 0xdc85, 0xdc86, 0xdc87, 0xdc88, 0xdc89, 0xdc8a, 0xeaa6, 0xdc8b, /*0xc8-0xcf*/ + 0xdc8c, 0xdc8d, 0xdc8e, 0xdc8f, 0xdc90, 0xdc91, 0xdc92, 0xdc93, /*0xd0-0xd7*/ + 0xdc94, 0xdc95, 0xdc96, 0xdc97, 0xdc98, 0xdc99, 0xdc9a, 0xdc9b, /*0xd8-0xdf*/ + 0xdc9c, 0xdc9d, 0xdc9e, 0xdc9f, 0xdca0, 0xdd40, 0xdd41, 0xdd42, /*0xe0-0xe7*/ + 0xdd43, 0xdd44, 0xdd45, 0xdd46, 0xdd47, 0xdd48, 0xdd49, 0xdd4a, /*0xe8-0xef*/ + 0xdd4b, 0xdd4c, 0xdd4d, 0xdd4e, 0xdd4f, 0xdd50, 0xdd51, 0xdd52, /*0xf0-0xf7*/ + 0xdd53, 0xdd54, 0xdd55, 0xdd56, 0xdd57, 0xdd58, 0xdd59, 0xdd5a, /*0xf8-0xff*/ + /* 0x8f00 */ + 0xdd5b, 0xdd5c, 0xdd5d, 0xdd5e, 0xdd5f, 0xdd60, 0xdd61, 0xdd62, /*0x00-0x07*/ + 0xdd63, 0xdd64, 0xdd65, 0xdd66, 0xdd67, 0xdd68, 0xdd69, 0xdd6a, /*0x08-0x0f*/ + 0xdd6b, 0xdd6c, 0xdd6d, 0xdd6e, 0xdd6f, 0xdd70, 0xdd71, 0xdd72, /*0x10-0x17*/ + 0xdd73, 0xdd74, 0xdd75, 0xdd76, 0xdd77, 0xdd78, 0xdd79, 0xdd7a, /*0x18-0x1f*/ + 0xdd7b, 0xdd7c, 0xdd7d, 0xdd7e, 0xdd80, 0xdd81, 0xdd82, 0xdd83, /*0x20-0x27*/ + 0xdd84, 0xdd85, 0xdd86, 0xdd87, 0xdd88, 0xdd89, 0xdd8a, 0xdd8b, /*0x28-0x2f*/ + 0xdd8c, 0xdd8d, 0xdd8e, 0xdd8f, 0xdd90, 0xdd91, 0xdd92, 0xdd93, /*0x30-0x37*/ + 0xdd94, 0xdd95, 0xdd96, 0xdd97, 0xdd98, 0xdd99, 0xdd9a, 0xdd9b, /*0x38-0x3f*/ + 0xdd9c, 0xdd9d, 0xdd9e, 0xdd9f, 0xdda0, 0xde40, 0xde41, 0xde42, /*0x40-0x47*/ + 0xde43, 0xde44, 0xde45, 0xde46, 0xde47, 0xde48, 0xde49, 0xde4a, /*0x48-0x4f*/ + 0xde4b, 0xde4c, 0xde4d, 0xde4e, 0xde4f, 0xde50, 0xde51, 0xde52, /*0x50-0x57*/ + 0xde53, 0xde54, 0xde55, 0xde56, 0xde57, 0xde58, 0xde59, 0xde5a, /*0x58-0x5f*/ + 0xde5b, 0xde5c, 0xde5d, 0xde5e, 0xde5f, 0xde60, 0xb3b5, 0xd4fe, /*0x60-0x67*/ + 0xb9ec, 0xd0f9, 0xde61, 0xe9ed, 0xd7aa, 0xe9ee, 0xc2d6, 0xc8ed, /*0x68-0x6f*/ + 0xbae4, 0xe9ef, 0xe9f0, 0xe9f1, 0xd6e1, 0xe9f2, 0xe9f3, 0xe9f5, /*0x70-0x77*/ + 0xe9f4, 0xe9f6, 0xe9f7, 0xc7e1, 0xe9f8, 0xd4d8, 0xe9f9, 0xbdce, /*0x78-0x7f*/ + 0xde62, 0xe9fa, 0xe9fb, 0xbdcf, 0xe9fc, 0xb8a8, 0xc1be, 0xe9fd, /*0x80-0x87*/ + 0xb1b2, 0xbbd4, 0xb9f5, 0xe9fe, 0xde63, 0xeaa1, 0xeaa2, 0xeaa3, /*0x88-0x8f*/ + 0xb7f8, 0xbcad, 0xde64, 0xcae4, 0xe0ce, 0xd4af, 0xcfbd, 0xd5b7, /*0x90-0x97*/ + 0xeaa4, 0xd5de, 0xeaa5, 0xd0c1, 0xb9bc, 0xde65, 0xb4c7, 0xb1d9, /*0x98-0x9f*/ + 0xde66, 0xde67, 0xde68, 0xc0b1, 0xde69, 0xde6a, 0xde6b, 0xde6c, /*0xa0-0xa7*/ + 0xb1e6, 0xb1e7, 0xde6d, 0xb1e8, 0xde6e, 0xde6f, 0xde70, 0xde71, /*0xa8-0xaf*/ + 0xb3bd, 0xc8e8, 0xde72, 0xde73, 0xde74, 0xde75, 0xe5c1, 0xde76, /*0xb0-0xb7*/ + 0xde77, 0xb1df, 0xde78, 0xde79, 0xde7a, 0xc1c9, 0xb4ef, 0xde7b, /*0xb8-0xbf*/ + 0xde7c, 0xc7a8, 0xd3d8, 0xde7d, 0xc6f9, 0xd1b8, 0xde7e, 0xb9fd, /*0xc0-0xc7*/ + 0xc2f5, 0xde80, 0xde81, 0xde82, 0xde83, 0xde84, 0xd3ad, 0xde85, /*0xc8-0xcf*/ + 0xd4cb, 0xbdfc, 0xde86, 0xe5c2, 0xb7b5, 0xe5c3, 0xde87, 0xde88, /*0xd0-0xd7*/ + 0xbbb9, 0xd5e2, 0xde89, 0xbdf8, 0xd4b6, 0xcea5, 0xc1ac, 0xb3d9, /*0xd8-0xdf*/ + 0xde8a, 0xde8b, 0xccf6, 0xde8c, 0xe5c6, 0xe5c4, 0xe5c8, 0xde8d, /*0xe0-0xe7*/ + 0xe5ca, 0xe5c7, 0xb5cf, 0xc6c8, 0xde8e, 0xb5fc, 0xe5c5, 0xde8f, /*0xe8-0xef*/ + 0xcaf6, 0xde90, 0xde91, 0xe5c9, 0xde92, 0xde93, 0xde94, 0xc3d4, /*0xf0-0xf7*/ + 0xb1c5, 0xbca3, 0xde95, 0xde96, 0xde97, 0xd7b7, 0xde98, 0xde99, /*0xf8-0xff*/ + /* 0x9000 */ + 0xcdcb, 0xcbcd, 0xcaca, 0xccd3, 0xe5cc, 0xe5cb, 0xc4e6, 0xde9a, /*0x00-0x07*/ + 0xde9b, 0xd1a1, 0xd1b7, 0xe5cd, 0xde9c, 0xe5d0, 0xde9d, 0xcdb8, /*0x08-0x0f*/ + 0xd6f0, 0xe5cf, 0xb5dd, 0xde9e, 0xcdbe, 0xde9f, 0xe5d1, 0xb6ba, /*0x10-0x17*/ + 0xdea0, 0xdf40, 0xcda8, 0xb9e4, 0xdf41, 0xcac5, 0xb3d1, 0xcbd9, /*0x18-0x1f*/ + 0xd4ec, 0xe5d2, 0xb7ea, 0xdf42, 0xdf43, 0xdf44, 0xe5ce, 0xdf45, /*0x20-0x27*/ + 0xdf46, 0xdf47, 0xdf48, 0xdf49, 0xdf4a, 0xe5d5, 0xb4fe, 0xe5d6, /*0x28-0x2f*/ + 0xdf4b, 0xdf4c, 0xdf4d, 0xdf4e, 0xdf4f, 0xe5d3, 0xe5d4, 0xdf50, /*0x30-0x37*/ + 0xd2dd, 0xdf51, 0xdf52, 0xc2df, 0xb1c6, 0xdf53, 0xd3e2, 0xdf54, /*0x38-0x3f*/ + 0xdf55, 0xb6dd, 0xcbec, 0xdf56, 0xe5d7, 0xdf57, 0xdf58, 0xd3f6, /*0x40-0x47*/ + 0xdf59, 0xdf5a, 0xdf5b, 0xdf5c, 0xdf5d, 0xb1e9, 0xdf5e, 0xb6f4, /*0x48-0x4f*/ + 0xe5da, 0xe5d8, 0xe5d9, 0xb5c0, 0xdf5f, 0xdf60, 0xdf61, 0xd2c5, /*0x50-0x57*/ + 0xe5dc, 0xdf62, 0xdf63, 0xe5de, 0xdf64, 0xdf65, 0xdf66, 0xdf67, /*0x58-0x5f*/ + 0xdf68, 0xdf69, 0xe5dd, 0xc7b2, 0xdf6a, 0xd2a3, 0xdf6b, 0xdf6c, /*0x60-0x67*/ + 0xe5db, 0xdf6d, 0xdf6e, 0xdf6f, 0xdf70, 0xd4e2, 0xd5da, 0xdf71, /*0x68-0x6f*/ + 0xdf72, 0xdf73, 0xdf74, 0xdf75, 0xe5e0, 0xd7f1, 0xdf76, 0xdf77, /*0x70-0x77*/ + 0xdf78, 0xdf79, 0xdf7a, 0xdf7b, 0xdf7c, 0xe5e1, 0xdf7d, 0xb1dc, /*0x78-0x7f*/ + 0xd1fb, 0xdf7e, 0xe5e2, 0xe5e4, 0xdf80, 0xdf81, 0xdf82, 0xdf83, /*0x80-0x87*/ + 0xe5e3, 0xdf84, 0xdf85, 0xe5e5, 0xdf86, 0xdf87, 0xdf88, 0xdf89, /*0x88-0x8f*/ + 0xdf8a, 0xd2d8, 0xdf8b, 0xb5cb, 0xdf8c, 0xe7df, 0xdf8d, 0xdaf5, /*0x90-0x97*/ + 0xdf8e, 0xdaf8, 0xdf8f, 0xdaf6, 0xdf90, 0xdaf7, 0xdf91, 0xdf92, /*0x98-0x9f*/ + 0xdf93, 0xdafa, 0xd0cf, 0xc4c7, 0xdf94, 0xdf95, 0xb0ee, 0xdf96, /*0xa0-0xa7*/ + 0xdf97, 0xdf98, 0xd0b0, 0xdf99, 0xdaf9, 0xdf9a, 0xd3ca, 0xbaaa, /*0xa8-0xaf*/ + 0xdba2, 0xc7f1, 0xdf9b, 0xdafc, 0xdafb, 0xc9db, 0xdafd, 0xdf9c, /*0xb0-0xb7*/ + 0xdba1, 0xd7de, 0xdafe, 0xc1da, 0xdf9d, 0xdf9e, 0xdba5, 0xdf9f, /*0xb8-0xbf*/ + 0xdfa0, 0xd3f4, 0xe040, 0xe041, 0xdba7, 0xdba4, 0xe042, 0xdba8, /*0xc0-0xc7*/ + 0xe043, 0xe044, 0xbdbc, 0xe045, 0xe046, 0xe047, 0xc0c9, 0xdba3, /*0xc8-0xcf*/ + 0xdba6, 0xd6a3, 0xe048, 0xdba9, 0xe049, 0xe04a, 0xe04b, 0xdbad, /*0xd0-0xd7*/ + 0xe04c, 0xe04d, 0xe04e, 0xdbae, 0xdbac, 0xbac2, 0xe04f, 0xe050, /*0xd8-0xdf*/ + 0xe051, 0xbfa4, 0xdbab, 0xe052, 0xe053, 0xe054, 0xdbaa, 0xd4c7, /*0xe0-0xe7*/ + 0xb2bf, 0xe055, 0xe056, 0xdbaf, 0xe057, 0xb9f9, 0xe058, 0xdbb0, /*0xe8-0xef*/ + 0xe059, 0xe05a, 0xe05b, 0xe05c, 0xb3bb, 0xe05d, 0xe05e, 0xe05f, /*0xf0-0xf7*/ + 0xb5a6, 0xe060, 0xe061, 0xe062, 0xe063, 0xb6bc, 0xdbb1, 0xe064, /*0xf8-0xff*/ + /* 0x9100 */ + 0xe065, 0xe066, 0xb6f5, 0xe067, 0xdbb2, 0xe068, 0xe069, 0xe06a, /*0x00-0x07*/ + 0xe06b, 0xe06c, 0xe06d, 0xe06e, 0xe06f, 0xe070, 0xe071, 0xe072, /*0x08-0x0f*/ + 0xe073, 0xe074, 0xe075, 0xe076, 0xe077, 0xe078, 0xe079, 0xe07a, /*0x10-0x17*/ + 0xe07b, 0xb1c9, 0xe07c, 0xe07d, 0xe07e, 0xe080, 0xdbb4, 0xe081, /*0x18-0x1f*/ + 0xe082, 0xe083, 0xdbb3, 0xdbb5, 0xe084, 0xe085, 0xe086, 0xe087, /*0x20-0x27*/ + 0xe088, 0xe089, 0xe08a, 0xe08b, 0xe08c, 0xe08d, 0xe08e, 0xdbb7, /*0x28-0x2f*/ + 0xe08f, 0xdbb6, 0xe090, 0xe091, 0xe092, 0xe093, 0xe094, 0xe095, /*0x30-0x37*/ + 0xe096, 0xdbb8, 0xe097, 0xe098, 0xe099, 0xe09a, 0xe09b, 0xe09c, /*0x38-0x3f*/ + 0xe09d, 0xe09e, 0xe09f, 0xdbb9, 0xe0a0, 0xe140, 0xdbba, 0xe141, /*0x40-0x47*/ + 0xe142, 0xd3cf, 0xf4fa, 0xc7f5, 0xd7c3, 0xc5e4, 0xf4fc, 0xf4fd, /*0x48-0x4f*/ + 0xf4fb, 0xe143, 0xbec6, 0xe144, 0xe145, 0xe146, 0xe147, 0xd0ef, /*0x50-0x57*/ + 0xe148, 0xe149, 0xb7d3, 0xe14a, 0xe14b, 0xd4cd, 0xccaa, 0xe14c, /*0x58-0x5f*/ + 0xe14d, 0xf5a2, 0xf5a1, 0xbaa8, 0xf4fe, 0xcbd6, 0xe14e, 0xe14f, /*0x60-0x67*/ + 0xe150, 0xf5a4, 0xc0d2, 0xe151, 0xb3ea, 0xe152, 0xcdaa, 0xf5a5, /*0x68-0x6f*/ + 0xf5a3, 0xbdb4, 0xf5a8, 0xe153, 0xf5a9, 0xbdcd, 0xc3b8, 0xbfe1, /*0x70-0x77*/ + 0xcbe1, 0xf5aa, 0xe154, 0xe155, 0xe156, 0xf5a6, 0xf5a7, 0xc4f0, /*0x78-0x7f*/ + 0xe157, 0xe158, 0xe159, 0xe15a, 0xe15b, 0xf5ac, 0xe15c, 0xb4bc, /*0x80-0x87*/ + 0xe15d, 0xd7ed, 0xe15e, 0xb4d7, 0xf5ab, 0xf5ae, 0xe15f, 0xe160, /*0x88-0x8f*/ + 0xf5ad, 0xf5af, 0xd0d1, 0xe161, 0xe162, 0xe163, 0xe164, 0xe165, /*0x90-0x97*/ + 0xe166, 0xe167, 0xc3d1, 0xc8a9, 0xe168, 0xe169, 0xe16a, 0xe16b, /*0x98-0x9f*/ + 0xe16c, 0xe16d, 0xf5b0, 0xf5b1, 0xe16e, 0xe16f, 0xe170, 0xe171, /*0xa0-0xa7*/ + 0xe172, 0xe173, 0xf5b2, 0xe174, 0xe175, 0xf5b3, 0xf5b4, 0xf5b5, /*0xa8-0xaf*/ + 0xe176, 0xe177, 0xe178, 0xe179, 0xf5b7, 0xf5b6, 0xe17a, 0xe17b, /*0xb0-0xb7*/ + 0xe17c, 0xe17d, 0xf5b8, 0xe17e, 0xe180, 0xe181, 0xe182, 0xe183, /*0xb8-0xbf*/ + 0xe184, 0xe185, 0xe186, 0xe187, 0xe188, 0xe189, 0xe18a, 0xb2c9, /*0xc0-0xc7*/ + 0xe18b, 0xd3d4, 0xcacd, 0xe18c, 0xc0ef, 0xd6d8, 0xd2b0, 0xc1bf, /*0xc8-0xcf*/ + 0xe18d, 0xbdf0, 0xe18e, 0xe18f, 0xe190, 0xe191, 0xe192, 0xe193, /*0xd0-0xd7*/ + 0xe194, 0xe195, 0xe196, 0xe197, 0xb8aa, 0xe198, 0xe199, 0xe19a, /*0xd8-0xdf*/ + 0xe19b, 0xe19c, 0xe19d, 0xe19e, 0xe19f, 0xe1a0, 0xe240, 0xe241, /*0xe0-0xe7*/ + 0xe242, 0xe243, 0xe244, 0xe245, 0xe246, 0xe247, 0xe248, 0xe249, /*0xe8-0xef*/ + 0xe24a, 0xe24b, 0xe24c, 0xe24d, 0xe24e, 0xe24f, 0xe250, 0xe251, /*0xf0-0xf7*/ + 0xe252, 0xe253, 0xe254, 0xe255, 0xe256, 0xe257, 0xe258, 0xe259, /*0xf8-0xff*/ + /* 0x9200 */ + 0xe25a, 0xe25b, 0xe25c, 0xe25d, 0xe25e, 0xe25f, 0xe260, 0xe261, /*0x00-0x07*/ + 0xe262, 0xe263, 0xe264, 0xe265, 0xe266, 0xe267, 0xe268, 0xe269, /*0x08-0x0f*/ + 0xe26a, 0xe26b, 0xe26c, 0xe26d, 0xe26e, 0xe26f, 0xe270, 0xe271, /*0x10-0x17*/ + 0xe272, 0xe273, 0xe274, 0xe275, 0xe276, 0xe277, 0xe278, 0xe279, /*0x18-0x1f*/ + 0xe27a, 0xe27b, 0xe27c, 0xe27d, 0xe27e, 0xe280, 0xe281, 0xe282, /*0x20-0x27*/ + 0xe283, 0xe284, 0xe285, 0xe286, 0xe287, 0xe288, 0xe289, 0xe28a, /*0x28-0x2f*/ + 0xe28b, 0xe28c, 0xe28d, 0xe28e, 0xe28f, 0xe290, 0xe291, 0xe292, /*0x30-0x37*/ + 0xe293, 0xe294, 0xe295, 0xe296, 0xe297, 0xe298, 0xe299, 0xe29a, /*0x38-0x3f*/ + 0xe29b, 0xe29c, 0xe29d, 0xe29e, 0xe29f, 0xe2a0, 0xe340, 0xe341, /*0x40-0x47*/ + 0xe342, 0xe343, 0xe344, 0xe345, 0xe346, 0xe347, 0xe348, 0xe349, /*0x48-0x4f*/ + 0xe34a, 0xe34b, 0xe34c, 0xe34d, 0xe34e, 0xe34f, 0xe350, 0xe351, /*0x50-0x57*/ + 0xe352, 0xe353, 0xe354, 0xe355, 0xe356, 0xe357, 0xe358, 0xe359, /*0x58-0x5f*/ + 0xe35a, 0xe35b, 0xe35c, 0xe35d, 0xe35e, 0xe35f, 0xe360, 0xe361, /*0x60-0x67*/ + 0xe362, 0xe363, 0xe364, 0xe365, 0xe366, 0xe367, 0xe368, 0xe369, /*0x68-0x6f*/ + 0xe36a, 0xe36b, 0xe36c, 0xe36d, 0xbcf8, 0xe36e, 0xe36f, 0xe370, /*0x70-0x77*/ + 0xe371, 0xe372, 0xe373, 0xe374, 0xe375, 0xe376, 0xe377, 0xe378, /*0x78-0x7f*/ + 0xe379, 0xe37a, 0xe37b, 0xe37c, 0xe37d, 0xe37e, 0xe380, 0xe381, /*0x80-0x87*/ + 0xe382, 0xe383, 0xe384, 0xe385, 0xe386, 0xe387, 0xf6c6, 0xe388, /*0x88-0x8f*/ + 0xe389, 0xe38a, 0xe38b, 0xe38c, 0xe38d, 0xe38e, 0xe38f, 0xe390, /*0x90-0x97*/ + 0xe391, 0xe392, 0xe393, 0xe394, 0xe395, 0xe396, 0xe397, 0xe398, /*0x98-0x9f*/ + 0xe399, 0xe39a, 0xe39b, 0xe39c, 0xe39d, 0xe39e, 0xe39f, 0xe3a0, /*0xa0-0xa7*/ + 0xe440, 0xe441, 0xe442, 0xe443, 0xe444, 0xe445, 0xf6c7, 0xe446, /*0xa8-0xaf*/ + 0xe447, 0xe448, 0xe449, 0xe44a, 0xe44b, 0xe44c, 0xe44d, 0xe44e, /*0xb0-0xb7*/ + 0xe44f, 0xe450, 0xe451, 0xe452, 0xe453, 0xe454, 0xe455, 0xe456, /*0xb8-0xbf*/ + 0xe457, 0xe458, 0xe459, 0xe45a, 0xe45b, 0xe45c, 0xe45d, 0xe45e, /*0xc0-0xc7*/ + 0xf6c8, 0xe45f, 0xe460, 0xe461, 0xe462, 0xe463, 0xe464, 0xe465, /*0xc8-0xcf*/ + 0xe466, 0xe467, 0xe468, 0xe469, 0xe46a, 0xe46b, 0xe46c, 0xe46d, /*0xd0-0xd7*/ + 0xe46e, 0xe46f, 0xe470, 0xe471, 0xe472, 0xe473, 0xe474, 0xe475, /*0xd8-0xdf*/ + 0xe476, 0xe477, 0xe478, 0xe479, 0xe47a, 0xe47b, 0xe47c, 0xe47d, /*0xe0-0xe7*/ + 0xe47e, 0xe480, 0xe481, 0xe482, 0xe483, 0xe484, 0xe485, 0xe486, /*0xe8-0xef*/ + 0xe487, 0xe488, 0xe489, 0xe48a, 0xe48b, 0xe48c, 0xe48d, 0xe48e, /*0xf0-0xf7*/ + 0xe48f, 0xe490, 0xe491, 0xe492, 0xe493, 0xe494, 0xe495, 0xe496, /*0xf8-0xff*/ + /* 0x9300 */ + 0xe497, 0xe498, 0xe499, 0xe49a, 0xe49b, 0xe49c, 0xe49d, 0xe49e, /*0x00-0x07*/ + 0xe49f, 0xe4a0, 0xe540, 0xe541, 0xe542, 0xe543, 0xe544, 0xe545, /*0x08-0x0f*/ + 0xe546, 0xe547, 0xe548, 0xe549, 0xe54a, 0xe54b, 0xe54c, 0xe54d, /*0x10-0x17*/ + 0xe54e, 0xe54f, 0xe550, 0xe551, 0xe552, 0xe553, 0xe554, 0xe555, /*0x18-0x1f*/ + 0xe556, 0xe557, 0xe558, 0xe559, 0xe55a, 0xe55b, 0xe55c, 0xe55d, /*0x20-0x27*/ + 0xe55e, 0xe55f, 0xe560, 0xe561, 0xe562, 0xe563, 0xe564, 0xe565, /*0x28-0x2f*/ + 0xe566, 0xe567, 0xe568, 0xe569, 0xe56a, 0xe56b, 0xe56c, 0xe56d, /*0x30-0x37*/ + 0xe56e, 0xe56f, 0xe570, 0xe571, 0xe572, 0xe573, 0xf6c9, 0xe574, /*0x38-0x3f*/ + 0xe575, 0xe576, 0xe577, 0xe578, 0xe579, 0xe57a, 0xe57b, 0xe57c, /*0x40-0x47*/ + 0xe57d, 0xe57e, 0xe580, 0xe581, 0xe582, 0xe583, 0xe584, 0xe585, /*0x48-0x4f*/ + 0xe586, 0xe587, 0xe588, 0xe589, 0xe58a, 0xe58b, 0xe58c, 0xe58d, /*0x50-0x57*/ + 0xe58e, 0xe58f, 0xe590, 0xe591, 0xe592, 0xe593, 0xe594, 0xe595, /*0x58-0x5f*/ + 0xe596, 0xe597, 0xe598, 0xe599, 0xe59a, 0xe59b, 0xe59c, 0xe59d, /*0x60-0x67*/ + 0xe59e, 0xe59f, 0xf6ca, 0xe5a0, 0xe640, 0xe641, 0xe642, 0xe643, /*0x68-0x6f*/ + 0xe644, 0xe645, 0xe646, 0xe647, 0xe648, 0xe649, 0xe64a, 0xe64b, /*0x70-0x77*/ + 0xe64c, 0xe64d, 0xe64e, 0xe64f, 0xe650, 0xe651, 0xe652, 0xe653, /*0x78-0x7f*/ + 0xe654, 0xe655, 0xe656, 0xe657, 0xe658, 0xe659, 0xe65a, 0xe65b, /*0x80-0x87*/ + 0xe65c, 0xe65d, 0xe65e, 0xe65f, 0xe660, 0xe661, 0xe662, 0xf6cc, /*0x88-0x8f*/ + 0xe663, 0xe664, 0xe665, 0xe666, 0xe667, 0xe668, 0xe669, 0xe66a, /*0x90-0x97*/ + 0xe66b, 0xe66c, 0xe66d, 0xe66e, 0xe66f, 0xe670, 0xe671, 0xe672, /*0x98-0x9f*/ + 0xe673, 0xe674, 0xe675, 0xe676, 0xe677, 0xe678, 0xe679, 0xe67a, /*0xa0-0xa7*/ + 0xe67b, 0xe67c, 0xe67d, 0xe67e, 0xe680, 0xe681, 0xe682, 0xe683, /*0xa8-0xaf*/ + 0xe684, 0xe685, 0xe686, 0xe687, 0xe688, 0xe689, 0xe68a, 0xe68b, /*0xb0-0xb7*/ + 0xe68c, 0xe68d, 0xe68e, 0xe68f, 0xe690, 0xe691, 0xe692, 0xe693, /*0xb8-0xbf*/ + 0xe694, 0xe695, 0xe696, 0xe697, 0xe698, 0xe699, 0xe69a, 0xe69b, /*0xc0-0xc7*/ + 0xe69c, 0xe69d, 0xf6cb, 0xe69e, 0xe69f, 0xe6a0, 0xe740, 0xe741, /*0xc8-0xcf*/ + 0xe742, 0xe743, 0xe744, 0xe745, 0xe746, 0xe747, 0xf7e9, 0xe748, /*0xd0-0xd7*/ + 0xe749, 0xe74a, 0xe74b, 0xe74c, 0xe74d, 0xe74e, 0xe74f, 0xe750, /*0xd8-0xdf*/ + 0xe751, 0xe752, 0xe753, 0xe754, 0xe755, 0xe756, 0xe757, 0xe758, /*0xe0-0xe7*/ + 0xe759, 0xe75a, 0xe75b, 0xe75c, 0xe75d, 0xe75e, 0xe75f, 0xe760, /*0xe8-0xef*/ + 0xe761, 0xe762, 0xe763, 0xe764, 0xe765, 0xe766, 0xe767, 0xe768, /*0xf0-0xf7*/ + 0xe769, 0xe76a, 0xe76b, 0xe76c, 0xe76d, 0xe76e, 0xe76f, 0xe770, /*0xf8-0xff*/ + /* 0x9400 */ + 0xe771, 0xe772, 0xe773, 0xe774, 0xe775, 0xe776, 0xe777, 0xe778, /*0x00-0x07*/ + 0xe779, 0xe77a, 0xe77b, 0xe77c, 0xe77d, 0xe77e, 0xe780, 0xe781, /*0x08-0x0f*/ + 0xe782, 0xe783, 0xe784, 0xe785, 0xe786, 0xe787, 0xe788, 0xe789, /*0x10-0x17*/ + 0xe78a, 0xe78b, 0xe78c, 0xe78d, 0xe78e, 0xe78f, 0xe790, 0xe791, /*0x18-0x1f*/ + 0xe792, 0xe793, 0xe794, 0xe795, 0xe796, 0xe797, 0xe798, 0xe799, /*0x20-0x27*/ + 0xe79a, 0xe79b, 0xe79c, 0xe79d, 0xe79e, 0xe79f, 0xe7a0, 0xe840, /*0x28-0x2f*/ + 0xe841, 0xe842, 0xe843, 0xe844, 0xe845, 0xe846, 0xe847, 0xe848, /*0x30-0x37*/ + 0xe849, 0xe84a, 0xe84b, 0xe84c, 0xe84d, 0xe84e, 0xf6cd, 0xe84f, /*0x38-0x3f*/ + 0xe850, 0xe851, 0xe852, 0xe853, 0xe854, 0xe855, 0xe856, 0xe857, /*0x40-0x47*/ + 0xe858, 0xe859, 0xe85a, 0xe85b, 0xe85c, 0xe85d, 0xe85e, 0xe85f, /*0x48-0x4f*/ + 0xe860, 0xe861, 0xe862, 0xe863, 0xe864, 0xe865, 0xe866, 0xe867, /*0x50-0x57*/ + 0xe868, 0xe869, 0xe86a, 0xe86b, 0xe86c, 0xe86d, 0xe86e, 0xe86f, /*0x58-0x5f*/ + 0xe870, 0xe871, 0xe872, 0xe873, 0xe874, 0xe875, 0xe876, 0xe877, /*0x60-0x67*/ + 0xe878, 0xe879, 0xe87a, 0xf6ce, 0xe87b, 0xe87c, 0xe87d, 0xe87e, /*0x68-0x6f*/ + 0xe880, 0xe881, 0xe882, 0xe883, 0xe884, 0xe885, 0xe886, 0xe887, /*0x70-0x77*/ + 0xe888, 0xe889, 0xe88a, 0xe88b, 0xe88c, 0xe88d, 0xe88e, 0xe88f, /*0x78-0x7f*/ + 0xe890, 0xe891, 0xe892, 0xe893, 0xe894, 0xeec4, 0xeec5, 0xeec6, /*0x80-0x87*/ + 0xd5eb, 0xb6a4, 0xeec8, 0xeec7, 0xeec9, 0xeeca, 0xc7a5, 0xeecb, /*0x88-0x8f*/ + 0xeecc, 0xe895, 0xb7b0, 0xb5f6, 0xeecd, 0xeecf, 0xe896, 0xeece, /*0x90-0x97*/ + 0xe897, 0xb8c6, 0xeed0, 0xeed1, 0xeed2, 0xb6db, 0xb3ae, 0xd6d3, /*0x98-0x9f*/ + 0xc4c6, 0xb1b5, 0xb8d6, 0xeed3, 0xeed4, 0xd4bf, 0xc7d5, 0xbefb, /*0xa0-0xa7*/ + 0xced9, 0xb9b3, 0xeed6, 0xeed5, 0xeed8, 0xeed7, 0xc5a5, 0xeed9, /*0xa8-0xaf*/ + 0xeeda, 0xc7ae, 0xeedb, 0xc7af, 0xeedc, 0xb2a7, 0xeedd, 0xeede, /*0xb0-0xb7*/ + 0xeedf, 0xeee0, 0xeee1, 0xd7ea, 0xeee2, 0xeee3, 0xbcd8, 0xeee4, /*0xb8-0xbf*/ + 0xd3cb, 0xccfa, 0xb2ac, 0xc1e5, 0xeee5, 0xc7a6, 0xc3ad, 0xe898, /*0xc0-0xc7*/ + 0xeee6, 0xeee7, 0xeee8, 0xeee9, 0xeeea, 0xeeeb, 0xeeec, 0xe899, /*0xc8-0xcf*/ + 0xeeed, 0xeeee, 0xeeef, 0xe89a, 0xe89b, 0xeef0, 0xeef1, 0xeef2, /*0xd0-0xd7*/ + 0xeef4, 0xeef3, 0xe89c, 0xeef5, 0xcdad, 0xc2c1, 0xeef6, 0xeef7, /*0xd8-0xdf*/ + 0xeef8, 0xd5a1, 0xeef9, 0xcfb3, 0xeefa, 0xeefb, 0xe89d, 0xeefc, /*0xe0-0xe7*/ + 0xeefd, 0xefa1, 0xeefe, 0xefa2, 0xb8f5, 0xc3fa, 0xefa3, 0xefa4, /*0xe8-0xef*/ + 0xbdc2, 0xd2bf, 0xb2f9, 0xefa5, 0xefa6, 0xefa7, 0xd2f8, 0xefa8, /*0xf0-0xf7*/ + 0xd6fd, 0xefa9, 0xc6cc, 0xe89e, 0xefaa, 0xefab, 0xc1b4, 0xefac, /*0xf8-0xff*/ + /* 0x9500 */ + 0xcffa, 0xcbf8, 0xefae, 0xefad, 0xb3fa, 0xb9f8, 0xefaf, 0xefb0, /*0x00-0x07*/ + 0xd0e2, 0xefb1, 0xefb2, 0xb7e6, 0xd0bf, 0xefb3, 0xefb4, 0xefb5, /*0x08-0x0f*/ + 0xc8f1, 0xcce0, 0xefb6, 0xefb7, 0xefb8, 0xefb9, 0xefba, 0xd5e0, /*0x10-0x17*/ + 0xefbb, 0xb4ed, 0xc3aa, 0xefbc, 0xe89f, 0xefbd, 0xefbe, 0xefbf, /*0x18-0x1f*/ + 0xe8a0, 0xcefd, 0xefc0, 0xc2e0, 0xb4b8, 0xd7b6, 0xbdf5, 0xe940, /*0x20-0x27*/ + 0xcfc7, 0xefc3, 0xefc1, 0xefc2, 0xefc4, 0xb6a7, 0xbcfc, 0xbee2, /*0x28-0x2f*/ + 0xc3cc, 0xefc5, 0xefc6, 0xe941, 0xefc7, 0xefcf, 0xefc8, 0xefc9, /*0x30-0x37*/ + 0xefca, 0xc7c2, 0xeff1, 0xb6cd, 0xefcb, 0xe942, 0xefcc, 0xefcd, /*0x38-0x3f*/ + 0xb6c6, 0xc3be, 0xefce, 0xe943, 0xefd0, 0xefd1, 0xefd2, 0xd5f2, /*0x40-0x47*/ + 0xe944, 0xefd3, 0xc4f7, 0xe945, 0xefd4, 0xc4f8, 0xefd5, 0xefd6, /*0x48-0x4f*/ + 0xb8e4, 0xb0f7, 0xefd7, 0xefd8, 0xefd9, 0xe946, 0xefda, 0xefdb, /*0x50-0x57*/ + 0xefdc, 0xefdd, 0xe947, 0xefde, 0xbeb5, 0xefe1, 0xefdf, 0xefe0, /*0x58-0x5f*/ + 0xe948, 0xefe2, 0xefe3, 0xc1cd, 0xefe4, 0xefe5, 0xefe6, 0xefe7, /*0x60-0x67*/ + 0xefe8, 0xefe9, 0xefea, 0xefeb, 0xefec, 0xc0d8, 0xe949, 0xefed, /*0x68-0x6f*/ + 0xc1ad, 0xefee, 0xefef, 0xeff0, 0xe94a, 0xe94b, 0xcfe2, 0xe94c, /*0x70-0x77*/ + 0xe94d, 0xe94e, 0xe94f, 0xe950, 0xe951, 0xe952, 0xe953, 0xb3a4, /*0x78-0x7f*/ + 0xe954, 0xe955, 0xe956, 0xe957, 0xe958, 0xe959, 0xe95a, 0xe95b, /*0x80-0x87*/ + 0xe95c, 0xe95d, 0xe95e, 0xe95f, 0xe960, 0xe961, 0xe962, 0xe963, /*0x88-0x8f*/ + 0xe964, 0xe965, 0xe966, 0xe967, 0xe968, 0xe969, 0xe96a, 0xe96b, /*0x90-0x97*/ + 0xe96c, 0xe96d, 0xe96e, 0xe96f, 0xe970, 0xe971, 0xe972, 0xe973, /*0x98-0x9f*/ + 0xe974, 0xe975, 0xe976, 0xe977, 0xe978, 0xe979, 0xe97a, 0xe97b, /*0xa0-0xa7*/ + 0xe97c, 0xe97d, 0xe97e, 0xe980, 0xe981, 0xe982, 0xe983, 0xe984, /*0xa8-0xaf*/ + 0xe985, 0xe986, 0xe987, 0xe988, 0xe989, 0xe98a, 0xe98b, 0xe98c, /*0xb0-0xb7*/ + 0xe98d, 0xe98e, 0xe98f, 0xe990, 0xe991, 0xe992, 0xe993, 0xe994, /*0xb8-0xbf*/ + 0xe995, 0xe996, 0xe997, 0xe998, 0xe999, 0xe99a, 0xe99b, 0xe99c, /*0xc0-0xc7*/ + 0xe99d, 0xe99e, 0xe99f, 0xe9a0, 0xea40, 0xea41, 0xea42, 0xea43, /*0xc8-0xcf*/ + 0xea44, 0xea45, 0xea46, 0xea47, 0xea48, 0xea49, 0xea4a, 0xea4b, /*0xd0-0xd7*/ + 0xea4c, 0xea4d, 0xea4e, 0xea4f, 0xea50, 0xea51, 0xea52, 0xea53, /*0xd8-0xdf*/ + 0xea54, 0xea55, 0xea56, 0xea57, 0xea58, 0xea59, 0xea5a, 0xea5b, /*0xe0-0xe7*/ + 0xc3c5, 0xe3c5, 0xc9c1, 0xe3c6, 0xea5c, 0xb1d5, 0xceca, 0xb4b3, /*0xe8-0xef*/ + 0xc8f2, 0xe3c7, 0xcfd0, 0xe3c8, 0xbce4, 0xe3c9, 0xe3ca, 0xc3c6, /*0xf0-0xf7*/ + 0xd5a2, 0xc4d6, 0xb9eb, 0xcec5, 0xe3cb, 0xc3f6, 0xe3cc, 0xea5d, /*0xf8-0xff*/ + /* 0x9600 */ + 0xb7a7, 0xb8f3, 0xbad2, 0xe3cd, 0xe3ce, 0xd4c4, 0xe3cf, 0xea5e, /*0x00-0x07*/ + 0xe3d0, 0xd1cb, 0xe3d1, 0xe3d2, 0xe3d3, 0xe3d4, 0xd1d6, 0xe3d5, /*0x08-0x0f*/ + 0xb2fb, 0xc0bb, 0xe3d6, 0xea5f, 0xc0ab, 0xe3d7, 0xe3d8, 0xe3d9, /*0x10-0x17*/ + 0xea60, 0xe3da, 0xe3db, 0xea61, 0xb8b7, 0xdae2, 0xea62, 0xb6d3, /*0x18-0x1f*/ + 0xea63, 0xdae4, 0xdae3, 0xea64, 0xea65, 0xea66, 0xea67, 0xea68, /*0x20-0x27*/ + 0xea69, 0xea6a, 0xdae6, 0xea6b, 0xea6c, 0xea6d, 0xc8ee, 0xea6e, /*0x28-0x2f*/ + 0xea6f, 0xdae5, 0xb7c0, 0xd1f4, 0xd2f5, 0xd5f3, 0xbdd7, 0xea70, /*0x30-0x37*/ + 0xea71, 0xea72, 0xea73, 0xd7e8, 0xdae8, 0xdae7, 0xea74, 0xb0a2, /*0x38-0x3f*/ + 0xcdd3, 0xea75, 0xdae9, 0xea76, 0xb8bd, 0xbcca, 0xc2bd, 0xc2a4, /*0x40-0x47*/ + 0xb3c2, 0xdaea, 0xea77, 0xc2aa, 0xc4b0, 0xbdb5, 0xea78, 0xea79, /*0x48-0x4f*/ + 0xcfde, 0xea7a, 0xea7b, 0xea7c, 0xdaeb, 0xc9c2, 0xea7d, 0xea7e, /*0x50-0x57*/ + 0xea80, 0xea81, 0xea82, 0xb1dd, 0xea83, 0xea84, 0xea85, 0xdaec, /*0x58-0x5f*/ + 0xea86, 0xb6b8, 0xd4ba, 0xea87, 0xb3fd, 0xea88, 0xea89, 0xdaed, /*0x60-0x67*/ + 0xd4c9, 0xcfd5, 0xc5e3, 0xea8a, 0xdaee, 0xea8b, 0xea8c, 0xea8d, /*0x68-0x6f*/ + 0xea8e, 0xea8f, 0xdaef, 0xea90, 0xdaf0, 0xc1ea, 0xccd5, 0xcfdd, /*0x70-0x77*/ + 0xea91, 0xea92, 0xea93, 0xea94, 0xea95, 0xea96, 0xea97, 0xea98, /*0x78-0x7f*/ + 0xea99, 0xea9a, 0xea9b, 0xea9c, 0xea9d, 0xd3e7, 0xc2a1, 0xea9e, /*0x80-0x87*/ + 0xdaf1, 0xea9f, 0xeaa0, 0xcbe5, 0xeb40, 0xdaf2, 0xeb41, 0xcbe6, /*0x88-0x8f*/ + 0xd2fe, 0xeb42, 0xeb43, 0xeb44, 0xb8f4, 0xeb45, 0xeb46, 0xdaf3, /*0x90-0x97*/ + 0xb0af, 0xcfb6, 0xeb47, 0xeb48, 0xd5cf, 0xeb49, 0xeb4a, 0xeb4b, /*0x98-0x9f*/ + 0xeb4c, 0xeb4d, 0xeb4e, 0xeb4f, 0xeb50, 0xeb51, 0xeb52, 0xcbed, /*0xa0-0xa7*/ + 0xeb53, 0xeb54, 0xeb55, 0xeb56, 0xeb57, 0xeb58, 0xeb59, 0xeb5a, /*0xa8-0xaf*/ + 0xdaf4, 0xeb5b, 0xeb5c, 0xe3c4, 0xeb5d, 0xeb5e, 0xc1a5, 0xeb5f, /*0xb0-0xb7*/ + 0xeb60, 0xf6bf, 0xeb61, 0xeb62, 0xf6c0, 0xf6c1, 0xc4d1, 0xeb63, /*0xb8-0xbf*/ + 0xc8b8, 0xd1e3, 0xeb64, 0xeb65, 0xd0db, 0xd1c5, 0xbcaf, 0xb9cd, /*0xc0-0xc7*/ + 0xeb66, 0xeff4, 0xeb67, 0xeb68, 0xb4c6, 0xd3ba, 0xf6c2, 0xb3fb, /*0xc8-0xcf*/ + 0xeb69, 0xeb6a, 0xf6c3, 0xeb6b, 0xeb6c, 0xb5f1, 0xeb6d, 0xeb6e, /*0xd0-0xd7*/ + 0xeb6f, 0xeb70, 0xeb71, 0xeb72, 0xeb73, 0xeb74, 0xeb75, 0xeb76, /*0xd8-0xdf*/ + 0xf6c5, 0xeb77, 0xeb78, 0xeb79, 0xeb7a, 0xeb7b, 0xeb7c, 0xeb7d, /*0xe0-0xe7*/ + 0xd3ea, 0xf6a7, 0xd1a9, 0xeb7e, 0xeb80, 0xeb81, 0xeb82, 0xf6a9, /*0xe8-0xef*/ + 0xeb83, 0xeb84, 0xeb85, 0xf6a8, 0xeb86, 0xeb87, 0xc1e3, 0xc0d7, /*0xf0-0xf7*/ + 0xeb88, 0xb1a2, 0xeb89, 0xeb8a, 0xeb8b, 0xeb8c, 0xceed, 0xeb8d, /*0xf8-0xff*/ + /* 0x9700 */ + 0xd0e8, 0xf6ab, 0xeb8e, 0xeb8f, 0xcff6, 0xeb90, 0xf6aa, 0xd5f0, /*0x00-0x07*/ + 0xf6ac, 0xc3b9, 0xeb91, 0xeb92, 0xeb93, 0xbbf4, 0xf6ae, 0xf6ad, /*0x08-0x0f*/ + 0xeb94, 0xeb95, 0xeb96, 0xc4de, 0xeb97, 0xeb98, 0xc1d8, 0xeb99, /*0x10-0x17*/ + 0xeb9a, 0xeb9b, 0xeb9c, 0xeb9d, 0xcbaa, 0xeb9e, 0xcfbc, 0xeb9f, /*0x18-0x1f*/ + 0xeba0, 0xec40, 0xec41, 0xec42, 0xec43, 0xec44, 0xec45, 0xec46, /*0x20-0x27*/ + 0xec47, 0xec48, 0xf6af, 0xec49, 0xec4a, 0xf6b0, 0xec4b, 0xec4c, /*0x28-0x2f*/ + 0xf6b1, 0xec4d, 0xc2b6, 0xec4e, 0xec4f, 0xec50, 0xec51, 0xec52, /*0x30-0x37*/ + 0xb0d4, 0xc5f9, 0xec53, 0xec54, 0xec55, 0xec56, 0xf6b2, 0xec57, /*0x38-0x3f*/ + 0xec58, 0xec59, 0xec5a, 0xec5b, 0xec5c, 0xec5d, 0xec5e, 0xec5f, /*0x40-0x47*/ + 0xec60, 0xec61, 0xec62, 0xec63, 0xec64, 0xec65, 0xec66, 0xec67, /*0x48-0x4f*/ + 0xec68, 0xec69, 0xc7e0, 0xf6a6, 0xec6a, 0xec6b, 0xbeb8, 0xec6c, /*0x50-0x57*/ + 0xec6d, 0xbeb2, 0xec6e, 0xb5e5, 0xec6f, 0xec70, 0xb7c7, 0xec71, /*0x58-0x5f*/ + 0xbfbf, 0xc3d2, 0xc3e6, 0xec72, 0xec73, 0xd8cc, 0xec74, 0xec75, /*0x60-0x67*/ + 0xec76, 0xb8ef, 0xec77, 0xec78, 0xec79, 0xec7a, 0xec7b, 0xec7c, /*0x68-0x6f*/ + 0xec7d, 0xec7e, 0xec80, 0xbdf9, 0xd1a5, 0xec81, 0xb0d0, 0xec82, /*0x70-0x77*/ + 0xec83, 0xec84, 0xec85, 0xec86, 0xf7b0, 0xec87, 0xec88, 0xec89, /*0x78-0x7f*/ + 0xec8a, 0xec8b, 0xec8c, 0xec8d, 0xec8e, 0xf7b1, 0xec8f, 0xec90, /*0x80-0x87*/ + 0xec91, 0xec92, 0xec93, 0xd0ac, 0xec94, 0xb0b0, 0xec95, 0xec96, /*0x88-0x8f*/ + 0xec97, 0xf7b2, 0xf7b3, 0xec98, 0xf7b4, 0xec99, 0xec9a, 0xec9b, /*0x90-0x97*/ + 0xc7ca, 0xec9c, 0xec9d, 0xec9e, 0xec9f, 0xeca0, 0xed40, 0xed41, /*0x98-0x9f*/ + 0xbecf, 0xed42, 0xed43, 0xf7b7, 0xed44, 0xed45, 0xed46, 0xed47, /*0xa0-0xa7*/ + 0xed48, 0xed49, 0xed4a, 0xf7b6, 0xed4b, 0xb1de, 0xed4c, 0xf7b5, /*0xa8-0xaf*/ + 0xed4d, 0xed4e, 0xf7b8, 0xed4f, 0xf7b9, 0xed50, 0xed51, 0xed52, /*0xb0-0xb7*/ + 0xed53, 0xed54, 0xed55, 0xed56, 0xed57, 0xed58, 0xed59, 0xed5a, /*0xb8-0xbf*/ + 0xed5b, 0xed5c, 0xed5d, 0xed5e, 0xed5f, 0xed60, 0xed61, 0xed62, /*0xc0-0xc7*/ + 0xed63, 0xed64, 0xed65, 0xed66, 0xed67, 0xed68, 0xed69, 0xed6a, /*0xc8-0xcf*/ + 0xed6b, 0xed6c, 0xed6d, 0xed6e, 0xed6f, 0xed70, 0xed71, 0xed72, /*0xd0-0xd7*/ + 0xed73, 0xed74, 0xed75, 0xed76, 0xed77, 0xed78, 0xed79, 0xed7a, /*0xd8-0xdf*/ + 0xed7b, 0xed7c, 0xed7d, 0xed7e, 0xed80, 0xed81, 0xcea4, 0xc8cd, /*0xe0-0xe7*/ + 0xed82, 0xbaab, 0xe8b8, 0xe8b9, 0xe8ba, 0xbec2, 0xed83, 0xed84, /*0xe8-0xef*/ + 0xed85, 0xed86, 0xed87, 0xd2f4, 0xed88, 0xd4cf, 0xc9d8, 0xed89, /*0xf0-0xf7*/ + 0xed8a, 0xed8b, 0xed8c, 0xed8d, 0xed8e, 0xed8f, 0xed90, 0xed91, /*0xf8-0xff*/ + /* 0x9800 */ + 0xed92, 0xed93, 0xed94, 0xed95, 0xed96, 0xed97, 0xed98, 0xed99, /*0x00-0x07*/ + 0xed9a, 0xed9b, 0xed9c, 0xed9d, 0xed9e, 0xed9f, 0xeda0, 0xee40, /*0x08-0x0f*/ + 0xee41, 0xee42, 0xee43, 0xee44, 0xee45, 0xee46, 0xee47, 0xee48, /*0x10-0x17*/ + 0xee49, 0xee4a, 0xee4b, 0xee4c, 0xee4d, 0xee4e, 0xee4f, 0xee50, /*0x18-0x1f*/ + 0xee51, 0xee52, 0xee53, 0xee54, 0xee55, 0xee56, 0xee57, 0xee58, /*0x20-0x27*/ + 0xee59, 0xee5a, 0xee5b, 0xee5c, 0xee5d, 0xee5e, 0xee5f, 0xee60, /*0x28-0x2f*/ + 0xee61, 0xee62, 0xee63, 0xee64, 0xee65, 0xee66, 0xee67, 0xee68, /*0x30-0x37*/ + 0xee69, 0xee6a, 0xee6b, 0xee6c, 0xee6d, 0xee6e, 0xee6f, 0xee70, /*0x38-0x3f*/ + 0xee71, 0xee72, 0xee73, 0xee74, 0xee75, 0xee76, 0xee77, 0xee78, /*0x40-0x47*/ + 0xee79, 0xee7a, 0xee7b, 0xee7c, 0xee7d, 0xee7e, 0xee80, 0xee81, /*0x48-0x4f*/ + 0xee82, 0xee83, 0xee84, 0xee85, 0xee86, 0xee87, 0xee88, 0xee89, /*0x50-0x57*/ + 0xee8a, 0xee8b, 0xee8c, 0xee8d, 0xee8e, 0xee8f, 0xee90, 0xee91, /*0x58-0x5f*/ + 0xee92, 0xee93, 0xee94, 0xee95, 0xee96, 0xee97, 0xee98, 0xee99, /*0x60-0x67*/ + 0xee9a, 0xee9b, 0xee9c, 0xee9d, 0xee9e, 0xee9f, 0xeea0, 0xef40, /*0x68-0x6f*/ + 0xef41, 0xef42, 0xef43, 0xef44, 0xef45, 0xd2b3, 0xb6a5, 0xc7ea, /*0x70-0x77*/ + 0xf1fc, 0xcfee, 0xcbb3, 0xd0eb, 0xe7ef, 0xcde7, 0xb9cb, 0xb6d9, /*0x78-0x7f*/ + 0xf1fd, 0xb0e4, 0xcbcc, 0xf1fe, 0xd4a4, 0xc2ad, 0xc1ec, 0xc6c4, /*0x80-0x87*/ + 0xbeb1, 0xf2a1, 0xbcd5, 0xef46, 0xf2a2, 0xf2a3, 0xef47, 0xf2a4, /*0x88-0x8f*/ + 0xd2c3, 0xc6b5, 0xef48, 0xcdc7, 0xf2a5, 0xef49, 0xd3b1, 0xbfc5, /*0x90-0x97*/ + 0xcce2, 0xef4a, 0xf2a6, 0xf2a7, 0xd1d5, 0xb6ee, 0xf2a8, 0xf2a9, /*0x98-0x9f*/ + 0xb5df, 0xf2aa, 0xf2ab, 0xef4b, 0xb2fc, 0xf2ac, 0xf2ad, 0xc8a7, /*0xa0-0xa7*/ + 0xef4c, 0xef4d, 0xef4e, 0xef4f, 0xef50, 0xef51, 0xef52, 0xef53, /*0xa8-0xaf*/ + 0xef54, 0xef55, 0xef56, 0xef57, 0xef58, 0xef59, 0xef5a, 0xef5b, /*0xb0-0xb7*/ + 0xef5c, 0xef5d, 0xef5e, 0xef5f, 0xef60, 0xef61, 0xef62, 0xef63, /*0xb8-0xbf*/ + 0xef64, 0xef65, 0xef66, 0xef67, 0xef68, 0xef69, 0xef6a, 0xef6b, /*0xc0-0xc7*/ + 0xef6c, 0xef6d, 0xef6e, 0xef6f, 0xef70, 0xef71, 0xb7e7, 0xef72, /*0xc8-0xcf*/ + 0xef73, 0xeca9, 0xecaa, 0xecab, 0xef74, 0xecac, 0xef75, 0xef76, /*0xd0-0xd7*/ + 0xc6ae, 0xecad, 0xecae, 0xef77, 0xef78, 0xef79, 0xb7c9, 0xcab3, /*0xd8-0xdf*/ + 0xef7a, 0xef7b, 0xef7c, 0xef7d, 0xef7e, 0xef80, 0xef81, 0xe2b8, /*0xe0-0xe7*/ + 0xf7cf, 0xef82, 0xef83, 0xef84, 0xef85, 0xef86, 0xef87, 0xef88, /*0xe8-0xef*/ + 0xef89, 0xef8a, 0xef8b, 0xef8c, 0xef8d, 0xef8e, 0xef8f, 0xef90, /*0xf0-0xf7*/ + 0xef91, 0xef92, 0xef93, 0xef94, 0xef95, 0xef96, 0xef97, 0xef98, /*0xf8-0xff*/ + /* 0x9900 */ + 0xef99, 0xef9a, 0xef9b, 0xef9c, 0xef9d, 0xef9e, 0xef9f, 0xefa0, /*0x00-0x07*/ + 0xf040, 0xf041, 0xf042, 0xf043, 0xf044, 0xf7d0, 0xf045, 0xf046, /*0x08-0x0f*/ + 0xb2cd, 0xf047, 0xf048, 0xf049, 0xf04a, 0xf04b, 0xf04c, 0xf04d, /*0x10-0x17*/ + 0xf04e, 0xf04f, 0xf050, 0xf051, 0xf052, 0xf053, 0xf054, 0xf055, /*0x18-0x1f*/ + 0xf056, 0xf057, 0xf058, 0xf059, 0xf05a, 0xf05b, 0xf05c, 0xf05d, /*0x20-0x27*/ + 0xf05e, 0xf05f, 0xf060, 0xf061, 0xf062, 0xf063, 0xf7d1, 0xf064, /*0x28-0x2f*/ + 0xf065, 0xf066, 0xf067, 0xf068, 0xf069, 0xf06a, 0xf06b, 0xf06c, /*0x30-0x37*/ + 0xf06d, 0xf06e, 0xf06f, 0xf070, 0xf071, 0xf072, 0xf073, 0xf074, /*0x38-0x3f*/ + 0xf075, 0xf076, 0xf077, 0xf078, 0xf079, 0xf07a, 0xf07b, 0xf07c, /*0x40-0x47*/ + 0xf07d, 0xf07e, 0xf080, 0xf081, 0xf082, 0xf083, 0xf084, 0xf085, /*0x48-0x4f*/ + 0xf086, 0xf087, 0xf088, 0xf089, 0xf7d3, 0xf7d2, 0xf08a, 0xf08b, /*0x50-0x57*/ + 0xf08c, 0xf08d, 0xf08e, 0xf08f, 0xf090, 0xf091, 0xf092, 0xf093, /*0x58-0x5f*/ + 0xf094, 0xf095, 0xf096, 0xe2bb, 0xf097, 0xbca2, 0xf098, 0xe2bc, /*0x60-0x67*/ + 0xe2bd, 0xe2be, 0xe2bf, 0xe2c0, 0xe2c1, 0xb7b9, 0xd2fb, 0xbda4, /*0x68-0x6f*/ + 0xcace, 0xb1a5, 0xcbc7, 0xf099, 0xe2c2, 0xb6fc, 0xc8c4, 0xe2c3, /*0x70-0x77*/ + 0xf09a, 0xf09b, 0xbdc8, 0xf09c, 0xb1fd, 0xe2c4, 0xf09d, 0xb6f6, /*0x78-0x7f*/ + 0xe2c5, 0xc4d9, 0xf09e, 0xf09f, 0xe2c6, 0xcfda, 0xb9dd, 0xe2c7, /*0x80-0x87*/ + 0xc0a1, 0xf0a0, 0xe2c8, 0xb2f6, 0xf140, 0xe2c9, 0xf141, 0xc1f3, /*0x88-0x8f*/ + 0xe2ca, 0xe2cb, 0xc2f8, 0xe2cc, 0xe2cd, 0xe2ce, 0xcad7, 0xd8b8, /*0x90-0x97*/ + 0xd9e5, 0xcfe3, 0xf142, 0xf143, 0xf144, 0xf145, 0xf146, 0xf147, /*0x98-0x9f*/ + 0xf148, 0xf149, 0xf14a, 0xf14b, 0xf14c, 0xf0a5, 0xf14d, 0xf14e, /*0xa0-0xa7*/ + 0xdcb0, 0xf14f, 0xf150, 0xf151, 0xf152, 0xf153, 0xf154, 0xf155, /*0xa8-0xaf*/ + 0xf156, 0xf157, 0xf158, 0xf159, 0xf15a, 0xf15b, 0xf15c, 0xf15d, /*0xb0-0xb7*/ + 0xf15e, 0xf15f, 0xf160, 0xf161, 0xf162, 0xf163, 0xf164, 0xf165, /*0xb8-0xbf*/ + 0xf166, 0xf167, 0xf168, 0xf169, 0xf16a, 0xf16b, 0xf16c, 0xf16d, /*0xc0-0xc7*/ + 0xf16e, 0xf16f, 0xf170, 0xf171, 0xf172, 0xf173, 0xf174, 0xf175, /*0xc8-0xcf*/ + 0xf176, 0xf177, 0xf178, 0xf179, 0xf17a, 0xf17b, 0xf17c, 0xf17d, /*0xd0-0xd7*/ + 0xf17e, 0xf180, 0xf181, 0xf182, 0xf183, 0xf184, 0xf185, 0xf186, /*0xd8-0xdf*/ + 0xf187, 0xf188, 0xf189, 0xf18a, 0xf18b, 0xf18c, 0xf18d, 0xf18e, /*0xe0-0xe7*/ + 0xf18f, 0xf190, 0xf191, 0xf192, 0xf193, 0xf194, 0xf195, 0xf196, /*0xe8-0xef*/ + 0xf197, 0xf198, 0xf199, 0xf19a, 0xf19b, 0xf19c, 0xf19d, 0xf19e, /*0xf0-0xf7*/ + 0xf19f, 0xf1a0, 0xf240, 0xf241, 0xf242, 0xf243, 0xf244, 0xf245, /*0xf8-0xff*/ + /* 0x9a00 */ + 0xf246, 0xf247, 0xf248, 0xf249, 0xf24a, 0xf24b, 0xf24c, 0xf24d, /*0x00-0x07*/ + 0xf24e, 0xf24f, 0xf250, 0xf251, 0xf252, 0xf253, 0xf254, 0xf255, /*0x08-0x0f*/ + 0xf256, 0xf257, 0xf258, 0xf259, 0xf25a, 0xf25b, 0xf25c, 0xf25d, /*0x10-0x17*/ + 0xf25e, 0xf25f, 0xf260, 0xf261, 0xf262, 0xf263, 0xf264, 0xf265, /*0x18-0x1f*/ + 0xf266, 0xf267, 0xf268, 0xf269, 0xf26a, 0xf26b, 0xf26c, 0xf26d, /*0x20-0x27*/ + 0xf26e, 0xf26f, 0xf270, 0xf271, 0xf272, 0xf273, 0xf274, 0xf275, /*0x28-0x2f*/ + 0xf276, 0xf277, 0xf278, 0xf279, 0xf27a, 0xf27b, 0xf27c, 0xf27d, /*0x30-0x37*/ + 0xf27e, 0xf280, 0xf281, 0xf282, 0xf283, 0xf284, 0xf285, 0xf286, /*0x38-0x3f*/ + 0xf287, 0xf288, 0xf289, 0xf28a, 0xf28b, 0xf28c, 0xf28d, 0xf28e, /*0x40-0x47*/ + 0xf28f, 0xf290, 0xf291, 0xf292, 0xf293, 0xf294, 0xf295, 0xf296, /*0x48-0x4f*/ + 0xf297, 0xf298, 0xf299, 0xf29a, 0xf29b, 0xf29c, 0xf29d, 0xf29e, /*0x50-0x57*/ + 0xf29f, 0xf2a0, 0xf340, 0xf341, 0xf342, 0xf343, 0xf344, 0xf345, /*0x58-0x5f*/ + 0xf346, 0xf347, 0xf348, 0xf349, 0xf34a, 0xf34b, 0xf34c, 0xf34d, /*0x60-0x67*/ + 0xf34e, 0xf34f, 0xf350, 0xf351, 0xc2ed, 0xd4a6, 0xcdd4, 0xd1b1, /*0x68-0x6f*/ + 0xb3db, 0xc7fd, 0xf352, 0xb2b5, 0xc2bf, 0xe6e0, 0xcabb, 0xe6e1, /*0x70-0x77*/ + 0xe6e2, 0xbed4, 0xe6e3, 0xd7a4, 0xcdd5, 0xe6e5, 0xbcdd, 0xe6e4, /*0x78-0x7f*/ + 0xe6e6, 0xe6e7, 0xc2ee, 0xf353, 0xbdbe, 0xe6e8, 0xc2e6, 0xbaa7, /*0x80-0x87*/ + 0xe6e9, 0xf354, 0xe6ea, 0xb3d2, 0xd1e9, 0xf355, 0xf356, 0xbfa5, /*0x88-0x8f*/ + 0xe6eb, 0xc6ef, 0xe6ec, 0xe6ed, 0xf357, 0xf358, 0xe6ee, 0xc6ad, /*0x90-0x97*/ + 0xe6ef, 0xf359, 0xc9a7, 0xe6f0, 0xe6f1, 0xe6f2, 0xe5b9, 0xe6f3, /*0x98-0x9f*/ + 0xe6f4, 0xc2e2, 0xe6f5, 0xe6f6, 0xd6e8, 0xe6f7, 0xf35a, 0xe6f8, /*0xa0-0xa7*/ + 0xb9c7, 0xf35b, 0xf35c, 0xf35d, 0xf35e, 0xf35f, 0xf360, 0xf361, /*0xa8-0xaf*/ + 0xf7bb, 0xf7ba, 0xf362, 0xf363, 0xf364, 0xf365, 0xf7be, 0xf7bc, /*0xb0-0xb7*/ + 0xbaa1, 0xf366, 0xf7bf, 0xf367, 0xf7c0, 0xf368, 0xf369, 0xf36a, /*0xb8-0xbf*/ + 0xf7c2, 0xf7c1, 0xf7c4, 0xf36b, 0xf36c, 0xf7c3, 0xf36d, 0xf36e, /*0xc0-0xc7*/ + 0xf36f, 0xf370, 0xf371, 0xf7c5, 0xf7c6, 0xf372, 0xf373, 0xf374, /*0xc8-0xcf*/ + 0xf375, 0xf7c7, 0xf376, 0xcbe8, 0xf377, 0xf378, 0xf379, 0xf37a, /*0xd0-0xd7*/ + 0xb8df, 0xf37b, 0xf37c, 0xf37d, 0xf37e, 0xf380, 0xf381, 0xf7d4, /*0xd8-0xdf*/ + 0xf382, 0xf7d5, 0xf383, 0xf384, 0xf385, 0xf386, 0xf7d6, 0xf387, /*0xe0-0xe7*/ + 0xf388, 0xf389, 0xf38a, 0xf7d8, 0xf38b, 0xf7da, 0xf38c, 0xf7d7, /*0xe8-0xef*/ + 0xf38d, 0xf38e, 0xf38f, 0xf390, 0xf391, 0xf392, 0xf393, 0xf394, /*0xf0-0xf7*/ + 0xf395, 0xf7db, 0xf396, 0xf7d9, 0xf397, 0xf398, 0xf399, 0xf39a, /*0xf8-0xff*/ + /* 0x9b00 */ + 0xf39b, 0xf39c, 0xf39d, 0xd7d7, 0xf39e, 0xf39f, 0xf3a0, 0xf440, /*0x00-0x07*/ + 0xf7dc, 0xf441, 0xf442, 0xf443, 0xf444, 0xf445, 0xf446, 0xf7dd, /*0x08-0x0f*/ + 0xf447, 0xf448, 0xf449, 0xf7de, 0xf44a, 0xf44b, 0xf44c, 0xf44d, /*0x10-0x17*/ + 0xf44e, 0xf44f, 0xf450, 0xf451, 0xf452, 0xf453, 0xf454, 0xf7df, /*0x18-0x1f*/ + 0xf455, 0xf456, 0xf457, 0xf7e0, 0xf458, 0xf459, 0xf45a, 0xf45b, /*0x20-0x27*/ + 0xf45c, 0xf45d, 0xf45e, 0xf45f, 0xf460, 0xf461, 0xf462, 0xdbcb, /*0x28-0x2f*/ + 0xf463, 0xf464, 0xd8aa, 0xf465, 0xf466, 0xf467, 0xf468, 0xf469, /*0x30-0x37*/ + 0xf46a, 0xf46b, 0xf46c, 0xe5f7, 0xb9ed, 0xf46d, 0xf46e, 0xf46f, /*0x38-0x3f*/ + 0xf470, 0xbffd, 0xbbea, 0xf7c9, 0xc6c7, 0xf7c8, 0xf471, 0xf7ca, /*0x40-0x47*/ + 0xf7cc, 0xf7cb, 0xf472, 0xf473, 0xf474, 0xf7cd, 0xf475, 0xceba, /*0x48-0x4f*/ + 0xf476, 0xf7ce, 0xf477, 0xf478, 0xc4a7, 0xf479, 0xf47a, 0xf47b, /*0x50-0x57*/ + 0xf47c, 0xf47d, 0xf47e, 0xf480, 0xf481, 0xf482, 0xf483, 0xf484, /*0x58-0x5f*/ + 0xf485, 0xf486, 0xf487, 0xf488, 0xf489, 0xf48a, 0xf48b, 0xf48c, /*0x60-0x67*/ + 0xf48d, 0xf48e, 0xf48f, 0xf490, 0xf491, 0xf492, 0xf493, 0xf494, /*0x68-0x6f*/ + 0xf495, 0xf496, 0xf497, 0xf498, 0xf499, 0xf49a, 0xf49b, 0xf49c, /*0x70-0x77*/ + 0xf49d, 0xf49e, 0xf49f, 0xf4a0, 0xf540, 0xf541, 0xf542, 0xf543, /*0x78-0x7f*/ + 0xf544, 0xf545, 0xf546, 0xf547, 0xf548, 0xf549, 0xf54a, 0xf54b, /*0x80-0x87*/ + 0xf54c, 0xf54d, 0xf54e, 0xf54f, 0xf550, 0xf551, 0xf552, 0xf553, /*0x88-0x8f*/ + 0xf554, 0xf555, 0xf556, 0xf557, 0xf558, 0xf559, 0xf55a, 0xf55b, /*0x90-0x97*/ + 0xf55c, 0xf55d, 0xf55e, 0xf55f, 0xf560, 0xf561, 0xf562, 0xf563, /*0x98-0x9f*/ + 0xf564, 0xf565, 0xf566, 0xf567, 0xf568, 0xf569, 0xf56a, 0xf56b, /*0xa0-0xa7*/ + 0xf56c, 0xf56d, 0xf56e, 0xf56f, 0xf570, 0xf571, 0xf572, 0xf573, /*0xa8-0xaf*/ + 0xf574, 0xf575, 0xf576, 0xf577, 0xf578, 0xf579, 0xf57a, 0xf57b, /*0xb0-0xb7*/ + 0xf57c, 0xf57d, 0xf57e, 0xf580, 0xf581, 0xf582, 0xf583, 0xf584, /*0xb8-0xbf*/ + 0xf585, 0xf586, 0xf587, 0xf588, 0xf589, 0xf58a, 0xf58b, 0xf58c, /*0xc0-0xc7*/ + 0xf58d, 0xf58e, 0xf58f, 0xf590, 0xf591, 0xf592, 0xf593, 0xf594, /*0xc8-0xcf*/ + 0xf595, 0xf596, 0xf597, 0xf598, 0xf599, 0xf59a, 0xf59b, 0xf59c, /*0xd0-0xd7*/ + 0xf59d, 0xf59e, 0xf59f, 0xf5a0, 0xf640, 0xf641, 0xf642, 0xf643, /*0xd8-0xdf*/ + 0xf644, 0xf645, 0xf646, 0xf647, 0xf648, 0xf649, 0xf64a, 0xf64b, /*0xe0-0xe7*/ + 0xf64c, 0xf64d, 0xf64e, 0xf64f, 0xf650, 0xf651, 0xf652, 0xf653, /*0xe8-0xef*/ + 0xf654, 0xf655, 0xf656, 0xf657, 0xf658, 0xf659, 0xf65a, 0xf65b, /*0xf0-0xf7*/ + 0xf65c, 0xf65d, 0xf65e, 0xf65f, 0xf660, 0xf661, 0xf662, 0xf663, /*0xf8-0xff*/ + /* 0x9c00 */ + 0xf664, 0xf665, 0xf666, 0xf667, 0xf668, 0xf669, 0xf66a, 0xf66b, /*0x00-0x07*/ + 0xf66c, 0xf66d, 0xf66e, 0xf66f, 0xf670, 0xf671, 0xf672, 0xf673, /*0x08-0x0f*/ + 0xf674, 0xf675, 0xf676, 0xf677, 0xf678, 0xf679, 0xf67a, 0xf67b, /*0x10-0x17*/ + 0xf67c, 0xf67d, 0xf67e, 0xf680, 0xf681, 0xf682, 0xf683, 0xf684, /*0x18-0x1f*/ + 0xf685, 0xf686, 0xf687, 0xf688, 0xf689, 0xf68a, 0xf68b, 0xf68c, /*0x20-0x27*/ + 0xf68d, 0xf68e, 0xf68f, 0xf690, 0xf691, 0xf692, 0xf693, 0xf694, /*0x28-0x2f*/ + 0xf695, 0xf696, 0xf697, 0xf698, 0xf699, 0xf69a, 0xf69b, 0xf69c, /*0x30-0x37*/ + 0xf69d, 0xf69e, 0xf69f, 0xf6a0, 0xf740, 0xf741, 0xf742, 0xf743, /*0x38-0x3f*/ + 0xf744, 0xf745, 0xf746, 0xf747, 0xf748, 0xf749, 0xf74a, 0xf74b, /*0x40-0x47*/ + 0xf74c, 0xf74d, 0xf74e, 0xf74f, 0xf750, 0xf751, 0xf752, 0xf753, /*0x48-0x4f*/ + 0xf754, 0xf755, 0xf756, 0xf757, 0xf758, 0xf759, 0xf75a, 0xf75b, /*0x50-0x57*/ + 0xf75c, 0xf75d, 0xf75e, 0xf75f, 0xf760, 0xf761, 0xf762, 0xf763, /*0x58-0x5f*/ + 0xf764, 0xf765, 0xf766, 0xf767, 0xf768, 0xf769, 0xf76a, 0xf76b, /*0x60-0x67*/ + 0xf76c, 0xf76d, 0xf76e, 0xf76f, 0xf770, 0xf771, 0xf772, 0xf773, /*0x68-0x6f*/ + 0xf774, 0xf775, 0xf776, 0xf777, 0xf778, 0xf779, 0xf77a, 0xf77b, /*0x70-0x77*/ + 0xf77c, 0xf77d, 0xf77e, 0xf780, 0xd3e3, 0xf781, 0xf782, 0xf6cf, /*0x78-0x7f*/ + 0xf783, 0xc2b3, 0xf6d0, 0xf784, 0xf785, 0xf6d1, 0xf6d2, 0xf6d3, /*0x80-0x87*/ + 0xf6d4, 0xf786, 0xf787, 0xf6d6, 0xf788, 0xb1ab, 0xf6d7, 0xf789, /*0x88-0x8f*/ + 0xf6d8, 0xf6d9, 0xf6da, 0xf78a, 0xf6db, 0xf6dc, 0xf78b, 0xf78c, /*0x90-0x97*/ + 0xf78d, 0xf78e, 0xf6dd, 0xf6de, 0xcfca, 0xf78f, 0xf6df, 0xf6e0, /*0x98-0x9f*/ + 0xf6e1, 0xf6e2, 0xf6e3, 0xf6e4, 0xc0f0, 0xf6e5, 0xf6e6, 0xf6e7, /*0xa0-0xa7*/ + 0xf6e8, 0xf6e9, 0xf790, 0xf6ea, 0xf791, 0xf6eb, 0xf6ec, 0xf792, /*0xa8-0xaf*/ + 0xf6ed, 0xf6ee, 0xf6ef, 0xf6f0, 0xf6f1, 0xf6f2, 0xf6f3, 0xf6f4, /*0xb0-0xb7*/ + 0xbea8, 0xf793, 0xf6f5, 0xf6f6, 0xf6f7, 0xf6f8, 0xf794, 0xf795, /*0xb8-0xbf*/ + 0xf796, 0xf797, 0xf798, 0xc8fa, 0xf6f9, 0xf6fa, 0xf6fb, 0xf6fc, /*0xc0-0xc7*/ + 0xf799, 0xf79a, 0xf6fd, 0xf6fe, 0xf7a1, 0xf7a2, 0xf7a3, 0xf7a4, /*0xc8-0xcf*/ + 0xf7a5, 0xf79b, 0xf79c, 0xf7a6, 0xf7a7, 0xf7a8, 0xb1ee, 0xf7a9, /*0xd0-0xd7*/ + 0xf7aa, 0xf7ab, 0xf79d, 0xf79e, 0xf7ac, 0xf7ad, 0xc1db, 0xf7ae, /*0xd8-0xdf*/ + 0xf79f, 0xf7a0, 0xf7af, 0xf840, 0xf841, 0xf842, 0xf843, 0xf844, /*0xe0-0xe7*/ + 0xf845, 0xf846, 0xf847, 0xf848, 0xf849, 0xf84a, 0xf84b, 0xf84c, /*0xe8-0xef*/ + 0xf84d, 0xf84e, 0xf84f, 0xf850, 0xf851, 0xf852, 0xf853, 0xf854, /*0xf0-0xf7*/ + 0xf855, 0xf856, 0xf857, 0xf858, 0xf859, 0xf85a, 0xf85b, 0xf85c, /*0xf8-0xff*/ + /* 0x9d00 */ + 0xf85d, 0xf85e, 0xf85f, 0xf860, 0xf861, 0xf862, 0xf863, 0xf864, /*0x00-0x07*/ + 0xf865, 0xf866, 0xf867, 0xf868, 0xf869, 0xf86a, 0xf86b, 0xf86c, /*0x08-0x0f*/ + 0xf86d, 0xf86e, 0xf86f, 0xf870, 0xf871, 0xf872, 0xf873, 0xf874, /*0x10-0x17*/ + 0xf875, 0xf876, 0xf877, 0xf878, 0xf879, 0xf87a, 0xf87b, 0xf87c, /*0x18-0x1f*/ + 0xf87d, 0xf87e, 0xf880, 0xf881, 0xf882, 0xf883, 0xf884, 0xf885, /*0x20-0x27*/ + 0xf886, 0xf887, 0xf888, 0xf889, 0xf88a, 0xf88b, 0xf88c, 0xf88d, /*0x28-0x2f*/ + 0xf88e, 0xf88f, 0xf890, 0xf891, 0xf892, 0xf893, 0xf894, 0xf895, /*0x30-0x37*/ + 0xf896, 0xf897, 0xf898, 0xf899, 0xf89a, 0xf89b, 0xf89c, 0xf89d, /*0x38-0x3f*/ + 0xf89e, 0xf89f, 0xf8a0, 0xf940, 0xf941, 0xf942, 0xf943, 0xf944, /*0x40-0x47*/ + 0xf945, 0xf946, 0xf947, 0xf948, 0xf949, 0xf94a, 0xf94b, 0xf94c, /*0x48-0x4f*/ + 0xf94d, 0xf94e, 0xf94f, 0xf950, 0xf951, 0xf952, 0xf953, 0xf954, /*0x50-0x57*/ + 0xf955, 0xf956, 0xf957, 0xf958, 0xf959, 0xf95a, 0xf95b, 0xf95c, /*0x58-0x5f*/ + 0xf95d, 0xf95e, 0xf95f, 0xf960, 0xf961, 0xf962, 0xf963, 0xf964, /*0x60-0x67*/ + 0xf965, 0xf966, 0xf967, 0xf968, 0xf969, 0xf96a, 0xf96b, 0xf96c, /*0x68-0x6f*/ + 0xf96d, 0xf96e, 0xf96f, 0xf970, 0xf971, 0xf972, 0xf973, 0xf974, /*0x70-0x77*/ + 0xf975, 0xf976, 0xf977, 0xf978, 0xf979, 0xf97a, 0xf97b, 0xf97c, /*0x78-0x7f*/ + 0xf97d, 0xf97e, 0xf980, 0xf981, 0xf982, 0xf983, 0xf984, 0xf985, /*0x80-0x87*/ + 0xf986, 0xf987, 0xf988, 0xf989, 0xf98a, 0xf98b, 0xf98c, 0xf98d, /*0x88-0x8f*/ + 0xf98e, 0xf98f, 0xf990, 0xf991, 0xf992, 0xf993, 0xf994, 0xf995, /*0x90-0x97*/ + 0xf996, 0xf997, 0xf998, 0xf999, 0xf99a, 0xf99b, 0xf99c, 0xf99d, /*0x98-0x9f*/ + 0xf99e, 0xf99f, 0xf9a0, 0xfa40, 0xfa41, 0xfa42, 0xfa43, 0xfa44, /*0xa0-0xa7*/ + 0xfa45, 0xfa46, 0xfa47, 0xfa48, 0xfa49, 0xfa4a, 0xfa4b, 0xfa4c, /*0xa8-0xaf*/ + 0xfa4d, 0xfa4e, 0xfa4f, 0xfa50, 0xfa51, 0xfa52, 0xfa53, 0xfa54, /*0xb0-0xb7*/ + 0xfa55, 0xfa56, 0xfa57, 0xfa58, 0xfa59, 0xfa5a, 0xfa5b, 0xfa5c, /*0xb8-0xbf*/ + 0xfa5d, 0xfa5e, 0xfa5f, 0xfa60, 0xfa61, 0xfa62, 0xfa63, 0xfa64, /*0xc0-0xc7*/ + 0xfa65, 0xfa66, 0xfa67, 0xfa68, 0xfa69, 0xfa6a, 0xfa6b, 0xfa6c, /*0xc8-0xcf*/ + 0xfa6d, 0xfa6e, 0xfa6f, 0xfa70, 0xfa71, 0xfa72, 0xfa73, 0xfa74, /*0xd0-0xd7*/ + 0xfa75, 0xfa76, 0xfa77, 0xfa78, 0xfa79, 0xfa7a, 0xfa7b, 0xfa7c, /*0xd8-0xdf*/ + 0xfa7d, 0xfa7e, 0xfa80, 0xfa81, 0xfa82, 0xfa83, 0xfa84, 0xfa85, /*0xe0-0xe7*/ + 0xfa86, 0xfa87, 0xfa88, 0xfa89, 0xfa8a, 0xfa8b, 0xfa8c, 0xfa8d, /*0xe8-0xef*/ + 0xfa8e, 0xfa8f, 0xfa90, 0xfa91, 0xfa92, 0xfa93, 0xfa94, 0xfa95, /*0xf0-0xf7*/ + 0xfa96, 0xfa97, 0xfa98, 0xfa99, 0xfa9a, 0xfa9b, 0xfa9c, 0xfa9d, /*0xf8-0xff*/ + /* 0x9e00 */ + 0xfa9e, 0xfa9f, 0xfaa0, 0xfb40, 0xfb41, 0xfb42, 0xfb43, 0xfb44, /*0x00-0x07*/ + 0xfb45, 0xfb46, 0xfb47, 0xfb48, 0xfb49, 0xfb4a, 0xfb4b, 0xfb4c, /*0x08-0x0f*/ + 0xfb4d, 0xfb4e, 0xfb4f, 0xfb50, 0xfb51, 0xfb52, 0xfb53, 0xfb54, /*0x10-0x17*/ + 0xfb55, 0xfb56, 0xfb57, 0xfb58, 0xfb59, 0xfb5a, 0xfb5b, 0xc4f1, /*0x18-0x1f*/ + 0xf0af, 0xbca6, 0xf0b0, 0xc3f9, 0xfb5c, 0xc5b8, 0xd1bb, 0xfb5d, /*0x20-0x27*/ + 0xf0b1, 0xf0b2, 0xf0b3, 0xf0b4, 0xf0b5, 0xd1bc, 0xfb5e, 0xd1ec, /*0x28-0x2f*/ + 0xfb5f, 0xf0b7, 0xf0b6, 0xd4a7, 0xfb60, 0xcdd2, 0xf0b8, 0xf0ba, /*0x30-0x37*/ + 0xf0b9, 0xf0bb, 0xf0bc, 0xfb61, 0xfb62, 0xb8eb, 0xf0bd, 0xbae8, /*0x38-0x3f*/ + 0xfb63, 0xf0be, 0xf0bf, 0xbee9, 0xf0c0, 0xb6ec, 0xf0c1, 0xf0c2, /*0x40-0x47*/ + 0xf0c3, 0xf0c4, 0xc8b5, 0xf0c5, 0xf0c6, 0xfb64, 0xf0c7, 0xc5f4, /*0x48-0x4f*/ + 0xfb65, 0xf0c8, 0xfb66, 0xfb67, 0xfb68, 0xf0c9, 0xfb69, 0xf0ca, /*0x50-0x57*/ + 0xf7bd, 0xfb6a, 0xf0cb, 0xf0cc, 0xf0cd, 0xfb6b, 0xf0ce, 0xfb6c, /*0x58-0x5f*/ + 0xfb6d, 0xfb6e, 0xfb6f, 0xf0cf, 0xbad7, 0xfb70, 0xf0d0, 0xf0d1, /*0x60-0x67*/ + 0xf0d2, 0xf0d3, 0xf0d4, 0xf0d5, 0xf0d6, 0xf0d8, 0xfb71, 0xfb72, /*0x68-0x6f*/ + 0xd3a5, 0xf0d7, 0xfb73, 0xf0d9, 0xfb74, 0xfb75, 0xfb76, 0xfb77, /*0x70-0x77*/ + 0xfb78, 0xfb79, 0xfb7a, 0xfb7b, 0xfb7c, 0xfb7d, 0xf5ba, 0xc2b9, /*0x78-0x7f*/ + 0xfb7e, 0xfb80, 0xf7e4, 0xfb81, 0xfb82, 0xfb83, 0xfb84, 0xf7e5, /*0x80-0x87*/ + 0xf7e6, 0xfb85, 0xfb86, 0xf7e7, 0xfb87, 0xfb88, 0xfb89, 0xfb8a, /*0x88-0x8f*/ + 0xfb8b, 0xfb8c, 0xf7e8, 0xc2b4, 0xfb8d, 0xfb8e, 0xfb8f, 0xfb90, /*0x90-0x97*/ + 0xfb91, 0xfb92, 0xfb93, 0xfb94, 0xfb95, 0xf7ea, 0xfb96, 0xf7eb, /*0x98-0x9f*/ + 0xfb97, 0xfb98, 0xfb99, 0xfb9a, 0xfb9b, 0xfb9c, 0xc2f3, 0xfb9d, /*0xa0-0xa7*/ + 0xfb9e, 0xfb9f, 0xfba0, 0xfc40, 0xfc41, 0xfc42, 0xfc43, 0xfc44, /*0xa8-0xaf*/ + 0xfc45, 0xfc46, 0xfc47, 0xfc48, 0xf4f0, 0xfc49, 0xfc4a, 0xfc4b, /*0xb0-0xb7*/ + 0xf4ef, 0xfc4c, 0xfc4d, 0xc2e9, 0xfc4e, 0xf7e1, 0xf7e2, 0xfc4f, /*0xb8-0xbf*/ + 0xfc50, 0xfc51, 0xfc52, 0xfc53, 0xbbc6, 0xfc54, 0xfc55, 0xfc56, /*0xc0-0xc7*/ + 0xfc57, 0xd9e4, 0xfc58, 0xfc59, 0xfc5a, 0xcaf2, 0xc0e8, 0xf0a4, /*0xc8-0xcf*/ + 0xfc5b, 0xbada, 0xfc5c, 0xfc5d, 0xc7ad, 0xfc5e, 0xfc5f, 0xfc60, /*0xd0-0xd7*/ + 0xc4ac, 0xfc61, 0xfc62, 0xf7ec, 0xf7ed, 0xf7ee, 0xfc63, 0xf7f0, /*0xd8-0xdf*/ + 0xf7ef, 0xfc64, 0xf7f1, 0xfc65, 0xfc66, 0xf7f4, 0xfc67, 0xf7f3, /*0xe0-0xe7*/ + 0xfc68, 0xf7f2, 0xf7f5, 0xfc69, 0xfc6a, 0xfc6b, 0xfc6c, 0xf7f6, /*0xe8-0xef*/ + 0xfc6d, 0xfc6e, 0xfc6f, 0xfc70, 0xfc71, 0xfc72, 0xfc73, 0xfc74, /*0xf0-0xf7*/ + 0xfc75, 0xede9, 0xfc76, 0xedea, 0xedeb, 0xfc77, 0xf6bc, 0xfc78, /*0xf8-0xff*/ + /* 0x9f00 */ + 0xfc79, 0xfc7a, 0xfc7b, 0xfc7c, 0xfc7d, 0xfc7e, 0xfc80, 0xfc81, /*0x00-0x07*/ + 0xfc82, 0xfc83, 0xfc84, 0xf6bd, 0xfc85, 0xf6be, 0xb6a6, 0xfc86, /*0x08-0x0f*/ + 0xd8be, 0xfc87, 0xfc88, 0xb9c4, 0xfc89, 0xfc8a, 0xfc8b, 0xd8bb, /*0x10-0x17*/ + 0xfc8c, 0xdcb1, 0xfc8d, 0xfc8e, 0xfc8f, 0xfc90, 0xfc91, 0xfc92, /*0x18-0x1f*/ + 0xcaf3, 0xfc93, 0xf7f7, 0xfc94, 0xfc95, 0xfc96, 0xfc97, 0xfc98, /*0x20-0x27*/ + 0xfc99, 0xfc9a, 0xfc9b, 0xfc9c, 0xf7f8, 0xfc9d, 0xfc9e, 0xf7f9, /*0x28-0x2f*/ + 0xfc9f, 0xfca0, 0xfd40, 0xfd41, 0xfd42, 0xfd43, 0xfd44, 0xf7fb, /*0x30-0x37*/ + 0xfd45, 0xf7fa, 0xfd46, 0xb1c7, 0xfd47, 0xf7fc, 0xf7fd, 0xfd48, /*0x38-0x3f*/ + 0xfd49, 0xfd4a, 0xfd4b, 0xfd4c, 0xf7fe, 0xfd4d, 0xfd4e, 0xfd4f, /*0x40-0x47*/ + 0xfd50, 0xfd51, 0xfd52, 0xfd53, 0xfd54, 0xfd55, 0xfd56, 0xfd57, /*0x48-0x4f*/ + 0xc6eb, 0xecb4, 0xfd58, 0xfd59, 0xfd5a, 0xfd5b, 0xfd5c, 0xfd5d, /*0x50-0x57*/ + 0xfd5e, 0xfd5f, 0xfd60, 0xfd61, 0xfd62, 0xfd63, 0xfd64, 0xfd65, /*0x58-0x5f*/ + 0xfd66, 0xfd67, 0xfd68, 0xfd69, 0xfd6a, 0xfd6b, 0xfd6c, 0xfd6d, /*0x60-0x67*/ + 0xfd6e, 0xfd6f, 0xfd70, 0xfd71, 0xfd72, 0xfd73, 0xfd74, 0xfd75, /*0x68-0x6f*/ + 0xfd76, 0xfd77, 0xfd78, 0xfd79, 0xfd7a, 0xfd7b, 0xfd7c, 0xfd7d, /*0x70-0x77*/ + 0xfd7e, 0xfd80, 0xfd81, 0xfd82, 0xfd83, 0xfd84, 0xfd85, 0xb3dd, /*0x78-0x7f*/ + 0xf6b3, 0xfd86, 0xfd87, 0xf6b4, 0xc1e4, 0xf6b5, 0xf6b6, 0xf6b7, /*0x80-0x87*/ + 0xf6b8, 0xf6b9, 0xf6ba, 0xc8a3, 0xf6bb, 0xfd88, 0xfd89, 0xfd8a, /*0x88-0x8f*/ + 0xfd8b, 0xfd8c, 0xfd8d, 0xfd8e, 0xfd8f, 0xfd90, 0xfd91, 0xfd92, /*0x90-0x97*/ + 0xfd93, 0xc1fa, 0xb9a8, 0xede8, 0xfd94, 0xfd95, 0xfd96, 0xb9ea, /*0x98-0x9f*/ + 0xd9df, 0xfd97, 0xfd98, 0xfd99, 0xfd9a, 0xfd9b, 0x0000, 0x0000, /*0xa0-0xa7*/ +}; +static const unsigned short cp936ext_page1f2f[32] = { + 0x0000, 0xfd9d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x78-0x7f*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x80-0x87*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x88-0x8f*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xfd9e, 0x0000, 0x0000, /*0x90-0x97*/ +}; +static const unsigned short cp936ext_page1f3c[24] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xfd9f, /*0xe0-0xe7*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0xe8-0xef*/ + 0x0000, 0xfda0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0xf0-0xf7*/ +}; +static const unsigned short cp936ext_page1f41[40] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0xfe40, 0xfe41, 0xfe42, 0xfe43, /*0x08-0x0f*/ + 0x0000, 0xfe44, 0x0000, 0xfe45, 0xfe46, 0x0000, 0x0000, 0x0000, /*0x10-0x17*/ + 0xfe47, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xfe48, /*0x18-0x1f*/ + 0xfe49, 0xfe4a, 0x0000, 0xfe4b, 0xfe4c, 0x0000, 0x0000, 0xfe4d, /*0x20-0x27*/ + 0xfe4e, 0xfe4f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x28-0x2f*/ +}; +static const unsigned short cp936ext_page1fc6[64] = { + 0xa955, 0xa6f2, 0x0000, 0xa6f4, 0xa6f5, 0xa6e0, 0xa6e1, 0xa6f0, /*0x30-0x37*/ + 0xa6f1, 0xa6e2, 0xa6e3, 0xa6ee, 0xa6ef, 0xa6e6, 0xa6e7, 0xa6e4, /*0x38-0x3f*/ + 0xa6e5, 0xa6e8, 0xa6e9, 0xa6ea, 0xa6eb, 0x0000, 0x0000, 0x0000, /*0x40-0x47*/ + 0x0000, 0xa968, 0xa969, 0xa96a, 0xa96b, 0xa96c, 0xa96d, 0xa96e, /*0x48-0x4f*/ + 0xa96f, 0xa970, 0xa971, 0x0000, 0xa972, 0xa973, 0xa974, 0xa975, /*0x50-0x57*/ + 0x0000, 0xa976, 0xa977, 0xa978, 0xa979, 0xa97a, 0xa97b, 0xa97c, /*0x58-0x5f*/ + 0xa97d, 0xa97e, 0xa980, 0xa981, 0xa982, 0xa983, 0xa984, 0x0000, /*0x60-0x67*/ + 0xa985, 0xa986, 0xa987, 0xa988, 0x0000, 0x0000, 0x0000, 0x0000, /*0x68-0x6f*/ +}; +static const unsigned short cp936ext_page1fe0[96] = { + 0x0000, 0xa3a1, 0xa3a2, 0xa3a3, 0xa1e7, 0xa3a5, 0xa3a6, 0xa3a7, /*0x00-0x07*/ + 0xa3a8, 0xa3a9, 0xa3aa, 0xa3ab, 0xa3ac, 0xa3ad, 0xa3ae, 0xa3af, /*0x08-0x0f*/ + 0xa3b0, 0xa3b1, 0xa3b2, 0xa3b3, 0xa3b4, 0xa3b5, 0xa3b6, 0xa3b7, /*0x10-0x17*/ + 0xa3b8, 0xa3b9, 0xa3ba, 0xa3bb, 0xa3bc, 0xa3bd, 0xa3be, 0xa3bf, /*0x18-0x1f*/ + 0xa3c0, 0xa3c1, 0xa3c2, 0xa3c3, 0xa3c4, 0xa3c5, 0xa3c6, 0xa3c7, /*0x20-0x27*/ + 0xa3c8, 0xa3c9, 0xa3ca, 0xa3cb, 0xa3cc, 0xa3cd, 0xa3ce, 0xa3cf, /*0x28-0x2f*/ + 0xa3d0, 0xa3d1, 0xa3d2, 0xa3d3, 0xa3d4, 0xa3d5, 0xa3d6, 0xa3d7, /*0x30-0x37*/ + 0xa3d8, 0xa3d9, 0xa3da, 0xa3db, 0xa3dc, 0xa3dd, 0xa3de, 0xa3df, /*0x38-0x3f*/ + 0xa3e0, 0xa3e1, 0xa3e2, 0xa3e3, 0xa3e4, 0xa3e5, 0xa3e6, 0xa3e7, /*0x40-0x47*/ + 0xa3e8, 0xa3e9, 0xa3ea, 0xa3eb, 0xa3ec, 0xa3ed, 0xa3ee, 0xa3ef, /*0x48-0x4f*/ + 0xa3f0, 0xa3f1, 0xa3f2, 0xa3f3, 0xa3f4, 0xa3f5, 0xa3f6, 0xa3f7, /*0x50-0x57*/ + 0xa3f8, 0xa3f9, 0xa3fa, 0xa3fb, 0xa3fc, 0xa3fd, 0xa1ab, 0x0000, /*0x58-0x5f*/ +}; +static const unsigned short cp936ext_page1ffc[8] = { + 0xa1e9, 0xa1ea, 0xa956, 0xa3fe, 0xa957, 0xa3a4, 0x0000, 0x0000, /*0xe0-0xe7*/ +}; + +static int +cp936ext_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (n >= 2) { + unsigned short c = 0; + if (wc >= 0x00a0 && wc < 0x0170) + c = cp936ext_page0014[wc-0x00a0]; + else if (wc >= 0x01c8 && wc < 0x01e0) + c = cp936ext_page0039[wc-0x01c8]; + else if (wc >= 0x0250 && wc < 0x0268) + c = cp936ext_page004a[wc-0x0250]; + else if (wc >= 0x02c0 && wc < 0x02e0) + c = cp936ext_page0058[wc-0x02c0]; + else if (wc >= 0x0390 && wc < 0x03d0) + c = cp936ext_page0072[wc-0x0390]; + else if (wc >= 0x0400 && wc < 0x0458) + c = cp936ext_page0080[wc-0x0400]; + else if (wc >= 0x2010 && wc < 0x2040) + c = cp936ext_page0402[wc-0x2010]; + else if (wc >= 0x2100 && wc < 0x21a0) + c = cp936ext_page0420[wc-0x2100]; + else if (wc >= 0x2208 && wc < 0x22c0) + c = cp936ext_page0441[wc-0x2208]; + else if (wc == 0x2312) + c = 0xa1d0; + else if (wc >= 0x2460 && wc < 0x24a0) + c = cp936ext_page048c[wc-0x2460]; + else if (wc >= 0x2500 && wc < 0x25e8) + c = cp936ext_page04a0[wc-0x2500]; + else if (wc >= 0x2600 && wc < 0x2648) + c = cp936ext_page04c0[wc-0x2600]; + else if (wc >= 0x3000 && wc < 0x3130) + c = cp936ext_page0600[wc-0x3000]; + else if (wc >= 0x3220 && wc < 0x3238) + c = cp936ext_page0644[wc-0x3220]; + else if (wc == 0x32a3) + c = 0xa949; + else if (wc >= 0x3388 && wc < 0x33d8) + c = cp936ext_page0671[wc-0x3388]; + else if (wc >= 0x4e00 && wc < 0x9fa8) + c = cp936ext_page09c0[wc-0x4e00]; + else if (wc == 0xf92c) + c = 0xfd9c; + else if (wc >= 0xf978 && wc < 0xf998) + c = cp936ext_page1f2f[wc-0xf978]; + else if (wc >= 0xf9e0 && wc < 0xf9f8) + c = cp936ext_page1f3c[wc-0xf9e0]; + else if (wc >= 0xfa08 && wc < 0xfa30) + c = cp936ext_page1f41[wc-0xfa08]; + else if (wc >= 0xfe30 && wc < 0xfe70) + c = cp936ext_page1fc6[wc-0xfe30]; + else if (wc >= 0xff00 && wc < 0xff60) + c = cp936ext_page1fe0[wc-0xff00]; + else if (wc >= 0xffe0 && wc < 0xffe8) + c = cp936ext_page1ffc[wc-0xffe0]; + if (c != 0) { + r[0] = (c >> 8); r[1] = (c & 0xff); + return 2; + } + return RET_ILSEQ; + } + return RET_TOOSMALL; +} + +#endif // CP936 + +#endif // __APPLE__ WIN32 + +// +// End of "$Id$". +// diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/gb2312.h b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/gb2312.h new file mode 100644 index 0000000..3c0c359 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/gb2312.h @@ -0,0 +1,2553 @@ +/* $XFree86: xc/lib/X11/lcUniConv/gb2312.h,v 1.5 2003/05/27 22:26:29 tsi Exp $ */ + +/* + * GB2312.1980-0 + */ + +static const unsigned short gb2312_2uni_page21[831] = { + /* 0x21 */ + 0x3000, 0x3001, 0x3002, 0x30fb, 0x02c9, 0x02c7, 0x00a8, 0x3003, + 0x3005, 0x2015, 0xff5e, 0x2016, 0x2026, 0x2018, 0x2019, 0x201c, + 0x201d, 0x3014, 0x3015, 0x3008, 0x3009, 0x300a, 0x300b, 0x300c, + 0x300d, 0x300e, 0x300f, 0x3016, 0x3017, 0x3010, 0x3011, 0x00b1, + 0x00d7, 0x00f7, 0x2236, 0x2227, 0x2228, 0x2211, 0x220f, 0x222a, + 0x2229, 0x2208, 0x2237, 0x221a, 0x22a5, 0x2225, 0x2220, 0x2312, + 0x2299, 0x222b, 0x222e, 0x2261, 0x224c, 0x2248, 0x223d, 0x221d, + 0x2260, 0x226e, 0x226f, 0x2264, 0x2265, 0x221e, 0x2235, 0x2234, + 0x2642, 0x2640, 0x00b0, 0x2032, 0x2033, 0x2103, 0xff04, 0x00a4, + 0xffe0, 0xffe1, 0x2030, 0x00a7, 0x2116, 0x2606, 0x2605, 0x25cb, + 0x25cf, 0x25ce, 0x25c7, 0x25c6, 0x25a1, 0x25a0, 0x25b3, 0x25b2, + 0x203b, 0x2192, 0x2190, 0x2191, 0x2193, 0x3013, + /* 0x22 */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x2488, 0x2489, 0x248a, 0x248b, 0x248c, 0x248d, 0x248e, 0x248f, + 0x2490, 0x2491, 0x2492, 0x2493, 0x2494, 0x2495, 0x2496, 0x2497, + 0x2498, 0x2499, 0x249a, 0x249b, 0x2474, 0x2475, 0x2476, 0x2477, + 0x2478, 0x2479, 0x247a, 0x247b, 0x247c, 0x247d, 0x247e, 0x247f, + 0x2480, 0x2481, 0x2482, 0x2483, 0x2484, 0x2485, 0x2486, 0x2487, + 0x2460, 0x2461, 0x2462, 0x2463, 0x2464, 0x2465, 0x2466, 0x2467, + 0x2468, 0x2469, 0xfffd, 0xfffd, 0x3220, 0x3221, 0x3222, 0x3223, + 0x3224, 0x3225, 0x3226, 0x3227, 0x3228, 0x3229, 0xfffd, 0xfffd, + 0x2160, 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, + 0x2168, 0x2169, 0x216a, 0x216b, 0xfffd, 0xfffd, + /* 0x23 */ + 0xff01, 0xff02, 0xff03, 0xffe5, 0xff05, 0xff06, 0xff07, 0xff08, + 0xff09, 0xff0a, 0xff0b, 0xff0c, 0xff0d, 0xff0e, 0xff0f, 0xff10, + 0xff11, 0xff12, 0xff13, 0xff14, 0xff15, 0xff16, 0xff17, 0xff18, + 0xff19, 0xff1a, 0xff1b, 0xff1c, 0xff1d, 0xff1e, 0xff1f, 0xff20, + 0xff21, 0xff22, 0xff23, 0xff24, 0xff25, 0xff26, 0xff27, 0xff28, + 0xff29, 0xff2a, 0xff2b, 0xff2c, 0xff2d, 0xff2e, 0xff2f, 0xff30, + 0xff31, 0xff32, 0xff33, 0xff34, 0xff35, 0xff36, 0xff37, 0xff38, + 0xff39, 0xff3a, 0xff3b, 0xff3c, 0xff3d, 0xff3e, 0xff3f, 0xff40, + 0xff41, 0xff42, 0xff43, 0xff44, 0xff45, 0xff46, 0xff47, 0xff48, + 0xff49, 0xff4a, 0xff4b, 0xff4c, 0xff4d, 0xff4e, 0xff4f, 0xff50, + 0xff51, 0xff52, 0xff53, 0xff54, 0xff55, 0xff56, 0xff57, 0xff58, + 0xff59, 0xff5a, 0xff5b, 0xff5c, 0xff5d, 0xffe3, + /* 0x24 */ + 0x3041, 0x3042, 0x3043, 0x3044, 0x3045, 0x3046, 0x3047, 0x3048, + 0x3049, 0x304a, 0x304b, 0x304c, 0x304d, 0x304e, 0x304f, 0x3050, + 0x3051, 0x3052, 0x3053, 0x3054, 0x3055, 0x3056, 0x3057, 0x3058, + 0x3059, 0x305a, 0x305b, 0x305c, 0x305d, 0x305e, 0x305f, 0x3060, + 0x3061, 0x3062, 0x3063, 0x3064, 0x3065, 0x3066, 0x3067, 0x3068, + 0x3069, 0x306a, 0x306b, 0x306c, 0x306d, 0x306e, 0x306f, 0x3070, + 0x3071, 0x3072, 0x3073, 0x3074, 0x3075, 0x3076, 0x3077, 0x3078, + 0x3079, 0x307a, 0x307b, 0x307c, 0x307d, 0x307e, 0x307f, 0x3080, + 0x3081, 0x3082, 0x3083, 0x3084, 0x3085, 0x3086, 0x3087, 0x3088, + 0x3089, 0x308a, 0x308b, 0x308c, 0x308d, 0x308e, 0x308f, 0x3090, + 0x3091, 0x3092, 0x3093, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x25 */ + 0x30a1, 0x30a2, 0x30a3, 0x30a4, 0x30a5, 0x30a6, 0x30a7, 0x30a8, + 0x30a9, 0x30aa, 0x30ab, 0x30ac, 0x30ad, 0x30ae, 0x30af, 0x30b0, + 0x30b1, 0x30b2, 0x30b3, 0x30b4, 0x30b5, 0x30b6, 0x30b7, 0x30b8, + 0x30b9, 0x30ba, 0x30bb, 0x30bc, 0x30bd, 0x30be, 0x30bf, 0x30c0, + 0x30c1, 0x30c2, 0x30c3, 0x30c4, 0x30c5, 0x30c6, 0x30c7, 0x30c8, + 0x30c9, 0x30ca, 0x30cb, 0x30cc, 0x30cd, 0x30ce, 0x30cf, 0x30d0, + 0x30d1, 0x30d2, 0x30d3, 0x30d4, 0x30d5, 0x30d6, 0x30d7, 0x30d8, + 0x30d9, 0x30da, 0x30db, 0x30dc, 0x30dd, 0x30de, 0x30df, 0x30e0, + 0x30e1, 0x30e2, 0x30e3, 0x30e4, 0x30e5, 0x30e6, 0x30e7, 0x30e8, + 0x30e9, 0x30ea, 0x30eb, 0x30ec, 0x30ed, 0x30ee, 0x30ef, 0x30f0, + 0x30f1, 0x30f2, 0x30f3, 0x30f4, 0x30f5, 0x30f6, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x26 */ + 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, + 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, 0x03a0, + 0x03a1, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7, 0x03a8, 0x03a9, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, 0x03b8, + 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, 0x03c0, + 0x03c1, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, 0x03c8, 0x03c9, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x27 */ + 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0401, 0x0416, + 0x0417, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, + 0x041f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, + 0x0427, 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, + 0x042f, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0451, 0x0436, + 0x0437, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, + 0x043f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, + 0x0447, 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, + 0x044f, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x28 */ + 0x0101, 0x00e1, 0x01ce, 0x00e0, 0x0113, 0x00e9, 0x011b, 0x00e8, + 0x012b, 0x00ed, 0x01d0, 0x00ec, 0x014d, 0x00f3, 0x01d2, 0x00f2, + 0x016b, 0x00fa, 0x01d4, 0x00f9, 0x01d6, 0x01d8, 0x01da, 0x01dc, + 0x00fc, 0x00ea, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x3105, 0x3106, 0x3107, 0x3108, + 0x3109, 0x310a, 0x310b, 0x310c, 0x310d, 0x310e, 0x310f, 0x3110, + 0x3111, 0x3112, 0x3113, 0x3114, 0x3115, 0x3116, 0x3117, 0x3118, + 0x3119, 0x311a, 0x311b, 0x311c, 0x311d, 0x311e, 0x311f, 0x3120, + 0x3121, 0x3122, 0x3123, 0x3124, 0x3125, 0x3126, 0x3127, 0x3128, + 0x3129, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x29 */ + 0xfffd, 0xfffd, 0xfffd, 0x2500, 0x2501, 0x2502, 0x2503, 0x2504, + 0x2505, 0x2506, 0x2507, 0x2508, 0x2509, 0x250a, 0x250b, 0x250c, + 0x250d, 0x250e, 0x250f, 0x2510, 0x2511, 0x2512, 0x2513, 0x2514, + 0x2515, 0x2516, 0x2517, 0x2518, 0x2519, 0x251a, 0x251b, 0x251c, + 0x251d, 0x251e, 0x251f, 0x2520, 0x2521, 0x2522, 0x2523, 0x2524, + 0x2525, 0x2526, 0x2527, 0x2528, 0x2529, 0x252a, 0x252b, 0x252c, + 0x252d, 0x252e, 0x252f, 0x2530, 0x2531, 0x2532, 0x2533, 0x2534, + 0x2535, 0x2536, 0x2537, 0x2538, 0x2539, 0x253a, 0x253b, 0x253c, + 0x253d, 0x253e, 0x253f, 0x2540, 0x2541, 0x2542, 0x2543, 0x2544, + 0x2545, 0x2546, 0x2547, 0x2548, 0x2549, 0x254a, 0x254b, +}; +static const unsigned short gb2312_2uni_page30[6768] = { + /* 0x30 */ + 0x554a, 0x963f, 0x57c3, 0x6328, 0x54ce, 0x5509, 0x54c0, 0x7691, + 0x764c, 0x853c, 0x77ee, 0x827e, 0x788d, 0x7231, 0x9698, 0x978d, + 0x6c28, 0x5b89, 0x4ffa, 0x6309, 0x6697, 0x5cb8, 0x80fa, 0x6848, + 0x80ae, 0x6602, 0x76ce, 0x51f9, 0x6556, 0x71ac, 0x7ff1, 0x8884, + 0x50b2, 0x5965, 0x61ca, 0x6fb3, 0x82ad, 0x634c, 0x6252, 0x53ed, + 0x5427, 0x7b06, 0x516b, 0x75a4, 0x5df4, 0x62d4, 0x8dcb, 0x9776, + 0x628a, 0x8019, 0x575d, 0x9738, 0x7f62, 0x7238, 0x767d, 0x67cf, + 0x767e, 0x6446, 0x4f70, 0x8d25, 0x62dc, 0x7a17, 0x6591, 0x73ed, + 0x642c, 0x6273, 0x822c, 0x9881, 0x677f, 0x7248, 0x626e, 0x62cc, + 0x4f34, 0x74e3, 0x534a, 0x529e, 0x7eca, 0x90a6, 0x5e2e, 0x6886, + 0x699c, 0x8180, 0x7ed1, 0x68d2, 0x78c5, 0x868c, 0x9551, 0x508d, + 0x8c24, 0x82de, 0x80de, 0x5305, 0x8912, 0x5265, + /* 0x31 */ + 0x8584, 0x96f9, 0x4fdd, 0x5821, 0x9971, 0x5b9d, 0x62b1, 0x62a5, + 0x66b4, 0x8c79, 0x9c8d, 0x7206, 0x676f, 0x7891, 0x60b2, 0x5351, + 0x5317, 0x8f88, 0x80cc, 0x8d1d, 0x94a1, 0x500d, 0x72c8, 0x5907, + 0x60eb, 0x7119, 0x88ab, 0x5954, 0x82ef, 0x672c, 0x7b28, 0x5d29, + 0x7ef7, 0x752d, 0x6cf5, 0x8e66, 0x8ff8, 0x903c, 0x9f3b, 0x6bd4, + 0x9119, 0x7b14, 0x5f7c, 0x78a7, 0x84d6, 0x853d, 0x6bd5, 0x6bd9, + 0x6bd6, 0x5e01, 0x5e87, 0x75f9, 0x95ed, 0x655d, 0x5f0a, 0x5fc5, + 0x8f9f, 0x58c1, 0x81c2, 0x907f, 0x965b, 0x97ad, 0x8fb9, 0x7f16, + 0x8d2c, 0x6241, 0x4fbf, 0x53d8, 0x535e, 0x8fa8, 0x8fa9, 0x8fab, + 0x904d, 0x6807, 0x5f6a, 0x8198, 0x8868, 0x9cd6, 0x618b, 0x522b, + 0x762a, 0x5f6c, 0x658c, 0x6fd2, 0x6ee8, 0x5bbe, 0x6448, 0x5175, + 0x51b0, 0x67c4, 0x4e19, 0x79c9, 0x997c, 0x70b3, + /* 0x32 */ + 0x75c5, 0x5e76, 0x73bb, 0x83e0, 0x64ad, 0x62e8, 0x94b5, 0x6ce2, + 0x535a, 0x52c3, 0x640f, 0x94c2, 0x7b94, 0x4f2f, 0x5e1b, 0x8236, + 0x8116, 0x818a, 0x6e24, 0x6cca, 0x9a73, 0x6355, 0x535c, 0x54fa, + 0x8865, 0x57e0, 0x4e0d, 0x5e03, 0x6b65, 0x7c3f, 0x90e8, 0x6016, + 0x64e6, 0x731c, 0x88c1, 0x6750, 0x624d, 0x8d22, 0x776c, 0x8e29, + 0x91c7, 0x5f69, 0x83dc, 0x8521, 0x9910, 0x53c2, 0x8695, 0x6b8b, + 0x60ed, 0x60e8, 0x707f, 0x82cd, 0x8231, 0x4ed3, 0x6ca7, 0x85cf, + 0x64cd, 0x7cd9, 0x69fd, 0x66f9, 0x8349, 0x5395, 0x7b56, 0x4fa7, + 0x518c, 0x6d4b, 0x5c42, 0x8e6d, 0x63d2, 0x53c9, 0x832c, 0x8336, + 0x67e5, 0x78b4, 0x643d, 0x5bdf, 0x5c94, 0x5dee, 0x8be7, 0x62c6, + 0x67f4, 0x8c7a, 0x6400, 0x63ba, 0x8749, 0x998b, 0x8c17, 0x7f20, + 0x94f2, 0x4ea7, 0x9610, 0x98a4, 0x660c, 0x7316, + /* 0x33 */ + 0x573a, 0x5c1d, 0x5e38, 0x957f, 0x507f, 0x80a0, 0x5382, 0x655e, + 0x7545, 0x5531, 0x5021, 0x8d85, 0x6284, 0x949e, 0x671d, 0x5632, + 0x6f6e, 0x5de2, 0x5435, 0x7092, 0x8f66, 0x626f, 0x64a4, 0x63a3, + 0x5f7b, 0x6f88, 0x90f4, 0x81e3, 0x8fb0, 0x5c18, 0x6668, 0x5ff1, + 0x6c89, 0x9648, 0x8d81, 0x886c, 0x6491, 0x79f0, 0x57ce, 0x6a59, + 0x6210, 0x5448, 0x4e58, 0x7a0b, 0x60e9, 0x6f84, 0x8bda, 0x627f, + 0x901e, 0x9a8b, 0x79e4, 0x5403, 0x75f4, 0x6301, 0x5319, 0x6c60, + 0x8fdf, 0x5f1b, 0x9a70, 0x803b, 0x9f7f, 0x4f88, 0x5c3a, 0x8d64, + 0x7fc5, 0x65a5, 0x70bd, 0x5145, 0x51b2, 0x866b, 0x5d07, 0x5ba0, + 0x62bd, 0x916c, 0x7574, 0x8e0c, 0x7a20, 0x6101, 0x7b79, 0x4ec7, + 0x7ef8, 0x7785, 0x4e11, 0x81ed, 0x521d, 0x51fa, 0x6a71, 0x53a8, + 0x8e87, 0x9504, 0x96cf, 0x6ec1, 0x9664, 0x695a, + /* 0x34 */ + 0x7840, 0x50a8, 0x77d7, 0x6410, 0x89e6, 0x5904, 0x63e3, 0x5ddd, + 0x7a7f, 0x693d, 0x4f20, 0x8239, 0x5598, 0x4e32, 0x75ae, 0x7a97, + 0x5e62, 0x5e8a, 0x95ef, 0x521b, 0x5439, 0x708a, 0x6376, 0x9524, + 0x5782, 0x6625, 0x693f, 0x9187, 0x5507, 0x6df3, 0x7eaf, 0x8822, + 0x6233, 0x7ef0, 0x75b5, 0x8328, 0x78c1, 0x96cc, 0x8f9e, 0x6148, + 0x74f7, 0x8bcd, 0x6b64, 0x523a, 0x8d50, 0x6b21, 0x806a, 0x8471, + 0x56f1, 0x5306, 0x4ece, 0x4e1b, 0x51d1, 0x7c97, 0x918b, 0x7c07, + 0x4fc3, 0x8e7f, 0x7be1, 0x7a9c, 0x6467, 0x5d14, 0x50ac, 0x8106, + 0x7601, 0x7cb9, 0x6dec, 0x7fe0, 0x6751, 0x5b58, 0x5bf8, 0x78cb, + 0x64ae, 0x6413, 0x63aa, 0x632b, 0x9519, 0x642d, 0x8fbe, 0x7b54, + 0x7629, 0x6253, 0x5927, 0x5446, 0x6b79, 0x50a3, 0x6234, 0x5e26, + 0x6b86, 0x4ee3, 0x8d37, 0x888b, 0x5f85, 0x902e, + /* 0x35 */ + 0x6020, 0x803d, 0x62c5, 0x4e39, 0x5355, 0x90f8, 0x63b8, 0x80c6, + 0x65e6, 0x6c2e, 0x4f46, 0x60ee, 0x6de1, 0x8bde, 0x5f39, 0x86cb, + 0x5f53, 0x6321, 0x515a, 0x8361, 0x6863, 0x5200, 0x6363, 0x8e48, + 0x5012, 0x5c9b, 0x7977, 0x5bfc, 0x5230, 0x7a3b, 0x60bc, 0x9053, + 0x76d7, 0x5fb7, 0x5f97, 0x7684, 0x8e6c, 0x706f, 0x767b, 0x7b49, + 0x77aa, 0x51f3, 0x9093, 0x5824, 0x4f4e, 0x6ef4, 0x8fea, 0x654c, + 0x7b1b, 0x72c4, 0x6da4, 0x7fdf, 0x5ae1, 0x62b5, 0x5e95, 0x5730, + 0x8482, 0x7b2c, 0x5e1d, 0x5f1f, 0x9012, 0x7f14, 0x98a0, 0x6382, + 0x6ec7, 0x7898, 0x70b9, 0x5178, 0x975b, 0x57ab, 0x7535, 0x4f43, + 0x7538, 0x5e97, 0x60e6, 0x5960, 0x6dc0, 0x6bbf, 0x7889, 0x53fc, + 0x96d5, 0x51cb, 0x5201, 0x6389, 0x540a, 0x9493, 0x8c03, 0x8dcc, + 0x7239, 0x789f, 0x8776, 0x8fed, 0x8c0d, 0x53e0, + /* 0x36 */ + 0x4e01, 0x76ef, 0x53ee, 0x9489, 0x9876, 0x9f0e, 0x952d, 0x5b9a, + 0x8ba2, 0x4e22, 0x4e1c, 0x51ac, 0x8463, 0x61c2, 0x52a8, 0x680b, + 0x4f97, 0x606b, 0x51bb, 0x6d1e, 0x515c, 0x6296, 0x6597, 0x9661, + 0x8c46, 0x9017, 0x75d8, 0x90fd, 0x7763, 0x6bd2, 0x728a, 0x72ec, + 0x8bfb, 0x5835, 0x7779, 0x8d4c, 0x675c, 0x9540, 0x809a, 0x5ea6, + 0x6e21, 0x5992, 0x7aef, 0x77ed, 0x953b, 0x6bb5, 0x65ad, 0x7f0e, + 0x5806, 0x5151, 0x961f, 0x5bf9, 0x58a9, 0x5428, 0x8e72, 0x6566, + 0x987f, 0x56e4, 0x949d, 0x76fe, 0x9041, 0x6387, 0x54c6, 0x591a, + 0x593a, 0x579b, 0x8eb2, 0x6735, 0x8dfa, 0x8235, 0x5241, 0x60f0, + 0x5815, 0x86fe, 0x5ce8, 0x9e45, 0x4fc4, 0x989d, 0x8bb9, 0x5a25, + 0x6076, 0x5384, 0x627c, 0x904f, 0x9102, 0x997f, 0x6069, 0x800c, + 0x513f, 0x8033, 0x5c14, 0x9975, 0x6d31, 0x4e8c, + /* 0x37 */ + 0x8d30, 0x53d1, 0x7f5a, 0x7b4f, 0x4f10, 0x4e4f, 0x9600, 0x6cd5, + 0x73d0, 0x85e9, 0x5e06, 0x756a, 0x7ffb, 0x6a0a, 0x77fe, 0x9492, + 0x7e41, 0x51e1, 0x70e6, 0x53cd, 0x8fd4, 0x8303, 0x8d29, 0x72af, + 0x996d, 0x6cdb, 0x574a, 0x82b3, 0x65b9, 0x80aa, 0x623f, 0x9632, + 0x59a8, 0x4eff, 0x8bbf, 0x7eba, 0x653e, 0x83f2, 0x975e, 0x5561, + 0x98de, 0x80a5, 0x532a, 0x8bfd, 0x5420, 0x80ba, 0x5e9f, 0x6cb8, + 0x8d39, 0x82ac, 0x915a, 0x5429, 0x6c1b, 0x5206, 0x7eb7, 0x575f, + 0x711a, 0x6c7e, 0x7c89, 0x594b, 0x4efd, 0x5fff, 0x6124, 0x7caa, + 0x4e30, 0x5c01, 0x67ab, 0x8702, 0x5cf0, 0x950b, 0x98ce, 0x75af, + 0x70fd, 0x9022, 0x51af, 0x7f1d, 0x8bbd, 0x5949, 0x51e4, 0x4f5b, + 0x5426, 0x592b, 0x6577, 0x80a4, 0x5b75, 0x6276, 0x62c2, 0x8f90, + 0x5e45, 0x6c1f, 0x7b26, 0x4f0f, 0x4fd8, 0x670d, + /* 0x38 */ + 0x6d6e, 0x6daa, 0x798f, 0x88b1, 0x5f17, 0x752b, 0x629a, 0x8f85, + 0x4fef, 0x91dc, 0x65a7, 0x812f, 0x8151, 0x5e9c, 0x8150, 0x8d74, + 0x526f, 0x8986, 0x8d4b, 0x590d, 0x5085, 0x4ed8, 0x961c, 0x7236, + 0x8179, 0x8d1f, 0x5bcc, 0x8ba3, 0x9644, 0x5987, 0x7f1a, 0x5490, + 0x5676, 0x560e, 0x8be5, 0x6539, 0x6982, 0x9499, 0x76d6, 0x6e89, + 0x5e72, 0x7518, 0x6746, 0x67d1, 0x7aff, 0x809d, 0x8d76, 0x611f, + 0x79c6, 0x6562, 0x8d63, 0x5188, 0x521a, 0x94a2, 0x7f38, 0x809b, + 0x7eb2, 0x5c97, 0x6e2f, 0x6760, 0x7bd9, 0x768b, 0x9ad8, 0x818f, + 0x7f94, 0x7cd5, 0x641e, 0x9550, 0x7a3f, 0x544a, 0x54e5, 0x6b4c, + 0x6401, 0x6208, 0x9e3d, 0x80f3, 0x7599, 0x5272, 0x9769, 0x845b, + 0x683c, 0x86e4, 0x9601, 0x9694, 0x94ec, 0x4e2a, 0x5404, 0x7ed9, + 0x6839, 0x8ddf, 0x8015, 0x66f4, 0x5e9a, 0x7fb9, + /* 0x39 */ + 0x57c2, 0x803f, 0x6897, 0x5de5, 0x653b, 0x529f, 0x606d, 0x9f9a, + 0x4f9b, 0x8eac, 0x516c, 0x5bab, 0x5f13, 0x5de9, 0x6c5e, 0x62f1, + 0x8d21, 0x5171, 0x94a9, 0x52fe, 0x6c9f, 0x82df, 0x72d7, 0x57a2, + 0x6784, 0x8d2d, 0x591f, 0x8f9c, 0x83c7, 0x5495, 0x7b8d, 0x4f30, + 0x6cbd, 0x5b64, 0x59d1, 0x9f13, 0x53e4, 0x86ca, 0x9aa8, 0x8c37, + 0x80a1, 0x6545, 0x987e, 0x56fa, 0x96c7, 0x522e, 0x74dc, 0x5250, + 0x5be1, 0x6302, 0x8902, 0x4e56, 0x62d0, 0x602a, 0x68fa, 0x5173, + 0x5b98, 0x51a0, 0x89c2, 0x7ba1, 0x9986, 0x7f50, 0x60ef, 0x704c, + 0x8d2f, 0x5149, 0x5e7f, 0x901b, 0x7470, 0x89c4, 0x572d, 0x7845, + 0x5f52, 0x9f9f, 0x95fa, 0x8f68, 0x9b3c, 0x8be1, 0x7678, 0x6842, + 0x67dc, 0x8dea, 0x8d35, 0x523d, 0x8f8a, 0x6eda, 0x68cd, 0x9505, + 0x90ed, 0x56fd, 0x679c, 0x88f9, 0x8fc7, 0x54c8, + /* 0x3a */ + 0x9ab8, 0x5b69, 0x6d77, 0x6c26, 0x4ea5, 0x5bb3, 0x9a87, 0x9163, + 0x61a8, 0x90af, 0x97e9, 0x542b, 0x6db5, 0x5bd2, 0x51fd, 0x558a, + 0x7f55, 0x7ff0, 0x64bc, 0x634d, 0x65f1, 0x61be, 0x608d, 0x710a, + 0x6c57, 0x6c49, 0x592f, 0x676d, 0x822a, 0x58d5, 0x568e, 0x8c6a, + 0x6beb, 0x90dd, 0x597d, 0x8017, 0x53f7, 0x6d69, 0x5475, 0x559d, + 0x8377, 0x83cf, 0x6838, 0x79be, 0x548c, 0x4f55, 0x5408, 0x76d2, + 0x8c89, 0x9602, 0x6cb3, 0x6db8, 0x8d6b, 0x8910, 0x9e64, 0x8d3a, + 0x563f, 0x9ed1, 0x75d5, 0x5f88, 0x72e0, 0x6068, 0x54fc, 0x4ea8, + 0x6a2a, 0x8861, 0x6052, 0x8f70, 0x54c4, 0x70d8, 0x8679, 0x9e3f, + 0x6d2a, 0x5b8f, 0x5f18, 0x7ea2, 0x5589, 0x4faf, 0x7334, 0x543c, + 0x539a, 0x5019, 0x540e, 0x547c, 0x4e4e, 0x5ffd, 0x745a, 0x58f6, + 0x846b, 0x80e1, 0x8774, 0x72d0, 0x7cca, 0x6e56, + /* 0x3b */ + 0x5f27, 0x864e, 0x552c, 0x62a4, 0x4e92, 0x6caa, 0x6237, 0x82b1, + 0x54d7, 0x534e, 0x733e, 0x6ed1, 0x753b, 0x5212, 0x5316, 0x8bdd, + 0x69d0, 0x5f8a, 0x6000, 0x6dee, 0x574f, 0x6b22, 0x73af, 0x6853, + 0x8fd8, 0x7f13, 0x6362, 0x60a3, 0x5524, 0x75ea, 0x8c62, 0x7115, + 0x6da3, 0x5ba6, 0x5e7b, 0x8352, 0x614c, 0x9ec4, 0x78fa, 0x8757, + 0x7c27, 0x7687, 0x51f0, 0x60f6, 0x714c, 0x6643, 0x5e4c, 0x604d, + 0x8c0e, 0x7070, 0x6325, 0x8f89, 0x5fbd, 0x6062, 0x86d4, 0x56de, + 0x6bc1, 0x6094, 0x6167, 0x5349, 0x60e0, 0x6666, 0x8d3f, 0x79fd, + 0x4f1a, 0x70e9, 0x6c47, 0x8bb3, 0x8bf2, 0x7ed8, 0x8364, 0x660f, + 0x5a5a, 0x9b42, 0x6d51, 0x6df7, 0x8c41, 0x6d3b, 0x4f19, 0x706b, + 0x83b7, 0x6216, 0x60d1, 0x970d, 0x8d27, 0x7978, 0x51fb, 0x573e, + 0x57fa, 0x673a, 0x7578, 0x7a3d, 0x79ef, 0x7b95, + /* 0x3c */ + 0x808c, 0x9965, 0x8ff9, 0x6fc0, 0x8ba5, 0x9e21, 0x59ec, 0x7ee9, + 0x7f09, 0x5409, 0x6781, 0x68d8, 0x8f91, 0x7c4d, 0x96c6, 0x53ca, + 0x6025, 0x75be, 0x6c72, 0x5373, 0x5ac9, 0x7ea7, 0x6324, 0x51e0, + 0x810a, 0x5df1, 0x84df, 0x6280, 0x5180, 0x5b63, 0x4f0e, 0x796d, + 0x5242, 0x60b8, 0x6d4e, 0x5bc4, 0x5bc2, 0x8ba1, 0x8bb0, 0x65e2, + 0x5fcc, 0x9645, 0x5993, 0x7ee7, 0x7eaa, 0x5609, 0x67b7, 0x5939, + 0x4f73, 0x5bb6, 0x52a0, 0x835a, 0x988a, 0x8d3e, 0x7532, 0x94be, + 0x5047, 0x7a3c, 0x4ef7, 0x67b6, 0x9a7e, 0x5ac1, 0x6b7c, 0x76d1, + 0x575a, 0x5c16, 0x7b3a, 0x95f4, 0x714e, 0x517c, 0x80a9, 0x8270, + 0x5978, 0x7f04, 0x8327, 0x68c0, 0x67ec, 0x78b1, 0x7877, 0x62e3, + 0x6361, 0x7b80, 0x4fed, 0x526a, 0x51cf, 0x8350, 0x69db, 0x9274, + 0x8df5, 0x8d31, 0x89c1, 0x952e, 0x7bad, 0x4ef6, + /* 0x3d */ + 0x5065, 0x8230, 0x5251, 0x996f, 0x6e10, 0x6e85, 0x6da7, 0x5efa, + 0x50f5, 0x59dc, 0x5c06, 0x6d46, 0x6c5f, 0x7586, 0x848b, 0x6868, + 0x5956, 0x8bb2, 0x5320, 0x9171, 0x964d, 0x8549, 0x6912, 0x7901, + 0x7126, 0x80f6, 0x4ea4, 0x90ca, 0x6d47, 0x9a84, 0x5a07, 0x56bc, + 0x6405, 0x94f0, 0x77eb, 0x4fa5, 0x811a, 0x72e1, 0x89d2, 0x997a, + 0x7f34, 0x7ede, 0x527f, 0x6559, 0x9175, 0x8f7f, 0x8f83, 0x53eb, + 0x7a96, 0x63ed, 0x63a5, 0x7686, 0x79f8, 0x8857, 0x9636, 0x622a, + 0x52ab, 0x8282, 0x6854, 0x6770, 0x6377, 0x776b, 0x7aed, 0x6d01, + 0x7ed3, 0x89e3, 0x59d0, 0x6212, 0x85c9, 0x82a5, 0x754c, 0x501f, + 0x4ecb, 0x75a5, 0x8beb, 0x5c4a, 0x5dfe, 0x7b4b, 0x65a4, 0x91d1, + 0x4eca, 0x6d25, 0x895f, 0x7d27, 0x9526, 0x4ec5, 0x8c28, 0x8fdb, + 0x9773, 0x664b, 0x7981, 0x8fd1, 0x70ec, 0x6d78, + /* 0x3e */ + 0x5c3d, 0x52b2, 0x8346, 0x5162, 0x830e, 0x775b, 0x6676, 0x9cb8, + 0x4eac, 0x60ca, 0x7cbe, 0x7cb3, 0x7ecf, 0x4e95, 0x8b66, 0x666f, + 0x9888, 0x9759, 0x5883, 0x656c, 0x955c, 0x5f84, 0x75c9, 0x9756, + 0x7adf, 0x7ade, 0x51c0, 0x70af, 0x7a98, 0x63ea, 0x7a76, 0x7ea0, + 0x7396, 0x97ed, 0x4e45, 0x7078, 0x4e5d, 0x9152, 0x53a9, 0x6551, + 0x65e7, 0x81fc, 0x8205, 0x548e, 0x5c31, 0x759a, 0x97a0, 0x62d8, + 0x72d9, 0x75bd, 0x5c45, 0x9a79, 0x83ca, 0x5c40, 0x5480, 0x77e9, + 0x4e3e, 0x6cae, 0x805a, 0x62d2, 0x636e, 0x5de8, 0x5177, 0x8ddd, + 0x8e1e, 0x952f, 0x4ff1, 0x53e5, 0x60e7, 0x70ac, 0x5267, 0x6350, + 0x9e43, 0x5a1f, 0x5026, 0x7737, 0x5377, 0x7ee2, 0x6485, 0x652b, + 0x6289, 0x6398, 0x5014, 0x7235, 0x89c9, 0x51b3, 0x8bc0, 0x7edd, + 0x5747, 0x83cc, 0x94a7, 0x519b, 0x541b, 0x5cfb, + /* 0x3f */ + 0x4fca, 0x7ae3, 0x6d5a, 0x90e1, 0x9a8f, 0x5580, 0x5496, 0x5361, + 0x54af, 0x5f00, 0x63e9, 0x6977, 0x51ef, 0x6168, 0x520a, 0x582a, + 0x52d8, 0x574e, 0x780d, 0x770b, 0x5eb7, 0x6177, 0x7ce0, 0x625b, + 0x6297, 0x4ea2, 0x7095, 0x8003, 0x62f7, 0x70e4, 0x9760, 0x5777, + 0x82db, 0x67ef, 0x68f5, 0x78d5, 0x9897, 0x79d1, 0x58f3, 0x54b3, + 0x53ef, 0x6e34, 0x514b, 0x523b, 0x5ba2, 0x8bfe, 0x80af, 0x5543, + 0x57a6, 0x6073, 0x5751, 0x542d, 0x7a7a, 0x6050, 0x5b54, 0x63a7, + 0x62a0, 0x53e3, 0x6263, 0x5bc7, 0x67af, 0x54ed, 0x7a9f, 0x82e6, + 0x9177, 0x5e93, 0x88e4, 0x5938, 0x57ae, 0x630e, 0x8de8, 0x80ef, + 0x5757, 0x7b77, 0x4fa9, 0x5feb, 0x5bbd, 0x6b3e, 0x5321, 0x7b50, + 0x72c2, 0x6846, 0x77ff, 0x7736, 0x65f7, 0x51b5, 0x4e8f, 0x76d4, + 0x5cbf, 0x7aa5, 0x8475, 0x594e, 0x9b41, 0x5080, + /* 0x40 */ + 0x9988, 0x6127, 0x6e83, 0x5764, 0x6606, 0x6346, 0x56f0, 0x62ec, + 0x6269, 0x5ed3, 0x9614, 0x5783, 0x62c9, 0x5587, 0x8721, 0x814a, + 0x8fa3, 0x5566, 0x83b1, 0x6765, 0x8d56, 0x84dd, 0x5a6a, 0x680f, + 0x62e6, 0x7bee, 0x9611, 0x5170, 0x6f9c, 0x8c30, 0x63fd, 0x89c8, + 0x61d2, 0x7f06, 0x70c2, 0x6ee5, 0x7405, 0x6994, 0x72fc, 0x5eca, + 0x90ce, 0x6717, 0x6d6a, 0x635e, 0x52b3, 0x7262, 0x8001, 0x4f6c, + 0x59e5, 0x916a, 0x70d9, 0x6d9d, 0x52d2, 0x4e50, 0x96f7, 0x956d, + 0x857e, 0x78ca, 0x7d2f, 0x5121, 0x5792, 0x64c2, 0x808b, 0x7c7b, + 0x6cea, 0x68f1, 0x695e, 0x51b7, 0x5398, 0x68a8, 0x7281, 0x9ece, + 0x7bf1, 0x72f8, 0x79bb, 0x6f13, 0x7406, 0x674e, 0x91cc, 0x9ca4, + 0x793c, 0x8389, 0x8354, 0x540f, 0x6817, 0x4e3d, 0x5389, 0x52b1, + 0x783e, 0x5386, 0x5229, 0x5088, 0x4f8b, 0x4fd0, + /* 0x41 */ + 0x75e2, 0x7acb, 0x7c92, 0x6ca5, 0x96b6, 0x529b, 0x7483, 0x54e9, + 0x4fe9, 0x8054, 0x83b2, 0x8fde, 0x9570, 0x5ec9, 0x601c, 0x6d9f, + 0x5e18, 0x655b, 0x8138, 0x94fe, 0x604b, 0x70bc, 0x7ec3, 0x7cae, + 0x51c9, 0x6881, 0x7cb1, 0x826f, 0x4e24, 0x8f86, 0x91cf, 0x667e, + 0x4eae, 0x8c05, 0x64a9, 0x804a, 0x50da, 0x7597, 0x71ce, 0x5be5, + 0x8fbd, 0x6f66, 0x4e86, 0x6482, 0x9563, 0x5ed6, 0x6599, 0x5217, + 0x88c2, 0x70c8, 0x52a3, 0x730e, 0x7433, 0x6797, 0x78f7, 0x9716, + 0x4e34, 0x90bb, 0x9cde, 0x6dcb, 0x51db, 0x8d41, 0x541d, 0x62ce, + 0x73b2, 0x83f1, 0x96f6, 0x9f84, 0x94c3, 0x4f36, 0x7f9a, 0x51cc, + 0x7075, 0x9675, 0x5cad, 0x9886, 0x53e6, 0x4ee4, 0x6e9c, 0x7409, + 0x69b4, 0x786b, 0x998f, 0x7559, 0x5218, 0x7624, 0x6d41, 0x67f3, + 0x516d, 0x9f99, 0x804b, 0x5499, 0x7b3c, 0x7abf, + /* 0x42 */ + 0x9686, 0x5784, 0x62e2, 0x9647, 0x697c, 0x5a04, 0x6402, 0x7bd3, + 0x6f0f, 0x964b, 0x82a6, 0x5362, 0x9885, 0x5e90, 0x7089, 0x63b3, + 0x5364, 0x864f, 0x9c81, 0x9e93, 0x788c, 0x9732, 0x8def, 0x8d42, + 0x9e7f, 0x6f5e, 0x7984, 0x5f55, 0x9646, 0x622e, 0x9a74, 0x5415, + 0x94dd, 0x4fa3, 0x65c5, 0x5c65, 0x5c61, 0x7f15, 0x8651, 0x6c2f, + 0x5f8b, 0x7387, 0x6ee4, 0x7eff, 0x5ce6, 0x631b, 0x5b6a, 0x6ee6, + 0x5375, 0x4e71, 0x63a0, 0x7565, 0x62a1, 0x8f6e, 0x4f26, 0x4ed1, + 0x6ca6, 0x7eb6, 0x8bba, 0x841d, 0x87ba, 0x7f57, 0x903b, 0x9523, + 0x7ba9, 0x9aa1, 0x88f8, 0x843d, 0x6d1b, 0x9a86, 0x7edc, 0x5988, + 0x9ebb, 0x739b, 0x7801, 0x8682, 0x9a6c, 0x9a82, 0x561b, 0x5417, + 0x57cb, 0x4e70, 0x9ea6, 0x5356, 0x8fc8, 0x8109, 0x7792, 0x9992, + 0x86ee, 0x6ee1, 0x8513, 0x66fc, 0x6162, 0x6f2b, + /* 0x43 */ + 0x8c29, 0x8292, 0x832b, 0x76f2, 0x6c13, 0x5fd9, 0x83bd, 0x732b, + 0x8305, 0x951a, 0x6bdb, 0x77db, 0x94c6, 0x536f, 0x8302, 0x5192, + 0x5e3d, 0x8c8c, 0x8d38, 0x4e48, 0x73ab, 0x679a, 0x6885, 0x9176, + 0x9709, 0x7164, 0x6ca1, 0x7709, 0x5a92, 0x9541, 0x6bcf, 0x7f8e, + 0x6627, 0x5bd0, 0x59b9, 0x5a9a, 0x95e8, 0x95f7, 0x4eec, 0x840c, + 0x8499, 0x6aac, 0x76df, 0x9530, 0x731b, 0x68a6, 0x5b5f, 0x772f, + 0x919a, 0x9761, 0x7cdc, 0x8ff7, 0x8c1c, 0x5f25, 0x7c73, 0x79d8, + 0x89c5, 0x6ccc, 0x871c, 0x5bc6, 0x5e42, 0x68c9, 0x7720, 0x7ef5, + 0x5195, 0x514d, 0x52c9, 0x5a29, 0x7f05, 0x9762, 0x82d7, 0x63cf, + 0x7784, 0x85d0, 0x79d2, 0x6e3a, 0x5e99, 0x5999, 0x8511, 0x706d, + 0x6c11, 0x62bf, 0x76bf, 0x654f, 0x60af, 0x95fd, 0x660e, 0x879f, + 0x9e23, 0x94ed, 0x540d, 0x547d, 0x8c2c, 0x6478, + /* 0x44 */ + 0x6479, 0x8611, 0x6a21, 0x819c, 0x78e8, 0x6469, 0x9b54, 0x62b9, + 0x672b, 0x83ab, 0x58a8, 0x9ed8, 0x6cab, 0x6f20, 0x5bde, 0x964c, + 0x8c0b, 0x725f, 0x67d0, 0x62c7, 0x7261, 0x4ea9, 0x59c6, 0x6bcd, + 0x5893, 0x66ae, 0x5e55, 0x52df, 0x6155, 0x6728, 0x76ee, 0x7766, + 0x7267, 0x7a46, 0x62ff, 0x54ea, 0x5450, 0x94a0, 0x90a3, 0x5a1c, + 0x7eb3, 0x6c16, 0x4e43, 0x5976, 0x8010, 0x5948, 0x5357, 0x7537, + 0x96be, 0x56ca, 0x6320, 0x8111, 0x607c, 0x95f9, 0x6dd6, 0x5462, + 0x9981, 0x5185, 0x5ae9, 0x80fd, 0x59ae, 0x9713, 0x502a, 0x6ce5, + 0x5c3c, 0x62df, 0x4f60, 0x533f, 0x817b, 0x9006, 0x6eba, 0x852b, + 0x62c8, 0x5e74, 0x78be, 0x64b5, 0x637b, 0x5ff5, 0x5a18, 0x917f, + 0x9e1f, 0x5c3f, 0x634f, 0x8042, 0x5b7d, 0x556e, 0x954a, 0x954d, + 0x6d85, 0x60a8, 0x67e0, 0x72de, 0x51dd, 0x5b81, + /* 0x45 */ + 0x62e7, 0x6cde, 0x725b, 0x626d, 0x94ae, 0x7ebd, 0x8113, 0x6d53, + 0x519c, 0x5f04, 0x5974, 0x52aa, 0x6012, 0x5973, 0x6696, 0x8650, + 0x759f, 0x632a, 0x61e6, 0x7cef, 0x8bfa, 0x54e6, 0x6b27, 0x9e25, + 0x6bb4, 0x85d5, 0x5455, 0x5076, 0x6ca4, 0x556a, 0x8db4, 0x722c, + 0x5e15, 0x6015, 0x7436, 0x62cd, 0x6392, 0x724c, 0x5f98, 0x6e43, + 0x6d3e, 0x6500, 0x6f58, 0x76d8, 0x78d0, 0x76fc, 0x7554, 0x5224, + 0x53db, 0x4e53, 0x5e9e, 0x65c1, 0x802a, 0x80d6, 0x629b, 0x5486, + 0x5228, 0x70ae, 0x888d, 0x8dd1, 0x6ce1, 0x5478, 0x80da, 0x57f9, + 0x88f4, 0x8d54, 0x966a, 0x914d, 0x4f69, 0x6c9b, 0x55b7, 0x76c6, + 0x7830, 0x62a8, 0x70f9, 0x6f8e, 0x5f6d, 0x84ec, 0x68da, 0x787c, + 0x7bf7, 0x81a8, 0x670b, 0x9e4f, 0x6367, 0x78b0, 0x576f, 0x7812, + 0x9739, 0x6279, 0x62ab, 0x5288, 0x7435, 0x6bd7, + /* 0x46 */ + 0x5564, 0x813e, 0x75b2, 0x76ae, 0x5339, 0x75de, 0x50fb, 0x5c41, + 0x8b6c, 0x7bc7, 0x504f, 0x7247, 0x9a97, 0x98d8, 0x6f02, 0x74e2, + 0x7968, 0x6487, 0x77a5, 0x62fc, 0x9891, 0x8d2b, 0x54c1, 0x8058, + 0x4e52, 0x576a, 0x82f9, 0x840d, 0x5e73, 0x51ed, 0x74f6, 0x8bc4, + 0x5c4f, 0x5761, 0x6cfc, 0x9887, 0x5a46, 0x7834, 0x9b44, 0x8feb, + 0x7c95, 0x5256, 0x6251, 0x94fa, 0x4ec6, 0x8386, 0x8461, 0x83e9, + 0x84b2, 0x57d4, 0x6734, 0x5703, 0x666e, 0x6d66, 0x8c31, 0x66dd, + 0x7011, 0x671f, 0x6b3a, 0x6816, 0x621a, 0x59bb, 0x4e03, 0x51c4, + 0x6f06, 0x67d2, 0x6c8f, 0x5176, 0x68cb, 0x5947, 0x6b67, 0x7566, + 0x5d0e, 0x8110, 0x9f50, 0x65d7, 0x7948, 0x7941, 0x9a91, 0x8d77, + 0x5c82, 0x4e5e, 0x4f01, 0x542f, 0x5951, 0x780c, 0x5668, 0x6c14, + 0x8fc4, 0x5f03, 0x6c7d, 0x6ce3, 0x8bab, 0x6390, + /* 0x47 */ + 0x6070, 0x6d3d, 0x7275, 0x6266, 0x948e, 0x94c5, 0x5343, 0x8fc1, + 0x7b7e, 0x4edf, 0x8c26, 0x4e7e, 0x9ed4, 0x94b1, 0x94b3, 0x524d, + 0x6f5c, 0x9063, 0x6d45, 0x8c34, 0x5811, 0x5d4c, 0x6b20, 0x6b49, + 0x67aa, 0x545b, 0x8154, 0x7f8c, 0x5899, 0x8537, 0x5f3a, 0x62a2, + 0x6a47, 0x9539, 0x6572, 0x6084, 0x6865, 0x77a7, 0x4e54, 0x4fa8, + 0x5de7, 0x9798, 0x64ac, 0x7fd8, 0x5ced, 0x4fcf, 0x7a8d, 0x5207, + 0x8304, 0x4e14, 0x602f, 0x7a83, 0x94a6, 0x4fb5, 0x4eb2, 0x79e6, + 0x7434, 0x52e4, 0x82b9, 0x64d2, 0x79bd, 0x5bdd, 0x6c81, 0x9752, + 0x8f7b, 0x6c22, 0x503e, 0x537f, 0x6e05, 0x64ce, 0x6674, 0x6c30, + 0x60c5, 0x9877, 0x8bf7, 0x5e86, 0x743c, 0x7a77, 0x79cb, 0x4e18, + 0x90b1, 0x7403, 0x6c42, 0x56da, 0x914b, 0x6cc5, 0x8d8b, 0x533a, + 0x86c6, 0x66f2, 0x8eaf, 0x5c48, 0x9a71, 0x6e20, + /* 0x48 */ + 0x53d6, 0x5a36, 0x9f8b, 0x8da3, 0x53bb, 0x5708, 0x98a7, 0x6743, + 0x919b, 0x6cc9, 0x5168, 0x75ca, 0x62f3, 0x72ac, 0x5238, 0x529d, + 0x7f3a, 0x7094, 0x7638, 0x5374, 0x9e4a, 0x69b7, 0x786e, 0x96c0, + 0x88d9, 0x7fa4, 0x7136, 0x71c3, 0x5189, 0x67d3, 0x74e4, 0x58e4, + 0x6518, 0x56b7, 0x8ba9, 0x9976, 0x6270, 0x7ed5, 0x60f9, 0x70ed, + 0x58ec, 0x4ec1, 0x4eba, 0x5fcd, 0x97e7, 0x4efb, 0x8ba4, 0x5203, + 0x598a, 0x7eab, 0x6254, 0x4ecd, 0x65e5, 0x620e, 0x8338, 0x84c9, + 0x8363, 0x878d, 0x7194, 0x6eb6, 0x5bb9, 0x7ed2, 0x5197, 0x63c9, + 0x67d4, 0x8089, 0x8339, 0x8815, 0x5112, 0x5b7a, 0x5982, 0x8fb1, + 0x4e73, 0x6c5d, 0x5165, 0x8925, 0x8f6f, 0x962e, 0x854a, 0x745e, + 0x9510, 0x95f0, 0x6da6, 0x82e5, 0x5f31, 0x6492, 0x6d12, 0x8428, + 0x816e, 0x9cc3, 0x585e, 0x8d5b, 0x4e09, 0x53c1, + /* 0x49 */ + 0x4f1e, 0x6563, 0x6851, 0x55d3, 0x4e27, 0x6414, 0x9a9a, 0x626b, + 0x5ac2, 0x745f, 0x8272, 0x6da9, 0x68ee, 0x50e7, 0x838e, 0x7802, + 0x6740, 0x5239, 0x6c99, 0x7eb1, 0x50bb, 0x5565, 0x715e, 0x7b5b, + 0x6652, 0x73ca, 0x82eb, 0x6749, 0x5c71, 0x5220, 0x717d, 0x886b, + 0x95ea, 0x9655, 0x64c5, 0x8d61, 0x81b3, 0x5584, 0x6c55, 0x6247, + 0x7f2e, 0x5892, 0x4f24, 0x5546, 0x8d4f, 0x664c, 0x4e0a, 0x5c1a, + 0x88f3, 0x68a2, 0x634e, 0x7a0d, 0x70e7, 0x828d, 0x52fa, 0x97f6, + 0x5c11, 0x54e8, 0x90b5, 0x7ecd, 0x5962, 0x8d4a, 0x86c7, 0x820c, + 0x820d, 0x8d66, 0x6444, 0x5c04, 0x6151, 0x6d89, 0x793e, 0x8bbe, + 0x7837, 0x7533, 0x547b, 0x4f38, 0x8eab, 0x6df1, 0x5a20, 0x7ec5, + 0x795e, 0x6c88, 0x5ba1, 0x5a76, 0x751a, 0x80be, 0x614e, 0x6e17, + 0x58f0, 0x751f, 0x7525, 0x7272, 0x5347, 0x7ef3, + /* 0x4a */ + 0x7701, 0x76db, 0x5269, 0x80dc, 0x5723, 0x5e08, 0x5931, 0x72ee, + 0x65bd, 0x6e7f, 0x8bd7, 0x5c38, 0x8671, 0x5341, 0x77f3, 0x62fe, + 0x65f6, 0x4ec0, 0x98df, 0x8680, 0x5b9e, 0x8bc6, 0x53f2, 0x77e2, + 0x4f7f, 0x5c4e, 0x9a76, 0x59cb, 0x5f0f, 0x793a, 0x58eb, 0x4e16, + 0x67ff, 0x4e8b, 0x62ed, 0x8a93, 0x901d, 0x52bf, 0x662f, 0x55dc, + 0x566c, 0x9002, 0x4ed5, 0x4f8d, 0x91ca, 0x9970, 0x6c0f, 0x5e02, + 0x6043, 0x5ba4, 0x89c6, 0x8bd5, 0x6536, 0x624b, 0x9996, 0x5b88, + 0x5bff, 0x6388, 0x552e, 0x53d7, 0x7626, 0x517d, 0x852c, 0x67a2, + 0x68b3, 0x6b8a, 0x6292, 0x8f93, 0x53d4, 0x8212, 0x6dd1, 0x758f, + 0x4e66, 0x8d4e, 0x5b70, 0x719f, 0x85af, 0x6691, 0x66d9, 0x7f72, + 0x8700, 0x9ecd, 0x9f20, 0x5c5e, 0x672f, 0x8ff0, 0x6811, 0x675f, + 0x620d, 0x7ad6, 0x5885, 0x5eb6, 0x6570, 0x6f31, + /* 0x4b */ + 0x6055, 0x5237, 0x800d, 0x6454, 0x8870, 0x7529, 0x5e05, 0x6813, + 0x62f4, 0x971c, 0x53cc, 0x723d, 0x8c01, 0x6c34, 0x7761, 0x7a0e, + 0x542e, 0x77ac, 0x987a, 0x821c, 0x8bf4, 0x7855, 0x6714, 0x70c1, + 0x65af, 0x6495, 0x5636, 0x601d, 0x79c1, 0x53f8, 0x4e1d, 0x6b7b, + 0x8086, 0x5bfa, 0x55e3, 0x56db, 0x4f3a, 0x4f3c, 0x9972, 0x5df3, + 0x677e, 0x8038, 0x6002, 0x9882, 0x9001, 0x5b8b, 0x8bbc, 0x8bf5, + 0x641c, 0x8258, 0x64de, 0x55fd, 0x82cf, 0x9165, 0x4fd7, 0x7d20, + 0x901f, 0x7c9f, 0x50f3, 0x5851, 0x6eaf, 0x5bbf, 0x8bc9, 0x8083, + 0x9178, 0x849c, 0x7b97, 0x867d, 0x968b, 0x968f, 0x7ee5, 0x9ad3, + 0x788e, 0x5c81, 0x7a57, 0x9042, 0x96a7, 0x795f, 0x5b59, 0x635f, + 0x7b0b, 0x84d1, 0x68ad, 0x5506, 0x7f29, 0x7410, 0x7d22, 0x9501, + 0x6240, 0x584c, 0x4ed6, 0x5b83, 0x5979, 0x5854, + /* 0x4c */ + 0x736d, 0x631e, 0x8e4b, 0x8e0f, 0x80ce, 0x82d4, 0x62ac, 0x53f0, + 0x6cf0, 0x915e, 0x592a, 0x6001, 0x6c70, 0x574d, 0x644a, 0x8d2a, + 0x762b, 0x6ee9, 0x575b, 0x6a80, 0x75f0, 0x6f6d, 0x8c2d, 0x8c08, + 0x5766, 0x6bef, 0x8892, 0x78b3, 0x63a2, 0x53f9, 0x70ad, 0x6c64, + 0x5858, 0x642a, 0x5802, 0x68e0, 0x819b, 0x5510, 0x7cd6, 0x5018, + 0x8eba, 0x6dcc, 0x8d9f, 0x70eb, 0x638f, 0x6d9b, 0x6ed4, 0x7ee6, + 0x8404, 0x6843, 0x9003, 0x6dd8, 0x9676, 0x8ba8, 0x5957, 0x7279, + 0x85e4, 0x817e, 0x75bc, 0x8a8a, 0x68af, 0x5254, 0x8e22, 0x9511, + 0x63d0, 0x9898, 0x8e44, 0x557c, 0x4f53, 0x66ff, 0x568f, 0x60d5, + 0x6d95, 0x5243, 0x5c49, 0x5929, 0x6dfb, 0x586b, 0x7530, 0x751c, + 0x606c, 0x8214, 0x8146, 0x6311, 0x6761, 0x8fe2, 0x773a, 0x8df3, + 0x8d34, 0x94c1, 0x5e16, 0x5385, 0x542c, 0x70c3, + /* 0x4d */ + 0x6c40, 0x5ef7, 0x505c, 0x4ead, 0x5ead, 0x633a, 0x8247, 0x901a, + 0x6850, 0x916e, 0x77b3, 0x540c, 0x94dc, 0x5f64, 0x7ae5, 0x6876, + 0x6345, 0x7b52, 0x7edf, 0x75db, 0x5077, 0x6295, 0x5934, 0x900f, + 0x51f8, 0x79c3, 0x7a81, 0x56fe, 0x5f92, 0x9014, 0x6d82, 0x5c60, + 0x571f, 0x5410, 0x5154, 0x6e4d, 0x56e2, 0x63a8, 0x9893, 0x817f, + 0x8715, 0x892a, 0x9000, 0x541e, 0x5c6f, 0x81c0, 0x62d6, 0x6258, + 0x8131, 0x9e35, 0x9640, 0x9a6e, 0x9a7c, 0x692d, 0x59a5, 0x62d3, + 0x553e, 0x6316, 0x54c7, 0x86d9, 0x6d3c, 0x5a03, 0x74e6, 0x889c, + 0x6b6a, 0x5916, 0x8c4c, 0x5f2f, 0x6e7e, 0x73a9, 0x987d, 0x4e38, + 0x70f7, 0x5b8c, 0x7897, 0x633d, 0x665a, 0x7696, 0x60cb, 0x5b9b, + 0x5a49, 0x4e07, 0x8155, 0x6c6a, 0x738b, 0x4ea1, 0x6789, 0x7f51, + 0x5f80, 0x65fa, 0x671b, 0x5fd8, 0x5984, 0x5a01, + /* 0x4e */ + 0x5dcd, 0x5fae, 0x5371, 0x97e6, 0x8fdd, 0x6845, 0x56f4, 0x552f, + 0x60df, 0x4e3a, 0x6f4d, 0x7ef4, 0x82c7, 0x840e, 0x59d4, 0x4f1f, + 0x4f2a, 0x5c3e, 0x7eac, 0x672a, 0x851a, 0x5473, 0x754f, 0x80c3, + 0x5582, 0x9b4f, 0x4f4d, 0x6e2d, 0x8c13, 0x5c09, 0x6170, 0x536b, + 0x761f, 0x6e29, 0x868a, 0x6587, 0x95fb, 0x7eb9, 0x543b, 0x7a33, + 0x7d0a, 0x95ee, 0x55e1, 0x7fc1, 0x74ee, 0x631d, 0x8717, 0x6da1, + 0x7a9d, 0x6211, 0x65a1, 0x5367, 0x63e1, 0x6c83, 0x5deb, 0x545c, + 0x94a8, 0x4e4c, 0x6c61, 0x8bec, 0x5c4b, 0x65e0, 0x829c, 0x68a7, + 0x543e, 0x5434, 0x6bcb, 0x6b66, 0x4e94, 0x6342, 0x5348, 0x821e, + 0x4f0d, 0x4fae, 0x575e, 0x620a, 0x96fe, 0x6664, 0x7269, 0x52ff, + 0x52a1, 0x609f, 0x8bef, 0x6614, 0x7199, 0x6790, 0x897f, 0x7852, + 0x77fd, 0x6670, 0x563b, 0x5438, 0x9521, 0x727a, + /* 0x4f */ + 0x7a00, 0x606f, 0x5e0c, 0x6089, 0x819d, 0x5915, 0x60dc, 0x7184, + 0x70ef, 0x6eaa, 0x6c50, 0x7280, 0x6a84, 0x88ad, 0x5e2d, 0x4e60, + 0x5ab3, 0x559c, 0x94e3, 0x6d17, 0x7cfb, 0x9699, 0x620f, 0x7ec6, + 0x778e, 0x867e, 0x5323, 0x971e, 0x8f96, 0x6687, 0x5ce1, 0x4fa0, + 0x72ed, 0x4e0b, 0x53a6, 0x590f, 0x5413, 0x6380, 0x9528, 0x5148, + 0x4ed9, 0x9c9c, 0x7ea4, 0x54b8, 0x8d24, 0x8854, 0x8237, 0x95f2, + 0x6d8e, 0x5f26, 0x5acc, 0x663e, 0x9669, 0x73b0, 0x732e, 0x53bf, + 0x817a, 0x9985, 0x7fa1, 0x5baa, 0x9677, 0x9650, 0x7ebf, 0x76f8, + 0x53a2, 0x9576, 0x9999, 0x7bb1, 0x8944, 0x6e58, 0x4e61, 0x7fd4, + 0x7965, 0x8be6, 0x60f3, 0x54cd, 0x4eab, 0x9879, 0x5df7, 0x6a61, + 0x50cf, 0x5411, 0x8c61, 0x8427, 0x785d, 0x9704, 0x524a, 0x54ee, + 0x56a3, 0x9500, 0x6d88, 0x5bb5, 0x6dc6, 0x6653, + /* 0x50 */ + 0x5c0f, 0x5b5d, 0x6821, 0x8096, 0x5578, 0x7b11, 0x6548, 0x6954, + 0x4e9b, 0x6b47, 0x874e, 0x978b, 0x534f, 0x631f, 0x643a, 0x90aa, + 0x659c, 0x80c1, 0x8c10, 0x5199, 0x68b0, 0x5378, 0x87f9, 0x61c8, + 0x6cc4, 0x6cfb, 0x8c22, 0x5c51, 0x85aa, 0x82af, 0x950c, 0x6b23, + 0x8f9b, 0x65b0, 0x5ffb, 0x5fc3, 0x4fe1, 0x8845, 0x661f, 0x8165, + 0x7329, 0x60fa, 0x5174, 0x5211, 0x578b, 0x5f62, 0x90a2, 0x884c, + 0x9192, 0x5e78, 0x674f, 0x6027, 0x59d3, 0x5144, 0x51f6, 0x80f8, + 0x5308, 0x6c79, 0x96c4, 0x718a, 0x4f11, 0x4fee, 0x7f9e, 0x673d, + 0x55c5, 0x9508, 0x79c0, 0x8896, 0x7ee3, 0x589f, 0x620c, 0x9700, + 0x865a, 0x5618, 0x987b, 0x5f90, 0x8bb8, 0x84c4, 0x9157, 0x53d9, + 0x65ed, 0x5e8f, 0x755c, 0x6064, 0x7d6e, 0x5a7f, 0x7eea, 0x7eed, + 0x8f69, 0x55a7, 0x5ba3, 0x60ac, 0x65cb, 0x7384, + /* 0x51 */ + 0x9009, 0x7663, 0x7729, 0x7eda, 0x9774, 0x859b, 0x5b66, 0x7a74, + 0x96ea, 0x8840, 0x52cb, 0x718f, 0x5faa, 0x65ec, 0x8be2, 0x5bfb, + 0x9a6f, 0x5de1, 0x6b89, 0x6c5b, 0x8bad, 0x8baf, 0x900a, 0x8fc5, + 0x538b, 0x62bc, 0x9e26, 0x9e2d, 0x5440, 0x4e2b, 0x82bd, 0x7259, + 0x869c, 0x5d16, 0x8859, 0x6daf, 0x96c5, 0x54d1, 0x4e9a, 0x8bb6, + 0x7109, 0x54bd, 0x9609, 0x70df, 0x6df9, 0x76d0, 0x4e25, 0x7814, + 0x8712, 0x5ca9, 0x5ef6, 0x8a00, 0x989c, 0x960e, 0x708e, 0x6cbf, + 0x5944, 0x63a9, 0x773c, 0x884d, 0x6f14, 0x8273, 0x5830, 0x71d5, + 0x538c, 0x781a, 0x96c1, 0x5501, 0x5f66, 0x7130, 0x5bb4, 0x8c1a, + 0x9a8c, 0x6b83, 0x592e, 0x9e2f, 0x79e7, 0x6768, 0x626c, 0x4f6f, + 0x75a1, 0x7f8a, 0x6d0b, 0x9633, 0x6c27, 0x4ef0, 0x75d2, 0x517b, + 0x6837, 0x6f3e, 0x9080, 0x8170, 0x5996, 0x7476, + /* 0x52 */ + 0x6447, 0x5c27, 0x9065, 0x7a91, 0x8c23, 0x59da, 0x54ac, 0x8200, + 0x836f, 0x8981, 0x8000, 0x6930, 0x564e, 0x8036, 0x7237, 0x91ce, + 0x51b6, 0x4e5f, 0x9875, 0x6396, 0x4e1a, 0x53f6, 0x66f3, 0x814b, + 0x591c, 0x6db2, 0x4e00, 0x58f9, 0x533b, 0x63d6, 0x94f1, 0x4f9d, + 0x4f0a, 0x8863, 0x9890, 0x5937, 0x9057, 0x79fb, 0x4eea, 0x80f0, + 0x7591, 0x6c82, 0x5b9c, 0x59e8, 0x5f5d, 0x6905, 0x8681, 0x501a, + 0x5df2, 0x4e59, 0x77e3, 0x4ee5, 0x827a, 0x6291, 0x6613, 0x9091, + 0x5c79, 0x4ebf, 0x5f79, 0x81c6, 0x9038, 0x8084, 0x75ab, 0x4ea6, + 0x88d4, 0x610f, 0x6bc5, 0x5fc6, 0x4e49, 0x76ca, 0x6ea2, 0x8be3, + 0x8bae, 0x8c0a, 0x8bd1, 0x5f02, 0x7ffc, 0x7fcc, 0x7ece, 0x8335, + 0x836b, 0x56e0, 0x6bb7, 0x97f3, 0x9634, 0x59fb, 0x541f, 0x94f6, + 0x6deb, 0x5bc5, 0x996e, 0x5c39, 0x5f15, 0x9690, + /* 0x53 */ + 0x5370, 0x82f1, 0x6a31, 0x5a74, 0x9e70, 0x5e94, 0x7f28, 0x83b9, + 0x8424, 0x8425, 0x8367, 0x8747, 0x8fce, 0x8d62, 0x76c8, 0x5f71, + 0x9896, 0x786c, 0x6620, 0x54df, 0x62e5, 0x4f63, 0x81c3, 0x75c8, + 0x5eb8, 0x96cd, 0x8e0a, 0x86f9, 0x548f, 0x6cf3, 0x6d8c, 0x6c38, + 0x607f, 0x52c7, 0x7528, 0x5e7d, 0x4f18, 0x60a0, 0x5fe7, 0x5c24, + 0x7531, 0x90ae, 0x94c0, 0x72b9, 0x6cb9, 0x6e38, 0x9149, 0x6709, + 0x53cb, 0x53f3, 0x4f51, 0x91c9, 0x8bf1, 0x53c8, 0x5e7c, 0x8fc2, + 0x6de4, 0x4e8e, 0x76c2, 0x6986, 0x865e, 0x611a, 0x8206, 0x4f59, + 0x4fde, 0x903e, 0x9c7c, 0x6109, 0x6e1d, 0x6e14, 0x9685, 0x4e88, + 0x5a31, 0x96e8, 0x4e0e, 0x5c7f, 0x79b9, 0x5b87, 0x8bed, 0x7fbd, + 0x7389, 0x57df, 0x828b, 0x90c1, 0x5401, 0x9047, 0x55bb, 0x5cea, + 0x5fa1, 0x6108, 0x6b32, 0x72f1, 0x80b2, 0x8a89, + /* 0x54 */ + 0x6d74, 0x5bd3, 0x88d5, 0x9884, 0x8c6b, 0x9a6d, 0x9e33, 0x6e0a, + 0x51a4, 0x5143, 0x57a3, 0x8881, 0x539f, 0x63f4, 0x8f95, 0x56ed, + 0x5458, 0x5706, 0x733f, 0x6e90, 0x7f18, 0x8fdc, 0x82d1, 0x613f, + 0x6028, 0x9662, 0x66f0, 0x7ea6, 0x8d8a, 0x8dc3, 0x94a5, 0x5cb3, + 0x7ca4, 0x6708, 0x60a6, 0x9605, 0x8018, 0x4e91, 0x90e7, 0x5300, + 0x9668, 0x5141, 0x8fd0, 0x8574, 0x915d, 0x6655, 0x97f5, 0x5b55, + 0x531d, 0x7838, 0x6742, 0x683d, 0x54c9, 0x707e, 0x5bb0, 0x8f7d, + 0x518d, 0x5728, 0x54b1, 0x6512, 0x6682, 0x8d5e, 0x8d43, 0x810f, + 0x846c, 0x906d, 0x7cdf, 0x51ff, 0x85fb, 0x67a3, 0x65e9, 0x6fa1, + 0x86a4, 0x8e81, 0x566a, 0x9020, 0x7682, 0x7076, 0x71e5, 0x8d23, + 0x62e9, 0x5219, 0x6cfd, 0x8d3c, 0x600e, 0x589e, 0x618e, 0x66fe, + 0x8d60, 0x624e, 0x55b3, 0x6e23, 0x672d, 0x8f67, + /* 0x55 */ + 0x94e1, 0x95f8, 0x7728, 0x6805, 0x69a8, 0x548b, 0x4e4d, 0x70b8, + 0x8bc8, 0x6458, 0x658b, 0x5b85, 0x7a84, 0x503a, 0x5be8, 0x77bb, + 0x6be1, 0x8a79, 0x7c98, 0x6cbe, 0x76cf, 0x65a9, 0x8f97, 0x5d2d, + 0x5c55, 0x8638, 0x6808, 0x5360, 0x6218, 0x7ad9, 0x6e5b, 0x7efd, + 0x6a1f, 0x7ae0, 0x5f70, 0x6f33, 0x5f20, 0x638c, 0x6da8, 0x6756, + 0x4e08, 0x5e10, 0x8d26, 0x4ed7, 0x80c0, 0x7634, 0x969c, 0x62db, + 0x662d, 0x627e, 0x6cbc, 0x8d75, 0x7167, 0x7f69, 0x5146, 0x8087, + 0x53ec, 0x906e, 0x6298, 0x54f2, 0x86f0, 0x8f99, 0x8005, 0x9517, + 0x8517, 0x8fd9, 0x6d59, 0x73cd, 0x659f, 0x771f, 0x7504, 0x7827, + 0x81fb, 0x8d1e, 0x9488, 0x4fa6, 0x6795, 0x75b9, 0x8bca, 0x9707, + 0x632f, 0x9547, 0x9635, 0x84b8, 0x6323, 0x7741, 0x5f81, 0x72f0, + 0x4e89, 0x6014, 0x6574, 0x62ef, 0x6b63, 0x653f, + /* 0x56 */ + 0x5e27, 0x75c7, 0x90d1, 0x8bc1, 0x829d, 0x679d, 0x652f, 0x5431, + 0x8718, 0x77e5, 0x80a2, 0x8102, 0x6c41, 0x4e4b, 0x7ec7, 0x804c, + 0x76f4, 0x690d, 0x6b96, 0x6267, 0x503c, 0x4f84, 0x5740, 0x6307, + 0x6b62, 0x8dbe, 0x53ea, 0x65e8, 0x7eb8, 0x5fd7, 0x631a, 0x63b7, + 0x81f3, 0x81f4, 0x7f6e, 0x5e1c, 0x5cd9, 0x5236, 0x667a, 0x79e9, + 0x7a1a, 0x8d28, 0x7099, 0x75d4, 0x6ede, 0x6cbb, 0x7a92, 0x4e2d, + 0x76c5, 0x5fe0, 0x949f, 0x8877, 0x7ec8, 0x79cd, 0x80bf, 0x91cd, + 0x4ef2, 0x4f17, 0x821f, 0x5468, 0x5dde, 0x6d32, 0x8bcc, 0x7ca5, + 0x8f74, 0x8098, 0x5e1a, 0x5492, 0x76b1, 0x5b99, 0x663c, 0x9aa4, + 0x73e0, 0x682a, 0x86db, 0x6731, 0x732a, 0x8bf8, 0x8bdb, 0x9010, + 0x7af9, 0x70db, 0x716e, 0x62c4, 0x77a9, 0x5631, 0x4e3b, 0x8457, + 0x67f1, 0x52a9, 0x86c0, 0x8d2e, 0x94f8, 0x7b51, + /* 0x57 */ + 0x4f4f, 0x6ce8, 0x795d, 0x9a7b, 0x6293, 0x722a, 0x62fd, 0x4e13, + 0x7816, 0x8f6c, 0x64b0, 0x8d5a, 0x7bc6, 0x6869, 0x5e84, 0x88c5, + 0x5986, 0x649e, 0x58ee, 0x72b6, 0x690e, 0x9525, 0x8ffd, 0x8d58, + 0x5760, 0x7f00, 0x8c06, 0x51c6, 0x6349, 0x62d9, 0x5353, 0x684c, + 0x7422, 0x8301, 0x914c, 0x5544, 0x7740, 0x707c, 0x6d4a, 0x5179, + 0x54a8, 0x8d44, 0x59ff, 0x6ecb, 0x6dc4, 0x5b5c, 0x7d2b, 0x4ed4, + 0x7c7d, 0x6ed3, 0x5b50, 0x81ea, 0x6e0d, 0x5b57, 0x9b03, 0x68d5, + 0x8e2a, 0x5b97, 0x7efc, 0x603b, 0x7eb5, 0x90b9, 0x8d70, 0x594f, + 0x63cd, 0x79df, 0x8db3, 0x5352, 0x65cf, 0x7956, 0x8bc5, 0x963b, + 0x7ec4, 0x94bb, 0x7e82, 0x5634, 0x9189, 0x6700, 0x7f6a, 0x5c0a, + 0x9075, 0x6628, 0x5de6, 0x4f50, 0x67de, 0x505a, 0x4f5c, 0x5750, + 0x5ea7, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x58 */ + 0x4e8d, 0x4e0c, 0x5140, 0x4e10, 0x5eff, 0x5345, 0x4e15, 0x4e98, + 0x4e1e, 0x9b32, 0x5b6c, 0x5669, 0x4e28, 0x79ba, 0x4e3f, 0x5315, + 0x4e47, 0x592d, 0x723b, 0x536e, 0x6c10, 0x56df, 0x80e4, 0x9997, + 0x6bd3, 0x777e, 0x9f17, 0x4e36, 0x4e9f, 0x9f10, 0x4e5c, 0x4e69, + 0x4e93, 0x8288, 0x5b5b, 0x556c, 0x560f, 0x4ec4, 0x538d, 0x539d, + 0x53a3, 0x53a5, 0x53ae, 0x9765, 0x8d5d, 0x531a, 0x53f5, 0x5326, + 0x532e, 0x533e, 0x8d5c, 0x5366, 0x5363, 0x5202, 0x5208, 0x520e, + 0x522d, 0x5233, 0x523f, 0x5240, 0x524c, 0x525e, 0x5261, 0x525c, + 0x84af, 0x527d, 0x5282, 0x5281, 0x5290, 0x5293, 0x5182, 0x7f54, + 0x4ebb, 0x4ec3, 0x4ec9, 0x4ec2, 0x4ee8, 0x4ee1, 0x4eeb, 0x4ede, + 0x4f1b, 0x4ef3, 0x4f22, 0x4f64, 0x4ef5, 0x4f25, 0x4f27, 0x4f09, + 0x4f2b, 0x4f5e, 0x4f67, 0x6538, 0x4f5a, 0x4f5d, + /* 0x59 */ + 0x4f5f, 0x4f57, 0x4f32, 0x4f3d, 0x4f76, 0x4f74, 0x4f91, 0x4f89, + 0x4f83, 0x4f8f, 0x4f7e, 0x4f7b, 0x4faa, 0x4f7c, 0x4fac, 0x4f94, + 0x4fe6, 0x4fe8, 0x4fea, 0x4fc5, 0x4fda, 0x4fe3, 0x4fdc, 0x4fd1, + 0x4fdf, 0x4ff8, 0x5029, 0x504c, 0x4ff3, 0x502c, 0x500f, 0x502e, + 0x502d, 0x4ffe, 0x501c, 0x500c, 0x5025, 0x5028, 0x507e, 0x5043, + 0x5055, 0x5048, 0x504e, 0x506c, 0x507b, 0x50a5, 0x50a7, 0x50a9, + 0x50ba, 0x50d6, 0x5106, 0x50ed, 0x50ec, 0x50e6, 0x50ee, 0x5107, + 0x510b, 0x4edd, 0x6c3d, 0x4f58, 0x4f65, 0x4fce, 0x9fa0, 0x6c46, + 0x7c74, 0x516e, 0x5dfd, 0x9ec9, 0x9998, 0x5181, 0x5914, 0x52f9, + 0x530d, 0x8a07, 0x5310, 0x51eb, 0x5919, 0x5155, 0x4ea0, 0x5156, + 0x4eb3, 0x886e, 0x88a4, 0x4eb5, 0x8114, 0x88d2, 0x7980, 0x5b34, + 0x8803, 0x7fb8, 0x51ab, 0x51b1, 0x51bd, 0x51bc, + /* 0x5a */ + 0x51c7, 0x5196, 0x51a2, 0x51a5, 0x8ba0, 0x8ba6, 0x8ba7, 0x8baa, + 0x8bb4, 0x8bb5, 0x8bb7, 0x8bc2, 0x8bc3, 0x8bcb, 0x8bcf, 0x8bce, + 0x8bd2, 0x8bd3, 0x8bd4, 0x8bd6, 0x8bd8, 0x8bd9, 0x8bdc, 0x8bdf, + 0x8be0, 0x8be4, 0x8be8, 0x8be9, 0x8bee, 0x8bf0, 0x8bf3, 0x8bf6, + 0x8bf9, 0x8bfc, 0x8bff, 0x8c00, 0x8c02, 0x8c04, 0x8c07, 0x8c0c, + 0x8c0f, 0x8c11, 0x8c12, 0x8c14, 0x8c15, 0x8c16, 0x8c19, 0x8c1b, + 0x8c18, 0x8c1d, 0x8c1f, 0x8c20, 0x8c21, 0x8c25, 0x8c27, 0x8c2a, + 0x8c2b, 0x8c2e, 0x8c2f, 0x8c32, 0x8c33, 0x8c35, 0x8c36, 0x5369, + 0x537a, 0x961d, 0x9622, 0x9621, 0x9631, 0x962a, 0x963d, 0x963c, + 0x9642, 0x9649, 0x9654, 0x965f, 0x9667, 0x966c, 0x9672, 0x9674, + 0x9688, 0x968d, 0x9697, 0x96b0, 0x9097, 0x909b, 0x909d, 0x9099, + 0x90ac, 0x90a1, 0x90b4, 0x90b3, 0x90b6, 0x90ba, + /* 0x5b */ + 0x90b8, 0x90b0, 0x90cf, 0x90c5, 0x90be, 0x90d0, 0x90c4, 0x90c7, + 0x90d3, 0x90e6, 0x90e2, 0x90dc, 0x90d7, 0x90db, 0x90eb, 0x90ef, + 0x90fe, 0x9104, 0x9122, 0x911e, 0x9123, 0x9131, 0x912f, 0x9139, + 0x9143, 0x9146, 0x520d, 0x5942, 0x52a2, 0x52ac, 0x52ad, 0x52be, + 0x54ff, 0x52d0, 0x52d6, 0x52f0, 0x53df, 0x71ee, 0x77cd, 0x5ef4, + 0x51f5, 0x51fc, 0x9b2f, 0x53b6, 0x5f01, 0x755a, 0x5def, 0x574c, + 0x57a9, 0x57a1, 0x587e, 0x58bc, 0x58c5, 0x58d1, 0x5729, 0x572c, + 0x572a, 0x5733, 0x5739, 0x572e, 0x572f, 0x575c, 0x573b, 0x5742, + 0x5769, 0x5785, 0x576b, 0x5786, 0x577c, 0x577b, 0x5768, 0x576d, + 0x5776, 0x5773, 0x57ad, 0x57a4, 0x578c, 0x57b2, 0x57cf, 0x57a7, + 0x57b4, 0x5793, 0x57a0, 0x57d5, 0x57d8, 0x57da, 0x57d9, 0x57d2, + 0x57b8, 0x57f4, 0x57ef, 0x57f8, 0x57e4, 0x57dd, + /* 0x5c */ + 0x580b, 0x580d, 0x57fd, 0x57ed, 0x5800, 0x581e, 0x5819, 0x5844, + 0x5820, 0x5865, 0x586c, 0x5881, 0x5889, 0x589a, 0x5880, 0x99a8, + 0x9f19, 0x61ff, 0x8279, 0x827d, 0x827f, 0x828f, 0x828a, 0x82a8, + 0x8284, 0x828e, 0x8291, 0x8297, 0x8299, 0x82ab, 0x82b8, 0x82be, + 0x82b0, 0x82c8, 0x82ca, 0x82e3, 0x8298, 0x82b7, 0x82ae, 0x82cb, + 0x82cc, 0x82c1, 0x82a9, 0x82b4, 0x82a1, 0x82aa, 0x829f, 0x82c4, + 0x82ce, 0x82a4, 0x82e1, 0x8309, 0x82f7, 0x82e4, 0x830f, 0x8307, + 0x82dc, 0x82f4, 0x82d2, 0x82d8, 0x830c, 0x82fb, 0x82d3, 0x8311, + 0x831a, 0x8306, 0x8314, 0x8315, 0x82e0, 0x82d5, 0x831c, 0x8351, + 0x835b, 0x835c, 0x8308, 0x8392, 0x833c, 0x8334, 0x8331, 0x839b, + 0x835e, 0x832f, 0x834f, 0x8347, 0x8343, 0x835f, 0x8340, 0x8317, + 0x8360, 0x832d, 0x833a, 0x8333, 0x8366, 0x8365, + /* 0x5d */ + 0x8368, 0x831b, 0x8369, 0x836c, 0x836a, 0x836d, 0x836e, 0x83b0, + 0x8378, 0x83b3, 0x83b4, 0x83a0, 0x83aa, 0x8393, 0x839c, 0x8385, + 0x837c, 0x83b6, 0x83a9, 0x837d, 0x83b8, 0x837b, 0x8398, 0x839e, + 0x83a8, 0x83ba, 0x83bc, 0x83c1, 0x8401, 0x83e5, 0x83d8, 0x5807, + 0x8418, 0x840b, 0x83dd, 0x83fd, 0x83d6, 0x841c, 0x8438, 0x8411, + 0x8406, 0x83d4, 0x83df, 0x840f, 0x8403, 0x83f8, 0x83f9, 0x83ea, + 0x83c5, 0x83c0, 0x8426, 0x83f0, 0x83e1, 0x845c, 0x8451, 0x845a, + 0x8459, 0x8473, 0x8487, 0x8488, 0x847a, 0x8489, 0x8478, 0x843c, + 0x8446, 0x8469, 0x8476, 0x848c, 0x848e, 0x8431, 0x846d, 0x84c1, + 0x84cd, 0x84d0, 0x84e6, 0x84bd, 0x84d3, 0x84ca, 0x84bf, 0x84ba, + 0x84e0, 0x84a1, 0x84b9, 0x84b4, 0x8497, 0x84e5, 0x84e3, 0x850c, + 0x750d, 0x8538, 0x84f0, 0x8539, 0x851f, 0x853a, + /* 0x5e */ + 0x8556, 0x853b, 0x84ff, 0x84fc, 0x8559, 0x8548, 0x8568, 0x8564, + 0x855e, 0x857a, 0x77a2, 0x8543, 0x8572, 0x857b, 0x85a4, 0x85a8, + 0x8587, 0x858f, 0x8579, 0x85ae, 0x859c, 0x8585, 0x85b9, 0x85b7, + 0x85b0, 0x85d3, 0x85c1, 0x85dc, 0x85ff, 0x8627, 0x8605, 0x8629, + 0x8616, 0x863c, 0x5efe, 0x5f08, 0x593c, 0x5941, 0x8037, 0x5955, + 0x595a, 0x5958, 0x530f, 0x5c22, 0x5c25, 0x5c2c, 0x5c34, 0x624c, + 0x626a, 0x629f, 0x62bb, 0x62ca, 0x62da, 0x62d7, 0x62ee, 0x6322, + 0x62f6, 0x6339, 0x634b, 0x6343, 0x63ad, 0x63f6, 0x6371, 0x637a, + 0x638e, 0x63b4, 0x636d, 0x63ac, 0x638a, 0x6369, 0x63ae, 0x63bc, + 0x63f2, 0x63f8, 0x63e0, 0x63ff, 0x63c4, 0x63de, 0x63ce, 0x6452, + 0x63c6, 0x63be, 0x6445, 0x6441, 0x640b, 0x641b, 0x6420, 0x640c, + 0x6426, 0x6421, 0x645e, 0x6484, 0x646d, 0x6496, + /* 0x5f */ + 0x647a, 0x64b7, 0x64b8, 0x6499, 0x64ba, 0x64c0, 0x64d0, 0x64d7, + 0x64e4, 0x64e2, 0x6509, 0x6525, 0x652e, 0x5f0b, 0x5fd2, 0x7519, + 0x5f11, 0x535f, 0x53f1, 0x53fd, 0x53e9, 0x53e8, 0x53fb, 0x5412, + 0x5416, 0x5406, 0x544b, 0x5452, 0x5453, 0x5454, 0x5456, 0x5443, + 0x5421, 0x5457, 0x5459, 0x5423, 0x5432, 0x5482, 0x5494, 0x5477, + 0x5471, 0x5464, 0x549a, 0x549b, 0x5484, 0x5476, 0x5466, 0x549d, + 0x54d0, 0x54ad, 0x54c2, 0x54b4, 0x54d2, 0x54a7, 0x54a6, 0x54d3, + 0x54d4, 0x5472, 0x54a3, 0x54d5, 0x54bb, 0x54bf, 0x54cc, 0x54d9, + 0x54da, 0x54dc, 0x54a9, 0x54aa, 0x54a4, 0x54dd, 0x54cf, 0x54de, + 0x551b, 0x54e7, 0x5520, 0x54fd, 0x5514, 0x54f3, 0x5522, 0x5523, + 0x550f, 0x5511, 0x5527, 0x552a, 0x5567, 0x558f, 0x55b5, 0x5549, + 0x556d, 0x5541, 0x5555, 0x553f, 0x5550, 0x553c, + /* 0x60 */ + 0x5537, 0x5556, 0x5575, 0x5576, 0x5577, 0x5533, 0x5530, 0x555c, + 0x558b, 0x55d2, 0x5583, 0x55b1, 0x55b9, 0x5588, 0x5581, 0x559f, + 0x557e, 0x55d6, 0x5591, 0x557b, 0x55df, 0x55bd, 0x55be, 0x5594, + 0x5599, 0x55ea, 0x55f7, 0x55c9, 0x561f, 0x55d1, 0x55eb, 0x55ec, + 0x55d4, 0x55e6, 0x55dd, 0x55c4, 0x55ef, 0x55e5, 0x55f2, 0x55f3, + 0x55cc, 0x55cd, 0x55e8, 0x55f5, 0x55e4, 0x8f94, 0x561e, 0x5608, + 0x560c, 0x5601, 0x5624, 0x5623, 0x55fe, 0x5600, 0x5627, 0x562d, + 0x5658, 0x5639, 0x5657, 0x562c, 0x564d, 0x5662, 0x5659, 0x565c, + 0x564c, 0x5654, 0x5686, 0x5664, 0x5671, 0x566b, 0x567b, 0x567c, + 0x5685, 0x5693, 0x56af, 0x56d4, 0x56d7, 0x56dd, 0x56e1, 0x56f5, + 0x56eb, 0x56f9, 0x56ff, 0x5704, 0x570a, 0x5709, 0x571c, 0x5e0f, + 0x5e19, 0x5e14, 0x5e11, 0x5e31, 0x5e3b, 0x5e3c, + /* 0x61 */ + 0x5e37, 0x5e44, 0x5e54, 0x5e5b, 0x5e5e, 0x5e61, 0x5c8c, 0x5c7a, + 0x5c8d, 0x5c90, 0x5c96, 0x5c88, 0x5c98, 0x5c99, 0x5c91, 0x5c9a, + 0x5c9c, 0x5cb5, 0x5ca2, 0x5cbd, 0x5cac, 0x5cab, 0x5cb1, 0x5ca3, + 0x5cc1, 0x5cb7, 0x5cc4, 0x5cd2, 0x5ce4, 0x5ccb, 0x5ce5, 0x5d02, + 0x5d03, 0x5d27, 0x5d26, 0x5d2e, 0x5d24, 0x5d1e, 0x5d06, 0x5d1b, + 0x5d58, 0x5d3e, 0x5d34, 0x5d3d, 0x5d6c, 0x5d5b, 0x5d6f, 0x5d5d, + 0x5d6b, 0x5d4b, 0x5d4a, 0x5d69, 0x5d74, 0x5d82, 0x5d99, 0x5d9d, + 0x8c73, 0x5db7, 0x5dc5, 0x5f73, 0x5f77, 0x5f82, 0x5f87, 0x5f89, + 0x5f8c, 0x5f95, 0x5f99, 0x5f9c, 0x5fa8, 0x5fad, 0x5fb5, 0x5fbc, + 0x8862, 0x5f61, 0x72ad, 0x72b0, 0x72b4, 0x72b7, 0x72b8, 0x72c3, + 0x72c1, 0x72ce, 0x72cd, 0x72d2, 0x72e8, 0x72ef, 0x72e9, 0x72f2, + 0x72f4, 0x72f7, 0x7301, 0x72f3, 0x7303, 0x72fa, + /* 0x62 */ + 0x72fb, 0x7317, 0x7313, 0x7321, 0x730a, 0x731e, 0x731d, 0x7315, + 0x7322, 0x7339, 0x7325, 0x732c, 0x7338, 0x7331, 0x7350, 0x734d, + 0x7357, 0x7360, 0x736c, 0x736f, 0x737e, 0x821b, 0x5925, 0x98e7, + 0x5924, 0x5902, 0x9963, 0x9967, 0x9968, 0x9969, 0x996a, 0x996b, + 0x996c, 0x9974, 0x9977, 0x997d, 0x9980, 0x9984, 0x9987, 0x998a, + 0x998d, 0x9990, 0x9991, 0x9993, 0x9994, 0x9995, 0x5e80, 0x5e91, + 0x5e8b, 0x5e96, 0x5ea5, 0x5ea0, 0x5eb9, 0x5eb5, 0x5ebe, 0x5eb3, + 0x8d53, 0x5ed2, 0x5ed1, 0x5edb, 0x5ee8, 0x5eea, 0x81ba, 0x5fc4, + 0x5fc9, 0x5fd6, 0x5fcf, 0x6003, 0x5fee, 0x6004, 0x5fe1, 0x5fe4, + 0x5ffe, 0x6005, 0x6006, 0x5fea, 0x5fed, 0x5ff8, 0x6019, 0x6035, + 0x6026, 0x601b, 0x600f, 0x600d, 0x6029, 0x602b, 0x600a, 0x603f, + 0x6021, 0x6078, 0x6079, 0x607b, 0x607a, 0x6042, + /* 0x63 */ + 0x606a, 0x607d, 0x6096, 0x609a, 0x60ad, 0x609d, 0x6083, 0x6092, + 0x608c, 0x609b, 0x60ec, 0x60bb, 0x60b1, 0x60dd, 0x60d8, 0x60c6, + 0x60da, 0x60b4, 0x6120, 0x6126, 0x6115, 0x6123, 0x60f4, 0x6100, + 0x610e, 0x612b, 0x614a, 0x6175, 0x61ac, 0x6194, 0x61a7, 0x61b7, + 0x61d4, 0x61f5, 0x5fdd, 0x96b3, 0x95e9, 0x95eb, 0x95f1, 0x95f3, + 0x95f5, 0x95f6, 0x95fc, 0x95fe, 0x9603, 0x9604, 0x9606, 0x9608, + 0x960a, 0x960b, 0x960c, 0x960d, 0x960f, 0x9612, 0x9615, 0x9616, + 0x9617, 0x9619, 0x961a, 0x4e2c, 0x723f, 0x6215, 0x6c35, 0x6c54, + 0x6c5c, 0x6c4a, 0x6ca3, 0x6c85, 0x6c90, 0x6c94, 0x6c8c, 0x6c68, + 0x6c69, 0x6c74, 0x6c76, 0x6c86, 0x6ca9, 0x6cd0, 0x6cd4, 0x6cad, + 0x6cf7, 0x6cf8, 0x6cf1, 0x6cd7, 0x6cb2, 0x6ce0, 0x6cd6, 0x6cfa, + 0x6ceb, 0x6cee, 0x6cb1, 0x6cd3, 0x6cef, 0x6cfe, + /* 0x64 */ + 0x6d39, 0x6d27, 0x6d0c, 0x6d43, 0x6d48, 0x6d07, 0x6d04, 0x6d19, + 0x6d0e, 0x6d2b, 0x6d4d, 0x6d2e, 0x6d35, 0x6d1a, 0x6d4f, 0x6d52, + 0x6d54, 0x6d33, 0x6d91, 0x6d6f, 0x6d9e, 0x6da0, 0x6d5e, 0x6d93, + 0x6d94, 0x6d5c, 0x6d60, 0x6d7c, 0x6d63, 0x6e1a, 0x6dc7, 0x6dc5, + 0x6dde, 0x6e0e, 0x6dbf, 0x6de0, 0x6e11, 0x6de6, 0x6ddd, 0x6dd9, + 0x6e16, 0x6dab, 0x6e0c, 0x6dae, 0x6e2b, 0x6e6e, 0x6e4e, 0x6e6b, + 0x6eb2, 0x6e5f, 0x6e86, 0x6e53, 0x6e54, 0x6e32, 0x6e25, 0x6e44, + 0x6edf, 0x6eb1, 0x6e98, 0x6ee0, 0x6f2d, 0x6ee2, 0x6ea5, 0x6ea7, + 0x6ebd, 0x6ebb, 0x6eb7, 0x6ed7, 0x6eb4, 0x6ecf, 0x6e8f, 0x6ec2, + 0x6e9f, 0x6f62, 0x6f46, 0x6f47, 0x6f24, 0x6f15, 0x6ef9, 0x6f2f, + 0x6f36, 0x6f4b, 0x6f74, 0x6f2a, 0x6f09, 0x6f29, 0x6f89, 0x6f8d, + 0x6f8c, 0x6f78, 0x6f72, 0x6f7c, 0x6f7a, 0x6fd1, + /* 0x65 */ + 0x6fc9, 0x6fa7, 0x6fb9, 0x6fb6, 0x6fc2, 0x6fe1, 0x6fee, 0x6fde, + 0x6fe0, 0x6fef, 0x701a, 0x7023, 0x701b, 0x7039, 0x7035, 0x704f, + 0x705e, 0x5b80, 0x5b84, 0x5b95, 0x5b93, 0x5ba5, 0x5bb8, 0x752f, + 0x9a9e, 0x6434, 0x5be4, 0x5bee, 0x8930, 0x5bf0, 0x8e47, 0x8b07, + 0x8fb6, 0x8fd3, 0x8fd5, 0x8fe5, 0x8fee, 0x8fe4, 0x8fe9, 0x8fe6, + 0x8ff3, 0x8fe8, 0x9005, 0x9004, 0x900b, 0x9026, 0x9011, 0x900d, + 0x9016, 0x9021, 0x9035, 0x9036, 0x902d, 0x902f, 0x9044, 0x9051, + 0x9052, 0x9050, 0x9068, 0x9058, 0x9062, 0x905b, 0x66b9, 0x9074, + 0x907d, 0x9082, 0x9088, 0x9083, 0x908b, 0x5f50, 0x5f57, 0x5f56, + 0x5f58, 0x5c3b, 0x54ab, 0x5c50, 0x5c59, 0x5b71, 0x5c63, 0x5c66, + 0x7fbc, 0x5f2a, 0x5f29, 0x5f2d, 0x8274, 0x5f3c, 0x9b3b, 0x5c6e, + 0x5981, 0x5983, 0x598d, 0x59a9, 0x59aa, 0x59a3, + /* 0x66 */ + 0x5997, 0x59ca, 0x59ab, 0x599e, 0x59a4, 0x59d2, 0x59b2, 0x59af, + 0x59d7, 0x59be, 0x5a05, 0x5a06, 0x59dd, 0x5a08, 0x59e3, 0x59d8, + 0x59f9, 0x5a0c, 0x5a09, 0x5a32, 0x5a34, 0x5a11, 0x5a23, 0x5a13, + 0x5a40, 0x5a67, 0x5a4a, 0x5a55, 0x5a3c, 0x5a62, 0x5a75, 0x80ec, + 0x5aaa, 0x5a9b, 0x5a77, 0x5a7a, 0x5abe, 0x5aeb, 0x5ab2, 0x5ad2, + 0x5ad4, 0x5ab8, 0x5ae0, 0x5ae3, 0x5af1, 0x5ad6, 0x5ae6, 0x5ad8, + 0x5adc, 0x5b09, 0x5b17, 0x5b16, 0x5b32, 0x5b37, 0x5b40, 0x5c15, + 0x5c1c, 0x5b5a, 0x5b65, 0x5b73, 0x5b51, 0x5b53, 0x5b62, 0x9a75, + 0x9a77, 0x9a78, 0x9a7a, 0x9a7f, 0x9a7d, 0x9a80, 0x9a81, 0x9a85, + 0x9a88, 0x9a8a, 0x9a90, 0x9a92, 0x9a93, 0x9a96, 0x9a98, 0x9a9b, + 0x9a9c, 0x9a9d, 0x9a9f, 0x9aa0, 0x9aa2, 0x9aa3, 0x9aa5, 0x9aa7, + 0x7e9f, 0x7ea1, 0x7ea3, 0x7ea5, 0x7ea8, 0x7ea9, + /* 0x67 */ + 0x7ead, 0x7eb0, 0x7ebe, 0x7ec0, 0x7ec1, 0x7ec2, 0x7ec9, 0x7ecb, + 0x7ecc, 0x7ed0, 0x7ed4, 0x7ed7, 0x7edb, 0x7ee0, 0x7ee1, 0x7ee8, + 0x7eeb, 0x7eee, 0x7eef, 0x7ef1, 0x7ef2, 0x7f0d, 0x7ef6, 0x7efa, + 0x7efb, 0x7efe, 0x7f01, 0x7f02, 0x7f03, 0x7f07, 0x7f08, 0x7f0b, + 0x7f0c, 0x7f0f, 0x7f11, 0x7f12, 0x7f17, 0x7f19, 0x7f1c, 0x7f1b, + 0x7f1f, 0x7f21, 0x7f22, 0x7f23, 0x7f24, 0x7f25, 0x7f26, 0x7f27, + 0x7f2a, 0x7f2b, 0x7f2c, 0x7f2d, 0x7f2f, 0x7f30, 0x7f31, 0x7f32, + 0x7f33, 0x7f35, 0x5e7a, 0x757f, 0x5ddb, 0x753e, 0x9095, 0x738e, + 0x7391, 0x73ae, 0x73a2, 0x739f, 0x73cf, 0x73c2, 0x73d1, 0x73b7, + 0x73b3, 0x73c0, 0x73c9, 0x73c8, 0x73e5, 0x73d9, 0x987c, 0x740a, + 0x73e9, 0x73e7, 0x73de, 0x73ba, 0x73f2, 0x740f, 0x742a, 0x745b, + 0x7426, 0x7425, 0x7428, 0x7430, 0x742e, 0x742c, + /* 0x68 */ + 0x741b, 0x741a, 0x7441, 0x745c, 0x7457, 0x7455, 0x7459, 0x7477, + 0x746d, 0x747e, 0x749c, 0x748e, 0x7480, 0x7481, 0x7487, 0x748b, + 0x749e, 0x74a8, 0x74a9, 0x7490, 0x74a7, 0x74d2, 0x74ba, 0x97ea, + 0x97eb, 0x97ec, 0x674c, 0x6753, 0x675e, 0x6748, 0x6769, 0x67a5, + 0x6787, 0x676a, 0x6773, 0x6798, 0x67a7, 0x6775, 0x67a8, 0x679e, + 0x67ad, 0x678b, 0x6777, 0x677c, 0x67f0, 0x6809, 0x67d8, 0x680a, + 0x67e9, 0x67b0, 0x680c, 0x67d9, 0x67b5, 0x67da, 0x67b3, 0x67dd, + 0x6800, 0x67c3, 0x67b8, 0x67e2, 0x680e, 0x67c1, 0x67fd, 0x6832, + 0x6833, 0x6860, 0x6861, 0x684e, 0x6862, 0x6844, 0x6864, 0x6883, + 0x681d, 0x6855, 0x6866, 0x6841, 0x6867, 0x6840, 0x683e, 0x684a, + 0x6849, 0x6829, 0x68b5, 0x688f, 0x6874, 0x6877, 0x6893, 0x686b, + 0x68c2, 0x696e, 0x68fc, 0x691f, 0x6920, 0x68f9, + /* 0x69 */ + 0x6924, 0x68f0, 0x690b, 0x6901, 0x6957, 0x68e3, 0x6910, 0x6971, + 0x6939, 0x6960, 0x6942, 0x695d, 0x6984, 0x696b, 0x6980, 0x6998, + 0x6978, 0x6934, 0x69cc, 0x6987, 0x6988, 0x69ce, 0x6989, 0x6966, + 0x6963, 0x6979, 0x699b, 0x69a7, 0x69bb, 0x69ab, 0x69ad, 0x69d4, + 0x69b1, 0x69c1, 0x69ca, 0x69df, 0x6995, 0x69e0, 0x698d, 0x69ff, + 0x6a2f, 0x69ed, 0x6a17, 0x6a18, 0x6a65, 0x69f2, 0x6a44, 0x6a3e, + 0x6aa0, 0x6a50, 0x6a5b, 0x6a35, 0x6a8e, 0x6a79, 0x6a3d, 0x6a28, + 0x6a58, 0x6a7c, 0x6a91, 0x6a90, 0x6aa9, 0x6a97, 0x6aab, 0x7337, + 0x7352, 0x6b81, 0x6b82, 0x6b87, 0x6b84, 0x6b92, 0x6b93, 0x6b8d, + 0x6b9a, 0x6b9b, 0x6ba1, 0x6baa, 0x8f6b, 0x8f6d, 0x8f71, 0x8f72, + 0x8f73, 0x8f75, 0x8f76, 0x8f78, 0x8f77, 0x8f79, 0x8f7a, 0x8f7c, + 0x8f7e, 0x8f81, 0x8f82, 0x8f84, 0x8f87, 0x8f8b, + /* 0x6a */ + 0x8f8d, 0x8f8e, 0x8f8f, 0x8f98, 0x8f9a, 0x8ece, 0x620b, 0x6217, + 0x621b, 0x621f, 0x6222, 0x6221, 0x6225, 0x6224, 0x622c, 0x81e7, + 0x74ef, 0x74f4, 0x74ff, 0x750f, 0x7511, 0x7513, 0x6534, 0x65ee, + 0x65ef, 0x65f0, 0x660a, 0x6619, 0x6772, 0x6603, 0x6615, 0x6600, + 0x7085, 0x66f7, 0x661d, 0x6634, 0x6631, 0x6636, 0x6635, 0x8006, + 0x665f, 0x6654, 0x6641, 0x664f, 0x6656, 0x6661, 0x6657, 0x6677, + 0x6684, 0x668c, 0x66a7, 0x669d, 0x66be, 0x66db, 0x66dc, 0x66e6, + 0x66e9, 0x8d32, 0x8d33, 0x8d36, 0x8d3b, 0x8d3d, 0x8d40, 0x8d45, + 0x8d46, 0x8d48, 0x8d49, 0x8d47, 0x8d4d, 0x8d55, 0x8d59, 0x89c7, + 0x89ca, 0x89cb, 0x89cc, 0x89ce, 0x89cf, 0x89d0, 0x89d1, 0x726e, + 0x729f, 0x725d, 0x7266, 0x726f, 0x727e, 0x727f, 0x7284, 0x728b, + 0x728d, 0x728f, 0x7292, 0x6308, 0x6332, 0x63b0, + /* 0x6b */ + 0x643f, 0x64d8, 0x8004, 0x6bea, 0x6bf3, 0x6bfd, 0x6bf5, 0x6bf9, + 0x6c05, 0x6c07, 0x6c06, 0x6c0d, 0x6c15, 0x6c18, 0x6c19, 0x6c1a, + 0x6c21, 0x6c29, 0x6c24, 0x6c2a, 0x6c32, 0x6535, 0x6555, 0x656b, + 0x724d, 0x7252, 0x7256, 0x7230, 0x8662, 0x5216, 0x809f, 0x809c, + 0x8093, 0x80bc, 0x670a, 0x80bd, 0x80b1, 0x80ab, 0x80ad, 0x80b4, + 0x80b7, 0x80e7, 0x80e8, 0x80e9, 0x80ea, 0x80db, 0x80c2, 0x80c4, + 0x80d9, 0x80cd, 0x80d7, 0x6710, 0x80dd, 0x80eb, 0x80f1, 0x80f4, + 0x80ed, 0x810d, 0x810e, 0x80f2, 0x80fc, 0x6715, 0x8112, 0x8c5a, + 0x8136, 0x811e, 0x812c, 0x8118, 0x8132, 0x8148, 0x814c, 0x8153, + 0x8174, 0x8159, 0x815a, 0x8171, 0x8160, 0x8169, 0x817c, 0x817d, + 0x816d, 0x8167, 0x584d, 0x5ab5, 0x8188, 0x8182, 0x8191, 0x6ed5, + 0x81a3, 0x81aa, 0x81cc, 0x6726, 0x81ca, 0x81bb, + /* 0x6c */ + 0x81c1, 0x81a6, 0x6b24, 0x6b37, 0x6b39, 0x6b43, 0x6b46, 0x6b59, + 0x98d1, 0x98d2, 0x98d3, 0x98d5, 0x98d9, 0x98da, 0x6bb3, 0x5f40, + 0x6bc2, 0x89f3, 0x6590, 0x9f51, 0x6593, 0x65bc, 0x65c6, 0x65c4, + 0x65c3, 0x65cc, 0x65ce, 0x65d2, 0x65d6, 0x7080, 0x709c, 0x7096, + 0x709d, 0x70bb, 0x70c0, 0x70b7, 0x70ab, 0x70b1, 0x70e8, 0x70ca, + 0x7110, 0x7113, 0x7116, 0x712f, 0x7131, 0x7173, 0x715c, 0x7168, + 0x7145, 0x7172, 0x714a, 0x7178, 0x717a, 0x7198, 0x71b3, 0x71b5, + 0x71a8, 0x71a0, 0x71e0, 0x71d4, 0x71e7, 0x71f9, 0x721d, 0x7228, + 0x706c, 0x7118, 0x7166, 0x71b9, 0x623e, 0x623d, 0x6243, 0x6248, + 0x6249, 0x793b, 0x7940, 0x7946, 0x7949, 0x795b, 0x795c, 0x7953, + 0x795a, 0x7962, 0x7957, 0x7960, 0x796f, 0x7967, 0x797a, 0x7985, + 0x798a, 0x799a, 0x79a7, 0x79b3, 0x5fd1, 0x5fd0, + /* 0x6d */ + 0x603c, 0x605d, 0x605a, 0x6067, 0x6041, 0x6059, 0x6063, 0x60ab, + 0x6106, 0x610d, 0x615d, 0x61a9, 0x619d, 0x61cb, 0x61d1, 0x6206, + 0x8080, 0x807f, 0x6c93, 0x6cf6, 0x6dfc, 0x77f6, 0x77f8, 0x7800, + 0x7809, 0x7817, 0x7818, 0x7811, 0x65ab, 0x782d, 0x781c, 0x781d, + 0x7839, 0x783a, 0x783b, 0x781f, 0x783c, 0x7825, 0x782c, 0x7823, + 0x7829, 0x784e, 0x786d, 0x7856, 0x7857, 0x7826, 0x7850, 0x7847, + 0x784c, 0x786a, 0x789b, 0x7893, 0x789a, 0x7887, 0x789c, 0x78a1, + 0x78a3, 0x78b2, 0x78b9, 0x78a5, 0x78d4, 0x78d9, 0x78c9, 0x78ec, + 0x78f2, 0x7905, 0x78f4, 0x7913, 0x7924, 0x791e, 0x7934, 0x9f9b, + 0x9ef9, 0x9efb, 0x9efc, 0x76f1, 0x7704, 0x770d, 0x76f9, 0x7707, + 0x7708, 0x771a, 0x7722, 0x7719, 0x772d, 0x7726, 0x7735, 0x7738, + 0x7750, 0x7751, 0x7747, 0x7743, 0x775a, 0x7768, + /* 0x6e */ + 0x7762, 0x7765, 0x777f, 0x778d, 0x777d, 0x7780, 0x778c, 0x7791, + 0x779f, 0x77a0, 0x77b0, 0x77b5, 0x77bd, 0x753a, 0x7540, 0x754e, + 0x754b, 0x7548, 0x755b, 0x7572, 0x7579, 0x7583, 0x7f58, 0x7f61, + 0x7f5f, 0x8a48, 0x7f68, 0x7f74, 0x7f71, 0x7f79, 0x7f81, 0x7f7e, + 0x76cd, 0x76e5, 0x8832, 0x9485, 0x9486, 0x9487, 0x948b, 0x948a, + 0x948c, 0x948d, 0x948f, 0x9490, 0x9494, 0x9497, 0x9495, 0x949a, + 0x949b, 0x949c, 0x94a3, 0x94a4, 0x94ab, 0x94aa, 0x94ad, 0x94ac, + 0x94af, 0x94b0, 0x94b2, 0x94b4, 0x94b6, 0x94b7, 0x94b8, 0x94b9, + 0x94ba, 0x94bc, 0x94bd, 0x94bf, 0x94c4, 0x94c8, 0x94c9, 0x94ca, + 0x94cb, 0x94cc, 0x94cd, 0x94ce, 0x94d0, 0x94d1, 0x94d2, 0x94d5, + 0x94d6, 0x94d7, 0x94d9, 0x94d8, 0x94db, 0x94de, 0x94df, 0x94e0, + 0x94e2, 0x94e4, 0x94e5, 0x94e7, 0x94e8, 0x94ea, + /* 0x6f */ + 0x94e9, 0x94eb, 0x94ee, 0x94ef, 0x94f3, 0x94f4, 0x94f5, 0x94f7, + 0x94f9, 0x94fc, 0x94fd, 0x94ff, 0x9503, 0x9502, 0x9506, 0x9507, + 0x9509, 0x950a, 0x950d, 0x950e, 0x950f, 0x9512, 0x9513, 0x9514, + 0x9515, 0x9516, 0x9518, 0x951b, 0x951d, 0x951e, 0x951f, 0x9522, + 0x952a, 0x952b, 0x9529, 0x952c, 0x9531, 0x9532, 0x9534, 0x9536, + 0x9537, 0x9538, 0x953c, 0x953e, 0x953f, 0x9542, 0x9535, 0x9544, + 0x9545, 0x9546, 0x9549, 0x954c, 0x954e, 0x954f, 0x9552, 0x9553, + 0x9554, 0x9556, 0x9557, 0x9558, 0x9559, 0x955b, 0x955e, 0x955f, + 0x955d, 0x9561, 0x9562, 0x9564, 0x9565, 0x9566, 0x9567, 0x9568, + 0x9569, 0x956a, 0x956b, 0x956c, 0x956f, 0x9571, 0x9572, 0x9573, + 0x953a, 0x77e7, 0x77ec, 0x96c9, 0x79d5, 0x79ed, 0x79e3, 0x79eb, + 0x7a06, 0x5d47, 0x7a03, 0x7a02, 0x7a1e, 0x7a14, + /* 0x70 */ + 0x7a39, 0x7a37, 0x7a51, 0x9ecf, 0x99a5, 0x7a70, 0x7688, 0x768e, + 0x7693, 0x7699, 0x76a4, 0x74de, 0x74e0, 0x752c, 0x9e20, 0x9e22, + 0x9e28, 0x9e29, 0x9e2a, 0x9e2b, 0x9e2c, 0x9e32, 0x9e31, 0x9e36, + 0x9e38, 0x9e37, 0x9e39, 0x9e3a, 0x9e3e, 0x9e41, 0x9e42, 0x9e44, + 0x9e46, 0x9e47, 0x9e48, 0x9e49, 0x9e4b, 0x9e4c, 0x9e4e, 0x9e51, + 0x9e55, 0x9e57, 0x9e5a, 0x9e5b, 0x9e5c, 0x9e5e, 0x9e63, 0x9e66, + 0x9e67, 0x9e68, 0x9e69, 0x9e6a, 0x9e6b, 0x9e6c, 0x9e71, 0x9e6d, + 0x9e73, 0x7592, 0x7594, 0x7596, 0x75a0, 0x759d, 0x75ac, 0x75a3, + 0x75b3, 0x75b4, 0x75b8, 0x75c4, 0x75b1, 0x75b0, 0x75c3, 0x75c2, + 0x75d6, 0x75cd, 0x75e3, 0x75e8, 0x75e6, 0x75e4, 0x75eb, 0x75e7, + 0x7603, 0x75f1, 0x75fc, 0x75ff, 0x7610, 0x7600, 0x7605, 0x760c, + 0x7617, 0x760a, 0x7625, 0x7618, 0x7615, 0x7619, + /* 0x71 */ + 0x761b, 0x763c, 0x7622, 0x7620, 0x7640, 0x762d, 0x7630, 0x763f, + 0x7635, 0x7643, 0x763e, 0x7633, 0x764d, 0x765e, 0x7654, 0x765c, + 0x7656, 0x766b, 0x766f, 0x7fca, 0x7ae6, 0x7a78, 0x7a79, 0x7a80, + 0x7a86, 0x7a88, 0x7a95, 0x7aa6, 0x7aa0, 0x7aac, 0x7aa8, 0x7aad, + 0x7ab3, 0x8864, 0x8869, 0x8872, 0x887d, 0x887f, 0x8882, 0x88a2, + 0x88c6, 0x88b7, 0x88bc, 0x88c9, 0x88e2, 0x88ce, 0x88e3, 0x88e5, + 0x88f1, 0x891a, 0x88fc, 0x88e8, 0x88fe, 0x88f0, 0x8921, 0x8919, + 0x8913, 0x891b, 0x890a, 0x8934, 0x892b, 0x8936, 0x8941, 0x8966, + 0x897b, 0x758b, 0x80e5, 0x76b2, 0x76b4, 0x77dc, 0x8012, 0x8014, + 0x8016, 0x801c, 0x8020, 0x8022, 0x8025, 0x8026, 0x8027, 0x8029, + 0x8028, 0x8031, 0x800b, 0x8035, 0x8043, 0x8046, 0x804d, 0x8052, + 0x8069, 0x8071, 0x8983, 0x9878, 0x9880, 0x9883, + /* 0x72 */ + 0x9889, 0x988c, 0x988d, 0x988f, 0x9894, 0x989a, 0x989b, 0x989e, + 0x989f, 0x98a1, 0x98a2, 0x98a5, 0x98a6, 0x864d, 0x8654, 0x866c, + 0x866e, 0x867f, 0x867a, 0x867c, 0x867b, 0x86a8, 0x868d, 0x868b, + 0x86ac, 0x869d, 0x86a7, 0x86a3, 0x86aa, 0x8693, 0x86a9, 0x86b6, + 0x86c4, 0x86b5, 0x86ce, 0x86b0, 0x86ba, 0x86b1, 0x86af, 0x86c9, + 0x86cf, 0x86b4, 0x86e9, 0x86f1, 0x86f2, 0x86ed, 0x86f3, 0x86d0, + 0x8713, 0x86de, 0x86f4, 0x86df, 0x86d8, 0x86d1, 0x8703, 0x8707, + 0x86f8, 0x8708, 0x870a, 0x870d, 0x8709, 0x8723, 0x873b, 0x871e, + 0x8725, 0x872e, 0x871a, 0x873e, 0x8748, 0x8734, 0x8731, 0x8729, + 0x8737, 0x873f, 0x8782, 0x8722, 0x877d, 0x877e, 0x877b, 0x8760, + 0x8770, 0x874c, 0x876e, 0x878b, 0x8753, 0x8763, 0x877c, 0x8764, + 0x8759, 0x8765, 0x8793, 0x87af, 0x87a8, 0x87d2, + /* 0x73 */ + 0x87c6, 0x8788, 0x8785, 0x87ad, 0x8797, 0x8783, 0x87ab, 0x87e5, + 0x87ac, 0x87b5, 0x87b3, 0x87cb, 0x87d3, 0x87bd, 0x87d1, 0x87c0, + 0x87ca, 0x87db, 0x87ea, 0x87e0, 0x87ee, 0x8816, 0x8813, 0x87fe, + 0x880a, 0x881b, 0x8821, 0x8839, 0x883c, 0x7f36, 0x7f42, 0x7f44, + 0x7f45, 0x8210, 0x7afa, 0x7afd, 0x7b08, 0x7b03, 0x7b04, 0x7b15, + 0x7b0a, 0x7b2b, 0x7b0f, 0x7b47, 0x7b38, 0x7b2a, 0x7b19, 0x7b2e, + 0x7b31, 0x7b20, 0x7b25, 0x7b24, 0x7b33, 0x7b3e, 0x7b1e, 0x7b58, + 0x7b5a, 0x7b45, 0x7b75, 0x7b4c, 0x7b5d, 0x7b60, 0x7b6e, 0x7b7b, + 0x7b62, 0x7b72, 0x7b71, 0x7b90, 0x7ba6, 0x7ba7, 0x7bb8, 0x7bac, + 0x7b9d, 0x7ba8, 0x7b85, 0x7baa, 0x7b9c, 0x7ba2, 0x7bab, 0x7bb4, + 0x7bd1, 0x7bc1, 0x7bcc, 0x7bdd, 0x7bda, 0x7be5, 0x7be6, 0x7bea, + 0x7c0c, 0x7bfe, 0x7bfc, 0x7c0f, 0x7c16, 0x7c0b, + /* 0x74 */ + 0x7c1f, 0x7c2a, 0x7c26, 0x7c38, 0x7c41, 0x7c40, 0x81fe, 0x8201, + 0x8202, 0x8204, 0x81ec, 0x8844, 0x8221, 0x8222, 0x8223, 0x822d, + 0x822f, 0x8228, 0x822b, 0x8238, 0x823b, 0x8233, 0x8234, 0x823e, + 0x8244, 0x8249, 0x824b, 0x824f, 0x825a, 0x825f, 0x8268, 0x887e, + 0x8885, 0x8888, 0x88d8, 0x88df, 0x895e, 0x7f9d, 0x7f9f, 0x7fa7, + 0x7faf, 0x7fb0, 0x7fb2, 0x7c7c, 0x6549, 0x7c91, 0x7c9d, 0x7c9c, + 0x7c9e, 0x7ca2, 0x7cb2, 0x7cbc, 0x7cbd, 0x7cc1, 0x7cc7, 0x7ccc, + 0x7ccd, 0x7cc8, 0x7cc5, 0x7cd7, 0x7ce8, 0x826e, 0x66a8, 0x7fbf, + 0x7fce, 0x7fd5, 0x7fe5, 0x7fe1, 0x7fe6, 0x7fe9, 0x7fee, 0x7ff3, + 0x7cf8, 0x7d77, 0x7da6, 0x7dae, 0x7e47, 0x7e9b, 0x9eb8, 0x9eb4, + 0x8d73, 0x8d84, 0x8d94, 0x8d91, 0x8db1, 0x8d67, 0x8d6d, 0x8c47, + 0x8c49, 0x914a, 0x9150, 0x914e, 0x914f, 0x9164, + /* 0x75 */ + 0x9162, 0x9161, 0x9170, 0x9169, 0x916f, 0x917d, 0x917e, 0x9172, + 0x9174, 0x9179, 0x918c, 0x9185, 0x9190, 0x918d, 0x9191, 0x91a2, + 0x91a3, 0x91aa, 0x91ad, 0x91ae, 0x91af, 0x91b5, 0x91b4, 0x91ba, + 0x8c55, 0x9e7e, 0x8db8, 0x8deb, 0x8e05, 0x8e59, 0x8e69, 0x8db5, + 0x8dbf, 0x8dbc, 0x8dba, 0x8dc4, 0x8dd6, 0x8dd7, 0x8dda, 0x8dde, + 0x8dce, 0x8dcf, 0x8ddb, 0x8dc6, 0x8dec, 0x8df7, 0x8df8, 0x8de3, + 0x8df9, 0x8dfb, 0x8de4, 0x8e09, 0x8dfd, 0x8e14, 0x8e1d, 0x8e1f, + 0x8e2c, 0x8e2e, 0x8e23, 0x8e2f, 0x8e3a, 0x8e40, 0x8e39, 0x8e35, + 0x8e3d, 0x8e31, 0x8e49, 0x8e41, 0x8e42, 0x8e51, 0x8e52, 0x8e4a, + 0x8e70, 0x8e76, 0x8e7c, 0x8e6f, 0x8e74, 0x8e85, 0x8e8f, 0x8e94, + 0x8e90, 0x8e9c, 0x8e9e, 0x8c78, 0x8c82, 0x8c8a, 0x8c85, 0x8c98, + 0x8c94, 0x659b, 0x89d6, 0x89de, 0x89da, 0x89dc, + /* 0x76 */ + 0x89e5, 0x89eb, 0x89ef, 0x8a3e, 0x8b26, 0x9753, 0x96e9, 0x96f3, + 0x96ef, 0x9706, 0x9701, 0x9708, 0x970f, 0x970e, 0x972a, 0x972d, + 0x9730, 0x973e, 0x9f80, 0x9f83, 0x9f85, 0x9f86, 0x9f87, 0x9f88, + 0x9f89, 0x9f8a, 0x9f8c, 0x9efe, 0x9f0b, 0x9f0d, 0x96b9, 0x96bc, + 0x96bd, 0x96ce, 0x96d2, 0x77bf, 0x96e0, 0x928e, 0x92ae, 0x92c8, + 0x933e, 0x936a, 0x93ca, 0x938f, 0x943e, 0x946b, 0x9c7f, 0x9c82, + 0x9c85, 0x9c86, 0x9c87, 0x9c88, 0x7a23, 0x9c8b, 0x9c8e, 0x9c90, + 0x9c91, 0x9c92, 0x9c94, 0x9c95, 0x9c9a, 0x9c9b, 0x9c9e, 0x9c9f, + 0x9ca0, 0x9ca1, 0x9ca2, 0x9ca3, 0x9ca5, 0x9ca6, 0x9ca7, 0x9ca8, + 0x9ca9, 0x9cab, 0x9cad, 0x9cae, 0x9cb0, 0x9cb1, 0x9cb2, 0x9cb3, + 0x9cb4, 0x9cb5, 0x9cb6, 0x9cb7, 0x9cba, 0x9cbb, 0x9cbc, 0x9cbd, + 0x9cc4, 0x9cc5, 0x9cc6, 0x9cc7, 0x9cca, 0x9ccb, + /* 0x77 */ + 0x9ccc, 0x9ccd, 0x9cce, 0x9ccf, 0x9cd0, 0x9cd3, 0x9cd4, 0x9cd5, + 0x9cd7, 0x9cd8, 0x9cd9, 0x9cdc, 0x9cdd, 0x9cdf, 0x9ce2, 0x977c, + 0x9785, 0x9791, 0x9792, 0x9794, 0x97af, 0x97ab, 0x97a3, 0x97b2, + 0x97b4, 0x9ab1, 0x9ab0, 0x9ab7, 0x9e58, 0x9ab6, 0x9aba, 0x9abc, + 0x9ac1, 0x9ac0, 0x9ac5, 0x9ac2, 0x9acb, 0x9acc, 0x9ad1, 0x9b45, + 0x9b43, 0x9b47, 0x9b49, 0x9b48, 0x9b4d, 0x9b51, 0x98e8, 0x990d, + 0x992e, 0x9955, 0x9954, 0x9adf, 0x9ae1, 0x9ae6, 0x9aef, 0x9aeb, + 0x9afb, 0x9aed, 0x9af9, 0x9b08, 0x9b0f, 0x9b13, 0x9b1f, 0x9b23, + 0x9ebd, 0x9ebe, 0x7e3b, 0x9e82, 0x9e87, 0x9e88, 0x9e8b, 0x9e92, + 0x93d6, 0x9e9d, 0x9e9f, 0x9edb, 0x9edc, 0x9edd, 0x9ee0, 0x9edf, + 0x9ee2, 0x9ee9, 0x9ee7, 0x9ee5, 0x9eea, 0x9eef, 0x9f22, 0x9f2c, + 0x9f2f, 0x9f39, 0x9f37, 0x9f3d, 0x9f3e, 0x9f44, +}; + +static int +gb2312_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c1 = (s[0] & 0x7F); + if ((c1 >= 0x21 && c1 <= 0x29) || (c1 >= 0x30 && c1 <= 0x77)) { + if (n >= 2) { + unsigned char c2 = (s[1] & 0x7F); + if (c2 >= 0x21 && c2 < 0x7f) { + unsigned int i = 94 * (c1 - 0x21) + (c2 - 0x21); + unsigned short wc = 0xfffd; + if (i < 1410) { + if (i < 831) + wc = gb2312_2uni_page21[i]; + } else { + if (i < 8178) + wc = gb2312_2uni_page30[i-1410]; + } + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 2; + } + } + return RET_ILSEQ; + } + return RET_TOOFEW(0); + } + return RET_ILSEQ; +} + +static const unsigned short gb2312_2charset[7445] = { + 0x2168, 0x216c, 0x2127, 0x2163, 0x2140, 0x2141, 0x2824, 0x2822, + 0x2828, 0x2826, 0x283a, 0x282c, 0x282a, 0x2830, 0x282e, 0x2142, + 0x2834, 0x2832, 0x2839, 0x2821, 0x2825, 0x2827, 0x2829, 0x282d, + 0x2831, 0x2823, 0x282b, 0x282f, 0x2833, 0x2835, 0x2836, 0x2837, + 0x2838, 0x2126, 0x2125, 0x2621, 0x2622, 0x2623, 0x2624, 0x2625, + 0x2626, 0x2627, 0x2628, 0x2629, 0x262a, 0x262b, 0x262c, 0x262d, + 0x262e, 0x262f, 0x2630, 0x2631, 0x2632, 0x2633, 0x2634, 0x2635, + 0x2636, 0x2637, 0x2638, 0x2641, 0x2642, 0x2643, 0x2644, 0x2645, + 0x2646, 0x2647, 0x2648, 0x2649, 0x264a, 0x264b, 0x264c, 0x264d, + 0x264e, 0x264f, 0x2650, 0x2651, 0x2652, 0x2653, 0x2654, 0x2655, + 0x2656, 0x2657, 0x2658, 0x2727, 0x2721, 0x2722, 0x2723, 0x2724, + 0x2725, 0x2726, 0x2728, 0x2729, 0x272a, 0x272b, 0x272c, 0x272d, + 0x272e, 0x272f, 0x2730, 0x2731, 0x2732, 0x2733, 0x2734, 0x2735, + 0x2736, 0x2737, 0x2738, 0x2739, 0x273a, 0x273b, 0x273c, 0x273d, + 0x273e, 0x273f, 0x2740, 0x2741, 0x2751, 0x2752, 0x2753, 0x2754, + 0x2755, 0x2756, 0x2758, 0x2759, 0x275a, 0x275b, 0x275c, 0x275d, + 0x275e, 0x275f, 0x2760, 0x2761, 0x2762, 0x2763, 0x2764, 0x2765, + 0x2766, 0x2767, 0x2768, 0x2769, 0x276a, 0x276b, 0x276c, 0x276d, + 0x276e, 0x276f, 0x2770, 0x2771, 0x2757, 0x212a, 0x212c, 0x212e, + 0x212f, 0x2130, 0x2131, 0x212d, 0x216b, 0x2164, 0x2165, 0x2179, + 0x2166, 0x216d, 0x2271, 0x2272, 0x2273, 0x2274, 0x2275, 0x2276, + 0x2277, 0x2278, 0x2279, 0x227a, 0x227b, 0x227c, 0x217b, 0x217c, + 0x217a, 0x217d, 0x214a, 0x2147, 0x2146, 0x214c, 0x2158, 0x215e, + 0x214f, 0x214e, 0x2144, 0x2145, 0x2149, 0x2148, 0x2152, 0x2153, + 0x2160, 0x215f, 0x2143, 0x214b, 0x2157, 0x2156, 0x2155, 0x2159, + 0x2154, 0x215c, 0x215d, 0x215a, 0x215b, 0x2151, 0x214d, 0x2150, + 0x2259, 0x225a, 0x225b, 0x225c, 0x225d, 0x225e, 0x225f, 0x2260, + 0x2261, 0x2262, 0x2245, 0x2246, 0x2247, 0x2248, 0x2249, 0x224a, + 0x224b, 0x224c, 0x224d, 0x224e, 0x224f, 0x2250, 0x2251, 0x2252, + 0x2253, 0x2254, 0x2255, 0x2256, 0x2257, 0x2258, 0x2231, 0x2232, + 0x2233, 0x2234, 0x2235, 0x2236, 0x2237, 0x2238, 0x2239, 0x223a, + 0x223b, 0x223c, 0x223d, 0x223e, 0x223f, 0x2240, 0x2241, 0x2242, + 0x2243, 0x2244, 0x2924, 0x2925, 0x2926, 0x2927, 0x2928, 0x2929, + 0x292a, 0x292b, 0x292c, 0x292d, 0x292e, 0x292f, 0x2930, 0x2931, + 0x2932, 0x2933, 0x2934, 0x2935, 0x2936, 0x2937, 0x2938, 0x2939, + 0x293a, 0x293b, 0x293c, 0x293d, 0x293e, 0x293f, 0x2940, 0x2941, + 0x2942, 0x2943, 0x2944, 0x2945, 0x2946, 0x2947, 0x2948, 0x2949, + 0x294a, 0x294b, 0x294c, 0x294d, 0x294e, 0x294f, 0x2950, 0x2951, + 0x2952, 0x2953, 0x2954, 0x2955, 0x2956, 0x2957, 0x2958, 0x2959, + 0x295a, 0x295b, 0x295c, 0x295d, 0x295e, 0x295f, 0x2960, 0x2961, + 0x2962, 0x2963, 0x2964, 0x2965, 0x2966, 0x2967, 0x2968, 0x2969, + 0x296a, 0x296b, 0x296c, 0x296d, 0x296e, 0x296f, 0x2176, 0x2175, + 0x2178, 0x2177, 0x2174, 0x2173, 0x2170, 0x2172, 0x2171, 0x216f, + 0x216e, 0x2162, 0x2161, 0x2121, 0x2122, 0x2123, 0x2128, 0x2129, + 0x2134, 0x2135, 0x2136, 0x2137, 0x2138, 0x2139, 0x213a, 0x213b, + 0x213e, 0x213f, 0x217e, 0x2132, 0x2133, 0x213c, 0x213d, 0x2421, + 0x2422, 0x2423, 0x2424, 0x2425, 0x2426, 0x2427, 0x2428, 0x2429, + 0x242a, 0x242b, 0x242c, 0x242d, 0x242e, 0x242f, 0x2430, 0x2431, + 0x2432, 0x2433, 0x2434, 0x2435, 0x2436, 0x2437, 0x2438, 0x2439, + 0x243a, 0x243b, 0x243c, 0x243d, 0x243e, 0x243f, 0x2440, 0x2441, + 0x2442, 0x2443, 0x2444, 0x2445, 0x2446, 0x2447, 0x2448, 0x2449, + 0x244a, 0x244b, 0x244c, 0x244d, 0x244e, 0x244f, 0x2450, 0x2451, + 0x2452, 0x2453, 0x2454, 0x2455, 0x2456, 0x2457, 0x2458, 0x2459, + 0x245a, 0x245b, 0x245c, 0x245d, 0x245e, 0x245f, 0x2460, 0x2461, + 0x2462, 0x2463, 0x2464, 0x2465, 0x2466, 0x2467, 0x2468, 0x2469, + 0x246a, 0x246b, 0x246c, 0x246d, 0x246e, 0x246f, 0x2470, 0x2471, + 0x2472, 0x2473, 0x2521, 0x2522, 0x2523, 0x2524, 0x2525, 0x2526, + 0x2527, 0x2528, 0x2529, 0x252a, 0x252b, 0x252c, 0x252d, 0x252e, + 0x252f, 0x2530, 0x2531, 0x2532, 0x2533, 0x2534, 0x2535, 0x2536, + 0x2537, 0x2538, 0x2539, 0x253a, 0x253b, 0x253c, 0x253d, 0x253e, + 0x253f, 0x2540, 0x2541, 0x2542, 0x2543, 0x2544, 0x2545, 0x2546, + 0x2547, 0x2548, 0x2549, 0x254a, 0x254b, 0x254c, 0x254d, 0x254e, + 0x254f, 0x2550, 0x2551, 0x2552, 0x2553, 0x2554, 0x2555, 0x2556, + 0x2557, 0x2558, 0x2559, 0x255a, 0x255b, 0x255c, 0x255d, 0x255e, + 0x255f, 0x2560, 0x2561, 0x2562, 0x2563, 0x2564, 0x2565, 0x2566, + 0x2567, 0x2568, 0x2569, 0x256a, 0x256b, 0x256c, 0x256d, 0x256e, + 0x256f, 0x2570, 0x2571, 0x2572, 0x2573, 0x2574, 0x2575, 0x2576, + 0x2124, 0x2845, 0x2846, 0x2847, 0x2848, 0x2849, 0x284a, 0x284b, + 0x284c, 0x284d, 0x284e, 0x284f, 0x2850, 0x2851, 0x2852, 0x2853, + 0x2854, 0x2855, 0x2856, 0x2857, 0x2858, 0x2859, 0x285a, 0x285b, + 0x285c, 0x285d, 0x285e, 0x285f, 0x2860, 0x2861, 0x2862, 0x2863, + 0x2864, 0x2865, 0x2866, 0x2867, 0x2868, 0x2869, 0x2265, 0x2266, + 0x2267, 0x2268, 0x2269, 0x226a, 0x226b, 0x226c, 0x226d, 0x226e, + 0x523b, 0x3621, 0x465f, 0x4d72, 0x5549, 0x487d, 0x494f, 0x4f42, + 0x5822, 0x323b, 0x536b, 0x5824, 0x3373, 0x5728, 0x4752, 0x5827, + 0x4a40, 0x4770, 0x317b, 0x5235, 0x3454, 0x362b, 0x4b3f, 0x5829, + 0x362a, 0x413d, 0x514f, 0x4925, 0x582d, 0x3876, 0x513e, 0x635c, + 0x5650, 0x3761, 0x342e, 0x4159, 0x583c, 0x4d68, 0x3524, 0x4e2a, + 0x5677, 0x4076, 0x3e59, 0x582f, 0x444b, 0x3e43, 0x5831, 0x4334, + 0x5265, 0x562e, 0x4e5a, 0x5527, 0x3a75, 0x3726, 0x4056, 0x4639, + 0x4552, 0x4747, 0x3954, 0x334b, 0x5252, 0x583f, 0x3e45, 0x4672, + 0x5232, 0x4f30, 0x4f67, 0x4a69, 0x5840, 0x4272, 0x4252, 0x4869, + 0x472c, 0x414b, 0x5368, 0x5579, 0x4a42, 0x367e, 0x5821, 0x535a, + 0x3f77, 0x5446, 0x3b25, 0x5841, 0x4e65, 0x3e2e, 0x5828, 0x5147, + 0x5029, 0x583d, 0x596f, 0x4d76, 0x3f3a, 0x3d3b, 0x3a25, 0x5260, + 0x327a, 0x3a60, 0x4436, 0x4f6d, 0x3e29, 0x4d24, 0x4141, 0x4757, + 0x5971, 0x5974, 0x484b, 0x5869, 0x525a, 0x4a32, 0x484a, 0x586c, + 0x586a, 0x5846, 0x3d76, 0x464d, 0x3370, 0x586b, 0x3d71, 0x3d69, + 0x4854, 0x3453, 0x4258, 0x3256, 0x5750, 0x4a4b, 0x4b7b, 0x554c, + 0x3836, 0x4f49, 0x595a, 0x5870, 0x472a, 0x586e, 0x347a, 0x416e, + 0x5254, 0x586d, 0x5247, 0x586f, 0x4347, 0x5176, 0x5659, 0x5872, + 0x5875, 0x3c7e, 0x3c5b, 0x484e, 0x375d, 0x3742, 0x4673, 0x5878, + 0x5241, 0x4e69, 0x3c3f, 0x377c, 0x3725, 0x505d, 0x565a, 0x5345, + 0x3b6f, 0x3b61, 0x5871, 0x4921, 0x4e30, 0x342b, 0x5873, 0x494b, + 0x5876, 0x4257, 0x5877, 0x4e31, 0x5879, 0x322e, 0x3940, 0x5923, + 0x3069, 0x4166, 0x496c, 0x4b45, 0x4b46, 0x5924, 0x3568, 0x352b, + 0x4e3b, 0x354d, 0x5721, 0x5774, 0x5353, 0x4c65, 0x3a4e, 0x5922, + 0x595c, 0x5360, 0x587d, 0x3770, 0x5777, 0x587e, 0x587a, 0x5921, + 0x4463, 0x5336, 0x5874, 0x595d, 0x587b, 0x4565, 0x4050, 0x5170, + 0x305b, 0x3c51, 0x5926, 0x5925, 0x592c, 0x592e, 0x592b, 0x4a39, + 0x5929, 0x5636, 0x335e, 0x5928, 0x407d, 0x4a4c, 0x592a, 0x5927, + 0x5930, 0x3631, 0x3929, 0x5240, 0x4f40, 0x4242, 0x3d44, 0x556c, + 0x3260, 0x4748, 0x3f6b, 0x592d, 0x592f, 0x4e6a, 0x3a6e, 0x4756, + 0x3163, 0x3459, 0x366d, 0x5934, 0x3f21, 0x595e, 0x474e, 0x407e, + 0x5938, 0x4b57, 0x377d, 0x5935, 0x5937, 0x3123, 0x5361, 0x5939, + 0x5045, 0x5936, 0x5931, 0x5932, 0x4129, 0x5933, 0x3c73, 0x505e, + 0x3829, 0x3e63, 0x593d, 0x593a, 0x3033, 0x5942, 0x5944, 0x3136, + 0x593f, 0x3539, 0x3e73, 0x4c48, 0x3a72, 0x5250, 0x5943, 0x3d68, + 0x332b, 0x5945, 0x3e6b, 0x5946, 0x593b, 0x445f, 0x593e, 0x5941, + 0x5940, 0x552e, 0x5635, 0x4763, 0x5948, 0x3c59, 0x594a, 0x593c, + 0x594b, 0x462b, 0x5949, 0x5776, 0x4d23, 0x3d21, 0x594c, 0x453c, + 0x4d35, 0x594d, 0x5947, 0x3325, 0x3f7e, 0x3835, 0x407c, 0x3078, + 0x3476, 0x594e, 0x594f, 0x3422, 0x5950, 0x345f, 0x3041, 0x5951, + 0x4935, 0x4f71, 0x5952, 0x4145, 0x5956, 0x492e, 0x5955, 0x5954, + 0x5957, 0x4b5b, 0x3d29, 0x4627, 0x5953, 0x5958, 0x5959, 0x4865, + 0x405c, 0x3679, 0x5823, 0x544a, 0x542a, 0x5056, 0x3364, 0x5557, + 0x4f48, 0x3962, 0x3f4b, 0x4362, 0x3652, 0x4d43, 0x596e, 0x5970, + 0x3533, 0x3635, 0x3e24, 0x486b, 0x482b, 0x304b, 0x392b, 0x4179, + 0x5962, 0x403c, 0x3932, 0x3958, 0x504b, 0x3178, 0x4664, 0x3e5f, + 0x3564, 0x5748, 0x5178, 0x3c66, 0x4a5e, 0x3c3d, 0x5966, 0x5867, + 0x445a, 0x3854, 0x483d, 0x3261, 0x5459, 0x4330, 0x4361, 0x5a22, + 0x485f, 0x5034, 0x3e7c, 0x4529, 0x395a, 0x5a23, 0x5429, 0x5a24, + 0x597b, 0x362c, 0x376b, 0x3179, 0x597c, 0x3365, 0x3e76, 0x3f76, + 0x5231, 0x4064, 0x3633, 0x597e, 0x597d, 0x3e3b, 0x4660, 0x573c, + 0x5a21, 0x4139, 0x3572, 0x4168, 0x3c75, 0x3455, 0x415d, 0x447d, + 0x3c38, 0x3732, 0x376f, 0x596c, 0x463e, 0x3f2d, 0x3b4b, 0x354a, + 0x5b49, 0x5057, 0x4d39, 0x303c, 0x3376, 0x3b77, 0x5b4a, 0x3a2f, + 0x5464, 0x3536, 0x3573, 0x5856, 0x4850, 0x3756, 0x4750, 0x5857, + 0x3f2f, 0x5b3b, 0x5858, 0x504c, 0x3b2e, 0x6b3e, 0x4150, 0x4175, + 0x5472, 0x3855, 0x3434, 0x3375, 0x493e, 0x4550, 0x4559, 0x407b, + 0x3170, 0x5859, 0x394e, 0x353d, 0x585a, 0x5646, 0x4b22, 0x482f, + 0x4932, 0x344c, 0x3f4c, 0x3974, 0x585b, 0x585c, 0x3667, 0x3c41, + 0x4c6a, 0x4f77, 0x585d, 0x4730, 0x3950, 0x3d23, 0x4c5e, 0x464a, + 0x5860, 0x585e, 0x585f, 0x307e, 0x3e67, 0x4a23, 0x3c74, 0x3831, + 0x386e, 0x5862, 0x3d4b, 0x5864, 0x5863, 0x457c, 0x5865, 0x5866, + 0x4126, 0x4830, 0x306c, 0x3926, 0x3c53, 0x4e71, 0x5b3d, 0x4153, + 0x362f, 0x567a, 0x452c, 0x3d59, 0x5b3e, 0x5b3f, 0x4078, 0x3e22, + 0x404d, 0x5b40, 0x4a46, 0x322a, 0x5342, 0x4363, 0x512b, 0x5b42, + 0x4055, 0x5b43, 0x3f31, 0x443c, 0x475a, 0x5b44, 0x5968, 0x4957, + 0x3934, 0x4e70, 0x5448, 0x307c, 0x3452, 0x5059, 0x5969, 0x5e4b, + 0x596b, 0x5830, 0x3b2f, 0x3131, 0x3357, 0x584e, 0x5451, 0x3d33, + 0x3f6f, 0x4f3b, 0x5850, 0x374b, 0x5851, 0x4625, 0x4778, 0x523d, + 0x5852, 0x4464, 0x4a2e, 0x4727, 0x5826, 0x497d, 0x4e67, 0x3b5c, + 0x306b, 0x3b2a, 0x502d, 0x3130, 0x5764, 0x573f, 0x3525, 0x4274, + 0x444f, 0x3229, 0x3237, 0x3165, 0x5f32, 0x553c, 0x3f28, 0x422c, + 0x5855, 0x4231, 0x5854, 0x4e54, 0x5a60, 0x4e40, 0x5834, 0x432e, + 0x5321, 0x4e23, 0x3c34, 0x4834, 0x4251, 0x3e6d, 0x5036, 0x5a61, + 0x4764, 0x3327, 0x3672, 0x4c7c, 0x407a, 0x4077, 0x5139, 0x5161, + 0x5847, 0x325e, 0x4065, 0x3a71, 0x5848, 0x542d, 0x4f61, 0x5849, + 0x584a, 0x4f43, 0x3378, 0x3e47, 0x584b, 0x5b4c, 0x4825, 0x4f58, + 0x487e, 0x324e, 0x5356, 0x3266, 0x3c30, 0x5351, 0x4b2b, 0x3734, + 0x3722, 0x4a65, 0x4821, 0x4a5c, 0x3164, 0x5070, 0x4551, 0x5b45, + 0x357e, 0x3f5a, 0x3945, 0x3e64, 0x416d, 0x5f36, 0x5f35, 0x563b, + 0x3d50, 0x5559, 0x3048, 0x3623, 0x3f49, 0x4c28, 0x5f33, 0x4a37, + 0x5352, 0x584f, 0x5236, 0x3a45, 0x4b3e, 0x4c3e, 0x5f37, 0x3570, + 0x5f34, 0x5375, 0x3354, 0x3877, 0x5f3a, 0x3a4f, 0x3c2a, 0x3575, + 0x4d2c, 0x437b, 0x3a73, 0x4074, 0x4d42, 0x4f72, 0x5f38, 0x4f45, + 0x4240, 0x5f39, 0x4270, 0x3e7d, 0x415f, 0x4d4c, 0x5277, 0x374d, + 0x5f41, 0x5f44, 0x3771, 0x3049, 0x3656, 0x3754, 0x3a2c, 0x4c7d, + 0x3f54, 0x4b31, 0x4674, 0x5628, 0x5f45, 0x4e62, 0x3333, 0x4e7c, + 0x3435, 0x4e47, 0x3a70, 0x4e61, 0x513d, 0x5f40, 0x3474, 0x334a, + 0x3866, 0x5f3b, 0x4445, 0x5f3c, 0x5f3d, 0x5f3e, 0x453b, 0x5f3f, + 0x5f42, 0x5431, 0x5f43, 0x473a, 0x4e58, 0x4458, 0x5f4a, 0x5f4f, + 0x565c, 0x5f49, 0x5f5a, 0x4e36, 0x3a47, 0x5f4e, 0x5f48, 0x455e, + 0x496b, 0x3a74, 0x437c, 0x3e57, 0x5f46, 0x5f4d, 0x4558, 0x5526, + 0x3a4d, 0x3e4c, 0x533d, 0x3840, 0x5664, 0x5f47, 0x393e, 0x3f27, + 0x417c, 0x5f4b, 0x5f4c, 0x5f50, 0x5f5b, 0x5f65, 0x5f57, 0x5f56, + 0x5749, 0x5f63, 0x5f64, 0x656b, 0x5227, 0x5f52, 0x3f29, 0x545b, + 0x3f48, 0x5f54, 0x4f4c, 0x5f5d, 0x514a, 0x5f5e, 0x3027, 0x4637, + 0x5f53, 0x3a65, 0x365f, 0x4d5b, 0x397e, 0x5455, 0x5f5f, 0x4f6c, + 0x3025, 0x5f67, 0x5f51, 0x5146, 0x5f55, 0x5f58, 0x5f59, 0x5f5c, + 0x3b29, 0x5f60, 0x5f61, 0x5f62, 0x5f66, 0x5f68, 0x5334, 0x3867, + 0x4536, 0x5f6a, 0x495a, 0x4128, 0x4444, 0x3f5e, 0x4f78, 0x555c, + 0x5f6e, 0x3238, 0x3a5f, 0x5f6c, 0x5b41, 0x5164, 0x4b74, 0x343d, + 0x3026, 0x5f71, 0x4c46, 0x5f72, 0x5f6d, 0x5f69, 0x5f6b, 0x5f6f, + 0x5f70, 0x3b3d, 0x5f73, 0x5f74, 0x3b23, 0x4a5b, 0x4e28, 0x6027, + 0x332a, 0x6026, 0x6021, 0x5f7e, 0x4d59, 0x5f7c, 0x5f7a, 0x3f50, + 0x5744, 0x494c, 0x5f78, 0x3021, 0x5f7d, 0x5f7b, 0x6022, 0x6028, + 0x3748, 0x4621, 0x4936, 0x4032, 0x5f75, 0x453e, 0x5844, 0x5f79, + 0x4476, 0x6023, 0x6024, 0x6025, 0x5025, 0x6034, 0x4c64, 0x6031, + 0x3f26, 0x602f, 0x4e39, 0x602b, 0x4946, 0x402e, 0x602e, 0x3a6d, + 0x3a30, 0x6029, 0x5f76, 0x6033, 0x6038, 0x342d, 0x6039, 0x4f32, + 0x3a48, 0x6030, 0x507a, 0x602c, 0x547b, 0x5f77, 0x4567, 0x602d, + 0x5377, 0x6036, 0x6037, 0x6044, 0x5061, 0x603c, 0x6049, 0x604a, + 0x603e, 0x602a, 0x4924, 0x6041, 0x6032, 0x4a48, 0x6043, 0x6035, + 0x4e4b, 0x4b43, 0x604d, 0x6046, 0x6042, 0x604b, 0x603a, 0x603f, + 0x6040, 0x6045, 0x6047, 0x6048, 0x604c, 0x603b, 0x4b54, 0x6055, + 0x6056, 0x6052, 0x6050, 0x3c4e, 0x6051, 0x3842, 0x5845, 0x506a, + 0x426f, 0x604f, 0x603d, 0x6054, 0x6053, 0x6057, 0x605c, 0x6058, + 0x5676, 0x3330, 0x576c, 0x4b3b, 0x605a, 0x4e7b, 0x3a59, 0x6061, + 0x605d, 0x522d, 0x6062, 0x605b, 0x6059, 0x605f, 0x6060, 0x605e, + 0x6064, 0x4677, 0x582c, 0x546b, 0x6066, 0x4a49, 0x6065, 0x3841, + 0x6067, 0x6068, 0x6069, 0x6063, 0x3a3f, 0x4c67, 0x606a, 0x4f79, + 0x606b, 0x4842, 0x3d40, 0x4452, 0x606c, 0x606d, 0x4774, 0x4b44, + 0x606e, 0x3b58, 0x5836, 0x5272, 0x606f, 0x4d45, 0x365a, 0x6071, + 0x5430, 0x4027, 0x3451, 0x4e27, 0x6070, 0x6072, 0x394c, 0x397a, + 0x4d3c, 0x6073, 0x4654, 0x6074, 0x5432, 0x4826, 0x6076, 0x6075, + 0x6077, 0x4d41, 0x4a25, 0x545a, 0x5b57, 0x5b59, 0x5b58, 0x3967, + 0x5b5c, 0x5b5d, 0x3558, 0x5b5a, 0x5b5b, 0x3321, 0x5b5f, 0x3b78, + 0x5637, 0x5b60, 0x3e79, 0x373b, 0x5b50, 0x4c2e, 0x3f32, 0x3b35, + 0x5778, 0x3f53, 0x3f69, 0x3c61, 0x4c33, 0x5b5e, 0x3053, 0x4e6b, + 0x3758, 0x5739, 0x4642, 0x4024, 0x4c39, 0x5b67, 0x5b61, 0x463a, + 0x5b63, 0x5b68, 0x4577, 0x5b6a, 0x5b69, 0x3f40, 0x5b66, 0x5b65, + 0x3439, 0x402c, 0x4222, 0x5b62, 0x5b64, 0x504d, 0x5b6d, 0x405d, + 0x5b72, 0x3662, 0x5b73, 0x5b52, 0x3938, 0x542b, 0x5b6c, 0x3f51, + 0x5b70, 0x5b51, 0x3566, 0x5b6b, 0x3f65, 0x5b6e, 0x5b71, 0x5b79, + 0x3921, 0x3023, 0x4271, 0x3347, 0x5b6f, 0x5b78, 0x4652, 0x5b74, + 0x5b75, 0x5b77, 0x5b76, 0x5b7e, 0x5372, 0x323a, 0x5b7d, 0x5c24, + 0x5b7b, 0x5b7a, 0x5b7c, 0x4560, 0x3b79, 0x5c23, 0x5c25, 0x4c43, + 0x3651, 0x5d40, 0x5c21, 0x5c22, 0x4735, 0x3669, 0x5c27, 0x5c26, + 0x5c29, 0x3124, 0x354c, 0x3f30, 0x515f, 0x3642, 0x5c28, 0x4b7a, + 0x6b73, 0x4b5c, 0x4b7e, 0x4c41, 0x487b, 0x5c2a, 0x4c6e, 0x5c2b, + 0x5b53, 0x5c2f, 0x5c2c, 0x3e33, 0x4a7b, 0x5c2d, 0x494a, 0x4439, + 0x473d, 0x5c2e, 0x5476, 0x5066, 0x442b, 0x3655, 0x5b54, 0x315a, + 0x5b55, 0x5b56, 0x3a3e, 0x4840, 0x4a3f, 0x4849, 0x5733, 0x4979, + 0x3f47, 0x3a78, 0x523c, 0x623a, 0x3426, 0x3138, 0x3834, 0x4f44, + 0x5967, 0x4f26, 0x4d62, 0x596d, 0x3660, 0x5239, 0x393b, 0x6239, + 0x6237, 0x3473, 0x4c6c, 0x4c2b, 0x3772, 0x5832, 0x516b, 0x3a3b, + 0x4a27, 0x4d37, 0x5244, 0x3f64, 0x3c50, 0x3661, 0x5e45, 0x5e46, + 0x5b3c, 0x5159, 0x4666, 0x444e, 0x376e, 0x375c, 0x3f7c, 0x5760, + 0x4675, 0x313c, 0x5e48, 0x3d31, 0x4c57, 0x5e4a, 0x5e49, 0x356c, + 0x495d, 0x3042, 0x452e, 0x452b, 0x444c, 0x3c69, 0x4b7d, 0x3a43, + 0x6579, 0x4867, 0x657a, 0x4d7d, 0x5731, 0x383e, 0x4268, 0x4851, + 0x657b, 0x364a, 0x3c4b, 0x517d, 0x6621, 0x436e, 0x6624, 0x657e, + 0x6625, 0x4d57, 0x3741, 0x657c, 0x657d, 0x6623, 0x445d, 0x6628, + 0x6627, 0x4343, 0x465e, 0x662a, 0x4437, 0x6622, 0x4a3c, 0x3d63, + 0x3943, 0x6626, 0x5055, 0x4e2f, 0x6629, 0x6630, 0x5226, 0x3d2a, + 0x662d, 0x662f, 0x4051, 0x524c, 0x3c27, 0x6631, 0x5276, 0x574b, + 0x4d7e, 0x4d5e, 0x4226, 0x662b, 0x662c, 0x3d3f, 0x662e, 0x6633, + 0x6632, 0x6636, 0x6638, 0x446f, 0x4448, 0x3e6a, 0x496f, 0x6637, + 0x3670, 0x4364, 0x5369, 0x6634, 0x6635, 0x4822, 0x663d, 0x6639, + 0x4645, 0x4d71, 0x663b, 0x663c, 0x3b69, 0x663e, 0x663a, 0x4037, + 0x5324, 0x663f, 0x4974, 0x6643, 0x6644, 0x5076, 0x433d, 0x4344, + 0x6642, 0x6641, 0x6647, 0x4f31, 0x6b74, 0x664a, 0x6645, 0x3c5e, + 0x4929, 0x3c35, 0x4f53, 0x6648, 0x6649, 0x664e, 0x6650, 0x6651, + 0x664b, 0x3555, 0x664c, 0x664f, 0x445b, 0x6646, 0x664d, 0x6652, + 0x6654, 0x6653, 0x6655, 0x5978, 0x6656, 0x6657, 0x5753, 0x665d, + 0x665e, 0x3f57, 0x5450, 0x5756, 0x3466, 0x4b6f, 0x665a, 0x5843, + 0x574e, 0x5022, 0x434f, 0x665f, 0x3c3e, 0x3942, 0x665b, 0x5127, + 0x3a22, 0x424f, 0x582b, 0x4a6b, 0x656e, 0x665c, 0x3775, 0x4866, + 0x4475, 0x6532, 0x447e, 0x4b7c, 0x6533, 0x552c, 0x536e, 0x4a58, + 0x3032, 0x4b4e, 0x4d6a, 0x3a6a, 0x6535, 0x6534, 0x575a, 0x3959, + 0x5666, 0x3628, 0x4d70, 0x524b, 0x3126, 0x4a35, 0x3368, 0x4973, + 0x3f4d, 0x507b, 0x4a52, 0x6536, 0x3b42, 0x4f5c, 0x392c, 0x5457, + 0x3a26, 0x5167, 0x4f7c, 0x3c52, 0x6537, 0x485d, 0x3f6d, 0x3176, + 0x4b5e, 0x3c45, 0x3c44, 0x527a, 0x435c, 0x3f5c, 0x383b, 0x4342, + 0x3a2e, 0x5422, 0x475e, 0x442f, 0x326c, 0x3951, 0x653b, 0x4148, + 0x552f, 0x653c, 0x653e, 0x3467, 0x3654, 0x4b42, 0x5130, 0x353c, + 0x4a59, 0x3762, 0x4964, 0x3d2b, 0x4e3e, 0x5770, 0x5021, 0x4959, + 0x367b, 0x6658, 0x3c62, 0x333e, 0x4950, 0x6659, 0x3322, 0x5e4c, + 0x5348, 0x5e4d, 0x5222, 0x5e4e, 0x3e4d, 0x5e4f, 0x4a2c, 0x527c, + 0x335f, 0x656a, 0x4461, 0x3e21, 0x4e32, 0x4472, 0x3e56, 0x4628, + 0x3263, 0x3e53, 0x477c, 0x4c6b, 0x3d6c, 0x4e5d, 0x4a3a, 0x4641, + 0x656c, 0x503c, 0x5539, 0x656d, 0x4a74, 0x4d40, 0x4245, 0x656f, + 0x4244, 0x6570, 0x6578, 0x4d4d, 0x493d, 0x5259, 0x6128, 0x536c, + 0x4b6a, 0x4671, 0x612c, 0x6127, 0x6129, 0x612a, 0x612f, 0x326d, + 0x612b, 0x385a, 0x612d, 0x612e, 0x6130, 0x353a, 0x6131, 0x6133, + 0x6138, 0x5152, 0x6136, 0x6135, 0x416b, 0x6137, 0x5440, 0x6132, + 0x613a, 0x3036, 0x6134, 0x3f79, 0x6139, 0x613b, 0x613e, 0x613c, + 0x5645, 0x4f3f, 0x613d, 0x613f, 0x424d, 0x366b, 0x5378, 0x474d, + 0x3765, 0x3e7e, 0x6140, 0x6141, 0x6147, 0x3367, 0x4669, 0x345e, + 0x5142, 0x6148, 0x6146, 0x6145, 0x6143, 0x6142, 0x3140, 0x5538, + 0x6144, 0x614b, 0x614c, 0x614a, 0x6f7a, 0x6153, 0x6152, 0x4736, + 0x6149, 0x614e, 0x6150, 0x6154, 0x6151, 0x614d, 0x614f, 0x6155, + 0x6156, 0x6157, 0x6158, 0x615a, 0x615b, 0x4e21, 0x675d, 0x3428, + 0x565d, 0x5132, 0x3332, 0x3924, 0x5773, 0x4749, 0x3e5e, 0x392e, + 0x4e57, 0x326e, 0x5b4f, 0x3c3a, 0x5251, 0x4b48, 0x304d, 0x4f6f, + 0x5963, 0x3d6d, 0x3152, 0x4a50, 0x323c, 0x4b27, 0x372b, 0x4a26, + 0x4f23, 0x6078, 0x554a, 0x607b, 0x607a, 0x4541, 0x4c7b, 0x4131, + 0x6079, 0x5663, 0x322f, 0x5644, 0x355b, 0x3478, 0x5621, 0x4f2f, + 0x306f, 0x607c, 0x6121, 0x3323, 0x607d, 0x607e, 0x4331, 0x435d, + 0x6122, 0x3779, 0x3b4f, 0x6123, 0x443b, 0x6124, 0x6125, 0x6126, + 0x3431, 0x3849, 0x463d, 0x446a, 0x3222, 0x5052, 0x675b, 0x3b43, + 0x5357, 0x5344, 0x3963, 0x624f, 0x572f, 0x476c, 0x3153, 0x3432, + 0x6251, 0x5072, 0x422e, 0x6250, 0x3f62, 0x5326, 0x3557, 0x6252, + 0x356a, 0x436d, 0x387d, 0x382e, 0x4553, 0x374f, 0x6254, 0x6253, + 0x3648, 0x5779, 0x4d25, 0x6258, 0x6256, 0x4a7c, 0x3f35, 0x5339, + 0x6255, 0x6257, 0x412e, 0x4048, 0x625b, 0x625a, 0x402a, 0x414e, + 0x625c, 0x625d, 0x625e, 0x5b48, 0x5153, 0x4d22, 0x3d28, 0x5e43, + 0x5825, 0x3f2a, 0x5b4d, 0x526c, 0x467a, 0x452a, 0x5e44, 0x3157, + 0x5f2e, 0x4a3d, 0x5f31, 0x392d, 0x527d, 0x3825, 0x3a6b, 0x335a, + 0x355c, 0x5545, 0x4356, 0x4f52, 0x3b21, 0x6573, 0x6572, 0x6574, + 0x4d64, 0x4875, 0x352f, 0x473f, 0x6576, 0x6c30, 0x6566, 0x3969, + 0x3531, 0x423c, 0x6568, 0x6567, 0x6569, 0x524d, 0x616a, 0x504e, + 0x4d2e, 0x5165, 0x324a, 0x316b, 0x3172, 0x456d, 0x5543, 0x5330, + 0x615c, 0x615d, 0x525b, 0x3339, 0x314b, 0x4d79, 0x5577, 0x615e, + 0x3e36, 0x347d, 0x615f, 0x3a5c, 0x6160, 0x3b32, 0x4249, 0x6161, + 0x506c, 0x4d3d, 0x6162, 0x3543, 0x4547, 0x6163, 0x6164, 0x5379, + 0x6165, 0x512d, 0x6166, 0x4e22, 0x6167, 0x3542, 0x6168, 0x3b55, + 0x5044, 0x6260, 0x3158, 0x5264, 0x6261, 0x3c49, 0x484c, 0x6263, + 0x6c7e, 0x6c7d, 0x5f2f, 0x6262, 0x563e, 0x4d7c, 0x4326, 0x6343, + 0x5652, 0x6267, 0x6268, 0x5347, 0x626c, 0x3f6c, 0x626d, 0x6265, + 0x3340, 0x446e, 0x626e, 0x5043, 0x3a76, 0x6269, 0x375e, 0x3b33, + 0x4c2c, 0x4b4b, 0x6264, 0x6266, 0x626a, 0x626b, 0x6277, 0x6274, + 0x5475, 0x6273, 0x452d, 0x557a, 0x4542, 0x3240, 0x626f, 0x6272, + 0x412f, 0x4b3c, 0x3521, 0x6279, 0x3c31, 0x6271, 0x5054, 0x5439, + 0x6275, 0x3956, 0x6276, 0x4753, 0x6270, 0x575c, 0x6d21, 0x6278, + 0x6d25, 0x627e, 0x4a51, 0x4135, 0x3b50, 0x3f56, 0x3a63, 0x4b21, + 0x6d26, 0x6d23, 0x6d22, 0x3b56, 0x6d27, 0x5074, 0x6d24, 0x3a5e, + 0x3677, 0x6321, 0x3632, 0x4c71, 0x3927, 0x4f22, 0x4721, 0x3f52, + 0x3671, 0x627a, 0x627b, 0x627d, 0x627c, 0x4455, 0x6322, 0x5341, + 0x6327, 0x4744, 0x4f24, 0x6329, 0x3a37, 0x6328, 0x3b5a, 0x6323, + 0x6324, 0x632a, 0x6326, 0x4e72, 0x5346, 0x3b3c, 0x5443, 0x447a, + 0x6d28, 0x507c, 0x6325, 0x4375, 0x632d, 0x312f, 0x6332, 0x3c42, + 0x632c, 0x353f, 0x4769, 0x6330, 0x3e2a, 0x4d6f, 0x3b73, 0x4c68, + 0x632f, 0x6331, 0x4f27, 0x632e, 0x4e29, 0x3b5d, 0x356b, 0x3e65, + 0x3252, 0x334d, 0x3139, 0x632b, 0x3251, 0x352c, 0x395f, 0x3668, + 0x4f6b, 0x6337, 0x3b4c, 0x4847, 0x504a, 0x6338, 0x336e, 0x6d29, + 0x537a, 0x5364, 0x6d2a, 0x6339, 0x5262, 0x6335, 0x535e, 0x3850, + 0x6333, 0x6336, 0x375f, 0x6334, 0x4022, 0x633a, 0x5438, 0x3448, + 0x633b, 0x3b45, 0x4977, 0x4965, 0x443d, 0x6d2b, 0x427d, 0x3b5b, + 0x3f2e, 0x4e3f, 0x633c, 0x3f36, 0x316f, 0x5477, 0x633e, 0x6d2d, + 0x633f, 0x3a29, 0x6d2c, 0x633d, 0x6340, 0x3a36, 0x362e, 0x5038, + 0x3043, 0x6d2e, 0x6d2f, 0x4041, 0x6341, 0x4533, 0x6342, 0x5c32, + 0x6d30, 0x386a, 0x4e6c, 0x6a27, 0x5067, 0x4a79, 0x4856, 0x4f37, + 0x3349, 0x4e52, 0x3d64, 0x635e, 0x3b72, 0x6a28, 0x553d, 0x465d, + 0x6a29, 0x6a2a, 0x6a2c, 0x6a2b, 0x6a2e, 0x6a2d, 0x3d58, 0x6a2f, + 0x423e, 0x3441, 0x3477, 0x3b27, 0x6c66, 0x6c65, 0x373f, 0x4b79, + 0x3162, 0x6c67, 0x4948, 0x6c68, 0x6c69, 0x4a56, 0x5e50, 0x3245, + 0x547a, 0x464b, 0x3047, 0x3472, 0x4853, 0x4d50, 0x3f38, 0x3f5b, + 0x4724, 0x5634, 0x4029, 0x5e51, 0x4928, 0x516f, 0x4524, 0x3067, + 0x3336, 0x4845, 0x3062, 0x3776, 0x457a, 0x3673, 0x5552, 0x3350, + 0x3c3c, 0x332d, 0x3e71, 0x3051, 0x5256, 0x4a63, 0x5725, 0x4d36, + 0x3636, 0x3f39, 0x555b, 0x3827, 0x4557, 0x5e52, 0x3f59, 0x4255, + 0x4740, 0x3b24, 0x3128, 0x456a, 0x457b, 0x4c27, 0x3127, 0x3556, + 0x4428, 0x5e53, 0x513a, 0x3369, 0x4372, 0x3777, 0x5674, 0x3523, + 0x3270, 0x4434, 0x4469, 0x402d, 0x5e54, 0x3068, 0x4544, 0x4160, + 0x3955, 0x3e5c, 0x4d58, 0x304e, 0x4d4f, 0x5e56, 0x3e50, 0x573e, + 0x5e55, 0x5550, 0x305d, 0x4462, 0x4223, 0x3c70, 0x5335, 0x4039, + 0x4521, 0x3226, 0x5471, 0x4028, 0x4a43, 0x5e57, 0x557c, 0x3930, + 0x482d, 0x4b29, 0x5e59, 0x3f3d, 0x4634, 0x5727, 0x4a30, 0x4443, + 0x3356, 0x3952, 0x5638, 0x6a7c, 0x3034, 0x3f66, 0x4c74, 0x4d5a, + 0x563f, 0x424e, 0x4e4e, 0x4c22, 0x502e, 0x4453, 0x3532, 0x5e58, + 0x5575, 0x3c37, 0x3b53, 0x3024, 0x4532, 0x346c, 0x5571, 0x6a7d, + 0x5e5a, 0x4d26, 0x4d6c, 0x4e66, 0x5e5c, 0x4d31, 0x4026, 0x573d, + 0x5e5b, 0x3046, 0x3a34, 0x4953, 0x4473, 0x3e68, 0x3236, 0x404c, + 0x4b70, 0x3c71, 0x3b3b, 0x3537, 0x4575, 0x5e66, 0x5e63, 0x3e5d, + 0x5e5f, 0x3437, 0x3d5d, 0x5e60, 0x446d, 0x4f46, 0x3560, 0x365e, + 0x4a5a, 0x3574, 0x5e65, 0x5546, 0x5e61, 0x4c4d, 0x467e, 0x4545, + 0x5234, 0x3e72, 0x4253, 0x4c3d, 0x3338, 0x3d53, 0x3f58, 0x4d46, + 0x515a, 0x346b, 0x5e64, 0x5e5d, 0x5e67, 0x6a7e, 0x4230, 0x5e62, + 0x5640, 0x3527, 0x3274, 0x5e68, 0x5e72, 0x5e6d, 0x5e71, 0x4860, + 0x5761, 0x5e6f, 0x4368, 0x4c61, 0x3265, 0x523e, 0x5e6e, 0x5e6b, + 0x4e55, 0x3427, 0x3f2b, 0x3e3e, 0x3d52, 0x5e69, 0x542e, 0x5e5e, + 0x5e6a, 0x403f, 0x5e6c, 0x3273, 0x3869, 0x4227, 0x3d41, 0x5e75, + 0x5e78, 0x322b, 0x3424, 0x346a, 0x4926, 0x5e76, 0x4b51, 0x3863, + 0x5e77, 0x5e7a, 0x5e79, 0x4c42, 0x3061, 0x346e, 0x653a, 0x502f, + 0x326b, 0x6b21, 0x5e74, 0x4963, 0x5e73, 0x305a, 0x5221, 0x3177, + 0x4c2f, 0x5e70, 0x4b24, 0x552a, 0x5e7b, 0x345d, 0x4426, 0x5e7d, + 0x437e, 0x4421, 0x5f21, 0x414c, 0x5e7c, 0x3e6f, 0x4632, 0x3345, + 0x4876, 0x4b3a, 0x5e7e, 0x5f24, 0x5732, 0x3337, 0x4143, 0x474b, + 0x3225, 0x3469, 0x572b, 0x446c, 0x5f22, 0x5f23, 0x5f25, 0x3a33, + 0x5f26, 0x405e, 0x4943, 0x3259, 0x4766, 0x5f27, 0x475c, 0x5f28, + 0x6b22, 0x4b53, 0x5f2a, 0x5f29, 0x3241, 0x454a, 0x5f2b, 0x545c, + 0x4841, 0x5f2c, 0x3e70, 0x5f2d, 0x5627, 0x6a37, 0x6b36, 0x4a55, + 0x587c, 0x3844, 0x3925, 0x3745, 0x557e, 0x394a, 0x5027, 0x744d, + 0x3550, 0x4374, 0x3e48, 0x6b37, 0x303d, 0x3d4c, 0x4132, 0x3156, + 0x3328, 0x3852, 0x4922, 0x3658, 0x6b38, 0x3e34, 0x4a7d, 0x4743, + 0x557b, 0x3773, 0x4e44, 0x552b, 0x3173, 0x6c33, 0x305f, 0x6c35, + 0x3637, 0x414f, 0x757a, 0x5031, 0x5565, 0x4e53, 0x3d6f, 0x3362, + 0x382b, 0x5536, 0x6d3d, 0x364f, 0x4b39, 0x5042, 0x373d, 0x6c36, + 0x4a29, 0x4554, 0x6c39, 0x6c38, 0x4243, 0x6c37, 0x507d, 0x6c3a, + 0x6c3b, 0x5765, 0x6c3c, 0x6c3d, 0x466c, 0x4e5e, 0x3c48, 0x4855, + 0x3529, 0x3e49, 0x563c, 0x5467, 0x512e, 0x5071, 0x6a38, 0x6a39, + 0x6a3a, 0x3a35, 0x4a31, 0x3f75, 0x4d7a, 0x6a40, 0x303a, 0x6a3e, + 0x4025, 0x6a3b, 0x327d, 0x4377, 0x3b68, 0x5257, 0x4e74, 0x6a3f, + 0x6a3c, 0x6a43, 0x5047, 0x5333, 0x343a, 0x4341, 0x5772, 0x5551, + 0x4a47, 0x6a45, 0x6a44, 0x6a47, 0x6a46, 0x5667, 0x4f54, 0x6a4b, + 0x3b4e, 0x3d7a, 0x494e, 0x6a4c, 0x4939, 0x4f7e, 0x6a4a, 0x544e, + 0x6a4d, 0x6a4f, 0x4d6d, 0x6a49, 0x6a4e, 0x4e6e, 0x3b5e, 0x333f, + 0x4655, 0x3e30, 0x4e7a, 0x4767, 0x3e27, 0x6a50, 0x5647, 0x4140, + 0x545d, 0x6a51, 0x4f3e, 0x6a52, 0x4a6e, 0x452f, 0x3035, 0x6a54, + 0x6a53, 0x745f, 0x443a, 0x3129, 0x655f, 0x6a55, 0x4a6f, 0x6a56, + 0x6a57, 0x4658, 0x6a58, 0x6a59, 0x543b, 0x477a, 0x5237, 0x387c, + 0x6a42, 0x325c, 0x427c, 0x5478, 0x4c66, 0x576e, 0x5442, 0x5350, + 0x6b43, 0x4573, 0x377e, 0x6b54, 0x4b37, 0x6b5e, 0x404a, 0x4d7b, + 0x332f, 0x465a, 0x6b7c, 0x443e, 0x4e34, 0x4429, 0x313e, 0x547d, + 0x4a75, 0x566c, 0x4653, 0x3664, 0x3b7a, 0x5060, 0x4931, 0x5453, + 0x4828, 0x384b, 0x683e, 0x493c, 0x683b, 0x406e, 0x5053, 0x3244, + 0x3465, 0x683c, 0x5548, 0x3645, 0x683d, 0x4a78, 0x385c, 0x4c75, + 0x4034, 0x516e, 0x683f, 0x6842, 0x3a3c, 0x312d, 0x3d5c, 0x6a3d, + 0x6843, 0x6846, 0x684b, 0x684c, 0x4b49, 0x3065, 0x3c2b, 0x3939, + 0x6841, 0x4d77, 0x684a, 0x4e76, 0x556d, 0x4156, 0x6844, 0x4336, + 0x397b, 0x5626, 0x6848, 0x4a60, 0x5466, 0x6840, 0x6845, 0x6847, + 0x4739, 0x3763, 0x6849, 0x3f5d, 0x6852, 0x6857, 0x6855, 0x3c5c, + 0x3c4f, 0x685b, 0x685e, 0x685a, 0x317a, 0x3058, 0x4433, 0x384c, + 0x4662, 0x483e, 0x4861, 0x684f, 0x6854, 0x6856, 0x3971, 0x6858, + 0x5775, 0x447b, 0x685c, 0x3269, 0x6851, 0x3c6d, 0x3f42, 0x684d, + 0x5679, 0x4178, 0x3271, 0x685f, 0x4a41, 0x6859, 0x5524, 0x316a, + 0x553b, 0x684e, 0x6850, 0x3630, 0x6853, 0x685d, 0x4038, 0x4a77, + 0x4b28, 0x465c, 0x4075, 0x6869, 0x5023, 0x6872, 0x566a, 0x6860, + 0x6861, 0x5179, 0x3a4b, 0x3879, 0x3871, 0x5454, 0x686f, 0x686e, + 0x686c, 0x3970, 0x4c52, 0x6866, 0x4e26, 0x3f72, 0x3038, 0x6871, + 0x6870, 0x5740, 0x6864, 0x4d29, 0x4923, 0x3b38, 0x3d5b, 0x686a, + 0x6862, 0x6863, 0x6865, 0x3535, 0x6867, 0x4745, 0x686b, 0x686d, + 0x3d30, 0x572e, 0x6878, 0x6875, 0x4d30, 0x6876, 0x413a, 0x6868, + 0x4337, 0x3070, 0x6874, 0x6877, 0x3923, 0x4952, 0x434e, 0x4e60, + 0x4066, 0x4b73, 0x4c5d, 0x5035, 0x4a61, 0x6873, 0x3c6c, 0x6879, + 0x435e, 0x4665, 0x3977, 0x3074, 0x5758, 0x3c2c, 0x456f, 0x4c44, + 0x6926, 0x492d, 0x6922, 0x4062, 0x3f43, 0x687e, 0x3957, 0x687b, + 0x6924, 0x524e, 0x6923, 0x5632, 0x5735, 0x6927, 0x3d37, 0x687c, + 0x687d, 0x6921, 0x4d56, 0x522c, 0x6932, 0x6929, 0x342a, 0x343b, + 0x692b, 0x5028, 0x6925, 0x337e, 0x692c, 0x4063, 0x692a, 0x6939, + 0x6938, 0x692e, 0x687a, 0x6928, 0x3f2c, 0x6931, 0x693a, 0x4225, + 0x692f, 0x3845, 0x692d, 0x535c, 0x6934, 0x6935, 0x6937, 0x6947, + 0x4046, 0x6945, 0x6930, 0x693b, 0x3071, 0x693c, 0x5525, 0x693e, + 0x693f, 0x6941, 0x4171, 0x4836, 0x693d, 0x6942, 0x6943, 0x6933, + 0x6936, 0x3b31, 0x6940, 0x3c77, 0x6944, 0x6946, 0x694a, 0x694e, + 0x325b, 0x6948, 0x372e, 0x694b, 0x694c, 0x5541, 0x4423, 0x6958, + 0x3a61, 0x6949, 0x5323, 0x6954, 0x6957, 0x6950, 0x694f, 0x4741, + 0x6952, 0x6959, 0x3348, 0x6953, 0x4f70, 0x694d, 0x3377, 0x6956, + 0x695a, 0x4c34, 0x4f2d, 0x6955, 0x695c, 0x695b, 0x695e, 0x6951, + 0x695d, 0x695f, 0x434a, 0x4737, 0x344e, 0x3b36, 0x5040, 0x6c23, + 0x4537, 0x537b, 0x6c24, 0x6c25, 0x465b, 0x3f6e, 0x6c26, 0x6c27, + 0x502a, 0x4738, 0x3868, 0x6c28, 0x5639, 0x557d, 0x344b, 0x323d, + 0x4e64, 0x4667, 0x4d61, 0x3475, 0x4b40, 0x3c5f, 0x6962, 0x6963, + 0x516a, 0x6965, 0x3479, 0x6964, 0x5133, 0x4a62, 0x3250, 0x6968, + 0x6966, 0x6967, 0x5633, 0x6969, 0x696a, 0x696b, 0x696c, 0x6c2f, + 0x4539, 0x364e, 0x5273, 0x356e, 0x3b59, 0x6c31, 0x5263, 0x4e63, + 0x4438, 0x433f, 0x363e, 0x5839, 0x3148, 0x314f, 0x3151, 0x457e, + 0x3150, 0x432b, 0x5531, 0x6b24, 0x3a41, 0x4c3a, 0x6b25, 0x6b27, + 0x6b28, 0x6b26, 0x6b29, 0x6b2b, 0x6b2a, 0x6b2c, 0x4a4f, 0x5835, + 0x4371, 0x4325, 0x4678, 0x6b2d, 0x444a, 0x6b2e, 0x6b2f, 0x6b30, + 0x3755, 0x377a, 0x6b31, 0x4762, 0x6b33, 0x3a24, 0x5175, 0x3031, + 0x6b32, 0x6b34, 0x352a, 0x4248, 0x4768, 0x6b35, 0x4b2e, 0x635f, + 0x5340, 0x595b, 0x4d21, 0x562d, 0x4773, 0x5960, 0x3b63, 0x3a3a, + 0x6362, 0x4f2b, 0x6360, 0x4947, 0x3a39, 0x5134, 0x6361, 0x486a, + 0x392f, 0x3d2d, 0x3358, 0x4e5b, 0x4c40, 0x6368, 0x6369, 0x4d74, + 0x4c2d, 0x3c33, 0x636a, 0x636b, 0x505a, 0x467b, 0x375a, 0x475f, + 0x524a, 0x4e56, 0x6364, 0x636c, 0x4972, 0x3341, 0x6367, 0x4663, + 0x6365, 0x6d33, 0x6366, 0x4933, 0x4566, 0x3935, 0x433b, 0x6363, + 0x453d, 0x4124, 0x4259, 0x3257, 0x636d, 0x3b26, 0x442d, 0x6370, + 0x3e5a, 0x637b, 0x6375, 0x3a53, 0x3750, 0x534d, 0x564e, 0x5553, + 0x3941, 0x5534, 0x5158, 0x5039, 0x4776, 0x482a, 0x3234, 0x435a, + 0x636e, 0x637c, 0x636f, 0x3728, 0x6377, 0x6374, 0x373a, 0x4522, + 0x6376, 0x455d, 0x3228, 0x467c, 0x4460, 0x5722, 0x4061, 0x6379, + 0x637a, 0x637d, 0x4c29, 0x6373, 0x533e, 0x3143, 0x6d34, 0x6371, + 0x6372, 0x6378, 0x503a, 0x4643, 0x5473, 0x637e, 0x3d60, 0x6427, + 0x6426, 0x5173, 0x6423, 0x6429, 0x4877, 0x4f34, 0x6428, 0x642e, + 0x4265, 0x3634, 0x3d72, 0x6422, 0x3a69, 0x642a, 0x642c, 0x367d, + 0x565e, 0x6432, 0x642d, 0x6421, 0x3b6e, 0x4d5d, 0x4722, 0x4549, + 0x4177, 0x6424, 0x4733, 0x3d2c, 0x3d3d, 0x6425, 0x5747, 0x3262, + 0x642b, 0x3c43, 0x642f, 0x3b6b, 0x6430, 0x4528, 0x6431, 0x5563, + 0x3f23, 0x643a, 0x6437, 0x643b, 0x643d, 0x4656, 0x3a46, 0x404b, + 0x3821, 0x6434, 0x5421, 0x3a23, 0x3d7e, 0x643c, 0x4d3f, 0x4479, + 0x4f7b, 0x4966, 0x533f, 0x4f51, 0x6433, 0x6438, 0x6439, 0x4c69, + 0x4c4e, 0x4054, 0x6435, 0x4130, 0x6436, 0x4e50, 0x3b41, 0x3553, + 0x4873, 0x3d27, 0x5547, 0x492c, 0x3822, 0x644a, 0x644c, 0x5144, + 0x523a, 0x3a2d, 0x3a54, 0x6443, 0x356d, 0x574d, 0x6440, 0x4f7d, + 0x643f, 0x415c, 0x4c4a, 0x4a67, 0x4457, 0x4c54, 0x6448, 0x6447, + 0x6441, 0x6444, 0x352d, 0x5359, 0x6446, 0x5279, 0x3463, 0x3b34, + 0x496e, 0x343e, 0x3b6c, 0x514d, 0x4c6d, 0x6d35, 0x4765, 0x5428, + 0x644b, 0x5755, 0x6442, 0x3d25, 0x6445, 0x5366, 0x6449, 0x4978, + 0x643e, 0x5365, 0x477e, 0x3649, 0x547c, 0x3233, 0x6457, 0x4e42, + 0x644d, 0x4e3c, 0x385b, 0x6456, 0x3f4a, 0x534e, 0x436c, 0x4548, + 0x6458, 0x4d44, 0x644f, 0x6454, 0x6455, 0x3a7e, 0x4f66, 0x553f, + 0x6452, 0x6450, 0x644e, 0x4d65, 0x4a2a, 0x4023, 0x3d26, 0x6453, + 0x3848, 0x6467, 0x5434, 0x645b, 0x416f, 0x6469, 0x5267, 0x645f, + 0x6460, 0x4f2a, 0x4b5d, 0x645a, 0x6451, 0x6465, 0x485c, 0x6463, + 0x4467, 0x6462, 0x6461, 0x337c, 0x6468, 0x3561, 0x574c, 0x6466, + 0x3b2c, 0x5752, 0x4c4f, 0x6b78, 0x6464, 0x3976, 0x564d, 0x6459, + 0x645c, 0x427a, 0x645e, 0x424b, 0x4044, 0x4250, 0x3175, 0x4c32, + 0x354e, 0x646f, 0x462f, 0x4661, 0x6475, 0x4229, 0x406c, 0x515d, + 0x646e, 0x442e, 0x646d, 0x6476, 0x6474, 0x427e, 0x645d, 0x6470, + 0x4a7e, 0x5544, 0x6471, 0x517a, 0x646b, 0x646c, 0x6472, 0x4e2b, + 0x454b, 0x4731, 0x423a, 0x646a, 0x414a, 0x4c36, 0x3331, 0x647b, + 0x6473, 0x647a, 0x647d, 0x647c, 0x334e, 0x333a, 0x6477, 0x6479, + 0x6478, 0x456c, 0x403d, 0x5468, 0x6522, 0x3044, 0x6524, 0x6523, + 0x3c24, 0x6525, 0x6521, 0x647e, 0x3174, 0x6528, 0x6529, 0x6526, + 0x6527, 0x652a, 0x4659, 0x652b, 0x652d, 0x652c, 0x652f, 0x652e, + 0x3960, 0x6530, 0x6531, 0x3b70, 0x6c61, 0x4370, 0x3546, 0x3b52, + 0x4169, 0x546e, 0x3e44, 0x5746, 0x5456, 0x3253, 0x6c3e, 0x6a41, + 0x422f, 0x3436, 0x5157, 0x3334, 0x4832, 0x3f3b, 0x6c40, 0x564b, + 0x6c3f, 0x6c41, 0x6c45, 0x3e66, 0x4c3f, 0x455a, 0x3e3c, 0x6c46, + 0x317e, 0x6c44, 0x5528, 0x3563, 0x6c42, 0x4136, 0x3363, 0x6c43, + 0x4b38, 0x4043, 0x4c7e, 0x4152, 0x6c48, 0x3a66, 0x4053, 0x5672, + 0x514c, 0x3f3e, 0x3733, 0x4955, 0x6c47, 0x3b62, 0x4c4c, 0x3d7d, + 0x4848, 0x4f29, 0x4d69, 0x456b, 0x3769, 0x5149, 0x3a38, 0x6c49, + 0x6c4a, 0x3b40, 0x6c4b, 0x6c62, 0x313a, 0x3759, 0x3d39, 0x6c4c, + 0x5166, 0x6c4d, 0x483b, 0x6c51, 0x6c53, 0x3b4d, 0x3c65, 0x6c4f, + 0x4937, 0x433a, 0x6c63, 0x5555, 0x6c50, 0x5673, 0x6c52, 0x6c4e, + 0x6c54, 0x6c55, 0x493f, 0x4f28, 0x505c, 0x512c, 0x485b, 0x6c56, + 0x4e75, 0x4a6c, 0x6c5a, 0x6c59, 0x303e, 0x6c57, 0x6c58, 0x6c64, + 0x483c, 0x4147, 0x6c5c, 0x5160, 0x6c5b, 0x546f, 0x6c5d, 0x5b46, + 0x6c5e, 0x312c, 0x6c5f, 0x6c60, 0x5726, 0x4540, 0x6b3c, 0x302e, + 0x3e74, 0x3838, 0x522f, 0x3056, 0x3579, 0x5833, 0x4b2c, 0x635d, + 0x462c, 0x3066, 0x4546, 0x6b39, 0x6b3a, 0x6b3b, 0x5140, 0x4523, + 0x6a72, 0x4432, 0x4435, 0x404e, 0x6a73, 0x4441, 0x4e6f, 0x6a70, + 0x6a74, 0x497c, 0x4723, 0x4c58, 0x4e7e, 0x6a75, 0x6a76, 0x4f2c, + 0x4067, 0x6a77, 0x363f, 0x6a78, 0x6a79, 0x6a7a, 0x6a7b, 0x6a71, + 0x482e, 0x616b, 0x3738, 0x616c, 0x616d, 0x5734, 0x616e, 0x616f, + 0x534c, 0x6171, 0x3f71, 0x6170, 0x3552, 0x3137, 0x6173, 0x6172, + 0x3a7c, 0x6174, 0x3937, 0x3e51, 0x447c, 0x3a5d, 0x3d46, 0x6175, + 0x6177, 0x3640, 0x4f41, 0x4a28, 0x6176, 0x5578, 0x537c, 0x6178, + 0x617c, 0x6179, 0x617a, 0x406a, 0x617e, 0x6221, 0x4047, 0x617b, + 0x617d, 0x6225, 0x4154, 0x6223, 0x6228, 0x327e, 0x6222, 0x434d, + 0x3242, 0x6227, 0x6226, 0x6224, 0x6229, 0x622b, 0x5049, 0x566d, + 0x4328, 0x622c, 0x4f57, 0x622e, 0x3a6f, 0x6960, 0x622d, 0x622a, + 0x3b2b, 0x5433, 0x6230, 0x622f, 0x6961, 0x6231, 0x6232, 0x6233, + 0x4c21, 0x6234, 0x6235, 0x507e, 0x424a, 0x5371, 0x4d75, 0x6760, + 0x6761, 0x3e41, 0x426a, 0x6764, 0x6763, 0x4d66, 0x4335, 0x6762, + 0x3b37, 0x4f56, 0x4161, 0x6769, 0x6768, 0x6774, 0x3223, 0x676a, + 0x6766, 0x676c, 0x676b, 0x493a, 0x5564, 0x6765, 0x3729, 0x6767, + 0x676e, 0x6773, 0x5669, 0x676d, 0x6772, 0x6771, 0x3060, 0x6775, + 0x4772, 0x4045, 0x406d, 0x4170, 0x6770, 0x6776, 0x4b76, 0x6822, + 0x6821, 0x5741, 0x677a, 0x6779, 0x677b, 0x6777, 0x677e, 0x677d, + 0x677c, 0x4155, 0x4759, 0x457d, 0x4543, 0x476d, 0x6823, 0x6826, + 0x6825, 0x6827, 0x3a77, 0x6778, 0x6824, 0x4870, 0x492a, 0x6829, + 0x3965, 0x517e, 0x6828, 0x682a, 0x682d, 0x682e, 0x4127, 0x682f, + 0x6830, 0x682c, 0x6834, 0x682b, 0x6831, 0x6835, 0x6832, 0x6833, + 0x6837, 0x6836, 0x394f, 0x702c, 0x702d, 0x4630, 0x306a, 0x483f, + 0x4d5f, 0x4e4d, 0x6a31, 0x6a32, 0x463f, 0x3449, 0x6a33, 0x5567, + 0x5d79, 0x6a34, 0x6a35, 0x6a36, 0x384a, 0x5f30, 0x4975, 0x4c70, + 0x497a, 0x497b, 0x5343, 0x4b26, 0x3826, 0x702e, 0x3142, 0x6538, + 0x4c6f, 0x5349, 0x3c57, 0x496a, 0x3567, 0x4450, 0x3569, 0x6e2e, + 0x3b2d, 0x675e, 0x6e2f, 0x3329, 0x6e32, 0x6e31, 0x3d67, 0x6e30, + 0x4e37, 0x454f, 0x4174, 0x5b4e, 0x6e33, 0x5073, 0x4254, 0x4668, + 0x372c, 0x6e34, 0x336b, 0x3b7b, 0x6e35, 0x675c, 0x6e36, 0x3d2e, + 0x7162, 0x4a68, 0x5249, 0x705a, 0x705b, 0x705c, 0x4146, 0x386d, + 0x3e4e, 0x705e, 0x4531, 0x705d, 0x5171, 0x7060, 0x304c, 0x3d6a, + 0x525f, 0x705f, 0x342f, 0x3768, 0x7066, 0x7065, 0x4623, 0x7061, + 0x7062, 0x3443, 0x7063, 0x556e, 0x4c5b, 0x3e52, 0x3c32, 0x7068, + 0x7067, 0x7064, 0x3221, 0x5622, 0x5338, 0x3e37, 0x482c, 0x706a, + 0x5177, 0x564c, 0x3a5b, 0x7069, 0x363b, 0x4d34, 0x4626, 0x4121, + 0x706b, 0x706e, 0x706d, 0x7070, 0x706c, 0x3b3e, 0x706f, 0x4c35, + 0x7072, 0x3355, 0x3154, 0x7073, 0x7074, 0x7076, 0x3461, 0x7071, + 0x7077, 0x707a, 0x7078, 0x7075, 0x707d, 0x7079, 0x707c, 0x707e, + 0x7121, 0x4e41, 0x7124, 0x7123, 0x4176, 0x707b, 0x4a5d, 0x3471, + 0x3171, 0x4c31, 0x7126, 0x7127, 0x712c, 0x554e, 0x7129, 0x4833, + 0x7122, 0x712b, 0x7128, 0x7125, 0x712a, 0x3029, 0x712d, 0x712f, + 0x7131, 0x7130, 0x712e, 0x5122, 0x7132, 0x7133, 0x396f, 0x3547, + 0x3057, 0x3059, 0x546d, 0x3544, 0x3d54, 0x3b4a, 0x7027, 0x385e, + 0x7028, 0x3028, 0x7029, 0x4d6e, 0x702a, 0x702b, 0x4624, 0x5665, + 0x7164, 0x7165, 0x4373, 0x535b, 0x5651, 0x4568, 0x532f, 0x5266, + 0x6e41, 0x303b, 0x5535, 0x514e, 0x3c60, 0x3a50, 0x3f78, 0x3847, + 0x3541, 0x454c, 0x4a22, 0x434b, 0x6e42, 0x443f, 0x3622, 0x6d6c, + 0x4324, 0x5631, 0x4f60, 0x6d6f, 0x454e, 0x365c, 0x4a21, 0x6d6d, + 0x6d70, 0x6d71, 0x433c, 0x3f34, 0x6d6e, 0x6d74, 0x6d72, 0x5566, + 0x435f, 0x6d73, 0x6d76, 0x5523, 0x5123, 0x6d75, 0x4350, 0x6d77, + 0x3f74, 0x3e6c, 0x6d78, 0x4c77, 0x515b, 0x5745, 0x5576, 0x6d7c, + 0x6d7b, 0x6d79, 0x6d7a, 0x6d7d, 0x3e26, 0x4b2f, 0x6e21, 0x363d, + 0x6e22, 0x4440, 0x6d7e, 0x3d5e, 0x3247, 0x3643, 0x6e25, 0x583a, + 0x6e23, 0x6e26, 0x4369, 0x3372, 0x6e27, 0x6e24, 0x4f39, 0x6e28, + 0x4277, 0x6e29, 0x6e2a, 0x5e2b, 0x4633, 0x4746, 0x5675, 0x3549, + 0x4b32, 0x6e2b, 0x4d2b, 0x6e2c, 0x5530, 0x6e2d, 0x7644, 0x5b47, + 0x3423, 0x432c, 0x7166, 0x4a38, 0x5253, 0x562a, 0x6f72, 0x3e58, + 0x3d43, 0x6f73, 0x364c, 0x302b, 0x4a2f, 0x6d36, 0x6d37, 0x4e79, + 0x372f, 0x3f73, 0x6d38, 0x426b, 0x4930, 0x6d39, 0x4676, 0x3f33, + 0x6d3c, 0x4578, 0x5150, 0x5729, 0x6d3a, 0x6d3b, 0x5162, 0x6d3f, + 0x6d40, 0x6d44, 0x6d48, 0x6d46, 0x6d4e, 0x5568, 0x6d49, 0x6d47, + 0x6d3e, 0x4569, 0x4646, 0x4969, 0x5452, 0x6d41, 0x6d42, 0x6d43, + 0x6d45, 0x4079, 0x3421, 0x3968, 0x6d50, 0x6d51, 0x6d4a, 0x6d4f, + 0x4e78, 0x4b36, 0x6d4c, 0x6d4d, 0x4f75, 0x6d52, 0x4172, 0x5332, + 0x6d4b, 0x4837, 0x3c6f, 0x4570, 0x6d56, 0x356f, 0x4235, 0x302d, + 0x4b69, 0x312e, 0x6d54, 0x4d6b, 0x3562, 0x6d55, 0x6d53, 0x6d57, + 0x357a, 0x6d58, 0x6d59, 0x6d5c, 0x314c, 0x4576, 0x3c6e, 0x6d5a, + 0x4c3c, 0x326a, 0x6d5b, 0x446b, 0x3445, 0x3075, 0x6d5f, 0x405a, + 0x3468, 0x454d, 0x6d5d, 0x3f44, 0x6d5e, 0x4425, 0x6d60, 0x6d61, + 0x6d63, 0x4157, 0x3b47, 0x3d38, 0x6d62, 0x6d64, 0x6d66, 0x6d65, + 0x6d67, 0x4a3e, 0x6c6a, 0x4071, 0x4967, 0x6c6b, 0x466e, 0x6c6c, + 0x466d, 0x6c6d, 0x6c70, 0x5766, 0x6c73, 0x6c71, 0x6c6e, 0x6c6f, + 0x5723, 0x4971, 0x4b6e, 0x6c74, 0x6c72, 0x4f69, 0x6c76, 0x4631, + 0x3c40, 0x6c75, 0x353b, 0x3b76, 0x6c77, 0x5977, 0x3d7b, 0x423b, + 0x6c78, 0x6c79, 0x3823, 0x6c7a, 0x6c7b, 0x6c7c, 0x536d, 0x582e, + 0x406b, 0x475d, 0x3a4c, 0x5063, 0x4b3d, 0x4d3a, 0x3851, 0x317c, + 0x476f, 0x5656, 0x3f46, 0x436b, 0x6f75, 0x4358, 0x5762, 0x6f77, + 0x3353, 0x4758, 0x516d, 0x5648, 0x6f78, 0x6f76, 0x3b7d, 0x3346, + 0x3d55, 0x5246, 0x3b60, 0x4f21, 0x6f7c, 0x6f7b, 0x6f79, 0x334c, + 0x4954, 0x4b30, 0x6f7e, 0x305e, 0x5649, 0x6f7d, 0x336d, 0x7655, + 0x4e48, 0x7022, 0x7021, 0x353e, 0x3c5a, 0x3b7c, 0x3865, 0x4442, + 0x7023, 0x4b6b, 0x7026, 0x5128, 0x3e3f, 0x476e, 0x7136, 0x7137, + 0x3f55, 0x3429, 0x7138, 0x4d3b, 0x4754, 0x552d, 0x7139, 0x713a, + 0x474f, 0x5224, 0x564f, 0x713b, 0x3d51, 0x3430, 0x3e3d, 0x345c, + 0x4e51, 0x3f5f, 0x713d, 0x3f7a, 0x713c, 0x713f, 0x713e, 0x7140, + 0x7141, 0x417e, 0x4122, 0x4a7a, 0x553e, 0x3e3a, 0x3e39, 0x5542, + 0x3f22, 0x4d2f, 0x7135, 0x3d5f, 0x364b, 0x5671, 0x7343, 0x7344, + 0x384d, 0x7346, 0x7347, 0x304a, 0x7345, 0x7349, 0x4b71, 0x734b, + 0x5026, 0x314a, 0x7348, 0x734f, 0x3551, 0x7357, 0x7352, 0x7354, + 0x7353, 0x377b, 0x313f, 0x734e, 0x734a, 0x355a, 0x7350, 0x7351, + 0x7355, 0x734d, 0x3c63, 0x417d, 0x7356, 0x735a, 0x734c, 0x3548, + 0x3d6e, 0x735c, 0x3724, 0x3f70, 0x567e, 0x4d32, 0x3470, 0x325f, + 0x7358, 0x7359, 0x4938, 0x735d, 0x735e, 0x7361, 0x735f, 0x7363, + 0x7362, 0x735b, 0x3f6a, 0x336f, 0x7360, 0x4729, 0x3c72, 0x736b, + 0x393f, 0x7364, 0x322d, 0x3b7e, 0x4b63, 0x736d, 0x7369, 0x395c, + 0x736e, 0x7365, 0x7366, 0x736a, 0x4261, 0x736c, 0x736f, 0x7368, + 0x3c7d, 0x4f64, 0x7370, 0x7367, 0x7372, 0x572d, 0x462a, 0x7373, + 0x7371, 0x4228, 0x385d, 0x7375, 0x7374, 0x345b, 0x7376, 0x7377, + 0x7378, 0x403a, 0x4069, 0x4571, 0x737b, 0x737a, 0x3458, 0x737e, + 0x7379, 0x737c, 0x737d, 0x7421, 0x7423, 0x3b49, 0x7422, 0x7424, + 0x323e, 0x7426, 0x7425, 0x3c2e, 0x4357, 0x5961, 0x4060, 0x744c, + 0x5751, 0x375b, 0x744e, 0x4123, 0x4649, 0x3456, 0x5533, 0x7450, + 0x744f, 0x7451, 0x4b5a, 0x7452, 0x5441, 0x5660, 0x3760, 0x4138, + 0x413b, 0x7453, 0x3e2c, 0x3462, 0x7454, 0x7455, 0x3e2b, 0x7456, + 0x745b, 0x7457, 0x745a, 0x3a7d, 0x7458, 0x7459, 0x3862, 0x4c47, + 0x745c, 0x325a, 0x4353, 0x5463, 0x3f37, 0x745d, 0x4534, 0x7469, + 0x4f35, 0x4e49, 0x4b58, 0x4b77, 0x3d74, 0x574f, 0x405b, 0x5075, + 0x746a, 0x746b, 0x746c, 0x7763, 0x3731, 0x746d, 0x576b, 0x746e, + 0x6679, 0x3e40, 0x667a, 0x3a6c, 0x667b, 0x4f4b, 0x667c, 0x543c, + 0x3c36, 0x667d, 0x667e, 0x3c4d, 0x4852, 0x4e33, 0x6721, 0x343f, + 0x6722, 0x4934, 0x3859, 0x4449, 0x575d, 0x425a, 0x3757, 0x563d, + 0x4e46, 0x3744, 0x4526, 0x6723, 0x4f5f, 0x6724, 0x6725, 0x6726, + 0x4137, 0x5769, 0x4970, 0x4f38, 0x562f, 0x5655, 0x6727, 0x306d, + 0x6728, 0x6729, 0x495c, 0x526f, 0x3e2d, 0x672a, 0x3073, 0x485e, + 0x3d61, 0x672b, 0x4846, 0x672c, 0x3b66, 0x3878, 0x5124, 0x672d, + 0x4267, 0x3e78, 0x3d4a, 0x4d33, 0x672e, 0x672f, 0x3e6e, 0x5065, + 0x4b67, 0x4c50, 0x3c4c, 0x6730, 0x3c28, 0x5077, 0x6731, 0x5078, + 0x6732, 0x6733, 0x3442, 0x6734, 0x6735, 0x497e, 0x4e2c, 0x4360, + 0x6737, 0x3141, 0x3371, 0x6738, 0x6739, 0x575b, 0x5540, 0x673a, + 0x424c, 0x573a, 0x673b, 0x673c, 0x673d, 0x3c6a, 0x4365, 0x4042, + 0x673e, 0x673f, 0x3c29, 0x6740, 0x6741, 0x6736, 0x3650, 0x6742, + 0x6743, 0x6744, 0x3b3a, 0x355e, 0x4246, 0x3160, 0x6745, 0x5435, + 0x6746, 0x383f, 0x6748, 0x6747, 0x376c, 0x6749, 0x3278, 0x674a, + 0x674b, 0x674c, 0x674d, 0x674e, 0x674f, 0x6750, 0x5327, 0x4b75, + 0x6751, 0x6752, 0x6753, 0x6754, 0x4949, 0x6755, 0x6756, 0x6757, + 0x6758, 0x6759, 0x3d49, 0x675a, 0x733e, 0x3857, 0x4831, 0x733f, + 0x7340, 0x7341, 0x395e, 0x4d78, 0x5868, 0x3a31, 0x425e, 0x6e37, + 0x3723, 0x6e39, 0x6e38, 0x3055, 0x6e3b, 0x5556, 0x576f, 0x5643, + 0x6e3d, 0x4a70, 0x6e3c, 0x6e3e, 0x6e40, 0x6e3f, 0x5172, 0x473c, + 0x4340, 0x3861, 0x4167, 0x7446, 0x505f, 0x7447, 0x4f5b, 0x483a, + 0x7448, 0x7449, 0x744a, 0x744b, 0x597a, 0x387e, 0x6571, 0x5370, + 0x7460, 0x4e4c, 0x3361, 0x7134, 0x526e, 0x7461, 0x4f68, 0x7462, + 0x474c, 0x3554, 0x3464, 0x7464, 0x7463, 0x7465, 0x7466, 0x7467, + 0x3a32, 0x303f, 0x7468, 0x372d, 0x526d, 0x522b, 0x404f, 0x3f3c, + 0x6b23, 0x555f, 0x6a48, 0x7173, 0x3678, 0x4b23, 0x444d, 0x7167, + 0x7168, 0x387b, 0x7169, 0x3a44, 0x5445, 0x3052, 0x716a, 0x716b, + 0x716c, 0x716d, 0x716e, 0x716f, 0x7171, 0x7170, 0x4555, 0x7172, + 0x367a, 0x7174, 0x522e, 0x5e47, 0x4b4a, 0x335c, 0x3522, 0x3922, + 0x4474, 0x7175, 0x7176, 0x4144, 0x417b, 0x5630, 0x7177, 0x7178, + 0x412a, 0x4638, 0x3e5b, 0x7179, 0x344f, 0x717a, 0x6d32, 0x6d31, + 0x4b60, 0x525e, 0x4b41, 0x5558, 0x4862, 0x405f, 0x3c21, 0x6b41, + 0x5024, 0x5662, 0x3647, 0x3858, 0x6b40, 0x384e, 0x6b3f, 0x3326, + 0x3949, 0x562b, 0x3774, 0x374a, 0x3c67, 0x373e, 0x6b46, 0x6b47, + 0x3039, 0x3f4f, 0x6b45, 0x537d, 0x6b48, 0x6b49, 0x374e, 0x6b42, + 0x6b44, 0x4976, 0x5657, 0x554d, 0x5032, 0x6b4f, 0x4e38, 0x6b50, + 0x3528, 0x3133, 0x6b52, 0x4c25, 0x4556, 0x6b53, 0x6b51, 0x455f, + 0x6b4e, 0x4a24, 0x6b55, 0x307b, 0x3a7a, 0x5837, 0x7163, 0x6b4a, + 0x6b4b, 0x6b4c, 0x6b4d, 0x6b56, 0x6640, 0x6b59, 0x3f68, 0x5248, + 0x6b57, 0x6b5c, 0x386c, 0x6b58, 0x3d3a, 0x5058, 0x3037, 0x6b5d, + 0x445c, 0x562c, 0x3460, 0x4276, 0x3c39, 0x6b5a, 0x6b5b, 0x5460, + 0x466a, 0x4454, 0x6b5f, 0x4527, 0x5975, 0x3231, 0x6b64, 0x3d45, + 0x6b62, 0x6b63, 0x382c, 0x4d51, 0x6b65, 0x6b61, 0x4133, 0x4622, + 0x4c73, 0x6b66, 0x4030, 0x5238, 0x6b67, 0x382f, 0x382d, 0x6b68, + 0x473b, 0x4d73, 0x6b6a, 0x6b6b, 0x6b6d, 0x5048, 0x6b72, 0x6b6e, + 0x6b71, 0x4879, 0x517c, 0x6b6c, 0x6b69, 0x3839, 0x4f59, 0x4465, + 0x6b6f, 0x6b70, 0x4c5a, 0x4d48, 0x3072, 0x6b76, 0x6b75, 0x3232, + 0x3860, 0x6b77, 0x316c, 0x4c45, 0x4424, 0x4f25, 0x6b79, 0x6c22, + 0x4572, 0x6b7a, 0x4945, 0x625f, 0x6b7e, 0x4d4e, 0x6c21, 0x315b, + 0x5337, 0x525c, 0x6b7d, 0x6b7b, 0x333c, 0x6a30, 0x5754, 0x742b, + 0x3374, 0x5641, 0x5642, 0x5569, 0x3e4a, 0x7427, 0x5228, 0x7428, + 0x7429, 0x742a, 0x3e4b, 0x535f, 0x4960, 0x4961, 0x7342, 0x4a66, + 0x4c72, 0x6236, 0x4b34, 0x4e68, 0x565b, 0x742d, 0x742e, 0x742f, + 0x7432, 0x3a3d, 0x7433, 0x3063, 0x7430, 0x7431, 0x3d22, 0x3255, + 0x7436, 0x7437, 0x3666, 0x3230, 0x4f4f, 0x7434, 0x342c, 0x7435, + 0x7438, 0x7439, 0x4d27, 0x743a, 0x743b, 0x743c, 0x4b52, 0x743d, + 0x743e, 0x743f, 0x745e, 0x413c, 0x3c68, 0x492b, 0x515e, 0x6575, + 0x5c33, 0x5255, 0x5c34, 0x302c, 0x5c35, 0x3d5a, 0x5c39, 0x5842, + 0x5c37, 0x5373, 0x4956, 0x5c3a, 0x5c36, 0x5c3b, 0x4322, 0x5c3c, + 0x5c45, 0x5c3d, 0x4e5f, 0x5625, 0x5c4f, 0x5c4d, 0x5c52, 0x3d66, + 0x422b, 0x5c38, 0x5c4b, 0x5c4e, 0x5c3e, 0x3752, 0x3045, 0x5c47, + 0x503e, 0x5c41, 0x3b28, 0x373c, 0x5c4c, 0x5c46, 0x5c3f, 0x475b, + 0x513f, 0x5c40, 0x5c4a, 0x5c50, 0x4e2d, 0x5c42, 0x5c43, 0x5c48, + 0x5c49, 0x3254, 0x5c51, 0x4b55, 0x5437, 0x5c5b, 0x5c5f, 0x4c26, + 0x5c66, 0x4367, 0x5c5c, 0x3f41, 0x5c59, 0x307a, 0x3936, 0x5c65, + 0x5c53, 0x5c44, 0x5c56, 0x4874, 0x3f60, 0x493b, 0x313d, 0x5322, + 0x5c5a, 0x5c55, 0x463b, 0x5c5e, 0x5742, 0x432f, 0x3736, 0x4751, + 0x4329, 0x5c62, 0x5c58, 0x5c6b, 0x5c54, 0x5c5d, 0x3e25, 0x5c57, + 0x5c60, 0x5c63, 0x5c64, 0x5c78, 0x5c61, 0x5d22, 0x5c67, 0x3c6b, + 0x3444, 0x4323, 0x3267, 0x5c7a, 0x5c72, 0x5c6f, 0x5c7c, 0x5c6e, + 0x5270, 0x3268, 0x4857, 0x4863, 0x5c7b, 0x5c6d, 0x5c77, 0x5c75, + 0x3e23, 0x5c74, 0x325d, 0x5c73, 0x3c76, 0x5c68, 0x3b44, 0x4073, + 0x3c54, 0x5c69, 0x5c6a, 0x5c71, 0x5c76, 0x5c79, 0x3534, 0x4859, + 0x3b67, 0x5c7e, 0x5c7d, 0x532b, 0x5d21, 0x5d23, 0x5d25, 0x5271, + 0x5d24, 0x5d26, 0x5d27, 0x5229, 0x3a49, 0x5d29, 0x5d36, 0x5d31, + 0x5d34, 0x5d30, 0x464e, 0x4072, 0x492f, 0x5c6c, 0x5d2e, 0x5d37, + 0x5c70, 0x5d2f, 0x5d38, 0x5d2c, 0x5d39, 0x5d33, 0x5d2d, 0x442a, + 0x5d28, 0x4033, 0x412b, 0x5d2a, 0x5d2b, 0x5d32, 0x3b71, 0x5d35, + 0x5328, 0x5d3a, 0x5d3b, 0x4327, 0x5d52, 0x5d3c, 0x5d51, 0x393d, + 0x3e55, 0x3e7a, 0x3a4a, 0x5d4a, 0x5d45, 0x5d3f, 0x324b, 0x5d43, + 0x5d4b, 0x3224, 0x5d55, 0x5d3e, 0x4650, 0x5d50, 0x5d54, 0x4162, + 0x3746, 0x5d4e, 0x5d4f, 0x5d44, 0x5d3d, 0x5d4d, 0x4c51, 0x5d49, + 0x5d42, 0x4348, 0x463c, 0x4e2e, 0x5d4c, 0x5d48, 0x5d41, 0x5d46, + 0x425c, 0x5329, 0x532a, 0x5d53, 0x4f74, 0x4878, 0x5d66, 0x5d47, + 0x5d60, 0x4264, 0x5d61, 0x5d57, 0x5678, 0x5d59, 0x5d58, 0x3870, + 0x5d56, 0x464f, 0x362d, 0x5d62, 0x3a79, 0x5461, 0x5d67, 0x3450, + 0x5d5a, 0x3f7b, 0x5d63, 0x5d5f, 0x5d5d, 0x3559, 0x5d5b, 0x5d5c, + 0x5d5e, 0x3d2f, 0x5d64, 0x5d65, 0x5d75, 0x4349, 0x4b62, 0x5d72, + 0x5861, 0x4651, 0x5d74, 0x5574, 0x5d73, 0x5d70, 0x5d6c, 0x5d6f, + 0x5d68, 0x506e, 0x4858, 0x5d6e, 0x5d69, 0x5d6a, 0x4b72, 0x5d6d, + 0x314d, 0x4036, 0x3c3b, 0x5d71, 0x5d77, 0x5d76, 0x5d6b, 0x456e, + 0x5d7b, 0x5e24, 0x5e23, 0x5d78, 0x436f, 0x427b, 0x5561, 0x4e35, + 0x5d7d, 0x324c, 0x4468, 0x4a5f, 0x473e, 0x5d7a, 0x5d7c, 0x5d7e, + 0x5e22, 0x302a, 0x314e, 0x5e2c, 0x5e26, 0x3d36, 0x486f, 0x5e21, + 0x5e25, 0x5e29, 0x5e28, 0x5e27, 0x5e2d, 0x544c, 0x5e33, 0x5e2a, + 0x5e2e, 0x4059, 0x3121, 0x5e36, 0x5e31, 0x5e32, 0x5126, 0x5e35, + 0x5e2f, 0x5e30, 0x503d, 0x5e34, 0x4a6d, 0x5e39, 0x5e38, 0x5e37, + 0x5e3b, 0x3d65, 0x3258, 0x436a, 0x5e3a, 0x453a, 0x5e3c, 0x4c59, + 0x372a, 0x5465, 0x5e3d, 0x5e3f, 0x4422, 0x5e41, 0x5e3e, 0x5e40, + 0x553a, 0x5e42, 0x722e, 0x3b22, 0x4232, 0x4530, 0x4247, 0x722f, + 0x5069, 0x535d, 0x6b3d, 0x3366, 0x7230, 0x7231, 0x4a2d, 0x3a67, + 0x7233, 0x7235, 0x7234, 0x4b64, 0x4f3a, 0x7232, 0x4a34, 0x524f, + 0x426c, 0x4e43, 0x7238, 0x3076, 0x7237, 0x723e, 0x324f, 0x5141, + 0x723a, 0x723c, 0x5469, 0x723b, 0x7236, 0x723f, 0x723d, 0x7239, + 0x7247, 0x7244, 0x7246, 0x724a, 0x7242, 0x7240, 0x7245, 0x567b, + 0x7241, 0x4779, 0x495f, 0x7248, 0x3946, 0x3530, 0x7243, 0x7249, + 0x7250, 0x7256, 0x3b57, 0x7255, 0x4d5c, 0x566b, 0x7252, 0x7254, + 0x3872, 0x724b, 0x724e, 0x4279, 0x555d, 0x724c, 0x724d, 0x724f, + 0x7253, 0x7259, 0x533c, 0x366a, 0x4a71, 0x3764, 0x7257, 0x7258, + 0x725a, 0x725d, 0x725b, 0x725c, 0x5151, 0x7251, 0x4d49, 0x4e4f, + 0x5629, 0x7263, 0x435b, 0x7260, 0x402f, 0x726c, 0x725e, 0x7261, + 0x7268, 0x7262, 0x7267, 0x7266, 0x7269, 0x725f, 0x7264, 0x726a, + 0x532c, 0x7265, 0x3275, 0x7272, 0x502b, 0x7275, 0x3b48, 0x7279, + 0x7270, 0x7276, 0x7278, 0x727a, 0x7273, 0x7271, 0x3a7b, 0x357b, + 0x726f, 0x7277, 0x726d, 0x726e, 0x726b, 0x7326, 0x7323, 0x7322, + 0x7274, 0x485a, 0x727b, 0x7325, 0x4378, 0x727d, 0x7327, 0x7329, + 0x7324, 0x727c, 0x732b, 0x732a, 0x425d, 0x732e, 0x7330, 0x7321, + 0x7331, 0x732c, 0x732f, 0x727e, 0x732d, 0x7332, 0x7334, 0x7328, + 0x7333, 0x7335, 0x5037, 0x7338, 0x5979, 0x7339, 0x7337, 0x4864, + 0x7336, 0x733a, 0x733b, 0x3440, 0x6e43, 0x733c, 0x733d, 0x512a, + 0x742c, 0x5046, 0x5050, 0x515c, 0x4f4e, 0x3d56, 0x5143, 0x3a62, + 0x6169, 0x5242, 0x7142, 0x3239, 0x316d, 0x7143, 0x4940, 0x3344, + 0x5972, 0x4b25, 0x7144, 0x5654, 0x7145, 0x7440, 0x7146, 0x542c, + 0x7147, 0x3040, 0x7441, 0x7442, 0x347c, 0x455b, 0x4c3b, 0x5064, + 0x4d60, 0x7148, 0x5973, 0x313b, 0x4f2e, 0x3824, 0x714a, 0x714b, + 0x3243, 0x4151, 0x5730, 0x7149, 0x714c, 0x714e, 0x5976, 0x5261, + 0x5423, 0x7443, 0x4839, 0x7444, 0x714d, 0x714f, 0x3f63, 0x7150, + 0x7154, 0x7156, 0x7151, 0x4951, 0x4561, 0x4263, 0x397c, 0x7153, + 0x7155, 0x3953, 0x715b, 0x3a56, 0x307d, 0x7159, 0x7158, 0x7152, + 0x715a, 0x7157, 0x486c, 0x4d4a, 0x715d, 0x653d, 0x715c, 0x715e, + 0x715f, 0x4f65, 0x7445, 0x3d73, 0x7160, 0x7161, 0x4e77, 0x522a, + 0x717b, 0x3832, 0x3c7b, 0x395b, 0x3966, 0x4359, 0x4a53, 0x6a68, + 0x4040, 0x3e75, 0x6a69, 0x6a6a, 0x6a6b, 0x6a6c, 0x6a6d, 0x6a6e, + 0x6a6f, 0x3d47, 0x757b, 0x757d, 0x757e, 0x757c, 0x3d62, 0x7621, + 0x3425, 0x7622, 0x7623, 0x6c32, 0x5154, 0x596a, 0x7624, 0x6e3a, + 0x5532, 0x537e, 0x4c5c, 0x4a44, 0x6540, 0x7625, 0x3e2f, 0x4629, + 0x5a25, 0x3c46, 0x3629, 0x383c, 0x484f, 0x3c25, 0x5a26, 0x5a27, + 0x4c56, 0x4843, 0x5a28, 0x467d, 0x5135, 0x5269, 0x5136, 0x3c47, + 0x3d32, 0x3b64, 0x5a29, 0x5a2a, 0x5148, 0x5a2b, 0x506d, 0x366f, + 0x425b, 0x4b4f, 0x376d, 0x4968, 0x3743, 0x3e77, 0x5624, 0x5a2c, + 0x5a2d, 0x4640, 0x5767, 0x4a36, 0x5529, 0x4b5f, 0x556f, 0x5a2e, + 0x565f, 0x344a, 0x5a30, 0x5a2f, 0x526b, 0x5a31, 0x5a32, 0x5a33, + 0x4a54, 0x5a34, 0x4a2b, 0x5a35, 0x5a36, 0x334f, 0x566f, 0x5a37, + 0x3b30, 0x352e, 0x5a38, 0x5a39, 0x396e, 0x512f, 0x5268, 0x5a3a, + 0x3843, 0x4f6a, 0x326f, 0x5a3b, 0x5a3c, 0x3d6b, 0x4e5c, 0x536f, + 0x5a3d, 0x4e73, 0x5a3e, 0x5355, 0x3b65, 0x5a3f, 0x4b35, 0x4b50, + 0x5a40, 0x476b, 0x566e, 0x5a41, 0x4535, 0x3641, 0x5a42, 0x374c, + 0x3f4e, 0x5a43, 0x5a44, 0x4b2d, 0x5a45, 0x3577, 0x5a46, 0x4142, + 0x573b, 0x5a47, 0x4c38, 0x526a, 0x4431, 0x5a48, 0x357d, 0x3b51, + 0x5a49, 0x5033, 0x5a4a, 0x5a4b, 0x4e3d, 0x5a4c, 0x5a4d, 0x5a4e, + 0x3277, 0x5a51, 0x5a4f, 0x5168, 0x5a50, 0x4355, 0x5a52, 0x5a53, + 0x5a54, 0x5a55, 0x503b, 0x5225, 0x3079, 0x5a56, 0x472b, 0x5a57, + 0x3d77, 0x4321, 0x5a58, 0x5a59, 0x437d, 0x4c37, 0x5a5a, 0x5a5b, + 0x403e, 0x4657, 0x5a5c, 0x5a5d, 0x4734, 0x5a5e, 0x5a5f, 0x3948, + 0x3b6d, 0x3639, 0x7478, 0x7479, 0x4d63, 0x7539, 0x6b60, 0x4f73, + 0x3b3f, 0x3a40, 0x5425, 0x6159, 0x7574, 0x312a, 0x3272, 0x7575, + 0x7577, 0x3a51, 0x7576, 0x4332, 0x7579, 0x7578, 0x3134, 0x556a, + 0x383a, 0x3931, 0x3246, 0x5470, 0x4f4d, 0x305c, 0x554b, 0x3b75, + 0x564a, 0x3737, 0x4c30, 0x4636, 0x3161, 0x393a, 0x567c, 0x3961, + 0x3721, 0x3c7a, 0x6a5a, 0x6a5b, 0x4c79, 0x3973, 0x6a5c, 0x347b, + 0x4333, 0x3751, 0x3a58, 0x6a5d, 0x5474, 0x6a5e, 0x3c56, 0x3b5f, + 0x6a5f, 0x415e, 0x4238, 0x545f, 0x574a, 0x6a60, 0x6a61, 0x6a64, + 0x6a62, 0x6a63, 0x495e, 0x3833, 0x3644, 0x6a65, 0x4a6a, 0x494d, + 0x344d, 0x6259, 0x4562, 0x6a66, 0x4035, 0x5738, 0x6a67, 0x572c, + 0x487c, 0x5853, 0x584d, 0x545e, 0x5479, 0x4944, 0x532e, 0x3853, + 0x3360, 0x4962, 0x7476, 0x3a55, 0x7477, 0x575f, 0x7471, 0x3830, + 0x5554, 0x384f, 0x4670, 0x3343, 0x7472, 0x332c, 0x543d, 0x4777, + 0x7474, 0x7473, 0x4c4b, 0x4824, 0x7475, 0x5763, 0x453f, 0x7540, + 0x753b, 0x7543, 0x7542, 0x563a, 0x7541, 0x543e, 0x7544, 0x754c, + 0x304f, 0x3578, 0x7549, 0x754a, 0x455c, 0x7545, 0x7546, 0x7547, + 0x754b, 0x3e60, 0x7548, 0x387a, 0x7550, 0x7553, 0x3f67, 0x3972, + 0x753c, 0x754d, 0x4237, 0x4c78, 0x3c79, 0x754e, 0x754f, 0x7551, + 0x3665, 0x7552, 0x7555, 0x753d, 0x7554, 0x533b, 0x336c, 0x4c24, + 0x7556, 0x7557, 0x3e61, 0x7558, 0x4c5f, 0x755b, 0x3248, 0x5759, + 0x7559, 0x755a, 0x755c, 0x7562, 0x7560, 0x755f, 0x755d, 0x7561, + 0x755e, 0x7564, 0x7565, 0x4c63, 0x653f, 0x3538, 0x7563, 0x7568, + 0x4c23, 0x7566, 0x7567, 0x753e, 0x3144, 0x753f, 0x3545, 0x3264, + 0x756c, 0x7569, 0x3657, 0x756d, 0x756a, 0x756b, 0x345a, 0x546a, + 0x756e, 0x3379, 0x756f, 0x7571, 0x7570, 0x7572, 0x7573, 0x496d, + 0x392a, 0x477b, 0x3663, 0x4c49, 0x6a26, 0x3335, 0x547e, 0x396c, + 0x5079, 0x696d, 0x572a, 0x696e, 0x4256, 0x486d, 0x3a64, 0x696f, + 0x6970, 0x6971, 0x5661, 0x6972, 0x6973, 0x6975, 0x6974, 0x6976, + 0x6977, 0x4761, 0x6978, 0x5458, 0x6979, 0x3d4e, 0x697a, 0x697b, + 0x3d4f, 0x697c, 0x3828, 0x413e, 0x697d, 0x3132, 0x3b54, 0x3975, + 0x697e, 0x6a21, 0x6a22, 0x6a23, 0x3778, 0x3c2d, 0x4a64, 0x604e, + 0x542f, 0x4f3d, 0x5537, 0x6a24, 0x555e, 0x6a25, 0x5041, 0x393c, + 0x3447, 0x3159, 0x4031, 0x3166, 0x3167, 0x3168, 0x333d, 0x4868, + 0x6541, 0x315f, 0x4149, 0x346f, 0x4728, 0x5358, 0x4679, 0x5138, + 0x397d, 0x4275, 0x532d, 0x544b, 0x3d7c, 0x6542, 0x3735, 0x6543, + 0x3b39, 0x5562, 0x3d78, 0x5436, 0x4e25, 0x412c, 0x3359, 0x4c76, + 0x6546, 0x6544, 0x6548, 0x654a, 0x6547, 0x354f, 0x4648, 0x357c, + 0x6545, 0x4a76, 0x6549, 0x4354, 0x3145, 0x3c23, 0x5737, 0x4d4b, + 0x4b4d, 0x4a4a, 0x4c53, 0x654c, 0x654b, 0x4466, 0x5121, 0x5137, + 0x654d, 0x6550, 0x4d38, 0x5670, 0x654f, 0x355d, 0x4d3e, 0x6551, + 0x363a, 0x4d28, 0x3964, 0x4a45, 0x3351, 0x4b59, 0x546c, 0x6552, + 0x376a, 0x654e, 0x6555, 0x347e, 0x6556, 0x6553, 0x6554, 0x525d, + 0x425f, 0x3146, 0x5362, 0x365d, 0x4b6c, 0x6557, 0x5376, 0x3169, + 0x3674, 0x655a, 0x6558, 0x6559, 0x3540, 0x5245, 0x655c, 0x655e, + 0x655d, 0x4732, 0x5223, 0x655b, 0x5462, 0x555a, 0x6560, 0x5771, + 0x6561, 0x315c, 0x517b, 0x6562, 0x6564, 0x6563, 0x6565, 0x5258, + 0x354b, 0x675f, 0x5a75, 0x5a78, 0x5a76, 0x5a77, 0x5a7a, 0x504f, + 0x4447, 0x306e, 0x5030, 0x5a79, 0x534a, 0x3a2a, 0x5b22, 0x4771, + 0x5a7c, 0x5a7b, 0x495b, 0x5a7d, 0x5b21, 0x575e, 0x5a7e, 0x415a, + 0x5b25, 0x5374, 0x5b27, 0x5b24, 0x5b28, 0x3d3c, 0x4049, 0x5b23, + 0x5b26, 0x5623, 0x5b29, 0x5b2d, 0x5b2e, 0x5b2c, 0x3a42, 0x3f24, + 0x5b2b, 0x5b2a, 0x5447, 0x323f, 0x5b2f, 0x3979, 0x5b30, 0x333b, + 0x3526, 0x363c, 0x5b31, 0x3675, 0x5b32, 0x3149, 0x5b34, 0x5b33, + 0x5b35, 0x5b37, 0x5b36, 0x5b38, 0x5b39, 0x5b3a, 0x534f, 0x747a, + 0x4775, 0x5743, 0x4564, 0x747c, 0x747d, 0x747b, 0x3e46, 0x506f, + 0x3753, 0x544d, 0x4c2a, 0x7522, 0x7521, 0x3a28, 0x747e, 0x4b56, + 0x7524, 0x4052, 0x336a, 0x4d2a, 0x7525, 0x7523, 0x3d34, 0x7528, + 0x7529, 0x3d4d, 0x4338, 0x3f61, 0x4b61, 0x752a, 0x7526, 0x7527, + 0x4470, 0x752c, 0x343c, 0x576d, 0x3457, 0x752b, 0x752e, 0x752d, + 0x752f, 0x5051, 0x4351, 0x4829, 0x7530, 0x7531, 0x7532, 0x7533, + 0x7534, 0x7535, 0x7537, 0x7536, 0x7538, 0x3249, 0x5354, 0x4a4d, + 0x406f, 0x5658, 0x5230, 0x413f, 0x3d70, 0x382a, 0x3c78, 0x7646, + 0x7647, 0x7648, 0x7649, 0x764a, 0x764c, 0x764b, 0x7769, 0x764d, + 0x764e, 0x6e44, 0x6e45, 0x6e46, 0x556b, 0x3624, 0x6e48, 0x6e47, + 0x6e49, 0x6e4a, 0x4725, 0x6e4b, 0x6e4c, 0x3730, 0x3576, 0x6e4d, + 0x6e4f, 0x6e4e, 0x3846, 0x6e50, 0x6e51, 0x6e52, 0x365b, 0x332e, + 0x5653, 0x4446, 0x3135, 0x3856, 0x6e53, 0x6e54, 0x543f, 0x4755, + 0x3e7b, 0x4e59, 0x3933, 0x6e56, 0x6e55, 0x6e58, 0x6e57, 0x4525, + 0x6e59, 0x6e5a, 0x472e, 0x6e5b, 0x472f, 0x6e5c, 0x3227, 0x6e5d, + 0x6e5e, 0x6e5f, 0x6e60, 0x6e61, 0x576a, 0x6e62, 0x6e63, 0x3c58, + 0x6e64, 0x534b, 0x4c7a, 0x322c, 0x4165, 0x6e65, 0x4726, 0x432d, + 0x6e66, 0x6e67, 0x6e68, 0x6e69, 0x6e6a, 0x6e6b, 0x6e6c, 0x6e6d, + 0x6e6e, 0x6e6f, 0x6e70, 0x6e71, 0x6e72, 0x6e74, 0x6e73, 0x6e75, + 0x4d2d, 0x4241, 0x6e76, 0x6e77, 0x6e78, 0x5521, 0x6e79, 0x4f33, + 0x6e7a, 0x6e7b, 0x6e7c, 0x6e7d, 0x6f21, 0x6e7e, 0x6f22, 0x3875, + 0x437a, 0x6f23, 0x6f24, 0x3d42, 0x523f, 0x3279, 0x6f25, 0x6f26, + 0x6f27, 0x5278, 0x6f28, 0x567d, 0x6f29, 0x464c, 0x6f2a, 0x6f2b, + 0x4134, 0x6f2c, 0x4f7a, 0x4b78, 0x6f2e, 0x6f2d, 0x337a, 0x3978, + 0x6f2f, 0x6f30, 0x5062, 0x6f31, 0x6f32, 0x3766, 0x503f, 0x6f33, + 0x6f34, 0x6f35, 0x4871, 0x4c60, 0x6f36, 0x6f37, 0x6f38, 0x6f39, + 0x6f3a, 0x5560, 0x6f3b, 0x346d, 0x432a, 0x6f3c, 0x6f3d, 0x6f3e, + 0x6f3f, 0x4e7d, 0x6f40, 0x4260, 0x3438, 0x5736, 0x3d75, 0x4f47, + 0x6f43, 0x6f41, 0x6f42, 0x6f44, 0x3627, 0x3c7c, 0x3e62, 0x434c, + 0x6f45, 0x6f46, 0x6f47, 0x6f4f, 0x6f48, 0x6f49, 0x6f4a, 0x4742, + 0x6f71, 0x364d, 0x6f4b, 0x6f4c, 0x6f4d, 0x3646, 0x433e, 0x6f4e, + 0x6f50, 0x6f51, 0x6f52, 0x5572, 0x6f53, 0x4477, 0x6f54, 0x4478, + 0x6f55, 0x6f56, 0x3864, 0x3077, 0x6f57, 0x6f58, 0x6f59, 0x6f5a, + 0x6f5b, 0x6f5c, 0x6f5d, 0x6f5e, 0x3e35, 0x6f61, 0x6f5f, 0x6f60, + 0x6f62, 0x6f63, 0x414d, 0x6f64, 0x6f65, 0x6f66, 0x6f67, 0x6f68, + 0x6f69, 0x6f6a, 0x6f6b, 0x6f6c, 0x4058, 0x6f6d, 0x412d, 0x6f6e, + 0x6f6f, 0x6f70, 0x4f62, 0x3324, 0x4345, 0x6345, 0x4941, 0x6346, + 0x3155, 0x4e4a, 0x3433, 0x4872, 0x6347, 0x4f50, 0x6348, 0x3c64, + 0x6349, 0x634a, 0x4346, 0x5522, 0x4456, 0x396b, 0x4e45, 0x634b, + 0x4376, 0x634c, 0x3727, 0x3873, 0x3a52, 0x634d, 0x634e, 0x5444, + 0x634f, 0x6350, 0x514b, 0x6351, 0x6352, 0x6353, 0x6354, 0x5156, + 0x6355, 0x327b, 0x403b, 0x6356, 0x402b, 0x6357, 0x6358, 0x6359, + 0x635a, 0x635b, 0x3837, 0x5a62, 0x3653, 0x5a64, 0x5a63, 0x5a66, + 0x486e, 0x5a65, 0x3740, 0x5174, 0x5275, 0x5573, 0x3d57, 0x5768, + 0x5a68, 0x5a67, 0x3022, 0x4d53, 0x5a69, 0x383d, 0x3c4a, 0x423d, + 0x4224, 0x3342, 0x5a6a, 0x422a, 0x4430, 0x3d35, 0x4f5e, 0x5a6b, + 0x4942, 0x315d, 0x5a6c, 0x3638, 0x543a, 0x337d, 0x5a6d, 0x5449, + 0x4f55, 0x4563, 0x5a6e, 0x5a6f, 0x5a70, 0x416a, 0x4c55, 0x4f5d, + 0x5367, 0x4221, 0x5a71, 0x4b65, 0x5a72, 0x4b66, 0x527e, 0x3874, + 0x5a73, 0x302f, 0x4f36, 0x554f, 0x4b6d, 0x5a74, 0x6344, 0x4125, + 0x763f, 0x7640, 0x7641, 0x4451, 0x4838, 0x5163, 0x505b, 0x5145, + 0x3c2f, 0x394d, 0x6f74, 0x3446, 0x533a, 0x7642, 0x337b, 0x7643, + 0x3571, 0x7645, 0x536a, 0x7627, 0x5129, 0x7629, 0x7628, 0x4163, + 0x4057, 0x3122, 0x4e6d, 0x5068, 0x762b, 0x4f76, 0x762a, 0x5570, + 0x762c, 0x4339, 0x3b74, 0x762e, 0x762d, 0x445e, 0x4158, 0x4b2a, + 0x4f3c, 0x762f, 0x7630, 0x7631, 0x4236, 0x3054, 0x4579, 0x7632, + 0x4760, 0x7626, 0x3e38, 0x3e32, 0x3565, 0x3747, 0x3f3f, 0x4352, + 0x4366, 0x584c, 0x386f, 0x3d79, 0x5125, 0x3050, 0x7730, 0x7731, + 0x502c, 0x3030, 0x7732, 0x7733, 0x7734, 0x474a, 0x3e4f, 0x7737, + 0x7736, 0x315e, 0x7735, 0x7738, 0x7739, 0x4e24, 0x484d, 0x3a2b, + 0x6838, 0x6839, 0x683a, 0x3e42, 0x5274, 0x544f, 0x4958, 0x5233, + 0x3625, 0x476a, 0x717c, 0x4f6e, 0x4b33, 0x506b, 0x676f, 0x4d67, + 0x394b, 0x3659, 0x717d, 0x3064, 0x4b4c, 0x717e, 0x5424, 0x422d, + 0x416c, 0x4644, 0x3e31, 0x7221, 0x3c55, 0x7222, 0x7223, 0x7224, + 0x5243, 0x4635, 0x4d47, 0x7225, 0x5331, 0x3f45, 0x4c62, 0x7226, + 0x7227, 0x5155, 0x366e, 0x7228, 0x7229, 0x355f, 0x722a, 0x722b, + 0x327c, 0x722c, 0x722d, 0x4827, 0x3767, 0x6c29, 0x6c2a, 0x6c2b, + 0x6c2c, 0x462e, 0x6c2d, 0x6c2e, 0x3749, 0x4a33, 0x6238, 0x774f, + 0x7750, 0x324d, 0x7751, 0x7753, 0x7752, 0x623b, 0x3c22, 0x623c, + 0x623d, 0x623e, 0x623f, 0x6240, 0x6241, 0x3739, 0x527b, 0x3d24, + 0x4a4e, 0x3125, 0x4b47, 0x6242, 0x367c, 0x4844, 0x6243, 0x3d48, + 0x317d, 0x6244, 0x3676, 0x6245, 0x4459, 0x6246, 0x4f5a, 0x395d, + 0x6247, 0x4021, 0x6248, 0x3276, 0x6249, 0x4173, 0x624a, 0x624b, + 0x4278, 0x624c, 0x624d, 0x624e, 0x4a57, 0x5838, 0x5965, 0x4f63, + 0x7025, 0x5c30, 0x426d, 0x5426, 0x4d54, 0x5131, 0x335b, 0x477d, + 0x3235, 0x423f, 0x6660, 0x4a3b, 0x6661, 0x6662, 0x3e54, 0x6663, + 0x5724, 0x4d55, 0x6665, 0x3c5d, 0x6664, 0x6666, 0x6667, 0x426e, + 0x3d3e, 0x6668, 0x4266, 0x3a27, 0x6669, 0x666a, 0x3352, 0x5169, + 0x3f25, 0x666b, 0x466f, 0x666c, 0x666d, 0x666e, 0x462d, 0x666f, + 0x4927, 0x6670, 0x6671, 0x6672, 0x6539, 0x6673, 0x6674, 0x4262, + 0x6675, 0x6676, 0x5668, 0x6677, 0x6678, 0x3947, 0x773b, 0x773a, + 0x773e, 0x773c, 0x3a21, 0x773f, 0x7740, 0x7742, 0x7741, 0x7744, + 0x7743, 0x7745, 0x7746, 0x7747, 0x4b68, 0x385f, 0x7754, 0x7755, + 0x7756, 0x7758, 0x775a, 0x7757, 0x775b, 0x7759, 0x5757, 0x775c, + 0x775d, 0x775e, 0x775f, 0x7760, 0x5b4b, 0x582a, 0x6577, 0x396d, + 0x3f7d, 0x3b6a, 0x7749, 0x4647, 0x7748, 0x774a, 0x774c, 0x774b, + 0x774d, 0x4e3a, 0x774e, 0x4427, 0x5363, 0x764f, 0x4233, 0x7650, + 0x7651, 0x7652, 0x7653, 0x7654, 0x7656, 0x312b, 0x7657, 0x7658, + 0x7659, 0x765a, 0x765b, 0x765c, 0x765d, 0x765e, 0x4f4a, 0x765f, + 0x7660, 0x7661, 0x7662, 0x7663, 0x7664, 0x4070, 0x7665, 0x7666, + 0x7667, 0x7668, 0x7669, 0x766a, 0x766b, 0x766c, 0x766d, 0x766e, + 0x766f, 0x7670, 0x7671, 0x7672, 0x7673, 0x7674, 0x3e28, 0x7675, + 0x7676, 0x7677, 0x7678, 0x487a, 0x7679, 0x767a, 0x767b, 0x767c, + 0x767d, 0x767e, 0x7721, 0x7722, 0x7723, 0x7724, 0x7725, 0x7726, + 0x7727, 0x7728, 0x316e, 0x7729, 0x772a, 0x772b, 0x772c, 0x772d, + 0x415b, 0x772e, 0x772f, 0x4471, 0x702f, 0x3c26, 0x7030, 0x4379, + 0x4538, 0x513b, 0x7031, 0x7032, 0x7033, 0x7034, 0x7035, 0x513c, + 0x516c, 0x7037, 0x7036, 0x5427, 0x4d52, 0x7038, 0x703a, 0x7039, + 0x703b, 0x703c, 0x386b, 0x703d, 0x3a68, 0x703e, 0x703f, 0x3e69, + 0x7040, 0x366c, 0x7041, 0x7042, 0x7043, 0x7044, 0x4835, 0x7045, + 0x7046, 0x7047, 0x4574, 0x7048, 0x7049, 0x704a, 0x773d, 0x704b, + 0x704c, 0x704d, 0x704e, 0x704f, 0x3a57, 0x7050, 0x7051, 0x7052, + 0x7053, 0x7054, 0x7055, 0x7056, 0x7058, 0x5325, 0x7057, 0x7059, + 0x753a, 0x4239, 0x7764, 0x7765, 0x7766, 0x7767, 0x7768, 0x4234, + 0x776a, 0x776b, 0x4273, 0x7470, 0x746f, 0x4269, 0x7761, 0x7762, + 0x3b46, 0x5964, 0x4a72, 0x4068, 0x7024, 0x3a5a, 0x472d, 0x442c, + 0x776c, 0x776d, 0x776e, 0x7770, 0x776f, 0x7771, 0x7774, 0x7773, + 0x7772, 0x7775, 0x7776, 0x6d69, 0x6d6a, 0x6d6b, 0x763c, 0x763d, + 0x763e, 0x3626, 0x583e, 0x3944, 0x583b, 0x5c31, 0x4a73, 0x7777, + 0x7778, 0x7779, 0x777b, 0x777a, 0x3147, 0x777c, 0x777d, 0x777e, + 0x466b, 0x6c34, 0x335d, 0x7633, 0x7634, 0x4164, 0x7635, 0x7636, + 0x7637, 0x7638, 0x7639, 0x763a, 0x4823, 0x763b, 0x417a, 0x3928, + 0x6d68, 0x396a, 0x595f, 0x2321, 0x2322, 0x2323, 0x2167, 0x2325, + 0x2326, 0x2327, 0x2328, 0x2329, 0x232a, 0x232b, 0x232c, 0x232d, + 0x232e, 0x232f, 0x2330, 0x2331, 0x2332, 0x2333, 0x2334, 0x2335, + 0x2336, 0x2337, 0x2338, 0x2339, 0x233a, 0x233b, 0x233c, 0x233d, + 0x233e, 0x233f, 0x2340, 0x2341, 0x2342, 0x2343, 0x2344, 0x2345, + 0x2346, 0x2347, 0x2348, 0x2349, 0x234a, 0x234b, 0x234c, 0x234d, + 0x234e, 0x234f, 0x2350, 0x2351, 0x2352, 0x2353, 0x2354, 0x2355, + 0x2356, 0x2357, 0x2358, 0x2359, 0x235a, 0x235b, 0x235c, 0x235d, + 0x235e, 0x235f, 0x2360, 0x2361, 0x2362, 0x2363, 0x2364, 0x2365, + 0x2366, 0x2367, 0x2368, 0x2369, 0x236a, 0x236b, 0x236c, 0x236d, + 0x236e, 0x236f, 0x2370, 0x2371, 0x2372, 0x2373, 0x2374, 0x2375, + 0x2376, 0x2377, 0x2378, 0x2379, 0x237a, 0x237b, 0x237c, 0x237d, + 0x212b, 0x2169, 0x216a, 0x237e, 0x2324, +}; + +static const Summary16 gb2312_uni2indx_page00[70] = { + /* 0x0000 */ + { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, + { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, + { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0190 }, { 3, 0x0003 }, + { 5, 0x0000 }, { 5, 0x0080 }, { 6, 0x3703 }, { 13, 0x168c }, + /* 0x0100 */ + { 19, 0x0002 }, { 20, 0x0808 }, { 22, 0x0800 }, { 23, 0x0000 }, + { 23, 0x2000 }, { 24, 0x0000 }, { 24, 0x0800 }, { 25, 0x0000 }, + { 25, 0x0000 }, { 25, 0x0000 }, { 25, 0x0000 }, { 25, 0x0000 }, + { 25, 0x4000 }, { 26, 0x1555 }, { 33, 0x0000 }, { 33, 0x0000 }, + /* 0x0200 */ + { 33, 0x0000 }, { 33, 0x0000 }, { 33, 0x0000 }, { 33, 0x0000 }, + { 33, 0x0000 }, { 33, 0x0000 }, { 33, 0x0000 }, { 33, 0x0000 }, + { 33, 0x0000 }, { 33, 0x0000 }, { 33, 0x0000 }, { 33, 0x0000 }, + { 33, 0x0280 }, { 35, 0x0000 }, { 35, 0x0000 }, { 35, 0x0000 }, + /* 0x0300 */ + { 35, 0x0000 }, { 35, 0x0000 }, { 35, 0x0000 }, { 35, 0x0000 }, + { 35, 0x0000 }, { 35, 0x0000 }, { 35, 0x0000 }, { 35, 0x0000 }, + { 35, 0x0000 }, { 35, 0xfffe }, { 50, 0x03fb }, { 59, 0xfffe }, + { 74, 0x03fb }, { 83, 0x0000 }, { 83, 0x0000 }, { 83, 0x0000 }, + /* 0x0400 */ + { 83, 0x0002 }, { 84, 0xffff }, { 100, 0xffff }, { 116, 0xffff }, + { 132, 0xffff }, { 148, 0x0002 }, +}; +static const Summary16 gb2312_uni2indx_page20[101] = { + /* 0x2000 */ + { 149, 0x0000 }, { 149, 0x3360 }, { 155, 0x0040 }, { 156, 0x080d }, + { 160, 0x0000 }, { 160, 0x0000 }, { 160, 0x0000 }, { 160, 0x0000 }, + { 160, 0x0000 }, { 160, 0x0000 }, { 160, 0x0000 }, { 160, 0x0000 }, + { 160, 0x0000 }, { 160, 0x0000 }, { 160, 0x0000 }, { 160, 0x0000 }, + /* 0x2100 */ + { 160, 0x0008 }, { 161, 0x0040 }, { 162, 0x0000 }, { 162, 0x0000 }, + { 162, 0x0000 }, { 162, 0x0000 }, { 162, 0x0fff }, { 174, 0x0000 }, + { 174, 0x0000 }, { 174, 0x000f }, { 178, 0x0000 }, { 178, 0x0000 }, + { 178, 0x0000 }, { 178, 0x0000 }, { 178, 0x0000 }, { 178, 0x0000 }, + /* 0x2200 */ + { 178, 0x8100 }, { 180, 0x6402 }, { 184, 0x4fa1 }, { 192, 0x20f0 }, + { 197, 0x1100 }, { 199, 0x0000 }, { 199, 0xc033 }, { 205, 0x0000 }, + { 205, 0x0000 }, { 205, 0x0200 }, { 206, 0x0020 }, { 207, 0x0000 }, + { 207, 0x0000 }, { 207, 0x0000 }, { 207, 0x0000 }, { 207, 0x0000 }, + /* 0x2300 */ + { 207, 0x0000 }, { 207, 0x0004 }, { 208, 0x0000 }, { 208, 0x0000 }, + { 208, 0x0000 }, { 208, 0x0000 }, { 208, 0x0000 }, { 208, 0x0000 }, + { 208, 0x0000 }, { 208, 0x0000 }, { 208, 0x0000 }, { 208, 0x0000 }, + { 208, 0x0000 }, { 208, 0x0000 }, { 208, 0x0000 }, { 208, 0x0000 }, + /* 0x2400 */ + { 208, 0x0000 }, { 208, 0x0000 }, { 208, 0x0000 }, { 208, 0x0000 }, + { 208, 0x0000 }, { 208, 0x0000 }, { 208, 0x03ff }, { 218, 0xfff0 }, + { 230, 0xffff }, { 246, 0x0fff }, { 258, 0x0000 }, { 258, 0x0000 }, + { 258, 0x0000 }, { 258, 0x0000 }, { 258, 0x0000 }, { 258, 0x0000 }, + /* 0x2500 */ + { 258, 0xffff }, { 274, 0xffff }, { 290, 0xffff }, { 306, 0xffff }, + { 322, 0x0fff }, { 334, 0x0000 }, { 334, 0x0000 }, { 334, 0x0000 }, + { 334, 0x0000 }, { 334, 0x0000 }, { 334, 0x0003 }, { 336, 0x000c }, + { 338, 0xc8c0 }, { 343, 0x0000 }, { 343, 0x0000 }, { 343, 0x0000 }, + /* 0x2600 */ + { 343, 0x0060 }, { 345, 0x0000 }, { 345, 0x0000 }, { 345, 0x0000 }, + { 345, 0x0005 }, +}; +static const Summary16 gb2312_uni2indx_page30[35] = { + /* 0x3000 */ + { 347, 0xff2f }, { 360, 0x00fb }, { 367, 0x0000 }, { 367, 0x0000 }, + { 367, 0xfffe }, { 382, 0xffff }, { 398, 0xffff }, { 414, 0xffff }, + { 430, 0xffff }, { 446, 0x000f }, { 450, 0xfffe }, { 465, 0xffff }, + { 481, 0xffff }, { 497, 0xffff }, { 513, 0xffff }, { 529, 0x087f }, + /* 0x3100 */ + { 537, 0xffe0 }, { 548, 0xffff }, { 564, 0x03ff }, { 574, 0x0000 }, + { 574, 0x0000 }, { 574, 0x0000 }, { 574, 0x0000 }, { 574, 0x0000 }, + { 574, 0x0000 }, { 574, 0x0000 }, { 574, 0x0000 }, { 574, 0x0000 }, + { 574, 0x0000 }, { 574, 0x0000 }, { 574, 0x0000 }, { 574, 0x0000 }, + /* 0x3200 */ + { 574, 0x0000 }, { 574, 0x0000 }, { 574, 0x03ff }, +}; +static const Summary16 gb2312_uni2indx_page4e[1263] = { + /* 0x4e00 */ + { 584, 0x7f8b }, { 595, 0x7f7b }, { 608, 0x3db4 }, { 617, 0xef55 }, + { 628, 0xfba8 }, { 638, 0xf35d }, { 649, 0x0243 }, { 653, 0x400b }, + { 657, 0xfb40 }, { 665, 0x8d3e }, { 674, 0x7bf7 }, { 687, 0x8c2c }, + { 693, 0x6eff }, { 706, 0xe3fa }, { 717, 0x1d3a }, { 725, 0xa8ed }, + /* 0x4f00 */ + { 734, 0xe602 }, { 740, 0xcf83 }, { 749, 0x8cf5 }, { 758, 0x3555 }, + { 766, 0xe048 }, { 771, 0xffab }, { 784, 0x92b9 }, { 792, 0xd859 }, + { 800, 0xab18 }, { 807, 0x2892 }, { 812, 0xd7e9 }, { 823, 0x8020 }, + { 825, 0xc438 }, { 831, 0xf583 }, { 840, 0xe74a }, { 849, 0x450a }, + /* 0x5000 */ + { 854, 0xb000 }, { 857, 0x9714 }, { 864, 0x7762 }, { 873, 0x5400 }, + { 876, 0xd188 }, { 882, 0x1420 }, { 885, 0x1020 }, { 887, 0xc8c0 }, + { 892, 0x2121 }, { 896, 0x0000 }, { 896, 0x13a8 }, { 902, 0x0c04 }, + { 905, 0x8000 }, { 906, 0x0440 }, { 908, 0x70c0 }, { 913, 0x0828 }, + /* 0x5100 */ + { 916, 0x08c0 }, { 919, 0x0004 }, { 920, 0x0002 }, { 921, 0x8000 }, + { 922, 0x2b7b }, { 932, 0x1472 }, { 938, 0x7924 }, { 945, 0x3bfb }, + { 957, 0x3327 }, { 965, 0x1ae4 }, { 972, 0x9835 }, { 979, 0x38ef }, + { 989, 0x9ad1 }, { 997, 0x2802 }, { 1000, 0xa813 }, { 1006, 0xbf69 }, + /* 0x5200 */ + { 1017, 0x65cf }, { 1027, 0x2fc6 }, { 1036, 0x6b11 }, { 1043, 0xafc9 }, + { 1053, 0x340f }, { 1060, 0x5053 }, { 1066, 0x86a2 }, { 1072, 0xa004 }, + { 1075, 0x0106 }, { 1078, 0xe809 }, { 1084, 0x3f0f }, { 1094, 0xc00e }, + { 1099, 0x0a88 }, { 1103, 0x8145 }, { 1108, 0x0010 }, { 1109, 0xc601 }, + /* 0x5300 */ + { 1114, 0xa161 }, { 1120, 0x26e1 }, { 1127, 0x444b }, { 1133, 0xce00 }, + { 1138, 0xc7aa }, { 1147, 0xd4ee }, { 1157, 0xcadf }, { 1168, 0x85bb }, + { 1177, 0x3a74 }, { 1185, 0xa520 }, { 1190, 0x436c }, { 1197, 0x8840 }, + { 1200, 0x3f06 }, { 1208, 0x8bd2 }, { 1216, 0xff79 }, { 1229, 0x3bef }, + /* 0x5400 */ + { 1241, 0xf75a }, { 1252, 0xe8ef }, { 1263, 0xfbcb }, { 1275, 0x5b36 }, + { 1284, 0x0d49 }, { 1290, 0x1bfd }, { 1301, 0x0154 }, { 1305, 0x39ee }, + { 1315, 0xd855 }, { 1323, 0x2e75 }, { 1332, 0xbfd8 }, { 1343, 0xa91a }, + { 1350, 0xf3d7 }, { 1362, 0xf6bf }, { 1375, 0x67e0 }, { 1383, 0xb40c }, + /* 0x5500 */ + { 1389, 0x82c2 }, { 1394, 0x0813 }, { 1398, 0xd49d }, { 1407, 0xd08b }, + { 1414, 0x065a }, { 1420, 0x1061 }, { 1424, 0x74f2 }, { 1433, 0x59e0 }, + { 1440, 0x8f9f }, { 1451, 0xb312 }, { 1458, 0x0080 }, { 1459, 0x6aaa }, + { 1467, 0x3230 }, { 1472, 0xb05e }, { 1480, 0x9d7a }, { 1490, 0x60ac }, + /* 0x5600 */ + { 1496, 0xd303 }, { 1503, 0xc900 }, { 1507, 0x3098 }, { 1512, 0x8a56 }, + { 1519, 0x7000 }, { 1522, 0x1390 }, { 1527, 0x1f14 }, { 1534, 0x1842 }, + { 1538, 0xc060 }, { 1542, 0x0008 }, { 1543, 0x8008 }, { 1545, 0x1080 }, + { 1547, 0x0400 }, { 1548, 0xec90 }, { 1555, 0x2817 }, { 1561, 0xe633 }, + /* 0x5700 */ + { 1570, 0x0758 }, { 1576, 0x9000 }, { 1578, 0xf708 }, { 1586, 0x4e09 }, + { 1592, 0xf485 }, { 1600, 0xfc83 }, { 1609, 0xaf53 }, { 1619, 0x18c8 }, + { 1624, 0x187c }, { 1631, 0x080c }, { 1634, 0x6adf }, { 1645, 0x0114 }, + { 1648, 0xc80c }, { 1653, 0xa734 }, { 1661, 0xa011 }, { 1665, 0x2710 }, + /* 0x5800 */ + { 1670, 0x28c5 }, { 1676, 0x4222 }, { 1680, 0x0413 }, { 1684, 0x0021 }, + { 1686, 0x3010 }, { 1689, 0x4112 }, { 1693, 0x1820 }, { 1696, 0x4000 }, + { 1697, 0x022b }, { 1702, 0xc60c }, { 1708, 0x0300 }, { 1710, 0x1000 }, + { 1711, 0x0022 }, { 1713, 0x0022 }, { 1715, 0x5810 }, { 1719, 0x0249 }, + /* 0x5900 */ + { 1723, 0xa094 }, { 1728, 0x9670 }, { 1735, 0xeeb0 }, { 1744, 0x1792 }, + { 1751, 0xcb96 }, { 1760, 0x05f2 }, { 1767, 0x0025 }, { 1770, 0x2358 }, + { 1776, 0x25de }, { 1785, 0x42cc }, { 1791, 0xcf38 }, { 1800, 0x4a04 }, + { 1804, 0x0c40 }, { 1807, 0x359f }, { 1817, 0x1128 }, { 1821, 0x8a00 }, + /* 0x5a00 */ + { 1824, 0x13fa }, { 1833, 0x910a }, { 1838, 0x0229 }, { 1842, 0x1056 }, + { 1847, 0x0641 }, { 1851, 0x0420 }, { 1853, 0x0484 }, { 1856, 0x84f0 }, + { 1862, 0x0000 }, { 1862, 0x0c04 }, { 1865, 0x0400 }, { 1866, 0x412c }, + { 1871, 0x1206 }, { 1875, 0x1154 }, { 1880, 0x0a4b }, { 1886, 0x0002 }, + /* 0x5b00 */ + { 1887, 0x0200 }, { 1888, 0x00c0 }, { 1890, 0x0000 }, { 1890, 0x0094 }, + { 1893, 0x0001 }, { 1894, 0xbfbb }, { 1907, 0x167c }, { 1915, 0x242b }, + { 1921, 0x9bbb }, { 1932, 0x7fa8 }, { 1942, 0x0c7f }, { 1951, 0xe379 }, + { 1961, 0x10f4 }, { 1967, 0xe00d }, { 1973, 0x4132 }, { 1978, 0x9f01 }, + /* 0x5c00 */ + { 1985, 0x8652 }, { 1991, 0x3572 }, { 1999, 0x10b4 }, { 2004, 0xff12 }, + { 2014, 0xcf27 }, { 2024, 0x4223 }, { 2029, 0xc06b }, { 2036, 0x8602 }, + { 2040, 0x3106 }, { 2045, 0x1fd3 }, { 2055, 0x3a0c }, { 2061, 0xa1aa }, + { 2068, 0x0812 }, { 2071, 0x0204 }, { 2073, 0x2572 }, { 2080, 0x0801 }, + /* 0x5d00 */ + { 2082, 0x40cc }, { 2087, 0x4850 }, { 2091, 0x62d0 }, { 2097, 0x6010 }, + { 2100, 0x1c80 }, { 2104, 0x2900 }, { 2107, 0x9a00 }, { 2111, 0x0010 }, + { 2112, 0x0004 }, { 2113, 0x2200 }, { 2115, 0x0000 }, { 2115, 0x0080 }, + { 2116, 0x2020 }, { 2118, 0x6800 }, { 2121, 0xcbe6 }, { 2131, 0x609e }, + /* 0x5e00 */ + { 2138, 0x916e }, { 2146, 0x3f73 }, { 2157, 0x60c0 }, { 2161, 0x3982 }, + { 2167, 0x1034 }, { 2171, 0x4830 }, { 2175, 0x0006 }, { 2177, 0xbd5c }, + { 2187, 0x8cd1 }, { 2194, 0xd6fb }, { 2206, 0x20e1 }, { 2211, 0x43e8 }, + { 2218, 0x0600 }, { 2220, 0x084e }, { 2225, 0x0500 }, { 2227, 0xc4d0 }, + /* 0x5f00 */ + { 2233, 0x8d1f }, { 2242, 0x89aa }, { 2249, 0xa6e1 }, { 2257, 0x1602 }, + { 2261, 0x0001 }, { 2262, 0x21ed }, { 2270, 0x3656 }, { 2278, 0x1a8b }, + { 2285, 0x1fb7 }, { 2296, 0x13a5 }, { 2303, 0x6502 }, { 2308, 0x30a0 }, + { 2312, 0xb278 }, { 2320, 0x23c7 }, { 2328, 0x6c93 }, { 2336, 0xe922 }, + /* 0x6000 */ + { 2343, 0xe47f }, { 2354, 0x3a74 }, { 2362, 0x8fe3 }, { 2372, 0x9820 }, + { 2376, 0x280e }, { 2381, 0x2625 }, { 2387, 0xbf9c }, { 2398, 0xbf49 }, + { 2408, 0x3218 }, { 2413, 0xac54 }, { 2420, 0xb949 }, { 2428, 0x1916 }, + { 2434, 0x0c60 }, { 2438, 0xb522 }, { 2445, 0xfbc1 }, { 2455, 0x0659 }, + /* 0x6100 */ + { 2461, 0xe343 }, { 2469, 0x8420 }, { 2472, 0x08d9 }, { 2478, 0x8000 }, + { 2479, 0x5500 }, { 2483, 0x2022 }, { 2486, 0x0184 }, { 2489, 0x00a1 }, + { 2492, 0x4800 }, { 2494, 0x2010 }, { 2496, 0x1380 }, { 2500, 0x4080 }, + { 2502, 0x0d04 }, { 2506, 0x0016 }, { 2509, 0x0040 }, { 2510, 0x8020 }, + /* 0x6200 */ + { 2512, 0xfd40 }, { 2520, 0x8de7 }, { 2530, 0x5436 }, { 2537, 0xe098 }, + { 2543, 0x7b8b }, { 2553, 0x091e }, { 2559, 0xfec8 }, { 2569, 0xd249 }, + { 2576, 0x0611 }, { 2580, 0x8dee }, { 2590, 0x1937 }, { 2598, 0xba22 }, + { 2605, 0x77f4 }, { 2616, 0x9fdd }, { 2628, 0xf3ec }, { 2639, 0xf0da }, + /* 0x6300 */ + { 2648, 0x4386 }, { 2654, 0xec42 }, { 2661, 0x8d3f }, { 2671, 0x2604 }, + { 2675, 0xfa6c }, { 2685, 0xc021 }, { 2689, 0x628e }, { 2696, 0x0cc2 }, + { 2701, 0xd785 }, { 2710, 0x0145 }, { 2714, 0x77ad }, { 2725, 0x5599 }, + { 2733, 0xe250 }, { 2739, 0x4045 }, { 2743, 0x260b }, { 2749, 0xa154 }, + /* 0x6400 */ + { 2755, 0x9827 }, { 2762, 0x5819 }, { 2768, 0x3443 }, { 2774, 0xa410 }, + { 2778, 0x05f2 }, { 2785, 0x4114 }, { 2789, 0x2280 }, { 2792, 0x0700 }, + { 2795, 0x00b4 }, { 2799, 0x4266 }, { 2805, 0x7210 }, { 2810, 0x15a1 }, + { 2816, 0x6025 }, { 2821, 0x4185 }, { 2826, 0x0054 }, { 2829, 0x0000 }, + /* 0x6500 */ + { 2829, 0x0201 }, { 2831, 0x0104 }, { 2833, 0xc820 }, { 2837, 0xcb70 }, + { 2845, 0x9320 }, { 2850, 0x6a62 }, { 2857, 0x184c }, { 2862, 0x0095 }, + { 2866, 0x1880 }, { 2869, 0x9a8b }, { 2877, 0xaab2 }, { 2885, 0x3201 }, + { 2889, 0xd87a }, { 2898, 0x00c4 }, { 2901, 0xf3e5 }, { 2912, 0x04c3 }, + /* 0x6600 */ + { 2917, 0xd44d }, { 2925, 0xa238 }, { 2931, 0xa1a1 }, { 2937, 0x5072 }, + { 2943, 0x980a }, { 2948, 0x84fc }, { 2956, 0xc152 }, { 2962, 0x44d1 }, + { 2968, 0x1094 }, { 2972, 0x20c2 }, { 2976, 0x4180 }, { 2979, 0x4210 }, + { 2982, 0x0000 }, { 2982, 0x3a00 }, { 2986, 0x0240 }, { 2988, 0xd29d }, + /* 0x6700 */ + { 2997, 0x2f01 }, { 3003, 0xa8b1 }, { 3010, 0xbd40 }, { 3017, 0x2432 }, + { 3022, 0xd34d }, { 3031, 0xd04b }, { 3038, 0xa723 }, { 3046, 0xd0ad }, + { 3054, 0x0a92 }, { 3059, 0x75a1 }, { 3067, 0xadac }, { 3076, 0x01e9 }, + { 3082, 0x801a }, { 3086, 0x771f }, { 3097, 0x9225 }, { 3103, 0xa01b }, + /* 0x6800 */ + { 3109, 0xdfa1 }, { 3119, 0x20ca }, { 3124, 0x0602 }, { 3127, 0x738c }, + { 3135, 0x577f }, { 3147, 0x003b }, { 3152, 0x0bff }, { 3163, 0x00d0 }, + { 3166, 0x806a }, { 3171, 0x0088 }, { 3173, 0xa1c4 }, { 3179, 0x0029 }, + { 3182, 0x2a05 }, { 3187, 0x0524 }, { 3191, 0x4009 }, { 3194, 0x1623 }, + /* 0x6900 */ + { 3200, 0x6822 }, { 3205, 0x8005 }, { 3208, 0x2011 }, { 3211, 0xa211 }, + { 3216, 0x0004 }, { 3217, 0x6490 }, { 3222, 0x4849 }, { 3227, 0x1382 }, + { 3232, 0x23d5 }, { 3240, 0x1930 }, { 3245, 0x2980 }, { 3249, 0x0892 }, + { 3253, 0x5402 }, { 3257, 0x8811 }, { 3261, 0x2001 }, { 3263, 0xa004 }, + /* 0x6a00 */ + { 3266, 0x0400 }, { 3267, 0x8180 }, { 3270, 0x8502 }, { 3274, 0x6022 }, + { 3278, 0x0090 }, { 3280, 0x0b01 }, { 3284, 0x0022 }, { 3286, 0x1202 }, + { 3289, 0x4011 }, { 3292, 0x0083 }, { 3295, 0x1a01 }, { 3299, 0x0000 }, + { 3299, 0x0000 }, { 3299, 0x0000 }, { 3299, 0x0000 }, { 3299, 0x0000 }, + /* 0x6b00 */ + { 3299, 0x0000 }, { 3299, 0x0000 }, { 3299, 0x009f }, { 3305, 0x4684 }, + { 3310, 0x12c8 }, { 3315, 0x0200 }, { 3316, 0x04fc }, { 3323, 0x1a00 }, + { 3326, 0x2ede }, { 3336, 0x0c4c }, { 3341, 0x0402 }, { 3343, 0x80b8 }, + { 3348, 0xa826 }, { 3354, 0x0afc }, { 3362, 0x8c02 }, { 3366, 0x2228 }, + /* 0x6c00 */ + { 3370, 0xa0e0 }, { 3375, 0x8f7b }, { 3386, 0xc7d6 }, { 3396, 0x2135 }, + { 3402, 0x06c7 }, { 3409, 0xf8b1 }, { 3418, 0x0713 }, { 3424, 0x6255 }, + { 3431, 0x936e }, { 3440, 0x8a19 }, { 3446, 0x6efa }, { 3457, 0xfb0e }, + { 3467, 0x1630 }, { 3472, 0x48f9 }, { 3480, 0xcd2f }, { 3490, 0x7deb }, + /* 0x6d00 */ + { 3502, 0x5892 }, { 3508, 0x4e84 }, { 3514, 0x4ca0 }, { 3519, 0x7a2e }, + { 3528, 0xedea }, { 3539, 0x561e }, { 3547, 0xc649 }, { 3554, 0x1190 }, + { 3558, 0x5324 }, { 3564, 0xe83a }, { 3572, 0xcfdb }, { 3584, 0x8124 }, + { 3588, 0x18f1 }, { 3595, 0x6342 }, { 3601, 0x5853 }, { 3608, 0x1a8a }, + /* 0x6e00 */ + { 3614, 0x7420 }, { 3619, 0x24d3 }, { 3626, 0xaa3b }, { 3635, 0x0514 }, + { 3639, 0x6018 }, { 3643, 0x8958 }, { 3649, 0x4800 }, { 3651, 0xc000 }, + { 3653, 0x8268 }, { 3658, 0x9101 }, { 3662, 0x84a4 }, { 3667, 0x2cd6 }, + { 3675, 0x8886 }, { 3680, 0xc4ba }, { 3688, 0x0377 }, { 3696, 0x0210 }, + /* 0x6f00 */ + { 3698, 0x8244 }, { 3702, 0x0038 }, { 3705, 0xae11 }, { 3712, 0x404a }, + { 3716, 0x28c0 }, { 3720, 0x5100 }, { 3723, 0x6044 }, { 3727, 0x1514 }, + { 3732, 0x7310 }, { 3738, 0x1000 }, { 3739, 0x0082 }, { 3741, 0x0248 }, + { 3744, 0x0205 }, { 3747, 0x4006 }, { 3750, 0xc003 }, { 3754, 0x0000 }, + /* 0x7000 */ + { 3754, 0x0000 }, { 3754, 0x0c02 }, { 3757, 0x0008 }, { 3758, 0x0220 }, + { 3760, 0x9000 }, { 3762, 0x4000 }, { 3763, 0xb800 }, { 3767, 0xd161 }, + { 3774, 0x4621 }, { 3779, 0x3274 }, { 3786, 0xf800 }, { 3791, 0x3b8a }, + { 3799, 0x050f }, { 3805, 0x8b00 }, { 3809, 0xbbd0 }, { 3818, 0x2280 }, + /* 0x7100 */ + { 3821, 0x0600 }, { 3823, 0x0769 }, { 3830, 0x8040 }, { 3832, 0x0043 }, + { 3835, 0x5420 }, { 3839, 0x5000 }, { 3841, 0x41d0 }, { 3846, 0x250c }, + { 3851, 0x8410 }, { 3854, 0x8310 }, { 3858, 0x1101 }, { 3861, 0x0228 }, + { 3864, 0x4008 }, { 3866, 0x0030 }, { 3868, 0x40a1 }, { 3872, 0x0200 }, + /* 0x7200 */ + { 3873, 0x0040 }, { 3874, 0x2000 }, { 3875, 0x1500 }, { 3878, 0xabe3 }, + { 3888, 0x3180 }, { 3892, 0xaa44 }, { 3898, 0xc2c6 }, { 3905, 0xc624 }, + { 3911, 0xac13 }, { 3918, 0x8004 }, { 3920, 0xb000 }, { 3923, 0x03d1 }, + { 3929, 0x611e }, { 3936, 0x4285 }, { 3941, 0xf303 }, { 3949, 0x1d9f }, + /* 0x7300 */ + { 3959, 0x440a }, { 3963, 0x78e8 }, { 3971, 0x5e26 }, { 3979, 0xc392 }, + { 3986, 0x2000 }, { 3987, 0x0085 }, { 3990, 0xb001 }, { 3994, 0x4000 }, + { 3995, 0x4a90 }, { 4000, 0x8842 }, { 4004, 0xca04 }, { 4009, 0x0c8d }, + { 4015, 0xa705 }, { 4022, 0x4203 }, { 4026, 0x22a1 }, { 4031, 0x0004 }, + /* 0x7400 */ + { 4032, 0x8668 }, { 4038, 0x0c01 }, { 4041, 0x5564 }, { 4048, 0x1079 }, + { 4054, 0x0002 }, { 4055, 0xdea0 }, { 4063, 0x2000 }, { 4064, 0x40c1 }, + { 4068, 0x488b }, { 4074, 0x5001 }, { 4077, 0x0380 }, { 4080, 0x0400 }, + { 4081, 0x0000 }, { 4081, 0x5004 }, { 4084, 0xc05d }, { 4091, 0x80d0 }, + /* 0x7500 */ + { 4095, 0xa010 }, { 4098, 0x970a }, { 4105, 0xbb20 }, { 4112, 0x4daf }, + { 4122, 0xd921 }, { 4129, 0x1e10 }, { 4134, 0x0460 }, { 4137, 0x8314 }, + { 4142, 0x8848 }, { 4146, 0xa6d6 }, { 4155, 0xd83b }, { 4164, 0x733f }, + { 4175, 0x27bc }, { 4184, 0x4974 }, { 4191, 0x0ddc }, { 4199, 0x9213 }, + /* 0x7600 */ + { 4205, 0x142b }, { 4211, 0x8ba1 }, { 4218, 0x2e75 }, { 4227, 0xd139 }, + { 4235, 0x3009 }, { 4239, 0x5050 }, { 4243, 0x8808 }, { 4246, 0x6900 }, + { 4250, 0x49d4 }, { 4257, 0x024a }, { 4261, 0x4010 }, { 4263, 0x8016 }, + { 4267, 0xe564 }, { 4275, 0x89d7 }, { 4284, 0xc020 }, { 4287, 0x5316 }, + /* 0x7700 */ + { 4294, 0x2b92 }, { 4301, 0x8600 }, { 4304, 0xa345 }, { 4311, 0x15e0 }, + { 4317, 0x008b }, { 4321, 0x0c03 }, { 4325, 0x196e }, { 4333, 0xe200 }, + { 4337, 0x7031 }, { 4343, 0x8006 }, { 4346, 0x16a5 }, { 4353, 0xa829 }, + { 4359, 0x2000 }, { 4360, 0x1880 }, { 4363, 0x7aac }, { 4372, 0xe148 }, + /* 0x7800 */ + { 4378, 0x3207 }, { 4384, 0xb5d6 }, { 4394, 0x32e8 }, { 4401, 0x5f91 }, + { 4410, 0x50a1 }, { 4415, 0x20e5 }, { 4421, 0x7c00 }, { 4426, 0x1080 }, + { 4428, 0x7280 }, { 4433, 0x9d8a }, { 4441, 0x00aa }, { 4445, 0x421f }, + { 4452, 0x0e22 }, { 4457, 0x0231 }, { 4461, 0x1100 }, { 4463, 0x0494 }, + /* 0x7900 */ + { 4467, 0x0022 }, { 4469, 0x4008 }, { 4471, 0x0010 }, { 4472, 0x5c10 }, + { 4477, 0x0343 }, { 4482, 0xfcc8 }, { 4491, 0xa1a5 }, { 4498, 0x0580 }, + { 4501, 0x8433 }, { 4507, 0x0400 }, { 4508, 0x0080 }, { 4509, 0x6e08 }, + { 4515, 0x2a4b }, { 4522, 0x8126 }, { 4527, 0xaad8 }, { 4535, 0x2901 }, + /* 0x7a00 */ + { 4539, 0x684d }, { 4546, 0x4490 }, { 4550, 0x0009 }, { 4552, 0xba88 }, + { 4559, 0x0040 }, { 4560, 0x0082 }, { 4562, 0x0000 }, { 4562, 0x87d1 }, + { 4570, 0x215b }, { 4577, 0xb1e6 }, { 4586, 0x3161 }, { 4592, 0x8008 }, + { 4594, 0x0800 }, { 4595, 0xc240 }, { 4599, 0xa069 }, { 4605, 0xa600 }, + /* 0x7b00 */ + { 4609, 0x8d58 }, { 4616, 0x4a32 }, { 4622, 0x5d71 }, { 4631, 0x550a }, + { 4637, 0x9aa0 }, { 4643, 0x2d57 }, { 4652, 0x4005 }, { 4655, 0x4aa6 }, + { 4662, 0x2021 }, { 4665, 0x30b1 }, { 4671, 0x3fc6 }, { 4681, 0x0112 }, + { 4684, 0x10c2 }, { 4688, 0x260a }, { 4693, 0x4462 }, { 4698, 0x5082 }, + /* 0x7c00 */ + { 4702, 0x9880 }, { 4706, 0x8040 }, { 4708, 0x04c0 }, { 4711, 0x8100 }, + { 4713, 0x2003 }, { 4716, 0x0000 }, { 4716, 0x0000 }, { 4716, 0x3818 }, + { 4721, 0x0200 }, { 4722, 0xf1a6 }, { 4731, 0x4434 }, { 4736, 0x720e }, + { 4743, 0x35a2 }, { 4750, 0x92e0 }, { 4756, 0x8101 }, { 4759, 0x0900 }, + /* 0x7d00 */ + { 4761, 0x0400 }, { 4762, 0x0000 }, { 4762, 0x8885 }, { 4767, 0x0000 }, + { 4767, 0x0000 }, { 4767, 0x0000 }, { 4767, 0x4000 }, { 4768, 0x0080 }, + { 4769, 0x0000 }, { 4769, 0x0000 }, { 4769, 0x4040 }, { 4771, 0x0000 }, + { 4771, 0x0000 }, { 4771, 0x0000 }, { 4771, 0x0000 }, { 4771, 0x0000 }, + /* 0x7e00 */ + { 4771, 0x0000 }, { 4771, 0x0000 }, { 4771, 0x0000 }, { 4771, 0x0800 }, + { 4772, 0x0082 }, { 4774, 0x0000 }, { 4774, 0x0000 }, { 4774, 0x0000 }, + { 4774, 0x0004 }, { 4775, 0x8800 }, { 4777, 0xbfff }, { 4792, 0xe7ef }, + { 4805, 0xffff }, { 4821, 0xffbf }, { 4836, 0xefef }, { 4850, 0xfdff }, + /* 0x7f00 */ + { 4865, 0xfbff }, { 4880, 0xbffe }, { 4894, 0xffff }, { 4910, 0x057f }, + { 4919, 0x0034 }, { 4922, 0x85b3 }, { 4930, 0x4706 }, { 4936, 0x4216 }, + { 4941, 0x5402 }, { 4945, 0xe410 }, { 4950, 0x8092 }, { 4954, 0xb305 }, + { 4961, 0x5422 }, { 4966, 0x8130 }, { 4970, 0x4263 }, { 4976, 0x180b }, + /* 0x8000 */ + { 4981, 0x387b }, { 4990, 0x13f5 }, { 4999, 0x07e5 }, { 5007, 0xa9ea }, + { 5016, 0x3c4c }, { 5023, 0x0514 }, { 5027, 0x0600 }, { 5029, 0x8002 }, + { 5031, 0x1ad9 }, { 5039, 0xbd48 }, { 5047, 0xee37 }, { 5058, 0xf496 }, + { 5067, 0x705f }, { 5076, 0x7ec0 }, { 5084, 0xbfb2 }, { 5095, 0x355f }, + /* 0x8100 */ + { 5105, 0xe644 }, { 5112, 0x455f }, { 5121, 0x9000 }, { 5123, 0x4146 }, + { 5128, 0x1d40 }, { 5133, 0x063b }, { 5140, 0x62a1 }, { 5146, 0xfe13 }, + { 5156, 0x8505 }, { 5161, 0x3902 }, { 5166, 0x0548 }, { 5170, 0x0c08 }, + { 5173, 0x144f }, { 5180, 0x0000 }, { 5180, 0x3488 }, { 5185, 0x5818 }, + /* 0x8200 */ + { 5190, 0x3077 }, { 5198, 0xd815 }, { 5205, 0xbd0e }, { 5214, 0x4bfb }, + { 5225, 0x8a90 }, { 5230, 0x8500 }, { 5233, 0xc100 }, { 5236, 0xe61d }, + { 5245, 0xed14 }, { 5253, 0xb386 }, { 5261, 0xff72 }, { 5273, 0x639b }, + { 5282, 0xfd92 }, { 5292, 0xd9be }, { 5303, 0x887b }, { 5311, 0x0a92 }, + /* 0x8300 */ + { 5316, 0xd3fe }, { 5328, 0x1cb2 }, { 5335, 0xb980 }, { 5341, 0x177a }, + { 5350, 0x82c9 }, { 5356, 0xdc17 }, { 5365, 0xfffb }, { 5380, 0x3980 }, + { 5385, 0x4260 }, { 5389, 0x590c }, { 5395, 0x0f01 }, { 5400, 0x37df }, + { 5412, 0x94a3 }, { 5419, 0xb150 }, { 5425, 0x0623 }, { 5430, 0x2307 }, + /* 0x8400 */ + { 5436, 0xf85a }, { 5445, 0x3102 }, { 5449, 0x01f0 }, { 5454, 0x3102 }, + { 5458, 0x0040 }, { 5459, 0x1e82 }, { 5465, 0x3a0a }, { 5471, 0x056a }, + { 5477, 0x5b84 }, { 5484, 0x1280 }, { 5487, 0x8002 }, { 5489, 0xa714 }, + { 5496, 0x2612 }, { 5501, 0xa04b }, { 5507, 0x1069 }, { 5512, 0x9001 }, + /* 0x8500 */ + { 5515, 0x1000 }, { 5516, 0x848a }, { 5521, 0x1802 }, { 5524, 0x3f80 }, + { 5531, 0x0708 }, { 5535, 0x4240 }, { 5538, 0x0110 }, { 5540, 0x4e14 }, + { 5546, 0x80b0 }, { 5550, 0x1800 }, { 5552, 0xc510 }, { 5557, 0x0281 }, + { 5560, 0x8202 }, { 5563, 0x1029 }, { 5567, 0x0210 }, { 5569, 0x8800 }, + /* 0x8600 */ + { 5571, 0x0020 }, { 5572, 0x0042 }, { 5574, 0x0280 }, { 5576, 0x1100 }, + { 5578, 0xe000 }, { 5581, 0x4413 }, { 5586, 0x5804 }, { 5590, 0xfe02 }, + { 5598, 0x3c07 }, { 5605, 0x3028 }, { 5609, 0x9798 }, { 5617, 0x0473 }, + { 5623, 0xced1 }, { 5632, 0xcb13 }, { 5640, 0x6210 }, { 5644, 0x431f }, + /* 0x8700 */ + { 5652, 0x278d }, { 5660, 0x55ac }, { 5668, 0x422e }, { 5674, 0xc892 }, + { 5680, 0x5380 }, { 5685, 0x0288 }, { 5688, 0x4039 }, { 5693, 0x7851 }, + { 5700, 0x292c }, { 5706, 0x8088 }, { 5709, 0xb900 }, { 5714, 0x2428 }, + { 5718, 0x0c41 }, { 5722, 0x080e }, { 5726, 0x4421 }, { 5730, 0x4200 }, + /* 0x8800 */ + { 5732, 0x0408 }, { 5734, 0x0868 }, { 5738, 0x0006 }, { 5740, 0x1204 }, + { 5743, 0x3031 }, { 5748, 0x0290 }, { 5751, 0x5b3e }, { 5761, 0xe085 }, + { 5767, 0x2936 }, { 5774, 0x1044 }, { 5777, 0x2814 }, { 5781, 0x1082 }, + { 5784, 0x4266 }, { 5790, 0x8334 }, { 5796, 0x013c }, { 5801, 0x531b }, + /* 0x8900 */ + { 5809, 0x0404 }, { 5811, 0x0e0d }, { 5817, 0x0c22 }, { 5821, 0x0051 }, + { 5824, 0x0012 }, { 5826, 0xc000 }, { 5828, 0x0040 }, { 5829, 0x8800 }, + { 5831, 0x004a }, { 5834, 0x0000 }, { 5834, 0x0000 }, { 5834, 0x0000 }, + { 5834, 0xdff6 }, { 5847, 0x5447 }, { 5854, 0x8868 }, { 5859, 0x0008 }, + /* 0x8a00 */ + { 5860, 0x0081 }, { 5862, 0x0000 }, { 5862, 0x0000 }, { 5862, 0x4000 }, + { 5863, 0x0100 }, { 5864, 0x0000 }, { 5864, 0x0000 }, { 5864, 0x0200 }, + { 5865, 0x0600 }, { 5867, 0x0008 }, { 5868, 0x0000 }, { 5868, 0x0000 }, + { 5868, 0x0000 }, { 5868, 0x0000 }, { 5868, 0x0000 }, { 5868, 0x0000 }, + /* 0x8b00 */ + { 5868, 0x0080 }, { 5869, 0x0000 }, { 5869, 0x0040 }, { 5870, 0x0000 }, + { 5870, 0x0000 }, { 5870, 0x0000 }, { 5870, 0x1040 }, { 5872, 0x0000 }, + { 5872, 0x0000 }, { 5872, 0x0000 }, { 5872, 0xefff }, { 5887, 0xf7fd }, + { 5901, 0xff7f }, { 5916, 0xfffe }, { 5931, 0xfbff }, { 5946, 0xffff }, + /* 0x8c00 */ + { 5962, 0xfdff }, { 5977, 0xbfff }, { 5992, 0xffff }, { 6008, 0x00ff }, + { 6016, 0x12c2 }, { 6021, 0x0420 }, { 6023, 0x0c06 }, { 6027, 0x0708 }, + { 6031, 0x1624 }, { 6036, 0x0110 }, { 6038, 0x0000 }, { 6038, 0x0000 }, + { 6038, 0x0000 }, { 6038, 0x0000 }, { 6038, 0x0000 }, { 6038, 0x0000 }, + /* 0x8d00 */ + { 6038, 0x0000 }, { 6038, 0xe000 }, { 6041, 0xfffe }, { 6056, 0xffff }, + { 6072, 0xffff }, { 6088, 0x7f79 }, { 6100, 0x28df }, { 6109, 0x00f9 }, + { 6115, 0x0c32 }, { 6120, 0x8012 }, { 6123, 0x0008 }, { 6124, 0xd53a }, + { 6133, 0xd858 }, { 6140, 0xecc2 }, { 6148, 0x9d18 }, { 6155, 0x2fa8 }, + /* 0x8e00 */ + { 6163, 0x9620 }, { 6168, 0xe010 }, { 6172, 0xd60c }, { 6179, 0x2622 }, + { 6184, 0x0f97 }, { 6193, 0x0206 }, { 6196, 0xb240 }, { 6201, 0x9055 }, + { 6207, 0x80a2 }, { 6211, 0x5011 }, { 6215, 0x9800 }, { 6218, 0x0404 }, + { 6220, 0x4000 }, { 6221, 0x0000 }, { 6221, 0x0000 }, { 6221, 0x0000 }, + /* 0x8f00 */ + { 6221, 0x0000 }, { 6221, 0x0000 }, { 6221, 0x0000 }, { 6221, 0x0000 }, + { 6221, 0x0000 }, { 6221, 0x0000 }, { 6221, 0xfbc0 }, { 6230, 0xffff }, + { 6246, 0xeffe }, { 6260, 0xdffb }, { 6274, 0x0b08 }, { 6278, 0x6243 }, + { 6284, 0x41b6 }, { 6291, 0xfb3b }, { 6303, 0x6f74 }, { 6313, 0x2389 }, + /* 0x9000 */ + { 6319, 0xae7f }, { 6331, 0xecd7 }, { 6342, 0xe047 }, { 6349, 0x5960 }, + { 6355, 0xa096 }, { 6361, 0x098f }, { 6368, 0x612c }, { 6374, 0xa030 }, + { 6378, 0x090d }, { 6383, 0x2aaa }, { 6390, 0xd44e }, { 6398, 0x4f7b }, + { 6409, 0xc4b2 }, { 6416, 0x388b }, { 6423, 0xa9c6 }, { 6431, 0x6110 }, + /* 0x9100 */ + { 6435, 0x0014 }, { 6437, 0x4200 }, { 6439, 0x800c }, { 6442, 0x0202 }, + { 6444, 0xfe48 }, { 6453, 0x6485 }, { 6459, 0xd63e }, { 6469, 0xe3f7 }, + { 6481, 0x3aa0 }, { 6487, 0x0c07 }, { 6492, 0xe40c }, { 6498, 0x0430 }, + { 6501, 0xf680 }, { 6508, 0x1002 }, { 6510, 0x0000 }, { 6510, 0x0000 }, + /* 0x9200 */ + { 6510, 0x0000 }, { 6510, 0x0000 }, { 6510, 0x0000 }, { 6510, 0x0000 }, + { 6510, 0x0000 }, { 6510, 0x0000 }, { 6510, 0x0000 }, { 6510, 0x0010 }, + { 6511, 0x4000 }, { 6512, 0x0000 }, { 6512, 0x4000 }, { 6513, 0x0000 }, + { 6513, 0x0100 }, { 6514, 0x0000 }, { 6514, 0x0000 }, { 6514, 0x0000 }, + /* 0x9300 */ + { 6514, 0x0000 }, { 6514, 0x0000 }, { 6514, 0x0000 }, { 6514, 0x4000 }, + { 6515, 0x0000 }, { 6515, 0x0000 }, { 6515, 0x0400 }, { 6516, 0x0000 }, + { 6516, 0x8000 }, { 6517, 0x0000 }, { 6517, 0x0000 }, { 6517, 0x0000 }, + { 6517, 0x0400 }, { 6518, 0x0040 }, { 6519, 0x0000 }, { 6519, 0x0000 }, + /* 0x9400 */ + { 6519, 0x0000 }, { 6519, 0x0000 }, { 6519, 0x0000 }, { 6519, 0x4000 }, + { 6520, 0x0000 }, { 6520, 0x0000 }, { 6520, 0x0800 }, { 6521, 0x0000 }, + { 6521, 0xffe0 }, { 6532, 0xfebd }, { 6545, 0xffff }, { 6561, 0xffff }, + { 6577, 0x7f7f }, { 6591, 0xfbe7 }, { 6604, 0xffbf }, { 6619, 0xf7ff }, + /* 0x9500 */ + { 6634, 0xffff }, { 6650, 0xefff }, { 6665, 0xff7e }, { 6679, 0xdff7 }, + { 6693, 0xf6f7 }, { 6706, 0xfbdf }, { 6720, 0xbffe }, { 6734, 0x804f }, + { 6740, 0x0000 }, { 6740, 0x0000 }, { 6740, 0x0000 }, { 6740, 0x0000 }, + { 6740, 0x0000 }, { 6740, 0x0000 }, { 6740, 0xef00 }, { 6747, 0x7fff }, + /* 0x9600 */ + { 6762, 0xff7f }, { 6777, 0xb6f7 }, { 6789, 0x4406 }, { 6793, 0xb87e }, + { 6803, 0x3bf5 }, { 6814, 0x8831 }, { 6819, 0x1796 }, { 6827, 0x00f4 }, + { 6832, 0xa960 }, { 6838, 0x1391 }, { 6844, 0x0080 }, { 6845, 0x7249 }, + { 6852, 0xf2f3 }, { 6863, 0x0024 }, { 6865, 0x8701 }, { 6870, 0x42c8 }, + /* 0x9700 */ + { 6875, 0xe3d3 }, { 6885, 0x5048 }, { 6889, 0x2400 }, { 6891, 0x4305 }, + { 6896, 0x0000 }, { 6896, 0x4a4c }, { 6902, 0x0227 }, { 6907, 0x1058 }, + { 6911, 0x2820 }, { 6914, 0x0116 }, { 6918, 0xa809 }, { 6923, 0x0014 }, + { 6925, 0x0000 }, { 6925, 0x0000 }, { 6925, 0x3ec0 }, { 6932, 0x0068 }, + /* 0x9800 */ + { 6935, 0x0000 }, { 6935, 0x0000 }, { 6935, 0x0000 }, { 6935, 0x0000 }, + { 6935, 0x0000 }, { 6935, 0x0000 }, { 6935, 0x0000 }, { 6935, 0xffe0 }, + { 6946, 0xb7ff }, { 6960, 0xfddb }, { 6973, 0x00f7 }, { 6980, 0x0000 }, + { 6980, 0x4000 }, { 6981, 0xc72e }, { 6990, 0x0180 }, { 6992, 0x0000 }, + /* 0x9900 */ + { 6992, 0x2000 }, { 6993, 0x0001 }, { 6994, 0x4000 }, { 6995, 0x0000 }, + { 6995, 0x0000 }, { 6995, 0x0030 }, { 6997, 0xffa8 }, { 7008, 0xb4f7 }, + { 7019, 0xadf3 }, { 7030, 0x03ff }, { 7040, 0x0120 }, { 7042, 0x0000 }, + { 7042, 0x0000 }, { 7042, 0x0000 }, { 7042, 0x0000 }, { 7042, 0x0000 }, + /* 0x9a00 */ + { 7042, 0x0000 }, { 7042, 0x0000 }, { 7042, 0x0000 }, { 7042, 0x0000 }, + { 7042, 0x0000 }, { 7042, 0x0000 }, { 7042, 0xf000 }, { 7046, 0xfffb }, + { 7061, 0x9df7 }, { 7073, 0xfdcf }, { 7086, 0x01bf }, { 7094, 0x15c3 }, + { 7101, 0x1827 }, { 7107, 0x810a }, { 7111, 0xa842 }, { 7116, 0x0a00 }, + /* 0x9b00 */ + { 7118, 0x8108 }, { 7121, 0x8008 }, { 7123, 0x8008 }, { 7125, 0x1804 }, + { 7128, 0xa3be }, { 7138, 0x0012 }, { 7140, 0x0000 }, { 7140, 0x0000 }, + { 7140, 0x0000 }, { 7140, 0x0000 }, { 7140, 0x0000 }, { 7140, 0x0000 }, + { 7140, 0x0000 }, { 7140, 0x0000 }, { 7140, 0x0000 }, { 7140, 0x0000 }, + /* 0x9c00 */ + { 7140, 0x0000 }, { 7140, 0x0000 }, { 7140, 0x0000 }, { 7140, 0x0000 }, + { 7140, 0x0000 }, { 7140, 0x0000 }, { 7140, 0x0000 }, { 7140, 0x9000 }, + { 7142, 0x69e6 }, { 7151, 0xdc37 }, { 7161, 0x6bff }, { 7174, 0x3dff }, + { 7187, 0xfcf8 }, { 7198, 0xf3f9 }, { 7210, 0x0004 }, +}; +static const Summary16 gb2312_uni2indx_page9e[27] = { + /* 0x9e00 */ + { 7211, 0x0000 }, { 7211, 0x8000 }, { 7212, 0xbf6f }, { 7225, 0xe7ee }, + { 7237, 0xdffe }, { 7251, 0x5da2 }, { 7259, 0x3fd8 }, { 7269, 0xc00b }, + { 7274, 0x0984 }, { 7278, 0xa00c }, { 7282, 0x0040 }, { 7283, 0x6910 }, + { 7288, 0xe210 }, { 7293, 0xb912 }, { 7300, 0x86a5 }, { 7307, 0x5a00 }, + /* 0x9f00 */ + { 7311, 0x6800 }, { 7314, 0x0289 }, { 7318, 0x9005 }, { 7322, 0x6a80 }, + { 7327, 0x0010 }, { 7328, 0x0003 }, { 7330, 0x0000 }, { 7330, 0x8000 }, + { 7331, 0x1ff9 }, { 7342, 0x8e00 }, { 7346, 0x0001 }, +}; +static const Summary16 gb2312_uni2indx_pageff[15] = { + /* 0xff00 */ + { 7347, 0xfffe }, { 7362, 0xffff }, { 7378, 0xffff }, { 7394, 0xffff }, + { 7410, 0xffff }, { 7426, 0x7fff }, { 7441, 0x0000 }, { 7441, 0x0000 }, + { 7441, 0x0000 }, { 7441, 0x0000 }, { 7441, 0x0000 }, { 7441, 0x0000 }, + { 7441, 0x0000 }, { 7441, 0x0000 }, { 7441, 0x002b }, +}; + +static int +gb2312_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (n >= 2) { + const Summary16 *summary = NULL; + if (wc < 0x0460) + summary = &gb2312_uni2indx_page00[(wc>>4)]; + else if (wc >= 0x2000 && wc < 0x2650) + summary = &gb2312_uni2indx_page20[(wc>>4)-0x200]; + else if (wc >= 0x3000 && wc < 0x3230) + summary = &gb2312_uni2indx_page30[(wc>>4)-0x300]; + else if (wc >= 0x4e00 && wc < 0x9cf0) + summary = &gb2312_uni2indx_page4e[(wc>>4)-0x4e0]; + else if (wc >= 0x9e00 && wc < 0x9fb0) + summary = &gb2312_uni2indx_page9e[(wc>>4)-0x9e0]; + else if (wc >= 0xff00 && wc < 0xfff0) + summary = &gb2312_uni2indx_pageff[(wc>>4)-0xff0]; + if (summary) { + unsigned short used = summary->used; + unsigned int i = wc & 0x0f; + if (used & ((unsigned short) 1 << i)) { + unsigned short c; + /* Keep in `used' only the bits 0..i-1. */ + used &= ((unsigned short) 1 << i) - 1; + /* Add `summary->indx' and the number of bits set in `used'. */ + used = (used & 0x5555) + ((used & 0xaaaa) >> 1); + used = (used & 0x3333) + ((used & 0xcccc) >> 2); + used = (used & 0x0f0f) + ((used & 0xf0f0) >> 4); + used = (used & 0x00ff) + (used >> 8); + c = gb2312_2charset[summary->indx + used]; + r[0] = (c >> 8); r[1] = (c & 0xff); + return 2; + } + } + return RET_ILSEQ; + } + return RET_TOOSMALL; +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/gbk_tab_to_h.c b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/gbk_tab_to_h.c new file mode 100644 index 0000000..0004ec2 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/gbk_tab_to_h.c @@ -0,0 +1,1020 @@ +/* $XFree86: xc/lib/X11/lcUniConv/cjk_tab_to_h.c,v 1.2 2000/12/04 18:49:31 dawes Exp $ */ + +/* 2009-02-17 : Create gbk_tab_to_h.c from + * cjk_tab_to_h.c to generate GBK(cp936ext) table correctly. + * + * + * Generates a CJK character set table from a .TXT table as found on + * ftp.unicode.org or in the X nls directory. + * Examples: + * + * ./gbk_tab_to_h CP936EXT cp936ext > cp936ext.h < CP936EXT.TXT + * + */ + +#include +#include +#include +#include + +typedef struct { + int start; + int end; +} Block; + +typedef struct { + int rows; /* number of possible values for the 1st byte */ + int cols; /* number of possible values for the 2nd byte */ + int (*row_byte) (int row); /* returns the 1st byte value for a given row */ + int (*col_byte) (int col); /* returns the 2nd byte value for a given col */ + int (*byte_row) (int byte); /* converts a 1st byte value to a row, else -1 */ + int (*byte_col) (int byte); /* converts a 2nd byte value to a col, else -1 */ + const char* check_row_expr; /* format string for 1st byte value checking */ + const char* check_col_expr; /* format string for 2nd byte value checking */ + const char* byte_row_expr; /* format string for 1st byte value to row */ + const char* byte_col_expr; /* format string for 2nd byte value to col */ + int** charset2uni; /* charset2uni[0..rows-1][0..cols-1] is valid */ + /* You'll understand the terms "row" and "col" when you buy Ken Lunde's book. + Once a row is fixed, choosing a "col" is the same as choosing a "cell". */ + int* charsetpage; /* charsetpage[0..rows]: how large is a page for a row */ + int ncharsetblocks; + Block* charsetblocks; /* blocks[0..nblocks-1] */ + int* uni2charset; /* uni2charset[0x0000..0xffff] */ +} Encoding; + +/* + * Outputs the file title. + */ +static void output_title (const char *charsetname) +{ + printf("\n"); + printf("/*\n"); + printf(" * %s\n", charsetname); + printf(" */\n"); + printf("\n"); +} + +/* + * Reads the charset2uni table from standard input. + */ +static void read_table (Encoding* enc) +{ + int row, col, i, i1, i2, c, j; + + enc->charset2uni = (int**) malloc(enc->rows*sizeof(int*)); + for (row = 0; row < enc->rows; row++) + enc->charset2uni[row] = (int*) malloc(enc->cols*sizeof(int)); + + for (row = 0; row < enc->rows; row++) + for (col = 0; col < enc->cols; col++) + enc->charset2uni[row][col] = 0xfffd; + + c = getc(stdin); + ungetc(c,stdin); + if (c == '#') { + /* Read a unicode.org style .TXT file. */ + for (;;) { + c = getc(stdin); + if (c == EOF) + break; + if (c == '\n' || c == ' ' || c == '\t') + continue; + if (c == '#') { + do { c = getc(stdin); } while (!(c == EOF || c == '\n')); + continue; + } + ungetc(c,stdin); + if (scanf("0x%x", &j) != 1) + exit(1); + i1 = j >> 8; + i2 = j & 0xff; + row = enc->byte_row(i1); + col = enc->byte_col(i2); + if (row < 0 || col < 0) { + fprintf(stderr, "lost entry for %02x %02x\n", i1, i2); + exit(1); + } + if (scanf(" 0x%x", &enc->charset2uni[row][col]) != 1) + exit(1); + } + } else { + /* Read a table of hexadecimal Unicode values. */ + for (i1 = 32; i1 < 132; i1++) + for (i2 = 32; i2 < 132; i2++) { + i = scanf("%x", &j); + if (i == EOF) + goto read_done; + if (i != 1) + exit(1); + if (j < 0 || j == 0xffff) + j = 0xfffd; + if (j != 0xfffd) { + if (enc->byte_row(i1) < 0 || enc->byte_col(i2) < 0) { + fprintf(stderr, "lost entry at %02x %02x\n", i1, i2); + exit (1); + } + enc->charset2uni[enc->byte_row(i1)][enc->byte_col(i2)] = j; + } + } + read_done: ; + } +} + +/* + * Computes the charsetpage[0..rows] array. + */ +static void find_charset2uni_pages (Encoding* enc) +{ + int row, col; + + enc->charsetpage = (int*) malloc((enc->rows+1)*sizeof(int)); + + for (row = 0; row <= enc->rows; row++) + enc->charsetpage[row] = 0; + + for (row = 0; row < enc->rows; row++) { + int used = 0; + for (col = 0; col < enc->cols; col++) + if (enc->charset2uni[row][col] != 0xfffd) + used = col+1; + enc->charsetpage[row] = used; + } +} + +/* + * Fills in nblocks and blocks. + */ +static void find_charset2uni_blocks (Encoding* enc) +{ + int n, row, lastrow; + + enc->charsetblocks = (Block*) malloc(enc->rows*sizeof(Block)); + + n = 0; + for (row = 0; row < enc->rows; row++) + if (enc->charsetpage[row] > 0 && (row == 0 || enc->charsetpage[row-1] == 0)) { + for (lastrow = row; enc->charsetpage[lastrow+1] > 0; lastrow++); + enc->charsetblocks[n].start = row * enc->cols; + enc->charsetblocks[n].end = lastrow * enc->cols + enc->charsetpage[lastrow]; + n++; + } + enc->ncharsetblocks = n; +} + +/* + * Outputs the charset to unicode table and function. + */ +static void output_charset2uni (const char* name, Encoding* enc) +{ + int row, col, lastrow, col_max, i, i1_min, i1_max; + + find_charset2uni_pages(enc); + + find_charset2uni_blocks(enc); + + for (row = 0; row < enc->rows; row++) + if (enc->charsetpage[row] > 0) { + if (row == 0 || enc->charsetpage[row-1] == 0) { + /* Start a new block. */ + for (lastrow = row; enc->charsetpage[lastrow+1] > 0; lastrow++); + printf("static const unsigned short %s_2uni_page%02x[%d] = {\n", + name, enc->row_byte(row), + (lastrow-row) * enc->cols + enc->charsetpage[lastrow]); + } + printf(" /""* 0x%02x *""/\n ", enc->row_byte(row)); + col_max = (enc->charsetpage[row+1] > 0 ? enc->cols : enc->charsetpage[row]); + for (col = 0; col < col_max; col++) { + printf(" 0x%04x,", enc->charset2uni[row][col]); + if ((col % 8) == 7 && (col+1 < col_max)) printf("\n "); + } + printf("\n"); + if (enc->charsetpage[row+1] == 0) { + /* End a block. */ + printf("};\n"); + } + } + printf("\n"); + + printf("static int\n"); + printf("%s_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n)\n", name); + printf("{\n"); + printf(" unsigned char c1 = s[0];\n"); + printf(" if ("); + for (i = 0; i < enc->ncharsetblocks; i++) { + i1_min = enc->row_byte(enc->charsetblocks[i].start / enc->cols); + i1_max = enc->row_byte((enc->charsetblocks[i].end-1) / enc->cols); + if (i > 0) + printf(" || "); + if (i1_min == i1_max) + printf("(c1 == 0x%02x)", i1_min); + else + printf("(c1 >= 0x%02x && c1 <= 0x%02x)", i1_min, i1_max); + } + printf(") {\n"); + printf(" if (n >= 2) {\n"); + printf(" unsigned char c2 = s[1];\n"); + printf(" if ("); + printf(enc->check_col_expr, "c2"); + printf(") {\n"); + printf(" unsigned int i = %d * (", enc->cols); + printf(enc->byte_row_expr, "c1"); + printf(") + ("); + printf(enc->byte_col_expr, "c2"); + printf(");\n"); + printf(" unsigned short wc = 0xfffd;\n"); + for (i = 0; i < enc->ncharsetblocks; i++) { + printf(" "); + if (i > 0) + printf("} else "); + if (i < enc->ncharsetblocks-1) + printf("if (i < %d) ", enc->charsetblocks[i+1].start); + printf("{\n"); + printf(" if (i < %d)\n", enc->charsetblocks[i].end); + printf(" wc = %s_2uni_page%02x[i", name, enc->row_byte(enc->charsetblocks[i].start / enc->cols)); + if (enc->charsetblocks[i].start > 0) + printf("-%d", enc->charsetblocks[i].start); + printf("];\n"); + } + printf(" }\n"); + printf(" if (wc != 0xfffd) {\n"); + printf(" *pwc = (ucs4_t) wc;\n"); + printf(" return 2;\n"); + printf(" }\n"); + printf(" }\n"); + printf(" return RET_ILSEQ;\n"); + printf(" }\n"); + printf(" return RET_TOOFEW(0);\n"); + printf(" }\n"); + printf(" return RET_ILSEQ;\n"); + printf("}\n"); + printf("\n"); +} + +/* + * Computes the uni2charset[0x0000..0xffff] array. + */ +static void invert (Encoding* enc) +{ + int row, col, j; + + enc->uni2charset = (int*) malloc(0x10000*sizeof(int)); + + for (j = 0; j < 0x10000; j++) + enc->uni2charset[j] = 0; + + for (row = 0; row < enc->rows; row++) + for (col = 0; col < enc->cols; col++) { + j = enc->charset2uni[row][col]; + if (j != 0xfffd) + enc->uni2charset[j] = 0x100 * enc->row_byte(row) + enc->col_byte(col); + } +} + +/* + * Outputs the unicode to charset table and function, using a linear array. + * (Suitable if the table is dense.) + */ +static void output_uni2charset_dense (const char* name, Encoding* enc) +{ + /* Like in 8bit_tab_to_h.c */ + bool pages[0x100]; + int line[0x2000]; + int tableno; + struct { int minline; int maxline; int usecount; } tables[0x2000]; + bool first; + int row, col, j, p, j1, j2, t; + + for (p = 0; p < 0x100; p++) + pages[p] = false; + for (row = 0; row < enc->rows; row++) + for (col = 0; col < enc->cols; col++) { + j = enc->charset2uni[row][col]; + if (j != 0xfffd) + pages[j>>8] = true; + } + for (j1 = 0; j1 < 0x2000; j1++) { + bool all_invalid = true; + for (j2 = 0; j2 < 8; j2++) { + j = 8*j1+j2; + if (enc->uni2charset[j] != 0) + all_invalid = false; + } + if (all_invalid) + line[j1] = -1; + else + line[j1] = 0; + } + tableno = 0; + for (j1 = 0; j1 < 0x2000; j1++) { + if (line[j1] >= 0) { + if (tableno > 0 + && ((j1 > 0 && line[j1-1] == tableno-1) + || ((tables[tableno-1].maxline >> 5) == (j1 >> 5) + && j1 - tables[tableno-1].maxline <= 8))) { + line[j1] = tableno-1; + tables[tableno-1].maxline = j1; + } else { + tableno++; + line[j1] = tableno-1; + tables[tableno-1].minline = tables[tableno-1].maxline = j1; + } + } + } + for (t = 0; t < tableno; t++) { + tables[t].usecount = 0; + j1 = 8*tables[t].minline; + j2 = 8*(tables[t].maxline+1); + for (j = j1; j < j2; j++) + if (enc->uni2charset[j] != 0) + tables[t].usecount++; + } + { + p = -1; + for (t = 0; t < tableno; t++) + if (tables[t].usecount > 1) { + //p = tables[t].minline >> 5; + p = tables[t].minline ; + //printf("static const unsigned short %s_page%02x[%d] = {\n", name, p, 8*(tables[t].maxline-tables[t].minline+1)); + printf("static const unsigned short %s_page%04x[%d] = {\n", name, p, 8*(tables[t].maxline-tables[t].minline+1)); + for (j1 = tables[t].minline; j1 <= tables[t].maxline; j1++) { + if ((j1 % 0x20) == 0 && j1 > tables[t].minline) + printf(" /* 0x%04x */\n", 8*j1); + printf(" "); + for (j2 = 0; j2 < 8; j2++) { + j = 8*j1+j2; + printf(" 0x%04x,", enc->uni2charset[j]); + } + printf(" /*0x%02x-0x%02x*/\n", 8*(j1 % 0x20), 8*(j1 % 0x20)+7); + } + printf("};\n"); + } + if (p >= 0) + printf("\n"); + } + printf("static int\n%s_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n)\n", name); + printf("{\n"); + printf(" if (n >= 2) {\n"); + printf(" unsigned short c = 0;\n"); + first = true; + for (j1 = 0; j1 < 0x2000;) { + t = line[j1]; + for (j2 = j1; j2 < 0x2000 && line[j2] == t; j2++); + if (t >= 0) { + if (j1 != tables[t].minline) abort(); + if (j2 > tables[t].maxline+1) abort(); + j2 = tables[t].maxline+1; + if (first) + printf(" "); + else + printf(" else "); + first = false; + if (tables[t].usecount == 0) abort(); + if (tables[t].usecount == 1) { + if (j2 != j1+1) abort(); + for (j = 8*j1; j < 8*j2; j++) + if (enc->uni2charset[j] != 0) { + printf("if (wc == 0x%04x)\n c = 0x%02x;\n", j, enc->uni2charset[j]); + break; + } + } else { + if (j1 == 0) { + printf("if (wc < 0x%04x)", 8*j2); + } else { + printf("if (wc >= 0x%04x && wc < 0x%04x)", 8*j1, 8*j2); + } + //printf("\n c = %s_page%02x[wc", name, j1 >> 5); + printf("\n c = %s_page%04x[wc", name, j1); + if (tables[t].minline > 0) + printf("-0x%04x", 8*j1); + printf("];\n"); + } + } + j1 = j2; + } + printf(" if (c != 0) {\n"); + printf(" r[0] = (c >> 8); r[1] = (c & 0xff);\n"); + printf(" return 2;\n"); + printf(" }\n"); + printf(" return RET_ILSEQ;\n"); + printf(" }\n"); + printf(" return RET_TOOSMALL;\n"); + printf("}\n"); +} + +/* + * Outputs the unicode to charset table and function, using a packed array. + * (Suitable if the table is sparse.) + */ +static void output_uni2charset_sparse (const char* name, Encoding* enc) +{ + bool pages[0x100]; + Block pageblocks[0x100]; int npageblocks; + int indx2charset[0x10000]; + int summary_indx[0x1000]; + int summary_used[0x1000]; + int i, row, col, j, p, j1, j2, indx; + + /* Fill pages[0x100]. */ + for (p = 0; p < 0x100; p++) + pages[p] = false; + for (row = 0; row < enc->rows; row++) + for (col = 0; col < enc->cols; col++) { + j = enc->charset2uni[row][col]; + if (j != 0xfffd) + pages[j>>8] = true; + } + +#if 0 + for (p = 0; p < 0x100; p++) + if (pages[p]) { + printf("static const unsigned short %s_page%02x[256] = {\n", name, p); + for (j1 = 0; j1 < 32; j1++) { + printf(" "); + for (j2 = 0; j2 < 8; j2++) + printf("0x%04x, ", enc->uni2charset[256*p+8*j1+j2]); + printf("/""*0x%02x-0x%02x*""/\n", 8*j1, 8*j1+7); + } + printf("};\n"); + } + printf("\n"); +#endif + + /* Fill summary_indx[] and summary_used[]. */ + indx = 0; + for (j1 = 0; j1 < 0x1000; j1++) { + summary_indx[j1] = indx; + summary_used[j1] = 0; + for (j2 = 0; j2 < 16; j2++) { + j = 16*j1+j2; + if (enc->uni2charset[j] != 0) { + indx2charset[indx++] = enc->uni2charset[j]; + summary_used[j1] |= (1 << j2); + } + } + } + + /* Fill npageblocks and pageblocks[]. */ + npageblocks = 0; + for (p = 0; p < 0x100; ) { + if (pages[p] && (p == 0 || !pages[p-1])) { + pageblocks[npageblocks].start = 16*p; + do p++; while (p < 0x100 && pages[p]); + j1 = 16*p; + while (summary_used[j1-1] == 0) j1--; + pageblocks[npageblocks].end = j1; + npageblocks++; + } else + p++; + } + + printf("static const unsigned short %s_2charset[%d] = {\n", name, indx); + for (i = 0; i < indx; ) { + if ((i % 8) == 0) printf(" "); + printf(" 0x%04x,", indx2charset[i]); + i++; + if ((i % 8) == 0 || i == indx) printf("\n"); + } + printf("};\n"); + printf("\n"); + for (i = 0; i < npageblocks; i++) { + printf("static const Summary16 %s_uni2indx_page%02x[%d] = {\n", name, + pageblocks[i].start/16, pageblocks[i].end-pageblocks[i].start); + for (j1 = pageblocks[i].start; j1 < pageblocks[i].end; ) { + if (((16*j1) % 0x100) == 0) printf(" /""* 0x%04x *""/\n", 16*j1); + if ((j1 % 4) == 0) printf(" "); + printf(" { %4d, 0x%04x },", summary_indx[j1], summary_used[j1]); + j1++; + if ((j1 % 4) == 0 || j1 == pageblocks[i].end) printf("\n"); + } + printf("};\n"); + } + printf("\n"); + + printf("static int\n"); + printf("%s_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n)\n", name); + printf("{\n"); + printf(" if (n >= 2) {\n"); + printf(" const Summary16 *summary = NULL;\n"); + for (i = 0; i < npageblocks; i++) { + printf(" "); + if (i > 0) + printf("else "); + printf("if (wc >= 0x%04x && wc < 0x%04x)\n", + 16*pageblocks[i].start, 16*pageblocks[i].end); + printf(" summary = &%s_uni2indx_page%02x[(wc>>4)", name, + pageblocks[i].start/16); + if (pageblocks[i].start > 0) + printf("-0x%03x", pageblocks[i].start); + printf("];\n"); + } + printf(" if (summary) {\n"); + printf(" unsigned short used = summary->used;\n"); + printf(" unsigned int i = wc & 0x0f;\n"); + printf(" if (used & ((unsigned short) 1 << i)) {\n"); + printf(" unsigned short c;\n"); + printf(" /* Keep in `used' only the bits 0..i-1. */\n"); + printf(" used &= ((unsigned short) 1 << i) - 1;\n"); + printf(" /* Add `summary->indx' and the number of bits set in `used'. */\n"); + printf(" used = (used & 0x5555) + ((used & 0xaaaa) >> 1);\n"); + printf(" used = (used & 0x3333) + ((used & 0xcccc) >> 2);\n"); + printf(" used = (used & 0x0f0f) + ((used & 0xf0f0) >> 4);\n"); + printf(" used = (used & 0x00ff) + (used >> 8);\n"); + printf(" c = %s_2charset[summary->indx + used];\n", name); + printf(" r[0] = (c >> 8); r[1] = (c & 0xff);\n"); + printf(" return 2;\n"); + printf(" }\n"); + printf(" }\n"); + printf(" return RET_ILSEQ;\n"); + printf(" }\n"); + printf(" return RET_TOOSMALL;\n"); + printf("}\n"); +} + +/* ISO-2022/EUC specifics */ + +static int row_byte_normal (int row) { return 0x21+row; } +static int col_byte_normal (int col) { return 0x21+col; } +static int byte_row_normal (int byte) { return byte-0x21; } +static int byte_col_normal (int byte) { return byte-0x21; } + +static void do_normal (const char* name) +{ + Encoding enc; + + enc.rows = 94; + enc.cols = 94; + enc.row_byte = row_byte_normal; + enc.col_byte = col_byte_normal; + enc.byte_row = byte_row_normal; + enc.byte_col = byte_col_normal; + enc.check_row_expr = "%1$s >= 0x21 && %1$s < 0x7f"; + enc.check_col_expr = "%1$s >= 0x21 && %1$s < 0x7f"; + enc.byte_row_expr = "%1$s - 0x21"; + enc.byte_col_expr = "%1$s - 0x21"; + + read_table(&enc); + output_charset2uni(name,&enc); + invert(&enc); output_uni2charset_sparse(name,&enc); +} + +/* Note: On first sight, the jisx0212_2charset[] table seems to be in order, + starting from the charset=0x3021/uni=0x4e02 pair. But it's only mostly in + order. There are 75 out-of-order values, scattered all throughout the table. + */ + +static void do_normal_only_charset2uni (const char* name) +{ + Encoding enc; + + enc.rows = 94; + enc.cols = 94; + enc.row_byte = row_byte_normal; + enc.col_byte = col_byte_normal; + enc.byte_row = byte_row_normal; + enc.byte_col = byte_col_normal; + enc.check_row_expr = "%1$s >= 0x21 && %1$s < 0x7f"; + enc.check_col_expr = "%1$s >= 0x21 && %1$s < 0x7f"; + enc.byte_row_expr = "%1$s - 0x21"; + enc.byte_col_expr = "%1$s - 0x21"; + + read_table(&enc); + output_charset2uni(name,&enc); +} + +/* CNS 11643 specifics - trick to put two tables into one */ + +static int row_byte_cns11643 (int row) { + return 0x100 * (row / 94) + (row % 94) + 0x21; +} +static int byte_row_cns11643 (int byte) { + return (byte >= 0x100 && byte < 0x200 ? byte-0x121 : + byte >= 0x200 && byte < 0x300 ? byte-0x221+94 : + byte >= 0x300 && byte < 0x400 ? byte-0x321+2*94 : + -1); +} + +static void do_cns11643_only_uni2charset (const char* name) +{ + Encoding enc; + int j, x; + + enc.rows = 3*94; + enc.cols = 94; + enc.row_byte = row_byte_cns11643; + enc.col_byte = col_byte_normal; + enc.byte_row = byte_row_cns11643; + enc.byte_col = byte_col_normal; + enc.check_row_expr = "%1$s >= 0x21 && %1$s < 0x7f"; + enc.check_col_expr = "%1$s >= 0x21 && %1$s < 0x7f"; + enc.byte_row_expr = "%1$s - 0x21"; + enc.byte_col_expr = "%1$s - 0x21"; + + read_table(&enc); + invert(&enc); + /* Move the 2 plane bits into the unused bits 15 and 7. */ + for (j = 0; j < 0x10000; j++) { + x = enc.uni2charset[j]; + if (x != 0) { + if (x & 0x8080) abort(); + switch (x >> 16) { + case 0: /* plane 1 */ x = (x & 0xffff) | 0x0000; break; + case 1: /* plane 2 */ x = (x & 0xffff) | 0x0080; break; + case 2: /* plane 3 */ x = (x & 0xffff) | 0x8000; break; + default: abort(); + } + enc.uni2charset[j] = x; + } + } + output_uni2charset_sparse(name,&enc); +} + +/* GBK specifics */ + +static int row_byte_gbk1 (int row) { + return 0x81+row; +} +static int col_byte_gbk1 (int col) { + return (col >= 0x3f ? 0x41 : 0x40) + col; +} +static int byte_row_gbk1 (int byte) { + if (byte >= 0x81 && byte < 0xff) + return byte-0x81; + else + return -1; +} +static int byte_col_gbk1 (int byte) { + if (byte >= 0x40 && byte < 0x7f) + return byte-0x40; + else if (byte >= 0x80 && byte < 0xff) + return byte-0x41; + else + return -1; +} + +static void do_gbk1 (const char* name) +{ + Encoding enc; + + enc.rows = 126; + enc.cols = 190; + enc.row_byte = row_byte_gbk1; + enc.col_byte = col_byte_gbk1; + enc.byte_row = byte_row_gbk1; + enc.byte_col = byte_col_gbk1; + enc.check_row_expr = "%1$s >= 0x81 && %1$s < 0xff"; + enc.check_col_expr = "(%1$s >= 0x40 && %1$s < 0x7f) || (%1$s >= 0x80 && %1$s < 0xff)"; + enc.byte_row_expr = "%1$s - 0x81"; + enc.byte_col_expr = "%1$s - (%1$s >= 0x80 ? 0x41 : 0x40)"; + + read_table(&enc); + output_charset2uni(name,&enc); + invert(&enc); output_uni2charset_dense(name,&enc); +} + +static void do_gbk1_only_charset2uni (const char* name) +{ + Encoding enc; + + enc.rows = 126; + enc.cols = 190; + enc.row_byte = row_byte_gbk1; + enc.col_byte = col_byte_gbk1; + enc.byte_row = byte_row_gbk1; + enc.byte_col = byte_col_gbk1; + enc.check_row_expr = "%1$s >= 0x81 && %1$s < 0xff"; + enc.check_col_expr = "(%1$s >= 0x40 && %1$s < 0x7f) || (%1$s >= 0x80 && %1$s < 0xff)"; + enc.byte_row_expr = "%1$s - 0x81"; + enc.byte_col_expr = "%1$s - (%1$s >= 0x80 ? 0x41 : 0x40)"; + + read_table(&enc); + output_charset2uni(name,&enc); +} + +static int row_byte_gbk2 (int row) { + return 0x81+row; +} +static int col_byte_gbk2 (int col) { + return (col >= 0x3f ? 0x41 : 0x40) + col; +} +static int byte_row_gbk2 (int byte) { + if (byte >= 0x81 && byte < 0xff) + return byte-0x81; + else + return -1; +} +static int byte_col_gbk2 (int byte) { + if (byte >= 0x40 && byte < 0x7f) + return byte-0x40; + else if (byte >= 0x80 && byte < 0xa1) + return byte-0x41; + else + return -1; +} + +static void do_gbk2_only_charset2uni (const char* name) +{ + Encoding enc; + + enc.rows = 126; + enc.cols = 96; + enc.row_byte = row_byte_gbk2; + enc.col_byte = col_byte_gbk2; + enc.byte_row = byte_row_gbk2; + enc.byte_col = byte_col_gbk2; + enc.check_row_expr = "%1$s >= 0x81 && %1$s < 0xff"; + enc.check_col_expr = "(%1$s >= 0x40 && %1$s < 0x7f) || (%1$s >= 0x80 && %1$s < 0xa1)"; + enc.byte_row_expr = "%1$s - 0x81"; + enc.byte_col_expr = "%1$s - (%1$s >= 0x80 ? 0x41 : 0x40)"; + + read_table(&enc); + output_charset2uni(name,&enc); +} + +static void do_gbk1_only_uni2charset (const char* name) +{ + Encoding enc; + + enc.rows = 126; + enc.cols = 190; + enc.row_byte = row_byte_gbk1; + enc.col_byte = col_byte_gbk1; + enc.byte_row = byte_row_gbk1; + enc.byte_col = byte_col_gbk1; + enc.check_row_expr = "%1$s >= 0x81 && %1$s < 0xff"; + enc.check_col_expr = "(%1$s >= 0x40 && %1$s < 0x7f) || (%1$s >= 0x80 && %1$s < 0xff)"; + enc.byte_row_expr = "%1$s - 0x81"; + enc.byte_col_expr = "%1$s - (%1$s >= 0x80 ? 0x41 : 0x40)"; + + read_table(&enc); + invert(&enc); output_uni2charset_sparse(name,&enc); +} + +/* KSC 5601 specifics */ + +/* + * Reads the charset2uni table from standard input. + */ +static void read_table_ksc5601 (Encoding* enc) +{ + int row, col, i, i1, i2, c, j; + + enc->charset2uni = (int**) malloc(enc->rows*sizeof(int*)); + for (row = 0; row < enc->rows; row++) + enc->charset2uni[row] = (int*) malloc(enc->cols*sizeof(int)); + + for (row = 0; row < enc->rows; row++) + for (col = 0; col < enc->cols; col++) + enc->charset2uni[row][col] = 0xfffd; + + c = getc(stdin); + ungetc(c,stdin); + if (c == '#') { + /* Read a unicode.org style .TXT file. */ + for (;;) { + c = getc(stdin); + if (c == EOF) + break; + if (c == '\n' || c == ' ' || c == '\t') + continue; + if (c == '#') { + do { c = getc(stdin); } while (!(c == EOF || c == '\n')); + continue; + } + ungetc(c,stdin); + if (scanf("0x%x", &j) != 1) + exit(1); + i1 = j >> 8; + i2 = j & 0xff; + if (scanf(" 0x%x", &j) != 1) + exit(1); + /* Take only the range covered by KS C 5601.1987-0 = KS C 5601.1989-0 + = KS X 1001.1992, ignore the rest. */ + if (!(i1 >= 128+33 && i1 < 128+127 && i2 >= 128+33 && i2 < 128+127)) + continue; /* KSC5601 specific */ + i1 &= 0x7f; /* KSC5601 specific */ + i2 &= 0x7f; /* KSC5601 specific */ + row = enc->byte_row(i1); + col = enc->byte_col(i2); + if (row < 0 || col < 0) { + fprintf(stderr, "lost entry for %02x %02x\n", i1, i2); + exit(1); + } + enc->charset2uni[row][col] = j; + } + } else { + /* Read a table of hexadecimal Unicode values. */ + for (i1 = 33; i1 < 127; i1++) + for (i2 = 33; i2 < 127; i2++) { + i = scanf("%x", &j); + if (i == EOF) + goto read_done; + if (i != 1) + exit(1); + if (j < 0 || j == 0xffff) + j = 0xfffd; + if (j != 0xfffd) { + if (enc->byte_row(i1) < 0 || enc->byte_col(i2) < 0) { + fprintf(stderr, "lost entry at %02x %02x\n", i1, i2); + exit (1); + } + enc->charset2uni[enc->byte_row(i1)][enc->byte_col(i2)] = j; + } + } + read_done: ; + } +} + +static void do_ksc5601 (const char* name) +{ + Encoding enc; + + enc.rows = 94; + enc.cols = 94; + enc.row_byte = row_byte_normal; + enc.col_byte = col_byte_normal; + enc.byte_row = byte_row_normal; + enc.byte_col = byte_col_normal; + enc.check_row_expr = "%1$s >= 0x21 && %1$s < 0x7f"; + enc.check_col_expr = "%1$s >= 0x21 && %1$s < 0x7f"; + enc.byte_row_expr = "%1$s - 0x21"; + enc.byte_col_expr = "%1$s - 0x21"; + + read_table_ksc5601(&enc); + output_charset2uni(name,&enc); + invert(&enc); output_uni2charset_sparse(name,&enc); +} + +/* Big5 specifics */ + +static int row_byte_big5 (int row) { + return 0xa1+row; +} +static int col_byte_big5 (int col) { + return (col >= 0x3f ? 0x62 : 0x40) + col; +} +static int byte_row_big5 (int byte) { + if (byte >= 0xa1 && byte < 0xff) + return byte-0xa1; + else + return -1; +} +static int byte_col_big5 (int byte) { + if (byte >= 0x40 && byte < 0x7f) + return byte-0x40; + else if (byte >= 0xa1 && byte < 0xff) + return byte-0x62; + else + return -1; +} + +static void do_big5 (const char* name) +{ + Encoding enc; + + enc.rows = 94; + enc.cols = 157; + enc.row_byte = row_byte_big5; + enc.col_byte = col_byte_big5; + enc.byte_row = byte_row_big5; + enc.byte_col = byte_col_big5; + enc.check_row_expr = "%1$s >= 0xa1 && %1$s < 0xff"; + enc.check_col_expr = "(%1$s >= 0x40 && %1$s < 0x7f) || (%1$s >= 0xa1 && %1$s < 0xff)"; + enc.byte_row_expr = "%1$s - 0xa1"; + enc.byte_col_expr = "%1$s - (%1$s >= 0xa1 ? 0x62 : 0x40)"; + + read_table(&enc); + output_charset2uni(name,&enc); + invert(&enc); output_uni2charset_sparse(name,&enc); +} + +/* Johab Hangul specifics */ + +static int row_byte_johab_hangul (int row) { + return 0x84+row; +} +static int col_byte_johab_hangul (int col) { + return (col >= 0x3e ? 0x43 : 0x41) + col; +} +static int byte_row_johab_hangul (int byte) { + if (byte >= 0x84 && byte < 0xd4) + return byte-0x84; + else + return -1; +} +static int byte_col_johab_hangul (int byte) { + if (byte >= 0x41 && byte < 0x7f) + return byte-0x41; + else if (byte >= 0x81 && byte < 0xff) + return byte-0x43; + else + return -1; +} + +static void do_johab_hangul (const char* name) +{ + Encoding enc; + + enc.rows = 80; + enc.cols = 188; + enc.row_byte = row_byte_johab_hangul; + enc.col_byte = col_byte_johab_hangul; + enc.byte_row = byte_row_johab_hangul; + enc.byte_col = byte_col_johab_hangul; + enc.check_row_expr = "%1$s >= 0x84 && %1$s < 0xd4"; + enc.check_col_expr = "(%1$s >= 0x41 && %1$s < 0x7f) || (%1$s >= 0x81 && %1$s < 0xff)"; + enc.byte_row_expr = "%1$s - 0x84"; + enc.byte_col_expr = "%1$s - (%1$s >= 0x81 ? 0x43 : 0x41)"; + + read_table(&enc); + output_charset2uni(name,&enc); + invert(&enc); output_uni2charset_dense(name,&enc); +} + +/* SJIS specifics */ + +static int row_byte_sjis (int row) { + return (row >= 0x1f ? 0xc1 : 0x81) + row; +} +static int col_byte_sjis (int col) { + return (col >= 0x3f ? 0x41 : 0x40) + col; +} +static int byte_row_sjis (int byte) { + if (byte >= 0x81 && byte < 0xa0) + return byte-0x81; + else if (byte >= 0xe0) + return byte-0xc1; + else + return -1; +} +static int byte_col_sjis (int byte) { + if (byte >= 0x40 && byte < 0x7f) + return byte-0x40; + else if (byte >= 0x80 && byte < 0xfd) + return byte-0x41; + else + return -1; +} + +static void do_sjis (const char* name) +{ + Encoding enc; + + enc.rows = 94; + enc.cols = 188; + enc.row_byte = row_byte_sjis; + enc.col_byte = col_byte_sjis; + enc.byte_row = byte_row_sjis; + enc.byte_col = byte_col_sjis; + enc.check_row_expr = "(%1$s >= 0x81 && %1$s < 0xa0) || (%1$s >= 0xe0)"; + enc.check_col_expr = "(%1$s >= 0x40 && %1$s < 0x7f) || (%1$s >= 0x80 && %1$s < 0xfd)"; + enc.byte_row_expr = "%1$s - (%1$s >= 0xe0 ? 0xc1 : 0x81)"; + enc.byte_col_expr = "%1$s - (%1$s >= 0x80 ? 0x41 : 0x40)"; + + read_table(&enc); + output_charset2uni(name,&enc); + invert(&enc); output_uni2charset_sparse(name,&enc); +} + +/* Main program */ + +int main (int argc, char *argv[]) +{ + const char* charsetname; + const char* name; + + if (argc != 3) + exit(1); + charsetname = argv[1]; + name = argv[2]; + + output_title(charsetname); + + if (!strcmp(name,"gb2312") || !strcmp(name,"gb12345ext") + || !strcmp(name,"jisx0208") || !strcmp(name,"jisx0212")) + do_normal(name); + else if (!strcmp(name,"cns11643_1") || !strcmp(name,"cns11643_2") + || !strcmp(name,"cns11643_3")) + do_normal_only_charset2uni(name); + else if (!strcmp(name,"cns11643_inv")) + do_cns11643_only_uni2charset(name); + else if (!strcmp(name,"gbkext1")) + do_gbk1_only_charset2uni(name); + else if (!strcmp(name,"gbkext2")) + do_gbk2_only_charset2uni(name); + else if (!strcmp(name,"gbkext_inv")) + do_gbk1_only_uni2charset(name); + else if (!strcmp(name,"cp936ext")) + do_gbk1(name); + else if (!strcmp(name,"ksc5601")) + do_ksc5601(name); + else if (!strcmp(name,"big5") || !strcmp(name,"cp950ext")) + do_big5(name); + else if (!strcmp(name,"johab_hangul")) + do_johab_hangul(name); + else if (!strcmp(name,"cp932ext")) + do_sjis(name); + else + exit(1); + + return 0; +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/georgian_academy.h b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/georgian_academy.h new file mode 100644 index 0000000..a847c52 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/georgian_academy.h @@ -0,0 +1,88 @@ +/* $XFree86: xc/lib/X11/lcUniConv/georgian_academy.h,v 1.3 2000/11/29 17:40:29 dawes Exp $ */ + +/* + * GEORGIAN-ACADEMY + */ + +static const unsigned short georgian_academy_2uni[32] = { + /* 0x80 */ + 0x0080, 0x0081, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, + 0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, 0x008d, 0x008e, 0x008f, + /* 0x90 */ + 0x0090, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + 0x02dc, 0x2122, 0x0161, 0x203a, 0x0153, 0x009d, 0x009e, 0x0178, +}; + +static int +georgian_academy_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c >= 0x80 && c < 0xa0) + *pwc = (ucs4_t) georgian_academy_2uni[c-0x80]; + else if (c >= 0xc0 && c < 0xe7) + *pwc = (ucs4_t) c + 0x1010; + else + *pwc = (ucs4_t) c; + return 1; +} + +static const unsigned char georgian_academy_page00[32] = { + 0x80, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x8d, 0x8e, 0x8f, /* 0x88-0x8f */ + 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x9d, 0x9e, 0x00, /* 0x98-0x9f */ +}; +static const unsigned char georgian_academy_page01[72] = { + 0x00, 0x00, 0x8c, 0x9c, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x8a, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x9f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ +}; +static const unsigned char georgian_academy_page02[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ +}; +static const unsigned char georgian_academy_page20[48] = { + 0x00, 0x00, 0x00, 0x96, 0x97, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x91, 0x92, 0x82, 0x00, 0x93, 0x94, 0x84, 0x00, /* 0x18-0x1f */ + 0x86, 0x87, 0x95, 0x00, 0x00, 0x00, 0x85, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x8b, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ +}; + +static int +georgian_academy_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x0080 && wc < 0x00a0) + c = georgian_academy_page00[wc-0x0080]; + else if ((wc >= 0x00a0 && wc < 0x00c0) || (wc >= 0x00e7 && wc < 0x0100)) + c = wc; + else if (wc >= 0x0150 && wc < 0x0198) + c = georgian_academy_page01[wc-0x0150]; + else if (wc >= 0x02c0 && wc < 0x02e0) + c = georgian_academy_page02[wc-0x02c0]; + else if (wc >= 0x10d0 && wc < 0x10f7) + c = wc-0x1010; + else if (wc >= 0x2010 && wc < 0x2040) + c = georgian_academy_page20[wc-0x2010]; + else if (wc == 0x2122) + c = 0x99; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILSEQ; +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/georgian_ps.h b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/georgian_ps.h new file mode 100644 index 0000000..e7220d0 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/georgian_ps.h @@ -0,0 +1,105 @@ +/* $XFree86: xc/lib/X11/lcUniConv/georgian_ps.h,v 1.3 2000/11/29 17:40:29 dawes Exp $ */ + +/* + * GEORGIAN-PS + */ + +static const unsigned short georgian_ps_2uni_1[32] = { + /* 0x80 */ + 0x0080, 0x0081, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, + 0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, 0x008d, 0x008e, 0x008f, + /* 0x90 */ + 0x0090, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + 0x02dc, 0x2122, 0x0161, 0x203a, 0x0153, 0x009d, 0x009e, 0x0178, +}; +static const unsigned short georgian_ps_2uni_2[39] = { + /* 0xc0 */ + 0x10d0, 0x10d1, 0x10d2, 0x10d3, 0x10d4, 0x10d5, 0x10d6, 0x10f1, + 0x10d7, 0x10d8, 0x10d9, 0x10da, 0x10db, 0x10dc, 0x10f2, 0x10dd, + /* 0xd0 */ + 0x10de, 0x10df, 0x10e0, 0x10e1, 0x10e2, 0x10f3, 0x10e3, 0x10e4, + 0x10e5, 0x10e6, 0x10e7, 0x10e8, 0x10e9, 0x10ea, 0x10eb, 0x10ec, + /* 0xe0 */ + 0x10ed, 0x10ee, 0x10f4, 0x10ef, 0x10f0, 0x10f5, +}; + +static int +georgian_ps_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c >= 0x80 && c < 0xa0) + *pwc = (ucs4_t) georgian_ps_2uni_1[c-0x80]; + else if (c >= 0xc0 && c < 0xe6) + *pwc = (ucs4_t) georgian_ps_2uni_2[c-0xc0]; + else + *pwc = (ucs4_t) c; + return 1; +} + +static const unsigned char georgian_ps_page00[32] = { + 0x80, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x8d, 0x8e, 0x8f, /* 0x88-0x8f */ + 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x9d, 0x9e, 0x00, /* 0x98-0x9f */ +}; +static const unsigned char georgian_ps_page01[72] = { + 0x00, 0x00, 0x8c, 0x9c, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x8a, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x9f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ +}; +static const unsigned char georgian_ps_page02[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ +}; +static const unsigned char georgian_ps_page10[40] = { + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc8, /* 0xd0-0xd7 */ + 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xcf, 0xd0, 0xd1, /* 0xd8-0xdf */ + 0xd2, 0xd3, 0xd4, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, /* 0xe0-0xe7 */ + 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe3, /* 0xe8-0xef */ + 0xe4, 0xc7, 0xce, 0xd5, 0xe2, 0xe5, 0x00, 0x00, /* 0xf0-0xf7 */ +}; +static const unsigned char georgian_ps_page20[48] = { + 0x00, 0x00, 0x00, 0x96, 0x97, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x91, 0x92, 0x82, 0x00, 0x93, 0x94, 0x84, 0x00, /* 0x18-0x1f */ + 0x86, 0x87, 0x95, 0x00, 0x00, 0x00, 0x85, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x8b, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ +}; + +static int +georgian_ps_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x0080 && wc < 0x00a0) + c = georgian_ps_page00[wc-0x0080]; + else if ((wc >= 0x00a0 && wc < 0x00c0) || (wc >= 0x00e6 && wc < 0x0100)) + c = wc; + else if (wc >= 0x0150 && wc < 0x0198) + c = georgian_ps_page01[wc-0x0150]; + else if (wc >= 0x02c0 && wc < 0x02e0) + c = georgian_ps_page02[wc-0x02c0]; + else if (wc >= 0x10d0 && wc < 0x10f8) + c = georgian_ps_page10[wc-0x10d0]; + else if (wc >= 0x2010 && wc < 0x2040) + c = georgian_ps_page20[wc-0x2010]; + else if (wc == 0x2122) + c = 0x99; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILSEQ; +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_1.h b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_1.h new file mode 100644 index 0000000..a600899 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_1.h @@ -0,0 +1,23 @@ +/* $XFree86: xc/lib/X11/lcUniConv/iso8859_1.h,v 1.3 2000/11/29 17:40:30 dawes Exp $ */ + +/* + * ISO-8859-1 + */ + +static int +iso8859_1_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + *pwc = (ucs4_t) c; + return 1; +} + +static int +iso8859_1_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (wc < 0x0100) { + *r = wc; + return 1; + } + return RET_ILSEQ; +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_10.h b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_10.h new file mode 100644 index 0000000..b63de3e --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_10.h @@ -0,0 +1,88 @@ +/* $XFree86: xc/lib/X11/lcUniConv/iso8859_10.h,v 1.3 2000/11/29 17:40:30 dawes Exp $ */ + +/* + * ISO-8859-10 + */ + +static const unsigned short iso8859_10_2uni[96] = { + /* 0xa0 */ + 0x00a0, 0x0104, 0x0112, 0x0122, 0x012a, 0x0128, 0x0136, 0x00a7, + 0x013b, 0x0110, 0x0160, 0x0166, 0x017d, 0x00ad, 0x016a, 0x014a, + /* 0xb0 */ + 0x00b0, 0x0105, 0x0113, 0x0123, 0x012b, 0x0129, 0x0137, 0x00b7, + 0x013c, 0x0111, 0x0161, 0x0167, 0x017e, 0x2015, 0x016b, 0x014b, + /* 0xc0 */ + 0x0100, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x012e, + 0x010c, 0x00c9, 0x0118, 0x00cb, 0x0116, 0x00cd, 0x00ce, 0x00cf, + /* 0xd0 */ + 0x00d0, 0x0145, 0x014c, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x0168, + 0x00d8, 0x0172, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, + /* 0xe0 */ + 0x0101, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x012f, + 0x010d, 0x00e9, 0x0119, 0x00eb, 0x0117, 0x00ed, 0x00ee, 0x00ef, + /* 0xf0 */ + 0x00f0, 0x0146, 0x014d, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x0169, + 0x00f8, 0x0173, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x0138, +}; + +static int +iso8859_10_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0xa0) + *pwc = (ucs4_t) c; + else + *pwc = (ucs4_t) iso8859_10_2uni[c-0xa0]; + return 1; +} + +static const unsigned char iso8859_10_page00[224] = { + 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xad, 0x00, 0x00, /* 0xa8-0xaf */ + 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb7, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0x00, /* 0xc0-0xc7 */ + 0x00, 0xc9, 0x00, 0xcb, 0x00, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */ + 0xd0, 0x00, 0x00, 0xd3, 0xd4, 0xd5, 0xd6, 0x00, /* 0xd0-0xd7 */ + 0xd8, 0x00, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, /* 0xd8-0xdf */ + 0x00, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0x00, /* 0xe0-0xe7 */ + 0x00, 0xe9, 0x00, 0xeb, 0x00, 0xed, 0xee, 0xef, /* 0xe8-0xef */ + 0xf0, 0x00, 0x00, 0xf3, 0xf4, 0xf5, 0xf6, 0x00, /* 0xf0-0xf7 */ + 0xf8, 0x00, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0x00, /* 0xf8-0xff */ + /* 0x0100 */ + 0xc0, 0xe0, 0x00, 0x00, 0xa1, 0xb1, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0xc8, 0xe8, 0x00, 0x00, /* 0x08-0x0f */ + 0xa9, 0xb9, 0xa2, 0xb2, 0x00, 0x00, 0xcc, 0xec, /* 0x10-0x17 */ + 0xca, 0xea, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0xa3, 0xb3, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0xa5, 0xb5, 0xa4, 0xb4, 0x00, 0x00, 0xc7, 0xe7, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0xb6, /* 0x30-0x37 */ + 0xff, 0x00, 0x00, 0xa8, 0xb8, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xd1, 0xf1, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0xaf, 0xbf, 0xd2, 0xf2, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0xaa, 0xba, 0x00, 0x00, 0x00, 0x00, 0xab, 0xbb, /* 0x60-0x67 */ + 0xd7, 0xf7, 0xae, 0xbe, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0xd9, 0xf9, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xac, 0xbc, 0x00, /* 0x78-0x7f */ +}; + +static int +iso8859_10_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x00a0) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x0180) + c = iso8859_10_page00[wc-0x00a0]; + else if (wc == 0x2015) + c = 0xbd; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILSEQ; +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_11.h b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_11.h new file mode 100644 index 0000000..ced0b3f --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_11.h @@ -0,0 +1,78 @@ +/* $XFree86: xc/lib/X11/lcUniConv/iso8859_11.h,v 1.2 2002/10/09 16:38:19 tsi Exp $ */ + +/* + * ISO8859-11 + */ + +static const unsigned short iso8859_11_2uni[96] = { + /* 0xa0 */ + 0x00a0, 0x0e01, 0x0e02, 0x0e03, 0x0e04, 0x0e05, 0x0e06, 0x0e07, + 0x0e08, 0x0e09, 0x0e0a, 0x0e0b, 0x0e0c, 0x0e0d, 0x0e0e, 0x0e0f, + /* 0xb0 */ + 0x0e10, 0x0e11, 0x0e12, 0x0e13, 0x0e14, 0x0e15, 0x0e16, 0x0e17, + 0x0e18, 0x0e19, 0x0e1a, 0x0e1b, 0x0e1c, 0x0e1d, 0x0e1e, 0x0e1f, + /* 0xc0 */ + 0x0e20, 0x0e21, 0x0e22, 0x0e23, 0x0e24, 0x0e25, 0x0e26, 0x0e27, + 0x0e28, 0x0e29, 0x0e2a, 0x0e2b, 0x0e2c, 0x0e2d, 0x0e2e, 0x0e2f, + /* 0xd0 */ + 0x0e30, 0x0e31, 0x0e32, 0x0e33, 0x0e34, 0x0e35, 0x0e36, 0x0e37, + 0x0e38, 0x0e39, 0x0e3a, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x0e3f, + /* 0xe0 */ + 0x0e40, 0x0e41, 0x0e42, 0x0e43, 0x0e44, 0x0e45, 0x0e46, 0x0e47, + 0x0e48, 0x0e49, 0x0e4a, 0x0e4b, 0x0e4c, 0x0e4d, 0x0e4e, 0x0e4f, + /* 0xf0 */ + 0x0e50, 0x0e51, 0x0e52, 0x0e53, 0x0e54, 0x0e55, 0x0e56, 0x0e57, + 0x0e58, 0x0e59, 0x0e5a, 0x0e5b, 0xfffd, 0xfffd, 0xfffd, 0xfffd, +}; + +static int +iso8859_11_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) { + *pwc = (ucs4_t) c; + return 1; + } + else if (c < 0xa0) { + } + else { + unsigned short wc = iso8859_11_2uni[c-0xa0]; + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 1; + } + } + return RET_ILSEQ; +} + +static const unsigned char iso8859_11_page0e[96] = { + 0x00, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0x00-0x07 */ + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0x08-0x0f */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0x10-0x17 */ + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, /* 0x18-0x1f */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0x20-0x27 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0x28-0x2f */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0x30-0x37 */ + 0xd8, 0xd9, 0xda, 0x00, 0x00, 0x00, 0x00, 0xdf, /* 0x38-0x3f */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0x40-0x47 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0x48-0x4f */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0x50-0x57 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ +}; + +static int +iso8859_11_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080 || wc == 0x00a0) { + *r = wc; + return 1; + } + else if (wc >= 0x0e00 && wc < 0x0e60) + c = iso8859_11_page0e[wc-0x0e00]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILSEQ; +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_13.h b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_13.h new file mode 100644 index 0000000..fe1d767 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_13.h @@ -0,0 +1,91 @@ +/* $XFree86: xc/lib/X11/lcUniConv/iso8859_13.h,v 1.2 2000/11/28 16:10:26 dawes Exp $ */ + +/* + * ISO-8859-13 + */ + +static const unsigned short iso8859_13_2uni[96] = { + /* 0xa0 */ + 0x00a0, 0x201d, 0x00a2, 0x00a3, 0x00a4, 0x201e, 0x00a6, 0x00a7, + 0x00d8, 0x00a9, 0x0156, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00c6, + /* 0xb0 */ + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x201c, 0x00b5, 0x00b6, 0x00b7, + 0x00f8, 0x00b9, 0x0157, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00e6, + /* 0xc0 */ + 0x0104, 0x012e, 0x0100, 0x0106, 0x00c4, 0x00c5, 0x0118, 0x0112, + 0x010c, 0x00c9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012a, 0x013b, + /* 0xd0 */ + 0x0160, 0x0143, 0x0145, 0x00d3, 0x014c, 0x00d5, 0x00d6, 0x00d7, + 0x0172, 0x0141, 0x015a, 0x016a, 0x00dc, 0x017b, 0x017d, 0x00df, + /* 0xe0 */ + 0x0105, 0x012f, 0x0101, 0x0107, 0x00e4, 0x00e5, 0x0119, 0x0113, + 0x010d, 0x00e9, 0x017a, 0x0117, 0x0123, 0x0137, 0x012b, 0x013c, + /* 0xf0 */ + 0x0161, 0x0144, 0x0146, 0x00f3, 0x014d, 0x00f5, 0x00f6, 0x00f7, + 0x0173, 0x0142, 0x015b, 0x016b, 0x00fc, 0x017c, 0x017e, 0x2019, +}; + +static int +iso8859_13_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0xa0) + *pwc = (ucs4_t) c; + else + *pwc = (ucs4_t) iso8859_13_2uni[c-0xa0]; + return 1; +} + +static const unsigned char iso8859_13_page00[224] = { + 0xa0, 0x00, 0xa2, 0xa3, 0xa4, 0x00, 0xa6, 0xa7, /* 0xa0-0xa7 */ + 0x00, 0xa9, 0x00, 0xab, 0xac, 0xad, 0xae, 0x00, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0x00, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0x00, 0xb9, 0x00, 0xbb, 0xbc, 0xbd, 0xbe, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0xc4, 0xc5, 0xaf, 0x00, /* 0xc0-0xc7 */ + 0x00, 0xc9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0xd3, 0x00, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0xa8, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0xdf, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0xe4, 0xe5, 0xbf, 0x00, /* 0xe0-0xe7 */ + 0x00, 0xe9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0xf3, 0x00, 0xf5, 0xf6, 0xf7, /* 0xf0-0xf7 */ + 0xb8, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, /* 0xf8-0xff */ + /* 0x0100 */ + 0xc2, 0xe2, 0x00, 0x00, 0xc0, 0xe0, 0xc3, 0xe3, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0xc8, 0xe8, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0xc7, 0xe7, 0x00, 0x00, 0xcb, 0xeb, /* 0x10-0x17 */ + 0xc6, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0xcc, 0xec, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0xce, 0xee, 0x00, 0x00, 0xc1, 0xe1, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcd, 0xed, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0xcf, 0xef, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0xd9, 0xf9, 0xd1, 0xf1, 0xd2, 0xf2, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0xd4, 0xf4, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xba, /* 0x50-0x57 */ + 0x00, 0x00, 0xda, 0xfa, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0xd0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0xdb, 0xfb, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0xd8, 0xf8, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0xca, 0xea, 0xdd, 0xfd, 0xde, 0xfe, 0x00, /* 0x78-0x7f */ +}; +static const unsigned char iso8859_13_page20[8] = { + 0x00, 0xff, 0x00, 0x00, 0xb4, 0xa1, 0xa5, 0x00, /* 0x18-0x1f */ +}; + +static int +iso8859_13_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x00a0) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x0180) + c = iso8859_13_page00[wc-0x00a0]; + else if (wc >= 0x2018 && wc < 0x2020) + c = iso8859_13_page20[wc-0x2018]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILSEQ; +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_14.h b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_14.h new file mode 100644 index 0000000..c76c2c2 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_14.h @@ -0,0 +1,109 @@ +/* $XFree86: xc/lib/X11/lcUniConv/iso8859_14.h,v 1.3 2000/11/29 17:40:30 dawes Exp $ */ + +/* + * ISO-8859-14 + */ + +static const unsigned short iso8859_14_2uni[96] = { + /* 0xa0 */ + 0x00a0, 0x1e02, 0x1e03, 0x00a3, 0x010a, 0x010b, 0x1e0a, 0x00a7, + 0x1e80, 0x00a9, 0x1e82, 0x1e0b, 0x1ef2, 0x00ad, 0x00ae, 0x0178, + /* 0xb0 */ + 0x1e1e, 0x1e1f, 0x0120, 0x0121, 0x1e40, 0x1e41, 0x00b6, 0x1e56, + 0x1e81, 0x1e57, 0x1e83, 0x1e60, 0x1ef3, 0x1e84, 0x1e85, 0x1e61, + /* 0xc0 */ + 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + /* 0xd0 */ + 0x0174, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x1e6a, + 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x0176, 0x00df, + /* 0xe0 */ + 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, + 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, + /* 0xf0 */ + 0x0175, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x1e6b, + 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x0177, 0x00ff, +}; + +static int +iso8859_14_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c >= 0xa0) + *pwc = (ucs4_t) iso8859_14_2uni[c-0xa0]; + else + *pwc = (ucs4_t) c; + return 1; +} + +static const unsigned char iso8859_14_page00[96] = { + 0xa0, 0x00, 0x00, 0xa3, 0x00, 0x00, 0x00, 0xa7, /* 0xa0-0xa7 */ + 0x00, 0xa9, 0x00, 0x00, 0x00, 0xad, 0xae, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb6, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */ + 0x00, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0x00, /* 0xd0-0xd7 */ + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0x00, 0xdf, /* 0xd8-0xdf */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xe0-0xe7 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xe8-0xef */ + 0x00, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0x00, /* 0xf0-0xf7 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0x00, 0xff, /* 0xf8-0xff */ +}; +static const unsigned char iso8859_14_page01_0[32] = { + 0x00, 0x00, 0xa4, 0xa5, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0xb2, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ +}; +static const unsigned char iso8859_14_page01_1[16] = { + 0x00, 0x00, 0x00, 0x00, 0xd0, 0xf0, 0xde, 0xfe, /* 0x70-0x77 */ + 0xaf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ +}; +static const unsigned char iso8859_14_page1e_0[136] = { + 0x00, 0x00, 0xa1, 0xa2, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0xa6, 0xab, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0xb1, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0xb4, 0xb5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb7, 0xb9, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0xbb, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0xd7, 0xf7, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0xa8, 0xb8, 0xaa, 0xba, 0xbd, 0xbe, 0x00, 0x00, /* 0x80-0x87 */ +}; +static const unsigned char iso8859_14_page1e_1[8] = { + 0x00, 0x00, 0xac, 0xbc, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ +}; + +static int +iso8859_14_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x00a0) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x0100) + c = iso8859_14_page00[wc-0x00a0]; + else if (wc >= 0x0108 && wc < 0x0128) + c = iso8859_14_page01_0[wc-0x0108]; + else if (wc >= 0x0170 && wc < 0x0180) + c = iso8859_14_page01_1[wc-0x0170]; + else if (wc >= 0x1e00 && wc < 0x1e88) + c = iso8859_14_page1e_0[wc-0x1e00]; + else if (wc >= 0x1ef0 && wc < 0x1ef8) + c = iso8859_14_page1e_1[wc-0x1ef0]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILSEQ; +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_15.h b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_15.h new file mode 100644 index 0000000..8c613d7 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_15.h @@ -0,0 +1,63 @@ +/* $XFree86: xc/lib/X11/lcUniConv/iso8859_15.h,v 1.3 2000/11/29 17:40:31 dawes Exp $ */ + +/* + * ISO-8859-15 + */ + +static const unsigned short iso8859_15_2uni[32] = { + /* 0xa0 */ + 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x20ac, 0x00a5, 0x0160, 0x00a7, + 0x0161, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, + /* 0xb0 */ + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x017d, 0x00b5, 0x00b6, 0x00b7, + 0x017e, 0x00b9, 0x00ba, 0x00bb, 0x0152, 0x0153, 0x0178, 0x00bf, +}; + +static int +iso8859_15_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c >= 0xa0 && c < 0xc0) + *pwc = (ucs4_t) iso8859_15_2uni[c-0xa0]; + else + *pwc = (ucs4_t) c; + return 1; +} + +static const unsigned char iso8859_15_page00[32] = { + 0xa0, 0xa1, 0xa2, 0xa3, 0x00, 0xa5, 0x00, 0xa7, /* 0xa0-0xa7 */ + 0x00, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0x00, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0x00, 0xb9, 0xba, 0xbb, 0x00, 0x00, 0x00, 0xbf, /* 0xb8-0xbf */ +}; +static const unsigned char iso8859_15_page01[48] = { + 0x00, 0x00, 0xbc, 0xbd, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0xa6, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0xbe, 0x00, 0x00, 0x00, 0x00, 0xb4, 0xb8, 0x00, /* 0x78-0x7f */ +}; + +static int +iso8859_15_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x00a0) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x00c0) + c = iso8859_15_page00[wc-0x00a0]; + else if (wc >= 0x00c0 && wc < 0x0100) + c = wc; + else if (wc >= 0x0150 && wc < 0x0180) + c = iso8859_15_page01[wc-0x0150]; + else if (wc == 0x20ac) + c = 0xa4; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILSEQ; +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_16.h b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_16.h new file mode 100644 index 0000000..5b3f870 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_16.h @@ -0,0 +1,98 @@ +/* $XFree86: xc/lib/X11/lcUniConv/iso8859_16.h,v 1.4 2003/07/15 17:33:45 pascal Exp $ */ + +/* + * ISO-8859-16 + */ + +static const unsigned short iso8859_16_2uni[96] = { + /* 0xa0 */ + 0x00a0, 0x0104, 0x0105, 0x0141, 0x20ac, 0x201e, 0x0160, 0x00a7, + 0x0161, 0x00a9, 0x0218, 0x00ab, 0x0179, 0x00ad, 0x017a, 0x017b, + /* 0xb0 */ + 0x00b0, 0x00b1, 0x010c, 0x0142, 0x017d, 0x201d, 0x00b6, 0x00b7, + 0x017e, 0x010d, 0x0219, 0x00bb, 0x0152, 0x0153, 0x0178, 0x017c, + /* 0xc0 */ + 0x00c0, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x0106, 0x00c6, 0x00c7, + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + /* 0xd0 */ + 0x0110, 0x0143, 0x00d2, 0x00d3, 0x00d4, 0x0150, 0x00d6, 0x015a, + 0x0170, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x0118, 0x021a, 0x00df, + /* 0xe0 */ + 0x00e0, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x0107, 0x00e6, 0x00e7, + 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, + /* 0xf0 */ + 0x0111, 0x0144, 0x00f2, 0x00f3, 0x00f4, 0x0151, 0x00f6, 0x015b, + 0x0171, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x0119, 0x021b, 0x00ff, +}; + +static int +iso8859_16_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0xa0) + *pwc = (ucs4_t) c; + else + *pwc = (ucs4_t) iso8859_16_2uni[c-0xa0]; + return 1; +} + +static const unsigned char iso8859_16_page00[224] = { + 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, /* 0xa0-0xa7 */ + 0x00, 0xa9, 0x00, 0xab, 0x00, 0xad, 0x00, 0x00, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0x00, 0x00, 0x00, 0x00, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0xbb, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0xc0, 0xc1, 0xc2, 0x00, 0xc4, 0x00, 0xc6, 0xc7, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */ + 0x00, 0x00, 0xd2, 0xd3, 0xd4, 0x00, 0xd6, 0x00, /* 0xd0-0xd7 */ + 0x00, 0xd9, 0xda, 0xdb, 0xdc, 0x00, 0x00, 0xdf, /* 0xd8-0xdf */ + 0xe0, 0xe1, 0xe2, 0x00, 0xe4, 0x00, 0xe6, 0xe7, /* 0xe0-0xe7 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xe8-0xef */ + 0x00, 0x00, 0xf2, 0xf3, 0xf4, 0x00, 0xf6, 0x00, /* 0xf0-0xf7 */ + 0x00, 0xf9, 0xfa, 0xfb, 0xfc, 0x00, 0x00, 0xff, /* 0xf8-0xff */ + /* 0x0100 */ + 0x00, 0x00, 0xc3, 0xe3, 0xa1, 0xa2, 0xc5, 0xe5, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0xb2, 0xb9, 0x00, 0x00, /* 0x08-0x0f */ + 0xd0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xdd, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0xa3, 0xb3, 0xd1, 0xf1, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0xd5, 0xf5, 0xbc, 0xbd, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0xd7, 0xf7, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0xa6, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0xd8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0xbe, 0xac, 0xae, 0xaf, 0xbf, 0xb4, 0xb8, 0x00, /* 0x78-0x7f */ +}; +static const unsigned char iso8859_16_page02[8] = { + 0xaa, 0xba, 0xde, 0xfe, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ +}; +static const unsigned char iso8859_16_page20[8] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0xb5, 0xa5, 0x00, /* 0x18-0x1f */ +}; + +static int +iso8859_16_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x00a0) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x0180) + c = iso8859_16_page00[wc-0x00a0]; + else if (wc >= 0x0218 && wc < 0x0220) + c = iso8859_16_page02[wc-0x0218]; + else if (wc >= 0x2018 && wc < 0x2020) + c = iso8859_16_page20[wc-0x2018]; + else if (wc == 0x20ac) + c = 0xa4; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILSEQ; +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_2.h b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_2.h new file mode 100644 index 0000000..9598d54 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_2.h @@ -0,0 +1,94 @@ +/* $XFree86: xc/lib/X11/lcUniConv/iso8859_2.h,v 1.3 2000/11/29 17:40:31 dawes Exp $ */ + +/* + * ISO-8859-2 + */ + +static const unsigned short iso8859_2_2uni[96] = { + /* 0xa0 */ + 0x00a0, 0x0104, 0x02d8, 0x0141, 0x00a4, 0x013d, 0x015a, 0x00a7, + 0x00a8, 0x0160, 0x015e, 0x0164, 0x0179, 0x00ad, 0x017d, 0x017b, + /* 0xb0 */ + 0x00b0, 0x0105, 0x02db, 0x0142, 0x00b4, 0x013e, 0x015b, 0x02c7, + 0x00b8, 0x0161, 0x015f, 0x0165, 0x017a, 0x02dd, 0x017e, 0x017c, + /* 0xc0 */ + 0x0154, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x0139, 0x0106, 0x00c7, + 0x010c, 0x00c9, 0x0118, 0x00cb, 0x011a, 0x00cd, 0x00ce, 0x010e, + /* 0xd0 */ + 0x0110, 0x0143, 0x0147, 0x00d3, 0x00d4, 0x0150, 0x00d6, 0x00d7, + 0x0158, 0x016e, 0x00da, 0x0170, 0x00dc, 0x00dd, 0x0162, 0x00df, + /* 0xe0 */ + 0x0155, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x013a, 0x0107, 0x00e7, + 0x010d, 0x00e9, 0x0119, 0x00eb, 0x011b, 0x00ed, 0x00ee, 0x010f, + /* 0xf0 */ + 0x0111, 0x0144, 0x0148, 0x00f3, 0x00f4, 0x0151, 0x00f6, 0x00f7, + 0x0159, 0x016f, 0x00fa, 0x0171, 0x00fc, 0x00fd, 0x0163, 0x02d9, +}; + +static int +iso8859_2_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0xa0) + *pwc = (ucs4_t) c; + else + *pwc = (ucs4_t) iso8859_2_2uni[c-0xa0]; + return 1; +} + +static const unsigned char iso8859_2_page00[224] = { + 0xa0, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0xa7, /* 0xa0-0xa7 */ + 0xa8, 0x00, 0x00, 0x00, 0x00, 0xad, 0x00, 0x00, /* 0xa8-0xaf */ + 0xb0, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0xc1, 0xc2, 0x00, 0xc4, 0x00, 0x00, 0xc7, /* 0xc0-0xc7 */ + 0x00, 0xc9, 0x00, 0xcb, 0x00, 0xcd, 0xce, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0xd3, 0xd4, 0x00, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0x00, 0x00, 0xda, 0x00, 0xdc, 0xdd, 0x00, 0xdf, /* 0xd8-0xdf */ + 0x00, 0xe1, 0xe2, 0x00, 0xe4, 0x00, 0x00, 0xe7, /* 0xe0-0xe7 */ + 0x00, 0xe9, 0x00, 0xeb, 0x00, 0xed, 0xee, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0xf3, 0xf4, 0x00, 0xf6, 0xf7, /* 0xf0-0xf7 */ + 0x00, 0x00, 0xfa, 0x00, 0xfc, 0xfd, 0x00, 0x00, /* 0xf8-0xff */ + /* 0x0100 */ + 0x00, 0x00, 0xc3, 0xe3, 0xa1, 0xb1, 0xc6, 0xe6, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0xc8, 0xe8, 0xcf, 0xef, /* 0x08-0x0f */ + 0xd0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xca, 0xea, 0xcc, 0xec, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0xc5, 0xe5, 0x00, 0x00, 0xa5, 0xb5, 0x00, /* 0x38-0x3f */ + 0x00, 0xa3, 0xb3, 0xd1, 0xf1, 0x00, 0x00, 0xd2, /* 0x40-0x47 */ + 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0xd5, 0xf5, 0x00, 0x00, 0xc0, 0xe0, 0x00, 0x00, /* 0x50-0x57 */ + 0xd8, 0xf8, 0xa6, 0xb6, 0x00, 0x00, 0xaa, 0xba, /* 0x58-0x5f */ + 0xa9, 0xb9, 0xde, 0xfe, 0xab, 0xbb, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd9, 0xf9, /* 0x68-0x6f */ + 0xdb, 0xfb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0xac, 0xbc, 0xaf, 0xbf, 0xae, 0xbe, 0x00, /* 0x78-0x7f */ +}; +static const unsigned char iso8859_2_page02[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb7, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0xa2, 0xff, 0x00, 0xb2, 0x00, 0xbd, 0x00, 0x00, /* 0xd8-0xdf */ +}; + +static int +iso8859_2_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x00a0) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x0180) + c = iso8859_2_page00[wc-0x00a0]; + else if (wc >= 0x02c0 && wc < 0x02e0) + c = iso8859_2_page02[wc-0x02c0]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILSEQ; +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_3.h b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_3.h new file mode 100644 index 0000000..1604c25 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_3.h @@ -0,0 +1,100 @@ +/* $XFree86: xc/lib/X11/lcUniConv/iso8859_3.h,v 1.3 2000/11/29 17:40:31 dawes Exp $ */ + +/* + * ISO-8859-3 + */ + +static const unsigned short iso8859_3_2uni[96] = { + /* 0xa0 */ + 0x00a0, 0x0126, 0x02d8, 0x00a3, 0x00a4, 0xfffd, 0x0124, 0x00a7, + 0x00a8, 0x0130, 0x015e, 0x011e, 0x0134, 0x00ad, 0xfffd, 0x017b, + /* 0xb0 */ + 0x00b0, 0x0127, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x0125, 0x00b7, + 0x00b8, 0x0131, 0x015f, 0x011f, 0x0135, 0x00bd, 0xfffd, 0x017c, + /* 0xc0 */ + 0x00c0, 0x00c1, 0x00c2, 0xfffd, 0x00c4, 0x010a, 0x0108, 0x00c7, + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + /* 0xd0 */ + 0xfffd, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x0120, 0x00d6, 0x00d7, + 0x011c, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x016c, 0x015c, 0x00df, + /* 0xe0 */ + 0x00e0, 0x00e1, 0x00e2, 0xfffd, 0x00e4, 0x010b, 0x0109, 0x00e7, + 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, + /* 0xf0 */ + 0xfffd, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x0121, 0x00f6, 0x00f7, + 0x011d, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x016d, 0x015d, 0x02d9, +}; + +static int +iso8859_3_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0xa0) { + *pwc = (ucs4_t) c; + return 1; + } + else { + unsigned short wc = iso8859_3_2uni[c-0xa0]; + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 1; + } + } + return RET_ILSEQ; +} + +static const unsigned char iso8859_3_page00[96] = { + 0xa0, 0x00, 0x00, 0xa3, 0xa4, 0x00, 0x00, 0xa7, /* 0xa0-0xa7 */ + 0xa8, 0x00, 0x00, 0x00, 0x00, 0xad, 0x00, 0x00, /* 0xa8-0xaf */ + 0xb0, 0x00, 0xb2, 0xb3, 0xb4, 0xb5, 0x00, 0xb7, /* 0xb0-0xb7 */ + 0xb8, 0x00, 0x00, 0x00, 0x00, 0xbd, 0x00, 0x00, /* 0xb8-0xbf */ + 0xc0, 0xc1, 0xc2, 0x00, 0xc4, 0x00, 0x00, 0xc7, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */ + 0x00, 0xd1, 0xd2, 0xd3, 0xd4, 0x00, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0x00, 0xd9, 0xda, 0xdb, 0xdc, 0x00, 0x00, 0xdf, /* 0xd8-0xdf */ + 0xe0, 0xe1, 0xe2, 0x00, 0xe4, 0x00, 0x00, 0xe7, /* 0xe0-0xe7 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xe8-0xef */ + 0x00, 0xf1, 0xf2, 0xf3, 0xf4, 0x00, 0xf6, 0xf7, /* 0xf0-0xf7 */ + 0x00, 0xf9, 0xfa, 0xfb, 0xfc, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; +static const unsigned char iso8859_3_page01[120] = { + 0xc6, 0xe6, 0xc5, 0xe5, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0xd8, 0xf8, 0xab, 0xbb, /* 0x18-0x1f */ + 0xd5, 0xf5, 0x00, 0x00, 0xa6, 0xb6, 0xa1, 0xb1, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0xa9, 0xb9, 0x00, 0x00, 0xac, 0xbc, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0xde, 0xfe, 0xaa, 0xba, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0xdd, 0xfd, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0xaf, 0xbf, 0x00, 0x00, 0x00, /* 0x78-0x7f */ +}; +static const unsigned char iso8859_3_page02[8] = { + 0xa2, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ +}; + +static int +iso8859_3_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x00a0) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x0100) + c = iso8859_3_page00[wc-0x00a0]; + else if (wc >= 0x0108 && wc < 0x0180) + c = iso8859_3_page01[wc-0x0108]; + else if (wc >= 0x02d8 && wc < 0x02e0) + c = iso8859_3_page02[wc-0x02d8]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILSEQ; +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_4.h b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_4.h new file mode 100644 index 0000000..6ea62d1 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_4.h @@ -0,0 +1,94 @@ +/* $XFree86: xc/lib/X11/lcUniConv/iso8859_4.h,v 1.3 2000/11/29 17:40:31 dawes Exp $ */ + +/* + * ISO-8859-4 + */ + +static const unsigned short iso8859_4_2uni[96] = { + /* 0xa0 */ + 0x00a0, 0x0104, 0x0138, 0x0156, 0x00a4, 0x0128, 0x013b, 0x00a7, + 0x00a8, 0x0160, 0x0112, 0x0122, 0x0166, 0x00ad, 0x017d, 0x00af, + /* 0xb0 */ + 0x00b0, 0x0105, 0x02db, 0x0157, 0x00b4, 0x0129, 0x013c, 0x02c7, + 0x00b8, 0x0161, 0x0113, 0x0123, 0x0167, 0x014a, 0x017e, 0x014b, + /* 0xc0 */ + 0x0100, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x012e, + 0x010c, 0x00c9, 0x0118, 0x00cb, 0x0116, 0x00cd, 0x00ce, 0x012a, + /* 0xd0 */ + 0x0110, 0x0145, 0x014c, 0x0136, 0x00d4, 0x00d5, 0x00d6, 0x00d7, + 0x00d8, 0x0172, 0x00da, 0x00db, 0x00dc, 0x0168, 0x016a, 0x00df, + /* 0xe0 */ + 0x0101, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x012f, + 0x010d, 0x00e9, 0x0119, 0x00eb, 0x0117, 0x00ed, 0x00ee, 0x012b, + /* 0xf0 */ + 0x0111, 0x0146, 0x014d, 0x0137, 0x00f4, 0x00f5, 0x00f6, 0x00f7, + 0x00f8, 0x0173, 0x00fa, 0x00fb, 0x00fc, 0x0169, 0x016b, 0x02d9, +}; + +static int +iso8859_4_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0xa0) + *pwc = (ucs4_t) c; + else + *pwc = (ucs4_t) iso8859_4_2uni[c-0xa0]; + return 1; +} + +static const unsigned char iso8859_4_page00[224] = { + 0xa0, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0xa7, /* 0xa0-0xa7 */ + 0xa8, 0x00, 0x00, 0x00, 0x00, 0xad, 0x00, 0xaf, /* 0xa8-0xaf */ + 0xb0, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0x00, /* 0xc0-0xc7 */ + 0x00, 0xc9, 0x00, 0xcb, 0x00, 0xcd, 0xce, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0xd8, 0x00, 0xda, 0xdb, 0xdc, 0x00, 0x00, 0xdf, /* 0xd8-0xdf */ + 0x00, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0x00, /* 0xe0-0xe7 */ + 0x00, 0xe9, 0x00, 0xeb, 0x00, 0xed, 0xee, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xf0-0xf7 */ + 0xf8, 0x00, 0xfa, 0xfb, 0xfc, 0x00, 0x00, 0x00, /* 0xf8-0xff */ + /* 0x0100 */ + 0xc0, 0xe0, 0x00, 0x00, 0xa1, 0xb1, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0xc8, 0xe8, 0x00, 0x00, /* 0x08-0x0f */ + 0xd0, 0xf0, 0xaa, 0xba, 0x00, 0x00, 0xcc, 0xec, /* 0x10-0x17 */ + 0xca, 0xea, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0xab, 0xbb, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0xa5, 0xb5, 0xcf, 0xef, 0x00, 0x00, 0xc7, 0xe7, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd3, 0xf3, /* 0x30-0x37 */ + 0xa2, 0x00, 0x00, 0xa6, 0xb6, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xd1, 0xf1, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0xbd, 0xbf, 0xd2, 0xf2, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa3, 0xb3, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0xa9, 0xb9, 0x00, 0x00, 0x00, 0x00, 0xac, 0xbc, /* 0x60-0x67 */ + 0xdd, 0xfd, 0xde, 0xfe, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0xd9, 0xf9, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xae, 0xbe, 0x00, /* 0x78-0x7f */ +}; +static const unsigned char iso8859_4_page02[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb7, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0xff, 0x00, 0xb2, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ +}; + +static int +iso8859_4_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x00a0) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x0180) + c = iso8859_4_page00[wc-0x00a0]; + else if (wc >= 0x02c0 && wc < 0x02e0) + c = iso8859_4_page02[wc-0x02c0]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILSEQ; +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_5.h b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_5.h new file mode 100644 index 0000000..d478567 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_5.h @@ -0,0 +1,77 @@ +/* $XFree86: xc/lib/X11/lcUniConv/iso8859_5.h,v 1.3 2000/11/29 17:40:32 dawes Exp $ */ + +/* + * ISO-8859-5 + */ + +static const unsigned short iso8859_5_2uni[96] = { + /* 0xa0 */ + 0x00a0, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407, + 0x0408, 0x0409, 0x040a, 0x040b, 0x040c, 0x00ad, 0x040e, 0x040f, + /* 0xb0 */ + 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, + 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f, + /* 0xc0 */ + 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, + 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, + /* 0xd0 */ + 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, + 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, + /* 0xe0 */ + 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, + 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f, + /* 0xf0 */ + 0x2116, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457, + 0x0458, 0x0459, 0x045a, 0x045b, 0x045c, 0x00a7, 0x045e, 0x045f, +}; + +static int +iso8859_5_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0xa0) + *pwc = (ucs4_t) c; + else + *pwc = (ucs4_t) iso8859_5_2uni[c-0xa0]; + return 1; +} + +static const unsigned char iso8859_5_page00[16] = { + 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfd, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xad, 0x00, 0x00, /* 0xa8-0xaf */ +}; +static const unsigned char iso8859_5_page04[96] = { + 0x00, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0x00-0x07 */ + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0x00, 0xae, 0xaf, /* 0x08-0x0f */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0x10-0x17 */ + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, /* 0x18-0x1f */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0x20-0x27 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0x28-0x2f */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0x30-0x37 */ + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, /* 0x38-0x3f */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0x40-0x47 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0x48-0x4f */ + 0x00, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0x50-0x57 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0x00, 0xfe, 0xff, /* 0x58-0x5f */ +}; + +static int +iso8859_5_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x00a0) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x00b0) + c = iso8859_5_page00[wc-0x00a0]; + else if (wc >= 0x0400 && wc < 0x0460) + c = iso8859_5_page04[wc-0x0400]; + else if (wc == 0x2116) + c = 0xf0; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILSEQ; +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_6.h b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_6.h new file mode 100644 index 0000000..4d57893 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_6.h @@ -0,0 +1,80 @@ +/* $XFree86: xc/lib/X11/lcUniConv/iso8859_6.h,v 1.3 2000/11/29 17:40:32 dawes Exp $ */ + +/* + * ISO-8859-6 + */ + +static const unsigned short iso8859_6_2uni[96] = { + /* 0xa0 */ + 0x00a0, 0xfffd, 0xfffd, 0xfffd, 0x00a4, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x060c, 0x00ad, 0xfffd, 0xfffd, + /* 0xb0 */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x061b, 0xfffd, 0xfffd, 0xfffd, 0x061f, + /* 0xc0 */ + 0xfffd, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, + 0x0628, 0x0629, 0x062a, 0x062b, 0x062c, 0x062d, 0x062e, 0x062f, + /* 0xd0 */ + 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637, + 0x0638, 0x0639, 0x063a, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0xe0 */ + 0x0640, 0x0641, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, + 0x0648, 0x0649, 0x064a, 0x064b, 0x064c, 0x064d, 0x064e, 0x064f, + /* 0xf0 */ + 0x0650, 0x0651, 0x0652, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, +}; + +static int +iso8859_6_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0xa0) { + *pwc = (ucs4_t) c; + return 1; + } + else { + unsigned short wc = iso8859_6_2uni[c-0xa0]; + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 1; + } + } + return RET_ILSEQ; +} + +static const unsigned char iso8859_6_page00[16] = { + 0xa0, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xad, 0x00, 0x00, /* 0xa8-0xaf */ +}; +static const unsigned char iso8859_6_page06[80] = { + 0x00, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0xbb, 0x00, 0x00, 0x00, 0xbf, /* 0x18-0x1f */ + 0x00, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0x20-0x27 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0x28-0x2f */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0x30-0x37 */ + 0xd8, 0xd9, 0xda, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0x40-0x47 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0x48-0x4f */ + 0xf0, 0xf1, 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ +}; + +static int +iso8859_6_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x00a0) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x00b0) + c = iso8859_6_page00[wc-0x00a0]; + else if (wc >= 0x0608 && wc < 0x0658) + c = iso8859_6_page06[wc-0x0608]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILSEQ; +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_7.h b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_7.h new file mode 100644 index 0000000..790cec7 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_7.h @@ -0,0 +1,88 @@ +/* $XFree86: xc/lib/X11/lcUniConv/iso8859_7.h,v 1.3 2000/11/29 17:40:32 dawes Exp $ */ + +/* + * ISO-8859-7 + */ + +static const unsigned short iso8859_7_2uni[96] = { + /* 0xa0 */ + 0x00a0, 0x2018, 0x2019, 0x00a3, 0xfffd, 0xfffd, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, 0xfffd, 0x00ab, 0x00ac, 0x00ad, 0xfffd, 0x2015, + /* 0xb0 */ + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x0384, 0x0385, 0x0386, 0x00b7, + 0x0388, 0x0389, 0x038a, 0x00bb, 0x038c, 0x00bd, 0x038e, 0x038f, + /* 0xc0 */ + 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, + 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, + /* 0xd0 */ + 0x03a0, 0x03a1, 0xfffd, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7, + 0x03a8, 0x03a9, 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03ae, 0x03af, + /* 0xe0 */ + 0x03b0, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, + 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, + /* 0xf0 */ + 0x03c0, 0x03c1, 0x03c2, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, + 0x03c8, 0x03c9, 0x03ca, 0x03cb, 0x03cc, 0x03cd, 0x03ce, 0xfffd, +}; + +static int +iso8859_7_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0xa0) { + *pwc = (ucs4_t) c; + return 1; + } + else { + unsigned short wc = iso8859_7_2uni[c-0xa0]; + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 1; + } + } + return RET_ILSEQ; +} + +static const unsigned char iso8859_7_page00[32] = { + 0xa0, 0x00, 0x00, 0xa3, 0x00, 0x00, 0xa6, 0xa7, /* 0xa0-0xa7 */ + 0xa8, 0xa9, 0x00, 0xab, 0xac, 0xad, 0x00, 0x00, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0x00, 0x00, 0x00, 0xb7, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0xbb, 0x00, 0xbd, 0x00, 0x00, /* 0xb8-0xbf */ +}; +static const unsigned char iso8859_7_page03[80] = { + 0x00, 0x00, 0x00, 0x00, 0xb4, 0xb5, 0xb6, 0x00, /* 0x80-0x87 */ + 0xb8, 0xb9, 0xba, 0x00, 0xbc, 0x00, 0xbe, 0xbf, /* 0x88-0x8f */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0x90-0x97 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0x98-0x9f */ + 0xd0, 0xd1, 0x00, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xa0-0xa7 */ + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, /* 0xa8-0xaf */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xb0-0xb7 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xb8-0xbf */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xc0-0xc7 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0x00, /* 0xc8-0xcf */ +}; +static const unsigned char iso8859_7_page20[16] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0xaf, 0x00, 0x00, /* 0x10-0x17 */ + 0xa1, 0xa2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ +}; + +static int +iso8859_7_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x00a0) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x00c0) + c = iso8859_7_page00[wc-0x00a0]; + else if (wc >= 0x0380 && wc < 0x03d0) + c = iso8859_7_page03[wc-0x0380]; + else if (wc >= 0x2010 && wc < 0x2020) + c = iso8859_7_page20[wc-0x2010]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILSEQ; +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_8.h b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_8.h new file mode 100644 index 0000000..7b780f0 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_8.h @@ -0,0 +1,89 @@ +/* $XFree86: xc/lib/X11/lcUniConv/iso8859_8.h,v 1.3 2000/11/29 17:40:32 dawes Exp $ */ + +/* + * ISO-8859-8 + */ + +static const unsigned short iso8859_8_2uni[96] = { + /* 0xa0 */ + 0x00a0, 0xfffd, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, 0x00d7, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, + /* 0xb0 */ + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, + 0x00b8, 0x00b9, 0x00f7, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0xfffd, + /* 0xc0 */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0xd0 */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x2017, + /* 0xe0 */ + 0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, 0x05d6, 0x05d7, + 0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05dd, 0x05de, 0x05df, + /* 0xf0 */ + 0x05e0, 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5, 0x05e6, 0x05e7, + 0x05e8, 0x05e9, 0x05ea, 0xfffd, 0xfffd, 0x200e, 0x200f, 0xfffd, +}; + +static int +iso8859_8_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c >= 0xa0) { + unsigned short wc = iso8859_8_2uni[c-0xa0]; + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 1; + } + } + else { + *pwc = (ucs4_t) c; + return 1; + } + return RET_ILSEQ; +} + +static const unsigned char iso8859_8_page00[88] = { + 0xa0, 0x00, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0xa0-0xa7 */ + 0xa8, 0xa9, 0x00, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0xb8, 0xb9, 0x00, 0xbb, 0xbc, 0xbd, 0xbe, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xba, /* 0xf0-0xf7 */ +}; +static const unsigned char iso8859_8_page05[32] = { + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xd0-0xd7 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xd8-0xdf */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xe0-0xe7 */ + 0xf8, 0xf9, 0xfa, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ +}; +static const unsigned char iso8859_8_page20[16] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfd, 0xfe, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdf, /* 0x10-0x17 */ +}; + +static int +iso8859_8_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x00a0) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x00f8) + c = iso8859_8_page00[wc-0x00a0]; + else if (wc >= 0x05d0 && wc < 0x05f0) + c = iso8859_8_page05[wc-0x05d0]; + else if (wc >= 0x2008 && wc < 0x2018) + c = iso8859_8_page20[wc-0x2008]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILSEQ; +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_9.h b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_9.h new file mode 100644 index 0000000..55ec1cb --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_9.h @@ -0,0 +1,67 @@ +/* $XFree86: xc/lib/X11/lcUniConv/iso8859_9.h,v 1.3 2000/11/29 17:40:32 dawes Exp $ */ + +/* + * ISO-8859-9 + */ + +static const unsigned short iso8859_9_2uni[48] = { + /* 0xd0 */ + 0x011e, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, + 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x0130, 0x015e, 0x00df, + /* 0xe0 */ + 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, + 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, + /* 0xf0 */ + 0x011f, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, + 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x0131, 0x015f, 0x00ff, +}; + +static int +iso8859_9_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c >= 0xd0) + *pwc = (ucs4_t) iso8859_9_2uni[c-0xd0]; + else + *pwc = (ucs4_t) c; + return 1; +} + +static const unsigned char iso8859_9_page00[48] = { + 0x00, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0x00, 0x00, 0xdf, /* 0xd8-0xdf */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xe0-0xe7 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xe8-0xef */ + 0x00, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xf0-0xf7 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0x00, 0x00, 0xff, /* 0xf8-0xff */ +}; +static const unsigned char iso8859_9_page01[72] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0xf0, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0xdd, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xfe, /* 0x58-0x5f */ +}; + +static int +iso8859_9_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x00d0) { + *r = wc; + return 1; + } + else if (wc >= 0x00d0 && wc < 0x0100) + c = iso8859_9_page00[wc-0x00d0]; + else if (wc >= 0x0118 && wc < 0x0160) + c = iso8859_9_page01[wc-0x0118]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILSEQ; +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_9e.h b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_9e.h new file mode 100644 index 0000000..a5a0b60 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/iso8859_9e.h @@ -0,0 +1,103 @@ +/* $XFree86: xc/lib/X11/lcUniConv/iso8859_9e.h,v 1.3 2000/11/28 16:10:28 dawes Exp $ */ + +/* + * ISO-8859-9E + */ + +static const unsigned short iso8859_9e_2uni[96] = { + /* 0xa0 */ + 0x00a0, 0x017d, 0x00a2, 0x00a3, 0x20ac, 0x00a5, 0x012c, 0x00a7, + 0x016c, 0x00a9, 0x01e6, 0x00ab, 0x014a, 0x00ad, 0x00ae, 0x01d1, + /* 0xb0 */ + 0x00b0, 0x017e, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x012d, 0x00b7, + 0x016d, 0x00b9, 0x01e7, 0x00bb, 0x014b, 0x00bd, 0x0178, 0x01d2, + /* 0xc0 */ + 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x018f, 0x00c7, + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + /* 0xd0 */ + 0x011e, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00dd, + 0x019f, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x0130, 0x015e, 0x00df, + /* 0xe0 */ + 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x0259, 0x00e7, + 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, + /* 0xf0 */ + 0x011f, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00fd, + 0x0275, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x0131, 0x015f, 0x00ff, +}; + +static int +iso8859_9e_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c >= 0xa0) + *pwc = (ucs4_t) iso8859_9e_2uni[c-0xa0]; + else + *pwc = (ucs4_t) c; + return 1; +} + +static const unsigned char iso8859_9e_page00[96] = { + 0xa0, 0x00, 0xa2, 0xa3, 0x00, 0xa5, 0x00, 0xa7, /* 0xa0-0xa7 */ + 0x00, 0xa9, 0x00, 0xab, 0x00, 0xad, 0xae, 0x00, /* 0xa8-0xaf */ + 0xb0, 0x00, 0xb2, 0xb3, 0xb4, 0xb5, 0x00, 0xb7, /* 0xb0-0xb7 */ + 0x00, 0xb9, 0x00, 0xbb, 0x00, 0xbd, 0x00, 0x00, /* 0xb8-0xbf */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0x00, 0xc7, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */ + 0x00, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0x00, /* 0xd0-0xd7 */ + 0x00, 0xd9, 0xda, 0xdb, 0xdc, 0xd7, 0x00, 0xdf, /* 0xd8-0xdf */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0x00, 0xe7, /* 0xe0-0xe7 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xe8-0xef */ + 0x00, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0x00, /* 0xf0-0xf7 */ + 0x00, 0xf9, 0xfa, 0xfb, 0xfc, 0xf7, 0x00, 0xff, /* 0xf8-0xff */ +}; +static const unsigned char iso8859_9e_page01[136] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0xf0, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0xa6, 0xb6, 0x00, 0x00, /* 0x28-0x2f */ + 0xdd, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0xac, 0xbc, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xfe, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0xa8, 0xb8, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0xbe, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xb1, 0x00, /* 0x78-0x7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, /* 0x98-0x9f */ +}; +static const unsigned char iso8859_9e_page01_d[24] = { + 0x00, 0xaf, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xba, /* 0xe0-0xe7 */ +}; + +static int +iso8859_9e_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x00a0) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x0100) + c = iso8859_9e_page00[wc-0x00a0]; + else if (wc >= 0x0118 && wc < 0x01a0) + c = iso8859_9e_page01[wc-0x0118]; + else if (wc >= 0x01d0 && wc < 0x01e8) + c = iso8859_9e_page01_d[wc-0x01d0]; + else if (wc == 0x0259) + c = 0xe6; + else if (wc == 0x0275) + c = 0xf8; + else if (wc == 0x20ac) + c = 0xa4; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILSEQ; +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/jisx0201.h b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/jisx0201.h new file mode 100644 index 0000000..4a30f28 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/jisx0201.h @@ -0,0 +1,48 @@ +/* $XFree86: xc/lib/X11/lcUniConv/jisx0201.h,v 1.3 2000/11/29 17:40:33 dawes Exp $ */ + +/* + * JISX0201.1976-0 + */ + +static int +jisx0201_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) { + if (c == 0x5c) + *pwc = (ucs4_t) 0x00a5; + else if (c == 0x7e) + *pwc = (ucs4_t) 0x203e; + else + *pwc = (ucs4_t) c; + return 1; + } else { + if (c >= 0xa1 && c < 0xe0) { + *pwc = (ucs4_t) c + 0xfec0; + return 1; + } + } + return RET_ILSEQ; +} + +static int +jisx0201_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (wc < 0x0080 && !(wc == 0x005c || wc == 0x007e)) { + *r = wc; + return 1; + } + if (wc == 0x00a5) { + *r = 0x5c; + return 1; + } + if (wc == 0x203e) { + *r = 0x7e; + return 1; + } + if (wc >= 0xff61 && wc < 0xffa0) { + *r = wc - 0xfec0; + return 1; + } + return RET_ILSEQ; +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/jisx0208.h b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/jisx0208.h new file mode 100644 index 0000000..9c08052 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/jisx0208.h @@ -0,0 +1,2397 @@ +/* $XFree86: xc/lib/X11/lcUniConv/jisx0208.h,v 1.6 2003/05/27 22:26:31 tsi Exp $ */ + +/* + * JISX0208.1990-0 + */ + +static const unsigned short jisx0208_2uni_page21[690] = { + /* 0x21 */ + 0x3000, 0x3001, 0x3002, 0xff0c, 0xff0e, 0x30fb, 0xff1a, 0xff1b, + 0xff1f, 0xff01, 0x309b, 0x309c, 0x00b4, 0xff40, 0x00a8, 0xff3e, + 0xffe3, 0xff3f, 0x30fd, 0x30fe, 0x309d, 0x309e, 0x3003, 0x4edd, + 0x3005, 0x3006, 0x3007, 0x30fc, 0x2015, 0x2010, 0xff0f, 0xff3c, + 0x301c, 0x2016, 0xff5c, 0x2026, 0x2025, 0x2018, 0x2019, 0x201c, + 0x201d, 0xff08, 0xff09, 0x3014, 0x3015, 0xff3b, 0xff3d, 0xff5b, + 0xff5d, 0x3008, 0x3009, 0x300a, 0x300b, 0x300c, 0x300d, 0x300e, + 0x300f, 0x3010, 0x3011, 0xff0b, 0x2212, 0x00b1, 0x00d7, 0x00f7, + 0xff1d, 0x2260, 0xff1c, 0xff1e, 0x2266, 0x2267, 0x221e, 0x2234, + 0x2642, 0x2640, 0x00b0, 0x2032, 0x2033, 0x2103, 0xffe5, 0xff04, + 0x00a2, 0x00a3, 0xff05, 0xff03, 0xff06, 0xff0a, 0xff20, 0x00a7, + 0x2606, 0x2605, 0x25cb, 0x25cf, 0x25ce, 0x25c7, + /* 0x22 */ + 0x25c6, 0x25a1, 0x25a0, 0x25b3, 0x25b2, 0x25bd, 0x25bc, 0x203b, + 0x3012, 0x2192, 0x2190, 0x2191, 0x2193, 0x3013, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x2208, 0x220b, 0x2286, 0x2287, 0x2282, 0x2283, 0x222a, + 0x2229, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x2227, 0x2228, 0x00ac, 0x21d2, 0x21d4, 0x2200, 0x2203, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x2220, 0x22a5, 0x2312, 0x2202, 0x2207, + 0x2261, 0x2252, 0x226a, 0x226b, 0x221a, 0x223d, 0x221d, 0x2235, + 0x222b, 0x222c, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x212b, 0x2030, 0x266f, 0x266d, 0x266a, 0x2020, 0x2021, + 0x00b6, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x25ef, + /* 0x23 */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xff10, + 0xff11, 0xff12, 0xff13, 0xff14, 0xff15, 0xff16, 0xff17, 0xff18, + 0xff19, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xff21, 0xff22, 0xff23, 0xff24, 0xff25, 0xff26, 0xff27, 0xff28, + 0xff29, 0xff2a, 0xff2b, 0xff2c, 0xff2d, 0xff2e, 0xff2f, 0xff30, + 0xff31, 0xff32, 0xff33, 0xff34, 0xff35, 0xff36, 0xff37, 0xff38, + 0xff39, 0xff3a, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xff41, 0xff42, 0xff43, 0xff44, 0xff45, 0xff46, 0xff47, 0xff48, + 0xff49, 0xff4a, 0xff4b, 0xff4c, 0xff4d, 0xff4e, 0xff4f, 0xff50, + 0xff51, 0xff52, 0xff53, 0xff54, 0xff55, 0xff56, 0xff57, 0xff58, + 0xff59, 0xff5a, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x24 */ + 0x3041, 0x3042, 0x3043, 0x3044, 0x3045, 0x3046, 0x3047, 0x3048, + 0x3049, 0x304a, 0x304b, 0x304c, 0x304d, 0x304e, 0x304f, 0x3050, + 0x3051, 0x3052, 0x3053, 0x3054, 0x3055, 0x3056, 0x3057, 0x3058, + 0x3059, 0x305a, 0x305b, 0x305c, 0x305d, 0x305e, 0x305f, 0x3060, + 0x3061, 0x3062, 0x3063, 0x3064, 0x3065, 0x3066, 0x3067, 0x3068, + 0x3069, 0x306a, 0x306b, 0x306c, 0x306d, 0x306e, 0x306f, 0x3070, + 0x3071, 0x3072, 0x3073, 0x3074, 0x3075, 0x3076, 0x3077, 0x3078, + 0x3079, 0x307a, 0x307b, 0x307c, 0x307d, 0x307e, 0x307f, 0x3080, + 0x3081, 0x3082, 0x3083, 0x3084, 0x3085, 0x3086, 0x3087, 0x3088, + 0x3089, 0x308a, 0x308b, 0x308c, 0x308d, 0x308e, 0x308f, 0x3090, + 0x3091, 0x3092, 0x3093, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x25 */ + 0x30a1, 0x30a2, 0x30a3, 0x30a4, 0x30a5, 0x30a6, 0x30a7, 0x30a8, + 0x30a9, 0x30aa, 0x30ab, 0x30ac, 0x30ad, 0x30ae, 0x30af, 0x30b0, + 0x30b1, 0x30b2, 0x30b3, 0x30b4, 0x30b5, 0x30b6, 0x30b7, 0x30b8, + 0x30b9, 0x30ba, 0x30bb, 0x30bc, 0x30bd, 0x30be, 0x30bf, 0x30c0, + 0x30c1, 0x30c2, 0x30c3, 0x30c4, 0x30c5, 0x30c6, 0x30c7, 0x30c8, + 0x30c9, 0x30ca, 0x30cb, 0x30cc, 0x30cd, 0x30ce, 0x30cf, 0x30d0, + 0x30d1, 0x30d2, 0x30d3, 0x30d4, 0x30d5, 0x30d6, 0x30d7, 0x30d8, + 0x30d9, 0x30da, 0x30db, 0x30dc, 0x30dd, 0x30de, 0x30df, 0x30e0, + 0x30e1, 0x30e2, 0x30e3, 0x30e4, 0x30e5, 0x30e6, 0x30e7, 0x30e8, + 0x30e9, 0x30ea, 0x30eb, 0x30ec, 0x30ed, 0x30ee, 0x30ef, 0x30f0, + 0x30f1, 0x30f2, 0x30f3, 0x30f4, 0x30f5, 0x30f6, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x26 */ + 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, + 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, 0x03a0, + 0x03a1, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7, 0x03a8, 0x03a9, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, 0x03b8, + 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, 0x03c0, + 0x03c1, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, 0x03c8, 0x03c9, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x27 */ + 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0401, 0x0416, + 0x0417, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, + 0x041f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, + 0x0427, 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, + 0x042f, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0451, 0x0436, + 0x0437, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, + 0x043f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, + 0x0447, 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, + 0x044f, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x28 */ + 0x2500, 0x2502, 0x250c, 0x2510, 0x2518, 0x2514, 0x251c, 0x252c, + 0x2524, 0x2534, 0x253c, 0x2501, 0x2503, 0x250f, 0x2513, 0x251b, + 0x2517, 0x2523, 0x2533, 0x252b, 0x253b, 0x254b, 0x2520, 0x252f, + 0x2528, 0x2537, 0x253f, 0x251d, 0x2530, 0x2525, 0x2538, 0x2542, +}; +static const unsigned short jisx0208_2uni_page30[6398] = { + /* 0x30 */ + 0x4e9c, 0x5516, 0x5a03, 0x963f, 0x54c0, 0x611b, 0x6328, 0x59f6, + 0x9022, 0x8475, 0x831c, 0x7a50, 0x60aa, 0x63e1, 0x6e25, 0x65ed, + 0x8466, 0x82a6, 0x9bf5, 0x6893, 0x5727, 0x65a1, 0x6271, 0x5b9b, + 0x59d0, 0x867b, 0x98f4, 0x7d62, 0x7dbe, 0x9b8e, 0x6216, 0x7c9f, + 0x88b7, 0x5b89, 0x5eb5, 0x6309, 0x6697, 0x6848, 0x95c7, 0x978d, + 0x674f, 0x4ee5, 0x4f0a, 0x4f4d, 0x4f9d, 0x5049, 0x56f2, 0x5937, + 0x59d4, 0x5a01, 0x5c09, 0x60df, 0x610f, 0x6170, 0x6613, 0x6905, + 0x70ba, 0x754f, 0x7570, 0x79fb, 0x7dad, 0x7def, 0x80c3, 0x840e, + 0x8863, 0x8b02, 0x9055, 0x907a, 0x533b, 0x4e95, 0x4ea5, 0x57df, + 0x80b2, 0x90c1, 0x78ef, 0x4e00, 0x58f1, 0x6ea2, 0x9038, 0x7a32, + 0x8328, 0x828b, 0x9c2f, 0x5141, 0x5370, 0x54bd, 0x54e1, 0x56e0, + 0x59fb, 0x5f15, 0x98f2, 0x6deb, 0x80e4, 0x852d, + /* 0x31 */ + 0x9662, 0x9670, 0x96a0, 0x97fb, 0x540b, 0x53f3, 0x5b87, 0x70cf, + 0x7fbd, 0x8fc2, 0x96e8, 0x536f, 0x9d5c, 0x7aba, 0x4e11, 0x7893, + 0x81fc, 0x6e26, 0x5618, 0x5504, 0x6b1d, 0x851a, 0x9c3b, 0x59e5, + 0x53a9, 0x6d66, 0x74dc, 0x958f, 0x5642, 0x4e91, 0x904b, 0x96f2, + 0x834f, 0x990c, 0x53e1, 0x55b6, 0x5b30, 0x5f71, 0x6620, 0x66f3, + 0x6804, 0x6c38, 0x6cf3, 0x6d29, 0x745b, 0x76c8, 0x7a4e, 0x9834, + 0x82f1, 0x885b, 0x8a60, 0x92ed, 0x6db2, 0x75ab, 0x76ca, 0x99c5, + 0x60a6, 0x8b01, 0x8d8a, 0x95b2, 0x698e, 0x53ad, 0x5186, 0x5712, + 0x5830, 0x5944, 0x5bb4, 0x5ef6, 0x6028, 0x63a9, 0x63f4, 0x6cbf, + 0x6f14, 0x708e, 0x7114, 0x7159, 0x71d5, 0x733f, 0x7e01, 0x8276, + 0x82d1, 0x8597, 0x9060, 0x925b, 0x9d1b, 0x5869, 0x65bc, 0x6c5a, + 0x7525, 0x51f9, 0x592e, 0x5965, 0x5f80, 0x5fdc, + /* 0x32 */ + 0x62bc, 0x65fa, 0x6a2a, 0x6b27, 0x6bb4, 0x738b, 0x7fc1, 0x8956, + 0x9d2c, 0x9d0e, 0x9ec4, 0x5ca1, 0x6c96, 0x837b, 0x5104, 0x5c4b, + 0x61b6, 0x81c6, 0x6876, 0x7261, 0x4e59, 0x4ffa, 0x5378, 0x6069, + 0x6e29, 0x7a4f, 0x97f3, 0x4e0b, 0x5316, 0x4eee, 0x4f55, 0x4f3d, + 0x4fa1, 0x4f73, 0x52a0, 0x53ef, 0x5609, 0x590f, 0x5ac1, 0x5bb6, + 0x5be1, 0x79d1, 0x6687, 0x679c, 0x67b6, 0x6b4c, 0x6cb3, 0x706b, + 0x73c2, 0x798d, 0x79be, 0x7a3c, 0x7b87, 0x82b1, 0x82db, 0x8304, + 0x8377, 0x83ef, 0x83d3, 0x8766, 0x8ab2, 0x5629, 0x8ca8, 0x8fe6, + 0x904e, 0x971e, 0x868a, 0x4fc4, 0x5ce8, 0x6211, 0x7259, 0x753b, + 0x81e5, 0x82bd, 0x86fe, 0x8cc0, 0x96c5, 0x9913, 0x99d5, 0x4ecb, + 0x4f1a, 0x89e3, 0x56de, 0x584a, 0x58ca, 0x5efb, 0x5feb, 0x602a, + 0x6094, 0x6062, 0x61d0, 0x6212, 0x62d0, 0x6539, + /* 0x33 */ + 0x9b41, 0x6666, 0x68b0, 0x6d77, 0x7070, 0x754c, 0x7686, 0x7d75, + 0x82a5, 0x87f9, 0x958b, 0x968e, 0x8c9d, 0x51f1, 0x52be, 0x5916, + 0x54b3, 0x5bb3, 0x5d16, 0x6168, 0x6982, 0x6daf, 0x788d, 0x84cb, + 0x8857, 0x8a72, 0x93a7, 0x9ab8, 0x6d6c, 0x99a8, 0x86d9, 0x57a3, + 0x67ff, 0x86ce, 0x920e, 0x5283, 0x5687, 0x5404, 0x5ed3, 0x62e1, + 0x64b9, 0x683c, 0x6838, 0x6bbb, 0x7372, 0x78ba, 0x7a6b, 0x899a, + 0x89d2, 0x8d6b, 0x8f03, 0x90ed, 0x95a3, 0x9694, 0x9769, 0x5b66, + 0x5cb3, 0x697d, 0x984d, 0x984e, 0x639b, 0x7b20, 0x6a2b, 0x6a7f, + 0x68b6, 0x9c0d, 0x6f5f, 0x5272, 0x559d, 0x6070, 0x62ec, 0x6d3b, + 0x6e07, 0x6ed1, 0x845b, 0x8910, 0x8f44, 0x4e14, 0x9c39, 0x53f6, + 0x691b, 0x6a3a, 0x9784, 0x682a, 0x515c, 0x7ac3, 0x84b2, 0x91dc, + 0x938c, 0x565b, 0x9d28, 0x6822, 0x8305, 0x8431, + /* 0x34 */ + 0x7ca5, 0x5208, 0x82c5, 0x74e6, 0x4e7e, 0x4f83, 0x51a0, 0x5bd2, + 0x520a, 0x52d8, 0x52e7, 0x5dfb, 0x559a, 0x582a, 0x59e6, 0x5b8c, + 0x5b98, 0x5bdb, 0x5e72, 0x5e79, 0x60a3, 0x611f, 0x6163, 0x61be, + 0x63db, 0x6562, 0x67d1, 0x6853, 0x68fa, 0x6b3e, 0x6b53, 0x6c57, + 0x6f22, 0x6f97, 0x6f45, 0x74b0, 0x7518, 0x76e3, 0x770b, 0x7aff, + 0x7ba1, 0x7c21, 0x7de9, 0x7f36, 0x7ff0, 0x809d, 0x8266, 0x839e, + 0x89b3, 0x8acc, 0x8cab, 0x9084, 0x9451, 0x9593, 0x9591, 0x95a2, + 0x9665, 0x97d3, 0x9928, 0x8218, 0x4e38, 0x542b, 0x5cb8, 0x5dcc, + 0x73a9, 0x764c, 0x773c, 0x5ca9, 0x7feb, 0x8d0b, 0x96c1, 0x9811, + 0x9854, 0x9858, 0x4f01, 0x4f0e, 0x5371, 0x559c, 0x5668, 0x57fa, + 0x5947, 0x5b09, 0x5bc4, 0x5c90, 0x5e0c, 0x5e7e, 0x5fcc, 0x63ee, + 0x673a, 0x65d7, 0x65e2, 0x671f, 0x68cb, 0x68c4, + /* 0x35 */ + 0x6a5f, 0x5e30, 0x6bc5, 0x6c17, 0x6c7d, 0x757f, 0x7948, 0x5b63, + 0x7a00, 0x7d00, 0x5fbd, 0x898f, 0x8a18, 0x8cb4, 0x8d77, 0x8ecc, + 0x8f1d, 0x98e2, 0x9a0e, 0x9b3c, 0x4e80, 0x507d, 0x5100, 0x5993, + 0x5b9c, 0x622f, 0x6280, 0x64ec, 0x6b3a, 0x72a0, 0x7591, 0x7947, + 0x7fa9, 0x87fb, 0x8abc, 0x8b70, 0x63ac, 0x83ca, 0x97a0, 0x5409, + 0x5403, 0x55ab, 0x6854, 0x6a58, 0x8a70, 0x7827, 0x6775, 0x9ecd, + 0x5374, 0x5ba2, 0x811a, 0x8650, 0x9006, 0x4e18, 0x4e45, 0x4ec7, + 0x4f11, 0x53ca, 0x5438, 0x5bae, 0x5f13, 0x6025, 0x6551, 0x673d, + 0x6c42, 0x6c72, 0x6ce3, 0x7078, 0x7403, 0x7a76, 0x7aae, 0x7b08, + 0x7d1a, 0x7cfe, 0x7d66, 0x65e7, 0x725b, 0x53bb, 0x5c45, 0x5de8, + 0x62d2, 0x62e0, 0x6319, 0x6e20, 0x865a, 0x8a31, 0x8ddd, 0x92f8, + 0x6f01, 0x79a6, 0x9b5a, 0x4ea8, 0x4eab, 0x4eac, + /* 0x36 */ + 0x4f9b, 0x4fa0, 0x50d1, 0x5147, 0x7af6, 0x5171, 0x51f6, 0x5354, + 0x5321, 0x537f, 0x53eb, 0x55ac, 0x5883, 0x5ce1, 0x5f37, 0x5f4a, + 0x602f, 0x6050, 0x606d, 0x631f, 0x6559, 0x6a4b, 0x6cc1, 0x72c2, + 0x72ed, 0x77ef, 0x80f8, 0x8105, 0x8208, 0x854e, 0x90f7, 0x93e1, + 0x97ff, 0x9957, 0x9a5a, 0x4ef0, 0x51dd, 0x5c2d, 0x6681, 0x696d, + 0x5c40, 0x66f2, 0x6975, 0x7389, 0x6850, 0x7c81, 0x50c5, 0x52e4, + 0x5747, 0x5dfe, 0x9326, 0x65a4, 0x6b23, 0x6b3d, 0x7434, 0x7981, + 0x79bd, 0x7b4b, 0x7dca, 0x82b9, 0x83cc, 0x887f, 0x895f, 0x8b39, + 0x8fd1, 0x91d1, 0x541f, 0x9280, 0x4e5d, 0x5036, 0x53e5, 0x533a, + 0x72d7, 0x7396, 0x77e9, 0x82e6, 0x8eaf, 0x99c6, 0x99c8, 0x99d2, + 0x5177, 0x611a, 0x865e, 0x55b0, 0x7a7a, 0x5076, 0x5bd3, 0x9047, + 0x9685, 0x4e32, 0x6adb, 0x91e7, 0x5c51, 0x5c48, + /* 0x37 */ + 0x6398, 0x7a9f, 0x6c93, 0x9774, 0x8f61, 0x7aaa, 0x718a, 0x9688, + 0x7c82, 0x6817, 0x7e70, 0x6851, 0x936c, 0x52f2, 0x541b, 0x85ab, + 0x8a13, 0x7fa4, 0x8ecd, 0x90e1, 0x5366, 0x8888, 0x7941, 0x4fc2, + 0x50be, 0x5211, 0x5144, 0x5553, 0x572d, 0x73ea, 0x578b, 0x5951, + 0x5f62, 0x5f84, 0x6075, 0x6176, 0x6167, 0x61a9, 0x63b2, 0x643a, + 0x656c, 0x666f, 0x6842, 0x6e13, 0x7566, 0x7a3d, 0x7cfb, 0x7d4c, + 0x7d99, 0x7e4b, 0x7f6b, 0x830e, 0x834a, 0x86cd, 0x8a08, 0x8a63, + 0x8b66, 0x8efd, 0x981a, 0x9d8f, 0x82b8, 0x8fce, 0x9be8, 0x5287, + 0x621f, 0x6483, 0x6fc0, 0x9699, 0x6841, 0x5091, 0x6b20, 0x6c7a, + 0x6f54, 0x7a74, 0x7d50, 0x8840, 0x8a23, 0x6708, 0x4ef6, 0x5039, + 0x5026, 0x5065, 0x517c, 0x5238, 0x5263, 0x55a7, 0x570f, 0x5805, + 0x5acc, 0x5efa, 0x61b2, 0x61f8, 0x62f3, 0x6372, + /* 0x38 */ + 0x691c, 0x6a29, 0x727d, 0x72ac, 0x732e, 0x7814, 0x786f, 0x7d79, + 0x770c, 0x80a9, 0x898b, 0x8b19, 0x8ce2, 0x8ed2, 0x9063, 0x9375, + 0x967a, 0x9855, 0x9a13, 0x9e78, 0x5143, 0x539f, 0x53b3, 0x5e7b, + 0x5f26, 0x6e1b, 0x6e90, 0x7384, 0x73fe, 0x7d43, 0x8237, 0x8a00, + 0x8afa, 0x9650, 0x4e4e, 0x500b, 0x53e4, 0x547c, 0x56fa, 0x59d1, + 0x5b64, 0x5df1, 0x5eab, 0x5f27, 0x6238, 0x6545, 0x67af, 0x6e56, + 0x72d0, 0x7cca, 0x88b4, 0x80a1, 0x80e1, 0x83f0, 0x864e, 0x8a87, + 0x8de8, 0x9237, 0x96c7, 0x9867, 0x9f13, 0x4e94, 0x4e92, 0x4f0d, + 0x5348, 0x5449, 0x543e, 0x5a2f, 0x5f8c, 0x5fa1, 0x609f, 0x68a7, + 0x6a8e, 0x745a, 0x7881, 0x8a9e, 0x8aa4, 0x8b77, 0x9190, 0x4e5e, + 0x9bc9, 0x4ea4, 0x4f7c, 0x4faf, 0x5019, 0x5016, 0x5149, 0x516c, + 0x529f, 0x52b9, 0x52fe, 0x539a, 0x53e3, 0x5411, + /* 0x39 */ + 0x540e, 0x5589, 0x5751, 0x57a2, 0x597d, 0x5b54, 0x5b5d, 0x5b8f, + 0x5de5, 0x5de7, 0x5df7, 0x5e78, 0x5e83, 0x5e9a, 0x5eb7, 0x5f18, + 0x6052, 0x614c, 0x6297, 0x62d8, 0x63a7, 0x653b, 0x6602, 0x6643, + 0x66f4, 0x676d, 0x6821, 0x6897, 0x69cb, 0x6c5f, 0x6d2a, 0x6d69, + 0x6e2f, 0x6e9d, 0x7532, 0x7687, 0x786c, 0x7a3f, 0x7ce0, 0x7d05, + 0x7d18, 0x7d5e, 0x7db1, 0x8015, 0x8003, 0x80af, 0x80b1, 0x8154, + 0x818f, 0x822a, 0x8352, 0x884c, 0x8861, 0x8b1b, 0x8ca2, 0x8cfc, + 0x90ca, 0x9175, 0x9271, 0x783f, 0x92fc, 0x95a4, 0x964d, 0x9805, + 0x9999, 0x9ad8, 0x9d3b, 0x525b, 0x52ab, 0x53f7, 0x5408, 0x58d5, + 0x62f7, 0x6fe0, 0x8c6a, 0x8f5f, 0x9eb9, 0x514b, 0x523b, 0x544a, + 0x56fd, 0x7a40, 0x9177, 0x9d60, 0x9ed2, 0x7344, 0x6f09, 0x8170, + 0x7511, 0x5ffd, 0x60da, 0x9aa8, 0x72db, 0x8fbc, + /* 0x3a */ + 0x6b64, 0x9803, 0x4eca, 0x56f0, 0x5764, 0x58be, 0x5a5a, 0x6068, + 0x61c7, 0x660f, 0x6606, 0x6839, 0x68b1, 0x6df7, 0x75d5, 0x7d3a, + 0x826e, 0x9b42, 0x4e9b, 0x4f50, 0x53c9, 0x5506, 0x5d6f, 0x5de6, + 0x5dee, 0x67fb, 0x6c99, 0x7473, 0x7802, 0x8a50, 0x9396, 0x88df, + 0x5750, 0x5ea7, 0x632b, 0x50b5, 0x50ac, 0x518d, 0x6700, 0x54c9, + 0x585e, 0x59bb, 0x5bb0, 0x5f69, 0x624d, 0x63a1, 0x683d, 0x6b73, + 0x6e08, 0x707d, 0x91c7, 0x7280, 0x7815, 0x7826, 0x796d, 0x658e, + 0x7d30, 0x83dc, 0x88c1, 0x8f09, 0x969b, 0x5264, 0x5728, 0x6750, + 0x7f6a, 0x8ca1, 0x51b4, 0x5742, 0x962a, 0x583a, 0x698a, 0x80b4, + 0x54b2, 0x5d0e, 0x57fc, 0x7895, 0x9dfa, 0x4f5c, 0x524a, 0x548b, + 0x643e, 0x6628, 0x6714, 0x67f5, 0x7a84, 0x7b56, 0x7d22, 0x932f, + 0x685c, 0x9bad, 0x7b39, 0x5319, 0x518a, 0x5237, + /* 0x3b */ + 0x5bdf, 0x62f6, 0x64ae, 0x64e6, 0x672d, 0x6bba, 0x85a9, 0x96d1, + 0x7690, 0x9bd6, 0x634c, 0x9306, 0x9bab, 0x76bf, 0x6652, 0x4e09, + 0x5098, 0x53c2, 0x5c71, 0x60e8, 0x6492, 0x6563, 0x685f, 0x71e6, + 0x73ca, 0x7523, 0x7b97, 0x7e82, 0x8695, 0x8b83, 0x8cdb, 0x9178, + 0x9910, 0x65ac, 0x66ab, 0x6b8b, 0x4ed5, 0x4ed4, 0x4f3a, 0x4f7f, + 0x523a, 0x53f8, 0x53f2, 0x55e3, 0x56db, 0x58eb, 0x59cb, 0x59c9, + 0x59ff, 0x5b50, 0x5c4d, 0x5e02, 0x5e2b, 0x5fd7, 0x601d, 0x6307, + 0x652f, 0x5b5c, 0x65af, 0x65bd, 0x65e8, 0x679d, 0x6b62, 0x6b7b, + 0x6c0f, 0x7345, 0x7949, 0x79c1, 0x7cf8, 0x7d19, 0x7d2b, 0x80a2, + 0x8102, 0x81f3, 0x8996, 0x8a5e, 0x8a69, 0x8a66, 0x8a8c, 0x8aee, + 0x8cc7, 0x8cdc, 0x96cc, 0x98fc, 0x6b6f, 0x4e8b, 0x4f3c, 0x4f8d, + 0x5150, 0x5b57, 0x5bfa, 0x6148, 0x6301, 0x6642, + /* 0x3c */ + 0x6b21, 0x6ecb, 0x6cbb, 0x723e, 0x74bd, 0x75d4, 0x78c1, 0x793a, + 0x800c, 0x8033, 0x81ea, 0x8494, 0x8f9e, 0x6c50, 0x9e7f, 0x5f0f, + 0x8b58, 0x9d2b, 0x7afa, 0x8ef8, 0x5b8d, 0x96eb, 0x4e03, 0x53f1, + 0x57f7, 0x5931, 0x5ac9, 0x5ba4, 0x6089, 0x6e7f, 0x6f06, 0x75be, + 0x8cea, 0x5b9f, 0x8500, 0x7be0, 0x5072, 0x67f4, 0x829d, 0x5c61, + 0x854a, 0x7e1e, 0x820e, 0x5199, 0x5c04, 0x6368, 0x8d66, 0x659c, + 0x716e, 0x793e, 0x7d17, 0x8005, 0x8b1d, 0x8eca, 0x906e, 0x86c7, + 0x90aa, 0x501f, 0x52fa, 0x5c3a, 0x6753, 0x707c, 0x7235, 0x914c, + 0x91c8, 0x932b, 0x82e5, 0x5bc2, 0x5f31, 0x60f9, 0x4e3b, 0x53d6, + 0x5b88, 0x624b, 0x6731, 0x6b8a, 0x72e9, 0x73e0, 0x7a2e, 0x816b, + 0x8da3, 0x9152, 0x9996, 0x5112, 0x53d7, 0x546a, 0x5bff, 0x6388, + 0x6a39, 0x7dac, 0x9700, 0x56da, 0x53ce, 0x5468, + /* 0x3d */ + 0x5b97, 0x5c31, 0x5dde, 0x4fee, 0x6101, 0x62fe, 0x6d32, 0x79c0, + 0x79cb, 0x7d42, 0x7e4d, 0x7fd2, 0x81ed, 0x821f, 0x8490, 0x8846, + 0x8972, 0x8b90, 0x8e74, 0x8f2f, 0x9031, 0x914b, 0x916c, 0x96c6, + 0x919c, 0x4ec0, 0x4f4f, 0x5145, 0x5341, 0x5f93, 0x620e, 0x67d4, + 0x6c41, 0x6e0b, 0x7363, 0x7e26, 0x91cd, 0x9283, 0x53d4, 0x5919, + 0x5bbf, 0x6dd1, 0x795d, 0x7e2e, 0x7c9b, 0x587e, 0x719f, 0x51fa, + 0x8853, 0x8ff0, 0x4fca, 0x5cfb, 0x6625, 0x77ac, 0x7ae3, 0x821c, + 0x99ff, 0x51c6, 0x5faa, 0x65ec, 0x696f, 0x6b89, 0x6df3, 0x6e96, + 0x6f64, 0x76fe, 0x7d14, 0x5de1, 0x9075, 0x9187, 0x9806, 0x51e6, + 0x521d, 0x6240, 0x6691, 0x66d9, 0x6e1a, 0x5eb6, 0x7dd2, 0x7f72, + 0x66f8, 0x85af, 0x85f7, 0x8af8, 0x52a9, 0x53d9, 0x5973, 0x5e8f, + 0x5f90, 0x6055, 0x92e4, 0x9664, 0x50b7, 0x511f, + /* 0x3e */ + 0x52dd, 0x5320, 0x5347, 0x53ec, 0x54e8, 0x5546, 0x5531, 0x5617, + 0x5968, 0x59be, 0x5a3c, 0x5bb5, 0x5c06, 0x5c0f, 0x5c11, 0x5c1a, + 0x5e84, 0x5e8a, 0x5ee0, 0x5f70, 0x627f, 0x6284, 0x62db, 0x638c, + 0x6377, 0x6607, 0x660c, 0x662d, 0x6676, 0x677e, 0x68a2, 0x6a1f, + 0x6a35, 0x6cbc, 0x6d88, 0x6e09, 0x6e58, 0x713c, 0x7126, 0x7167, + 0x75c7, 0x7701, 0x785d, 0x7901, 0x7965, 0x79f0, 0x7ae0, 0x7b11, + 0x7ca7, 0x7d39, 0x8096, 0x83d6, 0x848b, 0x8549, 0x885d, 0x88f3, + 0x8a1f, 0x8a3c, 0x8a54, 0x8a73, 0x8c61, 0x8cde, 0x91a4, 0x9266, + 0x937e, 0x9418, 0x969c, 0x9798, 0x4e0a, 0x4e08, 0x4e1e, 0x4e57, + 0x5197, 0x5270, 0x57ce, 0x5834, 0x58cc, 0x5b22, 0x5e38, 0x60c5, + 0x64fe, 0x6761, 0x6756, 0x6d44, 0x72b6, 0x7573, 0x7a63, 0x84b8, + 0x8b72, 0x91b8, 0x9320, 0x5631, 0x57f4, 0x98fe, + /* 0x3f */ + 0x62ed, 0x690d, 0x6b96, 0x71ed, 0x7e54, 0x8077, 0x8272, 0x89e6, + 0x98df, 0x8755, 0x8fb1, 0x5c3b, 0x4f38, 0x4fe1, 0x4fb5, 0x5507, + 0x5a20, 0x5bdd, 0x5be9, 0x5fc3, 0x614e, 0x632f, 0x65b0, 0x664b, + 0x68ee, 0x699b, 0x6d78, 0x6df1, 0x7533, 0x75b9, 0x771f, 0x795e, + 0x79e6, 0x7d33, 0x81e3, 0x82af, 0x85aa, 0x89aa, 0x8a3a, 0x8eab, + 0x8f9b, 0x9032, 0x91dd, 0x9707, 0x4eba, 0x4ec1, 0x5203, 0x5875, + 0x58ec, 0x5c0b, 0x751a, 0x5c3d, 0x814e, 0x8a0a, 0x8fc5, 0x9663, + 0x976d, 0x7b25, 0x8acf, 0x9808, 0x9162, 0x56f3, 0x53a8, 0x9017, + 0x5439, 0x5782, 0x5e25, 0x63a8, 0x6c34, 0x708a, 0x7761, 0x7c8b, + 0x7fe0, 0x8870, 0x9042, 0x9154, 0x9310, 0x9318, 0x968f, 0x745e, + 0x9ac4, 0x5d07, 0x5d69, 0x6570, 0x67a2, 0x8da8, 0x96db, 0x636e, + 0x6749, 0x6919, 0x83c5, 0x9817, 0x96c0, 0x88fe, + /* 0x40 */ + 0x6f84, 0x647a, 0x5bf8, 0x4e16, 0x702c, 0x755d, 0x662f, 0x51c4, + 0x5236, 0x52e2, 0x59d3, 0x5f81, 0x6027, 0x6210, 0x653f, 0x6574, + 0x661f, 0x6674, 0x68f2, 0x6816, 0x6b63, 0x6e05, 0x7272, 0x751f, + 0x76db, 0x7cbe, 0x8056, 0x58f0, 0x88fd, 0x897f, 0x8aa0, 0x8a93, + 0x8acb, 0x901d, 0x9192, 0x9752, 0x9759, 0x6589, 0x7a0e, 0x8106, + 0x96bb, 0x5e2d, 0x60dc, 0x621a, 0x65a5, 0x6614, 0x6790, 0x77f3, + 0x7a4d, 0x7c4d, 0x7e3e, 0x810a, 0x8cac, 0x8d64, 0x8de1, 0x8e5f, + 0x78a9, 0x5207, 0x62d9, 0x63a5, 0x6442, 0x6298, 0x8a2d, 0x7a83, + 0x7bc0, 0x8aac, 0x96ea, 0x7d76, 0x820c, 0x8749, 0x4ed9, 0x5148, + 0x5343, 0x5360, 0x5ba3, 0x5c02, 0x5c16, 0x5ddd, 0x6226, 0x6247, + 0x64b0, 0x6813, 0x6834, 0x6cc9, 0x6d45, 0x6d17, 0x67d3, 0x6f5c, + 0x714e, 0x717d, 0x65cb, 0x7a7f, 0x7bad, 0x7dda, + /* 0x41 */ + 0x7e4a, 0x7fa8, 0x817a, 0x821b, 0x8239, 0x85a6, 0x8a6e, 0x8cce, + 0x8df5, 0x9078, 0x9077, 0x92ad, 0x9291, 0x9583, 0x9bae, 0x524d, + 0x5584, 0x6f38, 0x7136, 0x5168, 0x7985, 0x7e55, 0x81b3, 0x7cce, + 0x564c, 0x5851, 0x5ca8, 0x63aa, 0x66fe, 0x66fd, 0x695a, 0x72d9, + 0x758f, 0x758e, 0x790e, 0x7956, 0x79df, 0x7c97, 0x7d20, 0x7d44, + 0x8607, 0x8a34, 0x963b, 0x9061, 0x9f20, 0x50e7, 0x5275, 0x53cc, + 0x53e2, 0x5009, 0x55aa, 0x58ee, 0x594f, 0x723d, 0x5b8b, 0x5c64, + 0x531d, 0x60e3, 0x60f3, 0x635c, 0x6383, 0x633f, 0x63bb, 0x64cd, + 0x65e9, 0x66f9, 0x5de3, 0x69cd, 0x69fd, 0x6f15, 0x71e5, 0x4e89, + 0x75e9, 0x76f8, 0x7a93, 0x7cdf, 0x7dcf, 0x7d9c, 0x8061, 0x8349, + 0x8358, 0x846c, 0x84bc, 0x85fb, 0x88c5, 0x8d70, 0x9001, 0x906d, + 0x9397, 0x971c, 0x9a12, 0x50cf, 0x5897, 0x618e, + /* 0x42 */ + 0x81d3, 0x8535, 0x8d08, 0x9020, 0x4fc3, 0x5074, 0x5247, 0x5373, + 0x606f, 0x6349, 0x675f, 0x6e2c, 0x8db3, 0x901f, 0x4fd7, 0x5c5e, + 0x8cca, 0x65cf, 0x7d9a, 0x5352, 0x8896, 0x5176, 0x63c3, 0x5b58, + 0x5b6b, 0x5c0a, 0x640d, 0x6751, 0x905c, 0x4ed6, 0x591a, 0x592a, + 0x6c70, 0x8a51, 0x553e, 0x5815, 0x59a5, 0x60f0, 0x6253, 0x67c1, + 0x8235, 0x6955, 0x9640, 0x99c4, 0x9a28, 0x4f53, 0x5806, 0x5bfe, + 0x8010, 0x5cb1, 0x5e2f, 0x5f85, 0x6020, 0x614b, 0x6234, 0x66ff, + 0x6cf0, 0x6ede, 0x80ce, 0x817f, 0x82d4, 0x888b, 0x8cb8, 0x9000, + 0x902e, 0x968a, 0x9edb, 0x9bdb, 0x4ee3, 0x53f0, 0x5927, 0x7b2c, + 0x918d, 0x984c, 0x9df9, 0x6edd, 0x7027, 0x5353, 0x5544, 0x5b85, + 0x6258, 0x629e, 0x62d3, 0x6ca2, 0x6fef, 0x7422, 0x8a17, 0x9438, + 0x6fc1, 0x8afe, 0x8338, 0x51e7, 0x86f8, 0x53ea, + /* 0x43 */ + 0x53e9, 0x4f46, 0x9054, 0x8fb0, 0x596a, 0x8131, 0x5dfd, 0x7aea, + 0x8fbf, 0x68da, 0x8c37, 0x72f8, 0x9c48, 0x6a3d, 0x8ab0, 0x4e39, + 0x5358, 0x5606, 0x5766, 0x62c5, 0x63a2, 0x65e6, 0x6b4e, 0x6de1, + 0x6e5b, 0x70ad, 0x77ed, 0x7aef, 0x7baa, 0x7dbb, 0x803d, 0x80c6, + 0x86cb, 0x8a95, 0x935b, 0x56e3, 0x58c7, 0x5f3e, 0x65ad, 0x6696, + 0x6a80, 0x6bb5, 0x7537, 0x8ac7, 0x5024, 0x77e5, 0x5730, 0x5f1b, + 0x6065, 0x667a, 0x6c60, 0x75f4, 0x7a1a, 0x7f6e, 0x81f4, 0x8718, + 0x9045, 0x99b3, 0x7bc9, 0x755c, 0x7af9, 0x7b51, 0x84c4, 0x9010, + 0x79e9, 0x7a92, 0x8336, 0x5ae1, 0x7740, 0x4e2d, 0x4ef2, 0x5b99, + 0x5fe0, 0x62bd, 0x663c, 0x67f1, 0x6ce8, 0x866b, 0x8877, 0x8a3b, + 0x914e, 0x92f3, 0x99d0, 0x6a17, 0x7026, 0x732a, 0x82e7, 0x8457, + 0x8caf, 0x4e01, 0x5146, 0x51cb, 0x558b, 0x5bf5, + /* 0x44 */ + 0x5e16, 0x5e33, 0x5e81, 0x5f14, 0x5f35, 0x5f6b, 0x5fb4, 0x61f2, + 0x6311, 0x66a2, 0x671d, 0x6f6e, 0x7252, 0x753a, 0x773a, 0x8074, + 0x8139, 0x8178, 0x8776, 0x8abf, 0x8adc, 0x8d85, 0x8df3, 0x929a, + 0x9577, 0x9802, 0x9ce5, 0x52c5, 0x6357, 0x76f4, 0x6715, 0x6c88, + 0x73cd, 0x8cc3, 0x93ae, 0x9673, 0x6d25, 0x589c, 0x690e, 0x69cc, + 0x8ffd, 0x939a, 0x75db, 0x901a, 0x585a, 0x6802, 0x63b4, 0x69fb, + 0x4f43, 0x6f2c, 0x67d8, 0x8fbb, 0x8526, 0x7db4, 0x9354, 0x693f, + 0x6f70, 0x576a, 0x58f7, 0x5b2c, 0x7d2c, 0x722a, 0x540a, 0x91e3, + 0x9db4, 0x4ead, 0x4f4e, 0x505c, 0x5075, 0x5243, 0x8c9e, 0x5448, + 0x5824, 0x5b9a, 0x5e1d, 0x5e95, 0x5ead, 0x5ef7, 0x5f1f, 0x608c, + 0x62b5, 0x633a, 0x63d0, 0x68af, 0x6c40, 0x7887, 0x798e, 0x7a0b, + 0x7de0, 0x8247, 0x8a02, 0x8ae6, 0x8e44, 0x9013, + /* 0x45 */ + 0x90b8, 0x912d, 0x91d8, 0x9f0e, 0x6ce5, 0x6458, 0x64e2, 0x6575, + 0x6ef4, 0x7684, 0x7b1b, 0x9069, 0x93d1, 0x6eba, 0x54f2, 0x5fb9, + 0x64a4, 0x8f4d, 0x8fed, 0x9244, 0x5178, 0x586b, 0x5929, 0x5c55, + 0x5e97, 0x6dfb, 0x7e8f, 0x751c, 0x8cbc, 0x8ee2, 0x985b, 0x70b9, + 0x4f1d, 0x6bbf, 0x6fb1, 0x7530, 0x96fb, 0x514e, 0x5410, 0x5835, + 0x5857, 0x59ac, 0x5c60, 0x5f92, 0x6597, 0x675c, 0x6e21, 0x767b, + 0x83df, 0x8ced, 0x9014, 0x90fd, 0x934d, 0x7825, 0x783a, 0x52aa, + 0x5ea6, 0x571f, 0x5974, 0x6012, 0x5012, 0x515a, 0x51ac, 0x51cd, + 0x5200, 0x5510, 0x5854, 0x5858, 0x5957, 0x5b95, 0x5cf6, 0x5d8b, + 0x60bc, 0x6295, 0x642d, 0x6771, 0x6843, 0x68bc, 0x68df, 0x76d7, + 0x6dd8, 0x6e6f, 0x6d9b, 0x706f, 0x71c8, 0x5f53, 0x75d8, 0x7977, + 0x7b49, 0x7b54, 0x7b52, 0x7cd6, 0x7d71, 0x5230, + /* 0x46 */ + 0x8463, 0x8569, 0x85e4, 0x8a0e, 0x8b04, 0x8c46, 0x8e0f, 0x9003, + 0x900f, 0x9419, 0x9676, 0x982d, 0x9a30, 0x95d8, 0x50cd, 0x52d5, + 0x540c, 0x5802, 0x5c0e, 0x61a7, 0x649e, 0x6d1e, 0x77b3, 0x7ae5, + 0x80f4, 0x8404, 0x9053, 0x9285, 0x5ce0, 0x9d07, 0x533f, 0x5f97, + 0x5fb3, 0x6d9c, 0x7279, 0x7763, 0x79bf, 0x7be4, 0x6bd2, 0x72ec, + 0x8aad, 0x6803, 0x6a61, 0x51f8, 0x7a81, 0x6934, 0x5c4a, 0x9cf6, + 0x82eb, 0x5bc5, 0x9149, 0x701e, 0x5678, 0x5c6f, 0x60c7, 0x6566, + 0x6c8c, 0x8c5a, 0x9041, 0x9813, 0x5451, 0x66c7, 0x920d, 0x5948, + 0x90a3, 0x5185, 0x4e4d, 0x51ea, 0x8599, 0x8b0e, 0x7058, 0x637a, + 0x934b, 0x6962, 0x99b4, 0x7e04, 0x7577, 0x5357, 0x6960, 0x8edf, + 0x96e3, 0x6c5d, 0x4e8c, 0x5c3c, 0x5f10, 0x8fe9, 0x5302, 0x8cd1, + 0x8089, 0x8679, 0x5eff, 0x65e5, 0x4e73, 0x5165, + /* 0x47 */ + 0x5982, 0x5c3f, 0x97ee, 0x4efb, 0x598a, 0x5fcd, 0x8a8d, 0x6fe1, + 0x79b0, 0x7962, 0x5be7, 0x8471, 0x732b, 0x71b1, 0x5e74, 0x5ff5, + 0x637b, 0x649a, 0x71c3, 0x7c98, 0x4e43, 0x5efc, 0x4e4b, 0x57dc, + 0x56a2, 0x60a9, 0x6fc3, 0x7d0d, 0x80fd, 0x8133, 0x81bf, 0x8fb2, + 0x8997, 0x86a4, 0x5df4, 0x628a, 0x64ad, 0x8987, 0x6777, 0x6ce2, + 0x6d3e, 0x7436, 0x7834, 0x5a46, 0x7f75, 0x82ad, 0x99ac, 0x4ff3, + 0x5ec3, 0x62dd, 0x6392, 0x6557, 0x676f, 0x76c3, 0x724c, 0x80cc, + 0x80ba, 0x8f29, 0x914d, 0x500d, 0x57f9, 0x5a92, 0x6885, 0x6973, + 0x7164, 0x72fd, 0x8cb7, 0x58f2, 0x8ce0, 0x966a, 0x9019, 0x877f, + 0x79e4, 0x77e7, 0x8429, 0x4f2f, 0x5265, 0x535a, 0x62cd, 0x67cf, + 0x6cca, 0x767d, 0x7b94, 0x7c95, 0x8236, 0x8584, 0x8feb, 0x66dd, + 0x6f20, 0x7206, 0x7e1b, 0x83ab, 0x99c1, 0x9ea6, + /* 0x48 */ + 0x51fd, 0x7bb1, 0x7872, 0x7bb8, 0x8087, 0x7b48, 0x6ae8, 0x5e61, + 0x808c, 0x7551, 0x7560, 0x516b, 0x9262, 0x6e8c, 0x767a, 0x9197, + 0x9aea, 0x4f10, 0x7f70, 0x629c, 0x7b4f, 0x95a5, 0x9ce9, 0x567a, + 0x5859, 0x86e4, 0x96bc, 0x4f34, 0x5224, 0x534a, 0x53cd, 0x53db, + 0x5e06, 0x642c, 0x6591, 0x677f, 0x6c3e, 0x6c4e, 0x7248, 0x72af, + 0x73ed, 0x7554, 0x7e41, 0x822c, 0x85e9, 0x8ca9, 0x7bc4, 0x91c6, + 0x7169, 0x9812, 0x98ef, 0x633d, 0x6669, 0x756a, 0x76e4, 0x78d0, + 0x8543, 0x86ee, 0x532a, 0x5351, 0x5426, 0x5983, 0x5e87, 0x5f7c, + 0x60b2, 0x6249, 0x6279, 0x62ab, 0x6590, 0x6bd4, 0x6ccc, 0x75b2, + 0x76ae, 0x7891, 0x79d8, 0x7dcb, 0x7f77, 0x80a5, 0x88ab, 0x8ab9, + 0x8cbb, 0x907f, 0x975e, 0x98db, 0x6a0b, 0x7c38, 0x5099, 0x5c3e, + 0x5fae, 0x6787, 0x6bd8, 0x7435, 0x7709, 0x7f8e, + /* 0x49 */ + 0x9f3b, 0x67ca, 0x7a17, 0x5339, 0x758b, 0x9aed, 0x5f66, 0x819d, + 0x83f1, 0x8098, 0x5f3c, 0x5fc5, 0x7562, 0x7b46, 0x903c, 0x6867, + 0x59eb, 0x5a9b, 0x7d10, 0x767e, 0x8b2c, 0x4ff5, 0x5f6a, 0x6a19, + 0x6c37, 0x6f02, 0x74e2, 0x7968, 0x8868, 0x8a55, 0x8c79, 0x5edf, + 0x63cf, 0x75c5, 0x79d2, 0x82d7, 0x9328, 0x92f2, 0x849c, 0x86ed, + 0x9c2d, 0x54c1, 0x5f6c, 0x658c, 0x6d5c, 0x7015, 0x8ca7, 0x8cd3, + 0x983b, 0x654f, 0x74f6, 0x4e0d, 0x4ed8, 0x57e0, 0x592b, 0x5a66, + 0x5bcc, 0x51a8, 0x5e03, 0x5e9c, 0x6016, 0x6276, 0x6577, 0x65a7, + 0x666e, 0x6d6e, 0x7236, 0x7b26, 0x8150, 0x819a, 0x8299, 0x8b5c, + 0x8ca0, 0x8ce6, 0x8d74, 0x961c, 0x9644, 0x4fae, 0x64ab, 0x6b66, + 0x821e, 0x8461, 0x856a, 0x90e8, 0x5c01, 0x6953, 0x98a8, 0x847a, + 0x8557, 0x4f0f, 0x526f, 0x5fa9, 0x5e45, 0x670d, + /* 0x4a */ + 0x798f, 0x8179, 0x8907, 0x8986, 0x6df5, 0x5f17, 0x6255, 0x6cb8, + 0x4ecf, 0x7269, 0x9b92, 0x5206, 0x543b, 0x5674, 0x58b3, 0x61a4, + 0x626e, 0x711a, 0x596e, 0x7c89, 0x7cde, 0x7d1b, 0x96f0, 0x6587, + 0x805e, 0x4e19, 0x4f75, 0x5175, 0x5840, 0x5e63, 0x5e73, 0x5f0a, + 0x67c4, 0x4e26, 0x853d, 0x9589, 0x965b, 0x7c73, 0x9801, 0x50fb, + 0x58c1, 0x7656, 0x78a7, 0x5225, 0x77a5, 0x8511, 0x7b86, 0x504f, + 0x5909, 0x7247, 0x7bc7, 0x7de8, 0x8fba, 0x8fd4, 0x904d, 0x4fbf, + 0x52c9, 0x5a29, 0x5f01, 0x97ad, 0x4fdd, 0x8217, 0x92ea, 0x5703, + 0x6355, 0x6b69, 0x752b, 0x88dc, 0x8f14, 0x7a42, 0x52df, 0x5893, + 0x6155, 0x620a, 0x66ae, 0x6bcd, 0x7c3f, 0x83e9, 0x5023, 0x4ff8, + 0x5305, 0x5446, 0x5831, 0x5949, 0x5b9d, 0x5cf0, 0x5cef, 0x5d29, + 0x5e96, 0x62b1, 0x6367, 0x653e, 0x65b9, 0x670b, + /* 0x4b */ + 0x6cd5, 0x6ce1, 0x70f9, 0x7832, 0x7e2b, 0x80de, 0x82b3, 0x840c, + 0x84ec, 0x8702, 0x8912, 0x8a2a, 0x8c4a, 0x90a6, 0x92d2, 0x98fd, + 0x9cf3, 0x9d6c, 0x4e4f, 0x4ea1, 0x508d, 0x5256, 0x574a, 0x59a8, + 0x5e3d, 0x5fd8, 0x5fd9, 0x623f, 0x66b4, 0x671b, 0x67d0, 0x68d2, + 0x5192, 0x7d21, 0x80aa, 0x81a8, 0x8b00, 0x8c8c, 0x8cbf, 0x927e, + 0x9632, 0x5420, 0x982c, 0x5317, 0x50d5, 0x535c, 0x58a8, 0x64b2, + 0x6734, 0x7267, 0x7766, 0x7a46, 0x91e6, 0x52c3, 0x6ca1, 0x6b86, + 0x5800, 0x5e4c, 0x5954, 0x672c, 0x7ffb, 0x51e1, 0x76c6, 0x6469, + 0x78e8, 0x9b54, 0x9ebb, 0x57cb, 0x59b9, 0x6627, 0x679a, 0x6bce, + 0x54e9, 0x69d9, 0x5e55, 0x819c, 0x6795, 0x9baa, 0x67fe, 0x9c52, + 0x685d, 0x4ea6, 0x4fe3, 0x53c8, 0x62b9, 0x672b, 0x6cab, 0x8fc4, + 0x4fad, 0x7e6d, 0x9ebf, 0x4e07, 0x6162, 0x6e80, + /* 0x4c */ + 0x6f2b, 0x8513, 0x5473, 0x672a, 0x9b45, 0x5df3, 0x7b95, 0x5cac, + 0x5bc6, 0x871c, 0x6e4a, 0x84d1, 0x7a14, 0x8108, 0x5999, 0x7c8d, + 0x6c11, 0x7720, 0x52d9, 0x5922, 0x7121, 0x725f, 0x77db, 0x9727, + 0x9d61, 0x690b, 0x5a7f, 0x5a18, 0x51a5, 0x540d, 0x547d, 0x660e, + 0x76df, 0x8ff7, 0x9298, 0x9cf4, 0x59ea, 0x725d, 0x6ec5, 0x514d, + 0x68c9, 0x7dbf, 0x7dec, 0x9762, 0x9eba, 0x6478, 0x6a21, 0x8302, + 0x5984, 0x5b5f, 0x6bdb, 0x731b, 0x76f2, 0x7db2, 0x8017, 0x8499, + 0x5132, 0x6728, 0x9ed9, 0x76ee, 0x6762, 0x52ff, 0x9905, 0x5c24, + 0x623b, 0x7c7e, 0x8cb0, 0x554f, 0x60b6, 0x7d0b, 0x9580, 0x5301, + 0x4e5f, 0x51b6, 0x591c, 0x723a, 0x8036, 0x91ce, 0x5f25, 0x77e2, + 0x5384, 0x5f79, 0x7d04, 0x85ac, 0x8a33, 0x8e8d, 0x9756, 0x67f3, + 0x85ae, 0x9453, 0x6109, 0x6108, 0x6cb9, 0x7652, + /* 0x4d */ + 0x8aed, 0x8f38, 0x552f, 0x4f51, 0x512a, 0x52c7, 0x53cb, 0x5ba5, + 0x5e7d, 0x60a0, 0x6182, 0x63d6, 0x6709, 0x67da, 0x6e67, 0x6d8c, + 0x7336, 0x7337, 0x7531, 0x7950, 0x88d5, 0x8a98, 0x904a, 0x9091, + 0x90f5, 0x96c4, 0x878d, 0x5915, 0x4e88, 0x4f59, 0x4e0e, 0x8a89, + 0x8f3f, 0x9810, 0x50ad, 0x5e7c, 0x5996, 0x5bb9, 0x5eb8, 0x63da, + 0x63fa, 0x64c1, 0x66dc, 0x694a, 0x69d8, 0x6d0b, 0x6eb6, 0x7194, + 0x7528, 0x7aaf, 0x7f8a, 0x8000, 0x8449, 0x84c9, 0x8981, 0x8b21, + 0x8e0a, 0x9065, 0x967d, 0x990a, 0x617e, 0x6291, 0x6b32, 0x6c83, + 0x6d74, 0x7fcc, 0x7ffc, 0x6dc0, 0x7f85, 0x87ba, 0x88f8, 0x6765, + 0x83b1, 0x983c, 0x96f7, 0x6d1b, 0x7d61, 0x843d, 0x916a, 0x4e71, + 0x5375, 0x5d50, 0x6b04, 0x6feb, 0x85cd, 0x862d, 0x89a7, 0x5229, + 0x540f, 0x5c65, 0x674e, 0x68a8, 0x7406, 0x7483, + /* 0x4e */ + 0x75e2, 0x88cf, 0x88e1, 0x91cc, 0x96e2, 0x9678, 0x5f8b, 0x7387, + 0x7acb, 0x844e, 0x63a0, 0x7565, 0x5289, 0x6d41, 0x6e9c, 0x7409, + 0x7559, 0x786b, 0x7c92, 0x9686, 0x7adc, 0x9f8d, 0x4fb6, 0x616e, + 0x65c5, 0x865c, 0x4e86, 0x4eae, 0x50da, 0x4e21, 0x51cc, 0x5bee, + 0x6599, 0x6881, 0x6dbc, 0x731f, 0x7642, 0x77ad, 0x7a1c, 0x7ce7, + 0x826f, 0x8ad2, 0x907c, 0x91cf, 0x9675, 0x9818, 0x529b, 0x7dd1, + 0x502b, 0x5398, 0x6797, 0x6dcb, 0x71d0, 0x7433, 0x81e8, 0x8f2a, + 0x96a3, 0x9c57, 0x9e9f, 0x7460, 0x5841, 0x6d99, 0x7d2f, 0x985e, + 0x4ee4, 0x4f36, 0x4f8b, 0x51b7, 0x52b1, 0x5dba, 0x601c, 0x73b2, + 0x793c, 0x82d3, 0x9234, 0x96b7, 0x96f6, 0x970a, 0x9e97, 0x9f62, + 0x66a6, 0x6b74, 0x5217, 0x52a3, 0x70c8, 0x88c2, 0x5ec9, 0x604b, + 0x6190, 0x6f23, 0x7149, 0x7c3e, 0x7df4, 0x806f, + /* 0x4f */ + 0x84ee, 0x9023, 0x932c, 0x5442, 0x9b6f, 0x6ad3, 0x7089, 0x8cc2, + 0x8def, 0x9732, 0x52b4, 0x5a41, 0x5eca, 0x5f04, 0x6717, 0x697c, + 0x6994, 0x6d6a, 0x6f0f, 0x7262, 0x72fc, 0x7bed, 0x8001, 0x807e, + 0x874b, 0x90ce, 0x516d, 0x9e93, 0x7984, 0x808b, 0x9332, 0x8ad6, + 0x502d, 0x548c, 0x8a71, 0x6b6a, 0x8cc4, 0x8107, 0x60d1, 0x67a0, + 0x9df2, 0x4e99, 0x4e98, 0x9c10, 0x8a6b, 0x85c1, 0x8568, 0x6900, + 0x6e7e, 0x7897, 0x8155, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x50 */ + 0x5f0c, 0x4e10, 0x4e15, 0x4e2a, 0x4e31, 0x4e36, 0x4e3c, 0x4e3f, + 0x4e42, 0x4e56, 0x4e58, 0x4e82, 0x4e85, 0x8c6b, 0x4e8a, 0x8212, + 0x5f0d, 0x4e8e, 0x4e9e, 0x4e9f, 0x4ea0, 0x4ea2, 0x4eb0, 0x4eb3, + 0x4eb6, 0x4ece, 0x4ecd, 0x4ec4, 0x4ec6, 0x4ec2, 0x4ed7, 0x4ede, + 0x4eed, 0x4edf, 0x4ef7, 0x4f09, 0x4f5a, 0x4f30, 0x4f5b, 0x4f5d, + 0x4f57, 0x4f47, 0x4f76, 0x4f88, 0x4f8f, 0x4f98, 0x4f7b, 0x4f69, + 0x4f70, 0x4f91, 0x4f6f, 0x4f86, 0x4f96, 0x5118, 0x4fd4, 0x4fdf, + 0x4fce, 0x4fd8, 0x4fdb, 0x4fd1, 0x4fda, 0x4fd0, 0x4fe4, 0x4fe5, + 0x501a, 0x5028, 0x5014, 0x502a, 0x5025, 0x5005, 0x4f1c, 0x4ff6, + 0x5021, 0x5029, 0x502c, 0x4ffe, 0x4fef, 0x5011, 0x5006, 0x5043, + 0x5047, 0x6703, 0x5055, 0x5050, 0x5048, 0x505a, 0x5056, 0x506c, + 0x5078, 0x5080, 0x509a, 0x5085, 0x50b4, 0x50b2, + /* 0x51 */ + 0x50c9, 0x50ca, 0x50b3, 0x50c2, 0x50d6, 0x50de, 0x50e5, 0x50ed, + 0x50e3, 0x50ee, 0x50f9, 0x50f5, 0x5109, 0x5101, 0x5102, 0x5116, + 0x5115, 0x5114, 0x511a, 0x5121, 0x513a, 0x5137, 0x513c, 0x513b, + 0x513f, 0x5140, 0x5152, 0x514c, 0x5154, 0x5162, 0x7af8, 0x5169, + 0x516a, 0x516e, 0x5180, 0x5182, 0x56d8, 0x518c, 0x5189, 0x518f, + 0x5191, 0x5193, 0x5195, 0x5196, 0x51a4, 0x51a6, 0x51a2, 0x51a9, + 0x51aa, 0x51ab, 0x51b3, 0x51b1, 0x51b2, 0x51b0, 0x51b5, 0x51bd, + 0x51c5, 0x51c9, 0x51db, 0x51e0, 0x8655, 0x51e9, 0x51ed, 0x51f0, + 0x51f5, 0x51fe, 0x5204, 0x520b, 0x5214, 0x520e, 0x5227, 0x522a, + 0x522e, 0x5233, 0x5239, 0x524f, 0x5244, 0x524b, 0x524c, 0x525e, + 0x5254, 0x526a, 0x5274, 0x5269, 0x5273, 0x527f, 0x527d, 0x528d, + 0x5294, 0x5292, 0x5271, 0x5288, 0x5291, 0x8fa8, + /* 0x52 */ + 0x8fa7, 0x52ac, 0x52ad, 0x52bc, 0x52b5, 0x52c1, 0x52cd, 0x52d7, + 0x52de, 0x52e3, 0x52e6, 0x98ed, 0x52e0, 0x52f3, 0x52f5, 0x52f8, + 0x52f9, 0x5306, 0x5308, 0x7538, 0x530d, 0x5310, 0x530f, 0x5315, + 0x531a, 0x5323, 0x532f, 0x5331, 0x5333, 0x5338, 0x5340, 0x5346, + 0x5345, 0x4e17, 0x5349, 0x534d, 0x51d6, 0x535e, 0x5369, 0x536e, + 0x5918, 0x537b, 0x5377, 0x5382, 0x5396, 0x53a0, 0x53a6, 0x53a5, + 0x53ae, 0x53b0, 0x53b6, 0x53c3, 0x7c12, 0x96d9, 0x53df, 0x66fc, + 0x71ee, 0x53ee, 0x53e8, 0x53ed, 0x53fa, 0x5401, 0x543d, 0x5440, + 0x542c, 0x542d, 0x543c, 0x542e, 0x5436, 0x5429, 0x541d, 0x544e, + 0x548f, 0x5475, 0x548e, 0x545f, 0x5471, 0x5477, 0x5470, 0x5492, + 0x547b, 0x5480, 0x5476, 0x5484, 0x5490, 0x5486, 0x54c7, 0x54a2, + 0x54b8, 0x54a5, 0x54ac, 0x54c4, 0x54c8, 0x54a8, + /* 0x53 */ + 0x54ab, 0x54c2, 0x54a4, 0x54be, 0x54bc, 0x54d8, 0x54e5, 0x54e6, + 0x550f, 0x5514, 0x54fd, 0x54ee, 0x54ed, 0x54fa, 0x54e2, 0x5539, + 0x5540, 0x5563, 0x554c, 0x552e, 0x555c, 0x5545, 0x5556, 0x5557, + 0x5538, 0x5533, 0x555d, 0x5599, 0x5580, 0x54af, 0x558a, 0x559f, + 0x557b, 0x557e, 0x5598, 0x559e, 0x55ae, 0x557c, 0x5583, 0x55a9, + 0x5587, 0x55a8, 0x55da, 0x55c5, 0x55df, 0x55c4, 0x55dc, 0x55e4, + 0x55d4, 0x5614, 0x55f7, 0x5616, 0x55fe, 0x55fd, 0x561b, 0x55f9, + 0x564e, 0x5650, 0x71df, 0x5634, 0x5636, 0x5632, 0x5638, 0x566b, + 0x5664, 0x562f, 0x566c, 0x566a, 0x5686, 0x5680, 0x568a, 0x56a0, + 0x5694, 0x568f, 0x56a5, 0x56ae, 0x56b6, 0x56b4, 0x56c2, 0x56bc, + 0x56c1, 0x56c3, 0x56c0, 0x56c8, 0x56ce, 0x56d1, 0x56d3, 0x56d7, + 0x56ee, 0x56f9, 0x5700, 0x56ff, 0x5704, 0x5709, + /* 0x54 */ + 0x5708, 0x570b, 0x570d, 0x5713, 0x5718, 0x5716, 0x55c7, 0x571c, + 0x5726, 0x5737, 0x5738, 0x574e, 0x573b, 0x5740, 0x574f, 0x5769, + 0x57c0, 0x5788, 0x5761, 0x577f, 0x5789, 0x5793, 0x57a0, 0x57b3, + 0x57a4, 0x57aa, 0x57b0, 0x57c3, 0x57c6, 0x57d4, 0x57d2, 0x57d3, + 0x580a, 0x57d6, 0x57e3, 0x580b, 0x5819, 0x581d, 0x5872, 0x5821, + 0x5862, 0x584b, 0x5870, 0x6bc0, 0x5852, 0x583d, 0x5879, 0x5885, + 0x58b9, 0x589f, 0x58ab, 0x58ba, 0x58de, 0x58bb, 0x58b8, 0x58ae, + 0x58c5, 0x58d3, 0x58d1, 0x58d7, 0x58d9, 0x58d8, 0x58e5, 0x58dc, + 0x58e4, 0x58df, 0x58ef, 0x58fa, 0x58f9, 0x58fb, 0x58fc, 0x58fd, + 0x5902, 0x590a, 0x5910, 0x591b, 0x68a6, 0x5925, 0x592c, 0x592d, + 0x5932, 0x5938, 0x593e, 0x7ad2, 0x5955, 0x5950, 0x594e, 0x595a, + 0x5958, 0x5962, 0x5960, 0x5967, 0x596c, 0x5969, + /* 0x55 */ + 0x5978, 0x5981, 0x599d, 0x4f5e, 0x4fab, 0x59a3, 0x59b2, 0x59c6, + 0x59e8, 0x59dc, 0x598d, 0x59d9, 0x59da, 0x5a25, 0x5a1f, 0x5a11, + 0x5a1c, 0x5a09, 0x5a1a, 0x5a40, 0x5a6c, 0x5a49, 0x5a35, 0x5a36, + 0x5a62, 0x5a6a, 0x5a9a, 0x5abc, 0x5abe, 0x5acb, 0x5ac2, 0x5abd, + 0x5ae3, 0x5ad7, 0x5ae6, 0x5ae9, 0x5ad6, 0x5afa, 0x5afb, 0x5b0c, + 0x5b0b, 0x5b16, 0x5b32, 0x5ad0, 0x5b2a, 0x5b36, 0x5b3e, 0x5b43, + 0x5b45, 0x5b40, 0x5b51, 0x5b55, 0x5b5a, 0x5b5b, 0x5b65, 0x5b69, + 0x5b70, 0x5b73, 0x5b75, 0x5b78, 0x6588, 0x5b7a, 0x5b80, 0x5b83, + 0x5ba6, 0x5bb8, 0x5bc3, 0x5bc7, 0x5bc9, 0x5bd4, 0x5bd0, 0x5be4, + 0x5be6, 0x5be2, 0x5bde, 0x5be5, 0x5beb, 0x5bf0, 0x5bf6, 0x5bf3, + 0x5c05, 0x5c07, 0x5c08, 0x5c0d, 0x5c13, 0x5c20, 0x5c22, 0x5c28, + 0x5c38, 0x5c39, 0x5c41, 0x5c46, 0x5c4e, 0x5c53, + /* 0x56 */ + 0x5c50, 0x5c4f, 0x5b71, 0x5c6c, 0x5c6e, 0x4e62, 0x5c76, 0x5c79, + 0x5c8c, 0x5c91, 0x5c94, 0x599b, 0x5cab, 0x5cbb, 0x5cb6, 0x5cbc, + 0x5cb7, 0x5cc5, 0x5cbe, 0x5cc7, 0x5cd9, 0x5ce9, 0x5cfd, 0x5cfa, + 0x5ced, 0x5d8c, 0x5cea, 0x5d0b, 0x5d15, 0x5d17, 0x5d5c, 0x5d1f, + 0x5d1b, 0x5d11, 0x5d14, 0x5d22, 0x5d1a, 0x5d19, 0x5d18, 0x5d4c, + 0x5d52, 0x5d4e, 0x5d4b, 0x5d6c, 0x5d73, 0x5d76, 0x5d87, 0x5d84, + 0x5d82, 0x5da2, 0x5d9d, 0x5dac, 0x5dae, 0x5dbd, 0x5d90, 0x5db7, + 0x5dbc, 0x5dc9, 0x5dcd, 0x5dd3, 0x5dd2, 0x5dd6, 0x5ddb, 0x5deb, + 0x5df2, 0x5df5, 0x5e0b, 0x5e1a, 0x5e19, 0x5e11, 0x5e1b, 0x5e36, + 0x5e37, 0x5e44, 0x5e43, 0x5e40, 0x5e4e, 0x5e57, 0x5e54, 0x5e5f, + 0x5e62, 0x5e64, 0x5e47, 0x5e75, 0x5e76, 0x5e7a, 0x9ebc, 0x5e7f, + 0x5ea0, 0x5ec1, 0x5ec2, 0x5ec8, 0x5ed0, 0x5ecf, + /* 0x57 */ + 0x5ed6, 0x5ee3, 0x5edd, 0x5eda, 0x5edb, 0x5ee2, 0x5ee1, 0x5ee8, + 0x5ee9, 0x5eec, 0x5ef1, 0x5ef3, 0x5ef0, 0x5ef4, 0x5ef8, 0x5efe, + 0x5f03, 0x5f09, 0x5f5d, 0x5f5c, 0x5f0b, 0x5f11, 0x5f16, 0x5f29, + 0x5f2d, 0x5f38, 0x5f41, 0x5f48, 0x5f4c, 0x5f4e, 0x5f2f, 0x5f51, + 0x5f56, 0x5f57, 0x5f59, 0x5f61, 0x5f6d, 0x5f73, 0x5f77, 0x5f83, + 0x5f82, 0x5f7f, 0x5f8a, 0x5f88, 0x5f91, 0x5f87, 0x5f9e, 0x5f99, + 0x5f98, 0x5fa0, 0x5fa8, 0x5fad, 0x5fbc, 0x5fd6, 0x5ffb, 0x5fe4, + 0x5ff8, 0x5ff1, 0x5fdd, 0x60b3, 0x5fff, 0x6021, 0x6060, 0x6019, + 0x6010, 0x6029, 0x600e, 0x6031, 0x601b, 0x6015, 0x602b, 0x6026, + 0x600f, 0x603a, 0x605a, 0x6041, 0x606a, 0x6077, 0x605f, 0x604a, + 0x6046, 0x604d, 0x6063, 0x6043, 0x6064, 0x6042, 0x606c, 0x606b, + 0x6059, 0x6081, 0x608d, 0x60e7, 0x6083, 0x609a, + /* 0x58 */ + 0x6084, 0x609b, 0x6096, 0x6097, 0x6092, 0x60a7, 0x608b, 0x60e1, + 0x60b8, 0x60e0, 0x60d3, 0x60b4, 0x5ff0, 0x60bd, 0x60c6, 0x60b5, + 0x60d8, 0x614d, 0x6115, 0x6106, 0x60f6, 0x60f7, 0x6100, 0x60f4, + 0x60fa, 0x6103, 0x6121, 0x60fb, 0x60f1, 0x610d, 0x610e, 0x6147, + 0x613e, 0x6128, 0x6127, 0x614a, 0x613f, 0x613c, 0x612c, 0x6134, + 0x613d, 0x6142, 0x6144, 0x6173, 0x6177, 0x6158, 0x6159, 0x615a, + 0x616b, 0x6174, 0x616f, 0x6165, 0x6171, 0x615f, 0x615d, 0x6153, + 0x6175, 0x6199, 0x6196, 0x6187, 0x61ac, 0x6194, 0x619a, 0x618a, + 0x6191, 0x61ab, 0x61ae, 0x61cc, 0x61ca, 0x61c9, 0x61f7, 0x61c8, + 0x61c3, 0x61c6, 0x61ba, 0x61cb, 0x7f79, 0x61cd, 0x61e6, 0x61e3, + 0x61f6, 0x61fa, 0x61f4, 0x61ff, 0x61fd, 0x61fc, 0x61fe, 0x6200, + 0x6208, 0x6209, 0x620d, 0x620c, 0x6214, 0x621b, + /* 0x59 */ + 0x621e, 0x6221, 0x622a, 0x622e, 0x6230, 0x6232, 0x6233, 0x6241, + 0x624e, 0x625e, 0x6263, 0x625b, 0x6260, 0x6268, 0x627c, 0x6282, + 0x6289, 0x627e, 0x6292, 0x6293, 0x6296, 0x62d4, 0x6283, 0x6294, + 0x62d7, 0x62d1, 0x62bb, 0x62cf, 0x62ff, 0x62c6, 0x64d4, 0x62c8, + 0x62dc, 0x62cc, 0x62ca, 0x62c2, 0x62c7, 0x629b, 0x62c9, 0x630c, + 0x62ee, 0x62f1, 0x6327, 0x6302, 0x6308, 0x62ef, 0x62f5, 0x6350, + 0x633e, 0x634d, 0x641c, 0x634f, 0x6396, 0x638e, 0x6380, 0x63ab, + 0x6376, 0x63a3, 0x638f, 0x6389, 0x639f, 0x63b5, 0x636b, 0x6369, + 0x63be, 0x63e9, 0x63c0, 0x63c6, 0x63e3, 0x63c9, 0x63d2, 0x63f6, + 0x63c4, 0x6416, 0x6434, 0x6406, 0x6413, 0x6426, 0x6436, 0x651d, + 0x6417, 0x6428, 0x640f, 0x6467, 0x646f, 0x6476, 0x644e, 0x652a, + 0x6495, 0x6493, 0x64a5, 0x64a9, 0x6488, 0x64bc, + /* 0x5a */ + 0x64da, 0x64d2, 0x64c5, 0x64c7, 0x64bb, 0x64d8, 0x64c2, 0x64f1, + 0x64e7, 0x8209, 0x64e0, 0x64e1, 0x62ac, 0x64e3, 0x64ef, 0x652c, + 0x64f6, 0x64f4, 0x64f2, 0x64fa, 0x6500, 0x64fd, 0x6518, 0x651c, + 0x6505, 0x6524, 0x6523, 0x652b, 0x6534, 0x6535, 0x6537, 0x6536, + 0x6538, 0x754b, 0x6548, 0x6556, 0x6555, 0x654d, 0x6558, 0x655e, + 0x655d, 0x6572, 0x6578, 0x6582, 0x6583, 0x8b8a, 0x659b, 0x659f, + 0x65ab, 0x65b7, 0x65c3, 0x65c6, 0x65c1, 0x65c4, 0x65cc, 0x65d2, + 0x65db, 0x65d9, 0x65e0, 0x65e1, 0x65f1, 0x6772, 0x660a, 0x6603, + 0x65fb, 0x6773, 0x6635, 0x6636, 0x6634, 0x661c, 0x664f, 0x6644, + 0x6649, 0x6641, 0x665e, 0x665d, 0x6664, 0x6667, 0x6668, 0x665f, + 0x6662, 0x6670, 0x6683, 0x6688, 0x668e, 0x6689, 0x6684, 0x6698, + 0x669d, 0x66c1, 0x66b9, 0x66c9, 0x66be, 0x66bc, + /* 0x5b */ + 0x66c4, 0x66b8, 0x66d6, 0x66da, 0x66e0, 0x663f, 0x66e6, 0x66e9, + 0x66f0, 0x66f5, 0x66f7, 0x670f, 0x6716, 0x671e, 0x6726, 0x6727, + 0x9738, 0x672e, 0x673f, 0x6736, 0x6741, 0x6738, 0x6737, 0x6746, + 0x675e, 0x6760, 0x6759, 0x6763, 0x6764, 0x6789, 0x6770, 0x67a9, + 0x677c, 0x676a, 0x678c, 0x678b, 0x67a6, 0x67a1, 0x6785, 0x67b7, + 0x67ef, 0x67b4, 0x67ec, 0x67b3, 0x67e9, 0x67b8, 0x67e4, 0x67de, + 0x67dd, 0x67e2, 0x67ee, 0x67b9, 0x67ce, 0x67c6, 0x67e7, 0x6a9c, + 0x681e, 0x6846, 0x6829, 0x6840, 0x684d, 0x6832, 0x684e, 0x68b3, + 0x682b, 0x6859, 0x6863, 0x6877, 0x687f, 0x689f, 0x688f, 0x68ad, + 0x6894, 0x689d, 0x689b, 0x6883, 0x6aae, 0x68b9, 0x6874, 0x68b5, + 0x68a0, 0x68ba, 0x690f, 0x688d, 0x687e, 0x6901, 0x68ca, 0x6908, + 0x68d8, 0x6922, 0x6926, 0x68e1, 0x690c, 0x68cd, + /* 0x5c */ + 0x68d4, 0x68e7, 0x68d5, 0x6936, 0x6912, 0x6904, 0x68d7, 0x68e3, + 0x6925, 0x68f9, 0x68e0, 0x68ef, 0x6928, 0x692a, 0x691a, 0x6923, + 0x6921, 0x68c6, 0x6979, 0x6977, 0x695c, 0x6978, 0x696b, 0x6954, + 0x697e, 0x696e, 0x6939, 0x6974, 0x693d, 0x6959, 0x6930, 0x6961, + 0x695e, 0x695d, 0x6981, 0x696a, 0x69b2, 0x69ae, 0x69d0, 0x69bf, + 0x69c1, 0x69d3, 0x69be, 0x69ce, 0x5be8, 0x69ca, 0x69dd, 0x69bb, + 0x69c3, 0x69a7, 0x6a2e, 0x6991, 0x69a0, 0x699c, 0x6995, 0x69b4, + 0x69de, 0x69e8, 0x6a02, 0x6a1b, 0x69ff, 0x6b0a, 0x69f9, 0x69f2, + 0x69e7, 0x6a05, 0x69b1, 0x6a1e, 0x69ed, 0x6a14, 0x69eb, 0x6a0a, + 0x6a12, 0x6ac1, 0x6a23, 0x6a13, 0x6a44, 0x6a0c, 0x6a72, 0x6a36, + 0x6a78, 0x6a47, 0x6a62, 0x6a59, 0x6a66, 0x6a48, 0x6a38, 0x6a22, + 0x6a90, 0x6a8d, 0x6aa0, 0x6a84, 0x6aa2, 0x6aa3, + /* 0x5d */ + 0x6a97, 0x8617, 0x6abb, 0x6ac3, 0x6ac2, 0x6ab8, 0x6ab3, 0x6aac, + 0x6ade, 0x6ad1, 0x6adf, 0x6aaa, 0x6ada, 0x6aea, 0x6afb, 0x6b05, + 0x8616, 0x6afa, 0x6b12, 0x6b16, 0x9b31, 0x6b1f, 0x6b38, 0x6b37, + 0x76dc, 0x6b39, 0x98ee, 0x6b47, 0x6b43, 0x6b49, 0x6b50, 0x6b59, + 0x6b54, 0x6b5b, 0x6b5f, 0x6b61, 0x6b78, 0x6b79, 0x6b7f, 0x6b80, + 0x6b84, 0x6b83, 0x6b8d, 0x6b98, 0x6b95, 0x6b9e, 0x6ba4, 0x6baa, + 0x6bab, 0x6baf, 0x6bb2, 0x6bb1, 0x6bb3, 0x6bb7, 0x6bbc, 0x6bc6, + 0x6bcb, 0x6bd3, 0x6bdf, 0x6bec, 0x6beb, 0x6bf3, 0x6bef, 0x9ebe, + 0x6c08, 0x6c13, 0x6c14, 0x6c1b, 0x6c24, 0x6c23, 0x6c5e, 0x6c55, + 0x6c62, 0x6c6a, 0x6c82, 0x6c8d, 0x6c9a, 0x6c81, 0x6c9b, 0x6c7e, + 0x6c68, 0x6c73, 0x6c92, 0x6c90, 0x6cc4, 0x6cf1, 0x6cd3, 0x6cbd, + 0x6cd7, 0x6cc5, 0x6cdd, 0x6cae, 0x6cb1, 0x6cbe, + /* 0x5e */ + 0x6cba, 0x6cdb, 0x6cef, 0x6cd9, 0x6cea, 0x6d1f, 0x884d, 0x6d36, + 0x6d2b, 0x6d3d, 0x6d38, 0x6d19, 0x6d35, 0x6d33, 0x6d12, 0x6d0c, + 0x6d63, 0x6d93, 0x6d64, 0x6d5a, 0x6d79, 0x6d59, 0x6d8e, 0x6d95, + 0x6fe4, 0x6d85, 0x6df9, 0x6e15, 0x6e0a, 0x6db5, 0x6dc7, 0x6de6, + 0x6db8, 0x6dc6, 0x6dec, 0x6dde, 0x6dcc, 0x6de8, 0x6dd2, 0x6dc5, + 0x6dfa, 0x6dd9, 0x6de4, 0x6dd5, 0x6dea, 0x6dee, 0x6e2d, 0x6e6e, + 0x6e2e, 0x6e19, 0x6e72, 0x6e5f, 0x6e3e, 0x6e23, 0x6e6b, 0x6e2b, + 0x6e76, 0x6e4d, 0x6e1f, 0x6e43, 0x6e3a, 0x6e4e, 0x6e24, 0x6eff, + 0x6e1d, 0x6e38, 0x6e82, 0x6eaa, 0x6e98, 0x6ec9, 0x6eb7, 0x6ed3, + 0x6ebd, 0x6eaf, 0x6ec4, 0x6eb2, 0x6ed4, 0x6ed5, 0x6e8f, 0x6ea5, + 0x6ec2, 0x6e9f, 0x6f41, 0x6f11, 0x704c, 0x6eec, 0x6ef8, 0x6efe, + 0x6f3f, 0x6ef2, 0x6f31, 0x6eef, 0x6f32, 0x6ecc, + /* 0x5f */ + 0x6f3e, 0x6f13, 0x6ef7, 0x6f86, 0x6f7a, 0x6f78, 0x6f81, 0x6f80, + 0x6f6f, 0x6f5b, 0x6ff3, 0x6f6d, 0x6f82, 0x6f7c, 0x6f58, 0x6f8e, + 0x6f91, 0x6fc2, 0x6f66, 0x6fb3, 0x6fa3, 0x6fa1, 0x6fa4, 0x6fb9, + 0x6fc6, 0x6faa, 0x6fdf, 0x6fd5, 0x6fec, 0x6fd4, 0x6fd8, 0x6ff1, + 0x6fee, 0x6fdb, 0x7009, 0x700b, 0x6ffa, 0x7011, 0x7001, 0x700f, + 0x6ffe, 0x701b, 0x701a, 0x6f74, 0x701d, 0x7018, 0x701f, 0x7030, + 0x703e, 0x7032, 0x7051, 0x7063, 0x7099, 0x7092, 0x70af, 0x70f1, + 0x70ac, 0x70b8, 0x70b3, 0x70ae, 0x70df, 0x70cb, 0x70dd, 0x70d9, + 0x7109, 0x70fd, 0x711c, 0x7119, 0x7165, 0x7155, 0x7188, 0x7166, + 0x7162, 0x714c, 0x7156, 0x716c, 0x718f, 0x71fb, 0x7184, 0x7195, + 0x71a8, 0x71ac, 0x71d7, 0x71b9, 0x71be, 0x71d2, 0x71c9, 0x71d4, + 0x71ce, 0x71e0, 0x71ec, 0x71e7, 0x71f5, 0x71fc, + /* 0x60 */ + 0x71f9, 0x71ff, 0x720d, 0x7210, 0x721b, 0x7228, 0x722d, 0x722c, + 0x7230, 0x7232, 0x723b, 0x723c, 0x723f, 0x7240, 0x7246, 0x724b, + 0x7258, 0x7274, 0x727e, 0x7282, 0x7281, 0x7287, 0x7292, 0x7296, + 0x72a2, 0x72a7, 0x72b9, 0x72b2, 0x72c3, 0x72c6, 0x72c4, 0x72ce, + 0x72d2, 0x72e2, 0x72e0, 0x72e1, 0x72f9, 0x72f7, 0x500f, 0x7317, + 0x730a, 0x731c, 0x7316, 0x731d, 0x7334, 0x732f, 0x7329, 0x7325, + 0x733e, 0x734e, 0x734f, 0x9ed8, 0x7357, 0x736a, 0x7368, 0x7370, + 0x7378, 0x7375, 0x737b, 0x737a, 0x73c8, 0x73b3, 0x73ce, 0x73bb, + 0x73c0, 0x73e5, 0x73ee, 0x73de, 0x74a2, 0x7405, 0x746f, 0x7425, + 0x73f8, 0x7432, 0x743a, 0x7455, 0x743f, 0x745f, 0x7459, 0x7441, + 0x745c, 0x7469, 0x7470, 0x7463, 0x746a, 0x7476, 0x747e, 0x748b, + 0x749e, 0x74a7, 0x74ca, 0x74cf, 0x74d4, 0x73f1, + /* 0x61 */ + 0x74e0, 0x74e3, 0x74e7, 0x74e9, 0x74ee, 0x74f2, 0x74f0, 0x74f1, + 0x74f8, 0x74f7, 0x7504, 0x7503, 0x7505, 0x750c, 0x750e, 0x750d, + 0x7515, 0x7513, 0x751e, 0x7526, 0x752c, 0x753c, 0x7544, 0x754d, + 0x754a, 0x7549, 0x755b, 0x7546, 0x755a, 0x7569, 0x7564, 0x7567, + 0x756b, 0x756d, 0x7578, 0x7576, 0x7586, 0x7587, 0x7574, 0x758a, + 0x7589, 0x7582, 0x7594, 0x759a, 0x759d, 0x75a5, 0x75a3, 0x75c2, + 0x75b3, 0x75c3, 0x75b5, 0x75bd, 0x75b8, 0x75bc, 0x75b1, 0x75cd, + 0x75ca, 0x75d2, 0x75d9, 0x75e3, 0x75de, 0x75fe, 0x75ff, 0x75fc, + 0x7601, 0x75f0, 0x75fa, 0x75f2, 0x75f3, 0x760b, 0x760d, 0x7609, + 0x761f, 0x7627, 0x7620, 0x7621, 0x7622, 0x7624, 0x7634, 0x7630, + 0x763b, 0x7647, 0x7648, 0x7646, 0x765c, 0x7658, 0x7661, 0x7662, + 0x7668, 0x7669, 0x766a, 0x7667, 0x766c, 0x7670, + /* 0x62 */ + 0x7672, 0x7676, 0x7678, 0x767c, 0x7680, 0x7683, 0x7688, 0x768b, + 0x768e, 0x7696, 0x7693, 0x7699, 0x769a, 0x76b0, 0x76b4, 0x76b8, + 0x76b9, 0x76ba, 0x76c2, 0x76cd, 0x76d6, 0x76d2, 0x76de, 0x76e1, + 0x76e5, 0x76e7, 0x76ea, 0x862f, 0x76fb, 0x7708, 0x7707, 0x7704, + 0x7729, 0x7724, 0x771e, 0x7725, 0x7726, 0x771b, 0x7737, 0x7738, + 0x7747, 0x775a, 0x7768, 0x776b, 0x775b, 0x7765, 0x777f, 0x777e, + 0x7779, 0x778e, 0x778b, 0x7791, 0x77a0, 0x779e, 0x77b0, 0x77b6, + 0x77b9, 0x77bf, 0x77bc, 0x77bd, 0x77bb, 0x77c7, 0x77cd, 0x77d7, + 0x77da, 0x77dc, 0x77e3, 0x77ee, 0x77fc, 0x780c, 0x7812, 0x7926, + 0x7820, 0x792a, 0x7845, 0x788e, 0x7874, 0x7886, 0x787c, 0x789a, + 0x788c, 0x78a3, 0x78b5, 0x78aa, 0x78af, 0x78d1, 0x78c6, 0x78cb, + 0x78d4, 0x78be, 0x78bc, 0x78c5, 0x78ca, 0x78ec, + /* 0x63 */ + 0x78e7, 0x78da, 0x78fd, 0x78f4, 0x7907, 0x7912, 0x7911, 0x7919, + 0x792c, 0x792b, 0x7940, 0x7960, 0x7957, 0x795f, 0x795a, 0x7955, + 0x7953, 0x797a, 0x797f, 0x798a, 0x799d, 0x79a7, 0x9f4b, 0x79aa, + 0x79ae, 0x79b3, 0x79b9, 0x79ba, 0x79c9, 0x79d5, 0x79e7, 0x79ec, + 0x79e1, 0x79e3, 0x7a08, 0x7a0d, 0x7a18, 0x7a19, 0x7a20, 0x7a1f, + 0x7980, 0x7a31, 0x7a3b, 0x7a3e, 0x7a37, 0x7a43, 0x7a57, 0x7a49, + 0x7a61, 0x7a62, 0x7a69, 0x9f9d, 0x7a70, 0x7a79, 0x7a7d, 0x7a88, + 0x7a97, 0x7a95, 0x7a98, 0x7a96, 0x7aa9, 0x7ac8, 0x7ab0, 0x7ab6, + 0x7ac5, 0x7ac4, 0x7abf, 0x9083, 0x7ac7, 0x7aca, 0x7acd, 0x7acf, + 0x7ad5, 0x7ad3, 0x7ad9, 0x7ada, 0x7add, 0x7ae1, 0x7ae2, 0x7ae6, + 0x7aed, 0x7af0, 0x7b02, 0x7b0f, 0x7b0a, 0x7b06, 0x7b33, 0x7b18, + 0x7b19, 0x7b1e, 0x7b35, 0x7b28, 0x7b36, 0x7b50, + /* 0x64 */ + 0x7b7a, 0x7b04, 0x7b4d, 0x7b0b, 0x7b4c, 0x7b45, 0x7b75, 0x7b65, + 0x7b74, 0x7b67, 0x7b70, 0x7b71, 0x7b6c, 0x7b6e, 0x7b9d, 0x7b98, + 0x7b9f, 0x7b8d, 0x7b9c, 0x7b9a, 0x7b8b, 0x7b92, 0x7b8f, 0x7b5d, + 0x7b99, 0x7bcb, 0x7bc1, 0x7bcc, 0x7bcf, 0x7bb4, 0x7bc6, 0x7bdd, + 0x7be9, 0x7c11, 0x7c14, 0x7be6, 0x7be5, 0x7c60, 0x7c00, 0x7c07, + 0x7c13, 0x7bf3, 0x7bf7, 0x7c17, 0x7c0d, 0x7bf6, 0x7c23, 0x7c27, + 0x7c2a, 0x7c1f, 0x7c37, 0x7c2b, 0x7c3d, 0x7c4c, 0x7c43, 0x7c54, + 0x7c4f, 0x7c40, 0x7c50, 0x7c58, 0x7c5f, 0x7c64, 0x7c56, 0x7c65, + 0x7c6c, 0x7c75, 0x7c83, 0x7c90, 0x7ca4, 0x7cad, 0x7ca2, 0x7cab, + 0x7ca1, 0x7ca8, 0x7cb3, 0x7cb2, 0x7cb1, 0x7cae, 0x7cb9, 0x7cbd, + 0x7cc0, 0x7cc5, 0x7cc2, 0x7cd8, 0x7cd2, 0x7cdc, 0x7ce2, 0x9b3b, + 0x7cef, 0x7cf2, 0x7cf4, 0x7cf6, 0x7cfa, 0x7d06, + /* 0x65 */ + 0x7d02, 0x7d1c, 0x7d15, 0x7d0a, 0x7d45, 0x7d4b, 0x7d2e, 0x7d32, + 0x7d3f, 0x7d35, 0x7d46, 0x7d73, 0x7d56, 0x7d4e, 0x7d72, 0x7d68, + 0x7d6e, 0x7d4f, 0x7d63, 0x7d93, 0x7d89, 0x7d5b, 0x7d8f, 0x7d7d, + 0x7d9b, 0x7dba, 0x7dae, 0x7da3, 0x7db5, 0x7dc7, 0x7dbd, 0x7dab, + 0x7e3d, 0x7da2, 0x7daf, 0x7ddc, 0x7db8, 0x7d9f, 0x7db0, 0x7dd8, + 0x7ddd, 0x7de4, 0x7dde, 0x7dfb, 0x7df2, 0x7de1, 0x7e05, 0x7e0a, + 0x7e23, 0x7e21, 0x7e12, 0x7e31, 0x7e1f, 0x7e09, 0x7e0b, 0x7e22, + 0x7e46, 0x7e66, 0x7e3b, 0x7e35, 0x7e39, 0x7e43, 0x7e37, 0x7e32, + 0x7e3a, 0x7e67, 0x7e5d, 0x7e56, 0x7e5e, 0x7e59, 0x7e5a, 0x7e79, + 0x7e6a, 0x7e69, 0x7e7c, 0x7e7b, 0x7e83, 0x7dd5, 0x7e7d, 0x8fae, + 0x7e7f, 0x7e88, 0x7e89, 0x7e8c, 0x7e92, 0x7e90, 0x7e93, 0x7e94, + 0x7e96, 0x7e8e, 0x7e9b, 0x7e9c, 0x7f38, 0x7f3a, + /* 0x66 */ + 0x7f45, 0x7f4c, 0x7f4d, 0x7f4e, 0x7f50, 0x7f51, 0x7f55, 0x7f54, + 0x7f58, 0x7f5f, 0x7f60, 0x7f68, 0x7f69, 0x7f67, 0x7f78, 0x7f82, + 0x7f86, 0x7f83, 0x7f88, 0x7f87, 0x7f8c, 0x7f94, 0x7f9e, 0x7f9d, + 0x7f9a, 0x7fa3, 0x7faf, 0x7fb2, 0x7fb9, 0x7fae, 0x7fb6, 0x7fb8, + 0x8b71, 0x7fc5, 0x7fc6, 0x7fca, 0x7fd5, 0x7fd4, 0x7fe1, 0x7fe6, + 0x7fe9, 0x7ff3, 0x7ff9, 0x98dc, 0x8006, 0x8004, 0x800b, 0x8012, + 0x8018, 0x8019, 0x801c, 0x8021, 0x8028, 0x803f, 0x803b, 0x804a, + 0x8046, 0x8052, 0x8058, 0x805a, 0x805f, 0x8062, 0x8068, 0x8073, + 0x8072, 0x8070, 0x8076, 0x8079, 0x807d, 0x807f, 0x8084, 0x8086, + 0x8085, 0x809b, 0x8093, 0x809a, 0x80ad, 0x5190, 0x80ac, 0x80db, + 0x80e5, 0x80d9, 0x80dd, 0x80c4, 0x80da, 0x80d6, 0x8109, 0x80ef, + 0x80f1, 0x811b, 0x8129, 0x8123, 0x812f, 0x814b, + /* 0x67 */ + 0x968b, 0x8146, 0x813e, 0x8153, 0x8151, 0x80fc, 0x8171, 0x816e, + 0x8165, 0x8166, 0x8174, 0x8183, 0x8188, 0x818a, 0x8180, 0x8182, + 0x81a0, 0x8195, 0x81a4, 0x81a3, 0x815f, 0x8193, 0x81a9, 0x81b0, + 0x81b5, 0x81be, 0x81b8, 0x81bd, 0x81c0, 0x81c2, 0x81ba, 0x81c9, + 0x81cd, 0x81d1, 0x81d9, 0x81d8, 0x81c8, 0x81da, 0x81df, 0x81e0, + 0x81e7, 0x81fa, 0x81fb, 0x81fe, 0x8201, 0x8202, 0x8205, 0x8207, + 0x820a, 0x820d, 0x8210, 0x8216, 0x8229, 0x822b, 0x8238, 0x8233, + 0x8240, 0x8259, 0x8258, 0x825d, 0x825a, 0x825f, 0x8264, 0x8262, + 0x8268, 0x826a, 0x826b, 0x822e, 0x8271, 0x8277, 0x8278, 0x827e, + 0x828d, 0x8292, 0x82ab, 0x829f, 0x82bb, 0x82ac, 0x82e1, 0x82e3, + 0x82df, 0x82d2, 0x82f4, 0x82f3, 0x82fa, 0x8393, 0x8303, 0x82fb, + 0x82f9, 0x82de, 0x8306, 0x82dc, 0x8309, 0x82d9, + /* 0x68 */ + 0x8335, 0x8334, 0x8316, 0x8332, 0x8331, 0x8340, 0x8339, 0x8350, + 0x8345, 0x832f, 0x832b, 0x8317, 0x8318, 0x8385, 0x839a, 0x83aa, + 0x839f, 0x83a2, 0x8396, 0x8323, 0x838e, 0x8387, 0x838a, 0x837c, + 0x83b5, 0x8373, 0x8375, 0x83a0, 0x8389, 0x83a8, 0x83f4, 0x8413, + 0x83eb, 0x83ce, 0x83fd, 0x8403, 0x83d8, 0x840b, 0x83c1, 0x83f7, + 0x8407, 0x83e0, 0x83f2, 0x840d, 0x8422, 0x8420, 0x83bd, 0x8438, + 0x8506, 0x83fb, 0x846d, 0x842a, 0x843c, 0x855a, 0x8484, 0x8477, + 0x846b, 0x84ad, 0x846e, 0x8482, 0x8469, 0x8446, 0x842c, 0x846f, + 0x8479, 0x8435, 0x84ca, 0x8462, 0x84b9, 0x84bf, 0x849f, 0x84d9, + 0x84cd, 0x84bb, 0x84da, 0x84d0, 0x84c1, 0x84c6, 0x84d6, 0x84a1, + 0x8521, 0x84ff, 0x84f4, 0x8517, 0x8518, 0x852c, 0x851f, 0x8515, + 0x8514, 0x84fc, 0x8540, 0x8563, 0x8558, 0x8548, + /* 0x69 */ + 0x8541, 0x8602, 0x854b, 0x8555, 0x8580, 0x85a4, 0x8588, 0x8591, + 0x858a, 0x85a8, 0x856d, 0x8594, 0x859b, 0x85ea, 0x8587, 0x859c, + 0x8577, 0x857e, 0x8590, 0x85c9, 0x85ba, 0x85cf, 0x85b9, 0x85d0, + 0x85d5, 0x85dd, 0x85e5, 0x85dc, 0x85f9, 0x860a, 0x8613, 0x860b, + 0x85fe, 0x85fa, 0x8606, 0x8622, 0x861a, 0x8630, 0x863f, 0x864d, + 0x4e55, 0x8654, 0x865f, 0x8667, 0x8671, 0x8693, 0x86a3, 0x86a9, + 0x86aa, 0x868b, 0x868c, 0x86b6, 0x86af, 0x86c4, 0x86c6, 0x86b0, + 0x86c9, 0x8823, 0x86ab, 0x86d4, 0x86de, 0x86e9, 0x86ec, 0x86df, + 0x86db, 0x86ef, 0x8712, 0x8706, 0x8708, 0x8700, 0x8703, 0x86fb, + 0x8711, 0x8709, 0x870d, 0x86f9, 0x870a, 0x8734, 0x873f, 0x8737, + 0x873b, 0x8725, 0x8729, 0x871a, 0x8760, 0x875f, 0x8778, 0x874c, + 0x874e, 0x8774, 0x8757, 0x8768, 0x876e, 0x8759, + /* 0x6a */ + 0x8753, 0x8763, 0x876a, 0x8805, 0x87a2, 0x879f, 0x8782, 0x87af, + 0x87cb, 0x87bd, 0x87c0, 0x87d0, 0x96d6, 0x87ab, 0x87c4, 0x87b3, + 0x87c7, 0x87c6, 0x87bb, 0x87ef, 0x87f2, 0x87e0, 0x880f, 0x880d, + 0x87fe, 0x87f6, 0x87f7, 0x880e, 0x87d2, 0x8811, 0x8816, 0x8815, + 0x8822, 0x8821, 0x8831, 0x8836, 0x8839, 0x8827, 0x883b, 0x8844, + 0x8842, 0x8852, 0x8859, 0x885e, 0x8862, 0x886b, 0x8881, 0x887e, + 0x889e, 0x8875, 0x887d, 0x88b5, 0x8872, 0x8882, 0x8897, 0x8892, + 0x88ae, 0x8899, 0x88a2, 0x888d, 0x88a4, 0x88b0, 0x88bf, 0x88b1, + 0x88c3, 0x88c4, 0x88d4, 0x88d8, 0x88d9, 0x88dd, 0x88f9, 0x8902, + 0x88fc, 0x88f4, 0x88e8, 0x88f2, 0x8904, 0x890c, 0x890a, 0x8913, + 0x8943, 0x891e, 0x8925, 0x892a, 0x892b, 0x8941, 0x8944, 0x893b, + 0x8936, 0x8938, 0x894c, 0x891d, 0x8960, 0x895e, + /* 0x6b */ + 0x8966, 0x8964, 0x896d, 0x896a, 0x896f, 0x8974, 0x8977, 0x897e, + 0x8983, 0x8988, 0x898a, 0x8993, 0x8998, 0x89a1, 0x89a9, 0x89a6, + 0x89ac, 0x89af, 0x89b2, 0x89ba, 0x89bd, 0x89bf, 0x89c0, 0x89da, + 0x89dc, 0x89dd, 0x89e7, 0x89f4, 0x89f8, 0x8a03, 0x8a16, 0x8a10, + 0x8a0c, 0x8a1b, 0x8a1d, 0x8a25, 0x8a36, 0x8a41, 0x8a5b, 0x8a52, + 0x8a46, 0x8a48, 0x8a7c, 0x8a6d, 0x8a6c, 0x8a62, 0x8a85, 0x8a82, + 0x8a84, 0x8aa8, 0x8aa1, 0x8a91, 0x8aa5, 0x8aa6, 0x8a9a, 0x8aa3, + 0x8ac4, 0x8acd, 0x8ac2, 0x8ada, 0x8aeb, 0x8af3, 0x8ae7, 0x8ae4, + 0x8af1, 0x8b14, 0x8ae0, 0x8ae2, 0x8af7, 0x8ade, 0x8adb, 0x8b0c, + 0x8b07, 0x8b1a, 0x8ae1, 0x8b16, 0x8b10, 0x8b17, 0x8b20, 0x8b33, + 0x97ab, 0x8b26, 0x8b2b, 0x8b3e, 0x8b28, 0x8b41, 0x8b4c, 0x8b4f, + 0x8b4e, 0x8b49, 0x8b56, 0x8b5b, 0x8b5a, 0x8b6b, + /* 0x6c */ + 0x8b5f, 0x8b6c, 0x8b6f, 0x8b74, 0x8b7d, 0x8b80, 0x8b8c, 0x8b8e, + 0x8b92, 0x8b93, 0x8b96, 0x8b99, 0x8b9a, 0x8c3a, 0x8c41, 0x8c3f, + 0x8c48, 0x8c4c, 0x8c4e, 0x8c50, 0x8c55, 0x8c62, 0x8c6c, 0x8c78, + 0x8c7a, 0x8c82, 0x8c89, 0x8c85, 0x8c8a, 0x8c8d, 0x8c8e, 0x8c94, + 0x8c7c, 0x8c98, 0x621d, 0x8cad, 0x8caa, 0x8cbd, 0x8cb2, 0x8cb3, + 0x8cae, 0x8cb6, 0x8cc8, 0x8cc1, 0x8ce4, 0x8ce3, 0x8cda, 0x8cfd, + 0x8cfa, 0x8cfb, 0x8d04, 0x8d05, 0x8d0a, 0x8d07, 0x8d0f, 0x8d0d, + 0x8d10, 0x9f4e, 0x8d13, 0x8ccd, 0x8d14, 0x8d16, 0x8d67, 0x8d6d, + 0x8d71, 0x8d73, 0x8d81, 0x8d99, 0x8dc2, 0x8dbe, 0x8dba, 0x8dcf, + 0x8dda, 0x8dd6, 0x8dcc, 0x8ddb, 0x8dcb, 0x8dea, 0x8deb, 0x8ddf, + 0x8de3, 0x8dfc, 0x8e08, 0x8e09, 0x8dff, 0x8e1d, 0x8e1e, 0x8e10, + 0x8e1f, 0x8e42, 0x8e35, 0x8e30, 0x8e34, 0x8e4a, + /* 0x6d */ + 0x8e47, 0x8e49, 0x8e4c, 0x8e50, 0x8e48, 0x8e59, 0x8e64, 0x8e60, + 0x8e2a, 0x8e63, 0x8e55, 0x8e76, 0x8e72, 0x8e7c, 0x8e81, 0x8e87, + 0x8e85, 0x8e84, 0x8e8b, 0x8e8a, 0x8e93, 0x8e91, 0x8e94, 0x8e99, + 0x8eaa, 0x8ea1, 0x8eac, 0x8eb0, 0x8ec6, 0x8eb1, 0x8ebe, 0x8ec5, + 0x8ec8, 0x8ecb, 0x8edb, 0x8ee3, 0x8efc, 0x8efb, 0x8eeb, 0x8efe, + 0x8f0a, 0x8f05, 0x8f15, 0x8f12, 0x8f19, 0x8f13, 0x8f1c, 0x8f1f, + 0x8f1b, 0x8f0c, 0x8f26, 0x8f33, 0x8f3b, 0x8f39, 0x8f45, 0x8f42, + 0x8f3e, 0x8f4c, 0x8f49, 0x8f46, 0x8f4e, 0x8f57, 0x8f5c, 0x8f62, + 0x8f63, 0x8f64, 0x8f9c, 0x8f9f, 0x8fa3, 0x8fad, 0x8faf, 0x8fb7, + 0x8fda, 0x8fe5, 0x8fe2, 0x8fea, 0x8fef, 0x9087, 0x8ff4, 0x9005, + 0x8ff9, 0x8ffa, 0x9011, 0x9015, 0x9021, 0x900d, 0x901e, 0x9016, + 0x900b, 0x9027, 0x9036, 0x9035, 0x9039, 0x8ff8, + /* 0x6e */ + 0x904f, 0x9050, 0x9051, 0x9052, 0x900e, 0x9049, 0x903e, 0x9056, + 0x9058, 0x905e, 0x9068, 0x906f, 0x9076, 0x96a8, 0x9072, 0x9082, + 0x907d, 0x9081, 0x9080, 0x908a, 0x9089, 0x908f, 0x90a8, 0x90af, + 0x90b1, 0x90b5, 0x90e2, 0x90e4, 0x6248, 0x90db, 0x9102, 0x9112, + 0x9119, 0x9132, 0x9130, 0x914a, 0x9156, 0x9158, 0x9163, 0x9165, + 0x9169, 0x9173, 0x9172, 0x918b, 0x9189, 0x9182, 0x91a2, 0x91ab, + 0x91af, 0x91aa, 0x91b5, 0x91b4, 0x91ba, 0x91c0, 0x91c1, 0x91c9, + 0x91cb, 0x91d0, 0x91d6, 0x91df, 0x91e1, 0x91db, 0x91fc, 0x91f5, + 0x91f6, 0x921e, 0x91ff, 0x9214, 0x922c, 0x9215, 0x9211, 0x925e, + 0x9257, 0x9245, 0x9249, 0x9264, 0x9248, 0x9295, 0x923f, 0x924b, + 0x9250, 0x929c, 0x9296, 0x9293, 0x929b, 0x925a, 0x92cf, 0x92b9, + 0x92b7, 0x92e9, 0x930f, 0x92fa, 0x9344, 0x932e, + /* 0x6f */ + 0x9319, 0x9322, 0x931a, 0x9323, 0x933a, 0x9335, 0x933b, 0x935c, + 0x9360, 0x937c, 0x936e, 0x9356, 0x93b0, 0x93ac, 0x93ad, 0x9394, + 0x93b9, 0x93d6, 0x93d7, 0x93e8, 0x93e5, 0x93d8, 0x93c3, 0x93dd, + 0x93d0, 0x93c8, 0x93e4, 0x941a, 0x9414, 0x9413, 0x9403, 0x9407, + 0x9410, 0x9436, 0x942b, 0x9435, 0x9421, 0x943a, 0x9441, 0x9452, + 0x9444, 0x945b, 0x9460, 0x9462, 0x945e, 0x946a, 0x9229, 0x9470, + 0x9475, 0x9477, 0x947d, 0x945a, 0x947c, 0x947e, 0x9481, 0x947f, + 0x9582, 0x9587, 0x958a, 0x9594, 0x9596, 0x9598, 0x9599, 0x95a0, + 0x95a8, 0x95a7, 0x95ad, 0x95bc, 0x95bb, 0x95b9, 0x95be, 0x95ca, + 0x6ff6, 0x95c3, 0x95cd, 0x95cc, 0x95d5, 0x95d4, 0x95d6, 0x95dc, + 0x95e1, 0x95e5, 0x95e2, 0x9621, 0x9628, 0x962e, 0x962f, 0x9642, + 0x964c, 0x964f, 0x964b, 0x9677, 0x965c, 0x965e, + /* 0x70 */ + 0x965d, 0x965f, 0x9666, 0x9672, 0x966c, 0x968d, 0x9698, 0x9695, + 0x9697, 0x96aa, 0x96a7, 0x96b1, 0x96b2, 0x96b0, 0x96b4, 0x96b6, + 0x96b8, 0x96b9, 0x96ce, 0x96cb, 0x96c9, 0x96cd, 0x894d, 0x96dc, + 0x970d, 0x96d5, 0x96f9, 0x9704, 0x9706, 0x9708, 0x9713, 0x970e, + 0x9711, 0x970f, 0x9716, 0x9719, 0x9724, 0x972a, 0x9730, 0x9739, + 0x973d, 0x973e, 0x9744, 0x9746, 0x9748, 0x9742, 0x9749, 0x975c, + 0x9760, 0x9764, 0x9766, 0x9768, 0x52d2, 0x976b, 0x9771, 0x9779, + 0x9785, 0x977c, 0x9781, 0x977a, 0x9786, 0x978b, 0x978f, 0x9790, + 0x979c, 0x97a8, 0x97a6, 0x97a3, 0x97b3, 0x97b4, 0x97c3, 0x97c6, + 0x97c8, 0x97cb, 0x97dc, 0x97ed, 0x9f4f, 0x97f2, 0x7adf, 0x97f6, + 0x97f5, 0x980f, 0x980c, 0x9838, 0x9824, 0x9821, 0x9837, 0x983d, + 0x9846, 0x984f, 0x984b, 0x986b, 0x986f, 0x9870, + /* 0x71 */ + 0x9871, 0x9874, 0x9873, 0x98aa, 0x98af, 0x98b1, 0x98b6, 0x98c4, + 0x98c3, 0x98c6, 0x98e9, 0x98eb, 0x9903, 0x9909, 0x9912, 0x9914, + 0x9918, 0x9921, 0x991d, 0x991e, 0x9924, 0x9920, 0x992c, 0x992e, + 0x993d, 0x993e, 0x9942, 0x9949, 0x9945, 0x9950, 0x994b, 0x9951, + 0x9952, 0x994c, 0x9955, 0x9997, 0x9998, 0x99a5, 0x99ad, 0x99ae, + 0x99bc, 0x99df, 0x99db, 0x99dd, 0x99d8, 0x99d1, 0x99ed, 0x99ee, + 0x99f1, 0x99f2, 0x99fb, 0x99f8, 0x9a01, 0x9a0f, 0x9a05, 0x99e2, + 0x9a19, 0x9a2b, 0x9a37, 0x9a45, 0x9a42, 0x9a40, 0x9a43, 0x9a3e, + 0x9a55, 0x9a4d, 0x9a5b, 0x9a57, 0x9a5f, 0x9a62, 0x9a65, 0x9a64, + 0x9a69, 0x9a6b, 0x9a6a, 0x9aad, 0x9ab0, 0x9abc, 0x9ac0, 0x9acf, + 0x9ad1, 0x9ad3, 0x9ad4, 0x9ade, 0x9adf, 0x9ae2, 0x9ae3, 0x9ae6, + 0x9aef, 0x9aeb, 0x9aee, 0x9af4, 0x9af1, 0x9af7, + /* 0x72 */ + 0x9afb, 0x9b06, 0x9b18, 0x9b1a, 0x9b1f, 0x9b22, 0x9b23, 0x9b25, + 0x9b27, 0x9b28, 0x9b29, 0x9b2a, 0x9b2e, 0x9b2f, 0x9b32, 0x9b44, + 0x9b43, 0x9b4f, 0x9b4d, 0x9b4e, 0x9b51, 0x9b58, 0x9b74, 0x9b93, + 0x9b83, 0x9b91, 0x9b96, 0x9b97, 0x9b9f, 0x9ba0, 0x9ba8, 0x9bb4, + 0x9bc0, 0x9bca, 0x9bb9, 0x9bc6, 0x9bcf, 0x9bd1, 0x9bd2, 0x9be3, + 0x9be2, 0x9be4, 0x9bd4, 0x9be1, 0x9c3a, 0x9bf2, 0x9bf1, 0x9bf0, + 0x9c15, 0x9c14, 0x9c09, 0x9c13, 0x9c0c, 0x9c06, 0x9c08, 0x9c12, + 0x9c0a, 0x9c04, 0x9c2e, 0x9c1b, 0x9c25, 0x9c24, 0x9c21, 0x9c30, + 0x9c47, 0x9c32, 0x9c46, 0x9c3e, 0x9c5a, 0x9c60, 0x9c67, 0x9c76, + 0x9c78, 0x9ce7, 0x9cec, 0x9cf0, 0x9d09, 0x9d08, 0x9ceb, 0x9d03, + 0x9d06, 0x9d2a, 0x9d26, 0x9daf, 0x9d23, 0x9d1f, 0x9d44, 0x9d15, + 0x9d12, 0x9d41, 0x9d3f, 0x9d3e, 0x9d46, 0x9d48, + /* 0x73 */ + 0x9d5d, 0x9d5e, 0x9d64, 0x9d51, 0x9d50, 0x9d59, 0x9d72, 0x9d89, + 0x9d87, 0x9dab, 0x9d6f, 0x9d7a, 0x9d9a, 0x9da4, 0x9da9, 0x9db2, + 0x9dc4, 0x9dc1, 0x9dbb, 0x9db8, 0x9dba, 0x9dc6, 0x9dcf, 0x9dc2, + 0x9dd9, 0x9dd3, 0x9df8, 0x9de6, 0x9ded, 0x9def, 0x9dfd, 0x9e1a, + 0x9e1b, 0x9e1e, 0x9e75, 0x9e79, 0x9e7d, 0x9e81, 0x9e88, 0x9e8b, + 0x9e8c, 0x9e92, 0x9e95, 0x9e91, 0x9e9d, 0x9ea5, 0x9ea9, 0x9eb8, + 0x9eaa, 0x9ead, 0x9761, 0x9ecc, 0x9ece, 0x9ecf, 0x9ed0, 0x9ed4, + 0x9edc, 0x9ede, 0x9edd, 0x9ee0, 0x9ee5, 0x9ee8, 0x9eef, 0x9ef4, + 0x9ef6, 0x9ef7, 0x9ef9, 0x9efb, 0x9efc, 0x9efd, 0x9f07, 0x9f08, + 0x76b7, 0x9f15, 0x9f21, 0x9f2c, 0x9f3e, 0x9f4a, 0x9f52, 0x9f54, + 0x9f63, 0x9f5f, 0x9f60, 0x9f61, 0x9f66, 0x9f67, 0x9f6c, 0x9f6a, + 0x9f77, 0x9f72, 0x9f76, 0x9f95, 0x9f9c, 0x9fa0, + /* 0x74 */ + 0x582f, 0x69c7, 0x9059, 0x7464, 0x51dc, 0x7199, +}; + +static int +jisx0208_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c1 = (s[0] & 0x7F); + if ((c1 >= 0x21 && c1 <= 0x28) || (c1 >= 0x30 && c1 <= 0x74)) { + if (n >= 2) { + unsigned char c2 = (s[1] & 0x7F); + if (c2 >= 0x21 && c2 < 0x7f) { + unsigned int i = 94 * (c1 - 0x21) + (c2 - 0x21); + unsigned short wc = 0xfffd; + if (i < 1410) { + if (i < 690) + wc = jisx0208_2uni_page21[i]; + } else { + if (i < 7808) + wc = jisx0208_2uni_page30[i-1410]; + } + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 2; + } + } + return RET_ILSEQ; + } + return RET_TOOFEW(0); + } + return RET_ILSEQ; +} + +static const unsigned short jisx0208_2charset[6879] = { + 0x2140, 0x2171, 0x2172, 0x2178, 0x212f, 0x224c, 0x216b, 0x215e, + 0x212d, 0x2279, 0x215f, 0x2160, 0x2621, 0x2622, 0x2623, 0x2624, + 0x2625, 0x2626, 0x2627, 0x2628, 0x2629, 0x262a, 0x262b, 0x262c, + 0x262d, 0x262e, 0x262f, 0x2630, 0x2631, 0x2632, 0x2633, 0x2634, + 0x2635, 0x2636, 0x2637, 0x2638, 0x2641, 0x2642, 0x2643, 0x2644, + 0x2645, 0x2646, 0x2647, 0x2648, 0x2649, 0x264a, 0x264b, 0x264c, + 0x264d, 0x264e, 0x264f, 0x2650, 0x2651, 0x2652, 0x2653, 0x2654, + 0x2655, 0x2656, 0x2657, 0x2658, 0x2727, 0x2721, 0x2722, 0x2723, + 0x2724, 0x2725, 0x2726, 0x2728, 0x2729, 0x272a, 0x272b, 0x272c, + 0x272d, 0x272e, 0x272f, 0x2730, 0x2731, 0x2732, 0x2733, 0x2734, + 0x2735, 0x2736, 0x2737, 0x2738, 0x2739, 0x273a, 0x273b, 0x273c, + 0x273d, 0x273e, 0x273f, 0x2740, 0x2741, 0x2751, 0x2752, 0x2753, + 0x2754, 0x2755, 0x2756, 0x2758, 0x2759, 0x275a, 0x275b, 0x275c, + 0x275d, 0x275e, 0x275f, 0x2760, 0x2761, 0x2762, 0x2763, 0x2764, + 0x2765, 0x2766, 0x2767, 0x2768, 0x2769, 0x276a, 0x276b, 0x276c, + 0x276d, 0x276e, 0x276f, 0x2770, 0x2771, 0x2757, 0x213e, 0x213d, + 0x2142, 0x2146, 0x2147, 0x2148, 0x2149, 0x2277, 0x2278, 0x2145, + 0x2144, 0x2273, 0x216c, 0x216d, 0x2228, 0x216e, 0x2272, 0x222b, + 0x222c, 0x222a, 0x222d, 0x224d, 0x224e, 0x224f, 0x225f, 0x2250, + 0x2260, 0x223a, 0x223b, 0x215d, 0x2265, 0x2267, 0x2167, 0x225c, + 0x224a, 0x224b, 0x2241, 0x2240, 0x2269, 0x226a, 0x2168, 0x2268, + 0x2266, 0x2262, 0x2162, 0x2261, 0x2165, 0x2166, 0x2263, 0x2264, + 0x223e, 0x223f, 0x223c, 0x223d, 0x225d, 0x225e, 0x2821, 0x282c, + 0x2822, 0x282d, 0x2823, 0x282e, 0x2824, 0x282f, 0x2826, 0x2831, + 0x2825, 0x2830, 0x2827, 0x283c, 0x2837, 0x2832, 0x2829, 0x283e, + 0x2839, 0x2834, 0x2828, 0x2838, 0x283d, 0x2833, 0x282a, 0x283a, + 0x283f, 0x2835, 0x282b, 0x283b, 0x2840, 0x2836, 0x2223, 0x2222, + 0x2225, 0x2224, 0x2227, 0x2226, 0x2221, 0x217e, 0x217b, 0x217d, + 0x217c, 0x227e, 0x217a, 0x2179, 0x216a, 0x2169, 0x2276, 0x2275, + 0x2274, 0x2121, 0x2122, 0x2123, 0x2137, 0x2139, 0x213a, 0x213b, + 0x2152, 0x2153, 0x2154, 0x2155, 0x2156, 0x2157, 0x2158, 0x2159, + 0x215a, 0x215b, 0x2229, 0x222e, 0x214c, 0x214d, 0x2141, 0x2421, + 0x2422, 0x2423, 0x2424, 0x2425, 0x2426, 0x2427, 0x2428, 0x2429, + 0x242a, 0x242b, 0x242c, 0x242d, 0x242e, 0x242f, 0x2430, 0x2431, + 0x2432, 0x2433, 0x2434, 0x2435, 0x2436, 0x2437, 0x2438, 0x2439, + 0x243a, 0x243b, 0x243c, 0x243d, 0x243e, 0x243f, 0x2440, 0x2441, + 0x2442, 0x2443, 0x2444, 0x2445, 0x2446, 0x2447, 0x2448, 0x2449, + 0x244a, 0x244b, 0x244c, 0x244d, 0x244e, 0x244f, 0x2450, 0x2451, + 0x2452, 0x2453, 0x2454, 0x2455, 0x2456, 0x2457, 0x2458, 0x2459, + 0x245a, 0x245b, 0x245c, 0x245d, 0x245e, 0x245f, 0x2460, 0x2461, + 0x2462, 0x2463, 0x2464, 0x2465, 0x2466, 0x2467, 0x2468, 0x2469, + 0x246a, 0x246b, 0x246c, 0x246d, 0x246e, 0x246f, 0x2470, 0x2471, + 0x2472, 0x2473, 0x212b, 0x212c, 0x2135, 0x2136, 0x2521, 0x2522, + 0x2523, 0x2524, 0x2525, 0x2526, 0x2527, 0x2528, 0x2529, 0x252a, + 0x252b, 0x252c, 0x252d, 0x252e, 0x252f, 0x2530, 0x2531, 0x2532, + 0x2533, 0x2534, 0x2535, 0x2536, 0x2537, 0x2538, 0x2539, 0x253a, + 0x253b, 0x253c, 0x253d, 0x253e, 0x253f, 0x2540, 0x2541, 0x2542, + 0x2543, 0x2544, 0x2545, 0x2546, 0x2547, 0x2548, 0x2549, 0x254a, + 0x254b, 0x254c, 0x254d, 0x254e, 0x254f, 0x2550, 0x2551, 0x2552, + 0x2553, 0x2554, 0x2555, 0x2556, 0x2557, 0x2558, 0x2559, 0x255a, + 0x255b, 0x255c, 0x255d, 0x255e, 0x255f, 0x2560, 0x2561, 0x2562, + 0x2563, 0x2564, 0x2565, 0x2566, 0x2567, 0x2568, 0x2569, 0x256a, + 0x256b, 0x256c, 0x256d, 0x256e, 0x256f, 0x2570, 0x2571, 0x2572, + 0x2573, 0x2574, 0x2575, 0x2576, 0x2126, 0x213c, 0x2133, 0x2134, + 0x306c, 0x437a, 0x3c37, 0x4b7c, 0x3e66, 0x3b30, 0x3e65, 0x323c, + 0x4954, 0x4d3f, 0x5022, 0x312f, 0x336e, 0x5023, 0x4024, 0x5242, + 0x3556, 0x4a3a, 0x3e67, 0x4e3e, 0x4a42, 0x5024, 0x4366, 0x5025, + 0x367a, 0x5026, 0x345d, 0x4330, 0x3c67, 0x5027, 0x5028, 0x5029, + 0x4735, 0x3557, 0x4737, 0x4663, 0x3843, 0x4b33, 0x6949, 0x502a, + 0x3e68, 0x502b, 0x3235, 0x3665, 0x3870, 0x4c69, 0x5626, 0x4d70, + 0x467d, 0x3425, 0x3535, 0x502c, 0x502d, 0x4e3b, 0x4d3d, 0x4168, + 0x502f, 0x3b76, 0x4673, 0x5032, 0x313e, 0x385f, 0x385e, 0x3066, + 0x4f4b, 0x4f4a, 0x3a33, 0x3021, 0x5033, 0x5034, 0x5035, 0x4b34, + 0x5036, 0x3872, 0x3067, 0x4b72, 0x357c, 0x357d, 0x357e, 0x4462, + 0x4e3c, 0x5037, 0x5038, 0x5039, 0x3f4d, 0x3d3a, 0x3f4e, 0x503e, + 0x503c, 0x503d, 0x3558, 0x3a23, 0x3270, 0x503b, 0x503a, 0x4a29, + 0x3b46, 0x3b45, 0x423e, 0x503f, 0x4955, 0x4067, 0x2138, 0x5040, + 0x5042, 0x4265, 0x4e61, 0x304a, 0x5041, 0x323e, 0x3644, 0x4367, + 0x376f, 0x5043, 0x4724, 0x346b, 0x5044, 0x304b, 0x3860, 0x346c, + 0x497a, 0x4832, 0x3559, 0x3271, 0x5067, 0x4541, 0x476c, 0x5046, + 0x483c, 0x4e62, 0x3f2d, 0x3b47, 0x3b77, 0x3240, 0x4451, 0x4322, + 0x504a, 0x304c, 0x4463, 0x3d3b, 0x3a34, 0x4d24, 0x424e, 0x323f, + 0x5049, 0x4d3e, 0x5045, 0x5047, 0x3a6e, 0x5048, 0x5524, 0x5050, + 0x5053, 0x5051, 0x3242, 0x4a3b, 0x504b, 0x504f, 0x3873, 0x3b48, + 0x3426, 0x5054, 0x504c, 0x4e63, 0x3b78, 0x504d, 0x5052, 0x5055, + 0x504e, 0x3621, 0x304d, 0x3622, 0x3241, 0x5525, 0x4b79, 0x496e, + 0x3874, 0x3f2f, 0x4e37, 0x4a58, 0x3738, 0x4225, 0x3264, 0x3d53, + 0x5059, 0x505e, 0x505c, 0x5057, 0x422f, 0x505a, 0x505d, 0x505b, + 0x4a5d, 0x5058, 0x3f2e, 0x4b73, 0x505f, 0x5060, 0x3d24, 0x506d, + 0x4750, 0x4936, 0x5068, 0x4a70, 0x3236, 0x506c, 0x5066, 0x506f, + 0x4152, 0x3844, 0x475c, 0x6047, 0x506e, 0x455d, 0x5063, 0x3876, + 0x3875, 0x5061, 0x3c5a, 0x5069, 0x4a6f, 0x434d, 0x5065, 0x3771, + 0x5062, 0x506a, 0x5064, 0x4e51, 0x506b, 0x4f41, 0x3666, 0x3770, + 0x5070, 0x5071, 0x5075, 0x304e, 0x4a50, 0x5074, 0x5073, 0x5077, + 0x5076, 0x4464, 0x3772, 0x5078, 0x3c45, 0x4226, 0x4465, 0x3676, + 0x5079, 0x3536, 0x507a, 0x507c, 0x4b35, 0x3766, 0x3b31, 0x4877, + 0x507b, 0x3a45, 0x4d43, 0x507e, 0x5123, 0x507d, 0x3a44, 0x3d7d, + 0x3739, 0x5124, 0x364f, 0x5121, 0x5122, 0x462f, 0x417c, 0x3623, + 0x4b4d, 0x5125, 0x4e3d, 0x5126, 0x5129, 0x5127, 0x414e, 0x5128, + 0x512a, 0x512c, 0x512b, 0x4a48, 0x3537, 0x512e, 0x512f, 0x322f, + 0x512d, 0x3c74, 0x5132, 0x5131, 0x5130, 0x5056, 0x5133, 0x3d7e, + 0x5134, 0x4d25, 0x4c59, 0x5136, 0x5135, 0x5138, 0x5137, 0x5139, + 0x513a, 0x3074, 0x3835, 0x373b, 0x3d3c, 0x437b, 0x3624, 0x4068, + 0x3877, 0x396e, 0x513c, 0x4c48, 0x4546, 0x3b79, 0x513b, 0x513d, + 0x455e, 0x3375, 0x513e, 0x467e, 0x4134, 0x5140, 0x5141, 0x482c, + 0x3878, 0x4f3b, 0x5142, 0x3626, 0x4a3c, 0x4236, 0x3671, 0x4535, + 0x3773, 0x5143, 0x5144, 0x4662, 0x315f, 0x5147, 0x3a7d, 0x5146, + 0x3a46, 0x5148, 0x666e, 0x5149, 0x4b41, 0x514a, 0x514b, 0x514c, + 0x3e69, 0x3c4c, 0x3427, 0x514f, 0x514d, 0x4c3d, 0x514e, 0x495a, + 0x5150, 0x5151, 0x5152, 0x455f, 0x5156, 0x5154, 0x5155, 0x5153, + 0x3a63, 0x5157, 0x4c6a, 0x4e64, 0x5158, 0x4028, 0x5159, 0x3d5a, + 0x515a, 0x437c, 0x4e3f, 0x4560, 0x5245, 0x515b, 0x7425, 0x3645, + 0x515c, 0x4b5e, 0x3d68, 0x427c, 0x515e, 0x4664, 0x515f, 0x5160, + 0x332e, 0x5161, 0x3627, 0x464c, 0x317a, 0x3d50, 0x4821, 0x5162, + 0x4561, 0x3f4f, 0x5163, 0x4a2c, 0x405a, 0x3422, 0x3429, 0x5164, + 0x5166, 0x373a, 0x5165, 0x4e73, 0x3d69, 0x483d, 0x4a4c, 0x5167, + 0x4d78, 0x5168, 0x5169, 0x457e, 0x516a, 0x4029, 0x3a7e, 0x3774, + 0x516b, 0x3b49, 0x396f, 0x4466, 0x516d, 0x4227, 0x3a6f, 0x516e, + 0x516f, 0x4130, 0x516c, 0x5171, 0x4b36, 0x3964, 0x5170, 0x3775, + 0x3a5e, 0x476d, 0x5174, 0x5172, 0x497b, 0x3e6a, 0x517b, 0x3364, + 0x5175, 0x5173, 0x414f, 0x5177, 0x5176, 0x3344, 0x3760, 0x517c, + 0x4e2d, 0x5178, 0x517d, 0x517a, 0x5179, 0x4e4f, 0x3879, 0x3243, + 0x4e74, 0x3d75, 0x4558, 0x3965, 0x5222, 0x5223, 0x4e65, 0x4f2b, + 0x5225, 0x387a, 0x5224, 0x332f, 0x5226, 0x4b56, 0x443c, 0x4d26, + 0x4a59, 0x5227, 0x7055, 0x4630, 0x5228, 0x342a, 0x4c33, 0x3e21, + 0x5229, 0x4a67, 0x522d, 0x402a, 0x522a, 0x3650, 0x522b, 0x342b, + 0x372e, 0x522e, 0x522f, 0x5230, 0x5231, 0x3c5b, 0x387b, 0x4c5e, + 0x4c68, 0x4677, 0x4a71, 0x5232, 0x5233, 0x5235, 0x5237, 0x5236, + 0x5238, 0x323d, 0x4b4c, 0x3a7c, 0x5239, 0x4159, 0x3e22, 0x3629, + 0x523a, 0x485b, 0x523b, 0x523c, 0x523d, 0x523e, 0x4924, 0x3668, + 0x3065, 0x463f, 0x523f, 0x3d3d, 0x4069, 0x5241, 0x5240, 0x3e23, + 0x3861, 0x5243, 0x483e, 0x5244, 0x485c, 0x4234, 0x426e, 0x3628, + 0x466e, 0x4331, 0x476e, 0x4b4e, 0x5246, 0x406a, 0x3735, 0x5247, + 0x5248, 0x312c, 0x3075, 0x346d, 0x4228, 0x3551, 0x4d71, 0x524b, + 0x3237, 0x524a, 0x362a, 0x524c, 0x4c71, 0x524d, 0x4e52, 0x387c, + 0x3836, 0x524e, 0x5250, 0x524f, 0x3f5f, 0x3139, 0x315e, 0x5251, + 0x5252, 0x3837, 0x5253, 0x356e, 0x3b32, 0x5254, 0x4b74, 0x3a35, + 0x355a, 0x4d27, 0x4150, 0x483f, 0x3c7d, 0x3d47, 0x3c68, 0x3c75, + 0x3d76, 0x4840, 0x5257, 0x3143, 0x4151, 0x387d, 0x3845, 0x3667, + 0x525b, 0x4321, 0x427e, 0x362b, 0x3e24, 0x525c, 0x525a, 0x3244, + 0x4266, 0x3c38, 0x3b4b, 0x3126, 0x3370, 0x3966, 0x3b4a, 0x525d, + 0x525e, 0x3549, 0x3346, 0x3967, 0x3548, 0x445f, 0x3125, 0x4631, + 0x4c3e, 0x3921, 0x4d79, 0x4547, 0x387e, 0x372f, 0x5267, 0x3663, + 0x4b4a, 0x485d, 0x5266, 0x345e, 0x5261, 0x5262, 0x5264, 0x5265, + 0x355b, 0x3f61, 0x4a2d, 0x5263, 0x525f, 0x3863, 0x5260, 0x4f24, + 0x4a72, 0x4468, 0x3862, 0x3970, 0x5268, 0x465d, 0x526c, 0x3c7e, + 0x3c76, 0x526f, 0x526d, 0x4c23, 0x526a, 0x5273, 0x526e, 0x5271, + 0x3846, 0x4c3f, 0x5272, 0x5274, 0x5276, 0x3a70, 0x4f42, 0x526b, + 0x5269, 0x5275, 0x5270, 0x5278, 0x5323, 0x527a, 0x527e, 0x5321, + 0x527b, 0x533e, 0x3a69, 0x3331, 0x5279, 0x5325, 0x3076, 0x5324, + 0x3025, 0x494a, 0x5322, 0x527c, 0x5277, 0x527d, 0x3a48, 0x5326, + 0x3077, 0x532f, 0x5327, 0x5328, 0x3e25, 0x4b69, 0x532d, 0x532c, + 0x452f, 0x532e, 0x532b, 0x3134, 0x3a36, 0x3f30, 0x5329, 0x4562, + 0x532a, 0x3022, 0x5334, 0x4d23, 0x3e27, 0x533a, 0x5339, 0x5330, + 0x4243, 0x5331, 0x426f, 0x5336, 0x3e26, 0x5333, 0x4c64, 0x373c, + 0x5337, 0x5338, 0x5335, 0x533b, 0x5332, 0x5341, 0x5346, 0x5342, + 0x533d, 0x5347, 0x4131, 0x5349, 0x3922, 0x533f, 0x437d, 0x5343, + 0x533c, 0x342d, 0x346e, 0x3365, 0x5344, 0x5340, 0x3776, 0x534a, + 0x5348, 0x4153, 0x354a, 0x362c, 0x5345, 0x3674, 0x3144, 0x534e, + 0x534c, 0x5427, 0x5351, 0x534b, 0x534f, 0x534d, 0x3b4c, 0x5350, + 0x5353, 0x5358, 0x5356, 0x5355, 0x4332, 0x3245, 0x5352, 0x5354, + 0x3e28, 0x3133, 0x5357, 0x325e, 0x5362, 0x3e7c, 0x535e, 0x535c, + 0x535d, 0x535f, 0x313d, 0x4139, 0x5359, 0x535a, 0x337a, 0x5361, + 0x346f, 0x5364, 0x5360, 0x5363, 0x4a2e, 0x4655, 0x4838, 0x5366, + 0x5365, 0x3345, 0x5367, 0x536a, 0x5369, 0x5368, 0x4739, 0x536b, + 0x536c, 0x536e, 0x536d, 0x5370, 0x5373, 0x5371, 0x536f, 0x5372, + 0x5374, 0x5375, 0x5376, 0x5377, 0x5378, 0x5145, 0x3c7c, 0x3b4d, + 0x3273, 0x3078, 0x4344, 0x5379, 0x3a24, 0x304f, 0x3f5e, 0x537a, + 0x3847, 0x3971, 0x537c, 0x537b, 0x4a60, 0x537d, 0x5421, 0x537e, + 0x5422, 0x5423, 0x3777, 0x3160, 0x5424, 0x5426, 0x5425, 0x5428, + 0x455a, 0x5429, 0x3035, 0x3a5f, 0x373d, 0x434f, 0x542a, 0x542b, + 0x542d, 0x542e, 0x3a64, 0x3651, 0x4b37, 0x542c, 0x542f, 0x3a41, + 0x3923, 0x5433, 0x3a25, 0x4333, 0x5430, 0x445a, 0x5434, 0x3f62, + 0x5432, 0x5435, 0x373f, 0x5436, 0x5437, 0x3924, 0x3340, 0x5439, + 0x543a, 0x543b, 0x5438, 0x5431, 0x543c, 0x543d, 0x4b64, 0x3e6b, + 0x543f, 0x5440, 0x543e, 0x5442, 0x4738, 0x3068, 0x4956, 0x5443, + 0x3e7d, 0x3c39, 0x475d, 0x3470, 0x3a6b, 0x4b59, 0x4632, 0x3778, + 0x424f, 0x5441, 0x5444, 0x4244, 0x5445, 0x5446, 0x5448, 0x4469, + 0x342e, 0x7421, 0x3161, 0x4a73, 0x3e6c, 0x4548, 0x3a66, 0x544e, + 0x4a3d, 0x4e5d, 0x3274, 0x544a, 0x413a, 0x544d, 0x4563, 0x4549, + 0x4564, 0x4839, 0x444d, 0x3a49, 0x5449, 0x3176, 0x4536, 0x544b, + 0x5447, 0x3f50, 0x544f, 0x3d4e, 0x362d, 0x5450, 0x4a68, 0x417d, + 0x4446, 0x5452, 0x4b4f, 0x5453, 0x5458, 0x4a2f, 0x5457, 0x5451, + 0x5454, 0x5456, 0x3a26, 0x4a49, 0x5459, 0x4345, 0x3275, 0x3e6d, + 0x545b, 0x545a, 0x3968, 0x545c, 0x545e, 0x545d, 0x5460, 0x5455, + 0x5462, 0x5461, 0x545f, 0x3b4e, 0x3f51, 0x4154, 0x5463, 0x403c, + 0x306d, 0x4764, 0x445b, 0x5465, 0x5464, 0x5466, 0x5467, 0x5468, + 0x5469, 0x4a51, 0x546a, 0x3246, 0x546b, 0x4d3c, 0x3330, 0x5249, + 0x3d48, 0x423f, 0x546c, 0x4c6b, 0x4c34, 0x546e, 0x4267, 0x4537, + 0x4240, 0x4957, 0x546f, 0x5470, 0x317b, 0x3c3a, 0x5471, 0x3050, + 0x5472, 0x5473, 0x3162, 0x3471, 0x4660, 0x4a74, 0x5477, 0x4155, + 0x5476, 0x3740, 0x4b5b, 0x5475, 0x4565, 0x5479, 0x5478, 0x547b, + 0x547a, 0x317c, 0x547c, 0x3e29, 0x547e, 0x4325, 0x547d, 0x4a33, + 0x3d77, 0x455b, 0x5521, 0x3925, 0x5522, 0x4721, 0x485e, 0x4c51, + 0x4725, 0x552b, 0x3538, 0x4d45, 0x4c2f, 0x562c, 0x5523, 0x5526, + 0x4245, 0x4b38, 0x454a, 0x5527, 0x4b65, 0x3a4a, 0x3e2a, 0x5528, + 0x3b50, 0x3b4f, 0x3039, 0x3848, 0x402b, 0x3051, 0x552c, 0x552d, + 0x552a, 0x3138, 0x342f, 0x5529, 0x4c45, 0x4931, 0x3028, 0x3079, + 0x3b51, 0x3052, 0x3023, 0x5532, 0x5530, 0x4c3c, 0x5533, 0x5531, + 0x552f, 0x3f31, 0x552e, 0x4a5a, 0x3864, 0x5537, 0x5538, 0x3e2b, + 0x5534, 0x4f2c, 0x474c, 0x5536, 0x3a27, 0x5539, 0x4958, 0x553a, + 0x5535, 0x4c3b, 0x475e, 0x553b, 0x4932, 0x553c, 0x5540, 0x553d, + 0x3247, 0x553f, 0x3c3b, 0x553e, 0x3779, 0x554c, 0x5545, 0x5542, + 0x4364, 0x5541, 0x5543, 0x5544, 0x5546, 0x5547, 0x3472, 0x5549, + 0x5548, 0x554a, 0x3e6e, 0x554d, 0x445c, 0x3145, 0x554b, 0x554e, + 0x554f, 0x5552, 0x5550, 0x5551, 0x3b52, 0x5553, 0x3926, 0x5554, + 0x3b7a, 0x4238, 0x5555, 0x5556, 0x3b5a, 0x3927, 0x4c52, 0x3528, + 0x3849, 0x5557, 0x3358, 0x5558, 0x4239, 0x5559, 0x5623, 0x555a, + 0x555b, 0x555c, 0x555e, 0x555f, 0x5560, 0x4270, 0x3127, 0x3c69, + 0x3042, 0x4157, 0x3430, 0x3c35, 0x3928, 0x4566, 0x3d21, 0x3431, + 0x4368, 0x446a, 0x3038, 0x3539, 0x4a75, 0x3c42, 0x3552, 0x406b, + 0x3c3c, 0x4d28, 0x5561, 0x355c, 0x3a4b, 0x3332, 0x3163, 0x3e2c, + 0x3248, 0x5562, 0x4d46, 0x3d49, 0x3c64, 0x5563, 0x3473, 0x4652, + 0x4c29, 0x5564, 0x5565, 0x4959, 0x5567, 0x3428, 0x3677, 0x5566, + 0x3432, 0x3f32, 0x556b, 0x3b21, 0x3249, 0x556a, 0x5568, 0x556c, + 0x5569, 0x472b, 0x5c4d, 0x3f33, 0x556d, 0x4e40, 0x556e, 0x5570, + 0x437e, 0x556f, 0x4023, 0x3b7b, 0x4250, 0x3c77, 0x4975, 0x406c, + 0x3c4d, 0x5571, 0x3e2d, 0x5572, 0x5573, 0x3053, 0x423a, 0x3f52, + 0x5574, 0x4633, 0x3e2e, 0x3e2f, 0x5575, 0x406d, 0x3e30, 0x5576, + 0x5577, 0x4c60, 0x5578, 0x3646, 0x3d22, 0x5579, 0x557a, 0x3c5c, + 0x3f2c, 0x4674, 0x3f54, 0x4878, 0x4722, 0x3649, 0x557b, 0x356f, + 0x557c, 0x367e, 0x464f, 0x3230, 0x3b53, 0x557d, 0x5622, 0x5621, + 0x367d, 0x557e, 0x4538, 0x4230, 0x454b, 0x3c48, 0x4158, 0x4d7a, + 0x5624, 0x5625, 0x4656, 0x3b33, 0x5627, 0x5628, 0x5629, 0x3474, + 0x562a, 0x562b, 0x322c, 0x413b, 0x3464, 0x562d, 0x4c28, 0x4252, + 0x3359, 0x562f, 0x5631, 0x345f, 0x562e, 0x5630, 0x5633, 0x5632, + 0x5634, 0x5635, 0x463d, 0x362e, 0x3265, 0x5636, 0x563b, 0x5639, + 0x4a77, 0x4a76, 0x4567, 0x5638, 0x3d54, 0x5637, 0x3f72, 0x563c, + 0x3a6a, 0x5642, 0x5643, 0x563d, 0x3333, 0x563e, 0x5647, 0x5646, + 0x5645, 0x5641, 0x5640, 0x5644, 0x4a78, 0x564b, 0x5648, 0x564a, + 0x4d72, 0x5649, 0x563f, 0x3f73, 0x564c, 0x3a37, 0x564d, 0x564e, + 0x5651, 0x5650, 0x564f, 0x4568, 0x563a, 0x5657, 0x5653, 0x5652, + 0x5654, 0x5655, 0x5658, 0x4e66, 0x5659, 0x5656, 0x565a, 0x3460, + 0x565b, 0x565d, 0x565c, 0x565e, 0x565f, 0x406e, 0x3d23, 0x3d64, + 0x4163, 0x3929, 0x3a38, 0x392a, 0x3570, 0x5660, 0x3a39, 0x384a, + 0x5661, 0x4c26, 0x4743, 0x5662, 0x392b, 0x342c, 0x4327, 0x3652, + 0x3b54, 0x495b, 0x4841, 0x5663, 0x3475, 0x5666, 0x4421, 0x5665, + 0x5664, 0x5667, 0x446b, 0x3f63, 0x3b55, 0x404a, 0x4253, 0x3522, + 0x4422, 0x5668, 0x5669, 0x3e6f, 0x4b39, 0x566c, 0x566b, 0x566a, + 0x497d, 0x5673, 0x4b5a, 0x566d, 0x566f, 0x4b6b, 0x566e, 0x5670, + 0x4828, 0x5671, 0x4a3e, 0x5672, 0x3433, 0x4a3f, 0x472f, 0x5674, + 0x5675, 0x392c, 0x3434, 0x5676, 0x3838, 0x4d44, 0x4d29, 0x3476, + 0x5678, 0x4423, 0x392d, 0x3e31, 0x485f, 0x3e32, 0x3d78, 0x446c, + 0x4a79, 0x4539, 0x392e, 0x495c, 0x5679, 0x4559, 0x3a42, 0x384b, + 0x446d, 0x3043, 0x3d6e, 0x392f, 0x4d47, 0x567a, 0x567b, 0x4751, + 0x567c, 0x4e77, 0x4f2d, 0x567e, 0x567d, 0x3347, 0x5721, 0x5724, + 0x5725, 0x5723, 0x4940, 0x3e33, 0x5727, 0x5726, 0x5722, 0x5728, + 0x5729, 0x572a, 0x572d, 0x572b, 0x572c, 0x572e, 0x3164, 0x446e, + 0x572f, 0x377a, 0x3276, 0x4736, 0x5730, 0x467b, 0x4a5b, 0x5731, + 0x4f2e, 0x5732, 0x4a40, 0x5735, 0x5021, 0x5031, 0x3c30, 0x4675, + 0x5736, 0x355d, 0x4424, 0x307a, 0x5737, 0x4a26, 0x3930, 0x4350, + 0x446f, 0x4c6f, 0x3839, 0x384c, 0x5738, 0x5739, 0x573f, 0x3c65, + 0x4425, 0x362f, 0x573a, 0x492b, 0x4346, 0x573b, 0x573c, 0x3630, + 0x573d, 0x573e, 0x5740, 0x4576, 0x5741, 0x5742, 0x5743, 0x5734, + 0x5733, 0x5744, 0x3741, 0x4927, 0x3a4c, 0x4937, 0x4426, 0x494b, + 0x5745, 0x3e34, 0x3146, 0x5746, 0x5747, 0x4c72, 0x4860, 0x574a, + 0x317d, 0x402c, 0x5749, 0x5748, 0x3742, 0x4254, 0x574e, 0x574c, + 0x574b, 0x4e27, 0x3865, 0x3d79, 0x574d, 0x454c, 0x3d3e, 0x4640, + 0x5751, 0x5750, 0x574f, 0x5752, 0x3866, 0x5753, 0x497c, 0x3d5b, + 0x5754, 0x4879, 0x4641, 0x4427, 0x4530, 0x5755, 0x352b, 0x3f34, + 0x492c, 0x3477, 0x4726, 0x5756, 0x3b56, 0x4b3a, 0x4b3b, 0x317e, + 0x575b, 0x4369, 0x5758, 0x3277, 0x582d, 0x575a, 0x4730, 0x5759, + 0x5757, 0x397a, 0x575d, 0x5763, 0x5769, 0x5761, 0x455c, 0x5766, + 0x495d, 0x5760, 0x5765, 0x4e67, 0x3b57, 0x4255, 0x575e, 0x355e, + 0x5768, 0x402d, 0x3165, 0x5762, 0x3278, 0x5767, 0x3631, 0x5764, + 0x576a, 0x576c, 0x5776, 0x5774, 0x5771, 0x5770, 0x4e78, 0x5772, + 0x3632, 0x3931, 0x3d7a, 0x5779, 0x576b, 0x576f, 0x575f, 0x327a, + 0x5773, 0x5775, 0x4351, 0x3a28, 0x3238, 0x576d, 0x5778, 0x5777, + 0x3633, 0x4229, 0x3366, 0x3743, 0x576e, 0x577a, 0x577d, 0x5821, + 0x3c3d, 0x5827, 0x4470, 0x577b, 0x5825, 0x3279, 0x5823, 0x5824, + 0x577e, 0x5822, 0x3867, 0x4d2a, 0x3435, 0x3159, 0x5826, 0x473a, + 0x302d, 0x4861, 0x575c, 0x582c, 0x5830, 0x4c65, 0x5829, 0x4569, + 0x582e, 0x3e70, 0x582f, 0x4657, 0x4f47, 0x582b, 0x5831, 0x397b, + 0x404b, 0x3054, 0x582a, 0x5828, 0x415a, 0x577c, 0x3b34, 0x4246, + 0x583d, 0x415b, 0x5838, 0x5835, 0x5836, 0x3c66, 0x5839, 0x583c, + 0x5837, 0x3d25, 0x583a, 0x5834, 0x4c7c, 0x4c7b, 0x583e, 0x583f, + 0x3055, 0x5833, 0x3672, 0x3026, 0x3436, 0x583b, 0x5843, 0x5842, + 0x5847, 0x5848, 0x5846, 0x5849, 0x5841, 0x5845, 0x584a, 0x584b, + 0x5840, 0x3b7c, 0x5844, 0x4256, 0x3932, 0x5832, 0x3f35, 0x5858, + 0x4a69, 0x584e, 0x584f, 0x5850, 0x5857, 0x5856, 0x4b7d, 0x3437, + 0x5854, 0x3745, 0x3334, 0x5851, 0x4e38, 0x5853, 0x3056, 0x5855, + 0x584c, 0x5852, 0x5859, 0x3744, 0x584d, 0x4d5d, 0x4d2b, 0x585c, + 0x5860, 0x417e, 0x4e79, 0x5861, 0x585e, 0x585b, 0x585a, 0x585f, + 0x4a30, 0x4634, 0x3746, 0x5862, 0x585d, 0x5863, 0x377b, 0x3231, + 0x586b, 0x3438, 0x5869, 0x586a, 0x3a29, 0x5868, 0x5866, 0x5865, + 0x586c, 0x5864, 0x586e, 0x327b, 0x5870, 0x586f, 0x4428, 0x5873, + 0x5871, 0x5867, 0x377c, 0x5872, 0x5876, 0x5875, 0x5877, 0x5874, + 0x5878, 0x5879, 0x587a, 0x4a6a, 0x587c, 0x587b, 0x3d3f, 0x402e, + 0x3266, 0x327c, 0x587d, 0x303f, 0x404c, 0x587e, 0x6c43, 0x5921, + 0x3761, 0x5922, 0x406f, 0x5923, 0x5924, 0x353a, 0x5925, 0x5926, + 0x5927, 0x4257, 0x384d, 0x4c61, 0x4b3c, 0x3d6a, 0x5928, 0x4070, + 0x6e3d, 0x4862, 0x3c6a, 0x3a4d, 0x5929, 0x4247, 0x4a27, 0x4271, + 0x592c, 0x592a, 0x592d, 0x592b, 0x592e, 0x4a31, 0x3037, 0x495e, + 0x4863, 0x592f, 0x5932, 0x3e35, 0x353b, 0x5930, 0x5937, 0x3e36, + 0x5931, 0x4744, 0x4d5e, 0x5933, 0x5934, 0x5938, 0x456a, 0x5935, + 0x3933, 0x405e, 0x5946, 0x4834, 0x4272, 0x4864, 0x5a2d, 0x4a7a, + 0x4471, 0x4b75, 0x593b, 0x3221, 0x436a, 0x5944, 0x4334, 0x593e, + 0x5945, 0x5940, 0x5947, 0x5943, 0x5942, 0x476f, 0x593c, 0x327d, + 0x593a, 0x3571, 0x4273, 0x5936, 0x5939, 0x3934, 0x405b, 0x3e37, + 0x5941, 0x4752, 0x3572, 0x3348, 0x3367, 0x3f21, 0x5949, 0x594e, + 0x594a, 0x377d, 0x594f, 0x3b22, 0x3969, 0x3d26, 0x593d, 0x3b7d, + 0x594c, 0x3b58, 0x594d, 0x3044, 0x5948, 0x4429, 0x3573, 0x3634, + 0x594b, 0x3027, 0x3a43, 0x3f36, 0x4472, 0x4854, 0x5951, 0x415e, + 0x422a, 0x3b2b, 0x5952, 0x5954, 0x5950, 0x4a61, 0x443d, 0x415c, + 0x4a7b, 0x3c4e, 0x5960, 0x595f, 0x3f78, 0x377e, 0x5959, 0x3e39, + 0x4668, 0x4731, 0x5957, 0x415d, 0x3c78, 0x595c, 0x3e38, 0x5956, + 0x595b, 0x4753, 0x5955, 0x3721, 0x335d, 0x595d, 0x4e2b, 0x3a4e, + 0x4335, 0x595a, 0x405c, 0x3935, 0x3f64, 0x3166, 0x413c, 0x5958, + 0x3545, 0x3747, 0x444f, 0x595e, 0x415f, 0x5961, 0x5963, 0x4237, + 0x5969, 0x5964, 0x5966, 0x4941, 0x4473, 0x5967, 0x4d2c, 0x4d48, + 0x3439, 0x302e, 0x5965, 0x5962, 0x3478, 0x3167, 0x5968, 0x4d49, + 0x596c, 0x423b, 0x5973, 0x596d, 0x596a, 0x5971, 0x5953, 0x596e, + 0x5972, 0x4842, 0x456b, 0x596b, 0x596f, 0x3748, 0x3a71, 0x405d, + 0x5977, 0x4526, 0x5974, 0x4b60, 0x5975, 0x5976, 0x4c4e, 0x4022, + 0x3762, 0x597d, 0x3b35, 0x597a, 0x5979, 0x4732, 0x4635, 0x4531, + 0x597b, 0x597c, 0x496f, 0x4745, 0x3b23, 0x4071, 0x4b50, 0x3349, + 0x5a25, 0x597e, 0x4d4a, 0x5a27, 0x5a23, 0x5a24, 0x4160, 0x5a22, + 0x593f, 0x5a26, 0x5a21, 0x5a2b, 0x5a2c, 0x4527, 0x5a2e, 0x3b24, + 0x5a29, 0x353c, 0x5a2f, 0x5a28, 0x5a33, 0x5a32, 0x5a31, 0x5a34, + 0x5a36, 0x3e71, 0x5a35, 0x5a39, 0x5a37, 0x5a38, 0x5970, 0x5a3b, + 0x5a3a, 0x5978, 0x5a3c, 0x5a30, 0x3b59, 0x5a3d, 0x5a3e, 0x5a40, + 0x5a3f, 0x5a41, 0x327e, 0x3936, 0x4a7c, 0x402f, 0x384e, 0x5a43, + 0x5a46, 0x4952, 0x355f, 0x5a45, 0x5a44, 0x4754, 0x5a47, 0x3635, + 0x5a49, 0x5a48, 0x343a, 0x3b36, 0x4658, 0x3749, 0x3f74, 0x5a4a, + 0x4030, 0x4528, 0x495f, 0x5a4b, 0x5a4c, 0x5a4d, 0x4a38, 0x555d, + 0x4046, 0x494c, 0x3a58, 0x4865, 0x4843, 0x454d, 0x4e41, 0x5a4f, + 0x3c50, 0x5a50, 0x3036, 0x3654, 0x404d, 0x4960, 0x5a51, 0x3b42, + 0x4347, 0x3b5b, 0x3f37, 0x5a52, 0x4a7d, 0x3177, 0x3b5c, 0x5a55, + 0x5a53, 0x5a56, 0x4e39, 0x5a54, 0x407b, 0x5a57, 0x4232, 0x5a58, + 0x347a, 0x5a5a, 0x5a59, 0x5a5b, 0x5a5c, 0x347b, 0x467c, 0x4336, + 0x356c, 0x3b5d, 0x4161, 0x3d5c, 0x3030, 0x5a5d, 0x3222, 0x5a61, + 0x3937, 0x5a60, 0x3a2b, 0x3e3a, 0x5a5f, 0x3e3b, 0x4c40, 0x3a2a, + 0x3057, 0x404e, 0x5a66, 0x4031, 0x3147, 0x3d55, 0x4b66, 0x3a72, + 0x3e3c, 0x4027, 0x5a65, 0x5a63, 0x5a64, 0x436b, 0x5b26, 0x5a6a, + 0x3b7e, 0x3938, 0x5a68, 0x5a69, 0x3f38, 0x5a67, 0x3b2f, 0x5a6c, + 0x5a6b, 0x5a70, 0x5a71, 0x5a6d, 0x3322, 0x5a6e, 0x5a6f, 0x4855, + 0x4961, 0x374a, 0x5a72, 0x4032, 0x3e3d, 0x4352, 0x3647, 0x5a73, + 0x5a77, 0x324b, 0x5a74, 0x5a76, 0x5a75, 0x3d6b, 0x4348, 0x3045, + 0x5a78, 0x5a79, 0x442a, 0x4e71, 0x3b43, 0x4a6b, 0x4b3d, 0x5b22, + 0x5a7b, 0x5a7e, 0x5a7d, 0x5a7a, 0x5b21, 0x465e, 0x5a7c, 0x5b23, + 0x3d6c, 0x5b24, 0x4d4b, 0x4778, 0x5b25, 0x5b27, 0x5b28, 0x5b29, + 0x364a, 0x3148, 0x3939, 0x5b2a, 0x5b2b, 0x3d71, 0x4162, 0x5258, + 0x413e, 0x413d, 0x4258, 0x3a47, 0x5072, 0x376e, 0x4d2d, 0x4a7e, + 0x497e, 0x5b2c, 0x3a73, 0x443f, 0x5b2d, 0x4f2f, 0x4b3e, 0x442b, + 0x5b2e, 0x347c, 0x5b2f, 0x5b30, 0x4c5a, 0x4c24, 0x4b76, 0x4b5c, + 0x3b25, 0x5b32, 0x3c6b, 0x4b51, 0x5b34, 0x5b37, 0x5b36, 0x3479, + 0x3560, 0x5b33, 0x5b35, 0x5b38, 0x3f79, 0x4d7b, 0x3049, 0x3a60, + 0x423c, 0x3c5d, 0x3e73, 0x5b3b, 0x454e, 0x5b39, 0x422b, 0x5b3a, + 0x3e72, 0x4c5d, 0x5b3c, 0x5b3d, 0x4d68, 0x5b42, 0x393a, 0x4755, + 0x5b3f, 0x456c, 0x5a5e, 0x5a62, 0x354f, 0x4747, 0x5b41, 0x3e3e, + 0x4844, 0x5b47, 0x487a, 0x5b3e, 0x5b44, 0x5b43, 0x404f, 0x4b6d, + 0x4e53, 0x4b67, 0x324c, 0x3b5e, 0x4f48, 0x5b46, 0x3f75, 0x5b45, + 0x5b40, 0x384f, 0x5b4c, 0x5b4a, 0x324d, 0x5b48, 0x5b4e, 0x5b54, + 0x4248, 0x4a41, 0x5b56, 0x4922, 0x5b55, 0x4770, 0x4b3f, 0x343b, + 0x4077, 0x3d40, 0x4453, 0x4d2e, 0x5b51, 0x5b50, 0x5b52, 0x5b4f, + 0x5b57, 0x5b4d, 0x5b4b, 0x5b53, 0x5b49, 0x436c, 0x4c78, 0x3c46, + 0x3a74, 0x3a3a, 0x4b6f, 0x3341, 0x444e, 0x464a, 0x3149, 0x4072, + 0x4034, 0x372a, 0x5b59, 0x393b, 0x337c, 0x5b5b, 0x3374, 0x5b61, + 0x5b5e, 0x4073, 0x334b, 0x3a2c, 0x334a, 0x3a4f, 0x5b5c, 0x3765, + 0x374b, 0x456d, 0x5b5a, 0x3046, 0x5b5d, 0x5b5f, 0x364d, 0x372c, + 0x343c, 0x354b, 0x5b62, 0x3a79, 0x4b71, 0x3b37, 0x5b63, 0x4930, + 0x5b6f, 0x3233, 0x5b64, 0x5b75, 0x5b65, 0x4e42, 0x5b6c, 0x475f, + 0x5b74, 0x5b67, 0x3034, 0x5b69, 0x393c, 0x5b6b, 0x5b6a, 0x5b66, + 0x5b71, 0x3e3f, 0x546d, 0x3868, 0x4d7c, 0x5b68, 0x4474, 0x3323, + 0x3a2d, 0x5b60, 0x5b70, 0x3361, 0x5b6e, 0x5b72, 0x456e, 0x347e, + 0x5c32, 0x4c49, 0x5b77, 0x347d, 0x5b7e, 0x4b40, 0x5c21, 0x5c23, + 0x5c27, 0x5b79, 0x432a, 0x456f, 0x5c2b, 0x5b7c, 0x5c28, 0x5c22, + 0x3f39, 0x5c2c, 0x4033, 0x5c2a, 0x343d, 0x4f50, 0x5b76, 0x5c26, + 0x3058, 0x5b78, 0x4c3a, 0x5b7d, 0x3f22, 0x4447, 0x5b73, 0x5c25, + 0x3f7a, 0x5c2f, 0x3371, 0x3821, 0x5c31, 0x5b7a, 0x5c30, 0x5c29, + 0x5b7b, 0x5c2d, 0x5c2e, 0x5c3f, 0x464e, 0x5c24, 0x5c3b, 0x5c3d, + 0x4458, 0x4d4c, 0x4976, 0x5c38, 0x424a, 0x5c3e, 0x413f, 0x5c35, + 0x5c42, 0x5c41, 0x466f, 0x5c40, 0x466a, 0x5c44, 0x5c37, 0x3648, + 0x5c3a, 0x3d5d, 0x4760, 0x5c3c, 0x364b, 0x5c34, 0x5c36, 0x5c33, + 0x4f30, 0x335a, 0x5c39, 0x5c43, 0x3335, 0x3a67, 0x315d, 0x5c54, + 0x4f31, 0x5c57, 0x3f3a, 0x5c56, 0x5c55, 0x5c52, 0x5c46, 0x5c63, + 0x5c45, 0x5c58, 0x5c50, 0x5c4b, 0x5c48, 0x5c49, 0x5c51, 0x7422, + 0x5c4e, 0x393d, 0x4448, 0x4164, 0x5c4c, 0x5c47, 0x5c4a, 0x4d4d, + 0x4b6a, 0x5c4f, 0x5c59, 0x5c61, 0x5c5a, 0x5c67, 0x5c65, 0x5c60, + 0x5c5f, 0x4450, 0x4165, 0x5c5d, 0x5c5b, 0x5c62, 0x5c68, 0x4875, + 0x5c6e, 0x5c69, 0x5c6c, 0x5c66, 0x4374, 0x4938, 0x5c5c, 0x5c64, + 0x3e40, 0x4c4f, 0x5c78, 0x5c6b, 0x3822, 0x3223, 0x335f, 0x5c53, + 0x3e41, 0x5c70, 0x5c77, 0x3c79, 0x3372, 0x432e, 0x5c6d, 0x5c72, + 0x5c76, 0x3636, 0x354c, 0x5c74, 0x3521, 0x464b, 0x5c73, 0x5c75, + 0x5c6f, 0x5c71, 0x3360, 0x4349, 0x5c7c, 0x5c7a, 0x3869, 0x5c79, + 0x5d21, 0x5b58, 0x5c7b, 0x5c7d, 0x5c7e, 0x5d2c, 0x5d28, 0x5b6d, + 0x5d27, 0x5d26, 0x5d23, 0x5c6a, 0x5d25, 0x5d24, 0x5d2a, 0x4f26, + 0x5d2d, 0x367b, 0x5d29, 0x5d2b, 0x4827, 0x5d2e, 0x5d32, 0x5d2f, + 0x4d73, 0x5d30, 0x5c5e, 0x5d33, 0x5d34, 0x3135, 0x5d36, 0x3767, + 0x3c21, 0x3655, 0x3224, 0x4d5f, 0x5d38, 0x5d37, 0x5d3a, 0x353d, + 0x3656, 0x343e, 0x5d3d, 0x5d3c, 0x5d3e, 0x324e, 0x4337, 0x5d3f, + 0x343f, 0x5d41, 0x5d40, 0x5d42, 0x5d43, 0x5d44, 0x3b5f, 0x4035, + 0x3a21, 0x4970, 0x4a62, 0x4f44, 0x3b75, 0x3a50, 0x4e72, 0x5d45, + 0x5d46, 0x3b60, 0x5d47, 0x5d48, 0x5d4a, 0x5d49, 0x4b58, 0x3d5e, + 0x3c6c, 0x3b44, 0x5d4b, 0x5d4d, 0x3f23, 0x5d4c, 0x5d4e, 0x5d4f, + 0x5d50, 0x5d51, 0x5d52, 0x5d54, 0x5d53, 0x5d55, 0x3225, 0x434a, + 0x5d56, 0x3b26, 0x334c, 0x5d57, 0x4542, 0x544c, 0x3523, 0x5d58, + 0x5d59, 0x4a6c, 0x4b68, 0x4647, 0x5d5a, 0x4866, 0x487b, 0x4c53, + 0x5d5b, 0x5d5d, 0x5d5c, 0x5d5f, 0x5d5e, 0x5d61, 0x3b61, 0x4c31, + 0x5d62, 0x5d63, 0x3524, 0x5d64, 0x5d66, 0x5d65, 0x3f65, 0x4939, + 0x314a, 0x4845, 0x4475, 0x3d41, 0x3561, 0x4846, 0x3c2e, 0x5d68, + 0x3440, 0x3178, 0x4672, 0x5d67, 0x393e, 0x4353, 0x5d69, 0x5d71, + 0x5d6a, 0x4241, 0x3562, 0x5d72, 0x3768, 0x3525, 0x5d70, 0x5d6e, + 0x5d6b, 0x4d60, 0x4440, 0x4659, 0x5d6c, 0x5d74, 0x5d73, 0x3723, + 0x322d, 0x3a3b, 0x5d6d, 0x5d6f, 0x4b57, 0x4274, 0x4b77, 0x5d7c, + 0x5d7d, 0x324f, 0x4a28, 0x4c7d, 0x5e21, 0x3c23, 0x3e42, 0x5d78, + 0x5d7e, 0x3168, 0x3637, 0x5d75, 0x5d7a, 0x4074, 0x4771, 0x4867, + 0x5d77, 0x4b21, 0x5d79, 0x5e24, 0x5e22, 0x5d7b, 0x4b22, 0x4748, + 0x3563, 0x4525, 0x436d, 0x5e25, 0x5e23, 0x4259, 0x5d76, 0x314b, + 0x4d4e, 0x5e30, 0x5e2f, 0x4076, 0x5e2c, 0x4d6c, 0x4636, 0x5e26, + 0x4445, 0x314c, 0x393f, 0x5e29, 0x3d27, 0x5e2e, 0x5e2d, 0x5e28, + 0x5e2b, 0x3368, 0x5e2a, 0x4749, 0x4e2e, 0x3e74, 0x4075, 0x5e36, + 0x5e34, 0x494d, 0x5e31, 0x5e33, 0x313a, 0x3940, 0x4f32, 0x333d, + 0x4962, 0x4d61, 0x3324, 0x3f3b, 0x5e35, 0x5e3a, 0x3e43, 0x4d30, + 0x5e37, 0x5e32, 0x5e38, 0x4e5e, 0x4573, 0x4642, 0x3336, 0x3155, + 0x5e3e, 0x5e41, 0x4e43, 0x4d64, 0x5e48, 0x5e42, 0x5e3f, 0x4e54, + 0x5e45, 0x3d4a, 0x5e47, 0x5e4c, 0x4571, 0x5e4a, 0x5e44, 0x4338, + 0x5e4b, 0x5e40, 0x5e46, 0x5e4d, 0x307c, 0x5e43, 0x5e4e, 0x3f3c, + 0x3d5f, 0x4a25, 0x3a2e, 0x5e3b, 0x5e49, 0x453a, 0x4036, 0x3369, + 0x3a51, 0x3e44, 0x5e3d, 0x3d42, 0x374c, 0x5e3c, 0x5e52, 0x3d6d, + 0x383a, 0x5e61, 0x5e5b, 0x3574, 0x454f, 0x5e56, 0x5e5f, 0x302f, + 0x3132, 0x3239, 0x5e58, 0x422c, 0x5e4f, 0x5e51, 0x3941, 0x5e62, + 0x5e5d, 0x5e55, 0x5e5c, 0x4c2b, 0x5e5a, 0x5e5e, 0x3850, 0x3e45, + 0x4339, 0x5e54, 0x4d2f, 0x5e57, 0x5e50, 0x4572, 0x5e53, 0x5e59, + 0x4f51, 0x3c3e, 0x4b7e, 0x5e63, 0x482e, 0x5e6f, 0x383b, 0x3d60, + 0x5e65, 0x4e2f, 0x3942, 0x5e72, 0x306e, 0x5e70, 0x5e64, 0x5e6a, + 0x5e6c, 0x4d4f, 0x5e67, 0x452e, 0x5e69, 0x5e71, 0x5e6b, 0x4c47, + 0x5e66, 0x3c22, 0x5e7e, 0x336a, 0x5e68, 0x5e6d, 0x5e6e, 0x426c, + 0x425a, 0x5e76, 0x5e7c, 0x5e7a, 0x4529, 0x5f23, 0x5e77, 0x5e78, + 0x5e60, 0x3579, 0x493a, 0x3c3f, 0x3977, 0x4f33, 0x5e74, 0x5f22, + 0x3169, 0x4166, 0x4779, 0x3441, 0x4e7a, 0x4c21, 0x4452, 0x5e7b, + 0x5e7d, 0x4132, 0x5f21, 0x5e79, 0x5e73, 0x3443, 0x3769, 0x5f2f, + 0x5f2a, 0x4078, 0x3363, 0x3d61, 0x5f33, 0x5f2c, 0x442c, 0x5f29, + 0x4459, 0x5f4c, 0x5f26, 0x5f25, 0x5f2e, 0x5f28, 0x5f27, 0x5f2d, + 0x4021, 0x5f24, 0x5f30, 0x5f31, 0x3442, 0x5f36, 0x5f35, 0x5f37, + 0x5f3a, 0x4543, 0x5f34, 0x5f38, 0x3763, 0x4279, 0x5f32, 0x473b, + 0x5f39, 0x5f3e, 0x5f3c, 0x5f3f, 0x5f42, 0x5f3b, 0x396a, 0x4728, + 0x5e39, 0x4d74, 0x5f3d, 0x5f41, 0x4275, 0x5f40, 0x5f2b, 0x6f69, + 0x5f45, 0x5f49, 0x5f47, 0x5f43, 0x5f44, 0x5f48, 0x5f46, 0x494e, + 0x5f4e, 0x5f4b, 0x5f4a, 0x5f4d, 0x4654, 0x5f4f, 0x4375, 0x426d, + 0x4025, 0x5f50, 0x5f52, 0x5f51, 0x5e75, 0x5f53, 0x4667, 0x5f54, + 0x3250, 0x4574, 0x3325, 0x3564, 0x3c5e, 0x3a52, 0x4f27, 0x3f66, + 0x316a, 0x5f56, 0x5f55, 0x5f59, 0x433a, 0x5f5c, 0x5f57, 0x5f5b, + 0x5f5a, 0x4540, 0x3059, 0x4e75, 0x5f5e, 0x3128, 0x5f60, 0x5f5f, + 0x5f5d, 0x5f58, 0x4b23, 0x5f62, 0x5f61, 0x316b, 0x5f64, 0x4a32, + 0x5f63, 0x4c35, 0x3e47, 0x4133, 0x3e46, 0x4e7b, 0x5f6a, 0x4079, + 0x5f66, 0x5f6b, 0x316c, 0x5f69, 0x4761, 0x5f65, 0x5f68, 0x3e48, + 0x4851, 0x5f6c, 0x3c51, 0x407a, 0x5f6f, 0x5f67, 0x3727, 0x5f6d, + 0x4d50, 0x5f70, 0x7426, 0x3d4f, 0x5f71, 0x5f72, 0x472e, 0x5f74, + 0x5f75, 0x4733, 0x4575, 0x5f77, 0x5f79, 0x4e55, 0x5f76, 0x5f78, + 0x316d, 0x5f73, 0x535b, 0x5f7a, 0x4167, 0x3b38, 0x5f7c, 0x5f7b, + 0x3f24, 0x5259, 0x5f7d, 0x6021, 0x5f6e, 0x5f7e, 0x6022, 0x477a, + 0x6023, 0x6024, 0x6025, 0x6026, 0x445e, 0x6028, 0x6027, 0x6029, + 0x602a, 0x3c5f, 0x4963, 0x4c6c, 0x602b, 0x602c, 0x4156, 0x3c24, + 0x602d, 0x602e, 0x602f, 0x4a52, 0x4847, 0x6030, 0x4757, 0x442d, + 0x6031, 0x3267, 0x356d, 0x4c46, 0x4c36, 0x3234, 0x4f34, 0x4b52, + 0x4a2a, 0x4037, 0x6032, 0x4643, 0x3823, 0x6033, 0x3a54, 0x6035, + 0x6034, 0x6036, 0x6037, 0x6038, 0x353e, 0x6039, 0x603a, 0x3824, + 0x4848, 0x603c, 0x3e75, 0x603b, 0x3638, 0x603d, 0x603f, 0x603e, + 0x6040, 0x3851, 0x6041, 0x3669, 0x4140, 0x397d, 0x6043, 0x6044, + 0x6042, 0x3c6d, 0x4648, 0x3639, 0x6046, 0x432c, 0x6045, 0x4f35, + 0x4762, 0x6049, 0x604b, 0x6048, 0x4c54, 0x604a, 0x604c, 0x4e44, + 0x6050, 0x604f, 0x4376, 0x472d, 0x3825, 0x604e, 0x604d, 0x4d31, + 0x4d32, 0x6051, 0x316e, 0x3976, 0x3b62, 0x6052, 0x6053, 0x6055, + 0x3d43, 0x6057, 0x6056, 0x6058, 0x334d, 0x605a, 0x6059, 0x605c, + 0x605b, 0x383c, 0x4e28, 0x364c, 0x3226, 0x366a, 0x3461, 0x4e68, + 0x605e, 0x6060, 0x6061, 0x3251, 0x605d, 0x3b39, 0x4441, 0x605f, + 0x6064, 0x3c6e, 0x6062, 0x373e, 0x4849, 0x6063, 0x607e, 0x6069, + 0x383d, 0x3565, 0x6066, 0x4d7d, 0x4e30, 0x4276, 0x6068, 0x606a, + 0x4e56, 0x3657, 0x487c, 0x474a, 0x606b, 0x606d, 0x6070, 0x606c, + 0x606f, 0x386a, 0x314d, 0x6071, 0x3f70, 0x606e, 0x4e5c, 0x6074, + 0x7424, 0x6072, 0x6075, 0x6067, 0x6073, 0x3a3c, 0x6076, 0x6077, + 0x4d7e, 0x6078, 0x6079, 0x6065, 0x607a, 0x3444, 0x3c25, 0x607b, + 0x607c, 0x607d, 0x313b, 0x6121, 0x493b, 0x6122, 0x3424, 0x6123, + 0x6124, 0x6125, 0x6127, 0x6128, 0x6126, 0x4953, 0x612a, 0x6129, + 0x612c, 0x612b, 0x612d, 0x612e, 0x6130, 0x612f, 0x3979, 0x6132, + 0x6131, 0x3445, 0x3f53, 0x453c, 0x6133, 0x4038, 0x3b3a, 0x3179, + 0x6134, 0x4d51, 0x4a63, 0x6135, 0x4544, 0x4d33, 0x3943, 0x3f3d, + 0x434b, 0x5234, 0x442e, 0x3268, 0x6136, 0x6137, 0x613c, 0x613a, + 0x6139, 0x5a42, 0x3326, 0x6138, 0x305a, 0x482a, 0x484a, 0x4e31, + 0x613d, 0x613b, 0x435c, 0x4026, 0x482b, 0x492d, 0x613f, 0x4e2c, + 0x374d, 0x6140, 0x613e, 0x4856, 0x6141, 0x6142, 0x305b, 0x3e76, + 0x6147, 0x6144, 0x466d, 0x6143, 0x3526, 0x614a, 0x6145, 0x6146, + 0x6149, 0x6148, 0x4925, 0x4142, 0x4141, 0x353f, 0x614b, 0x614c, + 0x614d, 0x614f, 0x614e, 0x3156, 0x6157, 0x4868, 0x6151, 0x6153, + 0x6155, 0x3f3e, 0x6156, 0x6154, 0x3c40, 0x6150, 0x6152, 0x4942, + 0x3e49, 0x6159, 0x6158, 0x615a, 0x3c26, 0x3a2f, 0x4577, 0x615b, + 0x444b, 0x615d, 0x4e21, 0x615c, 0x4169, 0x6162, 0x6164, 0x6165, + 0x4354, 0x6163, 0x6160, 0x615e, 0x615f, 0x6161, 0x6168, 0x6166, + 0x6167, 0x6169, 0x616b, 0x616c, 0x616d, 0x616e, 0x616a, 0x6170, + 0x616f, 0x6171, 0x4e45, 0x6174, 0x6172, 0x6173, 0x3462, 0x4c7e, + 0x4a4a, 0x6176, 0x6175, 0x6177, 0x6178, 0x617c, 0x6179, 0x617a, + 0x617b, 0x617d, 0x617e, 0x6221, 0x6222, 0x6223, 0x482f, 0x4550, + 0x6224, 0x4772, 0x4934, 0x6225, 0x6226, 0x452a, 0x3327, 0x3944, + 0x6227, 0x6228, 0x6229, 0x3b29, 0x622b, 0x622a, 0x622c, 0x622d, + 0x4869, 0x622e, 0x622f, 0x7369, 0x6230, 0x6231, 0x6232, 0x3b2e, + 0x6233, 0x4756, 0x4b5f, 0x314e, 0x3157, 0x6234, 0x6236, 0x6235, + 0x4570, 0x4039, 0x5d39, 0x6237, 0x4c41, 0x6238, 0x3446, 0x4857, + 0x6239, 0x623a, 0x623b, 0x4c5c, 0x4c55, 0x443e, 0x416a, 0x623d, + 0x3d62, 0x3e4a, 0x6240, 0x623f, 0x623e, 0x487d, 0x3447, 0x3829, + 0x6246, 0x6243, 0x3f3f, 0x4c32, 0x6242, 0x6244, 0x6245, 0x6241, + 0x6247, 0x6248, 0x442f, 0x3463, 0x4365, 0x6249, 0x624a, 0x624d, + 0x3f67, 0x4644, 0x624e, 0x4b53, 0x624b, 0x624c, 0x6251, 0x6250, + 0x624f, 0x6253, 0x6252, 0x6254, 0x6256, 0x6255, 0x4a4d, 0x3d56, + 0x4e46, 0x6257, 0x4637, 0x6258, 0x6259, 0x625d, 0x625b, 0x625c, + 0x625a, 0x625e, 0x625f, 0x6260, 0x6261, 0x4c37, 0x6262, 0x4c70, + 0x6263, 0x434e, 0x476a, 0x366b, 0x433b, 0x6264, 0x363a, 0x4050, + 0x6265, 0x3a3d, 0x6266, 0x6267, 0x3826, 0x3a55, 0x6269, 0x4556, + 0x3a56, 0x354e, 0x4b24, 0x474b, 0x4557, 0x395c, 0x626b, 0x3e4b, + 0x4e32, 0x3945, 0x3827, 0x4823, 0x626d, 0x626f, 0x386b, 0x626e, + 0x4476, 0x6271, 0x3337, 0x626c, 0x486a, 0x3130, 0x3a6c, 0x4f52, + 0x6270, 0x6272, 0x4a4b, 0x4059, 0x6274, 0x6275, 0x6273, 0x334e, + 0x627b, 0x627a, 0x3c27, 0x627c, 0x6277, 0x627d, 0x6278, 0x4858, + 0x6276, 0x6279, 0x6322, 0x6321, 0x4b61, 0x627e, 0x306b, 0x6324, + 0x6323, 0x3e4c, 0x6325, 0x4143, 0x6327, 0x6326, 0x6328, 0x6268, + 0x626a, 0x632a, 0x6329, 0x3c28, 0x4e69, 0x3c52, 0x632b, 0x3737, + 0x3540, 0x3527, 0x3b63, 0x4d34, 0x6331, 0x6330, 0x4144, 0x632d, + 0x632f, 0x3d4b, 0x3f40, 0x632e, 0x632c, 0x472a, 0x3e4d, 0x493c, + 0x3a57, 0x4578, 0x6332, 0x6333, 0x6349, 0x3658, 0x4f3d, 0x4135, + 0x6334, 0x3252, 0x4477, 0x4a21, 0x6335, 0x357a, 0x6336, 0x6338, + 0x6339, 0x4729, 0x633a, 0x633b, 0x633c, 0x3659, 0x3253, 0x4645, + 0x3d28, 0x3b64, 0x633d, 0x3d29, 0x324a, 0x4943, 0x633e, 0x486b, + 0x4145, 0x6341, 0x6342, 0x4769, 0x3f41, 0x633f, 0x4361, 0x6340, + 0x3e4e, 0x305c, 0x3529, 0x6343, 0x4478, 0x6344, 0x4047, 0x4c2d, + 0x4923, 0x6345, 0x6346, 0x4355, 0x4e47, 0x6348, 0x6347, 0x3c6f, + 0x634a, 0x3070, 0x634d, 0x634b, 0x3254, 0x374e, 0x634c, 0x3946, + 0x3972, 0x4a66, 0x634e, 0x4b54, 0x6350, 0x4051, 0x314f, 0x323a, + 0x302c, 0x634f, 0x6351, 0x6352, 0x3e77, 0x6353, 0x334f, 0x6355, + 0x376a, 0x3566, 0x6356, 0x3675, 0x6357, 0x407c, 0x464d, 0x4060, + 0x3a75, 0x6358, 0x4362, 0x416b, 0x635a, 0x635c, 0x6359, 0x635b, + 0x3722, 0x635d, 0x3726, 0x3567, 0x4d52, 0x635f, 0x6360, 0x312e, + 0x6363, 0x3376, 0x6362, 0x6361, 0x6365, 0x635e, 0x6366, 0x4e29, + 0x6367, 0x6368, 0x5474, 0x636a, 0x6369, 0x636b, 0x636c, 0x4e35, + 0x636d, 0x706f, 0x3e4f, 0x636e, 0x636f, 0x3d57, 0x4638, 0x6370, + 0x4328, 0x6371, 0x433c, 0x6372, 0x3625, 0x513f, 0x435d, 0x3c33, + 0x3448, 0x6373, 0x6422, 0x6376, 0x3568, 0x6375, 0x6424, 0x6374, + 0x3e50, 0x6378, 0x6379, 0x452b, 0x637a, 0x335e, 0x3f5a, 0x4964, + 0x637c, 0x4268, 0x6377, 0x637b, 0x637d, 0x3a7b, 0x6426, 0x492e, + 0x4826, 0x4579, 0x365a, 0x6425, 0x6423, 0x4835, 0x637e, 0x435e, + 0x457b, 0x457a, 0x3a76, 0x6438, 0x6428, 0x642a, 0x642d, 0x642e, + 0x642b, 0x642c, 0x6429, 0x6427, 0x6421, 0x4a4f, 0x3255, 0x6435, + 0x6432, 0x6437, 0x6436, 0x4773, 0x4c27, 0x3b3b, 0x6430, 0x6439, + 0x6434, 0x6433, 0x642f, 0x6431, 0x3449, 0x433d, 0x407d, 0x4822, + 0x643e, 0x4824, 0x4061, 0x643b, 0x484f, 0x643f, 0x4a53, 0x435b, + 0x643a, 0x643c, 0x643d, 0x6440, 0x3c44, 0x4646, 0x6445, 0x6444, + 0x6441, 0x4f36, 0x644a, 0x644e, 0x644b, 0x6447, 0x6448, 0x644d, + 0x6442, 0x5255, 0x6449, 0x6443, 0x644c, 0x6452, 0x344a, 0x644f, + 0x6450, 0x6451, 0x6454, 0x6453, 0x4876, 0x6455, 0x4e7c, 0x4a6d, + 0x645a, 0x6457, 0x6456, 0x4052, 0x6459, 0x645b, 0x6458, 0x645f, + 0x645c, 0x645d, 0x6446, 0x645e, 0x6460, 0x6461, 0x4a46, 0x6462, + 0x4c62, 0x364e, 0x3729, 0x6463, 0x4a34, 0x3f68, 0x4c30, 0x6464, + 0x4e33, 0x4774, 0x4146, 0x4734, 0x3d4d, 0x3040, 0x6469, 0x6467, + 0x6465, 0x3421, 0x3e51, 0x646a, 0x6468, 0x6466, 0x646e, 0x646d, + 0x646c, 0x646b, 0x646f, 0x6470, 0x403a, 0x6471, 0x6473, 0x6472, + 0x3852, 0x4138, 0x6475, 0x457c, 0x6474, 0x6476, 0x4a35, 0x416c, + 0x3947, 0x6477, 0x4e48, 0x6479, 0x647a, 0x647b, 0x647c, 0x3b65, + 0x647d, 0x374f, 0x356a, 0x352a, 0x6521, 0x4c73, 0x3948, 0x647e, + 0x6524, 0x4c66, 0x473c, 0x4933, 0x3d63, 0x6523, 0x3c53, 0x3949, + 0x3b66, 0x3569, 0x4a36, 0x6522, 0x4147, 0x4b42, 0x3a77, 0x3b67, + 0x445d, 0x6527, 0x4e5f, 0x3a59, 0x6528, 0x3f42, 0x652a, 0x3e52, + 0x3a30, 0x6529, 0x3d2a, 0x383e, 0x4148, 0x6525, 0x652b, 0x6526, + 0x3750, 0x652e, 0x6532, 0x376b, 0x652d, 0x6536, 0x394a, 0x4d6d, + 0x303c, 0x6533, 0x356b, 0x6530, 0x6531, 0x457d, 0x652f, 0x652c, + 0x3328, 0x4064, 0x3828, 0x6538, 0x6535, 0x6537, 0x6534, 0x3751, + 0x4233, 0x6539, 0x416e, 0x6546, 0x6542, 0x653c, 0x6540, 0x3c7a, + 0x305d, 0x653b, 0x6543, 0x6547, 0x394b, 0x4c56, 0x4456, 0x653d, + 0x6545, 0x653a, 0x433e, 0x653f, 0x303d, 0x4c4a, 0x653e, 0x365b, + 0x486c, 0x416d, 0x4e50, 0x3d6f, 0x656e, 0x6548, 0x407e, 0x6544, + 0x6549, 0x654b, 0x4479, 0x654e, 0x654a, 0x4a54, 0x344b, 0x4c4b, + 0x305e, 0x654d, 0x4e7d, 0x654c, 0x316f, 0x466c, 0x654f, 0x6556, + 0x6550, 0x6557, 0x6553, 0x477b, 0x3c4a, 0x6555, 0x6552, 0x6558, + 0x6551, 0x3d44, 0x4b25, 0x3d4c, 0x6554, 0x6560, 0x655c, 0x655f, + 0x655d, 0x6561, 0x655b, 0x6541, 0x4053, 0x484b, 0x655e, 0x6559, + 0x4121, 0x3752, 0x3d2b, 0x3f25, 0x4136, 0x6564, 0x6566, 0x6567, + 0x6563, 0x6565, 0x655a, 0x6562, 0x656a, 0x6569, 0x4b7a, 0x372b, + 0x6568, 0x656c, 0x656b, 0x656f, 0x6571, 0x3b3c, 0x656d, 0x6572, + 0x6573, 0x6574, 0x657a, 0x453b, 0x6576, 0x6575, 0x6577, 0x6578, + 0x6579, 0x657b, 0x657c, 0x344c, 0x657d, 0x657e, 0x6621, 0x6622, + 0x6623, 0x6624, 0x6625, 0x6626, 0x6628, 0x6627, 0x6629, 0x662a, + 0x662b, 0x662e, 0x662c, 0x662d, 0x3a61, 0x3753, 0x4356, 0x4833, + 0x3d70, 0x474d, 0x486d, 0x662f, 0x586d, 0x6630, 0x6632, 0x4d65, + 0x6631, 0x6634, 0x6633, 0x4d53, 0x6635, 0x487e, 0x6636, 0x6639, + 0x6638, 0x6637, 0x663a, 0x3732, 0x4122, 0x3541, 0x663e, 0x663b, + 0x663c, 0x663f, 0x6640, 0x663d, 0x3129, 0x3227, 0x6642, 0x6643, + 0x6644, 0x4d62, 0x3d2c, 0x6646, 0x6645, 0x3f69, 0x6647, 0x6648, + 0x6649, 0x3465, 0x344d, 0x664a, 0x664b, 0x4b5d, 0x4d63, 0x4d54, + 0x4f37, 0x394d, 0x664e, 0x3c54, 0x664d, 0x664f, 0x3c29, 0x4251, + 0x6650, 0x394c, 0x4c57, 0x6651, 0x6652, 0x6653, 0x6654, 0x6655, + 0x3c2a, 0x4c6d, 0x6657, 0x433f, 0x6656, 0x6659, 0x6658, 0x665a, + 0x403b, 0x665b, 0x665c, 0x4a39, 0x665d, 0x416f, 0x665e, 0x665f, + 0x4e7e, 0x6662, 0x6661, 0x6660, 0x4430, 0x6663, 0x3f26, 0x6664, + 0x6665, 0x4f38, 0x6666, 0x6667, 0x6669, 0x6668, 0x4825, 0x4679, + 0x4f3e, 0x4829, 0x666b, 0x3e53, 0x492a, 0x666c, 0x666a, 0x344e, + 0x3854, 0x3b68, 0x486e, 0x382a, 0x4b43, 0x666f, 0x666d, 0x394e, + 0x394f, 0x3069, 0x3a68, 0x4759, 0x305f, 0x6674, 0x4340, 0x4758, + 0x425b, 0x6676, 0x6672, 0x6675, 0x6670, 0x6673, 0x4b26, 0x3855, + 0x307d, 0x6671, 0x6678, 0x6679, 0x4639, 0x363b, 0x6726, 0x473d, + 0x3b69, 0x363c, 0x4048, 0x4f46, 0x4c2e, 0x6677, 0x4054, 0x3553, + 0x667a, 0x667c, 0x667b, 0x667d, 0x4326, 0x473e, 0x4431, 0x6723, + 0x6722, 0x667e, 0x3f55, 0x4965, 0x6725, 0x6724, 0x3950, 0x4f53, + 0x6735, 0x6729, 0x672a, 0x3c70, 0x6728, 0x3978, 0x6727, 0x672b, + 0x4432, 0x4a22, 0x4123, 0x425c, 0x672f, 0x6730, 0x672c, 0x672d, + 0x672e, 0x3951, 0x6736, 0x6732, 0x4966, 0x4b6c, 0x4928, 0x6731, + 0x6734, 0x6733, 0x4b44, 0x6737, 0x6738, 0x4137, 0x6739, 0x673b, + 0x673f, 0x673c, 0x673a, 0x473f, 0x673d, 0x673e, 0x3232, 0x6745, + 0x6740, 0x6741, 0x6742, 0x4221, 0x6744, 0x6743, 0x6746, 0x6747, + 0x6748, 0x3f43, 0x3269, 0x6749, 0x4e57, 0x3c2b, 0x3d2d, 0x3b6a, + 0x4357, 0x674a, 0x674b, 0x3131, 0x674c, 0x674d, 0x674e, 0x674f, + 0x6750, 0x363d, 0x5a2a, 0x6751, 0x4065, 0x6752, 0x3c4b, 0x6753, + 0x5030, 0x6754, 0x4a5e, 0x345c, 0x4124, 0x3d58, 0x4971, 0x3d2e, + 0x6755, 0x3952, 0x6756, 0x484c, 0x6764, 0x6758, 0x4249, 0x4775, + 0x383f, 0x6757, 0x4125, 0x6759, 0x447a, 0x675b, 0x675a, 0x675d, + 0x675c, 0x675e, 0x6760, 0x675f, 0x344f, 0x6761, 0x6762, 0x6763, + 0x3a31, 0x4e49, 0x6765, 0x3f27, 0x3170, 0x6766, 0x6767, 0x6768, + 0x3072, 0x6769, 0x676a, 0x4967, 0x3c47, 0x676c, 0x3329, 0x3032, + 0x676b, 0x676e, 0x474e, 0x3f44, 0x3256, 0x4b27, 0x375d, 0x365c, + 0x676d, 0x326a, 0x3423, 0x3171, 0x6772, 0x4e6a, 0x425d, 0x4944, + 0x677e, 0x3257, 0x677c, 0x677a, 0x6771, 0x676f, 0x6770, 0x3c63, + 0x366c, 0x4377, 0x4651, 0x3151, 0x6774, 0x6773, 0x6779, 0x6775, + 0x6778, 0x4c50, 0x6777, 0x3258, 0x337d, 0x677b, 0x677d, 0x3754, + 0x6823, 0x682c, 0x682d, 0x302b, 0x6834, 0x3071, 0x682b, 0x682a, + 0x6825, 0x6824, 0x6822, 0x6821, 0x4363, 0x427b, 0x6827, 0x6826, + 0x6829, 0x4170, 0x3755, 0x3141, 0x6828, 0x3953, 0x4171, 0x683a, + 0x683b, 0x3259, 0x322e, 0x6838, 0x682e, 0x6836, 0x683d, 0x6837, + 0x6835, 0x6776, 0x6833, 0x682f, 0x3450, 0x6831, 0x683c, 0x6832, + 0x683e, 0x6830, 0x477c, 0x4d69, 0x6839, 0x684f, 0x6847, 0x3f7b, + 0x3546, 0x365d, 0x6842, 0x325b, 0x3e54, 0x6845, 0x3a5a, 0x4551, + 0x684a, 0x4a6e, 0x6841, 0x325a, 0x3856, 0x4929, 0x684b, 0x683f, + 0x6848, 0x6852, 0x6843, 0x6844, 0x463a, 0x6849, 0x6846, 0x4b28, + 0x684c, 0x3060, 0x6840, 0x684e, 0x684d, 0x476b, 0x6854, 0x685f, + 0x337e, 0x6862, 0x6850, 0x6855, 0x4d6e, 0x685e, 0x4d55, 0x4e2a, + 0x4378, 0x336b, 0x4972, 0x6864, 0x4621, 0x3031, 0x685d, 0x6859, + 0x4172, 0x6853, 0x685b, 0x6860, 0x472c, 0x302a, 0x6858, 0x6861, + 0x4978, 0x685c, 0x6857, 0x3e55, 0x3d2f, 0x3c2c, 0x4c58, 0x4947, + 0x6867, 0x6870, 0x685a, 0x3377, 0x3e78, 0x6865, 0x686a, 0x4173, + 0x6866, 0x686d, 0x435f, 0x686e, 0x4d56, 0x6863, 0x3338, 0x6869, + 0x686c, 0x4c2c, 0x686f, 0x6868, 0x686b, 0x4b29, 0x4f21, 0x6873, + 0x687a, 0x6872, 0x3c43, 0x6851, 0x4a4e, 0x4c22, 0x6879, 0x6878, + 0x6874, 0x6875, 0x3136, 0x6877, 0x6871, 0x4455, 0x6876, 0x307e, + 0x4222, 0x4a43, 0x687b, 0x6921, 0x4859, 0x687e, 0x3e56, 0x3c49, + 0x6923, 0x363e, 0x6924, 0x4979, 0x687d, 0x6856, 0x687c, 0x4f4f, + 0x4622, 0x4973, 0x692b, 0x6931, 0x6932, 0x6925, 0x4776, 0x692f, + 0x6927, 0x6929, 0x6933, 0x6928, 0x692c, 0x3172, 0x4665, 0x692d, + 0x6930, 0x6926, 0x4126, 0x692a, 0x3b27, 0x3f45, 0x3730, 0x4c74, + 0x4c79, 0x3d72, 0x6937, 0x6935, 0x4f4e, 0x6934, 0x4d75, 0x6936, + 0x6938, 0x6939, 0x693c, 0x693a, 0x4623, 0x693b, 0x484d, 0x692e, + 0x3d73, 0x693d, 0x6942, 0x4174, 0x6941, 0x6922, 0x6943, 0x4149, + 0x693e, 0x6940, 0x693f, 0x5d31, 0x5d22, 0x6945, 0x6944, 0x4d76, + 0x623c, 0x6946, 0x6947, 0x6948, 0x3857, 0x3554, 0x694a, 0x515d, + 0x3575, 0x4e3a, 0x3673, 0x694b, 0x694c, 0x436e, 0x694d, 0x467a, + 0x303a, 0x3263, 0x6952, 0x6953, 0x694e, 0x3b3d, 0x694f, 0x4742, + 0x6950, 0x6951, 0x695b, 0x6955, 0x6958, 0x6954, 0x6956, 0x6957, + 0x3c58, 0x6959, 0x4341, 0x3756, 0x3342, 0x695c, 0x333f, 0x6961, + 0x695d, 0x6960, 0x483a, 0x695e, 0x695f, 0x4948, 0x485a, 0x6962, + 0x427d, 0x696c, 0x6968, 0x326b, 0x6966, 0x4b2a, 0x6967, 0x6964, + 0x6965, 0x696a, 0x696d, 0x696b, 0x6969, 0x6963, 0x4358, 0x6974, + 0x4c2a, 0x6972, 0x6973, 0x696e, 0x6970, 0x6971, 0x696f, 0x4066, + 0x4f39, 0x6978, 0x6979, 0x6a21, 0x3f2a, 0x697b, 0x697e, 0x6976, + 0x6975, 0x6a22, 0x325c, 0x697c, 0x6a23, 0x697d, 0x697a, 0x4433, + 0x6977, 0x4768, 0x6a27, 0x4d3b, 0x6a26, 0x6a25, 0x6a2e, 0x6a28, + 0x6a30, 0x4d66, 0x6a33, 0x6a2a, 0x6a2b, 0x6a2f, 0x6a32, 0x6a31, + 0x6a29, 0x6a2c, 0x6a3d, 0x6a36, 0x6a34, 0x6a35, 0x6a3a, 0x6a3b, + 0x332a, 0x3542, 0x6a39, 0x6a24, 0x6a38, 0x6a3c, 0x6a37, 0x6a3e, + 0x6a40, 0x6a3f, 0x6a42, 0x6a41, 0x695a, 0x6a46, 0x6a43, 0x6a44, + 0x6a45, 0x6a47, 0x376c, 0x6a49, 0x6a48, 0x3d30, 0x3954, 0x5e27, + 0x6a4a, 0x3d51, 0x3339, 0x6a4b, 0x3152, 0x3e57, 0x6a4c, 0x3955, + 0x6a4d, 0x3061, 0x493d, 0x6a4e, 0x3f6a, 0x6a55, 0x6a52, 0x436f, + 0x6a53, 0x6a50, 0x365e, 0x6a4f, 0x6a56, 0x3736, 0x425e, 0x6a5c, + 0x6a58, 0x4235, 0x6a57, 0x6a5a, 0x6a51, 0x6a5b, 0x6a5d, 0x486f, + 0x6a59, 0x6a5e, 0x6a60, 0x3853, 0x6a54, 0x3041, 0x6a5f, 0x3a5b, + 0x4e76, 0x6a61, 0x6a62, 0x4175, 0x4e22, 0x6a63, 0x4d35, 0x6a64, + 0x6a65, 0x4a64, 0x6a66, 0x3a40, 0x4e23, 0x6a6b, 0x6a6c, 0x3e58, + 0x6a6a, 0x4d67, 0x6a67, 0x6a69, 0x403d, 0x3f7e, 0x6a68, 0x6a6d, + 0x4a23, 0x6a6f, 0x6a6e, 0x336c, 0x4b2b, 0x6a70, 0x6a7c, 0x6a72, + 0x6a73, 0x6a74, 0x6a75, 0x6a79, 0x6a7a, 0x6a78, 0x6a76, 0x6a71, + 0x6a77, 0x6a7b, 0x7037, 0x3228, 0x6a7e, 0x365f, 0x6a7d, 0x6b22, + 0x6b21, 0x6b24, 0x6b23, 0x6b25, 0x3d31, 0x6b26, 0x6b27, 0x6b28, + 0x403e, 0x4d57, 0x6b29, 0x4a24, 0x4746, 0x6b2a, 0x6b2b, 0x382b, + 0x352c, 0x6b2c, 0x3b6b, 0x4741, 0x6b2d, 0x3350, 0x6b2e, 0x6b30, + 0x4d77, 0x6b2f, 0x3f46, 0x6b31, 0x6b32, 0x6b33, 0x3451, 0x6b34, + 0x6b35, 0x6b36, 0x6b37, 0x3351, 0x6b38, 0x6b39, 0x6b3a, 0x3272, + 0x3f28, 0x6b3b, 0x6b3c, 0x6b3d, 0x3840, 0x447b, 0x6b3e, 0x3757, + 0x3f56, 0x6b41, 0x4624, 0x6b40, 0x3731, 0x6b3f, 0x4277, 0x352d, + 0x6b42, 0x6b43, 0x3e59, 0x376d, 0x6b44, 0x4b2c, 0x405f, 0x3576, + 0x4c75, 0x414a, 0x6b45, 0x3f47, 0x4370, 0x3e5a, 0x6b46, 0x6b49, + 0x6b4a, 0x3a3e, 0x4242, 0x6b48, 0x3e5b, 0x493e, 0x6b47, 0x3b6c, + 0x3153, 0x6b4e, 0x3758, 0x3b6e, 0x3b6d, 0x4f4d, 0x6b4d, 0x6b4c, + 0x4127, 0x354d, 0x4f43, 0x333a, 0x3e5c, 0x6b4b, 0x6b50, 0x6b51, + 0x6b4f, 0x3858, 0x4d40, 0x3b6f, 0x4727, 0x6b54, 0x4040, 0x4342, + 0x4d36, 0x6b57, 0x386c, 0x403f, 0x6b53, 0x6b58, 0x386d, 0x6b55, + 0x6b56, 0x6b52, 0x4062, 0x4649, 0x432f, 0x325d, 0x4870, 0x3543, + 0x4434, 0x6b5b, 0x6b59, 0x434c, 0x4041, 0x3452, 0x6b5a, 0x3f5b, + 0x4e4a, 0x4f40, 0x6b5c, 0x6b67, 0x4435, 0x6b66, 0x6b63, 0x6b6b, + 0x6b64, 0x6b60, 0x447c, 0x6b5f, 0x6b5d, 0x4d21, 0x3b70, 0x6b61, + 0x6b5e, 0x6b65, 0x3d74, 0x3841, 0x427a, 0x4b45, 0x315a, 0x3062, + 0x4625, 0x6b69, 0x6b68, 0x4666, 0x6b6d, 0x6b62, 0x6b6c, 0x6b6e, + 0x382c, 0x6b6a, 0x3956, 0x3c55, 0x6b6f, 0x4d58, 0x6b72, 0x6b75, + 0x6b73, 0x4935, 0x6b70, 0x3660, 0x6b74, 0x6b76, 0x6b7a, 0x6b77, + 0x6b79, 0x6b78, 0x6b7b, 0x3c31, 0x6b7d, 0x6b7c, 0x4968, 0x6c21, + 0x3759, 0x6b7e, 0x6c22, 0x6c23, 0x3544, 0x6641, 0x3e79, 0x6c24, + 0x386e, 0x6c25, 0x6c26, 0x3b3e, 0x5a4e, 0x6c27, 0x6c28, 0x3d32, + 0x6c29, 0x6c2a, 0x6c2b, 0x6c2c, 0x6c2d, 0x432b, 0x6c2e, 0x6c30, + 0x6c2f, 0x4626, 0x6c31, 0x4b2d, 0x6c32, 0x6c33, 0x6c34, 0x6c35, + 0x465a, 0x3e5d, 0x6c36, 0x396b, 0x502e, 0x6c37, 0x6c38, 0x493f, + 0x6c39, 0x6c41, 0x6c3a, 0x6c3c, 0x6c3b, 0x6c3d, 0x4b46, 0x6c3e, + 0x6c3f, 0x6c40, 0x6c42, 0x332d, 0x4467, 0x4969, 0x3a62, 0x3957, + 0x494f, 0x325f, 0x484e, 0x6c45, 0x3453, 0x4055, 0x6c44, 0x6c49, + 0x4379, 0x4c63, 0x6c47, 0x6c48, 0x352e, 0x6c4a, 0x4763, 0x425f, + 0x4871, 0x453d, 0x6c46, 0x4b47, 0x326c, 0x6c4c, 0x4f28, 0x4442, + 0x4f45, 0x3b71, 0x6c4b, 0x4231, 0x6c5c, 0x4128, 0x4678, 0x4950, + 0x6c4f, 0x3b3f, 0x3b72, 0x3e5e, 0x4765, 0x382d, 0x6c4e, 0x6c4d, + 0x496a, 0x3c41, 0x4552, 0x6c51, 0x6c52, 0x3958, 0x6c50, 0x6c53, + 0x6c54, 0x6c56, 0x4223, 0x6c55, 0x3466, 0x6c58, 0x6c57, 0x6c59, + 0x6c5b, 0x6c5d, 0x6c5e, 0x4056, 0x3c4f, 0x6c5f, 0x3352, 0x6c60, + 0x4176, 0x6c61, 0x6c62, 0x496b, 0x352f, 0x6c63, 0x4436, 0x315b, + 0x6c64, 0x3c71, 0x3f76, 0x422d, 0x6c67, 0x6c66, 0x6c65, 0x6c6d, + 0x6c6b, 0x6c68, 0x6c6a, 0x6c69, 0x6c6c, 0x3577, 0x6c70, 0x4057, + 0x6c71, 0x3859, 0x6c6e, 0x6c6f, 0x4f29, 0x4437, 0x4129, 0x6c72, + 0x6c75, 0x6c73, 0x6c74, 0x4d59, 0x4627, 0x6c78, 0x6c76, 0x6c77, + 0x6c79, 0x6d29, 0x6c7c, 0x6c7d, 0x6c7b, 0x6c7a, 0x447d, 0x6d21, + 0x6d25, 0x6d22, 0x6c7e, 0x6d23, 0x6d24, 0x6d2b, 0x6d26, 0x4058, + 0x6d28, 0x6d2a, 0x6d27, 0x6d2d, 0x3d33, 0x6d2c, 0x6d2e, 0x6d2f, + 0x6d32, 0x6d31, 0x6d30, 0x6d34, 0x6d33, 0x4c76, 0x6d36, 0x6d35, + 0x6d37, 0x6d38, 0x6d3a, 0x6d39, 0x3f48, 0x6d3b, 0x366d, 0x6d3c, + 0x6d3e, 0x6d3f, 0x6d40, 0x6d3d, 0x6d41, 0x3c56, 0x6d42, 0x3530, + 0x3733, 0x382e, 0x6d43, 0x4670, 0x453e, 0x6d44, 0x6d47, 0x3c34, + 0x6d46, 0x6d45, 0x375a, 0x6d48, 0x3353, 0x6d4a, 0x3a5c, 0x6d49, + 0x6d52, 0x6d4c, 0x6d4e, 0x4a65, 0x6d4b, 0x6d4d, 0x6d51, 0x6d4f, + 0x3531, 0x6d50, 0x6d53, 0x475a, 0x4e58, 0x3d34, 0x6d54, 0x4d22, + 0x6d56, 0x6d55, 0x6d59, 0x4d41, 0x6d58, 0x336d, 0x6d57, 0x6d5c, + 0x6d5b, 0x6d5a, 0x4532, 0x6d5d, 0x6d5e, 0x6d5f, 0x396c, 0x3725, + 0x6d60, 0x6d61, 0x6d62, 0x3f49, 0x6d63, 0x3c2d, 0x6d64, 0x6d65, + 0x5221, 0x517e, 0x6d66, 0x6570, 0x6d67, 0x4324, 0x3f2b, 0x4740, + 0x6d68, 0x4a55, 0x4454, 0x397e, 0x4329, 0x312a, 0x4b78, 0x3f57, + 0x375e, 0x3661, 0x4a56, 0x6d69, 0x6d6b, 0x6d6a, 0x3260, 0x4676, + 0x6d6c, 0x4777, 0x4533, 0x6d6d, 0x3d52, 0x6d6f, 0x4c42, 0x6d7e, + 0x6d71, 0x6d72, 0x4449, 0x4260, 0x4177, 0x4628, 0x6d70, 0x3555, + 0x6d79, 0x6d76, 0x6e25, 0x4629, 0x4360, 0x6d73, 0x447e, 0x4553, + 0x6d74, 0x6d78, 0x3f60, 0x4767, 0x444c, 0x4042, 0x6d77, 0x422e, + 0x4224, 0x6d75, 0x3029, 0x4f22, 0x6d7a, 0x4261, 0x3d35, 0x3f4a, + 0x6d7c, 0x6d7b, 0x306f, 0x6d7d, 0x492f, 0x6e27, 0x465b, 0x3f6b, + 0x4359, 0x3678, 0x6e26, 0x4d37, 0x313f, 0x4a57, 0x3261, 0x6e21, + 0x6e22, 0x6e23, 0x6e24, 0x463b, 0x4323, 0x3063, 0x6e28, 0x6e29, + 0x7423, 0x423d, 0x6e2a, 0x3173, 0x414c, 0x382f, 0x4d5a, 0x6e2b, + 0x452c, 0x4178, 0x3c57, 0x6e2c, 0x6e2f, 0x3d65, 0x6e2d, 0x412b, + 0x412a, 0x3064, 0x4e4b, 0x6e31, 0x4872, 0x6e33, 0x6e32, 0x6e30, + 0x6364, 0x3454, 0x6d6e, 0x6e35, 0x6e34, 0x6e36, 0x4d38, 0x4661, + 0x4b2e, 0x6e37, 0x3c59, 0x6e38, 0x6e39, 0x6e3a, 0x4521, 0x306a, + 0x3959, 0x4f3a, 0x6e3e, 0x3734, 0x6e3b, 0x6e3c, 0x4974, 0x3354, + 0x4d39, 0x363f, 0x4554, 0x6e3f, 0x6e40, 0x6e41, 0x4522, 0x6e43, + 0x6e42, 0x4653, 0x6e44, 0x3d36, 0x3c60, 0x475b, 0x4371, 0x3c72, + 0x3f6c, 0x6e45, 0x6e46, 0x3f5d, 0x6e47, 0x6e48, 0x6e49, 0x4d6f, + 0x3d37, 0x6e4b, 0x6e4a, 0x395a, 0x3973, 0x3b40, 0x6e4e, 0x3d66, + 0x6e4d, 0x6e4c, 0x4269, 0x386f, 0x4043, 0x4830, 0x3d39, 0x6e4f, + 0x3e5f, 0x6e52, 0x6e50, 0x6e51, 0x6e54, 0x6e53, 0x3e7a, 0x6e55, + 0x6e56, 0x6e57, 0x4850, 0x3a53, 0x3c61, 0x6e58, 0x6e59, 0x4e24, + 0x3d45, 0x4c6e, 0x4e4c, 0x6e5a, 0x3662, 0x6e5b, 0x4523, 0x6e5e, + 0x3378, 0x3f4b, 0x6e5c, 0x6e5d, 0x4460, 0x4b55, 0x367c, 0x6e60, + 0x6e61, 0x6e5f, 0x6e63, 0x465f, 0x3343, 0x6e67, 0x6e64, 0x6e66, + 0x6e62, 0x6f4f, 0x6e65, 0x4e6b, 0x385a, 0x6e6f, 0x4534, 0x6e6a, + 0x6e6d, 0x6e6b, 0x6e70, 0x6e71, 0x6e69, 0x6e76, 0x3174, 0x6e68, + 0x482d, 0x6e6c, 0x3e60, 0x395b, 0x4b48, 0x3664, 0x3d46, 0x463c, + 0x412d, 0x6e74, 0x6e6e, 0x6e73, 0x4c43, 0x4438, 0x6e75, 0x6e72, + 0x412c, 0x6e79, 0x6e78, 0x6e77, 0x4b2f, 0x3d7b, 0x6e7a, 0x4a5f, + 0x3154, 0x4946, 0x4372, 0x3578, 0x6e7c, 0x395d, 0x3b2c, 0x6e7b, + 0x3f6d, 0x3f6e, 0x6f21, 0x6f23, 0x3e7b, 0x6f22, 0x6f24, 0x3653, + 0x4945, 0x3c62, 0x4f23, 0x6e7e, 0x3a78, 0x4f3f, 0x6f26, 0x6f25, + 0x6f27, 0x6e7d, 0x4669, 0x4555, 0x4457, 0x6f2c, 0x4343, 0x6f28, + 0x6f29, 0x372d, 0x6f2b, 0x3830, 0x6f2a, 0x3e61, 0x3379, 0x6f30, + 0x3a3f, 0x4179, 0x444a, 0x333b, 0x6f2e, 0x6f2f, 0x4443, 0x6f2d, + 0x6f31, 0x6f37, 0x6f3a, 0x6f39, 0x452d, 0x6f32, 0x6f33, 0x6f36, + 0x6f38, 0x3640, 0x6f3b, 0x6f35, 0x6f34, 0x6f3f, 0x6f40, 0x6f41, + 0x6f3e, 0x6f3d, 0x3e62, 0x462a, 0x6f3c, 0x6f45, 0x6f43, 0x6f44, + 0x6f42, 0x4278, 0x6f46, 0x6f47, 0x6f49, 0x3455, 0x6f48, 0x4c7a, + 0x6f54, 0x6f4a, 0x6f4d, 0x6f4b, 0x6f4c, 0x6f4e, 0x6f50, 0x6f51, + 0x6f52, 0x6f55, 0x6f53, 0x6f56, 0x6f58, 0x6f57, 0x4439, 0x4c67, + 0x6f59, 0x412e, 0x6f5a, 0x4a44, 0x6f5b, 0x332b, 0x313c, 0x3457, + 0x3456, 0x6f5c, 0x6f5d, 0x6f5e, 0x6f5f, 0x6f60, 0x3458, 0x3355, + 0x395e, 0x4836, 0x6f62, 0x6f61, 0x6f63, 0x315c, 0x6f66, 0x6f65, + 0x6f64, 0x6f67, 0x6f6a, 0x3047, 0x6f68, 0x6f6c, 0x6f6b, 0x6f6e, + 0x6f6d, 0x6f6f, 0x462e, 0x6f70, 0x6f71, 0x6f73, 0x6f72, 0x496c, + 0x6f74, 0x6f75, 0x3a65, 0x6f76, 0x6f77, 0x4b49, 0x414b, 0x3024, + 0x424b, 0x6f78, 0x496d, 0x6f7b, 0x6f79, 0x395f, 0x6f7a, 0x3842, + 0x4a45, 0x6f7d, 0x7021, 0x6f7e, 0x7022, 0x3121, 0x3f58, 0x3d7c, + 0x3459, 0x7023, 0x4766, 0x7025, 0x3122, 0x7024, 0x4444, 0x4e4d, + 0x462b, 0x6f7c, 0x4e26, 0x3831, 0x4d5b, 0x3679, 0x4e34, 0x3728, + 0x4262, 0x6721, 0x7026, 0x332c, 0x3f6f, 0x3356, 0x7028, 0x7029, + 0x7027, 0x3764, 0x3a5d, 0x3e63, 0x3123, 0x4e59, 0x702b, 0x6e2e, + 0x702a, 0x702e, 0x702c, 0x702d, 0x702f, 0x7030, 0x4e6c, 0x7031, + 0x7032, 0x4049, 0x483b, 0x3f7d, 0x3467, 0x4d3a, 0x326d, 0x3d38, + 0x385b, 0x7035, 0x7034, 0x3b73, 0x7036, 0x7033, 0x3b28, 0x703a, + 0x6a2d, 0x5256, 0x3f77, 0x7038, 0x4e25, 0x4671, 0x312b, 0x4063, + 0x3c36, 0x4a37, 0x3140, 0x4e6d, 0x4d6b, 0x703b, 0x4545, 0x3c7b, + 0x703c, 0x703d, 0x3f4c, 0x703e, 0x4e6e, 0x7039, 0x7040, 0x7042, + 0x7041, 0x703f, 0x7043, 0x7044, 0x417a, 0x3262, 0x7045, 0x4c38, + 0x7046, 0x7047, 0x4f2a, 0x5b31, 0x7048, 0x7049, 0x704a, 0x704e, + 0x704b, 0x704c, 0x704d, 0x704f, 0x4044, 0x4c77, 0x4045, 0x7050, + 0x4873, 0x7051, 0x7353, 0x4c4c, 0x7052, 0x7053, 0x7054, 0x3357, + 0x7056, 0x3f59, 0x7057, 0x3724, 0x7058, 0x705c, 0x705a, 0x705b, + 0x3373, 0x7059, 0x705d, 0x705e, 0x3048, 0x705f, 0x7060, 0x3e64, + 0x7061, 0x3547, 0x7064, 0x7063, 0x7062, 0x6b71, 0x4a5c, 0x7065, + 0x7066, 0x7067, 0x7068, 0x7069, 0x706a, 0x345a, 0x706b, 0x706c, + 0x4723, 0x706e, 0x323b, 0x7071, 0x7070, 0x3124, 0x3641, 0x4a47, + 0x443a, 0x3a22, 0x3960, 0x3d67, 0x3f5c, 0x7073, 0x7072, 0x4d42, + 0x3468, 0x4852, 0x465c, 0x3f7c, 0x4e4e, 0x375b, 0x7076, 0x7075, + 0x4b4b, 0x462c, 0x3150, 0x7077, 0x7074, 0x4951, 0x4d6a, 0x7078, + 0x7079, 0x707b, 0x426a, 0x335b, 0x335c, 0x707a, 0x3469, 0x3832, + 0x346a, 0x453f, 0x4e60, 0x385c, 0x707c, 0x707d, 0x707e, 0x7121, + 0x7123, 0x7122, 0x4977, 0x7124, 0x7125, 0x7126, 0x7127, 0x7129, + 0x7128, 0x712a, 0x4874, 0x664c, 0x3f29, 0x3532, 0x712b, 0x712c, + 0x522c, 0x5d3b, 0x4853, 0x307b, 0x303b, 0x3b74, 0x4b30, 0x3e7e, + 0x712d, 0x4c5f, 0x712e, 0x4d5c, 0x3142, 0x3b41, 0x712f, 0x326e, + 0x7130, 0x7131, 0x7133, 0x7134, 0x7136, 0x7132, 0x7135, 0x345b, + 0x7137, 0x7138, 0x7139, 0x713a, 0x713b, 0x713d, 0x713c, 0x713f, + 0x7142, 0x713e, 0x7140, 0x7141, 0x7143, 0x3642, 0x3c73, 0x7144, + 0x7145, 0x3961, 0x7146, 0x333e, 0x474f, 0x7147, 0x7148, 0x435a, + 0x466b, 0x7149, 0x477d, 0x424c, 0x3158, 0x366e, 0x366f, 0x4373, + 0x714e, 0x3670, 0x326f, 0x714d, 0x714b, 0x714c, 0x714a, 0x7158, + 0x714f, 0x7150, 0x7151, 0x7152, 0x7154, 0x7153, 0x3d59, 0x7155, + 0x7157, 0x3533, 0x7156, 0x417b, 0x3833, 0x7159, 0x424d, 0x715a, + 0x462d, 0x715b, 0x7160, 0x715e, 0x715d, 0x715f, 0x715c, 0x7162, + 0x7161, 0x7164, 0x3643, 0x7163, 0x7165, 0x7166, 0x7168, 0x7167, + 0x7169, 0x716b, 0x716a, 0x397c, 0x716c, 0x716d, 0x333c, 0x716e, + 0x716f, 0x3f71, 0x7170, 0x7171, 0x7172, 0x7173, 0x3962, 0x7174, + 0x7175, 0x7176, 0x7177, 0x7178, 0x4831, 0x717a, 0x4926, 0x717b, + 0x7179, 0x717d, 0x717c, 0x717e, 0x7221, 0x7222, 0x7223, 0x7224, + 0x7225, 0x7226, 0x7227, 0x7228, 0x7229, 0x722a, 0x722b, 0x722c, + 0x722d, 0x722e, 0x5d35, 0x722f, 0x6478, 0x3534, 0x3321, 0x3a32, + 0x7231, 0x7230, 0x4c25, 0x7233, 0x7234, 0x7232, 0x7235, 0x4b62, + 0x7236, 0x357b, 0x4f25, 0x7237, 0x7239, 0x303e, 0x723a, 0x4a2b, + 0x7238, 0x723b, 0x723c, 0x723d, 0x723e, 0x723f, 0x4b6e, 0x3b2d, + 0x3a7a, 0x412f, 0x7240, 0x7243, 0x7241, 0x7244, 0x3871, 0x7242, + 0x7245, 0x7246, 0x7247, 0x724b, 0x3b2a, 0x4264, 0x724c, 0x7249, + 0x7248, 0x724a, 0x375f, 0x7250, 0x724f, 0x724e, 0x3033, 0x725a, + 0x7256, 0x7257, 0x7253, 0x7259, 0x7255, 0x3362, 0x4f4c, 0x7258, + 0x7254, 0x7252, 0x7251, 0x725c, 0x725f, 0x725e, 0x725d, 0x4949, + 0x725b, 0x3073, 0x7260, 0x7262, 0x336f, 0x724d, 0x3137, 0x7264, + 0x7263, 0x7261, 0x432d, 0x4b70, 0x4e5a, 0x7265, 0x7266, 0x7267, + 0x7268, 0x7269, 0x443b, 0x726a, 0x4837, 0x726f, 0x726b, 0x726c, + 0x4b31, 0x4c44, 0x4650, 0x7270, 0x7271, 0x463e, 0x726e, 0x726d, + 0x322a, 0x7279, 0x7278, 0x3175, 0x7276, 0x7275, 0x7273, 0x337b, + 0x7272, 0x3c32, 0x3229, 0x3963, 0x727c, 0x727b, 0x727a, 0x7277, + 0x727d, 0x727e, 0x7325, 0x7324, 0x7326, 0x312d, 0x7321, 0x7322, + 0x3974, 0x4c39, 0x7323, 0x4b32, 0x732b, 0x7327, 0x732c, 0x7329, + 0x7328, 0x375c, 0x732d, 0x732e, 0x732f, 0x732a, 0x7274, 0x7330, + 0x4461, 0x7334, 0x7335, 0x7333, 0x7332, 0x7338, 0x7331, 0x7336, + 0x7337, 0x733a, 0x7339, 0x733c, 0x733d, 0x733e, 0x4f49, 0x733b, + 0x426b, 0x3a6d, 0x733f, 0x7340, 0x7341, 0x7342, 0x7343, 0x3834, + 0x7344, 0x7345, 0x3c2f, 0x7346, 0x7347, 0x7348, 0x7349, 0x734c, + 0x734a, 0x4f3c, 0x734b, 0x4e6f, 0x734d, 0x4e5b, 0x734e, 0x477e, + 0x734f, 0x7351, 0x7352, 0x7350, 0x396d, 0x4c4d, 0x4b63, 0x5677, + 0x5d60, 0x4b7b, 0x322b, 0x7354, 0x3550, 0x7355, 0x7356, 0x7357, + 0x3975, 0x7358, 0x6054, 0x4c5b, 0x4263, 0x7359, 0x735b, 0x735a, + 0x735c, 0x735d, 0x735e, 0x735f, 0x7360, 0x7361, 0x7362, 0x7363, + 0x7364, 0x7365, 0x7366, 0x7367, 0x7368, 0x4524, 0x385d, 0x736a, + 0x414d, 0x736b, 0x736c, 0x4921, 0x736d, 0x736e, 0x6337, 0x6c5a, + 0x706d, 0x736f, 0x7370, 0x7372, 0x7373, 0x7374, 0x4e70, 0x7371, + 0x7375, 0x7376, 0x7378, 0x7377, 0x737a, 0x737b, 0x7379, 0x4e36, + 0x737c, 0x737d, 0x6354, 0x737e, 0x212a, 0x2174, 0x2170, 0x2173, + 0x2175, 0x214a, 0x214b, 0x2176, 0x215c, 0x2124, 0x2125, 0x213f, + 0x2330, 0x2331, 0x2332, 0x2333, 0x2334, 0x2335, 0x2336, 0x2337, + 0x2338, 0x2339, 0x2127, 0x2128, 0x2163, 0x2161, 0x2164, 0x2129, + 0x2177, 0x2341, 0x2342, 0x2343, 0x2344, 0x2345, 0x2346, 0x2347, + 0x2348, 0x2349, 0x234a, 0x234b, 0x234c, 0x234d, 0x234e, 0x234f, + 0x2350, 0x2351, 0x2352, 0x2353, 0x2354, 0x2355, 0x2356, 0x2357, + 0x2358, 0x2359, 0x235a, 0x214e, 0x214f, 0x2130, 0x2132, 0x212e, + 0x2361, 0x2362, 0x2363, 0x2364, 0x2365, 0x2366, 0x2367, 0x2368, + 0x2369, 0x236a, 0x236b, 0x236c, 0x236d, 0x236e, 0x236f, 0x2370, + 0x2371, 0x2372, 0x2373, 0x2374, 0x2375, 0x2376, 0x2377, 0x2378, + 0x2379, 0x237a, 0x2150, 0x2143, 0x2151, 0x2131, 0x216f, +}; + +static const Summary16 jisx0208_uni2indx_page00[16] = { + /* 0x0000 */ + { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, + { 0, 0x0000 }, { 0, 0x1000 }, { 1, 0x0000 }, { 1, 0x0000 }, + { 1, 0x0000 }, { 1, 0x0000 }, { 1, 0x118c }, { 6, 0x0053 }, + { 10, 0x0000 }, { 10, 0x0080 }, { 11, 0x0000 }, { 11, 0x0080 }, +}; +static const Summary16 jisx0208_uni2indx_page03[22] = { + /* 0x0300 */ + { 12, 0x0000 }, { 12, 0x0000 }, { 12, 0x0000 }, { 12, 0x0000 }, + { 12, 0x0000 }, { 12, 0x0000 }, { 12, 0x0000 }, { 12, 0x0000 }, + { 12, 0x0000 }, { 12, 0xfffe }, { 27, 0x03fb }, { 36, 0xfffe }, + { 51, 0x03fb }, { 60, 0x0000 }, { 60, 0x0000 }, { 60, 0x0000 }, + /* 0x0400 */ + { 60, 0x0002 }, { 61, 0xffff }, { 77, 0xffff }, { 93, 0xffff }, + { 109, 0xffff }, { 125, 0x0002 }, +}; +static const Summary16 jisx0208_uni2indx_page20[50] = { + /* 0x2000 */ + { 126, 0x0000 }, { 126, 0x3361 }, { 133, 0x0063 }, { 137, 0x080d }, + { 141, 0x0000 }, { 141, 0x0000 }, { 141, 0x0000 }, { 141, 0x0000 }, + { 141, 0x0000 }, { 141, 0x0000 }, { 141, 0x0000 }, { 141, 0x0000 }, + { 141, 0x0000 }, { 141, 0x0000 }, { 141, 0x0000 }, { 141, 0x0000 }, + /* 0x2100 */ + { 141, 0x0008 }, { 142, 0x0000 }, { 142, 0x0800 }, { 143, 0x0000 }, + { 143, 0x0000 }, { 143, 0x0000 }, { 143, 0x0000 }, { 143, 0x0000 }, + { 143, 0x0000 }, { 143, 0x000f }, { 147, 0x0000 }, { 147, 0x0000 }, + { 147, 0x0000 }, { 147, 0x0014 }, { 149, 0x0000 }, { 149, 0x0000 }, + /* 0x2200 */ + { 149, 0x098d }, { 155, 0x6404 }, { 159, 0x1f81 }, { 166, 0x2030 }, + { 169, 0x0000 }, { 169, 0x0004 }, { 170, 0x0cc3 }, { 176, 0x0000 }, + { 176, 0x00cc }, { 180, 0x0000 }, { 180, 0x0020 }, { 181, 0x0000 }, + { 181, 0x0000 }, { 181, 0x0000 }, { 181, 0x0000 }, { 181, 0x0000 }, + /* 0x2300 */ + { 181, 0x0000 }, { 181, 0x0004 }, +}; +static const Summary16 jisx0208_uni2indx_page25[23] = { + /* 0x2500 */ + { 182, 0x900f }, { 188, 0x3999 }, { 196, 0x9939 }, { 204, 0x9999 }, + { 212, 0x0804 }, { 214, 0x0000 }, { 214, 0x0000 }, { 214, 0x0000 }, + { 214, 0x0000 }, { 214, 0x0000 }, { 214, 0x0003 }, { 216, 0x300c }, + { 220, 0xc8c0 }, { 225, 0x0000 }, { 225, 0x8000 }, { 226, 0x0000 }, + /* 0x2600 */ + { 226, 0x0060 }, { 228, 0x0000 }, { 228, 0x0000 }, { 228, 0x0000 }, + { 228, 0x0005 }, { 230, 0x0000 }, { 230, 0xa400 }, +}; +static const Summary16 jisx0208_uni2indx_page30[16] = { + /* 0x3000 */ + { 233, 0xffef }, { 248, 0x103f }, { 255, 0x0000 }, { 255, 0x0000 }, + { 255, 0xfffe }, { 270, 0xffff }, { 286, 0xffff }, { 302, 0xffff }, + { 318, 0xffff }, { 334, 0x780f }, { 342, 0xfffe }, { 357, 0xffff }, + { 373, 0xffff }, { 389, 0xffff }, { 405, 0xffff }, { 421, 0x787f }, +}; +static const Summary16 jisx0208_uni2indx_page4e[1307] = { + /* 0x4e00 */ + { 432, 0x6f8b }, { 442, 0x43f3 }, { 451, 0x2442 }, { 455, 0x9b46 }, + { 463, 0xe82c }, { 470, 0xe3e0 }, { 478, 0x0004 }, { 479, 0x400a }, + { 482, 0x5f65 }, { 492, 0xdb36 }, { 502, 0x7977 }, { 513, 0x0449 }, + { 517, 0xecd7 }, { 528, 0xe3f0 }, { 537, 0x6038 }, { 542, 0x08c5 }, + /* 0x4f00 */ + { 547, 0xe602 }, { 553, 0x3403 }, { 558, 0x8000 }, { 559, 0x3551 }, + { 566, 0xe0c8 }, { 572, 0x7eab }, { 583, 0x8200 }, { 585, 0x9869 }, + { 592, 0xa948 }, { 598, 0x2942 }, { 603, 0xe803 }, { 609, 0x8060 }, + { 612, 0x441c }, { 617, 0xad93 }, { 626, 0xc03a }, { 632, 0x4568 }, + /* 0x5000 */ + { 638, 0xaa60 }, { 644, 0x8656 }, { 651, 0x3f7a }, { 662, 0x0240 }, + { 664, 0x8388 }, { 669, 0x1461 }, { 674, 0x1020 }, { 676, 0x2174 }, + { 682, 0x2021 }, { 685, 0x0702 }, { 689, 0x3000 }, { 691, 0x40bc }, + { 697, 0xa624 }, { 703, 0x4462 }, { 708, 0x60a8 }, { 713, 0x0a20 }, + /* 0x5100 */ + { 716, 0x0217 }, { 721, 0x8574 }, { 728, 0x0402 }, { 730, 0x9c84 }, + { 736, 0x7bfb }, { 749, 0x1415 }, { 754, 0x7f24 }, { 763, 0x11e2 }, + { 769, 0xb665 }, { 778, 0x02ef }, { 786, 0x1f75 }, { 796, 0x20ff }, + { 805, 0x3a70 }, { 812, 0x3840 }, { 816, 0x26c3 }, { 823, 0x6763 }, + /* 0x5200 */ + { 832, 0x4dd9 }, { 841, 0x2092 }, { 845, 0x46b0 }, { 851, 0x0fc9 }, + { 859, 0xbc98 }, { 867, 0x4850 }, { 871, 0x8638 }, { 877, 0xa03f }, + { 885, 0x2388 }, { 890, 0x8816 }, { 895, 0x3e09 }, { 902, 0x5232 }, + { 908, 0x22aa }, { 914, 0xe3a4 }, { 922, 0x00dd }, { 928, 0xc72c }, + /* 0x5300 */ + { 936, 0xa166 }, { 943, 0x26e1 }, { 950, 0x840b }, { 955, 0x8f0a }, + { 962, 0x27eb }, { 972, 0x559e }, { 981, 0xc241 }, { 986, 0x89bb }, + { 995, 0x0014 }, { 997, 0x8540 }, { 1001, 0x6361 }, { 1008, 0x0849 }, + { 1012, 0x7f0c }, { 1021, 0x8ad0 }, { 1027, 0xff3e }, { 1040, 0x05cf }, + /* 0x5400 */ + { 1048, 0xff1a }, { 1059, 0xa803 }, { 1064, 0x7a41 }, { 1071, 0x7b40 }, + { 1078, 0x4745 }, { 1085, 0x8002 }, { 1087, 0x0500 }, { 1089, 0x38eb }, + { 1098, 0xd851 }, { 1105, 0x0005 }, { 1107, 0x9934 }, { 1114, 0x710c }, + { 1120, 0x0397 }, { 1127, 0x0100 }, { 1128, 0x6366 }, { 1136, 0x2404 }, + /* 0x5500 */ + { 1139, 0x80d0 }, { 1143, 0x0051 }, { 1146, 0xc000 }, { 1148, 0x430a }, + { 1153, 0x9071 }, { 1159, 0x30c8 }, { 1164, 0x0008 }, { 1165, 0x5800 }, + { 1168, 0x0e99 }, { 1175, 0xf700 }, { 1182, 0x5f80 }, { 1189, 0x0041 }, + { 1191, 0x00b0 }, { 1194, 0x9410 }, { 1198, 0x0018 }, { 1200, 0x6280 }, + /* 0x5600 */ + { 1204, 0x0240 }, { 1206, 0x09d0 }, { 1211, 0x8200 }, { 1213, 0x0156 }, + { 1218, 0x5004 }, { 1221, 0x0801 }, { 1223, 0x1d10 }, { 1228, 0x0510 }, + { 1231, 0x84c1 }, { 1236, 0x0010 }, { 1237, 0x4025 }, { 1241, 0x1050 }, + { 1244, 0x410f }, { 1250, 0x4d8a }, { 1257, 0x4009 }, { 1260, 0xa60d }, + /* 0x5700 */ + { 1267, 0xab19 }, { 1275, 0x914c }, { 1281, 0x21c0 }, { 1285, 0x0981 }, + { 1289, 0xc485 }, { 1295, 0x0003 }, { 1297, 0x0652 }, { 1302, 0x8000 }, + { 1303, 0x0b04 }, { 1307, 0x0008 }, { 1308, 0x041d }, { 1313, 0x0009 }, + { 1315, 0x4849 }, { 1320, 0x905c }, { 1326, 0x0009 }, { 1328, 0x1690 }, + /* 0x5800 */ + { 1333, 0x0c65 }, { 1339, 0x2220 }, { 1342, 0x8412 }, { 1346, 0x2433 }, + { 1352, 0x0c03 }, { 1356, 0x4796 }, { 1364, 0x0a04 }, { 1367, 0x4225 }, + { 1372, 0x0028 }, { 1374, 0x9088 }, { 1378, 0x4900 }, { 1381, 0x4f08 }, + { 1387, 0x14a2 }, { 1392, 0xd3aa }, { 1401, 0xd830 }, { 1407, 0x3e87 }, + /* 0x5900 */ + { 1416, 0x8604 }, { 1420, 0x1f61 }, { 1428, 0x7ea4 }, { 1437, 0x4186 }, + { 1442, 0xc390 }, { 1448, 0x05b3 }, { 1455, 0x57a5 }, { 1464, 0x2118 }, + { 1468, 0x241e }, { 1474, 0x2a48 }, { 1479, 0x1128 }, { 1483, 0x4a04 }, + { 1487, 0x0a40 }, { 1490, 0x161b }, { 1497, 0x0d60 }, { 1502, 0x8840 }, + /* 0x5a00 */ + { 1505, 0x020a }, { 1508, 0x9502 }, { 1513, 0x8221 }, { 1517, 0x1060 }, + { 1520, 0x0243 }, { 1524, 0x0400 }, { 1525, 0x1444 }, { 1529, 0x8000 }, + { 1530, 0x0000 }, { 1530, 0x0c04 }, { 1533, 0x0000 }, { 1533, 0x7000 }, + { 1536, 0x1a06 }, { 1541, 0x00c1 }, { 1544, 0x024a }, { 1548, 0x0c00 }, + /* 0x5b00 */ + { 1550, 0x1a00 }, { 1553, 0x0040 }, { 1554, 0x1404 }, { 1557, 0x4045 }, + { 1561, 0x0029 }, { 1564, 0xbdb3 }, { 1575, 0x0a78 }, { 1581, 0x052b }, + { 1587, 0xbba9 }, { 1597, 0xbfa0 }, { 1606, 0x407c }, { 1612, 0x8379 }, + { 1620, 0x12fc }, { 1628, 0xe81d }, { 1636, 0x4bf6 }, { 1646, 0xc569 }, + /* 0x5c00 */ + { 1654, 0xeff6 }, { 1667, 0x044a }, { 1671, 0x2115 }, { 1676, 0xff02 }, + { 1685, 0xed63 }, { 1695, 0x402b }, { 1700, 0xd033 }, { 1707, 0x0242 }, + { 1710, 0x1000 }, { 1711, 0x0013 }, { 1714, 0x1b02 }, { 1719, 0x59ca }, + { 1727, 0x00a0 }, { 1729, 0x0200 }, { 1730, 0xa703 }, { 1737, 0x2c41 }, + /* 0x5d00 */ + { 1742, 0x4880 }, { 1745, 0x8ff2 }, { 1755, 0x0204 }, { 1757, 0x0000 }, + { 1757, 0x5800 }, { 1760, 0x1005 }, { 1763, 0x9200 }, { 1766, 0x0048 }, + { 1768, 0x1894 }, { 1773, 0x2001 }, { 1775, 0x5004 }, { 1778, 0x3480 }, + { 1782, 0x3200 }, { 1785, 0x684c }, { 1791, 0x49ea }, { 1799, 0x68be }, + /* 0x5e00 */ + { 1808, 0x184c }, { 1813, 0x2e42 }, { 1819, 0xa820 }, { 1823, 0x21c9 }, + { 1829, 0x50b9 }, { 1836, 0x80b0 }, { 1840, 0x001e }, { 1844, 0xff7c }, + { 1857, 0x849a }, { 1863, 0x14e0 }, { 1868, 0x28c1 }, { 1873, 0x01e0 }, + { 1877, 0x870e }, { 1884, 0xac49 }, { 1891, 0x130f }, { 1898, 0xdddb }, + /* 0x5f00 */ + { 1910, 0xbe1a }, { 1919, 0x89fb }, { 1929, 0xa2e0 }, { 1935, 0x51a2 }, + { 1941, 0x5502 }, { 1946, 0x32ca }, { 1953, 0x3e46 }, { 1961, 0x928b }, + { 1968, 0x1dbf }, { 1979, 0x438f }, { 1987, 0x6703 }, { 1994, 0x3218 }, + { 1999, 0x3028 }, { 2003, 0x33c0 }, { 2009, 0x0811 }, { 2012, 0xa923 }, + /* 0x6000 */ + { 2019, 0xc000 }, { 2021, 0x3a65 }, { 2029, 0x8fe3 }, { 2039, 0x0402 }, + { 2041, 0x2c4e }, { 2048, 0x8625 }, { 2054, 0xbf3d }, { 2066, 0x00a1 }, + { 2069, 0x3a1a }, { 2076, 0x8cd4 }, { 2083, 0x06c9 }, { 2089, 0x317c }, + { 2097, 0x00e0 }, { 2100, 0x950a }, { 2106, 0x018b }, { 2111, 0x0edb }, + /* 0x6100 */ + { 2120, 0xe34b }, { 2129, 0x8c20 }, { 2133, 0x1182 }, { 2137, 0xf010 }, + { 2142, 0x7d94 }, { 2151, 0xa728 }, { 2158, 0xc9ac }, { 2166, 0x40fb }, + { 2174, 0x4484 }, { 2178, 0x0653 }, { 2184, 0x5a90 }, { 2190, 0x4444 }, + { 2194, 0x3fc8 }, { 2203, 0x0001 }, { 2204, 0x0048 }, { 2206, 0xf5d4 }, + /* 0x6200 */ + { 2216, 0x7701 }, { 2223, 0xec57 }, { 2233, 0xc442 }, { 2238, 0x891d }, + { 2245, 0x6b83 }, { 2253, 0x4928 }, { 2258, 0x4109 }, { 2262, 0xd242 }, + { 2268, 0x061d }, { 2274, 0x59fe }, { 2285, 0x1800 }, { 2287, 0x3a22 }, + { 2293, 0xb7e4 }, { 2303, 0x3b9f }, { 2314, 0xf003 }, { 2320, 0xc0ea }, + /* 0x6300 */ + { 2327, 0x1386 }, { 2333, 0x8202 }, { 2336, 0x8980 }, { 2340, 0xe400 }, + { 2344, 0xb200 }, { 2348, 0x10a1 }, { 2352, 0x4b80 }, { 2357, 0x0cc4 }, + { 2362, 0xd309 }, { 2369, 0x8944 }, { 2374, 0x1faf }, { 2385, 0x4834 }, + { 2390, 0x8259 }, { 2396, 0x0c45 }, { 2401, 0x420a }, { 2405, 0x0450 }, + /* 0x6400 */ + { 2408, 0xa040 }, { 2411, 0x10c8 }, { 2415, 0x3140 }, { 2419, 0x4450 }, + { 2423, 0x4004 }, { 2425, 0x0100 }, { 2426, 0x8280 }, { 2429, 0x0540 }, + { 2432, 0x0108 }, { 2434, 0x442c }, { 2439, 0x6a30 }, { 2445, 0x1a05 }, + { 2450, 0x20a6 }, { 2455, 0x0514 }, { 2459, 0x90cf }, { 2467, 0x6456 }, + /* 0x6500 */ + { 2474, 0x0021 }, { 2476, 0x3100 }, { 2479, 0x9c18 }, { 2485, 0xcbf0 }, + { 2494, 0xa120 }, { 2498, 0x63e2 }, { 2506, 0x104c }, { 2510, 0x01b5 }, + { 2516, 0x538c }, { 2523, 0x9a83 }, { 2530, 0xb8b2 }, { 2538, 0x3281 }, + { 2543, 0x987a }, { 2551, 0x0a84 }, { 2555, 0x33e7 }, { 2565, 0x0c02 }, + /* 0x6600 */ + { 2568, 0xd4cc }, { 2576, 0x9018 }, { 2580, 0xa1a1 }, { 2586, 0x9070 }, + { 2591, 0x8a1e }, { 2598, 0xe004 }, { 2602, 0xc3d4 }, { 2610, 0x0451 }, + { 2614, 0x439a }, { 2621, 0x21c2 }, { 2626, 0x4844 }, { 2630, 0x5310 }, + { 2635, 0x0292 }, { 2639, 0x3640 }, { 2644, 0x0241 }, { 2647, 0xf3bd }, + /* 0x6700 */ + { 2659, 0xab09 }, { 2666, 0xe8f0 }, { 2674, 0x7dc0 }, { 2682, 0xa5d2 }, + { 2690, 0xc242 }, { 2695, 0xd24b }, { 2703, 0xa43f }, { 2712, 0xd0af }, + { 2721, 0x1aa0 }, { 2726, 0x34a1 }, { 2732, 0x8247 }, { 2738, 0x03d8 }, + { 2744, 0xc452 }, { 2750, 0x651b }, { 2758, 0xd294 }, { 2765, 0xc83a }, + /* 0x6800 */ + { 2772, 0x001c }, { 2775, 0x40c8 }, { 2779, 0x0e06 }, { 2784, 0x3314 }, + { 2790, 0x614f }, { 2798, 0xb21b }, { 2806, 0x0088 }, { 2808, 0xc0d0 }, + { 2813, 0xa02a }, { 2818, 0xa898 }, { 2824, 0xa1c5 }, { 2831, 0x166b }, + { 2839, 0x2e50 }, { 2845, 0x85b4 }, { 2852, 0xc08b }, { 2858, 0x0604 }, + /* 0x6900 */ + { 2861, 0xf933 }, { 2871, 0x1e04 }, { 2876, 0x056e }, { 2883, 0xa251 }, + { 2889, 0x0400 }, { 2890, 0x7638 }, { 2898, 0xec07 }, { 2906, 0x73b8 }, + { 2915, 0x4406 }, { 2919, 0x1832 }, { 2924, 0x4081 }, { 2927, 0xc816 }, + { 2933, 0x7c8a }, { 2941, 0x6309 }, { 2947, 0x2980 }, { 2951, 0xaa04 }, + /* 0x6a00 */ + { 2956, 0x1c24 }, { 2961, 0xca9c }, { 2969, 0x4e0e }, { 2976, 0x2760 }, + { 2982, 0x0990 }, { 2986, 0x8300 }, { 2989, 0x0046 }, { 2992, 0x8104 }, + { 2995, 0x6011 }, { 2999, 0x1081 }, { 3002, 0x540d }, { 3008, 0x0908 }, + { 3011, 0x000e }, { 3014, 0xcc0a }, { 3020, 0x0500 }, { 3022, 0x0c00 }, + /* 0x6b00 */ + { 3024, 0x0430 }, { 3027, 0xa044 }, { 3031, 0x008b }, { 3035, 0x6784 }, + { 3042, 0x5288 }, { 3047, 0x8a19 }, { 3053, 0x865e }, { 3061, 0x8b18 }, + { 3067, 0x2e59 }, { 3075, 0x4160 }, { 3079, 0x8c10 }, { 3083, 0x9cbe }, + { 3093, 0x6861 }, { 3099, 0x891c }, { 3105, 0x9800 }, { 3108, 0x0008 }, + /* 0x6c00 */ + { 3109, 0x8100 }, { 3111, 0x089a }, { 3116, 0x0018 }, { 3118, 0x4190 }, + { 3122, 0x4007 }, { 3126, 0xe4a1 }, { 3133, 0x0505 }, { 3137, 0x640d }, + { 3143, 0x310e }, { 3149, 0x0e4d }, { 3156, 0x4806 }, { 3160, 0xff0a }, + { 3170, 0x1632 }, { 3176, 0x2aa8 }, { 3182, 0x852e }, { 3189, 0x000b }, + /* 0x6d00 */ + { 3192, 0x1800 }, { 3194, 0xca84 }, { 3200, 0x0e20 }, { 3204, 0x696c }, + { 3212, 0x0032 }, { 3215, 0x1600 }, { 3218, 0x5658 }, { 3225, 0x0390 }, + { 3229, 0x5120 }, { 3233, 0x1a28 }, { 3238, 0x8000 }, { 3239, 0x1124 }, + { 3243, 0x18e1 }, { 3249, 0x4326 }, { 3255, 0x5d52 }, { 3263, 0x0eaa }, + /* 0x6e00 */ + { 3270, 0x0fa0 }, { 3276, 0xae28 }, { 3283, 0xfa7b }, { 3295, 0x4500 }, + { 3298, 0x6408 }, { 3302, 0x8940 }, { 3306, 0xc880 }, { 3310, 0xc044 }, + { 3314, 0x9005 }, { 3318, 0xb141 }, { 3324, 0x8424 }, { 3328, 0x24c4 }, + { 3333, 0x1a34 }, { 3339, 0x603a }, { 3345, 0x9000 }, { 3347, 0xc194 }, + /* 0x6f00 */ + { 3353, 0x8246 }, { 3358, 0x003a }, { 3362, 0x180d }, { 3367, 0xc106 }, + { 3372, 0x0022 }, { 3374, 0x9910 }, { 3379, 0xe050 }, { 3384, 0x1511 }, + { 3389, 0x4057 }, { 3395, 0x0082 }, { 3397, 0x041a }, { 3401, 0x020a }, + { 3404, 0x004f }, { 3409, 0x8930 }, { 3414, 0xd813 }, { 3421, 0x444a }, + /* 0x7000 */ + { 3426, 0x8a02 }, { 3430, 0xed22 }, { 3438, 0x10c0 }, { 3441, 0x4005 }, + { 3444, 0x1000 }, { 3445, 0x0102 }, { 3447, 0x8808 }, { 3450, 0x3101 }, + { 3454, 0x4600 }, { 3457, 0x0204 }, { 3459, 0xf000 }, { 3463, 0x0708 }, + { 3467, 0x8900 }, { 3470, 0xa200 }, { 3473, 0x0000 }, { 3473, 0x2202 }, + /* 0x7100 */ + { 3476, 0x0200 }, { 3477, 0x1610 }, { 3481, 0x0042 }, { 3483, 0x1040 }, + { 3485, 0x5200 }, { 3488, 0x0260 }, { 3491, 0x52f4 }, { 3499, 0x2000 }, + { 3500, 0x8510 }, { 3504, 0x8230 }, { 3508, 0x1100 }, { 3510, 0x4202 }, + { 3513, 0x4308 }, { 3517, 0x80b5 }, { 3523, 0x70e1 }, { 3530, 0x9a20 }, + /* 0x7200 */ + { 3535, 0x2040 }, { 3537, 0x0801 }, { 3539, 0x3500 }, { 3543, 0xfc65 }, + { 3553, 0x19c1 }, { 3559, 0xab04 }, { 3565, 0x0286 }, { 3569, 0x6214 }, + { 3574, 0x0087 }, { 3578, 0x0044 }, { 3580, 0x9085 }, { 3585, 0x0244 }, + { 3588, 0x405c }, { 3593, 0x0a85 }, { 3598, 0x3207 }, { 3604, 0x3380 }, + /* 0x7300 */ + { 3609, 0x0400 }, { 3610, 0xb8c0 }, { 3616, 0xce20 }, { 3622, 0xc0d0 }, + { 3627, 0xc030 }, { 3631, 0x0080 }, { 3632, 0x0508 }, { 3635, 0x0d25 }, + { 3641, 0x0a90 }, { 3645, 0x0040 }, { 3646, 0x0200 }, { 3647, 0x080c }, + { 3650, 0x6505 }, { 3656, 0x4000 }, { 3657, 0x6421 }, { 3662, 0x4102 }, + /* 0x7400 */ + { 3665, 0x0268 }, { 3669, 0x0000 }, { 3669, 0x0024 }, { 3671, 0x847c }, + { 3678, 0x0002 }, { 3679, 0xde20 }, { 3686, 0x8619 }, { 3692, 0x4049 }, + { 3696, 0x0808 }, { 3698, 0x4000 }, { 3699, 0x0084 }, { 3701, 0x2001 }, + { 3703, 0x8400 }, { 3705, 0x1010 }, { 3707, 0x42cd }, { 3714, 0x01c7 }, + /* 0x7500 */ + { 3720, 0x7038 }, { 3726, 0xd52a }, { 3734, 0x1968 }, { 3740, 0x1d8f }, + { 3749, 0xbe50 }, { 3757, 0x3e12 }, { 3764, 0x2ef5 }, { 3774, 0x81d9 }, + { 3781, 0xcec4 }, { 3789, 0x2412 }, { 3793, 0x0828 }, { 3796, 0x732e }, + { 3805, 0x24ac }, { 3811, 0x4b34 }, { 3818, 0x020c }, { 3821, 0xd41d }, + /* 0x7600 */ + { 3829, 0x2a02 }, { 3833, 0x8000 }, { 3834, 0x0097 }, { 3839, 0x0811 }, + { 3842, 0x11c4 }, { 3847, 0x1144 }, { 3851, 0x1786 }, { 3858, 0x7d45 }, + { 3867, 0x49d9 }, { 3875, 0x0649 }, { 3880, 0x4000 }, { 3881, 0x8791 }, + { 3888, 0x254c }, { 3894, 0xd8c4 }, { 3901, 0x44ba }, { 3908, 0x4914 }, + /* 0x7700 */ + { 3913, 0x1b92 }, { 3920, 0xc800 }, { 3923, 0x0271 }, { 3928, 0x1580 }, + { 3932, 0x0081 }, { 3934, 0x0c00 }, { 3936, 0x096a }, { 3942, 0xc200 }, + { 3945, 0x4800 }, { 3947, 0x4002 }, { 3949, 0x3021 }, { 3953, 0xba49 }, + { 3961, 0x2080 }, { 3963, 0x1c80 }, { 3967, 0xe2ac }, { 3975, 0x1008 }, + /* 0x7800 */ + { 3977, 0x1004 }, { 3979, 0x0034 }, { 3982, 0x00e1 }, { 3986, 0x8414 }, + { 3990, 0x0020 }, { 3991, 0x2000 }, { 3992, 0x9800 }, { 3995, 0x1014 }, + { 3998, 0x70c2 }, { 4004, 0x04aa }, { 4009, 0x8688 }, { 4014, 0x5420 }, + { 4018, 0x0c62 }, { 4023, 0x0413 }, { 4027, 0x9180 }, { 4031, 0x2010 }, + /* 0x7900 */ + { 4033, 0x4082 }, { 4036, 0x0206 }, { 4039, 0x1c40 }, { 4043, 0x5400 }, + { 4046, 0x0383 }, { 4051, 0xe4e9 }, { 4060, 0x2125 }, { 4065, 0x8480 }, + { 4068, 0xe433 }, { 4076, 0x2000 }, { 4077, 0x44c0 }, { 4081, 0xe609 }, + { 4088, 0x0a03 }, { 4092, 0x8126 }, { 4097, 0x12da }, { 4104, 0x0801 }, + /* 0x7a00 */ + { 4106, 0x6901 }, { 4111, 0x9790 }, { 4118, 0x4001 }, { 4120, 0xf886 }, + { 4128, 0xe24d }, { 4136, 0x0081 }, { 4138, 0x0a0e }, { 4143, 0xa651 }, + { 4150, 0x011a }, { 4154, 0x81ec }, { 4161, 0xc600 }, { 4165, 0x8441 }, + { 4169, 0xadb8 }, { 4178, 0xb62c }, { 4186, 0xa46f }, { 4195, 0x8741 }, + /* 0x7b00 */ + { 4201, 0x8d54 }, { 4208, 0x4b02 }, { 4213, 0x1161 }, { 4218, 0x0268 }, + { 4222, 0xbb60 }, { 4230, 0x2057 }, { 4236, 0x50a0 }, { 4240, 0x0433 }, + { 4245, 0xa8c0 }, { 4250, 0xb7b4 }, { 4260, 0x2402 }, { 4263, 0x0112 }, + { 4266, 0x9ad3 }, { 4275, 0x2000 }, { 4276, 0x2271 }, { 4282, 0x00c8 }, + /* 0x7c00 */ + { 4285, 0x2081 }, { 4288, 0x809e }, { 4294, 0x0c8a }, { 4299, 0xe180 }, + { 4304, 0xb009 }, { 4309, 0x8151 }, { 4314, 0x1031 }, { 4318, 0x4028 }, + { 4321, 0x2a0e }, { 4327, 0x89a5 }, { 4334, 0x69b6 }, { 4343, 0x620e }, + { 4349, 0x4425 }, { 4354, 0xd144 }, { 4360, 0x8085 }, { 4364, 0x4d54 }, + /* 0x7d00 */ + { 4371, 0x2c75 }, { 4379, 0x1fb1 }, { 4388, 0xd807 }, { 4395, 0x862d }, + { 4402, 0xd87c }, { 4411, 0x4841 }, { 4415, 0x414e }, { 4421, 0x226e }, + { 4428, 0x8200 }, { 4430, 0x9e08 }, { 4436, 0xf80c }, { 4443, 0xed37 }, + { 4454, 0x8c80 }, { 4458, 0x7526 }, { 4466, 0x9313 }, { 4473, 0x0814 }, + /* 0x7e00 */ + { 4476, 0x0e32 }, { 4482, 0xc804 }, { 4486, 0x484e }, { 4492, 0x6ea6 }, + { 4501, 0x2c4a }, { 4507, 0x6670 }, { 4514, 0x26c0 }, { 4519, 0xba01 }, + { 4525, 0xd30c }, { 4532, 0x185d }, { 4539, 0x0000 }, { 4539, 0x0000 }, + { 4539, 0x0000 }, { 4539, 0x0000 }, { 4539, 0x0000 }, { 4539, 0x0000 }, + /* 0x7f00 */ + { 4539, 0x0000 }, { 4539, 0x0000 }, { 4539, 0x0000 }, { 4539, 0x0540 }, + { 4542, 0x7020 }, { 4546, 0x8133 }, { 4552, 0x4f81 }, { 4559, 0x03a5 }, + { 4565, 0x55ec }, { 4574, 0x6410 }, { 4578, 0xc318 }, { 4584, 0x2344 }, + { 4589, 0x1462 }, { 4594, 0x0034 }, { 4597, 0x0a43 }, { 4602, 0x1a09 }, + /* 0x8000 */ + { 4607, 0x187b }, { 4615, 0x13a5 }, { 4622, 0x0102 }, { 4624, 0xa848 }, + { 4629, 0x0440 }, { 4631, 0xc544 }, { 4637, 0x8106 }, { 4641, 0xe2dd }, + { 4651, 0x1af0 }, { 4658, 0x2d48 }, { 4664, 0xb626 }, { 4672, 0x0416 }, + { 4676, 0x5058 }, { 4681, 0x6e40 }, { 4687, 0x8032 }, { 4691, 0x3112 }, + /* 0x8100 */ + { 4696, 0x07e4 }, { 4703, 0x0c00 }, { 4705, 0x8208 }, { 4708, 0x420a }, + { 4712, 0x4840 }, { 4715, 0x803b }, { 4721, 0x4860 }, { 4725, 0x8713 }, + { 4732, 0x850d }, { 4738, 0x3428 }, { 4743, 0x0319 }, { 4748, 0xe529 }, + { 4756, 0x2345 }, { 4762, 0x870a }, { 4768, 0x25a9 }, { 4775, 0x5c18 }, + /* 0x8200 */ + { 4781, 0x77a6 }, { 4791, 0xd9c5 }, { 4800, 0x5e00 }, { 4805, 0x03e8 }, + { 4811, 0x0081 }, { 4813, 0xa700 }, { 4818, 0xcd54 }, { 4826, 0x41c6 }, + { 4832, 0x2800 }, { 4834, 0xa204 }, { 4838, 0xb860 }, { 4844, 0x2b0a }, + { 4850, 0x0020 }, { 4851, 0xda9e }, { 4861, 0x08ea }, { 4867, 0x0e1a }, + /* 0x8300 */ + { 4873, 0x427c }, { 4880, 0x11c0 }, { 4884, 0x8908 }, { 4888, 0x0376 }, + { 4895, 0x8621 }, { 4900, 0x0105 }, { 4903, 0x0000 }, { 4903, 0x18a8 }, + { 4908, 0x46a0 }, { 4913, 0xc448 }, { 4918, 0x0d05 }, { 4923, 0x2022 }, + { 4926, 0x5422 }, { 4931, 0x9148 }, { 4936, 0x8a01 }, { 4940, 0x2897 }, + /* 0x8400 */ + { 4947, 0x7898 }, { 4954, 0x0008 }, { 4955, 0x1605 }, { 4960, 0x3122 }, + { 4965, 0x4240 }, { 4968, 0x0880 }, { 4970, 0xfa4e }, { 4980, 0x06a2 }, + { 4985, 0x0814 }, { 4988, 0x9211 }, { 4993, 0x2002 }, { 4995, 0x9b04 }, + { 5001, 0x2e52 }, { 5008, 0x0643 }, { 5013, 0x5000 }, { 5015, 0x9010 }, + /* 0x8500 */ + { 5018, 0x0041 }, { 5020, 0x85ba }, { 5028, 0x3042 }, { 5032, 0x2020 }, + { 5034, 0x4f0b }, { 5042, 0x05a0 }, { 5046, 0x2708 }, { 5051, 0x4080 }, + { 5053, 0x0591 }, { 5058, 0x1a93 }, { 5065, 0xdf50 }, { 5074, 0x0600 }, + { 5076, 0xa202 }, { 5080, 0x3021 }, { 5084, 0x0630 }, { 5088, 0x4e80 }, + /* 0x8600 */ + { 5093, 0x0cc4 }, { 5098, 0x04c8 }, { 5102, 0xa004 }, { 5105, 0x8001 }, + { 5107, 0x6000 }, { 5109, 0xd431 }, { 5116, 0x0880 }, { 5118, 0x0a02 }, + { 5121, 0x1c00 }, { 5124, 0x0028 }, { 5126, 0x8e18 }, { 5132, 0x0041 }, + { 5134, 0x6ad0 }, { 5141, 0xca10 }, { 5146, 0xf210 }, { 5152, 0x4b00 }, + /* 0x8700 */ + { 5156, 0x274d }, { 5164, 0x1506 }, { 5169, 0x0220 }, { 5171, 0x8890 }, + { 5175, 0x5a00 }, { 5179, 0x82a8 }, { 5184, 0x4549 }, { 5190, 0x8150 }, + { 5194, 0x2004 }, { 5196, 0x8000 }, { 5197, 0x8804 }, { 5200, 0x2c08 }, + { 5204, 0x08d1 }, { 5209, 0x0005 }, { 5211, 0x8001 }, { 5213, 0x4ac4 }, + /* 0x8800 */ + { 5219, 0xe020 }, { 5223, 0x0062 }, { 5226, 0x008e }, { 5230, 0x0a42 }, + { 5234, 0x3055 }, { 5240, 0x6a8c }, { 5247, 0x090e }, { 5252, 0xe0a5 }, + { 5259, 0x2906 }, { 5264, 0x42c4 }, { 5269, 0x4814 }, { 5273, 0x80b3 }, + { 5279, 0x803e }, { 5285, 0xb330 }, { 5292, 0x0102 }, { 5294, 0x731c }, + /* 0x8900 */ + { 5302, 0x1494 }, { 5307, 0x600d }, { 5312, 0x0c20 }, { 5315, 0x0940 }, + { 5318, 0x301a }, { 5323, 0xc040 }, { 5326, 0xa451 }, { 5332, 0xc094 }, + { 5337, 0x8dca }, { 5345, 0x05c8 }, { 5350, 0x96c2 }, { 5357, 0xa40c }, + { 5362, 0x0001 }, { 5363, 0x3404 }, { 5367, 0x00c8 }, { 5370, 0x0110 }, + /* 0x8a00 */ + { 5372, 0x550d }, { 5379, 0xa9c9 }, { 5387, 0x2428 }, { 5391, 0x1c5a }, + { 5398, 0x0142 }, { 5401, 0x4837 }, { 5408, 0x7a4d }, { 5417, 0x100f }, + { 5422, 0x32b4 }, { 5429, 0x452a }, { 5435, 0x317b }, { 5444, 0x9205 }, + { 5449, 0xb894 }, { 5456, 0x5c44 }, { 5462, 0x68d7 }, { 5471, 0x458a }, + /* 0x8b00 */ + { 5477, 0x5097 }, { 5484, 0x2ed1 }, { 5492, 0x1943 }, { 5498, 0x4208 }, + { 5501, 0xd202 }, { 5506, 0x9d40 }, { 5512, 0x9840 }, { 5516, 0x2097 }, + { 5522, 0x5409 }, { 5527, 0x064d }, { 5533, 0x0000 }, { 5533, 0x0000 }, + { 5533, 0x0000 }, { 5533, 0x0000 }, { 5533, 0x0000 }, { 5533, 0x0000 }, + /* 0x8c00 */ + { 5533, 0x0000 }, { 5533, 0x0000 }, { 5533, 0x0000 }, { 5533, 0x8480 }, + { 5536, 0x5542 }, { 5542, 0x0421 }, { 5545, 0x1c06 }, { 5550, 0x1700 }, + { 5554, 0x7624 }, { 5561, 0x6110 }, { 5565, 0xff87 }, { 5577, 0xb9dd }, + { 5588, 0x659f }, { 5598, 0x5c0a }, { 5604, 0x245d }, { 5611, 0x3c00 }, + /* 0x8d00 */ + { 5615, 0xadb0 }, { 5623, 0x0059 }, { 5627, 0x0000 }, { 5627, 0x0000 }, + { 5627, 0x0000 }, { 5627, 0x0000 }, { 5627, 0x28d0 }, { 5632, 0x009b }, + { 5637, 0x0422 }, { 5640, 0x0200 }, { 5641, 0x0108 }, { 5643, 0x4408 }, + { 5646, 0x9804 }, { 5650, 0xac40 }, { 5655, 0x8d0a }, { 5661, 0x9028 }, + /* 0x8e00 */ + { 5665, 0x8700 }, { 5669, 0xe001 }, { 5673, 0x0400 }, { 5674, 0x0031 }, + { 5677, 0x1794 }, { 5684, 0x8221 }, { 5688, 0x0019 }, { 5691, 0x1054 }, + { 5695, 0x2cb2 }, { 5702, 0x021a }, { 5706, 0x9c02 }, { 5711, 0x4003 }, + { 5714, 0x3d60 }, { 5721, 0x8804 }, { 5724, 0x080c }, { 5727, 0x7900 }, + /* 0x8f00 */ + { 5732, 0x1628 }, { 5737, 0xba3c }, { 5746, 0x8640 }, { 5750, 0xcb08 }, + { 5756, 0x7274 }, { 5764, 0x9080 }, { 5767, 0x001e }, { 5771, 0x0000 }, + { 5771, 0x0000 }, { 5771, 0xd800 }, { 5775, 0xe188 }, { 5781, 0x9c87 }, + { 5789, 0x4034 }, { 5793, 0x0412 }, { 5796, 0xae64 }, { 5804, 0x2791 }, + /* 0x9000 */ + { 5811, 0xe86b }, { 5820, 0xe6fb }, { 5832, 0x408f }, { 5838, 0x5366 }, + { 5846, 0xeea6 }, { 5856, 0x537f }, { 5867, 0xe32b }, { 5876, 0xb5e4 }, + { 5885, 0x869f }, { 5894, 0x0002 }, { 5895, 0x8548 }, { 5900, 0x0122 }, + { 5903, 0x4402 }, { 5906, 0x0800 }, { 5907, 0x2116 }, { 5912, 0x20a0 }, + /* 0x9100 */ + { 5915, 0x0004 }, { 5916, 0x0204 }, { 5918, 0x2000 }, { 5919, 0x0005 }, + { 5921, 0x7e00 }, { 5927, 0x0154 }, { 5931, 0x162c }, { 5937, 0x01ac }, + { 5942, 0x2a84 }, { 5947, 0x1085 }, { 5951, 0x8c14 }, { 5956, 0x0530 }, + { 5960, 0xfbc3 }, { 5971, 0xb943 }, { 5979, 0x00ca }, { 5983, 0x9060 }, + /* 0x9200 */ + { 5987, 0x6000 }, { 5989, 0x4032 }, { 5993, 0x1200 }, { 5995, 0x8090 }, + { 5998, 0x0b30 }, { 6003, 0x4c81 }, { 6008, 0x0054 }, { 6011, 0x4002 }, + { 6013, 0x0029 }, { 6016, 0x1d6a }, { 6024, 0x2000 }, { 6025, 0x0280 }, + { 6027, 0x8000 }, { 6028, 0x0004 }, { 6029, 0x2610 }, { 6033, 0x150c }, + /* 0x9300 */ + { 6038, 0x8040 }, { 6040, 0x0701 }, { 6044, 0xd94d }, { 6053, 0x0c24 }, + { 6057, 0x2810 }, { 6060, 0x1850 }, { 6064, 0x5001 }, { 6067, 0x5020 }, + { 6070, 0x1000 }, { 6071, 0x04d0 }, { 6075, 0x7080 }, { 6079, 0x0201 }, + { 6081, 0x0108 }, { 6083, 0x21c3 }, { 6089, 0x0132 }, { 6093, 0x0000 }, + /* 0x9400 */ + { 6093, 0x0088 }, { 6095, 0x0719 }, { 6101, 0x0802 }, { 6103, 0x0560 }, + { 6107, 0x0012 }, { 6109, 0x4c0e }, { 6115, 0x0405 }, { 6118, 0xf0a1 }, + { 6125, 0x0002 }, { 6126, 0x0000 }, { 6126, 0x0000 }, { 6126, 0x0000 }, + { 6126, 0x0000 }, { 6126, 0x0000 }, { 6126, 0x0000 }, { 6126, 0x0000 }, + /* 0x9500 */ + { 6126, 0x0000 }, { 6126, 0x0000 }, { 6126, 0x0000 }, { 6126, 0x0000 }, + { 6126, 0x0000 }, { 6126, 0x0000 }, { 6126, 0x0000 }, { 6126, 0x0080 }, + { 6127, 0x8e8d }, { 6135, 0x035a }, { 6141, 0x21bd }, { 6149, 0x5a04 }, + { 6154, 0x3488 }, { 6159, 0x1170 }, { 6164, 0x0026 }, { 6167, 0x0000 }, + /* 0x9600 */ + { 6167, 0x0000 }, { 6167, 0x1000 }, { 6168, 0xc502 }, { 6173, 0x8804 }, + { 6176, 0xb815 }, { 6183, 0xf801 }, { 6189, 0x147c }, { 6196, 0x25ed }, + { 6205, 0xed60 }, { 6213, 0x1bb0 }, { 6220, 0x0589 }, { 6225, 0x1bd7 }, + { 6235, 0x7af3 }, { 6246, 0x1a62 }, { 6252, 0x0d0c }, { 6257, 0x0ac5 }, + /* 0x9700 */ + { 6263, 0xe5d1 }, { 6272, 0x524a }, { 6278, 0x0490 }, { 6281, 0x6305 }, + { 6287, 0x0354 }, { 6292, 0x5244 }, { 6297, 0x2b57 }, { 6306, 0x1612 }, + { 6311, 0xa872 }, { 6318, 0x1101 }, { 6321, 0x2949 }, { 6327, 0x0018 }, + { 6329, 0x0948 }, { 6333, 0x1008 }, { 6335, 0x6000 }, { 6337, 0x886c }, + /* 0x9800 */ + { 6343, 0x916e }, { 6351, 0x058f }, { 6358, 0x3012 }, { 6362, 0x3990 }, + { 6368, 0xf840 }, { 6374, 0x4930 }, { 6379, 0x8880 }, { 6382, 0x001b }, + { 6386, 0x0000 }, { 6386, 0x0000 }, { 6386, 0x8500 }, { 6389, 0x0042 }, + { 6391, 0x0058 }, { 6394, 0x9800 }, { 6397, 0xea04 }, { 6403, 0x7014 }, + /* 0x9900 */ + { 6408, 0x1628 }, { 6413, 0x611d }, { 6420, 0x5113 }, { 6426, 0x6000 }, + { 6428, 0x1a24 }, { 6433, 0x00a7 }, { 6438, 0x0000 }, { 6438, 0x0000 }, + { 6438, 0x0000 }, { 6438, 0x03c0 }, { 6442, 0x7120 }, { 6447, 0x1018 }, + { 6450, 0x0172 }, { 6455, 0xa927 }, { 6463, 0x6004 }, { 6466, 0x8906 }, + /* 0x9a00 */ + { 6471, 0xc022 }, { 6475, 0x020c }, { 6478, 0x0900 }, { 6480, 0x4081 }, + { 6483, 0x202d }, { 6488, 0x8ca0 }, { 6493, 0x0e34 }, { 6499, 0x0000 }, + { 6499, 0x0000 }, { 6499, 0x0000 }, { 6499, 0x2100 }, { 6501, 0x1101 }, + { 6504, 0x8011 }, { 6507, 0xc11a }, { 6513, 0xec4c }, { 6521, 0x0892 }, + /* 0x9b00 */ + { 6525, 0x0040 }, { 6526, 0x8500 }, { 6529, 0xc7ac }, { 6538, 0x1806 }, + { 6542, 0xe03e }, { 6550, 0x0512 }, { 6554, 0x8000 }, { 6555, 0x0010 }, + { 6556, 0x4008 }, { 6558, 0x80ce }, { 6564, 0x6d01 }, { 6570, 0x0210 }, + { 6572, 0x8641 }, { 6577, 0x0856 }, { 6582, 0x011e }, { 6587, 0x0027 }, + /* 0x9c00 */ + { 6591, 0x3750 }, { 6598, 0x083d }, { 6604, 0xe032 }, { 6610, 0x4e05 }, + { 6616, 0x01c0 }, { 6619, 0x0484 }, { 6622, 0x0081 }, { 6624, 0x0140 }, + { 6626, 0x0000 }, { 6626, 0x0000 }, { 6626, 0x0000 }, { 6626, 0x0000 }, + { 6626, 0x0000 }, { 6626, 0x0000 }, { 6626, 0x1aa0 }, { 6631, 0x0059 }, + /* 0x9d00 */ + { 6635, 0x43c8 }, { 6641, 0x8824 }, { 6645, 0x1d48 }, { 6651, 0xc800 }, + { 6654, 0x0152 }, { 6658, 0x7203 }, { 6664, 0x9013 }, { 6669, 0x0404 }, + { 6671, 0x8280 }, { 6674, 0x0400 }, { 6675, 0x8a10 }, { 6679, 0x0d14 }, + { 6684, 0x8056 }, { 6689, 0x0208 }, { 6691, 0xa040 }, { 6694, 0x2704 }, + /* 0x9e00 */ + { 6699, 0x0000 }, { 6699, 0x4c00 }, { 6702, 0x0000 }, { 6702, 0x0000 }, + { 6702, 0x0000 }, { 6702, 0x0000 }, { 6702, 0x0000 }, { 6702, 0xa320 }, + { 6707, 0x1902 }, { 6711, 0xa0ae }, { 6718, 0x2660 }, { 6723, 0xdf00 }, + { 6730, 0xf010 }, { 6735, 0x7b15 }, { 6744, 0x8121 }, { 6748, 0x3ad0 }, + /* 0x9f00 */ + { 6755, 0x4180 }, { 6758, 0x0028 }, { 6760, 0x1003 }, { 6763, 0x4800 }, + { 6765, 0xcc00 }, { 6769, 0x8014 }, { 6772, 0x14cf }, { 6780, 0x00c4 }, + { 6783, 0x2000 }, { 6784, 0x3020 }, { 6787, 0x0001 }, +}; +static const Summary16 jisx0208_uni2indx_pageff[15] = { + /* 0xff00 */ + { 6788, 0xdf7a }, { 6800, 0xffff }, { 6816, 0xffff }, { 6832, 0xefff }, + { 6847, 0xffff }, { 6863, 0x3fff }, { 6877, 0x0000 }, { 6877, 0x0000 }, + { 6877, 0x0000 }, { 6877, 0x0000 }, { 6877, 0x0000 }, { 6877, 0x0000 }, + { 6877, 0x0000 }, { 6877, 0x0000 }, { 6877, 0x0028 }, +}; + +static int +jisx0208_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (n >= 2) { + const Summary16 *summary = NULL; + if (wc < 0x0100) + summary = &jisx0208_uni2indx_page00[(wc>>4)]; + else if (wc >= 0x0300 && wc < 0x0460) + summary = &jisx0208_uni2indx_page03[(wc>>4)-0x030]; + else if (wc >= 0x2000 && wc < 0x2320) + summary = &jisx0208_uni2indx_page20[(wc>>4)-0x200]; + else if (wc >= 0x2500 && wc < 0x2670) + summary = &jisx0208_uni2indx_page25[(wc>>4)-0x250]; + else if (wc >= 0x3000 && wc < 0x3100) + summary = &jisx0208_uni2indx_page30[(wc>>4)-0x300]; + else if (wc >= 0x4e00 && wc < 0x9fb0) + summary = &jisx0208_uni2indx_page4e[(wc>>4)-0x4e0]; + else if (wc >= 0xff00 && wc < 0xfff0) + summary = &jisx0208_uni2indx_pageff[(wc>>4)-0xff0]; + if (summary) { + unsigned short used = summary->used; + unsigned int i = wc & 0x0f; + if (used & ((unsigned short) 1 << i)) { + unsigned short c; + /* Keep in `used' only the bits 0..i-1. */ + used &= ((unsigned short) 1 << i) - 1; + /* Add `summary->indx' and the number of bits set in `used'. */ + used = (used & 0x5555) + ((used & 0xaaaa) >> 1); + used = (used & 0x3333) + ((used & 0xcccc) >> 2); + used = (used & 0x0f0f) + ((used & 0xf0f0) >> 4); + used = (used & 0x00ff) + (used >> 8); + c = jisx0208_2charset[summary->indx + used]; + r[0] = (c >> 8); r[1] = (c & 0xff); + return 2; + } + } + return RET_ILSEQ; + } + return RET_TOOSMALL; +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/jisx0212.h b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/jisx0212.h new file mode 100644 index 0000000..a4857b9 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/jisx0212.h @@ -0,0 +1,2164 @@ +/* $XFree86: xc/lib/X11/lcUniConv/jisx0212.h,v 1.5 2003/05/27 22:26:31 tsi Exp $ */ + +/* + * JISX0212.1990-0 + */ + +static const unsigned short jisx0212_2uni_page22[81] = { + /* 0x22 */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x02d8, 0x02c7, + 0x00b8, 0x02d9, 0x02dd, 0x00af, 0x02db, 0x02da, 0x007e, 0x0384, + 0x0385, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x00a1, 0x00a6, 0x00bf, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0x00ba, 0x00aa, 0x00a9, 0x00ae, 0x2122, 0x00a4, + 0x2116, +}; +static const unsigned short jisx0212_2uni_page26[188] = { + /* 0x26 */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x0386, 0x0388, 0x0389, 0x038a, 0x03aa, 0xfffd, 0x038c, 0xfffd, + 0x038e, 0x03ab, 0xfffd, 0x038f, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x03ac, 0x03ad, 0x03ae, 0x03af, 0x03ca, 0x0390, 0x03cc, 0x03c2, + 0x03cd, 0x03cb, 0x03b0, 0x03ce, 0xfffd, 0xfffd, + /* 0x27 */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407, 0x0408, + 0x0409, 0x040a, 0x040b, 0x040c, 0x040e, 0x040f, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457, 0x0458, + 0x0459, 0x045a, 0x045b, 0x045c, 0x045e, 0x045f, +}; +static const unsigned short jisx0212_2uni_page29[275] = { + /* 0x29 */ + 0x00c6, 0x0110, 0xfffd, 0x0126, 0xfffd, 0x0132, 0xfffd, 0x0141, + 0x013f, 0xfffd, 0x014a, 0x00d8, 0x0152, 0xfffd, 0x0166, 0x00de, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x00e6, 0x0111, 0x00f0, 0x0127, 0x0131, 0x0133, 0x0138, 0x0142, + 0x0140, 0x0149, 0x014b, 0x00f8, 0x0153, 0x00df, 0x0167, 0x00fe, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x2a */ + 0x00c1, 0x00c0, 0x00c4, 0x00c2, 0x0102, 0x01cd, 0x0100, 0x0104, + 0x00c5, 0x00c3, 0x0106, 0x0108, 0x010c, 0x00c7, 0x010a, 0x010e, + 0x00c9, 0x00c8, 0x00cb, 0x00ca, 0x011a, 0x0116, 0x0112, 0x0118, + 0xfffd, 0x011c, 0x011e, 0x0122, 0x0120, 0x0124, 0x00cd, 0x00cc, + 0x00cf, 0x00ce, 0x01cf, 0x0130, 0x012a, 0x012e, 0x0128, 0x0134, + 0x0136, 0x0139, 0x013d, 0x013b, 0x0143, 0x0147, 0x0145, 0x00d1, + 0x00d3, 0x00d2, 0x00d6, 0x00d4, 0x01d1, 0x0150, 0x014c, 0x00d5, + 0x0154, 0x0158, 0x0156, 0x015a, 0x015c, 0x0160, 0x015e, 0x0164, + 0x0162, 0x00da, 0x00d9, 0x00dc, 0x00db, 0x016c, 0x01d3, 0x0170, + 0x016a, 0x0172, 0x016e, 0x0168, 0x01d7, 0x01db, 0x01d9, 0x01d5, + 0x0174, 0x00dd, 0x0178, 0x0176, 0x0179, 0x017d, 0x017b, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x2b */ + 0x00e1, 0x00e0, 0x00e4, 0x00e2, 0x0103, 0x01ce, 0x0101, 0x0105, + 0x00e5, 0x00e3, 0x0107, 0x0109, 0x010d, 0x00e7, 0x010b, 0x010f, + 0x00e9, 0x00e8, 0x00eb, 0x00ea, 0x011b, 0x0117, 0x0113, 0x0119, + 0x01f5, 0x011d, 0x011f, 0xfffd, 0x0121, 0x0125, 0x00ed, 0x00ec, + 0x00ef, 0x00ee, 0x01d0, 0xfffd, 0x012b, 0x012f, 0x0129, 0x0135, + 0x0137, 0x013a, 0x013e, 0x013c, 0x0144, 0x0148, 0x0146, 0x00f1, + 0x00f3, 0x00f2, 0x00f6, 0x00f4, 0x01d2, 0x0151, 0x014d, 0x00f5, + 0x0155, 0x0159, 0x0157, 0x015b, 0x015d, 0x0161, 0x015f, 0x0165, + 0x0163, 0x00fa, 0x00f9, 0x00fc, 0x00fb, 0x016d, 0x01d4, 0x0171, + 0x016b, 0x0173, 0x016f, 0x0169, 0x01d8, 0x01dc, 0x01da, 0x01d6, + 0x0175, 0x00fd, 0x00ff, 0x0177, 0x017a, 0x017e, 0x017c, +}; +static const unsigned short jisx0212_2uni_page30[5801] = { + /* 0x30 */ + 0x4e02, 0x4e04, 0x4e05, 0x4e0c, 0x4e12, 0x4e1f, 0x4e23, 0x4e24, + 0x4e28, 0x4e2b, 0x4e2e, 0x4e2f, 0x4e30, 0x4e35, 0x4e40, 0x4e41, + 0x4e44, 0x4e47, 0x4e51, 0x4e5a, 0x4e5c, 0x4e63, 0x4e68, 0x4e69, + 0x4e74, 0x4e75, 0x4e79, 0x4e7f, 0x4e8d, 0x4e96, 0x4e97, 0x4e9d, + 0x4eaf, 0x4eb9, 0x4ec3, 0x4ed0, 0x4eda, 0x4edb, 0x4ee0, 0x4ee1, + 0x4ee2, 0x4ee8, 0x4eef, 0x4ef1, 0x4ef3, 0x4ef5, 0x4efd, 0x4efe, + 0x4eff, 0x4f00, 0x4f02, 0x4f03, 0x4f08, 0x4f0b, 0x4f0c, 0x4f12, + 0x4f15, 0x4f16, 0x4f17, 0x4f19, 0x4f2e, 0x4f31, 0x4f60, 0x4f33, + 0x4f35, 0x4f37, 0x4f39, 0x4f3b, 0x4f3e, 0x4f40, 0x4f42, 0x4f48, + 0x4f49, 0x4f4b, 0x4f4c, 0x4f52, 0x4f54, 0x4f56, 0x4f58, 0x4f5f, + 0x4f63, 0x4f6a, 0x4f6c, 0x4f6e, 0x4f71, 0x4f77, 0x4f78, 0x4f79, + 0x4f7a, 0x4f7d, 0x4f7e, 0x4f81, 0x4f82, 0x4f84, + /* 0x31 */ + 0x4f85, 0x4f89, 0x4f8a, 0x4f8c, 0x4f8e, 0x4f90, 0x4f92, 0x4f93, + 0x4f94, 0x4f97, 0x4f99, 0x4f9a, 0x4f9e, 0x4f9f, 0x4fb2, 0x4fb7, + 0x4fb9, 0x4fbb, 0x4fbc, 0x4fbd, 0x4fbe, 0x4fc0, 0x4fc1, 0x4fc5, + 0x4fc6, 0x4fc8, 0x4fc9, 0x4fcb, 0x4fcc, 0x4fcd, 0x4fcf, 0x4fd2, + 0x4fdc, 0x4fe0, 0x4fe2, 0x4ff0, 0x4ff2, 0x4ffc, 0x4ffd, 0x4fff, + 0x5000, 0x5001, 0x5004, 0x5007, 0x500a, 0x500c, 0x500e, 0x5010, + 0x5013, 0x5017, 0x5018, 0x501b, 0x501c, 0x501d, 0x501e, 0x5022, + 0x5027, 0x502e, 0x5030, 0x5032, 0x5033, 0x5035, 0x5040, 0x5041, + 0x5042, 0x5045, 0x5046, 0x504a, 0x504c, 0x504e, 0x5051, 0x5052, + 0x5053, 0x5057, 0x5059, 0x505f, 0x5060, 0x5062, 0x5063, 0x5066, + 0x5067, 0x506a, 0x506d, 0x5070, 0x5071, 0x503b, 0x5081, 0x5083, + 0x5084, 0x5086, 0x508a, 0x508e, 0x508f, 0x5090, + /* 0x32 */ + 0x5092, 0x5093, 0x5094, 0x5096, 0x509b, 0x509c, 0x509e, 0x509f, + 0x50a0, 0x50a1, 0x50a2, 0x50aa, 0x50af, 0x50b0, 0x50b9, 0x50ba, + 0x50bd, 0x50c0, 0x50c3, 0x50c4, 0x50c7, 0x50cc, 0x50ce, 0x50d0, + 0x50d3, 0x50d4, 0x50d8, 0x50dc, 0x50dd, 0x50df, 0x50e2, 0x50e4, + 0x50e6, 0x50e8, 0x50e9, 0x50ef, 0x50f1, 0x50f6, 0x50fa, 0x50fe, + 0x5103, 0x5106, 0x5107, 0x5108, 0x510b, 0x510c, 0x510d, 0x510e, + 0x50f2, 0x5110, 0x5117, 0x5119, 0x511b, 0x511c, 0x511d, 0x511e, + 0x5123, 0x5127, 0x5128, 0x512c, 0x512d, 0x512f, 0x5131, 0x5133, + 0x5134, 0x5135, 0x5138, 0x5139, 0x5142, 0x514a, 0x514f, 0x5153, + 0x5155, 0x5157, 0x5158, 0x515f, 0x5164, 0x5166, 0x517e, 0x5183, + 0x5184, 0x518b, 0x518e, 0x5198, 0x519d, 0x51a1, 0x51a3, 0x51ad, + 0x51b8, 0x51ba, 0x51bc, 0x51be, 0x51bf, 0x51c2, + /* 0x33 */ + 0x51c8, 0x51cf, 0x51d1, 0x51d2, 0x51d3, 0x51d5, 0x51d8, 0x51de, + 0x51e2, 0x51e5, 0x51ee, 0x51f2, 0x51f3, 0x51f4, 0x51f7, 0x5201, + 0x5202, 0x5205, 0x5212, 0x5213, 0x5215, 0x5216, 0x5218, 0x5222, + 0x5228, 0x5231, 0x5232, 0x5235, 0x523c, 0x5245, 0x5249, 0x5255, + 0x5257, 0x5258, 0x525a, 0x525c, 0x525f, 0x5260, 0x5261, 0x5266, + 0x526e, 0x5277, 0x5278, 0x5279, 0x5280, 0x5282, 0x5285, 0x528a, + 0x528c, 0x5293, 0x5295, 0x5296, 0x5297, 0x5298, 0x529a, 0x529c, + 0x52a4, 0x52a5, 0x52a6, 0x52a7, 0x52af, 0x52b0, 0x52b6, 0x52b7, + 0x52b8, 0x52ba, 0x52bb, 0x52bd, 0x52c0, 0x52c4, 0x52c6, 0x52c8, + 0x52cc, 0x52cf, 0x52d1, 0x52d4, 0x52d6, 0x52db, 0x52dc, 0x52e1, + 0x52e5, 0x52e8, 0x52e9, 0x52ea, 0x52ec, 0x52f0, 0x52f1, 0x52f4, + 0x52f6, 0x52f7, 0x5300, 0x5303, 0x530a, 0x530b, + /* 0x34 */ + 0x530c, 0x5311, 0x5313, 0x5318, 0x531b, 0x531c, 0x531e, 0x531f, + 0x5325, 0x5327, 0x5328, 0x5329, 0x532b, 0x532c, 0x532d, 0x5330, + 0x5332, 0x5335, 0x533c, 0x533d, 0x533e, 0x5342, 0x534c, 0x534b, + 0x5359, 0x535b, 0x5361, 0x5363, 0x5365, 0x536c, 0x536d, 0x5372, + 0x5379, 0x537e, 0x5383, 0x5387, 0x5388, 0x538e, 0x5393, 0x5394, + 0x5399, 0x539d, 0x53a1, 0x53a4, 0x53aa, 0x53ab, 0x53af, 0x53b2, + 0x53b4, 0x53b5, 0x53b7, 0x53b8, 0x53ba, 0x53bd, 0x53c0, 0x53c5, + 0x53cf, 0x53d2, 0x53d3, 0x53d5, 0x53da, 0x53dd, 0x53de, 0x53e0, + 0x53e6, 0x53e7, 0x53f5, 0x5402, 0x5413, 0x541a, 0x5421, 0x5427, + 0x5428, 0x542a, 0x542f, 0x5431, 0x5434, 0x5435, 0x5443, 0x5444, + 0x5447, 0x544d, 0x544f, 0x545e, 0x5462, 0x5464, 0x5466, 0x5467, + 0x5469, 0x546b, 0x546d, 0x546e, 0x5474, 0x547f, + /* 0x35 */ + 0x5481, 0x5483, 0x5485, 0x5488, 0x5489, 0x548d, 0x5491, 0x5495, + 0x5496, 0x549c, 0x549f, 0x54a1, 0x54a6, 0x54a7, 0x54a9, 0x54aa, + 0x54ad, 0x54ae, 0x54b1, 0x54b7, 0x54b9, 0x54ba, 0x54bb, 0x54bf, + 0x54c6, 0x54ca, 0x54cd, 0x54ce, 0x54e0, 0x54ea, 0x54ec, 0x54ef, + 0x54f6, 0x54fc, 0x54fe, 0x54ff, 0x5500, 0x5501, 0x5505, 0x5508, + 0x5509, 0x550c, 0x550d, 0x550e, 0x5515, 0x552a, 0x552b, 0x5532, + 0x5535, 0x5536, 0x553b, 0x553c, 0x553d, 0x5541, 0x5547, 0x5549, + 0x554a, 0x554d, 0x5550, 0x5551, 0x5558, 0x555a, 0x555b, 0x555e, + 0x5560, 0x5561, 0x5564, 0x5566, 0x557f, 0x5581, 0x5582, 0x5586, + 0x5588, 0x558e, 0x558f, 0x5591, 0x5592, 0x5593, 0x5594, 0x5597, + 0x55a3, 0x55a4, 0x55ad, 0x55b2, 0x55bf, 0x55c1, 0x55c3, 0x55c6, + 0x55c9, 0x55cb, 0x55cc, 0x55ce, 0x55d1, 0x55d2, + /* 0x36 */ + 0x55d3, 0x55d7, 0x55d8, 0x55db, 0x55de, 0x55e2, 0x55e9, 0x55f6, + 0x55ff, 0x5605, 0x5608, 0x560a, 0x560d, 0x560e, 0x560f, 0x5610, + 0x5611, 0x5612, 0x5619, 0x562c, 0x5630, 0x5633, 0x5635, 0x5637, + 0x5639, 0x563b, 0x563c, 0x563d, 0x563f, 0x5640, 0x5641, 0x5643, + 0x5644, 0x5646, 0x5649, 0x564b, 0x564d, 0x564f, 0x5654, 0x565e, + 0x5660, 0x5661, 0x5662, 0x5663, 0x5666, 0x5669, 0x566d, 0x566f, + 0x5671, 0x5672, 0x5675, 0x5684, 0x5685, 0x5688, 0x568b, 0x568c, + 0x5695, 0x5699, 0x569a, 0x569d, 0x569e, 0x569f, 0x56a6, 0x56a7, + 0x56a8, 0x56a9, 0x56ab, 0x56ac, 0x56ad, 0x56b1, 0x56b3, 0x56b7, + 0x56be, 0x56c5, 0x56c9, 0x56ca, 0x56cb, 0x56cf, 0x56d0, 0x56cc, + 0x56cd, 0x56d9, 0x56dc, 0x56dd, 0x56df, 0x56e1, 0x56e4, 0x56e5, + 0x56e6, 0x56e7, 0x56e8, 0x56f1, 0x56eb, 0x56ed, + /* 0x37 */ + 0x56f6, 0x56f7, 0x5701, 0x5702, 0x5707, 0x570a, 0x570c, 0x5711, + 0x5715, 0x571a, 0x571b, 0x571d, 0x5720, 0x5722, 0x5723, 0x5724, + 0x5725, 0x5729, 0x572a, 0x572c, 0x572e, 0x572f, 0x5733, 0x5734, + 0x573d, 0x573e, 0x573f, 0x5745, 0x5746, 0x574c, 0x574d, 0x5752, + 0x5762, 0x5765, 0x5767, 0x5768, 0x576b, 0x576d, 0x576e, 0x576f, + 0x5770, 0x5771, 0x5773, 0x5774, 0x5775, 0x5777, 0x5779, 0x577a, + 0x577b, 0x577c, 0x577e, 0x5781, 0x5783, 0x578c, 0x5794, 0x5797, + 0x5799, 0x579a, 0x579c, 0x579d, 0x579e, 0x579f, 0x57a1, 0x5795, + 0x57a7, 0x57a8, 0x57a9, 0x57ac, 0x57b8, 0x57bd, 0x57c7, 0x57c8, + 0x57cc, 0x57cf, 0x57d5, 0x57dd, 0x57de, 0x57e4, 0x57e6, 0x57e7, + 0x57e9, 0x57ed, 0x57f0, 0x57f5, 0x57f6, 0x57f8, 0x57fd, 0x57fe, + 0x57ff, 0x5803, 0x5804, 0x5808, 0x5809, 0x57e1, + /* 0x38 */ + 0x580c, 0x580d, 0x581b, 0x581e, 0x581f, 0x5820, 0x5826, 0x5827, + 0x582d, 0x5832, 0x5839, 0x583f, 0x5849, 0x584c, 0x584d, 0x584f, + 0x5850, 0x5855, 0x585f, 0x5861, 0x5864, 0x5867, 0x5868, 0x5878, + 0x587c, 0x587f, 0x5880, 0x5881, 0x5887, 0x5888, 0x5889, 0x588a, + 0x588c, 0x588d, 0x588f, 0x5890, 0x5894, 0x5896, 0x589d, 0x58a0, + 0x58a1, 0x58a2, 0x58a6, 0x58a9, 0x58b1, 0x58b2, 0x58c4, 0x58bc, + 0x58c2, 0x58c8, 0x58cd, 0x58ce, 0x58d0, 0x58d2, 0x58d4, 0x58d6, + 0x58da, 0x58dd, 0x58e1, 0x58e2, 0x58e9, 0x58f3, 0x5905, 0x5906, + 0x590b, 0x590c, 0x5912, 0x5913, 0x5914, 0x8641, 0x591d, 0x5921, + 0x5923, 0x5924, 0x5928, 0x592f, 0x5930, 0x5933, 0x5935, 0x5936, + 0x593f, 0x5943, 0x5946, 0x5952, 0x5953, 0x5959, 0x595b, 0x595d, + 0x595e, 0x595f, 0x5961, 0x5963, 0x596b, 0x596d, + /* 0x39 */ + 0x596f, 0x5972, 0x5975, 0x5976, 0x5979, 0x597b, 0x597c, 0x598b, + 0x598c, 0x598e, 0x5992, 0x5995, 0x5997, 0x599f, 0x59a4, 0x59a7, + 0x59ad, 0x59ae, 0x59af, 0x59b0, 0x59b3, 0x59b7, 0x59ba, 0x59bc, + 0x59c1, 0x59c3, 0x59c4, 0x59c8, 0x59ca, 0x59cd, 0x59d2, 0x59dd, + 0x59de, 0x59df, 0x59e3, 0x59e4, 0x59e7, 0x59ee, 0x59ef, 0x59f1, + 0x59f2, 0x59f4, 0x59f7, 0x5a00, 0x5a04, 0x5a0c, 0x5a0d, 0x5a0e, + 0x5a12, 0x5a13, 0x5a1e, 0x5a23, 0x5a24, 0x5a27, 0x5a28, 0x5a2a, + 0x5a2d, 0x5a30, 0x5a44, 0x5a45, 0x5a47, 0x5a48, 0x5a4c, 0x5a50, + 0x5a55, 0x5a5e, 0x5a63, 0x5a65, 0x5a67, 0x5a6d, 0x5a77, 0x5a7a, + 0x5a7b, 0x5a7e, 0x5a8b, 0x5a90, 0x5a93, 0x5a96, 0x5a99, 0x5a9c, + 0x5a9e, 0x5a9f, 0x5aa0, 0x5aa2, 0x5aa7, 0x5aac, 0x5ab1, 0x5ab2, + 0x5ab3, 0x5ab5, 0x5ab8, 0x5aba, 0x5abb, 0x5abf, + /* 0x3a */ + 0x5ac4, 0x5ac6, 0x5ac8, 0x5acf, 0x5ada, 0x5adc, 0x5ae0, 0x5ae5, + 0x5aea, 0x5aee, 0x5af5, 0x5af6, 0x5afd, 0x5b00, 0x5b01, 0x5b08, + 0x5b17, 0x5b34, 0x5b19, 0x5b1b, 0x5b1d, 0x5b21, 0x5b25, 0x5b2d, + 0x5b38, 0x5b41, 0x5b4b, 0x5b4c, 0x5b52, 0x5b56, 0x5b5e, 0x5b68, + 0x5b6e, 0x5b6f, 0x5b7c, 0x5b7d, 0x5b7e, 0x5b7f, 0x5b81, 0x5b84, + 0x5b86, 0x5b8a, 0x5b8e, 0x5b90, 0x5b91, 0x5b93, 0x5b94, 0x5b96, + 0x5ba8, 0x5ba9, 0x5bac, 0x5bad, 0x5baf, 0x5bb1, 0x5bb2, 0x5bb7, + 0x5bba, 0x5bbc, 0x5bc0, 0x5bc1, 0x5bcd, 0x5bcf, 0x5bd6, 0x5bd7, + 0x5bd8, 0x5bd9, 0x5bda, 0x5be0, 0x5bef, 0x5bf1, 0x5bf4, 0x5bfd, + 0x5c0c, 0x5c17, 0x5c1e, 0x5c1f, 0x5c23, 0x5c26, 0x5c29, 0x5c2b, + 0x5c2c, 0x5c2e, 0x5c30, 0x5c32, 0x5c35, 0x5c36, 0x5c59, 0x5c5a, + 0x5c5c, 0x5c62, 0x5c63, 0x5c67, 0x5c68, 0x5c69, + /* 0x3b */ + 0x5c6d, 0x5c70, 0x5c74, 0x5c75, 0x5c7a, 0x5c7b, 0x5c7c, 0x5c7d, + 0x5c87, 0x5c88, 0x5c8a, 0x5c8f, 0x5c92, 0x5c9d, 0x5c9f, 0x5ca0, + 0x5ca2, 0x5ca3, 0x5ca6, 0x5caa, 0x5cb2, 0x5cb4, 0x5cb5, 0x5cba, + 0x5cc9, 0x5ccb, 0x5cd2, 0x5cdd, 0x5cd7, 0x5cee, 0x5cf1, 0x5cf2, + 0x5cf4, 0x5d01, 0x5d06, 0x5d0d, 0x5d12, 0x5d2b, 0x5d23, 0x5d24, + 0x5d26, 0x5d27, 0x5d31, 0x5d34, 0x5d39, 0x5d3d, 0x5d3f, 0x5d42, + 0x5d43, 0x5d46, 0x5d48, 0x5d55, 0x5d51, 0x5d59, 0x5d4a, 0x5d5f, + 0x5d60, 0x5d61, 0x5d62, 0x5d64, 0x5d6a, 0x5d6d, 0x5d70, 0x5d79, + 0x5d7a, 0x5d7e, 0x5d7f, 0x5d81, 0x5d83, 0x5d88, 0x5d8a, 0x5d92, + 0x5d93, 0x5d94, 0x5d95, 0x5d99, 0x5d9b, 0x5d9f, 0x5da0, 0x5da7, + 0x5dab, 0x5db0, 0x5db4, 0x5db8, 0x5db9, 0x5dc3, 0x5dc7, 0x5dcb, + 0x5dd0, 0x5dce, 0x5dd8, 0x5dd9, 0x5de0, 0x5de4, + /* 0x3c */ + 0x5de9, 0x5df8, 0x5df9, 0x5e00, 0x5e07, 0x5e0d, 0x5e12, 0x5e14, + 0x5e15, 0x5e18, 0x5e1f, 0x5e20, 0x5e2e, 0x5e28, 0x5e32, 0x5e35, + 0x5e3e, 0x5e4b, 0x5e50, 0x5e49, 0x5e51, 0x5e56, 0x5e58, 0x5e5b, + 0x5e5c, 0x5e5e, 0x5e68, 0x5e6a, 0x5e6b, 0x5e6c, 0x5e6d, 0x5e6e, + 0x5e70, 0x5e80, 0x5e8b, 0x5e8e, 0x5ea2, 0x5ea4, 0x5ea5, 0x5ea8, + 0x5eaa, 0x5eac, 0x5eb1, 0x5eb3, 0x5ebd, 0x5ebe, 0x5ebf, 0x5ec6, + 0x5ecc, 0x5ecb, 0x5ece, 0x5ed1, 0x5ed2, 0x5ed4, 0x5ed5, 0x5edc, + 0x5ede, 0x5ee5, 0x5eeb, 0x5f02, 0x5f06, 0x5f07, 0x5f08, 0x5f0e, + 0x5f19, 0x5f1c, 0x5f1d, 0x5f21, 0x5f22, 0x5f23, 0x5f24, 0x5f28, + 0x5f2b, 0x5f2c, 0x5f2e, 0x5f30, 0x5f34, 0x5f36, 0x5f3b, 0x5f3d, + 0x5f3f, 0x5f40, 0x5f44, 0x5f45, 0x5f47, 0x5f4d, 0x5f50, 0x5f54, + 0x5f58, 0x5f5b, 0x5f60, 0x5f63, 0x5f64, 0x5f67, + /* 0x3d */ + 0x5f6f, 0x5f72, 0x5f74, 0x5f75, 0x5f78, 0x5f7a, 0x5f7d, 0x5f7e, + 0x5f89, 0x5f8d, 0x5f8f, 0x5f96, 0x5f9c, 0x5f9d, 0x5fa2, 0x5fa7, + 0x5fab, 0x5fa4, 0x5fac, 0x5faf, 0x5fb0, 0x5fb1, 0x5fb8, 0x5fc4, + 0x5fc7, 0x5fc8, 0x5fc9, 0x5fcb, 0x5fd0, 0x5fd1, 0x5fd2, 0x5fd3, + 0x5fd4, 0x5fde, 0x5fe1, 0x5fe2, 0x5fe8, 0x5fe9, 0x5fea, 0x5fec, + 0x5fed, 0x5fee, 0x5fef, 0x5ff2, 0x5ff3, 0x5ff6, 0x5ffa, 0x5ffc, + 0x6007, 0x600a, 0x600d, 0x6013, 0x6014, 0x6017, 0x6018, 0x601a, + 0x601f, 0x6024, 0x602d, 0x6033, 0x6035, 0x6040, 0x6047, 0x6048, + 0x6049, 0x604c, 0x6051, 0x6054, 0x6056, 0x6057, 0x605d, 0x6061, + 0x6067, 0x6071, 0x607e, 0x607f, 0x6082, 0x6086, 0x6088, 0x608a, + 0x608e, 0x6091, 0x6093, 0x6095, 0x6098, 0x609d, 0x609e, 0x60a2, + 0x60a4, 0x60a5, 0x60a8, 0x60b0, 0x60b1, 0x60b7, + /* 0x3e */ + 0x60bb, 0x60be, 0x60c2, 0x60c4, 0x60c8, 0x60c9, 0x60ca, 0x60cb, + 0x60ce, 0x60cf, 0x60d4, 0x60d5, 0x60d9, 0x60db, 0x60dd, 0x60de, + 0x60e2, 0x60e5, 0x60f2, 0x60f5, 0x60f8, 0x60fc, 0x60fd, 0x6102, + 0x6107, 0x610a, 0x610c, 0x6110, 0x6111, 0x6112, 0x6113, 0x6114, + 0x6116, 0x6117, 0x6119, 0x611c, 0x611e, 0x6122, 0x612a, 0x612b, + 0x6130, 0x6131, 0x6135, 0x6136, 0x6137, 0x6139, 0x6141, 0x6145, + 0x6146, 0x6149, 0x615e, 0x6160, 0x616c, 0x6172, 0x6178, 0x617b, + 0x617c, 0x617f, 0x6180, 0x6181, 0x6183, 0x6184, 0x618b, 0x618d, + 0x6192, 0x6193, 0x6197, 0x6198, 0x619c, 0x619d, 0x619f, 0x61a0, + 0x61a5, 0x61a8, 0x61aa, 0x61ad, 0x61b8, 0x61b9, 0x61bc, 0x61c0, + 0x61c1, 0x61c2, 0x61ce, 0x61cf, 0x61d5, 0x61dc, 0x61dd, 0x61de, + 0x61df, 0x61e1, 0x61e2, 0x61e7, 0x61e9, 0x61e5, + /* 0x3f */ + 0x61ec, 0x61ed, 0x61ef, 0x6201, 0x6203, 0x6204, 0x6207, 0x6213, + 0x6215, 0x621c, 0x6220, 0x6222, 0x6223, 0x6227, 0x6229, 0x622b, + 0x6239, 0x623d, 0x6242, 0x6243, 0x6244, 0x6246, 0x624c, 0x6250, + 0x6251, 0x6252, 0x6254, 0x6256, 0x625a, 0x625c, 0x6264, 0x626d, + 0x626f, 0x6273, 0x627a, 0x627d, 0x628d, 0x628e, 0x628f, 0x6290, + 0x62a6, 0x62a8, 0x62b3, 0x62b6, 0x62b7, 0x62ba, 0x62be, 0x62bf, + 0x62c4, 0x62ce, 0x62d5, 0x62d6, 0x62da, 0x62ea, 0x62f2, 0x62f4, + 0x62fc, 0x62fd, 0x6303, 0x6304, 0x630a, 0x630b, 0x630d, 0x6310, + 0x6313, 0x6316, 0x6318, 0x6329, 0x632a, 0x632d, 0x6335, 0x6336, + 0x6339, 0x633c, 0x6341, 0x6342, 0x6343, 0x6344, 0x6346, 0x634a, + 0x634b, 0x634e, 0x6352, 0x6353, 0x6354, 0x6358, 0x635b, 0x6365, + 0x6366, 0x636c, 0x636d, 0x6371, 0x6374, 0x6375, + /* 0x40 */ + 0x6378, 0x637c, 0x637d, 0x637f, 0x6382, 0x6384, 0x6387, 0x638a, + 0x6390, 0x6394, 0x6395, 0x6399, 0x639a, 0x639e, 0x63a4, 0x63a6, + 0x63ad, 0x63ae, 0x63af, 0x63bd, 0x63c1, 0x63c5, 0x63c8, 0x63ce, + 0x63d1, 0x63d3, 0x63d4, 0x63d5, 0x63dc, 0x63e0, 0x63e5, 0x63ea, + 0x63ec, 0x63f2, 0x63f3, 0x63f5, 0x63f8, 0x63f9, 0x6409, 0x640a, + 0x6410, 0x6412, 0x6414, 0x6418, 0x641e, 0x6420, 0x6422, 0x6424, + 0x6425, 0x6429, 0x642a, 0x642f, 0x6430, 0x6435, 0x643d, 0x643f, + 0x644b, 0x644f, 0x6451, 0x6452, 0x6453, 0x6454, 0x645a, 0x645b, + 0x645c, 0x645d, 0x645f, 0x6460, 0x6461, 0x6463, 0x646d, 0x6473, + 0x6474, 0x647b, 0x647d, 0x6485, 0x6487, 0x648f, 0x6490, 0x6491, + 0x6498, 0x6499, 0x649b, 0x649d, 0x649f, 0x64a1, 0x64a3, 0x64a6, + 0x64a8, 0x64ac, 0x64b3, 0x64bd, 0x64be, 0x64bf, + /* 0x41 */ + 0x64c4, 0x64c9, 0x64ca, 0x64cb, 0x64cc, 0x64ce, 0x64d0, 0x64d1, + 0x64d5, 0x64d7, 0x64e4, 0x64e5, 0x64e9, 0x64ea, 0x64ed, 0x64f0, + 0x64f5, 0x64f7, 0x64fb, 0x64ff, 0x6501, 0x6504, 0x6508, 0x6509, + 0x650a, 0x650f, 0x6513, 0x6514, 0x6516, 0x6519, 0x651b, 0x651e, + 0x651f, 0x6522, 0x6526, 0x6529, 0x652e, 0x6531, 0x653a, 0x653c, + 0x653d, 0x6543, 0x6547, 0x6549, 0x6550, 0x6552, 0x6554, 0x655f, + 0x6560, 0x6567, 0x656b, 0x657a, 0x657d, 0x6581, 0x6585, 0x658a, + 0x6592, 0x6595, 0x6598, 0x659d, 0x65a0, 0x65a3, 0x65a6, 0x65ae, + 0x65b2, 0x65b3, 0x65b4, 0x65bf, 0x65c2, 0x65c8, 0x65c9, 0x65ce, + 0x65d0, 0x65d4, 0x65d6, 0x65d8, 0x65df, 0x65f0, 0x65f2, 0x65f4, + 0x65f5, 0x65f9, 0x65fe, 0x65ff, 0x6600, 0x6604, 0x6608, 0x6609, + 0x660d, 0x6611, 0x6612, 0x6615, 0x6616, 0x661d, + /* 0x42 */ + 0x661e, 0x6621, 0x6622, 0x6623, 0x6624, 0x6626, 0x6629, 0x662a, + 0x662b, 0x662c, 0x662e, 0x6630, 0x6631, 0x6633, 0x6639, 0x6637, + 0x6640, 0x6645, 0x6646, 0x664a, 0x664c, 0x6651, 0x664e, 0x6657, + 0x6658, 0x6659, 0x665b, 0x665c, 0x6660, 0x6661, 0x66fb, 0x666a, + 0x666b, 0x666c, 0x667e, 0x6673, 0x6675, 0x667f, 0x6677, 0x6678, + 0x6679, 0x667b, 0x6680, 0x667c, 0x668b, 0x668c, 0x668d, 0x6690, + 0x6692, 0x6699, 0x669a, 0x669b, 0x669c, 0x669f, 0x66a0, 0x66a4, + 0x66ad, 0x66b1, 0x66b2, 0x66b5, 0x66bb, 0x66bf, 0x66c0, 0x66c2, + 0x66c3, 0x66c8, 0x66cc, 0x66ce, 0x66cf, 0x66d4, 0x66db, 0x66df, + 0x66e8, 0x66eb, 0x66ec, 0x66ee, 0x66fa, 0x6705, 0x6707, 0x670e, + 0x6713, 0x6719, 0x671c, 0x6720, 0x6722, 0x6733, 0x673e, 0x6745, + 0x6747, 0x6748, 0x674c, 0x6754, 0x6755, 0x675d, + /* 0x43 */ + 0x6766, 0x676c, 0x676e, 0x6774, 0x6776, 0x677b, 0x6781, 0x6784, + 0x678e, 0x678f, 0x6791, 0x6793, 0x6796, 0x6798, 0x6799, 0x679b, + 0x67b0, 0x67b1, 0x67b2, 0x67b5, 0x67bb, 0x67bc, 0x67bd, 0x67f9, + 0x67c0, 0x67c2, 0x67c3, 0x67c5, 0x67c8, 0x67c9, 0x67d2, 0x67d7, + 0x67d9, 0x67dc, 0x67e1, 0x67e6, 0x67f0, 0x67f2, 0x67f6, 0x67f7, + 0x6852, 0x6814, 0x6819, 0x681d, 0x681f, 0x6828, 0x6827, 0x682c, + 0x682d, 0x682f, 0x6830, 0x6831, 0x6833, 0x683b, 0x683f, 0x6844, + 0x6845, 0x684a, 0x684c, 0x6855, 0x6857, 0x6858, 0x685b, 0x686b, + 0x686e, 0x686f, 0x6870, 0x6871, 0x6872, 0x6875, 0x6879, 0x687a, + 0x687b, 0x687c, 0x6882, 0x6884, 0x6886, 0x6888, 0x6896, 0x6898, + 0x689a, 0x689c, 0x68a1, 0x68a3, 0x68a5, 0x68a9, 0x68aa, 0x68ae, + 0x68b2, 0x68bb, 0x68c5, 0x68c8, 0x68cc, 0x68cf, + /* 0x44 */ + 0x68d0, 0x68d1, 0x68d3, 0x68d6, 0x68d9, 0x68dc, 0x68dd, 0x68e5, + 0x68e8, 0x68ea, 0x68eb, 0x68ec, 0x68ed, 0x68f0, 0x68f1, 0x68f5, + 0x68f6, 0x68fb, 0x68fc, 0x68fd, 0x6906, 0x6909, 0x690a, 0x6910, + 0x6911, 0x6913, 0x6916, 0x6917, 0x6931, 0x6933, 0x6935, 0x6938, + 0x693b, 0x6942, 0x6945, 0x6949, 0x694e, 0x6957, 0x695b, 0x6963, + 0x6964, 0x6965, 0x6966, 0x6968, 0x6969, 0x696c, 0x6970, 0x6971, + 0x6972, 0x697a, 0x697b, 0x697f, 0x6980, 0x698d, 0x6992, 0x6996, + 0x6998, 0x69a1, 0x69a5, 0x69a6, 0x69a8, 0x69ab, 0x69ad, 0x69af, + 0x69b7, 0x69b8, 0x69ba, 0x69bc, 0x69c5, 0x69c8, 0x69d1, 0x69d6, + 0x69d7, 0x69e2, 0x69e5, 0x69ee, 0x69ef, 0x69f1, 0x69f3, 0x69f5, + 0x69fe, 0x6a00, 0x6a01, 0x6a03, 0x6a0f, 0x6a11, 0x6a15, 0x6a1a, + 0x6a1d, 0x6a20, 0x6a24, 0x6a28, 0x6a30, 0x6a32, + /* 0x45 */ + 0x6a34, 0x6a37, 0x6a3b, 0x6a3e, 0x6a3f, 0x6a45, 0x6a46, 0x6a49, + 0x6a4a, 0x6a4e, 0x6a50, 0x6a51, 0x6a52, 0x6a55, 0x6a56, 0x6a5b, + 0x6a64, 0x6a67, 0x6a6a, 0x6a71, 0x6a73, 0x6a7e, 0x6a81, 0x6a83, + 0x6a86, 0x6a87, 0x6a89, 0x6a8b, 0x6a91, 0x6a9b, 0x6a9d, 0x6a9e, + 0x6a9f, 0x6aa5, 0x6aab, 0x6aaf, 0x6ab0, 0x6ab1, 0x6ab4, 0x6abd, + 0x6abe, 0x6abf, 0x6ac6, 0x6ac9, 0x6ac8, 0x6acc, 0x6ad0, 0x6ad4, + 0x6ad5, 0x6ad6, 0x6adc, 0x6add, 0x6ae4, 0x6ae7, 0x6aec, 0x6af0, + 0x6af1, 0x6af2, 0x6afc, 0x6afd, 0x6b02, 0x6b03, 0x6b06, 0x6b07, + 0x6b09, 0x6b0f, 0x6b10, 0x6b11, 0x6b17, 0x6b1b, 0x6b1e, 0x6b24, + 0x6b28, 0x6b2b, 0x6b2c, 0x6b2f, 0x6b35, 0x6b36, 0x6b3b, 0x6b3f, + 0x6b46, 0x6b4a, 0x6b4d, 0x6b52, 0x6b56, 0x6b58, 0x6b5d, 0x6b60, + 0x6b67, 0x6b6b, 0x6b6e, 0x6b70, 0x6b75, 0x6b7d, + /* 0x46 */ + 0x6b7e, 0x6b82, 0x6b85, 0x6b97, 0x6b9b, 0x6b9f, 0x6ba0, 0x6ba2, + 0x6ba3, 0x6ba8, 0x6ba9, 0x6bac, 0x6bad, 0x6bae, 0x6bb0, 0x6bb8, + 0x6bb9, 0x6bbd, 0x6bbe, 0x6bc3, 0x6bc4, 0x6bc9, 0x6bcc, 0x6bd6, + 0x6bda, 0x6be1, 0x6be3, 0x6be6, 0x6be7, 0x6bee, 0x6bf1, 0x6bf7, + 0x6bf9, 0x6bff, 0x6c02, 0x6c04, 0x6c05, 0x6c09, 0x6c0d, 0x6c0e, + 0x6c10, 0x6c12, 0x6c19, 0x6c1f, 0x6c26, 0x6c27, 0x6c28, 0x6c2c, + 0x6c2e, 0x6c33, 0x6c35, 0x6c36, 0x6c3a, 0x6c3b, 0x6c3f, 0x6c4a, + 0x6c4b, 0x6c4d, 0x6c4f, 0x6c52, 0x6c54, 0x6c59, 0x6c5b, 0x6c5c, + 0x6c6b, 0x6c6d, 0x6c6f, 0x6c74, 0x6c76, 0x6c78, 0x6c79, 0x6c7b, + 0x6c85, 0x6c86, 0x6c87, 0x6c89, 0x6c94, 0x6c95, 0x6c97, 0x6c98, + 0x6c9c, 0x6c9f, 0x6cb0, 0x6cb2, 0x6cb4, 0x6cc2, 0x6cc6, 0x6ccd, + 0x6ccf, 0x6cd0, 0x6cd1, 0x6cd2, 0x6cd4, 0x6cd6, + /* 0x47 */ + 0x6cda, 0x6cdc, 0x6ce0, 0x6ce7, 0x6ce9, 0x6ceb, 0x6cec, 0x6cee, + 0x6cf2, 0x6cf4, 0x6d04, 0x6d07, 0x6d0a, 0x6d0e, 0x6d0f, 0x6d11, + 0x6d13, 0x6d1a, 0x6d26, 0x6d27, 0x6d28, 0x6c67, 0x6d2e, 0x6d2f, + 0x6d31, 0x6d39, 0x6d3c, 0x6d3f, 0x6d57, 0x6d5e, 0x6d5f, 0x6d61, + 0x6d65, 0x6d67, 0x6d6f, 0x6d70, 0x6d7c, 0x6d82, 0x6d87, 0x6d91, + 0x6d92, 0x6d94, 0x6d96, 0x6d97, 0x6d98, 0x6daa, 0x6dac, 0x6db4, + 0x6db7, 0x6db9, 0x6dbd, 0x6dbf, 0x6dc4, 0x6dc8, 0x6dca, 0x6dce, + 0x6dcf, 0x6dd6, 0x6ddb, 0x6ddd, 0x6ddf, 0x6de0, 0x6de2, 0x6de5, + 0x6de9, 0x6def, 0x6df0, 0x6df4, 0x6df6, 0x6dfc, 0x6e00, 0x6e04, + 0x6e1e, 0x6e22, 0x6e27, 0x6e32, 0x6e36, 0x6e39, 0x6e3b, 0x6e3c, + 0x6e44, 0x6e45, 0x6e48, 0x6e49, 0x6e4b, 0x6e4f, 0x6e51, 0x6e52, + 0x6e53, 0x6e54, 0x6e57, 0x6e5c, 0x6e5d, 0x6e5e, + /* 0x48 */ + 0x6e62, 0x6e63, 0x6e68, 0x6e73, 0x6e7b, 0x6e7d, 0x6e8d, 0x6e93, + 0x6e99, 0x6ea0, 0x6ea7, 0x6ead, 0x6eae, 0x6eb1, 0x6eb3, 0x6ebb, + 0x6ebf, 0x6ec0, 0x6ec1, 0x6ec3, 0x6ec7, 0x6ec8, 0x6eca, 0x6ecd, + 0x6ece, 0x6ecf, 0x6eeb, 0x6eed, 0x6eee, 0x6ef9, 0x6efb, 0x6efd, + 0x6f04, 0x6f08, 0x6f0a, 0x6f0c, 0x6f0d, 0x6f16, 0x6f18, 0x6f1a, + 0x6f1b, 0x6f26, 0x6f29, 0x6f2a, 0x6f2f, 0x6f30, 0x6f33, 0x6f36, + 0x6f3b, 0x6f3c, 0x6f2d, 0x6f4f, 0x6f51, 0x6f52, 0x6f53, 0x6f57, + 0x6f59, 0x6f5a, 0x6f5d, 0x6f5e, 0x6f61, 0x6f62, 0x6f68, 0x6f6c, + 0x6f7d, 0x6f7e, 0x6f83, 0x6f87, 0x6f88, 0x6f8b, 0x6f8c, 0x6f8d, + 0x6f90, 0x6f92, 0x6f93, 0x6f94, 0x6f96, 0x6f9a, 0x6f9f, 0x6fa0, + 0x6fa5, 0x6fa6, 0x6fa7, 0x6fa8, 0x6fae, 0x6faf, 0x6fb0, 0x6fb5, + 0x6fb6, 0x6fbc, 0x6fc5, 0x6fc7, 0x6fc8, 0x6fca, + /* 0x49 */ + 0x6fda, 0x6fde, 0x6fe8, 0x6fe9, 0x6ff0, 0x6ff5, 0x6ff9, 0x6ffc, + 0x6ffd, 0x7000, 0x7005, 0x7006, 0x7007, 0x700d, 0x7017, 0x7020, + 0x7023, 0x702f, 0x7034, 0x7037, 0x7039, 0x703c, 0x7043, 0x7044, + 0x7048, 0x7049, 0x704a, 0x704b, 0x7054, 0x7055, 0x705d, 0x705e, + 0x704e, 0x7064, 0x7065, 0x706c, 0x706e, 0x7075, 0x7076, 0x707e, + 0x7081, 0x7085, 0x7086, 0x7094, 0x7095, 0x7096, 0x7097, 0x7098, + 0x709b, 0x70a4, 0x70ab, 0x70b0, 0x70b1, 0x70b4, 0x70b7, 0x70ca, + 0x70d1, 0x70d3, 0x70d4, 0x70d5, 0x70d6, 0x70d8, 0x70dc, 0x70e4, + 0x70fa, 0x7103, 0x7104, 0x7105, 0x7106, 0x7107, 0x710b, 0x710c, + 0x710f, 0x711e, 0x7120, 0x712b, 0x712d, 0x712f, 0x7130, 0x7131, + 0x7138, 0x7141, 0x7145, 0x7146, 0x7147, 0x714a, 0x714b, 0x7150, + 0x7152, 0x7157, 0x715a, 0x715c, 0x715e, 0x7160, + /* 0x4a */ + 0x7168, 0x7179, 0x7180, 0x7185, 0x7187, 0x718c, 0x7192, 0x719a, + 0x719b, 0x71a0, 0x71a2, 0x71af, 0x71b0, 0x71b2, 0x71b3, 0x71ba, + 0x71bf, 0x71c0, 0x71c1, 0x71c4, 0x71cb, 0x71cc, 0x71d3, 0x71d6, + 0x71d9, 0x71da, 0x71dc, 0x71f8, 0x71fe, 0x7200, 0x7207, 0x7208, + 0x7209, 0x7213, 0x7217, 0x721a, 0x721d, 0x721f, 0x7224, 0x722b, + 0x722f, 0x7234, 0x7238, 0x7239, 0x7241, 0x7242, 0x7243, 0x7245, + 0x724e, 0x724f, 0x7250, 0x7253, 0x7255, 0x7256, 0x725a, 0x725c, + 0x725e, 0x7260, 0x7263, 0x7268, 0x726b, 0x726e, 0x726f, 0x7271, + 0x7277, 0x7278, 0x727b, 0x727c, 0x727f, 0x7284, 0x7289, 0x728d, + 0x728e, 0x7293, 0x729b, 0x72a8, 0x72ad, 0x72ae, 0x72b1, 0x72b4, + 0x72be, 0x72c1, 0x72c7, 0x72c9, 0x72cc, 0x72d5, 0x72d6, 0x72d8, + 0x72df, 0x72e5, 0x72f3, 0x72f4, 0x72fa, 0x72fb, + /* 0x4b */ + 0x72fe, 0x7302, 0x7304, 0x7305, 0x7307, 0x730b, 0x730d, 0x7312, + 0x7313, 0x7318, 0x7319, 0x731e, 0x7322, 0x7324, 0x7327, 0x7328, + 0x732c, 0x7331, 0x7332, 0x7335, 0x733a, 0x733b, 0x733d, 0x7343, + 0x734d, 0x7350, 0x7352, 0x7356, 0x7358, 0x735d, 0x735e, 0x735f, + 0x7360, 0x7366, 0x7367, 0x7369, 0x736b, 0x736c, 0x736e, 0x736f, + 0x7371, 0x7377, 0x7379, 0x737c, 0x7380, 0x7381, 0x7383, 0x7385, + 0x7386, 0x738e, 0x7390, 0x7393, 0x7395, 0x7397, 0x7398, 0x739c, + 0x739e, 0x739f, 0x73a0, 0x73a2, 0x73a5, 0x73a6, 0x73aa, 0x73ab, + 0x73ad, 0x73b5, 0x73b7, 0x73b9, 0x73bc, 0x73bd, 0x73bf, 0x73c5, + 0x73c6, 0x73c9, 0x73cb, 0x73cc, 0x73cf, 0x73d2, 0x73d3, 0x73d6, + 0x73d9, 0x73dd, 0x73e1, 0x73e3, 0x73e6, 0x73e7, 0x73e9, 0x73f4, + 0x73f5, 0x73f7, 0x73f9, 0x73fa, 0x73fb, 0x73fd, + /* 0x4c */ + 0x73ff, 0x7400, 0x7401, 0x7404, 0x7407, 0x740a, 0x7411, 0x741a, + 0x741b, 0x7424, 0x7426, 0x7428, 0x7429, 0x742a, 0x742b, 0x742c, + 0x742d, 0x742e, 0x742f, 0x7430, 0x7431, 0x7439, 0x7440, 0x7443, + 0x7444, 0x7446, 0x7447, 0x744b, 0x744d, 0x7451, 0x7452, 0x7457, + 0x745d, 0x7462, 0x7466, 0x7467, 0x7468, 0x746b, 0x746d, 0x746e, + 0x7471, 0x7472, 0x7480, 0x7481, 0x7485, 0x7486, 0x7487, 0x7489, + 0x748f, 0x7490, 0x7491, 0x7492, 0x7498, 0x7499, 0x749a, 0x749c, + 0x749f, 0x74a0, 0x74a1, 0x74a3, 0x74a6, 0x74a8, 0x74a9, 0x74aa, + 0x74ab, 0x74ae, 0x74af, 0x74b1, 0x74b2, 0x74b5, 0x74b9, 0x74bb, + 0x74bf, 0x74c8, 0x74c9, 0x74cc, 0x74d0, 0x74d3, 0x74d8, 0x74da, + 0x74db, 0x74de, 0x74df, 0x74e4, 0x74e8, 0x74ea, 0x74eb, 0x74ef, + 0x74f4, 0x74fa, 0x74fb, 0x74fc, 0x74ff, 0x7506, + /* 0x4d */ + 0x7512, 0x7516, 0x7517, 0x7520, 0x7521, 0x7524, 0x7527, 0x7529, + 0x752a, 0x752f, 0x7536, 0x7539, 0x753d, 0x753e, 0x753f, 0x7540, + 0x7543, 0x7547, 0x7548, 0x754e, 0x7550, 0x7552, 0x7557, 0x755e, + 0x755f, 0x7561, 0x756f, 0x7571, 0x7579, 0x757a, 0x757b, 0x757c, + 0x757d, 0x757e, 0x7581, 0x7585, 0x7590, 0x7592, 0x7593, 0x7595, + 0x7599, 0x759c, 0x75a2, 0x75a4, 0x75b4, 0x75ba, 0x75bf, 0x75c0, + 0x75c1, 0x75c4, 0x75c6, 0x75cc, 0x75ce, 0x75cf, 0x75d7, 0x75dc, + 0x75df, 0x75e0, 0x75e1, 0x75e4, 0x75e7, 0x75ec, 0x75ee, 0x75ef, + 0x75f1, 0x75f9, 0x7600, 0x7602, 0x7603, 0x7604, 0x7607, 0x7608, + 0x760a, 0x760c, 0x760f, 0x7612, 0x7613, 0x7615, 0x7616, 0x7619, + 0x761b, 0x761c, 0x761d, 0x761e, 0x7623, 0x7625, 0x7626, 0x7629, + 0x762d, 0x7632, 0x7633, 0x7635, 0x7638, 0x7639, + /* 0x4e */ + 0x763a, 0x763c, 0x764a, 0x7640, 0x7641, 0x7643, 0x7644, 0x7645, + 0x7649, 0x764b, 0x7655, 0x7659, 0x765f, 0x7664, 0x7665, 0x766d, + 0x766e, 0x766f, 0x7671, 0x7674, 0x7681, 0x7685, 0x768c, 0x768d, + 0x7695, 0x769b, 0x769c, 0x769d, 0x769f, 0x76a0, 0x76a2, 0x76a3, + 0x76a4, 0x76a5, 0x76a6, 0x76a7, 0x76a8, 0x76aa, 0x76ad, 0x76bd, + 0x76c1, 0x76c5, 0x76c9, 0x76cb, 0x76cc, 0x76ce, 0x76d4, 0x76d9, + 0x76e0, 0x76e6, 0x76e8, 0x76ec, 0x76f0, 0x76f1, 0x76f6, 0x76f9, + 0x76fc, 0x7700, 0x7706, 0x770a, 0x770e, 0x7712, 0x7714, 0x7715, + 0x7717, 0x7719, 0x771a, 0x771c, 0x7722, 0x7728, 0x772d, 0x772e, + 0x772f, 0x7734, 0x7735, 0x7736, 0x7739, 0x773d, 0x773e, 0x7742, + 0x7745, 0x7746, 0x774a, 0x774d, 0x774e, 0x774f, 0x7752, 0x7756, + 0x7757, 0x775c, 0x775e, 0x775f, 0x7760, 0x7762, + /* 0x4f */ + 0x7764, 0x7767, 0x776a, 0x776c, 0x7770, 0x7772, 0x7773, 0x7774, + 0x777a, 0x777d, 0x7780, 0x7784, 0x778c, 0x778d, 0x7794, 0x7795, + 0x7796, 0x779a, 0x779f, 0x77a2, 0x77a7, 0x77aa, 0x77ae, 0x77af, + 0x77b1, 0x77b5, 0x77be, 0x77c3, 0x77c9, 0x77d1, 0x77d2, 0x77d5, + 0x77d9, 0x77de, 0x77df, 0x77e0, 0x77e4, 0x77e6, 0x77ea, 0x77ec, + 0x77f0, 0x77f1, 0x77f4, 0x77f8, 0x77fb, 0x7805, 0x7806, 0x7809, + 0x780d, 0x780e, 0x7811, 0x781d, 0x7821, 0x7822, 0x7823, 0x782d, + 0x782e, 0x7830, 0x7835, 0x7837, 0x7843, 0x7844, 0x7847, 0x7848, + 0x784c, 0x784e, 0x7852, 0x785c, 0x785e, 0x7860, 0x7861, 0x7863, + 0x7864, 0x7868, 0x786a, 0x786e, 0x787a, 0x787e, 0x788a, 0x788f, + 0x7894, 0x7898, 0x78a1, 0x789d, 0x789e, 0x789f, 0x78a4, 0x78a8, + 0x78ac, 0x78ad, 0x78b0, 0x78b1, 0x78b2, 0x78b3, + /* 0x50 */ + 0x78bb, 0x78bd, 0x78bf, 0x78c7, 0x78c8, 0x78c9, 0x78cc, 0x78ce, + 0x78d2, 0x78d3, 0x78d5, 0x78d6, 0x78e4, 0x78db, 0x78df, 0x78e0, + 0x78e1, 0x78e6, 0x78ea, 0x78f2, 0x78f3, 0x7900, 0x78f6, 0x78f7, + 0x78fa, 0x78fb, 0x78ff, 0x7906, 0x790c, 0x7910, 0x791a, 0x791c, + 0x791e, 0x791f, 0x7920, 0x7925, 0x7927, 0x7929, 0x792d, 0x7931, + 0x7934, 0x7935, 0x793b, 0x793d, 0x793f, 0x7944, 0x7945, 0x7946, + 0x794a, 0x794b, 0x794f, 0x7951, 0x7954, 0x7958, 0x795b, 0x795c, + 0x7967, 0x7969, 0x796b, 0x7972, 0x7979, 0x797b, 0x797c, 0x797e, + 0x798b, 0x798c, 0x7991, 0x7993, 0x7994, 0x7995, 0x7996, 0x7998, + 0x799b, 0x799c, 0x79a1, 0x79a8, 0x79a9, 0x79ab, 0x79af, 0x79b1, + 0x79b4, 0x79b8, 0x79bb, 0x79c2, 0x79c4, 0x79c7, 0x79c8, 0x79ca, + 0x79cf, 0x79d4, 0x79d6, 0x79da, 0x79dd, 0x79de, + /* 0x51 */ + 0x79e0, 0x79e2, 0x79e5, 0x79ea, 0x79eb, 0x79ed, 0x79f1, 0x79f8, + 0x79fc, 0x7a02, 0x7a03, 0x7a07, 0x7a09, 0x7a0a, 0x7a0c, 0x7a11, + 0x7a15, 0x7a1b, 0x7a1e, 0x7a21, 0x7a27, 0x7a2b, 0x7a2d, 0x7a2f, + 0x7a30, 0x7a34, 0x7a35, 0x7a38, 0x7a39, 0x7a3a, 0x7a44, 0x7a45, + 0x7a47, 0x7a48, 0x7a4c, 0x7a55, 0x7a56, 0x7a59, 0x7a5c, 0x7a5d, + 0x7a5f, 0x7a60, 0x7a65, 0x7a67, 0x7a6a, 0x7a6d, 0x7a75, 0x7a78, + 0x7a7e, 0x7a80, 0x7a82, 0x7a85, 0x7a86, 0x7a8a, 0x7a8b, 0x7a90, + 0x7a91, 0x7a94, 0x7a9e, 0x7aa0, 0x7aa3, 0x7aac, 0x7ab3, 0x7ab5, + 0x7ab9, 0x7abb, 0x7abc, 0x7ac6, 0x7ac9, 0x7acc, 0x7ace, 0x7ad1, + 0x7adb, 0x7ae8, 0x7ae9, 0x7aeb, 0x7aec, 0x7af1, 0x7af4, 0x7afb, + 0x7afd, 0x7afe, 0x7b07, 0x7b14, 0x7b1f, 0x7b23, 0x7b27, 0x7b29, + 0x7b2a, 0x7b2b, 0x7b2d, 0x7b2e, 0x7b2f, 0x7b30, + /* 0x52 */ + 0x7b31, 0x7b34, 0x7b3d, 0x7b3f, 0x7b40, 0x7b41, 0x7b47, 0x7b4e, + 0x7b55, 0x7b60, 0x7b64, 0x7b66, 0x7b69, 0x7b6a, 0x7b6d, 0x7b6f, + 0x7b72, 0x7b73, 0x7b77, 0x7b84, 0x7b89, 0x7b8e, 0x7b90, 0x7b91, + 0x7b96, 0x7b9b, 0x7b9e, 0x7ba0, 0x7ba5, 0x7bac, 0x7baf, 0x7bb0, + 0x7bb2, 0x7bb5, 0x7bb6, 0x7bba, 0x7bbb, 0x7bbc, 0x7bbd, 0x7bc2, + 0x7bc5, 0x7bc8, 0x7bca, 0x7bd4, 0x7bd6, 0x7bd7, 0x7bd9, 0x7bda, + 0x7bdb, 0x7be8, 0x7bea, 0x7bf2, 0x7bf4, 0x7bf5, 0x7bf8, 0x7bf9, + 0x7bfa, 0x7bfc, 0x7bfe, 0x7c01, 0x7c02, 0x7c03, 0x7c04, 0x7c06, + 0x7c09, 0x7c0b, 0x7c0c, 0x7c0e, 0x7c0f, 0x7c19, 0x7c1b, 0x7c20, + 0x7c25, 0x7c26, 0x7c28, 0x7c2c, 0x7c31, 0x7c33, 0x7c34, 0x7c36, + 0x7c39, 0x7c3a, 0x7c46, 0x7c4a, 0x7c55, 0x7c51, 0x7c52, 0x7c53, + 0x7c59, 0x7c5a, 0x7c5b, 0x7c5c, 0x7c5d, 0x7c5e, + /* 0x53 */ + 0x7c61, 0x7c63, 0x7c67, 0x7c69, 0x7c6d, 0x7c6e, 0x7c70, 0x7c72, + 0x7c79, 0x7c7c, 0x7c7d, 0x7c86, 0x7c87, 0x7c8f, 0x7c94, 0x7c9e, + 0x7ca0, 0x7ca6, 0x7cb0, 0x7cb6, 0x7cb7, 0x7cba, 0x7cbb, 0x7cbc, + 0x7cbf, 0x7cc4, 0x7cc7, 0x7cc8, 0x7cc9, 0x7ccd, 0x7ccf, 0x7cd3, + 0x7cd4, 0x7cd5, 0x7cd7, 0x7cd9, 0x7cda, 0x7cdd, 0x7ce6, 0x7ce9, + 0x7ceb, 0x7cf5, 0x7d03, 0x7d07, 0x7d08, 0x7d09, 0x7d0f, 0x7d11, + 0x7d12, 0x7d13, 0x7d16, 0x7d1d, 0x7d1e, 0x7d23, 0x7d26, 0x7d2a, + 0x7d2d, 0x7d31, 0x7d3c, 0x7d3d, 0x7d3e, 0x7d40, 0x7d41, 0x7d47, + 0x7d48, 0x7d4d, 0x7d51, 0x7d53, 0x7d57, 0x7d59, 0x7d5a, 0x7d5c, + 0x7d5d, 0x7d65, 0x7d67, 0x7d6a, 0x7d70, 0x7d78, 0x7d7a, 0x7d7b, + 0x7d7f, 0x7d81, 0x7d82, 0x7d83, 0x7d85, 0x7d86, 0x7d88, 0x7d8b, + 0x7d8c, 0x7d8d, 0x7d91, 0x7d96, 0x7d97, 0x7d9d, + /* 0x54 */ + 0x7d9e, 0x7da6, 0x7da7, 0x7daa, 0x7db3, 0x7db6, 0x7db7, 0x7db9, + 0x7dc2, 0x7dc3, 0x7dc4, 0x7dc5, 0x7dc6, 0x7dcc, 0x7dcd, 0x7dce, + 0x7dd7, 0x7dd9, 0x7e00, 0x7de2, 0x7de5, 0x7de6, 0x7dea, 0x7deb, + 0x7ded, 0x7df1, 0x7df5, 0x7df6, 0x7df9, 0x7dfa, 0x7e08, 0x7e10, + 0x7e11, 0x7e15, 0x7e17, 0x7e1c, 0x7e1d, 0x7e20, 0x7e27, 0x7e28, + 0x7e2c, 0x7e2d, 0x7e2f, 0x7e33, 0x7e36, 0x7e3f, 0x7e44, 0x7e45, + 0x7e47, 0x7e4e, 0x7e50, 0x7e52, 0x7e58, 0x7e5f, 0x7e61, 0x7e62, + 0x7e65, 0x7e6b, 0x7e6e, 0x7e6f, 0x7e73, 0x7e78, 0x7e7e, 0x7e81, + 0x7e86, 0x7e87, 0x7e8a, 0x7e8d, 0x7e91, 0x7e95, 0x7e98, 0x7e9a, + 0x7e9d, 0x7e9e, 0x7f3c, 0x7f3b, 0x7f3d, 0x7f3e, 0x7f3f, 0x7f43, + 0x7f44, 0x7f47, 0x7f4f, 0x7f52, 0x7f53, 0x7f5b, 0x7f5c, 0x7f5d, + 0x7f61, 0x7f63, 0x7f64, 0x7f65, 0x7f66, 0x7f6d, + /* 0x55 */ + 0x7f71, 0x7f7d, 0x7f7e, 0x7f7f, 0x7f80, 0x7f8b, 0x7f8d, 0x7f8f, + 0x7f90, 0x7f91, 0x7f96, 0x7f97, 0x7f9c, 0x7fa1, 0x7fa2, 0x7fa6, + 0x7faa, 0x7fad, 0x7fb4, 0x7fbc, 0x7fbf, 0x7fc0, 0x7fc3, 0x7fc8, + 0x7fce, 0x7fcf, 0x7fdb, 0x7fdf, 0x7fe3, 0x7fe5, 0x7fe8, 0x7fec, + 0x7fee, 0x7fef, 0x7ff2, 0x7ffa, 0x7ffd, 0x7ffe, 0x7fff, 0x8007, + 0x8008, 0x800a, 0x800d, 0x800e, 0x800f, 0x8011, 0x8013, 0x8014, + 0x8016, 0x801d, 0x801e, 0x801f, 0x8020, 0x8024, 0x8026, 0x802c, + 0x802e, 0x8030, 0x8034, 0x8035, 0x8037, 0x8039, 0x803a, 0x803c, + 0x803e, 0x8040, 0x8044, 0x8060, 0x8064, 0x8066, 0x806d, 0x8071, + 0x8075, 0x8081, 0x8088, 0x808e, 0x809c, 0x809e, 0x80a6, 0x80a7, + 0x80ab, 0x80b8, 0x80b9, 0x80c8, 0x80cd, 0x80cf, 0x80d2, 0x80d4, + 0x80d5, 0x80d7, 0x80d8, 0x80e0, 0x80ed, 0x80ee, + /* 0x56 */ + 0x80f0, 0x80f2, 0x80f3, 0x80f6, 0x80f9, 0x80fa, 0x80fe, 0x8103, + 0x810b, 0x8116, 0x8117, 0x8118, 0x811c, 0x811e, 0x8120, 0x8124, + 0x8127, 0x812c, 0x8130, 0x8135, 0x813a, 0x813c, 0x8145, 0x8147, + 0x814a, 0x814c, 0x8152, 0x8157, 0x8160, 0x8161, 0x8167, 0x8168, + 0x8169, 0x816d, 0x816f, 0x8177, 0x8181, 0x8190, 0x8184, 0x8185, + 0x8186, 0x818b, 0x818e, 0x8196, 0x8198, 0x819b, 0x819e, 0x81a2, + 0x81ae, 0x81b2, 0x81b4, 0x81bb, 0x81cb, 0x81c3, 0x81c5, 0x81ca, + 0x81ce, 0x81cf, 0x81d5, 0x81d7, 0x81db, 0x81dd, 0x81de, 0x81e1, + 0x81e4, 0x81eb, 0x81ec, 0x81f0, 0x81f1, 0x81f2, 0x81f5, 0x81f6, + 0x81f8, 0x81f9, 0x81fd, 0x81ff, 0x8200, 0x8203, 0x820f, 0x8213, + 0x8214, 0x8219, 0x821a, 0x821d, 0x8221, 0x8222, 0x8228, 0x8232, + 0x8234, 0x823a, 0x8243, 0x8244, 0x8245, 0x8246, + /* 0x57 */ + 0x824b, 0x824e, 0x824f, 0x8251, 0x8256, 0x825c, 0x8260, 0x8263, + 0x8267, 0x826d, 0x8274, 0x827b, 0x827d, 0x827f, 0x8280, 0x8281, + 0x8283, 0x8284, 0x8287, 0x8289, 0x828a, 0x828e, 0x8291, 0x8294, + 0x8296, 0x8298, 0x829a, 0x829b, 0x82a0, 0x82a1, 0x82a3, 0x82a4, + 0x82a7, 0x82a8, 0x82a9, 0x82aa, 0x82ae, 0x82b0, 0x82b2, 0x82b4, + 0x82b7, 0x82ba, 0x82bc, 0x82be, 0x82bf, 0x82c6, 0x82d0, 0x82d5, + 0x82da, 0x82e0, 0x82e2, 0x82e4, 0x82e8, 0x82ea, 0x82ed, 0x82ef, + 0x82f6, 0x82f7, 0x82fd, 0x82fe, 0x8300, 0x8301, 0x8307, 0x8308, + 0x830a, 0x830b, 0x8354, 0x831b, 0x831d, 0x831e, 0x831f, 0x8321, + 0x8322, 0x832c, 0x832d, 0x832e, 0x8330, 0x8333, 0x8337, 0x833a, + 0x833c, 0x833d, 0x8342, 0x8343, 0x8344, 0x8347, 0x834d, 0x834e, + 0x8351, 0x8355, 0x8356, 0x8357, 0x8370, 0x8378, + /* 0x58 */ + 0x837d, 0x837f, 0x8380, 0x8382, 0x8384, 0x8386, 0x838d, 0x8392, + 0x8394, 0x8395, 0x8398, 0x8399, 0x839b, 0x839c, 0x839d, 0x83a6, + 0x83a7, 0x83a9, 0x83ac, 0x83be, 0x83bf, 0x83c0, 0x83c7, 0x83c9, + 0x83cf, 0x83d0, 0x83d1, 0x83d4, 0x83dd, 0x8353, 0x83e8, 0x83ea, + 0x83f6, 0x83f8, 0x83f9, 0x83fc, 0x8401, 0x8406, 0x840a, 0x840f, + 0x8411, 0x8415, 0x8419, 0x83ad, 0x842f, 0x8439, 0x8445, 0x8447, + 0x8448, 0x844a, 0x844d, 0x844f, 0x8451, 0x8452, 0x8456, 0x8458, + 0x8459, 0x845a, 0x845c, 0x8460, 0x8464, 0x8465, 0x8467, 0x846a, + 0x8470, 0x8473, 0x8474, 0x8476, 0x8478, 0x847c, 0x847d, 0x8481, + 0x8485, 0x8492, 0x8493, 0x8495, 0x849e, 0x84a6, 0x84a8, 0x84a9, + 0x84aa, 0x84af, 0x84b1, 0x84b4, 0x84ba, 0x84bd, 0x84be, 0x84c0, + 0x84c2, 0x84c7, 0x84c8, 0x84cc, 0x84cf, 0x84d3, + /* 0x59 */ + 0x84dc, 0x84e7, 0x84ea, 0x84ef, 0x84f0, 0x84f1, 0x84f2, 0x84f7, + 0x8532, 0x84fa, 0x84fb, 0x84fd, 0x8502, 0x8503, 0x8507, 0x850c, + 0x850e, 0x8510, 0x851c, 0x851e, 0x8522, 0x8523, 0x8524, 0x8525, + 0x8527, 0x852a, 0x852b, 0x852f, 0x8533, 0x8534, 0x8536, 0x853f, + 0x8546, 0x854f, 0x8550, 0x8551, 0x8552, 0x8553, 0x8556, 0x8559, + 0x855c, 0x855d, 0x855e, 0x855f, 0x8560, 0x8561, 0x8562, 0x8564, + 0x856b, 0x856f, 0x8579, 0x857a, 0x857b, 0x857d, 0x857f, 0x8581, + 0x8585, 0x8586, 0x8589, 0x858b, 0x858c, 0x858f, 0x8593, 0x8598, + 0x859d, 0x859f, 0x85a0, 0x85a2, 0x85a5, 0x85a7, 0x85b4, 0x85b6, + 0x85b7, 0x85b8, 0x85bc, 0x85bd, 0x85be, 0x85bf, 0x85c2, 0x85c7, + 0x85ca, 0x85cb, 0x85ce, 0x85ad, 0x85d8, 0x85da, 0x85df, 0x85e0, + 0x85e6, 0x85e8, 0x85ed, 0x85f3, 0x85f6, 0x85fc, + /* 0x5a */ + 0x85ff, 0x8600, 0x8604, 0x8605, 0x860d, 0x860e, 0x8610, 0x8611, + 0x8612, 0x8618, 0x8619, 0x861b, 0x861e, 0x8621, 0x8627, 0x8629, + 0x8636, 0x8638, 0x863a, 0x863c, 0x863d, 0x8640, 0x8642, 0x8646, + 0x8652, 0x8653, 0x8656, 0x8657, 0x8658, 0x8659, 0x865d, 0x8660, + 0x8661, 0x8662, 0x8663, 0x8664, 0x8669, 0x866c, 0x866f, 0x8675, + 0x8676, 0x8677, 0x867a, 0x868d, 0x8691, 0x8696, 0x8698, 0x869a, + 0x869c, 0x86a1, 0x86a6, 0x86a7, 0x86a8, 0x86ad, 0x86b1, 0x86b3, + 0x86b4, 0x86b5, 0x86b7, 0x86b8, 0x86b9, 0x86bf, 0x86c0, 0x86c1, + 0x86c3, 0x86c5, 0x86d1, 0x86d2, 0x86d5, 0x86d7, 0x86da, 0x86dc, + 0x86e0, 0x86e3, 0x86e5, 0x86e7, 0x8688, 0x86fa, 0x86fc, 0x86fd, + 0x8704, 0x8705, 0x8707, 0x870b, 0x870e, 0x870f, 0x8710, 0x8713, + 0x8714, 0x8719, 0x871e, 0x871f, 0x8721, 0x8723, + /* 0x5b */ + 0x8728, 0x872e, 0x872f, 0x8731, 0x8732, 0x8739, 0x873a, 0x873c, + 0x873d, 0x873e, 0x8740, 0x8743, 0x8745, 0x874d, 0x8758, 0x875d, + 0x8761, 0x8764, 0x8765, 0x876f, 0x8771, 0x8772, 0x877b, 0x8783, + 0x8784, 0x8785, 0x8786, 0x8787, 0x8788, 0x8789, 0x878b, 0x878c, + 0x8790, 0x8793, 0x8795, 0x8797, 0x8798, 0x8799, 0x879e, 0x87a0, + 0x87a3, 0x87a7, 0x87ac, 0x87ad, 0x87ae, 0x87b1, 0x87b5, 0x87be, + 0x87bf, 0x87c1, 0x87c8, 0x87c9, 0x87ca, 0x87ce, 0x87d5, 0x87d6, + 0x87d9, 0x87da, 0x87dc, 0x87df, 0x87e2, 0x87e3, 0x87e4, 0x87ea, + 0x87eb, 0x87ed, 0x87f1, 0x87f3, 0x87f8, 0x87fa, 0x87ff, 0x8801, + 0x8803, 0x8806, 0x8809, 0x880a, 0x880b, 0x8810, 0x8819, 0x8812, + 0x8813, 0x8814, 0x8818, 0x881a, 0x881b, 0x881c, 0x881e, 0x881f, + 0x8828, 0x882d, 0x882e, 0x8830, 0x8832, 0x8835, + /* 0x5c */ + 0x883a, 0x883c, 0x8841, 0x8843, 0x8845, 0x8848, 0x8849, 0x884a, + 0x884b, 0x884e, 0x8851, 0x8855, 0x8856, 0x8858, 0x885a, 0x885c, + 0x885f, 0x8860, 0x8864, 0x8869, 0x8871, 0x8879, 0x887b, 0x8880, + 0x8898, 0x889a, 0x889b, 0x889c, 0x889f, 0x88a0, 0x88a8, 0x88aa, + 0x88ba, 0x88bd, 0x88be, 0x88c0, 0x88ca, 0x88cb, 0x88cc, 0x88cd, + 0x88ce, 0x88d1, 0x88d2, 0x88d3, 0x88db, 0x88de, 0x88e7, 0x88ef, + 0x88f0, 0x88f1, 0x88f5, 0x88f7, 0x8901, 0x8906, 0x890d, 0x890e, + 0x890f, 0x8915, 0x8916, 0x8918, 0x8919, 0x891a, 0x891c, 0x8920, + 0x8926, 0x8927, 0x8928, 0x8930, 0x8931, 0x8932, 0x8935, 0x8939, + 0x893a, 0x893e, 0x8940, 0x8942, 0x8945, 0x8946, 0x8949, 0x894f, + 0x8952, 0x8957, 0x895a, 0x895b, 0x895c, 0x8961, 0x8962, 0x8963, + 0x896b, 0x896e, 0x8970, 0x8973, 0x8975, 0x897a, + /* 0x5d */ + 0x897b, 0x897c, 0x897d, 0x8989, 0x898d, 0x8990, 0x8994, 0x8995, + 0x899b, 0x899c, 0x899f, 0x89a0, 0x89a5, 0x89b0, 0x89b4, 0x89b5, + 0x89b6, 0x89b7, 0x89bc, 0x89d4, 0x89d5, 0x89d6, 0x89d7, 0x89d8, + 0x89e5, 0x89e9, 0x89eb, 0x89ed, 0x89f1, 0x89f3, 0x89f6, 0x89f9, + 0x89fd, 0x89ff, 0x8a04, 0x8a05, 0x8a07, 0x8a0f, 0x8a11, 0x8a12, + 0x8a14, 0x8a15, 0x8a1e, 0x8a20, 0x8a22, 0x8a24, 0x8a26, 0x8a2b, + 0x8a2c, 0x8a2f, 0x8a35, 0x8a37, 0x8a3d, 0x8a3e, 0x8a40, 0x8a43, + 0x8a45, 0x8a47, 0x8a49, 0x8a4d, 0x8a4e, 0x8a53, 0x8a56, 0x8a57, + 0x8a58, 0x8a5c, 0x8a5d, 0x8a61, 0x8a65, 0x8a67, 0x8a75, 0x8a76, + 0x8a77, 0x8a79, 0x8a7a, 0x8a7b, 0x8a7e, 0x8a7f, 0x8a80, 0x8a83, + 0x8a86, 0x8a8b, 0x8a8f, 0x8a90, 0x8a92, 0x8a96, 0x8a97, 0x8a99, + 0x8a9f, 0x8aa7, 0x8aa9, 0x8aae, 0x8aaf, 0x8ab3, + /* 0x5e */ + 0x8ab6, 0x8ab7, 0x8abb, 0x8abe, 0x8ac3, 0x8ac6, 0x8ac8, 0x8ac9, + 0x8aca, 0x8ad1, 0x8ad3, 0x8ad4, 0x8ad5, 0x8ad7, 0x8add, 0x8adf, + 0x8aec, 0x8af0, 0x8af4, 0x8af5, 0x8af6, 0x8afc, 0x8aff, 0x8b05, + 0x8b06, 0x8b0b, 0x8b11, 0x8b1c, 0x8b1e, 0x8b1f, 0x8b0a, 0x8b2d, + 0x8b30, 0x8b37, 0x8b3c, 0x8b42, 0x8b43, 0x8b44, 0x8b45, 0x8b46, + 0x8b48, 0x8b52, 0x8b53, 0x8b54, 0x8b59, 0x8b4d, 0x8b5e, 0x8b63, + 0x8b6d, 0x8b76, 0x8b78, 0x8b79, 0x8b7c, 0x8b7e, 0x8b81, 0x8b84, + 0x8b85, 0x8b8b, 0x8b8d, 0x8b8f, 0x8b94, 0x8b95, 0x8b9c, 0x8b9e, + 0x8b9f, 0x8c38, 0x8c39, 0x8c3d, 0x8c3e, 0x8c45, 0x8c47, 0x8c49, + 0x8c4b, 0x8c4f, 0x8c51, 0x8c53, 0x8c54, 0x8c57, 0x8c58, 0x8c5b, + 0x8c5d, 0x8c59, 0x8c63, 0x8c64, 0x8c66, 0x8c68, 0x8c69, 0x8c6d, + 0x8c73, 0x8c75, 0x8c76, 0x8c7b, 0x8c7e, 0x8c86, + /* 0x5f */ + 0x8c87, 0x8c8b, 0x8c90, 0x8c92, 0x8c93, 0x8c99, 0x8c9b, 0x8c9c, + 0x8ca4, 0x8cb9, 0x8cba, 0x8cc5, 0x8cc6, 0x8cc9, 0x8ccb, 0x8ccf, + 0x8cd6, 0x8cd5, 0x8cd9, 0x8cdd, 0x8ce1, 0x8ce8, 0x8cec, 0x8cef, + 0x8cf0, 0x8cf2, 0x8cf5, 0x8cf7, 0x8cf8, 0x8cfe, 0x8cff, 0x8d01, + 0x8d03, 0x8d09, 0x8d12, 0x8d17, 0x8d1b, 0x8d65, 0x8d69, 0x8d6c, + 0x8d6e, 0x8d7f, 0x8d82, 0x8d84, 0x8d88, 0x8d8d, 0x8d90, 0x8d91, + 0x8d95, 0x8d9e, 0x8d9f, 0x8da0, 0x8da6, 0x8dab, 0x8dac, 0x8daf, + 0x8db2, 0x8db5, 0x8db7, 0x8db9, 0x8dbb, 0x8dc0, 0x8dc5, 0x8dc6, + 0x8dc7, 0x8dc8, 0x8dca, 0x8dce, 0x8dd1, 0x8dd4, 0x8dd5, 0x8dd7, + 0x8dd9, 0x8de4, 0x8de5, 0x8de7, 0x8dec, 0x8df0, 0x8dbc, 0x8df1, + 0x8df2, 0x8df4, 0x8dfd, 0x8e01, 0x8e04, 0x8e05, 0x8e06, 0x8e0b, + 0x8e11, 0x8e14, 0x8e16, 0x8e20, 0x8e21, 0x8e22, + /* 0x60 */ + 0x8e23, 0x8e26, 0x8e27, 0x8e31, 0x8e33, 0x8e36, 0x8e37, 0x8e38, + 0x8e39, 0x8e3d, 0x8e40, 0x8e41, 0x8e4b, 0x8e4d, 0x8e4e, 0x8e4f, + 0x8e54, 0x8e5b, 0x8e5c, 0x8e5d, 0x8e5e, 0x8e61, 0x8e62, 0x8e69, + 0x8e6c, 0x8e6d, 0x8e6f, 0x8e70, 0x8e71, 0x8e79, 0x8e7a, 0x8e7b, + 0x8e82, 0x8e83, 0x8e89, 0x8e90, 0x8e92, 0x8e95, 0x8e9a, 0x8e9b, + 0x8e9d, 0x8e9e, 0x8ea2, 0x8ea7, 0x8ea9, 0x8ead, 0x8eae, 0x8eb3, + 0x8eb5, 0x8eba, 0x8ebb, 0x8ec0, 0x8ec1, 0x8ec3, 0x8ec4, 0x8ec7, + 0x8ecf, 0x8ed1, 0x8ed4, 0x8edc, 0x8ee8, 0x8eee, 0x8ef0, 0x8ef1, + 0x8ef7, 0x8ef9, 0x8efa, 0x8eed, 0x8f00, 0x8f02, 0x8f07, 0x8f08, + 0x8f0f, 0x8f10, 0x8f16, 0x8f17, 0x8f18, 0x8f1e, 0x8f20, 0x8f21, + 0x8f23, 0x8f25, 0x8f27, 0x8f28, 0x8f2c, 0x8f2d, 0x8f2e, 0x8f34, + 0x8f35, 0x8f36, 0x8f37, 0x8f3a, 0x8f40, 0x8f41, + /* 0x61 */ + 0x8f43, 0x8f47, 0x8f4f, 0x8f51, 0x8f52, 0x8f53, 0x8f54, 0x8f55, + 0x8f58, 0x8f5d, 0x8f5e, 0x8f65, 0x8f9d, 0x8fa0, 0x8fa1, 0x8fa4, + 0x8fa5, 0x8fa6, 0x8fb5, 0x8fb6, 0x8fb8, 0x8fbe, 0x8fc0, 0x8fc1, + 0x8fc6, 0x8fca, 0x8fcb, 0x8fcd, 0x8fd0, 0x8fd2, 0x8fd3, 0x8fd5, + 0x8fe0, 0x8fe3, 0x8fe4, 0x8fe8, 0x8fee, 0x8ff1, 0x8ff5, 0x8ff6, + 0x8ffb, 0x8ffe, 0x9002, 0x9004, 0x9008, 0x900c, 0x9018, 0x901b, + 0x9028, 0x9029, 0x902f, 0x902a, 0x902c, 0x902d, 0x9033, 0x9034, + 0x9037, 0x903f, 0x9043, 0x9044, 0x904c, 0x905b, 0x905d, 0x9062, + 0x9066, 0x9067, 0x906c, 0x9070, 0x9074, 0x9079, 0x9085, 0x9088, + 0x908b, 0x908c, 0x908e, 0x9090, 0x9095, 0x9097, 0x9098, 0x9099, + 0x909b, 0x90a0, 0x90a1, 0x90a2, 0x90a5, 0x90b0, 0x90b2, 0x90b3, + 0x90b4, 0x90b6, 0x90bd, 0x90cc, 0x90be, 0x90c3, + /* 0x62 */ + 0x90c4, 0x90c5, 0x90c7, 0x90c8, 0x90d5, 0x90d7, 0x90d8, 0x90d9, + 0x90dc, 0x90dd, 0x90df, 0x90e5, 0x90d2, 0x90f6, 0x90eb, 0x90ef, + 0x90f0, 0x90f4, 0x90fe, 0x90ff, 0x9100, 0x9104, 0x9105, 0x9106, + 0x9108, 0x910d, 0x9110, 0x9114, 0x9116, 0x9117, 0x9118, 0x911a, + 0x911c, 0x911e, 0x9120, 0x9125, 0x9122, 0x9123, 0x9127, 0x9129, + 0x912e, 0x912f, 0x9131, 0x9134, 0x9136, 0x9137, 0x9139, 0x913a, + 0x913c, 0x913d, 0x9143, 0x9147, 0x9148, 0x914f, 0x9153, 0x9157, + 0x9159, 0x915a, 0x915b, 0x9161, 0x9164, 0x9167, 0x916d, 0x9174, + 0x9179, 0x917a, 0x917b, 0x9181, 0x9183, 0x9185, 0x9186, 0x918a, + 0x918e, 0x9191, 0x9193, 0x9194, 0x9195, 0x9198, 0x919e, 0x91a1, + 0x91a6, 0x91a8, 0x91ac, 0x91ad, 0x91ae, 0x91b0, 0x91b1, 0x91b2, + 0x91b3, 0x91b6, 0x91bb, 0x91bc, 0x91bd, 0x91bf, + /* 0x63 */ + 0x91c2, 0x91c3, 0x91c5, 0x91d3, 0x91d4, 0x91d7, 0x91d9, 0x91da, + 0x91de, 0x91e4, 0x91e5, 0x91e9, 0x91ea, 0x91ec, 0x91ed, 0x91ee, + 0x91ef, 0x91f0, 0x91f1, 0x91f7, 0x91f9, 0x91fb, 0x91fd, 0x9200, + 0x9201, 0x9204, 0x9205, 0x9206, 0x9207, 0x9209, 0x920a, 0x920c, + 0x9210, 0x9212, 0x9213, 0x9216, 0x9218, 0x921c, 0x921d, 0x9223, + 0x9224, 0x9225, 0x9226, 0x9228, 0x922e, 0x922f, 0x9230, 0x9233, + 0x9235, 0x9236, 0x9238, 0x9239, 0x923a, 0x923c, 0x923e, 0x9240, + 0x9242, 0x9243, 0x9246, 0x9247, 0x924a, 0x924d, 0x924e, 0x924f, + 0x9251, 0x9258, 0x9259, 0x925c, 0x925d, 0x9260, 0x9261, 0x9265, + 0x9267, 0x9268, 0x9269, 0x926e, 0x926f, 0x9270, 0x9275, 0x9276, + 0x9277, 0x9278, 0x9279, 0x927b, 0x927c, 0x927d, 0x927f, 0x9288, + 0x9289, 0x928a, 0x928d, 0x928e, 0x9292, 0x9297, + /* 0x64 */ + 0x9299, 0x929f, 0x92a0, 0x92a4, 0x92a5, 0x92a7, 0x92a8, 0x92ab, + 0x92af, 0x92b2, 0x92b6, 0x92b8, 0x92ba, 0x92bb, 0x92bc, 0x92bd, + 0x92bf, 0x92c0, 0x92c1, 0x92c2, 0x92c3, 0x92c5, 0x92c6, 0x92c7, + 0x92c8, 0x92cb, 0x92cc, 0x92cd, 0x92ce, 0x92d0, 0x92d3, 0x92d5, + 0x92d7, 0x92d8, 0x92d9, 0x92dc, 0x92dd, 0x92df, 0x92e0, 0x92e1, + 0x92e3, 0x92e5, 0x92e7, 0x92e8, 0x92ec, 0x92ee, 0x92f0, 0x92f9, + 0x92fb, 0x92ff, 0x9300, 0x9302, 0x9308, 0x930d, 0x9311, 0x9314, + 0x9315, 0x931c, 0x931d, 0x931e, 0x931f, 0x9321, 0x9324, 0x9325, + 0x9327, 0x9329, 0x932a, 0x9333, 0x9334, 0x9336, 0x9337, 0x9347, + 0x9348, 0x9349, 0x9350, 0x9351, 0x9352, 0x9355, 0x9357, 0x9358, + 0x935a, 0x935e, 0x9364, 0x9365, 0x9367, 0x9369, 0x936a, 0x936d, + 0x936f, 0x9370, 0x9371, 0x9373, 0x9374, 0x9376, + /* 0x65 */ + 0x937a, 0x937d, 0x937f, 0x9380, 0x9381, 0x9382, 0x9388, 0x938a, + 0x938b, 0x938d, 0x938f, 0x9392, 0x9395, 0x9398, 0x939b, 0x939e, + 0x93a1, 0x93a3, 0x93a4, 0x93a6, 0x93a8, 0x93ab, 0x93b4, 0x93b5, + 0x93b6, 0x93ba, 0x93a9, 0x93c1, 0x93c4, 0x93c5, 0x93c6, 0x93c7, + 0x93c9, 0x93ca, 0x93cb, 0x93cc, 0x93cd, 0x93d3, 0x93d9, 0x93dc, + 0x93de, 0x93df, 0x93e2, 0x93e6, 0x93e7, 0x93f9, 0x93f7, 0x93f8, + 0x93fa, 0x93fb, 0x93fd, 0x9401, 0x9402, 0x9404, 0x9408, 0x9409, + 0x940d, 0x940e, 0x940f, 0x9415, 0x9416, 0x9417, 0x941f, 0x942e, + 0x942f, 0x9431, 0x9432, 0x9433, 0x9434, 0x943b, 0x943f, 0x943d, + 0x9443, 0x9445, 0x9448, 0x944a, 0x944c, 0x9455, 0x9459, 0x945c, + 0x945f, 0x9461, 0x9463, 0x9468, 0x946b, 0x946d, 0x946e, 0x946f, + 0x9471, 0x9472, 0x9484, 0x9483, 0x9578, 0x9579, + /* 0x66 */ + 0x957e, 0x9584, 0x9588, 0x958c, 0x958d, 0x958e, 0x959d, 0x959e, + 0x959f, 0x95a1, 0x95a6, 0x95a9, 0x95ab, 0x95ac, 0x95b4, 0x95b6, + 0x95ba, 0x95bd, 0x95bf, 0x95c6, 0x95c8, 0x95c9, 0x95cb, 0x95d0, + 0x95d1, 0x95d2, 0x95d3, 0x95d9, 0x95da, 0x95dd, 0x95de, 0x95df, + 0x95e0, 0x95e4, 0x95e6, 0x961d, 0x961e, 0x9622, 0x9624, 0x9625, + 0x9626, 0x962c, 0x9631, 0x9633, 0x9637, 0x9638, 0x9639, 0x963a, + 0x963c, 0x963d, 0x9641, 0x9652, 0x9654, 0x9656, 0x9657, 0x9658, + 0x9661, 0x966e, 0x9674, 0x967b, 0x967c, 0x967e, 0x967f, 0x9681, + 0x9682, 0x9683, 0x9684, 0x9689, 0x9691, 0x9696, 0x969a, 0x969d, + 0x969f, 0x96a4, 0x96a5, 0x96a6, 0x96a9, 0x96ae, 0x96af, 0x96b3, + 0x96ba, 0x96ca, 0x96d2, 0x5db2, 0x96d8, 0x96da, 0x96dd, 0x96de, + 0x96df, 0x96e9, 0x96ef, 0x96f1, 0x96fa, 0x9702, + /* 0x67 */ + 0x9703, 0x9705, 0x9709, 0x971a, 0x971b, 0x971d, 0x9721, 0x9722, + 0x9723, 0x9728, 0x9731, 0x9733, 0x9741, 0x9743, 0x974a, 0x974e, + 0x974f, 0x9755, 0x9757, 0x9758, 0x975a, 0x975b, 0x9763, 0x9767, + 0x976a, 0x976e, 0x9773, 0x9776, 0x9777, 0x9778, 0x977b, 0x977d, + 0x977f, 0x9780, 0x9789, 0x9795, 0x9796, 0x9797, 0x9799, 0x979a, + 0x979e, 0x979f, 0x97a2, 0x97ac, 0x97ae, 0x97b1, 0x97b2, 0x97b5, + 0x97b6, 0x97b8, 0x97b9, 0x97ba, 0x97bc, 0x97be, 0x97bf, 0x97c1, + 0x97c4, 0x97c5, 0x97c7, 0x97c9, 0x97ca, 0x97cc, 0x97cd, 0x97ce, + 0x97d0, 0x97d1, 0x97d4, 0x97d7, 0x97d8, 0x97d9, 0x97dd, 0x97de, + 0x97e0, 0x97db, 0x97e1, 0x97e4, 0x97ef, 0x97f1, 0x97f4, 0x97f7, + 0x97f8, 0x97fa, 0x9807, 0x980a, 0x9819, 0x980d, 0x980e, 0x9814, + 0x9816, 0x981c, 0x981e, 0x9820, 0x9823, 0x9826, + /* 0x68 */ + 0x982b, 0x982e, 0x982f, 0x9830, 0x9832, 0x9833, 0x9835, 0x9825, + 0x983e, 0x9844, 0x9847, 0x984a, 0x9851, 0x9852, 0x9853, 0x9856, + 0x9857, 0x9859, 0x985a, 0x9862, 0x9863, 0x9865, 0x9866, 0x986a, + 0x986c, 0x98ab, 0x98ad, 0x98ae, 0x98b0, 0x98b4, 0x98b7, 0x98b8, + 0x98ba, 0x98bb, 0x98bf, 0x98c2, 0x98c5, 0x98c8, 0x98cc, 0x98e1, + 0x98e3, 0x98e5, 0x98e6, 0x98e7, 0x98ea, 0x98f3, 0x98f6, 0x9902, + 0x9907, 0x9908, 0x9911, 0x9915, 0x9916, 0x9917, 0x991a, 0x991b, + 0x991c, 0x991f, 0x9922, 0x9926, 0x9927, 0x992b, 0x9931, 0x9932, + 0x9933, 0x9934, 0x9935, 0x9939, 0x993a, 0x993b, 0x993c, 0x9940, + 0x9941, 0x9946, 0x9947, 0x9948, 0x994d, 0x994e, 0x9954, 0x9958, + 0x9959, 0x995b, 0x995c, 0x995e, 0x995f, 0x9960, 0x999b, 0x999d, + 0x999f, 0x99a6, 0x99b0, 0x99b1, 0x99b2, 0x99b5, + /* 0x69 */ + 0x99b9, 0x99ba, 0x99bd, 0x99bf, 0x99c3, 0x99c9, 0x99d3, 0x99d4, + 0x99d9, 0x99da, 0x99dc, 0x99de, 0x99e7, 0x99ea, 0x99eb, 0x99ec, + 0x99f0, 0x99f4, 0x99f5, 0x99f9, 0x99fd, 0x99fe, 0x9a02, 0x9a03, + 0x9a04, 0x9a0b, 0x9a0c, 0x9a10, 0x9a11, 0x9a16, 0x9a1e, 0x9a20, + 0x9a22, 0x9a23, 0x9a24, 0x9a27, 0x9a2d, 0x9a2e, 0x9a33, 0x9a35, + 0x9a36, 0x9a38, 0x9a47, 0x9a41, 0x9a44, 0x9a4a, 0x9a4b, 0x9a4c, + 0x9a4e, 0x9a51, 0x9a54, 0x9a56, 0x9a5d, 0x9aaa, 0x9aac, 0x9aae, + 0x9aaf, 0x9ab2, 0x9ab4, 0x9ab5, 0x9ab6, 0x9ab9, 0x9abb, 0x9abe, + 0x9abf, 0x9ac1, 0x9ac3, 0x9ac6, 0x9ac8, 0x9ace, 0x9ad0, 0x9ad2, + 0x9ad5, 0x9ad6, 0x9ad7, 0x9adb, 0x9adc, 0x9ae0, 0x9ae4, 0x9ae5, + 0x9ae7, 0x9ae9, 0x9aec, 0x9af2, 0x9af3, 0x9af5, 0x9af9, 0x9afa, + 0x9afd, 0x9aff, 0x9b00, 0x9b01, 0x9b02, 0x9b03, + /* 0x6a */ + 0x9b04, 0x9b05, 0x9b08, 0x9b09, 0x9b0b, 0x9b0c, 0x9b0d, 0x9b0e, + 0x9b10, 0x9b12, 0x9b16, 0x9b19, 0x9b1b, 0x9b1c, 0x9b20, 0x9b26, + 0x9b2b, 0x9b2d, 0x9b33, 0x9b34, 0x9b35, 0x9b37, 0x9b39, 0x9b3a, + 0x9b3d, 0x9b48, 0x9b4b, 0x9b4c, 0x9b55, 0x9b56, 0x9b57, 0x9b5b, + 0x9b5e, 0x9b61, 0x9b63, 0x9b65, 0x9b66, 0x9b68, 0x9b6a, 0x9b6b, + 0x9b6c, 0x9b6d, 0x9b6e, 0x9b73, 0x9b75, 0x9b77, 0x9b78, 0x9b79, + 0x9b7f, 0x9b80, 0x9b84, 0x9b85, 0x9b86, 0x9b87, 0x9b89, 0x9b8a, + 0x9b8b, 0x9b8d, 0x9b8f, 0x9b90, 0x9b94, 0x9b9a, 0x9b9d, 0x9b9e, + 0x9ba6, 0x9ba7, 0x9ba9, 0x9bac, 0x9bb0, 0x9bb1, 0x9bb2, 0x9bb7, + 0x9bb8, 0x9bbb, 0x9bbc, 0x9bbe, 0x9bbf, 0x9bc1, 0x9bc7, 0x9bc8, + 0x9bce, 0x9bd0, 0x9bd7, 0x9bd8, 0x9bdd, 0x9bdf, 0x9be5, 0x9be7, + 0x9bea, 0x9beb, 0x9bef, 0x9bf3, 0x9bf7, 0x9bf8, + /* 0x6b */ + 0x9bf9, 0x9bfa, 0x9bfd, 0x9bff, 0x9c00, 0x9c02, 0x9c0b, 0x9c0f, + 0x9c11, 0x9c16, 0x9c18, 0x9c19, 0x9c1a, 0x9c1c, 0x9c1e, 0x9c22, + 0x9c23, 0x9c26, 0x9c27, 0x9c28, 0x9c29, 0x9c2a, 0x9c31, 0x9c35, + 0x9c36, 0x9c37, 0x9c3d, 0x9c41, 0x9c43, 0x9c44, 0x9c45, 0x9c49, + 0x9c4a, 0x9c4e, 0x9c4f, 0x9c50, 0x9c53, 0x9c54, 0x9c56, 0x9c58, + 0x9c5b, 0x9c5d, 0x9c5e, 0x9c5f, 0x9c63, 0x9c69, 0x9c6a, 0x9c5c, + 0x9c6b, 0x9c68, 0x9c6e, 0x9c70, 0x9c72, 0x9c75, 0x9c77, 0x9c7b, + 0x9ce6, 0x9cf2, 0x9cf7, 0x9cf9, 0x9d0b, 0x9d02, 0x9d11, 0x9d17, + 0x9d18, 0x9d1c, 0x9d1d, 0x9d1e, 0x9d2f, 0x9d30, 0x9d32, 0x9d33, + 0x9d34, 0x9d3a, 0x9d3c, 0x9d45, 0x9d3d, 0x9d42, 0x9d43, 0x9d47, + 0x9d4a, 0x9d53, 0x9d54, 0x9d5f, 0x9d63, 0x9d62, 0x9d65, 0x9d69, + 0x9d6a, 0x9d6b, 0x9d70, 0x9d76, 0x9d77, 0x9d7b, + /* 0x6c */ + 0x9d7c, 0x9d7e, 0x9d83, 0x9d84, 0x9d86, 0x9d8a, 0x9d8d, 0x9d8e, + 0x9d92, 0x9d93, 0x9d95, 0x9d96, 0x9d97, 0x9d98, 0x9da1, 0x9daa, + 0x9dac, 0x9dae, 0x9db1, 0x9db5, 0x9db9, 0x9dbc, 0x9dbf, 0x9dc3, + 0x9dc7, 0x9dc9, 0x9dca, 0x9dd4, 0x9dd5, 0x9dd6, 0x9dd7, 0x9dda, + 0x9dde, 0x9ddf, 0x9de0, 0x9de5, 0x9de7, 0x9de9, 0x9deb, 0x9dee, + 0x9df0, 0x9df3, 0x9df4, 0x9dfe, 0x9e0a, 0x9e02, 0x9e07, 0x9e0e, + 0x9e10, 0x9e11, 0x9e12, 0x9e15, 0x9e16, 0x9e19, 0x9e1c, 0x9e1d, + 0x9e7a, 0x9e7b, 0x9e7c, 0x9e80, 0x9e82, 0x9e83, 0x9e84, 0x9e85, + 0x9e87, 0x9e8e, 0x9e8f, 0x9e96, 0x9e98, 0x9e9b, 0x9e9e, 0x9ea4, + 0x9ea8, 0x9eac, 0x9eae, 0x9eaf, 0x9eb0, 0x9eb3, 0x9eb4, 0x9eb5, + 0x9ec6, 0x9ec8, 0x9ecb, 0x9ed5, 0x9edf, 0x9ee4, 0x9ee7, 0x9eec, + 0x9eed, 0x9eee, 0x9ef0, 0x9ef1, 0x9ef2, 0x9ef5, + /* 0x6d */ + 0x9ef8, 0x9eff, 0x9f02, 0x9f03, 0x9f09, 0x9f0f, 0x9f10, 0x9f11, + 0x9f12, 0x9f14, 0x9f16, 0x9f17, 0x9f19, 0x9f1a, 0x9f1b, 0x9f1f, + 0x9f22, 0x9f26, 0x9f2a, 0x9f2b, 0x9f2f, 0x9f31, 0x9f32, 0x9f34, + 0x9f37, 0x9f39, 0x9f3a, 0x9f3c, 0x9f3d, 0x9f3f, 0x9f41, 0x9f43, + 0x9f44, 0x9f45, 0x9f46, 0x9f47, 0x9f53, 0x9f55, 0x9f56, 0x9f57, + 0x9f58, 0x9f5a, 0x9f5d, 0x9f5e, 0x9f68, 0x9f69, 0x9f6d, 0x9f6e, + 0x9f6f, 0x9f70, 0x9f71, 0x9f73, 0x9f75, 0x9f7a, 0x9f7d, 0x9f8f, + 0x9f90, 0x9f91, 0x9f92, 0x9f94, 0x9f96, 0x9f97, 0x9f9e, 0x9fa1, + 0x9fa2, 0x9fa3, 0x9fa5, +}; + +static int +jisx0212_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c1 = (s[0] & 0x7F); + if ((c1 == 0x22) || (c1 >= 0x26 && c1 <= 0x27) || (c1 >= 0x29 && c1 <= 0x2b) || (c1 >= 0x30 && c1 <= 0x6d)) { + if (n >= 2) { + unsigned char c2 = (s[1] & 0x7F); + if (c2 >= 0x21 && c2 < 0x7f) { + unsigned int i = 94 * (c1 - 0x21) + (c2 - 0x21); + unsigned short wc = 0xfffd; + if (i < 470) { + if (i < 175) + wc = jisx0212_2uni_page22[i-94]; + } else if (i < 752) { + if (i < 658) + wc = jisx0212_2uni_page26[i-470]; + } else if (i < 1410) { + if (i < 1027) + wc = jisx0212_2uni_page29[i-752]; + } else { + if (i < 7211) + wc = jisx0212_2uni_page30[i-1410]; + } + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 2; + } + } + return RET_ILSEQ; + } + return RET_TOOFEW(0); + } + return RET_ILSEQ; +} + +static const unsigned short jisx0212_2charset[6067] = { + 0x2237, 0x2242, 0x2270, 0x2243, 0x226d, 0x226c, 0x226e, 0x2234, + 0x2231, 0x226b, 0x2244, 0x2a22, 0x2a21, 0x2a24, 0x2a2a, 0x2a23, + 0x2a29, 0x2921, 0x2a2e, 0x2a32, 0x2a31, 0x2a34, 0x2a33, 0x2a40, + 0x2a3f, 0x2a42, 0x2a41, 0x2a50, 0x2a52, 0x2a51, 0x2a54, 0x2a58, + 0x2a53, 0x292c, 0x2a63, 0x2a62, 0x2a65, 0x2a64, 0x2a72, 0x2930, + 0x294e, 0x2b22, 0x2b21, 0x2b24, 0x2b2a, 0x2b23, 0x2b29, 0x2941, + 0x2b2e, 0x2b32, 0x2b31, 0x2b34, 0x2b33, 0x2b40, 0x2b3f, 0x2b42, + 0x2b41, 0x2943, 0x2b50, 0x2b52, 0x2b51, 0x2b54, 0x2b58, 0x2b53, + 0x294c, 0x2b63, 0x2b62, 0x2b65, 0x2b64, 0x2b72, 0x2950, 0x2b73, + 0x2a27, 0x2b27, 0x2a25, 0x2b25, 0x2a28, 0x2b28, 0x2a2b, 0x2b2b, + 0x2a2c, 0x2b2c, 0x2a2f, 0x2b2f, 0x2a2d, 0x2b2d, 0x2a30, 0x2b30, + 0x2922, 0x2942, 0x2a37, 0x2b37, 0x2a36, 0x2b36, 0x2a38, 0x2b38, + 0x2a35, 0x2b35, 0x2a3a, 0x2b3a, 0x2a3b, 0x2b3b, 0x2a3d, 0x2b3d, + 0x2a3c, 0x2a3e, 0x2b3e, 0x2924, 0x2944, 0x2a47, 0x2b47, 0x2a45, + 0x2b45, 0x2a46, 0x2b46, 0x2a44, 0x2945, 0x2926, 0x2946, 0x2a48, + 0x2b48, 0x2a49, 0x2b49, 0x2947, 0x2a4a, 0x2b4a, 0x2a4c, 0x2b4c, + 0x2a4b, 0x2b4b, 0x2929, 0x2949, 0x2928, 0x2948, 0x2a4d, 0x2b4d, + 0x2a4f, 0x2b4f, 0x2a4e, 0x2b4e, 0x294a, 0x292b, 0x294b, 0x2a57, + 0x2b57, 0x2a56, 0x2b56, 0x292d, 0x294d, 0x2a59, 0x2b59, 0x2a5b, + 0x2b5b, 0x2a5a, 0x2b5a, 0x2a5c, 0x2b5c, 0x2a5d, 0x2b5d, 0x2a5f, + 0x2b5f, 0x2a5e, 0x2b5e, 0x2a61, 0x2b61, 0x2a60, 0x2b60, 0x292f, + 0x294f, 0x2a6c, 0x2b6c, 0x2a69, 0x2b69, 0x2a66, 0x2b66, 0x2a6b, + 0x2b6b, 0x2a68, 0x2b68, 0x2a6a, 0x2b6a, 0x2a71, 0x2b71, 0x2a74, + 0x2b74, 0x2a73, 0x2a75, 0x2b75, 0x2a77, 0x2b77, 0x2a76, 0x2b76, + 0x2a26, 0x2b26, 0x2a43, 0x2b43, 0x2a55, 0x2b55, 0x2a67, 0x2b67, + 0x2a70, 0x2b70, 0x2a6d, 0x2b6d, 0x2a6f, 0x2b6f, 0x2a6e, 0x2b6e, + 0x2b39, 0x2230, 0x222f, 0x2232, 0x2236, 0x2235, 0x2233, 0x2238, + 0x2239, 0x2661, 0x2662, 0x2663, 0x2664, 0x2667, 0x2669, 0x266c, + 0x2676, 0x2665, 0x266a, 0x2671, 0x2672, 0x2673, 0x2674, 0x267b, + 0x2678, 0x2675, 0x267a, 0x2677, 0x2679, 0x267c, 0x2742, 0x2743, + 0x2744, 0x2745, 0x2746, 0x2747, 0x2748, 0x2749, 0x274a, 0x274b, + 0x274c, 0x274d, 0x274e, 0x2772, 0x2773, 0x2774, 0x2775, 0x2776, + 0x2777, 0x2778, 0x2779, 0x277a, 0x277b, 0x277c, 0x277d, 0x277e, + 0x2271, 0x226f, 0x3021, 0x3022, 0x3023, 0x3024, 0x3025, 0x3026, + 0x3027, 0x3028, 0x3029, 0x302a, 0x302b, 0x302c, 0x302d, 0x302e, + 0x302f, 0x3030, 0x3031, 0x3032, 0x3033, 0x3034, 0x3035, 0x3036, + 0x3037, 0x3038, 0x3039, 0x303a, 0x303b, 0x303c, 0x303d, 0x303e, + 0x303f, 0x3040, 0x3041, 0x3042, 0x3043, 0x3044, 0x3045, 0x3046, + 0x3047, 0x3048, 0x3049, 0x304a, 0x304b, 0x304c, 0x304d, 0x304e, + 0x304f, 0x3050, 0x3051, 0x3052, 0x3053, 0x3054, 0x3055, 0x3056, + 0x3057, 0x3058, 0x3059, 0x305a, 0x305b, 0x305c, 0x305d, 0x305e, + 0x3060, 0x3061, 0x3062, 0x3063, 0x3064, 0x3065, 0x3066, 0x3067, + 0x3068, 0x3069, 0x306a, 0x306b, 0x306c, 0x306d, 0x306e, 0x306f, + 0x3070, 0x305f, 0x3071, 0x3072, 0x3073, 0x3074, 0x3075, 0x3076, + 0x3077, 0x3078, 0x3079, 0x307a, 0x307b, 0x307c, 0x307d, 0x307e, + 0x3121, 0x3122, 0x3123, 0x3124, 0x3125, 0x3126, 0x3127, 0x3128, + 0x3129, 0x312a, 0x312b, 0x312c, 0x312d, 0x312e, 0x312f, 0x3130, + 0x3131, 0x3132, 0x3133, 0x3134, 0x3135, 0x3136, 0x3137, 0x3138, + 0x3139, 0x313a, 0x313b, 0x313c, 0x313d, 0x313e, 0x313f, 0x3140, + 0x3141, 0x3142, 0x3143, 0x3144, 0x3145, 0x3146, 0x3147, 0x3148, + 0x3149, 0x314a, 0x314b, 0x314c, 0x314d, 0x314e, 0x314f, 0x3150, + 0x3151, 0x3152, 0x3153, 0x3154, 0x3155, 0x3156, 0x3157, 0x3158, + 0x3159, 0x315a, 0x315b, 0x315c, 0x315d, 0x315e, 0x3176, 0x315f, + 0x3160, 0x3161, 0x3162, 0x3163, 0x3164, 0x3165, 0x3166, 0x3167, + 0x3168, 0x3169, 0x316a, 0x316b, 0x316c, 0x316d, 0x316e, 0x316f, + 0x3170, 0x3171, 0x3172, 0x3173, 0x3174, 0x3175, 0x3177, 0x3178, + 0x3179, 0x317a, 0x317b, 0x317c, 0x317d, 0x317e, 0x3221, 0x3222, + 0x3223, 0x3224, 0x3225, 0x3226, 0x3227, 0x3228, 0x3229, 0x322a, + 0x322b, 0x322c, 0x322d, 0x322e, 0x322f, 0x3230, 0x3231, 0x3232, + 0x3233, 0x3234, 0x3235, 0x3236, 0x3237, 0x3238, 0x3239, 0x323a, + 0x323b, 0x323c, 0x323d, 0x323e, 0x323f, 0x3240, 0x3241, 0x3242, + 0x3243, 0x3244, 0x3245, 0x3251, 0x3246, 0x3247, 0x3248, 0x3249, + 0x324a, 0x324b, 0x324c, 0x324d, 0x324e, 0x324f, 0x3250, 0x3252, + 0x3253, 0x3254, 0x3255, 0x3256, 0x3257, 0x3258, 0x3259, 0x325a, + 0x325b, 0x325c, 0x325d, 0x325e, 0x325f, 0x3260, 0x3261, 0x3262, + 0x3263, 0x3264, 0x3265, 0x3266, 0x3267, 0x3268, 0x3269, 0x326a, + 0x326b, 0x326c, 0x326d, 0x326e, 0x326f, 0x3270, 0x3271, 0x3272, + 0x3273, 0x3274, 0x3275, 0x3276, 0x3277, 0x3278, 0x3279, 0x327a, + 0x327b, 0x327c, 0x327d, 0x327e, 0x3321, 0x3322, 0x3323, 0x3324, + 0x3325, 0x3326, 0x3327, 0x3328, 0x3329, 0x332a, 0x332b, 0x332c, + 0x332d, 0x332e, 0x332f, 0x3330, 0x3331, 0x3332, 0x3333, 0x3334, + 0x3335, 0x3336, 0x3337, 0x3338, 0x3339, 0x333a, 0x333b, 0x333c, + 0x333d, 0x333e, 0x333f, 0x3340, 0x3341, 0x3342, 0x3343, 0x3344, + 0x3345, 0x3346, 0x3347, 0x3348, 0x3349, 0x334a, 0x334b, 0x334c, + 0x334d, 0x334e, 0x334f, 0x3350, 0x3351, 0x3352, 0x3353, 0x3354, + 0x3355, 0x3356, 0x3357, 0x3358, 0x3359, 0x335a, 0x335b, 0x335c, + 0x335d, 0x335e, 0x335f, 0x3360, 0x3361, 0x3362, 0x3363, 0x3364, + 0x3365, 0x3366, 0x3367, 0x3368, 0x3369, 0x336a, 0x336b, 0x336c, + 0x336d, 0x336e, 0x336f, 0x3370, 0x3371, 0x3372, 0x3373, 0x3374, + 0x3375, 0x3376, 0x3377, 0x3378, 0x3379, 0x337a, 0x337b, 0x337c, + 0x337d, 0x337e, 0x3421, 0x3422, 0x3423, 0x3424, 0x3425, 0x3426, + 0x3427, 0x3428, 0x3429, 0x342a, 0x342b, 0x342c, 0x342d, 0x342e, + 0x342f, 0x3430, 0x3431, 0x3432, 0x3433, 0x3434, 0x3435, 0x3436, + 0x3438, 0x3437, 0x3439, 0x343a, 0x343b, 0x343c, 0x343d, 0x343e, + 0x343f, 0x3440, 0x3441, 0x3442, 0x3443, 0x3444, 0x3445, 0x3446, + 0x3447, 0x3448, 0x3449, 0x344a, 0x344b, 0x344c, 0x344d, 0x344e, + 0x344f, 0x3450, 0x3451, 0x3452, 0x3453, 0x3454, 0x3455, 0x3456, + 0x3457, 0x3458, 0x3459, 0x345a, 0x345b, 0x345c, 0x345d, 0x345e, + 0x345f, 0x3460, 0x3461, 0x3462, 0x3463, 0x3464, 0x3465, 0x3466, + 0x3467, 0x3468, 0x3469, 0x346a, 0x346b, 0x346c, 0x346d, 0x346e, + 0x346f, 0x3470, 0x3471, 0x3472, 0x3473, 0x3474, 0x3475, 0x3476, + 0x3477, 0x3478, 0x3479, 0x347a, 0x347b, 0x347c, 0x347d, 0x347e, + 0x3521, 0x3522, 0x3523, 0x3524, 0x3525, 0x3526, 0x3527, 0x3528, + 0x3529, 0x352a, 0x352b, 0x352c, 0x352d, 0x352e, 0x352f, 0x3530, + 0x3531, 0x3532, 0x3533, 0x3534, 0x3535, 0x3536, 0x3537, 0x3538, + 0x3539, 0x353a, 0x353b, 0x353c, 0x353d, 0x353e, 0x353f, 0x3540, + 0x3541, 0x3542, 0x3543, 0x3544, 0x3545, 0x3546, 0x3547, 0x3548, + 0x3549, 0x354a, 0x354b, 0x354c, 0x354d, 0x354e, 0x354f, 0x3550, + 0x3551, 0x3552, 0x3553, 0x3554, 0x3555, 0x3556, 0x3557, 0x3558, + 0x3559, 0x355a, 0x355b, 0x355c, 0x355d, 0x355e, 0x355f, 0x3560, + 0x3561, 0x3562, 0x3563, 0x3564, 0x3565, 0x3566, 0x3567, 0x3568, + 0x3569, 0x356a, 0x356b, 0x356c, 0x356d, 0x356e, 0x356f, 0x3570, + 0x3571, 0x3572, 0x3573, 0x3574, 0x3575, 0x3576, 0x3577, 0x3578, + 0x3579, 0x357a, 0x357b, 0x357c, 0x357d, 0x357e, 0x3621, 0x3622, + 0x3623, 0x3624, 0x3625, 0x3626, 0x3627, 0x3628, 0x3629, 0x362a, + 0x362b, 0x362c, 0x362d, 0x362e, 0x362f, 0x3630, 0x3631, 0x3632, + 0x3633, 0x3634, 0x3635, 0x3636, 0x3637, 0x3638, 0x3639, 0x363a, + 0x363b, 0x363c, 0x363d, 0x363e, 0x363f, 0x3640, 0x3641, 0x3642, + 0x3643, 0x3644, 0x3645, 0x3646, 0x3647, 0x3648, 0x3649, 0x364a, + 0x364b, 0x364c, 0x364d, 0x364e, 0x364f, 0x3650, 0x3651, 0x3652, + 0x3653, 0x3654, 0x3655, 0x3656, 0x3657, 0x3658, 0x3659, 0x365a, + 0x365b, 0x365c, 0x365d, 0x365e, 0x365f, 0x3660, 0x3661, 0x3662, + 0x3663, 0x3664, 0x3665, 0x3666, 0x3667, 0x3668, 0x3669, 0x366a, + 0x366b, 0x366c, 0x366d, 0x3670, 0x3671, 0x366e, 0x366f, 0x3672, + 0x3673, 0x3674, 0x3675, 0x3676, 0x3677, 0x3678, 0x3679, 0x367a, + 0x367b, 0x367d, 0x367e, 0x367c, 0x3721, 0x3722, 0x3723, 0x3724, + 0x3725, 0x3726, 0x3727, 0x3728, 0x3729, 0x372a, 0x372b, 0x372c, + 0x372d, 0x372e, 0x372f, 0x3730, 0x3731, 0x3732, 0x3733, 0x3734, + 0x3735, 0x3736, 0x3737, 0x3738, 0x3739, 0x373a, 0x373b, 0x373c, + 0x373d, 0x373e, 0x373f, 0x3740, 0x3741, 0x3742, 0x3743, 0x3744, + 0x3745, 0x3746, 0x3747, 0x3748, 0x3749, 0x374a, 0x374b, 0x374c, + 0x374d, 0x374e, 0x374f, 0x3750, 0x3751, 0x3752, 0x3753, 0x3754, + 0x3755, 0x3756, 0x3757, 0x3760, 0x3758, 0x3759, 0x375a, 0x375b, + 0x375c, 0x375d, 0x375e, 0x375f, 0x3761, 0x3762, 0x3763, 0x3764, + 0x3765, 0x3766, 0x3767, 0x3768, 0x3769, 0x376a, 0x376b, 0x376c, + 0x376d, 0x377e, 0x376e, 0x376f, 0x3770, 0x3771, 0x3772, 0x3773, + 0x3774, 0x3775, 0x3776, 0x3777, 0x3778, 0x3779, 0x377a, 0x377b, + 0x377c, 0x377d, 0x3821, 0x3822, 0x3823, 0x3824, 0x3825, 0x3826, + 0x3827, 0x3828, 0x3829, 0x382a, 0x382b, 0x382c, 0x382d, 0x382e, + 0x382f, 0x3830, 0x3831, 0x3832, 0x3833, 0x3834, 0x3835, 0x3836, + 0x3837, 0x3838, 0x3839, 0x383a, 0x383b, 0x383c, 0x383d, 0x383e, + 0x383f, 0x3840, 0x3841, 0x3842, 0x3843, 0x3844, 0x3845, 0x3846, + 0x3847, 0x3848, 0x3849, 0x384a, 0x384b, 0x384c, 0x384d, 0x384e, + 0x3850, 0x3851, 0x384f, 0x3852, 0x3853, 0x3854, 0x3855, 0x3856, + 0x3857, 0x3858, 0x3859, 0x385a, 0x385b, 0x385c, 0x385d, 0x385e, + 0x385f, 0x3860, 0x3861, 0x3862, 0x3863, 0x3864, 0x3865, 0x3867, + 0x3868, 0x3869, 0x386a, 0x386b, 0x386c, 0x386d, 0x386e, 0x386f, + 0x3870, 0x3871, 0x3872, 0x3873, 0x3874, 0x3875, 0x3876, 0x3877, + 0x3878, 0x3879, 0x387a, 0x387b, 0x387c, 0x387d, 0x387e, 0x3921, + 0x3922, 0x3923, 0x3924, 0x3925, 0x3926, 0x3927, 0x3928, 0x3929, + 0x392a, 0x392b, 0x392c, 0x392d, 0x392e, 0x392f, 0x3930, 0x3931, + 0x3932, 0x3933, 0x3934, 0x3935, 0x3936, 0x3937, 0x3938, 0x3939, + 0x393a, 0x393b, 0x393c, 0x393d, 0x393e, 0x393f, 0x3940, 0x3941, + 0x3942, 0x3943, 0x3944, 0x3945, 0x3946, 0x3947, 0x3948, 0x3949, + 0x394a, 0x394b, 0x394c, 0x394d, 0x394e, 0x394f, 0x3950, 0x3951, + 0x3952, 0x3953, 0x3954, 0x3955, 0x3956, 0x3957, 0x3958, 0x3959, + 0x395a, 0x395b, 0x395c, 0x395d, 0x395e, 0x395f, 0x3960, 0x3961, + 0x3962, 0x3963, 0x3964, 0x3965, 0x3966, 0x3967, 0x3968, 0x3969, + 0x396a, 0x396b, 0x396c, 0x396d, 0x396e, 0x396f, 0x3970, 0x3971, + 0x3972, 0x3973, 0x3974, 0x3975, 0x3976, 0x3977, 0x3978, 0x3979, + 0x397a, 0x397b, 0x397c, 0x397d, 0x397e, 0x3a21, 0x3a22, 0x3a23, + 0x3a24, 0x3a25, 0x3a26, 0x3a27, 0x3a28, 0x3a29, 0x3a2a, 0x3a2b, + 0x3a2c, 0x3a2d, 0x3a2e, 0x3a2f, 0x3a30, 0x3a31, 0x3a33, 0x3a34, + 0x3a35, 0x3a36, 0x3a37, 0x3a38, 0x3a32, 0x3a39, 0x3a3a, 0x3a3b, + 0x3a3c, 0x3a3d, 0x3a3e, 0x3a3f, 0x3a40, 0x3a41, 0x3a42, 0x3a43, + 0x3a44, 0x3a45, 0x3a46, 0x3a47, 0x3a48, 0x3a49, 0x3a4a, 0x3a4b, + 0x3a4c, 0x3a4d, 0x3a4e, 0x3a4f, 0x3a50, 0x3a51, 0x3a52, 0x3a53, + 0x3a54, 0x3a55, 0x3a56, 0x3a57, 0x3a58, 0x3a59, 0x3a5a, 0x3a5b, + 0x3a5c, 0x3a5d, 0x3a5e, 0x3a5f, 0x3a60, 0x3a61, 0x3a62, 0x3a63, + 0x3a64, 0x3a65, 0x3a66, 0x3a67, 0x3a68, 0x3a69, 0x3a6a, 0x3a6b, + 0x3a6c, 0x3a6d, 0x3a6e, 0x3a6f, 0x3a70, 0x3a71, 0x3a72, 0x3a73, + 0x3a74, 0x3a75, 0x3a76, 0x3a77, 0x3a78, 0x3a79, 0x3a7a, 0x3a7b, + 0x3a7c, 0x3a7d, 0x3a7e, 0x3b21, 0x3b22, 0x3b23, 0x3b24, 0x3b25, + 0x3b26, 0x3b27, 0x3b28, 0x3b29, 0x3b2a, 0x3b2b, 0x3b2c, 0x3b2d, + 0x3b2e, 0x3b2f, 0x3b30, 0x3b31, 0x3b32, 0x3b33, 0x3b34, 0x3b35, + 0x3b36, 0x3b37, 0x3b38, 0x3b39, 0x3b3a, 0x3b3b, 0x3b3d, 0x3b3c, + 0x3b3e, 0x3b3f, 0x3b40, 0x3b41, 0x3b42, 0x3b43, 0x3b44, 0x3b45, + 0x3b47, 0x3b48, 0x3b49, 0x3b4a, 0x3b46, 0x3b4b, 0x3b4c, 0x3b4d, + 0x3b4e, 0x3b4f, 0x3b50, 0x3b51, 0x3b52, 0x3b53, 0x3b57, 0x3b55, + 0x3b54, 0x3b56, 0x3b58, 0x3b59, 0x3b5a, 0x3b5b, 0x3b5c, 0x3b5d, + 0x3b5e, 0x3b5f, 0x3b60, 0x3b61, 0x3b62, 0x3b63, 0x3b64, 0x3b65, + 0x3b66, 0x3b67, 0x3b68, 0x3b69, 0x3b6a, 0x3b6b, 0x3b6c, 0x3b6d, + 0x3b6e, 0x3b6f, 0x3b70, 0x3b71, 0x3b72, 0x6674, 0x3b73, 0x3b74, + 0x3b75, 0x3b76, 0x3b77, 0x3b78, 0x3b7a, 0x3b79, 0x3b7b, 0x3b7c, + 0x3b7d, 0x3b7e, 0x3c21, 0x3c22, 0x3c23, 0x3c24, 0x3c25, 0x3c26, + 0x3c27, 0x3c28, 0x3c29, 0x3c2a, 0x3c2b, 0x3c2c, 0x3c2e, 0x3c2d, + 0x3c2f, 0x3c30, 0x3c31, 0x3c34, 0x3c32, 0x3c33, 0x3c35, 0x3c36, + 0x3c37, 0x3c38, 0x3c39, 0x3c3a, 0x3c3b, 0x3c3c, 0x3c3d, 0x3c3e, + 0x3c3f, 0x3c40, 0x3c41, 0x3c42, 0x3c43, 0x3c44, 0x3c45, 0x3c46, + 0x3c47, 0x3c48, 0x3c49, 0x3c4a, 0x3c4b, 0x3c4c, 0x3c4d, 0x3c4e, + 0x3c4f, 0x3c50, 0x3c52, 0x3c51, 0x3c53, 0x3c54, 0x3c55, 0x3c56, + 0x3c57, 0x3c58, 0x3c59, 0x3c5a, 0x3c5b, 0x3c5c, 0x3c5d, 0x3c5e, + 0x3c5f, 0x3c60, 0x3c61, 0x3c62, 0x3c63, 0x3c64, 0x3c65, 0x3c66, + 0x3c67, 0x3c68, 0x3c69, 0x3c6a, 0x3c6b, 0x3c6c, 0x3c6d, 0x3c6e, + 0x3c6f, 0x3c70, 0x3c71, 0x3c72, 0x3c73, 0x3c74, 0x3c75, 0x3c76, + 0x3c77, 0x3c78, 0x3c79, 0x3c7a, 0x3c7b, 0x3c7c, 0x3c7d, 0x3c7e, + 0x3d21, 0x3d22, 0x3d23, 0x3d24, 0x3d25, 0x3d26, 0x3d27, 0x3d28, + 0x3d29, 0x3d2a, 0x3d2b, 0x3d2c, 0x3d2d, 0x3d2e, 0x3d2f, 0x3d32, + 0x3d30, 0x3d31, 0x3d33, 0x3d34, 0x3d35, 0x3d36, 0x3d37, 0x3d38, + 0x3d39, 0x3d3a, 0x3d3b, 0x3d3c, 0x3d3d, 0x3d3e, 0x3d3f, 0x3d40, + 0x3d41, 0x3d42, 0x3d43, 0x3d44, 0x3d45, 0x3d46, 0x3d47, 0x3d48, + 0x3d49, 0x3d4a, 0x3d4b, 0x3d4c, 0x3d4d, 0x3d4e, 0x3d4f, 0x3d50, + 0x3d51, 0x3d52, 0x3d53, 0x3d54, 0x3d55, 0x3d56, 0x3d57, 0x3d58, + 0x3d59, 0x3d5a, 0x3d5b, 0x3d5c, 0x3d5d, 0x3d5e, 0x3d5f, 0x3d60, + 0x3d61, 0x3d62, 0x3d63, 0x3d64, 0x3d65, 0x3d66, 0x3d67, 0x3d68, + 0x3d69, 0x3d6a, 0x3d6b, 0x3d6c, 0x3d6d, 0x3d6e, 0x3d6f, 0x3d70, + 0x3d71, 0x3d72, 0x3d73, 0x3d74, 0x3d75, 0x3d76, 0x3d77, 0x3d78, + 0x3d79, 0x3d7a, 0x3d7b, 0x3d7c, 0x3d7d, 0x3d7e, 0x3e21, 0x3e22, + 0x3e23, 0x3e24, 0x3e25, 0x3e26, 0x3e27, 0x3e28, 0x3e29, 0x3e2a, + 0x3e2b, 0x3e2c, 0x3e2d, 0x3e2e, 0x3e2f, 0x3e30, 0x3e31, 0x3e32, + 0x3e33, 0x3e34, 0x3e35, 0x3e36, 0x3e37, 0x3e38, 0x3e39, 0x3e3a, + 0x3e3b, 0x3e3c, 0x3e3d, 0x3e3e, 0x3e3f, 0x3e40, 0x3e41, 0x3e42, + 0x3e43, 0x3e44, 0x3e45, 0x3e46, 0x3e47, 0x3e48, 0x3e49, 0x3e4a, + 0x3e4b, 0x3e4c, 0x3e4d, 0x3e4e, 0x3e4f, 0x3e50, 0x3e51, 0x3e52, + 0x3e53, 0x3e54, 0x3e55, 0x3e56, 0x3e57, 0x3e58, 0x3e59, 0x3e5a, + 0x3e5b, 0x3e5c, 0x3e5d, 0x3e5e, 0x3e5f, 0x3e60, 0x3e61, 0x3e62, + 0x3e63, 0x3e64, 0x3e65, 0x3e66, 0x3e67, 0x3e68, 0x3e69, 0x3e6a, + 0x3e6b, 0x3e6c, 0x3e6d, 0x3e6e, 0x3e6f, 0x3e70, 0x3e71, 0x3e72, + 0x3e73, 0x3e74, 0x3e75, 0x3e76, 0x3e77, 0x3e78, 0x3e79, 0x3e7a, + 0x3e7b, 0x3e7e, 0x3e7c, 0x3e7d, 0x3f21, 0x3f22, 0x3f23, 0x3f24, + 0x3f25, 0x3f26, 0x3f27, 0x3f28, 0x3f29, 0x3f2a, 0x3f2b, 0x3f2c, + 0x3f2d, 0x3f2e, 0x3f2f, 0x3f30, 0x3f31, 0x3f32, 0x3f33, 0x3f34, + 0x3f35, 0x3f36, 0x3f37, 0x3f38, 0x3f39, 0x3f3a, 0x3f3b, 0x3f3c, + 0x3f3d, 0x3f3e, 0x3f3f, 0x3f40, 0x3f41, 0x3f42, 0x3f43, 0x3f44, + 0x3f45, 0x3f46, 0x3f47, 0x3f48, 0x3f49, 0x3f4a, 0x3f4b, 0x3f4c, + 0x3f4d, 0x3f4e, 0x3f4f, 0x3f50, 0x3f51, 0x3f52, 0x3f53, 0x3f54, + 0x3f55, 0x3f56, 0x3f57, 0x3f58, 0x3f59, 0x3f5a, 0x3f5b, 0x3f5c, + 0x3f5d, 0x3f5e, 0x3f5f, 0x3f60, 0x3f61, 0x3f62, 0x3f63, 0x3f64, + 0x3f65, 0x3f66, 0x3f67, 0x3f68, 0x3f69, 0x3f6a, 0x3f6b, 0x3f6c, + 0x3f6d, 0x3f6e, 0x3f6f, 0x3f70, 0x3f71, 0x3f72, 0x3f73, 0x3f74, + 0x3f75, 0x3f76, 0x3f77, 0x3f78, 0x3f79, 0x3f7a, 0x3f7b, 0x3f7c, + 0x3f7d, 0x3f7e, 0x4021, 0x4022, 0x4023, 0x4024, 0x4025, 0x4026, + 0x4027, 0x4028, 0x4029, 0x402a, 0x402b, 0x402c, 0x402d, 0x402e, + 0x402f, 0x4030, 0x4031, 0x4032, 0x4033, 0x4034, 0x4035, 0x4036, + 0x4037, 0x4038, 0x4039, 0x403a, 0x403b, 0x403c, 0x403d, 0x403e, + 0x403f, 0x4040, 0x4041, 0x4042, 0x4043, 0x4044, 0x4045, 0x4046, + 0x4047, 0x4048, 0x4049, 0x404a, 0x404b, 0x404c, 0x404d, 0x404e, + 0x404f, 0x4050, 0x4051, 0x4052, 0x4053, 0x4054, 0x4055, 0x4056, + 0x4057, 0x4058, 0x4059, 0x405a, 0x405b, 0x405c, 0x405d, 0x405e, + 0x405f, 0x4060, 0x4061, 0x4062, 0x4063, 0x4064, 0x4065, 0x4066, + 0x4067, 0x4068, 0x4069, 0x406a, 0x406b, 0x406c, 0x406d, 0x406e, + 0x406f, 0x4070, 0x4071, 0x4072, 0x4073, 0x4074, 0x4075, 0x4076, + 0x4077, 0x4078, 0x4079, 0x407a, 0x407b, 0x407c, 0x407d, 0x407e, + 0x4121, 0x4122, 0x4123, 0x4124, 0x4125, 0x4126, 0x4127, 0x4128, + 0x4129, 0x412a, 0x412b, 0x412c, 0x412d, 0x412e, 0x412f, 0x4130, + 0x4131, 0x4132, 0x4133, 0x4134, 0x4135, 0x4136, 0x4137, 0x4138, + 0x4139, 0x413a, 0x413b, 0x413c, 0x413d, 0x413e, 0x413f, 0x4140, + 0x4141, 0x4142, 0x4143, 0x4144, 0x4145, 0x4146, 0x4147, 0x4148, + 0x4149, 0x414a, 0x414b, 0x414c, 0x414d, 0x414e, 0x414f, 0x4150, + 0x4151, 0x4152, 0x4153, 0x4154, 0x4155, 0x4156, 0x4157, 0x4158, + 0x4159, 0x415a, 0x415b, 0x415c, 0x415d, 0x415e, 0x415f, 0x4160, + 0x4161, 0x4162, 0x4163, 0x4164, 0x4165, 0x4166, 0x4167, 0x4168, + 0x4169, 0x416a, 0x416b, 0x416c, 0x416d, 0x416e, 0x416f, 0x4170, + 0x4171, 0x4172, 0x4173, 0x4174, 0x4175, 0x4176, 0x4177, 0x4178, + 0x4179, 0x417a, 0x417b, 0x417c, 0x417d, 0x417e, 0x4221, 0x4222, + 0x4223, 0x4224, 0x4225, 0x4226, 0x4227, 0x4228, 0x4229, 0x422a, + 0x422b, 0x422c, 0x422d, 0x422e, 0x4230, 0x422f, 0x4231, 0x4232, + 0x4233, 0x4234, 0x4235, 0x4237, 0x4236, 0x4238, 0x4239, 0x423a, + 0x423b, 0x423c, 0x423d, 0x423e, 0x4240, 0x4241, 0x4242, 0x4244, + 0x4245, 0x4247, 0x4248, 0x4249, 0x424a, 0x424c, 0x4243, 0x4246, + 0x424b, 0x424d, 0x424e, 0x424f, 0x4250, 0x4251, 0x4252, 0x4253, + 0x4254, 0x4255, 0x4256, 0x4257, 0x4258, 0x4259, 0x425a, 0x425b, + 0x425c, 0x425d, 0x425e, 0x425f, 0x4260, 0x4261, 0x4262, 0x4263, + 0x4264, 0x4265, 0x4266, 0x4267, 0x4268, 0x4269, 0x426a, 0x426b, + 0x426c, 0x426d, 0x423f, 0x426e, 0x426f, 0x4270, 0x4271, 0x4272, + 0x4273, 0x4274, 0x4275, 0x4276, 0x4277, 0x4278, 0x4279, 0x427a, + 0x427b, 0x427c, 0x427d, 0x427e, 0x4321, 0x4322, 0x4323, 0x4324, + 0x4325, 0x4326, 0x4327, 0x4328, 0x4329, 0x432a, 0x432b, 0x432c, + 0x432d, 0x432e, 0x432f, 0x4330, 0x4331, 0x4332, 0x4333, 0x4334, + 0x4335, 0x4336, 0x4337, 0x4339, 0x433a, 0x433b, 0x433c, 0x433d, + 0x433e, 0x433f, 0x4340, 0x4341, 0x4342, 0x4343, 0x4344, 0x4345, + 0x4346, 0x4347, 0x4348, 0x4338, 0x434a, 0x434b, 0x434c, 0x434d, + 0x434f, 0x434e, 0x4350, 0x4351, 0x4352, 0x4353, 0x4354, 0x4355, + 0x4356, 0x4357, 0x4358, 0x4359, 0x435a, 0x435b, 0x4349, 0x435c, + 0x435d, 0x435e, 0x435f, 0x4360, 0x4361, 0x4362, 0x4363, 0x4364, + 0x4365, 0x4366, 0x4367, 0x4368, 0x4369, 0x436a, 0x436b, 0x436c, + 0x436d, 0x436e, 0x436f, 0x4370, 0x4371, 0x4372, 0x4373, 0x4374, + 0x4375, 0x4376, 0x4377, 0x4378, 0x4379, 0x437a, 0x437b, 0x437c, + 0x437d, 0x437e, 0x4421, 0x4422, 0x4423, 0x4424, 0x4425, 0x4426, + 0x4427, 0x4428, 0x4429, 0x442a, 0x442b, 0x442c, 0x442d, 0x442e, + 0x442f, 0x4430, 0x4431, 0x4432, 0x4433, 0x4434, 0x4435, 0x4436, + 0x4437, 0x4438, 0x4439, 0x443a, 0x443b, 0x443c, 0x443d, 0x443e, + 0x443f, 0x4440, 0x4441, 0x4442, 0x4443, 0x4444, 0x4445, 0x4446, + 0x4447, 0x4448, 0x4449, 0x444a, 0x444b, 0x444c, 0x444d, 0x444e, + 0x444f, 0x4450, 0x4451, 0x4452, 0x4453, 0x4454, 0x4455, 0x4456, + 0x4457, 0x4458, 0x4459, 0x445a, 0x445b, 0x445c, 0x445d, 0x445e, + 0x445f, 0x4460, 0x4461, 0x4462, 0x4463, 0x4464, 0x4465, 0x4466, + 0x4467, 0x4468, 0x4469, 0x446a, 0x446b, 0x446c, 0x446d, 0x446e, + 0x446f, 0x4470, 0x4471, 0x4472, 0x4473, 0x4474, 0x4475, 0x4476, + 0x4477, 0x4478, 0x4479, 0x447a, 0x447b, 0x447c, 0x447d, 0x447e, + 0x4521, 0x4522, 0x4523, 0x4524, 0x4525, 0x4526, 0x4527, 0x4528, + 0x4529, 0x452a, 0x452b, 0x452c, 0x452d, 0x452e, 0x452f, 0x4530, + 0x4531, 0x4532, 0x4533, 0x4534, 0x4535, 0x4536, 0x4537, 0x4538, + 0x4539, 0x453a, 0x453b, 0x453c, 0x453d, 0x453e, 0x453f, 0x4540, + 0x4541, 0x4542, 0x4543, 0x4544, 0x4545, 0x4546, 0x4547, 0x4548, + 0x4549, 0x454a, 0x454b, 0x454d, 0x454c, 0x454e, 0x454f, 0x4550, + 0x4551, 0x4552, 0x4553, 0x4554, 0x4555, 0x4556, 0x4557, 0x4558, + 0x4559, 0x455a, 0x455b, 0x455c, 0x455d, 0x455e, 0x455f, 0x4560, + 0x4561, 0x4562, 0x4563, 0x4564, 0x4565, 0x4566, 0x4567, 0x4568, + 0x4569, 0x456a, 0x456b, 0x456c, 0x456d, 0x456e, 0x456f, 0x4570, + 0x4571, 0x4572, 0x4573, 0x4574, 0x4575, 0x4576, 0x4577, 0x4578, + 0x4579, 0x457a, 0x457b, 0x457c, 0x457d, 0x457e, 0x4621, 0x4622, + 0x4623, 0x4624, 0x4625, 0x4626, 0x4627, 0x4628, 0x4629, 0x462a, + 0x462b, 0x462c, 0x462d, 0x462e, 0x462f, 0x4630, 0x4631, 0x4632, + 0x4633, 0x4634, 0x4635, 0x4636, 0x4637, 0x4638, 0x4639, 0x463a, + 0x463b, 0x463c, 0x463d, 0x463e, 0x463f, 0x4640, 0x4641, 0x4642, + 0x4643, 0x4644, 0x4645, 0x4646, 0x4647, 0x4648, 0x4649, 0x464a, + 0x464b, 0x464c, 0x464d, 0x464e, 0x464f, 0x4650, 0x4651, 0x4652, + 0x4653, 0x4654, 0x4655, 0x4656, 0x4657, 0x4658, 0x4659, 0x465a, + 0x465b, 0x465c, 0x465d, 0x465e, 0x465f, 0x4660, 0x4736, 0x4661, + 0x4662, 0x4663, 0x4664, 0x4665, 0x4666, 0x4667, 0x4668, 0x4669, + 0x466a, 0x466b, 0x466c, 0x466d, 0x466e, 0x466f, 0x4670, 0x4671, + 0x4672, 0x4673, 0x4674, 0x4675, 0x4676, 0x4677, 0x4678, 0x4679, + 0x467a, 0x467b, 0x467c, 0x467d, 0x467e, 0x4721, 0x4722, 0x4723, + 0x4724, 0x4725, 0x4726, 0x4727, 0x4728, 0x4729, 0x472a, 0x472b, + 0x472c, 0x472d, 0x472e, 0x472f, 0x4730, 0x4731, 0x4732, 0x4733, + 0x4734, 0x4735, 0x4737, 0x4738, 0x4739, 0x473a, 0x473b, 0x473c, + 0x473d, 0x473e, 0x473f, 0x4740, 0x4741, 0x4742, 0x4743, 0x4744, + 0x4745, 0x4746, 0x4747, 0x4748, 0x4749, 0x474a, 0x474b, 0x474c, + 0x474d, 0x474e, 0x474f, 0x4750, 0x4751, 0x4752, 0x4753, 0x4754, + 0x4755, 0x4756, 0x4757, 0x4758, 0x4759, 0x475a, 0x475b, 0x475c, + 0x475d, 0x475e, 0x475f, 0x4760, 0x4761, 0x4762, 0x4763, 0x4764, + 0x4765, 0x4766, 0x4767, 0x4768, 0x4769, 0x476a, 0x476b, 0x476c, + 0x476d, 0x476e, 0x476f, 0x4770, 0x4771, 0x4772, 0x4773, 0x4774, + 0x4775, 0x4776, 0x4777, 0x4778, 0x4779, 0x477a, 0x477b, 0x477c, + 0x477d, 0x477e, 0x4821, 0x4822, 0x4823, 0x4824, 0x4825, 0x4826, + 0x4827, 0x4828, 0x4829, 0x482a, 0x482b, 0x482c, 0x482d, 0x482e, + 0x482f, 0x4830, 0x4831, 0x4832, 0x4833, 0x4834, 0x4835, 0x4836, + 0x4837, 0x4838, 0x4839, 0x483a, 0x483b, 0x483c, 0x483d, 0x483e, + 0x483f, 0x4840, 0x4841, 0x4842, 0x4843, 0x4844, 0x4845, 0x4846, + 0x4847, 0x4848, 0x4849, 0x484a, 0x484b, 0x484c, 0x4853, 0x484d, + 0x484e, 0x484f, 0x4850, 0x4851, 0x4852, 0x4854, 0x4855, 0x4856, + 0x4857, 0x4858, 0x4859, 0x485a, 0x485b, 0x485c, 0x485d, 0x485e, + 0x485f, 0x4860, 0x4861, 0x4862, 0x4863, 0x4864, 0x4865, 0x4866, + 0x4867, 0x4868, 0x4869, 0x486a, 0x486b, 0x486c, 0x486d, 0x486e, + 0x486f, 0x4870, 0x4871, 0x4872, 0x4873, 0x4874, 0x4875, 0x4876, + 0x4877, 0x4878, 0x4879, 0x487a, 0x487b, 0x487c, 0x487d, 0x487e, + 0x4921, 0x4922, 0x4923, 0x4924, 0x4925, 0x4926, 0x4927, 0x4928, + 0x4929, 0x492a, 0x492b, 0x492c, 0x492d, 0x492e, 0x492f, 0x4930, + 0x4931, 0x4932, 0x4933, 0x4934, 0x4935, 0x4936, 0x4937, 0x4938, + 0x4939, 0x493a, 0x493b, 0x493c, 0x4941, 0x493d, 0x493e, 0x493f, + 0x4940, 0x4942, 0x4943, 0x4944, 0x4945, 0x4946, 0x4947, 0x4948, + 0x4949, 0x494a, 0x494b, 0x494c, 0x494d, 0x494e, 0x494f, 0x4950, + 0x4951, 0x4952, 0x4953, 0x4954, 0x4955, 0x4956, 0x4957, 0x4958, + 0x4959, 0x495a, 0x495b, 0x495c, 0x495d, 0x495e, 0x495f, 0x4960, + 0x4961, 0x4962, 0x4963, 0x4964, 0x4965, 0x4966, 0x4967, 0x4968, + 0x4969, 0x496a, 0x496b, 0x496c, 0x496d, 0x496e, 0x496f, 0x4970, + 0x4971, 0x4972, 0x4973, 0x4974, 0x4975, 0x4976, 0x4977, 0x4978, + 0x4979, 0x497a, 0x497b, 0x497c, 0x497d, 0x497e, 0x4a21, 0x4a22, + 0x4a23, 0x4a24, 0x4a25, 0x4a26, 0x4a27, 0x4a28, 0x4a29, 0x4a2a, + 0x4a2b, 0x4a2c, 0x4a2d, 0x4a2e, 0x4a2f, 0x4a30, 0x4a31, 0x4a32, + 0x4a33, 0x4a34, 0x4a35, 0x4a36, 0x4a37, 0x4a38, 0x4a39, 0x4a3a, + 0x4a3b, 0x4a3c, 0x4a3d, 0x4a3e, 0x4a3f, 0x4a40, 0x4a41, 0x4a42, + 0x4a43, 0x4a44, 0x4a45, 0x4a46, 0x4a47, 0x4a48, 0x4a49, 0x4a4a, + 0x4a4b, 0x4a4c, 0x4a4d, 0x4a4e, 0x4a4f, 0x4a50, 0x4a51, 0x4a52, + 0x4a53, 0x4a54, 0x4a55, 0x4a56, 0x4a57, 0x4a58, 0x4a59, 0x4a5a, + 0x4a5b, 0x4a5c, 0x4a5d, 0x4a5e, 0x4a5f, 0x4a60, 0x4a61, 0x4a62, + 0x4a63, 0x4a64, 0x4a65, 0x4a66, 0x4a67, 0x4a68, 0x4a69, 0x4a6a, + 0x4a6b, 0x4a6c, 0x4a6d, 0x4a6e, 0x4a6f, 0x4a70, 0x4a71, 0x4a72, + 0x4a73, 0x4a74, 0x4a75, 0x4a76, 0x4a77, 0x4a78, 0x4a79, 0x4a7a, + 0x4a7b, 0x4a7c, 0x4a7d, 0x4a7e, 0x4b21, 0x4b22, 0x4b23, 0x4b24, + 0x4b25, 0x4b26, 0x4b27, 0x4b28, 0x4b29, 0x4b2a, 0x4b2b, 0x4b2c, + 0x4b2d, 0x4b2e, 0x4b2f, 0x4b30, 0x4b31, 0x4b32, 0x4b33, 0x4b34, + 0x4b35, 0x4b36, 0x4b37, 0x4b38, 0x4b39, 0x4b3a, 0x4b3b, 0x4b3c, + 0x4b3d, 0x4b3e, 0x4b3f, 0x4b40, 0x4b41, 0x4b42, 0x4b43, 0x4b44, + 0x4b45, 0x4b46, 0x4b47, 0x4b48, 0x4b49, 0x4b4a, 0x4b4b, 0x4b4c, + 0x4b4d, 0x4b4e, 0x4b4f, 0x4b50, 0x4b51, 0x4b52, 0x4b53, 0x4b54, + 0x4b55, 0x4b56, 0x4b57, 0x4b58, 0x4b59, 0x4b5a, 0x4b5b, 0x4b5c, + 0x4b5d, 0x4b5e, 0x4b5f, 0x4b60, 0x4b61, 0x4b62, 0x4b63, 0x4b64, + 0x4b65, 0x4b66, 0x4b67, 0x4b68, 0x4b69, 0x4b6a, 0x4b6b, 0x4b6c, + 0x4b6d, 0x4b6e, 0x4b6f, 0x4b70, 0x4b71, 0x4b72, 0x4b73, 0x4b74, + 0x4b75, 0x4b76, 0x4b77, 0x4b78, 0x4b79, 0x4b7a, 0x4b7b, 0x4b7c, + 0x4b7d, 0x4b7e, 0x4c21, 0x4c22, 0x4c23, 0x4c24, 0x4c25, 0x4c26, + 0x4c27, 0x4c28, 0x4c29, 0x4c2a, 0x4c2b, 0x4c2c, 0x4c2d, 0x4c2e, + 0x4c2f, 0x4c30, 0x4c31, 0x4c32, 0x4c33, 0x4c34, 0x4c35, 0x4c36, + 0x4c37, 0x4c38, 0x4c39, 0x4c3a, 0x4c3b, 0x4c3c, 0x4c3d, 0x4c3e, + 0x4c3f, 0x4c40, 0x4c41, 0x4c42, 0x4c43, 0x4c44, 0x4c45, 0x4c46, + 0x4c47, 0x4c48, 0x4c49, 0x4c4a, 0x4c4b, 0x4c4c, 0x4c4d, 0x4c4e, + 0x4c4f, 0x4c50, 0x4c51, 0x4c52, 0x4c53, 0x4c54, 0x4c55, 0x4c56, + 0x4c57, 0x4c58, 0x4c59, 0x4c5a, 0x4c5b, 0x4c5c, 0x4c5d, 0x4c5e, + 0x4c5f, 0x4c60, 0x4c61, 0x4c62, 0x4c63, 0x4c64, 0x4c65, 0x4c66, + 0x4c67, 0x4c68, 0x4c69, 0x4c6a, 0x4c6b, 0x4c6c, 0x4c6d, 0x4c6e, + 0x4c6f, 0x4c70, 0x4c71, 0x4c72, 0x4c73, 0x4c74, 0x4c75, 0x4c76, + 0x4c77, 0x4c78, 0x4c79, 0x4c7a, 0x4c7b, 0x4c7c, 0x4c7d, 0x4c7e, + 0x4d21, 0x4d22, 0x4d23, 0x4d24, 0x4d25, 0x4d26, 0x4d27, 0x4d28, + 0x4d29, 0x4d2a, 0x4d2b, 0x4d2c, 0x4d2d, 0x4d2e, 0x4d2f, 0x4d30, + 0x4d31, 0x4d32, 0x4d33, 0x4d34, 0x4d35, 0x4d36, 0x4d37, 0x4d38, + 0x4d39, 0x4d3a, 0x4d3b, 0x4d3c, 0x4d3d, 0x4d3e, 0x4d3f, 0x4d40, + 0x4d41, 0x4d42, 0x4d43, 0x4d44, 0x4d45, 0x4d46, 0x4d47, 0x4d48, + 0x4d49, 0x4d4a, 0x4d4b, 0x4d4c, 0x4d4d, 0x4d4e, 0x4d4f, 0x4d50, + 0x4d51, 0x4d52, 0x4d53, 0x4d54, 0x4d55, 0x4d56, 0x4d57, 0x4d58, + 0x4d59, 0x4d5a, 0x4d5b, 0x4d5c, 0x4d5d, 0x4d5e, 0x4d5f, 0x4d60, + 0x4d61, 0x4d62, 0x4d63, 0x4d64, 0x4d65, 0x4d66, 0x4d67, 0x4d68, + 0x4d69, 0x4d6a, 0x4d6b, 0x4d6c, 0x4d6d, 0x4d6e, 0x4d6f, 0x4d70, + 0x4d71, 0x4d72, 0x4d73, 0x4d74, 0x4d75, 0x4d76, 0x4d77, 0x4d78, + 0x4d79, 0x4d7a, 0x4d7b, 0x4d7c, 0x4d7d, 0x4d7e, 0x4e21, 0x4e22, + 0x4e24, 0x4e25, 0x4e26, 0x4e27, 0x4e28, 0x4e29, 0x4e23, 0x4e2a, + 0x4e2b, 0x4e2c, 0x4e2d, 0x4e2e, 0x4e2f, 0x4e30, 0x4e31, 0x4e32, + 0x4e33, 0x4e34, 0x4e35, 0x4e36, 0x4e37, 0x4e38, 0x4e39, 0x4e3a, + 0x4e3b, 0x4e3c, 0x4e3d, 0x4e3e, 0x4e3f, 0x4e40, 0x4e41, 0x4e42, + 0x4e43, 0x4e44, 0x4e45, 0x4e46, 0x4e47, 0x4e48, 0x4e49, 0x4e4a, + 0x4e4b, 0x4e4c, 0x4e4d, 0x4e4e, 0x4e4f, 0x4e50, 0x4e51, 0x4e52, + 0x4e53, 0x4e54, 0x4e55, 0x4e56, 0x4e57, 0x4e58, 0x4e59, 0x4e5a, + 0x4e5b, 0x4e5c, 0x4e5d, 0x4e5e, 0x4e5f, 0x4e60, 0x4e61, 0x4e62, + 0x4e63, 0x4e64, 0x4e65, 0x4e66, 0x4e67, 0x4e68, 0x4e69, 0x4e6a, + 0x4e6b, 0x4e6c, 0x4e6d, 0x4e6e, 0x4e6f, 0x4e70, 0x4e71, 0x4e72, + 0x4e73, 0x4e74, 0x4e75, 0x4e76, 0x4e77, 0x4e78, 0x4e79, 0x4e7a, + 0x4e7b, 0x4e7c, 0x4e7d, 0x4e7e, 0x4f21, 0x4f22, 0x4f23, 0x4f24, + 0x4f25, 0x4f26, 0x4f27, 0x4f28, 0x4f29, 0x4f2a, 0x4f2b, 0x4f2c, + 0x4f2d, 0x4f2e, 0x4f2f, 0x4f30, 0x4f31, 0x4f32, 0x4f33, 0x4f34, + 0x4f35, 0x4f36, 0x4f37, 0x4f38, 0x4f39, 0x4f3a, 0x4f3b, 0x4f3c, + 0x4f3d, 0x4f3e, 0x4f3f, 0x4f40, 0x4f41, 0x4f42, 0x4f43, 0x4f44, + 0x4f45, 0x4f46, 0x4f47, 0x4f48, 0x4f49, 0x4f4a, 0x4f4b, 0x4f4c, + 0x4f4d, 0x4f4e, 0x4f4f, 0x4f50, 0x4f51, 0x4f52, 0x4f53, 0x4f54, + 0x4f55, 0x4f56, 0x4f57, 0x4f58, 0x4f59, 0x4f5a, 0x4f5b, 0x4f5c, + 0x4f5d, 0x4f5e, 0x4f5f, 0x4f60, 0x4f61, 0x4f62, 0x4f63, 0x4f64, + 0x4f65, 0x4f66, 0x4f67, 0x4f68, 0x4f69, 0x4f6a, 0x4f6b, 0x4f6c, + 0x4f6d, 0x4f6e, 0x4f6f, 0x4f70, 0x4f71, 0x4f72, 0x4f74, 0x4f75, + 0x4f76, 0x4f73, 0x4f77, 0x4f78, 0x4f79, 0x4f7a, 0x4f7b, 0x4f7c, + 0x4f7d, 0x4f7e, 0x5021, 0x5022, 0x5023, 0x5024, 0x5025, 0x5026, + 0x5027, 0x5028, 0x5029, 0x502a, 0x502b, 0x502c, 0x502e, 0x502f, + 0x5030, 0x5031, 0x502d, 0x5032, 0x5033, 0x5034, 0x5035, 0x5037, + 0x5038, 0x5039, 0x503a, 0x503b, 0x5036, 0x503c, 0x503d, 0x503e, + 0x503f, 0x5040, 0x5041, 0x5042, 0x5043, 0x5044, 0x5045, 0x5046, + 0x5047, 0x5048, 0x5049, 0x504a, 0x504b, 0x504c, 0x504d, 0x504e, + 0x504f, 0x5050, 0x5051, 0x5052, 0x5053, 0x5054, 0x5055, 0x5056, + 0x5057, 0x5058, 0x5059, 0x505a, 0x505b, 0x505c, 0x505d, 0x505e, + 0x505f, 0x5060, 0x5061, 0x5062, 0x5063, 0x5064, 0x5065, 0x5066, + 0x5067, 0x5068, 0x5069, 0x506a, 0x506b, 0x506c, 0x506d, 0x506e, + 0x506f, 0x5070, 0x5071, 0x5072, 0x5073, 0x5074, 0x5075, 0x5076, + 0x5077, 0x5078, 0x5079, 0x507a, 0x507b, 0x507c, 0x507d, 0x507e, + 0x5121, 0x5122, 0x5123, 0x5124, 0x5125, 0x5126, 0x5127, 0x5128, + 0x5129, 0x512a, 0x512b, 0x512c, 0x512d, 0x512e, 0x512f, 0x5130, + 0x5131, 0x5132, 0x5133, 0x5134, 0x5135, 0x5136, 0x5137, 0x5138, + 0x5139, 0x513a, 0x513b, 0x513c, 0x513d, 0x513e, 0x513f, 0x5140, + 0x5141, 0x5142, 0x5143, 0x5144, 0x5145, 0x5146, 0x5147, 0x5148, + 0x5149, 0x514a, 0x514b, 0x514c, 0x514d, 0x514e, 0x514f, 0x5150, + 0x5151, 0x5152, 0x5153, 0x5154, 0x5155, 0x5156, 0x5157, 0x5158, + 0x5159, 0x515a, 0x515b, 0x515c, 0x515d, 0x515e, 0x515f, 0x5160, + 0x5161, 0x5162, 0x5163, 0x5164, 0x5165, 0x5166, 0x5167, 0x5168, + 0x5169, 0x516a, 0x516b, 0x516c, 0x516d, 0x516e, 0x516f, 0x5170, + 0x5171, 0x5172, 0x5173, 0x5174, 0x5175, 0x5176, 0x5177, 0x5178, + 0x5179, 0x517a, 0x517b, 0x517c, 0x517d, 0x517e, 0x5221, 0x5222, + 0x5223, 0x5224, 0x5225, 0x5226, 0x5227, 0x5228, 0x5229, 0x522a, + 0x522b, 0x522c, 0x522d, 0x522e, 0x522f, 0x5230, 0x5231, 0x5232, + 0x5233, 0x5234, 0x5235, 0x5236, 0x5237, 0x5238, 0x5239, 0x523a, + 0x523b, 0x523c, 0x523d, 0x523e, 0x523f, 0x5240, 0x5241, 0x5242, + 0x5243, 0x5244, 0x5245, 0x5246, 0x5247, 0x5248, 0x5249, 0x524a, + 0x524b, 0x524c, 0x524d, 0x524e, 0x524f, 0x5250, 0x5251, 0x5252, + 0x5253, 0x5254, 0x5255, 0x5256, 0x5257, 0x5258, 0x5259, 0x525a, + 0x525b, 0x525c, 0x525d, 0x525e, 0x525f, 0x5260, 0x5261, 0x5262, + 0x5263, 0x5264, 0x5265, 0x5266, 0x5267, 0x5268, 0x5269, 0x526a, + 0x526b, 0x526c, 0x526d, 0x526e, 0x526f, 0x5270, 0x5271, 0x5272, + 0x5273, 0x5274, 0x5276, 0x5277, 0x5278, 0x5275, 0x5279, 0x527a, + 0x527b, 0x527c, 0x527d, 0x527e, 0x5321, 0x5322, 0x5323, 0x5324, + 0x5325, 0x5326, 0x5327, 0x5328, 0x5329, 0x532a, 0x532b, 0x532c, + 0x532d, 0x532e, 0x532f, 0x5330, 0x5331, 0x5332, 0x5333, 0x5334, + 0x5335, 0x5336, 0x5337, 0x5338, 0x5339, 0x533a, 0x533b, 0x533c, + 0x533d, 0x533e, 0x533f, 0x5340, 0x5341, 0x5342, 0x5343, 0x5344, + 0x5345, 0x5346, 0x5347, 0x5348, 0x5349, 0x534a, 0x534b, 0x534c, + 0x534d, 0x534e, 0x534f, 0x5350, 0x5351, 0x5352, 0x5353, 0x5354, + 0x5355, 0x5356, 0x5357, 0x5358, 0x5359, 0x535a, 0x535b, 0x535c, + 0x535d, 0x535e, 0x535f, 0x5360, 0x5361, 0x5362, 0x5363, 0x5364, + 0x5365, 0x5366, 0x5367, 0x5368, 0x5369, 0x536a, 0x536b, 0x536c, + 0x536d, 0x536e, 0x536f, 0x5370, 0x5371, 0x5372, 0x5373, 0x5374, + 0x5375, 0x5376, 0x5377, 0x5378, 0x5379, 0x537a, 0x537b, 0x537c, + 0x537d, 0x537e, 0x5421, 0x5422, 0x5423, 0x5424, 0x5425, 0x5426, + 0x5427, 0x5428, 0x5429, 0x542a, 0x542b, 0x542c, 0x542d, 0x542e, + 0x542f, 0x5430, 0x5431, 0x5432, 0x5434, 0x5435, 0x5436, 0x5437, + 0x5438, 0x5439, 0x543a, 0x543b, 0x543c, 0x543d, 0x543e, 0x5433, + 0x543f, 0x5440, 0x5441, 0x5442, 0x5443, 0x5444, 0x5445, 0x5446, + 0x5447, 0x5448, 0x5449, 0x544a, 0x544b, 0x544c, 0x544d, 0x544e, + 0x544f, 0x5450, 0x5451, 0x5452, 0x5453, 0x5454, 0x5455, 0x5456, + 0x5457, 0x5458, 0x5459, 0x545a, 0x545b, 0x545c, 0x545d, 0x545e, + 0x545f, 0x5460, 0x5461, 0x5462, 0x5463, 0x5464, 0x5465, 0x5466, + 0x5467, 0x5468, 0x5469, 0x546a, 0x546c, 0x546b, 0x546d, 0x546e, + 0x546f, 0x5470, 0x5471, 0x5472, 0x5473, 0x5474, 0x5475, 0x5476, + 0x5477, 0x5478, 0x5479, 0x547a, 0x547b, 0x547c, 0x547d, 0x547e, + 0x5521, 0x5522, 0x5523, 0x5524, 0x5525, 0x5526, 0x5527, 0x5528, + 0x5529, 0x552a, 0x552b, 0x552c, 0x552d, 0x552e, 0x552f, 0x5530, + 0x5531, 0x5532, 0x5533, 0x5534, 0x5535, 0x5536, 0x5537, 0x5538, + 0x5539, 0x553a, 0x553b, 0x553c, 0x553d, 0x553e, 0x553f, 0x5540, + 0x5541, 0x5542, 0x5543, 0x5544, 0x5545, 0x5546, 0x5547, 0x5548, + 0x5549, 0x554a, 0x554b, 0x554c, 0x554d, 0x554e, 0x554f, 0x5550, + 0x5551, 0x5552, 0x5553, 0x5554, 0x5555, 0x5556, 0x5557, 0x5558, + 0x5559, 0x555a, 0x555b, 0x555c, 0x555d, 0x555e, 0x555f, 0x5560, + 0x5561, 0x5562, 0x5563, 0x5564, 0x5565, 0x5566, 0x5567, 0x5568, + 0x5569, 0x556a, 0x556b, 0x556c, 0x556d, 0x556e, 0x556f, 0x5570, + 0x5571, 0x5572, 0x5573, 0x5574, 0x5575, 0x5576, 0x5577, 0x5578, + 0x5579, 0x557a, 0x557b, 0x557c, 0x557d, 0x557e, 0x5621, 0x5622, + 0x5623, 0x5624, 0x5625, 0x5626, 0x5627, 0x5628, 0x5629, 0x562a, + 0x562b, 0x562c, 0x562d, 0x562e, 0x562f, 0x5630, 0x5631, 0x5632, + 0x5633, 0x5634, 0x5635, 0x5636, 0x5637, 0x5638, 0x5639, 0x563a, + 0x563b, 0x563c, 0x563d, 0x563e, 0x563f, 0x5640, 0x5641, 0x5642, + 0x5643, 0x5644, 0x5645, 0x5647, 0x5648, 0x5649, 0x564a, 0x564b, + 0x5646, 0x564c, 0x564d, 0x564e, 0x564f, 0x5650, 0x5651, 0x5652, + 0x5653, 0x5654, 0x5656, 0x5657, 0x5658, 0x5655, 0x5659, 0x565a, + 0x565b, 0x565c, 0x565d, 0x565e, 0x565f, 0x5660, 0x5661, 0x5662, + 0x5663, 0x5664, 0x5665, 0x5666, 0x5667, 0x5668, 0x5669, 0x566a, + 0x566b, 0x566c, 0x566d, 0x566e, 0x566f, 0x5670, 0x5671, 0x5672, + 0x5673, 0x5674, 0x5675, 0x5676, 0x5677, 0x5678, 0x5679, 0x567a, + 0x567b, 0x567c, 0x567d, 0x567e, 0x5721, 0x5722, 0x5723, 0x5724, + 0x5725, 0x5726, 0x5727, 0x5728, 0x5729, 0x572a, 0x572b, 0x572c, + 0x572d, 0x572e, 0x572f, 0x5730, 0x5731, 0x5732, 0x5733, 0x5734, + 0x5735, 0x5736, 0x5737, 0x5738, 0x5739, 0x573a, 0x573b, 0x573c, + 0x573d, 0x573e, 0x573f, 0x5740, 0x5741, 0x5742, 0x5743, 0x5744, + 0x5745, 0x5746, 0x5747, 0x5748, 0x5749, 0x574a, 0x574b, 0x574c, + 0x574d, 0x574e, 0x574f, 0x5750, 0x5751, 0x5752, 0x5753, 0x5754, + 0x5755, 0x5756, 0x5757, 0x5758, 0x5759, 0x575a, 0x575b, 0x575c, + 0x575d, 0x575e, 0x575f, 0x5760, 0x5761, 0x5762, 0x5764, 0x5765, + 0x5766, 0x5767, 0x5768, 0x5769, 0x576a, 0x576b, 0x576c, 0x576d, + 0x576e, 0x576f, 0x5770, 0x5771, 0x5772, 0x5773, 0x5774, 0x5775, + 0x5776, 0x5777, 0x5778, 0x5779, 0x583e, 0x5763, 0x577a, 0x577b, + 0x577c, 0x577d, 0x577e, 0x5821, 0x5822, 0x5823, 0x5824, 0x5825, + 0x5826, 0x5827, 0x5828, 0x5829, 0x582a, 0x582b, 0x582c, 0x582d, + 0x582e, 0x582f, 0x5830, 0x5831, 0x5832, 0x5833, 0x584c, 0x5834, + 0x5835, 0x5836, 0x5837, 0x5838, 0x5839, 0x583a, 0x583b, 0x583c, + 0x583d, 0x583f, 0x5840, 0x5841, 0x5842, 0x5843, 0x5844, 0x5845, + 0x5846, 0x5847, 0x5848, 0x5849, 0x584a, 0x584b, 0x584d, 0x584e, + 0x584f, 0x5850, 0x5851, 0x5852, 0x5853, 0x5854, 0x5855, 0x5856, + 0x5857, 0x5858, 0x5859, 0x585a, 0x585b, 0x585c, 0x585d, 0x585e, + 0x585f, 0x5860, 0x5861, 0x5862, 0x5863, 0x5864, 0x5865, 0x5866, + 0x5867, 0x5868, 0x5869, 0x586a, 0x586b, 0x586c, 0x586d, 0x586e, + 0x586f, 0x5870, 0x5871, 0x5872, 0x5873, 0x5874, 0x5875, 0x5876, + 0x5877, 0x5878, 0x5879, 0x587a, 0x587b, 0x587c, 0x587d, 0x587e, + 0x5921, 0x5922, 0x5923, 0x5924, 0x5925, 0x5926, 0x5927, 0x5928, + 0x592a, 0x592b, 0x592c, 0x592d, 0x592e, 0x592f, 0x5930, 0x5931, + 0x5932, 0x5933, 0x5934, 0x5935, 0x5936, 0x5937, 0x5938, 0x5939, + 0x593a, 0x593b, 0x593c, 0x5929, 0x593d, 0x593e, 0x593f, 0x5940, + 0x5941, 0x5942, 0x5943, 0x5944, 0x5945, 0x5946, 0x5947, 0x5948, + 0x5949, 0x594a, 0x594b, 0x594c, 0x594d, 0x594e, 0x594f, 0x5950, + 0x5951, 0x5952, 0x5953, 0x5954, 0x5955, 0x5956, 0x5957, 0x5958, + 0x5959, 0x595a, 0x595b, 0x595c, 0x595d, 0x595e, 0x595f, 0x5960, + 0x5961, 0x5962, 0x5963, 0x5964, 0x5965, 0x5966, 0x5974, 0x5967, + 0x5968, 0x5969, 0x596a, 0x596b, 0x596c, 0x596d, 0x596e, 0x596f, + 0x5970, 0x5971, 0x5972, 0x5973, 0x5975, 0x5976, 0x5977, 0x5978, + 0x5979, 0x597a, 0x597b, 0x597c, 0x597d, 0x597e, 0x5a21, 0x5a22, + 0x5a23, 0x5a24, 0x5a25, 0x5a26, 0x5a27, 0x5a28, 0x5a29, 0x5a2a, + 0x5a2b, 0x5a2c, 0x5a2d, 0x5a2e, 0x5a2f, 0x5a30, 0x5a31, 0x5a32, + 0x5a33, 0x5a34, 0x5a35, 0x5a36, 0x3866, 0x5a37, 0x5a38, 0x5a39, + 0x5a3a, 0x5a3b, 0x5a3c, 0x5a3d, 0x5a3e, 0x5a3f, 0x5a40, 0x5a41, + 0x5a42, 0x5a43, 0x5a44, 0x5a45, 0x5a46, 0x5a47, 0x5a48, 0x5a49, + 0x5a4a, 0x5a4b, 0x5a6d, 0x5a4c, 0x5a4d, 0x5a4e, 0x5a4f, 0x5a50, + 0x5a51, 0x5a52, 0x5a53, 0x5a54, 0x5a55, 0x5a56, 0x5a57, 0x5a58, + 0x5a59, 0x5a5a, 0x5a5b, 0x5a5c, 0x5a5d, 0x5a5e, 0x5a5f, 0x5a60, + 0x5a61, 0x5a62, 0x5a63, 0x5a64, 0x5a65, 0x5a66, 0x5a67, 0x5a68, + 0x5a69, 0x5a6a, 0x5a6b, 0x5a6c, 0x5a6e, 0x5a6f, 0x5a70, 0x5a71, + 0x5a72, 0x5a73, 0x5a74, 0x5a75, 0x5a76, 0x5a77, 0x5a78, 0x5a79, + 0x5a7a, 0x5a7b, 0x5a7c, 0x5a7d, 0x5a7e, 0x5b21, 0x5b22, 0x5b23, + 0x5b24, 0x5b25, 0x5b26, 0x5b27, 0x5b28, 0x5b29, 0x5b2a, 0x5b2b, + 0x5b2c, 0x5b2d, 0x5b2e, 0x5b2f, 0x5b30, 0x5b31, 0x5b32, 0x5b33, + 0x5b34, 0x5b35, 0x5b36, 0x5b37, 0x5b38, 0x5b39, 0x5b3a, 0x5b3b, + 0x5b3c, 0x5b3d, 0x5b3e, 0x5b3f, 0x5b40, 0x5b41, 0x5b42, 0x5b43, + 0x5b44, 0x5b45, 0x5b46, 0x5b47, 0x5b48, 0x5b49, 0x5b4a, 0x5b4b, + 0x5b4c, 0x5b4d, 0x5b4e, 0x5b4f, 0x5b50, 0x5b51, 0x5b52, 0x5b53, + 0x5b54, 0x5b55, 0x5b56, 0x5b57, 0x5b58, 0x5b59, 0x5b5a, 0x5b5b, + 0x5b5c, 0x5b5d, 0x5b5e, 0x5b5f, 0x5b60, 0x5b61, 0x5b62, 0x5b63, + 0x5b64, 0x5b65, 0x5b66, 0x5b67, 0x5b68, 0x5b69, 0x5b6a, 0x5b6b, + 0x5b6c, 0x5b6d, 0x5b6e, 0x5b70, 0x5b71, 0x5b72, 0x5b73, 0x5b6f, + 0x5b74, 0x5b75, 0x5b76, 0x5b77, 0x5b78, 0x5b79, 0x5b7a, 0x5b7b, + 0x5b7c, 0x5b7d, 0x5b7e, 0x5c21, 0x5c22, 0x5c23, 0x5c24, 0x5c25, + 0x5c26, 0x5c27, 0x5c28, 0x5c29, 0x5c2a, 0x5c2b, 0x5c2c, 0x5c2d, + 0x5c2e, 0x5c2f, 0x5c30, 0x5c31, 0x5c32, 0x5c33, 0x5c34, 0x5c35, + 0x5c36, 0x5c37, 0x5c38, 0x5c39, 0x5c3a, 0x5c3b, 0x5c3c, 0x5c3d, + 0x5c3e, 0x5c3f, 0x5c40, 0x5c41, 0x5c42, 0x5c43, 0x5c44, 0x5c45, + 0x5c46, 0x5c47, 0x5c48, 0x5c49, 0x5c4a, 0x5c4b, 0x5c4c, 0x5c4d, + 0x5c4e, 0x5c4f, 0x5c50, 0x5c51, 0x5c52, 0x5c53, 0x5c54, 0x5c55, + 0x5c56, 0x5c57, 0x5c58, 0x5c59, 0x5c5a, 0x5c5b, 0x5c5c, 0x5c5d, + 0x5c5e, 0x5c5f, 0x5c60, 0x5c61, 0x5c62, 0x5c63, 0x5c64, 0x5c65, + 0x5c66, 0x5c67, 0x5c68, 0x5c69, 0x5c6a, 0x5c6b, 0x5c6c, 0x5c6d, + 0x5c6e, 0x5c6f, 0x5c70, 0x5c71, 0x5c72, 0x5c73, 0x5c74, 0x5c75, + 0x5c76, 0x5c77, 0x5c78, 0x5c79, 0x5c7a, 0x5c7b, 0x5c7c, 0x5c7d, + 0x5c7e, 0x5d21, 0x5d22, 0x5d23, 0x5d24, 0x5d25, 0x5d26, 0x5d27, + 0x5d28, 0x5d29, 0x5d2a, 0x5d2b, 0x5d2c, 0x5d2d, 0x5d2e, 0x5d2f, + 0x5d30, 0x5d31, 0x5d32, 0x5d33, 0x5d34, 0x5d35, 0x5d36, 0x5d37, + 0x5d38, 0x5d39, 0x5d3a, 0x5d3b, 0x5d3c, 0x5d3d, 0x5d3e, 0x5d3f, + 0x5d40, 0x5d41, 0x5d42, 0x5d43, 0x5d44, 0x5d45, 0x5d46, 0x5d47, + 0x5d48, 0x5d49, 0x5d4a, 0x5d4b, 0x5d4c, 0x5d4d, 0x5d4e, 0x5d4f, + 0x5d50, 0x5d51, 0x5d52, 0x5d53, 0x5d54, 0x5d55, 0x5d56, 0x5d57, + 0x5d58, 0x5d59, 0x5d5a, 0x5d5b, 0x5d5c, 0x5d5d, 0x5d5e, 0x5d5f, + 0x5d60, 0x5d61, 0x5d62, 0x5d63, 0x5d64, 0x5d65, 0x5d66, 0x5d67, + 0x5d68, 0x5d69, 0x5d6a, 0x5d6b, 0x5d6c, 0x5d6d, 0x5d6e, 0x5d6f, + 0x5d70, 0x5d71, 0x5d72, 0x5d73, 0x5d74, 0x5d75, 0x5d76, 0x5d77, + 0x5d78, 0x5d79, 0x5d7a, 0x5d7b, 0x5d7c, 0x5d7d, 0x5d7e, 0x5e21, + 0x5e22, 0x5e23, 0x5e24, 0x5e25, 0x5e26, 0x5e27, 0x5e28, 0x5e29, + 0x5e2a, 0x5e2b, 0x5e2c, 0x5e2d, 0x5e2e, 0x5e2f, 0x5e30, 0x5e31, + 0x5e32, 0x5e33, 0x5e34, 0x5e35, 0x5e36, 0x5e37, 0x5e38, 0x5e39, + 0x5e3f, 0x5e3a, 0x5e3b, 0x5e3c, 0x5e3d, 0x5e3e, 0x5e40, 0x5e41, + 0x5e42, 0x5e43, 0x5e44, 0x5e45, 0x5e46, 0x5e47, 0x5e48, 0x5e49, + 0x5e4e, 0x5e4a, 0x5e4b, 0x5e4c, 0x5e4d, 0x5e4f, 0x5e50, 0x5e51, + 0x5e52, 0x5e53, 0x5e54, 0x5e55, 0x5e56, 0x5e57, 0x5e58, 0x5e59, + 0x5e5a, 0x5e5b, 0x5e5c, 0x5e5d, 0x5e5e, 0x5e5f, 0x5e60, 0x5e61, + 0x5e62, 0x5e63, 0x5e64, 0x5e65, 0x5e66, 0x5e67, 0x5e68, 0x5e69, + 0x5e6a, 0x5e6b, 0x5e6c, 0x5e6d, 0x5e6e, 0x5e6f, 0x5e72, 0x5e70, + 0x5e71, 0x5e73, 0x5e74, 0x5e75, 0x5e76, 0x5e77, 0x5e78, 0x5e79, + 0x5e7a, 0x5e7b, 0x5e7c, 0x5e7d, 0x5e7e, 0x5f21, 0x5f22, 0x5f23, + 0x5f24, 0x5f25, 0x5f26, 0x5f27, 0x5f28, 0x5f29, 0x5f2a, 0x5f2b, + 0x5f2c, 0x5f2d, 0x5f2e, 0x5f2f, 0x5f30, 0x5f32, 0x5f31, 0x5f33, + 0x5f34, 0x5f35, 0x5f36, 0x5f37, 0x5f38, 0x5f39, 0x5f3a, 0x5f3b, + 0x5f3c, 0x5f3d, 0x5f3e, 0x5f3f, 0x5f40, 0x5f41, 0x5f42, 0x5f43, + 0x5f44, 0x5f45, 0x5f46, 0x5f47, 0x5f48, 0x5f49, 0x5f4a, 0x5f4b, + 0x5f4c, 0x5f4d, 0x5f4e, 0x5f4f, 0x5f50, 0x5f51, 0x5f52, 0x5f53, + 0x5f54, 0x5f55, 0x5f56, 0x5f57, 0x5f58, 0x5f59, 0x5f5a, 0x5f5b, + 0x5f5c, 0x5f5d, 0x5f6f, 0x5f5e, 0x5f5f, 0x5f60, 0x5f61, 0x5f62, + 0x5f63, 0x5f64, 0x5f65, 0x5f66, 0x5f67, 0x5f68, 0x5f69, 0x5f6a, + 0x5f6b, 0x5f6c, 0x5f6d, 0x5f6e, 0x5f70, 0x5f71, 0x5f72, 0x5f73, + 0x5f74, 0x5f75, 0x5f76, 0x5f77, 0x5f78, 0x5f79, 0x5f7a, 0x5f7b, + 0x5f7c, 0x5f7d, 0x5f7e, 0x6021, 0x6022, 0x6023, 0x6024, 0x6025, + 0x6026, 0x6027, 0x6028, 0x6029, 0x602a, 0x602b, 0x602c, 0x602d, + 0x602e, 0x602f, 0x6030, 0x6031, 0x6032, 0x6033, 0x6034, 0x6035, + 0x6036, 0x6037, 0x6038, 0x6039, 0x603a, 0x603b, 0x603c, 0x603d, + 0x603e, 0x603f, 0x6040, 0x6041, 0x6042, 0x6043, 0x6044, 0x6045, + 0x6046, 0x6047, 0x6048, 0x6049, 0x604a, 0x604b, 0x604c, 0x604d, + 0x604e, 0x604f, 0x6050, 0x6051, 0x6052, 0x6053, 0x6054, 0x6055, + 0x6056, 0x6057, 0x6058, 0x6059, 0x605a, 0x605b, 0x605c, 0x605d, + 0x6064, 0x605e, 0x605f, 0x6060, 0x6061, 0x6062, 0x6063, 0x6065, + 0x6066, 0x6067, 0x6068, 0x6069, 0x606a, 0x606b, 0x606c, 0x606d, + 0x606e, 0x606f, 0x6070, 0x6071, 0x6072, 0x6073, 0x6074, 0x6075, + 0x6076, 0x6077, 0x6078, 0x6079, 0x607a, 0x607b, 0x607c, 0x607d, + 0x607e, 0x6121, 0x6122, 0x6123, 0x6124, 0x6125, 0x6126, 0x6127, + 0x6128, 0x6129, 0x612a, 0x612b, 0x612c, 0x612d, 0x612e, 0x612f, + 0x6130, 0x6131, 0x6132, 0x6133, 0x6134, 0x6135, 0x6136, 0x6137, + 0x6138, 0x6139, 0x613a, 0x613b, 0x613c, 0x613d, 0x613e, 0x613f, + 0x6140, 0x6141, 0x6142, 0x6143, 0x6144, 0x6145, 0x6146, 0x6147, + 0x6148, 0x6149, 0x614a, 0x614b, 0x614c, 0x614d, 0x614e, 0x614f, + 0x6150, 0x6151, 0x6152, 0x6154, 0x6155, 0x6156, 0x6153, 0x6157, + 0x6158, 0x6159, 0x615a, 0x615b, 0x615c, 0x615d, 0x615e, 0x615f, + 0x6160, 0x6161, 0x6162, 0x6163, 0x6164, 0x6165, 0x6166, 0x6167, + 0x6168, 0x6169, 0x616a, 0x616b, 0x616c, 0x616d, 0x616e, 0x616f, + 0x6170, 0x6171, 0x6172, 0x6173, 0x6174, 0x6175, 0x6176, 0x6177, + 0x6178, 0x6179, 0x617a, 0x617b, 0x617d, 0x617e, 0x6221, 0x6222, + 0x6223, 0x6224, 0x617c, 0x622d, 0x6225, 0x6226, 0x6227, 0x6228, + 0x6229, 0x622a, 0x622b, 0x622c, 0x622f, 0x6230, 0x6231, 0x6232, + 0x622e, 0x6233, 0x6234, 0x6235, 0x6236, 0x6237, 0x6238, 0x6239, + 0x623a, 0x623b, 0x623c, 0x623d, 0x623e, 0x623f, 0x6240, 0x6241, + 0x6242, 0x6243, 0x6245, 0x6246, 0x6244, 0x6247, 0x6248, 0x6249, + 0x624a, 0x624b, 0x624c, 0x624d, 0x624e, 0x624f, 0x6250, 0x6251, + 0x6252, 0x6253, 0x6254, 0x6255, 0x6256, 0x6257, 0x6258, 0x6259, + 0x625a, 0x625b, 0x625c, 0x625d, 0x625e, 0x625f, 0x6260, 0x6261, + 0x6262, 0x6263, 0x6264, 0x6265, 0x6266, 0x6267, 0x6268, 0x6269, + 0x626a, 0x626b, 0x626c, 0x626d, 0x626e, 0x626f, 0x6270, 0x6271, + 0x6272, 0x6273, 0x6274, 0x6275, 0x6276, 0x6277, 0x6278, 0x6279, + 0x627a, 0x627b, 0x627c, 0x627d, 0x627e, 0x6321, 0x6322, 0x6323, + 0x6324, 0x6325, 0x6326, 0x6327, 0x6328, 0x6329, 0x632a, 0x632b, + 0x632c, 0x632d, 0x632e, 0x632f, 0x6330, 0x6331, 0x6332, 0x6333, + 0x6334, 0x6335, 0x6336, 0x6337, 0x6338, 0x6339, 0x633a, 0x633b, + 0x633c, 0x633d, 0x633e, 0x633f, 0x6340, 0x6341, 0x6342, 0x6343, + 0x6344, 0x6345, 0x6346, 0x6347, 0x6348, 0x6349, 0x634a, 0x634b, + 0x634c, 0x634d, 0x634e, 0x634f, 0x6350, 0x6351, 0x6352, 0x6353, + 0x6354, 0x6355, 0x6356, 0x6357, 0x6358, 0x6359, 0x635a, 0x635b, + 0x635c, 0x635d, 0x635e, 0x635f, 0x6360, 0x6361, 0x6362, 0x6363, + 0x6364, 0x6365, 0x6366, 0x6367, 0x6368, 0x6369, 0x636a, 0x636b, + 0x636c, 0x636d, 0x636e, 0x636f, 0x6370, 0x6371, 0x6372, 0x6373, + 0x6374, 0x6375, 0x6376, 0x6377, 0x6378, 0x6379, 0x637a, 0x637b, + 0x637c, 0x637d, 0x637e, 0x6421, 0x6422, 0x6423, 0x6424, 0x6425, + 0x6426, 0x6427, 0x6428, 0x6429, 0x642a, 0x642b, 0x642c, 0x642d, + 0x642e, 0x642f, 0x6430, 0x6431, 0x6432, 0x6433, 0x6434, 0x6435, + 0x6436, 0x6437, 0x6438, 0x6439, 0x643a, 0x643b, 0x643c, 0x643d, + 0x643e, 0x643f, 0x6440, 0x6441, 0x6442, 0x6443, 0x6444, 0x6445, + 0x6446, 0x6447, 0x6448, 0x6449, 0x644a, 0x644b, 0x644c, 0x644d, + 0x644e, 0x644f, 0x6450, 0x6451, 0x6452, 0x6453, 0x6454, 0x6455, + 0x6456, 0x6457, 0x6458, 0x6459, 0x645a, 0x645b, 0x645c, 0x645d, + 0x645e, 0x645f, 0x6460, 0x6461, 0x6462, 0x6463, 0x6464, 0x6465, + 0x6466, 0x6467, 0x6468, 0x6469, 0x646a, 0x646b, 0x646c, 0x646d, + 0x646e, 0x646f, 0x6470, 0x6471, 0x6472, 0x6473, 0x6474, 0x6475, + 0x6476, 0x6477, 0x6478, 0x6479, 0x647a, 0x647b, 0x647c, 0x647d, + 0x647e, 0x6521, 0x6522, 0x6523, 0x6524, 0x6525, 0x6526, 0x6527, + 0x6528, 0x6529, 0x652a, 0x652b, 0x652c, 0x652d, 0x652e, 0x652f, + 0x6530, 0x6531, 0x6532, 0x6533, 0x6534, 0x6535, 0x653b, 0x6536, + 0x6537, 0x6538, 0x6539, 0x653a, 0x653c, 0x653d, 0x653e, 0x653f, + 0x6540, 0x6541, 0x6542, 0x6543, 0x6544, 0x6545, 0x6546, 0x6547, + 0x6548, 0x6549, 0x654a, 0x654b, 0x654c, 0x654d, 0x654f, 0x6550, + 0x654e, 0x6551, 0x6552, 0x6553, 0x6554, 0x6555, 0x6556, 0x6557, + 0x6558, 0x6559, 0x655a, 0x655b, 0x655c, 0x655d, 0x655e, 0x655f, + 0x6560, 0x6561, 0x6562, 0x6563, 0x6564, 0x6565, 0x6566, 0x6568, + 0x6567, 0x6569, 0x656a, 0x656b, 0x656c, 0x656d, 0x656e, 0x656f, + 0x6570, 0x6571, 0x6572, 0x6573, 0x6574, 0x6575, 0x6576, 0x6577, + 0x6578, 0x6579, 0x657a, 0x657c, 0x657b, 0x657d, 0x657e, 0x6621, + 0x6622, 0x6623, 0x6624, 0x6625, 0x6626, 0x6627, 0x6628, 0x6629, + 0x662a, 0x662b, 0x662c, 0x662d, 0x662e, 0x662f, 0x6630, 0x6631, + 0x6632, 0x6633, 0x6634, 0x6635, 0x6636, 0x6637, 0x6638, 0x6639, + 0x663a, 0x663b, 0x663c, 0x663d, 0x663e, 0x663f, 0x6640, 0x6641, + 0x6642, 0x6643, 0x6644, 0x6645, 0x6646, 0x6647, 0x6648, 0x6649, + 0x664a, 0x664b, 0x664c, 0x664d, 0x664e, 0x664f, 0x6650, 0x6651, + 0x6652, 0x6653, 0x6654, 0x6655, 0x6656, 0x6657, 0x6658, 0x6659, + 0x665a, 0x665b, 0x665c, 0x665d, 0x665e, 0x665f, 0x6660, 0x6661, + 0x6662, 0x6663, 0x6664, 0x6665, 0x6666, 0x6667, 0x6668, 0x6669, + 0x666a, 0x666b, 0x666c, 0x666d, 0x666e, 0x666f, 0x6670, 0x6671, + 0x6672, 0x6673, 0x6675, 0x6676, 0x6677, 0x6678, 0x6679, 0x667a, + 0x667b, 0x667c, 0x667d, 0x667e, 0x6721, 0x6722, 0x6723, 0x6724, + 0x6725, 0x6726, 0x6727, 0x6728, 0x6729, 0x672a, 0x672b, 0x672c, + 0x672d, 0x672e, 0x672f, 0x6730, 0x6731, 0x6732, 0x6733, 0x6734, + 0x6735, 0x6736, 0x6737, 0x6738, 0x6739, 0x673a, 0x673b, 0x673c, + 0x673d, 0x673e, 0x673f, 0x6740, 0x6741, 0x6742, 0x6743, 0x6744, + 0x6745, 0x6746, 0x6747, 0x6748, 0x6749, 0x674a, 0x674b, 0x674c, + 0x674d, 0x674e, 0x674f, 0x6750, 0x6751, 0x6752, 0x6753, 0x6754, + 0x6755, 0x6756, 0x6757, 0x6758, 0x6759, 0x675a, 0x675b, 0x675c, + 0x675d, 0x675e, 0x675f, 0x6760, 0x6761, 0x6762, 0x6763, 0x6764, + 0x6765, 0x6766, 0x676a, 0x6767, 0x6768, 0x6769, 0x676b, 0x676c, + 0x676d, 0x676e, 0x676f, 0x6770, 0x6771, 0x6772, 0x6773, 0x6774, + 0x6776, 0x6777, 0x6778, 0x6779, 0x6775, 0x677a, 0x677b, 0x677c, + 0x677d, 0x6828, 0x677e, 0x6821, 0x6822, 0x6823, 0x6824, 0x6825, + 0x6826, 0x6827, 0x6829, 0x682a, 0x682b, 0x682c, 0x682d, 0x682e, + 0x682f, 0x6830, 0x6831, 0x6832, 0x6833, 0x6834, 0x6835, 0x6836, + 0x6837, 0x6838, 0x6839, 0x683a, 0x683b, 0x683c, 0x683d, 0x683e, + 0x683f, 0x6840, 0x6841, 0x6842, 0x6843, 0x6844, 0x6845, 0x6846, + 0x6847, 0x6848, 0x6849, 0x684a, 0x684b, 0x684c, 0x684d, 0x684e, + 0x684f, 0x6850, 0x6851, 0x6852, 0x6853, 0x6854, 0x6855, 0x6856, + 0x6857, 0x6858, 0x6859, 0x685a, 0x685b, 0x685c, 0x685d, 0x685e, + 0x685f, 0x6860, 0x6861, 0x6862, 0x6863, 0x6864, 0x6865, 0x6866, + 0x6867, 0x6868, 0x6869, 0x686a, 0x686b, 0x686c, 0x686d, 0x686e, + 0x686f, 0x6870, 0x6871, 0x6872, 0x6873, 0x6874, 0x6875, 0x6876, + 0x6877, 0x6878, 0x6879, 0x687a, 0x687b, 0x687c, 0x687d, 0x687e, + 0x6921, 0x6922, 0x6923, 0x6924, 0x6925, 0x6926, 0x6927, 0x6928, + 0x6929, 0x692a, 0x692b, 0x692c, 0x692d, 0x692e, 0x692f, 0x6930, + 0x6931, 0x6932, 0x6933, 0x6934, 0x6935, 0x6936, 0x6937, 0x6938, + 0x6939, 0x693a, 0x693b, 0x693c, 0x693d, 0x693e, 0x693f, 0x6940, + 0x6941, 0x6942, 0x6943, 0x6944, 0x6945, 0x6946, 0x6947, 0x6948, + 0x6949, 0x694a, 0x694c, 0x694d, 0x694b, 0x694e, 0x694f, 0x6950, + 0x6951, 0x6952, 0x6953, 0x6954, 0x6955, 0x6956, 0x6957, 0x6958, + 0x6959, 0x695a, 0x695b, 0x695c, 0x695d, 0x695e, 0x695f, 0x6960, + 0x6961, 0x6962, 0x6963, 0x6964, 0x6965, 0x6966, 0x6967, 0x6968, + 0x6969, 0x696a, 0x696b, 0x696c, 0x696d, 0x696e, 0x696f, 0x6970, + 0x6971, 0x6972, 0x6973, 0x6974, 0x6975, 0x6976, 0x6977, 0x6978, + 0x6979, 0x697a, 0x697b, 0x697c, 0x697d, 0x697e, 0x6a21, 0x6a22, + 0x6a23, 0x6a24, 0x6a25, 0x6a26, 0x6a27, 0x6a28, 0x6a29, 0x6a2a, + 0x6a2b, 0x6a2c, 0x6a2d, 0x6a2e, 0x6a2f, 0x6a30, 0x6a31, 0x6a32, + 0x6a33, 0x6a34, 0x6a35, 0x6a36, 0x6a37, 0x6a38, 0x6a39, 0x6a3a, + 0x6a3b, 0x6a3c, 0x6a3d, 0x6a3e, 0x6a3f, 0x6a40, 0x6a41, 0x6a42, + 0x6a43, 0x6a44, 0x6a45, 0x6a46, 0x6a47, 0x6a48, 0x6a49, 0x6a4a, + 0x6a4b, 0x6a4c, 0x6a4d, 0x6a4e, 0x6a4f, 0x6a50, 0x6a51, 0x6a52, + 0x6a53, 0x6a54, 0x6a55, 0x6a56, 0x6a57, 0x6a58, 0x6a59, 0x6a5a, + 0x6a5b, 0x6a5c, 0x6a5d, 0x6a5e, 0x6a5f, 0x6a60, 0x6a61, 0x6a62, + 0x6a63, 0x6a64, 0x6a65, 0x6a66, 0x6a67, 0x6a68, 0x6a69, 0x6a6a, + 0x6a6b, 0x6a6c, 0x6a6d, 0x6a6e, 0x6a6f, 0x6a70, 0x6a71, 0x6a72, + 0x6a73, 0x6a74, 0x6a75, 0x6a76, 0x6a77, 0x6a78, 0x6a79, 0x6a7a, + 0x6a7b, 0x6a7c, 0x6a7d, 0x6a7e, 0x6b21, 0x6b22, 0x6b23, 0x6b24, + 0x6b25, 0x6b26, 0x6b27, 0x6b28, 0x6b29, 0x6b2a, 0x6b2b, 0x6b2c, + 0x6b2d, 0x6b2e, 0x6b2f, 0x6b30, 0x6b31, 0x6b32, 0x6b33, 0x6b34, + 0x6b35, 0x6b36, 0x6b37, 0x6b38, 0x6b39, 0x6b3a, 0x6b3b, 0x6b3c, + 0x6b3d, 0x6b3e, 0x6b3f, 0x6b40, 0x6b41, 0x6b42, 0x6b43, 0x6b44, + 0x6b45, 0x6b46, 0x6b47, 0x6b48, 0x6b49, 0x6b50, 0x6b4a, 0x6b4b, + 0x6b4c, 0x6b4d, 0x6b52, 0x6b4e, 0x6b4f, 0x6b51, 0x6b53, 0x6b54, + 0x6b55, 0x6b56, 0x6b57, 0x6b58, 0x6b59, 0x6b5a, 0x6b5b, 0x6b5c, + 0x6b5e, 0x6b5d, 0x6b5f, 0x6b60, 0x6b61, 0x6b62, 0x6b63, 0x6b64, + 0x6b65, 0x6b66, 0x6b67, 0x6b68, 0x6b69, 0x6b6a, 0x6b6b, 0x6b6d, + 0x6b6e, 0x6b6f, 0x6b6c, 0x6b70, 0x6b71, 0x6b72, 0x6b73, 0x6b74, + 0x6b76, 0x6b75, 0x6b77, 0x6b78, 0x6b79, 0x6b7a, 0x6b7b, 0x6b7c, + 0x6b7d, 0x6b7e, 0x6c21, 0x6c22, 0x6c23, 0x6c24, 0x6c25, 0x6c26, + 0x6c27, 0x6c28, 0x6c29, 0x6c2a, 0x6c2b, 0x6c2c, 0x6c2d, 0x6c2e, + 0x6c2f, 0x6c30, 0x6c31, 0x6c32, 0x6c33, 0x6c34, 0x6c35, 0x6c36, + 0x6c37, 0x6c38, 0x6c39, 0x6c3a, 0x6c3b, 0x6c3c, 0x6c3d, 0x6c3e, + 0x6c3f, 0x6c40, 0x6c41, 0x6c42, 0x6c43, 0x6c44, 0x6c45, 0x6c46, + 0x6c47, 0x6c48, 0x6c49, 0x6c4a, 0x6c4b, 0x6c4c, 0x6c4e, 0x6c4f, + 0x6c4d, 0x6c50, 0x6c51, 0x6c52, 0x6c53, 0x6c54, 0x6c55, 0x6c56, + 0x6c57, 0x6c58, 0x6c59, 0x6c5a, 0x6c5b, 0x6c5c, 0x6c5d, 0x6c5e, + 0x6c5f, 0x6c60, 0x6c61, 0x6c62, 0x6c63, 0x6c64, 0x6c65, 0x6c66, + 0x6c67, 0x6c68, 0x6c69, 0x6c6a, 0x6c6b, 0x6c6c, 0x6c6d, 0x6c6e, + 0x6c6f, 0x6c70, 0x6c71, 0x6c72, 0x6c73, 0x6c74, 0x6c75, 0x6c76, + 0x6c77, 0x6c78, 0x6c79, 0x6c7a, 0x6c7b, 0x6c7c, 0x6c7d, 0x6c7e, + 0x6d21, 0x6d22, 0x6d23, 0x6d24, 0x6d25, 0x6d26, 0x6d27, 0x6d28, + 0x6d29, 0x6d2a, 0x6d2b, 0x6d2c, 0x6d2d, 0x6d2e, 0x6d2f, 0x6d30, + 0x6d31, 0x6d32, 0x6d33, 0x6d34, 0x6d35, 0x6d36, 0x6d37, 0x6d38, + 0x6d39, 0x6d3a, 0x6d3b, 0x6d3c, 0x6d3d, 0x6d3e, 0x6d3f, 0x6d40, + 0x6d41, 0x6d42, 0x6d43, 0x6d44, 0x6d45, 0x6d46, 0x6d47, 0x6d48, + 0x6d49, 0x6d4a, 0x6d4b, 0x6d4c, 0x6d4d, 0x6d4e, 0x6d4f, 0x6d50, + 0x6d51, 0x6d52, 0x6d53, 0x6d54, 0x6d55, 0x6d56, 0x6d57, 0x6d58, + 0x6d59, 0x6d5a, 0x6d5b, 0x6d5c, 0x6d5d, 0x6d5e, 0x6d5f, 0x6d60, + 0x6d61, 0x6d62, 0x6d63, +}; + +static const Summary16 jisx0212_uni2indx_page00[70] = { + /* 0x0000 */ + { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, + { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x4000 }, + { 1, 0x0000 }, { 1, 0x0000 }, { 1, 0xc652 }, { 8, 0x8500 }, + { 11, 0xffff }, { 27, 0xff7e }, { 41, 0xffff }, { 57, 0xff7f }, + /* 0x0100 */ + { 72, 0xffff }, { 88, 0xffcf }, { 102, 0xcff7 }, { 115, 0xffff }, + { 131, 0x3fff }, { 145, 0xffff }, { 161, 0xffff }, { 177, 0x7fff }, + { 192, 0x0000 }, { 192, 0x0000 }, { 192, 0x0000 }, { 192, 0x0000 }, + { 192, 0xe000 }, { 195, 0x1fff }, { 208, 0x0000 }, { 208, 0x0020 }, + /* 0x0200 */ + { 209, 0x0000 }, { 209, 0x0000 }, { 209, 0x0000 }, { 209, 0x0000 }, + { 209, 0x0000 }, { 209, 0x0000 }, { 209, 0x0000 }, { 209, 0x0000 }, + { 209, 0x0000 }, { 209, 0x0000 }, { 209, 0x0000 }, { 209, 0x0000 }, + { 209, 0x0080 }, { 210, 0x2f00 }, { 215, 0x0000 }, { 215, 0x0000 }, + /* 0x0300 */ + { 215, 0x0000 }, { 215, 0x0000 }, { 215, 0x0000 }, { 215, 0x0000 }, + { 215, 0x0000 }, { 215, 0x0000 }, { 215, 0x0000 }, { 215, 0x0000 }, + { 215, 0xd770 }, { 224, 0x0001 }, { 225, 0xfc00 }, { 231, 0x0001 }, + { 232, 0x7c04 }, { 238, 0x0000 }, { 238, 0x0000 }, { 238, 0x0000 }, + /* 0x0400 */ + { 238, 0xdffc }, { 251, 0x0000 }, { 251, 0x0000 }, { 251, 0x0000 }, + { 251, 0x0000 }, { 251, 0xdffc }, +}; +static const Summary16 jisx0212_uni2indx_page21[3] = { + /* 0x2100 */ + { 264, 0x0000 }, { 264, 0x0040 }, { 265, 0x0004 }, +}; +static const Summary16 jisx0212_uni2indx_page4e[1307] = { + /* 0x4e00 */ + { 266, 0x1034 }, { 270, 0x8004 }, { 272, 0xc918 }, { 278, 0x0021 }, + { 280, 0x0093 }, { 284, 0x1402 }, { 287, 0x0308 }, { 290, 0x8230 }, + { 294, 0x2000 }, { 295, 0x20c0 }, { 298, 0x8000 }, { 299, 0x0200 }, + { 300, 0x0008 }, { 301, 0x0c01 }, { 304, 0x8107 }, { 309, 0xe02a }, + /* 0x4f00 */ + { 315, 0x190d }, { 321, 0x02e4 }, { 326, 0x4000 }, { 327, 0x4aaa }, + { 334, 0x1b05 }, { 340, 0x8154 }, { 345, 0x5409 }, { 350, 0x6782 }, + { 357, 0x5636 }, { 365, 0xc69d }, { 374, 0x0000 }, { 374, 0x7a84 }, + { 381, 0xbb63 }, { 391, 0x1004 }, { 393, 0x0005 }, { 395, 0xb005 }, + /* 0x5000 */ + { 400, 0x5493 }, { 407, 0x7989 }, { 415, 0x4084 }, { 418, 0x082d }, + { 423, 0x5467 }, { 431, 0x828e }, { 437, 0x24cd }, { 444, 0x0003 }, + { 446, 0xc45a }, { 453, 0xd85d }, { 462, 0x8407 }, { 467, 0x2601 }, + { 471, 0x5099 }, { 477, 0xb119 }, { 484, 0x8354 }, { 490, 0x4446 }, + /* 0x5100 */ + { 495, 0x79c8 }, { 503, 0x7a81 }, { 510, 0xb188 }, { 516, 0x033a }, + { 522, 0x8404 }, { 525, 0x81a8 }, { 530, 0x0050 }, { 532, 0x4000 }, + { 533, 0x4818 }, { 537, 0x2100 }, { 539, 0x200a }, { 542, 0xd500 }, + { 547, 0x8104 }, { 550, 0x412e }, { 556, 0x4024 }, { 559, 0x009c }, + /* 0x5200 */ + { 563, 0x0026 }, { 566, 0x016c }, { 571, 0x0104 }, { 573, 0x1026 }, + { 577, 0x0220 }, { 579, 0x95a0 }, { 585, 0x4043 }, { 589, 0x0380 }, + { 592, 0x1425 }, { 597, 0x15e8 }, { 604, 0x80f0 }, { 609, 0x2dc1 }, + { 616, 0x9151 }, { 622, 0x1852 }, { 627, 0x1722 }, { 633, 0x00d3 }, + /* 0x5300 */ + { 638, 0x1c09 }, { 643, 0xd90a }, { 650, 0x3ba0 }, { 657, 0x7025 }, + { 663, 0x1804 }, { 666, 0x0a00 }, { 668, 0x302a }, { 673, 0x4204 }, + { 676, 0x4188 }, { 680, 0x2218 }, { 684, 0x8c12 }, { 689, 0x25b4 }, + { 696, 0x8021 }, { 699, 0x642c }, { 705, 0x00c1 }, { 708, 0x0020 }, + /* 0x5400 */ + { 709, 0x0004 }, { 710, 0x0408 }, { 712, 0x8582 }, { 717, 0x0032 }, + { 720, 0xa098 }, { 725, 0x4000 }, { 726, 0x6ad4 }, { 734, 0x8010 }, + { 736, 0x232a }, { 742, 0x9062 }, { 747, 0x66c2 }, { 754, 0x8e82 }, + { 760, 0x6440 }, { 764, 0x0000 }, { 764, 0x9401 }, { 768, 0xd040 }, + /* 0x5500 */ + { 772, 0x7323 }, { 780, 0x0020 }, { 781, 0x0c00 }, { 783, 0x3864 }, + { 789, 0x2682 }, { 794, 0x4d03 }, { 800, 0x0053 }, { 804, 0x8000 }, + { 805, 0xc146 }, { 811, 0x009e }, { 816, 0x2018 }, { 819, 0x8004 }, + { 821, 0x5a4a }, { 828, 0x498e }, { 835, 0x0204 }, { 837, 0x8040 }, + /* 0x5600 */ + { 839, 0xe520 }, { 845, 0x0207 }, { 849, 0x1000 }, { 850, 0xbaa9 }, + { 859, 0xaa5b }, { 868, 0x4010 }, { 870, 0xa24f }, { 878, 0x0026 }, + { 881, 0x1930 }, { 886, 0xe620 }, { 892, 0x3bc0 }, { 899, 0x408a }, + { 903, 0xbe20 }, { 910, 0xb201 }, { 915, 0x29f2 }, { 923, 0x00c2 }, + /* 0x5700 */ + { 926, 0x1486 }, { 931, 0x2c22 }, { 936, 0xd63d }, { 946, 0xe018 }, + { 951, 0x3060 }, { 955, 0x0004 }, { 956, 0xe9a4 }, { 964, 0x5ebb }, + { 975, 0x100a }, { 978, 0xf6b0 }, { 987, 0x1382 }, { 992, 0x2100 }, + { 994, 0x9180 }, { 998, 0x6020 }, { 1001, 0x22d2 }, { 1007, 0xe161 }, + /* 0x5800 */ + { 1014, 0x3318 }, { 1020, 0xc800 }, { 1023, 0x20c1 }, { 1027, 0x8204 }, + { 1030, 0xb200 }, { 1034, 0x8021 }, { 1037, 0x0192 }, { 1041, 0x9100 }, + { 1044, 0xb783 }, { 1053, 0x2051 }, { 1057, 0x0247 }, { 1062, 0x1006 }, + { 1065, 0x6114 }, { 1070, 0x2455 }, { 1076, 0x0206 }, { 1079, 0x0008 }, + /* 0x5900 */ + { 1080, 0x1860 }, { 1084, 0x201c }, { 1088, 0x811a }, { 1093, 0x8069 }, + { 1098, 0x0048 }, { 1100, 0xea0c }, { 1107, 0xa80a }, { 1112, 0x1a64 }, + { 1118, 0x5800 }, { 1121, 0x80a4 }, { 1125, 0xe090 }, { 1130, 0x1489 }, + { 1135, 0x251a }, { 1141, 0xe004 }, { 1145, 0xc098 }, { 1150, 0x0096 }, + /* 0x5a00 */ + { 1154, 0x7011 }, { 1159, 0x400c }, { 1162, 0x2598 }, { 1168, 0x0001 }, + { 1169, 0x11b0 }, { 1174, 0x4021 }, { 1177, 0x20a8 }, { 1181, 0x4c80 }, + { 1185, 0x0800 }, { 1186, 0xd249 }, { 1193, 0x1085 }, { 1197, 0x8d2e }, + { 1205, 0x8150 }, { 1209, 0x1400 }, { 1211, 0x4421 }, { 1215, 0x2060 }, + /* 0x5b00 */ + { 1218, 0x0103 }, { 1221, 0x2a80 }, { 1225, 0x2022 }, { 1228, 0x0110 }, + { 1230, 0x1802 }, { 1233, 0x4044 }, { 1236, 0xc100 }, { 1239, 0xf000 }, + { 1243, 0x4452 }, { 1248, 0x005b }, { 1253, 0xb300 }, { 1258, 0x1486 }, + { 1263, 0xa003 }, { 1267, 0x07c0 }, { 1272, 0x8001 }, { 1274, 0x2012 }, + /* 0x5c00 */ + { 1277, 0x1000 }, { 1278, 0xc080 }, { 1281, 0x5a48 }, { 1287, 0x0065 }, + { 1291, 0x0000 }, { 1291, 0x1600 }, { 1294, 0x238c }, { 1300, 0x3c31 }, + { 1307, 0x8580 }, { 1311, 0xa004 }, { 1314, 0x044d }, { 1319, 0x0434 }, + { 1323, 0x0a00 }, { 1325, 0x2084 }, { 1328, 0x4000 }, { 1329, 0x0016 }, + /* 0x5d00 */ + { 1332, 0x2042 }, { 1335, 0x0004 }, { 1336, 0x08d8 }, { 1341, 0xa212 }, + { 1346, 0x054c }, { 1351, 0x8222 }, { 1355, 0x2417 }, { 1361, 0xc601 }, + { 1366, 0x050a }, { 1370, 0x8a3c }, { 1377, 0x0881 }, { 1380, 0x0315 }, + { 1385, 0x4888 }, { 1389, 0x0301 }, { 1392, 0x0211 }, { 1395, 0x0300 }, + /* 0x5e00 */ + { 1397, 0x2081 }, { 1400, 0x8134 }, { 1405, 0x4101 }, { 1408, 0x4024 }, + { 1411, 0x0a00 }, { 1413, 0x5943 }, { 1420, 0x7d00 }, { 1426, 0x0001 }, + { 1427, 0x4801 }, { 1430, 0x0000 }, { 1430, 0x1534 }, { 1436, 0xe00a }, + { 1441, 0x5840 }, { 1445, 0x5036 }, { 1451, 0x0820 }, { 1453, 0x0000 }, + /* 0x5f00 */ + { 1453, 0x41c4 }, { 1458, 0x3200 }, { 1461, 0x591e }, { 1469, 0xa851 }, + { 1475, 0x20b1 }, { 1480, 0x0911 }, { 1484, 0x8099 }, { 1489, 0x6534 }, + { 1496, 0xa200 }, { 1499, 0x3040 }, { 1502, 0x9894 }, { 1508, 0x0103 }, + { 1511, 0x0b90 }, { 1516, 0x401f }, { 1522, 0xf706 }, { 1531, 0x144c }, + /* 0x6000 */ + { 1536, 0x2480 }, { 1539, 0x8598 }, { 1545, 0x2010 }, { 1547, 0x0028 }, + { 1549, 0x1381 }, { 1554, 0x20d2 }, { 1559, 0x0082 }, { 1561, 0xc002 }, + { 1564, 0x4544 }, { 1569, 0x612a }, { 1575, 0x0134 }, { 1579, 0x4883 }, + { 1584, 0xcf14 }, { 1592, 0x6a30 }, { 1598, 0x0024 }, { 1600, 0x3124 }, + /* 0x6100 */ + { 1605, 0x1484 }, { 1609, 0x52df }, { 1619, 0x0c04 }, { 1622, 0x02e3 }, + { 1628, 0x0262 }, { 1632, 0x4000 }, { 1633, 0x1001 }, { 1635, 0x9904 }, + { 1640, 0x281b }, { 1646, 0xb18c }, { 1653, 0x2521 }, { 1658, 0x1300 }, + { 1661, 0xc007 }, { 1666, 0xf020 }, { 1671, 0xb2a6 }, { 1679, 0x0000 }, + /* 0x6200 */ + { 1679, 0x009a }, { 1683, 0x1028 }, { 1686, 0x0a8d }, { 1692, 0x2200 }, + { 1694, 0x105c }, { 1699, 0x1457 }, { 1706, 0xa010 }, { 1709, 0x2408 }, + { 1712, 0xe000 }, { 1715, 0x0001 }, { 1716, 0x0140 }, { 1718, 0xc4c8 }, + { 1724, 0x4010 }, { 1726, 0x0460 }, { 1729, 0x0400 }, { 1730, 0x3014 }, + /* 0x6300 */ + { 1734, 0x2c18 }, { 1739, 0x0149 }, { 1743, 0x2600 }, { 1746, 0x1260 }, + { 1750, 0x4c5e }, { 1758, 0x091c }, { 1763, 0x3060 }, { 1767, 0xb132 }, + { 1774, 0x0494 }, { 1778, 0x4631 }, { 1784, 0xe050 }, { 1789, 0x2000 }, + { 1790, 0x4122 }, { 1794, 0x103a }, { 1799, 0x1421 }, { 1803, 0x032c }, + /* 0x6400 */ + { 1808, 0x0600 }, { 1810, 0x4115 }, { 1815, 0x8635 }, { 1822, 0xa021 }, + { 1826, 0x8800 }, { 1828, 0xbc1e }, { 1837, 0x200b }, { 1841, 0x2818 }, + { 1845, 0x80a0 }, { 1848, 0xab03 }, { 1855, 0x114a }, { 1860, 0xe008 }, + { 1864, 0x5e10 }, { 1870, 0x00a3 }, { 1874, 0x2630 }, { 1879, 0x88a1 }, + /* 0x6500 */ + { 1884, 0x8712 }, { 1890, 0xca58 }, { 1897, 0x4244 }, { 1901, 0x3402 }, + { 1905, 0x0288 }, { 1908, 0x8015 }, { 1912, 0x0881 }, { 1915, 0x2400 }, + { 1917, 0x0422 }, { 1920, 0x2124 }, { 1924, 0x4049 }, { 1928, 0x801c }, + { 1932, 0x4304 }, { 1936, 0x8151 }, { 1941, 0x0000 }, { 1941, 0xc235 }, + /* 0x6600 */ + { 1948, 0x2311 }, { 1953, 0x6066 }, { 1959, 0x5e5e }, { 1969, 0x028b }, + { 1974, 0x5461 }, { 1980, 0x1b82 }, { 1986, 0x1c03 }, { 1991, 0xdba8 }, + { 2000, 0x3801 }, { 2004, 0x9e05 }, { 2011, 0x2011 }, { 2014, 0x8826 }, + { 2019, 0xd10d }, { 2026, 0x8810 }, { 2029, 0x5900 }, { 2033, 0x0c00 }, + /* 0x6700 */ + { 2035, 0x40a0 }, { 2038, 0x1208 }, { 2041, 0x0005 }, { 2043, 0x4008 }, + { 2045, 0x11a0 }, { 2049, 0x2030 }, { 2052, 0x5040 }, { 2055, 0x0850 }, + { 2058, 0xc012 }, { 2062, 0x0b4a }, { 2068, 0x0000 }, { 2068, 0x3827 }, + { 2075, 0x032d }, { 2081, 0x1284 }, { 2085, 0x0042 }, { 2087, 0x02c5 }, + /* 0x6800 */ + { 2092, 0x0000 }, { 2092, 0xa210 }, { 2096, 0xb180 }, { 2101, 0x880b }, + { 2106, 0x1430 }, { 2110, 0x09a4 }, { 2115, 0xc800 }, { 2118, 0x1e27 }, + { 2126, 0x0154 }, { 2130, 0x1540 }, { 2134, 0x462a }, { 2140, 0x0804 }, + { 2142, 0x9120 }, { 2146, 0x324b }, { 2153, 0x3d20 }, { 2159, 0x3863 }, + /* 0x6900 */ + { 2166, 0x0640 }, { 2169, 0x00cb }, { 2174, 0x0000 }, { 2174, 0x092a }, + { 2179, 0x4224 }, { 2183, 0x0880 }, { 2185, 0x1378 }, { 2192, 0x8c07 }, + { 2198, 0x2001 }, { 2200, 0x0144 }, { 2203, 0xa962 }, { 2210, 0x1580 }, + { 2214, 0x0120 }, { 2216, 0x00c2 }, { 2219, 0xc024 }, { 2223, 0x402a }, + /* 0x6a00 */ + { 2227, 0x800b }, { 2231, 0x2422 }, { 2235, 0x0111 }, { 2238, 0xc895 }, + { 2245, 0x4660 }, { 2250, 0x0867 }, { 2256, 0x0490 }, { 2259, 0x400a }, + { 2262, 0x0aca }, { 2268, 0xe802 }, { 2273, 0x8820 }, { 2276, 0xe013 }, + { 2282, 0x1340 }, { 2286, 0x3071 }, { 2292, 0x1090 }, { 2295, 0x3007 }, + /* 0x6b00 */ + { 2300, 0x82cc }, { 2306, 0x4883 }, { 2311, 0x9910 }, { 2316, 0x8860 }, + { 2320, 0x2440 }, { 2323, 0x2144 }, { 2327, 0x4881 }, { 2331, 0x6021 }, + { 2335, 0x0024 }, { 2337, 0x8880 }, { 2340, 0x730d }, { 2348, 0x6301 }, + { 2353, 0x1218 }, { 2357, 0x0440 }, { 2359, 0x40ca }, { 2364, 0x8282 }, + /* 0x6c00 */ + { 2368, 0x6234 }, { 2374, 0x8205 }, { 2378, 0x51c0 }, { 2383, 0x8c68 }, + { 2389, 0xac00 }, { 2393, 0x1a14 }, { 2398, 0xa880 }, { 2402, 0x0b50 }, + { 2407, 0x02e0 }, { 2411, 0x91b0 }, { 2417, 0x0000 }, { 2417, 0x0015 }, + { 2420, 0xa044 }, { 2424, 0x1457 }, { 2431, 0x5a81 }, { 2437, 0x0014 }, + /* 0x6d00 */ + { 2439, 0xc490 }, { 2444, 0x040a }, { 2447, 0xc1c0 }, { 2452, 0x9202 }, + { 2456, 0x0000 }, { 2456, 0xc080 }, { 2459, 0x80a2 }, { 2463, 0x1001 }, + { 2465, 0x0084 }, { 2467, 0x01d6 }, { 2473, 0x1400 }, { 2475, 0xa290 }, + { 2480, 0xc510 }, { 2485, 0xa840 }, { 2489, 0x8225 }, { 2494, 0x1051 }, + /* 0x6e00 */ + { 2498, 0x0011 }, { 2500, 0x4000 }, { 2501, 0x0084 }, { 2503, 0x1a44 }, + { 2508, 0x8b30 }, { 2514, 0x709e }, { 2522, 0x010c }, { 2525, 0x2808 }, + { 2528, 0x2000 }, { 2529, 0x0208 }, { 2531, 0x6081 }, { 2535, 0x880a }, + { 2539, 0xe58b }, { 2548, 0x0000 }, { 2548, 0x6800 }, { 2551, 0x2a00 }, + /* 0x6f00 */ + { 2554, 0x3510 }, { 2559, 0x0d40 }, { 2563, 0xa640 }, { 2568, 0x1849 }, + { 2573, 0x8000 }, { 2574, 0x668e }, { 2582, 0x1106 }, { 2586, 0x6000 }, + { 2588, 0x3988 }, { 2594, 0x845d }, { 2601, 0xc1e1 }, { 2608, 0x1061 }, + { 2612, 0x05a0 }, { 2616, 0x4400 }, { 2618, 0x0300 }, { 2620, 0x3221 }, + /* 0x7000 */ + { 2625, 0x20e1 }, { 2630, 0x0080 }, { 2631, 0x8009 }, { 2634, 0x1290 }, + { 2638, 0x4f18 }, { 2645, 0x6030 }, { 2649, 0x5030 }, { 2653, 0x4060 }, + { 2656, 0x0062 }, { 2659, 0x09f0 }, { 2665, 0x0810 }, { 2667, 0x0093 }, + { 2671, 0x0400 }, { 2672, 0x117a }, { 2679, 0x0010 }, { 2680, 0x0400 }, + /* 0x7100 */ + { 2681, 0x98f8 }, { 2689, 0x4000 }, { 2690, 0xa801 }, { 2694, 0x0103 }, + { 2697, 0x0ce2 }, { 2703, 0x5485 }, { 2709, 0x0101 }, { 2711, 0x0200 }, + { 2712, 0x10a1 }, { 2716, 0x0c04 }, { 2719, 0x8005 }, { 2722, 0x840d }, + { 2727, 0x1813 }, { 2732, 0x1648 }, { 2737, 0x0000 }, { 2737, 0x4100 }, + /* 0x7200 */ + { 2739, 0x0381 }, { 2743, 0xa488 }, { 2748, 0x8810 }, { 2751, 0x0310 }, + { 2754, 0xc02e }, { 2760, 0x5469 }, { 2767, 0xc909 }, { 2773, 0x9982 }, + { 2779, 0x6210 }, { 2783, 0x0808 }, { 2785, 0x6100 }, { 2788, 0x4012 }, + { 2791, 0x1282 }, { 2795, 0x8160 }, { 2799, 0x0020 }, { 2800, 0x4c18 }, + /* 0x7300 */ + { 2805, 0x28b4 }, { 2811, 0x430c }, { 2816, 0x1194 }, { 2821, 0x2c26 }, + { 2827, 0x2008 }, { 2829, 0xe145 }, { 2836, 0xdac1 }, { 2844, 0x1282 }, + { 2848, 0x406b }, { 2854, 0xd1a9 }, { 2862, 0x2c65 }, { 2869, 0xb2a0 }, + { 2875, 0x9a60 }, { 2881, 0x224c }, { 2886, 0x02ca }, { 2891, 0xaeb0 }, + /* 0x7400 */ + { 2899, 0x0493 }, { 2904, 0x0c02 }, { 2907, 0xff50 }, { 2917, 0x0203 }, + { 2920, 0x28d9 }, { 2927, 0x2086 }, { 2931, 0x69c4 }, { 2938, 0x0006 }, + { 2940, 0x82e3 }, { 2947, 0x9707 }, { 2955, 0xcf4b }, { 2965, 0x8a26 }, + { 2971, 0x1300 }, { 2974, 0xcd09 }, { 2981, 0x8d10 }, { 2986, 0x9c10 }, + /* 0x7500 */ + { 2991, 0x0040 }, { 2992, 0x00c4 }, { 2995, 0x8693 }, { 3002, 0xe240 }, + { 3007, 0x4189 }, { 3012, 0xc085 }, { 3017, 0x8002 }, { 3019, 0x7e02 }, + { 3026, 0x0022 }, { 3028, 0x122d }, { 3034, 0x0014 }, { 3036, 0x8410 }, + { 3039, 0xd053 }, { 3046, 0x9080 }, { 3049, 0xd093 }, { 3056, 0x0202 }, + /* 0x7600 */ + { 3058, 0x959d }, { 3067, 0x7a6c }, { 3076, 0x2268 }, { 3081, 0x172c }, + { 3088, 0x0e3b }, { 3096, 0x8220 }, { 3099, 0xe030 }, { 3104, 0x0012 }, + { 3106, 0x3022 }, { 3110, 0xb820 }, { 3115, 0x25fd }, { 3125, 0x2000 }, + { 3126, 0x5a22 }, { 3132, 0x0210 }, { 3134, 0x1141 }, { 3138, 0x1243 }, + /* 0x7700 */ + { 3143, 0x4441 }, { 3147, 0x16b4 }, { 3154, 0xe104 }, { 3159, 0x6270 }, + { 3165, 0xe464 }, { 3172, 0xd0c4 }, { 3178, 0x1495 }, { 3184, 0x241d }, + { 3190, 0x3011 }, { 3194, 0x8470 }, { 3199, 0xc484 }, { 3204, 0x4022 }, + { 3207, 0x0208 }, { 3209, 0xc226 }, { 3215, 0x1451 }, { 3220, 0x0913 }, + /* 0x7800 */ + { 3225, 0x6260 }, { 3230, 0x2002 }, { 3232, 0x600e }, { 3237, 0x00a1 }, + { 3240, 0x5198 }, { 3246, 0x5004 }, { 3249, 0x451b }, { 3256, 0x4400 }, + { 3258, 0x8400 }, { 3260, 0xe110 }, { 3265, 0x3112 }, { 3270, 0xa80f }, + { 3277, 0x5380 }, { 3282, 0x886c }, { 3288, 0x0453 }, { 3293, 0x8ccc }, + /* 0x7900 */ + { 3300, 0x1041 }, { 3303, 0xd401 }, { 3308, 0x22a1 }, { 3313, 0xa832 }, + { 3319, 0x8c70 }, { 3325, 0x1912 }, { 3330, 0x0a80 }, { 3333, 0x5a04 }, + { 3338, 0x1800 }, { 3340, 0x197a }, { 3348, 0x8b02 }, { 3353, 0x0912 }, + { 3357, 0x8594 }, { 3363, 0x6450 }, { 3368, 0x2c25 }, { 3374, 0x1102 }, + /* 0x7a00 */ + { 3377, 0x168c }, { 3383, 0x4822 }, { 3387, 0xa882 }, { 3392, 0x0731 }, + { 3398, 0x11b0 }, { 3403, 0xb260 }, { 3409, 0x24a1 }, { 3414, 0x4120 }, + { 3417, 0x0c65 }, { 3423, 0x4013 }, { 3427, 0x1009 }, { 3430, 0x1a28 }, + { 3435, 0x5240 }, { 3439, 0x0802 }, { 3441, 0x1b00 }, { 3445, 0x6812 }, + /* 0x7b00 */ + { 3450, 0x0080 }, { 3451, 0x8010 }, { 3453, 0xee88 }, { 3461, 0xa013 }, + { 3466, 0x4083 }, { 3470, 0x0020 }, { 3471, 0xa651 }, { 3478, 0x008c }, + { 3481, 0x4210 }, { 3484, 0x4843 }, { 3489, 0x9021 }, { 3493, 0x3c65 }, + { 3501, 0x0524 }, { 3505, 0x0ed0 }, { 3511, 0x0500 }, { 3513, 0x5734 }, + /* 0x7c00 */ + { 3521, 0xda5e }, { 3531, 0x0a00 }, { 3533, 0x1161 }, { 3538, 0x065a }, + { 3544, 0x0440 }, { 3546, 0x7e2e }, { 3556, 0x628a }, { 3562, 0x3205 }, + { 3567, 0x80c0 }, { 3570, 0x4010 }, { 3572, 0x0041 }, { 3574, 0x9cc1 }, + { 3581, 0xa390 }, { 3587, 0x26b8 }, { 3594, 0x0a40 }, { 3597, 0x0020 }, + /* 0x7d00 */ + { 3598, 0x8388 }, { 3603, 0x604e }, { 3609, 0x2448 }, { 3613, 0x7002 }, + { 3617, 0x2183 }, { 3622, 0x368a }, { 3629, 0x04a0 }, { 3632, 0x8d01 }, + { 3637, 0x396e }, { 3646, 0x60c2 }, { 3651, 0x04c0 }, { 3654, 0x02c8 }, + { 3658, 0x707c }, { 3666, 0x0280 }, { 3668, 0x2c64 }, { 3674, 0x0662 }, + /* 0x7e00 */ + { 3679, 0x0101 }, { 3681, 0x30a3 }, { 3687, 0xb181 }, { 3693, 0x8048 }, + { 3696, 0x40b0 }, { 3700, 0x8105 }, { 3704, 0xc826 }, { 3710, 0x4108 }, + { 3713, 0x24c2 }, { 3718, 0x6522 }, { 3724, 0x0000 }, { 3724, 0x0000 }, + { 3724, 0x0000 }, { 3724, 0x0000 }, { 3724, 0x0000 }, { 3724, 0x0000 }, + /* 0x7f00 */ + { 3724, 0x0000 }, { 3724, 0x0000 }, { 3724, 0x0000 }, { 3724, 0xf800 }, + { 3729, 0x8098 }, { 3733, 0x380c }, { 3738, 0x207a }, { 3744, 0xe002 }, + { 3748, 0xa801 }, { 3752, 0x10c3 }, { 3757, 0x2446 }, { 3762, 0x9010 }, + { 3765, 0xc109 }, { 3770, 0x8800 }, { 3772, 0xd128 }, { 3778, 0xe404 }, + /* 0x8000 */ + { 3783, 0xe580 }, { 3789, 0xe05a }, { 3796, 0x5051 }, { 3801, 0x56b1 }, + { 3809, 0x0011 }, { 3811, 0x0000 }, { 3811, 0x2051 }, { 3815, 0x0022 }, + { 3817, 0x4102 }, { 3820, 0x5000 }, { 3822, 0x08c0 }, { 3825, 0x0300 }, + { 3827, 0xa100 }, { 3830, 0x01b4 }, { 3835, 0x6001 }, { 3838, 0x464d }, + /* 0x8100 */ + { 3845, 0x0808 }, { 3847, 0x51c0 }, { 3852, 0x1091 }, { 3856, 0x1421 }, + { 3860, 0x14a0 }, { 3864, 0x0084 }, { 3866, 0xa383 }, { 3873, 0x0080 }, + { 3874, 0x4872 }, { 3880, 0x4941 }, { 3885, 0x4004 }, { 3887, 0x0814 }, + { 3890, 0xcc28 }, { 3896, 0x68a0 }, { 3901, 0x1812 }, { 3905, 0xa367 }, + /* 0x8200 */ + { 3914, 0x8009 }, { 3917, 0x2618 }, { 3922, 0x0106 }, { 3925, 0x0414 }, + { 3928, 0xc878 }, { 3935, 0x1042 }, { 3938, 0x2089 }, { 3942, 0xa810 }, + { 3946, 0x469b }, { 3954, 0x0d52 }, { 3960, 0x479b }, { 3969, 0xd495 }, + { 3977, 0x0040 }, { 3978, 0x0421 }, { 3981, 0xa515 }, { 3988, 0x60c0 }, + /* 0x8300 */ + { 3992, 0x0d83 }, { 3998, 0xe800 }, { 4002, 0x7006 }, { 4007, 0x3489 }, + { 4013, 0x609c }, { 4019, 0x00fa }, { 4025, 0x0000 }, { 4025, 0xa101 }, + { 4029, 0x2055 }, { 4034, 0x3b34 }, { 4042, 0x32c0 }, { 4047, 0xc000 }, + { 4049, 0x8281 }, { 4053, 0x2013 }, { 4057, 0x0500 }, { 4059, 0x1340 }, + /* 0x8400 */ + { 4063, 0x8442 }, { 4067, 0x0222 }, { 4070, 0x8000 }, { 4071, 0x0200 }, + { 4072, 0xa5a0 }, { 4078, 0x1746 }, { 4085, 0x04b1 }, { 4090, 0x3159 }, + { 4097, 0x0022 }, { 4099, 0x402c }, { 4103, 0x8740 }, { 4108, 0x6412 }, + { 4113, 0x9185 }, { 4119, 0x1008 }, { 4121, 0x8480 }, { 4124, 0x2c87 }, + /* 0x8500 */ + { 4131, 0x508c }, { 4136, 0x5001 }, { 4139, 0x8cbc }, { 4147, 0x805c }, + { 4152, 0x8040 }, { 4154, 0xf24f }, { 4164, 0x8817 }, { 4170, 0xae00 }, + { 4175, 0x9a62 }, { 4182, 0xa108 }, { 4186, 0x20a5 }, { 4191, 0xf1d0 }, + { 4199, 0x4c84 }, { 4204, 0x8500 }, { 4207, 0x2141 }, { 4211, 0x9048 }, + /* 0x8600 */ + { 4215, 0x6031 }, { 4220, 0x4b07 }, { 4227, 0x0282 }, { 4230, 0x3540 }, + { 4235, 0x0047 }, { 4239, 0x23cc }, { 4246, 0x921f }, { 4254, 0x04e0 }, + { 4258, 0x2100 }, { 4260, 0x1542 }, { 4265, 0x21c2 }, { 4270, 0x83ba }, + { 4278, 0x002b }, { 4282, 0x14a6 }, { 4288, 0x00a9 }, { 4292, 0x3400 }, + /* 0x8700 */ + { 4295, 0xc8b0 }, { 4301, 0xc219 }, { 4307, 0xc10a }, { 4312, 0x7606 }, + { 4319, 0x2029 }, { 4323, 0x2100 }, { 4325, 0x8032 }, { 4329, 0x0806 }, + { 4332, 0x1bf8 }, { 4341, 0x43a9 }, { 4348, 0x7089 }, { 4354, 0xc022 }, + { 4358, 0x4702 }, { 4363, 0x9660 }, { 4369, 0x2c1c }, { 4375, 0x850a }, + /* 0x8800 */ + { 4380, 0x0e4a }, { 4386, 0xdf1d }, { 4397, 0x6100 }, { 4400, 0x1425 }, + { 4405, 0x4f2a }, { 4413, 0x9562 }, { 4420, 0x0211 }, { 4423, 0x0a02 }, + { 4426, 0x0001 }, { 4427, 0x9d00 }, { 4432, 0x0501 }, { 4435, 0x6400 }, + { 4438, 0x7c01 }, { 4444, 0x480e }, { 4449, 0x8080 }, { 4451, 0x00a3 }, + /* 0x8900 */ + { 4455, 0xe042 }, { 4460, 0x1760 }, { 4466, 0x01c1 }, { 4470, 0x4627 }, + { 4477, 0x8265 }, { 4483, 0x1c84 }, { 4488, 0x480e }, { 4493, 0x3c29 }, + { 4500, 0x2200 }, { 4502, 0x9831 }, { 4508, 0x0021 }, { 4510, 0x10f1 }, + { 4516, 0x0000 }, { 4516, 0x01f0 }, { 4521, 0x2a20 }, { 4525, 0xa24a }, + /* 0x8a00 */ + { 4531, 0x80b0 }, { 4535, 0x4036 }, { 4540, 0x9855 }, { 4547, 0x60a0 }, + { 4551, 0x62a9 }, { 4558, 0x31c8 }, { 4564, 0x00a2 }, { 4567, 0xcee0 }, + { 4575, 0x8849 }, { 4580, 0x82c5 }, { 4586, 0xc280 }, { 4590, 0x48c8 }, + { 4595, 0x0748 }, { 4600, 0xa0ba }, { 4607, 0x1000 }, { 4608, 0x9071 }, + /* 0x8b00 */ + { 4614, 0x0c60 }, { 4618, 0xd002 }, { 4622, 0x2000 }, { 4623, 0x1081 }, + { 4626, 0x217c }, { 4633, 0x421c }, { 4638, 0x2008 }, { 4640, 0x5340 }, + { 4645, 0xa832 }, { 4651, 0xd030 }, { 4656, 0x0000 }, { 4656, 0x0000 }, + { 4656, 0x0000 }, { 4656, 0x0000 }, { 4656, 0x0000 }, { 4656, 0x0000 }, + /* 0x8c00 */ + { 4656, 0x0000 }, { 4656, 0x0000 }, { 4656, 0x0000 }, { 4656, 0x6300 }, + { 4660, 0x8aa0 }, { 4665, 0x2b9a }, { 4673, 0x2358 }, { 4679, 0x4868 }, + { 4684, 0x08c0 }, { 4687, 0x1a0d }, { 4693, 0x0010 }, { 4694, 0x0600 }, + { 4696, 0x8a60 }, { 4701, 0x2260 }, { 4705, 0x9102 }, { 4709, 0xc1a5 }, + /* 0x8d00 */ + { 4716, 0x020a }, { 4719, 0x0884 }, { 4722, 0x0000 }, { 4722, 0x0000 }, + { 4722, 0x0000 }, { 4722, 0x0000 }, { 4722, 0x5220 }, { 4726, 0x8000 }, + { 4727, 0x2114 }, { 4731, 0xc023 }, { 4736, 0x9841 }, { 4741, 0x1aa4 }, + { 4747, 0x45e1 }, { 4754, 0x02b2 }, { 4759, 0x10b0 }, { 4763, 0x2017 }, + /* 0x8e00 */ + { 4768, 0x0872 }, { 4773, 0x0052 }, { 4776, 0x00cf }, { 4782, 0x23ca }, + { 4789, 0xe803 }, { 4795, 0x7810 }, { 4800, 0xb206 }, { 4806, 0x0e03 }, + { 4811, 0x020c }, { 4814, 0x6c25 }, { 4821, 0x6284 }, { 4826, 0x0c28 }, + { 4830, 0x809b }, { 4836, 0x1012 }, { 4839, 0x6100 }, { 4842, 0x0683 }, + /* 0x8f00 */ + { 4847, 0x8185 }, { 4852, 0x41c1 }, { 4857, 0x71ab }, { 4866, 0x04f0 }, + { 4871, 0x808b }, { 4876, 0x613e }, { 4884, 0x0020 }, { 4885, 0x0000 }, + { 4885, 0x0000 }, { 4885, 0x2000 }, { 4886, 0x0073 }, { 4891, 0x4160 }, + { 4895, 0x2c43 }, { 4901, 0x002d }, { 4905, 0x4119 }, { 4910, 0x4862 }, + /* 0x9000 */ + { 4915, 0x1114 }, { 4919, 0x0900 }, { 4921, 0xb700 }, { 4927, 0x8098 }, + { 4931, 0x1018 }, { 4934, 0x2800 }, { 4936, 0x10c4 }, { 4940, 0x0211 }, + { 4943, 0x5920 }, { 4948, 0x0ba1 }, { 4954, 0x0027 }, { 4958, 0x605d }, + { 4965, 0x11b8 }, { 4971, 0xb3a4 }, { 4979, 0x8820 }, { 4982, 0xc051 }, + /* 0x9100 */ + { 4987, 0x2171 }, { 4993, 0x55d1 }, { 5001, 0xc2ad }, { 5009, 0x36d2 }, + { 5017, 0x8188 }, { 5021, 0x0e88 }, { 5026, 0x2092 }, { 5030, 0x0e10 }, + { 5034, 0x446a }, { 5040, 0x413a }, { 5046, 0x7142 }, { 5052, 0xb84f }, + { 5061, 0x002c }, { 5064, 0x4698 }, { 5070, 0xf630 }, { 5078, 0x2a83 }, + /* 0x9200 */ + { 5084, 0x16f3 }, { 5093, 0x314d }, { 5100, 0xc178 }, { 5107, 0x5769 }, + { 5116, 0xe4cd }, { 5125, 0x3302 }, { 5130, 0xc3a3 }, { 5138, 0xbbe1 }, + { 5148, 0x6700 }, { 5153, 0x8284 }, { 5157, 0x89b1 }, { 5164, 0xbd44 }, + { 5172, 0x79ef }, { 5184, 0xb3a9 }, { 5193, 0x51ab }, { 5201, 0x8a01 }, + /* 0x9300 */ + { 5205, 0x2105 }, { 5209, 0xf032 }, { 5216, 0x06b2 }, { 5222, 0x00d8 }, + { 5226, 0x0380 }, { 5229, 0x45a7 }, { 5237, 0xa6b0 }, { 5244, 0xa45b }, + { 5252, 0xad07 }, { 5260, 0x4924 }, { 5265, 0x0b5a }, { 5272, 0x0470 }, + { 5276, 0x3ef2 }, { 5286, 0xd208 }, { 5291, 0x00c4 }, { 5294, 0x2f80 }, + /* 0x9400 */ + { 5300, 0xe316 }, { 5308, 0x80e0 }, { 5312, 0xc000 }, { 5314, 0xa81e }, + { 5321, 0x1528 }, { 5326, 0x9220 }, { 5330, 0xe90a }, { 5337, 0x0006 }, + { 5339, 0x0018 }, { 5341, 0x0000 }, { 5341, 0x0000 }, { 5341, 0x0000 }, + { 5341, 0x0000 }, { 5341, 0x0000 }, { 5341, 0x0000 }, { 5341, 0x0000 }, + /* 0x9500 */ + { 5341, 0x0000 }, { 5341, 0x0000 }, { 5341, 0x0000 }, { 5341, 0x0000 }, + { 5341, 0x0000 }, { 5341, 0x0000 }, { 5341, 0x0000 }, { 5341, 0x4300 }, + { 5344, 0x7110 }, { 5349, 0xe000 }, { 5352, 0x1a42 }, { 5357, 0xa450 }, + { 5362, 0x0b40 }, { 5366, 0xe60f }, { 5375, 0x0051 }, { 5378, 0x0000 }, + /* 0x9600 */ + { 5378, 0x0000 }, { 5378, 0x6000 }, { 5380, 0x1074 }, { 5385, 0x378a }, + { 5393, 0x0002 }, { 5394, 0x01d4 }, { 5399, 0x4002 }, { 5401, 0xd810 }, + { 5406, 0x021e }, { 5411, 0xa442 }, { 5416, 0xc270 }, { 5422, 0x0408 }, + { 5424, 0x0400 }, { 5425, 0xe504 }, { 5431, 0x8200 }, { 5433, 0x0402 }, + /* 0x9700 */ + { 5435, 0x022c }, { 5439, 0x2c00 }, { 5442, 0x010e }, { 5446, 0x000a }, + { 5448, 0xc40a }, { 5453, 0x0da0 }, { 5458, 0x4488 }, { 5462, 0xa9c8 }, + { 5469, 0x0201 }, { 5471, 0xc6e0 }, { 5478, 0x5004 }, { 5481, 0xd766 }, + { 5491, 0x76b2 }, { 5500, 0x6b93 }, { 5509, 0x8013 }, { 5513, 0x0592 }, + /* 0x9800 */ + { 5518, 0x6480 }, { 5522, 0x5250 }, { 5527, 0xc869 }, { 5534, 0x402d }, + { 5539, 0x0490 }, { 5542, 0x06ce }, { 5549, 0x146c }, { 5555, 0x0000 }, + { 5555, 0x0000 }, { 5555, 0x0000 }, { 5555, 0x6800 }, { 5558, 0x8d91 }, + { 5565, 0x1124 }, { 5569, 0x0000 }, { 5569, 0x04ea }, { 5575, 0x0048 }, + /* 0x9900 */ + { 5577, 0x0184 }, { 5580, 0x9ce2 }, { 5588, 0x08c4 }, { 5592, 0x1e3e }, + { 5601, 0x61c3 }, { 5608, 0xdb10 }, { 5615, 0x0001 }, { 5616, 0x0000 }, + { 5616, 0x0000 }, { 5616, 0xa800 }, { 5619, 0x0040 }, { 5620, 0xa627 }, + { 5628, 0x0208 }, { 5630, 0x5618 }, { 5636, 0x1c80 }, { 5640, 0x6231 }, + /* 0x9a00 */ + { 5646, 0x181c }, { 5651, 0x4043 }, { 5655, 0x609d }, { 5662, 0x0168 }, + { 5666, 0x5c92 }, { 5673, 0x2052 }, { 5677, 0x0000 }, { 5677, 0x0000 }, + { 5677, 0x0000 }, { 5677, 0x0000 }, { 5677, 0xd400 }, { 5681, 0xca74 }, + { 5689, 0x414a }, { 5694, 0x18e5 }, { 5701, 0x12b1 }, { 5707, 0xa62c }, + /* 0x9b00 */ + { 5714, 0x7b3f }, { 5726, 0x1a45 }, { 5732, 0x2841 }, { 5736, 0x26b8 }, + { 5743, 0x1900 }, { 5746, 0x48e0 }, { 5751, 0x7d6a }, { 5761, 0x83a8 }, + { 5767, 0xaef1 }, { 5777, 0x6411 }, { 5782, 0x12c0 }, { 5786, 0xd987 }, + { 5795, 0x4182 }, { 5799, 0xa181 }, { 5804, 0x8ca0 }, { 5809, 0xa788 }, + /* 0x9c00 */ + { 5816, 0x8805 }, { 5820, 0x5742 }, { 5827, 0x07cc }, { 5834, 0x20e2 }, + { 5839, 0xc63a }, { 5847, 0xf959 }, { 5857, 0x4f08 }, { 5863, 0x08a5 }, + { 5868, 0x0000 }, { 5868, 0x0000 }, { 5868, 0x0000 }, { 5868, 0x0000 }, + { 5868, 0x0000 }, { 5868, 0x0000 }, { 5868, 0x0040 }, { 5869, 0x0284 }, + /* 0x9d00 */ + { 5872, 0x0804 }, { 5874, 0x7182 }, { 5880, 0x8000 }, { 5881, 0x341d }, + { 5888, 0x04ac }, { 5893, 0x8018 }, { 5896, 0x0e2c }, { 5902, 0x58c1 }, + { 5908, 0x6458 }, { 5914, 0x01ec }, { 5920, 0x5402 }, { 5924, 0x9222 }, + { 5929, 0x0688 }, { 5933, 0xc4f0 }, { 5940, 0x4aa1 }, { 5946, 0x4019 }, + /* 0x9e00 */ + { 5950, 0x4484 }, { 5954, 0x3267 }, { 5962, 0x0000 }, { 5962, 0x0000 }, + { 5962, 0x0000 }, { 5962, 0x0000 }, { 5962, 0x0000 }, { 5962, 0x1c00 }, + { 5965, 0xc0bd }, { 5973, 0x4940 }, { 5977, 0xd110 }, { 5982, 0x0039 }, + { 5986, 0x0940 }, { 5989, 0x8020 }, { 5991, 0x7090 }, { 5996, 0x8127 }, + /* 0x9f00 */ + { 6002, 0x820c }, { 6006, 0x8ed7 }, { 6016, 0x8c44 }, { 6021, 0xb696 }, + { 6030, 0x00fa }, { 6036, 0x65e8 }, { 6044, 0xe300 }, { 6049, 0x242b }, + { 6055, 0x8000 }, { 6056, 0x40d7 }, { 6063, 0x002e }, +}; + +static int +jisx0212_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (n >= 2) { + const Summary16 *summary = NULL; + if (wc < 0x0460) + summary = &jisx0212_uni2indx_page00[(wc>>4)]; + else if (wc >= 0x2100 && wc < 0x2130) + summary = &jisx0212_uni2indx_page21[(wc>>4)-0x210]; + else if (wc >= 0x4e00 && wc < 0x9fb0) + summary = &jisx0212_uni2indx_page4e[(wc>>4)-0x4e0]; + if (summary) { + unsigned short used = summary->used; + unsigned int i = wc & 0x0f; + if (used & ((unsigned short) 1 << i)) { + unsigned short c; + /* Keep in `used' only the bits 0..i-1. */ + used &= ((unsigned short) 1 << i) - 1; + /* Add `summary->indx' and the number of bits set in `used'. */ + used = (used & 0x5555) + ((used & 0xaaaa) >> 1); + used = (used & 0x3333) + ((used & 0xcccc) >> 2); + used = (used & 0x0f0f) + ((used & 0xf0f0) >> 4); + used = (used & 0x00ff) + (used >> 8); + c = jisx0212_2charset[summary->indx + used]; + r[0] = (c >> 8); r[1] = (c & 0xff); + return 2; + } + } + return RET_ILSEQ; + } + return RET_TOOSMALL; +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/koi8_c.h b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/koi8_c.h new file mode 100644 index 0000000..e31c368 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/koi8_c.h @@ -0,0 +1,103 @@ +/* $XFree86: xc/lib/X11/lcUniConv/koi8_c.h,v 1.2 2000/11/28 16:10:29 dawes Exp $ */ + +/* + * KOI8-C + */ + +static const unsigned short koi8_c_2uni[128] = { + /* 0x80 */ + 0x0493, 0x0497, 0x049b, 0x049d, 0x04a3, 0x04af, 0x04b1, 0x04b3, + 0x04b7, 0x04b9, 0x04bb, 0x2580, 0x04d9, 0x04e3, 0x04e9, 0x04ef, + /* 0x90 */ + 0x0492, 0x0496, 0x049a, 0x049c, 0x04a2, 0x04ae, 0x04b0, 0x04b2, + 0x04b6, 0x04b8, 0x04ba, 0x2321, 0x04d8, 0x04e2, 0x04e8, 0x04ee, + /* 0xa0 */ + 0x00a0, 0x0452, 0x0453, 0x0451, 0x0454, 0x0455, 0x0456, 0x0457, + 0x0458, 0x0459, 0x045a, 0x045b, 0x045c, 0x0491, 0x045e, 0x045f, + /* 0xb0 */ + 0x2116, 0x0402, 0x0403, 0x0401, 0x0404, 0x0405, 0x0406, 0x0407, + 0x0486, 0x0409, 0x040a, 0x040b, 0x040c, 0x0490, 0x040e, 0x040f, + /* 0xc0 */ + 0x044e, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, + 0x0445, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, + /* 0xd0 */ + 0x043f, 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, + 0x044c, 0x044b, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x044a, + /* 0xe0 */ + 0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, + 0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, + /* 0xf0 */ + 0x041f, 0x042f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412, + 0x042c, 0x042b, 0x0417, 0x0428, 0x042d, 0x0429, 0x0427, 0x042a, +}; + +static int +koi8_c_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) + *pwc = (ucs4_t) c; + else + *pwc = (ucs4_t) koi8_c_2uni[c-0x80]; + return 1; +} + +static const unsigned char koi8_c_page00[1] = { + 0xa0, /* 0xa0-0xa7 */ +}; +static const unsigned char koi8_c_page04[240] = { + 0x00, 0xb3, 0xb1, 0xb2, 0xb4, 0xb5, 0xb6, 0xb7, /* 0x00-0x07 */ + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0x00, 0xbe, 0xbf, /* 0x08-0x0f */ + 0xe1, 0xe2, 0xf7, 0xe7, 0xe4, 0xe5, 0xf6, 0xfa, /* 0x10-0x17 */ + 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, /* 0x18-0x1f */ + 0xf2, 0xf3, 0xf4, 0xf5, 0xe6, 0xe8, 0xe3, 0xfe, /* 0x20-0x27 */ + 0xfb, 0xfd, 0xff, 0xf9, 0xf8, 0xfc, 0xe0, 0xf1, /* 0x28-0x2f */ + 0xc1, 0xc2, 0xd7, 0xc7, 0xc4, 0xc5, 0xd6, 0xda, /* 0x30-0x37 */ + 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, /* 0x38-0x3f */ + 0xd2, 0xd3, 0xd4, 0xd5, 0xc6, 0xc8, 0xc3, 0xde, /* 0x40-0x47 */ + 0xdb, 0xdd, 0xdf, 0xd9, 0xd8, 0xdc, 0xc0, 0xd1, /* 0x48-0x4f */ + 0x00, 0xa3, 0xa1, 0xa2, 0xa4, 0xa5, 0xa6, 0xa7, /* 0x50-0x57 */ + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0x00, 0xae, 0xaf, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0xbd, 0xad, 0x90, 0x80, 0x00, 0x00, 0x91, 0x81, /* 0x90-0x97 */ + 0x00, 0x00, 0x92, 0x82, 0x93, 0x83, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x94, 0x84, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x95, 0x85, /* 0xa8-0xaf */ + 0x96, 0x86, 0x97, 0x87, 0x00, 0x00, 0x98, 0x88, /* 0xb0-0xb7 */ + 0x99, 0x89, 0x9a, 0x8a, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x9c, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x9d, 0x8d, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x9e, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x8f, /* 0xe8-0xef */ +}; +static const unsigned char koi8_c_page22[1] = { + 0xb0, /* 0x16-0x16 */ +}; + +static int +koi8_c_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x00a1) + c = koi8_c_page00[wc-0x00a0]; + else if (wc >= 0x0400 && wc < 0x04ef) + c = koi8_c_page04[wc-0x0400]; + else if (wc >= 0x2216 && wc < 0x2217) + c = koi8_c_page22[wc-0x2216]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILSEQ; +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/koi8_r.h b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/koi8_r.h new file mode 100644 index 0000000..a0d3d9b --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/koi8_r.h @@ -0,0 +1,135 @@ +/* $XFree86: xc/lib/X11/lcUniConv/koi8_r.h,v 1.3 2000/11/29 17:40:34 dawes Exp $ */ + +/* + * KOI8-R + */ + +/* Specification: RFC 1489 */ + +static const unsigned short koi8_r_2uni[128] = { + /* 0x80 */ + 0x2500, 0x2502, 0x250c, 0x2510, 0x2514, 0x2518, 0x251c, 0x2524, + 0x252c, 0x2534, 0x253c, 0x2580, 0x2584, 0x2588, 0x258c, 0x2590, + /* 0x90 */ + 0x2591, 0x2592, 0x2593, 0x2320, 0x25a0, 0x2219, 0x221a, 0x2248, + 0x2264, 0x2265, 0x00a0, 0x2321, 0x00b0, 0x00b2, 0x00b7, 0x00f7, + /* 0xa0 */ + 0x2550, 0x2551, 0x2552, 0x0451, 0x2553, 0x2554, 0x2555, 0x2556, + 0x2557, 0x2558, 0x2559, 0x255a, 0x255b, 0x255c, 0x255d, 0x255e, + /* 0xb0 */ + 0x255f, 0x2560, 0x2561, 0x0401, 0x2562, 0x2563, 0x2564, 0x2565, + 0x2566, 0x2567, 0x2568, 0x2569, 0x256a, 0x256b, 0x256c, 0x00a9, + /* 0xc0 */ + 0x044e, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, + 0x0445, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, + /* 0xd0 */ + 0x043f, 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, + 0x044c, 0x044b, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x044a, + /* 0xe0 */ + 0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, + 0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, + /* 0xf0 */ + 0x041f, 0x042f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412, + 0x042c, 0x042b, 0x0417, 0x0428, 0x042d, 0x0429, 0x0427, 0x042a, +}; + +static int +koi8_r_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) + *pwc = (ucs4_t) c; + else + *pwc = (ucs4_t) koi8_r_2uni[c-0x80]; + return 1; +} + +static const unsigned char koi8_r_page00[88] = { + 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x9c, 0x00, 0x9d, 0x00, 0x00, 0x00, 0x00, 0x9e, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, /* 0xf0-0xf7 */ +}; +static const unsigned char koi8_r_page04[88] = { + 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0xe1, 0xe2, 0xf7, 0xe7, 0xe4, 0xe5, 0xf6, 0xfa, /* 0x10-0x17 */ + 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, /* 0x18-0x1f */ + 0xf2, 0xf3, 0xf4, 0xf5, 0xe6, 0xe8, 0xe3, 0xfe, /* 0x20-0x27 */ + 0xfb, 0xfd, 0xff, 0xf9, 0xf8, 0xfc, 0xe0, 0xf1, /* 0x28-0x2f */ + 0xc1, 0xc2, 0xd7, 0xc7, 0xc4, 0xc5, 0xd6, 0xda, /* 0x30-0x37 */ + 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, /* 0x38-0x3f */ + 0xd2, 0xd3, 0xd4, 0xd5, 0xc6, 0xc8, 0xc3, 0xde, /* 0x40-0x47 */ + 0xdb, 0xdd, 0xdf, 0xd9, 0xd8, 0xdc, 0xc0, 0xd1, /* 0x48-0x4f */ + 0x00, 0xa3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ +}; +static const unsigned char koi8_r_page22[80] = { + 0x00, 0x95, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x97, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x98, 0x99, 0x00, 0x00, /* 0x60-0x67 */ +}; +static const unsigned char koi8_r_page23[8] = { + 0x93, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ +}; +static const unsigned char koi8_r_page25[168] = { + 0x80, 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x83, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x85, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0xa0, 0xa1, 0xa2, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, /* 0x50-0x57 */ + 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, /* 0x58-0x5f */ + 0xb1, 0xb2, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, /* 0x60-0x67 */ + 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0x8b, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x8d, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x8f, 0x90, 0x91, 0x92, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ +}; + +static int +koi8_r_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x00f8) + c = koi8_r_page00[wc-0x00a0]; + else if (wc >= 0x0400 && wc < 0x0458) + c = koi8_r_page04[wc-0x0400]; + else if (wc >= 0x2218 && wc < 0x2268) + c = koi8_r_page22[wc-0x2218]; + else if (wc >= 0x2320 && wc < 0x2328) + c = koi8_r_page23[wc-0x2320]; + else if (wc >= 0x2500 && wc < 0x25a8) + c = koi8_r_page25[wc-0x2500]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILSEQ; +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/koi8_u.h b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/koi8_u.h new file mode 100644 index 0000000..43457af --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/koi8_u.h @@ -0,0 +1,143 @@ +/* $XFree86: xc/lib/X11/lcUniConv/koi8_u.h,v 1.3 2000/11/29 17:40:34 dawes Exp $ */ + +/* + * KOI8-U + */ + +/* Specification: RFC 2319 */ + +static const unsigned short koi8_u_2uni[128] = { + /* 0x80 */ + 0x2500, 0x2502, 0x250c, 0x2510, 0x2514, 0x2518, 0x251c, 0x2524, + 0x252c, 0x2534, 0x253c, 0x2580, 0x2584, 0x2588, 0x258c, 0x2590, + /* 0x90 */ + 0x2591, 0x2592, 0x2593, 0x2320, 0x25a0, 0x2219, 0x221a, 0x2248, + 0x2264, 0x2265, 0x00a0, 0x2321, 0x00b0, 0x00b2, 0x00b7, 0x00f7, + /* 0xa0 */ + 0x2550, 0x2551, 0x2552, 0x0451, 0x0454, 0x2554, 0x0456, 0x0457, + 0x2557, 0x2558, 0x2559, 0x255a, 0x255b, 0x0491, 0x255d, 0x255e, + /* 0xb0 */ + 0x255f, 0x2560, 0x2561, 0x0401, 0x0404, 0x2563, 0x0406, 0x0407, + 0x2566, 0x2567, 0x2568, 0x2569, 0x256a, 0x0490, 0x256c, 0x00a9, + /* 0xc0 */ + 0x044e, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, + 0x0445, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, + /* 0xd0 */ + 0x043f, 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, + 0x044c, 0x044b, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x044a, + /* 0xe0 */ + 0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, + 0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, + /* 0xf0 */ + 0x041f, 0x042f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412, + 0x042c, 0x042b, 0x0417, 0x0428, 0x042d, 0x0429, 0x0427, 0x042a, +}; + +static int +koi8_u_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) + *pwc = (ucs4_t) c; + else + *pwc = (ucs4_t) koi8_u_2uni[c-0x80]; + return 1; +} + +static const unsigned char koi8_u_page00[88] = { + 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x9c, 0x00, 0x9d, 0x00, 0x00, 0x00, 0x00, 0x9e, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, /* 0xf0-0xf7 */ +}; +static const unsigned char koi8_u_page04[152] = { + 0x00, 0xb3, 0x00, 0x00, 0xb4, 0x00, 0xb6, 0xb7, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0xe1, 0xe2, 0xf7, 0xe7, 0xe4, 0xe5, 0xf6, 0xfa, /* 0x10-0x17 */ + 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, /* 0x18-0x1f */ + 0xf2, 0xf3, 0xf4, 0xf5, 0xe6, 0xe8, 0xe3, 0xfe, /* 0x20-0x27 */ + 0xfb, 0xfd, 0xff, 0xf9, 0xf8, 0xfc, 0xe0, 0xf1, /* 0x28-0x2f */ + 0xc1, 0xc2, 0xd7, 0xc7, 0xc4, 0xc5, 0xd6, 0xda, /* 0x30-0x37 */ + 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, /* 0x38-0x3f */ + 0xd2, 0xd3, 0xd4, 0xd5, 0xc6, 0xc8, 0xc3, 0xde, /* 0x40-0x47 */ + 0xdb, 0xdd, 0xdf, 0xd9, 0xd8, 0xdc, 0xc0, 0xd1, /* 0x48-0x4f */ + 0x00, 0xa3, 0x00, 0x00, 0xa4, 0x00, 0xa6, 0xa7, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0xbd, 0xad, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ +}; +static const unsigned char koi8_u_page22[80] = { + 0x00, 0x95, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x97, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x98, 0x99, 0x00, 0x00, /* 0x60-0x67 */ +}; +static const unsigned char koi8_u_page23[8] = { + 0x93, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ +}; +static const unsigned char koi8_u_page25[168] = { + 0x80, 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x83, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x85, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0xa0, 0xa1, 0xa2, 0x00, 0xa5, 0x00, 0x00, 0xa8, /* 0x50-0x57 */ + 0xa9, 0xaa, 0xab, 0xac, 0x00, 0xae, 0xaf, 0xb0, /* 0x58-0x5f */ + 0xb1, 0xb2, 0x00, 0xb5, 0x00, 0x00, 0xb8, 0xb9, /* 0x60-0x67 */ + 0xba, 0xbb, 0xbc, 0x00, 0xbe, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0x8b, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x8d, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x8f, 0x90, 0x91, 0x92, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ +}; + +static int +koi8_u_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x00f8) + c = koi8_u_page00[wc-0x00a0]; + else if (wc >= 0x0400 && wc < 0x0498) + c = koi8_u_page04[wc-0x0400]; + else if (wc >= 0x2218 && wc < 0x2268) + c = koi8_u_page22[wc-0x2218]; + else if (wc >= 0x2320 && wc < 0x2328) + c = koi8_u_page23[wc-0x2320]; + else if (wc >= 0x2500 && wc < 0x25a8) + c = koi8_u_page25[wc-0x2500]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILSEQ; +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/ksc5601.h b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/ksc5601.h new file mode 100644 index 0000000..62ac66d --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/ksc5601.h @@ -0,0 +1,3003 @@ +/* $XFree86: xc/lib/X11/lcUniConv/ksc5601.h,v 1.5 2003/05/27 22:26:34 tsi Exp $ */ + +/* + * KSC5601.1987-0 + */ + +static const unsigned short ksc5601_2uni_page21[1115] = { + /* 0x21 */ + 0x3000, 0x3001, 0x3002, 0x00b7, 0x2025, 0x2026, 0x00a8, 0x3003, + 0x00ad, 0x2015, 0x2225, 0xff3c, 0x223c, 0x2018, 0x2019, 0x201c, + 0x201d, 0x3014, 0x3015, 0x3008, 0x3009, 0x300a, 0x300b, 0x300c, + 0x300d, 0x300e, 0x300f, 0x3010, 0x3011, 0x00b1, 0x00d7, 0x00f7, + 0x2260, 0x2264, 0x2265, 0x221e, 0x2234, 0x00b0, 0x2032, 0x2033, + 0x2103, 0x212b, 0xffe0, 0xffe1, 0xffe5, 0x2642, 0x2640, 0x2220, + 0x22a5, 0x2312, 0x2202, 0x2207, 0x2261, 0x2252, 0x00a7, 0x203b, + 0x2606, 0x2605, 0x25cb, 0x25cf, 0x25ce, 0x25c7, 0x25c6, 0x25a1, + 0x25a0, 0x25b3, 0x25b2, 0x25bd, 0x25bc, 0x2192, 0x2190, 0x2191, + 0x2193, 0x2194, 0x3013, 0x226a, 0x226b, 0x221a, 0x223d, 0x221d, + 0x2235, 0x222b, 0x222c, 0x2208, 0x220b, 0x2286, 0x2287, 0x2282, + 0x2283, 0x222a, 0x2229, 0x2227, 0x2228, 0xffe2, + /* 0x22 */ + 0x21d2, 0x21d4, 0x2200, 0x2203, 0x00b4, 0xff5e, 0x02c7, 0x02d8, + 0x02dd, 0x02da, 0x02d9, 0x00b8, 0x02db, 0x00a1, 0x00bf, 0x02d0, + 0x222e, 0x2211, 0x220f, 0x00a4, 0x2109, 0x2030, 0x25c1, 0x25c0, + 0x25b7, 0x25b6, 0x2664, 0x2660, 0x2661, 0x2665, 0x2667, 0x2663, + 0x2299, 0x25c8, 0x25a3, 0x25d0, 0x25d1, 0x2592, 0x25a4, 0x25a5, + 0x25a8, 0x25a7, 0x25a6, 0x25a9, 0x2668, 0x260f, 0x260e, 0x261c, + 0x261e, 0x00b6, 0x2020, 0x2021, 0x2195, 0x2197, 0x2199, 0x2196, + 0x2198, 0x266d, 0x2669, 0x266a, 0x266c, 0x327f, 0x321c, 0x2116, + 0x33c7, 0x2122, 0x33c2, 0x33d8, 0x2121, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x23 */ + 0xff01, 0xff02, 0xff03, 0xff04, 0xff05, 0xff06, 0xff07, 0xff08, + 0xff09, 0xff0a, 0xff0b, 0xff0c, 0xff0d, 0xff0e, 0xff0f, 0xff10, + 0xff11, 0xff12, 0xff13, 0xff14, 0xff15, 0xff16, 0xff17, 0xff18, + 0xff19, 0xff1a, 0xff1b, 0xff1c, 0xff1d, 0xff1e, 0xff1f, 0xff20, + 0xff21, 0xff22, 0xff23, 0xff24, 0xff25, 0xff26, 0xff27, 0xff28, + 0xff29, 0xff2a, 0xff2b, 0xff2c, 0xff2d, 0xff2e, 0xff2f, 0xff30, + 0xff31, 0xff32, 0xff33, 0xff34, 0xff35, 0xff36, 0xff37, 0xff38, + 0xff39, 0xff3a, 0xff3b, 0xffe6, 0xff3d, 0xff3e, 0xff3f, 0xff40, + 0xff41, 0xff42, 0xff43, 0xff44, 0xff45, 0xff46, 0xff47, 0xff48, + 0xff49, 0xff4a, 0xff4b, 0xff4c, 0xff4d, 0xff4e, 0xff4f, 0xff50, + 0xff51, 0xff52, 0xff53, 0xff54, 0xff55, 0xff56, 0xff57, 0xff58, + 0xff59, 0xff5a, 0xff5b, 0xff5c, 0xff5d, 0xffe3, + /* 0x24 */ + 0x3131, 0x3132, 0x3133, 0x3134, 0x3135, 0x3136, 0x3137, 0x3138, + 0x3139, 0x313a, 0x313b, 0x313c, 0x313d, 0x313e, 0x313f, 0x3140, + 0x3141, 0x3142, 0x3143, 0x3144, 0x3145, 0x3146, 0x3147, 0x3148, + 0x3149, 0x314a, 0x314b, 0x314c, 0x314d, 0x314e, 0x314f, 0x3150, + 0x3151, 0x3152, 0x3153, 0x3154, 0x3155, 0x3156, 0x3157, 0x3158, + 0x3159, 0x315a, 0x315b, 0x315c, 0x315d, 0x315e, 0x315f, 0x3160, + 0x3161, 0x3162, 0x3163, 0x3164, 0x3165, 0x3166, 0x3167, 0x3168, + 0x3169, 0x316a, 0x316b, 0x316c, 0x316d, 0x316e, 0x316f, 0x3170, + 0x3171, 0x3172, 0x3173, 0x3174, 0x3175, 0x3176, 0x3177, 0x3178, + 0x3179, 0x317a, 0x317b, 0x317c, 0x317d, 0x317e, 0x317f, 0x3180, + 0x3181, 0x3182, 0x3183, 0x3184, 0x3185, 0x3186, 0x3187, 0x3188, + 0x3189, 0x318a, 0x318b, 0x318c, 0x318d, 0x318e, + /* 0x25 */ + 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, + 0x2178, 0x2179, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x2160, + 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, 0x2168, + 0x2169, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, + 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, 0x03a0, + 0x03a1, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7, 0x03a8, 0x03a9, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, 0x03b8, + 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, 0x03c0, + 0x03c1, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, 0x03c8, 0x03c9, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x26 */ + 0x2500, 0x2502, 0x250c, 0x2510, 0x2518, 0x2514, 0x251c, 0x252c, + 0x2524, 0x2534, 0x253c, 0x2501, 0x2503, 0x250f, 0x2513, 0x251b, + 0x2517, 0x2523, 0x2533, 0x252b, 0x253b, 0x254b, 0x2520, 0x252f, + 0x2528, 0x2537, 0x253f, 0x251d, 0x2530, 0x2525, 0x2538, 0x2542, + 0x2512, 0x2511, 0x251a, 0x2519, 0x2516, 0x2515, 0x250e, 0x250d, + 0x251e, 0x251f, 0x2521, 0x2522, 0x2526, 0x2527, 0x2529, 0x252a, + 0x252d, 0x252e, 0x2531, 0x2532, 0x2535, 0x2536, 0x2539, 0x253a, + 0x253d, 0x253e, 0x2540, 0x2541, 0x2543, 0x2544, 0x2545, 0x2546, + 0x2547, 0x2548, 0x2549, 0x254a, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x27 */ + 0x3395, 0x3396, 0x3397, 0x2113, 0x3398, 0x33c4, 0x33a3, 0x33a4, + 0x33a5, 0x33a6, 0x3399, 0x339a, 0x339b, 0x339c, 0x339d, 0x339e, + 0x339f, 0x33a0, 0x33a1, 0x33a2, 0x33ca, 0x338d, 0x338e, 0x338f, + 0x33cf, 0x3388, 0x3389, 0x33c8, 0x33a7, 0x33a8, 0x33b0, 0x33b1, + 0x33b2, 0x33b3, 0x33b4, 0x33b5, 0x33b6, 0x33b7, 0x33b8, 0x33b9, + 0x3380, 0x3381, 0x3382, 0x3383, 0x3384, 0x33ba, 0x33bb, 0x33bc, + 0x33bd, 0x33be, 0x33bf, 0x3390, 0x3391, 0x3392, 0x3393, 0x3394, + 0x2126, 0x33c0, 0x33c1, 0x338a, 0x338b, 0x338c, 0x33d6, 0x33c5, + 0x33ad, 0x33ae, 0x33af, 0x33db, 0x33a9, 0x33aa, 0x33ab, 0x33ac, + 0x33dd, 0x33d0, 0x33d3, 0x33c3, 0x33c9, 0x33dc, 0x33c6, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x28 */ + 0x00c6, 0x00d0, 0x00aa, 0x0126, 0xfffd, 0x0132, 0xfffd, 0x013f, + 0x0141, 0x00d8, 0x0152, 0x00ba, 0x00de, 0x0166, 0x014a, 0xfffd, + 0x3260, 0x3261, 0x3262, 0x3263, 0x3264, 0x3265, 0x3266, 0x3267, + 0x3268, 0x3269, 0x326a, 0x326b, 0x326c, 0x326d, 0x326e, 0x326f, + 0x3270, 0x3271, 0x3272, 0x3273, 0x3274, 0x3275, 0x3276, 0x3277, + 0x3278, 0x3279, 0x327a, 0x327b, 0x24d0, 0x24d1, 0x24d2, 0x24d3, + 0x24d4, 0x24d5, 0x24d6, 0x24d7, 0x24d8, 0x24d9, 0x24da, 0x24db, + 0x24dc, 0x24dd, 0x24de, 0x24df, 0x24e0, 0x24e1, 0x24e2, 0x24e3, + 0x24e4, 0x24e5, 0x24e6, 0x24e7, 0x24e8, 0x24e9, 0x2460, 0x2461, + 0x2462, 0x2463, 0x2464, 0x2465, 0x2466, 0x2467, 0x2468, 0x2469, + 0x246a, 0x246b, 0x246c, 0x246d, 0x246e, 0x00bd, 0x2153, 0x2154, + 0x00bc, 0x00be, 0x215b, 0x215c, 0x215d, 0x215e, + /* 0x29 */ + 0x00e6, 0x0111, 0x00f0, 0x0127, 0x0131, 0x0133, 0x0138, 0x0140, + 0x0142, 0x00f8, 0x0153, 0x00df, 0x00fe, 0x0167, 0x014b, 0x0149, + 0x3200, 0x3201, 0x3202, 0x3203, 0x3204, 0x3205, 0x3206, 0x3207, + 0x3208, 0x3209, 0x320a, 0x320b, 0x320c, 0x320d, 0x320e, 0x320f, + 0x3210, 0x3211, 0x3212, 0x3213, 0x3214, 0x3215, 0x3216, 0x3217, + 0x3218, 0x3219, 0x321a, 0x321b, 0x249c, 0x249d, 0x249e, 0x249f, + 0x24a0, 0x24a1, 0x24a2, 0x24a3, 0x24a4, 0x24a5, 0x24a6, 0x24a7, + 0x24a8, 0x24a9, 0x24aa, 0x24ab, 0x24ac, 0x24ad, 0x24ae, 0x24af, + 0x24b0, 0x24b1, 0x24b2, 0x24b3, 0x24b4, 0x24b5, 0x2474, 0x2475, + 0x2476, 0x2477, 0x2478, 0x2479, 0x247a, 0x247b, 0x247c, 0x247d, + 0x247e, 0x247f, 0x2480, 0x2481, 0x2482, 0x00b9, 0x00b2, 0x00b3, + 0x2074, 0x207f, 0x2081, 0x2082, 0x2083, 0x2084, + /* 0x2a */ + 0x3041, 0x3042, 0x3043, 0x3044, 0x3045, 0x3046, 0x3047, 0x3048, + 0x3049, 0x304a, 0x304b, 0x304c, 0x304d, 0x304e, 0x304f, 0x3050, + 0x3051, 0x3052, 0x3053, 0x3054, 0x3055, 0x3056, 0x3057, 0x3058, + 0x3059, 0x305a, 0x305b, 0x305c, 0x305d, 0x305e, 0x305f, 0x3060, + 0x3061, 0x3062, 0x3063, 0x3064, 0x3065, 0x3066, 0x3067, 0x3068, + 0x3069, 0x306a, 0x306b, 0x306c, 0x306d, 0x306e, 0x306f, 0x3070, + 0x3071, 0x3072, 0x3073, 0x3074, 0x3075, 0x3076, 0x3077, 0x3078, + 0x3079, 0x307a, 0x307b, 0x307c, 0x307d, 0x307e, 0x307f, 0x3080, + 0x3081, 0x3082, 0x3083, 0x3084, 0x3085, 0x3086, 0x3087, 0x3088, + 0x3089, 0x308a, 0x308b, 0x308c, 0x308d, 0x308e, 0x308f, 0x3090, + 0x3091, 0x3092, 0x3093, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x2b */ + 0x30a1, 0x30a2, 0x30a3, 0x30a4, 0x30a5, 0x30a6, 0x30a7, 0x30a8, + 0x30a9, 0x30aa, 0x30ab, 0x30ac, 0x30ad, 0x30ae, 0x30af, 0x30b0, + 0x30b1, 0x30b2, 0x30b3, 0x30b4, 0x30b5, 0x30b6, 0x30b7, 0x30b8, + 0x30b9, 0x30ba, 0x30bb, 0x30bc, 0x30bd, 0x30be, 0x30bf, 0x30c0, + 0x30c1, 0x30c2, 0x30c3, 0x30c4, 0x30c5, 0x30c6, 0x30c7, 0x30c8, + 0x30c9, 0x30ca, 0x30cb, 0x30cc, 0x30cd, 0x30ce, 0x30cf, 0x30d0, + 0x30d1, 0x30d2, 0x30d3, 0x30d4, 0x30d5, 0x30d6, 0x30d7, 0x30d8, + 0x30d9, 0x30da, 0x30db, 0x30dc, 0x30dd, 0x30de, 0x30df, 0x30e0, + 0x30e1, 0x30e2, 0x30e3, 0x30e4, 0x30e5, 0x30e6, 0x30e7, 0x30e8, + 0x30e9, 0x30ea, 0x30eb, 0x30ec, 0x30ed, 0x30ee, 0x30ef, 0x30f0, + 0x30f1, 0x30f2, 0x30f3, 0x30f4, 0x30f5, 0x30f6, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x2c */ + 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0401, 0x0416, + 0x0417, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, + 0x041f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, + 0x0427, 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, + 0x042f, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0451, 0x0436, + 0x0437, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, + 0x043f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, + 0x0447, 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, + 0x044f, +}; +static const unsigned short ksc5601_2uni_page30[2350] = { + /* 0x30 */ + 0xac00, 0xac01, 0xac04, 0xac07, 0xac08, 0xac09, 0xac0a, 0xac10, + 0xac11, 0xac12, 0xac13, 0xac14, 0xac15, 0xac16, 0xac17, 0xac19, + 0xac1a, 0xac1b, 0xac1c, 0xac1d, 0xac20, 0xac24, 0xac2c, 0xac2d, + 0xac2f, 0xac30, 0xac31, 0xac38, 0xac39, 0xac3c, 0xac40, 0xac4b, + 0xac4d, 0xac54, 0xac58, 0xac5c, 0xac70, 0xac71, 0xac74, 0xac77, + 0xac78, 0xac7a, 0xac80, 0xac81, 0xac83, 0xac84, 0xac85, 0xac86, + 0xac89, 0xac8a, 0xac8b, 0xac8c, 0xac90, 0xac94, 0xac9c, 0xac9d, + 0xac9f, 0xaca0, 0xaca1, 0xaca8, 0xaca9, 0xacaa, 0xacac, 0xacaf, + 0xacb0, 0xacb8, 0xacb9, 0xacbb, 0xacbc, 0xacbd, 0xacc1, 0xacc4, + 0xacc8, 0xaccc, 0xacd5, 0xacd7, 0xace0, 0xace1, 0xace4, 0xace7, + 0xace8, 0xacea, 0xacec, 0xacef, 0xacf0, 0xacf1, 0xacf3, 0xacf5, + 0xacf6, 0xacfc, 0xacfd, 0xad00, 0xad04, 0xad06, + /* 0x31 */ + 0xad0c, 0xad0d, 0xad0f, 0xad11, 0xad18, 0xad1c, 0xad20, 0xad29, + 0xad2c, 0xad2d, 0xad34, 0xad35, 0xad38, 0xad3c, 0xad44, 0xad45, + 0xad47, 0xad49, 0xad50, 0xad54, 0xad58, 0xad61, 0xad63, 0xad6c, + 0xad6d, 0xad70, 0xad73, 0xad74, 0xad75, 0xad76, 0xad7b, 0xad7c, + 0xad7d, 0xad7f, 0xad81, 0xad82, 0xad88, 0xad89, 0xad8c, 0xad90, + 0xad9c, 0xad9d, 0xada4, 0xadb7, 0xadc0, 0xadc1, 0xadc4, 0xadc8, + 0xadd0, 0xadd1, 0xadd3, 0xaddc, 0xade0, 0xade4, 0xadf8, 0xadf9, + 0xadfc, 0xadff, 0xae00, 0xae01, 0xae08, 0xae09, 0xae0b, 0xae0d, + 0xae14, 0xae30, 0xae31, 0xae34, 0xae37, 0xae38, 0xae3a, 0xae40, + 0xae41, 0xae43, 0xae45, 0xae46, 0xae4a, 0xae4c, 0xae4d, 0xae4e, + 0xae50, 0xae54, 0xae56, 0xae5c, 0xae5d, 0xae5f, 0xae60, 0xae61, + 0xae65, 0xae68, 0xae69, 0xae6c, 0xae70, 0xae78, + /* 0x32 */ + 0xae79, 0xae7b, 0xae7c, 0xae7d, 0xae84, 0xae85, 0xae8c, 0xaebc, + 0xaebd, 0xaebe, 0xaec0, 0xaec4, 0xaecc, 0xaecd, 0xaecf, 0xaed0, + 0xaed1, 0xaed8, 0xaed9, 0xaedc, 0xaee8, 0xaeeb, 0xaeed, 0xaef4, + 0xaef8, 0xaefc, 0xaf07, 0xaf08, 0xaf0d, 0xaf10, 0xaf2c, 0xaf2d, + 0xaf30, 0xaf32, 0xaf34, 0xaf3c, 0xaf3d, 0xaf3f, 0xaf41, 0xaf42, + 0xaf43, 0xaf48, 0xaf49, 0xaf50, 0xaf5c, 0xaf5d, 0xaf64, 0xaf65, + 0xaf79, 0xaf80, 0xaf84, 0xaf88, 0xaf90, 0xaf91, 0xaf95, 0xaf9c, + 0xafb8, 0xafb9, 0xafbc, 0xafc0, 0xafc7, 0xafc8, 0xafc9, 0xafcb, + 0xafcd, 0xafce, 0xafd4, 0xafdc, 0xafe8, 0xafe9, 0xaff0, 0xaff1, + 0xaff4, 0xaff8, 0xb000, 0xb001, 0xb004, 0xb00c, 0xb010, 0xb014, + 0xb01c, 0xb01d, 0xb028, 0xb044, 0xb045, 0xb048, 0xb04a, 0xb04c, + 0xb04e, 0xb053, 0xb054, 0xb055, 0xb057, 0xb059, + /* 0x33 */ + 0xb05d, 0xb07c, 0xb07d, 0xb080, 0xb084, 0xb08c, 0xb08d, 0xb08f, + 0xb091, 0xb098, 0xb099, 0xb09a, 0xb09c, 0xb09f, 0xb0a0, 0xb0a1, + 0xb0a2, 0xb0a8, 0xb0a9, 0xb0ab, 0xb0ac, 0xb0ad, 0xb0ae, 0xb0af, + 0xb0b1, 0xb0b3, 0xb0b4, 0xb0b5, 0xb0b8, 0xb0bc, 0xb0c4, 0xb0c5, + 0xb0c7, 0xb0c8, 0xb0c9, 0xb0d0, 0xb0d1, 0xb0d4, 0xb0d8, 0xb0e0, + 0xb0e5, 0xb108, 0xb109, 0xb10b, 0xb10c, 0xb110, 0xb112, 0xb113, + 0xb118, 0xb119, 0xb11b, 0xb11c, 0xb11d, 0xb123, 0xb124, 0xb125, + 0xb128, 0xb12c, 0xb134, 0xb135, 0xb137, 0xb138, 0xb139, 0xb140, + 0xb141, 0xb144, 0xb148, 0xb150, 0xb151, 0xb154, 0xb155, 0xb158, + 0xb15c, 0xb160, 0xb178, 0xb179, 0xb17c, 0xb180, 0xb182, 0xb188, + 0xb189, 0xb18b, 0xb18d, 0xb192, 0xb193, 0xb194, 0xb198, 0xb19c, + 0xb1a8, 0xb1cc, 0xb1d0, 0xb1d4, 0xb1dc, 0xb1dd, + /* 0x34 */ + 0xb1df, 0xb1e8, 0xb1e9, 0xb1ec, 0xb1f0, 0xb1f9, 0xb1fb, 0xb1fd, + 0xb204, 0xb205, 0xb208, 0xb20b, 0xb20c, 0xb214, 0xb215, 0xb217, + 0xb219, 0xb220, 0xb234, 0xb23c, 0xb258, 0xb25c, 0xb260, 0xb268, + 0xb269, 0xb274, 0xb275, 0xb27c, 0xb284, 0xb285, 0xb289, 0xb290, + 0xb291, 0xb294, 0xb298, 0xb299, 0xb29a, 0xb2a0, 0xb2a1, 0xb2a3, + 0xb2a5, 0xb2a6, 0xb2aa, 0xb2ac, 0xb2b0, 0xb2b4, 0xb2c8, 0xb2c9, + 0xb2cc, 0xb2d0, 0xb2d2, 0xb2d8, 0xb2d9, 0xb2db, 0xb2dd, 0xb2e2, + 0xb2e4, 0xb2e5, 0xb2e6, 0xb2e8, 0xb2eb, 0xb2ec, 0xb2ed, 0xb2ee, + 0xb2ef, 0xb2f3, 0xb2f4, 0xb2f5, 0xb2f7, 0xb2f8, 0xb2f9, 0xb2fa, + 0xb2fb, 0xb2ff, 0xb300, 0xb301, 0xb304, 0xb308, 0xb310, 0xb311, + 0xb313, 0xb314, 0xb315, 0xb31c, 0xb354, 0xb355, 0xb356, 0xb358, + 0xb35b, 0xb35c, 0xb35e, 0xb35f, 0xb364, 0xb365, + /* 0x35 */ + 0xb367, 0xb369, 0xb36b, 0xb36e, 0xb370, 0xb371, 0xb374, 0xb378, + 0xb380, 0xb381, 0xb383, 0xb384, 0xb385, 0xb38c, 0xb390, 0xb394, + 0xb3a0, 0xb3a1, 0xb3a8, 0xb3ac, 0xb3c4, 0xb3c5, 0xb3c8, 0xb3cb, + 0xb3cc, 0xb3ce, 0xb3d0, 0xb3d4, 0xb3d5, 0xb3d7, 0xb3d9, 0xb3db, + 0xb3dd, 0xb3e0, 0xb3e4, 0xb3e8, 0xb3fc, 0xb410, 0xb418, 0xb41c, + 0xb420, 0xb428, 0xb429, 0xb42b, 0xb434, 0xb450, 0xb451, 0xb454, + 0xb458, 0xb460, 0xb461, 0xb463, 0xb465, 0xb46c, 0xb480, 0xb488, + 0xb49d, 0xb4a4, 0xb4a8, 0xb4ac, 0xb4b5, 0xb4b7, 0xb4b9, 0xb4c0, + 0xb4c4, 0xb4c8, 0xb4d0, 0xb4d5, 0xb4dc, 0xb4dd, 0xb4e0, 0xb4e3, + 0xb4e4, 0xb4e6, 0xb4ec, 0xb4ed, 0xb4ef, 0xb4f1, 0xb4f8, 0xb514, + 0xb515, 0xb518, 0xb51b, 0xb51c, 0xb524, 0xb525, 0xb527, 0xb528, + 0xb529, 0xb52a, 0xb530, 0xb531, 0xb534, 0xb538, + /* 0x36 */ + 0xb540, 0xb541, 0xb543, 0xb544, 0xb545, 0xb54b, 0xb54c, 0xb54d, + 0xb550, 0xb554, 0xb55c, 0xb55d, 0xb55f, 0xb560, 0xb561, 0xb5a0, + 0xb5a1, 0xb5a4, 0xb5a8, 0xb5aa, 0xb5ab, 0xb5b0, 0xb5b1, 0xb5b3, + 0xb5b4, 0xb5b5, 0xb5bb, 0xb5bc, 0xb5bd, 0xb5c0, 0xb5c4, 0xb5cc, + 0xb5cd, 0xb5cf, 0xb5d0, 0xb5d1, 0xb5d8, 0xb5ec, 0xb610, 0xb611, + 0xb614, 0xb618, 0xb625, 0xb62c, 0xb634, 0xb648, 0xb664, 0xb668, + 0xb69c, 0xb69d, 0xb6a0, 0xb6a4, 0xb6ab, 0xb6ac, 0xb6b1, 0xb6d4, + 0xb6f0, 0xb6f4, 0xb6f8, 0xb700, 0xb701, 0xb705, 0xb728, 0xb729, + 0xb72c, 0xb72f, 0xb730, 0xb738, 0xb739, 0xb73b, 0xb744, 0xb748, + 0xb74c, 0xb754, 0xb755, 0xb760, 0xb764, 0xb768, 0xb770, 0xb771, + 0xb773, 0xb775, 0xb77c, 0xb77d, 0xb780, 0xb784, 0xb78c, 0xb78d, + 0xb78f, 0xb790, 0xb791, 0xb792, 0xb796, 0xb797, + /* 0x37 */ + 0xb798, 0xb799, 0xb79c, 0xb7a0, 0xb7a8, 0xb7a9, 0xb7ab, 0xb7ac, + 0xb7ad, 0xb7b4, 0xb7b5, 0xb7b8, 0xb7c7, 0xb7c9, 0xb7ec, 0xb7ed, + 0xb7f0, 0xb7f4, 0xb7fc, 0xb7fd, 0xb7ff, 0xb800, 0xb801, 0xb807, + 0xb808, 0xb809, 0xb80c, 0xb810, 0xb818, 0xb819, 0xb81b, 0xb81d, + 0xb824, 0xb825, 0xb828, 0xb82c, 0xb834, 0xb835, 0xb837, 0xb838, + 0xb839, 0xb840, 0xb844, 0xb851, 0xb853, 0xb85c, 0xb85d, 0xb860, + 0xb864, 0xb86c, 0xb86d, 0xb86f, 0xb871, 0xb878, 0xb87c, 0xb88d, + 0xb8a8, 0xb8b0, 0xb8b4, 0xb8b8, 0xb8c0, 0xb8c1, 0xb8c3, 0xb8c5, + 0xb8cc, 0xb8d0, 0xb8d4, 0xb8dd, 0xb8df, 0xb8e1, 0xb8e8, 0xb8e9, + 0xb8ec, 0xb8f0, 0xb8f8, 0xb8f9, 0xb8fb, 0xb8fd, 0xb904, 0xb918, + 0xb920, 0xb93c, 0xb93d, 0xb940, 0xb944, 0xb94c, 0xb94f, 0xb951, + 0xb958, 0xb959, 0xb95c, 0xb960, 0xb968, 0xb969, + /* 0x38 */ + 0xb96b, 0xb96d, 0xb974, 0xb975, 0xb978, 0xb97c, 0xb984, 0xb985, + 0xb987, 0xb989, 0xb98a, 0xb98d, 0xb98e, 0xb9ac, 0xb9ad, 0xb9b0, + 0xb9b4, 0xb9bc, 0xb9bd, 0xb9bf, 0xb9c1, 0xb9c8, 0xb9c9, 0xb9cc, + 0xb9ce, 0xb9cf, 0xb9d0, 0xb9d1, 0xb9d2, 0xb9d8, 0xb9d9, 0xb9db, + 0xb9dd, 0xb9de, 0xb9e1, 0xb9e3, 0xb9e4, 0xb9e5, 0xb9e8, 0xb9ec, + 0xb9f4, 0xb9f5, 0xb9f7, 0xb9f8, 0xb9f9, 0xb9fa, 0xba00, 0xba01, + 0xba08, 0xba15, 0xba38, 0xba39, 0xba3c, 0xba40, 0xba42, 0xba48, + 0xba49, 0xba4b, 0xba4d, 0xba4e, 0xba53, 0xba54, 0xba55, 0xba58, + 0xba5c, 0xba64, 0xba65, 0xba67, 0xba68, 0xba69, 0xba70, 0xba71, + 0xba74, 0xba78, 0xba83, 0xba84, 0xba85, 0xba87, 0xba8c, 0xbaa8, + 0xbaa9, 0xbaab, 0xbaac, 0xbab0, 0xbab2, 0xbab8, 0xbab9, 0xbabb, + 0xbabd, 0xbac4, 0xbac8, 0xbad8, 0xbad9, 0xbafc, + /* 0x39 */ + 0xbb00, 0xbb04, 0xbb0d, 0xbb0f, 0xbb11, 0xbb18, 0xbb1c, 0xbb20, + 0xbb29, 0xbb2b, 0xbb34, 0xbb35, 0xbb36, 0xbb38, 0xbb3b, 0xbb3c, + 0xbb3d, 0xbb3e, 0xbb44, 0xbb45, 0xbb47, 0xbb49, 0xbb4d, 0xbb4f, + 0xbb50, 0xbb54, 0xbb58, 0xbb61, 0xbb63, 0xbb6c, 0xbb88, 0xbb8c, + 0xbb90, 0xbba4, 0xbba8, 0xbbac, 0xbbb4, 0xbbb7, 0xbbc0, 0xbbc4, + 0xbbc8, 0xbbd0, 0xbbd3, 0xbbf8, 0xbbf9, 0xbbfc, 0xbbff, 0xbc00, + 0xbc02, 0xbc08, 0xbc09, 0xbc0b, 0xbc0c, 0xbc0d, 0xbc0f, 0xbc11, + 0xbc14, 0xbc15, 0xbc16, 0xbc17, 0xbc18, 0xbc1b, 0xbc1c, 0xbc1d, + 0xbc1e, 0xbc1f, 0xbc24, 0xbc25, 0xbc27, 0xbc29, 0xbc2d, 0xbc30, + 0xbc31, 0xbc34, 0xbc38, 0xbc40, 0xbc41, 0xbc43, 0xbc44, 0xbc45, + 0xbc49, 0xbc4c, 0xbc4d, 0xbc50, 0xbc5d, 0xbc84, 0xbc85, 0xbc88, + 0xbc8b, 0xbc8c, 0xbc8e, 0xbc94, 0xbc95, 0xbc97, + /* 0x3a */ + 0xbc99, 0xbc9a, 0xbca0, 0xbca1, 0xbca4, 0xbca7, 0xbca8, 0xbcb0, + 0xbcb1, 0xbcb3, 0xbcb4, 0xbcb5, 0xbcbc, 0xbcbd, 0xbcc0, 0xbcc4, + 0xbccd, 0xbccf, 0xbcd0, 0xbcd1, 0xbcd5, 0xbcd8, 0xbcdc, 0xbcf4, + 0xbcf5, 0xbcf6, 0xbcf8, 0xbcfc, 0xbd04, 0xbd05, 0xbd07, 0xbd09, + 0xbd10, 0xbd14, 0xbd24, 0xbd2c, 0xbd40, 0xbd48, 0xbd49, 0xbd4c, + 0xbd50, 0xbd58, 0xbd59, 0xbd64, 0xbd68, 0xbd80, 0xbd81, 0xbd84, + 0xbd87, 0xbd88, 0xbd89, 0xbd8a, 0xbd90, 0xbd91, 0xbd93, 0xbd95, + 0xbd99, 0xbd9a, 0xbd9c, 0xbda4, 0xbdb0, 0xbdb8, 0xbdd4, 0xbdd5, + 0xbdd8, 0xbddc, 0xbde9, 0xbdf0, 0xbdf4, 0xbdf8, 0xbe00, 0xbe03, + 0xbe05, 0xbe0c, 0xbe0d, 0xbe10, 0xbe14, 0xbe1c, 0xbe1d, 0xbe1f, + 0xbe44, 0xbe45, 0xbe48, 0xbe4c, 0xbe4e, 0xbe54, 0xbe55, 0xbe57, + 0xbe59, 0xbe5a, 0xbe5b, 0xbe60, 0xbe61, 0xbe64, + /* 0x3b */ + 0xbe68, 0xbe6a, 0xbe70, 0xbe71, 0xbe73, 0xbe74, 0xbe75, 0xbe7b, + 0xbe7c, 0xbe7d, 0xbe80, 0xbe84, 0xbe8c, 0xbe8d, 0xbe8f, 0xbe90, + 0xbe91, 0xbe98, 0xbe99, 0xbea8, 0xbed0, 0xbed1, 0xbed4, 0xbed7, + 0xbed8, 0xbee0, 0xbee3, 0xbee4, 0xbee5, 0xbeec, 0xbf01, 0xbf08, + 0xbf09, 0xbf18, 0xbf19, 0xbf1b, 0xbf1c, 0xbf1d, 0xbf40, 0xbf41, + 0xbf44, 0xbf48, 0xbf50, 0xbf51, 0xbf55, 0xbf94, 0xbfb0, 0xbfc5, + 0xbfcc, 0xbfcd, 0xbfd0, 0xbfd4, 0xbfdc, 0xbfdf, 0xbfe1, 0xc03c, + 0xc051, 0xc058, 0xc05c, 0xc060, 0xc068, 0xc069, 0xc090, 0xc091, + 0xc094, 0xc098, 0xc0a0, 0xc0a1, 0xc0a3, 0xc0a5, 0xc0ac, 0xc0ad, + 0xc0af, 0xc0b0, 0xc0b3, 0xc0b4, 0xc0b5, 0xc0b6, 0xc0bc, 0xc0bd, + 0xc0bf, 0xc0c0, 0xc0c1, 0xc0c5, 0xc0c8, 0xc0c9, 0xc0cc, 0xc0d0, + 0xc0d8, 0xc0d9, 0xc0db, 0xc0dc, 0xc0dd, 0xc0e4, + /* 0x3c */ + 0xc0e5, 0xc0e8, 0xc0ec, 0xc0f4, 0xc0f5, 0xc0f7, 0xc0f9, 0xc100, + 0xc104, 0xc108, 0xc110, 0xc115, 0xc11c, 0xc11d, 0xc11e, 0xc11f, + 0xc120, 0xc123, 0xc124, 0xc126, 0xc127, 0xc12c, 0xc12d, 0xc12f, + 0xc130, 0xc131, 0xc136, 0xc138, 0xc139, 0xc13c, 0xc140, 0xc148, + 0xc149, 0xc14b, 0xc14c, 0xc14d, 0xc154, 0xc155, 0xc158, 0xc15c, + 0xc164, 0xc165, 0xc167, 0xc168, 0xc169, 0xc170, 0xc174, 0xc178, + 0xc185, 0xc18c, 0xc18d, 0xc18e, 0xc190, 0xc194, 0xc196, 0xc19c, + 0xc19d, 0xc19f, 0xc1a1, 0xc1a5, 0xc1a8, 0xc1a9, 0xc1ac, 0xc1b0, + 0xc1bd, 0xc1c4, 0xc1c8, 0xc1cc, 0xc1d4, 0xc1d7, 0xc1d8, 0xc1e0, + 0xc1e4, 0xc1e8, 0xc1f0, 0xc1f1, 0xc1f3, 0xc1fc, 0xc1fd, 0xc200, + 0xc204, 0xc20c, 0xc20d, 0xc20f, 0xc211, 0xc218, 0xc219, 0xc21c, + 0xc21f, 0xc220, 0xc228, 0xc229, 0xc22b, 0xc22d, + /* 0x3d */ + 0xc22f, 0xc231, 0xc232, 0xc234, 0xc248, 0xc250, 0xc251, 0xc254, + 0xc258, 0xc260, 0xc265, 0xc26c, 0xc26d, 0xc270, 0xc274, 0xc27c, + 0xc27d, 0xc27f, 0xc281, 0xc288, 0xc289, 0xc290, 0xc298, 0xc29b, + 0xc29d, 0xc2a4, 0xc2a5, 0xc2a8, 0xc2ac, 0xc2ad, 0xc2b4, 0xc2b5, + 0xc2b7, 0xc2b9, 0xc2dc, 0xc2dd, 0xc2e0, 0xc2e3, 0xc2e4, 0xc2eb, + 0xc2ec, 0xc2ed, 0xc2ef, 0xc2f1, 0xc2f6, 0xc2f8, 0xc2f9, 0xc2fb, + 0xc2fc, 0xc300, 0xc308, 0xc309, 0xc30c, 0xc30d, 0xc313, 0xc314, + 0xc315, 0xc318, 0xc31c, 0xc324, 0xc325, 0xc328, 0xc329, 0xc345, + 0xc368, 0xc369, 0xc36c, 0xc370, 0xc372, 0xc378, 0xc379, 0xc37c, + 0xc37d, 0xc384, 0xc388, 0xc38c, 0xc3c0, 0xc3d8, 0xc3d9, 0xc3dc, + 0xc3df, 0xc3e0, 0xc3e2, 0xc3e8, 0xc3e9, 0xc3ed, 0xc3f4, 0xc3f5, + 0xc3f8, 0xc408, 0xc410, 0xc424, 0xc42c, 0xc430, + /* 0x3e */ + 0xc434, 0xc43c, 0xc43d, 0xc448, 0xc464, 0xc465, 0xc468, 0xc46c, + 0xc474, 0xc475, 0xc479, 0xc480, 0xc494, 0xc49c, 0xc4b8, 0xc4bc, + 0xc4e9, 0xc4f0, 0xc4f1, 0xc4f4, 0xc4f8, 0xc4fa, 0xc4ff, 0xc500, + 0xc501, 0xc50c, 0xc510, 0xc514, 0xc51c, 0xc528, 0xc529, 0xc52c, + 0xc530, 0xc538, 0xc539, 0xc53b, 0xc53d, 0xc544, 0xc545, 0xc548, + 0xc549, 0xc54a, 0xc54c, 0xc54d, 0xc54e, 0xc553, 0xc554, 0xc555, + 0xc557, 0xc558, 0xc559, 0xc55d, 0xc55e, 0xc560, 0xc561, 0xc564, + 0xc568, 0xc570, 0xc571, 0xc573, 0xc574, 0xc575, 0xc57c, 0xc57d, + 0xc580, 0xc584, 0xc587, 0xc58c, 0xc58d, 0xc58f, 0xc591, 0xc595, + 0xc597, 0xc598, 0xc59c, 0xc5a0, 0xc5a9, 0xc5b4, 0xc5b5, 0xc5b8, + 0xc5b9, 0xc5bb, 0xc5bc, 0xc5bd, 0xc5be, 0xc5c4, 0xc5c5, 0xc5c6, + 0xc5c7, 0xc5c8, 0xc5c9, 0xc5ca, 0xc5cc, 0xc5ce, + /* 0x3f */ + 0xc5d0, 0xc5d1, 0xc5d4, 0xc5d8, 0xc5e0, 0xc5e1, 0xc5e3, 0xc5e5, + 0xc5ec, 0xc5ed, 0xc5ee, 0xc5f0, 0xc5f4, 0xc5f6, 0xc5f7, 0xc5fc, + 0xc5fd, 0xc5fe, 0xc5ff, 0xc600, 0xc601, 0xc605, 0xc606, 0xc607, + 0xc608, 0xc60c, 0xc610, 0xc618, 0xc619, 0xc61b, 0xc61c, 0xc624, + 0xc625, 0xc628, 0xc62c, 0xc62d, 0xc62e, 0xc630, 0xc633, 0xc634, + 0xc635, 0xc637, 0xc639, 0xc63b, 0xc640, 0xc641, 0xc644, 0xc648, + 0xc650, 0xc651, 0xc653, 0xc654, 0xc655, 0xc65c, 0xc65d, 0xc660, + 0xc66c, 0xc66f, 0xc671, 0xc678, 0xc679, 0xc67c, 0xc680, 0xc688, + 0xc689, 0xc68b, 0xc68d, 0xc694, 0xc695, 0xc698, 0xc69c, 0xc6a4, + 0xc6a5, 0xc6a7, 0xc6a9, 0xc6b0, 0xc6b1, 0xc6b4, 0xc6b8, 0xc6b9, + 0xc6ba, 0xc6c0, 0xc6c1, 0xc6c3, 0xc6c5, 0xc6cc, 0xc6cd, 0xc6d0, + 0xc6d4, 0xc6dc, 0xc6dd, 0xc6e0, 0xc6e1, 0xc6e8, + /* 0x40 */ + 0xc6e9, 0xc6ec, 0xc6f0, 0xc6f8, 0xc6f9, 0xc6fd, 0xc704, 0xc705, + 0xc708, 0xc70c, 0xc714, 0xc715, 0xc717, 0xc719, 0xc720, 0xc721, + 0xc724, 0xc728, 0xc730, 0xc731, 0xc733, 0xc735, 0xc737, 0xc73c, + 0xc73d, 0xc740, 0xc744, 0xc74a, 0xc74c, 0xc74d, 0xc74f, 0xc751, + 0xc752, 0xc753, 0xc754, 0xc755, 0xc756, 0xc757, 0xc758, 0xc75c, + 0xc760, 0xc768, 0xc76b, 0xc774, 0xc775, 0xc778, 0xc77c, 0xc77d, + 0xc77e, 0xc783, 0xc784, 0xc785, 0xc787, 0xc788, 0xc789, 0xc78a, + 0xc78e, 0xc790, 0xc791, 0xc794, 0xc796, 0xc797, 0xc798, 0xc79a, + 0xc7a0, 0xc7a1, 0xc7a3, 0xc7a4, 0xc7a5, 0xc7a6, 0xc7ac, 0xc7ad, + 0xc7b0, 0xc7b4, 0xc7bc, 0xc7bd, 0xc7bf, 0xc7c0, 0xc7c1, 0xc7c8, + 0xc7c9, 0xc7cc, 0xc7ce, 0xc7d0, 0xc7d8, 0xc7dd, 0xc7e4, 0xc7e8, + 0xc7ec, 0xc800, 0xc801, 0xc804, 0xc808, 0xc80a, + /* 0x41 */ + 0xc810, 0xc811, 0xc813, 0xc815, 0xc816, 0xc81c, 0xc81d, 0xc820, + 0xc824, 0xc82c, 0xc82d, 0xc82f, 0xc831, 0xc838, 0xc83c, 0xc840, + 0xc848, 0xc849, 0xc84c, 0xc84d, 0xc854, 0xc870, 0xc871, 0xc874, + 0xc878, 0xc87a, 0xc880, 0xc881, 0xc883, 0xc885, 0xc886, 0xc887, + 0xc88b, 0xc88c, 0xc88d, 0xc894, 0xc89d, 0xc89f, 0xc8a1, 0xc8a8, + 0xc8bc, 0xc8bd, 0xc8c4, 0xc8c8, 0xc8cc, 0xc8d4, 0xc8d5, 0xc8d7, + 0xc8d9, 0xc8e0, 0xc8e1, 0xc8e4, 0xc8f5, 0xc8fc, 0xc8fd, 0xc900, + 0xc904, 0xc905, 0xc906, 0xc90c, 0xc90d, 0xc90f, 0xc911, 0xc918, + 0xc92c, 0xc934, 0xc950, 0xc951, 0xc954, 0xc958, 0xc960, 0xc961, + 0xc963, 0xc96c, 0xc970, 0xc974, 0xc97c, 0xc988, 0xc989, 0xc98c, + 0xc990, 0xc998, 0xc999, 0xc99b, 0xc99d, 0xc9c0, 0xc9c1, 0xc9c4, + 0xc9c7, 0xc9c8, 0xc9ca, 0xc9d0, 0xc9d1, 0xc9d3, + /* 0x42 */ + 0xc9d5, 0xc9d6, 0xc9d9, 0xc9da, 0xc9dc, 0xc9dd, 0xc9e0, 0xc9e2, + 0xc9e4, 0xc9e7, 0xc9ec, 0xc9ed, 0xc9ef, 0xc9f0, 0xc9f1, 0xc9f8, + 0xc9f9, 0xc9fc, 0xca00, 0xca08, 0xca09, 0xca0b, 0xca0c, 0xca0d, + 0xca14, 0xca18, 0xca29, 0xca4c, 0xca4d, 0xca50, 0xca54, 0xca5c, + 0xca5d, 0xca5f, 0xca60, 0xca61, 0xca68, 0xca7d, 0xca84, 0xca98, + 0xcabc, 0xcabd, 0xcac0, 0xcac4, 0xcacc, 0xcacd, 0xcacf, 0xcad1, + 0xcad3, 0xcad8, 0xcad9, 0xcae0, 0xcaec, 0xcaf4, 0xcb08, 0xcb10, + 0xcb14, 0xcb18, 0xcb20, 0xcb21, 0xcb41, 0xcb48, 0xcb49, 0xcb4c, + 0xcb50, 0xcb58, 0xcb59, 0xcb5d, 0xcb64, 0xcb78, 0xcb79, 0xcb9c, + 0xcbb8, 0xcbd4, 0xcbe4, 0xcbe7, 0xcbe9, 0xcc0c, 0xcc0d, 0xcc10, + 0xcc14, 0xcc1c, 0xcc1d, 0xcc21, 0xcc22, 0xcc27, 0xcc28, 0xcc29, + 0xcc2c, 0xcc2e, 0xcc30, 0xcc38, 0xcc39, 0xcc3b, + /* 0x43 */ + 0xcc3c, 0xcc3d, 0xcc3e, 0xcc44, 0xcc45, 0xcc48, 0xcc4c, 0xcc54, + 0xcc55, 0xcc57, 0xcc58, 0xcc59, 0xcc60, 0xcc64, 0xcc66, 0xcc68, + 0xcc70, 0xcc75, 0xcc98, 0xcc99, 0xcc9c, 0xcca0, 0xcca8, 0xcca9, + 0xccab, 0xccac, 0xccad, 0xccb4, 0xccb5, 0xccb8, 0xccbc, 0xccc4, + 0xccc5, 0xccc7, 0xccc9, 0xccd0, 0xccd4, 0xcce4, 0xccec, 0xccf0, + 0xcd01, 0xcd08, 0xcd09, 0xcd0c, 0xcd10, 0xcd18, 0xcd19, 0xcd1b, + 0xcd1d, 0xcd24, 0xcd28, 0xcd2c, 0xcd39, 0xcd5c, 0xcd60, 0xcd64, + 0xcd6c, 0xcd6d, 0xcd6f, 0xcd71, 0xcd78, 0xcd88, 0xcd94, 0xcd95, + 0xcd98, 0xcd9c, 0xcda4, 0xcda5, 0xcda7, 0xcda9, 0xcdb0, 0xcdc4, + 0xcdcc, 0xcdd0, 0xcde8, 0xcdec, 0xcdf0, 0xcdf8, 0xcdf9, 0xcdfb, + 0xcdfd, 0xce04, 0xce08, 0xce0c, 0xce14, 0xce19, 0xce20, 0xce21, + 0xce24, 0xce28, 0xce30, 0xce31, 0xce33, 0xce35, + /* 0x44 */ + 0xce58, 0xce59, 0xce5c, 0xce5f, 0xce60, 0xce61, 0xce68, 0xce69, + 0xce6b, 0xce6d, 0xce74, 0xce75, 0xce78, 0xce7c, 0xce84, 0xce85, + 0xce87, 0xce89, 0xce90, 0xce91, 0xce94, 0xce98, 0xcea0, 0xcea1, + 0xcea3, 0xcea4, 0xcea5, 0xceac, 0xcead, 0xcec1, 0xcee4, 0xcee5, + 0xcee8, 0xceeb, 0xceec, 0xcef4, 0xcef5, 0xcef7, 0xcef8, 0xcef9, + 0xcf00, 0xcf01, 0xcf04, 0xcf08, 0xcf10, 0xcf11, 0xcf13, 0xcf15, + 0xcf1c, 0xcf20, 0xcf24, 0xcf2c, 0xcf2d, 0xcf2f, 0xcf30, 0xcf31, + 0xcf38, 0xcf54, 0xcf55, 0xcf58, 0xcf5c, 0xcf64, 0xcf65, 0xcf67, + 0xcf69, 0xcf70, 0xcf71, 0xcf74, 0xcf78, 0xcf80, 0xcf85, 0xcf8c, + 0xcfa1, 0xcfa8, 0xcfb0, 0xcfc4, 0xcfe0, 0xcfe1, 0xcfe4, 0xcfe8, + 0xcff0, 0xcff1, 0xcff3, 0xcff5, 0xcffc, 0xd000, 0xd004, 0xd011, + 0xd018, 0xd02d, 0xd034, 0xd035, 0xd038, 0xd03c, + /* 0x45 */ + 0xd044, 0xd045, 0xd047, 0xd049, 0xd050, 0xd054, 0xd058, 0xd060, + 0xd06c, 0xd06d, 0xd070, 0xd074, 0xd07c, 0xd07d, 0xd081, 0xd0a4, + 0xd0a5, 0xd0a8, 0xd0ac, 0xd0b4, 0xd0b5, 0xd0b7, 0xd0b9, 0xd0c0, + 0xd0c1, 0xd0c4, 0xd0c8, 0xd0c9, 0xd0d0, 0xd0d1, 0xd0d3, 0xd0d4, + 0xd0d5, 0xd0dc, 0xd0dd, 0xd0e0, 0xd0e4, 0xd0ec, 0xd0ed, 0xd0ef, + 0xd0f0, 0xd0f1, 0xd0f8, 0xd10d, 0xd130, 0xd131, 0xd134, 0xd138, + 0xd13a, 0xd140, 0xd141, 0xd143, 0xd144, 0xd145, 0xd14c, 0xd14d, + 0xd150, 0xd154, 0xd15c, 0xd15d, 0xd15f, 0xd161, 0xd168, 0xd16c, + 0xd17c, 0xd184, 0xd188, 0xd1a0, 0xd1a1, 0xd1a4, 0xd1a8, 0xd1b0, + 0xd1b1, 0xd1b3, 0xd1b5, 0xd1ba, 0xd1bc, 0xd1c0, 0xd1d8, 0xd1f4, + 0xd1f8, 0xd207, 0xd209, 0xd210, 0xd22c, 0xd22d, 0xd230, 0xd234, + 0xd23c, 0xd23d, 0xd23f, 0xd241, 0xd248, 0xd25c, + /* 0x46 */ + 0xd264, 0xd280, 0xd281, 0xd284, 0xd288, 0xd290, 0xd291, 0xd295, + 0xd29c, 0xd2a0, 0xd2a4, 0xd2ac, 0xd2b1, 0xd2b8, 0xd2b9, 0xd2bc, + 0xd2bf, 0xd2c0, 0xd2c2, 0xd2c8, 0xd2c9, 0xd2cb, 0xd2d4, 0xd2d8, + 0xd2dc, 0xd2e4, 0xd2e5, 0xd2f0, 0xd2f1, 0xd2f4, 0xd2f8, 0xd300, + 0xd301, 0xd303, 0xd305, 0xd30c, 0xd30d, 0xd30e, 0xd310, 0xd314, + 0xd316, 0xd31c, 0xd31d, 0xd31f, 0xd320, 0xd321, 0xd325, 0xd328, + 0xd329, 0xd32c, 0xd330, 0xd338, 0xd339, 0xd33b, 0xd33c, 0xd33d, + 0xd344, 0xd345, 0xd37c, 0xd37d, 0xd380, 0xd384, 0xd38c, 0xd38d, + 0xd38f, 0xd390, 0xd391, 0xd398, 0xd399, 0xd39c, 0xd3a0, 0xd3a8, + 0xd3a9, 0xd3ab, 0xd3ad, 0xd3b4, 0xd3b8, 0xd3bc, 0xd3c4, 0xd3c5, + 0xd3c8, 0xd3c9, 0xd3d0, 0xd3d8, 0xd3e1, 0xd3e3, 0xd3ec, 0xd3ed, + 0xd3f0, 0xd3f4, 0xd3fc, 0xd3fd, 0xd3ff, 0xd401, + /* 0x47 */ + 0xd408, 0xd41d, 0xd440, 0xd444, 0xd45c, 0xd460, 0xd464, 0xd46d, + 0xd46f, 0xd478, 0xd479, 0xd47c, 0xd47f, 0xd480, 0xd482, 0xd488, + 0xd489, 0xd48b, 0xd48d, 0xd494, 0xd4a9, 0xd4cc, 0xd4d0, 0xd4d4, + 0xd4dc, 0xd4df, 0xd4e8, 0xd4ec, 0xd4f0, 0xd4f8, 0xd4fb, 0xd4fd, + 0xd504, 0xd508, 0xd50c, 0xd514, 0xd515, 0xd517, 0xd53c, 0xd53d, + 0xd540, 0xd544, 0xd54c, 0xd54d, 0xd54f, 0xd551, 0xd558, 0xd559, + 0xd55c, 0xd560, 0xd565, 0xd568, 0xd569, 0xd56b, 0xd56d, 0xd574, + 0xd575, 0xd578, 0xd57c, 0xd584, 0xd585, 0xd587, 0xd588, 0xd589, + 0xd590, 0xd5a5, 0xd5c8, 0xd5c9, 0xd5cc, 0xd5d0, 0xd5d2, 0xd5d8, + 0xd5d9, 0xd5db, 0xd5dd, 0xd5e4, 0xd5e5, 0xd5e8, 0xd5ec, 0xd5f4, + 0xd5f5, 0xd5f7, 0xd5f9, 0xd600, 0xd601, 0xd604, 0xd608, 0xd610, + 0xd611, 0xd613, 0xd614, 0xd615, 0xd61c, 0xd620, + /* 0x48 */ + 0xd624, 0xd62d, 0xd638, 0xd639, 0xd63c, 0xd640, 0xd645, 0xd648, + 0xd649, 0xd64b, 0xd64d, 0xd651, 0xd654, 0xd655, 0xd658, 0xd65c, + 0xd667, 0xd669, 0xd670, 0xd671, 0xd674, 0xd683, 0xd685, 0xd68c, + 0xd68d, 0xd690, 0xd694, 0xd69d, 0xd69f, 0xd6a1, 0xd6a8, 0xd6ac, + 0xd6b0, 0xd6b9, 0xd6bb, 0xd6c4, 0xd6c5, 0xd6c8, 0xd6cc, 0xd6d1, + 0xd6d4, 0xd6d7, 0xd6d9, 0xd6e0, 0xd6e4, 0xd6e8, 0xd6f0, 0xd6f5, + 0xd6fc, 0xd6fd, 0xd700, 0xd704, 0xd711, 0xd718, 0xd719, 0xd71c, + 0xd720, 0xd728, 0xd729, 0xd72b, 0xd72d, 0xd734, 0xd735, 0xd738, + 0xd73c, 0xd744, 0xd747, 0xd749, 0xd750, 0xd751, 0xd754, 0xd756, + 0xd757, 0xd758, 0xd759, 0xd760, 0xd761, 0xd763, 0xd765, 0xd769, + 0xd76c, 0xd770, 0xd774, 0xd77c, 0xd77d, 0xd781, 0xd788, 0xd789, + 0xd78c, 0xd790, 0xd798, 0xd799, 0xd79b, 0xd79d, +}; +static const unsigned short ksc5601_2uni_page4a[4888] = { + /* 0x4a */ + 0x4f3d, 0x4f73, 0x5047, 0x50f9, 0x52a0, 0x53ef, 0x5475, 0x54e5, + 0x5609, 0x5ac1, 0x5bb6, 0x6687, 0x67b6, 0x67b7, 0x67ef, 0x6b4c, + 0x73c2, 0x75c2, 0x7a3c, 0x82db, 0x8304, 0x8857, 0x8888, 0x8a36, + 0x8cc8, 0x8dcf, 0x8efb, 0x8fe6, 0x99d5, 0x523b, 0x5374, 0x5404, + 0x606a, 0x6164, 0x6bbc, 0x73cf, 0x811a, 0x89ba, 0x89d2, 0x95a3, + 0x4f83, 0x520a, 0x58be, 0x5978, 0x59e6, 0x5e72, 0x5e79, 0x61c7, + 0x63c0, 0x6746, 0x67ec, 0x687f, 0x6f97, 0x764e, 0x770b, 0x78f5, + 0x7a08, 0x7aff, 0x7c21, 0x809d, 0x826e, 0x8271, 0x8aeb, 0x9593, + 0x4e6b, 0x559d, 0x66f7, 0x6e34, 0x78a3, 0x7aed, 0x845b, 0x8910, + 0x874e, 0x97a8, 0x52d8, 0x574e, 0x582a, 0x5d4c, 0x611f, 0x61be, + 0x6221, 0x6562, 0x67d1, 0x6a44, 0x6e1b, 0x7518, 0x75b3, 0x76e3, + 0x77b0, 0x7d3a, 0x90af, 0x9451, 0x9452, 0x9f95, + /* 0x4b */ + 0x5323, 0x5cac, 0x7532, 0x80db, 0x9240, 0x9598, 0x525b, 0x5808, + 0x59dc, 0x5ca1, 0x5d17, 0x5eb7, 0x5f3a, 0x5f4a, 0x6177, 0x6c5f, + 0x757a, 0x7586, 0x7ce0, 0x7d73, 0x7db1, 0x7f8c, 0x8154, 0x8221, + 0x8591, 0x8941, 0x8b1b, 0x92fc, 0x964d, 0x9c47, 0x4ecb, 0x4ef7, + 0x500b, 0x51f1, 0x584f, 0x6137, 0x613e, 0x6168, 0x6539, 0x69ea, + 0x6f11, 0x75a5, 0x7686, 0x76d6, 0x7b87, 0x82a5, 0x84cb, 0xf900, + 0x93a7, 0x958b, 0x5580, 0x5ba2, 0x5751, 0xf901, 0x7cb3, 0x7fb9, + 0x91b5, 0x5028, 0x53bb, 0x5c45, 0x5de8, 0x62d2, 0x636e, 0x64da, + 0x64e7, 0x6e20, 0x70ac, 0x795b, 0x8ddd, 0x8e1e, 0xf902, 0x907d, + 0x9245, 0x92f8, 0x4e7e, 0x4ef6, 0x5065, 0x5dfe, 0x5efa, 0x6106, + 0x6957, 0x8171, 0x8654, 0x8e47, 0x9375, 0x9a2b, 0x4e5e, 0x5091, + 0x6770, 0x6840, 0x5109, 0x528d, 0x5292, 0x6aa2, + /* 0x4c */ + 0x77bc, 0x9210, 0x9ed4, 0x52ab, 0x602f, 0x8ff2, 0x5048, 0x61a9, + 0x63ed, 0x64ca, 0x683c, 0x6a84, 0x6fc0, 0x8188, 0x89a1, 0x9694, + 0x5805, 0x727d, 0x72ac, 0x7504, 0x7d79, 0x7e6d, 0x80a9, 0x898b, + 0x8b74, 0x9063, 0x9d51, 0x6289, 0x6c7a, 0x6f54, 0x7d50, 0x7f3a, + 0x8a23, 0x517c, 0x614a, 0x7b9d, 0x8b19, 0x9257, 0x938c, 0x4eac, + 0x4fd3, 0x501e, 0x50be, 0x5106, 0x52c1, 0x52cd, 0x537f, 0x5770, + 0x5883, 0x5e9a, 0x5f91, 0x6176, 0x61ac, 0x64ce, 0x656c, 0x666f, + 0x66bb, 0x66f4, 0x6897, 0x6d87, 0x7085, 0x70f1, 0x749f, 0x74a5, + 0x74ca, 0x75d9, 0x786c, 0x78ec, 0x7adf, 0x7af6, 0x7d45, 0x7d93, + 0x8015, 0x803f, 0x811b, 0x8396, 0x8b66, 0x8f15, 0x9015, 0x93e1, + 0x9803, 0x9838, 0x9a5a, 0x9be8, 0x4fc2, 0x5553, 0x583a, 0x5951, + 0x5b63, 0x5c46, 0x60b8, 0x6212, 0x6842, 0x68b0, + /* 0x4d */ + 0x68e8, 0x6eaa, 0x754c, 0x7678, 0x78ce, 0x7a3d, 0x7cfb, 0x7e6b, + 0x7e7c, 0x8a08, 0x8aa1, 0x8c3f, 0x968e, 0x9dc4, 0x53e4, 0x53e9, + 0x544a, 0x5471, 0x56fa, 0x59d1, 0x5b64, 0x5c3b, 0x5eab, 0x62f7, + 0x6537, 0x6545, 0x6572, 0x66a0, 0x67af, 0x69c1, 0x6cbd, 0x75fc, + 0x7690, 0x777e, 0x7a3f, 0x7f94, 0x8003, 0x80a1, 0x818f, 0x82e6, + 0x82fd, 0x83f0, 0x85c1, 0x8831, 0x88b4, 0x8aa5, 0xf903, 0x8f9c, + 0x932e, 0x96c7, 0x9867, 0x9ad8, 0x9f13, 0x54ed, 0x659b, 0x66f2, + 0x688f, 0x7a40, 0x8c37, 0x9d60, 0x56f0, 0x5764, 0x5d11, 0x6606, + 0x68b1, 0x68cd, 0x6efe, 0x7428, 0x889e, 0x9be4, 0x6c68, 0xf904, + 0x9aa8, 0x4f9b, 0x516c, 0x5171, 0x529f, 0x5b54, 0x5de5, 0x6050, + 0x606d, 0x62f1, 0x63a7, 0x653b, 0x73d9, 0x7a7a, 0x86a3, 0x8ca2, + 0x978f, 0x4e32, 0x5be1, 0x6208, 0x679c, 0x74dc, + /* 0x4e */ + 0x79d1, 0x83d3, 0x8a87, 0x8ab2, 0x8de8, 0x904e, 0x934b, 0x9846, + 0x5ed3, 0x69e8, 0x85ff, 0x90ed, 0xf905, 0x51a0, 0x5b98, 0x5bec, + 0x6163, 0x68fa, 0x6b3e, 0x704c, 0x742f, 0x74d8, 0x7ba1, 0x7f50, + 0x83c5, 0x89c0, 0x8cab, 0x95dc, 0x9928, 0x522e, 0x605d, 0x62ec, + 0x9002, 0x4f8a, 0x5149, 0x5321, 0x58d9, 0x5ee3, 0x66e0, 0x6d38, + 0x709a, 0x72c2, 0x73d6, 0x7b50, 0x80f1, 0x945b, 0x5366, 0x639b, + 0x7f6b, 0x4e56, 0x5080, 0x584a, 0x58de, 0x602a, 0x6127, 0x62d0, + 0x69d0, 0x9b41, 0x5b8f, 0x7d18, 0x80b1, 0x8f5f, 0x4ea4, 0x50d1, + 0x54ac, 0x55ac, 0x5b0c, 0x5da0, 0x5de7, 0x652a, 0x654e, 0x6821, + 0x6a4b, 0x72e1, 0x768e, 0x77ef, 0x7d5e, 0x7ff9, 0x81a0, 0x854e, + 0x86df, 0x8f03, 0x8f4e, 0x90ca, 0x9903, 0x9a55, 0x9bab, 0x4e18, + 0x4e45, 0x4e5d, 0x4ec7, 0x4ff1, 0x5177, 0x52fe, + /* 0x4f */ + 0x5340, 0x53e3, 0x53e5, 0x548e, 0x5614, 0x5775, 0x57a2, 0x5bc7, + 0x5d87, 0x5ed0, 0x61fc, 0x62d8, 0x6551, 0x67b8, 0x67e9, 0x69cb, + 0x6b50, 0x6bc6, 0x6bec, 0x6c42, 0x6e9d, 0x7078, 0x72d7, 0x7396, + 0x7403, 0x77bf, 0x77e9, 0x7a76, 0x7d7f, 0x8009, 0x81fc, 0x8205, + 0x820a, 0x82df, 0x8862, 0x8b33, 0x8cfc, 0x8ec0, 0x9011, 0x90b1, + 0x9264, 0x92b6, 0x99d2, 0x9a45, 0x9ce9, 0x9dd7, 0x9f9c, 0x570b, + 0x5c40, 0x83ca, 0x97a0, 0x97ab, 0x9eb4, 0x541b, 0x7a98, 0x7fa4, + 0x88d9, 0x8ecd, 0x90e1, 0x5800, 0x5c48, 0x6398, 0x7a9f, 0x5bae, + 0x5f13, 0x7a79, 0x7aae, 0x828e, 0x8eac, 0x5026, 0x5238, 0x52f8, + 0x5377, 0x5708, 0x62f3, 0x6372, 0x6b0a, 0x6dc3, 0x7737, 0x53a5, + 0x7357, 0x8568, 0x8e76, 0x95d5, 0x673a, 0x6ac3, 0x6f70, 0x8a6d, + 0x8ecc, 0x994b, 0xf906, 0x6677, 0x6b78, 0x8cb4, + /* 0x50 */ + 0x9b3c, 0xf907, 0x53eb, 0x572d, 0x594e, 0x63c6, 0x69fb, 0x73ea, + 0x7845, 0x7aba, 0x7ac5, 0x7cfe, 0x8475, 0x898f, 0x8d73, 0x9035, + 0x95a8, 0x52fb, 0x5747, 0x7547, 0x7b60, 0x83cc, 0x921e, 0xf908, + 0x6a58, 0x514b, 0x524b, 0x5287, 0x621f, 0x68d8, 0x6975, 0x9699, + 0x50c5, 0x52a4, 0x52e4, 0x61c3, 0x65a4, 0x6839, 0x69ff, 0x747e, + 0x7b4b, 0x82b9, 0x83eb, 0x89b2, 0x8b39, 0x8fd1, 0x9949, 0xf909, + 0x4eca, 0x5997, 0x64d2, 0x6611, 0x6a8e, 0x7434, 0x7981, 0x79bd, + 0x82a9, 0x887e, 0x887f, 0x895f, 0xf90a, 0x9326, 0x4f0b, 0x53ca, + 0x6025, 0x6271, 0x6c72, 0x7d1a, 0x7d66, 0x4e98, 0x5162, 0x77dc, + 0x80af, 0x4f01, 0x4f0e, 0x5176, 0x5180, 0x55dc, 0x5668, 0x573b, + 0x57fa, 0x57fc, 0x5914, 0x5947, 0x5993, 0x5bc4, 0x5c90, 0x5d0e, + 0x5df1, 0x5e7e, 0x5fcc, 0x6280, 0x65d7, 0x65e3, + /* 0x51 */ + 0x671e, 0x671f, 0x675e, 0x68cb, 0x68c4, 0x6a5f, 0x6b3a, 0x6c23, + 0x6c7d, 0x6c82, 0x6dc7, 0x7398, 0x7426, 0x742a, 0x7482, 0x74a3, + 0x7578, 0x757f, 0x7881, 0x78ef, 0x7941, 0x7947, 0x7948, 0x797a, + 0x7b95, 0x7d00, 0x7dba, 0x7f88, 0x8006, 0x802d, 0x808c, 0x8a18, + 0x8b4f, 0x8c48, 0x8d77, 0x9321, 0x9324, 0x98e2, 0x9951, 0x9a0e, + 0x9a0f, 0x9a65, 0x9e92, 0x7dca, 0x4f76, 0x5409, 0x62ee, 0x6854, + 0x91d1, 0x55ab, 0x513a, 0xf90b, 0xf90c, 0x5a1c, 0x61e6, 0xf90d, + 0x62cf, 0x62ff, 0xf90e, 0xf90f, 0xf910, 0xf911, 0xf912, 0xf913, + 0x90a3, 0xf914, 0xf915, 0xf916, 0xf917, 0xf918, 0x8afe, 0xf919, + 0xf91a, 0xf91b, 0xf91c, 0x6696, 0xf91d, 0x7156, 0xf91e, 0xf91f, + 0x96e3, 0xf920, 0x634f, 0x637a, 0x5357, 0xf921, 0x678f, 0x6960, + 0x6e73, 0xf922, 0x7537, 0xf923, 0xf924, 0xf925, + /* 0x52 */ + 0x7d0d, 0xf926, 0xf927, 0x8872, 0x56ca, 0x5a18, 0xf928, 0xf929, + 0xf92a, 0xf92b, 0xf92c, 0x4e43, 0xf92d, 0x5167, 0x5948, 0x67f0, + 0x8010, 0xf92e, 0x5973, 0x5e74, 0x649a, 0x79ca, 0x5ff5, 0x606c, + 0x62c8, 0x637b, 0x5be7, 0x5bd7, 0x52aa, 0xf92f, 0x5974, 0x5f29, + 0x6012, 0xf930, 0xf931, 0xf932, 0x7459, 0xf933, 0xf934, 0xf935, + 0xf936, 0xf937, 0xf938, 0x99d1, 0xf939, 0xf93a, 0xf93b, 0xf93c, + 0xf93d, 0xf93e, 0xf93f, 0xf940, 0xf941, 0xf942, 0xf943, 0x6fc3, + 0xf944, 0xf945, 0x81bf, 0x8fb2, 0x60f1, 0xf946, 0xf947, 0x8166, + 0xf948, 0xf949, 0x5c3f, 0xf94a, 0xf94b, 0xf94c, 0xf94d, 0xf94e, + 0xf94f, 0xf950, 0xf951, 0x5ae9, 0x8a25, 0x677b, 0x7d10, 0xf952, + 0xf953, 0xf954, 0xf955, 0xf956, 0xf957, 0x80fd, 0xf958, 0xf959, + 0x5c3c, 0x6ce5, 0x533f, 0x6eba, 0x591a, 0x8336, + /* 0x53 */ + 0x4e39, 0x4eb6, 0x4f46, 0x55ae, 0x5718, 0x58c7, 0x5f56, 0x65b7, + 0x65e6, 0x6a80, 0x6bb5, 0x6e4d, 0x77ed, 0x7aef, 0x7c1e, 0x7dde, + 0x86cb, 0x8892, 0x9132, 0x935b, 0x64bb, 0x6fbe, 0x737a, 0x75b8, + 0x9054, 0x5556, 0x574d, 0x61ba, 0x64d4, 0x66c7, 0x6de1, 0x6e5b, + 0x6f6d, 0x6fb9, 0x75f0, 0x8043, 0x81bd, 0x8541, 0x8983, 0x8ac7, + 0x8b5a, 0x931f, 0x6c93, 0x7553, 0x7b54, 0x8e0f, 0x905d, 0x5510, + 0x5802, 0x5858, 0x5e62, 0x6207, 0x649e, 0x68e0, 0x7576, 0x7cd6, + 0x87b3, 0x9ee8, 0x4ee3, 0x5788, 0x576e, 0x5927, 0x5c0d, 0x5cb1, + 0x5e36, 0x5f85, 0x6234, 0x64e1, 0x73b3, 0x81fa, 0x888b, 0x8cb8, + 0x968a, 0x9edb, 0x5b85, 0x5fb7, 0x60b3, 0x5012, 0x5200, 0x5230, + 0x5716, 0x5835, 0x5857, 0x5c0e, 0x5c60, 0x5cf6, 0x5d8b, 0x5ea6, + 0x5f92, 0x60bc, 0x6311, 0x6389, 0x6417, 0x6843, + /* 0x54 */ + 0x68f9, 0x6ac2, 0x6dd8, 0x6e21, 0x6ed4, 0x6fe4, 0x71fe, 0x76dc, + 0x7779, 0x79b1, 0x7a3b, 0x8404, 0x89a9, 0x8ced, 0x8df3, 0x8e48, + 0x9003, 0x9014, 0x9053, 0x90fd, 0x934d, 0x9676, 0x97dc, 0x6bd2, + 0x7006, 0x7258, 0x72a2, 0x7368, 0x7763, 0x79bf, 0x7be4, 0x7e9b, + 0x8b80, 0x58a9, 0x60c7, 0x6566, 0x65fd, 0x66be, 0x6c8c, 0x711e, + 0x71c9, 0x8c5a, 0x9813, 0x4e6d, 0x7a81, 0x4edd, 0x51ac, 0x51cd, + 0x52d5, 0x540c, 0x61a7, 0x6771, 0x6850, 0x68df, 0x6d1e, 0x6f7c, + 0x75bc, 0x77b3, 0x7ae5, 0x80f4, 0x8463, 0x9285, 0x515c, 0x6597, + 0x675c, 0x6793, 0x75d8, 0x7ac7, 0x8373, 0xf95a, 0x8c46, 0x9017, + 0x982d, 0x5c6f, 0x81c0, 0x829a, 0x9041, 0x906f, 0x920d, 0x5f97, + 0x5d9d, 0x6a59, 0x71c8, 0x767b, 0x7b49, 0x85e4, 0x8b04, 0x9127, + 0x9a30, 0x5587, 0x61f6, 0xf95b, 0x7669, 0x7f85, + /* 0x55 */ + 0x863f, 0x87ba, 0x88f8, 0x908f, 0xf95c, 0x6d1b, 0x70d9, 0x73de, + 0x7d61, 0x843d, 0xf95d, 0x916a, 0x99f1, 0xf95e, 0x4e82, 0x5375, + 0x6b04, 0x6b12, 0x703e, 0x721b, 0x862d, 0x9e1e, 0x524c, 0x8fa3, + 0x5d50, 0x64e5, 0x652c, 0x6b16, 0x6feb, 0x7c43, 0x7e9c, 0x85cd, + 0x8964, 0x89bd, 0x62c9, 0x81d8, 0x881f, 0x5eca, 0x6717, 0x6d6a, + 0x72fc, 0x7405, 0x746f, 0x8782, 0x90de, 0x4f86, 0x5d0d, 0x5fa0, + 0x840a, 0x51b7, 0x63a0, 0x7565, 0x4eae, 0x5006, 0x5169, 0x51c9, + 0x6881, 0x6a11, 0x7cae, 0x7cb1, 0x7ce7, 0x826f, 0x8ad2, 0x8f1b, + 0x91cf, 0x4fb6, 0x5137, 0x52f5, 0x5442, 0x5eec, 0x616e, 0x623e, + 0x65c5, 0x6ada, 0x6ffe, 0x792a, 0x85dc, 0x8823, 0x95ad, 0x9a62, + 0x9a6a, 0x9e97, 0x9ece, 0x529b, 0x66c6, 0x6b77, 0x701d, 0x792b, + 0x8f62, 0x9742, 0x6190, 0x6200, 0x6523, 0x6f23, + /* 0x56 */ + 0x7149, 0x7489, 0x7df4, 0x806f, 0x84ee, 0x8f26, 0x9023, 0x934a, + 0x51bd, 0x5217, 0x52a3, 0x6d0c, 0x70c8, 0x88c2, 0x5ec9, 0x6582, + 0x6bae, 0x6fc2, 0x7c3e, 0x7375, 0x4ee4, 0x4f36, 0x56f9, 0xf95f, + 0x5cba, 0x5dba, 0x601c, 0x73b2, 0x7b2d, 0x7f9a, 0x7fce, 0x8046, + 0x901e, 0x9234, 0x96f6, 0x9748, 0x9818, 0x9f61, 0x4f8b, 0x6fa7, + 0x79ae, 0x91b4, 0x96b7, 0x52de, 0xf960, 0x6488, 0x64c4, 0x6ad3, + 0x6f5e, 0x7018, 0x7210, 0x76e7, 0x8001, 0x8606, 0x865c, 0x8def, + 0x8f05, 0x9732, 0x9b6f, 0x9dfa, 0x9e75, 0x788c, 0x797f, 0x7da0, + 0x83c9, 0x9304, 0x9e7f, 0x9e93, 0x8ad6, 0x58df, 0x5f04, 0x6727, + 0x7027, 0x74cf, 0x7c60, 0x807e, 0x5121, 0x7028, 0x7262, 0x78ca, + 0x8cc2, 0x8cda, 0x8cf4, 0x96f7, 0x4e86, 0x50da, 0x5bee, 0x5ed6, + 0x6599, 0x71ce, 0x7642, 0x77ad, 0x804a, 0x84fc, + /* 0x57 */ + 0x907c, 0x9b27, 0x9f8d, 0x58d8, 0x5a41, 0x5c62, 0x6a13, 0x6dda, + 0x6f0f, 0x763b, 0x7d2f, 0x7e37, 0x851e, 0x8938, 0x93e4, 0x964b, + 0x5289, 0x65d2, 0x67f3, 0x69b4, 0x6d41, 0x6e9c, 0x700f, 0x7409, + 0x7460, 0x7559, 0x7624, 0x786b, 0x8b2c, 0x985e, 0x516d, 0x622e, + 0x9678, 0x4f96, 0x502b, 0x5d19, 0x6dea, 0x7db8, 0x8f2a, 0x5f8b, + 0x6144, 0x6817, 0xf961, 0x9686, 0x52d2, 0x808b, 0x51dc, 0x51cc, + 0x695e, 0x7a1c, 0x7dbe, 0x83f1, 0x9675, 0x4fda, 0x5229, 0x5398, + 0x540f, 0x550e, 0x5c65, 0x60a7, 0x674e, 0x68a8, 0x6d6c, 0x7281, + 0x72f8, 0x7406, 0x7483, 0xf962, 0x75e2, 0x7c6c, 0x7f79, 0x7fb8, + 0x8389, 0x88cf, 0x88e1, 0x91cc, 0x91d0, 0x96e2, 0x9bc9, 0x541d, + 0x6f7e, 0x71d0, 0x7498, 0x85fa, 0x8eaa, 0x96a3, 0x9c57, 0x9e9f, + 0x6797, 0x6dcb, 0x7433, 0x81e8, 0x9716, 0x782c, + /* 0x58 */ + 0x7acb, 0x7b20, 0x7c92, 0x6469, 0x746a, 0x75f2, 0x78bc, 0x78e8, + 0x99ac, 0x9b54, 0x9ebb, 0x5bde, 0x5e55, 0x6f20, 0x819c, 0x83ab, + 0x9088, 0x4e07, 0x534d, 0x5a29, 0x5dd2, 0x5f4e, 0x6162, 0x633d, + 0x6669, 0x66fc, 0x6eff, 0x6f2b, 0x7063, 0x779e, 0x842c, 0x8513, + 0x883b, 0x8f13, 0x9945, 0x9c3b, 0x551c, 0x62b9, 0x672b, 0x6cab, + 0x8309, 0x896a, 0x977a, 0x4ea1, 0x5984, 0x5fd8, 0x5fd9, 0x671b, + 0x7db2, 0x7f54, 0x8292, 0x832b, 0x83bd, 0x8f1e, 0x9099, 0x57cb, + 0x59b9, 0x5a92, 0x5bd0, 0x6627, 0x679a, 0x6885, 0x6bcf, 0x7164, + 0x7f75, 0x8cb7, 0x8ce3, 0x9081, 0x9b45, 0x8108, 0x8c8a, 0x964c, + 0x9a40, 0x9ea5, 0x5b5f, 0x6c13, 0x731b, 0x76f2, 0x76df, 0x840c, + 0x51aa, 0x8993, 0x514d, 0x5195, 0x52c9, 0x68c9, 0x6c94, 0x7704, + 0x7720, 0x7dbf, 0x7dec, 0x9762, 0x9eb5, 0x6ec5, + /* 0x59 */ + 0x8511, 0x51a5, 0x540d, 0x547d, 0x660e, 0x669d, 0x6927, 0x6e9f, + 0x76bf, 0x7791, 0x8317, 0x84c2, 0x879f, 0x9169, 0x9298, 0x9cf4, + 0x8882, 0x4fae, 0x5192, 0x52df, 0x59c6, 0x5e3d, 0x6155, 0x6478, + 0x6479, 0x66ae, 0x67d0, 0x6a21, 0x6bcd, 0x6bdb, 0x725f, 0x7261, + 0x7441, 0x7738, 0x77db, 0x8017, 0x82bc, 0x8305, 0x8b00, 0x8b28, + 0x8c8c, 0x6728, 0x6c90, 0x7267, 0x76ee, 0x7766, 0x7a46, 0x9da9, + 0x6b7f, 0x6c92, 0x5922, 0x6726, 0x8499, 0x536f, 0x5893, 0x5999, + 0x5edf, 0x63cf, 0x6634, 0x6773, 0x6e3a, 0x732b, 0x7ad7, 0x82d7, + 0x9328, 0x52d9, 0x5deb, 0x61ae, 0x61cb, 0x620a, 0x62c7, 0x64ab, + 0x65e0, 0x6959, 0x6b66, 0x6bcb, 0x7121, 0x73f7, 0x755d, 0x7e46, + 0x821e, 0x8302, 0x856a, 0x8aa3, 0x8cbf, 0x9727, 0x9d61, 0x58a8, + 0x9ed8, 0x5011, 0x520e, 0x543b, 0x554f, 0x6587, + /* 0x5a */ + 0x6c76, 0x7d0a, 0x7d0b, 0x805e, 0x868a, 0x9580, 0x96ef, 0x52ff, + 0x6c95, 0x7269, 0x5473, 0x5a9a, 0x5c3e, 0x5d4b, 0x5f4c, 0x5fae, + 0x672a, 0x68b6, 0x6963, 0x6e3c, 0x6e44, 0x7709, 0x7c73, 0x7f8e, + 0x8587, 0x8b0e, 0x8ff7, 0x9761, 0x9ef4, 0x5cb7, 0x60b6, 0x610d, + 0x61ab, 0x654f, 0x65fb, 0x65fc, 0x6c11, 0x6cef, 0x739f, 0x73c9, + 0x7de1, 0x9594, 0x5bc6, 0x871c, 0x8b10, 0x525d, 0x535a, 0x62cd, + 0x640f, 0x64b2, 0x6734, 0x6a38, 0x6cca, 0x73c0, 0x749e, 0x7b94, + 0x7c95, 0x7e1b, 0x818a, 0x8236, 0x8584, 0x8feb, 0x96f9, 0x99c1, + 0x4f34, 0x534a, 0x53cd, 0x53db, 0x62cc, 0x642c, 0x6500, 0x6591, + 0x69c3, 0x6cee, 0x6f58, 0x73ed, 0x7554, 0x7622, 0x76e4, 0x76fc, + 0x78d0, 0x78fb, 0x792c, 0x7d46, 0x822c, 0x87e0, 0x8fd4, 0x9812, + 0x98ef, 0x52c3, 0x62d4, 0x64a5, 0x6e24, 0x6f51, + /* 0x5b */ + 0x767c, 0x8dcb, 0x91b1, 0x9262, 0x9aee, 0x9b43, 0x5023, 0x508d, + 0x574a, 0x59a8, 0x5c28, 0x5e47, 0x5f77, 0x623f, 0x653e, 0x65b9, + 0x65c1, 0x6609, 0x678b, 0x699c, 0x6ec2, 0x78c5, 0x7d21, 0x80aa, + 0x8180, 0x822b, 0x82b3, 0x84a1, 0x868c, 0x8a2a, 0x8b17, 0x90a6, + 0x9632, 0x9f90, 0x500d, 0x4ff3, 0xf963, 0x57f9, 0x5f98, 0x62dc, + 0x6392, 0x676f, 0x6e43, 0x7119, 0x76c3, 0x80cc, 0x80da, 0x88f4, + 0x88f5, 0x8919, 0x8ce0, 0x8f29, 0x914d, 0x966a, 0x4f2f, 0x4f70, + 0x5e1b, 0x67cf, 0x6822, 0x767d, 0x767e, 0x9b44, 0x5e61, 0x6a0a, + 0x7169, 0x71d4, 0x756a, 0xf964, 0x7e41, 0x8543, 0x85e9, 0x98dc, + 0x4f10, 0x7b4f, 0x7f70, 0x95a5, 0x51e1, 0x5e06, 0x68b5, 0x6c3e, + 0x6c4e, 0x6cdb, 0x72af, 0x7bc4, 0x8303, 0x6cd5, 0x743a, 0x50fb, + 0x5288, 0x58c1, 0x64d8, 0x6a97, 0x74a7, 0x7656, + /* 0x5c */ + 0x78a7, 0x8617, 0x95e2, 0x9739, 0xf965, 0x535e, 0x5f01, 0x8b8a, + 0x8fa8, 0x8faf, 0x908a, 0x5225, 0x77a5, 0x9c49, 0x9f08, 0x4e19, + 0x5002, 0x5175, 0x5c5b, 0x5e77, 0x661e, 0x663a, 0x67c4, 0x68c5, + 0x70b3, 0x7501, 0x75c5, 0x79c9, 0x7add, 0x8f27, 0x9920, 0x9a08, + 0x4fdd, 0x5821, 0x5831, 0x5bf6, 0x666e, 0x6b65, 0x6d11, 0x6e7a, + 0x6f7d, 0x73e4, 0x752b, 0x83e9, 0x88dc, 0x8913, 0x8b5c, 0x8f14, + 0x4f0f, 0x50d5, 0x5310, 0x535c, 0x5b93, 0x5fa9, 0x670d, 0x798f, + 0x8179, 0x832f, 0x8514, 0x8907, 0x8986, 0x8f39, 0x8f3b, 0x99a5, + 0x9c12, 0x672c, 0x4e76, 0x4ff8, 0x5949, 0x5c01, 0x5cef, 0x5cf0, + 0x6367, 0x68d2, 0x70fd, 0x71a2, 0x742b, 0x7e2b, 0x84ec, 0x8702, + 0x9022, 0x92d2, 0x9cf3, 0x4e0d, 0x4ed8, 0x4fef, 0x5085, 0x5256, + 0x526f, 0x5426, 0x5490, 0x57e0, 0x592b, 0x5a66, + /* 0x5d */ + 0x5b5a, 0x5b75, 0x5bcc, 0x5e9c, 0xf966, 0x6276, 0x6577, 0x65a7, + 0x6d6e, 0x6ea5, 0x7236, 0x7b26, 0x7c3f, 0x7f36, 0x8150, 0x8151, + 0x819a, 0x8240, 0x8299, 0x83a9, 0x8a03, 0x8ca0, 0x8ce6, 0x8cfb, + 0x8d74, 0x8dba, 0x90e8, 0x91dc, 0x961c, 0x9644, 0x99d9, 0x9ce7, + 0x5317, 0x5206, 0x5429, 0x5674, 0x58b3, 0x5954, 0x596e, 0x5fff, + 0x61a4, 0x626e, 0x6610, 0x6c7e, 0x711a, 0x76c6, 0x7c89, 0x7cde, + 0x7d1b, 0x82ac, 0x8cc1, 0x96f0, 0xf967, 0x4f5b, 0x5f17, 0x5f7f, + 0x62c2, 0x5d29, 0x670b, 0x68da, 0x787c, 0x7e43, 0x9d6c, 0x4e15, + 0x5099, 0x5315, 0x532a, 0x5351, 0x5983, 0x5a62, 0x5e87, 0x60b2, + 0x618a, 0x6249, 0x6279, 0x6590, 0x6787, 0x69a7, 0x6bd4, 0x6bd6, + 0x6bd7, 0x6bd8, 0x6cb8, 0xf968, 0x7435, 0x75fa, 0x7812, 0x7891, + 0x79d5, 0x79d8, 0x7c83, 0x7dcb, 0x7fe1, 0x80a5, + /* 0x5e */ + 0x813e, 0x81c2, 0x83f2, 0x871a, 0x88e8, 0x8ab9, 0x8b6c, 0x8cbb, + 0x9119, 0x975e, 0x98db, 0x9f3b, 0x56ac, 0x5b2a, 0x5f6c, 0x658c, + 0x6ab3, 0x6baf, 0x6d5c, 0x6ff1, 0x7015, 0x725d, 0x73ad, 0x8ca7, + 0x8cd3, 0x983b, 0x6191, 0x6c37, 0x8058, 0x9a01, 0x4e4d, 0x4e8b, + 0x4e9b, 0x4ed5, 0x4f3a, 0x4f3c, 0x4f7f, 0x4fdf, 0x50ff, 0x53f2, + 0x53f8, 0x5506, 0x55e3, 0x56db, 0x58eb, 0x5962, 0x5a11, 0x5beb, + 0x5bfa, 0x5c04, 0x5df3, 0x5e2b, 0x5f99, 0x601d, 0x6368, 0x659c, + 0x65af, 0x67f6, 0x67fb, 0x68ad, 0x6b7b, 0x6c99, 0x6cd7, 0x6e23, + 0x7009, 0x7345, 0x7802, 0x793e, 0x7940, 0x7960, 0x79c1, 0x7be9, + 0x7d17, 0x7d72, 0x8086, 0x820d, 0x838e, 0x84d1, 0x86c7, 0x88df, + 0x8a50, 0x8a5e, 0x8b1d, 0x8cdc, 0x8d66, 0x8fad, 0x90aa, 0x98fc, + 0x99df, 0x9e9d, 0x524a, 0xf969, 0x6714, 0xf96a, + /* 0x5f */ + 0x5098, 0x522a, 0x5c71, 0x6563, 0x6c55, 0x73ca, 0x7523, 0x759d, + 0x7b97, 0x849c, 0x9178, 0x9730, 0x4e77, 0x6492, 0x6bba, 0x715e, + 0x85a9, 0x4e09, 0xf96b, 0x6749, 0x68ee, 0x6e17, 0x829f, 0x8518, + 0x886b, 0x63f7, 0x6f81, 0x9212, 0x98af, 0x4e0a, 0x50b7, 0x50cf, + 0x511f, 0x5546, 0x55aa, 0x5617, 0x5b40, 0x5c19, 0x5ce0, 0x5e38, + 0x5e8a, 0x5ea0, 0x5ec2, 0x60f3, 0x6851, 0x6a61, 0x6e58, 0x723d, + 0x7240, 0x72c0, 0x76f8, 0x7965, 0x7bb1, 0x7fd4, 0x88f3, 0x89f4, + 0x8a73, 0x8c61, 0x8cde, 0x971c, 0x585e, 0x74bd, 0x8cfd, 0x55c7, + 0xf96c, 0x7a61, 0x7d22, 0x8272, 0x7272, 0x751f, 0x7525, 0xf96d, + 0x7b19, 0x5885, 0x58fb, 0x5dbc, 0x5e8f, 0x5eb6, 0x5f90, 0x6055, + 0x6292, 0x637f, 0x654d, 0x6691, 0x66d9, 0x66f8, 0x6816, 0x68f2, + 0x7280, 0x745e, 0x7b6e, 0x7d6e, 0x7dd6, 0x7f72, + /* 0x60 */ + 0x80e5, 0x8212, 0x85af, 0x897f, 0x8a93, 0x901d, 0x92e4, 0x9ecd, + 0x9f20, 0x5915, 0x596d, 0x5e2d, 0x60dc, 0x6614, 0x6673, 0x6790, + 0x6c50, 0x6dc5, 0x6f5f, 0x77f3, 0x78a9, 0x84c6, 0x91cb, 0x932b, + 0x4ed9, 0x50ca, 0x5148, 0x5584, 0x5b0b, 0x5ba3, 0x6247, 0x657e, + 0x65cb, 0x6e32, 0x717d, 0x7401, 0x7444, 0x7487, 0x74bf, 0x766c, + 0x79aa, 0x7dda, 0x7e55, 0x7fa8, 0x817a, 0x81b3, 0x8239, 0x861a, + 0x87ec, 0x8a75, 0x8de3, 0x9078, 0x9291, 0x9425, 0x994d, 0x9bae, + 0x5368, 0x5c51, 0x6954, 0x6cc4, 0x6d29, 0x6e2b, 0x820c, 0x859b, + 0x893b, 0x8a2d, 0x8aaa, 0x96ea, 0x9f67, 0x5261, 0x66b9, 0x6bb2, + 0x7e96, 0x87fe, 0x8d0d, 0x9583, 0x965d, 0x651d, 0x6d89, 0x71ee, + 0xf96e, 0x57ce, 0x59d3, 0x5bac, 0x6027, 0x60fa, 0x6210, 0x661f, + 0x665f, 0x7329, 0x73f9, 0x76db, 0x7701, 0x7b6c, + /* 0x61 */ + 0x8056, 0x8072, 0x8165, 0x8aa0, 0x9192, 0x4e16, 0x52e2, 0x6b72, + 0x6d17, 0x7a05, 0x7b39, 0x7d30, 0xf96f, 0x8cb0, 0x53ec, 0x562f, + 0x5851, 0x5bb5, 0x5c0f, 0x5c11, 0x5de2, 0x6240, 0x6383, 0x6414, + 0x662d, 0x68b3, 0x6cbc, 0x6d88, 0x6eaf, 0x701f, 0x70a4, 0x71d2, + 0x7526, 0x758f, 0x758e, 0x7619, 0x7b11, 0x7be0, 0x7c2b, 0x7d20, + 0x7d39, 0x852c, 0x856d, 0x8607, 0x8a34, 0x900d, 0x9061, 0x90b5, + 0x92b7, 0x97f6, 0x9a37, 0x4fd7, 0x5c6c, 0x675f, 0x6d91, 0x7c9f, + 0x7e8c, 0x8b16, 0x8d16, 0x901f, 0x5b6b, 0x5dfd, 0x640d, 0x84c0, + 0x905c, 0x98e1, 0x7387, 0x5b8b, 0x609a, 0x677e, 0x6dde, 0x8a1f, + 0x8aa6, 0x9001, 0x980c, 0x5237, 0xf970, 0x7051, 0x788e, 0x9396, + 0x8870, 0x91d7, 0x4fee, 0x53d7, 0x55fd, 0x56da, 0x5782, 0x58fd, + 0x5ac2, 0x5b88, 0x5cab, 0x5cc0, 0x5e25, 0x6101, + /* 0x62 */ + 0x620d, 0x624b, 0x6388, 0x641c, 0x6536, 0x6578, 0x6a39, 0x6b8a, + 0x6c34, 0x6d19, 0x6f31, 0x71e7, 0x72e9, 0x7378, 0x7407, 0x74b2, + 0x7626, 0x7761, 0x79c0, 0x7a57, 0x7aea, 0x7cb9, 0x7d8f, 0x7dac, + 0x7e61, 0x7f9e, 0x8129, 0x8331, 0x8490, 0x84da, 0x85ea, 0x8896, + 0x8ab0, 0x8b90, 0x8f38, 0x9042, 0x9083, 0x916c, 0x9296, 0x92b9, + 0x968b, 0x96a7, 0x96a8, 0x96d6, 0x9700, 0x9808, 0x9996, 0x9ad3, + 0x9b1a, 0x53d4, 0x587e, 0x5919, 0x5b70, 0x5bbf, 0x6dd1, 0x6f5a, + 0x719f, 0x7421, 0x74b9, 0x8085, 0x83fd, 0x5de1, 0x5f87, 0x5faa, + 0x6042, 0x65ec, 0x6812, 0x696f, 0x6a53, 0x6b89, 0x6d35, 0x6df3, + 0x73e3, 0x76fe, 0x77ac, 0x7b4d, 0x7d14, 0x8123, 0x821c, 0x8340, + 0x84f4, 0x8563, 0x8a62, 0x8ac4, 0x9187, 0x931e, 0x9806, 0x99b4, + 0x620c, 0x8853, 0x8ff0, 0x9265, 0x5d07, 0x5d27, + /* 0x63 */ + 0x5d69, 0x745f, 0x819d, 0x8768, 0x6fd5, 0x62fe, 0x7fd2, 0x8936, + 0x8972, 0x4e1e, 0x4e58, 0x50e7, 0x52dd, 0x5347, 0x627f, 0x6607, + 0x7e69, 0x8805, 0x965e, 0x4f8d, 0x5319, 0x5636, 0x59cb, 0x5aa4, + 0x5c38, 0x5c4e, 0x5c4d, 0x5e02, 0x5f11, 0x6043, 0x65bd, 0x662f, + 0x6642, 0x67be, 0x67f4, 0x731c, 0x77e2, 0x793a, 0x7fc5, 0x8494, + 0x84cd, 0x8996, 0x8a66, 0x8a69, 0x8ae1, 0x8c55, 0x8c7a, 0x57f4, + 0x5bd4, 0x5f0f, 0x606f, 0x62ed, 0x690d, 0x6b96, 0x6e5c, 0x7184, + 0x7bd2, 0x8755, 0x8b58, 0x8efe, 0x98df, 0x98fe, 0x4f38, 0x4f81, + 0x4fe1, 0x547b, 0x5a20, 0x5bb8, 0x613c, 0x65b0, 0x6668, 0x71fc, + 0x7533, 0x795e, 0x7d33, 0x814e, 0x81e3, 0x8398, 0x85aa, 0x85ce, + 0x8703, 0x8a0a, 0x8eab, 0x8f9b, 0xf971, 0x8fc5, 0x5931, 0x5ba4, + 0x5be6, 0x6089, 0x5be9, 0x5c0b, 0x5fc3, 0x6c81, + /* 0x64 */ + 0xf972, 0x6df1, 0x700b, 0x751a, 0x82af, 0x8af6, 0x4ec0, 0x5341, + 0xf973, 0x96d9, 0x6c0f, 0x4e9e, 0x4fc4, 0x5152, 0x555e, 0x5a25, + 0x5ce8, 0x6211, 0x7259, 0x82bd, 0x83aa, 0x86fe, 0x8859, 0x8a1d, + 0x963f, 0x96c5, 0x9913, 0x9d09, 0x9d5d, 0x580a, 0x5cb3, 0x5dbd, + 0x5e44, 0x60e1, 0x6115, 0x63e1, 0x6a02, 0x6e25, 0x9102, 0x9354, + 0x984e, 0x9c10, 0x9f77, 0x5b89, 0x5cb8, 0x6309, 0x664f, 0x6848, + 0x773c, 0x96c1, 0x978d, 0x9854, 0x9b9f, 0x65a1, 0x8b01, 0x8ecb, + 0x95bc, 0x5535, 0x5ca9, 0x5dd6, 0x5eb5, 0x6697, 0x764c, 0x83f4, + 0x95c7, 0x58d3, 0x62bc, 0x72ce, 0x9d28, 0x4ef0, 0x592e, 0x600f, + 0x663b, 0x6b83, 0x79e7, 0x9d26, 0x5393, 0x54c0, 0x57c3, 0x5d16, + 0x611b, 0x66d6, 0x6daf, 0x788d, 0x827e, 0x9698, 0x9744, 0x5384, + 0x627c, 0x6396, 0x6db2, 0x7e0a, 0x814b, 0x984d, + /* 0x65 */ + 0x6afb, 0x7f4c, 0x9daf, 0x9e1a, 0x4e5f, 0x503b, 0x51b6, 0x591c, + 0x60f9, 0x63f6, 0x6930, 0x723a, 0x8036, 0xf974, 0x91ce, 0x5f31, + 0xf975, 0xf976, 0x7d04, 0x82e5, 0x846f, 0x84bb, 0x85e5, 0x8e8d, + 0xf977, 0x4f6f, 0xf978, 0xf979, 0x58e4, 0x5b43, 0x6059, 0x63da, + 0x6518, 0x656d, 0x6698, 0xf97a, 0x694a, 0x6a23, 0x6d0b, 0x7001, + 0x716c, 0x75d2, 0x760d, 0x79b3, 0x7a70, 0xf97b, 0x7f8a, 0xf97c, + 0x8944, 0xf97d, 0x8b93, 0x91c0, 0x967d, 0xf97e, 0x990a, 0x5704, + 0x5fa1, 0x65bc, 0x6f01, 0x7600, 0x79a6, 0x8a9e, 0x99ad, 0x9b5a, + 0x9f6c, 0x5104, 0x61b6, 0x6291, 0x6a8d, 0x81c6, 0x5043, 0x5830, + 0x5f66, 0x7109, 0x8a00, 0x8afa, 0x5b7c, 0x8616, 0x4ffa, 0x513c, + 0x56b4, 0x5944, 0x63a9, 0x6df9, 0x5daa, 0x696d, 0x5186, 0x4e88, + 0x4f59, 0xf97f, 0xf980, 0xf981, 0x5982, 0xf982, + /* 0x66 */ + 0xf983, 0x6b5f, 0x6c5d, 0xf984, 0x74b5, 0x7916, 0xf985, 0x8207, + 0x8245, 0x8339, 0x8f3f, 0x8f5d, 0xf986, 0x9918, 0xf987, 0xf988, + 0xf989, 0x4ea6, 0xf98a, 0x57df, 0x5f79, 0x6613, 0xf98b, 0xf98c, + 0x75ab, 0x7e79, 0x8b6f, 0xf98d, 0x9006, 0x9a5b, 0x56a5, 0x5827, + 0x59f8, 0x5a1f, 0x5bb4, 0xf98e, 0x5ef6, 0xf98f, 0xf990, 0x6350, + 0x633b, 0xf991, 0x693d, 0x6c87, 0x6cbf, 0x6d8e, 0x6d93, 0x6df5, + 0x6f14, 0xf992, 0x70df, 0x7136, 0x7159, 0xf993, 0x71c3, 0x71d5, + 0xf994, 0x784f, 0x786f, 0xf995, 0x7b75, 0x7de3, 0xf996, 0x7e2f, + 0xf997, 0x884d, 0x8edf, 0xf998, 0xf999, 0xf99a, 0x925b, 0xf99b, + 0x9cf6, 0xf99c, 0xf99d, 0xf99e, 0x6085, 0x6d85, 0xf99f, 0x71b1, + 0xf9a0, 0xf9a1, 0x95b1, 0x53ad, 0xf9a2, 0xf9a3, 0xf9a4, 0x67d3, + 0xf9a5, 0x708e, 0x7130, 0x7430, 0x8276, 0x82d2, + /* 0x67 */ + 0xf9a6, 0x95bb, 0x9ae5, 0x9e7d, 0x66c4, 0xf9a7, 0x71c1, 0x8449, + 0xf9a8, 0xf9a9, 0x584b, 0xf9aa, 0xf9ab, 0x5db8, 0x5f71, 0xf9ac, + 0x6620, 0x668e, 0x6979, 0x69ae, 0x6c38, 0x6cf3, 0x6e36, 0x6f41, + 0x6fda, 0x701b, 0x702f, 0x7150, 0x71df, 0x7370, 0xf9ad, 0x745b, + 0xf9ae, 0x74d4, 0x76c8, 0x7a4e, 0x7e93, 0xf9af, 0xf9b0, 0x82f1, + 0x8a60, 0x8fce, 0xf9b1, 0x9348, 0xf9b2, 0x9719, 0xf9b3, 0xf9b4, + 0x4e42, 0x502a, 0xf9b5, 0x5208, 0x53e1, 0x66f3, 0x6c6d, 0x6fca, + 0x730a, 0x777f, 0x7a62, 0x82ae, 0x85dd, 0x8602, 0xf9b6, 0x88d4, + 0x8a63, 0x8b7d, 0x8c6b, 0xf9b7, 0x92b3, 0xf9b8, 0x9713, 0x9810, + 0x4e94, 0x4f0d, 0x4fc9, 0x50b2, 0x5348, 0x543e, 0x5433, 0x55da, + 0x5862, 0x58ba, 0x5967, 0x5a1b, 0x5be4, 0x609f, 0xf9b9, 0x61ca, + 0x6556, 0x65ff, 0x6664, 0x68a7, 0x6c5a, 0x6fb3, + /* 0x68 */ + 0x70cf, 0x71ac, 0x7352, 0x7b7d, 0x8708, 0x8aa4, 0x9c32, 0x9f07, + 0x5c4b, 0x6c83, 0x7344, 0x7389, 0x923a, 0x6eab, 0x7465, 0x761f, + 0x7a69, 0x7e15, 0x860a, 0x5140, 0x58c5, 0x64c1, 0x74ee, 0x7515, + 0x7670, 0x7fc1, 0x9095, 0x96cd, 0x9954, 0x6e26, 0x74e6, 0x7aa9, + 0x7aaa, 0x81e5, 0x86d9, 0x8778, 0x8a1b, 0x5a49, 0x5b8c, 0x5b9b, + 0x68a1, 0x6900, 0x6d63, 0x73a9, 0x7413, 0x742c, 0x7897, 0x7de9, + 0x7feb, 0x8118, 0x8155, 0x839e, 0x8c4c, 0x962e, 0x9811, 0x66f0, + 0x5f80, 0x65fa, 0x6789, 0x6c6a, 0x738b, 0x502d, 0x5a03, 0x6b6a, + 0x77ee, 0x5916, 0x5d6c, 0x5dcd, 0x7325, 0x754f, 0xf9ba, 0xf9bb, + 0x50e5, 0x51f9, 0x582f, 0x592d, 0x5996, 0x59da, 0x5be5, 0xf9bc, + 0xf9bd, 0x5da2, 0x62d7, 0x6416, 0x6493, 0x64fe, 0xf9be, 0x66dc, + 0xf9bf, 0x6a48, 0xf9c0, 0x71ff, 0x7464, 0xf9c1, + /* 0x69 */ + 0x7a88, 0x7aaf, 0x7e47, 0x7e5e, 0x8000, 0x8170, 0xf9c2, 0x87ef, + 0x8981, 0x8b20, 0x9059, 0xf9c3, 0x9080, 0x9952, 0x617e, 0x6b32, + 0x6d74, 0x7e1f, 0x8925, 0x8fb1, 0x4fd1, 0x50ad, 0x5197, 0x52c7, + 0x57c7, 0x5889, 0x5bb9, 0x5eb8, 0x6142, 0x6995, 0x6d8c, 0x6e67, + 0x6eb6, 0x7194, 0x7462, 0x7528, 0x752c, 0x8073, 0x8338, 0x84c9, + 0x8e0a, 0x9394, 0x93de, 0xf9c4, 0x4e8e, 0x4f51, 0x5076, 0x512a, + 0x53c8, 0x53cb, 0x53f3, 0x5b87, 0x5bd3, 0x5c24, 0x611a, 0x6182, + 0x65f4, 0x725b, 0x7397, 0x7440, 0x76c2, 0x7950, 0x7991, 0x79b9, + 0x7d06, 0x7fbd, 0x828b, 0x85d5, 0x865e, 0x8fc2, 0x9047, 0x90f5, + 0x91ea, 0x9685, 0x96e8, 0x96e9, 0x52d6, 0x5f67, 0x65ed, 0x6631, + 0x682f, 0x715c, 0x7a36, 0x90c1, 0x980a, 0x4e91, 0xf9c5, 0x6a52, + 0x6b9e, 0x6f90, 0x7189, 0x8018, 0x82b8, 0x8553, + /* 0x6a */ + 0x904b, 0x9695, 0x96f2, 0x97fb, 0x851a, 0x9b31, 0x4e90, 0x718a, + 0x96c4, 0x5143, 0x539f, 0x54e1, 0x5713, 0x5712, 0x57a3, 0x5a9b, + 0x5ac4, 0x5bc3, 0x6028, 0x613f, 0x63f4, 0x6c85, 0x6d39, 0x6e72, + 0x6e90, 0x7230, 0x733f, 0x7457, 0x82d1, 0x8881, 0x8f45, 0x9060, + 0xf9c6, 0x9662, 0x9858, 0x9d1b, 0x6708, 0x8d8a, 0x925e, 0x4f4d, + 0x5049, 0x50de, 0x5371, 0x570d, 0x59d4, 0x5a01, 0x5c09, 0x6170, + 0x6690, 0x6e2d, 0x7232, 0x744b, 0x7def, 0x80c3, 0x840e, 0x8466, + 0x853f, 0x875f, 0x885b, 0x8918, 0x8b02, 0x9055, 0x97cb, 0x9b4f, + 0x4e73, 0x4f91, 0x5112, 0x516a, 0xf9c7, 0x552f, 0x55a9, 0x5b7a, + 0x5ba5, 0x5e7c, 0x5e7d, 0x5ebe, 0x60a0, 0x60df, 0x6108, 0x6109, + 0x63c4, 0x6538, 0x6709, 0xf9c8, 0x67d4, 0x67da, 0xf9c9, 0x6961, + 0x6962, 0x6cb9, 0x6d27, 0xf9ca, 0x6e38, 0xf9cb, + /* 0x6b */ + 0x6fe1, 0x7336, 0x7337, 0xf9cc, 0x745c, 0x7531, 0xf9cd, 0x7652, + 0xf9ce, 0xf9cf, 0x7dad, 0x81fe, 0x8438, 0x88d5, 0x8a98, 0x8adb, + 0x8aed, 0x8e30, 0x8e42, 0x904a, 0x903e, 0x907a, 0x9149, 0x91c9, + 0x936e, 0xf9d0, 0xf9d1, 0x5809, 0xf9d2, 0x6bd3, 0x8089, 0x80b2, + 0xf9d3, 0xf9d4, 0x5141, 0x596b, 0x5c39, 0xf9d5, 0xf9d6, 0x6f64, + 0x73a7, 0x80e4, 0x8d07, 0xf9d7, 0x9217, 0x958f, 0xf9d8, 0xf9d9, + 0xf9da, 0xf9db, 0x807f, 0x620e, 0x701c, 0x7d68, 0x878d, 0xf9dc, + 0x57a0, 0x6069, 0x6147, 0x6bb7, 0x8abe, 0x9280, 0x96b1, 0x4e59, + 0x541f, 0x6deb, 0x852d, 0x9670, 0x97f3, 0x98ee, 0x63d6, 0x6ce3, + 0x9091, 0x51dd, 0x61c9, 0x81ba, 0x9df9, 0x4f9d, 0x501a, 0x5100, + 0x5b9c, 0x610f, 0x61ff, 0x64ec, 0x6905, 0x6bc5, 0x7591, 0x77e3, + 0x7fa9, 0x8264, 0x858f, 0x87fb, 0x8863, 0x8abc, + /* 0x6c */ + 0x8b70, 0x91ab, 0x4e8c, 0x4ee5, 0x4f0a, 0xf9dd, 0xf9de, 0x5937, + 0x59e8, 0xf9df, 0x5df2, 0x5f1b, 0x5f5b, 0x6021, 0xf9e0, 0xf9e1, + 0xf9e2, 0xf9e3, 0x723e, 0x73e5, 0xf9e4, 0x7570, 0x75cd, 0xf9e5, + 0x79fb, 0xf9e6, 0x800c, 0x8033, 0x8084, 0x82e1, 0x8351, 0xf9e7, + 0xf9e8, 0x8cbd, 0x8cb3, 0x9087, 0xf9e9, 0xf9ea, 0x98f4, 0x990c, + 0xf9eb, 0xf9ec, 0x7037, 0x76ca, 0x7fca, 0x7fcc, 0x7ffc, 0x8b1a, + 0x4eba, 0x4ec1, 0x5203, 0x5370, 0xf9ed, 0x54bd, 0x56e0, 0x59fb, + 0x5bc5, 0x5f15, 0x5fcd, 0x6e6e, 0xf9ee, 0xf9ef, 0x7d6a, 0x8335, + 0xf9f0, 0x8693, 0x8a8d, 0xf9f1, 0x976d, 0x9777, 0xf9f2, 0xf9f3, + 0x4e00, 0x4f5a, 0x4f7e, 0x58f9, 0x65e5, 0x6ea2, 0x9038, 0x93b0, + 0x99b9, 0x4efb, 0x58ec, 0x598a, 0x59d9, 0x6041, 0xf9f4, 0xf9f5, + 0x7a14, 0xf9f6, 0x834f, 0x8cc3, 0x5165, 0x5344, + /* 0x6d */ + 0xf9f7, 0xf9f8, 0xf9f9, 0x4ecd, 0x5269, 0x5b55, 0x82bf, 0x4ed4, + 0x523a, 0x54a8, 0x59c9, 0x59ff, 0x5b50, 0x5b57, 0x5b5c, 0x6063, + 0x6148, 0x6ecb, 0x7099, 0x716e, 0x7386, 0x74f7, 0x75b5, 0x78c1, + 0x7d2b, 0x8005, 0x81ea, 0x8328, 0x8517, 0x85c9, 0x8aee, 0x8cc7, + 0x96cc, 0x4f5c, 0x52fa, 0x56bc, 0x65ab, 0x6628, 0x707c, 0x70b8, + 0x7235, 0x7dbd, 0x828d, 0x914c, 0x96c0, 0x9d72, 0x5b71, 0x68e7, + 0x6b98, 0x6f7a, 0x76de, 0x5c91, 0x66ab, 0x6f5b, 0x7bb4, 0x7c2a, + 0x8836, 0x96dc, 0x4e08, 0x4ed7, 0x5320, 0x5834, 0x58bb, 0x58ef, + 0x596c, 0x5c07, 0x5e33, 0x5e84, 0x5f35, 0x638c, 0x66b2, 0x6756, + 0x6a1f, 0x6aa3, 0x6b0c, 0x6f3f, 0x7246, 0xf9fa, 0x7350, 0x748b, + 0x7ae0, 0x7ca7, 0x8178, 0x81df, 0x81e7, 0x838a, 0x846c, 0x8523, + 0x8594, 0x85cf, 0x88dd, 0x8d13, 0x91ac, 0x9577, + /* 0x6e */ + 0x969c, 0x518d, 0x54c9, 0x5728, 0x5bb0, 0x624d, 0x6750, 0x683d, + 0x6893, 0x6e3d, 0x6ed3, 0x707d, 0x7e21, 0x88c1, 0x8ca1, 0x8f09, + 0x9f4b, 0x9f4e, 0x722d, 0x7b8f, 0x8acd, 0x931a, 0x4f47, 0x4f4e, + 0x5132, 0x5480, 0x59d0, 0x5e95, 0x62b5, 0x6775, 0x696e, 0x6a17, + 0x6cae, 0x6e1a, 0x72d9, 0x732a, 0x75bd, 0x7bb8, 0x7d35, 0x82e7, + 0x83f9, 0x8457, 0x85f7, 0x8a5b, 0x8caf, 0x8e87, 0x9019, 0x90b8, + 0x96ce, 0x9f5f, 0x52e3, 0x540a, 0x5ae1, 0x5bc2, 0x6458, 0x6575, + 0x6ef4, 0x72c4, 0xf9fb, 0x7684, 0x7a4d, 0x7b1b, 0x7c4d, 0x7e3e, + 0x7fdf, 0x837b, 0x8b2b, 0x8cca, 0x8d64, 0x8de1, 0x8e5f, 0x8fea, + 0x8ff9, 0x9069, 0x93d1, 0x4f43, 0x4f7a, 0x50b3, 0x5168, 0x5178, + 0x524d, 0x526a, 0x5861, 0x587c, 0x5960, 0x5c08, 0x5c55, 0x5edb, + 0x609b, 0x6230, 0x6813, 0x6bbf, 0x6c08, 0x6fb1, + /* 0x6f */ + 0x714e, 0x7420, 0x7530, 0x7538, 0x7551, 0x7672, 0x7b4c, 0x7b8b, + 0x7bad, 0x7bc6, 0x7e8f, 0x8a6e, 0x8f3e, 0x8f49, 0x923f, 0x9293, + 0x9322, 0x942b, 0x96fb, 0x985a, 0x986b, 0x991e, 0x5207, 0x622a, + 0x6298, 0x6d59, 0x7664, 0x7aca, 0x7bc0, 0x7d76, 0x5360, 0x5cbe, + 0x5e97, 0x6f38, 0x70b9, 0x7c98, 0x9711, 0x9b8e, 0x9ede, 0x63a5, + 0x647a, 0x8776, 0x4e01, 0x4e95, 0x4ead, 0x505c, 0x5075, 0x5448, + 0x59c3, 0x5b9a, 0x5e40, 0x5ead, 0x5ef7, 0x5f81, 0x60c5, 0x633a, + 0x653f, 0x6574, 0x65cc, 0x6676, 0x6678, 0x67fe, 0x6968, 0x6a89, + 0x6b63, 0x6c40, 0x6dc0, 0x6de8, 0x6e1f, 0x6e5e, 0x701e, 0x70a1, + 0x738e, 0x73fd, 0x753a, 0x775b, 0x7887, 0x798e, 0x7a0b, 0x7a7d, + 0x7cbe, 0x7d8e, 0x8247, 0x8a02, 0x8aea, 0x8c9e, 0x912d, 0x914a, + 0x91d8, 0x9266, 0x92cc, 0x9320, 0x9706, 0x9756, + /* 0x70 */ + 0x975c, 0x9802, 0x9f0e, 0x5236, 0x5291, 0x557c, 0x5824, 0x5e1d, + 0x5f1f, 0x608c, 0x63d0, 0x68af, 0x6fdf, 0x796d, 0x7b2c, 0x81cd, + 0x85ba, 0x88fd, 0x8af8, 0x8e44, 0x918d, 0x9664, 0x969b, 0x973d, + 0x984c, 0x9f4a, 0x4fce, 0x5146, 0x51cb, 0x52a9, 0x5632, 0x5f14, + 0x5f6b, 0x63aa, 0x64cd, 0x65e9, 0x6641, 0x66fa, 0x66f9, 0x671d, + 0x689d, 0x68d7, 0x69fd, 0x6f15, 0x6f6e, 0x7167, 0x71e5, 0x722a, + 0x74aa, 0x773a, 0x7956, 0x795a, 0x79df, 0x7a20, 0x7a95, 0x7c97, + 0x7cdf, 0x7d44, 0x7e70, 0x8087, 0x85fb, 0x86a4, 0x8a54, 0x8abf, + 0x8d99, 0x8e81, 0x9020, 0x906d, 0x91e3, 0x963b, 0x96d5, 0x9ce5, + 0x65cf, 0x7c07, 0x8db3, 0x93c3, 0x5b58, 0x5c0a, 0x5352, 0x62d9, + 0x731d, 0x5027, 0x5b97, 0x5f9e, 0x60b0, 0x616b, 0x68d5, 0x6dd9, + 0x742e, 0x7a2e, 0x7d42, 0x7d9c, 0x7e31, 0x816b, + /* 0x71 */ + 0x8e2a, 0x8e35, 0x937e, 0x9418, 0x4f50, 0x5750, 0x5de6, 0x5ea7, + 0x632b, 0x7f6a, 0x4e3b, 0x4f4f, 0x4f8f, 0x505a, 0x59dd, 0x80c4, + 0x546a, 0x5468, 0x55fe, 0x594f, 0x5b99, 0x5dde, 0x5eda, 0x665d, + 0x6731, 0x67f1, 0x682a, 0x6ce8, 0x6d32, 0x6e4a, 0x6f8d, 0x70b7, + 0x73e0, 0x7587, 0x7c4c, 0x7d02, 0x7d2c, 0x7da2, 0x821f, 0x86db, + 0x8a3b, 0x8a85, 0x8d70, 0x8e8a, 0x8f33, 0x9031, 0x914e, 0x9152, + 0x9444, 0x99d0, 0x7af9, 0x7ca5, 0x4fca, 0x5101, 0x51c6, 0x57c8, + 0x5bef, 0x5cfb, 0x6659, 0x6a3d, 0x6d5a, 0x6e96, 0x6fec, 0x710c, + 0x756f, 0x7ae3, 0x8822, 0x9021, 0x9075, 0x96cb, 0x99ff, 0x8301, + 0x4e2d, 0x4ef2, 0x8846, 0x91cd, 0x537d, 0x6adb, 0x696b, 0x6c41, + 0x847a, 0x589e, 0x618e, 0x66fe, 0x62ef, 0x70dd, 0x7511, 0x75c7, + 0x7e52, 0x84b8, 0x8b49, 0x8d08, 0x4e4b, 0x53ea, + /* 0x72 */ + 0x54ab, 0x5730, 0x5740, 0x5fd7, 0x6301, 0x6307, 0x646f, 0x652f, + 0x65e8, 0x667a, 0x679d, 0x67b3, 0x6b62, 0x6c60, 0x6c9a, 0x6f2c, + 0x77e5, 0x7825, 0x7949, 0x7957, 0x7d19, 0x80a2, 0x8102, 0x81f3, + 0x829d, 0x82b7, 0x8718, 0x8a8c, 0xf9fc, 0x8d04, 0x8dbe, 0x9072, + 0x76f4, 0x7a19, 0x7a37, 0x7e54, 0x8077, 0x5507, 0x55d4, 0x5875, + 0x632f, 0x6422, 0x6649, 0x664b, 0x686d, 0x699b, 0x6b84, 0x6d25, + 0x6eb1, 0x73cd, 0x7468, 0x74a1, 0x755b, 0x75b9, 0x76e1, 0x771e, + 0x778b, 0x79e6, 0x7e09, 0x7e1d, 0x81fb, 0x852f, 0x8897, 0x8a3a, + 0x8cd1, 0x8eeb, 0x8fb0, 0x9032, 0x93ad, 0x9663, 0x9673, 0x9707, + 0x4f84, 0x53f1, 0x59ea, 0x5ac9, 0x5e19, 0x684e, 0x74c6, 0x75be, + 0x79e9, 0x7a92, 0x81a3, 0x86ed, 0x8cea, 0x8dcc, 0x8fed, 0x659f, + 0x6715, 0xf9fd, 0x57f7, 0x6f57, 0x7ddd, 0x8f2f, + /* 0x73 */ + 0x93f6, 0x96c6, 0x5fb5, 0x61f2, 0x6f84, 0x4e14, 0x4f98, 0x501f, + 0x53c9, 0x55df, 0x5d6f, 0x5dee, 0x6b21, 0x6b64, 0x78cb, 0x7b9a, + 0xf9fe, 0x8e49, 0x8eca, 0x906e, 0x6349, 0x643e, 0x7740, 0x7a84, + 0x932f, 0x947f, 0x9f6a, 0x64b0, 0x6faf, 0x71e6, 0x74a8, 0x74da, + 0x7ac4, 0x7c12, 0x7e82, 0x7cb2, 0x7e98, 0x8b9a, 0x8d0a, 0x947d, + 0x9910, 0x994c, 0x5239, 0x5bdf, 0x64e6, 0x672d, 0x7d2e, 0x50ed, + 0x53c3, 0x5879, 0x6158, 0x6159, 0x61fa, 0x65ac, 0x7ad9, 0x8b92, + 0x8b96, 0x5009, 0x5021, 0x5275, 0x5531, 0x5a3c, 0x5ee0, 0x5f70, + 0x6134, 0x655e, 0x660c, 0x6636, 0x66a2, 0x69cd, 0x6ec4, 0x6f32, + 0x7316, 0x7621, 0x7a93, 0x8139, 0x8259, 0x83d6, 0x84bc, 0x50b5, + 0x57f0, 0x5bc0, 0x5be8, 0x5f69, 0x63a1, 0x7826, 0x7db5, 0x83dc, + 0x8521, 0x91c7, 0x91f5, 0x518a, 0x67f5, 0x7b56, + /* 0x74 */ + 0x8cac, 0x51c4, 0x59bb, 0x60bd, 0x8655, 0x501c, 0xf9ff, 0x5254, + 0x5c3a, 0x617d, 0x621a, 0x62d3, 0x64f2, 0x65a5, 0x6ecc, 0x7620, + 0x810a, 0x8e60, 0x965f, 0x96bb, 0x4edf, 0x5343, 0x5598, 0x5929, + 0x5ddd, 0x64c5, 0x6cc9, 0x6dfa, 0x7394, 0x7a7f, 0x821b, 0x85a6, + 0x8ce4, 0x8e10, 0x9077, 0x91e7, 0x95e1, 0x9621, 0x97c6, 0x51f8, + 0x54f2, 0x5586, 0x5fb9, 0x64a4, 0x6f88, 0x7db4, 0x8f1f, 0x8f4d, + 0x9435, 0x50c9, 0x5c16, 0x6cbe, 0x6dfb, 0x751b, 0x77bb, 0x7c3d, + 0x7c64, 0x8a79, 0x8ac2, 0x581e, 0x59be, 0x5e16, 0x6377, 0x7252, + 0x758a, 0x776b, 0x8adc, 0x8cbc, 0x8f12, 0x5ef3, 0x6674, 0x6df8, + 0x807d, 0x83c1, 0x8acb, 0x9751, 0x9bd6, 0xfa00, 0x5243, 0x66ff, + 0x6d95, 0x6eef, 0x7de0, 0x8ae6, 0x902e, 0x905e, 0x9ad4, 0x521d, + 0x527f, 0x54e8, 0x6194, 0x6284, 0x62db, 0x68a2, + /* 0x75 */ + 0x6912, 0x695a, 0x6a35, 0x7092, 0x7126, 0x785d, 0x7901, 0x790e, + 0x79d2, 0x7a0d, 0x8096, 0x8278, 0x82d5, 0x8349, 0x8549, 0x8c82, + 0x8d85, 0x9162, 0x918b, 0x91ae, 0x4fc3, 0x56d1, 0x71ed, 0x77d7, + 0x8700, 0x89f8, 0x5bf8, 0x5fd6, 0x6751, 0x90a8, 0x53e2, 0x585a, + 0x5bf5, 0x60a4, 0x6181, 0x6460, 0x7e3d, 0x8070, 0x8525, 0x9283, + 0x64ae, 0x50ac, 0x5d14, 0x6700, 0x589c, 0x62bd, 0x63a8, 0x690e, + 0x6978, 0x6a1e, 0x6e6b, 0x76ba, 0x79cb, 0x82bb, 0x8429, 0x8acf, + 0x8da8, 0x8ffd, 0x9112, 0x914b, 0x919c, 0x9310, 0x9318, 0x939a, + 0x96db, 0x9a36, 0x9c0d, 0x4e11, 0x755c, 0x795d, 0x7afa, 0x7b51, + 0x7bc9, 0x7e2e, 0x84c4, 0x8e59, 0x8e74, 0x8ef8, 0x9010, 0x6625, + 0x693f, 0x7443, 0x51fa, 0x672e, 0x9edc, 0x5145, 0x5fe0, 0x6c96, + 0x87f2, 0x885d, 0x8877, 0x60b4, 0x81b5, 0x8403, + /* 0x76 */ + 0x8d05, 0x53d6, 0x5439, 0x5634, 0x5a36, 0x5c31, 0x708a, 0x7fe0, + 0x805a, 0x8106, 0x81ed, 0x8da3, 0x9189, 0x9a5f, 0x9df2, 0x5074, + 0x4ec4, 0x53a0, 0x60fb, 0x6e2c, 0x5c64, 0x4f88, 0x5024, 0x55e4, + 0x5cd9, 0x5e5f, 0x6065, 0x6894, 0x6cbb, 0x6dc4, 0x71be, 0x75d4, + 0x75f4, 0x7661, 0x7a1a, 0x7a49, 0x7dc7, 0x7dfb, 0x7f6e, 0x81f4, + 0x86a9, 0x8f1c, 0x96c9, 0x99b3, 0x9f52, 0x5247, 0x52c5, 0x98ed, + 0x89aa, 0x4e03, 0x67d2, 0x6f06, 0x4fb5, 0x5be2, 0x6795, 0x6c88, + 0x6d78, 0x741b, 0x7827, 0x91dd, 0x937c, 0x87c4, 0x79e4, 0x7a31, + 0x5feb, 0x4ed6, 0x54a4, 0x553e, 0x58ae, 0x59a5, 0x60f0, 0x6253, + 0x62d6, 0x6736, 0x6955, 0x8235, 0x9640, 0x99b1, 0x99dd, 0x502c, + 0x5353, 0x5544, 0x577c, 0xfa01, 0x6258, 0xfa02, 0x64e2, 0x666b, + 0x67dd, 0x6fc1, 0x6fef, 0x7422, 0x7438, 0x8a17, + /* 0x77 */ + 0x9438, 0x5451, 0x5606, 0x5766, 0x5f48, 0x619a, 0x6b4e, 0x7058, + 0x70ad, 0x7dbb, 0x8a95, 0x596a, 0x812b, 0x63a2, 0x7708, 0x803d, + 0x8caa, 0x5854, 0x642d, 0x69bb, 0x5b95, 0x5e11, 0x6e6f, 0xfa03, + 0x8569, 0x514c, 0x53f0, 0x592a, 0x6020, 0x614b, 0x6b86, 0x6c70, + 0x6cf0, 0x7b1e, 0x80ce, 0x82d4, 0x8dc6, 0x90b0, 0x98b1, 0xfa04, + 0x64c7, 0x6fa4, 0x6491, 0x6504, 0x514e, 0x5410, 0x571f, 0x8a0e, + 0x615f, 0x6876, 0xfa05, 0x75db, 0x7b52, 0x7d71, 0x901a, 0x5806, + 0x69cc, 0x817f, 0x892a, 0x9000, 0x9839, 0x5078, 0x5957, 0x59ac, + 0x6295, 0x900f, 0x9b2a, 0x615d, 0x7279, 0x95d6, 0x5761, 0x5a46, + 0x5df4, 0x628a, 0x64ad, 0x64fa, 0x6777, 0x6ce2, 0x6d3e, 0x722c, + 0x7436, 0x7834, 0x7f77, 0x82ad, 0x8ddb, 0x9817, 0x5224, 0x5742, + 0x677f, 0x7248, 0x74e3, 0x8ca9, 0x8fa6, 0x9211, + /* 0x78 */ + 0x962a, 0x516b, 0x53ed, 0x634c, 0x4f69, 0x5504, 0x6096, 0x6557, + 0x6c9b, 0x6d7f, 0x724c, 0x72fd, 0x7a17, 0x8987, 0x8c9d, 0x5f6d, + 0x6f8e, 0x70f9, 0x81a8, 0x610e, 0x4fbf, 0x504f, 0x6241, 0x7247, + 0x7bc7, 0x7de8, 0x7fe9, 0x904d, 0x97ad, 0x9a19, 0x8cb6, 0x576a, + 0x5e73, 0x67b0, 0x840d, 0x8a55, 0x5420, 0x5b16, 0x5e63, 0x5ee2, + 0x5f0a, 0x6583, 0x80ba, 0x853d, 0x9589, 0x965b, 0x4f48, 0x5305, + 0x530d, 0x530f, 0x5486, 0x54fa, 0x5703, 0x5e03, 0x6016, 0x629b, + 0x62b1, 0x6355, 0xfa06, 0x6ce1, 0x6d66, 0x75b1, 0x7832, 0x80de, + 0x812f, 0x82de, 0x8461, 0x84b2, 0x888d, 0x8912, 0x900b, 0x92ea, + 0x98fd, 0x9b91, 0x5e45, 0x66b4, 0x66dd, 0x7011, 0x7206, 0xfa07, + 0x4ff5, 0x527d, 0x5f6a, 0x6153, 0x6753, 0x6a19, 0x6f02, 0x74e2, + 0x7968, 0x8868, 0x8c79, 0x98c7, 0x98c4, 0x9a43, + /* 0x79 */ + 0x54c1, 0x7a1f, 0x6953, 0x8af7, 0x8c4a, 0x98a8, 0x99ae, 0x5f7c, + 0x62ab, 0x75b2, 0x76ae, 0x88ab, 0x907f, 0x9642, 0x5339, 0x5f3c, + 0x5fc5, 0x6ccc, 0x73cc, 0x7562, 0x758b, 0x7b46, 0x82fe, 0x999d, + 0x4e4f, 0x903c, 0x4e0b, 0x4f55, 0x53a6, 0x590f, 0x5ec8, 0x6630, + 0x6cb3, 0x7455, 0x8377, 0x8766, 0x8cc0, 0x9050, 0x971e, 0x9c15, + 0x58d1, 0x5b78, 0x8650, 0x8b14, 0x9db4, 0x5bd2, 0x6068, 0x608d, + 0x65f1, 0x6c57, 0x6f22, 0x6fa3, 0x701a, 0x7f55, 0x7ff0, 0x9591, + 0x9592, 0x9650, 0x97d3, 0x5272, 0x8f44, 0x51fd, 0x542b, 0x54b8, + 0x5563, 0x558a, 0x6abb, 0x6db5, 0x7dd8, 0x8266, 0x929c, 0x9677, + 0x9e79, 0x5408, 0x54c8, 0x76d2, 0x86e4, 0x95a4, 0x95d4, 0x965c, + 0x4ea2, 0x4f09, 0x59ee, 0x5ae6, 0x5df7, 0x6052, 0x6297, 0x676d, + 0x6841, 0x6c86, 0x6e2f, 0x7f38, 0x809b, 0x822a, + /* 0x7a */ + 0xfa08, 0xfa09, 0x9805, 0x4ea5, 0x5055, 0x54b3, 0x5793, 0x595a, + 0x5b69, 0x5bb3, 0x61c8, 0x6977, 0x6d77, 0x7023, 0x87f9, 0x89e3, + 0x8a72, 0x8ae7, 0x9082, 0x99ed, 0x9ab8, 0x52be, 0x6838, 0x5016, + 0x5e78, 0x674f, 0x8347, 0x884c, 0x4eab, 0x5411, 0x56ae, 0x73e6, + 0x9115, 0x97ff, 0x9909, 0x9957, 0x9999, 0x5653, 0x589f, 0x865b, + 0x8a31, 0x61b2, 0x6af6, 0x737b, 0x8ed2, 0x6b47, 0x96aa, 0x9a57, + 0x5955, 0x7200, 0x8d6b, 0x9769, 0x4fd4, 0x5cf4, 0x5f26, 0x61f8, + 0x665b, 0x6ceb, 0x70ab, 0x7384, 0x73b9, 0x73fe, 0x7729, 0x774d, + 0x7d43, 0x7d62, 0x7e23, 0x8237, 0x8852, 0xfa0a, 0x8ce2, 0x9249, + 0x986f, 0x5b51, 0x7a74, 0x8840, 0x9801, 0x5acc, 0x4fe0, 0x5354, + 0x593e, 0x5cfd, 0x633e, 0x6d79, 0x72f9, 0x8105, 0x8107, 0x83a2, + 0x92cf, 0x9830, 0x4ea8, 0x5144, 0x5211, 0x578b, + /* 0x7b */ + 0x5f62, 0x6cc2, 0x6ece, 0x7005, 0x7050, 0x70af, 0x7192, 0x73e9, + 0x7469, 0x834a, 0x87a2, 0x8861, 0x9008, 0x90a2, 0x93a3, 0x99a8, + 0x516e, 0x5f57, 0x60e0, 0x6167, 0x66b3, 0x8559, 0x8e4a, 0x91af, + 0x978b, 0x4e4e, 0x4e92, 0x547c, 0x58d5, 0x58fa, 0x597d, 0x5cb5, + 0x5f27, 0x6236, 0x6248, 0x660a, 0x6667, 0x6beb, 0x6d69, 0x6dcf, + 0x6e56, 0x6ef8, 0x6f94, 0x6fe0, 0x6fe9, 0x705d, 0x72d0, 0x7425, + 0x745a, 0x74e0, 0x7693, 0x795c, 0x7cca, 0x7e1e, 0x80e1, 0x82a6, + 0x846b, 0x84bf, 0x864e, 0x865f, 0x8774, 0x8b77, 0x8c6a, 0x93ac, + 0x9800, 0x9865, 0x60d1, 0x6216, 0x9177, 0x5a5a, 0x660f, 0x6df7, + 0x6e3e, 0x743f, 0x9b42, 0x5ffd, 0x60da, 0x7b0f, 0x54c4, 0x5f18, + 0x6c5e, 0x6cd3, 0x6d2a, 0x70d8, 0x7d05, 0x8679, 0x8a0c, 0x9d3b, + 0x5316, 0x548c, 0x5b05, 0x6a3a, 0x706b, 0x7575, + /* 0x7c */ + 0x798d, 0x79be, 0x82b1, 0x83ef, 0x8a71, 0x8b41, 0x8ca8, 0x9774, + 0xfa0b, 0x64f4, 0x652b, 0x78ba, 0x78bb, 0x7a6b, 0x4e38, 0x559a, + 0x5950, 0x5ba6, 0x5e7b, 0x60a3, 0x63db, 0x6b61, 0x6665, 0x6853, + 0x6e19, 0x7165, 0x74b0, 0x7d08, 0x9084, 0x9a69, 0x9c25, 0x6d3b, + 0x6ed1, 0x733e, 0x8c41, 0x95ca, 0x51f0, 0x5e4c, 0x5fa8, 0x604d, + 0x60f6, 0x6130, 0x614c, 0x6643, 0x6644, 0x69a5, 0x6cc1, 0x6e5f, + 0x6ec9, 0x6f62, 0x714c, 0x749c, 0x7687, 0x7bc1, 0x7c27, 0x8352, + 0x8757, 0x9051, 0x968d, 0x9ec3, 0x532f, 0x56de, 0x5efb, 0x5f8a, + 0x6062, 0x6094, 0x61f7, 0x6666, 0x6703, 0x6a9c, 0x6dee, 0x6fae, + 0x7070, 0x736a, 0x7e6a, 0x81be, 0x8334, 0x86d4, 0x8aa8, 0x8cc4, + 0x5283, 0x7372, 0x5b96, 0x6a6b, 0x9404, 0x54ee, 0x5686, 0x5b5d, + 0x6548, 0x6585, 0x66c9, 0x689f, 0x6d8d, 0x6dc6, + /* 0x7d */ + 0x723b, 0x80b4, 0x9175, 0x9a4d, 0x4faf, 0x5019, 0x539a, 0x540e, + 0x543c, 0x5589, 0x55c5, 0x5e3f, 0x5f8c, 0x673d, 0x7166, 0x73dd, + 0x9005, 0x52db, 0x52f3, 0x5864, 0x58ce, 0x7104, 0x718f, 0x71fb, + 0x85b0, 0x8a13, 0x6688, 0x85a8, 0x55a7, 0x6684, 0x714a, 0x8431, + 0x5349, 0x5599, 0x6bc1, 0x5f59, 0x5fbd, 0x63ee, 0x6689, 0x7147, + 0x8af1, 0x8f1d, 0x9ebe, 0x4f11, 0x643a, 0x70cb, 0x7566, 0x8667, + 0x6064, 0x8b4e, 0x9df8, 0x5147, 0x51f6, 0x5308, 0x6d36, 0x80f8, + 0x9ed1, 0x6615, 0x6b23, 0x7098, 0x75d5, 0x5403, 0x5c79, 0x7d07, + 0x8a16, 0x6b20, 0x6b3d, 0x6b46, 0x5438, 0x6070, 0x6d3d, 0x7fd5, + 0x8208, 0x50d6, 0x51de, 0x559c, 0x566b, 0x56cd, 0x59ec, 0x5b09, + 0x5e0c, 0x6199, 0x6198, 0x6231, 0x665e, 0x66e6, 0x7199, 0x71b9, + 0x71ba, 0x72a7, 0x79a7, 0x7a00, 0x7fb2, 0x8a70, +}; + +static int +ksc5601_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c1 = (s[0] & 0x7F); + if ((c1 >= 0x21 && c1 <= 0x2c) || (c1 >= 0x30 && c1 <= 0x48) || (c1 >= 0x4a && c1 <= 0x7d)) { + if (n >= 2) { + unsigned char c2 = (s[1] & 0x7F); + if (c2 >= 0x21 && c2 < 0x7f) { + unsigned int i = 94 * (c1 - 0x21) + (c2 - 0x21); + unsigned short wc = 0xfffd; + if (i < 1410) { + if (i < 1115) + wc = ksc5601_2uni_page21[i]; + } else if (i < 3854) { + if (i < 3760) + wc = ksc5601_2uni_page30[i-1410]; + } else { + if (i < 8742) + wc = ksc5601_2uni_page4a[i-3854]; + } + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 2; + } + } + return RET_ILSEQ; + } + return RET_TOOFEW(0); + } + return RET_ILSEQ; +} + +static const unsigned short ksc5601_2charset[8224] = { + 0x222e, 0x2234, 0x2157, 0x2127, 0x2823, 0x2129, 0x2146, 0x213e, + 0x2977, 0x2978, 0x2225, 0x2252, 0x2124, 0x222c, 0x2976, 0x282c, + 0x2879, 0x2876, 0x287a, 0x222f, 0x2821, 0x2822, 0x213f, 0x282a, + 0x282d, 0x292c, 0x2921, 0x2923, 0x2140, 0x292a, 0x292d, 0x2922, + 0x2824, 0x2924, 0x2925, 0x2826, 0x2926, 0x2927, 0x2828, 0x2928, + 0x2829, 0x2929, 0x2930, 0x282f, 0x292f, 0x282b, 0x292b, 0x282e, + 0x292e, 0x2227, 0x2230, 0x2228, 0x222b, 0x222a, 0x222d, 0x2229, + 0x2541, 0x2542, 0x2543, 0x2544, 0x2545, 0x2546, 0x2547, 0x2548, + 0x2549, 0x254a, 0x254b, 0x254c, 0x254d, 0x254e, 0x254f, 0x2550, + 0x2551, 0x2552, 0x2553, 0x2554, 0x2555, 0x2556, 0x2557, 0x2558, + 0x2561, 0x2562, 0x2563, 0x2564, 0x2565, 0x2566, 0x2567, 0x2568, + 0x2569, 0x256a, 0x256b, 0x256c, 0x256d, 0x256e, 0x256f, 0x2570, + 0x2571, 0x2572, 0x2573, 0x2574, 0x2575, 0x2576, 0x2577, 0x2578, + 0x2c27, 0x2c21, 0x2c22, 0x2c23, 0x2c24, 0x2c25, 0x2c26, 0x2c28, + 0x2c29, 0x2c2a, 0x2c2b, 0x2c2c, 0x2c2d, 0x2c2e, 0x2c2f, 0x2c30, + 0x2c31, 0x2c32, 0x2c33, 0x2c34, 0x2c35, 0x2c36, 0x2c37, 0x2c38, + 0x2c39, 0x2c3a, 0x2c3b, 0x2c3c, 0x2c3d, 0x2c3e, 0x2c3f, 0x2c40, + 0x2c41, 0x2c51, 0x2c52, 0x2c53, 0x2c54, 0x2c55, 0x2c56, 0x2c58, + 0x2c59, 0x2c5a, 0x2c5b, 0x2c5c, 0x2c5d, 0x2c5e, 0x2c5f, 0x2c60, + 0x2c61, 0x2c62, 0x2c63, 0x2c64, 0x2c65, 0x2c66, 0x2c67, 0x2c68, + 0x2c69, 0x2c6a, 0x2c6b, 0x2c6c, 0x2c6d, 0x2c6e, 0x2c6f, 0x2c70, + 0x2c71, 0x2c57, 0x212a, 0x212e, 0x212f, 0x2130, 0x2131, 0x2253, + 0x2254, 0x2125, 0x2126, 0x2236, 0x2147, 0x2148, 0x2158, 0x2979, + 0x297a, 0x297b, 0x297c, 0x297d, 0x297e, 0x2149, 0x2235, 0x2724, + 0x2260, 0x2265, 0x2262, 0x2759, 0x214a, 0x2877, 0x2878, 0x287b, + 0x287c, 0x287d, 0x287e, 0x2530, 0x2531, 0x2532, 0x2533, 0x2534, + 0x2535, 0x2536, 0x2537, 0x2538, 0x2539, 0x2521, 0x2522, 0x2523, + 0x2524, 0x2525, 0x2526, 0x2527, 0x2528, 0x2529, 0x252a, 0x2167, + 0x2168, 0x2166, 0x2169, 0x216a, 0x2255, 0x2258, 0x2256, 0x2259, + 0x2257, 0x2221, 0x2222, 0x2223, 0x2153, 0x2224, 0x2154, 0x2174, + 0x2175, 0x2233, 0x2232, 0x216e, 0x2170, 0x2144, 0x2150, 0x212b, + 0x217c, 0x217d, 0x217b, 0x217a, 0x2172, 0x2173, 0x2231, 0x2145, + 0x2171, 0x212d, 0x216f, 0x2156, 0x2141, 0x2155, 0x2142, 0x2143, + 0x216c, 0x216d, 0x2178, 0x2179, 0x2176, 0x2177, 0x2241, 0x2151, + 0x2152, 0x2867, 0x2868, 0x2869, 0x286a, 0x286b, 0x286c, 0x286d, + 0x286e, 0x286f, 0x2870, 0x2871, 0x2872, 0x2873, 0x2874, 0x2875, + 0x2967, 0x2968, 0x2969, 0x296a, 0x296b, 0x296c, 0x296d, 0x296e, + 0x296f, 0x2970, 0x2971, 0x2972, 0x2973, 0x2974, 0x2975, 0x294d, + 0x294e, 0x294f, 0x2950, 0x2951, 0x2952, 0x2953, 0x2954, 0x2955, + 0x2956, 0x2957, 0x2958, 0x2959, 0x295a, 0x295b, 0x295c, 0x295d, + 0x295e, 0x295f, 0x2960, 0x2961, 0x2962, 0x2963, 0x2964, 0x2965, + 0x2966, 0x284d, 0x284e, 0x284f, 0x2850, 0x2851, 0x2852, 0x2853, + 0x2854, 0x2855, 0x2856, 0x2857, 0x2858, 0x2859, 0x285a, 0x285b, + 0x285c, 0x285d, 0x285e, 0x285f, 0x2860, 0x2861, 0x2862, 0x2863, + 0x2864, 0x2865, 0x2866, 0x2621, 0x262c, 0x2622, 0x262d, 0x2623, + 0x2648, 0x2647, 0x262e, 0x2624, 0x2642, 0x2641, 0x262f, 0x2626, + 0x2646, 0x2645, 0x2631, 0x2625, 0x2644, 0x2643, 0x2630, 0x2627, + 0x263c, 0x2649, 0x264a, 0x2637, 0x264b, 0x264c, 0x2632, 0x2629, + 0x263e, 0x264d, 0x264e, 0x2639, 0x264f, 0x2650, 0x2634, 0x2628, + 0x2651, 0x2652, 0x2638, 0x263d, 0x2653, 0x2654, 0x2633, 0x262a, + 0x2655, 0x2656, 0x263a, 0x263f, 0x2657, 0x2658, 0x2635, 0x262b, + 0x2659, 0x265a, 0x263b, 0x265b, 0x265c, 0x2640, 0x265d, 0x265e, + 0x265f, 0x2660, 0x2661, 0x2662, 0x2663, 0x2664, 0x2636, 0x2246, + 0x2161, 0x2160, 0x2243, 0x2247, 0x2248, 0x224b, 0x224a, 0x2249, + 0x224c, 0x2163, 0x2162, 0x223a, 0x2239, 0x2165, 0x2164, 0x2238, + 0x2237, 0x215f, 0x215e, 0x2242, 0x215b, 0x215d, 0x215c, 0x2244, + 0x2245, 0x215a, 0x2159, 0x224f, 0x224e, 0x2250, 0x2251, 0x214f, + 0x214e, 0x223c, 0x223d, 0x2240, 0x223b, 0x223e, 0x223f, 0x224d, + 0x225b, 0x225c, 0x225d, 0x225a, 0x2121, 0x2122, 0x2123, 0x2128, + 0x2134, 0x2135, 0x2136, 0x2137, 0x2138, 0x2139, 0x213a, 0x213b, + 0x213c, 0x213d, 0x216b, 0x2132, 0x2133, 0x2a21, 0x2a22, 0x2a23, + 0x2a24, 0x2a25, 0x2a26, 0x2a27, 0x2a28, 0x2a29, 0x2a2a, 0x2a2b, + 0x2a2c, 0x2a2d, 0x2a2e, 0x2a2f, 0x2a30, 0x2a31, 0x2a32, 0x2a33, + 0x2a34, 0x2a35, 0x2a36, 0x2a37, 0x2a38, 0x2a39, 0x2a3a, 0x2a3b, + 0x2a3c, 0x2a3d, 0x2a3e, 0x2a3f, 0x2a40, 0x2a41, 0x2a42, 0x2a43, + 0x2a44, 0x2a45, 0x2a46, 0x2a47, 0x2a48, 0x2a49, 0x2a4a, 0x2a4b, + 0x2a4c, 0x2a4d, 0x2a4e, 0x2a4f, 0x2a50, 0x2a51, 0x2a52, 0x2a53, + 0x2a54, 0x2a55, 0x2a56, 0x2a57, 0x2a58, 0x2a59, 0x2a5a, 0x2a5b, + 0x2a5c, 0x2a5d, 0x2a5e, 0x2a5f, 0x2a60, 0x2a61, 0x2a62, 0x2a63, + 0x2a64, 0x2a65, 0x2a66, 0x2a67, 0x2a68, 0x2a69, 0x2a6a, 0x2a6b, + 0x2a6c, 0x2a6d, 0x2a6e, 0x2a6f, 0x2a70, 0x2a71, 0x2a72, 0x2a73, + 0x2b21, 0x2b22, 0x2b23, 0x2b24, 0x2b25, 0x2b26, 0x2b27, 0x2b28, + 0x2b29, 0x2b2a, 0x2b2b, 0x2b2c, 0x2b2d, 0x2b2e, 0x2b2f, 0x2b30, + 0x2b31, 0x2b32, 0x2b33, 0x2b34, 0x2b35, 0x2b36, 0x2b37, 0x2b38, + 0x2b39, 0x2b3a, 0x2b3b, 0x2b3c, 0x2b3d, 0x2b3e, 0x2b3f, 0x2b40, + 0x2b41, 0x2b42, 0x2b43, 0x2b44, 0x2b45, 0x2b46, 0x2b47, 0x2b48, + 0x2b49, 0x2b4a, 0x2b4b, 0x2b4c, 0x2b4d, 0x2b4e, 0x2b4f, 0x2b50, + 0x2b51, 0x2b52, 0x2b53, 0x2b54, 0x2b55, 0x2b56, 0x2b57, 0x2b58, + 0x2b59, 0x2b5a, 0x2b5b, 0x2b5c, 0x2b5d, 0x2b5e, 0x2b5f, 0x2b60, + 0x2b61, 0x2b62, 0x2b63, 0x2b64, 0x2b65, 0x2b66, 0x2b67, 0x2b68, + 0x2b69, 0x2b6a, 0x2b6b, 0x2b6c, 0x2b6d, 0x2b6e, 0x2b6f, 0x2b70, + 0x2b71, 0x2b72, 0x2b73, 0x2b74, 0x2b75, 0x2b76, 0x2421, 0x2422, + 0x2423, 0x2424, 0x2425, 0x2426, 0x2427, 0x2428, 0x2429, 0x242a, + 0x242b, 0x242c, 0x242d, 0x242e, 0x242f, 0x2430, 0x2431, 0x2432, + 0x2433, 0x2434, 0x2435, 0x2436, 0x2437, 0x2438, 0x2439, 0x243a, + 0x243b, 0x243c, 0x243d, 0x243e, 0x243f, 0x2440, 0x2441, 0x2442, + 0x2443, 0x2444, 0x2445, 0x2446, 0x2447, 0x2448, 0x2449, 0x244a, + 0x244b, 0x244c, 0x244d, 0x244e, 0x244f, 0x2450, 0x2451, 0x2452, + 0x2453, 0x2454, 0x2455, 0x2456, 0x2457, 0x2458, 0x2459, 0x245a, + 0x245b, 0x245c, 0x245d, 0x245e, 0x245f, 0x2460, 0x2461, 0x2462, + 0x2463, 0x2464, 0x2465, 0x2466, 0x2467, 0x2468, 0x2469, 0x246a, + 0x246b, 0x246c, 0x246d, 0x246e, 0x246f, 0x2470, 0x2471, 0x2472, + 0x2473, 0x2474, 0x2475, 0x2476, 0x2477, 0x2478, 0x2479, 0x247a, + 0x247b, 0x247c, 0x247d, 0x247e, 0x2931, 0x2932, 0x2933, 0x2934, + 0x2935, 0x2936, 0x2937, 0x2938, 0x2939, 0x293a, 0x293b, 0x293c, + 0x293d, 0x293e, 0x293f, 0x2940, 0x2941, 0x2942, 0x2943, 0x2944, + 0x2945, 0x2946, 0x2947, 0x2948, 0x2949, 0x294a, 0x294b, 0x294c, + 0x225f, 0x2831, 0x2832, 0x2833, 0x2834, 0x2835, 0x2836, 0x2837, + 0x2838, 0x2839, 0x283a, 0x283b, 0x283c, 0x283d, 0x283e, 0x283f, + 0x2840, 0x2841, 0x2842, 0x2843, 0x2844, 0x2845, 0x2846, 0x2847, + 0x2848, 0x2849, 0x284a, 0x284b, 0x284c, 0x225e, 0x2749, 0x274a, + 0x274b, 0x274c, 0x274d, 0x273a, 0x273b, 0x275c, 0x275d, 0x275e, + 0x2736, 0x2737, 0x2738, 0x2754, 0x2755, 0x2756, 0x2757, 0x2758, + 0x2721, 0x2722, 0x2723, 0x2725, 0x272b, 0x272c, 0x272d, 0x272e, + 0x272f, 0x2730, 0x2731, 0x2732, 0x2733, 0x2734, 0x2727, 0x2728, + 0x2729, 0x272a, 0x273d, 0x273e, 0x2765, 0x2766, 0x2767, 0x2768, + 0x2761, 0x2762, 0x2763, 0x273f, 0x2740, 0x2741, 0x2742, 0x2743, + 0x2744, 0x2745, 0x2746, 0x2747, 0x2748, 0x274e, 0x274f, 0x2750, + 0x2751, 0x2752, 0x2753, 0x275a, 0x275b, 0x2263, 0x276c, 0x2726, + 0x2760, 0x276f, 0x2261, 0x273c, 0x276d, 0x2735, 0x2739, 0x276a, + 0x276b, 0x275f, 0x2264, 0x2764, 0x276e, 0x2769, 0x6c69, 0x6f4b, + 0x7652, 0x5832, 0x6d5b, 0x5f32, 0x5f3e, 0x793b, 0x5c74, 0x7564, + 0x7326, 0x5d60, 0x6126, 0x4e78, 0x5c30, 0x632a, 0x7169, 0x4d7a, + 0x7c2f, 0x5321, 0x712b, 0x6751, 0x522c, 0x4e79, 0x717d, 0x5e3f, + 0x7b3a, 0x7939, 0x4e52, 0x632b, 0x6b60, 0x4e7a, 0x4b77, 0x6525, + 0x4a61, 0x544c, 0x6a61, 0x5c63, 0x5f2d, 0x4b6b, 0x552f, 0x5675, + 0x6578, 0x5e40, 0x6c23, 0x694d, 0x6a27, 0x6976, 0x7b3b, 0x6769, + 0x6f4c, 0x5066, 0x5e41, 0x642c, 0x584c, 0x7971, 0x4e5f, 0x7a24, + 0x6632, 0x7a7b, 0x7a3d, 0x4c48, 0x6f4d, 0x5555, 0x5322, 0x6c51, + 0x6427, 0x6c52, 0x7631, 0x4e7b, 0x5051, 0x4b3f, 0x6d24, 0x6d28, + 0x5e42, 0x7662, 0x6d5c, 0x5c75, 0x6039, 0x544e, 0x7435, 0x535b, + 0x5635, 0x6c24, 0x6466, 0x716a, 0x4b6c, 0x4b40, 0x6c72, 0x506a, + 0x7972, 0x6c25, 0x505f, 0x676a, 0x506b, 0x5c51, 0x5b69, 0x7d4c, + 0x5b57, 0x5a61, 0x5636, 0x635f, 0x5e43, 0x5e44, 0x4a21, 0x6e6c, + 0x5323, 0x6e37, 0x784f, 0x6a48, 0x6e38, 0x712c, 0x7125, 0x694e, + 0x793c, 0x6579, 0x6c6a, 0x5d56, 0x6d42, 0x7825, 0x653a, 0x5b58, + 0x4a22, 0x514d, 0x6e6d, 0x6c6b, 0x5e45, 0x6360, 0x4a49, 0x7269, + 0x554e, 0x7636, 0x4e42, 0x5647, 0x6334, 0x712d, 0x6a62, 0x5742, + 0x7327, 0x4d6a, 0x6b6e, 0x5932, 0x7d25, 0x7655, 0x5562, 0x7835, + 0x4c75, 0x7535, 0x642d, 0x676b, 0x7155, 0x703b, 0x6935, 0x4c49, + 0x7a55, 0x6154, 0x5756, 0x5c41, 0x5e46, 0x7a6f, 0x6361, 0x6173, + 0x5c76, 0x4e7c, 0x5b44, 0x7871, 0x5c64, 0x656f, 0x5c31, 0x5556, + 0x735a, 0x4b41, 0x5b43, 0x597a, 0x536e, 0x7a38, 0x7d26, 0x6b6f, + 0x7426, 0x4c4a, 0x7328, 0x735b, 0x5b27, 0x7637, 0x4f66, 0x7072, + 0x4b5a, 0x6752, 0x5743, 0x7670, 0x685e, 0x6526, 0x6567, 0x4a23, + 0x4c27, 0x6a49, 0x7836, 0x7a25, 0x712e, 0x6f4e, 0x4b6d, 0x7630, + 0x6f4f, 0x694f, 0x775e, 0x4e53, 0x5c77, 0x5b28, 0x4b78, 0x5f21, + 0x5d61, 0x754a, 0x6936, 0x676c, 0x6e6e, 0x7370, 0x5f3f, 0x4c4b, + 0x5041, 0x7452, 0x603a, 0x5f40, 0x4e60, 0x5c52, 0x7d6a, 0x5676, + 0x6a4a, 0x6869, 0x632c, 0x7350, 0x4a24, 0x5b78, 0x5e47, 0x6b70, + 0x7156, 0x6562, 0x4c4c, 0x4b7b, 0x6a63, 0x5f41, 0x566d, 0x6950, + 0x6e39, 0x5563, 0x5153, 0x6570, 0x6834, 0x6b43, 0x6a2a, 0x7a7c, + 0x7576, 0x703c, 0x7d54, 0x603b, 0x4e43, 0x503a, 0x773a, 0x5873, + 0x774d, 0x642e, 0x545f, 0x5067, 0x6c7d, 0x522e, 0x6e6f, 0x5557, + 0x6a64, 0x7822, 0x4d6b, 0x573f, 0x7b31, 0x4d6c, 0x5c32, 0x506c, + 0x4e7d, 0x6e70, 0x4c42, 0x506d, 0x6577, 0x737c, 0x6e22, 0x5933, + 0x5874, 0x6937, 0x4e2e, 0x5922, 0x5871, 0x544f, 0x6527, 0x5552, + 0x5629, 0x7422, 0x7157, 0x5558, 0x703d, 0x5750, 0x5450, 0x574f, + 0x6b6a, 0x7d6b, 0x5b6d, 0x7c45, 0x4b42, 0x7d55, 0x7448, 0x686a, + 0x7573, 0x795e, 0x536f, 0x6c53, 0x5d42, 0x6f37, 0x6754, 0x4a4a, + 0x597b, 0x7a7d, 0x562a, 0x7478, 0x7777, 0x5c2c, 0x5757, 0x5f22, + 0x4e3e, 0x5370, 0x7024, 0x616c, 0x4f67, 0x734b, 0x6d29, 0x4a3e, + 0x746f, 0x764e, 0x5e7b, 0x503b, 0x5537, 0x6e71, 0x7428, 0x5c78, + 0x4b27, 0x5a4e, 0x6066, 0x6d25, 0x6e72, 0x5c79, 0x795c, 0x735c, + 0x7872, 0x7479, 0x7c71, 0x503c, 0x5b79, 0x5731, 0x4b7c, 0x7025, + 0x4b7d, 0x5574, 0x4d6d, 0x4a25, 0x562b, 0x5042, 0x703e, 0x523d, + 0x4c24, 0x7a36, 0x4c4d, 0x5a7a, 0x764f, 0x6938, 0x5875, 0x4c4e, + 0x574d, 0x5451, 0x696d, 0x4a6b, 0x5962, 0x7d32, 0x632d, 0x564c, + 0x5934, 0x6127, 0x6e53, 0x5043, 0x7d33, 0x5564, 0x4f68, 0x6d43, + 0x5032, 0x4e7e, 0x5a28, 0x7850, 0x7d56, 0x7851, 0x7852, 0x5c53, + 0x5d62, 0x7b79, 0x5d41, 0x6335, 0x6d5d, 0x4e44, 0x4b21, 0x5d63, + 0x7c5d, 0x792f, 0x527b, 0x4f21, 0x6428, 0x7436, 0x6c7e, 0x632e, + 0x676d, 0x7d41, 0x5a62, 0x5833, 0x5d64, 0x706f, 0x7671, 0x7a70, + 0x5175, 0x5a4f, 0x5c54, 0x5c26, 0x6f3f, 0x4e4f, 0x6059, 0x5956, + 0x6c54, 0x6a4b, 0x4a3f, 0x5530, 0x4f69, 0x716d, 0x4c4f, 0x6478, + 0x646d, 0x5758, 0x7d27, 0x6a2b, 0x7632, 0x4f70, 0x793d, 0x6674, + 0x4b5b, 0x7351, 0x6951, 0x7329, 0x5060, 0x6952, 0x5a63, 0x6252, + 0x7622, 0x6174, 0x5a64, 0x6755, 0x753f, 0x4f22, 0x4d2f, 0x4f23, + 0x4d30, 0x717e, 0x5023, 0x612f, 0x7823, 0x4a26, 0x773b, 0x726a, + 0x5e48, 0x6953, 0x5e49, 0x7d5e, 0x4a40, 0x796a, 0x514e, 0x6e54, + 0x5452, 0x5923, 0x7d28, 0x5759, 0x774e, 0x7a3e, 0x4f56, 0x5770, + 0x6b61, 0x7845, 0x5c7a, 0x5d43, 0x795f, 0x676f, 0x7d65, 0x7623, + 0x597c, 0x7d29, 0x676e, 0x5565, 0x6f50, 0x4d31, 0x7722, 0x7132, + 0x7131, 0x4d32, 0x5a2b, 0x4a27, 0x6362, 0x7b3c, 0x5924, 0x6e3a, + 0x7853, 0x7b7a, 0x4f24, 0x5c7b, 0x7663, 0x6d2a, 0x7221, 0x4e61, + 0x7a26, 0x7960, 0x6c56, 0x646e, 0x7921, 0x7b6f, 0x796b, 0x6e23, + 0x6a2c, 0x4a28, 0x747a, 0x4d56, 0x7c76, 0x7449, 0x7854, 0x7826, + 0x5e4a, 0x7246, 0x575a, 0x5350, 0x5845, 0x6a66, 0x735d, 0x645a, + 0x7664, 0x7672, 0x5f42, 0x597d, 0x4c76, 0x533a, 0x642f, 0x7961, + 0x7026, 0x4b53, 0x603c, 0x744a, 0x547a, 0x7d2a, 0x7962, 0x7437, + 0x7d42, 0x7c30, 0x7d6c, 0x4a62, 0x7d3d, 0x6a67, 0x5f43, 0x5152, + 0x4e62, 0x5324, 0x7d2b, 0x5f60, 0x7247, 0x6770, 0x506e, 0x732a, + 0x5e4b, 0x7638, 0x6175, 0x7133, 0x7723, 0x4a29, 0x4f25, 0x5f44, + 0x6130, 0x703f, 0x7624, 0x6336, 0x7a46, 0x506f, 0x7d6d, 0x5d44, + 0x7c77, 0x663f, 0x5e2d, 0x7a3f, 0x6571, 0x6d44, 0x5225, 0x7d6e, + 0x7536, 0x6176, 0x5e4c, 0x7c5e, 0x6c57, 0x4d5d, 0x5637, 0x4d33, + 0x7855, 0x6558, 0x4f6a, 0x4f50, 0x6a4c, 0x6a2e, 0x6a2d, 0x5371, + 0x5325, 0x774f, 0x6e24, 0x5024, 0x7222, 0x5070, 0x7223, 0x7778, + 0x5033, 0x5b29, 0x533b, 0x4a6c, 0x7126, 0x4b55, 0x7767, 0x4d5e, + 0x7724, 0x7840, 0x535d, 0x4c50, 0x4f26, 0x7673, 0x6177, 0x535c, + 0x7a7e, 0x7a27, 0x6b59, 0x4f27, 0x6a2f, 0x646f, 0x6939, 0x7158, + 0x5858, 0x6072, 0x6634, 0x5c7c, 0x7371, 0x6350, 0x727b, 0x5b46, + 0x5071, 0x5072, 0x4f5c, 0x5351, 0x4c31, 0x7758, 0x4b28, 0x6b3c, + 0x643e, 0x745c, 0x5c42, 0x7027, 0x6640, 0x4a6d, 0x686b, 0x6568, + 0x5c43, 0x6d5e, 0x5372, 0x4c77, 0x4e54, 0x672b, 0x4b43, 0x6131, + 0x7732, 0x5373, 0x5352, 0x7540, 0x5f5d, 0x6e73, 0x6771, 0x7d34, + 0x7248, 0x7352, 0x6e74, 0x6253, 0x4c51, 0x5f6a, 0x693a, 0x5957, + 0x754d, 0x7172, 0x7a47, 0x5978, 0x5442, 0x7665, 0x5d45, 0x6772, + 0x6d5f, 0x4a4b, 0x5b7a, 0x6835, 0x5326, 0x7d35, 0x7949, 0x6462, + 0x7b3d, 0x5724, 0x4e45, 0x4e55, 0x5666, 0x653d, 0x5e4d, 0x6c73, + 0x6d60, 0x6c6c, 0x7b3e, 0x5f6b, 0x6178, 0x793e, 0x5073, 0x602a, + 0x6862, 0x6254, 0x527d, 0x6528, 0x5953, 0x535e, 0x7438, 0x773c, + 0x5c7d, 0x686c, 0x6467, 0x6377, 0x6c28, 0x7a71, 0x6572, 0x5074, + 0x522f, 0x5c65, 0x5025, 0x7134, 0x7c31, 0x4c78, 0x5d46, 0x7a51, + 0x775f, 0x7a28, 0x6e75, 0x5e4e, 0x6773, 0x772c, 0x6b44, 0x6d61, + 0x602b, 0x5d47, 0x5233, 0x523f, 0x4a4c, 0x7b3f, 0x657d, 0x5d65, + 0x584d, 0x6c74, 0x5075, 0x686d, 0x5052, 0x5958, 0x7666, 0x5b2a, + 0x7760, 0x5859, 0x7423, 0x745d, 0x6f51, 0x5935, 0x6d2b, 0x6337, + 0x6e3b, 0x4d34, 0x6073, 0x6a4d, 0x6c75, 0x686e, 0x4b29, 0x712f, + 0x4a4d, 0x6c29, 0x726b, 0x7d6f, 0x7973, 0x6641, 0x6c58, 0x6d2c, + 0x6a4e, 0x685f, 0x5e4f, 0x5226, 0x6774, 0x5156, 0x6642, 0x6363, + 0x6430, 0x5834, 0x7625, 0x735e, 0x5725, 0x7768, 0x6846, 0x7b66, + 0x5d66, 0x5c7e, 0x585a, 0x5a2c, 0x6a30, 0x6338, 0x4a2a, 0x6179, + 0x6a31, 0x726c, 0x7a6e, 0x6e55, 0x7974, 0x526c, 0x7b7b, 0x7d70, + 0x603d, 0x4e63, 0x7846, 0x5e2e, 0x5f45, 0x653e, 0x6d2d, 0x7a6a, + 0x4d6e, 0x6d26, 0x6d2e, 0x706d, 0x5d21, 0x6d2f, 0x7c78, 0x586b, + 0x4c79, 0x4d35, 0x7a29, 0x615d, 0x6255, 0x6d4f, 0x5d22, 0x794a, + 0x6a68, 0x656d, 0x536b, 0x6954, 0x617a, 0x644c, 0x6164, 0x6847, + 0x4e5b, 0x5c55, 0x7735, 0x7c73, 0x7073, 0x4e2f, 0x7135, 0x6f52, + 0x6848, 0x6b71, 0x4b54, 0x603e, 0x6378, 0x6a69, 0x7c32, 0x6074, + 0x4f60, 0x6e25, 0x7a2a, 0x6643, 0x6132, 0x4a2b, 0x6364, 0x693b, + 0x6256, 0x7372, 0x6e56, 0x6a32, 0x5076, 0x6c59, 0x5a4b, 0x4f28, + 0x5d23, 0x585b, 0x794e, 0x6955, 0x6351, 0x523c, 0x582c, 0x734c, + 0x4d7b, 0x7656, 0x6775, 0x686f, 0x6379, 0x523b, 0x7373, 0x637b, + 0x5e50, 0x4e30, 0x5677, 0x7159, 0x7541, 0x5c44, 0x753b, 0x5e51, + 0x5c66, 0x5e52, 0x6d62, 0x6e76, 0x6a4f, 0x706e, 0x637c, 0x535f, + 0x5374, 0x6133, 0x6134, 0x7453, 0x5f46, 0x6956, 0x5b2b, 0x7626, + 0x6339, 0x6b45, 0x7429, 0x4d36, 0x5279, 0x5a2d, 0x5263, 0x4f51, + 0x4b5c, 0x4c7a, 0x4f5d, 0x6829, 0x633b, 0x633a, 0x605a, 0x6e77, + 0x5c33, 0x5375, 0x5726, 0x7635, 0x575b, 0x6155, 0x546a, 0x5f23, + 0x7d5f, 0x5077, 0x6d54, 0x4b2a, 0x645b, 0x617b, 0x4b22, 0x5360, + 0x643f, 0x7b40, 0x5a3e, 0x644d, 0x5639, 0x6f40, 0x617c, 0x7639, + 0x5f47, 0x6431, 0x5c67, 0x5c68, 0x7a56, 0x5376, 0x715a, 0x7a72, + 0x627d, 0x554f, 0x5078, 0x4d5f, 0x754b, 0x6470, 0x4b2b, 0x5744, + 0x627e, 0x5d5a, 0x5a2e, 0x4a6e, 0x5539, 0x6321, 0x6863, 0x732b, + 0x4f29, 0x5377, 0x5471, 0x4e64, 0x6872, 0x6575, 0x672e, 0x563a, + 0x5f6c, 0x6440, 0x6864, 0x5835, 0x645c, 0x7439, 0x7136, 0x625e, + 0x6135, 0x4d6f, 0x7127, 0x4e65, 0x4b5d, 0x5963, 0x732c, 0x5079, + 0x6c2b, 0x5e53, 0x7769, 0x7975, 0x615e, 0x4b6e, 0x633c, 0x7856, + 0x5b6e, 0x7d71, 0x7736, 0x745e, 0x726d, 0x5b59, 0x7028, 0x617d, + 0x5e54, 0x602c, 0x6d63, 0x5361, 0x5f48, 0x5936, 0x7d2c, 0x6f53, + 0x6441, 0x786b, 0x5b2c, 0x7c46, 0x582d, 0x763a, 0x5b5f, 0x5353, + 0x7847, 0x4a4e, 0x7841, 0x5234, 0x5c34, 0x7a39, 0x4a4f, 0x7c33, + 0x6a6a, 0x6a6b, 0x507a, 0x6d64, 0x5d67, 0x5f49, 0x5f6d, 0x6e3c, + 0x6f41, 0x4c52, 0x5d24, 0x5f4a, 0x5378, 0x7128, 0x4d37, 0x6f54, + 0x645d, 0x5f6e, 0x4b2c, 0x693c, 0x6a6c, 0x5f4b, 0x793f, 0x562f, + 0x5546, 0x4f2a, 0x4e29, 0x5678, 0x7137, 0x6e78, 0x5959, 0x735f, + 0x7848, 0x4e46, 0x5566, 0x7466, 0x6645, 0x6f55, 0x4b6f, 0x7c5f, + 0x5c27, 0x5667, 0x7849, 0x6352, 0x633d, 0x4f61, 0x7040, 0x6c5a, + 0x5d57, 0x7b70, 0x6c2c, 0x7029, 0x7a57, 0x7b41, 0x5240, 0x6530, + 0x6d65, 0x4b2d, 0x7930, 0x7725, 0x4b2e, 0x5a2f, 0x5836, 0x5327, + 0x7b32, 0x7d44, 0x6c2d, 0x7b21, 0x6569, 0x696e, 0x7374, 0x7873, + 0x7041, 0x5e2f, 0x7830, 0x7360, 0x672f, 0x5b2d, 0x6635, 0x7928, + 0x5d58, 0x6859, 0x6f56, 0x5362, 0x625f, 0x7c60, 0x5748, 0x7d2d, + 0x5f6f, 0x4c53, 0x5379, 0x5470, 0x5b47, 0x5e55, 0x7074, 0x5550, + 0x6559, 0x7c47, 0x5c56, 0x6260, 0x5a30, 0x7323, 0x536c, 0x744b, + 0x7d45, 0x637d, 0x7931, 0x507b, 0x6c5b, 0x753c, 0x7224, 0x584e, + 0x584f, 0x7577, 0x7661, 0x5237, 0x7b6c, 0x5d48, 0x6468, 0x5241, + 0x7857, 0x563b, 0x5e56, 0x773d, 0x6c2e, 0x5061, 0x6075, 0x6a33, + 0x4e56, 0x4c25, 0x6c76, 0x6261, 0x633e, 0x7c48, 0x4d70, 0x7976, + 0x5f70, 0x653f, 0x4e3f, 0x7c61, 0x6d30, 0x7d51, 0x763b, 0x794f, + 0x6b5a, 0x4a41, 0x5238, 0x4d71, 0x6353, 0x7d66, 0x666d, 0x637a, + 0x702a, 0x7950, 0x7c62, 0x7827, 0x6165, 0x6e79, 0x6776, 0x6a6d, + 0x7c34, 0x7542, 0x575c, 0x7075, 0x5d68, 0x536d, 0x757c, 0x5a3f, + 0x4c7b, 0x537a, 0x7424, 0x6f57, 0x5443, 0x7b63, 0x7b6d, 0x602d, + 0x6a6e, 0x7b33, 0x6442, 0x7667, 0x525d, 0x5f4c, 0x7c49, 0x6529, + 0x6076, 0x7633, 0x617e, 0x4b70, 0x6a6f, 0x6a70, 0x5a40, 0x7834, + 0x6b72, 0x6443, 0x6957, 0x6471, 0x4a6f, 0x4e57, 0x7c4a, 0x7361, + 0x4b44, 0x6365, 0x4b45, 0x6a34, 0x693d, 0x5749, 0x6b5b, 0x6d31, + 0x4c43, 0x773e, 0x7c4b, 0x7874, 0x5937, 0x7353, 0x7354, 0x7764, + 0x7751, 0x5837, 0x4e31, 0x4a42, 0x7b34, 0x4b46, 0x7076, 0x5567, + 0x6a50, 0x4c54, 0x4b2f, 0x742a, 0x692f, 0x7543, 0x6958, 0x5d69, + 0x7173, 0x557b, 0x5e3b, 0x747b, 0x7d73, 0x7d72, 0x7726, 0x5d49, + 0x5453, 0x4c28, 0x5a41, 0x4c55, 0x5964, 0x7a4a, 0x6563, 0x533c, + 0x4a70, 0x5044, 0x4a50, 0x7a2b, 0x6b6b, 0x6778, 0x5965, 0x5157, + 0x7324, 0x547b, 0x7c63, 0x7a58, 0x7355, 0x4f2b, 0x6b73, 0x557c, + 0x5354, 0x4d7c, 0x5966, 0x6279, 0x6221, 0x6b54, 0x6077, 0x6432, + 0x4c7c, 0x7b64, 0x742b, 0x503d, 0x4a71, 0x6f38, 0x5740, 0x6e7a, + 0x7d74, 0x5363, 0x7b42, 0x5568, 0x5b2e, 0x6136, 0x7837, 0x603f, + 0x7b43, 0x5d6a, 0x6222, 0x6e26, 0x7668, 0x7675, 0x5d4a, 0x5062, + 0x5d26, 0x5d6b, 0x6479, 0x632f, 0x507c, 0x747c, 0x4c3c, 0x776a, + 0x6564, 0x5f71, 0x7761, 0x7977, 0x6f39, 0x7858, 0x7929, 0x7859, + 0x6e3d, 0x5846, 0x6463, 0x754e, 0x5d59, 0x5967, 0x5239, 0x5543, + 0x5a65, 0x5a50, 0x5159, 0x4e58, 0x4b5e, 0x742c, 0x5a7b, 0x7669, + 0x6873, 0x4f2c, 0x7070, 0x747d, 0x5b48, 0x4e40, 0x6354, 0x514f, + 0x7175, 0x4d72, 0x4f6b, 0x4d38, 0x6326, 0x515a, 0x7225, 0x7226, + 0x644e, 0x537b, 0x7129, 0x7249, 0x6f58, 0x6649, 0x5838, 0x7a73, + 0x7335, 0x7824, 0x5173, 0x6648, 0x785a, 0x5c69, 0x5e57, 0x4b5f, + 0x4f6c, 0x745f, 0x5174, 0x523a, 0x5f72, 0x6137, 0x6223, 0x537c, + 0x6d66, 0x5b49, 0x647a, 0x4f5e, 0x4e50, 0x5553, 0x7375, 0x772e, + 0x6f48, 0x4d73, 0x754f, 0x6573, 0x7042, 0x4a51, 0x6a71, 0x5026, + 0x595a, 0x702b, 0x6b67, 0x6540, 0x7c35, 0x6444, 0x4c29, 0x7d46, + 0x6a35, 0x652a, 0x5f3a, 0x615f, 0x5a51, 0x6138, 0x6874, 0x537d, + 0x6224, 0x724a, 0x5a66, 0x7733, 0x7d4d, 0x7336, 0x6e57, 0x7544, + 0x5824, 0x7227, 0x5938, 0x5939, 0x6f49, 0x564e, 0x774b, 0x5f2e, + 0x6875, 0x5235, 0x5355, 0x744c, 0x5a7c, 0x5968, 0x776b, 0x7549, + 0x733c, 0x5a52, 0x5335, 0x6836, 0x564f, 0x743a, 0x7749, 0x4c2a, + 0x7043, 0x4c56, 0x5053, 0x533d, 0x5b7b, 0x4b60, 0x5364, 0x7677, + 0x553a, 0x734d, 0x4b61, 0x6b74, 0x742d, 0x7c2a, 0x776c, 0x6876, + 0x5a67, 0x774c, 0x6541, 0x606e, 0x557d, 0x4e66, 0x7c2b, 0x553b, + 0x7228, 0x6225, 0x4d39, 0x6a72, 0x4b47, 0x4d74, 0x5b2f, 0x6f59, + 0x4d3a, 0x7c79, 0x5f73, 0x4e67, 0x5a42, 0x4f2d, 0x6779, 0x7828, + 0x7362, 0x4a72, 0x5f24, 0x5444, 0x4c57, 0x6542, 0x4d3b, 0x6f5a, + 0x6e58, 0x5d27, 0x6226, 0x6040, 0x5630, 0x784a, 0x7c7a, 0x597e, + 0x5e30, 0x5d6c, 0x5a68, 0x5460, 0x5679, 0x4d57, 0x5e58, 0x7278, + 0x6456, 0x5045, 0x742e, 0x5d28, 0x6d45, 0x7356, 0x5e59, 0x6366, + 0x5328, 0x5b30, 0x655a, 0x633f, 0x5b31, 0x5569, 0x6041, 0x6f5b, + 0x7069, 0x5732, 0x507d, 0x5969, 0x507e, 0x6c6d, 0x5329, 0x7229, + 0x7044, 0x6262, 0x696f, 0x7951, 0x6959, 0x685a, 0x5a43, 0x5a44, + 0x5445, 0x677a, 0x4d60, 0x6330, 0x5b32, 0x7b44, 0x7363, 0x5925, + 0x7b67, 0x5d4b, 0x5054, 0x6636, 0x602e, 0x7d5a, 0x5c35, 0x6078, + 0x6731, 0x7570, 0x585c, 0x6d46, 0x6139, 0x6340, 0x7940, 0x6970, + 0x595b, 0x7364, 0x5c36, 0x6469, 0x7045, 0x6341, 0x7c4c, 0x7c4d, + 0x724b, 0x724c, 0x644f, 0x715b, 0x7a59, 0x7138, 0x7d75, 0x6079, + 0x677b, 0x7c37, 0x7c64, 0x7b45, 0x6367, 0x5839, 0x7678, 0x5c45, + 0x4c58, 0x602f, 0x7467, 0x6f5c, 0x4f7c, 0x6f5d, 0x722a, 0x7d3e, + 0x4a2c, 0x7d3b, 0x7d47, 0x6732, 0x6a51, 0x5f74, 0x516c, 0x645e, + 0x6543, 0x5926, 0x4d3c, 0x7365, 0x6d55, 0x593a, 0x6d67, 0x7b35, + 0x786c, 0x6067, 0x4c59, 0x5446, 0x6725, 0x5575, 0x533e, 0x7c7b, + 0x6472, 0x5f75, 0x6878, 0x786d, 0x4e47, 0x7d76, 0x6858, 0x4d58, + 0x6756, 0x4c5a, 0x4a63, 0x5f76, 0x7047, 0x7046, 0x583a, 0x7174, + 0x7470, 0x754c, 0x7c65, 0x6a45, 0x6a73, 0x5d5b, 0x5c57, 0x5e7d, + 0x7279, 0x5547, 0x5850, 0x7048, 0x5121, 0x5122, 0x5954, 0x5668, + 0x594a, 0x5a31, 0x5847, 0x5c62, 0x734e, 0x7574, 0x7139, 0x5a53, + 0x766a, 0x4f75, 0x7d2e, 0x4a52, 0x5f34, 0x575d, 0x7a3a, 0x6e27, + 0x753d, 0x7875, 0x6d68, 0x5461, 0x5123, 0x6156, 0x7978, 0x5b4a, + 0x4b79, 0x5454, 0x595c, 0x6e3e, 0x776d, 0x526e, 0x6166, 0x7779, + 0x5d6d, 0x685b, 0x5b33, 0x5177, 0x6030, 0x5462, 0x7657, 0x5779, + 0x585d, 0x4d7d, 0x722b, 0x4d3d, 0x7842, 0x722c, 0x4a2d, 0x4a2e, + 0x4f2e, 0x6342, 0x5c37, 0x5b5a, 0x593b, 0x4a73, 0x7653, 0x6678, + 0x6a75, 0x6a76, 0x7679, 0x4f2f, 0x4a53, 0x4a2f, 0x5230, 0x713a, + 0x5733, 0x6343, 0x737d, 0x5e5a, 0x5e5b, 0x6f5e, 0x6263, 0x6e7b, + 0x5f77, 0x574a, 0x4e68, 0x5b5b, 0x713b, 0x6971, 0x7a37, 0x5046, + 0x4c2b, 0x6e28, 0x4b7a, 0x7979, 0x4c7d, 0x537e, 0x6450, 0x726e, + 0x5455, 0x5f4d, 0x7c38, 0x5150, 0x724d, 0x7752, 0x4a54, 0x5559, + 0x585e, 0x4d59, 0x6e29, 0x763c, 0x4c5b, 0x7049, 0x7c7c, 0x6849, + 0x747e, 0x677c, 0x575e, 0x5e5c, 0x702c, 0x4c7e, 0x4d61, 0x613a, + 0x5b6f, 0x5a32, 0x5125, 0x5c38, 0x5876, 0x5124, 0x4d62, 0x5c6a, + 0x7077, 0x704a, 0x503e, 0x5d5c, 0x5456, 0x5356, 0x6d50, 0x4d21, + 0x5f35, 0x5f78, 0x5421, 0x4e32, 0x684a, 0x6b75, 0x6355, 0x7550, + 0x7521, 0x5927, 0x652b, 0x664b, 0x7571, 0x6545, 0x7923, 0x605b, + 0x766b, 0x4b71, 0x596a, 0x7522, 0x5751, 0x5178, 0x6a78, 0x6a79, + 0x5a33, 0x6f5f, 0x716f, 0x6576, 0x6e3f, 0x6264, 0x503f, 0x7a2c, + 0x7551, 0x6733, 0x693e, 0x724e, 0x5b34, 0x7c4e, 0x5d6e, 0x6734, + 0x5734, 0x7734, 0x4d3e, 0x5a69, 0x4f30, 0x7759, 0x7366, 0x4e59, + 0x4e2a, 0x4b48, 0x5027, 0x704b, 0x5047, 0x6445, 0x5b60, 0x555a, + 0x5727, 0x6e40, 0x7876, 0x7552, 0x6d69, 0x593c, 0x6546, 0x7523, + 0x5a54, 0x6227, 0x7b7c, 0x715c, 0x4a74, 0x687a, 0x4e69, 0x6978, + 0x6265, 0x5039, 0x5472, 0x5126, 0x5f4e, 0x7c74, 0x532a, 0x4c2c, + 0x6f60, 0x6565, 0x5055, 0x5b7c, 0x7c66, 0x4b7e, 0x6d6a, 0x5e31, + 0x7963, 0x5422, 0x4f76, 0x5650, 0x556a, 0x716e, 0x7a4b, 0x6521, + 0x5531, 0x4f6d, 0x6d6b, 0x5532, 0x553c, 0x7d62, 0x732d, 0x7d5b, + 0x6930, 0x5127, 0x7d63, 0x4e33, 0x7d64, 0x7a4e, 0x4a30, 0x7727, + 0x4f31, 0x6622, 0x7c36, 0x722d, 0x6f61, 0x732e, 0x5c46, 0x596b, + 0x6860, 0x6128, 0x5576, 0x4f7d, 0x5e5d, 0x5951, 0x646a, 0x724f, + 0x773f, 0x6266, 0x6228, 0x6356, 0x6d51, 0x6979, 0x5631, 0x5e32, + 0x6068, 0x532b, 0x6b5c, 0x5f2f, 0x4a43, 0x6e7c, 0x7d43, 0x6b76, + 0x4f32, 0x596c, 0x593d, 0x585f, 0x5438, 0x6b3e, 0x5d6f, 0x5d70, + 0x5d71, 0x5d72, 0x593e, 0x7b46, 0x4f33, 0x6e7d, 0x642b, 0x5a45, + 0x586c, 0x5128, 0x6229, 0x5e3c, 0x6735, 0x5b70, 0x6f62, 0x7170, + 0x4f34, 0x5b71, 0x6031, 0x5f25, 0x7952, 0x677d, 0x6623, 0x7b71, + 0x4b30, 0x722e, 0x4d67, 0x685c, 0x6757, 0x7740, 0x5063, 0x5a21, + 0x4c3d, 0x5129, 0x5d4c, 0x637e, 0x512a, 0x682a, 0x6a36, 0x797a, + 0x664c, 0x7658, 0x5447, 0x594b, 0x5952, 0x534b, 0x5877, 0x5a29, + 0x7578, 0x5e5e, 0x722f, 0x7829, 0x5848, 0x6e41, 0x7941, 0x5d73, + 0x6a7a, 0x763d, 0x613b, 0x4d3f, 0x7454, 0x664d, 0x7c4f, 0x7b22, + 0x605c, 0x743b, 0x5a55, 0x7932, 0x7b72, 0x5b76, 0x5e5f, 0x5b72, + 0x785c, 0x776e, 0x6b68, 0x527a, 0x713c, 0x7a5a, 0x5a6a, 0x5a46, + 0x7741, 0x6736, 0x6547, 0x562c, 0x5c47, 0x6129, 0x622a, 0x5526, + 0x5457, 0x7250, 0x6a7b, 0x605d, 0x7b73, 0x713d, 0x6267, 0x7d57, + 0x4e48, 0x6a37, 0x7c40, 0x7d67, 0x776f, 0x5735, 0x6f3a, 0x715d, + 0x5e33, 0x684b, 0x785d, 0x7b47, 0x5548, 0x575f, 0x5d29, 0x6931, + 0x7a2d, 0x7659, 0x7a74, 0x782a, 0x666e, 0x4c5c, 0x613c, 0x606f, + 0x693f, 0x7c7d, 0x664e, 0x6157, 0x664f, 0x7471, 0x6473, 0x647b, + 0x7964, 0x6f63, 0x4f6e, 0x763e, 0x6032, 0x7c7e, 0x512b, 0x577a, + 0x7b48, 0x6257, 0x5423, 0x7078, 0x5728, 0x6167, 0x533f, 0x6f64, + 0x5745, 0x6b62, 0x7c67, 0x6422, 0x6268, 0x6650, 0x7b68, 0x7468, + 0x6574, 0x743c, 0x7455, 0x5f36, 0x7c39, 0x6e42, 0x4a75, 0x6f65, + 0x4b62, 0x5424, 0x5e60, 0x5a7d, 0x6446, 0x683e, 0x605e, 0x7634, + 0x6a52, 0x797b, 0x6042, 0x4a64, 0x6737, 0x6a7d, 0x595d, 0x5a34, + 0x6e2a, 0x7b69, 0x5b4b, 0x5a35, 0x713e, 0x532c, 0x7b49, 0x5f4f, + 0x5340, 0x6357, 0x6f66, 0x7c50, 0x6940, 0x7553, 0x6c5c, 0x7737, + 0x6a38, 0x5179, 0x5c48, 0x6a39, 0x715e, 0x5736, 0x4f35, 0x5928, + 0x6c6e, 0x5d2a, 0x4d22, 0x682e, 0x613d, 0x7251, 0x6941, 0x527c, + 0x5b35, 0x7367, 0x587e, 0x7c51, 0x6d32, 0x742f, 0x7b23, 0x7c41, + 0x6e2b, 0x5425, 0x7472, 0x6e59, 0x7b4a, 0x4d63, 0x583b, 0x655b, + 0x7877, 0x7654, 0x5729, 0x4b49, 0x6651, 0x704c, 0x582e, 0x7953, + 0x557e, 0x583c, 0x7230, 0x622b, 0x7368, 0x6f42, 0x6d6c, 0x6738, + 0x5a7e, 0x4c3e, 0x727c, 0x5a6b, 0x6258, 0x6d56, 0x5651, 0x6033, + 0x7c52, 0x6b48, 0x5341, 0x704d, 0x4f77, 0x6d52, 0x5458, 0x5c49, + 0x5771, 0x5f3b, 0x7325, 0x744d, 0x713f, 0x7831, 0x697a, 0x7b4b, + 0x4a55, 0x7954, 0x774a, 0x5648, 0x7c68, 0x733d, 0x6e7e, 0x677e, + 0x5342, 0x5336, 0x4c2d, 0x767a, 0x5632, 0x5258, 0x6758, 0x6325, + 0x6739, 0x702d, 0x7b4c, 0x6b21, 0x5426, 0x7b4d, 0x553d, 0x715f, + 0x767b, 0x5e34, 0x556b, 0x6548, 0x7b24, 0x5439, 0x5e61, 0x6423, + 0x5737, 0x786e, 0x5e35, 0x5652, 0x7955, 0x673a, 0x6b55, 0x5577, + 0x6f67, 0x613e, 0x7a2e, 0x5669, 0x566e, 0x673b, 0x6c4b, 0x5533, + 0x4e34, 0x7b25, 0x616e, 0x7728, 0x7b4e, 0x583d, 0x7b7d, 0x7c69, + 0x4f36, 0x6d47, 0x6e2c, 0x4c5d, 0x7627, 0x667a, 0x7524, 0x7d5c, + 0x6d33, 0x4e49, 0x6f68, 0x613f, 0x7a5b, 0x4b63, 0x7729, 0x7b26, + 0x5c39, 0x7140, 0x6d48, 0x6f43, 0x562d, 0x7d4e, 0x6821, 0x7b74, + 0x5527, 0x7176, 0x6653, 0x4c5e, 0x7832, 0x5c6b, 0x7d36, 0x656a, + 0x7160, 0x5b4c, 0x5d4d, 0x5448, 0x596d, 0x7525, 0x667b, 0x6654, + 0x7d48, 0x5621, 0x7d3f, 0x7c53, 0x6f21, 0x673c, 0x516e, 0x6655, + 0x6972, 0x5f30, 0x5860, 0x7c3a, 0x7d2f, 0x704e, 0x5b61, 0x6549, + 0x6d34, 0x6043, 0x6358, 0x697b, 0x6a28, 0x7d37, 0x7b27, 0x6942, + 0x7d77, 0x6259, 0x5c6c, 0x6822, 0x6670, 0x7d78, 0x7d79, 0x763f, + 0x6727, 0x6657, 0x5473, 0x5449, 0x567a, 0x5772, 0x6140, 0x5b62, + 0x6658, 0x673d, 0x704f, 0x733e, 0x622c, 0x7537, 0x6070, 0x7d38, + 0x6368, 0x5427, 0x687c, 0x7a52, 0x786f, 0x5653, 0x5534, 0x7050, + 0x7770, 0x6e33, 0x6a3a, 0x6a53, 0x6d49, 0x5d2b, 0x652c, 0x7d21, + 0x5f50, 0x6c33, 0x5f51, 0x6d6d, 0x7838, 0x777a, 0x782b, 0x7460, + 0x543a, 0x6433, 0x695a, 0x5e36, 0x593f, 0x5940, 0x566f, 0x594c, + 0x5a2a, 0x5f65, 0x7765, 0x4c32, 0x5f79, 0x5760, 0x543b, 0x7d7a, + 0x4c33, 0x5b73, 0x5f52, 0x4e4a, 0x6e5a, 0x6464, 0x7b4f, 0x4f37, + 0x6e43, 0x4e6a, 0x622d, 0x5761, 0x7a75, 0x5549, 0x782c, 0x6759, + 0x7369, 0x586d, 0x6344, 0x7071, 0x6865, 0x607a, 0x6e44, 0x595e, + 0x6b22, 0x6b23, 0x7c42, 0x6a3b, 0x682b, 0x5e62, 0x6d6f, 0x6823, + 0x4f71, 0x543c, 0x7c6a, 0x673e, 0x7c72, 0x5634, 0x622e, 0x5337, + 0x7a4c, 0x7a5c, 0x6d35, 0x6163, 0x682c, 0x685d, 0x6f69, 0x743d, + 0x4f38, 0x695b, 0x512c, 0x5a47, 0x6b49, 0x684c, 0x5e37, 0x563c, + 0x5365, 0x7a5d, 0x5a56, 0x4a31, 0x5a48, 0x5f26, 0x7933, 0x7252, + 0x4a44, 0x4e4b, 0x4d75, 0x7d30, 0x5528, 0x7141, 0x6269, 0x5c4a, + 0x6c34, 0x7a40, 0x7b28, 0x5028, 0x5a6c, 0x596e, 0x607b, 0x6f6a, + 0x7a5e, 0x6044, 0x4f39, 0x554a, 0x5762, 0x622f, 0x5738, 0x684d, + 0x765a, 0x6f22, 0x625a, 0x767c, 0x7b50, 0x512d, 0x4d64, 0x512e, + 0x5c6d, 0x684e, 0x7079, 0x4e35, 0x667c, 0x577b, 0x5056, 0x5d75, + 0x7771, 0x767d, 0x5b77, 0x7b6a, 0x695c, 0x5941, 0x7572, 0x6045, + 0x6a54, 0x7942, 0x6a3c, 0x5245, 0x7b51, 0x6740, 0x6b25, 0x5f7a, + 0x6322, 0x5739, 0x6943, 0x687d, 0x682f, 0x7253, 0x7b29, 0x5825, + 0x554b, 0x5048, 0x512f, 0x5763, 0x6046, 0x5622, 0x6d70, 0x5773, + 0x7c54, 0x5a57, 0x4c5f, 0x7254, 0x5130, 0x4c60, 0x5b7d, 0x733f, + 0x7051, 0x7c3b, 0x6230, 0x6625, 0x625b, 0x5f5e, 0x6047, 0x726f, + 0x4c61, 0x566a, 0x6742, 0x4e36, 0x7340, 0x4d7e, 0x7b52, 0x7878, + 0x777b, 0x683f, 0x6837, 0x6d36, 0x5c3a, 0x4c34, 0x7177, 0x6838, + 0x4a76, 0x6424, 0x7456, 0x5f66, 0x5f27, 0x5f67, 0x6141, 0x6944, + 0x5c4b, 0x6945, 0x6f23, 0x6b26, 0x4b23, 0x6369, 0x517b, 0x6f24, + 0x6f6b, 0x5034, 0x4d23, 0x6866, 0x6f25, 0x534c, 0x5a6d, 0x573a, + 0x7255, 0x7565, 0x596f, 0x7934, 0x5554, 0x7d4f, 0x5b63, 0x7161, + 0x6c36, 0x7b7e, 0x5357, 0x5131, 0x4b31, 0x5132, 0x4b32, 0x7142, + 0x7461, 0x7935, 0x6143, 0x6142, 0x6b77, 0x5f28, 0x4b4a, 0x6639, + 0x785e, 0x792a, 0x4a77, 0x6d37, 0x5338, 0x7256, 0x5459, 0x6e45, + 0x7270, 0x4a32, 0x5c3b, 0x7178, 0x6c37, 0x654a, 0x7640, 0x7d5d, + 0x5463, 0x4c62, 0x7754, 0x5765, 0x5343, 0x5826, 0x7641, 0x5d76, + 0x4d40, 0x655c, 0x654b, 0x6144, 0x6830, 0x7430, 0x736a, 0x5a6e, + 0x573b, 0x6231, 0x572a, 0x567b, 0x645f, 0x4a56, 0x6b28, 0x5b7e, + 0x7642, 0x6f3b, 0x547d, 0x6048, 0x6839, 0x6f26, 0x4d24, 0x5474, + 0x5b21, 0x5b5c, 0x5b5d, 0x6e5c, 0x4b4b, 0x7c55, 0x4e6b, 0x4d41, + 0x7b53, 0x792b, 0x7554, 0x5929, 0x695d, 0x5b4d, 0x5d4e, 0x6743, + 0x6c4c, 0x796c, 0x4b4c, 0x607c, 0x5428, 0x6d53, 0x586f, 0x7257, + 0x4a78, 0x5a6f, 0x5654, 0x594d, 0x586e, 0x7241, 0x5f53, 0x5a70, + 0x626a, 0x607d, 0x5878, 0x772f, 0x5a36, 0x4a57, 0x7258, 0x5879, + 0x7a5f, 0x4f6f, 0x5942, 0x7052, 0x6451, 0x7337, 0x7a60, 0x6f6c, + 0x6232, 0x543d, 0x594e, 0x7462, 0x5429, 0x4d42, 0x675a, 0x7259, + 0x592a, 0x583e, 0x5c2d, 0x626b, 0x567c, 0x4a79, 0x545a, 0x7457, + 0x4c21, 0x4f3a, 0x7538, 0x5943, 0x5068, 0x6345, 0x6b78, 0x7231, + 0x4f3b, 0x532d, 0x6861, 0x4e6c, 0x6034, 0x5e63, 0x5d77, 0x7232, + 0x7376, 0x765b, 0x577e, 0x785f, 0x7772, 0x5029, 0x665a, 0x7526, + 0x573c, 0x4c63, 0x665b, 0x5d5d, 0x5133, 0x6f6d, 0x565e, 0x6474, + 0x616f, 0x5d78, 0x684f, 0x4a65, 0x5c21, 0x6035, 0x7c2c, 0x7c2d, + 0x5827, 0x6d38, 0x5b36, 0x5670, 0x732f, 0x4d25, 0x5a71, 0x5828, + 0x4c64, 0x5134, 0x4a58, 0x5a72, 0x7527, 0x7528, 0x6626, 0x556c, + 0x5578, 0x5a73, 0x6346, 0x5e64, 0x5e65, 0x5135, 0x5136, 0x5137, + 0x7233, 0x695e, 0x7053, 0x7234, 0x7054, 0x4b64, 0x7b54, 0x7566, + 0x636a, 0x5e66, 0x5f54, 0x7879, 0x702e, 0x5138, 0x565f, 0x5057, + 0x7c21, 0x6f6e, 0x5c58, 0x695f, 0x655d, 0x7d7b, 0x6049, 0x5649, + 0x542a, 0x654c, 0x6960, 0x5058, 0x7c22, 0x543e, 0x6233, 0x5e67, + 0x5c3c, 0x5236, 0x7555, 0x4e21, 0x7529, 0x5d79, 0x5d7a, 0x7055, + 0x765f, 0x725a, 0x646b, 0x7271, 0x6c39, 0x7d7c, 0x612a, 0x4a59, + 0x6f6f, 0x752a, 0x6c79, 0x782d, 0x7242, 0x7643, 0x5752, 0x7922, + 0x7056, 0x707a, 0x7660, 0x6973, 0x7243, 0x542b, 0x4a33, 0x4d26, + 0x4d43, 0x4d5a, 0x594f, 0x7644, 0x6e5d, 0x6744, 0x6234, 0x5f62, + 0x675b, 0x6831, 0x7c2e, 0x654d, 0x7a6b, 0x4f3c, 0x4f62, 0x4d76, + 0x6f70, 0x743e, 0x544d, 0x7338, 0x6921, 0x7272, 0x736b, 0x7057, + 0x4f57, 0x4f5f, 0x6840, 0x6841, 0x4f63, 0x6922, 0x502a, 0x7341, + 0x502b, 0x5464, 0x6f3c, 0x5821, 0x595f, 0x7357, 0x5c3d, 0x4c65, + 0x6d71, 0x7162, 0x545b, 0x6235, 0x4a66, 0x532e, 0x4c66, 0x7153, + 0x7567, 0x4a5a, 0x7b6e, 0x6145, 0x5f69, 0x6e5e, 0x7742, 0x5822, + 0x5d2c, 0x702f, 0x563d, 0x612b, 0x7936, 0x5475, 0x5049, 0x6f27, + 0x626c, 0x5b6a, 0x4e4c, 0x7568, 0x7755, 0x534d, 0x737e, 0x5035, + 0x607e, 0x5f7b, 0x665d, 0x6824, 0x4b4d, 0x6f28, 0x6e34, 0x5a58, + 0x5139, 0x5f29, 0x7330, 0x4c44, 0x4e37, 0x6f29, 0x5f55, 0x6d57, + 0x6e46, 0x6f3d, 0x7c56, 0x5b74, 0x6f2a, 0x7839, 0x7569, 0x6359, + 0x6146, 0x543f, 0x5e68, 0x706a, 0x7342, 0x532f, 0x4a5b, 0x7c57, + 0x6d58, 0x6147, 0x7458, 0x5633, 0x5d2d, 0x553e, 0x7143, 0x6e5f, + 0x566b, 0x7459, 0x5766, 0x5a37, 0x5d7b, 0x5d4f, 0x5823, 0x5a59, + 0x7058, 0x6f44, 0x6158, 0x7154, 0x6d72, 0x555b, 0x555c, 0x7344, + 0x4b57, 0x6236, 0x6f71, 0x7b55, 0x5358, 0x5d50, 0x7059, 0x4b33, + 0x555d, 0x4d27, 0x502c, 0x513a, 0x7144, 0x6533, 0x7b75, 0x6961, + 0x7d60, 0x7c3c, 0x5a22, 0x5a23, 0x5221, 0x526f, 0x626d, 0x5e69, + 0x4e5c, 0x7235, 0x5064, 0x5d51, 0x6148, 0x5b37, 0x5f63, 0x6d39, + 0x7145, 0x734f, 0x572b, 0x612c, 0x636b, 0x6e47, 0x6149, 0x4a7a, + 0x707b, 0x7a61, 0x705a, 0x4c67, 0x5a74, 0x4c3f, 0x4e6d, 0x5529, + 0x7a62, 0x5065, 0x6b56, 0x6c5f, 0x5f7c, 0x7756, 0x5e6a, 0x4b34, + 0x6f3e, 0x4c35, 0x4f3d, 0x6f72, 0x6237, 0x4c68, 0x707c, 0x5660, + 0x7146, 0x6238, 0x6b2b, 0x4b35, 0x5851, 0x744e, 0x7377, 0x5746, + 0x513b, 0x772a, 0x6d4a, 0x5753, 0x587a, 0x7645, 0x514c, 0x5d7c, + 0x5f7d, 0x7965, 0x604a, 0x727d, 0x5330, 0x7473, 0x5a49, 0x665e, + 0x783a, 0x6850, 0x587b, 0x6a55, 0x5623, 0x7646, 0x725b, 0x647c, + 0x6832, 0x5a5a, 0x725c, 0x7b56, 0x6932, 0x6e2d, 0x7a63, 0x5c6e, + 0x756a, 0x6660, 0x707d, 0x572c, 0x7545, 0x6e60, 0x5b65, 0x5d5e, + 0x5970, 0x6923, 0x7179, 0x7244, 0x604b, 0x6924, 0x6239, 0x6331, + 0x7c6b, 0x4d28, 0x4c36, 0x705b, 0x663a, 0x4d29, 0x7343, 0x6159, + 0x6f2b, 0x6745, 0x6069, 0x7345, 0x5440, 0x553f, 0x5d2e, 0x797c, + 0x4c40, 0x6522, 0x4e38, 0x5852, 0x7956, 0x712a, 0x4e51, 0x7647, + 0x5b6b, 0x5f7e, 0x5861, 0x7773, 0x5767, 0x547e, 0x513c, 0x654f, + 0x4b36, 0x5a38, 0x4d44, 0x563e, 0x623a, 0x4f58, 0x604c, 0x6b79, + 0x7d7d, 0x5768, 0x4b58, 0x6962, 0x683a, 0x6347, 0x6c4d, 0x6c4e, + 0x563f, 0x6327, 0x5f56, 0x7d68, 0x6e61, 0x7628, 0x5d7d, 0x783b, + 0x6851, 0x7957, 0x4e6e, 0x6c4f, 0x6925, 0x5655, 0x4d45, 0x6d3a, + 0x513d, 0x4f3e, 0x6c3b, 0x5231, 0x4c69, 0x5944, 0x697c, 0x513e, + 0x6c3c, 0x652d, 0x7730, 0x4c6a, 0x5344, 0x5640, 0x567d, 0x6121, + 0x5e3d, 0x7629, 0x5a24, 0x5624, 0x7546, 0x6122, 0x6946, 0x7245, + 0x7469, 0x566c, 0x6b53, 0x6c3d, 0x625c, 0x5e6b, 0x705c, 0x6b3f, + 0x574e, 0x513f, 0x752b, 0x797d, 0x4a5c, 0x4d46, 0x7236, 0x5d7e, + 0x4c37, 0x5b38, 0x5069, 0x4e5d, 0x6b40, 0x7d22, 0x784b, 0x6a56, + 0x7130, 0x5b4e, 0x7743, 0x5b4f, 0x4b24, 0x7860, 0x7b57, 0x6b4a, + 0x6021, 0x4e4d, 0x545c, 0x7d58, 0x5276, 0x7237, 0x7a76, 0x762a, + 0x7a77, 0x5866, 0x7431, 0x6852, 0x4a45, 0x4c6b, 0x626e, 0x623b, + 0x772d, 0x7861, 0x736c, 0x5e21, 0x647d, 0x636c, 0x5d2f, 0x5d30, + 0x4b37, 0x6853, 0x6123, 0x5260, 0x707e, 0x6926, 0x4b72, 0x6d73, + 0x5c59, 0x604d, 0x775a, 0x5b39, 0x4c2e, 0x5a5b, 0x4d47, 0x5d31, + 0x582f, 0x6323, 0x4e6f, 0x7273, 0x7833, 0x604e, 0x757d, 0x6b6c, + 0x5345, 0x7c6c, 0x525b, 0x546b, 0x5e22, 0x6566, 0x7030, 0x5544, + 0x6d74, 0x636d, 0x6842, 0x6d75, 0x577c, 0x6d3b, 0x762b, 0x7238, + 0x7648, 0x5366, 0x725d, 0x4f3f, 0x6b2c, 0x4f40, 0x6628, 0x7d69, + 0x4f41, 0x605f, 0x5e6c, 0x6022, 0x743f, 0x626f, 0x5971, 0x7147, + 0x4b38, 0x797e, 0x5b3a, 0x5a75, 0x766c, 0x5a5c, 0x7a64, 0x604f, + 0x5d32, 0x6629, 0x6f73, 0x736d, 0x6b7a, 0x7966, 0x4a5d, 0x555e, + 0x4a5e, 0x5f64, 0x667d, 0x752c, 0x6475, 0x6963, 0x6d4b, 0x4f64, + 0x5853, 0x5d33, 0x546c, 0x7239, 0x5f37, 0x4b4e, 0x7b58, 0x5059, + 0x5d52, 0x7774, 0x675c, 0x6425, 0x7c23, 0x5b3b, 0x723a, 0x697d, + 0x504a, 0x7556, 0x5945, 0x6434, 0x6d27, 0x6a3d, 0x667e, 0x7744, + 0x752d, 0x5960, 0x4a34, 0x7862, 0x4f42, 0x6c3e, 0x6534, 0x4d48, + 0x6e48, 0x6748, 0x4d49, 0x7937, 0x7168, 0x5972, 0x5b75, 0x4a35, + 0x5946, 0x5849, 0x592b, 0x6d3c, 0x5854, 0x5c5a, 0x623c, 0x7c6d, + 0x6c60, 0x527e, 0x6947, 0x662a, 0x6270, 0x7a3b, 0x752e, 0x7b2a, + 0x6c7b, 0x6c3f, 0x7c58, 0x5465, 0x7943, 0x6e62, 0x5769, 0x6d76, + 0x5e6d, 0x4c6c, 0x636e, 0x6854, 0x7a78, 0x5d34, 0x6435, 0x5830, + 0x5855, 0x746a, 0x4e39, 0x5661, 0x4f52, 0x5036, 0x4e22, 0x736e, + 0x7378, 0x5c4c, 0x504b, 0x7c24, 0x4d4a, 0x5754, 0x5e23, 0x6460, + 0x6e49, 0x625d, 0x757e, 0x542c, 0x5551, 0x5870, 0x7843, 0x6a57, + 0x7557, 0x583f, 0x7d40, 0x6b2d, 0x552a, 0x6728, 0x6e4a, 0x4a67, + 0x7863, 0x545d, 0x6a58, 0x7b59, 0x6d77, 0x6535, 0x502d, 0x7171, + 0x623d, 0x6348, 0x5955, 0x5f2a, 0x5b3c, 0x7864, 0x717a, 0x6536, + 0x736f, 0x7b5a, 0x6160, 0x592c, 0x756b, 0x6036, 0x6948, 0x4b4f, + 0x6349, 0x5e6e, 0x623e, 0x5c6f, 0x5625, 0x6271, 0x567e, 0x5921, + 0x5840, 0x5c5b, 0x6d3d, 0x5f38, 0x6a25, 0x572d, 0x7379, 0x6d78, + 0x7547, 0x614a, 0x6b63, 0x725e, 0x784c, 0x6a59, 0x5346, 0x5b66, + 0x752f, 0x4e70, 0x697e, 0x7b36, 0x6272, 0x4f72, 0x7739, 0x5973, + 0x614b, 0x5a5d, 0x5a39, 0x6b7b, 0x4b39, 0x6d79, 0x6060, 0x7440, + 0x7d3c, 0x5f31, 0x636f, 0x6023, 0x7d39, 0x7031, 0x4d4b, 0x6d3e, + 0x5540, 0x6370, 0x6d7a, 0x6964, 0x556d, 0x675d, 0x5476, 0x6537, + 0x5b67, 0x623f, 0x6e4b, 0x5774, 0x705d, 0x4e2b, 0x675e, 0x5656, + 0x614c, 0x6833, 0x656e, 0x5c22, 0x6050, 0x5535, 0x5521, 0x7b5b, + 0x794b, 0x4b73, 0x7425, 0x7a48, 0x5657, 0x6965, 0x7b5c, 0x7d50, + 0x7b76, 0x5a25, 0x5b3d, 0x6c62, 0x4d77, 0x705e, 0x7649, 0x5e6f, + 0x5331, 0x7c6e, 0x6843, 0x7148, 0x4e71, 0x796d, 0x7274, 0x6436, + 0x7539, 0x5c70, 0x6371, 0x6825, 0x723b, 0x5e24, 0x5a4c, 0x4a69, + 0x635a, 0x7c59, 0x6a5a, 0x7944, 0x6324, 0x7b5d, 0x6f4a, 0x6844, + 0x554c, 0x6b57, 0x592d, 0x7b2b, 0x5359, 0x5522, 0x765e, 0x5a76, + 0x6051, 0x6928, 0x7579, 0x7a2f, 0x6b7c, 0x606a, 0x6332, 0x5545, + 0x7163, 0x556e, 0x4d4c, 0x6d59, 0x5841, 0x7a6c, 0x716b, 0x7a3c, + 0x6662, 0x7a65, 0x627a, 0x4a36, 0x6437, 0x6a5b, 0x757a, 0x7b2c, + 0x4f43, 0x6b7d, 0x787a, 0x5f39, 0x6171, 0x5224, 0x757b, 0x505a, + 0x505b, 0x6a3e, 0x5931, 0x4a37, 0x5367, 0x7865, 0x5332, 0x6240, + 0x725f, 0x4d65, 0x792c, 0x4d4d, 0x6e2e, 0x562e, 0x576a, 0x6760, + 0x6b2e, 0x4f59, 0x5c4d, 0x6d7b, 0x5e70, 0x576b, 0x5e25, 0x5f57, + 0x5b50, 0x5b51, 0x5523, 0x7032, 0x5c5c, 0x4a68, 0x7866, 0x5c4e, + 0x6a5c, 0x5b52, 0x6933, 0x775b, 0x6328, 0x572e, 0x6061, 0x4b3a, + 0x6551, 0x505c, 0x5541, 0x584a, 0x6329, 0x6024, 0x6929, 0x5347, + 0x5c5d, 0x782e, 0x4c38, 0x502e, 0x5872, 0x634a, 0x4c2f, 0x542d, + 0x7651, 0x504c, 0x4a46, 0x5542, 0x4e3a, 0x4a47, 0x7a30, 0x5f58, + 0x753a, 0x656b, 0x6f74, 0x5d35, 0x4d2a, 0x6372, 0x7b77, 0x7750, + 0x7d3a, 0x7d61, 0x767e, 0x5140, 0x6845, 0x6438, 0x6168, 0x4c41, + 0x526d, 0x5b3e, 0x6062, 0x7a49, 0x614d, 0x4a38, 0x7260, 0x7149, + 0x5e71, 0x705f, 0x7844, 0x6e4c, 0x5e72, 0x6749, 0x6273, 0x6761, + 0x634b, 0x634c, 0x4f78, 0x6f2c, 0x7d7e, 0x7c25, 0x7a31, 0x5f59, + 0x6052, 0x745a, 0x714a, 0x4e23, 0x723c, 0x6c63, 0x6025, 0x772b, + 0x6b2f, 0x655e, 0x6124, 0x4d2b, 0x5974, 0x6826, 0x4d4e, 0x6169, + 0x7c6f, 0x6063, 0x6241, 0x4e24, 0x5e26, 0x6b7e, 0x6b5d, 0x7060, + 0x745b, 0x6274, 0x5348, 0x746b, 0x6e35, 0x7558, 0x555f, 0x5665, + 0x6b30, 0x7463, 0x634d, 0x7474, 0x7a32, 0x6f75, 0x4a5f, 0x6b31, + 0x6d3f, 0x7d49, 0x6426, 0x7924, 0x7033, 0x656c, 0x5167, 0x5947, + 0x6457, 0x6a5d, 0x5477, 0x5a3a, 0x5a4d, 0x794c, 0x615a, 0x5b3f, + 0x4c45, 0x6c50, 0x4b3b, 0x5e73, 0x692a, 0x5948, 0x6e63, 0x573d, + 0x4f44, 0x504d, 0x7c26, 0x717b, 0x7d52, 0x5141, 0x635b, 0x5349, + 0x5c4f, 0x4c6d, 0x5e27, 0x663b, 0x6c21, 0x4c39, 0x7b5e, 0x6762, + 0x5441, 0x5c28, 0x6242, 0x7358, 0x6553, 0x7359, 0x7346, 0x4d5b, + 0x4d2c, 0x7c43, 0x5467, 0x5142, 0x7925, 0x6855, 0x634e, 0x544a, + 0x5f5a, 0x7b5f, 0x6763, 0x787b, 0x634f, 0x7530, 0x5867, 0x5949, + 0x782f, 0x6f76, 0x5d36, 0x6e2f, 0x4d78, 0x5e38, 0x7c27, 0x777c, + 0x7731, 0x4e3b, 0x7421, 0x6e4d, 0x612e, 0x6c43, 0x4f7e, 0x783f, + 0x5862, 0x5368, 0x5e28, 0x7464, 0x6c42, 0x5975, 0x7945, 0x5d53, + 0x5671, 0x6c7c, 0x7c70, 0x6d40, 0x4a39, 0x6e64, 0x7261, 0x5e39, + 0x5672, 0x5e74, 0x5f5b, 0x5b53, 0x7a67, 0x5863, 0x7441, 0x5d37, + 0x7275, 0x542e, 0x5673, 0x5d38, 0x4f45, 0x5f5f, 0x723e, 0x7621, + 0x6b4b, 0x717c, 0x7347, 0x606b, 0x6d7c, 0x615b, 0x6e65, 0x5e75, + 0x7a53, 0x714b, 0x502f, 0x5d39, 0x5143, 0x7531, 0x6a46, 0x7061, + 0x762c, 0x7559, 0x706b, 0x5d3a, 0x723f, 0x7745, 0x5b22, 0x7276, + 0x4a3a, 0x7775, 0x4b65, 0x6e66, 0x6053, 0x4e25, 0x5658, 0x542f, + 0x6949, 0x534e, 0x7442, 0x4b66, 0x7121, 0x6b32, 0x7122, 0x6b33, + 0x7034, 0x4b74, 0x5430, 0x7332, 0x7b37, 0x756c, 0x6e67, 0x7432, + 0x756d, 0x4f73, 0x7062, 0x6e4e, 0x714c, 0x6538, 0x5775, 0x6373, + 0x4f65, 0x4f46, 0x7333, 0x6458, 0x4f79, 0x4f5a, 0x7a4d, 0x6663, + 0x7262, 0x756e, 0x4a3b, 0x635c, 0x4e72, 0x5659, 0x6e30, 0x7465, + 0x5842, 0x5c50, 0x4c6e, 0x5560, 0x764a, 0x7d4a, 0x5856, 0x744f, + 0x5626, 0x5c3e, 0x5b54, 0x5747, 0x727e, 0x714d, 0x6243, 0x5c5e, + 0x5c5f, 0x6f2d, 0x662b, 0x795d, 0x6a3f, 0x6f2e, 0x7450, 0x4e73, + 0x662c, 0x4e5e, 0x5579, 0x6374, 0x4d50, 0x5538, 0x777d, 0x5c29, + 0x5e76, 0x5c2a, 0x7263, 0x6934, 0x525c, 0x6966, 0x6376, 0x674a, + 0x504e, 0x5a77, 0x4a3c, 0x6e68, 0x5a5e, 0x7277, 0x627b, 0x4c26, + 0x5a3b, 0x6e69, 0x755a, 0x775c, 0x616a, 0x4e41, 0x5431, 0x7d31, + 0x663d, 0x7b2d, 0x7867, 0x614e, 0x7762, 0x756f, 0x4f47, 0x5432, + 0x4c6f, 0x5468, 0x6e4f, 0x7757, 0x6026, 0x5641, 0x615c, 0x7063, + 0x7164, 0x5c71, 0x5627, 0x7475, 0x714e, 0x7264, 0x5030, 0x6c6f, + 0x793a, 0x6b35, 0x546d, 0x6244, 0x6967, 0x6b34, 0x6a21, 0x783c, + 0x4e26, 0x7946, 0x7c5a, 0x5433, 0x5339, 0x6a5e, 0x692b, 0x6161, + 0x534f, 0x7476, 0x6a40, 0x614f, 0x4c3a, 0x6e6a, 0x7064, 0x7334, + 0x546e, 0x7240, 0x7165, 0x7443, 0x6054, 0x6b36, 0x5721, 0x4b68, + 0x792d, 0x692d, 0x5864, 0x7a33, 0x6245, 0x7c3d, 0x6c44, 0x5831, + 0x5c2b, 0x5524, 0x6b69, 0x683b, 0x5857, 0x7b2e, 0x5161, 0x5b40, + 0x753e, 0x5e77, 0x4a7b, 0x7746, 0x4f48, 0x6150, 0x6e50, 0x6974, + 0x4e74, 0x554d, 0x4f5b, 0x5d3b, 0x4e2c, 0x6968, 0x5434, 0x6447, + 0x755b, 0x7a41, 0x5e29, 0x5478, 0x6f77, 0x5333, 0x6b37, 0x6f78, + 0x755c, 0x6d4c, 0x5b55, 0x714f, 0x7150, 0x7532, 0x592e, 0x552c, + 0x6246, 0x7d23, 0x7b65, 0x5f2b, 0x6275, 0x762d, 0x7533, 0x7035, + 0x6125, 0x755d, 0x6c22, 0x6d7d, 0x7534, 0x7b38, 0x5b23, 0x564a, + 0x4b59, 0x6554, 0x737a, 0x6b38, 0x6037, 0x576c, 0x716c, 0x652f, + 0x5561, 0x576d, 0x5151, 0x6172, 0x6f79, 0x5d3c, 0x765c, 0x7065, + 0x7444, 0x6969, 0x737b, 0x546f, 0x4c22, 0x777e, 0x5f3c, 0x6b4d, + 0x5037, 0x5642, 0x682d, 0x6f2f, 0x4b25, 0x4b69, 0x7a68, 0x4c46, + 0x6667, 0x6a47, 0x5b24, 0x4f49, 0x627c, 0x6f7a, 0x6b5e, 0x7548, + 0x545e, 0x6055, 0x6f30, 0x6247, 0x592f, 0x7967, 0x6765, 0x4f4a, + 0x6151, 0x6248, 0x6f7b, 0x7a79, 0x5c72, 0x6027, 0x7868, 0x4b6a, + 0x4b3c, 0x5662, 0x755e, 0x755f, 0x6e36, 0x6276, 0x534a, 0x6f7c, + 0x5144, 0x6f31, 0x5145, 0x505e, 0x5961, 0x6038, 0x4d51, 0x7339, + 0x674c, 0x5628, 0x4e27, 0x5435, 0x6448, 0x5334, 0x6b39, 0x4b75, + 0x765d, 0x7123, 0x4c47, 0x694a, 0x6170, 0x7560, 0x7b2f, 0x4b51, + 0x7b60, 0x7265, 0x6c70, 0x706c, 0x6e6b, 0x694b, 0x4c70, 0x572f, + 0x7321, 0x7c75, 0x7124, 0x6056, 0x6f32, 0x7451, 0x7721, 0x7151, + 0x4a7c, 0x4a7d, 0x4e4e, 0x7348, 0x733a, 0x6d7e, 0x5a26, 0x606c, + 0x784d, 0x4b52, 0x6b4e, 0x7958, 0x7959, 0x4a60, 0x5a4a, 0x4b26, + 0x4a48, 0x796e, 0x5b6c, 0x5031, 0x556f, 0x6673, 0x6722, 0x6459, + 0x6461, 0x7c44, 0x796f, 0x4f74, 0x7766, 0x4e3c, 0x7445, 0x5c23, + 0x5d3d, 0x7446, 0x7821, 0x6856, 0x5b41, 0x7066, 0x6439, 0x766d, + 0x792e, 0x5d3e, 0x5730, 0x5868, 0x4b3d, 0x795a, 0x784e, 0x7970, + 0x606d, 0x6333, 0x7433, 0x6a42, 0x7266, 0x7036, 0x5b56, 0x6b64, + 0x7267, 0x5755, 0x5436, 0x7968, 0x5741, 0x6555, 0x696a, 0x574c, + 0x5369, 0x6249, 0x7c5b, 0x4d2d, 0x4c30, 0x6a22, 0x6476, 0x5040, + 0x7037, 0x6e21, 0x5776, 0x624a, 0x624b, 0x7a4f, 0x6b5f, 0x564b, + 0x7434, 0x6d4d, 0x6452, 0x6a29, 0x643a, 0x7322, 0x4d52, 0x764b, + 0x7166, 0x6d41, 0x683c, 0x6e51, 0x7067, 0x624c, 0x642a, 0x7561, + 0x6d5a, 0x576e, 0x5171, 0x696b, 0x696c, 0x6064, 0x5a27, 0x5d54, + 0x6a23, 0x5643, 0x5674, 0x5a5f, 0x6f33, 0x624d, 0x6f7d, 0x7268, + 0x6f45, 0x6767, 0x577d, 0x674e, 0x5f5c, 0x7947, 0x5976, 0x5f2c, + 0x565a, 0x5c24, 0x7038, 0x557a, 0x6477, 0x5644, 0x746c, 0x6f7e, + 0x7021, 0x5e2a, 0x5a3c, 0x587c, 0x7a54, 0x6c65, 0x7c28, 0x6c66, + 0x584b, 0x7b39, 0x6453, 0x4d79, 0x4f53, 0x4a6a, 0x4f54, 0x783d, + 0x7447, 0x6a5f, 0x795b, 0x5437, 0x6b65, 0x6152, 0x6a24, 0x7a42, + 0x7b61, 0x7a6d, 0x7022, 0x4c71, 0x7a23, 0x6277, 0x624e, 0x6975, + 0x616b, 0x6768, 0x6857, 0x5a78, 0x544b, 0x7776, 0x5645, 0x5469, + 0x7a7a, 0x4c72, 0x775d, 0x5e3a, 0x4e28, 0x7039, 0x647e, 0x6449, + 0x6454, 0x6a43, 0x6f34, 0x573e, 0x7b62, 0x4d53, 0x6f35, 0x7a69, + 0x7926, 0x5f3d, 0x7747, 0x787d, 0x787c, 0x5e2b, 0x5b68, 0x635d, + 0x6162, 0x5146, 0x7650, 0x6b66, 0x5a79, 0x6c47, 0x5e78, 0x7869, + 0x635e, 0x4e75, 0x7a43, 0x6557, 0x6c48, 0x7349, 0x643b, 0x662e, + 0x6f36, 0x5c3f, 0x4e3d, 0x5843, 0x504f, 0x4f7a, 0x734a, 0x6057, + 0x5147, 0x692e, 0x683d, 0x7a44, 0x624f, 0x7a45, 0x7938, 0x5c60, + 0x7b30, 0x5829, 0x655f, 0x7927, 0x766e, 0x764c, 0x6278, 0x6c71, + 0x5a60, 0x7152, 0x524c, 0x4f4b, 0x4a3d, 0x5d3f, 0x766f, 0x5e79, + 0x7a34, 0x552d, 0x7167, 0x5e3e, 0x5c40, 0x5148, 0x5149, 0x783e, + 0x4b76, 0x5479, 0x7562, 0x6153, 0x5869, 0x787e, 0x4f4c, 0x7d24, + 0x4e76, 0x7a50, 0x4c73, 0x663e, 0x762e, 0x5570, 0x514a, 0x7c3e, + 0x5571, 0x4d69, 0x7a35, 0x6250, 0x7477, 0x4d54, 0x6723, 0x5b25, + 0x6251, 0x5722, 0x7763, 0x6a26, 0x5021, 0x4e5a, 0x7b6b, 0x5b26, + 0x5b5e, 0x5865, 0x6a60, 0x582a, 0x6560, 0x565b, 0x6f46, 0x786a, + 0x6455, 0x4e77, 0x6058, 0x576f, 0x746d, 0x4d66, 0x4c74, 0x7563, + 0x644a, 0x5c61, 0x7948, 0x7c3f, 0x6827, 0x5844, 0x4b3e, 0x5c2e, + 0x5777, 0x7068, 0x5d40, 0x4f4d, 0x5c73, 0x5930, 0x6669, 0x643c, + 0x6a44, 0x646c, 0x6465, 0x7b78, 0x4c3b, 0x643d, 0x4d5c, 0x5977, + 0x5d5f, 0x6d4e, 0x5950, 0x6523, 0x794d, 0x4d2e, 0x4f4e, 0x762f, + 0x7d53, 0x6b6d, 0x565c, 0x6524, 0x5536, 0x565d, 0x7969, 0x6724, + 0x5663, 0x514b, 0x5664, 0x5572, 0x5e7a, 0x5778, 0x586a, 0x4f55, + 0x587d, 0x582b, 0x7d4b, 0x7c5c, 0x6028, 0x5573, 0x7d59, 0x4c23, + 0x5979, 0x536a, 0x7575, 0x6f47, 0x535a, 0x5a3d, 0x6828, 0x5c2f, + 0x7023, 0x4d55, 0x6029, 0x5e2c, 0x703a, 0x6e31, 0x6e32, 0x764d, + 0x6e52, 0x5646, 0x6065, 0x733b, 0x6561, 0x644b, 0x5723, 0x5b42, + 0x4a7e, 0x4f4f, 0x3021, 0x3022, 0x3023, 0x3024, 0x3025, 0x3026, + 0x3027, 0x3028, 0x3029, 0x302a, 0x302b, 0x302c, 0x302d, 0x302e, + 0x302f, 0x3030, 0x3031, 0x3032, 0x3033, 0x3034, 0x3035, 0x3036, + 0x3037, 0x3038, 0x3039, 0x303a, 0x303b, 0x303c, 0x303d, 0x303e, + 0x303f, 0x3040, 0x3041, 0x3042, 0x3043, 0x3044, 0x3045, 0x3046, + 0x3047, 0x3048, 0x3049, 0x304a, 0x304b, 0x304c, 0x304d, 0x304e, + 0x304f, 0x3050, 0x3051, 0x3052, 0x3053, 0x3054, 0x3055, 0x3056, + 0x3057, 0x3058, 0x3059, 0x305a, 0x305b, 0x305c, 0x305d, 0x305e, + 0x305f, 0x3060, 0x3061, 0x3062, 0x3063, 0x3064, 0x3065, 0x3066, + 0x3067, 0x3068, 0x3069, 0x306a, 0x306b, 0x306c, 0x306d, 0x306e, + 0x306f, 0x3070, 0x3071, 0x3072, 0x3073, 0x3074, 0x3075, 0x3076, + 0x3077, 0x3078, 0x3079, 0x307a, 0x307b, 0x307c, 0x307d, 0x307e, + 0x3121, 0x3122, 0x3123, 0x3124, 0x3125, 0x3126, 0x3127, 0x3128, + 0x3129, 0x312a, 0x312b, 0x312c, 0x312d, 0x312e, 0x312f, 0x3130, + 0x3131, 0x3132, 0x3133, 0x3134, 0x3135, 0x3136, 0x3137, 0x3138, + 0x3139, 0x313a, 0x313b, 0x313c, 0x313d, 0x313e, 0x313f, 0x3140, + 0x3141, 0x3142, 0x3143, 0x3144, 0x3145, 0x3146, 0x3147, 0x3148, + 0x3149, 0x314a, 0x314b, 0x314c, 0x314d, 0x314e, 0x314f, 0x3150, + 0x3151, 0x3152, 0x3153, 0x3154, 0x3155, 0x3156, 0x3157, 0x3158, + 0x3159, 0x315a, 0x315b, 0x315c, 0x315d, 0x315e, 0x315f, 0x3160, + 0x3161, 0x3162, 0x3163, 0x3164, 0x3165, 0x3166, 0x3167, 0x3168, + 0x3169, 0x316a, 0x316b, 0x316c, 0x316d, 0x316e, 0x316f, 0x3170, + 0x3171, 0x3172, 0x3173, 0x3174, 0x3175, 0x3176, 0x3177, 0x3178, + 0x3179, 0x317a, 0x317b, 0x317c, 0x317d, 0x317e, 0x3221, 0x3222, + 0x3223, 0x3224, 0x3225, 0x3226, 0x3227, 0x3228, 0x3229, 0x322a, + 0x322b, 0x322c, 0x322d, 0x322e, 0x322f, 0x3230, 0x3231, 0x3232, + 0x3233, 0x3234, 0x3235, 0x3236, 0x3237, 0x3238, 0x3239, 0x323a, + 0x323b, 0x323c, 0x323d, 0x323e, 0x323f, 0x3240, 0x3241, 0x3242, + 0x3243, 0x3244, 0x3245, 0x3246, 0x3247, 0x3248, 0x3249, 0x324a, + 0x324b, 0x324c, 0x324d, 0x324e, 0x324f, 0x3250, 0x3251, 0x3252, + 0x3253, 0x3254, 0x3255, 0x3256, 0x3257, 0x3258, 0x3259, 0x325a, + 0x325b, 0x325c, 0x325d, 0x325e, 0x325f, 0x3260, 0x3261, 0x3262, + 0x3263, 0x3264, 0x3265, 0x3266, 0x3267, 0x3268, 0x3269, 0x326a, + 0x326b, 0x326c, 0x326d, 0x326e, 0x326f, 0x3270, 0x3271, 0x3272, + 0x3273, 0x3274, 0x3275, 0x3276, 0x3277, 0x3278, 0x3279, 0x327a, + 0x327b, 0x327c, 0x327d, 0x327e, 0x3321, 0x3322, 0x3323, 0x3324, + 0x3325, 0x3326, 0x3327, 0x3328, 0x3329, 0x332a, 0x332b, 0x332c, + 0x332d, 0x332e, 0x332f, 0x3330, 0x3331, 0x3332, 0x3333, 0x3334, + 0x3335, 0x3336, 0x3337, 0x3338, 0x3339, 0x333a, 0x333b, 0x333c, + 0x333d, 0x333e, 0x333f, 0x3340, 0x3341, 0x3342, 0x3343, 0x3344, + 0x3345, 0x3346, 0x3347, 0x3348, 0x3349, 0x334a, 0x334b, 0x334c, + 0x334d, 0x334e, 0x334f, 0x3350, 0x3351, 0x3352, 0x3353, 0x3354, + 0x3355, 0x3356, 0x3357, 0x3358, 0x3359, 0x335a, 0x335b, 0x335c, + 0x335d, 0x335e, 0x335f, 0x3360, 0x3361, 0x3362, 0x3363, 0x3364, + 0x3365, 0x3366, 0x3367, 0x3368, 0x3369, 0x336a, 0x336b, 0x336c, + 0x336d, 0x336e, 0x336f, 0x3370, 0x3371, 0x3372, 0x3373, 0x3374, + 0x3375, 0x3376, 0x3377, 0x3378, 0x3379, 0x337a, 0x337b, 0x337c, + 0x337d, 0x337e, 0x3421, 0x3422, 0x3423, 0x3424, 0x3425, 0x3426, + 0x3427, 0x3428, 0x3429, 0x342a, 0x342b, 0x342c, 0x342d, 0x342e, + 0x342f, 0x3430, 0x3431, 0x3432, 0x3433, 0x3434, 0x3435, 0x3436, + 0x3437, 0x3438, 0x3439, 0x343a, 0x343b, 0x343c, 0x343d, 0x343e, + 0x343f, 0x3440, 0x3441, 0x3442, 0x3443, 0x3444, 0x3445, 0x3446, + 0x3447, 0x3448, 0x3449, 0x344a, 0x344b, 0x344c, 0x344d, 0x344e, + 0x344f, 0x3450, 0x3451, 0x3452, 0x3453, 0x3454, 0x3455, 0x3456, + 0x3457, 0x3458, 0x3459, 0x345a, 0x345b, 0x345c, 0x345d, 0x345e, + 0x345f, 0x3460, 0x3461, 0x3462, 0x3463, 0x3464, 0x3465, 0x3466, + 0x3467, 0x3468, 0x3469, 0x346a, 0x346b, 0x346c, 0x346d, 0x346e, + 0x346f, 0x3470, 0x3471, 0x3472, 0x3473, 0x3474, 0x3475, 0x3476, + 0x3477, 0x3478, 0x3479, 0x347a, 0x347b, 0x347c, 0x347d, 0x347e, + 0x3521, 0x3522, 0x3523, 0x3524, 0x3525, 0x3526, 0x3527, 0x3528, + 0x3529, 0x352a, 0x352b, 0x352c, 0x352d, 0x352e, 0x352f, 0x3530, + 0x3531, 0x3532, 0x3533, 0x3534, 0x3535, 0x3536, 0x3537, 0x3538, + 0x3539, 0x353a, 0x353b, 0x353c, 0x353d, 0x353e, 0x353f, 0x3540, + 0x3541, 0x3542, 0x3543, 0x3544, 0x3545, 0x3546, 0x3547, 0x3548, + 0x3549, 0x354a, 0x354b, 0x354c, 0x354d, 0x354e, 0x354f, 0x3550, + 0x3551, 0x3552, 0x3553, 0x3554, 0x3555, 0x3556, 0x3557, 0x3558, + 0x3559, 0x355a, 0x355b, 0x355c, 0x355d, 0x355e, 0x355f, 0x3560, + 0x3561, 0x3562, 0x3563, 0x3564, 0x3565, 0x3566, 0x3567, 0x3568, + 0x3569, 0x356a, 0x356b, 0x356c, 0x356d, 0x356e, 0x356f, 0x3570, + 0x3571, 0x3572, 0x3573, 0x3574, 0x3575, 0x3576, 0x3577, 0x3578, + 0x3579, 0x357a, 0x357b, 0x357c, 0x357d, 0x357e, 0x3621, 0x3622, + 0x3623, 0x3624, 0x3625, 0x3626, 0x3627, 0x3628, 0x3629, 0x362a, + 0x362b, 0x362c, 0x362d, 0x362e, 0x362f, 0x3630, 0x3631, 0x3632, + 0x3633, 0x3634, 0x3635, 0x3636, 0x3637, 0x3638, 0x3639, 0x363a, + 0x363b, 0x363c, 0x363d, 0x363e, 0x363f, 0x3640, 0x3641, 0x3642, + 0x3643, 0x3644, 0x3645, 0x3646, 0x3647, 0x3648, 0x3649, 0x364a, + 0x364b, 0x364c, 0x364d, 0x364e, 0x364f, 0x3650, 0x3651, 0x3652, + 0x3653, 0x3654, 0x3655, 0x3656, 0x3657, 0x3658, 0x3659, 0x365a, + 0x365b, 0x365c, 0x365d, 0x365e, 0x365f, 0x3660, 0x3661, 0x3662, + 0x3663, 0x3664, 0x3665, 0x3666, 0x3667, 0x3668, 0x3669, 0x366a, + 0x366b, 0x366c, 0x366d, 0x366e, 0x366f, 0x3670, 0x3671, 0x3672, + 0x3673, 0x3674, 0x3675, 0x3676, 0x3677, 0x3678, 0x3679, 0x367a, + 0x367b, 0x367c, 0x367d, 0x367e, 0x3721, 0x3722, 0x3723, 0x3724, + 0x3725, 0x3726, 0x3727, 0x3728, 0x3729, 0x372a, 0x372b, 0x372c, + 0x372d, 0x372e, 0x372f, 0x3730, 0x3731, 0x3732, 0x3733, 0x3734, + 0x3735, 0x3736, 0x3737, 0x3738, 0x3739, 0x373a, 0x373b, 0x373c, + 0x373d, 0x373e, 0x373f, 0x3740, 0x3741, 0x3742, 0x3743, 0x3744, + 0x3745, 0x3746, 0x3747, 0x3748, 0x3749, 0x374a, 0x374b, 0x374c, + 0x374d, 0x374e, 0x374f, 0x3750, 0x3751, 0x3752, 0x3753, 0x3754, + 0x3755, 0x3756, 0x3757, 0x3758, 0x3759, 0x375a, 0x375b, 0x375c, + 0x375d, 0x375e, 0x375f, 0x3760, 0x3761, 0x3762, 0x3763, 0x3764, + 0x3765, 0x3766, 0x3767, 0x3768, 0x3769, 0x376a, 0x376b, 0x376c, + 0x376d, 0x376e, 0x376f, 0x3770, 0x3771, 0x3772, 0x3773, 0x3774, + 0x3775, 0x3776, 0x3777, 0x3778, 0x3779, 0x377a, 0x377b, 0x377c, + 0x377d, 0x377e, 0x3821, 0x3822, 0x3823, 0x3824, 0x3825, 0x3826, + 0x3827, 0x3828, 0x3829, 0x382a, 0x382b, 0x382c, 0x382d, 0x382e, + 0x382f, 0x3830, 0x3831, 0x3832, 0x3833, 0x3834, 0x3835, 0x3836, + 0x3837, 0x3838, 0x3839, 0x383a, 0x383b, 0x383c, 0x383d, 0x383e, + 0x383f, 0x3840, 0x3841, 0x3842, 0x3843, 0x3844, 0x3845, 0x3846, + 0x3847, 0x3848, 0x3849, 0x384a, 0x384b, 0x384c, 0x384d, 0x384e, + 0x384f, 0x3850, 0x3851, 0x3852, 0x3853, 0x3854, 0x3855, 0x3856, + 0x3857, 0x3858, 0x3859, 0x385a, 0x385b, 0x385c, 0x385d, 0x385e, + 0x385f, 0x3860, 0x3861, 0x3862, 0x3863, 0x3864, 0x3865, 0x3866, + 0x3867, 0x3868, 0x3869, 0x386a, 0x386b, 0x386c, 0x386d, 0x386e, + 0x386f, 0x3870, 0x3871, 0x3872, 0x3873, 0x3874, 0x3875, 0x3876, + 0x3877, 0x3878, 0x3879, 0x387a, 0x387b, 0x387c, 0x387d, 0x387e, + 0x3921, 0x3922, 0x3923, 0x3924, 0x3925, 0x3926, 0x3927, 0x3928, + 0x3929, 0x392a, 0x392b, 0x392c, 0x392d, 0x392e, 0x392f, 0x3930, + 0x3931, 0x3932, 0x3933, 0x3934, 0x3935, 0x3936, 0x3937, 0x3938, + 0x3939, 0x393a, 0x393b, 0x393c, 0x393d, 0x393e, 0x393f, 0x3940, + 0x3941, 0x3942, 0x3943, 0x3944, 0x3945, 0x3946, 0x3947, 0x3948, + 0x3949, 0x394a, 0x394b, 0x394c, 0x394d, 0x394e, 0x394f, 0x3950, + 0x3951, 0x3952, 0x3953, 0x3954, 0x3955, 0x3956, 0x3957, 0x3958, + 0x3959, 0x395a, 0x395b, 0x395c, 0x395d, 0x395e, 0x395f, 0x3960, + 0x3961, 0x3962, 0x3963, 0x3964, 0x3965, 0x3966, 0x3967, 0x3968, + 0x3969, 0x396a, 0x396b, 0x396c, 0x396d, 0x396e, 0x396f, 0x3970, + 0x3971, 0x3972, 0x3973, 0x3974, 0x3975, 0x3976, 0x3977, 0x3978, + 0x3979, 0x397a, 0x397b, 0x397c, 0x397d, 0x397e, 0x3a21, 0x3a22, + 0x3a23, 0x3a24, 0x3a25, 0x3a26, 0x3a27, 0x3a28, 0x3a29, 0x3a2a, + 0x3a2b, 0x3a2c, 0x3a2d, 0x3a2e, 0x3a2f, 0x3a30, 0x3a31, 0x3a32, + 0x3a33, 0x3a34, 0x3a35, 0x3a36, 0x3a37, 0x3a38, 0x3a39, 0x3a3a, + 0x3a3b, 0x3a3c, 0x3a3d, 0x3a3e, 0x3a3f, 0x3a40, 0x3a41, 0x3a42, + 0x3a43, 0x3a44, 0x3a45, 0x3a46, 0x3a47, 0x3a48, 0x3a49, 0x3a4a, + 0x3a4b, 0x3a4c, 0x3a4d, 0x3a4e, 0x3a4f, 0x3a50, 0x3a51, 0x3a52, + 0x3a53, 0x3a54, 0x3a55, 0x3a56, 0x3a57, 0x3a58, 0x3a59, 0x3a5a, + 0x3a5b, 0x3a5c, 0x3a5d, 0x3a5e, 0x3a5f, 0x3a60, 0x3a61, 0x3a62, + 0x3a63, 0x3a64, 0x3a65, 0x3a66, 0x3a67, 0x3a68, 0x3a69, 0x3a6a, + 0x3a6b, 0x3a6c, 0x3a6d, 0x3a6e, 0x3a6f, 0x3a70, 0x3a71, 0x3a72, + 0x3a73, 0x3a74, 0x3a75, 0x3a76, 0x3a77, 0x3a78, 0x3a79, 0x3a7a, + 0x3a7b, 0x3a7c, 0x3a7d, 0x3a7e, 0x3b21, 0x3b22, 0x3b23, 0x3b24, + 0x3b25, 0x3b26, 0x3b27, 0x3b28, 0x3b29, 0x3b2a, 0x3b2b, 0x3b2c, + 0x3b2d, 0x3b2e, 0x3b2f, 0x3b30, 0x3b31, 0x3b32, 0x3b33, 0x3b34, + 0x3b35, 0x3b36, 0x3b37, 0x3b38, 0x3b39, 0x3b3a, 0x3b3b, 0x3b3c, + 0x3b3d, 0x3b3e, 0x3b3f, 0x3b40, 0x3b41, 0x3b42, 0x3b43, 0x3b44, + 0x3b45, 0x3b46, 0x3b47, 0x3b48, 0x3b49, 0x3b4a, 0x3b4b, 0x3b4c, + 0x3b4d, 0x3b4e, 0x3b4f, 0x3b50, 0x3b51, 0x3b52, 0x3b53, 0x3b54, + 0x3b55, 0x3b56, 0x3b57, 0x3b58, 0x3b59, 0x3b5a, 0x3b5b, 0x3b5c, + 0x3b5d, 0x3b5e, 0x3b5f, 0x3b60, 0x3b61, 0x3b62, 0x3b63, 0x3b64, + 0x3b65, 0x3b66, 0x3b67, 0x3b68, 0x3b69, 0x3b6a, 0x3b6b, 0x3b6c, + 0x3b6d, 0x3b6e, 0x3b6f, 0x3b70, 0x3b71, 0x3b72, 0x3b73, 0x3b74, + 0x3b75, 0x3b76, 0x3b77, 0x3b78, 0x3b79, 0x3b7a, 0x3b7b, 0x3b7c, + 0x3b7d, 0x3b7e, 0x3c21, 0x3c22, 0x3c23, 0x3c24, 0x3c25, 0x3c26, + 0x3c27, 0x3c28, 0x3c29, 0x3c2a, 0x3c2b, 0x3c2c, 0x3c2d, 0x3c2e, + 0x3c2f, 0x3c30, 0x3c31, 0x3c32, 0x3c33, 0x3c34, 0x3c35, 0x3c36, + 0x3c37, 0x3c38, 0x3c39, 0x3c3a, 0x3c3b, 0x3c3c, 0x3c3d, 0x3c3e, + 0x3c3f, 0x3c40, 0x3c41, 0x3c42, 0x3c43, 0x3c44, 0x3c45, 0x3c46, + 0x3c47, 0x3c48, 0x3c49, 0x3c4a, 0x3c4b, 0x3c4c, 0x3c4d, 0x3c4e, + 0x3c4f, 0x3c50, 0x3c51, 0x3c52, 0x3c53, 0x3c54, 0x3c55, 0x3c56, + 0x3c57, 0x3c58, 0x3c59, 0x3c5a, 0x3c5b, 0x3c5c, 0x3c5d, 0x3c5e, + 0x3c5f, 0x3c60, 0x3c61, 0x3c62, 0x3c63, 0x3c64, 0x3c65, 0x3c66, + 0x3c67, 0x3c68, 0x3c69, 0x3c6a, 0x3c6b, 0x3c6c, 0x3c6d, 0x3c6e, + 0x3c6f, 0x3c70, 0x3c71, 0x3c72, 0x3c73, 0x3c74, 0x3c75, 0x3c76, + 0x3c77, 0x3c78, 0x3c79, 0x3c7a, 0x3c7b, 0x3c7c, 0x3c7d, 0x3c7e, + 0x3d21, 0x3d22, 0x3d23, 0x3d24, 0x3d25, 0x3d26, 0x3d27, 0x3d28, + 0x3d29, 0x3d2a, 0x3d2b, 0x3d2c, 0x3d2d, 0x3d2e, 0x3d2f, 0x3d30, + 0x3d31, 0x3d32, 0x3d33, 0x3d34, 0x3d35, 0x3d36, 0x3d37, 0x3d38, + 0x3d39, 0x3d3a, 0x3d3b, 0x3d3c, 0x3d3d, 0x3d3e, 0x3d3f, 0x3d40, + 0x3d41, 0x3d42, 0x3d43, 0x3d44, 0x3d45, 0x3d46, 0x3d47, 0x3d48, + 0x3d49, 0x3d4a, 0x3d4b, 0x3d4c, 0x3d4d, 0x3d4e, 0x3d4f, 0x3d50, + 0x3d51, 0x3d52, 0x3d53, 0x3d54, 0x3d55, 0x3d56, 0x3d57, 0x3d58, + 0x3d59, 0x3d5a, 0x3d5b, 0x3d5c, 0x3d5d, 0x3d5e, 0x3d5f, 0x3d60, + 0x3d61, 0x3d62, 0x3d63, 0x3d64, 0x3d65, 0x3d66, 0x3d67, 0x3d68, + 0x3d69, 0x3d6a, 0x3d6b, 0x3d6c, 0x3d6d, 0x3d6e, 0x3d6f, 0x3d70, + 0x3d71, 0x3d72, 0x3d73, 0x3d74, 0x3d75, 0x3d76, 0x3d77, 0x3d78, + 0x3d79, 0x3d7a, 0x3d7b, 0x3d7c, 0x3d7d, 0x3d7e, 0x3e21, 0x3e22, + 0x3e23, 0x3e24, 0x3e25, 0x3e26, 0x3e27, 0x3e28, 0x3e29, 0x3e2a, + 0x3e2b, 0x3e2c, 0x3e2d, 0x3e2e, 0x3e2f, 0x3e30, 0x3e31, 0x3e32, + 0x3e33, 0x3e34, 0x3e35, 0x3e36, 0x3e37, 0x3e38, 0x3e39, 0x3e3a, + 0x3e3b, 0x3e3c, 0x3e3d, 0x3e3e, 0x3e3f, 0x3e40, 0x3e41, 0x3e42, + 0x3e43, 0x3e44, 0x3e45, 0x3e46, 0x3e47, 0x3e48, 0x3e49, 0x3e4a, + 0x3e4b, 0x3e4c, 0x3e4d, 0x3e4e, 0x3e4f, 0x3e50, 0x3e51, 0x3e52, + 0x3e53, 0x3e54, 0x3e55, 0x3e56, 0x3e57, 0x3e58, 0x3e59, 0x3e5a, + 0x3e5b, 0x3e5c, 0x3e5d, 0x3e5e, 0x3e5f, 0x3e60, 0x3e61, 0x3e62, + 0x3e63, 0x3e64, 0x3e65, 0x3e66, 0x3e67, 0x3e68, 0x3e69, 0x3e6a, + 0x3e6b, 0x3e6c, 0x3e6d, 0x3e6e, 0x3e6f, 0x3e70, 0x3e71, 0x3e72, + 0x3e73, 0x3e74, 0x3e75, 0x3e76, 0x3e77, 0x3e78, 0x3e79, 0x3e7a, + 0x3e7b, 0x3e7c, 0x3e7d, 0x3e7e, 0x3f21, 0x3f22, 0x3f23, 0x3f24, + 0x3f25, 0x3f26, 0x3f27, 0x3f28, 0x3f29, 0x3f2a, 0x3f2b, 0x3f2c, + 0x3f2d, 0x3f2e, 0x3f2f, 0x3f30, 0x3f31, 0x3f32, 0x3f33, 0x3f34, + 0x3f35, 0x3f36, 0x3f37, 0x3f38, 0x3f39, 0x3f3a, 0x3f3b, 0x3f3c, + 0x3f3d, 0x3f3e, 0x3f3f, 0x3f40, 0x3f41, 0x3f42, 0x3f43, 0x3f44, + 0x3f45, 0x3f46, 0x3f47, 0x3f48, 0x3f49, 0x3f4a, 0x3f4b, 0x3f4c, + 0x3f4d, 0x3f4e, 0x3f4f, 0x3f50, 0x3f51, 0x3f52, 0x3f53, 0x3f54, + 0x3f55, 0x3f56, 0x3f57, 0x3f58, 0x3f59, 0x3f5a, 0x3f5b, 0x3f5c, + 0x3f5d, 0x3f5e, 0x3f5f, 0x3f60, 0x3f61, 0x3f62, 0x3f63, 0x3f64, + 0x3f65, 0x3f66, 0x3f67, 0x3f68, 0x3f69, 0x3f6a, 0x3f6b, 0x3f6c, + 0x3f6d, 0x3f6e, 0x3f6f, 0x3f70, 0x3f71, 0x3f72, 0x3f73, 0x3f74, + 0x3f75, 0x3f76, 0x3f77, 0x3f78, 0x3f79, 0x3f7a, 0x3f7b, 0x3f7c, + 0x3f7d, 0x3f7e, 0x4021, 0x4022, 0x4023, 0x4024, 0x4025, 0x4026, + 0x4027, 0x4028, 0x4029, 0x402a, 0x402b, 0x402c, 0x402d, 0x402e, + 0x402f, 0x4030, 0x4031, 0x4032, 0x4033, 0x4034, 0x4035, 0x4036, + 0x4037, 0x4038, 0x4039, 0x403a, 0x403b, 0x403c, 0x403d, 0x403e, + 0x403f, 0x4040, 0x4041, 0x4042, 0x4043, 0x4044, 0x4045, 0x4046, + 0x4047, 0x4048, 0x4049, 0x404a, 0x404b, 0x404c, 0x404d, 0x404e, + 0x404f, 0x4050, 0x4051, 0x4052, 0x4053, 0x4054, 0x4055, 0x4056, + 0x4057, 0x4058, 0x4059, 0x405a, 0x405b, 0x405c, 0x405d, 0x405e, + 0x405f, 0x4060, 0x4061, 0x4062, 0x4063, 0x4064, 0x4065, 0x4066, + 0x4067, 0x4068, 0x4069, 0x406a, 0x406b, 0x406c, 0x406d, 0x406e, + 0x406f, 0x4070, 0x4071, 0x4072, 0x4073, 0x4074, 0x4075, 0x4076, + 0x4077, 0x4078, 0x4079, 0x407a, 0x407b, 0x407c, 0x407d, 0x407e, + 0x4121, 0x4122, 0x4123, 0x4124, 0x4125, 0x4126, 0x4127, 0x4128, + 0x4129, 0x412a, 0x412b, 0x412c, 0x412d, 0x412e, 0x412f, 0x4130, + 0x4131, 0x4132, 0x4133, 0x4134, 0x4135, 0x4136, 0x4137, 0x4138, + 0x4139, 0x413a, 0x413b, 0x413c, 0x413d, 0x413e, 0x413f, 0x4140, + 0x4141, 0x4142, 0x4143, 0x4144, 0x4145, 0x4146, 0x4147, 0x4148, + 0x4149, 0x414a, 0x414b, 0x414c, 0x414d, 0x414e, 0x414f, 0x4150, + 0x4151, 0x4152, 0x4153, 0x4154, 0x4155, 0x4156, 0x4157, 0x4158, + 0x4159, 0x415a, 0x415b, 0x415c, 0x415d, 0x415e, 0x415f, 0x4160, + 0x4161, 0x4162, 0x4163, 0x4164, 0x4165, 0x4166, 0x4167, 0x4168, + 0x4169, 0x416a, 0x416b, 0x416c, 0x416d, 0x416e, 0x416f, 0x4170, + 0x4171, 0x4172, 0x4173, 0x4174, 0x4175, 0x4176, 0x4177, 0x4178, + 0x4179, 0x417a, 0x417b, 0x417c, 0x417d, 0x417e, 0x4221, 0x4222, + 0x4223, 0x4224, 0x4225, 0x4226, 0x4227, 0x4228, 0x4229, 0x422a, + 0x422b, 0x422c, 0x422d, 0x422e, 0x422f, 0x4230, 0x4231, 0x4232, + 0x4233, 0x4234, 0x4235, 0x4236, 0x4237, 0x4238, 0x4239, 0x423a, + 0x423b, 0x423c, 0x423d, 0x423e, 0x423f, 0x4240, 0x4241, 0x4242, + 0x4243, 0x4244, 0x4245, 0x4246, 0x4247, 0x4248, 0x4249, 0x424a, + 0x424b, 0x424c, 0x424d, 0x424e, 0x424f, 0x4250, 0x4251, 0x4252, + 0x4253, 0x4254, 0x4255, 0x4256, 0x4257, 0x4258, 0x4259, 0x425a, + 0x425b, 0x425c, 0x425d, 0x425e, 0x425f, 0x4260, 0x4261, 0x4262, + 0x4263, 0x4264, 0x4265, 0x4266, 0x4267, 0x4268, 0x4269, 0x426a, + 0x426b, 0x426c, 0x426d, 0x426e, 0x426f, 0x4270, 0x4271, 0x4272, + 0x4273, 0x4274, 0x4275, 0x4276, 0x4277, 0x4278, 0x4279, 0x427a, + 0x427b, 0x427c, 0x427d, 0x427e, 0x4321, 0x4322, 0x4323, 0x4324, + 0x4325, 0x4326, 0x4327, 0x4328, 0x4329, 0x432a, 0x432b, 0x432c, + 0x432d, 0x432e, 0x432f, 0x4330, 0x4331, 0x4332, 0x4333, 0x4334, + 0x4335, 0x4336, 0x4337, 0x4338, 0x4339, 0x433a, 0x433b, 0x433c, + 0x433d, 0x433e, 0x433f, 0x4340, 0x4341, 0x4342, 0x4343, 0x4344, + 0x4345, 0x4346, 0x4347, 0x4348, 0x4349, 0x434a, 0x434b, 0x434c, + 0x434d, 0x434e, 0x434f, 0x4350, 0x4351, 0x4352, 0x4353, 0x4354, + 0x4355, 0x4356, 0x4357, 0x4358, 0x4359, 0x435a, 0x435b, 0x435c, + 0x435d, 0x435e, 0x435f, 0x4360, 0x4361, 0x4362, 0x4363, 0x4364, + 0x4365, 0x4366, 0x4367, 0x4368, 0x4369, 0x436a, 0x436b, 0x436c, + 0x436d, 0x436e, 0x436f, 0x4370, 0x4371, 0x4372, 0x4373, 0x4374, + 0x4375, 0x4376, 0x4377, 0x4378, 0x4379, 0x437a, 0x437b, 0x437c, + 0x437d, 0x437e, 0x4421, 0x4422, 0x4423, 0x4424, 0x4425, 0x4426, + 0x4427, 0x4428, 0x4429, 0x442a, 0x442b, 0x442c, 0x442d, 0x442e, + 0x442f, 0x4430, 0x4431, 0x4432, 0x4433, 0x4434, 0x4435, 0x4436, + 0x4437, 0x4438, 0x4439, 0x443a, 0x443b, 0x443c, 0x443d, 0x443e, + 0x443f, 0x4440, 0x4441, 0x4442, 0x4443, 0x4444, 0x4445, 0x4446, + 0x4447, 0x4448, 0x4449, 0x444a, 0x444b, 0x444c, 0x444d, 0x444e, + 0x444f, 0x4450, 0x4451, 0x4452, 0x4453, 0x4454, 0x4455, 0x4456, + 0x4457, 0x4458, 0x4459, 0x445a, 0x445b, 0x445c, 0x445d, 0x445e, + 0x445f, 0x4460, 0x4461, 0x4462, 0x4463, 0x4464, 0x4465, 0x4466, + 0x4467, 0x4468, 0x4469, 0x446a, 0x446b, 0x446c, 0x446d, 0x446e, + 0x446f, 0x4470, 0x4471, 0x4472, 0x4473, 0x4474, 0x4475, 0x4476, + 0x4477, 0x4478, 0x4479, 0x447a, 0x447b, 0x447c, 0x447d, 0x447e, + 0x4521, 0x4522, 0x4523, 0x4524, 0x4525, 0x4526, 0x4527, 0x4528, + 0x4529, 0x452a, 0x452b, 0x452c, 0x452d, 0x452e, 0x452f, 0x4530, + 0x4531, 0x4532, 0x4533, 0x4534, 0x4535, 0x4536, 0x4537, 0x4538, + 0x4539, 0x453a, 0x453b, 0x453c, 0x453d, 0x453e, 0x453f, 0x4540, + 0x4541, 0x4542, 0x4543, 0x4544, 0x4545, 0x4546, 0x4547, 0x4548, + 0x4549, 0x454a, 0x454b, 0x454c, 0x454d, 0x454e, 0x454f, 0x4550, + 0x4551, 0x4552, 0x4553, 0x4554, 0x4555, 0x4556, 0x4557, 0x4558, + 0x4559, 0x455a, 0x455b, 0x455c, 0x455d, 0x455e, 0x455f, 0x4560, + 0x4561, 0x4562, 0x4563, 0x4564, 0x4565, 0x4566, 0x4567, 0x4568, + 0x4569, 0x456a, 0x456b, 0x456c, 0x456d, 0x456e, 0x456f, 0x4570, + 0x4571, 0x4572, 0x4573, 0x4574, 0x4575, 0x4576, 0x4577, 0x4578, + 0x4579, 0x457a, 0x457b, 0x457c, 0x457d, 0x457e, 0x4621, 0x4622, + 0x4623, 0x4624, 0x4625, 0x4626, 0x4627, 0x4628, 0x4629, 0x462a, + 0x462b, 0x462c, 0x462d, 0x462e, 0x462f, 0x4630, 0x4631, 0x4632, + 0x4633, 0x4634, 0x4635, 0x4636, 0x4637, 0x4638, 0x4639, 0x463a, + 0x463b, 0x463c, 0x463d, 0x463e, 0x463f, 0x4640, 0x4641, 0x4642, + 0x4643, 0x4644, 0x4645, 0x4646, 0x4647, 0x4648, 0x4649, 0x464a, + 0x464b, 0x464c, 0x464d, 0x464e, 0x464f, 0x4650, 0x4651, 0x4652, + 0x4653, 0x4654, 0x4655, 0x4656, 0x4657, 0x4658, 0x4659, 0x465a, + 0x465b, 0x465c, 0x465d, 0x465e, 0x465f, 0x4660, 0x4661, 0x4662, + 0x4663, 0x4664, 0x4665, 0x4666, 0x4667, 0x4668, 0x4669, 0x466a, + 0x466b, 0x466c, 0x466d, 0x466e, 0x466f, 0x4670, 0x4671, 0x4672, + 0x4673, 0x4674, 0x4675, 0x4676, 0x4677, 0x4678, 0x4679, 0x467a, + 0x467b, 0x467c, 0x467d, 0x467e, 0x4721, 0x4722, 0x4723, 0x4724, + 0x4725, 0x4726, 0x4727, 0x4728, 0x4729, 0x472a, 0x472b, 0x472c, + 0x472d, 0x472e, 0x472f, 0x4730, 0x4731, 0x4732, 0x4733, 0x4734, + 0x4735, 0x4736, 0x4737, 0x4738, 0x4739, 0x473a, 0x473b, 0x473c, + 0x473d, 0x473e, 0x473f, 0x4740, 0x4741, 0x4742, 0x4743, 0x4744, + 0x4745, 0x4746, 0x4747, 0x4748, 0x4749, 0x474a, 0x474b, 0x474c, + 0x474d, 0x474e, 0x474f, 0x4750, 0x4751, 0x4752, 0x4753, 0x4754, + 0x4755, 0x4756, 0x4757, 0x4758, 0x4759, 0x475a, 0x475b, 0x475c, + 0x475d, 0x475e, 0x475f, 0x4760, 0x4761, 0x4762, 0x4763, 0x4764, + 0x4765, 0x4766, 0x4767, 0x4768, 0x4769, 0x476a, 0x476b, 0x476c, + 0x476d, 0x476e, 0x476f, 0x4770, 0x4771, 0x4772, 0x4773, 0x4774, + 0x4775, 0x4776, 0x4777, 0x4778, 0x4779, 0x477a, 0x477b, 0x477c, + 0x477d, 0x477e, 0x4821, 0x4822, 0x4823, 0x4824, 0x4825, 0x4826, + 0x4827, 0x4828, 0x4829, 0x482a, 0x482b, 0x482c, 0x482d, 0x482e, + 0x482f, 0x4830, 0x4831, 0x4832, 0x4833, 0x4834, 0x4835, 0x4836, + 0x4837, 0x4838, 0x4839, 0x483a, 0x483b, 0x483c, 0x483d, 0x483e, + 0x483f, 0x4840, 0x4841, 0x4842, 0x4843, 0x4844, 0x4845, 0x4846, + 0x4847, 0x4848, 0x4849, 0x484a, 0x484b, 0x484c, 0x484d, 0x484e, + 0x484f, 0x4850, 0x4851, 0x4852, 0x4853, 0x4854, 0x4855, 0x4856, + 0x4857, 0x4858, 0x4859, 0x485a, 0x485b, 0x485c, 0x485d, 0x485e, + 0x485f, 0x4860, 0x4861, 0x4862, 0x4863, 0x4864, 0x4865, 0x4866, + 0x4867, 0x4868, 0x4869, 0x486a, 0x486b, 0x486c, 0x486d, 0x486e, + 0x486f, 0x4870, 0x4871, 0x4872, 0x4873, 0x4874, 0x4875, 0x4876, + 0x4877, 0x4878, 0x4879, 0x487a, 0x487b, 0x487c, 0x487d, 0x487e, + 0x4b50, 0x4b56, 0x4b67, 0x4d4f, 0x4d68, 0x4e2d, 0x4f7b, 0x5022, + 0x5038, 0x5050, 0x505d, 0x5154, 0x5155, 0x5158, 0x515b, 0x515c, + 0x515d, 0x515e, 0x515f, 0x5160, 0x5162, 0x5163, 0x5164, 0x5165, + 0x5166, 0x5168, 0x5169, 0x516a, 0x516b, 0x516d, 0x516f, 0x5170, + 0x5172, 0x5176, 0x517a, 0x517c, 0x517d, 0x517e, 0x5222, 0x5223, + 0x5227, 0x5228, 0x5229, 0x522a, 0x522b, 0x522d, 0x5232, 0x523e, + 0x5242, 0x5243, 0x5244, 0x5246, 0x5247, 0x5248, 0x5249, 0x524a, + 0x524b, 0x524d, 0x524e, 0x524f, 0x5250, 0x5251, 0x5252, 0x5253, + 0x5254, 0x5255, 0x5256, 0x5257, 0x5259, 0x525a, 0x525e, 0x525f, + 0x5261, 0x5262, 0x5264, 0x5265, 0x5266, 0x5267, 0x5268, 0x5269, + 0x526a, 0x526b, 0x5270, 0x5271, 0x5272, 0x5273, 0x5274, 0x5275, + 0x5277, 0x5278, 0x5466, 0x547c, 0x5525, 0x552b, 0x552e, 0x5638, + 0x564d, 0x574b, 0x5764, 0x5b45, 0x5b64, 0x5c25, 0x5d25, 0x5d55, + 0x5d74, 0x5e7c, 0x5e7e, 0x5f33, 0x5f61, 0x5f68, 0x6071, 0x612d, + 0x616d, 0x6375, 0x6421, 0x6429, 0x652e, 0x6531, 0x6532, 0x6539, + 0x653b, 0x653c, 0x6544, 0x654e, 0x6550, 0x6552, 0x6556, 0x657a, + 0x657b, 0x657c, 0x657e, 0x6621, 0x6624, 0x6627, 0x662d, 0x662f, + 0x6630, 0x6631, 0x6633, 0x6637, 0x6638, 0x663c, 0x6644, 0x6646, + 0x6647, 0x664a, 0x6652, 0x6656, 0x6659, 0x665c, 0x665f, 0x6661, + 0x6664, 0x6665, 0x6666, 0x6668, 0x666a, 0x666b, 0x666c, 0x666f, + 0x6671, 0x6672, 0x6675, 0x6676, 0x6677, 0x6679, 0x6721, 0x6726, + 0x6729, 0x672a, 0x672c, 0x672d, 0x6730, 0x673f, 0x6741, 0x6746, + 0x6747, 0x674b, 0x674d, 0x674f, 0x6750, 0x6753, 0x675f, 0x6764, + 0x6766, 0x6777, 0x6867, 0x6868, 0x6870, 0x6871, 0x6877, 0x6879, + 0x687b, 0x687e, 0x6927, 0x692c, 0x694c, 0x6977, 0x6a41, 0x6a65, + 0x6a74, 0x6a77, 0x6a7c, 0x6a7e, 0x6b24, 0x6b27, 0x6b29, 0x6b2a, + 0x6b3a, 0x6b3b, 0x6b3d, 0x6b41, 0x6b42, 0x6b46, 0x6b47, 0x6b4c, + 0x6b4f, 0x6b50, 0x6b51, 0x6b52, 0x6b58, 0x6c26, 0x6c27, 0x6c2a, + 0x6c2f, 0x6c30, 0x6c31, 0x6c32, 0x6c35, 0x6c38, 0x6c3a, 0x6c40, + 0x6c41, 0x6c45, 0x6c46, 0x6c49, 0x6c4a, 0x6c55, 0x6c5d, 0x6c5e, + 0x6c61, 0x6c64, 0x6c67, 0x6c68, 0x6c77, 0x6c78, 0x6c7a, 0x6d21, + 0x6d22, 0x6d23, 0x6d6e, 0x6e5b, 0x723d, 0x727a, 0x7331, 0x7427, + 0x746e, 0x7674, 0x7676, 0x7738, 0x7748, 0x7753, 0x785b, 0x7870, + 0x7a21, 0x7a22, 0x7a66, 0x7c29, 0x2321, 0x2322, 0x2323, 0x2324, + 0x2325, 0x2326, 0x2327, 0x2328, 0x2329, 0x232a, 0x232b, 0x232c, + 0x232d, 0x232e, 0x232f, 0x2330, 0x2331, 0x2332, 0x2333, 0x2334, + 0x2335, 0x2336, 0x2337, 0x2338, 0x2339, 0x233a, 0x233b, 0x233c, + 0x233d, 0x233e, 0x233f, 0x2340, 0x2341, 0x2342, 0x2343, 0x2344, + 0x2345, 0x2346, 0x2347, 0x2348, 0x2349, 0x234a, 0x234b, 0x234c, + 0x234d, 0x234e, 0x234f, 0x2350, 0x2351, 0x2352, 0x2353, 0x2354, + 0x2355, 0x2356, 0x2357, 0x2358, 0x2359, 0x235a, 0x235b, 0x212c, + 0x235d, 0x235e, 0x235f, 0x2360, 0x2361, 0x2362, 0x2363, 0x2364, + 0x2365, 0x2366, 0x2367, 0x2368, 0x2369, 0x236a, 0x236b, 0x236c, + 0x236d, 0x236e, 0x236f, 0x2370, 0x2371, 0x2372, 0x2373, 0x2374, + 0x2375, 0x2376, 0x2377, 0x2378, 0x2379, 0x237a, 0x237b, 0x237c, + 0x237d, 0x2226, 0x214b, 0x214c, 0x217e, 0x237e, 0x214d, 0x235c, +}; + +static const Summary16 ksc5601_uni2indx_page00[70] = { + /* 0x0000 */ + { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, + { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, + { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x2592 }, { 6, 0xf7df }, + { 20, 0x0040 }, { 21, 0xc181 }, { 26, 0x0040 }, { 27, 0x4181 }, + /* 0x0100 */ + { 31, 0x0000 }, { 31, 0x0002 }, { 32, 0x00c0 }, { 34, 0x810e }, + { 39, 0x0e07 }, { 45, 0x000c }, { 47, 0x00c0 }, { 49, 0x0000 }, + { 49, 0x0000 }, { 49, 0x0000 }, { 49, 0x0000 }, { 49, 0x0000 }, + { 49, 0x0000 }, { 49, 0x0000 }, { 49, 0x0000 }, { 49, 0x0000 }, + /* 0x0200 */ + { 49, 0x0000 }, { 49, 0x0000 }, { 49, 0x0000 }, { 49, 0x0000 }, + { 49, 0x0000 }, { 49, 0x0000 }, { 49, 0x0000 }, { 49, 0x0000 }, + { 49, 0x0000 }, { 49, 0x0000 }, { 49, 0x0000 }, { 49, 0x0000 }, + { 49, 0x0080 }, { 50, 0x2f01 }, { 56, 0x0000 }, { 56, 0x0000 }, + /* 0x0300 */ + { 56, 0x0000 }, { 56, 0x0000 }, { 56, 0x0000 }, { 56, 0x0000 }, + { 56, 0x0000 }, { 56, 0x0000 }, { 56, 0x0000 }, { 56, 0x0000 }, + { 56, 0x0000 }, { 56, 0xfffe }, { 71, 0x03fb }, { 80, 0xfffe }, + { 95, 0x03fb }, { 104, 0x0000 }, { 104, 0x0000 }, { 104, 0x0000 }, + /* 0x0400 */ + { 104, 0x0002 }, { 105, 0xffff }, { 121, 0xffff }, { 137, 0xffff }, + { 153, 0xffff }, { 169, 0x0002 }, +}; +static const Summary16 ksc5601_uni2indx_page20[103] = { + /* 0x2000 */ + { 170, 0x0000 }, { 170, 0x3320 }, { 175, 0x0063 }, { 179, 0x080d }, + { 183, 0x0000 }, { 183, 0x0000 }, { 183, 0x0000 }, { 183, 0x8010 }, + { 185, 0x001e }, { 189, 0x0000 }, { 189, 0x0000 }, { 189, 0x0000 }, + { 189, 0x0000 }, { 189, 0x0000 }, { 189, 0x0000 }, { 189, 0x0000 }, + /* 0x2100 */ + { 189, 0x0208 }, { 191, 0x0048 }, { 193, 0x0846 }, { 197, 0x0000 }, + { 197, 0x0000 }, { 197, 0x7818 }, { 203, 0x03ff }, { 213, 0x03ff }, + { 223, 0x0000 }, { 223, 0x03ff }, { 233, 0x0000 }, { 233, 0x0000 }, + { 233, 0x0000 }, { 233, 0x0014 }, { 235, 0x0000 }, { 235, 0x0000 }, + /* 0x2200 */ + { 235, 0x898d }, { 242, 0x6402 }, { 246, 0x5fa1 }, { 255, 0x3030 }, + { 259, 0x0000 }, { 259, 0x0004 }, { 260, 0x0c33 }, { 266, 0x0000 }, + { 266, 0x00cc }, { 270, 0x0200 }, { 271, 0x0020 }, { 272, 0x0000 }, + { 272, 0x0000 }, { 272, 0x0000 }, { 272, 0x0000 }, { 272, 0x0000 }, + /* 0x2300 */ + { 272, 0x0000 }, { 272, 0x0004 }, { 273, 0x0000 }, { 273, 0x0000 }, + { 273, 0x0000 }, { 273, 0x0000 }, { 273, 0x0000 }, { 273, 0x0000 }, + { 273, 0x0000 }, { 273, 0x0000 }, { 273, 0x0000 }, { 273, 0x0000 }, + { 273, 0x0000 }, { 273, 0x0000 }, { 273, 0x0000 }, { 273, 0x0000 }, + /* 0x2400 */ + { 273, 0x0000 }, { 273, 0x0000 }, { 273, 0x0000 }, { 273, 0x0000 }, + { 273, 0x0000 }, { 273, 0x0000 }, { 273, 0x7fff }, { 288, 0xfff0 }, + { 300, 0x0007 }, { 303, 0xf000 }, { 307, 0xffff }, { 323, 0x003f }, + { 329, 0x0000 }, { 329, 0xffff }, { 345, 0x03ff }, { 355, 0x0000 }, + /* 0x2500 */ + { 355, 0xf00f }, { 363, 0xffff }, { 379, 0xffff }, { 395, 0xffff }, + { 411, 0x0fff }, { 423, 0x0000 }, { 423, 0x0000 }, { 423, 0x0000 }, + { 423, 0x0000 }, { 423, 0x0004 }, { 424, 0x03fb }, { 433, 0x30cc }, + { 439, 0xc9c3 }, { 447, 0x0003 }, { 449, 0x0000 }, { 449, 0x0000 }, + /* 0x2600 */ + { 449, 0xc060 }, { 453, 0x5000 }, { 455, 0x0000 }, { 455, 0x0000 }, + { 455, 0x0005 }, { 457, 0x0000 }, { 457, 0x37bb }, +}; +static const Summary16 ksc5601_uni2indx_page30[62] = { + /* 0x3000 */ + { 468, 0xff0f }, { 480, 0x003b }, { 485, 0x0000 }, { 485, 0x0000 }, + { 485, 0xfffe }, { 500, 0xffff }, { 516, 0xffff }, { 532, 0xffff }, + { 548, 0xffff }, { 564, 0x000f }, { 568, 0xfffe }, { 583, 0xffff }, + { 599, 0xffff }, { 615, 0xffff }, { 631, 0xffff }, { 647, 0x007f }, + /* 0x3100 */ + { 654, 0x0000 }, { 654, 0x0000 }, { 654, 0x0000 }, { 654, 0xfffe }, + { 669, 0xffff }, { 685, 0xffff }, { 701, 0xffff }, { 717, 0xffff }, + { 733, 0x7fff }, { 748, 0x0000 }, { 748, 0x0000 }, { 748, 0x0000 }, + { 748, 0x0000 }, { 748, 0x0000 }, { 748, 0x0000 }, { 748, 0x0000 }, + /* 0x3200 */ + { 748, 0xffff }, { 764, 0x1fff }, { 777, 0x0000 }, { 777, 0x0000 }, + { 777, 0x0000 }, { 777, 0x0000 }, { 777, 0xffff }, { 793, 0x8fff }, + { 806, 0x0000 }, { 806, 0x0000 }, { 806, 0x0000 }, { 806, 0x0000 }, + { 806, 0x0000 }, { 806, 0x0000 }, { 806, 0x0000 }, { 806, 0x0000 }, + /* 0x3300 */ + { 806, 0x0000 }, { 806, 0x0000 }, { 806, 0x0000 }, { 806, 0x0000 }, + { 806, 0x0000 }, { 806, 0x0000 }, { 806, 0x0000 }, { 806, 0x0000 }, + { 806, 0xff1f }, { 819, 0xffff }, { 835, 0xffff }, { 851, 0xffff }, + { 867, 0x87ff }, { 879, 0x3949 }, +}; +static const Summary16 ksc5601_uni2indx_page4e[1306] = { + /* 0x4e00 */ + { 886, 0x2f8b }, { 895, 0x4372 }, { 902, 0x2000 }, { 903, 0x0b04 }, + { 907, 0xe82c }, { 914, 0xe340 }, { 920, 0x2800 }, { 922, 0x40c8 }, + { 926, 0x5944 }, { 932, 0x4937 }, { 940, 0x7976 }, { 950, 0x0440 }, + { 952, 0x2c93 }, { 959, 0xa3f0 }, { 967, 0x0038 }, { 970, 0x08c5 }, + /* 0x4f00 */ + { 975, 0xee02 }, { 982, 0x0003 }, { 984, 0x8000 }, { 985, 0x3550 }, + { 991, 0xe1c8 }, { 998, 0x1e23 }, { 1005, 0x8200 }, { 1007, 0xc449 }, + { 1013, 0xad5a }, { 1022, 0x2942 }, { 1027, 0xc000 }, { 1029, 0x8060 }, + { 1032, 0x461c }, { 1038, 0xa49a }, { 1045, 0xc003 }, { 1049, 0x052a }, + /* 0x5000 */ + { 1054, 0x2a44 }, { 1059, 0xd646 }, { 1067, 0x3dda }, { 1077, 0x0800 }, + { 1078, 0x8388 }, { 1083, 0x1420 }, { 1086, 0x0020 }, { 1087, 0x0170 }, + { 1091, 0x2021 }, { 1094, 0x0302 }, { 1097, 0x3000 }, { 1099, 0x40ac }, + { 1104, 0x8620 }, { 1108, 0x4462 }, { 1113, 0x20a0 }, { 1116, 0x8a00 }, + /* 0x5100 */ + { 1119, 0x0253 }, { 1124, 0x8004 }, { 1126, 0x0402 }, { 1128, 0x1484 }, + { 1132, 0x7bfb }, { 1145, 0x1004 }, { 1147, 0x7fa4 }, { 1157, 0x11e2 }, + { 1163, 0x2441 }, { 1167, 0x00a4 }, { 1170, 0x1421 }, { 1174, 0x20c0 }, + { 1177, 0x3a50 }, { 1183, 0x7000 }, { 1186, 0x0002 }, { 1187, 0x2743 }, + /* 0x5200 */ + { 1194, 0x45c9 }, { 1201, 0x2082 }, { 1204, 0x4630 }, { 1209, 0x0fc1 }, + { 1216, 0x3c88 }, { 1222, 0x2850 }, { 1226, 0x8602 }, { 1230, 0xa024 }, + { 1234, 0x2388 }, { 1239, 0x8806 }, { 1243, 0x0e19 }, { 1249, 0x4000 }, + { 1250, 0x22aa }, { 1256, 0xeb64 }, { 1265, 0x001c }, { 1268, 0xcd28 }, + /* 0x5300 */ + { 1275, 0xa120 }, { 1279, 0x02e1 }, { 1284, 0x840b }, { 1289, 0x8200 }, + { 1291, 0x279b }, { 1300, 0x549e }, { 1308, 0x8141 }, { 1312, 0xa0b3 }, + { 1319, 0x0010 }, { 1320, 0x8508 }, { 1324, 0x2061 }, { 1328, 0x0800 }, + { 1329, 0x2f08 }, { 1335, 0x08d0 }, { 1339, 0xbe3e }, { 1350, 0x010f }, + /* 0x5400 */ + { 1355, 0xf718 }, { 1364, 0xa803 }, { 1369, 0x0a41 }, { 1373, 0x5b08 }, + { 1379, 0x0504 }, { 1382, 0x0002 }, { 1383, 0x0500 }, { 1385, 0x382a }, + { 1391, 0x5041 }, { 1395, 0x0001 }, { 1396, 0x1910 }, { 1400, 0x2108 }, + { 1403, 0x0313 }, { 1408, 0x0000 }, { 1408, 0x6122 }, { 1413, 0x0404 }, + /* 0x5500 */ + { 1415, 0x40d0 }, { 1419, 0x1001 }, { 1421, 0x8000 }, { 1422, 0x4022 }, + { 1425, 0x8050 }, { 1428, 0x4048 }, { 1431, 0x0008 }, { 1432, 0x1000 }, + { 1433, 0x06d1 }, { 1439, 0x3700 }, { 1444, 0x5e80 }, { 1450, 0x0000 }, + { 1450, 0x00a0 }, { 1452, 0x9410 }, { 1456, 0x0018 }, { 1458, 0x6000 }, + /* 0x5600 */ + { 1460, 0x0240 }, { 1462, 0x0090 }, { 1464, 0x8000 }, { 1465, 0x0054 }, + { 1468, 0x0000 }, { 1468, 0x0008 }, { 1469, 0x0900 }, { 1471, 0x0010 }, + { 1472, 0x0040 }, { 1473, 0x0000 }, { 1473, 0x5020 }, { 1476, 0x1010 }, + { 1478, 0x2400 }, { 1480, 0x4c02 }, { 1484, 0x0001 }, { 1485, 0x0601 }, + /* 0x5700 */ + { 1488, 0x2918 }, { 1493, 0x814c }, { 1498, 0x2100 }, { 1500, 0x0801 }, + { 1502, 0x6485 }, { 1508, 0x0003 }, { 1510, 0x4452 }, { 1515, 0x1021 }, + { 1518, 0x0904 }, { 1521, 0x0008 }, { 1522, 0x000d }, { 1525, 0x0000 }, + { 1525, 0x4988 }, { 1530, 0x8000 }, { 1531, 0x0001 }, { 1532, 0x1691 }, + /* 0x5800 */ + { 1538, 0x0765 }, { 1545, 0x4000 }, { 1546, 0x8492 }, { 1551, 0x0433 }, + { 1556, 0x8c00 }, { 1559, 0x4592 }, { 1565, 0x0016 }, { 1568, 0x5220 }, + { 1572, 0x0228 }, { 1575, 0xd008 }, { 1579, 0x4300 }, { 1582, 0x4c08 }, + { 1586, 0x40a2 }, { 1590, 0xc32a }, { 1597, 0x9810 }, { 1601, 0x2e00 }, + /* 0x5900 */ + { 1605, 0x8000 }, { 1606, 0x1670 }, { 1612, 0x6e84 }, { 1619, 0x4082 }, + { 1622, 0xc390 }, { 1628, 0x04b3 }, { 1634, 0x7c85 }, { 1642, 0x2118 }, + { 1646, 0x041c }, { 1650, 0x02c8 }, { 1654, 0x1120 }, { 1657, 0x4a00 }, + { 1660, 0x0a48 }, { 1664, 0x361b }, { 1672, 0x5540 }, { 1677, 0x8900 }, + /* 0x5a00 */ + { 1680, 0x000a }, { 1682, 0x9902 }, { 1687, 0x0221 }, { 1690, 0x1040 }, + { 1692, 0x0242 }, { 1695, 0x0400 }, { 1696, 0x0044 }, { 1698, 0x0000 }, + { 1698, 0x0000 }, { 1698, 0x0c04 }, { 1701, 0x0010 }, { 1702, 0x0000 }, + { 1702, 0x1216 }, { 1707, 0x0000 }, { 1707, 0x0242 }, { 1710, 0x0000 }, + /* 0x5b00 */ + { 1710, 0x1a20 }, { 1714, 0x0040 }, { 1715, 0x0400 }, { 1716, 0x0000 }, + { 1716, 0x0009 }, { 1718, 0xb5b3 }, { 1728, 0x0a18 }, { 1732, 0x1523 }, + { 1738, 0x9ba0 }, { 1745, 0x1fe8 }, { 1754, 0x507c }, { 1761, 0x8379 }, + { 1769, 0x10fd }, { 1777, 0xc09d }, { 1784, 0xdbf6 }, { 1796, 0x0560 }, + /* 0x5c00 */ + { 1800, 0xef92 }, { 1810, 0x0242 }, { 1813, 0x0110 }, { 1815, 0xdf02 }, + { 1823, 0x6961 }, { 1830, 0x0822 }, { 1833, 0x9035 }, { 1839, 0x0202 }, + { 1841, 0x0000 }, { 1841, 0x0003 }, { 1843, 0x1a02 }, { 1847, 0x45aa }, + { 1854, 0x0001 }, { 1855, 0x0200 }, { 1856, 0x8101 }, { 1859, 0x2851 }, + /* 0x5d00 */ + { 1864, 0x6080 }, { 1867, 0x02d2 }, { 1872, 0x0280 }, { 1874, 0x0000 }, + { 1874, 0x1800 }, { 1876, 0x0001 }, { 1877, 0x9200 }, { 1880, 0x0000 }, + { 1880, 0x0880 }, { 1882, 0x2000 }, { 1883, 0x0405 }, { 1886, 0x3500 }, + { 1890, 0x2000 }, { 1891, 0x6044 }, { 1895, 0x49e6 }, { 1903, 0x609e }, + /* 0x5e00 */ + { 1910, 0x104c }, { 1914, 0x2a42 }, { 1919, 0x2820 }, { 1922, 0xa148 }, + { 1927, 0x10b1 }, { 1932, 0x8020 }, { 1934, 0x000e }, { 1937, 0x7b9c }, + { 1947, 0x8490 }, { 1951, 0x14a0 }, { 1955, 0x28c1 }, { 1960, 0x41e0 }, + { 1965, 0x0704 }, { 1969, 0x8c49 }, { 1975, 0x100d }, { 1979, 0x0cc8 }, + /* 0x5f00 */ + { 1984, 0x8412 }, { 1988, 0x89ba }, { 1996, 0x02c0 }, { 1999, 0x1422 }, + { 2003, 0x5500 }, { 2007, 0x0ac0 }, { 2011, 0x3ec4 }, { 2019, 0x9283 }, + { 2025, 0x1ca3 }, { 2032, 0x4387 }, { 2039, 0x4703 }, { 2045, 0x22a0 }, + { 2049, 0x3028 }, { 2053, 0x03c0 }, { 2057, 0x0801 }, { 2059, 0xa020 }, + /* 0x6000 */ + { 2062, 0x8000 }, { 2063, 0x3044 }, { 2067, 0x85a3 }, { 2074, 0x0000 }, + { 2074, 0x200e }, { 2078, 0x2225 }, { 2083, 0xb73c }, { 2093, 0x0001 }, + { 2094, 0x3220 }, { 2098, 0x8c50 }, { 2103, 0x0099 }, { 2107, 0x315d }, + { 2115, 0x00a0 }, { 2117, 0x9402 }, { 2121, 0x0003 }, { 2123, 0x0e4b }, + /* 0x6100 */ + { 2130, 0xe342 }, { 2137, 0x8c20 }, { 2141, 0x0080 }, { 2142, 0xd091 }, + { 2148, 0x1d94 }, { 2155, 0xa328 }, { 2161, 0x499c }, { 2168, 0x60c1 }, + { 2173, 0x4406 }, { 2177, 0x0713 }, { 2183, 0x5a90 }, { 2189, 0x4444 }, + { 2193, 0x0f88 }, { 2199, 0x0000 }, { 2199, 0x0040 }, { 2200, 0x95c4 }, + /* 0x6200 */ + { 2207, 0x7581 }, { 2214, 0x8447 }, { 2220, 0x4402 }, { 2223, 0xc053 }, + { 2229, 0x2b83 }, { 2236, 0x0108 }, { 2238, 0x4000 }, { 2239, 0x9242 }, + { 2244, 0x0611 }, { 2248, 0x09a6 }, { 2254, 0x0800 }, { 2255, 0x3222 }, + { 2260, 0xb384 }, { 2267, 0x1bdd }, { 2277, 0xf000 }, { 2281, 0xc08a }, + /* 0x6300 */ + { 2286, 0x0282 }, { 2289, 0x0002 }, { 2290, 0x8800 }, { 2292, 0x6c00 }, + { 2296, 0x9200 }, { 2299, 0x0021 }, { 2301, 0x4180 }, { 2304, 0x8c84 }, + { 2309, 0x1308 }, { 2313, 0x0944 }, { 2317, 0x07a7 }, { 2325, 0x0000 }, + { 2325, 0x8051 }, { 2329, 0x0c41 }, { 2333, 0x6002 }, { 2336, 0x00d0 }, + /* 0x6400 */ + { 2339, 0xa000 }, { 2341, 0x10d0 }, { 2345, 0x3004 }, { 2348, 0x4400 }, + { 2350, 0x0000 }, { 2350, 0x0100 }, { 2351, 0x8201 }, { 2354, 0x0700 }, + { 2357, 0x0100 }, { 2358, 0x440e }, { 2363, 0x6830 }, { 2368, 0x0805 }, + { 2371, 0x64b2 }, { 2378, 0x0514 }, { 2382, 0x10e6 }, { 2388, 0x4414 }, + /* 0x6500 */ + { 2392, 0x0011 }, { 2394, 0x2100 }, { 2396, 0x9c08 }, { 2401, 0xcbc0 }, + { 2408, 0xe120 }, { 2413, 0x40c2 }, { 2417, 0x304c }, { 2422, 0x41b4 }, + { 2428, 0x10ac }, { 2433, 0x9a83 }, { 2440, 0x98b2 }, { 2447, 0x3281 }, + { 2452, 0x9822 }, { 2457, 0x0084 }, { 2459, 0x3369 }, { 2467, 0xbc12 }, + /* 0x6600 */ + { 2474, 0xd6c0 }, { 2481, 0xc03b }, { 2488, 0xa1a1 }, { 2494, 0x0c53 }, + { 2500, 0x8a1e }, { 2507, 0xea00 }, { 2512, 0xcbf0 }, { 2521, 0x05d8 }, + { 2527, 0x4390 }, { 2532, 0x21c3 }, { 2538, 0x4805 }, { 2542, 0x4a1c }, + { 2548, 0x02d0 }, { 2552, 0x3240 }, { 2556, 0x0041 }, { 2558, 0xd79d }, + /* 0x6700 */ + { 2569, 0x2b09 }, { 2575, 0xe8b0 }, { 2582, 0x7dc0 }, { 2590, 0x2452 }, + { 2595, 0xc240 }, { 2599, 0xd04b }, { 2606, 0xa000 }, { 2608, 0xc8ab }, + { 2616, 0x8a80 }, { 2620, 0x34a9 }, { 2627, 0x8000 }, { 2628, 0x41c9 }, + { 2634, 0x8010 }, { 2636, 0x241f }, { 2643, 0x9200 }, { 2646, 0x487b }, + /* 0x6800 */ + { 2654, 0x0000 }, { 2654, 0x00cc }, { 2658, 0x8406 }, { 2662, 0x3300 }, + { 2666, 0x410f }, { 2672, 0x001b }, { 2676, 0x2000 }, { 2677, 0x8040 }, + { 2679, 0x8022 }, { 2682, 0xa098 }, { 2687, 0xa186 }, { 2693, 0x006b }, + { 2698, 0x2a30 }, { 2703, 0x85a4 }, { 2709, 0x4181 }, { 2713, 0x0604 }, + /* 0x6900 */ + { 2716, 0x6021 }, { 2720, 0x0004 }, { 2721, 0x0080 }, { 2722, 0xa001 }, + { 2725, 0x0400 }, { 2726, 0x46b8 }, { 2733, 0xe90f }, { 2742, 0x03a0 }, + { 2746, 0x0000 }, { 2746, 0x1820 }, { 2749, 0x40a0 }, { 2752, 0x0810 }, + { 2754, 0x380a }, { 2759, 0x0001 }, { 2760, 0x0500 }, { 2762, 0xa800 }, + /* 0x6a00 */ + { 2765, 0x0404 }, { 2767, 0xc28a }, { 2773, 0x000a }, { 2775, 0x2720 }, + { 2780, 0x0910 }, { 2783, 0x830c }, { 2788, 0x0802 }, { 2790, 0x0000 }, + { 2790, 0x6211 }, { 2795, 0x1080 }, { 2797, 0x000c }, { 2799, 0x0808 }, + { 2801, 0x000c }, { 2803, 0x0c08 }, { 2806, 0x0000 }, { 2806, 0x0840 }, + /* 0x6b00 */ + { 2808, 0x1410 }, { 2811, 0x0044 }, { 2813, 0x000b }, { 2816, 0x6404 }, + { 2820, 0x50c0 }, { 2824, 0x8001 }, { 2826, 0x047e }, { 2833, 0x8984 }, + { 2838, 0x0658 }, { 2843, 0x4140 }, { 2846, 0xc000 }, { 2848, 0x94a4 }, + { 2854, 0xa862 }, { 2860, 0x09dc }, { 2867, 0x1800 }, { 2869, 0x0000 }, + /* 0x6c00 */ + { 2869, 0x8100 }, { 2871, 0x000a }, { 2873, 0x0008 }, { 2874, 0x4190 }, + { 2878, 0x4007 }, { 2882, 0xe4a1 }, { 2889, 0x2501 }, { 2893, 0x6445 }, + { 2899, 0x11ee }, { 2907, 0x0e7d }, { 2916, 0x4800 }, { 2918, 0xfb08 }, + { 2926, 0x1616 }, { 2932, 0x08a8 }, { 2936, 0xc92e }, { 2944, 0x0009 }, + /* 0x6d00 */ + { 2946, 0x1800 }, { 2948, 0x4a82 }, { 2953, 0x06a0 }, { 2957, 0x6b64 }, + { 2965, 0x0002 }, { 2966, 0x1600 }, { 2969, 0x5648 }, { 2975, 0x8390 }, + { 2980, 0x73a0 }, { 2987, 0x002a }, { 2990, 0x8000 }, { 2991, 0x0024 }, + { 2993, 0x88f9 }, { 3001, 0x4702 }, { 3006, 0x4d02 }, { 3011, 0x0faa }, + /* 0x6e00 */ + { 3019, 0x0000 }, { 3019, 0x8e80 }, { 3024, 0xb87b }, { 3034, 0x7554 }, + { 3042, 0x2418 }, { 3046, 0xd940 }, { 3052, 0xc880 }, { 3056, 0x040c }, + { 3059, 0x0000 }, { 3059, 0xb041 }, { 3064, 0x8c24 }, { 3069, 0x0442 }, + { 3072, 0x5a34 }, { 3079, 0x001a }, { 3082, 0x8000 }, { 3083, 0xc110 }, + /* 0x6f00 */ + { 3087, 0x8046 }, { 3091, 0x0032 }, { 3094, 0x180d }, { 3099, 0x8106 }, + { 3103, 0x0002 }, { 3104, 0xcd92 }, { 3112, 0x6014 }, { 3116, 0x7401 }, + { 3121, 0x6112 }, { 3126, 0x0091 }, { 3129, 0xc098 }, { 3134, 0x420a }, + { 3138, 0x040f }, { 3143, 0x8420 }, { 3146, 0x9a13 }, { 3153, 0x4002 }, + /* 0x7000 */ + { 3155, 0x8a62 }, { 3161, 0xfd22 }, { 3170, 0x8188 }, { 3174, 0x4080 }, + { 3176, 0x1000 }, { 3177, 0x2103 }, { 3181, 0x0808 }, { 3183, 0x3101 }, + { 3187, 0x4420 }, { 3190, 0x0704 }, { 3194, 0xb812 }, { 3200, 0x0388 }, + { 3204, 0x8900 }, { 3207, 0xa300 }, { 3211, 0x0000 }, { 3211, 0x2202 }, + /* 0x7100 */ + { 3214, 0x1210 }, { 3217, 0x4600 }, { 3220, 0x0042 }, { 3222, 0x0041 }, + { 3224, 0x5680 }, { 3229, 0x5241 }, { 3234, 0x52f0 }, { 3241, 0x2000 }, + { 3242, 0x8610 }, { 3246, 0x8214 }, { 3250, 0x1004 }, { 3252, 0x4602 }, + { 3256, 0x430a }, { 3261, 0x8035 }, { 3266, 0x60e0 }, { 3271, 0xd800 }, + /* 0x7200 */ + { 3275, 0x0041 }, { 3277, 0x0801 }, { 3279, 0x3400 }, { 3282, 0x6c65 }, + { 3290, 0x11c1 }, { 3295, 0xab04 }, { 3301, 0x0286 }, { 3305, 0x2204 }, + { 3308, 0x0003 }, { 3310, 0x0000 }, { 3310, 0x9084 }, { 3314, 0x0000 }, + { 3314, 0x4015 }, { 3318, 0x0281 }, { 3321, 0x0202 }, { 3323, 0x3300 }, + /* 0x7300 */ + { 3327, 0x0400 }, { 3328, 0x3840 }, { 3332, 0x0e20 }, { 3336, 0xc0c0 }, + { 3340, 0x0030 }, { 3342, 0x0085 }, { 3345, 0x0500 }, { 3347, 0x0d25 }, + { 3353, 0x4ad0 }, { 3359, 0x81d0 }, { 3364, 0x2280 }, { 3367, 0x020c }, + { 3370, 0xb605 }, { 3377, 0x6240 }, { 3381, 0x2679 }, { 3389, 0x6280 }, + /* 0x7400 */ + { 3393, 0x02ea }, { 3399, 0x0808 }, { 3401, 0xdd67 }, { 3412, 0x8579 }, + { 3420, 0x081b }, { 3425, 0xdea0 }, { 3433, 0x8735 }, { 3441, 0x4000 }, + { 3442, 0x0a8c }, { 3447, 0xd100 }, { 3451, 0x05aa }, { 3457, 0xa225 }, + { 3463, 0x8440 }, { 3466, 0x1510 }, { 3470, 0x404d }, { 3475, 0x0080 }, + /* 0x7500 */ + { 3476, 0x0012 }, { 3478, 0x8d22 }, { 3484, 0x1968 }, { 3490, 0x058f }, + { 3497, 0x9080 }, { 3500, 0x3a1a }, { 3507, 0x8464 }, { 3512, 0x8561 }, + { 3518, 0xccc0 }, { 3524, 0x2002 }, { 3526, 0x0820 }, { 3528, 0x732e }, + { 3537, 0x20a4 }, { 3541, 0x0b34 }, { 3547, 0x0004 }, { 3548, 0x1415 }, + /* 0x7600 */ + { 3553, 0x2001 }, { 3555, 0x8200 }, { 3557, 0x0057 }, { 3562, 0x0800 }, + { 3563, 0x5004 }, { 3566, 0x0044 }, { 3568, 0x1212 }, { 3572, 0x7905 }, + { 3579, 0x40d0 }, { 3583, 0x0009 }, { 3585, 0x4000 }, { 3586, 0x8400 }, + { 3588, 0x054c }, { 3593, 0xd844 }, { 3599, 0x409a }, { 3604, 0x5114 }, + /* 0x7700 */ + { 3609, 0x0b12 }, { 3614, 0x4000 }, { 3615, 0x0201 }, { 3617, 0x1580 }, + { 3621, 0x2001 }, { 3623, 0x0800 }, { 3624, 0x084a }, { 3628, 0xc200 }, + { 3631, 0x0800 }, { 3632, 0x4002 }, { 3634, 0x3020 }, { 3637, 0x9809 }, + { 3642, 0x0000 }, { 3642, 0x1880 }, { 3645, 0xe22c }, { 3652, 0x0008 }, + /* 0x7800 */ + { 3653, 0x0004 }, { 3654, 0x0004 }, { 3655, 0x10e0 }, { 3659, 0x0014 }, + { 3661, 0x8020 }, { 3663, 0x2000 }, { 3664, 0x9800 }, { 3667, 0x1000 }, + { 3668, 0x7082 }, { 3673, 0x0082 }, { 3675, 0x0288 }, { 3678, 0x1c00 }, + { 3681, 0x4c22 }, { 3686, 0x0001 }, { 3687, 0x9100 }, { 3690, 0x0820 }, + /* 0x7900 */ + { 3692, 0x4002 }, { 3694, 0x0040 }, { 3695, 0x1c00 }, { 3698, 0x4400 }, + { 3700, 0x0383 }, { 3705, 0x7cc1 }, { 3713, 0x2121 }, { 3717, 0x8400 }, + { 3719, 0xe002 }, { 3723, 0x0002 }, { 3724, 0x44c0 }, { 3728, 0xe20a }, + { 3734, 0x0e03 }, { 3739, 0x8126 }, { 3744, 0x02d0 }, { 3748, 0x0800 }, + /* 0x7a00 */ + { 3749, 0x2921 }, { 3754, 0x9690 }, { 3760, 0x4001 }, { 3762, 0xb8c2 }, + { 3769, 0x6241 }, { 3774, 0x0080 }, { 3775, 0x0a06 }, { 3779, 0xa651 }, + { 3786, 0x0112 }, { 3789, 0x812c }, { 3794, 0xc600 }, { 3798, 0x0400 }, + { 3799, 0x0cb0 }, { 3804, 0xa280 }, { 3808, 0xa429 }, { 3814, 0x8640 }, + /* 0x7b00 */ + { 3818, 0x8000 }, { 3819, 0x4a02 }, { 3823, 0x3041 }, { 3827, 0x0200 }, + { 3828, 0xba40 }, { 3834, 0x0057 }, { 3839, 0x5001 }, { 3842, 0x2020 }, + { 3844, 0x8880 }, { 3847, 0x24b0 }, { 3852, 0x2002 }, { 3854, 0x0112 }, + { 3857, 0x02d3 }, { 3863, 0x0004 }, { 3864, 0x0211 }, { 3867, 0x0000 }, + /* 0x7c00 */ + { 3867, 0x0080 }, { 3868, 0x4004 }, { 3870, 0x0c82 }, { 3874, 0xe000 }, + { 3877, 0x3008 }, { 3880, 0x0000 }, { 3880, 0x1011 }, { 3883, 0x0008 }, + { 3884, 0x0208 }, { 3886, 0x81a4 }, { 3891, 0x40a0 }, { 3894, 0x420e }, + { 3899, 0x0400 }, { 3900, 0xc040 }, { 3903, 0x0081 }, { 3905, 0x4800 }, + /* 0x7d00 */ + { 3907, 0x2df5 }, { 3917, 0x0f91 }, { 3924, 0xd807 }, { 3931, 0x0629 }, + { 3936, 0x007c }, { 3941, 0x4001 }, { 3943, 0x4546 }, { 3949, 0x824e }, + { 3955, 0xc000 }, { 3957, 0x1008 }, { 3959, 0x3005 }, { 3963, 0xed36 }, + { 3973, 0x0c80 }, { 3976, 0x6540 }, { 3981, 0x930b }, { 3988, 0x0810 }, + /* 0x7e00 */ + { 3990, 0x0600 }, { 3992, 0xe820 }, { 3997, 0xc80a }, { 4002, 0x6082 }, + { 4006, 0x00ca }, { 4010, 0x4034 }, { 4014, 0x2e02 }, { 4019, 0x1201 }, + { 4022, 0x9004 }, { 4025, 0x1948 }, { 4030, 0x0000 }, { 4030, 0x0000 }, + { 4030, 0x0000 }, { 4030, 0x0000 }, { 4030, 0x0000 }, { 4030, 0x0000 }, + /* 0x7f00 */ + { 4030, 0x0000 }, { 4030, 0x0000 }, { 4030, 0x0000 }, { 4030, 0x0540 }, + { 4033, 0x1000 }, { 4034, 0x0031 }, { 4037, 0x4c00 }, { 4040, 0x02a5 }, + { 4045, 0x5520 }, { 4050, 0x4410 }, { 4053, 0x0310 }, { 4056, 0x2304 }, + { 4060, 0x5422 }, { 4065, 0x8034 }, { 4069, 0x0a03 }, { 4073, 0x1201 }, + /* 0x8000 */ + { 4076, 0x126b }, { 4083, 0x01a1 }, { 4087, 0x2000 }, { 4088, 0xa048 }, + { 4092, 0x0448 }, { 4095, 0x4540 }, { 4099, 0x8000 }, { 4100, 0xe08d }, + { 4107, 0x1af0 }, { 4114, 0x2840 }, { 4117, 0x8626 }, { 4123, 0x0416 }, + { 4127, 0x5018 }, { 4131, 0x4c00 }, { 4134, 0x0032 }, { 4137, 0x2112 }, + /* 0x8100 */ + { 4141, 0x05e4 }, { 4147, 0x0d00 }, { 4150, 0x8a08 }, { 4154, 0x4200 }, + { 4156, 0x4800 }, { 4158, 0x0033 }, { 4162, 0x0860 }, { 4165, 0x8703 }, + { 4171, 0x8501 }, { 4175, 0x3400 }, { 4178, 0x0109 }, { 4181, 0xe428 }, + { 4187, 0x2045 }, { 4191, 0x8100 }, { 4193, 0x25a8 }, { 4199, 0x5c18 }, + /* 0x8200 */ + { 4205, 0x35a0 }, { 4211, 0xd804 }, { 4216, 0x1c02 }, { 4220, 0x02e0 }, + { 4224, 0x00a1 }, { 4227, 0x0200 }, { 4228, 0xc050 }, { 4232, 0x4146 }, + { 4237, 0x6800 }, { 4240, 0xa604 }, { 4245, 0xf260 }, { 4252, 0xbb8a }, + { 4261, 0x0000 }, { 4261, 0xc8b6 }, { 4269, 0x00e2 }, { 4273, 0x6002 }, + /* 0x8300 */ + { 4276, 0x023e }, { 4282, 0x0080 }, { 4283, 0x8900 }, { 4286, 0x0372 }, + { 4292, 0x8681 }, { 4297, 0x0006 }, { 4299, 0x0000 }, { 4299, 0x0888 }, + { 4302, 0x4600 }, { 4305, 0x4140 }, { 4308, 0x0e04 }, { 4312, 0x2000 }, + { 4313, 0x1622 }, { 4318, 0x1048 }, { 4321, 0x8a00 }, { 4324, 0x2217 }, + /* 0x8400 */ + { 4330, 0x7418 }, { 4336, 0x0000 }, { 4336, 0x1200 }, { 4338, 0x2102 }, + { 4341, 0x0200 }, { 4342, 0x0880 }, { 4344, 0x984a }, { 4350, 0x0420 }, + { 4352, 0x0000 }, { 4352, 0x1211 }, { 4356, 0x0002 }, { 4357, 0x9904 }, + { 4362, 0x2a55 }, { 4369, 0x0402 }, { 4371, 0x5000 }, { 4373, 0x1010 }, + /* 0x8500 */ + { 4375, 0x0000 }, { 4375, 0x459a }, { 4382, 0xb02a }, { 4388, 0xa000 }, + { 4390, 0x420a }, { 4394, 0x0208 }, { 4396, 0x2708 }, { 4401, 0x0000 }, + { 4401, 0x8090 }, { 4404, 0x0812 }, { 4407, 0x8740 }, { 4412, 0x0401 }, + { 4414, 0xe202 }, { 4419, 0x3020 }, { 4422, 0x0630 }, { 4426, 0x8c80 }, + /* 0x8600 */ + { 4430, 0x04c4 }, { 4434, 0x04c0 }, { 4437, 0x2000 }, { 4438, 0x8000 }, + { 4439, 0x4000 }, { 4440, 0xd831 }, { 4447, 0x0080 }, { 4448, 0x0200 }, + { 4449, 0x1400 }, { 4451, 0x0008 }, { 4452, 0x0218 }, { 4455, 0x0000 }, + { 4455, 0x0880 }, { 4457, 0x8a10 }, { 4461, 0x2010 }, { 4463, 0x4000 }, + /* 0x8700 */ + { 4464, 0x010d }, { 4468, 0x1500 }, { 4471, 0x0000 }, { 4471, 0x0000 }, + { 4471, 0x4000 }, { 4472, 0x80a0 }, { 4475, 0x0140 }, { 4477, 0x0150 }, + { 4480, 0x2004 }, { 4482, 0x8000 }, { 4483, 0x0004 }, { 4484, 0x0408 }, + { 4486, 0x0010 }, { 4487, 0x0000 }, { 4487, 0x9001 }, { 4490, 0x4a04 }, + /* 0x8800 */ + { 4494, 0x0020 }, { 4495, 0x8000 }, { 4496, 0x000c }, { 4498, 0x0842 }, + { 4501, 0x3041 }, { 4505, 0x2a8c }, { 4511, 0x090e }, { 4516, 0xc085 }, + { 4521, 0x2906 }, { 4526, 0x40c4 }, { 4530, 0x0800 }, { 4531, 0x0010 }, + { 4532, 0x8006 }, { 4535, 0xb230 }, { 4541, 0x0102 }, { 4543, 0x2138 }, + /* 0x8900 */ + { 4548, 0x0080 }, { 4549, 0x030d }, { 4554, 0x0420 }, { 4556, 0x0940 }, + { 4559, 0x0012 }, { 4561, 0x8000 }, { 4562, 0x0410 }, { 4564, 0x8004 }, + { 4566, 0x88ca }, { 4572, 0x0048 }, { 4574, 0x0602 }, { 4577, 0x2404 }, + { 4580, 0x0001 }, { 4581, 0x0004 }, { 4582, 0x0008 }, { 4583, 0x0110 }, + /* 0x8a00 */ + { 4585, 0x550d }, { 4592, 0xa9c8 }, { 4599, 0x2428 }, { 4603, 0x0c52 }, + { 4608, 0x0000 }, { 4608, 0x4831 }, { 4613, 0x624d }, { 4620, 0x022f }, + { 4626, 0x30a0 }, { 4630, 0x4128 }, { 4634, 0x057b }, { 4642, 0xd205 }, + { 4648, 0xa894 }, { 4654, 0x1844 }, { 4658, 0x6cc2 }, { 4665, 0x45c2 }, + /* 0x8b00 */ + { 4671, 0x4017 }, { 4676, 0x2ed1 }, { 4684, 0x1901 }, { 4688, 0x0208 }, + { 4690, 0xc202 }, { 4694, 0x1500 }, { 4697, 0x9040 }, { 4700, 0x2091 }, + { 4704, 0x0401 }, { 4706, 0x044d }, { 4711, 0x0000 }, { 4711, 0x0000 }, + { 4711, 0x0000 }, { 4711, 0x0000 }, { 4711, 0x0000 }, { 4711, 0x0000 }, + /* 0x8c00 */ + { 4711, 0x0000 }, { 4711, 0x0000 }, { 4711, 0x0000 }, { 4711, 0x8080 }, + { 4713, 0x1542 }, { 4718, 0x0420 }, { 4720, 0x0c02 }, { 4723, 0x0600 }, + { 4725, 0x1404 }, { 4728, 0x6000 }, { 4730, 0x9f87 }, { 4740, 0xb9d9 }, + { 4750, 0x059f }, { 4758, 0x540a }, { 4763, 0x245d }, { 4770, 0x3810 }, + /* 0x8d00 */ + { 4774, 0x25b0 }, { 4780, 0x0048 }, { 4782, 0x0000 }, { 4782, 0x0000 }, + { 4782, 0x0000 }, { 4782, 0x0000 }, { 4782, 0x0850 }, { 4785, 0x0099 }, + { 4789, 0x0420 }, { 4791, 0x0200 }, { 4792, 0x0108 }, { 4794, 0x4408 }, + { 4797, 0x9840 }, { 4801, 0x2800 }, { 4803, 0x810a }, { 4807, 0x0008 }, + /* 0x8e00 */ + { 4808, 0x8400 }, { 4810, 0x4001 }, { 4812, 0x0400 }, { 4813, 0x0021 }, + { 4815, 0x0794 }, { 4821, 0x8200 }, { 4823, 0x0001 }, { 4824, 0x0050 }, + { 4826, 0x2482 }, { 4830, 0x0000 }, { 4830, 0x1c00 }, { 4833, 0x0000 }, + { 4833, 0x3c01 }, { 4838, 0x8004 }, { 4840, 0x0800 }, { 4841, 0x4900 }, + /* 0x8f00 */ + { 4844, 0x0228 }, { 4847, 0xf83c }, { 4856, 0x86c0 }, { 4861, 0xcb08 }, + { 4867, 0x6230 }, { 4872, 0xa000 }, { 4874, 0x0004 }, { 4875, 0x0000 }, + { 4875, 0x0000 }, { 4875, 0x1800 }, { 4877, 0xa148 }, { 4882, 0x0007 }, + { 4885, 0x4024 }, { 4888, 0x0012 }, { 4890, 0x2c40 }, { 4894, 0x2285 }, + /* 0x9000 */ + { 4899, 0xa96f }, { 4909, 0xe6b3 }, { 4919, 0x400f }, { 4924, 0x5126 }, + { 4930, 0x6c86 }, { 4937, 0x723b }, { 4946, 0xe20b }, { 4953, 0xb5a4 }, + { 4961, 0x859f }, { 4970, 0x0222 }, { 4973, 0x854c }, { 4979, 0x0123 }, + { 4983, 0x0402 }, { 4985, 0x4000 }, { 4986, 0x2102 }, { 4989, 0x2020 }, + /* 0x9100 */ + { 4991, 0x0004 }, { 4992, 0x0224 }, { 4995, 0x2080 }, { 4997, 0x0004 }, + { 4998, 0x7e00 }, { 5004, 0x0004 }, { 5005, 0x1604 }, { 5009, 0x01a0 }, + { 5012, 0x2a80 }, { 5016, 0x1004 }, { 5018, 0xd800 }, { 5022, 0x0032 }, + { 5025, 0xfa81 }, { 5033, 0x3183 }, { 5039, 0x0488 }, { 5042, 0x0020 }, + /* 0x9200 */ + { 5043, 0x2000 }, { 5044, 0x4087 }, { 5049, 0x0000 }, { 5049, 0x8410 }, + { 5052, 0x0221 }, { 5055, 0x4880 }, { 5058, 0x0074 }, { 5062, 0x0000 }, + { 5062, 0x0029 }, { 5065, 0x114a }, { 5070, 0x0000 }, { 5070, 0x02c8 }, + { 5074, 0x9000 }, { 5076, 0x0004 }, { 5077, 0x0410 }, { 5079, 0x1100 }, + /* 0x9300 */ + { 5081, 0x0010 }, { 5082, 0xc501 }, { 5087, 0xc957 }, { 5096, 0x0000 }, + { 5096, 0x2d00 }, { 5100, 0x0810 }, { 5102, 0x4000 }, { 5103, 0x5020 }, + { 5106, 0x1000 }, { 5107, 0x0450 }, { 5110, 0x3088 }, { 5114, 0x0001 }, + { 5115, 0x0008 }, { 5116, 0x4002 }, { 5118, 0x0012 }, { 5120, 0x0040 }, + /* 0x9400 */ + { 5121, 0x0010 }, { 5122, 0x0100 }, { 5123, 0x0820 }, { 5125, 0x0120 }, + { 5127, 0x0010 }, { 5128, 0x0806 }, { 5131, 0x0000 }, { 5131, 0xa000 }, + { 5133, 0x0000 }, { 5133, 0x0000 }, { 5133, 0x0000 }, { 5133, 0x0000 }, + { 5133, 0x0000 }, { 5133, 0x0000 }, { 5133, 0x0000 }, { 5133, 0x0000 }, + /* 0x9500 */ + { 5133, 0x0000 }, { 5133, 0x0000 }, { 5133, 0x0000 }, { 5133, 0x0000 }, + { 5133, 0x0000 }, { 5133, 0x0000 }, { 5133, 0x0000 }, { 5133, 0x0080 }, + { 5134, 0x8a09 }, { 5139, 0x011e }, { 5144, 0x2138 }, { 5149, 0x1802 }, + { 5152, 0x0480 }, { 5154, 0x1070 }, { 5158, 0x0006 }, { 5160, 0x0000 }, + /* 0x9600 */ + { 5160, 0x0000 }, { 5160, 0x1000 }, { 5161, 0x4402 }, { 5164, 0x8804 }, + { 5167, 0x3815 }, { 5173, 0xf801 }, { 5179, 0x041c }, { 5183, 0x21e9 }, + { 5190, 0x6c60 }, { 5196, 0x1b30 }, { 5202, 0x0588 }, { 5206, 0x0882 }, + { 5209, 0x7af3 }, { 5220, 0x1a60 }, { 5225, 0x870c }, { 5231, 0x0ac5 }, + /* 0x9700 */ + { 5237, 0x00c1 }, { 5240, 0x524a }, { 5246, 0x0080 }, { 5247, 0x2205 }, + { 5251, 0x0114 }, { 5254, 0x5042 }, { 5258, 0x2206 }, { 5262, 0x0490 }, + { 5265, 0xa800 }, { 5268, 0x0000 }, { 5268, 0x2901 }, { 5272, 0x0000 }, + { 5272, 0x0840 }, { 5274, 0x1008 }, { 5276, 0x0000 }, { 5276, 0x8848 }, + /* 0x9800 */ + { 5280, 0x156f }, { 5289, 0x018f }, { 5295, 0x2000 }, { 5296, 0x0b01 }, + { 5300, 0x7040 }, { 5304, 0x4510 }, { 5308, 0x88a0 }, { 5312, 0x0000 }, + { 5312, 0x0000 }, { 5312, 0x0000 }, { 5312, 0x8100 }, { 5314, 0x0002 }, + { 5315, 0x0090 }, { 5317, 0x9800 }, { 5320, 0xe006 }, { 5325, 0x7010 }, + /* 0x9900 */ + { 5329, 0x1608 }, { 5333, 0x4109 }, { 5337, 0x0101 }, { 5339, 0x0000 }, + { 5339, 0x3a20 }, { 5344, 0x0096 }, { 5348, 0x0000 }, { 5348, 0x0000 }, + { 5348, 0x0000 }, { 5348, 0x2240 }, { 5351, 0x7120 }, { 5356, 0x021a }, + { 5360, 0x0002 }, { 5361, 0xa227 }, { 5368, 0x2000 }, { 5369, 0x8002 }, + /* 0x9a00 */ + { 5371, 0xc102 }, { 5375, 0x0200 }, { 5376, 0x0800 }, { 5377, 0x00c1 }, + { 5380, 0x2029 }, { 5384, 0x8ca0 }, { 5389, 0x0624 }, { 5393, 0x0000 }, + { 5393, 0x0000 }, { 5393, 0x0000 }, { 5393, 0x0100 }, { 5394, 0x0100 }, + { 5395, 0x0000 }, { 5395, 0x0118 }, { 5398, 0x4020 }, { 5400, 0x0000 }, + /* 0x9b00 */ + { 5400, 0x0000 }, { 5400, 0x0400 }, { 5401, 0x0480 }, { 5403, 0x1002 }, + { 5405, 0x803e }, { 5411, 0x0410 }, { 5413, 0x8000 }, { 5414, 0x0000 }, + { 5414, 0x4000 }, { 5415, 0x8002 }, { 5417, 0x4800 }, { 5419, 0x0000 }, + { 5419, 0x0200 }, { 5420, 0x0040 }, { 5421, 0x0110 }, { 5423, 0x0000 }, + /* 0x9c00 */ + { 5423, 0x2000 }, { 5424, 0x0025 }, { 5427, 0x0020 }, { 5428, 0x0804 }, + { 5430, 0x0280 }, { 5432, 0x0080 }, { 5433, 0x0000 }, { 5433, 0x0000 }, + { 5433, 0x0000 }, { 5433, 0x0000 }, { 5433, 0x0000 }, { 5433, 0x0000 }, + { 5433, 0x0000 }, { 5433, 0x0000 }, { 5433, 0x02a0 }, { 5436, 0x0058 }, + /* 0x9d00 */ + { 5439, 0x0200 }, { 5440, 0x0800 }, { 5441, 0x0140 }, { 5443, 0x0800 }, + { 5444, 0x0000 }, { 5444, 0x2002 }, { 5446, 0x1003 }, { 5449, 0x0004 }, + { 5450, 0x0000 }, { 5450, 0x0000 }, { 5450, 0x8200 }, { 5452, 0x0010 }, + { 5453, 0x0010 }, { 5454, 0x0080 }, { 5455, 0x0000 }, { 5455, 0x0704 }, + /* 0x9e00 */ + { 5459, 0x0000 }, { 5459, 0x4400 }, { 5461, 0x0000 }, { 5461, 0x0000 }, + { 5461, 0x0000 }, { 5461, 0x0000 }, { 5461, 0x0000 }, { 5461, 0xa220 }, + { 5465, 0x0000 }, { 5465, 0xa08c }, { 5470, 0x0020 }, { 5471, 0x4830 }, + { 5475, 0x6008 }, { 5478, 0x5912 }, { 5484, 0x0100 }, { 5485, 0x0010 }, + /* 0x9f00 */ + { 5486, 0x4180 }, { 5489, 0x0008 }, { 5490, 0x0001 }, { 5491, 0x0800 }, + { 5492, 0x4c00 }, { 5495, 0x8004 }, { 5497, 0x1482 }, { 5501, 0x0080 }, + { 5502, 0x2000 }, { 5503, 0x1021 }, +}; +static const Summary16 ksc5601_uni2indx_pageac[698] = { + /* 0xac00 */ + { 5506, 0x0793 }, { 5513, 0x3eff }, { 5526, 0xb011 }, { 5531, 0x1303 }, + { 5536, 0x2801 }, { 5539, 0x1110 }, { 5542, 0x0000 }, { 5542, 0x0593 }, + { 5548, 0x1e7b }, { 5558, 0xb011 }, { 5563, 0x9703 }, { 5570, 0x3b01 }, + { 5576, 0x1112 }, { 5580, 0x00a0 }, { 5582, 0x9593 }, { 5590, 0x306b }, + /* 0xad00 */ + { 5597, 0xb051 }, { 5603, 0x1102 }, { 5606, 0x3201 }, { 5610, 0x1130 }, + { 5614, 0x02b0 }, { 5618, 0x0111 }, { 5621, 0x300a }, { 5625, 0xb879 }, + { 5634, 0x1306 }, { 5639, 0x3001 }, { 5642, 0x0010 }, { 5643, 0x0080 }, + { 5644, 0x0113 }, { 5648, 0x100b }, { 5652, 0x0011 }, { 5654, 0x9300 }, + /* 0xae00 */ + { 5658, 0x2b03 }, { 5664, 0x0010 }, { 5665, 0x0000 }, { 5665, 0x0593 }, + { 5671, 0x746b }, { 5680, 0xb051 }, { 5686, 0x1323 }, { 5692, 0x3b01 }, + { 5698, 0x1030 }, { 5701, 0x0000 }, { 5701, 0x0000 }, { 5701, 0x7000 }, + { 5704, 0xb011 }, { 5709, 0x1303 }, { 5714, 0x2900 }, { 5717, 0x1110 }, + /* 0xaf00 */ + { 5720, 0x2180 }, { 5723, 0x0001 }, { 5724, 0x3000 }, { 5726, 0xb015 }, + { 5732, 0x030e }, { 5737, 0x3001 }, { 5740, 0x0030 }, { 5742, 0x0200 }, + { 5743, 0x0111 }, { 5746, 0x1023 }, { 5750, 0x0000 }, { 5750, 0x1300 }, + { 5753, 0x6b81 }, { 5760, 0x1010 }, { 5762, 0x0300 }, { 5764, 0x0113 }, + /* 0xb000 */ + { 5768, 0x1013 }, { 5772, 0x3011 }, { 5776, 0x0100 }, { 5777, 0x0000 }, + { 5777, 0x5530 }, { 5783, 0x22b8 }, { 5789, 0x0000 }, { 5789, 0x3000 }, + { 5791, 0xb011 }, { 5796, 0x9702 }, { 5802, 0xfb07 }, { 5812, 0x113a }, + { 5818, 0x03b0 }, { 5823, 0x0113 }, { 5827, 0x0021 }, { 5829, 0x0000 }, + /* 0xb100 */ + { 5829, 0x1b00 }, { 5833, 0x3b0d }, { 5841, 0x1138 }, { 5846, 0x03b0 }, + { 5851, 0x0113 }, { 5855, 0x1133 }, { 5861, 0x0001 }, { 5862, 0x1300 }, + { 5865, 0x2b05 }, { 5871, 0x111c }, { 5876, 0x0100 }, { 5877, 0x0000 }, + { 5877, 0x1000 }, { 5878, 0xb011 }, { 5883, 0x1300 }, { 5886, 0x2a01 }, + /* 0xb200 */ + { 5890, 0x1930 }, { 5895, 0x02b0 }, { 5899, 0x0001 }, { 5900, 0x1010 }, + { 5902, 0x0000 }, { 5902, 0x1100 }, { 5904, 0x0301 }, { 5907, 0x1030 }, + { 5910, 0x0230 }, { 5913, 0x0713 }, { 5919, 0x146b }, { 5926, 0x0011 }, + { 5928, 0x1300 }, { 5931, 0x2b05 }, { 5937, 0xf974 }, { 5947, 0x8fb8 }, + /* 0xb300 */ + { 5956, 0x0113 }, { 5960, 0x103b }, { 5966, 0x0000 }, { 5966, 0x0000 }, + { 5966, 0x0000 }, { 5966, 0xd970 }, { 5974, 0x4ab0 }, { 5980, 0x0113 }, + { 5984, 0x103b }, { 5990, 0x0011 }, { 5992, 0x1103 }, { 5996, 0x0000 }, + { 5996, 0x5930 }, { 6002, 0x2ab1 }, { 6009, 0x0111 }, { 6012, 0x1000 }, + /* 0xb400 */ + { 6013, 0x0000 }, { 6013, 0x1101 }, { 6016, 0x0b01 }, { 6020, 0x0010 }, + { 6021, 0x0000 }, { 6021, 0x0113 }, { 6025, 0x102b }, { 6030, 0x0000 }, + { 6030, 0x0101 }, { 6032, 0x2000 }, { 6033, 0x1110 }, { 6036, 0x02a0 }, + { 6039, 0x0111 }, { 6042, 0x3021 }, { 6046, 0xb059 }, { 6053, 0x0102 }, + /* 0xb500 */ + { 6055, 0x0000 }, { 6055, 0x1930 }, { 6060, 0x07b0 }, { 6066, 0x0113 }, + { 6070, 0x383b }, { 6078, 0xb011 }, { 6083, 0x0003 }, { 6085, 0x0000 }, + { 6085, 0x0000 }, { 6085, 0x0000 }, { 6085, 0x0d13 }, { 6091, 0x383b }, + { 6099, 0xb011 }, { 6104, 0x0103 }, { 6107, 0x1000 }, { 6108, 0x0000 }, + /* 0xb600 */ + { 6108, 0x0000 }, { 6108, 0x0113 }, { 6112, 0x1020 }, { 6114, 0x0010 }, + { 6115, 0x0100 }, { 6116, 0x0000 }, { 6116, 0x0110 }, { 6118, 0x0000 }, + { 6118, 0x0000 }, { 6118, 0x3000 }, { 6120, 0x1811 }, { 6124, 0x0002 }, + { 6125, 0x0000 }, { 6125, 0x0010 }, { 6126, 0x0000 }, { 6126, 0x0111 }, + /* 0xb700 */ + { 6129, 0x0023 }, { 6132, 0x0000 }, { 6132, 0x9300 }, { 6136, 0x0b01 }, + { 6140, 0x1110 }, { 6143, 0x0030 }, { 6145, 0x0111 }, { 6148, 0x302b }, + { 6154, 0xb011 }, { 6159, 0x13c7 }, { 6167, 0x3b01 }, { 6173, 0x0130 }, + { 6176, 0x0280 }, { 6178, 0x0000 }, { 6178, 0x3000 }, { 6180, 0xb011 }, + /* 0xb800 */ + { 6185, 0x1383 }, { 6191, 0x2b01 }, { 6196, 0x1130 }, { 6200, 0x03b0 }, + { 6205, 0x0011 }, { 6207, 0x300a }, { 6211, 0xb011 }, { 6216, 0x1102 }, + { 6219, 0x2000 }, { 6220, 0x0000 }, { 6220, 0x0100 }, { 6221, 0x0111 }, + { 6224, 0x102b }, { 6229, 0xa011 }, { 6233, 0x1302 }, { 6237, 0x2b01 }, + /* 0xb900 */ + { 6242, 0x0010 }, { 6243, 0x0100 }, { 6244, 0x0001 }, { 6245, 0x3000 }, + { 6247, 0x9011 }, { 6251, 0x1302 }, { 6255, 0x2b01 }, { 6260, 0x1130 }, + { 6264, 0x66b0 }, { 6271, 0x0000 }, { 6271, 0x3000 }, { 6273, 0xb011 }, + { 6278, 0xd302 }, { 6284, 0x6b07 }, { 6292, 0x113a }, { 6298, 0x07b0 }, + /* 0xba00 */ + { 6304, 0x0103 }, { 6307, 0x0020 }, { 6308, 0x0000 }, { 6308, 0x1300 }, + { 6311, 0x6b05 }, { 6318, 0x1138 }, { 6323, 0x03b0 }, { 6328, 0x0113 }, + { 6332, 0x10b8 }, { 6337, 0x0000 }, { 6337, 0x1b00 }, { 6341, 0x2b05 }, + { 6347, 0x0110 }, { 6349, 0x0300 }, { 6351, 0x0000 }, { 6351, 0x1000 }, + /* 0xbb00 */ + { 6352, 0xa011 }, { 6356, 0x1102 }, { 6359, 0x0a01 }, { 6362, 0x7970 }, + { 6370, 0xa2b0 }, { 6376, 0x0111 }, { 6379, 0x100a }, { 6382, 0x0000 }, + { 6382, 0x1100 }, { 6384, 0x0001 }, { 6385, 0x1110 }, { 6388, 0x0090 }, + { 6390, 0x0111 }, { 6393, 0x0009 }, { 6395, 0x0000 }, { 6395, 0x9300 }, + /* 0xbc00 */ + { 6399, 0xbb05 }, { 6407, 0xf9f2 }, { 6418, 0x22b0 }, { 6423, 0x0113 }, + { 6427, 0x323b }, { 6435, 0x2001 }, { 6437, 0x0000 }, { 6437, 0x0000 }, + { 6437, 0x5930 }, { 6443, 0x06b0 }, { 6448, 0x0193 }, { 6453, 0x303b }, + { 6460, 0xa011 }, { 6464, 0x1123 }, { 6469, 0x0000 }, { 6469, 0x1170 }, + /* 0xbd00 */ + { 6474, 0x02b0 }, { 6478, 0x0011 }, { 6480, 0x1010 }, { 6482, 0x0000 }, + { 6482, 0x1301 }, { 6486, 0x0301 }, { 6489, 0x0110 }, { 6491, 0x0000 }, + { 6491, 0x0793 }, { 6498, 0x162b }, { 6505, 0x0010 }, { 6506, 0x0101 }, + { 6508, 0x0000 }, { 6508, 0x1130 }, { 6512, 0x0200 }, { 6513, 0x0111 }, + /* 0xbe00 */ + { 6516, 0x3029 }, { 6521, 0xb011 }, { 6526, 0x0000 }, { 6526, 0x0000 }, + { 6526, 0x5130 }, { 6531, 0x0eb0 }, { 6537, 0x0513 }, { 6542, 0x383b }, + { 6550, 0xb011 }, { 6555, 0x0303 }, { 6559, 0x0100 }, { 6560, 0x0000 }, + { 6560, 0x0000 }, { 6560, 0x0193 }, { 6565, 0x1039 }, { 6570, 0x0000 }, + /* 0xbf00 */ + { 6570, 0x0302 }, { 6573, 0x3b00 }, { 6578, 0x0000 }, { 6578, 0x0000 }, + { 6578, 0x0113 }, { 6582, 0x0023 }, { 6585, 0x0000 }, { 6585, 0x0000 }, + { 6585, 0x0000 }, { 6585, 0x0010 }, { 6586, 0x0000 }, { 6586, 0x0001 }, + { 6587, 0x3020 }, { 6590, 0x9011 }, { 6594, 0x0002 }, { 6595, 0x0000 }, + /* 0xc000 */ + { 6595, 0x0000 }, { 6595, 0x0000 }, { 6595, 0x0000 }, { 6595, 0x1000 }, + { 6596, 0x0000 }, { 6596, 0x1102 }, { 6599, 0x0301 }, { 6602, 0x0000 }, + { 6602, 0x0000 }, { 6602, 0x0113 }, { 6606, 0xb02b }, { 6613, 0xb079 }, + { 6621, 0x1323 }, { 6627, 0x3b01 }, { 6633, 0x1130 }, { 6637, 0x02b0 }, + /* 0xc100 */ + { 6641, 0x0111 }, { 6644, 0xf021 }, { 6650, 0xb0d9 }, { 6658, 0x1343 }, + { 6664, 0x3b01 }, { 6670, 0x1130 }, { 6674, 0x03b0 }, { 6679, 0x0111 }, + { 6682, 0x7020 }, { 6686, 0xb051 }, { 6692, 0x1322 }, { 6697, 0x2001 }, + { 6699, 0x1110 }, { 6702, 0x0190 }, { 6705, 0x0111 }, { 6708, 0x300b }, + /* 0xc200 */ + { 6713, 0xb011 }, { 6718, 0x9302 }, { 6723, 0xab01 }, { 6729, 0x0016 }, + { 6732, 0x0100 }, { 6733, 0x0113 }, { 6737, 0x3021 }, { 6741, 0xb011 }, + { 6746, 0x0302 }, { 6749, 0x2901 }, { 6753, 0x3130 }, { 6758, 0x02b0 }, + { 6762, 0x0000 }, { 6762, 0x3000 }, { 6764, 0xb819 }, { 6771, 0x1b42 }, + /* 0xc300 */ + { 6777, 0x3301 }, { 6782, 0x1138 }, { 6787, 0x0330 }, { 6791, 0x0000 }, + { 6791, 0x0020 }, { 6792, 0x0000 }, { 6792, 0x1300 }, { 6795, 0x3305 }, + { 6801, 0x1110 }, { 6804, 0x0000 }, { 6804, 0x0000 }, { 6804, 0x0000 }, + { 6804, 0x0001 }, { 6805, 0x9300 }, { 6809, 0x2305 }, { 6814, 0x0130 }, + /* 0xc400 */ + { 6817, 0x0100 }, { 6818, 0x0001 }, { 6819, 0x1010 }, { 6821, 0x3011 }, + { 6825, 0x0100 }, { 6826, 0x0000 }, { 6826, 0x1130 }, { 6830, 0x0230 }, + { 6833, 0x0001 }, { 6834, 0x1010 }, { 6836, 0x0000 }, { 6836, 0x1100 }, + { 6838, 0x0000 }, { 6838, 0x0000 }, { 6838, 0x0200 }, { 6839, 0x8513 }, + /* 0xc500 */ + { 6845, 0x1003 }, { 6848, 0x1011 }, { 6851, 0x1300 }, { 6854, 0x2b01 }, + { 6859, 0x7730 }, { 6867, 0x63b8 }, { 6875, 0x0113 }, { 6879, 0x303b }, + { 6886, 0xb091 }, { 6892, 0x11a2 }, { 6897, 0x0201 }, { 6899, 0x7b30 }, + { 6907, 0x57f0 }, { 6916, 0x0113 }, { 6920, 0x702b }, { 6927, 0xf0d1 }, + /* 0xc600 */ + { 6935, 0x11e3 }, { 6942, 0x1b01 }, { 6947, 0x7130 }, { 6953, 0x0ab9 }, + { 6960, 0x0113 }, { 6964, 0x303b }, { 6971, 0x9001 }, { 6974, 0x1302 }, + { 6978, 0x2b01 }, { 6983, 0x1130 }, { 6987, 0x02b0 }, { 6991, 0x0713 }, + { 6997, 0x302b }, { 7003, 0x3011 }, { 7007, 0x1303 }, { 7012, 0x2301 }, + /* 0xc700 */ + { 7016, 0x1130 }, { 7020, 0x02b0 }, { 7024, 0x0113 }, { 7028, 0x30ab }, + { 7035, 0xb411 }, { 7041, 0x11fe }, { 7050, 0x0901 }, { 7053, 0x7130 }, + { 7059, 0x47b8 }, { 7067, 0x05d3 }, { 7074, 0x307b }, { 7082, 0xb011 }, + { 7087, 0x5303 }, { 7093, 0x2101 }, { 7096, 0x1110 }, { 7099, 0x0000 }, + /* 0xc800 */ + { 7099, 0x0513 }, { 7104, 0x306b }, { 7111, 0xb011 }, { 7116, 0x1102 }, + { 7119, 0x3301 }, { 7124, 0x0010 }, { 7125, 0x0000 }, { 7125, 0x0513 }, + { 7130, 0x38eb }, { 7139, 0xa010 }, { 7142, 0x0102 }, { 7144, 0x3000 }, + { 7146, 0x1110 }, { 7149, 0x02b0 }, { 7153, 0x0013 }, { 7156, 0x3020 }, + /* 0xc900 */ + { 7159, 0xb071 }, { 7166, 0x0102 }, { 7168, 0x1000 }, { 7169, 0x0010 }, + { 7170, 0x0000 }, { 7170, 0x0113 }, { 7174, 0x100b }, { 7178, 0x1011 }, + { 7181, 0x1300 }, { 7184, 0x2b01 }, { 7189, 0x0000 }, { 7189, 0x0000 }, + { 7189, 0x0593 }, { 7195, 0x366b }, { 7204, 0xb095 }, { 7211, 0x1303 }, + /* 0xca00 */ + { 7216, 0x3b01 }, { 7222, 0x0110 }, { 7224, 0x0200 }, { 7225, 0x0000 }, + { 7225, 0x3000 }, { 7227, 0xb011 }, { 7232, 0x0103 }, { 7235, 0x2000 }, + { 7236, 0x0010 }, { 7237, 0x0100 }, { 7238, 0x0000 }, { 7238, 0x3000 }, + { 7240, 0xb011 }, { 7245, 0x030a }, { 7249, 0x1001 }, { 7251, 0x0010 }, + /* 0xcb00 */ + { 7252, 0x0100 }, { 7253, 0x0111 }, { 7256, 0x0003 }, { 7258, 0x0000 }, + { 7258, 0x1302 }, { 7262, 0x2301 }, { 7266, 0x0010 }, { 7267, 0x0300 }, + { 7269, 0x0000 }, { 7269, 0x1000 }, { 7270, 0x0000 }, { 7270, 0x0100 }, + { 7271, 0x0000 }, { 7271, 0x0010 }, { 7272, 0x0290 }, { 7275, 0x0000 }, + /* 0xcc00 */ + { 7275, 0x3000 }, { 7277, 0x3011 }, { 7281, 0x5386 }, { 7288, 0x7b01 }, + { 7295, 0x1130 }, { 7299, 0x03b0 }, { 7304, 0x0151 }, { 7308, 0x0021 }, + { 7310, 0x0000 }, { 7310, 0x1300 }, { 7313, 0x3b01 }, { 7319, 0x1130 }, + { 7323, 0x02b0 }, { 7327, 0x0011 }, { 7329, 0x1010 }, { 7331, 0x0001 }, + /* 0xcd00 */ + { 7332, 0x1302 }, { 7336, 0x2b01 }, { 7341, 0x1110 }, { 7344, 0x0200 }, + { 7345, 0x0000 }, { 7345, 0x1000 }, { 7346, 0xb011 }, { 7351, 0x0102 }, + { 7353, 0x0100 }, { 7354, 0x1130 }, { 7358, 0x02b0 }, { 7362, 0x0001 }, + { 7363, 0x1010 }, { 7365, 0x0001 }, { 7366, 0x1100 }, { 7368, 0x2b01 }, + /* 0xce00 */ + { 7373, 0x1110 }, { 7376, 0x0210 }, { 7378, 0x0113 }, { 7382, 0x002b }, + { 7386, 0x0000 }, { 7386, 0x9300 }, { 7390, 0x2b03 }, { 7396, 0x1130 }, + { 7400, 0x02b0 }, { 7404, 0x0113 }, { 7408, 0x303b }, { 7415, 0x0000 }, + { 7415, 0x0002 }, { 7416, 0x0000 }, { 7416, 0x1930 }, { 7421, 0x03b0 }, + /* 0xcf00 */ + { 7426, 0x0113 }, { 7430, 0x102b }, { 7435, 0xb011 }, { 7440, 0x0103 }, + { 7443, 0x0000 }, { 7443, 0x1130 }, { 7447, 0x02b0 }, { 7451, 0x0113 }, + { 7455, 0x1021 }, { 7458, 0x0000 }, { 7458, 0x0102 }, { 7460, 0x0001 }, + { 7461, 0x0010 }, { 7462, 0x0000 }, { 7462, 0x0113 }, { 7466, 0x102b }, + /* 0xd000 */ + { 7471, 0x0011 }, { 7473, 0x0102 }, { 7475, 0x2000 }, { 7476, 0x1130 }, + { 7480, 0x02b0 }, { 7484, 0x0111 }, { 7487, 0x3001 }, { 7490, 0x3011 }, + { 7494, 0x0002 }, { 7495, 0x0000 }, { 7495, 0x1130 }, { 7499, 0x02b0 }, + { 7503, 0x0313 }, { 7508, 0x303b }, { 7515, 0xb011 }, { 7520, 0x0103 }, + /* 0xd100 */ + { 7523, 0x2000 }, { 7524, 0x0000 }, { 7524, 0x0000 }, { 7524, 0x0513 }, + { 7529, 0x303b }, { 7536, 0xb011 }, { 7541, 0x1102 }, { 7544, 0x1000 }, + { 7545, 0x0110 }, { 7547, 0x0000 }, { 7547, 0x0113 }, { 7551, 0x142b }, + { 7557, 0x0001 }, { 7558, 0x0100 }, { 7559, 0x0000 }, { 7559, 0x0110 }, + /* 0xd200 */ + { 7561, 0x0280 }, { 7563, 0x0001 }, { 7564, 0x3000 }, { 7566, 0xb011 }, + { 7571, 0x0102 }, { 7573, 0x1000 }, { 7574, 0x0010 }, { 7575, 0x0000 }, + { 7575, 0x0113 }, { 7579, 0x1023 }, { 7583, 0x1011 }, { 7586, 0x9302 }, + { 7591, 0x0b05 }, { 7596, 0x1110 }, { 7599, 0x0030 }, { 7601, 0x0113 }, + /* 0xd300 */ + { 7605, 0x702b }, { 7612, 0xb051 }, { 7618, 0x1323 }, { 7624, 0x3b01 }, + { 7630, 0x0030 }, { 7632, 0x0000 }, { 7632, 0x0000 }, { 7632, 0x3000 }, + { 7634, 0xb011 }, { 7639, 0x1303 }, { 7644, 0x2b01 }, { 7649, 0x1110 }, + { 7652, 0x0330 }, { 7656, 0x0101 }, { 7658, 0x300a }, { 7662, 0xb011 }, + /* 0xd400 */ + { 7667, 0x0102 }, { 7669, 0x2000 }, { 7670, 0x0000 }, { 7670, 0x0000 }, + { 7670, 0x0011 }, { 7672, 0x1000 }, { 7673, 0xa011 }, { 7677, 0x9300 }, + { 7681, 0x2b05 }, { 7687, 0x0010 }, { 7688, 0x0200 }, { 7689, 0x0000 }, + { 7689, 0x1000 }, { 7690, 0x9011 }, { 7694, 0x1100 }, { 7696, 0x2901 }, + /* 0xd500 */ + { 7700, 0x1110 }, { 7703, 0x00b0 }, { 7706, 0x0000 }, { 7706, 0x3000 }, + { 7708, 0xb011 }, { 7713, 0x1302 }, { 7717, 0x2b21 }, { 7723, 0x1130 }, + { 7727, 0x03b0 }, { 7732, 0x0001 }, { 7733, 0x0020 }, { 7734, 0x0000 }, + { 7734, 0x1300 }, { 7737, 0x2b05 }, { 7743, 0x1130 }, { 7747, 0x02b0 }, + /* 0xd600 */ + { 7751, 0x0113 }, { 7755, 0x103b }, { 7761, 0x2011 }, { 7764, 0x1300 }, + { 7767, 0x2b21 }, { 7773, 0x1132 }, { 7778, 0x0280 }, { 7780, 0x0013 }, + { 7783, 0x3028 }, { 7787, 0xa011 }, { 7791, 0x1102 }, { 7794, 0x0a01 }, + { 7797, 0x1130 }, { 7801, 0x0292 }, { 7805, 0x0111 }, { 7808, 0x3021 }, + /* 0xd700 */ + { 7812, 0x0011 }, { 7814, 0x1302 }, { 7818, 0x2b01 }, { 7823, 0x1130 }, + { 7827, 0x0290 }, { 7830, 0x03d3 }, { 7837, 0x122b }, { 7843, 0x3011 }, + { 7847, 0x1302 }, { 7851, 0x2b01 }, +}; +static const Summary16 ksc5601_uni2indx_pagef9[17] = { + /* 0xf900 */ + { 7856, 0xffff }, { 7872, 0xffff }, { 7888, 0xffff }, { 7904, 0xffff }, + { 7920, 0xffff }, { 7936, 0xffff }, { 7952, 0xffff }, { 7968, 0xffff }, + { 7984, 0xffff }, { 8000, 0xffff }, { 8016, 0xffff }, { 8032, 0xffff }, + { 8048, 0xffff }, { 8064, 0xffff }, { 8080, 0xffff }, { 8096, 0xffff }, + /* 0xfa00 */ + { 8112, 0x0fff }, +}; +static const Summary16 ksc5601_uni2indx_pageff[15] = { + /* 0xff00 */ + { 8124, 0xfffe }, { 8139, 0xffff }, { 8155, 0xffff }, { 8171, 0xffff }, + { 8187, 0xffff }, { 8203, 0x7fff }, { 8218, 0x0000 }, { 8218, 0x0000 }, + { 8218, 0x0000 }, { 8218, 0x0000 }, { 8218, 0x0000 }, { 8218, 0x0000 }, + { 8218, 0x0000 }, { 8218, 0x0000 }, { 8218, 0x006f }, +}; + +static int +ksc5601_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (n >= 2) { + const Summary16 *summary = NULL; + if (wc < 0x0460) + summary = &ksc5601_uni2indx_page00[(wc>>4)]; + else if (wc >= 0x2000 && wc < 0x2670) + summary = &ksc5601_uni2indx_page20[(wc>>4)-0x200]; + else if (wc >= 0x3000 && wc < 0x33e0) + summary = &ksc5601_uni2indx_page30[(wc>>4)-0x300]; + else if (wc >= 0x4e00 && wc < 0x9fa0) + summary = &ksc5601_uni2indx_page4e[(wc>>4)-0x4e0]; + else if (wc >= 0xac00 && wc < 0xd7a0) + summary = &ksc5601_uni2indx_pageac[(wc>>4)-0xac0]; + else if (wc >= 0xf900 && wc < 0xfa10) + summary = &ksc5601_uni2indx_pagef9[(wc>>4)-0xf90]; + else if (wc >= 0xff00 && wc < 0xfff0) + summary = &ksc5601_uni2indx_pageff[(wc>>4)-0xff0]; + if (summary) { + unsigned short used = summary->used; + unsigned int i = wc & 0x0f; + if (used & ((unsigned short) 1 << i)) { + unsigned short c; + /* Keep in `used' only the bits 0..i-1. */ + used &= ((unsigned short) 1 << i) - 1; + /* Add `summary->indx' and the number of bits set in `used'. */ + used = (used & 0x5555) + ((used & 0xaaaa) >> 1); + used = (used & 0x3333) + ((used & 0xcccc) >> 2); + used = (used & 0x0f0f) + ((used & 0xf0f0) >> 4); + used = (used & 0x00ff) + (used >> 8); + c = ksc5601_2charset[summary->indx + used]; + r[0] = (c >> 8); r[1] = (c & 0xff); + return 2; + } + } + return RET_ILSEQ; + } + return RET_TOOSMALL; +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/mulelao.h b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/mulelao.h new file mode 100644 index 0000000..2afd7b5 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/mulelao.h @@ -0,0 +1,78 @@ +/* $XFree86: xc/lib/X11/lcUniConv/mulelao.h,v 1.3 2000/11/29 17:40:35 dawes Exp $ */ + +/* + * MULELAO-1 + */ + +static const unsigned short mulelao_2uni[96] = { + /* 0xa0 */ + 0x00a0, 0x0e81, 0x0e82, 0xfffd, 0x0e84, 0xfffd, 0xfffd, 0x0e87, + 0x0e88, 0xfffd, 0x0e8a, 0xfffd, 0xfffd, 0x0e8d, 0xfffd, 0xfffd, + /* 0xb0 */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x0e94, 0x0e95, 0x0e96, 0x0e97, + 0xfffd, 0x0e99, 0x0e9a, 0x0e9b, 0x0e9c, 0x0e9d, 0x0e9e, 0x0e9f, + /* 0xc0 */ + 0xfffd, 0x0ea1, 0x0ea2, 0x0ea3, 0xfffd, 0x0ea5, 0xfffd, 0x0ea7, + 0xfffd, 0xfffd, 0x0eaa, 0x0eab, 0xfffd, 0x0ead, 0x0eae, 0x0eaf, + /* 0xd0 */ + 0x0eb0, 0x0eb1, 0x0eb2, 0x0eb3, 0x0eb4, 0x0eb5, 0x0eb6, 0x0eb7, + 0x0eb8, 0x0eb9, 0xfffd, 0x0ebb, 0x0ebc, 0x0ebd, 0xfffd, 0xfffd, + /* 0xe0 */ + 0x0ec0, 0x0ec1, 0x0ec2, 0x0ec3, 0x0ec4, 0xfffd, 0x0ec6, 0xfffd, + 0x0ec8, 0x0ec9, 0x0eca, 0x0ecb, 0x0ecc, 0x0ecd, 0xfffd, 0xfffd, + /* 0xf0 */ + 0x0ed0, 0x0ed1, 0x0ed2, 0x0ed3, 0x0ed4, 0x0ed5, 0x0ed6, 0x0ed7, + 0x0ed8, 0x0ed9, 0xfffd, 0xfffd, 0x0edc, 0x0edd, 0xfffd, 0xfffd, +}; + +static int +mulelao_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0xa0) { + *pwc = (ucs4_t) c; + return 1; + } + else { + unsigned short wc = mulelao_2uni[c-0xa0]; + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 1; + } + } + return RET_ILSEQ; +} + +static const unsigned char mulelao_page0e[96] = { + 0x00, 0xa1, 0xa2, 0x00, 0xa4, 0x00, 0x00, 0xa7, /* 0x80-0x87 */ + 0xa8, 0x00, 0xaa, 0x00, 0x00, 0xad, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0xb4, 0xb5, 0xb6, 0xb7, /* 0x90-0x97 */ + 0x00, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, /* 0x98-0x9f */ + 0x00, 0xc1, 0xc2, 0xc3, 0x00, 0xc5, 0x00, 0xc7, /* 0xa0-0xa7 */ + 0x00, 0x00, 0xca, 0xcb, 0x00, 0xcd, 0xce, 0xcf, /* 0xa8-0xaf */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xb0-0xb7 */ + 0xd8, 0xd9, 0x00, 0xdb, 0xdc, 0xdd, 0x00, 0x00, /* 0xb8-0xbf */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0x00, 0xe6, 0x00, /* 0xc0-0xc7 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0x00, 0x00, /* 0xc8-0xcf */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xd0-0xd7 */ + 0xf8, 0xf9, 0x00, 0x00, 0xfc, 0xfd, 0x00, 0x00, /* 0xd8-0xdf */ +}; + +static int +mulelao_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x00a0) { + *r = wc; + return 1; + } + else if (wc == 0x00a0) + c = 0xa0; + else if (wc >= 0x0e80 && wc < 0x0ee0) + c = mulelao_page0e[wc-0x0e80]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILSEQ; +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/tatar_cyr.h b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/tatar_cyr.h new file mode 100644 index 0000000..5360700 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/tatar_cyr.h @@ -0,0 +1,123 @@ +/* $XFree86: xc/lib/X11/lcUniConv/tatar_cyr.h,v 1.3 2000/12/04 18:49:42 dawes Exp $ */ + +/* + * TATAR-CYR + */ + +static const unsigned short tatar_cyr_2uni[128] = { + /* 0x80 */ + 0x04d8, 0x0403, 0x201a, 0x0453, 0x201e, 0x2026, 0x2020, 0x2021, + 0x20ac, 0x2030, 0x04e8, 0x2039, 0x04ae, 0x0496, 0x04a2, 0x04ba, + /* 0x90 */ + 0x04d9, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + 0x98, 0x2122, 0x04e9, 0x203a, 0x04af, 0x0497, 0x04a3, 0x04bb, + /* 0xa0 */ + 0x00a0, 0x040e, 0x045e, 0x0408, 0x00a4, 0x0490, 0x00a6, 0x00a7, + 0x0401, 0x00a9, 0x0404, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x0407, + /* 0xb0 */ + 0x00b0, 0x00b1, 0x0406, 0x0456, 0x0491, 0x00b5, 0x00b6, 0x00b7, + 0x0451, 0x2116, 0x0454, 0x00bb, 0x0458, 0x0405, 0x0455, 0x0457, + /* 0xc0 */ + 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, + 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f, + /* 0xd0 */ + 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, + 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, + /* 0xe0 */ + 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, + 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, + /* 0xf0 */ + 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, + 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f, +}; + +static int +tatar_cyr_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) + *pwc = (ucs4_t) c; + else + *pwc = (ucs4_t) tatar_cyr_2uni[c-0x80]; + return 1; +} + +static const unsigned char tatar_cyr_page00[32] = { + 0xa0, 0x00, 0x00, 0x00, 0xa4, 0x00, 0xa6, 0xa7, /* 0xa0-0xa7 */ + 0x00, 0xa9, 0x00, 0xab, 0xac, 0xad, 0xae, 0x00, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0x00, 0x00, 0x00, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0xbb, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ +}; +static const unsigned char tatar_cyr_page04[240] = { + 0x00, 0xa8, 0x00, 0x81, 0xaa, 0xbd, 0xb2, 0xaf, /* 0x00-0x07 */ + 0xa3, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0x00, /* 0x08-0x0f */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0x10-0x17 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0x18-0x1f */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0x20-0x27 */ + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, /* 0x28-0x2f */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0x30-0x37 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0x38-0x3f */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0x40-0x47 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0x48-0x4f */ + 0x00, 0xb8, 0x00, 0x83, 0xba, 0xbe, 0xb3, 0xbf, /* 0x50-0x57 */ + 0xbc, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0xa5, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x8d, 0x9d, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x8e, 0x9e, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8c, 0x9c, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x8f, 0x9f, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x80, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x8a, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ +}; +static const unsigned char tatar_cyr_page20[48] = { + 0x00, 0x00, 0x00, 0x96, 0x97, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x91, 0x92, 0x82, 0x00, 0x93, 0x94, 0x84, 0x00, /* 0x18-0x1f */ + 0x86, 0x87, 0x95, 0x00, 0x00, 0x00, 0x85, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x8b, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ +}; +static const unsigned char tatar_cyr_page21[24] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb9, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ +}; +static const unsigned char tatar_cyr_page22[1] = { + 0xb0, /* 0x16-0x16 */ +}; + +static int +tatar_cyr_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x00bc) + c = tatar_cyr_page00[wc-0x00a0]; + else if (wc >= 0x0400 && wc < 0x04ef) + c = tatar_cyr_page04[wc-0x0400]; + else if (wc >= 0x2010 && wc < 0x203b) + c = tatar_cyr_page20[wc-0x2010]; + else if (wc == 0x20ac) + c = 0x88; + else if (wc >= 0x2110 && wc < 0x2123) + c = tatar_cyr_page21[wc-0x2110]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILSEQ; +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/tcvn.h b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/tcvn.h new file mode 100644 index 0000000..f3d4975 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/tcvn.h @@ -0,0 +1,134 @@ +/* $XFree86: xc/lib/X11/lcUniConv/tcvn.h,v 1.3 2000/11/29 17:40:35 dawes Exp $ */ + +/* + * TCVN-5712 + */ + +static const unsigned short tcvn_2uni_1[32] = { + /* 0x00 */ + 0x0000, 0x00da, 0x1ee4, 0x0003, 0x1eea, 0x1eec, 0x1eee, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + /* 0x10 */ + 0x0010, 0x1ee8, 0x1ef0, 0x1ef2, 0x1ef6, 0x1ef8, 0x00dd, 0x1ef4, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, +}; +static const unsigned short tcvn_2uni_2[128] = { + /* 0x80 */ + 0x00c0, 0x1ea2, 0x00c3, 0x00c1, 0x1ea0, 0x1eb6, 0x1eac, 0x00c8, + 0x1eba, 0x1ebc, 0x00c9, 0x1eb8, 0x1ec6, 0x00cc, 0x1ec8, 0x0128, + /* 0x90 */ + 0x00cd, 0x1eca, 0x00d2, 0x1ece, 0x00d5, 0x00d3, 0x1ecc, 0x1ed8, + 0x1edc, 0x1ede, 0x1ee0, 0x1eda, 0x1ee2, 0x00d9, 0x1ee6, 0x0168, + /* 0xa0 */ + 0x00a0, 0x0102, 0x00c2, 0x00ca, 0x00d4, 0x01a0, 0x01af, 0x0110, + 0x0103, 0x00e2, 0x00ea, 0x00f4, 0x01a1, 0x01b0, 0x0111, 0x1eb0, + /* 0xb0 */ + 0x0300, 0x0309, 0x0303, 0x0301, 0x0323, 0x00e0, 0x1ea3, 0x00e3, + 0x00e1, 0x1ea1, 0x1eb2, 0x1eb1, 0x1eb3, 0x1eb5, 0x1eaf, 0x1eb4, + /* 0xc0 */ + 0x1eae, 0x1ea6, 0x1ea8, 0x1eaa, 0x1ea4, 0x1ec0, 0x1eb7, 0x1ea7, + 0x1ea9, 0x1eab, 0x1ea5, 0x1ead, 0x00e8, 0x1ec2, 0x1ebb, 0x1ebd, + /* 0xd0 */ + 0x00e9, 0x1eb9, 0x1ec1, 0x1ec3, 0x1ec5, 0x1ebf, 0x1ec7, 0x00ec, + 0x1ec9, 0x1ec4, 0x1ebe, 0x1ed2, 0x0129, 0x00ed, 0x1ecb, 0x00f2, + /* 0xe0 */ + 0x1ed4, 0x1ecf, 0x00f5, 0x00f3, 0x1ecd, 0x1ed3, 0x1ed5, 0x1ed7, + 0x1ed1, 0x1ed9, 0x1edd, 0x1edf, 0x1ee1, 0x1edb, 0x1ee3, 0x00f9, + /* 0xf0 */ + 0x1ed6, 0x1ee7, 0x0169, 0x00fa, 0x1ee5, 0x1eeb, 0x1eed, 0x1eef, + 0x1ee9, 0x1ef1, 0x1ef3, 0x1ef7, 0x1ef9, 0x00fd, 0x1ef5, 0x1ed0, +}; + +static int +tcvn_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x20) + *pwc = (ucs4_t) tcvn_2uni_1[c]; + else if (c < 0x80) + *pwc = (ucs4_t) c; + else + *pwc = (ucs4_t) tcvn_2uni_2[c-0x80]; + return 1; +} + +static const unsigned char tcvn_page00[96+184] = { + 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x80, 0x83, 0xa2, 0x82, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x87, 0x8a, 0xa3, 0x00, 0x8d, 0x90, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x92, 0x95, 0xa4, 0x94, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x9d, 0x01, 0x00, 0x00, 0x16, 0x00, 0x00, /* 0xd8-0xdf */ + 0xb5, 0xb8, 0xa9, 0xb7, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0xcc, 0xd0, 0xaa, 0x00, 0xd7, 0xdd, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0xdf, 0xe3, 0xab, 0xe2, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0xef, 0xf3, 0x00, 0x00, 0xfd, 0x00, 0x00, /* 0xf8-0xff */ + /* 0x0100 */ + 0x00, 0x00, 0xa1, 0xa8, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0xa7, 0xae, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x8f, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x9f, 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xa5, 0xac, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, /* 0xa8-0xaf */ + 0xad, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ +}; +static const unsigned char tcvn_page03[40] = { + 0xb0, 0xb3, 0x00, 0xb2, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ +}; +static const unsigned char tcvn_page1e[96] = { + 0x84, 0xb9, 0x81, 0xb6, 0xc4, 0xca, 0xc1, 0xc7, /* 0xa0-0xa7 */ + 0xc2, 0xc8, 0xc3, 0xc9, 0x86, 0xcb, 0xc0, 0xbe, /* 0xa8-0xaf */ + 0xaf, 0xbb, 0xba, 0xbc, 0xbf, 0xbd, 0x85, 0xc6, /* 0xb0-0xb7 */ + 0x8b, 0xd1, 0x88, 0xce, 0x89, 0xcf, 0xda, 0xd5, /* 0xb8-0xbf */ + 0xc5, 0xd2, 0xcd, 0xd3, 0xd9, 0xd4, 0x8c, 0xd6, /* 0xc0-0xc7 */ + 0x8e, 0xd8, 0x91, 0xde, 0x96, 0xe4, 0x93, 0xe1, /* 0xc8-0xcf */ + 0xff, 0xe8, 0xdb, 0xe5, 0xe0, 0xe6, 0xf0, 0xe7, /* 0xd0-0xd7 */ + 0x97, 0xe9, 0x9b, 0xed, 0x98, 0xea, 0x99, 0xeb, /* 0xd8-0xdf */ + 0x9a, 0xec, 0x9c, 0xee, 0x02, 0xf4, 0x9e, 0xf1, /* 0xe0-0xe7 */ + 0x11, 0xf8, 0x04, 0xf5, 0x05, 0xf6, 0x06, 0xf7, /* 0xe8-0xef */ + 0x12, 0xf9, 0x13, 0xfa, 0x17, 0xfe, 0x14, 0xfb, /* 0xf0-0xf7 */ + 0x15, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static int +tcvn_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080 && (wc >= 0x0020 || (0x00fe0076 & (1 << wc)) == 0)) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x01b8) + c = tcvn_page00[wc-0x00a0]; + else if (wc >= 0x0300 && wc < 0x0328) + c = tcvn_page03[wc-0x0300]; + else if (wc >= 0x1ea0 && wc < 0x1f00) + c = tcvn_page1e[wc-0x1ea0]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILSEQ; +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/tis620.h b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/tis620.h new file mode 100644 index 0000000..beb7cd9 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/tis620.h @@ -0,0 +1,78 @@ +/* $XFree86: xc/lib/X11/lcUniConv/tis620.h,v 1.4 2001/02/09 00:02:54 dawes Exp $ */ + +/* + * TIS620-0 + */ + +static const unsigned short tis620_2uni[96] = { + /* 0xa0 */ + 0xfffd, 0x0e01, 0x0e02, 0x0e03, 0x0e04, 0x0e05, 0x0e06, 0x0e07, + 0x0e08, 0x0e09, 0x0e0a, 0x0e0b, 0x0e0c, 0x0e0d, 0x0e0e, 0x0e0f, + /* 0xb0 */ + 0x0e10, 0x0e11, 0x0e12, 0x0e13, 0x0e14, 0x0e15, 0x0e16, 0x0e17, + 0x0e18, 0x0e19, 0x0e1a, 0x0e1b, 0x0e1c, 0x0e1d, 0x0e1e, 0x0e1f, + /* 0xc0 */ + 0x0e20, 0x0e21, 0x0e22, 0x0e23, 0x0e24, 0x0e25, 0x0e26, 0x0e27, + 0x0e28, 0x0e29, 0x0e2a, 0x0e2b, 0x0e2c, 0x0e2d, 0x0e2e, 0x0e2f, + /* 0xd0 */ + 0x0e30, 0x0e31, 0x0e32, 0x0e33, 0x0e34, 0x0e35, 0x0e36, 0x0e37, + 0x0e38, 0x0e39, 0x0e3a, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x0e3f, + /* 0xe0 */ + 0x0e40, 0x0e41, 0x0e42, 0x0e43, 0x0e44, 0x0e45, 0x0e46, 0x0e47, + 0x0e48, 0x0e49, 0x0e4a, 0x0e4b, 0x0e4c, 0x0e4d, 0x0e4e, 0x0e4f, + /* 0xf0 */ + 0x0e50, 0x0e51, 0x0e52, 0x0e53, 0x0e54, 0x0e55, 0x0e56, 0x0e57, + 0x0e58, 0x0e59, 0x0e5a, 0x0e5b, 0xfffd, 0xfffd, 0xfffd, 0xfffd, +}; + +static int +tis620_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) { + *pwc = (ucs4_t) c; + return 1; + } + else if (c < 0xa0) { + } + else { + unsigned short wc = tis620_2uni[c-0xa0]; + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 1; + } + } + return RET_ILSEQ; +} + +static const unsigned char tis620_page0e[96] = { + 0x00, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0x00-0x07 */ + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0x08-0x0f */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0x10-0x17 */ + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, /* 0x18-0x1f */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0x20-0x27 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0x28-0x2f */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0x30-0x37 */ + 0xd8, 0xd9, 0xda, 0x00, 0x00, 0x00, 0x00, 0xdf, /* 0x38-0x3f */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0x40-0x47 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0x48-0x4f */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0x50-0x57 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ +}; + +static int +tis620_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x0e00 && wc < 0x0e60) + c = tis620_page0e[wc-0x0e00]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILSEQ; +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/ucs2be.h b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/ucs2be.h new file mode 100644 index 0000000..af2a586 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/ucs2be.h @@ -0,0 +1,32 @@ +/* + * UCS-2BE = UCS-2 big endian + */ +/* $XFree86: xc/lib/X11/lcUniConv/ucs2be.h,v 1.1 2000/11/28 17:25:09 dawes Exp $ */ + +static int +ucs2be_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + if (n >= 2) { + if (s[0] >= 0xd8 && s[0] < 0xe0) { + return RET_ILSEQ; + } else { + *pwc = (s[0] << 8) + s[1]; + return 2; + } + } + return RET_TOOFEW(0); +} + +static int +ucs2be_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (wc < 0x10000 && !(wc >= 0xd800 && wc < 0xe000)) { + if (n >= 2) { + r[0] = (unsigned char) (wc >> 8); + r[1] = (unsigned char) wc; + return 2; + } else + return RET_TOOSMALL; + } + return RET_ILSEQ; +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/utf8.h b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/utf8.h new file mode 100644 index 0000000..fe189cc --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/utf8.h @@ -0,0 +1,110 @@ +/* $XFree86: xc/lib/X11/lcUniConv/utf8.h,v 1.3 2000/11/28 18:50:07 dawes Exp $ */ + +/* + * UTF-8 + */ + +/* Specification: RFC 2279 */ + +static int +utf8_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = s[0]; + + if (c < 0x80) { + *pwc = c; + return 1; + } else if (c < 0xc2) { + return RET_ILSEQ; + } else if (c < 0xe0) { + if (n < 2) + return RET_TOOFEW(0); + if (!((s[1] ^ 0x80) < 0x40)) + return RET_ILSEQ; + *pwc = ((ucs4_t) (c & 0x1f) << 6) + | (ucs4_t) (s[1] ^ 0x80); + return 2; + } else if (c < 0xf0) { + if (n < 3) + return RET_TOOFEW(0); + if (!((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40 + && (c >= 0xe1 || s[1] >= 0xa0))) + return RET_ILSEQ; + *pwc = ((ucs4_t) (c & 0x0f) << 12) + | ((ucs4_t) (s[1] ^ 0x80) << 6) + | (ucs4_t) (s[2] ^ 0x80); + return 3; + } else if (c < 0xf8) { + if (n < 4) + return RET_TOOFEW(0); + if (!((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40 + && (s[3] ^ 0x80) < 0x40 + && (c >= 0xf1 || s[1] >= 0x90))) + return RET_ILSEQ; + *pwc = ((ucs4_t) (c & 0x07) << 18) + | ((ucs4_t) (s[1] ^ 0x80) << 12) + | ((ucs4_t) (s[2] ^ 0x80) << 6) + | (ucs4_t) (s[3] ^ 0x80); + return 4; + } else if (c < 0xfc) { + if (n < 5) + return RET_TOOFEW(0); + if (!((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40 + && (s[3] ^ 0x80) < 0x40 && (s[4] ^ 0x80) < 0x40 + && (c >= 0xf9 || s[1] >= 0x88))) + return RET_ILSEQ; + *pwc = ((ucs4_t) (c & 0x03) << 24) + | ((ucs4_t) (s[1] ^ 0x80) << 18) + | ((ucs4_t) (s[2] ^ 0x80) << 12) + | ((ucs4_t) (s[3] ^ 0x80) << 6) + | (ucs4_t) (s[4] ^ 0x80); + return 5; + } else if (c < 0xfe) { + if (n < 6) + return RET_TOOFEW(0); + if (!((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40 + && (s[3] ^ 0x80) < 0x40 && (s[4] ^ 0x80) < 0x40 + && (s[5] ^ 0x80) < 0x40 + && (c >= 0xfd || s[1] >= 0x84))) + return RET_ILSEQ; + *pwc = ((ucs4_t) (c & 0x01) << 30) + | ((ucs4_t) (s[1] ^ 0x80) << 24) + | ((ucs4_t) (s[2] ^ 0x80) << 18) + | ((ucs4_t) (s[3] ^ 0x80) << 12) + | ((ucs4_t) (s[4] ^ 0x80) << 6) + | (ucs4_t) (s[5] ^ 0x80); + return 6; + } else + return RET_ILSEQ; +} + +static int +utf8_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) /* n == 0 is acceptable */ +{ + int count; + if (wc < 0x80) + count = 1; + else if (wc < 0x800) + count = 2; + else if (wc < 0x10000) + count = 3; + else if (wc < 0x200000) + count = 4; + else if (wc < 0x4000000) + count = 5; + else if (wc <= 0x7fffffff) + count = 6; + else + return RET_ILSEQ; + if (n < count) + return RET_TOOSMALL; + switch (count) { /* note: code falls through cases! */ + case 6: r[5] = 0x80 | (wc & 0x3f); wc = wc >> 6; wc |= 0x4000000; + case 5: r[4] = 0x80 | (wc & 0x3f); wc = wc >> 6; wc |= 0x200000; + case 4: r[3] = 0x80 | (wc & 0x3f); wc = wc >> 6; wc |= 0x10000; + case 3: r[2] = 0x80 | (wc & 0x3f); wc = wc >> 6; wc |= 0x800; + case 2: r[1] = 0x80 | (wc & 0x3f); wc = wc >> 6; wc |= 0xc0; + case 1: r[0] = wc; + } + return count; +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/viscii.h b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/viscii.h new file mode 100644 index 0000000..9dffbf0 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/lcUniConv/viscii.h @@ -0,0 +1,123 @@ +/* $XFree86: xc/lib/X11/lcUniConv/viscii.h,v 1.3 2000/11/29 17:40:35 dawes Exp $ */ + +/* + * VISCII1.1-1 + */ + +/* Specification: RFC 1456 */ + +static const unsigned short viscii_2uni_1[32] = { + /* 0x00 */ + 0x0000, 0x0001, 0x1eb2, 0x0003, 0x0004, 0x1eb4, 0x1eaa, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + /* 0x10 */ + 0x0010, 0x0011, 0x0012, 0x0013, 0x1ef6, 0x0015, 0x0016, 0x0017, + 0x0018, 0x1ef8, 0x001a, 0x001b, 0x001c, 0x001d, 0x1ef4, 0x001f, +}; +static const unsigned short viscii_2uni_2[128] = { + /* 0x80 */ + 0x1ea0, 0x1eae, 0x1eb0, 0x1eb6, 0x1ea4, 0x1ea6, 0x1ea8, 0x1eac, + 0x1ebc, 0x1eb8, 0x1ebe, 0x1ec0, 0x1ec2, 0x1ec4, 0x1ec6, 0x1ed0, + /* 0x90 */ + 0x1ed2, 0x1ed4, 0x1ed6, 0x1ed8, 0x1ee2, 0x1eda, 0x1edc, 0x1ede, + 0x1eca, 0x1ece, 0x1ecc, 0x1ec8, 0x1ee6, 0x0168, 0x1ee4, 0x1ef2, + /* 0xa0 */ + 0x00d5, 0x1eaf, 0x1eb1, 0x1eb7, 0x1ea5, 0x1ea7, 0x1ea9, 0x1ead, + 0x1ebd, 0x1eb9, 0x1ebf, 0x1ec1, 0x1ec3, 0x1ec5, 0x1ec7, 0x1ed1, + /* 0xb0 */ + 0x1ed3, 0x1ed5, 0x1ed7, 0x1ee0, 0x01a0, 0x1ed9, 0x1edd, 0x1edf, + 0x1ecb, 0x1ef0, 0x1ee8, 0x1eea, 0x1eec, 0x01a1, 0x1edb, 0x01af, + /* 0xc0 */ + 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x1ea2, 0x0102, 0x1eb3, 0x1eb5, + 0x00c8, 0x00c9, 0x00ca, 0x1eba, 0x00cc, 0x00cd, 0x0128, 0x1ef3, + /* 0xd0 */ + 0x0110, 0x1ee9, 0x00d2, 0x00d3, 0x00d4, 0x1ea1, 0x1ef7, 0x1eeb, + 0x1eed, 0x00d9, 0x00da, 0x1ef9, 0x1ef5, 0x00dd, 0x1ee1, 0x01b0, + /* 0xe0 */ + 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x1ea3, 0x0103, 0x1eef, 0x1eab, + 0x00e8, 0x00e9, 0x00ea, 0x1ebb, 0x00ec, 0x00ed, 0x0129, 0x1ec9, + /* 0xf0 */ + 0x0111, 0x1ef1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x1ecf, 0x1ecd, + 0x1ee5, 0x00f9, 0x00fa, 0x0169, 0x1ee7, 0x00fd, 0x1ee3, 0x1eee, +}; + +static int +viscii_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x20) + *pwc = (ucs4_t) viscii_2uni_1[c]; + else if (c < 0x80) + *pwc = (ucs4_t) c; + else + *pwc = (ucs4_t) viscii_2uni_2[c-0x80]; + return 1; +} + +static const unsigned char viscii_page00[64+184] = { + 0xc0, 0xc1, 0xc2, 0xc3, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0x00, 0xcc, 0xcd, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0xd2, 0xd3, 0xd4, 0xa0, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0xd9, 0xda, 0x00, 0x00, 0xdd, 0x00, 0x00, /* 0xd8-0xdf */ + 0xe0, 0xe1, 0xe2, 0xe3, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0xe8, 0xe9, 0xea, 0x00, 0xec, 0xed, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0xf2, 0xf3, 0xf4, 0xf5, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0xf9, 0xfa, 0x00, 0x00, 0xfd, 0x00, 0x00, /* 0xf8-0xff */ + /* 0x0100 */ + 0x00, 0x00, 0xc5, 0xe5, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0xd0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0xce, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x9d, 0xfb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xb4, 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, /* 0xa8-0xaf */ + 0xdf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ +}; +static const unsigned char viscii_page1e[96] = { + 0x80, 0xd5, 0xc4, 0xe4, 0x84, 0xa4, 0x85, 0xa5, /* 0xa0-0xa7 */ + 0x86, 0xa6, 0x06, 0xe7, 0x87, 0xa7, 0x81, 0xa1, /* 0xa8-0xaf */ + 0x82, 0xa2, 0x02, 0xc6, 0x05, 0xc7, 0x83, 0xa3, /* 0xb0-0xb7 */ + 0x89, 0xa9, 0xcb, 0xeb, 0x88, 0xa8, 0x8a, 0xaa, /* 0xb8-0xbf */ + 0x8b, 0xab, 0x8c, 0xac, 0x8d, 0xad, 0x8e, 0xae, /* 0xc0-0xc7 */ + 0x9b, 0xef, 0x98, 0xb8, 0x9a, 0xf7, 0x99, 0xf6, /* 0xc8-0xcf */ + 0x8f, 0xaf, 0x90, 0xb0, 0x91, 0xb1, 0x92, 0xb2, /* 0xd0-0xd7 */ + 0x93, 0xb5, 0x95, 0xbe, 0x96, 0xb6, 0x97, 0xb7, /* 0xd8-0xdf */ + 0xb3, 0xde, 0x94, 0xfe, 0x9e, 0xf8, 0x9c, 0xfc, /* 0xe0-0xe7 */ + 0xba, 0xd1, 0xbb, 0xd7, 0xbc, 0xd8, 0xff, 0xe6, /* 0xe8-0xef */ + 0xb9, 0xf1, 0x9f, 0xcf, 0x1e, 0xdc, 0x14, 0xd6, /* 0xf0-0xf7 */ + 0x19, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static int +viscii_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080 && (wc >= 0x0020 || (0x42100064 & (1 << wc)) == 0)) { + *r = wc; + return 1; + } + else if (wc >= 0x00c0 && wc < 0x01b8) + c = viscii_page00[wc-0x00c0]; + else if (wc >= 0x1ea0 && wc < 0x1f00) + c = viscii_page1e[wc-0x1ea0]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILSEQ; +} diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/makedepend b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/makedepend new file mode 100644 index 0000000..a0eeffc --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/makedepend @@ -0,0 +1,27 @@ +# DO NOT DELETE + +case.o: headers/case.h +is_spacing.o: headers/spacing.h +keysym2Ucs.o: imKStoUCS.c Xlibint.h Ximint.h +ucs2fontmap.o: lcUniConv/big5.h lcUniConv/gb2312.h lcUniConv/iso8859_10.h +ucs2fontmap.o: lcUniConv/iso8859_11.h lcUniConv/iso8859_13.h +ucs2fontmap.o: lcUniConv/iso8859_14.h lcUniConv/iso8859_15.h +ucs2fontmap.o: lcUniConv/iso8859_2.h lcUniConv/iso8859_3.h +ucs2fontmap.o: lcUniConv/iso8859_4.h lcUniConv/iso8859_5.h +ucs2fontmap.o: lcUniConv/iso8859_6.h lcUniConv/iso8859_7.h +ucs2fontmap.o: lcUniConv/iso8859_8.h lcUniConv/iso8859_9.h +ucs2fontmap.o: lcUniConv/jisx0201.h lcUniConv/jisx0208.h lcUniConv/jisx0212.h +ucs2fontmap.o: lcUniConv/koi8_r.h lcUniConv/koi8_u.h lcUniConv/ksc5601.h +ucs2fontmap.o: lcUniConv/cp1251.h headers/symbol_.h headers/dingbats_.h +utf8Input.o: lcUniConv/big5.h lcUniConv/gb2312.h lcUniConv/jisx0201.h +utf8Input.o: lcUniConv/jisx0208.h lcUniConv/jisx0212.h lcUniConv/ksc5601.h +utf8Wrap.o: ucs2fontmap.c lcUniConv/big5.h lcUniConv/gb2312.h +utf8Wrap.o: lcUniConv/iso8859_10.h lcUniConv/iso8859_11.h +utf8Wrap.o: lcUniConv/iso8859_13.h lcUniConv/iso8859_14.h +utf8Wrap.o: lcUniConv/iso8859_15.h lcUniConv/iso8859_2.h +utf8Wrap.o: lcUniConv/iso8859_3.h lcUniConv/iso8859_4.h lcUniConv/iso8859_5.h +utf8Wrap.o: lcUniConv/iso8859_6.h lcUniConv/iso8859_7.h lcUniConv/iso8859_8.h +utf8Wrap.o: lcUniConv/iso8859_9.h lcUniConv/jisx0201.h lcUniConv/jisx0208.h +utf8Wrap.o: lcUniConv/jisx0212.h lcUniConv/koi8_r.h lcUniConv/koi8_u.h +utf8Wrap.o: lcUniConv/ksc5601.h lcUniConv/cp1251.h headers/symbol_.h +utf8Wrap.o: headers/dingbats_.h diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/mk_wcwidth.c b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/mk_wcwidth.c new file mode 100644 index 0000000..0c4eb2c --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/mk_wcwidth.c @@ -0,0 +1,353 @@ +/* + * FLTK: Important! + * This file should remain as close to Markus Kuhn's original source + * as possible for easy checking for changes later, however unlikely. + * All customisations to work with FLTK shall be annotated! + */ + +/* + * This is an implementation of wcwidth() and wcswidth() (defined in + * IEEE Std 1002.1-2001) for Unicode. + * + * http://www.opengroup.org/onlinepubs/007904975/functions/wcwidth.html + * http://www.opengroup.org/onlinepubs/007904975/functions/wcswidth.html + * + * In fixed-width output devices, Latin characters all occupy a single + * "cell" position of equal width, whereas ideographic CJK characters + * occupy two such cells. Interoperability between terminal-line + * applications and (teletype-style) character terminals using the + * UTF-8 encoding requires agreement on which character should advance + * the cursor by how many cell positions. No established formal + * standards exist at present on which Unicode character shall occupy + * how many cell positions on character terminals. These routines are + * a first attempt of defining such behavior based on simple rules + * applied to data provided by the Unicode Consortium. + * + * For some graphical characters, the Unicode standard explicitly + * defines a character-cell width via the definition of the East Asian + * FullWidth (F), Wide (W), Half-width (H), and Narrow (Na) classes. + * In all these cases, there is no ambiguity about which width a + * terminal shall use. For characters in the East Asian Ambiguous (A) + * class, the width choice depends purely on a preference of backward + * compatibility with either historic CJK or Western practice. + * Choosing single-width for these characters is easy to justify as + * the appropriate long-term solution, as the CJK practice of + * displaying these characters as double-width comes from historic + * implementation simplicity (8-bit encoded characters were displayed + * single-width and 16-bit ones double-width, even for Greek, + * Cyrillic, etc.) and not any typographic considerations. + * + * Much less clear is the choice of width for the Not East Asian + * (Neutral) class. Existing practice does not dictate a width for any + * of these characters. It would nevertheless make sense + * typographically to allocate two character cells to characters such + * as for instance EM SPACE or VOLUME INTEGRAL, which cannot be + * represented adequately with a single-width glyph. The following + * routines at present merely assign a single-cell width to all + * neutral characters, in the interest of simplicity. This is not + * entirely satisfactory and should be reconsidered before + * establishing a formal standard in this area. At the moment, the + * decision which Not East Asian (Neutral) characters should be + * represented by double-width glyphs cannot yet be answered by + * applying a simple rule from the Unicode database content. Setting + * up a proper standard for the behavior of UTF-8 character terminals + * will require a careful analysis not only of each Unicode character, + * but also of each presentation form, something the author of these + * routines has avoided to do so far. + * + * http://www.unicode.org/unicode/reports/tr11/ + * + * Markus Kuhn -- 2007-05-26 (Unicode 5.0) + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted. The author + * disclaims all warranties with regard to this software. + * + * Latest version: http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c + */ + +/* + * FLTK - avoid possible problems on systems with 32-bit wchar_t. + * Don't include wchar.h, and change wchar_t to unsigned int. + * Can we guarantee sizeof(unsigned int) >= 4 ? + */ +#if 0 +#include +#endif + +struct interval { + int first; + int last; +}; + +/* auxiliary function for binary search in interval table */ +/* + * FLTK: was +static int bisearch(wchar_t ucs, const struct interval *table, int max) { + */ +static int bisearch(unsigned int ucs, const struct interval *table, int max) { + int min = 0; + int mid; + + if (ucs < table[0].first || ucs > table[max].last) + return 0; + while (max >= min) { + mid = (min + max) / 2; + if (ucs > table[mid].last) + min = mid + 1; + else if (ucs < table[mid].first) + max = mid - 1; + else + return 1; + } + + return 0; +} + + +/* The following two functions define the column width of an ISO 10646 + * character as follows: + * + * - The null character (U+0000) has a column width of 0. + * + * - Other C0/C1 control characters and DEL will lead to a return + * value of -1. + * + * - Non-spacing and enclosing combining characters (general + * category code Mn or Me in the Unicode database) have a + * column width of 0. + * + * - SOFT HYPHEN (U+00AD) has a column width of 1. + * + * - Other format characters (general category code Cf in the Unicode + * database) and ZERO WIDTH SPACE (U+200B) have a column width of 0. + * + * - Hangul Jamo medial vowels and final consonants (U+1160-U+11FF) + * have a column width of 0. + * + * - Spacing characters in the East Asian Wide (W) or East Asian + * Full-width (F) category as defined in Unicode Technical + * Report #11 have a column width of 2. + * + * - All remaining characters (including all printable + * ISO 8859-1 and WGL4 characters, Unicode control characters, + * etc.) have a column width of 1. + * + * This implementation assumes that wchar_t characters are encoded + * in ISO 10646. + */ + +/* + * FLTK: was +int mk_wcwidth(wchar_t ucs) + */ +int mk_wcwidth(unsigned int ucs) +{ + /* sorted list of non-overlapping intervals of non-spacing characters */ + /* generated by "uniset +cat=Me +cat=Mn +cat=Cf -00AD +1160-11FF +200B c" */ + static const struct interval combining[] = { + { 0x0300, 0x036F }, { 0x0483, 0x0486 }, { 0x0488, 0x0489 }, + { 0x0591, 0x05BD }, { 0x05BF, 0x05BF }, { 0x05C1, 0x05C2 }, + { 0x05C4, 0x05C5 }, { 0x05C7, 0x05C7 }, { 0x0600, 0x0603 }, + { 0x0610, 0x0615 }, { 0x064B, 0x065E }, { 0x0670, 0x0670 }, + { 0x06D6, 0x06E4 }, { 0x06E7, 0x06E8 }, { 0x06EA, 0x06ED }, + { 0x070F, 0x070F }, { 0x0711, 0x0711 }, { 0x0730, 0x074A }, + { 0x07A6, 0x07B0 }, { 0x07EB, 0x07F3 }, { 0x0901, 0x0902 }, + { 0x093C, 0x093C }, { 0x0941, 0x0948 }, { 0x094D, 0x094D }, + { 0x0951, 0x0954 }, { 0x0962, 0x0963 }, { 0x0981, 0x0981 }, + { 0x09BC, 0x09BC }, { 0x09C1, 0x09C4 }, { 0x09CD, 0x09CD }, + { 0x09E2, 0x09E3 }, { 0x0A01, 0x0A02 }, { 0x0A3C, 0x0A3C }, + { 0x0A41, 0x0A42 }, { 0x0A47, 0x0A48 }, { 0x0A4B, 0x0A4D }, + { 0x0A70, 0x0A71 }, { 0x0A81, 0x0A82 }, { 0x0ABC, 0x0ABC }, + { 0x0AC1, 0x0AC5 }, { 0x0AC7, 0x0AC8 }, { 0x0ACD, 0x0ACD }, + { 0x0AE2, 0x0AE3 }, { 0x0B01, 0x0B01 }, { 0x0B3C, 0x0B3C }, + { 0x0B3F, 0x0B3F }, { 0x0B41, 0x0B43 }, { 0x0B4D, 0x0B4D }, + { 0x0B56, 0x0B56 }, { 0x0B82, 0x0B82 }, { 0x0BC0, 0x0BC0 }, + { 0x0BCD, 0x0BCD }, { 0x0C3E, 0x0C40 }, { 0x0C46, 0x0C48 }, + { 0x0C4A, 0x0C4D }, { 0x0C55, 0x0C56 }, { 0x0CBC, 0x0CBC }, + { 0x0CBF, 0x0CBF }, { 0x0CC6, 0x0CC6 }, { 0x0CCC, 0x0CCD }, + { 0x0CE2, 0x0CE3 }, { 0x0D41, 0x0D43 }, { 0x0D4D, 0x0D4D }, + { 0x0DCA, 0x0DCA }, { 0x0DD2, 0x0DD4 }, { 0x0DD6, 0x0DD6 }, + { 0x0E31, 0x0E31 }, { 0x0E34, 0x0E3A }, { 0x0E47, 0x0E4E }, + { 0x0EB1, 0x0EB1 }, { 0x0EB4, 0x0EB9 }, { 0x0EBB, 0x0EBC }, + { 0x0EC8, 0x0ECD }, { 0x0F18, 0x0F19 }, { 0x0F35, 0x0F35 }, + { 0x0F37, 0x0F37 }, { 0x0F39, 0x0F39 }, { 0x0F71, 0x0F7E }, + { 0x0F80, 0x0F84 }, { 0x0F86, 0x0F87 }, { 0x0F90, 0x0F97 }, + { 0x0F99, 0x0FBC }, { 0x0FC6, 0x0FC6 }, { 0x102D, 0x1030 }, + { 0x1032, 0x1032 }, { 0x1036, 0x1037 }, { 0x1039, 0x1039 }, + { 0x1058, 0x1059 }, { 0x1160, 0x11FF }, { 0x135F, 0x135F }, + { 0x1712, 0x1714 }, { 0x1732, 0x1734 }, { 0x1752, 0x1753 }, + { 0x1772, 0x1773 }, { 0x17B4, 0x17B5 }, { 0x17B7, 0x17BD }, + { 0x17C6, 0x17C6 }, { 0x17C9, 0x17D3 }, { 0x17DD, 0x17DD }, + { 0x180B, 0x180D }, { 0x18A9, 0x18A9 }, { 0x1920, 0x1922 }, + { 0x1927, 0x1928 }, { 0x1932, 0x1932 }, { 0x1939, 0x193B }, + { 0x1A17, 0x1A18 }, { 0x1B00, 0x1B03 }, { 0x1B34, 0x1B34 }, + { 0x1B36, 0x1B3A }, { 0x1B3C, 0x1B3C }, { 0x1B42, 0x1B42 }, + { 0x1B6B, 0x1B73 }, { 0x1DC0, 0x1DCA }, { 0x1DFE, 0x1DFF }, + { 0x200B, 0x200F }, { 0x202A, 0x202E }, { 0x2060, 0x2063 }, + { 0x206A, 0x206F }, { 0x20D0, 0x20EF }, { 0x302A, 0x302F }, + { 0x3099, 0x309A }, { 0xA806, 0xA806 }, { 0xA80B, 0xA80B }, + { 0xA825, 0xA826 }, { 0xFB1E, 0xFB1E }, { 0xFE00, 0xFE0F }, + { 0xFE20, 0xFE23 }, { 0xFEFF, 0xFEFF }, { 0xFFF9, 0xFFFB }, + { 0x10A01, 0x10A03 }, { 0x10A05, 0x10A06 }, { 0x10A0C, 0x10A0F }, + { 0x10A38, 0x10A3A }, { 0x10A3F, 0x10A3F }, { 0x1D167, 0x1D169 }, + { 0x1D173, 0x1D182 }, { 0x1D185, 0x1D18B }, { 0x1D1AA, 0x1D1AD }, + { 0x1D242, 0x1D244 }, { 0xE0001, 0xE0001 }, { 0xE0020, 0xE007F }, + { 0xE0100, 0xE01EF } + }; + + /* test for 8-bit control characters */ + if (ucs == 0) + return 0; + if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0)) + return -1; + + /* binary search in table of non-spacing characters */ + if (bisearch(ucs, combining, + sizeof(combining) / sizeof(struct interval) - 1)) + return 0; + + /* if we arrive here, ucs is not a combining or C0/C1 control character */ + + return 1 + + (ucs >= 0x1100 && + (ucs <= 0x115f || /* Hangul Jamo init. consonants */ + ucs == 0x2329 || ucs == 0x232a || + (ucs >= 0x2e80 && ucs <= 0xa4cf && + ucs != 0x303f) || /* CJK ... Yi */ + (ucs >= 0xac00 && ucs <= 0xd7a3) || /* Hangul Syllables */ + (ucs >= 0xf900 && ucs <= 0xfaff) || /* CJK Compatibility Ideographs */ + (ucs >= 0xfe10 && ucs <= 0xfe19) || /* Vertical forms */ + (ucs >= 0xfe30 && ucs <= 0xfe6f) || /* CJK Compatibility Forms */ + (ucs >= 0xff00 && ucs <= 0xff60) || /* Fullwidth Forms */ + (ucs >= 0xffe0 && ucs <= 0xffe6) || + (ucs >= 0x20000 && ucs <= 0x2fffd) || + (ucs >= 0x30000 && ucs <= 0x3fffd))); +} + + +/* + * FLTK: comment out the remaining functions, as we don't need themm. + */ +#if 0 + +/* + * FLTK: was +int mk_wcswidth(const wchar_t *pwcs, size_t n) + */ +int mk_wcswidth(const unsigned int *pwcs, size_t n) +{ + int w, width = 0; + + for (;*pwcs && n-- > 0; pwcs++) + if ((w = mk_wcwidth(*pwcs)) < 0) + return -1; + else + width += w; + + return width; +} + + +/* + * The following functions are the same as mk_wcwidth() and + * mk_wcswidth(), except that spacing characters in the East Asian + * Ambiguous (A) category as defined in Unicode Technical Report #11 + * have a column width of 2. This variant might be useful for users of + * CJK legacy encodings who want to migrate to UCS without changing + * the traditional terminal character-width behaviour. It is not + * otherwise recommended for general use. + */ +/* + * FLTK: was +int mk_wcwidth_cjk(wchar_t ucs) + */ +int mk_wcwidth_cjk(unsigned int ucs) +{ + /* sorted list of non-overlapping intervals of East Asian Ambiguous + * characters, generated by "uniset +WIDTH-A -cat=Me -cat=Mn -cat=Cf c" */ + static const struct interval ambiguous[] = { + { 0x00A1, 0x00A1 }, { 0x00A4, 0x00A4 }, { 0x00A7, 0x00A8 }, + { 0x00AA, 0x00AA }, { 0x00AE, 0x00AE }, { 0x00B0, 0x00B4 }, + { 0x00B6, 0x00BA }, { 0x00BC, 0x00BF }, { 0x00C6, 0x00C6 }, + { 0x00D0, 0x00D0 }, { 0x00D7, 0x00D8 }, { 0x00DE, 0x00E1 }, + { 0x00E6, 0x00E6 }, { 0x00E8, 0x00EA }, { 0x00EC, 0x00ED }, + { 0x00F0, 0x00F0 }, { 0x00F2, 0x00F3 }, { 0x00F7, 0x00FA }, + { 0x00FC, 0x00FC }, { 0x00FE, 0x00FE }, { 0x0101, 0x0101 }, + { 0x0111, 0x0111 }, { 0x0113, 0x0113 }, { 0x011B, 0x011B }, + { 0x0126, 0x0127 }, { 0x012B, 0x012B }, { 0x0131, 0x0133 }, + { 0x0138, 0x0138 }, { 0x013F, 0x0142 }, { 0x0144, 0x0144 }, + { 0x0148, 0x014B }, { 0x014D, 0x014D }, { 0x0152, 0x0153 }, + { 0x0166, 0x0167 }, { 0x016B, 0x016B }, { 0x01CE, 0x01CE }, + { 0x01D0, 0x01D0 }, { 0x01D2, 0x01D2 }, { 0x01D4, 0x01D4 }, + { 0x01D6, 0x01D6 }, { 0x01D8, 0x01D8 }, { 0x01DA, 0x01DA }, + { 0x01DC, 0x01DC }, { 0x0251, 0x0251 }, { 0x0261, 0x0261 }, + { 0x02C4, 0x02C4 }, { 0x02C7, 0x02C7 }, { 0x02C9, 0x02CB }, + { 0x02CD, 0x02CD }, { 0x02D0, 0x02D0 }, { 0x02D8, 0x02DB }, + { 0x02DD, 0x02DD }, { 0x02DF, 0x02DF }, { 0x0391, 0x03A1 }, + { 0x03A3, 0x03A9 }, { 0x03B1, 0x03C1 }, { 0x03C3, 0x03C9 }, + { 0x0401, 0x0401 }, { 0x0410, 0x044F }, { 0x0451, 0x0451 }, + { 0x2010, 0x2010 }, { 0x2013, 0x2016 }, { 0x2018, 0x2019 }, + { 0x201C, 0x201D }, { 0x2020, 0x2022 }, { 0x2024, 0x2027 }, + { 0x2030, 0x2030 }, { 0x2032, 0x2033 }, { 0x2035, 0x2035 }, + { 0x203B, 0x203B }, { 0x203E, 0x203E }, { 0x2074, 0x2074 }, + { 0x207F, 0x207F }, { 0x2081, 0x2084 }, { 0x20AC, 0x20AC }, + { 0x2103, 0x2103 }, { 0x2105, 0x2105 }, { 0x2109, 0x2109 }, + { 0x2113, 0x2113 }, { 0x2116, 0x2116 }, { 0x2121, 0x2122 }, + { 0x2126, 0x2126 }, { 0x212B, 0x212B }, { 0x2153, 0x2154 }, + { 0x215B, 0x215E }, { 0x2160, 0x216B }, { 0x2170, 0x2179 }, + { 0x2190, 0x2199 }, { 0x21B8, 0x21B9 }, { 0x21D2, 0x21D2 }, + { 0x21D4, 0x21D4 }, { 0x21E7, 0x21E7 }, { 0x2200, 0x2200 }, + { 0x2202, 0x2203 }, { 0x2207, 0x2208 }, { 0x220B, 0x220B }, + { 0x220F, 0x220F }, { 0x2211, 0x2211 }, { 0x2215, 0x2215 }, + { 0x221A, 0x221A }, { 0x221D, 0x2220 }, { 0x2223, 0x2223 }, + { 0x2225, 0x2225 }, { 0x2227, 0x222C }, { 0x222E, 0x222E }, + { 0x2234, 0x2237 }, { 0x223C, 0x223D }, { 0x2248, 0x2248 }, + { 0x224C, 0x224C }, { 0x2252, 0x2252 }, { 0x2260, 0x2261 }, + { 0x2264, 0x2267 }, { 0x226A, 0x226B }, { 0x226E, 0x226F }, + { 0x2282, 0x2283 }, { 0x2286, 0x2287 }, { 0x2295, 0x2295 }, + { 0x2299, 0x2299 }, { 0x22A5, 0x22A5 }, { 0x22BF, 0x22BF }, + { 0x2312, 0x2312 }, { 0x2460, 0x24E9 }, { 0x24EB, 0x254B }, + { 0x2550, 0x2573 }, { 0x2580, 0x258F }, { 0x2592, 0x2595 }, + { 0x25A0, 0x25A1 }, { 0x25A3, 0x25A9 }, { 0x25B2, 0x25B3 }, + { 0x25B6, 0x25B7 }, { 0x25BC, 0x25BD }, { 0x25C0, 0x25C1 }, + { 0x25C6, 0x25C8 }, { 0x25CB, 0x25CB }, { 0x25CE, 0x25D1 }, + { 0x25E2, 0x25E5 }, { 0x25EF, 0x25EF }, { 0x2605, 0x2606 }, + { 0x2609, 0x2609 }, { 0x260E, 0x260F }, { 0x2614, 0x2615 }, + { 0x261C, 0x261C }, { 0x261E, 0x261E }, { 0x2640, 0x2640 }, + { 0x2642, 0x2642 }, { 0x2660, 0x2661 }, { 0x2663, 0x2665 }, + { 0x2667, 0x266A }, { 0x266C, 0x266D }, { 0x266F, 0x266F }, + { 0x273D, 0x273D }, { 0x2776, 0x277F }, { 0xE000, 0xF8FF }, + { 0xFFFD, 0xFFFD }, { 0xF0000, 0xFFFFD }, { 0x100000, 0x10FFFD } + }; + + /* binary search in table of non-spacing characters */ + if (bisearch(ucs, ambiguous, + sizeof(ambiguous) / sizeof(struct interval) - 1)) + return 2; + + return mk_wcwidth(ucs); +} + + +/* + * FLTK: was +int mk_wcswidth_cjk(const wchar_t *pwcs, size_t n) + */ +int mk_wcswidth_cjk(const unsigned int *pwcs, size_t n) +{ + int w, width = 0; + + for (;*pwcs && n-- > 0; pwcs++) + if ((w = mk_wcwidth_cjk(*pwcs)) < 0) + return -1; + else + width += w; + + return width; +} + +/* + * FLTK: end of commented out functions + */ +#endif diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/stamp-h b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/stamp-h new file mode 100644 index 0000000..9788f70 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/stamp-h @@ -0,0 +1 @@ +timestamp diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/stamp-h.in b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/stamp-h.in new file mode 100644 index 0000000..9788f70 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/stamp-h.in @@ -0,0 +1 @@ +timestamp diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/test.c b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/test.c new file mode 100644 index 0000000..75b17a9 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/test.c @@ -0,0 +1,292 @@ +/* "$Id: $" + * + * Author: Jean-Marc Lienher ( http://oksid.ch ) + * Copyright 2000-2003 by O'ksi'D. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems on the following page: + * + * http://www.fltk.org/str.php + */ + +/* + * UTF-8 X test program (It contains MINIMAL code to support XIM !!!) + * + **************** + * To test it do: + **************** + +kinput2 -canna +XMODIFIERS="@im=kinput2"; export XMODIFIERS +LANG=ja_JP; export LANG +./test + + to open a conversion window press "Shift space" + type some keys. + press space. + select glyph with arrows keys. + press return. + press return. + press "Shift space" to close the window + +LANG=ar_AE; export LANG +LANG=he_IL; export LANG +export LANG=ja_JP; export XMODIFIERS="@im=kinput2" +export LANG=ja_JP; export XMODIFIERS="@im=nicolatter" +export LANG=ja_JP; export XMODIFIERS="@im=jmode" +export LANG=ja_JP; export XMODIFIERS="@im=htt" +export LANG=ko_KR; export XMODIFIERS="@im=Ami" +export LANG=zh_TW; export XMODIFIERS="@im=xcin-zh_TW" +export LANG=zh_TW; export XMODIFIERS="@im=xcin-zh_CN" +export LANG=C; export XMODIFIERS="@im=interxim" +**********************************************************/ + +#include +#include +#include +#include +#include "Xutf8.h" +#include +#include +#include +#include +#include +#include + +char *jp_txt = "Γ© UTF-8 e\xCC\x82=\xC3\xAA" + " \357\274\270\357\274\254\357\274\246\357\274" + "\244\345\220\215\343\201\247\346\214\207 \345\256\232" + "\343\201\231\343\202\213"; + +char *rtl_txt = "->e\xCC\x82=\xC3\xAA"; + +XIM xim_im = NULL; +XIC xim_ic = NULL; +static XIMStyles* xim_styles = NULL; +XUtf8FontStruct *fontset; +GC gc; +int x = 2; +int y = 40; + +int main(int argc, char**argv) { + char **missing_charset_list; + int missing_charset_count; + XGCValues xgcv; + unsigned long mask; + Display* dpy; + int scr; + Window w, root; + XSetWindowAttributes set_attr; + int i; + XIMStyle *style; + static char buf[128]; + KeySym keysym = 0; + Status status; + XWMHints wm_hints; + XClassHint class_hints; + XIMStyle input_style = 0; + char **font_name_list; + char *def_string; + XFontStruct **font_struct_list; + char **font_encoding_list; + int nb_font; + int len = 0; + int no_xim = 0; + + printf ("A -> %c \n", XUtf8Tolower('A')); + if (!setlocale(LC_ALL, "")) + puts("locale not supported by C library, locale unchanged"); + + if (!XSetLocaleModifiers("")) + puts("X locale modifiers not supported, using default"); + + dpy = XOpenDisplay(0); + if (!dpy) { puts("cannot open display.\n"); exit(-1); } + scr = DefaultScreen(dpy); + root = RootWindow(dpy, scr); + set_attr.event_mask = KeyPressMask|FocusChangeMask; + set_attr.background_pixel = WhitePixel(dpy, DefaultScreen(dpy)); + set_attr.border_pixel = BlackPixel(dpy, DefaultScreen(dpy)); + w = XCreateWindow(dpy, root, 10,10,200,100,0, + DefaultDepth(dpy, DefaultScreen(dpy)), + InputOutput, DefaultVisual(dpy, DefaultScreen(dpy)), + CWEventMask | CWBackPixel | CWBorderPixel, &set_attr); + if (!w) { + puts("cannot creat window.\n"); + exit(-1); + } + + class_hints.res_name = "test"; + class_hints.res_class = "Test"; + wm_hints.input = True; + wm_hints.flags = InputHint; + + XmbSetWMProperties(dpy, w, "test", "test", NULL, 0, + NULL, &wm_hints, &class_hints); + + XMapWindow(dpy, w); + xim_im = XOpenIM(dpy, NULL, "test", "Test"); + if (!xim_im) { + puts("cannot Open Input Manager: Try default.\n"); + XSetLocaleModifiers("@im="); + xim_im = XOpenIM(dpy, NULL, "test", "Test"); + if (!xim_im) { + puts("Failed exiting.\n"); + exit(-1); + } + } + XGetIMValues (xim_im, XNQueryInputStyle, &xim_styles, NULL, NULL); + for (i = 0, style = xim_styles->supported_styles; + i < xim_styles->count_styles; i++, style++) { + if (i == 0 && *style == (XIMStatusNone|XIMPreeditNone)) { + printf("this is not a XIM server !!!\n"); + no_xim = 1; + } + printf("input style : 0x%X\n", *style); + } + + xim_ic = XCreateIC(xim_im, + XNInputStyle, + (XIMPreeditNothing | XIMStatusNothing), + XNClientWindow, w, + XNFocusWindow, w, + NULL); + if (!xim_ic) { + puts("cannot create Input Context.\n"); + exit(-1); + } + XFree(xim_styles); + XSetICFocus(xim_ic); + + /*************************************************************** + * I don't recommend to use a font base name list similar + * to the following one in a real application ;-) + * You should use an iso8859-1 font, plus a single font for + * your language. + ***************************************************************/ + fontset = XCreateUtf8FontStruct(dpy, + "-*-*-*-*-*-*-*-*-*-*-*-*-iso8858-3," /* not valid */ + "-*-*-medium-r-*-*-*-*-*-*-*-*-iso8859-1," + "-*-*-*-*-*-*-*-*-*-*-*-*-iso8859-6," + "-*-*-*-*-*-*-*-*-*-*-*-*-iso8859-8," + "-*-*-*-*-*-*-*-*-*-*-*-*-ksc5601.1987-0," + "-*-symbol-*-*-*-*-*-*-*-*-*-*-adobe-fontspecific," + "-*-*-*-*-*-*-*-*-*-*-*-*-iso8859-2," + "-*-*-*-*-*-*-*-*-*-*-*-*-koi8-1," + "-*-*-*-*-*-*-*-*-*-*-*-*-jisx0208.1983-0," + "-*-*-*-*-*-*-*-*-*-*-*-*-jisx0212.1990-0," + "-*-*-*-*-*-*-*-*-*-*-*-*-big5-0," + "-*-*-*-*-*-*-*-*-*-*-*-*-jisx0201.1976-0," + "-*-unifont-*-*-*-*-*-*-*-*-*-*-iso10646-1[0x300 0x400_0x500]," + "-*-*-*-*-*-*-*-*-*-*-*-*-*-*"); + + /* THIS PART IS NOT REQUIERED */ + nb_font = fontset->nb_font; + + while (nb_font > 0) { + nb_font--; + if (fontset->fonts[nb_font]) { + printf("encoding=\"\" fid=%d \n %s\n", + // fontset->encodings[nb_font], + fontset->fonts[nb_font]->fid, + fontset->font_name_list[nb_font]); + } + } + /* END OF NOT REQUIERED PART*/ + + mask = (GCForeground | GCBackground); + xgcv.foreground = BlackPixel(dpy, DefaultScreen(dpy)); + xgcv.background = WhitePixel(dpy, DefaultScreen(dpy)); + + gc = XCreateGC(dpy, w, mask, &xgcv); + if (!gc) { + puts("cannot create Graphic Context.\n"); + exit(-1); + } + + /***************************************************************/ + while (1) { + int filtered; + static XEvent xevent; + static XVaNestedList list1 = 0; + int r; + + XNextEvent(dpy, &xevent); + if (xevent.type == KeyPress) { + XKeyEvent *e = (XKeyEvent*) &xevent; + printf ("0x%X %d\n", e->state, e->keycode); + } + if (xevent.type == DestroyNotify) { + /* XIM server has crashed */ + no_xim = 1; + XSetLocaleModifiers("@im="); + xim_im = XOpenIM(dpy, NULL, "test", "Test"); + if (xim_im) { + xim_ic = XCreateIC(xim_im, + XNInputStyle, (XIMPreeditNothing | XIMStatusNothing), + XNClientWindow, w, + XNFocusWindow, w, + NULL); + } else { + xim_ic = NULL; + } + if (!xim_ic) { + puts("Crash recovery failed. exiting.\n"); + exit(-1); + } + } + if (xevent.type != DestroyNotify) { + filtered = XFilterEvent(&xevent, 0); + } + if (xevent.type == FocusOut && xim_ic) XUnsetICFocus(xim_ic); + if (xevent.type == FocusIn && xim_ic) XSetICFocus(xim_ic); + + if (xevent.type == KeyPress && !filtered) { + len = XUtf8LookupString(xim_ic, &xevent.xkey, + buf, 127, &keysym, &status); + + if (len == 1 && buf[0] == '\b') { + x -= XUtf8TextWidth(fontset, buf, len); + XUtf8DrawImageString(dpy, w, fontset, gc, + x, y, buf, len); + } else if (len == 1 && buf[0] == '\r') { + y += fontset->ascent + fontset->descent; + x = 0; + XCloseIM(xim_im); + } else { + XUtf8DrawImageString(dpy, w, fontset, gc, x, y, buf, len); + x += XUtf8TextWidth(fontset, buf, len); + } + + XUtf8DrawString(dpy, w, fontset, gc, 0, 20, jp_txt, strlen(jp_txt)); + XUtf8DrawString(dpy, w, fontset, gc, 50, 90, rtl_txt, strlen(rtl_txt)); + XUtf8DrawRtlString(dpy, w, fontset, gc, 50, 90, rtl_txt, strlen(rtl_txt)); + buf[len] = 0; + printf("'%s' %d %x\n", buf, keysym, keysym); + buf[0] = 0; + } + if (filtered) { + printf("Dead key\n"); + } + } + XFreeUtf8FontStruct(dpy, fontset); + return 0; +} + +/* + * End of "$Id$". + */ diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/test2.c b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/test2.c new file mode 100644 index 0000000..2d985b6 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/test2.c @@ -0,0 +1,223 @@ +/* "$Id: $" + * + * Author: Jean-Marc Lienher ( http://oksid.ch ) + * Copyright 2000-2003 by O'ksi'D. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems on the following page: + * + * http://www.fltk.org/str.php + */ + +/* + * UTF-8 X test program + * + ***************** + * To test it do : + ***************** + +kinput2 -canna +XMODIFIERS="@im=kinput2"; export XMODIFIERS +LANG=ja_JP; export LANG +./test + + to open a conversion window press "Shift space" + type some keys. + press space. + select glyph with arrows keys. + press return. + press return. + press "Shift space" to close the window + +LANG=ar_AE; export LANG +LANG=he_IL; export LANG +export LANG=ja_JP; export XMODIFIERS="@im=kinput2" +export LANG=ja_JP; export XMODIFIERS="@im=nicolatter" +export LANG=ja_JP; export XMODIFIERS="@im=jmode" +export LANG=ja_JP; export XMODIFIERS="@im=htt" +export LANG=ko_KR; export XMODIFIERS="@im=ami" +export LANG=zh_TW; export XMODIFIERS="@im=xcin-zh_TW" +export LANG=zh_TW; export XMODIFIERS="@im=xcin-zh_CN" +export LANG=fr_FR.UTF-8; export XMODIFIERS="@im=interxim" + +export LD_PRELOAD="/usr/src/x11/xc/exports/lib/libX11.so /usr/src/x11/xc/exports/lib/libxlcDef.so.2 /usr/src/x11/xc/exports/lib/libxlibi18n.so.2 /usr/src/x11/xc/exports/lib/libxlocale.so.2 /usr/src/x11/xc/exports/lib/libxomGeneric.so.2 /usr/src/x11/xc/exports/lib/libximcp.so.2" + +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +char *jp_txt = "Γ© UTF-8 e\xCC\x82=\xC3\xAA" + " \357\274\270\357\274\254\357\274\246\357\274" + "\244\345\220\215\343\201\247\346\214\207 \345\256\232" + "\343\201\231\343\202\213"; + +char *rtl_txt = "->e\xCC\x82=\xC3\xAA"; + +XIM xim_im = NULL; +XIC xim_ic = NULL; +static XIMStyles* xim_styles = NULL; +XFontSet fontset; +GC gc; +int x = 2; +int y = 40; + +int main(int argc, char**argv) { + char **missing_charset_list; + int missing_charset_count; + XGCValues xgcv; + unsigned long mask; + Display* dpy; + int scr; + Window w, root; + XSetWindowAttributes set_attr; + int i; + XIMStyle *style; + static char buf[128]; + KeySym keysym = 0; + Status status; + XWMHints wm_hints; + XClassHint class_hints; + XIMStyle input_style = 0; + char **font_name_list; + char *def_string; + XFontStruct **font_struct_list; + char **font_encoding_list; + int nb_font; + int len = 0; + int no_xim = 0; + char **missing_charset_list_return; + int missing_charset_count_return; + char *def_string_return; + + if (!setlocale(LC_ALL, "")) + puts("locale not supported by C library, locale unchanged"); + + if (!XSetLocaleModifiers("")) + puts("X locale modifiers not supported, using default"); + + dpy = XOpenDisplay(0); + scr = DefaultScreen(dpy); + root = RootWindow(dpy, scr); + set_attr.event_mask = KeyPressMask|FocusChangeMask; + set_attr.background_pixel = WhitePixel(dpy, DefaultScreen(dpy)); + set_attr.border_pixel = BlackPixel(dpy, DefaultScreen(dpy)); + w = XCreateWindow(dpy, root, 10,10,200,100,0, + DefaultDepth(dpy, DefaultScreen(dpy)), + InputOutput, DefaultVisual(dpy, DefaultScreen(dpy)), + CWEventMask | CWBackPixel | CWBorderPixel, &set_attr); + + class_hints.res_name = "test"; + class_hints.res_class = "Test"; + wm_hints.input = True; + wm_hints.flags = InputHint; + + XmbSetWMProperties(dpy, w, "test", "test", NULL, 0, + NULL, &wm_hints, &class_hints); + + XMapWindow(dpy, w); + xim_im = XOpenIM(dpy, NULL, "test", "Test"); + XGetIMValues(xim_im, XNQueryInputStyle, &xim_styles, NULL, NULL); + for (i = 0, style = xim_styles->supported_styles; + i < xim_styles->count_styles; i++, style++) { + if (*style == (XIMStatusNone|XIMPreeditNone)) { + printf("this is not a XIM server !!!\n"); + no_xim = 1; + } + printf("input style : 0x%X\n", *style); + } + XFree(xim_styles); + + xim_ic = XCreateIC(xim_im, + XNInputStyle, (XIMPreeditNothing | XIMStatusNothing), + XNClientWindow, w, + XNFocusWindow, w, + NULL); + XSetICFocus(xim_ic); + + /*************************************************************** + * I don't recommend to use a font base name list similar + * to the following one in a real application ;-) + ***************************************************************/ + fontset = XCreateFontSet(dpy, + "-*-*-*-*-*-*-*-*-*-*-*-*-iso8858-3," /* not valid */ + "-*-*-medium-r-*-*-*-*-*-*-*-*-iso8859-1," + "-*-*-*-*-*-*-*-*-*-*-*-*-iso8859-6," + "-*-*-*-*-*-*-*-*-*-*-*-*-iso8859-8," + "-*-symbol-*-*-*-*-*-*-*-*-*-*-adobe-fontspecific," + "-*-*-*-*-*-*-*-*-*-*-*-*-iso8859-2," + "-*-*-*-*-*-*-*-*-*-*-*-*-koi8-1," + "-*-*-*-*-*-*-*-*-*-*-*-*-jisx0208.1983-0," + "-*-*-*-*-*-*-*-*-*-*-*-*-jisx0212.1990-0," + "-*-*-*-*-*-*-*-*-*-*-*-*-big5-0," + "-*-*-*-*-*-*-*-*-*-*-*-*-jisx0201.1976-0," + "-*-unifont-*-*-*-*-*-*-*-*-*-*-iso10646-1[0x300 0x400_0x500]," + "-*-*-*-*-*-*-*-*-*-*-*-*-*-*", + &missing_charset_list_return, + &missing_charset_count_return, + &def_string_return); + mask = (GCForeground | GCBackground); + xgcv.foreground = BlackPixel(dpy, DefaultScreen(dpy)); + xgcv.background = WhitePixel(dpy, DefaultScreen(dpy)); + + gc = XCreateGC(dpy, w, mask, &xgcv); + + /***************************************************************/ + while (1) { + int filtered; + static XEvent xevent; + static XVaNestedList list1 = 0; + int r; + + XNextEvent(dpy, &xevent); + if (xevent.type == KeyPress) { + XKeyEvent *e = (XKeyEvent*) &xevent; + printf ("0x%X %d\n", e->state, e->keycode); + } + filtered = XFilterEvent(&xevent, w); + if (xevent.type == FocusOut) XUnsetICFocus(xim_ic); + if (xevent.type == FocusIn) XSetICFocus(xim_ic); + + if (xevent.type == KeyPress && !filtered) { + len = Xutf8LookupString(xim_ic, &xevent.xkey, buf, 127, &keysym, &status); + Xutf8DrawImageString(dpy, w, fontset, gc, x, y, buf, len); + Xutf8DrawString(dpy, w, fontset, gc, 0, 20, jp_txt, strlen(jp_txt)); + Xutf8DrawString(dpy, w, fontset, gc, 50, 90, rtl_txt, strlen(rtl_txt)); + buf[len] = 0; + printf("'%s' %d\n", buf, keysym); + buf[0] = 0; + XCloseIM(xim_im); + } + if (filtered) { + printf("Dead key\n"); + } + } + XFreeFontSet(dpy, fontset); + return 0; +} + +/* + * End of "$Id$". + */ diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/ucs2fontmap.c b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/ucs2fontmap.c new file mode 100644 index 0000000..37f74d7 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/ucs2fontmap.c @@ -0,0 +1,380 @@ +/* "$Id: $" + * + * Author: Jean-Marc Lienher ( http://oksid.ch ) + * Copyright 2000-2003 by O'ksi'D. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems on the following page: + * + * http://www.fltk.org/str.php + */ + +#include +#include + +#define RET_ILSEQ -1 +#define RET_TOOFEW(x) (-10 - x) +#define RET_TOOSMALL -2 +#define conv_t void* +#define ucs4_t unsigned int +typedef struct { + unsigned short indx; + unsigned short used; +} Summary16; + + +#include "lcUniConv/cp936ext.h" +#include "lcUniConv/big5.h" +#include "lcUniConv/gb2312.h" +#include "lcUniConv/iso8859_10.h" +#include "lcUniConv/iso8859_11.h" +#include "lcUniConv/iso8859_13.h" +#include "lcUniConv/iso8859_14.h" +#include "lcUniConv/iso8859_15.h" +#include "lcUniConv/iso8859_2.h" +#include "lcUniConv/iso8859_3.h" +#include "lcUniConv/iso8859_4.h" +#include "lcUniConv/iso8859_5.h" +#include "lcUniConv/iso8859_6.h" +#include "lcUniConv/iso8859_7.h" +#include "lcUniConv/iso8859_8.h" +#include "lcUniConv/iso8859_9.h" +#include "lcUniConv/jisx0201.h" +#include "lcUniConv/jisx0208.h" +#include "lcUniConv/jisx0212.h" +#include "lcUniConv/koi8_r.h" +#include "lcUniConv/koi8_u.h" +#include "lcUniConv/ksc5601.h" +#include "lcUniConv/cp1251.h" +#include "headers/symbol_.h" +#include "headers/dingbats_.h" + +/*************** conv_gen.c ************/ + +/*const*/ +int ucs2fontmap(char *s, unsigned int ucs, int enc) { + switch(enc) { + case 0: /* iso10646-1 */ + s[0] = (char) ((ucs & 0xFF00) >> 8); + s[1] = (char) (ucs & 0xFF); + return 0; + break; + case 1: /* iso8859-1 */ + if (ucs <= 0x00FF) { + if (ucs >= 0x0001) { + s[0] = 0; + s[1] = (char) (ucs & 0xFF); + return 1; + } + } + break; + case 2: /* iso8859-2 */ + if (ucs <= 0x00a0) { + s[0] = 0; + s[1] = (char) ucs; + return 2; + } else if (ucs < 0x0180) { + if (ucs >= 0x00a0) { + s[0] = 0; + s[1] = (char) iso8859_2_page00[ucs-0x00a0]; + if (s[1]) return 2; + } + } else if (ucs < 0x02e0) { + if (ucs >= 0x02c0) { + s[0] = 0; + s[1] = (char) iso8859_2_page02[ucs-0x02c0]; + if (s[1]) return 2; + } + } + break; + case 3: /* iso8859-3 */ + if (iso8859_3_wctomb(NULL, (unsigned char*)s, ucs, 2) > 0) { + return 3; + } + break; + case 4: /* iso8859-4 */ + if (iso8859_4_wctomb(NULL, (unsigned char*)s, ucs, 2) > 0) { + return 4; + } + break; + case 5: /* iso8859-5 */ + if (iso8859_5_wctomb(NULL, (unsigned char*)s, ucs, 2) > 0) { + return 5; + } + break; + case 6: /* iso8859-6 */ + if (iso8859_6_wctomb(NULL, (unsigned char*)s, ucs, 2) > 0) { + return 6; + } + break; + case 7: /* iso8859-7 */ + if (iso8859_7_wctomb(NULL, (unsigned char*)s, ucs, 2) > 0) { + return 7; + } + break; + case 8: /* iso8859-8 */ + if (iso8859_8_wctomb(NULL, (unsigned char*)s, ucs, 2) > 0) { + return 8; + } + break; + case 9: /* iso8859-9 */ + if (iso8859_9_wctomb(NULL, (unsigned char*)s, ucs, 2) > 0) { + return 9; + } + break; + case 10: /* iso8859-10 */ + if (iso8859_10_wctomb(NULL, (unsigned char*)s, ucs, 2) > 0) { + return 10; + } + break; + case 25: /* iso8859-11 */ + if (iso8859_11_wctomb(NULL, (unsigned char*)s, ucs, 2) > 0) { + return 25; + } + break; + case 11: /* iso8859-13 */ + if (iso8859_13_wctomb(NULL, (unsigned char*)s, ucs, 2) > 0) { + return 11; + } + break; + case 12: /* iso8859-14 */ + if (iso8859_14_wctomb(NULL, (unsigned char*)s, ucs, 2) > 0) { + return 12; + } + break; + case 13: /* iso8859-15 */ + if (iso8859_15_wctomb(NULL, (unsigned char*)s, ucs, 2) > 0) { + return 13; + } + break; + case 14: /* koi8-r */ + if (koi8_r_wctomb(NULL, (unsigned char*)s, ucs, 2) > 0) { + return 14; + } + break; + case 15: /* big5 */ + if (big5_wctomb(NULL, (unsigned char*)s, ucs, 2) > 0) { + return 15; + } + break; + case 16: /* ksc5601.1987-0 */ + if (ksc5601_wctomb(NULL, (unsigned char*)s, ucs, 2) > 0) { + return 16; + } + break; + case 17: /* gb2312.1980-0 */ + if (gb2312_wctomb(NULL, (unsigned char*)s, ucs, 2) > 0) { + return 17; + } + break; + case 18: /* jisx0201.1976-0 */ + if (jisx0201_wctomb(NULL, (unsigned char*)s, ucs, 2) > 0) { + return 18; + } + break; + case 19: /* jisx0208.1983-0 */ + if (jisx0208_wctomb(NULL, (unsigned char*)s, ucs, 2) > 0) { + return 19; + } + break; + case 20: /* jisx0212.1990-0 */ + if (jisx0212_wctomb(NULL, (unsigned char*)s, ucs, 2) > 0) { + return 20; + } + break; + case 21: /* symbol */ + if (ucs <= 0x00F7) { + if (ucs >= 0x0020) { + s[0] = 0; + s[1] = unicode_to_symbol_1b_0020[ucs - 0x0020]; + if (s[1]) return 21; + } + } else if (ucs <= 0x0192) { + if (ucs >= 0x0192) { + s[0] = 0; + s[1] = unicode_to_symbol_1b_0192[ucs - 0x0192]; + if (s[1]) return 21; + } + } else if (ucs <= 0x03D6) { + if (ucs >= 0x0391) { + s[0] = 0; + s[1] = unicode_to_symbol_1b_0391[ucs - 0x0391]; + if (s[1]) return 21; + } + } else if (ucs <= 0x232A) { + if (ucs >= 0x2022) { + s[0] = 0; + s[1] = unicode_to_symbol_1b_2022[ucs - 0x2022]; + if (s[1]) return 21; + } + } else if (ucs <= 0x25CA) { + if (ucs >= 0x25CA) { + s[0] = 0; + s[1] = unicode_to_symbol_1b_25CA[ucs - 0x25CA]; + if (s[1]) return 21; + } + } else if (ucs <= 0x2666) { + if (ucs >= 0x2660) { + s[0] = 0; + s[1] = unicode_to_symbol_1b_2660[ucs - 0x2660]; + if (s[1]) return 21; + } + } else if (ucs <= 0xF6DB) { + if (ucs >= 0xF6D9) { + s[0] = 0; + s[1] = unicode_to_symbol_1b_F6D9[ucs - 0xF6D9]; + if (s[1]) return 21; + } + } else if (ucs <= 0xF8FE) { + if (ucs >= 0xF8E5) { + s[0] = 0; + s[1] = unicode_to_symbol_1b_F8E5[ucs - 0xF8E5]; + if (s[1]) return 21; + } + } + break; + case 22: /* dingbats */ + if (ucs <= 0x00A0) { + if (ucs >= 0x0020) { + s[0] = 0; + s[1] = unicode_to_dingbats_1b_0020[ucs - 0x0020]; + if (s[1]) return 22; + } + } else if (ucs <= 0x2195) { + if (ucs >= 0x2192) { + s[0] = 0; + s[1] = unicode_to_dingbats_1b_2192[ucs - 0x2192]; + if (s[1]) return 22; + } + } else if (ucs <= 0x2469) { + if (ucs >= 0x2460) { + s[0] = 0; + s[1] = unicode_to_dingbats_1b_2460[ucs - 0x2460]; + if (s[1]) return 22; + } + } else if (ucs <= 0x2666) { + if (ucs >= 0x25A0) { + s[0] = 0; + s[1] = unicode_to_dingbats_1b_25A0[ucs - 0x25A0]; + if (s[1]) return 22; + } + } else if (ucs <= 0x27BE) { + if (ucs >= 0x2701) { + s[0] = 0; + s[1] = unicode_to_dingbats_1b_2701[ucs - 0x2701]; + if (s[1]) return 22; + } + } else if (ucs <= 0xF8E4) { + if (ucs >= 0xF8D7) { + s[0] = 0; + s[1] = unicode_to_dingbats_1b_F8D7[ucs - 0xF8D7]; + if (s[1]) return 22; + } + } + break; + case 23: /* koi8-u */ + if (koi8_u_wctomb(NULL, (unsigned char*)s, ucs, 2) > 0) { + return 23; + } + break; + case 24: /* microsoft-cp1251 */ + if (cp1251_wctomb(NULL, (unsigned char*)s, ucs, 2) > 0) { + return 24; + } + break; + case 26: /* gbk/cp936ext */ + if (cp936ext_wctomb(NULL, (unsigned char*)s, ucs, 2) > 0) { + return 26; + } + break; + default: + break; + }; + return -1; +}; + +/*const*/ +int encoding_number(const char *enc) { + if (!enc || !strncmp(enc, "iso10646-1", 10)) { + return 0; + } else if (!strcmp(enc, "iso8859-1")) { + return 1; + } else if (!strcmp(enc, "iso8859-2")) { + return 2; + } else if (!strcmp(enc, "iso8859-3")) { + return 3; + } else if (!strcmp(enc, "iso8859-4")) { + return 4; + } else if (!strcmp(enc, "iso8859-5")) { + return 5; + } else if (!strcmp(enc, "iso8859-6")) { + return 6; + } else if (!strcmp(enc, "iso8859-7")) { + return 7; + } else if (!strcmp(enc, "iso8859-8")) { + return 8; + } else if (!strcmp(enc, "iso8859-9")) { + return 9; + } else if (!strcmp(enc, "iso8859-10")) { + return 10; + } else if (!strcmp(enc, "iso8859-13")) { + return 11; + } else if (!strcmp(enc, "iso8859-14")) { + return 12; + } else if (!strcmp(enc, "iso8859-15")) { + return 13; + } else if (!strcmp(enc, "koi8-r")) { + return 14; + } else if (!strcmp(enc, "big5-0") || !strcmp(enc, "big5.eten-0") || + !strcmp(enc, "big5p-0")) + { + return 15; + } else if (!strcmp(enc, "ksc5601.1987-0")) { + return 16; + } else if (!strcmp(enc, "gb2312.1980-0") || !strcmp(enc, "gb2312.80-0") || + !strcmp(enc, "gb2312.80&gb8565.88") || !strcmp(enc, "gb2312.80-0")) + { + return 17; + } else if (!strcmp(enc, "jisx0201.1976-0")) { + return 18; + } else if (!strcmp(enc, "jisx0208.1983-0") || !strcmp(enc, "jisx0208.1990-0") + || !strcmp(enc, "jisx0208.1978-0")) + { + return 19; + } else if (!strcmp(enc, "jisx0212.1990-0")) { + return 20; + } else if (!strcmp(enc, "symbol")) { + return 21; + } else if (!strcmp(enc, "dingbats") || !strcmp(enc, "zapfdingbats") || + !strcmp(enc, "zapf dingbats") || !strcmp(enc, "itc zapf dingbats")) + { + return 22; + } else if (!strcmp(enc, "koi8-u")) { + return 23; + } else if (!strcmp(enc, "microsoft-cp1251")) { + return 24; + } else if (!strcmp(enc, "iso8859-11")) { + return 25; + } else if (!strcmp(enc, "gbk-0") || !strcmp(enc, "cp936") || !strcmp(enc, "gbk")) { + return 26; + }; + return -1; +}; + +/* + * End of "$Id$". + */ diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/ucs2fontmap.c.mini b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/ucs2fontmap.c.mini new file mode 100644 index 0000000..b8e3159 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/ucs2fontmap.c.mini @@ -0,0 +1,46 @@ +/* "$Id: $" + * + * Author: Jean-Marc Lienher ( http://oksid.ch ) + * Copyright 2000-2003 by O'ksi'D. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems on the following page: + * + * http://www.fltk.org/str.php + */ + +int ucs2fontmap(char *s, unsigned long ucs, int enc) +{ + s[0] = (char) ((ucs & 0xFF00) >> 8); + s[1] = (char) (ucs & 0xFF); + return 0; +} + + +int encoding_number(const char *enc) +{ + return 0; +} + +const char *encoding_name(int num) +{ + return "iso10646-1"; +}; + +/* + * End of "$Id$". + */ diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/utf8Input.c b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/utf8Input.c new file mode 100644 index 0000000..4108c9f --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/utf8Input.c @@ -0,0 +1,457 @@ +/* "$Id: $" + * + * Author: Jean-Marc Lienher ( http://oksid.ch ) + * Copyright 2000-2003 by O'ksi'D. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems on the following page: + * + * http://www.fltk.org/str.php + */ + +#if !defined(WIN32) && !defined(__APPLE__) + +#include "config.h" +#include "../../FL/Xutf8.h" +#include +#include +#include +#include +#include + +#if HAVE_LIBC_ICONV +#include +#endif +/* + I haven't found much doc on the web about EUC encodings, so I've used + GNU libiconv source code as a reference. + http://clisp.cons.org/~haible/packages-libiconv.html +*/ + +#define RET_ILSEQ -1 +#define RET_TOOFEW(x) (-10 - x) +#define RET_TOOSMALL -2 +#define conv_t void* +#define ucs4_t unsigned int +typedef struct { + unsigned short indx; + unsigned short used; +} Summary16; + +#include "lcUniConv/big5.h" +#include "lcUniConv/gb2312.h" +#include "lcUniConv/cp936ext.h" +#include "lcUniConv/jisx0201.h" +#include "lcUniConv/jisx0208.h" +#include "lcUniConv/jisx0212.h" +#include "lcUniConv/ksc5601.h" + +int +XConvertEucTwToUtf8(char* buffer_return, int len) { + /* FIXME */ +#if HAVE_LIBC_ICONV + iconv_t cd; + int cdl; +#else + int i = 0; +#endif + int l = 0; + char *buf, *b; + + if (len < 1) return 0; + b = buf = (char*) malloc((unsigned)len); + memcpy(buf, buffer_return, (unsigned) len); + +#if HAVE_LIBC_ICONV + l = cdl = len; + cd = iconv_open("EUC-TW", "UTF-8"); + iconv(cd, &b, &len, &buffer_return, &cdl); + iconv_close(cd); + l -= cdl; +#else + while (i < len) { + unsigned int ucs; + unsigned char c; + c = (unsigned char) buf[i]; + if (c < 0x80) { + ucs = c; + i++; + } else if (c >= 0xa1 && c < 0xff && len - i > 1 ) { + unsigned char b[2]; + b[0] = (unsigned char) c - 0x80; + b[1] = (unsigned char) buf[i + 1] - 0x80; + ucs = ' '; i += 2; + } else if (c == 0x8e && len - i > 3) { + unsigned char b[2]; + unsigned char c1 = buf[i + 1]; + unsigned char c2 = buf[i + 2]; + unsigned char c3 = buf[i + 3]; + b[0] = (unsigned char) buf[i + 2] - 0x80; + b[1] = (unsigned char) buf[i + 3] - 0x80; + if (c1 >= 0xa1 && c1 <= 0xb0) { + if (c2 >= 0xa1 && c2 < 0xff && c3 >= 0xa1 && c3 < 0xff) { + ucs = ' '; i += 4; + } else { + ucs = '?'; i++; + } + } else { + ucs = '?'; i++; + } + } else { + ucs = '?'; + i++; + } + l += XConvertUcsToUtf8(ucs, buffer_return + l); + } +#endif + free(buf); + return l; +} + +int +XConvertEucKrToUtf8(char* buffer_return, int len) { + int i = 0, l = 0; + char *buf; + + if (len < 1) return 0; + + buf = (char*) malloc((unsigned)len); + memcpy(buf, buffer_return, (unsigned)len); + + while (i < len) { + unsigned int ucs; + unsigned char c, c1; + c = (unsigned char) buf[i]; + if (c < 0x80) { + ucs = c; + i++; + } else if (c >= 0xA1 && c < 0xFF && len - i > 1) { + c1 = (unsigned char) buf[i + 1]; + if (c1 >= 0xa1 && c1 < 0xff) { + unsigned char b[2]; + b[0] = c - 0x80; + b[1] = c1 - 0x80; + if (ksc5601_mbtowc(NULL, &ucs, b, 2) < 1) { + ucs = '?'; + } + } else { + ucs = '?'; + } + i += 2; + } else { + ucs = '?'; + i++; + } + l += XConvertUcsToUtf8(ucs, buffer_return + l); + } + free(buf); + return l; +} + +int +XConvertBig5ToUtf8(char* buffer_return, int len) { + int i = 0, l = 0; + char *buf; + + if (len < 1) return 0; + buf = (char*) malloc((unsigned)len); + memcpy(buf, buffer_return, (unsigned)len); + + if (len == 1) { + l += XConvertUcsToUtf8((unsigned int)buf[i], buffer_return + l); + } + while (i + 1 < len) { + unsigned int ucs; + unsigned char b[2]; + b[0] = (unsigned char) buf[i]; + b[1] = (unsigned char) buf[i + 1]; + if (big5_mbtowc(NULL, &ucs, b, 2) == 2) { + i += 2; + } else { + ucs = '?'; + i++; + } + l += XConvertUcsToUtf8(ucs, buffer_return + l); + } + free(buf); + return l; +} + +int +XConvertCp936extToUtf8(char* buffer_return, int len) +{ + int i = 0, l = 0; + char *buf; + + if (len < 1) return 0; + buf = (char*) malloc((unsigned)len); + memcpy(buf, buffer_return, (unsigned)len); + + if (len == 1) { + l += XConvertUcsToUtf8((unsigned int)buf[i], buffer_return + l); + } + while (i + 1 < len) { + unsigned int ucs; + unsigned char b[2]; + b[0] = (unsigned char) buf[i]; + b[1] = (unsigned char) buf[i + 1]; + if (cp936ext_mbtowc(NULL, &ucs, b, 2) == 2) { + i += 2; + } else { + if ( b[0] < 0x80) { + ucs = b[0]; + }else{ + ucs = '?'; + } + i++; + } + l += XConvertUcsToUtf8(ucs, buffer_return + l); + } + if(i + 1 == len) { + l += XConvertUcsToUtf8((unsigned int)buf[i], buffer_return + l); + } + free(buf); + return l; +} + +int +XConvertGb2312ToUtf8(char* buffer_return, int len) { + int i = 0, l = 0; + char *buf; + + if (len < 1) return 0; + buf = (char*) malloc((unsigned)len); + memcpy(buf, buffer_return, (unsigned)len); + + if (len == 1) { + l += XConvertUcsToUtf8((unsigned int)buf[i], buffer_return + l); + } + while (i + 1 < len) { + unsigned int ucs; + unsigned char b[2]; + b[0] = (unsigned char) buf[i]; + b[1] = (unsigned char) buf[i + 1]; + if ( b[0] < 0x80 ) { + ucs = b[0]; + i++; + } else if (gb2312_mbtowc(NULL, &ucs, b, 2) == 2) { + i += 2; + } else { + ucs = '?'; + i++; + } + l += XConvertUcsToUtf8(ucs, buffer_return + l); + } + if (i + 1 == len) { + l += XConvertUcsToUtf8((unsigned int)buf[i], buffer_return + l); + } + free(buf); + return l; +} + +int +XConvertEucCnToUtf8(char* buffer_return, int len) { + int i = 0, l = 0; + char *buf; + + if (len < 1) return 0; + buf = (char*) malloc((unsigned)len); + memcpy(buf, buffer_return, (unsigned)len); + + while (i < len) { + unsigned int ucs; + unsigned char c, c1; + c = (unsigned char) buf[i]; + if (c < 0x80) { + ucs = c; + i++; + } else if (c >= 0xA1 && c < 0xFF && len - i > 1) { + c1 = (unsigned char) buf[i + 1]; + if (c1 >= 0xa1 && c1 < 0xff) { + unsigned char b[2]; + b[0] = (unsigned char) c; + b[1] = (unsigned char) c1; + if (gb2312_mbtowc(NULL, &ucs, b, 2) < 1) { + ucs = '?'; + } + } else { + ucs = '?'; + } + i += 2; + } else { + ucs = '?'; + i++; + } + l += XConvertUcsToUtf8(ucs, buffer_return + l); + } + free(buf); + return l; +} + +int +XConvertEucJpToUtf8(char* buffer_return, int len) { + int i = 0, l = 0; + char *buf; + + if (len < 1) return 0; + buf = (char*) malloc((unsigned)len); + memcpy(buf, buffer_return, (unsigned)len); + + while (i < len) { + unsigned int ucs; + unsigned char c, c1; + c = (unsigned char) buf[i]; + if (c < 0x80) { + ucs = c; + i++; + } else if (c >= 0xA1 && c < 0xFF && len - i > 1) { + c1 = (unsigned char) buf[i + 1]; + if (c < 0xF5 && c1 >= 0xa1) { + unsigned char b[2]; + b[0] = c - 0x80; + b[1] = c1 - 0x80; + if (jisx0208_mbtowc(NULL, &ucs, b, 2) < 1) { + ucs = '?'; + } + } else if (c1 >= 0xA1 && c1 < 0xFF) { + ucs = 0xE000 + 94 * (c - 0xF5) + (c1 - 0xA1); + } else { + ucs = '?'; + } + i += 2; + } else if (c == 0x8E && len - i > 1) { + c1 = (unsigned char) buf[i + 1]; + if (c1 >= 0xa1 && c1 <= 0xe0) { + if (jisx0201_mbtowc(NULL, &ucs, &c1, 1) != 1) { + ucs = '?'; + } + } else { + ucs = '?'; + } + i += 2; + } else if (c == 0x8F && len - i > 2) { + c = (unsigned char) buf[i + 1]; + c1 = (unsigned char) buf[i + 2]; + if (c >= 0xa1 && c < 0xff) { + if (c < 0xf5 && c1 >= 0xa1 && c1 < 0xff) { + unsigned char b[2]; + b[0] = c - 0x80; + b[1] = c1 - 0x80; + if (jisx0212_mbtowc(NULL, &ucs, b, 2) < 1) { + ucs = '?'; + } + } else { + ucs = '?'; + } + } else { + if (c1 >= 0xa1 && c1 < 0xff) { + ucs = 0xe3ac + 94 * (c - 0xF5) + (c1 - 0xA1); + } else { + ucs = '?'; + } + } + i += 3; + } else { + ucs = '?'; + i++; + } + l += XConvertUcsToUtf8(ucs, buffer_return + l); + } + free(buf); + return l; +} + +int +XConvertEucToUtf8(const char* locale, + char* buffer_return, + int len, + int bytes_buffer) { + + //if (!locale/* || strstr(locale, "UTF") || strstr(locale, "utf")*/) { + if (!locale || strstr(locale, "UTF") || strstr(locale, "utf")) { + return len; + } + + if (strstr(locale, "ja")) { + return XConvertEucJpToUtf8(buffer_return, len); + } else if (strstr(locale, "Big5") || strstr(locale, "big5")) { /* BIG5 */ + return XConvertBig5ToUtf8(buffer_return, len); + } else if (strstr(locale, "GBK") || strstr(locale, "gbk")) { + return XConvertCp936extToUtf8(buffer_return, len); + } else if (strstr(locale, "zh") || strstr(locale, "chinese-")) { + if (strstr(locale, "TW") || strstr(locale, "chinese-t")) { + if (strstr(locale, "EUC") || strstr(locale, "euc") || strstr(locale, "chinese-t")) { + return XConvertEucTwToUtf8(buffer_return, len); + } + return XConvertBig5ToUtf8(buffer_return, len); + } + if (strstr(locale, "EUC") || strstr(locale, "euc")) { + return XConvertEucCnToUtf8(buffer_return, len); + } + return XConvertGb2312ToUtf8(buffer_return, len); + } else if (strstr(locale, "ko")) { + return XConvertEucKrToUtf8(buffer_return, len); + } + return len; +} + +int +XUtf8LookupString(XIC ic, + XKeyPressedEvent* event, + char* buffer_return, + int bytes_buffer, + KeySym* keysym, + Status* status_return) { + + long ucs = -1; + int len; + len = XmbLookupString(ic, event, buffer_return, bytes_buffer / 5, + keysym, status_return); + if (*status_return == XBufferOverflow) { + return len * 5; + } + if (*keysym > 0 && *keysym < 0x100 && len == 1) { + if (*keysym < 0x80) { + ucs = (unsigned char)buffer_return[0]; + } else { + ucs = *keysym; + } + } else if (((*keysym >= 0x100 && *keysym <= 0xf000) || + (*keysym & 0xff000000U) == 0x01000000)) + { + ucs = XKeysymToUcs(*keysym); + } else { + ucs = -2; + } + + if (ucs > 0) { + len = XConvertUcsToUtf8((unsigned)ucs, (char *)buffer_return); + } else if (len > 0) { + XIM im; + if (!ic) return 0; + im = XIMOfIC(ic); + if (!im) return 0; + len = XConvertEucToUtf8(XLocaleOfIM(im), buffer_return, len, bytes_buffer); + } + return len; +} + +#endif /* X11 only */ + +/* + * End of "$Id$". + */ diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/utf8Utils.c b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/utf8Utils.c new file mode 100644 index 0000000..6c177a7 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/utf8Utils.c @@ -0,0 +1,238 @@ +/* "$Id: $" + * + * Author: Jean-Marc Lienher ( http://oksid.ch ) + * Copyright 2000-2003 by O'ksi'D. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems on the following page: + * + * http://www.fltk.org/str.php + */ + +/* + * Unicode to UTF-8 conversion functions. + */ + +#if !defined(WIN32) && !defined(__APPLE__) + +#include "../../FL/Xutf8.h" + +/*** NOTE : all functions are LIMITED to 24 bits Unicode values !!! ***/ + +/* + * Converts the first char of the UTF-8 string to an Unicode value + * Returns the byte length of the converted UTF-8 char + * Returns -1 if the UTF-8 string is not valid + */ +int +XConvertUtf8ToUcs(const unsigned char *buf, + int len, + unsigned int *ucs) { + + if (buf[0] & 0x80) { + if (buf[0] & 0x40) { + if (buf[0] & 0x20) { + if (buf[0] & 0x10) { + if (buf[0] & 0x08) { + if (buf[0] & 0x04) { + if (buf[0] & 0x02) { + /* bad UTF-8 string */ + } else { + /* 0x04000000 - 0x7FFFFFFF */ + } + } else if (len > 4 + && (buf[1] & 0xC0) == 0x80 + && (buf[2] & 0xC0) == 0x80 + && (buf[3] & 0xC0) == 0x80 + && (buf[4] & 0xC0) == 0x80) { + /* 0x00200000 - 0x03FFFFFF */ + *ucs = ((buf[0] & ~0xF8) << 24) + + ((buf[1] & ~0x80) << 18) + + ((buf[2] & ~0x80) << 12) + + ((buf[3] & ~0x80) << 6) + + (buf[4] & ~0x80); + if (*ucs > 0x001FFFFF && *ucs < 0x01000000) return 5; + } + } else if (len > 3 + && (buf[1] & 0xC0) == 0x80 + && (buf[2] & 0xC0) == 0x80 + && (buf[3] & 0xC0) == 0x80) { + /* 0x00010000 - 0x001FFFFF */ + *ucs = ((buf[0] & ~0xF0) << 18) + + ((buf[1] & ~0x80) << 12) + + ((buf[2] & ~0x80) << 6) + + (buf[3] & ~0x80); + if (*ucs > 0x0000FFFF) return 4; + } + } else if (len > 2 + && (buf[1] & 0xC0) == 0x80 + && (buf[2] & 0xC0) == 0x80) { + /* 0x00000800 - 0x0000FFFF */ + *ucs = ((buf[0] & ~0xE0) << 12) + + ((buf[1] & ~0x80) << 6) + + (buf[2] & ~0x80); + if (*ucs > 0x000007FF) return 3; + } + } else if (len > 1 && (buf[1] & 0xC0) == 0x80) { + /* 0x00000080 - 0x000007FF */ + *ucs = ((buf[0] & ~0xC0) << 6) + + (buf[1] & ~0x80); + if (*ucs > 0x0000007F) return 2; + } + } + } else if (len > 0) { + /* 0x00000000 - 0x0000007F */ + *ucs = buf[0]; + return 1; + } + + *ucs = (unsigned int) '?'; /* bad utf-8 string */ + return -1; +} + +/* + * Converts an Unicode value to an UTF-8 string + * NOTE : the buffer (buf) must be at least 5 bytes long !!! + */ +int +XConvertUcsToUtf8(unsigned int ucs, + char *buf) { + + if (ucs < 0x000080) { + buf[0] = ucs; + return 1; + } else if (ucs < 0x000800) { + buf[0] = 0xC0 | (ucs >> 6); + buf[1] = 0x80 | (ucs & 0x3F); + return 2; + } else if (ucs < 0x010000) { + buf[0] = 0xE0 | (ucs >> 12); + buf[1] = 0x80 | ((ucs >> 6) & 0x3F); + buf[2] = 0x80 | (ucs & 0x3F); + return 3; + } else if (ucs < 0x00200000) { + buf[0] = 0xF0 | (ucs >> 18); + buf[1] = 0x80 | ((ucs >> 12) & 0x3F); + buf[2] = 0x80 | ((ucs >> 6) & 0x3F); + buf[3] = 0x80 | (ucs & 0x3F); + return 4; + } else if (ucs < 0x01000000) { + buf[0] = 0xF8 | (ucs >> 24); + buf[1] = 0x80 | ((ucs >> 18) & 0x3F); + buf[2] = 0x80 | ((ucs >> 12) & 0x3F); + buf[3] = 0x80 | ((ucs >> 6) & 0x3F); + buf[4] = 0x80 | (ucs & 0x3F); + return 5; + } + buf[0] = '?'; + return -1; +} + +/* + * returns the byte length of the first UTF-8 char + * (returns -1 if not valid) + */ +int +XUtf8CharByteLen(const unsigned char *buf, + int len) { + unsigned int ucs; + return XConvertUtf8ToUcs(buf, len, &ucs); +} + +/* + * returns the quantity of Unicode chars in the UTF-8 string + */ +int +XCountUtf8Char(const unsigned char *buf, + int len) { + + int i = 0; + int nbc = 0; + while (i < len) { + int cl = XUtf8CharByteLen(buf + i, len - i); + if (cl < 1) cl = 1; + nbc++; + i += cl; + } + return nbc; +} + +/* + * Same as XConvertUtf8ToUcs but no sanity check is done. + */ +int +XFastConvertUtf8ToUcs(const unsigned char *buf, + int len, + unsigned int *ucs) { + + if (buf[0] & 0x80) { + if (buf[0] & 0x40) { + if (buf[0] & 0x20) { + if (buf[0] & 0x10) { + if (buf[0] & 0x08) { + if (buf[0] & 0x04) { + if (buf[0] & 0x02) { + /* bad UTF-8 string */ + } else { + /* 0x04000000 - 0x7FFFFFFF */ + } + } else if (len > 4) { + /* 0x00200000 - 0x03FFFFFF */ + *ucs = ((buf[0] & ~0xF8) << 24) + + ((buf[1] & ~0x80) << 18) + + ((buf[2] & ~0x80) << 12) + + ((buf[3] & ~0x80) << 6) + + (buf[4] & ~0x80); + return 5; + } + } else if (len > 3) { + /* 0x00010000 - 0x001FFFFF */ + *ucs = ((buf[0] & ~0xF0) << 18) + + ((buf[1] & ~0x80) << 12) + + ((buf[2] & ~0x80) << 6) + + (buf[3] & ~0x80); + return 4; + } + } else if (len > 2) { + /* 0x00000800 - 0x0000FFFF */ + *ucs = ((buf[0] & ~0xE0) << 12) + + ((buf[1] & ~0x80) << 6) + + (buf[2] & ~0x80); + return 3; + } + } else if (len > 1) { + /* 0x00000080 - 0x000007FF */ + *ucs = ((buf[0] & ~0xC0) << 6) + + (buf[1] & ~0x80); + return 2; + } + } + } else if (len > 0) { + /* 0x00000000 - 0x0000007F */ + *ucs = buf[0]; + return 1; + } + + *ucs = (unsigned int) '?'; /* bad utf-8 string */ + return -1; +} + +#endif /* X11 only */ + +/* + * End of "$Id: $". + */ diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/utf8Wrap.c b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/utf8Wrap.c new file mode 100644 index 0000000..bb3676d --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/utf8Wrap.c @@ -0,0 +1,902 @@ +/* "$Id: $" + * + * Author: Jean-Marc Lienher ( http://oksid.ch ) + * Copyright 2000-2003 by O'ksi'D. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems on the following page: + * + * http://www.fltk.org/str.php + */ + +/* + * X11 UTF-8 text drawing functions. + */ +#if !defined(WIN32) && !defined(__APPLE__) + +#include "../../FL/Xutf8.h" +#include +#include +#include +#include +#include + +/* External auto generated functions : */ +#include "ucs2fontmap.c" +/* + * extern int ucs2fontmap(char *s, unsigned int ucs, int enc); + * extern int encoding_number(const char *enc); + * extern const char *encoding_name(int num); + */ + +/* The ARM header files have a bug by not taking into account that ARM cpu + * likes pacing to 4 bytes. This little trick defines our own version of + * XChar2b which does not have this problem + */ + +typedef struct { + unsigned char byte1; + unsigned char byte2; +} +#if defined(__GNUC__) && defined(__arm__) && !defined(__ARM_EABI__) +__attribute__ ((packed)) +#endif +Fl_XChar2b; + + +/*********************************************************************/ +/** extract a list of font from the base font name list **/ +/*********************************************************************/ +static int +get_font_list( + const char *base_font_name_list, + char ***flist) { + const char *ptr; + const char *p; + int nb; + int nb_name; + + ptr = base_font_name_list; + p = NULL; + nb = 0; + nb_name = 1; + + while (*ptr) { + if (*ptr == ',') nb_name++; + ptr++; + } + + *flist = (char **) malloc(sizeof(char*) * nb_name); + ptr = base_font_name_list; + + while (*ptr) { + int l = 0, i = 0; + + while(isspace(*ptr)) ptr++; + p = ptr; + while (*ptr && *ptr != ',') { ptr++; l++; } + if (l > 2) { + (*flist)[nb] = (char*) malloc((unsigned)l + 2); + while (p != ptr) { ((*flist)[nb])[i] = *p; i++; p++; } + (*flist)[nb][i] = '\0'; + nb++; + } + if (*ptr) ptr++; + } + if (nb < 1) { + free(*flist); + *flist = (char**)NULL; + } + return nb; +} + +/*********************************************************************/ +/** get the font name used as encoding for "fontspecific" encoding **/ +/** (mainly used for adobe-symbol and adobe-zapfdingbats) **/ +/*********************************************************************/ +static int +font_spec_enc(char *font) { + int ret; + char *enc; + char *end; + + enc = font; + while (*enc != '-') enc++; + enc++; + while (*enc != '-') enc++; + enc++; + end = enc; + while (*end != '-') end++; + *end = '\0'; + + ret = encoding_number(enc); + *end = '-'; + + return ret; +} + + +/*********************************************************************/ +/** get the sub range of a iso10646-1 font **/ +/*********************************************************************/ +static void +get_range(const char *enc, + int *min, + int *max) { + + const char *ptr = enc; + const char *ptr1; + + if (!enc) return; + + while (*ptr && *ptr != '-') ptr++; + if (!*ptr) return; + while (*ptr && *ptr != '[') ptr++; + if (!*ptr) return; + *min = 0xFFFF; + *max = 0; + while (*ptr && *ptr != ']') { + int val; + ptr++; + ptr1 = ptr; + while (*ptr && *ptr != ']' && *ptr != ' ' && *ptr != '_') ptr++; + val = strtol(ptr1, NULL, 0); + if (val < *min) *min = val; + if (val > *max) *max = val; + } +} + +/*********************************************************************/ +/** get the internal encoding number of each fonts **/ +/*********************************************************************/ +static int * +get_encodings(char **font_name_list, + int *ranges, + int nb_font) { + + int *font_encoding_list; + int i; + i = 0; + + font_encoding_list = (int *) malloc(sizeof(int) * nb_font); + while (i < nb_font) { + char *ptr; + int ec; + ptr = font_name_list[i]; + ec = 0; + font_encoding_list[i] = -1; + ranges[i * 2] = 0; + ranges[i * 2 + 1] = 0xFFFF; + + if (ptr && strstr(ptr, "fontspecific")) { + font_encoding_list[i] = font_spec_enc(ptr); + ptr = NULL; + } + while (ptr && *ptr) { + if (*ptr == '-') { + ec++; + if (ec == 13) { + font_encoding_list[i] = encoding_number(ptr + 1); + if (font_encoding_list[i] == 0) { + get_range(ptr + 1, + ranges + i * 2, + ranges + i * 2 + 1); + } + break; + } + } + ptr++; + } + if (font_encoding_list[i] < 0) font_encoding_list[i] = 1; + i++; + } + return font_encoding_list; +} + +/*********************************************************************/ +/** find the first font which matches the name and load it. **/ +/*********************************************************************/ +XFontStruct * +find_best_font(Display *dpy, + char **name) { + + char **list; + int cnt; + XFontStruct *s; + + list = XListFonts(dpy, *name, 1, &cnt); + if (cnt && list) { + free(*name); + *name = strdup(list[0]); + s = XLoadQueryFont(dpy, *name); + XFreeFontNames(list); + return s; + } + return NULL; +} + +/*********************************************************************/ +/** load all fonts **/ +/*********************************************************************/ +static void +load_fonts(Display *dpy, + XUtf8FontStruct *font_set) { + + int i; + char **list; + + i = 0; + list = NULL; + + font_set->fonts = (XFontStruct**) malloc(sizeof(XFontStruct*) * + font_set->nb_font); + + font_set->ranges = (int*) malloc(sizeof(int) * + font_set->nb_font * 2); + + font_set->descent = 0; + font_set->ascent = 0; + font_set->fid = 0; + + while (i < font_set->nb_font) { + XFontStruct *fnt; + + fnt = font_set->fonts[i] = + find_best_font(dpy, &(font_set->font_name_list[i])); + if (fnt) { + font_set->fid = fnt->fid; + if (fnt->ascent > font_set->ascent) { + font_set->ascent = fnt->ascent; + } + if (fnt->descent > font_set->descent) { + font_set->descent = fnt->descent; + } + } else { + free(font_set->font_name_list[i]); + font_set->font_name_list[i] = NULL; + } + i++; + } + + font_set->encodings = + get_encodings(font_set->font_name_list, + font_set->ranges, font_set->nb_font); + + /* unload fonts with same encoding */ + for (i = 0; i < font_set->nb_font; i++) { + if (font_set->font_name_list[i]) { + int j; + for (j = 0; j < i; j++) { + if (font_set->font_name_list[j] && + font_set->encodings[j] == + font_set->encodings[i] && + font_set->ranges[2*j] == + font_set->ranges[2*i] && + font_set->ranges[(2*j)+1] && + font_set->ranges[(2*i)+1]) { + XFreeFont(dpy, font_set->fonts[i]); + free(font_set->font_name_list[i]); + font_set->font_name_list[i] = NULL; + font_set->fonts[i] = 0; + } + } + } + } +} + +/*********************************************************************/ +/** Creates an array of XFontStruct acording to the comma separated **/ +/** list of fonts. XLoad all fonts. **/ +/*********************************************************************/ +XUtf8FontStruct * +XCreateUtf8FontStruct(Display *dpy, + const char *base_font_name_list) { + + XUtf8FontStruct *font_set; + + font_set = (XUtf8FontStruct*)malloc(sizeof(XUtf8FontStruct)); + + if (!font_set) { + return NULL; + } + + font_set->nb_font = get_font_list(base_font_name_list, + &font_set->font_name_list); + + if (font_set->nb_font < 1) { + free(font_set); + return NULL; + } + + load_fonts(dpy, font_set); + + return font_set; +} + + +/*****************************************************************************/ +/** draw a Right To Left UTF-8 string using multiple fonts as needed. **/ +/*****************************************************************************/ +void +XUtf8DrawRtlString(Display *display, + Drawable d, + XUtf8FontStruct *font_set, + GC gc, + int x, + int y, + const char *string, + int num_bytes) { + + int *encodings; /* encodings array */ + XFontStruct **fonts; /* fonts array */ + Fl_XChar2b buf[128]; /* drawing buffer */ + Fl_XChar2b *ptr; /* pointer to the drawing buffer */ + int fnum; /* index of the current font in the fonts array*/ + int i; /* current byte in the XChar2b buffer */ + int first; /* first valid font index */ + int last_fnum; /* font index of the previous char */ + int nb_font; /* quantity of fonts in the font array */ + char glyph[2]; /* byte1 and byte1 value of the UTF-8 char */ + int *ranges; /* sub range of iso10646 */ + + nb_font = font_set->nb_font; + + if (nb_font < 1) { + /* there is no font in the font_set :-( */ + return; + } + + ranges = font_set->ranges; + fonts = font_set->fonts; + encodings = font_set->encodings; + i = 0; + fnum = 0; + ptr = buf + 128; + + while(fnum < nb_font && !fonts[fnum]) fnum++; + if (fnum >= nb_font) { + /* there is no valid font for the X server */ + return; + } + + first = fnum; + last_fnum = fnum; + + while (num_bytes > 0) { + int ulen; /* byte length of the UTF-8 char */ + unsigned int ucs; /* Unicode value of the UTF-8 char */ + unsigned int no_spc; /* Spacing char equivalent of a non-spacing char */ + + if (i > 120) { + /*** draw the buffer **/ + XSetFont(display, gc, fonts[fnum]->fid); + x -= XTextWidth16(fonts[fnum], ptr, i); + XDrawString16(display, d, gc, x, y, ptr, i); + i = 0; + ptr = buf + 128; + } + + ulen = XFastConvertUtf8ToUcs((unsigned char*)string, num_bytes, &ucs); + + if (ulen < 1) ulen = 1; + + no_spc = XUtf8IsNonSpacing(ucs); + if (no_spc) ucs = no_spc; + + /* + * find the first encoding which can be used to + * draw the glyph + */ + fnum = first; + while (fnum < nb_font) { + if (fonts[fnum] && ucs2fontmap(glyph, ucs, encodings[fnum]) >= 0) { + if (encodings[fnum] != 0 || + (ucs >= ranges[fnum * 2] && ucs <= ranges[fnum * 2 + 1])) { + break; + } + } + fnum++; + } + if (fnum == nb_font) { + /* the char is not valid in all encodings -> + * draw it using the first font :-( + */ + fnum = first; + ucs2fontmap(glyph, '?', encodings[fnum]); + } + + if (last_fnum != fnum || no_spc) { + XSetFont(display, gc, fonts[last_fnum]->fid); + x -= XTextWidth16(fonts[last_fnum], ptr, i); + XDrawString16(display, d, gc, x, y, ptr, i); + i = 0; + ptr = buf + 127; + (*ptr).byte1 = glyph[0]; + (*ptr).byte2 = glyph[1]; + if (no_spc) { + x += XTextWidth16(fonts[fnum], ptr, 1); + } + } else { + ptr--; + (*ptr).byte1 = glyph[0]; + (*ptr).byte2 = glyph[1]; + } + last_fnum = fnum; + i++; + string += ulen; + num_bytes -= ulen; + } + + if (i < 1) return; + + XSetFont(display, gc, fonts[fnum]->fid); + x -= XTextWidth16(fonts[last_fnum], ptr, i); + XDrawString16(display, d, gc, x, y, ptr, i); +} + + +/*****************************************************************************/ +/** draw an UTF-8 string using multiple fonts as needed. **/ +/*****************************************************************************/ +void +XUtf8DrawString(Display *display, + Drawable d, + XUtf8FontStruct *font_set, + GC gc, + int x, + int y, + const char *string, + int num_bytes) { + + int *encodings; /* encodings array */ + XFontStruct **fonts; /* fonts array */ + Fl_XChar2b buf[128]; /* drawing buffer */ + int fnum; /* index of the current font in the fonts array*/ + int i; /* current byte in the XChar2b buffer */ + int first; /* first valid font index */ + int last_fnum; /* font index of the previous char */ + int nb_font; /* quantity of fonts in the font array */ + char glyph[2]; /* byte1 and byte1 value of the UTF-8 char */ + int *ranges; /* sub range of iso10646 */ + + nb_font = font_set->nb_font; + + if (nb_font < 1) { + /* there is no font in the font_set :-( */ + return; + } + ranges = font_set->ranges; + fonts = font_set->fonts; + encodings = font_set->encodings; + i = 0; + fnum = 0; + + while(fnum < nb_font && !fonts[fnum]) fnum++; + if (fnum >= nb_font) { + /* there is no valid font for the X server */ + return; + } + + first = fnum; + last_fnum = fnum; + + while (num_bytes > 0) { + int ulen; /* byte length of the UTF-8 char */ + unsigned int ucs; /* Unicode value of the UTF-8 char */ + unsigned int no_spc; /* Spacing char equivalent of a non-spacing char */ + + if (i > 120) { + /*** draw the buffer **/ + XSetFont(display, gc, fonts[fnum]->fid); + XDrawString16(display, d, gc, x, y, buf, i); + x += XTextWidth16(fonts[fnum], buf, i); + i = 0; + } + + ulen = XFastConvertUtf8ToUcs((unsigned char*)string, num_bytes, &ucs); + + if (ulen < 1) ulen = 1; + + no_spc = XUtf8IsNonSpacing(ucs); + if (no_spc) ucs = no_spc; + + /* + * find the first encoding which can be used to + * draw the glyph + */ + fnum = first; + while (fnum < nb_font) { + if (fonts[fnum] && ucs2fontmap(glyph, ucs, encodings[fnum]) >= 0) { + if (encodings[fnum] != 0 || + (ucs >= ranges[fnum * 2] && + ucs <= ranges[fnum * 2 + 1])) { + break; + } + } + fnum++; + } + if (fnum == nb_font) { + /* the char is not valid in all encodings -> + * draw it using the first font :-( + */ + fnum = first; + ucs2fontmap(glyph, '?', encodings[fnum]); + } + + if (last_fnum != fnum || no_spc) { + XSetFont(display, gc, fonts[last_fnum]->fid); + XDrawString16(display, d, gc, x, y, buf, i); + x += XTextWidth16(fonts[last_fnum], buf, i); + i = 0; + (*buf).byte1 = glyph[0]; + (*buf).byte2 = glyph[1]; + if (no_spc) { + x -= XTextWidth16(fonts[fnum], buf, 1); + } + } else { + (*(buf + i)).byte1 = glyph[0]; + (*(buf + i)).byte2 = glyph[1]; + } + last_fnum = fnum; + i++; + string += ulen; + num_bytes -= ulen; + } + + XSetFont(display, gc, fonts[fnum]->fid); + XDrawString16(display, d, gc, x, y, buf, i); +} + + + +/*****************************************************************************/ +/** returns the pixel width of a UTF-8 string **/ +/*****************************************************************************/ +int +XUtf8TextWidth(XUtf8FontStruct *font_set, + const char *string, + int num_bytes) { + + int x; + int *encodings; /* encodings array */ + XFontStruct **fonts; /* fonts array */ + Fl_XChar2b buf[128]; /* drawing buffer */ + int fnum; /* index of the current font in the fonts array*/ + int i; /* current byte in the XChar2b buffer */ + int first; /* first valid font index */ + int last_fnum; /* font index of the previous char */ + int nb_font; /* quantity of fonts in the font array */ + char glyph[2]; /* byte1 and byte1 value of the UTF-8 char */ + int *ranges; /* sub range of iso10646 */ + + nb_font = font_set->nb_font; + x = 0; + + if (nb_font < 1) { + /* there is no font in the font_set :-( */ + return x; + } + + ranges = font_set->ranges; + fonts = font_set->fonts; + encodings = font_set->encodings; + i = 0; + fnum = 0; + + while(fnum < nb_font && !fonts[fnum]) fnum++; + if (fnum >= nb_font) { + /* there is no valid font for the X server */ + return x; + } + + first = fnum; + last_fnum = fnum; + + while (num_bytes > 0) { + int ulen; /* byte length of the UTF-8 char */ + unsigned int ucs; /* Unicode value of the UTF-8 char */ + unsigned int no_spc; /* Spacing char equivalent of a non-spacing char */ + + if (i > 120) { + /*** measure the buffer **/ + x += XTextWidth16(fonts[fnum], buf, i); + i = 0; + } + + ulen = XFastConvertUtf8ToUcs((unsigned char*)string, num_bytes, &ucs); + + if (ulen < 1) ulen = 1; + + no_spc = XUtf8IsNonSpacing(ucs); + if (no_spc) { + ucs = no_spc; + } + + /* + * find the first encoding which can be used to + * draw the glyph + */ + fnum = first; + while (fnum < nb_font) { + if (fonts[fnum] && ucs2fontmap(glyph, ucs, encodings[fnum]) >= 0) { + if (encodings[fnum] != 0 || + (ucs >= ranges[fnum * 2] && + ucs <= ranges[fnum * 2 + 1])) { + break; + } + } + fnum++; + } + if (fnum == nb_font) { + /* the char is not valid in all encodings -> + * draw it using the first font :-( + */ + fnum = first; + ucs2fontmap(glyph, '?', encodings[fnum]); + } + + if (last_fnum != fnum || no_spc) { + x += XTextWidth16(fonts[last_fnum], buf, i); + i = 0; + (*buf).byte1 = glyph[0]; + (*buf).byte2 = glyph[1]; + if (no_spc) { + /* go back to draw the non-spacing char over the previous char */ + x -= XTextWidth16(fonts[fnum], buf, 1); + } + } else { + (*(buf + i)).byte1 = glyph[0]; + (*(buf + i)).byte2 = glyph[1]; + } + last_fnum = fnum; + i++; + string += ulen; + num_bytes -= ulen; + } + + x += XTextWidth16(fonts[last_fnum], buf, i); + + return x; +} + +/*****************************************************************************/ +/** get the X font and glyph ID of a UCS char **/ +/*****************************************************************************/ +int +XGetUtf8FontAndGlyph(XUtf8FontStruct *font_set, + unsigned int ucs, + XFontStruct **fnt, + unsigned short *id) { + + int x; + int *encodings; /* encodings array */ + XFontStruct **fonts; /* fonts array */ + int fnum; /* index of the current font in the fonts array*/ + int i; /* current byte in the XChar2b buffer */ + int first; /* first valid font index */ + int last_fnum; /* font index of the previous char */ + int nb_font; /* quantity of fonts in the font array */ + char glyph[2]; /* byte1 and byte1 value of the UTF-8 char */ + int *ranges; /* sub range of iso10646 */ + + nb_font = font_set->nb_font; + x = 0; + + if (nb_font < 1) { + /* there is no font in the font_set :-( */ + return -1; + } + + ranges = font_set->ranges; + fonts = font_set->fonts; + encodings = font_set->encodings; + i = 0; + fnum = 0; + + while(fnum < nb_font && !fonts[fnum]) fnum++; + if (fnum >= nb_font) { + /* there is no valid font for the X server */ + return -1; + } + + first = fnum; + last_fnum = fnum; + + /* + * find the first encoding which can be used to + * draw the glyph + */ + fnum = first; + while (fnum < nb_font) { + if (fonts[fnum] && ucs2fontmap(glyph, ucs, encodings[fnum]) >= 0) { + if (encodings[fnum] != 0 || + (ucs >= ranges[fnum * 2] && + ucs <= ranges[fnum * 2 + 1])) { + break; + } + } + fnum++; + } + if (fnum == nb_font) { + /* the char is not valid in all encodings -> + * draw it using the first font :-( + */ + fnum = first; + ucs2fontmap(glyph, '?', encodings[fnum]); + } + + *id = ((unsigned char)glyph[0] << 8) | (unsigned char)glyph[1] ; + *fnt = fonts[fnum]; + return 0; +} + +/*****************************************************************************/ +/** returns the pixel width of a UCS char **/ +/*****************************************************************************/ +int +XUtf8UcsWidth(XUtf8FontStruct *font_set, + unsigned int ucs) { + + int x; + int *encodings; /* encodings array */ + XFontStruct **fonts; /* fonts array */ + Fl_XChar2b buf[8]; /* drawing buffer */ + int fnum; /* index of the current font in the fonts array*/ + int i; /* current byte in the XChar2b buffer */ + int first; /* first valid font index */ + int last_fnum; /* font index of the previous char */ + int nb_font; /* quantity of fonts in the font array */ + char glyph[2]; /* byte1 and byte1 value of the UTF-8 char */ + int *ranges; /* sub range of iso10646 */ + + nb_font = font_set->nb_font; + x = 0; + + if (nb_font < 1) { + /* there is no font in the font_set :-( */ + return x; + } + + ranges = font_set->ranges; + fonts = font_set->fonts; + encodings = font_set->encodings; + i = 0; + fnum = 0; + + while(fnum < nb_font && !fonts[fnum]) fnum++; + if (fnum >= nb_font) { + /* there is no valid font for the X server */ + return x; + } + + first = fnum; + last_fnum = fnum; + + ucs = XUtf8IsNonSpacing(ucs); + + /* + * find the first encoding which can be used to + * draw the glyph + */ + fnum = first; + while (fnum < nb_font) { + if (fonts[fnum] && + ucs2fontmap(glyph, ucs, encodings[fnum]) >= 0) { + if (encodings[fnum] != 0 || (ucs >= ranges[fnum * 2] && + ucs <= ranges[fnum * 2 + 1])) { + break; + } + } + fnum++; + } + if (fnum == nb_font) { + /* the char is not valid in all encodings -> + * draw it using the first font :-( + */ + fnum = first; + ucs2fontmap(glyph, '?', encodings[fnum]); + } + + (*buf).byte1 = glyph[0]; + (*buf).byte2 = glyph[1]; + + x += XTextWidth16(fonts[fnum], buf, 1); + + return x; +} + +/*****************************************************************************/ +/** draw an UTF-8 string and clear the background. **/ +/*****************************************************************************/ +void +XUtf8DrawImageString(Display *display, + Drawable d, + XUtf8FontStruct *font_set, + GC gc, + int x, + int y, + const char *string, + int num_bytes) { + + /* FIXME: must be improved ! */ + int w; + int fill_style; + unsigned long foreground; + unsigned long background; + int function; + XGCValues xgcv; + + w = XUtf8TextWidth(font_set, string, num_bytes); + + XGetGCValues(display, gc, + GCFunction|GCForeground|GCBackground|GCFillStyle, &xgcv); + + function = xgcv.function; + fill_style = xgcv.fill_style; + foreground = xgcv.foreground; + background = xgcv.background; + + xgcv.function = GXcopy; + xgcv.foreground = background; + xgcv.background = foreground; + xgcv.fill_style = FillSolid; + + XChangeGC(display, gc, + GCFunction|GCForeground|GCBackground|GCFillStyle, &xgcv); + + XFillRectangle(display, d, gc, x, y - font_set->ascent, + (unsigned)w, (unsigned)(font_set->ascent + font_set->descent)); + + xgcv.function = function; + xgcv.foreground = foreground; + xgcv.background = background; + xgcv.fill_style = fill_style; + + XChangeGC(display, gc, + GCFunction|GCForeground|GCBackground|GCFillStyle, &xgcv); + + XUtf8DrawString(display, d, font_set, gc, x, y, string, num_bytes); +} + +/*****************************************************************************/ +/** free the XFontSet and others things created by XCreateUtf8FontSet **/ +/*****************************************************************************/ +void +XFreeUtf8FontStruct(Display *dpy, + XUtf8FontStruct *font_set) { + + int i; + i = 0; + while (i < font_set->nb_font) { + if (font_set->fonts[i]) { + XFreeFont(dpy, font_set->fonts[i]); + free(font_set->font_name_list[i]); + } + i++; + } + free(font_set->ranges); + free(font_set->font_name_list); + free(font_set->fonts); + free(font_set->encodings); + free(font_set); +} + +#endif /* X11 only */ + +/* + * End of "$Id: $". + */ diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/utils/INSTALL b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/utils/INSTALL new file mode 100644 index 0000000..a9fbd7c --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/utils/INSTALL @@ -0,0 +1,26 @@ + +Default install : + + tar -xvzf Xutf8.tar.gz + cd Xutf8 + ./configure --prefix=/usr + su -c "make install" + + + +Install with tables generation : + + You must have a copy of http://www.unicode.org/Public/MAPPINGS/ in + the ./MAPPINGS/ directory and a copy of UnicodeData-2.txt in ./ + to generate the conversion tables. + + To add a table, edit utils/tbl_gen.sh and utils/convert_map.c. + + tar -xvzf Xutf8.tar.gz + cd Xutf8 + ./configure + cd utils + make + cd .. + su -c "make install" + diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/utils/Makefile b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/utils/Makefile new file mode 100644 index 0000000..3bed422 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/utils/Makefile @@ -0,0 +1,22 @@ +euc_tw: euc_tw.c + gcc euc_tw.c -o euc_tw + +all: convert_map create_table conv_gen + ./tbl_gen.sh + ./non_spacing.sh + ./case.sh + +conv_gen: conv_gen.c + gcc conv_gen.c -o conv_gen + +convert_map: convert_map.c + gcc convert_map.c -o convert_map + +create_table: create_table.c + gcc create_table.c -o create_table + +clean: + rm -f *.o convert_map create_table conv_gen euc_tw + + + diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/utils/README b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/utils/README new file mode 100644 index 0000000..5f6771d --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/utils/README @@ -0,0 +1,14 @@ +tbl_gen.sh : + shell script that convert unicode.org mappings tables to c headers. + Also creates unicode2fontmap.c. + +conv_gen.c: + create unicode2fontmap.c functions. + +convert_map.c: + convert diffrent unicode.org mappings to a unique format. + +create_table.c: + convert text files created by convert_map.c to to c tables. + + diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/utils/case.sh b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/utils/case.sh new file mode 100644 index 0000000..c12e27c --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/utils/case.sh @@ -0,0 +1,105 @@ +#!/bin/sh + + +nopsc=`grep 'CAPITAL' ../UnicodeData-2.txt` + +IFS=" +" + +#echo "# +# List of case chars +# +# +# Format: Three tab-separated columns +# Column #1 is the non-spacing Unicode (in hex as 0xXXXX) +# Column #2 is the spacing Unicode (in hex as 0xXXXX) +# Column #3 the Unicode name (follows a comment sign, '#') +# " > case.txt + +rm -f case.txt + + +for line in ${nopsc} +do + ucs=`echo ${line} | cut -d\; -f1` + name=`echo ${line} | cut -d\; -f2 | cut -d\; -f1| sed s/CAPITAL/SMALL/` + small=`grep ";${name};" ../UnicodeData-2.txt` + if test "X${small}" != X ;then + tbl=`echo ${small} | cut -d\; -f1` + # echo "0x${ucs} 0x${tbl} # ${name}" >> space.txt + echo "/* U+${ucs} */ 0x${tbl}," >> case.txt + else + # echo "0x${ucs} 0x${ucs} # ${name}" >> space.txt + echo "/* U+${ucs} */ 0x0," >> case.txt + fi +done + +unset nospc + +# echo "/* EOF */" >> space.txt + +cat case.txt | ./create_table "spacing" > "../headers/case.h" 2> ../headers/case_tbl.txt + +rm -f case.txt + +cat >../case.c << ENDOFTEXT +/* + * Author: Jean-Marc Lienher ( http://oksid.ch ) + * Copyright 2000-2003 by O'ksi'D. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems on the following page: + * + * http://www.fltk.org/str.php + */ + +#include "headers/case.h" + +ENDOFTEXT + +echo " +int +XUtf8Tolower( + int ucs) +{ + int ret; +" >>../case.c + +tables=`cat ../headers/case_tbl.txt` + +for line in ${tables} +do + tbl=`echo ${line} | cut -d']' -f1` + bot=`echo ${line} | cut -d'_' -f3 | cut -d'[' -f1` + eot=`echo ${line} | cut -d' ' -f2 | cut -d'+' -f2 | cut -d' ' -f1` + echo "\ + if (ucs <= 0x${eot}) { + if (ucs >= 0x${bot}) { + ret = ${tbl}ucs - 0x${bot}]; + if (ret > 0) return ret; + } + return ucs; + } +" >>../case.c + +done + +echo " return ucs; +} +" >>../case.c + + diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/utils/conv_gen.c b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/utils/conv_gen.c new file mode 100644 index 0000000..c979029 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/utils/conv_gen.c @@ -0,0 +1,174 @@ +/* "$Id: $" + * + * Author: Jean-Marc Lienher ( http://oksid.ch ) + * Copyright 2000-2003 by O'ksi'D. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems on the following page: + * + * http://www.fltk.org/str.php + */ + +/* + * generate the "if(){} else if ..." structure of ucs2fontmap() + */ +#include +#include +char buffer[1000000]; + +int main(int argc, char **argv) { + char buf[80]; + int len; + char *encode[256]; + int encode_number = 0; + unsigned int i = 0; + unsigned char *ptr; + unsigned char *lst = ""; + size_t nb; + int nbb = 0; + len = fread(buffer, 1, 1000000, stdin); + + puts(" "); + puts(" /*************** conv_gen.c ************/"); + buffer[len] = '\0'; + ptr = buffer; + + printf("const int ucs2fontmap" + "(char *s, unsigned int ucs, int enc)\n"); + printf("{\n"); + printf(" switch(enc) {\n"); + printf(" case 0:\n"); + printf(" s[0] = (char) ((ucs & 0xFF00) >> 8);\n"); + printf(" s[1] = (char) (ucs & 0xFF);\n"); + printf(" return 0;"); + while (len > 0) { + unsigned char *p = ptr; + unsigned char *f, *t; + + while (*p != ']') { + i++; + p++; + } + *(p - 1) = '\0'; + *(p - 6) = '\0'; + f = p - 5; + while (*p != '+') { i++; p++;} + p++; + t = p; + *(p + 4) = '\0'; + if (strcmp(lst, ptr)) { + encode_number++; + encode[encode_number] = ptr; + printf("\n break;"); + printf("\n case %d:\n", encode_number); + printf(" "); + } else { + printf(" else "); + } + lst = ptr; + printf("if (ucs <= 0x%s) {\n", t); + printf(" if (ucs >= 0x%s) {\n", f); + if (*(f - 3) == '2') { + printf(" int i = (ucs - 0x%s) * 2;\n", f); + printf(" s[0] = %s_%s[i++];\n", ptr, f, f); + printf(" s[1] = %s_%s[i];\n", ptr, f, f); + printf(" if (s[0] || s[1]) return %d;\n", encode_number); + } else { + printf(" s[0] = 0;\n"); + printf(" s[1] = %s_%s[ucs - 0x%s];\n", ptr, f, f); + printf(" if (s[1]) return %d;\n", encode_number); + } + printf(" }\n"); + printf(" }"); + while (*ptr != '\n') { + ptr++; + len--; + } + ptr++; + len--; + } + printf("\n break;\n"); + printf("\n default:\n"); + printf(" break;\n"); + printf(" };\n"); + printf(" return -1;\n"); + printf("};\n\n"); + + printf("const int encoding_number(const char *enc)\n{\n"); + printf(" if (!enc || !strcmp(enc, \"iso10646-1\")) {\n"); + printf(" return 0;\n"); + i = 1; + while (i <= encode_number) { + int l; + char *ptr; + l = strlen(encode[i]) - 3; + ptr = encode[i] + l; + *(ptr) = '\0'; + ptr--; + while (ptr != encode[i]) { + if (*ptr == '_') { + *ptr = '-'; + ptr--; + break; + } + ptr--; + } + while (ptr != encode[i]) { + if (*ptr == '_') { + *ptr = '.'; + } + ptr--; + } + printf(" } else if (!strcmp(enc, \"%s\")", encode[i] +11); + + if (!strcmp(encode[i] + 11, "big5-0")) { + printf(" || !strcmp(enc, \"big5.eten-0\")"); + } else if (!strcmp(encode[i] + 11, "dingbats")) { + printf(" || !strcmp(enc, \"zapfdingbats\")"); + printf(" || !strcmp(enc, \"zapf dingbats\")"); + printf(" || !strcmp(enc, \"itc zapf dingbats\")"); + } else if (!strcmp(encode[i] + 11, "jisx0208.1983-0")) { + printf(" || !strcmp(enc, \"jisx0208.1990-0\")"); + } + + printf(") {\n"); + printf(" return %d;\n", i); + i++; + } + printf(" };\n"); + printf(" return -1;\n"); + printf("};\n\n"); + + printf("/*\n"); + printf("const char *encoding_name(int num)\n{\n"); + printf(" switch (num) {\n"); + i = 1; + while (i <= encode_number) { + printf(" case %d:\n", i); + printf(" return \"%s\";\n", encode[i] + 11); + i++; + } + printf(" };\n"); + printf(" return \"iso10646-1\";\n"); + printf("};\n\n"); + printf("*/\n"); + return 0; +} + +/* + * End of "$Id$". + */ diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/utils/convert_map.c b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/utils/convert_map.c new file mode 100644 index 0000000..6e9c649 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/utils/convert_map.c @@ -0,0 +1,179 @@ +/* "$Id: $" + * + * Author: Jean-Marc Lienher ( http://oksid.ch ) + * Copyright 2000-2003 by O'ksi'D. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems on the following page: + * + * http://www.fltk.org/str.php + */ + +/* + * read the http://www.unicode.org/Public/MAPPINGS/ and create something + * usable in C. + */ + +#include +#include + +char buffer[1000000]; + +int JIS0208(unsigned char * ptr) { + int i = 0; + unsigned int fmap; + unsigned int ucs; + while(*ptr != '\t') { ptr++; i++; } + ptr++; i++; *(ptr+6) = '\0'; + fmap = (unsigned int)strtoul(ptr, NULL, 16); + while(*ptr != '\0') { ptr++; i++; } + i++; ptr++; *(ptr+6) = '\0'; + ucs = (unsigned int)strtoul(ptr, NULL, 16); + if (ucs) + printf("/* U+%04X */ 0x%02X, 0x%02X,\n", ucs, + (fmap & 0xFF00) >> 8, fmap & 0xFF); + while(*ptr != '\0') { ptr++; i++; } + i++; ptr++; + while(*ptr != '\n') { ptr++; i++; } + i++; + return i; +} + +int JIS0201(unsigned char * ptr) { + int i = 0; + unsigned int fmap; + unsigned int ucs; + *(ptr+4) = '\0'; + fmap = (unsigned int)strtoul(ptr, NULL, 16); + while(*ptr != '\0') { ptr++; i++; } + i++; ptr++; *(ptr+6) = '\0'; + ucs = (unsigned int)strtoul(ptr, NULL, 16); + if (*(ptr + 1) != 'x') { + printf("/* EOF */\n"); + abort(); + } + if (ucs) printf("/* U+%04X */ 0x%02X,\n", ucs, (unsigned char)fmap); + while(*ptr != '\0') { ptr++; i++; } + i++; ptr++; + while(*ptr != '\n') { ptr++; i++; } + i++; + return i; +} + +int ADOBE(unsigned char * ptr) { + int i = 0; + unsigned int fmap; + unsigned int ucs; + *(ptr+4) = '\0'; + ucs = (unsigned int)strtoul(ptr, NULL, 16); + while(*ptr != '\0') { ptr++; i++; } + i++; ptr++; *(ptr+2) = '\0'; + fmap = (unsigned int)strtoul(ptr, NULL, 16); + if (fmap < 1) { + printf("/* EOF */\n"); + abort(); + } + if (ucs) printf("/* U+%04X */ 0x%02X,\n", ucs, (unsigned char)fmap); + while(*ptr != '\0') { ptr++; i++; } + i++; ptr++; + while(*ptr != '\n') { ptr++; i++; } + i++; + return i; +} + + +int JIS0212(unsigned char * ptr) { + int i = 0; + unsigned int fmap; + unsigned int ucs; + *(ptr+6) = '\0'; + fmap = (unsigned int)strtoul(ptr, NULL, 16); + ptr += 7; + i += 7; + while(*ptr == ' ') { ptr++; i++; } + //i++; ptr++; + *(ptr+6) = '\0'; + ucs = (unsigned int)strtoul(ptr, NULL, 16); + if (*(ptr + 1) != 'x') { + printf("/* EOF */\n"); + abort(); + } + if (ucs) + printf("/* U+%04X */ 0x%02X, 0x%02X,\n", ucs, + (fmap & 0xFF00) >> 8, fmap & 0xFF); + while(*ptr != '\0') { ptr++; i++; } + i++; ptr++; + while(*ptr != '\n') { ptr++; i++; } + i++; + return i; +} + +int main(int argc, char **argv) { + char buf[80]; + int len; + int i; + unsigned char *ptr; + size_t nb; + len = fread(buffer, 1, 1000000, stdin); + + buffer[len] = '\0'; + ptr = (unsigned char *)buffer; + while (*ptr !='\n') {ptr++; len--;}; + ptr++; len--; + while (*ptr == '#') { + while (*ptr !='\n') { + ptr++; + len--; + } + ptr++; + len--; + } + + while (len > 0) { + nb = 0; + if (!strcmp("jisx0208.1983-0", argv[1])) { + nb = JIS0208(ptr); + } else if (!strcmp("jisx0201.1976-0", argv[1])) { + nb = JIS0201(ptr); + } else if (!strcmp("jisx0212.1990-0", argv[1])) { + nb = JIS0212(ptr); + } else if (!strcmp("gb2312.1980-0", argv[1])) { + nb = JIS0212(ptr); + } else if (!strcmp("ksc5601.1987-0", argv[1])) { + nb = JIS0212(ptr); + } else if (!strcmp("big5-0", argv[1])) { + nb = JIS0212(ptr); + } else if (!strncmp("iso8859", argv[1], 7)) { + nb = JIS0201(ptr); + } else if (!strcmp("koi8-1", argv[1])) { + nb = JIS0201(ptr); + } else if (!strcmp("dingbats", argv[1]) || + !strcmp("symbol", argv[1])) + { + nb = ADOBE(ptr); + } else { + len = 0; + } + ptr += nb; + len = len - nb; + } + return 0; +} + +/* + * End of "$Id$". + */ diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/utils/create_table.c b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/utils/create_table.c new file mode 100644 index 0000000..cfee793 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/utils/create_table.c @@ -0,0 +1,112 @@ +/* "$Id: $" + * + * Author: Jean-Marc Lienher ( http://oksid.ch ) + * Copyright 2000-2003 by O'ksi'D. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems on the following page: + * + * http://www.fltk.org/str.php + */ + +#include +#include +char buffer[1000000]; + +/*** you can try to modifie this value to have better performences **/ +#define MAX_DELTA 0x80 + +int main(int argc, char **argv) { + char buf[80]; + int len; + unsigned int i = 0; + unsigned char *ptr; + size_t nb; + int nbb = 0; + len = fread(buffer, 1, 1000000, stdin); + + buffer[len] = '\0'; + ptr = (unsigned char *)buffer; + while (*ptr != '\n') ptr++; + ptr++; + while (*ptr != '\n') { + if (*ptr == ',') nbb++; + ptr++; + } + ptr = (unsigned char *)buffer; + printf("/* %s */\n", argv[1]); + while (len > 0) { + unsigned int ucs = 0; + char *p = ptr; + char pp[20]; + nb = 0; + pp[0] = '\0'; + while (*p != 'U') p++; + strncat(pp, p, 6); + *pp = '0'; + *(pp+1) = 'x'; + ucs = (unsigned int)strtoul(pp, NULL, 16);; + if (ucs < 1) { + printf("ERROR %d %d\n", len, ucs); + abort(); + } + if (i != ucs - 1 || !i) { + if ((ucs - i) > MAX_DELTA || !i) { + if (i) { + printf("};\n"); + fprintf(stderr, "\t/* end: U+%04X */\n", i); + } + if (strcmp(argv[1], "spacing")) { + printf("\nstatic const char unicode_to_%s_%db_%04X[] = {\n", + argv[1], nbb, ucs); + fprintf(stderr, "unicode_to_%s_%db_%04X[]; ", + argv[1], nbb, ucs); + } else { + printf("\nstatic const unsigned short" + " ucs_table_%04X[]" + " = {\n", ucs); + fprintf(stderr, "ucs_table_%04X[]; ", ucs); + } + } else { + while (i < ucs - 1) { + i++; + if (nbb == 1) { + printf("0x00,\n"); + } else { + printf("0x00, 0x00,\n"); + } + }; + } + } + i = ucs; + while (*ptr != '\n') { + printf("%c", *ptr); + ptr++; + len--; + } + printf("\n"); + ptr++; + len--; + } + printf("};\n"); + fprintf(stderr, "\t/* end: U+%04X */\n", i); + return 0; +} + +/* + * End of "$Id$". + */ diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/utils/euc_tw.c b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/utils/euc_tw.c new file mode 100644 index 0000000..5232666 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/utils/euc_tw.c @@ -0,0 +1,67 @@ +/* + * Author: Jean-Marc Lienher ( http://oksid.ch ) + * Copyright 2000-2003 by O'ksi'D. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems on the following page: + * + * http://www.fltk.org/str.php + */ + +/* + * generate the "if(){} else if ..." structure of ucs2fontmap() + */ + +#include +#include +#include +char uni[0x10000]; +#include "../utf8Utils.c" + +int main(int argc, char **argv) { + + iconv_t cd; + + int i; + cd = iconv_open("EUC-TW", "UTF16"); + for(i = 0; i < 0x10000; i++) uni[i] = 0; + for(i = 0x00000000; i < 0xFFFFFFFF; i++) { + char buf[4], ob[6]; + char *b = buf; + int ucs = -1; + int l1 = 4, l2 = 6; + char *o = ob ; + buf[0] = i & 0xff; + buf[1] = (i >> 8) & 0xFF; + buf[2] = (i >> 16) & 0xFF; + buf[3] = (i >> 24) & 0xFF; + iconv(cd, NULL, NULL, NULL, NULL); + iconv(cd, &b, &l1, &o, &l2); + if (l2 != 6) { + ucs = (unsigned)ob[0]; + ucs += (unsigned) (ob[1] << 8); + //XConvertUtf8ToUcs((unsigned char*)ob, 6 - l2, &ucs); + printf ("%x --> %X\n", i, ucs & 0xFFFF); + } + } + iconv_close(cd); + return 0; +} + +/* + * End of "$Id$". + */ diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/utils/non_spacing.sh b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/utils/non_spacing.sh new file mode 100644 index 0000000..c9195e3 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/utils/non_spacing.sh @@ -0,0 +1,101 @@ +#!/bin/sh + + +nopsc=`grep ';Mn;' ../UnicodeData-2.txt` + +IFS=" +" + +#echo "# +# List of non-spacing chars +# +# +# Format: Three tab-separated columns +# Column #1 is the non-spacing Unicode (in hex as 0xXXXX) +# Column #2 is the spacing Unicode (in hex as 0xXXXX) +# Column #3 the Unicode name (follows a comment sign, '#') +# " > space.txt + +rm -f space.txt + + +for line in ${nopsc} +do + ucs=`echo ${line} | cut -d\; -f1` + name=`echo ${line} | cut -d\; -f2` + space=`grep " 0020 ${ucs};" ../UnicodeData-2.txt` + if test "X${space}" != X ;then + tbl=`echo ${space} | cut -d\; -f1` + # echo "0x${ucs} 0x${tbl} # ${name}" >> space.txt + echo "/* U+${ucs} */ 0x${tbl}," >> space.txt + else + # echo "0x${ucs} 0x${ucs} # ${name}" >> space.txt + echo "/* U+${ucs} */ 0x${ucs}," >> space.txt + fi +done + +unset nospc + +# echo "/* EOF */" >> space.txt + +cat space.txt | ./create_table "spacing" > "../headers/spacing.h" 2> ../headers/spacing_tbl.txt + +rm -f space.txt + +cat >../is_spacing.c << ENDOFTEXT +/* + * Author: Jean-Marc Lienher ( http://oksid.ch ) + * Copyright 2000-2003 by O'ksi'D. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems on the following page: + * + * http://www.fltk.org/str.php + */ + +#include "headers/spacing.h" + +ENDOFTEXT + +echo " +unsigned short +XUtf8IsNonSpacing( + unsigned int ucs) +{ +" >>../is_spacing.c + +tables=`cat ../headers/spacing_tbl.txt` + +for line in ${tables} +do + tbl=`echo ${line} | cut -d']' -f1` + bot=`echo ${line} | cut -d'_' -f3 | cut -d'[' -f1` + eot=`echo ${line} | cut -d' ' -f2 | cut -d'+' -f2 | cut -d' ' -f1` + echo "\ + if (ucs <= 0x${eot}) { + if (ucs >= 0x${bot}) return ${tbl}ucs - 0x${bot}]; + return 0; + } +" >>../is_spacing.c + +done + +echo " return 0; +} +" >>../is_spacing.c + + diff --git a/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/utils/tbl_gen.sh b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/utils/tbl_gen.sh new file mode 100644 index 0000000..255dff1 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/src/xutf8/utils/tbl_gen.sh @@ -0,0 +1,179 @@ +#!/bin/sh +#/* +# * generates ucs2fontmap.c and headers/*_.h +# * +# * Author: Jean-Marc Lienher ( http://oksid.ch ) +# * Copyright 2000-2003 by O'ksi'D. +# * +# * This library is free software; you can redistribute it and/or +# * modify it under the terms of the GNU Library General Public +# * License as published by the Free Software Foundation; either +# * version 2 of the License, or (at your option) any later version. +# * +# * This library is distributed in the hope that it will be useful, +# * but WITHOUT ANY WARRANTY; without even the implied warranty of +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# * Library General Public License for more details. +# * +# * You should have received a copy of the GNU Library General Public +# * License along with this library; if not, write to the Free Software +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +# * USA. +# * +# * Please report all bugs and problems on the following page: +# * +# * http://www.fltk.org/str.php +# */ +# + +# iso10646-1 + +encode="iso8859-1 iso8859-2 iso8859-3 \ + iso8859-4 iso8859-5 iso8859-6 iso8859-7 iso8859-8 iso8859-9 \ + iso8859-10 iso8859-13 iso8859-14 iso8859-15 \ + koi8-1 big5-0 ksc5601.1987-0 gb2312.1980-0 jisx0201.1976-0 \ + jisx0208.1983-0 jisx0212.1990-0 symbol dingbats" + +mkdir -p ../headers/ +rm -f ../headers/* ucs2fontmap + +for enc in ${encode} +do + echo ${enc} + + case ${enc} in + ksc5601.1987-0) +# cat ../MAPPINGS/EASTASIA/KSC/KSC5601.TXT | \ + cat ../MAPPINGS/EASTASIA/KSC/KSX1001.TXT | \ + ./convert_map "${enc}" > ${enc}.txt + ;; + koi8-1) + cat ../MAPPINGS/VENDORS/MISC/KOI8-R.TXT | \ + ./convert_map "${enc}" > ${enc}.txt + ;; + iso8859-14) + cat ../MAPPINGS/ISO8859/8859-14.TXT | \ + ./convert_map "${enc}" > ${enc}.txt + ;; + iso8859-13) + cat ../MAPPINGS/ISO8859/8859-13.TXT | \ + ./convert_map "${enc}" > ${enc}.txt + ;; + iso8859-5) + cat ../MAPPINGS/ISO8859/8859-5.TXT | \ + ./convert_map "${enc}" > ${enc}.txt + ;; + iso8859-6) + cat ../MAPPINGS/ISO8859/8859-6.TXT | \ + ./convert_map "${enc}" > ${enc}.txt + ;; + iso8859-1) + cat ../MAPPINGS/ISO8859/8859-1.TXT | \ + ./convert_map "${enc}" > ${enc}.txt + ;; + iso8859-10) + cat ../MAPPINGS/ISO8859/8859-10.TXT | \ + ./convert_map "${enc}" > ${enc}.txt + ;; + iso8859-15) + cat ../MAPPINGS/ISO8859/8859-15.TXT | \ + ./convert_map "${enc}" > ${enc}.txt + ;; + iso8859-2) + cat ../MAPPINGS/ISO8859/8859-2.TXT | \ + ./convert_map "${enc}" > ${enc}.txt + ;; + iso8859-3) + cat ../MAPPINGS/ISO8859/8859-3.TXT | \ + ./convert_map "${enc}" > ${enc}.txt + ;; + iso8859-4) + cat ../MAPPINGS/ISO8859/8859-4.TXT | \ + ./convert_map "${enc}" > ${enc}.txt + ;; + iso8859-7) + cat ../MAPPINGS/ISO8859/8859-7.TXT | \ + ./convert_map "${enc}" > ${enc}.txt + ;; + iso8859-8) + cat ../MAPPINGS/ISO8859/8859-8.TXT | \ + ./convert_map "${enc}" > ${enc}.txt + ;; + iso8859-9) + cat ../MAPPINGS/ISO8859/8859-9.TXT | \ + ./convert_map "${enc}" > ${enc}.txt + ;; + dingbats) + cat ../MAPPINGS/VENDORS/ADOBE/zdingbat.txt | \ + ./convert_map "${enc}" > ${enc}.txt + ;; + symbol) + cat ../MAPPINGS/VENDORS/ADOBE/symbol.txt | \ + ./convert_map "${enc}" > ${enc}.txt + ;; + big5-0) + cat ../MAPPINGS/EASTASIA/OTHER/BIG5.TXT | \ + ./convert_map "${enc}" > ${enc}.txt + ;; + gb2312.1980-0) + cat ../MAPPINGS/EASTASIA/GB/GB2312.TXT | \ + ./convert_map "${enc}" > ${enc}.txt + ;; + jisx0212.1990-0) + cat ../MAPPINGS/EASTASIA/JIS/JIS0212.TXT | \ + ./convert_map "${enc}" > ${enc}.txt + ;; + jisx0208.1983-0) + cat ../MAPPINGS/EASTASIA/JIS/JIS0208.TXT | \ + ./convert_map "${enc}" > ${enc}.txt + ;; + jisx0201.1976-0) + cat ../MAPPINGS/EASTASIA/JIS/JIS0201.TXT | \ + ./convert_map "${enc}" > ${enc}.txt + ;; + esac + nm=`echo ${enc} |tr '.' '_' | tr '-' '_'` + cat ${enc}.txt | sort | uniq | \ + ./create_table "${nm}" >> ../headers/${nm}_.h 2>> ../headers/tbl.txt + rm -f ${enc}.txt + enc=" " +done + +cat > ../ucs2fontmap.c << ENDOFTEXT +/* + * Author: Jean-Marc Lienher ( http://oksid.ch ) + * Copyright 2000-2003 by O'ksi'D. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems on the following page: + * + * http://www.fltk.org/str.php + */ + +ENDOFTEXT + + +he=`cd ..; ls headers/*.h` +for hea in ${he} +do + echo "#include \"${hea}\"" >> ../ucs2fontmap.c +done + + +cat ../headers/tbl.txt | ./conv_gen >> ../ucs2fontmap.c + + diff --git a/mod/maxgui.mod/fltkmaxgui.mod/version.txt b/mod/maxgui.mod/fltkmaxgui.mod/version.txt new file mode 100644 index 0000000..993e701 --- /dev/null +++ b/mod/maxgui.mod/fltkmaxgui.mod/version.txt @@ -0,0 +1,240 @@ +1.60 +Various UTF8 fixes +AntiAlias fonts on +1.58 Release +Updated FLTK library to FLTK 1.3.x r7907 with numerous fixes (e.g. shortcut + caps lock problem). +1.57 Release +Added RemoveColor implementation. +Modified license. +1.56 Release +Added GetStatusText() implementation. +Added missing Class() methods to TFLTextField and TFLLabel. +Fixed RequestColor() parameter passing. +Fixed pasting into text areas to work with WINDOW_ACCEPTFILES flag. +1.55 Release +Added hack to fix X crash that appeared when Ubuntu's Maximus is running. +Bumped FLTK 1.3 version to rev. 7652. +Added support for new PANEL_RAISED style flag. +1.54 Release +Fixed label background colors not showing. +1.53 Release +Added LookupColor() method to TFLTKGUIDriver. +1.52b Release +Disabled FLTK text widgets pasting file-names when files are dropped onto a window. +1.52 Release +Bumped FLTK 1.3 version to rev. 7062 to fix OS X compilation issues with GCC 3. +1.51b Release +Fixed button image offset when no text is displayed. +1.50 Release +Merged in markcw's latest Fl_Help_View changes which include basic CSS support! :-) +Updated FLTK 1.3.x library to revision 6980 (fixes a few Cocoa bugs). +Added MacOS compilation support. +1.49 Release +Fixed filename_list.cxx compile error on Ubuntu 9.10. +Bumped FLTK 1.3.x version to rev. 6948. +1.48b Release +Fixed GCC 4.4.1 compiler errors - thanks Otus (/Community/posts.php?topic=87472). +1.48 Release +Added icon support to list boxes (http://www.fltk.org/str.php?L1739). +Fixed another memory corruption bug concerning incorrectly casting toolbar Fl_Group to Fl_Panel. +Fixed group panel label background so that it is 'transparent'. +Implemented primitive software-based pixmap scaling for panels. +Updated FLTK library to FLTK 1.3 rev. 6873. +Disabled XDBE for Linux as it was sometimes causing black flickering on window resize. +(Finally) found and fixed the memory corruption bug in Fl_Menu and plugged up a memory leak. +Fixed textarea paste crash. +Fixed UpdateWindowMenu() crash. +Toolbars now push down the client area of the parent window. +More work to improve handling of WINDOW_CLIENTCOORDS style. +Hacked in 'xdg-get-user-path' for Flu_File_Chooser using Brucey's kindly donated BaH.Volumes code. +Added user_data() node information to speed up treeviews and event generation. +Added maximize() and restore() methods for Fl_AWindow. +Fixed textfields with TEXTFIELD_PASSWORD style. +Added hover effect for non-standard push-buttons and non-editable comboboxes. +Reworked event handling to use extremely nice and tidy C++ template system - improves mouse/keyboard event generation. +Fixed SelectedTreeViewNode() and EVENT_GADGETMENU on treeviews. +1.47 Release +Fixed textfield crash upon typing. +Fixed stray EVENT_GADGETACTION event when enter was pressed in a textfield. +Fixed push buttons losing background colors on mouse hover. +Implemented new trial OnMouse() and OnKey() system for generating mouse and key events, that facilitates SetSensitivity(). +Added Flmm_Tabs so that, when too many tabs are added to a tabber, a drop-down menu is shown instead of squashing them up. +Added degac's label text fix. +LABEL_FRAME border fix. +1.46 Release +Added toolbar separators. +Fixed comboboxes losing selection after ModifyGadgetItem. +Fixed RemoveGadgetItem on toolbars. +1.45 Release +Added XPMFromPixmap() function to TFLWidget to enable support for window icons. +Other clearing up. +1.44 Release +Fixed window SetGadgetText() memory leak and stray WidgetHandle() as a parameter. +Uncommented XCloseIM() from Fl_x.cxx - cause of memory leak. +Latest set of markcw's Fl_Help_View fixes - see http://www.blitzbasic.com/Community/posts.php?topic=79280#947564. +1.43 Release +FLTK's event system will now completely override over BRL.System's default. +All function externs and constants have been moved to a separate, privately included fltkdecls.bmx. +1.42 Release +Fixed double event for EVENT_MOUSEDOWN and hacked in workaround for missing XEvents. +1.41 Release +Modified TFLPanel's event handling code so that it makes use of SetSensitivity()/GetSensitivity(). +SelectTreeViewNode(TreeViewRoot(treeView)) now deselects the currently selected node. +Fixed missing EVENT_WINDOWACCEPT events. +Updated FLTK 1.3 library to revision 6719. +1.40 Release +Updated FLTK 1.3 library to revision 6663. +1.39 Release +Added hack to scale up font sizes on Windows. +Committed version with FreeType support enabled by default. +1.38 Release +Fixed window disabling. +Added markcw's HTMLView forward/back code - thanks Mark. +Fixed event.data on button EVENT_GADGETACTION. +Tweaked to allow module to compile and run on Windows. +Fixed missing mouse wheel events on canvas. +Improved font handling and FontRequest() window. +Updated to FLTK 1.3, rev 6649. +1.37 Release +Skid's GCC 4.X fixes. +Fixed crash when freeing Fl_Text_Display. +Radio buttons and check boxes should now be left-aligned. +1.36 Release +Loads more Fl_Help_View fixes courtesy of markcw. +1.35 Release +Added prelimary pixmap support for push-buttons. +Added text support for group-panels. +1.34 Release +Tweaked Fl_Color to accept a wider range of formatting color contrasts before resorting to black or white defaults. +1.33 Release +Added SetTextColor() method to allow for multi-colored widgets. +Added a MaxGUI style stepper, complete with repeat buttons. +1.32 Release +Completely restructured fltkgui.bmx into OO code. +Fixed a small memory leak in text area and treeview. +Fixed OK button text getting corrupted by the new Flu_Button. +RequestFont() dialog should now be modal. +Another set of markcw's Fl_Help_View fixes. +1.30 Release +Implemented the FLU Tree Browser to replace the old list-box based treeview. +Increased clipping stack length in Fl_Rect.cxx to suppress warnings when running MaxIDE. +Replaced Fl_Button and Fl_Return_Button with Flu_Button and Flu_Return_Button. +Some more Fl_Help_View fixes from markcw. +1.29 Release +Fixed an undo bug in IDE by getting FLTK to mimic Win32/Cocoa textarea event behaviour more closely. +Dropped in the FLU file requester to replace the default FLTK one. +Some more of markcw's Fl_Help_View.cxx fixes. +Copied FLU source into FLTKMaxGUI folder. +1.28 Release +Added Fl_Multi_List handling code. +Corrected logic error that was allowing only left-mouse clicks to pass through to widgets. +Added error handler to fl_read_image.cxx to catch XGetImage exceptions and handle them safely. +1.27 Release +Added EVENT_GADGETMENU for tabbers. +Improved layout of PANEL_GROUP. +Added the latest set of markcw's Fl_Help_View.cxx fixes. +1.26 Release +Changed the status-bar border so that it looks more like one. +BUTTON_DEFAULT now uses Fl_Return_Button instead. +Fixed strange EventX/EventY coords in EVENT_WINDOWMOVE and EVENT_WINDOWSIZE. +Done some work cleaning up EVENT_GADGETSELECT generation by textareas. +Added CharX() and CharY() methods. +1.25 Release +Windows are now extending Fl_Double_Buffer to reduce random drawing artifacts. +Child windows should now stay on top, but behaviour still isn't exactly the same as Win32 or Cocoa. +Default message box font is now set to match other fonts. +Added clip_children() calls to Fl_Group based widgets. +Added some more of markcw's Fl_Help_View.cxx fixes. +Changed menu appearance and fixed label SetGadgetFont() redraw problems. +Changed default font size for FLTK to size 12 (in Fl_Widget.cxx). +Tidied up RequestFont() dialog layout and positioning. +Added standardized FLTK LookupGuiFont() handling. +Added support for TEXTAREA_WORDWRAP flag. +Added Fl::get_system_colors() to flReset() so that FLTK looks a bit more like the other apps. +Hacked in an editable combobox, but no EVENT_GADGETSELECT yet. +Added markcw's Fl_Help_View.cxx tweaks - thanks Mark! +1.24 Release +Fixed FL timers and therefore tooltips. +EventExtra() now contains the selected item's extra object for tabbers. +All right-clicks are ignored internally in FL_TEXTEDITORs. +Added SetMaxWindowSize() support. +Found and fixed glibc error originating from flRedirectView() in fltkglue.cpp. +Swapped Fl_Select_Browser with Fl_Hold_Browser so that highlight remains after mouse button is released. +Added EVENT_GADGETMENU for treeviews. +Hacked Fl_X.cxx to fix file drag n' drop support. +Added alpha-support for pixmaps on panels. +Added tab text alignment in the status bar similar to Win32, GTK and Cocoa. +Added support for windows without the WINDOW_TITLEBAR flag. +Added support for the TEXTFORMAT_BOLD and TEXTFORMAT_ITALIC flags in Text Areas. +Fixed EVENT_GADGETACTION on text-areas/text-fields. +Fixed gadget filter key codes, so that the tab key sends the correct data. +Fixed (somewhat) active panel events and attempted to eliminate double firing. +Imporoved toolbars. +Switched to GTK+ FLTK theme, and removed black tabs and yellow highlighting. +Fixed a glibc error in Fl_Text_Display.cxx. +Fixed Fl_HelpView image freeing crash with broken_image substitute. +Changed Fl_Panel so that it uses FL_NO_BOX, and fixed XGetImage crash in Fl_x.cxx +Swapped out source code for FLTK 1.1.9. +1.23 Release +Removed Fl_Text_Editor.cxx right mouse-button handling that was clearing selection. +Added new BUTTON_PUSH support for radio/checkboxes. +1.22 Release +Added Class() method for new GadgetClass() function. +1.21 Release +Removed pixmap field from TFLIconStrip that was conflicting with field in inherited TIconStrip. +1.20 Release +Fixed SetPanelColor not redrawing +1.19 Release +Fixed SetPanelPixmap panel,Null crash +1.18 Release +Fixed panel not clipping children +1.17 Release +Fixed crash removing last item of a Tabber +1.16 Release +Added GetText and SetText methods to TFLNode class +1.15 Release +Fixed broken shortcuts due to panel changes +1.14 Release +Fixed TFLMenu.GetText +Implemented KEY_REPEAT for canvas and active panels +1.13 Release +FLTKSystem OpenURL now uses new system.linux implementation +Added PopupMenu extra parameter support +1.12 Release +Added Brucey's GADGETLOSTFOCUS tweak +1.11 Release +ListBox now fires GADGETSELECT, GADGETACTION and GADGETMENU events +Fixed SetGadgetText for checkboxes and radiobuttons courtesy Byteemoz +1.10 Release +Initial OpenURL support for fltksystem using firefox - remote +Initial MinimizeWindow support +1.09 Release +Fixed radio buttons to exclude others in group +Fixed TFLWidget.kids usage +Fixed FreeGadget flwindow +Fixed ClearGadgetItems combobox +Fixed RemoveGadgetItem combobox,index +Fixed ModifyGadgetItem combobox,index,label$,extra:Object +1.08 Release +Fixed EventX EventY reporting for canvas and panel events +1.07 Release +Fixed ClearListItems +Fixed some keyboard focus problems +Fixed case sensitive shortcut keys issue with fltk1.1.7 +Fixed Canvas depthbuffers +1.06 Release +Upgraded to fltk-1.1.7 +Fixed GadgetHidden() +Initial support code added for WINDOW_CHILD +Fixed implementation of ActiveGadget +1.05 Release +Fixed MouseEnter and MouseLeave for Panel / Canvas children +Fixed SelectGadgetItem not generating event for ListBoxes +Fixed font support for TextField gadgets +Fixed EventExtra reporting in ListBox events +1.04 Release +Removed RuntimeError from TFLSystem.OpenURL +1.02 Release +Fixed up mouse events for active panels and canvas gadgets +1.01 Release +Added Query(QUERY_FLWIDGET) and Query(QUERY_FLWIDGET_CLIENT) diff --git a/mod/maxgui.mod/localization.mod/doc/createlanguage.bmx b/mod/maxgui.mod/localization.mod/doc/createlanguage.bmx new file mode 100644 index 0000000..2a38c8c --- /dev/null +++ b/mod/maxgui.mod/localization.mod/doc/createlanguage.bmx @@ -0,0 +1,47 @@ +' createlanguage.bmx + +Strict + +Import MaxGUI.Drivers + +' Enable the localization engine, and automatically localize gadgets when they are created +SetLocalizationMode(LOCALIZATION_ON|LOCALIZATION_OVERRIDE) + +Global window:TGadget = CreateWindow("{{window_title}}",100,100,320,240,Null,WINDOW_TITLEBAR|WINDOW_STATUS) + + Global btnEnglish:TGadget = CreateButton("{{btn_english}}",5,5,100,30,window,BUTTON_RADIO) + Global btnFrench:TGadget = CreateButton("{{btn_french}}",5,40,100,30,window,BUTTON_RADIO) + SetButtonState( btnEnglish, True ) + +' Create a new 'English' language +Global lngEnglish:TMaxGUILanguage = CreateLanguage("English (English)") + +DefineLanguageToken( lngEnglish, "window_title", "My Window" ) +DefineLanguageToken( lngEnglish, "btn_english", "English" ) +DefineLanguageToken( lngEnglish, "btn_french", "French" ) + +' Create a new 'French' language +Global lngFrench:TMaxGUILanguage = CreateLanguage("FranΓ§ais (French)") + +DefineLanguageToken( lngFrench, "window_title", "Ma FenΓͺtre" ) +DefineLanguageToken( lngFrench, "btn_english", "Anglais" ) +DefineLanguageToken( lngFrench, "btn_french", "FranΓ§ais" ) + +' Set the default language +SetLocalizationLanguage( lngEnglish ) + +Repeat + SetStatusText window, LanguageName( LocalizationLanguage() ) + Select WaitEvent() + Case EVENT_GADGETACTION + Select EventSource() + Case btnEnglish + SetLocalizationLanguage( lngEnglish ) + Case btnFrench + SetLocalizationLanguage( lngFrench ) + EndSelect + Case EVENT_APPTERMINATE, EVENT_WINDOWCLOSE + End + EndSelect +Forever + diff --git a/mod/maxgui.mod/localization.mod/doc/intro.bbdoc b/mod/maxgui.mod/localization.mod/doc/intro.bbdoc new file mode 100644 index 0000000..ceb2e48 --- /dev/null +++ b/mod/maxgui.mod/localization.mod/doc/intro.bbdoc @@ -0,0 +1,10 @@ +MaxGUI.Localization is a simple yet powerful localization engine that you can use to localize your applications. +Although the module is designed primarily for use with the MaxGUI toolkit, it is self-contained and so can be +imported into other BlitzMax games and applications separately, without the overhead of the rest of MaxGUI. + + +It is recommended that you read through the command set below to familiarize yourself with the module before +use. + +Whenever applicable, MaxGUI coders should use the #LocalizeGadget command in #{MaxGUI.MaxGUI} in favour of +#LocalizeString to ensure that gadgets are updated when the language or localization settings are changed. \ No newline at end of file diff --git a/mod/maxgui.mod/localization.mod/language.bmx b/mod/maxgui.mod/localization.mod/language.bmx new file mode 100644 index 0000000..b581457 --- /dev/null +++ b/mod/maxgui.mod/localization.mod/language.bmx @@ -0,0 +1,377 @@ +Strict + +Import Brl.Map +Import Brl.TextStream + +Rem +bbdoc: Create a new empty language to be used with MaxGUI's localization system. +about: This function is provided in case it is necessary to create a new language from scratch. +In the majority of cases, languages should instead be loaded from INI files using #LoadLanguage. + +Use the #DefineLanguageToken, #RemoveLanguageToken and #ClearLanguageTokens commands to add to and +modify the returned language. #SetLanguageName and #LanguageName may also be useful. + +See Also: #LoadLanguage, #SetLocalizationLanguage, #LocalizeString and #LocalizeGadget. +EndRem +Function CreateLanguage:TMaxGuiLanguage( name$ ) + Return New TMaxGuiLanguage.Create(name) +EndFunction + +Rem +bbdoc: Load a language from an INI text stream. +about: @{url} can be a filepath or any other readable #TStream object. + +The INI text stream must contain, at minimum, an INI section labelled '[LanguageDefinition]' and +a 'LanguageID' token which should be assigned an appropriate language name. + +A typical language INI file may look something like: + +{{ +[LanguageDefinition] + +LanguageID = FranΓ§ais (French) +LanguageVersion = v0.1 +LanguageAuthor = Various Sources + +; Toolbar Tips +tb_new = "Nouveau" +tb_open = "Ouvrir" +tb_close = "Fermer" +tb_save = "Enregistrer" +tb_cut = "Couper" +tb_copy = "Copier" +tb_paste = "Coller" +... +tb_home = "Page d'Accueil" +tb_back = "PrΓ©cΓ©dente" +tb_forward = "Suivante" + +; Tabs +tab_help = "Aide" +tab_output = "Sortie" +tab_locked:%1 = "construction:%1" + +; Time Format, by example: 13:09:02 +; h = 1 (12 hour clock) hh = 13 (24 hour clock) +; m = 9 (without leading 0) mm = 09 (including leading 0) +; s = 2 (without leading 0) ss = 02 (including leading 0) +; pp = {{pm}} (or '{{am}}' from 00:00 -> 11:59) + +longtime = hh:mm:ss pp +shorttime = {{longtime}} ; We want short time to be formatted exactly like {{longtime}} + +; Date Format, by example: 9th June 2009 +; d = 9 dd = 09 ddd = {{Wed}} dddd = {{Wednesday}} +; m = 6 mm = 06 mmm = {{Jun}} mmmm = {{June}} +; yy = 09 yyyy = 2009 oo = {{9th}} + +longdate = dddd oo mmmm dddd ; e.g. Wednesday 9th June 2009 +shortdate = dd/mm/yy ; e.g. 09/06/09 + +; AM / PM +am = AM +pm = PM + +; Ordinals + +1st = 1e +2nd = 2er +3rd = 3e +4th = 4e +; etc. + +; Days of the week + +Monday = "Lundi" +Mon = "Lun" +Tueday = "Mardi" +Tue = "Mar" +Wednesday = "Mercredi" +Wed = "Mer" +Thursday = "Jeudi" +Thu = "Jeu" +Friday = "Vendredi" +Fri = "Ven" +Saturday = "Samedi" +Sat = "Sam" +Sunday = "Dimanche" +Sun = "Dim" +}} + +Note how a semicolon ';' is used to mark the start of a line comment. + +INI files support the following escape sequence characters: + +[ @{INI Escape Sequence} | @{BlitzMax Equivalent} +* \\ | ~\Β  +* \r | ~~r +* \n | ~~n +* \t | ~~t +* \# | ~# +* \; | ; +* \: | : +] + +The bottom three escape sequences are only strictly required if the value of the INI key is not enclosed +in quotes. For example, the following definitions are expected to evaluate to the same string ( ~#;: ). + +{{ + MyToken = \#\;\: + MyToken = "#;:" + MyToken = "\#\;\:" +}} + +Use the #DefineLanguageToken, #RemoveLanguageToken and #ClearLanguageTokens commands to add to and +modify the returned language. #SetLanguageName and #LanguageName may also be useful. + +To construct a new language from scratch, use the #CreateLanguage command instead. + +See Also: #SetLocalizationLanguage, #SaveLanguage, #LocalizeString and #LocalizeGadget. +EndRem +Function LoadLanguage:TMaxGuiLanguage( url:Object ) + Return TMaxGuiLanguage.LoadLanguage(url) +EndFunction + +Rem +bbdoc: Saves a language as an INI section to the supplied stream. +about: @{url} can be a filepath or any other writable #TStream object. + +If @{url} is a string ending in "/" or "\", it is assumed that @{url} is a directory path and a default filename +will be appended like so: + +{{ +url = String(url) + LanguageName(language).Split(" ")[0] + ".language.ini" +}} + +WARNING: This command will automatically overwrite any existing file at the supplied/resulting file path. + +See Also: #LoadLanguage, #SetLocalizationLanguage, #LocalizeString and #LocalizeGadget. +EndRem +Function SaveLanguage( language:TMaxGuiLanguage, url:Object ) + If Not TStream(url) And (String(url).EndsWith("/") Or String(url).EndsWith("\")) Then + url = String(url) + language.GetName().Split(" ")[0] + ".language.ini" + EndIf + SaveText( language.Serialize(), url ) +EndFunction + +Rem +bbdoc: Redefine a language's name. +about: See Also: #LanguageName, #LoadLanguage, #CreateLanguage and #SetLocalizationLanguage. +EndRem +Function SetLanguageName( language:TMaxGuiLanguage, name$ ) + language.SetName(name) +EndFunction + +Rem +bbdoc: Returns a language's name. +about: See Also: #SetLanguageName, #LoadLanguage, #CreateLanguage and #SetLocalizationLanguage. +EndRem +Function LanguageName$( language:TMaxGuiLanguage ) + Return language.GetName() +EndFunction + +Rem +bbdoc: Define a language-specific value for a localization token. +about: Localization tokens are case insensitive, and if a token definition already exists in the language +the token value will be overwritten with this most recent @{value$}. + +See Also: #LoadLanguage, #CreateLanguage, #SaveLanguage and #SetLocalizationLanguage. +EndRem +Function DefineLanguageToken( language:TMaxGuiLanguage, token$, value$ ) + language.DefineToken(token,value) +EndFunction + +Rem +bbdoc: Look-up the value of a token for a specific language. +about: Localization tokens are case insensitive, and are either loaded in with the language or defined +using the #DefineLanguageToken command. + +If an explicit token definition is not found in the language, the @{token$} string is returned as it was passed. + +See Also: #LoadLanguage, #CreateLanguage, #SaveLanguage and #SetLocalizationLanguage. +EndRem +Function LanguageTokenDefinition$( language:TMaxGuiLanguage, token$ ) + Return language.LookupToken(token) +EndFunction + +Rem +bbdoc: Remove a token definition from a language. +about: The only token which cannot be removed is 'LanguageID' as every language requires this one token to be defined - +it defines the language name. If a matching token isn't already defined, then the command returns silently. + +Note: Localization tokens are case insensitive so the following commands are all requesting the same token to be removed: + +{{ +RemoveLanguageToken( language, "WelcomeMessage" ) +RemoveLanguageToken( language, "WELCOMEMESSAGE" ) +RemoveLanguageToken( language, "welcomemessage" ) +RemoveLanguageToken( language, "WeLcOmEmEsSaGe" ) +}} + +See Also: #ClearLanguageTokens, #DefineLanguageToken, #LoadLanguage, #CreateLanguage, #SaveLanguage and #SetLocalizationLanguage. +EndRem +Function RemoveLanguageToken( language:TMaxGuiLanguage, token$ ) + language.RemoveToken(token) +EndFunction + +Rem +bbdoc: Removes all the tokens defined in a language. +about: The only token which will not be removed is 'LanguageID' as every language requires this one token to be defined - +it defines the language name. + +See Also: #RemoveLanguageToken, #DefineLanguageToken, #LoadLanguage, #CreateLanguage, #SaveLanguage and #SetLocalizationLanguage. +EndRem +Function ClearLanguageTokens( language:TMaxGuiLanguage ) + language.ClearTokens() +EndFunction + +Type TMaxGuiLanguage + + ?Win32 + Const CARRIAGE_RETURN:String = "~r~n" + ?Not Win32 + Const CARRIAGE_RETURN:String = "~n" + ? + + Const SECTION_HEADER:String = "LanguageDefinition" + Const LANGUAGENAME_TOKEN:String = "LanguageId" + + Field strName:String = "Unknown Language" + Field mapDictionary:TMap = CreateMap() + + Method Create:TMaxGuiLanguage(name$) + SetName(name) + Return Self + EndMethod + + Method SetName(pName$) + DefineToken( LANGUAGENAME_TOKEN, pName ) + EndMethod + + Method GetName$() + Return strName + EndMethod + + Method DefineToken( pToken:String, pText:String ) + If pToken Then + If pToken = LANGUAGENAME_TOKEN Then strName = pText + MapInsert( mapDictionary, pToken.ToLower(), Prepare(pText) ) + EndIf + EndMethod + + Method RemoveToken( pToken:String ) + If pToken And pToken.ToLower() <> LANGUAGENAME_TOKEN.ToLower() Then MapRemove( mapDictionary, pToken.ToLower() ) + EndMethod + + Method LookupToken$(pToken$) + Local tmpValue$ = String(MapValueForKey( mapDictionary, pToken.ToLower() )) + If tmpValue Then Return Prepare(tmpValue) Else Return pToken + EndMethod + + Method ClearTokens() + ClearMap mapDictionary + SetName(GetName()) + EndMethod + + Method LoadEntriesFromText( text:String ) + + 'Very rough INI section parser + + Local tmpIndex:Int, tmpStage:Int = 0 + + For Local tmpLine:String = EachIn text.Split("~n") + + tmpStage = 0 + + 'Search for valid ';' comment + For tmpIndex = 0 Until tmpLine.length + Select tmpLine[tmpIndex] + Case Asc("~q");If tmpStage <> 0 Then tmpStage = 2 + Case Asc("=");If tmpStage = 0 Then tmpStage = 1 + Case Asc(";") + If tmpStage = 0 Or tmpStage = 1 Then + Exit + Else + If tmpLine[tmpIndex-1] <> Asc("\") Then tmpStage = 0-(tmpIndex) + EndIf + EndSelect + Next + + 'Strip the comment if ';' was the last character + If tmpStage < 0 Then tmpLine = tmpLine[..Abs(tmpStage)] + + 'Strip any whitespace + tmpLine = StripWhitespace(tmpLine[..tmpIndex]) + If Not tmpLine Then Continue + + 'Test for a new section header + If tmpLine[0] = "["[0] Then Exit + + 'Slow but easy code to handle any escape characters + tmpLine = tmpLine.Replace("\\","~0").Replace("\r","~r").Replace("\n","~n").Replace("\;",";").Replace("\#","#").Replace("\:",":").Replace("\t","~t").Replace("~0","\") + + 'Find the separator + tmpIndex = tmpLine.Find("=") + + 'If we have a key/value pair, define a new key in our dictionary. + If tmpIndex > 0 Then DefineToken( StripWhitespace(tmpLine[..tmpIndex],True), StripWhitespace(tmpLine[tmpIndex+1..],True) ) + Next + + EndMethod + + Method Serialize:String() + + Local tmpString:String = "["+SECTION_HEADER+"]" + CARRIAGE_RETURN + LANGUAGENAME_TOKEN + " = ~q" + GetName() + "~q" + CARRIAGE_RETURN + For Local tmpKey:String = EachIn MapKeys(mapDictionary) + If tmpKey <> LANGUAGENAME_TOKEN Then + tmpString:+tmpKey+" = ~q"+String(MapValueForKey(mapDictionary,tmpKey))+"~q"+CARRIAGE_RETURN + EndIf + Next + Return tmpString + + EndMethod + + Method Deserialize:TMaxGuiLanguage(pString$) + + Local tmpIndex:Int = pString.Find("["+SECTION_HEADER+"]") + If tmpIndex < 0 Then Return Null + + tmpIndex = pString.Find("~n",tmpIndex+SECTION_HEADER.length+2) + If tmpIndex < 0 Then Return Null + + If pString.ToLower().Find(LANGUAGENAME_TOKEN.ToLower(),tmpIndex+1) < 0 Then Return Null + + ClearMap mapDictionary + LoadEntriesFromText( pString[tmpIndex..] ) + + Return Self + EndMethod + + Function LoadLanguage:TMaxGUILanguage( stream:Object ) + + Return New TMaxGuiLanguage.Deserialize( LoadText(stream) ) + + EndFunction + + Function StripWhitespace:String( text$, pStripQuotes:Int = False ) + Local i:Int, j:Int + For i = 0 Until text.length + If text[i] = " "[0] Or text[i] = "~t"[0] Then Continue + Exit + Next + For j = text.length-1 To i Step -1 + If text[j] = " "[0] Or text[j] = "~t"[0] Or text[j] = "~r"[0] Then Continue + Exit + Next + If pStripQuotes And (j-i)>0 And text[i] = "~q"[0] And text[j] = "~q"[0] Then + i:+1;j:-1 + EndIf + Return text[i..j+1] + EndFunction + + Function Prepare$(text$) + If text="~0" Then Return "" ElseIf text="" Then Return "~0" + Return text + EndFunction + +EndType diff --git a/mod/maxgui.mod/localization.mod/localization.bmx b/mod/maxgui.mod/localization.mod/localization.bmx new file mode 100644 index 0000000..860bd85 --- /dev/null +++ b/mod/maxgui.mod/localization.mod/localization.bmx @@ -0,0 +1,420 @@ +Strict + +Rem +bbdoc: MaxGUI/Localization +End Rem +Module MaxGUI.Localization + +ModuleInfo "Version: 1.02" +ModuleInfo "Author: Seb Hollington" +ModuleInfo "License: zlib/libpng" + +Import BRL.System +Import "language.bmx" + +Const LOCALIZATION_OFF:Int = 0 +Const LOCALIZATION_ON:Int = 1 + +Rem +bbdoc: Returns the localized version of a string. +about: This function takes one parameter: @{localizationstring$}. + +A localization string is just like any other string except that any phrase enclosed in a double pair of +curly-braces is identified as a localization token. For example, the following examples all use valid +localization strings. + +{{ +LocalizeString("{{welcomemessage}}") 'Localization token(s): welcomemessage +LocalizeString("{{apptitlelabel}}: {{AppTitle}}") 'Localization token(s): apptitlelabel, AppTitle +LocalizeString("Current Time: {{CurrentTime}}") 'Localization token(s): CurrentTime +}} + +Localization tokens are case insensitive, and may be made up of any combination of alphanumeric +characters. Firstly, the token is tested to see if it is a reserved word. The following tokens +are currently reserved (although more maybe added in the future): + +[ @{Localization Token} | @{Token Will Be Replaced With...} +* AppDir | The value of the #AppDir global constant. +* AppFile | The value of the #AppFile global constant. +* AppTitle | The value of the #AppTitle global constant. +* LaunchDir | The value of the #LaunchDir global constant. +* GCMemAlloced | The value returned by the #GCMemAlloced function (at the moment the token is parsed). +] + +There are also some reserved date and time tokens which will display the current date and time (at the +moment of parsing) using any formats defined in the current language. If there are no matching formats +explicitly defined, the formats default to: + +[ @{Localization Token} | @{Default Format} | @{Sample Output} +* ShortTime | "hh:mm pp" | 02:36 {{pm}} +* LongTime | "hh:mm:ss" | 14:36:51 +* ShortDate | "dd/mm/yy" | 04/08/09 +* LongDate | "dddd oo mmmm yyyy" | {{Monday}} {{4th}} {{August}} 2009 +] + +Notice how any text-based time and date information is wrapped in curly braces. These tokens will be +localized, just like any other token, and so can be modified by adding a corresponding entry to the +localization language. + +This also demonstrates the ability of the localization parser to handle nested tokens. To prevent lock- +ups, the localization parser checks for cyclic token definitions, and if one is encountered the token will +be simply replaced with '!ERROR!' and the the offending localization string will be identified in the warning +message written to standard error. + +If and only if the localization token isn't reserved will the current localization language be queried. If +no localization language is selected, or if there is no matching token defined in the current language, the +token will simply be stripped of its curly braces in the returned string. Each language is required to have +at least one token defined: {{LanguageID}}. This should represent the language name e.g. 'FranΓ―ΒΏΒ½ais (French)'. + +%{NOTE: This function requires the LOCALIZATION_ON flag to be set (see #SetLocalizationMode) otherwise +the function will simply return @{localizationstring$} exactly as it was passed (including any curly braces).} + +See Also: #SetLocalizationMode, #LocalizationMode, #SetLocalizationLanguage and #LocalizationLanguage. +EndRem +Function LocalizeString$( localizationstring$ ) + Return TMaxGUILocalizationEngine.LocalizeString( localizationstring ) +EndFunction + + +Rem +bbdoc: Enable or disable the localization engine, and set other localization modes. +about: The mode can be set to: + +[ @{Constant} | @{Meaning} +* LOCALIZATION_OFF | Any localized gadgets will display their localizedtext$ as their actual text. +* LOCALIZATION_ON | Localized gadgets will use the current language to display their text. +] + +Either mode can be combined (btiwse OR'd) with LOCALIZATION_OVERRIDE, which will cause gadgets +to become automatically 'localized' when they are created, with any @{text$} parameters supplied +to the @{CreateGadget()} functions being interpreted as localization strings. + +If any window menus are localized, #UpdateWindowMenu may have to be called on all relevant windows for the text changes +to be visible. + +See Also: #LocalizationMode, #SetLocalizationLanguage, #LocalizationLanguage and #LocalizeGadget. +EndRem +Function SetLocalizationMode( mode:Int = LOCALIZATION_ON ) + _SetLocalizationMode(mode:Int) +EndFunction + +Global _SetLocalizationMode( mode:Int ) = TMaxGUILocalizationEngine.SetMode + +Rem +bbdoc: Returns the value previously set using #SetLocalizationMode. +about: The default value for a MaxGUI program is LOCALIZATION_OFF. + +See #SetLocalizationMode for valid modes, and their corresponding constants. +EndRem +Function LocalizationMode:Int() + Return TMaxGUILocalizationEngine.GetMode() +EndFunction + +Rem +bbdoc: Set the language to be used by MaxGUI's localization system. +about: Languages can be loaded from files/streams using #LoadLanguage and created from scratch using +#CreateLanguage. + +This function will automatically update the text of any gadget marked as 'localized' using #LocalizeGadget. + +If any window menus are localized, #UpdateWindowMenu may have to be called on all relevant windows for the text changes +to be visible. + +See Also: #LocalizationLanguage, #SetLocalizationMode, #LocalizationMode and #LocalizeString. +EndRem +Function SetLocalizationLanguage( language:TMaxGUILanguage ) + _SetLocalizationLanguage( language ) +EndFunction + +Global _SetLocalizationLanguage( language:TMaxGUILanguage ) = TMaxGUILocalizationEngine.SetLanguage + +Rem +bbdoc: Returns the current language used by MaxGUI's localization system. +about: Use the #DefineLanguageToken, #RemoveLanguageToken and #ClearLanguageTokens commands to add to and +modify the returned language. #SetLanguageName and #LanguageName may also be useful. + +about: See Also: #SetLocalizationLanguage, #SetLocalizationMode, #LocalizationMode and #LocalizeGadget. +EndRem +Function LocalizationLanguage:TMaxGUILanguage() + Return TMaxGUILocalizationEngine.GetLanguage() +EndFunction + +Private + +Type TMaxGUILocalizationEngine + + Global intLocalizationMode:Int = LOCALIZATION_OFF + Global _currentLanguage:TMaxGUILanguage + Global _localizeStack:String[] + + Method New() + Return Null + EndMethod + + ' Indirection allows MaxGUI.MaxGUI's TMaxGUIDriver to intercept function calls + ' and update gadgets if necessary (see bottom of maxgui.mod/driver.bmx). + Global SetMode( mode:Int ) = TMaxGUILocalizationEngine._SetMode + Global SetLanguage( language:TMaxGUILanguage ) = TMaxGUILocalizationEngine._SetLanguage + + Function _SetMode( mode:Int ) + intLocalizationMode = mode + EndFunction + + Function GetMode:Int() + Return intLocalizationMode + EndFunction + + Function GetLanguage:TMaxGUILanguage() + Return _currentLanguage + EndFunction + + Function _SetLanguage( language:TMaxGUILanguage ) + _currentLanguage = language + EndFunction + + Function LocalizeString:String( Text$ ) + + ' Only localize the string if the localization engine is turned on. + If (intLocalizationMode&LOCALIZATION_ON) Then + + ' Check for cyclic definitions by comparing localization string with those on the stack. + For Local i:Int = _localizeStack.length-1 To 0 Step -1 + If _localizeStack[i] = Text Then + WriteStderr "WARNING: Encountered cyclic localization string: ~q"+_localizeStack[i]+"~q.~n" + Return "!ERROR!" + EndIf + Next + + ' Add localization string to the stack. + _localizeStack:+[Text] + + Local tmpText:String + Local i:Int, tmpPrevChar:Int + Local tmpCount:Int, tmpOpenings:Int[Text.length/2] 'manages opening character index for nested tokens + + ' Start parsing for curly braces + While i < Text.length + Select Text[i] + Case Asc("{") + + 'If previous char was also an opening "{" then we're entering into a token + If tmpPrevChar = Text[i] Then + tmpOpenings[tmpCount] = i+1 + tmpCount:+1 + tmpPrevChar = 0 + + 'Otherwise update the value of the last char and move onto the next character. + Else + tmpPrevChar = Text[i] + EndIf + + Case Asc("}") + + 'If previous char was also a closing "}" then we're leaving a token, so interpret it. + If tmpPrevChar = Text[i] Then + + ' Retrieve the token text + tmpCount:-1 + tmpText = Text[tmpOpenings[tmpCount]..i-1] + + ' Check for reserved words or run it through the dictionary. + Select tmpText.ToLower() + + ' Keywords + Case "appfile";tmpText = AppFile + Case "appdir";tmpText = AppDir + Case "apptitle";tmpText = AppTitle + Case "launchdir";tmpText = LaunchDir + Case "gcmemalloced";tmpText = GCMemAlloced() + + ' Time parsing + Case "shorttime", "longtime" + ' Check if the current language defines its own time format for the token + If _currentLanguage Then tmpText = LocalizeString(_currentLanguage.LookupToken(tmpText)) + ' Either way, call LocalizeTime() and then localize the returned string (in case it contains tokens too). + tmpText = LocalizeString(LocalizedTime(tmpText)) + + ' Date parsing + Case "shortdate", "longdate" + ' Check if the current language defines its own date format for the token + If _currentLanguage Then tmpText = LocalizeString(_currentLanguage.LookupToken(tmpText)) + ' Either way, call LocalizeDate() and then localize the returned string (in case it contains tokens too). + tmpText = LocalizeString(LocalizedDate(tmpText)) + + ' Language definition + Default + If _currentLanguage Then + ' Lookup token using the current language, and localize the returned string (in case that contains tokens). + tmpText = LocalizeString(_currentLanguage.LookupToken(tmpText)) + EndIf + + EndSelect + + ' Substitute the localized text into the string in-place, to enable nested parsing to work. + Text = Text[..tmpOpenings[tmpCount]-2] + tmpText + Text[i+1..] + i:+(tmpText.length-(i+3-tmpOpenings[tmpCount])) + tmpPrevChar = 0 + + 'Otherwise update the value of the last char and move onto the next character. + Else + tmpPrevChar = Text[i] + EndIf + + Default + tmpPrevChar = 0 + EndSelect + i:+1 + Wend + + ' Remove localization string from stack as we're about to return + _localizeStack = _localizeStack[.._localizeStack.length-1] + + EndIf + + ' Return the localized text. + Return Text + + EndFunction + + Function LocalizedTime:String(pTimeFormat$) + Local i:Int = 0, tmpTokenCount:Int = 0, tmpToken$, tmpTime:String[] = CurrentTime().Split(":") + Select pTimeFormat.ToLower() + Case "shorttime";pTimeFormat = "hh:mm " + Case "longtime";pTimeFormat = "hh:mm:ss " + Default;pTimeFormat:+" " + EndSelect + While i < pTimeFormat.length + + If tmpTokenCount And (pTimeFormat[i-1] <> pTimeFormat[i]) Then + tmpToken = Null + Select pTimeFormat[i-1] + Case Asc("h") + Select tmpTokenCount + Case 1;tmpToken = Int(tmpTime[0]) Mod 12 + Case 2;tmpToken = Int(tmpTime[0]) + EndSelect + Case Asc("m") + Select tmpTokenCount + Case 1;tmpToken = Int(tmpTime[1]) + Case 2;tmpToken = tmpTime[1] + EndSelect + Case Asc("s") + Select tmpTokenCount + Case 1;tmpToken = Int(tmpTime[2]) + Case 2;tmpToken = tmpTime[2] + EndSelect + Case Asc("p") + If tmpTokenCount = 2 Then + If tmpTime[0] < 12 Then tmpToken = "{{am}}" Else tmpToken = "{{pm}}" + EndIf + EndSelect + If tmpToken + pTimeFormat = pTimeFormat[..(i-tmpTokenCount)] + tmpToken + pTimeFormat[i..] + i:+tmpToken.length-tmpTokenCount + EndIf + tmpTokenCount = 0 + EndIf + + Select pTimeFormat[i] + Case "h"[0],"m"[0],"s"[0],"p"[0] + tmpTokenCount:+1 + Default + tmpTokenCount = 0 + EndSelect + + i:+1 + + Wend + Return pTimeFormat[..pTimeFormat.length-1] + EndFunction + + Function LocalizedDate:String(pDateFormat$) + Local i:Int = 0, tmpTokenCount:Int = 0, tmpToken$, tmpDate:String[] = CurrentDate().Split(" ") + Select pDateFormat.ToLower() + Case "shortdate";pDateFormat= "dd/mm/yy " + Case "longdate";pDateFormat = "dddd oo mmmm yyyy " + Default;pDateFormat:+" " + EndSelect + While i < pDateFormat.length + + If tmpTokenCount And (pDateFormat[i-1] <> pDateFormat[i]) Then + tmpToken = Null + Select pDateFormat[i-1] + Case Asc("d") + Select tmpTokenCount + Case 1;tmpToken = Int(tmpDate[0]) + Case 2;tmpToken = tmpDate[0] + Case 3,4 + Local tmpDayAsInt:Int = DayOfTheWeek(Int(tmpDate[0]),_MonthAsNumber(tmpDate[1]),Int(tmpDate[2])) + If tmpTokenCount = 3 Then tmpToken = "{{"+_shortDays[tmpDayAsInt]+"}}" Else tmpToken = "{{"+_fullDays[tmpDayAsInt]+"}}" + EndSelect + Case Asc("m") + Select tmpTokenCount + Case 1,2 + Local tmpMonth:Int = _MonthAsNumber(tmpDate[1]) + If tmpTokenCount = 1 And tmpMonth < 10 Then tmpToken = " " + tmpMonth Else tmpToken = tmpMonth + Case 3;tmpToken = "{{"+tmpDate[1]+"}}" + Case 4;tmpToken = "{{" + _fullMonths[_MonthAsNumber(tmpDate[1])] + "}}" + EndSelect + Case Asc("y") + Select tmpTokenCount + Case 2;tmpToken = tmpDate[2][tmpDate.length-2..] + Case 4;tmpToken = tmpDate[2] + EndSelect + Case Asc("o") + If tmpTokenCount = 2 Then + Select Int(tmpDate[0]) + Case 1,21,31;tmpToken = "{{" + Int(tmpDate[0]) + "st}}" + Case 2,22;tmpToken = "{{" + Int(tmpDate[0]) + "nd}}" + Case 3,23;tmpToken = "{{" + Int(tmpDate[0]) + "rd}}" + Default;tmpToken = "{{" + Int(tmpDate[0]) + "th}}" + EndSelect + EndIf + EndSelect + If tmpToken + pDateFormat = pDateFormat[..(i-tmpTokenCount)] + tmpToken + pDateFormat[i..] + i:+tmpToken.length-tmpTokenCount + EndIf + tmpTokenCount = 0 + EndIf + + Select pDateFormat[i] + Case Asc("d"),Asc("m"),Asc("y"),Asc("o") + tmpTokenCount:+1 + Default + tmpTokenCount = 0 + EndSelect + + i:+1 + Wend + Return pDateFormat[..pDateFormat.length-1] + EndFunction + + Global _fullMonths:String[] = ["", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"] + Global _shortDays:String[] = ["Mon","Tue","Wed","Thu","Fri","Sat","Sun"] + Global _fullDays:String[] = ["Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"] + + Function _MonthAsNumber:Int(month$) + Select month.ToLower() + Case "jan";Return 1 + Case "feb";Return 2 + Case "mar";Return 3 + Case "apr";Return 4 + Case "may";Return 5 + Case "jun";Return 6 + Case "jul";Return 7 + Case "aug";Return 8 + Case "sep";Return 9 + Case "oct";Return 10 + Case "nov";Return 11 + Case "dec";Return 12 + EndSelect + RuntimeError "Unrecognised month: ~q" + month + "~q" + EndFunction + + Function DayOfTheWeek:Int(Day:Int, Month:Int, Year:Int) + Local Jt:Float = Float(367 * Year - ((7 * (Year + 5001 + ((Month - 9) / 7))) / 4) + ((275 * Month) / 9) + Day + 1729777)+1.5 + Return (jt Mod 7) + End Function + +EndType diff --git a/mod/maxgui.mod/localization.mod/version.txt b/mod/maxgui.mod/localization.mod/version.txt new file mode 100644 index 0000000..3a7e9ca --- /dev/null +++ b/mod/maxgui.mod/localization.mod/version.txt @@ -0,0 +1,8 @@ +1.02 Release +Fixed date ordinals so that entire term is a token. +1.01 Release +Added a CreateLanguage() example. +Added INI file escape sequence info to LoadLanguage() docs. +Fixed semicolon INI escape sequence bug. +1.00 Release +Initial release. diff --git a/mod/maxgui.mod/maxgui.mod/doc/canvasbeginpaint.bmx b/mod/maxgui.mod/maxgui.mod/doc/canvasbeginpaint.bmx new file mode 100644 index 0000000..07b2d4a --- /dev/null +++ b/mod/maxgui.mod/maxgui.mod/doc/canvasbeginpaint.bmx @@ -0,0 +1,36 @@ +' canvasbeginpaint.bmx + +Strict + +Import MaxGui.Drivers + +AppTitle = "Canvas Painter Example" + +Local window:TGadget = CreateWindow(AppTitle,50,50,200,200) + + ' create a canvas that occupies entire window client area + + Local canvas:TGadget = CreateCanvas(0,0,ClientWidth(window),ClientHeight(window),window) + SetGadgetLayout canvas, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED + +' create a timer as our single event source + +Local timer:TTimer = CreateTimer(50) + +Repeat + Select WaitEvent() + Case EVENT_WINDOWCLOSE, EVENT_APPTERMINATE + End + Default + CanvasBeginPaint(canvas) + SetClsColor( 0, 255*Sin(MilliSecs()/5.0), 0 ) + Cls() + Flip() + EndSelect +Forever + +Function CanvasBeginPaint(canvas:TGadget) + SetGraphics CanvasGraphics(canvas) + SetVirtualResolution ClientWidth(canvas), ClientHeight(canvas) + SetViewport 0, 0, ClientWidth(canvas), ClientHeight(canvas) +End Function diff --git a/mod/maxgui.mod/maxgui.mod/doc/createbutton.bmx b/mod/maxgui.mod/maxgui.mod/doc/createbutton.bmx new file mode 100644 index 0000000..780d35b --- /dev/null +++ b/mod/maxgui.mod/maxgui.mod/doc/createbutton.bmx @@ -0,0 +1,38 @@ +' createbutton.bmx + +Import MaxGui.Drivers + +Strict + +Global window:TGadget = CreateWindow("MaxGUI Buttons",40,40,400,330,Null,WINDOW_TITLEBAR|WINDOW_CLIENTCOORDS) + CreateButton("Std. Button",10,10,120,30,window,BUTTON_PUSH) + CreateButton("OK Button",140,10,120,30,window,BUTTON_OK) + CreateButton("Cancel Button",270,10,120,30,window,BUTTON_CANCEL) + +Global panel:TGadget[4] + panel[0]=CreatePanel(10,50,380,60,window,PANEL_GROUP,"Checkbox") + FillPanelWithButtons(panel[0], BUTTON_CHECKBOX, "Checkbox") + panel[1]=CreatePanel(10,120,380,60,window,PANEL_GROUP,"Checkbox (with Push Button Style)") + FillPanelWithButtons(panel[1], BUTTON_CHECKBOX|BUTTON_PUSH, "Toggle") + panel[2]=CreatePanel(10,190,380,60,window,PANEL_GROUP,"Radio Buttons") + FillPanelWithButtons(panel[2], BUTTON_RADIO, "Option ") + panel[3]=CreatePanel(10,260,380,60,window,PANEL_GROUP,"Radio Buttons (with Push Button Style)") + FillPanelWithButtons(panel[3], BUTTON_RADIO|BUTTON_PUSH, "Option") + +Repeat + Select WaitEvent() + Case EVENT_WINDOWCLOSE, EVENT_APPTERMINATE + End + Case EVENT_GADGETACTION + Print "EVENT_GADGETACTION~n" + .. + "GadgetText(): ~q" + GadgetText(TGadget(EventSource())) + "~q ~t " + .. + "ButtonState(): "+ ButtonState(TGadget(EventSource())) + EndSelect +Forever + +Function FillPanelWithButtons( pPanel:TGadget, pStyle%, pText$ = "Button" ) + Local buttonwidth% = (pPanel.width-10)/3 + For Local i% = 0 Until 3 + CreateButton( pText + " " + (i+1), 5+(i*buttonwidth), 5, buttonwidth-10, 26, pPanel, pStyle ) + Next +EndFunction \ No newline at end of file diff --git a/mod/maxgui.mod/maxgui.mod/doc/createcanvas.bmx b/mod/maxgui.mod/maxgui.mod/doc/createcanvas.bmx new file mode 100644 index 0000000..dc70207 --- /dev/null +++ b/mod/maxgui.mod/maxgui.mod/doc/createcanvas.bmx @@ -0,0 +1,50 @@ +' createcanvas.bmx + +Import MaxGui.Drivers + +Strict + +Global GAME_WIDTH=320 +Global GAME_HEIGHT=240 + +' create a centered window with client size GAME_WIDTH,GAME_HEIGHT + +Local wx=(ClientWidth(Desktop())-GAME_WIDTH)/2 +Local wy=(ClientHeight(Desktop())-GAME_HEIGHT)/2 + +Local window:TGadget=CreateWindow("My Canvas",wx,wy,GAME_WIDTH,GAME_HEIGHT,Null,WINDOW_TITLEBAR|WINDOW_CLIENTCOORDS) + +' create a canvas for our game + +Local canvas:TGadget=CreateCanvas(0,0,320,240,window) + +' create an update timer + +CreateTimer 60 + +While WaitEvent() + Select EventID() + Case EVENT_TIMERTICK + RedrawGadget canvas + + Case EVENT_GADGETPAINT + SetGraphics CanvasGraphics(canvas) + SetOrigin 160,120 + SetLineWidth 5 + Cls + Local t=MilliSecs() + DrawLine 0,0,120*Cos(t),120*Sin(t) + DrawLine 0,0,80*Cos(t/60),80*Sin(t/60) + Flip + + Case EVENT_MOUSEMOVE + Print "MOVE!" + + Case EVENT_WINDOWCLOSE + FreeGadget canvas + End + + Case EVENT_APPTERMINATE + End + End Select +Wend diff --git a/mod/maxgui.mod/maxgui.mod/doc/createcombobox.bmx b/mod/maxgui.mod/maxgui.mod/doc/createcombobox.bmx new file mode 100644 index 0000000..2ed5ee5 --- /dev/null +++ b/mod/maxgui.mod/maxgui.mod/doc/createcombobox.bmx @@ -0,0 +1,51 @@ +' createcombobox.bmx + +Strict + +Import MaxGui.Drivers + +AppTitle = "ComboBox Style Example" + +Global window:TGadget = CreateWindow( AppTitle, 100, 100, 300, 200, Null, WINDOW_TITLEBAR|WINDOW_STATUS ) + + CreateLabel( "No Style (0): ", 5, 5, ClientWidth(window)-10, 24, window, LABEL_LEFT ) + Global stdComboBox:TGadget = CreateComboBox( 5, 29, ClientWidth(window)-10, 26, window, 0 ) + AddGadgetItem stdComboBox, "Short" + AddGadgetItem stdComboBox, "Medium" + AddGadgetItem stdComboBox, "Fat", True + AddGadgetItem stdComboBox, "Humungous" + + CreateLabel( "COMBOBOX_EDITABLE: ", 5, 59, ClientWidth(window)-10, 24, window, LABEL_LEFT ) + Global editcombobox:TGadget = CreateComboBox( 5, 83, ClientWidth(window)-10, 26, window, COMBOBOX_EDITABLE ) + AddGadgetItem editcombobox, "United Kingdom" + AddGadgetItem editcombobox, "United States", True + +Local tmpText$ + +Repeat + WaitEvent() + Print CurrentEvent.ToString() + Select EventID() + 'Combobox Event(s) + 'EventData() holds the index of the selected item (or -1 if no item is currently selected) + Case EVENT_GADGETACTION + Select EventSource() + Case stdComboBox + tmpText = "" + If EventData() > -1 Then + tmpText = GadgetItemText(TGadget(EventSource()), EventData()) + EndIf + SetStatusText window, "Weight chosen: " + tmpText + Case editComboBox + tmpText = "" + If EventData() > -1 Then + tmpText = GadgetItemText(TGadget(EventSource()), EventData()) + Else + tmpText = GadgetText(TGadget(EventSource())) + " [user text]" + EndIf + SetStatusText window, "Country chosen: " + tmpText + EndSelect + Case EVENT_WINDOWCLOSE, EVENT_APPTERMINATE + End + EndSelect +Forever diff --git a/mod/maxgui.mod/maxgui.mod/doc/createhtmlview.bmx b/mod/maxgui.mod/maxgui.mod/doc/createhtmlview.bmx new file mode 100644 index 0000000..8927147 --- /dev/null +++ b/mod/maxgui.mod/maxgui.mod/doc/createhtmlview.bmx @@ -0,0 +1,23 @@ +' createhtmlview.bmx + +Import MaxGui.Drivers + +Strict + +Local window:TGadget +Local htmlview:TGadget + +window=CreateWindow("My Window",30,20,600,440,,15|WINDOW_ACCEPTFILES) + +htmlview=CreateHTMLView(0,0,ClientWidth(window),ClientHeight(window),window) +SetGadgetLayout htmlview,1,1,1,1 + +HtmlViewGo htmlview,"www.blitzmax.com" + +While WaitEvent() + Print CurrentEvent.ToString() + Select EventID() + Case EVENT_WINDOWCLOSE + End + End Select +Wend diff --git a/mod/maxgui.mod/maxgui.mod/doc/createlabel.bmx b/mod/maxgui.mod/maxgui.mod/doc/createlabel.bmx new file mode 100644 index 0000000..2bf0f19 --- /dev/null +++ b/mod/maxgui.mod/maxgui.mod/doc/createlabel.bmx @@ -0,0 +1,17 @@ +' createlabel.bmx + +Import MaxGui.Drivers + +Strict + +Local window:TGadget + +window=CreateWindow("My Window",30,20,320,480) + +CreateLabel("A plain label",10,10,280,52,window) +CreateLabel("A label with LABEL_FRAME",10,80,280,60,window,LABEL_FRAME) +CreateLabel("A label with LABEL_SUNKENFRAME",10,150,280,60,window,LABEL_SUNKENFRAME) +CreateLabel("not applicable",10,220,280,54,window,LABEL_SEPARATOR) + +While WaitEvent()<>EVENT_WINDOWCLOSE +Wend diff --git a/mod/maxgui.mod/maxgui.mod/doc/createlistbox.bmx b/mod/maxgui.mod/maxgui.mod/doc/createlistbox.bmx new file mode 100644 index 0000000..142dab9 --- /dev/null +++ b/mod/maxgui.mod/maxgui.mod/doc/createlistbox.bmx @@ -0,0 +1,37 @@ +' createlistbox.bmx + +Strict + +Import MaxGui.Drivers + +AppTitle = "ListBox Example" + +Global window:TGadget = CreateWindow( AppTitle, 100, 100, 200, 200, Null, WINDOW_TITLEBAR|WINDOW_STATUS|WINDOW_RESIZABLE ) + + Global listbox:TGadget = CreateListBox( 0, 0, ClientWidth(window), ClientHeight(window), window ) + SetGadgetLayout listbox, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED + + SetGadgetIconStrip listbox, LoadIconStrip("toolbar.png") + + AddGadgetItem listbox, "New", False, 0, "Create something." + AddGadgetItem listbox, "Open", False, 1, "Open something." + AddGadgetItem listbox, "Save", False, 2, "Save something.", "Extra Item Object!" + AddGadgetItem listbox, "No Icon", False, -1, "This should not have an icon set." + + +SelectGadgetItem listbox, 2 + +While WaitEvent() + Print CurrentEvent.ToString() + Select EventID() + Case EVENT_WINDOWCLOSE, EVENT_APPTERMINATE;End + 'ListBox Event(s) + 'EventData() holds the index of the corresponding listbox item. + Case EVENT_GADGETSELECT + SetStatusText window, "Selected Item Index: " + EventData() + Case EVENT_GADGETACTION + SetStatusText window, "Double-Clicked Item Index: " + EventData() + Case EVENT_GADGETMENU + SetStatusText window, "Right-Clicked Item Index: " + EventData() + End Select +Wend diff --git a/mod/maxgui.mod/maxgui.mod/doc/createmenu.bmx b/mod/maxgui.mod/maxgui.mod/doc/createmenu.bmx new file mode 100644 index 0000000..a5e3af8 --- /dev/null +++ b/mod/maxgui.mod/maxgui.mod/doc/createmenu.bmx @@ -0,0 +1,58 @@ +' createmenu.bmx + +Import MaxGui.Drivers + +Strict + +Local window:TGadget +Local filemenu:TGadget +Local editmenu:TGadget +Local helpmenu:TGadget + +Const MENU_NEW=101 +Const MENU_OPEN=102 +Const MENU_SAVE=103 +Const MENU_CLOSE=104 +Const MENU_EXIT=105 + +Const MENU_CUT=106 +Const MENU_COPY=107 +Const MENU_PASTE=108 + +Const MENU_ABOUT=109 + +window=CreateWindow("My Window",40,40,320,240) + +filemenu=CreateMenu("&File",0,WindowMenu(window)) +CreateMenu"&New",MENU_NEW,filemenu,KEY_N,MODIFIER_COMMAND +CreateMenu"&Open",MENU_OPEN,filemenu,KEY_O,MODIFIER_COMMAND +CreateMenu"&Close",MENU_CLOSE,filemenu,KEY_W,MODIFIER_COMMAND +CreateMenu"",0,filemenu +CreateMenu"&Save",MENU_SAVE,filemenu,KEY_S,MODIFIER_COMMAND +CreateMenu"",0,filemenu +CreateMenu"E&xit",MENU_EXIT,filemenu,KEY_F4,MODIFIER_COMMAND + +editmenu=CreateMenu("&Edit",0,WindowMenu(window)) +CreateMenu "Cu&t",MENU_CUT,editmenu,KEY_X,MODIFIER_COMMAND +CreateMenu "&Copy",MENU_COPY,editmenu,KEY_C,MODIFIER_COMMAND +CreateMenu "&Paste",MENU_PASTE,editmenu,KEY_V,MODIFIER_COMMAND + +helpmenu=CreateMenu("&Help",0,WindowMenu(window)) +CreateMenu "&About",MENU_ABOUT,helpmenu + +UpdateWindowMenu window + +While True + WaitEvent + Select EventID() + Case EVENT_WINDOWCLOSE + End + Case EVENT_MENUACTION + Select EventData() + Case MENU_EXIT + End + Case MENU_ABOUT + Notify "Incrediabler~n(C)2005 Incredible Software" + End Select + End Select +Wend diff --git a/mod/maxgui.mod/maxgui.mod/doc/createpanel.bmx b/mod/maxgui.mod/maxgui.mod/doc/createpanel.bmx new file mode 100644 index 0000000..22d820b --- /dev/null +++ b/mod/maxgui.mod/maxgui.mod/doc/createpanel.bmx @@ -0,0 +1,34 @@ +' createpanel.bmx + +Strict + +Import MaxGui.Drivers + +AppTitle = "Panel Example" + +Local window:TGadget = CreateWindow( AppTitle, 100, 100, 440, 240, Null, WINDOW_TITLEBAR|WINDOW_CLIENTCOORDS|WINDOW_RESIZABLE ) + +' create an active panel that occupies entire window client area + +Local panel:TGadget = CreatePanel(0,0,ClientWidth(window),ClientHeight(window),window,PANEL_ACTIVE) +SetGadgetLayout panel, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED + +' and add to it a smaller green panel with a sunken edge + +Local panel2:TGadget = CreatePanel(10,10,200,200,panel,PANEL_ACTIVE|PANEL_SUNKEN) +SetGadgetColor(panel2,160,255,160) + +' and finally a group panel with a child button + +Local group:TGadget = CreatePanel(220,10,200,200,panel,PANEL_GROUP,"Group Label") +Local button:TGadget = CreateButton("Push Button",0,10,ClientWidth(group)-20,26,group) + + +Repeat + WaitEvent() + Print CurrentEvent.ToString() + Select EventID() + Case EVENT_WINDOWCLOSE, EVENT_APPTERMINATE + End + End Select +Forever diff --git a/mod/maxgui.mod/maxgui.mod/doc/createprogbar.bmx b/mod/maxgui.mod/maxgui.mod/doc/createprogbar.bmx new file mode 100644 index 0000000..2cd6870 --- /dev/null +++ b/mod/maxgui.mod/maxgui.mod/doc/createprogbar.bmx @@ -0,0 +1,24 @@ +' createprogbar.bmx + +Import MaxGui.Drivers + +Strict + +Local window:TGadget=CreateWindow("My Window",50,50,240,100,,WINDOW_TITLEBAR) + +Local progbar:TGadget=CreateProgBar(10,10,200,20,window) + +CreateLabel "Please Wait",10,40,200,20,window + +CreateTimer 10 + +While WaitEvent() + Select EventID() + Case EVENT_WINDOWCLOSE + End + Case EVENT_TIMERTICK + Local t=EventData() + If t=50 End + UpdateProgBar progbar,t/50.0 + End Select +Wend diff --git a/mod/maxgui.mod/maxgui.mod/doc/createslider.bmx b/mod/maxgui.mod/maxgui.mod/doc/createslider.bmx new file mode 100644 index 0000000..32397ee --- /dev/null +++ b/mod/maxgui.mod/maxgui.mod/doc/createslider.bmx @@ -0,0 +1,42 @@ +' createslider.bmx + +Import MaxGui.Drivers + +Strict + +Local window:TGadget=CreateWindow("My Window",0,0,240,240,,WINDOW_TITLEBAR) + +Local slider:TGadget[3] + +' standard vertical and horizontal scroll bars + +slider[0]=CreateSlider(10,10,16,100,window,SLIDER_VERTICAL) +slider[1]=CreateSlider(30,10,100,16,window,SLIDER_HORIZONTAL) + +' a horizontal trackbar + +slider[2]=CreateSlider(30,30,100,24,window,SLIDER_HORIZONTAL|SLIDER_TRACKBAR) + +' a row of vertical trackbars + +Local trackbar:TGadget[5] + +For Local i=0 To 4 + trackbar[i]=CreateSlider(30+i*20,50,16,60,window,SLIDER_VERTICAL|SLIDER_TRACKBAR) +Next + +' a single stepper + +Local stepper:TGadget +stepper=CreateSlider(10,120,24,24,window,SLIDER_STEPPER) + +SetSliderValue stepper,4 +Print SliderValue(stepper) + +While WaitEvent() + Print CurrentEvent.ToString() + Select EventID() + Case EVENT_WINDOWCLOSE + End + End Select +Wend diff --git a/mod/maxgui.mod/maxgui.mod/doc/createtabber.bmx b/mod/maxgui.mod/maxgui.mod/doc/createtabber.bmx new file mode 100644 index 0000000..ee0b6e1 --- /dev/null +++ b/mod/maxgui.mod/maxgui.mod/doc/createtabber.bmx @@ -0,0 +1,65 @@ +' createtabber.bmx + +Import MaxGui.Drivers + +Strict + +Local window:TGadget +Local tabber:TGadget +Local document:TGadget[3] +Local currentdocument:TGadget + +' CreateDocument creates a hidden panel that fills entire tabber client area + +Function CreateDocument:TGadget(tabber:TGadget) + Local panel:TGadget + panel=CreatePanel(0,0,ClientWidth(tabber),ClientHeight(tabber),tabber) + SetGadgetLayout panel,1,1,1,1 + HideGadget panel + Return panel +End Function + +' create a default window with a tabber gadget that fills entire client area + +window=CreateWindow("My Window",30,20,400,300) + +tabber=CreateTabber(0,0,ClientWidth(window),ClientHeight(window),window) +SetGadgetLayout tabber,1,1,1,1 + +' add three items and corresponding document panels to the tabber + +AddGadgetItem tabber,"Document 0",False,-1,"" +AddGadgetItem tabber,"Document 1",False,-1,"Tabber Tip 1" +AddGadgetItem tabber,"Document 2",False,-1,"tips 4 2" + +document[0]=CreateDocument(tabber) +document[1]=CreateDocument(tabber) +document[2]=CreateDocument(tabber) + +SetPanelColor document[0],255,200,200 +SetPanelColor document[1],200,255,200 +SetPanelColor document[2],200,200,255 + +' our documents start off hidden so make first one current and show + +currentdocument=document[0] +ShowGadget currentdocument + +' standard message loop with special tabber EVENT_GADGETACTION and EVENT_GADGETMENU handling + +While WaitEvent() + Select EventID() + Case EVENT_GADGETACTION + If EventSource()=tabber + HideGadget currentdocument + currentdocument=document[EventData()] + ShowGadget currentdocument + EndIf + Case EVENT_GADGETMENU + If EventSource()=tabber + Notify "You right clicked the tab with index " + EventData() + "!" + EndIf + Case EVENT_WINDOWCLOSE + End + End Select +Wend diff --git a/mod/maxgui.mod/maxgui.mod/doc/createtextarea.bmx b/mod/maxgui.mod/maxgui.mod/doc/createtextarea.bmx new file mode 100644 index 0000000..ce08bc2 --- /dev/null +++ b/mod/maxgui.mod/maxgui.mod/doc/createtextarea.bmx @@ -0,0 +1,29 @@ +' createtextarea.bmx + +Import MaxGui.Drivers + +Strict + +Global window:TGadget = CreateWindow( "My Window", 130, 20, 200, 200 ) + +Global textarea:TGadget = CreateTextArea( 0, 0, ClientWidth(window), ClientHeight(window), window ) + SetGadgetLayout( textarea, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED ) + SetGadgetText( textarea, "A TextArea gadget. :-)~n~nOne line...~n...and then another!") + ActivateGadget( textarea ) + +' Select the entire third (index: 2 [base-0]) line. +SelectTextAreaText( textarea, 2, 1, TEXTAREA_LINES ) + +' Output the properties of the current text selection (should be 1, 1 as set above). +Print "TextAreaCursor(): " + TextAreaCursor( textarea, TEXTAREA_LINES ) +Print "TextAreaSelLen(): " + TextAreaSelLen( textarea, TEXTAREA_LINES ) + +While WaitEvent() + Print CurrentEvent.ToString() + Select EventID() + Case EVENT_WINDOWCLOSE + End + Case EVENT_APPTERMINATE + End + End Select +Wend diff --git a/mod/maxgui.mod/maxgui.mod/doc/createtextfield.bmx b/mod/maxgui.mod/maxgui.mod/doc/createtextfield.bmx new file mode 100644 index 0000000..ba8d01e --- /dev/null +++ b/mod/maxgui.mod/maxgui.mod/doc/createtextfield.bmx @@ -0,0 +1,35 @@ +' createtextfield.bmx + +Import MaxGui.Drivers + +Strict + +Local window:TGadget +Local textfield:TGadget +Local button:TGadget + +window=CreateWindow("My Window",30,20,320,200) + +textfield=CreateTextField(4,4,120,22,window) +SetGadgetText( textfield,"A textfield gadget" ) + +' we need an OK button to catch return key + +button=CreateButton("OK",130,4,80,24,window,BUTTON_OK) + +ActivateGadget textfield + +While WaitEvent() + Print CurrentEvent.ToString() + Select EventID() + Case EVENT_GADGETACTION + Select EventSource() + Case textfield + Print "textfield updated" + Case button + Print "return key / OK button pressed" + End Select + Case EVENT_WINDOWCLOSE + End + End Select +Wend diff --git a/mod/maxgui.mod/maxgui.mod/doc/createtimer.bmx b/mod/maxgui.mod/maxgui.mod/doc/createtimer.bmx new file mode 100644 index 0000000..82d5c80 --- /dev/null +++ b/mod/maxgui.mod/maxgui.mod/doc/createtimer.bmx @@ -0,0 +1,23 @@ +' createtimer.bmx + +Import MaxGui.Drivers + +Strict + +Local window:TGadget +Local label:TGadget + +window=CreateWindow("Timer Test",40,40,160,64,Null,WINDOW_TITLEBAR) +label=CreateLabel("",10,10,200,20,window) + +CreateTimer(1) + +While True + WaitEvent + Select EventID() + Case EVENT_WINDOWCLOSE + End + Case EVENT_TIMERTICK + SetGadgetText label,CurrentTime() + End Select +Wend diff --git a/mod/maxgui.mod/maxgui.mod/doc/createtoolbar.bmx b/mod/maxgui.mod/maxgui.mod/doc/createtoolbar.bmx new file mode 100644 index 0000000..d3c2b92 --- /dev/null +++ b/mod/maxgui.mod/maxgui.mod/doc/createtoolbar.bmx @@ -0,0 +1,36 @@ +' createtoolbar.bmx + +Strict + +Import MaxGui.Drivers + +AppTitle = "ToolBar Example" + +Global window:TGadget = CreateWindow( AppTitle, 100, 100, 400, 32, Null, WINDOW_TITLEBAR|WINDOW_STATUS|WINDOW_RESIZABLE|WINDOW_CLIENTCOORDS ) + + Global toolbar:TGadget = CreateToolBar( "toolbar.png", 0, 0, 0, 0, window ) + DisableGadgetItem toolbar, 2 + + SetToolBarTips toolbar, ["New", "Open", "Save should be disabled."] + + AddGadgetItem toolbar, "", 0, GADGETICON_SEPARATOR 'Add a separator. + AddGadgetItem toolbar, "Toggle", GADGETITEM_TOGGLE, 2, "This toggle button should change to a light bulb when clicked." + + Global button:TGadget = CreateButton( "Show/Hide Toolbar", 2, 2, 180, 28, window ) + SetGadgetLayout button, EDGE_ALIGNED, EDGE_CENTERED, EDGE_ALIGNED, EDGE_CENTERED + +While WaitEvent() + Print CurrentEvent.ToString() + Select EventID() + Case EVENT_WINDOWCLOSE, EVENT_APPTERMINATE;End + 'ToolBar Event(s) + 'EventData() holds the index of the toolbar item clicked. + Case EVENT_GADGETACTION + Select EventSource() + Case button + If GadgetHidden(toolbar) Then ShowGadget(toolbar) Else HideGadget(toolbar) + Case toolbar + SetStatusText window, "Toolbar Item Clicked: " + EventData() + EndSelect + End Select +Wend diff --git a/mod/maxgui.mod/maxgui.mod/doc/createtreeview.bmx b/mod/maxgui.mod/maxgui.mod/doc/createtreeview.bmx new file mode 100644 index 0000000..9ea3bc3 --- /dev/null +++ b/mod/maxgui.mod/maxgui.mod/doc/createtreeview.bmx @@ -0,0 +1,30 @@ +' createtreeview.bmx + +Import MaxGui.Drivers + +Strict + +Local window:TGadget=CreateWindow("My Window",50,50,240,240,Null,WINDOW_TITLEBAR|WINDOW_CLIENTCOORDS) +Local treeview:TGadget=CreateTreeView(5,5,ClientWidth(window)-10,ClientHeight(window)-10,window) + +SetGadgetLayout treeview, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED + +Local root:TGadget=TreeViewRoot(treeview) + +Local help:TGadget=AddTreeViewNode("Help",root) +AddTreeViewNode "Topic 1",help +AddTreeViewNode "Topic 2",help +AddTreeViewNode "Topic 3",help + +Local projects:TGadget=AddTreeViewNode("Projects",root) +AddTreeViewNode("Sub Project",AddTreeViewNode("Project 1",projects)) +AddTreeViewNode("Project 2",projects) +AddTreeViewNode("Project 3",projects) + +While WaitEvent() + Print CurrentEvent.ToString() + Select EventID() + Case EVENT_WINDOWCLOSE + End + End Select +Wend diff --git a/mod/maxgui.mod/maxgui.mod/doc/createwindow.bmx b/mod/maxgui.mod/maxgui.mod/doc/createwindow.bmx new file mode 100644 index 0000000..15a9993 --- /dev/null +++ b/mod/maxgui.mod/maxgui.mod/doc/createwindow.bmx @@ -0,0 +1,36 @@ +' createwindow.bmx + +Import MaxGui.Drivers + +Strict + +AppTitle = "CreateWindow() Example" + +Global FLAGS:Int + +' Comment/uncomment any of the following lines to experiment with the different styles. + +FLAGS:| WINDOW_TITLEBAR +FLAGS:| WINDOW_RESIZABLE +FLAGS:| WINDOW_MENU +FLAGS:| WINDOW_STATUS +FLAGS:| WINDOW_CLIENTCOORDS +'FLAGS:| WINDOW_HIDDEN +FLAGS:| WINDOW_ACCEPTFILES +'FLAGS:| WINDOW_TOOL +'FLAGS:| WINDOW_CENTER + +Local window:TGadget = CreateWindow( AppTitle, 100, 100, 320, 240, Null, FLAGS ) + +If (FLAGS & WINDOW_STATUS) Then + SetStatusText( window, "Left aligned~tCenter aligned~tRight aligned" ) +EndIf + +Repeat + WaitEvent() + Print CurrentEvent.ToString() + Select EventID() + Case EVENT_APPTERMINATE, EVENT_WINDOWCLOSE + End + End Select +Forever \ No newline at end of file diff --git a/mod/maxgui.mod/maxgui.mod/doc/fltkbuttons.png b/mod/maxgui.mod/maxgui.mod/doc/fltkbuttons.png new file mode 100644 index 0000000000000000000000000000000000000000..142d2db33ca31ab0d7b51b214b06576ff88374a7 GIT binary patch literal 1783 zcmV`oLH z62b@Z2LNiOd4g>|9pg2oFfwt#9G?;~G3LB8E5{#@ZM@k7UkC2`^sF&GK?erR@hQW; zr6R+vKzKv=ApW3yq)d{q6Cm-EhzoTdp-P|Uj%CfY9*9s0j=2$!73QP61UXuNEW`(1 zo~bZ$p39iEoXv-TovsO<82>n)gAsfXf6U`U)L;ubt$cLl1wLlXIlZe}F7bSDNyJBD z{jr=sBJt%hjmXcm$5swn?bKRQAF@leU{Lwkr5+JmRgfDFP7Q-1-Aj{m<)wtk&nk2w+qp zydiw>_a8f7#(Z_%0K44!19JGI#&ItJm<(>qmS<*B|g+7v6s?f5Kb} zDFT<5m))1=FMHwm6BS4aOslaY0^KK9C~&m@Dw4pG*&2bv{;O_lD}fV4pzyJ^+|$aB z_#@ckN^D;Q3Lohb-a4W9;{>FTFj4r}TJCA(#UJ~)U_^7_BVEE0yN+hI*4ePw;Qo?dYL2sxVyW1 ze0==b8;}y}q!1V0RWVGdK1=eci34`|l$5R1btfTLyOmcGcn?4A64$TNmv-HrFm#YUziN74YzP=8$!4esafbo16QUXD5 zjc$fZU?u{&XHA=$W~n_8+e|WR?(zuK`}4s@ziC>%A6#DIQwobe&WpSXA5-PLd~)%} zCL$PATliRB;!_HXKZ-x53h0whF8&y7^qZy?f1DTKia&}!&Z{EN%bVhlO++xLw)o@B z@L{&k))uVu>b0NI8v`GZ4ChY{TIIxFm6MFQb!wm>TU)T4SLg#)=mmTC?fsbY$Slbp zm<;?ET6(}{2KZHP*yX#S__iy(OKPmGntJp$t$A|;I>oh*UEpEUFi#pL1NJlc|9A*w z_$*z#=9ZC2bvWSDKRI@XZ4KyjwxkTWakT!xe88vkU%3z>=0+xCH|py?D1v`$18(;` z?Wc0~*Xmul!YGNhq=YpTs(l&&Ux{x7N#@4WXp=VNw=$$Yik`lv?pEF{E@=Pd`&sGYPzOc z#V88j!3X}NanOQJx2_lCgWoSBKAbJpcpog5AlQ6F3-0m+P2tm>W8KHOQDH8nheu$c z&WH~NDT;PUDQPW1#NvauOY|U8?{vFmPQjB76sX2YGNMQ8)F=@O_2rNf;U0bER=Bn< zuNeG+z1v9%UwM4Sr$--uP4@HM)*~zdruw=(0`>l5@`2Oh>Gl3&d5KRctoP?1&l%i< Z{{WpHenbMJ_m}_x002ovPDHLkV1g=bddvU- literal 0 HcmV?d00001 diff --git a/mod/maxgui.mod/maxgui.mod/doc/fltkcombobox.png b/mod/maxgui.mod/maxgui.mod/doc/fltkcombobox.png new file mode 100644 index 0000000000000000000000000000000000000000..41f88aa65b9a042af46a8c13d4e77b155030b267 GIT binary patch literal 638 zcmV-^0)hRBP)|00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUz{7FPXRA@u(nXzt!Fbsz23-OwaJOU$QM@B}(aH@1uH^z<~yY@$p ze7?lVg^1{KZ9Jf0V&i=F`J(W4xm=p2xn8fhR>?u2ZQI@Lx~{`8d{oIspznJ?ZpLw( z=lQ!zP6A-PgWk3crM)amy@m+@QJNUg(=@$T$w|O~Mvq1&fty5*!%BYo=Lag2csK?$ zwP_YOmA5ojmF~2EsNs!DVC@Dpel*mZNaQ%IOlw%LXr(eCR#JRRGoX}E)%tg^lXt=5s{i|h2^depRqE7}E-X?`Tx6Q`YD(Q4JiRP@8l$kuQqzsRkzfyK79-Fl(PV@S0r*utz8T{5?iCMuUM1$P>-G<`_?!g+Yus1KL4XMV Y0$-#@h?cY{?f?J)07*qoM6N<$f=0_AsQ>@~ literal 0 HcmV?d00001 diff --git a/mod/maxgui.mod/maxgui.mod/doc/fltklistbox.png b/mod/maxgui.mod/maxgui.mod/doc/fltklistbox.png new file mode 100644 index 0000000000000000000000000000000000000000..4b3a2f20e7fe9563176023b1cfd20d6babdc430a GIT binary patch literal 1104 zcmV-W1h4yvP)Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBU#&PhZ;RCr$PoUxJ{Aq<9{#t-9{_TzY5c0G8vd2R49<}?C{ zAEC|eZA5eHJ)uP(5=a#MxL&Wv9`e7sv4ba|e9z*XUrlS49ePjH4wWqV3^(y!8&#q9clcBga{%?8_i zyBJAPPKC#^z{y#w)IIN>zB1ETN}vTPZF*=5Hb0G<(%|V+n=;IOFhL4MYT5fx-Gg!)U)L=8)F1&= zJV^b=r06LU%?W6hP-+zY80)(nP9<|J(N_~ej;PEss822|H?X2hMTT@#0=@^;F3h2? z-sn@Tj%}X#1*xw?UUovj<|RlulR}Ot`mwRRgj@90g|XsO`Z1R7s>?HJf5CxNP6+C3 zKq6(3UyBa?Zq$9~ECi__g%UvJ!l!~1N&uDX`_zsPd{IcBavCXC376e{=mWbE?vSeO z-1vFhauZ|8JZbeWC7i_{rNb<##-_??j=CHIP_vyBjZNv91uPS57C_x&EYL7_F_cuj zu7gJf^{Hk7)HG(Z1v5&D1qG|!n$A)aQK;cF;qEM;!YNX^Q-Gw{4*UIlDtnEx_eq!*lgLcOai)+nlnZH!WxAyDPUs9E=xVv4I@D8BL?dQngR9RDh)yO?h7g zpte3KP|@zif)qN%K`Kb01W>u~scBL)X|9i7Q1v^KLvwTktkrWx-)TZgNh!NBnjrOp zQx~)aWixE`5~t2K5&2rCPJ^YP8r%)_DW!I4)+JKy!V>+_lE_QmnH2L5sjxt*f5}G{ zdfy$YGbu^ksCo4o*M+NmLYcp25h}@#!a}2u>Rp#q*FqMdU3pMohoq1l*1OxT?E{?%6KNzNA>P=;~(e=QYhpg6{JuCs9g9|kU|Nda^X`!3MGKbg-@AC zrMm?u?{VC5_k11d>pstXn{HeXt6vbCZf8EE8+8MgjwvB}-8=mAvt?M(Y66*0YJUOq WN@UjJpF?N>0000&D4#k_9 zk^-(zSVPJ=uJ4;%&x?Fia^5}LC`6`4%wg~#S1hq!Be94U9)#|4Z@2lhK{W4Rv$p*N zJ$t=%|H{P2)L?9iTHR9UUc&)j`;WSWp!i?g8rORCwmyibCY$E@`iEL4`Fo>S;pX!L zTUneG+goBt={t_95Cn}~dnuEv)xUZGL%JrJU)97j;H-)LDJd=#_e0pI{ zf)vop6b&8*Ei_)Wlnp`_BYbj$r5J#fGwqhKkS;!nl$$^uSM+yv{PjWvcJpBETb$ zciKuoa@dQGZ2ZdjHcvz~OwkDgOK-wp6-Idg5moRVdW290%x1KTNcFGU2A>zb0nhN2 znBtkcyiuz;;x0z<-ZPoDoCIPjvAjRg?sEXbcezzObqD+W5w1jTX_-p$5Zk|npnn^> z*6hDMU;d=&T92Hbf}rihG9h-)Ex_T0$Q7XeNWR9QYID$2R`ee=r7c67Gw^=4=yWCb zmAeOz<0;tN03O1)^we0Lu*w_h*c7_Sm)I7ym!lfI?^P(da0GFQZ(ZO&i^*VNoPqt} zDjP?XWTF*4EHKPe4>32_!b^DOCh^)iRHqXlK?o&oHy07LFR);~JAt(Jb87lp$|JXv z{_M(cfp!`lR=9XQc3IX6-=?H0iuG^`-thJFv*9ilUv8`O{W(mR(q_D}DJg`)zzkQ$=+}MPwH1x2&#JYT3+R zXqJYpskLXtU2+A#(@Vxn@#27ncRhspx+iPVN6+9Th%s{KWi>;>1tyKo@EHYN9d!^L4a@#PK+-JX{ z33kCZX$fHs4dbFCy~%R5ZsW|iveo?sy~`~I=S@CWKJAH*

      Zi*T6+}1a6cS>(m(7 z)Q0x9MV)t|q{#a$QpT&CYHMo;GBv_l!r5X4<*-J7Pn6Z<>EGZxVUdL%GBZ%oSiy!H zuQy76`Jle1cy=1>lM0qPVg#g>+{Vh?Cu^n~Uc9!u%PM*JXMy#GfvC8ssHn<|jn8HiKJ`Ik$Gg;2=WOrrhn*mv-xMtw*Ht zgA2uj!Rw}Qq$RfENzzEMMVWQo_SSqC&%W4$)|uH3qfB*_RGcWhkd<$$;l*af>iUbL2sivJpjtF?xmBk-?)En31gBfBpc#%v2q^BH~CsmWSTzzqgG6u^lI$v3`> z;M=neCUV^8IdWzK*ehS+oqeY3{WLF*u70CIDY>x8{%Pg-sV`mJ=lqdg7=+g>s6_Uq z=S*YBne&i{b;C>7gt9CKi7~{p{dnjY(^C+)GxAlH{Y{=H&gNi5;!y0h5pqJnV^)~n z7LQ+FXnYLx&Br9@V7e2oa&eUWJUhUb@*XO!SG4OK*=^j|A01AEb=&e8yOSWQ`Sm=R z@MUAu4A&N3HdF&lRBC129}7OG^3NtxvbQY31AI;p?LPMdHTt5-cJ#!e2yPNAV|_y* zW^!O6iZ*zc1vnqeIMAaUXt_^DJQRc7|Cb|=l#6xwR^Zf2hFGenkD*^;qYF7hrUy|#^)-- z--lOP)jM7xZ~*lzdy{()lFOh?qg^NVnz`0A%2I0gAUk^ED76qkBFGT;MG|C13kR

      nV=2-efgEsi7^FJVfDC1 zrF8Q+Dt08>+IGr9skqNisHSEwI*A2GU10BJ=(J1OsWg671L zP=+o4jQ)3MKX@Bl&_P3Lrrv%XHY|HFh?)BU08dAGTEZevVJi;D)o^kOi6 zF)Z{CHs)411ze}Y+%0g${=$8@4}JS~PA|&a`PG7iCI6zI&SBHskk;*ryq-Z}ACy%g z@ldG`tZg!6OY;8Ixi@mz=c4R{cj6Ge)XMpH?pkX@0(u8EqTF_%Qd{zH zl3!=1kr{>(@@d?!nPTjNfZE(O-Aa5M%RH%J)d7qIVngKW>vTz_durncNZt43-Ah9+ z6@~A8&TL^4VO&Dcc$zEt{)-NIUDg{;F@9dV8g}y(;)K34*etN>K7ucr4e2sU#3sWw zUwUg0=Pc8ExP5|4PLAKguF6PYQTpZ2airiJ38Vg#uM(TZ=R}45oP;f{<0em&pwL2f z(yHka63NG}KbD99qe%+&nY?9frp0mBXaCYam)E$X>^NWGvf=a=lgQ4+f6?V_3c}ks z^O<;vdB;O@^|b1H%9ql6?%nwVKCfOR&kZQ1lieJW8^1xBx27@Vb$32UYf$Jj%0qU+cq{EEuQnBE(PY9 zPwSo-B+|cCU9kGT-~Ft3cS5{r#4C}H*BwhCD3}}+`Tm{ul>{ny^JYz4Kt|oQz4aiU z3rH{T>$EYP`f#pX$omvSN{l9J!;QGni!simTX(@!n2b68F%?Y~9@`dmR zmXE|^jdcMOGt*UopFqtfT)K>wQ1dR~0MNy+hTS-%)3kJO1){a8k&C*?;ctIEoEI|A zjMX2%Om#030hCx$Dv6x~YVeq!w;ZKO9Hhi>Qs{MDNo)ld{EO2t*jhpFdRUxEZs_`V zAs77)opcYdRqUFWB4%{yo7=BP!}1<91S(BZW<4pD_*^~DreYTuNwc?>hTY5Dm!%33 z(Mb?99=E+YQs_I)9svi_w!!>HbfIA=Im$3hI;qAqo@7M9@UwZ+7wGuXc=Up^wX5Y! zSv%fC5G5=emG6$hdq#py354#!Tg-`Hvq)h322`AKenX@^B+4ciS{D z!`0M8w)p+orE@c5t{(nQG%NG-3+atA4MsOV_o3vl1IR z&7_sL%3j-F?pJsS(?nTmMThKAp+6&5$sh+R>Z|GL9v3Zw>onyj%nrzxDwf3ef%BGx zjvJ$}{fCGj?W%14!E0-4sv@y+Oj#B;k`r(^?v&)-QEiL?w;Y)(!kl;64BmQwDyAbD z^sU&7HF667uNINIjQd|L7PBkx=Z=jwo=4(I(JSq17d4oxp7*WvDZMk`&x*)&+!E6S botziZEN?e}30R(9`XD`RL#Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUzl}SWFR9HvtmN82MK@f%G-}Mjp3+%O(V8BK!L=aRgLQaC7MPiyO z0zs|`q)1_rB5j_`vF;9Y2fo`TFvH`TV?K6gcjwJXQ51vh0ciFZDB{)a6CnjjpunA; zopXx0e^4RbJd6q5J-;J2a2u!)FR$P5Ec2c~ z^wc*iW`w#93b^6LkdwWAAy%Iiq19rATs=z(ar!dFZ(4!d)KsAOu9s_0@nRDwHomR5 zoLZq+<8HGfghYqhr|&f-?h{h{O8JYjUli&>_dTPga02Pm{oB5FQ<@talx@+3n;z{f ZbpR*TzI%`oD%Ai0002ovPDHLkV1k@&=eGa= literal 0 HcmV?d00001 diff --git a/mod/maxgui.mod/maxgui.mod/doc/fltkprogbar.png b/mod/maxgui.mod/maxgui.mod/doc/fltkprogbar.png new file mode 100644 index 0000000000000000000000000000000000000000..cc8f780347d10ec11415bc2888526177470809de GIT binary patch literal 347 zcmeAS@N?(olHy`uVBq!ia0vp^DL^d1!2~4pjeV~GDaPU;cPEB*=VV?2IV|apzK#qG z8~eHcB(ehe3dtTpz6=aiY77hwEes65fI=PvbRsRSr{&I z?cV)W8@^3CWYxNK1D}A!h7j%5%wkC_?s*PB1T?sAs-|x}I6-+|GTQ{r39B|IO7mM* qaJINMC(h)Jk2j39;n-7>(P8&IRn$sVz|;xoNd`|>KbLh*2~7ad(0%U! literal 0 HcmV?d00001 diff --git a/mod/maxgui.mod/maxgui.mod/doc/fltksliders.png b/mod/maxgui.mod/maxgui.mod/doc/fltksliders.png new file mode 100644 index 0000000000000000000000000000000000000000..037b25222bc393215a2df6d550360075303555b7 GIT binary patch literal 1548 zcmV+n2J`ueP)Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBU%ib+I4RCr$PU9ooCFbs6RI%9qzOJBx*LdLEc(;+WI7jGT&8$|;> z8UjcfkRiJ?kCR_QSmx<;1P_wFz@)zKawAE`4(ZHuiQi@$cnwgI<=>Cey4FE1~De2oB-OpnI4`j3cv zbnJ}Vfd!3%KR!Nw`Wm4lWv~-V^OO2Yif#2D6m*H39j_dI!EMEKhq}Dd1yN1n1gU+~Bm|k6-RkexvZb1aot-|y)y|W&MrrUYG zI+1SI^j0Q=>_tMqF?*?MdM9_3+H^K{!j!R3R;}sBL7#5_GT z_GLxN88@#IJuU!svw3Ow#H=~U};tc^aYo66H!#RyGLeRkSDQtMAl4<-5P)G^|3 zZ*K)t`ixc(AZ!Vl0@|YK)dfp+t;DMsDXWY)b(VE;x*F(6Xc7U!XXU*_7dVpX47#n0 z6Yk_opfLiH?58|Ev?i1aRX|tw6A2q9+<8Y$m&+@z z1l=)?p`q=i>4dVZq0ky?l3dU;OkN_DMQK8wUW^yUoeNJ`iz)<4lD?{u`coHGBjrqn zmq@_6ihwj;PWPvW5LbD6@nK*zwmei-0a(>Y{m`QlbO{1En(iqKqEA5pOuvM(8)Hv? zx?fvbnm&B(@>&DPWO~2;*=NO6v1yv_NnKj9K3i-K(`Ci3nl`B=nKdc7+BZXNPM$8S z(k+!JCDT$TWc{2ib{9XrWkj&ktBT@f9ov8I_?}`{_os(a7wTNCkrFyB?@aD(S)e8-liPZFD~=>)p8cGZ&wr1jMVrc9)h#3pMx zgH9z9!q+Oh1l?--Jh91|?g!2$>GQO`LY?|B_()|535Ax{s0p3L;D`_uibfu=*#q3QST+d$Ky z={|>Y^!WhZ%k7xXD&wyianG#0HM*J|{kYKd+c6z^y2lyKnoFSRw_`dq-NW>(xdfVi zJElX^JxqtDFP2|4-OO?dFF7v!^nkoT)5m8zG##3L=9awwL6@QFH_+uM==Mn~RE};@ zIfAA`)1m2Ympv~ z9@884BaMO%O;6Z)HwrqKe%j|Kv`_TRx*R2$eKT0XZtBq=0j6tBmy_q&y^@iqdmPH9 zpN{OM{}PF;t5fIcQqwyx?6Z4JN9ASa`9SCC8}>?Wtw`yyQb-_Z_?P zUM|^Vy4WvPyyRcxMn5)HpC^_^ny|;TFOQgRwd_&UA-G1x>vHwK>IHe?Z3!& ys@R3;l6UyLHv&tZ-j`JTHx~ggeQ#PPx#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBU#Ye_^wRA@u(T04&0Fc5Vvq@(02IYLU8DpR^t86b_*sWe;|2E4`Y z4fY7zh6<(G(VGt`S-xSw72krpgY1P? z3t;jnL%#3(!|Bx3bp)aeEIHQDg0G+cwpsv_QyKF8@%W><=DTu3zeiv5x&&aX!^{zGh?ZlUBS$TPuw}-6MX-S-`6GBNkuk_82U%|D z_oSA{xpHRDv03rrk|opES%M{*%RN8FAU5=1{s;?L5?|Yi1XoTn2K|>dG$vO9Rk|We zth&SsHuc979}nmX7z0$8QGK=OhdJ^zOMoczk;kmTB}W=assTBiF(rGv>QxPu#S-Z< z$tsHnPQSe(v3kv6318{+_z)Wp|}dKq5({2ZB0>Vz6F zi;J8kmX^p2<&WkgT$*u!{VGe=edFApS(dUyR=(@^OSoXj2w5@U{YfUNzFxgw0t%O8 zNfN44m$=B6?U(SC4d=<~l?##-C(b|MB3vdiPK2duhU_F`xe&qQ4#W7f?us;b=q=1~ zH1#gwf!U?8d^O0ks=JbP$=r3bnjo%hhGe`8F`nifjiJ=AG7&vx%@W61P?z|ksumpE zcKZ7z$+=XnC!gBHz~3)%J}wHmwUQ;4z-;1EYmnsLt3UgPv&5=P3ZcRVU&4M3|4?$! z;K~2v6wVTBzoZ(LM4ErLf8c?x+rPa0etkVvbOgY|?@RdaNk7jY>Vd$Lz>l}L=ZcO1 bII!doetl<@Om2m800000NkvXXu0mjfs~*z1 literal 0 HcmV?d00001 diff --git a/mod/maxgui.mod/maxgui.mod/doc/fltktextarea.png b/mod/maxgui.mod/maxgui.mod/doc/fltktextarea.png new file mode 100644 index 0000000000000000000000000000000000000000..66a230c0fba38beff3989ae71dbede01595960f5 GIT binary patch literal 2291 zcmeH}`B#(28h}4yWD&6xsskErN+*5e#87L}CMB4IqKA1~H&*3D(LQ zgo+@GB_ZsT#Z)Svh9DOOK|~hWWWNT(zBE1O-h=OnEwv44BgYN}l`;0^mXbprt z-hD0uQS@*kB37D7Z+Elsj!a41ew3Tk7MwT+GlfI6Atn!xUyx0+KF%No!8d8U^)!qQ zmm0EK*5yo`7?=+k7WAtp;g4hq-^H{zA&Ll08ISZ$r1#kPi4y5AlQUT%mkkl)P0Bx9 znUjBnF^-@!i`H%GGL%i8^9*>s=!e3?^z$=U^H}34!|`hQ-BD(8hwj2AgoH!z=?*ee z+V)*xUR7kkS8mEKrmyp%C01P|wH5z#@+fw}5EUI-L+o5tzDkB6!mB z72#*fmXgZ_uVM+4NM(7}JycKOK)!(YkV5fGpPqY87v9>*A^kAfY?MmRX)BMoyWz4LqdVA~HCl4cTnZ-ff&D?eQqVRgn zv$;a9zzAn~tWbz(#S>I_xgPenR+iduXd|p7%xrb|g zvZFATjr9cptc~X$ahvI0hf)uM8oy~WNM3Ez4vt;I02XDvK;4M)G4QjT_@Bx@ zO~*q_Qb~&cQsV3Dj4VIU(jlbtneaF|y-8JVV_z~TnX8M`kZpAg#3(2}gL2*vWc?+| zUS64K@mCtvy0w1y@RYCEi(-a6O?W2=Z7#UDnmXT6YsN9of|2{t&66ZWMLu~8$zDSR34nredTx7 z)5!7PSD$V?>9yM#zQm#9EImst;c*-t&?{_O|G{gG?i}CDh^+8v>QJqIr`yKR9Io=i z33_l~Wq<)rr(R#@Ff2OEgZDO0&5xyr>pjb%gsb(5Js zcSG;_62Uw+EP2pd@Ip7B(EQhcR)^7>B&~*t3YoyZnX*#1d$71Jh0s|FJ(w6=>AoF< z9FVoC(tGJ-P98GJ2V?0GXl?UXyf^c;&F*Ik-#-!7sM9sRFsYIehkQ+GVZ|(Q zLH1VqYq`n>4^6fj8_52nqM7TVyA_xn+k8`8;1IT8oLC!o;}<&YQE8$lAGsjnSD98e9dvp&iehph|O-DChLBe6eI*hqJ{nyvz{Qi(>aQa z8xv)6a8a(^8P>nCL19aFphji<^ULs-s_NoIZ80@8xS~V5!Nl36NvpSZX!b-2l)kVNbssB;+K?k{G^3}TM)PD7aZ&fn)#5E2KCi^7rS?HTo`{3%OJsv6J<%X}z?cELAJ*+zyKjZ%| z;D2ie2x^;aGc_X@Ftz|B5wbL#)Ht%#u<+QiW+AQ1^q&V`8-lLFgVp4>p8t@NgcjzK Y;N?XlY10wvl3xjcKIde|u_a#r8@;3?WdHyG literal 0 HcmV?d00001 diff --git a/mod/maxgui.mod/maxgui.mod/doc/fltktextfield.png b/mod/maxgui.mod/maxgui.mod/doc/fltktextfield.png new file mode 100644 index 0000000000000000000000000000000000000000..79e2954dae80ff878ee3153fe4e7f410451271dc GIT binary patch literal 540 zcmV+%0^|LOP)Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUznn^@KR9HvtnavJ^APj)r#fR~weH`P#XyRozk2~(T>q?q1)|P_C zA29SXe+sl8rF8h{`@XL0X_~4c2M}nQ#`HRlW81dRA_ovymIc@j!%)Fb*L858wO|yc z=>iZolp&m7nF~@*&XAIxauBLcR<{-E@PF4tK3~{xJ1TAP1gFa=Evg?1mLY9=t0vD5pk_|*s zzBzCgK2I#96`AskcR!LP*2XfK5`{}JRC!*$6=fwDm5}s>{N{{tbISS-BUS}v_fvLM zdG~W`DW%LHlc5wR;wzppY$>K>En*u_P-2QZxu_t+g=>s!?OQv#FDBOZv#)-kyf06= zw?E48UpwmLBVi?s<mho|^yp3L6BDquU$a|I{)1@uAFi62VLw-Wg72ZErB e>`MUIf_wogBN5r{Sjcq%0000Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBU%E=fc|RCr$PolQ<1F$~9_=%(tTt%TTADwQgA$)dYg0-)FkeI7K6TvGce?flMX z-GZ6CX1oyx#FwHR93sSmrKa~e+q_UHi-{dQOGIeCBA_%pHS3=OnrgcuppJWJ5BXtp z!wF*!FmCD-1~2_g$H^XqT~u#UXfaThvVb0iGuy8qTV$Wrd+ttB z2o$ccj8(7DluuS)QL6E$cA%_m8v&)Er@0o9m6ci;0VoWAJJ4KqtbL(Evw#j$MO)i; z7k|D?C<}Q^vE`FcWx6!CAT9(7?-6933KcplQVS6{Dq0+~TGj+v7T-dk zS+%^fY}bp?(J~8`#(3>O=cUlm6+=6Na6OTmZJ<4SyCEm5dgnQlLPvr68W`1NY_6P3 z2dV_6HCq5sV|W^yYe7ESEdXfll%};`3(!HQ4Oq7T+BoP^)OG~uXqnhRHTp8dJ{Xfi zHEW&%${suiWBFV;7|`bMJ-REPAyO}BngXRYD8d)Ng-q#7#48FAwSvxRN0nq-2o#k- zLZq-NW@QWIISMo-QiMqvANEM!YGsl?7Bd1Bnk#{_vEqWYP@(#G$(=miMpOHMhMm55 z7n+YlwJ20M2sQ(-NeQxp29a_qU!}aEOvN@=&O&L{0;qB*yJ6OWI~vcIrH63)xKS14;?TuOb)czQ#Xfqr2D7_0dT0t1)+g-AF?FgRjL}rtH`KE6 z{?Gy_i-Q(_LM_i0W(a8eqKMUUb)b<2!kW6>U`46~%5K)Xrck(yu=1;_P+mK`@hcF0 zB=(S3<-^pO3Eh3f4FTPQ$Wbh0Hktrc!!;W<+Cz)SInT3^Fr5yxc&+({vj*BYLA#)x zHBgrsHg+;G(8X<$qsvnQ6lUJ3h)mUQ6`=5@M=mQzyDv6a5>U-ph2uKSB*Gh7kJA;B zo1>9TwZPkBFa51&7EoHD3wJ`)GrKS-0%(y64U|7E4u#x?FZNLV<|x!Z7NFE^YIWK7 zb2w%(NhwRA0zP_0q*o}bJNBMs!g~n~-YQpc5jo zEGb3p(;a+{Ny)fGSg^ceSIBho}8S7ujl9I7Z(@4OjinYZ|~K>G+eg%GF=_etE;QP@%5Yc z9}mCPV7gMEZ{K}5`ug+m^RYYAl>*&A`11Yu*Z#rL;in(IO#cIjkWW~ZpJPP;0000< KMNUMnLSTYra-mrO literal 0 HcmV?d00001 diff --git a/mod/maxgui.mod/maxgui.mod/doc/fltkwindow.png b/mod/maxgui.mod/maxgui.mod/doc/fltkwindow.png new file mode 100644 index 0000000000000000000000000000000000000000..2ef1262f010ccfaf89b8041583f86a7402a676cf GIT binary patch literal 6458 zcmY*ebzBr}*Iv4$JC-!)5Ef}&x)xbFq0Vl3Nr{CO5v45_(T zdEWQ;d%pLNnLFmhb16&6%1PlOFCX!rP;bF$?HmW)h0Koqt01y%Z09;_ELN);aFJS=Sk0k&g zl>q?IzsmXwl>q=48q^fQdcNj6W&}ohDpP~E*D;MnU~1AB$Ki}2hSm-S2q)8sBY!1; zb6O-8kA{}S8q5)bZ4IV`zT~E(8Q~Ux8BNt08)gKK9nU}IUA}GITAh8FE}+0#XSOc) z=!wThcBbgjptQr_y8!yz?r(DYKyP7OF$yg06e5LZIF!CB%`PRS0qu%p*nfb)6B9#b z5F^)bN^K#faXT~F@%y_T^z(&S){uvK^OTBlO^R(O+|&g8W4_INZyNcBfcvj;b{x zA*&IxMAt>@ip?PS69J!07&8G9#t`ssLVG?Hp3Lw>qB+gQm#Z3u_p$wU!Ed|HuLLjAVmGo;Mj)@!?r+ZPMDS?3o**FP!nc7bM0kX zq<28t$o!UHb%>9Lr=soL`sK&d8Plp%wVUi{hK$x5nSqx!(R!2)g%Q|G`DI}xz2rzg z`1W62f74z`B_&$@uT|gVaM#p<8A|9M>ia>q4n!ApuiiI(S+Fu{&XuywEYe+u0 zZE+21slljFej7?%_ZL%6I#)X4qZ?M|+N%Db4Lj}9X7KVEzjQjyC^<-B*e+m)DBu<;z;d5+A`eBrG+ z;za>{>ax4@a7=a`YeN$%)r;q%a`2QZs(~%AqC1H$NR!q;mF7^LPn$ee`_EWuGAIcA zOG&gs!R84Yy^8chIh?D$A3{95)N-zqP5x&3*TgIWrDb3(Eihxx>tyv_-jIUxD9e~+ z9UJ&4PqZfN&1_Zrdp@gY1oE46lO&ZU}EWlQLJ z2ocBz5Nz(Doe(Xw6@fZDfz#hprC(i^X?HS1Y|Lwfw~;LP^J`b1guwSFRi%N=>VG8t zx7196do52DKEfP!WpE->mZlmZKG~ZAVH7|+>4aM5C9ly%jeuf@$tiQn#g5 z-XSuQ>*R4MyJR&0-Hw>$5z&P4Yhly&q#ya5)AhxyT)myTUthVMa4f~iQ71hZp(GpX z+~J;N@d9dWc3EPuDM9Jl2A4x*9&rkg2g%W&bo|^?yk5?;=R#c*M}DS;t(IvE7d0ln z$2&l@(wwh(qNsh|zkZR(aSWS4%*Aq1sNP}h(Xfv{x}Jk5#`&XRfB+7O{Vc6w!YUvLre_|;^UE+teo0QX&_S7Q); zviJ0_Mdy+AIjRpxv#Q{L3cRn3J1Z$&nZ*Xxp_U zq#AWk5k0I#+jzoYTP4mB<7Gwukx&iQKIHQO$YB5L^>6udRPFa`B^VQ;=pN;Fd`e-F zoK(vRYe;$GnT{bMF8k<94kGv*(EGGkL$k3X?y6~-xQudBk}wwcV`j&3)1zMOW63M? zt1E$Sf(kiyXqNWauv3LRm>@^N|D!e|F~j&tKzJ@|CrV$>n?aVj{pIgX zQSIWCpqS3lL*i@j3g#JP8{WSM@N8j=3E}tl86Tw)w33eRF*W!-SBaNk@{S zHXI7JHuL1^{^|&E`#WZvInMISJEw*JfHcw>7q9azUvigO2j9^X)}4A-y&|bC_}0qq z*${2x8X<3olpw3;kEw1mdB{{yTkW)+DLeMSr1E+MdXG6ivaQne`76m;7hQRSn*|bR z)1LD2t7$>=PaZuW?y|p&7JBAiUX7XC5D2~SCy2`1pmiZ83uwKSu*Ngj?H*Q4RhFGc zomr(*6LYcw712{3jy{*IhhS;j!vL~N*!Okwgf@SeMXT$AkJzz|g?;-M!M{XJDM@th z2PP%#-F}AqM{zI4qtJFJJFnp>J_yERk(CR+Tp+YDW6V?;KtzrO{A84s7SN$d%wcraFrGV9KJA~@! zUdh8V(+opA5{ZsZG}l%2K#sM;kaZfGrMXUDla1oieK}$2Rtl6+1aFoR0WcKS7U5{NEwIGW32`XV%Z-^D!BlFWF zxZ+t>R|GwCW;|}BVnnEf1pBa{bdM%G`Jj%#c&O&U9?R)CJxO;+VJ~(Pxh?@#yyBP@ z1Bq0@%DZkM$oBQuAyXkJ4r`VrLv~KzM;D#QeVwax32D1DdASevrYT=y!UFROCH(7H zVM4qw11o)*uh`rL=Nbsg1H}W(u7Cd0{t&WHN&L>`$y{)9XkXhK9bf5iM(1c+ zUr4YUb&TguH$zp)ZUrgJXS;AKl79fsGz%<@<^D4 zYx_l%(5&hxordfz)9jDmLVw?eu1-U`TeBO>H*^s2tZqsC`+4gNc%b)%g?98CG{p7s z6hTXIV(v+ajl-eqQy!D*aml`LC8CgeQ(Q?Zv`<&rN zo-JmxN8a0@Llth&*?f8aqbFR;jjz63JevyCkw<9BkQni9yKa)cDokS)DYT`dk*p~{ zKpyW>33aGnxNT>HJk9=`rCoiVxUT51rLFBVI>w{F#K+Z2} zZvvD`Tlszq+eq&q$_NYO*9^Ho8g{EgeU4+u7MP7T)-ku*Xnu6`DTQt@0?!mdB9n$r ziw}7Ss&||iB83z1r}C(9~1NZdF6N!lb@1xV;*$)M)R<| zdMdbf`Z>$S2k&5`+HbAX5&bn;)?l!)_lKm^e`93grjR zfe0cFnzHwaEO2jiefCVtXQj#2$&S)9zr#h4vokO6XJS?#BX6W>E$?5KM4e*LTcYCA z0E*qbd5q+)5zj{UrH2>B9K(ArzZ=;?Q7(I-qdAHFmj-K4dPlqcvgsQ>XGM`p}I7Kl)-wkBsXYi<3rYpdcT0YW_cupF9kxIaym~e~RkuEy7rEXm=?wiQvra7) z5`*(yjVZ6#_%irmZQ;K%vCzPRFY0m7TzYz%RD1f=HJbF8Wi83c5r)q3ZDAjzp3~F$ z(o5T+0ToUvoyf#L(Gmx{SWWz&ilPWkNMf$+s|pt=m}QSTcRoECuUP6j5}U?v_~hWK zo!>tn5Im4fVzg;wxRbM_eCdH%Hf^WOeF%kATs{OVPP;`*~Wf!Jc6F+L-=m!jYEPd-Pk z_xS`6n0;{vNd_zJLo^jyk%Hr`F?+et4ReMw-|^< z@kY8;B|QnO8>I2kXL9j0JyYv4MKMmnA|P*LO6AZ?C&{(-5`%2_jPcEhADA^%B%ru_ zOXE-qg!RwV8w6i+tkDt8Gl)UMJ1~eO?vnekpmD-v{vbgBe`xX?{;=Y`z@j6^Ubkdm zyOY$@xK12JGJlUgmu+d9^+m8^1%}8gm#0PB~%1B4WZpZZ923jV4mOCO%H`ua8(&spdd@ue|2}FFRZM{`AZ>{_%xky5* z58voFHGd*EAI`;tJ4wo>?~P_Ie^(U2)}30O5MivVK<)mzwH^!HKBUu~tjTzYw?VgJ zc!0?6+7eZ6c}9Rfd9BvmNvo@Spm#H&;84YkXrf-U##;=`+?QD(l9cK(TqThnJZ(PY z&J@FDgL|7USJ-@siqXSGKR11y7@qC0PTkPrzV9Y(i|EpQSqow(tH5B63o<_Fk$(p6&L>}j72l9*TTH=-2JkCo^J8;?1)-s9#}Jv zlfqZPJEX70KD=OAL~B#%d!Jf)&cjDjjKr{y8$akdI;ewJ63u27>~qh%ERpfwcUx7y z0vp%8xBs}Qysha!CI@aZO*>_iyRA0aD}3_fT0hjJKNvufa23UrXH4)i0BbX}H6blC zR1<`A0JmdnR&Q_RnFHlPTB#_j$tJ66H0isU8aujY6!Hg1Qnxdfg(5$h6+D@-PWg)B zk`GWM2QO^Ffk5F|EurOOZRio1Gy`^tQb;Mn`~1q}%85QBXJ$1@GcL=@wlJf#3==Ds~)5d)S9tZMo-M~*c{v3QxW zyH&_poTWFnYAzjQuPMfN`3eYr}KI5urM7w#eN?8JERL-=)V3 zZ5?>lcZ~8ksVig6&T-q6j60h~WxZiiq<1*~BaZ3tA6xy`ty({Ywg`63`1r7I1PIx9 z2e?x-D%0kl4jf;!o8lh;Fco$wsf(rd*QX1ts-?}cKU@IrVLE(LK(9LF8VUDLl86}Q>5MLY}R8dT;btKpH@Qgs} zPu=L=f=3v511szF-F5(E4NoK9SkxNQ&!JsCpkj7GW;DE>yNeIJr1oAuh)#h&x-{4A zYqFQVHqY&EJ|V@g9oZ_M+GQrY)S`2SX})|=&+*adNH@G?1wpzwIkukb-E6uUTvA#( zG|`Zfj{do1+AymQEhDOsv~R0(yO^%OtU(;D?<@q>pEnMmJw`E$s1{jyXkge*Ns$O5 zAoV$~YSd?LHV+JD-hObswZrjqFXAXZK0Y$IJ>JoP$OPs-#pa|kbmK2S)k%FpBYWLq z_BHdSvF|f~Xh;($XZO}rMdk5|aW;-nEGB}0l#D*6=chpfExroBo1}6~eU5Ml6o`q5 zv9YnqSY>>VH%D{}wal7)DKFny7S^@e7UmatpV95s>8ye%jg=P@Lw(|c&aU2?rw7IH z^YZeBhlOcn%lIv|MMg&xZuf_$LVBEG1`MOeCS0+gN~E#5c|s4B1xLKF@yp>awloQfYMQ3SI3#J!V{Falr=-BWrHrn z%uU?eEvUAg=skCp;Xg-2Uy*55*3=yLXNnSX4`s_Dz3FLbx0sJzCw{Vvh!D+nh9yj7 ziSCVIqRdJwuNU+>u!6|D4YUlvt1xTCC;vL*pi+N(9DKYflEqy_gh!^BNqU5a2z?!E zVC4$yAVAwrCjpFgb##bHkQAQlYiml%%FB#|$7}ucS^dti6dZh@QY$Go$&$2?+1Che zQ86(we*Sw4sm#)7jGdp9$)J3LH=ERb{=U9vYkjERI!b~%Q6-z6mZ|ZF6+9yb%Zj~5 zZ87fKsB}!Q#Upu`f3m-{dXxJB5A@hrpq3cCRkk*}ozA304%nG5g-c_;6?-qA^Xw44zanhF~O(Y29PU>A64o`UDa6brxvKk}Nm z{_UXkKmkpQlfH%1|MRG;utGV>zsrd+@UKe~+WgO5?pPQia}NlsT5w{=P|B*SYP)~I zhdU<0aiDdks=wnh`Y`%Qf=}|8)y!q*l=(14V|WB4#%eXNEO^I4-;6ua9WHk?s1GG} z=BKByTy%DyJ#mEZO`oFYNGEHW9584F{_@SaN+CgCDAM6oas?2QV=82<;{c#C#qtx+EaQh}qvl0~)+hSvQEqcfB>AXKS2V7YBeLT*MZ zd2th1SYHI{%ussfJB2nY_StC-Sad%=9UXz%7<#XwhAAhf#shjLg<)YiLw6#Nu{+@6 zap+eoJpZvk339fWnwV&I!hB-mTt4fOUPUOr!oj|Ig9ofu`bHKN@|Y6PtvJqKT4FV> z_i(ywH;SEIYoG*eqC5~4((RcR6CwfX{Ww79X}3J^r$9Lbn!?0eP-KG30MbW3saB2$ z|9XYT3=D;al$JF*m4TR0|a?ziQ6B-q{LL_{pNzr*We#FO_>uz6ab-KxA3Bt zsr#)STox{mw;8a1D1=-IM_-9Y{|SJMxS?kfdDE^u+6v5@qn-2+7MPlfTabwR%uoc! za5UlgM#l0UNW~u*n&B!Ddn7!R!?F81Ll~C{7#dnie(#kup#0QpLB+8o1FcAI_pNWq znS7-`f+Oc1E~X?%A$DnH_su6EfIYT&#wF&~kWAX2e^H6>2Sz{!_nU|?X&}xPjqVZV z^*w2b-gOJs3dH*=G~fG={xfw#iAlQ=@qLI0=)@%`+B2gu5>xm0BV_15+Oe(IzaLwy zCWb*W9u{(Jp~s2BT-za3J>LQ@BYMO08L|H;{c=MXDK|r`CK<7pF?aap?ZA1kyMLk}=NHvno%T8icJmSO(~=)+v8 literal 0 HcmV?d00001 diff --git a/mod/maxgui.mod/maxgui.mod/doc/gadgetclass.bmx b/mod/maxgui.mod/maxgui.mod/doc/gadgetclass.bmx new file mode 100644 index 0000000..e6a31c4 --- /dev/null +++ b/mod/maxgui.mod/maxgui.mod/doc/gadgetclass.bmx @@ -0,0 +1,37 @@ +Strict + +Import MaxGUI.Drivers + +AppTitle = "GadgetClass() Example" +Global wndMain:TGadget = CreateWindow(AppTitle,100,100,220,200,Null,WINDOW_TITLEBAR|WINDOW_CLIENTCOORDS|WINDOW_STATUS) + + Global btnTest:TGadget = CreateButton("Push Button",10,10,200,30,wndMain,BUTTON_PUSH) + Global chkTest:TGadget = CreateButton("Check Button",10,40,200,30,wndMain,BUTTON_CHECKBOX) + + Global cmbTest:TGadget = CreateComboBox(10,70,200,30,wndMain) + AddGadgetItem(cmbTest,"Item 1");AddGadgetItem(cmbTest,"Item 2",GADGETITEM_DEFAULT);AddGadgetItem(cmbTest,"Item 3") + + Global sldTest:TGadget = CreateSlider(10,100,200,30,wndMain,SLIDER_HORIZONTAL|SLIDER_TRACKBAR) + +Repeat + + WaitEvent() + SetStatusText wndMain, CurrentEvent.ToString() + + Select EventID() + + Case EVENT_WINDOWCLOSE, EVENT_APPTERMINATE;End + + Case EVENT_GADGETACTION, EVENT_GADGETSELECT, EVENT_WINDOWMOVE, EVENT_WINDOWSIZE + + Select GadgetClass(TGadget(EventSource())) + Case GADGET_WINDOW;Print "Window Event" + Case GADGET_BUTTON;Print "Button Event" + Case GADGET_COMBOBOX;Print "ComboBox Event" + Case GADGET_SLIDER;Print "Slider Event" + EndSelect + + EndSelect + +Forever + \ No newline at end of file diff --git a/mod/maxgui.mod/maxgui.mod/doc/intro.bbdoc b/mod/maxgui.mod/maxgui.mod/doc/intro.bbdoc new file mode 100644 index 0000000..4ecaf55 --- /dev/null +++ b/mod/maxgui.mod/maxgui.mod/doc/intro.bbdoc @@ -0,0 +1,207 @@ +The MaxGUI module contains commands to create and control user interfaces for developing applications in BlitzMax. + +Users should be familiar with the #WaitEvent command and BlitzMax #events which provide the basic communication mechanism +between user interface and program when developing MaxGUI applications. + ++Gadgets +MaxGUI provides numerous types of gadgets that can be created and arranged for the purposes of providing a user interface to +BlitzMax applications. + +The position of gadgets in relation to their group (parent) gadget can be controlled with the #SetGadgetShape command and +monitored with the #GadgetX, #GadgetY, #GadgetWidth and #GadgetHeight commands. Gadgets that can act as group gadgets +(such as Windows, Tabbers and Panels) have an inner client region that contains their children, with an area that can be +found using #ClientWidth and #ClientHeight. + +Gadgets can be made to automatically reposition themselves when their group gadget changes size with the #SetGadgetLayout +command. + +A gadget's group, or parent, gadget can be retrieved using the #GadgetGroup command. A gadget can be shown with #ShowGadget, +hidden with #HideGadget, its visibility found with the #GadgetHidden function and removed completely from the system with +the #FreeGadget command. It is now also possible to determine a gadget's class/type using the #GadgetClass command. + +#EnableGadget, #DisableGadget and #GadgetDisabled control and determine if a gadget is currently enabled. + +#ActivateGadget will set a particular gadget as active so that it is highlighted and receives any keyboard events while +#ActiveGadget returns which gadget (if any) is currently active. + +#SetGadgetText, #SetGadgetFont, #SetGadgetColor and #SetGadgetTextColor change the appearance of many of the MaxGUI gadgets. + +Those wanting to store their own object with gadget can do so using the #SetGadgetExtra command - a reference to your object +will be stored inside the @TGadget type and is retrievable using the matching #GadgetExtra command. The object reference will +be overwritten by future calls to #SetGadgetExtra or when #FreeGadget is called. + +Recently, #SetGadgetTooltip and #GadgetTooltip have been added to MaxGUI to allow tooltips to be set on standard +%{non list-based} gadgets, including Buttons, Labels, TextFields etc. + +Tooltips are set on an item-by-item basis for gadgets such as ListBoxes and Tabbers etc. +Attempting to set an overall gadget tooltip on a %{list-based} gadget will have no effect. + +Finally, a more generic #SetGadgetPixmap command has been added which will eventually allow you to set pixmaps for many +gadgets (not just for panels), depending on your platform. + +

      Events

      +Gadgets that allow user-interaction emit events that can be caught and processed in your main application +loop (typically with the #WaitEvent command). The events a gadget can generate will be listed under the +corresponding CreateGadget() documentation. + +It is important to note, however, that events are only emitted when @{the user} interacts with, or changes the +state, of a gadget. Any changes made to gadget through MaxGUI command calls (such as #SelectGadgetItem) should +not result in events being emitted. + +

      Windows

      + + +A Window is used to contain a collection of gadgets that make up the user interface of an application. The #CreateWindow +command creates a window of a specified size that can then be used as the @{group} parameter for the other gadget creation +commands. + +The #WindowMenu command returns a handle that can be used as the parent parameter of the #CreateMenu command to add menus +to a window. #UpdateWindowMenu should be called after adding/changing a window's menu for the changes to take effect. +A window can be activated (bringing the window in front, with focus) with the #ActivateWindow command. +The text displayed in a window's optional status-bar can be set using the #SetStatusText command. + +If a window is created with the WINDOW_RESIZABLE style, its sizing can be restrained using #SetMinWindowSize and +#SetMaxWindowSize and it can be minimized, maximized and restored with the #MinimizeWindow, #MaximizeWindow and +#RestoreWindow commands. The state of a window can be dermined using #WindowMinimized and #WindowMaximized. + +

      Menus

      + + +The #CreateMenu command is used to create menu-items. Menus can be attached either to a window's menu-bar by parenting them to a +#WindowMenu or can popup at the current mouse location if used with the #PopupWindowMenu command. + +#CheckMenu adds a tick next to a menu-item and #UncheckMenu removes it. #DisableGadget will "gray out" a menu item, preventing it from +being chosen by the user. #EnableGadget reverses this operation. + +

      Buttons

      + + +The #CreateButton command is used to add buttons to a group gadget. Buttons can be standard push buttons that emit a single +event whenever clicked, or they can be created with the BUTTON_CHECKBOX or BUTTON_RADIO styles +in which case they can be toggled by the user (or programatically with the #SetButtonState command). +Their current state can be found with the help of the #ButtonState function. + +

      Panels

      + + +The #CreatePanel command is used to to create a Panel gadget. Panels can be used to group other gadgets together and +can be optionally assigned a background color or image using the #SetPanelColor or #SetPanelPixmap commands. They can +be created with or without a border. Panels were one of the first gadgets that could emit mouse/key events by +specifying the optional PANEL_ACTIVE style upon creation. + +

      Text Fields

      + + +A text-field allows the users to enter a single line of text. A text-field's characters can be masked by specifying an +optional TEXTFIELD_PASSWORD style flag upon the call to #CreateTextField. This is useful for creating password-entry +forms. As with all other gadgets, #GadgetText and #SetGadgetText can be used to set and retrieve the text in the field. + +

      Text Areas

      + + +The #CreateTextArea command creates a gadget for displaying formatted text, with optional TEXTAREA_WORDWRAP and +TEXTAREA_READONLY styles. + +The MaxGUI commands specific to text-areas are summarised below: + +[ +* #SetTextAreaText and #AddTextAreaText allow for convenient editing of the text. +* #TextAreaText returns either a specified portion or the entire contents of a text-area. +* #TextAreaLen returns the number of characters or lines currently contained. +* #TextAreaCursor and #TextAreaSelLen commands return the cursor position and selection length. +* #SelectTextAreaText command provides a means to programatically select/highlight text. +* #SetTextAreaFont and #SetTextAreaColor affect the style and appearance of the text displayed in a Text Area. +* #SetTextAreaTabs allows you to alter the position of tab stops. +* #FormatTextAreaText allows sections of text to be formatted using their own colors and font styles. +* #LockTextArea and #UnlockTextArea commands should be used to improve performance when formatting lots of text. +* #TextAreaChar and #TextAreaLine commands convert between line and character positions. +* #TextAreaCharX and #TextAreaCharY find the x,y coordinates of a character position relative to the top-left corner +of the gadget. +] + +

      Combo Boxes

      + + +Combo-boxes provide a dropdown list of options to the user with an optional style that allows the user to enter +their own text in a similar manner to the TextField gadget. #CreateComboBox creates a ComboBox and the standard +list based gadget commands #ClearGadgetItems, #AddGadgetItem, #ModifyGadgetItem, #RemoveGadgetItem, #SelectGadgetItem, +#SelectedGadgetItem, #CountGadgetItems and #GadgetItemText can be used to manage the items contained by the ComboBox gadget. + +

      List Boxes

      + + +List-boxes are similiar to ComboBoxes but features a scrolling list rather than a drop-down selection mechanism. +The #CreateListBox command is used to create a ListBox gadget while the standard list based gadget commands listed +in the previous ComboBox section are used to manage the items. + +

      Toolbars

      + + +Toolbars display a row of clickable icons at the top of a window. The #CreateToolbar command creates a window toolbar +using a previously loaded @TIconStrip or using a specified image file containing a strip of icons. + +#EnableGadgetItem and #DisableGadgetItem control the interactive state of individual items while #SetToolbarTips +assigns a list of meaningful strings to the toolbar items. + +The recommended icon size for toolbars is 24x24 pixels which seems to work well on most platforms. Using a different +image size may result in the pixmaps being scaled before being set depending on the OS. + +It is important to note that Toolbars should only ever be added to @{Window}s - adding ToolBars to other group gadgets may +cause your program to crash on some platforms. + +

      Tabbers

      + + +The #CreateTabber command creates a tab control gadget commonly used to group gadgets into a collection of pages. +The standard list based gadget commands #ClearGadgetItems, #AddGadgetItem, #ModifyGadgetItem, #RemoveGadgetItem, +#SelectGadgetItem, #SelectedGadgetItem, #CountGadgetItems and #GadgetItemText can be used to manage the items contained +in a Tabber gadget. + +

      TreeViews

      + + +A TreeView is used to display hierarchical data where items are contained in nodes that can be children of other nodes. +The #CreateTreeView command creates a new TreeView gadget that provides a #TreeViewRoot used to create a tree of nodes. + +#AddTreeViewNode, #InsertTreeViewNode, #ModifyTreeViewNode, #ExpandTreeViewNode, #CollapseTreeViewNode and +#FreeTreeViewNode provide commands to control the the contents of a TreeView. + +#SelectedTreeViewNode and #SelectTreeViewNode return and set the currently highlighted node in a TreeView while +#CountTreeViewNodes returns the number of nodes contained in a single TreeViewNode. #FreeTreeViewNode and #ClearTreeView +can be used to remove nodes previously added to a TreeView gadget. + +

      HtmlViews

      + + +An HTMLView is a gadget containing a complete web browser display. The #CreateHTMLView command creates an HTMLView gadget +while #HtmlViewGo, #HtmlViewBack and #HtmlViewForward control the page being displayed. + +#HtmlViewStatus and #HtmlViewCurrentURL provide extended information about the state of an HTMLView gadget while +#HtmlViewRun allows scripts (i.e. javascript) to be run (on some platforms). + +

      Labels

      +Labels are read-only regions of text on a user inteface that do not have a background and are created with the +#CreateLabel command. + +

      Sliders

      + + +Sliders allow the user to control a numerical value by dragging a control inside a container. #CreateSlider can create +both a scroll-bar type slider (where the size of the knob represents the portion of the document being viewed) and +trackbar style sliders (where the knob is a fixed size and #SetSliderRange controls the minimum and maximum values +allowed by the control). + +#SetSliderValue and #SliderValue set and retrieve the position of a Slider control. + +

      Progress Bars

      + + +#CreateProgBar creates a progress bar gadget commonly used to display the progress of an operation. The +#UpdateProgBar command is used to update the progress bar with a floating point value between 0.0 and 1.0 and +are typically used to represent how complete the current operation is. + +

      Desktop

      +A gadget representing the user's desktop is returned by the #Desktop command. The Desktop gadget is particularly useful +for finding primary screen and workspace resolutions using #GadgetWidth / #GadgetHeight or #ClientWidth / #ClientHeight respectively. + +The #LookupGuiFont and #LookupGuiColor commands can be used to retrieve system defined font and color information. diff --git a/mod/maxgui.mod/maxgui.mod/doc/lookupguicolor.bmx b/mod/maxgui.mod/maxgui.mod/doc/lookupguicolor.bmx new file mode 100644 index 0000000..530f17f --- /dev/null +++ b/mod/maxgui.mod/maxgui.mod/doc/lookupguicolor.bmx @@ -0,0 +1,38 @@ +' lookupguicolor.bmx + +Strict + +Import MaxGUI.Drivers + +AppTitle = "LookupGuiColor() Example" + +Global wndMain:TGadget = CreateWindow( AppTitle, 100, 100, 300, 200, Null, WINDOW_TITLEBAR|WINDOW_STATUS ) + + Global pnlMain:TGadget = CreatePanel( 0, 0, ClientWidth(wndMain), ClientHeight(wndMain), wndMain ) + + Global cmbColors:TGadget = CreateComboBox( 5, 5, ClientWidth(wndMain) - 10, 28, pnlMain ) + + ' Populate combo-box with the available color constants + + AddGadgetItem cmbColors, "GUICOLOR_WINDOWBG", GADGETITEM_DEFAULT, GUICOLOR_WINDOWBG + AddGadgetItem cmbColors, "GUICOLOR_GADGETBG", 0, GUICOLOR_GADGETBG + AddGadgetItem cmbColors, "GUICOLOR_GADGETFG", 0, GUICOLOR_GADGETFG + AddGadgetItem cmbColors, "GUICOLOR_SELECTIONBG", 0, GUICOLOR_SELECTIONBG + AddGadgetItem cmbColors, "GUICOLOR_LINKFG", 0, GUICOLOR_LINKFG + +ActivateGadget cmbColors + +Repeat + Select WaitEvent() + + Case EVENT_APPTERMINATE, EVENT_WINDOWCLOSE + End + + Case EVENT_GADGETACTION + Local red:Byte, green:Byte, blue:Byte + LookupGuiColor( GadgetItemIcon( cmbColors, EventData() ), red, green, blue ) + SetGadgetColor( pnlMain, red, green, blue ) + SetStatusText( wndMain, "RGB( " + red + ", " + green + ", " + blue + " )" ) + + EndSelect +Forever diff --git a/mod/maxgui.mod/maxgui.mod/doc/lookupguifont.bmx b/mod/maxgui.mod/maxgui.mod/doc/lookupguifont.bmx new file mode 100644 index 0000000..b69d049 --- /dev/null +++ b/mod/maxgui.mod/maxgui.mod/doc/lookupguifont.bmx @@ -0,0 +1,50 @@ +' lookupguifont.bmx + +Strict + +Import MaxGUI.Drivers + +AppTitle = "LookupGuiFont() Example" + +Const strSampleText$ = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nulla eget mauris quis dolor "+.. +"ullamcorper dapibus. Duis facilisis ullamcorper metus. Pellentesque eget enim. Vivamus auctor hendrerit turpis. " + .. +"Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus tincidunt leo quis urna." + +Const intWindowFlags% = WINDOW_TITLEBAR|WINDOW_RESIZABLE|WINDOW_STATUS|WINDOW_CLIENTCOORDS + +Global wndMain:TGadget = CreateWindow( AppTitle, 100, 100, 500, 300, Null, intWindowFlags ) + SetMinWindowSize( wndMain, ClientWidth(wndMain), ClientHeight(wndMain) ) +Global lstFontTypes:TGadget = CreateListBox(0,0,200,ClientHeight(wndMain),wndMain) + SetGadgetLayout lstFontTypes,EDGE_ALIGNED,EDGE_CENTERED,EDGE_ALIGNED,EDGE_ALIGNED + AddGadgetItem lstFontTypes, "GUIFONT_SYSTEM", GADGETITEM_DEFAULT, -1, "Default OS font.", LookupGuiFont(GUIFONT_SYSTEM) + AddGadgetItem lstFontTypes, "GUIFONT_SERIF", 0, -1, "Serif font.", LookupGuiFont(GUIFONT_SERIF) + AddGadgetItem lstFontTypes, "GUIFONT_SANSSERIF", 0, -1, "Sans serif font.", LookupGuiFont(GUIFONT_SANSSERIF) + AddGadgetItem lstFontTypes, "GUIFONT_SCRIPT", 0, -1, "Script/handwriting font.", LookupGuiFont(GUIFONT_SCRIPT) + AddGadgetItem lstFontTypes, "GUIFONT_MONOSPACED", 0, -1, "Fixed width/coding font.", LookupGuiFont(GUIFONT_MONOSPACED) + +Global txtPreview:TGadget = CreateTextArea(200,0,300,ClientHeight(wndMain),wndMain,TEXTAREA_WORDWRAP|TEXTAREA_READONLY) + SetGadgetLayout txtPreview,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED + SetTextAreaText( txtPreview, strSampleText ) + +Global strFontString$ + +ChooseFont( LookupGuiFont() ) + +Repeat + Select WaitEvent() + Case EVENT_APPTERMINATE, EVENT_WINDOWCLOSE;End + Case EVENT_GADGETACTION, EVENT_GADGETSELECT + Select EventSource() + Case lstFontTypes + If EventData() >= 0 Then + ChooseFont( TGuiFont(GadgetItemExtra( lstFontTypes, EventData() )) ) + EndIf + EndSelect + EndSelect + SetStatusText( wndMain, strFontString + "~t~t" + CurrentEvent.ToString() + " " ) +Forever + +Function ChooseFont( pFont:TGuiFont ) + SetGadgetFont( txtPreview, pFont ) + strFontString$ = FontName(pFont) + ", " + Int(FontSize(pFont)) + "pt" +EndFunction \ No newline at end of file diff --git a/mod/maxgui.mod/maxgui.mod/doc/osxbuttons.png b/mod/maxgui.mod/maxgui.mod/doc/osxbuttons.png new file mode 100644 index 0000000000000000000000000000000000000000..fc0d6c1d30007b4975b64515bff808cc4e87c455 GIT binary patch literal 8820 zcmV-)B8%OLP)Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBV8@<~KNRCr$P-F3JwZP^y^O?P*9_d$1ehZuBsNOyO4cM2*}3P@NW zh^W{~cL_?1fbjj^b#Bgmz4ttOy&L`b>*N08IcCi>&&)mNmG^a>GwWFId*Azxb*y9k z{`bH4dEmf-xt%|=$M&(0ee8LdJsCM>+3wl42V_t8&+U2eJgrMFU-cyYs(UiqeE#lt zzw37Q&jT{;?3qXAPJL$dX1Ck(xAWlTD)Z`@)luV}?|kRq*&FYA*Sp^R?sxy)z47<= z#(UoLp7*}@y~LC8fe(D(gCG3hKinJt=nvz=AO7%1KJt-&{D<+;kAC!HAN$zHKmPH5 zvN!(e-uP!@{PVr>FZRYKKl#Z|ed<&Ha&LU*GoSfad*id8{p`Qq8=w2!=l;zf#=qMe zpa1;l|HIz+k9*@k?T!DkH~#D1`0sn;zwM3e`OjnIct8L5dn4!kw|m2NT+T%^hfja{ z)0veSnrEh;JNm>YKH=^Rx9MgLw{O7VLm&DOWI&Yh{`bEhXaLOk2YUmgJ_E0D;2rOH z2LTw+j{uCnw>KgHNBgmjSG?jCkAM8*?|=XM-|0?wy6tUm``7k{jXD1M(Z}D|jK6vK z@wbj(-0pU_>rvVExs2^;c3yKkx9(Z)B7ZJ-nm_M+=Q}^}fe(Drlb-bISHHTrXM?it zL?4oY*Emo`COU%*qt4Z68*hB$8z1}F$3EmC4|&5I-asS1`ORL#V>xbu*i}4Y?#bO zLjrklO)L8G@}y+rRj+!La|y`b{`R+j_`@GMyU%R=&p+8Mg@?Ko#QNLIm<~; zdeRe~@PubP;~6=`eU99Ib>8!y_pNVz>pnlZ?|tukyyG43L?=4Y#V>yG$2{gSf7HqU zat|)_K?X#C0@q7k@)9}(Lz!UmA|u<$4HH(41IabF9-q&7_`@Gg24DHgSHAO|?|koj z-*fgK{NM)_!2amJ?sc#8D>zDO1?nTe?IS_|rZ>H*`S6)iayi1`PA;uH?P*U7ksNUC zYhRm69{Eg;@JN7w1vsYUmcd1pANj~fzVxLpjeE(M-apx=u^W9N0sV8H^Bmdkm%j8R zH{jHP{>afc`)_>X8!SLJW;WH+CqMbg4|>ppa&MA^OI_+xCp+26WR2Ma{nxzaHMhR? ztpRthd);db0o{kb{nB|xz)jiSdH#!C>|$hpp7WgNZg;!e!yfjq;~)R{XE?(doZr3p z3C*~`1uo#ySG(HPWcs<#wXSt7Q`+b1+xY|&;5aRyzy-ADJ@0w$7rxu58?Sy4eOXPj z`@~+K&^P0^yyY#H8&)FU`qsC|HoEWfxgNVa+~9elWzTrVGXP{cbJx4x^&a=QM~;^u zOUYxl=RWtjU6H$Vm3#}GGoSg)1W&2q#cr0XK>w;&y(-(f<~6VR;0HfA-|jp=8;3p% z`0|&({ME01^}-jvu>8&P%kk1gCx7|NU(QkZ?fK7tez$fcSD%xqE=KnaK)Dg15$(P2 zeQ!V~{3Zf74AdYFEIx-M$RqN1|8Cym(;2NZEibc%{K6N$U`groaN|s8IupI4XeU1L ziJ$q*XF3erceukHay&8I>Q=YP_Sw#Mw!7c`?#|p(o$FlZVs`lxC>-E&6<|64MJ{p? z#zDsUcIWx6NTCnz9OEZF8>{kX_PfWd`E4KL)#qda0zkmx7C;0ja5*99tlcPhms5?s zS%qaBc-!0F2J5bPX}xW!>kV#j1FL_hqq)v&jh>6KEUwLUrVMPKxy7iIfqH@lhTYtMZ8)1O{`aU@rtlL-z0aS7mn$o-~n0Xpsx zm;?}@TWL7jS~n?Xb9{cvHiNk3EpKVHma0g^`^7JQF(&-AuYJuLZ=V5uWr=yf9q)KY zi}LKTZH?Y%oz4NV@tfXbbbY+l= zWwr%LmY3gN;u4p5*~?zGT!rb}P9``21T4UDxmNe!$@*bSo0HAA_|yEyR|mGb&rJM`KGGD56O|`q zV7ZJ4lOU6rvvWY7LzrK&M@oJ2lb@W^;P;iid~3Qq`1#IvKDmcNRgQzY7dA21um6f2FiOwKk4RSGtRV4T5o7tN&vET z$+a@+uYUC_^}PT6hvCmZSD4k;fdGoa0wRBc>wfpUpI8Fex}BxQ5dUMWYu$8L45Fj> ze|v9OKD5X7=Z$?3km+;xDNR!7me`i+X1iSncGi|tkBK~1X7y+24~GD7sH|l? z=&heXpC(m0j*I7M7i_oRZ#Pmhz>7WZagUQtOV{4~<~Li*iS@tz?Qj1q2_W$DYDAJW zIx3e_!m@g$y9@M(_4`YOd1;yp10+H5WqxEJm{Cc;wOs1C&wZ}IV%RX0^g6WGlm{}b z>*KCOpK53#Z}LK11$JDisc z6Uda3qD-pDwmeygZRCEN$z)@8787-s74K1<#aUrqdc5s2rcRVn^-NE5#uiaCgYqFJ zzUk-(-^ue?xILlw1TwI81lEvz%JT^oM`6ndMJH^ZY-~w8le*(1B@Q`l#g;2hfkj#o zSY$T&3iU0eEG+V?NOo74xApz5ep7mDe_&DVGEnAXI!n81bT||Reao+!=)2EqbXivA zT16gZTvgMjJVL&Tc(T8+=7&bW^_er*ID&ZWBPKGfB=nFuN)nm4H?NQBG~wAs-Jp7) z{I#XW5{g5sKqRr%{VIMX9IrCbH@Qh?`=hvQLC~n0PaO}VEo8OHXiH@tskoIZ>wx6%Wb{Nq*%qig7Tu;vCXZ6j!s46 zs&`T6eCCFyLkOkNo{C|rb~HVL$q1CSfa-qz$yD&naPcZpl&wE$aH?VzfoR(d6>XYN z^k>#z4#OcPVc48m=!Qqd8fFbHUZ{S*xoLgOK?&j3@ zur||jQeQM?`>C8xc937i2v|S@#uQjpKHkY_lrEdIf{B_NDW5gWb|rO0Ov35qXOAU7 zS4u4yO$%7O{LEXDu@v#?(`Q_r`N@_%yJgWv4AcL_t4w(mW&3mF1UkJZBbTdrB~7X= z*4xY&P;b+~+jvld?X-zW9%&*JvTepum4?Y>OR0IuDdX|O44vekoqpdX7r%eFJkmWR z%r2?U46WH-1XJT!a-Ici-^OKaA#T*2o^T1alaASV+njBoX4d1E&fSD{;-1XsP^Dqp zRWHLfE+~KQY{JwRMKHCM=KC`*nnu%nf99Yym&H&3RCzSRiI)$jd|{I(2*(2QRpV_! zZcJeYj55fVV4Ezc$xl?igz`y@t>2$1=A^JqR!<8#2b6@uATNvGhIO+}>5XrEF4wMt{OUv&^RX3z47ZHo(p>knDc(Jk55B ze!P5fFK53tQQCeDVp)_eB;=XV$K%hnRTVLn$^xC1ZN?!6d3VL<_yX}r!H5h*Fjeed z|N7VB7&}nwS4D#OT-O!rSX|T18FlyZJVAdxMsc{+)_ky{j%ZnVE$L&Odo%sHlInF2 z=WupXz`JZ*vY?svw2ie-&Xa(8V5Ttyg|Uo;1(a=#9oY z2kI^RqaTCVT0_^pGeKISYy5s!UiJP{7;{CPe000)T5{7Ssa^NR7bP94FD+ZY&$@Ie zaEQklGLK;tOF!YugR0&|>CPyB9x`jI;h-C*6gx8F14S7xT2xHsegLnKjqqh3fa4Q&lis z8Fa;4UqAg%Dncz)&Wv*wb4uH<3yOn*-oa;AT9fnl)1LM;Uw}iKSi4f^%+SE}=}%2$ z5cshwCd8*_#}&Zo;E|B0abtL`I{H{ZwPR+Y&{q~GQO5}Wa|t$UXG_k5n1#jzFG_$# zOL7&=%r#l68KR1SIJwZ3uY6?$#p(CEhzt6EY{uD}s@8WAu%tjsXR)sPP?b$FRuL5t z=7$-fZ!n(=U=2tUY?)H1sRFC$yAt%#&HYw*KwwhZg{gY%%U|BT zxC@48GG{;g*_HJ%;8@IQPIDT6nj7gdbet3{E*z7{-mUqq{my^NQ=ZbVW+`;h{Q_MJ z*cNt{oTmZ#P^BU6pN%L|(^+@Lki*^yaSBnwhCgvJ7`R*YV@)m>Yo#IRb6@B>P>ZrF zjw_Kn3^5peD(N#x=(mU*ZW6@P^CTqVZfexf4u*Jw6P!TZe93vVcbvq}uXLp=VO=EW zIn}97rTvf!4{D;qJ%{6Vpbs5z0~c|Ku+7;muwcTF+WAuxh8S{{bDZNG=sjjdehzSk zu6yUopqc2bfbR34Rz$TdkB=hxhR4Z%DH?xb(oha*ng79($OakMNh)LmJI;r~whV`{ z#1Xqy(3^3oqcJg&fNr`NNh6oJTmlgz@I;tNYk<&VcVfdyoH-SUOJ4Gl#Aaizw&=cx zGA?wX3sGd9kmx(~HCU3@LqGeEN-7Qy?ojH0+p`b5P@kK1XS;2z78%7IsK(ipWk1Wn1%%uRjGGl_NX&mP`$Ds!R zI!w5~7{ zo5tZLgptkUQ6<|c$>(5&nZjzPxf9S+b{=1t{pBxzDcP6u%XVxN10!Gox@($q?yXe^ zIgeD8P4Ji|ZNnwqiJqsaASFWILdfPTy_ECb*ZW`}Rloljoo^Ui#9Pj!DsOnSx;EU7IF-(vw`EC&c(1~?(wdJ%9b_TYEpa31na#@}M zqV=Gx-?yKkFbmI0K-`%fz~EBMF)PAz5|ih3gE-w6|AKftPpg=-sIE%GudSU4dTsbC!3q z!kq5K?Cogner2Ev;4#mUdMFY4B?Iy!Cw>$#dqIh0NLKS}F~R8W>dE;AaKw6{vq8@Wq)}$Ov}*iJC>2VG)z)TYq_;f zKP%h)>zA`=JZr^q!8_4UrGBgLheLU*_0{x5@{IbQCYP<@G^FiJC|g6`8D@8K+44;8 z!T0kVj!{x7)xzgFTxW41QAHm6c%Io>NoR4ND%<{Ssx-M86_$4SF?JS{?JUKE*;ZUC zJWYP;@n;dOy{#>mZAYD_?ZZf8_H~m%)=6zWOnWJ_b=5F?xXwwu{7iBhdl$l5Yml>u zzhJ$!hAnAlar8OuBwDqwyoh0+sJm2{TVm_;h}(>_d1sUL14qtjXz#EE(kYMnyO#B5 z2d1uR+w*G8xfGy;wOQ4g$!G&|!sgOzY#%XF+4fuNc}gD&n<3d`bYiiFh4V9eDQ&03 zLCrARMZnTkKN_c@ERspkT$;4gxd*=X_@}1tY|^$ukei%*sU^nNdrWnXi!WiMPp~G~ zE=-=u=gAA&c6L`1Z>K?&zg8J+Q}`KUTj!a@%SotOn1oAUo*11Z+3D67YHmBX zrN=H^+-0e?O?4)JWTyOw3%{iu>=aBg%gG_!a;GMnVaYhVl(SJXPs8uhSnrCr?a~Nf zTV*RsQ}^dOAi5v@KGa<)k26f>K0@8}C=q;$YRkB)z!v^U+rKjoM?B4oa_8Ii7sagK zpV4(Oi@up~cDTxBXnxtWazVcW_)~ix5XH?L#US6w=PAFca4(NGHWV-RF&A8uQ?(7t z&3T&Y%wo<$RtV_LH79dzX8In#Hm3inHB6>SQvSILYo(z9xtXZxH4SZ#x2;6Vv~#Vy z@b~9hw+}$T_P|bJe&ThhYB7^Uj~G#7Z0pzMaMdrho70fn9CWdOB~5D7?ZR@__m|)? zWA8S`?kv|NhA+LUot1`^lo#&8jJn(2OLcB3_a}A+rDmmv-W0H~2e&-6>U*RzE6i;d zENq5m{j==Tcra-^OO>r4|OLxuihxNK1#S9%<%6 zGX>hGyFxp=B0H4x5Qs7|VQQ^tr0g8N;_19VV|l_Nrz3y$XR>jUI5<2G)w(4TOz*$g zK|?V)X>)pUN$z~Ejb~vl4_3_T^uk>0GHNN7Ip@x&C$_pjbIRJmvap(&{{EGQ*;zd5 z$)S|kQrFbtku&5~v!PNgFP!xi#sfA7vzo~z)AQu2{v3Xp_Ng`#nua^kIr6fHrR30c z?6$_)GA9u84ysw-X8{V`8e3YDuA&h%7h=sg=L&1__{lr#_i-aM-L%QBaD^+RuUl!& zlEdLNeYO&pBwLI`qz)g?+Q6Bb$fuNL9gyTOQCZ;l|WjOTH8{MpUg|w z(=D5@Zm{j`N~-k(URRSNIxa?{P`JmI>}Qdu$;dHw7LUp}yS8#CbRUZ?FFl+u-^&Ym z@}3yzqml!<`6wAgrguHI;#*x=6fbMhiRlt02i zxw+o;u16S7s~L+h0`$^J>|_L#fakHFO=!;=$O`a^MO7ZzyC)6OJ zlB}GUE~GiUX2|-*k(yjx=<0cyjjK*y6u)n}TI5`W zd7u|KKLI$BYs%%Y7U1aq#dBl`SU5oN2UBz(Oc+5(5-F}}slycI2HC^`X*v=iMEuH) z@JL*ioeoBHAT5%(#x<^?9lh-=5_VDy^aYydTILDFxEeErI7@XSxvulOM`q`KT~10v z!%PE*%ubRs4IbDXg=1<0952n#te^eGl}YG3(K2+f$p7nk->SlBwe1L9I$e$ns7L4GF7&WNA7Q4#l74Hu?@_XJ#U;^MuSpwM~`hApq)P!*c+6c22zU z6UQgs(nNpK#8Q`Mg_$5tkDRCob2LvqROlx`;)J7f0Z6XQIO>|+D;O3X% znDqe<%MR!@9@Wf56T?C5qTHqpa|WV>n**U4L75#uKb3~)eu~UuUdXvIcgoJKMXy;N zU+ODdKbRyD;#3?zL-ZjgVWKVs@t-&>K+kv7CHCSF=DlpTNhNuGQvUdQ@rTNAnlT6( z#5J1@-3Lc<3Azs>cj7__Rn#`R;|AOMpyTRELcae~axKpfVlSB&}0=&Q$UAQL*w8Ke8rcW0E+ zm=n0&Du3ePFLMnkH3@!bk;x!&5oOu#hs(CjUpv^mNyQ$K6L#V-9H}+|z%lGW53ZER z#)kL@-UdL}a2_&iWcO+mLYk)UFlK=>F34YEd&TsLO&we4f04Iq$%uFTmRW zm0uKrQus+$TibR@T>nggTGZU~7-ng6lJwiK-L`F)C)1CF&$GNEAW>m1)236JZI&(3 zVU{Ag7IVLIt(&?_1oWnyMFcmso@;1jI=RT@CQbgw3@ zb8<;$(QU4BmjYb8Q$ADGnPWCyb{3yw77KgF&ceEru+}AX78C6}XJI^hyi0|7kxF92 zBtW$N(&BEGpNFmQb4D~;NR)t!MWQ8P*f1;^d;(pljBf$`gu9DaSa0jbE$nQ$Bqb;; zY^pk$cD4Fw+*bGVrsy)-WV7Mo?Z%XEGRt#wxv*uH&xTjcqQ&6g9+f?m z^Ykh8yqzRZtoP~lIPI(;Ul^vb;P{Knp$y~drTw^;(JUMJzn z;&CT~Valex-0An5TsG&)o31mCT5WCLNHVFiZ3VQiyEJv@@~YjHy7iKLW))%fX_sJI z24{fFD8$=0QH8g&KZ~~hr|;*PUG+(C-q~W@=0DT#FHXPf{Kfg~_B@l*Fgcyed-)fV zVfmr+l}THfEtK0W<6-u~DzGW1xTc*^H>NN-CW#HRreCtcws|`p-E>e}Bgn*--uljd zdOiD2Vqw==hpKF4_7tg77Fsz-ypAwuD%pG{^J_x6bP(&@m#8~wZpmb3ccoOSW}nS! zf^Ww1j*{)OD_L;u&*$0MOkeVxc7P|rB&p8KcBbyPFSazu8j26S3Ah}d$?WVqG)kw9 zBifP}Vp)r4Z$~A;t%?7nY$g~koQCE?!6gnMPHBPx#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBU@8%ab#RCr$PodF@*o zfOhac{%ZreF1lW@)jnO;xgH)KFBtLMxpPmSKCSAiGn9}p6d${K^;r{Wzy4?K z?Ov+`ThH^$-|@Jv@Vdo|7n>t4RH#tSoH-vqeyk9fIB_Cv=&4hu)G(=Dz51d>i;x^S za%6`N9n>6>A!G#NPe+{ZyEe#v?e7uPZAAcxb9FwUE4_KyvSn5f=g5%*^;Yh@bm`LB zvSpJ+93CDX8XB4*@Ts{-fw<(TOTE{Hh+4W)cQYT4J?!tdKJ@z)x9d*#%hltQuGWqv zOO{wc{LMGteD&2=;>739ovTx)&RcK2B@oBQ$M@~qmye%(@(B*Lkn#8TuTrH--n@Cc zbm>yATsfh|ZfF>SwUX2lI? zfBrUY+N47#QXtl~@v1g0P}K56k7mzTM4`+!d&IvgP7VBclyBZXf9sm=UA1bJ6~r4h zYV>zW^0uwa1|#Fs8z!Z<8nzC0-@ z>BA2{eDL6bg1BYNma}Hf3J3@|d-g1SLIgN>_Uzf&BW~ELEw+UijTT4!@WT%sJ9ZS? zjT<-S`Td*t)SOEo&NjfW)$%B%Hl2O5c$1$%%wM*Z{Y{oc)Nl(eG4hJ8?J<$5t< zXnXKsJs+t959B z#?s@(Q=+w}(Eejmi13tc_Pwj?Fyauj?HXdW4@(L$Kl*Lkwt0GbZr{FLhlx;o66cna zLX4dx3_#htcdriK&W%p(-Af^+$pP-Zef#$B->)P1Vs?_axHyasf5m=8MIX<}ixgrM z7eh=y&EQd(X)ysXLO+!%RibN0j`;leAgyrP89#eRVp<3bFG z@S_s9q`4%{OTU?&xaC5)QKLpMty{NlyLRnHj~-1|oA@uWU=hv8&_xO{PBeURCk##- zAdK()yYIdu{)>dN6T}31i02X`u359@*s){zm$$b!_~?M+AuF}GCBjA-y+|RZ>qf^1J~U%GJ{aG8a&j^d3G1|N+ZMlCXmQ1g6$L^1DPqiN z*sx)YA&CPSqa!T+=bwKH#KzH1WC*`ybhzUBr4ZAxUA=lWs%9`0MBgnDFb?$g+i$zN zx(dWfNQ|~oAa38jefRF&l>-@n6J7_1F(Ar*r$vk{CIEzbLD>+au&QMk5aPVH5Hsdh zyLN4HU{q8T790oADq?qccPG?hqBU3v{5FHrCTy!H*Pj-#-MV#ahN5jD1}K9}zP`Q) z5Klqn0d0wxu|6|fpK)TLQw?D@heRHV$26qCW;p?j;p|^l5ifZ8VdIFZ19~w z`sgF91l<_H&dgBY71C5P$e(e^DpxLrm_{DBsIVbMVHRn_yJFPccs7t7Is};rq}s=a zOjuZ$vmr){39h2DhBtdr%;O=_MhFZ=HpGj~5Ffno@aW|zv9r@}H~zlI}PA=7%Y--VlxBOfR3{5#V7cC66i-#kOzkAw+aq^}RGehwpI-%!W16FEK zSloY?+!6xeQ3)Q$!oU61p9dCj_sQZv?zNrffB#{^e-|4B(p!~6ESfu1nAxp{V5S-3 z_S5|_4&yw6D-ZF$6CPK8w2y-L$fc+mTSHq;yx#fu8__X|2%vGX@k#6vUt-l3+d_;+ zi=%e@6`>gJlitxhzx2kJ>ybi?ZD0x=<``YJVkkhoVDG)tK9Bk?2t0PhU@;WLkDnyn zx*z8k@~hqoHHLOi zL5#mKb+f?^C>7zPq~zKoQmm&f#KQho8R8ulm7o}kOpF+hg7ru?JqoCS!}m@su0^e< z-kXAW_2Dp|JF!j28C(ULJ}Mhfo3W`Vb`{uj^N2T17ed% z8^fcPwwOKW-Ov@c#lIB95J&ZB4DlR-!{dYrrn><+%*E!D56<7P;unuucZX(>#%=o6 z5aZ@96Kk=F)0T!v8~TV-Vfp57V6q!26dV#C0anbQVhHS3cy(;^O)`XPnbB+_O!h1(J_i^9nMgHn@c z%k#Ni0UCbNOe*4=@a^`s=WqL2uT(;qo6qbg9sqid2AS)8{x>>QL zAy%`JUxa~DMxf2oNm(Lh!I$WsFc@WwIMXcRaD)~U24c1q?gT4v&8KjiA!aQYYdWyS zWCiNkv!}8UEHf?Qa0FtL4zyW}!cvPFqGpLG$(GP}TxOy5nQ0M+gAhL-yHk^og2m8c zg)PgHlokG&W)X*j5I-OFFkWV^@?_2_Ce`&YS$C(!C{${U6k?Ngcg9N_Ri4Z_#nO&A z9p(T{pN~)qF}WoO^`tCq)I#zqpQsdKF&ijlnYm?dAeE#vJI7-12>BWkMTz)=v}%BE!%F`2Z9W%K1k5MQDen-~g}%^iq& zJCA_EyF82yMXHGV_3I}N#Aqmn!YX32{gd)q2=nt2T5Kzu7Kkn1Wg(6wI~18I8FYAA zTFh_J-c%Lic@#=>ck|{=-nM!F{(XLfm`?SG8SW;(BN_JSu#?BoK4NAZV2c@yAsAS+ zXi+8?2wqmRX<2=j1sS@?hRspDw~4j%FAK4W7F*h4tBAQ)(qLi=xO198^@w>SWWl2K zV&6m@t zzXB4ds~0ww6feb+D(L?3;lq_ftY*`~=v#6m52eUi`(ld}V!}Yrdv{h7I=Ug#I(abz5Sg>Ha%4aHtIPF@j9#+~UnSX>wL1I%DXs1E(({@soM@bN8?Da15)&qtuOsVa^@tZ16k>WCB8iyc?KIj{6-OXuISr#8BEPQgmtTHSc@8HRlhtBg zcOn)oX)nf9t2t7LvBfNH)LuHF7Os$!LQJv*G3t?$TvzT?&MGa1*rd7BmeZ)z87ai{ v?r#Qu$Re3%q6q7Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBU-%}GQ-RCr$PoM)^P%N55>2hkx^(K`Yp2pu7M69Ul`A({|~-Vwcg z00amS5>2!Z6wyHsC6C8@d5@3=gf!96+A3EmZwg1*y+hRX^>g@5AzgCg7;#7hySm{P-`!@~e>iT9e;| zv!+oefaRp44SXAxI6}r?-?wjHx)1bOE#2qDT)}E!GPlSiWH$d*s#Gaj zwCImQQmIlU+cqs+xNyjjA>4%~=g*%%((S66?epVR-wHCo!j>UvwhWg-ZwHY1QImAB zc>DJ4<;$1Ttrjl`Y@cHVnesoOvMkO(@UP`-Tmp+kqFpY7YXU%YrR7au-+SfD_GUAuMx!J1fvK?ee@_fv9co-o3dZT9!aEHa0DDwo6o4flJF^ zwZz)7Dw2M(J_j|%KVP?P+t#&f*ZcSHuU@^nSFc`jFGP0b%9S^6+=vSUTZ<-hap}^f zAiID6ewbTUw(=-1!J9$*7~Abuw#*@ah_n!KK~}wb^&f`>S6BMkv13P72eJ^(2a1)c zw|Md5!s-ASOrg|i)TogxIcwCYF?Q@&{ozJ}H?}@!@GdLJWFIrg%K99bE}LDXND+7o zwn9XNo(3|(7lGhrCxt@3eEFoHB;m}WYKawO&cH;!B*ws{Wl<wUHE!Ja_U+r0;WLm(T88;!jEfaxM@q(cV)^UXw9MII zQXyhiTK3|_3%ZSs$Jnut8D(HTd-kk<|NeRMg> zH2qYDj7=&&R@!W3%N!y*#bo#l$@^?mP9{x1%96wCSZSFPk|$c0B7f2i{B-!TR7jrB zf$4Dns2KZlNDdoxe!62dFrj_emkW|V8JRKtG%K0wSV5K|vaOvASumwVWQ(GC)q%w} zffU!SU6WOJ&J!ywli1>j;l&&dARG*~r%jtSty;CBzzXRLhfGu~7%OXZWyg&hNBG>` zyLSa9XhL-D3x~|vF7ZNk?%lidYqxIQgoZ?njBaNCNwxzsEh3xH0+;uXUE>s)#51{s zNJIkaFoYbkfYD~jO$8TW3k3wG2M-?PTo~a~3~l!PU}Z~`C?SN0oDPGe9XN2{j2ScJ z6-GuksUUL#47_KUU{m4gjm_mJ6a?M^Y2CWDL~^(YTROjW>sGlPCQ?X8j#B}jYjhKv z)}ccO1(}!8O)AJfi!XDzvZ#QHN0dghGctVma0(+wjx1BAj3Q$N8W&-!6OF}+6~q0b z4mzbEBSduS)TspKvDKpDMve4jQb87N!33W}5U?IBM({Z?h;#tHP~QQNF4;m>zkdB? z%a(B?h-V|nFh^-lhB3Zu^5n@7v+$4tih_*g0%W0twIf6&+CoMwHlr0qhNK)bW{i-I zNb+l0I-7EEhtsD|FI>1VY&G_q`EJ321=2TEgW*=MUOj9)#>f^j>T}G3O)0osHuNx> zd}a&C947u$h*=D4!L{kwL{fvkD+=48KssNvusudi9N=86?7q#XoPqi#|L zG8N7Uvg+V(B*-EqJupIMB!Rt|5R8Glafj@)qY`pjLVt(k$$+F6eL)C$Rcr@|+Y~f9 z&*cZQNJ$TjkQqr}Zzcp|;BMR@bDRug{xTVu`dd*eVaJf2J9kR-zi62XDfU7(Y0@OA z#vqk}87b)jkcs_*gCxXV2Bwh&mIvyY5R8Glafi%_$QI(?J1||4!JuO4p;8e}Jg8t- z9WwSr2nA(fA*0-2En_GUsb2JXfk zG6`cr%wa5EEqn0b0o#t~0{f4hI&~uVidW0H0+)-QK{6Z4>_XM9U7Ni)Y|WG@Qv@=^ znDl@&5Y%LQ6ho=ZKb5^Cus0KeF>p8Tkg0T#!3+inGk~9W{5K@gYm)Xy_5?(t)ORI4 zz@afRv|bX}mR3VM@MY?tv_xiz&!Nt>s{JRfc=PkBeFF-{Hc zDoL*^MXxJYucYf0VP95#Rk2{gJ*Y&zDpxOS7)eH^7gV|}xl8Q51W1XboyT-#DHase zelP{WLUI-B{r5ru3Zy6&k+OaTfFx;xh>nZIpt`ab3py%|v1+$8JyK$0>8HTt1qh7v pe8#eDR9T7@h007zu0ssI2t`y$g00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBVdo=HSORCr$Pod=i|Mb?G~cg;Edrd@T{oO3|TS=WehRf2$+P;rfz z1G;8K5fL$ALUIn0lYr!5h?2uF8I0??uKT~;r*GZ5Rn_6n++k##`}A|4>gvFj%Yb3ujYPJ+Miu>2mgH>`S51F55Li0n)O-# zN1?7<9rvN;0Tx^Z;JR|o??c{U!p}GMrm+6Y@YA}~udXb2BDeR!1DNH|roC94<+J}W z_?&x&uux!W&}sl;4Q?NBvR`1i@wu_HmsA|pqEB=?&h{0$YuB!|%Y}u7`T6;?Q$NZ@ zMMWZ}%b$Dhxo^Gomeeoyf3}RXeWRT)899f7f&$K`D(%$BzIlhY7~n0<`v-;0@-a6L z{NMln_w#@L`@>KFk)`{XiylT{pBH5*N`zgpAee=MGcEZ~K{`>FYXa419l;3&h z9eTQ(Z@&2!sb8NyeQf#Nci;W#r=OPkE3drr!V52qXfy0sVfE$Z<($LD8*luFKm38h zU;gr!e*OC8u>EY$CtLZv!byf7f&g1ImQ&v{SIka!z zzM`UH^5n_K9e3RR`|l5nhMn_otv>INCOspTBb)aIyeB`HZpgelaKXo4d@YrCwws8| z5zTtZYRebL&0n$ZyB~iZK6Q2d+xkVf&s~f7b?n%Yo4aVyB149oe%D=h?Xt@*fBy5I zUwGjK0Dk=O$3^CjJMOsYrkf}{`|PvZZo4gS{y_&F)UsvE=mSM;U9)Bl=kVHVuZhgV z4?oQ6f&~kD_wG&0Uw!q}si&S=zkYo-@vcAi*kk+bv(MIBZ%xg}kt0>JF#OqPpS{gC z+Z=uL(L5{c$b-mMyOF6=r#5NQB03!>wOeuU@@qVYl6Od;a<7OG`_e zH*dc4&O4)_*emQ3Jb({w+#~E?0c^+&oVa4dwAHeg0+@2cM~1`aPj{Jd%@ZSLEh_If zetC5J>a@5!c3A+PG-=X&|F?AMQjvM!fd{tRZabhIKYsjm*IkE<0{HUFFF*hM^O2c8 zeL7cu=%I(gsE9e+7gVCp!2o!_{r1~qk3HC>OP4Mj_t;~P1@eId2hz@i4?f5v#hDBp zI`q;@FWq$0O=r%WNj*sHyYIdSAAE54?%f9r7;wZ9N3bKOXE#F4ph1ILw{AUT$dJB$ z`=XmVb?PLi$93`O9C_rCojZ31_&@&fk6b2?!p9$f%v0W~RjaUT$vgDMzAT3{_5SVh zkuCc3cK++%zkK_{&n!h1KZ?x2NvlRqUnAu^U!RQ3kuCaB9`NPL8DE!6{llH71NPy~ zqS}Y+zWw&wuzxO3_ck?d+!#r28R+t+s=aukpLpU4Y3GV7uDIZW3#8n%Y15NWJ~^WO z=%dTll9Ce6p;4no_uO+2=%R_cb?Zhwcb0l!mi8eP*y5I3ZjrsX-CJ(CC0s)JqmMp9 z63j$$*sx)&qDLry^2sNZ5pbT#nP;BKg& zpgp8%AOByLjIsdycE1G;A0657(NUK@GE!s&U?~g0M>Ow8dEv@$3d?>NKf9PEe{lu% zXS5y~(Y|uyhg^{f z3&4N+)1OX1{d53>lchlcSWb!GlqpkKegFOURh!74bka#&OPe-rc$;ZQu50-4;Yb3K zYJ^StwZs3A)17zTx#ymHayj;OL1wf78OX7CeGfnU@UUyiJE&1NSq^U0-7X(~V-G-j z;{B{g^Rhs6-nndEQ`@pU6OE=bd++lzHR1#S!g?9apbky?Ql=d*zi^jCMZ!@I&g^ zD)pmAjbgQH*RE<`I`imDw!$vF&7deJJb3V6B+;6bKltDS)rhnMCGa#r!aTvpAAkI1 zmtAIG7aEL*r~yuT+=K ziP~iWmQme!u|-+;GDU(g<1>U2b2O z0$4T)!1}rA<-CKM^ggIbAOByLjPl{l`+9Hi2Q!TNffHAbm|iIIt=diU-r#2J*yoz3 zM*sTjuW$EXaPl344{qA~;x@yNY|%HOeQf`TpLDXOO`EnP_2Z2}p642MNPlG9xN*F% zn{BokcuPA%(Nb>Lt{wdpI^oeriQbB8;2dbm5EISH)28aLz4lra*;Im|Y;a)z>% zeh@#P#cZR4%_cyi-fo0$)I}Fvv~uN2I#Vd!1`Qh6*M-iah5r5f%ck3Jza4>fTtBoWdQJvePp%u8+@%L1_e zgS!wLJ9aGhi+Xxns6E|G0$}My^W&+&Y=!YKC!Fmg6I*ZeqLsY#qJdwIMLmbR6RLeQG$)3>Kp%hp`RDA2uenRz zV;xBQ0&v*1&-i`5xw7@2YLTJ)_+;`S;G1VwWA(f@w(uj!ghM`#TQkVD!PxElWWgA z;D&AoHtNp5EbF<<71sT#^$z6icTE?6`7l*juVwTNmInXwt1IXHKICn)&si+n?&~e< zzudNMTPzCs)s?H`KIE-hz2q>>VieAjqqOp$d1PJhiVX=#Mp(vZ%^Tu~L2al(1JR_5MGr zYN1A7mEDaRYc;RxBoN+0@v1_WFk(?#MMhth@^4^SlR5_}@Gpxh>jhmvNmg@V^_pT9 zPD%Y61pxjH+{YZAgMvi0sUXp7su>LZrl%hZ3v64=sL|1qvS8_iQ|gTcidIbW8!H54 zWu28>A4gNMJXUFe;><(qtEx;v7LMWk&DZ)X0S6cLqBSh`}>GzCbc+RWBQ2VY`HitJs%j!O$>}L! zDd>yZYHzAcO;Kk1#wv%F8ud@XC`(Pql9ze+BkpqOrgP6bf74Aj8#C@p)zpwLysVT( z;B4LWs?^vJI#G;8C=75A2{E&Ci8x(MAF0;)!1$Usas<(MRe4|P^lOen`v0z!|f(x^AcGsmlI zO>$1PpBsQ1UUB7?TWY&0Dw_fr~G>^x5ZL z5ahac>v7{-Ed>dt%z%v@y<5g!X+m zYGhTfq^wt}O;T?!vb)+vFL?Epr)Wi(Q1q?0wR-aDXExhx^9hr_g6M{PF+x%F7sE&W z@sAs~efGKj1BV=S)X_W&2;9{2mJ?5`FI0I$qs9ogdH7MG)<5sL=O>?iuDCZ^7aC$Q zD$v$;5z0)|o+;pw9=xP6CuMt8D)mjejI^MdvdjAJc3JHnEf#F8Jitnu3c$RsM;vkF zNexb>Z>0d{j$d|p!()#GtQ(u zV$@ieV99d4e#f0` zf@U|`=npTv__CsCDxu#!NGd+#Ocvf?Ue+1;bCxb&1;9`@U9;VG-@Rw=zFTauB|x@$ z=#fhEFKW8^bDM&P&0+{m6 zx8BAp_(2yhDI6V)*uMMicgm@!b$ILT4sUgmW%1G#)HgW!lv{4Q{jn#WYSg$Xy=~}y z(2!wAAAL-Rj-7l61xWip6HXmP8?B^RZWvI7=-`->PfF3YE>!x@qv+dPi2$q%<)TLc z7$B*kW3}sUyRBSZWVG<$Lyyq&g3{mr@FO%4dL3m8UwIGMYlK&sC0nY1YnZrDggHzKq7y=R(IY7Goz=`vQp3cNuv9@ zawys!M7QtPuymCXW!Ss6DP`}d+sC?9ZJ5Pj22yrLFkO%UU}bkE^c5$00unZ5izzki z1gtV1;|LeA)1l$^a%AV_w_GA&@c^f*#3`JuOT?3R>tLt76y`KGge$kNZg=TC?{q{f zp4W9jZoJTj&)FdVFbA?7r_0*a9O_JVIhjp=q^&_p$^)Jc0JiUMY@8tH0#1x|C9Ui4 z+`wroZ{+VkO-bTynCrRy|#g=~#{9a}LwO{TPGG{W*pxXCt2a!iYsH*dGy z_T+LQBCv4rGFFNIQ-1e-<`SznW%^9Y z^A|3zS8t05_Mt1qzMHioT`WepCi*{-zvX`8;kipf}!qQdY>g;u} z;rBN>SrPUzFCSoZ>inJo@S~4ENj*7~0x++*65y@9_V3rRdhh)Y5(5T2SvJ{ZQ{Ges zuw-Vjkd>!0^bFmc1Av__j<9HiZu?f39UPk-rau|+{Vb27m9b$sfs=TZfdL>NdgL*K zqMP2>3~H510ETIm04n*4E3abp?tAVf;Lj#Mp~qWD(NYvm5{R5wqsC3@*FQ;VjU4c^ zt!SMAN2lA;IaH*&%p~39Ra~tze7vQU_C-6DTyz&qFe9VmulwvnZ%aW4>L}DEO>eXT zCYuA@e9yi2v#I0T-hAKmt&As0bTEdsoRR|AFoLr~+UPnN-6$PPJCWT^Vb2+&23oOQ zu*6;tKY&fhA?>QvdDu{R(VCbn9GLd%Yp(qoVAqt)p1XiN4U#ve&zdbe@&=!J+Ucwk z@V~S5-2gmk$~5W`r&C@3qz0t#aKvdd^CwT8ZcsFiHIJ?u(aumwjKJh{VW79dC{yOM}{nYr4vp#al%9|16~0P{Mbm_Y_lyE z5ihQE;`kr;&TDzwNf$wR^pN7{G>so*ZD+Va)JsIMb)?tZCb`k_--5 z1$MjwE>yl~+dZkr>B4LzqaNdD=&+HzrbfN!U^tw2w6LhuZjD!e=Il8JQQHh$C5n#l zN=7SS!$X-fa*kzVLqOR@dVMk-?DXC1otlIIhlv@TEL|+Zkz$;cj&4M-AyhHj?h9M* z>h25Y(6Jn#8y(`cQLk!9I3p)Zj~nJNbV%AI&M8I9in?vLsBQ)6%ECdj(fT!ZYZyh_ z!$BiLzqz!O^!%&{FQ%T~6Hn2eFIopxzmEzJ!$eM^l6453@?pUS`vj8fT8CtW^SRRI zuim}NCBO!#5dmOl%3mnhj+`um<*LZfVY@put}SdBZ@Q(Potb2N9}S61B{nEGN3Uqd&KJ+bxIbS3?I^QVlz;VLj@g2MpE+im^e3u&!1Vz$)X; z1K6NwMUu+y%!-r4gbf#?A!e)IFdt;)IowdLc5068o^(1atC5xy1`uO1buf(>^rxc5 z9>9i+!?=l+130TbnxQ`JURaKO&b9*9ty{zPt;R@0LcMDwPV1wS)l1sR=~}mm zW0Y}5JlN>MBv-c|f7%sC70Eip`5EWW=R*JV=RezyX#Ei}f*iUsHa6MXH);1O!vAbw z>_oSE;mp?LwUu!Ow7T9U&L5=0fev@Eeg+tIBz zXqdbStzNeeGR*!_6K)tLveT=aOGO*&eXN8)f`r*r##Z2qj`s9MpbImTRl~dsVKRC! zIKN;X`5Vap-!8l0ou0d3k?ck6fux`9x8H$Lrq4b9qI%SrjfGSm+}F5D=FD4INt@VC zWY>F7VOYju94nACAQ9WQ3VQ%Ft{gw!vU#Qm7fx=OybUA zhaFCS);pcw+i(BX>I?;x&9u-bx3a52&w5kgOxOd+H0Q`CPo=U$OeK7^FOxz*SUl!Ch zt9|+nq~+s|JKjqHC<$hKlrv$%CF(`^wb$PuB1xdaHq)~}-N>D@VNgnUeQVz&`q&8m zJJ3~XIKvJOQ+Q4tY4fm5s6#fLA+J^yMc?;88$eR?8y3u4h~{QUKg8Ri zFK@oJ;OixJmoRMN#5RJgKCbe&pry=`J zmQBu1f3NO7w9AY{Vk`o0BuP1VIp{6l)+$JZ*3F~=gNBlx$K1mt_Z)iYVd!t6Tsl+G zHD;2iVRcF*_vq8}kkyq)^*V=u+JRn0$kEBL+3|L)QJavQ^_ZZ+(($8`Ja@F%!KCa& zdlh7BLU%MNJG^$vy45`=y4z$%egQo!!{N;PO}!I8UU$*H&L!jgo!$(?4t9nRY~7rj z+^cNyj*!=#8}S%}uE6Zj!Br=1#qEa4q*@MhN8A3(EC@MF^*YBIIn$dfY2zl0>?Rbm z%^@|9Q(QKds9sG0d*MR;p4wJsgc>%$(;X(pUa`IuIj-?wRo(?{CtKMO-)hG)p+e0z zFIuMA3Y)qs=ysX$U^`l8uxpqJ6iwYmAW}DBZM|UBL@N$AUE5Tw+q;Hh&SmCJM0!oO z6m6(pd;F3zkiuEo7(Qw{C?cY>36-%@+eQ?@S#Jb6BA&LW9+s_rjS#O5w$sZ|c?WVr zENwBp#@MQ7;;E=`f=GiF^LJCUPLIO3wl=ldTbI#U*QwNXH5{QPlImdH5K^{~Zc`by z@A@!@vWo8-!a}w>A;-|NK2?@(3J1REObmiaw{>V0V9^~Yr}kCts3*WE*eGVLfSo-l zBdyM`hGSjR+3D$6e??ed$>=)Ss|xH$1+02lS|`gJn-ocj-mJ^ErQ|f6!mKI1UT5q? zW>0K-vl0C@SU1cfvh%ZYV-#g;<2p62ZT0FkA$if6dRHZ6c|%vc*_gH4q#LZxUQ(DE zwjTvs0V|m>y_>vmWlGvXUtKFl2NJS#WmFo)gz4-?$I8~wswTuEZ6w|4{OP31Fdgi) zi|k6LVh&^AteH71^F~*(x=PNDbrV{y!kp1|kyD{YPtOo>bk$mDNH|c#P&D_HnVhH3 zDp3D3XU}C-{;9;lgpZJayCC(98>1lqPBFD(to#h`h{1vQTwb(10wS*pfjm3T%%90= z&&;2}Db1Q4R*-s;+<@h0hn_zlt@Ly-FIfqLh5ZTCje=TLFSk=n?U*z9a_xM)UPEwV zJeYC5Rc1!9Mt=UWJyF;#lEn%){-BL2Vl1VJ!C{Ltq5NGgnabZz$StK==mX;P5 z7Z(*3t?_>pSfw%{o7e2_2~W}~=Fq`m`ci3DBb2Mx+qmk6wXT~D$fK2X1oqyCsS7>T zE0L+-!>fA-Itl8b2rfXnMs@L#% z>q2NGJSg%8*yzfQ6O0j%=fnQh?C!}?jF40mtvf8G?0dpA zU$o7W(V<3zkdwP1lPhE4=T(J8VU#88%0F)^Kb`KRMhQ4usM+0<^KgWuJ@`x^U25ya zu)xEzm4(bl%1kRNuS(a`YOmt6(0P&-Xvj#t;}k zaq{&yG-7-a1H&6PX*%D}d%f=Z8yMuG^!mUdU+~h)*Jj-#MV%S1sY;KZ1BzY~p@R+8 zt0WZxiY5-z!8N#havqM+!7lJjbPb)VD`STC@)855peXn;>X2ayj3w;WqZeQIW^fUe zj0J_vm#-`oF@V45;!7xeF??+ipEfu0WmG`!*}Qy;t1*3$s5UK6IS#OhUBjT<5L zhKykW*Wm8!Ne3GqX*(&0u`0Zm3^U=|z@x^DH~iJCo_@xe%;!%#^A;=uNT%$d%yiI9 zK+20tImt*-mokQ*1B#9|WQC$_9urF`)()=0-E(3G8_tcjPBm=cs-r07UVZw(##?N$ zC4(CT42By$`_JbY!@?LO2KGzk+2@=qL%Er*g<&Z&+uwv-I-=r*0$Ip#0K~kg#%h=-n>7SB%@|gDEIcbS+;xS^;&IR($x; zCrqV-1;y}iX4qipKAU7mI#y^|depj>edpcx^pT?ZbLNG*IBbB6L+#+?H=?#mW=GMs z0v1x`TMHw{j5BN-kY?T_shmA$K5w&W{8-+{=#iq{?piWz5<9qx3al3Fo&~_lL7^ML zQmN}>9YrI+Q2BU+dyH>d2TQp3_xZz@9`REY?bO8SO50~?)abg|(A*LJ9zL+F(Z@m&i4(&rD_vCQEIq16VMQ0XWk#31Yyuvb1Sg zWQ=^BSS{-o&_vV)-G=E{-nRgGaZn`_RW#9Af8+zQ${i^#wwWIwU0Q_Rt+2!BIp-*$Ah-kO&`pZ&l8{qL1-1=V_#TGMz{Df;4vMsd5_yfZ`8*r|67ZP02+wW_qG zYrb3e{lEFI)}z###;XeO8Fvr+<-fnS?>*nRBbPihs>hh+i&lSIy!Kz+MlBQ6dyZZH zcE5#6^7^*p=PX-y;%$Sex$V`-3s!#f-H$(yoWAC?yS@m!zs+Cx^2eY4)4Kf>o~mZg zf2oUg?6+`n;dit!YDQ75fv4&hk^_qFJAOI0yT|CIC*3wcF%tKKH$q0VGPNp-s6_B zbw%;_{U$6|V$Gi)2ecfn;iDs3y*9Dd5Ny>iBnJR<5}o?b|Mk~jSCxE!%RMUtJl2pz=V?npOV<92_N#tJYFP_arD(+=Enb`m8~^aH|1^Gff>fS!@9^h7 zE%;!_;?<=;4EbucRF0ihJYeD~3iouFTDtD1V_JHZU$6SMulV2KIRlus&ico&wcq`_ z_qY|5QIouFT}Ljx_pNEXoeJOwJ5A>y03kHxheH<2NdViVxux{f)Z*-^@f?7?{+qjO zodWWdJBNNYVkvJwhdcJ>L3IEJ0OyvG#^)E!TI7-KqE+AY9J5p!A342n$Yf8~vYdEp zf2j4JpUeUY^rch|pSrrJ{KunQw5(1K{fZ6N@R1Q`-912g={U!k8t?fKu0p)_F6~I>iw*C)voU*3;$0_qm)jdMv{_Eer zAfReM1r^SY_(_17c22m(^kbmKN6jeIZ!}sQ!l0){B|a8G`ue9w^XOb~|IiH=lH8to zRVn)BmnYGE{rAtmpaRjgAAPap_**@*2a2ZGgPQzmUfJXC&-(9we`S-9MyqyT@sj=X zlLDPZ@9Q`Xl?*oD{_yjv(jU&gXPCYf`u*{zUue@H-cLs?MIOR`z1MtB1H6kWer(rc zUL8NHJ5W`CrJ)NR7}4;tF~)7B1BI0=m1o@jg#aJD&{wL8pX9vzM#LWC_a;zPiq0*c z)U}rLJ5UF3Ef0t1hN6FOyte^eZ`~VQ+uz`Hl9WC-mXtGR%Th^L&cQ5|%*KkH5jt#E zU~k7PaZ35KZ! z04HcrFgBKiM={dyN=u4B*V!PIskGVjjK`@dh%5IIx#+!Ozba^a5hv`EbbfudX|s&* zVX!E7$D52cSftFqT8vG>Dx=pJOPnOdI-8@&LDdPcmh>pbnQ&cUKOf)#T@Bh`%HEi9 zX)5^{er6;;LxlOxU^*k(hBF%AWFMPwOHguT; zdC|hmLbj@`SBB4)MPBsdPdvrM4DxkvX4&Bbg)#a#;uAQ+!}=H`>pM4mk(RM*e1%r0 z=q_ElP{|~eyr6oyib=(_V0V9PlCFAnm|dML13V^M;m$H-Tk7Y`Td03$Fg+N_J-8?Z zr#=Wc4Bb>cpSRq0+wJ)G)9z)StTlB2hdqnh&=p0?QV6I!=5wxd=YP!@(KZh~VvJRp z_|?=#jho0UJ58G2$dG;nZfMlxANSs;B!>=;fm2YF zrQg88eDZt1;GsQx_XQF@;!foYFTDbp^XAEf{7r9ce(@!jQXVmSECc=-F+6DKFeV7N z;>xRo&-1BoYorQn`ula)gX>;<@6GH!bpR(Go1_e1!&1t$f}G<&nJ9x%{W8lApN6&- z@M))?!9##@EttCiAV2!#Gh~*oSOwE|`S?@nFT4B-z6&iozVh1Z8*jV`Q)gu;V_y@` znZJ-31bB2PKiKABrU{t4;Ojbyj+>*yP{5G@NA#W;>MyhG^cyf(#HP=j&0HL}+;%%7 z|J58FXPtcxQ#gRoJMX^FkbVzHe?kwYdEhx89@^yh|{Gm+_97A;-A zc-abcKdOOQeChy>0XTz@b#j)nF?2JGu6@eIM&c{pP$*^8ByZb|&0BPS?}OuyKS52S z^w!&*cnHwD%*=A@?X9H!efQh%lv7XZ(6JLt?*Dg6v%RK(yrEHJsXYIJ3opH_ zp_G>{UxiBM&4a6%Y(4&ZJs0L9P74X0guILDk`yKnN32E{#G4z^09qLDBJF zRUbBDG*eMemng-ViYal)Z~uMTN5? zpSZ%0K|7FedO8kY0bhO1-_|vXfbM zPHJ#6{U&DFVUz4a$BH+PnJIOL2D2^cv+VFmvow}PCG!?8qDw`a#w08^HfyoXHrp;* zvNVYu48WkvPi~3=nEKVLSF3u;GPM@)$P*ybg2zII7Ku5&C}&c%Z6oQQ-3@1H`b1+VOf*bkrYXcqmP!gTy^>?m z{Fl7Jp7yoB18aP9FlZ;yREGMLSlmQtjVp&d6-BE8Td9{jp2$zWQ_= z#?%~vzs34YqhDW%U<0?6Yu2YVlzS~T6eJqKs(gz>EopE+u!=loZ&3(;s_qNkT36M6A#t_7M+Iz6M)stRX0>rwTLO*9IJy7 zFgjU+t2`*OJFUsPg`{X-`Beg7Ih@|fk_JTwi{keHcJp(Fy%gh)&W@bJLcGf0PWXvm zkEJW4gBAM$p0J|mU3sxY*YX+(`$3r8rsUR+5UgrVb`(OEo|@unZoM2)YGfwdtSDLu zOFPoNP&!y$1v*&&zOnYf;jA1T5xQ270c*28n~#M8J|VzmS?l0v#g-h!SOsY~IsjNu zv=5QPgE~VFUMI`9gI$r}%y@88`c1;&&WNv5>DrYVnP-)TucpDQ8Xgova$Uzcqf)JpT*Y;Y&habP{t&$>>C_2s{ZztLR~+ zalO$(lZwGIn_{E-f48VoOrPF5S zvrM0vPcj=mDVC|zy+ZKs7i80v=`$&?NI|WNq`uYL9ZA1lHmL^n_N7@RW)!qlV|P~l z)0j46DrYin2EUmzXUe}S7^|@Y8<0HLGHcc>`Bw#Fm3n&Dc>v5CTw1Y?MGF24T_JCF z>itf~l+s&0V)w;V!I1Y~L{Gl70vWwocl%1-->Wor8mf?SKE9d6!l%Fac(6R?s#9w8 zPW37Aonp0B-m`;sAhkQFv~tQ#Xc2W5bRDg94S%Fkw7SOCUE*46DrG13qYJf6AeOh4 zfE(Zp#hg&5>S9hr?M_yh(<6x~oT-Cr8Gf;slLf$}G{VwhOFB(DTU*GO0y=tFiZX;^ zUC_E@mafVgw^(ZA1o9NX6vDs`JRwH*vT_vL*oS378Tsp0wOdB^yo3+Eh8S&|~FFKafYMDS56diauQZNVFHx%Y-2s}7D zQ?Y8eP6sCg*>hE*fP?>(GLBNr%6FYaD~ElI!Pd~xgGF-@4^BpDwM{DJi}o@0)Uf>9 z-7fz*P>Y@$<&Hzxu4d;0p?AJw^{)94WHCOtw&9ledaRtRa5XH>3ey4N=Ua(GieYEz zAfO&4G%Tnj>bA-hU6A=(x^$_eL{TmJSVox=h}{s?b257Nq)dR71)PB;(8^-zW>h#S z>|{@p2}|lL;}Twa<<*Q>uQLX0SirGx1_FLZFWq2hC(Cou<>hU%$tGK*eodP;1xU${ zCw^y?fBP6WZ{FgKH`+_OU{+D&%y6NW6zwTyrIP)6vLr=SQ_$&}bmdb|I~}6tJ?0CP zWVBD1_*DjP>sFH<7EEsSx^(b;_dmdZ2^qR#FcxVT0Qu5OFB$bqmMj@DVuYl&Y*@pH z|Ni&uSei9!K5Epc#PsY5W&kX`tqf(H!Zi(WCc5k*0Q>NleBQk$ceZ!G0h05~@FYI@ zP2x18PI~q2uad181$x2>CvLsQC<=EUV1|zx)1u|gj6z`C3Ixk{N}+W2qMq@hpLXp=<(d*pc!eiSvO7-|9#Q(m-WIfENOi!wu3C^Pa?_hyJN0~$Qx zrDh z`6kMnXP@%3&px~BuDe3)H3+R7+5lKq+qZu+7UNJI?4DIAP}1qqE<(|J?zz_;cijcd zfTz^+efK}eNM9Kg%EIs#UOpKtN?%MLWkjVXyon`TRKnmy0A?_;$TLU4iS_FX)x+)e zPdX_=2j6}7-J|{AxN+lzFvCW;z}tM^`b__K^wCFiL^|8Z^H2TGJMY}KZQCT%DCL%x z_12sKzyA6gu}2ICSm|SP@~i;epwCs5(!s^0{#%&Wsq=e+aqEBFv*lJ>z47K-%;3?! zLq`@yl>rRXYk+rp_^+?6@4EXRTW%@Bo@5|gHGu6-Rv5th?YG})r=9k;_FKMux!gNm z-xe)e@J{oJ+atYV?{BUI41nov_3YU*N#og4v^D3FZzhQjW}#cV!;U-7oxhOs+wXJ+ z?|uUZ1y1agHH@C-ZDx#`Zu2ns4B@^5d|_=7ie|`Rik6%5)=Gm=G$W5AC_1?gzWCyc z_t;|(89wCv4Ie(-JH5VrYl^FNfS-KwDIU96au$I|fTQy9(ntpY`zpC$-h%D6-=2Y^ z(&zf?U-xOy;N;;WN3+W3-m#;=#vd%2$H;$%_b*tqgdR1OK={|c{*|GKUyK;VD#Cb9 zR3|F~;Q9f;FTe5{z34gf7U()y278H_^zzFu8_)QMAAYE2ThhxzhYqb*uU_lct>?{~ z2Nh44FhRPhAc|RnSp~rK!pP}K^3qg?i~vmEs!C>3q~28%9STLO|B}E=68pHQ^wrm1 z=O(s$y*(^VhwJzgPGA+(x7}{Lc5l2Xs9fNAAQtlZGEnS?sLyQ$8a0_pfVOF?3ZmPOAQlpO>9|I z67;Y#ZDn3lGWrZZHt+Z3DbrQ&N%gsyLy3eseQ>b5oQek{%=lo1u3UfgHAifnJ$v@D zWy^E{TFcMRuS%PhKAD6&MiWN1IyfSU+9Per!3(Tpmuu5ZEslh zQkDUWhAHEqUbtGhGsQ%XNWhj&Sul2{4*o5hG07=6TggNeoy@tB;n_$TrlNz>9uK1_ z0aawAGZhPP8s-wM{}mi1bEXbI!%OMlI)KB#&WfTVSUSu;_Kjl|UQ~v1NLsEaW<}Rg zia9fF_IGF?iH=XCgJ;g3Gb6u1{m&|x%c}fSsp`GLEWai{v3zC=(x9}QUodwjM`6`# z&@UADg#y1Y+bhU_{v7{&X3zDGp6?%h)@&rH#6d=R1}g;xbLY;TGiMI}_>(EfKdY+V zE^O%Xa+GX=_;g2|>MrTBSx7eXA1NFy)!2jSFN# zpmag4vWaEos@0Y5WElprvV9#hU#2v1I>SEba3$z=sh*eD|I!t6NGFR+s$29skX#3g zh3ZtpwppBE94oUpFpfhqaGfKSRb`-<{g*zlm^Cv=y}@gWit85r4kQOS0$PQ=jpGVln%3p{0Ti(&@0#WeNa1Avr|7h{?;!$}87kacLR5S8iXm zS4lRFB&TRI46GSTHa}+&wW4Ury%l~A%Bd)F78X?6T*l7ESn~3sm6>Gob1}08uPMqQ zZ?7&SU$ne(4HlK=;AD78l3!6)0Ne2fJve;Hd<_lB*4F}_2Z3-G$i|GMx2lVT86w1nJ*4t(6 zI;M#c`7+9-Wl}~!j;@ZyCU#LRdm?Ms*_2L$VrVe0Ci|uvmxB@-_v^VLR+H;sCzg88 zODXBdnbnjIR^y$Lc|TluduAJK84Yll!t*RKX3gf-qf<-EY zs0T~{Fv7@q7|;+lUh0_u0}soRQZ~sGU;`{$sTUyS`KVa;jRH&_5&QhL#+j--{j~Xy zi}wI|4SMi@%b_bl(ay<1!!evYGPC(W)}UC7MbC~tjh zP`Ns&g!z#{zz|jxE%mHYU_l;zFAW-M(mU4bLh212EPHVk=opMZ1b9$*wt_~=yv7~9 ziVPjhIaEmF9KA5r+fXN;1AzIO&R5fBc*|7ppVY}{|8~K=g|p`_NO!m@hpqy6O^gl> z)1v~OzHm1)EB%K63^MB#z)}w$`r-swb@X(A!IFCZJ%Ig2(ht+>LZIR)ah|;K^uS@# z=gI&$bdPBm!7gG|2l+jfvW$Jtnl~3(B`6va zLs1#(&8UPbkrB133wxyNQ?$rCRe+~=Q@U2fgm{$>_H=!!anZ+$jXm0j)gkRv3&tVz z#(6%VVrd+HR=cE5zBnPkc91^}GiaTB%BfnQUU1coV;$)VrZt>Ab-JMYK%0m75L%RR z92!ej3b--=d$$8M>8o20s*=*+9{K$j?}qwnEPd0_$6kGjr&Il2n9`|APqS6o#~wVs ztsLm!wWbaZ9wr|cUk9g;CD`cwIBF2!l;ohQaj#40cm0BTC%}org(^5`>R|Gs8=QQK z){bW{HE(ef!yWjvk(kR*wSDH&%NvT!t+(CIfKLifKHZjNX}xwJdGo08xR=i-__~cnXjz1PY7OY!YosJ-MCe*kG;LDj zw^OFt$)srS#r4{xTa=>cl=g+XixoeMLRF3UXBeC$XQFx%Zi-F@uqC6yH5 z8fI>GzPuh*l>k<^Pu;l8ngCj(7Zzqu8;xjc($P+Io2kBD%#JHpc|E&W`#vE>>wZeZ zXX)u+{dd%WGKNmI6($~b(+h_tcfhqinh ziOEQ#?BFmnsaoqZ)MS?KanIaJnP*i$$*cf&2mAq;0bzXaOcsW6D=fip)6F(x1m+Td z=(lvNY=9+QKD$uFZyVsMIKTn8>i%l=WF#?@^rRez5uDP&#wL%AZ)n_vmzyq__dT9e z`i`P#YOZh8xc*5EwB(+2>XygY5uWNaMHl(XG#IWDOIg1+fg}JsyI1KPyi9;qed+sM zKH6s6Z9nMp5ijv$PdurVy#{azPrz}N(a{g92El3ilW^~%TP3< z?&p8KgmGj3{}MV`j3dP$e(UXbAl~O*c!_a@Uko2oh&%HSKoe2*>S~HSE~U_4Eo-C@4Xj!AD+~8a0O4pvBw?9 zD~{o$hdnYJAWl;_(CD6x5#7lOQ-@(u)trQEa|KV;+sOe%TUoSDXSJQmldfT+mc?|> zQhC%-UQ88X4AQebBbaGADiIG3i>m6Ts%Kdi1@P-g>!&wRX@Db8w0m22vOvbT zCOsoS^l>_kOPeb-ohjfuqWuTU130>q6&4Rp09Z71DTX=n2o zCUsP7(a*ig9Br)WV4wfvDLO13tfHzCvQ;r-J!FeLDlTPsoqF%sYMJM zJq#?NTrak`){EllSw40oSlp$0^w)?D>s+mlf=4rmc>1QcxGix_^RF!FtN^y7`eB2H zjS*>%0cv)lfu5U}`bvvqcFe%n5xBd>&sP~oM@Gojb1w((V%#=cWJI*&|0itpE~P$!@@>-o27Fgd`^NjY**nc?L~5@t|% z2P4PR0P_MQS8~QpOh;8i0M@})5ePp9kdDdgZ5mNz@AXZ^5BT=91TFMPaO%vxAT*uE zhzrq=;sIO{1pFoJLF1A^5CEKgPF8$IPQo?=6)TE1aTcxajuu~ZB`I19u7yQa^$4pL zr1R)Bi1KEJY@HF=Ah761c}3TvCROYYNc6lMFWGACIxl`45)3xtzTRnk`>kjJy;(`x z@+dkX7*!Y3A@o{{n0Y)Q*rJBDfImZVk{gccj!%#_<%p{4fcY^1l_BNnNIN?^5x{X}8JeeR5&`jmmkCFyBqycgOjsMx|r|4iJ4&V4meH=n!fBF}F zvPi{JG@hbpv4ds&WL6X{AzpM?SX5Pyuo8ClL%axk#xcaGFA+&Ia!Ni$dxM2oyfi<5 vI2OlMTq=~Vg1f1xvm+pwaaI~dJDdG~jv@Y^aNuIg00000NkvXXu0mjfJ53n< literal 0 HcmV?d00001 diff --git a/mod/maxgui.mod/maxgui.mod/doc/osxpanels.png b/mod/maxgui.mod/maxgui.mod/doc/osxpanels.png new file mode 100644 index 0000000000000000000000000000000000000000..de4c5e68ccbc157d48cc9092f91dc91d751fe214 GIT binary patch literal 458 zcmV;*0X6=KP)Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUzNJ&INR9Hvtm_ZK0Fbo94&v+Vt;6wbSmCCU{085V2#EN?8?jDSY zdg!GiG}!Sbw{=~MV!bu1H0+bK99YbQtz}sZ`(Z2xR<6A{x7;6>A1739?}5Ut9#mYH z%lF_q_*|6-6<6g!#Z`H5?zU~LejD}&ew`)sYjRD>->+8&*@LPtRCN}(;82e9t@SZJ zk>h;h=96R2HzAalAwPg}{qrL~^nJ|ti{~gO%=cg9_YOHK)Gv)2`WWZV^BIk+@<7bh zXZe@rLG`~0{r0&U_b@+S;M~;p+j1Z7A+=x1`S_RiUvMN3^NrQVUZe5;ff7d=#`?|Ux6jqMhk5?Rxq1Ee=Wg6X zYQOD#O!E-(FO8dUe~|QXa=&=q;pbnU$2sqJz98tn)V~dGd;kCd07*qoM6N<$f-xf4 Awg3PC literal 0 HcmV?d00001 diff --git a/mod/maxgui.mod/maxgui.mod/doc/osxprogbar.png b/mod/maxgui.mod/maxgui.mod/doc/osxprogbar.png new file mode 100644 index 0000000000000000000000000000000000000000..776ad19488a1344aae2fd95a3f3906e48bf7aa1d GIT binary patch literal 1135 zcmV-#1d#iQP)Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBU#?MXyIR9Hvd*lSZ7R~QHI#Wa19ui_WzOw&u!X)>)&(y3EpFFHoi zXv&zF#3m6H4Ix|vH4PwW6tId~MCGo4+5{?Iu%os1MJH2bS#a8pCT%*cHRU{gfUXUV z`vvwlXU;r(_CLeUnccHz5sZwCG@6bPB7i&rbp(#Qd=!of04VYjm6w+%075;Z@HmBi z>hE+-r33=Op?O)s&lDf!=jY>8P!@}&Mzva{TCGs8RccnNy4I_->y`I5Dz)DUyElaT zjVf)Xb$wf*UKOg=s#U98`R{ou91broE>e2EUT)u%k8ia*X|C09QMwsTW{$MMq%OF9 zFOckEz*eCrJreWIN{)j=0(u_exQ zGew5v+3p0^g<9rx7jv?MepAI9SJJQCe#Dihc`6tTMx)X6)AzdOm$$lhPU&~w(d`x* zAD_AZwAl2d*!)|u>FL?NUki-8h24+e*6p6`+<8s2^QwBAEB_NuO;1lREG$s{{r&Iu z?!9N;FS7hqGL$+uv|nZ;=f_Bm6UuF=(ora}KEv_%E&ByMdzd_J_=79|gr|Hy-~9YM zrPJv?7$&7-q|8CiPeQeu)cW9Z0ItqLeE>e4f@&{RI-qQld}t%*MoE#CaOHpJssGlg z3J+ZHLu~*q%|gT1&=3M~1ezD1Wf2;}Q2!7v&4FkJYNnvV3*}zm%Kynzfk0q+c{#mK z)qMq5LU1h%HzOd4LR%E>tbu9+fim8$z-aV zCRc)_eujKDN5l_F>pW?T5LtvsBSbP!nnUE~19EMa)CY*jOD=i|SNKF$ z&*)=e7~!3mWj34f8#`-YVBny@Ix9Q=MK1jLg8{6ESa>mLn1%my{Ld)sOO}l_Ha2Fr z+s9dxtci(Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBVEdr3q=RCr#^-RG|?OVu9m4Sx=TPk;nSh!02z36a4dcu4|r$vNkY z!DN$jFu?)a*ajP%@oR%^Y?E`&IhdUNJNvn3&DyJa=FGnLSi1FL)YH?|UG=P0D_768 z-uJ%uUHjVC{_9`=daY|+>*VBQ^E1DWYh0X`F5|eLtY0^;>38mT>m%s{GmOpq)bPfy z&YNH#;ka@PuP!!#w7S0kl;d1b2mSi$SOd<3&U}5>yWaJl_q^xb?|!#W?H``De{|aZ z@oD=fr|rG(eXq}ddfNWkX{&>Oez76szqr``<;C`|&bIfz|NS5Mzz6>IY5O;)?Smiu zU_P}Eedt5~_G0^Yr|sXLZU5o4{m0YxpH5pHIR4KU+lN2=;s4Uwe{Jo*owkpB(O*G_b#DcFM?AO(`hZ@z!#enP+&lUMbhxLj=>P3$3n2o1$grYcSO@XK zy-+LM3)ui&aCh8`LLt~0^Z^Z4oDN5yrVYWs3MtbzlaGG%qi*r3PkrjMpZ%;)qY3-N zy*~AVau^qm?&C8Y?I(}$AZsh@X|xd1vawFwBx~aTce4sT&ZiNYW*>H~zwkt+Qz!d@ zJ8YiM^s7PAyx;(?S`#RALgoY)zk&E?Kl|A)e({SR{pd$u``Xt&^O?_l?sK2}%2&Sf z?Qehkhd=z`&wu{&U;gr!KELyw?+l@YZ2Gz#+I;eppY#Bq&Uor8U-`-xz34@M_q4s_ zB`AsEp#SY}fBU=N{m$q2 zzyJL&fBDPb{N^{m``z#U^rt`l)vtc#q)+EN`qZ3yO0)o2~^uPc8?|nk>8{hZ_ zm~{KiZ+`Q~KmPI0fBy3y{_qE1Bj2sN`s`%0K0M&L&wVcRU-!D#0TjXY`t`4W9nz*b z*4){kJsJnN7!7D|LkuTg-WE1A7!uqg5QAK`6fA;wzVn^0fBoxmE(B_jeY7>~en2X0 zp6_$4nSuyhmQ+pZBywMaemxr^L=DCd`Zxk`(ErO{{u1;7R2EM31X6`;`hMXHUx4G& zp7yjizxmB%8iD@BFMiRp-Ndh2hu&8|SphC{u`X|T!yDj2$5<I#tQxK zeeZie`N>ZP`jnMchNGd=6XBE}{NM*T>)FqKHi3?)F0ZCkP?yjG1{;#93!dB%H6NH;tF?WNYI?XHA%w9l5zo# zHY}gvL?=yH7niwM7Y{-M7etd^#^#3D>&HL-F)~glPn2mvfn?JW8ycL8buj=>cPrdC zIO}SDjkrTjG%ylO02;%Ch$%qdLN^|d)*NVldefWU^!F~d{8Y`a<4j$tmtWlhAV4!m zAb1MiueS4bk%if75rCE0wFnRvQ%j$83Y4wXAaCgG>G3?9`6ab6T{*1VR<}`<(UDI)K(?d zFuqs|RD#t&Rz&M2gn(M^7;y0>hV@8|MaIni8N6m8nFlqQ^g}L z^N6S%WI!ZXyWldm5HDT}ZEwt2(g>L!CPKR6tylym;xmgc2cSeD2fg95amF>SbTT(_ z5PLtXE!uK=3sohKsI4{v;{=uwH6r-+0OfDW{DVg@Ws&{?_pNS zlb-aXhd%V73<+`!zMIfH=_gco8BK)%mb2C1ZmZRNHO~ZkTnTy)H68q9L1S1rm|9k( zmWlMw`l%nd&*u5w7aCb`AOcjRh-R86BpnNnpa3Yv3$pl`e#Z5Q@K`nImJvrrC$1TX z3-OBgOD=nui-9hZ^Vr8e_Q4N+@O|!cpS$1v?svP}-F*H{YxlnQy&w3%2R`wMPo(j3 zE1-DRSkaf|Yxgir1l*=+$^?#?u1e*SiU%x*RZ$o}A}G9{plRAp?lWVs0KB3q6XC)2 z34LVpr6eQnD?sl?mPld}X))}aL}9lje~>wpPFyefgLoT2PXGj8=%Qov-eqsmqWCF1 zWD!Fj`#XQto)tsmaEs!NpJ9$Y7JX%;0T!U7Zy6iJjs=4814JSOiOD#KvMSym8I^bd zaRr8SDivL!b{DThv-LY3^Q)JnxuM=mAFkjiBB99G4m2Qi8&g?k9r z(a(KOxEL5efpr5l8aE{YB6bp(Eb&K#LBH(%z5+@IlmlG6UqA=t;M@5<>5JsE!s#P@ z7)~D4V=_mJin#@8kFIen&rCAI7h2*DlHi z7n3w@RATKAi;0U7_d%cTcHpa%B}PW3u=sRk%$y0tBX`*Ih=qR9pdTbRl5}G~=-J2o z6s{jR$dXr^3CJWPN751TLd(7;l37e5H(8V-RfJ3^)X}flPEXXFh=nnD=)*!kP8O{j zOP{*H?2$jQl%d}L#qNZ}WJ%Jv^uhjXVK_D9dReCl&UeNTE?2ze!X^8TX{_f1) z^WBmAxi|;ov%Z!H>bFYrAicDa#Z6BBOm?MWoRK^UFeKy+CLsDWRivYY6ZT?|bn()G z9vZd8OHZ0tl|nIfPnwSm;!v$2#?Y~wA}9hq)ap61u6ui#Le(p*WeT0gBRxtM?bEtl z{nj-@{kq8oi!(9KBvdsLoUbp)&NSryCF$b~DBYAXPU}`yJyw4y;qrmkMbK@YS`Z=6 zKAWc`(!QF8Rj`yfghEBRUf(cO#VBzIsft2KLRI9m*N;@rwvxKt1nP>Rpgjy+p7}P2YHAZR~MJ1+s zrAgPxC8G-5ZpjqCgR=NKI0nkVn%tH-mSnRaO00+LhYi}(~r zxFh#X9>nt6xIQHgQNntn8?OYuA_2~`h^n5aYN`s^sDWXF_NCBm&0$%NdY-O4yN!Q9 z@>G>hmp0{FMtO#{fo{x?c*G-ad)wRI>}EH+;SFzi)0^J(Hn+Kr*tqk4&Be(8hkl`4 zErk%NmsORxufnNby;IdeyR3TEsew#h2IJGijxF}s{-llAZ?YmO262}T@#W zR#SCVywAEX8>t)ek&RtluhOZscd3vPK{;?l*_G6;H)yH_*L^YpJ^3bt6mo*53z&a2@`oW)UNE0=f&-+q7noU5hGQ4p=YE} zg#KF7*<;a>>_v&PKFizcY&+bmP4(DA2o*(GEt#_X2n}7x)qCFao@6YyhEHQsK-U~3 z-vVVT;2!t5hbvtl`?ZH9_SvtI?`3gz`BNgO8=WVWS;PqPGO4G~5|Hy1*QcT+@nIoJ zC~xw9Da`dCi1*lBB!2(wu0Sb()jVD0NvVNudTtiR;$;LDbJa}T`X*6DHu zff_U(_qfMB{_&4@Pq>#?HQ0Zj#aV3Lec%fIlxW&T**uRBMER<4%HXgA8(+F0=!*?g z6=k1{VCV3px_l^iw0og(uU74v^Hoo{78b5&x}%VFGb~PL^s+iF-?XZYCVJebS2R)`%md`HIki1F?X*>@L#HS^HB6esb zj4xeK=*JlCreWl`G&&RF_P4)1t@U@VdF{@3zVjXLc*k4b@|F*K*u$tdv$hnVgUQ0G zn&qDQ2D5X`Lmu)F*XyP4RhtkfbbrcIp5lfj{o{*W$gZT0lk|rvdxnUw1dyvO1=4Uu ze=YW>3FHy)b+3C#q&To_uW606dE_G>N#ZjuQaM@017$l>9u$o8#GoavB*gW4>3h|t z0}6nEMP=WJG|(s~QI&*X(8v3!L4#ru5X;O3l-#5Q4+12Vgl$xJX)7cmWqU~bw?#(f(J-ql!O?2 zxlGS%&H*kV9+mlVS%{h{zDq@WY6jRpAp;#?1&}tb&(@NwHW5(3MBhXz<8xIIVwY8q z#fkXwK7=z}Y8*-JI+J>kSe)J7PYJY^a-b2cUoD(9Y-yRV!LN!LjBH7T4JvxmgUKTa z6)r2LV>=S}+!}g|hD)7j(#R?1P2yKW3D=N0RsiV~%d)(rN~Dy!jz;ZHR{2?3OqEnQ zvva5_O5$x%_X#5#nL)cn(kw=nGKF|sqnc{dmhWlXk+Km4`lY3!KRsC zPFYVG7Qvi^CTTzvpb8nADpyl;kk8oG*ptx5x%xWpX5XYBVg@fgY!LsvD(V0ZEKLk%pdKsl<9^(uYGk@`xjem~_<|A?V52Dcx$}E$_+J>)N*_HCYD(GK<&&?R;8QzcF z_n9agvxnez45P}hqh6Bi!k>wqLWI`81 zrQ~=gY)Ye*#l!MG9kWuHm<$k1lhP)w*D=IX9jl?oc`D#DJl-mCDDv!he?*w^Z;vor zYY;cGM3@KfkCeJw?MrwS&_FNmw~{Aook-6t0(W0#aSizNn11<|6?k#Ik??hhAojSJ z8lT9gWAxwvVLo^03EL1LIy0HuDrM-Q&3=A(yk+WCmj6nvOTb++yMkFNyE5wc%k^FB z6?%MlU)4f|4XW;A6o91MY_y2@Uei$7m1KR3R2A!w0*^}25!DkhWK&8g`AlNNdB2vn z9~BZK=G=u+QFk-GU*6WPmaSKmT%F8fr^hjpr{`6AesL5-R6xI1E%cI;&Dw<`UZOpl znML?Umn5K6iU$dUd(~ZyYKDDro-X%C0Z&%|m9@WM?+5+VvYjid-Ydu}UVosXqzCAS z%!%X~l^{LJ)+N#~SUb=w%2_U5UJV)5Q(!snSogf{;Rth&wN)mdClo6^+0$Vsy`~|8 z{+NoAsv-%?k8I*=U;A3VwZH=hJ>lq{XdDG@q*f;+qf1;@U+O)|f0(Bw%0`aY;MohR zruDUd!5YHCkwrb)ye}ny|DO8Pr?RJ67H-ue_!Y0O3c#TcjFbPYZ?@}fRuWcjtBTq# zuOflEN76s_k~e8ZWV*;B0O%lEZFD^zFz$>Qs<+hguPT_7FWnt$X-RemeXE|ey^hKm4t`Uuh+(mDv|_4 z1huh0^ORS~n!@ZQntE+>5?+k9rMuYo0@2};}efPxZOKR`4 zI4c@j2m2_uM&CvNgG?KJOJ~G4uFo>Py7nG@OJlFjZIpjG8CTZtpV#K82=gdgi%j2# zV6VvRX@FiNJNhQaU6F>eb2`hHIloGeU{rCH@|Z^C$JdqjyJF~p%!>0=VaO_Z4%9Gr z!~e{_t>bN;&h?Q(y+U^7{a)iApE}?r-iQDorr@!aW|@C^p%2kN5HZx_crH zMArnD)VdXEh$b%+U>D;&m*lDKqHDN~7&#z4)}qY55rw^fz~v zq@CHbc)Z*{P`}T6IBfHbZ7pMCm#Q%VBH_8bs0Qn;+q*`Dxy1TDskO!@D(bmUW5aGU z!dz@ynZ?ypTfMEl5$38SOoZ8JTzbhJqob0r?*v+H9`=co1LaXgo4h>2h?z+2DJGEX z5O*XK#wL~?GU~>t<5g-!MvWXm*SbZR(KqP#y)LOEuTt_D?D3mMUm41^g1npmjpPP5xWSEYeB)c(;ucb`!WGy* z`LDI6;ehnOmB&PwW0j9F1E{J|DyCM+#meh$dRr-ku4;x*VnzQ#9cPa)ThY+>R9@NP zHwBdU)HCTti7^xW+lBt{wtS^U1Zi(|t6OdEBoQ%v@{^xzS)|OrhxL203EGV3n#kcY zp$c4+Z=>(N80T8bfFz@DMcK-^?LoIQm4x+PHr!`!N4_Ovyqjw5SsbGQ!M-Fru17!6 z6ZZ#plHB#Kca{2ZajDSFMX(S3H5XsrW`#dji?bqh2eK=hah}65&NEuKEKbaI{2OBS zMT|Fn-Le|Pxjl)BVWqRZGv<;zNn9gd4fGyZ?yT*2XlxQAx%HktEbnQAfCl=BvK`1Q z9?-gpj~2>3r#LOngln=Pg2>KRF&!+B18+y_Z^>At%9u&TDK~egsHQ)1CkY*3gng5L z9UC^H4vh`FSoFQFt%F`ll_j&<>@f=a#{QD~6=R4<8GU<`D$%Lf!#;mCygwq$ zql$L)W%HzVvzt2EvzVo@5#Kk&Sd4He3ns8hzkmUP-vx`(umf2zl0hb`|93dK+pFYF7MmpT&ve zdW~C`JdRVW3Y|;tB%ztrs&v=M8%LG@T~cGa#+8|1&k}bBVjxH;RV`3|^G_96bp5f~ zO9yJ%&Pbk;`*_w8^Q2?m1ibz=NWEkYBahK!r(h}S($W!Ac7-3glLVU^Tg4UVr|hUY zX74AdW&L&aJL;%5ZJx-b0~xW+IL~35C!#;?g12S#J`K()JMt~qUGA^8{FsS(c77if z`gZ3Wxs!x^S9#YFe9(g)bfm_n+v%81%Y9#zxMY1*%l6&56)k}EnD59eR$jMf79)Ii zH4WkYBi{gz)5o6@<$VunV>ASP?d{5o33~0@6Q1w{0kuo+BykP&t+`ITb7^dzO@hYV z#jRqjeco0q^hlCk(2xjzC^Y)gw^csX?aNB7RA%iY8&OCD?CEy-=LHp1hyVRxv(BKB zg<~{k*o$FH>*hekl`=d7I=qvFfKua!e|v$#ximIstvuVZ`O2j_CeBlcm%Sgp-pBjv zMxsP}c6(PU(g1ygI`W@CHs47Yt?P66oYYr;d&a0T$C5URkUxmGxs$|sR->|d%Pa0k zRkt0lv296%KAAhRRF%9P2v(H1*W*`+X6&9=y{%q6QWj1X`RwBRRm%o_*V(F=Kk!gJ z=$#$={(Iu$OOUR75mE$8PQqyToFJ=AWRJ>4Vfcv^kNr7Q7+iO85`~NTFA$&;?x_bQ z8>!rmzVkqeqoUU&TaK_pMm2Z5>P-7qNO zjBSg4vaPO{MkOwvnkx1<5QonxmLPhZqCqrHBDd-o9QcVMu{TpJ^Sal)?)9&K{hQq6 zCbsB{?LduaLK4ugL1r)7K2l@bt50)m)(D9*=7|ja1Wzj@rl~Xvg7@# zATO<3yl=A{)}t%zpri@C3aZ|FgCR0)oeH&g9F{>dgY!aSBi1x zZGpfYOYY3;D3dPCYOBbzc`pySbm_4>qF|2JF{_iTZw(n5_rUU+w+jeC_Q0yqVf3 zevHi%-bX!q5b!>`g2A45>({^D4D@L~?*1ixPS@BLi3fXPvez&JddOb`4c8aH_XzWm zdq088STc)ViI4ZqPUheM$8eHEfR1>jx+-11YV5vWZbX>Rcw5;mtq};Z_w%}6%wpjO zePkef)bAJieJ3=?yk!4KpVO5f8x@>ARl8cN2eRrg<$pyplT@q5R#tBdI2VMnA+>tU zz{UdaoVX;%|kPUl3 z0>o1W)rp<5DSHk**C%k4wyUB&7y85I5&J#T=M*zwAPtN20Q!}Y@AYeACs##&hSW0i zq+-IVeb*y_h6#@37`(+>?E7_totvwTQ(LcdoMrW)r+ zpVO5#wf6Knp>aU#9@sTkp4UF~M>W;h?R9*Vf=dDYzQNHk{lO%;-R*97z*lfhMe$1J zWCKOo?%xlP(R$3^dgdPx>28M-Ix3-O^Q) z9NY28H&l6J6yZ#`^|}&k{YdYUq>ZnjZD`%>S@d}>^b=36j1|L)6%YOU-uJ%N>F_ym z87E6-O327hRBpFz)h!V&2;9nJ7P!kS)XKOz^Tol~t5binKHJKC5x$V^=_7I{H$N-Q*~) zj|BHMC64SFJU%!E8`T@C64j~Px`T813eexHb>r)5=Zf>}`?oVF`)PO|z^xry#rU1y zkFj~WjX!pv@7n=ER;=%7DCr*$zy&0m;SG+lwmh-N_j{z_T)qOeu|}A~3TJ%X<71rN z-mffU6(tUz(=@8yf8F0(5$4ciGtM(2`&lb}$Mf-8x9i>#1;{Ws1{86xB5iubvZWyG ze57}2RpIO&aPI!s&euIxeE;gaC8KB9vlO}}I3~(AZ2x0?-BGYVY8rf9^SULeLWb_^ z9`7s2zQL;Ver|Oo?7dYfVmE$F(LWldSkm z57Z2HK37cx|3(t@k{Qjs&DO$Az`1G~D%5-u`;THgS6;U>?5NRnpYgt$UdvWNg`VB* z$D{Az2=iD3qwnyxdVIeZ_C)@SzO`>Ff+BcTMula;DDu;Rj3%t9ZXz1V*J9?B^z8O+ z75c~2H1v0?RVAT=NR{z!s&&`gfk?yX3#K)`HZ*YQfbo8*BX`Y33a#&^svP==<|77n zk$Ms-GPX@$!Fg7!43(i8MwK8Y)xL`~)cbi>-j`UnbwX4}gh$3vvR8rywIy4|%N1g7 z7WypcdQTaf%1~Ac)y1h=sMrH5yZT}=$c{uOgkzAO8C z+1L>PifBrRxbwah;CciAE_2=@fT0>5xj!BQS;9T$^hm22UZ7vSteKjTq$w2T%7U5teXl>6gkgWob?8H-8?3*f5+WqPL@ouzu2;@uTNE0>x&j5JrcC3 zxJ~!1M)~Hxtom3bt7BZ%RO?&u`nHzRs}3s2Qyx=6JXSzgu)Tsjf}-}nRmnnL{#eFL zqR@U-P?ZhSmv{qw{$SoG&UJupDNOSfh^bmdNrdqXkN1gdMsBN?La!7byua?A2nmPW zFCwMnzi&Az!*q!IzMo<(`&s3FWn~9pLYt93+?4x3D0+0l)V8dBRkT?FSvn}avw6A+ zzrKP5NxG~^xpFUx>f)kD5k}EqmmURTe>c_G&0ENh9X|={k6-h($~`+(Hs27_-|bWD zW^AZSbgb;3DyxbnDC?zY5CZf!;q@J(*)q4=w^dp7tbmk?jN@#SsGsV%RzMxp1`4a^ zKr~`dxBfpN<%J{uT!kkktgw74+ z>v?Lg`ubNYRi;_Hi~44{4q3uDYYeA{5Xwv%!lajnbY9*UPFP=Pmo2-4k+Vy^vg(H; z4P7xDqjjrfp_FPViC*vDi>SK5sldaPZ$}#2fQDGFe}To$wL_>5I-6G&|Ed6n&C{!B zyAbOH>vI2?nua34h)Hw}JWQS9^g0;PhzRJana#oG9@0|F{h-U4B1UeaUC8SaK2|{g z`#2)V*S;~a%cA;|q5eML5TnOCNB(Q9o4$0qMkz14*SoE2s7s+u|EuSF*JxX*NSrfy|pp00000NkvXXu0mjf D0b6Rc literal 0 HcmV?d00001 diff --git a/mod/maxgui.mod/maxgui.mod/doc/osxtabber.png b/mod/maxgui.mod/maxgui.mod/doc/osxtabber.png new file mode 100644 index 0000000000000000000000000000000000000000..52a6e91a3c5b28c2c4c2e729c6160a20769be11d GIT binary patch literal 8816 zcmV-$B9GmPP)Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBV8?ny*JRCr$Pop!VpDJ6cvW57^Mv$41+KX zMFeRA383^|G(e;a(n$y@kU)wFAreX?q!0p9q=gVg!4L__41s*^`~KdSFKeH3?tPEP z$a~}du27XC@JR|+d%%sCC@u?ecypcS=$~do*n{K*EzfLay(@1|dGg0Pz zX8wFe`imJU^BjKfd*91n4*Swy&P-HrzGVLD)#Y?Y7%) zzx{T8@3`ZRJMX;n?`EbS{NM+7-F4UB&q#OQeK)`VFf;vAq<@~7?z!ilf0>!?z4zXK zotf^t?>-JyLcUG+-+w=a{AT)LlQ>J6>i8yp3K<@uci@-g7gL5;{>PcgAHsJz@v(fe zk{f{x&7wpr>6f-5sr6_^rSE_L`?Ripm1y%!YX4Hmp(`uH9egY0NmEx}ef2fhT*EKv zcV?vDZPM>WLeg_|-F4UL*Xj2o{lSd%hfUHza`NEm96uT`IcyjzIW~Og@t^_F4g=#J zOe;SO?wfDES!h>=Unkny4Xs93%euFWehmQqD$&7h(%4V}69$SwLngtbF+&1s`Zf5- zc=#BjloY%QvQAv3n+Uu4Eb{ppWvK!pJpdKk5mp$vw zmEa@23f!QaB#389v{QjYke$Ooh<5_7lBNr#1ikVu>>LA$`Z((8_+bS2k#3U439NpYmP;JM6f{Yhx#=Nh&_5Gm5Xd1E11=WZb>rP;IzLnZK30dRyEym!nEi4DUb>@1z$1+ zrU_ZleDJ{sf8{G**?<524?XnI-<+G%Z~Q9FJuPs^A%`4rzybU1x8Ko6AI&f@>*(Y# z5-}3|Qxesd*+p`@{Hm+2+H0@95U7tm_SnyV{`3Ewn-fy=|K`Pnpq&>#YxGSozWCx# zfBI7<-miZ3tB7h(l1Uc}nL)ZwU2(+~S6+D~zsiunaY+<1Zq7aT+^3#;>glJS<}q`1 zqDB5^UQEz~dGWKRzv+b+UU=@g=PtP5g2N6w4B!gN$-+&w;hEx}QzFM&4VHzV=`x}n zDgp_9{PD-Z_kYag2~PH3^I~F}o)c7`mE1+4fo_A6i!Z+Tj5E$)C;;v!o_ONl1`~BIyX>;vcH52V zgGK6aZobdNmp2+Rb052TGY+Gy>y*FN&dBe&mv z`!9Uq3&WMmS!@dE_-5&n*{ICaMoW!N4?q0yr$7Dal~!8m@WT&h;`+523F$R_A^KzV zYp%2Hw%eX`(n({VHAgByKqtA+M?UfqV7l|pJ8!=E<{$jv2Nzmsp%YI$ari=0Pa6xg2lmU|<+a{q_|2S>LX=#bTZE`{dko}$Se1{7F zw}dwk?@SCAjHT#G`zj2Vf9qS{dhdJRJA2noeih=1mKvLwe3n~oIX+o6p<^HZ@P|M9 z+0PDN_?gdqX79cC9((iGqXM(@B)0|JAk{Sygc!8x;(=>dU3JydPCIRqo40iYZpxp0 z@<|@VBrqHIk=O>@=-t2j-S1*>wB<6*YDJ4O1@S1Blr)-S73<{Z-5XpQC@5~D`*HifQuYdh5Z+VMem=;sDQ%*TWH=$pd z*7;t}o_zAj^f84$`q7U#WPwj3EWY^SNP0d&^-nnA1iq2_TWz(~B+_nj$xV0U4QXT^ zq!N03jWyQbp_^{H=>rcuK*?sCZMNWo3og0jlDsGOd6?u*JMDzXf7iR-^~EoK5y(;p zfy!AJj&8EeHrvoI%3E@O{No>|^_E#?8EV4a(J6B|vW$*{8jSrwz>WL@U~pYpn~$}g z+ZOnenYK_$_a{?47lR}%F-hdlKKpD6v6f-Mvj2lTAKC;U_=YXF+>*hdvvkti-u5=W zpFGG|WRXSS@vQ2Y5b0DVaeAFoOz1}(aRg1qg-|O>Xbw7?{5QVw4LG0f27ne_bW!ll zs6*?y@WKnPv(7q~TyhB`kmqv4z87;j^AeC6PE1_fjeBM_I-Wv$fUve)D6)D(rfEtA97zV96d1JkwET8j)k3DL;?xu@?#tAQ9D zGRX=_uyDSI%3MM@@}4?0F?j}w0If?v1GpJ@F`Z&mAa8~fb02pGRap&TLm@(!!cTnS z6UaZEFViU*aLbqk zClcq8I;LdX!lSQLWKWqLnF89?KDJfec`Is>B>Z`7y^F!%b92qLgRpkjGtg z(M7{A##v0FFW?F$(z{MyAg)Yae&qaU3#Z# zmmpiw@qrU~scep9kVFVIK+8)aplQr$^E-1H&jZB38bAX$YRgGbws)=v-!KO-gus@z zWUS7FIxrAE22~n)p^(SJN0FUo#*!9@D5eDpnURsoI?HmHOX%Q2qZ#o~6cxgr)uuXR zO65Dp((Xw(H%-Z#Y_Y`_$pvXU7?GHzsU&&6h}YoJ+CwH^&N94M z9r75}WC;TJV0$`*cro0`P=VpgA$dj`^CJ&Z9r!Ds4Iv{BfWQG6^j3gd75FOJi;mYJ z_vdXpUn~nJG~yr(V99)r3(^fP-(rSktb|4S`bVI2H z`0%BdUK*IG9H=16$sBv^u~3(RH^(-qvy4M9z-Izf31vHz${@qs&N2z=L1turho%5_ z9*N9`0LgL6t4S>=A-=Q%7~*Xh)+}}V61Ge}4Dp5nf$0w#z5p}YtN)fX@4gLMeF8I1$4=d1pEvV`>t)G}rB zIlL9E^!)SB>rxO55Ftpw6oNrRs~ivm1-^@RS2eJrQ}jJ|gLkodgZ0wc6pF`#W7YZG z=RODW$S~J2mS`NF4&j;PeQDcCs=*m}A_*49?7`yzjW2|=fpvNiAff?OIiJbwtvtk< z4`d9$$mvsVLMu@Yf@yzP4a0y%Bt*asqXQ{W*0vyiF&$<8HBM8K8E#_ya5~oNmHsJ zs2K63kO4#eQV3X)f-Xd;@aWl4j`m%`XaDcS3AY_>S0R%Zt-t>Ij7bV4hwYOCz?W&(3W)LOFCCSv&$aVjPkr4N30DN!pD#=ZkY=c2Ssl7K`Q5775fmJxj2GVfu z(Snj|klX-TsuFKA%l&3ZbPgE+=$O$2q3b~bj87R$`{DHKuTHp6%tpesP>E}u&kQd! zs|iKNK;qN-QhqNVr^DCsndOW6J_L7$zJ%uqr})i;1yqSb=d;k2%WVf*va|8~I<&Nj z+R80944cyUydh=*EKMjjP=-J}GF(S)>(=gIunx^0>A68V8ZN{(Jlh^7?M^dFs6aK? z3~U{94{9AA#;+2pA|+1Yiy{Lj8ImlW&XDI0N{ldNm>Ed&t@SCD@I;*@1N-M!i4qP~ z;$K$A$}2-6vDyD!#54c2y{`IzQvq$+Sr!$2%Qc>caR`U0>lXLNQ)~!TM{Vd5lCt3IO=F&aL zMyM80hBk3>bD0;=lH}E%oK@Z>Dp&hEqekZ45X`WS4B%1nq9w>{`VQUEXhDe+ANTSL z6+%*2ir$h!|GKkv2bFhno3c$)EtS?#PaWyJm3`)oaOuowH%0{masZ$b=R~1@+NK%X zUS(BYY-2j~%0`C{2$7K?+QjkRf+ndHpyRah0I7y>NP3*G6~HN>O@ASN`%*F zvw}D`Vk|j#fo73R9yo}xYFyn!zZomThaLk3?w(Q|_a{MY{23n^<;TIU9O*`ZO&r@K179hsiGCeS zCqqLyFBdf#c^%puUoh;W0M zS2#CCEI$#qnnpc!wqW&KnRBA!^(2ln+DXax1*s|~Kkbg@67ffeouPlS zQ5@8&1oX+qwX~4!K*{o^h*$$uJ(}@%5(gQU%~&yj9LXtTwF$cdWoIlXg>frEc3jvQ z_skE{J2=9Q14Q{N(!Vrkn-Yx9p`kQ`AL!A|=sSxl=0p5JH%ly% zyK|Lki6(U!z<`O29H+Po8fY*Lg3G@56tSYkt{~N^!0p9f=F3^L>aiM+&u>pHiq$3=gP|<1CDe=Ru&6%EVUDH3^3|twJ^XpJ zR~@#1S1w4G6~oM1c^#$|LtI?y_vGTK9dEr0t%tFeumqKD#}(s2%E8X4$DJ{bQwLHM z-qM8RFzBT6sWcr{1&VDa=QfE?(Vm1y^J$S=W&PAHt#Z~bN<&8nw@${apoGWPgwPcq zd|E@2;@MzTp_j`o<#2%QLN-#LojUtmeWp?+n`J;@lBz&;sC!u%P5!TNZfam?1diJG zZp@YCpjCb<*CqxVw0t&AXud$P^7G!7s{ikYm46~jF-K#d@q&tksdNI8XJTg?b57pMPUgq_tbEkd{7ano6i*a~Uuq+7xH2 zUNPyVoJ&QxhJ?pP4w5qUw?>>a&cCn|JtxHsjAsqo&8XO`atPe;Fz! zetn8_yS8@Dd!3^~dhU_StBg2s41+acYC7RUhd1do_Xx**uCpnIi-x3)QKprF7SZ&GVx;z6Yb&l->w`PMf6{KrJs~gd3%H=u)7;x#4;}o(`=65T$i&ncm zlyTlZB*l}YIFO`?p7CIcVtSLJx|lO_sap7Vszh34Nckrnle4}*6&aw{?G%~IQ?+a# zZ?*}u^&x5X*{zw=!msrSv8JLG{AG~jfN{QM)n-s0nVv@UtfKPsb1l(Z9iQG`ay@BG zSyvSJ4pWr!Z!pOx)ys4}P+<)@@-1P4#)D7V5^JnmlVp~pirOmhv@)hjq}UhRe}QUO zjeWi)DaDI#Nm(x@Z?+20L%bLrEsRrv?b*55&s*VIwAU#GrGiL8+`4)68Bp|ROFEm1 zZ6BsF()tilt)ood2$VqZZ_?bpv(hw zBBKT2%hydy?%b@4w|b3-aj z`k01%iwBe&sr9psrgJ>V7*zfOb6Dw-9(>8(S{r1`s$1|`JKN{AC-G*hUIH|AYMm95 zh`0K?!nr*&B)#r5r+b!21bccJ)^iuhUGSY`M)~9|smAUUy@lJfdhTMv93VOLCi6BN zn=#oTxm#~+(`Z58;7$(R%5SOdimEQniq=&Z_onh!u6-JhKGla88R_8uK=|h`}_A<^>N946cI%cWyi?gA`QyMbue8PHcT5`h~*mSAQ3XU?BUQmK^ z(N#-lmxQ}D#dq4w`&dWrgiCNsCDLh;v9_cv69?=yveBe(d*=eh#)8&r(CIbasdKee z*|S8acT_RNSg%q%Qqs(su1@8DR&9#69X@UH`OmAJf3ljkQhTHn(JnNnwxrY5B)y|j zS)MjUyGdCQZcTPt)Dr+LQ%yuwe{Mu+>bW~Mm}st@XZhCEA*1 zB>q#+-SMpg(7RziLXd*a_pgmqj(QxGHD6y zNgStI2o}k0y|so{pP!S@rfDXf0ozq$8O@zUymjE7qy<~Ysn)}GtSYcDkk*2ewA;Sm zp6N5R-cm z%1W`!0}{{t7V+$Lq0OsiQ0YdNR#+;uK(~cb&DFXPmZ@*ph+`u|k@qUsr~nlhVfd&~ zXa_k+0mM|~wFZ=8?zUu=SZ&F4aU>V=`pCe594(qS(}NVE3CaS{PM6+`fU<(B+@Er(Y`(S>?`}|0F@kJ0+qkD!D`v50$veNlvi( zwKr^GTTNS7CGU~jJ6wgV`k1atS1Fe;(_?Fp0P5oZ%%`I#I7%&FR)2cvN2NoUJ zw&Z9hS9VAMWvmHFU)D|$TdX!BBuP|8bG7j`cAQm;}tbU7?M#D0IR z0m$+uJu5nQPZmpit`x~z`X*_X-b3EiX~an@j5X7JF0TS8)e@;`&`Cd7LpIG!dV!oD zauU!yWB8W+m$uFn-Ct4jSwNVhr=W5Br)yMMz84MyY*-Bfj}f>*GmwIF6HY{-Bw8a* zDRCs&V%*8aXy>K}2#iLKG%Yzf*ojZLPxKdKO?o*d#HBGDt2b=X+&2T*EZj#+tS)RF zKC?$Vb-=CtJTKvflKRS&B;43wo{I4FI+O(EY#&8Qq^5<^<)T9(+^v&|iMUuzt241F zAl29f-01{6iEqgOEukM_2MB2J!@G?*H-H0Vl!9z%IQ&HTPRGCmu~psT=zW1lT8~-p zp|tyyRN&rAX7^OlXnRey`w~DfUm_t*CaqjvgPXd!$%?0kRj00yK7aj%wF>0e$be$j2yESeRqW>L$h&xuvq5@$jPfC1T{h-c|0qY%a*iE~^Js(>uu z)&_;LLAdYGL4zDOs56XE*>v3QJMMGX$_PfDLloaAU2yvbTXEIu^jIuj&!nVuROh}y z?-;a@vg)jCJ#h=Wyr|uZyJ+!5l4OJhkl{`EYQ`|&*1R|UZ)Vzu%OK!`LA~^^oyn@% zayE^wUOyG52v2Z!SI8MKmsUwYbNOP@naZs67Bau|+9=mawqoSY!dzV`?}e8ZWVtfq zpEQ0rGZ7@8EWaiB@6`DBoUwncMg^)VsdC?8X9ZVQh8U$J{<|apmrH+j=RdqFc`EA? z|LP`6zJKQPCHuZnZK9@fhCB_Zq*G*QUj4RGO=z5w{F9Pf z=5)kZasMz0PSsnVeWZgYnM3+an=rJ>Y->)+lF>R7>$9yn@jy+*i1L$bOIo+85*;PC(YcmFJHhRx zUgy?kcs|yqH))MC9G;B1{rAa?6`JL*T^j)!Hr&A|mRlUYT mtAezOuzX@&5t$)%GoUP2)%a0000TP@PJ5Zb$it1s@uiApn3NaR4A98UQ%`6N*>^0Q}_v zfDKy!K>Z~Ez~P!j*mTjZ=-mT7}5y5Je$9|oWJOAJ{p9;5MQ-v!_TV#c`Wf9>}fsgctcAxLsOi%*GZ?SK6=cp z{J<{x=wNSWE^2N#GrDG4h2H*!rKrO1$N-WBxYYTzuX1(dQoKp&C+P61@<+qHR-zzu z49BETn`-P672Qf`^jQ`VxiKlfJ#a*g!Vc`()va#dw9G+nuUf%e(yhli*Cjv*kd}(| z7?1g}!!DyC1INoAi5Lt+{(f2ZT%~)0v!+*rrS4w0>gs9A3U3_$({A8(g<**z^*cIs z6Jp^mK7F*OB5`g8gG)NnIacAdw2UQh2&c~!E7ptX*Y$90bfv4#9vZyC#?Ds4c5iCH z>SFoX%Qr6$N^Uk9t2z*iHzB>{Tg+ExAFy-T!QusVf?G3|ei!W7VmSt0Fb8u>K1B3@ zYO)D^S&rj}V&!V!tkp~y4k!FN-vW8>t79%4TQc16!KWYSigpZQ!yCQKHS_znfH8aZ zCFs`KXntMr7qUoC>dFT*^QLdc2^FpGISoAg@fdu{{Fk)2PixtQ-+{ievU-*=`>VI)ZV<&5U3jo*`8nty7t-Xy1 z0MV&&bK#Pdo%AMh`aNoEh94vPSD{ANg^h4+Ux=$G!9lFrY70QoL2B8D(*m*}?T-;V zw9+E?kn8uw+f)9GBs4IrEhZh3#`mY5Po>+DYc$nIBG38!gE4&e2CUc!Ac@T*9iBk{oY{<2|5>Y4;?hC|_M z^?Tc^iZK}i$#4gJEGFcB#;e=Bk@}2iU+2%iK{XoR`R+^*sQ_+Y;3VYn=sCy!0HQ2N zv~Srg0^L2866RipV8Vu@Gc#apeG9W|CFf&}^mo`!>v|MDaCC?g4)@BydHmlKx_ce8q zQJIg!=|Y}}pgs>1Y{2HS*1g+$aFLB_FqA^G%gC%l0WtuK#~89~&=}H6_5p9CFXE3I z*7>kl8T+3PgHygL*M8Wo2m& zj`I4{8FoyGAbueEmfG<&HzlQ>R@Yi&+{K<-f@TqXy~m7dh={YwFX(@}d8=Ep#9+@{ zRtnQlQ+H+6%aOO3Oo=O4+wO~WFuog+sLD=C&X2;-B6oYpnoLnUU?6zTB0@D0WGx2m z=AqlsGi@)UAmAPX=On?n3;-Kerj19JvXbTh$`D9sGE`G_8@6KY_+)OzALr7+-sDXi zwr3-Yc$6o8)0?9VV%&r!55g_J(AT@XkY91_)!mccZ%#$oqqS;}U-;paoJm9Bl9|S#{9S*A7GI&Wg!qhd8p% zjej{?LrFjnW<0)px2tm}1U)S6dcL8OSHWpEw)qXo_uvktMM6yHlU#MT z(}-IqPLB#MsAS>rJ>2&7UHGw2f}ihY0$t)ET8O|s9dv7qDS6r?Jd+Ba+;4Pigh74w zEA3Ej*yW0eIZS~W*?oV6$#0XOar(TKhRv`t{rP!;RNYiad?a8(g?xh}6y9$R<*?nP{)cUF-H|N7+18L;_P&fv8Zi&nAX>{fYt5r_+{s$n!( zsj?~3RdirTA;uF^k(uim?Cb-$i?q7KL9gB^{^Ah@{i_Zp6`QT*nXy$)tF|NyzlFW> zWFHD}N;IqP;@o$2^7#q7ylgv@10E!g=U3!PMd3N@IL306eu{zMB$CY#O>L;i(rpN( zglRBz6AHRJv(-KH4!9HFl3C)p{J*88RKpY#I#-jo^*=lKfyY@khlhNrH5CR=D*c+( zhD>E&{icqS=K0=;r4SY9W-*p6N8A*?Z0UT^7|n#C5;^{L(;_)dSDnR)bQ=2+yW3lI zI=S_=>Dl)6S^k&4zbxLXss9Xi%yHj3ZA`g3>nCdr!Y-PR2I7}mcrF6rCd8^oBLOqS z0hJhC8}2W1CH;cX7-piUrvJ=yxN@=h)6tA~7<4w$RG4T^EbcQZ`QZP&h)-oAQXCRN z(u~io(r6P$0uw0wrfquTC&XD<_{rH6bL$vpXYI(7o2Q{surx?*Z1y6wbJ7XM^zUO@ z-^J&&=oz71Rkz=e(FFz>ew}TjWlpNnym7_7U+k9A&!4za4=Z`vpJA_H(?%cFHhXQ5cPDL7HYc*%_^DSoV*S(p;HPheA_o9m@kr)Ok;=wq@ z2~vwI3&;#T|tfhKQa{$x14JVt&x4&I3mqelVAttoRw9Ekgoa)a%3 zOZ)Bsp@QBex1mu{qPjB~sbg>)K@Lu5)Tn8Oi=&2qmV7^Dr45ayLE-9cjT#?5FH~z* zK)$^pC0~%8M0i-l1dWkR;aOwHebVOicKAWVmOe7vdY*Wn>%76M1f)e-nfO^<$Rv0f zEc#}Shsa5_Ts1l5E)&(?_o59NLtFfE>~MuKV_mO-MT_^DGCMh2I-=|vVn<$H9{Jiz zr?9fXlBAbz9dn#epV|B(C9#2N@|3roGbdRDb)}F3Kw(3-<9^ql*{a-7ooViC)2OYy z8VYp66XdD{LR?cMPK7xu_6+o6b?g?e+0bWoK1iSdzay-Cd~|Ne!iH1yW1GegfQ`De zSlSsf-bkMG$AY|qFu5re(UFlLHfj>gxWkDNd5^xUL117FMl&?-|6v&K*(u4QPiTuh zU7UQKYq~BJDO7~-BXjId12WSHtqJjWn5tJEUc15t8UjdKwyv>y25E z?bd=a;a^=^2pun|+1P`hUYoFk-J2eXArE>Ba(1cx+{{_oQ9Dc3XDfI^5osqkBe4;q zScyb|?2%aa1~Szuu7~m0u{PQHoS0o=#I;;KjMzb@)Iy3@g`9I{n6Fa500syjFzeC_~OiVgp9hUSHiS*Zy?3i2~L!RE$>$;4EEJVW7a zzxSR81gvVm#`@Gu#?H^#Vb7()$1Og_bC1fycCv0)Zb~z)D=2XVV80HabGO^Rv8ANn zo^ZYrU3uxM2qN!|hC7p3|E*}UGcZ_|s=oZUw*T-&QdFYIj@8lEd{3Y5yX~LUcq7Gm zvE5;ouUArTsiA^O9NYPR_cj=MW%L|gl#Qn9TW^Oy=se&l7JW6UKFT3ba<)2<{F%CV zzvKr|_sG((gQ@%XJW%Pu{#de4x#_Z1!a}-g-5UMSp3iJdnr_g#nwVqeB%*fC>fSsf zM?0Nq~^nz%JM0#RO+;29684S^A>mkX-4c%;))Q>GYdWXkJUX0e*3TlSU#Vd(qc#~MM8t>QWA>{fzYI$ISM^4oZw^B#?icOzH z8vdpNpZ!UbdJjI;PKKlR0}Gma|9DYB1=clp&InCiM&hXN--AM4Rs3oWp2{cvemJ(y zfr^L=qe|uyVn;cVA6ZK3MNw}Nsc0i2+;*fDa%_QA>GuI_9te1SDkdh6k1L)KsbuIo zM~{O-*xWR}3K1Ey!Mmtgv&q@OaJ^M*ye=Cx%_n;8P?MFd%=ZXRCH%EqMbUHd|Q0=acvs0&8 z(h9xbRxCr)F%szxsuSX)w=(A=>CG=z zwCbjn$k`}L)taK8sCpwo`PL*dw%=XBxds?Xy^*rRd^Oue6-blQ6E)iKi|Odg1rz>f zHRy1sH<{Y4RdJ=;Qg~-uCgr5Fp3GGo+~(cenQ-%=>Zdiux3l;3&Dkrb$~UCt{_3m= zn}fbd18SA zW9)z841i@tA7-ONPyQb+(3Ktxl!RmZ$Sa^r*V4F3XhzJR;~QY8YYeNPx#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBU&07*naRA@u(nQKTDTNKC7B{C^3G%8KYSM-hu(@>1aq}0SpiN5s3 zC<@CDqKGL(zC!Us5M>#aX}+_!l@%g%10NsM%&>fQ714b4ewbGG{?6T(@h~&a^@zu~ zmorez*|YcBd;Rv>|FvfPEiW(c$&)9uXV0EKeY(zknTEi~$jFBeAN>6MbVWr)=g*&i z@ZiDk=F4ORzzgJ?H*e~3Gt0Yo@BTDjCL;h|AnS4S&y3q-oc}Q_aNoOkPnVycZ^k_} zxUXNoZpLkD)O!0Oy02ZkrYkNk{w2{}Sy_4H$dT~y@Q)uqYI~fPme$zVDC@(TGcz+M z1r;?zR8-WLFJC6bnyL|j`}XbIy28T3smJ~G>sLz8va+&Aj~><3)L2+pXt=s;*|J-= zZpk{FI(3S=YEl68^z=~vy?y(3Qmkp<#tYq*D_4xdefI3xy?gf>yRy#C&iV7_4-XHE zf#v1pix)2z_usyKYi(`)&*3(TgNW{uk`f()BEy}SnCR~AZf9qA;J|^OKYtp6Kmq2> zn`dQZMa12?bB9M94p&##1q&9OJb99z^xv~*PeMY17?qu!ja+cEZrwT}Xz9|WhYufq z{`|Rvg9C3>7`b@y;>(vWSFc_z`nR>UZQQtV&YU@+p`o8XeG-jQbhBHB4jr01ckcT2 z>kl40s2bh5xw+2H&W?_bCr+GT;QROQv7qV^H3B^sEn1Y6lq5wrdyi!?MQm(rSXh`? zgUn4O2krP1xbNP*t5SCp?=3AYuV24r)~c#1Lqn`4K0bciwr$r1;Teogyt7Nz@T)41y?OJw=UGetzR^n#hj2Sa9{`vFgL{d z2btsO(W6pNUPe}~Tv=aV-__N{#)~PGZpt`lv*xM5edERrmFSiR`}+ExIdev4D>XHB z$BrGMkq-c%|Ksn=%ggKj{rjSwNOy5@2?+@ya70Ucdpj;kVp3XK%9#+4B;0szZEfAu z)P%L<=;+OxH!Js+ zGeNMUMFj-~X)M+rCHQJEm?_)c{1+__V%LFOhcG7j3rM?X zk+Bw3`;WfFBXdT*RZhzECNhGQ@dA>Sm38UTC3JiOv#?>PP)0@uhkg?O1|V?j^$nf< z-{77A->DfQaI=M@VuCE1FB1_MO_kK${3VSSaVkIaWg-IL1v07fFDyml6qbOwDF6Tf M07*qoM6N<$g54(_ApigX literal 0 HcmV?d00001 diff --git a/mod/maxgui.mod/maxgui.mod/doc/osxtreeview.png b/mod/maxgui.mod/maxgui.mod/doc/osxtreeview.png new file mode 100644 index 0000000000000000000000000000000000000000..fdccc10115fc17880f7d8a5de0f7f06672240cd5 GIT binary patch literal 4060 zcmV<24Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBU>T1iAfRCr$Pop-Di)fUDD1f=&4g7gkjrE@{)9U>x-C%q&D$fHOJ zp(YR@TzW955L9X)gx;hG5dsP*UBRaiiqbng%KL>C_Zw#B%$a*;=FBsxD0ikB~6z7ZVJM*!TtJGO4!`pq}rc-MaXw){p?hyM24Z)>3(HELALmMudy zGIs3Pu3ft(wTpj3`Tyg7{P^)XbLRZp?BF`T3LF9Mu875J^1g84LQ~wit~#^8eZ`6u zMT-{AlPAxtS+k_PlJ~P`&z3J={@ZWAtx%x?1riezT^W7+Hu4(omoHzQG-;9!daiI? zi+lh6{lEPCK*@-nxq0(u_Uze@9zFW=&p&6&mhJA{yIS0T`st^XDN}y<;fDtg9-KaX zI_EcT+=yS)oR3_u-`B2PtHYfu+HR2ddiCo4>+b{k72Lo6`s=1moBrq3QL9$1EnBwe zaDVg7H=jItB25)3Qe@4VHO@yLzb)u-zkmP!`0?Wv^qg}=hr8*z+OucRT)A?gOypR! zXps*0G-=YPcA7VDPRsF&n)8vH>}L)fIG}LnT-Qe^{XT5iu!MvJU16o)(KA}yix)4x zZQC~IqmSPfOmKhp>=`N;==saJP23M1I+Q9^s@=PHOZi8S9vSufkt0XA_`?rBq)V6X z;lqdVi<fOB{+QNrEfD3f3H0C#`pG{8N;-5&(}={1n|IK*8U<)b`y-Vc8H z<(J=o|K0eaU}q%XefOQ1k9<5F$vb=q@1?*I?z`K!Z;$wfdFT4{ z(@%5e%vrm3?f2e$kCWlUhg-B(s#GcC{*__B|Ni?CkHM9Sj&K+A83uZ6#X7U48l1bh zWBRXAqsG;%SEc=@PoE<77C`W;abU>=cR?S!F2+lv9W4~@8#ZhJ!7N#_^y<}1fjDsB zz#KVplq**b+nHQ!)~wm8RjV2|Zrr6ymx~uKLYVB^x6cSPR=GNL>d5sICrhw#0xKKPqs>rIDN>|REy|ibcc>oxHGSe`TF(iO`0@Wx^$@*5SzB?GVaU) zhD>Z~sm@y8z#Kv^@veZhhS(i)Ujrc9YkZzC-3ojZ31 zU#Y9~%)NW}Xz=vu({ws{@?@x+c*Wf)?;wauQTJ21a%IGve<51mdFP$Ng$pZ_Ju?I! zq8KZ%5Zu+mxOeYf{EIO4sMgR+5RUvC7I(NXwVo^7AtPa9RF9~d_`^Mveg`-fUUfg1 z@3BqFzi5ncFL|c{D;*JUeCZt~dI$*$n?%lf!?zwa4mg`KUQP02%ELpNd zC-1`5T)A>3YH+KLT+lPt`xzcy^y%%}x9O6NGp+^?9z0-`yKvzGSJ;`PPoG|V3s5^e z4YDi!@2f*6@BBMx&>-#1Dcpbi?Kf2aUw{3@Q^K-r#GQ)p?>s9kKNJxC&M-=rEQxLu zN+1HhA>s*hgu9*n`yYS&QMGDSz^z!ZBAVo@ufAfew{G1kSg>H3GG%~3sa>`cIG3eO zn-)$AhXbRYp(5^X1DoX3QA5c{V(-T`U{8m>6-#yQDyY0$gWxrHWct zj~zRPo?)MZV}x4FBSzDHMMt>Xd|zev!WNM2olc?6c3xmMx3v z>e8i4uyJC{3T0|HZI&vZeDVqQPK^GbFKz^;#8!OcZseOR^bEcT4I4I8xKEolP0le5 zijlodn>OmAA}d1Su7Fd`65EEoUJTA0%p4QRi7Bxa-?-b6cb@&hg9o>0(E=lIg9Z&0 z?uu7JtBAQ6uF6Ofg~Hv~ETKHKpa504n-W{`ihC%&$tdrb-KR{M!hQ18TjO50Ze28w zAVL+TXH2OjW3x~wkRi(Ui<5!KyD701f4E!oO*-5$xFc@pcUX?TefvU*Sjamqqu)1f z+(;lYga)fIg-xlYP|ZTNz@-qcjFxA%@G77MQ(`NgaJRXChe2icBFFyy`zK78z~c|2 zguezq@t1qn@~BGBprF~$RIgrr#E22dJ9=5rF{PGFo5eMO+2W~My?QlsED@ll#8y1v z9`XAsJg3m7AZzLmV?+VhrO~5DtLvuJl0~y<8z^kT$yEz>h%N6X!_hv{yJ1Po>}uF_ z6(K9T@;*CDmlV1TDF zitAlu5lOD!wy{AB61XTwp(E+S5$<;0S8@3y=N@j*5|KnMEM@zR+D+Q&NLkJ76n0+5 z5$<;QCW%P8cI}#s70y8%PGjweKin<&CX0w9BEI05Fx23gP8f|$gQVT#dB=8$0cXdK z9h)|7;#HG>4<9~krvPOpPMnA-hOisnRPjYswXoG70faWFjA;^c!y^bAMHR7Da`1o> z5WzF5%dO_3thgZW7V%A?B9eduC~=L)|9$!L<#=g}Aw-LJ4t`-@JKq#F*Nt=rZm)zR4JoBx72)Zk?710(7zQ zYSRP37Qwhmc|v4R5q1ht2HvV$w{GxROxwJ9^K`YK{lFa~DB(D!Y!u~Z&YTHBNEm{5 zAvmt#Zpt?yx!iy;K9NXQZeHY?1B~E6?7$j!V%XZg_10U&IM5pWlm+fYfbb9y(kElk zt*fj|JcZ~tJHi`585eN3=9>sC%AY^KWYXi{DaPRf+cy{4hH{0+AKfbCYFJpq7Qh(< zi!sK1lo%`a)TvWL$vf9sdzlzsDbR=L7Fk!ZHcQALKY15<;|O;<`*(>*LIyzry@9WQ zEML&mESp3Rqh#4X$gG5gHEaPCH`!XD^w^)kQgOmsqOGO$4Besq$?}J`AwCT*S8&J2 zh6S1GgjwOM6M-z-sp1HC`|qm=APXAF^mJoFfr6BsfhMVpN6-UHnILBOA019?xrxMK{#z-!YlEJ-l% zZb_Pfoa0ni@DX^+m7Ef+uq_%J}-=d@fXvbqa=t4%a_<=

      quMBY4XQuwN4B8Gm0;e(0-WtDgdo(SmSL-45=82(gfyhmCI{U6t^n#QbS-R{>Dae#C)jaSxRl&zQB(E#Mrs z6D8akC8_fWQQz+cwzM-oigP`9~ zL0a57H)h5&&D!S>FSn|Di#wwfrb%E@M+EUr5_pEvu>O#xF*BZN);_o3i?|)nagTUp zx{9Wm+}&zC`t8IG?j#uS&YLB`J^Bdv(_`GoyFc)F)@y*fXV6+U9N-?{?hgX~^!l2- z+xP$SXRyhr*Vk~jA={Hu-Fnos*JY^chhusXmFq>)QHE0fNLNiGgl7wiKZqf7h7KLtv*Cst_N=(#iq*64d*A!~W!;}k&(-~o zzFFJX`3Kyakd2zh>;*0UKpZzQzdE}9J@WBV;CqMZ~Jn+B+ z-GQHd;B`O!=}+G=9(w4Zz?6Kf2?(2B`@y7$>i6@?T$9VF| zCj;ZDr=IE#d>4#oo_VG_o_p@O(DD59&j-fOfBy68mg5({_(i<%!VA^F@p$Q_m%8KS zmtPK!S6+D~UVZh|?s)CB*W&fpUteb6F?|j02R{#P@%eP% z^K(4=?6cv6#{lQm2al5;J04FSYaDl;3!EQ6hdjT$#W^P)fDPh^xFMc8z>LL<7k399 z$M50q<9p)vzyl9dmfebco>+ZRe3-lLx+`wK{r0%^)?4G|n{SR=Zni?)j355+hw-By{iu73`#=8ikE?`?`Z)90!4e2Zjd?x4ejWA?d-#$>0T}7Y8o}-s;6baPUHK z@biN3iv_=@K*D&4CQq(MT##AA?wipPw{lgF6H9_In)h3AR4 zJcm55IQPT>F#^mGOE=wgQ*hjH!wqr$_1AaDjW^y{;SQL#n=58h9^$Alzc$1L?pA#|Pxa zQMwp-5#V4D`1rgW4srq=2N?&RC&6b71+>l-K07#|32Ke-1fE8A+y@v5Lf&JZXzNp(rZS9H0E(wK3Zg8HVINJe|Iuq%%jQcp&Jnp#IF?c=@Q5hg~rqsx) z(N#f?Km@>Rq*c&+Ak*Lm@Z+`k`?y#t(C)tb?o|W?SoI3XBI~KAo*Fytv{S6N-g@!z zkAJ)xxWDtxJ4YvBuA(d>EpK_nG5qV5h{xv4nG?J1x@!zve}nka$5yDufc4jp@#DtD zym|Aw(+R)0rXsu`Gz#M&E?BT2@Vz$LXruVVCq7Y)e*OBzo_p>Y=bd+6_r%~NW$6R} zpgB6DE^o7_>k*d`l~I=YqDEFmYvzl*RbcA{r5Bs8AM|47cT!O5G_Sw}C^<_hFf%av zG@k*F=NEV)9(2}bgw@D;`Q?{~j!Q4SG&nA~FHaCp+OfwT8y(go zMvopH$81UiCXPkL@b^j}0`AP-k^TnSp_&9ZIj;T{V^HHP&*&?Wv zuhyjmo(4F8HMP;`>iH-mC?Y4KrKSU#pK4ypv_Jy`*DZ{iy0$?S^hl~RGVTK#9<&%R zIm7!cQVW2ezc+pQ^yoSF+;gi3HQxY8HCNrg1K2Nq_Oo%o*q!3K^B2W4k31T`>8x~r z+gSxa*ID6T+j(q4=ebooubI$U>3M45IV`@wA)VKK`E#qpv>kSiyDnH1FFgKe{I2t! z7%x2bX!Y1ho#!_H+!teFhtU9woEe)Km73c;woQ^oyYAQi!NOhk38{c{PML| zc|05mE7Xaf_J;Q72neWdQb60DteJAN^=|@tQ?k zU06AYdHiuM6tDyhjJXN`u;prN#__`j#O;$0j$hogD1QI=t?`GaZ|{sBRQK`N4<{cIQ%4MnZP(}< z_^`av9lQYWS!bOUYp=a_4BmQh95UySxZuu3amO<^$KvO2ug0C7`xoB5C=TvCH+ZW- zvCcZ{#QEo+zYN{tsRE-n0E5?q8U=tf=f&@Q_`@HL4o};qj6UL1`hznOy-(&;pYfxJWUOE+ADvfat+N!IR7x_(sfW_uONT_*y4= zox0iJxN_+5xO0c?V(~uTj0g7Fy)(WU_w7AC?i#aQ_1vlb2glbxziRBe&putIKvM;# z3kUDJZ|t?|=i=Jk2FAlvN5o6#kB-;A_qBNK`(LldtCw#RFPt|z9zJPAT(jGtII_>G zF>%6#E^FYl7^XO+CaZ0_Y79SoVC=GBczpZX(J}4jug8pA$Hd9Ejfs;w_m8<|RP4H7 zL=2laFjnusY9KOal$X+802@HZJidSb{>v}{xTula1GE}xHANtUfC#I(?f(1kAM19~ zBSzIjJLwYMXULEt-9;Jl@UdgZc0sJ1XO45{8U~Wne0A`J} zo(gE5t24PqUEC)IajSp^coAfK5TSrzPlf?v{KAM0HjJbDtP>Znu}0ju=IU|hfQ{nb zQA1<#)?38=opImjp>b#bjpF7$tH(vFuMtPDxlWAQuwQo?;D^&i+SrZy#q7=d!~+x8 zisxs1CSE=BGx3}ASBu|Y*f)N6ao_muqSfM8^FI^MpYoY_;K;S&ysxekJ8!&kmk)Lx z7>kDfLpF=`c3(S2p4=zKp1)G;fBDLB@TW+~!wNUL;KCAnfzHxj94<20o zEv5nZ+XDvDc%@WdFu-?;1dHg(fs-I z{{>pS2ydu}XYMib<15DeHP?$<`u2%?25uA&ZM}Iswd?lr?4CQtbDic*;ug9}7Pff4*eR`0uL+#G5w`kH6hCBHp}y zVEpB>KJlk>{!hF-d*!%o|Mg^tkmE{j%)30JKg$K0}ROuKt{ z%v`*AoVs{qOuu(nOuBu&IOv*{WBf&{bY8n&th~`DYa=bIL5#FGQ7f<9xfnW&L*%nK z`8eU2tpHj?*ON~^xdI7(2f)ON|3e@8P{qzDUyJ8)p?vUzAFOg!01;rtxj>45bAc)O z10VQ6wGc(RfOKM?&Mby#3ozkztE{q0m9kuT;f2*_0SV7zf>{9r=N140=rq!9y6L9X zdtP+WMb*F}b+gSjtAGzi2*5=^z~{hs!UYB}0@T}VvrWa&Xr4=&OLJV$bF=8HQI~ly z0k2UP$EHdTKmp+iuF{x;@XFa`g-^xh>#Q61Z$2cR{>E41rG3W5Zw{Lfe>iqx{BhFZ z@w=lAidXj=AJ6TuRXjX$NL;@5I&Aax_@#Jg^15+c=XaFf<>HI^*~&v#j4`LJ8;9S} zH>TXRam;;abe#9h*tq!l-8y4@od4|3G4HXj#EJLxiz9FB8)N3J8(-Lb#bp*HUSU%{ z82K`C!aX|aQlCD3D&Qa`L1e|01<(R`_??e@>0X{Px10HZ8;bOzz!D|5K)mB@rS||dXh|E|M0JP4@`oc^L4_VHu z#VXv-3J;j|5p6+d_8{CcJ<$At2tR1>(73AKI`R0}ZQ}Ih{AR))@pR`kSM^&v4jnSATlLCv+NnDZiASfd6@R&E(|G&Nk+JmQF|qWS zePZb^4veKQ9284`zHcmjWXI~czh2iro}9i`Oxv-OhDeE5D_)2!TZ|tP;}-OZsdo;J z`A=;Xm%OlBT>F~?;?_SN))^Dy`rl88@BVVP&U0UllkOQD;})(FqxK%!T~uX-17#18 zd*YElE@g)uc8IOE+A6@;f8h&XSf;ekAVuyLpRa9Bt2KdAwG4RdMp|4g zK(>}&5oP%Yr*#%97p}cVCl%N={`1(w;;k9S$6NDf#gYr=$C3*d#9L?0iMLLf9B)iI zEMC}aTwKz3jhNo~9rAY0&*I9QbNmr;?{_{I|8?W$@sEdgjHS=-761IzVG)0t6!FG! z@z38K5&wK)@A$_fW8*KkZ61p|ubq3sk;~{1s6}8+{M#oU72lY(a?HAS%eeT(UE})y zI3Rxf*Q4Y9wPP;^gD?nDTK!lmsXM9bSv6n(vSF1Jge8RJ@l)TI9!gKSo+S z&k9*bnO8+^L{@+Y?+Z%PBP|wi1nB7)mK_+ zrPzM^?PL7-@m*a>Rtd|hU(AQe*D~rd57vB`DT4wUp9`s2&lzW&QRPFV6_^Bf6Xi}M znbLo=cyOn0#Gj`gAAj$Fbjc-W$C4{9iX~TH5=$;SH~zkGZv3?qeV-WDS*3Sgdqw9! z;sbf1fmh=-S6vzN_un91xnfxS&r^HE(hf-DuO~z-nI5rpM#P(w*+yEr+twz&&V(FGr*#iuC|eu6)t=RL~Wc4Osk0c$Z08J!t*0Xj;sO} zKr(FDu@zoXuH;0YgL~O!3^ICk70(^SyWjAEh4BGhU|f|2&@rkil9K%wH6j? z6?=gHaMe*5LxeM@Mb5Zj*6f(K!P@cs#0l}nIj6^)S6&=%-Fj8Lb=x)Zw`(trKc7E8 zUitQ6F~8q>v2f05)$~P$my264H31lBpE)PaJ9_na@yFZ8Uw{4WSn}qKSi1C#So-#v zvE=VFlgBM0gkD$sy=XS{T;;~uN;`)8R8MAiY zKF;doQ8@6bGhh<#xh+oQ!ufOK)Z<3R^_Pu|Cm-2Ae*5ba<9ENB8c#oQVBC7$s5ouP zmT~ric~zuR*`mr7nI_<*VYR+s;pws8iCe_fYrYy+J$_K!_xefklV6`4*FAAWoO09G z;=q}sV*c4@RGQVSbgObdMo8Qudh#|a*}60lpxtDXO)8Bmo+EFoC;ZCu67)3=CTyHXcddmmtqW@wEGv|7iY{n zDNdQ*DFjU2EM}avS)4X|yO@8*v?`+DWGgULW~c&UuJpl`-hcn%n0@B-m^fqm_}0{c zvH!F|an$TFF=zhtDiwgZSk+T5RCmr6-%CX;nK(v)41j;OQ_{wQg@APtwq67{4hmXN zA?lQ2{Op-vCX*pDol*r?CYT{Rqxxs+5j1)#sL3QK^`*J3N*c3jS|)GQd>0tS`k@E8 z4)R&#uo-)xJQ+SL4j@iC)%7?jIH|ZwnU{D$!8Nw3wM5j!NyGb5$qz+7PAU#Mr;$39 zmtG7w$N(fF96JVZi}%L+;J1X{W!ASkZktwv)4SXEv43@9+*b*iUTo>uc* zYG++T+a#D_sn_L*Tv#!>s({;7T~v0l3g$u?=UxfCOirlhm3gvjXtUC7Z;A_8IHo); z{-7$!T~&@RLVgri7t435t#$SwQ+ZJYg9C=EozarDa=qHUt3kUPyu$&%j}wLW{0< zRT6<``d0!l10h>%$O^dDpd{YrbgeBmSx&3DEL&~7e~T?Q%x|-lLGxy%$GmevTWPcp zOM9=HB5jlQKy%wHJy5w~Q+nV+8wE1iq)fu-0vvYKRH7pM2Y|9YhEdhSe z_WYL7R&P~u=wfc|DXZ%r(?WwziHsmx*>Z}j)WyJ5K*cl6ZMD3sGR3-fo4Wol)#_@~ zrZyAmeMWs{B~*FloeoSRG@Z~!Lv}QA+hiELWNB~Odc ztGNYxbUXqx3Txh~{a}37wO)j@{i=MAM!No7i|tUT)r zt4#c@RWUCpc$Li4gN(x^Z`-Q4pbch>>)o*7{n&Wy=L3^OGW=BRQO#!?aQKw@EpVC;&Lvc%g0Yp&sMxZ|e zybE-I8KG1$i@y5aS!;R8mq0&z)Tdzs2z~$)$-UKzF5ypuDn*SZ2aO@MevRs-IO(wu$m`R-ja(ZAt~0`)MTQ ziPqd#BUhb|fiKY9(S`Y~rW8(zl}ffHnWE;on(MmH0l!yo+ieu6T4cy7Vp$(qT}3RT zzA_+Zd2v>#&{lK;9V9@P@&d9wg8Hqo44x>4&$`4t-^)jyK zvdUL#b&J5w*aNQAJ>S*JmsYK^c5?5~b-IUVKX3Wl=aY?C{6PZ)Xu( zkGHm;v z%hTfIWX5^ff-M8LdL?9>trjAjJ@BfQa;=Q29$o9esJaVnW>lLa0xB!r)};WY+}2qH zJ(o^%W!l+NV`Cc;IPzY|4UidBpv6M0PJ7_pl9`uRrY}(Hf>%=p+R|dnS%=J&u2exQ z`FAN0-1neP1nyM221Xkf8HZ8v$JMF>(_nRup-Nyx-AdXeeH=-Ps;(&Zu=FGyrld?r&Y<*iv! zK`AW7l(*O@TcusQ2(HVp2X%T{58rCO;FYo7x+Z2eN+s&c7j<6d^_-b0gjS1`DR8ZV zFXFU|L8tJ{%PTAGx?VObE|hXwjkFn);Hg6?>bi$lNt&o?FLg`Ifa>gkQeeGxO>}RA zlEVxtwx}so4l{M_Hsr|M0Yt9^_4~@CiC!gBkaDr7v{*@h>#2fP&)Vd)nOCiAYD;1o zHHyoWU5J{>*LtL_<7uhvs?*b|NJiZhJ-YIOREL?2^e1&#k|Cq~?t_D+ztjV)B6U}HTI0JG?<<(|!=Jx2y>Au&XC0Fa_$xZBm z+KFm9pck3z5cGTLMe1H&Ss|e}j6x<5cMXYyHS1Ey^t6b|zGm{qM$YWDW*u!KtriqY zodv4ka)S-m9%R$Jn<|&IvuY~r9HuIz)NxR`(d@oQSIuQh)h|yUT-fc>!%TjdH9}^4 z9Owd4Ioyn^R&(Xvioi>eR+||!KU)QIU7?}ZdRq5AU{uxC3BB*STUG01O^g}E-*?K;lX=t?EQkoy*mQo2PglRo$#319H}#-~m!o2Q12}7IKZW-V2shweZKi^B@y* zt4>yxMNV>)V|Af-NrO;V#?{n8=`7bCc(sesH!I_68c-(=*TzQOC?vD5FEudw0!!tC z+I_(LwAp84Bhvyc&zAOFaM@uUxXI}yfs%f|(L%m!})I zO$)gLx=jmtNid`07*}zX7FeE#mMUWIFyrZgF2uB2#`{X6b|bB(2U<>ZIbu^3&ioGQ zdcIU<=*DuoAj?GHzAKCGzwlnA2cF+D?<|>h)HOEhCVOt+(Udm0i#YSyQXbp1=qjZL zrS|fY;!6ep&iT3rLT`7s;aVw;wC^^j)x}rVLhjT^rk5=NxJeYF)gIqOM1kzW@64~O z$u-ecUI1_@r|nH~LDL6k8tR%Ey$eC}c7nFe?lw+`dHPoB#;v2g6ri5lX6-m`SD-Qh zt-c}yfT7+p?Kb*`Du{43PpK8B4xq{k)V1Vf4UNhgG*!Pck+-gx-|KE%O$*%jAX|uK zz6UC6R1*&s+UP~2IWePf$uG<)K3#}9%fN03Rgk$SLe?~yHBM@yWVV%)rWYm9I8vM_8^P2T1d!Jh76!iXQ}WTz;n}$ELZi$MwcTtDY`OF z^?yS*ZWA5WjkMZs<0>!a6PYK1F0kB9M%jcqWmeW2&XsCr){(WvWD77aG-!0m^aWlt zP{v?+%{p{*Xw6~kdc@io(3M)sGr>&B7D5lfx6+BBJYAgGHX zSq-YrTzh~iUn^p2#Gw*Jx`&r?+N|j@(-oB3%PCFF#NZ_^)^)Y+s94m~Qh$(v*1c;r z0%wA6TtVL0n32-iZZ)iTH!adKAlI3CIP>7<9?Cpu#3mS2gR6@-jn-PK&3w4B1r|5k zQ{8OV@|{K6l1y=V7GfDwkkMe?pqha<^FnC5QHbv%TD1CfLym0M@k~IIwcDuEjJnM@ zPs@HY_f8;K>*%mL3nVQx)aA5ZP$((5G#V}sGD2FjEJ1I&LbPkmauspkv*L5zq2;94N@tsQ2M6Zt3<+&vT z4{ybBmY~j=Cfifj9csMEKp6uCbT`s^df*I!Zi=U}MNJ*t0!denS(U6LO)QDOGu^Fs zGSsCLdg4lbU_SL{PBKgfN)(w3YBGtT`^~oXJ#ejorZN=F@S-g>HadGyw-19#66-|Z zS*I?i{LGHNj*Hdm7jc+&eQ`ED-`Ie zU&tC8xlmK!YJRHjib{2{0*0yH^|TpJ>$+O+ZeW_=f*J1-Bdd^=ZUNXVe^qW)`^M^& zSsp>PvQ^hYuBm|bi?y+`cmFQ#LXKPP1B`UG2Ojoy`-nN10qEYSyh^*wDvp4pUDBR>d-4IxC=4y>{7_ zHvUjEVT+{Lq^if%d0nxf>%nKB4$&1 zP|_oC`YZK_HMNj?1ZE^=UhHn+o(q>Gh9%vscG~*%PXNg#h2%*O@f)s^NTsG=dv1Myc;(I ztj1u7%6ipH6vHu)ZCew#Hp>b6e=zZM#@`+D(Y{bK5%<9%~V18UA+0(n+B zYhxRl0ofN~E|^ge`!=K1j*T!sfbS;-Gw;}DRJLlO+ehYI>zj*YG+5?Yi>uG+FbBSO zLAZz}YZq6$PCcQT0=N^nx_f7gfKy&>u&flAnI%D5M@rl(!s18;0>(;D6zX(Dr{k~C3u2BmIY zwLQurZIfKF&i9~BTkEA+X9wPk9x>G#lq^8&D6cl!11(HwnYz@Ks~d$V!;oDJ8Oz}L za-B307lM1%s`r6L+OGB>+mZ=rFPY3~W25U0>LO;_F58m2D{CEhGdb;<()(I@(%QXx z4P^J-3hBM1yj=gPE$o>GLKbOz<4;>+54@RCt6bSGHY#CsV`cBsRj_*Jg7=7(7J0gU z0w%#A^x!{)aRngvUr-S0DzdJzFs%>N zu8HU)#~V7emC;(fB1)||Dns;wfVbjsDj^U{wn&~iWk#jqnQ~E8o^pUamJ_ z;M1Vk-E$$^D5SK5O(p`*x*N3m!!*CE@z243nbMcC_~Ux;`Ls#%vpvVxNZ$vr>FIb7=KQ;87=L(kmag;EYl^ZN{p06 z$-u)w?``O9O_gZ0$In8Ha)O{67JJRsnx-TtrT+eNRDa~j7zUQ=+sj}|asI_FZYV>HS`HF7xk+qO# zJgxR0HSMdAd3lwhYNoNRi?psiD4El#Y_K<`%4*QTLWFA))XrY-*LmA&TH(9qAdfEb zx>@^<=E~0JdNkIwLbbXoU34oXtW}ye(5sUsre0oDc{ObmQfkF<`+8M(sq44XXS!vn zY7a7(L`F+DP*g-HXjk3Bp#PkAN9;;8+87Nzz-U%f=t@8E0Fe_~oQs?Eh zTzXpN&N2f!KGs&6SQlxP64P#6?_Minb&i*M zl~R*q*MLro3tCXng_tkAw3{JI2UHEFX+X)4F6+4M4M4M!tqQuEK&up%@6xDKe&$bG zvPE*cPtQZOxS-`?O$ju|L>l0&GFfLW0J%I4GcGaIg_w3H=z7L^dDW!2l~&eUmic-y zt;oD<5iF~1MoZd*ESfqU*5rFo(%3pLTk<_wKtb++&jd570`nZWBuC7&2kO+_ zw%w*=nC!h@nckq3)ArWmpyZI4nRH~9Nm{M+LIMHW)NYeS+9oIPN}8Cp+jw!obKT7L zGuwZ`y=U9xs-+zmGdoW=40e8!{A?zeQEja1Qs0fivTx|z#>-0qtR1*62yZJ*>@DS$ zwcEH*Mpau5VBfJw%~*OPm}zPu2j;qwmYoalWjAitF3u^&`9J-Vr7fE>n|oHleD}t- zJS{JRHWe{l*=w0L+Z4nrV!G%miD5J)$utS2;(~YJYH`7NTwio~$<}k;tjLhre)dMc zpp1fQP~4n@T&{17*Dd1$wAw|6T@jVD+&2x2wJ>^+5bC1l_qttGb?IzA+t~s%m zy2&DxoWq@?Re7Vc4sPg?nJ%THcSs48 zxze(3H$7Nh-vbA$HbypC+SlzP=1w%3Yofa%;(*s}lBc;}sZ@(7=cz-T(VXwEKwBi( zAiea`OUn%Mw93`02SNsB78B|U2${00}QyE3c#Ox;DmX60DUwoRS48Bgn*fiN&O z?$`+43opuylijm`5mG;3*4VNok)dVaIb zK{Ec;iwOiRH*{vvs~c(Sc5HO(BX4@lJZY7i)v4dXU1Avcr88+_=0#iTDbq#W@>+e? z<+NFKOwBs#c5HNE3|WP2OH!@a>4H+hkNa)fZAwZpWfn?W+iW8|?-6spwoaN@5`AmO zF79h(w%gbUhZ*#V0mW)TleOCr@m}J^o4YhI%V{0Z1a*@L+#_vWRMi!)Z$}D%w-JGB z8Cbg&n#?*%`{im|xaOzcR^zNdDGHLV(&CD)=rf!7(w0eHs%;W?yTF@)%LU&h?QE02 zKah1|_Jnz|YMLdf=IXri;~OqdykT@{9lpsj0SSLKB= zE}|+PP>n%v?Ca~y=Dgj;6ZR(Btf|E7jDkiSrV~v)Vs0U-UbmXxx)8^m6_?jknGv?F zsd6Sq^d?95F36~?tfRIqh2;t_7t^>jk&!oBd@1fc(kgqr6puzg*8GDe4XWAIhDJ!6w2>mRoq0kgaX9Qj8Q*TgeA@6Ow zO-Z7d>1SCm$i(1TW25eW%i!l$vWT{|J!0&})feIy>IC6!8yl6w^IdN03_qOu(%d&| zAs4MhJnwX^rO)cbY{b`rSIN9@8_4HB)nx;rwCr#9d+T=p> zZrW|!7AY&$YC52NYo@jBO-`FFu$s*2yl=1+X`4*xe6O%p>_KLWl<5ofLuOI3jm4)% zNw0LN2dx{A zk2IZLjG5J^YI8lZJKK=?*y=(q%a1efTF$sy0@g(vqH(4GL%{5A$yDd%RWjO80B6&F z<|d<4zEA(o0AwPX%o#D;oiUs4>xv8N^imSjr~*qjwp(6lVyTGWW*xpsUY2$+k5(P9 zFWlTRRCDP%YRu(}+NPskY-+l!d~miOL)NXJ=_b83GM1t1<;BLvcWaB(#{N^IaaO){ z4wt!X#^?6N{!_v2pw3K`OGN~yw6tWaf*P_5z4bk)+lGnhLR+7&k{yyS=D48atuqfL zuiMOB(OHMK&5pXTr>Lf1zkbzXOa(Mue_E=%db1F76S+2uE_V?xRl#_rX8dbb#w~R^ zs0TtD*F@D6l-g=~Yt~URperf6ybZ_G3hi~%UNYAn)bY4_0lW9CtGr4JF?aXQB!^0I zx&LfkG)0aJ!2an^f2yjiseOH0%1c*xrNvj~eCYgamKvx#jOVMa-g09&UqofOpHBPQ z(W+etnQ>fZi`3+hsP><#G0>=6+Qo(%f;!=Mn;x;O^VT~NGABhBDQV=)%Dp8DOldGR zeesqW{;bUg8*Q{v1y~#}WgFOTQ~A>}J*aE9@yP0}!F8Oh=e(XGXoYD)}FjTExA$P}+q&^E&W0a$b;Hopb&-a{{mPo-HZ5+&!k$57xxp zmKI(L*sSTX+d_^=t9vfgdC=DR9_Stmst)t$n`vp=`X0CdCNt*9BC(#(rfrwrjqd^X zTu}XN=6Arh8%-Y=!8LVIp^a|Ugh=dmMx~0FJIiF7d-&q1Zu&2^f@j`dz5$2^KV3rs zI|^9-?47yYg;8cDqg zG!nZ{f=68yc)JAAy%2PdT+e$w>N>NaR9jZ|b;dwh0|mTWDwP&uzG%)G95cmOR?a10 z@%;g2{tVEjdoH-1Ry~$9VyY6y+hs};!;(3NyB(4VsH3&&njV|XIKWfGx!cS+Th51w`7s@@32L3E>3BrLJjj+I#{;ZpbEYm_xhZ%0k z#PqX=O8i+BRie{a#9C)yWXG^sV6bZIrUYK%GBrn{Ab}M5_P=&KO~F%uxBl&${OV z@QJlowdX=9J;)dWKGr5ZP-pLwGh$XW$i(05(|6sgG6g05fVYjS4AJ|!m}8bwf+hnx zU5KH7*j7iXT8!s-nwY_gS+NKfGwYCH-QY2tW ze@05cpS`3D&{tkwC@vs1Km^S+v|4mvilAMS8eP=^oYB=+kgihKRcD>|7cT-_0N$~y z;Lk)f?gY*VrA&k7#q>&0yCg(a%N#?}q% zIEytctbD6bZ&=g<0$Bhosx+bkZ&`!|Pm5!R=<2(WSCJMW7jLSzoB&U$EDP|IO0YU@ ztEjsq9d!QH-DWaMOXYbQHCz*0CjxgcIxkzQd}XeQ+Gg$!GCla+SMarIb$k@y1;AC%$YN*1Q(&Wi6J0x)j32dvTW+tMON00+Z%_OHap&APBVJ)9JHlXKhl6~ zXYp*KXB=oZS1#??s7{L6mQ3%)fR3|GQxjvUO}tdvZCa$c_Q1K=tZ={-pe|+5O+-Kz zVEr{?#*FAWeB#7_=O?1A+ajrpOlDt?e6`6<#$}47Zd~PROMETU1-4e#m25pdAXr_q znn@Eg;Wu>wb$c?j^{3TRtnO%|pCz;U)C(^2FyQfU&2VPI;rdvXZZp@Jl6}1{u(RE8 zumIDDiU8Gi5r#mZ3o!r~pgroyBctaV+ixGUXU(d74|F5vI-1HCPmG}1W+2&)H+6d2 zl9DS+0knRuiz^pz>&ezdjaHHBx)NMZ%T&R|Gj$6wvH)!h{H#gH}@kuXMRf zqBcKL?Ui|ZIe@bTTSk|8`ByRI?OWd1h+vAKdfJ>hvBQ`#(G#72haPfBAWeXR22X+? z%k~j-_P|9ps{ZoInksoR#-I-PzA>K57qufI+g?vCGHh>_mn z>$ANTvTj_LBPxHJF$RdL-r$%uHf9Bfx-ML|ruUsUGuLl#V$Al-b?YPDp%FM_T5!rK zr^F!#9}Kwu3$&w0kB$iwCdACn6X3y+@OnX^ZV!gcVa6#h2W_dKP?9pbi@1xxn_Lqa zrL?N0(bc7iPG=EhS-ZF|!ngn{Z4i7FJE0-#O)_ zw3m0^D%Gl@Z>+NrNKfqq)B_JZu)=8@l$bVcT1=llJtlYF0Aot$F^&^EAfGyQ zYBf$e>7;7l^&I#;toTko`Q&OK%tV@@ZJ;W+KI(*k4e+_}}5 zH*elM2DB6$*pd?Wam#@g86{8kIgpQEPV9u-#>f|7%(7o3>-KxI0g+G6s0kE@Zj(%lv>7-CI))D)-u)T(O9KbkNA_BOe|#o9R`=QTd-#3*&UMF!&*|~xeLv>edBJ1Z xIn2&=9X9kiU`lZY+yQ?$ZfmZ&<~#8D{{Uv;7f9;E%Ul2e002ovPDHLkV1mFq{a*k8 literal 0 HcmV?d00001 diff --git a/mod/maxgui.mod/maxgui.mod/doc/popupwindowmenu.bmx b/mod/maxgui.mod/maxgui.mod/doc/popupwindowmenu.bmx new file mode 100644 index 0000000..3965ea8 --- /dev/null +++ b/mod/maxgui.mod/maxgui.mod/doc/popupwindowmenu.bmx @@ -0,0 +1,30 @@ +Strict + +Import MaxGui.Drivers + +Local menu:TGadget +Local window:TGadget +Local panel:TGadget + +menu=CreateMenu("popup",0,Null) +CreateMenu("Load",101,menu) +CreateMenu("Save",102,menu) + +window=CreateWindow("Test PopupWindowMenu",20,20,200,200) + +' create a panel to capture some mouse events + +panel=CreatePanel(0,0,ClientWidth(window),ClientHeight(window),window,PANEL_ACTIVE) + +While True + WaitEvent + Select EventID() + Case EVENT_MOUSEDOWN + If EventData()=2 PopupWindowMenu window,menu + Case EVENT_WINDOWCLOSE + End + Case EVENT_MENUACTION + Print "EVENT_MENUACTION: eventdata()="+EventData() + End Select +Wend + diff --git a/mod/maxgui.mod/maxgui.mod/doc/redrawgadget.bmx b/mod/maxgui.mod/maxgui.mod/doc/redrawgadget.bmx new file mode 100644 index 0000000..949c61e --- /dev/null +++ b/mod/maxgui.mod/maxgui.mod/doc/redrawgadget.bmx @@ -0,0 +1,89 @@ +' redrawgadget.bmx + +' version 3 - fixed to be compatible with virtual resolutions + +Import MaxGui.Drivers + +Strict + +Type TApplet + + Method OnEvent(Event:TEvent) Abstract + + Method Run() + AddHook EmitEventHook,eventhook,Self + End Method + + Function eventhook:Object(id,data:Object,context:Object) + Local event:TEvent = TEvent(data) + Local app:TApplet = TApplet(context) + app.OnEvent( event ) + Return data + End Function + +End Type + +Type TSpinningApplet Extends TApplet + + Global image:TImage + + Field timer:TTimer + Field window:TGadget, canvas:TGadget + + Method Draw() + + SetGraphics CanvasGraphics(canvas) + SetVirtualResolution ClientWidth(canvas),ClientHeight(canvas) + SetViewport 0,0,ClientWidth(canvas), ClientHeight(canvas) + + SetBlend( ALPHABLEND ) + SetRotation( MilliSecs()*.1 ) + SetClsColor( 255, 0, 0 ) + + Cls() + DrawImage( image, GraphicsWidth()/2, GraphicsHeight()/2 ) + + Flip() + + End Method + + Method OnEvent(event:TEvent) + If Not event Then Return + Select event.id + Case EVENT_WINDOWCLOSE, EVENT_APPTERMINATE + End + Case EVENT_TIMERTICK + RedrawGadget( canvas ) + Case EVENT_GADGETPAINT + If (event.source = canvas) Then Draw() + End Select + End Method + + Method Create:TSpinningApplet(name$) + + If Not image Then image = LoadImage( "fltkwindow.png" ) + + window = CreateWindow( name, 20, 20, 512, 512 ) + + Local w = ClientWidth(window) + Local h = ClientHeight(window) + + canvas = CreateCanvas( 0, 0, w, h, window ) + SetGadgetLayout( canvas, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED ) + + timer = CreateTimer( 100 ) + Run() + + Return Self + + End Method + +End Type + +AutoMidHandle True + +Local spinner:TSpinningApplet = New TSpinningApplet.Create("Spinning Applet") + +Repeat + WaitSystem() +Forever diff --git a/mod/maxgui.mod/maxgui.mod/doc/requestcolor.bmx b/mod/maxgui.mod/maxgui.mod/doc/requestcolor.bmx new file mode 100644 index 0000000..f2645b8 --- /dev/null +++ b/mod/maxgui.mod/maxgui.mod/doc/requestcolor.bmx @@ -0,0 +1,28 @@ +' requestcolor.bmx + +Import MaxGui.Drivers + +Strict + +Local window:TGadget +Local panel:TGadget +Local red,green,blue + +window=CreateWindow("RequestColor",40,40,320,240) +panel=CreatePanel(20,20,32,32,window,PANEL_ACTIVE|PANEL_SUNKEN) + +While True + WaitEvent + Select EventID() + Case EVENT_WINDOWCLOSE + End + Case EVENT_MOUSEDOWN + If RequestColor(red,green,blue) + red=RequestedRed() + green=RequestedGreen() + blue=RequestedBlue() + SetPanelColor panel,red,green,blue + EndIf + End Select +Wend + diff --git a/mod/maxgui.mod/maxgui.mod/doc/requestfont.bmx b/mod/maxgui.mod/maxgui.mod/doc/requestfont.bmx new file mode 100644 index 0000000..8367ebc --- /dev/null +++ b/mod/maxgui.mod/maxgui.mod/doc/requestfont.bmx @@ -0,0 +1,33 @@ +' requestfont.bmx + +Import MaxGui.Drivers + +Strict + +AppTitle = "RequestFont() Example" + +Const teststring:String = "The quick brown fox jumps over the lazy dog." + +Local window:TGadget = CreateWindow(AppTitle,50,50,300,200,Null,WINDOW_TITLEBAR|WINDOW_STATUS|WINDOW_RESIZABLE) + SetMinWindowSize window, GadgetWidth(window), GadgetHeight(window) + + Local label:TGadget = CreateLabel(teststring,0,0,ClientWidth(window),ClientHeight(window)-26,window) + SetGadgetLayout label, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_CENTERED + + Local button:TGadget = CreateButton("Select Font",0,ClientHeight(window)-26,ClientWidth(window),26,window) + SetGadgetLayout button, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_CENTERED, EDGE_ALIGNED + +Local font:TGUIFont + +Repeat + Select WaitEvent() + Case EVENT_WINDOWCLOSE, EVENT_APPTERMINATE + End + Case EVENT_GADGETACTION + font = RequestFont(font) + If font Then + SetGadgetFont label, font + SetStatusText window,FontName(font) + ": " + Int(FontSize(font)+0.5) + "pt" + EndIf + End Select +Forever diff --git a/mod/maxgui.mod/maxgui.mod/doc/setgadgetfilter.bmx b/mod/maxgui.mod/maxgui.mod/doc/setgadgetfilter.bmx new file mode 100644 index 0000000..5c131fe --- /dev/null +++ b/mod/maxgui.mod/maxgui.mod/doc/setgadgetfilter.bmx @@ -0,0 +1,40 @@ +' setgadgetfilter.bmx + +Import MaxGui.Drivers + +Strict + +Local window:TGadget +Global textarea:TGadget + +window=CreateWindow("My Window",30,20,320,240) + +textarea=CreateTextArea(0,24,ClientWidth(window),ClientHeight(window)-24,window) + +SetGadgetLayout textarea,1,1,1,1 +SetGadgetText textarea,"A textarea gadget that filters out down arrows~nand tab keys." +ActivateGadget textarea + +SetGadgetFilter textarea,filter + +Print "KEY_TAB="+KEY_TAB + +Function filter(event:TEvent,context:Object) + Select event.id + Case EVENT_KEYDOWN + Print "filtering keydown:"+event.data+","+event.mods + If event.data=KEY_DOWN Return 0 + If event.data=13 Return 0 + Case EVENT_KEYCHAR + Print "filtering charkey:"+event.data+","+event.mods + If event.data=KEY_TAB Return 0 + End Select + Return 1 +End Function + +While WaitEvent() + Select EventID() + Case EVENT_WINDOWCLOSE + End + End Select +Wend diff --git a/mod/maxgui.mod/maxgui.mod/doc/setpointer.bmx b/mod/maxgui.mod/maxgui.mod/doc/setpointer.bmx new file mode 100644 index 0000000..43af335 --- /dev/null +++ b/mod/maxgui.mod/maxgui.mod/doc/setpointer.bmx @@ -0,0 +1,41 @@ +' setpointer.bmx + +Import MaxGui.Drivers + +Strict + +Local window:TGadget +Local combo:TGadget + +window=CreateWindow("SetPointer",40,40,320,240,,WINDOW_TITLEBAR) + +CreateLabel "Select a pointer shape:",10,10,200,20,window + +combo=CreateComboBox(10,30,200,24,window) +AddGadgetItem combo,"POINTER_DEFAULT" +AddGadgetItem combo,"POINTER_ARROW" +AddGadgetItem combo,"POINTER_IBEAM" +AddGadgetItem combo,"POINTER_WAIT" +AddGadgetItem combo,"POINTER_CROSS" +AddGadgetItem combo,"POINTER_UPARROW" +AddGadgetItem combo,"POINTER_SIZENWSE" +AddGadgetItem combo,"POINTER_SIZENESW" +AddGadgetItem combo,"POINTER_SIZEWE" +AddGadgetItem combo,"POINTER_SIZENS" +AddGadgetItem combo,"POINTER_SIZEALL" +AddGadgetItem combo,"POINTER_NO" +AddGadgetItem combo,"POINTER_HAND" +AddGadgetItem combo,"POINTER_APPSTARTING" +AddGadgetItem combo,"POINTER_HELP" + +SelectGadgetItem combo,0 + +While True + WaitEvent + Select EventID() + Case EVENT_WINDOWCLOSE + End + Case EVENT_GADGETACTION + SetPointer EventData() + End Select +Wend diff --git a/mod/maxgui.mod/maxgui.mod/doc/toolbar.png b/mod/maxgui.mod/maxgui.mod/doc/toolbar.png new file mode 100644 index 0000000000000000000000000000000000000000..b825e1a62c2097993e8e0605c03b28d6fd4e6254 GIT binary patch literal 5744 zcmV-$7LVzPP)KLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=00004XF*Lt006O$eEU(80000WV@Og>004R=004l4008;_004mL004C` z008P>0026e000+nl3&F}000Y%NklHz$HU z12U~$r=u%%Elo|`+Cf`r5*1>FL36jkt{EM75eAKgl6W26A5xY!RIu7Q8>@59f|pY) zq%%~Hnk8r2+~qDMxt~d%{qfE7&Heh`_Y%YQfe(DY&-eK}-{;5s^XqvYq?F_`AkDa~ ztxZZPX=`gMSY9fZ@~>i?+n(F)HmvJ*yAA6vq|d6~x$PC}XQ6)^apo8nBB%Jmg$uH) ztE*r?jvYI;;P#Bh=W@AZDfJiozyAdn?6j0pHa9m*Bl7ut`oI7=GNN&Jx4FU;oTL+D zk`rTEcS>MYKX-D~zj}IlL>uWZ{OCRH*DCTzi->Nja<5W7wmQz8ObmA`=OdCm@&jlXlRUOY8{!jBJW{u0=g^__)30uc9vz!mMy6QeDcXB1=n`D(IP5KmTCDHyTGQDNEfu6#`S0O ztY}Y94;G6>2mg29eMdYVXW6o4Itw8XLg040an4y$x7&@^>&0fX0T2#{3r%IoWq>9na52qEOu)D($CVyPVf@pzn} zp`pCB)jdGwBC3T{KsN(?FbK7^^Y6!xYi#D)+S=N3Jiw1jRDglJqRpE(Q(j)KgFlr@ zF*7s6?Ch-0D(+jka-}Zka5#k1>6E*7?`F@QJ=knEZr!?-HBq_X@9XQMudk0!KmAlV zole=^-EFj>NGWM)X(6{xe}6yq_4PXVV~G?EySLD=d%n(&-+f^!pBoA_tShIcro1Tl zRlT=N!VbA}C+yq_PA6k?R$uYcTG%Lxf!}Ji0^sxcOqDB{jnbCQ6Hrslq1(`lxsr=EM2T3Fn z)YjHAF)=|T648Ml3De>fD+8ne&mn+Jc1mS0x_&8!v$zj{|nKt>p(z;Cfwh(sbp zqfw&KD3M5nnVA`?tE;K3tkijSc9zM>NnO6OvXXE(%+%CW7T49)QB_q%b#*mWRaF2) zqfsU%CKw(b&dveuCAszcwH=FvTL0W#pv98g?dHIN1Drj37K_EATj9ycNm8j4$z+m9 zB!bmyC7Dd(bUL#V(A>86@86Hx?PkxOJ-VDKD`p@vsk;;_pe$HCKLlEce8w&iui7hU z7&8x@-?CTG+1Uwz%jKfJzMffN5O~PrA(R39V&HeVT(q~h+8eo_3GYoE=kAZ z@!)hi_4)PreAL(1<8rxp{q@&{5JINYX+oip4t&K{t2GP!3hbE*FfgFygp-q#I#*X$ z=ke(1C=(MCM59q&eDOt1`7^fuisk^hi#_M&g%CnEH|NLx#T1~WWqvY+5R%{g9e|!+ zMzI_0nMNWJ0)YV6u3e*JcM1mtnj*z>1 zk|{sGb!%tezI|NX*~-Z?gW$1eDT$I-)-y9ES0Rv@M-@Wr!aGg(6U*=bhfhRGmd^y` zrcImVbI<*o_I7Qn(}*5hBWP@Fn4h z3Yp^>=J2H*i@g_y7gp0Cu}wkGZ?Ly7J<9l~fh-7-~1?=FOYb)zwi^Q9&#g17PLK zmBeB(lF6iAw-ETB`R61jhY~O`h5w8ndjEvK>Uo}d@*#L~{+sjAdI0HgIE35n)^~Hv zyn5bpl=*H3 zex(4V#{NdTI=P@Pbr(okW~bAsD`Musoa$qtFh&Qz=Nz1A&1_-&fa|UM|5@`;8lA?)>fwqlhonYu3fvt zqmMo+$KIX)-YhjGAOrkrcdS&pURK8aU#DSh#=5+)I`8bmND128+n4+tAR3LbW5

      zr7{eGiiJYCA&@$?+`HG@`dh7Scs!mg*TBREG2C&(q=G zs=f66ib4lgr%q|-63QC|gKFE=Ac+$~^7b9jEIT}M0)G9-{JX(7vlHVIEE52K*t;St z3I6kWSctp=|3@FeQ%|uV%PEAAlh@#TTj$F{e}y$KYYD5(W}~L2CNE?uG+rS@!4Rm( z8Hr(gz><0ZqxMQlg3VmRT)vLQi%4;oFUY)@Ng9`_LRw8~K;x{zlXC}sTC*!8=X7L&LXJ!#sq)U}wifhN1Tydtv io0}}bRrdb}|91dr&JwJr)pltB0000Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBU%2uVaiRCr$PoiT3PFcgN}dwJ1Sf==;J^bXnWwQHsh1&kaZHwch5 zb2kG4ik_eq`6%*{kCdJ*$&{@>@DRup6@UEslahZjUp`MC8~oHF(9*}N7J-ew@IU;_ zPvHBvue_xr`hWlY#%n$TzkdE0pkJ#GuHm|%UvrQHeb8U)EDPFSr}p2T8g@ssJ1Qu& zr!-IRrH&F+xIMfnDy-e->S>>&?8oXE4by*kp~9t-{kaSwE%{TkeBhUN_J`@adCQA&n;cE9MD9GNw%N9aBby@;W$F8%-zkfYy~l?Q!P?N= zu|Ts#-?c=pLTd7U=kcObZF|^m6nrWs&9N8sL4U0?A7~%ihxXg-J|-a*34nf07Xp3IU+WkE?JrXM{9#kY zap}GjgML`! z(6O*-z&L))Z6t~Lxq>2A&f|iz$Cx9F3o4&AeoUeLXqkPEps}V99{%*X!T7if6{m4Q zUwa|>oY8*Gpz_t}2j6FiOG@{t%Dk52r9x3u_BMjbm(y?0ELp#H)NOU$hT=_bvRg}4 zqI@>}+XyO;rB6%c`Pl1^EF$h{AdTc*?fOr)>HL zM9GT@K>N`C?L3*eSmxOip?zo{+Ml*hp*9TxI1ii$&ZFrmC^IbqI1ii$&NFSFLTwrX za2_}hoJZ4BP-a>Ja2_}hoJX@lzWD9#TJeoEqToD9ZdtCGFNR8h{!#)d{hoh*QKHY| z3nq4;k7*|15xMK~$PDwy(=TPJ?+|0@yKs*CLru72x9{D(y7ZB0W7i6c&N&}Wx~=d ztre}^SbPL}9{TCd#;l7t$}De7p-;DyEDL~A-Zt62IY}g%%&2LAX8-IrSPr%;Pv>$; zf~4WC>qVgFp`YyT8V3S5fi=6+@ntMf_tIpTO<~(z_=%;(7aICKWqbhpECVbT9!H8av)8(jpJM?X)HGFI_=aD{>q0F5pCY~6# zX$hHmc1NuLyhgLV%<0S8t9hjM<4`f#z0{632V>%cqb{YCyOkib4C({#v#F YANFwaFP!-)tpET307*qoM6N<$f=rFS=l}o! literal 0 HcmV?d00001 diff --git a/mod/maxgui.mod/maxgui.mod/doc/win32combobox.png b/mod/maxgui.mod/maxgui.mod/doc/win32combobox.png new file mode 100644 index 0000000000000000000000000000000000000000..f5fa2f5dc52ed68ba28eb7b1fdd6c761410bb2ff GIT binary patch literal 1513 zcmVPx#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBU%XGugsRCr$PoxN_`Fc8PnN9x)q@ZO=Dr=mlaqJUo^$P;uZ;K@VK zp>L4Elh&5UVl_x||)UI{Khv`^iLSsE`3)scG?dYutiTw>XR$T#8H!b?s8X zT&g5ghpQO3k4RiysA!Kh9*wku)(Vxp^*Iu)OEJ!TyUKu8wh@LgCs}tiViQDNhh^=J z`C35>B&#jpgI>|9vSBr(bRdGYjNOQ*ar@T9T}{eI1EFwa-40r!TL5eX5sgKJ+EPGg z3_AM!k^wD0=5mx5Itu-k&0$=EbvV`}*rj0GT&bdqKwB5-pa8Z+XQ)PmCMW7O8|m&t zz@SIm1C8j?E-{WC(d~@)QW$h4+W=_j;<~>$Oj>A|f{7Rxk0wnSaOMI6VAY#K%W^Ry zfu5&-xq3{1XdBK>CZK7P%W(lB0R~M3R+^nbmy#ovi-ATFeHXwZ*2~#F0wHJ>bCcOr zgpL#gB4wVFH3HBfDH1zU=2?SwGfoDBWVbd!QoRZmF1S%?ZW9rwHyeLOrozdqbcAF??e zo=6GBMf6sj5``yYL(hgC|W=~-EB^ySG1~Z zToO_`co?i@>_$9|+qcZg>=k{xTRuXU_$mbJK%egL$RP!k0vfzWB}EP0OiIz}V=l>R zaL7^Uw_FNX#kr2#{Z18>eJM(}Rk;&ZGx8@*5-G+H61Ry?AWVD$E8TOtNpr@^1*61s5B?rgEqZ#=JPxnR^B zbK2jI4zsO97IgEwLkzkUe;3fkfrQJYOIw{`xh&|0=aA!S)jRSEXqsC1$&kjYI5&eX zMn@~iplQ5{b2I2-bhLsDn#QX*H-j!lM=QvnX}pSa=f=?-6fH(e3zITv27Ms{m8$9H zI^y5EkL}!__=bLZyALy67TEv<{dk7k&q7@A6erl)0`5#3~#d-T0koKIg#k-U;(XA=U8E$k!ptUoV!Ncjr4!eOCq0vNC z+TW=oozux5Z3>dwJ1E+scFvO=33UXGqSDPB{llI6U9aZl^!yB-9#e0rl<@a-%&$rX zSt<<}F4D}m+P9GnItXa;RbD{>>nZu9cLM(a?&JC6trKC_ P00000NkvXXu0mjfy1vI# literal 0 HcmV?d00001 diff --git a/mod/maxgui.mod/maxgui.mod/doc/win32htmlview.png b/mod/maxgui.mod/maxgui.mod/doc/win32htmlview.png new file mode 100644 index 0000000000000000000000000000000000000000..bb1050f3778b1830773567eb51a4bee560f8e0dd GIT binary patch literal 2130 zcmbVN`8(8m8~%J}CPuayWbI@qEnZnFNn;sHwus77BnDX`B5SrU$&$%(wU}g?N+|o% zIgT>EWnT*K7;_@bu@sX=M#z}y9Dl-ly+1tnecku{!}G&^J=c@vbjDh8r}9n!fTXRB z<+*LH+MWa~Y8xLlus&`RbmN@0IjH@xdvRM}0?ZuD0BFb+7m#;sYl5%MIR^l4?gs!) z1AxD6!3zLH=>ov<2H+$W0EO#Ct!Iq@5FNI)G;@x<{H=H*>X|Msy=n3}L4mE!Gndv* zQBcS?P_~i2oYq1Kg^$Vjus8ZX-s`d%oM!~?b683)9r_|(NA#c_0Ncp^`k~(({%ss$}&$UMxI)2 zdHs84<8m#Jr{btN_tb*6!FG!uyKh1?LY0=An!dDra1g?B5nN=897Sh zbiqSCG6&!p`fIB8-4MDR666cBgu4P#24sdAk?Te@kuo}yO&@7nuI)7&e3PgzqPu1C z)DX*dSHg69e9u&@pU~l^wG>LJ?Dg+mGI!)@$rqGZI6h~&@w(rygxYNDj$&@?7BI`bUI}oPhHC!-HLcitekta13=I zCoiGl5pvrHxvBnT2lLXwrR>IawdoX$Vnx|LMmS3p-@!A-q-A8X_JoebCZQHM(I#Qh z@-OgQ1EO5AHqPv5Tht!=zt`j4#LnOm_l^boyx6giXYbqpH>EJvGq+YqkIq_LXDOz6Pjoh74E5f@@b9{ z;lNeYtpklElNZPaDeG%jTxMv$~y)iqpiL$Nz~j{UIm0@e{@U=#u277 zj3h~5D2eBB3v8Oq1p!p-`n_poOz(!8BN~S^l?uiPB)W8*G7L(DbAO0Hyu@Axz zj{KDv^o|4%A@(Te0!^&0*us>lICS+5eSGkkK;M*r1T$o1Xz5zmUL(}I$>O{4A)l%i zA>SoJ`utB^caIji=t%k3++W)K*IsU&Fb*BCmsaY`S0d*?ZNU`+l2_PhI~vy!bqXys zrrN{c5r!glTtQq8zZHYS8OIk9MSfsf#01LFTMSB%6e=ZET(vMCKof;YtVXQIW5jo%t>vYwSzOF56X3kv*hpGgm_v|}mE zuNOB;4WfwyIJDG#`P}|62$wfq-gvXx5lPUBoYQG6a&{i)W8_?PS5wT~?GZ#3UiJ9trJ zY*{zwfH>!RCFxsMq@N_wL{Za0@UfS50iBP$JN& zmz~Y^SGysod^Q44^C2Ap9pR-WO@~}Gjt6>{iMZS}>a!$CgD)_(8$ROV)9;u#bb=5K zzqddHyBf35>XszBW&?RAGE(1Ts)W7p5R>(b#eCv_s`B#hS88MiE~k`Kb6+SoiqSgS zgO$Ji`4`JwqW7#ud3N@Xs`z$B8pXw~SGZlLm-cTJNh6wi@tWazckZoSjj51jZ_aqO znl=;lwA?kyV^S!p)glh*46&B+3oTV91a@sn>5p1RB)^Ni+Qj8XKTS?Vu_>+c0E+tN z_0J-KMwjN;0TgGv{TIWGl&CuT0Ja4$J2|a79SlRv4{pV4cyS)msOsdWqTMyp50h1t zMIcYs;kLD7OH-oJZx6d^j0y9Ha7#f56mEqIbQ_eN@qO9JuV6bNN=Xz&-Hk3S9B0dr zW+$=3Jf$e*G%!^2n}cpwb@qy>@!%s(@MnTC{zRFb{SBw3XW2)~=3QFZ-LP%ol=Z;F zIvJHY=U49t$c&Z(RC*YUcq|rzjdmr^C4vybEagZFB6&?!k^DQ z!3fA2Q8yDbz&b`pu{N3Ofe|L+Fub}scOi=-3u`v`8ejG|rPWHsp6o%b`2y>k&GR1H z2Yc<{Yf&6wA~|8v3{0mt#sjEP*i*3Q{|qwzQFvK+Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBU#8`(Bmu=- zP28-eK(b&!lG{})NIAc6A@CsLa3mV-bePOZsYP=5T#=J~-TWNX9+kV63pni_aYF3a z>XULHIXwF|=QA9VgK+qSxdtBrOArvGvT*o(Zs%WlR6uYWLP%11*9ZuLM}Y_xBn70^ zqs|>s1yIk5mY;)~P21WU$9Om}NkfUW1VH&=sx7;WJapWJ+ZVPPD!stxjI#2=;mF%7 z1XO{Cg}2CndH^z@vjMr?d})HIXW87l3;yQTpz?R1-ND*)NB z*4fG@mw6`#>0TW54Z0#W?M0%?mldSyGklwph@Eb1b`BzY3#lWj$qECi&Q7&YL3rtM z0J+=K>1`1Gu&)S^*TK{K7&0I`id~2q+*Kv);UNZ%sm{{MX<8jblGceUwQoILZppn8 zSJG!!(z%EiZpR8@1(ivh6;z_2{_1zPw7(yNl!j)ul1=$>=@9F7&-RNW_ z@BZdN0&3JLOwbQZI||GQh{C3G8_sr`m6s3?BQzj#;^csgt6?V6ZiHMy=QEEu|9T~0 zNvxE7v>h#?Wdovf+~G#x*d9PfJuB(lfXEQjDzh>{>HKlq$g@F+;gnC>01*?{ASfs` z;;?21q(DIC47sRBjgo7#UO}PYC27(|Qggz`Ptt+G+(~+j%0=i!r1mjpR&!3Ppm%e_ zNF$nD-wRo#fTrtFCIU3ZW$K-iH_V22^YuRMG47ld#0o0Y6)T7p#0n}SzzQnk$2o`< t#0n}SkgXsQZ2Tn&2!ze34`Bh5{|B3hiQZEUIZyxq002ovPDHLkV1lEf1OWg5 literal 0 HcmV?d00001 diff --git a/mod/maxgui.mod/maxgui.mod/doc/win32menu.png b/mod/maxgui.mod/maxgui.mod/doc/win32menu.png new file mode 100644 index 0000000000000000000000000000000000000000..646eef0be624e946bede1cf4d50db151336b12aa GIT binary patch literal 2766 zcmZuzYd8}O8(vb*qyssolZr7)=9DQSDI|yGG{>QpDQ9ML$cR`u&AI4hX_#RS@B8t7*Zbpnp6h;oJU{N|x$oN*(K*mXIdhgl6YQ9$-t^)uu>Ht9e z0|0=((~6(l8KMIKEO-F`M)?4Md`L0%h6w;5e$CqAqGOcjVu=<`*=ipa1T^W!iAsWX z+aUWCL)e+xV6uN;|CMyf^7t!x_x!Ys;9Z}0_3g@r8Y#!jFV}A67nIJ&1bh#^P4Pk^ zE2$gv&BTD0h#30D79NAKn?BEA@eB2Xh*kA)mXl^N}$4c*gE zS!R)7^f&>9QP6YXEdk&Al)kxn(Bocx2t?)`E}k)Uym^CG#|U8;$Xx|9menKctZB`I$5y zu^O{AJJtBq8c1(zZQ*;-qGM|$4;#L7Xs04(uu~9v^sH5(g5Su(rVciTNjDf$oA*;4=t|Acs3|zEE2p5a>}=31xqy7V3X4Lo6j$* zkZKhETPj%&IYH(50K85yg5E2qb?*~&Gz@Xb?!JSAtX0wLK8(6t{eFE8?$X{W`-mE z;au}L!^Md|dCYl3`EHbfijU5ZkWbgEoqgMb^RXf9-%XSgb)3H=>Yy+9;YRtr8K`-0 z{yB^}l&iX&lX!L_KcWaP8yWa;%T!sh6{tcnSBo3Q4&7jFglOOxyaC1fM)*$?b(*We z-Xh|?ZzY)LTNry#4Y|LJsnj`sRrkc${LEMf7GhB`RC>2Usa*ZW5N`1COYdiVscmFGX;EeH zu_teZCjxFWz!3LjO|=KKNmN7r(DAi`+d~)VTITgd4G%y~#AFit?fzG;@&a)fa94GB-`|j# zfhH#C1KsYHq=0@;nrtB!_Xp>Fqn_Ex0(UFa-4R<$Yj z=H}WwuaSL- z1{H#`%3%}fC*vuZean^FA3wS(sMBsejxA9qTMRVBzCXNs{3?ndC;V!4CcWA!lRBW0 zBA7uOSi7{d%TV4zIEDDE(@` z>M(3;*3VSe!q~PHue9nS>A`bF9|(3^fkX!ThG4a*sYEi&xP1i}F}jPB)lI>c8X~Zo z5+}`lEk~$yXsSGXxWf8~w<;|zJgPfD0(NIv{BLfw`TwBGvya5TI$k1tiSQ5u^`H+4 zMZ!JS(icPitIx~y4tW~@!edPnr62}`aonI{(t@n>r3E%75}F={87J{p!!yA)5EwOw zHR#1_p+J2YGh*TsK@t+o`-Fx%FdieVU%Srl$uP+#B>Sx&?sQkJtqG{;sEqse? zQb={nMx$OR;Y3g2hpDfUgZ;OFJek@qz4HY3aNM(`@_D((DpHe-8FGeo|06jZF#K2& z+M0tc$FhEh-f3qTuSDw>uNok=?E#)lcx!f}6SliAM1^1J>D~uG1nX{%R z-J1M^ayz2OP>444gY*g$95(pWpHEtEMs~br0>=~g*Ckm)m`mE|PkVQC7W?lylNSU( z1w~#PVIoK^ea9s4)6u$|aFuQ~dXq2$GNK~^+v3JVp){k-o@{y^ER?_t(6m%8RR)G7 zUrd}cVd=YXR{qdohhNs|9P|w{0L-RG*~v}_AV**xpi*wkN~6!&t_!B!V<_GfYd*2i zsV=U`gKpqr8dc#+8DQWq&`NhV#;1!QT)h6cVF7_b;yr4cerqU#Jptp5$9x)ydP!MH)2|2CrKpA!A+47G%t_)yDcbaqNyOY>7;m4C0?@ZzhF zjbS9!$l@O{(lj2<%vNp$WtNMi9Ox~BZ5Yf)`9gVcy32xo&oN^-U#l^!!_Kjs*|)qB zr3dMq$CRBj?$Gl~jpEV_s^Ar^NmeqFN{JcDZ@a;j<+-Cam3EX|x-vqi#X^%0y;C_L zwr!tdlje`9%L`^3JjhQ%o+hm5G~sUqQbp?+Vathju*TF-jw5MG$Sg`j|#Sz%{PVh9mbM&i+56?_wsL z&`h>Huw6$*llLt3Q0L@FC;ol!kt{GwthNS}S?%KE7KvslqedIbKR)pf_3RX-#aQ?0 z4ldA4O0T6sOUa?*SdycW2(0jvEI#dvA{kHQiX=ySr$|div+|y&?fw-JP+xax)F{K8 z?&PPwY{pIGj+hufC4jSV4O$e=AT|k^_yWgigqxyhf{q=(atS{SI)L!yR{0|Cik=y_P literal 0 HcmV?d00001 diff --git a/mod/maxgui.mod/maxgui.mod/doc/win32panels.png b/mod/maxgui.mod/maxgui.mod/doc/win32panels.png new file mode 100644 index 0000000000000000000000000000000000000000..b63260fd8e37cd0948e03d1bde82dc4036fcb39e GIT binary patch literal 343 zcmeAS@N?(olHy`uVBq!ia0vp^vOpZd!2~2fE?fNvNHG=%xjQkeJ16rJ$YDu$^mSxl z*x1kgCy^D%S4j2<@?~JCQe$9fXklRZ1r%y{!N5>zz`*b-fq}tl1_Oh5!JJ)zHb9B1 zo-U3d5$?$~pFgoN>oQ!3iBe#TlHlTE-mx<~?939GzyJTsCn#$J=8_Wd!-(lan??0t2yK!TUu!_!QPZ}G#1oA2dxVH?EU36&F%n{Lny(@5Ibv6Wg9; n?H9i^M8-ZmBd)xomW?5(LcIJ_yWt9;2N^tF{an^LB{Ts5fKz|5 literal 0 HcmV?d00001 diff --git a/mod/maxgui.mod/maxgui.mod/doc/win32progbar.png b/mod/maxgui.mod/maxgui.mod/doc/win32progbar.png new file mode 100644 index 0000000000000000000000000000000000000000..84153dcfa3f803871e8b00e30f1948dbcbd5b74a GIT binary patch literal 236 zcmeAS@N?(olHy`uVBq!ia0vp^DL^d1!2~4pjeV~GDaPU;cPEB*=VV?2IV|apzK#qG z8~eHcB(ehe3dtTpz6=aiY77hwEes65fIEaj?;hr3`IZ5rXhJq4H)8We!4UJ!)J?#y2F<|-k|35#k&fztSLmXMw%IxBDWA1Lz zF_nr~+~_)6slp_+ciEbYQ%oOReUV`%bGB{q%>onYNfWr;n6oq3t~DIL{h*v-g&E7E eK!+3#28N&`!GD7nbWa7^%HZkh=d#Wzp$P!9l}r=> literal 0 HcmV?d00001 diff --git a/mod/maxgui.mod/maxgui.mod/doc/win32sliders.png b/mod/maxgui.mod/maxgui.mod/doc/win32sliders.png new file mode 100644 index 0000000000000000000000000000000000000000..0a5526cf8d8c7e18c507aedf403a39a53f0181c5 GIT binary patch literal 1303 zcmV+y1?c*TP)Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBU$l}SWFRCr$Pok5P=AP_|-XNWXc$i=dca-7^?7CBJX*+q&p$_YBO zszVcuq2QMdnBTHS8V%J{J%1NvFyjxufBksj=VSs7I**eHyhwk4-hb+kuU|fgUg{0o zTDtCTx0~y6w4b%%cy3SVE+oz8``foIbd903apum~s`k>|XvCdAZGqhLxmUVGRXp~f z7Y(I>hpulwveK2%B=EG-H6Xe`A6e-dXy-w96~We_Yb!k&vcJR+SGv?-R?ufr`d-u( zO5dZF97sdHzUsAtKHw-SC0~@&^MRL@zGq*|>EV5b74*53p45AJAdPO&LUu*y_mb$} z#|rxOm7csM_V_f=J$EbUb16Mp&yIg}W8>iIl#F?j-1YCwx2pXwLC~+}i@V z%TWT>+v}BX2z@}}RnRI*#$s-&Jz>(f{sf1<4#>SN5HqDal={Q@s&6b8)_}xC>9v7~ zOrPmRZy((pxnGYy#;jf%qK={KXNM!`nPHHBN)j-bPbb-00tVGfZI^6M=;d`AbCuXY z|M>dJdB&d_0yZV1^u$9?z((o%{^n{KE}-Kzn^&g+^b0Fpmi*-=2#4+kX8=7Cul^=$ z{FVaU&qmZb9IY!IsB{sLVkD?OUkbkH^P zoL6lln%hPvXW}TOgO}&E%^%QhbIY}n;n7j)9hP6H^nTFYCBqDZ=MCjIQ0Y|q8VlT1 zI+aePXGYh(5yMYa>i2K^uUf~}xK5X;=c=dWL+Fdx8t3#3^vpg-;l7S7m7Y7<#k#xg z%05r&2L({PN(StgN~hA-7=)>GDxFHt&pRdusJ793#=#Krnbk|b^kOxiPNf$s)aSyq z)d~ioS3sxI&zvt}PG?SEs$^tN?~q>B%;|gES!BzL=4dM%md@#Zn`pFy%WuFaa)+QV ztMsI(^;<6>=xgS5+1j!_^t&D)=(y5*SYo>H0KO*A+V%r&d-|7V!4-nhV(DCX82>=-n5L?7&#MUgQ zBTgXoGGdGPjM$pxbi@f{JV0y_pAp+3l#T>2qwNq%pAj5VHBsq}D@RDxM5RN}x3e^w zJ8&w!9eVQ}IF;TA9jThA^hW5&;7_IZgI@J-9y1FoZ7V5=YG$;3C|&>N-u&oH=$cih z|DbCO2tB0KCNe_rn$wkgoT+pw{qY=D+hyKs5Kg3*+V_#-XTDePz4}e(^r|=S5_;{! zr@I5G{vFeVZU)_y=;3;b=2k0gvyQDX^jgqs zwkLGejtg6H5PDbW&97&$Rly41_E0)s&v53+ey$vy+3Vtc5qgK5{uh0M<=CKv6f6J$ N002ovPDHLkV1mojeG>ox literal 0 HcmV?d00001 diff --git a/mod/maxgui.mod/maxgui.mod/doc/win32tabber.png b/mod/maxgui.mod/maxgui.mod/doc/win32tabber.png new file mode 100644 index 0000000000000000000000000000000000000000..511c665d6f226197502e2330895a67b182ee000d GIT binary patch literal 1342 zcmZwHeLNF*7y$6!n3s8vbx8E0mQmemMwToNS>~lJB;_;5!sI2IMfJIn)Lj@hZp$Js ztz2G8$23c8mus>Od8xa|U5;g5ZzRR(_D}xmkLP(l-{@Q|^=1_J26zH+pJ})frK9oYXg^{A0GS8? z7&!oZ(zF=w0HC1&P>}(^asaSQ;R%npYeq$QZ_lIWBByx=l5F;vT`oaGrR!5+7~xNa zhaIzro;>R3hm>q(+|*vu)g3}4V)gcB^A2vIxBfF_I#KDon9AMZz}RA(euX(A;-1{4 zo>^Il&I&t`^+7>Q(G4?pY2#sH_J&0zl=Nz8`9H_puBf(S6*(8o2yT9IV?=0n zmD=3E66XKp>`Sdb; z&W;MPoGU`1-!n(B!FLX@DnAxRx}>S-3r&?bA3+gI4H7%-dQ$h;DMR{HE zV(LzK*{-;kal!%gTfG>=I$u_FKs&m5pKc@711~VAHtuGzAyTqh+SDbC^k`SfGHw)4 zc`-dE#!fR2t{4k1?6;FCxb8vIZ*B4d%M@m#zueX)2{^e%`Eu6`v;|I*vcr5}BnwFa zNRGr^K5MvC**4qW&NWd^c2GN$40_hpWri64)qp8ns7K#OEPB|L&!4=ng4uhCd>c~` z*yTBDft+ZasG!Sw%BpmOCHX^7gRIeMh;&aIUaoKQ@fbm-SBTsAoo5drJj~4=3YMOy zolul@=%ve~U;B%cyOR$5-it1E;riqMzhPw#P~)6hQMZQ34#4$X_O$MTc6 zV-%*3Q}zxocFCN}c8b)z2@E<5O-baLD$el3-r&US=F8g^ z1PhPj;j6V>KkRGRXe@sacg@Q#VdtFNb}_JODw6YxsanWD$vNv}fRpnvz}?)tR6m z2#k(qF}wKB`u)0VqO}#o(AJLn%87<3?&G;!EmueKXHv$zX|lu3Dlrac63$#^gyd-+ O9KibodN+8Hv;PN!>|w$H literal 0 HcmV?d00001 diff --git a/mod/maxgui.mod/maxgui.mod/doc/win32textarea.png b/mod/maxgui.mod/maxgui.mod/doc/win32textarea.png new file mode 100644 index 0000000000000000000000000000000000000000..81cb78bca8f2fd553b60747b33b2183ef6535f08 GIT binary patch literal 2780 zcma);cTkhr8pc1OQKUtLfC2^wHMG4fO^8{f_woUui6|mcqzFOjpnzhbNRcj~mrw+x z1XqJdF9He#q=XniA%r3&^ddJqckfQ-{&oL3<(+xXnNyzM`$n08dfXgB8~^}t8|Z6e z0Dw)1Ire9VFx&KmoU-p))5(T{TQJ0H8XabN?2UIX`z>A7cUl!AJlI zj|6~SW+;3P0Q_VDVBP@$(CGjmh{e4(R{;QyYX;gHmVx$5I5n>c6#p|<(>fb$269+{ zvycaJ{so^?xMI{56ZFUlu5Cc0Bi#F>vSjGdfMWt!SBGlxbhtrOp|)YFVmtz~6B{A7 zsn5Sb+WV#!#poQ~ih-+1ghN84S4ODb)^Kpy)SjWq#y_eTaro=N^(}cARS~DuU4 zqyaGSB>zbZ0M}NCTN)hok>d#GL*<31L)gG&FhEU>+Q9dRx_sw-e+GkbkXGyTomK@X z^nwwqC`m?z{z3zfYrg_^o~)BI-VS7Boz0n0CHBOUf)G#$&OVEBsPZ8cF4V@wFmbn1 zm^}g-RIxwyZgPv|?NtxxedAfH2yL;}c1GhDy0}a1ldj#gJd-QfZyBoa&O%(RuJxI-LS04RY@nodxVV8^vq#t2u6aQ_hrFP}*a<-B3 z-i9vmW0`K8?yn--VTP0S8H97Ft9O%@$0;E#8{gsOFJJAATFvkp72I`RfkVeeMl*`5 z=}(62l$6R~mV%cncJ8Fk^ERCD?e&!yD~AoBcU>M#Aw@L3O8xtU{bUfb6^(JLf|GSl zR5@;ZE_}dI{mk{w?0pHEYP99%k&f}TtyPWjBlU?Zp`+}$X@+R}O1~arfBfmOwyB_G z9SK=(e1vLt6l}|eGD}E%Y)fr84)Vag6J*rp3$9j$9R-mVev;0L)v*^s5*y?Sg>VAR zz3ML|pIW4}>`3OMv0vgfzJS*8Su4*fUW`gqgWwBHVh*o5j>(XBZyZ7W>uh#{v>YxO zZl7gcNg4AgOpv{^bSCSOMsO{WPDrW+J`QE1EJpC5HjdXsShu-2n{?_)uz|>;x&tn9 z{^_mAwvxFY{Lgh;yexcF+=f6SFU`}nyis7q(@dkCy34x))OA9!j`&uCrflwu$cL^~ z=<@k5k^%XY(6Y042WIl@2-~~C>sqwwO9~$GTCTsh{;Z!&E}r6l(ABjbMyZerpmuNH zz7M0V4{p@prwYAChLj%#3x$7@Yje-muMt!dA9=XuhV-T_X7iNVZSER(62$6=gWAI! zuibQhyK*2LPtp+EaCmAvK^Q=_dnJl$+wn+M0jO?|`IpZE@JFUBWjh^8jQIh49ct&@ z%v5%xX;57I47;Q_?lL&a#*thIpi+DZ@&<0{x;c=^qoBmOVgMCo5cNfu4GR(f+XrpR z1pq37kK?%{06Jo(GtB{9(+OxBKOinAx!NZIfRm9BM~?8M^yF<9W)Q2%CI@XYFg6TT z_^)>+FCZ^Ao`E)f=P zzVz*Nea^jinve&0iSl9J9?L@bb2v9>7p6= zVD;H6au7-f2?L9y5_rJ{@{I-BW^i3n33l*ub~Jbeb*8{ZfSR`W!T@5T_=oKhI58n* zHXJsqEB?g7b*)HT_fWdC{?@?gh|>~EE%C|?@iAex!t7ch2ZKiJ2z=uTlv`UjUWTODE)dp6-?;wj6}fo}QPm#s-D(Jo8A<};DO)cXu_ zah%mp!B{%X`SWyr*2PylC33CZ@hTolJzxY1OereI6v{(vURZ|NS9u6yMClHWfhBSb z|58==Ymj=Se(RY4PNB$oUd6Yy?s#@THt^Fc6aA=Z{vO!U8=BRM+y>?d21;%{UhyUB zAqhdUFtBinD>wSBHZ8BGQFP%_O)a9uTrZ+=ZYWycK76gR)~*?)``N|zIqwY7WyGysz70r6K=fYu4exo z+<4-r#XF9#)I4$D-17AbNa{5sqFL7iSM!rjT&jE??XT)tIp+s4(JLGeaG^c|QV5VF zth~XEr1rk&pnKX+Q%*#m-GM?LoYzof6YgmmYUqo()s||Y3L+P^GZ&X!f|XAaEE?TZ z#XO9}R?GR*A6b;gt@V_R4M^6-qsJIVuXnobr6Ijd-5;f$g<%i*@(;d=RJNMZOs#zB z$m0WUQI$V}eCCUvd_WQG&M7q9Gj*-9qpj;mJl5~1-)dAVk`aU^-pa;wk8jS={cV7hMHR7&#er>JO|mlux{ zg?W89uiFHl6C3*g`aUKuHsL= zXP-#NO`ZB)Z8oeJDwmnpnBH_o^1O5tF^ibMw)|i}&kos0=kSMJR#U^Ot0FjQ=2tlyiQ=O! zN^|*Ml)-nVo2f(a9I>F(XtN9Hb@X9%h)U&0bq^H!iO2V)fEjol4#Cij7!AgIktg>n zHTAVlVR&`L-?mYNX>PdPk&X~Sw~j~cpI;{U^w1f-JsDQNI8;&==`Hlm)+)7){McNL zEfEyF28UoG>B>O2ck))Dzb&aJGP(xF%jGrQpK>aDJ?mwqx7AEo{Yh+-zxh{K{V1Ml z!k<01N2v^KVa!C`!y4YP4^rY9?Bie}755*cl6F*dWpr5h`&;{C`7gdKPvMNt>Fg?E z1#eNH*=z>LqA{j1PQT-4A#M#n?2`(KN$`JQO%Fw!Ps?W^d+M}ChAWyyBcJu<_74mT z(m!ETBpAkc7ELiDDE4|Z3(IYzk2`16Sv9_@@rg#PIm2i*w^t#HMU(NFCU;Mg^?;Iy z`M)n^68nDlVKXPx%pnYF{db*r(tI+E{qFP83x_|rnB^y6paW`GYC1gn EH{|FY#{d8T literal 0 HcmV?d00001 diff --git a/mod/maxgui.mod/maxgui.mod/doc/win32textfield.png b/mod/maxgui.mod/maxgui.mod/doc/win32textfield.png new file mode 100644 index 0000000000000000000000000000000000000000..fd8106dbcd6fbb4006eeec45eb32996d429a6e21 GIT binary patch literal 621 zcmV-z0+RiSP)Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUz>q$gGRA@u(m{DrOFbsyf+vOm8AA??IkOS;tcgQvNR@hr%Fm{4W zwroqX>^2$LURQ-c6DP9lPrqcR51;4vgB=|RyuH5I*_yz*t_Se({PbvNI|AQd9|Rh% z>}W*5K(A1l8^Pt>8t8ukdO5m<{J2yUbDF1VKJkaTWtZ4~W&Xz$y?qY!CUEwUYqkSH zGuO8d`f6<%8r-x)P<=HEk1DX_7n=_LO?FeutLcfZ* zHbfWuKr_wP%*&wV-iN(23UnM$mc^oU#7qzD!cVZcR63-gDjlw)E2SguWH5_DMWS5F zT4H+1V#1e=QHmBxCg#ld#A!i_3k#K4nCTpL&zd+^m{f3dIf5lr@2q*D;486SoRfK> z07}+W(iWTH_)4)-pWh%r&6a#8E6CD zi9jbeq-eOZvnc`h71}ARckjkPcangCHqf02baG>g?gaV=VOt>sjRMkS00000NkvXX Hu0mjfhQSVA literal 0 HcmV?d00001 diff --git a/mod/maxgui.mod/maxgui.mod/doc/win32toolbar.png b/mod/maxgui.mod/maxgui.mod/doc/win32toolbar.png new file mode 100644 index 0000000000000000000000000000000000000000..9cc80479c448e559d29453a3556289f7353abf1c GIT binary patch literal 9715 zcmVPx#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBVCaY;l$RCr$PdslFr*_EFB=2vgI%6{^Ty|&-%^17teZh2R`TCG-^ z8EH5(KD>O)r z?6OxT>ei3je>gXN_uTKCd+xv3^XY!@>F-ky{89D*0QaZ#sR#Zjd*BCul&$)sX;dU) zi6Nyn_tdVASCcdLuE9#~%pqxgtS#II$NDd-p@0tu0wB;fzEefZB_6 zQN;VqKPl1YHB3*weck%%ZEwR+FQT=j`|BV7%R7JdgBQR4SA{?QLDjGSbzN1#U|Yjz zPt$n&i@yF2@P0gDe=q-I>JOF|zsJ}&@J6Rmg#AvJ%VBZ3ZFZ~M=k+60Ulj2%?fl4h{?7>q$aY$^?L9M9 zwN2G8J6=3%Dz9#;ss`7V7uAi`wJpz|BdVS^Jg#c0eb!V_{_<(nD+(TUxbOOynge75 z`Tn3uw6WgW*c=K4j3$fAZnN3!?qFOCM`fVPMHyX0K9TufYZ89odPMbd*@dY$4pVr~hI9(c-Q)72%67lpD zibk!MHbH0D!u36Nqsp`k9L7>G412tL;Yj@8@Zj+H z2>jF<4Na|0!4S|0m-CW zT@#xXEh}=PS7~zY>fK7COR4iIbt%Z_eubb(*rz1H17u*svv&mnSk z0$RuIRx{{CFjTEQ11G0&*yj#}qrp(*@bqwMWUTPlUud+uhcNuQqP+NKR$~7jtqGY( zXEbKhY2|~1gLwQJ4v*Ixv{t*-=P{=eK`M<*Cg5b!ZP}K1dwWYDmVmrmt`coY#ZvK> zSjt`J$hHOh`_4?mYBtG{ub+#ipYlg5rBhYg^HqkWI{j+BapmdS zOR&DdV{*teB9Ffb%GlbHaMn3Hij7n%qh3pQTENWZZh#J9FsMR_*le>xW+)a9y4+Tw zkdMLR=nR_OVF52VosKty13urC;7%m$O7+$Xih~__5e?Y=0l(iL3WZ`SnPg;WY>muC zqFDqy3yWuw(BxGV8;7Bi@Ju9{fyU9MXGkXFZX#&|-2c*n1on_ttwEw_OXJTYezQLi z_4|XtU{tjwc{emlA#u?_EQW={vyf;C5l6;iSV$C=gks~-tfd7q;F^GDWg10Lu2!=} zSmrJbmq+{%sCgg|3I=1U9qHTG<75Jph#?ViEFcPrW1^4@0-8#|(J`Q)HP-4pNq;Up zQ_U}$6OCD%=AFWlrki(PnrwSEi^*z)j1Xio8FXfo!33F&CaVF`>Qr*2vAut=uxh#$ z(eiF|7*OO7f*WucjYbK^3H%`%>)l?zO09G{Ji*u=xU;ml`0dYr8VCosRNCraU8}9B z2__t;@ZLe1z@*7TrkW=cE`U+N=DN*h428YNhrz^Q=!JufA#!ddZK)@4-wq?p) znUpUO@_2MwAmrZ*2K-KIDB^!!UPGs0lNlfgnHAW+O6gcRf2>qE_Cz#VCY*dGoqRan z_)zcK;|ax*&2^DXCDZCea*0H;&EsOXR}!4n%$}SrTclsUww7++O^!0hvm(U9Y%w}>$Tx9m}JVAiFv0rx7Du4 z&iCu64=wyBM)otOpxGgK=@9o==nt&CM>~ zG8eyKw4=&uFr*TfkEPYBCC&9{sbw~PnT1v1T(5HpYMr7E3;m8w@I*&{tfLmHsHFya zB}6H)F^lb-M<(`t9VnOc#IyNeu%lA1R|C>^XrV`f$Gen5BeT*#dt~MoIrvYZjdI(1sgYZ5VN`fGi^ke3EP8b^1ChOePAm!; z%!X;Kvc8+F)7z{TGh{qZkVR*)Sd2QzWYp=@c7t9b({+yWhUetXh_3miMX+vM4erAO z7oxqRuVY|tQzh*Ij|RXIBaA*eq(ckMx!#Av~_`K zeVw-<;v?}WI)NaT%A*I#x);yUsKwO2`|>_FZ)3V1@dgX|14W#-#p~~i_=EZAH#M>3 zfy3!S<8bQ&2@uX^GDQ-}I-j?}-^3yDcnVD>6(>^h>bgcWawd~m;&f=pWU^YVcl$j@ z$0uNhvw7^NCC|%>pX1iZXQyc`z+!H;w)N*0mLU*r-Cga6hyJU;ZL{gVXvu?U+CAa8Sq~j@V_#weXhrRp&|ZSkNaGW`P_j2!cO=J zVXRalV5Sbdm-dC(qNbty47k5n;;!xBK2u^p)1f|7qJOT!T~lMPX)vEFFkhJP*VM~D zwd4Og9NTeeST6d{bm%X%_^++xzax%4lx(t72fj;%TdY9%ka_J_s@2a`=r5G0&ve*d zsL=nQLjOvQ`%;bh4Aj=V_PJ*DuNAEEqf_W8Wls6TZqi>F2w%EMe@_^FC=oIeDbJCU%ufO@9{=*OdKd-A^~pEi%!~{J&6;UY6A7nAy#ql;gKk@AQahbiFlz)no=7NoJ3KrzFv#Yy0HftF zm}Cl>K*Z75Ogxq-*^-zH=2Se^+=js5mr|+A`Mnw1neTYSeO*ZH&tvsJU=8LG`yPw= ze6eJEWOM{@Auel!NFp;CG!ltSBTyL(CKiJeO9Uo8bdWkmbarB}8E3xBsTNB`Oe$ez zagj)%@HaQBs%je=x(Nj4#rn3R(n&-+D!F26a;55N?K+1Mjb~IMY0Yi3=_#v&TH-fa ze2$fvW1-|2NI6E*bu;NJ1361i{#Jwk#!SjllCo8#91|(qM7#-sD=Ei9&apFY;Kv^; zguILs-J&HUhqa`e+O=#w5s1yvkg{}yYexK68vIQ?;kt3{)(-ZXi}<(j{*K<{H||)% zPMx3e7e>N$E8`k=qD&^{?PtKB)u!cOM@?(rKqMgQTLUr6OvzD^ZyNDgYErh2kZmF4 zXer-nuz$~|Gef{%;0S1x0nFR1Jzlnj^X1w^nL@%%BrhMu3vfrHkkzE`8RL}KqYOsB z&*e7QJuZjG>2!JR4ztT+vU^Mxuhk7H6uOqTywqU%6#fWnj0{F`IcCt-C0># zMWT^_rwRlTK!oW$npU|h+ELv9@sEG?r+->eTnGkr;&tzXn_o)gvI97XrBUne+)N#L zt^l`6y`wWK6+7ETlg8??W3aeIB#uF2Y;6O+pwsDfZjamR1uDb67YIZ{5tq+rf`DJb zdX$JF5G{nOz%8F`%i|8*q4(XV^xmbmU!R{G#I2#3R3LmyqtgK4E|1^i-*Y=1L9kc= zV&o6IY$mteok+$J?XBnFzI-WmIkoaF1&vOfo1JE|n5&D+1rMJQNlZ42!=P?*SwcE( zlgHlF=`68OvaY7Sv!lo524i%&w=oTFyG_f)zO_=a%!Du1i@B)`{sAkb6vodfe zCCv`8t`TRRDFmB|dZ_Giq-6Tx$WP z`yR0~htzYA`05uc$Q1&aIWjW%Zs^_U=;#V^6}>n=`EC@4#?LOS&dtu^h-+jLN2HKO zQ?ah*R`eC%c4_5`t>yW}iJ5sem+|yzb$9O&iOfP{C{zL)w??IqXjBTAN1Jx5eQk|X zQ1DcvlmK7ZrCsrz=4N5Wtn}+Qg6CwH_Wtb3pLA1&$2VJ?6fR1^|qOr z4bih~tb1m9wi(;a#~`sXern+GxNHWlx?GC1C^itkeUS~K(s6; zEz5}e^)WPz9`6&d_+gKG&*cnz?9B}$@4DNPqOa-Gl`_D2_A`Lns$pS=t@Io{Ai1Tr zb9H{{gPa@qwk1NITCH1MS|k%GY3?f!h$P!OwNfhIe)D?x?c``zdq>&d{$+4GzohLI>F@U4xFk4;QX zpiyWf8V|0-H6rkxu$U|o4#gxh(RiZWY&$wQZ9{Zmv8z|mlDXz0R#!H$HHXl48(aU& z#bq>u%6d08J~KIkL?Uq*)G~6JNWc@ROeTwm#S@rxB9XLawLvF`hb@RU40a`x=5{!> z0-2n`VADx7I)zwLR{6T`Efz~bE@1)50ds^%Vy|;VTBX6|@Pmae_wGZ3ChcClv@6av zw_QuazI8FPO)P-994GCjla*s;-Z3$AAy&4BdB?qe&&~YSO1tY|=DWCe9gHj^E6YvK zcCqioHg9m2sQW z`6-JoMsK>fBR_l%2dW^3-JH+BPXcP%VTeNb})TCyz@DfD_K zo6g)|^4IxX_PR(S^*Sv$9Ig@3-ajzV-#_x>|NN(SzrHp+I-LLX(cd2&)Nk)(8ME5D#pqfrBQUq*1-tU4BEB)Wdn!@lL^-1f2a+?<WHNcRie& zKK3m)JIlw(^#aN3`R?^>5AT6@GuzL9;O6{V%BIEwdx=1B&lT=(s)Eh;V8u<^e8rZ8 znLN0hIe=w>gB$m5WcxW;!S!4(H{Syjo?X~dxHTf!1O>4i@3&Vnf;$1c?+T+)BUgw3$@93NndN0Bjf`GeSXx=0o1b5u zN21WH7}N>|3p6-tZH#4OAUF{_8X+;uSke5u`hl; zySPfGa2FPk_?4xZx%rtTU_z{}u42&`ENT@^AP@o8cXoGxgDIJav^2fK;I06-4mjN% z4i~6~%k8RfZf|IA+u7OGYn0mxjZ$q?>>3;{U(gdcIf45J$BK%oRa!+XZoAZ3oYveH zn}$vpj7VI3L^z3GeR-9{2?LLBah!@q>`GAR)+& zi0;C&TN|hv;QLQx;M|Z|%fgK$Hgo*KJ7M8{zwmBEa3?Ct4Q=KH1$V-N{IKv&QkuWF z{^b^z77Ioqz-Dv$x|_;j%Y9gz!(Xo274Y{navseFaUvqV6B6Cp+qe}M1#A|`4VmIWzf$d;f7g1ZzR5>c$^{${v~Y#DByCVamfE)E z)}f8Em*{&>W^EZK*iY8oD^Ky0bQhhJ6x}VU{*1a@8`!NRP zmP}-GT6H?5!)hlJ@omj5C8Z@z4T#r0y@=*cl}_pQ`6(cVI7g zcy!d%)IeHW%FMZU=b8(t9oYm#HU@D6Tk{L#>N11HA>ffDAeII^ifc?3g+?Ztjan~| z>h}XP#pCuxL!sk?qlPBL6$Yiptx;)qhlbwu5A@HkE{;r0Jjg40Gc=CIP*;{QG%{;? zVh(J!n2nZrBvSS4RclYb!=b*)pahy*ur{{8Q<&V!O^OQ=viy_nN6GC6iLJbZEH5d` zO(+Ueiu}VZ@F+L2lb2BBgOrlxr*=wVU7i44DHCt*r!ME*CP>30Pr$0>#aHWNzP2 z$n%cm4^#5|)b{=4?t`P9LReLpl-`hSFq5If{V3Qf4h=Mx!R`mJ?V$)&DV1=O84OA@ zq-L*;oGI?5B*jTt@xJ(eQeKjj7wpRl6WjTRyLqrI_f%Kpr2i5-J05W*_QP(o!S%GL zA}Yy;-4Depl}ZUGd8M}mY_A#&`kD?*+4GU5g$13_uG1Phn^J*DCYEaWTMDsQI?&(S zJitKoFKjSM({AcN6uh3qb?$LI6_my*Y^2X@z@Ag;w7J3Ocbnj4!@bGzL- zgF%~!1fsE6azAx^kSHv!EG?-bkw{?YFC2}>_m5M_6lAl#9vXX8QAeYb;xP~p17+6S zRvm9`0@f73+6S;Y4K-Mm2df^z+WWBbKCCK&H6^gF1lAV7s?zj*bqTC2In$M#)vUD0Mp#Uu>Fy8I(eJ`5&m&GL@G-gCmb%e;Mq_m0;_(B<$D+3`&ay(mrd&JbgJX;;{=Kx8AvT zkIfLi8=jaMc{}!QWNdP_qpi7dfL1p^MD!ACx~Pb@&dJ5a4~9>H&Cv}uyR`*TTvB%D z&b{8gw=Sm>(2uT;&gZqYqZ6YbPbK3alN2cIbg1g@1bbu#w?m^)2j1b=h@%se3k&GExrH_CDglQD!gWf8$LTpehFf3N z6L3qQ?U$~WZnwc`u<|!HsT8tEAeJi>z@1rFS9kY8QD<8ZaP>@1&yKtsD=vLrT3r41 z^%5Gn!52vr=Z>A<#rHWav1&HSqp;-xKnZLrf{g{~WCoaf2pb>4)-u>w44WUr25<+w z@EFz?!@A;>t{B#r!QNsm<)sXGi!*qROeVFEFaev3&!qtg=Lv{PODlq*!gR(`a%wGs z?L}1NBlO54(o~Iz+yn>8;k^P4xlSQwCo}lD0l0kchC5M)h1E}aUP?c2P#Sb?mRF6)>kB{u-u)jb@c_|U|5?9g^5L;q|v=s<+ zMfD(Oo!dUNRsRaXX7lEk&~x)B%rX|eO6uu;^{S8ivX@xbPkq%%Zfrw7~0J2IJaM{O~hoSr>DP}qSzx7!m6L~K@@a!2L! z`_sZ-A<(#ter}+-U2dO1ET&S4Qju7#*@4Vvk$^WaFkDq$Q(jh4`S^Kxb+-9?myHXGPZ^6Dipe$iuKJ3qf10Yib`*Yz?Uiv3^ z6v#{GgXd|lF#Xe?4uyRFIaO zF0KIHdkDvi;e!Y8QE9rYXg&<*ZY@0C6#;NxZBSY?MqNcS?rH59kHxO(r`Nn{r8Akp zVp>HJfYS?Xzx8$@YI^A{eaxl-_Ny)ua0M>RO@9#Ffbi_9^Yaw2oom^~#N(I8mH>Aw2rHVJ!H$ou0wLh@sd40F zS|D+DVs&%^H4N^L5@*M7bL05wQPS)vZhUlgb_6*)j9i^04i3E4%23hRRl*l$Xk%lj z=`rHi6mDz^H8X~q9Y@ZN6K2PVb7R=qY1H(@>hvUPYzjF$hMgNF&Wzw@hEel##5X;I z1{o@zLHLCx01&j8)Kv)llb2KMO@7aqpslHc$=je)xL}WYjk3XEhz7b_8u~WtUUM4; zxG%b?^(`GUbJHL6a|1I-t&ztPaXb+(k_mTrl-@nBR;!Ig{BFNHkx0bj@#KC2M0ooA zfumG35&dwO;l;QD(1U0QIq(p%z}^r;w8ciF@w;m6^z7o&(jtdJm&v5SW6WW*g%a78 zbeqLp*DIB5IwKnJ0?@pyZY1JRnG8z3al5S|x9{;k3|0Q3_vx=*KlmT$6*QP6lXH_x zOUqm~MC{2CG&lR0Ka&M&@9Zgk zT;5*s=R1_T9o1(1JRa*kzP}53O&@$XiX6k?v(q?y7C%0V9-llu-?atY0r^vK z|1_4aFdRQV2_3_r<`HmUBypwi3vg>RJ7raUwJ$rCXQvhxMv%*^W24iP(`@I5;l8*04+{U@ zlEH@`KA0Gd+R)gQit@^)hPoFuO)p;7)l}ELsIPB)SyNL}TU}H03IycWzkF3&gLqX_ zQ&IJ#tei?DWLkOOBL>*`!97Q5acS>BXaDQhZ+Zti``)~M-SfJy^G)ZQuHM0pH+`?W zI|lk*_xJWs&rTPYR;E&5J5=}k9yS9=LZdPJ$*9NYi$$YnXE5-b@9*y)92|g5JP|)V zIXXH%2EW4*F!|HWfrv+gGhLY`5?FH%_FW(*;_$$8dg@2vu^`+k0Af_4(UWtpeCk{} z$RrZUlau3<Yi6TTbQ0dNV=>x!@YZVT1$Rt*%;d0*?jL)`gF|f!^h0P z7z29+EH7X&f#KvSSQcQgG9+La=vpvfk<+t%uzaN-!C=|h2d@G1`ePsnd?1045w*HP z#Dfh(9F~A1fE_-tbx6VyNh?Ggo&a<#9>i$iz@GN>?BoY0%;mZ^VWYE|SUizNr_ngz z`~Z{9ea`gR-s)*?oU>7r>Oqreg6pHl4;~ zZ}2!w4u>sV=kfV`@Jq}WZk|i#0@-5WwnF~mS?%iL%oPnupV2&U9Upto69|0$F7ul^ z>6;giz!ezfpvl1Z5)FADJ}9cb{U3LP$Yk<6$K5Aze-yYcJWan@d@fF9Uo02z^S`|` z0kh`A3&I5u!B~Qs1N?^IdXYIlJ#=v>>AQ6C=wcwhUy4NR!cF$@;80gbdv9lZX9uDU z7^F8+dXhyVkb+xxD6x>Y5%zn25;jo1-;Pkv1>}+f60Y3V! zE<{InTSsS4TU%#GQ+H=aS7&!e2coB=wX3tEvmLQ5XMfBYsNbulfPHzq=Fy3F>RrYA zlct}*{XOCGdv*Q)^_Rgik^*~GdnS)t>-Fe-9&k-(JYFrh0}eO>vJ0*rj}|!Nz-w1< zl1tkHjvWO8CbwI2F6SbFQo!}R6p#MAL>(v#2+wr%F1xo{R!NEv_0?%+<&w~`_EL}{%@@I{{#`|)0;aNmV*EQ002ovPDHLkV1kp| B-DLm( literal 0 HcmV?d00001 diff --git a/mod/maxgui.mod/maxgui.mod/doc/win32treeview.png b/mod/maxgui.mod/maxgui.mod/doc/win32treeview.png new file mode 100644 index 0000000000000000000000000000000000000000..3263dc10796058c0dd7cae8a2d2eb4c492aef947 GIT binary patch literal 3281 zcmV;?3@-DDP)Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBU;Pf0{URCr$PTuX8+xeXj2$y*=E_wm9vn1!$5t*`Xl8cuM~_z~b2 ztb#(Jkg7luOk^ccB-MZW_3PJf`IQK)K;Xlz|NQ=M>HBk+epNT>EqaA*2ze|Sd4wfq{d!S`9Y+1zjbv$3UETx#lEjaH~uYD|7Gtv@nQB|`P{)kM; ztu+zf*Xt5)HQi6$YC`k?gFm_DTHn&wAhO!qum&H`&S!khc=(XB-;Cbt#=d#c+gx&?FPDJ*i_xd;T(t+^A+-i{+MO}7pf zYR5rL2UrABw~`pE5J=rxg>3elx|JMQg}_$bvMjnzpC}yEwalR#=Shubq;~6;<&;Fz zX}bX&ZaN!WOtt&`7|S8u@*cGRpth4+tH(-i>5svXZcRUEuk1D!UQ+ErDGwSb+(Ksb zc#k4-^%mRzbalK}#zu9Eoq69saTuvkNd|{T5v|+aN?=gBq?QtOiX|O!Y5u*DVS#i@ zNiogr#@75w!WFhKm-?*6Y-*O6IvA%Ln~&<2_n`fa7^TmB2n^{~ z-;mkrB?t`Z7Q`seZ@q*u_GzYW*|ADX9|GrfOBcLPY5c!`{o?^YePMZob#&eO5bN*% z{O|4GpIJPDExt)ypj)>S>*IfO?bjEyORQ73c8Fr?*3aY6{kpfP;pd6}Jon{6MFPfN zq#{=z@`L)9x)o7sOT9&jRfr;8XBl>oTd7;2b*nN1^63_CrEcA!TN1bQ+@~mC&8^6W zb_gwtG0n@Y8>w4yb*rYo8c~=KQGli5OfT19E2Tr0UNu1@-q$}n-IyKrwddR^@l< z)=AxxcwKc%=ay9H=xI)BrPo_Zmdtt!#_^_gd0ng67qt2+*Su?4bcLPJq8?WCNcmE? zqU+Yd#m~W^v)+ncZw&_cVDr?i)U8$f)~Q=Tb?X5K15>vm>Q+R)r%yHnqQ58FW|3AA z5r}^7G$Ll{lMR8?EgMd0W@ z&6>_v`HTYC_OFJfVNV;uXtBRf2`8K->X7!|F`~E0ltI0rW1W=nrw`JXB^rCtv3F&L z-VvLV_oB(#2jLb9s+XM|P*~tqsP^@Ib_{>Ei86U9IX1HxolzgRq=A$qOK;Vo(RA29 zl{{6e1s5Z`xy7jLV{{9K1l0=CpUOjmLf#~wl2762&3>pPlq>LOM<;eU=-`(4MA=6T zV%eO$uGq$hxKFnVMA8t=q1iztZt3jTxu`!>ecX+!Thh7H<~(UQ5x10lWQUjm?hiS! z)M~nJDR-$7v)U}Nxk+Wa^U9N^jB?-l)}U?~)pxUQ>621OCMo59-C|S#UGl!Q)#lq8 zdbveq%tEi#+)@&^Bu-GDbocbCK%c$~UMiViLtB6jVk1=;^?I3V`GP*P7xjcFjRl8L z2BNpBz@S@bpn8}3jIO|jh;~XR_F2PZjmDC0;i+AxTS17PZZr|Nuik1-DGh=kaL0aP z5U|n>7XqnUF1XUzfk5h(1FST4A&|P|f-8+32&8T~z)DjW0;yXrxYF2xz#Y29E-<1M zLdT?ArgS*C@`+lr3zgp0+LlM+eQ6n8TD+|j=^oME@DAOQHZkgT7GgUJ)RM03OHpb1 zHsZ#oZTHkV8g?{MW_O2f!3juD>R)=3bsO7gxH}%K$oM%LJdJTdZd2GNV0n-(VwUDr3Q)Fk@P9 zmz0>c)q7L!cHA=N1mgtnsJC1>krfh}wsh%IbPKVn@0q@cTd3wU66>cGf_U38tU9iA z;#Bga`E0SlmNJVmp-@qjWKt^mb&XW0e_XewajRK~95?WCtIuIww;nkE7s1nzrJ^vo`8Pa<&Ny8KDBa%>L*saqbj($<4O z>XrwswDlmcTeqY&J&(_6dj|psbgN^fgao@%7)<2QtuyMG&byh95mMVBxyXx1h+dV zIn~lfA`LB-bSY&!%zA5xTdu|(?};d(u+gG%g;f!)knAjx5**5XmJUD!=yIwHoP8H_aDLqf`aEe#g zb#lFKU5EI49Dagsy(e0C%`|oEu6W(#ZR*xd(Ynjm)UCVXb(6PebPKJ8h6M~Q?S}O; zreg9TDha-M65PFLe1iTA=~mx;tQ|u4bjMO!YwIswR6`mm2i@Du@8o_pP2d4#oYbfI|SzQ0;1Jj(eJmE@()R=mx>z3kDa;u+P_LepG z(I(CFHZYCSXt6~-`(g+SDfZP54TMMo`;;nu$r*Irh1*MvM|JD?xzm@#>Beae)mt}C zIDOuRz>sc1FPnLA+mv#kAPA&x1qs9h-ALVfU{HfhDRnDIARg#O>ed5;8e~eTTR{Tx zKsOHPmb9L^0$p~Odc{E5Cq-blZYc*{)`cg}FRa5>>3O$q(J*fa{DvWp1TXlYhjmNZ zOk_8$l^w%RKgtH5#4Raf!mORV>}K$8-Kr#L#;i%NI%mi#mSL<|vi%qLDC4{FeRIRz zx&^VOJdgwfo?j?EAZDO$o8(Xk)Fl0z>EfFEWZj}CPMiCTls5`{SY!HrVBr?xF_p1= z$8<3%+=`Hf za%x;<0w;ijUmb-Op z#oUrxD^MNp^LpLN1Q8Kbx;ZAa!dUwr}q_b?fa6SU3OF zt##PGz2{EdQa0np5zRG)aSS8$(63v~9pVtv%dNn3Vff)z$H$h|otEl(OtFdS)wytQ z9r;ggv15*W)DhhZge+wD{t90QZ=p?V%f@B$ZxQ1#w;<4c+$xUJg9hwHHm)?=!Yk;^ zf^@68L4l)#CcReBYlvI=5rgiaHY+(OPC6(S?yi6}`}~oTQg6Y0RE0tL*iu?=AvBFa zwV2U&(m`&qlT9{EM_@>|6mKk~kqFw|ftnhg7P_I&63L z+`leA*Go2e%^f0p+l)XIZdr2WW@vJ_K?DMEYj7snJQ@PYt!NQ>jz9kgQXID&6OV0k P00000NkvXXu0mjf$y8V& literal 0 HcmV?d00001 diff --git a/mod/maxgui.mod/maxgui.mod/doc/win32window.png b/mod/maxgui.mod/maxgui.mod/doc/win32window.png new file mode 100644 index 0000000000000000000000000000000000000000..22077b3d02f2d0496629398b9130fd5ac234753e GIT binary patch literal 7051 zcmYkBRa6{Zw5=O$BuL{fjeBr!tZ{dDYXZSNI0PCC5C|3=0t9yr5+FFio#5^eEa>4s z=RVwrs$Dhqs=3$t*4(2;jf&P#lgGj!!vFvPSc(czt=F;X^(a6?d_7yw=B>UC$o5jI zQUE}00_LM73IISZtq7IU@ijZiMmN!!zaF4on2dgGjHc(DRnXAnb6&?T$gAT*FeLaQ zn_^1i1cvoREIrnzGsdIOzDu47n(9kWZ)o~nsi=~sY%L-Rty`KlT)%lre7rR$KvStS+s>)R#YIAy_{K zOJbHy8Mj14S6I&}X85A`H7_sp^$GGE5sXI4t%UekIerBW8f7#-IoB!`zl@beZKTAD ziWOu?C2xGF30qEdBR@}KLwB}#EP~a9Qvb{(?P9d^vlSFWi$x=q(bny~bQVe754w1> zwEd^e;e)3$*Wt>|p_rM}Uw^Fkeyy@}g!gL|eBaN!uU{OzmtQm#A|r#D!fl;}Qu!wf`G(X*gZWW`GiY_tARKF?6}`XW#6qln8=8Q&^_K(RY#eGBxLuKE|6>kru80^uc@$oBEm|y7Eme7RMd-hr+K{`4~#w1!U=8)_BeM zp%7#^a<1LntT!n=gPORf(-$jM0_P@u)(|`HL0xZ zFWUQ6%E^MbhrTcQd|{1IA>-f5KeImoM3uM+3%L*kL?n#I$8Z&S0NPsxsUKhO$pYMqZWTuzF4Ozytd3>_QOXm!>T{$-kx%liGt0`?k1-I_5|qEaLs_59(xO!GmP zm7LPS_*DCdVJ*ZWa(xBC%Fm4KNRA8Z=z7$=I2`U(^fQh9^9L&1k8HYMSjLqSal!_R zw%%xPU$TV9#0BCgcc?8sVCeR_?uEmV)6(+ZJ52@C5C0sA)DXV+h(LWbNb;IUFvfwI zLzY@^$FtjCia5mb#yIDTpX8D+>lhChRC{7G?}+(oUqb<*|R# zC+cUtwAx3dYP~b3C0X9~^aI2Ztp^$MW|$u&U_zaq>9s8#=DL!b|$uN*%Y6Q>O%BW z+INH`Ghqa17$~WKYP1W* z73f1_Fs3aIf)sSxG{Z>f3g{Y^Lh_0H`yk%|obV%__ibTB$^=e~y_{ z&m9cTCUM(IhIL;8x*$uH0`8}`mb`1XzB8=gE}_uNO>|bR@PYwQ<+POEO5wq0>{*{E zg(Lg6BVf#%=?hqLLO|<3xh({gEbR{=Qh12Z?xsF%Uvd|TvmzsFQ6_nU3LU3hbY&+J zG?ObDHUxZREqtV6F#ZiBX9dxBl$zpf)+!?f+!5EV`gKS72c^DqE`F!i_Rg-&U$4#I z+y7xyl}8-B!b^b9Bo4MZ>Zzr+juKJYAJtJgep9V=jFV03TfNPoP{RQ%y# z;uM!#Ngv_WCN9paZ#3l+6iU>9cGBqP?%E~oAGz;v8of8xyu}B=(-{RfM%ikY{q38$ zRqZ2&rG9nW{7(Z^{dm}u?yh44;EH|_oj4`mo+CDjq-x2-p-dFF3o)2&)_CB@nC{V{ z5Yz}Ka(M>Tm;&QSQu{GxHqj42J=8VVFHvHsU5vgqgi2V?hB<52diZg%OgQ6kV0yOd z`=JBNA*sV*#=!~i=OTP*2&fD`p_l+q7vZJ>E8m2VB5jTQwz1U|JCkp7`^NXX-14M{ z6Vg*W8#SH?9esp&_CF{yS|}6g)1pt0r=yV3f+anP!Gi0<^<@lg4Qu8NI1=LY*r%WQ z52X;G!~6@M#w7?oWC2}P&H>yHzsmiol)Ev(We8lK&~r${-`QeQa2E*Mb`PrqLFpHa zCqHrPpA82k_$);YUfx%zhc40Si%S^uvuU4XR^@yy%SkElR@7Bjcg*cn6oD)dfL777 znh2R{=4a3$^}kGzaWzxvSuLLt&rpsC7d6H36a73dKqB8DzFL8$vGf7=!7|0cH8ww} zl2CN@K%uStZ(J)rdq9zUO%&oh8MeA{P@zWW5Q$p@v2~KxXq^tP-_5QEg?RhXNv>{C zN&pVZ#8P6&^!pV7mr9_dC#V`zr8PARPhJI|*o3U<6ARm;Aj=#PNmhWjk$G|~BclHH z#Qpr2@Qvzl>S6^`N9Owq3RVvez6Oktswd0{fob4WMR4sx4|fy zkadu8X{8Z;#@nWJ70fNEE2t#Ve=><=4N$GG1KM)_wR_xblt{`7(QYssE}NWF!+sG; z-rEd`7Fdxa{7yD+qTzO4L!qE^+omqyA5#%_lF8-)HlIbXQMHH^U3z6#Y|yK)hLVhn zP$w4v0##z;LouE zGgMDXVvz)gYMnEEDL(6R2X3H$saKvffZ-(1x`xr8D8upTZ-1h6wlf8oQO6Jp_zC@nRqNS0$CN_gIoDGgxA?STS?yF|(O5y~=PrAk_N-oGvwo)Ivg$T0`*vk95l4#(+_!ElfheFHw2Sa>>EzY^}8RXnYj9W*Ji55 zVh>%7jJ>NVHR%17)Vo=uN3Y0)qKo@LR*kfIn8hxP9Yi061EhQ>Pqs;TkKiF%DS-@j zH)xRi2oHG94=({Qc%jgeCx1{sAAK-OPZh8WIafMgz z$aR=dOq#jIwC|_!TQ^Gl#O-7P`+8*@hEN8Cr$sx8MhM=?q3iPuKYz~v$Zs#8(Baj`BTD=@a=e5YtE6W-2y0D4&`lB z*fPl@%`GSWT1omfpDa7?uJuI`I|=(OKGXSR4E}=SA$?nXbPL9gm%14Ct=M*kB_ImS zq?JSY^KZVw4R~2__GFmZ-uBK{cHh8ZVu4yO?zw(>yp{o?)ZdQHl3^MS7rP{9?+Xq= zO96vbN!al$-mcHmQA>`;KX$Aw$m#;XeYh#6^Y0Yh4+BYok|mIq+Bhd`%bHB#Zmd;m z2E1&dYP&Pkx)doG0(G)eF;NDZ-Sy(=e6CQOFgQ$xz7F`-91*&1T@sW|tb>?`Fkq2` z0)I@U36sB)as7AMosfqJ&7uP%FP)p-D(yCJ!%u+t!+k6OhR(Oc-JD^aw&9taij-#m z%0f;KYfOa#d4tE6@-vJo0xJ}FIn8-R3;oKa{GiX-@G?UxH`)9(i}J%Y(a{d{>P4Q z7hp25vU60)EEFCF;PRgemj)Y8B?~8kr5!sbqtKGC8~D3fG!WH#&?Q zu$bImX@aQY^yd7VK=r5uD(V=Hi>@#dTqRd-Ks6W{WUz&y$%v4~6n_(Bo3i(}P%LNQ z_M7wv=NT zS*-z9H)B!1NpiW-qUX?KY!h@&pCk}P8Riduk+JSp$hbw4U?&I^8Z%2k(?Eo?JNGP~ z_lFi!%}dIx_R(6U`7S~<9lE}QR2o_xVDIXgD^Z+aWdSe|`|s|WF{{V*E?7hTUhWp% z80mvJJaJE($SZc>gqWwy>mB8FwSG;_evZ>gyhvSdxHWNf#h&P2sKt?kA4$B7L;@VQW#BkH4MjrMX=aw_`T z2P#$#mrI`LcKZ{Rr8((xv1+xuSlc^Kw-7jFHNETKaiAKW6De|lMzcOBv}O|v7Aki7 z5oZDH$u(j)IRZ(nR83Qid+!;he7PLL()d=jiMpUfT?$ltRR$8;t^MD)htUh(D8Svn zgwH5@2IV|We)nGZoQU0#2mqg}6k{ft>*UqA!U5EYTCPXb)mTG6AOw1qyDJepr8csx zhSkI5EN4b}nUzR-aKi)bh1d7d1B-;k9NWv)t@PffH(g?uPlWTT`g=vD*=dUc!OCBk zQ@xujZWe`4cypY5{OWpHN~}#%hq+}?XzdKFqMq8yRbb*d7T(Y{ca%LvN z8(Q$Agz~)^x$)$R46bPJ`fA)QNm&w zBT5J$X>=MZ0$3b~HiZW4FmEv{W=I$xkWMR2#A{p-F(BJQ>u(m7VUf&9MmrYM)Qlxg_Qi5Ger>vt1G<>Q=Lx zZlizW1>4@1*KudJYL>x!po4GtDFuDxbt8gmz_uKtW8Zg+cQLxZ37n$EB)1Rv`dctWm%>iLb~%X z9u=67VC1zjc^gr<#)NYpB+_%c?YcJptNa<|-$CLI(@E+}?8V~@%dxNQtnD4AgPcoN z(c>ouc+s(TbB@H{dEF`(3CQN)O4OGMcILBj(&f8$FDQ-ajyuTx!7)&D1xrRoIMnNeg1N70g$C7f zaAj~259KhJPO9TYHN~A0RWV(8sgA?317R)f>@(_Ge)34jN2LbM@aY1q>;fUx;UnMJ zohGxoRPyd9=88Ye#G#Vb6<`XmYc6%p)!{t-)_c86(b%dl&po+PMH>YDed{{c+U9@# zoPtx+j8OP)E&M9trHYeT`Ama?N-g#%R~Ix1eO>wB=_njrw@g=W0ln7!m6r+?#7n(lms6 zD|P_kk!blgbB0Ryv1{byw1v&l)f7mw!p+ol9QI7d0;FR&$5yxLUPq_&f#TP+u*?SgL;SXWLnysN=h{^k)?#Goo-L)0VLRURWQX;AAQX(u!Y z51zhx<9ygRlie@6rJ}lA7Ux$k|GobiOcrt_E(ywKUiciF{zR65nz^jI^`Ql#3n~Nq zl!C8H^av=oO!{oN0Z)`;;uJ#8w=?V3|AlJRP6-}2|igR;zY`l}@)kiUC zSe#AQlDDCD>E!>ducsRU=2_Ps%T+^qEvT`^a>_BMN{jH{fk_|ID&BwjIcb7gyzDLq z2quOZFq{!!wh=R3J^H}jK zMQh_c?k8nDomX5WPqm=G5?8Ch(7&>M-9H_CBm3hXuT1Uv z1V&*n&Z%7DojlRhXL&rv;Dks{R1#05MIWsHRaMRleE|1Me9mK?@_7yVyV4N@Kd9st z0SdHv*)TgE`H!(86i{&s5GY7a21E+&T_jc| zq_MJ`QU)Ew22n#HuX~&6Bp>)+5su=3fRJ_4Dc$6c(Wmz>VUehrQUnC2&f1|kJoopy z_6eC{2jAc;YY7)<)UV)d+s+VZsdZ$T8H&YewhP&aLmSH(LnBv-Tie|NYkYY(3fU&s zgKcEbVprCNfRawXfwB>D8C6s@eNn#@xv==c8TeMdcpGi@E(N~wGd;MM+UUcemJ98- zQ3T1_Xv8_6kvnAL#0);=#4hy6>vLKu%64N0{wWu?C`3ERolK|WdDj@nZccdv#dk6I zy7V-MMaO<5k zj(|Y75`S#F$`a!vY)6GdzutG#XM3!)90kaKNOA7;Z86o`Q2avHK0SjeJvxeHfY|Ll z;F$Hy~dxY!RIh(@8f#VV3NVXJ;U hufLhkH{dgMNYA#X$lhYn>)$niqO2OUO4=gqe*k@|C5He2 literal 0 HcmV?d00001 diff --git a/mod/maxgui.mod/maxgui.mod/driver.bmx b/mod/maxgui.mod/maxgui.mod/driver.bmx new file mode 100644 index 0000000..3630c11 --- /dev/null +++ b/mod/maxgui.mod/maxgui.mod/driver.bmx @@ -0,0 +1,192 @@ +Strict + +Import "gadget.bmx" +Import "guifont.bmx" + +Import MaxGUI.Localization +Import Brl.Map + +Type TMaxGUIDriver + + Method UserName$() Abstract + Method ComputerName$() Abstract + + Method LoadFont:TGuiFont(name$,size,flags) Abstract + Method CreateGadget:TGadget(GadgetClass,name$,x,y,w,h,group:TGadget,style) Abstract + Method ActiveGadget:TGadget() Abstract + Method RequestColor(r,g,b) Abstract + Method RequestFont:TGuiFont(font:TGuiFont) Abstract + Method SetPointer(shape) Abstract + Method LoadIconStrip:TIconStrip(source:Object) Abstract + + Method LookupColor( colorindex:Int, pRed:Byte Var, pGreen:Byte Var, pBlue:Byte Var ) + + Select colorindex + Case GUICOLOR_WINDOWBG + pRed = 240; pGreen = 240; pBlue = 240 + Case GUICOLOR_GADGETBG + pRed = 255; pGreen = 255; pBlue = 255 + Case GUICOLOR_GADGETFG + pRed = 0; pGreen = 0; pBlue = 0 + Case GUICOLOR_SELECTIONBG + pRed = 50; pGreen = 150; pBlue = 255 + Case GUICOLOR_LINKFG + pRed = 0; pGreen = 0; pBlue = 255 + EndSelect + + Return False + + EndMethod + + Method LibraryFont:TGuiFont( pFontType% = GUIFONT_SYSTEM, pFontSize:Double = 0, pFontStyle% = FONT_NORMAL ) + ?Win32 + If pFontSize <= 0 Then + Select pFontType + Case GUIFONT_SYSTEM;pFontSize = 8 + Case GUIFONT_SERIF;pFontSize = 11 + Default;pFontSize = 10 + EndSelect + EndIf + ?Not Win32 + If pFontSize <= 0 Then + pFontSize = 12 + ?MacOs + If pFontType = GUIFONT_SYSTEM Then pFontSize = 11 + ?Not Win32 + EndIf + ? + Select pFontType + Case GUIFONT_MONOSPACED + ?Linux + Return LoadFontWithDouble("Lucida",pFontSize,pFontStyle) + ?MacOS + Return LoadFontWithDouble("Monaco",pFontSize,pFontStyle) + ?Win32 + 'Let's give any Vista users the chance to use the new Consolas font. + Local tmpFont:TGuiFont = LoadFontWithDouble("Consolas",pFontSize,pFontStyle) + If tmpFont.name = "Consolas" Then Return tmpFont + Return LoadFontWithDouble("Courier New",pFontSize,pFontStyle) + ? + Case GUIFONT_SANSSERIF + ?Linux + Return LoadFontWithDouble("FreeSans",pFontSize,pFontStyle) + ?MacOS + Return LoadFontWithDouble("Helvetica",pFontSize,pFontStyle) + ?Win32 + Return LoadFontWithDouble("Arial",pFontSize,pFontStyle) + ? + Case GUIFONT_SERIF + ?Linux + Return LoadFontWithDouble("FreeSerif",pFontSize,pFontStyle) + ?MacOS + Return LoadFontWithDouble("Times New Roman",pFontSize,pFontStyle) + ?Win32 + Return LoadFontWithDouble("Times New Roman",pFontSize,pFontStyle) + ? + Case GUIFONT_SCRIPT + ?Linux + Return LoadFontWithDouble("TSCu_Comic",pFontSize,pFontStyle) + ?MacOS + Return LoadFontWithDouble("Comic Sans MS",pFontSize,pFontStyle) + ?Win32 + Return LoadFontWithDouble("Comic Sans MS",pFontSize,pFontStyle) + ? + Default 'GUIFONT_SYSTEM + ?Linux + Return LoadFontWithDouble("FreeSans",pFontSize,pFontStyle) + ?MacOS + Return LoadFontWithDouble("Lucida Grande",pFontSize,pFontStyle) + ?Win32 + Return LoadFontWithDouble("MS Shell Dlg",pFontSize,pFontStyle) + ? + EndSelect + EndMethod + + Method LoadFontWithDouble:TGuiFont(name$,size:Double,flags) + Return LoadFont(name,Int(size+0.5),flags) + EndMethod + + ' Localization Code + + Field _mapLocalized:TMap = CreateMap() + + Method SetLocalizationMode( mode:Int ) + Local tmpApply:Int = False + If (LocalizationMode() ~ mode) & LOCALIZATION_ON Then tmpApply = True + engine_SetLocalizationMode(mode) + If tmpApply Then ApplyLanguage() + EndMethod + + Method SetLanguage( language:TMaxGUILanguage ) + engine_SetLocalizationLanguage(language) + ApplyLanguage() + EndMethod + + Method ApplyLanguage() + For Local tmpGadget:TGadget = EachIn MapKeys(_mapLocalized) + ApplyLocalization( tmpGadget ) + Next + EndMethod + + Method SetGadgetLocalization( gadget:TGadget, text$, tooltip$ ) + If gadget Then + MapInsert _mapLocalized, gadget, [text,tooltip] + ApplyLocalization( gadget ) + EndIf + EndMethod + + Method ApplyLocalization( gadget:TGadget ) + If gadget.Class() <> GADGET_CANVAS Then + Local tmpString$[] = String[](MapValueForKey( _mapLocalized, gadget )) + gadget.SetText(LocalizeString(tmpString[0])) + gadget.SetTooltip(LocalizeString(tmpString[1])) + For Local i:Int = 0 Until gadget.items.length + If Max(gadget.ItemFlags(i),0)&GADGETITEM_LOCALIZED Then + LocalizeGadgetItem( gadget, i ) + EndIf + Next + EndIf + EndMethod + + Method LocalizeGadgetItem( gadget:TGadget, index:Int ) + gadget.SetListItem(index,LocalizeString(gadget.ItemText(index)),LocalizeString(gadget.ItemTip(index)),gadget.ItemIcon(index),gadget.ItemExtra(index)) + EndMethod + + Method GadgetLocalized:Int( gadget:TGadget ) + Return MapContains( _mapLocalized, gadget ) + EndMethod + + Method DelocalizeGadget( gadget:TGadget ) + MapRemove _mapLocalized, gadget + EndMethod + +End Type + +Global maxgui_driver:TMaxGUIDriver + +' Localization Handling + +Const LOCALIZATION_OVERRIDE:Int = 2 + +Private + +Function DelocalizeGadget(gadget:TGadget) + maxgui_driver.DelocalizeGadget(gadget) +EndFunction + +Function driver_SetLocalizationMode(mode:Int) + maxgui_driver.SetLocalizationMode(mode) +EndFunction + +Function driver_SetLocalizationLanguage(language:TMaxGUILanguage) + maxgui_driver.SetLanguage(language) +EndFunction + +Global engine_SetLocalizationMode( mode:Int ) = _SetLocalizationMode +Global engine_SetLocalizationLanguage( language:TMaxGUILanguage ) = _SetLocalizationLanguage + +_SetLocalizationMode = driver_SetLocalizationMode +_SetLocalizationLanguage = driver_SetLocalizationLanguage + +TGadget.LocalizeString = LocalizeString +TGadget.DelocalizeGadget = DelocalizeGadget diff --git a/mod/maxgui.mod/maxgui.mod/event.bmx b/mod/maxgui.mod/maxgui.mod/event.bmx new file mode 100644 index 0000000..93a9122 --- /dev/null +++ b/mod/maxgui.mod/maxgui.mod/event.bmx @@ -0,0 +1,43 @@ +Strict + +Import BRL.Event + +Import "gadget.bmx" + +Function PostGuiEvent( id,source:TGadget=Null,data=0,mods=0,x=0,y=0,extra:Object=Null ) + + If source Then + While source.source + source=source.source + Wend + EndIf + + EmitEvent CreateEvent( id,source,data,mods,x,y,extra ) + +End Function + +Function QueueGuiEvent( id,source:TGadget=Null,data=0,mods=0,x=0,y=0,extra:Object=Null ) + + If source Then + While source.source + source=source.source + Wend + EndIf + + eventQueue.AddLast CreateEvent( id,source,data,mods,x,y,extra ) + +End Function + +Function DispatchGuiEvents() + + For Local tmpEvent:TEvent = EachIn eventQueue + EmitEvent tmpEvent + Next + + eventQueue.Clear() + +End Function + +Private + +Global eventQueue:TList = New TList diff --git a/mod/maxgui.mod/maxgui.mod/gadget.bmx b/mod/maxgui.mod/maxgui.mod/gadget.bmx new file mode 100644 index 0000000..0dea7fd --- /dev/null +++ b/mod/maxgui.mod/maxgui.mod/gadget.bmx @@ -0,0 +1,1088 @@ +Strict + +Import BRL.LinkedList +Import BRL.Graphics +Import BRL.Pixmap + +Import "guifont.bmx" +Import "iconstrip.bmx" +Import "gadgetitem.bmx" + +Const GADGET_DESKTOP=0 +Const GADGET_WINDOW=1 +Const GADGET_BUTTON=2 +Const GADGET_PANEL=3 +Const GADGET_TEXTFIELD=4 +Const GADGET_TEXTAREA=5 +Const GADGET_COMBOBOX=6 +Const GADGET_LISTBOX=7 +Const GADGET_TOOLBAR=8 +Const GADGET_TABBER=9 +Const GADGET_TREEVIEW=10 +Const GADGET_HTMLVIEW=11 +Const GADGET_LABEL=12 +Const GADGET_SLIDER=13 +Const GADGET_PROGBAR=14 +Const GADGET_MENUITEM=15 +Const GADGET_NODE=16 +Const GADGET_CANVAS=17 +Const GADGET_TIMER=18 + +Const ACTIVATE_FOCUS=0 +Const ACTIVATE_CUT=1 +Const ACTIVATE_COPY=2 +Const ACTIVATE_PASTE=3 +Const ACTIVATE_MINIMIZE=4 +Const ACTIVATE_MAXIMIZE=5 +Const ACTIVATE_RESTORE=6 +Const ACTIVATE_SELECT=7 +Const ACTIVATE_EXPAND=8 +Const ACTIVATE_COLLAPSE=9 +Const ACTIVATE_BACK=10 +Const ACTIVATE_FORWARD=11 +Const ACTIVATE_PRINT=12 +Const ACTIVATE_REDRAW=13 +Const ACTIVATE_UNDO=14 +Const ACTIVATE_REDO=15 + +Const LAYOUT_NONE=0 +Const LAYOUT_ABSOLUTE=1 +Const LAYOUT_PROPORTIONAL=2 + +Const GUICOLOR_WINDOWBG = 0 +Const GUICOLOR_GADGETBG = 1 +Const GUICOLOR_GADGETFG = 2 +Const GUICOLOR_SELECTIONBG = 3 +Const GUICOLOR_LINKFG = 4 + +Const WINDOW_TITLEBAR=1 +Const WINDOW_RESIZABLE=2 +Const WINDOW_MENU=4 +Const WINDOW_STATUS=8 +Const WINDOW_TOOL=16 +Const WINDOW_CLIENTCOORDS=32 +Const WINDOW_HIDDEN=64 +Const WINDOW_ACCEPTFILES=128 +Const WINDOW_CHILD=256 +Const WINDOW_CENTER=512 + +Const WINDOW_DEFAULT=WINDOW_TITLEBAR|WINDOW_RESIZABLE|WINDOW_MENU|WINDOW_STATUS + +Const LABEL_LEFT=0 +Const LABEL_FRAME=1 +Const LABEL_SUNKENFRAME=2 +Const LABEL_SEPARATOR=3 +Const LABEL_RIGHT=8 +Const LABEL_CENTER=16 + +Const BUTTON_PUSH=8 +Const BUTTON_CHECKBOX=2 +Const BUTTON_RADIO=3 +Const BUTTON_OK=4 +Const BUTTON_CANCEL=5 + + +Const CHECK_CLEARED = 0 +Const CHECK_SELECTED = 1 +Const CHECK_INDETERMINATE = -1 + + +Const PANEL_SUNKEN=1 +Const PANEL_RAISED=2 +Const PANEL_GROUP=3 +Const PANEL_BORDER=PANEL_SUNKEN 'For backwards compatibility + +Const PANEL_ACTIVE=4 +Const PANEL_CANVAS=8 + +Const PANELPIXMAP_TILE=0 +Const PANELPIXMAP_CENTER=1 +Const PANELPIXMAP_FIT=2 +Const PANELPIXMAP_STRETCH=3 +Const PANELPIXMAP_FIT2=4 + +Const GADGETPIXMAP_BACKGROUND = 0 +Const GADGETPIXMAP_ICON = 8 +Const GADGETPIXMAP_NOTEXT = 16 + +Const TEXTAREA_ALL=-1 + +Const TEXTAREA_CHARS=1 +Const TEXTAREA_LINES=2 + +Const TEXTAREA_WORDWRAP=1 +Const TEXTAREA_READONLY=2 + +Const TEXTFIELD_PASSWORD=1 + +Const TEXTFORMAT_BOLD=1 +Const TEXTFORMAT_ITALIC=2 +Const TEXTFORMAT_UNDERLINE=4 +Const TEXTFORMAT_STRIKETHROUGH=8 + +Const LISTBOX_MULTISELECT=1 + +Const COMBOBOX_EDITABLE=1 + +Const TREEVIEW_DRAGNDROP=1 + +Const SLIDER_HORIZONTAL=1 +Const SLIDER_VERTICAL=2 +Const SLIDER_SCROLLBAR=0 +Const SLIDER_TRACKBAR=4 +Const SLIDER_STEPPER=8 +Const SLIDER_DIAL=12 + +Const HTMLVIEW_NOCONTEXTMENU=1 +Const HTMLVIEW_NONAVIGATE=2 + +Const STATE_MINIMIZED=1 +Const STATE_MAXIMIZED=2 +Const STATE_DISABLED=4 +Const STATE_HIDDEN=8 +Const STATE_SELECTED=16 +Const STATE_ACTIVE=32 +Const STATE_INDETERMINATE=64|STATE_SELECTED + +Const GADGETICON_SEPARATOR=-2 +Const GADGETICON_BLANK=-1 + +Const GADGETITEM_NONE=-1 +Const GADGETITEM_NORMAL=0 +Const GADGETITEM_DEFAULT=1 +Const GADGETITEM_TOGGLE=2 +Const GADGETITEM_LOCALIZED=4 + +Const SENSITIZE_MOUSE=1 +Const SENSITIZE_KEYS=2 +Const SENSITIZE_ALL=SENSITIZE_MOUSE|SENSITIZE_KEYS + +Const EDGE_CENTERED=0 +Const EDGE_ALIGNED=1 +Const EDGE_RELATIVE=2 + +Const QUERY_HWND=1 +Const QUERY_HWND_CLIENT=2 +Const QUERY_NSVIEW=3 +Const QUERY_NSVIEW_CLIENT=4 +Const QUERY_FLWIDGET=5 +Const QUERY_FLWIDGET_CLIENT=6 + +Const EVENT_GADGETDRAG% = $200A, EVENT_GADGETDROP% = $200B +TEvent.RegisterId EVENT_GADGETDRAG, "GadgetDrag" +TEvent.RegisterId EVENT_GADGETDROP, "GadgetDrop" + +' WARNING - struct nsgadget in brl.mod/cocoagui.mod/cocoa.macos.m must be modified if TGadget field count changes + +Type TGadget +' event propagation + Field source:TGadget +' hierachy + Field parent:TGadget + Field kids:TList=New TList +' properties + Field xpos,ypos,width,height + Field name$, extra:Object 'See GadgetExtra() and SetGadgetExtra() + Field style, sensitivity +' slider vars + Field visible,total=1 +' layout + Field lockl,lockr,lockt,lockb + Field lockx,locky,lockw,lockh,lockcw,lockch +' filters + Field eventfilter(event:TEvent,context:Object) + Field context:Object +' items + Field items:TGadgetItem[] + + Global dragGadget:TGadget[3] + + Global LocalizeString$( text$ ) 'set at the bottom of maxgui.mod/driver.bmx + 'Global LocalizeGadget( gadget:TGadget, text$ ) + Global DelocalizeGadget( gadget:TGadget ) + +' core methods + + Method SetFilter(callback(event:TEvent,context:Object),user:Object) + eventfilter=callback + context=user + End Method + + Method HasDescendant(pGadget:TGadget) + If pGadget = Self Then Return True + For Local tmpGadget:TGadget = EachIn kids + Local tmpResult = tmpGadget.HasDescendant(pGadget) + If tmpResult Then Return tmpResult + Next + EndMethod + + Method _setparent(widget:TGadget,index=-1) 'private use setgroup + If parent parent.kids.remove Self + parent=widget + If parent + If index<0 Or index>=parent.kids.count() + parent.kids.addlast Self + Else + If index=0 + parent.kids.addfirst Self + Else + Local link:TLink + link=parent.kids.findlink(parent.kids.valueatindex(index)) + parent.kids.InsertBeforeLink Self,link + EndIf + EndIf + EndIf + End Method + + Field arrPrevSelection:Int[] + + 'Private method for multi-select listbox event handling. + 'Returns first item whose state has changed or -1 if selection has stayed the same. + + Method SelectionChanged() + Local i%, arrLastSelection:Int[] = arrPrevSelection, arrCurrSelection:Int[] = SelectedItems() + arrPrevSelection = arrCurrSelection + For i = 0 Until Min(arrLastSelection.length,arrCurrSelection.length) + If arrCurrSelection[i] <> arrLastSelection[i] Then Return Min(arrCurrSelection[i],arrLastSelection[i]) + Next + If i < arrLastSelection.length Then Return arrLastSelection[i] ElseIf i < arrCurrSelection.length Then Return arrCurrSelection[i] + Return -1 + EndMethod + + Method Handle:TGadget() + Return Self + End Method + +' layout + + Method GetXPos%() + Return xpos + EndMethod + + Method GetYPos%() + Return ypos + EndMethod + + Method GetWidth%() + Return width + EndMethod + + Method GetHeight%() + Return height + EndMethod + + Method GetGroup:TGadget() + Return parent + EndMethod + + Method SetShape(x,y,w,h) + SetArea(x,y,w,h) + LockLayout + End Method + + Method SetArea(x,y,w,h) + SetRect x,y,w,h + Rethink() + LayoutKids + End Method + + Method SetRect(x,y,w,h) + xpos=x;ypos=y;width=Max(w,0);height=Max(h,0) + End Method + + Method LockLayout() + lockx=xpos + locky=ypos + lockw=width + lockh=height + lockcw=1 + lockch=1 + If parent + lockcw=Max(parent.ClientWidth(),1) + lockch=Max(parent.ClientHeight(),1) + EndIf + End Method + + Method SetLayout( lft,rht,top,bot ) + lockl=lft + lockr=rht + lockt=top + lockb=bot + LockLayout + End Method + + Method LayoutKids() + For Local w:TGadget = EachIn kids + w.DoLayout() + Next + End Method + + Method DoLayout() + Local cw,ch,x,x2,y,y2 + + If Not parent Or Class() = GADGET_WINDOW Or Class() = GADGET_MENUITEM Or Class() = GADGET_NODE Then Return + +' horizontal + cw=Max(parent.ClientWidth(),1) + x=xpos + x2=xpos+width + If lockl Or lockr + If lockl=LAYOUT_ABSOLUTE x=lockx Else If lockl=LAYOUT_PROPORTIONAL x=cw*lockx/lockcw + If lockr=LAYOUT_ABSOLUTE x2=lockx+lockw-lockcw+cw Else If lockr=LAYOUT_PROPORTIONAL x2=cw*(lockx+lockw)/lockcw + If Not lockl x=x2-lockw Else If Not lockr x2=x+lockw + Else + x=cw*(lockx+lockw/2)/lockcw-lockw/2 + x2=x+lockw + EndIf +' vertical + ch=Max(parent.ClientHeight(),1) + y=ypos + y2=ypos+height + If lockt Or lockb + If lockt=LAYOUT_ABSOLUTE y=locky Else If lockt=LAYOUT_PROPORTIONAL y=ch*locky/lockch + If lockb=LAYOUT_ABSOLUTE y2=locky+lockh-lockch+ch Else If lockb=LAYOUT_PROPORTIONAL y2=ch*(locky+lockh)/lockch + If Not lockt y=y2-lockh Else If Not lockb y2=y+lockh + Else + y=ch*(locky+lockh/2)/lockch-lockh/2 + y2=y+lockh + EndIf + + SetArea( x,y,x2-x,y2-y ) + End Method + +' datasource + Field datasource:Object + Field datakeys$[] + +' Global gadgetdatamap:TMap=New TMap 'need pollevent for automatic refresh + + Method SetDataSource(data:Object) + Clear + datasource=data + datakeys=Null +' gadgetdatamap.insert Self,data + SyncDataSource + End Method + + Function KeysFromList$[](list:TList) + Local s:String[] + Local o:Object + Local i + s=New String[list.count()] + For o=EachIn list + s[i]=o.ToString() + i:+1 + Next + Return s + End Function + + Function KeysFromObjectArray$[](list:Object[]) + Local s:String[] + Local o:Object + Local i + s=New String[list.length] + For o=EachIn list + s[i]=o.ToString() + i:+1 + Next + Return s + End Function + + Method SyncDataSource() 'returns true if items modified + Local newkeys$[] + If Not datasource Return False + Select True + Case TList(datasource)<>Null + newkeys=KeysFromList(TList(datasource)) + Case String[](datasource)<>Null + newkeys=String[](datasource) + Case Object[](datasource)<>Null + newkeys=KeysFromObjectArray(Object[](datasource)) + End Select + If Not newkeys Or newkeys.length=0 'datasource is empty or unsupported + If items.length + Clear + Return True + EndIf + Return False + EndIf +' If newkeys.compare(datakeys)=0 Return False + SyncData newkeys + datakeys=newkeys[..newkeys.length] + End Method + +' for each item +' if same move on +' if diff +' see when next occurance is and how big a match will occur from remove +' if deletes=datakeys.length + InsertItemFromKey(icount,k$) + icount:+1 + Continue + EndIf + + If k$=datakeys[d1] + d1:+1 + icount:+1 + Continue + EndIf + + diff=1 + For d2=d1+1 Until datakeys.length + If k=datakeys[d2] Exit + diff:+1 + Next + same=1 + p2=p1+1 + For d3=d2+1 Until datakeys.length + If p2>=newkeys.length Exit + If newkeys[p2]<>datakeys[d3] Exit + same:+1 + p2:+1 + Next + + If same>diff + d1:+diff + While diff + RemoveItem icount + diff:-1 + Wend + d1:+1 + icount:+1 + Else + InsertItemFromKey(icount,k$) + icount:+1 + EndIf + Next + While icountitems.length Throw "Gadget item index out of range." +? + items=items[..items.length+1] + For Local i=items.length-2 To index Step -1 + items[i+1]=items[i] + Next + items[index]=New TGadgetItem + items[index].Set(text,tip,icon,extra,flags) + If flags&GADGETITEM_LOCALIZED Then + InsertListItem(index,LocalizeString(text),LocalizeString(tip),icon,extra) + Else + InsertListItem(index,text,tip,icon,extra) + EndIf + If flags&GADGETITEM_DEFAULT SelectItem(index) + End Method + + + Method SetItem(index,text$,tip$,icon,extra:Object,flags) +?debug + If index<0 Or index>=items.length Throw "Gadget item index out of range." +? + items[index].Set(text,tip,icon,extra,flags) + If flags&GADGETITEM_LOCALIZED Then + SetListItem(index,LocalizeString(text),LocalizeString(tip),icon,extra) + Else + SetListItem(index,text,tip,icon,extra) + EndIf + If flags&GADGETITEM_DEFAULT SelectItem(index) + End Method + + Method RemoveItem(index) +?debug + If index<0 Or index>=items.length Throw "Gadget item index out of range." +? + For Local i=index Until items.length-1 + items[i]=items[i+1] + Next + items=items[..items.length-1] + RemoveListItem(index) + End Method + + Method ItemCount() + Return items.length + End Method + + Method ItemText$(index) +?debug + If index<0 Or index>=items.length Throw "Gadget item index out of range." +? + Return items[index].text + End Method + + Method ItemTip$(index) +?debug + If index<0 Or index>=items.length Throw "Gadget item index out of range." +? + Return items[index].tip + End Method + + Method ItemFlags(index) +?debug + If index<0 Or index>=items.length Throw "Gadget item index out of range." +? + Return items[index].flags + End Method + + Method ItemIcon(index) +?debug + If index<0 Or index>=items.length Throw "Gadget item index out of range." +? + Return items[index].icon + End Method + + Method ItemExtra:Object(index) + If index = -1 Then Return Null +?debug + If index<0 Or index>=items.length Throw "Gadget item index out of range." +? + Return items[index].extra + End Method + + Method SetItemState(index,state) +?debug + If index<0 Or index>=items.length Throw "Gadget item index out of range." +? + SetListItemState(index,state) + End Method + + Method ItemState(index) +?debug + If index<0 Or index>=items.length Throw "Gadget item index out of range." +? + Return ListItemState(index) + End Method + + Method SelectItem(index,op=1) '0=deselect 1=select 2=toggle + Local item:TGadgetItem + Local state,icon + Local i + If index=-1 + For i=0 Until items.length + SelectItem i,op + Next + Return + EndIf +?debug + If index<0 Or index>=items.length Throw "Gadget item index out of range." +? + state=ItemState(index) + Select op + Case 0 + state:&~STATE_SELECTED + Case 1 + state:|STATE_SELECTED + Case 2 + state:~STATE_SELECTED + End Select + item=items[index] + icon=item.icon + If icon>-1 And item.flags&GADGETITEM_TOGGLE + If state&STATE_SELECTED icon:+1 + SetListItem index,item.text,item.tip,icon,item.extra 'toggle icon + EndIf + SetItemState index,state + End Method + + Method SelectedItem() + Local selection:Int[] = SelectedItems() + If selection.length = 1 Then Return selection[0] Else Return -1 + End Method + + Method SelectedItems[]() + Local index,count,array[items.length] + For index=0 Until items.length + If ListItemState(index)&STATE_SELECTED Then + array[count] = index + count:+1 + EndIf + Next + If count Then Return array[..count] + End Method + +' maxgui interface + Method Insert(group:TGadget,index=-1) + End Method + Method Query(queryid) + End Method + Method CleanUp() + For Local tmpChild:TGadget = EachIn kids.Copy() + tmpChild.CleanUp() + Next + Free() + + DelocalizeGadget( Self ) + kids.Clear();parent = Null;extra = Null + eventfilter = Null;context = Null;items = Null + + For Local i% = 0 Until dragGadget.length + If dragGadget[i] = Self Then dragGadget[i] = Null + Next + End Method + Method Free() + End Method + Method Rethink() 'resize + End Method + Method ClientWidth() + End Method + Method ClientHeight() + End Method + Method Activate(command) + End Method + Method State() + End Method + Method SetText(text$) + End Method + Method GetText$() + End Method + Method SetFont(font:TGuiFont) + End Method + Method SetColor(r,g,b) + End Method + Method RemoveColor() + End Method + Method SetAlpha(a#) + End Method + Method SetTextColor(r,g,b) + End Method + Method SetTooltip( pTip$ ) + EndMethod + Method GetTooltip$() + EndMethod + Method SetPixmap(pixmap:TPixmap,flags) + End Method + Method SetIconStrip(iconstrip:TIconStrip) + End Method + Method SetShow(bool) + End Method + Method SetEnabled(bool) + End Method + Method SetSelected(bool) + End Method + Method SetHotKey(keycode,modifier) + End Method + Method SetSensitivity( flags ) + sensitivity = flags + EndMethod + Method GetSensitivity() + Return sensitivity + EndMethod + Method Class() + EndMethod +' window commands + Method GetStatusText$() + End Method + Method SetStatusText(text$) + End Method + Method GetMenu:TGadget() + End Method + Method PopupMenu(menu:TGadget,extra:Object=Null) + End Method + Method UpdateMenu() + End Method + Method SetMinimumSize(w,h) + End Method + Method SetMaximumSize(w,h) + End Method +' list commands + Method ClearListItems() + End Method + Method InsertListItem(index,text$,tip$,icon,tag:Object) + End Method + Method SetListItem(index,text$,tip$,icon,tag:Object) + End Method + Method RemoveListItem(index) + End Method + Method SetListItemState(index,state) + End Method + Method ListItemState(index) + End Method +' treeview commands + Method RootNode:TGadget() + End Method + Method InsertNode:TGadget(index,text$,icon) + End Method + Method ModifyNode(text$,icon) + End Method + Method SelectedNode:TGadget() + End Method + Method CountKids() + End Method +' textarea commands + Method ReplaceText(pos,length,text$,units) + End Method + Method AddText(text$) + End Method + Method AreaText$(pos,length,units) + End Method + Method AreaLen(units) + End Method + Method LockText() + End Method + Method UnlockText() + End Method + Method SetTabs(tabwidth) + End Method + Method SetMargins(leftmargin) + End Method + Method GetCursorPos(units) + End Method + Method GetSelectionLength(units) + End Method + Method SetStyle(r,g,b,flags,pos,length,units) + End Method + Method SetSelection(pos,length,units) + End Method + Method CharX(char) + EndMethod + Method CharY(char) + EndMethod + Method CharAt(line) + End Method + Method LineAt(index) + End Method +' progbar + Method SetValue(value#) + End Method +' slider + Method SetRange(visible,total) + End Method + Method SetProp(value) + End Method + Method GetProp() + End Method +' canvas + Method AttachGraphics:TGraphics( flags ) + End Method + Method CanvasGraphics:TGraphics() + End Method +' htmlview + Method Run$(script$) + End Method +End Type + +Global NullProxy:TGadget=New TGadget + +Type TProxyGadget Extends TGadget + Field proxy:TGadget=NullProxy + + Method SetProxy(gadget:TGadget) + If proxy And proxy.source = Self Then proxy.source = Null + proxy=gadget + If proxy Then proxy.source = Self + End Method + + Method GetProxy:TGadget() + Return proxy + End Method + +' maxgui interface + Method GetXPos%() + Return proxy.GetXPos() + EndMethod + Method GetYPos%() + Return proxy.GetYPos() + EndMethod + Method GetWidth%() + Return proxy.GetWidth() + EndMethod + Method GetHeight%() + Return proxy.GetHeight() + EndMethod + Method GetGroup:TGadget() + Return proxy.GetGroup() + EndMethod + Method HasDescendant(pGadget:TGadget) + Return proxy.HasDescendant(pGadget) + EndMethod + Method Query(queryid) + Return proxy.Query(queryid) + End Method + Method CleanUp() + Return proxy.CleanUp() + End Method + Method Free() + Return proxy.Free() + End Method + Method SetShape(x,y,w,h) + proxy.SetShape(x,y,w,h) + End Method + Method Rethink() 'resize + Return proxy.Rethink() + End Method + Method ClientWidth() + Return proxy.ClientWidth() + End Method + Method ClientHeight() + Return proxy.ClientHeight() + End Method + Method Activate(command) + Return proxy.Activate(command) + End Method + Method State() + Return proxy.State() + End Method + Method SetText(text$) + Return proxy.SetText(text) + End Method + Method GetText$() + Return proxy.GetText() + End Method + Method SetTooltip( pTip$ ) + Return proxy.SetTooltip( pTip ) + EndMethod + Method GetTooltip$() + Return proxy.GetTooltip() + EndMethod + Method SetFont(font:TGuiFont) + Return proxy.SetFont(font) + End Method + Method SetColor(r,g,b) + Return proxy.SetColor(r,g,b) + End Method + Method RemoveColor() + Return proxy.RemoveColor() + End Method + Method SetAlpha(a#) + Return proxy.SetAlpha(a) + End Method + Method SetTextColor(r,g,b) + Return proxy.SetTextColor(r,g,b) + End Method + Method SetShow(bool) + Return proxy.SetShow(bool) + End Method + Method SetSelected(bool) + Return proxy.SetSelected(bool) + End Method + Method SetEnabled(bool) + Return proxy.SetEnabled(bool) + End Method + Method SetSensitivity( flags ) + Return proxy.SetSensitivity(flags) + EndMethod + Method GetSensitivity() + Return proxy.GetSensitivity() + EndMethod + Method SetHotKey(keycode,modifier) + Return proxy.SetHotKey(keycode,modifier) + End Method + Method SetIconStrip(iconstrip:TIconStrip) + Return proxy.SetIconStrip(iconstrip) + End Method + Method SetLayout( lft,rht,top,bot ) + proxy.SetLayout lft,rht,top,bot + End Method + Method Class() + Return proxy.Class() + EndMethod +' window commands + Method GetStatusText$() + End Method + Method SetStatusText(text$) + Return proxy.SetStatusText(text) + End Method + Method SetStatus(text$) + Return Self.SetStatusText(text) + EndMethod + Method GetMenu:TGadget() + Return proxy.GetMenu() + End Method + Method PopupMenu(menu:TGadget,extra:Object) + Return proxy.PopupMenu(menu,extra) + End Method + Method UpdateMenu() + Return proxy.UpdateMenu() + End Method + Method SetMinimumSize(w,h) + Return proxy.SetMinimumSize(w,h) + End Method + Method SetMaximumSize(w,h) + Return proxy.SetMaximumSize(w,h) + End Method +' list commands + Method ClearListItems() + Return proxy.ClearListItems() + End Method + Method InsertListItem(index,text$,tip$,icon,extra:Object) + Return proxy.InsertListItem(index,text,tip,icon,extra) + End Method + Method SetListItem(index,text$,tip$,icon,extra:Object) + Return proxy.SetListItem(index,text,tip,icon,extra) + End Method + Method RemoveListItem(index) + Return proxy.RemoveListItem(index) + End Method + Method SetListItemState(index,state) + Return proxy.SetListItemState(index,state) + End Method + Method ListItemState(index) + Return proxy.ListItemState(index) + End Method +' treeview commands + Method RootNode:TGadget() + Return proxy.RootNode() + End Method + Method InsertNode:TGadget(index,text$,icon) + Return proxy.InsertNode(index,text,icon) + End Method + Method ModifyNode(text$,icon) + Return proxy.ModifyNode(text,icon) + End Method + Method SelectedNode:TGadget() + Return proxy.SelectedNode() + End Method + Method CountKids() + Return proxy.CountKids() + End Method +' textarea commands + Method ReplaceText(pos,length,text$,units) + Return proxy.ReplaceText(pos,length,text,units) + End Method + Method AddText(text$) + Return proxy.AddText(text) + End Method + Method AreaText$(pos,length,units) + Return proxy.AreaText(pos,length,units) + End Method + Method AreaLen(units) + Return proxy.AreaLen(units) + End Method + Method LockText() + Return proxy.LockText() + End Method + Method UnlockText() + Return proxy.UnlockText() + End Method + Method SetTabs(tabwidth) + Return proxy.SetTabs(tabwidth) + End Method + Method SetMargins(leftmargin) + Return proxy.SetMargins(leftmargin) + End Method + Method GetCursorPos(units) + Return proxy.GetCursorPos(units) + End Method + Method GetSelectionLength(units) + Return proxy.GetSelectionLength(units) + End Method + Method SetStyle(r,g,b,flags,pos,length,units) + Return proxy.SetStyle(r,g,b,flags,pos,length,units) + End Method + Method SetSelection(pos,length,units) + Return proxy.SetSelection(pos,length,units) + End Method + Method CharX(char) + Return proxy.CharX(char) + End Method + Method CharY(char) + Return proxy.CharY(char) + End Method + Method CharAt(line) + Return proxy.CharAt(line) + End Method + Method LineAt(index) + Return proxy.LineAt(index) + End Method +' progbar + Method SetValue(value#) + Return proxy.SetValue(value) + End Method +' slider + Method SetRange(visible,total) + Return proxy.SetRange(visible,total) + End Method + Method SetProp(value) + Return proxy.SetProp(value) + End Method + Method GetProp() + Return proxy.GetProp() + End Method +' panel + Method SetPixmap(pixmap:TPixmap,flags) + Return proxy.SetPixmap(pixmap,flags) + End Method +' canvas + Method AttachGraphics:TGraphics( flags ) + Return proxy.AttachGraphics( flags ) + End Method + Method CanvasGraphics:TGraphics() + Return proxy.CanvasGraphics() + End Method +' htmlview + Method Run$(script$) + Return proxy.Run(script) + End Method +'items + Method Clear() + Return proxy.Clear() + End Method + Method InsertItem(index,text$,tip$,icon,extra:Object,flags) + Return proxy.InsertItem(index,text,tip,icon,extra,flags) + End Method + Method SetItem(index,text$,tip$,icon,extra:Object,flags) + Return proxy.SetItem(index,text,tip,icon,extra,flags) + End Method + Method RemoveItem(index) + Return proxy.RemoveItem(index) + End Method + Method ItemCount() + Return proxy.ItemCount() + End Method + Method ItemText$(index) + Return proxy.ItemText(index) + End Method + Method ItemTip$(index) + Return proxy.ItemTip(index) + End Method + Method ItemFlags(index) + Return proxy.ItemFlags(index) + End Method + Method ItemIcon(index) + Return proxy.ItemIcon(index) + End Method + Method ItemExtra:Object(index) + Return proxy.ItemExtra(index) + End Method + Method SetItemState(index,state) + Return proxy.SetItemState(index,state) + End Method + Method ItemState(index) + Return proxy.ItemState(index) + End Method + Method SelectItem(index,op=1) '0=deselect 1=select 2=toggle + Return proxy.SelectItem(index,op) + End Method + Method SelectedItem() + Return proxy.SelectedItem() + End Method + Method SelectedItems[]() + Return proxy.SelectedItems() + End Method +End Type diff --git a/mod/maxgui.mod/maxgui.mod/gadgetitem.bmx b/mod/maxgui.mod/maxgui.mod/gadgetitem.bmx new file mode 100644 index 0000000..fd7081d --- /dev/null +++ b/mod/maxgui.mod/maxgui.mod/gadgetitem.bmx @@ -0,0 +1,18 @@ +Strict + +Type TGadgetItem + + Field text$, tip$, icon, flags + Field extra:Object + + 'Method Set:TGadgetItem(_text$,_tip$,_icon,_extra:Object,_flags) + Method Set(_text$,_tip$,_icon,_extra:Object,_flags) + text=_text + tip=_tip + icon=_icon + flags=_flags + extra=_extra + 'Return Self + End Method + +End Type diff --git a/mod/maxgui.mod/maxgui.mod/guifont.bmx b/mod/maxgui.mod/maxgui.mod/guifont.bmx new file mode 100644 index 0000000..37a7b24 --- /dev/null +++ b/mod/maxgui.mod/maxgui.mod/guifont.bmx @@ -0,0 +1,23 @@ +Strict + +Const FONT_NORMAL = 0 +Const FONT_BOLD = 1 +Const FONT_ITALIC = 2 +Const FONT_UNDERLINE = 4 +Const FONT_STRIKETHROUGH = 8 'Unsupported on some platforms + +Const GUIFONT_SYSTEM% = 1 +Const GUIFONT_MONOSPACED% = 2 +Const GUIFONT_SANSSERIF% = 3 +Const GUIFONT_SERIF% = 4 +Const GUIFONT_SCRIPT% = 5 + +Type TGuiFont + Field name$ + Field path$ + Field style + Field size + Field handle + + Method CharWidth(charcode) Abstract +End Type diff --git a/mod/maxgui.mod/maxgui.mod/iconstrip.bmx b/mod/maxgui.mod/maxgui.mod/iconstrip.bmx new file mode 100644 index 0000000..cff63dd --- /dev/null +++ b/mod/maxgui.mod/maxgui.mod/iconstrip.bmx @@ -0,0 +1,16 @@ +Strict + +Import BRL.Pixmap + +Type TIconStrip + + Field pixmap:TPixmap + Field count + + Method ExtractIconPixmap:TPixmap(index:Int) + If (index>=count) Then Return Null + If (index < 0) Then Return pixmap.Copy() + Return pixmap.Window(index*pixmap.height,0,pixmap.height,pixmap.height) + EndMethod + +EndType diff --git a/mod/maxgui.mod/maxgui.mod/maxgui.bmx b/mod/maxgui.mod/maxgui.mod/maxgui.bmx new file mode 100644 index 0000000..c1d8263 --- /dev/null +++ b/mod/maxgui.mod/maxgui.mod/maxgui.bmx @@ -0,0 +1,2394 @@ + +Strict + +Rem +bbdoc: MaxGUI/MaxGUI +End Rem +Module MaxGUI.MaxGUI + +ModuleInfo "Version: 1.35" +ModuleInfo "Author: Simon Armstrong, Mark Sibly" +ModuleInfo "License: zlib/libpng" + +Import BRL.Map +Import BRL.LinkedList +Import BRL.FileSystem +Import BRL.StandardIO + +Import "driver.bmx" +Import "event.bmx" +Import "gadget.bmx" +Import "guifont.bmx" +Import "iconstrip.bmx" + +Global RequestedColor + +Type THotKey + Field succ:THotKey + Field key,mods + Field event:TEvent + Field owner +End Type + +Global hotKeys:THotKey + +Rem +bbdoc: Set a hotkey event. +about: +When the specified hotkey combination is selected by the user, the specified +@event will be emitted using #EmitEvent. + +If @event is #Null, an event with an @id equal to EVENT_HOTKEYHIT, @data equal +to @key and @mods equal to @mods will be emitted. + +#SetHotKeyEvent will overwrite any existing hotkey event with the same @key, @mods and @owner. + +Please refer to the #{Key Codes} module for valid key and modifier codes. +End Rem +Function SetHotKeyEvent:THotKey( key,mods,event:TEvent=Null,owner=0 ) + If Not event event=CreateEvent( EVENT_HOTKEYHIT,Null,key,mods ) + Local t:THotKey=hotKeys + While t + If t.key=key And t.mods=mods And t.owner=owner Then Exit + t=t.succ + Wend + If Not t + t=New THotKey + t.key=key + t.mods=mods + t.succ=hotKeys + t.owner=owner + hotKeys=t + EndIf + t.event=event + Return t +End Function + +Rem +bbdoc: Remove a hotkey event. +about: +Clears a hotkey object created with #SetHotKeyEvent. +End Rem +Function RemoveHotKey(hotkey:THotKey) + Local t:THotKey,tt:THotKey + t=hotKeys + While t + If t=hotkey + If tt tt.succ=t.succ Else hotkeys=t.succ + t.succ=Null + Return + EndIf + tt=t + t=t.succ + Wend +End Function + +Function HotKeyEvent:TEvent( key,mods,owner ) + Local t:THotKey=hotKeys + While t + If t.key=key And t.mods=mods + If t.owner And t.owner<>owner + Else + Return t.event + EndIf + EndIf + t=t.succ + Wend + Return Null +End Function + +Rem +bbdoc: Look-up a system defined color. +returns: #True if a matching color is retrieved from the system, #False if the hard-coded fall-back is used. +about: +@colorindex can be one of the following values: + +[ @Constant | @Description | @{Fall Back} +* GUICOLOR_WINDOWBG | Window/panel background color. | R: 240, G: 240, B: 240 +* GUICOLOR_GADGETBG | Gadget background color (e.g. textfield). | R: 255, G: 255, B: 255 +* GUICOLOR_GADGETFG | Gadget text color. | R: 0, G: 0, B: 0 +* GUICOLOR_SELECTIONBG | Text selection background color. | R: 50, G: 150, B: 255 +* GUICOLOR_LINKFG | Hyperlink text color. | R: 0, G: 0, B: 255 +] + +See Also: #LookupGuiFont, #RequestColor +EndRem +Function LookupGuiColor( colorindex, red:Byte Var, green:Byte Var, blue:Byte Var ) + Return maxgui_driver.LookupColor( colorindex, red, green, blue ) +EndFunction + +Rem +bbdoc: Prompts the user for a color. +returns: #True if a color is selected, #False if the requester was cancelled. +about: +The parameters @red, @green, @blue are the initial color to display in the requester, +with components in the range 0 to 255. + +After a color is selected, use the #RequestedRed, #RequestedGreen and #RequestedBlue +functions to determine the color chosen by the user. + +See Also: #LookupGuiColor +EndRem +Function RequestColor(r,g,b) + Local argb + argb=maxgui_driver.RequestColor(Byte(r),Byte(g),Byte(b)) + If argb + RequestedColor=argb + Return True + EndIf +End Function + +Rem +bbdoc: Get the red component of the color previously chosen by the user. +about: See #RequestColor for more information. +EndRem +Function RequestedRed() + Return (RequestedColor Shr 16) & $FF +End Function + +Rem +bbdoc: Get the green component of the color previously chosen by the user. +about: See #RequestColor for more information. +EndRem +Function RequestedGreen() + Return (RequestedColor Shr 8) & $FF +End Function + +Rem +bbdoc: Get the blue component of the color previously chosen by the user. +about: See #RequestColor for more information. +EndRem +Function RequestedBlue() + Return RequestedColor & $FF +End Function + +Rem +bbdoc: Prompts the user to select a system font. +returns: A @TGuiFont object, or #Null if no font was selected. +about: +Prompts the user for a font and returns an object that can then be used with the #SetGadgetFont command. + +See Also: #LoadGuiFont, #LookupGuiFont, #FontName, #FontSize and #FontStyle +EndRem +Function RequestFont:TGuiFont(font:TGuiFont=Null) + Return maxgui_driver.RequestFont(font:TGuiFont) +End Function + +Rem +bbdoc: Load a system font by name. +returns: A @TGuiFont object, or #Null if a suitable matching font was not found on the system. +about: +Loads a system font by name and returns an object that can then be used with the #SetGadgetFont command. + +Depending on the platform, some gadgets may not respond to all or any of the attributes specified in the function +parameters. + +See Also: #RequestFont, #LookupGuiFont, #FontName, #FontSize and #FontStyle +EndRem +Function LoadGuiFont:TGuiFont(name$,height:Double,bold=False,italic=False,underline=False,strikethrough=False) + Local flags = FONT_NORMAL + If bold flags:|FONT_BOLD + If italic flags:|FONT_ITALIC + If underline flags:|FONT_UNDERLINE + If strikethrough flags:|FONT_STRIKETHROUGH + Return maxgui_driver.LoadFontWithDouble(name,height,flags) +End Function + +Rem +bbdoc: Loads a suitable GUI font that best matches the supplied font characteristics. +returns: A new @TGuiFont instance chosen using the supplied parameters. +about: If the current MaxGUI driver doesn't return a suitable GUI font, then +a hard-coded fall-back font is returned instead, depending upon the platform. + +@pFontType can take one of the following constants: + +[ @Constant | @{Windows Fall-Back} | @{Mac OS X Fall-Back} | @{Linux Fall-Back} | @Description +* GUIFONT_SYSTEM | MS Shell Dlg | Lucida Grande | FreeSerif | Default font used to draw gadgets by the OS. +* GUIFONT_SERIF | Times New Roman | Times New Roman | FreeSerif | Serif font. +* GUIFONT_SANSSERIF | Arial | Helvetica | FreeSans | Sans Serif font. +* GUIFONT_SCRIPT | Comic Sans MS | Comic Sans MS | TSCu_Comic | Handwriting style font. +* GUIFONT_MONOSPACED | Consolas/Courier New | Courier | Courier | Fixed width font typically used for coding. +] + +@pFontSize specifies the point size the font should be loaded with. If this value is less than or equal to 0, then +a suitable size is automatically chosen, or a hard-coded alternative is used (usually between 8-13pt). + +@pFontStyle should specify any additional font styles that the font should be loaded with. A combination of any of the +following flags can be used: + +[ @Constant | @{Font Style} +* FONT_BOLD | Bold +* FONT_ITALIC | Italic +* FONT_UNDERLINE | Underlined +* FONT_STRIKETHROUGH | *Strikethrough +] + +%{Note: FONT_STRIKETHROUGH isn't fully supported by all gadgets/platforms.} + +See Also: #LookupGuiColor, #RequestFont, #FontName, #FontSize and #FontStyle +EndRem +Function LookupGuiFont:TGuiFont( pFontType% = GUIFONT_SYSTEM, pFontSize:Double = 0, pFontStyle% = 0 ) + Return maxgui_driver.LibraryFont( pFontType, pFontSize, pFontStyle ) +End Function + +Rem +bbdoc: Retrieves the corresponding property from the @TGuiFont type instance. +returns: A string representing the name of the font. +about: See Also: #LoadGuiFont, #LookupGuiFont, #RequestFont, #FontSize and #FontStyle +EndRem +Function FontName$(font:TGuiFont) + Return font.name +End Function + +Rem +bbdoc: Retrieves the corresponding property from the @TGuiFont type instance. +returns: A double representing the size (in points) of the font. +about: See Also: #LoadGuiFont, #LookupGuiFont, #RequestFont, #FontName and #FontStyle +EndRem +Function FontSize:Double(font:TGuiFont) + Return font.size +End Function + +Rem +bbdoc: Retrieves the corresponding property from the @TGuiFont type instance. +returns: An integer representing the style of the font (e.g. Bold, Underlined, Italics, Strikethrough). +about: The returned value will be a combination of the following bit flags: + +[ @Constant | @{Font Style} +* FONT_BOLD | Bold +* FONT_ITALIC | Italic +* FONT_UNDERLINE | Underlined +* FONT_STRIKETHROUGH | *Strikethrough +] + +%{Note: FONT_STRIKETHROUGH isn't fully supported by all gadgets/platforms.} + +See Also: #LoadGuiFont, #RequestFont, #FontName and #FontSize +EndRem +Function FontStyle(font:TGuiFont) + Return font.style +End Function + +Const POINTER_DEFAULT=0 +Const POINTER_ARROW=1 +Const POINTER_IBEAM=2 +Const POINTER_WAIT=3 +Const POINTER_CROSS=4 +Const POINTER_UPARROW=5 +Const POINTER_SIZENWSE=6 +Const POINTER_SIZENESW=7 +Const POINTER_SIZEWE=8 +Const POINTER_SIZENS=9 +Const POINTER_SIZEALL=10 +Const POINTER_NO=11 +Const POINTER_HAND=12 +Const POINTER_APPSTARTING=13 +Const POINTER_HELP=14 + +Global lastPointer% = -1 + +Rem +bbdoc: Changes the applcation's mouse cursor. +about: +The shape of the system mouse pointer can be one of the following: + +[ @Constant | @Description +* POINTER_DEFAULT | Default OS pointer. +* POINTER_ARROW | Arrow pointer. +* POINTER_IBEAM | Typically used when making text selections. +* POINTER_WAIT | Hourglass animation. +* POINTER_CROSS | Typically used for precise drawing. +* POINTER_UPARROW | Typically used for selections. +* POINTER_SIZENWSE | Typically used over sizing handles. +* POINTER_SIZENESW | Typically used over sizing handles. +* POINTER_SIZEWE | Typically used over sizing handles. +* POINTER_SIZENS | Typically used over sizing handles. +* POINTER_SIZEALL | Typically shown when moving an item. +* POINTER_NO | Typically shown when an action is prohibited. +* POINTER_HAND | Typically used for links. +* POINTER_APPSTARTING | Usually shows a pointer and miniature hourglass animation. +* POINTER_HELP | Usually shows an arrow pointer, with an adjacent question mark. +] + +%{Note: Some pointers may not be supported on all platforms.} +EndRem +Function SetPointer(shape) + If shape <> lastPointer Then + lastPointer = shape + maxgui_driver.SetPointer(shape) + EndIf +End Function + +Function UserName$() + Return maxgui_driver.UserName() +End Function + +Function ComputerName$() + Return maxgui_driver.ComputerName() +End Function + +' gadget + +Rem +bbdoc: Remove a gadget and free its resources. +EndRem +Function FreeGadget( gadget:TGadget ) + gadget.CleanUp() +End Function + +Rem +bbdoc: Client area dimensions of a gadget. +returns: The width of the client area (in pixels) of the specified container gadget. +EndRem +Function ClientWidth( gadget:TGadget ) + Return gadget.ClientWidth() +End Function + +Rem +bbdoc: Client area dimensions of a gadget. +returns: The height of the client area (in pixels) of the specified container gadget. +EndRem +Function ClientHeight( gadget:TGadget ) + Return gadget.ClientHeight() +End Function + +Rem +bbdoc: Horizontal position of gadget. +returns: The horizontal position (in pixels) of a gadget relative to the top-left corner of the parent's client area. +EndRem +Function GadgetX( gadget:TGadget ) + Return gadget.GetXPos() +End Function + +Rem +bbdoc: Vertical position of gadget. +returns: The vertical position (in pixels) of a gadget relative to the top-left corner of the parent's client area. +EndRem +Function GadgetY( gadget:TGadget ) + Return gadget.GetYPos() +End Function + +Rem +bbdoc: Gadget width. +returns: The current width (in pixels) of a gadget. +EndRem +Function GadgetWidth( gadget:TGadget ) + Return gadget.GetWidth() +End Function + +Rem +bbdoc: Gadget height. +returns: The current height (in pixels) of a gadget. +EndRem +Function GadgetHeight( gadget:TGadget ) + Return gadget.GetHeight() +End Function + +Rem +bbdoc: Return a gadget's group or parent. +returns: The @TGadget instance of the parent or group gadget. +EndRem +Function GadgetGroup:TGadget( gadget:TGadget ) + Return gadget.GetGroup() +End Function + +Rem +bbdoc: Returns an integer representing a gadget's class. +about: The returned integer will match one of the following constants: + +[ @Constant | @{Corresponding Gadget Class} +* GADGET_DESKTOP | Desktop +* GADGET_WINDOW | Window +* GADGET_BUTTON | Button +* GADGET_PANEL | Panel +* GADGET_TEXTFIELD | TextField +* GADGET_TEXTAREA | TextArea +* GADGET_COMBOBOX | ComboBox +* GADGET_LISTBOX | ListBox +* GADGET_TOOLBAR | Toolbar +* GADGET_TABBER | Tabber +* GADGET_TREEVIEW | Treeview +* GADGET_HTMLVIEW | HtmlView +* GADGET_LABEL | Label +* GADGET_SLIDER | Slider +* GADGET_PROGBAR | Progress Bar +* GADGET_MENUITEM | Menu +* GADGET_NODE | Treeview Node +* GADGET_CANVAS | Canvas Gadget +] + +EndRem +Function GadgetClass( gadget:TGadget ) + Return gadget.Class() +End Function + +Rem +bbdoc: Make a gadget visible. +about: See Also: #HideGadget and #GadgetHidden. +EndRem +Function ShowGadget( gadget:TGadget ) + gadget.SetShow True +End Function + +Rem +bbdoc: Hide a gadget. +about: See Also: #ShowGadget and #GadgetHidden. +EndRem +Function HideGadget( gadget:TGadget ) + gadget.SetShow False +End Function + +Rem +bbdoc: Enable a gadget, allowing user interaction. +about: See Also: #DisableGadget and #GadgetDisabled. +EndRem +Function EnableGadget( gadget:TGadget ) + gadget.SetEnabled True +End Function + +Rem +bbdoc: Disable a gadget, blocking user interaction. +about: See Also: #EnableGadget and #GadgetDisabled. +EndRem +Function DisableGadget( gadget:TGadget ) + gadget.SetEnabled False +End Function + +Rem +bbdoc: Determines whether a gadget is marked as hidden. +returns: #True if the gadget is set to be hidden, #False otherwise. +about: If the optional @recursive parameter is set to #True, the function will only return #False +if the gadget and all of its ancestors are visible, otherwise the function simply returns the +property of the individual gadget. + +See Also: #ShowGadget and #HideGadget. +EndRem +Function GadgetHidden( gadget:TGadget, recursive% = False ) + If recursive Then + While Not (gadget.State()&STATE_HIDDEN) + gadget = gadget.parent + If Not gadget Return False + Wend + Return True + EndIf + Return (gadget.State()&STATE_HIDDEN) +End Function + +Rem +bbdoc: Determines whether a gadget is marked as enabled. +returns: #True if the gadget is set to be disabled, #False otherwise. +about: If the optional @recursive parameter is set to #True, the function will only return #False +if the gadget and all of its ancestors are enabled, otherwise the function simply returns the +property of the individual gadget. + +See Also: #EnableGadget and #DisableGadget. +EndRem +Function GadgetDisabled( gadget:TGadget, recursive% = False ) + If recursive Then + While Not (gadget.State()&STATE_DISABLED) + gadget = gadget.parent + If Not gadget Return False + Wend + Return True + EndIf + Return (gadget.State()&STATE_DISABLED) +End Function + +Rem +bbdoc: Set a gadget's size and position. +about: The position and size should be given in pixels, and are relative to the upper-left corner of its parent's client-area. + +The @w and @h parameters set the gadget width or height, unless the gadget concerned is a window with the WINDOW_CLIENTCOORDS flag, +in which case, they represent the client-area dimensions. +EndRem +Function SetGadgetShape( gadget:TGadget,x,y,w,h ) + gadget.SetShape x,y,w,h +End Function + +Rem +bbdoc: Set the layout rules for a gadget when its parent is resized. +about: +#SetGadgetLayout lets you control the automatic layout of a gadget in the event that its parent is resized. + +This will happen either if a window is resized, or if #SetGadgetShape is called on a group gadget. + +Each edge of a @Gadget has an alignment setting that fixes it in place in the following manner: + +[ @Constant | @Description +* EDGE_CENTERED | The edge of the gadget is kept a fixed distance from the center of its parent. +* EDGE_ALIGNED | The edge of the gadget stays a fixed distance from its parent's corresponding edge. +* EDGE_RELATIVE | The edge of the gadget remains a proportional distance from both of its parent's edges. +] + +The default behaviour may vary between platforms, so it is highly recommended that you set this for gadgets on resizable windows. +EndRem +Function SetGadgetLayout( gadget:TGadget,Left,Right,Top,Bottom ) + gadget.SetLayout Left,Right,Top,Bottom +End Function + +Rem +bbdoc: Sets whether a standard MaxGUI gadget emits events from the keyboard or mouse. +about: This functions attempts to provide similar functionality for all gadgets to that of @Panels created with the PANEL_ACTIVE flag. + +The @flags parameter can be any combination of the following: + +SENSITIZE_MOUSE: The gadget will emit the following events: + +[ @{Event ID} | @Description +* EVENT_MOUSEDOWN | Mouse button pressed. Event data contains mouse button code. +* EVENT_MOUSEUP | Mouse button released. Event data contains mouse button code. +* EVENT_MOUSEMOVE | Mouse moved. Event x and y contain mouse coordinates. +* EVENT_MOUSEWHEEL | Mouse wheel spun. Event data contains delta clicks. +* EVENT_MOUSEENTER | Mouse entered gadget area. +* EVENT_MOUSELEAVE | Mouse left gadget area. +] + +SENSITIZE_KEYS: The gadget will emit the following events: + +[ @{Event ID} | @Description +* EVENT_KEYDOWN | Key pressed. Event data contains keycode. +* EVENT_KEYUP | Key released. Event data contains keycode. +* EVENT_KEYREPEAT | Key is being held down. Event data contains keycode. +] + +SENSITIZE_ALL: Exactly the same as combining SENSITIZE_MOUSE and SENSITIZE_KEYS. + +Gadgets that have been disabled should not emit key events, although they may still emit mouse events. + +Not all gadgets will be able to emit all of the events, particularly those that don't receive typical focus +such as labels or htmlviews, but even this may differ depending on the platform. + +%{ @{Warning:} This is a powerful new function that possibly involves hooking into the system's message queue +to ask for mouse/key events before they are processed even by the OS's GUI library. As such, using this function +on certain controls may cause them to be behave differently. In addition, care should be taken when using +this function to avoid infinite loops, for example repositioning gadgets in an event hook that processes the +message as it is received. + +It is therefore recommended that this function is only used by advanced MaxGUI users.} + +See Also: #GadgetSensitivity +EndRem +Function SetGadgetSensitivity( gadget:TGadget, flags ) + Return gadget.SetSensitivity( flags ) +End Function + +Rem +bbdoc: Returns flags specifying whether a gadget emits events from the keyboard or mouse. +about: The function will return a combination of the following flags: + +[ +* SENSITIZE_MOUSE: The gadget will emit mouse events. +* SENSITIZE_KEYS: The gadget will emit keyboard events. +] + +See #SetGadgetSensitivity for more information. +EndRem +Function GadgetSensitivity( gadget:TGadget ) + Return gadget.GetSensitivity() +End Function + + +Rem +bbdoc: Stores a pointer to a related object, that can later be retrieved using #GadgetExtra. +about: +This function has many uses - you may want to store a custom type instance to the treeview node that +represents it, or you may want to store a hidden string value that represents a gadget's action. + +However, it is important to note that this function will result in a pointer being stored to that object +which will only be released when a new object or #Null is passed to this function, or when the gadget is freed +using #FreeGadget. +End Rem +Function SetGadgetExtra( gadget:TGadget, extra:Object ) + gadget.extra = extra +End Function + +Rem +bbdoc: Retrieves the object instance previously stored using #SetGadgetExtra. +End Rem +Function GadgetExtra:Object( gadget:TGadget ) + Return gadget.extra +End Function + +Rem +bbdoc: Request focus for a gadget. +about: See Also: #ActiveGadget() +EndRem +Function ActivateGadget( gadget:TGadget ) + gadget.Activate ACTIVATE_FOCUS +End Function + +Rem +bbdoc: Return the currently active gadget. +returns: The gadget that currently has the keyboard focus. Returns #Null if no MaxGUI gadget has focus. +about: See Also: #ActivateGadget. +EndRem +Function ActiveGadget:TGadget() + Return maxgui_driver.ActiveGadget() +End Function + +Rem +bbdoc: Perform a cut operation on a gadget. +about: This is most commonly used on @TextAreas to cut text that is currently selected. +EndRem +Function GadgetCut( gadget:TGadget ) + gadget.Activate ACTIVATE_CUT +End Function + +Rem +bbdoc: Perform a copy operation on a gadget. +about: This is most commonly used on @TextAreas to copy text that is currently selected. +EndRem +Function GadgetCopy( gadget:TGadget ) + gadget.Activate ACTIVATE_COPY +End Function + +Rem +bbdoc: Perform a paste operation on a gadget. +about: This is most commonly used on @TextAreas to paste text into the gadget from the clipboard. +EndRem +Function GadgetPaste( gadget:TGadget ) + gadget.Activate ACTIVATE_PASTE +End Function + +Rem +bbdoc: Perform a print operation on a gadget. +about: This function is currently only supported on @TextAreas and @HTMLViews. +EndRem +Function GadgetPrint( gadget:TGadget ) + gadget.Activate ACTIVATE_PRINT +End Function + +Rem +bbdoc: Redraws a gadget. +about: +The RedrawGadget command requests that the gadget should be redrawn by the underlying +Operating System but is not necessarily guaranteed to happen immediately. + +In the case of a @Canvas gadget an EVENT_GADGETPAINT event is emitted +when the Operating System begins the actual redraw. The following example +illustrates how to manage this feature: +EndRem +Function RedrawGadget( gadget:TGadget ) + gadget.Activate ACTIVATE_REDRAW +End Function + +Rem +bbdoc: Set a gadget's pixmap. +about: This is a more generic form of old backwards-compatible #SetPanelPixmap function which now allows icons +to be set for other gadgets as well as just backgrounds for panels. + +For setting background pixmaps on panels, @flags should still be one of the following: + +[ @Flag | @Description +* PANELPIXMAP_TILE | The panel is filled with repeating tiles. +* PANELPIXMAP_CENTER | The pixmap is positioned at the center of the panel. +* PANELPIXMAP_FIT | The pixmap is scaled proportionally to best fit the panel size. +* PANELPIXMAP_FIT2 | A variant of PANELPIXMAP_FIT where clipping can occur to achieve a better fit. +* PANELPIXMAP_STRETCH | The pixmap is stretched to fit the entire panel. +] + +Alternatively, to set a push-button or menu's icon, use the following constants: + +[ @Flag | @Description +* GADGETPIXMAP_ICON | Places an icon-sized pixmap onto a push-button/menu. +* GADGETPIXMAP_NOTEXT | Removes text on buttons when used in conjunction with GADGETPIXMAP_ICON. +] + +Each platform allows slightly different maximum icon sizes for their menus. Therefore, the recommended +size for menu icons is 12x12 pixels which appears to work well on all supported platforms. + +Note: At present, OK buttons do not support icons as a cross-platform solution is unavailable. Icons +are also not supported for radio buttons or checkbox style buttons. + +Passing #Null as the value for the @pixmap parameter will remove the pixmap from the gadget. +EndRem +Function SetGadgetPixmap( gadget:TGadget, pixmap:TPixmap, flags% = GADGETPIXMAP_ICON ) + Return gadget.SetPixmap( pixmap, flags ) +End Function + +Rem +bbdoc: Set the transparency of a gadget. +about: Alpha should be in the range 0.0 (invisible) to 1.0 (solid). Very few gadgets support this functionality, +but some Mac OS X gadgets do, in addition to @Windows when running Windows XP+. In certain circumstances, window +transparency may be disabled (for example, when a canvas is added to a window) to prevent redraw issues on some +platforms. + +Using the function on windows with @Canvases on them may cause undesired effects, particularly on Windows 2000/XP +because of conflicts between the software based window manager and the hardware accelerated graphics contexts. +EndRem +Function SetGadgetAlpha( gadget:TGadget,alpha# ) + gadget.SetAlpha(alpha) +End Function + +Rem +bbdoc: Sets a gadget's text. +about: For the @Label, @Button, @TextField, @ComboBox, @TextArea and Group @Panel gadgets, the contents +of the gadget are replaced with the new @text$. + +For a @Window gadget, #SetGadgetText changes the title. For @{Window}s with a status bar, #SetStatusText +should be used to independently set the status bar text. + +This command will automatically delocalize the gadget - to set localized gadget text, see #LocalizeGadget. +EndRem +Function SetGadgetText( gadget:TGadget,Text$ ) + maxgui_driver.DelocalizeGadget( gadget ) + gadget.SetText( Text ) +End Function + +Rem +bbdoc: Returns a gadget's text. +about: For the @Label, @Button, @TextField, @ComboBox, @TextArea and Group @Panel gadgets, the contents +of the gadget are returned with the new gadget's text. + +For a @Window gadget, #GadgetText returns the title of the @Window. +EndRem +Function GadgetText$( gadget:TGadget ) + Return gadget.GetText() +End Function + +Rem +bbdoc: Set a gadget's tooltip. +about: Sets the tooltip for a %{non-item based} positionable MaxGUI gadget. This function will have no effect on the following gadget types: + +[ +* Windows +* Menus +* Tree-view nodes +* List-boxes +* Toolbars +* Tabbers +* Desktops +] + +This command will automatically delocalize the gadget - to set a localized gadget tooltip, see #LocalizeGadget. + +See Also: #GadgetTooltip() +EndRem +Function SetGadgetToolTip( gadget:TGadget, tip$ ) + maxgui_driver.DelocalizeGadget( gadget ) + gadget.SetTooltip( tip ) +End Function + +Rem +bbdoc: Returns the gadget tooltip previously set with #SetGadgetTooltip. +about: Returns the tooltip for a %{non-item based} positionable MaxGUI gadget. As such, this function will have no effect on the following gadget types: + +[ +* Windows +* Menus +* Tree-view nodes +* List-boxes +* Toolbars +* Tabbers +* Desktops +] + +See Also: #SetGadgetTooltip() +EndRem +Function GadgetTooltip$( gadget:TGadget ) + Return gadget.GetTooltip() +End Function + +Rem +bbdoc: Set a gadget's font. +about: See #LoadGuiFont and #RequestFont for creating a @TGuiFont. +EndRem +Function SetGadgetFont( gadget:TGadget,font:TGuiFont ) + gadget.SetFont( font ) +End Function + +Rem +bbdoc: Set a gadget's foreground color. +about: The @{r}ed, @{g}reen and @{b}lue components should be in the range 0 to 255. +See Also: #SetGadgetColor() +EndRem +Function SetGadgetTextColor( gadget:TGadget,r,g,b ) + gadget.SetTextColor( r,g,b ) +End Function + +Rem +bbdoc: Set a gadget's background color. +about: The @{r}ed, @{g}reen and @{b}lue components should be in the range 0 to 255. +This command is not supported for all Gadget types on all platforms. +See Also: #SetGadgetTextColor() #SetGadgetAlpha #RemoveGadgetColor +EndRem +Function SetGadgetColor( gadget:TGadget,r,g,b,bg=True ) + If bg + gadget.SetColor r,g,b + Else + gadget.SetTextColor( r,g,b ) + EndIf +End Function + +Rem +bbdoc: Removes a gadget's background color. +about: Restores a gadget to it's default color. +See Also: #SetGadgetColor() +EndRem +Function RemoveGadgetColor( gadget:TGadget ) + gadget.RemoveColor +End Function + + +Rem +bbdoc: Set the hot-key combination for a gadget. +End Rem +Function SetGadgetHotKey( gadget:TGadget,hotkey,modifier ) + gadget.SetHotKey hotkey,modifier +End Function + +Rem +bbdoc: Attaches an event filter function to a MaxGUI gadget. +about: +The filter function supplied is called by the gadget with a #TEvent +and optional user context object. If the function returns zero the event +is filtered and not processed further by the system whereas a non zero +return indicates event processing should proceed as normal. + +The TextArea/TextField events currently supported: + +[ @{Event ID} | @Description +* EVENT_KEYDOWN | Key pressed. Event data contains keycode. +* EVENT_KEYCHAR | Key character. Event data contains unicode value. +] + +Currently only the EVENT_KEYDOWN, EVENT_KEYCHAR events produced by +TextArea and TextField gadgets can be filtered with the SetGadgetFilter +command. +End Rem +Function SetGadgetFilter( gadget:TGadget,callback(event:TEvent,context:Object),context:Object=Null ) + gadget.SetFilter callback,context +End Function + + +' localization (constants declared in maxgui.mod/driver.bmx) + +Rem +bbdoc: Localize a gadget using the supplied localization strings. +about: The function will use the supplied localization strings to localize a gadget and its text. The gadget +will also be marked so that changing the language will update the text. Calling #DelocalizeGadget or +#SetGadgetText will disable this behaviour. + +Localization strings and their structure are described in #LocalizeString function documentation. + +Item-based gadgets should mark any items, whose strings are also wanted to be localized, with the +GADGETITEM_LOCALIZED flag. See the @flags parameter of the #AddGadgetItem / #InsertGadgetItem +/ #ModifyGadgetItem calls. + +See Also: #GadgetLocalized, #SetLocalizationMode and #SetLocalizationLanguage. +EndRem +Function LocalizeGadget( gadget:TGadget, localizationtext$, localizationtooltip$ = "" ) + maxgui_driver.SetGadgetLocalization( gadget, localizationtext, localizationtooltip ) +EndFunction + +Rem +bbdoc: Determines whether a gadget is registered as being 'localized'. +about: See #LocalizeGadget and #SetLocalizationMode for more information. +EndRem +Function GadgetLocalized:Int( gadget:TGadget ) + Return maxgui_driver.GadgetLocalized(gadget) +EndFunction + +Rem +bbdoc: Delocalizes a gadget so that it's no longer updated if the localization language/mode changes. +about: See Also: #LocalizeGadget, #SetLocalizationLanguage and #SetLocalizationMode. +EndRem +Function DelocalizeGadget( gadget:TGadget ) + maxgui_driver.DelocalizeGadget( gadget ) +EndFunction + + +' menus + +Rem +bbdoc: Creates a new menu item. +about: Menu gadgets should be attached to either a #WindowMenu, other Menu gadgets +or used with the #PopupWindowMenu command. The tag field should be a unique identifier +that will be present in the #EventData field of EVENT_MENUACTION events. + +Keyboard shortcuts can be associated with a Menu by using the optional hotKey and +modifier parameters. + +Please refer to the #{key codes} module for valid key and modifier codes. +The MODIFIER_COMMAND value should be used instead of MODIFIER_CONTROL +with Menu hotkeys for best crossplatform compatability. + +Menus now also support icons on most platforms through the use of #SetGadgetPixmap. + +See Also: #FreeMenu, #SetMenuText, #CheckMenu, #UncheckMenu, #EnableMenu, #DisableMenu, +#MenuText, #MenuChecked, #MenuEnabled and #SetGadgetPixmap. +EndRem +Function CreateMenu:TGadget( Text$,tag,parent:TGadget,hotkey=0,modifier=0 ) + Local gadget:TGadget=maxgui_driver.CreateGadget(GADGET_MENUITEM,Text,0,0,0,0,GetGroup(parent),tag) + If gadget And hotKey SetGadgetHotKey gadget,hotKey,modifier + Return gadget +End Function + +Rem +bbdoc: Remove a menu. +about: This function has been superseded by #FreeGadget, but is available for backwards compatability. +EndRem +Function FreeMenu( menu:TGadget ) + menu.CleanUp() +End Function + +Rem +bbdoc: Modify a menu's text. +about: This function has been superseded by #SetGadgetText, but is available for backwards compatability. +EndRem +Function SetMenuText( menu:TGadget,Text$ ) + SetGadgetText( menu, Text ) +End Function + +Rem +bbdoc: Set a menu's checked state. +about: #UpdateWindowMenu should be called where appropriate after changing a menu's state for the changes +to become visible. +EndRem +Function CheckMenu( menu:TGadget ) + menu.SetSelected True +End Function + +Rem +bbdoc: Clear a menu's checked state. +about: #UpdateWindowMenu should be called where appropriate after changing a menu's state for the changes +to become visible. +EndRem +Function UncheckMenu( menu:TGadget ) + menu.SetSelected False +End Function + +Rem +bbdoc: Enable a menu for selection. +about: #UpdateWindowMenu should be called where appropriate after changing a menu's status for the changes +to become visible. +EndRem +Function EnableMenu( menu:TGadget ) + menu.SetEnabled True +End Function + +Rem +bbdoc: Disable a menu so it cannot be selected. +about: #UpdateWindowMenu should be called where appropriate after changing a menu's status for the changes +to become visible. +EndRem +Function DisableMenu( menu:TGadget ) + menu.SetEnabled False +End Function + +Rem +bbdoc: Return a menu's text. +about: This function has been superseded by #GadgetText, but is available for backwards compatability. +EndRem +Function MenuText$( menu:TGadget ) + Return menu.GetText() +End Function + +Rem +bbdoc: Return a menu's checked state. +EndRem +Function MenuChecked( menu:TGadget ) + Return (menu.State()&STATE_SELECTED)<>0 +End Function + +Rem +bbdoc: Return a menu's enabled state. +EndRem +Function MenuEnabled( menu:TGadget ) + Return Not (menu.State()&STATE_DISABLED) +End Function + +' desktop + +Rem +bbdoc: Return a gadget representing the system's desktop. +about: This is particularly useful for finding the resolution of the desktop using #GadgetWidth / #ClientWidth or #GadgetHeight / #ClientHeight. +EndRem +Function Desktop:TGadget() + Return maxgui_driver.CreateGadget(GADGET_DESKTOP,"",0,0,0,0,Null,0) +End Function + +' window + +Rem +bbdoc: Create a Window gadget. +about: +A Window is the primary gadget of MaxGUI. Windows should be used as the primary +group gadgets in MaxGUI applications to contain the gadgets that make up the program's +user interface. + +The following style flags are supported when creating a Window. Any of the +style flags can be combined using the bitwise operator '|'. + +[ @Style | @Meaning +* WINDOW_TITLEBAR | The Window has a titlebar that displays the @titletext$. +* WINDOW_RESIZABLE | The Window can be resized by the user. +* WINDOW_MENU | The Window has an associated window menu (retrieve menu handle using #WindowMenu). +* WINDOW_STATUS | The Window has a statusbar. +* WINDOW_TOOL | A window style commonly used for toolbars and other tool windows. +* WINDOW_CLIENTCOORDS | The dimensions specified relate to the client area as opposed to the window frame. +* WINDOW_CENTER | The x and y parameters are ignored, and the Window is positioned either in the middle of the screen or the middle of the parent gadget. +* WINDOW_HIDDEN | The Window is created in a hidden state and can be revealed later using #ShowGadget. +* WINDOW_ACCEPTFILES | Enable file drag and drop operations (emits the EVENT_WINDOWACCEPT events). +] + +Note: For cross-platform projects, it is highly recommended that the WINDOW_CLIENTCOORDS style is used to maintain +similar layouts with different operating systems and window managers. + +The default window style (WINDOW_DEFAULT) is equivalent to WINDOW_TITLEBAR | WINDOW_RESIZABLE | WINDOW_MENU | WINDOW_STATUS. + +A Window emits the following events: + +[ @{Event ID} | @Description +* EVENT_WINDOWMOVE | Window has been moved. +* EVENT_WINDOWSIZE | Window has been resized. +* EVENT_WINDOWCLOSE | Window close icon clicked. +* EVENT_WINDOWACTIVATE | Window has been activated. +* EVENT_WINDOWACCEPT | A file was dropped onto a Window with the WINDOW_ACCEPTFILES style. The event @Extra object holds the filepath. +] + +See Also: #WindowMenu, #UpdateWindowMenu, #PopupWindowMenu, #ActivateWindow, #SetStatusText, #WindowStatusText, +#SetMinWindowSize, #SetMaxWindowSize, #MinimizeWindow, #MaximizeWindow, #RestoreWindow, #WindowMinimized +and #WindowMaximized. +EndRem +Function CreateWindow:TGadget( titletext$,x,y,w,h,group:TGadget=Null,style=WINDOW_DEFAULT ) + If (style&WINDOW_CENTER) Then + If group Then + x = GadgetX(group) + (GadgetWidth(group)-w)/2 + y = GadgetY(group) + (GadgetHeight(group)-h)/2 + Else + x = (Min(GadgetWidth(Desktop()), ClientWidth(Desktop()))-w)/2 + y = (Min(GadgetHeight(Desktop()), ClientHeight(Desktop()))-h)/2 + EndIf + EndIf + Return maxgui_driver.CreateGadget(GADGET_WINDOW,titletext,x,y,w,h,GetGroup(group),style) +End Function + +Rem +bbdoc: Returns a window's main-menu handle. +about: Required when a root menu is to be added to a window using #CreateMenu. This function +should %not be used for sub-menus - the sub-menu should be parented directly to its parent menu. + +It should also be mentioned that this function isn't required when creating popup menus - #Null should +instead be passed as the parent of the root menu. + +To avoid any unexpected behavior, make sure that the window specified was created with the WINDOW_MENU +style flag. + +See Also: #CreateMenu and #UpdateWindowMenu +EndRem +Function WindowMenu:TGadget( window:TGadget ) + Return window.GetMenu() +End Function + +Rem +bbdoc: Update a window's menu hierachy. +about: Required after changing a window's menu properties/structure for the changes to become visible. + +To avoid any unexpected behavior, make sure that the window specified was created with the WINDOW_MENU +style flag. + +See Also: #WindowMenu and #CreateMenu +EndRem +Function UpdateWindowMenu( window:TGadget ) + window.UpdateMenu() +End Function + +Rem +bbdoc: Display a popup menu. +about: A popup context-menu is displayed on the screen at the user's current mouse position. +See Also: #CreateMenu +EndRem +Function PopupWindowMenu( window:TGadget,menu:TGadget,extra:Object=Null ) + window.PopupMenu(menu,extra) +End Function + +Rem +bbdoc: Activate a window gadget. +about: This function has been superseded by #ActivateGadget, but is available for backwards compatability. +EndRem +Function ActivateWindow( window:TGadget ) + window.Activate ACTIVATE_FOCUS +End Function + +Rem +bbdoc: Retrieve a window's status-bar text. +about: Can only be used with windows created with the WINDOW_STATUS flag (see #CreateWindow). Tab characters +delimit between the three alignments of text. See #SetStatusText for more information. +EndRem +Function WindowStatusText$( window:TGadget ) + Return window.GetStatusText() +End Function + +Rem +bbdoc: Set a window's status bar text. +about: Can only be used with windows created with the WINDOW_STATUS flag (see #CreateWindow). Use tab characters +to delimit between the three alignments of text. For example: + +{{ +SetStatusText( window, "Left Aligned Only" ) +SetStatusText( window, "Left Aligned~tCenter Aligned~tRight Aligned" ) +SetStatusText( window, "~tCenter Aligned Only" ) +SetStatusText( window, "~t~tRight Aligned Only" ) +}} + +See Also: #WindowStatusText +EndRem +Function SetStatusText( window:TGadget,Text$ ) + window.SetStatusText Text +End Function + +Rem +bbdoc: Set a window's minimum size. +about: Only useful for resizable windows (i.e. windows created with the WINDOW_RESIZABLE flag, see #CreateWindow). +EndRem +Function SetMinWindowSize( window:TGadget,w,h ) + window.SetMinimumSize( w,h ) +End Function + +Rem +bbdoc: Set a window's maximum size. +about: Only useful for resizable windows (i.e. windows created with the WINDOW_RESIZABLE flag, see #CreateWindow). + +Calling this function will disable the Maximize button window hint on Windows, and will limit the window zoom size on Mac OS X. +EndRem +Function SetMaxWindowSize( window:TGadget,w,h ) + window.SetMaximumSize( w,h ) +End Function + +Rem +bbdoc: Minimize a window. +about: A minimized window can be restored by the user to its previous state, typically by clicking on the icon representation +of the window in the taskbar or dock. The same effect can be obtained programatically by calling #RestoreWindow. + +See Also: #WindowMinimized. +EndRem +Function MinimizeWindow( window:TGadget ) + window.Activate ACTIVATE_MINIMIZE +End Function + +Rem +bbdoc: Maximize a window. +about: +Maximizing a window makes the window visible and sizes it to fill the current desktop. #RestoreWindow can be used to +programatically restore a window to its previous unmaximized state, although the window will still remain unhidden. + +See Also: #WindowMaximized. +EndRem +Function MaximizeWindow( window:TGadget ) + window.Activate ACTIVATE_MAXIMIZE +End Function + +Rem +bbdoc: Restore a window from a minimized or maximized state. +about: See Also: #MinimizeWindow and #MaximizeWindow. +EndRem +Function RestoreWindow( window:TGadget ) + window.Activate ACTIVATE_RESTORE +End Function + +Rem +bbdoc: Detect if a window is minimized. +returns: #True if the window is currently minimized, #False if not. +EndRem +Function WindowMinimized( window:TGadget ) + Return (window.State()&STATE_MINIMIZED)<>0 +End Function + +Rem +bbdoc: Detect if a window is maximized. +returns: #True if the window is currently maximized, #False if not. +about: A maximized window fills the entire desktop. A window may +be maximized with the #MaximizeWindow command or by the user if +#CreateWindow was called with the WINDOW_RESIZABLE flag. +EndRem +Function WindowMaximized( window:TGadget ) + Return (window.State()&STATE_MAXIMIZED)<>0 +End Function + +' button + +Rem +bbdoc: Create a Button gadget. +about: +A Button generates an EVENT_GADGETACTION #TEvent whenever it is pushed. + +[ @Style | @Meaning +* BUTTON_PUSH | Standard push button. +* BUTTON_CHECKBOX | A check box button that displays a tick when its state is #True. +* BUTTON_RADIO | A radio button is accompanied by a small circular indicator, filled when its state is #True. +* BUTTON_OK | Standard push button that is also activated when the user presses the RETURN key. +* BUTTON_CANCEL | Standard push button that is also activated when the user presses the ESCAPE key. +] + +On certain platforms, the BUTTON_PUSH flag can be combined with either BUTTON_CHECKBOX or BUTTON_RADIO to obtain +a button looking similar to standard push-buttons, but mimicking the behaviour of the checkbox or radio button. + +See Also: #SetGadgetText, #SetButtonState, #ButtonState and #SetGadgetPixmap. +EndRem +Function CreateButton:TGadget(label$,x,y,w,h,group:TGadget,style=BUTTON_PUSH) + Return maxgui_driver.CreateGadget(GADGET_BUTTON,label,x,y,w,h,GetGroup(group),style) +End Function + +Rem +bbdoc: Set a button's state. +about: +Buttons created with the BUTTON_CHECKBOX and BUTTON_RADIO styles are able to show a selected state. +In addition, the BUTTON_CHECKBOX style may also be able to distinguish an indeterminate state from that +of a checked state through the use of the CHECK_INDETERMINATE (-1) constant, depending on the platform. + +See Also: #CreateButton, #SetGadgetText, #ButtonState and #SetGadgetPixmap. +EndRem +Function SetButtonState( button:TGadget,checked ) + button.SetSelected checked +End Function + +Rem +bbdoc: Retrieve a button's state. +about: +Returns a non-zero value if a checkbox or radio button is selected or false if it isn't. +On certain platforms, if a checkbox is set using #SetButtonState to have an indeterminant +state (CHECK_INDETERMINATE), then this function will return CHECK_INDETERMINATE too. +See Also: #CreateButton, #SetGadgetText, #SetButtonState and #SetGadgetPixmap. +EndRem +Function ButtonState( button:TGadget ) + Local tmpResult% = button.State()&STATE_INDETERMINATE + If (tmpResult&~STATE_SELECTED) Then Return -1 Else Return (tmpResult <> 0) +End Function + +' panel + +Rem +bbdoc: Create a Panel gadget. +about: +A Panel is a general purpose gadget that can be used to group other gadgets. + +Background colours and images can be set using #SetGadgetColor and #SetPanelPixmap. + +A panel can be created with any one of the following %optional styles: + +[ @Style | @Meaning +* PANEL_SUNKEN | Panel is drawn with a sunken border (or just a simple border on OS X). +* PANEL_RAISED | Panel is drawn with a raised border (or just a simple border on OS X). +* PANEL_GROUP | Panel is drawn with a titled etched border. +] + +The PANEL_ACTIVE flag can be combined with any other style flags, or specified on its own, +to generate mouse and key events (equivalent to calling #SetGadgetSensitivity immediately +after creation): + +[ @{Event ID} | @Description +* EVENT_MOUSEDOWN | Mouse button pressed. Event data contains mouse button code. +* EVENT_MOUSEUP | Mouse button released. Event data contains mouse button code. +* EVENT_MOUSEMOVE | Mouse moved. Event x and y contain mouse coordinates. +* EVENT_MOUSEWHEEL | Mouse wheel spun. Event data contains delta clicks. +* EVENT_MOUSEENTER | Mouse entered gadget area. +* EVENT_MOUSELEAVE | Mouse left gadget area. +* EVENT_KEYDOWN | Key pressed. Event data contains keycode. +* EVENT_KEYUP | Key released. Event data contains keycode. +* EVENT_KEYCHAR | Key character. Event data contains unicode value. +] + +%{Note: The PANEL_SUNKEN / PANEL_RAISED style flags cannot be used with PANEL_GROUP.} + +See Also: #SetPanelColor and #SetPanelPixmap. +EndRem +Function CreatePanel:TGadget(x,y,w,h,group:TGadget,style=0,title$="") + Return maxgui_driver.CreateGadget(GADGET_PANEL,title,x,y,w,h,GetGroup(group),style) +End Function + +Rem +bbdoc: Set the color of a Panel. +about: This function has been superseded by #SetGadgetColor, but is available for backwards compatability. +See Also: #CreatePanel and #SetPanelPixmap +EndRem +Function SetPanelColor( panel:TGadget,r,g,b ) + panel.SetColor(r,g,b) +End Function + +Rem +bbdoc: Set panel's background image to a pixmap. +about: This function has been superseded by #SetGadgetPixmap, but is available for backwards compatability. + +[ @Flags | @Description +* PANELPIXMAP_TILE | The panel is filled with repeating tiles. +* PANELPIXMAP_CENTER | The pixmap is positioned at the center of the panel. +* PANELPIXMAP_FIT | The pixmap is scaled to best fit the panel size. +* PANELPIXMAP_FIT2 | A variant of PANELPIXMAP_FIT where clipping can occur to achieve a better fit. +* PANELPIXMAP_STRETCH | The pixmap is stretched to fit the entire panel. +] + +The function can be passed 'Null' as the parameter for @pixmap, in which case the pixmap should be removed. + +See Also: #CreatePanel and #SetPanelColor +EndRem +Function SetPanelPixmap( panel:TGadget,pixmap:TPixmap,flags=PANELPIXMAP_TILE) + Return SetGadgetPixmap( panel,pixmap,flags) +End Function + +' textfield + +Rem +bbdoc: Create a TextField gadget. +about: A TextField is a single line text entry gadget and currently has only one style flag: + +[ @Flags | @Description +* TEXTFIELD_PASSWORD | Masks characters being typed as a string as asterisks. +] + +Irrespective of the flag used, the TextField gadget will emit the following event(s): + +[ @{Event ID} | @Description +* EVENT_GADGETACTION | The user has edited the text in the TextField. +] + +It is also possible to validate any typed input before it reaches the TextArea using +the #SetGadgetFilter command. + +See Also: #GadgetText, #SetGadgetText, #SetGadgetFilter. +EndRem +Function CreateTextField:TGadget(x,y,w,h,group:TGadget,style=0) + Return maxgui_driver.CreateGadget(GADGET_TEXTFIELD,"",x,y,w,h,GetGroup(group),style) +End Function + +Rem +bbdoc: Get the current text in a TextField gadget. +about: This function has been superseded by #GadgetText, but is available for backwards compatability. +See Also: #CreateTextField and #SetGadgetText +EndRem +Function TextFieldText$( textfield:TGadget ) + Return textfield.GetText() +End Function + +' textarea + +Rem +bbdoc: Create a TextArea gadget. +about: +A TextArea gadget is a multiline text editor with commands that allow control +over the contents, style and selection of the text it contains. + +A TextArea gadget may have the following optional styles: + +[ @Style | @Meaning +* TEXTAREA_WORDWRAP | Long lines of text 'wrap round' onto the next lines. +* TEXTAREA_READONLY | The text cannot be edited by the user. +] + +A TextArea gadget can generate the following events: + +[ @{Event ID} | @Description +* EVENT_GADGETACTION | The user has modified the text in a TextArea. +* EVENT_GADGETSELECT | The text-cursor has moved or a selection of text is made by the user. +* EVENT_GADGETMENU | The user has right-clicked somewhere in the TextArea. +] + +It is also possible to validate any typed input before it reaches the TextArea using +the #SetGadgetFilter command. + +See Also: #SetTextAreaText, #AddTextAreaText, #TextAreaText, #TextAreaLen, #LockTextArea, +#UnlockTextArea, #SetTextAreaTabs, #SetGadgetFont, #SetGadgetColor, #TextAreaCursor, +#TextAreaSelLen, #FormatTextAreaText, #SelectTextAreaText, #TextAreaChar, #TextAreaLine, +#TextAreaCharX and #TextAreaCharY. +EndRem +Function CreateTextArea:TGadget(x,y,w,h,group:TGadget,style=0) + Return maxgui_driver.CreateGadget(GADGET_TEXTAREA,"",x,y,w,h,GetGroup(group),style) +End Function + +Rem +bbdoc: Set the contents of a TextArea gadget. +about: +See Also: #CreateTextArea, #AddTextAreaText and #SetGadgetText +EndRem +Function SetTextAreaText( textarea:TGadget,Text$,pos=0,length=TEXTAREA_ALL,units=TEXTAREA_CHARS ) + textarea.ReplaceText(pos,length,Text,units) +End Function + +Rem +bbdoc: Append text to the contents of a TextArea gadget. +about: +See Also: #CreateTextArea, #SetTextAreaText and #SetGadgetText +EndRem +Function AddTextAreaText( textarea:TGadget,Text$ ) + textarea.AddText(Text) +End Function + +Rem +bbdoc: Get the contents of a TextArea gadget. +about: +See Also: #CreateTextArea, #AddTextAreaText, #SetTextAreaText and #SetGadgetText +EndRem +Function TextAreaText$( textarea:TGadget,pos=0,length=TEXTAREA_ALL,units=TEXTAREA_CHARS ) + Return textarea.AreaText(pos,length,units) +End Function + +Rem +bbdoc: Get the number of characters in a TextArea gadget. +about: +See Also: #CreateTextArea +EndRem +Function TextAreaLen( textarea:TGadget,units=TEXTAREA_CHARS ) + Return textarea.AreaLen(units) +End Function + +Rem +bbdoc: Lock a TextArea gadget for improved performance when formatting. +about: +See Also: #UnlockTextArea and #CreateTextArea +EndRem +Function LockTextArea( textarea:TGadget ) + textarea.locktext +End Function + +Rem +bbdoc: Unlock a previously locked TextArea gadget. +about: +See Also: #LockTextArea and #CreateTextArea +EndRem +Function UnlockTextArea( textarea:TGadget ) + textarea.unlocktext +End Function + +Rem +bbdoc: Set the tab stops of a TextArea gadget measured in pixels. +about: +See Also: #CreateTextArea #SetIndents +EndRem +Function SetTextAreaTabs( textarea:TGadget,tabwidth ) + textarea.SetTabs tabwidth +End Function + +Rem +bbdoc: Set left margin of a TextArea measured in pixels. +about: +See Also: #CreateTextArea and #SetTextAreaTabs +EndRem +Function SetMargins( textarea:TGadget,leftmargin ) + textarea.SetMargins leftmargin +End Function + + +Rem +bbdoc: Set the font of a TextArea gadget. +about: This function has been superseded by #SetGadgetFont, but is available for backwards compatability. +See Also: #CreateTextArea +EndRem +Function SetTextAreaFont( textarea:TGadget,font:TGuiFont ) + textarea.SetFont font +End Function + +Rem +bbdoc: Set the background or foreground colors of a TextArea gadget. +about: This function has been superseded by #SetGadgetColor, but is available for backwards compatability. +See Also: #CreateTextArea +EndRem +Function SetTextAreaColor( textarea:TGadget,r,g,b,bg=False ) + If bg + textarea.SetColor r,g,b + Else + textarea.SetTextColor r,g,b + EndIf +End Function + +Rem +bbdoc: Find the position of the cursor in a TextArea gadget. +about: +Use the default TEXTAREA_CHARS units argument to find out which character +(column) in the line the cursor is on and use TEXTAREA_LINES to find out +which line (row) the cursor is on. + +See Also: #TextAreaSelLen and #CreateTextArea +EndRem +Function TextAreaCursor( textarea:TGadget,units=TEXTAREA_CHARS ) + Return textarea.GetCursorPos(units) +End Function + +Rem +bbdoc: Find the size of the selected text in a TextArea gadget. +about: +The TEXTAREA_CHARS option returns the number of characters currently +highlighted by the user where as TEXTAREA_LINES will specify the +function returns the number of lines selected. + +See Also: #TextAreaCursor and #CreateTextArea +EndRem +Function TextAreaSelLen( textarea:TGadget,units=TEXTAREA_CHARS ) + Return textarea.GetSelectionLength( units ) +End Function + +Rem +bbdoc: Format the color and style of some text in a TextArea gadget. +about: +The @r, @g and @b parameters represent the @{r}ed, @{g}reen and @{b}lue components (0..255) +which, when combined, represent the new text color for the the sepecified region +of characters. + +The @flags parameter can be a combination of the following values: + +[ @Constant | @Meaning +* TEXTFORMAT_BOLD | Bold +* TEXTFORMAT_ITALIC | Italic +* TEXTFORMAT_UNDERLINE | Underline +* TEXTFORMAT_STRIKETHROUGH | StrikeThrough +] + +Depending on the value of the units parameter the position and length parameters specify +the character position and number of characters or the starting line and the number +of lines that FormatTextAreaText will modify. + +See Also: #LockTextArea and #CreateTextArea +EndRem +Function FormatTextAreaText( textarea:TGadget,r,g,b,flags,pos=0,length=TEXTAREA_ALL,units=TEXTAREA_CHARS ) + textarea.SetStyle(r,g,b,flags,pos,length,units) +End Function + +Rem +bbdoc: Select a range of text in a TextArea gadget. +about: +Depending on the value of the units the position and length parameters specify +the character position and number of characters or the starting line and the number +of lines that SelextTextAreaText will highlight. + +See Also: #TextAreaCursor, #TextAreaSelLen and #CreateTextArea +EndRem +Function SelectTextAreaText( textarea:TGadget,pos=0,length=TEXTAREA_ALL,units=TEXTAREA_CHARS ) + textarea.SetSelection(pos,length,units) +End Function + +Rem +bbdoc: Find the character position of a given line in a TextArea gadget. +endrem +Function TextAreaChar( textarea:TGadget,Line ) + Return textarea.CharAt(Line) +End Function + +Rem +bbdoc: Find the line of a given character position in a TextArea gadget. +endrem +Function TextAreaLine( textarea:TGadget,index ) + Return textarea.LineAt(index) +End Function + +Rem +bbdoc: Find the x-coordinate of a textarea character position, relative to the upper left corner of the gadget. +about: The returned value may be greater than the width of the gadget (or even negative) if the specified character +index is positioned outside the immediately visible area of a scrollable TextArea. +EndRem +Function TextAreaCharX( textarea:TGadget, char ) + Return textarea.CharX(char) +End Function + +Rem +bbdoc: Find the y-coordinate of a textarea character position, relative to the upper left corner of the gadget. +about: The returned value may be greater than the height of the gadget (or even negative) if the specified character +index is positioned outside the immediately visible area of a scrollable TextArea. +EndRem +Function TextAreaCharY( textarea:TGadget, char ) + Return textarea.CharY(char) +End Function + +' gadget lists + +Rem +bbdoc: Create a ComboBox gadget. +about: +A ComboBox gadget provides a dropdown list of items to the user. + +The ComboBox supports the following styles: + +[ @Style | @Meaning +* COMBOBOX_EDITABLE | Allows the ComboBox to behave similar to a TextField, by allowing typed user input also. +] + +And emits the following events: + +[ @{Event ID} | @Description +* EVENT_GADGETACTION | The selection has been cleared, or the text has changed. +] + +See Also: #AddGadgetItem, #ClearGadgetItems, #ModifyGadgetItem, #SelectGadgetItem, +#RemoveGadgetItem, #SelectedGadgetItem and #SetGadgetIconStrip. +EndRem +Function CreateComboBox:TGadget(x,y,w,h,group:TGadget,style=0) + Return maxgui_driver.CreateGadget(GADGET_COMBOBOX,"",x,y,w,h,GetGroup(group),style) +End Function + +Rem +bbdoc: Create a ListBox gadget. +about: +A ListBox gadget displays a scrollable list of items and generates the following events: + +[ @{Event ID} | @Description +* EVENT_GADGETSELECT | An item has been selected, or the selection has been cleared. +* EVENT_GADGETACTION | An item has been double-clicked. +* EVENT_GADGETMENU | The user has right-clicked somewhere in the listbox. +] + +See Also: #AddGadgetItem, #ClearGadgetItems, #ModifyGadgetItem, #SelectGadgetItem, +#RemoveGadgetItem, #SelectedGadgetItem, #SelectedGadgetItems and #SetGadgetIconStrip. +EndRem +Function CreateListBox:TGadget(x,y,w,h,group:TGadget,style=0) + Return maxgui_driver.CreateGadget(GADGET_LISTBOX,"",x,y,w,h,GetGroup(group),style) +End Function + +Rem +bbdoc: Create a Tabber gadget. +about: +A Tabber gadget shows a list of tabs above a client area, typically used for +handling multiple documents/panels. + +[ @{Event ID} | @Description +* EVENT_GADGETACTION | A new tab has been selected. Event data contains the tab index. +* EVENT_GADGETMENU | A tab has been right-clicked. Event data contains the tab index. +] + +Event extra for both events point to the #GadgetItemExtra object set for the corresponding tab item index in the latest call +to #AddGadgetItem / #InsertGadgetItem or #ModifyGadgetItem. + +It is important to note also that, similar to #SelectedGadgetItem, either event may be emitted with the event +data set to '-1'. This either means that somehow the user has deselected a tab, or that the user +has right-clicked on an area of the tabber which doesn't represent a particular tab item index. As +such, your MaxGUI applications should check the value before proceeding to use it with any of the +standard #GadgetItemText, #GadgetItemExtra etc. commands. + +See Also: #AddGadgetItem, #ClearGadgetItems, #ModifyGadgetItem, #SelectGadgetItem, +#RemoveGadgetItem, #SelectedGadgetItem and #SetGadgetIconStrip. +EndRem +Function CreateTabber:TGadget(x,y,w,h,group:TGadget,style=0) + Return maxgui_driver.CreateGadget(GADGET_TABBER,"",x,y,w,h,GetGroup(group),style) +End Function + +Rem +bbdoc: Remove all items added to a list based gadget. +about: +See Also: #CreateComboBox, #CreateListBox, #CreateToolbar and #CreateTabber +EndRem +Function ClearGadgetItems(gadget:TGadget) + gadget.Clear() +End Function + +Rem +bbdoc: Add an item to a list based gadget. +about: +An item can be added to the ComboBox, ListBox, Tabber and Toolbar list based gadgets. + +Its @text parameter is used as its label. + +The @flags parameter can be a combination of the following values: + +[ @Flag | @Meaning +* GADGETITEM_NORMAL | A plain gadget item. +* GADGETITEM_DEFAULT | The item defaults to a selected state. +* GADGETITEM_TOGGLE | The item alternates between selected states when pressed. +* GADGETITEM_LOCALIZED | The item text and tooltip are localization strings. +] + +The @tip$ parameter attaches an optional tooltip to the item. + +The optional @icon parameter specifies an icon from the gadget's IconStrip (see #SetGadgetIconStrip). + +The @extra parameter is supplied in the EventExtra field of any Event generated by the Item. + +See Also: #InsertGadgetItem, #CreateComboBox, #CreateListBox, #CreateTabber, #CreateToolbar and #SetGadgetIconStrip. +EndRem +Function AddGadgetItem(gadget:TGadget,Text$,flags=0,icon=-1,tip$="",extra:Object=Null) + gadget.InsertItem(gadget.ItemCount(),Text,tip,icon,extra,flags) +End Function + +Rem +bbdoc: Inserts an item in a list based gadget at the specified index. +about: +An item can be inserted in a ComboBox, ListBox, Tabber and Toolbar list based gadgets. + +See #AddGadgetItem for a description of the parameters. + +See Also: #CreateComboBox, #CreateListBox, #CreateTabber and #CreateToolbar +EndRem +Function InsertGadgetItem(gadget:TGadget,index,Text$,flags=0,icon=-1,tip$="",extra:Object=Null) + gadget.InsertItem(index,Text,tip,icon,extra,flags) +End Function + +Rem +bbdoc: Modify the properties of a gadget-item. +about: +See #AddGadgetItem for a description of the parameters. + +See Also: #CreateComboBox, #CreateListBox, #CreateTabber and #CreateToolbar +EndRem +Function ModifyGadgetItem( gadget:TGadget,index,Text$,flags=0,icon=-1,tip$="",extra:Object=Null ) + gadget.SetItem(index,Text,tip,icon,extra,flags) +End Function + +Rem +bbdoc: Remove a gadget-item from a list based gadget. +about: +See Also: #CreateComboBox, #CreateListBox, #CreateTabber and #CreateToolbar +EndRem +Function RemoveGadgetItem( gadget:TGadget,index ) + gadget.RemoveItem index +End Function + +Rem +bbdoc: Enable a particular item in a list based gadget. +about: Typically, this can only be used on toolbars. +See Also: #CreateToolbar +EndRem +Function EnableGadgetItem( gadget:TGadget,index ) + Local state=gadget.ItemState(index)&~STATE_DISABLED + gadget.SetItemState(index,state) +End Function + +Rem +bbdoc: Disable a particular item in a list based gadget. +about: Typically, this can only be used on toolbars. +See Also: #CreateToolbar +EndRem +Function DisableGadgetItem( gadget:TGadget,index ) + Local state=gadget.ItemState(index)|STATE_DISABLED + gadget.SetItemState(index,state) +End Function + +Rem +bbdoc: Select an item in a list based gadget. +about: +See Also: #DeselectGadgetItem, #ToggleGadgetItem, #CreateComboBox, #CreateListBox, #CreateToolbar and #CreateTabber +EndRem +Function SelectGadgetItem(gadget:TGadget,index) + gadget.SelectItem(index,1) +End Function + +Rem +bbdoc: Deselect an item in a list based gadget. +about: +See Also: #SelectGadgetItem, #ToggleGadgetItem, #CreateComboBox, #CreateListBox, #CreateToolbar and #CreateTabber +EndRem +Function DeselectGadgetItem(gadget:TGadget,index) + gadget.SelectItem(index,0) +End Function + +Rem +bbdoc: Invert the selected state of an item in a list based gadget. +about: +See Also: #SelectGadgetItem, #DeselectGadgetItem and #CreateToolbar +EndRem +Function ToggleGadgetItem(gadget:TGadget,index) + gadget.SelectItem(index,2) +End Function + + +Rem +bbdoc: Get the index of the first selected item in a list based gadget. +about: +SelectedGadgetItem will return -1 if the list based gadget has no selected items. + +See Also: #CreateComboBox, #CreateListBox and #CreateTabber +EndRem +Function SelectedGadgetItem(gadget:TGadget) + Return gadget.SelectedItem() +End Function + +Rem +bbdoc: Returns an integer array of the selected item indexes in a list based gadget. +about: +See Also: #CreateComboBox, #CreateListBox and #CreateTabber +EndRem +Function SelectedGadgetItems[](gadget:TGadget) + Return gadget.SelectedItems() +End Function + +Rem +bbdoc: Get the number of items in a list based gadget. +about: +See Also: #CreateComboBox, #CreateListBox, #CreateTabber and #CreateToolbar +EndRem +Function CountGadgetItems( gadget:TGadget ) + Return gadget.ItemCount() +End Function + +Rem +bbdoc: Get the text of a given item in a list based gadget. +about: +See Also: #CreateComboBox, #CreateListBox, #CreateToolbar and #CreateTabber +EndRem +Function GadgetItemText$( gadget:TGadget,index ) + Return gadget.ItemText(index) +End Function + +Rem +bbdoc: Get the tooltip of a given item in a list based gadget. +about: +See Also: #CreateComboBox, #CreateListBox, #CreateToolbar and #CreateTabber +EndRem +Function GadgetItemTooltip$( gadget:TGadget,index ) + Return gadget.ItemTip(index) +End Function + +Rem +bbdoc: Get the icon of a given item in a list based gadget. +about: +See Also: #CreateComboBox, #CreateListBox, #CreateToolbar and #CreateTabber +EndRem +Function GadgetItemIcon( gadget:TGadget,index ) + Return gadget.ItemIcon(index) +End Function + +Rem +bbdoc: Get the extra data of a given item in a list based gadget. +about: +See Also: #CreateComboBox, #CreateListBox, #CreateToolbar and #CreateTabber +EndRem +Function GadgetItemExtra:Object( gadget:TGadget,index ) + Return gadget.ItemExtra(index) +End Function + +Rem +bbdoc: Get the flags parameter of a given item in a list based gadget. +about: +See Also: #AddGadgetItem +EndRem +Function GadgetItemFlags( gadget:TGadget,index ) + Return gadget.ItemFlags(index) +End Function + + + +' toolbar + +Rem +bbdoc: Creates a window toolbar. +about: +A Toolbar is created from an iconstrip - an image that contains a row of equally shaped icons. +Any images in the row left blank are treated as Toolbar separators. + +Toolbars are positioned along the top of the @window and either the client-area and/or window frame will be +resized so that the client area of the window will begin just below the toolbar. + +At present, MaxGUI windows only support one toolbar at a time. + +A Toolbar generates the following events: + +[ @{Event ID} | @Description +* EVENT_GADGETACTION | A toolbar item has been selected/clicked. Event data contains the item index. +] + +The @source parameter can be a previously loaded @TIconStrip, a #TPixmap or a URL to an image +file which @CreateToolBar will attempt to load an icon-strip from automatically. + +The recommended icon size is 24x24 pixels which seems to work well on most platforms. Using a +different icon size may result in the pixmaps being scaled before being set depending on the OS. + +The @x, @y, @w, @h parameters are all ignored and are simply there to make the CreateToolbar() system call +consistent with the other @{CreateGadget()} calls. + +The toolbar can be alterted during runtime using the #ClearGadgetItems, #InsertGadgetItem, #ModifyGadgetItem etc. +functions. Use the GADGETICON_SEPARATOR constant as an item's icon if you want it to be a separator, or +GADGETICON_BLANK if you would like a blank square icon instead. + +%{IMPORTANT: Toolbars should only be parented to window gadgets. Parenting a toolbar to a panel is not +officially supported - users are strongly advised to instead use push-buttons with pixmap icons set. Debug builds +will output a warning message to standard error if toolbars are parented otherwise.} + +See Also: #AddGadgetItem, #EnableGadgetItem, #DisableGadgetItem and #SetToolbarTips. +EndRem +Function CreateToolbar:TGadget(source:Object,x,y,w,h,window:TGadget,style=0) + Local flags:Int = 0 + Local iconstrip:TIconStrip = TIconStrip(source) + ?Debug + If window.Class() <> GADGET_WINDOW Then + DebugLog "WARNING: Toolbars should *only* be parented to window gadgets." + EndIf + ? + Local toolbar:TGadget = maxgui_driver.CreateGadget(GADGET_TOOLBAR,"",x,y,w,h,window,style) + If toolbar + If Not iconstrip Then iconstrip = LoadIconStrip(source) + If (LocalizationMode()&LOCALIZATION_OVERRIDE) Then flags:|GADGETITEM_LOCALIZED + If iconstrip + toolbar.SetIconStrip iconstrip + For Local icon=0 Until iconstrip.count + AddGadgetItem toolbar,"",flags,icon + Next + EndIf + EndIf + Return toolbar +End Function + +Rem +bbdoc: Attach a list of tips to a Toolbar gadget. +about: Simply provides a quick way to set the tooltips of a toolbar's items after them being added. +See Also: #CreateToolbar +EndRem +Function SetToolbarTips( toolbar:TGadget,tips$[] ) + Local Text$,icon,extra:Object,flags,index + For Local tip$ = EachIn tips + Text=GadgetItemText(toolbar,index) + icon=GadgetItemIcon(toolbar,index) + extra=GadgetItemExtra(toolbar,index) + flags=GadgetItemFlags(toolbar,index) + ModifyGadgetItem toolbar,index,Text,flags,icon,tip,extra + index:+1 + Next +End Function +'index,text$,icon=-1,tip$,extra:Object=Null + +' treeview + +Rem +bbdoc: Create a TreeView gadget. +about: +A TreeView provides a view of an expandable list of nodes populated with the +#AddTreeViewNode command. TreeView nodes can themselves contain nodes providing +a flexible method of displaying a hierachy of information. + +[ @{Event ID} | @Description +* EVENT_GADGETSELECT | The user has selected a node. +* EVENT_GADGETACTION | The user has double-clicked a node. +* EVENT_GADGETOPEN | The user has expanded a node, revealing its children. +* EVENT_GADGETCLOSE | The user has collapsed a node, hiding its children. +* EVENT_GADGETMENU | The user has right-clicked somewhere in the TreeView. +] + +Each event will have the containing TreeView gadget as the event source and the concerned +node gadget in the EventExtra field of the #TEvent. + +See Also: #AddTreeViewNode, #InsertTreeViewNode, #ModifyTreeViewNode, #TreeViewRoot, +#SelectedTreeViewNode and #CountTreeViewNodes, #SelectTreeViewNode, #ExpandTreeViewNode, +#CollapseTreeViewNode and #FreeTreeViewNode. +EndRem +Function CreateTreeView:TGadget(x,y,w,h,group:TGadget,style=0) + Return maxgui_driver.CreateGadget(GADGET_TREEVIEW,"",x,y,w,h,GetGroup(group),style) +End Function + +Rem +bbdoc: Add a node to a TreeView gadget. +about: The optional @extra parameter is for convenience and is equivalent to calling +#SetGadgetExtra immediately after the node is created. + +See Also: #CreateTreeView, #InsertTreeViewNode +EndRem +Function AddTreeViewNode:TGadget( Text$,node:TGadget,icon=-1,extra:Object=Null ) + Local tmpNode:TGadget = node.InsertNode(-1,Text,icon) + SetGadgetExtra tmpNode, extra + Return tmpNode +End Function + +Rem +bbdoc: Insert a node at a given index in a TreeView gadget. +about: The optional @extra parameter is for convenience and is equivalent to calling +#SetGadgetExtra immediately after the node is created. + +See Also: #CreateTreeView, #AddTreeViewNode +EndRem +Function InsertTreeViewNode:TGadget( index,Text$,node:TGadget,icon=-1,extra:Object=Null ) + Local tmpNode:TGadget = node.InsertNode(index,Text,icon) + SetGadgetExtra tmpNode, extra + Return tmpNode +End Function + +Rem +bbdoc: Modify a node. +about: +See Also: #CreateTreeView +EndRem +Function ModifyTreeViewNode( node:TGadget,Text$,icon=-1 ) + node.ModifyNode Text,icon +End Function + +Rem +bbdoc: Frees all the nodes of a TreeView. +about: +See Also: #CreateTreeView +EndRem +Function ClearTreeView( treeview:TGadget ) + For Local tmpNode:TGadget=EachIn treeview.RootNode().kids.Copy() + FreeGadget(tmpNode) + Next +End Function + +Rem +bbdoc: Get the root node of a TreeView gadget. +about: This is required to parent the first nodes of a blank treeview to. + +A treeview's root node can also be used to deselect any currently selected +nodes (see #SelectTreeViewNode for more information). + +See Also: #CreateTreeView +EndRem +Function TreeViewRoot:TGadget( treeview:TGadget ) + Return treeview.RootNode() +End Function + +Rem +bbdoc: Get the node currently selected in a TreeView gadget. +about: Will return #Null if there aren't any nodes currently selected. + +See Also: #CreateTreeView, #SelectTreeViewNode +EndRem +Function SelectedTreeViewNode:TGadget( treeview:TGadget ) + Return treeview.SelectedNode() +End Function + +Rem +bbdoc: Get the number of children of a Node gadget. +about: +See Also: #CreateTreeView +EndRem +Function CountTreeViewNodes( node:TGadget ) + Return node.CountKids() +End Function + +Rem +bbdoc: Selects/highlights a treeview node. +about: It is possible to deselect a selection by selecting a treeview's root node. +For example: + +{{ +SelectTreeViewNode( TreeViewRoot( myTree ) ) +}} + +See Also: #CreateTreeView, #SelectedTreeViewNode +EndRem +Function SelectTreeViewNode( node:TGadget ) + node.Activate ACTIVATE_SELECT +End Function + +Rem +bbdoc: Expands a treeview node in a TreeView gadget. +about: +See Also: #CreateTreeView, #CollapseTreeViewNode +EndRem +Function ExpandTreeViewNode( node:TGadget ) + node.Activate ACTIVATE_EXPAND +End Function + +Rem +bbdoc: Collapses a treeview node in a TreeView gadget. +about: +See Also: #CreateTreeView, #ExpandTreeViewNode +EndRem +Function CollapseTreeViewNode( node:TGadget ) + node.Activate ACTIVATE_COLLAPSE +End Function + +Rem +bbdoc: Removes a treeview node from a TreeView gadget. +about: This function has been superseded by #FreeGadget, but is available for backwards compatability. + +See Also: #CreateTreeView +EndRem +Function FreeTreeViewNode( node:TGadget ) + node.CleanUp +End Function + +' htmlview + +Rem +bbdoc: Create an HTMLView gadget. +about: +The HTMLView is a complete web browser object inside a MaxGUI gadget. The HTML +page displayed is controlled with the #HTMLViewGo command or from the user navigating +from within the currently viewed page. + +#CreateHTMLView supports the following styles: + +[ @Style | @Meaning +* HTMLVIEW_NOCONTEXTMENU | The webpage's default context menu is disabled. +* HTMLVIEW_NONAVIGATE | User navigation is disabled and EVENT_GADGETACTION is generated instead. +] + +[ @{Event ID} | @Description +* EVENT_GADGETDONE | Generated when a webpage has finished loading or a page anchor has been scrolled to. +* EVENT_GADGETACTION | Generated when a user clicks a link. Event Text contains the requested URL. +] + +%{Note: EVENT_GADGETACTION requires the HTMLVIEW_NONAVIGATE style flag.} + +See Also: #HtmlViewGo, #HtmlViewBack, #HtmlViewForward, #HtmlViewStatus and #HtmlViewCurrentURL. +EndRem +Function CreateHTMLView:TGadget(x,y,w,h,group:TGadget,style=0) + Return maxgui_driver.CreateGadget(GADGET_HTMLVIEW,"",x,y,w,h,GetGroup(group),style) +End Function + +Rem +bbdoc: Direct the HTMLView gadget to a new URL. +about: +See Also: #CreateHTMLView +EndRem +Function HtmlViewGo( view:TGadget,url$ ) + view.SetText url +End Function + +Rem +bbdoc: Go back a page in an HTMLView gadget. +about: +See Also: #CreateHTMLView +EndRem +Function HtmlViewBack( view:TGadget ) + view.Activate ACTIVATE_BACK +End Function + +Rem +bbdoc: Go forward a page in an HTMLView gadget. +about: +See Also: #CreateHTMLView +EndRem +Function HtmlViewForward( view:TGadget ) + view.Activate ACTIVATE_FORWARD +End Function + +Rem +bbdoc: Get the status of an HTMLView gadget. +about: +See Also: #CreateHTMLView +EndRem +Function HtmlViewStatus( view:TGadget ) + Return view.State() +End Function + +Rem +bbdoc: Get the current URL of an HTMLView gadget. +about: +See Also: #CreateHTMLView +EndRem +Function HtmlViewCurrentURL$( view:TGadget ) + Return view.GetText() +End Function + +Rem +bbdoc: Run a script in an HTMLView gadget. +about: +See Also: #CreateHTMLView +EndRem +Function HtmlViewRun$( view:TGadget,script$ ) + Return view.Run(script) +End Function + +' label + +Rem +bbdoc: Create a Label gadget. +about: +A Label gadget is used to place static text or frames in a MaxGUI user interface. They do not +generate any events. + +Labels support these optional styles: + +[ @Style | @Meaning +* LABEL_FRAME | The label has a simple border. +* LABEL_SUNKENFRAME | The label has a sunken border. +* LABEL_SEPARATOR | The label is an etched box with no text useful for drawing separators. +* LABEL_LEFT | The label's text is left-aligned. This is the default. +* LABEL_CENTER | The label's text is center-aligned. +* LABEL_RIGHT | The label's text is right-aligned. +] + +See Also: #SetGadgetText, #SetGadgetTextColor, #SetGadgetFont and #SetGadgetColor. +EndRem +Function CreateLabel:TGadget( name$,x,y,w,h,group:TGadget,style=LABEL_LEFT ) + Return maxgui_driver.CreateGadget(GADGET_LABEL,name,x,y,w,h,GetGroup(group),style) +End Function + +' slider + +Rem +bbdoc: Create a Slider gadget. +about: +A Slider gadget supports the following styles: + +[ @Style | @Meaning +* SLIDER_HORIZONTAL | The slider is moved left and right. +* SLIDER_VERTICAL | The slider is moved up and down. +* SLIDER_SCROLLBAR | The slider uses a proportional size knob. +* SLIDER_TRACKBAR | The slider uses a fixed size knob. +* SLIDER_STEPPER | The slider has no knob, just arrow buttons. +] + +A slider only emits one type of event: + +[ @{Event ID} | @Description +* EVENT_GADGETACTION | The user has changed the slider's value. Event Data contains the SliderValue. +] + +See Also: #SetSliderRange, #SetSliderValue and #SliderValue +EndRem +Function CreateSlider:TGadget( x,y,w,h,group:TGadget,style=0 ) + Return maxgui_driver.CreateGadget(GADGET_SLIDER,"",x,y,w,h,GetGroup(group),style) +End Function + +Rem +bbdoc: Set the range of a Slider gadget. +about: For the default SLIDER_SCROLLBAR style the range0,range1 parameters are treated +as a visible / total ratio which dictates both the size of the knob and it's +maximum value. The default value is 1,10 which displays a Slider with a knob +that occupies 1/10th the area and with a #SliderValue range of 0..9. + +For the SLIDER_TRACKBAR and SLIDER_STEPPER styles the range0,range1 parameters +are treated as the minimum and maximum #SliderValue range inclusive. + +See Also: #CreateSlider, #SliderValue and #SetSliderValue +EndRem +Function SetSliderRange( slider:TGadget,range0,range1 ) + slider.SetRange(range0,range1) +End Function + +Rem +bbdoc: Set the position of a Slider gadget. +about: +See Also: #CreateSlider, #SetSliderRange and #SliderValue +EndRem +Function SetSliderValue( slider:TGadget,value ) + slider.SetProp value +End Function + +Rem +bbdoc: Get the position of a Slider gadget. +about: +See Also: #CreateSlider, #SetSliderRange and #SetSliderValue +EndRem +Function SliderValue( slider:TGadget ) + Return slider.GetProp() +End Function + +' progress + +Rem +bbdoc: Create a Progress Bar gadget. +about: Similar to Labels, Progress Bar gadgets do not generate any events themselves. +See Also: #UpdateProgBar +EndRem +Function CreateProgBar:TGadget( x,y,w,h,group:TGadget,style=0 ) + Return maxgui_driver.CreateGadget(GADGET_PROGBAR,"",x,y,w,h,GetGroup(group),style) +End Function + +Rem +bbdoc: Update the display of a ProgressBar gadget. +about: +See Also: #CreateProgBar +EndRem +Function UpdateProgBar( progbar:TGadget,value# ) + progbar.SetValue value +End Function + +Rem +bbdoc: Creates an icon strip from an image file. +about: +An icon strip is a series of small images that can be attached to item-based gadgets. + +Icons must be square, and arranged in a single horizontal strip across the source image. + +The number of icons in an iconstrip is determined by dividing the image width by its height. For example, +an iconstrip 64 wide by 8 high is assumed to contain 64/8=8 icons. + +Once an icon strip has been loaded, it can be attached to item-based gadgets using #SetGadgetIconStrip. + +See Also: #SetGadgetIconStrip and #PixmapFromIconStrip +EndRem +Function LoadIconStrip:TIconStrip( source:Object ) + Return maxgui_driver.LoadIconStrip(source) +End Function + +Rem +bbdoc: Attaches an icon strip to an item-based gadget. +about: Once attached, icons can be specified when items are added or modified with the #AddGadgetItem, +#InsertGadgetItem and #ModifyGadgetItem commands. + +This command may only be used with the @ComboBox, @ListBox, @Tabber and @TreeNode gadgets. + +%{Note: It is highly recommended that icon-strips are set before any items are added to a gadget.} + +See Also: #LoadIconStrip +EndRem +Function SetGadgetIconStrip( gadget:TGadget,iconstrip:TIconStrip ) + gadget.SetIconStrip(iconstrip) +End Function + +Rem +bbdoc: Returns a pixmap containing either a copy of the original icon-strip or just the specified icon. +about: @iconstrip: The icon-strip to return a pixmap from. + +@index: The index (base 0) of the icon to extract. If this is negative, a %copy of the +original pixmap used to create the iconstrip is returned. + +This function will return #Null if no iconstrip is passed, or if the icon index is invalid. + +See Also: #LoadIconStrip +EndRem +Function PixmapFromIconStrip:TPixmap( iconstrip:TIconStrip, index = -1 ) + If iconstrip Then Return iconstrip.ExtractIconPixmap(index) +End Function + + +Rem +bbdoc: Create a Canvas gadget. +about: +A Canvas provides a #Graphics interface for realtime drawing purposes. + +Once a Canvas is created, the #CanvasGraphics() Function can be used with the +#SetGraphics command to direct #Max2D drawing commands to be +drawn directly on the Canvas. + +An EVENT_GADGETPAINT event is generated whenever the gadget must be redrawn by either +the system (for instance when it is first shown) or due to the #RedrawGadget command. + +An EVENT_GADGETPAINT handler should always call #SetGraphics +with the canvas's Max2D graphics context to ensure the viewport and similar +properties are in their correct state. + +When a Canvas is active using either the #ActivateGadget command or clicking +on the Canvas when the application is running, the following events will also +be sent from the Canvas: + +[ @{Event ID} | @Description +* EVENT_MOUSEDOWN | Mouse button pressed. Event data contains mouse button code. +* EVENT_MOUSEUP | Mouse button released. Event data contains mouse button code. +* EVENT_MOUSEMOVE | Mouse moved. Event x and y contain mouse coordinates. +* EVENT_MOUSEWHEEL | Mouse wheel spun. Event data contains delta clicks. +* EVENT_MOUSEENTER | Mouse entered gadget area. +* EVENT_MOUSELEAVE | Mouse left gadget area. +* EVENT_KEYDOWN | Key pressed. Event data contains keycode. +* EVENT_KEYUP | Key released. Event data contains keycode. +* EVENT_KEYCHAR | Key character. Event data contains unicode value. +] + +See Also: #ActivateGadget, #RedrawGadget, #CanvasGraphics +EndRem +Function CreateCanvas:TGadget( x,y,w,h,group:TGadget,style=0 ) + Local t:TGadget=maxgui_driver.CreateGadget(GADGET_CANVAS,"",x,y,w,h,GetGroup(group),style) + t.AttachGraphics DefaultGraphicsFlags() 'gfxFlags + Return t +End Function + +Rem +bbdoc: Retrieve a Canvas gadget's Graphics context. +about: The #RedrawGadget example shows an alternative method for drawing to Canvas +gadgets utilizing the EVENT_GADGETPAINT event. + +See Also: #CreateCanvas +EndRem +Function CanvasGraphics:TGraphics( gadget:TGadget ) + Return gadget.CanvasGraphics() +End Function + +Rem +bbdoc: Return internal gadget handle. +about: #QueryGadget retrieves system handles for use with API specific functions. + +[ @Constant | @{Return Value} +* QUERY_HWND | A Windows API HWND handle. +* QUERY_HWND_CLIENT | A Windows API HWND handle representing a gadget's client area. +* QUERY_NSVIEW | A Cocoa NSView handle. +* QUERY_NSVIEW_CLIENT | A Cocoa NSView representing a gadget's client area. +* QUERY_FLWIDGET | An FL_WIDGET handle. +* QUERY_FLWIDGET_CLIENT | An FL_WIDGET handle representing a gadget's client area. +] +EndRem +Function QueryGadget( gadget:TGadget,queryid ) + Return gadget.Query(queryid) +End Function + +Private + +Function GetGroup:TGadget( gadget:TGadget ) + Local tmpProxy:TProxyGadget = TProxyGadget(gadget) + If tmpProxy Then Return GetGroup(tmpProxy.proxy) + Return gadget +EndFunction diff --git a/mod/maxgui.mod/maxgui.mod/maxgui.h b/mod/maxgui.mod/maxgui.mod/maxgui.h new file mode 100644 index 0000000..38412ed --- /dev/null +++ b/mod/maxgui.mod/maxgui.mod/maxgui.h @@ -0,0 +1,174 @@ +#ifndef BB_BRL_MAXGUI_H +#define BB_BRL_MAXGUI_H + +#include + +#define ACTIVATE_FOCUS 0 +#define ACTIVATE_CUT 1 +#define ACTIVATE_COPY 2 +#define ACTIVATE_PASTE 3 +#define ACTIVATE_MINIMIZE 4 +#define ACTIVATE_MAXIMIZE 5 +#define ACTIVATE_RESTORE 6 +#define ACTIVATE_SELECT 7 +#define ACTIVATE_EXPAND 8 +#define ACTIVATE_COLLAPSE 9 +#define ACTIVATE_BACK 10 +#define ACTIVATE_FORWARD 11 +#define ACTIVATE_PRINT 12 +#define ACTIVATE_REDRAW 13 + +#define GADGET_DESKTOP 0 +#define GADGET_WINDOW 1 +#define GADGET_BUTTON 2 +#define GADGET_PANEL 3 +#define GADGET_TEXTFIELD 4 +#define GADGET_TEXTAREA 5 +#define GADGET_COMBOBOX 6 +#define GADGET_LISTBOX 7 +#define GADGET_TOOLBAR 8 +#define GADGET_TABBER 9 +#define GADGET_TREEVIEW 10 +#define GADGET_HTMLVIEW 11 +#define GADGET_LABEL 12 +#define GADGET_SLIDER 13 +#define GADGET_PROGBAR 14 +#define GADGET_MENUITEM 15 +#define GADGET_NODE 16 +#define GADGET_CANVAS 17 +#define GADGET_TIMER 18 + +#define GUICOLOR_WINDOWBG 0 +#define GUICOLOR_GADGETBG 1 +#define GUICOLOR_GADGETFG 2 +#define GUICOLOR_SELECTIONBG 3 +#define GUICOLOR_LINKFG 4 + +#define FONT_NORMAL 0 +#define FONT_BOLD 1 +#define FONT_ITALIC 2 +#define FONT_UNDERLINE 4 +#define FONT_STRIKETHROUGH 8 + +#define CHECK_CLEARED 0 +#define CHECK_SELECTED 1 +#define CHECK_INDETERMINATE -1 + +#define STATE_MINIMIZED 1 +#define STATE_MAXIMIZED 2 +#define STATE_DISABLED 4 +#define STATE_HIDDEN 8 +#define STATE_SELECTED 16 +#define STATE_ACTIVE 32 +#define STATE_INDETERMINATE 80 + +#define GADGETICON_SEPARATOR -2 +#define GADGETICON_BLANK -1 + +#define GADGETITEM_NONE -1 +#define GADGETITEM_NORMAL 0 +#define GADGETITEM_DEFAULT 1 +#define GADGETITEM_TOGGLE 2 +#define GADGETITEM_LOCALIZED 4 + +#define WINDOW_TITLEBAR 1 +#define WINDOW_RESIZABLE 2 +#define WINDOW_MENU 4 +#define WINDOW_STATUS 8 +#define WINDOW_TOOL 16 +#define WINDOW_CLIENTCOORDS 32 +#define WINDOW_HIDDEN 64 +#define WINDOW_ACCEPTFILES 128 +#define WINDOW_CHILD 256 +#define WINDOW_CENTER 512 + +#define LABEL_LEFT 0 +#define LABEL_FRAME 1 +#define LABEL_SUNKENFRAME 2 +#define LABEL_SEPARATOR 3 +#define LABEL_RIGHT 8 +#define LABEL_CENTER 16 + +#define BUTTON_CHECKBOX 2 +#define BUTTON_RADIO 3 +#define BUTTON_OK 4 +#define BUTTON_CANCEL 5 +#define BUTTON_PUSH 8 + +#define PANEL_SUNKEN 1 +#define PANEL_RAISED 2 +#define PANEL_GROUP 3 +#define PANEL_BORDER PANEL_SUNKEN + +#define PANEL_ACTIVE 4 +#define PANEL_CANVAS 8 + +#define TEXTAREA_ALL -1 + +#define TEXTAREA_CHARS 1 +#define TEXTAREA_LINES 2 + +#define TEXTAREA_WORDWRAP 1 +#define TEXTAREA_READONLY 2 + +#define TEXTFIELD_PASSWORD 1 + +#define TEXTFORMAT_BOLD 1 +#define TEXTFORMAT_ITALIC 2 +#define TEXTFORMAT_UNDERLINE 4 +#define TEXTFORMAT_STRIKETHROUGH 8 + +#define SLIDER_HORIZONTAL 1 +#define SLIDER_VERTICAL 2 +#define SLIDER_SCROLLBAR 0 +#define SLIDER_TRACKBAR 4 +#define SLIDER_STEPPER 8 +#define SLIDER_DIAL 12 + +#define LISTBOX_MULTISELECT 1 + +#define COMBOBOX_EDITABLE 1 + +#define TREEVIEW_DRAGNDROP 1 + +#define HTMLVIEW_NOCONTEXTMENU 1 +#define HTMLVIEW_NONAVIGATE 2 + +#define SENSITIZE_MOUSE 1 +#define SENSITIZE_KEYS 2 +#define SENSITIZE_ALL 3 + +#define PANELPIXMAP_TILE 0 +#define PANELPIXMAP_CENTER 1 +#define PANELPIXMAP_FIT 2 +#define PANELPIXMAP_STRETCH 3 +#define PANELPIXMAP_FIT2 4 + +#define GADGETPIXMAP_BACKGROUND 0 +#define GADGETPIXMAP_ICON 8 +#define GADGETPIXMAP_NOTEXT 16 + +#define POINTER_DEFAULT 0 +#define POINTER_ARROW 1 +#define POINTER_IBEAM 2 +#define POINTER_WAIT 3 +#define POINTER_CROSS 4 +#define POINTER_UPARROW 5 +#define POINTER_SIZENWSE 6 +#define POINTER_SIZENESW 7 +#define POINTER_SIZEWE 8 +#define POINTER_SIZENS 9 +#define POINTER_SIZEALL 10 +#define POINTER_NO 11 +#define POINTER_HAND 12 +#define POINTER_APPSTARTING 13 +#define POINTER_HELP 14 + +#define QUERY_HWND 1 +#define QUERY_HWND_CLIENT 2 +#define QUERY_NSVIEW 3 +#define QUERY_NSVIEW_CLIENT 4 +#define QUERY_FLWIDGET 5 +#define QUERY_FLWIDGET_CLIENT 6 + +#endif diff --git a/mod/maxgui.mod/maxgui.mod/version.txt b/mod/maxgui.mod/maxgui.mod/version.txt new file mode 100644 index 0000000..053a2b1 --- /dev/null +++ b/mod/maxgui.mod/maxgui.mod/version.txt @@ -0,0 +1,101 @@ +1.35 +January 2013 release +cocoamaxgui-1.56 +fltkmaxgui-1.60 +win32maxgui-0.75 +1.34 Release +Left margin added to textareas through SetIndents (SetTextAreaTabs replacement). +1.33 Release +Added WindowStatusText() command. +Renamed TGadget.SetStatus() to more specific TGadget.SetStatusText(). +1.32 Release +Added PANEL_RAISED/PANEL_SUNKEN style flags (PANEL_BORDER now redundant). +1.31 Release +Added optional 'extra' parameter to AddTreeViewNode/InsertTreeViewNode commands. +1.30 Release +Added LookupGuiColor() command. +1.29 Release +Added hack to better center windows by taking into account task-bars/docks. +1.28 Release +Changed default Mac OS X monospaced font to 'Monaco'. +Added GetWidth() etc. methods to TGadget for TProxyGadget. +Added recursive source.source handling to PostGuiEvent/QueueGuiEvent. +1.27 Release +Added some internal event queueing functions. +Tweaked some docs. +1.26 Release +Added GetProxy() method to TProxyGadget. +1.25 Release +Item array is now cleared in CleanUp() to avoid potential cyclic memory references. +Added CleanUp() method to free generic MaxGUI objects before calling API specific Free(). +1.24 Release +Added tooltip methods to TProxyGadget. +1.23 Release +Updated docs to include EVENT_GADGETMENU for tabbers. +Added TextAreaCharX() and TextAreaCharY() commands. +1.22 Release +Corrected GADGETITEM_TOGGLE in docs. +Added width and height constraints in SetRect() to enforce positive values. +1.21 Release +Changed LookupGuiFont()'s Linux default for GUIFONT_SYSTEM. +1.20 Release +Added SetShape() method to TProxyGadget. +1.19 Release +Added new BUTTON_PUSH flag support. +Added new GadgetExtra()/SetGadgetExtra() functions. +Renamed the infamous ExtractIconPixmapFromStrip() function to PixmapFromIconStrip(). +LoadGuiFont now accepts a Double for the font size so that some platforms are able to handle non-integer font sizes. +Added new LookupGuiFont() function, new strikethough parameter for LoadGuiFont, and copied font constants to maxgui.h. +Moved HasDescendant() method from Win32MaxGUIEx driver as it is probably more useful here. +1.18 Release +Added new GadgetClass() function. +1.17 Release +Implemented framework for CHECK_INDETERMINATE button state. +Added SetGadgetSensitivity() and GetGadgetSensitivity() for capturing mouse/key events on more gadgets. +Added WINDOW_CENTER flag to CreateWindow to centralise windows automatically on the screen. +1.16 Release +Added SetGadgetTooltip() and GadgetTooltip() functions for setting tooltips on non-item based gadgets. +Added ExtractIconPixmapFromStrip() function and corresponding TIconStrip method. +Added SetGadgetPixmap() for push-button and menu icon support. +Added Fabian's SetHotKeyEvent() fix so that the owner parameter must be the same also to overwrite. +Added TProxyGadget.SetLayout() method. +Added PANELPIXMAP_FIT2 constant. +1.15 Release +New SetDataSource method for TGadget +1.14 Release +Bumped just in case... +1.13 Release +Added RemoveHotKey Function +1.12 Release +Bumped for popupmenu method change +1.11 Release +Bumped for new TMap +1.10 Release +Rebuilt under 10.3.9 +1.09 Release +Added extra detail to CreateListBox docs +Added TEXTFORMAT_UNDERLINE and TEXTFORMAT_STRIKETHROUGH constants +Added GadgetText function for accessing Gadget.GetText +1.08 Release +Added SetGraphics requirement to CreateCanvas documentation +Replaced EnableToolBarItem references with Enable/DisableGadgetItem +1.07 Release +Added optional owner window field to THotKey processing +1.06 Release +GraphicsFlags removed from CreatePanel, panels now use Graphic's DefaultGraphicsFlags +1.05 Release +Added range checking on gadget item parameters +1.04 Release +Bumped version to restore missing docs on Apple modserver +1.03 Release +Fixed some broken examples due to new 1.14 strict rules +New common MaxGUI.h header file for use by native drivers +ModuleInfo Histroy: Documented TEXTAREA_ALL, TEXTAREA_CHARS and TEXTAREA_LINES constants +ModuleInfo Histroy: TreeView now uses EventExtra to specify node involved +1.02 Release +Renamed Query() to QueryGadget() +Added QUERY_HWND,QUERY_HWND_CLIENT,QUERY_NSVIEW, QUERY_NSVIEW_CLIENT, +QUERY_FLWIDGET, and QUERY_FLWIDGET_CLIENT constants +EventSource() fixed for TProxyGadgets +Removed SetGadgetTarget, see new Event.AddEventTarget +RedrawGadget now uses ACTIVATE_REDRAW diff --git a/mod/maxgui.mod/proxygadgets.mod/doc/createhyperlink.bmx b/mod/maxgui.mod/proxygadgets.mod/doc/createhyperlink.bmx new file mode 100644 index 0000000..069e66f --- /dev/null +++ b/mod/maxgui.mod/proxygadgets.mod/doc/createhyperlink.bmx @@ -0,0 +1,41 @@ +Strict + +Import MaxGUI.Drivers +Import MaxGUI.ProxyGadgets + +AppTitle = "Hyperlink Test Window" + +Global wndMain:TGadget = CreateWindow( AppTitle, 100, 100, 300, 59, Null, WINDOW_TITLEBAR|WINDOW_CLIENTCOORDS|WINDOW_STATUS ) + + 'Standard Hyperlink Gadget + Global hypLeft:TGadget = CreateHyperlink( "http://www.google.com/", 2, 2, ClientWidth(wndMain)-4, 15, wndMain, LABEL_LEFT ) + + 'Center Aligned Hyperlink Gadget with alternate text + Global hypCenter:TGadget = CreateHyperlink( "http://www.blitzbasic.com/", 2, 21, ClientWidth(wndMain)-4, 17, wndMain, LABEL_CENTER|LABEL_FRAME, "BlitzBasic" ) + + 'Right Aligned Sunken Hyperlink Gadget with custom rollover colors set + Global hypRight:TGadget = CreateHyperlink( "http://www.blitzmax.com/", 2, 42, ClientWidth(wndMain)-4, 15, wndMain, LABEL_RIGHT, "Custom Rollover Colors" ) + SetGadgetTextColor(hypRight,128,128,128) 'Set normal text color to grey. + SetGadgetColor(hypRight,255,128,0) 'Set rollover color to orange. + +'Example of how to retrieve a hyperlink gadget's URL +Print "Hyperlink 1 URL: " + String(GadgetExtra(hypLeft)) +Print "Hyperlink 2 URL: " + String(GadgetExtra(hypCenter)) +Print "Hyperlink 3 URL: " + String(GadgetExtra(hypRight)) + +'Example of how to set a hyperlink gadget's URL +SetGadgetExtra( hypRight, "http://www.blitzbasic.co.nz" ) +'We need to update the tooltip to the new URL +SetGadgetToolTip( hypRight, String(GadgetExtra(hypRight)) ) + +Repeat + + WaitEvent() + + SetStatusText wndMain, CurrentEvent.ToString() + + Select EventID() + Case EVENT_WINDOWCLOSE, EVENT_APPTERMINATE;End + EndSelect + +Forever diff --git a/mod/maxgui.mod/proxygadgets.mod/doc/createscrollpanel.bmx b/mod/maxgui.mod/proxygadgets.mod/doc/createscrollpanel.bmx new file mode 100644 index 0000000..38fe54a --- /dev/null +++ b/mod/maxgui.mod/proxygadgets.mod/doc/createscrollpanel.bmx @@ -0,0 +1,63 @@ +Strict + +Import MaxGUI.Drivers +Import MaxGUI.ProxyGadgets + +AppTitle = "Scroll Panel Example" +SeedRnd MilliSecs() + +Global wndMain:TGadget = CreateWindow(AppTitle,100,100,400,300,Null,WINDOW_TITLEBAR|WINDOW_RESIZABLE|WINDOW_CENTER|WINDOW_CLIENTCOORDS|WINDOW_STATUS) + + ' Create a scroll-panel + Global scrlMain:TScrollPanel = CreateScrollPanel( 0, 0, ClientWidth(wndMain), ClientHeight(wndMain)-30, wndMain, SCROLLPANEL_SUNKEN ) + SetGadgetLayout scrlMain,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED + + ' Retrieve the panel that is scrolled + Local tmpClient:TGadget = ScrollPanelClient(scrlMain) + + ' Draw some buttons on the scroll-panel + Local tmpButton:TGadget + + For Local i:Int = 1 To 50 + tmpButton = CreateButton( "Button " + i, 0, (i-1)*35, ClientWidth(scrlMain)-20, 30, tmpClient, BUTTON_PUSH ) + SetGadgetTextColor tmpButton,Rand(0,255),Rand(0,255),Rand(0,255) + SetGadgetLayout tmpButton,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_CENTERED + Next + + ' Resize the scrollable region tight around the buttons + FitScrollPanelClient( scrlMain, SCROLLPANEL_SIZETOKIDS ) + + ' Add some buttons for testing the ScrollScrollPanel function. + Global btnTopLeft:TGadget = CreateButton( "Top Left", 0, ClientHeight(wndMain)-30, ClientWidth(wndMain)/4, 30, wndMain, BUTTON_PUSH ) + SetGadgetLayout( btnTopLeft, EDGE_ALIGNED, EDGE_RELATIVE, EDGE_CENTERED, EDGE_ALIGNED ) + SetGadgetToolTip( btnTopLeft, "ScrollScrollPanel( scrlMain, SCROLLPANEL_LEFT, SCROLLPANEL_TOP )" ) + + Global btnTopRight:TGadget = CreateButton( "Top Right", ClientWidth(wndMain)/4, ClientHeight(wndMain)-30, ClientWidth(wndMain)/4, 30, wndMain, BUTTON_PUSH ) + SetGadgetLayout( btnTopRight, EDGE_RELATIVE, EDGE_RELATIVE, EDGE_CENTERED, EDGE_ALIGNED ) + SetGadgetToolTip( btnTopRight, "ScrollScrollPanel( scrlMain, SCROLLPANEL_RIGHT, SCROLLPANEL_TOP )" ) + + Global btnBottomLeft:TGadget = CreateButton( "Bottom Left", 2*ClientWidth(wndMain)/4, ClientHeight(wndMain)-30, ClientWidth(wndMain)/4, 30, wndMain, BUTTON_PUSH ) + SetGadgetLayout( btnBottomLeft, EDGE_RELATIVE, EDGE_RELATIVE, EDGE_CENTERED, EDGE_ALIGNED ) + SetGadgetToolTip( btnBottomLeft, "ScrollScrollPanel( scrlMain, SCROLLPANEL_LEFT, SCROLLPANEL_BOTTOM )" ) + + Global btnBottomRight:TGadget = CreateButton( "Bottom Right", 3*ClientWidth(wndMain)/4, ClientHeight(wndMain)-30, ClientWidth(wndMain)/4, 30, wndMain, BUTTON_PUSH ) + SetGadgetLayout( btnBottomRight, EDGE_RELATIVE, EDGE_ALIGNED, EDGE_CENTERED, EDGE_ALIGNED ) + SetGadgetToolTip( btnBottomRight, "ScrollScrollPanel( scrlMain, SCROLLPANEL_RIGHT, SCROLLPANEL_BOTTOM )" ) + +Repeat + Select WaitEvent() + Case EVENT_WINDOWCLOSE, EVENT_APPTERMINATE;End + Case EVENT_GADGETACTION + Select EventSource() + Case btnTopLeft + ScrollScrollPanel( scrlMain, SCROLLPANEL_LEFT, SCROLLPANEL_TOP ) + Case btnTopRight + ScrollScrollPanel( scrlMain, SCROLLPANEL_RIGHT, SCROLLPANEL_TOP ) + Case btnBottomLeft + ScrollScrollPanel( scrlMain, SCROLLPANEL_LEFT, SCROLLPANEL_BOTTOM ) + Case btnBottomRight + ScrollScrollPanel( scrlMain, SCROLLPANEL_RIGHT, SCROLLPANEL_BOTTOM ) + EndSelect + EndSelect + SetStatusText wndMain, "ScrollPanelX(): " + ScrollPanelX( scrlMain ) + ", ScrollPanelY():" + ScrollPanelY( scrlMain ) +Forever diff --git a/mod/maxgui.mod/proxygadgets.mod/doc/createsplitter.bmx b/mod/maxgui.mod/proxygadgets.mod/doc/createsplitter.bmx new file mode 100644 index 0000000..3246081 --- /dev/null +++ b/mod/maxgui.mod/proxygadgets.mod/doc/createsplitter.bmx @@ -0,0 +1,37 @@ +Strict + +Import MaxGUI.Drivers +Import MaxGUI.ProxyGadgets + +Global wndMain:TGadget = CreateWindow("Splitter Example",100,100,400,300,Null,WINDOW_TITLEBAR|WINDOW_RESIZABLE|WINDOW_CENTER|WINDOW_CLIENTCOORDS|WINDOW_STATUS) + + 'Create a splitter gadget + Global spltMain:TSplitter = CreateSplitter( 0, 0, ClientWidth(wndMain), ClientHeight(wndMain), wndMain ) + SetGadgetLayout spltMain,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED + + Local tmpSplitPanel:TGadget + + 'Add a gadget to our left pane + tmpSplitPanel = SplitterPanel(spltMain,SPLITPANEL_MAIN) + Global txtEditor:TGadget = CreateTextArea(0,0,ClientWidth(tmpSplitPanel),ClientHeight(tmpSplitPanel),tmpSplitPanel,TEXTAREA_WORDWRAP) + SetGadgetLayout(txtEditor,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED) + + AddTextAreaText(txtEditor, "The quick brown fox jumped over the lazy dogs.~n~n") + AddTextAreaText(txtEditor, "The quick brown fox jumped over the lazy dogs.~n~n") + AddTextAreaText(txtEditor, "The quick brown fox jumped over the lazy dogs.~n~n") + + 'Add a gadget to our right pane + tmpSplitPanel = SplitterPanel(spltMain,SPLITPANEL_SIDEPANE) + Global treeView:TGadget = CreateTreeView(0,0,ClientWidth(tmpSplitPanel),ClientHeight(tmpSplitPanel),tmpSplitPanel) + SetGadgetLayout(treeView,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED) + + AddTreeViewNode("Child", AddTreeViewNode("Parent Node", TreeViewRoot(treeView))) + AddTreeViewNode("Other", TreeViewRoot(treeView)) + +Repeat + WaitEvent() + SetStatusText wndMain, CurrentEvent.ToString() + Select EventID() + Case EVENT_WINDOWCLOSE, EVENT_APPTERMINATE;End + EndSelect +Forever \ No newline at end of file diff --git a/mod/maxgui.mod/proxygadgets.mod/doc/scroll_dimensions.png b/mod/maxgui.mod/proxygadgets.mod/doc/scroll_dimensions.png new file mode 100644 index 0000000000000000000000000000000000000000..9283f3d174e0360bf6a5b9ea4ae54ede15b9acef GIT binary patch literal 205920 zcmYIv1yox>w{u`}#i2OGwK&18IK{0u z)9=0Se``(FUAdW?Gjrx-&)NG-V&1DO;J%=E0RRASl@w*Q0Dx!N007EcO!TKa_iwbL zo-SCfiUuA405;LT7YZOdmka=Sq47yZ=KXs+7f%-tI~Uj2N-{F9UEN)5J~>(g06wdE z+O|5{2P6{k%}Z&O=-{s^E?UHxueGGV1iwmVW~ak?sT@sLxI(PiOCTrroO0w_G-^UZ za2&BFCr<2(WsDuVqJ*&G=-9FQE&pPN#SZx1B%*Oia=!|e*D#IIgNc)_$ge3Fj8iU6 zL+~eTcwlI2hx=W~3r1JKOUwopFOufXe z2Vmj=-e^WgumPU?13r#0F!%t%vjDH;FZ9IEIci?+vp;z%t6sd7QA94p2$RbVLr;&J zhILAbl;f3<`7`tEcierxS>${n0{DMm69B-sWa6jU!XAC5@M@-}gc6$Y%(xD_(UJ5P z77)blbfxP%0AR~AXa>Q_(?Ag{h92yMC}M&>w=>25<^}&^Q;+|y5%BF`RS)L+&o^>~ zNv$g@yE{9}$^+6y=3{z+2-`lh9=%7$+aU1=_|>1TZN?BjlMsdHH-GvjE>*u%O{ZXm zTdeOTDm*k}BOj>e=m(T6TJ_mqK{N^75@fUEV0_={W295q2AO7&R@-3CdsIoVAmFFH zB#M7B*AEj*)N2)%m-?PP+i(EjqTQu;o)r@{*e+~q+8cQad{p?x1PHcKN^t`KOl29l zb;cTi!%G_yABDoD83+2LUrN8Q3Z`=Z$W|39%^ErR zlbZb_&-^=TfgVk}$W&K6?mpcXJPB9)J9EtZUe=BftmjfAm_+7utI;SHvHA=Nn50<| zH*~#<&k4UUz8;N!rAe=nEU3t<6|3`FSCRTc!u^>@l(BqUve*cKFZ3a@LxJ~eNWG@S zJWiub>knayaQPza-&UTy*@-0Ia(=u2qL7FaD%}5FX@|d>C@C}irsppi2LFKL8}6Zg z>AJU^SgDrdb@Wv@l|vLiKUAT%$6Q%X*LgoD43X=>5_;|}{o0&HN>N``Uwv8e$7?D^ z0fJR5VJy^e%{~_T)E_FpnA-?$2goe=c%$?cIT;oS6Nz|U`bWzQ2s0AK$ndeWCOuQC zE76%HoRyz-)?zr|EYA^8q+m!LUA1zk#}N6-`I=)SVkd8>e}{jEa)<81=tZ8zJGYV> z?QK@AF?(h5-Iu!pyXe-Ld{Vl_*;*Sv3Uvqs6Ah)S3!AiRHKTqI33z3TOoovtseG?4 zN}HpwBejEns{QNPMzE1aqn`0wZ+84Z;cv!Y)Jtz1+(_cE;b>b{@*FY@GFx(Qvf515 zQu4Vko7e-0lgD19DW@@~QL^*slvk8iY*t|F!gR-V63b1s z18d}U`L!YCSo7(Xx)pivkF+VZZOg@eL{-@SaM1yl1Q|TWpd0k7_G`$LXnw0RgLDkN z#)BxJl;T&NoV(?vG*U+RvzB;d(X|cV!y^Nr&RXtU` zGJnyw|L1wrXj6GJ`On>D^tGBMr=~!2TMJU#=E0hNXliF_U|V4PqXY(S)CyiDwIOwo z$1nF+q8~&zv!`;Qz`()F^aCDS{ppv}%lwcgqH(r?PkGuoa|*Vkwyhpvu;?!_Dxu@t z8Is&NltUXMojb~&S8gU-ezRA3ISn~|CqLF|p+eA4(5Ur-34sE(d;@-u-~A&pe>8Vz zfY=3TZydl?K^ig|A-0YC3_O-R$$HgGKbyaMSHR6rNhPl(-3uU+5OLv6zD)zO3E`gR zk>+uYewTc+2(S!@0cnNwL(Txof|*ckQDZ`+LX4i>-}nX4bteEt*Q~GWS5BnjzO_mb zOC^R@hwk=P)7gz2CsotI_cN!Gr#|6Dybt=j_#4A~&-_b&5DrU3RD@n6Fu^ripJIkL zL(qF>UB&|}dncPNyP0Flt07X$r7XxUS;1{DzAD@%&;}ghwlSDk(9hFXa#W!b;byN9 za(3(jKb*j#w)3{JA^xP9JR>HqzJ*hLml0(o<=ljvqUrBcqt)MjJ(GIL{(~fr>4M0c zDdB~0A9bHCJ#y?4fmW+&n^~KKy-lus zBfRvAjJ*szXWW(5U%228zfP{M<<@vICRx|o!c-~|Z8Nya`tBUSvA}Q| zT+!9fasE|X7<06rscorw?4`3WvgLEMv+s>8jM_9NBxe>6H~k(I)@bo_1;h<}m0>!g zpH>e-=TdDirsML`@&bdnZ`VJr6*c+qTTX%P@m)^aUV3iL$|1k(i*<-i8DF$`UevGc z66v+*W!H+DIURZ)iX&3zG=|%A+p}w0jU8H{ew~f}Ht++=eBr5$%TC{O66E4SzKFy| zC(O?UJ_x@8lWYXJvpi0Xx374!K&v}6I?OKLok*?7Y(y;pjS%b0r|Tg59`A3knRNv? zdPLYXBKay2Uj{8PD{(v$H}WX|t)z&^Hqia?;Gs-r+G?6PpA=Dq7_T8E;R(7~I9i&T z$($+7xX4KDb_)3Zc-V79Ub{BbH$>Al>ch`#diml0q}O}hoBFgEjIXg1@EXL5w7adl z(*9j`pGuyZihPcm345^Q=URKpH=o-|sYw9Uz7F*ADvLj$^D#x{`#e7L>Unr8}m-p zt_~$l=~>om9bK*da{lT4OCXr-Pm~J!;5t#x$MR)QatC%fHQgOSw>0Ii$!Od!Q!)8Yzq~VPzL@>c0a&^Xo6|>$Xl=tH3bx%5uooqGQORgT^do?=3X` z-{5>CE@Db=L(r1kdZ=rkx(=I^ib!Jo`&vQMM9-qpmI~S@yFEu2Fpte^RHvGjs%u@~ zFiV%f&OW$daC;`1VQd#(zSsxQ73>3+5;pmPaiT>PnMjv2yL zQnEa;Qr5$GA@ON?->!1MxZ5ms_pRtWO6v0(QM?wyc3S;|~|{ zSLaI9EZP6@RvY(nhGrEP@a&z@E6Gt#i!}ULyr^Sto;M;6L!(n~XQ-asI8hr|_0yeJ z$tK#v`T^!P?Jc1B1@GRGsxzwL==Nrlk|o=0P_%nUFQ{(l_8dcI^Wjdi`wo)|YWBD! zsyBh}Gs=T=Gd|bVoiSVnY+D+ZOd0kC?PDiA?BZ$MKq^+py8X0s9J&sYMKkb&Bo-6) zXEapRhncPU?|JiRJ_kl@U9cUy>SMK(ZZH&x1#fH?fsWt&7$k|fw@h~HdGyl|piNtb zUlGD-@|WTIar}w*%fj^~GxT84OKLpwbq`W|Y)9TWH++Zk0uVvPPwyK%&$k13kr4XR z^K3gwtC&QX2lOt2O7aFi0z|w%n_Tzwp=~zyfA$DO^5UQF?g-y)bVuOh&X59KcJ5uM zeI<}LIp9R&TM=)^JH8rZtwYDHLR-g4ay#zneM>-}`_8JjTkp~S)}Wr-&E39b*@uxD zr+D$DjIGsa;IsXUN|VG!h_68L(Ls#O(Td(|z+uDh4eE3dQkXS?HUULAC)Wmg1=Ns~ z7=~tak35KhpRq3Y0rTRRK6j@0LRCxE64SRGVW1M<3fq6i={c=y=GL`2jra_x=M~6Z@>+-^Zf3v z;((xE=1z3jRq`w?2Z+gYqdAcnfY0;LUDmSI5h%X1FL|N@^@nuV4ufDE8+D!j)R_=k zwV;>xKWV|8)cb)C2sB`<$R+3IS+CR0hw;g$!!YbG zD330XOmweBz(^JOCuih3FCH(-s*`Qc6zQ=u=K-(-;fqmy#0Yf6Y;ot=ck7_3R)rM? zPFA-qH(&5gBtB5>DR6I(xfJY24m+*;`&j&E!ca@_$gFvmz~`<&~D7Xta2uNPfIIKyvJ7mkq8(IUr9%X+;icK#+F6n-2HExgDJD{a+CAi!C~hfYZ(n z=p)rql;qOR2+-bR!TW*ux>V&Rs{nWS>eL5D`C{|)i0jfcHtp@34yYWV*(t7-aY4YT zDY7f!B&4%>%r?>;wjaSU3lZse_*yWh2d6mqrS11x`McV2J3TTjDI4_1ShZpD*a19o z;UAP!e)=eNaS+J;o4deb3m+UpeTkyR?oW=fTUmMachQDIG$qne(Z3Au=;ZFw0@4^2zt9e zv>#8%0^Plzsr9t7RE_g6YjvU#`rxw$Y8v5xsN3M|fbO4el{JrdcUo+NU@5l7Q6udw z*NPYSFn;gcB@jh&Grdb!9?a~k2Skno4l+KFrz-{;g<5iSoB%nNHc?$M9~CY(a(tQW$xV<6K2E zJ>oDheNetv85D06bU(fBb*}$NajQI)$4oOKaqohXO_Uef_0I&Ze)!u)_z03!Y0Dj zb+Eg~(d0M*mIVrvxPB8TYWqI;?M1SNdw&MpO~z@6dXoi=*Aa@pU=wVRKOe{g_PRwC zZ}Rtb5vJ06z3&CO=zo~Ne;W4vyhrO+?7`T1htJL<=&v?ER51Up41Y`TI&fqCt-aF# z18(!8!2=HxKMbP4o=DC;>G8A%*}V@E+@qIfY#%;#bS3D)eILd&x`}<2DDJ}x5cb=f z@M(#k_n)ZXP(kR58qM-~pdjx-?@*V^@0NWFGo=TE`;mM7?(?=e8jnMGP<&&eiCJGn zWZ|CF&Ni*E%S3?=Rji7bwcY>?0Ej|{R~eqhiPQc9bYV%u;y*!hzcHp zKseW%sl%Anl#A-NC%%r)%YkMwbw5ALZMcR!2?ZwZh4*dns0PV&SsDm!wbT*+3?BZT zz1ax0#c=bfUE6z{j=fy0K}-_y^p!ln+7uW#-S<62+>17?RqUVOoW|o5ckG~2_MjQV z{3Exy&bC#$%H72^B>tElHBsXAh|DeQKUA0%cgWMEnlTjQR9pdWo|OwHeQ5XdXcSfK zBp^~1`|BT93KTZAg~t60?~9|YX#Z&h+Js{-+QkRj`)~(SE__L7p1&Dc`i!$etp`d)d4GWca|klQhoYN z*fuC(&J?l-Z|9BeAQm}OcYb^N!e`XOr%odrcu|wsiyic}OwxZ5<2iJ-`~NKb`2X;*#_go+~Qpx$m|J)UoE^~ z_B?a!#if<#Bk(i6nuOYduPz>qdkL4i9K1>nXZQnvevYH3-3PmwOGpR!)yDK^-HL7D z@JCnISQR*`>Ul|-{Z$|SaK`f-N`!YWfsOCRbP#37p_wJ3pU3rPhv#hj>A8spy!C0f z@4a=w`&PyGfJKMXdQYT?S2;uUAds$&2TAbV|<72!0Ew7;?%|koMj=E{_Q$mdU zTlf*aC^Yb|Fs{P*-BB{P)RI)pkm zsLG2_UMa=*A5`oD?~&W^1|EMd4?QFdlXA94lymjz0UnERFaSiOJE(mh_z)o_J ziP^7^-v_V28-MnMyQ7xi1>uKD_y|;21nhQ2k0bZ`@$Y%wtzh4h8RDFKi6)Gr=9c#o zB;Y%1yCm{Vd`l~&aSqv3-?hGvb!zy8JJEL1AMg*6|}vhJOvr432(T zy#KyK2(kyhvE;r9@x5s}m0Pv->Adu>v@>Kr8i9MSFV*GUcIYgk^$~TILnWs{IUb17 z{*J9HmdZqtV^he((j)C(q@CNNH@2`D47|P{w36C2wv_38sz#e*R%}Vzn7*0DQ~h&1 z@o{y!9+oE7a*w=K`kc6q^==XBzWB7A;4fRYGeRGhbqaoCi)1(&eh*5GtO?%Xt#9Ay&e*(x0QaeUkuh;>gIn*^kP&)e~v~Z!@|uaFBuqE ztg8Cyn#k&TS(lMAz(Ic-1e!}Aa`ONMzCi>DzPDq{t~H?jABLP_hZss4^nPe3JMt8O zG9ed=Sc!$uC9jEP(ECGo4?N!9bDcsCx@T#get|P%!^_eCthWfj7`eRknUH2FNO_?) zT3$J@M}d_+Z}^L&fBAR*3(WZ56GnoG7&2z9)vUBJxNNS!Jot2ZLE;qHiIXvQ6`r!kw8^$36tKj{r4 zZS6oc?`zIGmPAo;Yb{rdMIS}kIq5a#h->viRg=qC(3OMG4a$P~VcjB;bmD(X%e$i{ zOH}8LEbHw9o*o%Y5F&n4$d%nt*Xc&Y2Jx~1 z3O7wblFM)Fp|X$vq^JLDF?;{yr~hk2lTR`7f6XtTHXz`||8$3f9=B*shBv%v+n2x~ zB;0JW5H>{)40^aZhtU3km3vm_?u%PVGaWACMAp8MBa`+J?$xV z2;4xHZn4Vrzi)Q<=FG~s&{ZP4+XGY62B`s6?9s3PQ0c!s1htP%Yzd+7k6ko3yVQ65 zJjus-j}&!gJLxvD-s4bv6B>OMBPMJh+KBoL@n#+P2(Nzn;97CGwF~p%B+rPG=eQ*b zo$iM$PT?)wVS>h~ownTnVYbitVuuh9P3jh=;q=BIPVu1^GvGpHjWci6>$I-k3G2l# zV8iHf9j2+1kwmzgb<+XDFFF}t@tm#2h|{v*D6^rWu zW_`I3jm^gKi}FsN3B{|Qk~ghfHi<4b5Ml(hhMGhp4Nn+qh>L(;|vV4 zPW-MNh%|`L*Vqj!ShIod2yH1Lpd9{H6Zj9XG>n}Z^sPJ4viZ~fidcevFzu%0C{Qwh z`Mj8<1ws2cQ=~BrP;^$_kD9KIn_}sv_qiqA`R0L}zwEOnCw(877TOSC|2L7jb@8F_ zad#h{Dbe_aOiK6mG8sjsED~``oNN_bF&5Rmyx-kL94Q)+`APD8%Sc~bCx=+HBpU)-17x9SeQg?MD4ZO>Z~ z6V`pMg9CaTwB(%Rx$zI!p?U8!4PNi<;&Eborhk*eLuKg})JqL=*Nz2lE)JjW%$eoy zkM65VTAZI1(>}7E2Ep5JcUXYspod}5LvX6vD9>$Zg2Db1ZkV+Tj*0R>1JIZ&<9Fj} zdab{NG%)T1@3`GO?$d6T zUOhiI$i9OoF&CK6@zZl3#EW$gKt3$&bpFuj-f$=vla34S9bov)c+|i;q^R1#$hb&9 z)%Viay~sMhl2v}gp_OPWeDSc@Wc(Nva&x3TrF9G>QKM zt)8H*z3Ut5OgB85PCf_8Wnos_bql5)(XgHJ5J*)c7oP)tLA2#wOW%=k{j^`&C&nNO z?;JU0O+6OoXp%c28>d0dL6^l(S?3c3#k&MBnBDY|-fVy$H!v;@E#v+d76Wx5ZyO{U zUsxCyefsuNg^r{EpT3bf@8I!Q``q!#aeZqC<|DN|At3{*JwXPW1%VE~F}ux6H>`rY zVM^L>ayS+Ne7nMyx+p{`*l_DW=I?Ycg60*&c_x0X&w=x&XWMIL+eAW2DSWy=nFojZR`xoe| z=alrba1EQ65O4ypj85}vFc@nzoveWDet75?*GYaW=KvX`-3Qufr^u?7eH>Mj&zKc? zQSOwA7_`XC<~iD_ayXV=byvcYi-X&ZuV<0{o{(@TNxL{?Hpwb-;3BOyfQiSa7n|nHA^yL+)xAD> ztR^Yaq=t|7=Xft6K#OMh$fl*-EBTDn2_st0hw>(o z{6ulA=tn7xNNh?WwQlk#DN99mw2U87PIIrL(I7-PVFS*Y#Dj()yH7Qd{$Prf`J`Ot zn4f(1Cl%3c(Ci=gobjh$u|C#M6fnr~@_r)FjnjX5WGZ7!Xfea6$x|T4=n<;3_Mwi5 zIHk^>yqG~Tte&HEA;EEEKXvD=RiRKmE1jC&ICrB)dgI;QCuy?w7_Fv_vAQ<422-TL z@Ra8+KPwTpQV>a7;MVP{_$4RRJ9ZP_80vwf2B~O`XBEJs^B`Ls-J41 zV)IH1GA-KM`-ipK0W%hLyLOTYV+#%50D~)P_mlyXih@E`>oPr)tOLpxgehC9iMQZA zPMf=u(uMEXCzCw|zEPYb!CK#V@!wV+asSFIPuW9T;`eAuOaI@QKT_mgXAQ(-5(sna ze&HpbguZIxwX(I0M~tx@R+BWUlQJ|e(OMW6SCFy{oU z>Q*qz5!PZ^zap!^ddU};+5fgf_Iyk1m!Z-xizOi{BdW*JQ5&XCPm^O;hSg{|x(zFIRP{m=TfY8P zwsCKWy)5qp8A9t?#76 z^WW1!*A0HRyBXvEDR@1t$elf*T8MN2Dd)#w*3lOq0x)E7*%zIJ=&nW_ewCKiJ(_%O z7G62xnLSYd{iB)nP4qc6u<-}Q&#d83ZC$x^aW5J}xm1m`hFqX@=07W}F%-uKIQHDO zSJ0#fs>qX-olBHLtq6}xd>%@42&)M>%10CO303;`$Y>Z|WD^kWavoeiS2d!7kdnm7 z)~m&~&y`TKrg2j<*-Tk8DwRrwQ$_0Vd{gWPM-cca+ViHohR=FfrX+lSDp>hy5O$tT zDDR#hDDi+3LEOA`axBu%5DeP_Dzh=ndGpCjXXMd#t6OP@yjs-$4p+NB2#r$Ul&@bR zJcJ|JeL0;L?5|+u#sf;5R&fLCx+w!j4{qqH6|%Wb?)m*H1_eDsGd>341JiVWEEet@ z+V6bB6ReI&qV_91^TvfqYS0`^FpT4ReH7*1vSr6T#CO|{JG4-p=)GtwVSQQ9`T@Z# zu0@MjUUC%L%>dnIoWgh|SE#)IH*f7)Wjd4}2t9gJ(Go9l>H9vBMW>rMR^B2^SB_~| z!2g$nTI>ey=OsPz#imc5epZe0F)^|P<*o4y4bJ_~mL$}KJ~zh@q_WbTR3$J{Yki*i z(eMiUuZ!tk%6; zq!i@;FpVnCCw4q`=%s@5Hc_rh$Y6W)nT^WbpoLX3+S+Cz<9OTpqb;0|(T6}G zD~NkrELW?3bHSTskO(H=`Hh1!Fvjve#pG11u>wzlT1gTSU?>)PbO|qWHRRQlMq6*R zm8fD2V1{}z_68|)`k7<^2a1E&(qGWr)-?_Nm&gQGBk;0LQmt`?2d;gTzn~Gnz=`gC z|FP<5kr@5ViUcC;YH2?&Hn-D=x3=bhv#4h$kTY*YL{@(5{Anu{FYNt5iTw5(-i-ix ztB)l+T0}}Og7Ar#82Ic{X81>85gVrT{2NR@q1hLj5sfkQiMflJ%6cnU?81s+Tw6Bz zZVrT{em+b&ip}9Og?{OQs_cyqwL{O}j3$++&I1@#l%$7TE-C7&=um_Y<%^|oUR(2# zEnqTWjw&dY5)Vc)+Ay{zjp57R&$=7JwHcb;yuw*{{)XA!zB5;wPXgaDfJ@=#;Hw!C z7PI%dQ2h~gCGey|mwDCN!`(BkfU&?GefgbLZd47}j*#@*^P!Rh+wbi^K4A#^svp&k zzUzqDaK%LnVaD<((s>ukMy!5>IedPrI7?NR%lIb4)zP$FMU6FcOj@2J5TOiibx$nY zf1d)a)2d(T7fe1RjZQxF68bMEqq#pqU3#SH20=_-g>lV8%~gq1HoQ3p%!kCewdLwc zLziLHZz1tV90_Yp7&Rlm?P~SM6dXpZP%6N>42C4OhQSmA+0k zE(R+ci^1=T6H6&`FhANnj8S9d4VT!D(Gh`@p%`E{ZzIeqKZW?DU3!#uwP#S#D|CPt z8UOVsnxGb)b{dvVmQO{REc}&OWN@_TLmu#ypwb|O{;O;79HR%T0)pZ^T-Q!Uwb6oJ z`D^(LPR|)ao^0kg2ExRyHNDSXby5jqUV8)M__|8$OoxI2`9fp2FNyZflA{8Gv}bQk`l$BZJy4&I7ctAa+cN;ZUlQ5kx^em6|cU*xTfM*FC50+IFj4`n}+OrJNL=aa$+^lXW+LcOSpoa6%v zd8bMUcI9mCD#nF=cO{!*?Scx$N#oA1UX~u>d=_5OHH=$QJ+`o?OMwc|Kj zDf?{%h%!d$tGSh@f>-L7?G?%7ud)c15+$Kt#UWhNXgdusloY>h~nWxR%zo<^IjJvs)uaFn;kLV;PRK>(7D2h7qAqBOpqht+U^FI^8EQS%d z6JoJ3lf2$)Rr`&rxICK%%lb;3joEPzw`NV1U-$*H6^SRQEjEFpr?558{yb*o}lYI`kt``gO$ zIwpiN(MVp_nVy8}Wym}cGY+$BbP8T}7_NRnAO%*Qd=w>i&Aa4ir!gx!_K&3(YVSh& ztx9nRGQW{8c{OD7rKwQ;h-74W87wZ(^X87>Kwdww2F zN0W6Q`JhdVLYQl>C_r3SBLgL5KAKWvn@FO9AB0(?dfHMe4h+B?14FFXmGsIjzowY~ zN+CNJ9y;UCHzN*+OSP}g?>1&Ab9k# zL}~+CI2gR;ik&L>yDB7Y!pTk(I{1}OT#0_)DoUJSn0@fK#f2ylzinM}<0y2GLUg%! z1)40}hSTYx@>-$=8hM_cj-rzF0{ag7<(x7#JaB~3Dxrd2oh?(H$|Hjjlf{76^;24M zy9V0qUKS(HGM@oaeThHWP&4naa!FF3{750YCS(aiwP!;$R;LOxu|~fsud=A7wC@;3pIXY= zjL8n7UJa+3Qk2d*4OqI$X?4^lV2-jR;gBc)ocC;d?RHF^oKB$+V>%vW96pH)_@z3g zw%WFkT=%XAs%8FI$)jUp{Tl1jSzYT;=*fQ$NSVUxP5rJaTOZRkMAY69ya?~w!MPwY zJkqKZ9AQi9MaOCC#iRZt@1~SbpcU$&$P6^Qu z$kmLa8O_xOOFvR^IC#EM7L-z2x6|U&ke=?#`YI~;OyLdtMwC`rF<+}nm7DS%FN%i2 zHj(x7uq7#=)Vu0N+t4v+IhZ~Z|~WtFX-8hrslyRqIWRmz(CzVeRmnsn?)rzE9ENshGf z`Cz21%e?%7r-X89u9?xH{`SO+*>l*ZrF!1)RC9ls3T4;y2x9bCURMBDC)NE|(~fL+ z-1byK(z??hh^pV$Es7Zv)Zs@g-3L0VM?9&-G`1=OPDKWriqA7n{R98@3tzN?Zp1YL z53M^MPr4_)O>do`;O<*9nu~4&Uv?^AmS0`u6G2_Dh|}#so}fC@pxfPtGUR2!4fGV@ zOald(xjy~7#qX&4mtnQS&h7N&sTpF|Y%kr&dFzYW13d;FRZ?xn(V*|Ed%QTZH$z^} zs=vQS`Sh+@oq_UaL+jMg7@J`=_tggsOZS4aG}BS~EEbhz#pmx|jmDkg*xh3 zRgVwn3K7=tf<9S6;Bd#Xuw-! z-TRHuk&8OK_YOuIachY>&a$YLO>nEgWFl3|`jJT3M@hUTa7L34si6@aN@67!p)HP8 z+4pskH5R(55M%8nxvTzBKwkho&Sp#D)a}wG@A-#!_+PM=B0k{1=3+0R(*3k%pLdrz zY*yM@l<;d=Kqy&>v3oXrOiVDRNP60b0*64bLO5&&+%11PIlAxAw7-`TAO(w|Sh0%l(1VPht_H}O{>4ZB z6@_-)FTWipudVe;k5SAcMMCs0j%|Taogwm6-4*@pc?aM;zk*wc_xoDx=D>50W3ce> z&dzi1po5yIhtqvT(rR-f8MAIZ1AVeajKDraDt zyT1s!dBtupDvnF3AnWdn+w*ZyL7A0pBP3R;z#Nn)K0SJbo5XqOr@Z|>r9MrjC~5ny zB2hV}vs}CRz1M1u4SDioO(8?7ojG$J8+AzT_Zs%1Txe4&O;p^k&x~r%rhjWM#5RfQ zGJ;3M%2(efuKrxs#+DUOxS6G-Awy0oi05ui-MyI`p;?^>Mi^S!Kj3hLok zQ87XNb_8a6Is4a_8_}^^Lir%Y8;Sv~cN@io|bUK$82ha^Dg9hW&9Sjy8<*Z0~P`FM)ii`y+VHpN?;9`1BE7 zmgYEbhhlU4^wggJ@D$Le^!E^> z;Zzsdw`^ayY(tQ)!qcG51_r+JOMTV z{ZExfo6cR9pkR+F3D46;p9^F~dJrh8i0qTOu|dkWT2sL#Ho?ZdP(5xuBZa}mc$Xfv4;8) zoSHwiPQ+a%%q!O}j8!VH`F6Q}lCKJrIpA(lCCn;FplAp?nrun)rFlzp|KcHAY$um! z9{0(pLCI#3iwa3*Z;M-Sj>Ve#GnttkAjPNB4b^YQE6+ zA+YK(&bHxp?ESonVzynp?{#U^b-Hjcvris>@N}`IJb}Q3BP&0VKM$R-)U@hP)93o~ z6{}|*LI*6F15yls)cPzTEkiC9@_a=rCUU0XtQ!OaKGlCv&aLGru$~1??8!USY;#u5 zzkTjrESLHmi;~^sXqP6XMwwpLNnT(-j%*}6r}okN`1n|BSu1TIJ$#U`ChfhF8FKLxES$l+h-=i|@G6JV@eLlbtc^UvP{)?JX84 zm!ld%eBIX$-Pc~Jj_7I%!?RuoB}4a&Fwq3%5HwA6lB768+h>)^)hoLxq#dy_2jmph z-05*et_j?7=_2F9Z_s}&#t+2P+q)t?7#ZV^il9!_4UJ8~bu!GQHb1<|URTcXbfhN5 zQj!{0zsas9af@@7V-+_NS2-r;H^$+tl1@*q{5V)dNaYeoNnpQnAD10%zMgNVX~@8p=9p@jBYtyOyxi*{(t~zTdj$2H&-K0eH zsu@F{YxsWX%S2QH8AS~$k-;D@F;UEoB*ZN^qR|=ydt~5-JEL9l4dEyU9khH|>oqMK zbznzyd-+S_hkL%hJX+*yv%3MapRG9__SKPB1r3ePe%g#k+`5_Qtxp=cRvsS7e(61E zPZBoVP@CB=`_7L=O8XlekNZf3=7VD4T>-;lWsgH;lOP>i5`+?N|Poutyz)+^_ zx57lN;z{^1rmQWXfSk28&fK?S(4l8u2dUPQ$qh2BFKB;CVUxb$rxmK7a6{$qHV+TB z3JB)kR4e{X&zz+h+Mh10@Yf}0;=Zd${hmGUNuedKZP@SXi#VzgCLI{G`jL%k!($MR z!mrg9XGI2f!um#C{^whjnzJYo!eQMvKIW|^Ua0J=rVGjbn`%~Gw(Ork4o>w7M-2#C z1mw|$kTlXK7i#<=>)UQlbnhUfjSu4Le)xG>k+~-luEQi0{;fudcoV)Kt>9GIlsrvj3UD&9;3iE@cXYiulF?_ z#RgV-I*EQxca(*9nxAu^aou0nms#C^7=6SsvM2Z(8b)IAE@TYW|HQeW`O?Wrmy$8H z_@HT^GV|9_5?TD{Cl+07WE~y)+b+0>UF6TDexAR=+o}o)!N`eRre@6FCP`mkI+WN~ zfaDMQ9ozNgX$aC2shW}v+863_NI7skPri6N4vrZu(zVG}OHHx414Z%*iWb(I(%UORqQSC7ezIA1l!=9clINsGgFv!wz2VY$zX#8k ztEALQoZqG0m6LOZw6T~DWi^>(BuvG!ccXGNPbc~2p!Lmly<>-bjx}?6nS~2kjIb)H zqjTkraFk(4-`+n30 zQ2X?K)sg3OtEaJlmcz@aNrx$lE3PC8Dy-LyjcsxGby(D4MPEc#Mn3$ZS(P+D_R>1s8ER}rB zbjguRKZi~?$z)im(VaO+r#Hpw(kbTextocp878J?AY(Ghkp}cDGqxcd1 zRsZac8|BDk-sKXncI!v$kK>M}ySXwX>(HG&$n3!j$Z9z&i}$cRe+1p#qA5`GBOJsy ztvPEwGcX5Z$c&*Tf>Bpl6$KPpr#*8P2hM#0hK%{6_pr9OfYG4?EPGZ~9H$x>W`4Aj zbm8zxi`Xj2S(6LEn9MVm-7%)RU)JL-)Dmu09hErc1TQ3J<3-#C% ziGjr!gE5(_22ECW>eRZ|^inC-`0ub3_aNX~5;ZvR&2@wuYrqRtLbXUTdm|)Fkt8Eaaj%iLZefIfG?mL^|V3&oH zUtweEIC(Lk?l%buPBPYdrnbLdjO*m(UfLwYJe%r$7&&&9{EfuOmmF0L6v*1+dnebRYvkRcuE zQVQZAWWp+PzO}%Y)K%+BG7fM8Xu06Tnnu zfZ*mdLZgxtgIS)8(>jC_Xi&){FvXP02u@W4Gv7Uzja}E$GIKN=tAa`r?aj&%(95Gq zNr1}?nBgAV>r3O&xq7O<5!Zf~yvg+b^Vxs!Nn|Et>Ezum;p}g^&XyV!<8c@zoqu2p z20-DZM$`xcYZ(*@^(NB?4>5h#d2DZOGk?z!2HUIDj3UN$F|F~{QxPugz#Mg>n8KF9 zLVZ_FGKs>o##=tAScY0qC=8=SuJM*}eoUU|y=6W?sdwohcgK&%K)K0?_#i8wg_DEu zT4iee_}92VT@;18xU*C<%;CfE5qT1^93$b&Nd0bKuqE-p# z*pwX!YZ3L2^`k$;RknqHzlvd~N`XO*>z3H#@8{NI9&>BNONx}&V<7!lh3o$OFZkT& zZ;8MAix1tvEnm3BT?4-IAFs#h5`$4MX;cKeJx%0^LQzzXRUMPo#Op2dtkR-@dTWxo zb1r0d?i~6%+nhS~6}DDRkQIH8m-KNjxbcWfGzMO0)B3nKL>XGk&_b;{$^JtZ(wdlI z>C`EfPTmcJ9WsAhMI!0qCgEC2(}a<^wb7<8#66b;IVU4$uV=Ah8LDNd4(Dk@w=a5q93+KT%3x=0NQ6)rapxvh-NinMlmNaO)T)dC#EsZu z7go#7P5ijrWCmo0v!8JVa1)EiNr1|wO9UrA#%)L8&;=KxT*O8H;y1YPV1i#Vu9_7; zT5=VB=5CB|`+IDZ7>A2>-OvH{&NpuO~&zKM_6AxLB<|=9Z&YjsFB4T)EGZ0kQ~iw zZftJU7oLg{7xx0jEsnvBw-BTh@J0f`!Y5d0#AFA_7wd@(7$M6fb~ZqECvs7D@ z_Dmi#i5RTb9HvSO$TGUq`)GB0tSv5Z;@DBTQxiz<j^oTPx$Z?16g|&-NOV4qM{nFpOiN9NX72ol) z=hE8x1fTkEpW&>RKZBF+`vVrkb6)jUo_X1Hq5xvhWF<+Ga4_G(Pl(_D!LrEicG@g0FY})F zzK2)5?4L3{v!4n*fbd+J=xvVte-v#`)dT`Q(Z-{2lVh*RX(VwD@&$(>A%c}qiTHiu zg`PIDqV}nliVHD;4+WZ^XaV3 zU_z7RR^#0x@&2QN^ehv1>+#Wxm49H;5 z70lxO=U@xhjjVMhneFu0*;;3Pb(!_GRi>u*(d^EE)S|C#E`a)q(5f46N#?W=Gcal~ zD&%>G*|R%rZ?3SldWz-U4W?%HkvC_sNW+l28KrcJ8q1cV(fLVq)r zT}BrWt+&B)T(P7|#>;+~MATLiJ*0}@ti&6jA~qZn(1?lgV_p;9kBJqr>#knJ?9<`s zr*C2Txfe0*s)xYJMP_Ef18iplmy-vzJ;e> zHj79Sc)#sJ_nP;7fWNrzMxJ=}+qw8Wmn|-R>|gSCi~o#od+E2*+V~`&dG}{H>*den zR3sg>T{MPn+>E<#z6P`-kYh=peUz_(tF=p8dK5+;y!F zcb^&dhMtcfKelnT1s@z2qqrg>uK2@1WjjjI*uB z>3ZqaujU!w{lh%r(#u^W2n0OJ?p5iNtyMIej9Sl0oL0D)(1PT&rw`Dcm}X;r znWcr3)N9L3%^o0YOgMJC79Nk~{#M-_70EKhIwFr`7E?GPWveqoz1d@9b%FJzdHP$c zOwOEz*c_ynK+@Be|%nqT7SPo8D^qRZgUMRw(4nh1Lv zCjhwX@Eu%o_JxS7va<+t7hOs#R@b+3%lmHSf>-<&&p4>)vG?)e_x%#LPrBq3t8n~% z-0;2|x!{%W;F5C`(L1^A?Z3odF8??$dch_Bin^6s?sz&c_=(@7>66bpe*Nv(SH8nN zk1AxYfsus{TuA)CC)f9M9j@Woqr@B9ClmwxX*WoBkywc?WdaOsp3 zLXZlZYXx&y76u8NBf(zA>r4{6o*<1!b&M^3GAN1TP9)}eiM>F~i6eW&7d$SzG!;{T zGrTRW;#D;vL8Y5txmh!W@=`7oM^faO=7?)S>@IxcIrUWg>}T1c6XLmdxFii6;@Z5VSSn2)C}$J z6vosU4hsz4-pcD?B8AHfH3O4TNWs7s)G+iWW|{0vvAMp&^3pQ3`UVpdlQi3t^d)Cd z_&UNk9HQ%N23<1}hMXke_TV_+6Fy_2j#y}K8obq*Dyhe6U?hr7Hzvd+u4ek6@2H~au`h6xOS$aaS+CQn zl@9FQZNK9J?+^bv=k)|OKf$Np{T4pMTY1KlXPFIwmkVhbVQ2lg3%p0}JGPZ%k59+il2N3ZQt>jd($kpz5VU*%6D?fdG57}SVgEN-8Ze5b_M-LOn8@6g#33e-8xrC{+09QNCKQNgyjgJ= zV`J(}%^sxPonmu!nfdv9s5M(mPR~+rbWzP26qXF@SgnC@BYtk6IT&T2L&OfLWjS+m z=TP+LSYKP<)X5XHyDfU%De`)UU3KzIu9z*NE})VnhaNV3Q;tJDb=ep%$&`ZGLW~Uf zA*w16Bn(_Pl?Wof2#a8PQf9iORSq6PI%KA^5`GU*_U-FZL~2 z!^+Vc;n4Rn)73~cbeJPW93zHsYp)JHH!im0NH70!NN~rIKiBoU)Z}I~A3bXbYufk2!%J z;I&R8d`X;2NYo__Nmx{4kqX?wi3CW+?>;j7@gy>1qAEhl1P@~AaZgq%jQK!-6-pv) zB(y@JO`2M3`l2s^%Yp3o}Xvw)JcpT z(8$Fz$A!WJ`5o%hI)JlKO67!$u&}ZEF1wOt(kIE-LW7J@ycr?SM#a%>NnR;?BZ+RD z|GpyXZmO7~z|iyeuSqrCP_%m?`_6--N5168Qtow@58nibp3Y1sY$7H9EziHgJvZIP z+?D^7b9z1?^q#}hufCGS8~+z8Kx5(@A9&p>?X29&1&~snL3$D71yZ-JIY_sfw?p1H);`2PVMK9vASG*8D^4@Y2TanC3yMRt$ z++eh1lGntLsU!RihDu&*Gd*_>bNkOh?U2P|N7-CDfebgvjYac}LckhDO+g{Uh!wR~ z9l=Ko1u(DzwI)+@2brGU$8cwth2zKAT3@D~yBMTEAsIzDemCexv=nMja5ASS8L^{N z#y#Ujvm+5u%B0AQSU!eLIhB=>NcB&JyaN{0$=#IXnJB9f@9`M-begFrT?(JMm6f1Z zy!8pb@@Y8q%;(SySwk>(FoGPrm7`q7S?BLBC7S@5Jir_`vUJQM=RSoCxRtGSK=0(# zr!J#=!2#xuo?_bo8}lr3kY=}9>~|-pa|yc+?7_zWv(JI<@ZoIzpB*^>Zk-? zcx)K)+Yv^%R+3PX{XW5BLd5KHCLQUdTWKP-DUf?8yP$adc06~XEAPqE267p&wR(c1 zw||Ds`NK>#lmjzuCZ;E;HQP+h?58uikJWyS|M}iOafSs)kmR3%(ee5uk)3Y=>6R4>igHiFDJ)^&8o2$#8aq$Cse1{`Zq%q%k(UJ5sT zk>%%I#H6*D%};XlGjQnYXZvoW7v~M{;Mf;A%%wc#&|KN{SCHOW%<+dT-1AbV&UrG2 z_y`+opxrw;_32A#y?j4&pPpw+gvQ1x7CFchyIR3+bth*MX9i1i@*o`jG|R`8<42+U ztl5}^BZ5qw#eQyNb3c_Xck(L^sr-w`FNdSsqYYx;H*<0 z=+MCn9>jsM9LI@7kY~hGtNKZdms8Q8^N5>>6gUy?dVPYk4|FK@wpd$UV19L(?$k8x zsX4N|!LTUeI6KIWfg?+b)UaAGr0@)9XtbwjHYZqHTVi2xf!6jm6H~Kf&9>7oR%evq zOfIa~yOfBXOgHpVBZAzLP^Y{T2%+u4eiiW&7x-S>#Hdaj-fW4!CZ|rN5P1-u)(SIm5f{0@gl} z*=N9!)n&A|$mXG^bN<0uHu*H0>xw;mBRu0@I$UTxHjU+Oft)i2& zbi+|fDIRZ2qn?D6MI^VV$L4F2?Ws>F4;^|!#HwqQI&!~z+S8tKuXjV5^jA7`VXyO& ze?coUA$`03Gj#{|Y_4OfrGOWoTlQHzsJ*qI;r4+Zd-byfzq^uijM4SeK(Zaj> z7|2_6=FX$pondorf#u_eX?J>br}vT7It0nUz1=7n}WHp3(iHkslimednjq^#rvo&)vF zc3aw#X=G$-d>zk3^5YC!0hmOQaxWxpJ)R6L;#j}^l&d&&(>qu={=G~d6n2h%hDEOA znFpl;#`ngX&UTL5_`-kx3BGWqz$+l;LiRlaj;t@i=wMuuxmch(+T+p?Z$~}wX)?&(0oKYpyl96gm7MmnfJ>!&` zqKp#Un^$bBAuO!z(WuEd^Lm^uqlMp4jo-LZ25-1-B|2=CMQ$bZ#X=jP5Xhv!c%48^ zrWmNx2sSt(n^i$tlT4pI!QR#?n`;Z~Zhnc0sX1D`8IT48JH(oxg_)6&qaJG>WC#n~ zs4_D-z1g#9PE4@AvcTfWd+1E`=uOUIOp}34h!a7VR!oJ^kdg$8;DBVrv++x!UUaVs z*vX)cjF0mPjx$xJh`PRs5O<-@Q7!09M%~7Q9AYwud$*d3dRx$o*!Oh!)Tchqx#wQY z@|SOer(flgz*LMoU4^9KW^@vjuttqB zK8dvc9!wI&l(ZV!7T$EAn#d>r2xcr5;dHGC(MR}&A7rN@@Dh$;mp82C+qE__TKiQ$(t}`6;-RCqcsMQ*nZks(X3+M#V>^RW`N5%-a zrT_-EHrQW zcd0#IEmW$;y@+SW`YvtZo^@%h&%Vh4_1gWTM?_#}uiyiJbBb>|zYgq-v#-a|sxctf zp<{ptBMGkwD8ADfHxnDk2g%0ezmIXx&(RCbd>%FQ-K~Pu$;J92)pK*nMQBaT&~EqG z*;rY}1Pp<=w+gLoFYiL!1Q)HGrXGqs8IE^Q_&2}D*)26Bq66hGPW zTAt#QFQS5}Cuez`P4`*IX-Q2u?#c77fX{q}m3!dS(M!4XJ1?wsSu5~>b1vf$H?p+> zw&&!SL_+cx(?y!+J)OB5=UJM&jk%duAtJPAE@SbIkHFDO+4r3Z`O_+JD<|(+<=m&t zcs!r7eE1`9=m(hVDpoFL{~T9ypFlTKYEdyyE0Cwv&=i9BHsQYl@L#Ev9(UZyJm$4W`5 z;8diZlcBK_8L^iEPZ=hMS~Zc3e;3F4<<1tdq@GU^aGPn@)?t)g{$YcOfu?dzlGsz* zm}p9Z>D1H(%7+Q7WkV%5N`GUO<&#I)UOmM`9VRB*v|3H_T8&!0#$Yg{k#*>HT2NDR z>C-O;NRgA-{y5PL%;%t%n2t#-;w{C(*u=(BKmZ}zXt(9Wf(3(VO)`71%ihj9%PR}) zoVc5Iw?}Vk2FWsPVX^9nLP5RE1Z)o`-pGX&jHxrd|6F!AS6N+NWbx!NdQ&qrJCmr% zTqlxJ*tKMzN+LF!_~EJvwQ05Dsn~>(STqtbonh`1@F93_U{}N@?hukP&Z|~n)?e7c z``c;}UsS{}eg2j3>CdoykLA?SOS$aI3rkS9WzK%eZ2Z~!;Tz%54={V~#c%84LW#6B2)|CmGO0?B+@I1sJPKm<1oN`)ER|G4W)7v z=O!*z+*sWNw73<-)M!rbr_-HcV`GW6l|{BT*XT}7(e6(9Zk2k?UZRa*^xyV&fEefx zq28WkuGL{ahaxJC%-hapK z6Yt>Ca|GoMZh!BM@XVj!P&Z83T;J0vk(9{4&9!CZ+Rld&QNc5 z9ClNcBIr^=)eAgy)M9n-9mT^4DpYUAkPK~80Eu_k@Ebz#$Tf0W79>ekW{gR^b`@i? z$molL)5b&_P7$Fv`}tgU=s)_v`*berQQ|~R0WW#E0yEQtERd!q}y9e18A8sGBbNB)T8=f9Ejdd^1eew+nLo+F9&u2h9wQzkA_8W7du6i>i@>Lm`q`ybl*cd07kGEBC)@kPjyZsex-bS((h2*H@UO&&2o%x8j z)Dq`K>FsSCm@pbCIGmzTgi)I&CUoA9Jd+%?g?Arvn`>VblhJH7z+nzYd>G1wt`9bY31Efkv5nLa?bH^s{G0?VgP(C+qVPfSs(HJu}o zj|TzgT-w>1QUf={_=p`$&Vv}=Eh0h?$_%gUP&&+|#&LWF7^~%YJCKds)V;I^4u!rA z&uWZsY|JtHq)WN=rrVf%;rG#U?(3x$<|tg|vLEH!_-#H`feXEmXaD#=VK%Uk3#Ze0 z_|pezb=AQHCJrzMaPcLyA{M=b^jvV&(>ZzVk4Nn11+VZDvg62=@UXjNvKWU0qLmJ8+L$2G`c!LU2Qn0kD%GUgs>P`krk!M47Hg6Q*O{A~Wpb)Vqt#_=bBjU0Agec+oS0;H zXt5O3n{A4rWoK{T&S_SRXna0i6HQ!qG02KLy+(ljn!4Q)>oOFExVG|8b9_a61)$NIAco?`Op|zQ*$)B6Krp+ zu(5oKR=Y#1H$|S+D2j?iSoG))AZH2bofT&T242p@_1D6Ccb>`a0=K^6Nyj}_3sfLe z{77En*ddfeB7PJf;U0cmW5reV3WZOyjSsr+!k=UIqD#5;#@m>C;j3tBB1o^Urjbmp)9 z@%Wrie8oGt_#A)#p7V0P=as@={K*^nvj6@5tNsK3_^C6_^2=J%y1G1f7jxiQ@W~JT z0w28N2YJ!e-$q-ss>L>5<8?pl1K0f?@B7$sGBc!?_u206qJutUZ8UG9CU;i3T6ngo z^Jx|WraJ8!87$U2@r0t(lBt_Js07QS<87I-?apEdoG+i@{1_z@dqDm2tTuhvrxVYzhzY7#G8HHL$bQE>|?_wxM zaDEbIq^Og%^Vx&7LyUU(l216D&b86swaE79Y^y-b?6}i7jp3%e?17zAOh_t z{|jDxnLmc;=VDx8U|oVS{rq?EqUQyiq@ulV<(Y5#*3vIKV8#PDZ}Pc(%TGQpc65Ua zlhv}_Cg;AK@A=7BL~rikL8PLf7jnr@yc3fJoT_`;+3$EKFZqsgzcd=g#m}}6_ zQj7f)wrpz12qs=i2ON={XIs z(uJ$+T9%CirCM*4g-$a1mU7GUePBc9fIoh^`k$E{W354qdZLTdA1kX)rBEd!hpbL_dLNBu zo2`uvw&zdKo9NQ*O;Tu1p(a*MiuG2Rnd>5;WJY{f(f!<2T15;>vEr7pN-8@8-ZwVI zTZac!B*p@uUVJd~7*CV=s?1ekR^qVE-_X#!>cPN4qIcu9( z(N=DFm!jmpt2gji%BLCr~FVr-95vLCq%!g<7mJ2)VP=lOk-_ zh$pfjim|B#S=k{CyR{~U7Nod3FTn<72P)Vass`bb0Guhy(U@Zxmt;Gw$x&-z6D@D? z@Fwvj(m=+Ptc*oY`NJloVU1(sXr*DLYy{YlTm{`lQ<xU)g6Wgu%Z&A zIygTV$I^6Io-EOD)8ytf4Ao*x#^lTaCc2Yst}L;BOd{xhFWui$!43~t#vjwR@vU%Vq$8RMyp4m5}k#>g2}yhmc~)8ic4yvja}%h zMJ#IY94>7c!wr?2#F;2+e|emw$;t#YN=lT1xloQ4lxW65%A0q^rxS>Zey>u|Ybpb+ z*JYE!jrGEAYLg&iG|;&c%}_6-8(gDP@%psL5QNi-iCWnxQlvp8xeOSxM7vM}s5}1s zxSu&*4{l|{9fs0kM-2m8rEWQ6DLX4#%Fd)X zwKA{p6CPtqi#kufadweqQexxlxQ%e2O5SKOch(^WTbrz}EV6Lo7>&*<-KjaUT8n{C z6x~F}8C=+iJagScxAE6#^=4_bJ8Z45u(Ys1tF=XMa)w&1#jtRH7ch__ZuSAz6}O1% zaC#V!lsaqvF{MsnN<^{V%h`D6pTc(zOIau(Gg+yLJ2G7l5h-}FOW97UDgmhLfTk`s zlEgn1^`BD~MZ8VGp876jA%T42y0XrbTB7b_AW2yg*Bmv;G3&j^Md7f&q;5#ny|I!M zs#e*~DwKj!?)7;%VxJ@<B2d=#I@$Gf4ip%Q5jqEW(!7V5X{RYujQaj8gr2{MEd6&t39Xf+8*49q4bn+<8_5_`ov#Hm*7_}6}RoAvK zD7m*P96Bdo^@8w{(dbQ6YjxRJS!ChVaXOtgz3Dl!yp34j4J-z}yXX@$<0^f}3C&!f z(ahn7tfk2OsM?m`cw#kZN=QK<4tacu)zT@I#4A{m&CbM5eK_C7j|0MJ-rWGfvQ2{f zLhyC<_HLnix7Llr)nt)9XCodh-0%|dEFsW(Dq-1CRL>F*{YMivVIN;KmBL7|V3c}= znr1Vvg>%LZt@mR8=NTZ6s99=n4+CTpQt zi-Lr79!M(ID@-JEKG6qkM37wl=+kOx=U7l~dPTS=adH~Qgz>y}I)5sN=H$(3=FaZ1 zv$M+D+9^&Qzl-kVewq{esGA&gKw&(d(dMXRF>W|Gjvr@d4LZ{YsJC`lTb^fo`zRBW zQ?w^$fm%$QMTP{IBg7?LLgBT1GpuH=W2;X8*GdxmkqSw}jpPIFTD@zLcWqNDPCHsj zV$?&Ff(so!4M-+u@o#KN&`7#_)>?|fNm`jKDoq&rADR?4gTWXf*8yv%jWzMEHlMIX6j7uJILnz5E!c0I>QBj=Yj4n z-l8a+V6QQV$$_GBqsFm?uh49`;UuZ}NPx~hIEv=ZM>tk^MLC9%a>O0F2B~PgQnI#V zrD&XdQwXT)B~y%;WJn;1qk_hb5;bHg4kmO2j3HC72AFt0-}0vCQAkm#UZaKQh}(*I z7Osf5E{)?XZ^0G`SBZ3mBqK`C7#a`H$LoQvmtOs9zTEs#BY{2I37QZ?DaJU5EC2g?cbd7*1UnlWY;3Hsy}iL?w@0TtMO_-~dGSPN4`^by$7O?n%XI z#Tbbs4T*%S!1C4Ty&^$I#}}s2z#&Y;(u60(&O|_)P$V0vCNjR@x84VeG%*bmp%912 zDQzwyN53SF27-(_#G61c`C9Y%;jGmvjOt2`#Q!Tr~p;3~UXMiHF$HEXTwe z!msO8M;V}^(#22VQ6Xsyu&LO^RyWqS$>T~!b|TttZL-(IzC~GN_>O0sdXXf=1ZgDC z1`owwVPjK8DnucZ(saxB7s?>xew$TrsZRFDNcmbW!Gv6dy^U3tPaI}zb%Az6nAz83 zve%{6odk0B$QfiU2Bt+JHJ_diG1|x2fg?@>YH|irgFt$V!%&A@zUtZ+o=20dlr|ER3$m?~6PM9r@lS0xIV7}p!uQz%eIJ?F6#tJJ-%hcD` zn3~x~t=Wy$v*6@^Lcp~OCh15NvC@*n6-g^MV~O9NDt+f@Wrm?Zkh!2=c829Es`qn z+Q5n6x|TM5VO$=fup>8`MC*_5>%o zpCV`)BVYdCuug@U>a=n4SS}=(BxQk77H~jH7!5~UK6*5iqN;h9!>JBfw7h>E2s?z z6oVZH1GHl@P^sspsk4Ojc#`sh2_uDo*|g$(PmNVHOMO+f94935H3p((oM62{tGj#) zj}0oU&}_}nIcJj1?Pb(ZQzuW*>~xr#o}*rGQWVb0u_n16UnrWHIBs#lNg|LvRMMGer4}h>C6EIWx_iWs zkdARmE3DATi&90l^j;TJt@1~4G~yWz!3ItUpNaKgeyMmKy9zsivCq&tbeX0Xy3a7d zNyT?)ve416jzpzV{MIMDX)sEr;F1K6=;D@iW-E>qGVW)N*MnPDYwQf`3`|C|UZYzZ zG92u&+uwz(i_IEr7En{6QJbVw>$A7J&0w$#q01wQFSI1MF(3B=F3fdAyh{tNcs3(j zedY_w=ny6)nZjomE&r_Vzvpfyrl#mkPJ`smHeAJPWBU6t%Y0%qOh%K@ zb0rb?4r29MNen9;#)#Q0rx_u38Y$h2qRf)@Ec*Jmhc|ZF%fw$2DTVU*O08K_N%kV8CQbt4IGx1e)hbzlU_>b* zn_zaUtxt)1Fhs>0ss>bL2Q$s3HL;zIunb!YyQ@Scl}x~hWovDPg=2Ry*j!+?mowd& zU~Xy})2!1sIeqCcuuXPN#!xb(uwJ60S&e8!Z`(vl zAnl}iEK}lTt-c%Qa6=BK>8jzvH^sfRy~i@C3a#D@_0}Z)%?-9TR@m5Dp*=lKqdn!A z(pZMWA!3}MyopRirLeAJn$=oN?K?z!XOs2SQ=B?>l-}et-N{+Vau=){0h{jwFGAvf>US zsN8n~toK%r$*UjfsmI6~&&n@s=*Bq4dU@>DcaW(v48@E%hm`L(XnjTzUzOMe3fEP{ zHwD?281RCPXAZTg2yQQ3GN|~UhtFhtPdRJKjc-M+b*U8tB6>>(w~md8g~eof z!u``Y1u5ea(WVg!Puj}~Y`vicF*PP<4$|rDv9qzt^3ptJbBXTsEP1^fNkN5oKMGwN z`L-pc^QK=>*_iE!kZT$GO2xJkP;{7yA$CWJZFe-L&4{@l@_TA_*>EN|~V&N=DfaRpm7Akx&FvPS`UheqoY6+G(i@^gQ8=#Drr^kt^|uCov8OZcQ#y3=c4bcND%{t zlLirSj7Aw6MC!CA=VvP85-?L$ekd%CsRiIOygw|3LRoiMy=ap zw$);1W1aPtWj42Vn4X!T)#{>Z{D?bL>eh{2y#IDOJ}4v|Px#7TY+_$E5Mn=wZi)U z7Rua|;q0008zy<0nwsMB%P&9u7dO9IE!NSeIV{7yWhL#c9ErT8I zvDaT?n6)5luxoR6_Mn;7$V`T4LB4kqTbm^_bypC10-f>L%z!J5ehxuT)5C|#`#NFY zigSt4AOk0E#BQuBv0pig(Kyx^cQ@Wc3ccxi-!I6zi*tES)?~v(;j9dXBu- zj?*O3pn0jWs{_hV3ruEcPtVcpOt7)K%)G4`I4wtAzVd7}iXYJkqBpUh#AZ#K3OMiZIjM&b zi65~C86ye!d!Mib;$hG&MT%6&ZY1szuZ1i~cKG;dgWO$Acrzy>l@!bYl2ytEWibhJ zg6XC8VoZL0xe|@1LIpp zXzf7~3?$mamgh&Rn(t-1xiawAk(Ufy@@O<59{;Qouf@!`ukH0k7ViEsc59W{PLtlm z6opkbwzgPUTB0|(52;PjH(iw6X~pWmL(A0pV~b$2nips=WLbvw=TOySyv4~Enykgn z))uWs(`$nk<3zJoZ!+6!u(7?&&dwI5F@?=tFvC}sF0u6Z3G2FJCad`yN-Dyw*5iEC zC#JSCb^xb9Sig46yAYFVVo=GPV7xjuq}9TMh+RM*Du`(?F>{b^cap93MHc5z(rT~M zotUKAoM1>!p%!CuAE4BeXq-;Mu&|&xt= z7^I^G;;6qJs=YIVsPnTbQxul8a&2JXH@>jxlKQqoQPwV7_ zYtnsNNY1tuY8aZeI;~otVzABLa0@YAY}TP~g`p??O*bqXyQdgP8yZs-rtbCxEpdr~ z5LuEsOvF*A9iVWDTT0?V=9%513K{XaV%)Q?bQ2OAX$UyxwB|bY_YPkz{wLwndnW^o17w(8d?O` zpD=}@oPu}^yjANbHhxB8h%ORNfZKX}Ul#GN>ZNhA;5rxfj?m3CWn2v%wAe)^Nl<;a zGh!^GbBovI6lEBSYfn0~KC6<^M9$+&)$5Ip#yyd8shhW4~^tV}DIL_+)-L$iU znaMWoRuhxgomT7ikexwBS8CXzAd{gpVhPh$Z=B%n-5LX1!`fXi1zDC;6s}N|hz+ix zMM1w`P-}EBYRK#k^?Z!cWNVnQD?KKAH5xlRZ1k65xJQQ2^#*a9B6!O4s5s=JlXIWRb6hlR_HWM@F(Cf{x zvAV?Ki4(LYcIZsbP^;B_s^xK)MH%R<$A=WE7*l6v|Jii99oCi>m_L4m$*CE-z1f%? zWu6=mN5)~aom}uLC2mB#V6dCSnAmBIKEaw|7A5gNFEz*T_$7ll26z|^Nm9iJ`3iqd z0{}WmXxP{(l!|9-2o|VR0!+}fM4T3=>$vy;ZL9JUB-q=~v5s1*;k_9W%}sZVsisA=b9UXx*aW`>xvX00Y zEPKP~)_RDL6^TAIBF+^}tcyD~cL}N#g=_xXP{=E4h^4Bl$K8k?YZ{25J2k2;q_8g=HE5+QjKcX#?&DxcqN& z+iWr2*kfmVgWa7iq~1fb4g)d@V-R)Kc^rR-^vjO{qD+LhcQRqLZrx}Gi5h zy9kBQY)sNV*kN;h#gmRUn3~;3t2+TUbW%+Ol1G;vajZm4Fu5utlVW{a-^AeMvro^o zQ(xUW;o>mv2>2Q!f)rjf*?7kbf5YY`bA%~M%%`j5ix?=f5lm^Aj@zMUcAJvnXOqE0 zU{6LOgV)sy!J#0KCrqp|)o<3(L)RF@I`Nnya|9!2=WEKYg+B*DVyYaK=)H`E9zW~I zwJ*^NUVlUEUXI7)_Y=0Hj1it*SfQ|3Q=_mBf7#3o%|;GcpWXhtSG^Dx_8N4uoOahz z?{BlSv&?RPldLsKVHylE6ygTv8P2v&{5|JJu@3Iz3eQ9i#`r|CP=;zDH?DK&H~7LQ z3gLc?(~v;6P$4sJL}^jifyH22J!a4Du)Dp@*7_2=o2zttQ?%MsNLG)|F69_EBq$lS zfJ|ykOzxxCnP6>sfra_wG+OIS@7qV7H?S(skxdMRIVW1gw9bVkz)$J%JIf)(gg$1*Fs5HL;_W8<*rohOxrHdmx3lk&PHighDwq4a9it zr=;UpBDo~G+#!f{%@V{=czflN-06a+v&bx>U9nh?cQvlTkzr6{O7}Cb;b>8x&?jEr z{=f&e$^3feB(Ms_h5{u(ht&PNunv>^O;5}d;*N)MjaWWbx`&c<-b;3kBP4|;b;apP zBRP1~P$P0PMvDH>^(TRwRDGj}M4fQ{gQ`GytR$|2PSwkM#|MIuuR=`bJIPL82o!Q7 z$Y6(4#}Biya5wE-nVIX+Y-VUtV68B;O1)+{{|QfEVQJM7f3uuCw-{p?=pKWC8%H=p z7X#Apy0b&aT`)DbFMEiFNDUD7`n!lxYK;bcE9CVF`g=pCh5L9 zMxN2=HR$%Y*xg*B7_OuBDKzhZS(e4dyd=b# zQiCjEB>USjR9NDf(=NEVf7a_Y8v9%9?rgHUvdrH02|Dd2t%(Vw*+vTkws1+B@fZ%H zKIpi{Y-ehYW_OacTU$@s(8mDaJCD)Cj)9rAm`VFZVDCEBlEq zIW#`W4x;?wbCT4F!FP26%g=R74Ozflrg(~y+wVs&rgQ``!WlI;l*d8xc|@;$$pwV` z@@H;RuDN2IT;AXMz;(aJAKi2qw2##sB}0AEV+;OMbhjodj6&Og+{SA78 zzVjBle4+DH>OjWMQp9|U7w8BsMj4&%6zxu%jrBFwSJv6v*rLR8q}(+AF_HL=C=;wg?D{R%U)GqfirQPV)w>1xJqmd`?h9GZt{k_kR3wB#o9 zSWhR9W<$U+8f^H8@a?b*sBZpVq3f}XbM5v*i~A4%FsG&dQre| z1e+c)>xD8HT0VYzpWVJh-OM*l-wCj`Ah9cTG9ePcyXA$Wl&tkAkr9y} zr7l+xcWtzKoYm;EyR*v1+7cT(TXcF8bSI~gyzXt;3IZ$I;e8C2%;{X!8cZHIo6ba! z)x~+{@41`qL&(Sv5y7!l1d?k)&Iu?F>W1>K_13}valUQX{M(9r( zFr=*RLb_(Wex;vEB~lwy0#~(~ki?t8CU{L7*|6!07HUfyO{=A&O2mOl+z7+CMx+#~ zuGnQpoR`LNlZn-<+kA?VL{di*%5ThR`OW%f$M8X~A19X&I&SGM{oP&2T9~|vl2K?$ zIxE!1YfX(}w8n6lvuz6yuT-&ll6tepur|qNU)U4FWV1%2w!_xWCc3pt-kd~hlUP$L zC4qd>G7Mu_Q(FBQKa~;GIp$dPmWl)`W(Nlf4D`gzz(!o6AM3{AGT_eK>lB4WvKqa~ zIeMKbHa8YnSzEEh zj|-5iQlUsr?;oV@O@ZiD!Ia`lqY}v(WEZ1ygZ}{Y%wYRFES|WVjiq~NnmuNwn@n_D zv|3Hn!sgblBk-6EV_g-C5 zPP55WeS^)-HTqjSNOKxf>!C&NtIWc)2&GJ>toj7Rjh9U3YC07gnTV2%X9LN^1eYGX zSFaCTDIo>_I}?dCp2a6hy*tTFZ<5{hRdzR4*xA~k)tjQ(nBEFm+sLByboPS8zWPh5PL{LwC&2UBLSc~ z&WOrU(WSyQPBr51PZQl$C)ysnB#cy?BVEoCh%auW9s+`Q0a8EGDMCV+*ky{>*R8$#AXvKFg*IgPAFyW66% zx60=BB6hG%)|vrn#tp`rB94fiRjl>SVwrbm5vMWiWyJ#MB!z&!aU0-Pg3u0Fgbe`rrxHo8e^A6s0^MAW6Q)Qk+L(1aJXoI5si>Qe8C#@8iVbn zv*h*NEN_QgCP5_smJ)t+FLAGubc$23QxzE67)vGSFZ+>hl!Y7dEqC$0D#Bw`9kk2Z zSWt%sVC<;Izp*80ghY3^(&4?2$<2Ml!g%fyr{oII)P|5>?H*TLetZIMFmZ+*G^H!z z$Ro*P%GgiOnN9rGrEER>1l^D8rIb%}*w@H)O_X4gW{NoHE~8*fhEdDL%1M@vAI5I2 zFw?Cw(d*D_w`eqK^!o*yo4ai9^-(qCbw^yQ)eU=ldvqt-Slg#&8Wd_77KY3!Qrkgl zLAFRRdCkEi20Jj^LHe$XSzs9ydte*1Tb(Fxl^Za2k78$q&Gl2f@H=0?E3Ur!@$GfK zZ4HY>k6ydQl&-V2x5QT8P~_7LYhBig9FtAbn5@(7uhQSXhyLCqrag=1%@XUU1`3yb zIbl=lE0qju4U!oQLpQ+jZWp7@F~NV>8n9B3k;jYJCbm})u!`bH0mc(jyhwa&Vup5i zip}*EHdmL~+1{i%F-x!01676;6vhx)c)?1`I^cX~Y9GzsG;1r1EF3>UtG&X^+*#y} zj>B!)VT6XnF-6%tECpo4))L1N0g&Vq#^AARNwX1bo;ZX;;hzh|K`nhMr@!6~G~VtU(4?=>uBiN0MH?I**^ zJjv;_4TUNRNWbAm=vT-!s$3H=npXV6{)-B*S#;SGgzAy}z1bJqE^cehwsJjKbwcQH9L z!{pQ)WDN$2!z}s)QPejWd`QXyAwW{PA+Ba71gAxDKP^~6YxqjO`%++l~W|W8cOw;v`LaW z*OlUWYbvw;Sf*L*-Ng)s=sxvDEKs_J8^A3zb`@1ZhyqmS9yJ?y|_Rn^h=yqtg z8wjwqz0KCvF8zMtZJPy?35`aBp(yKXo3y)=2tx+_0@G-sVi*nq-6k_Nikd;GxoJt3 zlc|yocad5hih|wkHHKnow(8`?E}G?zB(=NE?)p43+~TYQ`{+&WdrZdAM|GgDV%RP+ z7I%f!qD8&EkBN4h=5UpKX8~ge3<_a;*r2G-(3v7Y24V{coAIVD`Pj}3Ji4zLLXYoFyi>iDk{YaBBgDZjUaq+391^9jDiBqgx=&n z4xIZ$TCE-%OA9O=KSHs$K_&&6$7va{nB3#4Pzn(SRw$&-)ZDq8bKZpv`^x;$!|W`d zq^8@{9W%f&5sh=q$s}_D3FEpd9!^kba6xin%azL8gV@!&aa+Vi;r+}d8GTorbdp&~ zVku`#a1SxAv!X#GE%RV;-vPF^Qmseam6Z6RGI$2uSioeC;z1===>ba{1D>z&Tt}tE zoTc$KbgoB>_xltx{s!!Hp8vY*MO8%)|5skjuW+UNY*b!ytsWU$!B^HxuYNUm-11p= ziw5h17DLma-EPs&`^az=8EjIsN~WHntR;pxCL{vueOTDb*ftY%di&_rps{<3tiK9s z*&Sx=6m9bMetO+08pAbM`wF$a6>7F1v-pIuAd9Zsg$FsinCI?`%pXH=x-nQ!hZ|aD zsFZ}4q+3*Oz+Ox+B~v%svk-Y?pZBR$EDcOXIIdne3H<^)~LuC2@$@eaynYy=G{Dnwj8rVzq>UBzn(5YuN-d z7f+yaPI)eA%|ytJVS9CnV|U)d#{8F=X$(0yH^Kh>`)N;3Goa4m`jF-I0sWytOzt#g z+cg^X3@L<0-eJ%mV$?FxYqLGrV|Q zd~X@if}LTTO`W9Ho@1&viP_ttSUri^TP0^Nj#AXiH#lZ;fyfZ-5N{{zF(LkzG_E_~ zbhxrO4o`6-n&ehlVhQO`8#a;_HAswTu#&VOHF}f#IQzgs>dhvnPR+A?@)%}si@GG8 zS8!d4r`4>63p;A#T($$A-( zYJwM}k&MY=(kY0;M`{(XL;~WDjzWPEX{sQ4)r4=T3C}XviblpnS+%O*ac#trqw6+0 zmTBfe*T#Dp2jG3>{rJQ&98<9MjA)(2u_7G18DYxny#O>HH<{M?uaoOlMOEddp8;-o zJr{@|@@BnxoN$(1@WDEn?qMZovoNgN8pB$bR;NSL>|yp6$p-7xbdY#&J3>Jzpq(+0 zChLP1YkN(y+9Wf*9=&Xrd}p5eV4cDmHj4@N%rxEJKDv!2#l{kL?G*WNgG`2z0Ut)e zjw~_+hE9UVdO5F1=y9IQHjEa1LWU;}Rk}b)+zSbgdIDk?A**;duz){QOIB+!H+K&E z<_^#=3QiomhwYUGYQ-M8SeJAJoOjd|cTDTPh4$ne=RM(Kn(Z#9P90}u{x}SF$Wz%e zbx8n{`D8cqkRR7YvlL!0NGnN+iy4`RGf3?0R#?=O4C>H53z+>-Fa!s?GJKelQ7w{y z75%=DB!o7~N@>Yn_V_>JNhij~J<;;`PWLWP@an#CQexgqd*U<2%8D2KgMbX_NJmpD zM5~BE^>TQrVkNOFj=$!D=zY?FjUD4iTG9lpnk2?%`fY5j z$LvItsd}GmZyD`xpqjB^yKI_Snp0=dX&Q>{MFyLv$aROz_%0fbl_fs#1xqs$aCWTp zq`Z-}ayKMhx6pYjw1O*i!`s5&R31Vsbu78lDbt}-^RKt*%%08MS?7^wIm`3MSz9=c z8TQE)C$4HjJ?4{6W3f^&0P2%->^t{KG~1Ibo}6cS{uuOksY^x{tS{AK#dTFBbK>!t zmjiK~-jVTzYDHLB62N)Iy3OC9nUvi_0&Dk2}VjCk`HEs@}RvmtG zU>mIUo2(Tb8qF?qy_~je!rlrDcNx%NO?wQQ2k1@B(J*`TH&0UREK!p|bOsZQXQOHf z&Ea$mVT^meOQ$0(tu!tg*Cs3>Gb!OlB+4y`X=2qC_i76#i`1TC>cDwS&mCZ}yTjs% zqinA&QBzB9T>=~J6vg_uS1@Eqk=5wVox|M0Cr}hHf6v`)EuSJU3TmEErPg&X)3_Iy z@@NqRk48^?G^0qJdD1Rm7@wDHZ;9UL#J+4*a?+TH`>Dje7!Nav#k3~fRUepR!kFP8 zS%xI;Y0zfYQr9>%01|mVt3>jaP{uunp)`>pADo8nE4S1K5c8ZImfvF&*`&g8pJM8;>g!Xyi(N zeSxF5eVVQLFEiIs4or2Jo}Q-JondQOV>jzj)Tb!&9-6no_lc8iY;H5v?NQ5e`g;QgyL+yyo;Mi`6)E<}{FFA3p8EX(^+uCctAP%-*jzr& z-u4Rn&N{%sCtbo`ZIa__1D3Z6hC}$s`~N4eeeG)>b34|f>vir+8DkA%TyyP~inYajcwTRcpOGPATS!Cj(_3>?qc|KV;%Ow!!Pw*2FAQYxw|DcoBASdUBFc6a~iA=uMwRqcy?C`Z5bAk1{neMQ>^r zk(vwe5n3ePH7BqntK^q3rOvz@MjXuq>|_??S`ufV(o(ie^rD|S$!N!qaK zeV-ry_}90|R-gh#GtY#zQ8-@XSlyHrsk-wWf^8AU?xhuGkTJ=(v|zSp%EVYc)ZKZ1uO;?e9U}#?oZ7Z)xTkjkcja*kyNbouTZJ)tZQ@ z$1U2)d>P;2f=udc+Xj362Az6~PG^tS?mD}>^Xv^f6pbl%$=S;$XiPNd4c6&zEi>F( zN7^%FjY$f1cDk9#ojjRwq#3cA5LGNzjf+>wb!`%ukR;<)C+zLOa_VW5%+YL5dag-<_->}rfZI zlgS7KN6YS*7O}CYT9R~vWL=Tq1VgOKGzX&gwhB^5`JLtZ=8C$r zoSmPMXFAGWG{)4>tkLBhDGF@YB1MB#9%C9h(~y=^z)`O+vGs=8WWxC?e}!5kJY5-D zr&0L{iE((>vak01Dv~t6KU-;l-? zI)tW5NfjI8FzL&Rg7XKjvN*XrjQ?j5=PTBpxskE)`O;ua(pLdX}D96!I(`rnkM^GE($ zLU{2D{}a~bkG}U!|I1vR|KT70A@lkC*Xq?O#D z#mFf|Q8Lmky1hZR8-^^iXvlF0yb`p^VI>$+Hf_$bNwIp$WIAK44QYLeZf?O@8cLi# zVKjR{nWUKI1>N#9wArDQj1V3fwCe7t?)8&98`kRh$o`D%BqVtA1BGpr(rXAfSZ7|&SVUUT{M5pKUClO~2^gojT> zowq!CoyOBS4_e#Ttjy%SI9P)>YuoS~T`=cOjAJ^kSlj?$*Q}j)Hc&(0Y@yECz zCpfBq;8Z+0T~9X%(ZYRd(y`uMh#qnuFYF>*Ksb^{`G4a&7Xj(wNNV6c(j8@~3!=96 zxbZ#y^!~uWd_lG`oEd|W?l8?2-W{C_he>IePKqINSPasM<1OXStL*}%!`acH5e|X{b$2WA`ZS@n(zbcIZ^&eS&E!e7y`>Wel=ivA=#q=6AgP)@z)-`W9Dv z$>q}GT!IuDyu|ASt5cG4{3}^QztoAQb`6RKCv`N8fE6AkL-S|6#`%=iLE{rfNyaqm zXzMMT`Z-ojA)QdU9GxVTi;`xyVtexxRcy#7=b&@w(LV9^GYFW4!1nZ;*drbEhOyxr z!nXT0K%YY7`cd0~-$=}TmC-bG#4WSJA(cQn6AG}@=wixAmecIlY&T0bn_H%{1?6}W zwUZiadu^zVjZ$dJit(JHoUmWtaC`k6y<0OsIYXy;q&!72_@K{nhc(&|0eLj}8wk7h zfOC+?F=>6aa##b27osFxgs^i|5c*r{FhPjZ$05b3*W)NL%y|xyoE{}1@2ouB%L;Lv zt~!5|;p@en?=QCM1DyJho&I_ErGIf<TqZYpVSYpDr+}#4sW$Gsa0twOO*c{DgdZ zhA!s_nPMZdMTMxe2>OniXc?#f)*n=A-Vc}mgBg(6{Kd(eixaZglpVGn0SzR*9I~sO z4-J(9q_^QhDO2+43Fl==wOw*`^%R|?%ok_qEJa9-_W^~Z22zH@dj(Q6TRdPqnz3D8 z@%-syMzcB7*&JkocQ$M)93kxesF4xk5K(#HH6Fh2VQnr$W8Lfg?2%-khmQB5n|%mn z&nD(L>Q@|PX%92SBkqR}rpw{XiAhYdk6aum=*OEEF}U5GJfMY+X&|A*9q>M(&br`G zmq#f>N8WGmKQ9@2*~uoeb1(}Hxjc6&Nw$kG(0H2Y?c@SY?|NKy?FOlN2sNt$bR zy9$hBGRe`h#h8jTA5m}jwDp=&D{NKaMaL^AGiI{|+fH$FwW1RVLTH4wXbzFprfX4H z+`spYrr)8>5|>PIG7rVY$7Mp~LOLsvBB8-k8Am21;{q1B#@0KwO@-A{S~a3mbJVnC zlIGOAD>j!K((x(D_yi$SgbX}5FBLlG)uIGe2%M1UK2gB;@UP%(yvSIY-OUBCrlcZQkaNa38@_p8>26!@F*MOGo?fjUcV5% z)w_862u(Sphaips)Uuyk^jtZ4K+D9bjqo0CZ7fUay{7K=H7Y7u65)}G8w~}ZP-^g?9CRJPN_wS z%nCA9qU$TF-34`ZOFq4a%BO=i+W3&lBfSr?u2Nzm9!K{`BOlh`NIyI)^xWB)ofAF+%SGSx^zQ1=Zdp7&$r+u#LOz+ZTdlZ!`jn!~n9fg8*(e~I1|6at zjFSk^dCC0Vt7O%d$US?U=aAnD%6T2$UXfOPJ$J3XpDOP zqaPv_!*tCBSZbX7s-U|(S{;kHoeRf@h-W}BzZe%HB1P1=T5IE)S4PB?h?}f%ju_{V zF}iq|^nK32=;Edgq&v(5eVmXEQ&L zv71Nn9s{%T$a#MhvhjI&9iIcMa~xM0cWLoW8~^2p5QCvve*t|oG_6virKj24a`EV2 z(XFpJ9VMJDW-$#a*T;G{s1;C+WsiW-TnHCE=7 zrQsysv0L3xw|h)J$LJjLbFyrP+}&Wdx0q@}I=zn^O)>F}sp3S3YT4d_k6vK&BWUZ`gx=D(WZGlGFQdP;Zy4ubNS{xkcy;+Om~4kj)#ahb0Dt$`vTUloQ{kN{;<3e9J1G? zRFOq^Ky~25nqEd+hzyd?LwZIu706>mThG7i`FrBv$uKVh+h3Syer|H z`PTdV;Lb1p5;>ZWzUROBjqm(iIQ%=`_QL<&Z+Y>JxA@jqz5i7O$R9GUVr-yP=v<+^ zA*CVL7A+dKs}<{NhZQZ`MzGm>+Rh?@th=OY_sDXAmuWow^srj@QU`sr2d5=FC-HSc zp*zNNLsqTX?Vi)B87`mEsS+`Il`=n}U0-2t9;34j$?P6J&G9BeyZZ~23-wp_Nnt}4 zN+4MXAD`d2LXWN%oU}0{<&LVM0Z?OXGQQA(BhKpg^i_M7>?x5d{DRYO$ilcblIPH`SD>LEk9XTM; zuqwrY4#3g+zK=>AYFnR_6A2qqsW9m~DrN$X9W)1BsyOzA-wmtqFK9OJ{-b|+-4n-+ z@4-@fzetgi&9{t)8XY)>C5XZUXhqZY4dBj1%QGe_FAr7*iZVo6bcU;J1lvNRJ zyq-i!oN2jv`k3XjPe}cqSI@@0{_s9|QSjv1MMP#v@-!z)3-A)1ra_?M48j|E7 zlT~Yq`58`RnBL_a8Jxs7vWmCbV8Dr*#kd;sM<|idxJ7576T@obASaB4CQbtSTb^}3 z@VsGGd9q}_I7Me8gw)YhJ=ovF#1kmT3-V&j>h_A~ zmzRvTTc(RsbXH)T0urcs*vcNT6A>S>3XG_A#URDS0`=A}}iGCWG9^4RRo*3Lgvofq zWOhQLvM_Bt+B6^p#)O>n`PnNJlPR~?&w2LvGiI|Hqv-;4igz*^0ez6`dy8-)IC(j& zk^}4Bqk9dXJD3QixC`v2*GKmG=tG_31teP3qYt*|C}lcA4-L`-=Wq@ZB?n&Qos^+C zjXMNj9H;I0yD^Z*7ww2l633}G;%?A~A10c74)69kL!|$_O!Khwe&LrnFrD2o?|6vA zj18ebIM&55hV9ee4s%f_4yLZ*>kbg=h%P)ZID14Sm0SQG~JrB(-Su9Ev|Dk-3n}AZl9gs=XZYRcgS+l&$pWuO)X9kCBxhEvsFq817oU-i zCnS>vRuw_#;w)CVu(ox9aVC#Z4AFejuY+(Ah#bvA5zmW{MM5|m9drTXlS&-~(b1jg zq&#GE$5o3U+|ql-T&fd_)BALzDVx5@sz*bP3I&3y?^i>_~3_eMg8dT?Y#M(_~Y+>-@o+_zQ^Bx=RN=C z7dF}ak^htLz`Ngl`!D>HZ-4Dwc>hoM(YN36@B9iT6z$j72&oWSlO$>2GP?M_R}zO} z-+7u2iliVPYm&C1>*~mkOh^}Rk-7%kRw%Q>RF`bJ7Lo}hQ&f_ZWGO01Q7T0#@G3k{ zt;p%DCr2^K1t(cU)l}^3J?Jq;6}WuCC@V=ex75pP%x+6MouNlFj7SFUo>U%h1kS0$ zKq?;Yf%oVRTEgh;cH*!MRWTaYTN`8kVx1Ggoag<)tk+-cdN{dr7AX|Q`YbXR!A)|ZF~)sVl*0|rNWsG>n(Usl1S22Q8zX9zGk+VGo78VtZGzw zLhUl{jmKpAineXTh1Cg+PTq-!wEj!Xq#%JTM?zc~LlF?4>Zjiz)RqkM!- zG)|n6%8se5VSmHz@|In=EeL8-)Gfa&8;@_|36ylHq62C^t z%XZ>-*Pb#$tG)Lji~1L>&tD=|`t_e|e#D>s06zGmmro4e{OZ@?2Y<##z?)z2Xa4$E z-+W=J`eVNP@rS(k=HVyy=2yS|EB)%VO-*asfC!TbS|%td(1}8&2}&iPG+sz{78>UQ zvMBYDr|lV)Gpr8kvXSZ-`-=VMIjhZ{y>)apr`qe#fXJ{SRf#6a3KE?mq@tCYYdfOU z1=DfO)NI*SH*8G~`3xs=(&;NCPAPTQH63B)10qR^0H$|Gd`B0wu=1$Z^&6j|j>@A|bDS=# zsM&N!Ao>v0{TJWIdVhg;E(T{DZ*TlvL(oego1dR<9%YIjHHdeUhYnN4JA6-$A@2;R zJp2*n$luMVKmPo3Z~?htb02=La+qp{+h2TnTzKxZgl@Oy^2tZ+uAeX|1ozHnoSrOD zI>+e(sS9kE(0NTq%Q#7pNe0f6CYGi%NSz{`q-z=!8lgizxsy50Yj6&w3sNZ&wn8g| zHyz$~q*`G+i?bbxmQ2P|ilV?Y4W_j`eE14F&$(IcsL-(QV0p_M4<;;1O;arqX^EA= zRERV9Y71>ek~j+KuwBdLvupm7|IOdxz5na~<(F_-|2c-vcfZTWAHK(5G@$rW8_hh0 z)Lu~A9Ffd0GH2}+d75$d>Iw6D$+l`SazrObwAN9#HEq+-wiUu}V%BboPExd%w25Gv zOD4sH^UTtj0m$1BcNHHyrS2w7cwCqUxI->$k{6skcu2F~ zv02`5_3R0w$&~SAg48L>`iK+pVQT3^(_DyFcW`W*DT zNf&q5G5)Aid@%__4k<=%5QM*&40Mb*y2F(_$~OLa4d}1i$B%#d2;TX8EBWZBKZbYz zfVaQI&-rD2{x9NVdiD@!TTI*HOgKQSG3W;QCGczNAZM*mOj8{yM5$vR*!C_xN8hncpKF-@}L^Oa`Ob&SS%+F4nfNMz#@2CL^5t zz-;W@yM9O`3zt1d)T+r~q6~Ho8_kgMu+b9d#0#t3(2@Gcha633lx4|&w`RS(Wnb-? z%w`njC>m>mZrgf?b0RQ2y<~BEkI7`h&GmC0KYqkyI%m9CkVM9^#SNU{K_~8Bm2 z&`HR%jM-#__X^W>B#A~B3F}?O_WG7$JRwg@8lbAT-0pXrEoMA_{24M;I5L#AqyluQ zSTzmRdW&iHc-N4`3+fjywg0An>-`_R)X@3pd*AeLiTC;7FOXh+sg0&_j>R;^c8+bm zrc)z~E?64H&TFP=!dNvlb&WDxige7VJi&@2xSq|P*0yw=#kGdEs%Wfb={-f_nPi@m zQBEdms@*euF~wz5C}xbyf@HU3cYDR{(~lX=&q>GO-)-YfOdmPv1V{PZQVg0IDJ2FM z;pgFv@A}3wYGdqC%vH}3lSi5!e>4G%^Uo-vcf)!ra6koVIpw?<(`+}aSJ!Mdx6I}< zCX+czX*w&AO2->qX*JpPiwU#&{bhgRx-rxwHKZ_|Cfe z=iO>w=++J*@cy+p;F0L{pD>^)(3+AM&I3zU|++TPghCd;bS~@WT&z^9x;D zza#$c2l(%N{~z<{y7sDC;-x4jpGj@u95`5tE`hUZ@N6Rl&$ z;}L|LfvMXYa$MAbhvw0%gmQL9IhsZ#X%*$GDu*35j#|5L+2_enK8O$YpG-1&1V{qnz#+HzneDqBlfFiouoM z$Nu^rjVF$>7h}`apApU-Hb9}d6oW)4u$<#6-1TT5e@C_y^rUJq>-fl#?xE^R$X}?v zyaRCmxm@AnMxD61J2;)Z@Wc9C9@W)eG9`|j=Z6iLzav%Z;qE;mPaLsE5Bcr~H@O^a zMk-FHJ*g6O^_Ht=AF;mrjInmyyFcUf^c}hx z$7ZwU$;CCsdy2A*>4r9J1+3-j>V~hq_8MuDVr@quD-xZdgy8n}ih6fTQ`bo0$r8oB zZrJR;V2$RFzUAL~AHMsszq5rpD6c*g{;S{e;v3)OYaf5;U-oCd^hWb)wda5R=>=zH z2F|mySGarv=?JotwaXaEgh`p=O~r11i*GYTHVriXbV4d11*CImYj9nMcb3l7tlEm@ zO+_jU&KlbF7L_j1d5TXml61o9{SmjH{)DSX{|mFzH%RBNkQC#ASJ`KxyFpJwaG5(9 z*=O$P_A2f)W&K0#y}&vforQ5$aDr`?kZ-}1zA2J(HT|-&1a%hS?XzVVxuU^}Gy81~19C9ZLF;Bq0y3 z$0L{JFkSJ7M4`TCadA>Bhbs2@VtcH^`gv=lU-yqU-}_K}%s2g8-}({$+hKP2gZJM; z@Bu&c{+Hr9f9LOimv`U#KL7a9d%XANFIvZZzz;us=U4dEyQ|-g5e4D>q$N7d(3zv~ zvB`2_O=fI|5Q@%N{`}DuvoxVKmc6*f6;o7NviCX8C?-1LWZclSJF5L9UX2my7%Ovh zkt6YBrAK>*>^i(LSZ8Rvnv3n0tL+wr!B~gcY)P^bktK+vARXW1EGv2X(;w4ro-#Ul zlWcwundI^E*9RV`$dL?q94RHjMswg%-IGy6EsiyMy)*?IFXV^y`e8E2kku|C>(OHo zJzlA=dmaqIIX+q3V?3F$++6Ye>XM?^G8vzcq$NrQ{-$%GeX+3t&PHSIX9d-I#qHGv zResC-FXUBo!njLL_(u#zUGUl*Nd)a!e;<@;t+|24fBP&hL?p$6Q_Cuv)E< zQj($qT}3K{QusFLd6!o=m{;#}djFK?&#xGbOX_OJ#nlbfZiTcSEhHAf)pCm!Df8EU z>zAVK|9K5$DD>YJKm0)WZ~Vg_@!q%J`FB6jEG7%|;tj6a8t-bnX_31vs#;>a#d}GW zj=9kpWuciQnu)Bb+C7z-V$)NEO2ZmNfk43h&KUffxE_bg-?0|ML& z{ln+h=P&6s{ci|M^Ue1@9K2rdedu}bm;VXHAARt?|HfN__lKA8-J{F$TfG1EAL2j! z)rYowA?_TyazMufXt)q+(54{;LL?-qMCt^g658?s7pBJh8sBxO?iMR9XuYQr3EO0h zPEsbNW>R>BU$bp0YQ4aw^N@HZZ3t)3DKgDb2nwn2u0i@5-&s-v%C@AeY3f^6Hw}%R z;<}E@Cl|~nIa;M`x0g&8_bDgmI9cK%b27o^D*0s3W_iW+^T&+xoay46G$}Ds z##Brbrln3Iv|@5{PBEUa-du9=^kc@88MDQ`5PR%g(54bJ@;x8jMb74($>odO%$QRy zkKz}F_XsZ|AUrl+v9^VjAcb%?zCVue@yF4|y*5hT{OvXlKGIWDGF`6Gp<5aM&Id*}M+ zD1zTNWl$;YfOKciHZ(~}YR?%ksppRn(sF$$X&v_8ey@V-ujLkf%X9l{wp zYiT=0D+N|0;agDxXDq4c5U$1>h1MmAoUYqKyG5sf&{)^tT}Pf}q{1QCv)xvdqX`es zUS+f1@UwsUGaQ0(k&|T#Z#_wxp>>MPa=aG!wxQjud4BO3_s&oFM1=Q4_?SJiitWuaw)HjpX3VZmxiS@#91^Xl%nrknY`j1wIWkEP%rYOM$DH?Q zSwNbD4i9^xM@*9iC+(W`YQ=6>vGg6A^`4vS4YTw6Y;TtAw-u9!6x?MA!ElA5T7KwK{#+CWdm@CC>e#W>Qb8~aW#nWfxqmtQTPNEZ9 zCkBV0lm|Xpzb5l9=zu~pkUVfiWgm6vkFtZ0;P)bMNAcnaViDFJDke4cF!o+}-={># zSbY1x)hBlNm+;>{r_+p6RVT!d7{rS%_s>1Y^{@x2-kLm3_2Mp{(tt6apS_1fXd{2cFWXdJ917mi%l*y@t?%?;JQp>8H@ zwjNE*qzHAV>ek5gmSi+T=rlI2J?18G0v#Hm$Dx5qgQhG`#+<1WPPa?en=PBRLOH|D ze^lF`iACOee9Cl`((qh;Shf@tyKT;>MAt)Aw5z=Y}wd z0MI^cy8?-%kHqvxX=MR4kM%D#UG}T>;mqi38%N}i&(*zt743)NhCkBP%NP30y9q)5 zFU~#}$4Jn_r1wrE-XoUc&%nhCLzv8Ztc_Bwqu9*jdOVzuN)BIFKaq9r@O|6JYF0v` zq+`Fj;`wJkq1|3_K1q4y?39z!Gisw)S00m$>12j=VSAX!4kZP`8@x3*DFZBDN;1j-m7C%@qCuL#O_-i?(+zA~VADE!^%j<5Kg=WJ=fUsp^iZbyzW? zHL&SAEDg@IxYY&1+n`y|DI_^km*^xzX$4-Pl#V&Vo~={Vm1d&noZOo-Z#Pu8SD2<| zc5+Tuo^pPA#(KSGSFKsCF3?Jl=5tUZgv!vlMkz&-Xq3cjp;bIPX|B19NnVsg8vpv;%$@RrEvOH&ca)!=I zY`j?qS-wM9iP9x!_g<%~D=x2|v#*~pUo04pXIK$ZiR{p9_8GEwo!W9R3B)O6WRv!Z zBK?+H%5Yn?E*O_Wl!cFJ91Xnze1q@&qCfJ%-~Hu4+kXQ-#4tbigTl@a)4K!Y+dHsA z3Ap8a~{4rWwTmxb9=*n zzh$vFB`-!8=liUVC~J}jovHYI-5XfTVP_qCCUF3|%iaJKyXyFFcak6!l6?f_0qxc| zZZFpT{@>GU{M}Jx&hdrX$DHrut&eyC<#q?xcC^X)T+REr(jh;*K0dnj`!uHh2jt_K z;p5Lr_6bk@S{#2g^z6S8AB|4pu;~JX6L&PQho(5Za$12f4YyA|nGWWw2^ zcJz=}tkn1EcHtCH_aDF=F&9}b7 z#oF-blP7ddgW2!cuW$M6vo&vgiCasPEl3XE4cJYDxi zYBb;GYwyDMzW_t$mpjqymkRRGfEmD`s2jlw!8A=6O*^u>V!Jn}d_*xl$0!w8Rjy_v z8usfemfKs}CdKGItw_SnR0_08gEKqTD3u^(#-`P@&M?j={LbI{8)QHIDZ9O+X?Jv- zGCO~rqS>+EJ!7|eMzgtPGE;bOXto{B36#=!FGy5Qnw4?75Ju}lC=#J?GT=Rw4-sH4 zHq&9v(Q82EA(wl&$AuK19^oJc=x$uuiG%)9MQA*6ji7YN?4)2?F4!z@c=qH|^6`lI z$vsk?(OMVFy~Nni+@{5tS6?ext#7%$x@Etqn4T<1@)F~F?4(Bt8H`c5gL~Ymh&yqE z5z5Csk8lxP?|QeYkJFvr*J=;>@;;_XUyq#g{&07L)A+6d;`%X4OVO;+vMH5NUdES(KD0l_8S^odgGLCo^vLjxrOB=V$z_|Li~E&wug=p#|&hlJnQT%DkA< z)l0VP$JEt67EbNuo%k!l|&CQPE)N5qPO0XIMsN zZgdADklqDWany7Ah#foh<|Rd?u=H@l^g@vpGm3Ofx81Q?U9;XSnJiA2PEQcX zFg+70Xy&~`NyY5sjAAn3=H`lLPo6QIO&QPTD4h=YC%i*T9lzFC_k4(rl>PKCMh*9o zoPAVqUpTxF7$@W8)^ji{3WQT(Rn8I2+=G|?=wjTz*W#qrgN;VCKHX{1r1#sVqwBYi z)6YJo&N+KWYka)hzAF>*FJGzO`GW^8rifcRcZ40{Xu8=CS2*HGhu=F;Lqs3zOh}Ou zxWnLq7uN9Jp=2=3w)-{DKm94q@;N7C&0;h`NLVg6v~@=@dxgB1(})D?97@-5V^8(U}U94iW1Xwq<$XK@~t%CGI3%>I9>zv+yo#mhYnAguI2%FQ^8QX~_%O9}1y5Z{i zC3S1rHJ-`It4z*bAuY!^o#CB8O4#prc-wxF+9&b*fAFq<|6n5hH#T&Bxg1R)QK(_1 z>4!B`&_FggZdy+!HPgIgo@{B_EvtHqPiK(ibTX$FDU1fXW`YHA1 zmU24dWOjy^Ic?k0ng(ke)pi{n)()WrDoFy`L}zH3hV^@&KP&s2sEyOU=<<#$_ux2J zhgMwlklNU+MaVl+;W1dup;`BG&^YP5U~%si^8JM6=9Z_Q{fy~!%5-{y)@6vNR6XY` z#H`I0r{(pkMJ$f>aUo9-24h`mfo<#F2je5e^WJa>bQ6 zOl?IJ*?WRaKuVDDa0(i*Ly|@RzqrFBQ`{MLik_NuXf&l5l1ajLPTa}Oz2iFfpC=dl z7X(Vb8SC?R#J9cY+dul2k5iB@Az%EF|K2yh!H>WDG5)ew)}At%G98V`(iOY< zn$3P4_?SvlQy|ik2d^*i^_ptmuyrXWnP6Pt=vnJ%w-s%qPbifjgkY@&NeU;k31<&q zOmc7%$G4&Cjq_(R4Lk*U_2=zuzN8G}U}-?O^CX0!W@`N@LOc!rO) zR5%-H9D(TJqApN+6(`j;=9~8g$@Vt(I0frVpc^KmLiDLcF2?KH*g&bHfC_m8C>M7o zoB{@EMtChausT(g8}(Ds{?84ob9Fb&;w5M|{7V|ny9}kHf_R{a9Jdz2AIqY8B+`LY zAo_H+0l6ve=sJfe(D-NiflUAWXem)x)>jui`}ALu+C2{@Ir%6bI!o@eZ5)%?3?pkMqcKIEQtdltCv&uPq)LUJz;)a_f6T*s3%qr7bsgBdwSw8S%_)|cH1q+Hl$g~{tK1a|1sbF{#$%Qzz_Y) zn$5qQq4UdKoyRv}?_3M|CKa>5Jwj^mlE!$J){*IgGFO~sEmgH*UoEl8jJ+z^TR|x& zjK>+1W=+y8X+?pU%&;oO*|5qorop<7)^r%-=o(A4+jFH1dNie3-LQS~Q%aq2_WEz* zvk`eQqI~sjcAGVu^)Ci8n3HKTJbr1V&aYdgBG#dycQ>F~Q60giBa1om!gMmgI;fNdo6NJ#Gn1(UH;&Y!^-8&-~R*N z9mL`hxAYgHkA8(d4tv$ZG23H$VgRi?K0w9YC>H0BQ7>T~7x=jnM1r?aH6GImay_P; zWaM4LcK4iCWY~1Z#${9pCh43asge5)wYkCRDSosFQX~h?7>sQ(&d`~Tu5+|I%Vx78 z(FRqNRI5*T^wa-^RB7^)2ax4V=V!RlnDy$Go7)@G?UwocKGVsJPAH7A;dwR&+jexe zqqB~>-6PC4tUr}PrwJ-mNFB^jO6mi=dtfn&Ac5+2*F!VzqA@bIDl%qcI5{N72p6O} zy(GqZk5h`t;*@eaVYj(qb#u#ZwP89tAs89NO{Ab{hEzV&Z)z|l<7Brk) z{(yG6qiyv=u6!62$QTdrj!qIeM7{Q!eyt?FYk2(0Pg!4n!pR8E7A0j-(t6K&TeGVS z_wPTX80C1^k|_h;;*G{xjgSdSDjFX&yaC@Iu~Z05ueC*n=vL8Nl%mR5Cs;Q^nGL0~ zG}VfIQ;}#`E|(w^{?_08Pr13dW&LbL`{ah!W(ZZ%xh-j4!u2&0L*fmIGUVDKx|V9Y zW4l?>)LW#Ic%iwxS=0H1(>H#H`T1)&ow2K%Ajgwo!@Aw=z*{Dhd1#=&(2qC8dmnm! z|9ju`Z;5a6-4_r>Kl;{Nyw7*}*#BZ^`m>VH zQcB5mlrpvr+j`G--ypIvTc1)n#WWo;Nn7f+W82(d$x!(epXNxdgO=9^ouKF(I7{bR zq+1|l%FUntDObxC<@5rnJgxJPO_AxC@$4MCz2f%b5pA`hIJt+)$3Y*e1WA&TG7iNK zaJB>6VQoX#wsduet3AeAgi<6rA=epFCrGV9>jUoSC^44a&5aCs<*}ejsgKrj?vSNB z=nG}PkfN9@n2hIaS1XpcH-YIjpOQ`HAQOxY+8E(I);rR?M)XB~gsk%w&e@p1%y3yg1kw(V!*F=I0sX@uc@aWJngjH3 zv0#o05Bov9d)XY3o#v(FxLb9=>^_88l;kqKl|bUJ1_*X(aExcuxVOiu5U z%}&ut2{8pJ%W|?PeR9s>O^bIO#x!(YgR4S{k8>WWHK|TXlN_m3*!Dzo$^lf~*RLQA z>N}x$uSH6Im&F*_jE4(=z<7aB3GUVGWE`mG2IWi@Cn4;Z@v$>tASQ4!tY zea#VrK_)uQd;Ka0UZ(R0HuErS_aeyOiGzdQFymb0X9nqje*vX&N1OiQq?4CB&kwaQ zhF}PB=WArhVfRNa*Hb9(PS(~}3Z;wh8Kgs;5)752M7<@xO%mzFp^rZJKt8(|T6 zSCe5$v>;0|s@|56*xfu$u54~!>hE@B1814hPQ7ZNK9Ha4SfI!0PE zomk3l&$hm$vMFQ}Hg3!w$0%=^XBD<-*;Th#U7)fO=aZ<(PI*b#&%fSV!D>5-hF17H8Oc(t_Xu!0_J*3YowA=q3hQEgjf zRzgzZtc*R5#wUT$q0)qe8M8CPWbqa5KfK30??~N-o11Gk`x~4wG+v;xDflfn7mrBS zSIkZxkQ8G?l7;E1(11c~1-b;`Nh2~y*Z>yk>QIL6UBmoSczm8N!(% zQO!6@lBAqJc%5duV{`MI=bMk2ot;rk;-t9eHoCaTl`>qioe9iMDUd_bP&9oxkL+a@ zaRS>*DFU+29XYwhor|{X4=Fyv1vpcOE>);$o=u(6Uc%3F`)g1i$o6iHJ$S$Nk(1ov9=*8QiRHIWFgYiT3lmM!XT9e zrNA|$@oNk`SQiaoVH>6eC@glrqFO$uRF1daegiKuu9iDwKEsHNs_94*h47v%%~=C_ni8Y%|M`!d5D65{O}5)g1JOEkAg_#4?=M#B%Rl6IzeR|WtK6S zw-mb-`}#SJ7}I4_)@@2E6h$r==?c@VsH+{M3y=jySgefe4C`sUCK;Xb>TfS_z}kl& z@bqlT>(dSGe$Tekv}%Et8ROHIrd?BQZm8DRD3y?u6Rb#aIz=ZMEfr~+p;U?xQKzXu zCkaZFB;E!HvI{9V##&4pBJE6FkryeWTw_d!F&5(mP9#{7poALY-9nC$4lB9n@Rt3- z7cihX0*x(u(UNGECR zo_ZhREV+4tPIFW?rb8psY#?%^Nd_VfD?J%ZL^{ht;+nO==;tiXJGy@T-gIbh7>{xi z4Q#?q73i!;_Ck=E%GT7&=d`;U9-N54nH-DoHV;@nPyt z9H>~^p@pZ~ZOMv^JP%ke7w@e9yKnv<`LF)YZ+$^E^)Epyx%2V!&y+8@(GuN+R81rHc>jIWGjASF|X)*0Jv_lXSr(Gh}teuD-;{l2(mrJ)|n9oTbQmhp8^H zBEuzPgf7D>rq{d-d9Yxt#(GWD!8Dmtj0?)PLe(pb%gD+(di;=Lc1pdzVRLgyyIe7u zouE`g(^~eXrWV^ES{4aPrQx=u6;f-ImS`0c2fPy`nS_zYS%(UV!89JU)+EZIoQd2# zk2MWoG0p~vyhy{r7pI##NwF?WC%xw|DMn!MSmzK*Gda7*cs66bTJr4jk}O+ua&khR z6%o=LJq^~96eI4v`X-yzEz9d`s`ZNb={adJ3We7B$QD$waJb0-3}W|zfz~Gw`J>ER z8C%YnK`f4Vop&@nKWB#{Vlsz6A_os#PdrMgI605ZPsB@C=k#c)&sE&t6q)9a{I}kE zpC5dwuJa%HZ+#<_sQ2#x+uuUGAB)njbQ;i6qp3i7hxIN>WCYep!V{|q)v7nMh#?g3 z@aBo{dl|vransg*?G0XyDT*2C zc!r&wvt2%?THd1D4U_p9PAJ-@qpd1x2~wy){g7!Gwdtr;kIks}5{D!$q9n$LSFwpt zph^;yvM6t2HoC>R7Vj;_J3I*<9j>#^qohWv1mifG0?I-2-S*hEyyW!Z>$Lld+uLha zPo6NDPMOW-F~Zm5{J{}DUYt^lCfwd$a{1&j}{{1lyLSQoZG9*&e53ICIm_T3@7P>j zaQVqk(6-{0lY$}_%*G`}R&cZ0(bOH%OPbvVH7-a-W1QXNJA+gT(-=q+L~(-M-@<-{ zat4=$=Dl(gMv8vhE8JTd< z)tJ_xRLXK?_}ZKIxp?{+D%WV~NTfw!G0l#f^$nZV65n;CQqUR8)p|!ZTJYK%zfCee z!^n)rc|0myE}X-}?$R84lhCBn)c^#^+PA@tXD36L#wrv+07xd_jlDI1`8;t;KdNrVYPF zutrZ}-nzFQ;VnuER_kjnmut>n zc@+~=HMCAJ(VQV{`4bG&d(W77h$gH!i7MHfDV#a@Ga7{C>d%VBzV!AO*mXG;?&Y}h>Gl+Fd<$J zRP%i@PSgnv{LCYXkR%v`dS}|;Jok4QupTfDKDsdc)1TedXgUY89A?GmHXq;k+YY5^lI8B+B8tJr|#S#OC5Lvr;pijwp+Sv&9T0B^Q_1 ztg9L+5~Oe>N>L;l={?PU3l`eOA(IitI+QfXbb_!JQE$RCnobZR!=u6`&Pfmom8O^u zkXe{`b`@>4!q!_}IbX22_X?}MWW8!|B1M*SObvCj#(7V>7pU18`({U(Nt|j))10JC zSY9o;c=nvO-60i7CD?8&s(l-#m|yv;ke0NrkHB`3bP(Pn`^_F<9izn*sj_fJdvT|^ z?5gTNtj>GJmUBKld_qPoUZgzQ_|QrbZm%M0O~}tanK1!^%r)gx544x>_+(CF9(3 zl5E-USM0kQvI#ODF?;28y4^L^)l;5+a>3-}9_7gcOp>Duh4PREDmmB=Z`&Z4w;iV5 zhFf`@ULX}Z$q-thbc&S;QfiEo>}@{*Rzr@h7LX`MsyqpXr$7B)sjg=HXaD)%rnZ)* zYiNz9aRTXeV9SLL4jBy%iOx7Xe~6jXY;LZ2{^@6or(?z^XLy|-me@`ul8XjF*KD+Tpw|_9!^VIi%B_Q80my!)xo;c%#)nSxW;!CySl>L0^FEN&uF|Q zD>_cymfh}>MvQRj0wq(Nl$faWQzAgkrIK_mWoreEO_-=LW!X};YpVK+x+{_Slyo}d zq)2I3&sknSX0v+A?EF>q^b{)+l0uTiEN|}&*bZk~+ODB94X$gzIh2S8sY*~uiqIOB zWEi1PGNm;K+?bSlh@nlSKr2I$3O3gjKlxw&Kg_fLEpL7Gt8DiTt+h1HW1PYZ4L$@> z2q}>+fUV2XgmE#U-fY<1UbA1Wn4O-IP3O3{E|u|OkQ5W{y*g&KyyoWWIlJWzr)T#m ziYcvk*r?s3zQyjY$Pz&+W+*wKMbbGDQsM}WJ#kwU?!|H#OZIiI*E-r4&Q5>q?v7yi zKvoLF80jN>xo1Cmdq8a+qm7QXId47CWT`vQHau)9$My2(?{NlEQ-7I?)7HUcB>j=* z^G=-5zyuu(NWCOLhBoQ2qy;h`LE})aqic2u?Z}cM$SorCQ%H?eo;*va_iL)# zr;Jm@t6%vFtyg?@vBk;+rLqvBq9h_8ns{&XBRIm>>x#hHf1;uMso^WqMuS9(Xa+u+R? z32gt%tj@!b;_dH!legag`mf6B+@VDr^~UJ2FaZ-W7rVb98Km;Vt+v0px!7pPhzJQN z$P6bWRo7w-6ne~P>dDNG{qBagDQJ@!9R(ele4H|~75n;1eD_A7LPK?sjh z2mO_d*IpsQ+ROSwwA<@>%FEjLhOX>^-G{+U~~>s&LbgwnF;>dT=M$) z-A41%=Qir8esi0sUlbAf1&Ko=XYH3gLH*@@q=_cgYKT>J!iTggY{c(Gw2c!X?7)SV z)Wl~GJUZ$*gGnR?62uiMv6+-2XtjdGBV4p>Uj%x)hYw(0Au_!8teS>eWsH)9$=s0D zTk3sHXD8TnLTeIottqBCnW?C%&#)p#{ZIP1^QiIG=yvVRJ(h39^8_-0d?j6$9Lm=P)z~5yY0|w@a?Cufyk63M~X> zmLjB}vn^>-A`xtMI~I#6$~0`&E7HknkgAy)k_2aRQr99C)a?$OCCMgO=jfUSaz`dT z)zzo8&5j56&zYXxW4#xwcLv7@;X73=)b$ha@CZH;l3bktBTb=_59~ny#x6 z(&LrjYE|K7#=Y0yBA=X~Msr$~(~sO3K=A@^4ZCWM?^?>y2%#07W8nHq;qlH=?Y4AX z&HwjDKj26I_douEvd;fCwo>nX$je;m|4tgs1WQhhaWZ6+ONmopdbgdBI3eRoTg5ed zA4wH~s#2hkG3g*=s7fL6DxvcV>m2*Krc?#vSwYd%Y^ozqg#*o;If@==0rYpVS% zuB%9j30{?9z3W3kl0*@;H&}Eiyq#v8O&KQ{UA3XvUt!D$k~3#ZUOXYa zy<&0iK3OrvlF~((p6HD(LLjt2i);Y2iwHAzw!`@r+tq-_Sc4V8NjJ(hsR|me#Q}jWe#vK#pR%g* zyh0U>Oe^{h&+g5gOts$k#{YhKm5>zCc$X=1fk`@yQ7560*$J8N|V3eeknL;)&=mpEI57m2IJj|n~P`EpRSms9qsZlqF#}u zl1_Cm1fec$Ux)sRMXh+rO~S^WX=G(;#5 z5Lyw>bdMI$?bkg2?9XXemzlInaFAvR zLO_}(*rw*$lV?cb&~%t)hsr16(xx;jpJ292G?pwYs9OiSE3_0y(O~L5O|_v&Q{Mco zuh6P7Pu8B!NpzZp8mX6zlIkYk(M}>4jzHQ{3Ru}Gqn2+T1u?W5J`@6{lzrq^|cL6wE=I*QcarW zn1A0_=ZP{Dst!CT1Qtc>!wpmT08R}$CK>dSQJ*=ax)9a_$T$t?d5nFYYM8;(`I2R4 zX-X4-`4O%I@aN*}Kqp07@ zIN9kX7f11tah-n9ULK&vgBB{T8oiHbqo@zPbFBwj1F3)q({S^4aqVs$5zhSU*yVk3 zj=_K9N#@^spC5eiL;Q>BKks~7eEi)X`?vnV_xSto{OSYSvs6-MIvDMo!`fbs5uaP{ zhNjWUU@8HR@(vkg--X&^2ySG9qVo#jB|_+^&+8KnL`aS~h*km}&j%LlQ1gyQ@&b@4 zwbQhixh6)6UZb%zUmc(fFi z5wrqIshLhQ%C2HlE$K{)%|@h?1*gT7YW^d4C;4%1W@ z`nY^N<+ZZl`pL&Ud-N|znqfWJt+?q3e^( zB)w_zNXO|9K^TV%IY(rTh^apKdv~7pdVZz(&YR1z9?;Ovst|_vN$$UZDIUFt8)+m*+-)~UG7*R}U z_Dk~8krxTgc8{RNwo6P`@#=#IEM{k{wk^x%3Mq5aAqq1PCPG4yW8YL{(qnCn$FW+~ zEH5v3_;A7B_`ToZ)z@C((@&prd9%hPBOZSBw<#ubs=7lLB~E997{PNu@tL-x+HEMx zG%#DOMXDsQKD_`8rry);w+QdZiV;aM3Y^=2-y2P(JXvnhHmp#MaU|AYBCf)tFxk zT`(UNG^;JUt7lZ}8|L>Ol1 z-e9Y+hS5r)1*F&zy{0_7)pJyL!y?PV1ky{K@E8Z3aWu7~sZChgD20_#yBW1mg%)U? zF;CBUAB2k^lkz4LO(=&uQ| zJv5q%A`6+>VHF!29~;d;PGRGuGfX_A)Tj5N5$ayzMEG;oVr&57c)~MoBOnJC^~ur6 zZgC;wI$omv!BsIpzWYX3dVvrLTL)FEC{@O|be!9oUA3gP8CH#`NJ-QQ`M6}%ZE5yb zG~EvJIZEYdB{3GP3@b|IEW$gylGJFd(d4pVJZ)&}HQRlS?Iws~N`C%;)A5Y`%`LYV zkI7b7%IspnGi z;K6-pH#~j%gi>rsvLe8-V}M0x9mY7S&Qeufxacd1l|EqOghxxrlwzVsoQ_hAxyRF| z7u-Jn8KcE1>NDw~3S&5g5`RO^?{vp-#hE=t}ZzWT!m?w}S(KKi(a+y$jh4*Qc zhsBLeoKS~Irx3}kIOs7Qy~Lu&m`e`6$U}zu-HtGlKw{lHHuG?_%}KT3KmHxf-}&n= zJh@LTfBx8D9WPzC_r=xquAaz97XFBXDf`fka5lSx0)#|@vke!Y{*?98PdO@D9aJ(AglAD z@B9N~zH1w*UB##@P-)I)yQR$YFx~bZ=?%?pO;cASi6$?m$h^cj5ihyFoXyk^{w)R* zUv8r*Ak~D`k#{62I4-RXIoF+av@XDW1296x2t7Ym&{J@law<$p$7(<=+oJv zFxg2!1>=Dt$_bQ@fMH@*YcRwZC+M7|0rs86+MHLv_8*azV=5b_u}Vu)ttqucr=g>A z*3z{#+kJzU3hNBk3-+C%-iIQeDuvbw^ZTzdKE227a!D#Jh1k)wj>aeWIEfg~@1wgd z-dmQRd`exlIO}PQXVO^C?j^`}%ScOhR$*0+cRmQ@hbT8WIPM%iOe9@IghW?mzhnp^ zcNy?S^7!_DNZaUdh~bs$ljT1TEIwrWas){JjoD%Q@BM?9G?{U_=zoY8U-)$KZNBy{ ze7}zZdU4+RC*Og0zsuXd2CrV0ghta@usS4RS?6&!Oub#?8n!mB)vb%kRWU?Bgo})e zC@`-D&PJZ1ceK{f`B?Xaj#Y_>b0b_brIrOUQ6##c==SV)Pw_HC77K(P2cS8j4k;g=Gw&rvC^pVhc|kss zO!Jmzx24@~vDug;9g{wIgYoQ~<<;Z3)mbo_pOa)GT10@`+W`L-KE^$IA2ZUyJAv|H zqksluq4QxFAy5b>=z!K)8X?#LesrHV{@Uwwy1@7lYnY^pOe@BTKr4ka7H=I@UD23^ zL}-i)`t|kJAOO-pEx$yVRwY`KBpDCip0L>OS#MXAszaKJ+J5r0=`dTSsPB_OCO%HYJ`6qwc@-Lqf*WriXpBFIAU-VeSggqC&CLetbULG(`14lMW zoci;u|NBZpv%BHhqko0l-SFUa#C$SF2w1IGAuT5#)9M0*MtY0Vo@`vw-dur{D5a?P zd-7bPrDnNWGMg<(l7uWP@lH^0D<+c(Mk%VUro;2f^d81bc1=Z=PqF)!X7!Bi?GkG{ z{`%kikI0IYpMLU;$%)3v94S3Yn5Z>PNOXb{9lPxc?;5hKVAHM0e9LzA9F=O)GUuQD zPydWhA77%zr@ZmIf1Pr6pKaaHG!?~YgwQF@hwG&E45+JSzoTgz%JGOSDX5JJ=U5Uk zRJLQcxy6}|Jj*FY6Hr-5Gn75C;EP<09R?KsJ^0=?-{Sj!@G&3${y*lMLhvVlN%_;4 zyE@mBOo5di>jVGM2~R3Q2vs5lxf9`b?>(J&81Jx7hN&DH@1v7b$hbZ?h#@bXqtpZ! z8*EpMF)EJ{mw9LpyDYo5E@0a*?Pm<2CdW7*Ryg6cm zjl&{jf+3}If|ibPF=d?B?6zCFO^wQDh-}K_-mB!}G2814E*?E%G?_5F_W+fbSl^qT z!rntl9S)Az2{|830wFg<;H5`JEve`u6NSL31mhGUPf=2`N8nAE4*Jd^Xi?IWB#Kli z5-kuiAuJB6o^}qJlI6b?E$`oaiut#Ii16bY1RFJ`t<9w7*9HkyaID4Of zak#L{n5`RGY(3$C2y~Csg5&4##YBud+&F*4+5ENt2-C%{|IyEx9lrfF-u=R-i*Jhe z{`kB8`)|F)x4wF}7(M#lH~lxh10VeG7w6;t%4jr|B2N;mI-XW~oDQq>0N)lQHvGPg zO{8%yVv7W+46bq)O^lv!Kzkp4&w3I5gQ4?*y3zj{Bmv|ewOM^*ftNAUI@n394`CF2 zOsjPgrxMn-!#K-Gm&~UbyLwMuKZj&Qt40_xCQUO&Dxqn1w7W}0Qjw%ntSn+GQjfN= zp|&bb>m|lWG9;skCTVw6Rj8S&Tp-Jm(^uc7USF}fzGQp5Vs?5?d3uIXfdMR{Q$(O* zUU+?fqY;{0?(S!75p*zH@g(FsLapuNM@YfzG0CkT;XwS;nvtykD)Cw&VHb z4bDmCry3Cw0T5neJ4>~%$;V@CU7@6+$WnH-NBRy|-B90t#;j1Bync?=BhFuWjpvt7 z*)*Q@&7RhFu~`ojO(7N1TdMU1W#T!VjrgBG`RA-}uD~@I*WiU-;rgCd0JEN zckDZZPewEnM_p$)rZKJ9g`* zI8~y`1?Bu6<#^8S>N&Sho=|O8Oz*uyKAJ^_X3(k&ArUTW{%~Q^LzEII3r@tC+Bn;j zF4RjzSeLm#l^C9JsQ`r&&^b@tcw`$co(P2$p!PMn4(r@Rdde)pT7fl&(RhrvmbTtw zgrc!9K6${yq~!6_Cp`Z2rzqdCzWfwtD)5ptpO9r^W|M+)oU-0-*ld;vCD^Yvj1~_` zvpEeJPHH+4@KVy5IJxXocZgbkAAi2Fd6V*mx=5OGN!(D9ljH2CBp<&dd8y>%j+Ae{T`L16h#pdlDd}Gv?u|IQtay% zp?2h2FdC)cI!s;T_cgoS4X?g(PEm}xx?SUiqwZS9qY>h2hnFcrM1GuR)Vnpi?GmLllj#X6$zm-CKi{sYsJ3gAQhagP=PyqF^rbeM zxmL_aIjyyH#?o1dO9JD}dKI$8jll^U_+k#E4Y@(7jLbT3B6M70yuf;e^EO12(IZ5H z?H?aw31ek)eZ*VT?HDWAJ58RBn4~SH-m$N@VS1TP@G3_aBl5IHb!*z~7Lm;m*#txq zZ{j^Sub1dcT9@F+$aP6R+mltd>^9Hnk_n7wNKS&Gs;5p@ZKDm zXtp=c_~_3+WxjZY-}#$kWTM!5LXNr+AqmO{=cSWzf*f;>Wh4{yV0MMT3V+b5IUmhi zYA_JVJ`25Pa`O4`AOC_m=(qv>&FD7!>Ebu|=GQ**A1G;J|)H9Z9a#IP(&cfaJiX}Gg@my5|5T)+87y}oiSlD8Y0k0qjt}G z$Rt=dBrnt15QQ1GAPz4S&Z`J`?>#p0xrjB%M*WwIHL!6KEi#IcV`ld>^$mNYvB`u^ zj&Nx~q8f5n;p=PKc7rTtxU>YXgSjK}{^B`_N3*vnmVzQ5F-bObyCv0Xk1J=0V#4&n ztBhu+++027^2yIA$5ZB~_et^zoe#}rzpYY21_P7`ZKuZLg$??{K{_LcNu6>;VGP)S zTMtQ0u`!lP4nMyh4HJePg2p+dcVUGuM2yi)*;SrQYlOY9JAa)AU;R4X3ick5@d%D+ zsen=nKSDg^AxqSRH{O*=}GtK#YMmb*a>~;fIa&j`|!7Bxw54u<9CB}4QT9IX; zF>5-5lPP&VWxrcdcO5E8Q7Vn~U0{u)tsC+p!Pt;GwOg;5OiG0C?AAA|uW!k+g15i= z6@n3sS83Vo2c;zCm<5sBRFhB`M}S`}Bg{ZjEpTsWi(?MQ!2a z)!*Ud;oFdu)Gn;TZBsEGkB~}-Ab~g}QX-u7+sz6s1>?yqTwEi<(X<_j)@(Pobo(&y z$wyPXNN`cBE4`)K?daN?Vl*brO4={D{{8sp$e$kl^vCe-AN-}{PhV=InWd6RnP9A> zvkGH^puV#XX9Kg$I28+USV0*Tj4a-UCc-!$R_g++47wrPH=sfVgh;$G*eIayil4P9N)?)TVqMkh0zDk)Tg(iOH{k#sA3I>l!*yhy@9(}R`0 z!;6G2uKydKGcM04vMpl2rCV3HY=+EdjLsjDP3NqaS3H0Agz)IDv8IdjFf2|X=Rfq64 z0@cGCN8rg*jWG^s4YN^3mQKhr&1h7zuN$scYi`#yQb~j`c-vy@4f~a5cXL60o}dvp zA11D$nRGbehD0OhJSyrfCphRLS!0&7)hCZnmxn4Wwf@z&v^3S4CroCih-8H6If9tj zZ0VlXbJQqB1}~95*XLzNAifat5ce4$?mh^jrvn7}OVe;8EErkL-ACn}CQJIq_Da-Aa^>)k6s-o>W1cs)nuuaAK`YEUPUm+<^>5vGg zV?1uqXIf$KGSqEvLyZj>H*s9}hPc6gs@bQ*91N02yy=%PG!N1se*|#%zi^`2C$3qJ z9q(cC>iSG>g8V7S94yPr&$#;R&ncAUe>@Pw@E!$VSwa4#wm=m!IkNtv!2d` z*hFg_&I*)+&U>T{w_JpaV`h)VU@dr|F;-!O!4Yo%(yIsq4~?1-LBA*w7@1IeO=k=_ zg0fH~wxMZPbVecch+3D(EG5wiy4zyxmbPjT$pon~I;T-8aN=y#F?k$LB&?kzm5@&o z@~)w(wlqzJDrcnml=J&+=84-k-$UnqFs`*z+}ixBGL>?W1R~CzVQxN;R2TnWQbi5^9iDMov6%0R}bjzyl9R zXy%D+zy;DX4-8nc0hb4cQLs@cmnl`LKxU?$DP@+Vk|>cP#U|R@op!f>^K~AqZ|`$% zFeH&uD3YYOfdJ#iy>Wy0oW0k-n)iKPe27x_Oq6)bqzJj`G%+#6gjONDlv8eM6Fxa& z%+!t$@YzTysWYPgj!NZNA=$!etqH1R7Yl|o&}c<7F0ihrAI^!oBH9V98DpA)%3G9g z8Tw0tYca(XudSq{==|r#5%DNAL#l8|QI{~PYC_ks-CPjt7CSm(G(Djn&DpG;vc7ym zd$r=|)_q2^V}dgD`(&?tjnY|*7S;6~R~RPkEuL$|NLqax!F>gfC*)hF8`DSDu z;`q)7%|muHN~5$PDHurfF=DW|-N4uW>{~3~e3Pcqn8Hxi1+&>qo;OCE^C2Wo=2ND3 z?=bWO+g-<--}*z!qx&2^_hGz-L?wJx1zJU7@&}#m{*=CtE8W+)1Ij3+?@9epi5qV7 z8~N$#9a~GTsTC>fJbm~E-T5PqMvCcp%+dUa z$ACLcN=!QH4rcwE|)7jHFsY8C`b2SAli~X%AnJ4w?scMnaxqU5E+P;Cz(+i zH*~bSHC0tpHO)bjU1)>WhRy1d)zwob(;4H%J&Y}cN1OSXeY;`kTbjC|sz;exk$A6d ztS^1`OX@X#HNE`#uaLeVyUXADwU<#p;DX|PHv>&-O9%o#9%953a88SZGa$`pF2+L) zI3IIUs-^G-&_3Wp$XrFTP9bj?jA)v?3B&+CS&5j8vcW_fyh>s$((16yOG*>TF7i-P z>55U^(zqSnAiOwVj)-Q0uPPb_YPZ9?D+XVo%!tH@khh2sGAl;{dnU3{ehCc3*z90&QfQnsUZ%-rVK` zU)FMRBSTjma&KcEi_)QFNs(5{aFDmM&(0Omx@?1kV3)O|Wkd`^G$>nP^?*tNf?{=b zCEEk5u}agg4Do0RAuyfQ+&YKkdU%@sbzH@rUHcWA5D$!xc>B#JpME1>d76a|E zMW~ejNV(bE7vmdX;lnxUaO&CbMZQ<7bT}jZ*cgG{-`7_@{~5mcE5E^OU-W!m@^6>MlE=t03ph!)JHi(YBDGu zOVT=Tq~w#3l)|TiO|rBxQWq6dBj>)Z@9}nwFGd8rz}gWbI_NvxaDmb_#*T@$VUK1} zL7zF(ug*BS^8)o~jtjEM zJ?Ju(!t4R&x$dcb%FO=rPRMmHW&OM~pnD9|A;vhS>m2ZXGk%EczEL-gxT_W7@()_J zpDqZZ&DaW~WEu#A@;43UU&zl#g^k$CN z6C#BeZiwg*A=xZTP_pHUd5x@YECX)TEw$I6YYw&Wy57CxlEXD=pc zwQNk&K{|#?lp4C_C8uwGhuAGS9@k8!CAaUKFdiRs%iwy-s-mdI!~nzKXt$S?rJ^hwi3=?ZWi=5!z5(wBjutZ(N5`C9 zEZO!BJsOkHRHHFITG~#|&QVqPWT^{?Lq|QD68eF&#}C=8m-u18SVKRE;nj?$+6y-^V2Uhr5ShuoNo>0vEI*#>nkYoZ-t#z!5QSCK0x#`kY9)>rjT*=%`htvo;H_7B5+4I-r_X;VW-&J1#9!Qq&k@!Gw$+lIi|x)dHIJW{uL0var1RffxCwKl3Vg-+02m z{njNHg9a_&XsdLN@Y8~N(F(DF?ZN9e9~L>nH11vIhiaV9JBoK!-R~)`H_u2vj$Pop z^3Z;T-+1jyeD#d1%RQ=os^RFgv5u zwOiWf!XKkL9BkI&q3@y8ULr61JwLm9Bq#$XbV2FOSKqm-6gSJ%D3CeHi+Dlw_iLU3EX2JO0 zOPKjFS5M#O;Tzvzu{dFV>prSzBuNe>wID~=>MUi5H_qv(>tS<$LXS60GYXBBlMW`u z9PnTcrWUli@w=rPTTOBQtEezo6pq4HeE8!(%~wxfCq|#=-y#G0L%smzrsQgibDrhZ zB{4bf-M!5({`}AKi_gEn|M#n}@n?^>_-Kiy05nCedk1209`MP{95?<!MUOj$`i?`ooWCQb~n#pL){pap8o*!{~ zHL&s)r)!8%D$&k{Fc3^bpu+f`svfg)0Tl+YH7F}&1-E7Bd$cJi%Nj;=LUaV*LQ*(C z5R>D0dQ7+5l7JUqdI767ufO$>w)5E07@MG~EBc`$DNA8AL%X7E3@#=n;~GuJc6G{= zM^A9WItR8Wmdh=DEV%Q+$7qgDaJr()Ja0{+ZC4C_U^<_nbdm96*`SPKyIJF1&vZIN z+mcLbl)#c0I6ZxY+pRg8&za1Q7!cf&P1w%z_v*3kF8 z(Hzy5xKCJ!;uOlBO&SMHvWvM{0MVM+7@zt0ok-q$wSR-?42U zqV=3uObPjoBpDkz>x2|KU?(+&U*R@a#H$@xghY7h6#Fmom6d!4g#_nMt}$l^1;B6ozC0ouAvusFb$9lwjgAXxlI)gN- zE-^SqLQ5^o+fE+>Nojmc2lJdwV2zl9VhBVWLHQgDsfbv7QfO7?ZJwZ%oGyuRz@w?^ zk|H|7uq5~`$xP@?gU3?U71O3?*KO!GJ4|_mHzSg<`S;6l8!DlVAz|neU@g^bMC>l` z?HO^{VaF#lqbcQ!AEsMfusMHB`}#MTpWIRH%qoVk1Y!3(~?4!TwU(?KmX=`#!r9ZBmB~5ewi0vIpSac@oPNZCW4s|q7n4f zVKXVXBeid)4~qari19#OxmmvUr*{dh2$?ttsWZg`#9T$v6gJU! z8y>&?U52ZN9FHo-;}P@4gcqKBo~SF{z8F}Cny4+Bgw;->IfsZY3RF>x{~{_(8fXg5 zuHRr(MbrgKTZ(!jn#`exG*DI*qzS$Y#1NT`C&W0g-K?0;XUrE1E-tTFt+v^%JtioH zDhjA7Ot9cR6`sD^qI*M;JY9sh-g<-Ww!;sOvM{tm1fLj!VAI4!DEdwxGB`QNbZJyh zc~KddoT3!de9H1l;W310Kouk<8_0xWP&GXzMGDkaK^?aY{RZFm0zNJ(1}s&nncI%k zw{(3=2xFoh6Lg*F|1u87%+CwSkSM4N!}zGdZ&wW4b6mH6DIRpU}|EJ0+{l&We&PVohQ@G72BVfQ%=aq#cQ8DK@uLCoQN_TExR&P&Sp1C z&V@G142+6-vMq2i^85!s!t(49Z+!LlsFlYm(8h?SEr?($ro?*JG9H&4&BhQtMK$K_ zvn9Xv+rPs<`1vK{$q7g0z%p3+G$9xxfF~V=Etiv^#1dwN8<_TLrW@y^tcgiECBx|a zptz}Lx?#Ue?}9k`FO#Iw%g=?+(%F zP%lX8P`}jSES(kYN%XGCC_etFUtoRygzofBN*%C9XIFbp`mu>VcvhP&)5!^yHIM?@ z82<2U-(uZ+KKau>!*ONUwvKJGIMoo)MCAqfc33Qg1Av|DBhIxP>c;6m=Hh1dffZVP z@A*7EyT$w~xxv{)X3fHeFnh7W)7s;XqQxaWA95xgRnx>XK@R0B> zaOduAl+k?qyRWg^^(bv9Y(bq8&2)+_3);RzB}=Ik%D2=euwAV_hX#Ny}# zU6!odfz}&NUi>)6_g?~2&^m_?Fs>~+DR%9S5C-P6BMvUSz0o!$Hk&ny#B4UZj$F;C zzU}&otJ9}U=VRvcV|Kfq!qj3Q3IpAC3o$ZV9Azp^-pU)1F7)k=Zns70g2{BwcJuH( zDtvzlIphaSlzU$rO|76R3L#{~Y?nz18x_H)%-pg$Q#KJ|$VoVY1(60b5}=NSsL6fGU4@UCM)(Tu3e z4Q6+NTRkLI6I3&!oF8+0vS4%Zl*_ZntX7xIPwvsoPQ)Fa^r2x=nMWD(glfz+PC;WZ zH_~(VoHL{4JgsxpNh%Qx1f?NqOinP6tYXpT5QQPQYdbc(6)AMwe&J=VP9L*;``gSb z(JpAENkoEjf@6q@-MZy?JVjdrCNdk(v1P^AzVR)p$r;7?gxYA5k+XzCVYR*n53Afr z=i(W1Gi|gWV-9)1xoB#AbI18?2Ico)KhislK|dC+@4ipl#h27C|MOo-za}n4KKtvR zxHrSXs(S! z$(@fmw}s$^^W?4XP*3J8Zau)(lN|3UjNOz% z4tmHz==}yR1#&XvZm80jl&RQW?&o95o&Wu=p1R-VaiH;7TQu+Ls5>2CK0wRMiuxlV2$D9ANvTat1})xc}h_lCZ-|!h*bs^ zBSs}^t4Sfywk=!N5`By7J08CMHlsrE;)~C7baceJ?br>G@zGsgxcegIs83S>t@qY(7J0L*O3275qTAU1N=<9!+Fm0F)8t>-zGX-EPb6dv_U+Cu}x5j4d!m z)Ad`n?Ut&lX(n@m76OdU4Sw)F?QTnqf$4OLEt<@ZeIH(*{(}1Q=f0Re^TP;ix7JXV zCOa~7laRG2QOB%v5=ggX0!wq@l99rhbAlzl&EUMom3tw*oXuSb1h1t)C!JABftWOd ziy8bb|J|5H_Yg5i>|;U`;((6|AEO{glKfr)16tElFoY3}EvZHwMc6S6PZ@@WSS;A6 z23<5XBhR$l(YB`yZHX!u1U)8UMZc8|@O6qkNLodSCUpj$cd9Of?Z{h)p&VJQFqf z%;`Km>$Lo_a{>M3+r=M*hxUC5$6x(?x~UKQ;$H}C|2+R;`a=5j4}G(F?En^M*?wM0 z`#cEPpVjx6vE0P$jcH{eb&n`)-;m@SA2PluC30SRM(`vh?pm8`Pzc1Jh|w^3jSIOx z1sI&@F}=$f`OxIBBrqu0N|@yQ(~^Lr%QWP_j~DH(jlP?0yNNE(wu zVN?>Bd(?7fS8~$Nhv*x1Pr5Lp;z8#aQzV2f{cc0Q8*o07kTkWrX_(!AiQp99{Jk&Z z!$x+b`wLb+#~YyKVl1a}1}u>n5?YBV&BZ8$5kWRf{*KZFDpE0n;flI2wEc#il#%b9 zZ1*LGv>$pdE}n8UUr;q;UcGmh4}JWni3DN{sHAay4@yx_WJu}yeZ$=|^jkKoEg%2L zt5~J@<~P5|)pEtwX`X-e6O3;?PcRijmctk=I5KNAo6Q>M9rMLPzK+=xsEx+?o_4dO zsVb_`n2=FjS}THcT%13}n#BDF_fV#wALI(#j4GC!D^v(fClgHB5ORZSwLFviwx!># zsOy@#nvt}{$H@D6i~IC{_&NCE4=`m=#50%W* zqNYy@O-)g1N?W5{%h2xdLyH~HFy)k6_g`i@JK^&52@l`;4%7L9`SESE9Z9pMGJ+y0 zQp|w%oG*mZvXM;bV5}i3;kYSv0P)&vlF}*S{Xp0CbX|w@14<=|qGqv}Q8zVKmvTx< ziN(oXKK#@FfUo}U?@&aKNdc=0+4zJ!lWSORwp81i*{s1i4|Ey9qA;ew>J24A3Fspd zt*LY_h$?Rxa)N8x%6wFd6{43Sz!C? zzxk`_i~t za&5g?_XH>BF=$=M^(9$>X%_{R@95eU$?YiW5#CK$>5@q~XI3=0uA_HnxX=*ojHE}o zIhO`NsYpP=H>@60G={PqiTr4HiFRAmXihzz^I$Y(eRaX|;*|Az#p2`^lj$*0iSt&Q ztcy&0mhwJ|n7t$L`jnr{KIfLG#FejY@$Fqi$lM^-r>_Wq%(}6w}C}V+uQ4%-cqihy~(zs+rZ>n3-6r&+!DU>p(q9KKz z=vqcrqoc#9#CGs9h;^fLpJl~owAY*8H4Lc zXeRRoQJE~^kn3AN?AUHsOhz?TH6}zEW{fd(-Hz4O8RMp6yqHViLX;#Ri0sxY(2CLQ zNQTiA^Ci&`yl1!DKnjefb8J})Lw7HE3*mjMim!kBPk>MU@R@NWB>BOcI zygKj@y^05BSBPLEkc>?5heVA;;UfbANSAGZ6k{KfoX~?NQpl#$M@i)fF&l^E9Obqp6Cy!@jd8Q=YN*So%eHOVY zLsMu}@G!KXbEffr8;PPU6-keX%H$%L4@FuXBJ0u(-Q3M*zdkIR()Z|;o)NyMXVFGK zcCSx=L8aF|ntt`=cLLjgh2MBBy+^L|AJ>#1ri#=y%aT%L2nwHIPzJ9wP8GPQDNRW|?n%RjI9#IKKq$v-LrKsT zle%V5J!5u!k7hDs zeffy1CvVd)FPWa)qihy(Da*O>CTWb?gUk2zVjowWvY9K_L6hr1aQLBT=sJd>C#6JH z6wI12RdoWkL>q~PRMFFQYu39RyKRe3krzMm37l&=f8%S6jF9c>x*(=(dU1lO+ET|MH??c2=fx6##z5597T?O=F%8ykx7$$^uvpAwILuoNrJ?OwcDoI;*^IKN4&Ngb?6z05?V9<~oVsrCK{nM^ z!{zD{NKEH5%4$T)QX8WUq$t>=exNEWqw$!C!3Pc`0;4s-b?;M6{7U*i{Mv89=YIW% zPors!rYH)GiJ5^ZnwJS3jgomu<3@M2| zDI|)Zh(%_1=7v+WP#Gx_0)x{s<%i7i^g)Vll%kx7n4~F^m4cldF2N8bjRRHS!Wd<1 zOgT`6Exx~E=nb))uq{TkYD865%!?gEzor{D48;tko5MLF#dtUmBOnciR8Wt{jO>Qg zU*dL;2(F=M7A%hMGM${TI)BR91D{kL;o}!)+3Fw^mQ)-P$O18U&oQ(u zZ+-pW(O5}=Dw>k$WOH0-!_WmDJv!&k$&A^wB=`Z>3*KYEV3kI@4OSac2|Wg-3o&@@ zmq~jVGwD!ICCT#IVJ|Yf>*S1gHkr@HP$qtC@tH4uR(&ab_Wk{DzAIAcM+eycU;MxR zubkX@j_g5xx7`r$P9NN#+U1W}6h)4yl*FGHBgtH!HMK`{(IIQ#Vv=iwRhXy_@6`|k z&WPhYCA~BuI2BSSbE=mk=?=|j5-Sa*YP0GV~M5%aoL?zB?zV3Rg~9#tLf+>QT+YZRp)O?NE`5DVmaGEPIYn zQhQvH#!;bdMKhgJbxVR<;WlfiCe-zu`rgY7)7xC0KH||E-(h}yo5k@1f-XoZ9AYi3 z);U=z=8fkydl$rb)o)vdVMiDSRDzps~uJ-I7vk zQlao_B>K=4P|6(Y*j|r*-~$WL^|~(Jn1Qs`@4y?q`;h&YHJi)xr>suD%k6o^bSzul z&JFlBplylKmJ|k5N))P;t61`Aok+T5pu}ejko5Q247cCTrU;mWhalJzstKF+l5uS* zQ($xY1}gQu^3n?w<6E4s1LgECrmWE}fY#XY6gv)>)DgQSN;%LqSId?Zwyc(GuFg*x zx*bY^3zo}uPdT~E^UuEm#T4oZeazbIXLPTM^>T^Uiuru;OmwGKk-pv1caG_7jg>O9$t(I{p(yencpyUX@71k2!sL)V9x z0m}-D!l+1zoU!`oa>MEbla!1U-lCu|j`6T#=q~YY2laxElG045#wDZFVs@9reoZVE zV8;YWGbbf4NTjU984`q|#@bs{sVB56hRcVjdX62PaP;66n)xj*P9O5<&2KZE&6u9t zr6`(=j>?)vqXhh#A|ZIXzQeUWL-Y_6g|&>D3AV1$wv++|q!{qNW77|`+ZG=jC{0<8 zxxKhUUDd*^i;_n?sDh9D{a<2v`jp-ILrR<2_N|~9+MYsbw9+`&b9K3f#(es`A?+a<3L6;)Id31DO=E<-5e0)3Ld+OBF$zU%GNU+3mh@qhxxez{ zjb}&<-ZKOk@~??eQ5b~}o-$b+fguE9a)ekAkTfr+8f;xs*@4t=8Fo(z^4C-IG{dMXwCHnow3Xqp)Mxt#G>ydVE4PUT|kLXR|!# z^6Vk)=FgZPpD;NWczBoTy=HTdcuKPE)LN5bIBYiGt?s>3 zGW7kdG}Ex=xjQqOsvs%Du6LZCU2yNYmno+UhM}icTS~17gC<4;Wr@-i!AqSsT4n9; z{?cS}vz&-3kd*xYkH}}lR5g|n{pJZnyJ0%2xcA&Ev}($uWh77%`wc@Muv(*XE1Q(Y zdrb;(G#gP`%P=_3PtVv~oI1 zKs{NcOSwkr-Vz zEE)O$UTbtwQ(J>~j<&lX*+v}dLq(w#vr&WcJ==CgbX!a{15@JD-s_lh)R!VCOHw6T zk0{LuGpyKbRt&DCn4C~F6YjtKD%<5L%d;nJmfzym?YoTUx1^A3jSr5#-7>Tt&WpjO zDoe)G8Ko^T)(ZB>$fnQ@`^{x5jK0Fs)D3lcgsuuO7M0CaDfz=L$2&(oJ>tWk`bYf! zm;WnV+JSd+MzkVluw{YOC4T5wF1H-tS`b6TDM#`pscTUriYA~3Lse>=nGsY?!piwE zpDeV_ld)F$WUg~m+x6yC>1$2ryK0qgoRxmeI==UehxP-kGShGVr(cB6eK{kQUQahS ztN+K}_|Jc2fbHMgXeQp3V(>i;==Da^7B<7x(?P=-_h;`A@+L<#TrtK2C)bCNHRI;M zx-~IE3?yabN|7K2ebAjt-80exhbS?ANo7W-Y&2bfkj$Y5`oU)gal!>d?<2j}^v=^d zacGx8bnZq)$|R?HAACl|C5EVR3B0is^@vefioS6-KsBMSM)ZSXWTwm}5!d%@`!g^N zs+54Yxmt1i&OOXX zP%=s>oa-364Zd?y^R=R?E1J5YFeTbbLn`4K0pD&J+Lo>r?RZ(1%*Hdyx<-{2ltBgA z498rfQ-s!gZom8yo_qX=*Z=h2Qdu!>)YS;B4L&5awP>B#t#@pin%Sf#1P9uZyeI88 zC<0n1%y30jCY+v0zz9az#woKyv+i_%PFERUckrR#7`C6i`F(6Or%gpsjG4^m z>~cxA5cW_3mE2gZ{zrXJy=V2^Z)w7WIK&{Eemp{}vECIsn&TpVauDoB z>4g$Sn%6&US62*!3_z3l5x??3{-5&Ce({y}te);Q{D0Z&x6~H_(!1jG{=GDsN(s^? z-f##fg~}PUDVf75egA=oQ9N{3OU#=5vz&qv6ESK`QfO_ZU>7>O1cQj@W6D^ONNMz8 zYZ(fi3%N|}K4v$1w0LLnF_5C@mm|27N4vY*A1cCS)ZP~1Q#*;)bHu60mT2v}nmJ>N1GiA^ z)$i)MV^qY<)BIkH2k&%W{@9+)|FX$cnoz#{UZ1iBsr0#DfA`bMj})-|pwr|X&8E81 zP^NeM^Z3jaU0W-L_55^CQGy4IR)^*?rTwKxwmBq?Fs#(dGobDXL@`>JzFri zKsO8&x}+`}rlT>Xv1qG^T9ZN~L`OelP5LmPQlzvc)5)B&8B>&1hTcmAXxeANq)fF! zpzkRr`lR^aPyZYj7mrvz`8KmsgX=&SI3FlYfmM=rwpzA~#}icaMDL&jQfj7c+vjJ>S1dx9> zfzp<$nP64Rt~Y>efmdD(21esk30Ul; z;;34)S)Q_ae8qTn8(UAY&4kJ9n09l;lh?maS(Mzp|1!nq1`8AM?T)tZ=(`?5 z!rFqS7*kGbY*CPmXq`gxs3a(gbYr$sS8JZwW#0*B(&zxOFtt5Yt%`=^v9;oTq` z0UzaqY-Hnmak-)z-NE1qZlKbNIB1+|QAT5wks_;0v@PVkn6hIrGvib~lOIGbN`?%z z=a=0mx6iuF(_alN{&8(Wzx=tR{+3WffAT&cmHswg|Li~hPx#;bZ~u3E`qTgTnREEN zn}crt{q+`fFMqkNdx`u^kv28yXBy3v5-M^Ss$rtO+t76bww$7Djn4)@1vos) zXcUGa8mu{{Icg}oD^^#JS+6gcEbf9Ssb|M{AJ{D~xIBN0#r%Z(cV5I)GlH@N1u6wn z@btTuuJ3XEfI(qxMcvFP>l$N?L}@1BE0fY;^QP1FP#qAB`@XsJDNs$OeDW9m1AhN2 zOZ@tj+JFxOT3eFyXsbxZ(C#{x%a-HYQ$p-0#2tn2#7dr?=W?v)b)1#8Nx>T{sSt;vpFGkY&(evk_;8?9zXcUXt9AgUnen`-AyZ3Hjw_X#xV=^1jj2f;k z*Fr3?R-#nj7jhpmDk+-04FDTLW=*LBn@+Z<3G3zTk2U*qmOLD)QA1G_Y`czj^Au|~*k(#kO{*HJ zs$x_P_-={ome^v7Hxsm1*1nIGSSVAyQ7_@To`k1>|fXiQy?(YC;60DMxy-b5=oMdh>2p3Sy5 zbH^AkITb@1KG`noa?B_G!Ke9m%N5&;w;5SO^d7VzR+Iu|4QWyI)9;vs|L5;DQt5AZM7~if;|*Qr&GY!pcTeP<@2ErFQ<+!0|96sT>rgjf z+c8Q6VTx#k*{3qLB!qwgiX;L~tCi%Or$kDEG)n1uD=KdEEcvlAY{!_-@;*`oeUJ%- zAVguoD@lEIPLq;lR3v&Q`owM!Y@82)&L=u2As8;G%rj0{<3%ePWn-$6VLY8s^aI;& zN59%ql{09@Y$-um>T%5^^bFloye~1u3~xsnKLk1kw3c{FuL=TCRFUZ-vA#U#>hX8! zePVKSkJ}GkMw!HFdCJx4Qy#wYZEoFtj%Ip9Hw4=47VmpvN|aT_Y&NH=MnVF}SgLS{ z7|Y)qqa=+i<>%6i`OI9^+F&tK#q;+q;_O6fRrPsDvJ{57^lM+P_dT z^j8$XZQHVH2R6GNQpw2HMCWCcvK9SqAZkJ1dDmeJjVdN|&e88S6t=_^4azo9C`|N3 zwnK#otXA~> z2DiOrwO!HeHk8(|={lC%p62*Dj*p*bdUO|;EZfb7qN=f@5k71CNfI=oVq&-1p|qwM zk0jB{34tXJlGrmEkFoWb09YdJ@|^8v$z&l&u8<8yIwjWYCB&Y^VurRgF)5sPVvOBx z8HSE=J*KWFM5Xfkk3$;XZndHxc2sr6?C3UHYj(R9=L3tyOmw;E_q2w8;V*kry!2W1 zrSJ2h`97P048|6Dm4BTTtnx`{Z{j%U>=L=)O2e|>ob5Fx6jFGVQWV-;gKLuj@>3E3 zYD)R!o-Dx&h&V(!7fUk=MIk499}>Z4oKZ+w|CA{0^=6^8P5`P}Hk~dCMx-4)gI5gR zGWe7M^5mor@J8i~_k>m@lfuw61O0Z#uCoW-rX%#Lm|9#6P<@`%T8zsc448D%|Tyf~&D zPtjFHRaTHwMBF}gBBp(;@byMzZ?;i+TN6``gHstzmooEG{+aWEdUnDme&L_;`(OSN zUB9L&3PSW?EHMU3Ytcrryj%i_JGT~M=t`bK36iPTn>>(2tO~-3GgA>)?_=N4S<|`~ z%F9_Zk}?}qy-R_82eAF`*z2WV{^$J4uf6wY?3X_KCG{G=nqL0=S4dxwHukrE?PV07 z4>fX&&l1f>Rm>ZRphv$?sp}}aP$r{dV zDncnzkZ4u2*R-9rA@ga?y%%4hZv#&r zpAm`?%7UUmRZ~KU^!<*iF4^u@B;P?jqO4BXv|G;3&l$EGR0^OYXO|nI8FT*wAH$4h z*lG+#&1$tqX+=G%*^43M*(}Sc&1NIAu~8$RB^5;`GIX>z{gnJ#W+iGawu`t1f49oA~5(>c1R@DlPV2|y&e-J0EQi#3+T z(J|T`nIRvo)P^NS4~((aa}i)f+pt-55A>KmVOv$GmgU+HIwmzvKe8G!KJ|H_A%9D z&H2+ec=XyC)7c5=3R8`F{-qBy?ADxLoPvhMy$NMmX9I#bGmXjddP$*`A!_;B?vX)h zpYJSXRosy3Kq>*f&v}g`1%vn8dj1tY_Ot(xul?))1``~LKxrzBD(QPCj!Y8E%OzUF zojXUQ=)eb*f#4KQL!pykOVFrN(_4$zRt!%hiI592tRx*X??}s8A-zkJ`Hr^X$8u}= z9*MgDI?d+(>-yO*B|iIO^A){0wA}pro2T{b(4-J%Dw7V>Fa@gsm!~kF?u0e%%r4 z8C@}^50Q~Am`*yP>*$7-L5*kwbY0Kj9M%|$V#H{Ei?VLSfT$wJ&mXf}o^pQnHoMhR zn(+})S>`AAI61z}^75S3KYBDW-tX_8_|sJLxAG`{kD(d73Y0Y=^bddXE~bRmt-g=DitW>fK3G| zMtt8(dQmD-W`rs&eZOT?TQI`2Oe2G~4a$^6w_|V)+7;FYiqNBy!*5!;&4vf}?=U^N z%jG7}_Ks*Q!9|qck(9=iB}H8l!WI>KCRVZQ2BI@;H!B`Jd=uw9g)(frp36WZyB(9sjG`XP1uw^*?lvoie#c@lryex~EG`Pm+8V>qiJM#n z&ulWLtjBmXK8a+b+wIWCFdC0ZDba2>tk=0E1V@TM{o69cr;ITO~JfujG z&*mW}f|YbgnfMjK8#EDHDA4wR5pnw%OrIEBWEcWIN&)T$N9Xd7tu&@SN03ErP+HMc z4Sny~b}er3sB$b#WpA*9qQWsP9R1}QLd{}+4^vN2x*{`v_K04#UB}=Yx|z}#%jV*g zkPIjHUu1T2pOBzFzQg(Bw|VsKuQ543;pEN(3R@qx5lKVTDxa2IjJ7ILdSc|neX)UGv z9tXnS#e1!3H(H?c35)X~*S2`jw9A=2<+>*)_h^N?8{-~v1l`~$D+!p0F;Yi!2)&TH z7jh(~VsM_ebM#q<)?1&qr5YU)Nn4bKrW~>B26k>k!jsB|P0;MTp%@~K_1JXIcDbc2 zkC-0cLD>eSi_FDTL_8rz+IELaih6Pc-ImKIZ&NlBV_8oY)F<~@Up(dF=|h&6XB^*q zz+!QWWQ_2VlM)T5x_M&0Hh1l7ULtQX^*+;F<+0*=ZK##Tdnn2=AN$lV@q1^FaoeX< zg_35us2Td6(i&8B#F#icy`-!RO{qjO;T%dC2Gxtk-)NCcBulC+%GQFriPvT|`I5x^ zT+QYn%rj@zXS2?~zjt|AD9TYu-*54uz?PPxFc>|MTn}c1DN7Oq{otsp8rONku)>ca5JkG#r|3{Njsw5dcDaxp73DDMfr#}8{r9+d_L*K#~R z;mP?^{05%CcfzE!tOm!$)rvM5?tkF#aqI3&T&+8dHPoXK>+Kdd^ekqJybl({l2(c2 zJnd#hRaR8Z7#9`EXcU3vXPl%Q|5~))5Qrr@}7)tV7FO;g89)g zT3Mmy=)BF}F7ZRpty{M+WzCTCGs`Lnf%WA%L)S4Gj~FfHppC?0lMV?%L)S5%jp^DA z+x3pOXMTK}q-#9Lwq>8wqyU{yNDc~}~g?GHD>!R%wx zG{G1?@^in$^70A8#UqLmTr1AYZnvedqA7|YaCv?~RUFe)g~0X)F&BvFx}Yc(+HVAK ztQE>Mc*@Mz%x-feOPZ{MJ3Rk?ETbm>_C?)43R~14wymc^@{v>CW+bEYSzLx?Nv8?y zlVPt-K{^}S6Da@8xmFv4wN_F^)O9+RB-|Ku4A(W#i$-&QNiya--dCDRse3**p!)y} z(Wvk19u!*WAGXwjlMCTM>)5BSxoC3TOALcyR26j2G5ClJmd^Ri?u6m6Ee%X;Wl9*3M%x4YHPXc|{;nRvCI+C4;d2_eRF}(vpD@@%mT|8i18eF&G^yw4c zc0l!X{i`o8D#;*#Rl z0;>()C1P^;B>C#b7>qS&zoO6@t!6k~=cJvy$<*o~BfH+bCi%IWH81^OEH`5`!_ZMz z6)wuNwB2n9zNc$D3R9y@jVc`u#ERvT(Zq&7pSU)3(-mj@_h7{+2KLgzN8Nd5YT}pB~Pcad# zAr2YUc>aQrZ#Y$(XWiNVbwmC?%9G zSlk=YOy`_FdB|Je{U(d!yUb7SF}rn_YBuNU>=BP1z0Jk>DR-ZLiDt6MGqFBwV8pnf z(R*E^mW{M#6OcN?@y^nE8fOrNN%ur_@^ zaDH~l-MhCbjK*fHlJ}9W>q%&;%AkWLIW5jiEe?I18GJDtmrTm3BPu>K)$@0v*?jLr z-9OS>)PHaNrjokH9=09i(5ejCUXIRbDKW)EUbj+^GGrWWrNPW!r6Qlxi3w#*uBW-? z8H1salVD6xMv(zUX(Tl%hp_A&)$;2~YxCJX*S)yk_*-$TTd8|mYpgAV!@18>&kSN0 zBR(2}2Up5fsCSlj7^E(G%itpYkl5{0jB;9-4T{28T=Wz`b87~+B&LF`gVF@*5!hh| zu4TPEW79^IDJhE)lf@CHtVpH;6ax|66x@4h#_IAZ=ciBDF0VMc{ea2QEp9#cGUKCT z&K|$XcfS4SERK)4b?*hLYD5TvRoV+{)ZX-!u2Y5fS?Wqb&LEK<75N_MxF4`1U5GsQ z>c`lepYh#4{&!S1;@lvnBcS(*y3iC@Hp>l#H5?x;&?MnLhKO^Xw(Y1JNlnA$Q+;7G z8b=!3m}|4nP;c3eUng57-XR(KK0kRWM#{?4yB=c;3adFkJ15zKA}UmWfgLSKs({Ke zbQ_FG)a8i2-%+r{7IRVvw9ChY-6?hH`Pe7_K3!_~qu0(Ek4Gq@sj7n7R#>g6nu4-6 z7?mj0jMB(+*ts3qR z46RE-)t17$yBcbcKJU^qhmfQF4qlyZbgwfn? zmL%tx&5p2TMTqkIJJ++_T%xsRadOOVw-c|0F<1;k-?3U<5mRJ3pHXGzrc0s-PAOrP zFj(8|mgV_l>QTdJG-h@*25kvk8;IVk8vgmu!xz5rY4s!3Xrc?09YG9I1XBO z8dS`BC0Udm8ce0-?5(muUgZuUGj+v$mvuv)^oF&BGE^PImRglQqDD3 zs6(;cYo1cpRTd#pc#ro^#M~*7Ow18+3SR_`r3|50I3;=|dqb9?3k9knCE<-3W3LC1J-9e;!=Jll zX#4N)gLypDynWU(Z8Xm&!TjX)!?Z>HVcl#hQ-cb5z%{w<$q7B>zn5B;4ssMylx@qQ z?qv!@OmbpVfKJz&&fGkxEIpFg)ksPvM_LxS*_67c*z4FiL;{mIq!5J=r0!{hwbHzp z9A#*cvqwC6^g34; zPdT~!fbne3=+%$1zBuFT(Hp$}XMfD?`!6y(xhL@Oke3ztc(d22tDA{q#7wi$Xuze2 z3K5%8IYFg-IWv6dXMTb8YRTp6-=wgLp>G+DC-~s;!Q}*+g4KG!mK`VaF~&e29A=+0 zuVrUt6ew>*mSHtXmHF8xY+{u$fH4ms`fn&1Qd-e=9ZfYx8<9?Qy{D`dRw=fd3rtc} zqgyB?1e54GqP7%8LvlNG3al=kG9DG&{oscf+8yQe7H>aVN>=%HE0PfsHlMR?@+iNh zwuy0N@xzAo@`~Vlno&X5JHGjyM^GH|!pA;Fy|{%-n(cN=LQ##U3?Z`KY^ld%lx=dL ztUUKq^lVov>Z+g`%eh<`&Cs=MS4&2t8TEL?c6CV#16P|hbu(tMI3}q=GRJ+#ZnLB` zipk=bq)VZ;sKjo!X4q|*OvlvqNJ3zo=V&2K_j0vl7<#7TG0kX1G+K1j?3E#ceDXub zc6-5UdBM?Q#$>)g>4JpD<(}z1cN%>0GpH}hZ~D0}C;qxgZtriSX-X(25Cb{|V)PIP zDX1yzxj8b0?=?*M1B{XrdQ!6S6c=>N0%sAm9|}MwJd!z)DT(dh!2o(PM_EHG42#=S`rVeUJIAS-Sj|v& zLJBFzd?~?1B`Lm>lY2CaBbH~6IeYvD>&wTS+<$?3dW+{i^iymv&w2XxYkc?5{)pqd z4>-C10tqW;H1?;Wl;sc{3LHx3&7ne3KprMiRxnuvCf&KjDtKp8HscFgB9y20amkFGQ>Bd>hcx9X(wSphDIsZ}d##n!)1*+!X7{wzB5Smq&8^sw zV~*-2WSwD*huB$>1%)hCkwJccZPME2CPidPK18h5l$rDqa@`Xav8E`5wHVR(Ix%sc zJ|z0V3I1k?4EY2vbuZzEND7kS-W!dL5mi~dIl}3JNv$~e+18EKZJyO0jJ_M&l8MNo=<(l$}$R71L2gw^QtPJL+}6j^Q7)T1#)H4-4Zgb)#&W4FFy)HIY;Lx`Y_VYl1hw;Sf; z31!pJxsJ{H3gvso(;1Va+XUpw&~8^a*D`Ku%CaVA<6m$c>&=SFXpWAAiwUynt&4(w zyJNjxQB);Iw~r}oiT4qLTzO4SymQWRwYtI&9fe6O7Bgl?w+Knxw~0idMWQAFH}7o? z|HA9PnSS-i9!ep9K(j_BLkDE?R~S_s zk^}ZiOJj82TE^@1`hGfBdvUb6!Ku>+gtAVc;x%|#rvB^v;dpRvrbB^=QCg-Lq{vid zfy%7Am=Y#NLX%^!m@ktSaFg%SdnH4bjzfu{w+`cuVGK%0mN{Q6K zYl-12D{-R_tq9|FqY28&sXxk~QUJ6Yyz7}XiZ`Duubr5C3C0a)=FJ}~rTCBj(QT&1 z4nO>)jr_^$2h?hsMx-YsR2(37ncN^XZ@;w^ZD2gGXcZc(%mMGVAFi#Hh)EUY(z4IC zCRfIk&3bu1D#(_-K`!o1Ey%E#FE`{9ZOZhHlImRl*MeH+YJa2qbEw2&u+L=)EvS z>#Ctqu5lx9j@Ysynp)T0IWUux*q7o0wN#OXKxl#@HpaeQ)*JI}qy z{N#kEkKW>~*S^hce!=bA_ozox`nZ=p%Fr6K?p!IAV+Y9tfyx`sAYbQ{pEp`01*63+ zKK66J$RGd9{~GU>Xg|=mJ4U01?RrCU0c{Q2P0!nJpK&y6C^Q7)CBuE_< zqib85dQ9|=e)W*?od+akh`PX7&F1n6I&69QrTf@s&f}|&)h;rt8d>~A4vPvImJ-Q# zl*Th{3K$$`r%$=MIECZ^%jxA7JDPLvm5)F@A)1<~5?$L8oo70oqm<@ic|}=S%4S52 z*Epy!ICkqLlTn4K8WIvZve|4Hx*d!8g31=O?Ut+M714W6PHt0;W`H3?&uV>zN`d)o zfzp+bPokq;UoZ?klgXI6Zp1{4L8BPD9Vt4r(##igil!l=7{ax$!5T|&j@5EW-)^az zg88i@w%aYE$&9#Pz-b^xy0&GvUDK}r7MwsYeO7%befEat{)>DjYwP*kmr38pY2Ci> z1vh6@%MUFWg)&i!WQ=*r_YgfQc~bJkBxoZYGDb(s*3#V2b|%DR6c0ifNwG<}Q55L= z{`6r`hcigtXmaiN!vftoS_;e*xm=U%8h0ccVSc+8IsS*DM|xc6g~suC6UM) z!!S6R5_Ke4Lx=_!w20y_@($4uqGm`DTfmWu z^kGLg1h5lQF(TynN^LZjhzdbO%JrPvFU@F{=RAGl_{5=Jve@+`0cEi}^8^ zr%!nJ+IJXFC)|1NMe1fmL`l*}QilhZ(%ImU^J-NF%kOQRF}t`-<^VS1IUoDfFY#~x z+Y5&7l2U7YKQNw*SgzKn;3x`#xnC`J+&Ny5l6*e~H{^$>LTfnzny65EMKA_!CqPX^ zVJ)=hPkH@M{(uxbqss6LAD(2;an1#y-DuIrxGpatbc z-nNk0pdhF_M(jT&*Qny)FxaPlOmq3XIh`TOE>-hj5Xk{z=^ftM-w=5oaQ? zurfqPMIQn_$OUI`lJwHK$l$Ehz2I^zX2K(!PN}a3pJbRF)diJzbYV#!9IBX*OofXI zuXNTsO87)l1=Z{>&yPet1UNOi|jBGXGj-KZe3U=+SY5Ih$bPw3kf$H&Li^-NfzQOv+Pf6s#(xLTjmw>v>5-M&R#)m&a(qKu^|N(q|r zj_qc{uH6BO(P+ef^gsEZ@y~wg)xSj<()Bj;E1y^CGvDWF-M;??_hvS*BGKf{Q4&RU zN+>)cwDG7oprX$jrabBAv-+O9sj_iMk;U<1;zB1wBtXtgKWI1iMLIWKdoc38DHV;A z${MGPQHs~w2S|7&hhS?pDrvMSq%h~-Ck9#T`Q!nev)A|8!;vm)9K9DbQb&qvczV#NHvnSkt{sm^YZgc;|4=|tK|JUFR@HY!8l<$)J`;^@JPeE4U6kw5!4U!fuphCoz~X4DXe zPO^Tjq3e6ryB$aKhUCGkfGs5bV(^X#)V0R=4Z7C^rAbAJCUW-ncX;^CKVlqvtkFN| zdw%lz_p{l|Wj9eAHaBu=h$!P_qnQS@^2Fq`em!4y_J%y7oUrpY5v0jcMzn1@nY?`z zlaFjZQ$~~RC+zFXko=Sk`;yp}hsG4q!3ZQh-N<6s5o5HV<&gSia#~x`Ix{_04$RP* z*{QROIuF<(*S!cXK;^Y)GGoMhPd6k6Zy2ItHx#skrT1R8pg!e+oCD`G1%nS@3d6)k zbiZcXZVAN{UCi>=TcdQ!9A+aaa;o6=-B-AMa$ity-}yG{r%$;1!V63mM~o*&T%Mlu z^wFEFuP(WB{{fT55!zUMit^`-qJK2moEi}m6k3T+PYay=a3INnA+P+@&$2u}=fDN&9V^z9Z~6c}xVd#x2(MO?qe@0Q$N zG}Jn=JU!#$^a&|+l*X{!>}dPQ^!D={-Twe)bVTa|Nom~B;kuUTbb_{)?Rt$)fyrc+ zFK`K?4Ss0ZtuL938melPUEhK2dId>yd~_^PkDE1aXc;vnr7E$d#G-CCEBw$gn@lOn zTH>ygXSKS5!7-goDe5MRT4bBOS+8ifD^lpWbLXz0lY-9u1QbT_N9*ks?Pg6;80JSu z;#*LbUFY!5b9_9f?>n}eEki$0lm*9&BdoRbeb4FBr@*W4k2vZJNu@93AAIHWe`$>I z``l;_K%3{voO^!w`~3-19G9pFrUFx;a~?O*p`w#w938|UuCXLyY?b!tBsoDH*kM|9 zGVJjbIug>2n7Djt*V!W|NFRM|L_(nrkk3XS!0?zPI#HppNi?J;3+YqNWi(L}qrz&N z&+Z9h0x3ysVp+-?%!fdTP(|`oFO6GSYAPRbAu$fndFY0c-VHb>X+*sjOp?pdmrmtv zM)cUaVp77o^SEJ2S;ou&lW44%ga^0h#`&a~9^Yp=IpX~EA+NvwEyfp*xc}fqX489& zKQ!a=>IqLz-{j)*33ngdXMTK_plZBNIa62Id@36mBncrLObUmuy9O5lm-xU(e}>iR z1&_Y*@0gUD&<>PMg|ann7^o_FtDasisY=7Nl81&HIy8x@8IwX}@E&UiV%VU)A|=OL zZ@tB%*S^k41<&0*;SZJiJJ#TQC4F9fhA;j#rq;jft)XO{|EGNV)Bl8L0qsA?E9SbF z&s}m{efIZK*IINa!33#$Daxrmc~bOJ_mUV;*e7$PJ$pE2B8N=cN*SU~`@8}%0^PvB z?SaK6DYBqBn_S{y+o_EpVD=KDh(hUrwmRdQLlF60?ys$O50Y zdD|&j>n2Y9P`-`r{{0;=9}MT zbn%G051yl*oG?U941441p2;Z2)|hD=*?MrDL$06?iK1xush|5N{O;ui-SQ!o)wo?p z)iezIcuZ><2FK~;71ixIg_eO~=yqrtOjYB306)l8DJV=-^y?+x`PQGYJAH%aPbQo! z7QFpXRKEYCpPlpaOUKV#a`qRTzvz;)-L9C7N3^>g+jdL4>zGVtSv(+^r(L&21<$A| zxH^3clHx-zzJMLw=F!r#2_uL-qoyG$jUIN`QORC}fZsAH5{$rYmOS3A*e)-zT8Oh} z=U1d^#tR?$7^kFE)WIUd-+HL7u*i~k z0_QzVT{F9Vg3<-s&4%sv9Ah-LFz??}X z&ITj-+{J_LiMSV-3n<>igf=$kqvkh7jL*c!X|xp211?0~@G*Eu5=|HLNkk$q6V@B7 z4LOM@<-FoZaEUr3hC<_l$&AiGH~7q|lNdPXgyHF<#`%Cwio!zgBR+N{20|<{MB3n$ zks_S`ydf!cQE~f)mzf?fc=G5izV*#-a&olf{)6W^zI%ts@r?7+$2@xbA(s~y+i{I;8Qaj95_$ogz_}eC$)d$YyoM`q8(T7M3`8%2CA-3&~}+ zvbnjuxS~3lqYDT_hYy~p6jeQvM4&-oiaqJ7!!I9ke{OlOm~ph2K64)byYb4R?(eM> zNqvT&G?m}i6((>EV^=?5)0qx+4`uUkz5k2rx|hribdJsD$OO7V;q#C!vZ557Xxov5 zE|rtIt`pPpk%((|EqWi%Dxnl9PE?tZmtEmgAdm*)?Xo$)RJX=d6oHq#a9Zm{6p7O$nKFaFyl*f=@OS zdk>zYca|rYR}5xK+01df6c2G53DyU+TEJM791U&ppC%|?cZ`OyrIwh0hSW)Z=)Fl_+IcH+UGlsk-rYjrp-;} zjYgAefU!~qs365thLv_Z@7+WOeu;ZG|3yvhk(h6MVf>g94RHLsvra{TFxx4cP3C; zVbq13I~;r>mQV$U^Kvo@Q89#obC$N(QfyVaM?DA)hjPKTbzViv4a^2HtW2LFo8il>laGHD#P&fX{(iUY!cT zHUj0k7eg*XRtW2dE$MaL)A`yUT1}I;qFKk8wdkV%+-GL*=^F<~4j6?s0uCqh8u#WQ zQ6x!Zqse%^LV9l-P>on2VCe-N)vR6Po+E$v>_r9n_63@x1MJ@zr*F( zV;((zozsg)+<)#x=0~@9`2$lfFQ4+{(HmS|{SkNXzQEDRUC@%|lX8=3$OILmCAcS_ z*o8$LNCXDoa`)vA@X=5G6Tb0#ze6Gr{D3J9c2v`CHjD~Op)9Laizy6MCEfwIS);8` zSd4}=i26)Lm^U@k557#T6Mz2`pP-!0`8QvE{ck*PbWaE5vj@U+ zyf|idwBUTxvflM5J3^%$$^`1VqTLKYWIUeXx=V~7I2u(fH;#*^4_RNFX2Y4`YPDvF zhC8o(g2mmJ*bbhMJasviSm6+9cN>bLz*a(Z*={>V(-GK0JPFF+ho0@~g7I`r(Ts^n z(RV%D^@{0y4oY!$agK@}YfHxCxip0?vAMiN;h7yBqss=8rf*v|>r0BVU~%gfXxVI} z7};!h>^2*!(sFX^1ZzuL=kPHytw#WK+YP(z5+Y1yQ|hM4v^lFgXO@>g80zSK z-e^XYcc2|A8gVFVEk#dd$CWt*_5gNeNXgpJ;4`&g&rC zk*29+qp20qDA5`v(KH$(5mSde;@p7xAUVXrOLS!jNuaJlBFlQ`+QD98T^ymQ( zKJ-z({&*=^h@ZTEvPJ!YHkvp8SKavgaAP3We{r)J203%bJYZ`XvfsV#=|kPyXKagV z+~#w)m8MgBRC0jN&8Evkwt9xdeY5VRLmEuXI`sViJ&F;Cd^!*Lw65|sNgvXOxIU}u zJXGhwF~)fPr;lQ~NJ(d!MuXHs3+_Ds5{p~+8O={PfBKLoPu^m=JmvPC=b24!F=U)uOd4%8F5k|z zQRpCx28AYQ2+`q#;=`Z#`)tl0^YH7x&$zN|w*#X^jcq1$eMhM!DC7KM!{TU6U241^ zSYKUY=5sVqR`RvdC1|6ty5hl0FJh1H@JHWy%Ao4M(Wk&<&ZH_UhE5ojNg1paQ>`+I z2lt*Mg~VHLKP8q8=$fK1#1!b-E36$$1ZUTyl43GxD79kSZh7mCH)z`}g#jNu=gS@C z_=J~V{wT%dn4N=u=$VY_!{=?c+fr0DF%|S7u-R@Hji!`EMTnB1HFQ0@^#$|kl(Mb~ zDba1VbY0JEHY2%#?a+}@q;6_PqZwLP@*Y|*QPHzFSzwC_=e@)|`ku*jO4W>VDwCqy zt=VlhpcM0?1yxazl$hOy!7*xT+|aUFE{VZ0nNApwXP^xs1%h|%wvMjtP%$tW*NjR_ z(j!7jJbe6^7!%{BVX>GC5FU|ibh|B9L-6izZCUU)NpE}K8%>fIknBFHD_W8Y+0m%M zcUXj`CEB^ys4peR_}xyR9b&f|w~@y2()%XE6i-REB9*2&#NtlQHkZ?n8S=idG2 znJ#V#;w1O?M(t$`iJ0YOC?#7@G<`Sl;MGrXd49%s{`gg@G*hp+*a+vN=D(bv(JN(ph8ecelen56D$EtsA|yz4<~wAc7$jkc0OQYA5Y zN;IYn+eVu_hzGRKF~2EdbRrCg@<~F8bSPhMeC85|q_QSGP+E1UFQckpaFNCbdS@7X zr0cvGCS8#DUoTgmXl3K-LZtTtofFe$vKDO$w5o|nVvnvG9=!M}Cr2l|{nnd&`|Drh z_MN+&+dKv_@lUXV=s#@9OL89*cq0#+vq5BOuB z`X{WfF4#PIowBs_n=Rwnj5at1KVXz0M(DN!wH;xSrQP-rmduW|q|6l14LfQB){J@U z(G%V{yP~a*i2Th=kPeOafkJCWlNn`MqD=wXQf_LOLnd3Nb6c6i>)?vZO3M_Vm6yfLmCs^T2Muk>4d)DVttQIimDzno{mXL zv0N`n!80CJIHNJPqU}0%s};5^SR5atO({%T?^v!b39e^4nb3@<#H8^ln_^X@Yj-F- z!Fwj7G2_{BcA_g>Kd{@b=(`qUD<-ok)A1NT3_O1LCdMdKVHr=RG@}VBhb8zZse926 zMCYhVgB#xC0Lowa4PN`wXL;#wxD9pODELj|-DpsAUI>UFqVbA*=*IKz)>wWkB4k=l36-%^=n>akD zzH`1|@BO~ddY;(ElD3VWCKiAX1V__0zlS+Fv2Vf#8n*7Zf(a;jHXMMjcsS zDuvX3b75>l6h|R*-E(qUz-hmAFu}3OIIzZ(=#?@d#Y50)gN`Ikvo`WA{lHwj6+2UFMZiPWGY$kEjbo8@QTEwq3#{i zj6~mjLKNzrK?I-Tj?al{gV@JMQF@G9265g2UKgSplx-NugE&$OWJuaF)`q?^(gkw) z7_{~^$y$kt4NYsvtfOg+ZzA)Ux^BHqTxBS`X46>erokA9wIFUCb=%U=VCn)V_DGra zTh|6iMpNGS*%`~5=UhH{pWB-oPVYb9Z&10Gi02zDlK)hp=}$_*{uqcfcKwV(zJU%`8WPLv-yx!vEz2R0X^X5pZR&R z>3v$GaMpP*RS9t%V-Re&8>EE6D8reSy4W$ubMkCNYkf~qmU}ka6_e?RBuz2Kv0JZ* zoMVt??907hd`ZV3$%zINsXSxHR1_{oX4Stn45ugAAc%QhPW`2mx()y3R*%I@zTg zg{^C_2+~f3I82R>f?bmFYD;AVkq%o?CoruiE4S8oGx)|(CyJ(ZRGIhXtZGA5x0J1< zYy?GVkp`3&Sf^-hi!m)tv%ULLpGixPC@*&Ih9-(h|Nu3i3fe}G;B_vV`D3>7&;HQtDKK{55 z12jj?-5(|laz~A*y#uj3Ymc^m24QTUCL{2vT?pwnpTYP%gq?elk5nL=P}e%t=S6x^ z*MNo%tngwNA$4dTjo+L))8}&c#_Ym+mAmMg+G7;T{|wz`)bqIAf&UI5Iu@t@e<6cs zF5TC3V1-9XRG04NpSuVHsE~dzmtl~%Vd2o#Ib|(2@?6r$SX!e{+FSmBz?dk+X0|km zqHY~^(^4mr);OvV`CHf43n*JbS+~f_+pfit&x$s-r7(}ix?A{J?Au&`F#fC zQ?8%C$L0HPvtB&s{)1PTPtTd;Q*Ljb^X&2oH@8>Zf9Yigqd5re8=#;I@LA*`pWHcw zbhNf%eD5Vb`xpNszVpxjvEL%M1|=fWWJFW$Jj=ma>UNKHhA4@VT5@@LOBBVNo=ng} z($XTSh=oA50u&L{UzZ=A2G5nrh2-yJWfC;hg32`i9p(^(j7keom|vT5Ft) zXpE+;4QX9zOgW`(n%0?ULJdMLvDN{a1blnT{yK0A|{nsxBD~ zbC8bBdW`_a;~_qoXNwYoJPBTzQnN2hcDoJZ+1NL4Rm*<6MoT~_%DN6N4UTL)Lq`eQ z{hrNs%_vJ548{m4*lic=wkt-{Dbx80S|%6-WwB+qSs_`Nb`*K>Kd&SBBYk2Iw8_2 zE*31VS7ebUI-e5>fpdzI#_xWDLiVSRpFaL%jb?qcJrqYxXSY?fN6n|@MR8C+cy>c| zmwpx!yE<^yS>bueLi+7jw@9ViN`{74D4guXlsdrdoud8V6YM&Xk?3IYF7?NAn4LAj zWj(0So$b};hsHQa)sNySf0(yQXqasOxt$?WCqimzkV+tw@|o^I_@G3G5CtF50K2oh4A8$r`rtf^>B?R^hLf-wnFC)|Je4W=h&Jb(I#cYg3a){`sF@4w3FgL~xj zG1r$*dH1b18IHz0c)CGezwzmfGWd)?(`F1KkDrD5oiMHjBs1XCo%j zi0Np;YP;vHci!dgM?WBoW3nt|JQ*^coiG^Rr*6GiX*7(<6OC0VX*A?hpZz57eE&`U z`G5c0tSZU9S3bk^;x$?kQ5%2WIxJ;Xkz^S{M{L$hB#zN&h7gL~dWFNGj>jP$dkK}3BhNf=9J=gl|b@ySOZGQ;Q{-_D%8-F~m z{YMO)hkWw@H~S)cP&jslSXl4J=$k`4x2JoNdmN%O{r2fLo)o0IQstXUWFJE*#bNv4 zCvzPtVP~BbCVJ<5;k9j;!aXmu|9t0tA%#*Q(or5Y%U!>0L-K|UK5g!ZALS=`sXOry z-g7f-<^1AQ1UiB4mm;pS1quzZwcwP0E++WLsajx6;2JrJwaVLtIA~i-VhoM(OBW5}(+e)2z0Z4(-ez(AlzT6|Ogx@b8&3`Byh#y)&Re>zEoU#i z!KeS+U*tRg<9|mSL9w|-rJ5wqsP+XqBoVcBLtC~C21A@}xxHPIB{5?uNi$8`SgaF> zNb*xH&`%$K+=tIPpNHnrys)*DFKja13()$(F~irrZX0;S-wcDdu)^03p?X*>%&@+` zSO=YD7!rgR{&`VR_p@jaI(Q2o`5|_#p%Y=)=3xG=e67OTkjCa~lQHM9O{;?9yrUCYZwHr3hAHeyMNt`cm7z4=)x*V(NcrZ!G0-?i zYYQ4v;!H%_D3U1V^-uf^+s%q6@4w6MfA9A=IX~m{;yy3E`YC4f`#gF79p3!jw>UXF z;q1XnxM)BfQ-l45F6x@`^Z%QE^OLH$B(AE=rOp zVK^AG-Q040eM6)bxl+go8fP(9A`^xCfRv%O+Ot_+bN_74XgFrESn)G&yut5&>wDa` z8vtc%yk;N%hQL)|a z4(bjmXxfH2&B^jHWnHsb-jZlIoy~DNVYS<^->pcah-^3_NrzY~*lpMBcT18qV|sp$ zl1a}|c35tgH`KcwgDmF$y>nEgxqkkfrfG<@CP^|Tvl%){X^mmIT2kybNZ}X`hvcI% zv5r_RmpJJ)65SF;bSYjzPhxTG%RNFkslf z&Nact!v=%fUmchFB`sWyXq*=SXPwx`G=@ybwWg8MsfP?VC(bw3i{9TZF=F zkG2u2hj_eiokh4nvbP3l+fYz#FEH{-PG8Jjr?zy?fBDc5cLi69!&bw&7J>2v-%wx= zne4$(Ny*Uc+TMTdP}?yG&0rDI zCNaYl%Eq!Q44blLSNRO$*1BLI>lNe1wnWC!wl%G(ur9*Zp3?BjYoDMzKjqou_xSzq ze2bHdSGc(MGB3aS2~JLDJbnBwfAH2HFqxflcK-osoY5MB5;Gho!9%cWEua3m|A5V6 z!F#{|JLIvUDQk2Td&tq*KwoGm>peQrL{UOhx7;ok=-9uHX`EmjzL|9&w~gi>4T0SC zMf>B!As?GZS^Aq;tHaHFhl|<%i01Mz#Cn9f4ciFMyX=Cq zwBR}5CL+rQeEKt=Wp(?Ur%&GJ`s#`YuY8Kx{G2yF^H~xHaV`nXXU97dve$iMfO{uBPc|K$I{esf8r8p_J_Ni$ww0F9|AtCA#5iQ|m@e$R5X z1T7)6XdU_2w^bjQGE{G_c=eTs3`aTdKfR@DBvso|Hzfi`k|bnF%5XB_!K-g@a`6gp zKfPj{XEa5{?eiONSC{70t>MZ0w~S8i^U`ad!9^p=HuM9**`;k7Xlq8p0p)&+Gd1J! z3?UNL{ZFiG9k?dA+i+qMM+&ZOy@Ic!gYF zDZ#0Jb0Chm^+E)GkL$Wl>x*vRg|-1=3WZB{q9Ng<$y^c&atAnZ@Ss!DU&zjr>z!*u zYFrl`7wkhgO!qE8NWHztF;zfn51j|an3EER@eOsK9-;i}(iQFyo#`8O?Jqd%Cv71F z!djFIv2cy*P32uExSjUcm*(NHihT6X)IT~V_x8yW-# zNo4{(8APNg>k?5Y z25Cy9z1Q4wvqES^Bs5A|T+@jiK2DE63Ih4*W4Ma8Z*7!m580o!V@fzcQB0;|hU1^*`s$j?ci&|B z{0V0dUS@iBpW(>`S5F`F{Qbvlt}l6b|78ZFQ)(CZtE(y43&G>7 zB}4-vp=q2VpIxwX33;9}8swy-A@4lC1;yFgs8A=Imm$%rqWj>vul8o(c%YM5ijbkSBGjx=&T5s5_7bJ1Sa5yB% z2mVeG8mwWnUQq0|M3LfrI>TDWdby&qElCoSWjVt%BO46a?Dnj;SJZV)n#7!)T@Xhp zPAYG=7w)TKw-{;yK@-Tn0ZYTmL*W*HbP|L08wKe+%;i8zfe;E|LUS6ncGhT=@`*$kuu>3f z87xD5DoFR97#9(>7Twe|ZHsY&Jl2e}hlb&NX?a$WrfYAhiJ1S+hCr`f2)Mv@xxR z?nF>)yUzA343}ZRvZ2ZI%^(P4d!)x5PuD>l>6=%9bHaOFI*#g|^^O{XFnF7gHWU(w zToZtjqt83yp1Pjmk1`m`zc$FKg;n;G&4uS}JR(TY(O#MkWeFcWY>Ei*T9;7Z;q)CR|=VUxIoO2jjS`-gndzr^?p7Q+d=cHOA ztnr9f6k+NbEfrQn+Z04eOrE7U=_sp;eNp%X9T_1^O`p5@Z}}*U=5k|@a)5GmxPCR+ z^d6BNV1>nKP1$$~SG8Tylr^i>RR9DO*EdUyOnK#JevWi{pV9^4YoJkB>%EWbx+K!x z&Z#IH2BQ&5$JABLezRgS8u(N_B*lJ5U6#zx<|Jv%`u3LH@`^z|ARP?ZmnD(bOs8YY zs%E{~preHO*&NdvZf>q=P0M6FCQCD{bu1PO7K0Lgy4qS$RvQZOD4 zKu8vWW0_gz(q!X0_t>_6lPg2BQHGZ#anyWUUnh3A?}iJm~_-CI#RgsP`K=^FFa*H`sy4u9Nlw~ zJ&y`}^L_BY3*MyNRzSL**Xfk$QwLP=qw@kI539GBRq>;cPX^f<-Tk0m{4qHuQMDKmqv@K_6Q|2cVo<4oXyMOR4w)0c&KX`?Q z4<9f)J>~J^_xb)?-)BCX^5ErHNOVqZ1d);myXVdC{2rT|cX;W+oXd9~_o`N*Q)H4* z7Y(rzXzf!&Kp~Yv7Vi|Lhz5i;oP4j>EYwDMg5z9>+kSa{>J~BPk;93xm?zyT9PG_ai*CLBgVO6m_-ay zO`J+p6nT-K3{ZAw9aQ+OyOqHzNg9+?VF~C0N**9^r+W0JPuuD0*s(arg#p?LpKl)O zR)2X**_V$)>Z0>Wz?r_7tq-x}>xY?iND!b+3!X>sz962?u#c2~05`61gl$eqLxd^#(iy4Dy;6G=a`TR~%L zBJFtfl?R-i&3W(r$GrKS-{Rr@mzkg4;}f6yG|Tll@4fpj-}%n(a{s{tPS5YtI!S9G zjU?6PId6UUw;99@r?Ua8n-!6cY1Xu$x@B6cmwv~173dp4M>L6 zwzJXl*R2s2tpsgd(VCVxP1tNp2KfY{h}zWbcN_9-Kon;fC)n)^n##lLT1c+0ui4yQ zbN^&Yk`CGID&lm&a4=xK@m`g)@sKDTvfb_2ZCAu;%xpGCD$RPgWxHAusfgidz-ThT z$p~kmD0b|&8>BGgd5pC#Y?CAM@t7pZ&^p4JmfNcgaLSh<2vEQ*PHnc@SQ~`%&w1~B;H2U}ZhT?Ga0F!s zGr68?B)ZfLVf!p@ailc$3(teE-kriJ=!y6^`kyVZ`RS}ogp!`XWCHPC`ankLv0#~Pc)6t&M?-?xU^Kx3dbjyTp~n*guA{D9Nxm}gI) z@aA`ao0E%|Il1==pLpX9PR{2%ee{U$|K7jm?A|@j9^9iYD;|C4U$MV@i&xHuOzyuz zisij`pCP1gD&uq*if#kSr$H^3J7)6%ah?E{wzU*R>9-soJC5cf_tn4m>+t1ogk*JjareD6RR;l$l~*Zp!`vw7hA1y!O)Yn<#2-n}wj^%h7!T=%>>-Z@{xdOj$JZ!3_< z;}RUur%w6XBmJGPahK38g9m4K7MH>;GU#NMpPhe||W{}5>M-8jZj$KjGHa?w6BnfRAQ`9Z{#`ri)=iNM%ao{v< z+cFv?{LH6bXK{VQ^QUjKxOv9;gV&gx+++ATuTH;w|1r1EpL73}ml;iGET3QU&bR+1 zS-a%5dsE!Wr}*~oeV_Ga55mWEMtM%L-BQ&JDvoI?pFTC64~TS(l7hNwK$N&x_2Q`y za(*kk%Zo*#wC4aj(~w9<8Vj;Sv0LA8`}`SgTal)k?XF;5InG{sgXz6b&=9PiJ0G*yY#lI>>io60D{v@M(MhBV30X@(JwVpmcX6|?!Aw%Bp~^a;ip?%%&hz>A)ve_%Q2^ zn#gWr>N=&nSLHcpu)_BA0HGYJJGk%`A^z_zD#U9#>yS3Y(HRrADH3J7*f(#zWLn>7 zyTEla#*jKm-b#k4W-?5|q+iiA2BkGgq%ebo#u&<~qG$}e+WI7pR$z?q#_*E?dHyQP z)taYI-e+}n#rcDmnccf!{@I`B`s$iz&mOT^KB8DHpxE%q2Nz^Y@Tu2d<*)sZf@vC7yONW1Or(89tEvhqK5qO>fVcVH*Wt^*_W2*p zwfW@d;OpPxZQ#{^r?;p-=7;c+d!T9YqK%?*EX#(gbwjEwS*jUk5qTmR4fS#9Zp%S#HWe%o|_WkB>z}*ZHm99s3Jny^Wz z5DOuLpJ*8RtwV_eyx!3aoHJPIKZfugn0F$IozGa8U5JMDiEPrF3}cN&1q(Z6eXUg{ zL=YPnc%HuYHLW3Yl01=&a?N(1ve{MacAguaq%mm{F?N2?Et{HMZP_;t+ggm4v>k2f ze9m|};Ogpz_kZwRhR>gK{_@MbbpIh|vooGOeZtds|A6O@Yu3-6F-;`*Pw$Z`_{)Fw zFY?Jxe~$mt|K{dSF#nj{;7gx!8kRW{7$Cny|GpT3V)f`<oF*PgACoF~T`kw@bGBf;`Wd&rXoqzmC>g){9%pqCg7elaQoFCkaWK zqoV|zq1qR0HXEv{Buf(};}IaqM`ItfVh+}3A|M4qiXH)I1BZAz9#HN#>~@785UeH5 zHK*q%Byo;uT5g^{C(AS9ET=W}oXx;7;T!+x@AD7;5C8f@$~yn>&W(?>(R}xL!SDS3 zE%Q;#B-acRO&UjNB|upOEw1(Mx551Q$Q#p&WBU+y2M+3OmHHwcOqu12#ai~s8@;Hg zE4oMORo7u(CMZAqvB*bcb_#PB8e|s;^ddm^hXi8J?Q~u4u@rq`iM2s@;3A|@7-a&_ zGh_~1MQjZw_I#u~)(ovesMnrJ-&el@c@-lvc#a zjLB%g_2msu-u^Dvmydb)$|t!vKY@0|@Bi!XlGuh}77?d0Djo6et)4l7yyiaLOWMO;uH_)@$aIkrzryfwAq!aHHuT-+Jp2eEx?^!kS#9<5P zEW*_wgE_fU0U~b^PI(y3YEP?i9@UW2ZB!vwPm1nCM5>J<-=PU)}=uymR9?wtrFwE~#)wp%+~m5yAN`)L+pp2m;ch zj*ul6P#jNZ_ncNM<-xl&yw1+~On0R5<|09CVXZ)EixkS&dh4Tpt#fGYlUUNgLC=zy z;UH(duUM}O%DP4gNfJd&205*X*%vicW7t;>W$mb1=bby8L`5-ac8~dF%;l3y-uk`Y zW_EU;`!B!7D=*)pTEEA$civvf)8!m92%Z~%ZJi}V!2>2p5cT6+n|MEnnkSEJ8rI?vRo|~ zqzTpvo?b1;C--^v)iHI57r=oTlEwr;3u-@wOFMwSggz;?aDS;u%h0tEZb zmZoW#&E}Z4=KV)MAl7jI{ynz)9YRG6Cu7#DHLWqsPG%qk*SEJA+i-R=BZ@P&>n*$O z8l@DolNm{tBb=aVY8JPbl*NuTiinehG|foToHWi6T2mXtcD-h|U4k_vSN}-nv6Xr8~giBAB;xr$#b|!P&wlnZ{NC^U7D}c88iO=SyeV!Jd7FvN zo>WILpGndd>;j`kCH))vR!_~3)0GW?T&`Iw7o%*8C{Y@9J4CX7c3gG`gf z3au?FG)Gc<61Qo+TZYo~ww+cAtg#3oQNk;3F&r$Cq^FK}0$8w13Ow>-k56CsEEw7I zDGz@0E~vOUSiT8&7oia^E_)9Hy%U{)v9oQW_rvTML89Yh9_6s#^%)HU&rVE4H-x+X zB2|GVV>_Qt(Q(*)V`({RHih(ddC~>{Vy|qsP9i(Hz6*gG!8XY|b_B~L1Ew`Z+K|MK zVV*D^rmVMnwwpa=RiTw2OH%SArEO}ere$B&ly%FlZYdf=Z6vJ`G>!;G7o74JQM z#_IMNP-Aure&)d$dE{TmvRI=h4`{O)Wi5E+lW$P0E_v_0_ekTMwl<_$Lff>|ZG(<9 zrZucrTM`|ilqDPH{u=&(jb<7ttZk{b3nrN&Q4%E`tK}{4J${C5D+X!8wyaof8%`g* z!TG~av#%Q(TC`Bu&hpQRe)n#z_o%hy9@|!=c}AM~pLw@kV%v(z>=Ypc+wGFJ_DyD4 z7Tnxia&mEkMzC5h8IEV56K-y9iM3>UGGn_h*=^S3g8`%QDXwX_es+m5EyKx_G#?_B zq-iP^x7Tb}OH6>!N8=e$lA?5kP?Dx;*e`F{?hCAiQ9fii8X{GML$EIjtb;g-juHc< z-{1;|4i;ifRkGjj*lo7dWx;edCC-N=S>pXLgFQvlIFyoXHcRTJ=Is7GS{e2E5H5Jg z67(lkRsKYt8y{(-Sv$?+B|Lg|jV(7M(s2K5!fP*GFrQ@Ho9E2O8RI-5OEpO>Nn%B$ zLC~V4hiHxSK5s(DA)*YdXi=gwPnSNMmo7^^Fe`g)P?ufaof+b;O-ZMi>^PboA^zB| zs8g4_ZX?;*a~zTGC5Iw<^qcSJjyP5aU+4bk>9&%0_)r15_h#_6kLm3Gjg%cF;J`(d z$bPdc`j9v;G;+%SJ1hJ;QwC9jLiCVTYg?qUsLub-K%@kwHN>{TI7gNUM%jejC}XkQ zvffsdb;Qow@ zd*@g^~G)+SsM+l)&{3V!CRL#-+$*ht}Ym*l2;#|@$h`k$u#9+HefnR8D%j^B1scP z9D$b3?@Fyt5VAOA6oJ$@X=p{qz&V7{38VTycRckDG8LUyXWuJ_+Taden~uP@?CM^C z*!#t$J*s;>bx0f0{fytA`96Q3AhII=s_`H7IL)6}UAHlqPCh5@#^Zk|inAVajTl zu~_ce?rVy&Ak9;R2+&&N-P4dHU=Lmrt(I7-o~4 zd#58_di6EF`}QT@_^t0UTh%L~EOh>2N@?Tp*(aFsv6V9zA*sq(()G+tr53ro8g$KhI!( zkJdy~^`1CQ!UjGpJC5^BBsArYW_L?I922J_?-g0>uyw&?G6Si?X0zdBHfFzFv#UzZ zE-tX9VR?JQ$$W-2hGKimWHcp;6w8}ijDwTYQzD(PTCTi}QI>OZc81b1ZDUwmU2=8# z7#&Hb(-~67OlBu29pi8`Rl|0%rY!a-Eg6p|#OV;F{1T_N7A*x;U67>lLEww>niFTJ z>yqtiPf-+L9Z~Rje);8>$?}}afpLP?9k|n4D%!eYdG(z6=_xu&LYBJkQDlc)D$gY? zi{dBp-1tZv&2qQn`LicDXULKSk}2<(8PDD>iPe^Is+bQW&ZjB&<^#@V8M8seIE%=0 zMHIE@wk1*;(ON`py!b$rS}`eP9@(#YDXa#VcHf40)KDcaUk^{S7Y}=QSOVo5C~K-fIn7$-Ze}nz)0Tu zBekr+uXmdO&p;K{D>s$Xfx8tFL9D~H4ygr^Q<%2(ka{FYv?7ZX!@Od% z+4^a|GGs|gnq?%mB~K$pjiGKFMcGo+hPrJjTT59>M#FpDyEkEZdCRl+-(_zFi$?M8 zqOcl*=WqW*XrO%F{4hYahw^hhr_k;3P91I}2gvZSgC z+NQx8!}H5$C@IL&0b7;x{o9zgR%3@CjZqqLo3+&6319jub%5n9qg?ap>IBH7c1I&q~Rc0HnT zC|Vo@@b)P1;)Ttx=&3}aH=XalMDIZ?4&KV)msIl30M1cpheI9)ej5(vUNseT^Dc-= zJJhI0f5J9Zc-Xz8CwXR*MWRE#yAAmu!3wUi$jI|ZP1_JVhjEfvN%A;ivn$wc_w4I} z%0%Q@N-?qv_&??AU;8@MZbjrQ6^0~Esj3nyyyl@SD~hrqt_-W? zmi21;f$o5&SfLs?oelW*xBj)iK0oyuNu+74;Q7sxWPHv`_dZFKPidU?TVecp(K`or z+6TYYz?p{aYQZSaNb(^@DC)YQ+;16A#we}XtQG)_heH)d`_BWAQX*pH1^mhEcIARn+@ z{^Xq-AF*M(B%hoy$aAmW5)Ol+aSnr_Dh#(p%UjQHh{Yw^6`W2oKJoH>F6KG&v1T?N zFv=o^ktB&EN`X)k8~B<+`t%MfBvOT9BxO)=9>}voilF8W@E4x5Xgf^Ed7^%o@!NNP zwjaNH)!1?Tr0CV3$2rB}77K*?UJUf265feB#akR>b={u>r?OMsi=%C5pPYofV+1XF zXugA=Y|pQfo$OBr0hM*$5kRTXU>;Q3!g?qk<-8ZEHC`oa!$hYnQaWPkm=C6uMa^ng zvMwt2ttHD+vMeFX8k)wCWtzr1>b9Y73`J!r3d25%7$rka&(C@G{2A|k=N*csWjLE~ z@8TuQe#h$hW1hVG2Nad#=l|j_vfS<1UcOJH6;)$MbV6N~n6^c0MO8Jt{r3B~;HCG| z$DiFT>WANBik<_A>luW>uh)kQSZk>2nz}47O^vY@9mPoHk(J5mOXO+d=`2FhB53gO zi2I%4>1NOO9xsVRLo6y@zBuL82dA7)6XxTX=_q3uYw}op$ee_bmtCU#HNQ@j#iZ7PU#XIhsYg?F8lOy)6<#m zzUA(R73v*~-+xTqF@f*CP0y+C`1u`Q)E)_(tPMQ45FLEza8S}>@rLWt^+r#4c`Kh$4-Y5x0vqi`9mfPuZ?ET;5#cX!zNm{Vb96 zp&d8thUvXeasJX96fNw^nsJg*He00f8-8PhBZ@nmZ4$@T^GlLAA{m`xg{C!z&1TJX zG)C!|&2s6ZI-`_lPo6RyJ$rKY(8l?2fawR=q zrfwQG`+|M3$F?nTB)BPBo@}ldq>@RdIh_u1|C!9hf5mw&N<^Fou_eN9Q=g}H-oacCk%=yY8$bnidMg}mbK>$?MoRP>Nim%tQ62hR9x zEDC4gjV-VeY>8$62Du{&VVvX~Z>1@PmS97~8eBo^r`5-16B;>+TRSj(& zVT_?lTgue2-8Vi4vr=UF%UqnEa=Tb?vs|%TEEvQIpL*?8^5ixC)%V_KQz>40{gZru zbq%HshQF2P-I&I!N`;~-s>4b3v3mT`=IQ?7Er(wJ>aXzHmp=EQ*$;iRThtH#@elvO zf6YJmmpkvjC>*WuG8`!c);5^BqAp9Cs>T6P6p@d{=r{r82VbcaDj#^?KYLN}~qO*_dd7!R847;?oKAzXT z;0OAn2I(JJ133tXI?>P3K;8>1ZP<_n#k!D3DNRBhc@cXRyuhM5OF3adnVweT!hr1@ zA^y(`v4r(?&%1Fb6c*D;q;MD|ki?8f17@?9<)-3xSyJpu;v^!=6NZ_(yu<2S#< zKzrnd5JXZnHCkzKin{cIC8a*taewdrOYCMPQ6BS&*YD9bE#Lmm_b7?E_xjH;IC)6r zy!(KaHC0p6+KMQS{e9qMKNwgXO2KxyKx@fteufd67RPF{WSFOB$*!K47(3Gt4vEwq?6nGsuPr>sZ{}kPR~CC#P&TYxcWqhNBUq=?QgF^6beIs=6Rg z2h8Ua;w(j}C?Iu)-FC_H=87m%3`bL@(=&7&VVtEgE^sZq#h{Q1E4>|~YioAv8>A4d z7uQIo$nu`~3EbD2d3XL(Gr$>^Rucee+j^`vTv1Qi)qfqNzTbQ^94AO#Kt1E zM9MI)OP|c)H*jHk5WyIpL*esDM8VUoBd@!_SL%{5oC`0VJ4*Pm2L}-0F9ctuWQdCE zR-U4tln*aVhrb`0&A%uJ>c02k8y*qxIf|-u!2>kJ(plRZZ1tk14rcE!5gDwc2s|ho z#6`hAM7rLmPliK91Y>F|*Nt#k%5ly<@X2h-1xYm@&*_ zL@a3AhQ?IXiDi_f6m>&UO3G5QNnkvPna@tRzTL3huUYR(&gKvKh0o1-vM70Sb)xMxAw=`9OvyLpyn9onivJpZ_42C_H z{myc|mHgoOmQ1f1=aQ3g#K}16=|v}_lu;g$M3N}-2bnKxrsq1Mb*M8Tf-(%mGQ{_a zkice~r}uP?rcmlY@##>MPT(UB=#7x>VCxIM$v)-+y@0qo=U%{b4)#PZqB)0XPI0K! z-RJdn&*FM?#~no*yS`5q_HG|5JCTONtEipAS`%h@pEhJW9vog=B$ba3?bPW)IF$B0 zJgej25o#HvnmkXLj)yFk1&d9=dc7yleNjL6-#e0Uy8f zuYQ-e-+q%U)r`j@E^k(}B4_^6r_uQ-r3pskS|PQhD)$H{h;-u5qy92*C?P2KI~vU098KGkED?_m0om z$7CLpI^BVT)blcriSnZ7m5O81Q)d(}TyKEiZBCtay?56gLCn!+z_|daITge~!3xP) ztn;3FT1Zc@55>I8nU}($oZt02Z9}7~aR#&!q-n}@lCxaxSgtl~ZkObvAz3;kNj2Ik zqS_KSj;wB}l87p67-T7{UBMu8j0P#oO~!V=;qhXHBW5%l@-y>Ka_@Y`Ti^K>i|0?N z3$Nx&;uLg5+tw&84)JwAef*i-qJH@7Oh;90sjHHzDsey>XN<>F;y6VpjTK!whxevM zdR4gSMR}HLzh$#o(v}U*O42N6JiAAnBq*i5tr)_`B;t9JO8L0T7RRb-S*gn+Qz3;! zwn0eK*F6z9m!fYrJrCR*oZEy9s#w>L&!VF(bq-8NFngDL>4F8*9XitS_vr@fAixyI zb<-Wk{~of?g%mgwhHa_tTAK;iJBe89eKckGT<3hKg$R(lk|B}JhK9C#O@x1abx3@( zAvH+_%c#jXVUTCc_N5m}ZnmteiqUvNoF*tK(XA$`A!)pAT$RR@X~Q5*SnVr@gN*Sg zVYSWK7hB%HUSM6sy^9$qXH(ARW8VJmcPO??irog&7Nk*1WovK-sW~L;eSpViyCK$^ zva~$AdCu&?YfPs1*&9u21xU}FwbtJs+kHu-W3-59IlP}r3hJU@vs^Geo%=8Z2mAFc zd88N)ayIK*TvPg_Ib*qZ{~={lp)n*;M6oYOQVl|}UT@KnCP^~Z+bvB~Ga3$YLh#vjMBb?AUC#cGbV!NWM3RI++%w|ZXD2ocDrVZ{6GSEJR^4_aewWHW< zXv!KXAWjqVLCSP~LKF>f7Mc*T(kE7h`@~wyezRjV93o_A&Dbrld`BULV7pl%rDHmq z)3yO3??i9T(r#$-NPncnQQ*60@_bse3Xq_+~&d3Hsk~qd9XsvIIntp58 z09Qe%zV%E36MTl8l0KP0B}geLE!5Vq-LyPgm%MekBa2|1N6f|-$h zC7LuAq_HH9d~xwLwDrZ&3U48T2#1C8!ke%Ka6%wm*cJv3Q(t(xd&zb@A_-Q7tl$8( zi!L|4tC{wYqIz`bfjRQpI#z>r(QrL|w1<`sYX@O% zNEZoPT@FG4i-*c>*c1!vMOadaU}_)uCK8AUX(s|5DY7(XHXU-aSh3n{DEE7^(U3gP zi3WnWZm^LeZ4_mqiIa#Vjo6hf!?IzJ3D!GBSsAuP#kO3d?3nrdA^I0a{O)i456Iy8zzLEhV?3LY<~dqNw8q2M7JM`vt{)CvmvR>1P^+{DdZnTyA|D9C1L8 zIiumv-N(g?b+2p?(j{t3r%RSgt7)3%*sWe4hZE3ZP~?bcBR=mqDXis zc965(kGNSZ*=`m{6)_l%NYjicvY5KXMv|&kB%$UdA#rVxMhr5^b{|t#t>?XOSH$U* zmtXxXPGtQ4w|@>#~`uTmL-t4gY- zB#sgg4&@wD#Wd%2J0Z|Y(o`ik*Uy=ZMx=3y!Li+}h=pZ5nzC9isJ3gQ5Gb86 zoXpsjC6Urt+fo;MhS`u^wM7WYWIAKLS+ZKM$g_+%PS|a>>~~wDG~%V#UL_lhK`L4Y z^}b-cS<*HQX_7HNyC8}qgpjP)Yn1l=h!^FD!iCEO&Fe>kR&NpQ?W1i zpd%XB2Ii>?+BpBBTj95vyUh+2Nun&FJzPCLIu(bK3R9QV`z^DRQ@Q|#&c9YUZ|k++ zZ7|iI;c&$5&62t(F{TRXPd_Fvk5@m*=lD%JBaxq2!}hjm$+H1zJ|s?u2q`_BZcS)t z4v>y<2fwrKruDv=oyVJ3Q(FX9Xm3N{5*pXCZ!I@V!=uHP=)Et?U{$C2@uz3<#G+*L+&hdsceY z`w`bOM9_sK-@Eok$M{ZP#l<0dv-ioPU&)I?bZ3ec;o$77o~{=@BZh+k zG8Hs+MQjvF-H@dbNnF!rDWhS`a2v5+*JN47sBvt!4b^^)lu(up&z~=Na5f`}1%kbw zA)KQ%&Bv(O3tPo6cU+nuwPpNwD-QCbe*De9^>_FW{`&ul&;G(MB6So7EblAZ-Rn{a z6qef56h(!rOKfApo$U{r@pwiy7@?vxSf3bb(}sJ_dc$@OhUgtaV*7jD*F7nvPw+zE zRE&}_#;v~9WWaw%%>T%NycOtGsq&cSd(alw5_*H zF%C-$rUj{eE9LrN+^{eVH?x%-87t9O3u*oKFKmQB`5I=dUleo)tUI2oJKxPC{QO8n z`9s^df75nOh<`)f6TxKUE?@oNh1{jBsXj(j1d5awI30p89IoHi-l=;>X7pN0qC^m9 z5yNrLX1nF~dckUO%|6K(4~JxVj^OFgtZ9SCQO00D>P0a_r#rKtE)h4|3>7ON^UQihcN|5B5a$i7j zLhxs$@o}csVr<|FOK9tg#r0FNR56*1F~U*qb|_<*%x2tNKc%h;(kLN{6I7(BiXEwr zv8{I!h~k*deoa0apoHf3>Wck-!(fwjm!5 z$xmho9b*ulI|*3h7~~lesGE}Ac0*Yf80$#moXKQHl6mCST7S0f_l1w4bUOI3dRpGW z0mhrNH%(1h?wQS}-gmcaBW)O}l$WP1R<}&XW70Iom~iQumZm9#8h_7Xc}0@O)MbH; z65=Ff5D$sd=tHc2uk)E-{yM+;PapBcFTUFU_xD0)`RJ{00iXM0eWj1I(HxAXj80yn zRgThGgf+fE1(WbDciRcC0Phkw`lX%6e){RwTM7B>Rc9S-Fk*L7Ba{ImYA0x0!K$*b zcD#9Apv4xg4OuFf4mBski1X=)({awpBw;>I8D=p_Dv7jj@chJU`b~fhFtjtlds6Da zcZ&VbZY)-a(42KS!6B-xhsR}zlOP7N!1u2g@dbPcleF>o#@=cN+F@sQDQz-+eR zcClu)+Oppl42J`Tc}gODv}My+(pXc~mO&da&U2Po!D6+iwa|=Uz2C7|Z~4rp?vYWk zyjd{FV&Wtv&2x&fV6|R-Yz*7K`Kw>x*MIppc;_ph@8cl9{0)aYihX?a)n9S13Bi~D zU5kVK2p>^8z)0nX-*9m&f5u`>O;wdtMM+~DoD-x;#%Mf7MKMZ8D5c3~_h^-+F(H+P zE(81k)!LAdqUdbW{9$BVcRyMW$Ql3doD)HbDi9*_O;Dt1t>4I$mEdM?d4K6p&o*eW zB#JD?U8D#?&>pkmjg&j$Xal?AQ$2Nvv_}r&>@9p>SFJsf2E*l zTaqNjnuhiAnmCrsrYBgT*p?+t({eJMaCvpfe!FHi9r^7gil#AWA!y2yILl~SZ=^pO zk611jY&Sbbg9&*yplvF&kW8j?hNB5mN!q4ny}o5%>=EE!-#iP>3U#C#NSHcdI74qy!||2MnB?J=B~>9X!F@Om`5TbUq8hW zBqa_ZBF=JP*?04MFx|DP?}TM&CZ#yyZ*_}^V4UosuV52`3-NL-QhJlz!EnOqS;6hi zlI3E}ZoMTR3>c4d;#iQhEp^q<*p#YiNwSzhnsB?`Q#%-qyh!5V>4ZTcn+7q+mwN)2vydAZCP&&&sH^WK50>EOBx9#xn?|w zI2lKr&vH&DDU(6WY@9R5HA$q=610#A<%ONbS+FgQZE0oO553+^#JhL&^RiI=sVk2D zt~X#8>M&^cL-%p56L$kM{;0b5Li2ft*WP{Xm`c*1(sf@d(QSk7^JsIO45YWvoof%Ih*Z{o2y$E*EejVnBi#1FwaO*M_ko3 zjis@WCM{W(Fi7?+cNKXaGaV(IjZ&SS``CB-sdb#;&X= z_a)=;kek&l)*7bsQJWtD4-B=N+%p;u84d@Y-V#MPB*uA^ z73@*CfMvhm636l39`-z%gY+U;ik15k(^v+xDNZP~6k%c2(zXSzHB|czH_zTelr$TnrR3)3hI{81WP>5bboXH}Z5QzW{=fa7`TPIHn;%lv`8VCKe!*An zFTE!CQr`r;hWJvb<6ryyPu@n;;%Kla+u0lhFH7Mki%!Wb0OhgkKj_dq`RR_KJH@jlEfp%!x7t)JvX;YZdYq|#g@r%$Z#-V zJd7~TQPwqeB^YWCFI{hT80X0In7XRT2QgbQ*3cfg>|5ljL~H7w;j@_b~)>l zXgX-DZ&q<$DJnWZ-P@V8*7iP-Jyzg6lrCHl09e~wv-O$d{ld*1{w~Djst~tGCqE2A zJ|&gsoI8Ob1T)|$8p~qQ!0nDmS`v9preTmp%tGBeoeY?da!w{0^GU)mi%1fQRsyYk zB{Ig~talSZ7z~vk^rb)wjglIHLJIFkX;tUlY5mXJ+0D5lj;2t3N=i>33InlFKWx7w zx+e0#K|0hu>kiH9(SYr`TFD_c^Wcr#Z9GF-9Gw@Wrn8yz#`1?jT!olH>rD7|Hq<>E z>YnUTI4KNCqDhlE)A5+qYRmQQlH28i-A*$dPe_x5K`N-Nr79~jB^bsL@oLYyEFskl z1_^_*WHd^-e=+CbOZRyE{uADN_kFTFCsK;dX2oiK`)|+Dl!AJ-;Qif>q9{1I_X=r} z(Hg(xNz;U4U(hrXV+?T;6GbVz?V8Q7nVlWu`t)lU+ zCqi__)qX+cknDHfYV6{{eT0w{rFSqHPv;2jC|kqk<~dbektQ+o(=&9E9paXq7j~J( zurGF$`vTKc=vWX%g6Zr&!_fp|eP3bhA!b_inhd|8Z(E-rm8K)_Q;Q5*Q-dNn+DHq| zP*ppovk|U^y53RM6-`xBH-)#^a+c-dn)~$i5tx#PhX&V`6EDWvyV>r*CdXtD&T2;nqV2r8g#Ew{Df$qwYR4Ut%pXc)$d*&t#* zPB@vSoX-c$r#a(s%4m?1YDKJrjT3E9ZMQhnQa24!wxMB`IH7{6yl*a*@)^B0q-sbc zqRTAql$*U%yYcBj9o+4L|3XK&e}SjjbHJQCpz3`j$1zFN-OX@6tS04V(4mjzH?q?&Ebn^UL62j^jW7 za4Y#uzxw>j#Cf$YC)tWLIy8h z=edH$))*ROFp&p|v#R&`6v1Z61)ogWrKs8FX!|J-NQ@7eJVMCjK^)l)&;26wkfPEf z?43~Y#k$wO2S?k}Q1|=-MJj?Uhi0~R=oMv2OF^4wm}KdQgZq3BW^CQc=;2bV0LL@FZEF~$T-F&V57t@Gg^P0MC^%VxX8)CEo5_!W{?s5oUZ zn3JaoH_x9iJDoAV|A59szR~S0p`2s2SP(}k)5(mcwY}g>Nl#PRu9tuz%?Fe}fi+bB zY4n-W*`Ul0$rQ&5L4?odb-wtDKz^4(^mV~@O;S*McOZp_VuO{2>SZhbV(V0nqHCON zZ$$1yS9ZHMHhesAN4qFACp8V0(pWZo!PA{XKHno*Ge}^Z!ekgTA7|cBewHzx4wy{_ z41xizj=XZw8V{^lTl@OdN{kaIr4hzAx=smi5-hs1Dv(wmifUIGk6@b)g72Dh=foYj zyoa5{LD}D%Aro${{`rSuE9DQtP~DVuu=x-NZ#)^eNx|w#cIh7dAm9fJ)WP~iSdDXy zr%Wh+U@IXQ4N`{rLyGe`S68>(-mWN$=S&9!Mw0=t8e3Ei9%b86FOvX8bEFsd8D8dig z&ToONt-*9+DTP)VC%iJ+N$)@C7mf~RrH{guM-Cjl3rGJh1sf&~buVn8dL&4yL&MP3 zO8Y|H>l=L0tK#p}J$cxOdXDB1kZ%tgX(10nFc+2s4o|`8+*OqWX?;SG6Md{4krJGq zOqfjuY&KgiFK@VBtk`XLOvfYgVMZh(lCokLM+}pg=eJuFit%{FI8Ryc3wC+JXqd9w zm)tHUeD^yO-hK4J8qKOHk=BuCIc2rw_rLwGIl1?cv->YI7*CNZr6~3&r4UlHTrP=| zl(w#jGG zXtwJmrFGo9_khZ1jFr7HyA+bm@)ji=6 zlnfw~>zYzuSX9`4x?s25#n1Wl3>5@IesgG?W8D}wjp6aSMLb>+Nr)pso(QJHgwt`# z*>u3ge8|}>XFSvl^N2i&(TVVxu&u$hmZm8}QSz#GA-pAtuZza}j7rfbdpLLS%j^m3 zy>n6LRU{9GRM?Ol2(gD9hY-hb(F>&d&ZDz~xsEoR2#L5uHg~<9=V2QSO6Zq4{d z{rn=YVhwOpSB!12k;?J`FTb2~aem6}V#&?TEw|4$j7C!?!x7m)lBb3^igQdnogw!VvfeIe||8Sk^{*B(K!?!ykG@EiWl z0m1>!m_rThA$(0IxRE_D?(a1z1P+-sLAq^fr7cV5_hApe=)!3G;mIiK0lqiWM#IazQN>4AEW}HuR&gVl;CmF+`W|&5#X^PNbn$|1b z+Xic^UI>bm-d;v|YK;*gEFxH}xlliF93dv+hm(x@P!0}H*m2}J-1Uw2Zru|{bq(5R&P1NSY{iS;@Fg*z7YV!vXg%&iLIALVas3 zOPCa(llXRR>Voh?c$1RzeU)Z>3B#a zBbwIWj6(`b+4>j1svFYbkl}cO)(QLF9@lJ{%%?~lv)>hLu5Zy&Fr7_6DDRQ2BU;l^ zmo-&UP*){Rc!A#h^To0}_6PESzL5Mu*pJNUD1 z)*Gs(=HztdkrKxpWMs2mBdujLonVFfi50qj#98MdFI&jKNa|h~e{sohv-T!BvWsNu zHj(0J?|Jy5holH^w?iOk`)!2lKf`C%`a+;QrX409d(@~Ai0PfZi1qp$b%0bvn07sH zgpeqtaZY=H#5o!qd*fJc4VRmWx1Q{Y#1(m>n4}Stk!C*0IX{_jdXjQFA2Q7|MrlMA zIh?C8&iG$#L)(BA3LzTb)P)tjl%6B$lRZQzgdI>V4yi;UhTkP9NaK1N*%bG)<0*_sq3xnH?LM$vOMPD z;2x)^C*0nyxVgIJ{l%KebjW-5mfHM9};=gpoxRbvbDxDaE_cO zq!hiNvlBT88T&X&>HUu@9HMsIlr4{!JM_D25@i`C5tD&tGKx8y4LLg*ae9(*G95BW z69$Pw34?VF#u-}MU~5N%H_S%1{)|u|=|=j2-*qPI9D5rFIKJa&na=sb9Kqb(dD6Yu z;t#KT?r^jpyy1_y@kdFVefmWRx#)PKp4Jd3O?}TQ5K4KUN#~nS*=J~Xt+bD7oJJk>6{(JJ2%i1m2NbI%^Ro+t)NJ=VPS0kPyDii4fajObu%;r96-vgmO~ZP# zKr6+rED=JH52wUQPJVU|w4^8sL}SQCBa{~Gw>!#WflgvhPNrn(5UC>e+bu=uVfM1D zvCffY36t5FB+XD#d$F7gS}$R}4kXa`oUue&AZ2*lrReV;XAN~#(NrZ(RneG+{dP^7 z#0Uo}Nk~Uyk|ZWp!jBU=qS$Y7&XHwf>e>s#I^%UE6wWlPZ=NyABSv{nYr9j@pp~ZB z?$~bDoS&aTaJ}fRFNI{gT%v5tcs4yWnZo_F(R4y#P{AU{PtR7kLo{MXpbzUf(@pyw z1ktyQ;wa%k9B~naS95lB`|d?|gd(YWCA)Oqq}Uq_9}JS6>$U^ompl{)A&#JV=M`UG zDQ|-qN%qF8q8Cm^Abj#c;~Yf`%dLTRgL<++$y+kjFv%n427ue@}hXHTzKub0ecW3o{eY(nhEgroU!*`oe7 z|HmRE>-fgPS$g5z@$#z|=Y*TU9dZ9G3Tu5TN|#LLf-u1y(OI1HYHlG9f+3Fm8r_R- z6Tt#0#N!>Ond3Tt-;iL_i7&n1N)HdZBdatU!YKR_Afy5Xv87YKMp_X>me!!1>l

      NI07fxPLO@-pP>JEN47S8DuF@B+){E zZ85IK7>hC8tEGL7lL`|e{5q6J3U6#Lt?<#3-SZCIcAtSBd=6!2pXd4w*1=0y-d*|j ziA0BOYM-%wXATeINZAQQY)@5kLV(mh^uxK{gVUdfLHyz%5}laH1S>r+6dmO$lUE*c zetyF9>uYY7x7@C7n2twGCo_^H;qm)VDfU}t(Emc*pFBa@JYnrxVFdQ+N%t_M>sr{nJ z;b^QE)w*zvcoCW(Vx;gec%EfA)6!bwQ^1;%|SH=O>6r(jJMYrGw3C zfwYF|yF}oi}do`J5e}sVnYy z^H(Vkjc_+1nP9hMrKHAETFdRa;nAu>y;q>cbFx@48EDR?8E3PEvuV!BG-EPO80Cq# ztxz7`$6B0g{lz9d*CNx2PY% zfNbr7<9JlaEk`!DA=g;+V!h)RPk{0QM9(>F0*LCfwhu`)hnnPq4T}(6-II6h$!wsh zsNfbML}v~z`(fQD(|DRoCp2`{9_{Ang?k+wZe{R&lrm6|Y)`wf&iRPV0H+g#M%IZV zWJ&aV#(n`1sFf`eL4=V|TgR?$xhz}Wy4j=N+z>0s6Uls(a5haio28sibDwTBPRY}l zSPCNPhi+#~Xe16CN2xRp?=5IULd&7<1>a($amXMFH3*`9b1SSldS~@fliv;M_P~R8 z<`5s)hq)iY=JL4ig$-v2?-0h}TyvZalidQw39K+!>D>a7Vam&cm$;}J zZmw@w-rjI~vt%|q<>iMDxxBunENiCI5ow~RtCswOnt6vh-n51&RwS{eZVa|5sGLJa z5z;}q+wkmh!)~)8Ng^bMNGYma$+LH^h?T(91#u)9jz)+$WjGijMMUj9Z6i+;K(O5v zG|n;@jyO3z@teM~VSRf`S!}V!5GNVK;Q*;dj3-kJ659$IV?%`Wk#-<#yQTEkcH1!YFlEG5`3Z*jI|IGy`VW@jyU zWc>J(c5dj8y3g#r#5%Yp6vA#hC;Gn)-i#fr?p~NYyD2(s9J|8XZ3~c{F))2IYI_=u zJxpkU-+2(qcuJ48?hZ(QoYrA%7dNLuN|E0NwqYAUpCx|SY#dC6T@UZrP6;m+2u)XJ z3{WxI3IoeuU%0 zffN`9R1s9nGE^rg0{q^Ou7M8i?q+o3)uuMoy&jDTC_;}O9E+4XC40Dk<7ZdOEIUOYoQ%M}G>!hGw~|d%n2~zY7zV5I$;C zD%;boBnMwpA)ObxyCY9x>n+?|-x!K8pmS93kKg++kRNT*ykgz>Wk{!1@6(Zv-p8JW zbf7o%RoMEUDUD+uKD@_#Heq?Y;P&Q*?P@`iO=yj!Y9P-uwA_=#AFS}%kYg?+G<8cH zL98`ZQ)6m_G!afnvN!<&i)T-9&7M4s&|0(E?vMh8^ErArrYQE5`;zJW3>)ft9L2QG zvfOQvQZpJ)$Oj{gF>JRxcDo&|X^FIAFdUJlIcbtolqJP}M{B*Alu#0dy0eLGO-o%@ zR8>jSG_+0Q7Z;|*2}_*C#8E;VCn&AMT`t45>v^+v*-|wvv*9=dkOT(^dGH)-+Lp2` zn9b)H7w9vdT!~VerYNZQ8s~g6XA!(k|wEjNRA%SeWTq3OTaJf`i z=ZCIHdIaJZ|LQOCzxdyNSXt+P$hq;&Uv=UO{E3zkA2~EfI9qe{G4&YJ4>Kj7u;dR^`S?kNG>_!RbR#run6UI0Jskz>aKZ-Rq3CVi`UWmEe8-d(c_bPV zSgfVzREpz4na-cwi)&)n%-Dp!vW#FvLj})ct-KM|iQRFwT1-_BMG3VN~Dvxz5ws2CnXb-0Gj{ zA!0dj!oq+o!8P<&avXCyyR*ymhoy7}(|H#*XAX72!K#r5rq{l4br z)^K_<=i+Qk6n(JcKFKm#XHmvqPj%A*-hN6*XxbLg)NLCEGH<`tR4rB6phAqXz)@E% zyP{+?nqsx0Xc`8Ir78Iw80wG{H8q#Tx{pBzE;YsylKCsXLEKk8!LSx5BgGGUVJGJ}QdOJm>)nFA+K95omn z8T+V->zmFy)8ygbb*1@u6XC-5H`XAWSVh0 z8*n-sFdrpM1}S+GlSay$D%%!EOWRakx-Uvn#SM^W(dXafY^iOTz1O{Nou;~~4E z;QDgS<yC= zxBd5aHlhzg==hKHgV$jc6CDcE2}F)In4+^D3syv;6YCre(^9D)j$!O=#^@tnyMt1` zFqF&Qd(-m-}IiEO;l5A?j<&8n!)M&dW7B^&(W}GYLN_<=;KwFXQP+mLuDotQ2T$i<=B~A-*ln@S5=9YOY0|-v(fo{k zV`+?IHlJZ7thO7<`j$vW&su2Jnv(o}a+8;+sa z&N}BXYCCbHQ17>IheptKQ2vp{zyT)W$Q(HA_IlF)5ufX56JWc;MRt1#LRPSkrt}ky z#e|Dl$&S45@31y(Q=LrwjVCf{=cuh=y|p~uSj5vcLM+G+q2H`XDY1cguh7A0zKi#iNb60Z#qoRAzm{DNs{^UKl&*f; z3{hyyO`sQ;{-72@2F|DiX9B@LY=WH($(bFg-s^h1hE^-ZWHe+v&UyIqDNi2X(6r{K z-R05a(OcgFKKEx}i~3_MTAjtYIEug%FvugO(;?gSil!`4LeQEPYamiSc2!Ay zgXNs}M#dl&BvA@TCesNx%YL_II2@6rIZ=``9p~(~6<62SNG*v615QU%k~sA)At7-G z=devl)3%tlp{Z+3Yp|yF2|r4a#0le3hKgg9lKo(X4bBespz&yJi?bH3{rljKs0;n_ zCoH*&eSy{yGScCgIz*Xvyy@L`$8b0dX@&Ih-6DlUMv5p4O{P<5C0N~DVNJ`) z`PspCEYJrx>m}ASOlI@&IsW-5p=rxK%iBvv<1yK2LiH1Rw0*Q3O>wlz>e`54TjatU zB?+(v#={+oUS)pFQ+kmHbX;(~k+?fpd>p0Q^!{gEq3j#Kqh_|t3GTQy_Nb_LR%u5U zSD!`f4vj9y3f1ErULg+K$?p00exQfEa}!qfD*SBL8t<*;4#a+8{nk~6wY;-7*rRyv zk;B_g7;9)+@AY}PsrderjnABoV4Nq6h6!iW0q4^J7t@^iIAM@#VhynZt^B5tce?Qd;iTXMvjvCa1cdj^AwF?_iUDt~)dv1Dg2I))Jkyxr5raRh^^=r$X59tC| z(mPMcUZjZ>0aTX8&(>MWs$w)69U`FRAw&jX zzu%(ch$K(_^&LzcrIHlIp1LYXv_@!26sNREA|cr?Z)wUsr)T$i+bs{*JGQGO&KV~2 z6Rhyg6%L1%f_lGYyIC=v%}DYAwRQZn|JUE=zxgkI=R?Xm|95ty>6-@GnH}Sf5^P-m zCUCilPmPmIYb19CdCMk}%Na&+V~2k1?$Ot;NcN=O%$$ zB!tF^ga$`#9jgtnw&=$T68W4=w+vIwXpnL;N_luTW}d-(lrSFWq4WI`;T?HvZxfopptb~xVPSkqtw zkJFR(MK1=E())H=+o04>Rp)meT{iij@*L-hoaA~?)_>-x5>QA$96~g*WUW8 zOPdjWoVM+Jd3(s)_C9`{?a;CP+K(KxkKz*V8pg{5MMug*=t5UlU$FVI)&wY225!3b zh)}RuQvEj8-G%ax5FLvPLL<>PyIl>m&b<&C(fy}5LP0#TWNmwt%;L9;F651ONh~gG z067wu8fUyCMu@}p?@QuEN77PR%f5l@1#nXnzjH|{YX-4nki|@fDQDB1hx43C3MbQ? z!7w99B5d2>l*2Tw7ZZh{!74>7l!wA)gcRP zUvvU4d>BBF+@lXf4B@xINT98QgH=d2>N2;TLut?7Qxay=!3S#=lpxlUB#ls7QdcdV zq_#B<=`5ygkKS(s#$j6vu^>(ocAE`RBG5^KRSB)kn4FB!NrFVuRwbMDmbPtaTT2^I zFsT%A9FdL3L{WlL!O{=!$=%i!)|NQyF#mt{{xrz8?5ytwe{0yonNJRPu2}*!l)!-7 zHrNI+8L4d$GsqobnGoIac7*$z2%@9={ov?$yMq^X+m3cP><-jz2-^%cVA&YSql66@ zj3k6ql1injxL^Ng$h?^+GtYkZv!3Vw|NVnP zv>jI(?Y|lB~4YxKNpR0Sx8J-d1KRfTsMmW zvPe}KrjrT7ZWm`9z3u?x1gVs47BjZXITy~I!)jG?z9q1nO|iCOFy5gOs-CneAy_RY zl&clv@d(}N1_1n7#q?`;qUjoqP`v_*D^C}r4g=Dog@lN#F?FAVS+pVRb@6p)Y{jni zf9>~ec#*LQb*&S-3qbaO5DDvd6B?Gd8jCS;&FU#?FYlXxIM)E+g=;3X@#D1s@q~gQ z!>QFzW<^-n`3AFUO&?qxcjm%+J~&sU!pU&bbs^=bj*kpzC@B%nb1NnOqMlmA>B7Ps z@`Dw>_3>voy!I)cxG>PAgt)yat13@-FPG0PELW=38pG>rg|-^ zFkf0P32^-b?w#T%`KhlM)ACPdiu&JwK6cIe`OFP0+!R_g2`3tOP}>wFWjsjvWFK22 z#bOMvH?qYUiJwx1T6yNFoNYYCnYWAko^Puz#>r@eMTEvI9>StAG9JjK5U7yKV}nts z#uC^1(?y{F0lhpU4Xatt8;x1lB~C~xr*IU_Pem#(F*2p+HpYWT)XR$45Cxv96v$9J zeQHo>f+9y+$UqZt{^Qn(RkprwDydLXVan1^Rr!75+I&30i5gZq6Xf(Aq~f)~7RM zm{fXChrosA&$i?&ky=CZ+7I_15vVd2D2*Xa(t4Uq>spEbR0_*_v!d7Qgh7aE0uF?S zyieydI-L$lmSK&ldk`lC^V2DVP6ul%vQ7^t6jBJP&4$fl&feZ0LhJB-)Cg->OeY8& zqn#a(FbeBWDID|Z3C@&^_x2Dfp{jyx2T`LHU(=0dJo(#j4)Ps{LdKJQ3n=c#+pf8w z>QzL`Y2JDfwY8F>mGt21-{0Td3RD1{MvYKy1QKVTPZT`I)kLFlY8q%ClZHnG#r(+D z`bnzRnuq(E-(@u3;lF(Bb2ypv#N&@K8f5H^ z2JDUpXazb^q$;7C3A(+MB+E&3LXsr@1gbzgKaq%_TN#Ab{(Bmxlu}_^Sh@(N2SX*P z!M8F@I8BW)Q1vv!H~l42dnA>y-dMnE&*SaY)EEb&J2m3J+?aY`j>v|63rRc}|U3xtg`JD1Q9ev!J@ zo*L5H>YS;2QQ{*-%c#^2tFZM~CR>IaDMal+HxX?nn-#ka*KBPH4Co&bBs{UknUL^x zzvRidCQzr&tgYjB!iERur-9B#cj5%j`r2khG#Hw2&k!|?8{zrKR`|x*OS2nPn{fiP z#8?GVlSzp(OKv{<45zoB<;rf(b60Qh`Okiyo%0vj{)gXZv~!L}9=^n|m$5${GVFH{ z%6cr0l=OR&JkLqeoFvicBmpT=%A%F#xjH9ajFu{o+-3sPXpZy_fGnf-mazITi zh%&H{I#N%Itu+W~ypF$W*st#8^_jk@wiQxHwDx*af1k8<`jJjNd(>10XAKfTzuWhC zp=!a!E0=ia;VT?ZR@^zf!?pyMW@K5;u-`{(KP|NgjBO#GUHHDZR`hZB{8D(iTg{{u z@{D?=EmiYdRcfhOS(WsAU5v9WlV5XgQ&Ox&)>@YH+3SsF+u2B1MaLZN;(sS3#+an|l{0J3T3M2vfkFn51imjNMUThCR*5ky?C zg;k25R^kyIb=w!-^(3C$9EIK&E&>a#f#Yl~8pmi4;wWk#!|FiPQ>B$=z$8 z<>1<!k`3hb54d+e_B1~g@Iu$GUw;K!@jqgU`ajacfr_i) z*r!O*5H#94aaSA9&!!n#d$uvOu5RRFYD~SofYzkaU*|P0r&T}YeRZ#v(uhV6?wi4| zW{vP~+pK8omAtrLhu%zaV^SJY)UqNa8W_6QTFYi4+LA$uu;mc3QE5$Oos)GsjzqTB z>p@BsYhbLauGt_-<#pFFGPlP3+Ni~AaA_i>%lY(_7!2xvZ%m03nnWw?=9C*xf1J(9 z3w+g;J;sAB!(Pgu+u@n(cd&X$AqKo~yhWYN=pGzXRR*Ur%2HBnN+cU{ZRmG$`n@h$ zw@cpb((m?2Q$?C(WNAvKC3zwk^|~af*K%fQf>w!d*pv(=7@wi7lpiLzFq~<&H?5ze zXbfRi`g?$%f~Dd6_VTpp+o}wQE7%ql#OfS;n&5BFvUfuCW-3 z&64q;OJ_KO&Iqgf7!rh2!R#6|#Li-^@ffaXjdStP7To-@oy6rQ;Qk)xw_&xWmzw8N z&xI>fpoJsVilUhn*O;+LOjxfsWO)}M(=gqS_%DAgE$4HF!vRWbTnHjjNQ%vdVmW6t z8naxl7>q|gdeS+BbpKWfOKnKFZb0P#Q$zuEODv72<2}i%%^Fry>j8RvUD}zom9{=jMu-bYF zLO;`F$}#MA>2-4Q)RCuxJWt8f43!Fm(*Ao;SwEqUT3lzb()s8->(Ekr{TQ!JzR{C! z_|j}Qk3Rb7AAcu)UvvAa{>BB`f)560!FuWyahN#N7_ewPcJ29M-BikU-HR@7(KMkZ z8e&3fnRr0mi_NPHQ^Pv`Rm3LiY^Ur3kIw~QI-$|6LBpb1yT^t#e%=~GXPZrowa&*- zHhb~Pb^cFtYo z!b6WSnXc)iDR}~UA{qAvbTUPjI`T}>$uhDmLu&7QkJvb4gVQ^7-Btyvi4$n4{WSSy zmc3$IvRoG2zH`WI<{i}DDC6&6Wo2rKLzZQn+uI{a6|2pH(P+e#E0@{d8?)YSDXpWM zcBq74Z7n9=gIp7|;d!^P>l!*h$8h}L-TF1A}TC6Ugd zTJex!?ir@A6|UOS8}z8EB5cJz;0qW4l?BCn?eb zrQ`VM9$E{!nWownSSL|RvX~xYtzkGEu`M^DsZFs4PAA8tTKe#j^(yoM0;LkB%PEW5 zDT6_mEKOK_r6gCc-iamwXW;^4(oZZS?kK1v8$D%>3-N{07q6zcwrH8HlXAp*xMrd! zBv#laBVG6v2F`l2e>mYbCu4s@kwLp@o%14YDeC<7SR}oG*t;p~34(2%=;L#3#l}T} zeuM_cM2#pau>t%pob)d5pe=E&;@RBX;zT5z(_90YZJJpRMz$@~3L#34kSL(FqAC|$ zd*%-)4xi%MP)4xjZ+${Qe^HO zdKm@I6jbFFTduLi49tevd`X&kti+95cbHC2_@=+~?L2jJ$*toRLZm2Lu$kN?la`&q zkk#}K)8o5n40)pH_IsX}IU3UM(ztZdaSN`$AU;BA}<@YyD45eu0UdKai3rJp123?bJ))WI9bee*yWiX0? z47I#Uiq>H?yzPtBJ!o#Us!sUv)1GLOjHV+Wy&E&nZM}V|Q_@7E-LyiWl=h8lm~7Vh z=q+An6WY)u6-69cUF$;Ki!vymQbvtxBh*nTB-ZKr03UI8URC6q0Tm9+UfXV)jZiJU zp*B=HDO&NhehTV>#u4X8wPZTE%gxXJ9s@h);fMAa^fFdu#l52mFKh?oiD0~QiREI- zaA%**YDTeMdsw!ps6u|ZRT7tEAa+o$B5?)AY%$vcTP+ZUr6@|Oa!!(Js>d4Wc)u9gXkzwj^20zliA)HZkw0!I#CM@b=+BrmV1+PNR zaV<&@|C6raYPP2#O)(DNjrhE!XNJ|-Wf}5JjsFHlr)FGRQ9De-O(`_zG9Zy0pp2+f zi)=6t32RYOptZuRPPz8E--Fd1-gsrq-e|zre(l$C{?RA+?N46i)-s_)ur+HEl~8Q9 zB%>V)5?onfq@pUP=v*Mg5JN`gKnq7DBqHe|lL69IsG>_^HVCt2vzlSc6(^@Nr0(;~ z^S4<$4Z7o-bXy`^#b&eN=3-7+tSAdXwJw-W4mh}Xhs}12PEw>!$&!Rr`xR7{W#pZd zPA6qJ9MJ9N^tv79izTo1$F*zM+;9HoZ}Oh^yyuUpx%-n?*Z=X=t;VD%!a>#6`|*ZV zNo!T>YRpYtNt{pNY8urha?%0Ln9xj8PaK;DDemPPUNACf5UB@`btpxhdL~>=e~77C z&Nb^sT7LQnLlS3J{-)9Y#ob7KkZozrn~d1HHhSz3Exu+P5XUL3slTRr5*N72HNV); z7Lc;VI2Nsn9eBer_E9>Ew8on*1A|f`Jz7Z!aFzFNOGPGOa_<^9p80+DvVw;%?r>p$ zpFjIee~zU|`Rz~NWF?0b<%-Hx2%#u9B{~~$GF{QlQns5C)G0}7fgu}I{amfopmJmi z%8rnmQ*v2RtQKsF73=wo`LaT18K3<0=UKZ1r85cv!W0M$r_&RTs)}M=Qf&p>)r{k# zI~*S!VR5J=L+O-Gl9DK|3GHMVS)S1AcNq-&bh;VCZkJDd^0P1NI=Fr30EgiGg?$bV z4=GAN;PCE#(8^C-N8=IJ6s#6ghJ&t8+%Zs=6={}}r70+Z4N&(^l9Jm5|C3R*xz^8E zlwS^1Wssc7Mi*SK(tW7O!W9gML+|?tDvE}M*%(D-eSN`T&_}4mGi*g8?~`HZGds16 zMmvFv8O?t_)^svGVKBNt-W_0#tG62K<$_cz_IAh2rW1z4AxdfH^C_K7G1}e71ObN> zhShA2=ym9icBqgzX%Pz6ixt&k&d%r}BFou2ixe6qG)1vyJ~?7Eyufh0iy&dMUeoIi zST7I$7`9J8!P$|)`(C{fl*FVM;q?WAvtssIh%UlZv*nbw!LU*nsg^3Y2BU_;T!Yg^ zOTQUTL=i7UbcV+h@fmEA2u0Eoo#;_hSquK-ng|bCj(8*&PUdYbpwC(t2qm$`)=_Wq zZO)kxmFilIPa0fG_`L`78h;UltlJ1b4qt{}jRiE54?6JE2vw(q1lOjJXz9?RVsm=P z&Ch*|)XsV0p&c^T3q)b>WmN=nNat-(!hNL8s-Zdce zlswmnai8ICj|&&iap(3OZr?egG>TGaTwxHdLb^@sIAV~>Q5nNxxqiLTympO${Ez=J z?|ILAUOVgh|L#YWpEQnY>b9pDSi0bJ6}3OuH9E^W9j0aWsn^Hxu-$|m)a|WpQq!72 zYSVZ&I?slB(KZ<>)LAX2I~zyYHY_>kVcYe`i`w#V0&d*l0UJg*$hY0?_vunS+DtTv zv9Q6i#_RZ^K~sbV+u8^yZ|bKI4jERVXVS-9!~b-l-ddr&vp;C@qOzzC$PfyFLAfnQ zH@?8VXFtuQ9mzv`eS}%^@MCY|E#LU(_>GTzlC{Y&LX#@xLn4rrn}Yt}JZaalE>=GB zZ@WMSqlcygl|zUEjKLV+JR7q?7BdQ4LQ!JMElz08U$}yGlI46J&`5LdB@mWGmL8L& zK=wMweugkTcJ_u`x^$5jZrtQ}vZj&=+d}x})D;M^_VK>LfiPZ+YAut~`OCWsoM5vp zV6h1Ct2S)b2u&cYR|~8y84Y_}xqP1CaDYw|w%d}^lNl-i)m5T#N`XodDk0My3UW%P zLky`6(X6t*H(F~@QZ-UEQH$!Z&QWZ(WSuTTrFBkxbB)HBNZ$|^MM07o^4_R69J|Q* z4x54HVnNm&k@ZH+_P`0GR;*V`oKOsh`#2OX^$mBmEvby-{KbpRXLCA(F-dp8YB|Rs z8K1v|lREIQ9gFEHQYQ3vM_8eK;E9CA{Dkdh#s0Z-NS#yRhc;Sjmh%OtlVf&9V}`>a z#yFPqCC(VW_eX!6cYNcOSFVl=o%mT&i}wWh2Y8qQphVNk>1!@*if+P4H59f-!( zQwYgfCwr?Ojw8o2&9H5~xZ!L>;OGAtcP5h2xi^rficATlQ>0mkWL+?wEO4q%r!!`?p3{*~6&s8>ppYv{ zly$6|l-e`EgdjmDB-P!O%i zJP{T;?o3`fEksb9+}bugp7sVPZioC~-PKO}R$Xjyi0eT^dq@y!tqPHvwAi09MJ-1A zoq3*(Hwx<FND#83JM1x?teH+$q{#qlVY}UsJJ>E~*b=rb^ClU) z#o0~J&KjiMl2Bqzg%H{&*UV-McJ_DtAjAo@gT?6t5Ol{Q$`HUJgky4gN>!}c z-#?F$n$iZT36`UyBet6rJA1qIdm}bQ!F+m(7I+kreI?K9*WCwx`u*^}kA$sMYwPsr zd&NKe*?-|4`{@txx8D9or@MV+Cz_(!)Oci%sGB!uZD>Sot)YuA;3&GW0(3Cr#D5nZ zWG)o6(7Mz&g;?~oQuT{ThFC)vqo`ynMv^95+ZTFKXO`A0rdAUyr8fy!)40p)Rg<&z z`$qVCY+9XZ;he%W!`7>ScwyV%c8?%g=b2j0g%v>G9nGISP%%;G)xnJ2!>!+}QPztFm%6asLzmcf`ShgSy(pf~3pu$a8 zO94)y!yHFg&yo8R9kPI)C*% z{_fxXyS(dN@A6>d{{bHF`u@McH+|3lp09fA*WcG@onZ;p4sDO(35v&>>qk?itY{qT z0x&j2%bGI>*t$uq*}Bv>L=iHxV^itE#>9VkamF0!lf~M(+yPf4?~Bi^>mKzD+|?VL z=JT{y-`2zlQH)S*n!#A}L@OTCSR4Gq(HJVjA-j^B zn(#VU=Ova0x9`v$q;lg9{oDCEK~f-K81STA3*ej~V;pQ6)*H1A-ItHJEk=?QtR$+Lu$;}dpv zb}6co>J3lAhrhIRx36fU zXvK(QAh2Pz!##p#y@KT z=S+rgEaoy~-%_t|;uO=?ujpw0iD@BDNQAX#F4Cyw6zwRu&>9LSYDl|O9?>ABs0I4< zgw(ovB_*8K8;Ouo(V!UwGQ=^)HNF%Qp(Mhtxqa<(+ zRs<-!%)0K?-(Xuq*+pDoN^zf5Km^XFskQ8c=t`-e zTApz2=}%Bi?(*h0yph2mK_n&L@~z*+v(F#!3;*)NtZau1J9{KjVi%_zt(H(3)@%a; zPN69LJw{p5V2lz{qJ%+Wk@vEuHYMg9zbqXr<7?Z={qE zh{V4>a-Gsm6EbbNa(Nd-$;UqN49mh{D&JUI;nRZ%6V+7v+V`?1`$GB%V5E;kc9!9w zN4MYQ-r*sqC&%nRdYLRuf^pT7b#gY_0^?w_-BK0>NtVzPf;{g8iC0K+b6ZrJkbpxU=4nfIXOi- zOLx3WCHysJ%YxbI35iM=@9z3zr}Ifn>*bQk=`sCb&UmnkbBg6+MY&lr8upP%%E93= z+x3d^&gd1deNR1i9p3)pR`U9DPr*BWh{s=T8qM|^Jb)(7YBjCFh7P`Vn}=&p#+)^pek3GX|wV|JO>uh2r1f^Lcai{>#m5D?Nfy7`i z0sW%u6TJ$f{%D}^Il=x)R!RkVL|~)3CQn+)1SuRUOf#L%NrWa-k}OqdnWGXxk_4hr zRgxu&K`-NxE9Y1)=lrMt@(EU3M^OqYQ<7$iPOp#F0$XhmuTi|w>yMXFx6aHl1M|_| zXCaKiC2e_%2_G*g_BE!FJaFd(odusB1*T~AYOjj40E zIw?uU{{p5dCJe>mA!>-XL5s@EYl2kD;c!*O>A_VJyWz1nJV7VxP`UzZ;9vcl-{kak zhI5*(R#@o|=~5Uq>6`6$ws&PU>X&ur&+1{6Ird;WZE=B-o)b(!%Ri9;9HzAOaB z_~=ZnlQ55J@gJn4EVfwZNINM8>wA>IxtuMgbh=%%@+)njB-`zl`FzUW{toNSmdaYj zgCR!;2aJXT`n?{N0c{2A$tkIT-p&qNe3NQ6Tjr<7^tu_H{tiW$zzYGhlVgg_hW*_g z@?HmHB#YS;X9{-4BR1uhd$;e=$ullqzQBL{H^0We`v3gjU!kn?w~N2^v+r<^{lwqr zqwoD0cV@16{R8fQ`iT$ozK?u}M|qWLH0#rHoNrqHgY_qLYN2`*_qw(&Qwpl!hk6$^D5`t}2g=uoe(diZ~C27_r<{P6VPC7bL)C2&FLW^j8@bQ)2aqrVOq!K>C zC^-Iw6G)|MSF11Fp$QGJel0+2?URI*BNLWPYebroDeZ;O2`H7Jlq5|AS*9r~!*aPI zk&=u1dwlnId@G;*{1-T!lq5-y3+K*rdUDEqy`t00>+jd=kJlex&Nwq3>SD%r+wd0w z?ws|)oUOjG?!{PH*>Y>Q4u{QhFX*k$m?ZrnHP+Df)UW0VKcMcljghe-jj(6YG9T8{ z!N?O&3 zoJED7fw3j73d9lTFt$XP5@CGZv#tteOT##GTzup*&RPmS3rbzoWwQ|oJ`P(BqXK)#iTI4J);(o&!#=p-ji6B233 z6=h5c@3xWWCW$4 z*Ub?E`hx+>O~K^!1fdmar%$)rBh7N8f>cVM1{BiXY+J7^!r;OhFUJZ$lQ;{GIttO! zN=N#El#UZ+QIFr*6GiskHtL_%jcq?8gT73=ky#mOBX={&a9Fq*(&k(QZh5yzw#zOOIB`t)44cbJBabaDg zbbYc?GDg2yL};jeq*vun^Va8uV@rfHI8%7mo-=-0>I@-iJgnqGOdAd@{3_ZxM;=a( zP6$+<`R6bFSEd86%t#ybmMY*@ECLB};RZc4%QpMS@B)5~UELLZyy0$w`s~tt5#OD5)s6CF|9i$$Z7`{x0AC z_P@w){?^C%ny+~qPrmuB{Qk#&kKg+J-y_XCJod;N`S@p_d%byj{qbc;ewzB!BmuRU zlQf#J)(rDZv*}~v8bPOYqH&1_2~ZWLd9`7Os4=9~kopPXi!xrqA-6UrwqToW`i66k z%D$MiAzDmOXI!0`e1EPwBAO3dhxDLHt&i2R0kPYFkrDBr8dl5Js*vmLLoAxZx5GKl zdlZp(Ybzim(O8QM$TMt(Grs-_YrT93i^SB8pc6iVQd#FG!oiK5CSmZQC0gZvG8P z81y>)#=rl!+_-g%hrar&+26ZBA#*-|^@W$UI#=4eqIDw3^Mq7obh;g!v1FMh?<7nn z6VC0Q3yobECkEn-mfGt&%Zl-!j}>5yWm{BCPEJr-lXv@chmhw9TWdY?N67m7Y+G^B zUjC+PgR#HXM2$ysb#O{E;VFv^N!T7l&a~H_TB_1us*3(#KqN8vhSIT`FBlF62;teX zS_&qorzDABFz7Qmozh7&iuDErbcaKX@jw5?2`94;}K3OHrs;rVnMf)W31u!y}M*-#)S))kSg)UTPK?J?kn7E#_#QW zKje7tf5*r8ibqh!>7*|t;e;;inH5z#x3$(z*ub%?PtCF(n_Fud9b<4Q#us-xnJ2!` zqIg_H*jCHnUu_P)o@&pJGxP0N_#z~~2&Vu!ui17UqA&1%F zu@fQ~aI6h_Q4{nz)YFK_x>L@A@`7ocLP|)YcwdD8vEZcDQutU&>5G!Y;fiANve4?gip7PDji>+gP) zvfS|QANgLs>07>?!sYz)fAt?<@19Nc;g?2vlG~O6BWb67;n?@$vx`OeEGAwq=P?6+#L!X-Gxs>uciBMTM3H zDlo^Tb7WeQW(j#O^HWnKPdsv&yLaw#`_@&Cj}LhC;eGzv_k0)M_!s^%pMU-yPd)el zeOZ@*PBmI9q!bMMJvyntRsy9I<#t0=6%2-b%*3+ZZ0Yv$@S5HCdkH zfJ7;}!!DJBO;NF4t(ni)WZfCrU=Pt5dK0Jf#<3V}DgsB=wb{|GoeD_9zLg;p$Qn#l z(CubKOrZ;MHYFvC)eNl@v`#2(F#1T%Y;sJZC7o`E(paD5vz)Tt&bWB-3Y*QwGiMzX zWyN@J7c0G{bbfM7A{@Q(E@j}%LV86chN~s=^R2yW|JxF<&?dh9Xj0}IFDJ{ zZa4Hg8LQQT)oRV|{;p4$a)KgE++WR$y07r++}5WOze|_Tq~MQ)J#p`BMMyuh>v=Y+C<|xgCdggu0rGDZm)!Jo?906 zonY#*r-{}ezK@sV1t@qP-=`xzR-!< z00kPUeDb-FApLuUL5(G5GT1l`wn48YY%uGH*3Hn>nej?ElvZAABoh(=srD!lsl3KW zD}}_Nwe}iZ)#MmU=O+zH`5UxT2{O}YsmY}xO%mU*rU~6nPMRpvRFh{pd72OgB9xUU z7VL~iT)%mf-}!H!;=+|jdFOZk7>~XANv>W$;1_=BSDDQhuQyMxKfbJ$p=v&S8uYmhcU{}>TI5?2dBqXa0z&g%nnIC!ft zDQysIO+!j+RbCq^0vuknwn{eEE_tTvg@bi$8hzdKlJ^$ZxRwi4V8X<)j!QH+Q{qg8 zqp5o`+#_Ugm}^IE=8FehfkmoVmu-`fhMzu3=Xt`B$s9vFjI>DIY{5h@3Mv;Q3Nmm^ zt)DeZ2B|iNJpL$tWL9gFKYe&D^p_6EYNmy()6qWHt&R|X(jYgbK7o=%U zk|?aJ&`~$$j9>j1Ys#`9Nm7h4z!sGx^!hoyUXRi^HrtZ*^nhwMLFIk&-VRBcp`|wj zIT7@l#x|PR##z@0SYo1{5R^rMl91}eUmG&KzENN;MY&}>8vESz&?8jEmSVePcX!7( zpF(0vKVdw-e;%Agel4FI> zw4WT^!x+o?a~Danl+qZs>m^0GB})|3(+OGD;mVaOIIXCRtG5DC2BYLF*=>IDtaJbH z;P%Hq@J=54i6>tjS?9i(1`b+{ENZ3YNI%^ooccuoi$@-oC;o>ERkj$HqH&@(udkrr zl(Lm4EL)tpMo!;uPit7Z&|a4ljW(f(Ht|%EZ5J|-0bE>VSD4aZj0yRz2Ioqjt8Pq~ zXjo*(As5mhTP?M)E=>9wZL429$GAIN4-5Phk$RFC%}`QGe{s8@g$%B4?~ar{gSd?* z2^tqsPaNsWhXr$I&94{q__LEPg6iJ$U9-HttwoOs6-fY-xOSH zyN`d2Ege38BT02Phx{2tus?n^6iZzNy_^5_j zJMC+gpRn8qMXx85zBzM3Hm1d}dX`QF*^jGDjXo|>Hhjcz0~GZI3=C{B*8i9bK`|T2lG*M{u949 zL7P|qv~=VatI*&_NtHibYwZueN41J1DJ@Sd6JyZ?~+s8?cb-oL+B8*6XwX$k$+dm-)m~&*PE- z|M3rQb2z!maE>yG(EH(#F{S^y($vQp zEA125mP>XlO3qs_jWYjpK}f_s~pht^5rQFIbI$k(hcwOAjfnqDD9b9chfpA~d|BWh#g~ zGOr=^h2Edw1zJj!lq6cCl_1fIJV{W(uZ48{FY)OKiBhD>V~PB~kx1oGT9c}TBuRWT znh3vs3^x$1HBxF+lAsceRJzWo-)su1YD-m?I4S9Lhm3dopmOF*!}Ys!K6mXYuHBn6 zS@xN&Ez5Pua<;}{Ie+B|uceZjt?g2kt_AxITH5=5Zyj_}$%UQQ8_n0+jor!tz;dBLZiKH;<1 zKgZqEEz{M2#oDl3mMoVm(nNFl@i%k(xljA=RMKOwNWGZF3-eOFJQeMkpjVG-L z?ag47^Bcb;?Q;J7fI%r(t_l{*1@qaIB-QkK13KLyN+v#xC2BEUWOT=2wEw*+OH!Tr z1S+9C>I?t%6vc*KzZ(v41}QbG)e<2by}<}${Oe$HdW=+(?qEbwY*|iDk)mR6e;=h% zDpN9_oRUgOZ?uaO2~}x0I=)LMOV}Bo3vPOt%}!X%mh6mn8T5OU7^-s1YQ8|06;-)G z=NY5DJ)HEK)wrLGTZ^LDaxy)oEDE%e9u4){UY+}-8iIyJ2F6#MDz*jXzSZ=YjVN1k z!ul+8YyISt#xbs1?(gUl6(J!Y=J)zRbJeV~Y~)?m8!zt+6uu!8RMhj-kaDA4g>_-& zW4xBqx)2TNYygx;&7=%Ov@i)!BCM=M>kiedt|W14>YsN^s%-LyMObw=Q0OQdFhL-y zWaGdS()z+4qw!?(g^KWZQPUb-pHh0wj4zB{f1{OeU=ywUXLPPlinVO0v8%s>j3izTb&%BKxw0+oq+igPgW6DeaH#x}oJ#$gN? z>wm4nuNS^C2JE$^(QJ(-9d&GNO;&Tws=KvYr@cWE!l!;o5fL}GwM}WU z0EI+2S;xh?keFpc6DWkLqZ(CY@V1SR5z1{vZE$g+sf%es-tgxFRNg-)CH>)9Av{1F z-*H%DQMN=-*7eSr;N*4=Wep1J|9yzkt?RjKQjX+{G@CN~F|Nd$&6EEUM9s~N{bE!1 zd?V%3DMN3#7`+D4lN}~qR>kF!*cwyl%WZg z^@L7`x|eEAsx&%LXype3QW0vYMuzpePy(qEq)I~FOTqvE%Cf{(70x+|vLsCtdc8g> z>9DON_f9uledZp|-#p^_ohc{tio$AyN-)+ipUv5<3xssY#L^q(sKjq?j^`HH4K>f+ zSL+^73oq|!K7YI7bemvR#$eQ?+%D?`y4pnMY;6`3IC|XdKv*KZ4}5}jpK z^}s1c0Qy5oSsA+BPJ7pYK(H=W7z|mKVyvGuT3az+%ovWxI3!v~wu=>RyJi2}IRuXR ze1a`k>|eM{k_<4WWHmh@Rhrb{ZAqTuA{fbJk?Fdk!3RF!2iIfiP>`SbfENe6?a zDmE;pQ;O}HOl!vb`{=ww>8MkGr1aDIs;oFZIcB|H((UH#UOY#)-)Hqot<2x|5!}zb zT|9V&{wmKp_nZT2#-s{Ols`?`u$C3|n$`y7m{bBIn#rhevK3qA*Ubipl2NPFpb#1j zrl0QFfGdb=CyNPML5r{z(pE_8fA6fHPC8@2Z9(|L3f436T$?Eubdw^iuxfo&Z0cmq zhV!eozy)nb%mu!tKZQpiP<=i7xXs{{j|ddc*$nQ+Q08N{y4M8xlc^MqmPv-wkk;C} z(6v8-$F)tC_~NIOH}42%Q9_Yufl8EbB&8zN%1<4Gjx5z0r6s9UD5X$|@(pStn}$|N zq*6$wP)ehc6sc3B@@~G$RIG~vTNOy>o%?yePd3Qd8aSA&xbf^E&t1RAjXQIW<|Ug- zAast>JIGA2Sj?Eu4=}}+EbWqXG8XF@y-rG&rcoMKPcyA+`Nv!{J!=0d1bpiH_Vq^d zwbo~b6qhq|%y2IZ!E|9u(eO6os<&bDHaf=`_TYno{7PIZ6(Z>BY{d}#5R5i)`iH2K zWMz={Ae>*Ni^#u>QIw%+6WW`8;{7`&3I#p6a29DRgz>S5!j@nvAFXFga3xaMfC-9; zJ-+7n?~R`zN@45FcVfCt^F{lbEgQ$apI$ao)tGl4-(S@S@u*{Mp1TaOx=M(a+$W~B zojpv;xGh1T1YtTUJ^3OWp0yODT9KxSzmbQDrgY9Xky?54qLd`kOM{g1;|{I-md9^( z6iWMpb&`bjx0LmyPR6>Z6QoX2Iz=eI`Yp?nYP0nwQ0qw2oU}I}mkGWw3A9~|R$!*a7>vz)V9Oer=CMtkST z`vbBh$2w7SYK<+iSX7!|oeldx|NqpvlY~6$fD@RiVmduxcXtP+ z6K3-%r>7@8a^(tHr%O>)Eap=ZozNZl?DBH6W;#8gKkCsP4gtY-z2)Tem^4e+zi8ne!$jwS-iZ7{odUYlRh z8YgJNH(b3$@V9ac4yAvb7cyE$mRd@en2ujd{m~DTrrzQAf|o z8d4l*z*5y&JHF|a0+c_@MP^%EA1ST8jz~+=BnjF|<*`9RqGU*=kTU2hWmx;q$gKy~B&hGy7cQQV+>6 zk&qT|xI#9y(Jw1}5|^{S#`&AJZx)a)aCln)>j?L#jX8~3(K9kFI6t8@#!oAiEs@qB zF=*lH^>%Gq^5Kb1R3!o{Y>NpT;{cljwg?Splom+bnTAk!CS3TML^GL1 z`|%7@*FNLU9<=R!2kkbN(IFX~yG*q@K}dsk4l!TXgAT89Xa+q(K$2+kJZHXGG92`4 z8i6qetp(fCQkE5IqU%CyOy$Qh!smb6Fd(tj7O6Ce^egYu_-mop?K0|jnMiQfFk37* zna$~DJ$k*q*H>yuxhg$4UbLhc2)1Pb*3j+ssjUCGZ?{|4n+@mpck6BA>Ewi7zem>X zQ&fhVckZ&kHzw)#DNDnAc7jrp?r;YuG^@p&VmW6t9-uotoRh3)GZyn1qtSrQU|37u zjt_1#pP$n24H)n3qmwwr3<${3Xs%{+X7edh!MXDn$nzWvROY^vtd}v({5S81cl_*k z@+jB&z)!!Qcl_)%?r$b*zUHek>pT?DnnfoZLir5bGwAb}86IBo3jaPLax-msZ&9au zjQN`n@lLfe2YohG|HMEcaw zWEr!B!zoXNl~+C9h|Q*KkS4-c$2!Yg1n!z>8JC3cT(|iBiz{y-eM6f_Rf~f~Xc7|{ zRy)!ga?&)Zb(UI6@Ai&w2ekB`Ln|*{S6U&RFT%b+dsn53D|V&AI@~v%N=q+@jyb== zYc6GyqEre}`Sna`*_0KoDp1Oy6Gd;(!-<61vgGQ$1fbjS&E}L} zpYC6OyyhP7`u@McH-FFnfj7SO>l++S0}g5qxi-u@WfTC3Q0wY5w!g_+Q=9f25sDr` z@L{*%e1j=*80U!(Ho)R#bU=rHhxD1-#D*|TQl+yVT26s*1ujf0T~&d#NKt~TS~bu4 zO^vYV&`5i(r>rNb{?O`bO?%VL`fEr8?YWHE?aptaYL%yphwG@r4DE{&fmLei31{fP zYfZhB4bDzTn%XG+R8tF8%W??vA05qvVZEKEY5jLv2&DFPQip9+BBkH3NRNTj;Ynsm z5~i9W)V!wdsj!{Vt-5DJjrP%(2{KKQG658&b!dyx z^O$nOl`B{14aZbSia?@B1H*N-Tr!i0q#nBw2_iX<(-ov@ZyA$D3u~a3Npn3 zo7IAHyT)SBDk00esH8__1e0mW&1=Ve;l>@V-ah5->6&FBu`)xb4kAtbP0sq8PLep5 ziz!D3hs@`5vOMAZ5A*OZt;a1 z2i!QAa5Ssf8jVvqQuQIzehOiOj#Ly(Pmee}JftW#42FF!T)sq-WK2#@DYsj8c6Zno z1(WHFG)Zx$z?!0-Xj<#|_$QyD*X{De6Hhb}BI_v1ivRrE|AjyIjentTP64u1`zBI% z5xK!u7NIkLpo)i%vm?-&C*ALLS*})8RfX27=DntgX0_g8DudF2+w9rt{^zek-nk9U ztl5MfK%<0jE^WMCgrEvg_$2Gn>2w(H`dG-te9mNY#CpA=C=9*cfGkZY%Mw$T3B;>g7%}ALmW)fPeAab$EOG_b+ZGKk7%HufD8vnypi{OMhKLy`2S_9$LY zl<+AMp}Ew$nO1rbdYmxEj}x4cQM?|wZz{Obm84#S`xQ}eSOyJ}kUm~b1*duvn3zK8 z+Py6k?W4eSicZq7&+^)ssxTN+QJN~GmpD3|E;{!o{M!dpo`2yw*Kf_aes{sabjh+3 z7@6bL4l378?tLg+I+d)K3vRw}lg0FuPABJ~hc7c6?XWFM?j0NNyf z-+IlqnGwM5LKI%(`V=7+l9&ub;|xEGP2-IDK)ASOj>#p#L0!iSxms)OD?z{p3Gen+ z#^Ng9ObS;524@SDt2}o%gg8Vkcr<$pW$WfGax$IpTcf(^YsdY`Fv+Z4QDG_>U=}fq zf%cj{axhffMEM#UM3-T};0+f_c_frSK&w!XLv0j(qUxJSNfPRwR(?X6Xj#j9ViV}y z>8-{wOfzM0jtl8LS}jE7M!lx44O}*r zp(qViRZ!UitR>NkZhwf#61H2*vo9QS{niOrZ!US^V8+RE!^Wjp)$vo%MALxyte5;K zn4BDPbng~Lv0*eC@$kb>kmX(GizNrQ?=b53*&P5hLCe06I5<8;0Np(ICQ1yalM_Fw zw*HX)Yrp;*Xs!9-?|T=IJ@!Q1WPb41KghM~S4onLZ~TV8&`dOy&vZ9VA(K8L2d5{H z7#yaSsmYMo<60pqT1oOGWwBf^91Oj}#F`*gfT}D|Dho7~xCs=PvhoKiEj;l6hqEQp ztVtvYkyD~*cUuC_&Mr-fkb-W1NS=3*QjjE?<#Ne%a!N1H&|1<-6`d@lGJ>iyEEW^S z;~`3GwnfQeGU5F0K6%z*HaTKCxyK_9KZ0|P+3_){P8ja&QW!WqKE%n2{R`)jB4IL} zGn*W-vooOAAA``?$}u@PWHLME(&bC+?Cet*OX+-il@ih$h$e@W<(7WG&tP;8DFv0W zIAd#KL`|gdojCvTU;Prl^#AZi+TM6 z?{wexet6$U-uvpyI*$n$E;=Qpr~$>X;Un^hhfrW0sY?8+M|v@O z1S>~PWnDo$P8nl~z7yc)Q(l^ZIif9^7F# z8uG{!k24yMF;;MRaKdUeXK#OpG|jkk;9n;z`h-3!Q**RE41^N=#XJDUg(;c}7R22qD<4HoS1_9)I|m z&-3s9^T#<^NrromWAZUp=g72&MAs{47~*X}i{+C2{eALo7a=8^ z<&xR)DKZf}{Kz9DNrz44>PfvRN+y#ToAr`zugC8GWt7%l-eqhp%Rx3PbDWpVIUL1y z`?BlZqwoEYaBuiY*REOb|2DzH3eM))8cO8SHZtO>B* zu<|j5FJ#7Nd<#=~?UD4z4jo*F5u=d==ckS0azUL@TVoh#@gkiF@rtrRkAxR1p+QVS z5|ENDpn7XcAy9$k86x50OF_lrt%wfI7*23!tk*kQ)l-Z#WP`_#p|$iZ%iyMz(tizp5)cZmRDM;V6CYt29GX(6h$Qn3 zrWClUq$&%l&60Av4O16EmZqd5FLqw97F>Vs873#EeD-tC@YK`S`Gco#uu&r(eaoL^ zoeY?+wrFjA@vYwx&cTl7pKsFzye~$``cCIMOudum9+e@=t&1m$-Luz~B1^f4_dE zKJv)pyyLsSr?m!r{qdT71m|}IJ2&3)&}hae#-J+~t!>EJ(if|d^~p67AL8H)3g=ma zw#3;I=PIN%sGv<#A-xM{d(N{ojhB9U zrd-4Wc?`B}>B}RJ(utrkA!3SzuX{A1??MJr22pDn*Ub_otVf`Q5Qa49#-lz`Yrlz+ zf`C%fp|SKPAEm;9SvFcprG2PJD%4?*Tk~c?zp>FE!=YZM zkYv6A#bV2nvM4E+E6ld=aw;Y1WF7RNi?fc|$uW0t-{R=#m_PV~&+yr2Z}X`y+-Cg9 zn>hFAn>n=_w_2kUOOoY2M_i~zf9f2o*@WZ6dn{K=2IDc0zTvAF^aog5a_8tC^T~|e z@gAemh=Y4~sj7<6c*J5op_}C_S5xN4$2@ZRVTzL%>I1g5@W1`;cVZoU`l+Y*R<4^)OX|(B2E-jCUAG8G;L3Tx2nyp+ zN>iDN+3^YM<$_M0bMevzRGLv4M_C2B0?LOtMAAY?vZ{(Lv)Pj6a>05re`RXk+kZwl z_cO0p3H^%RL8Xu=7o(`G7siVciNO_x7yA;iLcypLCIebHqzLhj!kda>af?EyI@w0H zIF$je9G#NU{VakGL`Z)DIUC*KjjkxhED|zPaSow$vo#L_b?dA@c}Ago6zs?6N-Gvp zgu)l1(Y%4ip(W&59vE%mR35mNTKQAAlo6ip(Lh>Cf;7lCp*r!+puoGn!>LCHuA9;t zp}eC!4eYiWZ5mKRLV(l>Qlto-)J{pEQa_26J`cXwtT5{}Wx2vsjx_1g%e$y7!CJ#) zy5!!qn>_p6H9r5@PqLXGQI!?959U03XHK&B7;pRfzl2G9lva=wB}K7izL+D#mL$pO zc5<|W>FI>ilT&n}dGv|L=?`{5Dz@7#cW&Kgz1^^X?mWX@hkJMKP?QCG=k}P*W=QR2 z3nxcMoIAHqC-2k^fC*@iB+2;EAN&!1@n8Hh2Zsm#R2P~|@p_Z_`Xe+>)&@3iM2f{t zj1!(?D@|>Vu|W$N|Fv?|j&J8mv^C%=Tv2#7rL$oTUe)P10*jUoAp)OL;x{~jt?O^( zw%&}ycwSn7YLAE^G@!Ch{88F#O8xt_2$n%2q@_U0kbtI>u<`L9!+$*~jTW<9#yAtLql=0uqrrc;g%?;sM*Lk~X;mEp#{E4<`2+9zQM$ds19a)qCozS_(O|JsBReCk zEW-yS5Dm^!V*P#H!@#n^$S*HWStRZ)?qIvjdzIG8zb3L`2oAT>BEaUz&+ z#Rjc>#IzDk!W6}MB!GPgtjF5g+ zfBWV&ge`gK(ML)19;E@H5}dJ2PfuA)CuF(e!o_o>X@|-}X&YU(3(1BERc`_|t2K-H zlMH10_AXj&5!;D}oEtAvcWw*9k$5RQ%Go-5J4PvvlGeH_7HA?5E?j6*)*7wo2-m0}ON=Q$ zqShsefEH3p`c;UO&2%v!G<48Yril&(*eC5ot&!G=pIk^83as$%NTtvU?}ikCO&Q#m zN_xJVkP#9r5n3a(|2}G=y)INsjFKb)xgnH7XpIydM4EaFy7d^BV!39sU1F*&(pqw@ z81;IPChI>A(q#p#68le=Vj$`g-2!Fp40{n`x% z{XV0eAxFoD^g4Y^QLtLAIk&SzC)I4W+d9gnodTqjoFDxDALifvhkr|&W_-(E{*FIY zP3B}WapUn=yxjMBZMK=VrQ?nh1z9s4BQrxf8!&1`_DXL?H!G?Af1#RM_clH!QA<2|m^<95J#%_IVZ31&bUZqE0mu8CG0 zt@IPjXncwZMsd0r*Zxw7I%FbhB2`FvQ`+k+RS0%yR^O5=)yPoubU3{Gzz7`<<`VC1 zRH5d{K)&#eYivNztleddvGw)LYf~kPBy4;nLMyb;K^~<1YFu>?srKIo>!?aYv01R) ztZ>##6?$1he>?)2vYc+X^};=#ef}!fZ{A_PEVzC1fZ6E*d*c*q4A*Z>xH+*r^0seg z@3FVAsAK?ud(B{)_K-NL!kb18ZcT7Nx8LK^!w=Kx_I*@gQ7}C@Vm?1%cYl}B&N+^c zj+swSICpNJ(v_S{j@cQEnNCj0q@p_-lct*4az>UX^;FszS7VI6>pQ-iB+WQEIpJHs zA%8Kfz~L_H+?nY#Z&r;^NSR?8*HaDYINB!cy7 zi7^REHyTYM{>qv#vG;=z@0d4;YU|g|fiNRl8t0hMMT|ccU<2oRv)N#RtjjtNUay?t z;+4x(B^=znLthU$J~?4Fy-uEYIe%fFVzZ^23eNTgi|GkkDbAnYC+l{w&QThOn6M}}R7&|u zR8`Cu6PC*v&RII$F6S;@AkT8YP?7Q#tbAWe)_ME!zE?-qIprL+xf@O_w5EKZ5lG>k z;J&EFm6RW&D{9@0usns4+0LSW@}xIyQ}ddj(UY8!phl$g4;|=RnYZB4QPxVi%hme`w67~+$t1LS+BC=+B!?qx>%|pdXJM#fg=ki zcUfaLe9`nT#88a2B9W5B`Rrm5)poRAOpK}t+faO=)pu3h^CN7E(qjo?#HJ;!*sL+K3njtF2H>R9_ z?CW{_ZGVm>9=wZCo*@W6d11X`dU}^)yI?r()9H_?tYWh*C{HJVWImrEuw1%yk-XpM z@Zga7WWt3D=P4?~-NQr9?~GVY7D%BO_qt@tu_+34h_eK!Owh~)qfw%B-ud0{s^i!G zG(A50(U0=M4}S0^MdBa+@Q2;c{oK#-3%~FSuXmOY6#Up03dl2fBmc!Y3svbG%g}V; zsxb95;0$Vex0bTRL>wg~Dq@9#j?v#wd`zXP`MS~}4OA6MJ9>GCG}{3ItNDU!&)wwNXTLxxbDq0)$elYU z?CtGyJe@OJ95d)kifYSq*AF9^hQXxeL4K zY{0g%OqVNG+mfoRn9imQdmSEq{0WSdT)%N0h2zrY%N$Qm!B*@IN6b$q3_4weEyxnh zY`J20IOgf?rrzY3GoW_(i{JeAn#=l9gbmyB7`PyX&{AWKK_*>P?kI31!r`{g%R=f1 zXc-zmi@?z7Bv@0iSZ(O{`bhsRVY}JV>8U#5K-Qrs(jW4wf0r zs}OLaP$0^}FJY7bFk!)fYMMNM)hc|JX z;X-i;jzxjT1GPApzDU#XCgX&_HAxf5@Hup|_KDgnpC%MjCgSNLaOZ-yM}$UI=@3UI z!UR)$z8hhpsY6jrvq!V18YUd&h-G=(2VM6 z3Q~ck2TG^NG(jqblPc_`6k7N+9?~2wHBe%WrP^-TZWmOhfWn(gJ9$dd?Lm^VTCI5I zxocd1?i!!`)MuD3X6&6GlMeQ=s>kJr-^gq_<@U{MbhJYY$<2F5T)ns8@|*txSKjz% zSXzn4n0d64(2~t!%H2CRm@Q@u#zXcmJw(#!V}MMh^sM3d;0~w92V{AV;c%C-u-tw2 zS<*b?;m00fdV0)iU9r2f$7FiMsN1F77AU1Cokb}a^+$DXwXv>-v3rhR18)D*_V~W< z`#v$5Ox%zE_>aG++5GT_KkWX|Kl(?nH<=H3eDK$Po)3O(fvHNL+Z`H5Y>9|BQY^~Z zz@e<;%YrG#*OW}!GkS3$eUs^R>8`%N#6zueQTE@WR|whQ--W2D5D2e_YnYV;iBU6w zd{Nz#vi20jIvC$BeSxc!bwuC-OX=6`iBds7=OY?pW9Tc!ygzZ!kMOVA$1^#hT|{xXYyI@HKzo+v)E=%%TX4NqkPY!!bX(%kjP2l%{0w z+bIqrUv>w?YE_ZkLnUlGSEIx0{lrDMeY5#}p{%8r+{F$kZHFRr=RhID82zT)C#B zHKhVv=_4eA1g3l+xYC4@hlamQrImW|2#|MX`i6Tk5 zWYY1_lp8!XTF%RUac7PdW?5=*_4LUdk3tSbChyidH7NomS{HXg4yXQ z))tIMeY*WV$b_Okw1#+8>F?3DGAtK!R`WTPDabo1`{(z`vJN<(qE{0yTpX%>g&uGJ z8S#<#3HNRP(+Bv@553BO?Mes|8T3PO9VG(OEehF{sI!Bqf#vOWPG|sy#9DvyR1|#3(c~Q2K{-orKsTZlMP()*TP7(m;Qbk^y z7o_`1f(`|@`L9_M$)NG{tTG+=Z#uX(BQs8Fg%--MsC3BC#WU7~@?V6L4k;6aOpscW zBsoH6em$hUYtjo{{OQsfL$RK-UC%MwElOIHc65`3v@-y!nXOhl{lXDfufM=&p8g!q zK6jN-l2Mfv=dWC3w11wPcTO1Y4mm!)$K9LHGw67S>CHQ*+?td;{^Yl?_sCmW8bw7| zdpXByG2!Uw9<$R^#)B?z`0B4F?F^`_#8`#Wp1pZ;c!+d{H@@)=pT_fB}>ga5yyyrbHYBKXYe|>HKAZ__(f~%@fTTDp4F*WDb z*7|Tik%(IkL=&>0gN|I*xV8|sAe-bH>sm=T+G`@AmHn+mXbNl%HkYy$!Y=Nsd$MKB z3G5fGW&M6mczvm8xz2IMn^L4VeaK*{^oB%PYs_Qai}8)o;3ElULm4KHN|MAH8S14D zMh0(w@iL!0)qw#l>w2h^taX$c6>6YgspI0bGO{}*QY9cYI!REv>y4Po2SxZ%u}>kx z8mgjXyIoPN<~UQ5Nbh*>W*tWgR=|^^s_`@o#6KIny-5z zqbwpLHps&iSd32?LZdrFtTAB&P+^Orjwy8^_(UK*I~GB|o3mIh$g&}6nzG#%R8>i$ z6TjIEsaV2Uob?TWsVve%jc`)?zo!T$FNd)eHjYTKY_}^9T6dNtNjW(>qLXE4tyryB z6vdj07cQ|{Z&+?NT)cRJ>FLx@$CcpT!A&k*d>Ebgn68ev@W>-{@&VVczrdZlcNh+O zbhDJn$tjEViUiAWkdqIFWZfQ%)t1@m5miypAN3fG_I=ZA1XbljFlFcm1hC$0ST5#l zHcOP2^oIkwy>lp)giQJ{S;k9vT-dmLrD4x+|EuqV_rD5(?W@IF6lL<&Uy4uvE5>d4Z>9j3`+a8y-0H~CB?ep*4xv=tY3 zFHx>GT)puOosQ=2-32df3U+qS@!Xy3^g1bP1!Yk(813`P=bmS{JEAH}4kjD6#gsIW z@Y4Nd{f2`{#UDI-%C|n*0jmFDo2J-o{`61(G$$t~yxwGf2?u1m2|3O-m~B}(Eaq#j-#X^` z8~3<-JY}{jkclG6Qlv{TRfRK#XTER^XAIV8Zr}YqiuIgct~j_;asBoIs(X$rPdv`S z!Ibje%^%-n z@6pY>?2XQGbn80n)r>q(c>3luq&lTP9CLX63+(O;xqftuEbFtJ%sHLTICuF12jMmN z{GC&teADiiRQH^7{FDDM;VloRwG_-a@0IXQZ&4@lS?droMR!IRTOuhuKG0NNju8#G zVG?PqBTqG^@~-dEXiS!+Y&QjIKMQy-e+{{CFBD37*@&sA5CI!#LYmOVPh5p(p*oRb zDuZ(lty2(+sw^qXl3s6!HI~_A!l2hjI?2(|9rn)cvs!N`ZN+%dRpLzQAJJ)OM@##PK_^a+Yof~JIOisV7e{=ZB zpXaK03;)Oe_3!fAzw_Vt;II8W|Lf2E{g?fFzV@HO)&CdFKMt4vXTJSA{vp5lo4@Hk z@{y15xBvFv=A$3|D6i!2f9~ggj*ouyql`u)e((2w@AW40k1CSV6EZ|A2G)tzin>Q#cTX)pMwiiQR(Rn-A+zX zdcJ0s`bM)drp}5dFg1k`fxYP&%f?k9G{glH9yn3q$_)yIOjDLc5!laO_qkfn$#O}j zlQWx5(NZw%4>>$MU}tB96PDRx&c$;(9N)Xcg$ox*vp%=)dVZ!MGi)o%YP00&&wl~u1cO1JhaP&EH1AOuFqLo6BL=M6teMZ}Y_=Paj$W@v zzjqF;HO>i)u>si|*5WaEhO?Yr*=jbwGLMhCzyA{-hWGu{1I<4#I=1Mq`Ha)U1T{*~ zgM{b);o^_wX?^??pFyR&EH{p#q81_BAWHTTSg!SVex|=SQuMRJYouQ4i;$8e&3X2g z#hB)l);1hH= zIqC#f>w^FKnIqou4Wrjg5l_;bRjJt);WhITuO-)tRvY&vdjrdAHRa0X9Ugi3%9r&y z|F8e^|AQa<(eLBQC*S;vel7byq+xvmt5aB?V7~B!NR|AlZ2lg9{Bie@k9>s39((Lh z^y{;xblpGuJZhMtM;bjydFJm-Ui5zN`u@MccfR9$dDENUa`xJj-kczUZczj-Z=Go# zR?|mE2fXo-hp5O|ZJO7r3$ImU8#7w0d&WBY9m&NVKl%TX8{#D6c%e9++85V6akhT6 zYgl`FdjCvIi1x(f#lIIViNKk+wFqIP-+zShco&&1SU zG8m08R(n09a!gMT(L&N6pT{~c;jonnavz}sCCuqCG z6ib9Lb<}ipfeYg$AC+}17Atzao=-B8l1?{m67~Y`RYaGs)HwXsFiA8*X^hY~nSo4^ zDnoR3IG)TA5=J|_n96W?bim&3m_+5=zI}`H=k_U!f}+^c84S34c*LcP`^=9H=w%sc z-sRwA!T8)BRaG)OIpy5>eUdci=;#P%wv2jxoOLLjP#~Bs7bMP*D#2>GqO1&^-k8zO z9$7EP0;}bc#dL-#OR_9wFzS)z9YAAEt;7yrbJJ2bHOCvQYzRqcU&nvtt-G&KZT%x$ z=kNGgu6^iLmJIaG-~5*#J;%M%P+YC6-EV#@>;c;GZIub5^+fRIM;#w~`jEf;*1?0D zj;w<-hRr9%nTG8CB6_9(iu>MvUt`%6MDY^;_P%EGfp0roh|heS7ky0eqJ~qvL=)P+ zK>%FYb6nkgfp7Vii?4|$QwTxU8Swnw=3rt>d_B4PHT9rh-~Np$zxtoA^2o#Gmp_?( z>T|sFo!{~LsOB~HkP$QFycWvUlgws~?WAumMg2cd%D8ml65sh<-_6x~v9>j@QEQxM z8s7g}wGLz8FZ~(Kzy9r8eCyl#bTjowKF>~X#E1XehQXy5*OoJNMf?$O|1#_3i)!3U zek}2T`uc$9@_>ew2i3#YA37;K_NE2TzHrL7{Fy(!2ktcQar;!VDI$3N>}%$wetpxU zifea{*-u_zy;)N^nn6wehS(OMi3qlZ_n_w zgRIF}+*aYL4S8>b6oS=ygO-vk%Q-qcVK^AzjAb#Mvb(>>(eWXd_Qq@`$GBpR&Qq4N zIs1F(na*c8XL#t!L(G>e4i9cJ8V}HEm+f+i0+#C)B{1IEqu=j=vy4j1db4Ien{oZx z=Y3-=6nWlZythl)_0rX52Eg-qMMsmvlWp?o_X0Ab1KtJo2+f<1|R+p|B3Zx z!(aLK@A6Re_*xA$;$T(<4A_@;Z8x=`UF*VPUp&As(0Y6O@9wXYXNr@1aRn5u_jz&s zqnXgu=8opuC0d^^W;YA>;)yG~bR9HS@S?HlpT^P$7}GSF@jm+TPd>#bKlK#f^ymIJ zJoeZVXI?`tG-Cp*^7R)Ed zoEr}*wkyibnk4aQL%m_2!_xzL{T|(JpTolgtb@xJE>V^RN5`iqX;4Da8}88Q_i+e{ z3Y17d_~)5q3H{Lk>0rCwu-&XVJw2vxEuG!~rBj?!wI)?W2B~YP6HVfz2*C+HrW)ti zY*s9mQ~uq*{6+rR>GhY9b^c{Mu7AM2^RcJ-sh419{>e0&;YDvud)4V!tvCGRfA)*q zy?4N5GUF|8e(Twb%&etMS=v!PB3A zhRJls>14{gfA~kxIm*p-B24soCCCB)*z z1GNh`3rQ=5s`XlR{=offzy2G1@>5TtwdU)d{8}ztxLnt;munzBb9jDmHz;Jm_ay+#R`;vPn_P+Yps)JvonLJw$&&K|~s16Eo zw!wZ4JgP9o^y_k8`>x%%!L=JVxOw|FKkz;8;?YMRf6*ZupwsO^mNV=OsWvM%iwS9- zay&Uf%9JEc$n!4S^@=n}kvhQ`2ZnH`bkQA)Gqy(l8Ebsjy=d0B76&p#cgGl0p=^cH z22*WA>K^rJCcdJ2y$v zm|=gw!QFez7c269m*Hqcr`rdadO3k}n6hNKnz3HZL0EeIKIeC?km(HTV6$2>pG`Ts zcR*$D((4b|8I9@n21unTtI9{b*4JP(>-h+4S6Q~3HM8j{C&!1B<(4!}c%_Z1*FW%1 z_t;N-_=~>JhsFB=+&g~u8XtP^qvF-kXtpMqtM!Ke-#_(D=7sa;dG`+?6>{ce8l z7k+_z2M7GZFaI(>^aDSFPO|!S^>QAsug+ha4@AiT>x^oU#n4< z*={m_LX7WpEIEP)qXK%sdm*6wEU_5}Q z?>OFY(Q*CA@bF$h&p964Og`uUeqRlIkxu^1m(aw?HUmxZr@8oHO#rUjMmqF8@ASFl zpZfGu{OZ5{An*FC@8aP{9(&PiNvV|5IE3>2$nKy|e|(OltSHKYa$B&R%~(xO=?r>o z%K|N9h=>2rIP0$isr>y>3ExOM&yx-@0Yu)b(;ZZIj9Hdwe0r9x3c!YYp$P0^hZ2rn zCug$QP#Q~`I8qe?5JciB3*o?LoC{587`Rr}2d5%Dv$HcI%QA%27$?|P1|cL#-sN1U&$;uLSS**!CMVp!aTT4U zjK;eR$79kw_uoeWrZQ|dYl_X5a$B-pttpBnQd;(Q`}7BwNwY53pZP2Yr?+0A7n?Wy zykrA;-$e8J_3Q3cGSPJPM04GmWL`Lbp1=MhKT48h&1$_~pNkhY7%$y?xR)%ne^kTS zUfnb+on~TqcGcqx?P3G#tz)`&6s2Rfv>2{a>V8~zp;dk>-fB6@x(P{p&LF})u&R?4kL6Z~S zG?lWRI5aDC8&c028%*4|8{4p2+fC*VeDAw>=*q**Dzs&6d%2BfyAD2RgAnBR2{tk`}L=L zlS3ULXiSI$;Af+53J#@EEA{E9$8e%yIJG%^f15S?*SuE!4 zo&*&q^m=`I{T-A_!u4!@1ZRwF^&)Rd>znT0V8Cd+Lsgc{ zr&H#$DU)N*`s@$-tkz35#TF+7X_ArmdyLQRkY^W3lO)t8Ft&*YeI*}HzTwd?>HQvk z^ilDuXf)%>$T|40zyERW-a7!`&wl+kKA_3uMU8>@A{tF6{^*mvYw01IN#z$Wq-Pq$ z_S@Urrnu^F{hhHdC1$^`fWD}qyl*xuUaGll-tJx_1@`RsOq`i$#)i{67z_qH`Iaa7 zo!|W(4h|1EI6CCg#fM(@=Y4&3{#xxcW45>F>$-6Aj4SlW#^k;YhW|IM={s8w;Rs(!CUZR&1Ab)-mjTF(=gumv0eMmv0;AD zfm*l+Q#V?FxW5j5u^MP%iYMZ=(P+lQwLRN#e$$`-WIQD=b!yNmmhlU?7+qO z>HK;&rPt{obwX(Zn#g!|^tRk0v|_ZggE3H+j_r2Ma<4!LhBxAoJ3>;tf{c3B*`qUSY!Q3B)kTFGwGbAn@P$}%67e>mkq;p=ltZ-2yY4! zE$y*2QM}@t%|sw55!NA4pel;RDH(?8(LJ=;vfXS+5GYqMIl9YWXOCP8*2@%^^{A}i z{KdD+@~3h$6R^jQIa&Lsw(EQIg7=d%9Lbj%I@wCX`Y2xWfhX=Jg7fjbTtMo zFnERZKhV|2yVHeKbUQiadd}hDZH|u|tM!V(Xv|}ezk$JM2ehVg0%M^Fr&3uHX5Pwk;^RF2_!~%)tZo**Smx?0QEYio zA#I7&d62HCRS?^S)p2%J?@!q7#f{`kO*8LnM88;36|WNyTLss(BGj6~JDJRQ>a+f4 z{>USbbME}bS0q;Q_0{=n^ARVOQZ@i|&jf6mz$mF{OhW!*jR`*SwK^CK`PwI+lHhrJ)BCocl$Q0#f*y=&$EBw0*g(> z?BJO7dW8^{ZofmfHzG-MtkpGQ$_1UaB*dk}AQ|Uy#!zlcHroxREHI|RTIY3{wn8{V zZ#dw><%@K>Io3H&j!wCG_W*ft%wRZTJl-MebU-VtHFdx7mAD4p{qA?Wzw>wg4i_(8 z{F1woKM{?lbI>0Qc=r$e82{{_|04Ge5BTL@`DK3i2j7j5y1r=cAMAZmji&qZZ87&Z zowN%sFCkJ7Z(D9WvvafcC#}`if9}QVtY%335l!SvA&XvWUG%`Wzvd>I{_Cuoh}imI zGMUc!rC<3)X0sWOKJqy4`0npPh*#!i{`%_t%YR(EcFlb;X69rvaRB4-_*MDh{ot?t zJiq&i=fdR0-#CO6A%aib*KB$>sL%RtQgGsHHP)PW{*`xN9X$1!r}(8``DK3a`+k_c zz4JAy=0UIbKdx)L-4y!I<<4ly`6Kj|r*ogPK41A_y4w2da9g^%-hWY(BM;J{f9Z8l z)Xi7xUht>fbzYg~J{q~f&cTQN{fGI?XP+X=a^Cg5Kg{0lxd#qw7PBdNw~JBR8>j0*YinN0xIVam5*)KSwfombep28FhxmKS{CJ;%0QCk17!gFFb*enp?Mz zD2pv=su_=mHpE>8#zJ0fv-JEmwIVUGMCkf;bLTD@u6o{1Q z$OvjFrB{*~cZhW@hsC|txR6F>|8F3WT z9}ejB2Y6xNG^_IS{~CP%``=HV=dbE>eoI{E8-UmD^!U%e`4960|MVYndUnbW{NwlW zu6O-m)d{)3smPru>vYr4b%UcBp05vL1*uLO6`HE|&L#GRT>=zh*$3q*=v zQ-5h+-PnBhX%8jP)J?GM=2X8-?c3}(e&aWa z&jd2x^{#jE-uJ$jXP8)Y?^E^4ooM-hh|wKH9LF|N19>>~jK{#?;hRNpCQr zc5wFCx+wNlyBnF3uplLV5E6$m!qilGP83C~(wr$yuy3y1f{+i5#?MCt;BiYo+V^ z78W60n7OVD(l#+l*5C;bt4l1FZl}$9xgaanL^hz)?GQw5Jm06(8tHpPO5!Vz`D{*Q zEm5n(U^u`JJg^dN90Mzbhfwa~HdzxM2LvDN2A;0i)3YqtPK{mNB1SaCULVz593QcDoD*6Vz*z*8eTjXl^2B z+U+ji{LVkbzxlWSnybgxJ~PPtY%`P3<=_58fahnp>24lw+;$g4CvZ2x>wO0lpO`c! z`3G*K_S0{e;y1=je(FEl&(m}8TE5wCSmW)rXf09L;)%zfq9}5{`m4Y0KPt$C%hCC( zT~QQ?_r33Z_FKN?TL2yao1X$QU(+vK-*cu1)d;kea{b*PP)apvFJjvZzU%51sI3`j zcVF3PiogDAT-NJyIcGFF{I%&i@mrS-`PuG+8*q57?~Fs&2JY{Uy6%wO37n2veCk2^ zGqo1I%6s6a-tL;b@Q30)xUbQ)O#|BFk3Gr7bjt7e%CBKGJoq(bXGLBRhCV?MQPgY= zZ5zW|UKB{-dgzTYNE|cgnj zq}GOgU$c;+G4HwOTjPEYUKDe5?GX--j!D)_7PC3GZ{6mJr{Bt7{O|tcYwiN@elzb_ zLO6{k59DM*tKH@IeB--*O*Y}zyZJbsk@!u!>3-__`v#xSd?OW~byW1}e`h}?E|kPYvFf%D5X?R!zm<6x>{T*Wn*rz+gPJU-sv`HWBIDDc*keaqPw8?SHse6vb2A* z!RLRB``~B22mU(uLHj^e;cxHzptW|lk2bHR>yJFnwQDy%tG>6^hO#Q?^!n8G=5=Ma zte^nOq9BT*ZRMi_lxABAEjOl?#^o&lDHXNW&h;z=%J=Y;B5t>^RZXc2@+v1?<|rg# z;1NXuVc2Ox*fl-|QyH|@Ae^$(T7xy3IP|H@nqr;e6BGLK0WgL&O&q7#HV!$xhe6i{ zglZUCgRU)gttpEfFqm319F7P&Ejou+nI#3wq~PfAm~Oj+=SNr}(ORHujjl`b${C4t zU4wOD?Y`&Ji6eq2!V7#*ib~fM>x|W6jWL?Q_i44-L{WtDJd72taS727Q)U;jxM@$q zv9k}z?u12~+9lf{Xmv+)2M5$u!D2CgxEamo@2q+1@d-DMz3tt~en!yt;A%&L=kLxr z8it?c!ZQfr@znL#_6_3KyZ?#b07EMUoX$%Q2jN2lUKUA(5b)$RZ%_MXf8Ezo;KSYX zjBeamB46dY9G(A%gUuvK__lBRHooV3zUK=9WWMuVe~fSaWB&zT`Xyh~jK`hx+*2Mx zvSTh~qqoB8tt8TcO<{TY{)(rrx5>-T{k1A3WQ9f>OTYcO-KMS8yzw!gqI&JxVm_DK z+Hd4O*lWT2e|5#tAoy*4ExmL<;mNBlmg(pIS^^mL1UFAJu8#w}Af&F11CoM0^NK-N z1?^7XImWHn)gSIfcCo>9&EH6=nhtJ@Fz#~<8jC>riqH=UTOr0usk-|?X|rKk#4tAw)1sOt*fi|BM(L{Z#GZd{>*)=kOS#xL$Ly))=-a%{J8YCC80=GQDY zy<-Bjb%0t*$>?D6a0AUh`N!YGH~)#h#8T~*>C=jHD=0h*c;pE>j z`Q86#zU2?Ui?901xAUj|^mlwt?;jpc2*QA``MP(#>d*ab?{o4M@X7x>488&UCs5wE z@a}iN+rHx+@8CV}c@OV?_q+M+@cs||&<~-M;(hOX-xmbP+#XOoMHqMpDNsT+Mg?d3 zabt29eIy&LrjUE1b1C?tUpVE-t6kdB=XSddeL-z3|MKVOyyMNC&-uC*LNI81eB|Yv zhi!fI<%0Xuly|&&^4t18_)DK$5cn&`z0ZwUP)ZQ`g8$>+Ex2*0XtzR^l|=}Jz@m+5 z#=w%QEE?us?X;OqKCJVFNsKky7y<|I#P(x_1!0;PBI)WBjR0X4wzdc*30e_BJHXZ& zT~ri#Nv>m1mJo~ZG`8BYr$)Ok?1hTDv?%3~Bq^PC3uF_A1Q=}{6DmaGz_!#zV}){B zX$(o4kk^*H$f$LVXDq#bi*;Ji9*ns9*i&S+;Pm7kRarHC?h?-rh+8p!*dz3Ol=2(T zh{LyKRkB*H$O;$N;rsx?}hMiOADs|sBg z_)3AW7+oWzLMa!O6NUjn;5)rqSyEONzUO1Kc8*~ow!PL=ePvKvVYhB^cMI+mcXui7 z5(pAp6GCw>Zp9snI}`~H#T^P1cPmi5xU@j2+YVF zep|V0yvA4Ine3d0?~FT@jr*I-qbC8kM~#Eu0lmt5|654hopil#Ook4ZeHVy<@JYkq zEDx9$8GlNE-((rq5ya!6Xq{Nat?6Wdg)Ds};;CFMBQmacC}Dsd!SB8MS}%tc_<>p6&C=g)+jYymLrqtdOp z>C(%-e9)bfkdz&a+d~qG7C>h;Vx|xP5pbgutN=_hg|MDME!gp=19`p%38?6uMI0WJh<3S z@y}@GbUvcg-`os`G2q_5qn|TWBeRYk1o>%~ivZ7rYn1h^A(1DV!{Q9dW@<-WYtzR+ zIDI8GA2)r~@r^~z)~ezSsZwhfazzaYf5tQYv`oBubQHq~ACFEsnh3d}cfZ}{yL-Nn z4E=pOajE-zRQG0M@lD7y0I>+}+np=^cXhpYHnIz7hst4S-7YVTbi=;SojpHaw&8bQ zU5edV{81S{c9)P01)1z=M(Dw4kMf(d`NWdF^b8m(?L0;Gx$>oF&P$J*_t}Qty**}+ z!tu(cPHXqRPQWWMnn9=%#6m-S(dCl&p+!5P@2D*Pd93s{KEA4S?S~&4s+Lplee{`x zd}y_(H#r%F31Q{zyaqRY-1<65AVm9aZbhX#b|mVgd53 z6(f@_=@jfU_&f=l<*RzK$w%;7EAE{AHc?A)P&zTaO^K9c)w2zjMQi}&nJKRpSCH!+ z(@uJ?F0Ir7Kc2EEuHF9y$D~I19+Gfs9x7u()t1ooOXN?M0~AQdxib=%o~eik0CIOM zovT>m6*JfRVVRjgoeoPPWugXS0uIe4Gy~44mP2L5ZXM^&&CyHIdPsePX(O>Wco7o4 zyh6oV$}LhvKY#w%{QlV1H@qXJJW_y-t4q8`7l7uCLE;KA{Zgd{J;k43;0}NL>3#~Q zZA&0>Uj#yG0CIGqKvj?@?X+OgHx#r@+`l@bBqOPK>!F;4_sL~X5*Y#}ithJvH-E3p zOpTHg`9R)vs|Ywr;P;&Hrh>|gz(Q8tM(*(fakQeFwR!4%2Js@vh$+2Gz&6B@$kNc7 z+TOD_Ici)tnPuEwo0sHE&&ZXi;dgq*3?3=xWkoDLFui`9Y%!|rx@8CN^Z0JgnnlzE z`}q&Bi1l&DKKYJ8}R7ziBkHSs_s-q^EXA?5)4kcL(&lnH5ikpye)N|vU z%$uUAbU*q+?Oq*bO<)ls34J#8-|Xx3yw-F083uiV@@FTreymHE=F8;~q6+^?vGba#y8-ZFojt*$gF9w_+u*EZEk`}{N|U1l&r06{7fJy!Y(GYb=x$ z6SrbRllg14{)?oP7PUtAx7|z}kXqX$IH#?y%~bl3zoOiC{$iaEyk5M=nq@;kwv_&G zV)_O=gHO#arrGt`Ucs!VKAV_l`YWufklu0sc8f-N%y0bTug>k07V@~&Zz_igf)RPx zMc4Y-tOgopmvOFzt!6v|@_zg*nqI5-h80F{Jc?Ut)J>dnyDP+~42@aSPCNq79fCR8 zGN?1D^s-$G!vwqoWjKAQR4YlRk0kT~#8E_>8q%fwtKD8nuol52Up%n|cdmc#7riQ= zBl)yf`y#Fu2l~y!k}6hHGNm;zkhIuT2i5%5^EO0-D4Eq2;F2J(EaMGhhidMHw`h+$ zmYcf9GS>M-#F=?Z!CHisJEZW6NSrT0PP*zCKP#3}j$L$GX6MHV$B8_u$0~M9Mfx>@ zA6TND_01<(+;Y9!ZOZEq!urqmqz#%TDH{-ym}ZomPi~K!fGD!uB#w_Z>9jZ-{J(z= zwW0Tr*o%JgBnf4s>g?J{fp2J27pT{%yRT0>WGafr&&2|qL$3e*{C9ln?%4$e!*}m~ z{HNu*0U{U7?&zR5n_8;pF(SdgOIU(2YB0oY`U50G4T0n46yA}(k)wSb!st4xP3<|I?~ei8O6uF{ zj7d%6-gA!C@lV)T)`;vH{ksTNIC%dkzq2dgo(Af5S8@FH(!_u193H_7;wI7IHTZTb z!j>YV&1#-3f%D2d1HNYDFj*qUkZi8TXaNO#>D5dn+IO+Jb)NlDaTDg`c1UXl&7Jy4 zs&P927u=NV*Ekw1i`kRsfs+u?*Ky3lzSLSXu7N6CxHsQK)s6L7H7ht={JIfedty9! zoMSiff?M=WdH0u*(;;hiST3HmfE@maix$GIJh!#*FRMNg?{?HYGpi+8a9hGni|qv zpxJ)KA!FpE2rHSL)$bptN`P}kiJ%t6rqdz7g$X1dV7jA(0x3hii^_|LnIv1QVD_^s z5<0SOi-z%+?2}~`y?cPFQgK2n4lb88pFC$Yq$s1CcXAOIid%HO5O4eKQ_9JU8}<;d zn;Q0+?U#ym?_g1e)V@>R$IT{lcV}Nicbojv8Xn}G?}GH7U7DzId;UFAkECuxWauF! z&jatScaP=}2*0~O!1Br>=N!iqoIFc!T!NK0KpA^IZn9{I*}gls-V5VW%qy~^3OkF5 zxESA)Ee^_39nsnx4%f7Cu^_p+9&^O)59ocT$I(e`00d?_%-W_2OZKsu~g|eeLY#f-(UgARajinm1!sztQmt*n)qLz0|v=_>kEs(Hk}h zR4GEW_X6w#w9}y#^ySfvnk1Wr_?N~B*`h4!5kzGHuAP)G1_nThko8I_fM>JC%`x9! zCiDa5zn8k9VZPfj&Wd%^jIf!$jr5%B&@dgEyU#01{lBIM3Z(OI8$+I~ZoU|aHZ;mTd=l5=b>hImr-bU_+=LZ3||pCL$d)z0#%Z4!sD;l0@8ZVRBYU%UD-Y& ziDZeBP!CA6*)7UzMh=!?JPu?e@q2JLYZX&aB9I;)t zOzx1HOWdeTTwtAfXDjXpVLJ>ir>i|-&QZpqQrYn+kfv2(DX?QjgaOm_omj(PW4%i_ zkpQ=?#z=EbE+ux?p8n|G_J82)TL=Ti^V#g(N zo@FD?Cr|u-whHNsp-u<`nW9EiI=+7b*fcVecq12G4F4SluGo(@+Z2VbXObJpiz;hf zyT4im@UVJhQZH*g=simUBqRqc8nb-<`}odw#(`{g35Zm&i-A03ybT?6QL3T-V3-HQW)r+Mc6mL!35xqW3Ify5WYX_qPFsrsxVan zpaRO(mlB8E6X`oR5;DhrN3bWx1t}%A*H=}ubMNdERRS}Cvk+M)ekubldahtdLs#et z+Zx=0@jLEksGf~{7D7<;X919uLczf@JhltcE)~g`WVBgUp%Sags-iU4tVVrEC4EMa zfPo%c z2Fa!6_$bHmcfa3Xx39mm#csC~9zpXCSwV-Dj2y)E(Fpi^Xef#yuE2OnBTX$W51J`f=1yHUj1a^m!+ZlFSQb5IAPTGYpYLVjCXAS! z{|h-6dLLa8y}lUtd7o4#AQ?RoKY5aKZPXAt6D)v;bPm%4m>Xh(tu?l@n^eA@6=0MUA2DIZZdA0seFn>3N8yAC^RyUz9 zpV1I2g};F<-m*{9N?waFhzoNh)v{By#M;+0Umk~vEX>4^LV`Sj-rrtXy@!^FA@4%x zH53FFOzb$_Os_XdQ~?+H?=Y(&e4Z(+?6b)IZ{r*)yFTNtCLoX+8^5sYu6Vhmx~Xkv zk*phw(e&%U)kmm=*u_O;ADXYzx`5+(yeej*h;~qFU7dHySMkAGk#2ZRgF=tRYi{)N zopU|R4hbA#Z5`@^E(1Db5U(SF*nBTdp%t9(0a5Kj)pD+{ZTa4yaPlOZl2VI$6a%-N zc*f{7yF6mtzBUeJ2h~^ZAgS(OzuQqE?WT`ic0F7Lq_a3>Rn?PYwJMJ@@l0}RJD{ns zS76fIA4`F^QOYH_sN@vvSmt~7oO>1$v2rjtzb7V0@#!_{Qu+oL1&kOXW(oG41;$4{ zV%fWG84YUd21b0D3f|`Ny`cC-MQv){n%5Q}Tq%Y zQ`|L@$x#+44WEj9=Spl?C7tdzfK&*@<5h$l2Jic=cA)f z{#2w3P~l$1asb{VoOHiM(^>{!AuMVO45t%EpkkjqgVh+BQQ?cNU;l2mNEmjnG9|ox zh)SKQ*}RbG7kd>*VzVsFDH5n%N@_5vqRrg-T;5YsPD|Yt-n4bz*rftn3bs%3*dskx zJWKNW)$>WfFICT=pY3gFPWk=xkNF0~zV#>&sCh;0BC2&1)3BX_y=fJg((EeFN>z_u zO6x8XC&m41{udOQyRF~_J_iD!|&)FUtq%Z zQ;te)Zc&^UylIQ^+Jy&IJXP;qYXz(PiYM4k5_=eR`>wFYF;qbt$H5<;KYMkm$FsEx zq~fblX%ddwKW~nW#=T-z4BoY!5*bctvW$Y@#j(egu?_>;c;A~7h47cHB!e6{tbRIJ zO|EcF{60ay}*UPd%oL2DZJRR0uqYp7?J&%E;KH!B3-*rhSHko4;LcL>8s|4DYq`zD=}Eh=)pr^*qdwGV%ni zB7qXvalF|MT~@J<9?j4@q6B6OexNaMiH6~_?v1ycd8!jWMR_Ec;h^S=3NM`E9(7=J zb9xRlc!zch%t1EXb@f=z z?KgtgQzt(rLbm8Ek>rzj6|=MBIOJBOYXNQ$BB%5%y=bu!aPYEncQTvX9n*%rf}?a@ z3H{sa`N!9L@bT-&mQTq4?&H!IT}9)yFXqu*Ar^_LJ9aFOC<{p_*;{d?GjbfA&>Cw3 zP`oZuJsy8ka_r1Z^Xeuge+I=UVl^9nZJ!c5tMFsRSu}0fpu-vMxRO3S%l5N81q^qKOpJs;q@1skyu2ot;Qv%nBANb;2`%4 zzb$YT#GHTQqR_xH{FZTHT~bMzw*Grb`?uzaV*BMJ^$ZcGlWN@8@5rZF-~PL69KA=A z`}eolxBPoc#b>YNWYsow6ysLxM1^IJwd6q3v-IcS@p2QkdU7FNW6H;Bw2X6Iq24?3 z=~^~ZIFbCou2Mia3P~90Y?E!%VI3JTZNcr)xqTC^T>YHH<7ik9KlRW@%7q(q-Id4)rKhL!~r zQT8e9$M#OR7gzo$Z1uZOVy3b>n8F$o&&@n-_`B+Qi@;rUMP%ZcRQ+%cN zCTD%_T1vKHty&sx#X9d}y^J4$ZsSB@_g>BPjd9Gw7sd1p%%?rt8k)Vgi-E_fM-A4h~mW{I*^xO}^8j2^eg2 z1RVeSB7Itw+Wj%{86DJ~Edix?*oU+2UPox3EDlrEe6 z0^_%Dmo^iBpdz*eaHqYDyl6M3XxIhvYYWN+2 z;{5d$v9B9&h{Q@NQ*I>H`o^_;n>oP8;PAEldWnFPm`f9OAqC| z8kpTYDeUQ^Hu8Hxxst3#F?AD4i$@ZVZaentDI9kq_eb$TCs2I40Or0)A6{~3d<#>e z`Dnvu*p+WWqrQgzvPA0%Ew+I0}7`_?JB z+-}Ffis;%?kt057JK!1DUY-KgCj;9@4GG)LGDUhog)oz_H#m<}AE&9zd#Y#>eeg_% zkqjoT!qap>;bh4c(Au$fxIniG1)5Kq{)$9$8bFGhdLoi93| zzJwdB<6vrksIF4I#Hg3;d%8fIlw0)m=$Na~{m4D4Y}{ELNM_^{4HvoJh-Xi(NmM|i zvpEc>xIZKj%jL`2?g|=mg%f$?{B4^4^Kt?JFVKPyrhc4n%UF3m&eFzY5MBCi9f91m zwUD9twUg+C-I{?`99`!5qMltyWxn*JlH=Y%FgJ#Sm=#jt4$dC0{A=3ZqP*`qFqE1L zrCn8?I-UzQ0&i;cQakN4ey_&a0o+mI05r#damR18)2eiat@jsslGqNOvPT}&K^Jf5fLwww?G{eH2R=@UX?fO99UWMfTU(B zvY7gW_(gxreIzoQL;Yj?&l;q0uVC*MS4ia^u!b=?m@6>#l%q@cF5kX*2JhZAh8(KS zZ`v*61HA2ey|wk7P;J8C5T=h^fx>Ly0#DBq@*SPHRaQS<xAA0m@Q@UYRY@jnVa1Z zT@GsBWv2QuBQgiDU0bDKUib3M^3I+JE?A#@SvmejTJlmfV-iULAfg3cwWOwjRbJ0|Ccij< zM1}gQ*E=J}?Q1CEiA#gH%8)Ulgp$*#O3 zv05FbT!Af9xXL_D!%8*lNXP_6OW%gGl{^?0n>zEGD=j*{WNqjds1;y2FTHoA*3N6n z|4A_slgrl4rdLu|@X~1|59Asj5zWQ6QomuTUP5aufGc#|M6*7;f+PwcDjyTiN1qIi z^)Oc`t+}yz%~X2tXQYJPcr0b*X%ZtQd5F^X_qzunt2g>p!H3Mnqb5A_BAenc%Mz&K z(LTqRAlS=ck@-Wh$Mvda;xAYm?}u5ES#s6`Xrt1olH+vLryWLI=2vZ^L8QghS+mC! z2$E>yE-UU9;9y;z5$${>ooV{iZ!=RF9~*syDB&ocX%3+-AHA1O6scc>uAYmOFJQ`H zDyU^ov$}LUN`GL;#86Ckk~o7*It!2bGq$%sX|$Mqd8O1NSG71ZqzIDcKp?-Pmw>Zp zogj_^MqDICj`XqZ_tL}oOg)FXV;5$tXfO78`heRg_*poZqEukEvH z?@xmK(>gChI?W83Z--x5Vc{n?GF8NqwIFFH>+{tWNKdnKCe5SIk+hi;*{mbmsI6it zHw%yeF~JP3>eX9i@xiNgB1>m9l~EaD>v_IC3C%HQwlTNJfvPDU9=;0KH=KUDS3;D! zrvyqZWuv*+gs3+1EmI&?$`-K_@@(Ty&AOH2Z{G@n9%wX1KjjN|v8e%xtdngKqP z%V_Fzdc)oy;MX}QSHkYSR@g229Kn$_8sE#_s1@^L>-DFUL|Yc?RSKoXC!8gU4cz|l zFPfP9{bf#&Qd?X$uFLNlHBuSpJ$)2vNEokB%#P^NSmul072@630{7_rRGz%K(Z`fD zQb91e6*#@i<-9-YyK$S6lTAWmj3RD7D^st;R4wWvyairGxOHl0vqsq@_;NXlN~uy0 z*?XSi(}A+jMbxteC1}c}380Lo@X3tK$)RzZw;!h>#=d1PII9sx8Es0uBm^hHh0sSB zRcc^Li2TVZr;A24DVt>xr6$3E(sfAHNd#Yb7ar_?|N6rl8Rdre7K z*LdPQCG)cb)VVquvaS&A+^D)Mc@gOgyWuYL}hxY1&g#DU84o@@xE@ z9@hMGf3XU*6mjOP;3n_#AIzj~YJRqI(JzA{O5g|% zWYh+eL%&uoFG+emTchYJZg)w|x1G(oN$Rn*I_<{R^zZ3qR6k53uKcdJPZ{Gn+<9JY>TU^snez}D74`d9zq$&Ghcg|kiL-!!#> zCIA)%K(poCM_5=|{)b+LwLAp1i`Abz_^dnvQ~x;5OoZ8D?c+O-z}Ob}hX#_XFKaXw zK`6+P^nr=dv7`};foi3Ci+199?k`s`o$Es4SVl$c+?v#vFxivA#XgtNCy!Jvi%2&IxMK@O^Og#09>dhNo{x%t=t9ik<5Lw&j-` zdxvpvdRbsh> zWMsx_n~MiG3u^-46#x;_mQu_FoeKn1FBFw!>Mpjg06PJ*r(Y+Qj2q9M@F-eCO%4nEm`()!Da z{zRM3(gy&hiinbNvx%ZC2W2o205NOUB}Mf&NF(RP-J(jWhh{dUiQ4o_Gv44KXqI!H z9h@Jv!VF|JG!lv1(6Pa*nd6GUd1!P&VKD+=qx`W|5isPM=6+(Y;TN3rb;!qPS)sfp zX;8R6ZEcy(xSPq8yGcce2Jbc^RRj7cV4!D@H5sT}M`qhr%Fd}0DKHM0oz+E=jFQvzwG>1o_1T5NWi^sYj@CJ7RS##-Coh27pA4W4*vR4*w8{Pnf( zmxy7xr~IRn&mULQuBdS^+zZ81G0e(-9+R*+^%5vFScAhgxen$DM<9iN=W(2)jk8_uuLY0D)=b9Lmj(g>e1S6nd2h zvv&~;Zvu#!(HtzBK}8uk5|(=l=Rfp|Sj?;IO`ubP%J~srYZ7>%n|(+=g=st|ZGk*( zwfg#Bo}SSAZllV`rJsMDTWHNm$VfPJ@q!6^(?P-Z!h286V(u@|R%6+eC~|KCWCbz# z^@|;lRGyNO1Dv`))+=yMF5C*#9YrME<1DfuOwbP0)nVEhJe-}c<~RFl%Kwb)R1rB7 z{E^wy-|b#|1S{qHb36~0E^cCkzs}D@V)Xrx-*{R6>+S5X&_9&}zF4AsYZMRvxoAfd zk5%m6SHd}0)e--l5SUHtgk!p%tuC4iMoOosf*IOr>iiQiKv|Z@!I-r3{4;o(NTqH* z5s1@&?sEN$+?*hu_99jIl=+mk)1%XTf*#zDz>g%lUWhX_Rr<(RAr*IOUP_04&!f|i z?Aed+6&0$NSl1%V#zqTseT)s(&^cJgGf5rZx2H2)lt{1Gn?NBS<)78|do=tFZI^IX zPpT8U1yW?6(czZwqPT_+G8(t{4};Ym$oesFeh+r7F3`~7H;v`BW^f$r$4ToVmTfwY zSQu+oy8ljz5^wUk!(v!lkfW(}PfVvg`&clMfBlg)R^zlwU3}MgK1K@8elVlG>m9`e zq_B}H4~_jUuW+Zh9e6UH3lDGpLx%Tk#wkvX7#8+PbZWp6f?l(nXVl z&h||~Gc>0O!}#q#EOdSC7!ag(S1<`GZMu(QC2JP%LbnQbLV7xrW~%YhWg`ESk{Us! zbfy7jX~DB5$lH*+mWR|qy@yPnTGMoeG(ZQO1%Ee@G1`#IfLUl{Z%4W$;!vbdisrD7 z{2YBv6iehlBSe#u8ggMzY1V4_n&pfNOlhV+I%FSbM3?X!-wnq^LF*1{DG>vdD5lsq zGvr(G186;igR?dQ$CFfxt^2qEDJiBDtbZmMUG&4hyL&f`oQ-AraC#--mScC5ujcY>3gTsH_Q^?reeNd=I(XvwytDRRcJ%)rX=fIF z#%x8MI;JFwE5EEs)YUUJasv%RUmHak$<}^M6wbY@8Y8!M1HGpOw3)kqS~77{+43AQ zira~?`^l`8hc{_$@pnH&aEe#vNI_NMe!gmQ)<{E->_6zqH!`nZf5KDIcoah}WPF;we} z;i%yLUZOgopnRgJRH#eGvEV-Be71d0WDwR~kdZ@KsFT7T5AMwfAN2Y)dgP7Wfq^fJgj26?Q0!^;1Jd<4svLA0 zL)Esg#3teGcH>DNF(l`Ck*UP2tlhjE@yNS5_V-?i?f#bXJv+k$iWLtXj7L6TePap4 z0W={4+`LQi6&ogCsyGR6NBE9XY+J6>XB04jnU%G-Aq$iQuf{wjm^BeXC-67%!>b(= z1YjOJp<0ilWNGx&Ac~B@zcYQtZVx5Tg&pqJ@pyS>Z$>cpF}UaED77tqF9-i6HeRE# zI@dQxQ8b{`+@|+*zf`X}@$+Z7Frbd^Xz3EY5X~AwZh4PRvI>^ZT2*6}==IG)ypNM- zlnu^^-7O>gf||hk%KVl2U_Q>AEgc|fTK9wag%~gFK-2H}YU`6gvyA}#tGt)Q?<#(O zQc-3!MeqOLkem0i8f$5B_g3}>IRGmw8y;w&qE?wFs?mIoCN`c#v4JW)^7lc@b^jj0p&W{+fx$VCSJ%@q1IU&&EOl;8^!OOm9sbz;%tqE#_H-eict@k5xk4g@0blG ziy{W%){zgGiu~<%>9yVp9o=(VU+)}$fs0M9zE&<1Cw;R+xMqJX+>-ut$Q(RozB_zB zCo?x=QdCW5d32QXmdR&mDdip3Ys80_OO&m^nFYJKd0MO2Yt(EY+eDnAhYI-|%5xS4 zyE6g|f6h_iK?`+tFp!%92bpj1(KcPUeC?8Wj0j<_S;kI95ugQAu*sd9O;wzyPhL<9 zW}RFVIp08=$Y4}Bw5wO}mpxxWHgrgQP15EeY5BhNi*d!Y*X9l{MFLtoP^~moWB( zHGg^_W|A+KK`jWckg5MQrraM4Y-I*k?qQpj z>*@`=4OI=Il{uZWHu%O`cE*y!`&6)_?-(=<7k{Mta*aBFzKb8Sj-dB1uqr5PN8}YU zS6;Wlt8AOaRW(lWQ~>+qOUh~KJk>PX1;?%2koqvD{8qCsr#{`>PB@&f+bj$p^$zKS zJ@+U~DgQ;)Z#@7;-BbsxDMN2nX2^m3Cocd{Dpj;^86Y6^=G!&f|U5- zpMeK`Ge}%JPfNEV7njWKqJ%*cTC9L~r5zRbYuomHUAw0@C(cj)j z$cjqw+K)1MVsr&K15ys(JGo>=kRDM2h~KWvHIK==e9nl^12hbYypsG5fx5jV68 zJ!G=_fElyK?%#Dc(1l-clWz*k+xc5FeTM*znt6_1c+$ z74I2>!^&vNbMhdCvhs@M?$7+Zo#gx zyk-bfwcX4vZcE@`GHweI`a5dKQ-MuIiM{oy1cQWnw8PLsIIV8nEOGTA7Os4Hco>!6 zxP5qYlj_?Oxv&Wg#;(RAp9#N0;(A7pY6;qgeOV}4wtIoP^?&Wq4Y_|OTC>RNeOYj} z`!o}p+4$~H=#LxULaUY!Ip^&y|K&`ra3{cUrDu|tp4!1OJ8sJkQ5(LIuH)8MBl$d9 zZk&hQig|3G1B5Jd2wEt#UEd2hHX6_VDco)<%%Aw`SAI32a^0Q`IuN$DET7B&8ia(1 zAH3+XzOID_eAj+!3x+s$9%Bw97)7wC^DFCoP;wI%^zMpZ%{CfWOgnhV&TeB7ab|rK z9b${r6JPzPWx{`X36xSB)5CmAIP=ut5E(JAUt~QMT$wHk@{{KjTeoqv5`ME ztu__RS&ZsPv1zZp(NEBMtJVOmYQ-5I=eCC=k)cB&oGqKNrH22N+i%B3;OJBuKFqAof$gZSz2`P;?s?LG<(GMuO>NcNJ-j* z>>Va0!5;i{b`8^*4GoptnsAGrp+7y30DABkPQkt^D17u=kZhkDJ(zsE=UMPSqoD?h z2s!JDF*?I~jpha1&f-F95Df@EKtqth1ELVwN|Svr-aWKz87R^mHQHY8+oC_>=HzAE zQY)TtZ&q8@q`LBbh3N+dv`8@dWTp0>&HE4Ejz<<072W&w|Dy+Afe?h{z&|6Q4@%qJ zJ|}nY{p0@cHaLsm5AuB5ck7>u+?{?ejujiiKI_`C1kO;g-^bZ_J540nD!XI6WuHZH zqubHHR2eNc7pyj&Ty6MxYeI=;Fs)qaMkRy76~ur(*hd@)Nmk!IQ%kPEnQBzg{!`O* zMq_9c(A48aTHy(nxIpR>(Ex2CRN;xx!8qz9RLEJ3IW$Y94quQ+<97at?9wj8v%s%` znc0L{C?q#9lE3>vs=7vh^oKq$ye0Xjf(18tF+E1)p`;d5T3lMvw%MW_rd>^q9Fs4m zEB?Vji|!rD?G5LLZ1b}r^qNLvoa{P;z%|D$bPsTX{+Da6+2j6PiK^V8Li(g=y z6gXaZ|L_Wi=uqd5g^VZTkG@3&`B|!<(RsWL10pr(ib|?y4p&jpsZ&tE$3)37pwp+v+W=PKwrHMmG%t2;a zWN^r_X{6;ObXVs3YYb7Um?aD02}-rx)6eN=8}E!0yd3X2^Z|l2Nx53dfS(g@Y!V5H zVI`vEk?vU)icE>DraWEZQZ^FBrJ44^lmfES3~ud1*y$^I_FZLPJP~196RHz!!>RWf zB$mN{B{n_2v~!t!n5|+l9UmG(S|(F2^58GhqabtEtU+G%QCx>CoTcQ>R683kP~v_} zL$GQi1}9R?tXYQ@cThhQyq-`y@(O&!FLGr;Ulsqk=H+_pFI)!aseZg7X3y!huHU9z zsbAL|gN1MnUjZf@74@J>l_HV*sj6_R>d%^P{hk>upKmhYWq(45iTwW~@Aw}SyLGg~$iMSh zdflWSHWsvQ$~h&e@OoI>Ws_o|@q?tb8oIO|f+L?Rbk*NB}g?1rO# z7@Hmjjv@(3D4U1h_X$RIu-uVts$n0LQ|GObpaZMzm&}6~^65@~+3DUb4Lo7BNcu{A zU{l~!HUskNw#>S4%M?<~wJ3MYSk`Q@|Hq#owpv)*k`ANrzvB}Jkj5Wa0 zARA6)^qkJ0>b(VX6w;>gM-9=kiSnu%=_p$^oQgi6V6FRsNDb99SiEX`f8cM@2jMo& zYq6NsGnjvGx2dnzxMbH25|oldvh)8vZl|W}dHt8erdqpm*D26fCWXmW%B3RJo`S|VE3?0Iv_a1i6bLY0O*Cs&iI+@r1h~pwfw+t_G-s5y{d*^ z1&1FqlQ7EWv*dKw-*r4o|EmM6GZ8We5Ib-Z`;QQMTM7VMQE=__anOHyx`POM3nTsYveo`qt4M_ivk+|L_U zPk`w!dlSUFByZAE_|f^|=BvgVWjOK3rUc#yjs}VV`&0sv9AI(E3e$daN;Y;;O=^8? z#eKsRa(~!U2Cjbe{!`*JFcvU~25}cE{B99llvQH?g+stJ)3+cLjO*gx_a|??Xuf5-!y_-4?c+~q+ zeZr0vX-NRH0GBBmNfO#0oSuSVhR` zkatH$h%sbiV@;a;jey#D_L;zBI5rFV5n5Y*s$VG$XmK+&hZSKuu<45Hg3joW5eb=G z<1o!D^HC<`L@$@+#J#OZao)^o5w`2Iu=deLES1-;Gk8r9hP7WN-yKi0Hi%n$x)0hG zrgD?uGu7_ zV?QcSQeZ!8TW+%2TcY_&Ri3{y2@u^b6@^#22-7V=+QnsL4vuHGXlQAP#{{xg*Q?T@ zCMsPhnGw2^1EkV~E^S@(^UDT{sQ=^$QQx8(45$2F8kqa{*X&x-YWufz5?US3r$1tQ zw{m`6U&dE*yec}L?S>r%3ekgUr(N0kD5w2eI0`Tf5QgbDjnB7|n z{Tg4HQC~jC8l-6I*H7?C)r$bsf_baYV3stS48N|rk6SX|`g|(U!AR zKuXh{G)Xi(uP~i zUgOiK=`AWTsV$-vk>V4Qp&>4=Pdm!$V-Nwv<)w0fwU}Tr*M*^+CR98N@HT(bAetq> zUfKj4g9Pd{?yy1#YJAF-vYN~+!Z;|k$Cr~tO*pW8hQ=nfe}jmBV34j-R%)R*v&PhZ zsktxM_gB<+z7te6sjPd!l{T|c1E@TO&prQnX)~uy7iQM>@&+@=q%h#RwEudVQsQiU zf9i4N^}dV~A$fc1KY8dkV00fyIPz4tw6}(S`=s3?qxc-2zy%2;OX#)kGBW_8^|__! zRHvK-ECZGESXibd`Z3CH!}t@$2XZ3}EV?}L!1hL_!|wbl(XuBe)lrtC*24Q)`CAP-`3mR9TZ$r|{!&{Gs(+V%LF6BybvLJ8Ici;nQI3J8gZ%&yJbc z-1vuP=J0AlE;PlUaQOR3sy3fr`}7aXKIZd+@<=+^uDdt?{;wo4eR9fy8!tHoC(fxYkhx6H_PoGsjX}Bs z&YqA+#Sc^{K~?GgOB^){dVj-QTkkAff>c%eUMAXlC@^4rNf&(3{JMC5_ut(;3rFIn zEGs%A?lP;#dKEiYW>aDy?bS~A?+t$=%+qP@cRFj)H+1A99%}LMx{hznJsPj4P``&9^YhB+< zR@~sA)J7Ih0x5z#^-{Y;`$?MeDpf>_vt|e|nn2@d>PS_rQ^v00ea3C3?O^&6hbrQ; zu#_bZgdK6^&0TufwD6}6cX$_c7z^fL3^4-zakUS!_gpfyox27LVZw}NQ4)$ocJT9% z0htD?K#wA2=)8gBaPhB|s^(j_RIJ*RP=u%(0bnp31a{@D^F$UJKgd0B1w@+)j&zdf z$Y7NG%OGXF4|f~>3Lld1Xo)W{VDyEuF zIew5_%wXN77dtZbWZq)lqpeyB-$4TpIb_U1LeB}FuNp5nL(ZI>y0#zkb`~+=03KHN zfyj%$-)~n_8H{cRPxB>wNJo8W|K zavzbqr3b{2!IhvuhNY2&k;RhDaZuadd+#TKd@eAF_wMe9B1W`m>AD49+wE3`uC_Z* zH--K#qWdk^HZIwSj+pV~p-?|wUf-Np{LpWg-EdShX>~Ag-F|KRT6XCHyV@<{V@G6- zw`TAm;QR?^w}n^e@zYJS(d(;FG&aj~O5zlgSL=U|>eL6Hgj49$rN2kP@&``C-uUvh zQ;Nn!;PLVYiGdRwKn=^X>7VmzBwObxnuKYZU3B0Iav(@pag=@eguMZC5bA5nueqHG z?KvSUZWax5wYFJKu_{rbT}oXQ9XhW!T{1>FU=qP|!<&yZ+j1DDXKr3Ug{3N^Umkbn|J~r*$e3Hkxdol%!rep3c`=(j*{Jyb; z!esTFJ-7f`tyW*{G#Nl$*DMavswkwG&|QU+DJ@f+Qo7I=S8{k5u;U@Y2czi$C_`vX zIH^5WF}hgj1DR+BGhQRMGvp{;bV-Y({D_9^1AAG*u)%Jjvd#O73`w!{AIGRtc>cB{ z&txpMxVV{Qdw-Ac$i*A-%^Kp0maxmKGwX5jYL49_{*aVnOGuNlb^zex=%(@?EuV|W z5v2xxAiCfZN%_Jxv&Lq2OB0S{%jR+^OUvkB{{-xb*=z;OjY}AJ!Z6^26e25ReIg_CJCvnZM;lg`9P(``ohR<7man=R$Rrz|0Vs6SB?*F4ZqtFmo)w^)&7vhsJHqD3 zx`iP}@uf*md{PVYEE_u0q1I$MQZ2ff~V0-uLfD`uk+qrY-=Mk^UT2g`52>fhEb zTlmwB`RCWn$beAzDXzt6&t@%qyoB<0D_nynFkXvkPDs0qic6Gqj>s{xbBo^cF;(K` zeW6oix`A8b6;x(!ir%!zGJE{U*QIgHc+~vAF+H!sJ7&aBUxaQh1G8ljLzN{OBfz2> znlzuApP>^Bgh?Ja=Y68Vpuf;7A}V@eLs^mxe`zJ_7pb!fRH*D2D0Nyb*-l*clBl1q zK!(OG3xA<0eB$fu+!<-?5)YE+U1jT+N%;$Q{nD)r1M^bW+q5md%xnDK@!)2fPV%N< zNxyd$b+GddAr+nJUzjqnFM~Lc$FCVeGT3)t1CX0Ab7ma8)@zBjIL(M%eHGgUJYGE> zpLi57fl=q%@5o<^#dG*Y6l1!FR$wSm=}zuKTgdsc(549>eg_Hm^A+UDAv8%Dr4h3Z zvsNq!6YeE7t*BPEx?}JNa$C(?%-DT&HjN$*J6Vf!m9L0F&enhw3ivf`o02B87P4)^ zqI-Rfv)Ram{f@dpT=krLvM>w_l8X7Yg~^eH#hWfDK0EC^w74Zu`C!vToEl1<^jXIU zqr&9i0`zml8gdXZ5(V<)95to##*fw&VX1C#cV38j%z#d5@-)(bl|L@Gp zBf+#6#?=f3%YHq3A0~Bd7{bxS-&vw4)9YUlpaEN^%qj3&9j>?hNx+$(xAz36$t=KCM z|C$`tPMkA#80yXt7Ht>WS^K4wG~s=CpKwcQbj|-XI3hguJQS-~ucYzi3M*`iC2JU@ zatIv}g42Ult4V({23=pFYi1FQ4k115(5Ly=C%8#dc{xU(g**hyZiyx{w&k66`b4d55%tN~75(lc?AZF-e z-yvIGD;7dD33Q7+DNRUAaK%$kDZ8^g)shYKX@{{8KafF+KFD~|Q6-EOOsChFzg4ms zkKQxw&N_q_WZgs`qA7v(Pd|5y8c7^@vodO0+g+tn!1=G45Fdb~NtMN116(627sYBm zIdFBW`S}Xcwnkv#>KXySB+29?uv~2wUL27q3@Ht24Wp*hij9mx#)KC84F_p7IZDFt zljwI*Wj(p{Ivqxw&>qtTV&y|#ps^lp!WH|$Z zfMHWxc6Q$d`RZog1T-6T8I$r$+3}U}qR7(Mgt)2Sgy$HrZa$FXeX zA+EU{W|dOl3|CBuq-fRdtQshgW4+IYF(;U&+P|IR0D)VhzghFutv7$IhHXNQ!(O8A z1{Fs#j-@HMtER9u8eu#rLr(7PnE}|=M}rGZ;2G_=?iu+X4{j5H!PRsyY`<(hy6z3f zjZIz?D3X}GHfP_pP)Lz=yVK~>v10eB+u_#St)aePH%&vzySCR$@;l@*ZX@3?76W3*7%*pLZg$!Cyn(C*}6^8-az>TKPY1PXE{U07gcNf z9w-CVQhJyHAzfLl?DRRPx5S_`0CMA#F4}#VG?GAb6Z_)jczdUI-}lIKUg(JPH- z^zG|;2#7ZO;_|-#__JOflL}Tzj=u!B)kP{7Sj}bxe5VOFkV`VM72ALgsSTx*+>ovG z1?dI(mrHCxaR`SY)|u~4Uotf&`Hsij+D1Dsw{=2peB&Ad%ZWt=1( zNbZ!(!p9{+EmYHNIaLj|PI@r~aNSd2a{*cgN*QaRD12CQFtDV_oKdPH ziw7+qk8=HOyJbhavc-}sN98#9x)60ZxdL#Ar)ctu$x=mtatpThOnnt~_hTbI?=F33 zpl{FQKkQh)D306Tzhhd7ez-!510`9Mp38X-IcjBRFPeGu3%1{?5&BB(0Mgs1qMWZ)tpc=u8 zqh49FN9OJvuG_rtpk8(F4G~1VidhKi*E0lN1EkS90J-1Fx;t!8kODecGO z_Y)!S4V@XU>9V8%SCZ`UaG=SqDRq&!rZSFsgf1Okl$No za1i+o(y~*I!XVb(>A0E*?ZlD>POG&!I%Kh6w$}*L*)kcp`N)4=8`n=l3X7Aq%NwJTyy}Niv z<@HYnIsp0JqwWh5C{#t>A}?N1I|KtKj8aak){>piC9)yCy80Lu^{O9-8a)yS*8N4i|5r$=P)pjv zFz+xWQ-b?uY@*;c2rtnS^B<#%*p7^h4i-ZN`yrSbxa|tJEnK|;FE4rh&lniCi;COS ze!KyHu7k5XrnPi=D)HgH##2O4kaBH0{nX_)^^L#}B0`mn?BYL37<2Xtgd_4)AR6XU z8oD|6p`BR>(auRe#$TCv^QSGx?rYWn15KFHVEPO3*W$8qO9KYW*l+__$Cg366>#;~ z(Vg!PTUTK+X}FVWDT0toSUfwCj!aTgiZp;yC7xcxS;t~7RM2svVHZ^#DKMU-z|%Qg zC{{oK1akuN0L=}dk!-04i7O@)=>|jIBsAl}g`a7{q_|all5$^K%eG@J)VPX)%k@mo|-?XkKZ zkN9pQ=!XeTU81#}_2WP7)MoS5Xa=Q3kqv3W*w!DDh;mhSK&m-x3Ow^$jPStYd)H=7 zz~*$z#!RNEn#6d-M+SQDivsz3XP~Q_7u*KV_~SlT&LMGKQB(Tt4tj#%Gn7r!ZW*|M zTuIG;+ike6973K0rUJGXbykA^9Of(2g3(pn_AAJ{&ceF?KR=sb=>HojDa%G%mq#u% z{y3O|9x|sCGMlh@1eXotHay)O+k7My(u=%Vh}HNu%dBmW_8-&;%z`-;Kut9%Dhv7> zoszx*8FnD?RLDx+j({_Hk~C2m=a)OI7ewNHZ?^qmGbLx1tgF}C=~zpwkjT~~iR`luZhb!rjw zfARf2w%Y2W4!k#8v6Vsl38*jy=4@YX7R+EbI{jjNRGlyVWiGE^QtXtHzKAAIRF3C* z)`Rd`^{oYekV^iMQZ?qdUBz%N*`YA_58tSWYeuO(Y1-3w1dLqqin^r4k3aqM6{?tW z8%|+eLajQdf--E%G&GL00D_~SBz$#?8kAk}&W9+~$fR<#Y1GCD2VnBYl#NT0 zjFj+_`Q&MZi?-+^=wh@S%6bhz#}3jde+r1agr2}vn=_ANHkrBPWR!-i+njccvt%tu z0@DIQtzm^ya;f<-#RL5c-0Fpz%Jl&{!?MwZM@X2eATu6r6WM1`hb zh4P0;FyD$V(C9xW4Yo z#fr-ZN(eF*f1gh1UpFs(iQkQ0*`H2aVm(VPHwS~e3q24Y--$l1UV7q%uZW&Tw(r}X zt}Z_udm`gJTW2+!VuaV+?o{kDI-j3Xlvo7?4<6_N!T<^{kHFfYqa(6#j?5pJzA=RZ z2Q$9p$=+Tm$?RU**uxRwcbE5B;f^zaXl1klJkak~b%2ym-$MLx#q78jvoc=oCiutr zYuzvC>~)3mRg1w^UTat#?w}J_IiIGuvLFMc4s1v}fU;)NxWqG%j8G9lf@h4Me!8UcyrrDgD`sx?Pv}+5eH?oT@;hk4gDT6d9 zRiJCeHR>6H4S3c%Mv8w{>U}@uB}Cy z49H)p7Q@c2pXfxm3yowFR^4Um?1m#ErV>>bv2+yE%X0I!fUz>05Z?U7qm9=(fGqeS zn~rN$Yh{I}Hv2Ueeq9_GtNFeGPF~Wqh?c_B=mS$=Z|u_nXM5?CeJgA3Xt}1ktc*b# zmd~*95fZCpHd`-`6_+3=C;Q#G&)ZeHbN=&A(Rum&9IKHSU3HU)7NwPy)xJ-^@r;?j zyY!50r>@GWZhF&w@@>jXX2;>tQKVA@A>TleH ztsc)rAK3GCxILOK8ValI2A-}mM~Hewn-sm@!@zmr3y=6(?cW+IrB@jD+G7MT^~yhr zptEnEbN`bY{wtDw6>9&7lHs(gnBF+YASk5C9>&VxhLVyU@y5%DX@_^&4lS_1dG;i| zC^k7ITyZ}{?3~>FIcyrXhGo)eol%aro)SKE?2sJONto~g0z9 zOg*?pD_;5ryM^{?uB|(b-wM$&pCQUmaEy;!rhH*FHr=XEJ75PKkfmkVGosgXcP{Wg zNZxfHlmEAo{_};=M7u|zjFo%d^|jhWI%UjIGEe-mrxXbQ=CyK1Bl#wpZ^dA###e{4 zB$fn5f)Rfu8MX*Y2i#PDVTA^E@M^&#p{a06Y&rSui4P(0Yqyp7#=D5WU0KVxpu0tv zfuu}L^HF>gfXo{my;t&?+ta8nOR1tZL+!>qp7Fmuir?4R!AqZ*kBqN?y(b_s-(C(G3`+*ayc2frd)tBt)b%@;5lsD-iP`b5Ss_CAw;pvYMqn6J9MSb z|M)kST!+KJG?fV1(TxHd0fKUgSo5`}Hwd>jU=!>GHD$9By7TY}ND%M{_x3GNN@b8x zlw6aVY>4U&*s@aQF=xg`{Om9|Ic#SJ_AGlN;K*#@Pt5_;p`!p0*8?!g<&`eyPg>ib z%7}M98{KC-cRMxH6#cnP?Vz)6gSB=`+kP{8S9|aOcua6@;5K4eQq~Y2*?y_6c*+r8 z7U;!M47@_UR+uKbQE16|&;_N3s3#K=2x8^h6u*_jGH5_`kBFlaH15fa}ufwpU>*|2HeSh{N{$Gm2MEEKf`VF z`ou+V|7-)OZBxun&SD1>Fjsvh?o_Zbi$!9k6Z3^IIby~0ke;JF=BwEL>c*Gn#+Sp+ zCm{74Fpqp;Viz<>9<2*k#G>0|hzrO+l(rt3lZXDJdRt>d#fM@1a_SspGK`O4N-n}V zA|uh3HFFKwbjIfySm8ejZ{vZJIonT`Jv%vDL+5^0uX7{$6`TQ~zZa=_br@vEbGM8| z0EeHjo!Thvreay?ygF44G(b>lVnFMkBUV5gbE8UZ+6PKg&Hu7#r1WB(J?&#dSI-Em zlV_cg=A2^HF(|ReS9y=mQa!Phv7n_0c4^Az2{52ZpG_4>1eai%tP^EvPhgZF_}$CTVa~jLo&VG zz0&|Fd5+!x75dxSRmMp<#nZRCB=4z|(>AAcGJvURs(8Cx<47*r-<`~q#X1(guR`O3 zy#Pe=0KHbEoTV9FS8)8FeY^LH=eMq3V~>cu8I}>xg$Xl zWNF%hj%+?-Qc$r-@!HqgRE9$^R8Z->-u12Uzm%&E0z$57;FOij+l1V0Twad%L^E4n zieUy%mAux-p9nx`%7X+u zqqPEdoNl%Xo^^ZPdY^3nqHq1{>_zFh3_LK}bP!UN=H5LV@wrS88rptYi6wqM`WS4+ z`QPzK2%vs73iO{!_+~$x@b>fpdn??P^|6lH)xUGinjm})Mf_Bwbh|Cz8xihd-pI2oK^xPJ-|+04DKZ2yTZ|8sUT zAN>cy^A0Ni_Q`OrA#V6SWe+mFWp&X*+b;XK?1{s70od?92jpWb*OkzofvM02wQsbL zMbc9jEWICOupx<~4RPv_$Isf#yHmw|-e1v#;Nn_v%ml91yz7|e)N&1So2J-)7zSd| zW837rH=2fR$gSH*9xHvFhDtti8>~by8p@BcYdD3KJb7 z@3NMz`*u@nx^jsYPL$^vL1y3@;M+eU{11KWW1P55uuJjd$wl!HzW)&~HeC9^Y~sh1 z+kiQ~-G+20!|_kOeIGHr@VkHFu!Ch}3Ya*zUqTEE6g%Y>e|G(1HqSK5{r&@J{rYxG z?8MU!uyn@WUI4)$bfAQM`Sz2>T3d$mjjdf3IbcneDJD1RTin!{btK-bh)$lPD6#cq$=A-_eQ*WJK)>DZx#Dc=>rv+O_8#y^fK?CC<4tb?Hie)0JM)%%uW5f9`26 z-p&$EJVmY1&-S88wdfvzSh(dZv2bCU2$;rJj|D@~kWf(?^CKh^naWq#%DC~8mT^jp zt8JHJp!0r78Z5had{ZW^p&(^;lS&bf?H)Q0M0M(R`AiDslWp8mzIo0$hrY=2_M)Cw z_=mlJW;-VB?aTY~#}np%?Etg?Kw5d%{TT7i^jn?qDD%hk$9LS<@6Y~{NL|nCy&>C= zk@R1WfC1jKYC!OMn++BAMVsl*owYdX%9fpr$s8aeEBpAM95puKb-^fP`&x0!ck!E6 zMDIuM4(iR`YiB|C!NnJxM_rhnGlJf5ajuTZg2RGu;DlR??YG{W0t1g>rXK_{owrL7fm4Ea+BJIU0HVpf3%jD1?Iv-A3Bf z;h=N!$XhY}l3Ts@m{5IdT}9ad%cgon816>fZOd$ zOVd|qrmk1A)9oj&fNZC$U7s+@Y^(sixqb}Wp%d$lh4vUu*bF`|mv3n2wn`SWNdd=q zhBl8BI1GwUPS3pVubt#6^$IVw*eymI zd`;|4T(Kt%JYP69>Ap|n4aE6#A+!VPQD|}xe-U4@Ca09^2_#Bf#zO~4Ujx3< zGNiJxoM8KBkABtTN>l`8Wfkn^e|==h(ED33Jf%`4UiM3b;*6S5j*PRwfL5;#?bA}M8BwGr-NX-X_Q(;fjD9rJQa5mqt-P@42nFdm8Zq68;7K<-*(~8)MT+8Wc@a% zU7r*W0TV8~LB2D>!^I>hOe|hoK$Zl}wbala!i|)&{S1kSA^Do;z&6CRUA{_NLWinF z7rjb;&cFa}Qm#ecg0!GSo54gE=3Y0+nn9joGma>ptXs4*qrHd*_r_Wq4l79;QXGx} z0%N?0{k%)K$_DFJ#~otFIW@d&?d>AZGdx_yj5Nc-({k*>dT;Ui2tUdlSL|_C8AF^G z-EnpTlnO^V%c+NA?dhAW?}!sPqtsCmq0FFIrTTmCkAP3dGF=WYT$BWjBuSoJKnRWKBn^Lc)h3vfILe*7{HhQN%e9%N!gX`*jfRvJ zNv}|lFiN#%5gum1Tfne$Pnk;w_*@Z7V(5D4Q~ZZQC?Q!0p8ad zOLwcvMuu2dk)b{Jm*X38f33%046;^_c(+Uu(?n3{?|;R*O<_(%d0FWanrN*vP)82A zxIfJr^Q+Y5lMced5#yY(e+;&*izoG8(7-CCSezd?8$z6zo&*e|k_U2rd;HWV1 z1$vE>7JQfWKreM_S6c^7QQFQTws z);*NdjJHe0`PRucHi&eqkQ1U{AVrA!HZ)jsoZz+4U9a##@jdIun-+<%5Rzoel5#Sa zLm${?=~jK$sVVkxC%dK~>Ls4X0C2;94yw{`D0W$ajEC|vQWf)Nx1(Z3hP2}9uEJvu zI>d|3Irhr^?FHv> zzihOj#7!JeH^&Cs-8S5u{@8?6WeVJHKY_j{obP7{c^Z@LKe4(hkj`n}#6o$q}-9dYL>1;%VYuUS3E7(KHLW#P^)z_=@nu*7O6cm!!T zW}mkW&f2Sj9RqS=7Gs6q_k<4(E`2jz_zhE>&BM-=_lmc6Cy$bw*0M7ZaI~ViN^lzf zKsfM~DIBL*N_H;I`l5(n2H*5^00oOoD94hAHD89;Z2-!@P*r(d}_-*$T(h?#5K&BTZ(JgwSu{M<& zJMZBwRn)!SHI(VmJ4s;!Qtls(ngMpz6fB%Gx(8_*v2I=QBSVZR4jzp;F}TCS@;)}1 zvW}!|dyP|q@*p<+{X_7zH%Y!M*>z!Pyh#>K^VHeCWUOzPH$(iz?e5~6w_pzrLDuA? zDZYkkl}Bbe`8TK|Rb^V7MtQ^mmTPEn>A+6|O*%7&k9DPQA022DQ2psS~W%PhD*1M#BaJEIo$0R2&?Y9Q zP1NPwy~+}OKUu7WN!_k~;n*a>Q8LTqgS_$;l*etd?{Huzs*ebJg&b8!pcR-nXu=yK z!Io3yW<2G~>B@C& z_9%E>zt?}@2H1#qLT)nsRq^H=eZD54BsoMa_H!RQh~DgI39)EMtn*W&lN?|<*6mGF ztr~o4$NhDC;n(MzG;j0))AiEJCUAv#UP*`WyX`43V0YX3EHEI&C~z+)o0r+aZpIaA zdjeMJ9s9%AOpjB;-ThSt-?Wva(f~0@BW`2R~9s62?5mhDGzJxcAPTLXVS70vDNc|0&*oDuz8;MJ8BQQ#$3 zP&UjoIegVI6|~ANzrz7CTz67tB+jeGZPv{#ZUqM6&3bX=4a?qb}{WY z4hbkV)Rd!({-5~!mf+d6zwzsre>Lg@upc-4P}d!|$A<4upMRsihsEWzeLpmDzsvD1 zg)PvcCW=vZQlBZ?MC~%9Pf~o684ULSc)ldn2yqvPJVckDwBYqJNgwQ}3spV6f(iDl zQ5-K1$WhU&g2-gp2mfw>gYL%~(-43Vp0!3|IF_ExoS0H1FC)oPEKydk(U1)zYmtR7 zF(fa@BgeW*QLGjl36iSo|A$NvMdds5X5zkS_xP@<%(SoELbo}} z6q-mwDGD#3s$7r7Vka3|y>smiCuNE^25Hh#yv`%Gu6m*_2Q7dfTB0&mh5^(vtIswk zaeO=0sp?wU$~5MuM%g%Gzr_L|6y~p?gE`JLC9SQ!OAWpWv9rr?@rR7iAM0jNVZ;P4 zuplkc5zUvCs?@2_W7Fas!iRRb*BK>@5DYfi`|=A5E0~zTD9`~%HOU)a&bKiXYTne* z7h}G1ZgD>D>WKv+)jYrvUx8hQqQhF7NS=d2`OoCvTkl91afS&ic#s&0eZ>z$rexU) z)+Fr}2P%lAw~3D_yY~xG#r#&duoBM?-wH_isEnt7TJLB94=P*#QXamUWFvD_6&>rI z24D)m;RJ-CPxZ>zsAaesLSiG#tCn``a(t>$Ax@>c|z-mGfv$(8{I=lE{azhCM0g)EEgNl}Mg6(at7Y)_g{w%)n{2}g0 zC{Eh-bKu9B&Xj@%i#b}Ah!)OVQzw{)wt<~Pkfw@%X$z7Ae-5Mpqtb&Hb;lR$n&I;?Sv^E(FiHW5ItHomy&OJPD$lnpa++K@U6cXG z?%Q+?7a;Ave>2 zC3X^N>3Fb#FJ-qlZ~j!9Jx zIPKF@e^dU>znX*Hpg#AchpI7UP^Lxh&UQ13dgMODnZ5-Gc|RGvP8Ka+&r&nPWfPqUG)ZV59t}* z*St>p#E8&DLeU}41I-uYZm4fHl zZX8bE7Jce@oUK3M?LQr*0r;IG;_#qu5KnO`&s>{n$&}XZ)xvLs5UsC`9)2+4BRpQC zVDNDG7d$-Urxh6-{vt3QLHNW&ok+p2_m=jDTuu6o>RV32KWFyv#cSwDos?y|glT=Y z$L6wYjK_RKYdNV#pxrNdci9R_2y|tHDa`qlXV~tP#rB(BC<%_L44U2-MpRi71d$?W zp<(f2S_lR!zM(jL=`#+|s@ARE++372VInpV_-x@gu_;HgrgR};rb(`4Fh}y!hnZQ7 zs?~V8|6ZI*>c8AcY{`KLyl>qfrGEOgZHEK4mlu7ye`c@$Hsr>KJq7fDf`T zaxPb7SQ?YU=W-PpG{+@Bb^0lkX_6OAVqX12PcK%fM^loxetDxA_mrh;!N6sbCrOq0 zL)_og2foL+g1tT>vQ0x^$7L=|l_bIHKfT3_3y&Nm4<$Fjk3$#=RkhQXRroQo$tZgyr)boKL4~;y=s0=ewO}HpBP8 z4-eWVF084Ea29~?$Ox}uVH`iMa|D4)f2h&mTs=X(D}SQpoRA86-4JkVPJu(}@avGK zn1kCH;y7|(Sbe}Qr1^- ztd5KGM^OnQPAZa0Rr{!rVlKG-*v3CVlp(9o_?nYfzxVhIY2@?3 zY|ppRE;!+vC&J>aQ`rFiI^w;%cjec+FqE(5(Fk6o6}nmcNSS_}H@cD|aH!G~R;FK3 zIrk<*5gBMtpd_g)*s0h;{&;H4J9~~3HW?$Ok)J0cjA~T;;0k=DzN&fqh)34Vv2?np zh8+z5=BqnfB)QTH!$Fs zr$=j}0Nr92O}#v@^^t^(fOzMYz1sQR{n6OO1!f-i-V)C?yAzP!2#E#7{JuynUjIf~ z2eqbr5f~ng`b>D_0K+lu8jkeh`S`x_V-$5A@!{@xzU$n<$xX1nCA>W4_|+=~26s|_ z!cwRVv#PNq1xM^pdWa1vAwnzTuA>PqF~?p$&(}aKNQ31{Y;YD4F?nfDtsG@zHFT+L za^%C+8}3w6y@tKYmDK1De@}_ru%A_iLE(znv(0z4$7@JA!jUw5Z<-o&?883s6 z{L)Aw5!WvkpP#SL<-cPgTgDb7@~KLO%CaL3SkFMA7e*LloT$wgcITVx z(O?vf({!6E2i-Bh`Scoa5)Pjo&%xk&>-O|&SbWV>Zd0J2k~}8{(X2w9r#R2TC~tul z4TY{+kxDO8B3fMmJC9MP)ksBNh!hhRyqT^V#eJPWuhvy@%*W^Rt2pb(`i=0?$1}NV zG~@c;Yv$qfP5z}~NodM?Ekj4(L9g>`20sA>&)KKK+Jb|i56GJJ< zW})kC?|Zuw>;8nOp&FE_Ywph&lQz!vr3&mE_{dAW7jFVj3rrl(kgBgxI8>@@s#cR1 z5(q22i3d)wXFgqr1?{mXZQ=Z@x8mfz2ZEFWqXqIK8-qUmv*_YZSk4Ox4U#i zx_<)+T@7bbi%qmkJN+UDP37g~XFA_n{10dRwDf1rfJ0KVSpDzJO4u*O;8Lj3>l2>9 z)RD#Ab0wb;T-LYFV~fdM#e>6_nv zg~f@cjFrM}PL@ZWD!AidG?!7 zbQxQkEOJqy3cU%}3B{fa1%8-nl4^_C00%tO=TJyPq!LB8O>v5RdtUeQro@hLotosF z0&;w%!k1t?%iEWxl1|8&=PX*Wo=-)}P~*0Cg|^vJMTz1jGc5StkPyK;EaeuYW#LqU zc*rTHq|+N4NQ<^fg-Qc8cD3uyIR@G#P~kSG#A{P_w{7OsM$*vP3zg{zM{~u7_3WIy zVHTOC^ESy<6mxqej;$wSXYDdkOq{j{WbA65cRy=7W4y^k>vVr#-j>)9+1?|l;Zo6H zyHcpis0yAYc1$xFi;*#OT3B_f6n9o2)-y|Q7M)jd)0l(dV7^K0vC6A`7tg?z^CVRf z_yUqaeKv)l6qQ9?w9N|(Bdjt<2n{bfI|XsQ;7dn`33U8GM~YxgT}*dWt-C%^kzWsCtaGV;!s7XxwYhp~03GWld$O z2S}k%=~XM9BL-N}l9uHaSAGJDp@!}oBRoU$3Mw3YXCd0b%tiM%iFI-k!YdS_=RJ*7SH<6ZBj@50YGazgd)`N##P9-}3P zrvv1098u&FrYc)`O?tE)eExJFz4^lCd}trzn$P10^ZoZy6xG5iy8;NuIP=}$?F`Q) zo|~=D`2z=sSFZ#%ZH4oXh+8ba3FyBc{6v}$wCCTe7PS0y*30W6a>qowY|Fnf@O5i{ zaFxBmjG+52+JT=B?4WjnbXInWFjrp!8@4vr8> z$~PX>0&k-wLQ@f}FqqD$H#n~(Jc+ue{omxnpwqJo-1Cx`eimgr3yvRHxL&|j94t9EL8Uy4sHZ%ueWT3Tg1767O8W?q%t)WMvI2*hJq(2c zlb)+&F1o*w->Rv-jt@#Q9U}X-zCr~J`c_-6e|AEsv{N&EZ-R9V*m#a;C^f3y4ZpjkOirI$9 z3QUU5Iq8Ce4rpXhO0y1SolKNP=7hqe^2B6HY=pE|g~+36CeEU3nlXvAknr?EmhR=&h7&DGmK0S>jQgm^6IB6~ zAU#EkE^__ye8+a^{8tcdm~uu%*~(_R{X-w5{5(mTyb7I0<#M&PYDtZs;DPJt@eL(< z`uVG#b{(8QJAzF%&K#!kdTXb*%`S8`q9>CxJ-S4cWsVP6OkEE}LFX$|i8bg^!zv^= zUOrp$hxPnn15LsDg9LQAjVT`0=~7*1(L=p%UA0&5%VxE1o#FNK^B?kr%J~YV8m*04 zARlc18C>ARoAtOID4ZpKco^a3=he*Iypm))fB2%kHchCJaF3eu#TUT4PkC+oiR9va zG5+I7u=hBl|sZ&uSYYi*&hKTuHn`~D=glCOD5 z#3JeYq2!&~%s))ay;imHDzpW^C?G=Cuwwxx^dogVa!;4uD){1)tpTE!b&Z=#a07+WY1uh?K81%BwgKjtB0WdvnkT#G2$q%U_;dD zH0a6@X1)8%e|=R@U#z_oBVl~mso{Sv8tR8+j_>{ciOaq#&YLZ6X=M7z_)3!@e3{xIXB112^U z$|R9bYl1sXrTiFzZ;Vbp4}l~i1H9x0biLIX#$f+XvaR0=P$dRKbf5PRE_4@ z`T6&`Z|`o>;}T9My72rUEgqB>jJ()i)?dZ-cjY~&>W?YfTzhkbb5PpUIP)GXp;p@4 zY&rMBb%lDjnFG$31L6QnaC2(&f9H!Pq6Me^S4q~W`F~`lK1L5V2h`bkAHi#ufNS(ms7a-m8XKg8 zlO!D}%^~~4T%{6`4jHpXWq=xL(Kf`@VCNb{%lT?vLu5<#edgPdA#wpqfX!cAjjjcB z%@Ex>+crjb$maA!V;v40%d2b)!+Xp}Q##QW%d49OhVAzeuuktW(?ypXKaqm*&Oj}J zJ7tQs>|EvIm2_NIJHx7KT1-1%(Vb;DFZC$&i=wN6ms)k(Efhr|6k2RFuQd6rn)?8|y5_JU~sgk5zni?Wi)izx7P-7_7 zP$X!G2!fcWNDUD~e8>I1-}igp{F9t>viDx+?6uc^)_T@Hd+NeTD}et`Pv+@16V0>y znQ?By;l)OFaND9#mCQdE-@o|iq-^&NBlq^^u>Cv&hYgqaseB-(t7)PlC42I=JU|;r&VD-1+%r(&B~4M}4DBg7e4vRm!I0 zbLMi()FRL8Jaek+UMKPR!;fPl)BMgME?h`>WIokcZ`Ne@;SDDLK_xZiqTOP7I>N(I z9tcs(9A`&|QzV2twfg*?nY9J8<1~NT7VN%gO$vo7p0M z^iFB^)LL|Fs!A347iJU-w-)i8;jJr8g18queuuVZ2act=g!#((xN)xLCRoIYgaMm5g$@p z!^X0-DR$c01qk~6BFVtvM$w){ugN7AbKdGA*2du{PDb{w`RAC~6-MC8DO35E?wzFU znjK0eQqC!&wePs-t(w94MQhHy00WZS>HU2Vm}@dCDUo1M^i*oVcEs0@XXcz~+hPFa zxAVBmd8`$C=d%`Mfpq(`WwtmiX8a`gUV~G+3RH0NP~vvUCb?}r%s$Huq*;7?J@k2_v6+2}f8jWZH-WB@+Yc2MF5kXEZb*6`f` z*kxde&Q#p0fWB^lN1ZY^Hy@aro9l^Ro?D(ycH2Ey?F8hCzI5Bl`x0@#ELLDUvkG*i zP&6a3a;BAS?pq3?D73~sg5B*D6ZJK8<2j@LiP-$akx-tem~>YRAk;S`$rHbta+3dAPY%g{Nck&K;8z(o(B}kP`~;8M;fePcm@JaixV39k2;nZpTVFYC zrjSgbXmfqDDVl{`bGndz{nz39{>wz-bV(^>+jyq#Zst02E0`*QB% z^^jshO0dHQ7{8Jt;;7+pel(P%T-&o;tr2 z`6XNY!uJcd;Og4g<=aQaj$dDLHyKS|KzrxeI!oeY#`Pv2sE9-p%&0NT1RD}`9 zmb}pV@;v}iwYB6a&itX%^|N;?NdtoOexuU1TK;!Rc*=xy;#`6ClJro4AV$iECUK^= z{!)XUWzO`ET4<9eRghF(DPkGQ3td`%H8Z@kjYR%#*|cDVMW2Rd$cZJ(zIb2C*lq@W zU4SjS!(cAzYhl0|uf$^sL0FWV;X38sM;}?uE|lS3ZyG}3`jyO?CJ@`D2=tc$Rf>iP zKAvb2Kq`8{1yB*ICO18Xd4&9S2NPvlXE*v(Zu6US@l`%O{d!}Oyw-<|N4yM|o<0V~ zprdL1+P zJ%P0SXOO)U{}{1>Rl#u3)^?XsjveAmcH>r)%*of`1y+D$Z5WO)+m5^7N;pMZa?QWEclE@KYs@Q5uq=o#-di&Bttrs#1wahq|x-j|8 zdiQYs#Y{9TlX5~tkGX?6>>-XB>Z52Jdw25_dz`UrU^kRnnc2A}#crl0k{6c)Pm#i( zOm-@du~Lb)SKgk?I^wfB7ZQK+$zR3(#2dey`&LXVlAmL?g>M<7T#pW)4wGiOXS{qcIuO_uNG`B?#i$4`7t)e?rLY>nMq?Gtq0b^ zg<`jb-VA|nQtBS@8tzIGHgxLV8rR_JOzX1~1>@^P%ex4c%sQdwuhUN?%(%P2%;+Zh zKT;PadS^LbGDgzSnKP?-G>0i~D6l^*HrN0*g)BS$I8umft7B(Vgg-$gg%@7G*Rb}u zN&ZMuiHt$`lp@sj%`-OTk->(|{y7D(!g4^#-CKbRO=udY72~dTnGcY}fc=d-Inel0 z+PsXxHoLS+ioP^*8WaBG>PzqYLZF!Sq_>qin!4?uWnfXd{YjHcLlVY^LGH7t=fym* ze9lg9p2OreokB@HV*X};ptS+sSxW7wW>opN#9=w1c3&s(MQfCRajH_B9TFWQ+ zO^__tAQf)@;ZwM=BA#Qc)Oiqn3*iB#f*7F<#Z5vB;~4H!`}~-=1h5uvkIRZ25&vSF35a%NZo)gzdc9LGq=z zGk8YgtMDQm4!2luq+CE4eJ~rqou8i%_%*-unBPT;xm22IL`m9K)?mnI!097z!d716 z%kT^bwYXVzd~;ae*6nN!H-HmhH|ju&>CM4?Tkvx8(f|X@Hp#a{l{1k1quGBibC<>#zV*-nAr%}?*+PB#=;rUJxPNoI8%3+9$&%|SjZ)*<4R+^r17kxl{QT6 z_Ev+OG(EO(F^irrO>Zh(TxGb#?xH6)w|ZnUaNfJ~zdlnMDK!#8hP$DQYmyr@x7|tc zXbyX}ZlAML%8(ciCP%K-h+MMzLWIp+yPVxqh{G9dEL9QO`pR*;{Lb8qN;Z&`DC?{uM5G8|yG4IMa@T$nbLdpi z6>Z{-uf$HveYfXK*^Ex_yEAEv^^;Pl292J8;8^H z>UdIYIPd43D{ODi-Q2r6o7q1D<= zleM`Yrvq$fg9q5dEd;b~^bVD_qWt27xbi(wkxF4%l9HdJnzlAJyiSVxm0D$_jJgBb z-@-?)_nEgN_cRT|?k-b21N=$|8mJ;kFE6hJ?C0FcHV|hO*|_=H8gtLNCQw!e*+8Qs zwQ<`6rI!=N5P;A6Ol^V6AXgSCR%~kpQNUyifWfS8>5j3 zM2Ukn^=0yO>wi|R{I58P7U)vxT2kG?QNxq)=+iPm=i z=fIiJ@}CoSvjKbuwE(U09$fOw_%G>!OLnu$_q1Jr$@~BAcew0R3>t|M=+p(q?k}i+@Sy0HS#c z0_2^5k>$@OHV>Y144USzwK-D={rW3mLNY|^b8(KNKDj*ZIv~g{QASh&Ny&l z2*(s`DEi)kh^u*}e`U{@(>C-`GO+R@qOk3`1TQa`pJllD+7J|64Bux~G7JSBev#Oi zeKzKrhQ{D_RJD^mpty=%kFvE2$Eb$gEw4P8J%fsZIcI$3uXU6>&oA2K8)}FFN$_eL z)DJmGfx63L8Bp-QF|s-tUu~0w*oGML((Rb-_4ymkwg(;S@LH#Noi#rBV`x;rfmh;; zZH`uNLr3SlE|_5R@EwOGxQr z;tr*?e4BG#d;Go$kKc!MIy)?lp*-9}Xu?Lvyys`vXBevD*qGJ-`>;gm?HxTO`oRrZDx`>z1mdDP`I(trLLB7pWK-*IztuH z#>c{J;5zumZ9UX}U|psLM`t-ECb+2MM`^hE-?ZHxn#(#@qi29ex}9ch%u3xXsXbZT zzQE2lBz}iFkR)=6RIJ7L{WVNI-N+~5M`^$VIc|AgGpG1#2I;nMY&Si0eyF@ROJAdO zJmC_9I}_e@A@mJCg4JgA08>x7Q%7Ly?BgP7lkskGy8%RYe{=bM>_C9iQ)(=0^mFdx z$zuiSlN4W!JtYv@P8b*s9@+dZV*O=jrNLUE;PKW(;y{~_;Zht!vvUPHj4ld6YfOh{ zM?xg)q$I2KbcbuA$Q3>WHrT}9#g(XsV*Pu6+siu()y$&ku7{O{rKQ&TJ4=LKsgY@7^rOfJZ9a?DTmY=Feg*9Al6BC_KM#yn7Ktr~)ccV0>Qm_b>6sx{ zUGr7*nU5ttas%)xqkKG{Y$fvI;>dyD&L0tYN^?0UgtmfswG=*6m*U&iQ^hoV7V8Gr zh*OsX?D!=NER7EYdvg$vR#zJ0Snsb}!=@G8@|v4L0F(i|^5Z88Fb{^`NuBlw)-@lJ zD~w*-NRlfojVKc)j7ux&0v*XMwcy-(hCkPl^A1qlG>^G{m#kuHXD^Z2*VNU}UEHIG z1~L@%@k5~r%gC$c$iJl|31tkXqCV)Y>a3!B>NSRq{_Ux7Z3r+hMWg<1Ty$kju1>V2 zz~Oa(p+5o`dT&3!SD{+nK<9tu3K~Q{zqUUK*Bw$1nmV<;T@v*CEf4-w7e7SjO{^#5 zkbfBv9T$?ajg`K;|6xrjAh+vr&4{JszT6P2s5k^LBA>0$;qhCVhe6xDiH}(gw4PhA zxG}K#+Ae#on@Eh9{C>fx$zZb?g0fU;%#fj6lfaw%2>NOQ7E15ce2fUOeHj=7&F~ zd51ctw=ypwRr!0HdHUk#>v+Yrs|}a*N;m#h+=mpFi}LK4g{H*Q>+Z`sS=NSoRSxr~ zNpnVdyhyb7WXoYl^d!4Kq#9+9wU)9+Ka+2wmc&*n`=)rkl{jnI_sLm|_(0kv_p?IH z@^xul-ET*H-SJ}x&F~nveWtCe=E|bFux^}bx0y`eT#s1-TKQ!? z@9H<9IGd3eM$z+$K{TOgg;5lbjuf?>=V_$niz#G#{HA zZDL%8Mj1<2YcD9?Er_@iI5i+AjO;UP)QYe05}tgT$ImY_^SVdt?KR@Go^$XgxSPr5 z9=@{^2H?XaJYDg(#D$RQ&U;mrl$h&!2I(GvdAGwR^*wJTq)H4?tq{1Shk+-CYNjqY z;g?QI%jgdoB@KBA3bc%u2pVl!;I()I`@*u;DlWVc!?65^>e1bqUci_Mbrj?PkTQW! z!o{DK768duoYa|_(#ceI@r{80l?9dUo<0zIw6Yz#AY<54?f5BRxWgwt>VBmoO6;)G zyp~&@ydP!Fg-|*DaCl4IljeG9O>8nl9uj|GF;Ten0@2G+z3F~)BRbwPIvURPPj6HR z)m-`Rsh!yMLqNdAh!;zT$#J95QOqzgV$lW*b@P#nt(|vg*!|(JRZIBlk^p8-$(6+N zE83~|-MhTON|d8f&QvNe8#slVuRxQRR_vF1!vp&ZYIcS-<_e*tR9UCDDN@}2Qw=*76%a8$aGJvY(#OcZGi_Peu;guPBeu zzMNpO#sTdRFY3D3d4J)1$+uvzsrf)|SN)}-yMI2MJ526`@l0^cTx*;80PtC>F>l_c zDApI*_f!yFby1m72S7Fe@3{atvVL4A>);0f8G$pw$3He4`Hw?h&i>&;WBhFv0k#r| QL%`?H8&;+z#_rGl2h0$VM*si- literal 0 HcmV?d00001 diff --git a/mod/maxgui.mod/proxygadgets.mod/doc/scroll_position.png b/mod/maxgui.mod/proxygadgets.mod/doc/scroll_position.png new file mode 100644 index 0000000000000000000000000000000000000000..2efdaba013d1859cce714f1509795731708333f9 GIT binary patch literal 143877 zcmZ^~byOTd(=WWZ1$Xx#NpRQT!GgO(2qd^J?(Pl=?iSqLA%OsaB)Bhbi`&{I&-32* z+&{kWoaxiEH9Ira)m7D1)xU|=e6NIyO@$2r0C1Jx$!h}uNS~gYEGGIhg`ePc&vS?6 z`p(D$0Kg&s*N^~T^C$oSY>iKHa+;d&o zei4Vggt5z5k`!JV6E_Lj_Ahl<=)K>chPN$B9elgaZ<)my#C(zUj$cbK65t_7LgE$EAVxm`$>%o?CSXuKcaVoB8i9W-`^6L~ zBm!yBGgU+tGlT^2)-Or60`OK5DI`DVr4FD76<|4KV+{gmz5!UW1@Hd`gycVb@kauf zWH6E<6{P|gh;3u!0ruj6Z?pPw3IIbM0Le$yQBlCs8vu{8!N+%i#ty*X3;|9v0P_Wa zM=K_h1Ayueu>8)<>;s7S0w7VmGLX1@RZnoh`7Eg~%@SQKq6(oVm~Y%L3=FvF*k_c< zUy%q|AzOWY%Qfu#g_18+0DtTHCjd~CO8Pw7YnaarUj59BP*OXd#hc>+bOe*NH3+^p zTkHB30NC~nnuEXQZlMYhM-Op=m$06r+MDAPdELif4kMc!xGA87OI5$ur>ViMy;G?HVrGndTl>h z3EF{!fYSbE8dbLLGUOxyX%V?4$$w3_<|}84l}+OqW1UBQ*x7syL6O=N1T=n@Lh?_2 zQ)Om@a;M5hVCXrxa}NMq^|%cEVaG%Xu@B##1tP%GFr^|^K*&esG&caiT%LtXcd|u# z0uum`FAC*sl%c*EqIf-sPBVnIHiQGU6pD~#86B1-kj4HGLgQ}9@hwc2J!-mNhRjKrC}W z62-GH{D>jZVp2^Ne8;ODr^}%Cj`m8@9a%KmRIxi%{5yaz3>wv|#G4V?tR?y9MVnk# zl`vI=VhPT#51zbVlgWy5f4R3(NhSytAN;Dd$6ra7lAGWeJfy(jA9dv68Xu8u5_yf4 zZZp-y^zB9MI8~$mHd%dbymryX-ShlXXUAsXmx{6r9>#OK=IGM6)d0k27Zz_9o z`}zQ=#vws=PPaP>8W*?&50AJunk%mvi*s)XQQeaTnQ35F%a?~m)f5%f! z=<*2jp5z>S!T;i-XUN&k89@5Ay=kV)MNqb9cRF?p=|Ma z&FFwz8|4)$IQp__dO5(GvnK~e+Y>KYQ(Y`7$FIU~(4u{v@lhHBl;if0=lLG%fW0#N zIw)>~1kAC+L0uuB*2QaU>QIxFon=`2u2!p7>7-An{;V>;qEDg62oj1XGoiv}%BEzO zJcE{hptG#AUWr{vrYB5|z zDsPou7^1hlU_oDfF+(9SCg|oOLCZa{dZ{I6Hu6@k+$z&5dpjbvYfhr{uVSJie!{15 zQxFTtY20bN^dSI4Z=|#MLIIe@>T7FMJWqmE>LIJIFoAUCiC= zur&5De%)Tx-f64cylY%xbl%?U9BC|SRBoteY}TS!mtV)a&{Nk_Nm$wSKK*@d!GhgL z<7NAg_UaDG#=Rx<)%td)_CPB;YjV4evHFqo^uF}K?!ZKtBnEEuGF~mMF>R1Xt2>F9 zzSzdsnY?r9z_FXGBW^pxS%TRmeo#B{6vybNe4X6iN_OOST^`}rG4ZjgVN+b$Qe3&z zx`NeFN7Z5Ubn6dvsO-Z7;y z;!w~8MLdchVM9cd6Ho#Yy0NHxcsEeM=j zlk?b=f0ECV-^jJ&)evoXqaw&DRm1gJVnw)Hpj&#J>!Z=nzlQmS%8sfuqFkKyLe7r; zo6xiC=$-r>9FRYG4)=F6SKs29;hV@xvT81(*J4?3)neX@WL(G)a8{8euwD@ZS(C7R zhiQlHn7HSJ=3AN`v|XIwj{(_f9+GlT5JFjiLz7`cZAcC$IC|K7k%1>`i)UsU zhTKM*ZB|cF`P5RRv2pbztK`|F!AtCGK6}*BE|UXa)-qbFYe&02%zm8zc(lLqroaR* zt0sFt8_yYcd8HM1Q@{1>_D*4yJA0aawI{q?uB&uFqO;ew^2f}yxU_DW?v3t~uF(1X zdYjeagY(=uwSVuO!0F#rliqun)Q|pEJtRH#zaRhFLX;sb_tN#THAfFw5GS*`_fBqS z6Dad2FbrnA_QkG0e`)6>b+wZhUY#i6P0;tl^TEJ3xI(ykiFxBY%&zjjyGQp}oA-3M zVk_PW{@=DSe$#u?+R<`D5RWVoRE5yXwq+8>s)ZD`Hh96XEl^#D&K*GpZhPgZj!ABxwFA$rh1lvZ0B{o8od@bZ_i|w<<_JBN}IsfmcVPlp9g_O*K=!1 z_vn$~v+&g0WPCZaRf&4s35;U-_ zdXX6#f=YzUf)qxC$%!RnB4dK7{-<4!K>R|-(bck%)QO-R)*gl>gt^4T!W16I!f1s_ zAdC6o`978Dj^mm8f=}REDBN(w9I`eED0#VH)XP=v5AHfRwK}ttJh={#DpZQaEaj#8 zcU(Tu_<3R}+6eqRWc>cq{Xb_UWlI0OWJ6L$j{wnveWH8s`@oW)_ihXP&r^ZDAX@iX z$@>J(mj65tdmdp9$__fp?mX{4SwP)c?A;d(c=}zq-}?K#PHC;czgKRaXfk7O3^?|l z+H$9hpLd2+J9mb@F==NHdDYOX?c94gK0o_E{Cv3qiaPh43HjdES_J;l`|Rs0`j!+N z2=?Fm$B1b#?AE~?vT@%}9%2CF+;&)u(wZXpz7Lt?g|3m~jl#@^DYH$evQM=D6 zkpEa)%ad4h*nr=4;4ruZLsmx|q!5p@I1Ggd=)od%-NF2t3Tby3hdTqjZ&=^|^to#% z?$xegFMesm+~VQM+(43OCuolE(C2iiDO|YkNPSz7+{`nz`(ha9aSKEGAyB;FReh(d zB-nS>1~u?`gbCwwihi&2Pot%77`v_}Uy0tYd2~UqrjY1_c+3MX#~fE$kE#ZGAm=@l zQQ{j2_`SzpJ%dY(;0ui2ZCsZWit~p-3@L_1Q;%t8y4Cab9?{!BI(r-bU|Jdae>3am zhw8Vv=Wul>k0FsC#JAz;S_15_cx&ysQftuB1I(9z#^0}O^O2IG>n_C`}n zy&X6)1Mets`w=$y{jF8xcmHQLN$U)OcguDj%eL7_5*2UzY$osk@5RpqM9*4(@1FO7 z_ebdAJSOdqT8n1Dd{h6kwqDqo%Rxyz7pLv+KXQZr`bj4!N!({be1q{hRG*cCIC`x* zbzD9z4g?7>|3}G|qQrOHZvPt8Y6R>MC+DaSJR5@!KuX70D z+JF4Qgm+5PcG3h0nJ-NIKgQ@&R;ucHbGfqEpGDqxsDSubDE!|mpq$yVWOSg!ntjLW zah}J_qcCw+!dB9M=5;^(2J`%Rf+-TUQs@%FpZ*^@5CsS|N&dfY3rL|GqWvEaQhF(w z`2R&u2J!w6FV9X1_~$qKEB}W(P!9h5|I(k_ zB>sm5i8;k5`m>1lPx%EBYv3o0rw`XC=E0DWf&EQ~8+-wybICoz3EOo)!e`@3lkz1eG#QG*s&; z=DzIju-o1W+a|U+@vt09;M!+@7fc`Cs(t5`Ji%a=8&O>;A(iYT0GCT_(NKH%Lp`1o zaCnk4)-`db#1z87#89M>zf+ejotO>PO6K0oP2@UeeM+($)K8sV;cpYH{G=ut{{5Fr9gPiNPrWA}sMi>U$w{)Wz)_Y@kT) z^}NKXrUbp9JnW`_`}ZY%VJ8?$``rma?DbLqQNhzHUz)nf3_tOX8JzR?p3w8(aR(q; zBC;g}w`)|jgKn8o`r$>}tQzVM4F`oYdf;GI;N4=u#P$2dykM2f>-Co5=>9xJt;O#* z#Bs^cMb5%U{TXo3=QFwW`XO$FCT}E}*u|yE^}L|CQ~C}t_}g$Y3=9W-tcTvT5Ec04 z?I#BFi|E^Uiefshshm9CeKCBhOy*tcp#IT9koQ}CHRoZw5P9o+G(5-AYQgGHh<0+K zks#HkKm3v2Zs$k|rhPISMQq{zXR~kjG(!Wbo!KI^&l4P>3jF52vUc|CNTT8%?%ZDx zkhedqBe;)K7|I;&bLIB+Y3J+|{@r2gd$C}HG~!Q0hne|yTDrdP-!97F$FH0~SjESw z4_ATG?GFwo8Ite2Ai3X#2YUDKD_xoW3&FVI=2 z+neEn1Mkmv`K$8-ULxnn6bAeX-nDaij*p(IG{*)aAk_R|5E=vw!6!c=$Q_Kvo~x$YDOPOoUP}1 zZ$v+SDMVm+(-?sCKo-&Goc7aM)k;$BO5%5Kbd*Gc5RGr%knzlE1tH?55ZslLd$Yb9 zW5HuXk}bWDk(9Xyz_0}~(;nXJ-i{IZ5dMuP z%IRolLaDp!uPyDIcwE@z1vL+&24c`9LA{_SiLu;Z`RK)9h~=}&(YJUHR0|X>^#_Wd zEJ)^#C{4?+ov>BRaR-tHqxIUl;CIvRp0E1;&Mg?JEiemM@B*^*Ub>vwt>3O96VX9UxOpQQ1NWZ&K~+t6K6twUkhhQ5h4<$>9zigoTgk%Q0pXbKt$>;9 zjk*!YWd;2~!scPve6ml&zro!)EeX^o`MpqrB(PC!Scy&j47xB=gWa4|IZDx)x%^Wf zymy2}_iMBLK$zI$u{%3mknrq=eFERnM21Wiu10t|xA-x5<58pWdWaMbM))!Ydmka2 zRK#t<;K{7eY#b8sW6QH!QlQ@hZae^?zrkkVYyKD~6Q?8o_u1#WYw=Q(v%OpEjzNdD zy^l%)!a;#q9^6mt!8dooTjh4Ig1|@OQ(pu^^ovM3*1f6y@1SikxD_ARyLR|fu3#{n zA4|Ob?^2)$O8LW*Q(U1Rs4mZcPO0lsXLDyhoqQ<(Jk3}t>fjhE-23=)rth$nrq_ku zK=KUGyh=A!h)^3g%EgsNyed3+<^!7_^7v~i+bOF-Pn4md%USNASa51Z>JRbXyaqD_ zZ9Qa?Ph2RhYa4v#uQ=hc{7MQ-6(>)yeNY2-Dt)2q(iw`Q(QtwD+XAi5_s8tNZ3*8G zbo?@ZXCCP0@@OvUk8eNy>^&nZIpK%N{k{87Qfqb+seGS)c&KGr>1T;vkq^vTBAorj zsntD8Ns(_h5VwlW<&P-}$$UpzDe&`X-sC6NbTJ&r?!*4=$mb)saP;0-Rb-4b;ADZb4l)9?d zC~hzK{$|>v>*$V^OSC60;A~t;q9f2F>e&YbU7?-$4rxdyYv>n-`yIC!o>SN-MV^A= z?66<>^*#;+MwncmJx>)3Gh5RCMHhn0KNxJW+XsGl-Lb#=C=GPMSp;tOmzM^O+kA;f z)LYC+w%v5oq}%PjQvGRmAG|1G%uf$Pd?zytnL&?%fSINIOP?dJB&srcr_;U-IPlsd z2@YxEfFBfiJVtkH%viwoIiNGw2EOO3_b8PYZMk4MCu!W#(R58?vt zP9!wf*~0o0;svn>|6qlC3KwlQ=YlVA&CaoTll!%&%-20MR5f7~%0L*jS z(~=rNk80RlRX}XTTTN>i$0PR|O+_<@X;CAFyMrtJ6_9 z3gI_>y&!Hnil?9Gv+r)S;QhTmqX%>K`_MHHV(;^#%Z>XWQm>&gCDFz0dsX^7$cSo` zI`PF0eNUFH&Krx=*drwgVU~j^Gtzp5_6&E>tpoJZrErS-8-ys>@8MH9p!pZ?sfcf0 ze9)n;v*$s_CyBi+SnYRcYB6YbG4FaLcpL<2BDaxsCA0bDOAyr=KoWbsl?JMEb?AN1vU{NO+)ha8Y{G3#mC5epqe)-3hT@RXE5E2~l%lx8;ei zy~~4N@3FZJX-H(N7D$@;xvUjNf#Nq#&S9d$>wiIKE(n>5nYHNv2b_bvs>gEt+vNd< z)3aCJ=hUuOKXe#89O`qEyTC#Btc}jhxfKo}7ve53z66aSO1o@6F397^#I@@t&f;3$ zWvm6&!S7%X%ED#w>0QHNU7gDo`a^Pu^^v?>ijfJpNn(Sv4^cXvn~~2Uz z?<=IfSh4f+J<+qf{(^G1vEuLb%5h11)c(HUQjB^0q6uLv`mCczZZuWvx1>!(E|R=` zFW-V;7A~V7C@0KrG5)+4$t+vmk3d|SpFc*@Gg^G*o<^e_qGncmfKXz%GwK5m~_gy#cY z??dy%`$2s5hcNT2%Hf}DA*%0ZMV^O*4 z4h$MYv)OnHD2PY6Wq*lG{{?WZr+J^BC(8fs0Gd2tymj+?(d~!P#auFY7gV@Hx&cY* z69t0vaDv65=Cd#u5*Sh2l z10DD-RFIw{#sj~TO9lQJNSv)RYeIsgflfDJe$OWRkxjM) zyR#^PY`yQXb4)BgNeoey4ydyxX&op8NvlC#!;Z_9q*GBWd_Jf>6+=?Q`_c1B<2{^L z@uV+)?%a0-qb>K;cKT>Ykta!`JszAC=_{FC3|~Rs%rII&WS=*FPmm73F)RiX2|3E- zLri@x=u>kyQ7d7^uppl`FY0C&;bRPL$)_fziHi4Pw96gT<7`?7QoyrI+P%Kr{a^q% zM&F@mCNOC_Y6vb#18X5aINf||vcft3=J9%*h8}_fT%DyaH1?2Cf|xr=4t?CY47^;F z?B-7PaSji~J%m3^1Ou<7-!_=!=|Cw*4y2*Rz?tJPa@kVYvp{@k?+02Gu4m23bEy0r z)5ez%n8$e#UCHThW+HcrexO$whaag15%G%h(+@;By5XhUof`iTMSwP~P7p3;{rkG&)m-=21f(KCsDB>b)I1rI$%+bosUyi&M09d4Y*m(~>@I0*cZJ5l@| z{$ozxO#uE^se`+9#U`g~q}cUMGZ{J|KJotJF9XE_yFZIga=%JN#j)p;-M*J;ZU*rOA4(s(U-@e@DsUqYXo&_lLeKWF=#ga_9a z|Fq$86|Tp2qKp0rRwkwthc)H@r+SnSc0+tFe}{SGllg(EoX_0$fS$YFcN#o!T?^>F z#7&m&w6U_H#+URI)d;$Z=@OvQ_}K)Xr}I20=2yLtcpm4aNQDF%cjuM_SLasm#9q_- z4hAGUkE&(ip3M8eHy+ug|t%QMm@rUs~I`?F`V-=l3^4D}ce93==M zg06hY=j_`bk8cYDmad_f1_-{{z`0~O<01Aj3)qj<&b{kkL}LS@+Tw{m?;c7&1c=p! z{w?gyY=B-f_rkL`fBH&4Ftfj<+?ETz66(Lg1S1NAkESI~qJ#dp>yic>CU1^sBObSt z5tYHq{pQ7QBkTXMumCpb9|TFYKy+{J8c9Et zw)ezqL-%@u+`8zC&W?q~YQ3<~Eevlqx~LA!yO%YAm?-&dLIDjDU+vKq9%l?x$RD>7`aqHYXps zdtWf4Bf+nNVJ|J9(b2)M;I3n*yx>b)`#J)fhj{4#eqrh16N~H3&2hAU{|zgPbJ%#4 z?tE-XzIYPuO~f(x5yeK*>P6rOh3CSziIX3mt}QOKGxXVU!3fyqR>iCo^rRsGB*6Cm>p!25;U&Ty}7t-~4Lx!Mgxr4S6c;I#j#O3BRc~>)HL=5G1&05iI$< zjX((YTkH{moVL&l>(w8pgEN%4Y2a8L=f-;q(w7#46yiVHWT_*`-ep=_`h9!NopKKm zSjDZG7CPkoLTX-2K$Oq$mJ7XHz*tm}485Gl^fjwi91SD+FXPe#w=kqtKb6=(Y1ZKl z2zWb-T6#p)0w$)(&{bsSU*nppplK{#sk|8eYkd2HDp;7bGsQM|N8Aj}DJ(Zdg~R=u zLY4L;ZL&Xp`B``!iOMRzHnIxIWMF;g{ml9$D?A74#vZA4=aV@CMLf700l2*woA<_OWLJ%t71>y;l!4Nmzy#2Y4 zde_I=zhx}0P%v=EV14SPhwU`j3DP@%lKZ2s4#fy9TI&eI^B9CBHrMw|BI?*%kwN(5 zFtuvgfE{q`K*c0&X^oT8&8q{`DZ{4Pv36|1NwAyGZ` zR^Q0XtYr1*7fmih^`A2ooE(W3VP%et&cWJ@YhG7AV>D5rx5XsB&YI^RV~NBcdjp#( zUJ5(zJm=unFd|)ONNi8#9UgUh^p99V`Q_+gR#rx92;ehYmSto5bmyRTc$Td04Umif zRRIwQImeRkUB;bNn8fFFL09~U`ILAD^j7_CB!Tlho(hr|ZZgJQ(cdvJsecVo$T%dv zGnZhPlVw&JW-23qh$4$AkF;GM>|{>eT?%Y_!ookuYp$RxGKUD=*{Nvxm>ljb5l-SF zVb&)53lM_HseAY+IgqQdalXN%lsySG71qSrGh%wAIe((9NnTf0X?-~Fe>^2ACt%(- zJd?Eo7wUNT^nj9txS1Mx&-+S>SjW-M4;wNb9PHv8jw_P~$i^i-;46=;TBb$1-tU?2 zNM+BTf)ulLGZGi9XO+7Kw2;T`a6)2m{Fu(Al)S+;K6Du*IF6WQ&d#5+Q6m*5RYCD4 znk?w>0qaFFw}a0Jr!@{S7h>Cc-yH*%4nU5*6xPerg;5IUfjyi65E$%#Gi*gu)ZwyO z4|vJO_IE-W?q-g7TJ(6{3X&{#ylF*#v-2{&om`pP-Ij+FIHadjoy;rL7Tdb=!Pl)| zW`{w|rHTCEwmbD%!aCWH zhbU=^U8gEtgLPI6{H z$t~ba7Q}0xBegHL5?Ii4RLX5n!3Nx9e#w(_`+aZIwg=|H*IM;6yj$TC?B{l#awC$s zg_>o5#%|-t7!j<_X!A>hY!we?d2Y% zOe*xMnGWg*&64EXWZ;@AzCu??VJTiHC=wM)lrbz2R}1!?8>V(f-Yp^MNZ{-!qsk@@ z@glg!k6I9lCmXfp+Bxs5n4_^-RTg(70ODs54lUjO{a6)b9pAJZ5|LOQNm7zv*u@3n zTv>=Nd}KhaLTx3=-BU%Xr_ezqCzat+nP8lTEB3rLqs+Y+EuLaCP;~8y6QR};3i*uK z%3*)yey_0LU9EMlio^Ku3Zs(!jN$9W!@~vg$~7{hu4sMPaccKVZ3aD+ z%&-0An&~glBvcyZmb$9k3B1UKk)nI-nC3*dnCI@oSIfnu~db_FbzBww%3Ox8TkmQ!Jbb$ zKvhml+KB7yQm(Q)5qUy05RYn17BvJuE=6oyhnr3`K`hN3PkC_RL0cdSp;7I;-|;47 z+Tnv(BNg2QNMiSlpjm&(ljs&cErr1^Da-Xp^3J?XqWe;CUv%}n^(`nRWyut)GtQT( zl(Vx8}E{Cw-`sRCMadvL0UerBSlBq+DJ4 zbKNF}$WuG}>4(cz3g^;`8S7jtEKNdhDmyVGa;_pAw-hunEc_-e%~|V0 z0@vB%x0Sj#_9RI01Tj%9-yT9aT{W$o07By#VcopiPv$gHG|iT*4#)$eLz~j$yqn#i zw)s&;S*k|SgF#saJt(a_r7BFA-(zwc#-#X8>2{1G@jGiUBf2Pr58@XcIxM3^*&@aU zrGYEkahxl#&e(&kTjY@iXTl_Mx1Qf>Yaq+vJl*09rsM);$Xh7)BMju^^L@}j0h;)x zeK(~@`Imj&9H$$(Zt01-vCc`=0@ZWu(A@1BG3u$DIktP+K30?=BOlIUW#VkTrp>fA zlh}v9F~U~wtI;_}G{VRP;6H6}=)$TP%_D92TU|kz+$%;R#N|PLe z3xpCr`z?Xv43JTnqtaE^mI7D_Yo0q$*6NH+;&s%Dr)g(rQ84rXN7BL&H-9dqSwnKvL>>&Xm6Exf!Ox1ib_p5bkm(fcF0StUEmB$mC$;t@+%`6 zge*boeNHr_p~Y8J6814bO)ht$6#eL=VE}Hm9UsrteTX$J`iCo5fkcI9H1vLq#*@+b zbyC@{^WgIeHo^Hj78~LdWzBCtX^VUK@Y7Q5qa&&IC)nIsc6J4ZH0qIfE4#UP^SDRMQs&0f(Dky3JkF9*rozF`&X>v9;9 zo+yXf)HX7#cF~bhH;J@fii;BusXKFxsWH|OnGCotDy%h47tXeA!=;;nsOZV7UJ}+RLD#vPKc8_R98*(M z4q>+k(uha4Z(XBk7bx9JMc}^n>^rLyirT+-Jf~_%OQ51 zlEg<0&JXok=trNaY$Y0XBXqQGW086E_V~UK_KX2FJN-k{mN-|pPO9{g=x+rbdf3_P zei?tGt^FYv8dFte@bf)~3?Ub+1E)sYoBErc9&9z23VAEZz#1(Z)&A9?8p?j?uFp}%3z%tB|alT+{~)mo*)#c>r5{XY7dUxWuR2V z@@2}&k*h^z7FAik>eJHv)cz%B<(*)4OLylxpc~m0oiU~SUQF|!9$i*cRCTP-{1fez zXO}ZI(eU_;rXkAC_#E#+Wx?VxL@^bwH>u7OjlYUq4l!#*+_g%j4#wd|;xOG|7L<_N z9@Ml>b3e53K8gVshpnGoX`+58wNsN_^zv6GPz#bu^qb;1N(T7$V$IvwvV`rpDKTAC zTKn>Mo=EE?gY8_dS{%p~c(($2rmsTe!x#2K#B`S!XN=dme%dWq$3-u<=&Gb@o4U2P z{>>tKqanIdB5gj9&y5`R#&h-51bbXVzK|K4g|}t!W2qL>dj-$wPWx}SREC4(*AY8l z7VGPGy5ccb474(wSsRK=MseH;;@|YYSVxz&;!(Co+9Wi%cYoWE;`cT`xq%Z6m2 zx%&;piqo8@*4s(tDgic%T+?V?Q5+9`PyK!6Rv8-_;$lmlhcMF^dF1JjxuEvKeLezG z`Bz`dz7NV{{M0OoUMC;ki5}riiThDq^1(=gv~B4)-Y!N$jkJd(i^(qxQF%#`-|(@A z)6Wt!qq*v^kjPd_`$N{)R{|$3Qit~0hy;VUQ@NeZF+HyicKb839ClT54$?)H1TuqP zHxmS)!U)y|OElC&*2#V~BP?wmnlkn*U%!gDW{KD;V}&fUtpz%VWR#D-yeaOCT2aN+ z3MEdL;+CbxnOy2LPB>L>7k=U(=2$N?wadfoL=E}mMN3=5Uk$hoIbMm=(UPOnh4FLM1|}zVh*Oj<=94rD}aCJpWna*U7hL*9QV$moK_FDWp(yw64y? z%-laGLe6`=@#Zusy!@{}XieJINX5Sn{}LAGTJNr3)aG3yVDb9OuyFbp4pbd&?89Z_ zcPe|dj4$D&T`STC`E{gM~= z4U%Anyha?aG^$lYYxX*u;6z@Hz=wjv=Z7Mtf!&3pIfh*1&lUGn1&IYpoX;iQZ&MB^ zC)zpqxc91LiF8ZQObJHhjYosJpfazJ6Zt=yMA+OHZomHy=0gqFdii?Es{W|ckC4=* z)XAR-`;FKjYQaews!S#-Z>C)s0ja7aLhQo;ufr%>CN$IipRmBk%DEP7&GR$QwTwl6ETSdo5yWi;k7F&<>?T(Mu`uMgc zU9%t83(tw|?*@kVRmWoQL~Q;#3VCNwC$9jexW(^LZ8^J++t7#3Dp%RZb|hnQuJ~>l4>gBDwTA2ly_+J zZFP@iDOe(X*hv(b$K|n<@GdeLE`vs{Fe#&gV6hlYc$}}77*mMtF7f_c^%UDr6f<+0 zf8u6vU`v(1ktV&aNR)Ng9RE#9hoT`iT(y@Ze!lgLo!xzgpSm3ZiHV6da$Y~}=ek%O zpiJcj>@O$Pqa9KyYcr7u6qj}FY<9jE9LDmyBsS20-O>FCyOEnCSmPx|36K3NYTVZPXx1@}q zJOY_M$>I2A;er+4_-hoZjBV#7cu{?$uah;vK+=5(XWG2Rhq)ozQjTR{}3*;^hUZ|2eF;RPQ zd7LGCnV0iR4oqYYIbnWEMGM)6oMXQDq$Z1|*KG`03smmG_^oDTHbkW)CJ@0z-P*A0 z*Qlwq=6|UzIS*R2ugHo&2oTE=!}}!BPdmIXk!u49lf$$>uQmC+UfCTt9~k8fT^!`l zs*^C)U`G2$$NM3yAqu~_f&jhR9>bwfi{rPm^%D1BJXv>Bu_1;26DQhrOLW&WGMY~G zoyGG4?fwiRMsj_|>s~wqa*tv+g;+Gp#`G^TnV4Bwi)#cv)oAu{^_??y8&?{;gudrx z+D$Wo&M@Oz$1C_$4K>`1f8;|cSLS@PLhPm8_kH-7$!MW+*LqShnyNU0`4XjY!3!emC5%kA(S;>)khy}QZts& zBvcws?OWxtUj#Z7F!rX0UhI{WoxlK1s(!`tlirG5?$oXFQ&qx6(jDn^A`L^dxOFNu zQKI^9eNqHCPb3*{P}s3!F7-EiybiTL8hJlnEepyyW?DvR5p_{0v6Zu{IMA|(?a|t> zILc=Ftkp!6DYHYBfAYlwO+G(-(Uj{cY3}(_@slY|L$tAmsg1*$NhlFJ{w?0xU0d$M zQzej&_T13iJnJ7q{vQrq$Z2JiP5SW%f&!^qKGbdAxlTF5?614>VJ&)%l+1H5x@q*$ z_ng4j4(p8(rqqJx7%H#YTgEW=cfVrqN#(xT z7>1DEsVsNgpJ-||sh;o&X&o*}aO)%QJDi{u5j9wPp|vo`C0|@mV&pXCknJ>pK;JA!a{nPlaxZ7Kcli@}3Hiiu+$51Dl z6E~5Q|D|5nMfK#E%m9FOrP(i}hRk-u!^m^@M3%^sde6IRqjVe`qShpe z2I~5yHMDw!q{i}sYTsGKG!JX`t-O9_)f$6BmGtMAut|gdw0~bMbPT}G5LRLQawon- z?W$RVq3+*4?#cR=D?2nR2HQsdEk{fHYkPd=mZpMIn%22?Cd7&U15KAGPH3g4n(=0g zlakuz_iiF@_Y{t&UGlHbZPfxRt+_UitNr2DEuX^Vg)M=`JS9xNZAzUu`)@71@a!5k zI>#~a#*A&~UAow7T&LpW^cEhfixMB4%FTMOE`0a54?oCB=x`YMO%jwM_wW-kZALRO z-%ij4kgF97QOs0ja_KY#yj_$d+U~rfOH$2jnl%JfF
        OdRJWh$3zt#KUsm+L7`X z7LF|fXfUN=zSk!F`=(-o_47MQk&J5cF}@OoHH>6-eT-r))10KoKWNz8lW~r{wWd}i zyJ7mSf@O{tCn9s>oqqA0c3;sH0pq)KefJ9QiJN%-5V$O_8|;-oM7lcW5LK5bsEl2? z#W}8zuqj6vkS_zvmOK~d zPA_d~plheLTQ<4#$H409%di`l7U@@;^gqYAe(R)J^{DE2=T-i`*S7mcvbzL- zE^71)3p5lppQy-sG^+%AMgE;3>Rz?|>>g%k;Td}ys)Q$rvw@&m|25SIr|h=V%z zl~-fNs)Q+2yopf3s=<_cQBndhM0G3Fi&zgYiOBU^`aUZ4{e0-+byymu4s@$(3DT7^ zyjs&?5nyfJ$T>H;qoAVvA?P*XOg+n=@ko)usx&=&ngHvkd_u}J%G&w%zM|6Vo!c5i zHG#;Y5&IrF%o=O8p@kSr9GN7hg4C4!nyoW4no@VlwtFu;WJ2xhaSBOEOH9JLgAHWl$jJn`}uzsSG8()$e3X?^)p zhBAvB@3+xcIom+auSI_Rcoyxmy<98@JI`ja#6~1b_uOiMCl;+jZBK^2L$I% zYV=QSg@UCqM(Pgs@zdzWy~R}ZPa)QEOy!$RkYPQnY1(#&L_T{Qi#;^Qt&T(O56)vH zCA~cwj$(9S?N=!|NlRj5G9*346att=1Dw2JvZ363-#Kx@ZwP=rnEFGVuX^7jmlZMV z(a*IIkcBYP$~a1D);q~h(4YCFRb9&L6!a`vC@N*u$bBvoY)jKL#LfC<`);ZxT77HP z-)AC&VP%4+zUN%*`E!{9=I4A%?4ZD(>tFvbxD2=mrw_13cc@E|=fV0wxc3Uk*&dem zDO4PZ52bshNU*D5`~lUdph?6(=kK1cygT_8tD})Rz*I0!pb_P2t0l)q4PC69S7_{J z-^o!F&a#hB|H121QXCNx=^Qu#i^h-@t^Kg8-8_r-&?U&)pR0<5nwQw+iwzq$YH8%s z7hWG-{~9-N%gZ1Nd8i98U;Pv3c+d~L0iC4rgZ|zG3k3vD z278}=>vp)`YeMc8I$d3nxGzLR%1Iowg+8$Zc4(u`)`B0vR8=;F$KMv_=>?n7x$lOi zbFs%1D*q1v1VQ`05}ct47`Q~)b4gs`u=C&zW1Pswm>7I#NWT*5A~|JsYC(T12xIX= z5U_Bi%J<5YVG~UxFe&-2sB+CWhVdedIp!r3Edm}NFQ?ful;|oK^zAOt7dsO_SBw|LsEF9O7)_6{`+@JM7jI!o(mNzKpzS2h{yHUUoV$kb{VgE&1-n~ zyWbst{*jM-grE7DpJ9A_TrR!z(kBEga=``XvD};^CwCQiXU6TA5J9zP9Bac^KC`V6 z+G?~BWf>cjEe5?VD=Q1EtS-}RjZtrop;T&h5X$3L#u4s|heNBV$|9N^*tq2+o_ooU z(Hxs(b!n0QYLE8VIF)9T%s9xxTW>0B-Duo{sio}Wn@HK4S4Fja?YCZWe(F*Y?Ht8& z$}j}tEhQ=8fPPUhia_fN0Z0TTx{MnJE6#%RYJy8n!8s^wXmo+W`b9Hj`$cihGX+Ye z`?yHwvr6xyt=A^rC9|VA*YN>ZM>P!PJ-W*HEXufhQCydB&t38#78ofTKE+sMiRBVA z*2Hhib=VPEh)4?RaNLt3GUE{9c24D{4HAoyob_mdAbGsmLSBj1MP{s{t~GKL7L6)% z?L^%5aans7x)2pq%TO4N@Yy05N1ig#&sAh`;EVXh?ko!GQB5OWh}f%?E_vdJd(Q&qC<=rT1KlP!2Ios7VIfKssJ#E!g7gPJ_(5Ltn%D5Y z_r0$ah|f9a9HyqGzTo`xxUYA}a*0tvn2^ULo=9D!NlNXph+NM^ zDXNV&Nwr45yG(C&g?^_)v)QIvZ(vl#0x3R#s=}njlx~#0ZM*KjhtK}a`+42({0Wt6 zgWk#t3-b%qdR^-67L`haJon*Cf=Hp@5|=YQ;vgNRYu1TQM=iD_!h;DDOAY()#=*>Q z4-*vx2f-dl%5XwZZG`}-N?DM{VNC&RJA5^=;FMt*Vi}v3A%1aDz4qgo5Bg&pD0Vyk3`M<`Ni3Q^KML=JlaM-JAi1c%5Z_P`$U5iiW7 zqzuso(=CtH>jH*!#e9|LbmnL2cUB(WyCWWV-+ebHpM3IBfA^vny@-Pc4?eNVhDuxM zs=;l^Gd*%JytBnQp}Pnwbm39(;KKa8mz1=urNDA)>|PVC-F{g zQQIuzS6k21Q_yI)*|vQLnE^>s8sk$;tlMC{KxPlKx-^d>M9yFjI*LSD`QQ*OL=ja^d8a_%yDvZk(f^_Xa46!4M2stmd!srC zSd~om10^utDu-|F94q?U6;`L77V7DZS`}HV((c%G`T7T=DGxrmjy)=335XOu6XP6F zi9#DGS)~GzCrBRdi|wl!Gk1nOQ&2|5jFin*aF zvI^#1o*S)(v*w6f?}KWhBK%*)ZR!lUlHm4e;zcWJOyIpXv}-D@Jo<^+R4HDzs*^vp2)BL+OIu&CjIi4znsr~?sG@|-Df}hS)TmlCqKa` zc-Bk6I3bJQ>ZpioTk3idK?L3h)+?)QwwGBciB74sCrKM^x+{w;FV2#t3$)skB-J_t z@kU98G-foojAPw~O;*g}ZlWayZ=~pg;nh*a=W6d*XQYJZ`Rb%0c1$aG*T{{xhSb4$Nr;X6k5e9s zcXvcLi#XDr536Lj`K#Mc4E2d2ts0oq*F{%aGQ%=k@w9Q;`6JaLS+yY$q@TS1$P4#?;MSk0(6*%p0!buut&yS zM-fNG!9DaGjqZzxAy<}K8_!uO75f}*)j>G9GR{S}pzu{Rn5@gf;e#y9>_z9RtZOGU zYBkSZdgR*Q^768HDfo+D{9<18q8D-Jop*Bm_1AObjW=@HWtTBEH5Fd}@5QUGKKV{b z$Eze0DV6amJO6lb&1-J{;w^mkwt04(`Sbug#MHBJaovSZoRrjyH@v*q7ql$iY>MpF z`);Tl$@+9wmgx8URH`)^%{EE35v=u$#opj)@ZdSKo=d%rR-|#uv$~dTeWuCfEg-;6?|Kvkj2K)PU7a8Lkpe?-UmgO z>S8lzhO)}UK`w^Gspm|T5r;NIkuka&ViUyOUvy|ND@DPO7zXmj@@q(#MHdb2><&wW z6%#T?9VEQv-h^eIcSOyg=s6f9=RwKnnhIb)GO%o%F;aYAR0%4uwzW}z*T@{o6&iIx z11rnkBdS=GMJjKD8yR8^Un5@>G;#l*i0T-cAH<)dVp^Xmfe>Yn=pw4Acws0@s0wOY zO2ZI|EvLhXs6Crye!mhMW%%sE;(IoCcF%D}K za-~SpI_=3i*`UkH(jrUqN2oSh)Ei^yv;v~TL#t3UTjOloep;BKMrjghdCsbFaUpY=ZS1sFHnAV>hN683kf0coAwA4melWw= zB*qkn{CrjH6(X!@&sDPNjMZn(zoNvy^?Yuz)p-*&I#t8o5T1S~1PfRmp@mXt4QArT zwW8Uo%w%{)jxKiG zdM$9YJ)0-`tim{GZLdkci22Ocl=?!lhK&(Z7kvj99IY-NvhED`JJFUMv|HSSL<{*~nYlxI znLqRpbuDb1Xi}?GsW)m&Oi$4tg6KfOAvwk9_g z6IHsvx0H#<{f=`??zaBXoC~mpaof&9lI@jhiMGEV^g1jrFOcUM&DI#L_5>n2RE#?- zE6mR9XY2MIu0m0$;RJ&+LaGzjp+e~OmRVh$BT>+7jZ>+Qk)bh01Zqqm9krEGs9XYL z$awtI@smZXQuY=k`{L~ciu+_dCXEV|wy1Ygf1A8g(Y_rDMPpspbYnmL}gNEk4 zijo&aSZIamHTAn3$fgW6`YrM`knAzF&< zZ()I3sK4-Z9bNQ06X!o68j}kmno70J^z*$qk$7(q#XV zVkJu+8wKwuyy+))%I$jwnnFDv@d$>nRTa8E`=I0bj{(P4k$hH_SKY97djX41XtgJK z!LxpV+wXjU2lwuy*X__~k1^hEa{NiB*-Y6@K4ak7XPv;2#SZuHJrdXmqV2n0_}X36ocU#n6h2Q`ETsi;`1hu{enNafLyM_uW)M70d9*SZi!)(8?=9Td<>5flqZ zW2l&_DEV9u^S(=hmAIW+T+EA_IEU`u#G5231@w{ytfN~B!@}-*;ZIpPOnh z{Z)<}+{415JyaO5VZ27OR$+Rg&Fa9=*A4oWF%GO4dPXCv7Ur<#SR0|Cs?+(1E>Xf1 zLoJMC$ge=FvR^XA)-!IEp_L6j$`$V%^^&xbaK?!n`H4%O$!VvYLcP|cySPAAr#$2Q zAEW|kn~L+oXPnA2pR|q5Q>`d7(}>X+6d8tr7*w^!_|yi*#wO@>d#udcrnp*iV(~Gq zco=7Iktx?2ta@1Y6?X?O8he^3Tcp$$tBCP_p@{m!#TccL&`Bkj=Xk|pRER2L;!;wZ zm7VG+tN)}3=7I7S6_@l-OD~^whyIN56CW-1UWr*Oa8km$OZ6iYDfr?nI8eI^FAY)g zC33;p6)|0xH|KGpi`_*jxRmcj>AI-$6)JV~R%@HIO6*?}U?N?Xj1Lw0O7?~UCX+SI zSH+8F;wBD5__hE4!mJ^le)02G)D6}c@0ZW^C<{>mT@Ke<10^u-%o2-bA|_DWXjlWO zQdG(5FCJ#k-M2Hl=RPK?ip}dLXx6HT!|>Yq#8#Y}C*4TgkDt;N*3O;oFOmKJ7NUN{1#Ppad}xsBiRkW@mWPL*uI(D;@*dJL3<)T-42D+fqRvMr*BHm0^l|(rK#)vW~C7vx| z0_1^XLX=uYp@MOfXUzD91BPK+PfA(7ii*45B2--0n;~2y6bb$L=TdNdb+l{I%66_y zq=1C{bqNrJI7O_d`AJa#H4-)IRprIgcETxQZYXHR*U*><@Qd456@k#hQ4+C90z@IE z@I!GsQ*Z1PcgqQ^C~xJeRVg9zCm^LxH<1;q>*%hdB3y!P)0H^?j?frBSg)6xA80j1 zw~Kax1&ma5Lh`*Hb<}}8LeIkLXPo4{Q1TM($OWAUs=vbQL-%rE=Ql}vb8McfGcn$v zUawMXG|*|CZl2O=Pf@RGT9up{t5ox4(!nwn9z&3xoSamzdey6V#VcOH(E|0WU;S!% z-t(Tv_U+rBFm8F;3`nw75;99ilgLa*3?g~qb{kp&N!f%wUTsZLxUpG-4K$GxLqvVj zC`maqx5CG6yc2-So_i+K>!+C9w2c#YJc%@^^8BZt${8na;?7+M_~%>i3&j-UMJtI9 zq*j=tUGXFnAy)~t_9PSQHlj$FKQcpSc>!gzNNOE%WhrM1L39^9k%#O&BV5}1Xh_tz z&ci~9Qc(-2IE#xn98uePHIz+-q8WwDo-P;&QQlcp&`Tyn(KZ`X=HEuykB+)##04~8 zYw#i`t%k%d5#r&CgACREb;Q1)=-&|9B^jsq3z)qQ?9L*aj&^VcDK)Z1N5OQsx*)?l zpE6by3r9l7Zl_|6|3{RhsF-)GC^d;y!v(pL<*Ey8(Y+4tghAj^z$u>k7;sS5HDcWKfOETJNPGWkG4U@j) zl1mgIuXx2P`0$56EW-i%iYu;o!UX6GE;x_s_jH%k3H{9E`RQsbULdTxs)IM!Sgud z#0}hj&u%{PPq)x$Hfgk4B$X=0s89$iwzVqY*NI9Ycl7zRMth=4zu%#|y25hSqtR$l zsWvbua$`%^I%GAGl*F4vg>=oE;^z*VGeyrkm-m`T;!aqibd;f6CP5(&F7W@LqKk`A zp7ZJ+WZ$Ywt0d~;tRf84i3>z*!vcpzi#RXfh)EEbEbg^FJ4XA$SkY6_sL1#yZoQ?W zY(9ueiU5!YOoT{sQe@`-{Kdo`7*e7yqGJY*LU}rcu~_tQTT6+Wq)JqT!&w~^9AOo; zPg5m29aczl8MQAq`nr!qaAHxHkg~8S zFhM9?KjSELQsR}zP?QO~LT?LDI2RUOVN@)B3cf48xpQQPpfpJWS$B~m2OeVK@Lt*# z!-jR^Oizu|Xt(JP3?_#>H>}&Rfy@Y*$w(RvFjac}0Z5Kg2A$;Sy=I*JHg27ygYqk6Z^3cF)77*SmPpvP ziBcSzU*Z4Vcqjkqxo7h77o5!(TV2jLaRYbmp5Y7M+Q;P723D5mS)7}p-fU5?w^6!+ zQHnfBpbIXq$qk8b?CRQWRq8D&)f&CdGM&|BdfhJdW{Ya2YBLg}N{u?hb~Nk*JoU?N zYh!!OQY+SwfvBJ}E7%%tL6brdpjF)3$fY9TI3&~ueCG@kDZ_@PwS};ua88mqC_B|m ztnTxMINl^uC9#ag2~2bZT@G#KWevk4Xv<2CMhn%O1hrsHVT`L8C2Hi*uESq?OZ$pk z`iP{~PafaP zs4ZDs%aBkEEYzkdSjCF70G7bMG9}7nq-HFt=8g(ViJqw=-i%rNII?;d|McNE@R5&xf^Xe%CvSi2uZMqM_|l)}mK#39zFj-{ng4PnH~#Zy z+4aB!T>dk^z%5_6fjztK<)yEDEw_B(Q|#S!FPFdSb$s=PPqBB`JzRdpYx&9zpJwj^ z_j38GU&mLk{}g*3xQCa%@^yUe#!s_%*FC)KRj=bKH+-5syLR%jD}IHqT>tm%-L;dK zUGX|@x#3gneW3XHo?Sb6>8oGQ-0nO0(?57Cl}d##f9*DY`HGkf-Mfju>zAq zmOW(UQ=*BjRcOY7owb4?hW>g;yhcecA9XxYYcj=HZV{Udtsz^M7M%5)w{gJ>F7+*3 zie$t$DRxOoOf`%JN;(oFp}aX#S$LwADybktfRB`=I&wtxI6j_>?HM|*=b;HfUArzf zMGLdIU6+cu)h0MG7OSi(HfTjWm*O>v+b?EL5M?b*g~7@qvj-leGq<0ynr3{g&g9fO z>h%_#{(vqObbS)Z4bqvR*{G4GHOMovtV=)7NgHG6bc~*8jH-Z2AvgTw#ZUR}#Vohq ze!CcBn4h2L?6c2i*REZUi+?}k@^6xE_yKg~07-R~+y3kX9(rgm3yVuU`K&X-zwbUg z&XFUttaKJR>7-LwKC++Q>H=H0ZDrqq8CE(2ww`XLV(TZ71$vab_Q@E6Z#>aR>8<53stj#BtkqaOBW_`}*ytF*mc{{rohJ9Ntf7 zWr=Mkp2qCVepXkO*|L2HFFf}o&OPfC`u#rLUZ0=*xi|2gd+rNQTB0nqYS8V{?{_gu zsMQ*zwK}2_a^o|BJi^W+%26pRHe}g=ey@WVL#^JRQmxs-XJ~b#0*s-e5Kt0OsNn}S z!aqd~$!Fu1M#G)_hMJYCwQZk<8-FSp3PnTWlA=mq2w;5CtjG`@Jf)&7HI%Spr* zzw13;`Xuvn`>8cIqczTXv1lJDMErACi>RcEPEV*X!*?E9=B~Y~g_%;+OjvRgSr804 z(+#miC<#o;%?=brTeCHbp$pmx1%B?;sD&+T)Zil0PQ>Cbk3}bxeXd18E>KAm$a)-^ z*~`Md2WhB26U`c9V{OJKCQy|c%e@?3X`$*942)*bT_(+r&~DnIp~*6IzCyp(Wk8B< zj*%yAGF8W@6pi8)&p+eXQXJm=#ap=HYr8o0N#|ga21chS3|0CxD)#ntdp&x20%-%$ zHF94-!g@&?$6d9~SGK#LFU5JSh(su*ip*VN3{7dfC49lTr*PKx4cvCuZhrnXujF(8 z_*np6`_2z@-$Mr>(WqRLqS0Cq(`9M#FpCRwq?HD(b(?9_$59BG^ey8fSBR=OXe}o} zNJPc48znhQ3$v^&&QYyZnOL`hN^OihFFJi_WkoS6vEW09_a^eH!-1v-dHsAy;+8N!8 z>u3`@u6aCG2mIOMmR`QBO+h`&88+Dw6ohNv`EztSOY}{fnFT{`Y*W@e zFaDe5Vt?-bo8`jETT)u}Rqohzklly7#I_i*3!o@v@3u&3R}#0P^1CE0DyqB6(EcKp zo)_7@Hw{xx#p)d$MeG70ku7bp7#7`eygJvLmL*CGF1XuCBpABO^Bmr{i`AvWOf?dw z$J#X8Ok~Zj=gj_d}v_WR9VwwITO**vdH8NEpGXmKP^!g0)0fR~fU7f_FV+>T4 zJkNO5#ZNi5c+xlDd<*yAdl$82K+<18XDcXj22x?EU!k8@XjL1GR~5-%0X>)}l>sOd zI(Da6PYo~_M=Oh4xcdNYEe>Xhnu16Tx5{6Q(fYmplWLISFwZQRbw? zwf1m^am6{`{wS6y8*-=Y1dO)5FH{;Z?4tb_MRykOgRE6yPe~yM^NwuJov376sKB;A)8*VkkdqhLIK^j)UP2Lm{Qxm!iX#i85)4&#!P} zUFixt_x3q7S2QrzLrPTwXMKnpUFsrJh;t-z2DJ1<9WrHcemlN6or?(?hC;1gh>Ikq z;zcfyqAiEdGI4Z(`BH?$%^5EUtE3v0b(r0IAN%h4CbDvvEmIA)Y@A}<#&t9&rpb~9 zU0r98j?+up^d&)*v23!uPwGv?lqS{I8H0Z>!L~@t88wpK$3l?2bloN>qN!jQsM^H)BC0-Sntamo_p694S79WC?zb?jL zB)7-vJ;Id^9Pz@P&vovOb|;QbP42n^Sza&!5|g9+mm$TTFw`E)7f$iLAf+Trk3pft zx3zMMmx&5^I?A?lU4S*Nv|r%L4#@Y5jfsk_M3xSb&w%A(yTwGu%oBl?*%|iUeH+XB z?`1<>IBvr@n>Vj#YI;45)&xe?Sxv_1BrOI>#U^LUP*p-z22>=sb3kbZqUcJ6EE!{< zTA->_wMJz<^4=2J>H_zE^Q-*c@BQAf7o?3Ote6@dX_D5aXw|D!%?i4|04iso6PEIX z<*Z85n55OHP-lg-KZi11XUgKYRF<(J;l$5%w=twc>rLc)EW5dP>dF}$UvH$IKy4>`oFVi1nMSljN z)HF4|hdN48bdbtW+&2fY1YWzNO9nW|pSOuz@0=fc@D=gUme%D$rk`Wpvn7ex8-DQ+ z-}FF53Q!Mg+80$5f&K~yciqLFo!_8h7TCPL$#I+4v3cWqD%Bd9Zm?ontTM(xH!vna z8$(46NL3%r0F(D^GXY(pn zuh6GKz1gN&Rj9!tI$J^k-Mqq5FQqG0YRxek)s!?_K@H|eq#Jm&1rsdl@a!`w=kpsI zl{c!DkU{^`*X}J*iejqL&fN!j{U3Z3fFHZ~TxWlny9t_rBxu*7tDgzg#yIOYZ)g3c z;~3;Q`}aM_;@m-$=}}D#TIb}F+X*cecTHTk^vq;rd5+N)#-=y3Y3p_>Y0Avrz04gt z0Fsd=I^qjUNlGk|73MUt`nB!b+~`i=vSz#_Bx=gFd}}W($X^O2<^`b`8x+g|SMHyuV5}8!*sK(xi^4O4zpP zzz?=XGVOx34Mdi3-^+47@R@J0xY8^4-E%8xfp&{^8W*u*5wv1uxm3Mx0&M?$M$1)2oDupvXxwHgx} zj;GmPVPW<#`}XW+YHHdx8c?ZSDBSkn7&ob1u+mYcXcT3Sj;P6k4-CN=zJ%vWcrSy( zXy2Sv5A|;pazN?CWorfVBQ$luw*a%(RGDZegxf|F6*7%PSg8lZRips44{|7el_bd4 zbX+@UKihp;hitas-6Y;rq$KKzVFT|S;$`aE@$ZeXorU~)N^t-4@^W#FY70-}kcIm| zjw!mMMEA>QqaND&?E*D0VE?gS;&lx!WR0ZLUU|A8#ZreYLufK2Rb+_e zNV_kk5=YoqGUU9&nwQeRpmQNbYT0Rml!hxridh^JZ0O+^T$X=mM`63)x6NW9iTy zG9<7~Fvb?$6iA}TvK~u^c3UiR{t&D4hl0;Y?DJtO{@!=QADb>*@LVA;633SkhGF|t z|Gfc>D~{%F@fY!MlIy~*mE-E#ExR@Z+N5^8;|SC)ysZ&?UmR|1j45>wccR83gZ_{W z&=V8mT=4Ak86O{K*RBWnyH8z5Kg)u{V2N#`3L_~KtQRO5_IsB&-!HM$kI?-tFPZAc zOw7VNrZ7B{(!9`77OvD1bPNM2blzimW)BbD`3-tU_OY>DW!*%JTD6W&npDyz zy+J~*>g2gWn?4B{smiJ793=y%2(|tVnbhd#iEW#eO61Gpjqvu*{3Z8&<+C7) zJO1f|eCr=S7z~SyYibaVLOBl?52b{{mG4$knDkfbja?)#@jJbeOlqe3r zSZbY#c3>q_{-^=15uvj@&o@8&mxb3dpi~n2MN00QB^P{R&#}&P;o86d6bBC30R4&| ze>u-S?|gpZWiMxZe4Ga#e1IEn_@^}wnAT+*-*`=qTtSMwHaJq+IquI@E4ym|0t^v* zm)I^lg-vTwpp=q?N{cmRQUw?t?LO?>tt6V>!Yq4tew#!0-$_e#*}A^X#&vC~6-7TE zu(-TLtzKu{#?44lCm#%`_UEV#=BS%hQq!fPGPE`b34JOId}}>Ptfm3uTG=HbWgPVT z7z1fz9I9hvRLOG~3#UF%$69f3m5T{M zL3@f}o={1fY}|A_>o;zp*X^=z&n}jhkDzr>7J5Q*F&HCF(JlBV^=M+GC8Z+sc7^ZYA2% z1Xy;kxWMv}{cPFsbd-WEr=7!=)6aEzk1Ke&uF}5mjS}M^Ai=nTqlsXY!adD6j{$nqv)gH$PwAy35?6RL^Y;2rLwRY4*Xt)n?k@2cXA*%w* zqiArznzm~JvT%jK!ZD-lHx-Pqlt#QenP{^!R6Pi`1Cj%ICFMr#~=cnWj;z z(ynCmdOiBRj9gccYK@gVMX7{FHKm>Q==D1Ex;-js3seIkwOe)N6iir2imWb%E2-(8Nh};|2x6N;G8UPFU+{Z;l^4xo#7U_Bc!P^UNPUNUf64nw&y4 z+t&Bg*an%lU#{iVT1drK`K#?oHnhfBTA1a?;TcvJ=b2o;4&7)2m9W(}xp8a@`+nLV zAdq^uKy22Ppvc8HV6wqhGvv@W)Lb=C*&HO`>1`7EI!M&rd$_g7rc<8E?f>wXtjr%` zYLI}^T{*uUm;FSRrdlg{-DPI>?V>Zg zkMV|LqSa))-J)KvvoN2tywasL)}~pj(yG;{)GI8`E|K@U=xSH{(ydeK%-GbX}sTWDbeM3G7E=xzq1A)&@%KPO2NTJO$NF0B{_SX#wzDTrR2s| zzS~plX|-D{9+~0LzI`;?O(xcFLRXq(V%aAmrsM!;m#ZWhW^S@Kw*zR>wI>c`$81(`D=cQ)1LLi9CyZf zD5W^O=N@kV$G_s#XZ4Z&!`ai?+ii(VN#u|NO*w{Y?~Kg4}s{~RlGhdA>& zFXf>-zR1elAwKuM|H1KRozEH1{*kc5kf^h^45=r5CM^Q>M$^*q#Pg@^93BqPB~07* z8(d4ua1dZokBD{WW=L8u5jCU0_NCl)B_bP{!UZN0OBs?Nwz59#DLM0p4lsLgH)^oJ zhVd#B?Ha9CgCwc2va(7)v-3=AMV9qBGP954PduJ#En$%73I4O}4ts>f#&+_wAw98lyeAfwWS!DlP%7Q|G$pc&)kpyh>7I!{!s{ zEiE!TH^YI49%OuaJNuWn zo_oa^ zUCs1yr}C8l^s4~uz3Udf`I!$ewr&fXPkt(6>$kH1-rG3-%x5AB_T2eZR^|_J@ZQ@v z?n%$WARK<^9>&*iwF0ZvWtI-_|gTK7ye8*w)?*RIZl7}kJ22UV%_nlqk!Fae36S^^R}VF zc0?@k43RZKT1pf<<5(9)9*I3w?!sNr5sRIWi7i=;lsckBI-3F(i42*vP9kNiDt&I~ z8sn6;B4Vu(w7BAELZUSN&O8V9KS*bGKVwzJ#B`JKW}RlEh9E30t+2YC~ zRgvWb*R0wENque$kpxRGKsz4Vo#WgC){zk&5(5v@2A&>`lcj zdVows2Fs%fXbHbR@0<(q)t+6)2!D>^Ht31VUm1_gq*0xhceFV zSR_CT);B|=RT_$TUcDDr|9xR7a}SN^s7UA70dW`R+!ecQVJE?8WmyBpP-%`awfRIQ zrnZpxdK@|UAoFuGBzaCn2|2ml0g&4QsLM<+ntleA_7oeBJC(`FEiB9&;n0KkA*+kj zwI)d%V?!GxF_0L0uF6COq`1&$&)pIOV_u%Z7}qVE*vBIY5^F0?(WM5XL7f)pWd#&+ z@;Mi?GC#xYo}B?Z-goy`nc8{^&FPKSOIj5Rq*jWDzI77-KXCDX4n?|cXP(FLXPwWz zU;8I=6zfhngQdg!$d$e3vwL@P{FBdT>Bv4u^AcwF>}2bXr&DI#b zOqiQrW@Wh>SXMewq-jc{-lW&dSXo)2TG8~nD~Pg1z+5z0zlR>IP@!ijzM{xU$iCIgbeD*gHWbPn%ks#WF0lTSnHlgAz=ee=z?u=Bwc zPCn!5R1~xlq21_MWBh&>owU$NlPtJ|6>2nR(hMjv5|;BS6-lY5HQKsQKIqZy=ZLOB zVwoaUU8UaWQyHw#>CRzPlcd^4rK#JNJ0l!ph+Sy37?iPiYl4LhL?^+St>~2(^%snB zT8V@V(a(%AD4n=Mh%?LA3AtrQ(`Zl99GjrCvcSUpVU8@#Gd4L%wLOVZRp+rR!L~Wi zZFVv+3L&92xshgjf+Gj_Ftc|LW8({quU|*4(xfl8D48lqe5)+S%{I;)!T^~Vk|d3A z=OR}syt#FWj~#j;s+bR4=E-{eGyGl@?di=-Z9Rp3cYT%V<4(sIVRr9*?0D9XAV!sZ zP5p5!9D0bA`9pl^um7+JIEn)LP_Sjk)7f?FKQnh=H;u6g08W0!3z^+>FRSx240>Gv zjyv<2VQy|d<*BGdhrZMGw*9-g{r7_i?Wv7yIN@|RSL|VpuiL`%+#$Nl^EBJ`fo@H1 zSW|R6n(4bl(2%F``Sv1TyJw!KoSbs;xvj_iY~8 zN2wK9je%c8%3z7sQ8)ImqtZl;z5{)6V6=+dglz=(}zK zVCxy@6$-Y<7zv=?U7#&tyw z&%HJRsa7N^XYufUX7)TtI#^}%SdFR47R|91nX1sGN~UToWs0upP}7Dq)zs=W+eq3# zT2Ux7V9@W;?Nz8{UHXGQ{VYM{2})<^w2d(!g8}F+I?+JY(Q9oI(qHM2>ME65gCt4F z`+d6eGbm-)yk!IJ<`}De!_w*sSz71TuieC#KfUYN3(}P|p_(nBs32*bfl95cT4@^1 zDz$7tx4%f`C{qwZC{(e9A(8UjYTvk3YmDU1 zwlQ@|4?$CLSfh2d%ZE4s3H_J-eM#}=o)T4eIP zv{ma z??ol=i9`3@POH7nIoAoBwx7kpUEikKXfw6tB*=y7ZKrbh!Mo^pmO1Y9a|>rz;NSyy zaOyK(92TU`$~*v5+fD@$?!4&}EY2QeY-+QEo`kILWW&{ZDG#7p!hgPKeMB7`b~R+EN22{%uh(H_zPLXDvWQ#ULO1mi{ zW2caPdjXVteJ#~w-DURgy^p0Mdzq*wOi#CHHJY?1rdZ8{zOJEb6XbaXlje{tQB4ia zT7oedViajwA?pv&A~c#c7M7M->a5Uiwdi#%1k~?zskR#EN|V6=RMsca70{KitL+a4 zsH950Rwa=horMJkofW1g+DvWUN>@_$FD%pV(OZ^%ob;g@@8oCd? zd27rhhCWrYq)nqaMlDg~D|6(lvm~ZRs=P8WLAl^h;xil*{%i8Q!1tog)LN^O?PF|P z8C=mkAntn3r%GAUoN-+(bV9D23|lG445%uN$<0h{+D zA|i(_Ob1ZXIM$E7ltlM@f?a7U$V0^R; zdyw@@=Jkl6@<_%k!uQKrK1l1eDs_%8D3t_!+1msJm%%8}kTtxJ0@nJ@!- z{Z%?W!K7_WQln3kv|6Q+bm(?h=`GHX^;QZ$WYIwGwEYE5$~dvV-zIB7jB-MRpcM?o zLm#{agHGI5U#tq!2N5!2gFVcqdN%3KAl zLr}@FMb=ZF^~2ozl}~Z~HNQ=@IZnT`NUb?;Sr#rBwI(;wn%W4!_~sKZ2$RR38t8SE z)|iu&7jx;>zkeUK);Rr@MMU77mt5(|Y@G9>KgZWU`R9D@FWy3}HAZh`k$Q8Sr@iQv zWw?W4u{OrA_4IT2_7^_R0GvQ$zvr*{9Zq=4`JD00AGQk*gvB@%=FImgNIUNm<%;7) z`!1Js7-uf(l%63gHVT!f;FjpNm20}B1)nSmELv%+)E#tInA!ILD@XRws=>Mq;~*LR z!GPs%7u9T$wkF7v7NSzbSTR<$q3I8*^p~MgYtZkng5=a|O>)WUt`1mP=~AyZ$#Ym< zUL{F1oxE!$;|O_gkxI1=Nu8|UA(1}WYL_(6sa6$BM-EYu9@{prr#ZQaxsGCKZh#@7 zlBCWjTSKbRjVAT>IQ`z-u@|J%YMp^@aAdhdMcGaxdEUdQ1$4EJu2e`W6|y9ynpCM* zYm8U=s2$Ea262-+s# zDnZEby~T}K+;v@}NpE?9`S~L(EiW^@Zk@$r9ba9W*yyLQy;vSjy&~+KjQ@Swqknxndh-_`mx%y9Uj`;pE9>n9qFwdz!>6>?*kU0z12Fy3w=3`k^! z%*iZMci?HYLSCuT>o3!&Bxsdj#L(%i(x^A6)hc8TTIqKCwA&35$?2@D(rVUdx9ao; z%cRw5#H4f=k5Em7RB~2l=b4^rv2JP$nX0q@$Rb^nfUclLqw>C`{5roIWqObuqb_(! zT4ii$80HbC+|nhY~oq~Gb$BV{EWBhd-XiZI?xXeK$m!3zC6!z3+4SI8Y* z&v(GKal!h^KK2Y13%tn5;*)J5Q$SNTp4ts_6P8)z&m9SUR$YN@Ifh*gDcm z)0+Jl+m$@QV#-=6GUrK=Y9CNd$?)BK_S%kA+R3L~mlUV!i~SRf^NC1&)!lh2`-Yvt zrA=GcF4Y)gvfgB{y2{e*ES;5QTH_Nm$0kXWDw!!docPR0lqOXPwe}Pnn`1029O2M` z{WKd5rq^wtT5XUiO>T0V{i?#0N02f`8g*>fiB)vwUML^;_Vd2YKI6`f-O6fRnD=PK z_@)zsd_Sylj=D8IxrJO@3o>UfT4}V|cIGpzZ;A13#)>Z3MhvaVjRhy!1(oSdC)(hD zl;U8sInF6(KRt-QN(%$6sMi|wRu@_A ztTHh*Nu^S=hG#mVyRr%>sBB%l;sY2Qy zt!q-#r>Y0kt2ruLWnq4imHrAQuQ1;e7M6rYRj8#f$X3YoDrv2as#Z~|LZZ_^ZL(RK zBGI-hpplf$KkZ(Pz*f&>hT^>zdW;CoPmt8JpTlzBEIBW`(r9fy&qvneQUu zxza|cXln*!1WSwaP=LYtg}5rZcXm?=MjQ747wzhEPhm4rPi4V&rO?iP6J4~TazYSs zO2KApj7F`+!s-h1i*qb3FEBkhL9;c1(sc%6)sV4R!H9saGP!OGW36%Kj~wK{-rbB% zPSc#2BGE};f%rww+q5RwW(C%kG`D^S%CfhuXGzqu$xEQM{coZ)lIU{2=(hQBSL)DY zHx$R5XNaur%5B7P#=Yr;?}+03JQAJQg)Z(y9qI_$@xF%wU0{|dhtY?K6qyDU_Nmr7 z)hb$pA*wga*S>gYqT;l6cBcitE3Bo%ea~T9#fm{G)fYq!rQM+!fUBiw57&9Uf-}zY zSaUGjBY~bMGBXoOR44Smoq*iNKN^O#oq$w)T z!DNUSDiuvl!D>IFU9Yn|e}sjF4)sP2trBuEWVx`guuO(!GU-YVy_`g#R;^I4)fn_M zwB+=bj?h`{(py=gQZ<}%`l%$f7KfLFN~KA?lAw|*nKLFUph+;2u`<8PWL+~g*5m-k zpm)bZ`J5B>dEbl-(Bx=V^Mrm+Q?E=ixnYcn-V!U_9s{XkRE1oG)qW4d02vI(`$sI+ zE09!csI-CBHFTPyQw?Gp$l6|Nnv4nyeN9bQXw>_RW;Y*s;`|3GcO?*E+6?shfqO9*A?yiB!?c$ee9dUZS;?ace-6dXkRN&io z`nhY;YHz{neXqrZDc?pc$9iKc?a7ze1=pQpEchXKWxECn*8M8-m3HR&>idI8mz9Su zu$C0B4(k`^6{E^&w@}PW?dk%yYmPMnOVR}C^_V^IAPf6g8o7#@lqdUGhwz3O;eI2MI{=QRP4&E zU^%N$O;YMjLoHin$tA+p|=J#QFjjIyqJx1&GSSL(b_(|CJzo{B8F6_t_i6GAL2Z;h*H+q!L_#sWBH_7 zQ=OQm)oQb{xWJLQd6I=i#wR9ev?oGG7A;Pglfc0FaI~k_(;6FRX?BL0Lo-wxD@;yp zpjK;la zS<;}V>gcq|M61r??5e#sNkU&VMprSCk*}_hm;o|aMM+MQHaT?g5XWuZ!q5KfmB(O^ z?sdpIcI%p|3W-ig5=Bx;Nh%e)6-p{(qF5TZthZL7Rx|WEJ-UNMNUD(5L02)_tMqe4mI|$;LaR}?Swepnkv61ls7%mU z-$t#@(>Zd0#pMO+>$XrGn?fsX1EtI4l@FTAMD!~w{k0)6xBUnU2DS^pKI^jEuEg%FB71-7rWMsnX_T8HcAeUpnU*%rN$B=LrSMV~(RS(a5UMPpsxbw-XZ zI*ED7L`)X%l4z7?y+nrcN|U+lHE|t+l=sNch4Ft(V=Oqy|I!%ke5xhddHCz#>5{%+ z7`qgrBcr4uFpI;7(nLYO%iPRfj_lt>P4`(h)ne1SDH`=AlGM=EHsmQiQz0WmCz`ZY zMbM-FdWhNfJ#q=ut^EgMpA|){DK> zYSC)7QRH-2R+yfeVtjg0+Q=`NG# zj4ByO#@vwu&j8m|J~+vzd|%y7cp&UF-vj4dV@@-({)Sr&F0CtJFxw*3qmrQA;x{&Ob!DdYG|^t)$H< zayB2Wc3CDA)GO;EIiT;G!z9#X3_Iib8?W zwGzpcK~+*F*KZ;pOtLgT$L!%l)ar|jO-xX&)u|YTrl1~)XtIH!T5GW7_~ThxoMV3W z2usV0Osrc+y)kZ`l}%3We3qSuY6PVe#YHh<&6z1WsRX{YgIo$XL044u!9>coq{^{I ze0Lq~*crjwSiD?6vfqrdZ4WmP#3WHynKcP`>`mgB8ouXZXxQp$l8&S&UJ|VfHJsq^FrAs z2PPM4l{UTp05Pj1HE~jK#XxB?RUxTrbe55II&QZiR4cZ)D3uCh%{J9ajc%_`qh6&} ztI^L5_doa$^=5;5V~W16lIJ}REzEMp@mpysp)*(|snjtBstW2gSREJ^78l6+UCdyW ziiUccu-fS#gF*V{TiE$vhttnGhqPXGCh|_0A_93%o)5^fK7(vP-XD^X9>UZnQH=>qrA}?bHq!A)R%ef}cxX5Ev3cs_8F~@5TCiOUz8Bmo5 zQyc2!-42TjhdFp)5ACrrCMKq>!(OIPx*F_4a~J*F<5M(SE#~KraQM(c+RbIACT)l2 z0j8j^MQjeGb;zETE;3?t(N-&P&I1G?p@>E3GVQnNCM;e-!I)OEA5FumB0HQqVdE!rk_PjvGj z7CfoY@K%%7C!Ou8Qm(#;em9V1JdEOrzFqfm(^l?-KiRHTPi728EcQY05D zNk-rF5nZKPZ_@Ag$+{gXHG`-sLd7~bY6EEnQ5AC4r`zpevH|PXO#_O4uR}lUvvJD? zM1(zi_p`dNM5R_mQMV>!CMP$rFt>o&wv~0$)9gO5p9WnT+EA@jSYBLUdEqeqj@@xL zstJR^fVrg(^D6`Hy6YJ9?kF}>j#RIr%5kMaTCI|rCQTdTFq!p*&GG>Qle0YNv$Bwp zkYn;3v$~2-5{Et4$diOYl2EHuY1A`nd5^)M$3Qj7(-unA5M@Xz1}!ORT1RVWbi1e| zVNhGg{?0Oq^dQd}tXMg=t|XXBjY@rt@u>|QnxEnDgAXyaaf!V7D0gHc4J89lOO921G(GV*LwzrfKBpUJ%MtxSS7nBuI%{JEgS-8#W!!YHx|T z`6H|x*vD9FoOWx1s&0^L$Sfxgqih#*trDiDH!;?pU~%p+`wu*5A&{|2R8p~su`0To zm`GMk^yup$iF7cYiZg66k(qpyF^ZI!5Gv7Y3XIA(W6*2i3UN#euz^uLRns3s@SZKW z+}=qp&?&v|vUVzYzwkonO(||CQ0{RkuAWeI`S9Fo4}lb2e#AWnH99?Eb{X>Ab_>sP z8Tz;TulxRljR_MiO}B3u8c8_ss7PNBse@04Z#XP&aX0Qnp@^z3f7x6%8;;|i{kQXb zzxR8`W{|d(}Ppl zhAt_G4;;XBS7YZY>FhQ zGQiXHY*u9yB=siiHXlc)yTHQi49iRNOt0Haz1b$ykYU@3d2ep*3Y{u)zcZ2dM<~$w zMa%JYJtmsCR##q7qm&Z@xniUi$c%A)8jD_iO0mYG)2N~wNQ6FwpzJegy!n$-AwXM4 zSPA|6#DrcwRy}$Yd(R*gaqvpPc9UXZ_KTZ`ucA)xNn%yA56|5=O08!AJNNcEFlTo- zMi-URAO(;8Wn7|^_(G<|IY>1mYQX%Vea!5+pGv;U#<41!Hmze~aw7vtS?oiW)X8+6 zfo(}oMTu?Y#(+d}jL8`oLuUY)R3J(0{z4g4wnD0N2H7gQnoy}#F?mkE-yy9C)wBUJ zz~nuWRMBiUNKmXSFOeh_wjF;0Cd;_@frnV?_GvY0G#X9EeNRb~8fjXgn%0p10Mio= zJhYq5Pd|%#rOM%hGxYj>R+f7tiESFNx;kL7+od`-$<~v$)0|j`x@+gLDQ59oVw1av zMEk5o&|-s3uB`vDcCYb_2-~gN8q@2f2C2&$ad>8iq&m;Kb<Igtdwr#K)OnT%J3+f(SP()U|M+?C6FMGy{|EjX-zqd7T^@BXx(Nz-u|LpzOuVvYq-HH9C zS#IyO&2iz=U0~TZO#lItX{b5CB<-@-FG zy`b;e`_ln4y-9+fU__G^$th|*H4!J=WdM3F7)MF2Dymt@+1xSoErXRf8ClFW1oB`} zenk5bH|%H+1}Ae+IsM@-R!I#Tq|!*8r>1ZiP~5f|Gp(rCHS@)eW_O2_u)KPJEEYWZ z@Cn<)p02&)@b(2tIEv~FRE<}PEY~Ql$g%<v^&oCtK&!@~Ph>XNTvi^9EVefSSJpa0>1NqK5u5h+I_#mV6jBu6(+ z)Yv0Zw7q-Fo992l^*bJ{D(02s!w(+O4}n*A2EDq%XE{DZ?5q?HE#qy`g@6tMWFFb& zLdHekz4n>-9?v10W5$k53Y=+K&X#1enjkXT{f1$83o4-S9JU)~h3DyqAK|kl&)?qh z=G85Q%n(>Ya&8GJsq2DY`Qi7mYQf+A>^b&u!1f*eVaMk76|3_lPo8~5HLD`Ke7mRf zusnan<&#fPqrYjCs zGFV4l7JTX?%)Eu1FQV`2}PuGRh+hnrySL5PGnO}ep* z{%tSg;;>#`u&7oXHh0{-eTClLadvS@(1r)6S1pw)?ZIHf3$C9D2E#r6ap3b8u=>%Qx7vgXlBHvTb)!mCGe=2NKHKI=owE9_JCK4pmOjFtl5*v7&sctKsOkI6*yd6 z`i~upndaAi_#IF=+s<*dp7G@DI|ys>c&e&6T2Pm(IUj%jS9tN_Igi#kdUb&vN7{CV z{ost{Y|c;r?#GPQv2P67?3^c$KSY;vWHG}f*N`21hQ1-!g8tijNKbm06sN;QaGDOq zy*KcQVSBIsCmPu9F$u)6Z_gv?(o&_=C1oYa+(J;J{EOSU&(vcG%9ul)Ldj;fZ3@+tXz zMSuI6X1}4BS(axHQCW>~7Gn+8+W2daeRLd1kIXWJ(rA^FsRHsmdV2-&MXsWF8GJYe zVuFZ(n2EKKsCLP29Hj~ozeYYxnykm+Q$%}OqNQY@&RAStQmmHjcDKBK^#ye`W4XR0 z&+FvBmG^*FfvR3o&T97C4c9k!l+B*A^UK(NA&DWOpi*!rNiQNwDRJmaOD50p_jjLw zCyq{*a4(%XY5GxD6+THF$e8*|)3QkMdlBy0*N(f8$&x0Haq$U^e_zv%$vbgkl^nS% z_n6V)emS5xzK-t~?B4J4o=P4#!cy=38o%T)4*#I(`o5!M;(nhdYnlE$N(eF;7@93F zzxX@M{w)`?oO)iNbB*_)MTHR_sY}dwKqybCOJo+m7tTU_QAV_{74dbbuuN`#FXXWZ zAij1IdnK<4-V#EfIW)L#MCWtt&|*zP-*+_oJ@vE4Y#Yn!yr!B7mR_-3)-+AWe6gY^ z6qy9Az`KFBFTbFWf)5^FVf!9yN9OZ~v|Yy^|H)tQ{Ht3imOS|IJ1j1ra2Om;NPGge z^?gs*HO%I5fcn-=(tq#=zsIoLpI-cFs+x9R{-|5VH`VkeJL-$~ov=p@Q6A}Gv6nAi ztDTTER?-Q;#kMV}C?-^YaA4N)`Glk3)Qb+H&QW}XyNPT+5`BTq}O4t0Uk5DE66*8no z6q%%iDG3>lheaS@2*{%3{NZEjeo3>vn!w%b7rg%b$5g84*+t3Oyv7Pa zYb&A#U_IMxq8=JL_U$YRdmJjRVwRY?enzUvvso_W0_(+Zzn zMBh4g$CvK*6wOWiVR27!JvyP1NO+9!ig1dz-n-R;JL+w5Y*TpUj(*WV&fZ7{sj0G@ zMQ#~}p1}?nQDAjJ;|n@bM_p^4)AYCaAw!jGysGe`KnN%_s7j|=DUS^X%>y9k`qtuP z0j@i*qAp90=ay zMoZsx5oszVg({BmdXcH9-AkDWfK%+*Bh@4|#Hri+5CKXeyffQ{qn0X#jCy>4yqHrx ztmzI1ws$wYef5H}o-tcrAa#N9lk3LgTtHm^^8MlKtd8bd7 z{rEN3!eiSVFJFGn;pQdFLU6HKP|r#%igxVLdB*Sl-fy!zIQEAgDKZ3(Tx$>+hLU0Q zjMiYW5t^hlft-+b2*(0}gzANaKbXAz1eD59c|o(iW^6YsmP;N!{g~_Bz^Imd@Zl#6 z&6YQB-e6pYD$i&~MV`-)nZ&sfjiu0nGApsBzu#a@j}ijw6gRgGKC5~3o$phh zKfsAtUONniOlL?b=-P&09m~Z6k!tZ)7Z3Pg{VkL`w6MgLK(b7Q(-KAAR~IMzz~mG5 z2}m~b_qW__T5M=BHpk17#p)qV zbIa|kFPI&6RP_p7&Tvu_ghI#+DKtvQ1&hox@@md>V!7aO-e89jZ$@0-<3)=J9=xP1 z3aYXo&m(KX;gP}OgFGe+NfC9Kl6zCj_q2eVEVVNA)j8twOqUBDJy|d|J9fJpuD|?( z`SOfm_R@t zfe$K9%+v2tOzU@<;@bW=#YVTx2_@=+KQ`ywKjBp3A%}Zy*e7K|9*KIB1BH8X$1#MG zgs1S1)$p{$llKndlXE1xh}@~#O7IQ9()*_Af5;Nii+h`&e>oWp9hhZcy3!E`D%}7>AM4|9m8JX3=$C$P;Na2v$Abhmp zWkRHOaTjlP2@{|MXgpy&&}?6#P0N#~kC@L_+}s^#y+&7SZudQBWkzt0S-oOA7?du^ zGKp|KneUk8vEy`icgJpXiy03n0wG9ty@cq$^!MWCk!o3+Y|H(k$!Tc}#3cNl}z2Ss+!8lsX=!N+M-WkyppGq7RV(XN@6POK^q^m=_vr9o7sHkR&pk z$l~Na1wTY~?1>E1!!X(0j>$)_5!i$!6%>mV7j^VlAGSB#wAq$(M|=R%4Y_xF<* zIvklPq-%Zj*G>%65^zcX6E~WnET1S7`#aGNIH;RI@Ir5`i_vS zk#-|_107UvZfhbmXRx!WRY&3snTj{})1@WRq; z@3>s#)RkoD4!pj-W53dE+8UuSskBzrxm0) zhAJj2R+xeVKK^sCn$al=l~K(tb$%0h$YzJvEB2#Asla@mGtV1*cf;6kG1(HS7ctcr z;=;l?cWe}~UV_lvwga82na@fVdB@OPGx!Wuo>LU(LrK$j@!*GYPaY7Y)v(<@lrp$k_Uv2n}-}?0!!}LDY8)>XJxZu+i7k#c1bJ_cFs;TERiHOO^O3Ee#z>5 z9aDdRGafU>+lRA;ap>sNZ9?k|rE-K)C@snJoRE@}BNF2$II6(fXqHeSM+$}3F_3|e zDb7quy0+mbpZ+C}o_xS;xx(0}8@j2w3w3l<*krA%)@M}91>I)L?d!MX*@pGS8O3~o zBa!onA)Q&hWL}jVb{pQldCl&yn?FgXEk!z;f7tj*<^Eq*LZY#_$XAC;eN!wb|b5GO_th-Cfu+} z@|78SZeD)Lr=NyzpWGp3Y)lCvTBoA!?9o1YPOT$thhtPV_HIammr3@B*H@pesy>x^ zN^uG(Alzx2f3Fndge&40A0}Z<8>1r(DVwp%d&Z%s83%B4te&wI6}hl1=RKz1(hfbN zc1TqsbcvS=muOvL3VI8L2|1flGf2roJI)p@L*H;{-{A8(s$8(RddPfP(Otjf^~=vF z>oxV|Qz+-4HCZLegFtu}{|=VX4p?XK&f|>5jfSC#qodLqghJ;r?WmMSN_DS_Fu6N| zKud{M9xXhIz}qi=PVPs(_n-ZKoa&9E9}UKV3o%Gzrn;q6-YHP5&n{WkYxZ}y+`N2E zUTs*MU!kjcVn+vp^8}$;oIfO=FWB6^=BqD$&T6^l?Cc>y=NKFc3;hjd_lhzTcz3QqYyG>}*#3VU|029JBoP65C`+LX#{pDdGymKgr_a4~c_>{;b_@U+1 zi=T10eZeZ1tQRvDb;)Y6KuXEW*VpV0&2bT(Nlj5j>Yf=5-UhBN&ZsiD>snN`LIjWW z4q22C3@R9$?Qt%UDCqf_(BGXOyj+c1scBR!)H$@W@}#GHT2G+vJxdtyg_Fr zqL?Fw19h%({ek`Njz{Nfyfp;rxO?-QyX_rgJCG@fb%C4h4wcue9zA9K;6uc0#c(g( z8Kwnh2$-RxYxb;{OR}QEPN)GfIiUhW*E04kfB9$snm_x0|DV5wi$f*jH*VUjyC_La zVJxkta7qN*$7`;_I-j0#3NNBJ*prIA#i^b?q#%M$x}*2$$0XfxsxzG+J_4DvGDSde zGZYkBv8XD}s+OVI(~Uh&FX?p|C6X#*QT2@7hOT$`>>Qb|Voekg#4m(DYUV)*1_9Pd zaxte~RIKcdp}l3;Z3)F0vRqL-shKq!Hg8|?=K0U4*B8vsE|FOoOFLEcq>{GcBDgq> zIbzx{c$~9%V{p!5+79Or$l%F~3?U_1QIO>t;RV4-jF9vmS_g`fXP^8Ug;sp|V#C#= zE6Ut6F9ce|f=-a^`jK`pNl#XImps^7vwm>JV!h<{=9<@EenGuha&~r(E@zA(#`~QY zsC>qQCm+)ucHF#q$!_-<53U|iFG_~}YYuOJMll{J<|RRgNKMoQE=7*x*ZI_zqNZI$ zdO!wzwBiL%Q0f$95hqW*3a90=PiyHQPFB##f#D{UXsW{Ui6D1`WyzBab06|_oZ#LG z%uE5>kT3_wwBtMOj;}8dzj;`{Yw4SQ?S6aB+vlI*+dHlnIp?dI#trj zjwY622v3=1WLjgaLF9rgQ}k_%F(bJMjLnu1H1qiq>r9j_iW#cgQ%FJYM{IA=WkAXT zXL_s{sdCBCT+{5ftk*S{k3VJzIWKn>8x~0A@MZ)*A~FqH<3pe*D{?95`hhHXmh*}q z-`=u4^mKiPRFQ+eZ97IISv~j;_1P6_w#4OiEL2Vzf%ra*@>JLEabrhWW@Kf7o07{+ zi)K&XHHC@2O2+gBl0qQ8nyjfPk*Dd{Ba8UpiHFpPcRhqCQJ5eogru%C zMW&EgdNVS5M^K7qA3fvk>({*e>N$t5WqI*1e&4hr%M@9jL7^$sNRdejt?_2W7(-`9 zMjMb>#^Was>DmRi*Khg!^PjRd0dYOlo@(Uq9%+c1TVs z&52k@z$cVx5I+68NGZuwDj;O^b93^*$x}ZTK73uOn4}UJQiat!VV3Y8@ZY^p?Jz^f zmp}e@EHb#bT(CM@QZJUMqGme;zPjDxtfo+&Ov9|0#l^E7$qF5NES03HN?yNu1471L zQQtH68AYCB27|8V1nn4YM^RP`PGi~~xqu2wa2ji+>l~p9d>YEa1mCibvEAY9K$dCpvO*TcxATzBlw_92nyiRk6gV%_ zq3w@}G>?zXCqbZy?aH3`aV5cr1fLHg=}yzqNv7(els=nekr1D(K21>}6;Pgd!e5Wo zB4;$-V~2rS=gbz8(i`^ufo2%6`I3Vu$wW>$FUU>9*l+P;izpV5FBlV-ce+-q^hCE_ z(S#f;B#S~)7Y5z6^usOImWXn}?CcRmU9-D>$(vU%neTQi&mU0CmKfrKX6nid=_?kQ zCn9w(PN9k%sk3+up13I9(~a?Kk!wMg7wA;UCG$Y0uXyw2b6)=ZZ<)<2@>$JbE!_yd z?PIICfI&f(Ycd^s?5a$oY@i=4MNu%TmYgq3cAGn{udn&)XE)5(=d8{jpj3|YDo#Br z4FqC8?X0jzVWdFAALjtp<{wZ@SU z!Z%{z$IyxYI;D@4lsh5{?gRA2#QvDP)sx{!9$!zV32j;wo|3Xtto#^rPc1y}Gk3iA z@9_RbqZ?W-XOhLdVtsbTyk0Sig3XZ8ha96iBt5fSQI(QmH1Q#yYsPLM%R$csZ+Bbz zrsMMJlDyF13^Md&Xo9!6-jSCJOlx5rD65j*OM+<$zM*Yyxjb9*?D2Q$$H48~ErOg% z=xIqrY>bmA0mgJ>c$D%uH{eIh7eDzDT!;AWU**FOp7Q$5EqB`;eaN_Y_CwAeKBetP zoXk;a`6rHy`qX6ZJndnJ)Pk&<(eHc8GQM_#08PLR9YcG-dqZB76LU1Vi`X=uGgzCuYRdzb6wOQ6|D%;vP>g z@`(}`#McTgCJj*qi4_I6R&&5H*PhkfG9O!-{)V0so7c2*PLY+&bwlX)blqD<*Q2sI zSyte@#3mS!z@t)wxRZ*V*R;N5UKZ4$L3S(lkvdNfbs4p87rws)3XN_3{EF4jDIc*)&n%gfhq*u43I z^~D3KyhMZy=QUnHHDB=f$%k}uV0ZV1n{C5lx#V0|X=~kYU&GA zCz#T)7$#1!5#f3|q^C6Ny&Uy78?2J=S;{1Lgt#j?7Rx4}l}t@06V%CudrjfNr^VDX zc~3H495^B+?)2LH+SDBG-THpXBJuutU1SOs`1=XxZS2G+sLZpQF_D<4ep85f^XgzX?n&y23_gL>S=>T^wzL-6!0&5Cc_*7mi z1X}nME0<_b`th+x&Lxg>2oZ70#IZh(GyZ69k71i=>2d^uCdHW*R%o^cdgEB<85ea! z+wEz_4yzZKY>p8%sw^qW0omSRh7A-;RC$IFd3<9Efzm441HHpb$tVP)7icY*FG`BB zrSIO-j~Sv|QO;Ks)tY{H&E1<9bh{mkvn#6gB~}XTv7k1Ef`UQ>fs@fG5u8AWlq!?~ zhrl=&F|8uf76>o~hZT~pw*SY!eNg>b=9c@3Lb%Avr z<2?O1(sprz%(O<0fxKSxVZCI3*i&eM7`HUN#fSot<>)MDzIsULwsg&&{_O@kTC8zw z4?U~16;GZ%MfyFnOwtC46=nS1Cb=X29UF0CkRlwXinFloH6ze(~npsnUym(?T8&3 z@=|kte!-i&19`cOnA+VdOuMJuANc6w@9~}Qf5PWqKBw4$D8{s`wkQ!mD5T2CbilMb zy8gh!ixusDLl}2#-gG$Ona$UH_Vefb-QWBSt7lw({A;Wqe8}Jgx4SJxS)hvw?@9de zG#v}D<3QInkGg9};-T$HkLOAbp>rwIhN%>!?IYH7{7Wj=tMqy8}ii-zXWyJV%-X zDIc44H_iegzH+dZbcMvNW4Tv4shDXJOG-COS7 zyk>uQ!}-IEI-ZNJteYyTqz?)8|7*7{5}-)^HIbrOeBC@K_{5=g~JE1m2}Z z*)U}gE&4E$DH$h0sgYSmUX;va(uTcf><6rKjN^z_im@FL!IMda^@^eQyn6MPb~Kzn zxa9o&4CfB)hdtL_ho0Ar-N4=52H7;ceEkxwH5XS8P(m}yGg_}P=p&YMBEQLrS9FiT zaU|P`s2?*??$ShkOcth7TitVKFm)GBwAB!;jgyn({(>(ec9X?VoG6a|ex;T7Xaq9E zudNr~*a&{(AinRH4!`8!cFyBO&SJeLR~kFE1ks|jMrV2S3s)7!m2~}{DvQ*`o10sj zX5{?xGW|K-k)+r)19M$4pGk(kXHi`tyg&<0=o^OpHJRV@^x-Au;T7kPo}%-TcJOq< z(=|N-8QYXnkEy0-Xz#!rcyzJg7eD)gn^&)Jw#WNEk|n#5LkFvik9hpScTw{-?PzJ+ z14UU;l-2S3Nh;C^NXBlD89L^(1tQNQ{AujTq@c)hyc=n@cLY09&F2)=f{<{=u|dhx zH9O4EemmJ6b~N$Y=~YV0#p~q#DcSo#u9F-R1kRDv@~lFP4R$<$9m$IYHk)Bm!bYUuyA&#NqD9Fecr-cntYGFk#DZwsNWI$(4GX*n*}wp~xAAQO&E3bYbPrO{bnKA)qN#Pls*NJb|p@|^i%!Ryzr zdGqEgUi|d0INZD4@3@zSun4#hISFfngpD;UrN}$4u9Gmzq zI=H0Cr*?23jva{scPgVjW(!ZujmW3=Olnvlb~R3A3QC?{DM!SpI_cixKKTD$Z2Ug; zPNvE)DLg8qV%qztRqpo~ax5!;uLbX&liFB^Pz6lrS(J+N^+UFIZ`j_vid~19!iAjMeS?#89)0%* ztgk-A$vomrn;m6Yk{1=ui=%}yqz7%^w0PSyo6nIdC;0dv9mbKW%JDU3K zUe54A#U>~r;sL(9Lu<|BXCG5Ps=s}5N1myqCr8t}cj2fnd++Z})Nyg>k{sd*c+au< z+j@a>GXB4G;Ck<{KE3EeiVII~KpD5Z-n-OB5f8H{iFi~n2m%={$|X}9c1RDCX#h&@ z5h1{$2+Zk5OQ}4w`A9W3w8LARsPM&-Q7utNqGA*!)uQ5j+_FF1GME--OZ2?r(f58xv%TZy_66PZpR!nAusnZ&R2ep1{bH4s zLQg180cwIf!-N&A|nP&ZC{u+2idYNJUVIT^@Y0W~qA*M}fVU0(8zJ11PDE#RF3bfCwjM z$I&mX5nR*gAP3coK-v9tX|GtWNdkM$K<1bH!2mS-$7NDvs3U$ut z9V#y{W<(lKRce&Z7>s9hke4f*ZD|LK$_rHTyoY2r9LF&xfz#K@ngM}feYU1+b{sZa zto1zm-~(p$l2_R1B}0&yF}kQ`WkFGvxWIAfkV%hj4tty(SuU3-sj=zX;*CW~i5WWj z{f?q6sTOCT%9xE1(X=`AEq&jR7bWxgg5UoA|C0aBAAIs{TpY@@oSVRP(5Rex+t@l_IWtK6^MrK1x*T2E&8mDJ;vZO3>bk-q;4dJlEWeY-i zj#qj7vk(v}!HrURX%_^>msGhTKPynf0n=RLhdH)dldms%RIfPfZrR*?MSIwAc7DZd zd5IHwGMkym!bYc4RURidm$Ynkw0)hLzoU;-odA^HC(S!e9Y@@(I%?vANV1!z&mhz7 z2t_*>WDvC0Pd^J8Br_y0zIwy{?v`A5$~vd6S1gwc4sFlPX2)n1yWNOjKzK`;!S41I z*I)gd^6~?+Y#Hf4L0~Q}FnJ`pYU>qDG6WqN05@!Z-EigmiX49dH1<$_! zBkJ?V7?ELpz}SJd-7&A`WJMK?0_lM$i3{AmJs^T*xmtkKnB=e&O5mEFv1>4HWI3Nv z)hnFLqq9gx$+11`3Er@*m#D0~$8h-;vO7vG_-Ft5KRF)KlONRk=tDhnfYUWK9=^$5 z7Cf0x(nv@LcnDGU@To>AP2SdfZ189&(vOXkc<_n69RK6E#L0AQK&i4G=LBA8tdpsX zK;eQy_}DffQ(383l3-m*pDD(m@m^vAl)0qJE!o&H_6?{xV_qXvjj9xxZ3)gWHm}gS z#$^>&6p0ZX2*SqcIvU<+U4*n3RYp~e^oN#y`xSb&Ko#eloj<0oSL|+Iar5dG{r156 z@*(+b!HB}ySQHDSLr5My)*%^oMWW=znyPz%dVIo&aw?Ba$GjK!g`x?LKf$dg&6m_9 z9w$#yJGGg*_8ffv{1w-4u9;_^of2H%!mO;2S)LlqbF{ELIA3snw&ddvC2iBvZ$78( zH=I5D0a<>A4HaHw$EY*jA%suGzsYu)T53cp0~UPqpquc-B&8C3u0ghAflJ7Hfn6)3-c({E*pV!LB{99a@5@$*LuN z+fr3C#<8MrN2)wSxE3jTD($KBK(pD<>^5}$0cS@tE!j7F4xQud;deNH`dwr-qj#zA zbR6m1hPtj%c^Qjfq)J_<@n+l|wkV~j<_m%V6C6q?GNBp9p1Zr(lv&34*(F&~MlOv9 zEd}G)(zgv+mNBc(@j|9SEc(~KmF$ipll)Kr`R~V;<;lMs(gB*L0-x^DQl%!3bT#x| z5nRA&f%oxh8bmy#osUz7^#Si<9N47;-nnS;n^J1Z2DBH)tE-PqM+gFC7E%q6$LknV z_ugYd^kmDF{Ifw4M3z#9Q&*k9g;-xd`amW|=DA>@2l~EY>_NocW+cm(6vdp2haXZe*KFRt0#HhG6nKVGDSrY;w#yg(}hIC7O^M;kSM1-6%r2T3pkeb+FrbE+ca;nk8q_=A6n z2^oL>lb7t=0;g9vQ6{%elsRH~ZIXagf)Gs=W8xmfE8K5fNt0OOn}`!6`5u=;9&dRQ zT~CFCv-Kw#B*^>iL*QLnMkWxxy3hEy_dE#iT^_y%jdz^>CB_Lff=nu!u0zywd^U?n zY1=XO9oPY#m*mx&-g$;y9|I(3noJ0SaIu|4R464G%)q=TxO#BKp&j__voFx|89`O( z%%gHm-x+!{l9eUBQxthlDefrBIg-HL>zC}e*9?6hWvKwyn;m2Y=g*#U_2hdAh!hd7 z#`HAZf%&{5E6NmLo5E)SH;y#>J$ac^R`cU+T!`49G&Eao-@aloFIZh%;zWTB5+P$1 z!f@Czn3if@lNYmS(M`leB?Oz>*L?b^`4+M}gdo%E*jOyn0UT810Efh4@DKwmGQGJH zH^QqFSP25>;wbK%i-&WFZzvZ6&WU5}JRa2XkhR|9l*a+qOd6vg*U^raD~*#U{nq)2 zqVzb74Vbi`uvW$cS*Ca?f#9PvB`A&Xp3w`e%;Gg~Hd4C=V|VnnCzMMLVMZpKoc4!I38CuQpWCZDt>}{WFvRsh#K~dxtMLr<<4W@fV-{)lYCE0wzi91 zKe*tZ|NcLrES~WfpYM6OYq2uJqmXI05QqULF&)~+=xLmGgB16+b>eIJLnYr~YRGVm zhfgI26FJZO>1&fd*S#-kj37tktB3%bgp7^6Ykc^I9(~^@{qFMcYg~`hw-hJK=w?t7 zEds;XAM9^Ygl+jJ90LkA%dsxJ03iIz}a%i%U5r> zz1t!48P-8j<^)N!yJZ<>>QZ8d4PU*wrrB>$(xIf_(DWR7&-&pyoF%1xdF+R#4lf}>ZsAc=Ki1evQb(HQXofHX_KP$6j z^Gj1VK7rvu$v~boNH4$zi^niJa3PC<6`}E7rOTKCp|L^HdP$}`Cl2GhSnP!X~< zjhLZjPE}WAzM*a20CQ}%ig5K5%#p}+=tSF_2`~hOnwOO24&Q8W+ZTv(jh>ycxOl{D zv7)JU9h-|%-f~=M+zW0y*34i%VTf99)7KyiUc`pRsdXz5d2gj!A zxVoH^%h;;%um0t~<=_9izv936pa0MJFMj7A@h5-#C4cwwmQk(o=xDdpkzFmP9>kEG zENSVfNCmr-Gvg%Gd~LvpQTyYQDoxYLsUxQT#&GPS4EK_SB6T;0w2X}wNP!@7xR2ZE zdw#p{j@|CP%fownh`BPR5K)VL~vx8 z=KSo8vF|AIjE_G4kVDh)=}&(SLNc%CpcFonh@t>dQp$k#Be^u#u0xp_g(`Ua_AT4p zp1zCHhINA5T?a+Y(;xki#l>TqzQ@==CUT?@41Gu2@0r&%c{V>D zKE?#dQWBiy&C3_qape5!L2UVvIUz`tl#D}1+ccC#Mp;#OsWASu^u>Gjhduq_K$dC7 zZ)2DRnOY+Qr|sd?5*-rLH=N2prztFuw(;rbPV$H+AU!DW(^VU^j}x*>Qie~~J@3Qu zpbjCRm55;c07b450_rNm`p7u8E>7vrxoDUd(YqavEZ{&0vF*hLFdl5MI4_g;St3Gg zp|PT1Bqwu@BGb&W9yhj(-5by~HlMS11xmtvk%KXe!yBwGv3h}5bG(cPCGtdD^Fm_0 zqL539MJU{Sy_`me8OyX#_swxFTeabv(=K-*#mS@V}v|1DJJlg3_ev> zMIBWoS;J47^O1oPuk{X>ER1PpJ@)Cv4g93TN>rNMITgVsTHs&|4?g^eC*S=c&;R<* zD5WJ=(VHB}bg@Xl1xM3bRzt;nF~d8F~_#?V?lCSLQelJPG-6(;Nqq#t`L&_PELY1G7`NSuSeki#gA~`ijlnAvGW=y!Di`8MEaK<1C|T$b~|N0U1WD9r*m`KjUKkn{4hj zjK-6fC2c>_4xaht$6S8!J#;x|@Q&U%w9e5&GK@W4zh_Y|(OGdU29Di`GJ>D_p5=0h z)H;z3B~l88zUTJMOR`MzU2c0{Wp4m8fuH5-C4Cw<#R2ZIz*?i`1XzHRUU&MvOV z%lWtTkQS3DNSv6b!+KhKgqRAPbVLyX(nW9cR8w~!QR+gpSrK9@28q?+(p2qJ^2~XW z?0P=>e*0^;qkpN8777Sv!wSvdYo3odOdvD-mKO-C1l9xL~6l zkPM3^$Qy8;;(i-bt2n+kHLz=?O3-gx%=Cbr{9 z$FuMM8vD(L&GR2qDnW1#Ayk^;1xm%VU$bplR&%6Q1nH^gHM*>L{_+j^b|9ObQEE*H z8G|oSa%!ZR+$$3-NgP8=a{7Nvw!+htD&(ozehS5Kk5e6zCJ{?0rfRPw)g5J$2#OLe z$tN<|(}E|{lIHfy_ge5~g*cXpPq)a?2DXRrjlRQaC+tuNSw(-e>nN3E7~9yY9TY-n za-DFtUNP(jup@{_g8R-VpHSuS{L3%NGR4({Gt4libgCfF1f`Z_LJ|6raqMue!}dMb zZ{JXAMfZbGI9o4y^=8A{+a1N?f=8cx#O&-5mWeF$^7t=0Lru$+I%m)g671 zG>6EqUapo%sc{~Jio;d2-?HCsST2{W&(0VI6FWNd95eQ`ZG+H)#qtcVQUi~Os9wCK z-yN{dP?Z&VQ5^wH-^y6{*UQ|J!$7?!ZRN%3RVt??j+{1&M;nw16XZR5TjRtXQq*>O zVT*WRrhgAAIt{#+Y3T@67To~rd4X{bXFbNAq!Q~b&M8LcG1eyyocQD1scjnxIU*kB zDdHYkBp!u|GpCSPDcSoOxy-4mk$E^Unp?Vk4*5BQp3#XJRbi>~ma*N@wGCt|q^b!b z!+V7a(SK{DLnyFL;YIXO=XOWvw}iu6kPTwCVzEA_sF&<_*KFUuV%%?7T|6P5pAlph zJ-Z=QFDOAgp2OEHXEMQpgij67QYA^mr!dDfSH~Z(#mUZOoyVAlzT07X8*e_kCb`pWJ(_QC{t8?y4_8L0q^fW=0d9T(n&i$ajCzS z8y6BK46i@`YrgvNpMS%C7XmyuliVIW&Yj*a#zQ;Ca^!bsplCfz`eC-j_KqT0a^dm) zK0cUL5kJ2NJNoF^wvNs28fz`RaXfkUl&dEnr?jR?Un{}bb=2o)2qb;);-QbjyOyqL z>DmDiEMI*7IbXee#m#Qy>e=_W{NQ`|Y|a?sYfMUob8*Nq<4D_gES3whEXTQ2GAv_> zaC6w8gkZi{#Mge9T6sL1n``XYarGd&H%14;U?_^5wm)F{o>?_VS5@2@g%}-=pLd`; z?8vlWS+5W($EG18witbD4{7&=M(NHOu3{>I2qztan(iFjixo$GX5^Y;ubPtOa8|#>dF| zB!g&`mX5*Wy}@~h^%CP9CJ1~eV~Q$dSfR*;B2xpE=@`40NL>($HGRl%a!x&~II}&Y zInWJzj9NjqCMXTTqQb;~NVkii(RziRmqc00`B4Z_Y5#ftU$Q|kF8cQ>zi^XfUX z`CHB}9+8zRMlYg=JP91$r-vyv>8Yu!PsDG!I(Qc_V!j;@!fXAm*D zIPO0iqPCx_4AbxU;_v>PyD$Eh2TT3lN&3}|8Fw*F)8O5}Y+l9XV@MC;loqw$#zXoK{^0jmuGhchkmh75_?ps|G&~h1FvZt1 zvqvazRIo(|Nb6$IB7jtrB}|@@j_E+NE=<_pq)7{ArNVg;58+J37&>5WoS>Zx7^^Xp zA3IIe#(73-8C}3yi}!*cQ_x1Z6xxXk$e%^kkb5tD%Z4r<5JRbeQf2rDr%@ z(WsnCYO1Orw=IWm%V>K5CC9a6wQ39%%IBa1m3& zbqcS9RF0e+B1uaRh&Wgf_4z_NnzzsS>0kYKi0+2(KU!1IviEAzRVnzjXR$P5!k}6Q z*BkfE9b)>u%h=2tgHgIfmP>|VOHpLp-QAIw3q)}2ZeLKBnx~)qfa}eU$GPR|!4*IM zYERHP?Jyu*g9#&TZ>eWF`_A*zpMJ{zaG+@p>~8Pa-n_-yj)0@-42J=h=O41Vdd7Tx z!RTY@^u*bjU|@YeFbqAHmzPMLVW-=O2v}#>Z?}}Ql35j5(K2yP#-X7-Y^lnEda+9S zvOp`vet*Ydzh!-K#;jbY_r6D}nEC9whOz6(lwz@5#^t^{eI>P&^xYn3`fn$@A^F85^hLNI8+uL`ph_R5BW;U8^MCMNLo$m{)n! zqkT*zS{JQ;P6%A4@D7ag>2QvzM&~`oIYuKHUBEewaRFoeF)=y12$WJmp(p-GaF`Gn z+?bH6Io6j1k)x{_rSGtP$Jli^RnZj-I$x0MjCtKr*_PJa;CzKtGo&gb2;ci7Q0Ul_ z9_ExqMX5>{HjLv9&TP@untHxsUadK7uDQK=#o@5$^6Dw&VtwQ(iy%@|I=W|s5(!L{ zv|jHRy`}Hl2=(#tI$M?{x|op{MVunjlsX#2Ff--gXPtm8y;P*Sk?uB5h)~2YDOW+q(s|2VifoSMxq|; zLh^wpwn<Ib>F$AA%glYRfaZTRoPCWg)z^j1t0hv7YB6XHc7eOT?!jHWC;>W!F z^v|i~z|$w^Eb9fxult|xCkwClFj{|nnL8ioM#!u8z0;z5H>KUE6SWc7fFD82$l|wH^MPS#WSD1AixUJTV3Cvmw>2e`u|t$VbV(FR8E z8J%Y|0Zsflc*q1~-o_$cXJgY$$QZq1lnaVkMQu99?tp1Ke7R<1Mz7}Nc}7+AlwE@v zJB(c7^&C`|pz8J*8c+l*;8cN{T~aaP`z_t(4JL2N7FX1lPbroc>~3Ch{rU^a?Q7Oo zPpPT}){A6SQix0|Mn+Y#G$*ufAaXr-yjIayI6vMerk(&TE*$S`*FT_2ZFQj+B* ztIKn$qC%@UDLUtHKF|xz5B~8#|KmHxFZP2=QZqi?C)NaE5QdJJweVcc)btwE+hEB;jriGY;k-rixdJfgJo3~)Uy(A zEt}ie9OT9pDPZ3X7zgw7XRIH7LKhS^%gM4FJMr4n*HB4G*LU}d{L=JlL^_P_XF@xT73-~Bco((0WFIlLo(sP`E`-;qJY z`zP*Wsc1L`6^_XbFHY$_aVob`>BnYSY{D+IBvYvbH^?+e$BS+VFpefJ4O62`@L*hY zfkZcm$Jn^Y3L#*_m}z^F2^#Tm+u z^!+AIHRX~nCNpZ}}>JHa1N))K@> zrZj`G=rSYEa!lW|-SnJau249vu!M1pZjRu|B*5}M&?!MpeJ3z0<<7m4vk7hBaOnF@59*Zlmi{}_Mxitk?4Jh(dN(ZdJq4jt{_ z_};JlCV%w*`M38HharV&zWJ7zEU520y(eFKka3%-MI_&ucEhlL%f+JL>5~t+*^b=o zu95Rgg3?%Lu-2hfMvy8}5xoJkW08$47jwF<5$c(f7>-GO0$U_P6X&F1NQ z7pLp7Zy5T9JdZ&Cyr^(aBzTsi+3)dYOw)5k5c0SnCIL?SW>44ckphZp&SG^Dt^eOf zcE@u43;ysA|M@$M#P?-f-_22pcO(+=o{zsfX@^tQhD<+fVo*-r)l9`&D-}5%MXsa& zH_`UIj&g`g4IP=z(*n^S34FP8N0^iKGWx7dltY5|6i#6>g|VJlVd?q-sWMzH7)FD0 z0^iUgNVl+5Ccok5gY+Ny;!V^n1+EBh(V1 zD@I~zuN0@CofV4C<>Y$B?7SdvH*EKB=({b|@`BlX$!u2B?{0bh;yIh`EsKi_5DFh8 zSysjFys|{g)P$h~-Z_S`XXv^}Qgaq9B~@8cFJ`E$K+6mt9L~FAos|?aUW!Dd=}9fY zdpc{l`tUn^{2Tw6AOFQ4v62d5Mx0D-D^{WuD3#G1dKSwSdKMe18T)uR$>{G@k>Ej= zE6B4H5l&7GKiTt=9dA;fL-?8u;qSqhCJyy|(5OnMwHMLTu9QRt!_AjJF|w9Nu$6tF$i&K9CX6wx`>?!i^g~ zc>0WLR`bQ{O&n^RfN@0S8EA=81xjmj4c7E{7s!NXJ+IkZ-*Ef(6=T;>XvttkZnh2i z?2_;N%5Njen$2#9RFY~w$NIz`5FnDC+_fF!5J`32&_vlRef+TB0G8!y9eYB9LJCi_ zy}^zHi{%Pcl$cbZ7rbS+-ywphUetI5L)%iQ3{ohj>l$*Ev0R_W2T>wUN~Mv&*!OhJ zo`7SyT+k0AI;-$xshap($nL1-XZ+zG{+H>*^#6cEI^3JC{d*>8`OcxOc)!)(gH%Zp zNuM{Q2J&Qf76OVwM}KCJF@o*`PQ~kEWP_vwJJI*zK`aO^PShqH+(rkik9I+y*doRl zyq65QWH1tx#AwZEJtoN^g9YoOFIZVg<^%?hvr(?FNOVzgmX;gcrh#IKE@MG!sTAcr zBOeC3aSN`e$mTeu@u+k_I|L4`70zoqHz%udF3LIW_AQ4uzrfDVkl7sPVX?l%jV;^j z7ig(?^!Q_D%Qa49SmGw#jU!#((2oP&1#*=!%PVwNkQD`}7y$7hVEq^$go%JSY2DFc znL;{p`ql}?0N?wq-{o+)!Prr1jbmdZ#F!x9-_pEcO&=+=`kX5 zp|wyEKd*AMR;jfodiSTkK{+`{d@7aoBqvLXwug9xhZA`;P0xu6C_G+*mI~1~{QPhK z9ottw=HW_lF|SZE@WChFWiwb_?iC_iF)#qb*A{@&Zv5qq=k5>}-S_wAnR?GD9XyOJ znU3i_KeX&_zG7ZVo_y~II8pFw*VBiJl7TAEX!{1OC0b>SHZpJWFrZYx1xs*-+t=6J z-CpBdPo7I|w+*co)R!Oe_@f^n%QLq79Ue(pEu!QjQ)O1NiS})aafZcmflvzTJXM(^ zgJ-wdBeh~yFYw41UAH5fn`?ydtj^95y1*ilDq=_5!xpV`=F2rfNcy&+tSXfB?00*t zF)SAgvb>0B)8xhxQsSNEu-{|HfofJ#FV1MYj?sE%ivsX$Z?F0E)9%}+jevhb@3{_1hDzYqRmXDNU!#M64U5uGK8J9T0yJJggkcz>3`cWaX znmo7oZp-G)ORD81=U30rMZsz~uzmZI7tepeV!7e$>ItJ49GVvIEJ7>Fs-i4s=oDvn z2@5Ne3r9+EY$%bW;71C@kihs82P1wc9_%8U@vFb{&-s(hmi^o3%(7UHiULp&N z|$pxtfB^NeD?z#(Gtu-$UlTvL=K_4yS(=+wO;Xb%l$ zXjs%UvV5M3K_aaXYuW9$73D8nx?0&>vYOE z{`>##U-3u(m%sWp9@6hlz4s5?cQxw2&zg7tQ1s z(Ts0A#=__v)(Wh17zddQ*brSN2tkzz%1YBW9mBZ6j2&6E!WJb53aYH2$_8ZLG7PVg zY7SWqGD-s0^o+wmKa3HWlWXew3Cl90S{=B%zUJ+#UvPHyh-y}oJ^TPAbMD^0Vt;!} zKAUm*iAxRp7imGDUWqJp#D8T4O>WSQ90!Q836R+3Gx6q+pI*Vui*D znQmHB0YZA1Pi*W|Y8>~_QOZ&xMqx#Q_s7MU;^yTq_~NhsoZ27w@bMf?&v!q1!mt18 zukzzxyy7Q6dBGqm7PFd6TE=cfIQI=%1!qYqG`;N`13 zjLIRaQidi&&dwS4HNH^o zXxk303yPvjhk|Duhi_|`n7H$$9FHY)EEf-YIGxmj!EqJ^rDdfO!|Ks1}@uP?Q z>wo(v{Orpc&n;JU>V35$u-Wnb} zdW?vmjv)KxZh+s7dV|SoC?3vGI)XN$#HKU6+Gbts`TDJQQ7(+EH zspbouh}?IH!dixP=fCb5f||Asrdk;wal#KUIKDmb{SYdmbI4Z+2pcI4zQvt#DZ+ z+NmtUVVsw#B|T2xqYW7A7>&c&=*{kO%V1pmxU&p4)`eNA64XghWP-AEbi>GCH-vnS zA>-}dLEo{+EX$e44GmgV*&@b`y&x!=IwpN;)t-`!9wF7qDW4!rKDhJ@ja`FG z2+#C2@2%v+AN&S)uV3)u$A7`R&Hf&cF>6yIA!YX-jm!2@QC zGu~_)no-5lVHJ>GAf3lsgB@B-XAu~%4d{Zse6e7#hW);wPW_cJt#`t~c85KLKwYo!Lg4~Pr8yjS^v!{@^K)cgftU16 z!}jJSWvMuS_!K7#oDc->=(by|v(&5Dn`pg9DvfiN-ENB=S{C)3`SOg>Ckv#G5BGMz zrEeOls-Qld$7Q4O9%}-|D~yW_kf^upXRs6iSd6 zC8P0--Y^75)9<5YNv)BxpHe~H#B!!zW=?C z*lu=g@AhoAEmjqL@S|U6`QSskLx(X@wy?xb!R5T9$n&@)7tyw-@bt}=;63xjGP-_J zCgHG+J%m+Nk!1zm1^WG#cDG?(*DTM@F{r5bn}Ne_L!}jGXXkiyEZ$I_w%swb9aUM7 zsTo-rT^~V2*T&Gbw1*v1!r9rHET6@%MJgp0BA|p~>|4AY8N-M%BV{#XeRhS^St@w@ zPm}cjACvaG{~hi*LBcPYy8ZjpS@(2sc^?;<@RHM;!v~jY#zX2-jEA*%39pJoh2#YB zDlHU4bU!2@d_d!LluDF}lXadce5UZuMJQ7U80{II#ReHY!zOu&t)m?VM(Z$6GY)~l zcrxc1ox|IJvk~s3lp?c%!aJ(VI#z;tjrD^4;K@~n&?BXboAPdNAg`ItS7b$nRxzsX zrC=l=L_vN2m}0)-_U$WPJpY_}e#iNPCsg%KNY`}>7+xX@dGCAJT6d5Z4q7aga7(FrGGh1Hr>%aHU`LloZ|G*D>q=dff zky>NCMQTAIHMSqQz1fjH%F$^t?1DpBN8b;Cq$m_v8I!6)#}Ejde9)v4Sr3sZ<)XJ< zNWANK`HR2f^=JQ{wHo>0@q)8O&2Rn2Z&J+W{F^`hW4?It8mS73EN3y(6uD&Vdx|2* z1;=O%<$T7gmoL95cN~FFe52p+eTQ|HSNz>qdp_SrTc*wxRgsfPMXoeusmU{#m5Soh<+}?pTTwGovi#aAS%)54n={pv)Ie8WB zd{Rifw=}yA-p5j0AE4}6fE#{Q-m^vIhsKn%u1hkY`GqQR66+#Kh z#gcltM(8X7*-lc@w~*cO!G9!O`0A$12T=>dJ5u48v&oGdb}vDT7hI^t7RYK`^*qa7whAd|BKm&L*Z;~>`= zgH;h(S$KxgMLpUWj1d?s7+i>UKpXiYnG1M7;*`b6=;c0ij>E3ya*=bjT(Bw(jnmj% z60$hWh|~$`ML^2P*%rFy;j{0vY&P6ozvT0u{VnVD1?P_*aencD#bU+Xo0q(K@tn== zEe{@lNV!YF==%;OGuDeGUU=@d`*#+HC(9lGz~!L}g2BLkAE#&pDB3iedZca8VW2KEL>Sp^ zt{J+9OoPyp=Pz&AwVFrY{SDR+pJHXkt~2zbp`O6k$;7f0y_>gZOe9hLsb@>U&f_( z2r5q7VrnG%7NSZcyW@xdk*DqOOEm8Ajk!b&qlILiU4fMJ1j@Nb4GqR_=}d#m zmk3?Q^4{bp4&F!OoD*cTH4i>o((m4K`|>&MkFQxjctU;gn5z%J$LjncZ@>BlUwrmA zEY7cZ`0NvuPWrHq3ncIT$(I}=;PY6qg^V&pa527}0Pi|k`vw#E_(#9VezW2EU;im{ zEik5~DwcSiGxR;8$najW+4h_*Jx*GJ_gD-Bj}-!?RRqTe;!Ozfg#bA_a$Zt74oV10 zrD$$m@sq#$Q-=LZo?cd*&m)#W<6OYZrkzu{N9*VMxMmWJsy8)W2gijaaNk=F>pQ56|8l`*sp*Kgl) z*k4nYnx^yY+kuga4}SEkl#H`>pJRsiOMv)-Hspxb-j#qL{514!}bm(1@&Sb zWeKeq%t*VvW1i>C=L>AG9QIqr!x(tT)F|!(La6BCIW7=)^j$-dE9UbVtFsG``qXVGBQJfl zhO#Vq`okaoC%NN4zH8)N&$j=X<3s5@Zm4}Y1}g$Fu{OO?6tadm8)@iJBC=n;}KqR7B6R^2v zEOQ3y7_4Qmp227a8!#qdOvX4^a&NK0W2DDsDoHT`V*^5!RJkCthNgXs)eS0NBjhYG zk>#l(DmbLfn6Do&uUBl|zTvBvU!iYrc=+%GR_hBs_};Iu+uri_0feramCry z!`LgAV8XEhCP^St;>CnAivH^3Br8>tK~iHoQK$aFKl&XGn`^c&Kcf_Zc7I^8T+muW zJB%?*V?1Ae`G$vA>nM3xiqh2_N*3X494=sn->W< zB;)e;zT6S`MjOlhN&3Big*XH_q0%cnfFDr|)TJT^HaFMYUcbhSJz8gMb{z)I<0wqY))Ox z7>Azyen;QzIa{B_5Q@wpcnvL}3yyE2-KWBISmPb!NV7)qLQ7_ov-SYa&7i?~CdGzcl^W_;q ziimxMgqw{^Lv<`I_g}N=`66>frs$>+BTLx z+d#M9QdbpaSj0n(g(1_D8f#1Fn##G1-m1^%dOi6D^4e;uYC zu(X#_I$|7^j%BUNC)=8j1TyD2!uMn1OpqyuVuGK`*d`MK&I?BCQ$M4}=aRv|m`jY8 zbk@@jn%-E9F&OI^jEfv>A3v9O3TGoHxyU_Ij_ijmo$V3%8l6=!8ZBa6I%<9j=RA3_ z4j{^(y4{D>W6>&vVv@n(#~L9J-Jp1b{? z%hfzd89se~T|{1**ch+uAvUv137Mj68@~9-zoUEmIUiguS=yF*J@)XSJ55P|-%V;l`~LdzV64_>7_W|{zgjAM@HD#} z&0&XDF}PAzGeBZ(pluo!i#gVeG=~ktFranDYPBZMbH-ud?)HY}Z~%VrZDe=+lt28# zfA$`Y_f{%eUYs=Tbo;el#b~kMf1k7Vl2@-k=jWe&%K7Cb7Z0CO>KdD-G(VN~ z2?#Qz7+1%5PWSrTM{H6u#J#pLaF&n#Ee zMSKYK%>m&(MLEL>$7n~CQh2*ZTNwHsKl}7=aQnA>bWyWj&FM$aqsJeD@H~KmPoEQe+fwx_BJs(M8?7=#b(c6T^u zIa@8!x&)!HW6yrSL5RR|eMXiQsa{NB&B%VgB{;)!Hp3N~a$aLxl*gnJ$l&SQJ%_^{ zAz-yyP*!yuaDpe7il*6uGqeZCXe?!!b9r@v5Sq4a+1zb_Kv`xe8Tj5 zh!jT;>7X`oy0%1rbqdp1n=?3v_K>SsW-z*e5G*ced@!*nR%pD)5}P?r*9O7t{2||4 zt+;;mk}qGpU~{wK(UYgl&(8UH`D<)%-}3s^b2gj5;^CtYSe!k=i`Ykq7!x}~Ba=oc zj#~6IVM=5wDNqu>3f?Dse9zWgzZT;s=)VqP%<#+n!<_ny1kE&6hmoIFvZ_fk*@ z5H=1FDhJUEq!V0JFss)*U7vCJ=#nq4dp5qtnU*ZeSfr7>O4VSC4Jzd>d3 zb@=-34ppuB_&dLf&uf}tU|to8^&A-6hAPXbt2u-7G;Kpwm58Fig@BUrrn%d^A=epI zy~GPiaDmP4hCEZO7UwkkhJF|b-ZGodnJrfMpy=BJ(p$1Jqh7C(GQ;~oyT4=T8>-oi zvRq~ z^I1hXTd_W?aY3-(ZRz_1N(fe~GxDOOZ5lrP_kYHp{MY}dZ{s2DiR_H~;gWYzqyIxq z*#eQ}5k8crS>Y$h`#aXXa4K4r0)&|K>Nr_XsY7u*u%mP`{dctBI#ec5N+)K7K+0Ik z7>Ga^pZ+O>$IJNZ%Jl2zd5#c*JX2T)$_0ED*&>;BI3ASu%XZb`Ys%Jbd;& zE-oJN=H-|C^s`S{pPljO$%kBAJ!HOE^5*SVJpTYHLDjzUb7nU;JbC&73{r-Q!pZtp*@{fMw*UA>4o%YWm$vtn#Ql!*o5Z>1a*Id|n}>yT`4*CwWXRj`u7N-}jf2f<>X& z-CcA0_9f2r6s2U}w(Odbv&SEC`RoTcSWPqS;4+H^O8G8n|yN0aD(Pf1t zN?JJ2ej5+t*1TSc|8%%%T^6~;%RtTA4 z`jK{bM-ZOX`8iVMsWidUwg=k79wi0q^9zc+!1_Qp49sUWO6mlE+7O&)Hm{l0vvk{) z1Sc?KM|ap`t)U-!&abXmE!PbF!0pX7<6tPtob!t_@}feDjO})Z(mBR{3pMF)PSpI8 z!&>rg67WCH87)E25#E8f1aD$D;Y3)Udh8}PWitF80r8ODXz9%^C;MJFPTNA9V(CE& zqzFi*(#JxqFrLZ^f=Ju*cu)%|qZaO>6jRNL$mu1Zw8Gj5&G%ZOmBboB(9zmgggB+! z2>_*2Lea;?p(zw)CKzpGV-LnLnm}&?{b=cpWEd=?_X+rvBJ7FsXWhu?M~u($uE2{N zrDeKt#O0?d7CiaxkGMG8@%oF;`0-!;Iag1fa`x~8o_zQN*5?m+`|3-6{`0?Mu{`I| zqYuc68OD2jh&_oh+!9L@Vog=rCMZSl4rd0=E+6r$zx|){@BY<)h4ur^ctSriTdwF2 z2ZHkmq1fzV!f&xC5J7O*?xGPhM5`siV?sbH0ivK>Ub6FwzxnIu9DEJw`zH_tYw@P1 zTF$xIHWb+aSu8vbvZR<_V1#Ga8)iyUFD1Pdm`1a2_Y|cjyXWrs#sq!u1AnjB;XSXv z`kc-FfD}=#ySdxr)Qk_m|Le>y9%9Hj99qh}j0_SX>6(rZpqwpmxc@JC|MhEGcISCw zpJlc^{#+L(Ba=+JVzF4&Rn^6sX)_oJGtwA9Pz%xsf&@WtlKvFE=noJe0fHdNyl5~F zGiak}jmmTvyI8)+WRgr5nGtd0n&Y=$Yw2OFz0bKpR#*2Vp_d4P$T0Vwd(7Uy_4|E) zU&Cg|7bY}+~NVn)&^STcHpEIHG2Fj?iD_%{ zamIKuL(13(+jb3QSx_8mu#QolFdn7Ub%auim)Ec8T1%d1oX@7jaq61^3r$<$Y>U)_ zx~|^VBK@z+G3@`|@Gve*{{L}-nEUojb_mycT-rIX25Y=es1rTcz=YHZ@0iw0#YONQ zcEPK{OHgIF=}Zv3`0-Lm?*XBN3aQnBU+sEuYKz`xVwAJ>z7}!y}Re~>AOtNuSmc4 zt86#-y#C@-KKk%4xVU`6^5O|jDq8Eg>e@TLdt?0&WG<{XJrYh()-6xo|5diDdp`Wr z-y_pt$`YqFDvfB0f=DQ&P&B2%B!0@N>zbSTp5=uArAabL*HwO*7%A>vExge z6yyS&=qLp=DyKDqDAtUo6LyD!TprL#6oMcejHc*|cUisq3@N}kr9$!J7lTWno=!>cG}G@YQ7;;=tZ zR3)=~gd#`B33c7E-)<4YF<;D4Q36P8XV~r5)K$SK&l!y;AT=f|leJcC%YwE(P?e4} zN|>HqqT-mggSxIc6nmQLfKU=V%D1;jn>TpOZ;DLh8(p>gTc~uu%wOvGUlASSxKxK!osZyh9bo-$@rA?7 zltf6#^VqbIz9a5)>U;u)Ldt-v+GEsL&n*dUx%c|Op4eZz69I!oXoa*<;B5QtnNr?; zPg>t;cA_2P!@QbZU?b1o=!`{aUnsN%tqr;p#KC~Z8b=o!vQW&M&W1wm@#?ziC>!5x zH=UtwTe{8>8PB3@<`AkI#3=~tX+R-@X^>h7 zIdH3eg*E=QTZ=$>NiF>%QJzrqJcVy4+9C3*S4QD1LWLqN2#gdj;dattrT24_!h2zh z;9X$x-qy-EqToAXti^PKSWBADczDA4D6GzO4;GAdZ0I^i-N_)9vDCGp?i6LyQB)nW zb7<{3*WT2|&@=_6D{&&msff-hj5P?6@aUbdF+0ED`o+h5{NWE-F3))SnBov%e*q%#dh=h`~7~(*=ie52oUsr_T_sWWQN)x8DEUym{&=?fy2X11QRp zyKRMwXT0;RUm=@aQd{9EYyyh1AdNLDQWV93x-5f=Pf?czrftac++Sx>(sq{BW<{Q- zIQF{@!nQ<_rfOS1Id+C*JR!|TR8`A*yCI1rXThwfEcO(K4cRDXx?B>g6i}3P z$zgwowT9VzPL_@F`Y(Z0(6t?_-HNt40G9K!b0*UTP1CSiuP6hrdo&ucSdP&;rYcKr zU%#elN@5)mr!f~7mk1Sm6Qmm)?Lg#LpGQ zhqj_`V${Fr_wGv;Z40jOH+Z0zG5E2GAU4p$EhIz~K5QS!C9DlgM*|q|OWnsHIqOY& zhI7TM<`5zj=!ehWW7#sKQJ)&^_}0-{FH09n4TpdW3_<4{PKe-j5loC+fIN)BNrzGn z=QPfMu?D03VWZo|LnKc4Lf!T5e$YgQ#u(bRqv@ctzNojEr0F8cTCk5R_H|9&dArrl zYMhlMIz*0jmey1>R(KYN>#!;z%OqIY0idl;xwxJpJldn4d3s z`TTQ!`s2Ui;_`~it0y=e(S^hp)6)_|cipFsk0uxV+VB2%`4|86|3%kU#7_b4*ilIP95> z$81+SI%SAQb8s=jwm9K9ySPM;4Bh5AiH6B!g6YhIe&N*c|KF5-cPMJo#XDR+`zB70 zs7#pdBotMNRGK);Dar$Nd0;kM5b2bv^eOI1KK7y!kV0!GamUUwZpDJbOs#> zI@@{6(9SZMF41wycC)1_3r6D!qtOWG9GmTiVz*{I&Y3RGa3aDQ%XYh_tO~|?%6L4% z2~A@?Rn?h}{c257>`CH?vx_Bd-5{jo_VqPQ+n}R}*?d8oj(jIv6kNZ$##+m0lyP-= z$)TuGO5&9E>EJ?~&}xGiO*opSK?*_B6wGI{2fCuS&%5Jd7B0Dthi^k)y%Y~qROBzf zum2{fM81J#|Jydw4rfYl1cW>>s}DXN!$Bc}fJ26-7gUSNB2<5O8HDw(QP|Ea^8)PQ zobf3hQiY4;;T`BsE+!Fve&0h0=>irGDhdlO>p9f|PwTS|FfxSe_K)ccuT&amJ3oF~ za7v(EkR&^Y6kY@)0)}pb7m2Zs*eLILZ8fIreXV^mdegxukxWv-p^}~>TN#SZQFmVE zj&fK9u@OYhVQfQVYOF0VmBh)I*=)&ly5RQanw#sF+~2?A^2t-?=TCY6+vluqU-A0I z$E@#O@#xvRjFwk)LSck=sL(yM5TY!b)^PUttNhBZ|2zEf`@e@49mW0@mBz$bN?TMY zC6Lb1Rux&2k|r6ZZCI_hq-o4tDP$_>ob)(*;?TlTRRw7jBclXsB+?qt5qf-1z3I?p z!E8EZyS-YhrJpYjX0lQ5+xaJYuN5~>~~wFaEwM7 zqwx$K#nfd%-F7U-Gk;Hre#sv^PJE^oRaIhaM_X5nMkA6mrL&gFV!`A5E%fd%hZ-3v zgjS*Eg~X1b0G{%u)!(pK{6)*eUsTuyzc>f+U$Z(iefFR6|L?z7$`G9-0-o6$GWqUW z5IEJoDu)6dp1+kyWy2!Tg6)DL@tCXU0;S9yQ%yat9q4{4oIBQ;fq$(;a9$QR_#Ata zd=V0(oefIJlXlDn^`5XMSb_!-Ls(`C;r*@yuLSG5!DcnGzJPbO^WnM%AM4dx+Rk`h zb?VLTt2SX$S@vbaq3Wm_Lt`x_l2|8@#$h`_Y<ruC6XQTTZ#Te#s{v zf5hZ&%cCdHxVXGzzL;@+{en-Qe@=RP$CIb;Fdk1sfG^>|3YMn=8sqr-cYcS>{XNfr z{HNrJps6ZUkb^sGypIQ#eX(aGCd6?}+qA6LYh1{)ead&G_6DG#Ls=E zL5Pe_B}CIp4)>q4j9RASjO}JczKD?`qdVMl_wvU)Jsb0#U-@_V?8Pn5Uv2r?*Yq#o zNWWpM^tb%daYF4v_uLy4SxZ}$jI#(~+Mz(}B&TgU_J<95o}uHEuBvI8nz}AY^D)!O z6kAo4`!&+F=qN#}*i+Y%gnTliENc$?Em52>oz4-?vEQsHs{_;Vh$I`cKO8W|a)0|8 zV=a?epys)L-m@HbTdKlOHxc9iQ|+Nx$TUyzSy=s2RP8#cE$l!qN!OXkx# zX*TjqDSW`ge(%EokP#;2WeN3dX5slqu3g5hp%18zn=*KJAd*gYNZV;r&Gg`xk}NiZ>RLe>*JgixnWcTo6Qem zb}0hra^j^eK=hs>!Q9Dr@fI8KM(@&hTm$&dT_BY=>36{kVaRy2z9>gl;X>A=VEn~{EWm{Hk%hubc;yco=^Q@4zv*@m)a{^;pjBV)Z5-Ajqo;+c` zJmco&D?a`3FPSXPxqRncp1$`D=F2Otzxb3-KKy|5<&vwb_lUBb+IjyI&;u0GO3kl- z@9$CX?^wP1DZQn86luEF;EY8^nx?JMjUtUB(j*38x8D)zh*&Cr*ftJljTa>$u#F@_ z(wYj#+~e1JL^8c%v-^zsY>YC7YWE7;Irg_-@a=CrsKIYKzH!cqU zO$zjp#4381T@-?{IG`nHCD?7ZjM9uK&al>T*xiz+DM^|P*GgFyES7U7`IxpU*st!e zt|K4ko>N|zWa9~GlCs@xDT|W%bV8a>IaC#g-5M&q0x{kwP zkCcL3r3h=0qQ$lfB{fKkavj2XC1xyAe*k7vq&a7|TQeU=+XK7&)o%CN+jQqXoSRZ(zzb4}MZWTTuon=oBw#Bn~@ zJiL8H`VYR(k3O$>_RZhq^`;}yC0Q()Wz+C zyaAVpH<%&nq&VAuEi*(o<6#G>9>OId|4%$|J=anz>45$9n$r}OLW%a)bQ8+4-QdNL4s~QWFdt-A=`Qb94Q~ZKmEbr523(m z3pcs5F62G>rKk&kXN^Ny6&8#(bi@V~DI%+=>e~B^SZHHKmL^O_hGLwsJJjrphNd&5 zfJ-FC#6dLUxz}|teCn+9#k*^nPEw}RuXA&A%k_&-DDPi$`Q(`o8dxlO_38!BUwp>R z-7B6wdyjN7r?m>LH2b^feEQelCvyj$JvrmEpM6Ri=a{ZSMI&UIQdfY$E zG%dUBo>7*gwP3f|@#@tVoQ*RUvpM_1;DnE{Dyov*e#bOV8I7kDRm1&ujZ}{F^95Qb z6jjN3wIY&|(I_R#5@eKm1F&FOitR{KjS!NeI)K#V;|Xb+qm;%P!)ATY-OX##EGHX} zxjeh{zA896XTi82DDpZ*fn&GZ5+?~FPQ8Pr^jZSbb~IJVq1e&2HCOK@ zo~Ar3012E6uRJ`$BB5#b3%g*^Df-73Vi2SZ;+fvs()J5UpF8DjzhIPM!Ki}8YM=)? z8@#04z{ci8sxG7#bR)&!H{$&*EI1vCwM7``gA9Uqwssb6I*j$<$O2$_EjMNHfh6s$lq3wwY13GtQ=CUcP$C^N)YT z=__II% zAyOyU&JxENo$09BhFB|vv8>m7meG_XOOe9Sb{&Vq0hh%7T9bZZ8{uIED1jAPYY=0! zGc=nQl=shh_UMB5zxowEy*=>R^@`cWd&o%QOoVZYG|~@-ydj8|f155kTqQn}n6|2j z6x2n5P!U;{0gl6dk9ClZrx+z@o0k2yU_73X#hRO!pVKrom&-FoSf!8oAnJ%S<<#O^W}o+e1TALP`7#rQ2MTFh-DK>QI<8v8fJ@`zmKe- zDGnTp9d%tG5RArC#(72|_T;04(Rk+L>H20T+}eNoFaA0I&HwW+-cnh3SZsJmz;kJ9 z993i4)*W}dhFDtiG$uH7Z>28&m0eB=<)$K z+c^^ot^nKmV(7whGk6<&M8kLVJyoZt@`&KOA%Yjju_HCUuuD4>W${KPk`N~_j*tY{ zd&t@oVaX?K|1}|0E-d`~`)P+i_r~cU2d@i)$&=q{`rJk*1C$b?UZqyy^@R{#;a&cO zz#jt6BDD*}I+#iYUaLZ(jgL|?#!K3r^#P#XE5y3tjbgUsBZ;DIGf1j59Cq zt(%%d(^1rxrZbohIxT5iOO!{v``%Ob`+}EWT=VIV{*?Lo6_@Wk;~U@j7LTsBeE$5$ z{P2(eIqi1C#Wd&X**mzV;hkq+;~T&FJwE#4p4HuoNJ3TY(Xpnn24f7F_Re|ReaRvo z6Gxu?(seDZ7U<5yN=67IUcD%Vz;zB+DWarffA zuWp#0#~2wO{YgUKQ8mUV)c;!)Xepr!@4H3Nwk;;8WQ9T=hgF%DRvv)dG-t=CA)nQyp>^ne}|3~%f&fGU9(=@p|$4h`~ocmhwYB_ zeovC7TwXp#M{%$rXfgW(b?ND?Nt~dRM#mXxp84s-Ihv|uzq_TXE221JKA+Kc9r<|b z!zPRgI)OfWGTaaSz2F>mT{9VvXzP;g{*Jb8!8wvF=KSJ}bF+;%c z@n)7GxZtgWJ5J8}u-o$D3LykG#QrD*9ne_Ip>ViE=@)z){HNQAQ>m;GYp76KD>DTm&LlGSE+`}$-z_G*k$l#>cV-nVP`+id| z!fQS*GI~KvAKAsph3EQ09US0#SH0e@b0A1tH+15|WA(i2(1$x`0&?T&N5aWrTmpRb#0Y)YhSmB#uW+NAIz^Tl3<@bM9Zi;_%Equ? zf5Ghh2}T-(t5ME-Mf~8y4Zr)HN5s*;IgRw4OUb|b@W7KZ$)>i{WrZ^hLTV)<($q!C;c#F&nGr`Z&p-Q!w%GCH$rZ*Ks;XtSSW=Y*Wl=Jj&Cp5A{boa5 zRV=0xCgTbFL&g1Og%pDMd`2=Fd3d4gSg&qa-QAKV5owx{q&aDllf)@fM|94y-|so> zHrTEqOLNZ8&q>pq{eFjY3Mr#tfzU6-J#6RmHq@Xo*sfRX*DKn@e|;23%;rZNx z)|>pY->oplaDI7)P?4vf$~Va90k?iDi*#?X-WR}twt8AjaDAiCY4ch#EdHjfE6cVr zT(2558)9LY<(jMWIkQR1IFHEE7#%BwCSZo{1Xi&4;nco?ZF|2phYxEN&Ufb$<<&{j z+a}_yPX%|qnUXpxx!qCHEqY8u_MPXk=!)=lA{{O5?MxB#AFmRouurx2R6HcwrhxDU%k1&jLVFWKWD=ruB(8!qC z`8mJ-8{g#zKlo!03mK4FlEw*j+YrS*fqK8MNOVM+DzYR)2sy~!o3>&+(l}ZVeZ&&! z3KA)K_WpOdGYKzO4P7)L9?vjM!)krcVln6SddFdN!`Vm^2}2t7ongoS@xT0-?|yaa zeM?!s!wOZ&VY^~FTM|VvRdt})@0m?zNFlj? z^#y6Fd35nE>(w2T$%N^2%67BE+J@!Xf~vEuu5XBA&E?f2gmv7!zNM)v^2vmJGD9hi zF%9>t8#b$Zy0&JVkC-nmh|?UU<3Vb^-QH3Z1)Xt>@-dU~IWmfHR?v24SV9g;+u(!a zgtzK-*3q>UyZxT3EGQ0p=Cc{ucuJI}ej>E~UTj-~)RMX`*lboT&(6K?x3R~iecwpq zar2_sznw)|JXpsayS!uP7qHR5L6*Y*-&%uh4P{fYt}ATU5-G(^n(*?lBaIJ?Q_Xx7 zGaJRsMhW9QCeJiN3-2~0?HiozQ@F!NWEtD}@yUo`f#zG@03q~Ebx;b5Qz1<#l*3~N zghWV%P=3iaQ0oRB^uvyLDA*woSM+R>(>bJP)`_992+!v@APj5OK8d@3ULt&>lEZWG z1-_>Ra`N?kQk?V{i}U~W(~lc)Zs#mc%Al}hcyb>4kr-!?)(&C2&N^I&?}V+vI71Q% z##ziPPnqNyt6fQ17C7fSuyGnQvJq|DQa3F{V<;<2SzD^s(ip=y(M+>vJieOn>gDHb zuMJ&W^X}Kb!ujPRp5GOG|Mz~tXPY1J^y(3hW+~tNwO^y`1b_0!e?}JjIHx2{QA*L& zHE|LnguK}vzJg4Ojkc@i-ik7!;g-AKB7gg!SAu<@i2;n!xeG&H5E)zQAqq46Tmsl%;<)sRR(G3w> zr`Y^a%Wa46Kf3AJuuv2yC!82)cSnMW8*bv`+w5;*Z=NrXhsg=~R)lU{3=EXM3qC4e z`fl6%WAp=q9k4q;350N6)yv?0moJs)WJ`q4i*tS&aTYphLujwXn2yL=jD<)^Vl5bD zn&J?#Jyg`y0THL9NlX++WNF8!>!@pQquO+qx@)LfM^Q^A<1@|{6Lybwy!`xAUaSi~ zT|H-28lJuXK4n#NSbfe6y7=HGnzho2%%Bm$x6R^-VhA7fFYuW8f zRI+Ek-LcyiG)ADJi2J)WWl?hV=)xB!C9$?ac9vAuM5d)YTvIzktz#l(D0gczY5Dro z3qJVaU(%H;CdqFMAK%ln_=MSW%I|&nXHNdEu1lJ#L<+%py1T0_@16lKAoIAFRKrM=5tp66KGvD@t!O=q;m5L^w0#k&(Am11@M8jRuc z(GzbYV27oTpZ&t3akJVmN`0i)TUVt2{@?!|-483j6mxFSav((5{dpLms~ZkgNn6)J zWg$t^oHQ9BBRzDno%6IMAw4$boba61qT>2?hcz`>qFK%>CV9d*Q!K_Q^Kr^Ji^wyD zjujqE43Sk$?USK}z)I;2jPTvClRYy+KDar2hw7mS>!IO3P8FdzDbS~sIX5U4#T(pi zabkBi{9g1Fx+C?_32{=K-Ldc=Tj8LLJi;lbdZ6KX6 zT-!-stVN*gNo4}(!OLu%Qv=>*okc0n)po`rmBw0&au#hZQdkn{SmY6x^PKgeX0>Z5 zikd78cHf^_HLg^oM-!?|zr@ zWc1|~y=}{Qae+|@PDr-v6-lHSji>DQ2W(R?$#ZUAzd{Me+1Uk$!vP@$lPqVu-yo%8 zxm>c_9XJ#R=JPpeI_7S*rLOl(rz57*IgK%_R{nr;w&Co2&Ui9G>llZktZJ&J!ra$1 zWlNmIoS&Z)XCv>*7;-pe@26oLN^4A8qk?JHVYj0=?EPmDX|gmU8=VowsTXAd>-9ZZ zo*|^f7~31zgf)%NW2}pU`} z1dL}Y1mmMThtYJzV%~ATF4*pC4sA!8MWk6umJ6Dy#dbd9v5p(+6fZ?@JNBhuoL=$d zV#;cB;PuUl-QAWn5Ff(d-MTE40?Ue)&0hmN7ZIWP3Oe zYfYpi+t6`$P0RZ3o+yrZ^ym>~S#k6F1!1nx@QW3*yW#0pSTzlE5z6e#I^ZR@tCt!mn`!dXicr^M-)EcGTTNPL2{JCTY@f1^87Q&uHy z?W3TS)+BLCHj0R&1Sxf(F!#Z&z63Q6n%c6iI$mvBV(Ca@NwL18Y7Bq=lND#PjAC}Z7SRTh(Er!EpmH4pZuwjV|9;0H+Wt0GPw zM-KEvuWan$9T{#&YyFAkJ137{J1vHA1c^nX=#)fC9pDy&6kfhP9%bwfE%)mK+rzVl#!X_^{iELz9plL>K@pmgM^cu4OT z+~cXj#}t{ap(!icx~6NIfKO+PM^mCW#v+4hiVcS0M_9pz*RHR0rjJSMQv|_ODYq zA`M9rGaaSu_Br?K4g1ZOE^A5iF>#)uoklm7sIjD4)5H-~(lW{twrRzvv5YgtcABs~ z?0CJ|V~jv1W8VMjS9o-B&WC^f7u>!2g1Xq!9QMRX=J9FM_>W3^=RtwQb&i@2sT@)4 zm&HO#TGMj<`kKvl!~0+R8t0F$h_pnSj!!=Nn41@$VcP>y6!Vjh|Act{h{xal_u!xY z-j}4eLV4IBx|)l{f~wq69d-yOs4Bzx@<2qN-?{ ziX=_ZD&hY2mfdzuq$N+Ey~}vEzzT(PlBTXHb~~EtfYOTDY(bi5Y&Khjj%m$_U%Ft3 z;;M^+ve?p;HBv~jJVWW6D48>vE-@X!H{6DzDhAX}O2KZuC5a>AIQ7k3|L?}3L(|YU zC1tVW{Nf@cym)v+4PswOS?s9G1CK8s6KO@)8k+h*T{pn_+vnZ!r~mR3zV)5oVw{ao zNs7=uDZ@JF!!C!L*OSSeHPmH6Qy#FULpg!gG2@x{uSEsOgOEiSUKaw#Vltz%~*~TCV9j-i$dWJu5*Nl ztIlGCkEZg$sS1bke^weRLID;84zdVLj{Y#|)l@;0<0M#%>?wotqzdD^i=KGz9;hl$ zAQ2aeUFc@}F8;VobPvD<u7{v9UP8JlyHy2o;1hZqOSDcZ5)s5}^Yn;OWXIg#@?3 z0r!^2gGTnj2hK~~B@(F=Ng6Ymjo57W+^<(Yy*e8)9*@bg2p1V_XK7kV+(pDqM4Uzx zRmUVt$TLNr3hLUjs~dJjO|@5~*^>8u<+r%G+oB`G^kPI^HJG*-;3}W26FBL{W9znq zy6e!9LTQE45lTfgwc&#w{fx)El4tKd#kHE(udY305~qCrdd2AK8$A29zelU{FHdpp zT1>U)Y`LJUYIf^;?|?29^TmwXcn_9XMH~)$M%kFww3J1`bh4yr8}3(kjIxX+o;#bnAEubN2<`4iv=zO+PHaD)7z2!QnZoVu%#;i()l^ny*BfqbSKQy0q}hn+WJ)qpM4ckBElDlOl87v6=vtVJW2Sk^ zYEzQ78S{x?x34IgHC?@@Di7@M*2u+-EX|QpQr0!bc2rg6!vb)guPeP%pg_>J9v11< zf|3ZSHLqU2X0^HF@zpsO^Eun~hEHE_c=EO1=BwZS9V(Gy{_XVNf8*kCxma>2cC7DS zGs<$5iip#crm4`v??P;ANt2vIRgk1H<9x>Eeob-Mqjd1VI2;gY<`)-?#$#mYimStc za=*p2l{ZsbTp*$ZgEz)fR$^L99Hm4`QP(Ah{f@FKd?<31d0BayB30zyFCl!qnNUPB zIq@zDFj~+M^c#-DenXmP2&H`(pAbkZ1N+l}60Gj;(2-_3ozfbAeVMkSZ4a2n!>rrw zJyHoT{80&cJ|Ye*qGGq=gAYD<3n_R~(K?H;3hAWBg%l7>w-2SyKtl?oj>*S!;y3}N z={IJ5_vV7Zgs9>e?4)@i#0UAF@JD zfN?1vcH%)WGuW^WVF{ejNKP0nV&Jm$&LQFB_1+=J9E3mvlwgHFY-CSE!!t>=O31QH zX44s)?Vh{UhMU{hq-n}@JR*%#V%5>bmNeGXjUh7;<2+}aSKO};vSW*lI?Cw-89~FTZspLDF8}&wVN>pYkYiJEEG~|ihaSyhfmor z_ZXr1#^3n|JbwQ>>>FqYt^Sw$6(wB(WUo)SMh+>TpnyT)Il%i=GbP|J>w8k(V zPuTCaT)%w9C?7MO&Nv*lbf#r8nvzfFL{UuJRP0vw6lE1syhn^K&b--Ch>ZhJrm66uWym)1u>;**thY3olS}F0e5GCmnTDF&^b!{~HX*gp~s=*Wn?Pvhb-m*(j%V z;oc8ZvT_QkG`sB`<$lY>**WXGTgtlepPTa@L0Ss-hXZFTLY3b3OTjz9Qk z{}un_)lc5OBJG5yc}XnNSlYVgP?gkejdPYXPC|@(j?fzGyfc-vF1UobP>}ip;xQ7- z@X4MsvIkpz7e?^DgFT(7V6m~42%V*JeVbg#-Hyo21`?0R+Zr6`xYfC z61^ge9n(y*oWxwrQqHCcXR|TOSp!7iB!^WM^ zIUk=3LAB|#7=@L9_6yctIVsigYzQ}@Pg)4dP!SGi*K08i2*}4dX`XX-zF@W5a(lDl z=K78}OIge(WLZKS8?vUOwSuy3NMcQ%#N2KUG}bX0M=U29SIZespI&l%bH^v2e9G(V z*Hlf5Qkt{n8C6kI7A3}pc(jnlE`>k|jRd-`#klaf8HJ7%X_m9um2?);SJ&u#!Sw1W zZ7`wwvcEdhvM+Xlr!26-&~+V3#~AC-QAFE$^M0ijFJ8XFb%x9HE6{@K&?2Ll#o0M& zGNPzk?rv|W%L1)6)9IKb%fnvBFUM8De_hv6lsgXlEr(*qXyoCiG|Ny?1W1g7wud5} z4FjK~styPth~i{OCbI5$$oJdmS2WcgQ&&DABuW@f z#w5uIsiI+zWsR4Ba?%a=FoqK1#5By)cT5n*2q6Xx>?nN>7scszE_BwugA;>nU2>8= zIQ-fFeCxaig%%!blX!pTzCJqXFwU|sTkcBBr}rh=9njMGEVoRv7$?5to@QJwM=WRF zY$(qZQKE?C(aXaHlOk*CA^F9J&uZ^K9B?}$#gQp;A`AdRA?!PF`M{2Q2yYGS7hhoI z5e|8vs(ix)%ASBp0tlG%KppQ7(NoS~53vk*fDGGqi*R-@k?N_3-rx!h9nweZ2EPz< z{5-V`22m|a3Zf(>eU!17FIaDP+}z#s>iRX~EM+p8kmm^qNNZ@6WE^XfM02+*s5?WJ z#f-)+lX1$~bi~!=IX5@AeEjieG*|joGpp7JS=h<5~Q^3_B%#-gc6edW=Gpr z)OAbO)d*)uBhBjmHM7}-^Q(8T(l>j38zzO|{{9A}U^1W4njZ7^&qFCex!Y2g1=(ms zbN3b&>0-ZScmJALM~p^OzcA2|XFV9g&2}Ql3yZRzZYFw0TBz7>F3SA4d@6?)oS?Zw zf#{(S*K?bXR0dBK!+HaJPtplmlpql4)nC?v=mu-jzOVB|H1fpwOZ20tc zhY}kSDad<2?Qz7_GUsfbakdz-n2wm`no$-JM-r*Dk9Z3Cgl*UOpB)%29um>P*xZMs zT1+r;3Z5L+gY;wLEzzW$;cp5xYESn@{@c6Qe25c;L7j;7BzbtWA0|Dt8pn z99N}bff`cJPZc-4sL1uZ2mDg`cujcuZ{Nl{1j#7jYMgL(HeKlQDvEJI z9W0%H-^-$;Di1VGg;IDfb2cST63ViqX*;Zi&W7anuy5(}Kc(!iIZ4~LIAclEyg#== zN|f+0r0F_r)zVZ2x3{mzvXtFs?StzgMUtkBlQTwH&SASEt#i(wzJrh>oB?YrGAL$? z{SMbT&Mq!|(6aAhP{RMbYQLqe3+9VCLh84(lTPA<^Rp{-60)*2&)UW=I+Q47>Y$eJ8UQr@`y+e#zDRJtPG5jaJvtRK-*{k1vfg&QFZ4|urY_X z@a)57dp1Mwmm!?PIOE|6t zz8G=7oU)kZO!Jg1)kHCX&q{Qz!`c>SIyx)-7$`fe2p%0GIF<;Xw_;Y{LHbbN{f-8RzEbj;ZijdkZ$g-5lY>JL`pl5<{ zf~xL_gCcOq@$CJ~!y#<}DSTLRv#%J9GPLwb?rrOBAnK;3ZCf9&CKXkAV7izy%11;| zik2E7C00p5QB@VI-GSxhW1P%s&Cy{}NkOsSQB`}EXXjYgbEO?7T)Kzt7TZ)z=X0Ej zhehsNSES=OLq#b~pkfi=3vX8E1r+Wi`NR+HVZCJCP-bmNIXSvboZzM>Q@HE9F>$mD z;^eyqHo^%g+j}Bd6P6W{V}w=kn;xJ9;icm?@Q3AztV9R#jT^92hjD#ciaMdPDWuBj zaO|vQQ(9gfEaIj`%7#eXGfD*WTzd}pV#L*Q#MwMyG0mAzGt!avo=L`GJBw*stTUc= zsCuD|$JxECTOSLh5a5DR%Z0zg1joHoS3Vmg{bBhkPJnECl4$;bzQ@Bfbk}!KM;6Y} zEJ!|FLW*FQ+W$G+>KDjhmXi6Tc9Cz#H#*=>0B>J`8C?O$b*CL9hWQlzxD^GWQ+U`zv2W19BM?|hs= zn3}5YkWozA7_!NP(PT;-CzMsoYJXrln-C>Fd||a(BLqyR6Vfc_P!=d1VT_@w3aX-@ zYidA}W*L+7B~cuM^i5W04H$(nmkXKpD(d4M66lQYVwQ5j@z48WNAW{FX&DRv{aI^s@U##oGoWa zCH;r*>~XDiK5amKoRv;*BL3Cvb_x^z4biGU$thl)`VMt>^A4B|T<5@Ow|Q7uDbc zZJhDNTZynV^PObx9Os!T1|=0(i4vY-=m0oD$G(K4la9_hs@kwB44>R?Nu-xG=ZRoC zN?1-uoG&9DpHI1%Pq>)nOtO?%8xWSxdbWXS!CHZn9Z-APqf`i?2FZKRn(5V{^buTr zF}1zQ)HQ z8ext9>_Q^DaHe0&VzDSKSf08X1zO9nyY>gM zwH9kEUE6y5ho;7K9aUAJq<}ag&NA{@N*u>t_~X1!j4>T$v0^ftV>*d(oo_Idw+>JO zHn*>d=vd6o1|_Trluy&P+~3}@T+Y!+<{_An9jb(++U_w`$!sx0Xm3h|aP+tHTj$;J zO71*_Amqd5s!!ey`F}lGtCup<6WV1UxQl>2A48==k>}@(=1hQ61U@-sIANtY(x*w6+<5)IQVVL3^;2x`f*#fbCynAtcXOEi&oNa@M? z&U9GQ4&Aem(sPu93|&fz6frg|6`eiG$9sTEO6`@Ep}Te*13bOobf1K-jwVyXzSkX> zibLe0dr+jk`k;ro`fJ99$M#+gBD{Alq~Ul|DGAPm=|+bm+6;P4oKO3n&&N!rIom_Q z-Q7JeuV0ZU&2o9h<40G-I_CcVmc?8%pQNOTrfn@vp3t_IeO)sdH_Yb~-hK9%&tF{g z$!8z)$;Y2?e|txk#zZ>e=H`ZX9zWsp&#p0T?I$oD_6a`Cm!{bM62vSG=V#{-k8wiL zb_O~_o~ED`hpM98ZAqe-vx`fTEW??Ox+>Wp?rExuvN|vt=S*h{(lkdZg~MQt4U1uM zRQI`_>o3q!(v%gEioiOW#w&~KruNI#&fgbt6q6(=$yiYo5tI2Goo2p)2-l9W9`;l? zwwn!68WW{axIFsn!1L>OyDe2yGo8&4aqMAC>2(LLHQc|xWBi^BXwCMb40 zy1HOKpW~v)`+o$@!r8?YkCJb_g%rFXB=Hb{JT3@rSOA@%oP+FHoNTScQCa7(A*|Is zAQ=pv6@B_kSTKrVfpzq-=sUTi2VHN*>;@dR2P>?xC#L)ikyIl1c+hulQiNPsdt5fk z;1?bK-8grILBiLWlXP;?`%4djwY{}y5G_anG8!b?mJy}t*c=?6?>fZiE0nlp6vJ$! zSd2BxX~Ox!7w+YJ%s5S$Br&n_uM+2Qwhf9*gOd^~YEL=rVUhl`P=S?UI~;oGwuR7x zH-nE1JDDp_!hfCUmxD53*Cu$N@KAzuf=l}YGZ5?hsY(c>2?CeFIWQ~_!vW!h3O?E1 z5zSfOQ9I#Pt|-Z5I%YbZP#i9}eSO2rm#@$|;$nG;x_Hc?*plap=~z)$4bDkACm1ym zMb=VQ4YP5?e4g>-=^5|6_b#9O>{Gt@{0o|@LZ^>(3##C@=_s3q&1U7TXAhpGrIZhpo{T3Xafa4WFey_MhaFN!s3@js zji;N2YoZr<)pbSFb)3x>Jte@0afHvZs!I0THKS2ZKAvFlu$>eF+Zi_ZH%uluqshn{ z{D*8*B_-uozr+9NAO6qYLJFQ>SlacJnBEV$U-X$%*ZLFc zm;1SF`_rhYqp$L*{jx9qE~xfIzw!&k+YW`guRYfF0vP+CDD|Qbd-5D?KURg#xo3{_ zUwfKm?m|)SSqirIyO6=(Lip~ab1q=;eWaH=iaJhJfgwG{1^`|<`~@hFdKLq0t!1-m z`C{FnT!WGuw3dvrh{Y)8e421MPq|#=ET>-Xo~4>B)<|oyw!;LkZ6|vlV-20}qCLO4 z^S&ucA*2a=1skY~KFrrC{~n3cLh76^pa`4{GWx(l_s{-x<$HQL^iWB^j5Nn2nlOnW z`aocBm5T5*Fe&^LC!9bH=fIJPGRjkucb;&5zF>8G&+XkSkTFulZ1)X|#e_Wfje&K7 zrcsQNgeq;Q>YC{&VU&69^~HR_SKfWb=Py3zxi^wGM$hnDN&T-fc0uc+gYFaEWLbs zP?O^5+K#62ueWU*pQGsTFr76_XCB**RE*LpP%J~DP`K}HXDO(F_|w##E}P_o!rVh%@&u=}19U0q z?JuP~*&w@9So7qjJ%LVer*P>T{uXa=fo;#}u*c#khs5sid(~SWotzh;P|Fil-|!gy zYgP}RX>f)<#)tLaFOGq_QoJGK?y=q>M^_A@H5UXqPAY_qaZdPw-#KbyIP5xJZ)<+~ zvOq~g77NCSVwy$F#wlmhG3Se%vuVoNA}3E3i3BbDf#9qK(_&oXStJ6q4a-L*{c@6^ zdXxd555`H7qnF5#qCTXr_uP1k?Uzkf3|O>tZZOFa0G$JChh^u3lbsNEh6&w~4Jq(F z-Wd)|*^6fSgA}qnC4cuFF4~5hyL(pmd+zQJY}R|e`rZ@9(-=of*EF<^C5d82X~d{& zNz;f(z$j9jPf{M8kNE1lm)zZNc=c)pI^l~~H>~e&h=NB=T{SeK`6Z|jplTYF(}+m3 zST0dfLR+=mync=CtUsjFlz22k=_o*VHW(23drB&Sl+t^3HwA6yP0iZ239g6|r8G&B zlBOwX9AT}aIP93sW?@GG=7dY%e|Ay|%Bn;NL6T$x&2x}`JBL=1{ceu{^3iBe0QU`< zaE{$>jS`M1&xo_!W65|kv+ep8a7^Y)|GL6`q@|+VZ)nQ{llc-E#dN(ly427)Hg~tg z5lqgPZ())CgYWa<=QZE_wZF>)%eVdl3p`sP#RK;?f9Zr$c)}Lw4OM)2syr4!#{)Qn z6MnP|3ovKHqOXTZP7*KralD5;#L2(QfQh=3#bw`(^|IC8blkaP>cb#T5$;rc7tG1U zKp8%E;5}PpNVM`W!qCx(L0lv8OUU5r9H5qgl3DJI zP_GXtwh>Q7{#WZ7@#~$ORLkNSljfWB%!Xi@Qls7~Y;q-7o z7Y-lkqOjDJI3os#%7+^`q;dgQ4s(_ZU9mf^hJ@=o=l*o+!ot@LubtprC#=JE?XYM* zRcVTo@Lr{k{PzXL|QSPExEhD z;e!tjZ);k3FH1Pt?w@qFE}YaucPx&Du!jqVR{I3M?y=+G=za3@+yfTa(7(H5XZFA` zs9%b3f@3;2m^7X4wX8c?EDEnU#POhurss1zHx%F@zN*KBThtkZyxF$KXj4I!lK)c#={Kw)^tLZd3|^F(xd5yl;WjF%C!P9If+lRM%CDy(x%P zfl{v-CxYczb2d%5m}guqa+b3Z(@DlCNr;t134eIH)_0mc+$5y*$v0A>X|dt=y_8*8 zfkF-Rza9j&!uqo5I{&()9uBcnSG}Gp=!?P8QdZa=`qBZOvByw`aOjDXZEe4a@D7cT z#EPpYQ!cJ%T)$fL(NCZA`u2`TkI$J+Gsd%wrmpCUl2|%2H6n5yw|6UV+>=UDC3tkU zWVNp-iw%k=?6(_=-Ht^0{KhZ)OUE&3HuAW)79^vL%Zn?bC`I*?173q}+LoqmY1;}o~5Meh-j9eqXePELq8P8vEuiekU!u-|fVd5M!cJiedaiegV) z7R(lNoQeXA!~Z;IT2^=0BuT_%v81+=@BjXP!$0}t&)!1Q|6r2eUo4`RAP@XzcXFeg zIID$1*t0R@F#U*un&mqoU&zA1eC(Y2u*u%|2ghkv;F|_yF1YKRLMe`8mY@r-Ll}nc zweOl8M}^&>lp7A7lMKMnIoq)45aFYm!Kj#FE80;bIbV zwaB=brOd`DlRRRY$BYt<6pp5Ahc4I>0zzd7Ly!R`5!!dgA_@@JDa*%i6r6Q9r3Ol$ z<1`rfI8_neA8U<&9YWzv1GCrJ{&k8#K8xt}DP+6#adi$$PL zhI>g#I@7V+ZOG#o=Q@&XgmD6`ByCYptXG_$UHHXpFd7pA%KeU}ESN2q2p!Q`{~EM_ zuCCZ^R^+2G~9I?Txg`&M?+4^U$<^uPVQAB^tp3C=49CWYk$mwxcQC-8|lF;?Oz z6&HWQBJ<6^@43tU1xdg!#o$>j0*=Se6MK6`iM2!LGF;I;MJz~AMZYYOVt{%E3Z6PC zti6=odIvZsPYY1b^_IQX1kp2I`f0#+Cs~GKV3HgWCwnsEgo7@;1}obkztLMp3WSV; zWH!S(I5@mBhHpfCgU+toN#e|&KF-iCyx@6#e_Tdyz}G{ z*Q-5QqL?p6+`Nh?i`pwdzvQpcWX`zuk#gJZmZquw=NN7#9Vy}{A{oz#qr{7VWC*PY zQhjSgP%hfRtlyn<#r>f!WbbuD2-y&59R*T=7<3MUEw2F6wX|);crgpjmwZ5f6~KPK zBTdub_wG*MD8YKQBGTULCCerV5upLwRP63=Ia@4<(u6i3S`xn`tm~3#=%BkG(9%Ls zmwU?nmdSWTJektk6P8zKCf~{;El#236NO<<H@5wZ?txEN$G=oxbR z!pAN9II18amz*r_I0+?rv(&zk8R&*q`}o1R&|L@_6jUJ*reBQoaD+Fi_f#aDhY@7o zy@gTVo$!bI(a;46bpJS~N=SF=KsQ*8%E5ff0@9u46ZXqV6?o}k=^BJ0wto+$9i|1> z)9i+0P7Hz&;TYuGUi$0lcruD`E~Um%IjCC4=Jk$0{KG%u@cO5GEdZEP0GSP6%gmnEuE_{&} zPKN!e2^2^1a1UU?NqrRMh~93%c>icAq3wLggmp~DIZaiwzQ5+3$4|Ie&UkTi%ZryU zNVMi`zGQiJ#&)+sM}qlm!e+N;xm+;HGW2>+q*UlC3#|F_MYYBtVwiC zoTTVTAywe-2P+2aju4=5{QgR##Eru#D955jH(Ol0kFz#W&PE~voz4o5to?1^A&>Mb_R zN#7Z~sC!IZI9!mE`#e86V2MFy;CbG*UzB=Mqj3h1f$1Shq(D>~KKtpPQQdvcvnQ8W z)AHiQ3+{IXfBeJejHVYnd-jAhhQ%ajGD>m666qM_1fxta8YPTIBl0XGPJP5$6vxDo z_LRTS5osBGKLj9s7buh-{33iImjesL$=?3j+rA2Un)N6Kw?Ky-K7W4`dy87n4>z1G z=05xH<#V3C^Ng>)`-DfAb5^%^yuNwC>zmi0BwEJImrJtOE7nEFXq013ixz@3NwGrE z@#W!;NGr~k3v?8F6C)w$%uyX^oxs|D=^8A2hh?}Nc+mZ>=0SK*xX+I4p>Y35N!!*$ zI#|piPF;ittiu9T)i9e)u}<>l%k4}@Sr*J@vtu_NFyp4KD9eKRWK30;ahSI8%SWxS!B0g=$!2wn>1xiFX9(rtkG>!~9P7Iq+PZu@i?lz* zPS0d9m=ZnEtAtL_od{V@myCV{vjgq!Xo(!gU*Qe>u_r}b1~rirzffc|@Ue#jKo0hx zNA9y54DWk(NUtz_;91eb4iD&2;pa>F;5Ezs$%m;zgfN7jw&a43g^*$>&_1rKPj7L7 zYZ@?n;k$Xyap=PH>;qqY9M^Hww+P*fJIo;9kzt7^kRAeXZV2A>N#JgHzxz(h+6IL3 z=JJO-KKtwMBgefx=I^3!{IRY5_`+p#U;*3e)h>Hyz}%iqdeisqcbiRQ#RX@ zPd@#e+v}HT6vo15FJ7`Mi;#LRXVt@aKkm-;jCBLiNSwG2FTF9 zLALTc7b!H#h3-;3963ES*K^(tn2sb(hG;6$8)I=yAS#Lytu%3*c}KkyNKZ+{X1gIx zVzM-)bJkMUOvxX=+YED~MlzE7ALf)mA*eZU6k#VtqM3Hu=3b@+MWq21;QR6LkL z$x}3393A_PJZLfSPQ{6n9_}QxU~q{$LP8Jr<|hkEA$u62FF5K%YAuEn&GqkR;2+CA z{?PS!`*DdmgpUc|=@VRqC0?T6InN5vQX;kBuzJB~fBi2RxdUH$=bVf4B`qV+v+eZUQrfqC>ilrYkvAd(6JZZ7bCE9&JlBkfkY32&!^R z78z_)@Z{aEv3&AXUfu1{Dk4=D)s>vhrp(48q$|+EFdn5$MkBKE2puPAEzwefH30|r zW3kf$v}YhhQlkSN>mAet!b#399?=@X7cXvj_Vj{S`@%k7O!&I~3Lkv<6LyCK&tJXf z`4_L)9$MN~@Z#k?udZ)>!IodXNIPrkY(KH}aE=?GHs?$TVKvwRmOIiKUAT6P>F7)w zAPE;#{eccC`Yk|!OiTw|>kY5!W;o1G?9k9sQtsB|`G~eI2lavs_eyIlU0E=nPpOK+ zyXJ)5&31iHtOT|#F|8pnDQ(fP+ij?;J?|d}i@7WIhF0Ria zJf-N#H_ht%jsFQ2J)}4c8{=bv5~4Q-@}afCVL9-ntJ`(ut0|CrQZ5QGJBs3ga?x7H9fI$ZSgoi7f zbHg}q-KmdOpYZvQ|Cr09=e)YBF+f~c&hrKKuqI1ml2o&~za>_R-M+%c4N4hWC+S3lP$^PnMA;PW47Tl% zU5RSesIKzXN;#)@-$(brDRD)nk7ufWAbs%Xp%D;=VWQdEYHc4geZ~7$YY;cI>u>CeTew{ z`8Cg;USgc3s&+Ju<>l>$sg1Z^?Ko5&FJ9d8(N8|(^H;aDZ5L>gU%p6J<&L}8YoyR8 z7f_&bdN=)`qYCO-d7S8cP^+eGDkR2>Nrdz%_u|N`85E(;p@a6-nx;j#W{3Hpw{W{{9{t zm?LfB_djiD<`bdsRbh}+FNOsoQlWxv}1kftflDemsqbjI@^*AILF zlIVpiJscrV(kSFfJeQLJZm`~{{0$?0>rPX@kJ0qUkXbjV4ST9lzcN2@L-k$p0C{*9 zzP@nxOG9go$A=&IiF8BA?s1VBvH^pK2`3>bB7AKZ)R6**>U}T(W&0!=fsqUsxDtX$ zT5do4kS~7rCp?`?E+z?!Nyh*1fBZk86e<73KmSwi+6>nWj&aK3H8C?i~yfKG4{6b-H}DGytka)%`%Nv8bSpZ^FKr3e{^$h8hF zYMklV*A|&%%r2kcnv(VUhF34Y;De7o!8nP~F-j=!bu1)WDs<%Im-0L%i6i1zGtF}5 zTY0Hwo`q7X1(GP#Z+42k-MZCOS^OryRn8tiUU0Hte(Q`id z;3Fa#^WL*}`26}MRoVVhdbUxTaIu_WgdQaI{Sw;qfeqFfw2nfmnSBt%Af#fq+Ym`X zHkyW|wiqlBg7a3mN&RPk*zHkLFq%y1jNz2j_D0)bRYx~65bzUTbxoMOKtj$`ssPFWl{B#QZBiO{iMUJFNE>}k`4$$W`Zk$=Y8 z(o_}2YR&xWoH!rTV6j3HiG;SR+1%eS8eK74EYK>Yu4;AQG$#ID7Ob?GTS+2fJk zF#n`m7V-h(VtA#_1!umK&N<+OvX{5^ufv6`LVAnThcfjCF<|}k3iL8(4C2&Qbr3?z zV9V-;*CYi_x*>_UnOqgVQ@s3nmBTe1ZVZXo|l+OQ_VipBi8q<(q&>s2=3uQGdp8f7Y zOL??f=<=Z2#R7;uS6zBb-OYZ(e7U4<4Mr%^$&8|^*%cMj`57)wL&yb`haGLzGG3fv zRD^Y2MOYjT9Cm9KvpFgqQ9A~2lk!k-cXz{RoHL&dZoYYj62flTmYndTAn6oIt z=l*tuh%&T{Da##>7S~po=9)&VFvcNl3$7VtJkqs6jAB6QV6&?H5>z@O2eEZ%Vf{8= zSTH`FlbT&^0SY5z1rhMgpMMLx}tqm6Gah`(!$&N?331Nwb(V%`shvkQSU`wYo)Vhti7OcEfbBr0Fd8t2L9^ z1d-&_))7fbwb{}&zCc^8{DM>nc6%R+dwzC~j#EnG{FH=awOUaf_RJPjCesC7YuWEs zIMXtpFAzd=e|raPIIN7s*R-d(PTO-|HOeOBrz)8puWaY7sH;g5i&^@|!C(jOl5(I*ALolFn|^kI)s zO0T4}&JLVw@rDCm?=>>e;d)M#bzXuUJezH>-g;BFZlS=7Zi1kj3dw2cEK&#No*(l zV|Lvyf#PZrT|=Z|4BD@Fr5G|nMUdtTD=?-*i=bw;ZV+r~DUmWjY<-3#N3pl-z1byH zRq68qmGD=Z^IpuoaLXD)TQ|%Xi@+{Y!z9_(CDt^IW*3;wKdusr!(opz4a?;@tJR7m zPmqz~)yr3mMmgDNL}&dZP;NK4wq-J(W0aqcBO%yr?`i6q^NTYgmCzc{N@LrWo7D{h z%jM-GR2CNaBrtoDb^juC89S#aSy~C;zVC2g7n*4 za>#*O-0$H|r$pQ1sq&O6afB~iU@XWUgMARJ8kT@>WE;vidE7mm;DY!=@F4Q*!PlNV ze6QTXo*W`UNr)5=e4|z9VlDRgTKXj+eqkdXC=O2#fWT>$V4WJ|=fl8i?cf5~vqnT8 zz&oUl_s`G!GRqTsp;A!oUh~lpe}F32{L0t9L7FK#QSj)=`}}`@@6Y)!|Lfn!s0p() zClU_P)~v6eBb`9fQXX0a8YPSurdaDKUD_v_OBuS|pwR3MkB|fc>V~jb4+&#u&rjbE&1_>pKyP-_Z;0Q8!iYbgwNT-i#lxEG8*N-3?YK= zrbR`pz3;L?^T44d>^r3MGHWGtV3r)Y$w$Mlhx?+_U}1^CG%Z@IhkjMz##2JFFA8*| zQ92qtIQlQ%ZP!dD6NJIcx1uZ$ zOs6CM>Ic8i|L(u~zr2l@^a&n(!j#}aV0SN>KE_D=e$pFU+l3D9fvvThJ}&? zl}-*9;)#z2Cmd&S;u&&kKtCJ=W-x$~L5XI=$SA}^(T?|na6>w_6ylhseahaD!O3pt=oNCr;Com^26)4n4kaW`SYPa<3|OQ+MvMiF$m9DqKs*ma5Bl(gAxOYjr0tLx zA3YYbN;qOHN+*a&6N`vMLlSGWN|73p z$n)T%wq8%e}?G$)D#(ivhYX}XTfCy)8n-}rTs z%u@louH$}v;G<7oa{cO_ILSz}jN)(z2{F+SAE!eYfl&US&hq4!QlvdB(W2~uM5WX& zr6a-$kRdbD3J?JrFwT0@E9a69>_bHCpqlqAn`jPa10agO`dJ)_A8q-49_aJE>mzF(6>5sUePu5)OiXt!HL z-7sG+X_ZedqU+e+-;zdx(QHXe^AolhdqnglysEgkZkumx~gC?pVC>w%NL&$ z>4-;Ura(c*3O?vN)GAa??J*pvQQ@W5}*UpJw1JjI-?co>5v-w?;hqXyAR@xVad z^+ooi1V5y@aiX9)=@okKj=sRzV`5AHe`9P|FuD@~j(DJ)8BBnJiZO5me~uU4a|?wy z3VMdaDimTX|Ql1ND+32~Byj66#!Akq;sj)|p4iWVISv`)}U5l50F)ffZ2-2rJW%lVT3 z@IUzX`S7F9SnXP#JpKw_dG}rZ{4f84>$@A`Bqd1_#?u*(-+hm-e&ZV?qY-Uu*sQkv z1XqvF+3i*w4*M^CYZXPoX1yZIbK*23 z(rSQJT%hF*UX0GG?~FBAYkZKbkU=}(VMKxo(FVofFhvF%1m{3Udg#Ij8(}GFt6~t? zSbG$;*ruc0d44m&XiOp4ti4&+Y&Pfqe#IyoQ5O{w!F0aFIDt@ta04OsN4k&g&I2EAXwAT3wm!m=#g{vRikiB^6QgfnR2nGf^_iLn^lA?Q4f&suN3WLuy4XFH?|1w42+3t>_6=+h zl;`2v@k>V~CA-~@EKNz`gx2~4_psm6v;|jJmlXQ~tVKFUQB^F?&M*iRl485XG&Qru zf>ugE)7CYc`&*`yG2`)=rV~i5sOyUD{ViD%^XSoIP@1}FD0Vy2IK~OZ%j;J}QN-1w zM@XH}*`YcO0MA>9Ne8-FzpEFglI&0n-YDxbzyl^M&-xCvXJHU{l094?Ptt?yXhl$8tN^8!^bDhO1=L0<0M!$WJZQ0=WX z{pjhRQ=tBw3>y~MmvBDbJ|U8U952iH1>kaln~^vJUDShLg~ ztCo&fME-MC5-sG=H7n&iXMZgOc+C0(si|w)qQt7!+i=R3L?~~`szJq)ST$(vC$Ly+ zk4dKyqxpg>eFX--`jvP1^FRL!e)iKJ(X=hU{u|%nfBg^tw_LsRKEMA*f64Fv;h*r? z^WSH?J#g3`sH=+VP#~N|OMy@h zSuSR@7OJ|X*zMTv_9UY@dbB`iQ>0)<$<}r#hceiY9{=`;h#dLQVt^!UfFGpCd?EM)9Ft@ET(n-vcUDki7k86%>Y064#bAdyg7Eho$<$n@nfogt}U)>ahTwHZ;?Ir41dxD?y|cT6;71MC-sh0IfAr`HmXrCykg0DJ)urDJ2r9I3kk%v646jC5V!gEK7+Z zMI0+{Qtv{RV{2*K4i!cG_y6Pn9;I>oi$DG=e(hI(lkfc2@3M9YzyJUKYyKbq*Z(`8 z{^TcQX~K9s#actx)I`dmMH<*c1}sE6MkLsMw(5DlN9h&Ji;MzjEW0(3gTgShEL7$ ze==RoC?AChE5LEiFTHogfhZxMVzu64ou#U3 zX3GUSN<0&Lv%)qt)8!l!e8&&l4NbXYIiC?FBaBlBVOihb($zKR=NF`DN@pEaRnRpR zQKZ=KwnRGO$&)9bRdCH?@PqG(2W?ZoeMS23|NZaL{iqBb;6SwqN;w7tcM-%Q?m=S4 zQ2^rXk^Nz;84?`^TqAVWr;$|lxR@Timc;`zY4-q=KDOOzz~6ejbV!om4L|GSkm%Kh z!4A`&z%jk5?`Z6IQY>wUvyJBkn}*JISYuGmjKD{k!zjgGPHF<`9DG)sTIVz$rt(7jq$n?=Zum zD5XXzL8P@eKazq-fmVu0Np$2>reiIMgg|RWtaQlU6DX~Tv_OaNPosoLc_pQad=W=T zq*g@QTXZU=h~p%Pk6N0#rZ{Xd)}WLoOD9ZbQ>;qZHSlYH??1&XzRUgI@K65LXKeN@ zT?g6xU3Bt_L|JTcKu8~I8^;;KNy@4MCrBfWiX_oEqv;F|Ls6D=z>}xH!sh0NEb{n$ z+j_5zUk0FPZ0Cc5m0zw#N|Q{-I2BR0u-cW}9S-OyCeL!xJPU~`iq08~_2MWSJh(k{ z6|8x~{bjAebcRUB!;YbMWo(*;wrv?r$AOjyIw%Fs!4W5TDMF=GD9eY)lY}RYa!|p9C(tq!Jyj1(2N2%R$#2Q!^J(u+~ zbo3+{yx)b%2Rysp)WrsGj-!9{KrlLyik}K;NM$G1)mQkdxhdj9GR5EBq60bP8;$VDC>E%{?L^Ql=jOf zUx*c2Dk2@Bl_ZW7aX1WO?V${0a6?T|{5PtJ(b5l$wob~Qix=$@Z`cE^X$Z@J%hv?8T$p)O&+ zEl9G6%XgmflOO#BrrQy@&SUE;#X3z>>_A$S)`-Zzf7QOC69SOq{{AtZO=y)JUO%EIV||Qc^Y*NgAVdL}x5oI67k}tAhD*fpros6m?Nxnwqn# zE39?w)^~JO!P)tOESu0-!(q3)$|alD89+ez4JV zHY8#2&{N}7-+an}4v#T7;+^2Yy+KjW5*PwrZSO1Xj$Psdb=L_6&xY?C#-HO=+DCEu zuJ%aX^Q#nl5|rtcZz{Y#X**BRvld}$BrVtu=Q^Y{xDZ4t9l;C3W6m;&QU*)W5ZX#u zv;{lB5DVo7NTWBs$GH=hg&f2_{lO-cA6;c=Z_R)m9^Vfk?O+t8dj7dM!Q{gNR!JF_ zdcL?vS`ll7(mvWqDK9>XqEKwL$BCmTbk0hK;x5C#`^WSw4DG*9`>zvHpp=J6r1bEM zR0^qMw2qP5cabT!-vmrcz(U*cH2<4F)~VV z2Dxy^ItJ<% zhiOXA&Xy#}7=xv48+MyDby*Nan%Qzrl8dp0YiH%VJQ^1)6av9z!frpO`Yl zZv}D0NfP+5$aDP??V)ulqR;(1c4d7uliv#(kENRqXG0OT24Ne7{r{2oUr(}b>3Jvi zTjn$AP1#-B9e>&aXmqnl7=kb)fdNU7oS+$MLQ;f6F%i0(dnrQvALd3Ek|GqL34+v+ z5($DcLxP|M34j0^=nYs5ljcy7cCH1a|9aXt2Gpj0deeZhL z^FF3TS>vc|6q_RKB+J67?dpDh17p-2XV*b1wM|m4?OQi$8xI9Z99zOz3pe`)+nvef%JcqcimGGp(IKL=paO?5TP8dnwJG>R!|iM zS{TA0pwWmCVUuMBPe%(Lot^T@=?!OBGbRg5L5PqV9rlTpVwI#!rnjW&oHz(+HQS_R zK~@+J_mBDf7k`9*{q!+;wI);{d6CiI8}Rn$zkm>uEX# z`+&)+pnZ6su&oI~OS)dVP}M&!4wV37N>5R(?KVnmnY(5tQed6OMG&fM#!iRhrbeQ?SCKl*Sm#bUJ0Zm=ebkhlhuRjRuu* z{x2`(;Lv$@B)s+IuR0TMDW79F)E)1q6nkPD1^;|fgwOnAJG8?a8r2Gz4HjEd?>5eF zW@nrxw(Jg{s^r|_#0KM4qE@iwPQGeg;<7bPF(*w9rt%$fg)$|=)7hk`+j*Rlt`;3& zwy7{eI(4BCF9w%y28>c{jPW+R+NM+9!Puo#JE1aSGZ?I?U(Vre>-kaNN66aQO!~Me z_XCw5A}Z-pz@?M~fp$2tR)m3rA(U1G+W9Rj;b0CW9o5anhZ&SqzAJW8Z7rqis+B9~ zfv!7g?Yd^IoD_V+LstZGjL;!Sjgrb?i)BffCuC)gKoCU@f<_M`6!TTi#rc9q&(3*t zdduZ#$z*LQWr$S`2pR+`Mv96wnK2#RvRbVXTGH$95$lM>e2xk=d;NWu^A(-J9p3)o zuk-jjzfW0JwD#Nl@K5|Co$elIr%y?ZWN>^;qtWK$N1yP;ul@;6Z>BtaaF3!Almy&+ z~S@?M{oZ)y4`%x?HiCPH45;G<#hiFf164 zt{9Il>2^Ex4(<{(S`?-AZi)_y!&sK{1$|hG5!S>F5=T+n?@=rP{%hEjY(C zN+;pA)~8Qo2y!sFyKO2&X^_&ntZlkYoT{%bpi)Zjv%6Icx-eR~O+2^GGr?}$a2$>+ zq|X5JHmS7-H=d5@QdsId8js7$EqB}%9ymm_#Ur z6}T>2gh(ACgTM{0D&ySIiX3Yyw1Oari5iYhHCZG)dvwVMr(-@jn{YYJNOSMNCi|c@ zN`cVUhX$;ej&7OFZU_R&-oZYtR*(5|$#k}$*XvSL70dY?Ej6WuSKj^-X;vXc!Ts0X zKzD}B^PIhV4|#TaN^|d!)2GjP^$TBSSr&wGK&#VcKA&TaA!zlfLMX}5RuG1hKRUa^ zI4Y)4a-%*h%hGL>KA{CG5M}1Pr8QJCc1lkRrL`0lSQ*eA42fD@s#d5vm`0x;fU^bhgh2`k(eJp~- zbc`qqhI{)|Dqy}?kS^!+2Yn*1PFzeUtd~m%Z#0`!Qevu#r;k4&SEKv``&#CqN}xxM7Q_ikQJ#i89b3EC8EyP%MQEPa}4T$8r-1Bx~P~I&s*?3Mt_uF0Dlx>kBaGGId5rwm?<6!}h2g zU)Tq|3tKsX2L|aG1!4!X!E=zM_uX~(6C2M4=@Vz9r^IcBo>pwa0i2P)aWD(sz{U^g zq?A}$Ghy5*qju$!Qfy@F^=l$)xJJ|}KPP&TK4#0|yAJOSluIYkN}#ktD7U~vt^Lr? zy?0tE2U+0w+)@hP8H>&H2fjlV%CR#Pj*X$Ua=d4)kbWpAwc}z-tx-YXPDV;0q(;gB zjH0xPJj=<`6}HOJTG4E^kx`Q@&AA$u zw3bxGnw!gWCetxN7;ax> zRhC%4i7DmHu>@|ISQjBF9j_dNkZzERt*0Pt!hI_PQUxF+gZ-F3l4QMRe0xiluPI8G z*xhNj2!numvZmQ+dKxWMc}|+F7z}zC0Y&ZxbA!D-R1}gf7i7x`cklRuJ()sPu{S)x zih#*vLXs{y*xM(Fnq+0gY;*(Ga(sM*4kC(rW@RUbjZNcN zW6{rtV~P!Sy~DVm_JM#p>Ca-lu)<AWH^NMnEsn=imt$o0*pC`&J&_D&X#Dkz-m z+y*|VyHx8k6fN5X@mkU7es^aJDW%x>C)6msm7Y@Pc@z$UFkZAGH+Z=ALYG>lx7n;v zzW7S7Ak!OoKw{k>&A-N4DTfz_4k}Q3JCM`T31+kqUM1&lD{%O*^vnxC-1gXF~*cDkynXNYtd`f9rjTS2E zfvI?McEdN{{RS7KgsYk1W?qn#V08nl+7LRXxD|H8aFJ3_<|)rk&zMYZXhb1*?%ZK8 z+@~@y8r_nnDF=IdNCDSZmoysm$NNEIeO7$^DvYgLZOq~EHLD;^k&)AB=pyLEbNN&d? zqBtasV=4sm$%H|>L$B2(NmpE6KIP=_kRS*cjYinYus1xw2*r3ZCMgp3jt&TQ%woA_ zbbCX$6Vn~+A!UduEsN=t@%)DU{UO7_KBbXlRfUvJ099l;qsa|Lk<;$9==8cssi-RB zeSPGH=U>mHkQO2I29A9xJL!$5!;T@n^8gDkn zDfNuAyi~@xMQI!*$XbK)$r51DHUn#j&B~{un9bl#Zn}KuR;Q$Q%d>I^I&qHqLW-@4 z`X<^-c)tlp;jng_qAa}>-1_IYcFS)T)=SWB%}#)E0shGvE?62$7z*HZr~3k1VIp>J+>@%hJjj1qQDLKgpvfx7k@w4LkQmy zORV+$XB|3&cwKkU3X~g9mPJ9aO33p9D%aaZQQ$eVP-Hn5XBRwrdd_cu;~oC>Z@+_y z_Zb|&fo|`i8f{b*QkkvSO3lI7T2kgYH@7!jUY??qK^>Dkf(|~Ckz9BinADel6wV0mM*Z^ zuPIUGZr$MgUyO|0=}c@r#cK$wEK3RtS(Y)}>l20zy4@~io^W${L7t^toIaz~>JWwv zG=^SpfDwx6WQvrEet$@jWsEK_=`=gEJ3XeO5g5a8f1j!{Ovhu4FdQ5ofsjmRQ>0I1|zyCH%ux3jLeAn%H$5MFH|BaZ$ zf6pg#2>(;1*s7k~>{4y{*Bd#u@NRI*W4q2{qY=eUB;t#)R1S;Oejq1=6P0Kcc$u~E zgF!Di@qA?E2Z41*9%$!}p}e274z=qTwcIdCj2|vK6`_MFgm#@WQu|~UjSNDZSE#^N zC0Uw~rzxf?5yqmGq8SAQK?AH}Hec}J2k&tD_!H){Iq$spG4FnI$&;ImSAXco7~FfE zd0Mf|Qphrt(u8rxvpzIRKvh=UT%I!>kB|~xeeHF+{XLY@q}iJ5vnNz#$(@s9q|lr` zJEhTR(CxLEEhlt3ZN^tuP-MLN@Ktmak`y_OW{2@)&i?)prx%ypdvK3;zVSPp9NnQi z*yn>spU`SGXf~blZ@pTel%dfKFs4EYmyTj}jBf7z(TlVcWLZiW=uJoM`2KEqW{Lu# zeedW+U%~*DLMbO`QOZ6yc*Y<96_96%KT!qbW#vwXK}56DuxZE#UC*kSJVW2Es<5e50ni>N1r_3VD zSj-kAs}=auW6n$J-LVmv$gRDh@K|kKqJozAme=~to4|&hX)*#U^kqR z4Yyfty(+fHxUI*Yb7Qke>D<4x+zr0nb)nlvS7D(t1}&{mVD>+6BV(7F)b4uHDRD>q zO7wD_nZ_)vE+<3XSyY zKBZijFMRPOgA(6(F<|lPDnxJiDUugy~Rgq;iQSPQey}4nQkp5F(_L zV3%c1xn5AD31k_@mM9(3iF-&LP}zdZn_JE=Mm&3Z%lq$t!074`abQT+IZrO;TqOZ- z|EWJu_s**%CA2z>qFWIi1;8I2h34=Ku$<LL-C*TRIN(dhO_tQA{gtBZNYS zf-ne~-j0|pCJgollv%=Zonf#H4hAe16HH~;KfJ>{%@~bu8FX5-yF=DV!gxHU8AtSo zdq^3Oq$%fTPso!64<0_C+38bMAe2T3%Y5oO?m)xw(E(xHpfZBo*bU5uF<2o%y1Y(n zEy-%laychU*Thl4aM&Y?n>5=URxe|b7GAP!y!gZo^dy_qH0wnjqI8{rabCvQ5-L}a zoqS^p_PgPglb1^$@l>np*zndplfsG}YTK?gs`q~mw0H8VRdjaCSN6qS`GKJI1+d1d zwe%U}^*~hCJ|y0~P1v0YvfMnM>+Bu9%?j)P4#(P%9^ZB_h3k5y?^xaNPHkX`+Av6K zg;svJw;2qoP1hWHtXb}K%|YPJ^?f+#_UF0VQh5*OKqEB%6yc$bKx4E-OLy@KrI9*B zsD{IrF_d{ukuE9H6=jv9YICDrACyaZKE1f)+4(K+y!RpF$($0!)x{OXdd6NqB1zYL zcsgO4H+b_$e~RYu16GA{=XT@PR1~&pH#(Hrit+6gqxlpaM1+kd?M@%vXktXjYPDuI zzQLNDdk-I?gNU=UQ?M1scTbqjCtwWSMvM7)%COaT?~BqbR|^JveMX~ej_%xHGM>>0 z1Il#C=;n$q{P0&0QOwojr?guwnynVA+)@}rmZl7QUCPoI4eMp|wdVeh+ygn7D$8=3 zVc=X8k^X$|W8A8e61RV%w6i>*#NxVSWz>d6WHDQMCl0RBN>Np%Q@d6bX_7MNwy_q9 zB4s+CaB#Fo6g9~zNu%!qZ9o3xeQaeJ4u=$}8&K~b++nuLxw*Y%e{Vpy)8=;KI^ll5 zPp9p8)8o;I@y#Vc2(Q2S20_@w7PR^^?$$C?sYE8 zoaJJ{YPCRMX|`JQ2SWTN^ z^6AzNz7W_Qrz*L9E-yr>MJyXU*AM?Zd1UJ;ZR>8nh9sP&wG=MjQ0@i*ur1iNzlhvK zZ`rN4h?mXQDJ$N4(_fHm5-{YhkA-p+Xg4bb+ew)p|xAsLTqv4n!~I^?HMJS zMi_0};*=H}h{6?oL$nzHdVaD}4j=Z%KI!RmT1b=up*2z~j~#2M@oNI4(%2}%c!r3S zk;gv^imD)6EU2;sQI<#`jsn8&0AxfuU-01vr#yQ4nA5YTMBP0m3&X|bnqhCB(akwU zxuVsC`D)GwkFQB=pD%p<=ZN=?S>)9gPn3c%5EMzm+07-%dP=L^G=SzC67PiW0L?N@)io?A_ zF0L=>9tg=|2X7gDhNo^gs5}_G%G5E3LLLrxLHAEN~mgDr*y-1a>x~m0O3!lmRj}=vZ}DA zq}gdv8iQ7v^?HTU%9}O8Y(AmYX%a_mZf|cWtDNJ*W9HK-caM&-MapbC;dXB6cl+Gr z7pzJ+zH>wrMqFN9Q8fr`u4j+(}SL38rGbUa?v&$g&h2Y6ks2&34O)W2%bET0ctK7K)e7yW?7pvH2Q_ z@o+`yjvrBl+wC9=ki*$P>te{naS|K4cc+U*b$FQl;>QxN%_ z^P9ERCZ>vAJ53?C;j(qWtMpuM52wf-uBG)wxh}%4=-X}Q3x3GvjqKG#(TGBHHwL4buM@uW?GJhP z-S@eCcENiee9Xa}1Man1&ReZ=7zVfrk#*jr; zx+ANHpRyw7;`}Mg$u)7i#o^r(;#Qvug^_}|A+cr7d^{xzEC>5{C`-Y|AACZVuekf* z0T#p6Kqb<9WKrvak$?nT`p)f8yp;; zV2tGUdPJkqpwaG<=M_O9SgjXCvEEQIOKUJ_?>Az6i0~hM-V+3xERz&PK^#Y3tzB+T zhP9r+b;E8=3FEJ|GDR!sGy|k9u)Z@FQc$KDQd)vgQ(8q;RAfm)tKC9M$vRn+ml^x} z_gJqo@+{@(XrIM&N|~iJBgrX9Ud_x3`v}$mz72Jh*p{qJq)w zh-5iO3d`~F0iD5s(gdXIocVN0RTcEREn1y6LI&Py)L-Yux`DNj6nV*NF=xG6VogOH zha4Oq5{4nxY8)ZP(Gl4RuO93ja-iOR`QQ$j&b-dg_>S0kDYo1MqHYFz8(5&W(5z{8 z<~c>4*_aM(!)t5$TAgVqYAaE>6F8RyG-UQ3IuodhnzlnM!&O1T2!nn$^OwpRNSH{43qJMhp#*&w-Tg9VOX!`G&`*w zSHys-@+wpzP=5^7pezccl!ReGp65hixJ5erb>jjB1=dQcvTzNE0%IJ`EJRMECDxW$ z0?Haf$rHD}rE&)RNrtHm%{Zp2DrU1W!@&S+Eu+bZz5N5ytRzn}dfhH(XOHL)2k2&x z>)RWe{XTbJeUsap31=6lM2&z%7%t8#va%%5l3phwY<7qmEmrG-+2o3<$Z2+(bbCXm zI5h%Oxxc4&Tf|t>BxSi=kfkehpy~A5G@5Os3^29ydlTTawLEsg9fGg@t#zDVQFEuaE^lH-#NrHt6e{p+2S3EqN^gpAsMW^Eej^}}b-Ic7 zO_tlo%UX0I#fDy|q{ExFRvR3?8HGe)unp@~5-GLgQ!BNFE420}4~5WyQ{m|dp+aO3 zfedhVc7ca`Dr{AdFX!axnmo%8CMVF)2%H@zQHv@sNs~2?AD#1?zyCh(etgNzY)vI2 z;#Pys(VH~)a&(m=@)cTY!XTs+86UsY#8A>MODephNVsQ6!yz;ppC)aHXD-l%W z>m{@Ch{a+`6b8Kd@FC6KkP1a!uo7jtfIuZg3G2lpQmg)yU>5$Dr04)zb(YwvS) zaY?t;VZYbn^z<>k-abW9usFZq-ti&x#f<&K6BcR7sx;htc#mgKpCYxSFePPCB2`4x z8DfQEGPNGppLP?b4VmJtsIZlf#Q9K~9Tt&Dq5wD@D-Nmr~^Ynsg_S(Z^0 z6=4uKdZ)p2qy@q{1t`W)mL(bogIHWxg((4)8!$@=R#BA&VHi1oXdy_FHE|dr5G)om zv{ba>CYP7jG+QA^n9mmM54&8QpVRI284M0Mzq}%D1hjiSF0XH>3i#3&e;6war%xU; zonMpX1#u&yakP(80h95RBuR*(n9klFVGvT8io&>dPf0-_B~?){pD$Rh76>4YVh#_F zh@!}eS1RKo;)Dh(H;k&?0A49~jQ@Ely*r-p`7eBF$GTH&f@bS<6@g1d*>t{QN5Wk< z%TjE_EYh2eTf23Mqvl<25M_6y+z1-HJD0^G)E1L=U9a815{^1&H^sd!s*a6UOQ~H) ztEC&%2_amTo~-%Fa^tbAwf1~w?{n-Q7kD-Xb%zeFi280>_@CoUi+mCHz87xLXE*)~ zaTvPXxq9Q!+S!VFJW|v)o+@@8(894V5CKBPAVU}I>CVqoMM|E}$~4uhYg>6;~IRyz$1{EHcYt zG2`H1z~fIoVejaW%jt~yD&_4rUt@A}MO9UZKoLZW^>WI|z1N&lugsax$K1Vp_c>dF zG)oZH5Ctu;0aCgMGp!UQmZ~y{KZaI12m~zJBJ*24&C8eXG zO6?_w5@T{io}xoVg`_MiI_)mjT4(oaGdjIPk|ZTvuQ)zBVm6%-1d3*-&GpSKhrG?IyPMcP%!P)r*jkwLxogYS%WFRQ*2%TY(6-Z?fwq!b;vY3x) zH=7(E9}VR)DXrzn`6>JRhg_dNC7aJ^wpuh>eU{4=!@-`Tdnv{E@{%YHX*8P@2BdKV;517K zqktd?T*Ol#v4y3oN>m^n!$SVi2Zu^3q97n$r^Io@YQ3haB1bAR#^*#T=V305D?!3} zUl?IgflEw5N@P`Ht2Ih0N?b;!4m85M-NjKz5NamlF^xupsw_#?YX*BmE-tPZ40zfgs-hfWOM-YW%$(qG%PFdu{af9Lh9#I^DP*kPGlxAzbChL>Aw`Qne)6IEZZ2jv6 z%*Laa)4M~6O@O!O5W5{s?F{v-+~G?5JVbXacME6}U*$ttH`b*uMpr1 z$`z1Pl__PuB2QDQGQkunQn=${95q37sVc>2mT`7@#`(=HA3VO`{PLFdY{K~JF-11# z&;9wI#LeSkmq}gtxwJUa1ZUYacCQnw3ZqG3o4v$Z0wc3=G z;r!x)<#NUG!4ZRAm&=P&k}T)=_?X8}KBUUmeBsMq<$Am#%`)zv9C3Ad&R%yw6vRxf zpYirvZ(~%%$jNx#=d^%y+X`ri= z>3mGT(_uNEF&GS4rUgZ@=H%#zEGs#EdP=v`rrX_PxmciWMV^-!Dd_cjG=1mZYxn8y z8`kR;*H;%@oIfT|0in_yogC9SzKf9om9^wvsk({6W5>9SI@L%xPkCW?NCwI`hnA`; z_>EuxRsPA7Z@#2y;k8k?c%Co(Vx*Pz9v3bt#CVD7PI2BSI;}tU*saV{nhmY5F6uR1 zP71Xn4skZ5q3;kHp)(WGzECQyeWxroSamIlcCdulris){3#m3f7|MHLXyt?i06`RO zZ8^0YK1%DlZ0!e%QaWRzx|r8PKnvc!GXS9+2RLfDE=&hL$IumKL;ym&&nW712NYnP z0eqP($g?G7nIfoAQqqV6f>sBqB9cOKI$HAV^oEb0jd*r3;(ByJB|yoTstA}&Z~5Hk zU*W4?`%x~h*8JLU{0@i5cX;cyJN(>F{TPeMgbzRZg!5@ax>_(FPnZP--}>fv_>s>) zq|;J#+Z{eWy>b=e2Qg2coe~BCG6>n*>vQ__2?qyRMM5YvQL~FMmSmL> z1rb`sT+c@A?e$o%)->aY+4!2_-T-4Q%jE*CH7G^1)nPQ7preTWgFQw!w-^H_$9J%0 z#r4$m_NnrrBxHAM~-6VZB;&eLG^hT+;6LX|}tB zb+CZ<%&Fm0NgZ6^{kFYZj`T2PRhF#RbC!#l^Q0bKyN2wgQyh9_+ZNUkn*rahxI+jq z8>c+Bsy()16p8dON$m`cSMhDFO>3ImhTB}@!)&F{N=V``KnlU2)!I_tw8xxfom9P} z_7k<+o98fls+{utYAJ<>JA6kh6~b0nEKwXe`L(CP$vTfvNpF%by*r#n2cct-SU2zq zbb!|?(El{fkNS3l4B`HW}didog-_UVZC z9-p(<4te9jA#c3(3O^i%%oc0j|L7zBhrj?toX{c#Fs9R~Q5LPwsGeeonhPq}}cC_}L?R-62u$fSdCt zh-?K?aeQ)z+v_V1_V(!=oDdgai;Sl?-(k>iaeDC#8MYk-uh}ABuN`eNipi|OR_=so z#rAD7#!$}tc9TM1*BZN%O8?w#3$vAFw#vDj#{?Ear7(?JCNB)3wqArK zH@+sqI{ks!sPO>L_z=>%&flM8tw}M(nmk)E+&^G49?@#VEM^nem6`%2O48+&Flw=0 zt?BO#A&9x1%xHIeSYf!lx}@D`G3*bxzPw~UTheH^==S$%v|4^0yMT{8%gEMKvUH6U zhE}^x+-?!55QJc04Cy*yKAUoLb&a{YqTBA!?+u*OowS=&@(rZnhw)fTl~-ixocV0R zbaF$Ur?i?an(a32Zim(K@+G9;)sXQf_|-2LYj+&(UNExvrWJKm58nS``&^PO6kQwN z`=X35g!SOgce-xBu-@lb5CsnNZZ+bK5JXDji>5cO_t1shB!qZD2zZ5`-h_YFNqqo^2PU6ST&j_(}NYInK4x@9~Wb98({p3Hgn(K|f2{~Cu!4|sZd zhR`7=ckXif^cl@oi}rBHlV^{J8xco)14g3})7g|zNsjKGkgQiEX~EImhvbDt=#bgu zmS(5P(f!w1W;yFLVY!@>ELN;%W1>btVJZR{ddqzGUR9>@8@}F6Q^tpDQyEvRjkOrB zs;rIut-o&S+ib>y7AT1WK~;s!*EvEucS0u)^L{vfkY?(n_*$K3ET#Yz3fEXvwGVYd zmS%)HBu$o#Z=SI?=rg&zAdVDeS;jpS$E*H$l zw>*3Dh$wE*>-XvQ`UGKw6_6JN>*bm>SyL4iWnNL0DS;N8+&QAvX%hqyLWX?1HF!B? z;hX8Hwa@!!)Wvlp3#@%Gwj5?rn-9sYO=xYLzv2Gk#UsK?#dqY;8zG6Tz3U7?5Fmgk zbZ|$r5o}UIYN@sMLKW>@-&`T~{Np-Nq_!bdZi5Jv+M(k)FJ>3FrO|QV*cCb?&>=F= zsKAA$x?lp|=?LZMaWW#*Zs9oS!bw}*1X}LM)?IX$sS@&JPL;2z$^u&&0wrh#njnZF z46#NrTV$MFUGmZSEgwC8#`VP+#dJ<(G@^GG!T}9770@4xpE|KL}C z9nrqS=fChZR+T2nE84vtjkpOY%F1<;5`k83(_SoR+>Gb6;sz)8?jb{sMUt#mOs=m9 zwc_N#Lxfg5d-eodmfXL4#OUUh(d{K~z4|%2gMB`F@|dXE;$;6WXV0DyMG?n`2b`XM zNUQ|+PVTc@uDQNC#bW90pAdu{E-oK&cyx!#YA+PYm`-oFcYH)8G(n{3HyVhp#g>M% z)f5C=UR|L@M5EaxZo~vZjFQ56m-zY1mP%)-Dqo4|eA*aDNY}0!#@>k~%eDzD7zx zyV<1G_TM*_vi@V`jt7u$+VZkOBIx#q^auMCShu}ic8j9SNsFAg(IAeS zwAw9#p)26pbN_`EK97{m#`O{o4!7bFCsVP{kujv)X7|->kGesWeh}ao6l^JR!i!C6 zaYvoSw?mavwK|Qu!&Mkly6#m#9BQN#beiGDJiji~?*5J(QFD}qaEZr`QYSX>MP1ly zXF25)N9q6oqe7a!E;@)o1qd{i6`(any3SZi=YN3=oRJNoUn;xsg+Wj_@_kievNdJ4 zCePQ{YK4-I#fN8O9zVO`^yxXdY*K|S^1MSYQbabVEM~-k z2CFG-{IfsF$%8le$N%zMtcoVRMnGjHSz)ot`AEyEKotuPI{|}+ z;{4IabeatcJ>ZxB!LRbw>S2*`p`Kalmlc=j!Z~^?JqIZ@opU+2fN(PY9Y#4vz2h z?D10qt+;#lnA@vUM455t-YXP&#qG@%#%A>QkLeAMc=q@ajb@uxyF*sGIl_E$O{67_ zc9*R5%D&Qg^{GLHnxm6DR4CGQ$vRoHSj-8eCTs+>TP;Ko`a$#-&Zvy<{MISWR(sn` z`|f%+o6~A_HbuKWnhIqR#(HPnihifTWVRy93UnNJzYyow>3rSI*5%P!FV2F>6o}Fd z!@)x7=&Dtg(r-p&iz!vU#uNpya>2r;%(%TdWADyg=F>4zM__}P;r;<-k@CSi-=y7Y zaq{pXLDZzkN>`?2x{$yeo{DCL}`tc7O9luW(G}yMjugApJadvLYF=w{h)7C zkhgLi_jT@YLsL?fYl?h@EmNv8!{j+yC>mi%5Vs+4eAlwFTwF~!KOb{*eam9K;+r4c zaG5m`K?6Y(X)QX8u|bpd>H??`RSIjD@NA?+NlQ7sV0rryf8poy#Ax8)&b3CgiwOA za;f5=u+oL}3Tv58$E@d5n(Zcs!+p2$8YfM@xH$u3xN~w$+-kCz&AGk2qTB5eMVj-o zQz~P5>vLa1YssU>AJOgaG1xodqfZ_o1GxY29yd2P%x6;`zVZgBnA?jpish6+ug$^X z9mbO>S($Ql_Z3PjJgu!@HXd7$@%hhvkstrDKl4H_ z?ffdFwHRBWm8RW{Ns^Q((A&(-IxDXBLO0g=dV9SEj zrwgWwB}e;5G(ydMJ|Zb|iXuY?O~Nol#xc{;Ez8B6qr*dvj*nSoC6kM5vLr=mL9^YU z*=nG4h_(I%wb4!ZMr#u{=P>*-PbrF=Jj*Hb+#4K2SydS0oH64@gS~?TTFnMB(5#nh zu5WMo`0-Pe4(N3|4EjT&xZwwt&fe8-vqWA#?+y`u=;%k@XJc#eSw~5E{8-|rt~F;^ zY=(6;=DRDwRy#rxH;D6G>YC2B3261^-rgs{8QVB+sStv8Gjc)^pLi`r%|q6Hu;=h; zp*$B_=}pHj)z)23>Hwtjj&L!`59NezAY|;qJ5`AC>Ek=2)19Jhz~-1Tr799knNSre zrYJyE&Xh?BA}tA{Cg>QXCQnPAJ-%c#neqGI_%`Pk*OXOAo@c!I=Bub6CbThS5EH19 zVlhHyGj!O(1P#{91x+oS>tJ?8t7TZtC#-Ki;xGS&KS$U(c> zEy;StbTS46hsQ@mQOldQTax9R>1agUjv4MBf|OieUy;tn9PXV^7CAQ;rv!1xgS)R| zfKMKO%>JN9e|W@`r;kuF=iYSdvS5{^2P`F3UrpGq*;nFyfBjpoYlWDNH6k=qJa5o%_2$Z zv||?`=k?;YPD$EP=3<>85yDdB1{H=FVVqRFtT0v(YROWwV>kD! zO`3dR6d1xl6L|_=Gm3m9l-$a@rSy?hzF;fgMQviH98N8Rz^9Fb$S_8#7<9Zd=+iqz zxaOnO5_NCKY70zJV2X^QOk9_2aQP!gJ1&2++WqEa4nwiw~$x$ZhQOm1&U)=RqGE}d>4q%$SLT1GcF6zes^{XLq!9;UKf zon2CuDZ_(9R*N~wY(l5qWbfWX(lqDt?39Cp1Ny@uPo6#nWqIYnYpm8O7w4zkJvt$1 z^hmRen+s?9e|Yy5gl=$iaZ0b-pxf<{R;5oVuUO0`4EFc2D#R8}$YhN5=_f8dyW2ma zvhFnKQ{b@H{VfuZK|nhU(OtFENjpsX7k=)~u~@A6m!%#%zXVdUsAatzQJ|L zd683<8F`wK=eY~m#S(@gK^V|(H?aotGN&wZtZ~LqjYbn4#z^UAO_lY#UCs8Y9K@qk z$o~E@`+G;E>5AEO%=PsJ*O#Ys+I79U|f-Qe?#Rq ziBKVB=&)+3K`2aVSH@?BU?>*x2=_#}MoP+&CESgrQ!=TsW>653t{@Mvb zR9v2)(Hh)An1Z~}pd&=kr79-KJfq#&r)+e{)=i3RLcX|xbjDx%tAB;tGUQ+U*87N{ zPoQ$wRar}@1kFasv-2@_ofGJiS+Znud%>_1AU z7uIfkOVVV??ahclha4Z@B?tmaYfwUyCQBxx8^R#sBeFAOloVM)RaOLHh^Z&0r2p_tNi@W|0Sf*pPKo|t%{AfVMwSnc~Ow2 z35)q05QI@kyWJ&>LLbrQV(qHRY@iXljWj}RDKL~(1p>lGljCNSqoZS1izSoEgeOm* zqEx_7fBsLteBK>TpIz~_AN`RR3ia0W)zRg=`MeK7l}c^sc*=L;HMe+M(8Z<;uT!q1 z^d?QRW^~kpN%1_o5GaTo6w+!1-ao_nC)as?Le<%Pj;Acc7!kw>9UxT$WV}<5)ed}N zHgq^liK!Ayl~Cq6Rgq)M9BT>`&Z<;Mg^V;>g;*&N^)RV4q^p$45AH!xV#|V9RDAI6x4C=wh;~Eqd%yn}M*B?A2 z&6Yen8`EqAm~6$>^@y9L;ocX&&e7{%W?2PT>xNMk6~bGy+M;4U9g(F8gI=FjyN48- z%2o&klgXI*WX%4cPpdybE6s8?=lc4JVK;V3ATwu+IT#E%JiNnnk#K!+#@*vPwEIII zJ$Z`3aR2@*n6l*d{1L}{u7H$QaC7mP<@}b1uRJ7dbtsFR(d{LB`+Eo(VT~IQ3v0L; zU2}Y}=a>Mv{K{HrrKBX8EQ#aT#X1>@Fir*Q+C{q=gi~&3E-!Y{;0pCG{e{2GKm5o4 zkjGCR@$kW`{KC)wB|lVtv5}SpVL(|_F5^=;#saoNp=d<`>m(&vCg^s&F$QyTgxb%; z!5uZb!3wC#!YL@j*r_9{lDu;1sIBt^xYlLrjCZKMoAN{Z4@ z!OftsPUps(+k4)$@=3t5esgx7q*gHsPuozT=Ug^G3IgRiRvCoo zAVvfcN;eQX1{J$bc{AXXJ1~aX(BY^GOqpVelp@GS}OwS{F;?i{&#WD zS(b(}shEtXJbv<&)3Xb%uCKYhy`|G>GF{BLxw@s-9q{1pJ&K}0M*+fE(lp~>xX0P~ z6?=ny@;u|W{=@Guoh4Y&U^cxX>_I~e5QJ0&L{WokxnO*8h8CJ4pE2lU{M1kWSstBU z^R4fENEmc!*u| z|2(V88`WB$yslm1T(VfPn$8I0fc-niZbPgbg|R9NZmv$LO2f(V9pbo6Wi2(5tHeJ>x&ESo}ADg?D6E$$CTNMhp)elv~YX%jBY!iKRhBg z0qOXX^y*_?z5jq#cSxl)Hy3BPP?U~W94N(PGD0g!r?*E@8ApuRM1WY7wB*T( zcCYQzhQy|G^xeV+O0eRE7H_AMuA5pR6ujZCM5Ga3Q$#NQTh_#MlS~ESY5D00oesX3^2yq5 z6|}A7=+zUB`*$cyNtPyL*@B`hDDr~J6fX5gYuc@tFpLO;aDxRKW6AQA*?2;c=U^)W z9ntOgh~o$;ovo-b_yMDMj^1m8x16xs&}(6~k$HB9L8F9l*-jplFRQ|-cC`Xwc<;UU zUPesXF)5sroAL{%9?*#m4|-deebL?&V?Q|D{o2d3g{)okWGzW#t8DQUBOzW$ZNO99 zTCPYpdycalHjt`;2%NeP`B_D|KAt+6HO63ygsMm=^Moo-u%>Y4>Y^eD0)i+&2q$K7 zd~gSa6b9Bw#dw}@c{61+S#tLA`+Va+{3eU#im1_`sw(cD9P`H8U*vXlO%TLfo}ba{ z59se7vRp0+!;mnDnXD69{T_Lik|ha2++#1=!x}?bm6+)*L0F6$TX|7UB$}(p<8bf925BG>$4Jur;nv#O`YQgCCnnpXM ze>@~m4a&UW`sN&I4f}gTmg@!5loSOFh6nTqL#{_-#Xr_brLr)1fR*I#)R zEkbUtFA+-8J~$?+B1~3seSXf-$sJk;$K*C7TcsrHHFxekq_hevtq(aCOm1%(9`xLN z!#grMVTxNDrN>l*ptqrsS|Jg#a*&8sexs_Fp>eT5&lPF=93NT;&7C{w!O)>cl<>r>XPtsN*effkfy#(I^K zm8GNU2}2ZW!ovYX9qzsQCWQ&OJUb^ZDsQi#h{Bk-*Fi<0r>y$031KmnB}sD9^_r|m zu+|cV5$$$|MjW{?V<9odP#Lo^RkQeHb024iFUXryO0CE68>q2ceX|tX0e$T~Z@nw0 zFoxgySO1J({or?Az9Ox(B#r|QQ+UjI!(FzX$_B#29@K@{cOGh&3tby3Z6J)TO{tH` z_J%5QoAm8WKz+dt{cR1*5mM6_K5)JlDg+U|09~*#B%&&?Re~upsv@N-)|7dUsp^z+ z*PsWX1{EMhgjB9TJCTNEomR}32^TjrE^fx0T}`k_CA_LN?d5n_Z+a z4)(AGzxVsU%h~A#NBusPEjYiOay2h_`-gv$-pT7MN_Rmz=*eNw^Vy8WYC$V*(LWdh z-VM%k=trX)vSiJ0Z$P8l1u03>lZlqbp+ZHG=TTQ@Zky(2=_+NJtqH<_BF$KpIgP=P!O>mj>k4ZHaonQa3kieJ>9RbN z$>2kpP34-1G$r#mbQlD5yB(r1Mk0fw*X=oqR0c zrHY-RTz{^=eo+dk5YfSNf{~4Rg2}N}N|moDij*=-p>V7VV=Kp-)&XG%y8R)k ztYno`Oy&!2ZdY8~%s9PSaz0uyUu6_kMI|&^1*~UNt{%Tnrxnm`w~>^5?MFVx?R>%Q zydZ82_~yHhdG_QfU-;bXv^smd-tJLlDer&heFpm{Jo)4aN#fZLttNv;K(EswO;Vb1 zz&cM^q%%~c31m)KrA)^oC=+fbBfk10Kfo1FRd z21&&S-yX4;-Y{qnSk9L`xgK$wTJC@TYnaX<*ON6?xK32*fXtRmZ?CZ!2E#)KU*yi@ zM}>mCTyuMSi;{wqlVg;QFjlgjubGZV^aecy1!=zaGG@c!ojb%)m+R4((PYdk_wUn) z8(f~BQY2IEKX@G#w3v+NELSs*PVOO;rXk_!C+}j41^3?iGFC=}0%o@tM9R?X?U7f7 z4~K9?WWarykE0G`IMl%NQokaQkt@IObR6`#{sv}cWcgWSNJ?4*{Kf^6t|aU;liI+tq-|lvIgDg%G_N$#uA4y)A^iEBSLA- za=oV8ZlSDGc3PZq6CReTii)Tip@d|ySW|enJS8MH&yiTV`*%5d{qxA?5R|jVwZc)~ zjPU^*LSn0uqRhzBlp;&PR_Gw2(`ge%5n2acv|}l4Z63OVQ5d$x)SD*Nj(&B>^iF-< zu&8VuC~fVg@vF`L>u~68sW;CR{g)5!P@2fA{FHPQxSH=PcYK>`n4=c8c+K}#3bcVP zd@&W;dn505zJc#@)c1U;my0pe>5RYqxBs^1=@eL7VSSQ=`&YSKMn8a5(r-5P`z+*U zm$p_=l!i1fStSLtRmNhKvPyEYyrQfuRw|c!E|eG8ShDq;<>-PymNeoJiR9$?E|XQo zXVohQ+gF6rT=)LbyRo~h0;ElD8*IN~YTBEe)nNY5q6pr$hWf?_TqNO5= zV?OY2Wszr8h3gcZ9jpKUqM+OD@GgQ>-f#P%nkzC{mXfUJ3?ROPF^Q9Q01vU-P z&3*FHf}NoP*C|@#>|O&Uh_z7G{JZHV0lV=IWmIPYS>9mQWhBM|Du3IiD zZ-(TphPU8^sOO>^&k|>|;9ohhtB<$ae^P8xptdi#gPB~4y4{vz5AAG~&h{lO(ozs< z?al2yY2I3bKzp>pF)6S$j$G@-cVwZ?J<0QqtuMkc5WUbL%kSeiau?5o2M_q){~!L3 z%w|)p4Y0(%^#@Nx*dc_tqi0qBY9eFj`rLdLAv8j0v|;~XE8EpNAS=XS_Gul#pR7Aqc}Xi5`qZ4~?~DK^fKzR>STr5`V9pLGSgMc9UNR)MLI+EC^R z#u$`46wJHl5%?3!#Y__EEDKCv!GF^;F@`^>$$99gf z*JBDZL#qg>wVT)&=j*&&F0s}S#}SQ2gJ#r42cbJX7%)`+Z>a;JrMDB68@ylGEpoXr zliFbA)(ts#F83O;aFJnk7cHLK4c$Y;&VK-bL4LluMq!(g`qFmN5Qk!C@wrOpc*i`i z&zC!phWERD9=h1=l-2iLkR2tiaI`o92tydg{5Su*|CXDXad=$q*}LQ0`&pmwA1V6H z1XJa78{hkP&_RR{f?xZ_w%BgcVYZB+?e})R&(6#90>fx~A@9CqFFfDYv-^dgv4QNw zr@tpY{d@8mkLOdrllatzq9q*kEdSSk@(KUzpWFWdp1TC(w#D`IKYlG8bW?us-N!5z zYf38-R&Mh^rK81J3kKtixQyLEf=W71yUGt417WE0k{C^-LXahx3}Y%(;I6kUONl~_ z)|xcQT=EJK1}+D&C@b=!pe#z(>ornHPEHQ^>Yw-_P!U&igJ>O5*^ts0@+>7u7p&K7 z0NU*iT07r!trS_FktCU8lGu8#Uz>zE4mo~yQJ<=XpHnGsZsvUDy+OaM!<7Au%fqB* zXZ_htDu~$bkbVcP{iTKP-0KG1iY*NC(s_4uLKi2s0c^dg3tF>H0`TXW`rmU{@-7!y zeUHA*?1)FI?PqJj6#luL;6zGEn%Ip+q^aG;jHM__o}8X>=jg;`0`6Ev=DFp=X--k3 z{K>c4-v=hI+;QEC4Q12rs2b|-Yx6y}N3@#Hy0iLr&dYWS1qoiXM)N8@yEUxZd3dc~ z*ydM=-IJjgXLzAT?eFdBO`G*^Untt2%8+wKDhlL|Kll&o+(lEQpS_m;{crsaZ@u}Z zi~f4Sb~Mi|S5w2yQZd}$Bd`2v&}@3{jmfF;Oa&=~mv#FzAWHJQAj@*{JVytSb3V+M zXl*dI^21q67;5r7_kqZ+2RgmFk12V9+B(QHQi!rPzY>Sl%w z6_Y$9SyyCbK~+^Wn@#ri_6Z`diWL%D;k`91##C5ay5U}Bsf@cOt#`V!rgE2PRXMR& zS&;jId<}qDE3n4V1f?eh)Qw*qny0+@OnBR3t<LYdZg{+$o%B!q z_}AI%2HP&VzS<2C1lvOM9Mvs&p+Jkz=#F__I6~oRah3PDFs`821>a>@?G$-GF7RDX zeQ{Z1$%~R-{`>zgKKkSnzVP|a@fUyLFYZj-U#NxOSK--Bp4lzN+v@w7g?dBM7vFWl z|03p67vVuil9jF-%L_{*5+oVi8A{H_X0tciO~JLB!t9QIJg))Rbk93@o_IdE;W@

        GT}%?JWTnp70V5NM4SmK=!? zis^jiE*qg)ua=Z$!M*zj{OH%d!p+Sszw#^pGlwUyQOXwcQj)5OMzci}4*by2)A@{} z^m)rCZ-uH+!e8SW^d_Lg0hZg)rR{}K5A=*R8|wg9>@C)~%}4mJZRIusW84N{ti@I( zX_CQ-zB;1x^!ABZ@>K#dUv1$&&FU|G_CM-H?dQg#SSw=yueGY2LqL7 zV3=)TuK!Qe)VjcbEqUJRQ@j8m3;(8WyPhmB`8&QqM^Vhzzxws>?&T}Q_tzcnr)u;MaFG^bLt(4eQf1)lU;8TWe()ieSJ(Xa zfA{b3H~-py6e9TGGv4*m=j=q+yvBotc(u;%2LXagHDCuQH=Ic3O5TT_ekOBL{A(vOz zwEBk}pS;3awJEK4r?cDLyk1Abn$7iVtb-D)treQjuL*1X1|(|1PaPUv7i{l0uXG(9 z>xTKl4QMygG9etRh;63hhQMbkAFm}mgye>Xm8mub`zQbGU*MPi#KV`cNGoq{WT{bsN4}W zFMNUi_!HtN=5PItzsbS=!G=;~>NJcU5!v@!c(zesFAh5Dzy5jH0d~9GE$p!Ee#LX> z$L8yu`&>*d`#sC)*z%Rq@@(W@v-64N?!Z3R+-?U|pT?Zs_wA=TW$_tZviP2_!4GJS z-sz-klYV0%3?u&Qzxg-$zyI>zlt14$P zU$a~;D2m+Ac?7|ZVoypyOrYpqyOoj^3lhi0PtV_<-hz~f!z;aZQPcy-T`YO`$@w&1U77C=V~Aab#*4*Q ze3!3xg$Cb+V)6suN&D`3Q>6X634)ma>aYC`{!jmx|1wX_)m zSCmyokr!mCv*(n;V5*9u$dFRf@3jcRh#+)oSgiw)?q`=p!F;jc_UepcIiXt52~Eb~ zUXQBEy+v!rtdo?m-6W19dc8Ks2M6?fUE(-ol@%3Fhy&E4AMpq;D>YdO%n|r`c^n#LH>={~N#Y+ca7oe)^~Xy#JqisK=)Vd$#nB zDQ3r7%op_<&k`>{7HoZ)ZB?>LRxDR3x6_pIY{g=ok>-ZV2&@PZqT!TSV!IcVzWa&7 zc=LO^X*3(ZfXZ&O=KfP+n)bQ*pxvymU53S{m=^Za9ZLONyT|HX{{my|XEHKAU4TD5 z3>4pup7#TeIe)JYW4CK*H}c9DCx5O#I^FK4){-$5w^tVwl_AdxtdMlOJzDLq@0hg@ zk*K5Spv+6=iy38+kgZb!t?72#zt#bBihY~o5_sp+k{4Mz~G<*w&MKpBTnwWLU%BrhzDHXj!DiFhI@O2QS7^7 zv7N8@QB;kFY^E|l6Y$hskL{P`D(I4<&w%}H^~*bx4tZFlQ{_b#zw=lZZ>10(J7 zBZZIdtJyT;(G~B#cm6VF92y|s7HN}jE2J&`##+C~+IwcG7mBcWp;HEI#X8BD&J(7y zC6jr=beWJ8hO&|l3K0<~h4uXG`iNuvn^I@V84ExAXMTnxN%_`0-{x2T$A8RU`o&-3 z!Gl+y%ba_$IDOxkwEZml#rN*6HwAfzVNnnEcDrX@z>_WZ5B+hQPWpu+y!+?;VZ*@B zqHK%r@%Oz9a7VqCc4gg@>72j&_kWozOL_RJmo13! zadU#Av=n7Qo+PB%8fy$e7!o%cbXr|*udlc~drUf?u$qhslw(y*MiZ*sS&d>Vs;Y3b zH?6S}=Bp)#_wMlam%qffzVS`YE^l3ct&9jFNvqSN#G+Mz%>|R`jCj9`ikcjs+-EVJ zaD912r`M&|A2<<{+2YIFr6@K9azlUHWyo#rVx8zjxGvcu5Vlqw+fByd22Sw|Cc9nE z+x5JGJcKtn6Pw3vTWhnywtxHI{2IUd!Ee8eMY;sDcE!3Zuw{V=Lx)oh>?&%qkl6-S5{2YWksa$N@>UsR+8oL)Pn;|I?i z#pxR#7OqHF_W2?#K3$B(F8KbLgTU_>i+}k#Y1bXQgq6Sd4}O{Xe9nVE#BNkdMSrkQ zquqCqi2!T-n$J_RbVZ(*2q6h|K)>4|ief5Lv0g2iE>;9#18sAX>V{BR;!qJc2h3+n z*6ReVocm;1WQ0+K(g8`4v&?edJbJ)14{7h;Bb|>~td`t48d5D5&ObVe984?&7VDIt zvKSv|+uz%#(QGjuk60%c4EOekn+>X}^lMjorf6NH4O>FK-BB05NEO{F#LrQYb_6~4 zh0`EAB9-T_qK!!Ah5vqG9`lka4lzD~L`YD|JIn<<&wCax4Emf|ewO4+7gJ`lHKSR= zY?-mjEqRH5zQ{*bNuP|t2KzDSAtTQ-+U*wO>6}KphX@+H@x?dk z9lpx>?UHu?9-YBHPd<8|S(4Cb#H4wK3v zm-PBQdV@Zd-@SxSt-+i0Z%=@=@rK>aoAq$Wjxc3stX>P^tnZve-Ld2G<~jl0ciFr1 z5Lu_Bi{}fu-IXN1lto$wpjtaej2gn&O)s%vE7CM)xk|X5teMOcW{ZSXT2fSkN=QeP zmjMLN%fB7QYBx2$RvZ~W?Ufs>*79i&U;7+}>!6RH=dCxsz@0nyzvspI{a(cXDLd^= zIo#sp{m^N%81W|IG(?4KXVZHz0~RA{|m3d|1W%4`{}jx_S;|Nt+&4D zoayWz{@CSePFiGSdEtVRjM-(^EGN39d=JPqpdI?g{Zng+ihb&8(&u&RqQvwC; z!H^_fvR;glK4>-wH2wY_7nkQ8-+u+&ThZM+P;3YlPXl!aCUBr`c|EdvncdwdU~PfG~<&A_{DRV-f5+ zB0bm5TEUKC|Ly==Z0M#A&a)firRVelp8?r@R`ap7KD9ffK3>uyy)7wLCsvGWdZd=A8x`ey8|gxTGBzAorA z1I}(fZ4YTI-?czDV`mZBZ>jIIJFF+z)qnP)@ma-t`#bTyG3VW*;Qt5pwh;-&i;_V9 zV6!{stAa)teWumuA6A^>NN|3eVQooPq%^u68l4Vd5FwSIvW7g(m@OuxSw_$Z=?{k} zrC2SOWJ!XkD)KC$-D@E$OR-+Fw|~G~8X8fEl_i0WFtWwlKk^f#h2h>?Z&MgUH?>?( zR-80SBqdsFDy!)3-K8uomrp;W69?!pLdOk)-X7CbP$0b@^A=mSR*;*DAda|u_a2k+ zn9GX`di@^Ves7~LtZ8s^<4NMyr+HB*Aa^il>ypH+-DxiTM6$MowPN>Ldwz`?W1ZuK z6&s77?YwAPOT^1tq_+Z=G|yQsmrQ4CM$?4JV$CusNGnApLZtKq6E7vM<+JP<%+!lQ z?0Ckq8J>yF5XYsEZ!elnkL{0I-+nyj!J*)1zuI~(#^`%}Jic7-oZYNW|P~|E$d{>{=or(4xB{Y6E3!J#0wSU zxjD;r(D$N4-d1?!+%>HbpE}c7ABwxNS=jWFPgjDtLci^9x^zDYFT)?E8P*KmHGE&L`DNRiyhZ$tyVo?Z?z_fFx@M>}aCr9>rqel-q-4L-rYsHC+prp8@Nvx^E4G_LXoMxL3c^-{JB_3-Q7>Z(sOYY}C6uqOYBz{`_gt-8P;X zBBbZF*Wb1ODap3~89%}=y=!$hMD;X5H{`?rZvL6~`}J>JkynDsD6G&386c&`3b9G$ zQ1zs?eyc3ck>YE4=kq3mb~6Zcj#$rscT30FlH9G`IVSB;8ft##R_*6*@4i<;Z1HR< z6;f2pZca(YXAC06Ua!T`$srHlc#A)H{}UGTCC#|WI;)T>piGv8WOQ4aX0yZf(sG>u z(g_r_R=zWEL7UbAK1f^A)Fny@(h`&@nchC*D}Kb4^hyKKS5We&J_+99xzA{(B#DJxys3?{WO#Z7LB^7`%kvnfYiP zV2gtFVn$^k?lcMG2wQpSt#xSLd_Kk+XvGcIi3?-xbvrEAYi6@Koo<&#qvPiKQm~#+ zNY_jHdk3H+*EyMzo9ioDtp?qGm(p0I3dque`RJPdpoa)ziY)h3ij4LAmM97!Y>*p` z6wcjE2b!{6ldb0*9G+lA07AJVv8^|E_g>zdJ!O9|B#7JO#(9`a-@z$wW?Y(*yvWJ3 z98AGtKBGVA5jWeYAS6&4YoMwsilQLPo!L=Ul}HJ3+#rlYbP#%f4!=HqWZd-nhSh9B zr`^QLkhtBZ)oLRQ%%&5P^^&0BGXL@<${I?dXc*!+nH`DD#p}K6sDUUweRVx5=zRB2dO4l_FWMdHnH* zyz$l>L{WpX5*X=hpHw{ts;@m!W6ImER|$a@l4P~!=H?o$HHSwB1W`;;RvQKFhFZ!F zr}9 zcI`rOv0t;>3zp+k22D*XYSQTqIXHSiQYcE%M5u~>zfE>CMyocep~=>_jAu)x%Y>-e z<)GbRZ9^&u z>kQ$S(_4xnVYt5sL5Q_3R%t%Eq1TLvTP>1x=GhVp7PAR)7?7^llvRRMnn-KrlM$U( zKxcSBDMJha66uR?$<1v-Z?I1#G-d5EEVt(IN(kn&DOv|ajV7fPF2W7xYf_aZd6|;u zDMeW!wW1LOXep`kkbZA~Rn9qXwOWy9DS4g)7Ns?DBO;1AD5W+^Iak=E)5%)HYB49v z6Oz>mr38b$J#^S6Glt1@#(J@!5k(vv9)b{zMq{d?RVF zqtOkacF!LM4Z5usXBQU?`a`si7>zG!G-6Z`QdNQ=ijWGXqg#$T9S@>Q41&s9qDB(~ zJbCgKT0>1uJf0mzl`@ekoinI`}02nJ? z@OrhInps)nLTbeh_9Q%&&fivEUTuBkkMvlz+{r+5n3GH9w#KJ1>`aDtH(}u`?>3r} z4Mw#=uDsk-3cEReDJm8>mn4%@hOLlJt3jw^j1G8oal_600;3y*()sjiY02}FtTNC)=*V()GCYe#&;mc-# zB3Uh$q{*6gt4p)pbgD~J8~zBgweyo`G()T@$+Dc@utyL^+>WPY`I>{h19T9B0WDxT z8)LFHz2SfgL6N4|$}pcz&{Wu1Gn&qjLK8^AayDVuZ=qXlj8!NZpj5zYazhY@^!5+Q z(HL*4RauJ`lIeJgRsmt$rl??7$0;`f@0Mh-WH=ar)Q$pIRV3M(qHq?RNqDdbrB?2u=xBQso8f)yjp!DnX~$q8Y~| z>p4Pe#xuTmvisku8}gL zH$33_`ifSgL9^Xtm95E(goD8$Mdccvs>liBfZOpc{i8bsaf{OUBy=D8dgtVr+v{sC zE-yGfxld8O;GZkpU~jj(m24RtHC8R9;ONc?oyC&tn`@SfB}Yd`gkeZg*1T%7F$?1upK-7k^0lvjmEZs1374akIA|c1rl>Mk zQwTFhuBp!d74%`ly6pxtLSrIqi0nG+UvRWH20pP)sIc%BtdE?+C0ROHwR?^myjR3-T#9i@Hl-x#VnL)dQ5dsWt;qAt5y+Jwh$C7-lR!)F zC$1>+iY!|*o6WFPm}G^DV%kxIAawrZ80$B)ZQ6)Zj$@pzQj+z`rJY0}z2Sf;j?h}N zUaeUzS6o&XAVcF*6GtYA7B(`vN{bVN}JtdgvjYX*Y@%G_{ycE&4jzC~q?Q~6oz z^E(3$_xG7krp)6J-MvGyvh-0^a(no#c0?%BS4!dX9wjaqx1gliZt<}BfZN+!o;`WO z{@y;_L7&o8&p{UAQz(bs3=E$eF!7=sh8?4J7y7ipV`^B$7k9a1xKzWNFP(SC`xhl| z|L~vOiN4vw9$urp^)lX;&~28Pr|UQ_jo4CY>~pWVmyy=b>&Wo34oIutsTYh?>Oo}P zt8c6gEm+|@Afa4mA}SWQ7c6fcbI{c^V@0pq;O>L_ltGJcfB2Ln53xd$rz=dkB51^D z86uiptkD=Dv09U*Gq>fKil|CyDUCIP)H?oY<+~GQA)sVAJ!h{I@F)J%pX6KbpK*SZ z5y+TWWmHy>mCAWLR29OkIX>u9mKo<~7j)YVqF_jxW;}j&MPqov;O^_>1Re%3e(XIQyDkvc$W7#w5N;h+*2$|U(-DnOF`bXGDj*DF!q6pMTi^NR zX+f5+$+8rQMN2o-K0G``Hai%rym`Ixru=M^M-Z5zVx24m@+TuANGiQ1FEuOdVA|I`gVhR$M+e}W~|GSgZ+JqbVah9vp3iyO;d+OH(OlZ zT+?WTboTaGXDO@sh`qxjj8J4rLRICox_eZc!eq#@gm$yd-r+INK7OA&Cnp4r7KN8l zTOo*okR(qyI=Rc!r_X4#T7*%9vf8pbgxxU`tL585Zc@2x`%!BluPT&)qr)Rw%{Dhz z*Q}B?2Z#FvK}b~@ci7npuC^P(pLCGa?!-`-ZE^P=Zq*mwei`_(PX3DXX{aGcMVhO=%JnA zz}CQp&GBq&r??^K`MfoOty~hc6s}}edCqKdMLxS?zpd#u6zzV8uYC2#Xm8srg?#wQDe>SA zd-vX?wBZIL7G6HTSWGFhgkHBp6t}!U!6K|d0Y#BA8IO^|5`~)E(G@`y5z2`9e8zG< zr`>AN-9N-giBt-$6wBF!PP;{axJQM;3W35h8C{{3rrjHo8F%#7Qn8p#Df67+{=N%- zwSJ>4a>mye^m~2UogV9QOLSETloTxHQ^Gi++3HYMY^1;zOHt$$d5X0a>*W$_E4qUN zqzXZ5gml)O$$CkaX5@vt@Pit=>DNBPEu5gw` zfeI9jMxQuta(i>lod*w*QegZrFOFm8lM&H=li_g4>C?x&{^r|MyOyL@AY=^@nw=Bt zmbYyDm0O1t=T$|k)27jgxw*aO*^_7N9qiNZ^(iXr#6cUD?eqMOx;BUxts?7dem4zh z!>1O`yIO3ie`c#T=ePg$ukowz|A2aTOg{N8)T1I{YbPo;;JtXkyK{3Q^~T?uBD#Z1 z*&PAKMj_;jzeGH5&FL485zdoVT1UNS2d}Cv5v`RD8j%7ca1?#vc3CM5wp=s0e1=(1 z*zX1myCK72m(PFsPtfk|@o)a!zvumrFA17mqNb%8YqSt3YYCfeWC?*#h|1&MRv>kZ zwFPC7pn{M*FNvd^hH_DiLP(@7NoUU(whcf26F^p z!crP0;~O-Res`b3N{lclB&)@ebiHD4f6r~e#%0|JV;NsxBXvMDyhBn6SMXe12U0?r zB_yjQ2S<0XLSv~Yvy`GJD9ap!CD4ji6j7{K^bQY+qBcpEldhK(MNVZ3hj0fWy>1H~ zHJoJIuZh)s2}*n3jpy15XUboiiY#%kg|!t?9I&@PK!$D;z?)jFS8JAw1*RgtP%HM2@3BrZM%TCO?+u8*P z*WY*zRKU&k2%$sbb{}g5d6rNWCGGuvOjW0D3#zj88<9dOMQ?wP>150xO$eK9Oev^@ zB?tnn)U4NQj!#bb;DZI{XJ_2K|A4Hh{6KaKPzc9q+Xl(*%y^z32ujMzBBkW`=nl)~ zlAGJxEmj?93RAPVcEi8zbIgt!o8H*_*7}SMH+r`b!;4~S4aTR@BYm) z0b1Kvz`l@D;(_E%VCs(Yq~2|J?KijZqJ2*CX*Yv~t*w@M;Z1msKPg_I;rZ=adOo&9 zASFmDrsGRUChWB}hl2*Myn3GpuYZv+YV(`F`EPmW58gqBUE+=$chXlpeY1JRk2uH({EM$$shkQzV-1rmzN8gahrMWHZqAo zDn+@j2m~DL_gGA>dHmsr+&kVUTQ9k|Jm+GxBI+NrfB!9V8WrSX`tfaPS2M$jGXQ&^WoqNJk8)+DPjdwWBKQj`{?bQjh9_MD=aa(M4PrSSZE z4|hqa5LB#YQ+n+-rh>(4Nm=FyYYC%}R;x+qP4d@^1yx}vOT*RmHKr<1fh3BXgi#x< zHNv_L+c_XQ27^`sMVioVHL$orH&Rj-1Zb+Se&Xf$J*t)3emdclXVmOM>a%;ywk zLA%|e(>X-xfTAc_&1NL4Ia)O7_6J09i^+6`MR0uQE>t<`a!Ie!B*~dQ<7|z69%C#+R*6@S-g}o;yG^%0q%c0_YD1?Lo}MW;r(DBxCJ?)n z4J=R?<4zo{1~*sNJbv;ChX;prdqWIRmb7Jeuu&p=^YIJdGmVVEeKt1!&Y?S>0naq9C5_f&Cc$?7~=m;-g`z% zcAe*$&)z3jPB(QxHyY?}WHdkk%o3wSib1rz#xm)VEZbCAo;4mzRIN-^X^MC(feV`TJMY7VTs4A7wQlb9;3BJ&Z~E6R2ie)O~yM{S!>l;ZFsmc zV}1P)u2KiY0841bi1J;~^-8&zcBoGVv$xw73u1}$o<8;rvlsfvrrFkw2GBBe#U-Nv?Uw54%{Z90CI0G%@)3=lw2 zt}vQT@k;^aQWYU=CgTZ{>4-+Nh3ENX%3SzbX$HLkj%`zKHp!IfE!rr?{T`sGHd~~^ z@WHKujyN3+Xf&Eg$0x}pNQo2~(XdB0?X$kV3Z74zn$`wFBD5JcPliLnaEf$n!s!Ux z^{E6^e8&L1@>~(kV$yWXpua`n`J`!vUoPRfF1BryMRT{@-1sE58Kxoyd7hKy8KrUw zr8QABWg1S&@)XB*s5feOo^O(?l_oE4$Y~ri9*s!Sgi^UgtJA@DjGAOJ9y1w_ais|? zuGXsv$D-TarBta>Z?4cE3`l1~);g=EO73ps3TSrL2;-F9?iNR{KSEHh63-H5<0&hx z4pQ1EC5UEIG%2N8v%n)rgfNYVB#v<$$MkTOCMZ|%e4jXqn2yI(YE6?JsG(G;(%ac0 zO%=WuaPaUUE?&IAiJ*k#xTbZ-QhJeiPIjkw4qkT-J}Ta8T@)u$Sgap7$YeZXYipD7 zc*6Sn2A=CKbk%Yp+0~1xdJzHu`;2RP2_&|M^xePnp4-&tTlN287U}TeV`z2czkAHT z|M%bIk@LO1UNC!peeo^19_;Zp^!|zMa+ubfuPcN^s3nur70F!ls+X;&LYq7C z@(xF96Z)x*zFJy}-D{T_Z(U%m8Gwptbv9^L%3QmAk&9pcDp#&&uo#YKR2y{yKR{@~WH=y95?Za6`Pnr{ zTcY!fey@k)c+~4PvRt8s#1@iizmLvyn(Yp$u=aYBxneZvQ7)CSyb@^+T3ARSiK8)- zL61hgg%>oK>h4W7;b#SYCj1To9(h9Z$x@Q9`cFmOW1+T*qR4 zV~q?4B`gyoWhRCDr1W#fun=HdHq&T|Z3&_{VmRrea|p@-wNeeoag3ZT*Pu;GbsR_Z zhXb-Crc?@Ow$`w0qlb^;h+)5v&YH%eY;W7CwMJzreo#he z3#GtuB-MJIaeqKGo!|u}q-~*<#_>Fq7Dg&31nu?;!_kln&pyk^lQ)s(xoN`{Mi;rb z?)1Ja$2rMvk8e`+t>@Z+A~n2Rt#hOlu(Q3z`SWL4TU)1AZ!92I=%u*1y#$Osgz2|v zfs1u{E@0r>SkM1QQ+L?5_x}qike0L8%GY~QPYW^n5+imAudz^AEECxlGP?QQQ7y^W zm*7`=sa-NJzNJ`J@)RfNVzD<{GtBjcWorhzSLk0m$40G$ts<13aq#eUH0n)0`?nvV z-=APh2jSQ_jz;SQTMEL_7>ks{8|!Rs^~sdcJ}bvV3734)S2MhWvhU(($igWqOUd&Y zc^q-wp$)EF+~&fi9#U4BOeak88D&S1$3W)QZC`o8^+IWtO z&T|ICK6#eXYIl&9jmkBaWjMuyUKh{vsMYJnq#y*gB?$+`FtFVr!&)$gA*b8l#dm$Y za+Oq>&&Lv)JP8?gyOe?weyzhak;F+%mSrfNU`Z$i0h8H;W~)i5T4NfeM58fTnxIsU zv?Na8QFc8%$EClsNx9x3$2Bb&xks%t8!)+7p#fGQ-HPKGqrom|G-Kx2R4O$Bzl4ys zF{$Kcrr}sNS(4Bn_n1WyLEzC^U&XR*l$NBqVlo{Pg%e7ihY%J@D{RLiO)?zEV`XiF zJj>|q?toGp+*kwYaCPe{mee#`Ybb5e-@QgHa0tpZGG#Lw^|2&Wn@v&;(z2ONXDFRh zDc8u;qEHb=k)hHQk*Bz>YsP%VPNGt2FzgKgMK~Q%Z*<6&Y2i7Z%PgEyZ?}lkoa>HU z&r_#Qvvut%YwH^%xmuFU%0>M1V%I!ZXzcYTi;G+?@ypHcxynIW96WfK$!NgV<~7E{ zA?q6laU7Slh)xp7MQFkvXL`Q~K`-sH<U*L{`pQaeKw zDh)m7G#6=}TI?rUX|Xp*RK-wIXpNM6I~chbE~-W4AfKc55QSJj&y5z;*q}AT?lpEU zK24|QW6Kzul<#@t_mg7t;DcYp3o6vKi_(e=&1^g%a0B95Orzuzlq>9PcZs3|RaB{I z9Ft4SXqhbst-#ih#TJpuv8Bm#R4S)G?D5qv4_Mhagcnqh`IKoGn0Qxj2rCD0t%%K@?8NvJ9_WB`Lr_vM@uLL6TSmrdpPb$`w&$ z2ASk3Q8;8}b)8DBNmfV|lqz;>(k9PR`lDTPoAb!E>o#DNV05U6x-Y7f~CY_z_{FxHu75aoISH#d_B!` z%C$O2f-<|?Tbw`l3@dAEG#VY#FJDUAo3}gmEZ<8ewmFitsN58LGpt25F2wV4krwA? z&3%ceN||Zyp2A}f%q^bd`xi@KeYME^D;D)aIws~H%)EcN=!?zUAL==hKa(7+=Fo6V zLa}2DCjBjTFP~w(Ri)%<@@T@b8;&s<&v^FIMJ`>sM5R=wTCE{%izte5J)b0s5Tx94 z%blFRaDhvgE}K54wkY{k)>c<>e2;OGkzs*=lIM`7F-aDY$0LZR=rmz{rAbilFc?R; z(yL7TPfZy^=|Ac@0>a5}*c z0)k4pfamB!+E%DqRK~E^!xDl@sl;p=;spUgwSvYXPf~ij+mr&2dc9E?_Ht~?CW~W+ zgD&MtiE^b*s^$YEi^+IIG@H?CcM!H^+5ti!rD8JL#U`cIT3hTeG#Z^mOnTd7voY0X zjZ8?qQi+mnV@sPX%ShrGlhKTRcZXW7hOivUeihqwjA{jqD$W?4=LjhnjfRveWuw_G z(3Pmd`ad@{2+&zdI2sbpBBUiKm&LZ6Q!u&S*F!OhQ`q2DXrdlL?;VkfbS@)~u|oF|xW0MX;#<>$*&a30V>&EsreA3Cd+Q4j$mb#S7eYa~WG& z2OhVe3^ajg9unDvJKHoP*ZXLY|wYIYL;hA3V%t*k@~Vi}7f}`hkO3u1A)o z&k<-8XVWqyQ$Hs`oF%?|(SB`pR%xC*iS^ERzVmry3;*WX?RPGBn8i|qUMxqh3Q-In z_QL)4K1{KIBkAWvYzwh8fLzi@3%%d&X;gPhTr6SwWtIR(3TC5iwl6--YCWJ+uQKlU z=(L+uY7I_5b(Rw+PS9*MxP0j%aS{>EW>l*+l+yS?iS>#G)ZwC zk5aizrX|8D69h&fk)p|xDLS2SU~Lu4@wn~IdpLIDB;)Cb>1c=)kfte7I7O#3jvid2 zS+?o!T*Gr*N}k2lYuC8EIUsjyY+QdU+OCl2n(25<5=T_)b^IVOZny%`XrZxfNt(tC z20a4T#j`DDvxsuFfmf=a5u{1Rpu0=CQl{Eyl4-NOv@Bs3=zfoKwL+;>z z7CGT~M7dmMZT%q939uY@aZ%^RHW&f6C5WR5vv5qk*)HY*vQQNn`J4ojIAS~+GMkPO zC~CDDwMHG+4+v)=NfJ}5x5>3MKqaji4+jkTU8Dt#W`kX4-wQ50f37SYVy2pg?7w&gM&4w+1btZl4Qs#J-SoL;w!A2`$-b&wY0;fUSs%dD=p z@hdg7uo-lF_@2#Z(B-4=zn}O1?yqwB+*4e;a)Db;-Hqdx3Y7``#ee!8w8}Yf@CZBC zuJVZwy_XZW-i2@+Gm9}cFl^Ul(C& zMuQRUcAIcK!FJt!v20>q?#lV~DiK2PzIXoy=bwI@legVfaNxxrUu6!VTI_Pb56aXV z4Z?8B*7g>*C8?B4MWH5^?BmZ30GKZYd(bBH+a9X);E`ke(D%Rk`N!^1i(pBL$eZPa z>ix2h<$0?t7G$O7+T|rF%|1=E+)u|VBy>wPI?Hm%CEzp?Gf#;|J-U~lVYTkltXCKh z`c%thgm5@};TqFa@zgUHICa}ieD}*=#`$yS==J*y2fIvW5vwZ)dFISTk~pGLDj_Y0 zPJ0cdGSVc)5}GWDu%%5p8)MlG;#tHjoRQB$UUb);)SE3HdHNb(KfB9`+~}+%4>Mq)?v3~4Ua=SvDWK4#AT-&16ZW^a! zQBCQ>WocWIXcjV_OeqBwbe0ll3AIKOEj_fbiNh)5VV_#PidU`}%_?9?o22+!wN^9z z~3Ip`$ACdaLoaf1ro z-qiFtmBz7c{J_WeD&%QQ63%F~R}Eni5IV;K^0}*2?5TUk!y(mDfNi@)TgAc>#=J6} zj)-OGU1-mvh{0fh z(9mhE;5s&=;h^BrXyQ1g-e}>K%H(-YueVD)3#pXLlu8w5vxM~FH#DpRZ0(Ar@%8j>av|M}g&!6!cW=iGePeFy}Pf8#6kyW4!>Z$Hd`{F9HMgjs$c z`0#%L;Ldwq#?_1Gxc?7-ix(rm9V8T4qcv>6P0toZ@9W#c$5 zNt_at3R2uuU=s?8nSWVAhzR@XKJtL+du6p z0%63y>fY$>)$_L}{h7~vMnCn)Ic~n=p1rKIqVKE=|GX%AWM-yeq)VnJy>}|8oSGjM5ED`Z*3(HoDTg~enr zq!CmYZ0>S-Ynv=dXg4YxzV0Z^W}VAdFVpTE0vEH8V}UF1>1we4N5?u^iGje|Gbj&jP3CS&3#Bq)~%{OZ0CPob6Z3JJk*G$2n> z%Hos4L8 z+Blv^Ug*!2GETqIppWmnWLjgp9zm&!WozQu$T;wnLO4FjEW)w_s+BU9?V1G=fgoeh z-=l|V~#Bg(Rja%Tl01h#-Qo-qzXqBt@JmvV_9C?TXI(}txy z*WOAES)S9V)EEx?j3*OZOHyxC@%$26*rb`pu^m*NGaL*EXA>&bGL2f3c$U!b?&7$D zC^qe}c4G}`J0wX;ue(jjbLh0%498=#C}uL~Qwb`R$~82aI2;mn5w40Ep+aQra$NdP$`#~g(0pVP%c-6e{#VTcEhXV-gk?!?zxzI3{pKI! zfe-%$z1>YZ?bXF1oyHNiWtk+FId{3JTp#=D7kT25uTrhoIeE)n^m;v7D;;+G1Fl{; z$I%;a;=-Ayc;K(!j~0^GeE-{MuWg_*#jwAN<2Xc7#M6&`jT>&eyU=qKJda{Aoa_A` zedtTP<%fQP>3GB^KlJDP=sSLqWw2T_3)$VeM!8buZ$EfHx7_tY?zr!zXr<`wZu7;z z`v}v?m^<%&A;(VM&b4dT7>q`mWV#l_*N6RBF_!K3e5mfAl)al`>~9UgqRYCn?pM zJp9D7l!FFZS`4RSlH9_zC9bp>4hDSwvtQ)I$s^o$>TWDYaNWiRqtSq~mv=}AIDEq$ zgqcHsJizsAD%C0o+bqz`5u_T+mgJck5W1d+Wm!xn6Kb_Ot{W7)Ohs?7gU*%F9Sa+! z=9Q8p3`a~y1KO=NmRllKrnTf)7PD}|XxOFRs1wH#lSz&g63?-4Jd4R_#A>UKV+)3Z zAxWAcrNprWwlIHguB_oynf*GrzI)N3^=)f#cG=yrQpDn}@VmXc9=ui{ioWJOAN z8ikY&Y=B=P7lJgN5l%(~o`;kguTn!J81C*MrQj=H{0s-KyPh}v;6DRxXpNJ}kY=Mr zt|kBI?f;4&eEUx>ik$g-6~!@E&!6Gve)J#mTkrc@ZoK&vLcq`dvp3Q2?$BtjAOw8y zJ^v4HdfVIifw%rsq_p|vcl--p{+c)P*-w0!_R1>5L61*<=zaWe@BA(9xc8;p|L)%@ z2#GPj^-Dj)FZ{+Iv2yTww2+I|<2+E|fsec&fS0}IjR1V|Lx0W#fBk-5{iYvWK-NC= z-aq84pZlaiPjq+q%I7}GZ@%|$_|#wjSKj;kzeclTBE>%Of%`dj;uhZdu0Lh->J`pB z{Um?+C%?n#M;@ZtUPS}_-EIEt_x>Zl{ocQ!*;!v$`WLH=g0Ft=@A$~m4?h1EY14x$ z7FSt#`in0}=FE;czt*S?7L$Ih$>%b?LQlCjnb(VHz#Ot9_7U#HzA$)M{IaDW4M%KV zc#@Kp(`h!bEt@D!*d2}8{>D>Gm5*?Il#0RfKq#uUGQxshze}^)q0w07+V)laET`UT zv9r62%1w`4X@O-~xUM9QQ%1SMYgK8sSGaKD0!ObqLaV*O!%tl$ri`a^u5OQsM3tc4 zK#-HodSuxYf#RVre}x09EnfB7SJCV4^1v59%_z0G?${{?QBIhQDObz5o@ah$WuQMA zjgp4398PCU$2}^QGP!~ziD|Z42+K8SO{M4$x(G|sZm$@5qB0Auv@Ax`5wlUB)m973 z3Cz~9(3sC=W4c>csnn_k@J3QD`Ph~NC??%abdr!;7I8Yk^#e+!8kS`YIoh(ZEDyKT zW~QuSu8>dVs3b6<0pX-iIS6QX*0H2Z7=}#431k@xO{o;% z)vADl(q@;Uq6wYO3c~eC5yaCe>3B%sy9mccYYWnhaMZ^S9HJzlT5F;#n`k^G&1S5v zt?`vFd}=ZHvTezD*vGP@k;>)TXx}x@!7C{8JjHSBh1*UDc-K44V*akb_%uPege?B< zgMao1yz=#LrqgPnl;Vq@`WXM=k3UG@dvw+h@WZdWhrhc2-Q02COZeBn^xORO55E!6 zy!~f?nR2y?>sZ8DzCf1FXHg%0|9d!c<4v?y)&R}X<2UoM_rHhNyy+h;T)$dt9{c)( z{I9?8>%8$F{|lm7NPlOG_x}E`@dH2n6TIoIKZ+3W^yA;)SKsk=?tk}h^CSQA9en-4 z&-2L-{{{c%*Z-K;y#6h?u3>He*gyC#{^kSs^VXmEY4bhQUW-Ffq(SWo0H0rl^g<22 zkA_zu0*l2&E4@%}?4bq4{?&e|OQPnJ+Qsf=S;kic4zrZltOT}j$Y&ut7f$1gh=c1j znvD`^p5d2jM54q@1_&!Cauzc~I+FppRmLsVK?t_HTVxtm*AEaU32~ZItJiT|8%Yl2 zD4io^PCOmZZunFi6&`=)DLSi7HVz%)ktd%e$sNMk)Vw~Yf?sK)h0Ayt;z^tJP76y~ ztTY=qmge%s^E~j`&oNFU8%J+rkSM}jQExSHeShy~T?$nY0!E`D)5(}xrAnHnXcUb` z%fRjtqol8f zJTJf&4oQ?S84tL25Nq)W)md39$=i7hPR zC}ekMi_vgE5L9WkSFv3m+jYrRV&*5(A&wGy+gHeQi4uip%>2Qe15+s^> zqd`!sp|Qzx6I+!gA)VC?wBw?LU^X6+j7|F}m!8p>3qh~fr|gx;(u_*Eg5w0lX-;p@ zquJ_!<$@M8+AF4Qk)_NgW9oGSxiX0*axaFexRmlD(%g0&mM_UizxE|g-thuTg;GLk z&5!@wuVPsiAOGNgq2wF&%snrCHSKnXSrmiT+ko4I*|X*q7u(*0M{eNFZ+$xwL8(;c6Cb=E zfH%MG#}-b(6Sv*Xi(mbHeBuN5ljNFHFZwS2-~*rLwimpRGtWFlueXD1+j|mUu|#Vs z<{8S`%UXOMriHUl2Pqc0g!9B;wPed=u@Wx})1TYMUf6f_l5t$@xr&S<(QL(q6i6Yl zfh?Y~b@2>72^%XVP8?rjG?~#0C6-?&5gr)=sdLbo8MG;h77h_rgyqv-hwZJ)Z0~Ne zwz5IBT4OXG5=Sw$YK7@|M4IMgNruoFhYqZ8?D|8TzjTqc^$xAobw2;#*GOa&g}}8H zjaGx+IECCoWC?XwQ1?A%(-7BoSZS5X@|bU&eunLlqJ7{5lSCsun_8)C+CFN|&o1^9 zLV->h_s8g5Q?8VlhEswdAShSR+6-*tIHo`7QYn`ymuq`SN5FC{CZhrIbWFQZCr#Dj zrsCQbQs!h?M7!BR3!Bk+ipp}sAoc>XEF&m+G&(D2Q2>XOxd@`^5KEZ^luEUUaQwnx zqnE-%&G0WxX3Qo-*4EZhx`<|!;BoX6qN)*RfjzyzVVKN#~ZZxqypE%bjvCN4# z3&xzy5l1t|;~`mY+Ee9n)xh|}DY*jIFCnFI1@?zsvNWY$D^n_!5Yiz@awek@NfaVc z1f_sdtq#)QX|pJ1)bHYWHucU1O4}w%Y%(O7jp(%62-Np|*)9$fsyr6_u zioxy@CpWd>@t<1R*WS1+FB z>cw+B`00=H<uq=t~dN{6CyzepVhmLaj*)#j7Nm^^_%{Hx8 zhx2F8a?5RZ6gPfzbNz4c`CYDDILAld|EGNH{eQY|m3aT3yo-1I(z_P??}cKkI47Te z>>FIUaF!o=-QC~5D8vkU!!YC{@B4MmKl3EJ+t-jnuzBSowv?s=T5RF9lssn?_B@Qw zn*U#ZYufKT(v0P3t#3JI$$_|(p0GGx@0o@6aM5BB!6OSdVir%?x_kylPuWU9rLV4HM+T42cjRutNI~=?520rt-hv-i-Dvbu!sz=F{WVs?u6;jQpxPrCS z7MCxcV>S!vR6Wu>r$3H4cd1Kb^*E_j#w(R@J-aZb>`#)>0@6HTI_wiT9@2K0&O)lS zI*57Iw(l|xL!vC9(^(;BKIzxE(k2T-M4F<~6xS=^`VF#N77{hJl>VG!X&4Op z)M_=P;~5TzCD3_J6h%yEDtR%#gOETx;N$ zj85GWHq*(}@JDK8f=Z24ODrK7jk=`Cm`=Ne5}t_%vjscbS18pQc)r7UG^Ew)poPV# zKfsfkX1!+KApzGPzl9I}>F;yt+|ziz%SxwRFu2XQ?wKbZ;n#lt$N5+P$8T`k3tnmf zw|R!++WY(heyPfVBgc5lKlw3ky5pWbVX-!rf7dUuy}fO8<(9=XoZ&bwvst)jAbXC_ zI!#j!9X-m^ryt|;#b-Hu^akQIM{B{CKK(IX^6EEo;`X~2+FK!@-sBLelEULEVP-V zF*{eD!OADBH7guByiTK8r?s-dwQj;FyoR!DGoaELQl|#wAuV!k`siAKk`9TkP_i{^ z>ypi@m+5vjt#*gC)fK|=fOfM^t?Ht+;+C6EaOKJ+kb;|UzKw?-euUX{Mx)-wD|-kM zY@5RL5>oLkjvu*>3m49iWFZGP>ZD=Fa5Cl0`Kwf#hY9K(>{1OaBw41HZcv4y#j*&a zkjZFBwNgc;30a!bXmqe_3zci6B^ix}gwsBq)(VanptLH|u5$!AlYSpf&c@mrw&Rg! zf;3m8Sxh*ZFdcSjcRIL11!cL|wp;Xsg;9A7y0km12euZ%2-@!b;J*EY#?Onaq;8w3btoE5X_l<|0g zQVHdhMCe|--C zx8L*91sN{SGJ+tWJ9pd`L_IWYUcJN{e(;|c*Px`^-Qv&w?_cEye(1-E;}oS8rBXmR z4Y6&TG>I3>r{Xz9nAT`4uD{_VPd)J%mFf=7R)?>C>2qAUaE^cVi@(F2_r82_O-nT2 z{OT9@nICyGAAa8-@#eR^{oAf2H{Nmwk397E96EM_pj2M0Er0ZX{Q{L*lM}bz#RvZL zA8_!<4gB=4{GKVcq`*#lfB&p)WEqCzA2R=)0r;lS<1ip(Oxa2Cuw_Va?hU;jK9$x42 zMJ*Q1)tb z72#G8wzFWZr16Y!u*+(*jpuj^#f=aG@{DlY!LniLX8I^;>p?#>q7 z-Zrjpv9h*8wO$7#nSy*yD3lVN=FG+;;&6=XTXfdfar`o93#AmJ{w|}zCW4G+vqi13 z2GT{=CDOK-40gz(kZQTkxHrIe9W2i! zP8E}Wmz7Qv%W+N1Xr2)&1#kV)pW@RW{Y!rLSAK?XeC11MAvp8IBmB-U{v@CL;QhSq zCw_YI8JKp52{qVr_DY0=*SzJeeBeF5$6x=&p8ybsQ-1H4e}+fD_V?Uy)9nP63VEJm z+cs|CGmB%gG%3_sMI4oo)SGPv-EGdCeuPXZ+@QpP>yB{#{CUzO;;-(1HwTX#9-ng^~Y)egB*OLll=EZWjSlQS6fuz*U*Ck!X}L5ZMTHf#(jkXq5(-7Sm& z72-HEV0hcY_k1i{FdPh+O()dqHKt*Rv>aUD$Mb9?CLyKOY~fWJ%<|%9sxdb)GDiI! zs+BUnS0>JizM{l%pC%ppb~nlMl*xEPlIM87N2zQy z&q_#x7+nf=kkVl~>f)DtEZ5k{rDc(&36oKmIF2Zl1DfqMgtSl^(!7vj&2#UhWHy~J z*x5o_7Axy3Xxk^%77{a{>vwm^q6uEfGlM(JC)dI}XO__2-NtuqR#rRcqC%HKFzD}+ zsf5mI8>JnTG7H3XG=MarU2ie!kEqmZ1hqO!SPX`{_<=_`Fc{al%4u$EzW3#?=BI!8 zclr2#`!nA4OFs?3)r;r2<*pa<3%~uJdC@ChXL|V3TFiND+vp7sUUzH}jPZ}&{*z2b z1ODp%ck|)<-;LJL?5yy!zxIdZO3~@88MbtuQ?ECej?Hybi}7uWMV1XiPY#rOR~KKN&U zz%!3M4BrOr0PydA<3I8H|L4#1Q$O^E#X9iPSAQRG`|)>x*8JGd{(GMI=2!TYpZe#E z_2zqj;Ggia*S?7_fBx_Ir~k{(Gifxqa_KVtexJifkK&emTAekTCr=`@*3YX($De%S zQN3@BywpQdJO|RhoUkASRsmW;FI(}&w{54)T|=Tcd4)>YymXFuxWnPKCTq=rQ@0;w zFq+Vt+H8&#k?>K%0O=i7K$)beQe$kCv~kF>bOO>MQx;m-2$>u5UOvUw6S7H+(>g}ooiPw(JGf{uBI{VA&zErceiNND^zNxlGj>b zW6|$*Q97oz)*{a>G#0j$M3X7Aai6u-ReC$Sj7D9qyYVdXyX*gzM?ST25G~{9q z?l8Z!}3mqTpayHvL`?mCjgQT_IWee6-k`2??z^ z`^2NPSJ!E*tS+uFM@Y^-eVX=4i_Y2s`nx?YoH@-6$B$F0w~cB<%7RR33Id92QWj9H z(~mw(yIJS(b;pQOwJ??$vBe^d^f`%EVh`xQD9Fr$(BIu+XY(p2Zo7La++#uZr`O%0 zyS2%QTTksd%nQe%ZCRjlu3R{#$T?Md(ByPCn4slc8St0m?rL1Ryy z|Gi$M{OUzKjz$)se!YNdy<3-9&p;u(Czi zY?_+^Bf=tAHjrQmP-JM4BQ;2Eql8`bP8B&RGnM1nE?(e(woxi&JRTs0#`j&eyM3gT z22f*J1b&$#2d|@43)tB_%XNp2u(> z1T}X6QGpE0^W57_=2I)NVtWXhH7WBJ4gs>=84TLE#f)y+Y)9DnI=b%%h zfO@UIw?GT9ghZt|Nirh}LzK=Kjrtrqc#xn}u&EW~xtYe#FEkdv2`nM$4R$D(102g{ z(Crh2Azt9pXt%IE&n$AeLTibXrtd8+3lxk71ET4ea=ApKQD=KI#<6|0aL_sQ`a49! zE`jG!@2q3_o*9NJu!R{GPlf~9jV9%4jU-D^mMJtQy)J^BR%ZpREQAKjlEl%B*?2^w z*#_HXJev@d18m153=JE5b**jMTY3+xDKywZ(jDyLl{{?ECCxR>&IZl)I`bH*MWmcE zQDj*>D^w%JpiRtguzHbrqP6DuEq59l^`h};cqff!o88?m?am7IMjgiw=ym(l8!O~w zg$STPH!SdJCfHd>$&JTP@WdnEq*`rLuD8gFXtH_spb=$>eK+5Q+G}4eZLWdV$~vu; z^(Cu0i$DQ@c4wV-du<^kK&yo!EX#7F6dXQ!J@r)o?u%Unw(O#L8b&xJ#&_NwZUi{a`wqbxc&Nr=VZ!nG*Qr5@D2>g~0Jq+CYS=)jGE2Ga8Le zkKJ(zN)=p7Fc}Q+N+rt82DvhcH@P;HJdtPgcDJ!Tk8-_9nu~=+OJLsf;a~@qCakQi zEl@SGs8-^5MjTJ@U56yfX?Hs0#a>-tktHeNY)F#Ku%x6`D>DnHtgfu$musY%G8e97 z52m$*rxn^b1hvYDrX$K_pRMg39LJ}>6GE9k7G$XYpZyU zM-t6Yc}A&JAxmR+ceV&;AuFvm)kYH~Eb`poGbMsvZ-+dK>8!SJ-4aQrj6p{!CjB0c zEveL-C?qO3QCUeG(d+HdZZ@z>0fW)Rz@el?o-4Y&ZK}00j^h($W|3Q{O(i5*LL7&z zZmg22VmTFs9$M{5Q4Rf57DM5fdc9(9a=Bi36!v1~SP%Engl8{Y;aWeY z)V_|DLnoLiYZ1PQHd$FU8jv`FbTAE3gqEGFY2X*^?PWpxj3 zCA6uIlZ4r5K(*pB9*?LtI%w&kG9#ax%_8zF#}903^%}nKlf@BH6tS|pPL}JUB_HRjV{xRcy~kW0B^HT$tz?S@44$+agO-`U69eYt$>0DrGWk z5~WGv1jn*Tl8|egSFtUN0|yQel*=T!k%KyxgUS`VJ6l+eVr8uZ*d$7s_czZN5Bm7F zi&w3fxhldWi)RVl?k2TH6~9_xIu1?ZNv%OTo6+xek&Ym!nY0>dS;f$=Fs9g&QLj&_ zSwuqq9`!T}vI6BX9sg|qsx;^UkI@M~E z?(Qy=(U4NTMUu}6lzB1yHLph%JAfortgRnpJREWEsV6vb>+L4dOYa55N=!Aa3mGBB z+-l*a;5i{6`Z-}NOM-&E^=2vVNiOX~3z=@7<=8?}tCV>1$tRzuw(w$sUZi~MrESS` z-rS{3g}vOXrMs*`6@w^{i;6)aWzO#Ac_up-IM`|6*n-W?E4=h&_c5D=oIZ1jjrHr8 zzcf`tiVnhi?`Vtr)i89HX0Xj$crtS1XMgAiKg6h=gn+% zI(+@{3q<+~cieF=zW*p!u5Kay8rm)qMiFa`3U$XPp7dC)mr!}mrL8WbnZ&PeuyW`) ziSW#AXr8`YY)jKPW;o~}g{dGXCEVMw{Sg=TD?=qx{6`06iB7%?e1XP4z*_6Xotl-dQ4$UnhjnInWsLymXHra#gt5}w8@))JY zu`I^Pj3k_Kbuyq-tFXGVftEgr%F$?C%OOo7dfhIb=g@4gkf}mRVhOS=BI@_?Js-bP zG3|w7NS3Rd?#@+e)qrZXPL{%SJfhXClO-{Ooo$3IXs>RdbU|xGqqIP33n4XG6p}qw>NAvpIaQq2qAE6n>1I&xy_RV^@8=CW}54d9p~|HevQp57g;}YJyD!4!WTr* z^4u@IT^1HBaY&Xb=H&|d+d7sP1~}6TUoIG>v`|{}g}?h4fBDpxpND3azmef^$_#;W ztMo@hYLzNNSWLo%N~J<3JbIH5C2ed=A|=?C!qyt{*rZu#jZz6pfGu2nk`o1}@N;(1tD%)$h%G_yD+jAM33F*99a z{qS*=^a_KDMrEo9bk&R}6I3*%Rx6XHIeD(|D>b4-qoOI&lK5UgI0>;Fn*(d>Shh{7 zGIZh7vn-1=jTv>f@cn>FqgBxIC@yx5g=Ww*5TAOhXiv-sZPM&6RF*Iv4{0=7Sh7T# zYrryw2chY8cd%TGLisR^xhqp zM9mu&McPim(%u`dnLoryjOTg9PDm}>xndC=ruPPPQam?M8&IT55R@ypo=3mC%le@T zjaGx5?aPMQU2hr%$|5UrFMwnI{c@FK*$&4}+{}}Yf0JsxhF5KoRceLDBJnHAGndPZR9s>Rljpptbzl!T_ylL?cKm4Un zaq-+!`&AlCtNYzAekDh4ym{dy`r4O1&BZfMEy!r|PDnhPFdcV!$%|h|`M^oyXol-p zeB+TvIsNoA%yNOUTy!$SwZL&bq-FEs@BSVd>&M7sKrS^8f9?S;o_%tUGk{tO2*`Nl ztG|asM^BRK97hNq{LJ6+^rPRP(WWR`%CyzoUYC(AT1xbq}YCi&oB z{Wa&#Jj>>_ZJPB8LZ@f}(^*WMNxtXJZ$n#U(kvxSXME+0pW@=Vr;$RKbnHywI+8q3 z$dux~?|MB)Z@dlLweh_wU;E-GdE%Q7p)~lVauJ{`7Vqr6-~BocAHAOb?k2Tzna3V} zh_g>WSsbSqllWOU1r)D%-9Mn-Sy@CLef4vn;KG^H=H@aB@m!N7sFbNr?)$FSas1{x z7!S75@r=hG{xYW@e;C(uu`Cy>NcWguIQM?n_j2^)Em+c|Yd`pzPte=GY8b|P$%87) zg?it2eJ`sAk1(B1v83ee6JO)<`KOtThK2`idrRA2&AqR99mj9F6P=|D2YtTuxsS7T z^;ulkD~54;p)9ea;M6@Y#&I2N35SlKHq>J#9SG|E7Zn|x;;C<;+ALHzkk9|ky@QYsc29Do)C!Lj5 zwy#~{=_elMsmC5>(C_i!-~Bb!dSl7s055s<8#r;(9S98>n!kVGqnv&6G2;Zb1e4K_ zPk#7)tgdeW7B76&8@TbN+l@L4!51I+C}&SUy3f3}{NGDn^G1%}ayx}8l`nkqBb+(? z=(p`(1H9}tZ{WsT?pW}wKmW-ObN0zc7i-Vi(~olFq0aMbk^Ye%`H_8(-|~{eQ`^$Bpm|59{u?IdTQKp0|Aen>cmq)ZX)d=tIo1{5wAX zeYfAR@A&HQ86H;O`Ssj)=gED?)4zzX!^Oj9v$gN|?|$iBi{o#(`4mq-^(<+Warn@o zZ?7xA_XMX-omf1sgy(r!48P;+dCSXg-uHgm-N*2v!{71v@40iGQ>RV>C(Zj4UB-_# zzs-?#0A6+HK~9}Ix+lZhS*Nr(zV$8t>NR(+bL!Lq;DC94u|rjizT@k8^&K0WI(204 z`FC&P;fJH|th>K$jZ>#?+WUNy3p^Zc!AAYtKmV<(oI15uJUT>Wc9w@9o_@#Yf6YC| z_IfqvWa$yZGJop`-|Mf3EzVCca&adFl_GE6X1^dsR zlWk7jx%c(#*&5cM3RJ)C^MCj8*1qG@b2aQi$vjvMzUBCr9f=Y zzx2i$r*5tn=f@3v=tCbO+o`}><=Y+c=VS}CsGV$nTT*?0W( z$r9{%-|_Xl@MxJ+Cu)nw pUrl Then SetGadgetToolTip( tmpLabel, pUrl ) + + SetProxy( tmpLabel );Super.SetTextColor(colors[0][0], colors[0][1], colors[0][2]) + + hyperlinkstyle = style;extra = pUrl + lstHyperlinkGadgets.AddLast Self + + Return Self + + EndMethod + + Method EventHook:TEvent( pEvent:TEvent ) + + Select pEvent.id + + Case EVENT_MOUSEENTER + Super.SetTextColor(colors[1][0], colors[1][1], colors[1][2]);SetPointer(POINTER_HAND) + Super.SetFont( fntHoverDefault ) + Case EVENT_MOUSELEAVE + Super.SetTextColor(colors[0][0], colors[0][1], colors[0][2]);SetPointer(POINTER_DEFAULT) + Super.SetFont( fntDefault ) + Case EVENT_MOUSEDOWN;If lastclick[0] <> pEvent.x Or lastclick[1] <> pEvent.y Then lastclick = [pEvent.x,pEvent.y];OpenURL(String(extra)) + + EndSelect + + Return Null + + EndMethod + + Method SetFont( font:TGuiFont ) + fntDefault = font;fntHoverDefault = font + Super.SetFont(font) + EndMethod + + Method SetColor(r,g,b) + colors[1][0] = r;colors[1][1] = g;colors[1][2] = b + EndMethod + + Method SetTextColor(r,g,b) + colors[0][0] = r;colors[0][1] = g;colors[0][2] = b + Super.SetTextColor(colors[0][0], colors[0][1], colors[0][2]) + EndMethod + + Method CleanUp() + lstHyperlinkGadgets.Remove(Self) + Super.CleanUp() + EndMethod + + Function Initialize() + lstHyperlinkGadgets = New TList + AddHook EmitEventHook, eventHandler, Null, -1 + fntDefault = LookupGuiFont( GUIFONT_SYSTEM, 0, 0 ) + fntHoverDefault = LookupGuiFont( GUIFONT_SYSTEM, 0, FONT_UNDERLINE ) + EndFunction + + Function eventHandler:Object( pID%, pData:Object, pContext:Object ) + Local pEvent:TEvent = TEvent(pData) + + If pEvent Then + For Local tmpHyperlinkGadget:THyperlinkGadget = EachIn lstHyperlinkGadgets + If tmpHyperlinkGadget = pEvent.source Then Return tmpHyperlinkGadget.EventHook( pEvent ) + Next + EndIf + + Return pData + EndFunction + +EndType diff --git a/mod/maxgui.mod/proxygadgets.mod/proxygadgets.bmx b/mod/maxgui.mod/proxygadgets.mod/proxygadgets.bmx new file mode 100644 index 0000000..d142bb4 --- /dev/null +++ b/mod/maxgui.mod/proxygadgets.mod/proxygadgets.bmx @@ -0,0 +1,16 @@ +Strict + +Rem +bbdoc: MaxGUI/Proxy Gadgets +about: This module contains any official proxy gadgets that wrap around the standard MaxGUI gadgets and provide an additional library +of gadgets that can be used in a whole host of programs. Any gadgets in this library can be used with the standard MaxGUI functions +available in the core #MaxGUI.MaxGUI module. +End Rem +Module MaxGUI.ProxyGadgets + +ModuleInfo "Version: 1.12" +ModuleInfo "License: zlib/libpng" + +Import "hyperlink.bmx" +Import "splitter.bmx" +Import "scrollpanel.bmx" diff --git a/mod/maxgui.mod/proxygadgets.mod/scrollpanel.bmx b/mod/maxgui.mod/proxygadgets.mod/scrollpanel.bmx new file mode 100644 index 0000000..5bea8e6 --- /dev/null +++ b/mod/maxgui.mod/proxygadgets.mod/scrollpanel.bmx @@ -0,0 +1,518 @@ +Strict + +Import MaxGUI.MaxGUI + +' TScrollPanel Proxy Gadget +' Author: Seb Hollington + +Const SCROLLPANEL_SUNKEN:Int = 1 +Const SCROLLPANEL_HALWAYS:Int = 2 +Const SCROLLPANEL_VALWAYS:Int = 4 + +Const SCROLLPANEL_HSCALING:Int = 8 +Const SCROLLPANEL_VSCALING:Int = 16 + +Const SCROLLPANEL_HNEVER:Int = 32 +Const SCROLLPANEL_VNEVER:Int = 64 + +Rem +bbdoc: Creates a scrollable panel. +about: A scroll panel can be used to present a large number of gadgets in a small area. Scrollbars are displayed to allow the +user to move around a client-area that is viewed through a, typically smaller, viewport. The #ScrollPanelX and #ScrollPanelY functions +can be used to retrieve the current scroll position, and the #ScrollScrollPanel command, to set the scroll position. A @TScrollPanel gadget +emits the following event when %{the user} scrolls around the scroll area: + +[ @{Event} | @{EventX} | @{EventY} +* EVENT_GADGETACTION | New value of #ScrollPanelX. | New value of #ScrollPanelY. +] + +Any combination of the following style flags are supported: + +[ @Constant | @Meaning +* SCROLLPANEL_SUNKEN | The scroll-panel will be drawn with a sunken border. +* SCROLLPANEL_HALWAYS | The horizontal scroll-bar will be shown at all times (even if not necessary). +* SCROLLPANEL_VALWAYS | The vertical scroll-bar will be shown at all times (even if not necessary). +* SCROLLPANEL_HNEVER | The horizontal scroll-bar will never be shown (even if client-area width is greater than viewport's). +* SCROLLPANEL_VNEVER | The vertical scroll-bar will never be shown (even if client-area height is greater than viewport's). +] + +The above can also be combined with any of the following behavioural flags which determine how the scrollable client-area resizes with the viewport: + +[ @Constant | @Meaning +* SCROLLPANEL_HSCALING | The client area's width grows uniformly as the viewport is sized. +* SCROLLPANEL_VSCALING | The client area's height grows uniformly as the viewport is sized. +] + +[ +* The @TScrollPanel instance itself represents the viewport of the scroll-panel, which can be manipulated (e.g. resized/shown/hidden) using the +standard MaxGUI commands. +* The client area is the panel that will actually be scrolled and is retrieved using the #ScrollPanelClient command. This is the panel +whose dimensions determine the total scrollable area, and is also the panel that all your child gadgets should be added to. +] + + + +The dimensions given above can each be retrieved programatically: + +{{ +GadgetWidth( myScrollPanel ) 'Gadget Width +GadgetHeight( myScrollPanel ) 'Gadget Height + +ClientWidth( myScrollPanel ) 'Viewport Width +ClientHeight( myScrollPanel ) 'Viewport Height + +ClientWidth( ScrollPanelClient( myScrollPanel ) ) 'Client Area Width +ClientHeight( ScrollPanelClient( myScrollPanel ) ) 'Client Area Height +}} + +And the gadget and client dimensions can be set programatically using (viewport sizing is handled automatically): + +{{ +'Set Gadget dimensions (and position). +SetGadgetShape( myScrollPanel, x, y, w, h ) + +'Set Client Area dimensions (position parameters are ignored). +SetGadgetShape( ScrollPanelClient( myScrollPanel ), 0, 0, w, h ) +}} + +See Also: #ScrollPanelClient, #FitScrollPanelClient, #ScrollScrollPanel, #ScrollPanelX, #ScrollPanelY and #FitScrollPanelClient. +End Rem +Function CreateScrollPanel:TScrollPanel( x,y,w,h,group:TGadget,flags=0 ) + + Return New TScrollPanel.Create(x,y,w,h,group,flags) + +EndFunction + +Rem +bbdoc: Retrieves the panel that is scrolled. +about: This panel represents the total scrollable region of the gadget. As such, use #SetGadgetShape on this panel to alter the +scrollable region (the xpos and ypos parameters will be ignored) or use the helper function #FitScrollPanelClient to resize the client area to +common dimensions. In either case, it is important to note that, contrary to typical MaxGUI behaviour, resizing the client panel +%{will not alter the position or dimensions of the children}, irrespective of any sizing behaviour previously defined using #SetGadgetLayout. + +See #CreateScrollPanel for more information. +End Rem +Function ScrollPanelClient:TGadget( scrollpanel:TScrollPanel ) + Return scrollpanel.pnlClientArea +EndFunction + +Const SCROLLPANEL_SIZETOKIDS:Int = 0 +Const SCROLLPANEL_SIZETOVIEWPORT:Int = 1 + +Rem +bbdoc: Helper function that resizes the client area to common dimensions. +about: This function resizes the scrollable area of a @TScrollPanel widget. Any child gadgets will retain their current +position and dimensions, irrespective of any sizing behaviour previously defined using #SetGadgetLayout. This function will +also reset the current visible area, to the furthest top-left. + +[ +* @scrollpanel: The scrollpanel whose client you want to resize. +* @fitType: Should be one of the following constants: +] + +[ @Constant | @Meaning +* SCROLLPANEL_SIZETOKIDS | The client area will be resized so that its width and height are just enough to enclose all child gadgets. +* SCROLLPANEL_SIZETOVIEWPORT | The client area will be resized so that it is the same size that the viewport is currently (effectively removing the scrollbars). +] + +See #CreateScrollPanel and #ScrollPanelClient for more information. +End Rem +Function FitScrollPanelClient( scrollpanel:TScrollPanel, fitType% = SCROLLPANEL_SIZETOKIDS ) + Select fitType + Case SCROLLPANEL_SIZETOKIDS + scrollpanel.FitToChildren() + Case SCROLLPANEL_SIZETOVIEWPORT + scrollpanel.FitToViewport() + EndSelect +EndFunction + +Const SCROLLPANEL_HOLD:Int = -1 +Const SCROLLPANEL_TOP:Int = 0 +Const SCROLLPANEL_LEFT:Int = 0 +Const SCROLLPANEL_BOTTOM:Int = 2147483647 +Const SCROLLPANEL_RIGHT:Int = 2147483647 + +Rem +bbdoc: Scrolls the current viewport to a new position. +about: This function moves the client area of the scroll panel so that the the top-left corner of the viewport is as close +as possible to the specified @{pX}, @{pY} position in the client-area. + + + +There are 4 position constants provided: + +[ @Constant | @{Position} +* SCROLLPANEL_TOP | Top-most edge. +* SCROLLPANEL_LEFT | Left-most edge. +* SCROLLPANEL_BOTTOM | Bottom-most edge. +* SCROLLPANEL_RIGHT | Right-most edge. +* SCROLLPANEL_HOLD | Current position. +] + +For example, both of these commands... + +{{ +ScrollScrollPanel( myScrollPanel, SCROLLPANEL_LEFT, SCROLLPANEL_TOP ) +ScrollScrollPanel( myScrollPanel, 0, 0 ) +}} +...would scroll to the top-leftmost section of the client area. Conversely, we can scroll to the bottom-right most +region of the client area by calling: +{{ +ScrollScrollPanel( myScrollPanel, SCROLLPANEL_RIGHT, SCROLLPANEL_BOTTOM ) +}} + +If we only want to change just the horizontal or just the vertical scroll position, we can use the SCROLLPANEL_HOLD constant. E.g. +to scroll to the left most side without changing the current vertical scroll position, we could use: +{{ +ScrollScrollPanel( myScrollPanel, SCROLLPANEL_LEFT, SCROLLPANEL_HOLD ) +}} + +See #CreateScrollPanel, #ScrollPanelX, #ScrollPanelY and #ScrollPanelClient for more information. +EndRem +Function ScrollScrollPanel( scrollpanel:TScrollPanel, pX = SCROLLPANEL_TOP, pY = SCROLLPANEL_LEFT ) + scrollpanel.ScrollTo( pX, pY ) + scrollpanel.Update() +EndFunction + +Rem +bbdoc: Returns the x position of the client-area that is currently at the top-left of the viewport. +about: Complementary function to #ScrollPanelY and #ScrollScrollPanel. See #ScrollScrollPanel for a visual representation +of this value. + +See #CreateScrollPanel for more information. +EndRem +Function ScrollPanelX:Int( scrollpanel:TScrollpanel ) + Return scrollpanel.GetXScroll() +EndFunction + +Rem +bbdoc: Returns the y position of the client-area that is currently at the top-left of the viewport. +about: Complementary function to #ScrollPanelX and #ScrollScrollPanel. See #ScrollScrollPanel for a visual representation +of this value. + +See #CreateScrollPanel for more information. +EndRem +Function ScrollPanelY:Int( scrollpanel:TScrollpanel ) + Return scrollpanel.GetYScroll() +EndFunction + +Type TScrollPanel Extends TProxyGadget + + Field flags:Int + + Field pnlEntire:TGadget + Field pnlViewport:TGadget + Field pnlClientArea:TScrollClient + Field scrHorizontal:TGadget + Field scrVertical:TGadget + + Field currentH%, currentV%, clientW%, clientH% + + Const SCROLL_WIDTH% = 18 + + Method New() + + AddHook EmitEventHook,eventHandler,Self, -1 + RemoveVerticalScroll();RemoveHorizontalScroll() + + EndMethod + + Method Create:TScrollPanel(pX%, pY%, pWidth%, pHeight%, pParent:TGadget, pFlags% = 0) + + Local tmpPanelFlags:Int + + flags = pFlags + + If flags & (SCROLLPANEL_SUNKEN) Then tmpPanelFlags:|PANEL_SUNKEN + + pnlEntire = CreatePanel(pX,pY,pWidth,pHeight,pParent,tmpPanelFlags);HideGadget(pnlEntire);SetProxy(pnlEntire) + pnlViewport = CreatePanel(0,0,pnlEntire.ClientWidth(),pnlEntire.ClientHeight(), pnlEntire) + pnlClientArea = New TScrollClient + pnlClientArea.SetProxy(CreatePanel(0,0,pnlViewport.ClientWidth(),pnlViewport.ClientHeight(), pnlViewport)) + scrHorizontal = CreateSlider(0,pnlEntire.ClientHeight()-SCROLL_WIDTH,pnlEntire.ClientWidth()-SCROLL_WIDTH,SCROLL_WIDTH, pnlEntire, SLIDER_HORIZONTAL|SLIDER_SCROLLBAR ) + scrVertical = CreateSlider(pnlEntire.ClientWidth()-SCROLL_WIDTH,0,SCROLL_WIDTH,pnlEntire.ClientHeight()-SCROLL_WIDTH, pnlEntire, SLIDER_VERTICAL|SLIDER_SCROLLBAR ) + + SetGadgetLayout(pnlViewport, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED ) + SetGadgetLayout(scrHorizontal, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_CENTERED, EDGE_ALIGNED ) + SetGadgetLayout(scrVertical, EDGE_CENTERED, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED ) + + Select (flags & (SCROLLPANEL_HSCALING|SCROLLPANEL_VSCALING)) + Case 0 + SetGadgetLayout(pnlClientArea.GetProxy(), EDGE_ALIGNED, EDGE_CENTERED, EDGE_ALIGNED, EDGE_CENTERED ) + Case SCROLLPANEL_HSCALING + SetGadgetLayout(pnlClientArea.GetProxy(), EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_CENTERED ) + Case SCROLLPANEL_VSCALING + SetGadgetLayout(pnlClientArea.GetProxy(), EDGE_ALIGNED, EDGE_CENTERED, EDGE_ALIGNED, EDGE_ALIGNED ) + Case SCROLLPANEL_HSCALING|SCROLLPANEL_VSCALING + SetGadgetLayout(pnlClientArea.GetProxy(), EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED ) + EndSelect + + HideGadget(scrHorizontal);HideGadget(scrVertical) + + ShowGadget(pnlEntire) + + Return Self + + EndMethod + + Method SetShape(x,y,w,h) + Super.SetShape(x,y,w,h) + Update() + EndMethod + + Method ClientWidth:Int() + Return pnlViewport.ClientWidth() + EndMethod + + Method ClientHeight:Int() + Return pnlViewport.ClientHeight() + EndMethod + + Method GetXScroll:Int() + Return currentH + EndMethod + + Method GetYScroll:Int() + Return currentV + EndMethod + + Method ScrollTo(pHSlider%, pVSlider%) + + Local tmpRight:Int = Max( pnlClientArea.ClientWidth()-pnlViewport.ClientWidth(), 0 ) + Local tmpBottom:Int = Max( pnlClientArea.ClientHeight()-pnlViewport.ClientHeight(), 0 ) + + If (pHSlider > tmpRight) Then pHSlider = tmpRight + If (pVSlider > tmpBottom) Then pVSlider = tmpBottom + + If (pHSlider >= 0) Then currentH = pHSlider + If (pVSlider >= 0) Then currentV = pVSlider + + SetGadgetShape(pnlClientArea.GetProxy(),-currentH,-currentV,pnlClientArea.GetWidth(),pnlClientArea.GetHeight()) + + EndMethod + + Method FitToChildren( pRightMargin:Int = 0, pBottomMargin:Int = 0 ) + + Local tmpRight:Int, tmpBottom:Int + + For Local tmpChild:TGadget = EachIn pnlClientArea.proxy.kids + tmpRight = Max(tmpRight,GadgetX(tmpChild)+GadgetWidth(tmpChild)) + tmpBottom = Max(tmpBottom,GadgetY(tmpChild)+GadgetHeight(tmpChild)) + Next + + HideGadget( pnlViewport ) + pnlClientArea.SetShape(0,0,tmpRight + pRightMargin,tmpBottom + pBottomMargin) + ScrollTo(0,0) + ShowGadget( pnlViewport ) + + EndMethod + + Method FitToViewport() + + HideGadget( pnlViewport ) + pnlClientArea.SetShape(0,0,pnlViewport.ClientWidth(),pnlViewport.ClientHeight()) + ScrollTo(0,0) + ShowGadget( pnlViewport ) + + EndMethod + + Method Update() + + Local tmpDiff:Int, tmpPos:Int + + If Not pnlClientArea Then Return + + If pnlViewport.ClientWidth() < pnlClientArea.GetWidth() Then + AddHorizontalScroll(pnlViewport.ClientWidth(),pnlClientArea.GetXPos(),pnlClientArea.GetWidth()) + Else + RemoveHorizontalScroll() + EndIf + + If pnlViewport.ClientHeight() < pnlClientArea.GetHeight() Then + AddVerticalScroll(pnlViewport.ClientHeight(),pnlClientArea.GetYPos(),pnlClientArea.GetHeight()) + Else + RemoveVerticalScroll() + EndIf + + If pnlViewport.ClientWidth() < pnlClientArea.GetWidth() Then + + tmpDiff = Max(pnlViewport.ClientWidth()-(pnlClientArea.GetXpos() + pnlClientArea.GetWidth()),0) + tmpPos = Min(pnlClientArea.GetXPos()+tmpDiff,0) + + AddHorizontalScroll(pnlViewport.ClientWidth(),tmpPos,pnlClientArea.GetWidth()) + ScrollTo( -tmpPos, currentV ) + + Else + + RemoveHorizontalScroll() + + EndIf + + If pnlViewport.ClientHeight() < pnlClientArea.GetHeight() Then + + tmpDiff = Max(pnlViewport.ClientHeight()-(pnlClientArea.GetYPos() + pnlClientArea.GetHeight()),0) + tmpPos = Min(pnlClientArea.GetYPos()+tmpDiff,0) + + AddVerticalScroll(pnlViewport.ClientHeight(),tmpPos,pnlClientArea.GetHeight()) + ScrollTo( currentH, -tmpPos ) + + Else + + RemoveVerticalScroll() + + EndIf + + EndMethod + + Method AddVerticalScroll(pVisible%, pY%, pHeight%) + + If scrVertical And Not (flags&SCROLLPANEL_VNEVER) Then + + SetGadgetShape(pnlViewport, 0, 0, pnlEntire.ClientWidth() - SCROLL_WIDTH, GadgetHeight(pnlViewport)) + SetGadgetShape(scrVertical, pnlEntire.ClientWidth()-SCROLL_WIDTH, 0, SCROLL_WIDTH, GadgetHeight(pnlViewport)) + + SetSliderRange(scrVertical, pVisible, pHeight);SetSliderValue(scrVertical,-pY) + EnableGadget(scrVertical);ShowGadget(scrVertical) + + EndIf + + EndMethod + + Method RemoveVerticalScroll() + + If scrVertical And Not GadgetDisabled(scrVertical) Then + + If Not (flags&SCROLLPANEL_VALWAYS) Then + HideGadget(scrVertical) + SetGadgetShape(pnlViewport, 0, 0, pnlEntire.ClientWidth(), GadgetHeight(pnlViewport)) + EndIf + + DisableGadget(scrVertical) + + ScrollTo(currentH,0) + + EndIf + + EndMethod + + Method AddHorizontalScroll(pVisible%, pX%, pWidth%) + + If scrHorizontal And Not (flags&SCROLLPANEL_HNEVER) Then + + SetGadgetShape(pnlViewport, 0, 0, GadgetWidth(pnlViewport), pnlEntire.ClientHeight()-SCROLL_WIDTH ) + SetGadgetShape(scrHorizontal, 0, pnlEntire.ClientHeight()-SCROLL_WIDTH, GadgetWidth(pnlViewport), SCROLL_WIDTH) + + SetSliderRange(scrHorizontal, pVisible, pWidth);SetSliderValue(scrHorizontal,-pX) + EnableGadget(scrHorizontal);ShowGadget(scrHorizontal) + + EndIf + + EndMethod + + Method RemoveHorizontalScroll() + + If scrHorizontal And Not GadgetDisabled(scrHorizontal) Then + + If Not (flags&SCROLLPANEL_HALWAYS) Then + SetGadgetShape(pnlViewport, 0, 0, GadgetWidth(pnlViewport), pnlEntire.ClientHeight()) + HideGadget(scrHorizontal) + EndIf + + DisableGadget(scrHorizontal) + + ScrollTo(0,currentV) + + EndIf + + EndMethod + + Method eventHook:Object(pID%, pData:Object, pContext:Object) + + Local tmpEvent:TEvent = TEvent(pData) + If tmpEvent = Null Then Return pData + + Select tmpEvent.id + + Case EVENT_WINDOWSIZE + + If CheckParent(pnlEntire, TGadget(tmpEvent.source)) Then Update() + + Case EVENT_GADGETACTION + + Local tmpH:Int = currentH, tmpV:Int = currentV + + Select tmpEvent.source + + Case scrHorizontal + tmpH = SliderValue(scrHorizontal) + Case scrVertical + tmpV = SliderValue(scrVertical) + Default + Return pData + + EndSelect + + ScrollTo(tmpH, tmpV) + EmitEvent CreateEvent( EVENT_GADGETACTION, Self, 0, 0, currentH, currentV, Null ) + pData = Null + + EndSelect + + Return pData + + EndMethod + + Method CleanUp() + + RemoveHook EmitEventHook, eventHandler, Self + SetProxy(Null) + If pnlClientArea Then pnlClientArea.SetProxy(Null);pnlClientArea = Null + If pnlEntire Then HideGadget(pnlEntire);FreeGadget(pnlEntire) + + EndMethod + + Function eventHandler:Object(pID%, pData:Object, pContext:Object) + + Local tmpSuperPanel:TScrollPanel = TScrollPanel(pContext) + If tmpSuperPanel Then pData = tmpSuperPanel.eventHook(pID%, pData:Object, pContext:Object) + Return pData + + EndFunction + + Function CheckParent%( pGadget:TGadget, pParentToCheck:TGadget ) + + If pGadget = pParentToCheck Then Return True + If pGadget.parent Then Return CheckParent(pGadget.parent, pParentToCheck) + + EndFunction + +EndType + +Private + +Type TScrollClient Extends TProxyGadget + + Method SetShape(x,y,w,h) + + Local i:Int, arrDimensions:Int[][], tmpDimensions:Int[] + + For Local tmpChild:TGadget = EachIn proxy.kids + tmpDimensions = [GadgetX(tmpChild),GadgetY(tmpChild),GadgetWidth(tmpChild),GadgetHeight(tmpChild)] + arrDimensions:+[tmpDimensions] + Next + + Super.SetShape(GetXPos(),GetYPos(),w,h) + TScrollPanel(proxy.parent.parent.source).Update() + + For Local tmpChild:TGadget = EachIn proxy.kids + tmpDimensions = arrDimensions[i];i:+1 + SetGadgetShape( tmpChild, tmpDimensions[0], tmpDimensions[1], tmpDimensions[2], tmpDimensions[3] ) + Next + + EndMethod + + Method SetLayout(lft,rht,top,bot) + 'Do nothing + EndMethod + +EndType diff --git a/mod/maxgui.mod/proxygadgets.mod/splitter.bmx b/mod/maxgui.mod/proxygadgets.mod/splitter.bmx new file mode 100644 index 0000000..67b0927 --- /dev/null +++ b/mod/maxgui.mod/proxygadgets.mod/splitter.bmx @@ -0,0 +1,817 @@ +SuperStrict + +Import MaxGUI.MaxGUI + +' TSplitter Proxy Gadget +' Author: Seb Hollington + +Rem +bbdoc: Creates a gadget consisting of two panels separated by a draggable divider. +about: A splitter is made up of two panels: a main panel (identified using SPLITPANEL_MAIN) which acts as the main working area; and a side pane +(identified using SPLITPANEL_SIDEPANE) which is typically used to display additional information. Both of these panels are contained within a +parent panel that is represented by the @TSplitter instance. The two panels are separated by a split handle/divider, the behavior of which can be +queried and altered using the #SplitterBehavior and #SetSplitterBehavior functions respectively. + +The size of the split handle is determined using the optional @pHandleSize parameter. The default size of 10 pixels should work well in most +situations, and the minimum value that this can be is 4. + +After creating a splitter gadget, you can start adding gadgets to it by retrieving the appropriate panel with the #SplitterPanel command. + +The @TSplitter type instance can be used with most of the standard MaxGUI commands, allowing you to change the properties of the entire splitter +gadget. There are, however, a few exceptions: + +#SetGadgetSensitivity and #GadgetSensitivity will have no effect on the splitter gadget. If you want to use active panels, create your own +sub-panel within each splitter panel. + +#SetGadgetTooltip and #GadgetTooltip will set/retrieve a tooltip for when the user is hovering over the splitter handle/divider. + +#SetGadgetColor will modify the split handle/divider background color. + +See Also: #SplitterPanel, #SetSplitterPosition, #SplitterPosition, #SetSplitterBehavior, #SplitterBehavior, #SetSplitterOrientation and #SplitterOrientation. +End Rem +Function CreateSplitter:TSplitter( pX%, pY%, pW%, pH%, pParent:TGadget, pOrientation% = SPLIT_VERTICAL, pHandleSize% = 10 ) + Return New TSplitter.Create( pX, pY, pW, pH, pParent, pOrientation, pHandleSize ) +EndFunction + +Const SPLITPANEL_MAIN% = 0, SPLITPANEL_SIDEPANE% = 1, SPLITPANEL_HANDLE% = 2 + +Rem +bbdoc: Retrieves either one of the two panels which make up a TSplitter gadget. +about: This function is used to return a standard MaxGUI panel that you can add your gadgets to. + +The panels available are SPLITPANEL_MAIN and SPLITPANEL_SIDEPANE. See #CreateSplitter for more information +about the differences between the two panels. + +See Also: #CreateSplitter, #SetSplitterPosition, #SplitterPosition, #SetSplitterBehavior, #SplitterBehavior, #SetSplitterOrientation and #SplitterOrientation. +End Rem +Function SplitterPanel:TGadget( splitter:TSplitter, panel% = SPLITPANEL_MAIN ) + Return splitter.GetPanel(panel) +EndFunction + +Rem +bbdoc: Sets the position of the splitter (in pixels) from the edge of a TSplitter gadget. +about: This function's most common use is to restore a split position previously returned by #SplitterPosition. + +The optional @save% parameter determines whether or not the position supplied is restored when the splitter returns from it's hidden state. +In most circumstances, this should be left as #True. + +See Also: #CreateSplitter, #SplitterPanel, #SplitterPosition, #SetSplitterBehavior, #SplitterBehavior, #SetSplitterOrientation and #SplitterOrientation. +End Rem +Function SetSplitterPosition( splitter:TSplitter, position%, save% = True ) + splitter.SetPanelSpace( position, save ) +EndFunction + +Rem +bbdoc: Returns the position of the splitter (in pixels) from the edge of a TSplitter gadget. +about: This function's most common use is probably for saving the current splitter position to restore at a later time using #SetSplitterPosition. + +See Also: #CreateSplitter, #SplitterPanel, #SetSplitterPosition, #SetSplitterBehavior, #SplitterBehavior, #SetSplitterOrientation and #SplitterOrientation. +End Rem +Function SplitterPosition:Int( splitter:TSplitter ) + Return splitter.GetPanelSpace( SPLITPANEL_SIDEPANE ) +EndFunction + +Const SPLIT_HORIZONTAL% = 0, SPLIT_VERTICAL% = 1, SPLIT_FLIPPED% = 2 + +Rem +bbdoc: Sets the splitter orientation. +about: The two orientations available are (both of which can be combined with SPLIT_FLIPPED): + +[ @Orientation | @Description +* -1 | Toggles the SPLIT_FLIPPED flag. +* SPLIT_VERTICAL | The splitter consists of a main left panel with a side-pane along the right edge. +* SPLIT_HORIZONTAL | The splitter consists of a main top panel with a side-pane along the bottom edge. +* SPLIT_VERTICAL ~| SPLIT_FLIPPED | The splitter consists of a main right panel with a side-pane along the left edge. +* SPLIT_HORIZONTAL ~| SPLIT_FLIPPED | The splitter consists of a main bottom with a side-pane along the top edge. +] + +See Also: #CreateSplitter, #SplitterPanel, #SetSplitterPosition, #SplitterPosition, #SetSplitterBehavior and #SplitterOrientation. +End Rem +Function SetSplitterOrientation( splitter:TSplitter, orientation% = -1 ) + splitter.ChangeOrientation( orientation ) +EndFunction + +Rem +bbdoc: Returns the orientation of the splitter. +about: The two orientations available are (both of which can be combined with SPLIT_FLIPPED): + +[ @Orientation | @Description +* SPLIT_VERTICAL | The splitter consists of a main left panel with a side-pane along the right edge. +* SPLIT_HORIZONTAL | The splitter consists of a main top panel with a side-pane along the bottom edge. +* SPLIT_VERTICAL ~| SPLIT_FLIPPED | The splitter consists of a main right panel with a side-pane along the left edge. +* SPLIT_HORIZONTAL ~| SPLIT_FLIPPED | The splitter consists of a main bottom with a side-pane along the top edge. +] + +See Also: #CreateSplitter, #SplitterPanel, #SetSplitterPosition, #SplitterPosition, #SetSplitterBehavior and #SetSplitterOrientation. +End Rem +Function SplitterOrientation:Int( splitter:TSplitter ) + Return splitter.GetOrientation() +EndFunction + +Const SPLIT_RESIZABLE% = %1, SPLIT_LIMITPANESIZE% = %10, SPLIT_CANFLIP% = %100, SPLIT_CANORIENTATE% = %1000, SPLIT_CLICKTOTOGGLE% = %100000, SPLIT_ALL% = -1 + +Rem +bbdoc: Sets the behavior of a splitter. +about: Any combination of the following are available: + +[ @{Behavior Flag} | @Description +* 0 | The splitter does none of the actions listed below. +* SPLIT_RESIZABLE | The splitter can be resized by dragging. +* SPLIT_LIMITPANESIZE | The splitter side-pane is not allowed to take up more than half the splitted dimensions. +* SPLIT_CANFLIP | The splitter can switch between opposite edges by dragging to the edge. +* SPLIT_CANORIENTATE | The splitter can switch between vertical and horizontal modes by dragging to right/bottom edges. +* SPLIT_CLICKTOTOGGLE | The splitter will hide/show when the drag-bar is clicked. +* SPLIT_ALL | A shorthand flag for representing all of the above. +] + +The default behavior of a splitter is SPLIT_ALL&~~SPLIT_LIMITPANESIZE (i.e. everything but SPLIT_LIMITPANESIZE). + +See Also: #CreateSplitter, #SplitterPanel, #SplitterPosition, #SplitterBehavior, #SetSplitterOrientation and #SplitterOrientation. +End Rem +Function SetSplitterBehavior( splitter:TSplitter, flags%=SPLIT_ALL ) + splitter.SetBehavior( flags ) +EndFunction + +Rem +bbdoc: Returns the value previously set using #SetSplitterBehavior. +returns: An integer composed of a combination of bitwise flags that describe the behavior of the splitter. +about: See #SetSplitterBehavior for more information. +End Rem +Function SplitterBehavior:Int( splitter:TSplitter ) + Return splitter.GetBehavior() +EndFunction + + +Type TSplitter Extends TProxyGadget + + Const JUMP% = 200 + + ' SPLITPANEL_MAIN SPLITPANEL_SIDEPANE SPLITPANEL_HANDLE + Global intOrientationLocks%[][][] = [[ [EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED],[EDGE_ALIGNED, EDGE_ALIGNED, EDGE_CENTERED, EDGE_ALIGNED],[EDGE_ALIGNED, EDGE_ALIGNED, EDGE_CENTERED, EDGE_ALIGNED] ], .. 'SPLIT_HORIZONTAL + [ [EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED],[EDGE_CENTERED, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED],[EDGE_CENTERED, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED] ], .. 'SPLIT_VERTICAL + [ [EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED],[EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_CENTERED],[EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_CENTERED] ], .. 'SPLIT_HORIZONTAL|SPLIT_FLIPPED + [ [EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED],[EDGE_ALIGNED, EDGE_CENTERED, EDGE_ALIGNED, EDGE_ALIGNED],[EDGE_ALIGNED, EDGE_CENTERED, EDGE_ALIGNED, EDGE_ALIGNED] ]] 'SPLIT_VERTICAL|SPLIT_FLIPPED + + Field strToggleTooltip$ = "Click to toggle!" + + Field intOrientation%, intMinPanelSpace% = 0, intSavePanelSpace% = 220, intBehavior% = 0, intGutterSize% + Field intPanelSpace% = intMinPanelSpace, intMouseDown%[2], intHasMoved% = False, intShouldUpdate% = False + + Field pnlPanes:TGadget[] + Field pnlSplitHandle:TGadget, divSplitHandle1:TGadget, divSplitHandle2:TGadget + Field gadParent:TGadget + + Field pixHandle:TPixmap[] = [TPixmap(Null), TPixmap(Null)] + + Method Create:TSplitter( pX%, pY%, pW%, pH%, pParent:TGadget, pOrientation% = SPLIT_VERTICAL, pHandleSize% = 10 ) + + gadParent = CreatePanel(pX, pY, pW, pH, pParent);SetProxy( gadParent ) + + intGutterSize = Max(pHandleSize, 4) + DrawHandle();DrawPanes();ChangeOrientation(pOrientation) + + SetBehavior(SPLIT_ALL&~SPLIT_LIMITPANESIZE) + + AddHook EmitEventHook, eventHandler, Self, -1 + + Return Self + + EndMethod + + 'Interface + + Method GetOrientation:Int() + Return intOrientation + EndMethod + + Method SetOrientation(pOrientation%) + ChangeOrientation(pOrientation) + EndMethod + + Method SetBehavior( pBehavior% ) + intBehavior = pBehavior + If (intBehavior&SPLIT_CLICKTOTOGGLE) Then + If strToggleTooltip Then SetGadgetToolTip(pnlSplitHandle,strToggleTooltip) + Else + If strToggleTooltip Then SetGadgetToolTip(pnlSplitHandle,"") + EndIf + EndMethod + + Method GetBehavior%() + Return intBehavior + EndMethod + + Method GetPanel:TGadget(pPane%) + Return pnlPanes[pPane] + EndMethod + + Method GetPanelSpace%(pPane%) + Select pPane + Case SPLITPANEL_SIDEPANE + Return intPanelSpace + Case SPLITPANEL_MAIN + If intOrientation&SPLIT_VERTICAL Then + Return (ClientWidth()-intPanelSpace-intGutterSize) + Else + Return (ClientHeight()-intPanelSpace-intGutterSize) + EndIf + EndSelect + EndMethod + + Method SetPanelSpace( pPanelSpace%, flgSave% = True ) + + Local tmpOldPanelSpace% = intPanelSpace + + If (intBehavior & SPLIT_LIMITPANESIZE) Then + pPanelSpace = Min(pPanelSpace, [ClientHeight(), ClientWidth()][intOrientation&SPLIT_VERTICAL] Shr 1) + EndIf + + pPanelSpace = Max(pPanelSpace, intMinPanelSpace) + + intPanelSpace = pPanelSpace + If GetPanelSpace(SPLITPANEL_MAIN) < intMinPanelSpace Then intPanelSpace = tmpOldPanelSpace + + If flgSave And intPanelSpace > Min(intGutterSize,intMinPanelSpace) Then intSavePanelSpace = intPanelSpace + + DrawHandle();DrawPanes() + + EndMethod + + 'Proxy Gadget Methods + + Method CleanUp() + RemoveHook EmitEventHook, eventHandler, Self + gadParent = Null + Super.CleanUp() + EndMethod + + Method SetTooltip%( pTooltip$ ) + strToggleTooltip = "" + divSplitHandle1.SetTooltip( pTooltip ) + divSplitHandle2.SetTooltip( pTooltip ) + Return pnlSplitHandle.SetTooltip( pTooltip ) + EndMethod + + Method GetTooltip$() + Return pnlSplitHandle.GetTooltip() + EndMethod + + Method SetTextColor%( pRed%, pGreen%, pBlue%) + pixHandle[0] = MakeColourHandlePixmap( pRed, pGreen, pBlue, intGutterSize ) + If intOrientation & SPLIT_VERTICAL Then pixHandle[0] = RotatePixmap(pixHandle[0]) + pixHandle[1] = BrightenPixmap(pixHandle[0]) + HideGadget(divSplitHandle1);HideGadget(divSplitHandle2) + SetPanelPixmap(pnlSplitHandle, pixHandle[0]) + EndMethod + + Method SetColor%( pRed%, pGreen%, pBlue%) + Return SetPanelColor( pnlSplitHandle, pRed, pGreen, pBlue ) + EndMethod + + Method SetSensitivity%(pSensitivity%) + Return 0 + EndMethod + + Method GetSensitivity%() + Return 0 + EndMethod + + 'Internal Methods + + Method ReapplyLocks() + Local tmpLocks%[][] = intOrientationLocks[intOrientation] + If pnlPanes And pnlPanes.length > 1 Then + SetGadgetLayout( pnlPanes[SPLITPANEL_MAIN], tmpLocks[SPLITPANEL_MAIN][0], tmpLocks[SPLITPANEL_MAIN][1], tmpLocks[SPLITPANEL_MAIN][2], tmpLocks[SPLITPANEL_MAIN][3] ) + SetGadgetLayout( pnlPanes[SPLITPANEL_SIDEPANE], tmpLocks[SPLITPANEL_SIDEPANE][0], tmpLocks[SPLITPANEL_SIDEPANE][1], tmpLocks[SPLITPANEL_SIDEPANE][2], tmpLocks[SPLITPANEL_SIDEPANE][3] ) + EndIf + If pnlSplitHandle Then SetGadgetLayout( pnlSplitHandle, tmpLocks[SPLITPANEL_HANDLE][0], tmpLocks[SPLITPANEL_HANDLE][1], tmpLocks[SPLITPANEL_HANDLE][2], tmpLocks[SPLITPANEL_HANDLE][3] ) + EndMethod + + Const SPLITSIDE_LEFT% = 0, SPLITSIDE_RIGHT% = 1, SPLITSIDE_TOP% = 0, SPLITSIDE_BOTTOM% = 1 + Global intSideToPanelMapping%[][] = [[ SPLITPANEL_MAIN, SPLITPANEL_SIDEPANE ], .. 'SPLIT_HORIZONTAL + [ SPLITPANEL_MAIN, SPLITPANEL_SIDEPANE ], .. 'SPLIT_VERTICAL + [ SPLITPANEL_SIDEPANE, SPLITPANEL_MAIN ], .. 'SPLIT_HORIZONTAL|SPLIT_FLIPPED + [ SPLITPANEL_SIDEPANE, SPLITPANEL_MAIN ]] 'SPLIT_VERTICAL|SPLIT_FLIPPED + + Method GetSideSpace%( pSide% ) + Return GetPanelSpace(intSideToPanelMapping[intOrientation][pSide]) + EndMethod + + Method DrawHandle() + + Local tmpDimensions%[] '0: X, 1: Y, 2: W, 3: H + + Select intOrientation&SPLIT_VERTICAL + + Case SPLIT_HORIZONTAL;tmpDimensions = [0, GetSideSpace(SPLITSIDE_TOP), ClientWidth(), intGutterSize] + Case SPLIT_VERTICAL;tmpDimensions = [GetSideSpace(SPLITSIDE_LEFT), 0, intGutterSize, ClientHeight()] + + EndSelect + + If pnlSplitHandle Then + SetGadgetShape(pnlSplitHandle, tmpDimensions[0], tmpDimensions[1], tmpDimensions[2], tmpDimensions[3]) + Select intOrientation&SPLIT_VERTICAL + Case SPLIT_HORIZONTAL + SetGadgetShape( divSplitHandle1,0,Ceil(tmpDimensions[3]/2.0)-2,tmpDimensions[2],2 ) + SetGadgetShape( divSplitHandle2,0,Ceil(tmpDimensions[3]/2.0),tmpDimensions[2],2 ) + Case SPLIT_VERTICAL + SetGadgetShape( divSplitHandle1,Ceil(tmpDimensions[2]/2.0)-2,0,2,tmpDimensions[3] ) + SetGadgetShape( divSplitHandle2,Ceil(tmpDimensions[2]/2.0),0,2,tmpDimensions[3] ) + EndSelect + If pixHandle[0] Then + HideGadget(divSplitHandle1) + HideGadget(divSplitHandle2) + Else + ShowGadget(divSplitHandle1) + ShowGadget(divSplitHandle2) + EndIf + Else + pnlSplitHandle = CreatePanel(tmpDimensions[0], tmpDimensions[1], tmpDimensions[2], tmpDimensions[3], gadParent, PANEL_ACTIVE) + + SetPanelPixmap( pnlSplitHandle, pixHandle[0]);SetGadgetToolTip(pnlSplitHandle,strToggleTooltip) + + Select intOrientation&SPLIT_VERTICAL + Case SPLIT_HORIZONTAL + divSplitHandle1 = CreateLabel("",0,Ceil(tmpDimensions[3]/2.0)-2,tmpDimensions[2],2,pnlSplitHandle,LABEL_SEPARATOR) + divSplitHandle2 = CreateLabel("",0,Ceil(tmpDimensions[3]/2.0),tmpDimensions[2],2,pnlSplitHandle,LABEL_SEPARATOR) + Case SPLIT_VERTICAL + divSplitHandle1 = CreateLabel("",Ceil(tmpDimensions[2]/2.0)-2,0,2,tmpDimensions[3],pnlSplitHandle,LABEL_SEPARATOR) + divSplitHandle2 = CreateLabel("",Ceil(tmpDimensions[2]/2.0),0,2,tmpDimensions[3],pnlSplitHandle,LABEL_SEPARATOR) + EndSelect + SetGadgetSensitivity(divSplitHandle1,SENSITIZE_MOUSE);SetGadgetSensitivity(divSplitHandle2,SENSITIZE_MOUSE) + + ?Win32 + DisableGadget( divSplitHandle1 );DisableGadget( divSplitHandle2 ) + ? + + SetGadgetToolTip( divSplitHandle1, strToggleTooltip );SetGadgetToolTip( divSplitHandle2, strToggleTooltip ) + SetGadgetLayout( divSplitHandle1, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED ) + SetGadgetLayout( divSplitHandle2, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED ) + If pixHandle[0] Then HideGadget(divSplitHandle1);HideGadget(divSplitHandle2) + + EndIf + + EndMethod + + Method DrawPanes() + + Local tmpDimensions%[][] '0: X, 1: Y, 2: W, 3: H + + Select intOrientation&SPLIT_VERTICAL + Case SPLIT_HORIZONTAL + tmpDimensions = [[0, 0, ClientWidth(), GetSideSpace(SPLITSIDE_TOP)], [0, GetSideSpace(SPLITSIDE_TOP)+intGutterSize, ClientWidth(), GetSideSpace(SPLITSIDE_BOTTOM)]] + Case SPLIT_VERTICAL + tmpDimensions = [[0,0,GetSideSpace(SPLITSIDE_LEFT),ClientHeight()], [GetSideSpace(SPLITSIDE_LEFT)+intGutterSize,0,GetSideSpace(SPLITSIDE_RIGHT),ClientHeight()]] + EndSelect + + If intOrientation & SPLIT_FLIPPED Then tmpDimensions = [tmpDimensions[1],tmpDimensions[0]] + + If pnlPanes.length <> 2 Then + pnlPanes = [CreatePanel(0,0,1,1,gadParent,0), CreatePanel(0,0,1,1,gadParent,0)] + ReapplyLocks() + EndIf + + SetGadgetShape(pnlPanes[SPLITPANEL_MAIN], tmpDimensions[SPLITPANEL_MAIN][0], tmpDimensions[SPLITPANEL_MAIN][1], tmpDimensions[SPLITPANEL_MAIN][2], tmpDimensions[SPLITPANEL_MAIN][3]) + SetGadgetShape(pnlPanes[SPLITPANEL_SIDEPANE], tmpDimensions[SPLITPANEL_SIDEPANE][0], tmpDimensions[SPLITPANEL_SIDEPANE][1], tmpDimensions[SPLITPANEL_SIDEPANE][2], tmpDimensions[SPLITPANEL_SIDEPANE][3]) + + EndMethod + + Method ChangeOrientation(pOrientation% = -1) + If pOrientation = intOrientation Then Return + If pOrientation < 0 Then + intOrientation:~SPLIT_FLIPPED + Else + If pixHandle[0] And intOrientation&SPLIT_VERTICAL <> pOrientation&SPLIT_VERTICAL Then + pixHandle[0] = RotatePixmap(pixHandle[0]);pixHandle[1] = RotatePixmap(pixHandle[1]) + EndIf + intOrientation = pOrientation + EndIf + SetPanelPixmap(pnlSplitHandle, pixHandle[0]);DrawHandle();DrawPanes();ReapplyLocks();RedrawGadget(gadParent) + EndMethod + + Method Toggle() + If intPanelSpace > intMinPanelSpace Then SetPanelSpace( intMinPanelSpace ) Else SetPanelSpace( intSavePanelSpace ) + EndMethod + + Method eventHook:Object( pID%, pData:Object ) + + Local tmpEvent:TEvent = TEvent(pData) + If (Not tmpEvent) Or (Not TGadget(tmpEvent.source)) Then Return pData + + Select tmpEvent.source + + Case pnlSplitHandle, divSplitHandle1, divSplitHandle2 + + If (tmpEvent.source = divSplitHandle1) Or (tmpEvent.source = divSplitHandle2) Then + tmpEvent.x:+GadgetX(TGadget(tmpEvent.source)) + tmpEvent.y:+GadgetY(TGadget(tmpEvent.source)) + tmpEvent.source = pnlSplitHandle + EndIf + + Select tmpEvent.id + + Case EVENT_MOUSEDOWN + + If (tmpEvent.data <> MOUSE_LEFT) Then Return Null + intMouseDown = [tmpEvent.x, tmpEvent.y] + intHasMoved = False + + Case EVENT_MOUSEMOVE + + intHasMoved = True + + If tmpEvent.data Then + + If intMouseDown Or (tmpEvent.data = MOUSE_LEFT And intShouldUpdate) Then + + 'Update our mouse pointer and re-set our drag-point (if needed). + ShowDragPointer() + If intShouldUpdate Or Not intMouseDown Then + intMouseDown = [tmpEvent.x,tmpEvent.y] + intShouldUpdate = False + EndIf + + 'New values that are updated once everything has been checked + Local tmpOrientation% = GetOrientation(), tmpPanelSpace% = -1, tmpPanelSave% = False + + 'New size of panel if resized with mouse cursor + Local tmpDraggedSpace% = -[tmpEvent.y-intMouseDown[1],tmpEvent.x-intMouseDown[0]][intOrientation&SPLIT_VERTICAL] + If tmpOrientation&SPLIT_FLIPPED Then tmpDraggedSpace:*-1 + tmpDraggedSpace:+intPanelSpace + + 'Update intPanelSpace if we can drag as any calls to GetPanelSpace() need to return an accurate value + If (intBehavior&SPLIT_RESIZABLE) And tmpDraggedSpace <> intPanelSpace Then + + 'Simulate a snap-closed action for the splitter + If tmpDraggedSpace < intGutterSize Then tmpDraggedSpace = intMinPanelSpace + + tmpPanelSpace = tmpDraggedSpace + intPanelSpace = tmpDraggedSpace + EndIf + + 'Limit the pane-size to half the client-area if SPLIT_LIMITPANESIZE is set. + If (intBehavior&SPLIT_LIMITPANESIZE) Then + Local tmpDimensions%[] = [ClientHeight(),ClientWidth()] + If GetPanelSpace(SPLITPANEL_SIDEPANE) > (tmpDimensions[(tmpOrientation&SPLIT_VERTICAL)])/2 Then + If (intBehavior&SPLIT_CANFLIP) Then + tmpOrientation:~SPLIT_FLIPPED + tmpPanelSpace = GetPanelSpace(SPLITPANEL_MAIN) + Else + tmpPanelSpace = (tmpDimensions[(tmpOrientation&SPLIT_VERTICAL)])/2 + EndIf + tmpPanelSave = True + EndIf + EndIf + + 'Update the splitter's orientation if needed. + If (intBehavior&(SPLIT_CANORIENTATE|SPLIT_CANFLIP)) Then + + 'Drag test conditions + Local tmpLeftCond% = (GadgetX(pnlSplitHandle)+tmpEvent.x < 1) + Local tmpRightCond% = (GadgetX(pnlSplitHandle)+tmpEvent.x > ClientWidth()-intGutterSize) + Local tmpTopCond% = (GadgetY(pnlSplitHandle)+tmpEvent.y < 1) + Local tmpBottomCond% = (GadgetY(pnlSplitHandle)+tmpEvent.y > ClientHeight()-intGutterSize) + + Select True + Case (tmpRightCond And Not (tmpTopCond|tmpBottomCond)), (tmpLeftCond And Not (tmpTopCond|tmpBottomCond)), .. + (tmpBottomCond And Not (tmpLeftCond|tmpRightCond)), (tmpTopCond And Not (tmpLeftCond|tmpRightCond)) + If (intBehavior&SPLIT_CANFLIP) Or ((tmpLeftCond|tmpTopCond)=(tmpOrientation&SPLIT_FLIPPED)) Then + If (intBehavior&SPLIT_CANORIENTATE) Then + If (tmpLeftCond|tmpRightCond) Then tmpOrientation:|SPLIT_VERTICAL Else tmpOrientation:&~SPLIT_VERTICAL + Else + Select (tmpOrientation&SPLIT_VERTICAL) + Case SPLIT_VERTICAL;tmpTopCond = 0;tmpBottomCond = 0 + Case SPLIT_HORIZONTAL;tmpLeftCond = 0;tmpRightCond = 0 + EndSelect + EndIf + 'Let's determine whether our side-panel should be flipped or not. + If (tmpLeftCond|tmpTopCond) Then tmpOrientation:|SPLIT_FLIPPED ElseIf (tmpRightCond|tmpBottomCond) Then tmpOrientation:&~SPLIT_FLIPPED + 'If we are resizable and the orientation has changed, let's reset the side-pane size. + If (intBehavior&SPLIT_RESIZABLE) And (tmpOrientation <> intOrientation) Then tmpPanelSpace = intMinPanelSpace;tmpPanelSave = True + EndIf + EndSelect + + EndIf + + 'Apply our newly calculated values to the splitter. + If (tmpOrientation <> GetOrientation()) Then + If (tmpOrientation&SPLIT_VERTICAL <> GetOrientation()&SPLIT_VERTICAL) Then + intMouseDown = Null + intShouldUpdate = True + EndIf + ChangeOrientation( tmpOrientation ) + ShowActivePointer() + EndIf + + If tmpPanelSpace > -1 Then SetPanelSpace( tmpPanelSpace, tmpPanelSave ) + + EndIf + + Else + + intMouseDown = Null + + EndIf + + Case EVENT_MOUSEUP + + If (intMouseDown And tmpEvent.data = MOUSE_LEFT) Then + + If Not intHasMoved Then + If (intBehavior&SPLIT_CLICKTOTOGGLE) Then Toggle() + Else + SetPanelSpace( intPanelSpace, True ) + EndIf + + intMouseDown = Null + + ShowNormalPointer() + + EndIf + + Case EVENT_MOUSELEAVE + + If (intBehavior&(SPLIT_RESIZABLE|SPLIT_CLICKTOTOGGLE)) Then + SetPanelPixmap(pnlSplitHandle, pixHandle[0]) + EndIf + + ShowNormalPointer() + + Case EVENT_MOUSEENTER + + If (intBehavior&(SPLIT_RESIZABLE|SPLIT_CLICKTOTOGGLE)) Then + SetPanelPixmap(pnlSplitHandle, pixHandle[1]) + EndIf + + ShowActivePointer() + + EndSelect + + Case pnlPanes[SPLITPANEL_MAIN], pnlPanes[SPLITPANEL_SIDEPANE], gadParent + + 'Don't show these events to the other hooks! + + Default + + Select tmpEvent.id + Case EVENT_WINDOWSIZE + If (intBehavior&SPLIT_RESIZABLE) And TGadget(tmpEvent.source).HasDescendant(gadParent) Then + Local tmpLimit% = [ClientHeight(),ClientWidth()][intOrientation&SPLIT_VERTICAL] + If (intBehavior&SPLIT_LIMITPANESIZE) Then tmpLimit:Shr 1 Else tmpLimit:-intGutterSize + If GetPanelSpace(SPLITPANEL_SIDEPANE) > tmpLimit Then SetPanelSpace( tmpLimit, True ) + EndIf + EndSelect + + Return pData + EndSelect + + EndMethod + + 'Mouse Cursor + Function ShowNormalPointer() + SetPointer(POINTER_DEFAULT) + EndFunction + + Method ShowActivePointer() + If (intBehavior&SPLIT_RESIZABLE) Then + Select intOrientation&SPLIT_VERTICAL + Case SPLIT_HORIZONTAL;SetPointer(POINTER_SIZENS) + Case SPLIT_VERTICAL;SetPointer(POINTER_SIZEWE) + EndSelect + ElseIf (intBehavior&SPLIT_CLICKTOTOGGLE) Then + SetPointer(POINTER_HAND) + Else + SetPointer(POINTER_DEFAULT) + EndIf + EndMethod + + Method ShowDragPointer() + If (intBehavior&SPLIT_RESIZABLE) Then + Select intOrientation&SPLIT_VERTICAL + Case SPLIT_HORIZONTAL;SetPointer(POINTER_SIZENS) + Case SPLIT_VERTICAL;SetPointer(POINTER_SIZEWE) + EndSelect + ElseIf (intBehavior&(SPLIT_CANFLIP|SPLIT_CANORIENTATE)) + SetPointer(POINTER_SIZEALL) + Else + SetPointer(POINTER_DEFAULT) + EndIf + EndMethod + + 'Helper Functions + + Function eventHandler:Object( pID%, pData:Object, pContext:Object) + If TSplitter(pContext) Then Return TSplitter(pContext).eventHook( pID, pData ) Else Return pData + EndFunction + + Function RotatePixmap:TPixmap( pSrcPixmap:TPixmap ) + Local tmpDestPixmap:TPixmap = CreatePixmap(pSrcPixmap.height, pSrcPixmap.width, pSrcPixmap.format) + For Local y% = 0 Until pSrcPixmap.height + For Local x% = 0 Until pSrcPixmap.width + WritePixel( tmpDestPixmap, y, x, ReadPixel(pSrcPixmap, x, y) ) + Next + Next + Return tmpDestPixmap + EndFunction + + Function BrightenPixmap:TPixmap( pSrcPixmap:TPixmap, pBrightness# = 1.05 ) + Local tmpDestPixmap:TPixmap = CreatePixmap(pSrcPixmap.width, pSrcPixmap.height, pSrcPixmap.format) + For Local y% = 0 Until pSrcPixmap.height + For Local x% = 0 Until pSrcPixmap.width + WritePixel( tmpDestPixmap, x, y, BrightenPixel(ReadPixel(pSrcPixmap, x, y), pBrightness) ) + Next + Next + Return tmpDestPixmap + EndFunction + + Function BrightenPixel%( pARGB%, pBrightness# = 1.05 ) + Local tmpHSV:TColorHSV = New TColorHSV.fromARGB(pARGB) + tmpHSV.v=Min(tmpHSV.v*pBrightness,1) + Return tmpHSV.toARGB() + EndFunction + + Function WhitenPixel%( pARGB%, pWhiteness# = 0.8 ) + Local tmpHSV:TColorHSV = New TColorHSV.fromARGB(pARGB) + tmpHSV.s=Min(tmpHSV.s*pWhiteness,1) + Return tmpHSV.toARGB() + EndFunction + + Function MakeColourHandlePixmap:TPixmap( pRed%, pGreen%, pBlue%, pWidth% ) + Local tmpPixmap:TPixmap = CreatePixmap(1,pWidth,PF_RGB888) + Local tmpPixel% = (pRed Shl 16)|(pGreen Shl 8)|pBlue + For Local i% = 0 To pWidth/2 + Local tmpCalculatedPixel% = BrightenPixel(tmpPixel,1.05^i) + WritePixel(tmpPixmap,0,i,tmpCalculatedPixel) + WritePixel(tmpPixmap,0,pWidth-1-i,tmpCalculatedPixel) + Next + Return tmpPixmap + EndFunction + +EndType + +Private + +'Some type declarations from fredborg's pub.color module +'http://www.blitzbasic.com/codearcs/codearcs.php?code=1749 + +Type TColor + Method toARGB:Int() Abstract +End Type + +Type TColorHSV Extends TColor + + Field h:Float,s:Float,v:Float,a:Float=1.0 + + Method toRGB:TColorRGB() + + Local temph:Float = Self.h + Local temps:Float = Self.s + Local tempv:Float = Self.v + + Local rgb:TColorRGB = New TColorRGB + + If temph=>360.0 Or temph<0.0 Then temph = 0.0 + + If temps = 0 Then + rgb.r = v + rgb.g = v + rgb.b = v + Else + temph = temph / 60.0 + + Local i:Int = Floor(temph) + Local f:Float = temph - i + Local p:Float = tempv * (1 - temps) + Local q:Float = tempv * (1 - temps * f) + Local t:Float = tempv * (1 - temps * (1 - f)) + + Select i + Case 0 + rgb.r = v + rgb.g = t + rgb.b = p + Case 1 + rgb.r = q + rgb.g = v + rgb.b = p + Case 2 + rgb.r = p + rgb.g = v + rgb.b = t + Case 3 + rgb.r = p + rgb.g = q + rgb.b = v + Case 4 + rgb.r = t + rgb.g = p + rgb.b = v + Default + rgb.r = v + rgb.g = p + rgb.b = q + End Select + EndIf + + rgb.a = a + + Return rgb + + EndMethod + + Function fromARGB:TColorHSV(argb:Int) + Return TColorRGB.fromARGB(argb).toHSV() + EndFunction + + Method toARGB:Int() + Return Self.toRGB().toARGB() + EndMethod + +EndType + +Type TColorRGB Extends TColor + + Field r:Float,g:Float,b:Float,a:Float=1.0 + + Method toHSV:TColorHSV() + + Local tempr:Float = Min(1.0,Max(0.0,Self.r)) + Local tempg:Float = Min(1.0,Max(0.0,Self.g)) + Local tempb:Float = Min(1.0,Max(0.0,Self.b)) + + Local minVal:Float = Min(Min(tempr,tempg),tempb) + Local maxVal:Float = Max(Max(tempr,tempg),tempb) + + Local diff:Float = maxVal - minVal + + Local hsv:TColorHSV = New TColorHSV + hsv.v = maxVal + + If maxVal = 0.0 Then + hsv.s = 0.0 + hsv.h = 0.0 + Else + hsv.s = diff / maxVal + + If tempr = maxVal + hsv.h = (tempg - tempb) / diff + ElseIf tempg = maxVal + hsv.h = 2.0 + (tempb - tempr) / diff + Else + hsv.h = 4.0 + (tempr - tempg) / diff + EndIf + + hsv.h = hsv.h * 60.0 + If hsv.h < 0 Then hsv.h = hsv.h + 360.0 + EndIf + + If hsv.h< 0.0 Then hsv.h = 0.0 + If hsv.h>360.0 Then hsv.h = 0.0 + + hsv.a = a + + Return hsv + + EndMethod + + Function fromARGB:TColorRGB(argb:Int,alpha:Int=True) + + Local rgb:TColorRGB = New TColorRGB + + If alpha + rgb.a = ((argb Shr 24) & $FF)/255.0 + EndIf + + rgb.r = ((argb Shr 16) & $FF)/255.0 + rgb.g = ((argb Shr 8) & $FF)/255.0 + rgb.b = (argb & $FF)/255.0 + + Return rgb + + EndFunction + + Function fromBGR:TColorRGB(argb:Int) + + Local rgb:TColorRGB = New TColorRGB + + rgb.r = (argb & $000000FF)/255.0 + rgb.g = ((argb Shr 8) & $000000FF)/255.0 + rgb.b = ((argb Shr 16) & $000000FF)/255.0 + + Return rgb + + EndFunction + + Method toARGB:Int() + + Local tempr:Int = Min(255,Max(0,Int(Self.r*255))) + Local tempg:Int = Min(255,Max(0,Int(Self.g*255))) + Local tempb:Int = Min(255,Max(0,Int(Self.b*255))) + Local tempa:Int = Min(255,Max(0,Int(Self.a*255))) + + Return (tempa Shl 24) | (tempr Shl 16) | (tempg Shl 8) | tempb + + EndMethod + +EndType + diff --git a/mod/maxgui.mod/proxygadgets.mod/version.txt b/mod/maxgui.mod/proxygadgets.mod/version.txt new file mode 100644 index 0000000..14dd32a --- /dev/null +++ b/mod/maxgui.mod/proxygadgets.mod/version.txt @@ -0,0 +1,31 @@ +1.12 Release +Added optional pHandleSize parameter. +Added ability to set split handle background color. +Fixed SPLIT_LIMITPANESIZE and SPLIT_CLICKTOTOGGLE bug. +1.11 Release +Hyperlink gadget now defaults to link colour returned by LookupGuiColor(). +1.10 Release +Decreased the TSplitter threshold for orientation flip. +1.09 Release +Added SCROLLPANEL_HNEVER and SCROLLPANEL_VNEVER constants. +1.08 Release +Added a new TScrollPanel gadget. +1.07 Release +Tweaked THyperlinkGadget.eventHandler() so that it works consistently on all platforms. +1.06 Release +Fixed some rogue dragging locks for splitters on Windows. +1.05 Release +Tidied up TSplitter.eventHook(), fixing several bugs in drag code. +1.04 Release +Added a new SetSplitterBehavior command. +1.03 Release +Fixed hyperlink tooltips. +A hyperlink's URL can now be modified/retrieved using SetGadgetExtra / GadgetExtra. +1.02 Release +Added a new TSplitter gadget. See CreateSplitter for more info. +1.01 Release +Filtered EVENT_MOUSEDOWN to avoid infinite loop on Windows. +Updated THyperlinkGadget to use LookupGuiFont(). +Inherited MaxGUI.Win32MaxGUI's label SS_NOTIFY fix. +1.00 Release +Added the first custom gadget: the hyperlink control. diff --git a/mod/maxgui.mod/win32maxguiex.mod/comdef.h b/mod/maxgui.mod/win32maxguiex.mod/comdef.h new file mode 100644 index 0000000..558757b --- /dev/null +++ b/mod/maxgui.mod/win32maxguiex.mod/comdef.h @@ -0,0 +1,331 @@ +/*** +* comdef.h - Native C++ compiler COM support - main definitions header +* +* Copyright (C) 1996-2001 Microsoft Corporation +* All rights reserved. +* +****/ + +#if _MSC_VER > 1000 +#pragma once +#endif + +#if !defined(_INC_COMDEF) +#define _INC_COMDEF + +#ifndef __cplusplus +#error Native Compiler support only available in C++ compiler +#endif + +#include +#include + +//#include + +#pragma warning(push) +#pragma warning(disable: 4244) +#pragma warning(disable: 4290) + +#ifdef _NATIVE_WCHAR_T_DEFINED +# ifdef _DEBUG +# pragma comment(lib, "comsuppwd.lib") +# else +# pragma comment(lib, "comsuppw.lib") +# endif +#else +# ifdef _DEBUG +# pragma comment(lib, "comsuppd.lib") +# else +# pragma comment(lib, "comsupp.lib") +# endif +#endif + +#pragma comment(lib, "user32.lib") +#pragma comment(lib, "ole32.lib") +#pragma comment(lib, "oleaut32.lib") + +class _com_error; +class _bstr_t; + +class _com_error { +public: + // Constructors + // + _com_error(HRESULT hr, + IErrorInfo* perrinfo = NULL, + bool fAddRef = false) throw(); + _com_error(const _com_error& that) throw(); + + // Destructor + // + virtual ~_com_error() throw(); + + // Assignment operator + // + _com_error& operator=(const _com_error& that) throw(); + + // Accessors + // + HRESULT Error() const throw(); + WORD WCode() const throw(); + IErrorInfo * ErrorInfo() const throw(); + + // IErrorInfo method accessors + // + _bstr_t Description() const throw(); + DWORD HelpContext() const throw(); + _bstr_t HelpFile() const throw(); + _bstr_t Source() const throw(); + GUID GUID() const throw(); + + // FormatMessage accessors + const TCHAR * ErrorMessage() const throw(); + + // EXCEPINFO.wCode <-> HRESULT mappers + static HRESULT WCodeToHRESULT(WORD wCode) throw(); + static WORD HRESULTToWCode(HRESULT hr) throw(); + +private: + enum { + WCODE_HRESULT_FIRST = MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x200), + WCODE_HRESULT_LAST = MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF+1, 0) - 1 + }; + const HRESULT m_hresult; + IErrorInfo * m_perrinfo; + mutable TCHAR * m_pszMsg; +}; + + +void __stdcall + _com_raise_error(HRESULT hr, IErrorInfo* perrinfo = 0) throw(_com_error); + +void __stdcall + _set_com_error_handler(void (__stdcall *pHandler)(HRESULT hr, IErrorInfo* perrinfo)); + +void __stdcall + _com_issue_error(HRESULT) throw(_com_error); +void __stdcall + _com_issue_errorex(HRESULT, IUnknown*, REFIID) throw(_com_error); + +HRESULT __stdcall + _com_dispatch_propget(IDispatch*, DISPID, VARTYPE, void*) throw(_com_error); +HRESULT __cdecl + _com_dispatch_propput(IDispatch*, DISPID, VARTYPE, ...) throw(_com_error); +HRESULT __cdecl + _com_dispatch_method(IDispatch*, DISPID, WORD, VARTYPE, void*, + const wchar_t*, ...) throw(_com_error); + +HRESULT __stdcall + _com_dispatch_raw_propget(IDispatch*, DISPID, VARTYPE, void*) throw(); +HRESULT __cdecl + _com_dispatch_raw_propput(IDispatch*, DISPID, VARTYPE, ...) throw(); +HRESULT __cdecl + _com_dispatch_raw_method(IDispatch*, DISPID, WORD, VARTYPE, void*, + const wchar_t*, ...) throw(); + + +inline _com_error::_com_error(HRESULT hr, + IErrorInfo* perrinfo, + bool fAddRef) throw() + : m_hresult(hr), m_perrinfo(perrinfo), m_pszMsg(NULL) +{ + if (m_perrinfo != NULL && fAddRef) { + m_perrinfo->AddRef(); + } +} + +inline _com_error::_com_error(const _com_error& that) throw() + : m_hresult(that.m_hresult), m_perrinfo(that.m_perrinfo), m_pszMsg(NULL) +{ + if (m_perrinfo != NULL) { + m_perrinfo->AddRef(); + } +} + +inline _com_error::~_com_error() throw() +{ + if (m_perrinfo != NULL) { + m_perrinfo->Release(); + } + if (m_pszMsg != NULL) { + LocalFree((HLOCAL)m_pszMsg); + } +} + +inline _com_error& _com_error::operator=(const _com_error& that) throw() +{ + if (this != &that) { + this->_com_error::~_com_error(); + this->_com_error::_com_error(that); + } + return *this; +} + +inline HRESULT _com_error::Error() const throw() +{ + return m_hresult; +} + +inline WORD _com_error::WCode() const throw() +{ + return HRESULTToWCode(m_hresult); +} + +inline IErrorInfo * _com_error::ErrorInfo() const throw() +{ + if (m_perrinfo != NULL) { + m_perrinfo->AddRef(); + } + return m_perrinfo; +} + +inline _bstr_t _com_error::Description() const throw(_com_error) +{ + BSTR bstr = NULL; + if (m_perrinfo != NULL) { + m_perrinfo->GetDescription(&bstr); + } + return _bstr_t(bstr, false); +} + +inline DWORD _com_error::HelpContext() const throw() +{ + DWORD dwHelpContext = 0; + if (m_perrinfo != NULL) { + m_perrinfo->GetHelpContext(&dwHelpContext); + } + return dwHelpContext; +} + +inline _bstr_t _com_error::HelpFile() const throw(_com_error) +{ + BSTR bstr = NULL; + if (m_perrinfo != NULL) { + m_perrinfo->GetHelpFile(&bstr); + } + return _bstr_t(bstr, false); +} + +inline _bstr_t _com_error::Source() const throw(_com_error) +{ + BSTR bstr = NULL; + if (m_perrinfo != NULL) { + m_perrinfo->GetSource(&bstr); + } + return _bstr_t(bstr, false); +} + +inline _GUID _com_error::GUID() const throw() +{ + _GUID guid; + memcpy(&guid, &__uuidof(NULL), sizeof(_GUID)); + if (m_perrinfo != NULL) { + m_perrinfo->GetGUID(&guid); + } + return guid; +} + +inline const TCHAR * _com_error::ErrorMessage() const throw() +{ + if (m_pszMsg == NULL) { + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + m_hresult, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR)&m_pszMsg, + 0, + NULL ); + if (m_pszMsg != NULL) { + int nLen = lstrlen(m_pszMsg); + if (nLen > 1 && m_pszMsg[nLen - 1] == '\n') { + m_pszMsg[nLen - 1] = 0; + if (m_pszMsg[nLen - 2] == '\r') { + m_pszMsg[nLen - 2] = 0; + } + } + } else { + m_pszMsg = (LPTSTR)LocalAlloc(0, 32 * sizeof(TCHAR)); + if (m_pszMsg != NULL) { + WORD wCode = WCode(); + if (wCode != 0) { + wsprintf(m_pszMsg, TEXT("IDispatch error #%d"), wCode); + } else { + wsprintf(m_pszMsg, TEXT("Unknown error 0x%0lX"), m_hresult); + } + } + } + } + return m_pszMsg; +} + +inline HRESULT _com_error::WCodeToHRESULT(WORD wCode) throw() +{ + return wCode >= 0xFE00 ? WCODE_HRESULT_LAST : WCODE_HRESULT_FIRST + wCode; +} + +inline WORD _com_error::HRESULTToWCode(HRESULT hr) throw() +{ + return (hr >= WCODE_HRESULT_FIRST && hr <= WCODE_HRESULT_LAST) + ? WORD(hr - WCODE_HRESULT_FIRST) + : 0; +} + +// +// give missing types from dependent type libraries a chance +// +typedef int __missing_type__; + +#if !defined(_COM_SMARTPTR) + #if !defined(_INC_COMIP) + #include + #endif + #define _COM_SMARTPTR _com_ptr_t + #define _COM_SMARTPTR_LEVEL2 _com_IIID +#endif +#if defined(_COM_SMARTPTR) + #if !defined(_COM_SMARTPTR_TYPEDEF) + #if defined(_COM_SMARTPTR_LEVEL2) + #define _COM_SMARTPTR_TYPEDEF(Interface, IID) \ + typedef _COM_SMARTPTR<_COM_SMARTPTR_LEVEL2 > \ + Interface ## Ptr + #else + #define _COM_SMARTPTR_TYPEDEF(Interface, IID) \ + typedef _COM_SMARTPTR \ + Interface ## Ptr + #endif + #endif +#endif + +#if !defined(_COM_NO_STANDARD_GUIDS_) + +// hard-coded smart pointer defs +#if defined(__IFontDisp_INTERFACE_DEFINED__) +__if_not_exists(Font) +{ + struct Font : IFontDisp {}; +} +_COM_SMARTPTR_TYPEDEF(Font, __uuidof(IDispatch)); +#endif +#if defined(__IFontEventsDisp_INTERFACE_DEFINED__) +__if_not_exists(FontEvents) +{ + struct FontEvents : IFontEventsDisp {}; +} +_COM_SMARTPTR_TYPEDEF(FontEvents, __uuidof(IDispatch)); +#endif +#if defined(__IPictureDisp_INTERFACE_DEFINED__) +__if_not_exists(Picture) +{ + struct Picture : IPictureDisp {}; +} +_COM_SMARTPTR_TYPEDEF(Picture, __uuidof(IDispatch)); +#endif + +#include "comdefsp.h" + +#endif /* _COM_NO_STANDARD_GUIDS_ */ + +#pragma warning(pop) + +#endif /* _INC_COMDEF */ + diff --git a/mod/maxgui.mod/win32maxguiex.mod/comutil.h b/mod/maxgui.mod/win32maxguiex.mod/comutil.h new file mode 100644 index 0000000..8591c04 --- /dev/null +++ b/mod/maxgui.mod/win32maxguiex.mod/comutil.h @@ -0,0 +1,2244 @@ +/*** +* comutil.h - Native C++ compiler COM support - BSTR, VARIANT wrappers header +* +* Copyright (C) 1996-2001 Microsoft Corporation +* All rights reserved. +* +****/ + +#if _MSC_VER > 1000 +#pragma once +#endif + +#if !defined(_INC_COMUTIL) +#define _INC_COMUTIL + +#include + +#if !defined(_COM_ASSERT) +# if defined(_DEBUG) +# include +# define _COM_ASSERT(x) assert(x) +# else +# define _COM_ASSERT(x) ((void)0) +# endif +#endif + +#pragma warning(push) +#pragma warning(disable: 4290) +#pragma warning(disable: 4310) + +#pragma push_macro("new") +#undef new + +class _com_error; + +void __stdcall _com_issue_error(HRESULT); + +////////////////////////////////////////////////////////////////////////////// +// +// Forward class declarations +// +////////////////////////////////////////////////////////////////////////////// + +class _bstr_t; +class _variant_t; + +////////////////////////////////////////////////////////////////////////////// +// +// Error checking routines +// +////////////////////////////////////////////////////////////////////////////// + +namespace _com_util { + inline void CheckError(HRESULT hr) throw(_com_error) + { + if (FAILED(hr)) { + _com_issue_error(hr); + } + } +} + +////////////////////////////////////////////////////////////////////////////// +// +// Routines for handling conversions between BSTR and char* +// +////////////////////////////////////////////////////////////////////////////// + +namespace _com_util { + // Convert char * to BSTR + // + BSTR __stdcall ConvertStringToBSTR(const char* pSrc) throw(_com_error); + + // Convert BSTR to char * + // + char* __stdcall ConvertBSTRToString(BSTR pSrc) throw(_com_error); +} + +////////////////////////////////////////////////////////////////////////////// +// +// Wrapper class for BSTR +// +////////////////////////////////////////////////////////////////////////////// + +class _bstr_t { +public: + // Constructors + // + _bstr_t() throw(); + _bstr_t(const _bstr_t& s) throw(); + _bstr_t(const char* s) throw(_com_error); + _bstr_t(const wchar_t* s) throw(_com_error); + _bstr_t(const _variant_t& var) throw(_com_error); + _bstr_t(BSTR bstr, bool fCopy) throw(_com_error); + + // Destructor + // + ~_bstr_t() throw(); + + // Assignment operators + // + _bstr_t& operator=(const _bstr_t& s) throw(); + _bstr_t& operator=(const char* s) throw(_com_error); + _bstr_t& operator=(const wchar_t* s) throw(_com_error); + _bstr_t& operator=(const _variant_t& var) throw(_com_error); + + // Operators + // + _bstr_t& operator+=(const _bstr_t& s) throw(_com_error); + _bstr_t operator+(const _bstr_t& s) const throw(_com_error); + + // Friend operators + // + friend _bstr_t operator+(const char* s1, const _bstr_t& s2) throw(_com_error); + friend _bstr_t operator+(const wchar_t* s1, const _bstr_t& s2) throw(_com_error); + + // Extractors + // + operator const wchar_t*() const throw(); + operator wchar_t*() const throw(); + operator const char*() const throw(_com_error); + operator char*() const throw(_com_error); + + // Comparison operators + // + bool operator!() const throw(); + bool operator==(const _bstr_t& str) const throw(); + bool operator!=(const _bstr_t& str) const throw(); + bool operator<(const _bstr_t& str) const throw(); + bool operator>(const _bstr_t& str) const throw(); + bool operator<=(const _bstr_t& str) const throw(); + bool operator>=(const _bstr_t& str) const throw(); + + // Low-level helper functions + // + BSTR copy(bool fCopy = true) const throw(_com_error); + unsigned int length() const throw(); + + // Binary string assign + // + void Assign(BSTR s) throw(_com_error); + + // Get the physical BSTR + // + BSTR& GetBSTR() throw(_com_error); + BSTR* GetAddress() throw(_com_error); + + // Attach to the internal BSTR w/o copying + // + void Attach(BSTR s) throw(_com_error); + + // Detach the internal BSTR + // + BSTR Detach() throw(); + +private: + // Referenced counted wrapper + // + class Data_t { + public: + // Constructors + // + Data_t(const char* s) throw(_com_error); + Data_t(const wchar_t* s) throw(_com_error); + Data_t(BSTR bstr, bool fCopy) throw(_com_error); + Data_t(const _bstr_t& s1, const _bstr_t& s2) throw(_com_error); + + // Reference counting routines + // + unsigned long AddRef() throw(); + unsigned long Release() throw(); + unsigned long RefCount() const throw(); + + // Extractors + // + operator const wchar_t*() const throw(); + operator const char*() const throw(_com_error); + + // Low-level helper functions + // + const wchar_t* GetWString() const throw(); + wchar_t*& GetWString() throw(); + const char* GetString() const throw(_com_error); + + BSTR Copy() const throw(_com_error); + void Assign(BSTR s) throw(_com_error); + void Attach(BSTR s) throw(); + unsigned int Length() const throw(); + int Compare(const Data_t& str) const throw(); + + // Exception agnostic wrapper for new + // + void* operator new(size_t sz); + + private: + wchar_t* m_wstr; + mutable char* m_str; + unsigned long m_RefCount; + + // Never allow default construction + // + Data_t() throw(); + + // Never allow copy + // + Data_t(const Data_t& s) throw(); + + // Prevent deletes from outside. Release() must be used. + // + ~Data_t() throw(); + + void _Free() throw(); + }; + +private: + // Reference counted representation + // + Data_t* m_Data; + +private: + // Low-level utilities + // + void _AddRef() throw(); + void _Free() throw(); + int _Compare(const _bstr_t& str) const throw(); +}; + +////////////////////////////////////////////////////////////////////////////// +// +// Constructors +// +////////////////////////////////////////////////////////////////////////////// + +// Default constructor +// +inline _bstr_t::_bstr_t() throw() + : m_Data(NULL) +{ +} + +// Copy constructor +// +inline _bstr_t::_bstr_t(const _bstr_t& s) throw() + : m_Data(s.m_Data) +{ + _AddRef(); +} + +// Construct a _bstr_t from a const char* +// +inline _bstr_t::_bstr_t(const char* s) throw(_com_error) + : m_Data(new Data_t(s)) +{ + if (m_Data == NULL) { + _com_issue_error(E_OUTOFMEMORY); + } +} + +// Construct a _bstr_t from a const whar_t* +// +inline _bstr_t::_bstr_t(const wchar_t* s) throw(_com_error) + : m_Data(new Data_t(s)) +{ + if (m_Data == NULL) { + _com_issue_error(E_OUTOFMEMORY); + } +} + +// Construct a _bstr_t from a BSTR. If fCopy is FALSE, give control of +// data to the _bstr_t without making a new copy. +// +inline _bstr_t::_bstr_t(BSTR bstr, bool fCopy) throw(_com_error) + : m_Data(new Data_t(bstr, fCopy)) +{ + if (m_Data == NULL) { + _com_issue_error(E_OUTOFMEMORY); + } +} + +// Destructor +// +inline _bstr_t::~_bstr_t() throw() +{ + _Free(); +} + +////////////////////////////////////////////////////////////////////////////// +// +// Assignment operators +// +////////////////////////////////////////////////////////////////////////////// + +// Default assign operator +// +inline _bstr_t& _bstr_t::operator=(const _bstr_t& s) throw() +{ + if (this != &s) { + _Free(); + m_Data = s.m_Data; + _AddRef(); + } + + return *this; +} + +// Assign a const char* to a _bstr_t +// +inline _bstr_t& _bstr_t::operator=(const char* s) throw(_com_error) +{ + _COM_ASSERT((const char*) *this != s); + + _Free(); + m_Data = new Data_t(s); + if (m_Data == NULL) { + _com_issue_error(E_OUTOFMEMORY); + } + + return *this; +} + +// Assign a const wchar_t* to a _bstr_t +// +inline _bstr_t& _bstr_t::operator=(const wchar_t* s) throw(_com_error) +{ + _COM_ASSERT((const wchar_t*) *this != s); + + _Free(); + m_Data = new Data_t(s); + if (m_Data == NULL) { + _com_issue_error(E_OUTOFMEMORY); + } + + return *this; +} + +////////////////////////////////////////////////////////////////////////////// +// +// Operators +// +////////////////////////////////////////////////////////////////////////////// + +// Concatenate a _bstr_t onto this _bstr_t +// +inline _bstr_t& _bstr_t::operator+=(const _bstr_t& s) throw(_com_error) +{ + Data_t* newData = new Data_t(*this, s); + if (newData == NULL) { + _com_issue_error(E_OUTOFMEMORY); + } + + _Free(); + m_Data = newData; + + return *this; +} + +// Return the concatenation of this _bstr_t with another _bstr_t +// +inline _bstr_t _bstr_t::operator+(const _bstr_t& s) const throw(_com_error) +{ + _bstr_t b = *this; + b += s; + + return b; +} + +////////////////////////////////////////////////////////////////////////////// +// +// Friend Operators +// +////////////////////////////////////////////////////////////////////////////// + +// Return the concatenation of a const char* with a _bstr_t +// +inline _bstr_t operator+(const char* s1, const _bstr_t& s2) throw(_com_error) +{ + _bstr_t b = s1; + b += s2; + + return b; +} + +// Return the concatenation of a const char* with a _bstr_t +// +inline _bstr_t operator+(const wchar_t* s1, const _bstr_t& s2) throw(_com_error) +{ + _bstr_t b = s1; + b += s2; + + return b; +} + +////////////////////////////////////////////////////////////////////////////// +// +// Extractors +// +////////////////////////////////////////////////////////////////////////////// + +// Extract a const wchar_t* +// +inline _bstr_t::operator const wchar_t*() const throw() +{ + return (m_Data != NULL) ? m_Data->GetWString() : NULL; +} + +// Extract a wchar_t* +// +inline _bstr_t::operator wchar_t*() const throw() +{ + return const_cast((m_Data != NULL) ? m_Data->GetWString() : NULL); +} + +// Extract a const char_t* +// +inline _bstr_t::operator const char*() const throw(_com_error) +{ + return (m_Data != NULL) ? m_Data->GetString() : NULL; +} + +// Extract a char_t* +// +inline _bstr_t::operator char*() const throw(_com_error) +{ + return const_cast((m_Data != NULL) ? m_Data->GetString() : NULL); +} + +////////////////////////////////////////////////////////////////////////////// +// +// Comparison operators +// +////////////////////////////////////////////////////////////////////////////// + +inline bool _bstr_t::operator!() const throw() +{ + return (m_Data != NULL) ? !m_Data->GetWString() : true; +} + +inline bool _bstr_t::operator==(const _bstr_t& str) const throw() +{ + return _Compare(str) == 0; +} + +inline bool _bstr_t::operator!=(const _bstr_t& str) const throw() +{ + return _Compare(str) != 0; +} + +inline bool _bstr_t::operator<(const _bstr_t& str) const throw() +{ + return _Compare(str) < 0; +} + +inline bool _bstr_t::operator>(const _bstr_t& str) const throw() +{ + return _Compare(str) > 0; +} + +inline bool _bstr_t::operator<=(const _bstr_t& str) const throw() +{ + return _Compare(str) <= 0; +} + +inline bool _bstr_t::operator>=(const _bstr_t& str) const throw() +{ + return _Compare(str) >= 0; +} + +////////////////////////////////////////////////////////////////////////////// +// +// Low-level help functions +// +////////////////////////////////////////////////////////////////////////////// + +// Extract a copy of the wrapped BSTR +// +inline BSTR _bstr_t::copy(bool fCopy) const throw(_com_error) +{ + return (m_Data != NULL) ? (fCopy ? m_Data->Copy() : m_Data->GetWString()) : NULL; +} + +// Return the length of the wrapped BSTR +// +inline unsigned int _bstr_t::length() const throw() +{ + return (m_Data != NULL) ? m_Data->Length() : 0; +} + +// Binary string assign +// +inline void _bstr_t::Assign(BSTR s) throw(_com_error) +{ + _COM_ASSERT( m_Data->GetWString() != s); + + _Free(); + m_Data = new Data_t(s, TRUE); + if (m_Data == NULL) { + _com_issue_error(E_OUTOFMEMORY); + } +} + +// Get the physical BSTR +// +inline BSTR& _bstr_t::GetBSTR() throw(_com_error) +{ + if (m_Data == NULL) { + m_Data = new Data_t(0, FALSE); + if (m_Data == NULL) { + _com_issue_error(E_OUTOFMEMORY); + } + } + return m_Data->GetWString(); +} + +// Get the address of the physical BSTR to pass as an 'out'-parameter +// +inline BSTR* _bstr_t::GetAddress() throw(_com_error) +{ + Attach(0); + return &m_Data->GetWString(); +} + +// Attach to the internal BSTR w/o copying +// +inline void _bstr_t::Attach(BSTR s) throw(_com_error) +{ + _Free(); + m_Data = new Data_t(s, FALSE); + if (m_Data == NULL) { + _com_issue_error(E_OUTOFMEMORY); + } +} + +// Detach the internal BSTR +// +inline BSTR _bstr_t::Detach() throw() +{ + _COM_ASSERT(m_Data->RefCount() == 1); + + BSTR b = m_Data->GetWString(); + m_Data->GetWString() = NULL; + _Free(); + return b; +} + +// AddRef the BSTR +// +inline void _bstr_t::_AddRef() throw() +{ + if (m_Data != NULL) { + m_Data->AddRef(); + } +} + +// Free the BSTR +// +inline void _bstr_t::_Free() throw() +{ + if (m_Data != NULL) { + m_Data->Release(); + m_Data = NULL; + } +} + +// Compare two _bstr_t objects +// +inline int _bstr_t::_Compare(const _bstr_t& str) const throw() +{ + if (m_Data == str.m_Data) { + return 0; + } + + if (m_Data == NULL) { + return -1; + } + + if (str.m_Data == NULL) { + return 1; + } + + return m_Data->Compare(*str.m_Data); +} + +////////////////////////////////////////////////////////////////////////////// +// +// Reference counted wrapper - Constructors +// +////////////////////////////////////////////////////////////////////////////// + +// Construct a Data_t from a const char* +// +inline _bstr_t::Data_t::Data_t(const char* s) throw(_com_error) + : m_str(NULL), m_RefCount(1) +{ + m_wstr = _com_util::ConvertStringToBSTR(s); +} + +// Construct a Data_t from a const wchar_t* +// +inline _bstr_t::Data_t::Data_t(const wchar_t* s) throw(_com_error) + : m_str(NULL), m_RefCount(1) +{ + m_wstr = ::SysAllocString(s); + + if (m_wstr == NULL && s != NULL) { + _com_issue_error(E_OUTOFMEMORY); + } +} + +// Construct a Data_t from a BSTR. If fCopy is FALSE, give control of +// data to the Data_t without doing a SysAllocStringByteLen. +// +inline _bstr_t::Data_t::Data_t(BSTR bstr, bool fCopy) throw(_com_error) + : m_str(NULL), m_RefCount(1) +{ + if (fCopy && bstr != NULL) { + m_wstr = ::SysAllocStringByteLen(reinterpret_cast(bstr), + ::SysStringByteLen(bstr)); + + if (m_wstr == NULL) { + _com_issue_error(E_OUTOFMEMORY); + } + } + else { + m_wstr = bstr; + } +} + +// Construct a Data_t from the concatenation of two _bstr_t objects +// +inline _bstr_t::Data_t::Data_t(const _bstr_t& s1, const _bstr_t& s2) throw(_com_error) + : m_str(NULL), m_RefCount(1) +{ + const unsigned int l1 = s1.length(); + const unsigned int l2 = s2.length(); + + m_wstr = ::SysAllocStringByteLen(NULL, (l1 + l2) * sizeof(wchar_t)); + + if (m_wstr == NULL) { + if (l1 + l2 == 0) { + return; + } + _com_issue_error(E_OUTOFMEMORY); + } + + const wchar_t* wstr1 = static_cast(s1); + + if (wstr1 != NULL) { + memcpy(m_wstr, wstr1, (l1 + 1) * sizeof(wchar_t)); + } + + const wchar_t* wstr2 = static_cast(s2); + + if (wstr2 != NULL) { + memcpy(m_wstr + l1, wstr2, (l2 + 1) * sizeof(wchar_t)); + } +} + +////////////////////////////////////////////////////////////////////////////// +// +// Reference counted wrapper - reference counting routines +// +////////////////////////////////////////////////////////////////////////////// + +inline unsigned long _bstr_t::Data_t::AddRef() throw() +{ + InterlockedIncrement(reinterpret_cast(&m_RefCount)); + return m_RefCount; +} + +inline unsigned long _bstr_t::Data_t::Release() throw() +{ + if (!InterlockedDecrement(reinterpret_cast(&m_RefCount))) { + delete this; + return 0; + } + + return m_RefCount; +} + +inline unsigned long _bstr_t::Data_t::RefCount() const throw() +{ + return m_RefCount; +} + +////////////////////////////////////////////////////////////////////////////// +// +// Reference counted wrapper - extractors +// +////////////////////////////////////////////////////////////////////////////// + +// Extract a const wchar_t* +// +inline _bstr_t::Data_t::operator const wchar_t*() const throw() +{ + return m_wstr; +} + +// Extract a const char_t* +// +inline _bstr_t::Data_t::operator const char*() const throw(_com_error) +{ + return GetString(); +} + +////////////////////////////////////////////////////////////////////////////// +// +// Reference counted wrapper - helper functions +// +////////////////////////////////////////////////////////////////////////////// + +inline const wchar_t* _bstr_t::Data_t::GetWString() const throw() +{ + return m_wstr; +} + +inline wchar_t*& _bstr_t::Data_t::GetWString() throw() +{ + return m_wstr; +} + +inline const char* _bstr_t::Data_t::GetString() const throw(_com_error) +{ + if (m_str == NULL) { + m_str = _com_util::ConvertBSTRToString(m_wstr); + } + + return m_str; +} + +// Return a copy of the wrapped BSTR +// +inline BSTR _bstr_t::Data_t::Copy() const throw(_com_error) +{ + if (m_wstr != NULL) { + BSTR bstr = ::SysAllocStringByteLen(reinterpret_cast(m_wstr), ::SysStringByteLen(m_wstr)); + + if (bstr == NULL) { + _com_issue_error(E_OUTOFMEMORY); + } + + return bstr; + } + + return NULL; +} + +inline void _bstr_t::Data_t::Assign(BSTR s) throw(_com_error) +{ + _Free(); + if (s != NULL) { + m_wstr = ::SysAllocStringByteLen(reinterpret_cast(s), ::SysStringByteLen(s)); + m_str = 0; + } +} + +inline void _bstr_t::Data_t::Attach(BSTR s) throw() +{ + _Free(); + m_wstr = s; + m_str = 0; + m_RefCount = 1; +} + +// Return the length of the wrapper BSTR +// +inline unsigned int _bstr_t::Data_t::Length() const throw() +{ + return m_wstr ? ::SysStringLen(m_wstr) : 0; +} + +// Compare two wrapped BSTRs +// +inline int _bstr_t::Data_t::Compare(const _bstr_t::Data_t& str) const throw() +{ + if (m_wstr == NULL) { + return str.m_wstr ? -1 : 0; + } + + if (str.m_wstr == NULL) { + return 1; + } + + const unsigned int l1 = ::SysStringLen(m_wstr); + const unsigned int l2 = ::SysStringLen(str.m_wstr); + + unsigned int len = l1; + if (len > l2) { + len = l2; + } + + BSTR bstr1 = m_wstr; + BSTR bstr2 = str.m_wstr; + + while (len-- > 0) { + if (*bstr1++ != *bstr2++) { + return bstr1[-1] - bstr2[-1]; + } + } + + return (l1 < l2) ? -1 : (l1 == l2) ? 0 : 1; +} + +// Exception agnostic wrapper for new +// +#ifdef _COM_OPERATOR_NEW_THROWS +inline void* _bstr_t::Data_t::operator new(size_t sz) { + try { + return ::operator new(sz); + } catch (...) { + return NULL; + } +} +#else // _COM_OPERATOR_NEW_THROWS +inline void* _bstr_t::Data_t::operator new(size_t sz) { + return ::operator new(sz); +} +#endif // _COM_OPERATOR_NEW_THROWS + +// Destruct this object +// +inline _bstr_t::Data_t::~Data_t() throw() +{ + _Free(); +} + +// Free up this object +// +inline void _bstr_t::Data_t::_Free() throw() +{ + if (m_wstr != NULL) { + ::SysFreeString(m_wstr); + } + + if (m_str != NULL) { + delete [] m_str; + } +} + +////////////////////////////////////////////////////////////////////////////// +// +// Wrapper class for VARIANT +// +////////////////////////////////////////////////////////////////////////////// + +/* + * VARENUM usage key, + * + * * [V] - may appear in a VARIANT + * * [T] - may appear in a TYPEDESC + * * [P] - may appear in an OLE property set + * * [S] - may appear in a Safe Array + * * [C] - supported by class _variant_t + * + * + * VT_EMPTY [V] [P] nothing + * VT_NULL [V] [P] SQL style Null + * VT_I2 [V][T][P][S][C] 2 byte signed int + * VT_I4 [V][T][P][S][C] 4 byte signed int + * VT_R4 [V][T][P][S][C] 4 byte real + * VT_R8 [V][T][P][S][C] 8 byte real + * VT_CY [V][T][P][S][C] currency + * VT_DATE [V][T][P][S][C] date + * VT_BSTR [V][T][P][S][C] OLE Automation string + * VT_DISPATCH [V][T][P][S][C] IDispatch * + * VT_ERROR [V][T] [S][C] SCODE + * VT_BOOL [V][T][P][S][C] True=-1, False=0 + * VT_VARIANT [V][T][P][S] VARIANT * + * VT_UNKNOWN [V][T] [S][C] IUnknown * + * VT_DECIMAL [V][T] [S][C] 16 byte fixed point + * VT_I1 [T] signed char + * VT_UI1 [V][T][P][S][C] unsigned char + * VT_UI2 [T][P] unsigned short + * VT_UI4 [T][P] unsigned short + * VT_I8 [T][P] signed 64-bit int + * VT_UI8 [T][P] unsigned 64-bit int + * VT_INT [T] signed machine int + * VT_UINT [T] unsigned machine int + * VT_VOID [T] C style void + * VT_HRESULT [T] Standard return type + * VT_PTR [T] pointer type + * VT_SAFEARRAY [T] (use VT_ARRAY in VARIANT) + * VT_CARRAY [T] C style array + * VT_USERDEFINED [T] user defined type + * VT_LPSTR [T][P] null terminated string + * VT_LPWSTR [T][P] wide null terminated string + * VT_FILETIME [P] FILETIME + * VT_BLOB [P] Length prefixed bytes + * VT_STREAM [P] Name of the stream follows + * VT_STORAGE [P] Name of the storage follows + * VT_STREAMED_OBJECT [P] Stream contains an object + * VT_STORED_OBJECT [P] Storage contains an object + * VT_BLOB_OBJECT [P] Blob contains an object + * VT_CF [P] Clipboard format + * VT_CLSID [P] A Class ID + * VT_VECTOR [P] simple counted array + * VT_ARRAY [V] SAFEARRAY* + * VT_BYREF [V] void* for local use + */ + +class _variant_t : public ::tagVARIANT { +public: + // Constructors + // + _variant_t() throw(); + + _variant_t(const VARIANT& varSrc) throw(_com_error); + _variant_t(const VARIANT* pSrc) throw(_com_error); + _variant_t(const _variant_t& varSrc) throw(_com_error); + + _variant_t(VARIANT& varSrc, bool fCopy) throw(_com_error); // Attach VARIANT if !fCopy + + _variant_t(short sSrc, VARTYPE vtSrc = VT_I2) throw(_com_error); // Creates a VT_I2, or a VT_BOOL + _variant_t(long lSrc, VARTYPE vtSrc = VT_I4) throw(_com_error); // Creates a VT_I4, a VT_ERROR, or a VT_BOOL + _variant_t(float fltSrc) throw(); // Creates a VT_R4 + _variant_t(double dblSrc, VARTYPE vtSrc = VT_R8) throw(_com_error); // Creates a VT_R8, or a VT_DATE + _variant_t(const CY& cySrc) throw(); // Creates a VT_CY + _variant_t(const _bstr_t& bstrSrc) throw(_com_error); // Creates a VT_BSTR + _variant_t(const wchar_t *pSrc) throw(_com_error); // Creates a VT_BSTR + _variant_t(const char* pSrc) throw(_com_error); // Creates a VT_BSTR + _variant_t(IDispatch* pSrc, bool fAddRef = true) throw(); // Creates a VT_DISPATCH + _variant_t(bool boolSrc) throw(); // Creates a VT_BOOL + _variant_t(IUnknown* pSrc, bool fAddRef = true) throw(); // Creates a VT_UNKNOWN + _variant_t(const DECIMAL& decSrc) throw(); // Creates a VT_DECIMAL + _variant_t(BYTE bSrc) throw(); // Creates a VT_UI1 + + _variant_t(char cSrc) throw(); // Creates a VT_I1 + _variant_t(unsigned short usSrc) throw(); // Creates a VT_UI2 + _variant_t(unsigned long ulSrc) throw(); // Creates a VT_UI4 + _variant_t(int iSrc) throw(); // Creates a VT_INT + _variant_t(unsigned int uiSrc) throw(); // Creates a VT_UINT + _variant_t(__int64 i8Src) throw(); // Creates a VT_I8 + _variant_t(unsigned __int64 ui8Src) throw(); // Creates a VT_UI8 + + // Destructor + // + ~_variant_t() throw(_com_error); + + // Extractors + // + operator short() const throw(_com_error); // Extracts a short from a VT_I2 + operator long() const throw(_com_error); // Extracts a long from a VT_I4 + operator float() const throw(_com_error); // Extracts a float from a VT_R4 + operator double() const throw(_com_error); // Extracts a double from a VT_R8 + operator CY() const throw(_com_error); // Extracts a CY from a VT_CY + operator _bstr_t() const throw(_com_error); // Extracts a _bstr_t from a VT_BSTR + operator IDispatch*() const throw(_com_error); // Extracts a IDispatch* from a VT_DISPATCH + operator bool() const throw(_com_error); // Extracts a bool from a VT_BOOL + operator IUnknown*() const throw(_com_error); // Extracts a IUnknown* from a VT_UNKNOWN + operator DECIMAL() const throw(_com_error); // Extracts a DECIMAL from a VT_DECIMAL + operator BYTE() const throw(_com_error); // Extracts a BTYE (unsigned char) from a VT_UI1 + operator VARIANT() const throw(); + + operator char() const throw(_com_error); // Extracts a char from a VT_I1 + operator unsigned short() const throw(_com_error); // Extracts a unsigned short from a VT_UI2 + operator unsigned long() const throw(_com_error); // Extracts a unsigned long from a VT_UI4 + operator int() const throw(_com_error); // Extracts a int from a VT_INT + operator unsigned int() const throw(_com_error); // Extracts a unsigned int from a VT_UINT + operator __int64() const throw(_com_error); // Extracts a __int64 from a VT_I8 + operator unsigned __int64() const throw(_com_error); // Extracts a unsigned __int64 from a VT_UI8 + + // Assignment operations + // + _variant_t& operator=(const VARIANT& varSrc) throw(_com_error); + _variant_t& operator=(const VARIANT* pSrc) throw(_com_error); + _variant_t& operator=(const _variant_t& varSrc) throw(_com_error); + + _variant_t& operator=(short sSrc) throw(_com_error); // Assign a VT_I2, or a VT_BOOL + _variant_t& operator=(long lSrc) throw(_com_error); // Assign a VT_I4, a VT_ERROR or a VT_BOOL + _variant_t& operator=(float fltSrc) throw(_com_error); // Assign a VT_R4 + _variant_t& operator=(double dblSrc) throw(_com_error); // Assign a VT_R8, or a VT_DATE + _variant_t& operator=(const CY& cySrc) throw(_com_error); // Assign a VT_CY + _variant_t& operator=(const _bstr_t& bstrSrc) throw(_com_error); // Assign a VT_BSTR + _variant_t& operator=(const wchar_t* pSrc) throw(_com_error); // Assign a VT_BSTR + _variant_t& operator=(const char* pSrc) throw(_com_error); // Assign a VT_BSTR + _variant_t& operator=(IDispatch* pSrc) throw(_com_error); // Assign a VT_DISPATCH + _variant_t& operator=(bool boolSrc) throw(_com_error); // Assign a VT_BOOL + _variant_t& operator=(IUnknown* pSrc) throw(_com_error); // Assign a VT_UNKNOWN + _variant_t& operator=(const DECIMAL& decSrc) throw(_com_error); // Assign a VT_DECIMAL + _variant_t& operator=(BYTE bSrc) throw(_com_error); // Assign a VT_UI1 + + _variant_t& operator=(char cSrc) throw(_com_error); // Assign a VT_I1 + _variant_t& operator=(unsigned short usSrc) throw(_com_error); // Assign a VT_UI2 + _variant_t& operator=(unsigned long ulSrc) throw(_com_error); // Assign a VT_UI4 + _variant_t& operator=(int iSrc) throw(_com_error); // Assign a VT_INT + _variant_t& operator=(unsigned int uiSrc) throw(_com_error); // Assign a VT_UINT + _variant_t& operator=(__int64 i8Src) throw(_com_error); // Assign a VT_I8 + _variant_t& operator=(unsigned __int64 ui8Src) throw(_com_error); // Assign a VT_UI8 + + // Comparison operations + // + bool operator==(const VARIANT& varSrc) const throw(_com_error); + bool operator==(const VARIANT* pSrc) const throw(_com_error); + + bool operator!=(const VARIANT& varSrc) const throw(_com_error); + bool operator!=(const VARIANT* pSrc) const throw(_com_error); + + // Low-level operations + // + void Clear() throw(_com_error); + + void Attach(VARIANT& varSrc) throw(_com_error); + VARIANT Detach() throw(_com_error); + + VARIANT& GetVARIANT() throw(); + VARIANT* GetAddress() throw(_com_error); + + void ChangeType(VARTYPE vartype, const _variant_t* pSrc = NULL) throw(_com_error); + + void SetString(const char* pSrc) throw(_com_error); // used to set ANSI string +}; + +////////////////////////////////////////////////////////////////////////////////////////// +// +// Constructors +// +////////////////////////////////////////////////////////////////////////////////////////// + +// Default constructor +// +inline _variant_t::_variant_t() throw() +{ + ::VariantInit(this); +} + +// Construct a _variant_t from a const VARIANT& +// +inline _variant_t::_variant_t(const VARIANT& varSrc) throw(_com_error) +{ + ::VariantInit(this); + _com_util::CheckError(::VariantCopy(this, const_cast(&varSrc))); +} + +// Construct a _variant_t from a const VARIANT* +// +inline _variant_t::_variant_t(const VARIANT* pSrc) throw(_com_error) +{ + ::VariantInit(this); + _com_util::CheckError(::VariantCopy(this, const_cast(pSrc))); +} + +// Construct a _variant_t from a const _variant_t& +// +inline _variant_t::_variant_t(const _variant_t& varSrc) throw(_com_error) +{ + ::VariantInit(this); + _com_util::CheckError(::VariantCopy(this, const_cast(static_cast(&varSrc)))); +} + +// Construct a _variant_t from a VARIANT&. If fCopy is FALSE, give control of +// data to the _variant_t without doing a VariantCopy. +// +inline _variant_t::_variant_t(VARIANT& varSrc, bool fCopy) throw(_com_error) +{ + if (fCopy) { + ::VariantInit(this); + _com_util::CheckError(::VariantCopy(this, &varSrc)); + } else { + memcpy(this, &varSrc, sizeof(varSrc)); + V_VT(&varSrc) = VT_EMPTY; + } +} + +// Construct either a VT_I2 VARIANT or a VT_BOOL VARIANT from +// a short (the default is VT_I2) +// +inline _variant_t::_variant_t(short sSrc, VARTYPE vtSrc) throw(_com_error) +{ + if ((vtSrc != VT_I2) && (vtSrc != VT_BOOL)) { + _com_issue_error(E_INVALIDARG); + } + + if (vtSrc == VT_BOOL) { + V_VT(this) = VT_BOOL; + V_BOOL(this) = (sSrc ? VARIANT_TRUE : VARIANT_FALSE); + } + else { + V_VT(this) = VT_I2; + V_I2(this) = sSrc; + } +} + +// Construct either a VT_I4 VARIANT, a VT_BOOL VARIANT, or a +// VT_ERROR VARIANT from a long (the default is VT_I4) +// +inline _variant_t::_variant_t(long lSrc, VARTYPE vtSrc) throw(_com_error) +{ + if ((vtSrc != VT_I4) && (vtSrc != VT_ERROR) && (vtSrc != VT_BOOL)) { + _com_issue_error(E_INVALIDARG); + } + + if (vtSrc == VT_ERROR) { + V_VT(this) = VT_ERROR; + V_ERROR(this) = lSrc; + } + else if (vtSrc == VT_BOOL) { + V_VT(this) = VT_BOOL; + V_BOOL(this) = (lSrc ? VARIANT_TRUE : VARIANT_FALSE); + } + else { + V_VT(this) = VT_I4; + V_I4(this) = lSrc; + } +} + +// Construct a VT_R4 VARIANT from a float +// +inline _variant_t::_variant_t(float fltSrc) throw() +{ + V_VT(this) = VT_R4; + V_R4(this) = fltSrc; +} + +// Construct either a VT_R8 VARIANT, or a VT_DATE VARIANT from +// a double (the default is VT_R8) +// +inline _variant_t::_variant_t(double dblSrc, VARTYPE vtSrc) throw(_com_error) +{ + if ((vtSrc != VT_R8) && (vtSrc != VT_DATE)) { + _com_issue_error(E_INVALIDARG); + } + + if (vtSrc == VT_DATE) { + V_VT(this) = VT_DATE; + V_DATE(this) = dblSrc; + } + else { + V_VT(this) = VT_R8; + V_R8(this) = dblSrc; + } +} + +// Construct a VT_CY from a CY +// +inline _variant_t::_variant_t(const CY& cySrc) throw() +{ + V_VT(this) = VT_CY; + V_CY(this) = cySrc; +} + +// Construct a VT_BSTR VARIANT from a const _bstr_t& +// +inline _variant_t::_variant_t(const _bstr_t& bstrSrc) throw(_com_error) +{ + V_VT(this) = VT_BSTR; + + BSTR bstr = static_cast(bstrSrc); + V_BSTR(this) = ::SysAllocStringByteLen(reinterpret_cast(bstr), + ::SysStringByteLen(bstr)); + + if (V_BSTR(this) == NULL) { + _com_issue_error(E_OUTOFMEMORY); + } +} + +// Construct a VT_BSTR VARIANT from a const wchar_t* +// +inline _variant_t::_variant_t(const wchar_t* pSrc) throw(_com_error) +{ + V_VT(this) = VT_BSTR; + V_BSTR(this) = ::SysAllocString(pSrc); + + if (V_BSTR(this) == NULL && pSrc != NULL) { + _com_issue_error(E_OUTOFMEMORY); + } +} + +// Construct a VT_BSTR VARIANT from a const char* +// +inline _variant_t::_variant_t(const char* pSrc) throw(_com_error) +{ + V_VT(this) = VT_BSTR; + V_BSTR(this) = _com_util::ConvertStringToBSTR(pSrc); +} + +// Construct a VT_DISPATCH VARIANT from an IDispatch* +// +inline _variant_t::_variant_t(IDispatch* pSrc, bool fAddRef) throw() +{ + V_VT(this) = VT_DISPATCH; + V_DISPATCH(this) = pSrc; + + // Need the AddRef() as VariantClear() calls Release(), unless fAddRef + // false indicates we're taking ownership + // + if (fAddRef) { + V_DISPATCH(this)->AddRef(); + } +} + +// Construct a VT_BOOL VARIANT from a bool +// +inline _variant_t::_variant_t(bool boolSrc) throw() +{ + V_VT(this) = VT_BOOL; + V_BOOL(this) = (boolSrc ? VARIANT_TRUE : VARIANT_FALSE); +} + +// Construct a VT_UNKNOWN VARIANT from an IUnknown* +// +inline _variant_t::_variant_t(IUnknown* pSrc, bool fAddRef) throw() +{ + V_VT(this) = VT_UNKNOWN; + V_UNKNOWN(this) = pSrc; + + // Need the AddRef() as VariantClear() calls Release(), unless fAddRef + // false indicates we're taking ownership + // + if (fAddRef) { + V_UNKNOWN(this)->AddRef(); + } +} + +// Construct a VT_DECIMAL VARIANT from a DECIMAL +// +inline _variant_t::_variant_t(const DECIMAL& decSrc) throw() +{ + // Order is important here! Setting V_DECIMAL wipes out the entire VARIANT + // + V_DECIMAL(this) = decSrc; + V_VT(this) = VT_DECIMAL; +} + +// Construct a VT_UI1 VARIANT from a BYTE (unsigned char) +// +inline _variant_t::_variant_t(BYTE bSrc) throw() +{ + V_VT(this) = VT_UI1; + V_UI1(this) = bSrc; +} + +// Construct a VT_I1 VARIANT from a char +// +inline _variant_t::_variant_t(char cSrc) throw() +{ + V_VT(this) = VT_I1; + V_I1(this) = cSrc; +} + +// Construct a VT_UI2 VARIANT from a unsigned short +// +inline _variant_t::_variant_t(unsigned short usSrc) throw() +{ + V_VT(this) = VT_UI2; + V_UI2(this) = usSrc; +} + +// Construct a VT_UI4 VARIANT from a unsigned long +// +inline _variant_t::_variant_t(unsigned long ulSrc) throw() +{ + V_VT(this) = VT_UI4; + V_UI4(this) = ulSrc; +} + +// Construct a VT_INT VARIANT from a int +// +inline _variant_t::_variant_t(int iSrc) throw() +{ + V_VT(this) = VT_INT; + V_INT(this) = iSrc; +} + +// Construct a VT_UINT VARIANT from a unsigned int +// +inline _variant_t::_variant_t(unsigned int uiSrc) throw() +{ + V_VT(this) = VT_UINT; + V_UINT(this) = uiSrc; +} + +// Construct a VT_I8 VARIANT from a __int64 +// +inline _variant_t::_variant_t(__int64 i8Src) throw() +{ + V_VT(this) = VT_I8; + V_I8(this) = i8Src; +} + +// Construct a VT_UI8 VARIANT from a unsigned __int64 +// +inline _variant_t::_variant_t(unsigned __int64 ui8Src) throw() +{ + V_VT(this) = VT_UI8; + V_UI8(this) = ui8Src; +} + + +////////////////////////////////////////////////////////////////////////////////////////// +// +// Extractors +// +////////////////////////////////////////////////////////////////////////////////////////// + +// Extracts a VT_I2 into a short +// +inline _variant_t::operator short() const throw(_com_error) +{ + if (V_VT(this) == VT_I2) { + return V_I2(this); + } + + _variant_t varDest; + + varDest.ChangeType(VT_I2, this); + + return V_I2(&varDest); +} + +// Extracts a VT_I4 into a long +// +inline _variant_t::operator long() const throw(_com_error) +{ + if (V_VT(this) == VT_I4) { + return V_I4(this); + } + + _variant_t varDest; + + varDest.ChangeType(VT_I4, this); + + return V_I4(&varDest); +} + +// Extracts a VT_R4 into a float +// +inline _variant_t::operator float() const throw(_com_error) +{ + if (V_VT(this) == VT_R4) { + return V_R4(this); + } + + _variant_t varDest; + + varDest.ChangeType(VT_R4, this); + + return V_R4(&varDest); +} + +// Extracts a VT_R8 into a double +// +inline _variant_t::operator double() const throw(_com_error) +{ + if (V_VT(this) == VT_R8) { + return V_R8(this); + } + + _variant_t varDest; + + varDest.ChangeType(VT_R8, this); + + return V_R8(&varDest); +} + +// Extracts a VT_CY into a CY +// +inline _variant_t::operator CY() const throw(_com_error) +{ + if (V_VT(this) == VT_CY) { + return V_CY(this); + } + + _variant_t varDest; + + varDest.ChangeType(VT_CY, this); + + return V_CY(&varDest); +} + +// Extracts a VT_BSTR into a _bstr_t +// +inline _variant_t::operator _bstr_t() const throw(_com_error) +{ + if (V_VT(this) == VT_BSTR) { + return V_BSTR(this); + } + + _variant_t varDest; + + varDest.ChangeType(VT_BSTR, this); + + return V_BSTR(&varDest); +} + +// Extracts a VT_DISPATCH into an IDispatch* +// +inline _variant_t::operator IDispatch*() const throw(_com_error) +{ + if (V_VT(this) == VT_DISPATCH) { + V_DISPATCH(this)->AddRef(); + return V_DISPATCH(this); + } + + _variant_t varDest; + + varDest.ChangeType(VT_DISPATCH, this); + + V_DISPATCH(&varDest)->AddRef(); + return V_DISPATCH(&varDest); +} + +// Extract a VT_BOOL into a bool +// +inline _variant_t::operator bool() const throw(_com_error) +{ + if (V_VT(this) == VT_BOOL) { + return V_BOOL(this) ? true : false; + } + + _variant_t varDest; + + varDest.ChangeType(VT_BOOL, this); + + return V_BOOL(&varDest) ? true : false; +} + +// Extracts a VT_UNKNOWN into an IUnknown* +// +inline _variant_t::operator IUnknown*() const throw(_com_error) +{ + if (V_VT(this) == VT_UNKNOWN) { + V_UNKNOWN(this)->AddRef(); + return V_UNKNOWN(this); + } + + _variant_t varDest; + + varDest.ChangeType(VT_UNKNOWN, this); + + V_UNKNOWN(&varDest)->AddRef(); + return V_UNKNOWN(&varDest); +} + +// Extracts a VT_DECIMAL into a DECIMAL +// +inline _variant_t::operator DECIMAL() const throw(_com_error) +{ + if (V_VT(this) == VT_DECIMAL) { + return V_DECIMAL(this); + } + + _variant_t varDest; + + varDest.ChangeType(VT_DECIMAL, this); + + return V_DECIMAL(&varDest); +} + +// Extracts a VT_UI1 into a BYTE (unsigned char) +// +inline _variant_t::operator BYTE() const throw(_com_error) +{ + if (V_VT(this) == VT_UI1) { + return V_UI1(this); + } + + _variant_t varDest; + + varDest.ChangeType(VT_UI1, this); + + return V_UI1(&varDest); +} + +// Extract the physical VARIANT +// +inline _variant_t::operator VARIANT() const throw() +{ + return *(VARIANT*) this; +} + +// Extracts a VT_I1 into a char +// +inline _variant_t::operator char() const throw(_com_error) +{ + if (V_VT(this) == VT_I1) { + return V_I1(this); + } + + _variant_t varDest; + + varDest.ChangeType(VT_I1, this); + + return V_I1(&varDest); +} + +// Extracts a VT_UI2 into a unsigned short +// +inline _variant_t::operator unsigned short() const throw(_com_error) +{ + if (V_VT(this) == VT_UI2) { + return V_UI2(this); + } + + _variant_t varDest; + + varDest.ChangeType(VT_UI2, this); + + return V_UI2(&varDest); +} + +// Extracts a VT_UI4 into a unsigned long +// +inline _variant_t::operator unsigned long() const throw(_com_error) +{ + if (V_VT(this) == VT_UI4) { + return V_UI4(this); + } + + _variant_t varDest; + + varDest.ChangeType(VT_UI4, this); + + return V_UI4(&varDest); +} + +// Extracts a VT_INT into a int +// +inline _variant_t::operator int() const throw(_com_error) +{ + if (V_VT(this) == VT_INT) { + return V_INT(this); + } + + _variant_t varDest; + + varDest.ChangeType(VT_INT, this); + + return V_INT(&varDest); +} + +// Extracts a VT_UINT into a unsigned int +// +inline _variant_t::operator unsigned int() const throw(_com_error) +{ + if (V_VT(this) == VT_UINT) { + return V_UINT(this); + } + + _variant_t varDest; + + varDest.ChangeType(VT_UINT, this); + + return V_UINT(&varDest); +} + +// Extracts a VT_I8 into a __int64 +// +inline _variant_t::operator __int64() const throw(_com_error) +{ + if (V_VT(this) == VT_I8) { + return V_I8(this); + } + + _variant_t varDest; + + varDest.ChangeType(VT_I8, this); + + return V_I8(&varDest); +} + +// Extracts a VT_UI8 into a unsigned __int64 +// +inline _variant_t::operator unsigned __int64() const throw(_com_error) +{ + if (V_VT(this) == VT_UI8) { + return V_UI8(this); + } + + _variant_t varDest; + + varDest.ChangeType(VT_UI8, this); + + return V_UI8(&varDest); +} + +////////////////////////////////////////////////////////////////////////////////////////// +// +// Assignment operations +// +////////////////////////////////////////////////////////////////////////////////////////// + +// Assign a const VARIANT& (::VariantCopy handles everything) +// +inline _variant_t& _variant_t::operator=(const VARIANT& varSrc) throw(_com_error) +{ + _com_util::CheckError(::VariantCopy(this, const_cast(&varSrc))); + + return *this; +} + +// Assign a const VARIANT* (::VariantCopy handles everything) +// +inline _variant_t& _variant_t::operator=(const VARIANT* pSrc) throw(_com_error) +{ + _com_util::CheckError(::VariantCopy(this, const_cast(pSrc))); + + return *this; +} + +// Assign a const _variant_t& (::VariantCopy handles everything) +// +inline _variant_t& _variant_t::operator=(const _variant_t& varSrc) throw(_com_error) +{ + _com_util::CheckError(::VariantCopy(this, const_cast(static_cast(&varSrc)))); + + return *this; +} + +// Assign a short creating either VT_I2 VARIANT or a +// VT_BOOL VARIANT (VT_I2 is the default) +// +inline _variant_t& _variant_t::operator=(short sSrc) throw(_com_error) +{ + if (V_VT(this) == VT_I2) { + V_I2(this) = sSrc; + } + else if (V_VT(this) == VT_BOOL) { + V_BOOL(this) = (sSrc ? VARIANT_TRUE : VARIANT_FALSE); + } + else { + // Clear the VARIANT and create a VT_I2 + // + Clear(); + + V_VT(this) = VT_I2; + V_I2(this) = sSrc; + } + + return *this; +} + +// Assign a long creating either VT_I4 VARIANT, a VT_ERROR VARIANT +// or a VT_BOOL VARIANT (VT_I4 is the default) +// +inline _variant_t& _variant_t::operator=(long lSrc) throw(_com_error) +{ + if (V_VT(this) == VT_I4) { + V_I4(this) = lSrc; + } + else if (V_VT(this) == VT_ERROR) { + V_ERROR(this) = lSrc; + } + else if (V_VT(this) == VT_BOOL) { + V_BOOL(this) = (lSrc ? VARIANT_TRUE : VARIANT_FALSE); + } + else { + // Clear the VARIANT and create a VT_I4 + // + Clear(); + + V_VT(this) = VT_I4; + V_I4(this) = lSrc; + } + + return *this; +} + +// Assign a float creating a VT_R4 VARIANT +// +inline _variant_t& _variant_t::operator=(float fltSrc) throw(_com_error) +{ + if (V_VT(this) != VT_R4) { + // Clear the VARIANT and create a VT_R4 + // + Clear(); + + V_VT(this) = VT_R4; + } + + V_R4(this) = fltSrc; + + return *this; +} + +// Assign a double creating either a VT_R8 VARIANT, or a VT_DATE +// VARIANT (VT_R8 is the default) +// +inline _variant_t& _variant_t::operator=(double dblSrc) throw(_com_error) +{ + if (V_VT(this) == VT_R8) { + V_R8(this) = dblSrc; + } + else if(V_VT(this) == VT_DATE) { + V_DATE(this) = dblSrc; + } + else { + // Clear the VARIANT and create a VT_R8 + // + Clear(); + + V_VT(this) = VT_R8; + V_R8(this) = dblSrc; + } + + return *this; +} + +// Assign a CY creating a VT_CY VARIANT +// +inline _variant_t& _variant_t::operator=(const CY& cySrc) throw(_com_error) +{ + if (V_VT(this) != VT_CY) { + // Clear the VARIANT and create a VT_CY + // + Clear(); + + V_VT(this) = VT_CY; + } + + V_CY(this) = cySrc; + + return *this; +} + +// Assign a const _bstr_t& creating a VT_BSTR VARIANT +// +inline _variant_t& _variant_t::operator=(const _bstr_t& bstrSrc) throw(_com_error) +{ + // Clear the VARIANT (This will SysFreeString() any previous occupant) + // + _COM_ASSERT(V_BSTR(this) != (BSTR) bstrSrc); + + Clear(); + + V_VT(this) = VT_BSTR; + + if (!bstrSrc) { + V_BSTR(this) = NULL; + } + else { + BSTR bstr = static_cast(bstrSrc); + V_BSTR(this) = ::SysAllocStringByteLen(reinterpret_cast(bstr), + ::SysStringByteLen(bstr)); + + if (V_BSTR(this) == NULL) { + _com_issue_error(E_OUTOFMEMORY); + } + } + + return *this; +} + +// Assign a const wchar_t* creating a VT_BSTR VARIANT +// +inline _variant_t& _variant_t::operator=(const wchar_t* pSrc) throw(_com_error) +{ + // Clear the VARIANT (This will SysFreeString() any previous occupant) + // + _COM_ASSERT(V_BSTR(this) != pSrc); + + Clear(); + + V_VT(this) = VT_BSTR; + + if (pSrc == NULL) { + V_BSTR(this) = NULL; + } + else { + V_BSTR(this) = ::SysAllocString(pSrc); + + if (V_BSTR(this) == NULL) { + _com_issue_error(E_OUTOFMEMORY); + } + } + + return *this; +} + +// Assign a const char* creating a VT_BSTR VARIANT +// +inline _variant_t& _variant_t::operator=(const char* pSrc) throw(_com_error) +{ + // Clear the VARIANT (This will SysFreeString() any previous occupant) + // + _COM_ASSERT(V_I1REF(this) != pSrc); + + Clear(); + + V_VT(this) = VT_BSTR; + V_BSTR(this) = _com_util::ConvertStringToBSTR(pSrc); + + return *this; +} + +// Assign an IDispatch* creating a VT_DISPATCH VARIANT +// +inline _variant_t& _variant_t::operator=(IDispatch* pSrc) throw(_com_error) +{ + // Clear the VARIANT (This will Release() any previous occupant) + // + _COM_ASSERT(V_DISPATCH(this) != pSrc); + + Clear(); + + V_VT(this) = VT_DISPATCH; + V_DISPATCH(this) = pSrc; + + // Need the AddRef() as VariantClear() calls Release() + // + V_DISPATCH(this)->AddRef(); + + return *this; +} + +// Assign a bool creating a VT_BOOL VARIANT +// +inline _variant_t& _variant_t::operator=(bool boolSrc) throw(_com_error) +{ + if (V_VT(this) != VT_BOOL) { + // Clear the VARIANT and create a VT_BOOL + // + Clear(); + + V_VT(this) = VT_BOOL; + } + + V_BOOL(this) = (boolSrc ? VARIANT_TRUE : VARIANT_FALSE); + + return *this; +} + +// Assign an IUnknown* creating a VT_UNKNOWN VARIANT +// +inline _variant_t& _variant_t::operator=(IUnknown* pSrc) throw(_com_error) +{ + // Clear VARIANT (This will Release() any previous occupant) + // + _COM_ASSERT(V_UNKNOWN(this) != pSrc); + + Clear(); + + V_VT(this) = VT_UNKNOWN; + V_UNKNOWN(this) = pSrc; + + // Need the AddRef() as VariantClear() calls Release() + // + V_UNKNOWN(this)->AddRef(); + + return *this; +} + +// Assign a DECIMAL creating a VT_DECIMAL VARIANT +// +inline _variant_t& _variant_t::operator=(const DECIMAL& decSrc) throw(_com_error) +{ + if (V_VT(this) != VT_DECIMAL) { + // Clear the VARIANT + // + Clear(); + } + + // Order is important here! Setting V_DECIMAL wipes out the entire VARIANT + V_DECIMAL(this) = decSrc; + V_VT(this) = VT_DECIMAL; + + return *this; +} + +// Assign a BTYE (unsigned char) creating a VT_UI1 VARIANT +// +inline _variant_t& _variant_t::operator=(BYTE bSrc) throw(_com_error) +{ + if (V_VT(this) != VT_UI1) { + // Clear the VARIANT and create a VT_UI1 + // + Clear(); + + V_VT(this) = VT_UI1; + } + + V_UI1(this) = bSrc; + + return *this; +} + +// Assign a char creating a VT_I1 VARIANT +// +inline _variant_t& _variant_t::operator=(char cSrc) throw(_com_error){ + if (V_VT(this) != VT_I1) { + // Clear the VARIANT and create a VT_I1 + // + Clear(); + + V_VT(this) = VT_I1; + } + + V_I1(this) = cSrc; + + return *this; +} + +// Assign a char creating a VT_UI2 VARIANT +// +inline _variant_t& _variant_t::operator=(unsigned short usSrc) throw(_com_error){ + if (V_VT(this) != VT_UI2) { + // Clear the VARIANT and create a VT_UI2 + // + Clear(); + + V_VT(this) = VT_UI2; + } + + V_UI2(this) = usSrc; + + return *this; +} + +// Assign a char creating a VT_UI4 VARIANT +// +inline _variant_t& _variant_t::operator=(unsigned long ulSrc) throw(_com_error){ + if (V_VT(this) != VT_UI4) { + // Clear the VARIANT and create a VT_UI4 + // + Clear(); + + V_VT(this) = VT_UI4; + } + + V_UI4(this) = ulSrc; + + return *this; +} + +// Assign a char creating a VT_INT VARIANT +// +inline _variant_t& _variant_t::operator=(int iSrc) throw(_com_error){ + if (V_VT(this) != VT_INT) { + // Clear the VARIANT and create a VT_INT + // + Clear(); + + V_VT(this) = VT_INT; + } + + V_INT(this) = iSrc; + + return *this; +} + +// Assign a char creating a VT_UINT VARIANT +// +inline _variant_t& _variant_t::operator=(unsigned int uiSrc) throw(_com_error){ + if (V_VT(this) != VT_UINT) { + // Clear the VARIANT and create a VT_UINT + // + Clear(); + + V_VT(this) = VT_UINT; + } + + V_UINT(this) = uiSrc; + + return *this; +} + +// Assign a char creating a VT_I8 VARIANT +// +inline _variant_t& _variant_t::operator=(__int64 i8Src) throw(_com_error){ + if (V_VT(this) != VT_I8) { + // Clear the VARIANT and create a VT_I8 + // + Clear(); + + V_VT(this) = VT_I8; + } + + V_I8(this) = i8Src; + + return *this; +} + +// Assign a char creating a VT_UI8 VARIANT +// +inline _variant_t& _variant_t::operator=(unsigned __int64 ui8Src) throw(_com_error){ + if (V_VT(this) != VT_UI8) { + // Clear the VARIANT and create a VT_UI8 + // + Clear(); + + V_VT(this) = VT_UI8; + } + + V_UI8(this) = ui8Src; + + return *this; +} + +////////////////////////////////////////////////////////////////////////////////////////// +// +// Comparison operations +// +////////////////////////////////////////////////////////////////////////////////////////// + +// Compare a _variant_t against a const VARIANT& for equality +// +inline bool _variant_t::operator==(const VARIANT& varSrc) const throw() +{ + return *this == &varSrc; +} + +// Compare a _variant_t against a const VARIANT* for equality +// +inline bool _variant_t::operator==(const VARIANT* pSrc) const throw() +{ + if (this == pSrc) { + return true; + } + + // + // Variants not equal if types don't match + // + if (V_VT(this) != V_VT(pSrc)) { + return false; + } + + // + // Check type specific values + // + switch (V_VT(this)) { + case VT_EMPTY: + case VT_NULL: + return true; + + case VT_I2: + return V_I2(this) == V_I2(pSrc); + + case VT_I4: + return V_I4(this) == V_I4(pSrc); + + case VT_R4: + return V_R4(this) == V_R4(pSrc); + + case VT_R8: + return V_R8(this) == V_R8(pSrc); + + case VT_CY: + return memcmp(&(V_CY(this)), &(V_CY(pSrc)), sizeof(CY)) == 0; + + case VT_DATE: + return V_DATE(this) == V_DATE(pSrc); + + case VT_BSTR: + return (::SysStringByteLen(V_BSTR(this)) == ::SysStringByteLen(V_BSTR(pSrc))) && + (memcmp(V_BSTR(this), V_BSTR(pSrc), ::SysStringByteLen(V_BSTR(this))) == 0); + + case VT_DISPATCH: + return V_DISPATCH(this) == V_DISPATCH(pSrc); + + case VT_ERROR: + return V_ERROR(this) == V_ERROR(pSrc); + + case VT_BOOL: + return V_BOOL(this) == V_BOOL(pSrc); + + case VT_UNKNOWN: + return V_UNKNOWN(this) == V_UNKNOWN(pSrc); + + case VT_DECIMAL: + return memcmp(&(V_DECIMAL(this)), &(V_DECIMAL(pSrc)), sizeof(DECIMAL)) == 0; + + case VT_UI1: + return V_UI1(this) == V_UI1(pSrc); + + case VT_I1: + return V_I1(this) == V_I1(pSrc); + + case VT_UI2: + return V_UI2(this) == V_UI2(pSrc); + + case VT_UI4: + return V_UI4(this) == V_UI4(pSrc); + + case VT_INT: + return V_INT(this) == V_INT(pSrc); + + case VT_UINT: + return V_UINT(this) == V_UINT(pSrc); + + case VT_I8: + return V_I8(this) == V_I8(pSrc); + + case VT_UI8: + return V_UI8(this) == V_UI8(pSrc); + + default: + _com_issue_error(E_INVALIDARG); + // fall through + } + + return false; +} + +// Compare a _variant_t against a const VARIANT& for in-equality +// +inline bool _variant_t::operator!=(const VARIANT& varSrc) const throw() +{ + return !(*this == &varSrc); +} + +// Compare a _variant_t against a const VARIANT* for in-equality +// +inline bool _variant_t::operator!=(const VARIANT* pSrc) const throw() +{ + return !(*this == pSrc); +} + +////////////////////////////////////////////////////////////////////////////////////////// +// +// Low-level operations +// +////////////////////////////////////////////////////////////////////////////////////////// + +// Clear the _variant_t +// +inline void _variant_t::Clear() throw(_com_error) +{ + _com_util::CheckError(::VariantClear(this)); +} + +inline void _variant_t::Attach(VARIANT& varSrc) throw(_com_error) +{ + // + // Free up previous VARIANT + // + Clear(); + + // + // Give control of data to _variant_t + // + memcpy(this, &varSrc, sizeof(varSrc)); + V_VT(&varSrc) = VT_EMPTY; +} + +inline VARIANT _variant_t::Detach() throw(_com_error) +{ + VARIANT varResult = *this; + V_VT(this) = VT_EMPTY; + + return varResult; +} + +inline VARIANT& _variant_t::GetVARIANT() throw() +{ + return *(VARIANT*) this; +} + +inline VARIANT* _variant_t::GetAddress() throw(_com_error) +{ + Clear(); + return (VARIANT*) this; +} + +// Change the type and contents of this _variant_t to the type vartype and +// contents of pSrc +// +inline void _variant_t::ChangeType(VARTYPE vartype, const _variant_t* pSrc) throw(_com_error) +{ + // + // If pDest is NULL, convert type in place + // + if (pSrc == NULL) { + pSrc = this; + } + + if ((this != pSrc) || (vartype != V_VT(this))) { + _com_util::CheckError(::VariantChangeType(static_cast(this), + const_cast(static_cast(pSrc)), + 0, vartype)); + } +} + +inline void _variant_t::SetString(const char* pSrc) throw(_com_error) +{ + // + // Free up previous VARIANT + // + Clear(); + + V_VT(this) = VT_BSTR; + V_BSTR(this) = _com_util::ConvertStringToBSTR(pSrc); +} + +////////////////////////////////////////////////////////////////////////////////////////// +// +// Destructor +// +////////////////////////////////////////////////////////////////////////////////////////// + +inline _variant_t::~_variant_t() throw(_com_error) +{ + _com_util::CheckError(::VariantClear(this)); +} + +////////////////////////////////////////////////////////////////////////////////////////// +// +// Mutually-dependent definitions +// +////////////////////////////////////////////////////////////////////////////////////////// + +// Construct a _bstr_t from a const _variant_t& +// +inline _bstr_t::_bstr_t(const _variant_t &var) throw(_com_error) + : m_Data(NULL) +{ + if (V_VT(&var) == VT_BSTR) { + *this = V_BSTR(&var); + return; + } + + _variant_t varDest; + + varDest.ChangeType(VT_BSTR, &var); + + *this = V_BSTR(&varDest); +} + +// Assign a const _variant_t& to a _bstr_t +// +inline _bstr_t& _bstr_t::operator=(const _variant_t &var) throw(_com_error) +{ + if (V_VT(&var) == VT_BSTR) { + *this = V_BSTR(&var); + return *this; + } + + _variant_t varDest; + + varDest.ChangeType(VT_BSTR, &var); + + *this = V_BSTR(&varDest); + + return *this; +} + +extern _variant_t vtMissing; + +#ifndef _USE_RAW +#define bstr_t _bstr_t +#define variant_t _variant_t +#endif + +#pragma pop_macro("new") + +#pragma warning(pop) + +#endif // _INC_COMUTIL diff --git a/mod/maxgui.mod/win32maxguiex.mod/doc/intro.bbdoc b/mod/maxgui.mod/win32maxguiex.mod/doc/intro.bbdoc new file mode 100644 index 0000000..c447ec5 --- /dev/null +++ b/mod/maxgui.mod/win32maxguiex.mod/doc/intro.bbdoc @@ -0,0 +1,21 @@ +This is the new unicode Windows driver for #MaxGUI that is designed to take advantage of some of the new GUI features available in Windows XP and Vista. + +@NOTE: If you would like to use this unicode driver on the older ANSI platforms (e.g. Windows 9X), then you must also import a unicode application layer. For example... + +{{ +?Win32 +Import "-lunicows" +? +Import MaxGUI.Drivers +? +}} + +By doing this, your program will be linked with libunicows. Although Windows 2000/XP/Vista users should not notice anything +different at run-time, Windows 9X users will require MSLU in order to run your program. This may be distributed with the EXE as a separate DLL or it can be installed +as a system-wide package onto the end-user's computer. + +See the following web-pages for more information: + +MSLU Announcement + +MSLU Software Development Kit Redistributable \ No newline at end of file diff --git a/mod/maxgui.mod/win32maxguiex.mod/mshtmhst.h b/mod/maxgui.mod/win32maxguiex.mod/mshtmhst.h new file mode 100644 index 0000000..9edb7e1 --- /dev/null +++ b/mod/maxgui.mod/win32maxguiex.mod/mshtmhst.h @@ -0,0 +1,1409 @@ + +#pragma warning( disable: 4049 ) /* more than 64k source lines */ + +/* this ALWAYS GENERATED file contains the definitions for the interfaces */ + + + /* File created by MIDL compiler version 6.00.0347 */ +/* Compiler settings for mshtmhst.idl: + Oicf, W1, Zp8, env=Win32 (32b run) + protocol : dce , ms_ext, c_ext + error checks: allocation ref bounds_check enum stub_data + VC __declspec() decoration level: + __declspec(uuid()), __declspec(selectany), __declspec(novtable) + DECLSPEC_UUID(), MIDL_INTERFACE() +*/ +//@@MIDL_FILE_HEADING( ) + + +/* verify that the version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCNDR_H_VERSION__ +#define __REQUIRED_RPCNDR_H_VERSION__ 440 +#endif + +#include "rpc.h" +#include "rpcndr.h" + +#ifndef __RPCNDR_H_VERSION__ +#error this stub requires an updated version of +#endif // __RPCNDR_H_VERSION__ + +#ifndef COM_NO_WINDOWS_H +#include "windows.h" +#include "ole2.h" +#endif /*COM_NO_WINDOWS_H*/ + +#ifndef __mshtmhst_h__ +#define __mshtmhst_h__ + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +/* Forward Declarations */ + +#ifndef __IHostDialogHelper_FWD_DEFINED__ +#define __IHostDialogHelper_FWD_DEFINED__ +typedef interface IHostDialogHelper IHostDialogHelper; +#endif /* __IHostDialogHelper_FWD_DEFINED__ */ + + +#ifndef __HostDialogHelper_FWD_DEFINED__ +#define __HostDialogHelper_FWD_DEFINED__ + +#ifdef __cplusplus +typedef class HostDialogHelper HostDialogHelper; +#else +typedef struct HostDialogHelper HostDialogHelper; +#endif /* __cplusplus */ + +#endif /* __HostDialogHelper_FWD_DEFINED__ */ + + +#ifndef __IDocHostUIHandler_FWD_DEFINED__ +#define __IDocHostUIHandler_FWD_DEFINED__ +typedef interface IDocHostUIHandler IDocHostUIHandler; +#endif /* __IDocHostUIHandler_FWD_DEFINED__ */ + + +#ifndef __IDocHostUIHandler2_FWD_DEFINED__ +#define __IDocHostUIHandler2_FWD_DEFINED__ +typedef interface IDocHostUIHandler2 IDocHostUIHandler2; +#endif /* __IDocHostUIHandler2_FWD_DEFINED__ */ + + +#ifndef __ICustomDoc_FWD_DEFINED__ +#define __ICustomDoc_FWD_DEFINED__ +typedef interface ICustomDoc ICustomDoc; +#endif /* __ICustomDoc_FWD_DEFINED__ */ + + +#ifndef __IDocHostShowUI_FWD_DEFINED__ +#define __IDocHostShowUI_FWD_DEFINED__ +typedef interface IDocHostShowUI IDocHostShowUI; +#endif /* __IDocHostShowUI_FWD_DEFINED__ */ + + +#ifndef __IClassFactoryEx_FWD_DEFINED__ +#define __IClassFactoryEx_FWD_DEFINED__ +typedef interface IClassFactoryEx IClassFactoryEx; +#endif /* __IClassFactoryEx_FWD_DEFINED__ */ + + +/* header files for imported files */ +#include "ocidl.h" +#include "docobj.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +void * __RPC_USER MIDL_user_allocate(size_t); +void __RPC_USER MIDL_user_free( void * ); + +/* interface __MIDL_itf_mshtmhst_0000 */ +/* [local] */ + +//=--------------------------------------------------------------------------= +// mshtmhst.h +//=--------------------------------------------------------------------------= +// (C) Copyright 1995-1998 Microsoft Corporation. All Rights Reserved. +// +// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO +// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A +// PARTICULAR PURPOSE. +//=--------------------------------------------------------------------------= + +#pragma comment(lib,"uuid.lib") + +//-------------------------------------------------------------------------- +// MSTHML Advanced Host Interfaces. + +#ifndef MSHTMHST_H +#define MSHTMHST_H +#define CONTEXT_MENU_DEFAULT 0 +#define CONTEXT_MENU_IMAGE 1 +#define CONTEXT_MENU_CONTROL 2 +#define CONTEXT_MENU_TABLE 3 +// in browse mode +#define CONTEXT_MENU_TEXTSELECT 4 +#define CONTEXT_MENU_ANCHOR 5 +#define CONTEXT_MENU_UNKNOWN 6 +//;begin_internal +// These 2 are mapped to IMAGE for the public +#define CONTEXT_MENU_IMGDYNSRC 7 +#define CONTEXT_MENU_IMGART 8 +#define CONTEXT_MENU_DEBUG 9 +//;end_internal +#define CONTEXT_MENU_VSCROLL 10 +#define CONTEXT_MENU_HSCROLL 11 +#define MENUEXT_SHOWDIALOG 0x1 +#define DOCHOSTUIFLAG_BROWSER DOCHOSTUIFLAG_DISABLE_HELP_MENU | DOCHOSTUIFLAG_DISABLE_SCRIPT_INACTIVE +#define HTMLDLG_NOUI 0x10 +#define HTMLDLG_MODAL 0x20 +#define HTMLDLG_MODELESS 0x40 +#define HTMLDLG_PRINT_TEMPLATE 0x80 +#define HTMLDLG_VERIFY 0x100 +#define PRINT_DONTBOTHERUSER 0x01 +#define PRINT_WAITFORCOMPLETION 0x02 +EXTERN_C const GUID CGID_MSHTML; +#define CMDSETID_Forms3 CGID_MSHTML +#define SZ_HTML_CLIENTSITE_OBJECTPARAM L"{d4db6850-5385-11d0-89e9-00a0c90a90ac}" +#ifndef __IHTMLWindow2_FWD_DEFINED__ +#define __IHTMLWindow2_FWD_DEFINED__ +typedef interface IHTMLWindow2 IHTMLWindow2; +#endif +typedef HRESULT STDAPICALLTYPE SHOWHTMLDIALOGFN (HWND hwndParent, IMoniker *pmk, VARIANT *pvarArgIn, WCHAR* pchOptions, VARIANT *pvArgOut); +typedef HRESULT STDAPICALLTYPE SHOWHTMLDIALOGEXFN (HWND hwndParent, IMoniker *pmk, DWORD dwDialogFlags, VARIANT *pvarArgIn, WCHAR* pchOptions, VARIANT *pvArgOut); +typedef HRESULT STDAPICALLTYPE SHOWMODELESSHTMLDIALOGFN (HWND hwndParent, IMoniker *pmk, VARIANT *pvarArgIn, VARIANT* pvarOptions, IHTMLWindow2 ** ppWindow); +//;begin_internal +STDAPI ShowHTMLDialog( + HWND hwndParent, + IMoniker * pMk, + VARIANT * pvarArgIn, + WCHAR * pchOptions, + VARIANT * pvarArgOut + ); +STDAPI ShowHTMLDialogEx( + HWND hwndParent, + IMoniker * pMk, + DWORD dwDialogFlags, + VARIANT * pvarArgIn, + WCHAR * pchOptions, + VARIANT * pvarArgOut + ); +STDAPI ShowModelessHTMLDialog( + HWND hwndParent, + IMoniker * pMk, + VARIANT * pvarArgIn, + VARIANT * pvarOptions, + IHTMLWindow2 ** ppWindow); +//;end_internal +//;begin_internal +STDAPI RunHTMLApplication( + HINSTANCE hinst, + HINSTANCE hPrevInst, + LPSTR szCmdLine, + int nCmdShow + ); +//;end_internal +//;begin_internal +STDAPI CreateHTMLPropertyPage( + IMoniker * pmk, + IPropertyPage ** ppPP + ); +//;end_internal + + +extern RPC_IF_HANDLE __MIDL_itf_mshtmhst_0000_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_mshtmhst_0000_v0_0_s_ifspec; + +#ifndef __IHostDialogHelper_INTERFACE_DEFINED__ +#define __IHostDialogHelper_INTERFACE_DEFINED__ + +/* interface IHostDialogHelper */ +/* [local][unique][uuid][object] */ + + +EXTERN_C const IID IID_IHostDialogHelper; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("53DEC138-A51E-11d2-861E-00C04FA35C89") + IHostDialogHelper : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE ShowHTMLDialog( + HWND hwndParent, + IMoniker *pMk, + VARIANT *pvarArgIn, + WCHAR *pchOptions, + VARIANT *pvarArgOut, + IUnknown *punkHost) = 0; + + }; + +#else /* C style interface */ + + typedef struct IHostDialogHelperVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IHostDialogHelper * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IHostDialogHelper * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IHostDialogHelper * This); + + HRESULT ( STDMETHODCALLTYPE *ShowHTMLDialog )( + IHostDialogHelper * This, + HWND hwndParent, + IMoniker *pMk, + VARIANT *pvarArgIn, + WCHAR *pchOptions, + VARIANT *pvarArgOut, + IUnknown *punkHost); + + END_INTERFACE + } IHostDialogHelperVtbl; + + interface IHostDialogHelper + { + CONST_VTBL struct IHostDialogHelperVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IHostDialogHelper_QueryInterface(This,riid,ppvObject) \ + (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) + +#define IHostDialogHelper_AddRef(This) \ + (This)->lpVtbl -> AddRef(This) + +#define IHostDialogHelper_Release(This) \ + (This)->lpVtbl -> Release(This) + + +#define IHostDialogHelper_ShowHTMLDialog(This,hwndParent,pMk,pvarArgIn,pchOptions,pvarArgOut,punkHost) \ + (This)->lpVtbl -> ShowHTMLDialog(This,hwndParent,pMk,pvarArgIn,pchOptions,pvarArgOut,punkHost) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + +HRESULT STDMETHODCALLTYPE IHostDialogHelper_ShowHTMLDialog_Proxy( + IHostDialogHelper * This, + HWND hwndParent, + IMoniker *pMk, + VARIANT *pvarArgIn, + WCHAR *pchOptions, + VARIANT *pvarArgOut, + IUnknown *punkHost); + + +void __RPC_STUB IHostDialogHelper_ShowHTMLDialog_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + + +#endif /* __IHostDialogHelper_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_mshtmhst_0267 */ +/* [local] */ + +EXTERN_C const GUID CLSID_HostDialogHelper; +//;begin_internal +typedef +enum tagDOCHOSTUITYPE + { DOCHOSTUITYPE_BROWSE = 0, + DOCHOSTUITYPE_AUTHOR = 1 + } DOCHOSTUITYPE; + +//;end_internal +typedef +enum tagDOCHOSTUIDBLCLK + { DOCHOSTUIDBLCLK_DEFAULT = 0, + DOCHOSTUIDBLCLK_SHOWPROPERTIES = 1, + DOCHOSTUIDBLCLK_SHOWCODE = 2 + } DOCHOSTUIDBLCLK; + +typedef +enum tagDOCHOSTUIFLAG + { DOCHOSTUIFLAG_DIALOG = 0x1, + DOCHOSTUIFLAG_DISABLE_HELP_MENU = 0x2, + DOCHOSTUIFLAG_NO3DBORDER = 0x4, + DOCHOSTUIFLAG_SCROLL_NO = 0x8, + DOCHOSTUIFLAG_DISABLE_SCRIPT_INACTIVE = 0x10, + DOCHOSTUIFLAG_OPENNEWWIN = 0x20, + DOCHOSTUIFLAG_DISABLE_OFFSCREEN = 0x40, + DOCHOSTUIFLAG_FLAT_SCROLLBAR = 0x80, + DOCHOSTUIFLAG_DIV_BLOCKDEFAULT = 0x100, + DOCHOSTUIFLAG_ACTIVATE_CLIENTHIT_ONLY = 0x200, + DOCHOSTUIFLAG_OVERRIDEBEHAVIORFACTORY = 0x400, + DOCHOSTUIFLAG_CODEPAGELINKEDFONTS = 0x800, + DOCHOSTUIFLAG_URL_ENCODING_DISABLE_UTF8 = 0x1000, + DOCHOSTUIFLAG_URL_ENCODING_ENABLE_UTF8 = 0x2000, + DOCHOSTUIFLAG_ENABLE_FORMS_AUTOCOMPLETE = 0x4000, + DOCHOSTUIFLAG_ENABLE_INPLACE_NAVIGATION = 0x10000, + DOCHOSTUIFLAG_IME_ENABLE_RECONVERSION = 0x20000, + DOCHOSTUIFLAG_THEME = 0x40000, + DOCHOSTUIFLAG_NOTHEME = 0x80000, + DOCHOSTUIFLAG_NOPICS = 0x100000, + DOCHOSTUIFLAG_NO3DOUTERBORDER = 0x200000, + DOCHOSTUIFLAG_DISABLE_EDIT_NS_FIXUP = 0x400000 + } DOCHOSTUIFLAG; + +#define DOCHOSTUIATOM_ENABLE_HIRES _T("TridentEnableHiRes") + + +extern RPC_IF_HANDLE __MIDL_itf_mshtmhst_0267_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_mshtmhst_0267_v0_0_s_ifspec; + +#ifndef __IDocHostUIHandler_INTERFACE_DEFINED__ +#define __IDocHostUIHandler_INTERFACE_DEFINED__ + +/* interface IDocHostUIHandler */ +/* [local][unique][uuid][object] */ + +typedef struct _DOCHOSTUIINFO + { + ULONG cbSize; + DWORD dwFlags; + DWORD dwDoubleClick; + OLECHAR *pchHostCss; + OLECHAR *pchHostNS; + } DOCHOSTUIINFO; + + +EXTERN_C const IID IID_IDocHostUIHandler; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("bd3f23c0-d43e-11cf-893b-00aa00bdce1a") + IDocHostUIHandler : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE ShowContextMenu( + /* [in] */ DWORD dwID, + /* [in] */ POINT *ppt, + /* [in] */ IUnknown *pcmdtReserved, + /* [in] */ IDispatch *pdispReserved) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetHostInfo( + /* [out][in] */ DOCHOSTUIINFO *pInfo) = 0; + + virtual HRESULT STDMETHODCALLTYPE ShowUI( + /* [in] */ DWORD dwID, + /* [in] */ IOleInPlaceActiveObject *pActiveObject, + /* [in] */ IOleCommandTarget *pCommandTarget, + /* [in] */ IOleInPlaceFrame *pFrame, + /* [in] */ IOleInPlaceUIWindow *pDoc) = 0; + + virtual HRESULT STDMETHODCALLTYPE HideUI( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE UpdateUI( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE EnableModeless( + /* [in] */ BOOL fEnable) = 0; + + virtual HRESULT STDMETHODCALLTYPE OnDocWindowActivate( + /* [in] */ BOOL fActivate) = 0; + + virtual HRESULT STDMETHODCALLTYPE OnFrameWindowActivate( + /* [in] */ BOOL fActivate) = 0; + + virtual HRESULT STDMETHODCALLTYPE ResizeBorder( + /* [in] */ LPCRECT prcBorder, + /* [in] */ IOleInPlaceUIWindow *pUIWindow, + /* [in] */ BOOL fRameWindow) = 0; + + virtual HRESULT STDMETHODCALLTYPE TranslateAccelerator( + /* [in] */ LPMSG lpMsg, + /* [in] */ const GUID *pguidCmdGroup, + /* [in] */ DWORD nCmdID) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetOptionKeyPath( + /* [out] */ LPOLESTR *pchKey, + /* [in] */ DWORD dw) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetDropTarget( + /* [in] */ IDropTarget *pDropTarget, + /* [out] */ IDropTarget **ppDropTarget) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetExternal( + /* [out] */ IDispatch **ppDispatch) = 0; + + virtual HRESULT STDMETHODCALLTYPE TranslateUrl( + /* [in] */ DWORD dwTranslate, + /* [in] */ OLECHAR *pchURLIn, + /* [out] */ OLECHAR **ppchURLOut) = 0; + + virtual HRESULT STDMETHODCALLTYPE FilterDataObject( + /* [in] */ IDataObject *pDO, + /* [out] */ IDataObject **ppDORet) = 0; + + }; + +#else /* C style interface */ + + typedef struct IDocHostUIHandlerVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDocHostUIHandler * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDocHostUIHandler * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDocHostUIHandler * This); + + HRESULT ( STDMETHODCALLTYPE *ShowContextMenu )( + IDocHostUIHandler * This, + /* [in] */ DWORD dwID, + /* [in] */ POINT *ppt, + /* [in] */ IUnknown *pcmdtReserved, + /* [in] */ IDispatch *pdispReserved); + + HRESULT ( STDMETHODCALLTYPE *GetHostInfo )( + IDocHostUIHandler * This, + /* [out][in] */ DOCHOSTUIINFO *pInfo); + + HRESULT ( STDMETHODCALLTYPE *ShowUI )( + IDocHostUIHandler * This, + /* [in] */ DWORD dwID, + /* [in] */ IOleInPlaceActiveObject *pActiveObject, + /* [in] */ IOleCommandTarget *pCommandTarget, + /* [in] */ IOleInPlaceFrame *pFrame, + /* [in] */ IOleInPlaceUIWindow *pDoc); + + HRESULT ( STDMETHODCALLTYPE *HideUI )( + IDocHostUIHandler * This); + + HRESULT ( STDMETHODCALLTYPE *UpdateUI )( + IDocHostUIHandler * This); + + HRESULT ( STDMETHODCALLTYPE *EnableModeless )( + IDocHostUIHandler * This, + /* [in] */ BOOL fEnable); + + HRESULT ( STDMETHODCALLTYPE *OnDocWindowActivate )( + IDocHostUIHandler * This, + /* [in] */ BOOL fActivate); + + HRESULT ( STDMETHODCALLTYPE *OnFrameWindowActivate )( + IDocHostUIHandler * This, + /* [in] */ BOOL fActivate); + + HRESULT ( STDMETHODCALLTYPE *ResizeBorder )( + IDocHostUIHandler * This, + /* [in] */ LPCRECT prcBorder, + /* [in] */ IOleInPlaceUIWindow *pUIWindow, + /* [in] */ BOOL fRameWindow); + + HRESULT ( STDMETHODCALLTYPE *TranslateAccelerator )( + IDocHostUIHandler * This, + /* [in] */ LPMSG lpMsg, + /* [in] */ const GUID *pguidCmdGroup, + /* [in] */ DWORD nCmdID); + + HRESULT ( STDMETHODCALLTYPE *GetOptionKeyPath )( + IDocHostUIHandler * This, + /* [out] */ LPOLESTR *pchKey, + /* [in] */ DWORD dw); + + HRESULT ( STDMETHODCALLTYPE *GetDropTarget )( + IDocHostUIHandler * This, + /* [in] */ IDropTarget *pDropTarget, + /* [out] */ IDropTarget **ppDropTarget); + + HRESULT ( STDMETHODCALLTYPE *GetExternal )( + IDocHostUIHandler * This, + /* [out] */ IDispatch **ppDispatch); + + HRESULT ( STDMETHODCALLTYPE *TranslateUrl )( + IDocHostUIHandler * This, + /* [in] */ DWORD dwTranslate, + /* [in] */ OLECHAR *pchURLIn, + /* [out] */ OLECHAR **ppchURLOut); + + HRESULT ( STDMETHODCALLTYPE *FilterDataObject )( + IDocHostUIHandler * This, + /* [in] */ IDataObject *pDO, + /* [out] */ IDataObject **ppDORet); + + END_INTERFACE + } IDocHostUIHandlerVtbl; + + interface IDocHostUIHandler + { + CONST_VTBL struct IDocHostUIHandlerVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDocHostUIHandler_QueryInterface(This,riid,ppvObject) \ + (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) + +#define IDocHostUIHandler_AddRef(This) \ + (This)->lpVtbl -> AddRef(This) + +#define IDocHostUIHandler_Release(This) \ + (This)->lpVtbl -> Release(This) + + +#define IDocHostUIHandler_ShowContextMenu(This,dwID,ppt,pcmdtReserved,pdispReserved) \ + (This)->lpVtbl -> ShowContextMenu(This,dwID,ppt,pcmdtReserved,pdispReserved) + +#define IDocHostUIHandler_GetHostInfo(This,pInfo) \ + (This)->lpVtbl -> GetHostInfo(This,pInfo) + +#define IDocHostUIHandler_ShowUI(This,dwID,pActiveObject,pCommandTarget,pFrame,pDoc) \ + (This)->lpVtbl -> ShowUI(This,dwID,pActiveObject,pCommandTarget,pFrame,pDoc) + +#define IDocHostUIHandler_HideUI(This) \ + (This)->lpVtbl -> HideUI(This) + +#define IDocHostUIHandler_UpdateUI(This) \ + (This)->lpVtbl -> UpdateUI(This) + +#define IDocHostUIHandler_EnableModeless(This,fEnable) \ + (This)->lpVtbl -> EnableModeless(This,fEnable) + +#define IDocHostUIHandler_OnDocWindowActivate(This,fActivate) \ + (This)->lpVtbl -> OnDocWindowActivate(This,fActivate) + +#define IDocHostUIHandler_OnFrameWindowActivate(This,fActivate) \ + (This)->lpVtbl -> OnFrameWindowActivate(This,fActivate) + +#define IDocHostUIHandler_ResizeBorder(This,prcBorder,pUIWindow,fRameWindow) \ + (This)->lpVtbl -> ResizeBorder(This,prcBorder,pUIWindow,fRameWindow) + +#define IDocHostUIHandler_TranslateAccelerator(This,lpMsg,pguidCmdGroup,nCmdID) \ + (This)->lpVtbl -> TranslateAccelerator(This,lpMsg,pguidCmdGroup,nCmdID) + +#define IDocHostUIHandler_GetOptionKeyPath(This,pchKey,dw) \ + (This)->lpVtbl -> GetOptionKeyPath(This,pchKey,dw) + +#define IDocHostUIHandler_GetDropTarget(This,pDropTarget,ppDropTarget) \ + (This)->lpVtbl -> GetDropTarget(This,pDropTarget,ppDropTarget) + +#define IDocHostUIHandler_GetExternal(This,ppDispatch) \ + (This)->lpVtbl -> GetExternal(This,ppDispatch) + +#define IDocHostUIHandler_TranslateUrl(This,dwTranslate,pchURLIn,ppchURLOut) \ + (This)->lpVtbl -> TranslateUrl(This,dwTranslate,pchURLIn,ppchURLOut) + +#define IDocHostUIHandler_FilterDataObject(This,pDO,ppDORet) \ + (This)->lpVtbl -> FilterDataObject(This,pDO,ppDORet) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + +HRESULT STDMETHODCALLTYPE IDocHostUIHandler_ShowContextMenu_Proxy( + IDocHostUIHandler * This, + /* [in] */ DWORD dwID, + /* [in] */ POINT *ppt, + /* [in] */ IUnknown *pcmdtReserved, + /* [in] */ IDispatch *pdispReserved); + + +void __RPC_STUB IDocHostUIHandler_ShowContextMenu_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IDocHostUIHandler_GetHostInfo_Proxy( + IDocHostUIHandler * This, + /* [out][in] */ DOCHOSTUIINFO *pInfo); + + +void __RPC_STUB IDocHostUIHandler_GetHostInfo_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IDocHostUIHandler_ShowUI_Proxy( + IDocHostUIHandler * This, + /* [in] */ DWORD dwID, + /* [in] */ IOleInPlaceActiveObject *pActiveObject, + /* [in] */ IOleCommandTarget *pCommandTarget, + /* [in] */ IOleInPlaceFrame *pFrame, + /* [in] */ IOleInPlaceUIWindow *pDoc); + + +void __RPC_STUB IDocHostUIHandler_ShowUI_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IDocHostUIHandler_HideUI_Proxy( + IDocHostUIHandler * This); + + +void __RPC_STUB IDocHostUIHandler_HideUI_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IDocHostUIHandler_UpdateUI_Proxy( + IDocHostUIHandler * This); + + +void __RPC_STUB IDocHostUIHandler_UpdateUI_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IDocHostUIHandler_EnableModeless_Proxy( + IDocHostUIHandler * This, + /* [in] */ BOOL fEnable); + + +void __RPC_STUB IDocHostUIHandler_EnableModeless_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IDocHostUIHandler_OnDocWindowActivate_Proxy( + IDocHostUIHandler * This, + /* [in] */ BOOL fActivate); + + +void __RPC_STUB IDocHostUIHandler_OnDocWindowActivate_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IDocHostUIHandler_OnFrameWindowActivate_Proxy( + IDocHostUIHandler * This, + /* [in] */ BOOL fActivate); + + +void __RPC_STUB IDocHostUIHandler_OnFrameWindowActivate_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IDocHostUIHandler_ResizeBorder_Proxy( + IDocHostUIHandler * This, + /* [in] */ LPCRECT prcBorder, + /* [in] */ IOleInPlaceUIWindow *pUIWindow, + /* [in] */ BOOL fRameWindow); + + +void __RPC_STUB IDocHostUIHandler_ResizeBorder_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IDocHostUIHandler_TranslateAccelerator_Proxy( + IDocHostUIHandler * This, + /* [in] */ LPMSG lpMsg, + /* [in] */ const GUID *pguidCmdGroup, + /* [in] */ DWORD nCmdID); + + +void __RPC_STUB IDocHostUIHandler_TranslateAccelerator_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IDocHostUIHandler_GetOptionKeyPath_Proxy( + IDocHostUIHandler * This, + /* [out] */ LPOLESTR *pchKey, + /* [in] */ DWORD dw); + + +void __RPC_STUB IDocHostUIHandler_GetOptionKeyPath_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IDocHostUIHandler_GetDropTarget_Proxy( + IDocHostUIHandler * This, + /* [in] */ IDropTarget *pDropTarget, + /* [out] */ IDropTarget **ppDropTarget); + + +void __RPC_STUB IDocHostUIHandler_GetDropTarget_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IDocHostUIHandler_GetExternal_Proxy( + IDocHostUIHandler * This, + /* [out] */ IDispatch **ppDispatch); + + +void __RPC_STUB IDocHostUIHandler_GetExternal_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IDocHostUIHandler_TranslateUrl_Proxy( + IDocHostUIHandler * This, + /* [in] */ DWORD dwTranslate, + /* [in] */ OLECHAR *pchURLIn, + /* [out] */ OLECHAR **ppchURLOut); + + +void __RPC_STUB IDocHostUIHandler_TranslateUrl_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IDocHostUIHandler_FilterDataObject_Proxy( + IDocHostUIHandler * This, + /* [in] */ IDataObject *pDO, + /* [out] */ IDataObject **ppDORet); + + +void __RPC_STUB IDocHostUIHandler_FilterDataObject_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + + +#endif /* __IDocHostUIHandler_INTERFACE_DEFINED__ */ + + +#ifndef __IDocHostUIHandler2_INTERFACE_DEFINED__ +#define __IDocHostUIHandler2_INTERFACE_DEFINED__ + +/* interface IDocHostUIHandler2 */ +/* [local][unique][uuid][object] */ + + +EXTERN_C const IID IID_IDocHostUIHandler2; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("3050f6d0-98b5-11cf-bb82-00aa00bdce0b") + IDocHostUIHandler2 : public IDocHostUIHandler + { + public: + virtual HRESULT STDMETHODCALLTYPE GetOverrideKeyPath( + /* [out] */ LPOLESTR *pchKey, + /* [in] */ DWORD dw) = 0; + + }; + +#else /* C style interface */ + + typedef struct IDocHostUIHandler2Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDocHostUIHandler2 * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDocHostUIHandler2 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDocHostUIHandler2 * This); + + HRESULT ( STDMETHODCALLTYPE *ShowContextMenu )( + IDocHostUIHandler2 * This, + /* [in] */ DWORD dwID, + /* [in] */ POINT *ppt, + /* [in] */ IUnknown *pcmdtReserved, + /* [in] */ IDispatch *pdispReserved); + + HRESULT ( STDMETHODCALLTYPE *GetHostInfo )( + IDocHostUIHandler2 * This, + /* [out][in] */ DOCHOSTUIINFO *pInfo); + + HRESULT ( STDMETHODCALLTYPE *ShowUI )( + IDocHostUIHandler2 * This, + /* [in] */ DWORD dwID, + /* [in] */ IOleInPlaceActiveObject *pActiveObject, + /* [in] */ IOleCommandTarget *pCommandTarget, + /* [in] */ IOleInPlaceFrame *pFrame, + /* [in] */ IOleInPlaceUIWindow *pDoc); + + HRESULT ( STDMETHODCALLTYPE *HideUI )( + IDocHostUIHandler2 * This); + + HRESULT ( STDMETHODCALLTYPE *UpdateUI )( + IDocHostUIHandler2 * This); + + HRESULT ( STDMETHODCALLTYPE *EnableModeless )( + IDocHostUIHandler2 * This, + /* [in] */ BOOL fEnable); + + HRESULT ( STDMETHODCALLTYPE *OnDocWindowActivate )( + IDocHostUIHandler2 * This, + /* [in] */ BOOL fActivate); + + HRESULT ( STDMETHODCALLTYPE *OnFrameWindowActivate )( + IDocHostUIHandler2 * This, + /* [in] */ BOOL fActivate); + + HRESULT ( STDMETHODCALLTYPE *ResizeBorder )( + IDocHostUIHandler2 * This, + /* [in] */ LPCRECT prcBorder, + /* [in] */ IOleInPlaceUIWindow *pUIWindow, + /* [in] */ BOOL fRameWindow); + + HRESULT ( STDMETHODCALLTYPE *TranslateAccelerator )( + IDocHostUIHandler2 * This, + /* [in] */ LPMSG lpMsg, + /* [in] */ const GUID *pguidCmdGroup, + /* [in] */ DWORD nCmdID); + + HRESULT ( STDMETHODCALLTYPE *GetOptionKeyPath )( + IDocHostUIHandler2 * This, + /* [out] */ LPOLESTR *pchKey, + /* [in] */ DWORD dw); + + HRESULT ( STDMETHODCALLTYPE *GetDropTarget )( + IDocHostUIHandler2 * This, + /* [in] */ IDropTarget *pDropTarget, + /* [out] */ IDropTarget **ppDropTarget); + + HRESULT ( STDMETHODCALLTYPE *GetExternal )( + IDocHostUIHandler2 * This, + /* [out] */ IDispatch **ppDispatch); + + HRESULT ( STDMETHODCALLTYPE *TranslateUrl )( + IDocHostUIHandler2 * This, + /* [in] */ DWORD dwTranslate, + /* [in] */ OLECHAR *pchURLIn, + /* [out] */ OLECHAR **ppchURLOut); + + HRESULT ( STDMETHODCALLTYPE *FilterDataObject )( + IDocHostUIHandler2 * This, + /* [in] */ IDataObject *pDO, + /* [out] */ IDataObject **ppDORet); + + HRESULT ( STDMETHODCALLTYPE *GetOverrideKeyPath )( + IDocHostUIHandler2 * This, + /* [out] */ LPOLESTR *pchKey, + /* [in] */ DWORD dw); + + END_INTERFACE + } IDocHostUIHandler2Vtbl; + + interface IDocHostUIHandler2 + { + CONST_VTBL struct IDocHostUIHandler2Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDocHostUIHandler2_QueryInterface(This,riid,ppvObject) \ + (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) + +#define IDocHostUIHandler2_AddRef(This) \ + (This)->lpVtbl -> AddRef(This) + +#define IDocHostUIHandler2_Release(This) \ + (This)->lpVtbl -> Release(This) + + +#define IDocHostUIHandler2_ShowContextMenu(This,dwID,ppt,pcmdtReserved,pdispReserved) \ + (This)->lpVtbl -> ShowContextMenu(This,dwID,ppt,pcmdtReserved,pdispReserved) + +#define IDocHostUIHandler2_GetHostInfo(This,pInfo) \ + (This)->lpVtbl -> GetHostInfo(This,pInfo) + +#define IDocHostUIHandler2_ShowUI(This,dwID,pActiveObject,pCommandTarget,pFrame,pDoc) \ + (This)->lpVtbl -> ShowUI(This,dwID,pActiveObject,pCommandTarget,pFrame,pDoc) + +#define IDocHostUIHandler2_HideUI(This) \ + (This)->lpVtbl -> HideUI(This) + +#define IDocHostUIHandler2_UpdateUI(This) \ + (This)->lpVtbl -> UpdateUI(This) + +#define IDocHostUIHandler2_EnableModeless(This,fEnable) \ + (This)->lpVtbl -> EnableModeless(This,fEnable) + +#define IDocHostUIHandler2_OnDocWindowActivate(This,fActivate) \ + (This)->lpVtbl -> OnDocWindowActivate(This,fActivate) + +#define IDocHostUIHandler2_OnFrameWindowActivate(This,fActivate) \ + (This)->lpVtbl -> OnFrameWindowActivate(This,fActivate) + +#define IDocHostUIHandler2_ResizeBorder(This,prcBorder,pUIWindow,fRameWindow) \ + (This)->lpVtbl -> ResizeBorder(This,prcBorder,pUIWindow,fRameWindow) + +#define IDocHostUIHandler2_TranslateAccelerator(This,lpMsg,pguidCmdGroup,nCmdID) \ + (This)->lpVtbl -> TranslateAccelerator(This,lpMsg,pguidCmdGroup,nCmdID) + +#define IDocHostUIHandler2_GetOptionKeyPath(This,pchKey,dw) \ + (This)->lpVtbl -> GetOptionKeyPath(This,pchKey,dw) + +#define IDocHostUIHandler2_GetDropTarget(This,pDropTarget,ppDropTarget) \ + (This)->lpVtbl -> GetDropTarget(This,pDropTarget,ppDropTarget) + +#define IDocHostUIHandler2_GetExternal(This,ppDispatch) \ + (This)->lpVtbl -> GetExternal(This,ppDispatch) + +#define IDocHostUIHandler2_TranslateUrl(This,dwTranslate,pchURLIn,ppchURLOut) \ + (This)->lpVtbl -> TranslateUrl(This,dwTranslate,pchURLIn,ppchURLOut) + +#define IDocHostUIHandler2_FilterDataObject(This,pDO,ppDORet) \ + (This)->lpVtbl -> FilterDataObject(This,pDO,ppDORet) + + +#define IDocHostUIHandler2_GetOverrideKeyPath(This,pchKey,dw) \ + (This)->lpVtbl -> GetOverrideKeyPath(This,pchKey,dw) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + +HRESULT STDMETHODCALLTYPE IDocHostUIHandler2_GetOverrideKeyPath_Proxy( + IDocHostUIHandler2 * This, + /* [out] */ LPOLESTR *pchKey, + /* [in] */ DWORD dw); + + +void __RPC_STUB IDocHostUIHandler2_GetOverrideKeyPath_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + + +#endif /* __IDocHostUIHandler2_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_mshtmhst_0269 */ +/* [local] */ + +DEFINE_GUID(CGID_DocHostCommandHandler,0xf38bc242,0xb950,0x11d1,0x89,0x18,0x00,0xc0,0x4f,0xc2,0xc8,0x36); + + +extern RPC_IF_HANDLE __MIDL_itf_mshtmhst_0269_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_mshtmhst_0269_v0_0_s_ifspec; + +#ifndef __ICustomDoc_INTERFACE_DEFINED__ +#define __ICustomDoc_INTERFACE_DEFINED__ + +/* interface ICustomDoc */ +/* [local][unique][uuid][object] */ + + +EXTERN_C const IID IID_ICustomDoc; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("3050f3f0-98b5-11cf-bb82-00aa00bdce0b") + ICustomDoc : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE SetUIHandler( + /* [in] */ IDocHostUIHandler *pUIHandler) = 0; + + }; + +#else /* C style interface */ + + typedef struct ICustomDocVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ICustomDoc * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ICustomDoc * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ICustomDoc * This); + + HRESULT ( STDMETHODCALLTYPE *SetUIHandler )( + ICustomDoc * This, + /* [in] */ IDocHostUIHandler *pUIHandler); + + END_INTERFACE + } ICustomDocVtbl; + + interface ICustomDoc + { + CONST_VTBL struct ICustomDocVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ICustomDoc_QueryInterface(This,riid,ppvObject) \ + (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) + +#define ICustomDoc_AddRef(This) \ + (This)->lpVtbl -> AddRef(This) + +#define ICustomDoc_Release(This) \ + (This)->lpVtbl -> Release(This) + + +#define ICustomDoc_SetUIHandler(This,pUIHandler) \ + (This)->lpVtbl -> SetUIHandler(This,pUIHandler) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + +HRESULT STDMETHODCALLTYPE ICustomDoc_SetUIHandler_Proxy( + ICustomDoc * This, + /* [in] */ IDocHostUIHandler *pUIHandler); + + +void __RPC_STUB ICustomDoc_SetUIHandler_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + + +#endif /* __ICustomDoc_INTERFACE_DEFINED__ */ + + +#ifndef __IDocHostShowUI_INTERFACE_DEFINED__ +#define __IDocHostShowUI_INTERFACE_DEFINED__ + +/* interface IDocHostShowUI */ +/* [local][unique][uuid][object] */ + + +EXTERN_C const IID IID_IDocHostShowUI; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("c4d244b0-d43e-11cf-893b-00aa00bdce1a") + IDocHostShowUI : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE ShowMessage( + /* [in] */ HWND hwnd, + /* [in] */ LPOLESTR lpstrText, + /* [in] */ LPOLESTR lpstrCaption, + /* [in] */ DWORD dwType, + /* [in] */ LPOLESTR lpstrHelpFile, + /* [in] */ DWORD dwHelpContext, + /* [out] */ LRESULT *plResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE ShowHelp( + /* [in] */ HWND hwnd, + /* [in] */ LPOLESTR pszHelpFile, + /* [in] */ UINT uCommand, + /* [in] */ DWORD dwData, + /* [in] */ POINT ptMouse, + /* [out] */ IDispatch *pDispatchObjectHit) = 0; + + }; + +#else /* C style interface */ + + typedef struct IDocHostShowUIVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDocHostShowUI * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDocHostShowUI * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDocHostShowUI * This); + + HRESULT ( STDMETHODCALLTYPE *ShowMessage )( + IDocHostShowUI * This, + /* [in] */ HWND hwnd, + /* [in] */ LPOLESTR lpstrText, + /* [in] */ LPOLESTR lpstrCaption, + /* [in] */ DWORD dwType, + /* [in] */ LPOLESTR lpstrHelpFile, + /* [in] */ DWORD dwHelpContext, + /* [out] */ LRESULT *plResult); + + HRESULT ( STDMETHODCALLTYPE *ShowHelp )( + IDocHostShowUI * This, + /* [in] */ HWND hwnd, + /* [in] */ LPOLESTR pszHelpFile, + /* [in] */ UINT uCommand, + /* [in] */ DWORD dwData, + /* [in] */ POINT ptMouse, + /* [out] */ IDispatch *pDispatchObjectHit); + + END_INTERFACE + } IDocHostShowUIVtbl; + + interface IDocHostShowUI + { + CONST_VTBL struct IDocHostShowUIVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDocHostShowUI_QueryInterface(This,riid,ppvObject) \ + (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) + +#define IDocHostShowUI_AddRef(This) \ + (This)->lpVtbl -> AddRef(This) + +#define IDocHostShowUI_Release(This) \ + (This)->lpVtbl -> Release(This) + + +#define IDocHostShowUI_ShowMessage(This,hwnd,lpstrText,lpstrCaption,dwType,lpstrHelpFile,dwHelpContext,plResult) \ + (This)->lpVtbl -> ShowMessage(This,hwnd,lpstrText,lpstrCaption,dwType,lpstrHelpFile,dwHelpContext,plResult) + +#define IDocHostShowUI_ShowHelp(This,hwnd,pszHelpFile,uCommand,dwData,ptMouse,pDispatchObjectHit) \ + (This)->lpVtbl -> ShowHelp(This,hwnd,pszHelpFile,uCommand,dwData,ptMouse,pDispatchObjectHit) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + +HRESULT STDMETHODCALLTYPE IDocHostShowUI_ShowMessage_Proxy( + IDocHostShowUI * This, + /* [in] */ HWND hwnd, + /* [in] */ LPOLESTR lpstrText, + /* [in] */ LPOLESTR lpstrCaption, + /* [in] */ DWORD dwType, + /* [in] */ LPOLESTR lpstrHelpFile, + /* [in] */ DWORD dwHelpContext, + /* [out] */ LRESULT *plResult); + + +void __RPC_STUB IDocHostShowUI_ShowMessage_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IDocHostShowUI_ShowHelp_Proxy( + IDocHostShowUI * This, + /* [in] */ HWND hwnd, + /* [in] */ LPOLESTR pszHelpFile, + /* [in] */ UINT uCommand, + /* [in] */ DWORD dwData, + /* [in] */ POINT ptMouse, + /* [out] */ IDispatch *pDispatchObjectHit); + + +void __RPC_STUB IDocHostShowUI_ShowHelp_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + + +#endif /* __IDocHostShowUI_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_mshtmhst_0271 */ +/* [local] */ + +#define IClassFactory3 IClassFactoryEx +#define IID_IClassFactory3 IID_IClassFactoryEx + + +extern RPC_IF_HANDLE __MIDL_itf_mshtmhst_0271_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_mshtmhst_0271_v0_0_s_ifspec; + +#ifndef __IClassFactoryEx_INTERFACE_DEFINED__ +#define __IClassFactoryEx_INTERFACE_DEFINED__ + +/* interface IClassFactoryEx */ +/* [local][unique][uuid][object] */ + + +EXTERN_C const IID IID_IClassFactoryEx; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("342D1EA0-AE25-11D1-89C5-006008C3FBFC") + IClassFactoryEx : public IClassFactory + { + public: + virtual HRESULT STDMETHODCALLTYPE CreateInstanceWithContext( + IUnknown *punkContext, + IUnknown *punkOuter, + REFIID riid, + /* [out] */ void **ppv) = 0; + + }; + +#else /* C style interface */ + + typedef struct IClassFactoryExVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IClassFactoryEx * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IClassFactoryEx * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IClassFactoryEx * This); + + /* [local] */ HRESULT ( STDMETHODCALLTYPE *CreateInstance )( + IClassFactoryEx * This, + /* [unique][in] */ IUnknown *pUnkOuter, + /* [in] */ REFIID riid, + /* [iid_is][out] */ void **ppvObject); + + /* [local] */ HRESULT ( STDMETHODCALLTYPE *LockServer )( + IClassFactoryEx * This, + /* [in] */ BOOL fLock); + + HRESULT ( STDMETHODCALLTYPE *CreateInstanceWithContext )( + IClassFactoryEx * This, + IUnknown *punkContext, + IUnknown *punkOuter, + REFIID riid, + /* [out] */ void **ppv); + + END_INTERFACE + } IClassFactoryExVtbl; + + interface IClassFactoryEx + { + CONST_VTBL struct IClassFactoryExVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IClassFactoryEx_QueryInterface(This,riid,ppvObject) \ + (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) + +#define IClassFactoryEx_AddRef(This) \ + (This)->lpVtbl -> AddRef(This) + +#define IClassFactoryEx_Release(This) \ + (This)->lpVtbl -> Release(This) + + +#define IClassFactoryEx_CreateInstance(This,pUnkOuter,riid,ppvObject) \ + (This)->lpVtbl -> CreateInstance(This,pUnkOuter,riid,ppvObject) + +#define IClassFactoryEx_LockServer(This,fLock) \ + (This)->lpVtbl -> LockServer(This,fLock) + + +#define IClassFactoryEx_CreateInstanceWithContext(This,punkContext,punkOuter,riid,ppv) \ + (This)->lpVtbl -> CreateInstanceWithContext(This,punkContext,punkOuter,riid,ppv) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + +HRESULT STDMETHODCALLTYPE IClassFactoryEx_CreateInstanceWithContext_Proxy( + IClassFactoryEx * This, + IUnknown *punkContext, + IUnknown *punkOuter, + REFIID riid, + /* [out] */ void **ppv); + + +void __RPC_STUB IClassFactoryEx_CreateInstanceWithContext_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + + +#endif /* __IClassFactoryEx_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_mshtmhst_0272 */ +/* [local] */ + +#endif + + +extern RPC_IF_HANDLE __MIDL_itf_mshtmhst_0272_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_mshtmhst_0272_v0_0_s_ifspec; + +/* Additional Prototypes for ALL interfaces */ + +/* end of Additional Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/mod/maxgui.mod/win32maxguiex.mod/mshtmlview.cpp b/mod/maxgui.mod/win32maxguiex.mod/mshtmlview.cpp new file mode 100644 index 0000000..b8748cd --- /dev/null +++ b/mod/maxgui.mod/win32maxguiex.mod/mshtmlview.cpp @@ -0,0 +1,1115 @@ + +#include +#include +#include +#include +#include + +#include "mshtmlview.h" + +// fix emit!!! + +// blitzmax / mingw compilations stuff... + +#include +#include + +#define NOCONTEXTMENU 1 +#define NONAVIGATE 2 + +BBString *bbStringFromVariant2(VARIANT *v){ + unsigned short *w; + int n; + if (v->vt!=VT_BSTR) return 0; + w=(unsigned short*)v->bstrVal; + n=0; + while (w[n++]) {} + return bbStringFromShorts(w,n-1); +} + + +#define OLERENDER_DRAW 1 + +#define TODO {printf("htmlview TODO error line:%d\n",__LINE__);fflush(stdout);brl_blitz_NullObjectError();return 0;} + +typedef IDispatch * DWebBrowserEventsPtr; +const IID IID_IDocHostUIHandler2={0xbd3f23c0,0xd43e,0x11cf,{0x89,0x3b,0x00,0xaa,0x00,0xbd,0xce,0x1a}}; +const IID IID_DWebBrowserEvents2={0x34A715A0,0x6587,0x11D0,{0x92,0x4A,0x00,0x20,0xAF,0xC7,0xAC,0x4D}}; +//const IID IID_IHTMLDocument={0x626FC520,0xA41E,0x11cf,{0xA7,0x31,0x00,0xa0,0xc9,0x08,0x26,0x37}}; + +#define DISPID_BEFORENAVIGATE2 250 // hyperlink clicked on +#define DISPID_NEWWINDOW2 251 +#define DISPID_NAVIGATECOMPLETE2 252 // UIActivate new document +#define DISPID_DOCUMENTCOMPLETE 259 + +//#ifdef MINGW322 + +typedef interface IHTMLFiltersCollection *LPHTMLFILTERSCOLLECTION; +typedef interface IHTMLLinkElement *LPHTMLLINKELEMENT; +typedef interface IHTMLImgElement *LPHTMLIMGELEMENT; +typedef interface IHTMLImageElementFactory *LPHTMLIMAGEELEMENTFACTORY; +typedef interface IHTMLEventObj *LPHTMLEVENTOBJ; +typedef interface IHTMLScreen *LPHTMLSCREEN; +typedef interface IHTMLOptionElementFactory *LPHTMLOPTIONELEMENTFACTORY; +typedef interface IOmHistory *LPOMHISTORY; +typedef interface IOmNavigator *LPOMNAVIGATOR; + +#if __W32API_MAJOR_VERSION<3 + +EXTERN_C const IID IID_IHTMLFramesCollection2; +EXTERN_C const IID IID_IHTMLWindow2; + +#undef INTERFACE +#define INTERFACE IHTMLFramesCollection2 +DECLARE_INTERFACE_(IHTMLFramesCollection2,IDispatch) +{ + STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + STDMETHOD(GetTypeInfoCount)(THIS_ UINT*) PURE; + STDMETHOD(GetTypeInfo)(THIS_ UINT,LCID,LPTYPEINFO*) PURE; + STDMETHOD(GetIDsOfNames)(THIS_ REFIID,LPOLESTR*,UINT,LCID,DISPID*) PURE; + STDMETHOD(Invoke)(THIS_ DISPID,REFIID,LCID,WORD,DISPPARAMS*,VARIANT*,EXCEPINFO*,UINT*) PURE; + STDMETHOD(item)(THIS_ VARIANT*,VARIANT*) PURE; + STDMETHOD(get_length)(THIS_ long*) PURE; +}; + +#undef INTERFACE +#define INTERFACE IHTMLWindow2 +DECLARE_INTERFACE_(IHTMLWindow2,IHTMLFramesCollection2) +{ + STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + STDMETHOD(GetTypeInfoCount)(THIS_ UINT*) PURE; + STDMETHOD(GetTypeInfo)(THIS_ UINT,LCID,LPTYPEINFO*) PURE; + STDMETHOD(GetIDsOfNames)(THIS_ REFIID,LPOLESTR*,UINT,LCID,DISPID*) PURE; + STDMETHOD(Invoke)(THIS_ DISPID,REFIID,LCID,WORD,DISPPARAMS*,VARIANT*,EXCEPINFO*,UINT*) PURE; + STDMETHOD(item)(THIS_ VARIANT*,VARIANT*) PURE; + STDMETHOD(get_length)(THIS_ long*) PURE; + + STDMETHOD(get_frames)(THIS_ IHTMLFramesCollection2**) PURE; + STDMETHOD(put_defaultStatus)(THIS_ BSTR) PURE; + STDMETHOD(get_defaultStatus)(THIS_ BSTR*) PURE; + STDMETHOD(put_status)(THIS_ BSTR) PURE; + STDMETHOD(get_status)(THIS_ BSTR*) PURE; + STDMETHOD(setTimeout)(THIS_ BSTR,long,VARIANT*,long*) PURE; + STDMETHOD(clearTimeout)(THIS_ long) PURE; + STDMETHOD(alert)(THIS_ BSTR) PURE; + STDMETHOD(confirm)(THIS_ BSTR,VARIANT_BOOL*) PURE; + STDMETHOD(prompt)(THIS_ BSTR,BSTR,VARIANT*) PURE; + STDMETHOD(get_Image)(THIS_ LPHTMLIMAGEELEMENTFACTORY*) PURE; + STDMETHOD(get_location)(THIS_ LPHTMLLOCATION*) PURE; + STDMETHOD(get_history)(THIS_ LPOMHISTORY*) PURE; + STDMETHOD(close)(THIS) PURE; + STDMETHOD(put_opener)(THIS_ VARIANT) PURE; + STDMETHOD(get_opener)(THIS_ VARIANT*) PURE; + STDMETHOD(get_navigator)(THIS_ LPOMNAVIGATOR*) PURE; + STDMETHOD(put_name)(THIS_ BSTR) PURE; + STDMETHOD(get_name)(THIS_ BSTR*) PURE; + STDMETHOD(get_parent)(THIS_ LPHTMLWINDOW2*) PURE; + STDMETHOD(open)(THIS_ BSTR,BSTR,BSTR,VARIANT_BOOL,LPHTMLWINDOW2*) PURE; + STDMETHOD(get_self)(THIS_ LPHTMLWINDOW2*) PURE; + STDMETHOD(get_top)(THIS_ LPHTMLWINDOW2*) PURE; + STDMETHOD(get_window)(THIS_ LPHTMLWINDOW2*) PURE; + STDMETHOD(navigate)(THIS_ BSTR) PURE; + STDMETHOD(put_onfocus)(THIS_ VARIANT) PURE; + STDMETHOD(get_onfocus)(THIS_ VARIANT*) PURE; + STDMETHOD(put_onblur)(THIS_ VARIANT) PURE; + STDMETHOD(get_onblur)(THIS_ VARIANT*) PURE; + STDMETHOD(put_onload)(THIS_ VARIANT) PURE; + STDMETHOD(get_onload)(THIS_ VARIANT*) PURE; + STDMETHOD(put_onbeforeunload)(THIS_ VARIANT) PURE; + STDMETHOD(get_onbeforeunload)(THIS_ VARIANT*) PURE; + STDMETHOD(put_onunload)(THIS_ VARIANT) PURE; + STDMETHOD(get_onunload)(THIS_ VARIANT*) PURE; + STDMETHOD(put_onhelp)(THIS_ VARIANT) PURE; + STDMETHOD(get_onhelp)(THIS_ VARIANT*) PURE; + STDMETHOD(put_onerror)(THIS_ VARIANT) PURE; + STDMETHOD(get_onerror)(THIS_ VARIANT*) PURE; + STDMETHOD(put_onresize)(THIS_ VARIANT) PURE; + STDMETHOD(get_onresize)(THIS_ VARIANT*) PURE; + STDMETHOD(put_onscroll)(THIS_ VARIANT) PURE; + STDMETHOD(get_onscroll)(THIS_ VARIANT*) PURE; + STDMETHOD(get_document)(THIS_ IHTMLDocument2**) PURE; + STDMETHOD(get_event)(THIS_ LPHTMLEVENTOBJ*) PURE; + STDMETHOD(get__newEnum)(THIS_ IUnknown**) PURE; + STDMETHOD(showModalDialog)(THIS_ BSTR,VARIANT*,VARIANT*,VARIANT*) PURE; + STDMETHOD(showHelp)(THIS_ BSTR,VARIANT,BSTR) PURE; + STDMETHOD(get_screen)(THIS_ LPHTMLSCREEN*) PURE; + STDMETHOD(get_Option)(THIS_ LPHTMLOPTIONELEMENTFACTORY*) PURE; + STDMETHOD(focus)(THIS) PURE; + STDMETHOD(get_closed)(THIS_ VARIANT_BOOL*) PURE; + STDMETHOD(blur)(THIS) PURE; + STDMETHOD(scroll)(THIS_ long,long) PURE; + STDMETHOD(get_clientInformation)(THIS_ LPOMNAVIGATOR*) PURE; + STDMETHOD(setInterval)(THIS_ BSTR,long,VARIANT*,long*) PURE; + STDMETHOD(clearInterval)(THIS_ long) PURE; + STDMETHOD(put_offscreenBuffering)(THIS_ VARIANT) PURE; + STDMETHOD(get_offscreenBuffering)(THIS_ VARIANT*) PURE; + STDMETHOD(execScript)(THIS_ BSTR,BSTR,VARIANT*) PURE; + STDMETHOD(toString)(THIS_ BSTR*) PURE; + STDMETHOD(scrollBy)(THIS_ long,long) PURE; + STDMETHOD(scrollTo)(THIS_ long,long) PURE; + STDMETHOD(moveTo)(THIS_ long,long) PURE; + STDMETHOD(moveBy)(THIS_ long,long) PURE; + STDMETHOD(resizeTo)(THIS_ long,long) PURE; + STDMETHOD(resizeBy)(THIS_ long,long) PURE; + STDMETHOD(get_external)(THIS_ IDispatch**) PURE; +}; + +#endif + +//#endif //additional mingw 3.2 includes + + +struct CNullStorage2 : public IStorage{ + // IUnknown + STDMETHODIMP QueryInterface(REFIID riid,void ** ppvObject); + STDMETHODIMP_(ULONG) AddRef(void); + STDMETHODIMP_(ULONG) Release(void); + // IStorage + STDMETHODIMP CreateStream(const WCHAR * pwcsName,DWORD grfMode,DWORD reserved1,DWORD reserved2,IStream ** ppstm); + STDMETHODIMP OpenStream(const WCHAR * pwcsName,void * reserved1,DWORD grfMode,DWORD reserved2,IStream ** ppstm); + STDMETHODIMP CreateStorage(const WCHAR * pwcsName,DWORD grfMode,DWORD reserved1,DWORD reserved2,IStorage ** ppstg); + STDMETHODIMP OpenStorage(const WCHAR * pwcsName,IStorage * pstgPriority,DWORD grfMode,SNB snbExclude,DWORD reserved,IStorage ** ppstg); + STDMETHODIMP CopyTo(DWORD ciidExclude,IID const * rgiidExclude,SNB snbExclude,IStorage * pstgDest); + STDMETHODIMP MoveElementTo(const OLECHAR * pwcsName,IStorage * pstgDest,const OLECHAR* pwcsNewName,DWORD grfFlags); + STDMETHODIMP Commit(DWORD grfCommitFlags); + STDMETHODIMP Revert(void); + STDMETHODIMP EnumElements(DWORD reserved1,void * reserved2,DWORD reserved3,IEnumSTATSTG ** ppenum); + STDMETHODIMP DestroyElement(const OLECHAR * pwcsName); + STDMETHODIMP RenameElement(const WCHAR * pwcsOldName,const WCHAR * pwcsNewName); + STDMETHODIMP SetElementTimes(const WCHAR * pwcsName,FILETIME const * pctime,FILETIME const * patime,FILETIME const * pmtime); + STDMETHODIMP SetClass(REFCLSID clsid); + STDMETHODIMP SetStateBits(DWORD grfStateBits,DWORD grfMask); + STDMETHODIMP Stat(STATSTG * pstatstg,DWORD grfStatFlag); +}; + +struct CMyFrame2 : public IOleInPlaceFrame{ + + // IUnknown + STDMETHODIMP QueryInterface(REFIID riid,void ** ppvObject); + STDMETHODIMP_(ULONG) AddRef(void); + STDMETHODIMP_(ULONG) Release(void); + // IOleWindow + STDMETHODIMP GetWindow(HWND FAR* lphwnd); + STDMETHODIMP ContextSensitiveHelp(BOOL fEnterMode); + // IOleInPlaceUIWindow + STDMETHODIMP GetBorder(LPRECT lprectBorder); + STDMETHODIMP RequestBorderSpace(LPCBORDERWIDTHS pborderwidths); + STDMETHODIMP SetBorderSpace(LPCBORDERWIDTHS pborderwidths); + STDMETHODIMP SetActiveObject(IOleInPlaceActiveObject *pActiveObject,LPCOLESTR pszObjName); + // IOleInPlaceFrame + STDMETHODIMP InsertMenus(HMENU hmenuShared,LPOLEMENUGROUPWIDTHS lpMenuWidths); + STDMETHODIMP SetMenu(HMENU hmenuShared,HOLEMENU holemenu,HWND hwndActiveObject); + STDMETHODIMP RemoveMenus(HMENU hmenuShared); + STDMETHODIMP SetStatusText(LPCOLESTR pszStatusText); + STDMETHODIMP EnableModeless(BOOL fEnable); + STDMETHODIMP TranslateAccelerator( LPMSG lpmsg,WORD wID); + + struct HTMLView *rep; +}; + +struct CMySite2 : public IOleClientSite,public IOleInPlaceSite,public IDocHostUIHandler +{ + // IUnknown + STDMETHODIMP QueryInterface(REFIID riid,void ** ppvObject); + STDMETHODIMP_(ULONG) AddRef(void); + STDMETHODIMP_(ULONG) Release(void); + // IOleClientSite + STDMETHODIMP SaveObject(); + STDMETHODIMP GetMoniker(DWORD dwAssign,DWORD dwWhichMoniker,IMoniker ** ppmk); + STDMETHODIMP GetContainer(LPOLECONTAINER FAR* ppContainer); + STDMETHODIMP ShowObject(); + STDMETHODIMP OnShowWindow(BOOL fShow); + STDMETHODIMP RequestNewObjectLayout(); + // IOleWindow + STDMETHODIMP GetWindow(HWND FAR* lphwnd); + STDMETHODIMP ContextSensitiveHelp(BOOL fEnterMode); + // IOleInPlaceSite methods + STDMETHODIMP CanInPlaceActivate(); + STDMETHODIMP OnInPlaceActivate(); + STDMETHODIMP OnUIActivate(); + STDMETHODIMP GetWindowContext(LPOLEINPLACEFRAME FAR* lplpFrame,LPOLEINPLACEUIWINDOW FAR* lplpDoc,LPRECT lprcPosRect,LPRECT lprcClipRect,LPOLEINPLACEFRAMEINFO lpFrameInfo); + STDMETHODIMP Scroll(SIZE scrollExtent); + STDMETHODIMP OnUIDeactivate(BOOL fUndoable); + STDMETHODIMP OnInPlaceDeactivate(); + STDMETHODIMP DiscardUndoState(); + STDMETHODIMP DeactivateAndUndo(); + STDMETHODIMP OnPosRectChange(LPCRECT lprcPosRect); + // idochost methods + STDMETHODIMP ShowContextMenu( DWORD dwID,POINT __RPC_FAR *ppt,IUnknown __RPC_FAR *pcmdtReserved,IDispatch __RPC_FAR *pdispReserved) ; + STDMETHODIMP GetHostInfo( DOCHOSTUIINFO __RPC_FAR *pInfo); + STDMETHODIMP ShowUI( DWORD dwID,IOleInPlaceActiveObject __RPC_FAR *pActiveObject,IOleCommandTarget __RPC_FAR *pCommandTarget,IOleInPlaceFrame __RPC_FAR *pFrame,IOleInPlaceUIWindow __RPC_FAR *pDoc); + STDMETHODIMP HideUI( void); + STDMETHODIMP UpdateUI( void); + STDMETHODIMP OnDocWindowActivate( BOOL fActivate); + STDMETHODIMP OnFrameWindowActivate( BOOL fActivate); + STDMETHODIMP ResizeBorder( LPCRECT prcBorder,IOleInPlaceUIWindow __RPC_FAR *pUIWindow,BOOL fRameWindow); + STDMETHODIMP TranslateAccelerator( LPMSG lpMsg,const GUID __RPC_FAR *pguidCmdGroup,DWORD nCmdID); + STDMETHODIMP GetOptionKeyPath( LPOLESTR __RPC_FAR *pchKey,DWORD dw); + STDMETHODIMP GetDropTarget( IDropTarget __RPC_FAR *pDropTarget,IDropTarget __RPC_FAR *__RPC_FAR *ppDropTarget); + STDMETHODIMP GetExternal( IDispatch __RPC_FAR *__RPC_FAR *ppDispatch); + STDMETHODIMP TranslateUrl(DWORD dwTranslate,OLECHAR __RPC_FAR *pchURLIn,OLECHAR __RPC_FAR *__RPC_FAR *ppchURLOut); + STDMETHODIMP EnableModeless( BOOL fEnable); + STDMETHODIMP FilterDataObject( IDataObject __RPC_FAR *pDO,IDataObject __RPC_FAR *__RPC_FAR *ppDORet); + + struct HTMLView *rep; +}; + +struct CMyContainer : public IOleContainer{ + // IUnknown + STDMETHODIMP QueryInterface(REFIID riid,void ** ppvObject); + STDMETHODIMP_(ULONG) AddRef(void); + STDMETHODIMP_(ULONG) Release(void); + // IParseDisplayName + STDMETHODIMP ParseDisplayName(IBindCtx *pbc,LPOLESTR pszDisplayName,ULONG *pchEaten,IMoniker **ppmkOut); + // IOleContainer + STDMETHODIMP EnumObjects(DWORD grfFlags,IEnumUnknown **ppenum); + STDMETHODIMP LockContainer(BOOL fLock); +}; + +struct _bstr_t +{ + struct Data_t + { + wchar_t* m_wstr; + mutable char* m_str; + unsigned long m_RefCount; + Data_t(BSTR bstr, bool fCopy) : m_str(NULL), m_RefCount(1) //throw(_com_error) + { + if (fCopy && bstr != NULL) + { + m_wstr = ::SysAllocStringByteLen(reinterpret_cast(bstr),::SysStringByteLen(bstr)); +// if (m_wstr == NULL) {_com_issue_error(E_OUTOFMEMORY);} + } + else + { + m_wstr = bstr; + } + } + Data_t(const wchar_t* s):m_str(NULL), m_RefCount(1) + { + m_wstr = ::SysAllocString(s); +// if (m_wstr == NULL && s != NULL) {_com_issue_error(E_OUTOFMEMORY);} + } + unsigned long AddRef() throw() + { + InterlockedIncrement(reinterpret_cast(&m_RefCount)); + return m_RefCount; + } + unsigned long Release() throw() + { + if (!InterlockedDecrement(reinterpret_cast(&m_RefCount))) {delete this;return 0;} + return m_RefCount; + } + unsigned long RefCount() const throw() + { + return m_RefCount; + } + wchar_t* GetWString() + { + return m_wstr; + } + }; + Data_t* m_Data; + + _bstr_t(BSTR bstr, bool fCopy):m_Data(new Data_t(bstr, fCopy)) + { +// if (m_Data == NULL) {_com_issue_error(E_OUTOFMEMORY);} + } + + _bstr_t(const wchar_t* s):m_Data(new Data_t(s)) + { +// if (m_Data == NULL) {_com_issue_error(E_OUTOFMEMORY);} + } + + BBString *bbString() + { + unsigned short *w; + int n; + w=(unsigned short*)m_Data->m_wstr;n=0;while (w[n++]) {} + return bbStringFromShorts(w,n-1); + } +}; + +struct DWebBrowserEventsImpl2 : public DWebBrowserEvents2 //DWebBrowserEvents +{ +// IUnknown methods + STDMETHOD(QueryInterface)(REFIID riid, LPVOID* ppv); + STDMETHOD_(ULONG, AddRef)(); + STDMETHOD_(ULONG, Release)(); +// IDispatch methods + STDMETHOD(GetTypeInfoCount)(UINT* pctinfo); + STDMETHOD(GetTypeInfo)(UINT iTInfo,LCID lcid,ITypeInfo** ppTInfo); + STDMETHOD(GetIDsOfNames)(REFIID riid,LPOLESTR* rgszNames,UINT cNames,LCID lcid,DISPID* rgDispId); + STDMETHOD(Invoke)(DISPID dispIdMember, + REFIID riid, + LCID lcid, + WORD wFlags, + DISPPARAMS __RPC_FAR *pDispParams, + VARIANT __RPC_FAR *pVarResult, + EXCEPINFO __RPC_FAR *pExcepInfo, + UINT __RPC_FAR *puArgErr); +// events + HRESULT BeforeNavigate ( + _bstr_t URL, + long Flags, + _bstr_t TargetFrameName, + VARIANT * PostData, + _bstr_t Headers, + VARIANT_BOOL * Cancel ); + + HRESULT NavigateComplete ( _bstr_t URL ) {return S_OK;} + HRESULT StatusTextChange ( _bstr_t Text ); + void ProgressChange ( + long Progress, + long ProgressMax ); + void DownloadComplete(); + void CommandStateChange ( + long Command, + VARIANT_BOOL Enable ); + void DownloadBegin (); + HRESULT NewWindow ( + _bstr_t URL, + long Flags, + _bstr_t TargetFrameName, + VARIANT * PostData, + _bstr_t Headers, + VARIANT_BOOL * Processed ); + HRESULT TitleChange ( _bstr_t Text ); + HRESULT FrameBeforeNavigate ( + _bstr_t URL, + long Flags, + _bstr_t TargetFrameName, + VARIANT * PostData, + _bstr_t Headers, + VARIANT_BOOL * Cancel ); + HRESULT FrameNavigateComplete ( + _bstr_t URL ); + HRESULT FrameNewWindow ( + _bstr_t URL, + long Flags, + _bstr_t TargetFrameName, + VARIANT * PostData, + _bstr_t Headers, + VARIANT_BOOL * Processed ); + HRESULT Quit ( + VARIANT_BOOL * Cancel ); + HRESULT WindowMove ( ); + HRESULT WindowResize ( ); + HRESULT WindowActivate ( ); + HRESULT PropertyChange ( + _bstr_t Property ); + + void StatusTextChange(OLECHAR*) {} + void TitleChange(OLECHAR*) {} + void PropertyChange(OLECHAR*) {} + void BeforeNavigate2(IDispatch*, VARIANT*, VARIANT*, VARIANT*, VARIANT*, VARIANT*, VARIANT_BOOL*); + void NewWindow2(IDispatch**, VARIANT_BOOL*); // {} + void NavigateComplete(IDispatch*, VARIANT*) ; + void DocumentComplete(IDispatch*, VARIANT*) ;//{} + void OnQuit() {} + void OnVisible(short int) {} + void OnToolBar(short int) {} + void OnMenuBar(short int) {} + void OnStatusBar(short int) {} + void OnFullScreen(short int) {} + void OnTheaterMode(short int) {} + void WindowSetResizable(short int) {} + void WindowSetLeft(long int) {} + void WindowSetTop(long int) {} + void WindowSetWidth(long int) {} + void WindowSetHeight(long int) {} + void WindowClosing(short int, VARIANT_BOOL*) {} + void ClientToHostWindow(long int*, long int*) {} + void SetSecureLockIcon(long int) {} + void FileDownload(VARIANT_BOOL*) {} + + HTMLView *rep; +}; + + + +struct HTMLView{ + + HWND hwnd; + BBObject *owner; + + CMySite2 site; + CMyFrame2 frame; + CNullStorage2 storage; + DWebBrowserEventsImpl2 eventsink; + + IOleObject *oleObject; + IWebBrowser2* iBrowser; + IOleInPlaceObject *inPlaceObject; + IConnectionPointContainer *iConnection; + IConnectionPoint *iConnectionPoint; + IOleCommandTarget *iTarget; + + BSTR current; + + DWORD dwCookie; + + int viewstyle; + int navcount; //used with style&NOUSERNAV to route user navigation to event queue + int loading; //state returned by getstatus() + + HTMLView( BBObject *gadget, wchar_t *wndclass,HWND parent,int style ){ + + owner=gadget; + current=0; + + viewstyle=style; + navcount=0; + loading=0; + + int xstyle=WS_EX_CONTROLPARENT; + int wstyle=WS_CHILD|WS_TABSTOP|WS_CLIPSIBLINGS|WS_VISIBLE; + + hwnd=CreateWindowExW( xstyle,wndclass,0,wstyle,0,0,200,200,parent,0,GetModuleHandle(0),0 ); + + site.rep=this; + eventsink.rep=this; + frame.rep=this; + + int res=OleCreate( CLSID_WebBrowser,IID_IOleObject,OLERENDER_DRAW,0,&site,&storage,(void**)&oleObject ); + + OleSetContainedObject( oleObject,TRUE); + + oleObject->SetHostNames(L"Web Host",L"Web View"); + oleObject->QueryInterface(IID_IWebBrowser2,(void**)&iBrowser); + oleObject->QueryInterface(IID_IOleInPlaceObject,(void**)&inPlaceObject ); + oleObject->QueryInterface(IID_IConnectionPointContainer,(void**)&iConnection); + oleObject->QueryInterface(IID_IOleCommandTarget,(void**)&iTarget ); + + iConnection->FindConnectionPoint(DIID_DWebBrowserEvents2, &iConnectionPoint); + iConnectionPoint->Advise((LPUNKNOWN)&eventsink, &dwCookie); + + RECT rect; + ::GetClientRect( hwnd,&rect ); + oleObject->DoVerb(OLEIVERB_SHOW,NULL,&site,-1,hwnd,&rect); + + oleObject->DoVerb(OLEIVERB_UIACTIVATE,NULL,&site,0,hwnd,&rect); //INPLACE + + go( L"about:blank" ); + } + + ~HTMLView(){ + if (current) SysFreeString(current); + inPlaceObject->Release(); + iBrowser->Release(); + oleObject->Close(OLECLOSE_NOSAVE); + oleObject->Release(); + } + + void setcurrenturl(VARIANT *url) + { + if (current) SysFreeString(current); + current=0; + if (url->vt==VT_BSTR){ + current=SysAllocString(url->bstrVal); + } + } + + void setshape(int x,int y,int w,int h){ + RECT rect; + rect.left=0;rect.right=w;rect.top=0;rect.bottom=h; + MoveWindow(hwnd,x,y,w,h,TRUE); + inPlaceObject->SetObjectRects( &rect,&rect ); + } + + void go( const wchar_t *url ){ + BSTR bstr=SysAllocString(url); + VARIANT flags={VT_INT}; + navcount=1; + loading=1; + iBrowser->Navigate( bstr,&flags,0,0,0 ); + SysFreeString(bstr); + } + + +#define IDM_COPY 15 +#define IDM_CUT 16 +#define IDM_PASTE 26 + + int activate(int cmd){ + + OLECMDF tmpOutput; + + switch (cmd) + { + case ACTIVATE_CUT: + iBrowser->QueryStatusWB(OLECMDID_CUT,&tmpOutput); + if(tmpOutput&OLECMDF_ENABLED) return iBrowser->ExecWB(OLECMDID_CUT,OLECMDEXECOPT_DONTPROMPTUSER,0,0); + break; + case ACTIVATE_COPY: + iBrowser->QueryStatusWB(OLECMDID_COPY,&tmpOutput); + if(tmpOutput&OLECMDF_ENABLED) return iBrowser->ExecWB(OLECMDID_COPY,OLECMDEXECOPT_DONTPROMPTUSER,0,0); + break; + case ACTIVATE_PASTE: + iBrowser->QueryStatusWB(OLECMDID_PASTE,&tmpOutput); + if(tmpOutput&OLECMDF_ENABLED) return iBrowser->ExecWB(OLECMDID_PASTE,OLECMDEXECOPT_DONTPROMPTUSER,0,0); + break; + case ACTIVATE_PRINT: + return iBrowser->ExecWB(OLECMDID_PRINT,OLECMDEXECOPT_PROMPTUSER,0,0); + case ACTIVATE_BACK: + navcount=1; + iBrowser->GoBack(); + return 0; + case ACTIVATE_FORWARD: + navcount=1; + iBrowser->GoForward(); + return 0; + } + return 0; + } + + void run( const wchar_t *script ) + { + IDispatch *disp; + BSTR bstr; + IHTMLDocument2 *doc; + IHTMLWindow2 *win; + HRESULT res; + VARIANT result; + +// bstr=SysAllocStringLen((OLECHAR*)script->buf,scripturl->length); + bstr=SysAllocString(script);//(OLECHAR*)script->buf,scripturl->length); + + res=iBrowser->get_Document(&disp); + if (res==S_OK) + { + res=disp->QueryInterface(IID_IHTMLDocument2,(void**)&doc); + res=doc->get_parentWindow(&win); + result.vt=VT_EMPTY; + res=win->execScript(bstr,0,&result); + } + SysFreeString(bstr); + } + + int status(){ + READYSTATE state; + iBrowser->get_ReadyState(&state); + return (state!=READYSTATE_COMPLETE); + } +}; + + + + +STDMETHODIMP CNullStorage2::QueryInterface(REFIID riid,void ** ppvObject){ + TODO +} +STDMETHODIMP_(ULONG) CNullStorage2::AddRef(void){ + return 1; +} +STDMETHODIMP_(ULONG) CNullStorage2::Release(void){ + return 1; +} +STDMETHODIMP CNullStorage2::CreateStream(const WCHAR * pwcsName,DWORD grfMode,DWORD reserved1,DWORD reserved2,IStream ** ppstm){ + TODO +} +STDMETHODIMP CNullStorage2::OpenStream(const WCHAR * pwcsName,void * reserved1,DWORD grfMode,DWORD reserved2,IStream ** ppstm){ + TODO +} +STDMETHODIMP CNullStorage2::CreateStorage(const WCHAR * pwcsName,DWORD grfMode,DWORD reserved1,DWORD reserved2,IStorage ** ppstg){ + TODO +} +STDMETHODIMP CNullStorage2::OpenStorage(const WCHAR * pwcsName,IStorage * pstgPriority,DWORD grfMode,SNB snbExclude,DWORD reserved,IStorage ** ppstg){ + TODO +} +STDMETHODIMP CNullStorage2::CopyTo(DWORD ciidExclude,IID const * rgiidExclude,SNB snbExclude,IStorage * pstgDest){ + TODO +} +STDMETHODIMP CNullStorage2::MoveElementTo(const OLECHAR * pwcsName,IStorage * pstgDest,const OLECHAR* pwcsNewName,DWORD grfFlags){ + TODO +} +STDMETHODIMP CNullStorage2::Commit(DWORD grfCommitFlags){ + TODO +} +STDMETHODIMP CNullStorage2::Revert(void){ + TODO +} +STDMETHODIMP CNullStorage2::EnumElements(DWORD reserved1,void * reserved2,DWORD reserved3,IEnumSTATSTG ** ppenum){ + TODO +} +STDMETHODIMP CNullStorage2::DestroyElement(const OLECHAR * pwcsName){ + TODO +} +STDMETHODIMP CNullStorage2::RenameElement(const WCHAR * pwcsOldName,const WCHAR * pwcsNewName){ + TODO +} +STDMETHODIMP CNullStorage2::SetElementTimes(const WCHAR * pwcsName,FILETIME const * pctime,FILETIME const * patime,FILETIME const * pmtime){ + TODO +} +STDMETHODIMP CNullStorage2::SetClass(REFCLSID clsid){ + return S_OK; +} +STDMETHODIMP CNullStorage2::SetStateBits(DWORD grfStateBits,DWORD grfMask){ + TODO +} +STDMETHODIMP CNullStorage2::Stat(STATSTG * pstatstg,DWORD grfStatFlag){ + TODO +} + +STDMETHODIMP CMySite2::QueryInterface(REFIID riid,void ** ppvObject){ + if( riid == IID_IUnknown || riid == IID_IOleClientSite ){ + *ppvObject = (IOleClientSite*)this; + }else if(riid == IID_IOleInPlaceSite){ + *ppvObject = (IOleInPlaceSite*)this; + }else if(riid == IID_IDocHostUIHandler2){ + *ppvObject = (IDocHostUIHandler*)this; + }else{ + *ppvObject = NULL; + return E_NOINTERFACE; + } + return S_OK; +} +STDMETHODIMP_(ULONG) CMySite2::AddRef(void){ + return 1; +} +STDMETHODIMP_(ULONG) CMySite2::Release(void){ + return 1; +} +STDMETHODIMP CMySite2::SaveObject(){ + TODO +} +STDMETHODIMP CMySite2::GetMoniker(DWORD dwAssign,DWORD dwWhichMoniker,IMoniker ** ppmk){ + TODO +} +STDMETHODIMP CMySite2::GetContainer(LPOLECONTAINER FAR* ppContainer){ + *ppContainer = NULL; + return E_NOINTERFACE; +} +STDMETHODIMP CMySite2::ShowObject(){ + return NOERROR; +} +STDMETHODIMP CMySite2::OnShowWindow(BOOL fShow){ + TODO +} +STDMETHODIMP CMySite2::RequestNewObjectLayout(){ + TODO +} +STDMETHODIMP CMySite2::GetWindow(HWND FAR* lphwnd){ + *lphwnd=rep->hwnd; + return S_OK; +} +STDMETHODIMP CMySite2::ContextSensitiveHelp(BOOL fEnterMode){ + TODO +} +STDMETHODIMP CMySite2::CanInPlaceActivate(){ + return S_OK; +} +STDMETHODIMP CMySite2::OnInPlaceActivate(){ + return S_OK; +} +STDMETHODIMP CMySite2::OnUIActivate(){ + return S_OK; +} +STDMETHODIMP CMySite2::GetWindowContext( + LPOLEINPLACEFRAME FAR* ppFrame, + LPOLEINPLACEUIWINDOW FAR* ppDoc, + LPRECT prcPosRect, + LPRECT prcClipRect, + LPOLEINPLACEFRAMEINFO lpFrameInfo){ + *ppFrame=&rep->frame; + *ppDoc = NULL; + GetClientRect(rep->hwnd,prcPosRect); + GetClientRect(rep->hwnd,prcClipRect); + lpFrameInfo->cb=sizeof(OLEINPLACEFRAMEINFO); + lpFrameInfo->fMDIApp=FALSE; + lpFrameInfo->hwndFrame=rep->hwnd; + lpFrameInfo->haccel=NULL; + lpFrameInfo->cAccelEntries=0; + return S_OK; +} +STDMETHODIMP CMySite2::Scroll(SIZE scrollExtent){ + TODO +} +STDMETHODIMP CMySite2::OnUIDeactivate(BOOL fUndoable){ + return S_OK; +} +STDMETHODIMP CMySite2::OnInPlaceDeactivate(){ + return S_OK; +} +STDMETHODIMP CMySite2::DiscardUndoState(){ + TODO +} +STDMETHODIMP CMySite2::DeactivateAndUndo(){ + TODO +} +STDMETHODIMP CMySite2::OnPosRectChange( const RECT *rect ){ + TODO +} +STDMETHODIMP CMySite2::EnableModeless( BOOL fEnable) {return S_OK;} //[in] + +STDMETHODIMP CMySite2::ShowContextMenu( + /* [in] */ DWORD dwID, + /* [in] */ POINT __RPC_FAR *ppt, + /* [in] */ IUnknown __RPC_FAR *pcmdtReserved, + /* [in] */ IDispatch __RPC_FAR *pdispReserved) +{ + if (rep->viewstyle&NOCONTEXTMENU) return S_OK; + return S_FALSE; +} + +STDMETHODIMP CMySite2::ShowUI( + /* [in] */ DWORD dwID, + /* [in] */ IOleInPlaceActiveObject __RPC_FAR *pActiveObject, + /* [in] */ IOleCommandTarget __RPC_FAR *pCommandTarget, + /* [in] */ IOleInPlaceFrame __RPC_FAR *pFrame, + /* [in] */ IOleInPlaceUIWindow __RPC_FAR *pDoc) +{ +// pCommandTarget->Exec(0,IDM_DISABLEMODELESS,OLECMDEXECOPT_DODEFAULT,0,0); +// if (rep->style&SHOWUI) return S_FALSE; + return S_OK; +} + +STDMETHODIMP CMySite2::HideUI( void) +{ + return S_OK; +} +STDMETHODIMP CMySite2::UpdateUI( void) +{ + return S_OK; +} + +STDMETHODIMP CMySite2::OnDocWindowActivate( /* [in] */ BOOL fActivate) {return S_OK;} +STDMETHODIMP CMySite2::OnFrameWindowActivate( /* [in] */ BOOL fActivate){return S_OK;} + +STDMETHODIMP CMySite2::ResizeBorder( + /* [in] */ LPCRECT prcBorder, + /* [in] */ IOleInPlaceUIWindow __RPC_FAR *pUIWindow, + /* [in] */ BOOL fRameWindow) {return S_OK;} + +STDMETHODIMP CMySite2::TranslateAccelerator( //simon was here + /* [in] */ LPMSG lpMsg, + /* [in] */ const GUID __RPC_FAR *pguidCmdGroup, + /* [in] */ DWORD nCmdID) +{ +// printf("CMySite2::TranslateAccelerator\n");fflush(stdout); + if (lpMsg && lpMsg->message == WM_KEYDOWN){// && pMsg->wParam == VK_TAB) { + return S_FALSE; + } return E_NOTIMPL; +} + +STDMETHODIMP CMySite2::GetOptionKeyPath( + /* [out] */ LPOLESTR __RPC_FAR *pchKey, + /* [in] */ DWORD dw) {return E_NOTIMPL;} + +STDMETHODIMP CMySite2::GetDropTarget( + /* [in] */ IDropTarget __RPC_FAR *pDropTarget, + /* [out] */ IDropTarget __RPC_FAR *__RPC_FAR *ppDropTarget) {return E_NOTIMPL;} + +STDMETHODIMP CMySite2::GetExternal( /* [out] */ IDispatch __RPC_FAR *__RPC_FAR *ppDispatch) {return -1;} + +STDMETHODIMP CMySite2::TranslateUrl( + /* [in] */ DWORD dwTranslate, + /* [in] */ OLECHAR __RPC_FAR *pchURLIn, + /* [out] */ OLECHAR __RPC_FAR *__RPC_FAR *ppchURLOut) +{ + return S_FALSE; +// ppchURLOut=0; +// return S_OK; +} + +STDMETHODIMP CMySite2::GetHostInfo( + /* [out][in] */ DOCHOSTUIINFO __RPC_FAR *pInfo) +{ +// static DOCHOSTUIINFO pi; +// pi.cbSize=sizeof(pi); +// pi.dwFlags|=DOCHOSTUIFLAG_SCROLL_NO; +// pi.dwDoubleClick=0; +// pInfo=π +// pinfo.dwFlags|=DOCHOSTUIFLAG_SCROLL_NO; +// return S_OK; + return E_NOTIMPL; +} + +STDMETHODIMP CMySite2::FilterDataObject( + /* [in] */ IDataObject __RPC_FAR *pDO, + /* [out] */ IDataObject __RPC_FAR *__RPC_FAR *ppDORet) {return S_FALSE;} + + +STDMETHODIMP CMyFrame2::QueryInterface(REFIID riid,void ** ppvObject){ + TODO +} +STDMETHODIMP_(ULONG) CMyFrame2::AddRef(void){ + return 1; +} +STDMETHODIMP_(ULONG) CMyFrame2::Release(void){ + return 1; +} +STDMETHODIMP CMyFrame2::GetWindow(HWND FAR* lphwnd){ + *lphwnd=rep->hwnd; + return S_OK; +} +STDMETHODIMP CMyFrame2::ContextSensitiveHelp(BOOL fEnterMode){ + TODO +} +STDMETHODIMP CMyFrame2::GetBorder(LPRECT lprectBorder){ + TODO +} +STDMETHODIMP CMyFrame2::RequestBorderSpace(LPCBORDERWIDTHS pborderwidths){ + TODO +} +STDMETHODIMP CMyFrame2::SetBorderSpace(LPCBORDERWIDTHS pborderwidths){ + TODO +} +STDMETHODIMP CMyFrame2::SetActiveObject(IOleInPlaceActiveObject *pActiveObject,LPCOLESTR pszObjName){ + return S_OK; +} +STDMETHODIMP CMyFrame2::InsertMenus(HMENU hmenuShared,LPOLEMENUGROUPWIDTHS lpMenuWidths){ + TODO +} +STDMETHODIMP CMyFrame2::SetMenu(HMENU hmenuShared,HOLEMENU holemenu,HWND hwndActiveObject){ + return S_OK; +} +STDMETHODIMP CMyFrame2::RemoveMenus(HMENU hmenuShared){ + TODO +} +STDMETHODIMP CMyFrame2::SetStatusText(LPCOLESTR pszStatusText){ + return S_OK; +} +STDMETHODIMP CMyFrame2::EnableModeless(BOOL fEnable){ + return S_OK; +} +STDMETHODIMP CMyFrame2::TranslateAccelerator(LPMSG lpmsg,WORD wID){ + TODO +} + + + +ULONG __stdcall DWebBrowserEventsImpl2::AddRef() { return 1;} +ULONG __stdcall DWebBrowserEventsImpl2::Release() { return 0;} + +HRESULT __stdcall DWebBrowserEventsImpl2::QueryInterface(REFIID riid, LPVOID* ppv) +{ + *ppv = NULL; + + if (IID_IUnknown == riid || IID_DWebBrowserEvents2 == riid) //__uuidof(DWebBrowserEventsPtr) == riid) //was PTR + { + *ppv = (LPUNKNOWN)(DWebBrowserEventsPtr*)this; + AddRef(); + return NOERROR; + } + else if (IID_IOleClientSite == riid) + { + *ppv = (IOleClientSite*)this; + AddRef(); + return NOERROR; + } + else if (IID_IDispatch == riid) + { + *ppv = (IDispatch*)this; + AddRef(); + return NOERROR; + } + else + { + return E_NOTIMPL; + } +} + +// void BeforeNavigate2(IDispatch*, VARIANT*, VARIANT*, VARIANT*, VARIANT*, VARIANT*, VARIANT_BOOL*); + + +HRESULT __stdcall DWebBrowserEventsImpl2::Invoke(DISPID dispIdMember, + REFIID riid, + LCID lcid, + WORD wFlags, + DISPPARAMS __RPC_FAR *pDispParams, + VARIANT __RPC_FAR *pVarResult, + EXCEPINFO __RPC_FAR *pExcepInfo, + UINT __RPC_FAR *puArgErr) +{ + switch (dispIdMember) + { + case DISPID_BEFORENAVIGATE2: + BeforeNavigate2( + pDispParams->rgvarg[6].pdispVal, + pDispParams->rgvarg[5].pvarVal, + pDispParams->rgvarg[4].pvarVal, + pDispParams->rgvarg[3].pvarVal, + pDispParams->rgvarg[2].pvarVal, + pDispParams->rgvarg[1].pvarVal, + pDispParams->rgvarg[0].pboolVal); + break; + case DISPID_NEWWINDOW2: + NewWindow2( + pDispParams->rgvarg[1].ppdispVal, + pDispParams->rgvarg[0].pboolVal); //IDispatch**, VARIANT_BOOL* + break; + case DISPID_NAVIGATECOMPLETE2: + NavigateComplete(pDispParams->rgvarg[1].pdispVal,pDispParams->rgvarg[0].pvarVal); + break; + case DISPID_DOCUMENTCOMPLETE: + DocumentComplete(pDispParams->rgvarg[1].pdispVal,pDispParams->rgvarg[0].pvarVal); + break; + } + return NOERROR; +} + +// IDispatch methods +HRESULT __stdcall DWebBrowserEventsImpl2::GetTypeInfoCount(UINT* pctinfo) +{ + return E_NOTIMPL; +} + +HRESULT __stdcall DWebBrowserEventsImpl2::GetTypeInfo(UINT iTInfo, + LCID lcid, + ITypeInfo** ppTInfo) +{ + return E_NOTIMPL; +} + +HRESULT __stdcall DWebBrowserEventsImpl2::GetIDsOfNames(REFIID riid, + LPOLESTR* rgszNames, + UINT cNames, + LCID lcid, + DISPID* rgDispId) +{ + return E_NOTIMPL; +} + +// Methods: + +void DWebBrowserEventsImpl2::NewWindow2(IDispatch**pdisp, VARIANT_BOOL*Cancel) +{ +// *pdisp=rep->iBrowser; + *Cancel=VARIANT_TRUE;// was FALSE; +} + +void DWebBrowserEventsImpl2::BeforeNavigate2(IDispatch*, VARIANT*URL, VARIANT*, VARIANT*TARGET, VARIANT*, VARIANT*, VARIANT_BOOL*Cancel) +{ + BBString *url; + *Cancel=VARIANT_FALSE; + if (TARGET->bstrVal) { + return; + } + if ((rep->viewstyle&NONAVIGATE) && (rep->navcount==0)){ + *Cancel=VARIANT_TRUE; + url=bbStringFromVariant2(URL); + bbSystemEmitEvent( BBEVENT_GADGETACTION,rep->owner,0,0,0,0,(BBObject*)url ); + }else{ + rep->navcount=0; + } +} + +void DWebBrowserEventsImpl2::NavigateComplete ( IDispatch* pDisp,VARIANT*URL ) +{ +// printf("Navigate Complete!\n");fflush(stdout); +// rep->setcurrenturl(URL); +// rep->loading=0; +// rep->owner->emit( BBEVENT_GADGETDONE ); +// bbSystemEmitEvent( BBEVENT_GADGETDONE,rep->owner,0,0,0,0,BBNULL ); +} + +void DWebBrowserEventsImpl2::DocumentComplete ( IDispatch* pDisp,VARIANT*URL ) +{ +// printf("Document Complete!\n");fflush(stdout); + rep->setcurrenturl(URL); + rep->loading=0; +// rep->owner->emit( BBEVENT_GADGETDONE ); + bbSystemEmitEvent( BBEVENT_GADGETDONE,rep->owner,0,0,0,0,BBNULL ); +} + +HRESULT DWebBrowserEventsImpl2::StatusTextChange ( _bstr_t Text ) { return S_OK; } + +void DWebBrowserEventsImpl2::ProgressChange (long Progress,long ProgressMax ) {} +void DWebBrowserEventsImpl2::DownloadComplete() {} +void DWebBrowserEventsImpl2::CommandStateChange (long Command,VARIANT_BOOL Enable ) {} +void DWebBrowserEventsImpl2::DownloadBegin () {} + +HRESULT DWebBrowserEventsImpl2::NewWindow ( + _bstr_t URL, + long Flags, + _bstr_t TargetFrameName, + VARIANT * PostData, + _bstr_t Headers, + VARIANT_BOOL * Processed ) { return S_OK; } +HRESULT DWebBrowserEventsImpl2::TitleChange ( _bstr_t Text ) { return S_OK; } +HRESULT DWebBrowserEventsImpl2::FrameBeforeNavigate ( + _bstr_t URL, + long Flags, + _bstr_t TargetFrameName, + VARIANT * PostData, + _bstr_t Headers, + VARIANT_BOOL * Cancel ) { return S_OK; } +HRESULT DWebBrowserEventsImpl2::FrameNavigateComplete ( + _bstr_t URL ) { return S_OK; } +HRESULT DWebBrowserEventsImpl2::FrameNewWindow ( + _bstr_t URL, + long Flags, + _bstr_t TargetFrameName, + VARIANT * PostData, + _bstr_t Headers, + VARIANT_BOOL * Processed ) { return S_OK; } +HRESULT DWebBrowserEventsImpl2::Quit ( + VARIANT_BOOL * Cancel ) { return S_OK; } +HRESULT DWebBrowserEventsImpl2::WindowMove ( ) { return S_OK; } +HRESULT DWebBrowserEventsImpl2::WindowResize ( ) { return S_OK; } +HRESULT DWebBrowserEventsImpl2::WindowActivate ( ) { return S_OK; } +HRESULT DWebBrowserEventsImpl2::PropertyChange ( + _bstr_t Property ) { return S_OK; } + + +// C style public interface + +int msHtmlCreate( void *gadget,wchar_t *wndclass,int hwnd,int flags ){ + HTMLView *view; + view=new HTMLView((BBObject *)gadget,wndclass,(HWND)hwnd,flags); + return (int)view; +} + +void msHtmlGo( int handle,wchar_t *url ){ + HTMLView *view; + view=(HTMLView*)handle; + view->go(url); +} + +void msHtmlRun( int handle,wchar_t *script ){ + HTMLView *view; + view=(HTMLView*)handle; + view->run(script); +} + +void msHtmlSetShape( int handle,int x,int y,int w,int h ){ + HTMLView *view; + view=(HTMLView*)handle; + view->setshape(x,y,w,h); +} + +void msHtmlSetVisible( int handle,int visible ){ +} + +void msHtmlSetEnabled( int handle,int enabled ){ +} + +int msHtmlActivate(int handle,int cmd){ + HTMLView *view; + view=(HTMLView*)handle; + return view->activate(cmd); +} + +int msHtmlStatus(int handle){ + HTMLView *view; + view=(HTMLView*)handle; + return view->status(); +} + +int msHtmlHwnd( int handle ){ + HTMLView *view; + view=(HTMLView*)handle; + return (int)view->hwnd; +} + +void *msHtmlBrowser( int handle ){ + HTMLView *view; + view=(HTMLView*)handle; + return view->iBrowser; +} + diff --git a/mod/maxgui.mod/win32maxguiex.mod/mshtmlview.h b/mod/maxgui.mod/win32maxguiex.mod/mshtmlview.h new file mode 100644 index 0000000..d278d2c --- /dev/null +++ b/mod/maxgui.mod/win32maxguiex.mod/mshtmlview.h @@ -0,0 +1,23 @@ + +#ifndef MSHTMLVIEW_H +#define MSHTMLVIEW_H + +extern "C"{ + +int msHtmlCreate( void *gadget,wchar_t *wndclass,int hwnd,int flags ); + +void msHtmlGo( int handle,wchar_t *url ); +void msHtmlRun( int handle,wchar_t *script ); + +void msHtmlSetShape( int handle,int x,int y,int w,int h ); +void msHtmlSetVisible( int handle,int visible ); +void msHtmlSetEnabled( int handle,int enabled ); + +int msHtmlActivate(int handle,int cmd); +int msHtmlStatus(int handle); +int msHtmlHwnd( int handle ); +void *msHtmlBrowser( int handle ); + +}; + +#endif diff --git a/mod/maxgui.mod/win32maxguiex.mod/tom.bmx b/mod/maxgui.mod/win32maxguiex.mod/tom.bmx new file mode 100644 index 0000000..135220a --- /dev/null +++ b/mod/maxgui.mod/win32maxguiex.mod/tom.bmx @@ -0,0 +1,226 @@ +' tom.bmx + +Import pub.win32 + +Strict + +Const TOMTRUE = -1 +Const TOMFALSE = 0 +Const TOMNONE = 0 +Const TOMSINGLE = 1 +Const TOMWORDS = 2 +Const TOMDOUBLE = 3 +Const TOMDOTTED = 4 + +Extern "win32" + +Type IRichEditOLE Extends IUnknown + Method GetClientSite()' (THIS_ LPOLECLIENTSITE FAR * lplpolesite) PURE; + Method GetObjectCount()' (THIS) PURE; + Method GetLinkCount()' (THIS) PURE; + Method GetObject()' (THIS_ Long iob, REOBJECT FAR * lpreobject, DWORD dwFlags) PURE; + Method InsertObject()' (THIS_ REOBJECT FAR * lpreobject) PURE; + Method ConvertObject()' (THIS_ Long iob, REFCLSID rclsidNew, LPCSTR lpstrUserTypeNew) PURE; + Method ActivateAs()' (THIS_ REFCLSID rclsid, REFCLSID rclsidAs) PURE; + Method SetHostNames()' (THIS_ LPCSTR lpstrContainerApp, LPCSTR lpstrContainerObj) PURE; + Method SetLinkAvailable()' (THIS_ Long iob, BOOL fAvailable) PURE; + Method SetDvaspect()' (THIS_ Long iob, DWORD dvaspect) PURE; + Method HandsOffStorage()' (THIS_ Long iob) PURE; + Method SaveCompleted()' (THIS_ Long iob, LPSTORAGE lpstg) PURE; + Method InPlaceDeactivate()' (THIS) PURE; + Method ContextSensitiveHelp()' (THIS_ BOOL fEnterMode) PURE; + Method GetClipboardData()' (THIS_ CHARRANGE FAR * lpchrg, DWORD reco,LPDATAOBJECT FAR * lplpdataobj) PURE; + Method ImportDataObject()' (THIS_ LPDATAOBJECT lpdataobj,CLIPFORMAT cf, HGLOBAL hMetaPict) PURE; +End Type + +Const ITextDocument_UUID$="{8CC497C0-A1DF-11ce-8098-00AA0047BE5D}" + +Type ITextDocument Extends IDispatch + Method GetName() + Method GetSlection() + Method GetStoryCount( storycount:Int Var) + Method GetStoryRanges() + Method GetSaved() + Method SetSaved() + Method GetDefaultTabStop(Value# Var) + Method SetDefaultTabStop(Value#) + Method NewDocument() + Method Open() + Method Save() + Method Freeze(count Var) + Method UnFreeze(count Var) + Method BeginEditCollection() + Method EndEditCollection() + Method Undo() + Method Redo() + Method Range(p0,p1,irange:ITextRange Var) + Method RangeFromPoint(x,y,irange:ITextRange Var) +End Type + +Type ITextRange Extends IDispatch + Method GetText(bstr:Short Ptr Ptr) + Method SetText(bstr:Short Ptr) + Method GetChar() + Method SetChar() + Method GetDuplicate(irange:ITextRange Var) + Method GetFormattedText() + Method SetFormattedText() + Method GetStart() + Method SetStart() + Method GetEnd() + Method SetEnd() + Method GetFont(ifont:ITextFont Var) + Method SetFont(ifont:ITextFont) + Method GetPara(para:ITextPara Var) + Method SetPara(para:ITextPara) + Method GetStoryLength( length:Int Var ) + Method GetStoryType( storytype:Int Var) + Method Collapse() + Method Expand() + Method GetIndex() + Method SetIndex() + Method SetRange(cp1,cp2) + Method InRange() + Method InStory() + Method IsEqual() + Method Select_() + Method StartOf() + Method EndOf() + Method Move() + Method MoveStart() + Method MoveEnd() + Method MoveWhile() + Method MoveStartWhile() + Method MoveEndWhile() + Method MoveUntil() + Method MoveStartUntil() + Method MoveEndUntil() + Method FindText() + Method FindTextStart() + Method FindTextEnd() + Method Delete_() + Method Cut() + Method Copy() + Method Paste() + Method CanPaste() + Method CanEdit(bool Var) + Method ChangeCase() + Method GetPoint() + Method SetPoint() + Method ScrollIntoView() + Method GetEmbeddedObject() +EndType + +Type ITextFont Extends IDispatch + Method GetDuplicate(ifont:ITextFont Var) + Method SetDuplicate() + Method CanChange() + Method IsEqual() + Method Reset() + Method GetStyle(Value:Int Ptr) + Method SetStyle(Value) + Method GetAllCaps(Value:Int Ptr) + Method SetAllCaps(Value) + Method GetAnimation(Value:Int Ptr) + Method SetAnimation(Value) + Method GetBackColor(Value:Int Ptr) + Method SetBackColor(Value) + Method GetBold(Value:Int Ptr) + Method SetBold(Value) + Method GetEmboss(Value:Int Ptr) + Method SetEmboss(Value) + Method GetForeColor(Value:Int Ptr) + Method SetForeColor(Value) + Method GetHidden(Value:Int Ptr) + Method SetHidden(Value) + Method GetEngrave(Value:Int Ptr) + Method SetEngrave(Value) + Method GetItalic(Value:Int Ptr) + Method SetItalic(Value) + Method GetKerning(Value:Int Ptr) + Method SetKerning(Value) + Method GetLanguageID() + Method SetLanguageID() + Method GetName() + Method SetName() + Method GetOutline(Value:Int Ptr) + Method SetOutline(Value) + Method GetPosition(Value:Int Ptr) + Method SetPosition(Value) + Method GetProtected(Value:Int Ptr) + Method SetProtected(Value) + Method GetShadow(Value:Int Ptr) + Method SetShadow(Value) + Method GetSize(Value:Int Ptr) + Method SetSize(Value) + Method GetSmallCaps(Value:Int Ptr) + Method SetSmallCaps(Value) + Method GetSpacing(Value:Int Ptr) + Method SetSpacing(Value) + Method GetStrikeThrough(Value:Int Ptr) + Method SetStrikeThrough(Value) + Method GetSubscript(Value:Int Ptr) + Method SetSubscript(Value) + Method GetSuperscript(Value:Int Ptr) + Method SetSuperscript(Value) + Method GetUnderline(Value:Int Ptr) + Method SetUnderline(Value) + Method GetWeight(Value:Int Ptr) + Method SetWeight(Value) +End Type + +Const ITextPara_UUID$="{8CC497C4-A1DF-11ce-8098-00AA0047BE5D}" + +Type ITextPara Extends IDispatch + Method GetDuplicate(ipara:ITextPara Var) + Method SetDuplicate() + Method CanChange() + Method IsEqual(para) + Method Reset(value) + Method GetStyle() + Method SetStyle(value) + Method GetAlignment() + Method SetAlignment(value) + Method GetHyphenation() + Method SetHyphenation(value) + Method GetFirstLineIndent() + Method GetKeepTogether() + Method SetKeepTogether(value) + Method GetKeepWithNext() + Method SetKeepWithNext(value) + Method GetLeftIndent#() + Method GetLineSpacing#() + Method GetLineSpacingRule() + Method GetListAlignment() + Method SetListAlignment( value) + Method GetListLevelIndex() + Method SetListLevelIndex(value) + Method GetListStart() + Method SetListStart(value) + Method GetListTab#() + Method SetListTab(value#) + Method GetListType() + Method SetListType(value) + Method GetNoLineNumber() + Method SetNoLineNumber(value) + Method GetPageBreakBefore() + Method SetPageBreakBefore(value) + Method GetRightIndent#() + Method SetRightIndent(value#) + Method SetIndents(startindent#,leftindent#,rightindent#) + Method SetLineSpacing( rule,spacing# ) + Method GetSpaceAfter() + Method SetSpaceAfter(value#) + Method GetSpaceBefore#() + Method SetSpaceBefore(value#) + Method GetWidowControl() + Method SetWidowControl(value) + Method GetTabCount( ) + Method AddTab( pos#,align,leader ) + Method ClearAllTabs() + Method DeleteTab(pos#) + Method GetTab(tab,pos,align,leader) +End Type + + +End Extern diff --git a/mod/maxgui.mod/win32maxguiex.mod/version.txt b/mod/maxgui.mod/win32maxguiex.mod/version.txt new file mode 100644 index 0000000..3b1bea9 --- /dev/null +++ b/mod/maxgui.mod/win32maxguiex.mod/version.txt @@ -0,0 +1,279 @@ +0.75 Relase +Added UserName and ComputerName driver methods +0.74 Release +Moved xpmanifest.o to it's own module MaxGUI.XPManifest +Added RemoveColor interface +Modified licence +Removed composite mode bit banging in window resizing states /topic=91447 +0.73 Release +Added GetStatusText() implementation. +0.72 Release +Added support for PANEL_RAISED style flag. +Implemented grable's OnCommand() tweak. +Fixed ActiveGadget() returning Null when HTMLViews have focus. +0.71 Release +Cleaned up TWindowsFont so that RequestFont() should now return expected results. +0.70 Release +Fixed tabber icons not being set. +0.69b Release +Windows are now only revealed when they are correctly positioned, to avoid momentary flicker. +0.69 Release +Task-bar area should now no longer be included when querying workspace dimensions. +Added LookupColor() method to TWindowsGUIDriver. +0.68b Release +Committed ListBox Slider glitch workaround for Grisu. +0.68 Release +Suppressed hotkeys with modifiers from being passed to graphics contexts/active panels. +Combined BitmapFromPixmap24 and BitmapFromPixmap32 into one function. +Swapped out String-based hWnd TMap for more efficient TIntWrapper equivalent. +Fixed HtmlViewCurrentUrl() and associated memory leak(s). +0.67 Release +Added hack to stop scroll-bars re-enabling when range is changed. +Silenced system beep with 'Alt' hotkeys. +0.66 Release +Fixed a textarea redraw problem, and added hack to fix cursor sometimes getting stuck on 'busy' when highlighting. +Improved handling of 'Alt' and firing of events when keys are hotkeys. +Optimized brush transparency code by caching brushes. +HotKey fix for modifiers. +Disabling a panel should now grey out all of its children. +State() is now no longer recursive. +Toolbars now push down the client area of the parent window. +Tidying up of some of the window sizing code. +Attempt to fix some drawing slow-downs/bugs. +0.65 Release +Made use of TGadget's style field instead of additional _style. +Fixed RequestFont() bug - thanks klepto2! +Fixed toolbar ListItemState() and loss of state on ModifyGadgetItem. +Fixed recursive PopupWindowMenu event extra bug when using hooks. +Standard checkboxes/radio-buttons now support text colors, but do so by losing theming. +Fixed hotkey focus issues for window menus. +Added recursive owner.source handling to SystemEmitOSEvent. +0.64 Release +SelectTreeViewNode(TreeViewRoot(treeView)) now deselects the currently selected node. +RichEdit 4.1 should now be used when available. +Controls will now only be double-buffered on Windows Vista (or higher) by default. +0.63 Release +Graphics contexts are now closed automatically when a canvas is freed. +Resizable windows with a maximum size set can no longer be maximized. +0.62 Release +Changed handling of '-1' icons in listboxes and toolbars. +0.61 Release +Added workaround for flipped vertical trackbar. +Corrected insert node index behaviour. +Fixed GetText() on tree-view nodes. +Tweaked SetIconStrip() for list based gadgets. +0.60 Release +Fixed memory exception when freeing a treeview node accidentally a second time. +Fixed htmlview GetText implementation. +0.59 Release +Maintenance release. +0.58 Release +Added calls so that the client position is updated when tab items are set. +0.57 Release +Added new iconless window class for child windows. +Swapped slider API messages for their 32-bit signed counterparts. +0.56 Release +Tweaked the appearance of LABEL_SEPARATOR. +Silenced EVENT_GADGETSELECT event emitted when a selected list item was removed. +Fixed mouse capture handling (again!) when holding more than one mouse button down. +0.55 Release +Added EVENT_GADGETMENU for tabbers. +Added CharX() and CharY() methods to TWindowsTextArea. +Fixed UnlockText() selection error that was causing erratic highlighting when block-indenting/outdenting code in the IDE. +Fixed SetGadgetPixmap() and SetGadgetText() bug. +Added GadgetCut(), GadgetCopy() and GadgetPaste() to textfields and editable comboboxes. +Added preliminary support for text and background colours on standard push buttons (no icon/pixmap support atm). +0.54 Release +Removed the DebugLog calls. +Fixed Windows 9X infinite loops from client hwnd CallWindowProc in TWindowsGUIDriver.ClassWndProc. +0.53 Release +Fixed missing event from tabber when removing items. +Fixed definition clash with mshtmlview.cpp and MaxGUI.Win32MaxGUI's win32htmlview.cpp. +0.52 Release +Added LockText() and UnlockText() selection code. +Fixed font-size rounding error. +Fixed more window hiding bugs with windows whose children have focus. +Fixed toolbar accepting files as drop-target without window having WINDOW_ACCEPTFILES flag. +Fixed SetGadgetSensitivity() mouse-click events where possible by implementing new system mouse hook. +Further improved the reliability of TWindowsFont.GetDefault(). +Added new BUTTON_PUSH support for radio/checkboxes. +Added symbol based font loading (e.g. Wingdings) and fixed tiny font memory leak. +Added LibraryFont() method to TWindowsGUIDriver. +Implemented quick-hack so that editable comboboxes are redrawn after the window has been moved. +0.51 Release +Fixed the TWindowsHTMLView x/y-coordinate bug when not positioned at 0,0. +0.50 Release +Added new Class() method to return a gadget's class for the new GadgetClass() function. +Plugged memory leaks from GetDC. +Events should now be silenced if generated while attemping to free a treeview node. +0.49 Release +Fixed button tooltips disappearing permanently on Windows XP. +Fixed resetting gadget tooltips using SetGadgetTooltip. +Gadgets should now respond to GetSensitivity() and SetSensitivity() methods. +0.48 Release +Removed redundant ATL code from Skid's original BlitzMax-based HTMLView. +Added hack to address XP's resistance to hide text when BS_BITMAP is set. +The drawing context is now saved/restored whenever the background is painted to fix font problems. +Fixed separators - they can now be horizontal or vertical but restricted to 4 pixels thick. +Reduced flickering when *moving* a window with an editable combobox on it. +Fixed conflicting WS_EX_COMPOSITED and WS_EX_LAYERED flags on windows. +Fixed slider redraw problems on XP. +Fixed treeview memory leak by releasing integer memory handle. +Removed WS_EX_TRANSPARENT from group panels as it was causing strange drawing problems on XP. +Fixed ComboBox GetText() method so text is retrieved even if it isn't COMBOBOX_EDITABLE. +Added support for toggle buttons on toolbars. +More events should now be suppressed if triggered programatically by using Sensitize()/Desensitize() pairs. +0.47 Release +Fixed XP tab-background redraw problem. +Added preliminary SetGadgetTooltip() support for non-item based gadgets. +Added SetPixmap() support for push-buttons and menus. +Added fix to prevent hot-key events being generated when the source gadget is disabled. +Added fix to remove hotkey before calling SetGadgetHotKey(). +Introduced possible fix for requester parenting bug. +Plugged a tiny memory leak when freeing gadgets. +0.46 Release +Fixed text-field text colour. +Added the WS_EX_TRANSPARENT and WS_CLIPCHILDREN flags to group-boxes to speed-up redraw. +Implemented BeginDeferWindowsPos(), DeferWindowPos(), and EndWindowPos(). +Fixed DC memory leaks as a result of incorrectly using ReleaseDC() instead of DeleteDC(). +Improved client dimensions methods so that they work independent of resize stage. +0.45 Release +Moved most externs and imports to a separate file 'winimports.bmx'. +Improved PANEL_GROUP drawing, and a few other transparency problems. +Improved redraw on resize by moving LayoutKids() to WM_SIZE, and adding WS_EX_COMPOSITED. +Implemented hack that should hopefully fix the text-area's ghost scroll bar glitch when resizing. +Added fix which resizes the tabber's client when an icon strip is set. +0.44 Release +Changed tabber tool-tip handling to use TCM_HITTEST message. +Fixed tab control up-down arrows being unresponsive. +0.43 Release +Fixed SetGadgetText() with treeview node. +Fixed FreeGadget() memory leak by adding _SetParent Null. +Fixed Windows Classic panel redraw issues. +0.42 Release +Fixed some treeview icon handling problems, and removed (now redundant) TVN_GETDISPINFO notification processing. +Cleaned up ToWString() calls to fix memory leaks. +0.41 Release +Added checks in mshtmlview.cpp to prevent text being Cut/Copied/Pasted when it shouldn't. +Added fix to stop black tick bands forming when using large range values on small track-bars. +Added a quick-hack that should greatly speed-up resizing/repositioning of gadgets, including when resizing windows. +Fixed a few loose-ends concerning tabber/panel WM_ERASEBKGND. +Fixed a few problems with WM_SIZE handling in TWindowsWindow.WndProc(). +Added some more constants to tom.bmx, and fixed text underlining style. +0.40 Release +Implemented proper GadgetPrint() support for text areas so that printing is done internally, as rich text. ;-) +Fixed tree-view parent status redraw issue when the first child is added/last child is removed. +0.39 Release +Implemented RequestColor() proper custom-color support that saves colours between calls. +Fixed tool-tips - list-boxes use LVN_GETINFOTIPW, and tabbers use TTN_GETDISPINFOW. +Fixed XP background drawing issue on text-boxes by removing SetBkMode, and adding SetBkColor. +0.38 Release +Added TWindowsGUIDriver.CreateExplorerStyleGadgets() +Fixed WINDOW_CLIENTCOORDS dimensions with WINDOW_MENU flag. +Fixed child window focus problem when maximising windows. +Added double-buffering support of treeviews/listboxes, as well as UseExplorerTheme() methods. +Added WS_CLIPSIBLINGS to text-area control. +0.37 Release +Added DestroyMenu() to UpdateWindowMenu() method to fix severe desktop heap memory leakage. +Fixed Grisu's list-box resize bug by moving LVM_SETCOLUMNWIDTH to Rethink() method. +Added TreeView icon support, changed Spawn() so that it is now called by the child node (tidier). +Moved pixmap background drawing to WM_ERASEBKGND, and modified so that only update region is drawn. +Improved panel alpha support somewhat, and implemented correct handling of alpha pixmaps in SetPixmap(). +Fixed icon strip corruption when not using ComCtl32.dll v6 or higher (see TWindowsGUIDriver.CheckCommonControlVersion() ). +Moved Bitmap functions to TWindowsGraphic and added BitmapMaskFromPixmap() and PreMultipliedBitmapFromPixmap32(). +0.36 Release +Fixed themed button drawing problems. +Changed default _textcolor value to -1. +0.35 Release +Added ClassWndProc SetPointer fix. +Fixed major redraw issues with gadgets. +Fixed window positioning problem. +0.34 Release +Fixed and re-implemented client panels for tabbers/windows. +Tidied up colour handling code. +Fixed SetMinWindowSize() for WINDOW_CLIENTCOORDS. +Added internal method for converting Window client dimensions into container dimensions. +0.33 Release +Treeview nodes now handle expansion of childless parents, removed .30 cludge +0.32 Release +Stopped mouse wheel events being generated on non-active panels. +Fixed recurring EVENT_MOUSEMOVE events. +Fixed panel drawing bug when changing pixmaps. +0.31 Release +Added menu SetText() method. +Improved PANEL_GROUP colour support. +Added LABEL_SEPARATOR support. +Fixed EVENT_MENUACTION so that that the menu is specified in the source. +Improved window behaviour slightly. +0.30 Release +InsertNode expands on first child to fix isparent status bug in treeviews +0.29 Release +added alpha support for windows (Windows 2000 or higher only) +added improved color support for windows, labels, text-fields, list-boxes and combo-boxes +added GetText() method +added menu hotkey text for special keys +changed manifest to one without an icon +0.28 Release +new native msHtmlView implementation added +0.27 Release +added Seb's setstyle tweaks +fixed blank readonly textareas, fixed window minimize event +0.26 Release +fixed list selection width +0.25 Release +fixed menu open states, faster TOM based richedit +0.24 Release +fixed new tabber size, fixed onnotify filter results, optimized SetStyle +0.23 Release +replaced client hwnds in windows and tabbers with setclienthandle +0.22 Release +fixes for treeview/nodes including CountKids SelectedNode ModifyNode/SetText +0.21 Release +fixed textfield event on settext bug +0.20 Release +fixed event extra field for select and action events +0.19 Release +fixed windowresize from top left messaging +0.18 Release +fixed alphablend clash with max2d +0.17 Release +added 32 bit panelpixmaps, fixed toolbar tips, checked extra events, unborked filter contexts +0.16 Release +fixed select treeviewnode and window clientcoord issues +0.15 Release +Fixed eventextra in events, and list item selection widths +0.14 Release +Fixed comboboxes and cursor repositioning with settextareatext +0.13 Release +Embedded manifest and added 32bit support for toolbars +0.12 Release +Fixed tabber client, autoscrollbar bug, menuevents, sliders +0.11 Release +Fixed toolbar width +Removed clientedge property from nonpanels +0.10 Release +Fixed sliders +Added TextField event handler +Fixed CharAt(line) method in TWindowsTextArea +Fixed scrollbars +0.09 Release +Fixed Dialog tabbing, OK buttons and TextField tabstops +New SetColor and SetTextColor methods +Fixed menu GetText method +0.08 Release +Fixed toolbar separators, new desktop object +eventwindowsize, gadget.setfont, +0.07 Release +Fixed gadget state reporting and implemented Menu states +Fixed non active CreateCanvas and WM_CLOSE window handling +Added HWND_TOPMOST property for WINDOW_TOOL style +0.06 Release +Fixed default font, implemented WINDOW_ACCEPTFILES +0.05 Release +Fixed menu parenting to window, PANELGROUP redraws and icon states +0.04 Release +Fixed button state, added menu DoLayout override +0.03 Release +Added basic constructors for all TGadget types +0.02 Release +Changed to Unicode, TWindowsGadget:HwndProc connected diff --git a/mod/maxgui.mod/win32maxguiex.mod/win32maxguiex.bmx b/mod/maxgui.mod/win32maxguiex.mod/win32maxguiex.bmx new file mode 100644 index 0000000..4e3f8fe --- /dev/null +++ b/mod/maxgui.mod/win32maxguiex.mod/win32maxguiex.bmx @@ -0,0 +1,5053 @@ +Rem +bbdoc: MaxGUI Drivers/Win32MaxGUIEx +End Rem +Module MaxGUI.Win32MaxGUIEx + +ModuleInfo "Version: 0.75" +ModuleInfo "Author: Simon Armstrong, Seb Hollington" +ModuleInfo "License: zlib/libpng" + +Strict + +?Win32 +Import MaxGUI.MaxGUI +Import "winimports.bmx" + +' Import "xpmanifest.o" + +maxgui_driver = New TWindowsGUIDriver + +Type TWindowsGUIDriver Extends TMaxGUIDriver + + Global GadgetMap:TMap + Global GDIDesktop:TWindowsDesktop + Global GDIFont:TWindowsFont + Global ClassAtom + Global ClassAtom2 + Global KBMessageHook,MouseMessageHook + + Global windowtheme:Short Ptr + Global _cursor, _commoncontrolversion[] + Global _explorerstyle = False + Global _activeWindow:TWindowsWindow = Null + + Global _customcolors[] = [$FFFFFF, $FFFFFF, $FFFFFF, $FFFFFF, $FFFFFF, $FFFFFF, $FFFFFF, $FFFFFF, .. + $FFFFFF, $FFFFFF, $FFFFFF, $FFFFFF, $FFFFFF, $FFFFFF, $FFFFFF, $FFFFFF ] + + Global _hwndTooltips% + + Global intDontReleaseCapture% = False 'See WM_CAPTURECHANGED + + Method New() + + 'Initialize libraries + OleInitialize(Null) + Local icc:TINITCOMMONCONTROLSEX = New TINITCOMMONCONTROLSEX + icc.dwSize = SizeOf(icc) + icc.dwICC = ICC_WIN95_CLASSES|ICC_USEREX_CLASSES'|ICC_COOL_CLASSES'|ICC_DATE_CLASSES + InitCommonControlsEx icc + + 'Initialize Global Variables + GDIFont=TWindowsFont.DefaultFont() + GadgetMap=New TMap + GDIDesktop=New TWindowsDesktop + + 'Set-up Message Hooks + KBMessageHook=SetWindowsHookExW(WH_KEYBOARD,KeyboardProc,GetModuleHandleW(Null),GetCurrentThreadId()) + MouseMessageHook=SetWindowsHookExW(WH_MOUSE,MouseProc,GetModuleHandleW(Null),GetCurrentThreadId()) + + 'Gadget Tooltips + _hwndTooltips = CreateWindowExW( 0,"tooltips_class32","",WS_POPUP|TTS_ALWAYSTIP,0,0,0,0,GDIDesktop._hwnd,0,GetModuleHandleW(Null),Null ) + SendMessageW( _hwndTooltips, TTM_SETMAXTIPWIDTH, 0, 300 ) + SetWindowPos( _hwndTooltips, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE ) + + EndMethod + + Method Delete() + DestroyWindow( _hwndTooltips );_hwndTooltips = 0 + UnhookWindowsHookEx MouseMessageHook + UnhookWindowsHookEx KBMessageHook + EndMethod + + Method UserName$() + Return getenv_("username") + End Method + + Method ComputerName$() + Return getenv_("userdomain") + End Method + + 'Low-level Win32 interface + + Function RegisterHwnd(hwnd,gadget:TWindowsGadget) + GadgetMap.Insert TIntWrapper.Create(hwnd),gadget + EndFunction + + Function RemoveHwnd(hwnd) + GadgetMap.Remove TIntWrapper.Create(hwnd) + EndFunction + + Function GadgetFromHwnd:TWindowsGadget(hwnd) nodebug + Return TWindowsGadget(GadgetMap.ValueForKey(TIntWrapper.Create(hwnd))) + EndFunction + + Function ClassWndProc(hwnd,msg,wp,lp) "win32" + Local owner:TWindowsGadget + Local res + Local nmhdr:Int Ptr + + '?Debug And Win32 + 'Print TWindowsDebug.ReverseLookupMsg(msg) + ", hwnd: " + hwnd + ", wp: " + wp + ", lp: " + lp + '?Win32 + + Select msg + + Case WM_MENUCHAR + + If HotKeyEventFromWp(wp & $FF) Then + Return (MNC_CLOSE Shl 16) + Else + Return (MNC_IGNORE Shl 16) + EndIf + + Case WM_SIZE + + owner = GadgetFromHwnd(hwnd) + If owner And Not TWindowsWindow(owner) Then + If hwnd = owner.Query(QUERY_HWND) Then owner.RethinkClient() + If hwnd = owner.Query(QUERY_HWND_CLIENT) Then owner.LayoutKids() + EndIf + + Case WM_CTLCOLORSTATIC, WM_CTLCOLOREDIT, WM_CTLCOLORBTN + + owner=GadgetFromHwnd(lp) + + Select True + + Case TWindowsLabel(owner) <> Null + + SetBkMode(wp, TRANSPARENT) + If owner.FgColor() > -1 Then SetTextColor_(wp, owner.FgColor()) + Return owner.CreateControlBrush( owner._hwnd, wp ) + + Case TWindowsPanel(owner) <> Null + + If TWindowsPanel(owner)._type = TWindowsPanel.PANELGROUP Then + + SetBkMode(wp, TRANSPARENT) + If owner.FgColor() > -1 Then SetTextColor_(wp, owner.FgColor()) + Return owner.CreateControlBrush( lp, wp ) + + EndIf + + Case TWindowsTextField(owner) <> Null, TWindowsComboBox(owner) <> Null + + If owner.FgColor() > -1 Then SetTextColor_(wp, owner.FgColor()) + If owner.BgBrush() Then SetBkColor(wp, owner.BgColor());Return owner.BgBrush() + + Case TWindowsButton(owner) <> Null, TWindowsSlider(owner) <> Null + + SetBkMode(wp, TRANSPARENT) + If owner.FgColor() > -1 Then SetTextColor_(wp, owner.FgColor()) + Return owner.CreateControlBrush( owner._hwnd, wp ) + + EndSelect + + owner = Null + + Case WM_COMMAND,WM_HSCROLL,WM_VSCROLL + If lp Then + owner=GadgetFromHwnd(lp) + 'Fix for tab control's up/down arrow. + If Not owner Then owner = GadgetFromHwnd(GetParent_(lp)) + Else + owner=GadgetFromHwnd(hwnd) 'Fixed for menu events + EndIf + + If Not owner Then owner = GadgetFromHwnd(hwnd) + + If owner Then + res=owner.OnCommand(msg,wp) + If Not res And owner._proc And owner._hwnd = hwnd Return CallWindowProcW(owner._proc,hwnd,msg,wp,lp) + Return res + Else + Return DefWindowProcW( hwnd,msg,wp,lp ) + EndIf + + Case WM_NOTIFY + + 'Gadget tooltips + nmhdr=Int Ptr(lp) + owner=GadgetFromHwnd(nmhdr[0]) + If owner Then + Select nmhdr[2] + Case TTN_GETDISPINFOW + If owner._wstrTooltip Then nmhdr[3] = Int(owner._wstrTooltip) + EndSelect + Return owner.OnNotify(wp,lp) + EndIf + + Case WM_SETCURSOR + + If _cursor Then + SetCursor(_cursor) + Return 1 + EndIf + + Case WM_ACTIVATEAPP, WM_ACTIVATE + + SystemEmitOSEvent(hwnd,msg,wp,lp,Null) + + Case WM_DRAWITEM + + Local tmpDrawItemStruct:DRAWITEMSTRUCT = New DRAWITEMSTRUCT + MemCopy tmpDrawItemStruct, Byte Ptr lp, SizeOf(tmpDrawItemStruct) + + owner = GadgetFromHwnd(tmpDrawItemStruct.hwndItem) + If owner And owner.OnDrawItem( tmpDrawItemStruct ) Then Return True + + owner = Null + + 'Allow BRL.System to handle mouse/key events on sensitive gadgets. + + Case WM_CAPTURECHANGED + + 'For preventing problem where controls which called SetCapture() internally + 'had their capture prematurely released by the ReleaseCapture() call in BRL.System. + intDontReleaseCapture = False + 'If SetCapture() is called again after BRL.System's call (when the new + 'capture hwnd [lp] = old hwnd [hwnd]) then we dont want to call ReleaseCapture() in BRL.System + 'when WM_MOUSEBUTTONUP is received by the system hook TWindowsGUIDriver.MouseProc(). + If (lp = hwnd) And (Not intEmitOSEvent) Then intDontReleaseCapture = True + + Default + + 'Added preliminary check to avoid searching for a gadget in GadgetMap un-necessarily. + If (msg = WM_MOUSEWHEEL) Or (msg = WM_MOUSELEAVE) Or (msg>=WM_KEYFIRST And msg<=WM_KEYLAST) Then + owner=GadgetFromHwnd(hwnd) + If owner Then + Select msg + Case WM_MOUSELEAVE, WM_MOUSEWHEEL + If (owner.sensitivity&SENSITIZE_MOUSE) Then SystemEmitOSEvent hwnd,msg,wp,lp,owner + Case WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN, WM_SYSKEYUP, WM_CHAR, WM_SYSCHAR + If (owner.sensitivity&SENSITIZE_KEYS) And Not GadgetDisabled(owner) Then + SystemEmitOSEvent hwnd,msg,wp,lp,owner + EndIf + If (msg<>WM_CHAR And msg<>WM_SYSCHAR) And HotKeyEventFromWp(wp) Then Return 1 + EndSelect + EndIf + EndIf + + EndSelect + + If Not owner Then owner=GadgetFromHwnd(hwnd) + If owner Return owner.WndProc(hwnd,msg,wp,lp) + + Return DefWindowProcW( hwnd,msg,wp,lp ) + + EndFunction + + Function KeyboardProc( code,wparam,lparam ) "win32" nodebug + Local ev:TEvent, hwnd%, tmpClassName:Short[16], mods:Int, key:Int = wparam + If code>=0 Then + 'Removed: http://www.blitzbasic.com/Community/posts.php?topic=72737 +' Rem + If wparam = $D Then '$D: VK_RETURN + hwnd = GetFocus() + If hwnd And GetClassNameW(hwnd,tmpClassName,tmpClassName.length) And String.FromWString(tmpClassName).ToUpper() = "EDIT" Then + SetFocus(GetParent_(hwnd)) + EndIf + EndIf +' EndRem + + ev = HotkeyEventFromWp(wparam) + If ev + 'Hot-key events shouldn't be emitted if the source gadget is disabled + If Not(TGadget(ev.source) And GadgetDisabled(TGadget(ev.source))) Then + If Not (lparam & $80000000) Then + EmitEvent ev + If ev.mods Then Return 1 'Key press events never reach active panels etc. if we return 1 + EndIf + EndIf + EndIf + EndIf + Return CallNextHookEx( KBMessageHook,code,wparam,lparam ); + EndFunction + + Function HotkeyEventFromWp:TEvent(wparam) + Local key = wparam, mods = KeyMods() + Select wparam + Case VK_SHIFT, $A0, $A1 + If (wparam=VK_SHIFT) Then key = KEY_LSHIFT + mods:&~MODIFIER_SHIFT + Case VK_CONTROL, $A2, $A3 + If (wparam=VK_CONTROL) Then key = KEY_LCONTROL + mods:&~MODIFIER_CONTROL + Case VK_MENU, $A4, $A5 + If (wparam=VK_MENU) Then key = KEY_LALT + mods:&~MODIFIER_ALT + Case VK_LWIN, VK_RWIN + mods:&~MODIFIER_SYSTEM + EndSelect + Return HotKeyEvent( key,mods,GetForegroundWindow() ) + EndFunction + + Global intButtonStates%[3] + + Function MouseProc( code,wparam,lparam ) "win32" nodebug + + If code>=0 And wparam >= WM_MOUSEFIRST And wparam <= WM_MOUSELAST Then 'Not needed as MouseProc only receives mouse messages!!! + + Local MOUSEHOOKSTRUCT:Int Ptr = Int Ptr(lparam), wp, lp, data + Local hwnd% = MOUSEHOOKSTRUCT[2], msg% = wparam, owner:TWindowsGadget + Local point:Int[] = [MOUSEHOOKSTRUCT[0],MOUSEHOOKSTRUCT[1]] + + Select msg + Case WM_LBUTTONDOWN, WM_LBUTTONDBLCLK + data = MOUSE_LEFT + msg = WM_LBUTTONDOWN + intButtonStates[MOUSE_LEFT] = True + Case WM_LBUTTONUP + data = MOUSE_LEFT + intButtonStates[MOUSE_LEFT] = False + Case WM_RBUTTONDOWN, WM_RBUTTONDBLCLK + data = MOUSE_RIGHT + msg = WM_RBUTTONDOWN + intButtonStates[MOUSE_RIGHT] = True + Case WM_RBUTTONUP + data = MOUSE_RIGHT + intButtonStates[MOUSE_RIGHT] = False + Case WM_MBUTTONDOWN, WM_MBUTTONDBLCLK + data = MOUSE_MIDDLE + msg = WM_MBUTTONDOWN + intButtonStates[MOUSE_MIDDLE] = True + Case WM_MBUTTONUP + data = MOUSE_MIDDLE + intButtonStates[MOUSE_MIDDLE] = False + EndSelect + + owner = GadgetFromHwnd(hwnd) + If owner And ScreenToClient( hwnd, point ) Then + + If data And (Not intButtonStates[data]) And TGadget.dragGadget[data-1] Then + PostGuiEvent EVENT_GADGETDROP, owner, data, KeyMods(), point[0], point[1], TGadget.dragGadget[data-1] + TGadget.dragGadget[data-1] = Null + EndIf + + If (owner.sensitivity&SENSITIZE_MOUSE) Then + + 'Fake wp parameter to pass onto bbSystemEmitOSEvent + If intButtonStates[MOUSE_LEFT] Then wp:|MK_LBUTTON + If intButtonStates[MOUSE_MIDDLE] Then wp:|MK_MBUTTON + If intButtonStates[MOUSE_RIGHT] Then wp:|MK_RBUTTON + If GetKeyState(VK_SHIFT)&$8000 Then wp:|MK_SHIFT + If GetKeyState(VK_CONTROL)&$8000 Then wp:|MK_CONTROL + + lp = (Short(point[1]) Shl 16) | Short(point[0]) + 'Sort and determine whether to emit the event + Select msg + Case WM_MOUSEMOVE + If (owner._oldcursorlp<>lp) Then + owner._oldcursorlp=lp + SystemEmitOSEvent hwnd,msg,wp,lp,owner + EndIf + Case WM_LBUTTONUP, WM_RBUTTONUP, WM_MBUTTONUP + If intDontReleaseCapture Then + PostGuiEvent EVENT_MOUSEUP, owner, data + Else + SystemEmitOSEvent hwnd,msg,wp,lp,owner + EndIf + Case WM_LBUTTONDOWN, WM_RBUTTONDOWN, WM_MBUTTONDOWN + SystemEmitOSEvent hwnd,msg,wp,lp,owner + EndSelect + + EndIf + EndIf + EndIf + Return CallNextHookEx( MouseMessageHook,code,wparam,lparam ) + EndFunction + + Global intEmitOSEvent + + Function SystemEmitOSEvent( hwnd, msg, wp, lp, owner:TGadget ) + intEmitOSEvent:+1 + If owner Then + While owner.source + owner = owner.source + Wend + EndIf + Local tmpResult% = bbSystemEmitOSEvent( hwnd, msg, wp, lp, owner ) + intEmitOSEvent:-1 + Return tmpResult + EndFunction + + Function ClassName$() + Global _name$ + Global _wc:WNDCLASSW + Global _icon + + If Not _name + _name="BLITZMAX_WINDOW_CLASS" + _icon=LoadIconW(GetModuleHandleW(Null),Short Ptr(101)) + _wc=New WNDCLASSW + _wc.style=CS_OWNDC|CS_HREDRAW|CS_VREDRAW + _wc.lpfnWndProc=ClassWndProc + _wc.hInstance=GetModuleHandleW(Null) + _wc.hIcon=_icon + _wc.hCursor=LoadCursorW( 0,Short Ptr( IDC_ARROW ) ) + _wc.hbrBackground=COLOR_BTNSHADOW + _wc.lpszMenuName=Null + _wc.lpszClassName=_name.ToWString() + _wc.cbWndExtra=DLGWINDOWEXTRA + ClassAtom=RegisterClassW(_wc) + EndIf + Return _name + EndFunction + + Function DialogClassName$() + Global _dname$ + Global _dc:WNDCLASSW + + If Not _dname + _dname="BLITZMAX_DIALOG_CLASS" + _dc=New WNDCLASSW + _dc.style=CS_OWNDC|CS_HREDRAW|CS_VREDRAW + _dc.lpfnWndProc=ClassWndProc + _dc.hInstance=GetModuleHandleW(Null) + _dc.hCursor=LoadCursorW( 0,Short Ptr( IDC_ARROW ) ) + _dc.hbrBackground=COLOR_BTNSHADOW + _dc.lpszMenuName=Null + _dc.lpszClassName=_dname.ToWString() + _dc.cbWndExtra=DLGWINDOWEXTRA + ClassAtom2=RegisterClassW(_dc) + EndIf + Return _dname + EndFunction + + 'TMaxGuiDriver interface + + Method CreateGadget:TGadget(class,Text$,x,y,w,h,group:TGadget,style) + + Select class + Case GADGET_WINDOW + If Not group group=GDIDesktop + End Select + + Local gadget:TGadget = GadgetInstanceFromClass(class,group,style,Text) + + Select class + Case GADGET_DESKTOP, GADGET_MENUITEM, GADGET_NODE + Return gadget + End Select + + If LocalizationMode() & LOCALIZATION_OVERRIDE Then + LocalizeGadget(gadget,Text,"") + Else + gadget.SetText(Text) + EndIf + + If group Then gadget._SetParent group + If class <> GADGET_TOOLBAR Then gadget.SetShape(x,y,w,h) + + 'v0.51: Gadgets are now only shown when they have been sized, and the text set. + If TWindowsGadget(gadget) Then + If Not TWindowsWindow(gadget) + gadget.SetFont(GDIFont) + If TWindowsGadget(group) Then + TWindowsGadget(gadget)._forceDisable = Not( TWindowsGadget(group)._enabled And Not TWindowsGadget(group)._forceDisable ) + gadget.SetEnabled(Not (gadget.State()&STATE_DISABLED)) + EndIf + gadget.SetShow(True) + ElseIf Not (style & WINDOW_HIDDEN) Then + gadget.SetShow(True) + EndIf + EndIf + + If TWindowsGadget(gadget) Then TWindowsGadget(gadget).Sensitize() + + Return gadget + EndMethod + + Method GadgetInstanceFromClass:TGadget(class, group:TGadget, style = 0, Text$ = "") + + Local gadget:TGadget + + Select class + Case GADGET_DESKTOP + gadget=GDIDesktop + Case GADGET_MENUITEM + gadget=New TWindowsMenu.Create(group,style,Text) + Case GADGET_WINDOW + gadget=New TWindowsWindow.Create(group,style) + Case GADGET_BUTTON + gadget=New TWindowsButton.Create(group,style) + Case GADGET_TEXTFIELD + gadget=New TWindowsTextField.Create(group,style,Text) + Case GADGET_TEXTAREA + gadget=New TWindowsTextArea.Create(group,style) + Case GADGET_COMBOBOX + gadget=New TWindowsComboBox.Create(group,style,Text) + Case GADGET_LISTBOX + gadget=New TWindowsListBox.Create(group,style) + Case GADGET_TOOLBAR + gadget=New TWindowsToolBar.Create(group,style,Text) + Case GADGET_TABBER + gadget=New TWindowsTabber.Create(group,style) + Case GADGET_NODE + gadget=New TWindowsTreeNode.Create(group,style,Text) + Case GADGET_TREEVIEW + gadget=New TWindowsTreeView.Create(group,style) + Case GADGET_LABEL + gadget=New TWindowsLabel.Create(group,style) + Case GADGET_SLIDER + gadget=New TWindowsSlider.Create(group,style) + Case GADGET_PROGBAR + gadget=New TWindowsProgressBar.Create(group,style) + Case GADGET_PANEL + gadget=New TWindowsPanel.Create(group,style) + Case GADGET_CANVAS + gadget=New TWindowsPanel.Create(group,style|PANEL_CANVAS|PANEL_ACTIVE) + Case GADGET_HTMLVIEW + gadget=New TWindowsHTMLView.Create(group,style) + End Select + + Return gadget + + EndMethod + + Method ActiveGadget:TGadget() + Local tmpHwnd:Int = GetFocus(), tmpGadget:TGadget + While tmpHwnd + tmpGadget = GadgetFromHwnd( tmpHwnd ) + If tmpGadget Then Exit + tmpHwnd = GetParent_(tmpHwnd) + Wend + Return tmpGadget + EndMethod + + Method RequestColor(red,green,blue) + Local cc:CHOOSECOLOR = New CHOOSECOLOR + cc.lStructSize=SizeOf(cc) + cc.hwndOwner=GetActiveHwnd() + cc.rgbResult=(red)|(green Shl 8)|(blue Shl 16) + cc.lpCustColors=_customcolors + cc.Flags=CC_RGBINIT|CC_FULLOPEN|CC_ANYCOLOR + Local hwnd = GetFocus() + Local n = ChooseColorW(cc) + SetFocus(hwnd) + If Not n Return 0 + n = ((cc.rgbResult Shr 16)&$ff) | (cc.rgbResult&$ff00) | ((cc.rgbResult Shl 16)&$ff0000) + Return n|$ff000000 + EndMethod + + Method LookupColor( colorindex:Int, red:Byte Var, green:Byte Var, blue:Byte Var ) + + Select colorindex + Case GUICOLOR_WINDOWBG + colorindex = COLOR_BTNFACE + Case GUICOLOR_GADGETBG + colorindex = COLOR_WINDOW + Case GUICOLOR_GADGETFG + colorindex = COLOR_WINDOWTEXT + Case GUICOLOR_LINKFG + colorindex = COLOR_HOTLIGHT + Case GUICOLOR_SELECTIONBG + colorindex = COLOR_HIGHLIGHT + Default + Return Super.LookupColor( colorindex, red, green, blue ) + EndSelect + + Local tmpColor:Int = GetSysColor( colorindex ) + red = tmpColor & $FF + green = (tmpColor Shr 8) & $FF + blue = (tmpColor Shr 16) & $FF + + Return True + + EndMethod + + Method LoadFont:TGuiFont(name$,size,flags) + Return New TWindowsFont.Load(name,Double(size),flags) + EndMethod + + Method LoadFontWithDouble:TGuiFont(name$,size:Double,flags) + Return New TWindowsFont.Load(name,size,flags) + EndMethod + + Method LibraryFont:TGuiFont( pFontType% = GUIFONT_SYSTEM, pFontSize:Double = 0, pFontStyle% = FONT_NORMAL ) + If pFontType = GUIFONT_SYSTEM Then Return TWindowsFont.DefaultFont( pFontSize, pFontStyle ) Else Return Super.LibraryFont( pFontType, pFontSize, pFontStyle ) + EndMethod + + Method RequestFont:TGuiFont(font:TGuiFont) + Return TWindowsFont.Request(font) + EndMethod + + Method SetPointer(shape) + Global winptrs[]=[0,32512,32513,32514,32515,32516,32642,32643,32644,32645,32646,32648,32649,32650,32651] + If shape<1 Or shape>14 Then _cursor = LoadCursorW( 0,Short Ptr( IDC_ARROW ) ) Else _cursor=LoadCursorW(0,Short Ptr(winptrs[shape])) + SetCursor(_cursor) + If TWindowsTextArea._oldCursor Then TWindowsTextArea._oldCursor = _cursor + If shape = 0 Then _cursor = 0 + EndMethod + + Method LoadIconStrip:TIconStrip(source:Object) + Return TWindowsIconStrip.Create(source) + EndMethod + + Function CheckCommonControlVersion() 'Returns True if supports alpha/themes etc. or False if not. + If Not _commoncontrolversion Then + Local libComCtl = LoadLibraryW("comctl32.dll") + Local GetCommonControlVersion( pDllVersionInfo:Byte Ptr ) "win32" = GetProcAddress(libComCtl, "DllGetVersion") + If GetCommonControlVersion Then + Local tmpDllVersion:DLLVERSIONINFO2 = New DLLVERSIONINFO2 + GetCommonControlVersion( tmpDllVersion ) + _commoncontrolversion = [tmpDllVersion.dwMajorVersion,tmpDllVersion.dwMinorVersion,tmpDLLVersion.dwBuildNo] + EndIf + GetCommonControlVersion = Null + FreeLibrary( libComCtl ) + EndIf + If _commoncontrolversion And _commoncontrolversion[0] >= 6 Then + If (_commoncontrolversion[0] > 6) Or (_commoncontrolversion[1] > 0) Then Return 2 Else Return 1 + EndIf + EndFunction + + Function GetThemeHandle(hwnd, pClass$ = "WINDOW") + If OpenThemeData And CheckCommonControlVersion() Then Return OpenThemeData(hwnd, pClass) + EndFunction + + Function CloseThemeHandle(hTheme) + If CloseThemeData Then Return CloseThemeData(hTheme) + EndFunction + + Function CreateExplorerStyleGadgets( pDisable = False ) + _explorerstyle = (pDisable <> True) + EndFunction + + Function GetActiveHwnd() + If _activeWindow Then Return _activeWindow._hwnd Else Return GetActiveWindow() + EndFunction + +EndType + +Type TWindowsGadget Extends TGadget + + 'Flag that determines whether gadgets should redraw when they are resized (see Rethink()). + Global _resizeRedraw = True + + 'Generic Unicode Strings to prevent memory-leak + Global _wstrEmpty:Short Ptr = "".ToWString() + Global _wstrSpace:Short Ptr = " ".ToWString() + Global _wstrExplorer:Short Ptr = "Explorer".ToWString() + + 'Important gadget fields that store OS control handles etc.. + + Field _class, _hwnd, _hwndclient, _tooltips + Field _proc(hwnd,msg,wp,lp) "win32" + Field _hotkey:THotKey + Field _oldcursorlp 'Should track events + + Field _sensitive% = False 'Determines whether gadgets should generate events. + 'Not to be confused with the sensitivity field of TGadget + 'which specifies which type of events are fired. + + 'Aesthetics + Field _bgbrush, _fgcolor = -1, _bgcolor = -1 'Background colour + Field _hbrush, _hbitmap 'Background colour + Field _bitmap 'Background bitmap + Field _iconBitmap 'Icon bitmap + Field _hTheme 'Open handle to XP Theme API (for use in button's WM_DRAWITEM etc.) + Field _font:TWindowsFont 'Font (needs to be stored, otherwise it may be collected by GC) + Field _wstrTooltip:Short Ptr, _toolAdded = False + Field _clientX:Int, _clientY:Int, _enabled:Int = True, _forcedisable:Int = False + + Method Create:TWindowsGadget(group:TGadget, style, Text$="") Abstract + + Method SetColor(red,green,blue) + If _bgbrush Then DeleteObject _bgbrush + _bgcolor = (blue Shl 16) | (green Shl 8) | red + _bgbrush=CreateSolidBrush(_bgcolor) + RedrawGadget(Self) + EndMethod + + Method RemoveColor() + If _bgbrush Then DeleteObject _bgbrush + _bgbrush=0 + RedrawGadget(Self) + EndMethod + + Method FgColor() + Return _fgcolor + EndMethod + + Method BgColor() + Return _bgcolor + EndMethod + + Method BgBrush() + Return _bgbrush + EndMethod + + Method SetTextColor(r,g,b) + _fgcolor = (b Shl 16) | (g Shl 8) | r + RedrawGadget(Self) + EndMethod + + Method Query(queryid) + Select queryid + Case QUERY_HWND + Return _hwnd + Case QUERY_HWND_CLIENT + If _hwndclient Return _hwndclient + Return _hwnd + End Select + EndMethod + + Method Register(class,hwnd,hwndclient=0,tips=False) + _class=class + _hwnd=hwnd + _hwndclient=hwndclient + TWindowsGUIDriver.RegisterHwnd(_hwnd,Self) + If _hwndclient TWindowsGUIDriver.RegisterHwnd(_hwndclient,Self) + Local atom=GetClassLongW(hwnd,GCW_ATOM) + If atom<>TWindowsGUIDriver.ClassAtom And atom<>TWindowsGUIDriver.ClassAtom2 And Not _proc + _proc=Byte Ptr(SetWindowLongW(hwnd,GWL_WNDPROC,Int Byte Ptr TWindowsGUIDriver.ClassWndProc)) + EndIf + If tips Then SetupToolTips() + EndMethod + + Method SetupToolTips() + If _tooltips Then DestroyWindow _tooltips;TWindowsGUIDriver.RemoveHwnd(_tooltips);_tooltips = 0 + _tooltips = CreateWindowExW( 0,"tooltips_class32","",TTS_ALWAYSTIP,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,_hwnd,0,GetModuleHandleW(Null),Null ) + SendMessageW _tooltips,TTM_SETMAXTIPWIDTH,0,300 + TWindowsGUIDriver.RegisterHwnd( _tooltips, Self ) + EndMethod + + Method isTabbable() + Local style:Int = GetWindowLongW(_hwnd,GWL_STYLE)&(WS_TABSTOP|WS_CHILD) + Return (style=(WS_TABSTOP|WS_CHILD)) + EndMethod + + Method isControl() + Return (GetWindowLongW(_hwnd,GWL_STYLE)&(WS_CHILD)=WS_CHILD) + EndMethod + + Method Activate(cmd) + Select cmd + Case ACTIVATE_FOCUS + If isTabbable() + DefDlgProcW GetParent_(_hwnd),WM_NEXTDLGCTL,_hwnd,1 + Return 1 + EndIf + Return SetFocus(_hwnd) + Case ACTIVATE_BACK + Return SendMessageW(_hwnd,WM_NEXTDLGCTL,1,0) + Case ACTIVATE_FORWARD + Return SendMessageW(_hwnd,WM_NEXTDLGCTL,0,0) + Case ACTIVATE_REDRAW + RefreshLook() + Return RedrawWindow( _hwnd, Null, Null, RDW_INVALIDATE | RDW_ERASE | RDW_FRAME | RDW_ALLCHILDREN ) + End Select + EndMethod + + Method Rethink() + QueueResize(_hwnd,xpos,ypos,width,height) + EndMethod + + Method RethinkClient(forceRedraw:Int = False) + EndMethod + + Method SetArea(x,y,w,h) + SetRect(x,y,w,h) + Rethink() + EndMethod + + Method LayoutKids() + + StartResize() + + 'Implemented hack to speed-up drawing considerably... + Local tmpOldState = TWindowsGadget._resizeredraw + TWindowsGadget._resizeredraw = False + + 'Child windows are laid-out like normal... + Super.LayoutKids() + + 'Reposition all child gadgets together. + EndResize() + + 'If this control is the first parent who started the resizing, then redraw parent and all controls now. + If tmpOldState Then + If (Not kids.IsEmpty()) Then Activate(ACTIVATE_REDRAW) + TWindowsGadget._resizeredraw = True + EndIf + + EndMethod + + Method ClientWidth() + Local Rect[] = [xpos,ypos,xpos+width,ypos+height] + SendMessageW Query(QUERY_HWND), WM_NCCALCSIZE, False, Int Byte Ptr Rect + Return Rect[2]-Rect[0]-_clientX + EndMethod + + Method ClientHeight() + Local Rect[] = [xpos,ypos,xpos+width,ypos+height] + SendMessageW Query(QUERY_HWND), WM_NCCALCSIZE, False, Int Byte Ptr Rect + Return Rect[3]-Rect[1]-_clientY + EndMethod + + Method SetText(Text$) + Desensitize() + SetWindowTextW _hwnd, Text + Sensitize() + EndMethod + + Method GetText$() + Local strText:Short[GetWindowTextLengthW(_hwnd)+1] 'Must include NULL terminator. + GetWindowTextW _hwnd, strText, strText.length + Return String.FromWString( strText ) + EndMethod + + Method SetFont(font:TGuiFont) + If TWindowsFont(font) Then _font = TWindowsFont(font) Else _font = TWindowsGUIDriver.GDIFont + SendMessageW _hwnd,WM_SETFONT,font.handle,1 + EndMethod + + Method SetShow(show) + If show + ShowWindow _hwnd,SW_SHOW + Else + 'Requester fix - ShowWindow activates the last activated window when an active window is hidden, so if + 'a file requester/child gadget was the last window to be activated, then the program will lose focus as it is + 'trying to activate a non-existent window. + If parent And HasDescendant(ActiveGadget()) Then ActivateGadget(parent) + ShowWindow _hwnd,SW_HIDE + EndIf + EndMethod + + Method SetEnabled(enable) + _enabled = enable + enable = enable And Not _forceDisable + If Not((EnableWindow(_hwnd,enable)<>0) ~ enable) Then + For Local tmpGadget:TWindowsGadget = EachIn kids + tmpGadget._forceDisable = Not enable + If tmpGadget.isControl() Then tmpGadget.SetEnabled(tmpGadget._enabled) + Next + EndIf + EndMethod + + Method SetTooltip( pTooltip$ ) + + If _wstrTooltip Then MemFree _wstrTooltip;_wstrTooltip = Null + + Local tmpToolInfo:TOOLINFOW = New TOOLINFOW + tmpToolInfo.cbSize = SizeOf(tmpToolInfo) + tmpToolInfo.hwnd = GetParent_(_hwnd) + tmpToolInfo.hinst = GetModuleHandleW(Null) + tmpToolInfo.uID = _hwnd + + If pTooltip Then + _wstrTooltip = pTooltip.Replace("~r","").Replace("~n","~r~n").ToWString() + + tmpToolInfo.uFlags = TTF_IDISHWND|TTF_TRANSPARENT|TTF_SUBCLASS + tmpToolInfo.lpszText = _wstrTooltip + + If Not _toolAdded Then + _toolAdded = SendMessageW(TWindowsGUIDriver._hwndTooltips, TTM_ADDTOOLW, 0, Int Byte Ptr tmpToolInfo) + Else + SendMessageW(TWindowsGUIDriver._hwndTooltips, TTM_UPDATETIPTEXTW, 0, Int Byte Ptr tmpToolInfo) + EndIf + ElseIf _tooladded Then + SendMessageW(TWindowsGUIDriver._hwndTooltips, TTM_DELTOOLW, 0, Int Byte Ptr tmpToolInfo ) + _toolAdded = 0 + EndIf + + EndMethod + + Method GetTooltip$() + If _wstrTooltip Then Return String.FromWString(_wstrTooltip) + EndMethod + + Method State() + Local t, style = GetWindowLongW(_hwnd, GWL_STYLE) + If Not (style&WS_VISIBLE) Then t:|STATE_HIDDEN + If Not _enabled Then t:|STATE_DISABLED + Return t + EndMethod + + Method Free() + If _tooltips Then DestroyWindow _tooltips;_tooltips=0 + SetTooltip("") 'Free any tooltip memory allocations + If _hwnd Then DestroyWindow _hwnd;TWindowsGUIDriver.RemoveHwnd(_hwnd);_hwnd=0 + If _hwndclient Then TWindowsGUIDriver.RemoveHwnd(_hwndclient);_hwndclient=0 + FlushBrushes(False) + If _hotKey Then RemoveHotKey(_hotKey);_hotKey = Null + If _iconBitmap Then DeleteObject(_iconBitmap);_iconBitmap = 0 + If _bitmap Then DeleteObject(_bitmap);_bitmap = 0 + If _bgbrush Then DeleteObject(_bgbrush);_bgbrush = 0 + If _htheme Then TWindowsGUIDriver.CloseThemeHandle(_hTheme);_hTheme = 0 + _font = Null + _SetParent Null + EndMethod + + Method OnNotify(wp,lp) + EndMethod + + Method WndProc(hwnd,msg,wp,lp) + Select msg + Case WM_WINDOWPOSCHANGING + FlushBrushes() + EndSelect + If _proc And _hwnd = hwnd Then + Return CallWindowProcW(_proc,hwnd,msg,wp,lp) 'fixed auto scrollbars + EndIf + Return DefWindowProcW( hwnd,msg,wp,lp ) + EndMethod + + Method OnCommand(msg,wp) + EndMethod + + Method OnDrawItem( pDrawItemStruct:DRAWITEMSTRUCT ) + EndMethod + + Method SetHotKey(key,modifier) + Local ev:TEvent = CreateEvent( EVENT_GADGETACTION,Self ) + If _hotKey Then RemoveHotKey(_hotKey);_hotKey = Null + If key Then _hotkey=SetHotKeyEvent(key,modifier,ev,FindGadgetWindowHwnd(Self)) + EndMethod + + 'Slow back-up code for mimicking transparency for PANEL_GROUPs and when + 'DrawThemeParentBackground() is not available (i.e. on Windows 9x/2000). + Method CreateControlBrush( hWndControl, hdc = 0 ) + + Local xOffset, yOffset + Local hwndWindow = GetParent_(hwndControl) + Local rectWindow[4], rectControl[4], rectClient[4] + + If _hbrush Then Return _hbrush + + If BgBrush() Then + If hdc Then SetBkColor(hdc, BgColor()) + Return BgBrush() + EndIf + + Local tmpDC = GetDC( hwndWindow ) + + 'Fix required to offset background when controls are drawn with WS_EX_CLIENTEDGE (e.g. panel with PANEL_SUNKEN/PANEL_RAISED set) + If GetWindowLongW(hwndWindow,GWL_EXSTYLE)&(WS_EX_CLIENTEDGE|WS_EX_WINDOWEDGE) Then + xOffset = -GetSystemMetrics(SM_CXEDGE) + yOffset = -GetSystemMetrics(SM_CYEDGE) + EndIf + + GetClientRect( hwndControl, rectClient ) + GetWindowRect( hwndWindow, rectWindow ) + GetWindowRect( hwndControl, rectControl ) + + Local x = rectControl[0]-rectWindow[0] + Local y = rectControl[1]-rectWindow[1] + Local w = rectControl[2]-rectControl[0] + Local h = rectControl[3]-rectControl[1] + + Local dcBitmap = CreateCompatibleDC( tmpDC ) + Local bkgndBitmap = CreateCompatibleBitmap( tmpDC, rectWindow[2]-rectWindow[0], rectWindow[3]-rectWindow[1] ) + SelectObject( dcBitmap, bkgndBitmap ) + + 'InvalidateRect( hwndWindow, Null, False ) + SendMessageW hwndWindow, WM_ERASEBKGND, dcBitmap, 0 + + Local bkgndClientBitmap = CreateCompatibleBitmap( tmpDC, w, h ) + Local dcClientBitmap = CreateCompatibleDC( tmpDC ) + SelectObject( dcClientBitmap, bkgndClientBitmap ) + + BitBlt( dcClientBitmap, 0,0 , w, h, dcBitmap, x+xOffset, y+yOffset, ROP_SRCCOPY ) + + DeleteObject( bkgndBitmap ) + DeleteDC( dcBitmap ) + DeleteDC( dcClientBitmap ) + + _hbrush = CreatePatternBrush( bkgndClientBitmap ) + _hbitmap = bkgndClientBitmap + + ReleaseDC( hwndWindow, tmpDC ) + + Return _hbrush + + EndMethod + + 'Clears the parent background brushes. + Method FlushBrushes(pRecurse:Int = True) + Local tmpChanges:Int = 0 + If _hbrush Then + DeleteObject( _hbrush ) + _hbrush = 0 + tmpChanges:|True + EndIf + If _hBitmap Then + DeleteObject( _hBitmap ) + _hBitmap = 0 + tmpChanges:|True + EndIf + Return tmpChanges + EndMethod + + 'Method that returns a brush for drawing backgrounds. + Method DrawBackground( hdc, hwnd ) + + If BgBrush() Then SetBkColor(hdc, BgColor());Return BgBrush() + + Return DrawParentBackground( hdc, hwnd ) + + EndMethod + + 'Another method which mimics transparency on Windows Controls. + Function DrawParentBackground( hdc, hwndControl, pForceHack = False ) + + Local rectWindow[4], rectControl[4], rectClient[4] + Local hwndWindow = GetParent_(hwndControl) + + GetClientRect( hwndControl, rectClient ) + GetClientRect( hwndWindow, rectWindow ) + GetWindowRect( hwndControl, rectControl ) + + 'Ensures that the the drawing context is returned in exactly the same state that it was passed. + Local tmpSaveState = SaveDC( hdc ) + + If DrawThemeParentBackground And Not pForceHack Then + + DrawThemeParentBackground(hwndControl,hdc,rectClient) + + Else 'Again, slow back-up code in case DrawThemeParentBackground() is not available. + + Local tmpDC, xOffset, yOffset + + 'Fix required to offset background when controls are drawn with WS_EX_CLIENTEDGE (e.g. panel with PANEL_BORDER set) + If GetWindowLongW(hwndWindow,GWL_EXSTYLE)&WS_EX_CLIENTEDGE Then + xOffset = -GetSystemMetrics(SM_CXEDGE) + yOffset = -GetSystemMetrics(SM_CYEDGE) + EndIf + + tmpDC = GetDC( hwndWindow ) + + ScreenToClient( hwndWindow, rectControl ) + ScreenToClient( hwndWindow, Int Ptr (rectControl)+2 ) + + Local x = rectControl[0]+rectClient[0] + Local y = rectControl[1]+rectClient[1] + Local w = rectClient[2]-rectClient[0] + Local h = rectClient[3]-rectClient[1] + + Local bkgndBitmap = CreateCompatibleBitmap( tmpDC, rectWindow[2]-rectWindow[0], rectWindow[3]-rectWindow[1] ) + Local dcBitmap = CreateCompatibleDC( tmpDC ) + SelectObject( dcBitmap, bkgndBitmap ) + + InvalidateRect( hwndWindow, Null, False ) + SendMessageW hwndWindow, WM_ERASEBKGND, dcBitmap, 0 + + BitBlt( hdc, 0,0 , w, h, dcBitmap, x+xOffset, y+yOffset, ROP_SRCCOPY ) + + DeleteObject( bkgndBitmap ) + DeleteDC( dcBitmap ) + ReleaseDC( hwndWindow, tmpDC ) + + EndIf + + 'Ensures that the the drawing context is returned in exactly the same state that it was passed. + RestoreDC( hdc, tmpSaveState ) + + Return GetStockObject( NULL_BRUSH ) + + EndFunction + + Method Sensitize() + _sensitive = True + EndMethod + + Method DeSensitize() + _sensitive = False + EndMethod + + Method PostGuiEvent( pID%, pData%=0, pMods%=0, pX%=0, pY%=0, pExtra:Object = Null) + + Select True + Case TWindowsListBox(Self) <> Null, TWindowsTabber(Self) <> Null, TWindowsToolbar(Self) <> Null, TWindowsCombobox(Self) <> Null + If pData>-1 Then + If (ItemFlags(pData) & GADGETITEM_TOGGLE) Then SelectItem(pData,2) + EndIf + End Select + + If _sensitive Then MaxGUI.MaxGUI.PostGuiEvent( pID, Self, pData, pMods, pX, pY, pExtra ) + + EndMethod + + 'Resize Methods + + Field hdwpStruct + + Method StartResize() + If Not hdwpStruct Then + Local tmpCount = kids.Count() + If tmpCount Then hdwpStruct = BeginDeferWindowPos( tmpCount ) + EndIf + EndMethod + + Method QueueResize( hwnd, xpos, ypos, width, height ) + If parent And GetParent_(hwnd) = parent.Query(QUERY_HWND_CLIENT) And TWindowsGadget(parent).hdwpStruct Then + Local tmpFlags = SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOACTIVATE' | SWP_NOCOPYBITS + If Not _resizeRedraw Then tmpFlags:| SWP_NOREDRAW + TWindowsGadget(parent).hdwpStruct = DeferWindowPos( TWindowsGadget(parent).hdwpStruct, hwnd, Null, xpos, ypos, width, height, tmpFlags ) + Else + MoveWindow( hwnd, xpos, ypos, width, height, _resizeRedraw ) + HasResized() + EndIf + EndMethod + + Method EndResize() + If hdwpStruct Then + EndDeferWindowPos( hdwpStruct );hdwpStruct = 0 + For Local tmpGadget:TWindowsGadget = EachIn kids + Sensitize() + tmpGadget.HasResized() + Next + EndIf + EndMethod + + 'Required for resizing columns in listboxes (has to be done outside WM_SIZE) + Method HasResized() + EndMethod + + 'Required to ensure problematic controls are updated when parent aesthetics are changed: + Method RefreshLook() + FlushBrushes(False) + For Local tmpGadget:TWindowsGadget = EachIn kids + tmpGadget.RefreshLook() + Next + EndMethod + +Rem + Method StartDoubleBuffer() + For Local tmpGadget:TWindowsGadget = EachIn kids + tmpGadget.StartDoubleBuffer() + Next + EndMethod + + Method EndDoubleBuffer() + For Local tmpGadget:TWindowsGadget = EachIn kids + tmpGadget.EndDoubleBuffer() + Next + EndMethod +EndRem +EndType + + +Type TWindowsDesktop Extends TWindowsGadget + + Method New() + Local Rect[4] + Local hwnd = GetDesktopWindow() + Register(GADGET_DESKTOP,hwnd,0,False) + GetClientRect hwnd,Rect + SetShape 0,0,Rect[2]-Rect[0],Rect[3]-Rect[1] + EndMethod + + Method Create:TWindowsGadget(group:TGadget,style,Text$="") + Return Self + EndMethod + + Method SetTooltip( pTooltip$ ) + 'Shouldn't have tool-tips. + EndMethod + + Method Free() + 'Can't be free'd. + EndMethod + + Method Class() + Return GADGET_DESKTOP + EndMethod + + Method ClientHeight() + Local Rect[4] + If Super.ClientHeight() = height And SystemParametersInfoW( SPI_GETWORKAREA, 0, Int Byte Ptr Rect, 0 ) + Return Rect[3]-Rect[1] + Else + Return Super.ClientHeight() + EndIf + EndMethod + + Method ClientWidth() + Local Rect[4] + If Super.ClientWidth() = width And SystemParametersInfoW( SPI_GETWORKAREA, 0, Int Byte Ptr Rect, 0 ) + Return Rect[2]-Rect[0] + Else + Return Super.ClientWidth() + EndIf + EndMethod + +EndType + +Type TWindowsWindow Extends TWindowsGadget + + Field _wstyle, _xstyle + Field _minwidth,_minheight,_maxwidth = -1,_maxheight = -1 + Field _menu:TWindowsMenu + Field _hmenu + Field _status + + Method Create:TWindowsGadget(group:TGadget,style,Text$="") + Local hwnd, parent, client + Local classname$ = TWindowsGUIDriver.ClassName() + + Self.style = style + _wstyle=WS_CLIPSIBLINGS|WS_CLIPCHILDREN + If group Then parent = group.Query(QUERY_HWND) + + If (style&WINDOW_TITLEBAR) + _wstyle:|WS_OVERLAPPED|WS_SYSMENU + If style&WINDOW_RESIZABLE _wstyle:|WS_MINIMIZEBOX|WS_MAXIMIZEBOX + If group <> TWindowsGUIDriver.GDIDesktop And Not (style&WINDOW_TOOL) Then + classname$ = TWindowsGUIDriver.DialogClassName() + _xstyle:|WS_EX_DLGMODALFRAME + EndIf + Else + _wstyle:|WS_POPUP + EndIf + + If style&WINDOW_RESIZABLE Then _wstyle:|WS_SIZEBOX + If style&WINDOW_MENU Then _hmenu=CreateMenu_();AppendMenuW( _hmenu,MF_STRING,Null,_wstrEmpty ) + If style&WINDOW_TOOL Then _xstyle:|WS_EX_TOOLWINDOW + + ' Note: No WINDOW_HIDDEN case as gadgets are always created hidden to hide initial resize flicker. + ' TWindowsGUIDriver.CreateGadget() will later show window if WINDOW_HIDDEN is not specified. + + hwnd=CreateWindowExW(_xstyle,classname,"",_wstyle,0,0,0,0,parent,_hmenu,GetModuleHandleW(Null),Null) + + If style&WINDOW_STATUS + _status=CreateWindowExW(0,"msctls_statusbar32","",WS_CHILD|WS_VISIBLE,0,0,0,0,hwnd,0,GetModuleHandleW(Null),Null) + SetWindowPos( _status, HWND_TOPMOST,0,0,0,0,SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOOWNERZORDER|SWP_NOSIZE) + EndIf + + client=CreateWindowExW(0,TWindowsGUIDriver.ClassName(),"",WS_CHILD|WS_VISIBLE|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,0,0,0,0,hwnd,0,GetModuleHandleW(Null),Null) + + Register GADGET_WINDOW,hwnd,client,False + + If style&WINDOW_ACCEPTFILES Then DragAcceptFiles _hwnd,True + _wstyle = GetWindowLongW( hwnd, GWL_STYLE ) + + Return Self + EndMethod + + Method SetAlpha( alpha# ) + If SetLayeredWindowAttributes Then + Local tmpStyle% = GetWindowLongW(_hwnd, GWL_EXSTYLE) + If alpha = 1.0 Then + SetLayeredWindowAttributes( _hwnd, 0, Byte(alpha*255), LWA_ALPHA) + If (tmpStyle & WS_EX_LAYERED) Then SetWindowLongW(_hwnd, GWL_EXSTYLE, tmpStyle&~WS_EX_LAYERED) + Else + If Not (tmpStyle & WS_EX_LAYERED) Then SetWindowLongW(_hwnd, GWL_EXSTYLE, tmpStyle|WS_EX_LAYERED) + SetLayeredWindowAttributes( _hwnd, 0, Byte(alpha*255), LWA_ALPHA) + EndIf + RedrawGadget(Self) + EndIf + EndMethod + + Method Rethink() + Local dimensions[] = [xpos,ypos,width,height] + ConvertToContainerDimensions( dimensions[0], dimensions[1], dimensions[2], dimensions[3] ) + MoveWindow _hwnd, dimensions[0], dimensions[1], dimensions[2], dimensions[3], True + RethinkClient(True) + EndMethod + + Method RethinkClient(forceRedraw:Int = False) + If _hwndClient Then + MoveWindow _hwndClient, _clientx,_clienty,ClientWidth(),ClientHeight(),forceRedraw + EndIf + LayoutKids() + EndMethod + + + Method ClientWidth() + If (style & WINDOW_CLIENTCOORDS) Then Return width + Local Rect:Int[4] + GetClientRect _hwnd, Rect + Return Max(Rect[2]-Rect[0]-_clientX,0) + EndMethod + + Method ClientHeight() + If (style & WINDOW_CLIENTCOORDS) Then Return height + Local h:Int = height, Rect:Int[] = [0,0,width,height] + AdjustWindowRectEx(Rect,GetWindowLongW(_hwnd, GWL_STYLE),_hmenu,GetWindowLongW(_hwnd, GWL_EXSTYLE)) + h:-(Rect[3]-Rect[1]+_clientY-height) + If _status Then GetWindowRect _status,Rect;h:-(Rect[3]-Rect[1]) + Return Max(h,0) + End Method + + Method Class() + Return GADGET_WINDOW + EndMethod + + Method State() + Local t = Super.State() + If IsIconic(_hwnd) t:|STATE_MINIMIZED + If IsZoomed(_hwnd) t:|STATE_MAXIMIZED + Return t + EndMethod + + Method SetEnabled(enable) + _enabled = enable + EnableWindow(_hwnd,enable) + EndMethod + + Method SetMinimumSize(w,h) + 'Set minimum size for current window style + _minwidth=w;_minheight=h + 'Get window style + Local tmpWStyle% = GetWindowLongW( _hwnd, GWL_STYLE ) + 'Update size border + If (_maxwidth = _minwidth And _maxheight = _minheight) Then tmpWStyle:&~WS_SIZEBOX ElseIf (style&WINDOW_RESIZABLE) Then tmpWStyle:|WS_SIZEBOX + 'Set new window style if necessary + If tmpWStyle <> GetWindowLongW( _hwnd, GWL_STYLE ) Then + SetWindowLongW( _hwnd, GWL_STYLE, tmpWStyle ) + Rethink() + SetWindowPos( _hwnd, Null, 0, 0, 0, 0, SWP_DRAWFRAME|SWP_FRAMECHANGED|SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOOWNERZORDER|SWP_NOZORDER|SWP_NOSIZE ) + EndIf + EndMethod + + Method SetMaximumSize(w,h) + 'Set maximum size for current window style + _maxwidth=w;_maxheight=h + 'Get window style + Local tmpWStyle% = GetWindowLongW( _hwnd, GWL_STYLE )&~WS_MAXIMIZEBOX + 'Update size border + If (_maxwidth = _minwidth And _maxheight = _minheight) Then tmpWStyle:&~WS_SIZEBOX ElseIf (style&WINDOW_RESIZABLE) Then tmpWStyle:|WS_SIZEBOX + 'Set new window style if necessary + If tmpWStyle <> GetWindowLongW( _hwnd, GWL_STYLE ) Then + SetWindowLongW( _hwnd, GWL_STYLE, tmpWStyle ) + Rethink() + SetWindowPos( _hwnd, Null, 0, 0, 0, 0, SWP_DRAWFRAME|SWP_FRAMECHANGED|SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOOWNERZORDER|SWP_NOZORDER|SWP_NOSIZE ) + EndIf + EndMethod + + Method GetMenu:TGadget() + If Not _menu Then + _menu = New TWindowsMenu.Create(Null,0,"") + _menu._setParent Self + EndIf + Return _menu + EndMethod + + Method UpdateMenu() + + Local hmenu, oldMenu + If _menu + _menu.FreeKids + _menu.Open + hmenu=_menu._hmenu + EndIf + + oldMenu = GetMenu_( _hwnd ) + SetMenu _hwnd,hmenu + DrawMenuBar _hwnd + DestroyMenu oldMenu + + EndMethod + + Field _statustext$ + + Method GetStatusText$() + If _status + Return _statustext + EndIf + EndMethod + + Method SetStatusText(Text$) + If _status + _statustext = Text + If (style&WINDOW_RESIZABLE) Then Text:+" " 'Cludge for size handle obfuscation + Local tmpWString:Short Ptr = Text.ToWString() + SendMessageW _status,WM_SETTEXT,0,Int(tmpWString) + MemFree tmpWString + EndIf + EndMethod + + Field popupextra:Object + + Method PopupMenu(menu:TGadget,extra:Object) + Local pt[2], wmenu:TWindowsMenu = TWindowsMenu(menu), tmpLink:TLink + If wmenu + + GetCursorPos_ pt + popupextra = extra + wmenu.Open(True) + + Local hmenu:Int = TrackPopupMenu( wmenu._hmenu,TPM_LEFTALIGN|TPM_TOPALIGN|TPM_RETURNCMD|TPM_NONOTIFY,pt[0],pt[1],0,_hwnd,0 ) + If hmenu Then HandleMenuEvent( WM_COMMAND, hmenu ) + + wmenu.Close() + popupextra = Null + + EndIf + EndMethod + + Function EnumChildProc(hwnd,lp) "win32" + Local winfo:WINDOWINFO = New WINDOWINFO + winfo.cbSize=SizeOf winfo + GetWindowInfo hwnd,winfo + If winfo.dwStyle&WS_TABSTOP + _firsttab=hwnd + Else + EnumChildWindows hwnd,EnumChildProc,0 + EndIf + If _firsttab Return 0 + Return 1 + EndFunction + + Global _firsttab + + Method Activate(cmd) + Select cmd + Case ACTIVATE_FOCUS + _firsttab=0 + EnumChildWindows _hwnd,EnumChildProc,0 + If Not _firsttab _firsttab=_hwnd + SetFocus _firsttab + Case ACTIVATE_MINIMIZE + ShowWindow _hwnd,SW_MINIMIZE + Case ACTIVATE_MAXIMIZE + ShowWindow _hwnd,SW_MAXIMIZE + Case ACTIVATE_RESTORE + ShowWindow _hwnd,SW_RESTORE + Case ACTIVATE_REDRAW + RefreshLook() + Return RedrawWindow( _hwnd, Null, Null, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE | RDW_FRAME | RDW_ALLCHILDREN ) + End Select + EndMethod + + Method OnCommand(msg,wp) + If wp>100 Then HandleMenuEvent(msg,wp) + EndMethod + + Method HandleMenuEvent( msg, wp ) + + Local tmpMenuSource:TWindowsMenu = TWindowsMenu.GetMenuFromKey(wp), tmpMenuID + If tmpMenuSource Then tmpMenuID = tmpMenuSource._tag + + Local tmpPopupExtra:Object = popupextra + popupextra = Null + + MaxGUI.MaxGUI.PostGuiEvent EVENT_MENUACTION,tmpMenuSource,tmpMenuID,0,0,0,tmpPopupExtra + + EndMethod + + Method WndProc(hwnd,msg,wp,lp) + Local x,y,w,h + Local move,size + Local Rect[4] + Local winrect[4] + + Select msg + + Case WM_ERASEBKGND + If BgBrush() Then + Local Rect[4] + If Not GetUpdateRect( hwnd, Rect, False ) Then GetClipBox( wp, Rect ) + FillRect( wp, Rect, BgBrush() ) + Return 1 + EndIf + + Case WM_SIZE + + If (hwnd = _hwnd) And (wp <> SIZE_MINIMIZED) Then + + If _status Then SendMessageW _status,WM_SIZE,0,0 + + If (style & WINDOW_CLIENTCOORDS) Then + GetClientRect _hwnd,Rect + w=Rect[2] + h=Rect[3] + AdjustWindowRectEx(Rect,GetWindowLongW(_hwnd, GWL_STYLE),_hmenu,GetWindowLongW(_hwnd, GWL_EXSTYLE)) + x=-Rect[0] + y=-Rect[1] + GetWindowRect _hwnd,Rect + x:+Rect[0] + y:+Rect[1] + If _status Then + GetWindowRect _status,Rect + h:-(Rect[3]-Rect[1]) + EndIf + x:+_clientX;y:+_clientY + w:-_clientX;h:-_clientY + Else + GetWindowRect(_hwnd,Rect) + x=Rect[0];y=Rect[1] + w=Rect[2]-Rect[0] + h=Rect[3]-Rect[1] + EndIf + + If x<>xpos Or y<>ypos Then move = True + If w<>width Or h<>height Then size = True + + SetRect x,y,w,h + + If size Then RethinkClient() + + If move PostGuiEvent EVENT_WINDOWMOVE,0,0,x,y + If size PostGuiEvent EVENT_WINDOWSIZE,0,0,w,h + + EndIf + + Case WM_MOVE + If (hwnd = _hwnd) And Not (IsZoomed(hwnd) Or IsIconic(hwnd)) Then + + If (style & WINDOW_CLIENTCOORDS) Then + GetClientRect _hwnd,Rect + w=Rect[2] + h=Rect[3] + AdjustWindowRectEx(Rect,GetWindowLongW(_hwnd, GWL_STYLE),_hmenu,GetWindowLongW(_hwnd, GWL_EXSTYLE)) + x=-Rect[0] + y=-Rect[1] + GetWindowRect _hwnd,Rect + x:+Rect[0]+_clientX + y:+Rect[1]+_clientY + Else + GetWindowRect(_hwnd,Rect) + x=Rect[0];y=Rect[1] + w=Rect[2]-Rect[0] + h=Rect[3]-Rect[1] + EndIf + + If x<>xpos Or y<>ypos Then + SetRect x,y,width,height + PostGuiEvent EVENT_WINDOWMOVE,0,0,x,y + EndIf + + EndIf + + Case WM_GETMINMAXINFO + If hwnd = _hwnd And lp Then + Local minmax:Int Ptr = Int Ptr(lp), tmpZero% = 0 + + minmax[6]=_minwidth + minmax[7]=_minheight + ConvertToContainerDimensions(tmpZero,tmpZero,minmax[6],minmax[7]) + + If (_maxwidth >= _minwidth) And (_maxheight >= _minheight) Then + minmax[8]=_maxwidth + minmax[9]=_maxheight + ConvertToContainerDimensions(tmpZero,tmpZero,minmax[8],minmax[9]) + EndIf + + EndIf + + Case WM_ACTIVATE + If (wp = WA_ACTIVE) Or (wp = WA_CLICKACTIVE) Then + TWindowsGUIDriver._ActiveWindow = Self + PostGuiEvent EVENT_WINDOWACTIVATE + EndIf + + Case WM_COMMAND + If wp>100 Then HandleMenuEvent(wp,msg) + + Case WM_CLOSE + PostGuiEvent EVENT_WINDOWCLOSE + Return 1 + + Case WM_DROPFILES + Local hdrop,pt[2],path$ + Local pbuffer:Short[MAX_PATH] + Local i,n,l + DragQueryPoint wp,pt + n=DragQueryFileW(wp,$ffffffff,Null,0); + For i=0 Until n + l=DragQueryFileW(wp,i,pbuffer,MAX_PATH) + path=String.FromShorts(pbuffer,l) + PostGuiEvent EVENT_WINDOWACCEPT,0,0,pt[0],pt[1],path + Next + DragFinish wp + + End Select + + Return Super.WndProc(hwnd,msg,wp,lp) + + EndMethod + + Method DoLayout() + 'Don't do anything! + EndMethod + + Method SetTooltip( pTooltip$ ) + 'Windows shouldn't have tool-tips! + EndMethod + + Method SetSensitivity(flags) + 'Problems with resizing/moving sensitive windows. + Super.SetSensitivity(flags&~SENSITIZE_MOUSE) + 'Easy to create an active panel in client area as a work around. + EndMethod + + Method SetPixmap(pPixmap:TPixmap, pFlags) + If Not (pFlags & GADGETPIXMAP_ICON) Then Return False + If _iconBitmap Then DestroyIcon(_iconBitmap);_iconBitmap = 0 + If pPixmap Then _iconBitmap = TWindowsGraphic.IconFromPixmap32( pPixmap ) + SendMessageW (_hwnd, WM_SETICON, 0, _iconBitmap) + SendMessageW (_hwnd, WM_SETICON, 1, _iconBitmap) + Return True + EndMethod + + ' Needed otherwise SetEnabled() locks if modal child window is opened and parent is disabled. + Method isControl() + Return False + EndMethod + + Method ConvertToContainerDimensions%( pX Var, pY Var, pW Var , pH Var ) + + If Not (style & WINDOW_CLIENTCOORDS) Then Return 0 + + Local Rect[4], menu = GetMenu_(_hwnd) + + If menu Then menu = True + If _status Then GetWindowRect _status,Rect;pH:+(Rect[3]-Rect[1]) + pW:+_clientX;pH:+_clientY;pX:-_clientX;pY:-_clientY + + Rect = [pX,pY,pX+pW,pY+pH] + AdjustWindowRectEx Rect,GetWindowLongW(_hwnd, GWL_STYLE),menu,GetWindowLongW(_hwnd, GWL_EXSTYLE) + + pX = Rect[0];pY = Rect[1];pW = Rect[2]-Rect[0];pH = Rect[3]-Rect[1] + + Return 1 + + EndMethod + + Method FlushBrushes(pRecurse:Int = True) + Super.FlushBrushes() + If Not pRecurse Then Return + For Local tmpGadget:TWindowsGadget = EachIn kids + tmpGadget.FlushBrushes() + Next + EndMethod + +EndType + +Type TWindowsButton Extends TWindowsGadget + + Field _buttonImageList[] = [-1,0,0,0,0,0], _strButtonText$, _mouseoverbutton + + Method Create:TWindowsGadget(group:TGadget,style,Text$="") + Local xstyle,wstyle,hotkey + Local hwnd,parent + Self.style = style + wstyle=WS_CHILD|WS_TABSTOP|WS_CLIPSIBLINGS|BS_MULTILINE + Select style&7 + Case 0 wstyle:|BS_PUSHBUTTON;style = BUTTON_PUSH + Case BUTTON_CHECKBOX wstyle:|BS_3STATE;If (style&BUTTON_PUSH) Then wstyle:|BS_PUSHLIKE + Case BUTTON_RADIO wstyle:|BS_AUTORADIOBUTTON;If (style&BUTTON_PUSH) Then wstyle:|BS_PUSHLIKE + Case BUTTON_OK wstyle:|BS_DEFPUSHBUTTON;hotkey=IDOK + Case BUTTON_CANCEL wstyle:|BS_PUSHBUTTON;hotkey=IDCANCEL + End Select + parent=group.query(QUERY_HWND_CLIENT) + hwnd=CreateWindowExW(xstyle,"BUTTON","",wstyle,0,0,0,0,parent,hotkey,GetModuleHandleW(Null),Null) + Register GADGET_BUTTON,hwnd + Return Self + EndMethod + + Method SetTextColor(r,g,b) + If Not (style&7) Then + SetWindowLongW(_hwnd,GWL_STYLE,GetWindowLongW(_hwnd,GWL_STYLE)|BS_OWNERDRAW) + If Not _hTheme Then _hTheme = TWindowsGUIDriver.GetThemeHandle( _hwnd, "Button" ) + ElseIf Not (style&BUTTON_PUSH) And ((style&7=BUTTON_CHECKBOX) Or (style&7=BUTTON_RADIO)) + If SetWindowThemeW Then SetWindowThemeW(_hwnd,_wstrSpace,_wstrSpace) + EndIf + Super.SetTextColor(r,g,b) + EndMethod + + Method SetColor(r,g,b) + If Not (style&7) Then + SetWindowLongW(_hwnd,GWL_STYLE,GetWindowLongW(_hwnd,GWL_STYLE)|BS_OWNERDRAW) + If Not _hTheme Then _hTheme = TWindowsGUIDriver.GetThemeHandle( _hwnd, "Button" ) + EndIf + Super.SetColor(r,g,b) + EndMethod + + Method RemoveColor() + If Not (style&7) Then + SetWindowLongW(_hwnd,GWL_STYLE,GetWindowLongW(_hwnd,GWL_STYLE)&~BS_OWNERDRAW) + _hTheme=0 + EndIf + Super.RemoveColor() + EndMethod + + Method State() + Local t=Super.State() + Select SendMessageW( _hwnd,BM_GETCHECK,0,0 ) + Case BST_CHECKED;t:|STATE_SELECTED + Case BST_INDETERMINATE;t:|STATE_INDETERMINATE + EndSelect + Return t + EndMethod + + Method SetSelected(bool) + Local state = BST_UNCHECKED + If bool Then + If (style&7 = BUTTON_CHECKBOX) And (bool = CHECK_INDETERMINATE) Then + state = BST_INDETERMINATE + Else + state = BST_CHECKED + EndIf + EndIf + SendMessageW _hwnd,BM_SETCHECK,state,0 + EndMethod + + Method WndProc(hwnd,msg,wp,lp) + Select msg + Case WM_THEMECHANGED + If _hTheme Then + TWindowsGUIDriver.CloseThemeHandle(_hTheme) + _hTheme = TWindowsGUIDriver.GetThemeHandle(_hwnd,"BUTTON") + EndIf + Case WM_LBUTTONDBLCLK + PostMessageW(_hwnd, WM_LBUTTONDOWN, wp, lp) + Case WM_MOUSEMOVE + If Not _mouseoverbutton Then + _mouseoverbutton = True + InvalidateRect(_hwnd,Null,False) + Local tmpTrackMouseEvent:Int[] = [ 16, $2, hwnd, 0 ] 'TME_LEAVE: $2 + _TrackMouseEvent( tmpTrackMouseEvent ) + EndIf + Case WM_MOUSELEAVE + If _mouseoverbutton Then + _mouseoverbutton = False + InvalidateRect(_hwnd,Null,False) + EndIf + Case WM_ERASEBKGND + Return 1 + EndSelect + + Return Super.WndProc(hwnd,msg,wp,lp) + + EndMethod + + Method OnDrawItem(pDrawItemStruct:DRAWITEMSTRUCT) + + Local tmpDc = pDrawItemStruct.hDc, txtWidth%, txtHeight% + Local tmpDcState = SaveDC(tmpDC) + + ' button state + Local tmpIsPressed = (pDrawItemStruct.ItemState & ODS_SELECTED) + Local tmpIsFocused = (pDrawItemStruct.ItemState & ODS_FOCUS) + Local tmpIsDisabled = (pDrawItemStruct.ItemState & ODS_DISABLED) + Local tmpDrawFocusRect = Not (pDrawItemStruct.ItemState & ODS_NOFOCUSRECT) + + Local itemRect:Int Ptr = Int Ptr Varptr pDrawItemStruct.rcItem_left, txtRect:Int[4], clientRect:Int[4] + + Local tmpBgMode = SetBkMode(tmpDc, TRANSPARENT) + + ' Prepare draw... paint button background + + If _hTheme Then + + Local tmpState = PBS_NORMAL + If tmpIsDisabled Then + tmpState = PBS_DISABLED + ElseIf tmpIsPressed Then + tmpState = PBS_PRESSED + ElseIf _mouseoverbutton Then + tmpState = PBS_HOT + ElseIf tmpIsFocused Then + tmpState = PBS_DEFAULTED + EndIf + + If IsThemeBackgroundPartiallyTransparent(_hTheme, BP_PUSHBUTTON, tmpState) Then + DrawThemeParentBackground( _hwnd, tmpDc, itemRect ) + EndIf + DrawThemeBackground(_hTheme, tmpDc, BP_PUSHBUTTON, tmpState, itemRect, Null) + GetThemeBackgroundContentRect(_hTheme, tmpDc, BP_PUSHBUTTON, tmpState, itemRect, clientRect) + + Else + + clientRect = [itemRect[0], itemRect[1], itemRect[2], itemRect[3]] + InflateRect(clientRect, -GetSystemMetrics(SM_CXEDGE), -GetSystemMetrics(SM_CYEDGE)) + + If tmpIsFocused Then + + Local tmpBr = CreateSolidBrush($000000) + FrameRect(tmpDc, itemRect , tmpBr) + InflateRect(itemRect, -1, -1) + DeleteObject(tmpBr) + + EndIf + + Local crColor + If BgColor() < 0 Then crColor = GetSysColor(COLOR_BTNFACE) Else crColor = BgColor() + + Local brBackground = CreateSolidBrush(crColor) + + FillRect(tmpDc, itemRect, brBackground) + + DeleteObject(brBackground) + + ' Draw pressed button + If tmpIsPressed + + Local brBtnShadow = CreateSolidBrush(GetSysColor(COLOR_BTNSHADOW)) + FrameRect(tmpDc, itemRect, brBtnShadow) + DeleteObject(brBtnShadow) + + OffsetRect( clientRect, 1, 1 ) + + Else ' ...Else draw non pressed button + + Local tmpUState = DFCS_BUTTONPUSH + If _mouseoverbutton Then tmpUState :| DFCS_HOT + If tmpIsPressed Then tmpUState :| DFCS_PUSHED + + DrawFrameControl(tmpDc, itemRect, DFC_BUTTON, tmpUState) + + EndIf + + EndIf + + If BgColor() > -1 Then + Local brBackground = CreateSolidBrush(BgColor()) + FillRect(tmpDc, clientRect, brBackground) + DeleteObject(brBackground) + EndIf + + txtRect = clientRect[..] + + clientRect[RECT_RIGHT]:-clientRect[RECT_LEFT] + clientRect[RECT_BOTTOM]:-clientRect[RECT_TOP] + + ' Read the button's title + Local tmpText$ = Super.GetText() + + ' Draw the icon + 'DrawTheIcon(GetDlgItem(hDlg, IDC_OWNERDRAW_BTN), &dc, bHasTitle, &lpDIS.rcItem, &captionRect, bIsPressed, bIsDisabled) + + ' Write the button title (if any) + If tmpText Then + + Local tmpFlags = DT_CENTER|DT_WORDBREAK + + DrawTextW( tmpDc, tmpText, -1, txtRect, DT_CALCRECT|tmpFlags ) + + txtWidth = txtRect[RECT_RIGHT]-txtRect[RECT_LEFT] + txtHeight = txtRect[RECT_BOTTOM]-txtRect[RECT_TOP] + + txtRect[RECT_LEFT] = clientRect[RECT_LEFT] + (clientRect[RECT_RIGHT] - txtWidth)/2 + txtRect[RECT_TOP] = clientRect[RECT_TOP] + (clientRect[RECT_BOTTOM] - txtHeight)/2 + txtRect[RECT_RIGHT] = txtRect[RECT_LEFT] + txtWidth + txtRect[RECT_BOTTOM] = txtRect[RECT_TOP] + txtHeight + + Local tmpTextColor + If tmpIsDisabled Then + tmpTextColor = GetSysColor(COLOR_GRAYTEXT) + Else + If FgColor() < 0 Then tmpTextColor = GetSysColor(COLOR_BTNTEXT) Else tmpTextColor = FgColor() + EndIf + tmpTextColor = SetTextColor_(tmpDc,tmpTextColor) + + DrawTextW( tmpDc, tmpText, -1, txtRect, tmpFlags ) + + SetTextColor_(tmpDc,tmpTextColor) + + EndIf + + RestoreDC(tmpDc,tmpDcState) + + ' Draw the focus rect + If tmpIsFocused And tmpDrawFocusRect Then + Local focusRect:Int[4] + CopyRect(focusRect, itemRect) + InflateRect(focusRect, -3, -3) + SetMapMode(tmpDc, MM_TEXT) + DrawFocusRect(tmpDc, focusRect) + EndIf + + Return True + EndMethod + + Method OnCommand(msg,wp) + Select wp Shr 16 + Case BN_CLICKED + Select (style&7) + Case BUTTON_CHECKBOX + Select State()&STATE_INDETERMINATE + Case 0, STATE_INDETERMINATE + SetSelected(True) + Case STATE_SELECTED + SetSelected(False) + EndSelect + EndSelect + + PostGuiEvent EVENT_GADGETACTION,ButtonState(Self) + + 'Fix so that tooltips reappear on Windows XP + Local tmpTooltip$ = GetTooltip() + If tmpTooltip Then SetTooltip("");SetTooltip(tmpTooltip) + + EndSelect + EndMethod + + Method SetPixmap(pixmap:TPixmap,pFlags) + + Local tmpWindowStyle = GetWindowLongW(_hwnd,GWL_STYLE) + + If (pFlags & GADGETPIXMAP_ICON) And (((style&BUTTON_PUSH)=BUTTON_PUSH) Or (style = BUTTON_CANCEL)) Then + + 'To remove an image from a button, a handle-list of -1 should be passed. + If _buttonImageList[0] >= 0 Then ImageList_Destroy(_buttonImageList[0]);_buttonImageList[0] = -1 + If pixmap Then _buttonImageList[0] = BuildImageList( pixmap ) + + If (pFlags & GADGETPIXMAP_NOTEXT) Then + _buttonImageList[5] = BUTTON_IMAGELIST_ALIGN_CENTER + Else + _buttonImageList[5] = BUTTON_IMAGELIST_ALIGN_LEFT + EndIf + + 'If running Windows XP/Vista, let's use BCM_SETIMAGELIST + + If Not SendMessageW (_hwnd, BCM_SETIMAGELIST, 0, Int Byte Ptr _buttonImageList) Then + 'Otherwise, if this fails we should use BM_SETIMAGE. + + If _buttonImageList[0] >= 0 Then ImageList_Destroy(_buttonImageList[0]);_buttonImageList[0] = -1 + + If _iconBitmap Then DeleteObject(_iconBitmap);_iconBitmap = 0 + If pixmap Then _iconBitmap = TWindowsGraphic.BitmapFromPixmap( pixmap, True ) + + SendMessageW (_hwnd, BM_SETIMAGE, IMAGE_BITMAP, _iconBitmap) + + EndIf + + 'Show the text if there isn't a pixmap or if we haven't specified GADGETPIXMAP_NOTEXT. + If (Not pixmap) Or Not(pFlags & GADGETPIXMAP_NOTEXT) Then + tmpWindowStyle:&(~BS_BITMAP) + + 'Text isn't hidden on XP image buttons regardless of whether BS_BITMAP is set + 'so we have to hack this in - they must have fixed it on Vista though as it works fine there. + + Super.SetText( GetText() ) + Else + tmpWindowStyle:|BS_BITMAP + + 'Text isn't hidden on XP image buttons regardless of whether BS_BITMAP is set + 'so we have to hack this in - they must have fixed it on Vista though as it works fine there. + + Super.SetText( "" ) + EndIf + + SetWindowLongW _hwnd,GWL_STYLE,tmpWindowStyle + + InvalidateRect _hwnd, Null, False + + Return True + + EndIf + + EndMethod + + Method SetText(pText$) + Local oldText$ = _strButtonText + _strButtonText = pText + If (_buttonImageList[0] < 0 And Not _iconBitmap) Or (oldText = Super.GetText()) Then Super.SetText(pText) + EndMethod + + Method GetText$() + Return _strButtonText + EndMethod + + Method Free() + If _buttonImageList[0] >= 0 Then ImageList_Destroy(_buttonImageList[0]) + If _iconBitmap Then DestroyIcon( _iconBitmap );_iconBitmap = 0 + _buttonImageList = Null + Super.Free() + EndMethod + + Function BuildImageList(pixmap:TPixmap) + Local bitmap,imagelist,mask + If TWindowsGUIDriver.CheckCommonControlVersion() And (Pixmap.format=PF_RGBA8888 Or pixmap.format=PF_BGRA8888) + imagelist=ImageList_Create(pixmap.width,pixmap.height,ILC_COLOR32,0,1) + If imagelist + bitmap=TWindowsGraphic.BitmapFromPixmap(pixmap, True) + ImageList_Add(imagelist,bitmap,0) + EndIf + EndIf + If imagelist=0 + bitmap=TWindowsGraphic.BitmapFromPixmap(pixmap, False) + mask=TWindowsGraphic.BitmapMaskFromPixmap(pixmap) + imagelist=ImageList_Create(pixmap.width,pixmap.height,ILC_COLOR24|ILC_MASK,0,1) + ImageList_Add(imagelist,bitmap,mask) + DeleteObject(mask) + EndIf + DeleteObject(bitmap) + Return imagelist + EndFunction + + Method Class() + Return GADGET_BUTTON + EndMethod + +EndType + +Type TWindowsTextField Extends TWindowsGadget + + Field _busy + + Method Create:TWindowsGadget(group:TGadget,style,Text$="") + Local xstyle,wstyle,hotkey + Local hwnd,parent + Self.style = style + xstyle=WS_EX_CLIENTEDGE + wstyle=WS_CHILD|WS_TABSTOP|ES_AUTOHSCROLL|WS_CLIPSIBLINGS + If style&TEXTFIELD_PASSWORD Then wstyle:|ES_PASSWORD + parent=group.query(QUERY_HWND_CLIENT) + hwnd=CreateWindowExW(xstyle,"EDIT","",wstyle,0,0,0,0,parent,hotkey,GetModuleHandleW(Null),Null) + 'SendMessageW hwnd,WM_SETFONT,TWindowsGUIDriver.GDIFont.handle,1 + Register GADGET_TEXTFIELD,hwnd + SetColor(255,255,255) + Return Self + EndMethod + + Method SetText(Text$) + Local p0,p1 + _busy:+1 + SendMessageW _hwnd,EM_GETSEL,Int Byte Ptr Varptr p0,Int Byte Ptr Varptr p1 + Super.SetText(Text) + SendMessageW _hwnd,EM_SETSEL,p0,p1 + _busy:-1 + EndMethod + + Method Activate(cmd) + Select cmd + Case ACTIVATE_CUT + SendMessageW _hwnd,WM_CUT,0,0 + Case ACTIVATE_COPY + SendMessageW _hwnd,WM_COPY,0,0 + Case ACTIVATE_PASTE + SendMessageW _hwnd,WM_PASTE,0,0 + Case ACTIVATE_FOCUS + SendMessageW _hwnd,EM_SETSEL,0,-1 + End Select + Return Super.Activate(cmd) + EndMethod + + Method OnCommand(msg,wp) + If Not _busy + Select (wp Shr 16) + Case EN_UPDATE + PostGuiEvent EVENT_GADGETACTION + Case EN_KILLFOCUS + SendMessageW _hwnd,EM_SETSEL,0,0 + End Select + EndIf + EndMethod + + Method WndProc(hwnd,msg,wp,lp) + Local event:TEvent + Select msg + Case WM_ERASEBKGND + Return 1 + Case WM_KEYDOWN + If eventfilter<>Null + event=CreateEvent(EVENT_KEYDOWN,Self,wp,keymods()) + If Not eventfilter(event,context) Return True + EndIf + Case WM_CHAR + If eventfilter<>Null + event=CreateEvent(EVENT_KEYCHAR,Self,wp,keymods()) + If Not eventfilter(event,context) Return True + EndIf + Case WM_KILLFOCUS + PostGuiEvent EVENT_GADGETLOSTFOCUS + End Select + Return Super.WndProc(hwnd,msg,wp,lp) + EndMethod + + Method Class() + Return GADGET_TEXTFIELD + EndMethod + +EndType + +Type TWindowsTextArea Extends TWindowsGadget + + Global _ClassName:String = Null 'See InitializeLibrary(). + + Global _pagemargin# = 0.5 'Page margin for print-out in inches + + Field _locked + + Field cr1:CHARRANGE=New CHARRANGE + Field cr2:CHARRANGE=New CHARRANGE + Field cf:CHARFORMATW=New CHARFORMATW + + Field ole:IRichEditOLE + Field idoc:ITextDocument + Field busy,readonly + + Field IID_ITextDocument:GUID = New GUID + + Function _InitializeLibrary() + + If Not _ClassName Then + + 'Load RichEdit DLL + If Not LoadLibraryW("msftedit.dll") Then + If LoadLibraryW("riched20.dll") _ClassName = "RichEdit20W" + Else + _ClassName = "RICHEDIT50W" + EndIf + + EndIf + + EndFunction + + Method New() + _InitializeLibrary() + EndMethod + + Method Create:TWindowsGadget(group:TGadget,style,Text$="") + Local xstyle,wstyle,hotkey + Local hwnd,parent + Local res + + xstyle=WS_EX_CLIENTEDGE + wstyle=WS_CHILD|WS_VSCROLL|WS_CLIPSIBLINGS + wstyle:|ES_MULTILINE|ES_NOOLEDRAGDROP|ES_NOHIDESEL|ES_LEFT + If Not (style&TEXTAREA_WORDWRAP) wstyle:|WS_HSCROLL|ES_AUTOHSCROLL +' If (style&TEXTAREA_READONLY) wstyle:|ES_READONLY + If (style&TEXTAREA_READONLY) readonly=True + + Self.style = style + + parent=group.query(QUERY_HWND_CLIENT) + + 'RichText control should be made have dimensions of 1x1 pixels to fix Windows XP vertical scrollbar drawing bug. + hwnd=CreateWindowExW(xstyle,_ClassName,"",wstyle,0,0,1,1,parent,hotkey,GetModuleHandleW(Null),Null) + + SendMessageW hwnd,EM_SETLIMITTEXT,4*1024*1024,0 + SendMessageW hwnd,EM_SETEVENTMASK,0,ENM_CHANGE|ENM_MOUSEEVENTS|ENM_SELCHANGE|ENM_KEYEVENTS + SendMessageW hwnd,EM_SETUNDOLIMIT,0,0 + + SendMessageW hwnd,EM_GETOLEINTERFACE,0,Int Byte Ptr Varptr ole + res=IIDFromString(ITextDocument_UUID,IID_ITextDocument) + + res=ole.QueryInterface(IID_ITextDocument,Varptr idoc) + + Register GADGET_TEXTAREA,hwnd + Return Self + EndMethod + + Method Free() + If ole Then ole.Release_ + If idoc Then idoc.Release_ + Super.Free() + EndMethod + + Method Activate(cmd) + Select cmd + Case ACTIVATE_CUT + SendMessageW _hwnd,WM_CUT,0,0 + Case ACTIVATE_COPY + SendMessageW _hwnd,WM_COPY,0,0 + SetFocus _hwnd + Case ACTIVATE_PASTE + DoPaste + Case ACTIVATE_PRINT + DoPrint + Default + Return Super.Activate(cmd) + End Select + EndMethod + + Method DoPaste() + Local h,handle,n + Local w:Short Ptr,cp:Short Ptr + Local tp:Byte Ptr,bp:Byte Ptr + + If OpenClipboard(_hwnd) + If IsClipboardFormatAvailable(CF_UNICODETEXT) + handle=GetClipboardData(CF_UNICODETEXT) + n=GlobalSize(handle) + w=Short Ptr GlobalLock(handle) + h=GlobalAlloc(GMEM_MOVEABLE,n) + cp=Short Ptr GlobalLock(h) + memcpy_(cp,w,n) + If cp[n/2-2]=10 Then cp[n/2-2]=13 + GlobalUnlock h + GlobalUnlock handle + If h + EmptyClipboard + SetClipboardData CF_UNICODETEXT,h + EndIf + ElseIf IsClipboardFormatAvailable(CF_OEMTEXT) + handle=GetClipboardData(CF_OEMTEXT) + n=GlobalSize(handle) + tp=Byte Ptr GlobalLock(handle) + h=GlobalAlloc(GMEM_MOVEABLE,n) + bp=Byte Ptr GlobalLock(h) + memcpy_(bp,tp,n) + If bp[n-2]=10 Then bp[n-2]=13 + GlobalUnlock h + GlobalUnlock handle + If h + EmptyClipboard + SetClipboardData CF_OEMTEXT,h + EndIf + EndIf + CloseClipboard + SendMessageW _hwnd,WM_PASTE,0,0 + SetFocus _hwnd + EndIf + EndMethod + + Method DoPrint() + + Local tmpTextSelLen = TextAreaSelLen(Self) + + Local tmpPrintDialog:PRINTDLGW = New PRINTDLGW + + tmpPrintDialog.flags = PD_RETURNDC | PD_HIDEPRINTTOFILE | PD_NOPAGENUMS + If Not tmpTextSelLen Then tmpPrintDialog.flags:|PD_NOSELECTION + + tmpPrintDialog.hwndOwner = _hwnd + + If Not PrintDlg( Byte Ptr tmpPrintDialog ) Then Return 0 + + Local hdcPrinter = tmpPrintDialog.hdc + + Local tmpDoc:DOCINFOW = New DOCINFOW + Local tmpDocTitle:Short Ptr = AppTitle.ToWString() + tmpDoc.lpszDocName = tmpDocTitle + + Local tmpSuccess = (StartDocW( hdcPrinter, Byte Ptr tmpDoc ) > 0) + + If tmpSuccess Then + + Local _cursor = TWindowsGUIDriver._cursor + + SetPointer( POINTER_WAIT ) + + SetMapMode( hdcPrinter, MM_TEXT ) + + Local wPage = GetDeviceCaps( hdcPrinter, PHYSICALWIDTH ) + Local hPage = GetDeviceCaps( hdcPrinter, PHYSICALHEIGHT ) + Local xPPI = GetDeviceCaps( hdcPrinter, LOGPIXELSX ) + Local yPPI = GetDeviceCaps( hdcPrinter, LOGPIXELSY ) + + Local tmpTextLengthStruct[] = [GTL_DEFAULT,1200] + Local tmpTextLength = SendMessageW (_hwnd, EM_GETTEXTLENGTHEX, Int Byte Ptr tmpTextLengthStruct, 0) + + Local tmpTextPrinted, tmpFormatRange:FORMATRANGE = New FORMATRANGE + + tmpFormatRange.hdc = hdcPrinter + tmpFormatRange.hdcTarget = hdcPrinter + + tmpFormatRange.rcPageRight = (wPage*1440:Long)/xPPI + tmpFormatRange.rcPageBottom = (hPage*1440:Long)/yPPI + + tmpFormatRange.rcLeft = (1440*_pagemargin);tmpFormatRange.rcTop = (1440*_pagemargin) + tmpFormatRange.rcRight = tmpFormatRange.rcPageRight - (2880*_pagemargin) + tmpFormatRange.rcBottom = tmpFormatRange.rcPageBottom - (2880*_pagemargin) + + If tmpPrintDialog.flags & PD_SELECTION Then + tmpTextPrinted = TextAreaCursor(Self) + tmpFormatRange.CHARRANGE_cpMax = tmpTextPrinted+tmpTextSelLen + Else + tmpFormatRange.CHARRANGE_cpMax = tmpTextLength + EndIf + + SendMessageW (_hwnd, EM_FORMATRANGE, False, 0) + + While tmpSuccess And ( tmpTextPrinted < tmpFormatRange.CHARRANGE_cpMax ) + + tmpFormatRange.CHARRANGE_cpMin = tmpTextPrinted + + tmpSuccess = (StartPage(hdcPrinter) > 0) + If Not tmpSuccess Then Exit + + tmpTextPrinted = SendMessageW( _hwnd, EM_FORMATRANGE, True, Int Byte Ptr tmpFormatRange ) + + tmpSuccess = (EndPage(hdcPrinter) > 0) + + Wend + + If tmpSuccess Then EndDoc( hdcPrinter ) Else AbortDoc( hdcPrinter ) + + SendMessageW (_hwnd, EM_FORMATRANGE, False, 0) + + TWindowsGUIDriver._cursor = _cursor + SetCursor _cursor + + EndIf + + GlobalFree( tmpPrintDialog.hDevMode ) + GlobalFree( tmpPrintDialog.hDevNames ) + DeleteDC( hdcPrinter ) + + MemFree tmpDocTitle + + Return tmpSuccess + + EndMethod + + Global gt[] = [GTL_DEFAULT, CP_ACP] + + Method CharCount() + Return SendMessageW(_hwnd,EM_GETTEXTLENGTHEX,Int Byte Ptr gt,0) + EndMethod + + Method SetStyle(r,g,b,flags,pos,length,units) + Local iifont:ITextFont + Local iirange:ITextRange + Local res, tmpOutput + If units=TEXTAREA_LINES + Local n=pos + pos=CharAt(pos) + If length>=0 length=CharAt(n+length)-pos + EndIf + If length<0 length=charcount()-pos + busy:+1 + res=idoc.Range(pos,pos+length,iirange) + res=iirange.GetFont(iifont) + res=iifont.SetForeColor(((b Shl 16)|(g Shl 8)|r)) + If (flags&TEXTFORMAT_BOLD) Then iifont.SetBold(TOMTRUE) Else iifont.SetBold(TOMFALSE) + If (flags&TEXTFORMAT_ITALIC) Then iifont.SetItalic(TOMTRUE) Else iifont.SetItalic(TOMFALSE) + If (flags&TEXTFORMAT_UNDERLINE) Then iifont.SetUnderline(TOMSINGLE) Else iifont.SetUnderline(TOMFALSE) + If (flags&TEXTFORMAT_STRIKETHROUGH) Then iifont.SetStrikeThrough(TOMTRUE) Else iifont.SetStrikeThrough(TOMNONE) + iifont.Release_ + iirange.Release_ + busy:-1 + EndMethod + + Method InsertText(Text$,pos,count) + Local iirange:ITextRange + Local bstr:Short Ptr, tmpWString:Short Ptr = Text.toWString() + Local res, bool + busy:+1 + res=idoc.Range(pos,pos+count,iirange) + bstr=SysAllocStringLen(tmpWString,Text.length);MemFree tmpWString + LockText() + res=iirange.SetText(bstr) + UnlockText() + SysFreeString bstr + iirange.Release_ + busy:-1 + EndMethod + + Method ReplaceText(pos,length,Text$,units) + If units=TEXTAREA_LINES + Local n=pos + pos=CharAt(pos) + If length>=0 length=CharAt(n+length)-pos + EndIf + If length<0 Then length=charcount()-pos + InsertText Text,pos,length + EndMethod + + Method AreaText$(pos,length,units) + Local iirange:ITextRange + Local bstr:Short Ptr + + If units=TEXTAREA_LINES + Local n=pos + pos=CharAt(pos) + If length>=0 length=CharAt(n+length)-pos + EndIf + If length<0 length=charcount()-pos + idoc.Range(pos,pos+length,iirange) + iirange.GetText(Varptr bstr) + Local Text$=String.FromWString(bstr) + SysFreeString bstr + iirange.Release_ + Text=Text.Replace(Chr(13),Chr(10)) + Return Text + EndMethod + + Method SetSelection(pos,length,units) + If units=TEXTAREA_LINES + Local n=pos + pos=CharAt(pos) + If length>0 + length=CharAt(n+length) + length=length-pos + EndIf + EndIf + If length<0 length=charcount()-pos + Local cr:CHARRANGE = New CHARRANGE + cr.cpMin=pos + cr.cpMax=pos+length + Desensitize() + SendMessageW _hwnd,EM_EXSETSEL,0,Int Byte Ptr(cr) + Sensitize() + EndMethod + + Method SetMargins(leftmargin) + SendMessageW _hwnd,EM_SETMARGINS,EC_LEFTMARGIN,leftmargin + EndMethod + + ' 72 points per inch + + Method SetTabs(tabs) + Local hdc=GetDC( 0 ) + idoc.SetDefaultTabStop tabs * 72.0 / GetDeviceCaps( hdc,LOGPIXELSX ) + ReleaseDC 0,hdc + EndMethod + + Method SetTextColor(r,g,b) + cf.cbSize=SizeOf(CHARFORMATW) + cf.dwMask=CFM_COLOR|CFM_BOLD|CFM_ITALIC + cf.crTextColor=(b Shl 16)|(g Shl 8)|r + SendMessageW _hwnd,EM_SETCHARFORMAT,SCF_DEFAULT,Int Byte Ptr cf + SendMessageW _hwnd,EM_SETCHARFORMAT,SCF_ALL,Int Byte Ptr cf + EndMethod + + Method SetColor(r,g,b) + SendMessageW _hwnd,EM_SETBKGNDCOLOR,0,((b Shl 16)|(g Shl 8)|r) + EndMethod + + Method RemoveColor() + SendMessageW _hwnd,EM_SETBKGNDCOLOR,1,0 + EndMethod + + Method GetCursorPos(units) + Local cr:CHARRANGE = New CHARRANGE + SendMessageW _hwnd,EM_EXGETSEL,0,Int Byte Ptr(cr) + Local pos=cr.cpMin + If units=TEXTAREA_LINES pos=LineAt(pos) + Return pos + EndMethod + + Method GetSelectionLength(units) + Local cr:CHARRANGE = New CHARRANGE + SendMessageW _hwnd,EM_EXGETSEL,0,Int Byte Ptr(cr) + If units=TEXTAREA_LINES + Return LineAt(cr.cpMax-1)-LineAt(cr.cpMin)+1 + Else + Return cr.cpMax-cr.cpMin + EndIf + EndMethod + + Method CharAt(Line) + If Line<0 Return + If Line>AreaLen(TEXTAREA_LINES) Return charcount() + Return SendMessageW(_hwnd,EM_LINEINDEX,Line,0) + EndMethod + + Method LineAt(pos) + If pos<0 Return + If pos>charcount() Return AreaLen(TEXTAREA_LINES) + Return SendMessageW(_hwnd,EM_EXLINEFROMCHAR,0,pos) + EndMethod + + Method AreaLen(units) + If units=TEXTAREA_LINES Return LineAt(charcount()) + Return charcount() + EndMethod + + Method CharX( char ) + Local tmpPoint[2] + SendMessageW(_hwnd, EM_POSFROMCHAR, Int Byte Ptr tmpPoint, char ) + Return tmpPoint[0] + EndMethod + + Method CharY( char ) + Local tmpPoint[2] + SendMessageW(_hwnd, EM_POSFROMCHAR, Int Byte Ptr tmpPoint, char ) + Return tmpPoint[1] + EndMethod + + Method SetText(Text$) + InsertText Text,0,charcount() + EndMethod + + Method AddText(Text$) + InsertText Text,charcount(),0 + Local cr:CHARRANGE = New CHARRANGE + Local p = charcount() + cr.cpMin=p + cr.cpMax=p + SendMessageW _hwnd,EM_EXSETSEL,0,Int Byte Ptr(cr) + EndMethod + + Method GetText$() + Return AreaText(0,charcount(),TEXTAREA_CHARS) + EndMethod + + Global _oldCursor = 0 + Field _oldSelPos%, _oldSelLen% = 0 + + Method LockText() + + If Not idoc.Freeze(_locked) + _oldSelPos = GetCursorPos(TEXTAREA_CHARS) + _oldSelLen = GetSelectionLength(TEXTAREA_CHARS) + If Not _oldCursor Then _oldCursor = GetCursor() + EndIf + + EndMethod + + Method UnlockText() + + If idoc.Unfreeze(_locked) = S_OK Then + SetSelection( _oldSelPos, _oldSelLen, TEXTAREA_CHARS ) + If _oldCursor And (_oldCursor <> GetCursor()) Then + SetCursor(_oldCursor) + EndIf + _oldCursor = 0 + EndIf + + EndMethod + + Method OnCommand(msg,wp) + If busy Then Return + Select wp Shr 16 + Case EN_CHANGE + If Not _locked Then PostGuiEvent EVENT_GADGETACTION + End Select + EndMethod + + Method OnNotify(wp,lp) + Local nmhdr:Int Ptr + Local event:TEvent + + Super.OnNotify(wp,lp) 'Tooltip + + nmhdr=Int Ptr(lp) + Select nmhdr[2] +' Case EN_PROTECTED +' DebugStop + Case EN_SELCHANGE + If Not (busy Or _locked) + PostGuiEvent EVENT_GADGETSELECT + EndIf + Case EN_MSGFILTER + Select nmhdr[3] + Case WM_RBUTTONDOWN + If GetSelectionLength(TEXTAREA_CHARS)=0 nmhdr[3]=WM_LBUTTONDOWN + Case WM_RBUTTONUP + Local mx=nmhdr[5] & $ffff + Local my=nmhdr[5] Shr 16 + PostGuiEvent EVENT_GADGETMENU,0,0,mx,my + Case WM_KEYDOWN + + Local k=nmhdr[4] + + 'Filtering out special shortcut combinations + If (keymods()&MODIFIER_CONTROL) Then + Select k + Case 76,69,82 'ctrl+l, ctrl+e, ctrl+r + Return 1 'Alignment shortcuts + + Case 188,190 'ctrl+<, ctrl+> + 'Font size shortcuts + If (keymods()&MODIFIER_SHIFT) Then Return 1 + EndSelect + EndIf + + 'Read-only + If readonly + If k>=33 And k<=40 Return 0 'selection keys + If (keymods()&MODIFIER_CONTROL) Then + Select k + Case 65, 67;Return 0 'ctrl-a, ctrl+c + EndSelect + EndIf + Return 1 + EndIf + + 'Event Filter + If eventfilter<>Null + event=CreateEvent(EVENT_KEYDOWN,Self,k,keymods()) + Return Not eventfilter(event,context) + EndIf + + Case WM_CHAR + If readonly Return 1 + If eventfilter<>Null + event=CreateEvent(EVENT_KEYCHAR,Self,nmhdr[4],keymods()) + Return Not eventfilter(event,context) + EndIf + End Select + End Select + EndMethod + + Method WndProc(hwnd,msg,wp,lp) + Select msg + + Case WM_MOUSEWHEEL + If (wp&MK_CONTROL) Then SendMessageW _hwnd, EM_SETZOOM, 0, 0 + + Case WM_KILLFOCUS + PostGuiEvent EVENT_GADGETLOSTFOCUS + + End Select + + Return Super.WndProc(hwnd,msg,wp,lp) + + EndMethod + + Method Class() + Return GADGET_TEXTAREA + EndMethod + +EndType + +Type TWindowsListBox Extends TWindowsGadget + + Field _icons:TWindowsIconStrip + Field _selected = -1 + + Method Create:TWindowsGadget(group:TGadget,style,Text$="") + Local xstyle,wstyle,hotkey + Local hwnd,parent + + Self.style = style + + xstyle=WS_EX_CLIENTEDGE + wstyle=WS_CHILD|WS_TABSTOP|LVS_REPORT|LVS_NOCOLUMNHEADER|LVS_SHOWSELALWAYS|LVS_SHAREIMAGELISTS + wstyle:|WS_CLIPSIBLINGS + + If (style&LISTBOX_MULTISELECT<>LISTBOX_MULTISELECT) Then wstyle:|LVS_SINGLESEL + + parent=group.query(QUERY_HWND_CLIENT) + hwnd=CreateWindowExW(xstyle,"SysListView32","",wstyle,0,0,20,20,parent,hotkey,GetModuleHandleW(Null),Null) + + Local column:LVCOLUMNW + column=New LVCOLUMNW + SendMessageW hwnd,LVM_INSERTCOLUMNW,0,Int Byte Ptr(column) + + SendMessageW hwnd,LVM_SETEXTENDEDLISTVIEWSTYLE,LVS_EX_FULLROWSELECT|LVS_EX_INFOTIP,LVS_EX_FULLROWSELECT|LVS_EX_INFOTIP + + If TWindowsGUIDriver.CheckCommonControlVersion() Then SendMessageW hwnd,LVM_SETEXTENDEDLISTVIEWSTYLE,LVS_EX_DOUBLEBUFFER,LVS_EX_DOUBLEBUFFER + + Register GADGET_LISTBOX,hwnd,0,False 'Set to True for normal Tooltips + + If TWindowsGUIDriver._explorerstyle Then UseExplorerTheme() + + Return Self + EndMethod + + Method SetColor(r,g,b) + SendMessageW _hwnd,LVM_SETBKCOLOR ,0,(b Shl 16)|(g Shl 8)|r + SendMessageW _hwnd,LVM_SETTEXTBKCOLOR ,0,(b Shl 16)|(g Shl 8)|r + EndMethod + + Method RemoveColor() + SendMessageW _hwnd,LVM_SETBKCOLOR ,1,0 + SendMessageW _hwnd,LVM_SETTEXTBKCOLOR ,1,0 + EndMethod + + Method SetTextColor(r,g,b) + SendMessageW _hwnd,LVM_SETTEXTCOLOR,0,(b Shl 16)|(g Shl 8)|r + EndMethod + + 'Hack: When image lists are removed from listviews, the items don't + 'reposition themselves automatically. Hack involves first setting a tiny + 'blank image-list to update item size, before attempting to remove it. + Method SetIconStrip(iconstrip:TIconStrip) + Local imagelist + If Not iconstrip Then + _icons = TWindowsIconStrip.CreateBlank() + Else + _icons = TWindowsIconStrip(iconstrip) + EndIf + If _icons Then imagelist = _icons._imagelist + SendMessageW _hwnd,LVM_SETIMAGELIST,LVSIL_SMALL,imagelist + If Not iconstrip Then + SendMessageW _hwnd,LVM_SETIMAGELIST,LVSIL_SMALL,0 + _icons = Null + EndIf + EndMethod + + Method ClearListItems() + _selected=-1 + DeSensitize() + SendMessageW _hwnd,LVM_DELETEALLITEMS,0,0 + If Not IsSingleSelect() Then SelectionChanged() + Sensitize() + EndMethod + + Method InsertListItem(index,Text$,tip$,icon,tag:Object) + + Local it:LVITEMW + it=New LVITEMW + it.mask=LVIF_TEXT|LVIF_DI_SETITEM + it.iItem=index + it.pszText=Text.toWString() + + 'If icon>=0 Then + it.mask:|LVIF_IMAGE + it.iImage=icon + 'EndIf + + Desensitize() + SendMessageW _hwnd,LVM_INSERTITEMW,0,Int Byte Ptr(it) + SendMessageW _hwnd,LVM_SETCOLUMNWIDTH,0,-2 + If Not IsSingleSelect() Then SelectionChanged() + Sensitize() + MemFree it.pszText + + EndMethod + + Method SetListItem(index,Text$,tip$,icon,tag:Object) + Local tmpReselect + If ListItemState(index) & STATE_SELECTED Then tmpReselect = True + RemoveListItem index + InsertListItem index,Text,tip,icon,tag + If tmpReselect Then SetItemState(index,STATE_SELECTED) + EndMethod + + Method RemoveListItem(index) + Desensitize() + If ListItemState(index) & STATE_SELECTED Then _selected = -1 + SendMessageW _hwnd,LVM_DELETEITEM,index,0 + SendMessageW _hwnd,LVM_SETCOLUMNWIDTH,0,-2 + If Not IsSingleSelect() Then SelectionChanged() + Sensitize() + EndMethod + + Method SetListItemState(index,state) + Local it:LVITEMW = New LVITEMW + it.mask=LVIF_STATE + it.iItem=index + If state&STATE_SELECTED + it.state=LVIS_SELECTED + If IsSingleSelect() Then _selected=index + ElseIf _selected=index + _selected=-1 + EndIf + it.stateMask=LVIS_SELECTED + Desensitize() + SendMessageW _hwnd,LVM_SETITEMSTATE,index,Int Byte Ptr(it) + If it.state Then SendMessageW _hwnd,LVM_ENSUREVISIBLE,index,False + If Not IsSingleSelect() Then SelectionChanged() + Sensitize() + EndMethod + + Method ListItemState(index) + Local state = SendMessageW(_hwnd,LVM_GETITEMSTATE,index,LVIS_SELECTED) + If state&LVIS_SELECTED Return STATE_SELECTED + EndMethod + + Method SetTooltip( pTooltip$ ) + 'ToolTips should be set on an item-by-item basis instead. + EndMethod + + Method WndProc(hwnd,msg,wp,lp) + Select msg + Case WM_MAXGUILISTREFRESH + Local index + + If IsSingleSelect() Then + index=SendMessageW(_hwnd,LVM_GETNEXTITEM,-1,LVNI_SELECTED) + Else + index = SelectionChanged() + EndIf + If index <> _selected Then + If IsSingleSelect() Then _selected = index + Local item:TGadgetItem = New TGadgetItem + If index>=0 And index=0 And index-1 + _selected=-1 + PostGuiEvent EVENT_GADGETSELECT,-1 + EndIf + Case NM_RCLICK + index=nmhdr[3] + Local item:TGadgetItem + If index>=0 And indexLISTBOX_MULTISELECT) + EndMethod + + Method Class() + Return GADGET_LISTBOX + EndMethod + + Method HasResized() + SendMessageW _hwnd,LVM_SETCOLUMNWIDTH,0,-2 + EndMethod + + Method UseExplorerTheme() + If TWindowsGUIDriver.CheckCommonControlVersion() And SetWindowThemeW Then SetWindowThemeW( _hwnd, _wstrExplorer, Null ) + EndMethod + +EndType + +Type TWindowsComboBox Extends TWindowsGadget + + Field _icons:TWindowsIconStrip + Field _editHwnd, _comboHwnd + Field _selected = -1 + + Method Create:TWindowsGadget(group:TGadget,style,Text$="") + Local xstyle,wstyle,hotkey,hwnd + Local parent,editstyle,combostyle + + Self.style = style + wstyle=WS_CHILD|WS_TABSTOP|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|CBS_AUTOHSCROLL + If (style & COMBOBOX_EDITABLE) Then wstyle:|CBS_DROPDOWN Else wstyle:|CBS_DROPDOWNLIST + + parent=group.query(QUERY_HWND_CLIENT) + hwnd=CreateWindowExW(xstyle,"ComboBoxEx32","",wstyle,0,0,0,180,parent,hotkey,GetModuleHandleW(Null),Null) + + If (style & COMBOBOX_EDITABLE) Then + _editHwnd=SendMessageW(hwnd,CBEM_GETEDITCONTROL,0,0) + If _editHwnd Then + editstyle=GetWindowLongW(_editHwnd,GWL_STYLE) + SetWindowLongW _editHwnd,GWL_STYLE,editstyle|WS_TABSTOP + EndIf + EndIf + + _comboHwnd=SendMessageW(hwnd,CBEM_GETCOMBOCONTROL,0,0) + comboStyle=GetWindowLongW(_comboHwnd,GWL_STYLE) + SetWindowLongW _comboHwnd,GWL_STYLE,comboStyle|WS_TABSTOP + + Register GADGET_COMBOBOX,hwnd + + TWindowsGUIDriver.RegisterHwnd(_combohwnd,Self) + If _edithwnd Then TWindowsGUIDriver.RegisterHwnd(_edithwnd,Self) + + SetColor(255,255,255) + + Return Self + + EndMethod + + Method SetText(Text$) + If Not _editHwnd Then + Local tmpWString:Short Ptr = Text.ToWString() + Local tmpResult = SendMessageW(_comboHwnd, CB_SETCUEBANNER, 0, Int(tmpWString)) + MemFree tmpWString;Return tmpResult + Else + Return Super.SetText(Text) + EndIf + EndMethod + + Method GetText$() + If Not _editHwnd Then + If _selected > -1 Then Return items[_selected].Text Else Return "" + Else + Return Super.GetText() + EndIf + EndMethod + + Method Activate(cmd) + If _editHwnd Then + Select cmd + Case ACTIVATE_CUT + SendMessageW _editHwnd,WM_CUT,0,0 + Case ACTIVATE_COPY + SendMessageW _editHwnd,WM_COPY,0,0 + SetFocus _hwnd + Case ACTIVATE_PASTE + SendMessageW _editHwnd,WM_PASTE,0,0 + Case ACTIVATE_FOCUS + SendMessageW _editHwnd,EM_SETSEL,0,-1 + End Select + EndIf + Return Super.Activate(cmd) + EndMethod + + Method SetIconStrip(iconstrip:TIconStrip) + Local imagelist + _icons=TWindowsIconStrip(iconstrip) + If _icons Then imagelist = _icons._imagelist + SendMessageW _hwnd,CBEM_SETIMAGELIST,LVSIL_SMALL,imagelist + EndMethod + + Method ClearListItems() + _selected=-1 + Desensitize() + SendMessageW _hwnd,CB_RESETCONTENT,0,0 + Sensitize() + EndMethod + + Method InsertListItem(index,Text$,tip$,icon,tag:Object) + Local it:COMBOBOXEXITEMW = New COMBOBOXEXITEMW + it.mask=CBEIF_TEXT + it.iItem=index + it.pszText=Text.toWString() + If icon>=0 + it.mask:|CBEIF_IMAGE|CBEIF_SELECTEDIMAGE + it.iImage=icon + it.iSelectedImage=icon + EndIf + Desensitize() + SendMessageW(_hwnd,CBEM_INSERTITEMW,0,Int Byte Ptr(it)) + Sensitize() + MemFree it.pszText + EndMethod + + Method SetListItem(index,Text$,tip$,icon,tag:Object) + Local it:COMBOBOXEXITEMW = New COMBOBOXEXITEMW + it.mask=CBEIF_TEXT + it.iItem=index + it.pszText=Text.toWString() + If _icons And icon>-1 + it.mask:|CBEIF_IMAGE|CBEIF_SELECTEDIMAGE + it.iImage=icon + it.iSelectedImage=icon + EndIf + Desensitize() + SendMessageW(_hwnd,CBEM_SETITEMW,0,Int Byte Ptr(it)) + Sensitize() + MemFree it.pszText + EndMethod + + Method RemoveListItem(index) + Desensitize() + SendMessageW _hwnd,CBEM_DELETEITEM,index,0 + Sensitize() + EndMethod + + Method SetListItemState(index,state) + If state&STATE_SELECTED + _selected=index + Else + If _selected=index _selected=-1 + index=-1 + EndIf + Desensitize() + SendMessageW _hwnd,CB_SETCURSEL,index,0 + Sensitize() + EndMethod + + Method ListItemState(index) + Local Current,state + Current=SendMessageW(_hwnd,CB_GETCURSEL,0,0) + If Current=CB_ERR Current=-1 + If Current=index state=STATE_SELECTED + Return state + EndMethod + + Method OnCommand(msg,wp) + Local index + Select wp Shr 16 + Case CBN_SELCHANGE + index=SendMessageW(_hwnd,CB_GETCURSEL,0,0) + If index=CB_ERR + index=-1 + Else + If _selected<>index 'user generated event + _selected=index + Local extra:Object + If index>=0 And index tmpHeight Then + TWindowsGadget(parent)._clientY = tmpHeight + parent.Rethink() + TWindowsGadget(parent).RethinkClient() + parent.LayoutKids() + EndIf + EndMethod + + Method DoLayout() + Rethink() + EndMethod + + Method SetTooltip( pTooltip$ ) + 'ToolTips should be set on an item-by-item basis instead. + EndMethod + + Method ClearListItems() + While SendMessageW(_hwnd,TB_BUTTONCOUNT,0,0) + RemoveListItem(0) + Wend + EndMethod + + Method InsertListItem(index,Text$,tip$,icon,tag:Object) + Local but:TBBUTTON + but=New TBBUTTON + but.fsState=TBSTATE_ENABLED + If icon = -2 Or (icon>-1 And _icons.IsBlankIcon(icon)) + but.idCommand=0 + but.fsStyle=TBSTYLE_SEP + Else + but.iBitmap=icon + but.idCommand=index+1 + but.fsStyle=TBSTYLE_BUTTON + EndIf + Desensitize() + SendMessageW _hwnd,TB_INSERTBUTTON,index,Int Byte Ptr(but) + Sensitize() + If tip + Local ti:TOOLINFOW=New TOOLINFOW + ti.cbSize=SizeOf(ti) + ti.uFlags=TTF_SUBCLASS + ti.hwnd=_hwnd + ti.lpszText=tip.towstring() + ti.uId=index+1 + SendMessageW _hwnd,TB_GETITEMRECT,index,Int(Varptr ti.rect_left) + SendMessageW _tooltips,TTM_ADDTOOLW,0,Int Byte Ptr(ti) + MemFree ti.lpszText + EndIf + EndMethod + + Method SetListItem(index,Text$,tip$,icon,tag:Object) + Local tmpState:Int = ListItemState(index) + RemoveListItem index + InsertListItem index,Text,tip,icon,tag + SetListItemState(index,tmpState) + EndMethod + + Method RemoveListItem(index) + Local ti:TOOLINFOW=New TOOLINFOW + ti.cbSize=SizeOf(ti) + ti.hwnd=_hwnd + ti.uId=index+1 + Desensitize() + SendMessageW _tooltips,TTM_DELTOOLW,0,Int(Varptr ti) + SendMessageW _hwnd,TB_DELETEBUTTON,index,0 + Sensitize() + EndMethod + + Method SetListItemState(index,state) + Local enable,pressed + If state&STATE_DISABLED=0 enable=$1 + If state&STATE_SELECTED pressed=$1 + SendMessageW _hwnd,TB_ENABLEBUTTON,index+1,enable + SendMessageW _hwnd,TB_CHECKBUTTON,index+1,pressed + EndMethod + + Method ListItemState(index) + Local state,flags + state=SendMessageW(_hwnd,TB_GETSTATE,index+1,0) + If state=-1 Return 0 + If Not (state&TBSTATE_ENABLED) flags:|STATE_DISABLED + If state&TBSTATE_CHECKED flags:|STATE_SELECTED + Return flags + EndMethod + + Method OnCommand(msg,wp) + Local index=wp-1 + Local extra:Object + If index>=0 And indexRect[0] Then Return Rect[2]-Rect[0] + EndMethod + + Method ClientHeight() + Local Rect[] = [0,0,width,height] + SendMessageW _hwnd,TCM_ADJUSTRECT,False,Int Byte Ptr(Rect) + If Rect[3]>Rect[1] Then Return Rect[3]-Rect[1] + EndMethod + + Method ClearListItems() + _tabcount=0 + _selected=-1 + Desensitize() + SendMessageW _hwnd,TCM_DELETEALLITEMS, 0, 0 + Sensitize() + RethinkClient() + EndMethod + + Method InsertListItem(index,Text$,tip$,icon,tag:Object) + If _tabcount=0 SendMessageW _hwnd,TCM_DELETEALLITEMS,0,0 + Local t:TCITEMW=New TCITEMW + t.mask=TCIF_TEXT|TCIF_IMAGE + t.pszText=Text.toWString() + t.iImage=icon + Desensitize() + SendMessageW _hwnd,TCM_INSERTITEMW,index,Int Byte Ptr(t) + Sensitize() + MemFree t.pszText + _tabcount:+1 + RethinkClient() + EndMethod + + Method SetListItem(index,Text$,tip$,icon,tag:Object) + Local t:TCITEMW=New TCITEMW + t.mask=TCIF_TEXT|TCIF_IMAGE + t.pszText=Text.toWString() + t.iImage=icon + Desensitize() + SendMessageW _hwnd,TCM_SETITEMW,index,Int Byte Ptr(t) + Sensitize() + MemFree t.pszText + RethinkClient() + EndMethod + + Method RemoveListItem(index) + Desensitize() + SendMessageW _hwnd,TCM_DELETEITEM,index,0 + _tabcount:-1 + _selected=SendMessageW(_hwnd,TCM_GETCURSEL,0,0) + If _tabcount=0 SendMessageW _hwnd,TCM_INSERTITEMW,0,Int(_blank) + Sensitize() + RethinkClient() + EndMethod + + Method SetListItemState(index,state) + Desensitize() + If state&STATE_SELECTED + _selected=index + SendMessageW _hwnd,TCM_SETCURSEL,index,0 + ElseIf _selected=index + _selected=-1 + EndIf + Sensitize() + EndMethod + + Method ListItemState(index) + Local state,Current + Current=-1 + If _tabcount Current=SendMessageW(_hwnd,TCM_GETCURSEL,0,0) + If Current=index state:|STATE_SELECTED + Return state + EndMethod + + Method OnNotify(wp,lp) + Local nmhdr:Int Ptr 'hwnd,id,code + Local index + nmhdr=Int Ptr(lp) + Select nmhdr[2] + + Case TTN_GETDISPINFOW + + Local TCHITTESTINFO[3], Rect[4] + + GetCursorPos_( TCHITTESTINFO );GetWindowRect( _hwnd, Rect ) + TCHITTESTINFO = [TCHITTESTINFO[0]-Rect[0],TCHITTESTINFO[1]-Rect[1],0] + + Local tmpItem = SendMessageW( _hwnd, TCM_HITTEST, 0, Int Byte Ptr TCHITTESTINFO ) + + If (tmpItem > -1) And (tmpItem < items.length) Then + Local tmpTooltip$ = items[tmpItem].tip + If (items[tmpItem].flags&GADGETITEM_LOCALIZED) Then tmpTooltip = LocalizeString(tmpTooltip) + SetTipBuffer( tmpTooltip ) + If tmpTooltip Then nmhdr[3] = Int(_tipbuffer) + EndIf + + Case TCN_SELCHANGE + If _tabcount + index=SendMessageW(_hwnd,TCM_GETCURSEL,0,0) + If index<>_selected + Local extra:Object + If index>=0 And index= items.length) Then index = -1 Else extra = items[index].extra + + PostGuiEvent EVENT_GADGETMENU,index,0,TCHITTESTINFO[0],TCHITTESTINFO[1],extra + + EndSelect + EndMethod + + Method WndProc(hwnd,msg,wp,lp) + Select msg + Case WM_ERASEBKGND + Select hwnd + Case _hwndclient + If DrawThemeParentBackground Then + DrawParentBackground(wp,hwnd) + Return 1 + EndIf + EndSelect + End Select + Return Super.WndProc(hwnd,msg,wp,lp) + EndMethod + + Method RethinkClient(forceRedraw:Int = False) + Local Rect[] = [0,0,width,height] + SendMessageW _hwnd,TCM_ADJUSTRECT,False, Int Byte Ptr(Rect) + MoveWindow _hwndclient,Rect[RECT_LEFT],Rect[RECT_TOP],Rect[RECT_RIGHT]-Rect[RECT_LEFT],Rect[RECT_BOTTOM]-Rect[RECT_TOP],forceRedraw + EndMethod + + Method SetTipBuffer( pTip$ ) + If _tipbuffer Then MemFree _tipbuffer + If pTip Then _tipbuffer = pTip.ToWString() + EndMethod + + Method SetTooltip( pTooltip$ ) + 'ToolTips should be set on an item-by-item basis instead. + EndMethod + + Method Class() + Return GADGET_TABBER + EndMethod + +EndType + +Type TWindowsTreeNode Extends TGadget + Field _parent:TWindowsTreeNode + Field _tree 'HWND + Field _item 'HTREEITEM + Field _expanded + Field _icon + Field _handle + + Method Activate(cmd) + Local tmpTree:TWindowsTreeView = TWindowsTreeView(TWindowsGUIDriver.GadgetFromHwnd(_tree)) + If tmpTree Then tmpTree.Desensitize() + Select cmd + Case ACTIVATE_SELECT + If _item <> TVI_ROOT Then + SendMessageW _tree,TVM_SELECTITEM,TVGN_CARET,_item + Else + SendMessageW _tree,TVM_SELECTITEM,TVGN_CARET,0 + EndIf + Case ACTIVATE_EXPAND + SendMessageW _tree,TVM_EXPAND,TVE_EXPAND,_item + _expanded=True + Case ACTIVATE_COLLAPSE + SendMessageW _tree,TVM_EXPAND,TVE_COLLAPSE,_item + _expanded=False + Case ACTIVATE_REDRAW + RedrawNode() + End Select + If tmpTree Then tmpTree.Sensitize() + EndMethod + + Method CreateRoot:TWindowsTreeNode(owner:TWindowsTreeView) + _tree=owner._hwnd + _item=TVI_ROOT + Return Self + EndMethod + + Method CountKids() + Return kids.count() + EndMethod + + Method Create:TWindowsTreeNode(group:TGadget,style,Text$="",index=-1,icon = -1) + _parent=TWindowsTreeNode(group) + If Not _parent Throw "Parent isn't a treeview node. Use TreeViewRoot() when creating a root node." + Self.style = style + _tree=_parent._tree + _icon = icon + Spawn(Text,index) + _SetParent group,index + If (LocalizationMode()&LOCALIZATION_OVERRIDE) Then + LocalizeGadget(Self, Text, "") + EndIf + Return Self + EndMethod + + Method GetText$() + Local item[10] + Local buffer:Short[260] + item[0]=TVIF_TEXT + item[1]=_item + item[4]=Int Byte Ptr buffer + item[5]=256 + SendMessageW _tree,TVM_GETITEMW,0,Int Byte Ptr(item) + Return String.FromWString(buffer) + EndMethod + + Method SetText(Text$) + Local tv:TVITEMW=New TVITEMW + tv.mask=TVIF_HANDLE|TVIF_TEXT + tv.hItem = _item + If _icon > -1 Then + tv.mask:|TVIF_IMAGE|TVIF_SELECTEDIMAGE + tv.iImage=_icon + tv.iSelectedImage=tv.iImage + EndIf + tv.pszText=Text.ToWString() + SendMessageW(_tree,TVM_SETITEMW,0,Int Byte Ptr tv) + MemFree tv.pszText + EndMethod + + Method DoLayout() + 'Don't do anything! + EndMethod + + Method Free() + 'If we don't have a parent then the node must have previously been freed. + If Not _parent Then Return + 'Avoid firing events when freeing a treenode that is selected. + If SendMessageW(_tree,TVM_GETNEXTITEM,TVGN_CARET,0) Then DeSelect() + 'Free treenode + If _item Then SendMessageW(_tree,TVM_DELETEITEM,0,_item);_item=0 + 'Redraw parent if we were its last child node + If Not SendMessageW(_tree, TVM_GETNEXTITEM, TVGN_CHILD, _parent._item) Then _parent.RedrawNode() + 'Cleanup variables that could be circular references + _parent = Null;_tree = 0;_SetParent Null + 'Release any handle we created using HandleFromObject() in Spawn() + If _handle Then Release _handle + EndMethod + + Method DeSelect() + SendMessageW _tree,TVM_SELECTITEM,TVGN_CARET,0 + EndMethod + + Method InsertNode:TGadget(index,Text$,icon) + Return New TWindowsTreeNode.Create(Self,0,Text,index,icon) + EndMethod + + Method ModifyNode(Text$,icon) + _icon = icon + SetText Text + EndMethod + + Method tviatindex(index) + If kids.IsEmpty() Then Return TVI_FIRST + If index<0 Or index>=kids.count() Return TVI_LAST + Local child:TWindowsTreeNode + child=TWindowsTreeNode(kids.valueatindex(index)) + Return child._item + EndMethod + + Method Spawn(name$,index=-1) + + Local it:TVINSERTSTRUCTW + Local hitem + it=New TVINSERTSTRUCTW + it.hParent=_parent._item + If index = 0 Then + it.hInsertAfter = TVI_FIRST + Else + it.hInsertAfter=_parent.tviatindex(index-1) + EndIf + it.item_mask=TVIF_TEXT|TVIF_PARAM + + If _icon > -1 Then + it.item_mask:|TVIF_IMAGE|TVIF_SELECTEDIMAGE + it.item_iImage=_icon + it.item_iSelectedImage=it.item_iImage + EndIf + + Local tmpParentHadKids = SendMessageW(_tree, TVM_GETNEXTITEM, TVGN_CHILD, _parent._item) + + it.item_pszText=name.ToWString() + it.item_lparam=HandleFromObject(Self) + + 'Make sure that we store handle so we can release it later. + If _handle Then Release _handle + _handle = it.item_lparam + + _item=SendMessageW(_tree,TVM_INSERTITEMW,0,Int Byte Ptr it) + + MemFree it.item_pszText + + 'Fix for tree-view parent status update problem. + If Not tmpParentHadKids Then _parent.RedrawNode() + + Return _item + + EndMethod + + Method RedrawNode() + + If _item = TVI_ROOT Then + InvalidateRect _tree, Null, True + Else + Local Rect[] = [_item,0,0,0] + If SendMessageW(_tree, TVM_GETITEMRECT, False, Int Byte Ptr Rect) Then + InvalidateRect _tree, Rect, True + EndIf + EndIf + + EndMethod + + Method SetTooltip( pTooltip$ ) + 'At the moment, nodes don't support tooltips. + EndMethod + + Method Class() + Return GADGET_NODE + EndMethod + +EndType + +Type TWindowsTreeView Extends TWindowsGadget + + Field _root:TWindowsTreeNode + Field _selected:TWindowsTreeNode + Field _icons:TWindowsIconStrip + + Method Create:TWindowsGadget(group:TGadget,style,Text$="") + Local xstyle,wstyle,hotkey + Local hwnd,parent + + Self.style = style + xstyle=WS_EX_CLIENTEDGE + wstyle=WS_CHILD|TVS_HASLINES|TVS_HASBUTTONS|TVS_LINESATROOT|TVS_SHOWSELALWAYS|TVS_NOTOOLTIPS|WS_CLIPSIBLINGS + If Not(style&TREEVIEW_DRAGNDROP) wstyle:|TVS_DISABLEDRAGDROP + + parent=group.query(QUERY_HWND_CLIENT) + hwnd=CreateWindowExW(xstyle,"SysTreeView32","",wstyle,0,0,0,0,parent,hotkey,GetModuleHandleW(Null),Null) + If TWindowsGUIDriver.CheckCommonControlVersion() Then SendMessageW hwnd, TVM_SETEXTENDEDSTYLE, TVS_EX_DOUBLEBUFFER, TVS_EX_DOUBLEBUFFER + Register GADGET_TREEVIEW,hwnd + _root=New TWindowsTreeNode.CreateRoot(Self) + + If TWindowsGUIDriver._explorerstyle Then UseExplorerTheme() + + Return Self + + EndMethod + + Method SetIconStrip(iconstrip:TIconStrip) + _icons=TWindowsIconStrip(iconstrip) + SendMessageW _hwnd,TVM_SETIMAGELIST,TVSIL_NORMAL,_icons._imagelist + EndMethod + + Method SetColor(r,g,b) + SendMessageW _hwnd,TVM_SETBKCOLOR,0,(b Shl 16)|(g Shl 8)|r + EndMethod + + Method RemoveColor() + SendMessageW _hwnd,TVM_SETBKCOLOR,1,0 + EndMethod + + Method SetTextColor(r,g,b) + SendMessageW _hwnd,TVM_SETTEXTCOLOR,0,(b Shl 16)|(g Shl 8)|r + EndMethod + + Method RootNode:TGadget() + Return _root + EndMethod + + Method SelectedNode:TGadget() + Return _selected + EndMethod + + Method CountKids() + Return _root.CountKids() + EndMethod + + Method OnNotify(wp,lp) + Local nmhdr:Int Ptr + Local itemnew:Int Ptr + Local node:TWindowsTreeNode + + Super.OnNotify(wp,lp) 'Tool-tips + + nmhdr=Int Ptr(lp) + Select nmhdr[2] 'code + + 'MSLU glitch requires handling of ANSI equivalent + Case TVN_SELCHANGEDW, TVN_SELCHANGEDA + itemnew=nmhdr+14 'Int Ptr(nmhdr[5]) 'itemNew + If itemnew[1]=TVI_ROOT 'hItem + _selected=_root + Else + _selected=TWindowsTreeNode(HandleToObject(itemnew[9])) 'lParaM + EndIf + PostGuiEvent EVENT_GADGETSELECT,0,0,0,0,_selected + + Case TVN_ITEMEXPANDEDW, TVN_ITEMEXPANDEDA + itemnew=nmhdr+14 'Int Ptr(nmhdr[5]) 'itemNew.TVITEM + If itemnew[1]=TVI_ROOT 'hItem + node=_root + Else + node=TWindowsTreeNode(HandleToObject(itemnew[9] )) 'lParaM + EndIf + Select nmhdr[3] 'action itemnew[2]&TVIS_EXPANDED 'state + Case 1 + PostGuiEvent EVENT_GADGETCLOSE,0,0,0,0,node + node._expanded=False + Case 2 + PostGuiEvent EVENT_GADGETOPEN,0,0,0,0,node + node._expanded=True + End Select + Return True + + Case TVN_BEGINDRAGW, TVN_BEGINRDRAGW, TVN_BEGINDRAGA, TVN_BEGINRDRAGA + + If (style&TREEVIEW_DRAGNDROP) Then + + Local data% = 1 + If (nmhdr[2] = TVN_BEGINRDRAGW) Or (nmhdr[2] = TVN_BEGINRDRAGA) Then data = 2 + + itemnew=nmhdr+14 'Int Ptr(nmhdr[5]) 'itemNew + + If itemnew[1]<>TVI_ROOT Then + TGadget.dragGadget[data-1]=TWindowsTreeNode(HandleToObject(itemnew[9])) + PostGuiEvent EVENT_GADGETDRAG, data, KeyMods(), itemnew[10], itemnew[11], TGadget.dragGadget[data-1] + Else + TGadget.dragGadget[data-1]=Null + EndIf + + EndIf + + Case NM_DBLCLK, NM_RETURN + PostGuiEvent EVENT_GADGETACTION,0,0,0,0,_selected + + Case NM_RCLICK + Local Rect[4] + Local pt[2] + Local hittest[4] + Local item[10] + GetWindowRect _hwnd,Rect + GetCursorPos_ pt + hittest[0]=pt[0]-Rect[0] + hittest[1]=pt[1]-Rect[1] + If SendMessageW(_hwnd,TVM_HITTEST,0,Int Byte Ptr(hittest)) + If hittest[3]=TVI_ROOT + node=_root + Else + item[0]=TVIF_PARAM + item[1]=hittest[3] + SendMessageW _hwnd,TVM_GETITEMW,0,Int Byte Ptr(item) + node=TWindowsTreeNode(HandleToObject(item[9])) + EndIf + PostGuiEvent EVENT_GADGETMENU,0,hittest[0],hittest[1],0,node + EndIf + Return True + + EndSelect + EndMethod + + Method WndProc(hwnd,msg,wp,lp) + Select msg + 'If we are using Vista's common controls, then the treeview will be double-buffered and so + 'we don't need to clear the background when redrawing (performance tweak). + Case WM_ERASEBKGND + If TWindowsGUIDriver.CheckCommonControlVersion() >= 2 Then Return 1 + EndSelect + Return Super.WndProc(hwnd,msg,wp,lp) + EndMethod + + Method UseExplorerTheme() + + If TWindowsGUIDriver.CheckCommonControlVersion() And SetWindowThemeW Then + SetWindowThemeW( _hwnd, _wstrExplorer, Null ) + SendMessageW _hwnd, TVM_SETEXTENDEDSTYLE, TVS_EX_FADEINOUTEXPANDOS, TVS_EX_FADEINOUTEXPANDOS + EndIf + + EndMethod + + Method Class() + Return GADGET_TREEVIEW + EndMethod + +EndType + +Type TWindowsLabel Extends TWindowsGadget + + Method Create:TWindowsGadget(group:TGadget,style,Text$="") + Local xstyle,wstyle,hotkey + Local hwnd,parent + + Self.style = style + wstyle=WS_CHILD|SS_NOPREFIX|WS_CLIPSIBLINGS|SS_NOTIFY + + Select style&24 + Case LABEL_LEFT wstyle:|SS_LEFT + Case LABEL_RIGHT wstyle:|SS_RIGHT + Case LABEL_CENTER wstyle:|SS_CENTER + End Select + Select style&7 + Case LABEL_FRAME wstyle:|WS_BORDER + Case LABEL_SUNKENFRAME wstyle:|SS_SUNKEN + Case LABEL_SEPARATOR wstyle:|SS_SUNKEN|SS_GRAYRECT + End Select + + parent=group.query(QUERY_HWND_CLIENT) + hwnd=CreateWindowExW(xstyle,"STATIC","",wstyle,0,0,0,0,parent,hotkey,GetModuleHandleW(Null),Null) + Register GADGET_LABEL,hwnd + + Return Self + EndMethod + + Method SetArea(x,y,w,h) + If ((style & 7) = LABEL_SEPARATOR) Then + If (w > h) Then h = 2 Else w = 2 + EndIf + Return Super.SetArea(x,y,w,h) + EndMethod + + Method SetText(Text$) + If ((style & 7) <> LABEL_SEPARATOR) Then Return Super.SetText(Text) + EndMethod + + Method WndProc(hwnd,msg,wp,lp) + Select msg + Case WM_ERASEBKGND + Return 1 + EndSelect + Return Super.WndProc(hwnd,msg,wp,lp) + EndMethod + + Method Class() + Return GADGET_LABEL + EndMethod + +EndType + +Type TWindowsSlider Extends TWindowsGadget + Field _slidertype,_ishorizontal,_visible = 5,_total = 10,_value + + Method Create:TWindowsGadget(group:TGadget,style,Text$="") + Local xstyle,wstyle,class$ + Local hwnd,parent,hotkey + + _slidertype=style&$fffc + _ishorizontal=style&SLIDER_HORIZONTAL + + Self.style = style + wstyle=WS_CHILD|WS_CLIPSIBLINGS|WS_CLIPCHILDREN + parent=group.query(QUERY_HWND_CLIENT) + Select _slidertype + Case SLIDER_SCROLLBAR + If _ishorizontal wstyle:|SBS_HORZ;Else wstyle:|SBS_VERT + class$="SCROLLBAR" + Case SLIDER_TRACKBAR + wstyle:|TBS_AUTOTICKS|WS_TABSTOP + xstyle:|WS_EX_COMPOSITED 'Reduces flicker when resizing (doesn't like scrollbars/up-down controls) + If _ishorizontal wstyle:|TBS_HORZ Else wstyle:|TBS_VERT + class$=TRACKBAR_CLASS + Case SLIDER_STEPPER + If _ishorizontal wstyle:|UDS_HORZ + class$="msctls_updown32" + Default + Return Null + End Select + + hwnd=CreateWindowExW(xstyle,class,"",wstyle,0,0,0,0,parent,hotkey,GetModuleHandleW(Null),Null) + Register GADGET_SLIDER,hwnd + RefreshLook() + + Return Self + EndMethod + + Method SetRange(visible,total) + _visible = visible + _total = total + Local tmpEnabled:Int = Not( State() & STATE_DISABLED ) + Desensitize() + Select _slidertype + Case SLIDER_SCROLLBAR + Local info:SCROLLINFO=New SCROLLINFO + info.cbSize=SizeOf(SCROLLINFO) + info.fMask=SIF_PAGE|SIF_RANGE + info.nMax=total-1 + info.nPage=visible + SendMessageW _hwnd,SBM_SETSCROLLINFO,True,Int Byte Ptr info + Case SLIDER_TRACKBAR + + SendMessageW _hwnd,TBM_SETRANGEMIN,False,visible + SendMessageW _hwnd,TBM_SETRANGEMAX,True,total + + ' Aesthetic tweak that should stop black tick bands forming when + ' large ranges are used on small trackbars. + + Local tmpFirstTick% = SendMessageW( _hwnd, TBM_GETTICPOS, 0, 0 ) + Local tmpNumTicks% = SendMessageW( _hwnd, TBM_GETNUMTICS, 0, 0) + Local tmpLastTick% = SendMessageW( _hwnd, TBM_GETTICPOS, tmpNumTicks-3, 0 ) + If Not( tmpLastTick < 0 Or tmpFirstTick < 0 Or (total-visible-2) < 1) Then + If (tmpLastTick-tmpFirstTick)/(total-visible-2) < 4 Then + SendMessageW( _hwnd, TBM_CLEARTICS, True, 0 ) + EndIf + EndIf + + Case SLIDER_STEPPER + SendMessageW _hwnd,UDM_SETRANGE32,visible,total + End Select + _value = GetProp() + SetEnabled(tmpEnabled) + Sensitize() + EndMethod + + Method SetProp(value) + Desensitize() + Select _slidertype + Case SLIDER_SCROLLBAR + Local info:SCROLLINFO=New SCROLLINFO + info.cbSize=SizeOf(SCROLLINFO) + info.fMask=SIF_POS + info.nPos=value + SendMessageW _hwnd,SBM_SETSCROLLINFO,True,Int Byte Ptr info + Case SLIDER_TRACKBAR + If _ishorizontal Then + SendMessageW _hwnd,TBM_SETPOS,True,value + Else + 'Flip the value so that the scale starts from the bottom + SendMessageW _hwnd,TBM_SETPOS,True,_visible + _total - value + EndIf + Case SLIDER_STEPPER + SendMessageW _hwnd,UDM_SETPOS,True,value + End Select + _value = value + Sensitize() + EndMethod + + Method GetProp() + Local value + Select _slidertype + Case SLIDER_SCROLLBAR + value=GetScrollPos(_hwnd,SB_CTL) + Case SLIDER_TRACKBAR + value=SendMessageW(_hwnd,TBM_GETPOS,0,0) + 'Flip the value so that the scale starts from the bottom + If Not _ishorizontal Then value = _visible + _total - value + Case SLIDER_STEPPER + value=SendMessageW(_hwnd,UDM_GETPOS32,0,Null) + End Select + Return value + EndMethod + + Method OnCommand(msg,wp) + If _slidertype=SLIDER_SCROLLBAR + If msg=WM_COMMAND Return + Local info:SCROLLINFO=New SCROLLINFO + info.cbSize=SizeOf(SCROLLINFO) + Select wp&$ffff + Case SB_THUMBTRACK,SB_THUMBPOSITION + info.fMask=SIF_TRACKPOS + SendMessageW _hwnd,SBM_GETSCROLLINFO,0,Int Byte Ptr info + SetScrollPos _hwnd,SB_CTL,info.nTrackPos,True + Default + info.fMask=SIF_POS|SIF_PAGE|SIF_RANGE + SendMessageW _hwnd,SBM_GETSCROLLINFO,0,Int Byte Ptr info + Local pos=info.nPos + Local vis=info.nPage + Select wp&$ffff + Case SB_LINEUP pos:-1 + Case SB_LINEDOWN pos:+1 + Case SB_PAGEUP pos:-vis + Case SB_PAGEDOWN pos:+vis + Default Return 0 + End Select + SetScrollPos _hwnd,SB_CTL,pos,True + End Select + EndIf + Local index=GetProp() + If (index <> _value) Then + PostGuiEvent EVENT_GADGETACTION,index + _value = index + EndIf + Return 1 + EndMethod + + Method WndProc(hwnd,msg,wp,lp) + Select msg + Case WM_ERASEBKGND + Return 1 + EndSelect + Return Super.WndProc(hwnd,msg,wp,lp) + EndMethod + + Method RefreshLook() + Super.RefreshLook() + SetRange(_visible,_total) + EndMethod + + Method Class() + Return GADGET_SLIDER + EndMethod + +EndType + +Type TWindowsProgressBar Extends TWindowsGadget + + Method Create:TWindowsGadget(group:TGadget,style,Text$="") + Local xstyle,wstyle,hotkey + Local hwnd,parent + Self.style = style + wstyle=WS_CHILD|PBS_SMOOTH|WS_CLIPSIBLINGS + parent=group.query(QUERY_HWND_CLIENT) + hwnd=CreateWindowExW(xstyle,"msctls_progress32","",wstyle,0,0,0,0,parent,hotkey,GetModuleHandleW(Null),Null) + Register GADGET_PROGBAR,hwnd + Return Self + EndMethod + + Method SetValue(value#) + SendMessageW _hwnd,PBM_SETPOS,value*100,0 + EndMethod + + Method SetColor(r,g,b) + 'Only works in Classic mode, but it's better than nothing. + SendMessageW _hwnd,PBM_SETBKCOLOR ,0,(b Shl 16)|(g Shl 8)|r + EndMethod + + Method RemoveColor() + 'Only works in Classic mode, but it's better than nothing. + SendMessageW _hwnd,PBM_SETBKCOLOR ,1,0 + EndMethod + + Method SetTextColor(r,g,b) + 'Only works in Classic mode, but it's better than nothing. + SendMessageW _hwnd,PBM_SETBARCOLOR ,0,(b Shl 16)|(g Shl 8)|r + EndMethod + + Method Class() + Return GADGET_PROGBAR + EndMethod + +EndType + +Type TWindowsPanel Extends TWindowsGadget + + Const PANELPANEL=0 + Const PANELGROUP=1 + Const PANELCANVAS=2 + + Field _type + Field _alpha#=1.0 + Field _bitmapwidth,_bitmapheight,_bitmapflags + Field _canvas:TGraphics + Field _hasalpha + + Method Create:TWindowsGadget(group:TGadget,style,Text$="") + Local xstyle,wstyle,hotkey + Local hwnd,client,parent + Self.style = style + + parent=group.query(QUERY_HWND_CLIENT) + If (style&3=PANEL_GROUP) Then + _type=PANELGROUP + hwnd=CreateWindowExW(WS_EX_CONTROLPARENT,"BUTTON","",BS_GROUPBOX|WS_CHILD|WS_CLIPSIBLINGS|WS_CLIPCHILDREN,0,0,0,0,parent,0,GetModuleHandleW(Null),Null ) + client=CreateWindowExW(WS_EX_CONTROLPARENT,TWindowsGUIDriver.ClassName(),"",WS_CHILD|WS_VISIBLE|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,0,0,0,0,hwnd,0,GetModuleHandleW(Null),Null) + Else + _type=PANELPANEL + xstyle=WS_EX_CONTROLPARENT + wstyle=WS_CHILD|WS_CLIPCHILDREN|WS_CLIPSIBLINGS + Select (style&3) + Case PANEL_SUNKEN xstyle:|WS_EX_CLIENTEDGE + Case PANEL_RAISED xstyle:|WS_EX_WINDOWEDGE ; wstyle:|WS_DLGFRAME + EndSelect + If (style&PANEL_CANVAS) Then _type=PANELCANVAS + hwnd=CreateWindowExW(xstyle,TWindowsGUIDriver.ClassName(),"",wstyle,0,0,0,0,parent,hotkey,GetModuleHandleW(Null),Null) + EndIf + + Register GADGET_PANEL,hwnd,client + If (style & PANEL_ACTIVE) Then sensitivity = SENSITIZE_ALL + + Return Self + EndMethod + + Method SetAlpha( alpha# ) + _alpha=alpha + RedrawGadget(Self) + EndMethod + + Method Activate( cmd ) + Select cmd + Case ACTIVATE_REDRAW + If (_type = PANELCANVAS) Then + InvalidateRect _hwnd, Null, False + Return True + EndIf + EndSelect + Return Super.Activate(cmd) + EndMethod + + Method SetPixmap(pixmap:TPixmap,flags) + If _bitmap Then DeleteObject _bitmap;_bitmap = 0 + If pixmap Then + If pixmap.format=PF_RGBA8888 Or pixmap.format=PF_BGRA8888 + _bitmap=TWindowsGraphic.PreMultipliedBitmapFromPixmap32( pixmap ) + EndIf + If _bitmap + _hasalpha=True + Else + _bitmap=TWindowsGraphic.BitmapFromPixmap( pixmap, False ) + _hasalpha=False + EndIf + _bitmapflags=flags + _bitmapwidth=pixmap.width + _bitmapheight=pixmap.height + EndIf + RedrawGadget(Self) + EndMethod + + Method AttachGraphics:TGraphics( flags ) + _canvas=brl.Graphics.AttachGraphics( _hwnd,flags ) + EndMethod + + Method CanvasGraphics:TGraphics() + Return _canvas + EndMethod + + Method Free() + If _canvas Then CloseGraphics(_canvas);_canvas = Null + Super.Free() + EndMethod + + Method WndProc(hwnd,msg,wp,lp) + Select msg + + Case WM_ERASEBKGND + + If _type = PANELCANVAS Then Return 1 + + Local hdc=wp,hdcCanvas,hdcBitmap,srcw,srch,x,y,xoffset,yoffset + Local clientRect[4], updateRect[4], clipRect[4], windowRect[4] + + GetClipBox( hdc, clipRect ) + GetWindowRect( hwnd, windowRect) + GetClientRect( hwnd, clientRect ) + + If Not GetUpdateRect( hwnd, updateRect, False) Then updateRect = clipRect + If IsRectEmpty(updateRect) Then updateRect = [0,0,windowRect[2]-windowRect[0],windowRect[3]-windowRect[1]] + + 'If we are drawing a bitmap or using alpha then let's do some double-buffering stuff + + If (hwnd <> _hwndclient) And ((_bitmap And _bitmapwidth And _bitmapheight) Or _alpha<1.0) Then + + hdc = CreateCompatibleDC(wp) + hdcCanvas = CreateCompatibleBitmap(wp,windowRect[2]-windowRect[0],windowRect[3]-windowRect[1]) + SelectObject( hdc, hdcCanvas ) + + EndIf + + 'Fill the drawing context with the background colour, or the background of the parent + + If BgBrush() And (hwnd <> _hwndclient) Then FillRect(hdc,updateRect,BgBrush()) Else DrawParentBackground(hdc,hwnd) + + 'If we aren't drawing to a bitmap or using alpha, then we can return now. + + If Not ((hwnd <> _hwndclient) And ((_bitmap And _bitmapwidth And _bitmapheight) Or _alpha<1.0)) Then Return 1 + + If _bitmap And _bitmapwidth And _bitmapheight + hdcBitmap=CreateCompatibleDC(hdc) + SelectObject(hdcBitmap,_bitmap) + srcw=_bitmapwidth + srch=_bitmapheight + Select (_bitmapflags & (GADGETPIXMAP_ICON-1)) + Case PANELPIXMAP_TILE + While ymy Then + If (_bitmapflags&(GADGETPIXMAP_ICON-1)) = PANELPIXMAP_FIT Then mx=my Else my=mx + EndIf + Local w=mx*srcw + Local h=mx*srch + x=(windowRect[RECT_RIGHT]-windowRect[RECT_LEFT]-w)/2 + y=(windowRect[RECT_BOTTOM]-windowRect[RECT_TOP]-h)/2 + SetStretchBltMode hdc,COLORONCOLOR + + If _hasalpha + AlphaBlend_ hdc,x,y,w,h,hdcBitmap,0,0,srcw,srch,$01ff0000 + Else + StretchBlt hdc,x,y,w,h,hdcBitmap,0,0,srcw,srch,ROP_SRCCOPY + EndIf + + Case PANELPIXMAP_STRETCH + SetStretchBltMode hdc,COLORONCOLOR + + If _hasalpha + AlphaBlend_ hdc,0,0,windowRect[RECT_RIGHT]-windowRect[RECT_LEFT],windowRect[RECT_BOTTOM]-windowRect[RECT_TOP],hdcBitmap,0,0,srcw,srch,$01ff0000 + Else + StretchBlt hdc,0,0,windowRect[RECT_RIGHT]-windowRect[RECT_LEFT],windowRect[RECT_BOTTOM]-windowRect[RECT_TOP],hdcBitmap,0,0,srcw,srch,ROP_SRCCOPY + EndIf + + EndSelect + + DeleteDC(hdcBitmap) + + EndIf + + If _alpha < 1.0 Then + + DrawParentBackground( wp, hwnd ) + Local blendfunction = ((Int(_alpha*255)&$FF) Shl 16) + AlphaBlend_(wp,updateRect[0],updateRect[1],updateRect[2]-updateRect[0],updateRect[3]-updateRect[1],hdc,updateRect[0],updateRect[1],updateRect[2]-updateRect[0],updateRect[3]-updateRect[1],blendfunction) + + Else + + BitBlt(wp,0,0,windowRect[2]-windowRect[0],WindowRect[3]-windowRect[1],hdc,0,0,ROP_SRCCOPY) + + EndIf + + Assert hdc <> wp, "hdc == wp! Please post a MaxGUI bug report." + + DeleteObject( hdcCanvas ) + DeleteDC( hdc ) + + Return 1 + + Case WM_PAINT + + Select _type + Case PANELCANVAS + PostGuiEvent EVENT_GADGETPAINT + ValidateRect _hwnd, Null + Return 1 + EndSelect + + Case WM_LBUTTONDOWN + + SetFocus Query(QUERY_HWND_CLIENT) + + End Select + + Return Super.WndProc(hwnd,msg,wp,lp) + + EndMethod + + Method FlushBrushes(pRecurse:Int = True) + Super.FlushBrushes() + If Not pRecurse Then Return + For Local tmpGadget:TWindowsGadget = EachIn kids + tmpGadget.FlushBrushes() + Next + EndMethod + + Method ClientWidth() + If _hwndClient Then Return (Super.ClientWidth()-8) Else Return Super.ClientWidth() + EndMethod + + Method ClientHeight() + If _hwndClient Then Return (Super.ClientHeight()-20) Else Return Super.ClientHeight() + EndMethod + + Method RethinkClient(forceRedraw:Int = False) + If _hwndClient Then + MoveWindow( _hwndClient, 4+_clientX,16+_clientY,ClientWidth(),ClientHeight(),forceRedraw) + EndIf + EndMethod + + Method Class() + If _type = PANELCANVAS Then Return GADGET_CANVAS Else Return GADGET_PANEL + EndMethod + +EndType + + +Type TWindowsHTMLView Extends TWindowsGadget + + Field mshtml + Field browser:IWebBrowser2 + + Field IID_IHTMLDocument2:GUID=New GUID + + Method Create:TWindowsGadget(group:TGadget,style,Text$="") + Self.style = style + Local parent=group.query(QUERY_HWND_CLIENT) + mshtml=msHtmlCreate(Self,TWindowsGUIDriver.ClassName(),parent,style) + browser=msHTMLBrowser(mshtml) + Register GADGET_HTMLVIEW,msHtmlHwnd(mshtml) + + Local res = IIDFromString(IHTMLDocument2_UUID,IID_IHTMLDocument2) + + Return Self + EndMethod + + Method Rethink() + msHtmlSetShape mshtml,xpos,ypos,width,height + EndMethod + + Method SetText(Text$) 'sets document url + If Text Then msHtmlGo mshtml,Text + EndMethod + + Method GetText$() + Local bstr:Short Ptr + browser.lfget_LocationURL(Varptr bstr) + Local result$ = String.FromWString(bstr) + SysFreeString(bstr) + Return result + EndMethod + + Method GetTitleText$() 'returns document title + + Local bstr:Short Ptr + Local res + + Local disp:IDispatch + Local doc:IHTMLDOCUMENT2 + + res=browser.lfget_Document(Varptr disp) + If res RuntimeError "no document" + + res=disp.QueryInterface(IID_IHTMLDocument2,Varptr doc) + If res RuntimeError "no document2 interface" + + If doc + doc.get_Title(Varptr bstr) + Else + browser.lfget_LocationName(Varptr bstr) + EndIf + + Local result$ = String.FromWString(bstr) + SysFreeString(bstr) + Return result + + End Method +Rem + Method Run$(script$) + Local res + Local disp:IDispatch + Local doc:IHTMLDOCUMENT2 + Local win:IHTMLWindow2 + Local result:VARIANT + + res=browser.lfget_Document(Varptr disp) + If res RuntimeError "no document" + res=disp.QueryInterface(IID_IHTMLDocument2,Varptr doc) + If res RuntimeError "no document2 interface" + res=doc.get_parentWindow(Varptr win) + If res RuntimeError "no parent window" + result=New VARIANT + result.vt=VT_EMPTY + Local bstr:Short Ptr + bstr=SysAllocStringLen(script.toWString(),script.length) + res=win.execScript(bstr,Null,result) + SysFreeString bstr + Return res + End Method + +EndRem + Method Activate(cmd) + Return msHtmlActivate(mshtml,cmd) + EndMethod + + Method State() + Return msHtmlStatus(mshtml) + EndMethod + + Method Run$(script$) + msHtmlRun(mshtml,script) + EndMethod + + Method WndProc(hwnd,msg,wp,lp) + Select msg + 'Reduces flicker on HTMLViews + Case WM_ERASEBKGND + Return 1 + EndSelect + Return Super.WndProc(hwnd,msg,wp,lp) + EndMethod + + Method Class() + Return GADGET_HTMLVIEW + EndMethod + +EndType + +Type TWindowsMenu Extends TGadget + Field _hmenu + Field _pmenu + Field _item + Field _state + Field _tag + Field _hotkeycode + Field _modifier + Field _shortcut$ + Field _hotkey:THotKey + Field _key = SetNewKey() + Field _iconBitmap + + Global iteminfo:MENUITEMINFOW + + Global keymap:TMap=New TMap 'key,gadget + Global keycount=100 + + Method SetNewKey%() + keycount:+1 + keymap.Insert( TIntWrapper.Create(keycount), Self ) + Return keycount + EndMethod + + Function GetMenuFromKey:TWindowsMenu(pKey%) + Return TWindowsMenu(keymap.ValueForKey(TIntWrapper.Create(pKey))) + EndFunction + + Method SetText(pText$) + name = pText + EndMethod + + Method GetText$() + Return name + EndMethod + + Method Free() + Close + _setparent Null + keymap.Remove(TIntWrapper.Create(_key)) + If _iconBitmap Then DeleteObject(_iconBitmap) + EndMethod + + Method DoLayout() + 'Don't do anything! + EndMethod + + Method State() + Return _state + EndMethod + + Method SetEnabled(enable) + If enable + If _pmenu EnableMenuItem(_pmenu,_item,MF_BYPOSITION|MF_ENABLED) + _state:&~STATE_DISABLED + Else + If _pmenu EnableMenuItem(_pmenu,_item,MF_BYPOSITION|MF_GRAYED) + _state:|STATE_DISABLED + EndIf + EndMethod + + Method SetSelected(bool) + If bool + If _pmenu CheckMenuItem(_pmenu,_item,MF_BYPOSITION|MF_CHECKED) + _state:|STATE_SELECTED + Else + If _pmenu CheckMenuItem(_pmenu,_item,MF_BYPOSITION|MF_UNCHECKED) + _state:&~STATE_SELECTED + EndIf + EndMethod + + Method SetHotKey(keycode,modifier) + _hotkeycode=keycode + _modifier=modifier + + Local pre$, suf$, m$ + + If LocalizationMode()&LOCALIZATION_ON Then + pre="{{" + suf="}}" + EndIf + + If keycode>=KEY_0 And keycode<=KEY_9 + m$=Chr(keycode) + ElseIf keycode>=KEY_A And keycode<=KEY_Z + m$=Chr(keycode) + ElseIf keycode>=KEY_F1 And keycode<=KEY_F12 + m$="F"+(keycode+1-KEY_F1) + ElseIf keycode>=KEY_NUM0 And keycode<=KEY_NUM9 + m$="Num "+(keycode+1-KEY_NUM0) + Else + Select keycode + Case KEY_BACKSPACE;m = pre+"Backspace"+suf + Case KEY_TAB;m = pre+"Tab"+suf + Case KEY_ESCAPE;m = pre+"Esc"+suf + Case KEY_SPACE;m = pre+"Space"+suf + Case KEY_ENTER;m = pre+"Enter"+suf + Case KEY_PAGEUP;m = pre+"PageUp"+suf + Case KEY_PAGEDOWN;m = pre+"PageDown"+suf + Case KEY_END;m = pre+"End"+suf + Case KEY_HOME;m = pre+"Home"+suf + Case KEY_LEFT;m = pre+"Left"+suf + Case KEY_RIGHT;m = pre+"Right"+suf + Case KEY_UP;m = pre+"Up"+suf + Case KEY_DOWN;m = pre+"Down"+suf + Case KEY_INSERT;m = pre+"Insert"+suf + Case KEY_DELETE;m = pre+"Delete"+suf + Case KEY_TILDE;m = "~~" + Case KEY_MINUS;m = "-" + Case KEY_EQUALS;m = "=" + Case KEY_OPENBRACKET;m = "[" + Case KEY_CLOSEBRACKET;m = "]" + Case KEY_BACKSLASH;m = "\" + Case KEY_SEMICOLON;m = ";" + Case KEY_QUOTES;m = "'" + Case KEY_COMMA;m = "," + Case KEY_PERIOD;m = "." + Case KEY_SLASH;m = "/" + Case KEY_NUMMULTIPLY;m = "Num *" + Case KEY_NUMADD;m = "Num +" + Case KEY_NUMSUBTRACT;m = "Num -" + Case KEY_NUMDECIMAL;m = "Num ." + Case KEY_NUMDIVIDE;m = "Num /" + EndSelect + EndIf + + If m + If modifier&MODIFIER_SHIFT m$=pre+"Shift"+suf+"+"+m$ + If modifier&MODIFIER_CONTROL m$=pre+"Ctrl"+suf+"+"+m$ + If modifier&MODIFIER_ALT m$=pre+"Alt"+suf+"+"+m$ + m="~t"+m + EndIf + _shortcut$=LocalizeString(m) + + If Not iteminfo + iteminfo=New MENUITEMINFOW + iteminfo.cbSize=SizeOf(iteminfo) + EndIf + iteminfo.fMask=MIIM_TYPE + iteminfo.dwTypeData=(name+_shortcut).toWString() + SetMenuItemInfoW _pmenu,_item,True,iteminfo + + MemFree iteminfo.dwTypeData + + Local ev:TEvent=CreateEvent( EVENT_MENUACTION, Self,_tag ) + If _hotKey RemoveHotKey(_hotKey);_hotKey = Null + If keycode Then _hotkey=SetHotKeyEvent(keycode,modifier,ev,FindGadgetWindowHwnd(Self)) + EndMethod + + Method Create:TWindowsMenu(group:TGadget,tag,Text$="") + If Not iteminfo Then + iteminfo=New MENUITEMINFOW + iteminfo.cbSize=SizeOf(iteminfo) + EndIf + name=Text + _tag=tag + Local window:TWindowsWindow = TWindowsWindow(group) + If window group=window.GetMenu() + _SetParent(group) + If (LocalizationMode()&LOCALIZATION_OVERRIDE) Then + LocalizeGadget(Self, name, "") + EndIf + Return Self + EndMethod + + Method Open(popup=False) + + Local dad:TWindowsMenu = TWindowsMenu(parent) + + If dad + _pmenu=dad._hmenu + If Not _pmenu Throw "Parent doesn't have a handle - the desktop heap may have run out of memory!" + _item=GetMenuItemCount(_pmenu) + If name + Local tmpWString:Short Ptr = (LocalizeString(name)+_shortcut).ToWString() + AppendMenuW _pmenu,MF_STRING,_key,tmpWString + MemFree tmpWString + Else + AppendMenuW _pmenu,MF_SEPARATOR,_key,Null + EndIf + If kids.count() + _hmenu=CreateMenu_() + Local tmpMenuInfo:MENUINFO = New MENUINFO + + tmpMenuInfo.fMask = MIM_APPLYTOSUBMENUS|MIM_STYLE + tmpMenuInfo.dwStyle = MNS_CHECKORBMP|MNS_MODELESS + SetMenuInfo(_hmenu, tmpMenuInfo) + + iteminfo.fMask=MIIM_SUBMENU + iteminfo.hSubMenu=_hmenu + SetMenuItemInfoW _pmenu,_item,True,iteminfo + EndIf + + If _state&STATE_DISABLED SetEnabled(False) + If _state&STATE_SELECTED SetSelected(True) + + If _iconBitmap Then SetMenuItemBitmaps(_pMenu,_key,MF_BYCOMMAND,_iconBitmap,Null) + Else + If popup + _hmenu=CreatePopupMenu() + Else + If kids _hmenu=CreateMenu_() + EndIf + EndIf + + For Local kid:TWindowsMenu = EachIn kids + kid.Open + Next + + EndMethod + + Method FreeKids() + For Local kid:TWindowsMenu = EachIn kids + kid.Close + Next + EndMethod + + Method Close() + FreeKids() + If _hmenu + DestroyMenu _hmenu + _hmenu=0 + EndIf + EndMethod + + Method SetPixmap(pixmap:TPixmap,pFlags) + If Not (pFlags & GADGETPIXMAP_ICON) Then Return + If _iconBitmap Then DeleteObject(_iconBitmap);_iconBitmap = 0 + If pixmap Then + pixmap = PixmapWindow(pixmap,0,0,Min(GetSystemMetrics(SM_CXMENUCHECK),PixmapWidth(pixmap)),Min(GetSystemMetrics(SM_CYMENUCHECK),PixmapHeight(pixmap))) + If TWindowsGUIDriver.CheckCommonControlVersion() >= 2 Then + _iconBitmap = TWindowsGraphic.PreMultipliedBitmapFromPixmap32( pixmap ) + Else + Local tmpRGB = GetSysColor(COLOR_MENU) + _iconBitmap = TWindowsGraphic.BitmapWithBackgroundFromPixmap32( pixmap, tmpRGB&$FF, (tmpRGB Shr 8) & $FF, (tmpRGB Shr 16) & $FF ) + EndIf + EndIf + + EndMethod + + Method SetTooltip( pTooltip$ ) + 'Menus shouldn't have tool-tips. + EndMethod + + Method Class() + Return GADGET_MENUITEM + EndMethod + +EndType + +Type TWindowsIconStrip Extends TIconStrip + + Field _blanks[] + Field _imagelist + + Function DetectNotBlank(pixmap:TPixmap,xx,n) + Local c = pixmap.ReadPixel(xx,0), y + For Local x=0 Until n + For y=0 Until n + If pixmap.ReadPixel(xx+x,y)<>c Return True + Next + Next + EndFunction + + Method IsBlankIcon(n) + Return _blanks[n] + EndMethod + + Function RemoveMask(pixmap:TPixmap) + If pixmap.format<>( PF_RGBA8888 ) And pixmap.format<>( PF_BGRA8888 ) Return + Local w = pixmap.width, h = pixmap.height, y, c + For Local x=0 Until w + For y=0 Until h + c=pixmap.ReadPixel(x,y) + If c>=0 pixmap.WritePixel x,y,-1 + Next + Next + EndFunction + + Function BuildImageList(pixmap:TPixmap) + Local bitmap,imagelist,sz,mask + sz=pixmap.height + If TWindowsGUIDriver.CheckCommonControlVersion() And (Pixmap.format=PF_RGBA8888 Or pixmap.format=PF_BGRA8888) + imagelist=ImageList_Create(sz,sz,ILC_COLOR32,0,1) + If imagelist + bitmap=TWindowsGraphic.BitmapFromPixmap(pixmap, True) + ImageList_Add(imagelist,bitmap,0) + EndIf + EndIf + If imagelist=0 + bitmap=TWindowsGraphic.BitmapFromPixmap(pixmap, False) + mask=TWindowsGraphic.BitmapMaskFromPixmap(pixmap) + imagelist=ImageList_Create(sz,sz,ILC_COLOR24|ILC_MASK,0,1) + ImageList_Add(imagelist,bitmap,mask) + DeleteObject(mask) + EndIf + DeleteObject(bitmap) + Return imagelist + EndFunction + + Function Create:TWindowsIconStrip(source:Object) + Local icons:TWindowsIconStrip + Local imagelist + Local n,i,sz + Local blanks[] + + 'Get a 24-bit pixmap from source + Local pix:TPixmap = TPixmap(source) + If Not pix pix = LoadPixmap(source) + If Not pix Return + + 'Detect blank icons in the set + sz=pix.height;If sz n=pix.width/sz + If n=0 Return + blanks=New Int[n] + For i=0 Until n + blanks[i]=Not DetectNotBlank(pix,i*sz,sz) + Next + + 'Build a Win32 Image-List + imagelist=BuildImageList(pix) + icons = New TWindowsIconStrip + icons.pixmap = pix + icons.count=n + icons._blanks=blanks + icons._imagelist=imagelist + + Return icons + EndFunction + + Function CreateBlank:TWindowsIconStrip() + Return Create(CreatePixmap(1,1,PF_BGR888)) + EndFunction + + Method Delete() + If _imagelist Then + ImageList_Destroy(_imagelist) + _imagelist = 0 + EndIf + EndMethod + +EndType + +Type TWindowsFont Extends TGuiFont + + Method Load:TWindowsFont(_name$,_size:Double,_style) + + If handle Then DeleteObject handle;handle = 0 + + Local cfweight = FW_NORMAL + Local cfsize = -LogicalUnitsFromSize( _size ) + + If _style & FONT_BOLD cfweight=FW_BOLD + handle=CreateFontW( cfsize, 0,0,0,cfweight,.. + (_style & FONT_ITALIC) ,.. + (_style & FONT_UNDERLINE),.. + (_style & FONT_STRIKETHROUGH),.. + DEFAULT_CHARSET,.. + OUT_DEFAULT_PRECIS,.. + CLIP_DEFAULT_PRECIS,.. + ANTIALIASED_QUALITY,.. + DEFAULT_PITCH|FF_DONTCARE,.. + _name.toWString()) + + 'Now lets test to see whether the right font was found + + name = NameFromHandle(handle) + + 'If the font returned has a different name to that requested, let's try the symbol character set + + If name.ToLower() <> _name.ToLower() Then + Local tmpSymbolHandle = CreateFontW( cfsize, 0,0,0,cfweight,.. + (_style & FONT_ITALIC) ,.. + (_style & FONT_UNDERLINE),.. + (_style & FONT_STRIKETHROUGH),.. + SYMBOL_CHARSET,.. + OUT_DEFAULT_PRECIS,.. + CLIP_DEFAULT_PRECIS,.. + ANTIALIASED_QUALITY,.. + DEFAULT_PITCH|FF_DONTCARE,.. + _name.toWString()) + + Local strSymbolName:String = NameFromHandle(tmpSymbolHandle) + + 'If we now have a match, delete the first font returned and use the new symbol one. + + If strSymbolName.ToLower() = _name.ToLower() Then + DeleteObject handle + handle = tmpSymbolHandle + name = strSymbolName + Else + DeleteObject tmpSymbolHandle + EndIf + + EndIf + + size=_size + style=_style + + Return Self + + EndMethod + + Method LoadFromLogFont:TWindowsFont( pLogFont:LOGFONTW, pStyle% = 0, pSize:Double = 0:Double ) + + If pLogFont.lfWeight>=FW_BOLD Then pStyle:| FONT_BOLD + If pLogFont.lfItalic Then pStyle:| FONT_ITALIC + If pLogFont.lfUnderline Then pStyle:| FONT_UNDERLINE + If pLogFont.lfStrikeOut Then pStyle:| FONT_STRIKETHROUGH + + style = pStyle + + If Not pSize Then pSize = SizeFromLogFont( pLogFont ) + + size = pSize + + SetLogFontProperties( pLogFont, pStyle, pSize ) + + name = String.FromWString( Varptr pLogFont.lfFaceName00 ) + + If handle Then DeleteObject handle + handle = CreateFontIndirectW( pLogFont ) + + Return Self + + EndMethod + + Method LoadFromHandle:TWindowsFont(hfont) + + Local tmpLogFont:LOGFONTW = New LOGFONTW + GetObjectW( hfont, SizeOf(LOGFONTW), tmpLogFont ) + Return LoadFromLogFont( tmpLogFont ) + + EndMethod + + Method CharWidth( charcode ) + Local hdc=GetDC(0) + Local tfont=SelectObject( hdc,handle ) + + Local width=8,widths[3] + + If GetCharABCWidthsW( hdc,charcode,charcode,widths ) + width=widths[0]+widths[1]+widths[2] + Else If GetCharWidth32W( hdc,charcode,charcode,widths ) + width=widths[0] + EndIf + + SelectObject hdc,tfont + ReleaseDC 0,hdc + + Return width + EndMethod + + Method GetMaxCharWidth() + Local hdc=GetDC(0) + Local tfont=SelectObject(hdc,handle) + Local tm:TEXTMETRIC=New TEXTMETRIC + GetTextMetricsW hdc,tm + SelectObject(hdc,tfont) + ReleaseDC(0,hdc) + Return tm.tmAveCharWidth + EndMethod + + Method Delete() + If handle Then DeleteObject handle + EndMethod + + Function Request:TWindowsFont(font:TGuiFont) + + Local lf:LOGFONTW = New LOGFONTW + Local cf:CHOOSEFONT = New CHOOSEFONT + + cf.lStructSize=SizeOf(cf) + cf.hwndOwner=TWindowsGUIDriver.GetActiveHwnd() + cf.lpLogFont=lf + cf.Flags=CF_BOTH + + If font + Local p:Short Ptr = Short Ptr(Varptr lf.lfFaceName00) + For Local i = 0 Until Min(font.name.length, 31) + p[i]=font.name[i] + Next + SetLogFontProperties( lf, font.style, font.size ) + cf.Flags:|CF_INITTOLOGFONTSTRUCT + EndIf + + Local hwnd = GetFocus() + Local n = ChooseFontW(cf) + SetFocus(hwnd) + If Not n Return + + Local style + If cf.nFontType&BOLD_FONTTYPE style:|FONT_BOLD + If cf.nFontType&ITALIC_FONTTYPE style:|FONT_ITALIC + Return New TWindowsFont.LoadFromLogFont( lf, style, cf.iPointSize/Double(10) ) + + EndFunction + + Function DefaultFont:TWindowsFont( pFontSize:Double = 0, pFontStyle% = FONT_NORMAL ) + + 'Attempts to get hold of the Windows themed font (typically Tahoma on XP, Segeo UI on Vista) + Local tmpNonClientMetrics:NONCLIENTMETRICSW = New NONCLIENTMETRICSW + + If SystemParametersInfoW And SystemParametersInfoW( SPI_GETNONCLIENTMETRICS, 0, Int Byte Ptr tmpNonClientMetrics, 0 ) Then + Local tmpLogFont:LOGFONTW = New LOGFONTW + MemCopy tmpLogFont, Varptr tmpNonClientMetrics.lfMessageFont_lfHeight, SizeOf(tmpLogFont) + Return New TWindowsFont.LoadFromLogFont( tmpLogFont, pFontStyle, pFontSize ) + EndIf + + 'If these functions, for whatever reason, fail, then the default GUI font is used (typically MS Sans Serif). + 'Note: A font size of '8' has has been hard-coded in as no reliable substitute can be found, however this may cause + 'text to appear too small in some languages/lacalizations. + If pFontSize <= 0 Then pFontSize = 8 + Return New TWindowsFont.Load( "MS Shell Dlg", pFontSize, pFontStyle ) + + EndFunction + + Function NameFromHandle:String( pFntHandle:Int ) + + Local hdc = GetDC(0), buffer:Short[512] + Local tfont = SelectObject(hdc,pFntHandle) + + If Not GetTextFaceW(hdc,buffer.length,buffer) buffer[0] = 0 + + SelectObject(hdc, tfont) + ReleaseDC(0,hdc) + + Return String.FromWString(buffer) + + EndFunction + + Function LogicalUnitsFromSize( pSize:Double ) + + Local tmpDC:Int = GetDC(0) + Local tmpSize:Int = (pSize * GetDeviceCaps(tmpDC,LOGPIXELSY))/72 + 0.5 + ReleaseDC( 0, tmpDC ) + Return tmpSize + + EndFunction + + Function SizeFromLogFont:Double( pLogFont:LOGFONTW ) + + Local tmpDC:Int = GetDC(0) + Local tmpSize:Double = (Abs(pLogFont.lfHeight) * Double(72.0) )/GetDeviceCaps(tmpDC,LOGPIXELSY) + ReleaseDC( 0, tmpDC ) + Return tmpSize + + EndFunction + + Function SetLogFontProperties( pLogFont:LOGFONTW, pFlags%, pSize:Double = 0:Double ) + + If pFlags&FONT_BOLD Then pLogFont.lfWeight=FW_BOLD Else pLogFont.lfWeight=FW_NORMAL + If pFlags&FONT_ITALIC Then pLogFont.lfItalic=True Else pLogFont.lfItalic=False + If pFlags&FONT_UNDERLINE Then pLogFont.lfUnderline=True Else pLogFont.lfUnderline=False + If pFlags&FONT_STRIKETHROUGH Then pLogFont.lfStrikeOut=True Else pLogFont.lfStrikeOut=False + + If pSize > 0 Then pLogFont.lfHeight = -LogicalUnitsFromSize( pSize ) + + EndFunction + +EndType + +'A collection of functions that convert between Blitz pixmaps and Windows icons/bitmaps. +Type TWindowsGraphic Final + + Function BitmapMaskFromPixmap:Int(pix:TPixmap) + + Local x, pix2:TPixmap, usealpha + + If PixmapFormat(pix) = PF_RGBA8888 Or PixmapFormat(pix) = PF_BGRA8888 Then usealpha = True + + pix2=ConvertPixmap(pix,PF_BGR888);ClearPixels(pix2) + + For Local y:Int = 0 Until pix.height + For x = 0 Until pix.width + If usealpha + If (ReadPixel(pix,x,y) Shr 24) < 128 Then WritePixel(pix2,x,y,$FFFFFF) + Else + If (ReadPixel(pix,x,y) & $FFFFFF) = $FFFFFF Then WritePixel(pix2,x,y,$FFFFFF) + EndIf + Next + Next + + Return BitmapFromPixmap(pix2,False) + + EndFunction + + Function PreMultipliedBitmapFromPixmap32:Int( pix:TPixmap ) + + Local argb, a + Local pix2:TPixmap = CreatePixmap( pix.width, pix.height, pix.format), x + + For Local y:Int = 0 Until pix.height + For x = 0 Until pix.width + argb = ReadPixel(pix,x,y) + a = ((argb Shr 24) & $FF) + WritePixel(pix2,x,y,((((argb&$ff00ff)*a)Shr 8)&$ff00ff)|((((argb&$ff00)*a)Shr 8)&$ff00)|(a Shl 24)) + Next + Next + + Return BitmapFromPixmap(pix2,True) + + EndFunction + + Function BitmapFromPixmap:Int(pix:TPixmap, alpha:Int = True) + + Local bitCount:Int = 32, format:Int = PF_BGRA8888, bm + + If Not alpha Then + bitCount = 24 + format = PF_BGR888 + EndIf + + pix=ConvertPixmap(pix,format) + + Local hdc = GetDC(0) + + Local bi:BITMAPINFOHEADER = New BITMAPINFOHEADER + bi.biSize=SizeOf(bi) + bi.biWidth=pix.width + bi.biHeight=-pix.height + bi.biPlanes=1 + bi.biBitCount=bitCount + bi.biCompression=BI_RGB + + Local bits:Byte Ptr + Local src:Byte Ptr = pix.pixels + + If alpha + bm = CreateDibSection(hdc,bi,DIB_RGB_COLORS,Varptr bits,0,0) + Else + bm = CreateCompatibleBitmap(hdc,pix.width,pix.height) + EndIf + + Assert bm, "Cannot create bitmap. The computer may be running low on resources." + + For Local y:Int = 0 Until pix.height + SetDIBits(hdc,bm,pix.height-y-1,1,src,bi,DIB_RGB_COLORS) + src:+pix.pitch + Next + + ReleaseDC(0,hdc) + + Return bm + + EndFunction + + Function BitmapWithBackgroundFromPixmap32:Int( pix:TPixmap, pRed, pGreen, pBlue ) + + Local tmpPixel, tmpRed, tmpGreen, tmpBlue, tmpAlpha, tmpAlphaFloat#, tmpAlphaFloat2# + Local pix2:TPixmap = CreatePixmap( pix.width, pix.height, pix.format), x + + For Local y:Int = 0 Until pix.height + For x = 0 Until pix.width + + 'Read pixel and alpha info + tmpPixel = ReadPixel(pix,x,y) + tmpAlpha = ((tmpPixel Shr 24) & $FF) + tmpAlphaFloat = tmpAlpha/255.0 + tmpAlphaFloat2 = 1-tmpAlphaFloat + + 'Get individual colours + tmpBlue = tmpPixel & $FF;tmpGreen = (tmpPixel Shr 8) & $FF;tmpRed = (tmpPixel Shr 16)&$FF + + 'Courtesy of Mark T + tmpRed = (tmpRed * tmpAlphaFloat) + (tmpAlphaFloat2 * pRed) + tmpGreen = (tmpGreen * tmpAlphaFloat) + (tmpAlphaFloat2 * pGreen) + tmpBlue = (tmpBlue * tmpAlphaFloat) + (tmpAlphaFloat2 * pBlue) + + 'Write the new pixels + WritePixel(pix2,x,y,(tmpAlpha Shl 24)|(tmpRed Shl 16)|(tmpGreen Shl 8)|tmpBlue) + Next + Next + + Return BitmapFromPixmap(pix2,False) + + EndFunction + + Function IconFromPixmap32:Int(pix:TPixmap) + + ' Convert the pixmap to a HBITMAP + Local bitmap = BitmapFromPixmap(pix,True) + + ' and then copy/resize it (to the default size for icons/cusors). + Local hSrcBMP = CopyImage(bitmap, IMAGE_BITMAP , 0 , 0 , LR_DEFAULTSIZE) + + ' Now we need to create a mask bitmap for the image + Local hMaskBMP = BitmapMaskFromPixmap( pix ) + + ' So now we have our source and mask bitmaps, we can create an ICONINFO structure + Local IconInf:ICONINFO = New IconInfo + IconInf.fIcon = True + IconInf.hbmMask = hMaskBMP + IconInf.hbmColor = hSrcBMP + + ' Create the icon + Local tmpIcon = CreateIconIndirect(IconInf) + + ' Free our temporary bitmaps + DeleteObject(hMaskBMP) + DeleteObject(hSrcBMP) + DeleteObject(bitmap) + + Return tmpIcon + + EndFunction + +EndType + +Private + +Function KeyMods() + Local mods + If GetKeyState(VK_SHIFT)&$8000 mods:|MODIFIER_SHIFT + If GetKeyState(VK_CONTROL)&$8000 mods:|MODIFIER_CONTROL + If GetKeyState(VK_MENU)&$8000 mods:|MODIFIER_OPTION + If GetKeyState(VK_LWIN)&$8000 Or GetKeyState(VK_RWIN)&$8000 mods:|MODIFIER_SYSTEM + Return mods +EndFunction + +Function FindGadgetWindowHwnd(g:TGadget) + Local wg:TWindowsWindow + While g + wg=TWindowsWindow(g) + If wg Return wg.Query(QUERY_HWND) 'handle + g=g.parent + Wend +EndFunction + +Type TIntWrapper Final + Field value:Int + Function Create:TIntWrapper(value:Int) + Local tmpWrapper:TIntWrapper = New TIntWrapper + tmpWrapper.value = value + Return tmpWrapper + EndFunction + Method Compare( o:Object ) + Local c:TIntWrapper = TIntWrapper(o) + If c Then Return (value - c.value) + Return Super.Compare(o) + EndMethod + Method ToString$() + Return value + EndMethod +EndType diff --git a/mod/maxgui.mod/win32maxguiex.mod/winimports.bmx b/mod/maxgui.mod/win32maxguiex.mod/winimports.bmx new file mode 100644 index 0000000..b06ec9f --- /dev/null +++ b/mod/maxgui.mod/win32maxguiex.mod/winimports.bmx @@ -0,0 +1,1076 @@ +'Win32 Libraries +Import "-lcomctl32" +Import "-lole32" +Import "-loleaut32" +Import "-luuid" +Import "-lmsimg32" + +Import "mshtmlview.cpp" +Import "tom.bmx" + + +' Custom Window Messages + + Const WM_MAXGUILISTREFRESH% = WM_APP + $100 + +'Error Codes + + Const S_OK = 0 + + Const E_OUTOFMEMORY=$8007000E + Const E_INVALIDARG=$80070057 + Const E_ACCESSDENIED=$80070005 + +' WM_SIZE message wParam values + + Const SIZE_RESTORED=0 + Const SIZE_MINIMIZED=1 + Const SIZE_MAXIMIZED=2 + Const SIZE_MAXSHOW=3 + Const SIZE_MAXHIDE=4 + +'Tool-tips + + Const TTS_ALWAYSTIP% = $1 + Const TTS_NOPREFIX% = $2 + Const TTS_NOANIMATE% = $10 + Const TTS_NOFADE% = $20 + Const TTS_BALLOON% = $40 + + Const LPSTR_TEXTCALLBACK% = -1 + Const TTM_ADDTOOLW% = (WM_USER + 50) + +'WM_MENUCHAR Return Constants + + Const MNC_IGNORE% = 0 + Const MNC_CLOSE% = 1 + Const MNC_EXECUTE% = 2 + Const MNC_SELECT% = 3 + +'MK Constants + + Const MK_CONTROL% = $8 + Const MK_LBUTTON% = $1 + Const MK_MBUTTON% = $10 + Const MK_RBUTTON% = $2 + Const MK_SHIFT% = $4 + Const MK_XBUTTON1% = $20 + Const MK_XBUTTON2% = $40 + +'Gadget Drawing and Color Constants + + Const WS_EX_COMPOSITED = $2000000 + + 'TextArea Gadget Printing + Const MM_TEXT = 1 + + Type FORMATRANGE + Field hdc, hdcTarget + Field rcLeft, rcTop, rcRight, rcBottom + Field rcPageLeft, rcPageTop, rcPageRight, rcPageBottom + Field CHARRANGE_cpMin, CHARRANGE_cpMax + EndType + + Const PD_NOSELECTION = $4 + Const PD_DISABLEPRINTTOFILE = $80000 + Const PD_PRINTTOFILE = $20 + Const PD_RETURNDC = $100 + Const PD_RETURNDEFAULT = $400 + Const PD_RETURNIC = $200 + Const PD_SELECTION = $1 + Const PD_SHOWHELP = $800 + Const PD_NOPAGENUMS = $8 + Const PD_PAGENUMS = $2 + Const PD_ALLPAGES = $0 + Const PD_COLLATE = $10 + Const PD_HIDEPRINTTOFILE = $100000 + + Type PRINTDLGW + Field lStructSize = SizeOf(Self) + Field hwndOwner, hDevMode, hDevNames, hdc + Field flags, nFromPage:Short, nToPage:Short, nMinPage:Short, nMaxPage:Short, nCopies:Short + Field padding:Short, padding2:Short, padding3:Short, padding4:Short, padding5:Short, padding6:Short + Field padding7:Short, padding8:Short, padding9:Short, padding10:Short, padding11:Short, padding12:Short + Field padding13:Short, padding14:Short, padding15:Short, padding16:Short + EndType + + Type DOCINFOW + Field cbSize = SizeOf(Self) + Field lpszDocName:Short Ptr, lpszOutput:Short Ptr, lpszDatatype:Short Ptr + Field fwType + EndType + + 'Button Image + Const BCM_FIRST = $1600 + Const BCM_SETIMAGELIST% = BCM_FIRST+2 + + Const BUTTON_IMAGELIST_ALIGN_LEFT% = 0 + Const BUTTON_IMAGELIST_ALIGN_RIGHT% = 1 + Const BUTTON_IMAGELIST_ALIGN_TOP% = 2 + Const BUTTON_IMAGELIST_ALIGN_BOTTOM% = 3 + Const BUTTON_IMAGELIST_ALIGN_CENTER% = 4 + + 'ComboBox cue-banners + Const CBM_FIRST = $1700 + Const CB_SETCUEBANNER = CBM_FIRST + 3 + + 'Progress bar colors + Const PBM_SETBARCOLOR=WM_USER+9 + Const PBM_SETBKCOLOR=CCM_FIRST+1 + + 'SetBkMode() consts, etc. + Const LWA_COLORKEY=1 + Const LWA_ALPHA=2 + Const LWA_BOTH=3 + Const TRANSPARENT=1 + Const OPAQUE = 2 + + 'RedrawWindow() flags + Const RDW_FRAME = $500 + Const RDW_UPDATENOW = $100 + Const RDW_INVALIDATE = $1 + Const RDW_NOCHILDREN = $40 + Const RDW_ALLCHILDREN = $80 + Const RDW_ERASE = $4 + Const RDW_ERASENOW = $200 + + 'ScrollBar constants + Const OBJID_HSCROLL = $FFFFFFFA + Const OBJID_VSCROLL = $FFFFFFFB + Const OBJID_CLIENT = $FFFFFFFC + + Const EM_GETSCROLLPOS = WM_USER + 221 + Const EM_SETSCROLLPOS = WM_USER + 222 + Const EM_SETZOOM = WM_USER + 225 + + 'GetDCEx Constants + Const DCX_WINDOW = $1 + Const DCX_CACHE = $2 + Const DCX_NORESETATTRS = $4 + Const DCX_CLIPCHILDREN = $8 + Const DCX_CLIPSIBLINGS = $10 + Const DCX_PARENTCLIP = $20 + Const DCX_EXCLUDERGN = $40 + Const DCX_INTERSECTRGN = $80 + Const DCX_EXCLUDEUPDATE = $100 + Const DCX_INTERSECTUPDATE = $200 + Const DCX_LOCKWINDOWUPDATE = $400 + Const DCX_VALIDATE = $200000 + + Const WM_THEMECHANGED = $31A + + 'These functions are only supported by Win 2000+, therefore we dynamically link to the functions using DLLs. + Global libUser32 = LoadLibraryW("user32.dll"), libUXTheme = LoadLibraryW("uxtheme.dll") + Global SetLayeredWindowAttributes(hwnd,crKey,bAlpha:Byte,dwFlags) "win32" = GetProcAddress(libUser32, "SetLayeredWindowAttributes") + Global SystemParametersInfoW%( uiAction%, uiParam%, pvParam, fWinIni% ) "win32" = GetProcAddress(libUser32,"SystemParametersInfoW") + Global DrawThemeParentBackground(hwnd,hDC,pRect:Int Ptr) "win32" = GetProcAddress(libUXTheme, "DrawThemeParentBackground") + Global SetWindowThemeW( pHwnd, pThemeStr:Short Ptr, pList:Short Ptr ) "win32" = GetProcAddress(libUXTheme, "SetWindowTheme") + Global OpenThemeData%( hwnd%, lpszClassString:Short Ptr ) "win32" = GetProcAddress(libUXTheme, "OpenThemeData") + Global GetThemeSysFont%( hTheme%, iFontID%, pLF:Byte Ptr ) "win32" = GetProcAddress(libUXTheme, "GetThemeSysFont") + Global DrawThemeBackground( hTheme%, hdc%, iPartID%, iStateID%, pRect:Int Ptr, pClipRect:Int Ptr) "win32" = GetProcAddress(libUXTheme, "DrawThemeBackground") + Global CloseThemeData( hTheme% ) "win32" = GetProcAddress(libUXTheme, "CloseThemeData") + Global DrawThemeText( hTheme%, hDC%, iPartID%, iStateID%, pszText$w, iCharCount%, dwTextFlags%, dwTextFlags2%, pRect:Int Ptr ) "win32" = GetProcAddress(libUXTheme, "DrawThemeText") + Global GetThemeBackgroundContentRect( hTheme%, hdc%, iPartId%, iStateId%, pBoundingRect:Int Ptr, pContentRect:Int Ptr ) "win32" = GetProcAddress(libUXTheme, "GetThemeBackgroundContentRect") + Global IsThemeBackgroundPartiallyTransparent( hTheme%, iPartId%, iStateId% ) "win32" = GetProcAddress(libUXTheme, "IsThemeBackgroundPartiallyTransparent") + + 'Theme Fonts + Const TMT_CAPTIONFONT = 801 + Const TMT_SMALLCAPTIONFONT = 802 + Const TMT_MENUFONT = 803 + Const TMT_STATUSFONT = 804 + Const TMT_MSGBOXFONT = 805 + Const TMT_ICONTITLEFONT = 806 + + Const SPI_GETWORKAREA = 48 + Const SPI_GETNONCLIENTMETRICS% = 41 + + 'WM_DRAWITEM States + + Const ODS_SELECTED = $1 + Const ODS_GRAYED = $2 + Const ODS_DISABLED = $4 + Const ODS_CHECKED = $8 + Const ODS_FOCUS = $10 + Const ODS_HOTLIGHT = $40 + Const ODS_INACTIVE = $80 + Const ODS_NOACCEL = $100 + Const ODS_NOFOCUSRECT = $200 + + 'DrawFrameControl Constants + Const DFC_BUTTON = $4 + Const DFCS_BUTTONPUSH = $10 + Const DFCS_INACTIVE = $100 + Const DFCS_PUSHED = $200 + Const DFCS_CHECKED = $400 + Const DFCS_TRANSPARENT = $800 + Const DFCS_HOT = $1000 + Const DFCS_ADJUSTRECT = $2000 + Const DFCS_FLAT = $4000 + Const DFCS_MONO = $8000 + + 'DrawThemeBackground Button States + Const BP_PUSHBUTTON = 1 + Const PBS_NORMAL = 1 + Const PBS_HOT = 2 + Const PBS_PRESSED = 3 + Const PBS_DISABLED = 4 + Const PBS_DEFAULTED = 5 + + Type NONCLIENTMETRICSW + Field cbSize = SizeOf(Self) + Field iBorderWidth + Field iScrollWidth + Field iScrollHeight + Field iCaptionWidth + Field iCaptionHeight + + ' lfCaptionFont:LOGFONTW + + Field lfCaptionFont_lfHeight, lfCaptionFont_lfWidth, lfCaptionFont_lfEscapement, lfCaptionFont_lfOrientation + Field lfCaptionFont_lfWeight, lfCaptionFont_lfItalic:Byte, lfCaptionFont_lfUnderline:Byte, lfCaptionFont_lfStrikeOut:Byte + Field lfCaptionFont_lfCharSet:Byte, lfCaptionFont_lfOutPrecision:Byte, lfCaptionFont_lfClipPrecision:Byte + Field lfCaptionFont_lfQuality:Byte, lfCaptionFont_lfPitchAndFamily:Byte + + Field lfCaptionFont_lfFaceName00:Short, lfCaptionFont_lfFaceName01:Short, lfCaptionFont_lfFaceName02:Short, lfCaptionFont_lfFaceName03:Short, lfCaptionFont_lfFaceName04:Short + Field lfCaptionFont_lfFaceName05:Short, lfCaptionFont_lfFaceName06:Short, lfCaptionFont_lfFaceName07:Short, lfCaptionFont_lfFaceName08:Short, lfCaptionFont_lfFaceName09:Short + Field lfCaptionFont_lfFaceName0a:Short, lfCaptionFont_lfFaceName0b:Short, lfCaptionFont_lfFaceName0c:Short, lfCaptionFont_lfFaceName0d:Short, lfCaptionFont_lfFaceName0e:Short + Field lfCaptionFont_lfFaceName0f:Short, lfCaptionFont_lfFaceName10:Short, lfCaptionFont_lfFaceName11:Short, lfCaptionFont_lfFaceName12:Short, lfCaptionFont_lfFaceName13:Short + Field lfCaptionFont_lfFaceName14:Short, lfCaptionFont_lfFaceName15:Short, lfCaptionFont_lfFaceName16:Short, lfCaptionFont_lfFaceName17:Short, lfCaptionFont_lfFaceName18:Short + Field lfCaptionFont_lfFaceName19:Short, lfCaptionFont_lfFaceName1a:Short, lfCaptionFont_lfFaceName1b:Short, lfCaptionFont_lfFaceName1c:Short, lfCaptionFont_lfFaceName1d:Short + Field lfCaptionFont_lfFaceName1e:Short, lfCaptionFont_lfFaceName1f:Short + + Field iSmCaptionWidth + Field iSmCaptionHeight + + ' lfSmCaptionFont:LOGFONTW + + Field lfSmCaptionFont_lfHeight, lfSmCaptionFont_lfWidth, lfSmCaptionFont_lfEscapement, lfSmCaptionFont_lfOrientation + Field lfSmCaptionFont_lfWeight, lfSmCaptionFont_lfItalic:Byte, lfSmCaptionFont_lfUnderline:Byte, lfSmCaptionFont_lfStrikeOut:Byte + Field lfSmCaptionFont_lfCharSet:Byte, lfSmCaptionFont_lfOutPrecision:Byte, lfSmCaptionFont_lfClipPrecision:Byte + Field lfSmCaptionFont_lfQuality:Byte, lfSmCaptionFont_lfPitchAndFamily:Byte + + Field lfSmCaptionFont_lfFaceName00:Short, lfSmCaptionFont_lfFaceName01:Short, lfSmCaptionFont_lfFaceName02:Short, lfSmCaptionFont_lfFaceName03:Short, lfSmCaptionFont_lfFaceName04:Short + Field lfSmCaptionFont_lfFaceName05:Short, lfSmCaptionFont_lfFaceName06:Short, lfSmCaptionFont_lfFaceName07:Short, lfSmCaptionFont_lfFaceName08:Short, lfSmCaptionFont_lfFaceName09:Short + Field lfSmCaptionFont_lfFaceName0a:Short, lfSmCaptionFont_lfFaceName0b:Short, lfSmCaptionFont_lfFaceName0c:Short, lfSmCaptionFont_lfFaceName0d:Short, lfSmCaptionFont_lfFaceName0e:Short + Field lfSmCaptionFont_lfFaceName0f:Short, lfSmCaptionFont_lfFaceName10:Short, lfSmCaptionFont_lfFaceName11:Short, lfSmCaptionFont_lfFaceName12:Short, lfSmCaptionFont_lfFaceName13:Short + Field lfSmCaptionFont_lfFaceName14:Short, lfSmCaptionFont_lfFaceName15:Short, lfSmCaptionFont_lfFaceName16:Short, lfSmCaptionFont_lfFaceName17:Short, lfSmCaptionFont_lfFaceName18:Short + Field lfSmCaptionFont_lfFaceName19:Short, lfSmCaptionFont_lfFaceName1a:Short, lfSmCaptionFont_lfFaceName1b:Short, lfSmCaptionFont_lfFaceName1c:Short, lfSmCaptionFont_lfFaceName1d:Short + Field lfSmCaptionFont_lfFaceName1e:Short, lfSmCaptionFont_lfFaceName1f:Short + + Field iMenuWidth + Field iMenuHeight + + ' lfMenuFont:LOGFONTW + + Field lfMenuFont_lfHeight, lfMenuFont_lfWidth, lfMenuFont_lfEscapement, lfMenuFont_lfOrientation + Field lfMenuFont_lfWeight, lfMenuFont_lfItalic:Byte, lfMenuFont_lfUnderline:Byte, lfMenuFont_lfStrikeOut:Byte + Field lfMenuFont_lfCharSet:Byte, lfMenuFont_lfOutPrecision:Byte, lfMenuFont_lfClipPrecision:Byte + Field lfMenuFont_lfQuality:Byte, lfMenuFont_lfPitchAndFamily:Byte + + Field lfMenuFont_lfFaceName00:Short, lfMenuFont_lfFaceName01:Short, lfMenuFont_lfFaceName02:Short, lfMenuFont_lfFaceName03:Short, lfMenuFont_lfFaceName04:Short + Field lfMenuFont_lfFaceName05:Short, lfMenuFont_lfFaceName06:Short, lfMenuFont_lfFaceName07:Short, lfMenuFont_lfFaceName08:Short, lfMenuFont_lfFaceName09:Short + Field lfMenuFont_lfFaceName0a:Short, lfMenuFont_lfFaceName0b:Short, lfMenuFont_lfFaceName0c:Short, lfMenuFont_lfFaceName0d:Short, lfMenuFont_lfFaceName0e:Short + Field lfMenuFont_lfFaceName0f:Short, lfMenuFont_lfFaceName10:Short, lfMenuFont_lfFaceName11:Short, lfMenuFont_lfFaceName12:Short, lfMenuFont_lfFaceName13:Short + Field lfMenuFont_lfFaceName14:Short, lfMenuFont_lfFaceName15:Short, lfMenuFont_lfFaceName16:Short, lfMenuFont_lfFaceName17:Short, lfMenuFont_lfFaceName18:Short + Field lfMenuFont_lfFaceName19:Short, lfMenuFont_lfFaceName1a:Short, lfMenuFont_lfFaceName1b:Short, lfMenuFont_lfFaceName1c:Short, lfMenuFont_lfFaceName1d:Short + Field lfMenuFont_lfFaceName1e:Short, lfMenuFont_lfFaceName1f:Short + + ' lfStatusFont:LOGFONTW + + Field lfStatusFont_lfHeight, lfStatusFont_lfWidth, lfStatusFont_lfEscapement, lfStatusFont_lfOrientation + Field lfStatusFont_lfWeight, lfStatusFont_lfItalic:Byte, lfStatusFont_lfUnderline:Byte, lfStatusFont_lfStrikeOut:Byte + Field lfStatusFont_lfCharSet:Byte, lfStatusFont_lfOutPrecision:Byte, lfStatusFont_lfClipPrecision:Byte + Field lfStatusFont_lfQuality:Byte, lfStatusFont_lfPitchAndFamily:Byte + + Field lfStatusFont_lfFaceName00:Short, lfStatusFont_lfFaceName01:Short, lfStatusFont_lfFaceName02:Short, lfStatusFont_lfFaceName03:Short, lfStatusFont_lfFaceName04:Short + Field lfStatusFont_lfFaceName05:Short, lfStatusFont_lfFaceName06:Short, lfStatusFont_lfFaceName07:Short, lfStatusFont_lfFaceName08:Short, lfStatusFont_lfFaceName09:Short + Field lfStatusFont_lfFaceName0a:Short, lfStatusFont_lfFaceName0b:Short, lfStatusFont_lfFaceName0c:Short, lfStatusFont_lfFaceName0d:Short, lfStatusFont_lfFaceName0e:Short + Field lfStatusFont_lfFaceName0f:Short, lfStatusFont_lfFaceName10:Short, lfStatusFont_lfFaceName11:Short, lfStatusFont_lfFaceName12:Short, lfStatusFont_lfFaceName13:Short + Field lfStatusFont_lfFaceName14:Short, lfStatusFont_lfFaceName15:Short, lfStatusFont_lfFaceName16:Short, lfStatusFont_lfFaceName17:Short, lfStatusFont_lfFaceName18:Short + Field lfStatusFont_lfFaceName19:Short, lfStatusFont_lfFaceName1a:Short, lfStatusFont_lfFaceName1b:Short, lfStatusFont_lfFaceName1c:Short, lfStatusFont_lfFaceName1d:Short + Field lfStatusFont_lfFaceName1e:Short, lfStatusFont_lfFaceName1f:Short + + ' lfMessageFont:LOGFONTW + + Field lfMessageFont_lfHeight, lfMessageFont_lfWidth, lfMessageFont_lfEscapement, lfMessageFont_lfOrientation + Field lfMessageFont_lfWeight, lfMessageFont_lfItalic:Byte, lfMessageFont_lfUnderline:Byte, lfMessageFont_lfStrikeOut:Byte + Field lfMessageFont_lfCharSet:Byte, lfMessageFont_lfOutPrecision:Byte, lfMessageFont_lfClipPrecision:Byte + Field lfMessageFont_lfQuality:Byte, lfMessageFont_lfPitchAndFamily:Byte + + Field lfMessageFont_lfFaceName00:Short, lfMessageFont_lfFaceName01:Short, lfMessageFont_lfFaceName02:Short, lfMessageFont_lfFaceName03:Short, lfMessageFont_lfFaceName04:Short + Field lfMessageFont_lfFaceName05:Short, lfMessageFont_lfFaceName06:Short, lfMessageFont_lfFaceName07:Short, lfMessageFont_lfFaceName08:Short, lfMessageFont_lfFaceName09:Short + Field lfMessageFont_lfFaceName0a:Short, lfMessageFont_lfFaceName0b:Short, lfMessageFont_lfFaceName0c:Short, lfMessageFont_lfFaceName0d:Short, lfMessageFont_lfFaceName0e:Short + Field lfMessageFont_lfFaceName0f:Short, lfMessageFont_lfFaceName10:Short, lfMessageFont_lfFaceName11:Short, lfMessageFont_lfFaceName12:Short, lfMessageFont_lfFaceName13:Short + Field lfMessageFont_lfFaceName14:Short, lfMessageFont_lfFaceName15:Short, lfMessageFont_lfFaceName16:Short, lfMessageFont_lfFaceName17:Short, lfMessageFont_lfFaceName18:Short + Field lfMessageFont_lfFaceName19:Short, lfMessageFont_lfFaceName1a:Short, lfMessageFont_lfFaceName1b:Short, lfMessageFont_lfFaceName1c:Short, lfMessageFont_lfFaceName1d:Short + Field lfMessageFont_lfFaceName1e:Short, lfMessageFont_lfFaceName1f:Short + + + 'Field iPaddedBorderWidth + EndType + + 'DrawText Constants + Const DT_BOTTOM= $8 + Const DT_CALCRECT= $400 + Const DT_CENTER= $1 + Const DT_EDITCONTROL= $2000 + Const DT_END_ELLIPSIS= $8000 + Const DT_EXPANDTABS = $40 + Const DT_EXTERNALLEADING = $200 + Const DT_HIDEPREFIX = $100000 + Const DT_INTERNAL = $1000 + Const DT_LEFT = $0 + Const DT_MODIFYSTRING = $10000 + Const DT_NOCLIP = $100 + Const DT_NOFULLWIDTHCHARBREAK = $80000 + Const DT_NOPREFIX = $800 + Const DT_NOT_SPECIFIC = $50000 + Const DT_PATH_ELLIPSIS = $4000 + Const DT_PREFIXONLY = $200000 + Const DT_RIGHT = $2 + Const DT_RTLREADING = $20000 + Const DT_SINGLELINE = $20 + Const DT_TABSTOP = $80 + Const DT_TOP = $0 + Const DT_VCENTER = $4 + Const DT_WORD_ELLIPSIS = $40000 + Const DT_WORDBREAK = $10 + + 'ExtTextOut + Const ETO_GRAYED:Int = 1 + Const ETO_OPAQUE:Int = 2 + Const ETO_CLIPPED:Int = 4 + + 'DrawItemStruct + Type DRAWITEMSTRUCT + Field CtlType, CtlID, ItemID, ItemAction, ItemState + Field hwndItem, hDC, rcItem_Left, rcItem_Top, rcItem_Right, rcItem_Bottom, itemData + EndType + + 'Button Image Constants + Const IMAGE_BITMAP = 0 + Const IMAGE_ICON = 1 + + 'Menu Info + Type MENUINFO + Field cbSize% = SizeOf(Self) + Field fMask% + Field dwStyle% + Field cyMax% + Field hbrBack% + Field dwContextHelpID% + Field dwMenuData:Int Ptr + EndType + + Const MIM_MAXHEIGHT = $1 + Const MIM_BACKGROUND = $2 + Const MIM_HELPID = $4 + Const MIM_MENUDATA = $8 + Const MIM_STYLE = $10 + Const MIM_APPLYTOSUBMENUS = $80000000 + + Const MNS_NOCHECK = $80000000 + Const MNS_MODELESS = $40000000 + Const MNS_DRAGDROP = $20000000 + Const MNS_AUTODISMISS = $10000000 + Const MNS_NOTIFYBYPOS = $8000000 + Const MNS_CHECKORBMP = $4000000 + + Const GA_PARENT = 1 + Const GA_ROOT = 2 + Const GA_ROOTOWNER = 3 + + 'External functions + Extern "Win32" + +' Function GetCharABCWidthsW(dc,firstcharcode,lastcharcode,widths:Int Ptr Ptr) + Function GetCharABCWidthsW(dc,firstcharcode,lastcharcode,widths:Int Ptr) + + Function GetCharWidth32W(hdc,first,last,widths:Int Ptr) + + 'BRL.System + Function _TrackMouseEvent( trackmouseeventstrunct:Byte Ptr ) + + 'Imagelists and pixmap conversion + Function ImageList_Add(himl,hbmImage,crMask) + Function ImageList_Destroy( hImageList ) + Function ImageList_GetImageCount( hImageList ) + Function CreateDIBSection(hdc,bminfo:Byte Ptr,iUsage,bits:Byte Ptr Ptr,hSection,dwOffset) + Function AlphaBlend_(hdc,dx,dy,dw,dh,hdc2,src,sry,srcw,srch,rop)="AlphaBlend@44" + + 'WM_CTLCOLORXXXX handling + Function SetBkMode( hdc, mode) + Function SetBkColor( hdc, crColor ) + Function GetAncestor_( hwnd, gaFlags ) = "GetAncestor@8" + Function SetTextColor_( hdc, crColor ) = "SetTextColor@8" + + 'Drawing Contexts + Function GetObjectW( hgdiobj, cbBuffer, lpvObject:Byte Ptr ) + Function SaveDC( hdc ) + Function RestoreDC( hdc, savestate ) + Function CreatePatternBrush( bitmap ) + Function GetDCEx( hwnd, hRgn, flags ) + Function ReleaseDC( hwnd, hdc ) + Function GetDCOrgEx( hdc, point:Int Ptr ) + Function GetWindowOrgEx( hdc, point:Int Ptr ) + Function GetWindowExtEx( hdc, size:Int Ptr ) + + 'Drawing + Function DrawTextW( hdc, lpString$w, nCount, lpRect:Int Ptr, uFormat ) + Function DrawFocusRect( hdc, lprc:Int Ptr ) + Function DrawFrameControl( hdc, lprc:Int Ptr, uType%, uState% ) + Function ExtTextOutW( hdc, x, y, fuOptions, lpRc:Int Ptr, lpString$w, cbCount, lpDx:Int Ptr ) + + 'Resizing + Function BeginDeferWindowPos( nCount ) + Function EndDeferWindowPos( hdwpStruct ) + Function DeferWindowPos( hWinPosInfo, hWnd, hWndInsertAfter, x, y, cx, cy, uFlags) + + 'Position and regions + Function IsRectEmpty( rect:Int Ptr ) + Function GetClipBox( hdc, rect:Int Ptr) + Function GetUpdateRect( hwnd, rect:Int Ptr, pErase ) + Function ScreenToClient( hwnd, rect:Int Ptr ) + Function RedrawWindow(hwnd, lprcUpdate:Int Ptr, hrgnUpdate:Int Ptr, flags ) + Function FrameRect( hdc, rect:Int Ptr, hBrush ) + Function InflateRect( rect:Int Ptr, dx, dy ) + Function OffsetRect( rect:Int Ptr, dx, dy ) + Function IntersectRect( lprcDest:Int Ptr, lprcSrc1:Int Ptr, lprcSrc2:Int Ptr ) + Function CopyRect( dest:Int Ptr, src:Int Ptr ) + Function GDISetRect( rect:Int Ptr, xLeft, yTop, xRight, yBottom ) = "SetRect@20" + + 'Menu Stuff + Function GetMenu_( hwnd ) = "GetMenu@4" + Function SetMenuItemBitmaps( hMenu, uPosition, uFlags, hBitmapUnchecked, hBitmapChecked ) + Function SetMenuInfo( hMenu, lpcMenuInfo:Byte Ptr ) + Function GetSysColor( hColor ) + + 'Scroll-bar fixes + Function GetSystemMetrics( metric ) + Function GetScrollBarInfo( hwnd, idObject, pScrollBarInfo:Int Ptr ) + + 'Gadget text retrieval + Function GetWindowTextLengthW( hwnd ) + Function GetWindowTextW( hwnd, lpString:Short Ptr, nMaxCount) + + 'Missing misc. system functions + Function GetCursor() + Function GetClassNameW%( pHwnd%, pTextOut:Short Ptr, pTextLength% ) + Function GetLastError() + Function FreeLibrary( hLibrary ) + + 'Printing functions for text-area GadgetPrint() + Function PrintDlg( printDialogStruct:Byte Ptr ) = "PrintDlgW@4" + Function StartDocW( hdc, pDocStruct:Byte Ptr ) + Function EndDoc( hdc ) + Function AbortDoc( hdc ) + Function StartPage( hdc ) + Function EndPage( hdc ) + Function SetMapMode( hdc, pMode ) + Function PrintWindow( hwnd, hdc, flags ) + + 'Icons + Function CreateIconIndirect(IconInf:Byte Ptr) + Function CopyImage(hImage , uType , xDesired , yDesired , flags) + Function DestroyIcon(hIcon) + + EndExtern + +'HTMLView C++ Functions (see mshtmlview.cpp) + + Extern "C" + Function msHtmlCreate( owner:Object,wndclass:Short Ptr,hwnd,flags ) + Function msHtmlGo( handle,url$w ) + Function msHtmlRun( handle,script$w ) + Function msHtmlSetShape( handle,x,y,w,h ) + Function msHtmlSetVisible( handle,visible ) + Function msHtmlSetEnabled( handle,enabled ) + Function msHtmlActivate(handle,cmd) + Function msHtmlStatus(handle) + Function msHtmlHwnd(handle) + Function msHtmlBrowser:IWebBrowser2(handle) + Function mstmlDocument:IHTMLDocument2(handle) + EndExtern + +'Icon Stuff + + Const LR_DEFAULTSIZE = $40 + + Type ICONINFO + Field fIcon + Field xHotspot + Field yHotspot + Field hbmMask + Field hbmColor + EndType + +'Treeview Consts + + Const TVM_FIRST = $1100 + Const TVS_EX_DOUBLEBUFFER = $4 + Const TVS_EX_FADEINOUTEXPANDOS = $40 + Const TVM_SETEXTENDEDSTYLE = TVM_FIRST + 44 + + Const TTN_GETDISPINFOW = -530 + +'System State Contstants + + Const STATE_SYSTEM_UNAVAILABLE = $00000001 + Const STATE_SYSTEM_SELECTED = $00000002 + Const STATE_SYSTEM_FOCUSED = $00000004 + Const STATE_SYSTEM_PRESSED = $00000008 + Const STATE_SYSTEM_CHECKED = $00000010 + Const STATE_SYSTEM_MIXED = $00000020 + Const STATE_SYSTEM_READONLY = $00000040 + Const STATE_SYSTEM_HOTTRACKED = $00000080 + Const STATE_SYSTEM_DEFAULT = $00000100 + Const STATE_SYSTEM_EXPANDED = $00000200 + Const STATE_SYSTEM_COLLAPSED = $00000400 + Const STATE_SYSTEM_BUSY = $00000800 + Const STATE_SYSTEM_FLOATING = $00001000 + Const STATE_SYSTEM_MARQUEED = $00002000 + Const STATE_SYSTEM_ANIMATED = $00004000 + Const STATE_SYSTEM_INVISIBLE = $00008000 + Const STATE_SYSTEM_OFFSCREEN = $00010000 + Const STATE_SYSTEM_SIZEABLE = $00020000 + Const STATE_SYSTEM_MOVEABLE = $00040000 + Const STATE_SYSTEM_SELFVOICING = $00080000 + Const STATE_SYSTEM_FOCUSABLE = $00100000 + Const STATE_SYSTEM_SELECTABLE = $00200000 + Const STATE_SYSTEM_LINKED = $00400000 + Const STATE_SYSTEM_TRAVERSED = $00800000 + Const STATE_SYSTEM_MULTISELECTABLE = $01000000 + Const STATE_SYSTEM_EXTSELECTABLE = $02000000 + Const STATE_SYSTEM_ALERT_LOW = $04000000 + Const STATE_SYSTEM_ALERT_MEDIUM = $08000000 + Const STATE_SYSTEM_ALERT_HIGH = $10000000 + Const STATE_SYSTEM_VALID = $1FFFFFFF + +'System Metrics + + Const SM_CXSCREEN = 0 + Const SM_CYSCREEN = 1 + Const SM_CXVSCROLL = 2 + Const SM_CYHSCROLL = 3 + Const SM_CYCAPTION = 4 + Const SM_CXBORDER = 5 + Const SM_CYBORDER = 6 + Const SM_CXDLGFRAME = 7 + Const SM_CYDLGFRAME = 8 + Const SM_CYVTHUMB = 9 + Const SM_CXHTHUMB = 10 + Const SM_CXICON = 11 + Const SM_CYICON = 12 + Const SM_CXCURSOR = 13 + Const SM_CYCURSOR = 14 + Const SM_CYMENU = 15 + Const SM_CXFULLSCREEN = 16 + Const SM_CYFULLSCREEN = 17 + Const SM_CYKANJIWINDOW = 18 + Const SM_MOUSEPRESENT = 19 + Const SM_CYVSCROLL = 20 + Const SM_CXHSCROLL = 21 + Const SM_DEBUG = 22 + Const SM_SWAPBUTTON = 23 + Const SM_RESERVED1 = 24 + Const SM_RESERVED2 = 25 + Const SM_RESERVED3 = 26 + Const SM_RESERVED4 = 27 + Const SM_CXMIN = 28 + Const SM_CYMIN = 29 + Const SM_CXSIZE = 30 + Const SM_CYSIZE = 31 + Const SM_CXFRAME = 32 + Const SM_CYFRAME = 33 + Const SM_CXMINTRACK = 34 + Const SM_CYMINTRACK = 35 + Const SM_CXDOUBLECLK = 36 + Const SM_CYDOUBLECLK = 37 + Const SM_CXICONSPACING = 38 + Const SM_CYICONSPACING = 39 + Const SM_MENUDROPALIGNMENT = 40 + Const SM_PENWINDOWS = 41 + Const SM_DBCSENABLED = 42 + Const SM_CMOUSEBUTTONS = 43 + Const SM_CXFIXEDFRAME = SM_CXDLGFRAME + Const SM_CYFIXEDFRAME = SM_CYDLGFRAME + Const SM_CXSIZEFRAME = SM_CXFRAME + Const SM_CYSIZEFRAME = SM_CYFRAME + Const SM_SECURE = 44 + Const SM_CXEDGE = 45 + Const SM_CYEDGE = 46 + Const SM_CXMINSPACING = 47 + Const SM_CYMINSPACING = 48 + Const SM_CXSMICON = 49 + Const SM_CYSMICON = 50 + Const SM_CYSMCAPTION = 51 + Const SM_CXSMSIZE = 52 + Const SM_CYSMSIZE = 53 + Const SM_CXMENUSIZE = 54 + Const SM_CYMENUSIZE = 55 + Const SM_ARRANGE = 56 + Const SM_CXMINIMIZED = 57 + Const SM_CYMINIMIZED = 58 + Const SM_CXMAXTRACK = 59 + Const SM_CYMAXTRACK = 60 + Const SM_CXMAXIMIZED = 61 + Const SM_CYMAXIMIZED = 62 + Const SM_NETWORK = 63 + Const SM_CLEANBOOT = 67 + Const SM_CXDRAG = 68 + Const SM_CYDRAG = 69 + Const SM_SHOWSOUNDS = 70 + Const SM_CXMENUCHECK = 71 + Const SM_CYMENUCHECK = 72 + Const SM_SLOWMACHINE = 73 + Const SM_MIDEASTENABLED = 74 + Const SM_MOUSEWHEELPRESENT = 75 + Const SM_XVIRTUALSCREEN = 76 + Const SM_YVIRTUALSCREEN = 77 + Const SM_CXVIRTUALSCREEN = 78 + Const SM_CYVIRTUALSCREEN = 79 + Const SM_CMONITORS = 80 + Const SM_SAMEDISPLAYFORMAT = 81 + Const SM_CMETRICS = 83 + + +Type DLLVERSIONINFO2 + Field cbSize = SizeOf(Self), dwMajorVersion, dwMinorVersion, dwBuildNo, dwPlatformID + Field dwFlags, ulVersion:Long +EndType + +Type NMLVGETINFOTIPW + Field NMHDR_hwnd, NMHDR_idFrom, NMHDR_code + Field dwFlags, pszText:Short Ptr, cchTextMax + Field iItem, iSubItem, lParam +EndType + +?Debug + +Type TWindowsDebug + + Const WM_ACTIVATE% = $6 + Const WM_ACTIVATEAPP% = $1C + Const WM_AFXFIRST% = $360 + Const WM_AFXLAST% = $37F + Const WM_APP% = $8000 + Const WM_ASKCBFORMATNAME% = $30C + Const WM_CANCELJOURNAL% = $4B + Const WM_CANCELMODE% = $1F + Const WM_CAPTURECHANGED% = $215 + Const WM_CHANGECBCHAIN% = $30D + Const WM_CHANGEUISTATE% = $127 + Const WM_CHAR% = $102 + Const WM_CHARTOITEM% = $2F + Const WM_CHILDACTIVATE% = $22 + Const WM_CLEAR% = $303 + Const WM_CLOSE% = $10 + Const WM_COMMAND% = $111 + Const WM_COMPACTING% = $41 + Const WM_COMPAREITEM% = $39 + Const WM_CONTEXTMENU% = $7B + Const WM_COPY% = $301 + Const WM_COPYDATA% = $4A + Const WM_CREATE% = $1 + Const WM_CTLCOLORBTN% = $135 + Const WM_CTLCOLORDLG% = $136 + Const WM_CTLCOLOREDIT% = $133 + Const WM_CTLCOLORLISTBOX% = $134 + Const WM_CTLCOLORMSGBOX% = $132 + Const WM_CTLCOLORSCROLLBAR% = $137 + Const WM_CTLCOLORSTATIC% = $138 + Const WM_CUT% = $300 + Const WM_DEADCHAR% = $103 + Const WM_DELETEITEM% = $2D + Const WM_DESTROY% = $2 + Const WM_DESTROYCLIPBOARD% = $307 + Const WM_DEVICECHANGE% = $219 + Const WM_DEVMODECHANGE% = $1B + Const WM_DISPLAYCHANGE% = $7E + Const WM_DRAWCLIPBOARD% = $308 + Const WM_DRAWITEM% = $2B + Const WM_DROPFILES% = $233 + Const WM_ENABLE% = $A + Const WM_ENDSESSION% = $16 + Const WM_ENTERIDLE% = $121 + Const WM_ENTERMENULOOP% = $211 + Const WM_ENTERSIZEMOVE% = $231 + Const WM_ERASEBKGND% = $14 + Const WM_EXITMENULOOP% = $212 + Const WM_EXITSIZEMOVE% = $232 + Const WM_FONTCHANGE% = $1D + Const WM_GETDLGCODE% = $87 + Const WM_GETFONT% = $31 + Const WM_GETHOTKEY% = $33 + Const WM_GETICON% = $7F + Const WM_GETMINMAXINFO% = $24 + Const WM_GETOBJECT% = $3D + Const WM_GETTEXT% = $D + Const WM_GETTEXTLENGTH% = $E + Const WM_HANDHELDFIRST% = $358 + Const WM_HANDHELDLAST% = $35F + Const WM_HELP% = $53 + Const WM_HOTKEY% = $312 + Const WM_HSCROLL% = $114 + Const WM_HSCROLLCLIPBOARD% = $30E + Const WM_ICONERASEBKGND% = $27 + Const WM_IME_CHAR% = $286 + Const WM_IME_COMPOSITION% = $10F + Const WM_IME_COMPOSITIONFULL% = $284 + Const WM_IME_CONTROL% = $283 + Const WM_IME_ENDCOMPOSITION% = $10E + Const WM_IME_KEYDOWN% = $290 + Const WM_IME_KEYLAST% = $10F + Const WM_IME_KEYUP% = $291 + Const WM_IME_NOTIFY% = $282 + Const WM_IME_REQUEST% = $288 + Const WM_IME_SELECT% = $285 + Const WM_IME_SETCONTEXT% = $281 + Const WM_IME_STARTCOMPOSITION% = $10D + Const WM_INITDIALOG% = $110 + Const WM_INITMENU% = $116 + Const WM_INITMENUPOPUP% = $117 + Const WM_INPUTLANGCHANGE% = $51 + Const WM_INPUTLANGCHANGEREQUEST% = $50 + Const WM_KEYDOWN% = $100 + Const WM_KEYFIRST% = $100 + Const WM_KEYLAST% = $108 + Const WM_KEYUP% = $101 + Const WM_KILLFOCUS% = $8 + Const WM_LBUTTONDBLCLK% = $203 + Const WM_LBUTTONDOWN% = $201 + Const WM_LBUTTONUP% = $202 + Const WM_MBUTTONDBLCLK% = $209 + Const WM_MBUTTONDOWN% = $207 + Const WM_MBUTTONUP% = $208 + Const WM_MDIACTIVATE% = $222 + Const WM_MDICASCADE% = $227 + Const WM_MDICREATE% = $220 + Const WM_MDIDESTROY% = $221 + Const WM_MDIGETACTIVE% = $229 + Const WM_MDIICONARRANGE% = $228 + Const WM_MDIMAXIMIZE% = $225 + Const WM_MDINEXT% = $224 + Const WM_MDIREFRESHMENU% = $234 + Const WM_MDIRESTORE% = $223 + Const WM_MDISETMENU% = $230 + Const WM_MDITILE% = $226 + Const WM_MEASUREITEM% = $2C + Const WM_MENUCHAR% = $120 + Const WM_MENUCOMMAND% = $126 + Const WM_MENUDRAG% = $123 + Const WM_MENUGETOBJECT% = $124 + Const WM_MENURBUTTONUP% = $122 + Const WM_MENUSELECT% = $11F + Const WM_MOUSEACTIVATE% = $21 + Const WM_MOUSEFIRST% = $200 + Const WM_MOUSEHOVER% = $2A1 + Const WM_MOUSELAST% = $20D + Const WM_MOUSELEAVE% = $2A3 + Const WM_MOUSEMOVE% = $200 + Const WM_MOUSEWHEEL% = $20A + Const WM_MOUSEHWHEEL% = $20E + Const WM_MOVE% = $3 + Const WM_MOVING% = $216 + Const WM_NCACTIVATE% = $86 + Const WM_NCCALCSIZE% = $83 + Const WM_NCCREATE% = $81 + Const WM_NCDESTROY% = $82 + Const WM_NCHITTEST% = $84 + Const WM_NCLBUTTONDBLCLK% = $A3 + Const WM_NCLBUTTONDOWN% = $A1 + Const WM_NCLBUTTONUP% = $A2 + Const WM_NCMBUTTONDBLCLK% = $A9 + Const WM_NCMBUTTONDOWN% = $A7 + Const WM_NCMBUTTONUP% = $A8 + Const WM_NCMOUSEMOVE% = $A0 + Const WM_NCPAINT% = $85 + Const WM_NCRBUTTONDBLCLK% = $A6 + Const WM_NCRBUTTONDOWN% = $A4 + Const WM_NCRBUTTONUP% = $A5 + Const WM_NEXTDLGCTL% = $28 + Const WM_NEXTMENU% = $213 + Const WM_NOTIFY% = $4E + Const WM_NOTIFYFORMAT% = $55 + Const WM_NULL% = $0 + Const WM_PAINT% = $F + Const WM_PAINTCLIPBOARD% = $309 + Const WM_PAINTICON% = $26 + Const WM_PALETTECHANGED% = $311 + Const WM_PALETTEISCHANGING% = $310 + Const WM_PARENTNOTIFY% = $210 + Const WM_PASTE% = $302 + Const WM_PENWINFIRST% = $380 + Const WM_PENWINLAST% = $38F + Const WM_POWER% = $48 + Const WM_POWERBROADCAST% = $218 + Const WM_PRINT% = $317 + Const WM_PRINTCLIENT% = $318 + Const WM_QUERYDRAGICON% = $37 + Const WM_QUERYENDSESSION% = $11 + Const WM_QUERYNEWPALETTE% = $30F + Const WM_QUERYOPEN% = $13 + Const WM_QUEUESYNC% = $23 + Const WM_QUIT% = $12 + Const WM_RBUTTONDBLCLK% = $206 + Const WM_RBUTTONDOWN% = $204 + Const WM_RBUTTONUP% = $205 + Const WM_RENDERALLFORMATS% = $306 + Const WM_RENDERFORMAT% = $305 + Const WM_SETCURSOR% = $20 + Const WM_SETFOCUS% = $7 + Const WM_SETFONT% = $30 + Const WM_SETHOTKEY% = $32 + Const WM_SETICON% = $80 + Const WM_SETREDRAW% = $B + Const WM_SETTEXT% = $C + Const WM_SETTINGCHANGE% = $1A + Const WM_SHOWWINDOW% = $18 + Const WM_SIZE% = $5 + Const WM_SIZECLIPBOARD% = $30B + Const WM_SIZING% = $214 + Const WM_SPOOLERSTATUS% = $2A + Const WM_STYLECHANGED% = $7D + Const WM_STYLECHANGING% = $7C + Const WM_SYNCPAINT% = $88 + Const WM_SYSCHAR% = $106 + Const WM_SYSCOLORCHANGE% = $15 + Const WM_SYSCOMMAND% = $112 + Const WM_SYSDEADCHAR% = $107 + Const WM_SYSKEYDOWN% = $104 + Const WM_SYSKEYUP% = $105 + Const WM_TCARD% = $52 + Const WM_THEMECHANGED% = $31A + Const WM_TIMECHANGE% = $1E + Const WM_TIMER% = $113 + Const WM_UNDO% = $304 + Const WM_UNINITMENUPOPUP% = $125 + Const WM_USER% = $400 + Const WM_USERCHANGED% = $54 + Const WM_VKEYTOITEM% = $2E + Const WM_VSCROLL% = $115 + Const WM_VSCROLLCLIPBOARD% = $30A + Const WM_WINDOWPOSCHANGED% = $47 + Const WM_WINDOWPOSCHANGING% = $46 + Const WM_WININICHANGE% = $1A + Const WM_XBUTTONDBLCLK% = $20D + Const WM_XBUTTONDOWN% = $20B + Const WM_XBUTTONUP% = $20C + + Function ReverseLookupMsg$( msg% ) + + Select msg + Case WM_ACTIVATE;Return "WM_ACTIVATE ($6)" + Case WM_ACTIVATEAPP;Return "WM_ACTIVATEAPP ($1C)" + Case WM_AFXFIRST;Return "WM_AFXFIRST ($360)" + Case WM_AFXLAST;Return "WM_AFXLAST ($37F)" + Case WM_APP;Return "WM_APP ($8000)" + Case WM_ASKCBFORMATNAME;Return "WM_ASKCBFORMATNAME ($30C)" + Case WM_CANCELJOURNAL;Return "WM_CANCELJOURNAL ($4B)" + Case WM_CANCELMODE;Return "WM_CANCELMODE ($1F)" + Case WM_CAPTURECHANGED;Return "WM_CAPTURECHANGED ($215)" + Case WM_CHANGECBCHAIN;Return "WM_CHANGECBCHAIN ($30D)" + Case WM_CHANGEUISTATE;Return "WM_CHANGEUISTATE ($127)" + Case WM_CHAR;Return "WM_CHAR ($102)" + Case WM_CHARTOITEM;Return "WM_CHARTOITEM ($2F)" + Case WM_CHILDACTIVATE;Return "WM_CHILDACTIVATE ($22)" + Case WM_CLEAR;Return "WM_CLEAR ($303)" + Case WM_CLOSE;Return "WM_CLOSE ($10)" + Case WM_COMMAND;Return "WM_COMMAND ($111)" + Case WM_COMPACTING;Return "WM_COMPACTING ($41)" + Case WM_COMPAREITEM;Return "WM_COMPAREITEM ($39)" + Case WM_CONTEXTMENU;Return "WM_CONTEXTMENU ($7B)" + Case WM_COPY;Return "WM_COPY ($301)" + Case WM_COPYDATA;Return "WM_COPYDATA ($4A)" + Case WM_CREATE;Return "WM_CREATE ($1)" + Case WM_CTLCOLORBTN;Return "WM_CTLCOLORBTN ($135)" + Case WM_CTLCOLORDLG;Return "WM_CTLCOLORDLG ($136)" + Case WM_CTLCOLOREDIT;Return "WM_CTLCOLOREDIT ($133)" + Case WM_CTLCOLORLISTBOX;Return "WM_CTLCOLORLISTBOX ($134)" + Case WM_CTLCOLORMSGBOX;Return "WM_CTLCOLORMSGBOX ($132)" + Case WM_CTLCOLORSCROLLBAR;Return "WM_CTLCOLORSCROLLBAR ($137)" + Case WM_CTLCOLORSTATIC;Return "WM_CTLCOLORSTATIC ($138)" + Case WM_CUT;Return "WM_CUT ($300)" + Case WM_DEADCHAR;Return "WM_DEADCHAR ($103)" + Case WM_DELETEITEM;Return "WM_DELETEITEM ($2D)" + Case WM_DESTROY;Return "WM_DESTROY ($2)" + Case WM_DESTROYCLIPBOARD;Return "WM_DESTROYCLIPBOARD ($307)" + Case WM_DEVICECHANGE;Return "WM_DEVICECHANGE ($219)" + Case WM_DEVMODECHANGE;Return "WM_DEVMODECHANGE ($1B)" + Case WM_DISPLAYCHANGE;Return "WM_DISPLAYCHANGE ($7E)" + Case WM_DRAWCLIPBOARD;Return "WM_DRAWCLIPBOARD ($308)" + Case WM_DRAWITEM;Return "WM_DRAWITEM ($2B)" + Case WM_DROPFILES;Return "WM_DROPFILES ($233)" + Case WM_ENABLE;Return "WM_ENABLE ($A)" + Case WM_ENDSESSION;Return "WM_ENDSESSION ($16)" + Case WM_ENTERIDLE;Return "WM_ENTERIDLE ($121)" + Case WM_ENTERMENULOOP;Return "WM_ENTERMENULOOP ($211)" + Case WM_ENTERSIZEMOVE;Return "WM_ENTERSIZEMOVE ($231)" + Case WM_ERASEBKGND;Return "WM_ERASEBKGND ($14)" + Case WM_EXITMENULOOP;Return "WM_EXITMENULOOP ($212)" + Case WM_EXITSIZEMOVE;Return "WM_EXITSIZEMOVE ($232)" + Case WM_FONTCHANGE;Return "WM_FONTCHANGE ($1D)" + Case WM_GETDLGCODE;Return "WM_GETDLGCODE ($87)" + Case WM_GETFONT;Return "WM_GETFONT ($31)" + Case WM_GETHOTKEY;Return "WM_GETHOTKEY ($33)" + Case WM_GETICON;Return "WM_GETICON ($7F)" + Case WM_GETMINMAXINFO;Return "WM_GETMINMAXINFO ($24)" + Case WM_GETOBJECT;Return "WM_GETOBJECT ($3D)" + Case WM_GETTEXT;Return "WM_GETTEXT ($D)" + Case WM_GETTEXTLENGTH;Return "WM_GETTEXTLENGTH ($E)" + Case WM_HANDHELDFIRST;Return "WM_HANDHELDFIRST ($358)" + Case WM_HANDHELDLAST;Return "WM_HANDHELDLAST ($35F)" + Case WM_HELP;Return "WM_HELP ($53)" + Case WM_HOTKEY;Return "WM_HOTKEY ($312)" + Case WM_HSCROLL;Return "WM_HSCROLL ($114)" + Case WM_HSCROLLCLIPBOARD;Return "WM_HSCROLLCLIPBOARD ($30E)" + Case WM_ICONERASEBKGND;Return "WM_ICONERASEBKGND ($27)" + Case WM_IME_CHAR;Return "WM_IME_CHAR ($286)" + Case WM_IME_COMPOSITION;Return "WM_IME_COMPOSITION ($10F)" + Case WM_IME_COMPOSITIONFULL;Return "WM_IME_COMPOSITIONFULL ($284)" + Case WM_IME_CONTROL;Return "WM_IME_CONTROL ($283)" + Case WM_IME_ENDCOMPOSITION;Return "WM_IME_ENDCOMPOSITION ($10E)" + Case WM_IME_KEYDOWN;Return "WM_IME_KEYDOWN ($290)" + Case WM_IME_KEYLAST;Return "WM_IME_KEYLAST ($10F)" + Case WM_IME_KEYUP;Return "WM_IME_KEYUP ($291)" + Case WM_IME_NOTIFY;Return "WM_IME_NOTIFY ($282)" + Case WM_IME_REQUEST;Return "WM_IME_REQUEST ($288)" + Case WM_IME_SELECT;Return "WM_IME_SELECT ($285)" + Case WM_IME_SETCONTEXT;Return "WM_IME_SETCONTEXT ($281)" + Case WM_IME_STARTCOMPOSITION;Return "WM_IME_STARTCOMPOSITION ($10D)" + Case WM_INITDIALOG;Return "WM_INITDIALOG ($110)" + Case WM_INITMENU;Return "WM_INITMENU ($116)" + Case WM_INITMENUPOPUP;Return "WM_INITMENUPOPUP ($117)" + Case WM_INPUTLANGCHANGE;Return "WM_INPUTLANGCHANGE ($51)" + Case WM_INPUTLANGCHANGEREQUEST;Return "WM_INPUTLANGCHANGEREQUEST ($50)" + Case WM_KEYDOWN;Return "WM_KEYDOWN ($100)" + Case WM_KEYFIRST;Return "WM_KEYFIRST ($100)" + Case WM_KEYLAST;Return "WM_KEYLAST ($108)" + Case WM_KEYUP;Return "WM_KEYUP ($101)" + Case WM_KILLFOCUS;Return "WM_KILLFOCUS ($8)" + Case WM_LBUTTONDBLCLK;Return "WM_LBUTTONDBLCLK ($203)" + Case WM_LBUTTONDOWN;Return "WM_LBUTTONDOWN ($201)" + Case WM_LBUTTONUP;Return "WM_LBUTTONUP ($202)" + Case WM_MBUTTONDBLCLK;Return "WM_MBUTTONDBLCLK ($209)" + Case WM_MBUTTONDOWN;Return "WM_MBUTTONDOWN ($207)" + Case WM_MBUTTONUP;Return "WM_MBUTTONUP ($208)" + Case WM_MDIACTIVATE;Return "WM_MDIACTIVATE ($222)" + Case WM_MDICASCADE;Return "WM_MDICASCADE ($227)" + Case WM_MDICREATE;Return "WM_MDICREATE ($220)" + Case WM_MDIDESTROY;Return "WM_MDIDESTROY ($221)" + Case WM_MDIGETACTIVE;Return "WM_MDIGETACTIVE ($229)" + Case WM_MDIICONARRANGE;Return "WM_MDIICONARRANGE ($228)" + Case WM_MDIMAXIMIZE;Return "WM_MDIMAXIMIZE ($225)" + Case WM_MDINEXT;Return "WM_MDINEXT ($224)" + Case WM_MDIREFRESHMENU;Return "WM_MDIREFRESHMENU ($234)" + Case WM_MDIRESTORE;Return "WM_MDIRESTORE ($223)" + Case WM_MDISETMENU;Return "WM_MDISETMENU ($230)" + Case WM_MDITILE;Return "WM_MDITILE ($226)" + Case WM_MEASUREITEM;Return "WM_MEASUREITEM ($2C)" + Case WM_MENUCHAR;Return "WM_MENUCHAR ($120)" + Case WM_MENUCOMMAND;Return "WM_MENUCOMMAND ($126)" + Case WM_MENUDRAG;Return "WM_MENUDRAG ($123)" + Case WM_MENUGETOBJECT;Return "WM_MENUGETOBJECT ($124)" + Case WM_MENURBUTTONUP;Return "WM_MENURBUTTONUP ($122)" + Case WM_MENUSELECT;Return "WM_MENUSELECT ($11F)" + Case WM_MOUSEACTIVATE;Return "WM_MOUSEACTIVATE ($21)" + Case WM_MOUSEFIRST;Return "WM_MOUSEFIRST ($200)" + Case WM_MOUSEHOVER;Return "WM_MOUSEHOVER ($2A1)" + Case WM_MOUSELAST;Return "WM_MOUSELAST ($20D)" + Case WM_MOUSELEAVE;Return "WM_MOUSELEAVE ($2A3)" + Case WM_MOUSEMOVE;Return "WM_MOUSEMOVE ($200)" + Case WM_MOUSEWHEEL;Return "WM_MOUSEWHEEL ($20A)" + Case WM_MOUSEHWHEEL;Return "WM_MOUSEHWHEEL ($20E)" + Case WM_MOVE;Return "WM_MOVE ($3)" + Case WM_MOVING;Return "WM_MOVING ($216)" + Case WM_NCACTIVATE;Return "WM_NCACTIVATE ($86)" + Case WM_NCCALCSIZE;Return "WM_NCCALCSIZE ($83)" + Case WM_NCCREATE;Return "WM_NCCREATE ($81)" + Case WM_NCDESTROY;Return "WM_NCDESTROY ($82)" + Case WM_NCHITTEST;Return "WM_NCHITTEST ($84)" + Case WM_NCLBUTTONDBLCLK;Return "WM_NCLBUTTONDBLCLK ($A3)" + Case WM_NCLBUTTONDOWN;Return "WM_NCLBUTTONDOWN ($A1)" + Case WM_NCLBUTTONUP;Return "WM_NCLBUTTONUP ($A2)" + Case WM_NCMBUTTONDBLCLK;Return "WM_NCMBUTTONDBLCLK ($A9)" + Case WM_NCMBUTTONDOWN;Return "WM_NCMBUTTONDOWN ($A7)" + Case WM_NCMBUTTONUP;Return "WM_NCMBUTTONUP ($A8)" + Case WM_NCMOUSEMOVE;Return "WM_NCMOUSEMOVE ($A0)" + Case WM_NCPAINT;Return "WM_NCPAINT ($85)" + Case WM_NCRBUTTONDBLCLK;Return "WM_NCRBUTTONDBLCLK ($A6)" + Case WM_NCRBUTTONDOWN;Return "WM_NCRBUTTONDOWN ($A4)" + Case WM_NCRBUTTONUP;Return "WM_NCRBUTTONUP ($A5)" + Case WM_NEXTDLGCTL;Return "WM_NEXTDLGCTL ($28)" + Case WM_NEXTMENU;Return "WM_NEXTMENU ($213)" + Case WM_NOTIFY;Return "WM_NOTIFY ($4E)" + Case WM_NOTIFYFORMAT;Return "WM_NOTIFYFORMAT ($55)" + Case WM_NULL;Return "WM_NULL ($0)" + Case WM_PAINT;Return "WM_PAINT ($F)" + Case WM_PAINTCLIPBOARD;Return "WM_PAINTCLIPBOARD ($309)" + Case WM_PAINTICON;Return "WM_PAINTICON ($26)" + Case WM_PALETTECHANGED;Return "WM_PALETTECHANGED ($311)" + Case WM_PALETTEISCHANGING;Return "WM_PALETTEISCHANGING ($310)" + Case WM_PARENTNOTIFY;Return "WM_PARENTNOTIFY ($210)" + Case WM_PASTE;Return "WM_PASTE ($302)" + Case WM_PENWINFIRST;Return "WM_PENWINFIRST ($380)" + Case WM_PENWINLAST;Return "WM_PENWINLAST ($38F)" + Case WM_POWER;Return "WM_POWER ($48)" + Case WM_POWERBROADCAST;Return "WM_POWERBROADCAST ($218)" + Case WM_PRINT;Return "WM_PRINT ($317)" + Case WM_PRINTCLIENT;Return "WM_PRINTCLIENT ($318)" + Case WM_QUERYDRAGICON;Return "WM_QUERYDRAGICON ($37)" + Case WM_QUERYENDSESSION;Return "WM_QUERYENDSESSION ($11)" + Case WM_QUERYNEWPALETTE;Return "WM_QUERYNEWPALETTE ($30F)" + Case WM_QUERYOPEN;Return "WM_QUERYOPEN ($13)" + Case WM_QUEUESYNC;Return "WM_QUEUESYNC ($23)" + Case WM_QUIT;Return "WM_QUIT ($12)" + Case WM_RBUTTONDBLCLK;Return "WM_RBUTTONDBLCLK ($206)" + Case WM_RBUTTONDOWN;Return "WM_RBUTTONDOWN ($204)" + Case WM_RBUTTONUP;Return "WM_RBUTTONUP ($205)" + Case WM_RENDERALLFORMATS;Return "WM_RENDERALLFORMATS ($306)" + Case WM_RENDERFORMAT;Return "WM_RENDERFORMAT ($305)" + Case WM_SETCURSOR;Return "WM_SETCURSOR ($20)" + Case WM_SETFOCUS;Return "WM_SETFOCUS ($7)" + Case WM_SETFONT;Return "WM_SETFONT ($30)" + Case WM_SETHOTKEY;Return "WM_SETHOTKEY ($32)" + Case WM_SETICON;Return "WM_SETICON ($80)" + Case WM_SETREDRAW;Return "WM_SETREDRAW ($B)" + Case WM_SETTEXT;Return "WM_SETTEXT ($C)" + Case WM_SETTINGCHANGE;Return "WM_SETTINGCHANGE ($1A)" + Case WM_SHOWWINDOW;Return "WM_SHOWWINDOW ($18)" + Case WM_SIZE;Return "WM_SIZE ($5)" + Case WM_SIZECLIPBOARD;Return "WM_SIZECLIPBOARD ($30B)" + Case WM_SIZING;Return "WM_SIZING ($214)" + Case WM_SPOOLERSTATUS;Return "WM_SPOOLERSTATUS ($2A)" + Case WM_STYLECHANGED;Return "WM_STYLECHANGED ($7D)" + Case WM_STYLECHANGING;Return "WM_STYLECHANGING ($7C)" + Case WM_SYNCPAINT;Return "WM_SYNCPAINT ($88)" + Case WM_SYSCHAR;Return "WM_SYSCHAR ($106)" + Case WM_SYSCOLORCHANGE;Return "WM_SYSCOLORCHANGE ($15)" + Case WM_SYSCOMMAND;Return "WM_SYSCOMMAND ($112)" + Case WM_SYSDEADCHAR;Return "WM_SYSDEADCHAR ($107)" + Case WM_SYSKEYDOWN;Return "WM_SYSKEYDOWN ($104)" + Case WM_SYSKEYUP;Return "WM_SYSKEYUP ($105)" + Case WM_TCARD;Return "WM_TCARD ($52)" + Case WM_THEMECHANGED;Return "WM_THEMECHANGED ($31A)" + Case WM_TIMECHANGE;Return "WM_TIMECHANGE ($1E)" + Case WM_TIMER;Return "WM_TIMER ($113)" + Case WM_UNDO;Return "WM_UNDO ($304)" + Case WM_UNINITMENUPOPUP;Return "WM_UNINITMENUPOPUP ($125)" + Case WM_USER;Return "WM_USER ($400)" + Case WM_USERCHANGED;Return "WM_USERCHANGED ($54)" + Case WM_VKEYTOITEM;Return "WM_VKEYTOITEM ($2E)" + Case WM_VSCROLL;Return "WM_VSCROLL ($115)" + Case WM_VSCROLLCLIPBOARD;Return "WM_VSCROLLCLIPBOARD ($30A)" + Case WM_WINDOWPOSCHANGED;Return "WM_WINDOWPOSCHANGED ($47)" + Case WM_WINDOWPOSCHANGING;Return "WM_WINDOWPOSCHANGING ($46)" + Case WM_WININICHANGE;Return "WM_WININICHANGE ($1A)" + Case WM_XBUTTONDBLCLK;Return "WM_XBUTTONDBLCLK ($20D)" + Case WM_XBUTTONDOWN;Return "WM_XBUTTONDOWN ($20B)" + Case WM_XBUTTONUP;Return "WM_XBUTTONUP ($20C)" + Default;Return "Unknown Message (" + msg + ")" + EndSelect + + EndFunction + +EndType +? diff --git a/mod/maxgui.mod/xpmanifest.mod/xpmanifest.bmx b/mod/maxgui.mod/xpmanifest.mod/xpmanifest.bmx new file mode 100644 index 0000000..8ee7712 --- /dev/null +++ b/mod/maxgui.mod/xpmanifest.mod/xpmanifest.bmx @@ -0,0 +1,18 @@ +Rem +bbdoc: MaxGUI Manifest File for some XP common control style +End Rem +Module MaxGUI.XPManifest + +ModuleInfo "Version: 0.01" +ModuleInfo "Author: Simon Armstrong" +ModuleInfo "License: zlib/libpng" + +ModuleInfo "History: 0.01 Release" + +Strict + +?Win32 + +Import "xpmanifest.o" + +? diff --git a/mod/maxgui.mod/xpmanifest.mod/xpmanifest.o b/mod/maxgui.mod/xpmanifest.mod/xpmanifest.o new file mode 100644 index 0000000000000000000000000000000000000000..02d8c498ed70888b3f6809d86a8ae4ac59225424 GIT binary patch literal 708 zcmah{O-}+b5G_h#Bq8z0akEDg7EmBa_>f?XM!lhOE!_f*+ji3_;NJW(p8X9bUi?{3 zSs+V7Vv}}e-b`lROXo3{Bkp`15t4d&5*RRSji%2Wa~*U)(YoX6t_k@@LrT9tH_ke= zgfHF?7iDo*Up;`I<_WpO+!*iKrZ>8z(|?zdx8w$dR$adqRDF*trbD4-UH^G>TWpfePG gz7>oT52)CosnW{!D^a1_5qD1ZHq&j@F~Joge`d|R-T(jq literal 0 HcmV?d00001 diff --git a/mod/pub.mod/directx.mod/d3d.bmx b/mod/pub.mod/directx.mod/d3d.bmx new file mode 100644 index 0000000..95839df --- /dev/null +++ b/mod/pub.mod/directx.mod/d3d.bmx @@ -0,0 +1,628 @@ + +Strict + +Const D3DADAPTER_DEFAULT=0 + +Const D3DENUMRET_CANCEL=0 +Const D3DENUMRET_OK=1 + +Const D3DSTATUS=$08760000 +Const D3DHRESULT=$88760000 + +Const D3DERR_WRONGTEXTUREFORMAT=D3DHRESULT|2072 +Const D3DERR_UNSUPPORTEDCOLOROPERATION=D3DHRESULT|2073 +Const D3DERR_UNSUPPORTEDCOLORARG=D3DHRESULT|2074 +Const D3DERR_UNSUPPORTEDALPHAOPERATION=D3DHRESULT|2075 +Const D3DERR_UNSUPPORTEDALPHAARG=D3DHRESULT|2076 +Const D3DERR_TOOMANYOPERATIONS=D3DHRESULT|2077 +Const D3DERR_CONFLICTINGTEXTUREFILTER=D3DHRESULT|2078 +Const D3DERR_UNSUPPORTEDFACTORVALUE=D3DHRESULT|2079 +Const D3DERR_CONFLICTINGRENDERSTATE=D3DHRESULT|2081 +Const D3DERR_UNSUPPORTEDTEXTUREFILTER=D3DHRESULT|2082 +Const D3DERR_CONFLICTINGTEXTUREPALETTE=D3DHRESULT|2086 +Const D3DERR_DRIVERINTERNALERROR=D3DHRESULT|2087 +Const D3DERR_NOTFOUND=D3DHRESULT|2150 +Const D3DERR_MOREDATA=D3DHRESULT|2151 +Const D3DERR_DEVICELOST=D3DHRESULT|2152 +Const D3DERR_DEVICENOTRESET=D3DHRESULT|2153 +Const D3DERR_NOTAVAILABLE=D3DHRESULT|2154 +Const D3DERR_OUTOFVIDEOMEMORY=D3DHRESULT|380 +Const D3DERR_INVALIDDEVICE=D3DHRESULT|2155 +Const D3DERR_INVALIDCALL=D3DHRESULT|2156 +Const D3DERR_DRIVERINVALIDCALL=D3DHRESULT|2157 +Const D3DERR_WASSTILLDRAWING=D3DHRESULT|540 + +Const D3D_OK=0 +Const D3DOK_NOAUTOGEN=D3DSTATUS|2159 + +Const D3DLOCK_READONLY=$10 +Const D3DLOCK_DISCARD=$2000 +Const D3DLOCK_NOOVERWRITE=$1000 +Const D3DLOCK_NOSYSLOCK=$800 +Const D3DLOCK_DONOTWAIT=$4000 +Const D3DLOCK_NO_DIRTY_UPDATE=$8000 + +Const D3DUSAGE_RENDERTARGET=$1 +Const D3DUSAGE_DEPTHSTENCIL=$2 +Const D3DUSAGE_DYNAMIC=$200 +Const D3DUSAGE_AUTOGENMIPMAP=$400 +Const D3DUSAGE_DMAP=$4000 +Const D3DUSAGE_QUERY_LEGACYBUMPMAP=$8000 +Const D3DUSAGE_QUERY_SRGBREAD=$10000 +Const D3DUSAGE_QUERY_FILTER=$20000 +Const D3DUSAGE_QUERY_SRGBWRITE=$40000 +Const D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING=$80000 +Const D3DUSAGE_QUERY_VERTEXTEXTURE=$100000 +Const D3DUSAGE_WRITEONLY=$8 +Const D3DUSAGE_SOFTWAREPROCESSING=$10 +Const D3DUSAGE_DONOTCLIP=$20 +Const D3DUSAGE_POINTS=$40 +Const D3DUSAGE_RTPATCHES=$80 +Const D3DUSAGE_NPATCHES=$100 + +'D3DTEXTUREADDRESS +Const D3DTADDRESS_WRAP=1 +Const D3DTADDRESS_MIRROR=2 +Const D3DTADDRESS_CLAMP=3 +Const D3DTADDRESS_BORDER=4 +Const D3DTADDRESS_MIRRORONCE=5 + +'D3DMATERIALCOLORSOURCE +Const D3DMCS_MATERIAL=0 +Const D3DMCS_COLOR1=1 +Const D3DMCS_COLOR2=2 + +'D3DBLEND +Const D3DBLEND_ZERO=1 +Const D3DBLEND_ONE=2 +Const D3DBLEND_SRCCOLOR=3 +Const D3DBLEND_INVSRCCOLOR=4 +Const D3DBLEND_SRCALPHA=5 +Const D3DBLEND_INVSRCALPHA=6 +Const D3DBLEND_DESTALPHA=7 +Const D3DBLEND_INVDESTALPHA=8 +Const D3DBLEND_DESTCOLOR=9 +Const D3DBLEND_INVDESTCOLOR=10 +Const D3DBLEND_SRCALPHASAT=11 +Const D3DBLEND_BOTHSRCALPHA=12 +Const D3DBLEND_BOTHINVSRCALPHA=13 +Const D3DBLEND_BLENDFACTOR=14 +Const D3DBLEND_INVBLENDFACTOR=15 + +'D3DTEXTUREOP +Const D3DTOP_DISABLE=1 +Const D3DTOP_SELECTARG1=2 +Const D3DTOP_SELECTARG2=3 +Const D3DTOP_MODULATE=4 +Const D3DTOP_MODULATE2X=5 +Const D3DTOP_MODULATE4X=6 +Const D3DTOP_ADD=7 +Const D3DTOP_ADDSIGNED=8 +Const D3DTOP_ADDSIGNED2X=9 +Const D3DTOP_SUBTRACT=10 +Const D3DTOP_ADDSMOOTH=11 +Const D3DTOP_BLENDDIFFUSEALPHA=12 +Const D3DTOP_BLENDTEXTUREALPHA=13 +Const D3DTOP_BLENDFACTORALPHA=14 +Const D3DTOP_BLENDTEXTUREALPHAPM=15 +Const D3DTOP_BLENDCURRENTALPHA=16 +Const D3DTOP_PREMODULATE=17 +Const D3DTOP_MODULATEALPHA_ADDCOLOR=18 +Const D3DTOP_MODULATECOLOR_ADDALPHA=19 +Const D3DTOP_MODULATEINVALPHA_ADDCOLOR=20 +Const D3DTOP_MODULATEINVCOLOR_ADDALPHA=21 +Const D3DTOP_BUMPENVMAP=22 +Const D3DTOP_BUMPENVMAPLUMINANCE=23 +Const D3DTOP_DOTPRODUCT3=24 +Const D3DTOP_MULTIPLYADD=25 +Const D3DTOP_LERP=26 + +Const D3DTA_SELECTMASK=$f +Const D3DTA_DIFFUSE=$0 +Const D3DTA_CURRENT=$1 +Const D3DTA_TEXTURE=$2 +Const D3DTA_TFACTOR=$3 +Const D3DTA_SPECULAR=$4 +Const D3DTA_TEMP=$5 +Const D3DTA_CONSTANT=$6 +Const D3DTA_COMPLEMENT=$10 +Const D3DTA_ALPHAREPLICATE=$20 + +'D3DCULL +Const D3DCULL_NONE=1 +Const D3DCULL_CW=2 +Const D3DCULL_CCW=3 + +'D3DCMPFUNC +Const D3DCMP_NEVER=1 +Const D3DCMP_LESS=2 +Const D3DCMP_EQUAL=3 +Const D3DCMP_LESSEQUAL=4 +Const D3DCMP_GREATER=5 +Const D3DCMP_NOTEQUAL=6 +Const D3DCMP_GREATEREQUAL=7 +Const D3DCMP_ALWAYS=8 + +'D3DSTENCILOP +Const D3DSTENCILOP_KEEP=1 +Const D3DSTENCILOP_ZERO=2 +Const D3DSTENCILOP_REPLACE=3 +Const D3DSTENCILOP_INCRSAT=4 +Const D3DSTENCILOP_DECRSAT=5 +Const D3DSTENCILOP_INVERT=6 +Const D3DSTENCILOP_INCR=7 +Const D3DSTENCILOP_DECR=8 + +'D3DFORMAT +Const D3DFMT_UNKNOWN=0 +Const D3DFMT_R8G8B8=20 +Const D3DFMT_A8R8G8B8=21 +Const D3DFMT_X8R8G8B8=22 +Const D3DFMT_R5G6B5=23 +Const D3DFMT_X1R5G5B5=24 +Const D3DFMT_A1R5G5B5=25 +Const D3DFMT_A4R4G4B4=26 +Const D3DFMT_R3G3B2=27 +Const D3DFMT_A8=28 +Const D3DFMT_A8R3G3B2=29 +Const D3DFMT_X4R4G4B4=30 +Const D3DFMT_A2B10G10R10=31 +Const D3DFMT_A8B8G8R8=32 +Const D3DFMT_X8B8G8R8=33 +Const D3DFMT_G16R16=34 +Const D3DFMT_A2R10G10B10=35 +Const D3DFMT_A16B16G16R16=36 +Const D3DFMT_D16_LOCKABLE=70 +Const D3DFMT_D32=71 +Const D3DFMT_D15S1=73 +Const D3DFMT_D24S8=75 +Const D3DFMT_D24X8=77 +Const D3DFMT_D24X4S4=79 +Const D3DFMT_D16=80 +Const D3DFMT_D32F_LOCKABLE=82 +Const D3DFMT_D24FS8=83 +Const D3DFMT_VERTEXDATA=100 +Const D3DFMT_INDEX16=101 +Const D3DFMT_INDEX32=102 + +'D3DDEVTYPE +Const D3DDEVTYPE_HAL=1 +Const D3DDEVTYPE_REF=2 +Const D3DDEVTYPE_SW=3 + +'D3DRESOURCETYPE +Const D3DRTYPE_SURFACE=1 +Const D3DRTYPE_VOLUME=2 +Const D3DRTYPE_TEXTURE=3 +Const D3DRTYPE_VOLUMETEXTURE=4 +Const D3DRTYPE_CUBETEXTURE=5 +Const D3DRTYPE_VERTEXBUFFER=6 +Const D3DRTYPE_INDEXBUFFER=7 + +'D3DMULTISAMPLE_TYPE +Const D3DMULTISAMPLE_NONE=0 +Const D3DMULTISAMPLE_NONMASKABLE=1 +Const D3DMULTISAMPLE_2_SAMPLES=2 +Const D3DMULTISAMPLE_3_SAMPLES=3 +Const D3DMULTISAMPLE_4_SAMPLES=4 +Const D3DMULTISAMPLE_5_SAMPLES=5 +Const D3DMULTISAMPLE_6_SAMPLES=6 +Const D3DMULTISAMPLE_7_SAMPLES=7 +Const D3DMULTISAMPLE_8_SAMPLES=8 +Const D3DMULTISAMPLE_9_SAMPLES=9 +Const D3DMULTISAMPLE_10_SAMPLES=10 +Const D3DMULTISAMPLE_11_SAMPLES=11 +Const D3DMULTISAMPLE_12_SAMPLES=12 +Const D3DMULTISAMPLE_13_SAMPLES=13 +Const D3DMULTISAMPLE_14_SAMPLES=14 +Const D3DMULTISAMPLE_15_SAMPLES=15 +Const D3DMULTISAMPLE_16_SAMPLES=16 + +'D3DSWAPEFFECT +Const D3DSWAPEFFECT_DISCARD=1 +Const D3DSWAPEFFECT_FLIP=2 +Const D3DSWAPEFFECT_COPY=3 + +'D3DPRESENT +Const D3DPRESENT_INTERVAL_DEFAULT=0 +Const D3DPRESENT_INTERVAL_ONE=1 +Const D3DPRESENT_INTERVAL_TWO=2 +Const D3DPRESENT_INTERVAL_THREE=4 +Const D3DPRESENT_INTERVAL_FOUR=8 +Const D3DPRESENT_INTERVAL_IMMEDIATE=$80000000 + +'D3DPOOL +Const D3DPOOL_DEFAULT=0 +Const D3DPOOL_MANAGED=1 +Const D3DPOOL_SYSTEMMEM=2 +Const D3DPOOL_SCRATCH=3 + +'D3DBACKBUFFER_TYPE +Const D3DBACKBUFFER_TYPE_MONO=0 +Const D3DBACKBUFFER_TYPE_LEFT=1 +Const D3DBACKBUFFER_TYPE_RIGHT=2 + +'D3DTEXTUREFILTERTYPE +Const D3DTEXF_NONE=0 +Const D3DTEXF_POINT=1 +Const D3DTEXF_LINEAR=2 +Const D3DTEXF_ANISOTROPIC=3 +Const D3DTEXF_PYRAMIDALQUAD=6 +Const D3DTEXF_GAUSSIANQUAD=7 + +'D3DTRANSFORMSTATETYPE +Const D3DTS_VIEW=2 +Const D3DTS_PROJECTION=3 +Const D3DTS_TEXTURE0=16 +Const D3DTS_TEXTURE1=17 +Const D3DTS_TEXTURE2=18 +Const D3DTS_TEXTURE3=19 +Const D3DTS_TEXTURE4=20 +Const D3DTS_TEXTURE5=21 +Const D3DTS_TEXTURE6=22 +Const D3DTS_TEXTURE7=23 +Const D3DTS_WORLD=256 +Const D3DTS_WORLD1=257 +Const D3DTS_WORLD2=258 +Const D3DTS_WORLD3=259 +'D3DLIGHTTYPE +Const D3DLIGHT_POINT=1 +Const D3DLIGHT_SPOT=2 +Const D3DLIGHT_DIRECTIONAL=3 + +'D3DRENDERSTATETYPE +Const D3DRS_TEXTUREPERSPECTIVE=4 'dx7 only +Const D3DRS_ZENABLE=7 +Const D3DRS_FILLMODE=8 +Const D3DRS_SHADEMODE=9 +Const D3DRS_ZWRITEENABLE=14 +Const D3DRS_ALPHATESTENABLE=15 +Const D3DRS_LASTPIXEL=16 +Const D3DRS_SRCBLEND=19 +Const D3DRS_DESTBLEND=20 +Const D3DRS_CULLMODE=22 +Const D3DRS_ZFUNC=23 +Const D3DRS_ALPHAREF=24 +Const D3DRS_ALPHAFUNC=25 +Const D3DRS_DITHERENABLE=26 +Const D3DRS_ALPHABLENDENABLE=27 +Const D3DRS_FOGENABLE=28 +Const D3DRS_SPECULARENABLE=29 +Const D3DRS_FOGCOLOR=34 +Const D3DRS_FOGTABLEMODE=35 +Const D3DRS_FOGSTART=36 +Const D3DRS_FOGEND=37 +Const D3DRS_FOGDENSITY=38 +Const D3DRS_RANGEFOGENABLE=48 +Const D3DRS_STENCILENABLE=52 +Const D3DRS_STENCILFAIL=53 +Const D3DRS_STENCILZFAIL=54 +Const D3DRS_STENCILPASS=55 +Const D3DRS_STENCILFUNC=56 +Const D3DRS_STENCILREF=57 +Const D3DRS_STENCILMASK=58 +Const D3DRS_STENCILWRITEMASK=59 +Const D3DRS_TEXTUREFACTOR=60 +Const D3DRS_WRAP0=128 +Const D3DRS_WRAP1=129 +Const D3DRS_WRAP2=130 +Const D3DRS_WRAP3=131 +Const D3DRS_WRAP4=132 +Const D3DRS_WRAP5=133 +Const D3DRS_WRAP6=134 +Const D3DRS_WRAP7=135 +Const D3DRS_CLIPPING=136 +Const D3DRS_LIGHTING=137 +Const D3DRS_AMBIENT=139 +Const D3DRS_FOGVERTEXMODE=140 +Const D3DRS_COLORVERTEX=141 +Const D3DRS_LOCALVIEWER=142 +Const D3DRS_NORMALIZENORMALS=143 +Const D3DRS_DIFFUSEMATERIALSOURCE=145 +Const D3DRS_SPECULARMATERIALSOURCE=146 +Const D3DRS_AMBIENTMATERIALSOURCE=147 +Const D3DRS_EMISSIVEMATERIALSOURCE=148 +Const D3DRS_VERTEXBLEND=151 +Const D3DRS_CLIPPLANEENABLE=152 +Const D3DRS_POINTSIZE=154 +Const D3DRS_POINTSIZE_MIN=155 +Const D3DRS_POINTSPRITEENABLE=156 +Const D3DRS_POINTSCALEENABLE=157 +Const D3DRS_POINTSCALE_A=158 +Const D3DRS_POINTSCALE_B=159 +Const D3DRS_POINTSCALE_C=160 +Const D3DRS_MULTISAMPLEANTIALIAS=161 +Const D3DRS_MULTISAMPLEMASK=162 +Const D3DRS_PATCHEDGESTYLE=163 +Const D3DRS_DEBUGMONITORTOKEN=165 +Const D3DRS_POINTSIZE_MAX=166 +Const D3DRS_INDEXEDVERTEXBLENDENABLE=167 +Const D3DRS_COLORWRITEENABLE=168 +Const D3DRS_TWEENFACTOR=170 +Const D3DRS_BLENDOP=171 +Const D3DRS_POSITIONDEGREE=172 +Const D3DRS_NORMALDEGREE=173 +Const D3DRS_SCISSORTESTENABLE=174 +Const D3DRS_SLOPESCALEDEPTHBIAS=175 +Const D3DRS_ANTIALIASEDLINEENABLE=176 +Const D3DRS_MINTESSELLATIONLEVEL=178 +Const D3DRS_MAXTESSELLATIONLEVEL=179 +Const D3DRS_ADAPTIVETESS_X=180 +Const D3DRS_ADAPTIVETESS_Y=181 +Const D3DRS_ADAPTIVETESS_Z=182 +Const D3DRS_ADAPTIVETESS_W=183 +Const D3DRS_ENABLEADAPTIVETESSELLATION=184 +Const D3DRS_TWOSIDEDSTENCILMODE=185 +Const D3DRS_CCW_STENCILFAIL=186 +Const D3DRS_CCW_STENCILZFAIL=187 +Const D3DRS_CCW_STENCILPASS=188 +Const D3DRS_CCW_STENCILFUNC=189 +Const D3DRS_COLORWRITEENABLE1=190 +Const D3DRS_COLORWRITEENABLE2=191 +Const D3DRS_COLORWRITEENABLE3=192 +Const D3DRS_BLENDFACTOR=193 +Const D3DRS_SRGBWRITEENABLE=194 +Const D3DRS_DEPTHBIAS=195 +Const D3DRS_WRAP8=198 +Const D3DRS_WRAP9=199 +Const D3DRS_WRAP10=200 +Const D3DRS_WRAP11=201 +Const D3DRS_WRAP12=202 +Const D3DRS_WRAP13=203 +Const D3DRS_WRAP14=204 +Const D3DRS_WRAP15=205 +Const D3DRS_SEPARATEALPHABLENDENABLE=206 +Const D3DRS_SRCBLENDALPHA=207 +Const D3DRS_DESTBLENDALPHA=208 +Const D3DRS_BLENDOPALPHA=209 + +'D3DTEXTURESTAGESTATETYPE +Const D3DTSS_COLOROP=1 +Const D3DTSS_COLORARG1=2 +Const D3DTSS_COLORARG2=3 +Const D3DTSS_ALPHAOP=4 +Const D3DTSS_ALPHAARG1=5 +Const D3DTSS_ALPHAARG2=6 +Const D3DTSS_BUMPENVMAT00=7 +Const D3DTSS_BUMPENVMAT01=8 +Const D3DTSS_BUMPENVMAT10=9 +Const D3DTSS_BUMPENVMAT11=10 +Const D3DTSS_TEXCOORDINDEX=11 +Const D3DTSS_ADDRESS=12 'dx7 only +Const D3DTSS_MAGFILTER=16 'dx7 only +Const D3DTSS_MINFILTER=17 'dx7 only +Const D3DTSS_MIPFILTER=18 'dx7 only +Const D3DTSS_BUMPENVLSCALE=22 +Const D3DTSS_BUMPENVLOFFSET=23 +Const D3DTSS_TEXTURETRANSFORMFLAGS=24 +Const D3DTSS_COLORARG0=26 +Const D3DTSS_ALPHAARG0=27 +Const D3DTSS_RESULTARG=28 +Const D3DTSS_CONSTANT=32 + +'D3DSAMPLERSTATETYPE +Const D3DSAMP_ADDRESSU=1 +Const D3DSAMP_ADDRESSV=2 +Const D3DSAMP_ADDRESSW=3 +Const D3DSAMP_BORDERCOLOR=4 +Const D3DSAMP_MAGFILTER=5 +Const D3DSAMP_MINFILTER=6 +Const D3DSAMP_MIPFILTER=7 +Const D3DSAMP_MIPMAPLODBIAS=8 +Const D3DSAMP_MAXMIPLEVEL=9 +Const D3DSAMP_MAXANISOTROPY=10 +Const D3DSAMP_SRGBTEXTURE=11 +Const D3DSAMP_ELEMENTINDEX=12 +Const D3DSAMP_DMAPOFFSET=13 + +'D3DSTATEBLOCKTYPE +Const D3DSBT_ALL=1 +Const D3DSBT_PIXELSTATE=2 +Const D3DSBT_VERTEXSTATE=3 + +'D3DPRIMITIVETYPE +Const D3DPT_POINTLIST=1 +Const D3DPT_LINELIST=2 +Const D3DPT_LINESTRIP=3 +Const D3DPT_TRIANGLELIST=4 +Const D3DPT_TRIANGLESTRIP=5 +Const D3DPT_TRIANGLEFAN=6 + +'D3DDECLUSAGE +Const D3DDECLUSAGE_POSITION=0 +Const D3DDECLUSAGE_BLENDWEIGHT=1 +Const D3DDECLUSAGE_BLENDINDICES=2 +Const D3DDECLUSAGE_NORMAL=3 +Const D3DDECLUSAGE_PSIZE=4 +Const D3DDECLUSAGE_TEXCOORD=5 +Const D3DDECLUSAGE_TANGENT=6 +Const D3DDECLUSAGE_BINORMAL=7 +Const D3DDECLUSAGE_TESSFACTOR=8 +Const D3DDECLUSAGE_POSITIONT=9 +Const D3DDECLUSAGE_COLOR=10 +Const D3DDECLUSAGE_FOG=11 +Const D3DDECLUSAGE_DEPTH=12 +Const D3DDECLUSAGE_SAMPLE=13 + +'D3DDECLMETHOD +Const D3DDECLMETHOD_DEFAULT=0 +Const D3DDECLMETHOD_PARTIALU=1 +Const D3DDECLMETHOD_PARTIALV=2 +Const D3DDECLMETHOD_CROSSUV=3 +Const D3DDECLMETHOD_UV=4 +Const D3DDECLMETHOD_LOOKUP=5 +Const D3DDECLMETHOD_LOOKUPPRESAMPLED=6 + +'D3DDECLTYPE +Const D3DDECLTYPE_FLOAT1=0 +Const D3DDECLTYPE_FLOAT2=1 +Const D3DDECLTYPE_FLOAT3=2 +Const D3DDECLTYPE_FLOAT4=3 +Const D3DDECLTYPE_D3DCOLOR=4 +Const D3DDECLTYPE_UBYTE4=5 +Const D3DDECLTYPE_SHORT2=6 +Const D3DDECLTYPE_SHORT4=7 +Const D3DDECLTYPE_UBYTE4N=8 +Const D3DDECLTYPE_SHORT2N=9 +Const D3DDECLTYPE_SHORT4N=10 +Const D3DDECLTYPE_USHORT2N=11 +Const D3DDECLTYPE_USHORT4N=12 +Const D3DDECLTYPE_UDEC3=13 +Const D3DDECLTYPE_DEC3N=14 +Const D3DDECLTYPE_FLOAT16_2=15 +Const D3DDECLTYPE_FLOAT16_4=16 +Const D3DDECLTYPE_UNUSED=17 + +'D3DQUERYTYPE +Const D3DQUERYTYPE_VCACHE=4 +Const D3DQUERYTYPE_RESOURCEMANAGER=5 +Const D3DQUERYTYPE_VERTEXSTATS=6 +Const D3DQUERYTYPE_EVENT=8 +Const D3DQUERYTYPE_OCCLUSION=9 + +Const D3DISSUE_END=1 +Const D3DISSUE_BEGIN=2 + +Const D3DGETDATA_FLUSH=1 + +Const D3DFVF_POSITION_MASK=$400e +Const D3DFVF_XYZ=$2 +Const D3DFVF_XYZRHW=$4 +Const D3DFVF_XYZB1=$6 +Const D3DFVF_XYZB2=$8 +Const D3DFVF_XYZB3=$a +Const D3DFVF_XYZB4=$c +Const D3DFVF_XYZB5=$e +Const D3DFVF_XYZW=$4002 +Const D3DFVF_NORMAL=$10 +Const D3DFVF_PSIZE=$20 +Const D3DFVF_DIFFUSE=$40 +Const D3DFVF_SPECULAR=$80 +Const D3DFVF_TEXCOUNT_MASK=$f00 +Const D3DFVF_TEXCOUNT_SHIFT=8 +Const D3DFVF_TEX0=$000 +Const D3DFVF_TEX1=$100 +Const D3DFVF_TEX2=$200 +Const D3DFVF_TEX3=$300 +Const D3DFVF_TEX4=$400 +Const D3DFVF_TEX5=$500 +Const D3DFVF_TEX6=$600 +Const D3DFVF_TEX7=$700 +Const D3DFVF_TEX8=$800 + +Const D3DPRESENTFLAG_LOCKABLE_BACKBUFFER=1 +Const D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL=2 +Const D3DPRESENTFLAG_DEVICECLIP=4 +Const D3DPRESENTFLAG_VIDEO=16 + +Const D3DCREATE_FPU_PRESERVE=$2 +Const D3DCREATE_MULTITHREADED=$4 +Const D3DCREATE_PUREDEVICE=$10 +Const D3DCREATE_SOFTWARE_VERTEXPROCESSING=$20 +Const D3DCREATE_HARDWARE_VERTEXPROCESSING=$40 +Const D3DCREATE_MIXED_VERTEXPROCESSING=$80 +Const D3DCREATE_DISABLE_DRIVER_MANAGEMENT=$100 +Const D3DCREATE_ADAPTERGROUP_DEVICE=$200 + +Const D3DCLEAR_TARGET=$1 +Const D3DCLEAR_ZBUFFER=$2 +Const D3DCLEAR_STENCIL=$4 + +Const D3DCS_LEFT=$1 +Const D3DCS_RIGHT=$2 +Const D3DCS_TOP=$4 +Const D3DCS_BOTTOM=$8 +Const D3DCS_FRONT=$10 +Const D3DCS_BACK=$20 +Const D3DCS_PLANE0=$40 +Const D3DCS_PLANE1=$80 +Const D3DCS_PLANE2=$100 +Const D3DCS_PLANE3=$200 +Const D3DCS_PLANE4=$400 +Const D3DCS_PLANE5=$800 +Const D3DCS_ALL=$fff + +Const D3DCLIPSTATUS_STATUS=$1 +Const D3DCLIPSTATUS_EXTENTS2=$2 +Const D3DCLIPSTATUS_EXTENTS3=$4 + +Const D3DSHADE_FLAT=1 +Const D3DSHADE_GOURAUD=2 +Const D3DSHADE_PHONG=3 + +Type D3DCLIPSTATUS + Field dwFlags + Field dwStatus + Field minx,maxx + Field miny,maxy + Field minz,maxz +End Type + +Type D3DMATRIX + Field _11#,_12#,_13#,_14# + Field _21#,_22#,_23#,_24# + Field _31#,_32#,_33#,_34# + Field _41#,_42#,_43#,_44# +End Type + +Type D3DDISPLAYMODE + Field Width,Height,RefreshRate,Format +End Type + +Type D3DRASTER_STATUS + Field InVBlank + Field ScanLine +End Type + +Type D3DPRESENT_PARAMETERS + Field BackBufferWidth + Field BackBufferHeight + Field BackBufferFormat + Field BackBufferCount + + Field MultiSampleType + Field MultiSampleQuality + + Field SwapEffect + Field hDeviceWindow + Field Windowed + Field EnableAutoDepthStencil + Field AutoDepthStencilFormat + Field Flags + + Field FullScreen_RefreshRateInHz + Field PresentationInterval +End Type + +Type D3DSURFACE_DESC + Field Format + Field Type_ + Field Usage + Field Pool + Field MultiSampleType + Field MultiSampleQuality + Field Width + Field Height +End Type + +Type D3DLOCKED_RECT + Field Pitch + Field pBits:Byte Ptr +End Type + +Type D3DRECTPATCH_INFO + Field StartVertexOffsetWidth + Field StartVertexOffsetHeight + Field Width + Field Height + Field Stride + Field Basis + Field Degree +End Type + +Type D3DTRIPATCH_INFO + Field StartVertexOffset + Field NumVertices + Field Basis + Field Degree +End Type diff --git a/mod/pub.mod/directx.mod/d3d7.bmx b/mod/pub.mod/directx.mod/d3d7.bmx new file mode 100644 index 0000000..d6a0e44 --- /dev/null +++ b/mod/pub.mod/directx.mod/d3d7.bmx @@ -0,0 +1,224 @@ + +Strict + +Import Pub.Win32 + +'This is very much a WORK IN PROGRESS, and highly subject to change! + +'IDirect3DDevice7 parameter definitions still incomplete + +Const D3DDEVCAPS_HWRASTERIZATION=$80000 + +Const D3DTFN_POINT=1 +Const D3DTFN_LINEAR=2 +Const D3DTFN_ANISOTROPIC=3 + +Const D3DTFP_NONE=1 +Const D3DTFP_POINT=2 +Const D3DTFP_LINEAR=3 + +Const D3DTFG_POINT=1 +Const D3DTFG_LINEAR=2 +Const D3DTFG_FLATCUBIC=3 +Const D3DTFG_GAUSSIANCUBIC=4 +Const D3DTFG_ANISOTROPIC=5 + +Const D3DVBCAPS_SYSTEMMEMORY=$800 +Const D3DVBCAPS_WRITEONLY=$10000 +Const D3DVBCAPS_OPTIMIZED=$80000000 +Const D3DVBCAPS_DONOTCLIP=$1 + +Type D3DMATERIAL7 + Field diffuse_r#,diffuse_g#,diffuse_b#,diffuse_a# + Field ambient_r#,ambient_g#,ambient_b#,ambient_a# + Field specular_r#,specular_g#,specular_b#,specular_a# + Field emissive_r#,emissive_g#,emissive_b#,emissive_a# + Field power# +End Type + +Type D3DVIEWPORT7 + Field dwX,dwY,dwWidth,dwHeight + Field dvMinZ,dvMaxZ +End Type + +Type D3DVERTEXBUFFERDESC + Field dwSize,dwCaps,dwFVF,dwNumVertices +End Type + +Extern "win32" + +Type IDirect3D7 Extends IUnknown + Method EnumDevices(callback(desc:Byte Ptr,name:Byte Ptr,d3ddevice:Byte Ptr,context:Object),user:Object) + Method CreateDevice(clsid:Byte Ptr,ddsurface7:Byte Ptr,d3ddevice7:Byte Ptr) + Method CreateVertexBuffer(lpVBDesc:Byte Ptr,lplpD3DVertexBuffer:Byte Ptr,dwFlags) + Method EnumZBufferFormats(clsid,d3dpfcallback,void) + Method EvictManagedTextures() +' /*** IDirect3D7 methods ***/ +' STDMETHOD(EnumDevices)(THIS_ LPD3DENUMDEVICESCALLBACK7,LPVOID) PURE; +' STDMETHOD(CreateDevice)(THIS_ REFCLSID,LPDIRECTDRAWSURFACE7,LPDIRECT3DDEVICE7*) PURE; +' STDMETHOD(CreateVertexBuffer)(THIS_ LPD3DVERTEXBUFFERDESC,LPDIRECT3DVERTEXBUFFER7*,DWORD) PURE; +' STDMETHOD(EnumZBufferFormats)(THIS_ REFCLSID,LPD3DENUMPIXELFORMATSCALLBACK,LPVOID) PURE; +' STDMETHOD(EvictManagedTextures)(THIS) PURE; +End Type + +Type IDirect3DDevice7 Extends IUnknown + Method GetCaps(desc:Byte Ptr) + Method EnumTextureFormats(callback(),context:Object) + Method BeginScene() + Method EndScene() + Method GetDirect3D() + Method SetRenderTarget(surf7:Byte Ptr,flags) + Method GetRenderTarget(surf7:Byte Ptr) + Method Clear(count,rects:Byte Ptr,flags,color,z,stencil) + Method SetTransform(state,matrix:Byte Ptr) + Method GetTransform(state,matrix:Byte Ptr) + + Method SetViewport(viewport:Byte Ptr) + Method MultiplyTransform() + Method GetViewport() + Method SetMaterial(material:Byte Ptr) + Method GetMaterial() + Method SetLight() + Method GetLight() + Method SetRenderState(renderstate,value) + Method GetRenderState() + Method BeginStateBlock() + Method EndStateBlock() + + Method PreLoad() + Method DrawPrimitive(primtype,verttype,verts:Byte Ptr,count,flags) + Method DrawIndexedPrimitive(d3dptPrimitiveType,dwVertexTypeDesc,lpvVertices:Byte Ptr,dwVertexCount,lpwIndices:Short Ptr,dwIndexCount,dwFlags) + Method SetClipStatus( lpD3DClipStatus:Byte Ptr ) + Method GetClipStatus( lpD3DClipStatus:Byte Ptr ) + Method DrawPrimitiveStrided(d3dptPrimitiveType,dwVertexTypeDesc,lpVertexArray:Byte Ptr,dwVertexCount,dwFlags) + Method DrawIndexedPrimitiveStrided(d3dptPrimitiveType,dwVertexTypeDesc,lpVertexArray:Byte Ptr,dwVertexCount,lpwIndices:Short Ptr,dwIndexCount,dwFlags) + Method DrawPrimitiveVB(d3dptPrimitiveType,lpd3dVertexBuffer:Byte Ptr,dwStartVertex,dwNumVertices,dwFlags) + Method DrawIndexedPrimitiveVB(d3dptPrimitiveType,lpd3dVertexBuffer:Byte Ptr,dwStartVertex,dwNumVertices,lpwIndices:Short Ptr,dwIndexCount,dwFlags) + + Method ComputeSphereVisibility() + Method GetTexture() + + Method SetTexture(stage,ddsurface7:Byte Ptr) + + Method GetTextureStageState() + Method SetTextureStageState(stage,state,value) + Method ValidateDevice() + Method ApplyStateBlock() + Method CaptureStateBlock() + Method DeleteStateBlock() + Method CreateStateBlock() + Method Load() + Method LightEnable() + Method GetLightEnable() + Method SetClipPlane( dwIndex,pPlaneEquation:Float Ptr ) + Method GetClipPlane( dwIndex,pPlaneEquation:Float Ptr ) + Method GetInfo() +' /*** IDirect3DDevice7 methods ***/ +Rem + STDMETHOD(GetCaps)(THIS_ LPD3DDEVICEDESC7) PURE; + STDMETHOD(EnumTextureFormats)(THIS_ LPD3DENUMPIXELFORMATSCALLBACK,LPVOID) PURE; + STDMETHOD(BeginScene)(THIS) PURE; + STDMETHOD(EndScene)(THIS) PURE; + STDMETHOD(GetDirect3D)(THIS_ LPDIRECT3D7*) PURE; + STDMETHOD(SetRenderTarget)(THIS_ LPDIRECTDRAWSURFACE7,DWORD) PURE; + STDMETHOD(GetRenderTarget)(THIS_ LPDIRECTDRAWSURFACE7 *) PURE; + STDMETHOD(Clear)(THIS_ DWORD,LPD3DRECT,DWORD,D3DCOLOR,D3DVALUE,DWORD) PURE; + STDMETHOD(SetTransform)(THIS_ D3DTRANSFORMSTATETYPE,LPD3DMATRIX) PURE; + STDMETHOD(GetTransform)(THIS_ D3DTRANSFORMSTATETYPE,LPD3DMATRIX) PURE; + + STDMETHOD(SetViewport)(THIS_ LPD3DVIEWPORT7) PURE; + STDMETHOD(MultiplyTransform)(THIS_ D3DTRANSFORMSTATETYPE,LPD3DMATRIX) PURE; + STDMETHOD(GetViewport)(THIS_ LPD3DVIEWPORT7) PURE; + STDMETHOD(SetMaterial)(THIS_ LPD3DMATERIAL7) PURE; + STDMETHOD(GetMaterial)(THIS_ LPD3DMATERIAL7) PURE; + STDMETHOD(SetLight)(THIS_ DWORD,LPD3DLIGHT7) PURE; + STDMETHOD(GetLight)(THIS_ DWORD,LPD3DLIGHT7) PURE; + STDMETHOD(SetRenderState)(THIS_ D3DRENDERSTATETYPE,DWORD) PURE; + STDMETHOD(GetRenderState)(THIS_ D3DRENDERSTATETYPE,LPDWORD) PURE; + STDMETHOD(BeginStateBlock)(THIS) PURE; + + STDMETHOD(EndStateBlock)(THIS_ LPDWORD) PURE; + STDMETHOD(PreLoad)(THIS_ LPDIRECTDRAWSURFACE7) PURE; + STDMETHOD(DrawPrimitive)(THIS_ D3DPRIMITIVETYPE,DWORD,LPVOID,DWORD,DWORD) PURE; + STDMETHOD(DrawIndexedPrimitive)(THIS_ D3DPRIMITIVETYPE,DWORD,LPVOID,DWORD,LPWORD,DWORD,DWORD) PURE; + STDMETHOD(SetClipStatus)(THIS_ LPD3DCLIPSTATUS) PURE; + STDMETHOD(GetClipStatus)(THIS_ LPD3DCLIPSTATUS) PURE; + STDMETHOD(DrawPrimitiveStrided)(THIS_ D3DPRIMITIVETYPE,DWORD,LPD3DDRAWPRIMITIVESTRIDEDDATA,DWORD,DWORD) PURE; + STDMETHOD(DrawIndexedPrimitiveStrided)(THIS_ D3DPRIMITIVETYPE,DWORD,LPD3DDRAWPRIMITIVESTRIDEDDATA,DWORD,LPWORD,DWORD,DWORD) PURE; + STDMETHOD(DrawPrimitiveVB)(THIS_ D3DPRIMITIVETYPE,LPDIRECT3DVERTEXBUFFER7,DWORD,DWORD,DWORD) PURE; + STDMETHOD(DrawIndexedPrimitiveVB)(THIS_ D3DPRIMITIVETYPE,LPDIRECT3DVERTEXBUFFER7,DWORD,DWORD,LPWORD,DWORD,DWORD) PURE; + + STDMETHOD(ComputeSphereVisibility)(THIS_ LPD3DVECTOR,LPD3DVALUE,DWORD,DWORD,LPDWORD) PURE; + STDMETHOD(GetTexture)(THIS_ DWORD,LPDIRECTDRAWSURFACE7 *) PURE; + STDMETHOD(SetTexture)(THIS_ DWORD,LPDIRECTDRAWSURFACE7) PURE; + STDMETHOD(GetTextureStageState)(THIS_ DWORD,D3DTEXTURESTAGESTATETYPE,LPDWORD) PURE; + STDMETHOD(SetTextureStageState)(THIS_ DWORD,D3DTEXTURESTAGESTATETYPE,DWORD) PURE; + STDMETHOD(ValidateDevice)(THIS_ LPDWORD) PURE; + STDMETHOD(ApplyStateBlock)(THIS_ DWORD) PURE; + STDMETHOD(CaptureStateBlock)(THIS_ DWORD) PURE; + STDMETHOD(DeleteStateBlock)(THIS_ DWORD) PURE; + STDMETHOD(CreateStateBlock)(THIS_ D3DSTATEBLOCKTYPE,LPDWORD) PURE; + STDMETHOD(Load)(THIS_ LPDIRECTDRAWSURFACE7,LPPOINT,LPDIRECTDRAWSURFACE7,LPRECT,DWORD) PURE; + STDMETHOD(LightEnable)(THIS_ DWORD,BOOL) PURE; + STDMETHOD(GetLightEnable)(THIS_ DWORD,BOOL*) PURE; + STDMETHOD(SetClipPlane)(THIS_ DWORD,D3DVALUE*) PURE; + STDMETHOD(GetClipPlane)(THIS_ DWORD,D3DVALUE*) PURE; + STDMETHOD(GetInfo)(THIS_ DWORD,LPVOID,DWORD) PURE; +EndRem +End Type + +Type IDirect3DVertexBuffer7 Extends IUnknown + Method Lock(flags,data:Byte Ptr,size:Int Ptr) + Method Unlock() + Method ProcessVertices(dwVertexOp,dwDestIndex,dwCount,lpSrcBuffer:Byte Ptr,dwSrcIndex,lpD3DDevice:Byte Ptr,dwFlags) + Method GetVertexBufferDesc(lpVBDesc:Byte Ptr) + Method Optimize(lpD3DDevice:Byte Ptr,dwFlags) + Method ProcessVerticesStrided(dwVertexOp,dwDestIndex,dwCount,lpVertexArray:Byte Ptr,dwSrcIndex,lpD3DDevice:Byte Ptr,dwFlags) +' /*** IDirect3DVertexBuffer7 methods ***/ +Rem + STDMETHOD(Lock)(THIS_ DWORD,LPVOID*,LPDWORD) PURE; + STDMETHOD(Unlock)(THIS) PURE; + STDMETHOD(ProcessVertices)(THIS_ DWORD,DWORD,DWORD,LPDIRECT3DVERTEXBUFFER7,DWORD,LPDIRECT3DDEVICE7,DWORD) PURE; + STDMETHOD(GetVertexBufferDesc)(THIS_ LPD3DVERTEXBUFFERDESC) PURE; + STDMETHOD(Optimize)(THIS_ LPDIRECT3DDEVICE7,DWORD) PURE; + STDMETHOD(ProcessVerticesStrided)(THIS_ DWORD,DWORD,DWORD,LPD3DDRAWPRIMITIVESTRIDEDDATA,DWORD,LPDIRECT3DDEVICE7,DWORD) PURE; +EndRem +End Type + +End Extern + +Global IID_IDirect3D7[]=[$f5049e77,$11d24861,$a00007a4,$a82906c9] +Global IID_IDirect3DHALDevice[]=[$84e63de0,$11cf46aa,$00006f81,$6e1520c0] +Global IID_IDirect3DTnLDevice[]=[$f5049e78,$11d24861,$A00007a4,$a82906c9] + +Rem + +DEFINE_GUID( IID_IDirect3D, 0x3BBA0080,0x2421,0x11CF,0xA3,0x1A,0x00,0xAA,0x00,0xB9,0x33,0x56 ); +DEFINE_GUID( IID_IDirect3D2, 0x6aae1ec1,0x662a,0x11d0,0x88,0x9d,0x00,0xaa,0x00,0xbb,0xb7,0x6a); +DEFINE_GUID( IID_IDirect3D3, 0xbb223240,0xe72b,0x11d0,0xa9,0xb4,0x00,0xaa,0x00,0xc0,0x99,0x3e); +DEFINE_GUID( IID_IDirect3D7, 0xf5049e77,0x4861,0x11d2,0xa4,0x7,0x0,0xa0,0xc9,0x6,0x29,0xa8); +DEFINE_GUID( IID_IDirect3DRampDevice, 0xF2086B20,0x259F,0x11CF,0xA3,0x1A,0x00,0xAA,0x00,0xB9,0x33,0x56 ); +DEFINE_GUID( IID_IDirect3DRGBDevice, 0xA4665C60,0x2673,0x11CF,0xA3,0x1A,0x00,0xAA,0x00,0xB9,0x33,0x56 ); +DEFINE_GUID( IID_IDirect3DHALDevice, 0x84E63dE0,0x46AA,0x11CF,0x81,0x6F,0x00,0x00,0xC0,0x20,0x15,0x6E ); +DEFINE_GUID( IID_IDirect3DMMXDevice, 0x881949a1,0xd6f3,0x11d0,0x89,0xab,0x00,0xa0,0xc9,0x05,0x41,0x29 ); +DEFINE_GUID( IID_IDirect3DRefDevice, 0x50936643, 0x13e9, 0x11d1, 0x89, 0xaa, 0x0, 0xa0, 0xc9, 0x5, 0x41, 0x29); +DEFINE_GUID( IID_IDirect3DNullDevice, 0x8767df22, 0xbacc, 0x11d1, 0x89, 0x69, 0x0, 0xa0, 0xc9, 0x6, 0x29, 0xa8); +DEFINE_GUID( IID_IDirect3DTnLHalDevice, 0xf5049e78, 0x4861, 0x11d2, 0xa4, 0x7, 0x0, 0xa0, 0xc9, 0x6, 0x29, 0xa8); +DEFINE_GUID( IID_IDirect3DDevice, 0x64108800,0x957d,0X11d0,0x89,0xab,0x00,0xa0,0xc9,0x05,0x41,0x29 ); +DEFINE_GUID( IID_IDirect3DDevice2, 0x93281501, 0x8cf8, 0x11d0, 0x89, 0xab, 0x0, 0xa0, 0xc9, 0x5, 0x41, 0x29); +DEFINE_GUID( IID_IDirect3DDevice3, 0xb0ab3b60, 0x33d7, 0x11d1, 0xa9, 0x81, 0x0, 0xc0, 0x4f, 0xd7, 0xb1, 0x74); +DEFINE_GUID( IID_IDirect3DDevice7, 0xf5049e79, 0x4861, 0x11d2, 0xa4, 0x7, 0x0, 0xa0, 0xc9, 0x6, 0x29, 0xa8); +DEFINE_GUID( IID_IDirect3DTexture, 0x2CDCD9E0,0x25A0,0x11CF,0xA3,0x1A,0x00,0xAA,0x00,0xB9,0x33,0x56 ); +DEFINE_GUID( IID_IDirect3DTexture2, 0x93281502, 0x8cf8, 0x11d0, 0x89, 0xab, 0x0, 0xa0, 0xc9, 0x5, 0x41, 0x29); +DEFINE_GUID( IID_IDirect3DLight, 0x4417C142,0x33AD,0x11CF,0x81,0x6F,0x00,0x00,0xC0,0x20,0x15,0x6E ); +DEFINE_GUID( IID_IDirect3DMaterial, 0x4417C144,0x33AD,0x11CF,0x81,0x6F,0x00,0x00,0xC0,0x20,0x15,0x6E ); +DEFINE_GUID( IID_IDirect3DMaterial2, 0x93281503, 0x8cf8, 0x11d0, 0x89, 0xab, 0x0, 0xa0, 0xc9, 0x5, 0x41, 0x29); +DEFINE_GUID( IID_IDirect3DMaterial3, 0xca9c46f4, 0xd3c5, 0x11d1, 0xb7, 0x5a, 0x0, 0x60, 0x8, 0x52, 0xb3, 0x12); +DEFINE_GUID( IID_IDirect3DExecuteBuffer,0x4417C145,0x33AD,0x11CF,0x81,0x6F,0x00,0x00,0xC0,0x20,0x15,0x6E ); +DEFINE_GUID( IID_IDirect3DViewport, 0x4417C146,0x33AD,0x11CF,0x81,0x6F,0x00,0x00,0xC0,0x20,0x15,0x6E ); +DEFINE_GUID( IID_IDirect3DViewport2, 0x93281500, 0x8cf8, 0x11d0, 0x89, 0xab, 0x0, 0xa0, 0xc9, 0x5, 0x41, 0x29); +DEFINE_GUID( IID_IDirect3DViewport3, 0xb0ab3b61, 0x33d7, 0x11d1, 0xa9, 0x81, 0x0, 0xc0, 0x4f, 0xd7, 0xb1, 0x74); +DEFINE_GUID( IID_IDirect3DVertexBuffer, 0x7a503555, 0x4a83, 0x11d1, 0xa5, 0xdb, 0x0, 0xa0, 0xc9, 0x3, 0x67, 0xf8); +DEFINE_GUID( IID_IDirect3DVertexBuffer7, 0xf5049e7d, 0x4861, 0x11d2, 0xa4, 0x7, 0x0, 0xa0, 0xc9, 0x6, 0x29, 0xa8); + +EndRem diff --git a/mod/pub.mod/directx.mod/d3d9.bmx b/mod/pub.mod/directx.mod/d3d9.bmx new file mode 100644 index 0000000..92bc8c6 --- /dev/null +++ b/mod/pub.mod/directx.mod/d3d9.bmx @@ -0,0 +1,690 @@ + +Strict + +Import Pub.Win32 + +Const DIRECT3D_VERSION9=$900 + +'what's up with this...? +Type D3DDEVTYPE + Const D3DDEVTYPE_HAL = 1 + Const D3DDEVTYPE_REF = 2 + Const D3DDEVTYPE_SW = 3 + Const D3DDEVTYPE_NULLREF = 4 + Const D3DDEVTYPE_FORCE_DWORD = $7fffffff +End Type + +Type D3DCAPS9 + Field DeviceType 'D3DDEVTYPE + Field AdapterOrdinal; + Field Caps; + Field Caps2; + Field Caps3; + Field PresentationIntervals; + Field CursorCaps; + Field DevCaps; + Field PrimitiveMiscCaps; + Field RasterCaps; + Field ZCmpCaps; + Field SrcBlendCaps; + Field DestBlendCaps; + Field AlphaCmpCaps; + Field ShadeCaps; + Field TextureCaps; + Field TextureFilterCaps; + Field CubeTextureFilterCaps; + Field VolumeTextureFilterCaps; + Field TextureAddressCaps; + Field VolumeTextureAddressCaps; + Field LineCaps; + Field MaxTextureWidth; + Field MaxTextureHeight; + Field MaxVolumeExtent; + Field MaxTextureRepeat; + Field MaxTextureAspectRatio; + Field MaxAnisotropy; + Field MaxVertexW#; + Field GuardBandLeft#; + Field GuardBandTop#; + Field GuardBandRight#; + Field GuardBandBottom#; + Field ExtentsAdjust#; + Field StencilCaps; + Field FVFCaps; + Field TextureOpCaps; + Field MaxTextureBlendStages; + Field MaxSimultaneousTextures; + Field VertexProcessingCaps; + Field MaxActiveLights; + Field MaxUserClipPlanes; + Field MaxVertexBlendMatrices; + Field MaxVertexBlendMatrixIndex; + Field MaxPointSize#; + Field MaxPrimitiveCount; + Field MaxVertexIndex; + Field MaxStreams; + Field MaxStreamStride; + Field VertexShaderVersion; + Field MaxVertexShaderConst; + Field PixelShaderVersion; + Field PixelShader1xMaxValue#; + Field DevCaps2; + Field MaxNpatchTessellationLevel#; + Field Reserved5; + Field MasterAdapterOrdinal; + Field AdapterOrdinalInGroup; + Field NumberOfAdaptersInGroup; + Field DeclTypes; + Field NumSimultaneousRTs; + Field StretchRectFilterCaps; + 'D3DVSHADERCAPS2_0 VS20Caps; + Field VS20Caps_Caps; + Field VS20Caps_DynamicFlowControlDepth; + Field VS20Caps_NumTemps; + Field VS20Caps_StaticFlowControlDepth; + 'D3DPSHADERCAPS2_0 D3DPSHADERCAPS2_0; + Field PS20Caps_Caps; + Field PS20Caps_DynamicFlowControlDepth; + Field PS20Caps_NumTemps; + Field PS20Caps_StaticFlowControlDepth; + Field PS20Caps_NumInstructionSlots; + Field VertexTextureFilterCaps; + Field MaxVShaderInstructionsExecuted; + Field MaxPShaderInstructionsExecuted; + Field MaxVertexShader30InstructionSlots; + Field MaxPixelShader30InstructionSlots; +End Type + +Type D3DCLIPSTATUS9 + Field ClipUnion + Field ClipIntersection +End Type + +Type D3DVIEWPORT9 + Field X + Field Y + Field Width + Field Height + Field MinZ# + Field MaxZ# +End Type + +Type D3DMATERIAL9 + Field Diffuse_r#,Diffuse_g#,Diffuse_b#,Diffuse_a# + Field Ambient_r#,Ambient_g#,Ambient_b#,Ambient_a# + Field Specular_r#,Specular_g#,Specular_b#,Specular_a# + Field Emissive_r#,Emissive_g#,Emissive_b#,Emissive_a# + Field Power# +End Type + +Type D3DLIGHT9 + Field Type_ + Field Diffuse_r#,Diffuse_g#,Diffuse_b#,Diffuse_a# + Field Specular_r#,Specular_g#,Specular_b#,Specular_a# + Field Ambient_r#,Ambient_g#,Ambient_b#,Ambient_a# + Field Position_x#,Position_y#,Position_z# + Field Direction_x#,Direction_y#,Direction_z# + Field Range# + Field Falloff# + Field Attenuation0# + Field Attenuation1# + Field Attenuation2# + Field Theta# + Field Phi# +End Type + +Type D3DVERTEXELEMENT9 + Field Stream:Short + Field Offset:Short + Field Type_:Byte + Field Method_:Byte + Field Usage:Byte + Field UsageIndex:Byte +End Type + + +Type D3DADAPTER_IDENTIFIER9 + Field Driver0, Driver1, Driver2, Driver3, Driver4, Driver5, Driver6, Driver7, Driver8, Driver9 + Field Driver10, Driver11, Driver12, Driver13, Driver14, Driver15, Driver16, Driver17, Driver18, Driver19 + Field Driver20, Driver21, Driver22, Driver23, Driver24, Driver25, Driver26, Driver27, Driver28, Driver29 + Field Driver30, Driver31, Driver32, Driver33, Driver34, Driver35, Driver36, Driver37, Driver38, Driver39 + Field Driver40, Driver41, Driver42, Driver43, Driver44, Driver45, Driver46, Driver47, Driver48, Driver49 + Field Driver50, Driver51, Driver52, Driver53, Driver54, Driver55, Driver56, Driver57, Driver58, Driver59 + Field Driver60, Driver61, Driver62, Driver63, Driver64, Driver65, Driver66, Driver67, Driver68, Driver69 + Field Driver70, Driver71, Driver72, Driver73, Driver74, Driver75, Driver76, Driver77, Driver78, Driver79 + Field Driver80, Driver81, Driver82, Driver83, Driver84, Driver85, Driver86, Driver87, Driver88, Driver89 + Field Driver90, Driver91, Driver92, Driver93, Driver94, Driver95, Driver96, Driver97, Driver98, Driver99 + Field Driver100, Driver101, Driver102, Driver103, Driver104, Driver105, Driver106, Driver107, Driver108, Driver109 + Field Driver110, Driver111, Driver112, Driver113, Driver114, Driver115, Driver116, Driver117, Driver118, Driver119 + Field Driver120, Driver121, Driver122, Driver123, Driver124, Driver125, Driver126, Driver127 + Field Description0, Description1, Description2, Description3, Description4, Description5, Description6, Description7, Description8, Description9 + Field Description10, Description11, Description12, Description13, Description14, Description15, Description16, Description17, Description18, Description19 + Field Description20, Description21, Description22, Description23, Description24, Description25, Description26, Description27, Description28, Description29 + Field Description30, Description31, Description32, Description33, Description34, Description35, Description36, Description37, Description38, Description39 + Field Description40, Description41, Description42, Description43, Description44, Description45, Description46, Description47, Description48, Description49 + Field Description50, Description51, Description52, Description53, Description54, Description55, Description56, Description57, Description58, Description59 + Field Description60, Description61, Description62, Description63, Description64, Description65, Description66, Description67, Description68, Description69 + Field Description70, Description71, Description72, Description73, Description74, Description75, Description76, Description77, Description78, Description79 + Field Description80, Description81, Description82, Description83, Description84, Description85, Description86, Description87, Description88, Description89 + Field Description90, Description91, Description92, Description93, Description94, Description95, Description96, Description97, Description98, Description99 + Field Description100, Description101, Description102, Description103, Description104, Description105, Description106, Description107, Description108, Description109 + Field Description110, Description111, Description112, Description113, Description114, Description115, Description116, Description117, Description118, Description119 + Field Description120, Description121, Description122, Description123, Description124, Description125, Description126, Description127 + Field DeviceName0, DeviceName1, DeviceName2, DeviceName3, DeviceName4, DeviceName5, DeviceName6, DeviceName7 + Field DriverVersionLowPart + Field DriverVersionHighPart + Field VendorId + Field DeviceId + Field SubSysId + Field Revision + Field DeviceIdentifier0 + Field DeviceIdentifier1 + Field DeviceIdentifier2 + Field DeviceIdentifier3 + Field WHQLLevel + + Method Driver$() + Return String.fromCString(Varptr Driver0) + End Method + Method Description$() + Return String.fromCString(Varptr Description0) + End Method + Method DeviceName$() + Return String.fromCString(Varptr DeviceName0) + End Method +End Type + +Extern "win32" + +Type IDirect3DQuery9 Extends IUnknown + + Method GetDevice( ppDevice:IDirect3DDevice9 Var ) + Method GetType() + Method GetDataSize() + Method Issue( dwIssueFlags ) + Method GetData( pData:Byte Ptr,dwSize,dwGetDataFlags ) +Rem + STDMETHOD(GetDevice)(THIS_ IDirect3DDevice9** ppDevice) PURE; + STDMETHOD_(D3DQUERYTYPE, GetType)(THIS) PURE; + STDMETHOD_(DWORD, GetDataSize)(THIS) PURE; + STDMETHOD(Issue)(THIS_ DWORD dwIssueFlags) PURE; + STDMETHOD(GetData)(THIS_ void* pData,DWORD dwSize,DWORD dwGetDataFlags) PURE; +End Rem + +End Type + +Type IDirect3DStateBlock9 Extends IUnknown + Method GetDevice(ppDevice: IDirect3DDevice9 Var) + Method Capture() + Method Apply() + +Rem + STDMETHOD(GetDevice)(THIS_ IDirect3DDevice9** ppDevice) PURE; + STDMETHOD(Capture)(THIS) PURE; + STDMETHOD(Apply)(THIS) PURE; +End Rem + +End Type + +Type IDirect3DPixelShader9 Extends IUnknown + +Rem + STDMETHOD(GetDevice)(THIS_ IDirect3DDevice9** ppDevice) PURE; + STDMETHOD(GetFunction)(THIS_ void*,UINT* pSizeOfData) PURE; +End Rem + +End Type + +Type IDirect3DVertexShader9 Extends IUnknown + +Rem + STDMETHOD(GetDevice)(THIS_ IDirect3DDevice9** ppDevice) PURE; + STDMETHOD(GetFunction)(THIS_ void*,UINT* pSizeOfData) PURE; +End Rem + +End Type + +Type IDirect3DVertexDeclaration9 Extends IUnknown + +Rem + STDMETHOD(GetDevice)(THIS_ IDirect3DDevice9** ppDevice) PURE; + STDMETHOD(GetDeclaration)(THIS_ D3DVERTEXELEMENT9*,UINT* pNumElements) PURE; +End Rem + +End Type + +Type IDirect3D9 Extends IUnknown + + Method RegisterSoftwareDevice( pInitializeFunction() ) + Method GetAdapterCount() + Method GetAdapterIdentifier( Adapter,Flags,pIdentifier:Byte Ptr ) + Method GetAdapterModeCount( Adapter,Format ) + Method EnumAdapterModes( Adapter,Format,Mode,pMode:Byte Ptr ) + Method GetAdapterDisplayMode( Adapter,pMode:Byte Ptr ) + Method CheckDeviceType( iAdapter,DevType,DisplayFormat,BackBufferFormat,bWindowed ) + Method CheckDeviceFormat( Adapter,DeviceType,AdapterFormat,Usage,RType,CheckFormat ) + Method CheckDeviceMultiSampleType( Adapter,DeviceType,SurfaceFormat,Windowed,MultiSampleType,pQualityLevels:Int Ptr ) + Method CheckDepthStencilMatch( Adapter,DeviceType,AdapterFormat,RenderTargetFormat,DepthStencilFormat ) + Method CheckDeviceFormatConversion( Adapter,DeviceType,SourceFormat,TargetFormat ) + Method GetDeviceCaps( Adapter,DeviceType,pCaps:Byte Ptr ) + Method GetAdapterMonitor( Adapter ) + Method CreateDevice( Adapter,DeviceType,hFocusWindow,BehaviorFlags,pPresentationParameters:Byte Ptr,ppReturnedDeviceInterface:IDirect3DDevice9 Var ) +Rem + STDMETHOD(RegisterSoftwareDevice)(THIS_ void* pInitializeFunction) PURE; + STDMETHOD_(UINT, GetAdapterCount)(THIS) PURE; + STDMETHOD(GetAdapterIdentifier)(THIS_ UINT Adapter,DWORD Flags,D3DADAPTER_IDENTIFIER9* pIdentifier) PURE; + STDMETHOD_(UINT, GetAdapterModeCount)(THIS_ UINT Adapter,D3DFORMAT Format) PURE; + STDMETHOD(EnumAdapterModes)(THIS_ UINT Adapter,D3DFORMAT Format,UINT Mode,D3DDISPLAYMODE* pMode) PURE; + STDMETHOD(GetAdapterDisplayMode)(THIS_ UINT Adapter,D3DDISPLAYMODE* pMode) PURE; + STDMETHOD(CheckDeviceType)(THIS_ UINT iAdapter,D3DDEVTYPE DevType,D3DFORMAT DisplayFormat,D3DFORMAT BackBufferFormat,BOOL bWindowed) PURE; + STDMETHOD(CheckDeviceFormat)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT AdapterFormat,DWORD Usage,D3DRESOURCETYPE RType,D3DFORMAT CheckFormat) PURE; + STDMETHOD(CheckDeviceMultiSampleType)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT SurfaceFormat,BOOL Windowed,D3DMULTISAMPLE_TYPE MultiSampleType,DWORD* pQualityLevels) PURE; + STDMETHOD(CheckDepthStencilMatch)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT AdapterFormat,D3DFORMAT RenderTargetFormat,D3DFORMAT DepthStencilFormat) PURE; + STDMETHOD(CheckDeviceFormatConversion)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT SourceFormat,D3DFORMAT TargetFormat) PURE; + STDMETHOD(GetDeviceCaps)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DCAPS9* pCaps) PURE; + STDMETHOD_(HMONITOR, GetAdapterMonitor)(THIS_ UINT Adapter) PURE; + STDMETHOD(CreateDevice)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,HWND hFocusWindow,DWORD BehaviorFlags,D3DPRESENT_PARAMETERS* pPresentationParameters,IDirect3DDevice9** ppReturnedDeviceInterface) PURE; +End Rem + +End Type + +Type IDirect3DDevice9 Extends IUnknown + + Method TestCooperativeLevel() + Method GetAvailableTextureMem() + Method EvictManagedResources() + Method GetDirect3D( ppD3D9:IDirect3D9 Var ) + Method GetDeviceCaps( caps:Byte Ptr ) + Method GetDisplayMode( iSwapChain,pMode:Byte Ptr ) + Method GetCreationParameters( pParameters:Byte Ptr ) + Method SetCursorProperties( XHotSpot,YHotSpot,pCursorBitmap:IDirect3DSurface9 ) + Method SetCursorPosition( X,Y,Flags ) + Method ShowCursor( bShow ) + Method CreateAdditionalSwapChain( pPresentationParameters:Byte Ptr,pSwapChain:IDirect3DSwapChain9 Var ) + Method GetSwapChain( iSwapChain,pSwapChain:IDirect3DSwapChain9 Var ) + Method GetNumberOfSwapChains() + Method Reset( pPresentationParameters:Byte Ptr ) + Method Present( pSourceRect:Byte Ptr,pDestRect:Byte Ptr,hDestWindowOverride,pDirtyRegion:Byte Ptr ) + Method GetBackBuffer( iSwapChain,iBackBuffer,bType,ppBackBuffer:IDirect3DSurface9 Var ) + Method GetRasterStatus( iSwapChain,pRasterStatus:Byte Ptr ) + Method SetDialogBoxMode( bEnableDialogs ) + Method SetGammaRamp( iSwapChain,Flags,pRamp:Short Ptr ) + Method GetGammaRamp( iSwapChain,pRamp:Short Ptr ) + Method CreateTexture( Width,Height,Levels,Usage,Format,Pool,ppTexture:IDirect3DTexture9 Var,pSharedHandle:Byte Ptr ) + Method CreateVolumeTexture( Width,Height,Depth,Levels,Usage,Format,Pool,ppVolumeTexture:IDirect3DVolumeTexture9,pSharedHandle:Byte Ptr ) + Method CreateCubeTexture( EdgeLength,Levels,Usage,Format,Pool,ppTexture:IDirect3DCubeTexture9 Var,pSharedHandle:Byte Ptr ) + Method CreateVertexBuffer( Length,Usage,FVF,Pool,ppVertexBuffer:IDirect3DVertexBuffer9 Var,pSharedHandle:Byte Ptr ) + Method CreateIndexBuffer( Length,Usage,Format,Pool,ppIndexBuffer:IDirect3DIndexBuffer9 Var,pSharedHandle:Byte Ptr ) + Method CreateRenderTarget( Width,Height,Format,MultiSample,MultisampleQuality,Lockable,ppSurface:IDirect3DSurface9 Var,pSharedHandle:Byte Ptr ) + Method CreateDepthStencilSurface( Width,Height,Format,MultiSample,MultisampleQuality,Discard,ppSurface:IDirect3DSurface9 Var,pSharedHandle:Byte Ptr ) + Method UpdateSurface( pSourceSurface:IDirect3DSurface9,pSourceRect:Byte Ptr,pDestinationSurface:IDirect3DSurface9,pDestPoint:Byte Ptr ) + Method UpdateTexture( pSourceTexture:IDirect3DBaseTexture9,pDestinationTexture:IDirect3DBaseTexture9 ) + Method GetRenderTargetData( pRenderTarget:IDirect3DSurface9,pDestSurface:IDirect3DSurface9 ) + Method GetFrontBufferData( iSwapChain,pDestSurface:IDirect3DSurface9 ) + Method StretchRect( pSourceSurface:IDirect3DSurface9,pSourceRect:Byte Ptr,pDestSurface:IDirect3DSurface9,pDestRect:Byte Ptr,Filter ) + Method ColorFill( pSurface:IDirect3DSurface9,pRect:Byte Ptr,color ) + Method CreateOffscreenPlainSurface( Width,Height,Format,Pool,ppSurface:IDirect3DSurface9 Var,pSharedHandle:Byte Ptr ) + Method SetRenderTarget( RenderTargetIndex,pRenderTarget:IDirect3DSurface9 ) + Method GetRenderTarget( RenderTargetIndex,pRenderTarget:IDirect3DSurface9 Var ) + Method SetDepthStencilSurface( pNewZStencil:IDirect3DSurface9 ) + Method GetDepthStencilSurface( ppZStencilSurface:IDirect3DSurface9 Var ) + Method BeginScene() + Method EndScene() + Method Clear( Count,pRects:Byte Ptr,Flags,Color,Z#,Stencil ) + Method SetTransform( State,pMatrix:Float Ptr ) + Method GetTransform( State,pMatrix:Float Ptr ) + Method MultiplyTransform( State,pMatrix:Float Ptr ) + Method SetViewport( pViewport:Byte Ptr ) + Method GetViewport( pViewport:Byte Ptr ) + Method SetMaterial( pMaterial:Byte Ptr ) + Method GetMaterial( pMaterial:Byte Ptr ) + Method SetLight( Index,pLight:Byte Ptr ) + Method GetLight( Index,pLight:Byte Ptr ) + Method LightEnable( Index,Enable ) + Method GetLightEnable( Index,Enable:Int Ptr ) + Method SetClipPlane( Index,pPlane:Float Ptr ) + Method GetClipPlane( Index,pPlane:Float Ptr ) + Method SetRenderState( State,Value ) + Method GetRenderState( State,Value Var ) + Method CreateStateBlock( Type_,ppSB:IDirect3DStateBlock9 Var ) + Method BeginStateBlock() + Method EndStateBlock( ppSB:IDirect3DStateBlock9 Var ) + Method SetClipStatus( pClipStatus:Byte Ptr ) + Method GetClipStatus( pClipStatus:Byte Ptr ) + Method GetTexture( Stage,ppTexture:IDirect3DBaseTexture9 Var ) + Method SetTexture( Stage,pTexture:IDirect3DBaseTexture9 ) + Method GetTextureStageState( Stage,Type_,pValue Var ) + Method SetTextureStageState( Stage,Type_,Value ) + Method GetSamplerState( Sampler,Type_,pValue Var ) + Method SetSamplerState( Sampler,Type_,Value ) + Method ValidateDevice( pNumPasses:Int Ptr ) + Method SetPaletteEntries( PaletteNumber,pEntries:Byte Ptr ) + Method GetPaletteEntries( PaletteNumber,pEntries:Byte Ptr ) + Method SetCurrentTexturePalette( PaletteNumber ) + Method GetCurrentTexturePalette( PaletteNumber Var ) + Method SetScissorRect( pRect:Byte Ptr ) + Method GetScissorRect( pRect:Byte Ptr ) + Method SetSoftwareVertexProcessing( bSoftware ) + Method GetSoftwareVertexProcessing() + Method SetNPatchMode( nSegments# ) + Method GetNPatchMode#() + Method DrawPrimitive( PrimitiveType,StartVertex,PrimitiveCount ) + Method DrawIndexedPrimitive( PrimitiveType,BaseVertexIndex,MinVertexIndex,NumVertices,startIndex,primCount ) + Method DrawPrimitiveUP( PrimitiveType,PrimitiveCount,pVertexStreamZeroData:Byte Ptr,VertexStreamZeroStride ) + Method DrawIndexedPrimitiveUP( PrimitiveType,MinVertexIndex,NumVertices,PrimitiveCount,pIndexData:Byte Ptr,IndexDataFormat,pVertexStreamZeroData:Byte Ptr,VertexStreamZeroStride ) + Method ProcessVertices( SrcStartIndex,DestIndex,VertexCount,pDestBuffer:IDirect3DVertexBuffer9,pVertexDecl:IDirect3DVertexDeclaration9,Flags ) + Method CreateVertexDeclaration( pVertexElements:Byte Ptr,ppDecl:IDirect3DVertexDeclaration9 Var ) + Method SetVertexDeclaration( pDecl:IDirect3DVertexDeclaration9 ) + Method GetVertexDeclaration( ppDecl:IDirect3DVertexDeclaration9 Var ) + Method SetFVF( FVF ) + Method GetFVF( FVF Var ) + Method CreateVertexShader( pFunction:Byte Ptr,ppShader:IDirect3DVertexShader9 Var ) + Method SetVertexShader( pShader:IDirect3DVertexShader9 ) + Method GetVertexShader( ppShader:IDirect3DVertexShader9 Var ) + Method SetVertexShaderConstantF( StartRegister,pConstantData:Float Ptr,Vector4fCount ) + Method GetVertexShaderConstantF( StartRegister,pConstantData:Float Ptr,Vector4fCount ) + Method SetVertexShaderConstantI( StartRegister,pConstantData:Int Ptr,Vector4iCount ) + Method GetVertexShaderConstantI( StartRegister,pConstantData:Int Ptr,Vector4iCount ) + Method SetVertexShaderConstantB( StartRegister,pConstantData:Byte Ptr,BoolCount ) + Method GetVertexShaderConstantB( StartRegister,pConstantData:Byte Ptr,BoolCount ) + Method SetStreamSource( StreamNumber,pStreamData:IDirect3DVertexBuffer9,OffsetInBytes,Stride ) + Method GetStreamSource( StreamNumber,ppStreamData:IDirect3DVertexBuffer9 Var,OffsetInBytes Var,Stride Var ) + Method SetStreamSourceFreq( StreamNumber,Divider ) + Method GetStreamSourceFreq( StreamNumber,Divider Var ) + Method SetIndices( pIndexData:IDirect3DIndexBuffer9 ) + Method GetIndices( ppIndexData:IDirect3DIndexBuffer9 Var ) + Method CreatePixelShader( pFunction:Byte Ptr,ppShader:IDirect3DPixelShader9 Var ) + Method SetPixelShader( pShader:IDirect3DPixelShader9 ) + Method GetPixelShader( ppShader:IDirect3DPixelShader9 Var ) + Method SetPixelShaderConstantF( StartRegister,pConstantData:Float Ptr,Vector4fCount ) + Method GetPixelShaderConstantF( StartRegister,pConstantData:Float Ptr,Vector4fCount ) + Method SetPixelShaderConstantI( StartRegister,pConstantData:Int Ptr,Vector4iCount ) + Method GetPixelShaderConstantI( StartRegister,pConstantData:Int Ptr,Vector4iCount ) + Method SetPixelShaderConstantB( StartRegister,pConstantData:Byte Ptr,BoolCount ) + Method GetPixelShaderConstantB( StartRegister,pConstantData:Byte Ptr,BoolCount ) + Method DrawRectPatch( Handle,pNumSegs:Float Ptr,pRectPathInfo:Byte Ptr ) + Method DrawTriPatch( Handle,pNumSegs:Float Ptr,pTriPatchInfo:Byte Ptr ) + Method DeletePatch( Handle ) + Method CreateQuery( Type_,ppQuery:IDirect3DQuery9 Var ) +Rem + STDMETHOD(TestCooperativeLevel)(THIS) PURE; + STDMETHOD_(UINT, GetAvailableTextureMem)(THIS) PURE; + STDMETHOD(EvictManagedResources)(THIS) PURE; + STDMETHOD(GetDirect3D)(THIS_ IDirect3D9** ppD3D9) PURE; + STDMETHOD(GetDeviceCaps)(THIS_ D3DCAPS9* pCaps) PURE; + STDMETHOD(GetDisplayMode)(THIS_ UINT iSwapChain,D3DDISPLAYMODE* pMode) PURE; + STDMETHOD(GetCreationParameters)(THIS_ D3DDEVICE_CREATION_PARAMETERS *pParameters) PURE; + STDMETHOD(SetCursorProperties)(THIS_ UINT XHotSpot,UINT YHotSpot,IDirect3DSurface9* pCursorBitmap) PURE; + STDMETHOD_(void, SetCursorPosition)(THIS_ Int X,Int Y,DWORD Flags) PURE; + STDMETHOD_(BOOL, ShowCursor)(THIS_ BOOL bShow) PURE; + STDMETHOD(CreateAdditionalSwapChain)(THIS_ D3DPRESENT_PARAMETERS* pPresentationParameters,IDirect3DSwapChain9** pSwapChain) PURE; + STDMETHOD(GetSwapChain)(THIS_ UINT iSwapChain,IDirect3DSwapChain9** pSwapChain) PURE; + STDMETHOD_(UINT, GetNumberOfSwapChains)(THIS) PURE; + STDMETHOD(Reset)(THIS_ D3DPRESENT_PARAMETERS* pPresentationParameters) PURE; + STDMETHOD(Present)(THIS_ Const RECT* pSourceRect,Const RECT* pDestRect,HWND hDestWindowOverride,Const RGNDATA* pDirtyRegion) PURE; + STDMETHOD(GetBackBuffer)(THIS_ UINT iSwapChain,UINT iBackBuffer,D3DBACKBUFFER_TYPE Type,IDirect3DSurface9** ppBackBuffer) PURE; + STDMETHOD(GetRasterStatus)(THIS_ UINT iSwapChain,D3DRASTER_STATUS* pRasterStatus) PURE; + STDMETHOD(SetDialogBoxMode)(THIS_ BOOL bEnableDialogs) PURE; + STDMETHOD_(void, SetGammaRamp)(THIS_ UINT iSwapChain,DWORD Flags,Const D3DGAMMARAMP* pRamp) PURE; + STDMETHOD_(void, GetGammaRamp)(THIS_ UINT iSwapChain,D3DGAMMARAMP* pRamp) PURE; + STDMETHOD(CreateTexture)(THIS_ UINT Width,UINT Height,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DTexture9** ppTexture,HANDLE* pSharedHandle) PURE; + STDMETHOD(CreateVolumeTexture)(THIS_ UINT Width,UINT Height,UINT Depth,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DVolumeTexture9** ppVolumeTexture,HANDLE* pSharedHandle) PURE; + STDMETHOD(CreateCubeTexture)(THIS_ UINT EdgeLength,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DCubeTexture9** ppCubeTexture,HANDLE* pSharedHandle) PURE; + STDMETHOD(CreateVertexBuffer)(THIS_ UINT Length,DWORD Usage,DWORD FVF,D3DPOOL Pool,IDirect3DVertexBuffer9** ppVertexBuffer,HANDLE* pSharedHandle) PURE; + STDMETHOD(CreateIndexBuffer)(THIS_ UINT Length,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DIndexBuffer9** ppIndexBuffer,HANDLE* pSharedHandle) PURE; + STDMETHOD(CreateRenderTarget)(THIS_ UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,DWORD MultisampleQuality,BOOL Lockable,IDirect3DSurface9** ppSurface,HANDLE* pSharedHandle) PURE; + STDMETHOD(CreateDepthStencilSurface)(THIS_ UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,DWORD MultisampleQuality,BOOL Discard,IDirect3DSurface9** ppSurface,HANDLE* pSharedHandle) PURE; + STDMETHOD(UpdateSurface)(THIS_ IDirect3DSurface9* pSourceSurface,Const RECT* pSourceRect,IDirect3DSurface9* pDestinationSurface,Const POINT* pDestPoint) PURE; + STDMETHOD(UpdateTexture)(THIS_ IDirect3DBaseTexture9* pSourceTexture,IDirect3DBaseTexture9* pDestinationTexture) PURE; + STDMETHOD(GetRenderTargetData)(THIS_ IDirect3DSurface9* pRenderTarget,IDirect3DSurface9* pDestSurface) PURE; + STDMETHOD(GetFrontBufferData)(THIS_ UINT iSwapChain,IDirect3DSurface9* pDestSurface) PURE; + STDMETHOD(StretchRect)(THIS_ IDirect3DSurface9* pSourceSurface,Const RECT* pSourceRect,IDirect3DSurface9* pDestSurface,Const RECT* pDestRect,D3DTEXTUREFILTERTYPE Filter) PURE; + STDMETHOD(ColorFill)(THIS_ IDirect3DSurface9* pSurface,Const RECT* pRect,D3DCOLOR color) PURE; + STDMETHOD(CreateOffscreenPlainSurface)(THIS_ UINT Width,UINT Height,D3DFORMAT Format,D3DPOOL Pool,IDirect3DSurface9** ppSurface,HANDLE* pSharedHandle) PURE; + STDMETHOD(SetRenderTarget)(THIS_ DWORD RenderTargetIndex,IDirect3DSurface9* pRenderTarget) PURE; + STDMETHOD(GetRenderTarget)(THIS_ DWORD RenderTargetIndex,IDirect3DSurface9** ppRenderTarget) PURE; + STDMETHOD(SetDepthStencilSurface)(THIS_ IDirect3DSurface9* pNewZStencil) PURE; + STDMETHOD(GetDepthStencilSurface)(THIS_ IDirect3DSurface9** ppZStencilSurface) PURE; + STDMETHOD(BeginScene)(THIS) PURE; + STDMETHOD(EndScene)(THIS) PURE; + STDMETHOD(Clear)(THIS_ DWORD Count,Const D3DRECT* pRects,DWORD Flags,D3DCOLOR Color,Float Z,DWORD Stencil) PURE; + STDMETHOD(SetTransform)(THIS_ D3DTRANSFORMSTATETYPE State,Const D3DMATRIX* pMatrix) PURE; + STDMETHOD(GetTransform)(THIS_ D3DTRANSFORMSTATETYPE State,D3DMATRIX* pMatrix) PURE; + STDMETHOD(MultiplyTransform)(THIS_ D3DTRANSFORMSTATETYPE,Const D3DMATRIX*) PURE; + STDMETHOD(SetViewport)(THIS_ Const D3DVIEWPORT9* pViewport) PURE; + STDMETHOD(GetViewport)(THIS_ D3DVIEWPORT9* pViewport) PURE; + STDMETHOD(SetMaterial)(THIS_ Const D3DMATERIAL9* pMaterial) PURE; + STDMETHOD(GetMaterial)(THIS_ D3DMATERIAL9* pMaterial) PURE; + STDMETHOD(SetLight)(THIS_ DWORD Index,Const D3DLIGHT9*) PURE; + STDMETHOD(GetLight)(THIS_ DWORD Index,D3DLIGHT9*) PURE; + STDMETHOD(LightEnable)(THIS_ DWORD Index,BOOL Enable) PURE; + STDMETHOD(GetLightEnable)(THIS_ DWORD Index,BOOL* pEnable) PURE; + STDMETHOD(SetClipPlane)(THIS_ DWORD Index,Const Float* pPlane) PURE; + STDMETHOD(GetClipPlane)(THIS_ DWORD Index,Float* pPlane) PURE; + STDMETHOD(SetRenderState)(THIS_ D3DRENDERSTATETYPE State,DWORD Value) PURE; + STDMETHOD(GetRenderState)(THIS_ D3DRENDERSTATETYPE State,DWORD* pValue) PURE; + STDMETHOD(CreateStateBlock)(THIS_ D3DSTATEBLOCKTYPE Type,IDirect3DStateBlock9** ppSB) PURE; + STDMETHOD(BeginStateBlock)(THIS) PURE; + STDMETHOD(EndStateBlock)(THIS_ IDirect3DStateBlock9** ppSB) PURE; + STDMETHOD(SetClipStatus)(THIS_ Const D3DCLIPSTATUS9* pClipStatus) PURE; + STDMETHOD(GetClipStatus)(THIS_ D3DCLIPSTATUS9* pClipStatus) PURE; + STDMETHOD(GetTexture)(THIS_ DWORD Stage,IDirect3DBaseTexture9** ppTexture) PURE; + STDMETHOD(SetTexture)(THIS_ DWORD Stage,IDirect3DBaseTexture9* pTexture) PURE; + STDMETHOD(GetTextureStageState)(THIS_ DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD* pValue) PURE; + STDMETHOD(SetTextureStageState)(THIS_ DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD Value) PURE; + STDMETHOD(GetSamplerState)(THIS_ DWORD Sampler,D3DSAMPLERSTATETYPE Type,DWORD* pValue) PURE; + STDMETHOD(SetSamplerState)(THIS_ DWORD Sampler,D3DSAMPLERSTATETYPE Type,DWORD Value) PURE; + STDMETHOD(ValidateDevice)(THIS_ DWORD* pNumPasses) PURE; + STDMETHOD(SetPaletteEntries)(THIS_ UINT PaletteNumber,Const PALETTEENTRY* pEntries) PURE; + STDMETHOD(GetPaletteEntries)(THIS_ UINT PaletteNumber,PALETTEENTRY* pEntries) PURE; + STDMETHOD(SetCurrentTexturePalette)(THIS_ UINT PaletteNumber) PURE; + STDMETHOD(GetCurrentTexturePalette)(THIS_ UINT *PaletteNumber) PURE; + STDMETHOD(SetScissorRect)(THIS_ Const RECT* pRect) PURE; + STDMETHOD(GetScissorRect)(THIS_ RECT* pRect) PURE; + STDMETHOD(SetSoftwareVertexProcessing)(THIS_ BOOL bSoftware) PURE; + STDMETHOD_(BOOL, GetSoftwareVertexProcessing)(THIS) PURE; + STDMETHOD(SetNPatchMode)(THIS_ Float nSegments) PURE; + STDMETHOD_(Float, GetNPatchMode)(THIS) PURE; + STDMETHOD(DrawPrimitive)(THIS_ D3DPRIMITIVETYPE PrimitiveType,UINT StartVertex,UINT PrimitiveCount) PURE; + STDMETHOD(DrawIndexedPrimitive)(THIS_ D3DPRIMITIVETYPE,Int BaseVertexIndex,UINT MinVertexIndex,UINT NumVertices,UINT startIndex,UINT primCount) PURE; + STDMETHOD(DrawPrimitiveUP)(THIS_ D3DPRIMITIVETYPE PrimitiveType,UINT PrimitiveCount,Const void* pVertexStreamZeroData,UINT VertexStreamZeroStride) PURE; + STDMETHOD(DrawIndexedPrimitiveUP)(THIS_ D3DPRIMITIVETYPE PrimitiveType,UINT MinVertexIndex,UINT NumVertices,UINT PrimitiveCount,Const void* pIndexData,D3DFORMAT IndexDataFormat,Const void* pVertexStreamZeroData,UINT VertexStreamZeroStride) PURE; + STDMETHOD(ProcessVertices)(THIS_ UINT SrcStartIndex,UINT DestIndex,UINT VertexCount,IDirect3DVertexBuffer9* pDestBuffer,IDirect3DVertexDeclaration9* pVertexDecl,DWORD Flags) PURE; + STDMETHOD(CreateVertexDeclaration)(THIS_ Const D3DVERTEXELEMENT9* pVertexElements,IDirect3DVertexDeclaration9** ppDecl) PURE; + STDMETHOD(SetVertexDeclaration)(THIS_ IDirect3DVertexDeclaration9* pDecl) PURE; + STDMETHOD(GetVertexDeclaration)(THIS_ IDirect3DVertexDeclaration9** ppDecl) PURE; + STDMETHOD(SetFVF)(THIS_ DWORD FVF) PURE; + STDMETHOD(GetFVF)(THIS_ DWORD* pFVF) PURE; + STDMETHOD(CreateVertexShader)(THIS_ Const DWORD* pFunction,IDirect3DVertexShader9** ppShader) PURE; + STDMETHOD(SetVertexShader)(THIS_ IDirect3DVertexShader9* pShader) PURE; + STDMETHOD(GetVertexShader)(THIS_ IDirect3DVertexShader9** ppShader) PURE; + STDMETHOD(SetVertexShaderConstantF)(THIS_ UINT StartRegister,Const Float* pConstantData,UINT Vector4fCount) PURE; + STDMETHOD(GetVertexShaderConstantF)(THIS_ UINT StartRegister,Float* pConstantData,UINT Vector4fCount) PURE; + STDMETHOD(SetVertexShaderConstantI)(THIS_ UINT StartRegister,Const Int* pConstantData,UINT Vector4iCount) PURE; + STDMETHOD(GetVertexShaderConstantI)(THIS_ UINT StartRegister,Int* pConstantData,UINT Vector4iCount) PURE; + STDMETHOD(SetVertexShaderConstantB)(THIS_ UINT StartRegister,Const BOOL* pConstantData,UINT BoolCount) PURE; + STDMETHOD(GetVertexShaderConstantB)(THIS_ UINT StartRegister,BOOL* pConstantData,UINT BoolCount) PURE; + STDMETHOD(SetStreamSource)(THIS_ UINT StreamNumber,IDirect3DVertexBuffer9* pStreamData,UINT OffsetInBytes,UINT Stride) PURE; + STDMETHOD(GetStreamSource)(THIS_ UINT StreamNumber,IDirect3DVertexBuffer9** ppStreamData,UINT* OffsetInBytes,UINT* pStride) PURE; + STDMETHOD(SetStreamSourceFreq)(THIS_ UINT StreamNumber,UINT Divider) PURE; + STDMETHOD(GetStreamSourceFreq)(THIS_ UINT StreamNumber,UINT* Divider) PURE; + STDMETHOD(SetIndices)(THIS_ IDirect3DIndexBuffer9* pIndexData) PURE; + STDMETHOD(GetIndices)(THIS_ IDirect3DIndexBuffer9** ppIndexData) PURE; + STDMETHOD(CreatePixelShader)(THIS_ Const DWORD* pFunction,IDirect3DPixelShader9** ppShader) PURE; + STDMETHOD(SetPixelShader)(THIS_ IDirect3DPixelShader9* pShader) PURE; + STDMETHOD(GetPixelShader)(THIS_ IDirect3DPixelShader9** ppShader) PURE; + STDMETHOD(SetPixelShaderConstantF)(THIS_ UINT StartRegister,Const Float* pConstantData,UINT Vector4fCount) PURE; + STDMETHOD(GetPixelShaderConstantF)(THIS_ UINT StartRegister,Float* pConstantData,UINT Vector4fCount) PURE; + STDMETHOD(SetPixelShaderConstantI)(THIS_ UINT StartRegister,Const Int* pConstantData,UINT Vector4iCount) PURE; + STDMETHOD(GetPixelShaderConstantI)(THIS_ UINT StartRegister,Int* pConstantData,UINT Vector4iCount) PURE; + STDMETHOD(SetPixelShaderConstantB)(THIS_ UINT StartRegister,Const BOOL* pConstantData,UINT BoolCount) PURE; + STDMETHOD(GetPixelShaderConstantB)(THIS_ UINT StartRegister,BOOL* pConstantData,UINT BoolCount) PURE; + STDMETHOD(DrawRectPatch)(THIS_ UINT Handle,Const Float* pNumSegs,Const D3DRECTPATCH_INFO* pRectPatchInfo) PURE; + STDMETHOD(DrawTriPatch)(THIS_ UINT Handle,Const Float* pNumSegs,Const D3DTRIPATCH_INFO* pTriPatchInfo) PURE; + STDMETHOD(DeletePatch)(THIS_ UINT Handle) PURE; + STDMETHOD(CreateQuery)(THIS_ D3DQUERYTYPE Type,IDirect3DQuery9** ppQuery) PURE; +End Rem + +End Type + +Type IDirect3DSwapChain9 Extends IUnknown + + Method Present( pSourceRect:Byte Ptr,pDestRect:Byte Ptr,hDestWindowOverride,pDirtyRegion:Byte Ptr,Flags ) + Method GetFrontBufferData(pDestSurface:IDirect3DSurface9) + Method GetBackBuffer(iBackBuffer:Int, Type_:Int,ppBackBuffer:IDirect3DSurface9 Var) + Method GetRasterStatus(pRasterStatus:Byte Ptr) +Rem + STDMETHOD(Present)(THIS_ Const RECT* pSourceRect,Const RECT* pDestRect,HWND hDestWindowOverride,Const RGNDATA* pDirtyRegion,DWORD dwFlags) PURE; + STDMETHOD(GetFrontBufferData)(THIS_ IDirect3DSurface9* pDestSurface) PURE; + STDMETHOD(GetBackBuffer)(THIS_ UINT iBackBuffer,D3DBACKBUFFER_TYPE Type,IDirect3DSurface9** ppBackBuffer) PURE; + STDMETHOD(GetRasterStatus)(THIS_ D3DRASTER_STATUS* pRasterStatus) PURE; + STDMETHOD(GetDisplayMode)(THIS_ D3DDISPLAYMODE* pMode) PURE; + STDMETHOD(GetDevice)(THIS_ IDirect3DDevice9** ppDevice) PURE; + STDMETHOD(GetPresentParameters)(THIS_ D3DPRESENT_PARAMETERS* pPresentationParameters) PURE; +End Rem + +End Type + +Type IDirect3DResource9 Extends IUnknown + + Method GetDevice( ppDevice:IDirect3DDevice9 Var ) + Method SetPrivateData( refguid:Byte Ptr,pData:Byte Ptr,SizeOfData,Flags ) + Method GetPrivateData( refguid:Byte Ptr,pData:Byte Ptr,pSizeOfData ) + Method FreePrivateData( refguid:Byte Ptr ) + Method SetPriority( PriorityNew ) + Method GetPriority() + Method PreLoad() + Method GetType() +Rem + STDMETHOD(GetDevice)(THIS_ IDirect3DDevice9** ppDevice) PURE; + STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid,Const void* pData,DWORD SizeOfData,DWORD Flags) PURE; + STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid,void* pData,DWORD* pSizeOfData) PURE; + STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE; + STDMETHOD_(DWORD, SetPriority)(THIS_ DWORD PriorityNew) PURE; + STDMETHOD_(DWORD, GetPriority)(THIS) PURE; + STDMETHOD_(void, PreLoad)(THIS) PURE; + STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE; +End Rem + +End Type + +Type IDirect3DSurface9 Extends IDirect3dResource9 + + Method GetContainer( riid:Byte Ptr,ppContainer:Byte Ptr Var ) + Method GetDesc( pDesc:Byte Ptr ) + Method LockRect( pLockedRect:Byte Ptr,pRect:Byte Ptr,Flags ) + Method UnlockRect() + Method GetDC( phdc:Byte Ptr Var ) + Method ReleaseDC( hdc:Byte Ptr ) +Rem + STDMETHOD(GetContainer)(THIS_ REFIID riid,void** ppContainer) PURE; + STDMETHOD(GetDesc)(THIS_ D3DSURFACE_DESC *pDesc) PURE; + STDMETHOD(LockRect)(THIS_ D3DLOCKED_RECT* pLockedRect,Const RECT* pRect,DWORD Flags) PURE; + STDMETHOD(UnlockRect)(THIS) PURE; + STDMETHOD(GetDC)(THIS_ HDC *phdc) PURE; + STDMETHOD(ReleaseDC)(THIS_ HDC hdc) PURE; +End Rem + +End Type + +Type IDirect3DVertexBuffer9 Extends IDirect3DResource9 + + Method Lock( OffsetToLock,SizeToLock,ppbData:Byte Ptr Var,Flags ) + Method Unlock() +Rem + STDMETHOD(Lock)(THIS_ UINT OffsetToLock,UINT SizeToLock,void** ppbData,DWORD Flags) PURE; + STDMETHOD(Unlock)(THIS) PURE; + STDMETHOD(GetDesc)(THIS_ D3DVERTEXBUFFER_DESC *pDesc) PURE; +End Rem + +End Type + +Type IDirect3DIndexBuffer9 Extends IDirect3DResource9 + + Method Lock( OffsetToLock,SizeToLock,ppbData:Byte Ptr Var,Flags ) + Method Unlock() +Rem + STDMETHOD(Lock)(THIS_ UINT OffsetToLock,UINT SizeToLock,void** ppbData,DWORD Flags) PURE; + STDMETHOD(Unlock)(THIS) PURE; + STDMETHOD(GetDesc)(THIS_ D3DINDEXBUFFER_DESC *pDesc) PURE; +End Rem + +End Type + +Type IDirect3DBaseTexture9 Extends IDirect3DResource9 + + Method SetLOD( LODNew ) + Method GetLOD() + Method GetLevelCount() + Method SetAutoGenFilterType( FilterType ) + Method GetAutoGenFilterType() + Method GenerateMipSubLevels() +Rem + STDMETHOD_(DWORD, SetLOD)(THIS_ DWORD LODNew) PURE; + STDMETHOD_(DWORD, GetLOD)(THIS) PURE; + STDMETHOD_(DWORD, GetLevelCount)(THIS) PURE; + STDMETHOD(SetAutoGenFilterType)(THIS_ D3DTEXTUREFILTERTYPE FilterType) PURE; + STDMETHOD_(D3DTEXTUREFILTERTYPE, GetAutoGenFilterType)(THIS) PURE; + STDMETHOD_(void, GenerateMipSubLevels)(THIS) PURE; +End Rem + +End Type + +Type IDirect3DTexture9 Extends IDirect3DBaseTexture9 + + Method GetLevelDesc( Level,pDesc:Byte Ptr ) + Method GetSurfaceLevel( Level,ppSurfaceLevel:IDirect3DSurface9 Var ) + Method LockRect( Level,pLockedRect:Byte Ptr,pRect:Byte Ptr,Flags ) + Method UnlockRect( Level ) + Method AddDirtyRect( pDirtyRect:Byte Ptr ) +Rem + STDMETHOD(GetLevelDesc)(THIS_ UINT Level,D3DSURFACE_DESC *pDesc) PURE; + STDMETHOD(GetSurfaceLevel)(THIS_ UINT Level,IDirect3DSurface9** ppSurfaceLevel) PURE; + STDMETHOD(LockRect)(THIS_ UINT Level,D3DLOCKED_RECT* pLockedRect,Const RECT* pRect,DWORD Flags) PURE; + STDMETHOD(UnlockRect)(THIS_ UINT Level) PURE; + STDMETHOD(AddDirtyRect)(THIS_ Const RECT* pDirtyRect) PURE; +End Rem + +End Type + +Type IDirect3DCubeTexture9 Extends IDirect3DBaseTexture9 + + Method GetLevelDesc( Level,pDesc:Byte Ptr ) + Method GetCubeMapSurface( FaceType,Level,ppCubeMapSurface:IDirect3DSurface9 Var ) + Method LockRect( FaceType,Level,pLockedRect:Byte Ptr,pRect:Byte Ptr,Flags ) + Method UnlockRect( FaceType,Level ) + Method AddDirtyRect( FaceType,pDirtyRect:Byte Ptr ) +Rem + STDMETHOD(GetLevelDesc)(THIS_ UINT Level,D3DSURFACE_DESC *pDesc) PURE; + STDMETHOD(GetCubeMapSurface)(THIS_ D3DCUBEMAP_FACES FaceType,UINT Level,IDirect3DSurface9** ppCubeMapSurface) PURE; + STDMETHOD(LockRect)(THIS_ D3DCUBEMAP_FACES FaceType,UINT Level,D3DLOCKED_RECT* pLockedRect,Const RECT* pRect,DWORD Flags) PURE; + STDMETHOD(UnlockRect)(THIS_ D3DCUBEMAP_FACES FaceType,UINT Level) PURE; + STDMETHOD(AddDirtyRect)(THIS_ D3DCUBEMAP_FACES FaceType,Const RECT* pDirtyRect) PURE; +End Rem + +End Type + +Type IDirect3DVolumeTexture9 Extends IDirect3DBaseTexture9 + +' Method GetLevelDesc( Level,pDesc:Byte Ptr ) +' Method GetVolumeLevel( Level,ppVolumeLevel:IDirect3DVolume9 Var ) +' Method LockBox( Level,pLockedVolume:Byte Ptr,pBox:Byte Ptr,Flags ) +' Method UnlockBox( Level ) +' Method AddDirtyBox( pDirtyBox:Byte Ptr ) +Rem + STDMETHOD(GetLevelDesc)(THIS_ UINT Level,D3DVOLUME_DESC *pDesc) PURE; + STDMETHOD(GetVolumeLevel)(THIS_ UINT Level,IDirect3DVolume9** ppVolumeLevel) PURE; + STDMETHOD(LockBox)(THIS_ UINT Level,D3DLOCKED_BOX* pLockedVolume,Const D3DBOX* pBox,DWORD Flags) PURE; + STDMETHOD(UnlockBox)(THIS_ UINT Level) PURE; + STDMETHOD(AddDirtyBox)(THIS_ Const D3DBOX* pDirtyBox) PURE; +End Rem + +End Type + +End Extern + +Global d3d9Lib=LoadLibraryA( "d3d9" ) + +If Not d3d9Lib Return + +Global Direct3DCreate9:IDirect3D9( SDKVersion )"win32" = GetProcAddress( d3d9Lib,"Direct3DCreate9" ) diff --git a/mod/pub.mod/directx.mod/d3d9x.bmx b/mod/pub.mod/directx.mod/d3d9x.bmx new file mode 100644 index 0000000..a203204 --- /dev/null +++ b/mod/pub.mod/directx.mod/d3d9x.bmx @@ -0,0 +1,25 @@ + +Strict + +Import Pub.Win32 + +Extern "win32" + +Type ID3DXBuffer Extends IUnknown + + Method GetBufferPointer:Byte Ptr() + Method GetBufferSize() +Rem + // ID3DXBuffer + STDMETHOD_(LPVOID, GetBufferPointer)(THIS) PURE; + STDMETHOD_(DWORD, GetBufferSize)(THIS) PURE; +end rem +End Type + +End Extern + +Global d3dx9Lib=LoadLibraryA( "d3dx9" ) + +If Not d3dx9Lib Return + +Global D3DXAssembleShader( pSrcData:Byte Ptr,SrcDataLen,pDefines:Byte Ptr,pInclude:Byte Ptr,Flags,ppShader:ID3DXBuffer Var,ppErrorMsgs:ID3DXBuffer Var )"win32"=GetProcAddress( d3dx9Lib,"D3DXAssembleShader" ) diff --git a/mod/pub.mod/directx.mod/dd.bmx b/mod/pub.mod/directx.mod/dd.bmx new file mode 100644 index 0000000..943612d --- /dev/null +++ b/mod/pub.mod/directx.mod/dd.bmx @@ -0,0 +1,1764 @@ + +Strict + +Import Pub.Win32 + +Const DIRECTDRAW_VERSION=$0700 +Const _FACDD=$876 + +Const FOURCC_DXT1$="DXT1" 'TODO: convert to 32 bit hex +Const FOURCC_DXT2$="DXT2" +Const FOURCC_DXT3$="DXT3" +Const FOURCC_DXT4$="DXT4" + +Const DDENUM_ATTACHEDSECONDARYDEVICES=1 +Const DDENUM_DETACHEDSECONDARYDEVICES=2 +Const DDENUM_NONDISPLAYDEVICES=4 + +Const REGSTR_KEY_DDHW_DESCRIPTION$="Description" +Const REGSTR_KEY_DDHW_DRIVERNAME$="DriverName" +Const REGSTR_PATH_DDHW$="Hardware\\DirectDrawDrivers" + +Const DDCREATE_HARDWAREONLY=$11 +Const DDCREATE_EMULATIONONLY=$21 + +Const DDSD_CAPS=$1 +Const DDSD_HEIGHT=$2 +Const DDSD_WIDTH=$4 +Const DDSD_PITCH=$8 +Const DDSD_BACKBUFFERCOUNT=$20 +Const DDSD_ZBUFFERBITDEPTH=$40 +Const DDSD_ALPHABITDEPTH=$80 +Const DDSD_LPSURFACE=$800 +Const DDSD_PIXELFORMAT=$1000 +Const DDSD_CKDESTOVERLAY=$2000 +Const DDSD_CKDESTBLT=$4000 +Const DDSD_CKSRCOVERLAY=$8000 +Const DDSD_CKSRCBLT=$10000 +Const DDSD_MIPMAPCOUNT=$20000 +Const DDSD_REFRESHRATE=$40000 +Const DDSD_LINEARSIZE=$80000 +Const DDSD_TEXTURESTAGE=$100000 +Const DDSD_FVF=$200000 +Const DDSD_SRCVBHANDLE=$400000 +Const DDSD_ALL=$7ff9ee + +Const DDOSD_GUID=$1 +Const DDOSD_COMPRESSION_RATIO=$2 +Const DDOSD_SCAPS=$4 +Const DDOSD_OSCAPS=$8 +Const DDOSD_ALL=$f + +Const DDOSDCAPS_OPTCOMPRESSED=$1 +Const DDOSDCAPS_OPTREORDERED=$2 +Const DDOSDCAPS_MONOLITHICMIPMAP=$4 +Const DDOSDCAPS_VALIDSCAPS=$30004800 +Const DDOSDCAPS_VALIDOSCAPS=$7 + +Const DDCOLOR_BRIGHTNESS=$1 +Const DDCOLOR_CONTRAST=$2 +Const DDCOLOR_HUE=$4 +Const DDCOLOR_SATURATION=$8 +Const DDCOLOR_SHARPNESS=$10 +Const DDCOLOR_GAMMA=$20 +Const DDCOLOR_COLORENABLE=$40 +Const DDSCAPS_RESERVED1=$1 +Const DDSCAPS_ALPHA=$2 +Const DDSCAPS_BACKBUFFER=$4 +Const DDSCAPS_COMPLEX=$8 +Const DDSCAPS_FLIP=$10 +Const DDSCAPS_FRONTBUFFER=$20 +Const DDSCAPS_OFFSCREENPLAIN=$40 +Const DDSCAPS_OVERLAY=$80 +Const DDSCAPS_PALETTE=$100 +Const DDSCAPS_PRIMARYSURFACE=$200 +Const DDSCAPS_RESERVED3=$400 +Const DDSCAPS_SYSTEMMEMORY=$800 +Const DDSCAPS_TEXTURE=$1000 +Const DDSCAPS_3DDEVICE=$2000 +Const DDSCAPS_VIDEOMEMORY=$4000 +Const DDSCAPS_VISIBLE=$8000 +Const DDSCAPS_WRITEONLY=$10000 +Const DDSCAPS_ZBUFFER=$20000 +Const DDSCAPS_OWNDC=$40000 +Const DDSCAPS_LIVEVIDEO=$80000 +Const DDSCAPS_HWCODEC=$100000 +Const DDSCAPS_MODEX=$200000 +Const DDSCAPS_MIPMAP=$400000 +Const DDSCAPS_RESERVED2=$800000 +Const DDSCAPS_ALLOCONLOAD=$4000000 +Const DDSCAPS_VIDEOPORT=$8000000 +Const DDSCAPS_LOCALVIDMEM=$10000000 +Const DDSCAPS_NONLOCALVIDMEM=$20000000 +Const DDSCAPS_STANDARDVGAMODE=$40000000 +Const DDSCAPS_OPTIMIZED=$80000000 + +Const DDSCAPS2_HARDWAREDEINTERLACE=$2 +Const DDSCAPS2_HINTDYNAMIC=$4 +Const DDSCAPS2_HINTSTATIC=$8 +Const DDSCAPS2_TEXTUREMANAGE=$10 +Const DDSCAPS2_RESERVED1=$20 +Const DDSCAPS2_RESERVED2=$40 +Const DDSCAPS2_OPAQUE=$80 +Const DDSCAPS2_HINTANTIALIASING=$100 +Const DDSCAPS2_CUBEMAP=$200 +Const DDSCAPS2_CUBEMAP_POSITIVEX=$400 +Const DDSCAPS2_CUBEMAP_NEGATIVEX=$800 +Const DDSCAPS2_CUBEMAP_POSITIVEY=$1000 +Const DDSCAPS2_CUBEMAP_NEGATIVEY=$2000 +Const DDSCAPS2_CUBEMAP_POSITIVEZ=$4000 +Const DDSCAPS2_CUBEMAP_NEGATIVEZ=$8000 +Const DDSCAPS2_CUBEMAP_ALLFACES=DDSCAPS2_CUBEMAP_POSITIVEX|DDSCAPS2_CUBEMAP_NEGATIVEX|DDSCAPS2_CUBEMAP_POSITIVEY|DDSCAPS2_CUBEMAP_NEGATIVEY|DDSCAPS2_CUBEMAP_POSITIVEZ|DDSCAPS2_CUBEMAP_NEGATIVEZ +Const DDSCAPS2_MIPMAPSUBLEVEL=$10000 +Const DDSCAPS2_D3DTEXTUREMANAGE=$20000 +Const DDSCAPS2_DONOTPERSIST=$40000 +Const DDSCAPS2_STEREOSURFACELEFT=$80000 + +Const DDCAPS_3D=$1 +Const DDCAPS_ALIGNBOUNDARYDEST=$2 +Const DDCAPS_ALIGNSIZEDEST=$4 +Const DDCAPS_ALIGNBOUNDARYSRC=$8 +Const DDCAPS_ALIGNSIZESRC=$10 +Const DDCAPS_ALIGNSTRIDE=$20 +Const DDCAPS_BLT=$40 +Const DDCAPS_BLTQUEUE=$80 +Const DDCAPS_BLTFOURCC=$100 +Const DDCAPS_BLTSTRETCH=$200 +Const DDCAPS_GDI=$400 +Const DDCAPS_OVERLAY=$800 +Const DDCAPS_OVERLAYCANTCLIP=$1000 +Const DDCAPS_OVERLAYFOURCC=$2000 +Const DDCAPS_OVERLAYSTRETCH=$4000 +Const DDCAPS_PALETTE=$8000 +Const DDCAPS_PALETTEVSYNC=$10000 +Const DDCAPS_READSCANLINE=$20000 +Const DDCAPS_RESERVED1=$40000 +Const DDCAPS_VBI=$80000 +Const DDCAPS_ZBLTS=$100000 +Const DDCAPS_ZOVERLAYS=$200000 +Const DDCAPS_COLORKEY=$400000 +Const DDCAPS_ALPHA=$800000 +Const DDCAPS_COLORKEYHWASSIST=$1000000 +Const DDCAPS_NOHARDWARE=$2000000 +Const DDCAPS_BLTCOLORFILL=$4000000 +Const DDCAPS_BANKSWITCHED=$8000000 +Const DDCAPS_BLTDEPTHFILL=$10000000 +Const DDCAPS_CANCLIP=$20000000 +Const DDCAPS_CANCLIPSTRETCHED=$40000000 +Const DDCAPS_CANBLTSYSMEM=$80000000 + +Const DDCAPS2_CERTIFIED=$1 +Const DDCAPS2_NO2DDURING3DSCENE=$2 +Const DDCAPS2_VIDEOPORT=$4 +Const DDCAPS2_AUTOFLIPOVERLAY=$8 +Const DDCAPS2_CANBOBINTERLEAVED=$10 +Const DDCAPS2_CANBOBNONINTERLEAVED=$20 +Const DDCAPS2_COLORCONTROLOVERLAY=$40 +Const DDCAPS2_COLORCONTROLPRIMARY=$80 +Const DDCAPS2_CANDROPZ16BIT=$100 +Const DDCAPS2_NONLOCALVIDMEM=$200 +Const DDCAPS2_NONLOCALVIDMEMCAPS=$400 +Const DDCAPS2_NOPAGELOCKREQUIRED=$800 +Const DDCAPS2_WIDESURFACES=$1000 +Const DDCAPS2_CANFLIPODDEVEN=$2000 +Const DDCAPS2_CANBOBHARDWARE=$4000 +Const DDCAPS2_COPYFOURCC=$8000 +Const DDCAPS2_PRIMARYGAMMA=$20000 +Const DDCAPS2_CANRENDERWINDOWED=$80000 +Const DDCAPS2_CANCALIBRATEGAMMA=$100000 +Const DDCAPS2_FLIPINTERVAL=$200000 +Const DDCAPS2_FLIPNOVSYNC=$400000 +Const DDCAPS2_CANMANAGETEXTURE=$800000 +Const DDCAPS2_TEXMANINNONLOCALVIDMEM=$1000000 +Const DDCAPS2_STEREO=$2000000 +Const DDCAPS2_SYSTONONLOCAL_AS_SYSTOLOCAL=$4000000 + +Const DDFXALPHACAPS_BLTALPHAEDGEBLEND=$1 +Const DDFXALPHACAPS_BLTALPHAPIXELS=$2 +Const DDFXALPHACAPS_BLTALPHAPIXELSNEG=$4 +Const DDFXALPHACAPS_BLTALPHASURFACES=$8 +Const DDFXALPHACAPS_BLTALPHASURFACESNEG=$10 +Const DDFXALPHACAPS_OVERLAYALPHAEDGEBLEND=$20 +Const DDFXALPHACAPS_OVERLAYALPHAPIXELS=$40 +Const DDFXALPHACAPS_OVERLAYALPHAPIXELSNEG=$80 +Const DDFXALPHACAPS_OVERLAYALPHASURFACES=$100 +Const DDFXALPHACAPS_OVERLAYALPHASURFACESNEG=$200 + +Const DDFXCAPS_BLTARITHSTRETCHY=$20 +Const DDFXCAPS_BLTARITHSTRETCHYN=$10 +Const DDFXCAPS_BLTMIRRORLEFTRIGHT=$40 +Const DDFXCAPS_BLTMIRRORUPDOWN=$80 +Const DDFXCAPS_BLTROTATION=$100 +Const DDFXCAPS_BLTROTATION90=$200 +Const DDFXCAPS_BLTSHRINKX=$400 +Const DDFXCAPS_BLTSHRINKXN=$800 +Const DDFXCAPS_BLTSHRINKY=$1000 +Const DDFXCAPS_BLTSHRINKYN=$2000 +Const DDFXCAPS_BLTSTRETCHX=$4000 +Const DDFXCAPS_BLTSTRETCHXN=$8000 +Const DDFXCAPS_BLTSTRETCHY=$10000 +Const DDFXCAPS_BLTSTRETCHYN=$20000 +Const DDFXCAPS_OVERLAYARITHSTRETCHY=$40000 +Const DDFXCAPS_OVERLAYARITHSTRETCHYN=$8 +Const DDFXCAPS_OVERLAYSHRINKX=$80000 +Const DDFXCAPS_OVERLAYSHRINKXN=$100000 +Const DDFXCAPS_OVERLAYSHRINKY=$200000 +Const DDFXCAPS_OVERLAYSHRINKYN=$400000 +Const DDFXCAPS_OVERLAYSTRETCHX=$800000 +Const DDFXCAPS_OVERLAYSTRETCHXN=$1000000 +Const DDFXCAPS_OVERLAYSTRETCHY=$2000000 +Const DDFXCAPS_OVERLAYSTRETCHYN=$4000000 +Const DDFXCAPS_OVERLAYMIRRORLEFTRIGHT=$8000000 +Const DDFXCAPS_OVERLAYMIRRORUPDOWN=$10000000 + +Const DDFXCAPS_BLTALPHA=$1 +Const DDFXCAPS_BLTFILTER=DDFXCAPS_BLTARITHSTRETCHY +Const DDFXCAPS_OVERLAYALPHA=$4 +Const DDFXCAPS_OVERLAYFILTER=DDFXCAPS_OVERLAYARITHSTRETCHY +Const DDSVCAPS_RESERVED1=$1 +Const DDSVCAPS_RESERVED2=$2 +Const DDSVCAPS_RESERVED3=$4 +Const DDSVCAPS_RESERVED4=$8 +Const DDSVCAPS_STEREOSEQUENTIAL=$10 + +Const DDPCAPS_4BIT=$1 +Const DDPCAPS_8BITENTRIES=$2 +Const DDPCAPS_8BIT=$4 +Const DDPCAPS_INITIALIZE=$0 +Const DDPCAPS_PRIMARYSURFACE=$10 +Const DDPCAPS_PRIMARYSURFACELEFT=$20 +Const DDPCAPS_ALLOW256=$40 +Const DDPCAPS_VSYNC=$80 +Const DDPCAPS_1BIT=$100 +Const DDPCAPS_2BIT=$200 +Const DDPCAPS_ALPHA=$400 + +Const DDSPD_IUNKNOWNPOINTER=$1 +Const DDSPD_VOLATILE=$2 + +Const DDBD_1=$4000 +Const DDBD_2=$2000 +Const DDBD_4=$1000 +Const DDBD_8=$800 +Const DDBD_16=$400 +Const DDBD_24=$200 +Const DDBD_32=$100 + +Const DDCKEY_COLORSPACE=$1 +Const DDCKEY_DESTBLT=$2 +Const DDCKEY_DESTOVERLAY=$4 +Const DDCKEY_SRCBLT=$8 +Const DDCKEY_SRCOVERLAY=$10 + +Const DDCKEYCAPS_DESTBLT=$1 +Const DDCKEYCAPS_DESTBLTCLRSPACE=$2 +Const DDCKEYCAPS_DESTBLTCLRSPACEYUV=$4 +Const DDCKEYCAPS_DESTBLTYUV=$8 +Const DDCKEYCAPS_DESTOVERLAY=$10 +Const DDCKEYCAPS_DESTOVERLAYCLRSPACE=$20 +Const DDCKEYCAPS_DESTOVERLAYCLRSPACEYUV=$40 +Const DDCKEYCAPS_DESTOVERLAYONEACTIVE=$80 +Const DDCKEYCAPS_DESTOVERLAYYUV=$100 +Const DDCKEYCAPS_SRCBLT=$200 +Const DDCKEYCAPS_SRCBLTCLRSPACE=$400 +Const DDCKEYCAPS_SRCBLTCLRSPACEYUV=$800 +Const DDCKEYCAPS_SRCBLTYUV=$1000 +Const DDCKEYCAPS_SRCOVERLAY=$2000 +Const DDCKEYCAPS_SRCOVERLAYCLRSPACE=$4000 +Const DDCKEYCAPS_SRCOVERLAYCLRSPACEYUV=$8000 +Const DDCKEYCAPS_SRCOVERLAYONEACTIVE=$10000 +Const DDCKEYCAPS_SRCOVERLAYYUV=$20000 +Const DDCKEYCAPS_NOCOSTOVERLAY=$40000 + +Const DDPF_ALPHAPIXELS=$1 +Const DDPF_ALPHA=$2 +Const DDPF_FOURCC=$4 +Const DDPF_PALETTEINDEXED4=$8 +Const DDPF_PALETTEINDEXEDTO8=$10 +Const DDPF_PALETTEINDEXED8=$20 +Const DDPF_RGB=$40 +Const DDPF_COMPRESSED=$80 +Const DDPF_RGBTOYUV=$100 +Const DDPF_YUV=$200 +Const DDPF_ZBUFFER=$400 +Const DDPF_PALETTEINDEXED1=$800 +Const DDPF_PALETTEINDEXED2=$1000 +Const DDPF_ZPIXELS=$2000 +Const DDPF_STENCILBUFFER=$4000 +Const DDPF_ALPHAPREMULT=$8000 +Const DDPF_LUMINANCE=$20000 +Const DDPF_BUMPLUMINANCE=$40000 +Const DDPF_BUMPDUDV=$80000 + + +Const DDENUMSURFACES_ALL=$1 +Const DDENUMSURFACES_MATCH=$2 +Const DDENUMSURFACES_NOMATCH=$4 +Const DDENUMSURFACES_CANBECREATED=$8 +Const DDENUMSURFACES_DOESEXIST=$10 + +Const DDSDM_STANDARDVGAMODE=$1 +Const DDEDM_REFRESHRATES=$1 +Const DDEDM_STANDARDVGAMODES=$2 + +Const DDSCL_FULLSCREEN=$1 +Const DDSCL_ALLOWREBOOT=$2 +Const DDSCL_NOWINDOWCHANGES=$4 +Const DDSCL_NORMAL=$8 +Const DDSCL_EXCLUSIVE=$10 +Const DDSCL_ALLOWMODEX=$40 +Const DDSCL_SETFOCUSWINDOW=$80 +Const DDSCL_SETDEVICEWINDOW=$100 +Const DDSCL_CREATEDEVICEWINDOW=$200 +Const DDSCL_MULTITHREADED=$400 +Const DDSCL_FPUSETUP=$800 +Const DDSCL_FPUPRESERVE=$1000 + +Const DDBLT_ALPHADEST=$1 +Const DDBLT_ALPHADESTCONSTOVERRIDE=$2 +Const DDBLT_ALPHADESTNEG=$4 +Const DDBLT_ALPHADESTSURFACEOVERRIDE=$8 +Const DDBLT_ALPHAEDGEBLEND=$10 +Const DDBLT_ALPHASRC=$20 +Const DDBLT_ALPHASRCCONSTOVERRIDE=$40 +Const DDBLT_ALPHASRCNEG=$80 +Const DDBLT_ALPHASRCSURFACEOVERRIDE=$100 +Const DDBLT_ASYNC=$200 +Const DDBLT_COLORFILL=$400 +Const DDBLT_DDFX=$800 +Const DDBLT_DDROPS=$1000 +Const DDBLT_KEYDEST=$2000 +Const DDBLT_KEYDESTOVERRIDE=$4000 +Const DDBLT_KEYSRC=$8000 +Const DDBLT_KEYSRCOVERRIDE=$10000 +Const DDBLT_ROP=$20000 +Const DDBLT_ROTATIONANGLE=$40000 +Const DDBLT_ZBUFFER=$80000 +Const DDBLT_ZBUFFERDESTCONSTOVERRIDE=$100000 +Const DDBLT_ZBUFFERDESTOVERRIDE=$200000 +Const DDBLT_ZBUFFERSRCCONSTOVERRIDE=$400000 +Const DDBLT_ZBUFFERSRCOVERRIDE=$800000 +Const DDBLT_WAIT=$1000000 +Const DDBLT_DEPTHFILL=$2000000 +Const DDBLT_DONOTWAIT=$8000000 + +Const DDBLTFAST_NOCOLORKEY=$0 +Const DDBLTFAST_SRCCOLORKEY=$1 +Const DDBLTFAST_DESTCOLORKEY=$2 +Const DDBLTFAST_WAIT=$10 +Const DDBLTFAST_DONOTWAIT=$20 + +Const DDFLIP_WAIT=$1 +Const DDFLIP_EVEN=$2 +Const DDFLIP_ODD=$4 +Const DDFLIP_NOVSYNC=$8 +Const DDFLIP_INTERVAL2=$2000000 +Const DDFLIP_INTERVAL3=$3000000 +Const DDFLIP_INTERVAL4=$4000000 +Const DDFLIP_STEREO=$10 +Const DDFLIP_DONOTWAIT=$20 + +Const DDOVER_ALPHADEST=$1 +Const DDOVER_ALPHADESTCONSTOVERRIDE=$2 +Const DDOVER_ALPHADESTNEG=$4 +Const DDOVER_ALPHADESTSURFACEOVERRIDE=$8 +Const DDOVER_ALPHAEDGEBLEND=$10 +Const DDOVER_ALPHASRC=$20 +Const DDOVER_ALPHASRCCONSTOVERRIDE=$40 +Const DDOVER_ALPHASRCNEG=$80 +Const DDOVER_ALPHASRCSURFACEOVERRIDE=$100 +Const DDOVER_HIDE=$200 +Const DDOVER_KEYDEST=$400 +Const DDOVER_KEYDESTOVERRIDE=$800 +Const DDOVER_KEYSRC=$1000 +Const DDOVER_KEYSRCOVERRIDE=$2000 +Const DDOVER_SHOW=$4000 +Const DDOVER_ADDDIRTYRECT=$8000 +Const DDOVER_REFRESHDIRTYRECTS=$10000 +Const DDOVER_REFRESHALL=$20000 +Const DDOVER_DDFX=$80000 +Const DDOVER_AUTOFLIP=$100000 +Const DDOVER_BOB=$200000 +Const DDOVER_OVERRIDEBOBWEAVE=$400000 +Const DDOVER_INTERLEAVED=$800000 +Const DDOVER_BOBHARDWARE=$1000000 +Const DDOVER_ARGBSCALEFACTORS=$2000000 +Const DDOVER_DEGRADEARGBSCALING=$4000000 + +Const DDLOCK_SURFACEMEMORYPTR=$0 +Const DDLOCK_WAIT=$1 +Const DDLOCK_EVENT=$2 +Const DDLOCK_READONLY=$10 +Const DDLOCK_WRITEONLY=$20 +Const DDLOCK_NOSYSLOCK=$800 +Const DDLOCK_NOOVERWRITE=$1000 +Const DDLOCK_DISCARDCONTENTS=$2000 +Const DDLOCK_OKTOSWAP=$2000 +Const DDLOCK_DONOTWAIT=$4000 + +Const DDBLTFX_ARITHSTRETCHY=$1 +Const DDBLTFX_MIRRORLEFTRIGHT=$2 +Const DDBLTFX_MIRRORUPDOWN=$4 +Const DDBLTFX_NOTEARING=$8 +Const DDBLTFX_ROTATE180=$10 +Const DDBLTFX_ROTATE270=$20 +Const DDBLTFX_ROTATE90=$40 +Const DDBLTFX_ZBUFFERRANGE=$80 +Const DDBLTFX_ZBUFFERBASEDEST=$100 + +Const DDOVERFX_ARITHSTRETCHY=$1 +Const DDOVERFX_MIRRORLEFTRIGHT=$2 +Const DDOVERFX_MIRRORUPDOWN=$4 + +Const DDWAITVB_BLOCKBEGIN=$1 +Const DDWAITVB_BLOCKBEGINEVENT=$2 +Const DDWAITVB_BLOCKEND=$4 + +Const DDGFS_CANFLIP=$1 +Const DDGFS_ISFLIPDONE=$2 + +Const DDGBS_CANBLT=$1 +Const DDGBS_ISBLTDONE=$2 + +Const DDENUMOVERLAYZ_BACKTOFRONT=$0 +Const DDENUMOVERLAYZ_FRONTTOBACK=$1 + +Const DDOVERZ_SENDTOFRONT=$1 +Const DDOVERZ_SENDTOBACK=$1 +Const DDOVERZ_MOVEFORWARD=$2 +Const DDOVERZ_MOVEBACKWARD=$3 +Const DDOVERZ_INSERTINFRONTOF=$4 +Const DDOVERZ_INSERTINBACKOF=$5 + +Const DDSGR_CALIBRATE=1 +Const DDSMT_ISTESTREQUIRED=1 + +Const DDEM_MODEPASSED=1 +Const DDEM_MODEFAILED=2 + +Const DD_OK=0 +Const DD_FALSE=1 + +Const DDENUMRET_CANCEL=0 +Const DDENUMRET_OK=1 + +' DIRECTDRAW ERRORS + +Const DDERR=$88760000 + +Const DDERR_ALREADYINITIALIZED=DDERR+5 +Const DDERR_CANNOTATTACHSURFACE=DDERR+10 +Const DDERR_CANNOTDETACHSURFACE=DDERR+20 +Const DDERR_CURRENTLYNOTAVAIL=DDERR+40 +Const DDERR_EXCEPTION=DDERR+55 + +Const DDERR_GENERIC=$80004005 'E_FAIL + +Const DDERR_HEIGHTALIGN=DDERR+90 +Const DDERR_INCOMPATIBLEPRIMARY=DDERR+95 +Const DDERR_INVALIDCAPS=DDERR+100 +Const DDERR_INVALIDCLIPLIST=DDERR+110 +Const DDERR_INVALIDMODE=DDERR+120 +Const DDERR_INVALIDOBJECT=DDERR+130 +Const DDERR_INVALIDPARAMS=$80070057 ' E_INVALIDARG + +Const DDERR_INVALIDPIXELFORMAT=DDERR+145 +Const DDERR_INVALIDRECT=DDERR+150 +Const DDERR_LOCKEDSURFACES=DDERR+160 +Const DDERR_NO3D=DDERR+170 +Const DDERR_NOALPHAHW=DDERR+180 +Const DDERR_NOSTEREOHARDWARE=DDERR+181 +Const DDERR_NOSURFACELEFT=DDERR+182 +Const DDERR_NOCLIPLIST=DDERR+205 +Const DDERR_NOCOLORCONVHW=DDERR+210 +Const DDERR_NOCOOPERATIVELEVELSET=DDERR+212 +Const DDERR_NOCOLORKEY=DDERR+215 +Const DDERR_NOCOLORKEYHW=DDERR+220 +Const DDERR_NODIRECTDRAWSUPPORT=DDERR+222 +Const DDERR_NOEXCLUSIVEMODE=DDERR+225 +Const DDERR_NOFLIPHW=DDERR+230 +Const DDERR_NOGDI=DDERR+240 +Const DDERR_NOMIRRORHW=DDERR+250 +Const DDERR_NOTFOUND=DDERR+255 +Const DDERR_NOOVERLAYHW=DDERR+260 +Const DDERR_OVERLAPPINGRECTS=DDERR+270 +Const DDERR_NORASTEROPHW=DDERR+280 +Const DDERR_NOROTATIONHW=DDERR+290 +Const DDERR_NOSTRETCHHW=DDERR+310 +Const DDERR_NOT4BITCOLOR=DDERR+316 +Const DDERR_NOT4BITCOLORINDEX=DDERR+317 +Const DDERR_NOT8BITCOLOR=DDERR+320 +Const DDERR_NOTEXTUREHW=DDERR+330 +Const DDERR_NOVSYNCHW=DDERR+335 +Const DDERR_NOZBUFFERHW=DDERR+340 +Const DDERR_NOZOVERLAYHW=DDERR+350 +Const DDERR_OUTOFCAPS=DDERR+360 +Const DDERR_OUTOFMEMORY=$8007000E ' E_OUTOFMEMORY +Const DDERR_OUTOFVIDEOMEMORY=DDERR+380 +Const DDERR_OVERLAYCANTCLIP=DDERR+382 +Const DDERR_OVERLAYCOLORKEYONLYONEACTIVE=DDERR+384 +Const DDERR_PALETTEBUSY=DDERR+387 +Const DDERR_COLORKEYNOTSET=DDERR+400 +Const DDERR_SURFACEALREADYATTACHED=DDERR+410 +Const DDERR_SURFACEALREADYDEPENDENT=DDERR+420 +Const DDERR_SURFACEBUSY=DDERR+430 +Const DDERR_CANTLOCKSURFACE=DDERR+435 +Const DDERR_SURFACEISOBSCURED=DDERR+440 +Const DDERR_SURFACELOST=DDERR+450 +Const DDERR_SURFACENOTATTACHED=DDERR+460 +Const DDERR_TOOBIGHEIGHT=DDERR+470 +Const DDERR_TOOBIGSIZE=DDERR+480 +Const DDERR_TOOBIGWIDTH=DDERR+490 +Const DDERR_UNSUPPORTED=$80000001 ' E_NOTIMPL +Const DDERR_UNSUPPORTEDFORMAT=DDERR+510 +Const DDERR_UNSUPPORTEDMASK=DDERR+520 +Const DDERR_INVALIDSTREAM=DDERR+521 +Const DDERR_VERTICALBLANKINPROGRESS=DDERR+537 +Const DDERR_WASSTILLDRAWING=DDERR+540 +Const DDERR_DDSCAPSCOMPLEXREQUIRED=DDERR+542 +Const DDERR_XALIGN=DDERR+560 +Const DDERR_INVALIDDIRECTDRAWGUID=DDERR+561 +Const DDERR_DIRECTDRAWALREADYCREATED=DDERR+562 +Const DDERR_NODIRECTDRAWHW=DDERR+563 +Const DDERR_PRIMARYSURFACEALREADYEXISTS=DDERR+564 +Const DDERR_NOEMULATION=DDERR+565 +Const DDERR_REGIONTOOSMALL=DDERR+566 +Const DDERR_CLIPPERISUSINGHWND=DDERR+567 +Const DDERR_NOCLIPPERATTACHED=DDERR+568 +Const DDERR_NOHWND=DDERR+569 +Const DDERR_HWNDSUBCLASSED=DDERR+570 +Const DDERR_HWNDALREADYSET=DDERR+571 +Const DDERR_NOPALETTEATTACHED=DDERR+572 +Const DDERR_NOPALETTEHW=DDERR+573 +Const DDERR_BLTFASTCANTCLIP=DDERR+574 +Const DDERR_NOBLTHW=DDERR+575 +Const DDERR_NODDROPSHW=DDERR+576 +Const DDERR_OVERLAYNOTVISIBLE=DDERR+577 +Const DDERR_NOOVERLAYDEST=DDERR+578 +Const DDERR_INVALIDPOSITION=DDERR+579 +Const DDERR_NOTAOVERLAYSURFACE=DDERR+580 +Const DDERR_EXCLUSIVEMODEALREADYSET=DDERR+581 +Const DDERR_NOTFLIPPABLE=DDERR+582 +Const DDERR_CANTDUPLICATE=DDERR+583 +Const DDERR_NOTLOCKED=DDERR+584 +Const DDERR_CANTCREATEDC=DDERR+585 +Const DDERR_NODC=DDERR+586 +Const DDERR_WRONGMODE=DDERR+587 +Const DDERR_IMPLICITLYCREATED=DDERR+588 +Const DDERR_NOTPALETTIZED=DDERR+589 +Const DDERR_UNSUPPORTEDMODE=DDERR+590 +Const DDERR_NOMIPMAPHW=DDERR+591 +Const DDERR_INVALIDSURFACETYPE=DDERR+592 +Const DDERR_NOOPTIMIZEHW=DDERR+600 +Const DDERR_NOTLOADED=DDERR+601 +Const DDERR_NOFOCUSWINDOW=DDERR+602 +Const DDERR_NOTONMIPMAPSUBLEVEL=DDERR+603 +Const DDERR_DCALREADYCREATED=DDERR+620 +Const DDERR_NONONLOCALVIDMEM=DDERR+630 +Const DDERR_CANTPAGELOCK=DDERR+640 +Const DDERR_CANTPAGEUNLOCK=DDERR+660 +Const DDERR_NOTPAGELOCKED=DDERR+680 +Const DDERR_MOREDATA=DDERR+690 +Const DDERR_EXPIRED=DDERR+691 +Const DDERR_TESTFINISHED=DDERR+692 +Const DDERR_NEWMODE=DDERR+693 +Const DDERR_D3DNOTINITIALIZED=DDERR+694 +Const DDERR_VIDEONOTACTIVE=DDERR+695 +Const DDERR_NOMONITORINFORMATION=DDERR+696 +Const DDERR_NODRIVERSUPPORT=DDERR+697 +Const DDERR_DEVICEDOESNTOWNSURFACE=DDERR+699 +Const DDERR_NOTINITIALIZED=$800401F0 ' CO_E_NOTINITIALIZED + +Rem + +DEFINE_GUID( CLSID_DirectDraw,=$D7B70EE0,0x4340,0x11CF,0xB0,0x63,0x00,0x20,0xAF,0xC2,0xCD,0x35 ); +DEFINE_GUID( CLSID_DirectDraw7,=$3c305196,0x50db,0x11d3,0x9c,0xfe,0x00,0xc0,0x4f,0xd9,0x30,0xc5 ); +DEFINE_GUID( CLSID_DirectDrawClipper,=$593817A0,0x7DB3,0x11CF,0xA2,0xDE,0x00,0xAA,0x00,0xb9,0x33,0x56 ); +DEFINE_GUID( IID_IDirectDraw,=$6C14DB80,0xA733,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60 ); +DEFINE_GUID( IID_IDirectDraw2,=$B3A6F3E0,0x2B43,0x11CF,0xA2,0xDE,0x00,0xAA,0x00,0xB9,0x33,0x56 ); +DEFINE_GUID( IID_IDirectDraw4,=$9c59509a,0x39bd,0x11d1,0x8c,0x4a,0x00,0xc0,0x4f,0xd9,0x30,0xc5 ); +DEFINE_GUID( IID_IDirectDraw7,=$15e65ec0,0x3b9c,0x11d2,0xb9,0x2f,0x00,0x60,0x97,0x97,0xea,0x5b ); +DEFINE_GUID( IID_IDirectDrawSurface,=$6C14DB81,0xA733,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60 ); +DEFINE_GUID( IID_IDirectDrawSurface2,=$57805885,0x6eec,0x11cf,0x94,0x41,0xa8,0x23,0x03,0xc1,0x0e,0x27 ); +DEFINE_GUID( IID_IDirectDrawSurface3,=$DA044E00,0x69B2,0x11D0,0xA1,0xD5,0x00,0xAA,0x00,0xB8,0xDF,0xBB ); +DEFINE_GUID( IID_IDirectDrawSurface4,=$B2B8630,0xAD35,0x11D0,0x8E,0xA6,0x00,0x60,0x97,0x97,0xEA,0x5B ); +DEFINE_GUID( IID_IDirectDrawSurface7,=$6675a80,0x3b9b,0x11d2,0xb9,0x2f,0x00,0x60,0x97,0x97,0xea,0x5b ); + +DEFINE_GUID( IID_IDirectDrawPalette,=$6C14DB84,0xA733,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60 ); +DEFINE_GUID( IID_IDirectDrawClipper,=$6C14DB85,0xA733,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60 ); +DEFINE_GUID( IID_IDirectDrawColorControl,=$4B9F0EE0,0x0D7E,0x11D0,0x9B,0x06,0x00,0xA0,0xC9,0x03,0xA3,0xB8 ); +DEFINE_GUID( IID_IDirectDrawGammaControl,=$69C11C3E,0xB46B,0x11D1,0xAD,0x7A,0x00,0xC0,0x4F,0xC2,0x9B,0x4E ); + +typedef BOOL (FAR PASCAL * LPDDENUMCALLBACKA)(GUID FAR *, LPSTR, LPSTR, LPVOID); +typedef BOOL (FAR PASCAL * LPDDENUMCALLBACKW)(GUID FAR *, LPWSTR, LPWSTR, LPVOID); +Extern HRESULT WINAPI DirectDrawEnumerateW( LPDDENUMCALLBACKW lpCallback, LPVOID lpContext ); +Extern HRESULT WINAPI DirectDrawEnumerateA( LPDDENUMCALLBACKA lpCallback, LPVOID lpContext ); + +EndRem + +Type DDSURFACEDESC + Field dwSize' size of the DDSURFACEDESC structure + Field dwFlags' determines what fields are valid + Field dwHeight' height of surface To be created + Field dwWidth' width of Input surface +' union Field dwLinearSize' Formless late-allocated optimized surface size + Field lPitch' distance To start of Next line (Return value only) + Field dwBackBufferCount' number of back buffers requested +'union Field dwMipMapCount' number of mip-map levels requested +'union Field dwZBufferBitDepth' depth of Z buffer requested + Field dwRefreshRate' refresh rate (used when display mode is described) + Field dwAlphaBitDepth' depth of alpha buffer requested + Field dwReserved' reserved + Field lpSurface:Byte Ptr' pointer To the associated surface memory +' DDCOLORKEYs + Field ddckCKDestOverlay:Long' color key For destination overlay use + Field ddckCKDestBlt:Long' color key For destination blt use + Field ddckCKSrcOverlay:Long' color key For source overlay use + Field ddckCKSrcBlt:Long' color key For source blt use +' DDPIXELFORMAT + Field ddpf_dwSize' size of structure + Field ddpf_dwFlags' pixel format flags + Field ddpf_dwFourCC' (FOURCC code) + Field ddpf_BitCount + Field ddpf_BitMask_0 + Field ddpf_BitMask_1 + Field ddpf_BitMask_2 + Field ddpf_BitMask_3 +' DDSCAPS + Field ddsCaps' direct draw surface capabilities +End Type + +Type DDSURFACEDESC2 + Field dwSize' size of the DDSURFACEDESC structure + Field dwFlags' determines what fields are valid + Field dwHeight' height of surface To be created + Field dwWidth' width of Input surface +' union dwLinearSize + Field lPitch' distance To start of Next line (Return value only) + Field dwBackBufferCount' number of back buffers requested +' union dwRefreshRate,dwSrcVBHandle + Field dwMipMapCount' number of mip-map levels requestde + Field dwAlphaBitDepth' depth of alpha buffer requested + Field dwReserved' reserved + Field lpSurface:Byte Ptr' pointer To the associated surface memory +' union dwEmptyFaceColor +' DDCOLORKEYs + Field dddckCKDestOverlay:Long' color key For destination overlay use + Field ddckCKDestBlt:Long' color key For destination blt use + Field ddckCKSrcOverlay:Long' color key For source overlay use + Field ddckCKSrcBlt:Long' color key For source blt use +' union dwFVF +' DDPFPIXELFORMAT + Field ddpf_dwSize' size of structure + Field ddpf_dwFlags' pixel format flags + Field ddpf_dwFourCC' (FOURCC code) + Field ddpf_BitCount + Field ddpf_BitMask_0 + Field ddpf_BitMask_1 + Field ddpf_BitMask_2 + Field ddpf_BitMask_3 +' DDSCAPS2 + Field ddsCaps' capabilities of surface wanted + Field ddsCaps2 + Field ddsCaps3 + Field ddsCaps4 + Field dwTextureStage' stage in multitexture cascade +End Type + +Type DDOPTSURFACEDESC + Field dwSize' size of the DDOPTSURFACEDESC structure + Field dwFlags' determines what fields are valid +' DDSCAPS2 + Field ddSCaps_0' Common caps like: Memory Type + Field ddsCaps_1 + Field ddsCaps_2 + Field ddsCaps_3 + Field ddOSCaps' Common caps like: Memory Type +' GUID + Field guid_0' Compression technique GUID + Field guid_1 + Field guid_2 + Field guid_3 + Field dwCompressionRatio' Compression ratio +End Type + +Type DDCOLORCONTROL + Field dwSize + Field dwFlags + Field lBrightness + Field lContrast + Field lHue + Field lSaturation + Field lSharpness + Field lGamma + Field lColorEnable + Field dwReserved1 +End Type + +Type DDARGB + Field blue:Byte,green:Byte,red:Byte,alpha:Byte +End Type + +Type DDRGBA + Field red:Byte,green:Byte,blue:Byte,alpha:Byte +End Type + +Type DDCOLORKEY + Field dwColorSpaceLowValue ' low boundary of color space that is to be treated as Color Key, inclusive + Field dwColorSpaceHighValue ' high boundary of color space that is to be treated as Color Key, inclusive +End Type + +Type DDBLTFX + Field dwSize' size of structure + Field dwDDFX' FX operations + Field dwROP' Win32 raster operations + Field dwDDROP' Raster operations New For DirectDraw + Field dwRotationAngle' Rotation angle For blt + Field dwZBufferOpCode' ZBuffer compares + Field dwZBufferLow' Low limit of Z buffer + Field dwZBufferHigh' High limit of Z buffer + Field dwZBufferBaseDest' Destination base value + Field dwZDestConstBitDepth' Bit depth used To specify Z constant For destination +' union LPDIRECTDRAWSURFACE lpDDSZBufferDest + Field dwZDestConst' Constant To use as Z buffer For dest + Field dwZSrcConstBitDepth' Bit depth used To specify Z constant For source +' union LPDIRECTDRAWSURFACE lpDDSZBufferSrc + Field dwZSrcConst' Constant To use as Z buffer For src + Field dwAlphaEdgeBlendBitDepth' Bit depth used To specify constant For alpha edge blend + Field dwAlphaEdgeBlend' Alpha For edge blending + Field dwReserved + Field dwAlphaDestConstBitDepth' Bit depth used To specify alpha constant For destination +' union LPDIRECTDRAWSURFACE lpDDSAlphaDest + Field dwAlphaDestConst' Constant To use as Alpha Channel + Field dwAlphaSrcConstBitDepth' Bit depth used To specify alpha constant For source +' union LPDIRECTDRAWSURFACE lpDDSAlphaSrc + Field dwAlphaSrcConst' Constant To use as Alpha Channel +' union dwFillDepth,dwFillPixel,LPDIRECTDRAWSURFACE lpDDSPattern + Field dwFillColor' color in RGB Or Palettized +' DDCOLORKEYs + Field ddckDestColorkeyLo,ddckDestColorkeyHi ' DestColorkey override + Field ddckSrcColorkeyLo,ddckSrcColorkeyHi ' SrcColorkey override +End Type + +Type DDSCAPS + Field dwCaps ' capabilities of surface wanted +End Type + +Type DDOSCAPS + Field dwCaps ' capabilities of surface wanted +End Type + +Type DDSCAPSEX + Field dwCaps2 + Field dwCaps3 + Field dwCaps4 +End Type + +Type DDSCAPS2 + Field dwCaps' capabilities of surface wanted + Field dwCaps2 + Field dwCaps3 + Field dwCaps4 +End Type + +Const DD_ROP_SPACE=(256/32) ' space required To store ROP array + +Type DDCAPS_DX1 + Field dwSize' size of the DDDRIVERCAPS structure + Field dwCaps' driver specific capabilities + Field dwCaps2' more driver specific capabilites + Field dwCKeyCaps' color key capabilities of the surface + Field dwFXCaps' driver specific stretching And effects capabilites + Field dwFXAlphaCaps' alpha driver specific capabilities + Field dwPalCaps' palette capabilities + Field dwSVCaps' stereo vision capabilities + Field dwAlphaBltConstBitDepths' DDBD_2,4,8 + Field dwAlphaBltPixelBitDepths' DDBD_1,2,4,8 + Field dwAlphaBltSurfaceBitDepths' DDBD_1,2,4,8 + Field dwAlphaOverlayConstBitDepths' DDBD_2,4,8 + Field dwAlphaOverlayPixelBitDepths' DDBD_1,2,4,8 + Field dwAlphaOverlaySurfaceBitDepths' DDBD_1,2,4,8 + Field dwZBufferBitDepths' DDBD_8,16,24,32 + Field dwVidMemTotal' total amount of video memory + Field dwVidMemFree' amount of free video memory + Field dwMaxVisibleOverlays' maximum number of visible overlays + Field dwCurrVisibleOverlays' current number of visible overlays + Field dwNumFourCCCodes' number of four cc codes + Field dwAlignBoundarySrc' source rectangle alignment + Field dwAlignSizeSrc' source rectangle Byte size + Field dwAlignBoundaryDest' dest rectangle alignment + Field dwAlignSizeDest' dest rectangle Byte size + Field dwAlignStrideAlign' stride alignment + Field dwRops_0' ROPS supported + Field dwRops_1 + Field dwRops_2 + Field dwRops_3 + Field dwRops_4 + Field dwRops_5 + Field dwRops_6 + Field dwRops_7 +' DDSCAPS + Field ddsCaps' DDSCAPS structure has all the general capabilities + Field dwMinOverlayStretch' minimum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 + Field dwMaxOverlayStretch' maximum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 + Field dwMinLiveVideoStretch' OBSOLETE! This Field remains For compatability reasons only + Field dwMaxLiveVideoStretch' OBSOLETE! This Field remains For compatability reasons only + Field dwMinHwCodecStretch' OBSOLETE! This Field remains For compatability reasons only + Field dwMaxHwCodecStretch' OBSOLETE! This Field remains For compatability reasons only + Field dwReserved1' reserved + Field dwReserved2' reserved + Field dwReserved3' reserved +End Type + +Type DDCAPS_DX3 + Field dwSize' size of the DDDRIVERCAPS structure + Field dwCaps' driver specific capabilities + Field dwCaps2' more driver specific capabilites + Field dwCKeyCaps' color key capabilities of the surface + Field dwFXCaps' driver specific stretching And effects capabilites + Field dwFXAlphaCaps' alpha driver specific capabilities + Field dwPalCaps' palette capabilities + Field dwSVCaps' stereo vision capabilities + Field dwAlphaBltConstBitDepths' DDBD_2,4,8 + Field dwAlphaBltPixelBitDepths' DDBD_1,2,4,8 + Field dwAlphaBltSurfaceBitDepths' DDBD_1,2,4,8 + Field dwAlphaOverlayConstBitDepths' DDBD_2,4,8 + Field dwAlphaOverlayPixelBitDepths' DDBD_1,2,4,8 + Field dwAlphaOverlaySurfaceBitDepths' DDBD_1,2,4,8 + Field dwZBufferBitDepths' DDBD_8,16,24,32 + Field dwVidMemTotal' total amount of video memory + Field dwVidMemFree' amount of free video memory + Field dwMaxVisibleOverlays' maximum number of visible overlays + Field dwCurrVisibleOverlays' current number of visible overlays + Field dwNumFourCCCodes' number of four cc codes + Field dwAlignBoundarySrc' source rectangle alignment + Field dwAlignSizeSrc' source rectangle Byte size + Field dwAlignBoundaryDest' dest rectangle alignment + Field dwAlignSizeDest' dest rectangle Byte size + Field dwAlignStrideAlign' stride alignment + Field dwRops_0' ROPS supported + Field dwRops_1 + Field dwRops_2 + Field dwRops_3 + Field dwRops_4 + Field dwRops_5 + Field dwRops_6 + Field dwRops_7 +' DDSCAPS + Field ddsCaps' DDSCAPS structure has all the general capabilities + Field dwMinOverlayStretch' minimum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 + Field dwMaxOverlayStretch' maximum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 + Field dwMinLiveVideoStretch' minimum live video stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 + Field dwMaxLiveVideoStretch' maximum live video stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 + Field dwMinHwCodecStretch' minimum hardware codec stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 + Field dwMaxHwCodecStretch' maximum hardware codec stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 + Field dwReserved1' reserved + Field dwReserved2' reserved + Field dwReserved3' reserved + Field dwSVBCaps' driver specific capabilities For System->Vmem blts + Field dwSVBCKeyCaps' driver color key capabilities For System->Vmem blts + Field dwSVBFXCaps' driver FX capabilities For System->Vmem blts + Field dwSVBRops_0 ' ROPS supported For System->Vmem blts + Field dwSVBRops_1 + Field dwSVBRops_2 + Field dwSVBRops_3 + Field dwSVBRops_4 + Field dwSVBRops_5 + Field dwSVBRops_6 + Field dwSVBRops_7 + Field dwVSBCaps' driver specific capabilities For Vmem->System blts + Field dwVSBCKeyCaps' driver color key capabilities For Vmem->System blts + Field dwVSBFXCaps' driver FX capabilities For Vmem->System blts + Field dwVSBRops_0' ROPS supported For Vmem->System blts + Field dwVSBRops_1 + Field dwVSBRops_2 + Field dwVSBRops_3 + Field dwVSBRops_4 + Field dwVSBRops_5 + Field dwVSBRops_6 + Field dwVSBRops_7 + Field dwSSBCaps' driver specific capabilities For System->System blts + Field dwSSBCKeyCaps' driver color key capabilities For System->System blts + Field dwSSBFXCaps' driver FX capabilities For System->System blts + Field dwSSBRops_0' ROPS supported For System->System blts + Field dwSSBRops_1 + Field dwSSBRops_2 + Field dwSSBRops_3 + Field dwSSBRops_4 + Field dwSSBRops_5 + Field dwSSBRops_6 + Field dwSSBRops_7 + Field dwReserved4' reserved + Field dwReserved5' reserved + Field dwReserved6' reserved +End Type + +Type DDCAPS_DX5 + Field dwSize' size of the DDDRIVERCAPS structure + Field dwCaps' driver specific capabilities + Field dwCaps2' more driver specific capabilites + Field dwCKeyCaps' color key capabilities of the surface + Field dwFXCaps' driver specific stretching And effects capabilites + Field dwFXAlphaCaps' alpha driver specific capabilities + Field dwPalCaps' palette capabilities + Field dwSVCaps' stereo vision capabilities + Field dwAlphaBltConstBitDepths' DDBD_2,4,8 + Field dwAlphaBltPixelBitDepths' DDBD_1,2,4,8 + Field dwAlphaBltSurfaceBitDepths' DDBD_1,2,4,8 + Field dwAlphaOverlayConstBitDepths' DDBD_2,4,8 + Field dwAlphaOverlayPixelBitDepths' DDBD_1,2,4,8 + Field dwAlphaOverlaySurfaceBitDepths' DDBD_1,2,4,8 + Field dwZBufferBitDepths' DDBD_8,16,24,32 + Field dwVidMemTotal' total amount of video memory + Field dwVidMemFree' amount of free video memory + Field dwMaxVisibleOverlays' maximum number of visible overlays + Field dwCurrVisibleOverlays' current number of visible overlays + Field dwNumFourCCCodes' number of four cc codes + Field dwAlignBoundarySrc' source rectangle alignment + Field dwAlignSizeSrc' source rectangle Byte size + Field dwAlignBoundaryDest' dest rectangle alignment + Field dwAlignSizeDest' dest rectangle Byte size + Field dwAlignStrideAlign' stride alignment + Field dwRops_0' ROPS supported + Field dwRops_1 + Field dwRops_2 + Field dwRops_3 + Field dwRops_4 + Field dwRops_5 + Field dwRops_6 + Field dwRops_7 +' DDSCAPS + Field ddsCaps' DDSCAPS structure has all the general capabilities + Field dwMinOverlayStretch' minimum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 + Field dwMaxOverlayStretch' maximum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 + Field dwMinLiveVideoStretch' minimum live video stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 + Field dwMaxLiveVideoStretch' maximum live video stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 + Field dwMinHwCodecStretch' minimum hardware codec stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 + Field dwMaxHwCodecStretch' maximum hardware codec stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 + Field dwReserved1' reserved + Field dwReserved2' reserved + Field dwReserved3' reserved + Field dwSVBCaps' driver specific capabilities For System->Vmem blts + Field dwSVBCKeyCaps' driver color key capabilities For System->Vmem blts + Field dwSVBFXCaps' driver FX capabilities For System->Vmem blts + Field dwSVBRops_0' ROPS supported For System->Vmem blts + Field dwSVBRops_1 + Field dwSVBRops_2 + Field dwSVBRops_3 + Field dwSVBRops_4 + Field dwSVBRops_5 + Field dwSVBRops_6 + Field dwSVBRops_7 + Field dwVSBCaps' driver specific capabilities For Vmem->System blts + Field dwVSBCKeyCaps' driver color key capabilities For Vmem->System blts + Field dwVSBFXCaps' driver FX capabilities For Vmem->System blts + Field dwVSBRops_0' ROPS supported For Vmem->System blts + Field dwVSBRops_1 + Field dwVSBRops_2 + Field dwVSBRops_3 + Field dwVSBRops_4 + Field dwVSBRops_5 + Field dwVSBRops_6 + Field dwVSBRops_7 + Field dwSSBCaps' driver specific capabilities For System->System blts + Field dwSSBCKeyCaps' driver color key capabilities For System->System blts + Field dwSSBFXCaps' driver FX capabilities For System->System blts + Field dwSSBRops_0' ROPS supported For System->System blts + Field dwSSBRops_1 + Field dwSSBRops_2 + Field dwSSBRops_3 + Field dwSSBRops_4 + Field dwSSBRops_5 + Field dwSSBRops_6 + Field dwSSBRops_7 +' Members added For DX5: + Field dwMaxVideoPorts' maximum number of usable video ports + Field dwCurrVideoPorts' current number of video ports used + Field dwSVBCaps2' more driver specific capabilities For System->Vmem blts + Field dwNLVBCaps' driver specific capabilities For non-Local->Local vidmem blts + Field dwNLVBCaps2' more driver specific capabilities non-Local->Local vidmem blts + Field dwNLVBCKeyCaps' driver color key capabilities For non-Local->Local vidmem blts + Field dwNLVBFXCaps' driver FX capabilities For non-Local->Local blts + Field dwNLVBRops_0' ROPS supported For non-Local->Local blts + Field dwNLVBRops_1 + Field dwNLVBRops_2 + Field dwNLVBRops_3 + Field dwNLVBRops_4 + Field dwNLVBRops_5 + Field dwNLVBRops_6 + Field dwNLVBRops_7 +End Type + +Type DDCAPS_DX6 + Field dwSize' size of the DDDRIVERCAPS structure + Field dwCaps' driver specific capabilities + Field dwCaps2' more driver specific capabilites + Field dwCKeyCaps' color key capabilities of the surface + Field dwFXCaps' driver specific stretching And effects capabilites + Field dwFXAlphaCaps' alpha caps + Field dwPalCaps' palette capabilities + Field dwSVCaps' stereo vision capabilities + Field dwAlphaBltConstBitDepths' DDBD_2,4,8 + Field dwAlphaBltPixelBitDepths' DDBD_1,2,4,8 + Field dwAlphaBltSurfaceBitDepths' DDBD_1,2,4,8 + Field dwAlphaOverlayConstBitDepths' DDBD_2,4,8 + Field dwAlphaOverlayPixelBitDepths' DDBD_1,2,4,8 + Field dwAlphaOverlaySurfaceBitDepths' DDBD_1,2,4,8 + Field dwZBufferBitDepths' DDBD_8,16,24,32 + Field dwVidMemTotal' total amount of video memory + Field dwVidMemFree' amount of free video memory + Field dwMaxVisibleOverlays' maximum number of visible overlays + Field dwCurrVisibleOverlays' current number of visible overlays + Field dwNumFourCCCodes' number of four cc codes + Field dwAlignBoundarySrc' source rectangle alignment + Field dwAlignSizeSrc' source rectangle Byte size + Field dwAlignBoundaryDest' dest rectangle alignment + Field dwAlignSizeDest' dest rectangle Byte size + Field dwAlignStrideAlign' stride alignment + Field dwRops_0' ROPS supported + Field dwRops_1 + Field dwRops_2 + Field dwRops_3 + Field dwRops_4 + Field dwRops_5 + Field dwRops_6 + Field dwRops_7 +' DDSCAPS + Field ddsOldCaps' Was DDSCAPS ddsCaps. ddsCaps is of Type DDSCAPS2 For DX6 + Field dwMinOverlayStretch' minimum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 + Field dwMaxOverlayStretch' maximum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 + Field dwMinLiveVideoStretch' minimum live video stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 + Field dwMaxLiveVideoStretch' maximum live video stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 + Field dwMinHwCodecStretch' minimum hardware codec stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 + Field dwMaxHwCodecStretch' maximum hardware codec stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 + Field dwReserved1' reserved + Field dwReserved2' reserved + Field dwReserved3' reserved + Field dwSVBCaps' driver specific capabilities For System->Vmem blts + Field dwSVBCKeyCaps' driver color key capabilities For System->Vmem blts + Field dwSVBFXCaps' driver FX capabilities For System->Vmem blts + Field dwSVBRops_0' ROPS supported for System->Vmem blts + Field dwSVBRops_1 + Field dwSVBRops_2 + Field dwSVBRops_3 + Field dwSVBRops_4 + Field dwSVBRops_5 + Field dwSVBRops_6 + Field dwSVBRops_7 + Field dwVSBCaps' driver specific capabilities For Vmem->System blts + Field dwVSBCKeyCaps' driver color key capabilities For Vmem->System blts + Field dwVSBFXCaps' driver FX capabilities For Vmem->System blts + Field dwVSBRops_0' ROPS supported for Vmem->System blts + Field dwVSBRops_1 + Field dwVSBRops_2 + Field dwVSBRops_3 + Field dwVSBRops_4 + Field dwVSBRops_5 + Field dwVSBRops_6 + Field dwVSBRops_7 + Field dwSSBCaps' driver specific capabilities For System->System blts + Field dwSSBCKeyCaps' driver color key capabilities For System->System blts + Field dwSSBFXCaps' driver FX capabilities For System->System blts + Field dwSSBRops_0' ROPS supported for System->System blts + Field dwSSBRops_1 + Field dwSSBRops_2 + Field dwSSBRops_3 + Field dwSSBRops_4 + Field dwSSBRops_5 + Field dwSSBRops_6 + Field dwSSBRops_7 + Field dwMaxVideoPorts' maximum number of usable video ports + Field dwCurrVideoPorts' current number of video ports used + Field dwSVBCaps2' more driver specific capabilities For System->Vmem blts + Field dwNLVBCaps' driver specific capabilities For non-Local->Local vidmem blts + Field dwNLVBCaps2' more driver specific capabilities non-Local->Local vidmem blts + Field dwNLVBCKeyCaps' driver color key capabilities For non-Local->Local vidmem blts + Field dwNLVBFXCaps' driver FX capabilities For non-Local->Local blts + Field dwNLVBRops_0' ROPS supported For non-Local->Local blts + Field dwNLVBRops_1 + Field dwNLVBRops_2 + Field dwNLVBRops_3 + Field dwNLVBRops_4 + Field dwNLVBRops_5 + Field dwNLVBRops_6 + Field dwNLVBRops_7 +' Members added For DX6 Release +' DDSCAPS2 + Field ddsCaps_0' Surface Caps + Field ddsCaps_1 + Field ddsCaps_2 + Field ddsCaps_3 +End Type + +Type DDCAPS_DX7 + Field dwSize' size of the DDDRIVERCAPS structure + Field dwCaps' driver specific capabilities + Field dwCaps2' more driver specific capabilites + Field dwCKeyCaps' color key capabilities of the surface + Field dwFXCaps' driver specific stretching And effects capabilites + Field dwFXAlphaCaps' alpha driver specific capabilities + Field dwPalCaps' palette capabilities + Field dwSVCaps' stereo vision capabilities + Field dwAlphaBltConstBitDepths' DDBD_2,4,8 + Field dwAlphaBltPixelBitDepths' DDBD_1,2,4,8 + Field dwAlphaBltSurfaceBitDepths' DDBD_1,2,4,8 + Field dwAlphaOverlayConstBitDepths' DDBD_2,4,8 + Field dwAlphaOverlayPixelBitDepths' DDBD_1,2,4,8 + Field dwAlphaOverlaySurfaceBitDepths' DDBD_1,2,4,8 + Field dwZBufferBitDepths' DDBD_8,16,24,32 + Field dwVidMemTotal' total amount of video memory + Field dwVidMemFree' amount of free video memory + Field dwMaxVisibleOverlays' maximum number of visible overlays + Field dwCurrVisibleOverlays' current number of visible overlays + Field dwNumFourCCCodes' number of four cc codes + Field dwAlignBoundarySrc' source rectangle alignment + Field dwAlignSizeSrc' source rectangle Byte size + Field dwAlignBoundaryDest' dest rectangle alignment + Field dwAlignSizeDest' dest rectangle Byte size + Field dwAlignStrideAlign' stride alignment + Field dwRops_0' ROPS supported + Field dwRops_1 + Field dwRops_2 + Field dwRops_3 + Field dwRops_4 + Field dwRops_5 + Field dwRops_6 + Field dwRops_7 +' DDSCAPS + Field ddsOldCaps' Was DDSCAPS ddsCaps. ddsCaps is of Type DDSCAPS2 For DX6 + Field dwMinOverlayStretch' minimum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 + Field dwMaxOverlayStretch' maximum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 + Field dwMinLiveVideoStretch' minimum live video stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 + Field dwMaxLiveVideoStretch' maximum live video stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 + Field dwMinHwCodecStretch' minimum hardware codec stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 + Field dwMaxHwCodecStretch' maximum hardware codec stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 + Field dwReserved1' reserved + Field dwReserved2' reserved + Field dwReserved3' reserved + Field dwSVBCaps' driver specific capabilities For System->Vmem blts + Field dwSVBCKeyCaps' driver color key capabilities For System->Vmem blts + Field dwSVBFXCaps' driver FX capabilities For System->Vmem blts + Field dwSVBRops_0' ROPS supported For System->Vmem blts + Field dwSVBRops_1 + Field dwSVBRops_2 + Field dwSVBRops_3 + Field dwSVBRops_4 + Field dwSVBRops_5 + Field dwSVBRops_6 + Field dwSVBRops_7 + Field dwVSBCaps' driver specific capabilities For Vmem->System blts + Field dwVSBCKeyCaps' driver color key capabilities For Vmem->System blts + Field dwVSBFXCaps' driver FX capabilities For Vmem->System blts + Field dwVSBRops_0' ROPS supported For Vmem->System blts + Field dwVSBRops_1 + Field dwVSBRops_2 + Field dwVSBRops_3 + Field dwVSBRops_4 + Field dwVSBRops_5 + Field dwVSBRops_6 + Field dwVSBRops_7 + Field dwSSBCaps' driver specific capabilities For System->System blts + Field dwSSBCKeyCaps' driver color key capabilities For System->System blts + Field dwSSBFXCaps' driver FX capabilities For System->System blts + Field dwSSBRops_0' ROPS supported For System->System blts + Field dwSSBRops_1 + Field dwSSBRops_2 + Field dwSSBRops_3 + Field dwSSBRops_4 + Field dwSSBRops_5 + Field dwSSBRops_6 + Field dwSSBRops_7 + Field dwMaxVideoPorts' maximum number of usable video ports + Field dwCurrVideoPorts' current number of video ports used + Field dwSVBCaps2' more driver specific capabilities For System->Vmem blts + Field dwNLVBCaps' driver specific capabilities For non-Local->Local vidmem blts + Field dwNLVBCaps2' more driver specific capabilities non-Local->Local vidmem blts + Field dwNLVBCKeyCaps' driver color key capabilities For non-Local->Local vidmem blts + Field dwNLVBFXCaps' driver FX capabilities For non-Local->Local blts + Field dwNLVBRops_0' ROPS supported For non-Local->Local blts + Field dwNLVBRops_1 + Field dwNLVBRops_2 + Field dwNLVBRops_3 + Field dwNLVBRops_4 + Field dwNLVBRops_5 + Field dwNLVBRops_6 + Field dwNLVBRops_7 + ' Members added For DX6 Release +' DDSCAPS2 + Field ddsCaps_0' Surface Caps + Field ddsCaps_1 + Field ddsCaps_2 + Field ddsCaps_3 +End Type + +Type DDPIXELFORMAT + Field dwSize' size of structure + Field dwFlags' pixel format flags + Field dwFourCC' (FOURCC code) + Field BitCount + Field BitMask_0 + Field BitMask_1 + Field BitMask_2 + Field BitMask_3 +End Type + +Type DDOVERLAYFX + Field dwSize' size of structure + Field dwAlphaEdgeBlendBitDepth' Bit depth used To specify constant For alpha edge blend + Field dwAlphaEdgeBlend' Constant To use as alpha For edge blend + Field dwReserved + Field dwAlphaDestConstBitDepth' Bit depth used To specify alpha constant For destination +' union LPDIRECTDRAWSURFACE lpDDSAlphaDest + Field dwAlphaDestConst' Constant To use as alpha channel For dest + Field dwAlphaSrcConstBitDepth' Bit depth used To specify alpha constant For source +' union LPDIRECTDRAWSURFACE lpDDSAlphaSrc + Field dwAlphaSrcConst' Constant To use as alpha channel For src +' DDCOLORKEYs + Field dckDestColorkey:Long' DestColorkey override + Field dckSrcColorkey:Long' DestColorkey override + Field dwDDFX' Overlay FX + Field dwFlags' flags +End Type + +Rem +Type DDBLTBATCH + LPRECT lprDest + LPDIRECTDRAWSURFACE lpDDSSrc + LPRECT lprSrc + Field dwFlags + LPDDBLTFX lpDDBltFx; +End Type + +Type DDGAMMARAMP + WORD red[256]; + WORD green[256]; + WORD blue[256]; +End Type + +Const MAX_DDDEVICEID_STRING=512 + +Type tagDDDEVICEIDENTIFIER + char szDriver[MAX_DDDEVICEID_STRING]; + char szDescription[MAX_DDDEVICEID_STRING]; + LARGE_INTEGER liDriverVersion; /* Defined For applications And other 32 bit components */ + Field dwVendorId; + Field dwDeviceId; + Field dwSubSysId; + Field dwRevision; + GUID guidDeviceIdentifier; +End Type + +Type tagDDDEVICEIDENTIFIER2 + char szDriver[MAX_DDDEVICEID_STRING]; + char szDescription[MAX_DDDEVICEID_STRING]; + LARGE_INTEGER liDriverVersion; /* Defined For applications And other 32 bit components */ + Field dwVendorId; + Field dwDeviceId; + Field dwSubSysId; + Field dwRevision; + GUID guidDeviceIdentifier; + Field dwWHQLLevel; +End Type +endrem + +'Const DDGDI_GETHOSTIDENTIFIER=$1 +'typedef DWORD (FAR PASCAL *LPCLIPPERCALLBACK)(LPDIRECTDRAWCLIPPER lpDDClipper, HWND hWnd, DWORD code, LPVOID lpContext ); +'typedef DWORD (FAR PASCAL *LPSURFACESTREAMINGCALLBACK)(DWORD); + +Extern "win32" + +Type IDirectDraw Extends IUnknown + Method Compact() + Method CreateClipper() + Method CreatePalette() + Method CreateSurface(surfacedesc:Byte Ptr,surf:IDirectDrawSurface Ptr,outer:Byte Ptr) + Method DuplicateSurface() + Method EnumDisplayModes( flags,surf:Byte Ptr,context:Object,callback(surf:Byte Ptr,context:Object)) 'surf:DDSurfaceDesc + Method EnumSurfaces() + Method FlipToGDISurface() + Method GetCaps( driverCaps:Byte Ptr,helCaps:Byte Ptr ) + Method GetDisplayMode() + Method GetFourCCCodes() + Method GetGDISurface() + Method GetMonitorFrequency() + Method GetScanLine() + Method GetVerticalBlankStatus() + Method Initialize() + Method RestoreDisplayMode() + Method SetCooperativeLevel(hwnd,flags) + Method SetDisplayMode(width,height,bpp) + Method WaitForVerticalBlank(flags,event) +Rem + STDMETHOD(Compact)(THIS) PURE; + STDMETHOD(CreateClipper)(THIS_ DWORD, LPDIRECTDRAWCLIPPER FAR*, IUnknown FAR * ) PURE; + STDMETHOD(CreatePalette)(THIS_ DWORD, LPPALETTEENTRY, LPDIRECTDRAWPALETTE FAR*, IUnknown FAR * ) PURE; + STDMETHOD(CreateSurface)(THIS_ LPDDSURFACEDESC, LPDIRECTDRAWSURFACE FAR *, IUnknown FAR *) PURE; + STDMETHOD(DuplicateSurface)( THIS_ LPDIRECTDRAWSURFACE, LPDIRECTDRAWSURFACE FAR * ) PURE; + STDMETHOD(EnumDisplayModes)( THIS_ DWORD, LPDDSURFACEDESC, LPVOID, LPDDENUMMODESCALLBACK ) PURE; + STDMETHOD(EnumSurfaces)(THIS_ DWORD, LPDDSURFACEDESC, LPVOID,LPDDENUMSURFACESCALLBACK ) PURE; + STDMETHOD(FlipToGDISurface)(THIS) PURE; + STDMETHOD(GetCaps)( THIS_ LPDDCAPS, LPDDCAPS) PURE; + STDMETHOD(GetDisplayMode)( THIS_ LPDDSURFACEDESC) PURE; + STDMETHOD(GetFourCCCodes)(THIS_ LPDWORD, LPDWORD ) PURE; + STDMETHOD(GetGDISurface)(THIS_ LPDIRECTDRAWSURFACE FAR *) PURE; + STDMETHOD(GetMonitorFrequency)(THIS_ LPDWORD) PURE; + STDMETHOD(GetScanLine)(THIS_ LPDWORD) PURE; + STDMETHOD(GetVerticalBlankStatus)(THIS_ LPBOOL ) PURE; + STDMETHOD(Initialize)(THIS_ GUID FAR *) PURE; + STDMETHOD(RestoreDisplayMode)(THIS) PURE; + STDMETHOD(SetCooperativeLevel)(THIS_ HWND, DWORD) PURE; + STDMETHOD(SetDisplayMode)(THIS_ DWORD, DWORD,DWORD) PURE; + STDMETHOD(WaitForVerticalBlank)(THIS_ DWORD, HANDLE ) PURE; +End Rem +End Type + +Type IDirectDraw2 Extends IUnknown + +Rem + STDMETHOD(Compact)(THIS) PURE; + STDMETHOD(CreateClipper)(THIS_ DWORD, LPDIRECTDRAWCLIPPER FAR*, IUnknown FAR * ) PURE; + STDMETHOD(CreatePalette)(THIS_ DWORD, LPPALETTEENTRY, LPDIRECTDRAWPALETTE FAR*, IUnknown FAR * ) PURE; + STDMETHOD(CreateSurface)(THIS_ LPDDSURFACEDESC, LPDIRECTDRAWSURFACE FAR *, IUnknown FAR *) PURE; + STDMETHOD(DuplicateSurface)( THIS_ LPDIRECTDRAWSURFACE, LPDIRECTDRAWSURFACE FAR * ) PURE; + STDMETHOD(EnumDisplayModes)( THIS_ DWORD, LPDDSURFACEDESC, LPVOID, LPDDENUMMODESCALLBACK ) PURE; + STDMETHOD(EnumSurfaces)(THIS_ DWORD, LPDDSURFACEDESC, LPVOID,LPDDENUMSURFACESCALLBACK ) PURE; + STDMETHOD(FlipToGDISurface)(THIS) PURE; + STDMETHOD(GetCaps)( THIS_ LPDDCAPS, LPDDCAPS) PURE; + STDMETHOD(GetDisplayMode)( THIS_ LPDDSURFACEDESC) PURE; + STDMETHOD(GetFourCCCodes)(THIS_ LPDWORD, LPDWORD ) PURE; + STDMETHOD(GetGDISurface)(THIS_ LPDIRECTDRAWSURFACE FAR *) PURE; + STDMETHOD(GetMonitorFrequency)(THIS_ LPDWORD) PURE; + STDMETHOD(GetScanLine)(THIS_ LPDWORD) PURE; + STDMETHOD(GetVerticalBlankStatus)(THIS_ LPBOOL ) PURE; + STDMETHOD(Initialize)(THIS_ GUID FAR *) PURE; + STDMETHOD(RestoreDisplayMode)(THIS) PURE; + STDMETHOD(SetCooperativeLevel)(THIS_ HWND, DWORD) PURE; + STDMETHOD(SetDisplayMode)(THIS_ DWORD, DWORD,DWORD, DWORD, DWORD) PURE; + STDMETHOD(WaitForVerticalBlank)(THIS_ DWORD, HANDLE ) PURE; + ' Added in the v2 interface + STDMETHOD(GetAvailableVidMem)(THIS_ LPDDSCAPS, LPDWORD, LPDWORD) PURE; +End Rem +End Type + +Type IDirectDraw4 Extends IUnknown +Rem + STDMETHOD(Compact)(THIS) PURE; + STDMETHOD(CreateClipper)(THIS_ DWORD, LPDIRECTDRAWCLIPPER FAR*, IUnknown FAR * ) PURE; + STDMETHOD(CreatePalette)(THIS_ DWORD, LPPALETTEENTRY, LPDIRECTDRAWPALETTE FAR*, IUnknown FAR * ) PURE; + STDMETHOD(CreateSurface)(THIS_ LPDDSURFACEDESC2, LPDIRECTDRAWSURFACE4 FAR *, IUnknown FAR *) PURE; + STDMETHOD(DuplicateSurface)( THIS_ LPDIRECTDRAWSURFACE4, LPDIRECTDRAWSURFACE4 FAR * ) PURE; + STDMETHOD(EnumDisplayModes)( THIS_ DWORD, LPDDSURFACEDESC2, LPVOID, LPDDENUMMODESCALLBACK2 ) PURE; + STDMETHOD(EnumSurfaces)(THIS_ DWORD, LPDDSURFACEDESC2, LPVOID,LPDDENUMSURFACESCALLBACK2 ) PURE; + STDMETHOD(FlipToGDISurface)(THIS) PURE; + STDMETHOD(GetCaps)( THIS_ LPDDCAPS, LPDDCAPS) PURE; + STDMETHOD(GetDisplayMode)( THIS_ LPDDSURFACEDESC2) PURE; + STDMETHOD(GetFourCCCodes)(THIS_ LPDWORD, LPDWORD ) PURE; + STDMETHOD(GetGDISurface)(THIS_ LPDIRECTDRAWSURFACE4 FAR *) PURE; + STDMETHOD(GetMonitorFrequency)(THIS_ LPDWORD) PURE; + STDMETHOD(GetScanLine)(THIS_ LPDWORD) PURE; + STDMETHOD(GetVerticalBlankStatus)(THIS_ LPBOOL ) PURE; + STDMETHOD(Initialize)(THIS_ GUID FAR *) PURE; + STDMETHOD(RestoreDisplayMode)(THIS) PURE; + STDMETHOD(SetCooperativeLevel)(THIS_ HWND, DWORD) PURE; + STDMETHOD(SetDisplayMode)(THIS_ DWORD, DWORD,DWORD, DWORD, DWORD) PURE; + STDMETHOD(WaitForVerticalBlank)(THIS_ DWORD, HANDLE ) PURE; +' /*** Added in the v2 interface ***/ + STDMETHOD(GetAvailableVidMem)(THIS_ LPDDSCAPS2, LPDWORD, LPDWORD) PURE; +' /*** Added in the V4 Interface ***/ + STDMETHOD(GetSurfaceFromDC) (THIS_ HDC, LPDIRECTDRAWSURFACE4 *) PURE; + STDMETHOD(RestoreAllSurfaces)(THIS) PURE; + STDMETHOD(TestCooperativeLevel)(THIS) PURE; + STDMETHOD(GetDeviceIdentifier)(THIS_ LPDDDEVICEIDENTIFIER, DWORD ) PURE; +End Rem +End Type + +Type IDirectDraw7 Extends IUnknown + Method Compact() + Method CreateClipper(flags,clipper:Byte Ptr,outer:Byte Ptr) + Method CreatePalette() + Method CreateSurface(surfdesc2:Byte Ptr,surf:IDirectDrawSurface7 Ptr,outer:Byte Ptr) + Method DuplicateSurface() + Method EnumDisplayModes(flags,surfdesc2:Byte Ptr,context:Object,callback(surfdesc2:Byte Ptr,context:Object)) 'surf:DDSurfaceDesc + Method EnumSurfaces() + Method FlipToGDISurface() + Method GetCaps( driverCaps:Byte Ptr,helCaps:Byte Ptr ) + Method GetDisplayMode() + Method GetFourCCCodes() + Method GetGDISurface() + Method GetMonitorFrequency() + Method GetScanLine() + Method GetVerticalBlankStatus() + Method Initialize() + Method RestoreDisplayMode() + Method SetCooperativeLevel(hwnd,flags) + Method SetDisplayMode(width,height,bpp,rate,flags) + Method WaitForVerticalBlank(flags,event) + + Method GetAvailableVidMem(Caps:Byte Ptr, Total:Int Ptr, Free: Int Ptr) + Method GetSurfaceFromDC(HDC :Int, surf:IDirectDrawSurface7) + Method RestoreAllSurfaces() + Method TestCooperativeLevel() + + + +Rem + STDMETHOD(Compact)(THIS) PURE; + STDMETHOD(CreateClipper)(THIS_ DWORD, LPDIRECTDRAWCLIPPER FAR*, IUnknown FAR * ) PURE; + STDMETHOD(CreatePalette)(THIS_ DWORD, LPPALETTEENTRY, LPDIRECTDRAWPALETTE FAR*, IUnknown FAR * ) PURE; + STDMETHOD(CreateSurface)(THIS_ LPDDSURFACEDESC2, LPDIRECTDRAWSURFACE7 FAR *, IUnknown FAR *) PURE; + STDMETHOD(DuplicateSurface)( THIS_ LPDIRECTDRAWSURFACE7, LPDIRECTDRAWSURFACE7 FAR * ) PURE; + STDMETHOD(EnumDisplayModes)( THIS_ DWORD, LPDDSURFACEDESC2, LPVOID, LPDDENUMMODESCALLBACK2 ) PURE; + STDMETHOD(EnumSurfaces)(THIS_ DWORD, LPDDSURFACEDESC2, LPVOID,LPDDENUMSURFACESCALLBACK7 ) PURE; + STDMETHOD(FlipToGDISurface)(THIS) PURE; + STDMETHOD(GetCaps)( THIS_ LPDDCAPS, LPDDCAPS) PURE; + STDMETHOD(GetDisplayMode)( THIS_ LPDDSURFACEDESC2) PURE; + STDMETHOD(GetFourCCCodes)(THIS_ LPDWORD, LPDWORD ) PURE; + STDMETHOD(GetGDISurface)(THIS_ LPDIRECTDRAWSURFACE7 FAR *) PURE; + STDMETHOD(GetMonitorFrequency)(THIS_ LPDWORD) PURE; + STDMETHOD(GetScanLine)(THIS_ LPDWORD) PURE; + STDMETHOD(GetVerticalBlankStatus)(THIS_ LPBOOL ) PURE; + STDMETHOD(Initialize)(THIS_ GUID FAR *) PURE; + STDMETHOD(RestoreDisplayMode)(THIS) PURE; + STDMETHOD(SetCooperativeLevel)(THIS_ HWND, DWORD) PURE; + STDMETHOD(SetDisplayMode)(THIS_ DWORD, DWORD,DWORD, DWORD, DWORD) PURE; + STDMETHOD(WaitForVerticalBlank)(THIS_ DWORD, HANDLE ) PURE; +' /*** Added in the v2 interface ***/ + STDMETHOD(GetAvailableVidMem)(THIS_ LPDDSCAPS2, LPDWORD, LPDWORD) PURE; +' /*** Added in the V4 Interface ***/ + STDMETHOD(GetSurfaceFromDC) (THIS_ HDC, LPDIRECTDRAWSURFACE7 *) PURE; + STDMETHOD(RestoreAllSurfaces)(THIS) PURE; + STDMETHOD(TestCooperativeLevel)(THIS) PURE; + STDMETHOD(GetDeviceIdentifier)(THIS_ LPDDDEVICEIDENTIFIER2, DWORD ) PURE; + STDMETHOD(StartModeTest)(THIS_ LPSIZE, DWORD, DWORD ) PURE; + STDMETHOD(EvaluateMode)(THIS_ DWORD, DWORD * ) PURE; +End Rem +End Type + +Type IDirectDrawPalette Extends IUnknown +Rem + STDMETHOD(GetCaps)(THIS_ LPDWORD) PURE; + STDMETHOD(GetEntries)(THIS_ DWORD,DWORD,DWORD,LPPALETTEENTRY) PURE; + STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW, DWORD, LPPALETTEENTRY) PURE; + STDMETHOD(SetEntries)(THIS_ DWORD,DWORD,DWORD,LPPALETTEENTRY) PURE; +End Rem +End Type + +Type IDirectDrawClipper Extends IUnknown + Method GetClipList(rect:Byte Ptr,region:Byte Ptr,flags) + Method GetHWnd() + Method Initialize() + Method IsClipListChanged() + Method SetClipList() + Method SetHWnd(flags,hwnd) +Rem + STDMETHOD(GetClipList)(THIS_ LPRECT, LPRGNDATA, LPDWORD) PURE; + STDMETHOD(GetHWnd)(THIS_ HWND FAR *) PURE; + STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW, DWORD) PURE; + STDMETHOD(IsClipListChanged)(THIS_ BOOL FAR *) PURE; + STDMETHOD(SetClipList)(THIS_ LPRGNDATA,DWORD) PURE; + STDMETHOD(SetHWnd)(THIS_ DWORD, HWND ) PURE; +End Rem +End Type + +Type IDirectDrawSurface Extends IUnknown + Method AddAttachedSurface(surface:Byte Ptr) + Method AddOverlayDirtyRect(rect:Byte Ptr) + Method Blt(destrect:Byte Ptr,srcsurface:Byte Ptr,srcrect:Byte Ptr,flags,blitfx:Byte Ptr) + Method BltBatch(bltbatch:Byte Ptr,count,flags) + Method BltFast(x,y,srcsurface:Byte Ptr,srcrect:Byte Ptr,trans) + Method DeleteAttachedSurface(flags,surface:Byte Ptr) + Method EnumAttachedSurfaces() + Method EnumOverlayZOrders() + Method Flip(target:Byte Ptr,flags) + Method GetAttachedSurface(caps:Byte Ptr,surface:IDirectDrawSurface Ptr) +Rem + STDMETHOD(AddAttachedSurface)(THIS_ LPDIRECTDRAWSURFACE) PURE; + STDMETHOD(AddOverlayDirtyRect)(THIS_ LPRECT) PURE; + STDMETHOD(Blt)(THIS_ LPRECT,LPDIRECTDRAWSURFACE, LPRECT,DWORD, LPDDBLTFX) PURE; + STDMETHOD(BltBatch)(THIS_ LPDDBLTBATCH, DWORD, DWORD ) PURE; + STDMETHOD(BltFast)(THIS_ DWORD,DWORD,LPDIRECTDRAWSURFACE, LPRECT,DWORD) PURE; + STDMETHOD(DeleteAttachedSurface)(THIS_ DWORD,LPDIRECTDRAWSURFACE) PURE; + STDMETHOD(EnumAttachedSurfaces)(THIS_ LPVOID,LPDDENUMSURFACESCALLBACK) PURE; + STDMETHOD(EnumOverlayZOrders)(THIS_ DWORD,LPVOID,LPDDENUMSURFACESCALLBACK) PURE; + STDMETHOD(Flip)(THIS_ LPDIRECTDRAWSURFACE, DWORD) PURE; + STDMETHOD(GetAttachedSurface)(THIS_ LPDDSCAPS, LPDIRECTDRAWSURFACE FAR *) PURE; + STDMETHOD(GetBltStatus)(THIS_ DWORD) PURE; + STDMETHOD(GetCaps)(THIS_ LPDDSCAPS) PURE; + STDMETHOD(GetClipper)(THIS_ LPDIRECTDRAWCLIPPER FAR*) PURE; + STDMETHOD(GetColorKey)(THIS_ DWORD, LPDDCOLORKEY) PURE; + STDMETHOD(GetDC)(THIS_ HDC FAR *) PURE; + STDMETHOD(GetFlipStatus)(THIS_ DWORD) PURE; + STDMETHOD(GetOverlayPosition)(THIS_ LPLONG, LPLONG ) PURE; + STDMETHOD(GetPalette)(THIS_ LPDIRECTDRAWPALETTE FAR*) PURE; + STDMETHOD(GetPixelFormat)(THIS_ LPDDPIXELFORMAT) PURE; + STDMETHOD(GetSurfaceDesc)(THIS_ LPDDSURFACEDESC) PURE; + STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW, LPDDSURFACEDESC) PURE; + STDMETHOD(IsLost)(THIS) PURE; + STDMETHOD(Lock)(THIS_ LPRECT,LPDDSURFACEDESC,DWORD,HANDLE) PURE; + STDMETHOD(ReleaseDC)(THIS_ HDC) PURE; + STDMETHOD(Restore)(THIS) PURE; + STDMETHOD(SetClipper)(THIS_ LPDIRECTDRAWCLIPPER) PURE; + STDMETHOD(SetColorKey)(THIS_ DWORD, LPDDCOLORKEY) PURE; + STDMETHOD(SetOverlayPosition)(THIS_ Long, Long ) PURE; + STDMETHOD(SetPalette)(THIS_ LPDIRECTDRAWPALETTE) PURE; + STDMETHOD(Unlock)(THIS_ LPVOID) PURE; + STDMETHOD(UpdateOverlay)(THIS_ LPRECT, LPDIRECTDRAWSURFACE,LPRECT,DWORD, LPDDOVERLAYFX) PURE; + STDMETHOD(UpdateOverlayDisplay)(THIS_ DWORD) PURE; + STDMETHOD(UpdateOverlayZOrder)(THIS_ DWORD, LPDIRECTDRAWSURFACE) PURE; +End Rem +End Type + +Type IDirectDrawSUrface2 Extends IUnknown +Rem + STDMETHOD(AddAttachedSurface)(THIS_ LPDIRECTDRAWSURFACE2) PURE; + STDMETHOD(AddOverlayDirtyRect)(THIS_ LPRECT) PURE; + STDMETHOD(Blt)(THIS_ LPRECT,LPDIRECTDRAWSURFACE2, LPRECT,DWORD, LPDDBLTFX) PURE; + STDMETHOD(BltBatch)(THIS_ LPDDBLTBATCH, DWORD, DWORD ) PURE; + STDMETHOD(BltFast)(THIS_ DWORD,DWORD,LPDIRECTDRAWSURFACE2, LPRECT,DWORD) PURE; + STDMETHOD(DeleteAttachedSurface)(THIS_ DWORD,LPDIRECTDRAWSURFACE2) PURE; + STDMETHOD(EnumAttachedSurfaces)(THIS_ LPVOID,LPDDENUMSURFACESCALLBACK) PURE; + STDMETHOD(EnumOverlayZOrders)(THIS_ DWORD,LPVOID,LPDDENUMSURFACESCALLBACK) PURE; + STDMETHOD(Flip)(THIS_ LPDIRECTDRAWSURFACE2, DWORD) PURE; + STDMETHOD(GetAttachedSurface)(THIS_ LPDDSCAPS, LPDIRECTDRAWSURFACE2 FAR *) PURE; + STDMETHOD(GetBltStatus)(THIS_ DWORD) PURE; + STDMETHOD(GetCaps)(THIS_ LPDDSCAPS) PURE; + STDMETHOD(GetClipper)(THIS_ LPDIRECTDRAWCLIPPER FAR*) PURE; + STDMETHOD(GetColorKey)(THIS_ DWORD, LPDDCOLORKEY) PURE; + STDMETHOD(GetDC)(THIS_ HDC FAR *) PURE; + STDMETHOD(GetFlipStatus)(THIS_ DWORD) PURE; + STDMETHOD(GetOverlayPosition)(THIS_ LPLONG, LPLONG ) PURE; + STDMETHOD(GetPalette)(THIS_ LPDIRECTDRAWPALETTE FAR*) PURE; + STDMETHOD(GetPixelFormat)(THIS_ LPDDPIXELFORMAT) PURE; + STDMETHOD(GetSurfaceDesc)(THIS_ LPDDSURFACEDESC) PURE; + STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW, LPDDSURFACEDESC) PURE; + STDMETHOD(IsLost)(THIS) PURE; + STDMETHOD(Lock)(THIS_ LPRECT,LPDDSURFACEDESC,DWORD,HANDLE) PURE; + STDMETHOD(ReleaseDC)(THIS_ HDC) PURE; + STDMETHOD(Restore)(THIS) PURE; + STDMETHOD(SetClipper)(THIS_ LPDIRECTDRAWCLIPPER) PURE; + STDMETHOD(SetColorKey)(THIS_ DWORD, LPDDCOLORKEY) PURE; + STDMETHOD(SetOverlayPosition)(THIS_ Long, Long ) PURE; + STDMETHOD(SetPalette)(THIS_ LPDIRECTDRAWPALETTE) PURE; + STDMETHOD(Unlock)(THIS_ LPVOID) PURE; + STDMETHOD(UpdateOverlay)(THIS_ LPRECT, LPDIRECTDRAWSURFACE2,LPRECT,DWORD, LPDDOVERLAYFX) PURE; + STDMETHOD(UpdateOverlayDisplay)(THIS_ DWORD) PURE; + STDMETHOD(UpdateOverlayZOrder)(THIS_ DWORD, LPDIRECTDRAWSURFACE2) PURE; +' /*** Added in the v2 interface ***/ + STDMETHOD(GetDDInterface)(THIS_ LPVOID FAR *) PURE; + STDMETHOD(PageLock)(THIS_ DWORD) PURE; + STDMETHOD(PageUnlock)(THIS_ DWORD) PURE; +End Rem +End Type + +Type IDirectDrawSurface3 Extends IUnknown +Rem + STDMETHOD(AddAttachedSurface)(THIS_ LPDIRECTDRAWSURFACE3) PURE; + STDMETHOD(AddOverlayDirtyRect)(THIS_ LPRECT) PURE; + STDMETHOD(Blt)(THIS_ LPRECT,LPDIRECTDRAWSURFACE3, LPRECT,DWORD, LPDDBLTFX) PURE; + STDMETHOD(BltBatch)(THIS_ LPDDBLTBATCH, DWORD, DWORD ) PURE; + STDMETHOD(BltFast)(THIS_ DWORD,DWORD,LPDIRECTDRAWSURFACE3, LPRECT,DWORD) PURE; + STDMETHOD(DeleteAttachedSurface)(THIS_ DWORD,LPDIRECTDRAWSURFACE3) PURE; + STDMETHOD(EnumAttachedSurfaces)(THIS_ LPVOID,LPDDENUMSURFACESCALLBACK) PURE; + STDMETHOD(EnumOverlayZOrders)(THIS_ DWORD,LPVOID,LPDDENUMSURFACESCALLBACK) PURE; + STDMETHOD(Flip)(THIS_ LPDIRECTDRAWSURFACE3, DWORD) PURE; + STDMETHOD(GetAttachedSurface)(THIS_ LPDDSCAPS, LPDIRECTDRAWSURFACE3 FAR *) PURE; + STDMETHOD(GetBltStatus)(THIS_ DWORD) PURE; + STDMETHOD(GetCaps)(THIS_ LPDDSCAPS) PURE; + STDMETHOD(GetClipper)(THIS_ LPDIRECTDRAWCLIPPER FAR*) PURE; + STDMETHOD(GetColorKey)(THIS_ DWORD, LPDDCOLORKEY) PURE; + STDMETHOD(GetDC)(THIS_ HDC FAR *) PURE; + STDMETHOD(GetFlipStatus)(THIS_ DWORD) PURE; + STDMETHOD(GetOverlayPosition)(THIS_ LPLONG, LPLONG ) PURE; + STDMETHOD(GetPalette)(THIS_ LPDIRECTDRAWPALETTE FAR*) PURE; + STDMETHOD(GetPixelFormat)(THIS_ LPDDPIXELFORMAT) PURE; + STDMETHOD(GetSurfaceDesc)(THIS_ LPDDSURFACEDESC) PURE; + STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW, LPDDSURFACEDESC) PURE; + STDMETHOD(IsLost)(THIS) PURE; + STDMETHOD(Lock)(THIS_ LPRECT,LPDDSURFACEDESC,DWORD,HANDLE) PURE; + STDMETHOD(ReleaseDC)(THIS_ HDC) PURE; + STDMETHOD(Restore)(THIS) PURE; + STDMETHOD(SetClipper)(THIS_ LPDIRECTDRAWCLIPPER) PURE; + STDMETHOD(SetColorKey)(THIS_ DWORD, LPDDCOLORKEY) PURE; + STDMETHOD(SetOverlayPosition)(THIS_ Long, Long ) PURE; + STDMETHOD(SetPalette)(THIS_ LPDIRECTDRAWPALETTE) PURE; + STDMETHOD(Unlock)(THIS_ LPVOID) PURE; + STDMETHOD(UpdateOverlay)(THIS_ LPRECT, LPDIRECTDRAWSURFACE3,LPRECT,DWORD, LPDDOVERLAYFX) PURE; + STDMETHOD(UpdateOverlayDisplay)(THIS_ DWORD) PURE; + STDMETHOD(UpdateOverlayZOrder)(THIS_ DWORD, LPDIRECTDRAWSURFACE3) PURE; +' /*** Added in the v2 interface ***/ + STDMETHOD(GetDDInterface)(THIS_ LPVOID FAR *) PURE; + STDMETHOD(PageLock)(THIS_ DWORD) PURE; + STDMETHOD(PageUnlock)(THIS_ DWORD) PURE; +' /*** Added in the V3 interface ***/ + STDMETHOD(SetSurfaceDesc)(THIS_ LPDDSURFACEDESC, DWORD) PURE; +End Rem +End Type + +Type IDirectDrawSurface4 Extends IUnknown +Rem + STDMETHOD(AddAttachedSurface)(THIS_ LPDIRECTDRAWSURFACE4) PURE; + STDMETHOD(AddOverlayDirtyRect)(THIS_ LPRECT) PURE; + STDMETHOD(Blt)(THIS_ LPRECT,LPDIRECTDRAWSURFACE4, LPRECT,DWORD, LPDDBLTFX) PURE; + STDMETHOD(BltBatch)(THIS_ LPDDBLTBATCH, DWORD, DWORD ) PURE; + STDMETHOD(BltFast)(THIS_ DWORD,DWORD,LPDIRECTDRAWSURFACE4, LPRECT,DWORD) PURE; + STDMETHOD(DeleteAttachedSurface)(THIS_ DWORD,LPDIRECTDRAWSURFACE4) PURE; + STDMETHOD(EnumAttachedSurfaces)(THIS_ LPVOID,LPDDENUMSURFACESCALLBACK2) PURE; + STDMETHOD(EnumOverlayZOrders)(THIS_ DWORD,LPVOID,LPDDENUMSURFACESCALLBACK2) PURE; + STDMETHOD(Flip)(THIS_ LPDIRECTDRAWSURFACE4, DWORD) PURE; + STDMETHOD(GetAttachedSurface)(THIS_ LPDDSCAPS2, LPDIRECTDRAWSURFACE4 FAR *) PURE; + STDMETHOD(GetBltStatus)(THIS_ DWORD) PURE; + STDMETHOD(GetCaps)(THIS_ LPDDSCAPS2) PURE; + STDMETHOD(GetClipper)(THIS_ LPDIRECTDRAWCLIPPER FAR*) PURE; + STDMETHOD(GetColorKey)(THIS_ DWORD, LPDDCOLORKEY) PURE; + STDMETHOD(GetDC)(THIS_ HDC FAR *) PURE; + STDMETHOD(GetFlipStatus)(THIS_ DWORD) PURE; + STDMETHOD(GetOverlayPosition)(THIS_ LPLONG, LPLONG ) PURE; + STDMETHOD(GetPalette)(THIS_ LPDIRECTDRAWPALETTE FAR*) PURE; + STDMETHOD(GetPixelFormat)(THIS_ LPDDPIXELFORMAT) PURE; + STDMETHOD(GetSurfaceDesc)(THIS_ LPDDSURFACEDESC2) PURE; + STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW, LPDDSURFACEDESC2) PURE; + STDMETHOD(IsLost)(THIS) PURE; + STDMETHOD(Lock)(THIS_ LPRECT,LPDDSURFACEDESC2,DWORD,HANDLE) PURE; + STDMETHOD(ReleaseDC)(THIS_ HDC) PURE; + STDMETHOD(Restore)(THIS) PURE; + STDMETHOD(SetClipper)(THIS_ LPDIRECTDRAWCLIPPER) PURE; + STDMETHOD(SetColorKey)(THIS_ DWORD, LPDDCOLORKEY) PURE; + STDMETHOD(SetOverlayPosition)(THIS_ Long, Long ) PURE; + STDMETHOD(SetPalette)(THIS_ LPDIRECTDRAWPALETTE) PURE; + STDMETHOD(Unlock)(THIS_ LPRECT) PURE; + STDMETHOD(UpdateOverlay)(THIS_ LPRECT, LPDIRECTDRAWSURFACE4,LPRECT,DWORD, LPDDOVERLAYFX) PURE; + STDMETHOD(UpdateOverlayDisplay)(THIS_ DWORD) PURE; + STDMETHOD(UpdateOverlayZOrder)(THIS_ DWORD, LPDIRECTDRAWSURFACE4) PURE; +' /*** Added in the v2 interface ***/ + STDMETHOD(GetDDInterface)(THIS_ LPVOID FAR *) PURE; + STDMETHOD(PageLock)(THIS_ DWORD) PURE; + STDMETHOD(PageUnlock)(THIS_ DWORD) PURE; +' /*** Added in the v3 interface ***/ + STDMETHOD(SetSurfaceDesc)(THIS_ LPDDSURFACEDESC2, DWORD) PURE; +' /*** Added in the v4 interface ***/ + STDMETHOD(SetPrivateData)(THIS_ REFGUID, LPVOID, DWORD, DWORD) PURE; + STDMETHOD(GetPrivateData)(THIS_ REFGUID, LPVOID, LPDWORD) PURE; + STDMETHOD(FreePrivateData)(THIS_ REFGUID) PURE; + STDMETHOD(GetUniquenessValue)(THIS_ LPDWORD) PURE; + STDMETHOD(ChangeUniquenessValue)(THIS) PURE; +End Rem +End Type + +Type IDirectDrawSurface7 Extends IUnknown + Method AddAttachedSurface(surface:Byte Ptr) + Method AddOverlayDirtyRect(rect:Byte Ptr) + Method Blt(destrect:Byte Ptr,srcsurface:Byte Ptr,srcrect:Byte Ptr,flags,blitfx:Byte Ptr) + Method BltBatch(bltbatch:Byte Ptr,count,flags) + Method BltFast(x,y,srcsurface:Byte Ptr,srcrect:Byte Ptr,trans) + Method DeleteAttachedSurface(flags,surface:Byte Ptr) + Method EnumAttachedSurfaces() + Method EnumOverlayZOrders() + Method Flip(target:Byte Ptr,flags) + Method GetAttachedSurface(caps:Byte Ptr,surface:IDirectDrawSurface7 Ptr) + Method GetBltStatus() + Method GetCaps() + Method GetClipper() + Method GetColorKey() + Method GetDC(hdc:Int Ptr) + Method GetFlipStatus() + Method GetOverlayPosition() + Method GetPalette() + Method GetPixelFormat() + Method GetSurfaceDesc(surfdesc:Byte Ptr) + Method Initialize() + Method IsLost() + Method Lock(rect:Byte Ptr,surfacedesc2:Byte Ptr,flags,handle) + Method ReleaseDC(hdc) + Method Restore() + Method SetClipper(clipper:Byte Ptr) + Method SetColorKey() + Method SetOverlayPosition() + Method SetPalette() + Method Unlock(rect:Byte Ptr) + Method UpdateOverlay() + Method UpdateOverlayDisplay() + Method UpdateOverlayZOrder() + Method GetDDInterface(ddinterface:Byte Ptr) + Method PageLock(flags) + Method PageUnlock(flags) +Rem + STDMETHOD(AddAttachedSurface)(THIS_ LPDIRECTDRAWSURFACE7) PURE; + STDMETHOD(AddOverlayDirtyRect)(THIS_ LPRECT) PURE; + STDMETHOD(Blt)(THIS_ LPRECT,LPDIRECTDRAWSURFACE7, LPRECT,DWORD, LPDDBLTFX) PURE; + STDMETHOD(BltBatch)(THIS_ LPDDBLTBATCH, DWORD, DWORD ) PURE; + STDMETHOD(BltFast)(THIS_ DWORD,DWORD,LPDIRECTDRAWSURFACE7, LPRECT,DWORD) PURE; + STDMETHOD(DeleteAttachedSurface)(THIS_ DWORD,LPDIRECTDRAWSURFACE7) PURE; + STDMETHOD(EnumAttachedSurfaces)(THIS_ LPVOID,LPDDENUMSURFACESCALLBACK7) PURE; + STDMETHOD(EnumOverlayZOrders)(THIS_ DWORD,LPVOID,LPDDENUMSURFACESCALLBACK7) PURE; + STDMETHOD(Flip)(THIS_ LPDIRECTDRAWSURFACE7, DWORD) PURE; + STDMETHOD(GetAttachedSurface)(THIS_ LPDDSCAPS2, LPDIRECTDRAWSURFACE7 FAR *) PURE; + STDMETHOD(GetBltStatus)(THIS_ DWORD) PURE; + STDMETHOD(GetCaps)(THIS_ LPDDSCAPS2) PURE; + STDMETHOD(GetClipper)(THIS_ LPDIRECTDRAWCLIPPER FAR*) PURE; + STDMETHOD(GetColorKey)(THIS_ DWORD, LPDDCOLORKEY) PURE; + STDMETHOD(GetDC)(THIS_ HDC FAR *) PURE; + STDMETHOD(GetFlipStatus)(THIS_ DWORD) PURE; + STDMETHOD(GetOverlayPosition)(THIS_ LPLONG, LPLONG ) PURE; + STDMETHOD(GetPalette)(THIS_ LPDIRECTDRAWPALETTE FAR*) PURE; + STDMETHOD(GetPixelFormat)(THIS_ LPDDPIXELFORMAT) PURE; + STDMETHOD(GetSurfaceDesc)(THIS_ LPDDSURFACEDESC2) PURE; + STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW, LPDDSURFACEDESC2) PURE; + STDMETHOD(IsLost)(THIS) PURE; + STDMETHOD(Lock)(THIS_ LPRECT,LPDDSURFACEDESC2,DWORD,HANDLE) PURE; + STDMETHOD(ReleaseDC)(THIS_ HDC) PURE; + STDMETHOD(Restore)(THIS) PURE; + STDMETHOD(SetClipper)(THIS_ LPDIRECTDRAWCLIPPER) PURE; + STDMETHOD(SetColorKey)(THIS_ DWORD, LPDDCOLORKEY) PURE; + STDMETHOD(SetOverlayPosition)(THIS_ Long, Long ) PURE; + STDMETHOD(SetPalette)(THIS_ LPDIRECTDRAWPALETTE) PURE; + STDMETHOD(Unlock)(THIS_ LPRECT) PURE; + STDMETHOD(UpdateOverlay)(THIS_ LPRECT, LPDIRECTDRAWSURFACE7,LPRECT,DWORD, LPDDOVERLAYFX) PURE; + STDMETHOD(UpdateOverlayDisplay)(THIS_ DWORD) PURE; + STDMETHOD(UpdateOverlayZOrder)(THIS_ DWORD, LPDIRECTDRAWSURFACE7) PURE; +' /*** Added in the v2 interface ***/ + STDMETHOD(GetDDInterface)(THIS_ LPVOID FAR *) PURE; + STDMETHOD(PageLock)(THIS_ DWORD) PURE; + STDMETHOD(PageUnlock)(THIS_ DWORD) PURE; +' /*** Added in the v3 interface ***/ + STDMETHOD(SetSurfaceDesc)(THIS_ LPDDSURFACEDESC2, DWORD) PURE; +' /*** Added in the v4 interface ***/ + STDMETHOD(SetPrivateData)(THIS_ REFGUID, LPVOID, DWORD, DWORD) PURE; + STDMETHOD(GetPrivateData)(THIS_ REFGUID, LPVOID, LPDWORD) PURE; + STDMETHOD(FreePrivateData)(THIS_ REFGUID) PURE; + STDMETHOD(GetUniquenessValue)(THIS_ LPDWORD) PURE; + STDMETHOD(ChangeUniquenessValue)(THIS) PURE; +' /*** Moved Texture7 methods here ***/ + STDMETHOD(SetPriority)(THIS_ DWORD) PURE; + STDMETHOD(GetPriority)(THIS_ LPDWORD) PURE; + STDMETHOD(SetLOD)(THIS_ DWORD) PURE; + STDMETHOD(GetLOD)(THIS_ LPDWORD) PURE; +End Rem +End Type + +Type IDirectDrawColorControl Extends IUnknown +Rem +DECLARE_INTERFACE_( IDirectDrawColorControl, IUnknown ) + STDMETHOD(GetColorControls)(THIS_ LPDDCOLORCONTROL) PURE; + STDMETHOD(SetColorControls)(THIS_ LPDDCOLORCONTROL) PURE; +End Rem +End Type + +Type IDirectDrawGammaControl Extends IUnknown +Rem + STDMETHOD(GetGammaRamp)(THIS_ DWORD, LPDDGAMMARAMP) PURE; + STDMETHOD(SetGammaRamp)(THIS_ DWORD, LPDDGAMMARAMP) PURE; +End Rem +End Type + +End Extern + +Global ddLib=LoadLibraryA( "ddraw" ) + +If Not ddLib Return + +Global IID_IDirectDraw7[]=[$15e65ec0,$11d23b9c,$60002fb9,$5bea9797] + +Global DirectDrawCreate( guid Ptr,ddraw:IDirectDraw Ptr,outer Ptr )"win32"=GetProcAddress( ddLib,"DirectDrawCreate" ) +Global DirectDrawCreateEx( guid:Byte Ptr,ddraw:Byte Ptr,iid Ptr,outer:Byte Ptr )"win32"=GetProcAddress( ddLib,"DirectDrawCreateEx" ) +Global DirectDrawEnumerate( callback(guid Ptr,desc:Byte Ptr,name:Byte Ptr,context Ptr),context Ptr )"win32"=GetProcAddress( ddLib,"DirectDrawEnumerateA" ) + diff --git a/mod/pub.mod/directx.mod/directx.bmx b/mod/pub.mod/directx.mod/directx.bmx new file mode 100644 index 0000000..7fb2b3a --- /dev/null +++ b/mod/pub.mod/directx.mod/directx.bmx @@ -0,0 +1,35 @@ + +Strict + +Module Pub.DirectX + +ModuleInfo "Version: 1.07" +ModuleInfo "Author: Various" +ModuleInfo "License: zlib/libpng" +ModuleInfo "Modserver: BRL" +ModuleInfo "Credit: Adapted for BlitzMax by Mark Sibly" + +ModuleInfo "History: 1.07 Release" +ModuleInfo "History: Fixed IDirectSound.GetCurrentPosition decl" +ModuleInfo "History: 1.06 Release" +ModuleInfo "History: Added more dsound" +ModuleInfo "History: 1.05 Release" +ModuleInfo "History: Added dsound.bmx" +ModuleInfo "History: 1.04 Release" +ModuleInfo "History: Added IDirectDraw.GetCaps" +ModuleInfo "History: 1.03 Release" +ModuleInfo "History: Added IDirect3DVertexBuffer7 interface definition" +ModuleInfo "History: 1.02 Release" +ModuleInfo "History: Added TnL device GUID" +ModuleInfo "History: 1.01 Release" +ModuleInfo "History: Updated" +ModuleInfo "History: 1.00 Release" + +?Win32 +Import "dd.bmx" +Import "d3d.bmx" +Import "d3d7.bmx" +Import "d3d9.bmx" +Import "d3d9x.bmx" +Import "dsound.bmx" +? \ No newline at end of file diff --git a/mod/pub.mod/directx.mod/dsound.bmx b/mod/pub.mod/directx.mod/dsound.bmx new file mode 100644 index 0000000..e1dde28 --- /dev/null +++ b/mod/pub.mod/directx.mod/dsound.bmx @@ -0,0 +1,167 @@ + +Strict + +Import Pub.Win32 + +Const DIRECTSOUND_VERSION=$0700 + +Const DSSCL_NORMAL=$00000001 +Const DSSCL_PRIORITY=$00000002 +Const DSSCL_EXCLUSIVE=$00000003 +Const DSSCL_WRITEPRIMARY=$00000004 + +Const DSCAPS_PRIMARYMONO=$00000001 +Const DSCAPS_PRIMARYSTEREO=$00000002 +Const DSCAPS_PRIMARY8BIT=$00000004 +Const DSCAPS_PRIMARY16BIT=$00000008 +Const DSCAPS_CONTINUOUSRATE=$00000010 +Const DSCAPS_EMULDRIVER=$00000020 +Const DSCAPS_CERTIFIED=$00000040 +Const DSCAPS_SECONDARYMONO=$00000100 +Const DSCAPS_SECONDARYSTEREO=$00000200 +Const DSCAPS_SECONDARY8BIT=$00000400 +Const DSCAPS_SECONDARY16BIT=$00000800 + +Const DSSPEAKER_HEADPHONE=$00000001 +Const DSSPEAKER_MONO=$00000002 +Const DSSPEAKER_QUAD=$00000003 +Const DSSPEAKER_STEREO=$00000004 +Const DSSPEAKER_SURROUND=$00000005 +Const DSSPEAKER_5POINT1=$00000006 +Const DSSPEAKER_GEOMETRY_MIN=$00000005 +Const DSSPEAKER_GEOMETRY_NARROW=$0000000A +Const DSSPEAKER_GEOMETRY_WIDE=$00000014 +Const DSSPEAKER_GEOMETRY_MAX=$000000B4 + +Const DSBCAPS_PRIMARYBUFFER=$00000001 +Const DSBCAPS_STATIC=$00000002 +Const DSBCAPS_LOCHARDWARE=$00000004 +Const DSBCAPS_LOCSOFTWARE=$00000008 +Const DSBCAPS_CTRL3D=$00000010 +Const DSBCAPS_CTRLFREQUENCY=$00000020 +Const DSBCAPS_CTRLPAN=$00000040 +Const DSBCAPS_CTRLVOLUME=$00000080 +Const DSBCAPS_CTRLPOSITIONNOTIFY=$00000100 +Const DSBCAPS_STICKYFOCUS=$00004000 +Const DSBCAPS_GLOBALFOCUS=$00008000 +Const DSBCAPS_GETCURRENTPOSITION2=$00010000 +Const DSBCAPS_MUTE3DATMAXDISTANCE=$00020000 +Const DSBCAPS_LOCDEFER=$00040000 + +Const DSBPLAY_LOOPING=$00000001 +Const DSBPLAY_LOCHARDWARE=$00000002 +Const DSBPLAY_LOCSOFTWARE=$00000004 +Const DSBPLAY_TERMINATEBY_TIME=$00000008 +Const DSBPLAY_TERMINATEBY_DISTANCE=$000000010 +Const DSBPLAY_TERMINATEBY_PRIORITY=$000000020 + +Const DSBSTATUS_PLAYING=$00000001 +Const DSBSTATUS_BUFFERLOST=$00000002 +Const DSBSTATUS_LOOPING=$00000004 +Const DSBSTATUS_LOCHARDWARE=$00000008 +Const DSBSTATUS_LOCSOFTWARE=$00000010 +Const DSBSTATUS_TERMINATED=$00000020 + +Const DSBLOCK_FROMWRITECURSOR=$00000001 +Const DSBLOCK_ENTIREBUFFER=$00000002 + +Type DSCAPS + Field dwSize + Field dwFlags + Field dwMinSecondarySampleRate + Field dwMaxSecondarySampleRate + Field dwPrimaryBuffers + Field dwMaxHwMixingAllBuffers + Field dwMaxHwMixingStaticBuffers + Field dwMaxHwMixingStreamingBuffers + Field dwFreeHwMixingAllBuffers + Field dwFreeHwMixingStaticBuffers + Field dwFreeHwMixingStreamingBuffers + Field dwMaxHw3DAllBuffers + Field dwMaxHw3DStaticBuffers + Field dwMaxHw3DStreamingBuffers + Field dwFreeHw3DAllBuffers + Field dwFreeHw3DStaticBuffers + Field dwFreeHw3DStreamingBuffers + Field dwTotalHwMemBytes + Field dwFreeHwMemBytes + Field dwMaxContigFreeHwMemBytes + Field dwUnlockTransferRateHwBuffers + Field dwPlayCpuOverheadSwBuffers + Field dwReserved1 + Field dwReserved2 +End Type + +Type DSBCAPS + Field dwSize + Field dwFlags + Field dwBufferBytes + Field dwUnlockTransferRate + Field dwPlayCpuOverhead +End Type + +Type WAVEFORMATEX + Field wFormatTag:Short + Field nChannels:Short + Field nSamplesPerSec + Field nAvgBytesPerSec + Field nBlockAlign:Short + Field wBitsPerSample:Short + Field cbSize:Short +End Type + +Type DSBUFFERDESC + Field dwSize + Field dwFlags + Field dwBufferBytes + Field dwReserved + Field lpwfxFormat:Byte Ptr + Field guid3DAlgorithm0 + Field guid3DAlgorithm1 + Field guid3DAlgorithm2 + Field guid3DAlgorithm3 +End Type + +Extern "win32" + +Type IDirectSound Extends IUnknown + Method CreateSoundBuffer( desc:Byte Ptr,buf:IDirectSoundBuffer Var,unk:Byte Ptr ) + Method GetCaps( caps:Byte Ptr ) + Method DuplicateSoundBuffer( in:IDirectSoundBuffer,out:IDirectSoundBuffer Var ) + Method SetCooperativeLevel( hwnd,coop ) + Method Compact() + Method GetSpeakerConfig( config Var ) + Method SetSpeakerConfig( config ) + Method Initialize( guid:Byte Ptr ) +End Type + +Type IDirectSoundBuffer Extends IUnknown + Method GetCaps( caps:Byte Ptr ) + Method GetCurrentPosition( pos Var,writePos Var ) + Method GetFormat( format:WAVEFORMATEX,sizein,sizeout Var ) + Method GetVolume( volume Var ) + Method GetPan( pan Var ) + Method GetFrequency( freq Var ) + Method GetStatus( status Var ) + Method Initialize( dsound:IDirectSound,desc:Byte Ptr ) + Method Lock( writeCursor,writeBytes,ptr1:Byte Ptr Var,bytes1 Var,ptr2:Byte Ptr Var,bytes2 Var,flags ) + Method Play( reserved,priority,flags ) + Method SetCurrentPosition( pos ) + Method SetFormat( format:WAVEFORMATEX ) + Method SetVolume( volume ) + Method SetPan( pan ) + Method SetFrequency( freq ) + Method Stop() + Method Unlock( ptr1:Byte Ptr,bytes1,ptr2:Byte Ptr,bytes2 ) + Method Restore() +End Type + +End Extern + +Private + +Global _ds=LoadLibraryA( "dsound" ) + +Public + +Global DirectSoundCreate( guid:Byte Ptr,dsound:IDirectSound Var,unk:Byte Ptr )"win32"=GetProcAddress( _ds,"DirectSoundCreate" ) diff --git a/mod/pub.mod/enet.mod/api.txt b/mod/pub.mod/enet.mod/api.txt new file mode 100644 index 0000000..ddde9b1 --- /dev/null +++ b/mod/pub.mod/enet.mod/api.txt @@ -0,0 +1,290 @@ +enet.h - The file that should be included to use the ENet API. + +enet_uint8 - unsigned 8 bit integer +enet_uint16 - unsigned 16 bit integer +enet_uint32 - unsigned 32 bit integer + +typedef struct +{ + enet_uint32 host; + enet_uint16 port; +} ENetAddress; + + Portable internet address structure. The host must be specified in network +byte-order, and the port must be in host byte-order. The constant ENET_HOST_ANY +may be used to specify the default server host. + +typedef struct +{ + enet_uint32 flags; + enet_uint8 * data; + size_t dataLength; +} ENetPacket; + + An ENet data packet that may be sent to or received from a peer. The shown fields +should only be read and never modified. The data field contains the allocated data +for the packet. The dataLength fields specifies the length of the allocated data. +The flags field is either 0 (specifying no flags), or a bitwise-or of any +combination of the following flags: + + ENET_PACKET_FLAG_RELIABLE - + + Specifies that the packet must be received by the target peer and that resend + attempts should be made should delivery of the packet fail. + +typedef struct +{ + ENetAddress address; + void * data; + size_t channelCount; + enet_uint32 incomingBandwidth; + enet_uint32 outgoingBandwidth; + enet_uint32 roundTripTime; + enet_uint32 packetLoss; +} ENetPeer; + + An ENet peer which data packets may be sent or received from. No fields should be +modified unless otherwise specified. The address field contains the internet address +of the peer. The data fields may be used to associate any desired data with the peer +and may be freely modified. The channelCount field tells the number of channels that +have been allocated for use to communnicate with the peer. The incomingBandwidth field +specifies the downstream bandwidth of the client in bytes per second. The +outgoingBandwidth field specifies the upstream bandwidth of the client in bytes per +second. The roundTripTime field tells the mean round trip time from the sending of +a reliable packet until the receipt of its acknowledgement in milliseconds. The +packetLoss field tells the mean packet loss of reliable packets as a ratio with +respect to the constant ENET_PEER_PACKET_LOSS_SCALE. + +typedef enum +{ + ENET_EVENT_TYPE_NONE, + ENET_EVENT_TYPE_CONNECT, + ENET_EVENT_TYPE_DISCONNECT, + ENET_EVENT_TYPE_RECEIVE +} ENetEventType; + +typedef struct _ENetEvent +{ + ENetEventType type; + ENetPeer * peer; + enet_uint8 channelID; + ENetPacket * packet; +} ENetEvent; + + An ENet event as returned by enet_host_service. The type field contains the type +of the event, which may be any one of the following: + + ENET_EVENT_TYPE_NONE - No event occurred within the specified time limit. + ENET_EVENT_TYPE_CONNECT - + + A connection request initiated by enet_host_connect has completed. The peer field + contains the peer which successfully connected. + + ENET_EVENT_TYPE_DISCONNECT - + + A peer has disconnected. This event is generated on successful completion of a + disconnect iniated by enet_peer_disconnect, if a peer has timed out, or if a + connection request initialized by enet_host_connect has timed out. The peer field + contains the peer which disconnected. + + ENET_EVENT_TYPE_RECEIVE - + + A packet has been received from a peer. The peer field specifies the peer which + send the packet. The channelID field specifies the channel number upon which the + packet was received. The packet field contains the packet that was destroyed; this + packet must be destroyed with enet_packet_destroy after use. + +typedef struct +{ + ENetAddress address; + enet_uint32 incomingBandwidth; + enet_uint32 outgoingBandwidth; + ENetPeer * peers; + size_t peerCount; +} ENetHost; + + An ENet host for communicating with peers. No fields should be modified. The address +field tells the internet address of the host. The incomingBandwidth field tells the downstream +bandwidth of the host. The outgoingBandwidth field specifies the upstream bandwidth of the host. +The peers field contains an array of the peers that have been allocated for this host. The +peerCount field specifies the number of peers that have been allocated for this host. + +unsigned ENET_HOST_TO_NET_8 (unsigned); +unsigned ENET_HOST_TO_NET_16 (unsigned); +unsigned ENET_HOST_TO_NET_32 (unsigned); + + Macros that convert from host byte-order to network byte-order (big +endian) for unsigned integers of 8 bits, 16 bits, and 32 bits repectively. + +unsigned ENET_NET_TO_HOST_8 (unsigned); +unsigned ENET_NET_TO_HOST_16 (unsigned); +unsigned ENET_NET_TO_HOST_32 (unsigned); + + Macros that convert from network byte-order (big endian) to host +byte-order for unsigned integers of 8 bits, 16 bits, and 32 bits repectively. + +enet_uint32 enet_time_get (void); + + Returns the wall-time in milliseconds. Its initial value is unspecified unless +otherwise set. + +void enet_time_set (enet_uint32); + + Sets the current wall-time in milliseconds. + +int enet_initialize (void); + + Initialize ENet for use. Must be called prior to using any functions in ENet. +Returns 0 on success and -1 on failure. + +void enet_deinitialize (void); + + Clean-up ENet after use. Should be called when a program that has initialized +and used ENet exits. + +int enet_address_set_host (ENetAddress * address, const char * hostName); + + Attempts to resolve the host named by the parameter hostName and sets the host +field in the address parameter if successful. Returns 0 on success and -1 on +failure. + +int enet_address_get_host (const ENetAddress * address, char * hostName, size_t nameLength); + + Attempts to do a reverse lookup of the host field in the address parameter. +If successful, the name of the host is placed in the string described by +hostName and nameLength. The host name is always null-delimited and will +not exceed nameLength in length. Returns 0 on success and -1 on failure. + +ENetPacket * enet_packet_create (const void * dataContents, size_t dataLength, enet_uint32 flags); + + Creates a packet that may be sent to a peer. The dataContents parameter +specifies the initial contents of the packet's data; the packet's data will +remain uninitialized if dataContents is NULL. The dataLength parameter specifies +the size of the data that is allocated for this packet. The flags parameter +specifies flags for this packet as described for the ENetPacket structure. +Returns the packet on success and NULL on failure. + +void enet_packet_destroy (ENetPacket * packet); + + Destroys the packet and deallocates its data. + +int enet_packet_resize (ENetPacket * packet, size_t dataLength); + + Attempts to resize the data in the packet to the length specified in the +dataLength parameter. Returns 0 on success and -1 on failure. + +ENetHost * enet_host_create (const ENetAddress * address, size_t peerCount, enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth); + + Creates a host for communicating with peers. The address parameter specifies +the address at which other peers may connect to this host; if the address parameter +is NULL, then no peers may connect to the host. The peerCount parameter specifies +the numbers of peers that should be allocated for the host; this limits the maximum +number of peers that may connect to this host to peerCount. The incomingBandwidth +parameter specifies the downstream bandwidth of the host in bytes per second; if +the incomingBandwidth parameter is 0, ENet will assume the host has unlimited +downstream bandwidth. The outgoingBandwidth parameter specifies the upstream bandwidth +of the host in bytes per second; if the outgoingBandwidth parameter is 0, ENet will +assume the host has unlimited upstream bandwidth. ENet will strategically drop packets +on specific sides of a connection between hosts to ensure the host's bandwidth is not +overwhelmed; the bandwidth parameters also determine the window size of a connection +which limits the amount of reliable packets that may be in transit at any given time. +Returns the host on success and NULL on failure. + +void enet_host_destroy (ENetHost * host); + + Destroys the host and all resources associated with it. + +ENetPeer * enet_host_connect (ENetHost * host, const ENetAddress * address, size_t channelCount); + + Initiates a connection from the host specified in the host parameter to a foreign +host whose internet address is specified by the address parameter. The channelCount +parameter specifies the number of channels that should be allocated for communicating +with the foreign host. Returns a peer representing the foreign host on success and NULL +on failure. The peer returned will have not completed the connection until enet_host_service +notifies of an ENET_EVENT_TYPE_CONNECT event for the peer. + +int enet_host_service (ENetHost * host, ENetEvent * event, enet_uint32 timeout); + + Waits for events on the host specified by the host parameters and shuttles packets +between the host and its peers. The event parameter specifies an event structure +where event details will be placed if one occurs. The timeout field specifies an +amount of time in milliseconds that ENet should wait for events. Returns 1 if an +event occured within the specified time limit, 0 if no event occurred within the +time limit, and -1 on failure. This function must be called frequently for adequate +performance. + +void enet_host_flush (ENetHost * host); + + Sends out any queued packets on the host specified in the host parameters to +the designated peers. This function need only be used in circumstances where one +wishes to send queued packets earlier than in a call to enet_host_service. + +void enet_host_broadcast (ENetHost * host, enet_uint8 channelID, ENetPacket * packet); + + Queues a packet to be sent to all peers on the host specified in the host parameter +over the channel number identified by the channelID parameter. + +void enet_host_bandwidth_limit (ENetHost * host, enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth); + + Adjusts the bandwidth limits of the host specified in the host parameter. The +incomingBandwidth and outgoingBandwidth parameters are as specified in a call to +enet_host_create. + +int enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet); + + Queues a packet to be sent to the peer specified by the peer parameter over the +channel number identified by the channelID parameter. Returns 0 on success and -1 +on failure. + +ENetPacket * enet_peer_receive (ENetPeer * peer, enet_uint8 channelID); + + Attempts to dequeue any incoming queued packets on the peer specified by the peer +parameter on the channel number identified by the channelID parameter. Returns a packet +if one is available and NULL if there are no available incoming queued packets. + +void enet_peer_ping (ENetPeer * peer); + + Sends a ping request to the peer specified by the peer parameter. Ping requests factor +into the mean round trip time as designated by the roundTripTime field in the ENetPeer +structure. ENet automatically pings all connected peer at an interval, however, this +function may be called to ensure more frequent ping requests. + +void enet_peer_reset (ENetPeer * peer); + + Forcefully disconnects the peer specified by the peer parameter. The foreign host +represented by the peer is not notified of the disconnection and so will timeout on its +connection to the local host. + +void enet_peer_disconnect (ENetPeer * peer); + + Request a disconnection from the peer specified by the peer parameter. An +ENET_EVENT_DISCONNECT event will be generated by enet_host_service once the +disconnection is complete. + +void enet_peer_throttle_configure (ENetPeer * peer, enet_uint32 interval, enet_uint32 acceleration, enet_uint32 deceleration); + + Configures throttle parameter for the peer specified by the peer parameter. +Unreliable packets are dropped by ENet in response to the varying conditions of +the internet connection to the peer. The throttle represents a probability that +an unreliable packet should not be dropped and thus sent by ENet to the peer. +The lowest mean round trip time from the sending of a reliable packet to the +receipt of its acknowledgement is measured over an amount of time specified +by the interval parameter in milliseconds; the constant ENET_PEER_PACKET_THROTTLE_INTERVAL +is the default value for this parameter. If a measured round trip time happens +to be signifigantly less than the mean round trip time measured over the interval, +then the throttle probability is increased to allow more traffic by an amount +specified in the acceleration parameter which is in ratio to the +ENET_PEER_PACKET_THROTTLE_SCALE constant. If a measured round trip time happens +to be signifigantly greater than the mean round trip time measured over the interval, +then the throttle probability is decreased to limit traffic by an amount specified +in the deceleration parameter which is in ratio to the ENET_PEER_PACKET_THROTTLE_SCALE +constant. When the throttle has a value of ENET_PEER_PACKET_THROTTLE_SCALE, no unreliable +packets are dropped by ENET, and so 100% of all unreliable packets will be sent. When the +throttle has a value of 0, all unreliable packets are dropped by ENet, and so 0% of all +unreliable packets will be sent. Intermediate values for the throttle represent intermediate +probabilities between 0% and 100% of unreliable packets being sent. The bandwidth limits +of the local and foreign host are taken into account to determine a sensible limit for +the throttle probability above which it should not raise even in the best of conditions. + + + diff --git a/mod/pub.mod/enet.mod/design.txt b/mod/pub.mod/enet.mod/design.txt new file mode 100644 index 0000000..9a88dba --- /dev/null +++ b/mod/pub.mod/enet.mod/design.txt @@ -0,0 +1,117 @@ +* Why ENet? + + ENet evolved specifically as a UDP networking layer for the multiplayer +first person shooter Cube. Cube necessitated low latency communcation with +data sent out very frequently, so TCP was an unsuitable choice due to its +high latency and stream orientation. UDP, however, lacks many sometimes +necessary features from TCP such as reliability, sequencing, unrestricted +packet sizes, and connection management. So UDP by itself was not suitable +as a network protocol either. No suitable freely available networking +libraries existed at the time of ENet's creation to fill this niche. + + UDP and TCP could have been used together in Cube to benefit somewhat +from both of their features, however, the resulting combinations of protocols +still leaves much to be desired. TCP lacks multiple streams of communication +without resorting to opening many sockets and complicates delineation of +packets due to its buffering behavior. UDP lacks sequencing, connection +management, management of bandwidth resources, and imposes limitations on +the size of packets. A significant investment is required to integrate these +two protocols, and the end result is worse off in features and performance +than the uniform protocol presented by ENet. + + ENet thus attempts to address these issues and provide a single, uniform +protocol layered over UDP to the developer with the best features of UDP and +TCP as well as some useful features neither provide, with a much cleaner +integration than any resulting from a mixture of UDP and TCP. + +* Connection management + + ENet provides a simple connection interface over which to communicate +with a foreign host. The liveness of the connection is actively monitored +by pinging the foreign host at frequent intervals, and also monitors the +network conditions from the local host to the foreign host such as the +mean round trip time and packet loss in this fashion. + +* Sequencing + + Rather than a single byte stream that complicates the delineation +of packets, ENet presents connections as multiple, properly sequenced packet +streams that simplify the transfer of various types of data. + + ENet provides sequencing for all packets by assigning to each sent +packet a sequence number that is incremented as packets are sent. ENet +guarentees that no packet with a higher sequence number will be delivered +before a packet with a lower sequence number, thus ensuring packets are +delivered exactly in the order they are sent. + + For unreliable packets, ENet will simply discard the lower sequence +number packet if a packet with a higher sequence number has already been +delivered. This allows the packets to be dispatched immediately as they +arrive, and reduce latency of unreliable packets to an absolute minimum. +For reliable packets, if a higher sequence number packet arrives, but the +preceding packets in the sequence have not yet arrived, ENet will stall +delivery of the higher sequence number packets until its predecessors +have arrived. + +* Channels + + Since ENet will stall delivery of reliable packets to ensure proper +sequencing, and consequently any packets of higher sequence number whether +reliable or unreliable, in the event the reliable packet's predecessors +have not yet arrived, this can introduce latency into the delivery of other +packets which may not need to be as strictly ordered with respect to the +packet that stalled their delivery. + + To combat this latency and reduce the ordering restrictions on packets, +ENet provides multiple channels of communication over a given connection. +Each channel is independently sequenced, and so the delivery status of +a packet in one channel will not stall the delivery of other packets +in another channel. + +* Reliability + + ENet provides optional reliability of packet delivery by ensuring the +foreign host acknowledges receipt of all reliable packets. ENet will attempt +to resend the packet up to a reasonable amount of times, if no acknowledgement +of the packet's receipt happens within a specified timeout. Retry timeouts +are progressive and become more lenient with every failed attempt to allow +for temporary turbulence in network conditions. + +* Fragmentation and reassembly + + ENet will send and deliver packets regardless of size. Large packets are +fragmented into many smaller packets of suitable size, and reassembled on +the foreign host to recover the original packet for delivery. The process +is entirely transparent to the developer. + +* Aggregation + + ENet aggregates all protocol commands, including acknowledgements and +packet transfer, into larger protocol packets to ensure the proper utilization +of the connection and to limit the opportunities for packet loss that might +otherwise result in further delivery latency. + +* Adaptability + + ENet provides an in-flight data window for reliable packets to ensure +connections are not overwhelmed by volumes of packets. It also provides a +static bandwidth allocation mechanism to ensure the total volume of packets +sent and received to a host don't exceed the host's capabilities. Further, +ENet also provides a dynamic throttle that responds to deviations from normal +network connections to rectify various types of network congestion by further +limiting the volume of packets sent. + +* Portability + + ENet works on Windows and any other Unix or Unix-like platform providing +a BSD sockets interface. The library has a small and stable code base that +can easily be extended to support other platforms and integrates easily. + +* Freedom + + ENet demands no royalties and doesn't carry a viral license that would +restrict you in how you might use it in your programs. ENet is licensed under +a short-and-sweet MIT-style license, which gives you the freedom to do anything +you want with it (well, almost anything). + + diff --git a/mod/pub.mod/enet.mod/enet.bmx b/mod/pub.mod/enet.mod/enet.bmx new file mode 100644 index 0000000..3988f7f --- /dev/null +++ b/mod/pub.mod/enet.mod/enet.bmx @@ -0,0 +1,116 @@ + +Strict + +Module Pub.ENet + +ModuleInfo "Version: 1.01" +ModuleInfo "Author: Lee Salzman" +ModuleInfo "Modserver: BRL" +ModuleInfo "Credit: Adapted for BlitzMax by Mark Sibly" + +ModuleInfo "History: 1.01 Release" + +Import Pub.StdC + +Import "include/*.h" + +Import "host.c" +Import "list.c" +Import "memory.c" +Import "packet.c" +Import "peer.c" +Import "protocol.c" + +?Win32 +Import "win32.c" +Import "-lws2_32" +?MacOS +Import "unix.c" +?Linux +Import "unix.c" +? + +Type ENetEvent + + Field event + Field peer:Byte Ptr + Field channel + Field packet:Byte Ptr + +End Type + +Extern "C" + +Const ENET_HOST_ANY=0 + +Const ENET_EVENT_TYPE_NONE=0 +Const ENET_EVENT_TYPE_CONNECT=1 +Const ENET_EVENT_TYPE_DISCONNECT=2 +Const ENET_EVENT_TYPE_RECEIVE=3 + +Const ENET_PACKET_FLAG_RELIABLE=1 + +Function enet_initialize() +Function enet_deinitialize() + +Function enet_address_set_host( address:Byte Ptr,name$z ) + +Function enet_time_get() +Function enet_time_set( walltime_ms ) + +Function enet_packet_create:Byte Ptr( data:Byte Ptr,size,flags ) +Function enet_packet_destroy( packet:Byte Ptr ) + +Function enet_host_create:Byte Ptr( address:Byte Ptr,peerCount,incomingBandwidth,outgoingBandwidth ) +Function enet_host_destroy( host:Byte Ptr ) +Function enet_host_connect:Byte Ptr( host:Byte Ptr,address:Byte Ptr,channelCount ) +Function enet_host_flush( host:Byte Ptr ) +Function enet_host_service( host:Byte Ptr,event:Byte Ptr,timeout_ms ) +Function enet_host_broadcast( host:Byte Ptr,channel,packet:Byte Ptr ) +Function enet_host_bandwidth_limit( host:Byte Ptr,incomingBandwidth,outgoingBandwidth ) + +Function enet_peer_send( peer:Byte Ptr,channel,packet:Byte Ptr ) +Function enet_peer_receive( peer:Byte Ptr,channel ) +Function enet_peer_ping( peer:Byte Ptr ) +Function enet_peer_reset( peer:Byte Ptr ) +Function enet_peer_disconnect( peer:Byte Ptr ) +Function enet_peer_throttle_configure( peer:Byte Ptr,interval,acceleration,deceleration ) + +End Extern + +Function enet_peer_address( peer:Byte Ptr,host_ip Var,host_port Var ) + Local ip=(Int Ptr peer)[3] + Local port=(Short Ptr peer)[8] +?LittleEndian + ip=(ip Shr 24) | (ip Shr 8 & $ff00) | (ip Shl 8 & $ff0000) | (ip Shl 24) +? + host_ip=ip + host_port=port +End Function + +Function enet_packet_data:Byte Ptr( packet:Byte Ptr ) + Return Byte Ptr( (Int Ptr packet)[2] ) +End Function + +Function enet_packet_size( packet:Byte Ptr ) + Return (Int Ptr packet)[3] +End Function + +Function enet_address_create:Byte Ptr( host_ip,host_port ) + Local t:Byte Ptr=MemAlloc( 6 ) +?BigEndian + (Int Ptr t)[0]=host_ip +?LittleEndian + (Int Ptr t)[0]=(host_ip Shr 24) | (host_ip Shr 8 & $ff00) | (host_ip Shl 8 & $ff0000) | (host_ip Shl 24) +? + (Short Ptr t)[2]=host_port + Return t +End Function + +Function enet_address_destroy( address:Byte Ptr ) + MemFree address +End Function + +enet_initialize +atexit_ enet_deinitialize + diff --git a/mod/pub.mod/enet.mod/host.c b/mod/pub.mod/enet.mod/host.c new file mode 100644 index 0000000..efba733 --- /dev/null +++ b/mod/pub.mod/enet.mod/host.c @@ -0,0 +1,390 @@ +/** + @file host.c + @brief ENet host management functions +*/ +#define ENET_BUILDING_LIB 1 +#include "enet/memory.h" +#include "enet/enet.h" + +/** @defgroup host ENet host functions + @{ +*/ + +/** Creates a host for communicating to peers. + + @param address the address at which other peers may connect to this host. If NULL, then no peers may connect to the host. + @param peerCount the maximum number of peers that should be allocated for the host. + @param incomingBandwidth downstream bandwidth of the host in bytes/second; if 0, ENet will assume unlimited bandwidth. + @param outgoingBandwidth upstream bandwidth of the host in bytes/second; if 0, ENet will assume unlimited bandwidth. + + @returns the host on success and NULL on failure + + @remarks ENet will strategically drop packets on specific sides of a connection between hosts + to ensure the host's bandwidth is not overwhelmed. The bandwidth parameters also determine + the window size of a connection which limits the amount of reliable packets that may be in transit + at any given time. +*/ +ENetHost * +enet_host_create (const ENetAddress * address, size_t peerCount, enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth) +{ + ENetHost * host = (ENetHost *) enet_malloc (sizeof (ENetHost)); + ENetPeer * currentPeer; + + host -> peers = (ENetPeer *) enet_calloc (peerCount, sizeof (ENetPeer)); + + host -> socket = enet_socket_create (ENET_SOCKET_TYPE_DATAGRAM, address); + if (host -> socket == ENET_SOCKET_NULL) + { + enet_free (host -> peers); + enet_free (host); + + return NULL; + } + + if (address != NULL) + host -> address = * address; + + host -> incomingBandwidth = incomingBandwidth; + host -> outgoingBandwidth = outgoingBandwidth; + host -> bandwidthThrottleEpoch = 0; + host -> recalculateBandwidthLimits = 0; + host -> mtu = ENET_HOST_DEFAULT_MTU; + host -> peerCount = peerCount; + host -> lastServicedPeer = host -> peers; + host -> commandCount = 0; + host -> bufferCount = 0; + host -> receivedAddress.host = ENET_HOST_ANY; + host -> receivedAddress.port = 0; + host -> receivedDataLength = 0; + + for (currentPeer = host -> peers; + currentPeer < & host -> peers [host -> peerCount]; + ++ currentPeer) + { + currentPeer -> host = host; + currentPeer -> incomingPeerID = currentPeer - host -> peers; + currentPeer -> data = NULL; + + enet_list_clear (& currentPeer -> acknowledgements); + enet_list_clear (& currentPeer -> sentReliableCommands); + enet_list_clear (& currentPeer -> sentUnreliableCommands); + enet_list_clear (& currentPeer -> outgoingReliableCommands); + enet_list_clear (& currentPeer -> outgoingUnreliableCommands); + + enet_peer_reset (currentPeer); + } + + return host; +} + +/** Destroys the host and all resources associated with it. + @param host pointer to the host to destroy +*/ +void +enet_host_destroy (ENetHost * host) +{ + ENetPeer * currentPeer; + + enet_socket_destroy (host -> socket); + + for (currentPeer = host -> peers; + currentPeer < & host -> peers [host -> peerCount]; + ++ currentPeer) + { + enet_peer_reset (currentPeer); + } + + enet_free (host -> peers); + enet_free (host); +} + +/** Initiates a connection to a foreign host. + @param host host seeking the connection + @param address destination for the connection + @param channelCount number of channels to allocate + @returns a peer representing the foreign host on success, NULL on failure + @remarks The peer returned will have not completed the connection until enet_host_service() + notifies of an ENET_EVENT_TYPE_CONNECT event for the peer. +*/ +ENetPeer * +enet_host_connect (ENetHost * host, const ENetAddress * address, size_t channelCount) +{ + ENetPeer * currentPeer; + ENetChannel * channel; + ENetProtocol command; + + if (channelCount < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT) + channelCount = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT; + else + if (channelCount > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT) + channelCount = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT; + + for (currentPeer = host -> peers; + currentPeer < & host -> peers [host -> peerCount]; + ++ currentPeer) + { + if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED) + break; + } + + if (currentPeer >= & host -> peers [host -> peerCount]) + return NULL; + + currentPeer -> state = ENET_PEER_STATE_CONNECTING; + currentPeer -> address = * address; + currentPeer -> channels = (ENetChannel *) enet_malloc (channelCount * sizeof (ENetChannel)); + currentPeer -> channelCount = channelCount; + currentPeer -> challenge = (enet_uint32) rand (); + + if (host -> outgoingBandwidth == 0) + currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; + else + currentPeer -> windowSize = (host -> outgoingBandwidth / + ENET_PEER_WINDOW_SIZE_SCALE) * + ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; + + if (currentPeer -> windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE) + currentPeer -> windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; + else + if (currentPeer -> windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE) + currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; + + for (channel = currentPeer -> channels; + channel < & currentPeer -> channels [channelCount]; + ++ channel) + { + channel -> outgoingReliableSequenceNumber = 0; + channel -> outgoingUnreliableSequenceNumber = 0; + channel -> incomingReliableSequenceNumber = 0; + channel -> incomingUnreliableSequenceNumber = 0; + + enet_list_clear (& channel -> incomingReliableCommands); + enet_list_clear (& channel -> incomingUnreliableCommands); + } + + command.header.command = ENET_PROTOCOL_COMMAND_CONNECT; + command.header.channelID = 0xFF; + command.header.flags = ENET_PROTOCOL_FLAG_ACKNOWLEDGE; + command.header.commandLength = sizeof (ENetProtocolConnect); + command.connect.outgoingPeerID = ENET_HOST_TO_NET_16 (currentPeer -> incomingPeerID); + command.connect.mtu = ENET_HOST_TO_NET_16 (currentPeer -> mtu); + command.connect.windowSize = ENET_HOST_TO_NET_32 (currentPeer -> windowSize); + command.connect.channelCount = ENET_HOST_TO_NET_32 (channelCount); + command.connect.incomingBandwidth = ENET_HOST_TO_NET_32 (host -> incomingBandwidth); + command.connect.outgoingBandwidth = ENET_HOST_TO_NET_32 (host -> outgoingBandwidth); + command.connect.packetThrottleInterval = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleInterval); + command.connect.packetThrottleAcceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleAcceleration); + command.connect.packetThrottleDeceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleDeceleration); + + enet_peer_queue_outgoing_command (currentPeer, & command, NULL, 0, 0); + + return currentPeer; +} + +/** Queues a packet to be sent to all peers associated with the host. + @param host host on which to broadcast the packet + @param channelID channel on which to broadcast + @param packet packet to broadcast +*/ +void +enet_host_broadcast (ENetHost * host, enet_uint8 channelID, ENetPacket * packet) +{ + ENetPeer * currentPeer; + + for (currentPeer = host -> peers; + currentPeer < & host -> peers [host -> peerCount]; + ++ currentPeer) + { + if (currentPeer -> state != ENET_PEER_STATE_CONNECTED) + continue; + + enet_peer_send (currentPeer, channelID, packet); + } + + if (packet -> referenceCount == 0) + enet_packet_destroy (packet); +} + +/** Adjusts the bandwidth limits of a host. + @param host host to adjust + @param incomingBandwidth new incoming bandwidth + @param outgoingBandwidth new outgoing bandwidth + @remarks the incoming and outgoing bandwidth parameters are identical in function to those + specified in enet_host_create(). +*/ +void +enet_host_bandwidth_limit (ENetHost * host, enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth) +{ + host -> incomingBandwidth = incomingBandwidth; + host -> outgoingBandwidth = outgoingBandwidth; + host -> recalculateBandwidthLimits = 1; +} + +void +enet_host_bandwidth_throttle (ENetHost * host) +{ + enet_uint32 timeCurrent = enet_time_get (), + elapsedTime = timeCurrent - host -> bandwidthThrottleEpoch, + peersTotal = 0, + dataTotal = 0, + peersRemaining, + bandwidth, + throttle = 0, + bandwidthLimit = 0; + int needsAdjustment; + ENetPeer * peer; + ENetProtocol command; + + if (elapsedTime < ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL) + return; + + for (peer = host -> peers; + peer < & host -> peers [host -> peerCount]; + ++ peer) + { + if (peer -> state != ENET_PEER_STATE_CONNECTED) + continue; + + ++ peersTotal; + dataTotal += peer -> outgoingDataTotal; + } + + if (peersTotal == 0) + return; + + peersRemaining = peersTotal; + needsAdjustment = 1; + + if (host -> outgoingBandwidth == 0) + bandwidth = ~0; + else + bandwidth = (host -> outgoingBandwidth * elapsedTime) / 1000; + + while (peersRemaining > 0 && needsAdjustment != 0) + { + needsAdjustment = 0; + + if (dataTotal < bandwidth) + throttle = ENET_PEER_PACKET_THROTTLE_SCALE; + else + throttle = (bandwidth * ENET_PEER_PACKET_THROTTLE_SCALE) / dataTotal; + + for (peer = host -> peers; + peer < & host -> peers [host -> peerCount]; + ++ peer) + { + enet_uint32 peerBandwidth; + + if (peer -> state != ENET_PEER_STATE_CONNECTED || + peer -> incomingBandwidth == 0 || + peer -> outgoingBandwidthThrottleEpoch == timeCurrent) + continue; + + peerBandwidth = (peer -> incomingBandwidth * elapsedTime) / 1000; + if ((throttle * peer -> outgoingDataTotal) / ENET_PEER_PACKET_THROTTLE_SCALE <= peerBandwidth) + continue; + + peer -> packetThrottleLimit = (peerBandwidth * + ENET_PEER_PACKET_THROTTLE_SCALE) / peer -> outgoingDataTotal; + + if (peer -> packetThrottleLimit == 0) + peer -> packetThrottleLimit = 1; + + if (peer -> packetThrottle > peer -> packetThrottleLimit) + peer -> packetThrottle = peer -> packetThrottleLimit; + + peer -> outgoingBandwidthThrottleEpoch = timeCurrent; + + + needsAdjustment = 1; + -- peersRemaining; + bandwidth -= peerBandwidth; + dataTotal -= peerBandwidth; + } + } + + if (peersRemaining > 0) + for (peer = host -> peers; + peer < & host -> peers [host -> peerCount]; + ++ peer) + { + if (peer -> state != ENET_PEER_STATE_CONNECTED || + peer -> outgoingBandwidthThrottleEpoch == timeCurrent) + continue; + + peer -> packetThrottleLimit = throttle; + + if (peer -> packetThrottle > peer -> packetThrottleLimit) + peer -> packetThrottle = peer -> packetThrottleLimit; + } + + if (host -> recalculateBandwidthLimits) + { + host -> recalculateBandwidthLimits = 0; + + peersRemaining = peersTotal; + bandwidth = host -> incomingBandwidth; + needsAdjustment = 1; + + if (bandwidth == 0) + bandwidthLimit = 0; + else + while (peersRemaining > 0 && needsAdjustment != 0) + { + needsAdjustment = 0; + bandwidthLimit = bandwidth / peersRemaining; + + for (peer = host -> peers; + peer < & host -> peers [host -> peerCount]; + ++ peer) + { + if (peer -> state != ENET_PEER_STATE_CONNECTED || + peer -> incomingBandwidthThrottleEpoch == timeCurrent) + continue; + + if (peer -> outgoingBandwidth > 0 && + bandwidthLimit > peer -> outgoingBandwidth) + continue; + + peer -> incomingBandwidthThrottleEpoch = timeCurrent; + + needsAdjustment = 1; + -- peersRemaining; + bandwidth -= peer -> outgoingBandwidth; + } + } + + for (peer = host -> peers; + peer < & host -> peers [host -> peerCount]; + ++ peer) + { + if (peer -> state != ENET_PEER_STATE_CONNECTED) + continue; + + command.header.command = ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT; + command.header.channelID = 0xFF; + command.header.flags = 0; + command.header.commandLength = sizeof (ENetProtocolBandwidthLimit); + command.bandwidthLimit.outgoingBandwidth = ENET_HOST_TO_NET_32 (host -> outgoingBandwidth); + + if (peer -> incomingBandwidthThrottleEpoch == timeCurrent) + command.bandwidthLimit.incomingBandwidth = ENET_HOST_TO_NET_32 (peer -> outgoingBandwidth); + else + command.bandwidthLimit.incomingBandwidth = ENET_HOST_TO_NET_32 (bandwidthLimit); + + enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0); + } + } + + host -> bandwidthThrottleEpoch = timeCurrent; + + for (peer = host -> peers; + peer < & host -> peers [host -> peerCount]; + ++ peer) + { + peer -> incomingDataTotal = 0; + peer -> outgoingDataTotal = 0; + } +} + +/** @} */ diff --git a/mod/pub.mod/enet.mod/include/enet/enet.h b/mod/pub.mod/enet.mod/include/enet/enet.h new file mode 100644 index 0000000..e4e9fee --- /dev/null +++ b/mod/pub.mod/enet.mod/include/enet/enet.h @@ -0,0 +1,422 @@ +/** + @file enet.h + @brief ENet public header file +*/ +#ifndef __ENET_ENET_H__ +#define __ENET_ENET_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include + +#include "enet/types.h" +#include "enet/protocol.h" +#include "enet/list.h" + +#ifdef WIN32 +#include "enet/win32.h" +#else +#include "enet/unix.h" +#endif + +#ifdef ENET_API +#undef ENET_API +#endif + +#if defined WIN32 +#if defined ENET_DLL +#if defined ENET_BUILDING_LIB +#define ENET_API __declspec( dllexport ) +#else +#define ENET_API __declspec( dllimport ) +#endif /* ENET_BUILDING_LIB */ +#endif /* ENET_DLL */ +#endif /* WIN32 */ + +#ifndef ENET_API +#define ENET_API extern +#endif + +typedef enum +{ + ENET_SOCKET_TYPE_STREAM = 1, + ENET_SOCKET_TYPE_DATAGRAM = 2 +} ENetSocketType; + +typedef enum +{ + ENET_SOCKET_WAIT_NONE = 0, + ENET_SOCKET_WAIT_SEND = (1 << 0), + ENET_SOCKET_WAIT_RECEIVE = (1 << 1) +} ENetSocketWait; + +enum +{ + ENET_HOST_ANY = 0 +}; + +/** + * Portable internet address structure. + * + * The host must be specified in network byte-order, and the port must be in host + * byte-order. The constant ENET_HOST_ANY may be used to specify the default + * server host. + */ +typedef struct _ENetAddress +{ + enet_uint32 host; /**< may use ENET_HOST_ANY to specify default server host */ + enet_uint16 port; +} ENetAddress; + +/** + * Packet flag bit constants. + * + * The host must be specified in network byte-order, and the port must be in + * host byte-order. The constant ENET_HOST_ANY may be used to specify the + * default server host. + + @sa ENetPacket +*/ +typedef enum +{ + /** packet must be received by the target peer and resend attempts should be + * made until the packet is delivered */ + ENET_PACKET_FLAG_RELIABLE = (1 << 0) +} ENetPacketFlag; + +/** + * ENet packet structure. + * + * An ENet data packet that may be sent to or received from a peer. The shown + * fields should only be read and never modified. The data field contains the + * allocated data for the packet. The dataLength fields specifies the length + * of the allocated data. The flags field is either 0 (specifying no flags), + * or a bitwise-or of any combination of the following flags: + * + * ENET_PACKET_FLAG_RELIABLE - packet must be received by the ta + + @sa ENetPacketFlag + */ +typedef struct _ENetPacket +{ + size_t referenceCount; /**< internal use only */ + enet_uint32 flags; /**< bitwise or of ENetPacketFlag constants */ + enet_uint8 * data; /**< allocated data for packet */ + size_t dataLength; /**< length of data */ +} ENetPacket; + +typedef struct _ENetAcknowledgement +{ + ENetListNode acknowledgementList; + enet_uint32 sentTime; + ENetProtocol command; +} ENetAcknowledgement; + +typedef struct _ENetOutgoingCommand +{ + ENetListNode outgoingCommandList; + enet_uint32 reliableSequenceNumber; + enet_uint32 unreliableSequenceNumber; + enet_uint32 sentTime; + enet_uint32 roundTripTimeout; + enet_uint32 roundTripTimeoutLimit; + enet_uint32 fragmentOffset; + enet_uint16 fragmentLength; + ENetProtocol command; + ENetPacket * packet; +} ENetOutgoingCommand; + +typedef struct _ENetIncomingCommand +{ + ENetListNode incomingCommandList; + enet_uint32 reliableSequenceNumber; + enet_uint32 unreliableSequenceNumber; + ENetProtocol command; + enet_uint32 fragmentCount; + enet_uint32 fragmentsRemaining; + enet_uint32 * fragments; + ENetPacket * packet; +} ENetIncomingCommand; + +typedef enum +{ + ENET_PEER_STATE_DISCONNECTED = 0, + ENET_PEER_STATE_CONNECTING = 1, + ENET_PEER_STATE_ACKNOWLEDGING_CONNECT = 2, + ENET_PEER_STATE_CONNECTED = 3, + ENET_PEER_STATE_DISCONNECTING = 4, + ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT = 5, + ENET_PEER_STATE_ZOMBIE = 6 +} ENetPeerState; + +#ifndef ENET_BUFFER_MAXIMUM +#define ENET_BUFFER_MAXIMUM (1 + 2 * ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS) +#endif + +enum +{ + ENET_HOST_RECEIVE_BUFFER_SIZE = 256 * 1024, + ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL = 1000, + ENET_HOST_DEFAULT_MTU = 1400, + + ENET_PEER_DEFAULT_ROUND_TRIP_TIME = 500, + ENET_PEER_DEFAULT_PACKET_THROTTLE = 32, + ENET_PEER_PACKET_THROTTLE_SCALE = 32, + ENET_PEER_PACKET_THROTTLE_COUNTER = 7, + ENET_PEER_PACKET_THROTTLE_ACCELERATION = 2, + ENET_PEER_PACKET_THROTTLE_DECELERATION = 2, + ENET_PEER_PACKET_THROTTLE_INTERVAL = 5000, + ENET_PEER_PACKET_LOSS_SCALE = (1 << 16), + ENET_PEER_PACKET_LOSS_INTERVAL = 10000, + ENET_PEER_WINDOW_SIZE_SCALE = 64 * 1024, + ENET_PEER_TIMEOUT_LIMIT = 32, + ENET_PEER_PING_INTERVAL = 500 +}; + +typedef struct _ENetChannel +{ + enet_uint32 outgoingReliableSequenceNumber; + enet_uint32 outgoingUnreliableSequenceNumber; + enet_uint32 incomingReliableSequenceNumber; + enet_uint32 incomingUnreliableSequenceNumber; + ENetList incomingReliableCommands; + ENetList incomingUnreliableCommands; +} ENetChannel; + +/** + * An ENet peer which data packets may be sent or received from. + * + * No fields should be modified unless otherwise specified. + */ +typedef struct _ENetPeer +{ + struct _ENetHost * host; + enet_uint16 outgoingPeerID; + enet_uint16 incomingPeerID; + enet_uint32 challenge; + ENetAddress address; /**< Internet address of the peer */ + void * data; /**< Application private data, may be freely modified */ + ENetPeerState state; + ENetChannel * channels; + size_t channelCount; /**< Number of channels allocated for communication with peer */ + enet_uint32 incomingBandwidth; /**< Downstream bandwidth of the client in bytes/second */ + enet_uint32 outgoingBandwidth; /**< Upstream bandwidth of the client in bytes/second */ + enet_uint32 incomingBandwidthThrottleEpoch; + enet_uint32 outgoingBandwidthThrottleEpoch; + enet_uint32 incomingDataTotal; + enet_uint32 outgoingDataTotal; + enet_uint32 lastSendTime; + enet_uint32 lastReceiveTime; + enet_uint32 nextTimeout; + enet_uint32 packetLossEpoch; + enet_uint32 packetsSent; + enet_uint32 packetsLost; + enet_uint32 packetLoss; /**< mean packet loss of reliable packets as a ratio with respect to the constant ENET_PEER_PACKET_LOSS_SCALE */ + enet_uint32 packetLossVariance; + enet_uint32 packetThrottle; + enet_uint32 packetThrottleLimit; + enet_uint32 packetThrottleCounter; + enet_uint32 packetThrottleEpoch; + enet_uint32 packetThrottleAcceleration; + enet_uint32 packetThrottleDeceleration; + enet_uint32 packetThrottleInterval; + enet_uint32 lastRoundTripTime; + enet_uint32 lowestRoundTripTime; + enet_uint32 lastRoundTripTimeVariance; + enet_uint32 highestRoundTripTimeVariance; + enet_uint32 roundTripTime; /**< mean round trip time (RTT), in milliseconds, between sending a reliable packet and receiving its acknowledgement */ + enet_uint32 roundTripTimeVariance; + enet_uint16 mtu; + enet_uint32 windowSize; + enet_uint32 reliableDataInTransit; + enet_uint32 outgoingReliableSequenceNumber; + ENetList acknowledgements; + ENetList sentReliableCommands; + ENetList sentUnreliableCommands; + ENetList outgoingReliableCommands; + ENetList outgoingUnreliableCommands; +} ENetPeer; + +/** An ENet host for communicating with peers. + * + * No fields should be modified. + + @sa enet_host_create() + @sa enet_host_destroy() + @sa enet_host_connect() + @sa enet_host_service() + @sa enet_host_flush() + @sa enet_host_broadcast() + @sa enet_host_bandwidth_limit() + @sa enet_host_bandwidth_throttle() + */ +typedef struct _ENetHost +{ + ENetSocket socket; + ENetAddress address; /**< Internet address of the host */ + enet_uint32 incomingBandwidth; /**< downstream bandwidth of the host */ + enet_uint32 outgoingBandwidth; /**< upstream bandwidth of the host */ + enet_uint32 bandwidthThrottleEpoch; + enet_uint32 mtu; + int recalculateBandwidthLimits; + ENetPeer * peers; /**< array of peers allocated for this host */ + size_t peerCount; /**< number of peers allocated for this host */ + ENetPeer * lastServicedPeer; + size_t packetSize; + ENetProtocol commands [ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS]; + size_t commandCount; + ENetBuffer buffers [ENET_BUFFER_MAXIMUM]; + size_t bufferCount; + ENetAddress receivedAddress; + enet_uint8 receivedData [ENET_PROTOCOL_MAXIMUM_MTU]; + size_t receivedDataLength; +} ENetHost; + +/** + * An ENet event type, as specified in @ref ENetEvent. + */ +typedef enum +{ + /** no event occurred within the specified time limit */ + ENET_EVENT_TYPE_NONE = 0, + + /** a connection request initiated by enet_host_connect has completed. + * The peer field contains the peer which successfully connected. + */ + ENET_EVENT_TYPE_CONNECT = 1, + + /** a peer has disconnected. This event is generated on a successful + * completion of a disconnect initiated by enet_pper_disconnect, if + * a peer has timed out, or if a connection request intialized by + * enet_host_connect has timed out. The peer field contains the peer + * which disconnected. + */ + ENET_EVENT_TYPE_DISCONNECT = 2, + + /** a packet has been received from a peer. The peer field specifies the + * peer which sent the packet. The channelID field specifies the channel + * number upon which the packet was received. The packet field contains + * the packet that was received; this packet must be destroyed with + * enet_packet_destroy after use. + */ + ENET_EVENT_TYPE_RECEIVE = 3 +} ENetEventType; + +/** + * An ENet event as returned by enet_host_service(). + + @sa enet_host_service + */ +typedef struct _ENetEvent +{ + ENetEventType type; /**< type of the event */ + ENetPeer * peer; /**< peer that generated a connect, disconnect or receive event */ + enet_uint8 channelID; + ENetPacket * packet; +} ENetEvent; + +/** @defgroup global ENet global functions + @{ +*/ + +/** + Initializes ENet globally. Must be called prior to using any functions in + ENet. + @returns 0 on success, < 0 on failure +*/ +ENET_API int enet_initialize (void); + +/** + Shuts down ENet globally. Should be called when a program that has + initialized ENet exits. +*/ +ENET_API void enet_deinitialize (void); + +/** @} */ + +/** @defgroup private ENet private implementation functions */ + +/** + Returns the wall-time in milliseconds. Its initial value is unspecified + unless otherwise set. + */ +ENET_API enet_uint32 enet_time_get (void); +/** + Sets the current wall-time in milliseconds. + */ +ENET_API void enet_time_set (enet_uint32); + +/** @defgroup socket ENet socket functions + @{ + @ingroup private +*/ +extern ENetSocket enet_socket_create (ENetSocketType, const ENetAddress *); +extern ENetSocket enet_socket_accept (ENetSocket, ENetAddress *); +extern int enet_socket_connect (ENetSocket, const ENetAddress *); +extern int enet_socket_send (ENetSocket, const ENetAddress *, const ENetBuffer *, size_t); +extern int enet_socket_receive (ENetSocket, ENetAddress *, ENetBuffer *, size_t); +extern int enet_socket_wait (ENetSocket, enet_uint32 *, enet_uint32); +extern void enet_socket_destroy (ENetSocket); + +/** @} */ + +/** @defgroup Address ENet address functions + @{ +*/ +/** Attempts to resolve the host named by the parameter hostName and sets + the host field in the address parameter if successful. + @param address destination to store resolved address + @param hostName host name to lookup + @retval 0 on success + @retval < 0 on failure + @returns the address of the given hostName in address on success +*/ +extern int enet_address_set_host (ENetAddress *address, const char *hostName ); + +/** Attempts to do a reserve lookup of the host field in the address parameter. + @param address address used for reverse lookup + @param hostName destination for name, must not be NULL + @param nameLength maximum length of hostName. + @returns the null-terminated name of the host in hostName on success + @retval 0 on success + @retval < 0 on failure +*/ +extern int enet_address_get_host (const ENetAddress *address, char *hostName, size_t nameLength ); + +/** @} */ + +ENET_API ENetPacket * enet_packet_create (const void *dataContents, size_t dataLength, enet_uint32 flags); +ENET_API void enet_packet_destroy (ENetPacket *packet ); +ENET_API int enet_packet_resize (ENetPacket *packet, size_t dataLength ); + +ENET_API ENetHost * enet_host_create (const ENetAddress *address, size_t peerCount, enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth ); +ENET_API void enet_host_destroy (ENetHost *host ); +ENET_API ENetPeer * enet_host_connect (ENetHost *host, const ENetAddress *address, size_t channelCount ); +ENET_API int enet_host_service (ENetHost *, ENetEvent *, enet_uint32); +ENET_API void enet_host_flush (ENetHost *); +ENET_API void enet_host_broadcast (ENetHost *, enet_uint8, ENetPacket *); +ENET_API void enet_host_bandwidth_limit (ENetHost *, enet_uint32, enet_uint32); +extern void enet_host_bandwidth_throttle (ENetHost *); + +ENET_API int enet_peer_send (ENetPeer *, enet_uint8, ENetPacket *); +ENET_API ENetPacket * enet_peer_receive (ENetPeer *, enet_uint8); +ENET_API void enet_peer_ping (ENetPeer *); +ENET_API void enet_peer_reset (ENetPeer *); +ENET_API void enet_peer_disconnect (ENetPeer *); +ENET_API void enet_peer_disconnect_now (ENetPeer *); +ENET_API void enet_peer_throttle_configure (ENetPeer *, enet_uint32, enet_uint32, enet_uint32); +extern int enet_peer_throttle (ENetPeer *, enet_uint32); +extern void enet_peer_reset_queues (ENetPeer *); +extern ENetOutgoingCommand * enet_peer_queue_outgoing_command (ENetPeer *, const ENetProtocol *, ENetPacket *, enet_uint32, enet_uint16); +extern ENetIncomingCommand * enet_peer_queue_incoming_command (ENetPeer *, const ENetProtocol *, ENetPacket *, enet_uint32); +extern ENetAcknowledgement * enet_peer_queue_acknowledgement (ENetPeer *, const ENetProtocol *, enet_uint32); + +#ifdef __cplusplus +} +#endif + +#endif /* __ENET_ENET_H__ */ + diff --git a/mod/pub.mod/enet.mod/include/enet/list.h b/mod/pub.mod/enet.mod/include/enet/list.h new file mode 100644 index 0000000..99bc4ae --- /dev/null +++ b/mod/pub.mod/enet.mod/include/enet/list.h @@ -0,0 +1,42 @@ +/** + @file list.h + @brief ENet list management +*/ +#ifndef __ENET_LIST_H__ +#define __ENET_LIST_H__ + +#include + +typedef struct _ENetListNode +{ + struct _ENetListNode * next; + struct _ENetListNode * previous; +} ENetListNode; + +typedef ENetListNode * ENetListIterator; + +typedef struct _ENetList +{ + ENetListNode sentinel; +} ENetList; + +extern void enet_list_clear (ENetList *); + +extern ENetListIterator enet_list_insert (ENetListIterator, void *); +extern void * enet_list_remove (ENetListIterator); + +extern size_t enet_list_size (ENetList *); + +#define enet_list_begin(list) ((list) -> sentinel.next) +#define enet_list_end(list) (& (list) -> sentinel) + +#define enet_list_empty(list) (enet_list_begin (list) == enet_list_end (list)) + +#define enet_list_next(iterator) ((iterator) -> next) +#define enet_list_previous(iterator) ((iterator) -> previous) + +#define enet_list_front(list) ((void *) (list) -> sentinel.next) +#define enet_list_back(list) ((void *) (list) -> sentinel.previous) + +#endif /* __ENET_LIST_H__ */ + diff --git a/mod/pub.mod/enet.mod/include/enet/memory.h b/mod/pub.mod/enet.mod/include/enet/memory.h new file mode 100644 index 0000000..13ed76e --- /dev/null +++ b/mod/pub.mod/enet.mod/include/enet/memory.h @@ -0,0 +1,22 @@ +/** + @file memory.h + @brief ENet memory management +*/ +#ifndef __ENET_MEMORY_H__ +#define __ENET_MEMORY_H__ + +#include + +/** @defgroup memory ENet internal memory management + @{ + @ingroup private +*/ +extern void * enet_malloc (size_t); +extern void * enet_realloc (void *, size_t); +extern void * enet_calloc (size_t, size_t); +extern void enet_free (void *); + +/** @} */ + +#endif /* __ENET_MEMORY_H__ */ + diff --git a/mod/pub.mod/enet.mod/include/enet/protocol.h b/mod/pub.mod/enet.mod/include/enet/protocol.h new file mode 100644 index 0000000..51ca532 --- /dev/null +++ b/mod/pub.mod/enet.mod/include/enet/protocol.h @@ -0,0 +1,157 @@ +/** + @file protocol.h + @brief ENet protocol +*/ +#ifndef __ENET_PROTOCOL_H__ +#define __ENET_PROTOCOL_H__ + +#include "enet/types.h" + +enum +{ + ENET_PROTOCOL_MINIMUM_MTU = 576, + ENET_PROTOCOL_MAXIMUM_MTU = 4096, + ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS = 32, + ENET_PROTOCOL_MINIMUM_WINDOW_SIZE = 4096, + ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE = 32768, + ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT = 1, + ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT = 255 +}; + +typedef enum +{ + ENET_PROTOCOL_COMMAND_NONE = 0, + ENET_PROTOCOL_COMMAND_ACKNOWLEDGE = 1, + ENET_PROTOCOL_COMMAND_CONNECT = 2, + ENET_PROTOCOL_COMMAND_VERIFY_CONNECT = 3, + ENET_PROTOCOL_COMMAND_DISCONNECT = 4, + ENET_PROTOCOL_COMMAND_PING = 5, + ENET_PROTOCOL_COMMAND_SEND_RELIABLE = 6, + ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE = 7, + ENET_PROTOCOL_COMMAND_SEND_FRAGMENT = 8, + ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT = 9, + ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE = 10 +} ENetProtocolCommand; + +typedef enum +{ + ENET_PROTOCOL_FLAG_ACKNOWLEDGE = (1 << 0) +} ENetProtocolFlag; + +typedef struct +{ + enet_uint16 peerID; + enet_uint8 flags; + enet_uint8 commandCount; + enet_uint32 sentTime; + enet_uint32 challenge; +} ENetProtocolHeader; + +typedef struct +{ + enet_uint8 command; + enet_uint8 channelID; + enet_uint8 flags; + enet_uint8 reserved; + enet_uint32 commandLength; + enet_uint32 reliableSequenceNumber; +} ENetProtocolCommandHeader; + +typedef struct +{ + ENetProtocolCommandHeader header; + enet_uint32 receivedReliableSequenceNumber; + enet_uint32 receivedSentTime; +} ENetProtocolAcknowledge; + +typedef struct +{ + ENetProtocolCommandHeader header; + enet_uint16 outgoingPeerID; + enet_uint16 mtu; + enet_uint32 windowSize; + enet_uint32 channelCount; + enet_uint32 incomingBandwidth; + enet_uint32 outgoingBandwidth; + enet_uint32 packetThrottleInterval; + enet_uint32 packetThrottleAcceleration; + enet_uint32 packetThrottleDeceleration; +} ENetProtocolConnect; + +typedef struct +{ + ENetProtocolCommandHeader header; + enet_uint16 outgoingPeerID; + enet_uint16 mtu; + enet_uint32 windowSize; + enet_uint32 channelCount; + enet_uint32 incomingBandwidth; + enet_uint32 outgoingBandwidth; + enet_uint32 packetThrottleInterval; + enet_uint32 packetThrottleAcceleration; + enet_uint32 packetThrottleDeceleration; +} ENetProtocolVerifyConnect; + +typedef struct +{ + ENetProtocolCommandHeader header; + enet_uint32 incomingBandwidth; + enet_uint32 outgoingBandwidth; +} ENetProtocolBandwidthLimit; + +typedef struct +{ + ENetProtocolCommandHeader header; + enet_uint32 packetThrottleInterval; + enet_uint32 packetThrottleAcceleration; + enet_uint32 packetThrottleDeceleration; +} ENetProtocolThrottleConfigure; + +typedef struct +{ + ENetProtocolCommandHeader header; +} ENetProtocolDisconnect; + +typedef struct +{ + ENetProtocolCommandHeader header; +} ENetProtocolPing; + +typedef struct +{ + ENetProtocolCommandHeader header; +} ENetProtocolSendReliable; + +typedef struct +{ + ENetProtocolCommandHeader header; + enet_uint32 unreliableSequenceNumber; +} ENetProtocolSendUnreliable; + +typedef struct +{ + ENetProtocolCommandHeader header; + enet_uint32 startSequenceNumber; + enet_uint32 fragmentCount; + enet_uint32 fragmentNumber; + enet_uint32 totalLength; + enet_uint32 fragmentOffset; +} ENetProtocolSendFragment; + +typedef union +{ + ENetProtocolCommandHeader header; + ENetProtocolAcknowledge acknowledge; + ENetProtocolConnect connect; + ENetProtocolVerifyConnect verifyConnect; + ENetProtocolDisconnect disconnect; + ENetProtocolPing ping; + ENetProtocolSendReliable sendReliable; + ENetProtocolSendUnreliable sendUnreliable; + ENetProtocolSendFragment sendFragment; + ENetProtocolBandwidthLimit bandwidthLimit; + ENetProtocolThrottleConfigure throttleConfigure; +} ENetProtocol; + +#endif /* __ENET_PROTOCOL_H__ */ + diff --git a/mod/pub.mod/enet.mod/include/enet/time.h b/mod/pub.mod/enet.mod/include/enet/time.h new file mode 100644 index 0000000..c82a546 --- /dev/null +++ b/mod/pub.mod/enet.mod/include/enet/time.h @@ -0,0 +1,18 @@ +/** + @file time.h + @brief ENet time constants and macros +*/ +#ifndef __ENET_TIME_H__ +#define __ENET_TIME_H__ + +#define ENET_TIME_OVERFLOW 86400000 + +#define ENET_TIME_LESS(a, b) ((a) - (b) >= ENET_TIME_OVERFLOW) +#define ENET_TIME_GREATER(a, b) ((b) - (a) >= ENET_TIME_OVERFLOW) +#define ENET_TIME_LESS_EQUAL(a, b) (! ENET_TIME_GREATER (a, b)) +#define ENET_TIME_GREATER_EQUAL(a, b) (! ENET_TIME_LESS (a, b)) + +#define ENET_TIME_DIFFERENCE(a, b) ((a) - (b) >= ENET_TIME_OVERFLOW ? (b) - (a) : (a) - (b)) + +#endif /* __ENET_TIME_H__ */ + diff --git a/mod/pub.mod/enet.mod/include/enet/types.h b/mod/pub.mod/enet.mod/include/enet/types.h new file mode 100644 index 0000000..ab010a4 --- /dev/null +++ b/mod/pub.mod/enet.mod/include/enet/types.h @@ -0,0 +1,13 @@ +/** + @file types.h + @brief type definitions for ENet +*/ +#ifndef __ENET_TYPES_H__ +#define __ENET_TYPES_H__ + +typedef unsigned char enet_uint8; /**< unsigned 8-bit type */ +typedef unsigned short enet_uint16; /**< unsigned 16-bit type */ +typedef unsigned int enet_uint32; /**< unsigned 32-bit type */ + +#endif /* __ENET_TYPES_H__ */ + diff --git a/mod/pub.mod/enet.mod/include/enet/unix.h b/mod/pub.mod/enet.mod/include/enet/unix.h new file mode 100644 index 0000000..e9fb414 --- /dev/null +++ b/mod/pub.mod/enet.mod/include/enet/unix.h @@ -0,0 +1,32 @@ +/** + @file unix.h + @brief ENet Unix header +*/ +#ifndef __ENET_UNIX_H__ +#define __ENET_UNIX_H__ + +#include +#include +#include + +typedef int ENetSocket; + +enum +{ + ENET_SOCKET_NULL = -1 +}; + +#define ENET_HOST_TO_NET_16(value) (htons (value)) /**< macro that converts host to net byte-order of a 16-bit value */ +#define ENET_HOST_TO_NET_32(value) (htonl (value)) /**< macro that converts host to net byte-order of a 32-bit value */ + +#define ENET_NET_TO_HOST_16(value) (ntohs (value)) /**< macro that converts net to host byte-order of a 16-bit value */ +#define ENET_NET_TO_HOST_32(value) (ntohl (value)) /**< macro that converts net to host byte-order of a 32-bit value */ + +typedef struct +{ + void * data; + size_t dataLength; +} ENetBuffer; + +#endif /* __ENET_UNIX_H__ */ + diff --git a/mod/pub.mod/enet.mod/include/enet/utility.h b/mod/pub.mod/enet.mod/include/enet/utility.h new file mode 100644 index 0000000..e48a476 --- /dev/null +++ b/mod/pub.mod/enet.mod/include/enet/utility.h @@ -0,0 +1,12 @@ +/** + @file utility.h + @brief ENet utility header +*/ +#ifndef __ENET_UTILITY_H__ +#define __ENET_UTILITY_H__ + +#define ENET_MAX(x, y) ((x) > (y) ? (x) : (y)) +#define ENET_MIN(x, y) ((x) < (y) ? (x) : (y)) + +#endif /* __ENET_UTILITY_H__ */ + diff --git a/mod/pub.mod/enet.mod/include/enet/win32.h b/mod/pub.mod/enet.mod/include/enet/win32.h new file mode 100644 index 0000000..8160c8d --- /dev/null +++ b/mod/pub.mod/enet.mod/include/enet/win32.h @@ -0,0 +1,32 @@ +/** + @file win32.h + @brief ENet Win32 header +*/ +#ifndef __ENET_WIN32_H__ +#define __ENET_WIN32_H__ + +#include +#include + +typedef SOCKET ENetSocket; + +enum +{ + ENET_SOCKET_NULL = INVALID_SOCKET +}; + +#define ENET_HOST_TO_NET_16(value) (htons (value)) +#define ENET_HOST_TO_NET_32(value) (htonl (value)) + +#define ENET_NET_TO_HOST_16(value) (ntohs (value)) +#define ENET_NET_TO_HOST_32(value) (ntohl (value)) + +typedef struct +{ + size_t dataLength; + void * data; +} ENetBuffer; + +#endif /* __ENET_WIN32_H__ */ + + diff --git a/mod/pub.mod/enet.mod/license.txt b/mod/pub.mod/enet.mod/license.txt new file mode 100644 index 0000000..a72c6ea --- /dev/null +++ b/mod/pub.mod/enet.mod/license.txt @@ -0,0 +1,26 @@ +/** + @page License License + +Copyright (c) 2002 Lee Salzman + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +*/ + diff --git a/mod/pub.mod/enet.mod/list.c b/mod/pub.mod/enet.mod/list.c new file mode 100644 index 0000000..1a4aa3a --- /dev/null +++ b/mod/pub.mod/enet.mod/list.c @@ -0,0 +1,57 @@ +/** + @file list.c + @brief ENet linked list functions +*/ +#define ENET_BUILDING_LIB 1 +#include "enet/list.h" + +/** + @defgroup list ENet linked list utility functions + @ingroup private + @{ +*/ +void +enet_list_clear (ENetList * list) +{ + list -> sentinel.next = & list -> sentinel; + list -> sentinel.previous = & list -> sentinel; +} + +ENetListIterator +enet_list_insert (ENetListIterator position, void * data) +{ + ENetListIterator result = (ENetListIterator) data; + + result -> previous = position -> previous; + result -> next = position; + + result -> previous -> next = result; + position -> previous = result; + + return result; +} + +void * +enet_list_remove (ENetListIterator position) +{ + position -> previous -> next = position -> next; + position -> next -> previous = position -> previous; + + return position; +} + +size_t +enet_list_size (ENetList * list) +{ + size_t size = 0; + ENetListIterator position; + + for (position = enet_list_begin (list); + position != enet_list_end (list); + position = enet_list_next (position)) + ++ size; + + return size; +} + +/** @} */ diff --git a/mod/pub.mod/enet.mod/memory.c b/mod/pub.mod/enet.mod/memory.c new file mode 100644 index 0000000..02871c0 --- /dev/null +++ b/mod/pub.mod/enet.mod/memory.c @@ -0,0 +1,48 @@ +/** + @file memory.c + @brief ENet memory management functions +*/ +#define ENET_BUILDING_LIB 1 +#include "enet/types.h" +#include "enet/memory.h" + +void * +enet_malloc (size_t size) +{ + void * memory = malloc (size); + + if (memory == NULL) + abort (); + + return memory; +} + +void * +enet_realloc (void * memory, size_t size) +{ + memory = realloc (memory, size); + + if (size > 0 && + memory == NULL) + abort (); + + return memory; +} + +void * +enet_calloc (size_t elements, size_t size) +{ + void * memory = calloc (elements, size); + + if (memory == NULL) + abort (); + + return memory; +} + +void +enet_free (void * memory) +{ + free (memory); +} + diff --git a/mod/pub.mod/enet.mod/packet.c b/mod/pub.mod/enet.mod/packet.c new file mode 100644 index 0000000..7c121e9 --- /dev/null +++ b/mod/pub.mod/enet.mod/packet.c @@ -0,0 +1,73 @@ +/** + @file packet.c + @brief ENet packet management functions +*/ +#include +#define ENET_BUILDING_LIB 1 +#include "enet/memory.h" +#include "enet/enet.h" + +/** @defgroup Packet ENet packet functions + @{ +*/ + +/** Creates a packet that may be sent to a peer. + @param dataContents initial contents of the packet's data; the packet's data will remain uninitialized if dataContents is NULL. + @param dataLength size of the data allocated for this packet + @param flags flags for this packet as described for the ENetPacket structure. + @returns the packet on success, NULL on failure +*/ +ENetPacket * +enet_packet_create (const void * data, size_t dataLength, enet_uint32 flags) +{ + ENetPacket * packet = (ENetPacket *) enet_malloc (sizeof (ENetPacket)); + + packet -> data = (enet_uint8 *) enet_malloc (dataLength); + + if (data != NULL) + memcpy (packet -> data, data, dataLength); + + packet -> referenceCount = 0; + packet -> flags = flags; + packet -> dataLength = dataLength; + + return packet; +} + +/** Destroys the packet and deallocates its data. + @param packet packet to be destroyed +*/ +void +enet_packet_destroy (ENetPacket * packet) +{ + enet_free (packet -> data); + enet_free (packet); +} + +/** Attempts to resize the data in the packet to length specified in the + dataLength parameter + @param packet packet to resize + @param dataLength new size for the packet data + @returns 0 on success, < 0 on failure +*/ +int +enet_packet_resize (ENetPacket * packet, size_t dataLength) +{ + enet_uint8 * newData; + + if (dataLength <= packet -> dataLength) + { + packet -> dataLength = dataLength; + + return 0; + } + + newData = (enet_uint8 *) enet_realloc (packet -> data, dataLength); + + packet -> data = newData; + packet -> dataLength = dataLength; + + return 0; +} + +/** @} */ diff --git a/mod/pub.mod/enet.mod/peer.c b/mod/pub.mod/enet.mod/peer.c new file mode 100644 index 0000000..810a326 --- /dev/null +++ b/mod/pub.mod/enet.mod/peer.c @@ -0,0 +1,613 @@ +/** + @file peer.c + @brief ENet peer management functions +*/ +#define ENET_BUILDING_LIB 1 +#include "enet/memory.h" +#include "enet/enet.h" + +/** @defgroup peer ENet peer functions + @{ +*/ + +/** Configures throttle parameter for a peer. + + Unreliable packets are dropped by ENet in response to the varying conditions + of the Internet connection to the peer. The throttle represents a probability + that an unreliable packet should not be dropped and thus sent by ENet to the peer. + The lowest mean round trip time from the sending of a reliable packet to the + receipt of its acknowledgement is measured over an amount of time specified by + the interval parameter in milliseconds. If a measured round trip time happens to + be significantly less than the mean round trip time measured over the interval, + then the throttle probability is increased to allow more traffic by an amount + specified in the acceleration parameter, which is a ratio to the ENET_PEER_PACKET_THROTTLE_SCALE + constant. If a measured round trip time happens to be significantly greater than + the mean round trip time measured over the interval, then the throttle probability + is decreased to limit traffic by an amount specified in the deceleration parameter, which + is a ratio to the ENET_PEER_PACKET_THROTTLE_SCALE constant. When the throttle has + a value of ENET_PEER_PACKET_THROTTLE_SCALE, on unreliable packets are dropped by + ENet, and so 100% of all unreliable packets will be sent. When the throttle has a + value of 0, all unreliable packets are dropped by ENet, and so 0% of all unreliable + packets will be sent. Intermediate values for the throttle represent intermediate + probabilities between 0% and 100% of unreliable packets being sent. The bandwidth + limits of the local and foreign hosts are taken into account to determine a + sensible limit for the throttle probability above which it should not raise even in + the best of conditions. + + @param peer peer to configure + @param interval interval, in milliseconds, over which to measure lowest mean RTT; the default value is ENET_PEER_PACKET_THROTTLE_INTERVAL. + @param acceleration rate at which to increase the throttle probability as mean RTT declines + @param deceleration rate at which to decrease the throttle probability as mean RTT increases +*/ +void +enet_peer_throttle_configure (ENetPeer * peer, enet_uint32 interval, enet_uint32 acceleration, enet_uint32 deceleration) +{ + ENetProtocol command; + + peer -> packetThrottleInterval = interval; + peer -> packetThrottleAcceleration = acceleration; + peer -> packetThrottleDeceleration = deceleration; + + command.header.command = ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE; + command.header.channelID = 0xFF; + command.header.flags = 0; + command.header.commandLength = sizeof (ENetProtocolThrottleConfigure); + + command.throttleConfigure.packetThrottleInterval = ENET_HOST_TO_NET_32 (interval); + command.throttleConfigure.packetThrottleAcceleration = ENET_HOST_TO_NET_32 (acceleration); + command.throttleConfigure.packetThrottleDeceleration = ENET_HOST_TO_NET_32 (deceleration); + + enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0); +} + +int +enet_peer_throttle (ENetPeer * peer, enet_uint32 rtt) +{ + if (peer -> lastRoundTripTime <= peer -> lastRoundTripTimeVariance) + { + peer -> packetThrottle = peer -> packetThrottleLimit; + } + else + if (rtt < peer -> lastRoundTripTime) + { + peer -> packetThrottle += peer -> packetThrottleAcceleration; + + if (peer -> packetThrottle > peer -> packetThrottleLimit) + peer -> packetThrottle = peer -> packetThrottleLimit; + + return 1; + } + else + if (rtt > peer -> lastRoundTripTime + 2 * peer -> lastRoundTripTimeVariance) + { + if (peer -> packetThrottle > peer -> packetThrottleDeceleration) + peer -> packetThrottle -= peer -> packetThrottleDeceleration; + else + peer -> packetThrottle = 0; + + return -1; + } + + return 0; +} + +/** Queues a packet to be sent. + @param peer destination for the packet + @param channelID channel on which to send + @param packet packet to send + @retval 0 on success + @retval < 0 on failure +*/ +int +enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet) +{ + ENetChannel * channel = & peer -> channels [channelID]; + ENetProtocol command; + size_t fragmentLength; + + if (peer -> state != ENET_PEER_STATE_CONNECTED) + return -1; + + fragmentLength = peer -> mtu - sizeof (ENetProtocolHeader) - sizeof (ENetProtocolSendFragment); + + if (packet -> dataLength > fragmentLength) + { + enet_uint32 fragmentCount = ENET_HOST_TO_NET_32 ((packet -> dataLength + fragmentLength - 1) / fragmentLength), + startSequenceNumber = ENET_HOST_TO_NET_32 (channel -> outgoingReliableSequenceNumber + 1), + fragmentNumber, + fragmentOffset; + + packet -> flags |= ENET_PACKET_FLAG_RELIABLE; + + for (fragmentNumber = 0, + fragmentOffset = 0; + fragmentOffset < packet -> dataLength; + ++ fragmentNumber, + fragmentOffset += fragmentLength) + { + command.header.command = ENET_PROTOCOL_COMMAND_SEND_FRAGMENT; + command.header.channelID = channelID; + command.header.flags = ENET_PROTOCOL_FLAG_ACKNOWLEDGE; + command.header.commandLength = sizeof (ENetProtocolSendFragment); + command.sendFragment.startSequenceNumber = startSequenceNumber; + command.sendFragment.fragmentCount = fragmentCount; + command.sendFragment.fragmentNumber = ENET_HOST_TO_NET_32 (fragmentNumber); + command.sendFragment.totalLength = ENET_HOST_TO_NET_32 (packet -> dataLength); + command.sendFragment.fragmentOffset = ENET_NET_TO_HOST_32 (fragmentOffset); + + if (packet -> dataLength - fragmentOffset < fragmentLength) + fragmentLength = packet -> dataLength - fragmentOffset; + + enet_peer_queue_outgoing_command (peer, & command, packet, fragmentOffset, fragmentLength); + } + + return 0; + } + + command.header.channelID = channelID; + + if (packet -> flags & ENET_PACKET_FLAG_RELIABLE) + { + command.header.command = ENET_PROTOCOL_COMMAND_SEND_RELIABLE; + command.header.flags = ENET_PROTOCOL_FLAG_ACKNOWLEDGE; + command.header.commandLength = sizeof (ENetProtocolSendReliable); + } + else + { + command.header.command = ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE; + command.header.flags = 0; + command.header.commandLength = sizeof (ENetProtocolSendUnreliable); + command.sendUnreliable.unreliableSequenceNumber = ENET_HOST_TO_NET_32 (channel -> outgoingUnreliableSequenceNumber + 1); + } + + enet_peer_queue_outgoing_command (peer, & command, packet, 0, packet -> dataLength); + + return 0; +} + +/** Attempts to dequeue any incoming queued packet. + @param peer peer to dequeue packets from + @param channelID channel on which to receive + @returns a pointer to the packet, or NULL if there are no available incoming queued packets +*/ +ENetPacket * +enet_peer_receive (ENetPeer * peer, enet_uint8 channelID) +{ + ENetChannel * channel = & peer -> channels [channelID]; + ENetIncomingCommand * incomingCommand = NULL; + ENetPacket * packet; + + if (enet_list_empty (& channel -> incomingUnreliableCommands) == 0) + { + incomingCommand = (ENetIncomingCommand *) enet_list_front (& channel -> incomingUnreliableCommands); + + if (incomingCommand -> reliableSequenceNumber > channel -> incomingReliableSequenceNumber) + incomingCommand = NULL; + else + channel -> incomingUnreliableSequenceNumber = incomingCommand -> unreliableSequenceNumber; + } + + if (incomingCommand == NULL && + enet_list_empty (& channel -> incomingReliableCommands) == 0) + { + do + { + incomingCommand = (ENetIncomingCommand *) enet_list_front (& channel -> incomingReliableCommands); + + if (incomingCommand -> fragmentsRemaining > 0 || + incomingCommand -> reliableSequenceNumber > channel -> incomingReliableSequenceNumber + 1) + return NULL; + + if (incomingCommand -> reliableSequenceNumber <= channel -> incomingReliableSequenceNumber) + { + -- incomingCommand -> packet -> referenceCount; + + if (incomingCommand -> packet -> referenceCount == 0) + enet_packet_destroy (incomingCommand -> packet); + + if (incomingCommand -> fragments != NULL) + enet_free (incomingCommand -> fragments); + + enet_list_remove (& incomingCommand -> incomingCommandList); + + enet_free (incomingCommand); + + incomingCommand = NULL; + } + } while (incomingCommand == NULL && + enet_list_empty (& channel -> incomingReliableCommands) == 0); + + if (incomingCommand == NULL) + return NULL; + + channel -> incomingReliableSequenceNumber = incomingCommand -> reliableSequenceNumber; + + if (incomingCommand -> fragmentCount > 0) + channel -> incomingReliableSequenceNumber += incomingCommand -> fragmentCount - 1; + } + + if (incomingCommand == NULL) + return NULL; + + enet_list_remove (& incomingCommand -> incomingCommandList); + + packet = incomingCommand -> packet; + + -- packet -> referenceCount; + + if (incomingCommand -> fragments != NULL) + enet_free (incomingCommand -> fragments); + + enet_free (incomingCommand); + + return packet; +} + +static void +enet_peer_reset_outgoing_commands (ENetList * queue) +{ + ENetOutgoingCommand * outgoingCommand; + + while (enet_list_empty (queue) == 0) + { + outgoingCommand = (ENetOutgoingCommand *) enet_list_remove (enet_list_begin (queue)); + + if (outgoingCommand -> packet != NULL) + { + -- outgoingCommand -> packet -> referenceCount; + + if (outgoingCommand -> packet -> referenceCount == 0) + enet_packet_destroy (outgoingCommand -> packet); + } + + enet_free (outgoingCommand); + } +} + +static void +enet_peer_reset_incoming_commands (ENetList * queue) +{ + ENetIncomingCommand * incomingCommand; + + while (enet_list_empty (queue) == 0) + { + incomingCommand = (ENetIncomingCommand *) enet_list_remove (enet_list_begin (queue)); + + if (incomingCommand -> packet != NULL) + { + -- incomingCommand -> packet -> referenceCount; + + if (incomingCommand -> packet -> referenceCount == 0) + enet_packet_destroy (incomingCommand -> packet); + } + + enet_free (incomingCommand); + } +} + +void +enet_peer_reset_queues (ENetPeer * peer) +{ + ENetChannel * channel; + + while (enet_list_empty (& peer -> acknowledgements) == 0) + enet_free (enet_list_remove (enet_list_begin (& peer -> acknowledgements))); + + enet_peer_reset_outgoing_commands (& peer -> sentReliableCommands); + enet_peer_reset_outgoing_commands (& peer -> sentUnreliableCommands); + enet_peer_reset_outgoing_commands (& peer -> outgoingReliableCommands); + enet_peer_reset_outgoing_commands (& peer -> outgoingUnreliableCommands); + + if (peer -> channels != NULL && peer -> channelCount > 0) + { + for (channel = peer -> channels; + channel < & peer -> channels [peer -> channelCount]; + ++ channel) + { + enet_peer_reset_incoming_commands (& channel -> incomingReliableCommands); + enet_peer_reset_incoming_commands (& channel -> incomingUnreliableCommands); + } + + enet_free (peer -> channels); + } + + peer -> channels = NULL; + peer -> channelCount = 0; +} + +/** Forcefully disconnects a peer. + @param peer peer to forcefully disconnect + @remarks The foreign host represented by the peer is not notified of the disconnection and will timeout + on its connection to the local host. +*/ +void +enet_peer_reset (ENetPeer * peer) +{ + peer -> outgoingPeerID = 0xFFFF; + peer -> challenge = 0; + + peer -> address.host = ENET_HOST_ANY; + peer -> address.port = 0; + + peer -> state = ENET_PEER_STATE_DISCONNECTED; + + peer -> incomingBandwidth = 0; + peer -> outgoingBandwidth = 0; + peer -> incomingBandwidthThrottleEpoch = 0; + peer -> outgoingBandwidthThrottleEpoch = 0; + peer -> incomingDataTotal = 0; + peer -> outgoingDataTotal = 0; + peer -> lastSendTime = 0; + peer -> lastReceiveTime = 0; + peer -> nextTimeout = 0; + peer -> packetLossEpoch = 0; + peer -> packetsSent = 0; + peer -> packetsLost = 0; + peer -> packetLoss = 0; + peer -> packetLossVariance = 0; + peer -> packetThrottle = ENET_PEER_DEFAULT_PACKET_THROTTLE; + peer -> packetThrottleLimit = ENET_PEER_PACKET_THROTTLE_SCALE; + peer -> packetThrottleCounter = 0; + peer -> packetThrottleEpoch = 0; + peer -> packetThrottleAcceleration = ENET_PEER_PACKET_THROTTLE_ACCELERATION; + peer -> packetThrottleDeceleration = ENET_PEER_PACKET_THROTTLE_DECELERATION; + peer -> packetThrottleInterval = ENET_PEER_PACKET_THROTTLE_INTERVAL; + peer -> lastRoundTripTime = ENET_PEER_DEFAULT_ROUND_TRIP_TIME; + peer -> lowestRoundTripTime = ENET_PEER_DEFAULT_ROUND_TRIP_TIME; + peer -> lastRoundTripTimeVariance = 0; + peer -> highestRoundTripTimeVariance = 0; + peer -> roundTripTime = ENET_PEER_DEFAULT_ROUND_TRIP_TIME; + peer -> roundTripTimeVariance = 0; + peer -> mtu = peer -> host -> mtu; + peer -> reliableDataInTransit = 0; + peer -> outgoingReliableSequenceNumber = 0; + peer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; + + enet_peer_reset_queues (peer); +} + +/** Sends a ping request to a peer. + @param peer destination for the ping request + @remarks ping requests factor into the mean round trip time as designated by the + roundTripTime field in the ENetPeer structure. Enet automatically pings all connected + peers at regular intervals, however, this function may be called to ensure more + frequent ping requests. +*/ +void +enet_peer_ping (ENetPeer * peer) +{ + ENetProtocol command; + + if (peer -> state != ENET_PEER_STATE_CONNECTED) + return; + + command.header.command = ENET_PROTOCOL_COMMAND_PING; + command.header.channelID = 0xFF; + command.header.flags = ENET_PROTOCOL_FLAG_ACKNOWLEDGE; + command.header.commandLength = sizeof (ENetProtocolPing); + + enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0); +} + +/** Force an immediate disconnection from a peer. + @param peer peer to disconnect + @remarks No ENET_EVENT_DISCONNECT event will be generated. The foreign peer is not + guarenteed to receive the disconnect notification, and is reset immediately upon + return from this function. +*/ +void +enet_peer_disconnect_now (ENetPeer * peer) +{ + ENetProtocol command; + + if (peer -> state != ENET_PEER_STATE_DISCONNECTED) + return; + + if (peer -> state != ENET_PEER_STATE_ZOMBIE && + peer -> state != ENET_PEER_STATE_DISCONNECTING) + { + enet_peer_reset_queues (peer); + + command.header.command = ENET_PROTOCOL_COMMAND_DISCONNECT; + command.header.channelID = 0xFF; + command.header.flags = 0; + command.header.commandLength = sizeof (ENetProtocolDisconnect); + + enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0); + + enet_host_flush (peer -> host); + } + + enet_peer_reset (peer); +} + +/** Request a disconnection from a peer. + @param peer peer to request a disconnection + @remarks An ENET_EVENT_DISCONNECT event will be generated by enet_host_service() + once the disconnection is complete. +*/ +void +enet_peer_disconnect (ENetPeer * peer) +{ + ENetProtocol command; + + if (peer -> state == ENET_PEER_STATE_DISCONNECTING || + peer -> state == ENET_PEER_STATE_DISCONNECTED || + peer -> state == ENET_PEER_STATE_ZOMBIE) + return; + + enet_peer_reset_queues (peer); + + command.header.command = ENET_PROTOCOL_COMMAND_DISCONNECT; + command.header.channelID = 0xFF; + command.header.flags = 0; + command.header.commandLength = sizeof (ENetProtocolDisconnect); + + if (peer -> state == ENET_PEER_STATE_CONNECTED) + command.header.flags |= ENET_PROTOCOL_FLAG_ACKNOWLEDGE; + + enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0); + + if (peer -> state == ENET_PEER_STATE_CONNECTED) + peer -> state = ENET_PEER_STATE_DISCONNECTING; + else + { + enet_host_flush (peer -> host); + enet_peer_reset (peer); + } +} + +ENetAcknowledgement * +enet_peer_queue_acknowledgement (ENetPeer * peer, const ENetProtocol * command, enet_uint32 sentTime) +{ + ENetAcknowledgement * acknowledgement; + + peer -> outgoingDataTotal += sizeof (ENetProtocolAcknowledge); + + acknowledgement = (ENetAcknowledgement *) enet_malloc (sizeof (ENetAcknowledgement)); + + acknowledgement -> sentTime = sentTime; + acknowledgement -> command = * command; + + enet_list_insert (enet_list_end (& peer -> acknowledgements), acknowledgement); + + return acknowledgement; +} + +ENetOutgoingCommand * +enet_peer_queue_outgoing_command (ENetPeer * peer, const ENetProtocol * command, ENetPacket * packet, enet_uint32 offset, enet_uint16 length) +{ + ENetChannel * channel = & peer -> channels [command -> header.channelID]; + ENetOutgoingCommand * outgoingCommand; + + peer -> outgoingDataTotal += command -> header.commandLength + length; + + outgoingCommand = (ENetOutgoingCommand *) enet_malloc (sizeof (ENetOutgoingCommand)); + + if (command -> header.channelID == 0xFF) + { + ++ peer -> outgoingReliableSequenceNumber; + + outgoingCommand -> reliableSequenceNumber = peer -> outgoingReliableSequenceNumber; + outgoingCommand -> unreliableSequenceNumber = 0; + } + else + if (command -> header.flags & ENET_PROTOCOL_FLAG_ACKNOWLEDGE) + { + ++ channel -> outgoingReliableSequenceNumber; + + outgoingCommand -> reliableSequenceNumber = channel -> outgoingReliableSequenceNumber; + outgoingCommand -> unreliableSequenceNumber = 0; + } + else + { + ++ channel -> outgoingUnreliableSequenceNumber; + + outgoingCommand -> reliableSequenceNumber = channel -> outgoingReliableSequenceNumber; + outgoingCommand -> unreliableSequenceNumber = channel -> outgoingUnreliableSequenceNumber; + } + + outgoingCommand -> sentTime = 0; + outgoingCommand -> roundTripTimeout = 0; + outgoingCommand -> roundTripTimeoutLimit = 0; + outgoingCommand -> fragmentOffset = offset; + outgoingCommand -> fragmentLength = length; + outgoingCommand -> packet = packet; + outgoingCommand -> command = * command; + outgoingCommand -> command.header.reliableSequenceNumber = ENET_HOST_TO_NET_32 (outgoingCommand -> reliableSequenceNumber); + + if (packet != NULL) + ++ packet -> referenceCount; + + if (command -> header.flags & ENET_PROTOCOL_FLAG_ACKNOWLEDGE) + enet_list_insert (enet_list_end (& peer -> outgoingReliableCommands), outgoingCommand); + else + enet_list_insert (enet_list_end (& peer -> outgoingUnreliableCommands), outgoingCommand); + + return outgoingCommand; +} + +ENetIncomingCommand * +enet_peer_queue_incoming_command (ENetPeer * peer, const ENetProtocol * command, ENetPacket * packet, enet_uint32 fragmentCount) +{ + ENetChannel * channel = & peer -> channels [command -> header.channelID]; + enet_uint32 unreliableSequenceNumber = 0; + ENetIncomingCommand * incomingCommand; + ENetListIterator currentCommand; + + if (command -> header.command == ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE) + unreliableSequenceNumber = ENET_NET_TO_HOST_32 (command -> sendUnreliable.unreliableSequenceNumber); + + if (unreliableSequenceNumber == 0) + { + for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingReliableCommands)); + currentCommand != enet_list_end (& channel -> incomingReliableCommands); + currentCommand = enet_list_previous (currentCommand)) + { + incomingCommand = (ENetIncomingCommand *) currentCommand; + + if (incomingCommand -> reliableSequenceNumber <= command -> header.reliableSequenceNumber) + { + if (incomingCommand -> reliableSequenceNumber < command -> header.reliableSequenceNumber) + break; + + goto freePacket; + } + } + } + else + { + if (command -> header.reliableSequenceNumber < channel -> incomingReliableSequenceNumber) + goto freePacket; + + if (unreliableSequenceNumber <= channel -> incomingUnreliableSequenceNumber) + goto freePacket; + + for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingUnreliableCommands)); + currentCommand != enet_list_end (& channel -> incomingUnreliableCommands); + currentCommand = enet_list_previous (currentCommand)) + { + incomingCommand = (ENetIncomingCommand *) currentCommand; + + if (incomingCommand -> unreliableSequenceNumber <= unreliableSequenceNumber) + { + if (incomingCommand -> unreliableSequenceNumber < unreliableSequenceNumber) + break; + + goto freePacket; + } + } + } + + incomingCommand = (ENetIncomingCommand *) enet_malloc (sizeof (ENetIncomingCommand)); + + incomingCommand -> reliableSequenceNumber = command -> header.reliableSequenceNumber; + incomingCommand -> unreliableSequenceNumber = unreliableSequenceNumber; + incomingCommand -> command = * command; + incomingCommand -> fragmentCount = fragmentCount; + incomingCommand -> fragmentsRemaining = fragmentCount; + incomingCommand -> packet = packet; + + if (fragmentCount > 0) + incomingCommand -> fragments = (enet_uint32 *) enet_calloc ((fragmentCount + 31) / 32, sizeof (enet_uint32)); + else + incomingCommand -> fragments = NULL; + + if (packet != NULL) + ++ packet -> referenceCount; + + enet_list_insert (enet_list_next (currentCommand), incomingCommand); + + return incomingCommand; + +freePacket: + if (packet != NULL) + { + if (packet -> referenceCount == 0) + enet_packet_destroy (packet); + } + + return NULL; +} + +/** @} */ diff --git a/mod/pub.mod/enet.mod/protocol.c b/mod/pub.mod/enet.mod/protocol.c new file mode 100644 index 0000000..8321f6d --- /dev/null +++ b/mod/pub.mod/enet.mod/protocol.c @@ -0,0 +1,1260 @@ +/** + @file protocol.c + @brief ENet protocol functions +*/ +#include +#include +#define ENET_BUILDING_LIB 1 +#include "enet/utility.h" +#include "enet/memory.h" +#include "enet/time.h" +#include "enet/enet.h" + +static enet_uint32 timeCurrent; + +static int +enet_protocol_dispatch_incoming_commands (ENetHost * host, ENetEvent * event) +{ + ENetPeer * currentPeer = host -> lastServicedPeer; + ENetChannel * channel; + + do + { + ++ currentPeer; + + if (currentPeer >= & host -> peers [host -> peerCount]) + currentPeer = host -> peers; + + if (currentPeer -> state == ENET_PEER_STATE_ZOMBIE) + { + host -> recalculateBandwidthLimits = 1; + + event -> type = ENET_EVENT_TYPE_DISCONNECT; + event -> peer = currentPeer; + + enet_peer_reset (currentPeer); + + host -> lastServicedPeer = currentPeer; + + return 1; + } + + if (currentPeer -> state != ENET_PEER_STATE_CONNECTED) + continue; + + for (channel = currentPeer -> channels; + channel < & currentPeer -> channels [currentPeer -> channelCount]; + ++ channel) + { + if (enet_list_empty (& channel -> incomingReliableCommands) && + enet_list_empty (& channel -> incomingUnreliableCommands)) + continue; + + event -> packet = enet_peer_receive (currentPeer, channel - currentPeer -> channels); + if (event -> packet == NULL) + continue; + + event -> type = ENET_EVENT_TYPE_RECEIVE; + event -> peer = currentPeer; + event -> channelID = (enet_uint8) (channel - currentPeer -> channels); + + host -> lastServicedPeer = currentPeer; + + return 1; + } + } while (currentPeer != host -> lastServicedPeer); + + return 0; +} + +static void +enet_protocol_remove_sent_unreliable_commands (ENetPeer * peer) +{ + ENetOutgoingCommand * outgoingCommand; + + while (enet_list_empty (& peer -> sentUnreliableCommands) == 0) + { + outgoingCommand = (ENetOutgoingCommand *) enet_list_front (& peer -> sentUnreliableCommands); + + enet_list_remove (& outgoingCommand -> outgoingCommandList); + + if (outgoingCommand -> packet != NULL) + { + -- outgoingCommand -> packet -> referenceCount; + + if (outgoingCommand -> packet -> referenceCount == 0) + enet_packet_destroy (outgoingCommand -> packet); + } + + enet_free (outgoingCommand); + } +} + +static ENetProtocolCommand +enet_protocol_remove_sent_reliable_command (ENetPeer * peer, enet_uint32 reliableSequenceNumber, enet_uint8 channelID) +{ + ENetOutgoingCommand * outgoingCommand; + ENetListIterator currentCommand; + ENetProtocolCommand commandNumber; + + for (currentCommand = enet_list_begin (& peer -> sentReliableCommands); + currentCommand != enet_list_end (& peer -> sentReliableCommands); + currentCommand = enet_list_next (currentCommand)) + { + outgoingCommand = (ENetOutgoingCommand *) currentCommand; + + if (outgoingCommand -> reliableSequenceNumber == reliableSequenceNumber && + outgoingCommand -> command.header.channelID == channelID) + break; + } + + if (currentCommand == enet_list_end (& peer -> sentReliableCommands)) + return ENET_PROTOCOL_COMMAND_NONE; + + commandNumber = outgoingCommand -> command.header.command; + + enet_list_remove (& outgoingCommand -> outgoingCommandList); + + if (outgoingCommand -> packet != NULL) + { + peer -> reliableDataInTransit -= outgoingCommand -> fragmentLength; + + -- outgoingCommand -> packet -> referenceCount; + + if (outgoingCommand -> packet -> referenceCount == 0) + enet_packet_destroy (outgoingCommand -> packet); + } + + enet_free (outgoingCommand); + + if (enet_list_empty (& peer -> sentReliableCommands)) + return commandNumber; + + outgoingCommand = (ENetOutgoingCommand *) enet_list_front (& peer -> sentReliableCommands); + + peer -> nextTimeout = outgoingCommand -> sentTime + outgoingCommand -> roundTripTimeout; + + return commandNumber; +} + +static ENetPeer * +enet_protocol_handle_connect (ENetHost * host, const ENetProtocolHeader * header, const ENetProtocol * command) +{ + enet_uint16 mtu; + enet_uint32 windowSize; + ENetChannel * channel; + size_t channelCount; + ENetPeer * currentPeer; + ENetProtocol verifyCommand; + + if (command -> header.commandLength < sizeof (ENetProtocolConnect)) + return NULL; + + channelCount = ENET_NET_TO_HOST_32 (command -> connect.channelCount); + + if (channelCount < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT || + channelCount > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT) + return NULL; + + for (currentPeer = host -> peers; + currentPeer < & host -> peers [host -> peerCount]; + ++ currentPeer) + { + if (currentPeer -> state != ENET_PEER_STATE_DISCONNECTED && + currentPeer -> address.host == host -> receivedAddress.host && + currentPeer -> address.port == host -> receivedAddress.port && + currentPeer -> challenge == header -> challenge) + return NULL; + } + + for (currentPeer = host -> peers; + currentPeer < & host -> peers [host -> peerCount]; + ++ currentPeer) + { + if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED) + break; + } + + if (currentPeer >= & host -> peers [host -> peerCount]) + return NULL; + + currentPeer -> state = ENET_PEER_STATE_ACKNOWLEDGING_CONNECT; + currentPeer -> challenge = header -> challenge; + currentPeer -> address = host -> receivedAddress; + currentPeer -> outgoingPeerID = ENET_NET_TO_HOST_16 (command -> connect.outgoingPeerID); + currentPeer -> incomingBandwidth = ENET_NET_TO_HOST_32 (command -> connect.incomingBandwidth); + currentPeer -> outgoingBandwidth = ENET_NET_TO_HOST_32 (command -> connect.outgoingBandwidth); + currentPeer -> packetThrottleInterval = ENET_NET_TO_HOST_32 (command -> connect.packetThrottleInterval); + currentPeer -> packetThrottleAcceleration = ENET_NET_TO_HOST_32 (command -> connect.packetThrottleAcceleration); + currentPeer -> packetThrottleDeceleration = ENET_NET_TO_HOST_32 (command -> connect.packetThrottleDeceleration); + currentPeer -> channels = (ENetChannel *) enet_malloc (channelCount * sizeof (ENetChannel)); + currentPeer -> channelCount = channelCount; + + for (channel = currentPeer -> channels; + channel < & currentPeer -> channels [channelCount]; + ++ channel) + { + channel -> outgoingReliableSequenceNumber = 0; + channel -> outgoingUnreliableSequenceNumber = 0; + channel -> incomingReliableSequenceNumber = 0; + channel -> incomingUnreliableSequenceNumber = 0; + + enet_list_clear (& channel -> incomingReliableCommands); + enet_list_clear (& channel -> incomingUnreliableCommands); + } + + mtu = ENET_NET_TO_HOST_16 (command -> connect.mtu); + + if (mtu < ENET_PROTOCOL_MINIMUM_MTU) + mtu = ENET_PROTOCOL_MINIMUM_MTU; + else + if (mtu > ENET_PROTOCOL_MAXIMUM_MTU) + mtu = ENET_PROTOCOL_MAXIMUM_MTU; + + currentPeer -> mtu = mtu; + + if (host -> outgoingBandwidth == 0 && + currentPeer -> incomingBandwidth == 0) + currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; + else + currentPeer -> windowSize = (ENET_MIN (host -> outgoingBandwidth, currentPeer -> incomingBandwidth) / + ENET_PEER_WINDOW_SIZE_SCALE) * + ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; + + if (currentPeer -> windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE) + currentPeer -> windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; + else + if (currentPeer -> windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE) + currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; + + if (host -> incomingBandwidth == 0) + windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; + else + windowSize = (host -> incomingBandwidth / ENET_PEER_WINDOW_SIZE_SCALE) * + ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; + + if (windowSize > ENET_NET_TO_HOST_32 (command -> connect.windowSize)) + windowSize = ENET_NET_TO_HOST_32 (command -> connect.windowSize); + + if (windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE) + windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; + else + if (windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE) + windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; + + verifyCommand.header.command = ENET_PROTOCOL_COMMAND_VERIFY_CONNECT; + verifyCommand.header.channelID = 0xFF; + verifyCommand.header.flags = ENET_PROTOCOL_FLAG_ACKNOWLEDGE; + verifyCommand.header.commandLength = sizeof (ENetProtocolVerifyConnect); + verifyCommand.verifyConnect.outgoingPeerID = ENET_HOST_TO_NET_16 (currentPeer -> incomingPeerID); + verifyCommand.verifyConnect.mtu = ENET_HOST_TO_NET_16 (currentPeer -> mtu); + verifyCommand.verifyConnect.windowSize = ENET_HOST_TO_NET_32 (windowSize); + verifyCommand.verifyConnect.channelCount = ENET_HOST_TO_NET_32 (channelCount); + verifyCommand.verifyConnect.incomingBandwidth = ENET_HOST_TO_NET_32 (host -> incomingBandwidth); + verifyCommand.verifyConnect.outgoingBandwidth = ENET_HOST_TO_NET_32 (host -> outgoingBandwidth); + verifyCommand.verifyConnect.packetThrottleInterval = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleInterval); + verifyCommand.verifyConnect.packetThrottleAcceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleAcceleration); + verifyCommand.verifyConnect.packetThrottleDeceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleDeceleration); + + enet_peer_queue_outgoing_command (currentPeer, & verifyCommand, NULL, 0, 0); + + return currentPeer; +} + +static void +enet_protocol_handle_send_reliable (ENetHost * host, ENetPeer * peer, const ENetProtocol * command) +{ + ENetPacket * packet; + + if (command -> header.commandLength <= sizeof (ENetProtocolSendReliable) || + command -> header.channelID >= peer -> channelCount || + peer -> state != ENET_PEER_STATE_CONNECTED) + return; + + packet = enet_packet_create ((const enet_uint8 *) command + sizeof (ENetProtocolSendReliable), + command -> header.commandLength - sizeof (ENetProtocolSendReliable), + ENET_PACKET_FLAG_RELIABLE); + + enet_peer_queue_incoming_command (peer, command, packet, 0); +} + +static void +enet_protocol_handle_send_unreliable (ENetHost * host, ENetPeer * peer, const ENetProtocol * command) +{ + ENetPacket * packet; + + if (command -> header.commandLength <= sizeof (ENetProtocolSendUnreliable) || + command -> header.channelID >= peer -> channelCount || + peer -> state != ENET_PEER_STATE_CONNECTED) + return; + + packet = enet_packet_create ((const enet_uint8 *) command + sizeof (ENetProtocolSendUnreliable), + command -> header.commandLength - sizeof (ENetProtocolSendUnreliable), + 0); + + enet_peer_queue_incoming_command (peer, command, packet, 0); +} + +static void +enet_protocol_handle_send_fragment (ENetHost * host, ENetPeer * peer, const ENetProtocol * command) +{ + enet_uint32 fragmentNumber, + fragmentCount, + fragmentOffset, + fragmentLength, + startSequenceNumber, + totalLength; + ENetChannel * channel; + ENetListIterator currentCommand; + ENetIncomingCommand * startCommand; + + if (command -> header.commandLength <= sizeof (ENetProtocolSendFragment) || + command -> header.channelID >= peer -> channelCount || + peer -> state != ENET_PEER_STATE_CONNECTED) + return; + + startSequenceNumber = ENET_NET_TO_HOST_32 (command -> sendFragment.startSequenceNumber); + fragmentNumber = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentNumber); + fragmentCount = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentCount); + fragmentOffset = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentOffset); + totalLength = ENET_NET_TO_HOST_32 (command -> sendFragment.totalLength); + fragmentLength = command -> header.commandLength - sizeof (ENetProtocolSendFragment); + + if (fragmentOffset >= totalLength || + fragmentOffset + fragmentLength > totalLength || + fragmentNumber >= fragmentCount) + return; + + channel = & peer -> channels [command -> header.channelID]; + + if (startSequenceNumber <= channel -> incomingReliableSequenceNumber) + return; + + for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingReliableCommands)); + currentCommand != enet_list_end (& channel -> incomingReliableCommands); + currentCommand = enet_list_previous (currentCommand)) + { + startCommand = (ENetIncomingCommand *) currentCommand; + + if (startCommand -> command.header.command == ENET_PROTOCOL_COMMAND_SEND_FRAGMENT && + startCommand -> command.sendFragment.startSequenceNumber == startSequenceNumber) + break; + } + + if (currentCommand == enet_list_end (& channel -> incomingReliableCommands)) + { + ENetProtocol hostCommand = * command; + + hostCommand.sendFragment.startSequenceNumber = startSequenceNumber; + hostCommand.sendFragment.fragmentNumber = fragmentNumber; + hostCommand.sendFragment.fragmentCount = fragmentCount; + hostCommand.sendFragment.fragmentOffset = fragmentOffset; + hostCommand.sendFragment.totalLength = totalLength; + + startCommand = enet_peer_queue_incoming_command (peer, + & hostCommand, + enet_packet_create (NULL, totalLength, ENET_PACKET_FLAG_RELIABLE), + fragmentCount); + } + else + if (totalLength != startCommand -> packet -> dataLength || + fragmentCount != startCommand -> fragmentCount) + return; + + if ((startCommand -> fragments [fragmentNumber / 32] & (1 << fragmentNumber)) == 0) + -- startCommand -> fragmentsRemaining; + + startCommand -> fragments [fragmentNumber / 32] |= (1 << fragmentNumber); + + if (fragmentOffset + fragmentLength > startCommand -> packet -> dataLength) + fragmentLength = startCommand -> packet -> dataLength - fragmentOffset; + + memcpy (startCommand -> packet -> data + fragmentOffset, + (enet_uint8 *) command + sizeof (ENetProtocolSendFragment), + fragmentLength); +} + +static void +enet_protocol_handle_ping (ENetHost * host, ENetPeer * peer, const ENetProtocol * command) +{ + if (command -> header.commandLength < sizeof (ENetProtocolPing)) + return; +} + +static void +enet_protocol_handle_bandwidth_limit (ENetHost * host, ENetPeer * peer, const ENetProtocol * command) +{ + if (command -> header.commandLength < sizeof (ENetProtocolBandwidthLimit)) + return; + + peer -> incomingBandwidth = ENET_NET_TO_HOST_32 (command -> bandwidthLimit.incomingBandwidth); + peer -> outgoingBandwidth = ENET_NET_TO_HOST_32 (command -> bandwidthLimit.outgoingBandwidth); + + if (peer -> incomingBandwidth == 0 && + host -> outgoingBandwidth == 0) + peer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; + else + peer -> windowSize = (ENET_MIN (peer -> incomingBandwidth, host -> outgoingBandwidth) / + ENET_PEER_WINDOW_SIZE_SCALE) * ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; + + if (peer -> windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE) + peer -> windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; + else + if (peer -> windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE) + peer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; +} + +static void +enet_protocol_handle_throttle_configure (ENetHost * host, ENetPeer * peer, const ENetProtocol * command) +{ + if (command -> header.commandLength < sizeof (ENetProtocolThrottleConfigure)) + return; + + peer -> packetThrottleInterval = ENET_NET_TO_HOST_32 (command -> throttleConfigure.packetThrottleInterval); + peer -> packetThrottleAcceleration = ENET_NET_TO_HOST_32 (command -> throttleConfigure.packetThrottleAcceleration); + peer -> packetThrottleDeceleration = ENET_NET_TO_HOST_32 (command -> throttleConfigure.packetThrottleDeceleration); +} + +static void +enet_protocol_handle_disconnect (ENetHost * host, ENetPeer * peer, const ENetProtocol * command) +{ + if (command -> header.commandLength < sizeof (ENetProtocolDisconnect)) + return; + + enet_peer_reset_queues (peer); + + if (peer -> state != ENET_PEER_STATE_CONNECTED) + enet_peer_reset (peer); + else + if (command -> header.flags & ENET_PROTOCOL_FLAG_ACKNOWLEDGE) + peer -> state = ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT; + else + peer -> state = ENET_PEER_STATE_ZOMBIE; +} + +static int +enet_protocol_handle_acknowledge (ENetHost * host, ENetEvent * event, ENetPeer * peer, const ENetProtocol * command) +{ + enet_uint32 roundTripTime, + receivedSentTime, + receivedReliableSequenceNumber; + ENetProtocolCommand commandNumber; + + if (command -> header.commandLength < sizeof (ENetProtocolAcknowledge)) + return 0; + + receivedSentTime = ENET_NET_TO_HOST_32 (command -> acknowledge.receivedSentTime); + + if (ENET_TIME_LESS (timeCurrent, receivedSentTime)) + return 0; + + peer -> lastReceiveTime = timeCurrent; + + roundTripTime = ENET_TIME_DIFFERENCE (timeCurrent, receivedSentTime); + + enet_peer_throttle (peer, roundTripTime); + + peer -> roundTripTimeVariance -= peer -> roundTripTimeVariance / 4; + + if (roundTripTime >= peer -> roundTripTime) + { + peer -> roundTripTime += (roundTripTime - peer -> roundTripTime) / 8; + peer -> roundTripTimeVariance += (roundTripTime - peer -> roundTripTime) / 4; + } + else + { + peer -> roundTripTime -= (peer -> roundTripTime - roundTripTime) / 8; + peer -> roundTripTimeVariance += (peer -> roundTripTime - roundTripTime) / 4; + } + + if (peer -> roundTripTime < peer -> lowestRoundTripTime) + peer -> lowestRoundTripTime = peer -> roundTripTime; + + if (peer -> roundTripTimeVariance > peer -> highestRoundTripTimeVariance) + peer -> highestRoundTripTimeVariance = peer -> roundTripTimeVariance; + + if (peer -> packetThrottleEpoch == 0 || + ENET_TIME_DIFFERENCE(timeCurrent, peer -> packetThrottleEpoch) >= peer -> packetThrottleInterval) + { + peer -> lastRoundTripTime = peer -> lowestRoundTripTime; + peer -> lastRoundTripTimeVariance = peer -> highestRoundTripTimeVariance; + peer -> lowestRoundTripTime = peer -> roundTripTime; + peer -> highestRoundTripTimeVariance = peer -> roundTripTimeVariance; + peer -> packetThrottleEpoch = timeCurrent; + } + + receivedReliableSequenceNumber = ENET_NET_TO_HOST_32 (command -> acknowledge.receivedReliableSequenceNumber); + + commandNumber = enet_protocol_remove_sent_reliable_command (peer, receivedReliableSequenceNumber, command -> header.channelID); + + switch (peer -> state) + { + case ENET_PEER_STATE_ACKNOWLEDGING_CONNECT: + if (commandNumber != ENET_PROTOCOL_COMMAND_VERIFY_CONNECT) + return 0; + + host -> recalculateBandwidthLimits = 1; + + peer -> state = ENET_PEER_STATE_CONNECTED; + + event -> type = ENET_EVENT_TYPE_CONNECT; + event -> peer = peer; + + return 1; + + case ENET_PEER_STATE_DISCONNECTING: + if (commandNumber != ENET_PROTOCOL_COMMAND_DISCONNECT) + return 0; + + host -> recalculateBandwidthLimits = 1; + + event -> type = ENET_EVENT_TYPE_DISCONNECT; + event -> peer = peer; + + enet_peer_reset (peer); + + return 1; + + default: + break; + } + + return 0; +} + +static void +enet_protocol_handle_verify_connect (ENetHost * host, ENetEvent * event, ENetPeer * peer, const ENetProtocol * command) +{ + enet_uint16 mtu; + enet_uint32 windowSize; + + if (command -> header.commandLength < sizeof (ENetProtocolVerifyConnect) || + peer -> state != ENET_PEER_STATE_CONNECTING) + return; + + if (ENET_NET_TO_HOST_32 (command -> verifyConnect.channelCount) != peer -> channelCount || + ENET_NET_TO_HOST_32 (command -> verifyConnect.packetThrottleInterval) != peer -> packetThrottleInterval || + ENET_NET_TO_HOST_32 (command -> verifyConnect.packetThrottleAcceleration) != peer -> packetThrottleAcceleration || + ENET_NET_TO_HOST_32 (command -> verifyConnect.packetThrottleDeceleration) != peer -> packetThrottleDeceleration) + { + peer -> state = ENET_PEER_STATE_ZOMBIE; + + return; + } + + peer -> outgoingPeerID = ENET_NET_TO_HOST_16 (command -> verifyConnect.outgoingPeerID); + + mtu = ENET_NET_TO_HOST_16 (command -> verifyConnect.mtu); + + if (mtu < ENET_PROTOCOL_MINIMUM_MTU) + mtu = ENET_PROTOCOL_MINIMUM_MTU; + else + if (mtu > ENET_PROTOCOL_MAXIMUM_MTU) + mtu = ENET_PROTOCOL_MAXIMUM_MTU; + + if (mtu < peer -> mtu) + peer -> mtu = mtu; + + windowSize = ENET_NET_TO_HOST_32 (command -> verifyConnect.windowSize); + + if (windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE) + windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; + + if (windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE) + windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; + + if (windowSize < peer -> windowSize) + peer -> windowSize = windowSize; + + peer -> incomingBandwidth = ENET_NET_TO_HOST_32 (command -> verifyConnect.incomingBandwidth); + peer -> outgoingBandwidth = ENET_NET_TO_HOST_32 (command -> verifyConnect.outgoingBandwidth); + + host -> recalculateBandwidthLimits = 1; + + peer -> state = ENET_PEER_STATE_CONNECTED; + + event -> type = ENET_EVENT_TYPE_CONNECT; + event -> peer = peer; +} + +static int +enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event) +{ + ENetProtocolHeader * header; + ENetProtocol * command; + ENetPeer * peer; + enet_uint8 * currentData; + size_t commandCount; + + if (host -> receivedDataLength < sizeof (ENetProtocolHeader)) + return 0; + + header = (ENetProtocolHeader *) host -> receivedData; + + header -> peerID = ENET_NET_TO_HOST_16 (header -> peerID); + header -> sentTime = ENET_NET_TO_HOST_32 (header -> sentTime); + + if (header -> peerID == 0xFFFF) + peer = NULL; + else + if (header -> peerID >= host -> peerCount) + return 0; + else + { + peer = & host -> peers [header -> peerID]; + + if (peer -> state == ENET_PEER_STATE_DISCONNECTED || + peer -> state == ENET_PEER_STATE_ZOMBIE || + host -> receivedAddress.host != peer -> address.host || + header -> challenge != peer -> challenge) + return 0; + else + peer -> address.port = host -> receivedAddress.port; + } + + if (peer != NULL) + peer -> incomingDataTotal += host -> receivedDataLength; + + commandCount = header -> commandCount; + currentData = host -> receivedData + sizeof (ENetProtocolHeader); + + while (commandCount > 0 && + currentData < & host -> receivedData [host -> receivedDataLength]) + { + command = (ENetProtocol *) currentData; + + if (currentData + sizeof (ENetProtocolCommandHeader) > & host -> receivedData [host -> receivedDataLength]) + return 0; + + command -> header.commandLength = ENET_NET_TO_HOST_32 (command -> header.commandLength); + + if (currentData + command -> header.commandLength > & host -> receivedData [host -> receivedDataLength]) + return 0; + + -- commandCount; + currentData += command -> header.commandLength; + + if (peer == NULL) + { + if (command -> header.command != ENET_PROTOCOL_COMMAND_CONNECT) + return 0; + } + + command -> header.reliableSequenceNumber = ENET_NET_TO_HOST_32 (command -> header.reliableSequenceNumber); + + switch (command -> header.command) + { + case ENET_PROTOCOL_COMMAND_ACKNOWLEDGE: + enet_protocol_handle_acknowledge (host, event, peer, command); + + break; + + case ENET_PROTOCOL_COMMAND_CONNECT: + peer = enet_protocol_handle_connect (host, header, command); + + break; + + case ENET_PROTOCOL_COMMAND_VERIFY_CONNECT: + enet_protocol_handle_verify_connect (host, event, peer, command); + + break; + + case ENET_PROTOCOL_COMMAND_DISCONNECT: + enet_protocol_handle_disconnect (host, peer, command); + + break; + + case ENET_PROTOCOL_COMMAND_PING: + enet_protocol_handle_ping (host, peer, command); + + break; + + case ENET_PROTOCOL_COMMAND_SEND_RELIABLE: + enet_protocol_handle_send_reliable (host, peer, command); + + break; + + case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE: + enet_protocol_handle_send_unreliable (host, peer, command); + + break; + + case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT: + enet_protocol_handle_send_fragment (host, peer, command); + + break; + + case ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT: + enet_protocol_handle_bandwidth_limit (host, peer, command); + + break; + + case ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE: + enet_protocol_handle_throttle_configure (host, peer, command); + + break; + + default: + break; + } + + if (peer != NULL && + (command -> header.flags & ENET_PROTOCOL_FLAG_ACKNOWLEDGE) != 0) + { + switch (peer -> state) + { + case ENET_PEER_STATE_DISCONNECTING: + break; + + case ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT: + if (command -> header.command != ENET_PROTOCOL_COMMAND_DISCONNECT) + break; + + default: + enet_peer_queue_acknowledgement (peer, command, header -> sentTime); + + break; + } + } + } + + if (event -> type != ENET_EVENT_TYPE_NONE) + return 1; + + return 0; +} + +static int +enet_protocol_receive_incoming_commands (ENetHost * host, ENetEvent * event) +{ + for (;;) + { + int receivedLength; + ENetBuffer buffer; + + buffer.data = host -> receivedData; + buffer.dataLength = sizeof (host -> receivedData); + + receivedLength = enet_socket_receive (host -> socket, + & host -> receivedAddress, + & buffer, + 1); + + if (receivedLength < 0) + return -1; + + if (receivedLength == 0) + return 0; + + host -> receivedDataLength = receivedLength; + + switch (enet_protocol_handle_incoming_commands (host, event)) + { + case 1: + return 1; + + case -1: + return -1; + + default: + break; + } + } + + return -1; +} + +static void +enet_protocol_send_acknowledgements (ENetHost * host, ENetPeer * peer) +{ + ENetProtocol * command = & host -> commands [host -> commandCount]; + ENetBuffer * buffer = & host -> buffers [host -> bufferCount]; + ENetAcknowledgement * acknowledgement; + ENetListIterator currentAcknowledgement; + + currentAcknowledgement = enet_list_begin (& peer -> acknowledgements); + + while (currentAcknowledgement != enet_list_end (& peer -> acknowledgements)) + { + if (command >= & host -> commands [sizeof (host -> commands) / sizeof (ENetProtocol)] || + buffer >= & host -> buffers [sizeof (host -> buffers) / sizeof (ENetBuffer)] || + peer -> mtu - host -> packetSize < sizeof (ENetProtocolAcknowledge)) + break; + + acknowledgement = (ENetAcknowledgement *) currentAcknowledgement; + + if (peer -> state == ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT && + acknowledgement -> command.header.command != ENET_PROTOCOL_COMMAND_DISCONNECT) + continue; + + currentAcknowledgement = enet_list_next (currentAcknowledgement); + + buffer -> data = command; + buffer -> dataLength = sizeof (ENetProtocolAcknowledge); + + host -> packetSize += buffer -> dataLength; + + command -> header.command = ENET_PROTOCOL_COMMAND_ACKNOWLEDGE; + command -> header.channelID = acknowledgement -> command.header.channelID; + command -> header.flags = 0; + command -> header.commandLength = ENET_HOST_TO_NET_32 (sizeof (ENetProtocolAcknowledge)); + command -> acknowledge.receivedReliableSequenceNumber = ENET_HOST_TO_NET_32 (acknowledgement -> command.header.reliableSequenceNumber); + command -> acknowledge.receivedSentTime = ENET_HOST_TO_NET_32 (acknowledgement -> sentTime); + + if (acknowledgement -> command.header.command == ENET_PROTOCOL_COMMAND_DISCONNECT) + peer -> state = ENET_PEER_STATE_ZOMBIE; + + enet_list_remove (& acknowledgement -> acknowledgementList); + enet_free (acknowledgement); + + ++ command; + ++ buffer; + } + + host -> commandCount = command - host -> commands; + host -> bufferCount = buffer - host -> buffers; +} + +static void +enet_protocol_send_unreliable_outgoing_commands (ENetHost * host, ENetPeer * peer) +{ + ENetProtocol * command = & host -> commands [host -> commandCount]; + ENetBuffer * buffer = & host -> buffers [host -> bufferCount]; + ENetOutgoingCommand * outgoingCommand; + ENetListIterator currentCommand; + + currentCommand = enet_list_begin (& peer -> outgoingUnreliableCommands); + + while (currentCommand != enet_list_end (& peer -> outgoingUnreliableCommands)) + { + outgoingCommand = (ENetOutgoingCommand *) currentCommand; + + if (command >= & host -> commands [sizeof (host -> commands) / sizeof (ENetProtocol)] || + buffer + 1 >= & host -> buffers [sizeof (host -> buffers) / sizeof (ENetBuffer)] || + peer -> mtu - host -> packetSize < outgoingCommand -> command.header.commandLength || + (outgoingCommand -> packet != NULL && + peer -> mtu - host -> packetSize < outgoingCommand -> command.header.commandLength + + outgoingCommand -> packet -> dataLength)) + break; + + currentCommand = enet_list_next (currentCommand); + + if (outgoingCommand -> packet != NULL) + { + peer -> packetThrottleCounter += ENET_PEER_PACKET_THROTTLE_COUNTER; + peer -> packetThrottleCounter %= ENET_PEER_PACKET_THROTTLE_SCALE; + + if (peer -> packetThrottleCounter > peer -> packetThrottle) + { + -- outgoingCommand -> packet -> referenceCount; + + if (outgoingCommand -> packet -> referenceCount == 0) + enet_packet_destroy (outgoingCommand -> packet); + + enet_list_remove (& outgoingCommand -> outgoingCommandList); + enet_free (outgoingCommand); + + continue; + } + } + + buffer -> data = command; + buffer -> dataLength = outgoingCommand -> command.header.commandLength; + + host -> packetSize += buffer -> dataLength; + + * command = outgoingCommand -> command; + + enet_list_remove (& outgoingCommand -> outgoingCommandList); + + if (outgoingCommand -> packet != NULL) + { + ++ buffer; + + buffer -> data = outgoingCommand -> packet -> data; + buffer -> dataLength = outgoingCommand -> packet -> dataLength; + + command -> header.commandLength += buffer -> dataLength; + + host -> packetSize += buffer -> dataLength; + + enet_list_insert (enet_list_end (& peer -> sentUnreliableCommands), outgoingCommand); + } + else + enet_free (outgoingCommand); + + command -> header.commandLength = ENET_HOST_TO_NET_32 (command -> header.commandLength); + + ++ command; + ++ buffer; + } + + host -> commandCount = command - host -> commands; + host -> bufferCount = buffer - host -> buffers; +} + +static int +enet_protocol_check_timeouts (ENetHost * host, ENetPeer * peer, ENetEvent * event) +{ + ENetOutgoingCommand * outgoingCommand; + ENetListIterator currentCommand; + + currentCommand = enet_list_begin (& peer -> sentReliableCommands); + + while (currentCommand != enet_list_end (& peer -> sentReliableCommands)) + { + outgoingCommand = (ENetOutgoingCommand *) currentCommand; + + currentCommand = enet_list_next (currentCommand); + + if (ENET_TIME_DIFFERENCE (timeCurrent, outgoingCommand -> sentTime) < outgoingCommand -> roundTripTimeout) + continue; + + if (outgoingCommand -> roundTripTimeout >= outgoingCommand -> roundTripTimeoutLimit) + { + event -> type = ENET_EVENT_TYPE_DISCONNECT; + event -> peer = peer; + + enet_peer_reset (peer); + + return 1; + } + + if (outgoingCommand -> packet != NULL) + peer -> reliableDataInTransit -= outgoingCommand -> fragmentLength; + + ++ peer -> packetsLost; + + outgoingCommand -> roundTripTimeout *= 2; + + enet_list_insert (enet_list_begin (& peer -> outgoingReliableCommands), + enet_list_remove (& outgoingCommand -> outgoingCommandList)); + + if (currentCommand == enet_list_begin (& peer -> sentReliableCommands) && + enet_list_empty (& peer -> sentReliableCommands) == 0) + { + outgoingCommand = (ENetOutgoingCommand *) currentCommand; + + peer -> nextTimeout = outgoingCommand -> sentTime + outgoingCommand -> roundTripTimeout; + } + } + + return 0; +} + +static void +enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer) +{ + ENetProtocol * command = & host -> commands [host -> commandCount]; + ENetBuffer * buffer = & host -> buffers [host -> bufferCount]; + ENetOutgoingCommand * outgoingCommand; + ENetListIterator currentCommand; + + currentCommand = enet_list_begin (& peer -> outgoingReliableCommands); + + while (currentCommand != enet_list_end (& peer -> outgoingReliableCommands)) + { + outgoingCommand = (ENetOutgoingCommand *) currentCommand; + + if (command >= & host -> commands [sizeof (host -> commands) / sizeof (ENetProtocol)] || + buffer + 1 >= & host -> buffers [sizeof (host -> buffers) / sizeof (ENetBuffer)] || + peer -> mtu - host -> packetSize < outgoingCommand -> command.header.commandLength) + break; + + currentCommand = enet_list_next (currentCommand); + + if (outgoingCommand -> packet != NULL) + { + if ((enet_uint16) (peer -> mtu - host -> packetSize) < + (enet_uint16) (outgoingCommand -> command.header.commandLength + + outgoingCommand -> fragmentLength) || + peer -> reliableDataInTransit + outgoingCommand -> fragmentLength > peer -> windowSize) + break; + } + + if (outgoingCommand -> roundTripTimeout == 0) + { + outgoingCommand -> roundTripTimeout = peer -> roundTripTime + 4 * peer -> roundTripTimeVariance; + outgoingCommand -> roundTripTimeoutLimit = ENET_PEER_TIMEOUT_LIMIT * outgoingCommand -> roundTripTimeout; + } + + if (enet_list_empty (& peer -> sentReliableCommands)) + peer -> nextTimeout = timeCurrent + outgoingCommand -> roundTripTimeout; + + enet_list_insert (enet_list_end (& peer -> sentReliableCommands), + enet_list_remove (& outgoingCommand -> outgoingCommandList)); + + outgoingCommand -> sentTime = timeCurrent; + + buffer -> data = command; + buffer -> dataLength = outgoingCommand -> command.header.commandLength; + + host -> packetSize += buffer -> dataLength; + + * command = outgoingCommand -> command; + + if (outgoingCommand -> packet != NULL) + { + ++ buffer; + + buffer -> data = outgoingCommand -> packet -> data + outgoingCommand -> fragmentOffset; + buffer -> dataLength = outgoingCommand -> fragmentLength; + + command -> header.commandLength += outgoingCommand -> fragmentLength; + + host -> packetSize += outgoingCommand -> fragmentLength; + + peer -> reliableDataInTransit += outgoingCommand -> fragmentLength; + } + + command -> header.commandLength = ENET_HOST_TO_NET_32 (command -> header.commandLength); + + ++ peer -> packetsSent; + + ++ command; + ++ buffer; + } + + host -> commandCount = command - host -> commands; + host -> bufferCount = buffer - host -> buffers; +} + +static int +enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int checkForTimeouts) +{ + size_t packetsSent = 1; + ENetProtocolHeader header; + ENetPeer * currentPeer; + int sentLength; + + while (packetsSent > 0) + for (currentPeer = host -> peers, + packetsSent = 0; + currentPeer < & host -> peers [host -> peerCount]; + ++ currentPeer) + { + if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED || + currentPeer -> state == ENET_PEER_STATE_ZOMBIE) + continue; + + host -> commandCount = 0; + host -> bufferCount = 1; + host -> packetSize = sizeof (ENetProtocolHeader); + + if (enet_list_empty (& currentPeer -> acknowledgements) == 0) + enet_protocol_send_acknowledgements (host, currentPeer); + + if (host -> commandCount < sizeof (host -> commands) / sizeof (ENetProtocol)) + { + if (checkForTimeouts != 0 && + enet_list_empty (& currentPeer -> sentReliableCommands) == 0 && + ENET_TIME_GREATER_EQUAL (timeCurrent, currentPeer -> nextTimeout) && + enet_protocol_check_timeouts (host, currentPeer, event) == 1) + return 1; + } + if (enet_list_empty (& currentPeer -> outgoingReliableCommands) == 0) + enet_protocol_send_reliable_outgoing_commands (host, currentPeer); + else + if (enet_list_empty (& currentPeer -> sentReliableCommands) && + ENET_TIME_DIFFERENCE (timeCurrent, currentPeer -> lastReceiveTime) >= ENET_PEER_PING_INTERVAL && + currentPeer -> mtu - host -> packetSize >= sizeof (ENetProtocolPing)) + { + enet_peer_ping (currentPeer); + enet_protocol_send_reliable_outgoing_commands (host, currentPeer); + } + + if (host -> commandCount < sizeof (host -> commands) / sizeof (ENetProtocol) && + enet_list_empty (& currentPeer -> outgoingUnreliableCommands) == 0) + enet_protocol_send_unreliable_outgoing_commands (host, currentPeer); + + if (host -> commandCount == 0) + continue; + + if (currentPeer -> packetLossEpoch == 0) + currentPeer -> packetLossEpoch = timeCurrent; + else + if (ENET_TIME_DIFFERENCE (timeCurrent, currentPeer -> packetLossEpoch) >= ENET_PEER_PACKET_LOSS_INTERVAL && + currentPeer -> packetsSent > 0) + { + enet_uint32 packetLoss = currentPeer -> packetsLost * ENET_PEER_PACKET_LOSS_SCALE / currentPeer -> packetsSent; + +#ifdef ENET_DEBUG +#ifdef WIN32 + printf ("peer %u: %f%%+-%f%% packet loss, %u+-%u ms round trip time, %f%% throttle, %u/%u outgoing, %u/%u incoming\n", currentPeer -> incomingPeerID, currentPeer -> packetLoss / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> packetLossVariance / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> roundTripTime, currentPeer -> roundTripTimeVariance, currentPeer -> packetThrottle / (float) ENET_PEER_PACKET_THROTTLE_SCALE, enet_list_size (& currentPeer -> outgoingReliableCommands), enet_list_size (& currentPeer -> outgoingUnreliableCommands), currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingReliableCommands) : 0, enet_list_size (& currentPeer -> channels -> incomingUnreliableCommands)); +#else + fprintf (stderr, "peer %u: %f%%+-%f%% packet loss, %u+-%u ms round trip time, %f%% throttle, %u/%u outgoing, %u/%u incoming\n", currentPeer -> incomingPeerID, currentPeer -> packetLoss / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> packetLossVariance / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> roundTripTime, currentPeer -> roundTripTimeVariance, currentPeer -> packetThrottle / (float) ENET_PEER_PACKET_THROTTLE_SCALE, enet_list_size (& currentPeer -> outgoingReliableCommands), enet_list_size (& currentPeer -> outgoingUnreliableCommands), currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingReliableCommands) : 0, enet_list_size (& currentPeer -> channels -> incomingUnreliableCommands)); +#endif +#endif + + currentPeer -> packetLossVariance -= currentPeer -> packetLossVariance / 4; + + if (packetLoss >= currentPeer -> packetLoss) + { + currentPeer -> packetLoss += (packetLoss - currentPeer -> packetLoss) / 8; + currentPeer -> packetLossVariance += (packetLoss - currentPeer -> packetLoss) / 4; + } + else + { + currentPeer -> packetLoss -= (currentPeer -> packetLoss - packetLoss) / 8; + currentPeer -> packetLossVariance += (currentPeer -> packetLoss - packetLoss) / 4; + } + + currentPeer -> packetLossEpoch = timeCurrent; + currentPeer -> packetsSent = 0; + currentPeer -> packetsLost = 0; + } + + header.peerID = ENET_HOST_TO_NET_16 (currentPeer -> outgoingPeerID); + header.flags = 0; + header.commandCount = host -> commandCount; + header.sentTime = ENET_HOST_TO_NET_32 (timeCurrent); + header.challenge = currentPeer -> challenge; + + host -> buffers -> data = & header; + host -> buffers -> dataLength = sizeof (ENetProtocolHeader); + + currentPeer -> lastSendTime = timeCurrent; + + ++ packetsSent; + + sentLength = enet_socket_send (host -> socket, & currentPeer -> address, host -> buffers, host -> bufferCount); + + enet_protocol_remove_sent_unreliable_commands (currentPeer); + + if (sentLength < 0) + return -1; + } + + return 0; +} + +/** Sends any queued packets on the host specified to its designated peers. + + @param host host to flush + @remarks this function need only be used in circumstances where one wishes to send queued packets earlier than in a call to enet_host_service(). + @ingroup host +*/ +void +enet_host_flush (ENetHost * host) +{ + timeCurrent = enet_time_get (); + + enet_protocol_send_outgoing_commands (host, NULL, 0); +} + +/** Waits for events on the host specified and shuttles packets between + the host and its peers. + + @param host host to service + @param event an event structure where event details will be placed if one occurs + @param timeout number of milliseconds that ENet should wait for events + @retval > 1 if an event occurred within the specified time limit + @retval 0 if no event occurred + @retval < 1 on failure + @remarks enet_host_service should be called fairly regularly for adequate performance + @ingroup host +*/ +int +enet_host_service (ENetHost * host, ENetEvent * event, enet_uint32 timeout) +{ + enet_uint32 waitCondition; + + event -> type = ENET_EVENT_TYPE_NONE; + event -> peer = NULL; + event -> packet = NULL; + + switch (enet_protocol_dispatch_incoming_commands (host, event)) + { + case 1: + return 1; + + case -1: + perror ("Error dispatching incoming packets"); + + return -1; + + default: + break; + } + + timeCurrent = enet_time_get (); + + timeout += timeCurrent; + + do + { + if (ENET_TIME_DIFFERENCE (timeCurrent, host -> bandwidthThrottleEpoch) >= ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL) + enet_host_bandwidth_throttle (host); + + switch (enet_protocol_send_outgoing_commands (host, event, 1)) + { + case 1: + return 1; + + case -1: + perror ("Error sending outgoing packets"); + + return -1; + + default: + break; + } + + switch (enet_protocol_receive_incoming_commands (host, event)) + { + case 1: + return 1; + + case -1: + perror ("Error receiving incoming packets"); + + return -1; + + default: + break; + } + + switch (enet_protocol_send_outgoing_commands (host, event, 1)) + { + case 1: + return 1; + + case -1: + perror ("Error sending outgoing packets"); + + return -1; + + default: + break; + } + + switch (enet_protocol_dispatch_incoming_commands (host, event)) + { + case 1: + return 1; + + case -1: + perror ("Error dispatching incoming packets"); + + return -1; + + default: + break; + } + + timeCurrent = enet_time_get (); + + if (ENET_TIME_GREATER_EQUAL (timeCurrent, timeout)) + return 0; + + waitCondition = ENET_SOCKET_WAIT_RECEIVE; + + if (enet_socket_wait (host -> socket, & waitCondition, ENET_TIME_DIFFERENCE (timeout, timeCurrent)) != 0) + return -1; + + timeCurrent = enet_time_get (); + } while (waitCondition == ENET_SOCKET_WAIT_RECEIVE); + + return 0; +} + diff --git a/mod/pub.mod/enet.mod/tutorial.txt b/mod/pub.mod/enet.mod/tutorial.txt new file mode 100644 index 0000000..f187e2d --- /dev/null +++ b/mod/pub.mod/enet.mod/tutorial.txt @@ -0,0 +1,325 @@ +* Using ENet + + Before using ENet, you must call enet_initialize() to initialize the +library. Upon program exit, you should call enet_deinitialize() so that +the library may clean up any used resources. + +i.e. + +int +main (int argc, char ** argv) +{ + if (enet_initialize () != 0) + { + fprintf (stderror, "An error occurred while initializing ENet.\n"); + return EXIT_FAILURE; + } + atexit (enet_deinitialize); + ... + ... + ... +} + +* Creating an ENet server + + Servers in ENet are constructed with enet_host_create(). You must specify +an address on which to receive data and new connections, as well as the maximum +allowable numbers of connected peers. You may optionally specify the incoming +and outgoing bandwidth of the server in bytes per second so that ENet may try +to statically manage bandwidth resources among connected peers in addition to +its dynamic throttling algorithm; specifying 0 for these two options will cause +ENet to rely entirely upon its dynamic throttling algorithm to manage +bandwidth. + + When done with a host, the host may be destroyed with enet_host_destroy(). +All connected peers to the host will be reset, and the resources used by +the host will be freed. + +i.e. + + ENetAddress address; + ENetHost * server; + + /* Bind the server to the default localhost. + * A specific host address can be specified by + * enet_address_set_host (& address, "x.x.x.x"); + */ + address.host = ENET_HOST_ANY; + /* Bind the server to port 1234. */ + address.port = 1234; + + server = enet_host_create (& address /* the address to bind the server host to */, + 32 /* allow up to 32 clients and/or outgoing connections */, + 0 /* assume any amount of incoming bandwidth */, + 0 /* assume any amount of outgoing bandwidth */); + if (server == NULL) + { + fprintf (stderr, + "An error occurred while trying to create an ENet server host.\n"); + exit (EXIT_FAILURE); + } + ... + ... + ... + enet_host_destroy(server); + +* Creating an ENet client + + Clients in ENet are similarly constructed with enet_host_create() when no +address is specified to bind the host to. Bandwidth may be specified for the +client host as in the above example. The peer count controls the maximum number +of connections to other server hosts that may be simultaneously open. + +i.e. + + ENetHost * client; + + clienet = enet_host_create (NULL /* create a client host */, + 1 /* only allow 1 outgoing connection */, + 57600 / 8 /* 56K modem with 56 Kbps downstream bandwidth */, + 14400 / 8 /* 56K modem with 14 Kbps upstream bandwidth */); + + if (client == NULL) + { + fprintf (stderr, + "An error occurred while trying to create an ENet client host.\n"); + exit (EXIT_FAILURE); + } + ... + ... + ... + enet_host_destroy(client); + +* Managing an ENet host + + ENet uses a polled event model to notify the programmer of significant +events. ENet hosts are polled for events with enet_host_service(), where an +optional timeout value in milliseconds may be specified to control how long +ENet will poll; if a timeout of 0 is specified, enet_host_service() will +return immediately if there are no events to dispatch. enet_host_service() +will return 1 if an event was dispatched within the specified timeout. + + Currently there are only four types of significant events in ENet: + +An event of type ENET_EVENT_TYPE_NONE is returned if no event occurred +within the specified time limit. enet_host_service() will return 0 +with this event. + +An event of type ENET_EVENT_TYPE_CONNECT is returned when either a new client +host has connected to the server host or when an attempt to establish a +connection with a foreign host has succeeded. Only the "peer" field of the +event structure is valid for this event and contains the newly connected peer. + +An event of type ENET_EVENT_TYPE_RECEIVE is returned when a packet is received +from a connected peer. The "peer" field contains the peer the packet was +received from, "channelID" is the channel on which the packet was sent, and +"packet" is the packet that was sent. The packet contained in the "packet" +field must be destroyed with enet_packet_destroy() when you are done +inspecting its contents. + +An event of type ENET_EVENT_TYPE_DISCONNECT is returned when a connected peer +has either explicitly disconnected or timed out. Only the "peer" field of the +event structure is valid for this event and contains the peer that +disconnected. Only the "data" field of the peer is still valid on a +disconnect event and must be explicitly reset. + +i.e. + + ENetEvent event; + + /* Wait up to 1000 milliseconds for an event. */ + while (enet_host_service (client, & event, 1000) > 0) + { + switch (event.type) + { + case ENET_EVENT_TYPE_CONNECT: + printf ("A new client connected from %x:%u.\n", + event.peer -> address.host, + event.peer -> address.port); + + /* Store any relevant client information here. */ + event.peer -> data = "Client information"; + + break; + + case ENET_EVENT_TYPE_RECEIVE: + printf ("A packet of length %u containing %s was received from %s on channel %u.\n", + event.packet -> dataLength, + event.packet -> data, + event.peer -> data, + event.channelID); + + /* Clean up the packet now that we're done using it. */ + enet_packet_destroy (event.packet); + + break; + + case ENET_EVENT_TYPE_DISCONNECT: + printf ("%s disconected.\n", event.peer -> data); + + /* Reset the peer's client information. */ + + event.peer -> data = NULL; + } + } + ... + ... + ... + +* Sending a packet to an ENet peer + + Packets in ENet are created with enet_packet_create(), where the size of +the packet must be specified. Optionally, initial data may be specified to +copy into the packet. + + Certain flags may also be supplied to enet_packet_create() to control +various packet features: + +ENET_PACKET_FLAG_RELIABLE specifies that the packet must use reliable delivery. +A reliable packet is guarenteed to be delivered, and a number of retry attempts +will be made until an acknowledgement is received from the foreign host the +packet is sent to. If a certain number of retry attempts is reached without +any acknowledgement, ENet will assume the peer has disconnected and forcefully +reset the connection. If this flag is not specified, the packet is assumed +an unreliable packet, and no retry attempts will be made nor acknowledgements +generated. + + A packet may be resized (extended or truncated) with enet_packet_resize(). + + A packet is sent to a foreign host with enet_peer_send(). enet_peer_send() +accepts a channel id over which to send the packet to a given peer. Once the +packet is handed over to ENet with enet_peer_send(), ENet will handle its +deallocation and enet_packet_destroy() should not be used upon it. + + One may also use enet_host_broadcast() to send a packet to all connected +peers on a given host over a specified channel id, as with enet_peer_send(). + + Queued packets will be sent on a call to enet_host_service(). +Alternatively, enet_host_flush() will send out queued packets without +dispatching any events. + +i.e. + + /* Create a reliable packet of size 7 containing "packet\0" */ + ENetPacket * packet = enet_packet_create ("packet", + strlen ("packet") + 1, + ENET_PACKET_FLAG_RELIABLE); + + /* Extend the packet so and append the string "foo", so it now + * contains "packetfoo\0" + * + enet_packet_resize (packet, strlen ("packetfoo") + 1); + strcpy (& packet -> data [strlen ("packet")], "foo"); + + /* Send the packet to the peer over channel id 3. + * One could also broadcast the packet by + * enet_host_broadcast (host, 3, packet); + */ + enet_peer_send (peer, 3, packet); + ... + ... + ... + /* One could just use enet_host_service() instead. */ + enet_host_flush (host); + +* Disconnecting an ENet peer + + Peers may be gently disconnected with enet_peer_disconnect(). A disconnect +request will be sent to the foreign host, and ENet will wait for an +acknowledgement from the foreign host before finally disconnecting. An +event of type ENET_EVENT_TYPE_DISCONNECT will be generated once the +disconnection succeeds. Normally timeouts apply to the disconnect +acknowledgement, and so if no acknowledgement is received after a length +of time the peer will be forcefully disconnected. + + enet_peer_reset() will forcefully disconnect a peer. The foreign host +will get no notification of a disconnect and will time out on the foreign +host. No event is generated. + +i.e. + ENetEvent event; + + enet_peer_disconnect (& client -> peers [0]); + + /* Allow up to 3 seconds for the disconnect to succeed + * and drop any packets received packets. + */ + while (enet_host_service (client, & event, 3000) > 0) + { + switch (event.type) + { + case ENET_EVENT_TYPE_RECEIVE: + enet_packet_destroy (event.packet); + break; + + case ENET_EVENT_TYPE_DISCONNECT: + puts ("Disconnection succeeded."); + return; + ... + ... + ... + } + } + + /* We've arrived here, so the disconnect attempt didn't succeed yet. + * Force the connection down. + */ + enet_peer_reset (& client -> peers [0]); + ... + ... + ... + +* Connecting to an ENet host + + A connection to a foregin host is initiated with enet_host_connect(). +It accepts the address of a foreign host to connect to, and the number of +channels that should be allocated for communication. If N channels are +allocated for use, their channel ids will be numbered 0 through N-1. +A peer representing the connection attempt is returned, or NULL if there +were no available peers over which to initiate the connection. When the +connection attempt succeeds, an event of type ENET_EVENT_TYPE_CONNECT will +be generated. If the connection attempt times out or otherwise fails, an +event of type ENET_EVENT_TYPE_DISCONNECT will be generated. + +i.e. + ENetAddress address; + ENetEvent event; + ENetPeer *peer; + + /* Connect to some.server.net:1234. */ + enet_address_set_host (& address, "some.server.net"); + address.port = 1234; + + /* Initiate the connection, allocating the two channels 0 and 1. */ + peer = enet_host_connect (client, & address, 2); + + if (peer == NULL) + { + fprintf (stderr, + "No available peers for initiating an ENet connection.\n"); + exit (EXIT_FAILURE); + } + + /* Wait up to 5 seconds for the connection attempt to succeed. + if (enet_host_service (client, & event, 5000) > 0 && + event.type == ENET_EVENT_TYPE_CONNECT) + { + puts ("Connection to some.server.net:1234 succeeded."); + ... + ... + ... + } + else + { + /* Either the 5 seconds are up or a disconnect event was + * received. Reset the peer in the event the 5 seconds + * had run out without any significant event. + */ + enet_peer_reset (peer); + + puts ("Connection to some.server.net:1234 failed."); + } + ... + ... + ... + diff --git a/mod/pub.mod/enet.mod/unix.c b/mod/pub.mod/enet.mod/unix.c new file mode 100644 index 0000000..8ec6ec8 --- /dev/null +++ b/mod/pub.mod/enet.mod/unix.c @@ -0,0 +1,367 @@ +/** + @file unix.c + @brief ENet Unix system specific functions +*/ +#ifndef WIN32 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ENET_BUILDING_LIB 1 +#include "enet/enet.h" + +#ifdef HAS_FCNTL +#include +#endif + +#ifdef HAS_POLL +#include +#endif + +#ifndef MSG_NOSIGNAL +#define MSG_NOSIGNAL 0 +#endif + +static enet_uint32 timeBase = 0; + +int +enet_initialize (void) +{ + return 0; +} + +void +enet_deinitialize (void) +{ +} + +enet_uint32 +enet_time_get (void) +{ + struct timeval timeVal; + + gettimeofday (& timeVal, NULL); + + return timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - timeBase; +} + +void +enet_time_set (enet_uint32 newTimeBase) +{ + struct timeval timeVal; + + gettimeofday (& timeVal, NULL); + + timeBase = timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - newTimeBase; +} + +int +enet_address_set_host (ENetAddress * address, const char * name) +{ + struct hostent * hostEntry = NULL; +#ifdef HAS_GETHOSTBYNAME_R + struct hostent hostData; + char buffer [2048]; + int errnum; + +#ifdef linux + gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum); +#else + hostEntry = gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & errnum); +#endif +#else + hostEntry = gethostbyname (name); +#endif + + if (hostEntry == NULL || + hostEntry -> h_addrtype != AF_INET) + return -1; + + address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0]; + + return 0; +} + +int +enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength) +{ + struct in_addr in; + struct hostent * hostEntry = NULL; +#ifdef HAS_GETHOSTBYADDR_R + struct hostent hostData; + char buffer [2048]; + int errnum; + + in.s_addr = address -> host; + +#ifdef linux + gethostbyaddr_r ((char *) & in, sizeof (struct in_addr), AF_INET, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum); +#else + hostEntry = gethostbyaddr_r ((char *) & in, sizeof (struct in_addr), AF_INET, & hostData, buffer, sizeof (buffer), & errnum); +#endif +#else + in.s_addr = address -> host; + + hostEntry = gethostbyaddr ((char *) & in, sizeof (struct in_addr), AF_INET); +#endif + + if (hostEntry == NULL) + return -1; + + strncpy (name, hostEntry -> h_name, nameLength); + + return 0; +} + +ENetSocket +enet_socket_create (ENetSocketType type, const ENetAddress * address) +{ + ENetSocket newSocket = socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0); + int receiveBufferSize = ENET_HOST_RECEIVE_BUFFER_SIZE; +#ifndef HAS_FCNTL + int nonBlocking = 1; +#endif + struct sockaddr_in sin; + + if (newSocket == ENET_SOCKET_NULL) + return ENET_SOCKET_NULL; + + if (type == ENET_SOCKET_TYPE_DATAGRAM) + { +#ifdef HAS_FCNTL + fcntl (newSocket, F_SETFL, O_NONBLOCK | fcntl (newSocket, F_GETFL)); +#else + ioctl (newSocket, FIONBIO, & nonBlocking); +#endif + + setsockopt (newSocket, SOL_SOCKET, SO_RCVBUF, (char *) & receiveBufferSize, sizeof (int)); + } + + if (address == NULL) + return newSocket; + + memset (& sin, 0, sizeof (struct sockaddr_in)); + + sin.sin_family = AF_INET; + sin.sin_port = ENET_HOST_TO_NET_16 (address -> port); + sin.sin_addr.s_addr = address -> host; + + if (bind (newSocket, + (struct sockaddr *) & sin, + sizeof (struct sockaddr_in)) == -1 || + (type == ENET_SOCKET_TYPE_STREAM && + listen (newSocket, SOMAXCONN) == -1)) + { + close (newSocket); + + return ENET_SOCKET_NULL; + } + + return newSocket; +} + +int +enet_socket_connect (ENetSocket socket, const ENetAddress * address) +{ + struct sockaddr_in sin; + + memset (& sin, 0, sizeof (struct sockaddr_in)); + + sin.sin_family = AF_INET; + sin.sin_port = ENET_HOST_TO_NET_16 (address -> port); + sin.sin_addr.s_addr = address -> host; + + return connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in)); +} + +ENetSocket +enet_socket_accept (ENetSocket socket, ENetAddress * address) +{ + int result; + struct sockaddr_in sin; + socklen_t sinLength = sizeof (struct sockaddr_in); + + result = accept (socket, + address != NULL ? (struct sockaddr *) & sin : NULL, + address != NULL ? & sinLength : NULL); + + if (result == -1) + return ENET_SOCKET_NULL; + + if (address != NULL) + { + address -> host = (enet_uint32) sin.sin_addr.s_addr; + address -> port = ENET_NET_TO_HOST_16 (sin.sin_port); + } + + return result; +} + +void +enet_socket_destroy (ENetSocket socket) +{ + close (socket); +} + +int +enet_socket_send (ENetSocket socket, + const ENetAddress * address, + const ENetBuffer * buffers, + size_t bufferCount) +{ + struct msghdr msgHdr; + struct sockaddr_in sin; + int sentLength; + + memset (& msgHdr, 0, sizeof (struct msghdr)); + + if (address != NULL) + { + sin.sin_family = AF_INET; + sin.sin_port = ENET_HOST_TO_NET_16 (address -> port); + sin.sin_addr.s_addr = address -> host; + + msgHdr.msg_name = (void*)& sin; + msgHdr.msg_namelen = sizeof (struct sockaddr_in); + } + + msgHdr.msg_iov = (struct iovec *) buffers; + msgHdr.msg_iovlen = bufferCount; + + sentLength = sendmsg (socket, & msgHdr, MSG_NOSIGNAL); + + if (sentLength == -1) + { + if (errno == EWOULDBLOCK) + return 0; + + return -1; + } + + return sentLength; +} + +int +enet_socket_receive (ENetSocket socket, + ENetAddress * address, + ENetBuffer * buffers, + size_t bufferCount) +{ + struct msghdr msgHdr; + struct sockaddr_in sin; + int recvLength; + + memset (& msgHdr, 0, sizeof (struct msghdr)); + + if (address != NULL) + { + msgHdr.msg_name = (void*)& sin; + msgHdr.msg_namelen = sizeof (struct sockaddr_in); + } + + msgHdr.msg_iov = (struct iovec *) buffers; + msgHdr.msg_iovlen = bufferCount; + + recvLength = recvmsg (socket, & msgHdr, MSG_NOSIGNAL); + + if (recvLength == -1) + { + if (errno == EWOULDBLOCK) + return 0; + + return -1; + } + +#ifdef HAS_MSGHDR_FLAGS + if (msgHdr.msg_flags & MSG_TRUNC) + return -1; +#endif + + if (address != NULL) + { + address -> host = (enet_uint32) sin.sin_addr.s_addr; + address -> port = ENET_NET_TO_HOST_16 (sin.sin_port); + } + + return recvLength; +} + +int +enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeout) +{ +#ifdef HAS_POLL + struct pollfd pollSocket; + int pollCount; + + pollSocket.fd = socket; + pollSocket.events = 0; + + if (* condition & ENET_SOCKET_WAIT_SEND) + pollSocket.events |= POLLOUT; + + if (* condition & ENET_SOCKET_WAIT_RECEIVE) + pollSocket.events |= POLLIN; + + pollCount = poll (& pollSocket, 1, timeout); + + if (pollCount < 0) + return -1; + + * condition = ENET_SOCKET_WAIT_NONE; + + if (pollCount == 0) + return 0; + + if (pollSocket.revents & POLLOUT) + * condition |= ENET_SOCKET_WAIT_SEND; + + if (pollSocket.revents & POLLIN) + * condition |= ENET_SOCKET_WAIT_RECEIVE; + + return 0; +#else + fd_set readSet, writeSet; + struct timeval timeVal; + int selectCount; + + timeVal.tv_sec = timeout / 1000; + timeVal.tv_usec = (timeout % 1000) * 1000; + + FD_ZERO (& readSet); + FD_ZERO (& writeSet); + + if (* condition & ENET_SOCKET_WAIT_SEND) + FD_SET (socket, & writeSet); + + if (* condition & ENET_SOCKET_WAIT_RECEIVE) + FD_SET (socket, & readSet); + + selectCount = select (socket + 1, & readSet, & writeSet, NULL, & timeVal); + + if (selectCount < 0) + return -1; + + * condition = ENET_SOCKET_WAIT_NONE; + + if (selectCount == 0) + return 0; + + if (FD_ISSET (socket, & writeSet)) + * condition |= ENET_SOCKET_WAIT_SEND; + + if (FD_ISSET (socket, & readSet)) + * condition |= ENET_SOCKET_WAIT_RECEIVE; + + return 0; +#endif +} + +#endif + diff --git a/mod/pub.mod/enet.mod/win32.c b/mod/pub.mod/enet.mod/win32.c new file mode 100644 index 0000000..4043394 --- /dev/null +++ b/mod/pub.mod/enet.mod/win32.c @@ -0,0 +1,291 @@ +/** + @file win32.c + @brief ENet Win32 system specific functions +*/ +#ifdef WIN32 + +#include +#define ENET_BUILDING_LIB 1 +#include "enet/enet.h" + +static enet_uint32 timeBase = 0; + +int +enet_initialize (void) +{ + WORD versionRequested = MAKEWORD (1, 1); + WSADATA wsaData; + + if (WSAStartup (versionRequested, & wsaData)) + return -1; + + if (LOBYTE (wsaData.wVersion) != 1|| + HIBYTE (wsaData.wVersion) != 1) + { + WSACleanup (); + + return -1; + } + + return 0; +} + +void +enet_deinitialize (void) +{ + WSACleanup (); +} + +enet_uint32 +enet_time_get (void) +{ + return (enet_uint32) GetTickCount () - timeBase; +} + +void +enet_time_set (enet_uint32 newTimeBase) +{ + timeBase = (enet_uint32) GetTickCount () - newTimeBase; +} + +int +enet_address_set_host (ENetAddress * address, const char * name) +{ + struct hostent * hostEntry; + + hostEntry = gethostbyname (name); + if (hostEntry == NULL || + hostEntry -> h_addrtype != AF_INET) + return -1; + + address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0]; + + return 0; +} + +int +enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength) +{ + struct in_addr in; + struct hostent * hostEntry; + + in.s_addr = address -> host; + + hostEntry = gethostbyaddr ((char *) & in, sizeof (struct in_addr), AF_INET); + if (hostEntry == NULL) + return -1; + + strncpy (name, hostEntry -> h_name, nameLength); + + return 0; +} + +ENetSocket +enet_socket_create (ENetSocketType type, const ENetAddress * address) +{ + ENetSocket newSocket = socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0); + int nonBlocking = 1, + receiveBufferSize = ENET_HOST_RECEIVE_BUFFER_SIZE; + struct sockaddr_in sin; + + if (newSocket == ENET_SOCKET_NULL) + return ENET_SOCKET_NULL; + + if (type == ENET_SOCKET_TYPE_DATAGRAM) + { + ioctlsocket (newSocket, FIONBIO, (void*) & nonBlocking); + + setsockopt (newSocket, SOL_SOCKET, SO_RCVBUF, (char *) & receiveBufferSize, sizeof (int)); + } + + memset (& sin, 0, sizeof (struct sockaddr_in)); + + sin.sin_family = AF_INET; + + if (address != NULL) + { + sin.sin_port = ENET_HOST_TO_NET_16 (address -> port); + sin.sin_addr.s_addr = address -> host; + } + else + { + sin.sin_port = 0; + sin.sin_addr.s_addr = INADDR_ANY; + } + + if (bind (newSocket, + (struct sockaddr *) & sin, + sizeof (struct sockaddr_in)) == SOCKET_ERROR || + (type == ENET_SOCKET_TYPE_STREAM && + address != NULL && + listen (newSocket, SOMAXCONN) == SOCKET_ERROR)) + { + closesocket (newSocket); + + return ENET_SOCKET_NULL; + } + + return newSocket; +} + +int +enet_socket_connect (ENetSocket socket, const ENetAddress * address) +{ + struct sockaddr_in sin; + + memset (& sin, 0, sizeof (struct sockaddr_in)); + + sin.sin_family = AF_INET; + sin.sin_port = ENET_HOST_TO_NET_16 (address -> port); + sin.sin_addr.s_addr = address -> host; + + return connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in)); +} + +ENetSocket +enet_socket_accept (ENetSocket socket, ENetAddress * address) +{ + int result; + struct sockaddr_in sin; + int sinLength = sizeof (struct sockaddr_in); + + result = accept (socket, + address != NULL ? (struct sockaddr *) & sin : NULL, + address != NULL ? & sinLength : NULL); + + if (result == -1) + return ENET_SOCKET_NULL; + + if (address != NULL) + { + address -> host = (enet_uint32) sin.sin_addr.s_addr; + address -> port = ENET_NET_TO_HOST_16 (sin.sin_port); + } + + return result; +} + +void +enet_socket_destroy (ENetSocket socket) +{ + closesocket (socket); +} + +int +enet_socket_send (ENetSocket socket, + const ENetAddress * address, + const ENetBuffer * buffers, + size_t bufferCount) +{ + struct sockaddr_in sin; + DWORD sentLength; + + if (address != NULL) + { + sin.sin_family = AF_INET; + sin.sin_port = ENET_HOST_TO_NET_16 (address -> port); + sin.sin_addr.s_addr = address -> host; + } + + if (WSASendTo (socket, + (LPWSABUF) buffers, + (DWORD) bufferCount, + & sentLength, + 0, + address != NULL ? (struct sockaddr *) & sin : 0, + address != NULL ? sizeof (struct sockaddr_in) : 0, + NULL, + NULL) == SOCKET_ERROR) + { + if (WSAGetLastError () == WSAEWOULDBLOCK) + return 0; + + return -1; + } + + return (int) sentLength; +} + +int +enet_socket_receive (ENetSocket socket, + ENetAddress * address, + ENetBuffer * buffers, + size_t bufferCount) +{ + DWORD sinLength = sizeof (struct sockaddr_in), + flags = 0, + recvLength; + struct sockaddr_in sin; + + if (WSARecvFrom (socket, + (LPWSABUF) buffers, + (DWORD) bufferCount, + & recvLength, + & flags, + address != NULL ? (struct sockaddr *) & sin : NULL, + address != NULL ? (void*) & sinLength : NULL, + NULL, + NULL) == SOCKET_ERROR) + { + switch (WSAGetLastError ()) + { + case WSAEWOULDBLOCK: + case WSAECONNRESET: + return 0; + } + + return -1; + } + + if (flags & MSG_PARTIAL) + return -1; + + if (address != NULL) + { + address -> host = (enet_uint32) sin.sin_addr.s_addr; + address -> port = ENET_NET_TO_HOST_16 (sin.sin_port); + } + + return (int) recvLength; +} + +int +enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeout) +{ + fd_set readSet, writeSet; + struct timeval timeVal; + int selectCount; + + timeVal.tv_sec = timeout / 1000; + timeVal.tv_usec = (timeout % 1000) * 1000; + + FD_ZERO (& readSet); + FD_ZERO (& writeSet); + + if (* condition & ENET_SOCKET_WAIT_SEND) + FD_SET (socket, & writeSet); + + if (* condition & ENET_SOCKET_WAIT_RECEIVE) + FD_SET (socket, & readSet); + + selectCount = select (socket + 1, & readSet, & writeSet, NULL, & timeVal); + + if (selectCount < 0) + return -1; + + * condition = ENET_SOCKET_WAIT_NONE; + + if (selectCount == 0) + return 0; + + if (FD_ISSET (socket, & writeSet)) + * condition |= ENET_SOCKET_WAIT_SEND; + + if (FD_ISSET (socket, & readSet)) + * condition |= ENET_SOCKET_WAIT_RECEIVE; + + return 0; +} + +#endif + diff --git a/mod/pub.mod/freeaudio.mod/alsadevice.cpp b/mod/pub.mod/freeaudio.mod/alsadevice.cpp new file mode 100644 index 0000000..38115c3 --- /dev/null +++ b/mod/pub.mod/freeaudio.mod/alsadevice.cpp @@ -0,0 +1,146 @@ +// alsadevice.cpp + +#ifdef __linux + +#include "freeaudio.h" + +#include +#include +#include +#include +#include + +//#include + +extern "C" audiodevice *OpenALSADevice(); + +void *audiothread(void *dev); + +#define LINUXFRAG 2048 + +struct alsaaudio:audiodevice{ + pthread_t audiothread; + int threadid; + int running,playing; + short *buffer; + int buffersize; //in bytes + + int reset(){ + running=1; + playing=0; + mix=new mixer(LINUXFRAG); + mix->freq=44100; + mix->channels=2; + buffer=new short[LINUXFRAG]; + buffersize=LINUXFRAG*2; + pthread_attr_t attr; + pthread_attr_init(&attr); + threadid=pthread_create(&audiothread,&attr,audiothread,(void*)this); + return 0; + } + + int close(){ + int timeout; + running=0; + timeout=5; + while (timeout-- && playing) sleep(1); + return 0; + } +}; + + +void *audiothread(void *v){ + int policy; + sched_param sched; + int err; + alsaaudio *dev; + + pthread_getschedparam(pthread_self(),&policy,&sched); + sched.sched_priority++;//policy=SCHED_RR; + pthread_setschedparam(pthread_self(),policy,&sched); + dev=(alsaaudio*)v; + + unsigned int val; + snd_pcm_t *fd; + snd_pcm_uframes_t periodsize; + snd_pcm_hw_params_t *hwparams; + snd_pcm_hw_params_alloca(&hwparams); + int output_rate; + int channels; + int fragment_size; + int fragment_count; + + err=snd_pcm_open(&fd, strdup("default"), SND_PCM_STREAM_PLAYBACK, 0); + if (err<0) return -1; + + fragment_size=LINUXFRAG; //overall buffer size + fragment_count=2; //2 - 16 fragment count - 2 minimum, the lower it is potentially the lower the latency + +//configure device + if (snd_pcm_hw_params_any(fd, hwparams) < 0) { + //printf("linuxaudio failed at params any\n"); + return -1; + } + if (snd_pcm_hw_params_set_access(fd, hwparams,SND_PCM_ACCESS_RW_INTERLEAVED) < 0) { + //printf("linuxaudio failed at set access\n"); + return -1; + } + + if (snd_pcm_hw_params_set_format(fd, hwparams,SND_PCM_FORMAT_S16_LE) < 0) { + //printf("linuxaudio failed at set format\n"); + return -1; + } + val = 44100; + if (snd_pcm_hw_params_set_rate_near(fd, hwparams,&val, 0) < 0) { + // Try 48KHZ too + //printf("linuxaudio - %d HZ not available, trying 48000HZ\n", output_rate); + val = 48000; + if (snd_pcm_hw_params_set_rate_near(fd, hwparams,&val, 0) < 0) { + //printf("linuxaudio failed at setting output rate (%d)\n", output_rate); + return -1; + } + dev->mix->freq=val; + } + channels=2; + if (snd_pcm_hw_params_set_channels(fd, hwparams, channels) < 0) { + //printf("linuxaudio failed at set channels (%d)\n", channels); + return -1; + } + periodsize = (fragment_size) / 4; // bytes -> frames for 16-bit,stereo - should be a minimum of 512 + if (snd_pcm_hw_params_set_period_size_near(fd, hwparams,&periodsize, 0) < 0) { + //printf("linuxaudio failed at set period size (%d)\n", (int)periodsize); + return -1; + } + val = fragment_count; + if (snd_pcm_hw_params_set_periods_near(fd, hwparams,&val, 0) < 0) { + //printf("linuxaudio failed at set periods (%d)\n", val); + //should attempt a one by one period increase up to 16? + return -1; + } + if (snd_pcm_hw_params(fd, hwparams) < 0) { + //printf("linuxaudio failed at installing hw params\n"); + return -1; + } + //loop while playing sound + dev->playing=1; + while (dev->playing) + { + dev->mix->mix16(dev->buffer); + if ((snd_pcm_writei (fd, dev->buffer,LINUXFRAG/2)) < 0) { //Half buffer for two channels? + //printf ("linuxaudio warning: buffer underrun occurred\n"); + if (snd_pcm_prepare(fd) < 0) { + //printf ("linuxaudio failed at preparing pcm\n"); + dev->playing=0; //die gracefully + } + } + } + snd_pcm_drop(fd); + snd_pcm_close (fd); + return 0; +} + +audiodevice *OpenALSADevice(){ + return new alsaaudio(); +} + +#endif diff --git a/mod/pub.mod/freeaudio.mod/audiodevice.h b/mod/pub.mod/freeaudio.mod/audiodevice.h new file mode 100644 index 0000000..e69de29 diff --git a/mod/pub.mod/freeaudio.mod/coreaudiodevice.cpp b/mod/pub.mod/freeaudio.mod/coreaudiodevice.cpp new file mode 100644 index 0000000..5d67f53 --- /dev/null +++ b/mod/pub.mod/freeaudio.mod/coreaudiodevice.cpp @@ -0,0 +1,137 @@ +// apple core audio device + +#include "freeaudio.h" + +#ifdef __APPLE__ + +#include +#include +#include +#include + +extern "C" audiodevice *OpenCoreAudioDevice(); + +OSStatus FeedSound(void *ref,AudioUnitRenderActionFlags *flags,const AudioTimeStamp *time,UInt32 bus,UInt32 frames,AudioBufferList *data); + +struct coreaudio:audiodevice{ + AudioUnit out; + AudioConverterRef conv; + AURenderCallbackStruct callback; + short *buffer; + int tcount; + + int reset(){ + int res; + + mix=new mixer(8192); + mix->freq=44100; + mix->channels=2; + + out=0; + res=initoutput(); + if (res) return res; + + callback.inputProc=FeedSound; + callback.inputProcRefCon=this; + + buffer=new short[8192]; + + res=AudioUnitSetProperty(out,kAudioUnitProperty_SetRenderCallback,kAudioUnitScope_Input,0,&callback,sizeof(callback)); + if (res) return res; + + res=AudioOutputUnitStart(out); + if (res) return res; + + return 0; + } + + int close(){ + int res; + + if (out){ + res=AudioOutputUnitStop(out); + if (res) return res; + out=0; + } + return 0; + } + + int initoutput(){ + ComponentDescription desc; + Component comp; + OSStatus err; + UInt32 size; + Boolean canwrite; + + AudioStreamBasicDescription inputdesc,outputdesc; + + desc.componentType=kAudioUnitType_Output; + desc.componentSubType=kAudioUnitSubType_DefaultOutput; + desc.componentManufacturer=kAudioUnitManufacturer_Apple; + desc.componentFlags=0; + desc.componentFlagsMask=0; + + comp=FindNextComponent(NULL,&desc);if (comp==NULL) return -1; + err=OpenAComponent(comp,&out);if (err) return err; + err=AudioUnitInitialize(out);if (err) return err; + + err=AudioUnitGetPropertyInfo(out,kAudioUnitProperty_StreamFormat,kAudioUnitScope_Output,0,&size,&canwrite); + if (err) return err; + + err=AudioUnitGetProperty(out,kAudioUnitProperty_StreamFormat,kAudioUnitScope_Input,0,&outputdesc,&size); + if (err) return err; + +// dumpdesc(&outputdesc); + + inputdesc.mSampleRate=44100.0; + inputdesc.mFormatID='lpcm'; +#if __BIG_ENDIAN__ + inputdesc.mFormatFlags=0x0e; +#else + inputdesc.mFormatFlags=0x0c; +#endif + inputdesc.mBytesPerPacket=4; + inputdesc.mFramesPerPacket=1; + inputdesc.mBytesPerFrame=4; + inputdesc.mChannelsPerFrame=2; + inputdesc.mBitsPerChannel=16; + inputdesc.mReserved=0; + +// dumpdesc(&inputdesc); + + err=AudioConverterNew(&inputdesc,&outputdesc,&conv); + if (err) { +// printf("AudioConvertNew failed %.*s\n",4,(char*)&err); + return err; + } + + return err; + } + + int read(AudioConverterRef conv,UInt32 *count,AudioBufferList *blist,AudioStreamPacketDescription **outdesc){ + if (*count>4096) *count=4096; +// printf("ac read count=%d\n",*count);fflush(stdout); + mix->mix16(buffer,*count*2); + blist->mBuffers[0].mData=buffer; + blist->mBuffers[0].mDataByteSize=*count*4; + return 0; + } +}; + +OSStatus Feed(AudioConverterRef conv,UInt32 *count,AudioBufferList *blist,AudioStreamPacketDescription **outdesc,void *ref){ + coreaudio *audio; + audio=(coreaudio*)ref; + return audio->read(conv,count,blist,outdesc); +} + +OSStatus FeedSound(void *ref,AudioUnitRenderActionFlags *flags,const AudioTimeStamp *time,UInt32 bus,UInt32 count,AudioBufferList *blist){ + coreaudio *audio; + audio=(coreaudio*)ref; + return AudioConverterFillComplexBuffer(audio->conv,Feed,ref,&count,blist,0); +} + +audiodevice *OpenCoreAudioDevice(){ + return new coreaudio(); +} + +#endif diff --git a/mod/pub.mod/freeaudio.mod/dsound.h b/mod/pub.mod/freeaudio.mod/dsound.h new file mode 100644 index 0000000..ce14133 --- /dev/null +++ b/mod/pub.mod/freeaudio.mod/dsound.h @@ -0,0 +1,152 @@ +// dsound.h + +#ifndef dsound_h +#define dsound_h + +#define DSBCAPS_PRIMARYBUFFER 0x00000001 +#define DSBCAPS_STATIC 0x00000002 +#define DSBCAPS_LOCHARDWARE 0x00000004 +#define DSBCAPS_LOCSOFTWARE 0x00000008 +#define DSBCAPS_CTRL3D 0x00000010 +#define DSBCAPS_CTRLFREQUENCY 0x00000020 +#define DSBCAPS_CTRLPAN 0x00000040 +#define DSBCAPS_CTRLVOLUME 0x00000080 +#define DSBCAPS_CTRLPOSITIONNOTIFY 0x00000100 +#define DSBCAPS_CTRLFX 0x00000200 +#define DSBCAPS_STICKYFOCUS 0x00004000 +#define DSBCAPS_GLOBALFOCUS 0x00008000 +#define DSBCAPS_GETCURRENTPOSITION2 0x00010000 +#define DSBCAPS_MUTE3DATMAXDISTANCE 0x00020000 +#define DSBCAPS_LOCDEFER 0x00040000 + +#define DSBPLAY_LOOPING 0x00000001 +#define DSBPLAY_LOCHARDWARE 0x00000002 +#define DSBPLAY_LOCSOFTWARE 0x00000004 +#define DSBPLAY_TERMINATEBY_TIME 0x00000008 +#define DSBPLAY_TERMINATEBY_DISTANCE 0x000000010 +#define DSBPLAY_TERMINATEBY_PRIORITY 0x000000020 + +#define DSBLOCK_FROMWRITECURSOR 0x00000001 +#define DSBLOCK_ENTIREBUFFER 0x00000002 + +#define DSSCL_NORMAL 0x00000001 +#define DSSCL_PRIORITY 0x00000002 +#define DSSCL_EXCLUSIVE 0x00000003 +#define DSSCL_WRITEPRIMARY 0x00000004 + +struct DSCAPS{ + DWORD dwSize; + DWORD dwFlags; + DWORD dwMinSecondarySampleRate; + DWORD dwMaxSecondarySampleRate; + DWORD dwPrimaryBuffers; + DWORD dwMaxHwMixingAllBuffers; + DWORD dwMaxHwMixingStaticBuffers; + DWORD dwMaxHwMixingStreamingBuffers; + DWORD dwFreeHwMixingAllBuffers; + DWORD dwFreeHwMixingStaticBuffers; + DWORD dwFreeHwMixingStreamingBuffers; + DWORD dwMaxHw3DAllBuffers; + DWORD dwMaxHw3DStaticBuffers; + DWORD dwMaxHw3DStreamingBuffers; + DWORD dwFreeHw3DAllBuffers; + DWORD dwFreeHw3DStaticBuffers; + DWORD dwFreeHw3DStreamingBuffers; + DWORD dwTotalHwMemBytes; + DWORD dwFreeHwMemBytes; + DWORD dwMaxContigFreeHwMemBytes; + DWORD dwUnlockTransferRateHwBuffers; + DWORD dwPlayCpuOverheadSwBuffers; + DWORD dwReserved1; + DWORD dwReserved2; +}; +typedef DSCAPS *LPDSCAPS; + +struct DSBUFFERDESC{ + DWORD dwSize; + DWORD dwFlags; + DWORD dwBufferBytes; + DWORD dwReserved; + LPWAVEFORMATEX lpwfxFormat; + GUID guid3DAlgorithm; +}; +typedef DSBUFFERDESC *LPDSBUFFERDESC; +typedef const DSBUFFERDESC *LPCDSBUFFERDESC; + +struct DSBPOSITIONNOTIFY{ + DWORD dwOffset; + HANDLE hEventNotify; +}; +typedef DSBPOSITIONNOTIFY *LPDSBPOSITIONNOTIFY; +typedef const DSBPOSITIONNOTIFY *LPCDSBPOSITIONNOTIFY; + + +typedef void *LPDSBCAPS; +typedef struct IDirectSound *LPDIRECTSOUND; +typedef struct IDirectSoundBuffer *LPDIRECTSOUNDBUFFER; + +#undef INTERFACE +#define INTERFACE IDirectSoundBuffer + +DECLARE_INTERFACE_(IDirectSoundBuffer, IUnknown){ + STDMETHOD(QueryInterface) (THIS_ REFIID, LPVOID FAR *) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + STDMETHOD(GetCaps) (THIS_ LPDSBCAPS) PURE; + STDMETHOD(GetCurrentPosition) (THIS_ LPDWORD, LPDWORD) PURE; + STDMETHOD(GetFormat) (THIS_ LPWAVEFORMATEX, DWORD, LPDWORD) PURE; + STDMETHOD(GetVolume) (THIS_ LPLONG) PURE; + STDMETHOD(GetPan) (THIS_ LPLONG) PURE; + STDMETHOD(GetFrequency) (THIS_ LPDWORD) PURE; + STDMETHOD(GetStatus) (THIS_ LPDWORD) PURE; + STDMETHOD(Initialize) (THIS_ LPDIRECTSOUND, LPCDSBUFFERDESC) PURE; + STDMETHOD(Lock) (THIS_ DWORD, DWORD, LPVOID *, LPDWORD, LPVOID *, LPDWORD, DWORD) PURE; + STDMETHOD(Play) (THIS_ DWORD, DWORD, DWORD) PURE; + STDMETHOD(SetCurrentPosition) (THIS_ DWORD) PURE; + STDMETHOD(SetFormat) (THIS_ LPCWAVEFORMATEX) PURE; + STDMETHOD(SetVolume) (THIS_ LONG) PURE; + STDMETHOD(SetPan) (THIS_ LONG) PURE; + STDMETHOD(SetFrequency) (THIS_ DWORD) PURE; + STDMETHOD(Stop) (THIS) PURE; + STDMETHOD(Unlock) (THIS_ LPVOID, DWORD, LPVOID, DWORD) PURE; + STDMETHOD(Restore) (THIS) PURE; +}; + +#undef INTERFACE +#define INTERFACE IDirectSound + +DECLARE_INTERFACE_(IDirectSound, IUnknown){ + + STDMETHOD(QueryInterface) (THIS_ REFIID, LPVOID FAR *) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + STDMETHOD(CreateSoundBuffer) (THIS_ LPCDSBUFFERDESC, LPDIRECTSOUNDBUFFER *, LPUNKNOWN) PURE; + STDMETHOD(GetCaps) (THIS_ LPDSCAPS) PURE; + STDMETHOD(DuplicateSoundBuffer) (THIS_ LPDIRECTSOUNDBUFFER, LPDIRECTSOUNDBUFFER *) PURE; + STDMETHOD(SetCooperativeLevel) (THIS_ HWND, DWORD) PURE; + STDMETHOD(Compact) (THIS) PURE; + STDMETHOD(GetSpeakerConfig) (THIS_ LPDWORD) PURE; + STDMETHOD(SetSpeakerConfig) (THIS_ DWORD) PURE; + STDMETHOD(Initialize) (THIS_ LPGUID) PURE; +}; + + +#undef INTERFACE +#define INTERFACE IDirectSoundNotify + +DECLARE_INTERFACE_(IDirectSoundNotify, IUnknown) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ REFIID, LPVOID *) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IDirectSoundNotify methods + STDMETHOD(SetNotificationPositions) (THIS_ DWORD dwPositionNotifies, LPCDSBPOSITIONNOTIFY pcPositionNotifies) PURE; +}; + +const IID IID_IDirectSoundNotify={0xb0210783,0x89cd,0x11d0,{0xaf,0x8,0x0,0xa0,0xc9,0x25,0xcd,0x16}}; + +#endif diff --git a/mod/pub.mod/freeaudio.mod/dsounddevice.cpp b/mod/pub.mod/freeaudio.mod/dsounddevice.cpp new file mode 100644 index 0000000..d86cea8 --- /dev/null +++ b/mod/pub.mod/freeaudio.mod/dsounddevice.cpp @@ -0,0 +1,222 @@ +// dsounddevice.cpp + +// changed to 4 x buffer spacing + +#include "freeaudio.h" + +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include +#include "dsound.h" + +#define DSOUNDFRAG 2048 + +extern "C" audiodevice *OpenDirectSoundDevice(); + +struct dsounddevice:audiodevice{ + + int running,playing; //threadsafe state machine + + int reset(){ + int res; + + running=1; + playing=0; + mix=new mixer(DSOUNDFRAG*6); + mix->freq=44100; + mix->channels=2; + res=initdevice(DSOUNDFRAG); + if (res) { + running=0; + } + return res; + } + + int close(){ + int timeout; + if (running){ +//stop + running=0; + timeout=20; //100ms timeout + while (timeout-- && playing) { + Sleep(5); + } + freedevice(); + } + return 0; + } + +// private + + HINSTANCE dsoundlib; + HRESULT WINAPI (*DirectSoundCreate)(LPGUID,LPDIRECTSOUND*,LPUNKNOWN); + + IDirectSound *directsound; + IDirectSoundBuffer *primarybuffer; + IDirectSoundBuffer *soundbuffer; + IDirectSoundNotify *soundnotify; + + HANDLE soundevent; + HANDLE soundthread; + DWORD soundthreadid; + + int fragsize; //in bytes + int buffersize; //4*fragsize + + int initdevice(int fragsamples){ + + PCMWAVEFORMAT pcmwf; + DSBUFFERDESC dsbdesc; + DSCAPS dscaps; + int res; +// init device + directsound=0; + primarybuffer=0; + soundbuffer=0; + soundnotify=0; + dsoundlib=LoadLibraryA("dsound"); + DirectSoundCreate=(HRESULT WINAPI (*)(LPGUID,LPDIRECTSOUND*,LPUNKNOWN))GetProcAddress(dsoundlib,"DirectSoundCreate"); + res=DirectSoundCreate(0,&directsound,0); + if (res) return res; + res=directsound->SetCooperativeLevel(GetDesktopWindow(),DSSCL_PRIORITY); + if (res) return res; +// printf("dsoundlib=%d soundcreate=%d res=%d\n",dsoundlib,(int)DirectSoundCreate,res); +// fflush(stdout); + dscaps.dwSize=sizeof(DSCAPS); + res=directsound->GetCaps(&dscaps); + if (res) return res; +// set primary buffer format + memset(&dsbdesc,0,sizeof(DSBUFFERDESC)); // Zero it out. + dsbdesc.dwSize=sizeof(DSBUFFERDESC); + dsbdesc.dwFlags=DSBCAPS_PRIMARYBUFFER; + res=directsound->CreateSoundBuffer(&dsbdesc,&primarybuffer,0); + if (res) return res; + memset(&pcmwf, 0, sizeof(PCMWAVEFORMAT)); + pcmwf.wf.wFormatTag=WAVE_FORMAT_PCM; + pcmwf.wf.nChannels=2; + pcmwf.wf.nSamplesPerSec=44100; + pcmwf.wBitsPerSample=16; + pcmwf.wf.nBlockAlign=4; + pcmwf.wf.nAvgBytesPerSec=pcmwf.wf.nSamplesPerSec * pcmwf.wf.nBlockAlign; + res=primarybuffer->SetFormat((LPWAVEFORMATEX)&pcmwf); + if (res) return res; +// fragment size + fragsize=fragsamples*4; //stereo 16bit=4 bytes per sample + buffersize=fragsize*4; //quad buffered +// format + memset(&pcmwf, 0, sizeof(PCMWAVEFORMAT)); + pcmwf.wf.wFormatTag=WAVE_FORMAT_PCM; + pcmwf.wf.nChannels=2; + pcmwf.wf.nSamplesPerSec=44100; + pcmwf.wf.nBlockAlign=4; + pcmwf.wf.nAvgBytesPerSec=pcmwf.wf.nSamplesPerSec * pcmwf.wf.nBlockAlign; + pcmwf.wBitsPerSample=16; +// description + memset(&dsbdesc,0,sizeof(DSBUFFERDESC)); // Zero it out. + dsbdesc.dwSize=sizeof(DSBUFFERDESC); + dsbdesc.dwBufferBytes=buffersize; //1 * pcmwf.wf.nAvgBytesPerSec; + dsbdesc.lpwfxFormat=(LPWAVEFORMATEX)&pcmwf; + dsbdesc.dwFlags=DSBCAPS_CTRLPOSITIONNOTIFY|DSBCAPS_GETCURRENTPOSITION2|DSBCAPS_GLOBALFOCUS; +// createbuffer + res=directsound->CreateSoundBuffer(&dsbdesc,&soundbuffer,0); + if (res) return res; +// notifications + soundevent=CreateEvent(0,0,0,"SOUNDEVENT"); + if (soundevent==0) return res; + res=soundbuffer->QueryInterface(IID_IDirectSoundNotify,(void**)&soundnotify); + if (res) return res; + DSBPOSITIONNOTIFY notif[4]; + int n; + for (n=0;n<4;n++){ + notif[n].dwOffset=n*fragsize; + notif[n].hEventNotify=soundevent; + } + res=soundnotify->SetNotificationPositions(4,notif); + if (res) return res; +// thread + soundthread=CreateThread(NULL,0,soundproc,this,REALTIME_PRIORITY_CLASS,&soundthreadid); + return 0; + } + + void freedevice(){ + int res; + if (primarybuffer){ + res=primarybuffer->Release(); + primarybuffer=0; + } + if (soundbuffer){ + res=soundbuffer->Release(); + soundbuffer=0; + } + if(directsound) { + res=directsound->Release(); + directsound=0; + } + } + +//thread entry point + + DWORD run(){ + DWORD read,write; + int lastread,loopcount; + void *mem1,*mem2; + DWORD size1,size2; + int readpos,writepos; + int res; + writepos=0; + lastread=0; + loopcount=0; + res=soundbuffer->Lock(0,4*fragsize,&mem1,&size1,&mem2,&size2,0); + if (res) return 0; +// printf("mem1=%d size1=%d mem2=%d size2=%d total=%d\n",mem1,size1,mem2,size2,size1+size2); +// fflush(stdout); + if (size1) memset(mem1,0,size1); + if (size2) memset(mem2,0,size2); + res=soundbuffer->Unlock(mem1,size1,mem2,size2); + if (res) return 0; +// playsound + soundbuffer->Play(0,0,DSBPLAY_LOOPING); + playing=1; +// printf("running=%d\n",running); +// fflush(stdout); + while (running){ + res=soundbuffer->GetCurrentPosition(&read,&write); + if (read0){ + if (count>2) count=2; //avoid overrun + res=soundbuffer->Lock(writepos%buffersize,count*fragsize,&mem1,&size1,&mem2,&size2,0); + if (res) break; +// printf("mem1=%d size1=%d mem2=%d size2=%d total=%d\n",mem1,size1,mem2,size2,size1+size2); +// fflush(stdout); + if (size1) mix->mix16((short*)mem1,size1/2); + if (size2) mix->mix16((short*)mem2,size2/2); + res=soundbuffer->Unlock(mem1,size1,mem2,size2); + if (res) break; + writepos+=size1+size2; + } + res=WaitForSingleObject(soundevent,1000); + if (res!=WAIT_OBJECT_0) break; + } + playing=0; + soundbuffer->Stop(); +// printf("done...\n"); +// fflush(stdout); + } + + static DWORD WINAPI soundproc(LPVOID lpParam){ + dsounddevice *dsd; + dsd=(dsounddevice*)lpParam; + return dsd->run(); + } +}; + +audiodevice *OpenDirectSoundDevice(){ + return new dsounddevice(); +} diff --git a/mod/pub.mod/freeaudio.mod/freeaudio.bmx b/mod/pub.mod/freeaudio.mod/freeaudio.bmx new file mode 100644 index 0000000..5dd5e9a --- /dev/null +++ b/mod/pub.mod/freeaudio.mod/freeaudio.bmx @@ -0,0 +1,125 @@ + +Module Pub.FreeAudio + +ModuleInfo "Version: 1.22" +ModuleInfo "Author: Simon Armstrong" +ModuleInfo "License: zlib/libpng" +ModuleInfo "Copyright: Blitz Research Ltd" +ModuleInfo "Modserver: BRL" + +ModuleInfo "History: 1.22 Release" +ModuleInfo "History: Fixed leak with sound recycling" +ModuleInfo "History: 1.21 Release" +ModuleInfo "History: Fixed reference counting for brl.freeaudioaudio" +ModuleInfo "History: 1.20 Release" +ModuleInfo "History: Removed duplication of sample memory" +ModuleInfo "History: 1.19 Release" +ModuleInfo "History: Added DirectSound mode" +ModuleInfo "History: 1.18 Release" +ModuleInfo "History: added fa_ChannelPosition for live sample generation" +ModuleInfo "History: 1.17 Release" +ModuleInfo "History: added check for windows playback position overflow" +ModuleInfo "History: 1.15 Release" +ModuleInfo "History: added low latency windows98 fix" +ModuleInfo "History: 1.14 Release" +ModuleInfo "History: fixed 1.13 recycling of stopped channels fix" +ModuleInfo "History: 1.13 Release" +ModuleInfo "History: fixed recycling of stopped channels" +ModuleInfo "History: 1.12 Release" +ModuleInfo "History: Uses linear interpolation for improved fidelity at low rates" +ModuleInfo "History: 1.11 Release" +ModuleInfo "History: Fixed freepool sounds Not resetting parameters - thanks To Fetze" +ModuleInfo "History: 1.10 Release" +ModuleInfo "History: Added ALSA support for Linux courtesy Craig Kiesau" +ModuleInfo "History: 1.09 Release" +ModuleInfo "History: Improved channel playback timing" +ModuleInfo "History: 1.08 Release" +ModuleInfo "History: Fixed memory leak in fa_FreeSound()" +ModuleInfo "History: 1.07 Release" +ModuleInfo "History: Removed output transitions for queued/paused sounds" +ModuleInfo "History: 1.06 Release" +ModuleInfo "History: Windows device error now silently fails" +ModuleInfo "History: 1.05 Release" +ModuleInfo "History: Linux version now opens audio device on second thread" +ModuleInfo "History: 1.04 Release" +ModuleInfo "History: Removed Linux debug output" + +Import "freeaudio.cpp" +Import "freeaudioglue.cpp" + +?Win32 +Import "dsounddevice.cpp" +Import "mmdevice.cpp" +Extern "C" +Function OpenMultiMediaDevice() +Function OpenDirectSoundDevice() +End Extern +?MacOS +Import "-framework AudioUnit" +Import "-framework AudioToolbox" +Import "coreaudiodevice.cpp" +Extern +Function OpenCoreAudioDevice() +End Extern +?Linux +'Import "-lasound" +'Import "alsadevice.cpp" +Import "ossdevice.cpp" +Extern "C" +Function OpenOSSDevice() +'Function OpenALSADevice() +End Extern +? + +Extern + +Const FA_CHANNELSTATUS_FREE=0 +Const FA_CHANNELSTATUS_STOPPED=1 +Const FA_CHANNELSTATUS_SINGLESHOT=2 +Const FA_CHANNELSTATUS_LOOPING=4 +Const FA_CHANNELSTATUS_STREAMING=8 +Const FA_CHANNELSTATUS_PAUSED=16 + +Function fa_Reset( audiodevice ) +Function fa_Close() +Function fa_CreateSound( length,bits,channels,hertz,samples:Byte Ptr=Null,looping=False ) +Function fa_WriteSound( sound,samples:Byte Ptr,length ) 'length really neceesary? +Function fa_FreeSound( sound ) +Function fa_AllocChannel() +Function fa_FreeChannel( channel ) +Function fa_PlaySound( sound,paused_flag,channel ) + +Function fa_StopChannel( channel ) +Function fa_ChannelStatus( channel ) +Function fa_ChannelPosition( channel ) + +Function fa_SetChannelPaused( channel,paused ) +Function fa_SetChannelVolume( channel,volume# ) +Function fa_SetChannelRate( channel,pitch# ) +Function fa_SetChannelPan( channel,pan# ) +Function fa_SetChannelDepth( channel,depth# ) + +End Extern + +Function fa_Init( deviceid ) + Local device +?Win32 + If deviceid + device=OpenDirectSoundDevice() + Else + device=OpenMultiMediaDevice() + EndIf +?Linux + Select deviceid + Case 0 + device=OpenOSSDevice() +' Case 1 +' device=OpenALSADevice() + EndSelect +?MacOS + device=OpenCoreAudioDevice() +? + Local res=-1 + If device res=fa_Reset(device) + Return res +End Function diff --git a/mod/pub.mod/freeaudio.mod/freeaudio.cpp b/mod/pub.mod/freeaudio.mod/freeaudio.cpp new file mode 100644 index 0000000..acaf7d5 --- /dev/null +++ b/mod/pub.mod/freeaudio.mod/freeaudio.cpp @@ -0,0 +1,590 @@ +// freeaudio.cpp + +// 2007.02.15 new dsound device, readpointer and tidy up SA +// 2006.05.26 overflow handling for winmmdevice waveOutGetPosition +// 2006.04.26 winmmdevice doubles latency for windows98 +// 2006.04.26 fixed recycling of autostopped channels +// 2006.01.17 fixed recycling of stopped channels +// 2005.11.22 fixed freepool sounds not resetting parameters - thanks to Fetze +// 2005.09.13 new ALSA code for Linux - thanks to Craig Kiesau +// 2005.08.05 new single looped buffer with timer callback for win32mmdevice +// 2005.07.04 reduced audio latency +// 2005.06.17 fixed memory leak in sound allocation +// 2005.05.23 removed output transitions for queued/paused sounds +// 2005.04.05 added AudioOutputUnitStop call for apple close +// 2005.01.07 fixed up audio hardware failure handling +// 2004.08.16 fixed channelstatus, allocchannel now always returns unique handle +// 2004.06.04 added linux drivers +// 2004.03.19 new ,loop parameter support in loadsound(file,looping) +// 2004.03.02 dynamic sounds release temp channel when recycled SA +// 2004.02.06 initial single file release SA + +#include "freeaudio.h" + +#include +#include +#include + +//static audiodevice *audio=0; + +mixer::mixer(int bufflen):output(0) +{ + int i; + size=bufflen; + playlist=0; +// freelist=0; + mbuff=new int[bufflen]; + for (i=0;ichannel){ + io->freechannel(s->channel); + s->channel=0; + } + }else{ + s=new sound(this); + } + if (out){ + s->resetrate(out->getrate(1)); + s->resetvolume(out->getvolume(1)); + s->resetpan(out->getpan(1)); + s->resetdepth(out->getdepth(1)); + }else{ + s->resetrate(65536); + s->resetvolume(VOLUMEONE); + s->resetpan(0); + s->resetdepth(0); + } + return s; +} + +sound *mixer::play(sample *sam,output *out,int state) +{ + sound *s; + + if (!sam) return 0; + if (sam->channels==0) return 0; + if (freq==0) return 0; + + s=allocsound(out); + sam->refcount++; + s->status=state; + s->samp=sam; + s->pos64=0; + s->mix64=0; + s->starttime=bbMilliSecs(); + startlist.push(s); + return s; +} + +sound::sound(output *p):output(p){ + status=STOPPED; + next=0; + resetrate(65536); + resetvolume(VOLUMEONE); + resetpan(0); + resetdepth(0); +} + +void sound::flush(){ + if (status==STREAMING && samp){ + int readpos=samp->writepos; + mix64=((i64)(readpos*samp->channels))<<32; + pos64=((i64)((readpos%samp->samples)*samp->channels))<<32; + } +} + +// mix audio stream at rate,amplitude with linear interpolation + +#define blend(a,b,c) (a+((((b)-(a))*((((int)(c))>>16)&65535))>>16)) + +#define ublend(a,b,c) ( ((a-128)<<8) + ((((b)-(a))*((((int)(c))>>16)&65535))>>8) ) + +/* +int ublend(u8 a,u8 b,int c) +{ + int a0=a-128; + int b0=b-128; + return blend(a0,b0,c); +} +*/ + +int sound::mix(int *b,int size) //returns 0=ok 1=releasechannel +{ + short *s; + u8 *c; + int t,n; + int count; + short pan,depth; + short right,left; + int amp0,amp1; + i64 freq0,freq1; + i64 len64,freq64; + int p; + + if (status==STOPPED) return 1; + if (status&PAUSED) return -2; + if (status==FREE) return -1; + count=size/2; + + if (delay) + { + if (delay>=count) + { + delay-=count; + return 0; + } + if (delay>0) + { + count-=delay; + b+=delay*2; + } + delay=0; + } + + freq0=((i64)samp->freq*getrate(0))/44100; + freq1=((i64)samp->freq*getrate(1))/44100; + n=(freq0*count)>>16; + int readpos=mix64>>32; + if ((status&STREAMING) && (readpos+n>samp->writepos)) return 0; + amp0=getvolume(0); + amp1=getvolume(1); + pan=getpan(1); + depth=getdepth(1); + len64=((i64)(samp->samples*samp->channels))<<32; + + if ((amp0==amp1) && (freq0==freq1)) + { + freq64=(freq0*samp->channels)<<16; + if (amp1==0) //muted + { + currentvolume=0; + pos64+=freq64*count; + mix64+=freq64*count; + while (pos64>=len64) + { + if (status&LOOPING) pos64-=len64;else return 1; + } + return 0; + } + right=left=amp0; + if (pan>0) left=(left*(4096-pan))>>12; + if (pan<0) right=(right*(4096+pan))>>12; + if (depth<0) right=-right; + if (samp->bits==8) + { + c=(u8 *)samp->data; + if (samp->channels==1) + { + while (count-->0) + { + p=(int)(pos64>>32); + t=ublend(c[p],c[p+1],pos64); + mix64+=freq64; + pos64+=freq64; + *b+++=(t*left)>>8; + *b+++=(t*right)>>8; + while (pos64>=len64) + { + if (status&LOOPING) pos64-=len64;else return 1; + } + } + } + else + { + while (count-->0) + { + p=(int)(pos64>>32)&-2; + *b+++=(ublend(c[p+0],c[p+2],pos64>>1)*left)>>8; + *b+++=(ublend(c[p+1],c[p+3],pos64>>1)*right)>>8; + pos64+=freq64; + mix64+=freq64; + while (pos64>=len64) + { + if (status&LOOPING) pos64-=len64;else return 1; + } + } + } + } + else + { + s=(short *)samp->data; + if (samp->channels==1) + { + while (count-->0) + { + p=(int)(pos64>>32); + t=blend(s[p],s[p+1],pos64); + mix64+=freq64; + pos64+=freq64; + *b+++=(t*left)>>8; + *b+++=(t*right)>>8; + while (pos64>=len64) + { + if (status&LOOPING) + { + pos64-=len64; + } + else + { + return 1; + } + } + } + } + else + { + while (count-->0) + { + p=(int)(pos64>>32)&-2; + *b+++=(blend(s[p+0],s[p+2],pos64>>1)*left)>>8; + *b+++=(blend(s[p+1],s[p+3],pos64>>1)*right)>>8; + mix64+=freq64; + pos64+=freq64; + while (pos64>=len64) + { + if (status&LOOPING) pos64-=len64;else return 1; + } + } + } + } + return 0; + } + else //dynamice volume|frequency + { + int v1,v2,vd; + i64 f1,f2,fd; + + v1=amp0<<8; + v2=amp1<<8; + vd=(v2-v1)/count; + + f1=(freq0*samp->channels)<<16; + f2=(freq1*samp->channels)<<16; + fd=(f2-f1)/count; + + currentvolume=targetvolume; + currentrate=targetrate; + + if (samp->bits==8) + { + c=(u8 *)samp->data; + if (samp->channels==1) + { + while (count-->0) + { + left=right=v1>>8; + if (pan>0) left=(left*(4096-pan))>>12; + if (pan<0) right=(right*(4096+pan))>>12; + p=(int)(pos64>>32); + t=ublend(c[p],c[p+1],pos64); + *b+++=(left*t)>>8; + *b+++=(right*t)>>8; + v1+=vd; + pos64+=f1; + mix64+=f1; + f1+=fd; + while (pos64>=len64) + { + if (status&LOOPING) pos64-=len64;else return 1; + } + } + } + else + { + while (count-->0) + { + left=right=v1>>8; + if (pan>0) left=(left*(4096-pan))>>12; + if (pan<0) right=(right*(4096+pan))>>12; + if (depth<0) right=-right; + p=(int)(pos64>>32)&-2; + *b+++=(ublend(c[p+0],c[p+2],pos64>>1)*left)>>8; + *b+++=(ublend(c[p+1],c[p+3],pos64>>1)*right)>>8; + v1+=vd; + pos64+=f1; + mix64+=f1; + f1+=fd; + while (pos64>=len64) + { + if (status&LOOPING) pos64-=len64;else return 1; + } + } + } + } + else + { + s=(short *)samp->data; + if (samp->channels==1) + { + while (count-->0) + { + left=right=v1>>8; + if (pan>0) left=(left*(4096-pan))>>12; + if (pan<0) right=(right*(4096+pan))>>12; + if (depth<0) right=-right; + p=(int)(pos64>>32); + t=blend(s[p],s[p+1],pos64); + *b+++=(t*left)>>8; + *b+++=(t*right)>>8; + v1+=vd; + mix64+=f1; + pos64+=f1; + f1+=fd; + while (pos64>=len64) + { + if (status&LOOPING) pos64-=len64;else return 1; + } + } + } + else + { + while (count-->0) + { + left=right=v1>>8; + if (pan>0) left=(left*(4096-pan))>>12; + if (pan<0) right=(right*(4096+pan))>>12; + if (depth<0) right=-right; + p=(int)(pos64>>32)&-2; + *b+++=(blend(s[p+0],s[p+2],pos64>>1)*left)>>8; + *b+++=(blend(s[p+1],s[p+3],pos64>>1)*right)>>8; + v1+=vd; + mix64+=f1; + pos64+=f1; + f1+=fd; + while (pos64>=len64) + { + if (status&LOOPING) pos64-=len64;else return 1; + } + } + } + } + return 0; + } +} + +void mixer::releaseall() +{ + sound *s; + + while (s=playlist) + { + playlist=s->next; + releasesound(s); + } +} + +void mixer::releasesound(sound *s) // should only be called by mix +{ + s->samp->free(); + s->samp=0; + freelist.push(s); +} + +void mixer::mix(int count) +{ + sound *sptr,*tptr,**lptr; + + while (sptr=startlist.pull()) + { + sptr->next=playlist; + playlist=sptr; + int skip=20+sptr->starttime-bbMilliSecs(); + if (skip<0) skip=0; + skip=(skip*freq)/1000; + sptr->delay=skip; + } + + sptr=playlist; + lptr=&playlist; + while (sptr) + { + int res=sptr->mix(mbuff,count); //,count + switch (res) + { + case 0: + lptr=&sptr->next; + sptr=sptr->next; + break; + case 1: //STOP + if (sptr->recycle){ + sptr->status=output::FREE; //dynamic + tptr=sptr; + *lptr=sptr=sptr->next; + releasesound(tptr); + }else{ + sptr->status=output::STOPPED; + lptr=&sptr->next; + sptr=sptr->next; + } + break; + case -1: //FREE + tptr=sptr; + *lptr=sptr=sptr->next; + releasesound(tptr); + break; + case -2: //PAUSED + lptr=&sptr->next; + sptr=sptr->next; + break; + } + } +} + +void mixer::mix8(u8 *abuff,int count) +{ + int i,j; + int *tptr; + + if (count==0) count=size; + mix(count); + tptr=mbuff; + for (i=0;i>16)+0x80; + if (j & 0xffffff00) {if (j<0) j=0;else j=0xff;} + *abuff++=j; + *tptr++=0; + } +} + +void mixer::mix16(short *d,int count) +{ + int *tptr; + + if (count==0) count=size; + mix(count); + tptr=mbuff; + for (int i=0;i>4,-32768,32767); + *tptr++=0; + } +} + +void mixer::mix16s(short *dd,int count) +{ + int *d,*tptr; + if (count==0) count=size; + mix(count); + d=(int*)dd; + tptr=mbuff; + for (int i=0;i>8; + int p=*d; + short s1=p; + u32 p1=BND(s1+t,-32768,32767); + u32 p2=BND((p>>16)+t,-32768,32767); + *d++=(p1&0xffff)+(p2<<16); + *tptr++=0; + } +} + +int sample::init(int n,int f,int c,int b,void *_data) +{ + freq=f; + channels=c; + bits=b; + refcount=1; + if (b<8) b=8; //single bit handler + samplesize=channels*b/8; + samples=n;//size/samplesize; + sizebytes=n*samplesize; + if (_data){ + capacity=0; + data=_data; + }else{ + capacity=sizebytes+samplesize; + data=malloc(capacity); + } + buffer=data; + writepos=0; + return 0; +}; + + +void sample::setloop(int l) +{ + char *p; + + loop=l; + p=(char*)data; + if (loop) + memcpy(p+sizebytes,p,samplesize); + else + memcpy(p+sizebytes,p+sizebytes-samplesize,samplesize); +} + +void sample::free() +{ + if (--refcount==0) + { + if (capacity) ::free(data); + delete this; + } +} + +void sample::write(int n) +{ + writepos+=n; + buffer=(char *)data+(writepos%samples)*samplesize; +} + +int sample::write( void *src,int samples,int readpos) +{ + int n,t,nn; //,bytes; + + t=0; + while (samples) + { + n=buffersize(readpos); + if (n==0) break; + if (n>samples) n=samples; + nn=n*samplesize; + memcpy(buffer,src,nn); + src=(char*)src+nn; + samples-=n;t+=n;write(n); + } + return t; +} + +int sample::buffersize(int readpos) +{ + int inuse,rpos,wpos; + inuse=writepos-readpos; + if (inuse>=samples) return 0; //buffer full! + wpos=writepos%samples; + rpos=readpos%samples; + if (rpos>wpos) return rpos-wpos; + return samples-wpos; +} + +int sample::peek(int t) +{ + int s; + + if (t<0||t>=samples) return 0; + + switch (samplesize) + { + case 1: + s=((u8*)data)[t]<<8; + break; + case 2: + if (channels==1) s=((u16*)data)[t];else s=((u8*)data)[t*2]<<8; + break; + case 4: + s=((u16*)data)[t*2]; + break; + } + return s-32768; +} + diff --git a/mod/pub.mod/freeaudio.mod/freeaudio.h b/mod/pub.mod/freeaudio.mod/freeaudio.h new file mode 100644 index 0000000..24ef1b2 --- /dev/null +++ b/mod/pub.mod/freeaudio.mod/freeaudio.h @@ -0,0 +1,312 @@ +// freeaudio.h + +// version 0.3 +// freeware cross platform audio engine sponsored by Blitz Research Ltd + +#ifndef freeaudio_h +#define freeaudio_h + +extern "C" int bbMilliSecs(); + +typedef int (*ReadFunc)(void*,int); + +#if _MSC_VER + typedef __int64 i64; +#else + typedef long long i64; +#endif + +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned int u32; + +#define MAXCHANNELS 4096 + +#define VOLUMEONE 4096 + +#define BBCALL + +#define ABS(a) (((a)>0)?(a):-(a)) +#define MAX(a,b) (((a)>(b))?(a):(b)) +#define MIN(a,b) (((a)<(b))?(a):(b)) +#define BND(a,b,c) MIN(MAX((a),(b)),(c)) + +struct control +{ + int current,target; +}; + +struct output +{ + enum outputstates{FREE=0,STOPPED=1,SINGLESHOT=2,LOOPING=4,STREAMING=8,PAUSED=16}; + + output *parent; + int status,channel,recycle; + + virtual void setrate(int r) {} + virtual void setvolume(short v) {} + virtual void setpan(short p) {} + virtual void setdepth(short d) {} + + virtual int getrate(int t) {return 65536;} //(status&PAUSED)?0:4096;} + virtual short getvolume(int t) {return 4096;} + virtual short getpan(int t) {return 0;} + virtual short getdepth(int t) {return 0;} + + virtual int getposition() {return 0;} + + output(output *p) { + parent=p; + status=FREE; + channel=0; + recycle=0; + } + + void stop(int user) { + if (user) recycle=1; + if (status!=FREE) status=STOPPED; + } + + void setpause(int pause) + { + if (pause) + { + status|=PAUSED; + } + else + { + status&=~PAUSED; + } + } + + void setloop(int loop) + { + if (loop) + { + if (status&SINGLESHOT) status=(status&~SINGLESHOT)|LOOPING; + } + else + { + if (status&LOOPING) status=(status&~LOOPING)|SINGLESHOT; + } + } +}; + +struct sample +{ + int freq,channels,bits; + int loop0,loop1; + int samples,samplesize,sizebytes; + int writepos; + int refcount; + int loop; + void *data,*buffer; + int capacity; + + sample() {freq=channels=bits=0;loop=0;capacity=0;} + int init(int length,int freq,int channels,int bits,void *data); //data=0 mallocs length in samples + void free(); + int buffersize(int readpos); + void write(int n); + int write(void *mem,int bytes,int readpos=0); + int peek(int t); + void setloop(int flag); +}; + +struct sound:output +{ + sound *next; + sample *samp; + i64 pos64; + i64 mix64; + + int currentrate,targetrate; + short currentvolume,targetvolume; + short currentpan,targetpan; + short currentdepth,targetdepth; + int starttime,delay; + + virtual int getrate(int t) {return t?targetrate:currentrate;} + virtual short getvolume(int t) {return t?targetvolume:currentvolume;} + virtual short getpan(int t) {return t?targetpan:currentpan;} + virtual short getdepth(int t) {return t?targetdepth:currentdepth;} + virtual int getposition() {return (mix64>>32)/samp->channels;} + + virtual void setrate(int r) {targetrate=r;if (status&PAUSED) currentrate=r;} + virtual void setvolume(short v) {targetvolume=v;if (status&PAUSED) currentvolume=v;} + virtual void setpan(short p) {targetpan=p;if (status&PAUSED) currentpan=p;} + virtual void setdepth(short d) {targetdepth=d;if (status&PAUSED) targetdepth=d;} + + void resetrate(int r) {currentrate=targetrate=r;} + void resetvolume(short v) {currentvolume=targetvolume=v;} + void resetpan(short p) {currentpan=targetpan=p;} + void resetdepth(short d) {currentdepth=targetdepth=d;} + +// private + sound(output *p); + void flush(); + int mix(int *b,int size); //return 0 to remove from playlist +}; + +struct queue +{ + int head,tail; + sound *que[MAXCHANNELS]; + + queue() {head=tail=0;} + + void push(sound *s) + { + que[tail++]=s; + if (tail>=MAXCHANNELS) tail=0; + } + + sound *pull() + { + sound *snd=0; + if (head!=tail) + { + snd=que[head++]; + if (head>=MAXCHANNELS) head=0; + } + return snd; + } +}; + +struct mixer:output +{ + int *mbuff,size; + int freq,channels; + sound *playlist; + queue startlist; + queue freelist; //multi threading friendly + + mixer(int size); + + sound *allocsound(output *out); + sound *play(sample *s,output *out,int state); + + void releasesound(sound *s); + void releaseall(); + + void mix8(u8 *abuff,int count=0); + void mix16(short *abuff,int count=0); + void mix16s(short *abuff,int count=0); + void mix(int count); +}; + +// freeaudio device + +struct audiodevice +{ + mixer *mix; + +// virtual OS dependent interface + virtual int reset()=0; + virtual int close()=0; + + audiodevice() + { + mix=0; + } + + sound *play(sample *sam,output *out,int paused) + { + sound *snd; + int freq,vol,state; + + if (mix==0) return 0; + state=sound::SINGLESHOT; + if (sam->loop) state=sound::LOOPING; + if (paused) state|=sound::PAUSED; //freq=0; + snd=mix->play(sam,out,state); + return snd; + } +}; + +// freeaudio standard C interface + +static audiodevice *audio=0; + +struct systemio +{ + output **channels; + int *freelist; + int *cyclelist; + + systemio() + { + channels=new output*[MAXCHANNELS]; + freelist=new int[MAXCHANNELS]; + cyclelist=new int[MAXCHANNELS]; + for (int i=0;istop(0); + channels[ch]=0; + } + freelist[ch]=freelist[0]; + freelist[0]=ch; + } + + void setchannel(int ch,output *o) + { + output *old; + if (ch==0) return; + old=getchannel(ch); + if (old) old->stop(0); + ch&=(MAXCHANNELS-1); + channels[ch]=o; + } + + output *getchannel(int ch) + { + if (ch==0) return 0; + if (audio==0) return 0; + int cycle=ch & (-MAXCHANNELS); + ch&=(MAXCHANNELS-1); + if (cyclelist[ch]==cycle) + { + if (!channels[ch]) channels[ch]=audio->mix->allocsound(0); + return channels[ch]; + } + return 0; + } +}; + +static systemio *io=0; + + +#endif diff --git a/mod/pub.mod/freeaudio.mod/freeaudioglue.cpp b/mod/pub.mod/freeaudio.mod/freeaudioglue.cpp new file mode 100644 index 0000000..ccc4165 --- /dev/null +++ b/mod/pub.mod/freeaudio.mod/freeaudioglue.cpp @@ -0,0 +1,154 @@ +// freeaudioglue.cpp + +#include "freeaudio.h" +#include "freeaudioglue.h" + +//int BBCALL fa_Init(int deviceid){ +// audio=OpenSystemAudio(); + +int BBCALL fa_Reset(audiodevice *audiodevice){ + audio=audiodevice; + if (audio==0) return -1; + if (audio->reset()) {audio->close();return -1;} + io=new systemio(); + return 0; +} + +int BBCALL fa_Close(){ + if (io) delete io; + if (audio) audio->close(); + audio=0; + io=0; + return 0; +} + +int BBCALL fa_PlaySound( int sound,int paused,int ch ){ + output *out; + bool recycle; + if (audio && sound) + { + recycle=(ch==0); + if (ch) + { + out=io->getchannel(ch); + } + else + { + ch=io->allocchannel(); + out=0; + } + out=audio->play((sample*)sound,out,paused); + io->setchannel(ch,out); + out->channel=ch; + out->recycle=recycle; + } + return ch; +} + +int BBCALL fa_AllocChannel(){ + if (io) return io->allocchannel(); + return 0; +} + +void BBCALL fa_FreeChannel( int ch ){ + if (io) io->freechannel(ch); +} + +int BBCALL fa_ChannelStatus( int channel ){ + output *out; + if (io==0) return 0; + out=io->getchannel(channel); + if (out) return out->status; + return 0; +} + +int BBCALL fa_ChannelPosition( int channel ){ + output *out; + if (io==0) return 0; + out=io->getchannel(channel); + if (out) return out->getposition(); + return 0; +} + +int BBCALL fa_StopChannel( int channel ){ + output *out; + if (io==0) return 0; + out=io->getchannel(channel); + if (out) { + out->stop(1); + io->freechannel(channel); + } + return 0; +} + +int BBCALL fa_SetChannelPaused( int channel,int paused ){ + output *out; + if (io==0) return 0; + out=io->getchannel(channel); + if (out) out->setpause(paused); + return 0; +} + +int BBCALL fa_SetChannelVolume( int channel,float volume ){ + output *out; + if (io==0) return 0; + out=io->getchannel(channel); + if (out) out->setvolume((short)(volume*VOLUMEONE)); + return 0; +} + +int BBCALL fa_SetChannelRate( int channel,float hertz ){ + output *out; + if (io==0) return 0; + out=io->getchannel(channel); + if (out) out->setrate((int)(hertz*65536)); + return 0; +} + +int BBCALL fa_SetChannelPan( int channel,float pan ){ + output *out; + if (io==0) return 0; + out=io->getchannel(channel); + if (out) out->setpan((short)(pan*4096)); + return 0; +} + +int BBCALL fa_SetChannelDepth( int channel,float depth ){ + output *out; + if (io==0) return 0; + out=io->getchannel(channel); + if (out) out->setdepth((short)(depth*4096)); + return 0; +} + +int BBCALL fa_CreateSound( int length,int bits,int channels,int freq,const char *samples,int loop ){ + sample *sam; + + if (io==0) return 0; + sam=new sample(); + if (loop==0x80000000){ //dynamic sounds stay in app memory + sam->init(length,freq,channels,bits,(void*)samples); + }else{ + sam->init(length,freq,channels,bits,0); + if( samples ) sam->write((void*)samples,length,0); + } + sam->setloop(loop); + return (int)sam; +} + +int BBCALL fa_WriteSound( int sound, void *data, int samples){ + sample *sam; + + if (io==0) return 0; + sam=(sample*)sound; + return sam->write(data,samples,0); +} + +int BBCALL fa_FreeSound( int sound ){ + sample *sam; + if (io==0) return 0; + sam=(sample*)sound; + if (sam) sam->free(); + return 0; +} + diff --git a/mod/pub.mod/freeaudio.mod/freeaudioglue.h b/mod/pub.mod/freeaudio.mod/freeaudioglue.h new file mode 100644 index 0000000..5e2913f --- /dev/null +++ b/mod/pub.mod/freeaudio.mod/freeaudioglue.h @@ -0,0 +1,40 @@ +// freeaudioglue.h +// version 0.2 + +// freeware cross platform audio engine sponsored by Blitz Research Ltd + +// 2004.02.07 initial 0.1 release SA +// 2004.03.02 channel management handling added SA + +#ifndef freeaudioglue_h +#define freeaudioglue_h + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +int fa_Reset(struct audiodevice *device); +int fa_Close(); + +int fa_CreateSound(int samples,int bits,int channels,int freq,const char *buf,int loop); +int fa_WriteSound( int sound, void *data, int samples); +int fa_FreeSound( int sound ); +int fa_PlaySound( int sound,int paused,int channel ); + +int fa_AllocChannel(); +void fa_FreeChannel( int channel ); + +int fa_ChannelStatus( int channel ); +int fa_StopChannel( int channel ); +int fa_SetChannelPaused( int channel,int paused ); +int fa_SetChannelVolume( int channel,float volume ); +int fa_SetChannelRate( int channel,float hertz ); +int fa_SetChannelPan( int channel,float pan ); +int fa_SetChannelDepth( int channel,float depth ); +int fa_ChannelPosition( int channel ); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/mod/pub.mod/freeaudio.mod/mmdevice.cpp b/mod/pub.mod/freeaudio.mod/mmdevice.cpp new file mode 100644 index 0000000..5da31fe --- /dev/null +++ b/mod/pub.mod/freeaudio.mod/mmdevice.cpp @@ -0,0 +1,208 @@ +// mmdevice.cpp +// windows mediadevice version 2 + +#include "freeaudio.h" + +#ifdef _WIN32 + +#define WIN32_LEAN_AND_MEAN + +#include +#include +#include +#include + +extern "C" audiodevice *OpenMultiMediaDevice(); + +static void __stdcall audioTimerProc( UINT id,UINT msg,DWORD user,DWORD u1,DWORD u2 ); + +struct pcmsetting +{ + WAVEFORMATEX wf; + + pcmsetting(int freq,int chan,int bits) + { + wf.wFormatTag=WAVE_FORMAT_PCM; + wf.nChannels=chan; + wf.nSamplesPerSec=freq; + wf.nBlockAlign=chan*bits/8; + wf.nAvgBytesPerSec=freq*wf.nBlockAlign; + wf.wBitsPerSample=bits; + wf.cbSize=0; + } +}; + +struct abuffer { + LPWAVEHDR hdr; + u8 *data; + int id; + + void init(HWAVEOUT device,int size,int n) { + hdr=(LPWAVEHDR)malloc(sizeof(WAVEHDR)); + data=(u8*)calloc(size,1); + id=n; + hdr->lpData=(LPSTR)data; + hdr->dwBufferLength=size; + hdr->dwUser=(int)this; + hdr->dwFlags=WHDR_BEGINLOOP|WHDR_ENDLOOP; + hdr->dwLoops=0x7fffffff; + waveOutPrepareHeader(device,hdr,sizeof(WAVEHDR)); + } + + void play(HWAVEOUT device) { + if (waveOutWrite(device,hdr,sizeof(WAVEHDR))) { + printf("waveOutWrite error\n"); + } + } + + void finit(HWAVEOUT device) { + waveOutUnprepareHeader(device,hdr,sizeof(WAVEHDR)); + free(data);data=0; + free(hdr);hdr=0; + } +}; + +struct winmmdevice:audiodevice { + HWAVEOUT device; + int buffersize; + int samplesize; //1=8 bit 2=16bit + abuffer buffer; + int bnum; + int mode; //0=8bit 1=16bit + int playing; + int timer; + int playpos,mixpos; + int timeout; + int lagbuffers; + + int iswin98() + { + OSVERSIONINFO osinfo; + osinfo.dwOSVersionInfoSize=sizeof(OSVERSIONINFO); + if (GetVersionEx(&osinfo)) + { + if + ( + (osinfo.dwPlatformId==VER_PLATFORM_WIN32_WINDOWS) && (osinfo.dwMajorVersion>4) + //((osinfo.dwMajorVersion>4)||((osinfo.dwMajorVersion==4)&&(osinfo.dwMinorVersion>0))) + ) //osversion=1; + return 0; + if (osinfo.dwPlatformId==VER_PLATFORM_WIN32_NT) return 0;//osversion=2; + } + return 1; + } + + int reset() + { + int sz=(iswin98())?2048:1024; //10ms fragment size 20ms for windows98 + mix=new mixer(sz); + device=0; + buffersize=0; + bnum=0; + mode=0; + playing=0; + timer=0; + timeout=0; + playpos=0; + mixpos=0; + return init(44100,2,16,sz); + } + + int close() + { + playing=0; + if (timer) timeKillEvent( timer ); + timer=0; + mix->releaseall(); + if (device) + { + waveOutReset(device); + buffer.finit(device); + waveOutClose(device); + } + } + + int init(int freq,int channels,int bits,int size) + { + pcmsetting pcm(freq,channels,bits); + if (bits==8) {mode=0;samplesize=1;} else {mode=1;samplesize=2;} + if (waveOutOpen(&device,WAVE_MAPPER,&pcm.wf,0,(long)this,0)) return 1; + buffersize=size; + bnum=0; + mix->freq=freq; + mix->channels=channels; + buffer.init(device,size*samplesize*32,0); + timeSetEvent(5,5,audioTimerProc,(DWORD)this,TIME_ONESHOT);//PERIODIC ); + timeout=0; + playing=1; + lagbuffers=6; + flip(); + buffer.play(device); + return 0; + } + + void flip() + { + MMTIME time; + int err; + + if (playing==0) return; + if (timeout) + { + if (--timeout) return; + buffer.play(device); + } + memset(&time,0,sizeof(MMTIME)); + time.wType=TIME_BYTES; + err=waveOutGetPosition(device,&time,sizeof(MMTIME)); + + if (time.wType!=TIME_BYTES) err=-666;else if (time.u.cb>0x10000000) err=-6667; + if (err) { +// printf("waveOutGetPosition failed err=%d\n",err);fflush(stdout); + waveOutReset(device); + mixpos=0; + memset(buffer.data,0,buffersize*samplesize*32); + buffer.play(device); + return; + } + + int wavepos=time.u.cb/samplesize; + int writeahead=buffersize*lagbuffers; + if (wavepos && wavepos+buffersize*2>mixpos) + { + timeout=250; + memset(buffer.data,0,buffersize*samplesize*32); + waveOutReset(device); + if (lagbuffers<10) lagbuffers+=2; + mixpos=buffersize*lagbuffers*2; +// printf("collision");fflush(stdout); + return; + } + int seek=wavepos+writeahead; + while (mixposmix8(buffer.data+f*buffersize); + } + else + { + mix->mix16((short *)buffer.data+f*buffersize); + } + mixpos+=buffersize; + } + } +}; + +static void __stdcall audioTimerProc( UINT id,UINT msg,DWORD user,DWORD u1,DWORD u2 ) { + ((winmmdevice *)user)->flip(); + timeSetEvent(5,5,audioTimerProc,(DWORD)user,TIME_ONESHOT); +} + +audiodevice *OpenMultiMediaDevice() { + return new winmmdevice(); +} + +#endif + diff --git a/mod/pub.mod/freeaudio.mod/ossdevice.cpp b/mod/pub.mod/freeaudio.mod/ossdevice.cpp new file mode 100644 index 0000000..d9a07b4 --- /dev/null +++ b/mod/pub.mod/freeaudio.mod/ossdevice.cpp @@ -0,0 +1,93 @@ +// ossdevice.cpp + +#ifdef __linux + +#include "freeaudio.h" + +#include +#include +#include +#include +#include + +extern "C" audiodevice *OpenOSSDevice(); + +void *ossaudiothread(void*dev); + +#define LINUXFRAG 2048 + +void *ossaudiothread(void *arg); + +struct ossdevice:audiodevice{ + pthread_t audiothread; + int threadid; + int running,playing; + short *buffer; + int buffersize; //in bytes + int fragsize,fragcount; + int fd,data,res; + + int reset(){ + running=0; + playing=0; + + fd=open("/dev/dsp",O_WRONLY,0); + if (fd==-1) return -1; + + mix=new mixer(LINUXFRAG); + mix->freq=44100; + mix->channels=2; + buffer=new short[LINUXFRAG]; + buffersize=LINUXFRAG*2; + pthread_attr_t attr; + pthread_attr_init(&attr); + + running=1; + threadid=pthread_create(&audiothread,&attr,ossaudiothread,(void*)this); + return 0; + } + + int close(){ + int timeout; + running=0; + timeout=500; + while (timeout-- && playing) usleep( 10*1000 ); + ::close(fd); + return 0; + } + + void run(){ + // printf("linuxaudio started\n"); + data=0x03000c; //2 fragments of 4096 samples + res=ioctl(fd,SNDCTL_DSP_SETFRAGMENT,&data); + // printf("res=%d\n",res); + data=AFMT_S16_LE; + res=ioctl(fd,SNDCTL_DSP_SETFMT,&data); + // printf("res=%d\n",res); + data=2; + res=ioctl(fd,SNDCTL_DSP_CHANNELS,&data); + // printf("res=%d\n",res); + data=44100; + res=ioctl(fd,SNDCTL_DSP_SPEED,&data); + playing=1; + while (playing && running){ + mix->mix16(buffer); + int n=write(fd,buffer,buffersize); + } + playing=0; + } + +}; + +void *ossaudiothread(void *arg){ + ossdevice*audio=(ossdevice*)arg; + audio->run(); + return 0; +} + +audiodevice *OpenOSSDevice(){ + return new ossdevice(); +} + +#endif + diff --git a/mod/pub.mod/freejoy.mod/doc/intro.bbdoc b/mod/pub.mod/freejoy.mod/doc/intro.bbdoc new file mode 100644 index 0000000..07f16c6 --- /dev/null +++ b/mod/pub.mod/freejoy.mod/doc/intro.bbdoc @@ -0,0 +1,3 @@ +The BlitzMax freejoy module contains commands that report +the status of any joysticks and game controllers connected +to the system. diff --git a/mod/pub.mod/freejoy.mod/doc/joycount.bmx b/mod/pub.mod/freejoy.mod/doc/joycount.bmx new file mode 100644 index 0000000..a3a97aa --- /dev/null +++ b/mod/pub.mod/freejoy.mod/doc/joycount.bmx @@ -0,0 +1,56 @@ +' testjoy.bmx + +Import Pub.FreeJoy + +Strict + +If Not JoyCount() RuntimeError "No joystick found!" + +Graphics 640,480 + +Function drawprop(n$,p#,y) + Local w + DrawText n$,0,y + w=Abs(p)*256 + If p<0 + DrawRect 320-w,y,w,16 + Else + DrawRect 320,y,w,16 + EndIf +End Function + +Local t=0 + +While Not KeyHit(KEY_ESCAPE) + Cls + + SetColor 255,255,255 + Local n=JoyCount() + DrawText "joycount="+n,0,0 + DrawText "JoyName(0)="+JoyName(0),0,20 + DrawText "JoyButtonCaps(0)="+Bin$(JoyButtonCaps(0)),0,40 + DrawText "JoyAxisCaps(0)="+Bin$(JoyAxisCaps(0)),0,60 + + For Local i=0 To 31 + SetColor 255,255,255 + If JoyDown(i) SetColor 255,0,0 + DrawOval i*16,80,14,14 + Next + + SetColor 255,255,0 + drawprop "JoyX=",JoyX(0),100 + drawprop "JoyY:",JoyY(0),120 + drawprop "JoyZ:",JoyZ(0),140 + drawprop "JoyR:",JoyR(0),160 + drawprop "JoyU:",JoyU(0),180 + drawprop "JoyV:",JoyV(0),200 + drawprop "JoyHat:",JoyHat(0),220 + drawprop "JoyWheel:",JoyWheel(0),240 + + DrawRect 0,280,t,10 + t=(t+1)&511 + + Flip +Wend + +End diff --git a/mod/pub.mod/freejoy.mod/freejoy.bmx b/mod/pub.mod/freejoy.mod/freejoy.bmx new file mode 100644 index 0000000..8128b5c --- /dev/null +++ b/mod/pub.mod/freejoy.mod/freejoy.bmx @@ -0,0 +1,294 @@ + +Rem +bbdoc: User input/Joystick +End Rem +Module Pub.FreeJoy + +ModuleInfo "Version: 1.08" +ModuleInfo "Author: Simon Armstrong" +ModuleInfo "License: zlib/libpng" +ModuleInfo "Copyright: Blitz Research Ltd" +ModuleInfo "Modserver: BRL" + +ModuleInfo "History: 1.08 Release" +ModuleInfo "History: Added JoyHit samplejoy fix, thanks to HamishTheHystericalHamster" +ModuleInfo "History: 1.07 Release" +ModuleInfo "History: Added MacOSX Rx,Ry,Rz (JoyR,JoyU,JoyV) and Wheel" +ModuleInfo "History: 1.06 Release" +ModuleInfo "History: Enabled Apple Gamepad and MultiAxis HID classes" +ModuleInfo "History: 1.05 Release" +ModuleInfo "History: Fixed Linux C Compiler warnings" +ModuleInfo "History: 1.04 Release" +ModuleInfo "History: Fixed C Compiler warnings" + +?MacOS +Import "freejoy.macosx.c" +Import "-framework IOKit" +?Win32 +Import "freejoy.win32.c" +?Linux +Import "freejoy.linux.c" +? + +Extern + +Rem +bbdoc: Counts the number of joysticks. +returns: The number of joysticks and gamecontrollers connected to the system. +end rem +Function JoyCount() + +Function JoyCName:Byte Ptr(port) + +Rem +bbdoc: Available buttons (on/off controls) on a joystick. +returns: A bitfield representing which buttons are present. +end rem +Function JoyButtonCaps(port) + +Rem +bbdoc: Available axis (proportional controls) on a joystick. +returns: A bitfield representing which axis are available. +about: +The bit positions of the returned value correspond to the following constants defined +in the FreeJoy module: +[ Const JOY_X=0 +* Const JOY_Y=1 +* Const JOY_Z=2 +* Const JOY_R=3 +* Const JOY_U=4 +* Const JOY_V=5 +* Const JOY_YAW=6 +* Const JOY_PITCH=7 +* Const JOY_ROLL=8 +* Const JOY_HAT=9 +* Const JOY_WHEEL=10 +] +End Rem +Function JoyAxisCaps(port) + +Function ReadJoy(port,buttons:Int Ptr,axis:Float Ptr) +Function WriteJoy(port,channel,value#) + +End Extern + +JoyCount 'required to kick starts some drivers + +Const JOY_X=0 +Const JOY_Y=1 +Const JOY_Z=2 +Const JOY_R=3 +Const JOY_U=4 +Const JOY_V=5 +Const JOY_YAW=6 +Const JOY_PITCH=7 +Const JOY_ROLL=8 +Const JOY_HAT=9 +Const JOY_WHEEL=10 + +Rem +bbdoc: Get the name of the joysticks connected to the specified port. +returns: The system name of the joystick. +end rem +Function JoyName$(port) + Return String.FromCString(JoyCName(port)) +End Function + +Global joy_time[16] +Global joy_buttons[16] +Global joy_axis#[16*16] +Global joy_hits[16,16] + +Function SampleJoy(port) + Local t + t=joy_time[port]-MilliSecs() + If t<0 Or t>1 + Local old=joy_buttons[port] + ReadJoy port,Varptr joy_buttons[port],Varptr joy_axis[port*16] + For Local button=0 Until 16'To 16 + Local b=1 Shl button + If Not(old & b) And joy_buttons[port]&b joy_hits[button, port]:+1'button and port were t'other way round. + Next + EndIf +End Function + +Rem +bbdoc: Test the status of a joystick button. +returns: True if the button is pressed. +end rem +Function JoyDown( button,port=0 ) + SampleJoy port + If joy_buttons[port] & (1 Shl button) Return True +End Function + +Rem +bbdoc: Check for a joystick button press +returns: Number of times @button has been hit. +about: +The returned value represents the number of the times @button has been hit since +the last call to #JoyHit with the same specified @button. +End Rem +Function JoyHit( button,port=0 ) + SampleJoy port + Local n=joy_hits[button,port] + joy_hits[button,port]=0 + Return n +End Function + +Rem +bbdoc: Reports the horizontal position of the joystick. +returns: Zero if the joystick is centered, -1 if Left, 1 if Right or a value inbetween. +end rem +Function JoyX#( port=0 ) + SampleJoy port + Return joy_axis[port*16+JOY_X] +End Function + +Rem +bbdoc: Reports the vertical position of the joystick. +returns: Zero if the joystick is centered, -1.0 if Up, 1.0 if Down or a value inbetween. +end rem +Function JoyY#( port=0 ) + SampleJoy port + Return joy_axis[port*16+JOY_Y] +End Function + +Rem +bbdoc: Reports the position of the joystick's Z axis if supported. +returns: Zero if the joystick is centered, -1.0 if Up, 1.0 if Down or a value inbetween. +end rem +Function JoyZ#( port=0 ) + SampleJoy port + Return joy_axis[port*16+JOY_Z] +End Function + +Rem +bbdoc: Reports the position of the joystick's R axis if supported. +returns: Zero if the joystick is centered, -1.0 if Up, 1.0 if Down or a value inbetween. +end rem +Function JoyR#( port=0 ) + SampleJoy port + Return joy_axis[port*16+JOY_R] +End Function + +Rem +bbdoc: Reports the position of the joystick's U axis if supported. +returns: Zero if the joystick is centered, -1.0 if Up, 1.0 if Down or a value inbetween. +about: +The U value of a joystick usually corresponds to a joystick's 'slider' or 'throttle' feature, although this may vary depending on the joystick, and will not be available with all joysticks. +End Rem +Function JoyU#( port=0 ) + SampleJoy port + Return joy_axis[port*16+JOY_U] +End Function + +Rem +bbdoc: Reports the position of the joystick's V axis if supported. +returns: Zero if the joystick is centered, -1.0 if Up, 1.0 if Down or a value inbetween. +about: +The V value of a joystick usually corresponds to a joystick's 'slider' or 'throttle' feature, although this may vary depending on the joystick, and will not be available with all joysticks. +End Rem +Function JoyV#( port=0 ) + SampleJoy port + Return joy_axis[port*16+JOY_V] +End Function + +Rem +bbdoc: Reports the position of the joystick's YAW axis if supported. +returns: Zero if the joystick is centered, -1.0 if Up, 1.0 if Down or a value inbetween. +end rem +Function JoyYaw#( port=0 ) + SampleJoy port + Return joy_axis[port*16+JOY_YAW] +End Function + +Rem +bbdoc: Reports the position of the joystick's PITCH axis if supported. +returns: Zero if the joystick is centered, -1.0 if Up, 1.0 if Down or a value inbetween. +end rem +Function JoyPitch#( port=0 ) + SampleJoy port + Return joy_axis[port*16+JOY_PITCH] +End Function + +Rem +bbdoc: Reports the position of the joystick's ROLL axis if supported. +returns: Zero if the joystick is centered, -1.0 if Up, 1.0 if Down or a value inbetween. +end rem +Function JoyRoll#( port=0 ) + SampleJoy port + Return joy_axis[port*16+JOY_ROLL] +End Function + +Rem +bbdoc: Reports the position of the joystick's HAT controller if supported. +returns: -1.0 if the joystick is centered, and values between 0.0, 0.25, 0.5 and 0.75 for the directions Up, Right, Down, Left respectively. +End Rem +Function JoyHat#( port=0 ) + SampleJoy port + Return joy_axis[port*16+JOY_HAT] +End Function + +Rem +bbdoc: Reports the position of the joystick's WHEEL controller if supported. +returns: Zero if the joystick is centered, -1.0 if Left, 1.0 if Right or a value inbetween. +End Rem +Function JoyWheel#( port=0 ) + SampleJoy port + Return joy_axis[port*16+JOY_WHEEL] +End Function + +Function JoyType( port=0 ) + If port.333333 Return 1 + Return 0 +End Function + +Function JoyYDir( port=0 ) + Local t#=JoyY( port ) + If t<.333333 Return -1 + If t>.333333 Return 1 + Return 0 +End Function + +Function JoyZDir( port=0 ) + Local t#=JoyZ( port ) + If t<.333333 Return -1 + If t>.333333 Return 1 + Return 0 +End Function + +Function JoyUDir( port=0 ) + Local t#=JoyU( port ) + If t<.333333 Return -1 + If t>.333333 Return 1 + Return 0 +End Function + +Function JoyVDir( port=0 ) + Local t#=JoyV( port ) + If t<.333333 Return -1 + If t>.333333 Return 1 + Return 0 +End Function + +Rem +bbdoc: Flush joystick button states. +End Rem +Function FlushJoy( port_mask=~0 ) + For Local i=0 Until JoyCount() + If i & port_mask + SampleJoy i + joy_buttons[i]=0 + For Local j=0 Until 16 + joy_hits[i,j]=0 + Next + EndIf + Next +End Function diff --git a/mod/pub.mod/freejoy.mod/freejoy.h b/mod/pub.mod/freejoy.mod/freejoy.h new file mode 100644 index 0000000..d4fee07 --- /dev/null +++ b/mod/pub.mod/freejoy.mod/freejoy.h @@ -0,0 +1,15 @@ +// freejoy.h + +#ifndef freejoy_h +#define freejoy_h + +enum axisbits {JOYX,JOYY,JOYZ,JOYR,JOYU,JOYV,JOYYAW,JOYPITCH,JOYROLL,JOYHAT,JOYWHEEL}; + +int JoyCount(); +char *JoyCName(int port); +int JoyButtonCaps(int port); +int JoyAxisCaps(int port); +int ReadJoy(int port,int *buttons,float *axis); +void WriteJoy(int port,int channel,float value); + +#endif diff --git a/mod/pub.mod/freejoy.mod/freejoy.linux.c b/mod/pub.mod/freejoy.mod/freejoy.linux.c new file mode 100644 index 0000000..c4449d2 --- /dev/null +++ b/mod/pub.mod/freejoy.mod/freejoy.linux.c @@ -0,0 +1,160 @@ +// freejoy.linux.c + +#include "freejoy.h" + +#include +#include +#include +#include +#include +#include + +struct linuxjoy +{ + pthread_t thread; + int threadid; + int open,fd,fp; + char name[256]; + int buttoncount,axiscount; + int button; + float axis[16]; +}; + +typedef struct linuxjoy linuxjoy; +typedef struct js_event js_event; +typedef struct sched_param sched_param; + +void *joythread(void *v) +{ + linuxjoy *j; + js_event js; + int n,b; + + int policy; + sched_param sched; + + pthread_getschedparam(pthread_self(),&policy,&sched); + sched.sched_priority++; + policy=SCHED_RR; + pthread_setschedparam(pthread_self(),policy,&sched); + + j=(linuxjoy*)v; + + while (j->open) + { + b=sizeof(struct js_event)-j->fp; + n=read(j->fd,&js,b); + if (n<=0) break; + if (nfp+=b;continue;} + j->fp=0; + switch (js.type & ~JS_EVENT_INIT) + { + case JS_EVENT_AXIS: + n=js.number; + if (n>=0 && n<16) j->axis[n]=js.value/32767.0; + break; + case JS_EVENT_BUTTON: + n=1<button|=n;else j->button&=~n; + break; + } + } + close(j->fd); + j->fd=0; + return 0; +} + +linuxjoy *getjoy(int n) +{ + linuxjoy *j; + char fname[16]; + int fd; + + sprintf(fname,"/dev/js%d",n); + fd=open(fname,O_RDONLY); + if (fd==-1) return 0; + j=(linuxjoy*)calloc(1,sizeof(struct linuxjoy)); + j->fd=fd; + ioctl(fd,JSIOCGNAME(256),&j->name); + ioctl(fd,JSIOCGAXES,&j->axiscount); + ioctl(fd,JSIOCGBUTTONS,&j->buttoncount); +// fcntl(fd,F_SETFL,O_NONBLOCK); + j->open=1; + pthread_attr_t attr; + pthread_attr_init(&attr); +// pthread_attr_setschedpolicy(&attr,SCHED_RR); +// pthread_attr_getschedparam(&attr); +// printf("mypid=%x\n",getpid()); +// pthread_attr_setschedparam(&attr,1); + j->threadid=pthread_create(&j->thread,&attr,joythread,(void*)j); + + return j; +} + +void updatejoy(linuxjoy *j,int *buttons,float *axis) +{ + *buttons=j->button; + memcpy(axis,j->axis,16*4); +} + +void freejoy(struct linuxjoy *j) +{ + int timeout=5; + j->open=0; + while (timeout-- && j->fd) sleep(1); +// close(j->fd); +} + +// standard freejoy interface + +int ljoyopen; +int ljoycount; +linuxjoy *ljoys[8]; + +int JoyCount() +{ + linuxjoy *j; + int i,n; + + if (!ljoyopen) + { + n=0; + for (i=0;i<8;i++) + { + j=getjoy(i); + if (j) ljoys[n++]=j; + } + ljoycount=n; + ljoyopen=1; + } + return ljoycount; +} + +char *JoyCName(int port) +{ + if (port>=0 && portname; + return 0; +} + +int JoyButtonCaps(int port) +{ + if (port>=0 && portbuttoncount)-1; + return 0; +} + +int JoyAxisCaps(int port) +{ + if (port>=0 && portaxiscount)-1; + return 0; +} + +int ReadJoy(int port,int *buttons,float *axis) +{ + if (port<0 || port>=ljoycount) return 0; + updatejoy (ljoys[port],buttons,axis); + return 1; +} + +void WriteJoy(int port,int channel,float value) +{ +} diff --git a/mod/pub.mod/freejoy.mod/freejoy.macosx.c b/mod/pub.mod/freejoy.mod/freejoy.macosx.c new file mode 100644 index 0000000..1a75cba --- /dev/null +++ b/mod/pub.mod/freejoy.mod/freejoy.macosx.c @@ -0,0 +1,348 @@ +// freejoy.macosx.c + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include + +#include "freejoy.h" + +mach_port_t masterPort; + +IOHIDDeviceInterface **OpenDevice(io_object_t device) +{ + IOHIDDeviceInterface **handle; + IOCFPlugInInterface **plug; + SInt32 score; + io_name_t class; + IOReturn iores; + HRESULT res; + + iores=IOObjectGetClass(device,class); + if (iores) printf("Failed to get class name"); + iores=IOCreatePlugInInterfaceForService(device,kIOHIDDeviceUserClientTypeID,kIOCFPlugInInterfaceID,&plug,&score); + if (iores!=kIOReturnSuccess) printf("IOCreatePlugInInterfaceForService failed"); + res=(*plug)->QueryInterface(plug,CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID),(void *)&handle); + if (res!= S_OK) printf("Couldn't query HID class device interface from plugInInterface\n"); + res=(*handle)->open(handle,0); + if (res!= S_OK) printf("Couldn't open HID device\n"); + (*plug)->Release(plug); + return handle; +} + +struct macjoy +{ + struct macjoy *link; + IOHIDDeviceInterface **device; + IOHIDElementCookie button[32]; + IOHIDElementCookie axis[16]; + long axismax[16],axismin[16]; + int bcaps,acaps; + char name[256]; +}; + +void freemacjoy(struct macjoy *j) +{ + int res; + res=IOObjectRelease( (int)j->device); +} + +void readmacjoy(struct macjoy *j,int *buttons,float *axis) +{ + IOHIDEventStruct event; + IOHIDElementCookie cookie; + int i,res,b; + + b=0; + for (i=0;i<32;i++) + { + if (cookie=j->button[i]) + { + res=(*j->device)->getElementValue(j->device,cookie,&event); + if (event.value) b|=1<axis[i]) + { + res=(*j->device)->getElementValue(j->device,cookie,&event); + if (i==JOYHAT) + { + axis[i]=event.value/8.0; + if (axis[i]==1.0) axis[i]=-1.0; + } + else + { +// axis[i]=(event.value-128)/128.0; + axis[i]=event.value; +// if (j->axismax[i]) axis[i]/=j->axismax[i]; //32768.0; + if (j->axismax[i]) { + axis[i]=(((axis[i]-j->axismin[i])/j->axismax[i])-0.5)*2.0; //32768.0; + } + } + } + } +}; + +void macjoyelement(struct macjoy *j,CFDictionaryRef element) +{ + IOHIDElementCookie cookie; + CFTypeRef object; + long number,usage,page,axismax,axismin; + int axis; + + object = CFDictionaryGetValue (element, CFSTR(kIOHIDElementCookieKey)); + if (object == 0 || CFGetTypeID (object) != CFNumberGetTypeID ()) return; + if(!CFNumberGetValue ((CFNumberRef) object, kCFNumberLongType, &number)) return; + cookie = (IOHIDElementCookie) number; + + object = CFDictionaryGetValue (element, CFSTR(kIOHIDElementUsageKey)); + if (object == 0 || CFGetTypeID (object) != CFNumberGetTypeID ()) return; + if (!CFNumberGetValue ((CFNumberRef) object, kCFNumberLongType, &number)) return; + usage = number; + + axismax=0;axismin=0; + object=CFDictionaryGetValue(element,CFSTR(kIOHIDElementMaxKey)); + if (object && CFNumberGetValue(object, kCFNumberLongType, &number)){ + axismax=number; +// printf("max=%d\n",number);fflush(stdout); + } + object=CFDictionaryGetValue(element,CFSTR(kIOHIDElementMinKey)); + if (object && CFNumberGetValue(object, kCFNumberLongType, &number)){ + axismin=number; +// printf("min=%d\n",number);fflush(stdout); + } + + object = CFDictionaryGetValue (element,CFSTR(kIOHIDElementUsagePageKey)); + if (object == 0 || CFGetTypeID (object) != CFNumberGetTypeID ()) return; + if (!CFNumberGetValue ((CFNumberRef) object, kCFNumberLongType, &number)) return; + page = number; + + switch (page) + { + case kHIDPage_GenericDesktop: +// printf("page=kHIDPage_GenericDesktop usage=%d cookie=%d\n",usage,cookie); + axis=-1; + switch (usage) + { + case kHIDUsage_GD_X: + axis=JOYX; + break; + case kHIDUsage_GD_Y: + axis=JOYY; + break; + case kHIDUsage_GD_Z: + axis=JOYZ; + break; + case kHIDUsage_GD_Rz: + axis=JOYR; + break; + case kHIDUsage_GD_Ry: + axis=JOYU; + break; + case kHIDUsage_GD_Rx: + axis=JOYV; + break; + case kHIDUsage_GD_Slider: + axis=JOYYAW; + break; + case kHIDUsage_GD_Hatswitch: + axis=JOYHAT; + break; + case kHIDUsage_GD_Wheel: + axis=JOYWHEEL; + break; + } + if (axis!=-1){ + j->axis[axis]=cookie; + j->axismax[axis]=axismax-axismin; + j->axismin[axis]=axismin; + } + break; + case kHIDPage_Button: +// printf("page=kHIDPage_Button usage=%d cookie=%d\n",usage,cookie); + if (usage>0 && usage<=32) + { + usage--; + if (!j->button[usage]) j->button[usage]=cookie; + } + break; + } +} + +void enumprops(CFTypeRef object,struct macjoy *j) +{ + CFTypeID type; + const void **keys,**vals,*obj; + CFTypeRef key,val; + int n,k; + const char *c; + + if (!object) return; + + type=CFGetTypeID(object); + + if (type==CFArrayGetTypeID()) + { +// printf( "array!\n" ); + n=CFArrayGetCount( object ); + for( k=0;k\n"); + } + } + free( vals ); + free( keys ); + return; + } +} + + +int macjoycount=0; +struct macjoy *joylist[16]; + +void enumhid(UInt32 page,UInt32 usage) +{ + CFMutableDictionaryRef dic,props; + CFNumberRef rpage,rusage; + CFTypeRef element; + IOHIDDeviceInterface **device; + io_iterator_t it; + io_object_t obj; + IOReturn res; + struct macjoy *joy; + int i,m; + + dic=IOServiceMatching(kIOHIDDeviceKey); + if (dic==0) {printf("No dictionary returned by IOServiceMatching");return;} + rpage=CFNumberCreate(kCFAllocatorDefault,kCFNumberIntType,&page); + rusage=CFNumberCreate(kCFAllocatorDefault,kCFNumberIntType,&usage); + CFDictionarySetValue(dic,CFSTR(kIOHIDPrimaryUsagePageKey),rpage); + CFDictionarySetValue(dic,CFSTR(kIOHIDPrimaryUsageKey),rusage); + res=IOServiceGetMatchingServices(masterPort,dic,&it); + if (res!=kIOReturnSuccess) {printf("IOServiceGetMatchingServices failed");return;} + + while (obj=IOIteratorNext(it)) + { + device=OpenDevice(obj); + if (device) + { +// printf("Got HID Device Handle\n"); + joy=calloc(1,sizeof (struct macjoy)); + joy->device=device; + + res=IORegistryEntryCreateCFProperties(obj,&props,kCFAllocatorDefault,kNilOptions); + if (res!=kIOReturnSuccess) {printf("IORegistryEntryCreateCFProperties failed");return;} + +// MyShowObject(props); + enumprops(props,joy); + + m=0;for (i=0;i<32;i++) {if (joy->button[i]) m|=1<bcaps=m; + + m=0;for (i=0;i<16;i++) {if (joy->axis[i]) m|=1<acaps=m; + + if (macjoycount<16) joylist[macjoycount++]=joy; + } + } + IOObjectRelease(it); +} + +int InitMacJoy() +{ + io_iterator_t it; + IOReturn res; + +// printf("enumerating hid devices\n"); + + macjoycount=0; + + res=IOMasterPort (bootstrap_port, &masterPort); + if (res) printf("IOMasterPort failed\n"); + + enumhid(kHIDPage_GenericDesktop,kHIDUsage_GD_Joystick); + enumhid(kHIDPage_GenericDesktop,kHIDUsage_GD_GamePad); + enumhid(kHIDPage_GenericDesktop,kHIDUsage_GD_MultiAxisController); + +// if (masterPort) mach_port_deallocate(mach_task_self(),masterPort); +} + +int JoyCount() +{ + if( !macjoycount ) InitMacJoy(); + return macjoycount; +} + +char *JoyCName(int port) +{ + return "MacOSX Joystick"; +} + +int JoyButtonCaps(int port) +{ + if (port>=0 && portbcaps; + return 0; +} + +int JoyAxisCaps(int port) +{ + if (port>=0 && portacaps; + return 0; +} + +int ReadJoy(int port,int *buttons,float *axis) +{ + if (port>=0 && port +#include +#include "freejoy.h" + +int joyhandle[256]; + +int JoyCount() +{ + JOYINFO j; + int n,i,t,res; + + n=joyGetNumDevs(); + t=0; + for (i=0;i36000) axis[JOYHAT]=-1.0;else axis[JOYHAT]=pov/36000.0; + } + return 1; +} + +void WriteJoy(int port,int channel,float value) +{ + port=joyhandle[port]; +} diff --git a/mod/pub.mod/freeprocess.mod/freeprocess.bmx b/mod/pub.mod/freeprocess.mod/freeprocess.bmx new file mode 100644 index 0000000..2eb4c99 --- /dev/null +++ b/mod/pub.mod/freeprocess.mod/freeprocess.bmx @@ -0,0 +1,205 @@ + +Module PUB.FreeProcess + +ModuleInfo "Version: 1.03" +ModuleInfo "Framework: FreeProcess multi platform external process control" +ModuleInfo "License: zlib/libpng" +ModuleInfo "Copyright: Blitz Research Ltd" +ModuleInfo "Author: Simon Armstrong" +ModuleInfo "Modserver: BRL" + +ModuleInfo "History: 1.03 Release" +ModuleInfo "History: Changed fork() to vfork() and exit() to _exit() to fix more hangs." +ModuleInfo "History: 1.02 Release" +ModuleInfo "History: Fixed a Linux hang when fork() is called." +ModuleInfo "History: Added SIGCHLD handling and fdReapZombies function." +ModuleInfo "History: 1.01 Release" +ModuleInfo "History: Inserts /Contents/MacOS/ into process path for Apple app packages" + +Strict + +' createproc - to launch external executable +' TPipeStream - nonblocking readlines with fd file handles + +Import brl.stream +Import brl.linkedlist +Import brl.filesystem + +Import "freeprocess.c" + +'note: Once fdProcessStatus() returns 0 OR fdTerminateProcess() is called, +'processhandle should be assumed to be invalid, and neither function should be called +'again. +Extern +Function fdClose(fd) +Function fdRead(fd,buffer:Byte Ptr,count) +Function fdWrite(fd,buffer:Byte Ptr,count) +Function fdFlush(fd) +Function fdAvail(fd) +Function fdProcess(exe$,in_fd Ptr,out_fd Ptr,err_fd Ptr,flags)="fdProcess" +Function fdProcessStatus(processhandle) +Function fdTerminateProcess(processhandle) +End Extern + +Const HIDECONSOLE=1 + +Type TPipeStream Extends TStream + + Field readbuffer:Byte[4096] + Field bufferpos + Field readhandle,writehandle + + Method Close() + If readhandle + fdClose(readhandle) + readhandle=0 + EndIf + If writehandle + fdClose(writehandle) + writehandle=0 + EndIf + End Method + + Method Read( buf:Byte Ptr,count ) + Return fdRead(readhandle,buf,count) + End Method + + Method Write( buf:Byte Ptr,count ) + Return fdWrite(writehandle,buf,count) + End Method + + Method Flush() + fdFlush(writehandle) + End Method + + Method ReadAvail() + Return fdAvail(readhandle) + End Method + + Method ReadPipe:Byte[]() + Local bytes:Byte[],n + n=ReadAvail() + If n + bytes=New Byte[n] + Read(bytes,n) + Return bytes + EndIf + End Method + + Method ReadLine$() 'nonblocking - returns empty string if no data available + Local n,r,p0,p1,line$ + n=ReadAvail() + If n + If bufferpos+n>4096 n=4096-bufferpos + If n<=0 RuntimeError "PipeStream ReadBuffer Overflow" + r=Read(Varptr readbuffer[bufferpos],n) + bufferpos:+r + EndIf + For n=0 To bufferpos + If readbuffer[n]=10 + p1=n + If (n>0) + If readbuffer[n-1]=13 p1=n-1 + EndIf + p0=0 + If readbuffer[0]=13 p0=1 + If p1>p0 line$=String.FromBytes(Varptr readbuffer[p0],p1-p0) + n:+1 + bufferpos:-n + If bufferpos MemMove(readbuffer,Varptr readbuffer[n],bufferpos) + Return line$ + EndIf + Next + End Method + + Function Create:TPipeStream( in,out ) + Local stream:TPipeStream=New TPipeStream + stream.readhandle=in + stream.writehandle=out + Return stream + End Function + +End Type + +Type TProcess + Global ProcessList:TList + Field name$ + Field handle + Field pipe:TPipeStream + Field err:TPipeStream + + Method Status() + If handle + If fdProcessStatus(handle) Return 1 + handle=0 + EndIf + Return 0 + End Method + + Method Close() + If pipe pipe.Close;pipe=Null + If err err.Close;err=Null + End Method + + Method Terminate() + Local res + If handle + res=fdTerminateProcess( handle ) + handle=0 + EndIf + Return res + End Method + + Function Create:TProcess(name$,flags) + Local p:TProcess + Local infd,outfd,errfd +?MacOS + If FileType(name)=2 + Local a$=StripExt(StripDir(name)) + name:+"/Contents/MacOS/"+a$ + EndIf +? + FlushZombies + p=New TProcess + p.name=name + p.handle=fdProcess(p.name,Varptr infd,Varptr outfd,Varptr errfd,flags) + If Not p.handle Return Null + p.pipe=TPipeStream.Create(infd,outfd) + p.err=TPipeStream.Create(errfd,0) + If Not ProcessList ProcessList=New TList + ProcessList.AddLast p + Return p + End Function + + Function FlushZombies() + If Not ProcessList Return + Local live:TList=New TList + For Local p:TProcess=EachIn ProcessList + If p.Status() live.AddLast p + Next + ProcessList=live + End Function + + Function TerminateAll() NoDebug + If Not ProcessList Return + For Local p:TProcess=EachIn ProcessList + p.Terminate + Next + ProcessList=Null + End Function + +End Type + +Function CreateProcess:TProcess(cmd$,flags=0) + Return TProcess.Create(cmd,flags) +End Function + +Function ProcessStatus(process:TProcess) + Return process.Status() +End Function + +Function TerminateProcess(process:TProcess) + Return process.Terminate() +End Function + +OnEnd TProcess.TerminateAll \ No newline at end of file diff --git a/mod/pub.mod/freeprocess.mod/freeprocess.c b/mod/pub.mod/freeprocess.mod/freeprocess.c new file mode 100644 index 0000000..d8bf18b --- /dev/null +++ b/mod/pub.mod/freeprocess.mod/freeprocess.c @@ -0,0 +1,346 @@ +// freeprocess.c + +#include + +#include + +#define HIDECONSOLE 1 + +#if __APPLE__ || __linux + +#include +#include +#include + +int fdClose(int fd) {return close(fd);} +int fdRead(int fd,char *buffer,int count) {return read(fd,buffer,count);} +int fdWrite(int fd,char *buffer,int count) {return write(fd,buffer,count);} +int fdAvail(int fd) {int avail;if (ioctl(fd,FIONREAD,&avail)) avail=avail;return avail;} +int fdFlush(int fd) {}//flush(fd);} + +///return 1 for running, 0 for finished +// +int fdProcessStatus( int pid ){ + + int status=0; + return !waitpid( pid,&status,WNOHANG ); +} + +//returns 0 for success, -1 for error +// +int fdTerminateProcess(int pid){ + + if( !killpg( pid,SIGTERM ) ){ + int status=0; + waitpid( pid,&status,0 ); + return 0; + } + return -1; +} + +static char **makeargv( const char *cmd ){ + int n,c; + char *p; + static char *args,**argv; + + if( args ) free( args ); + if( argv ) free( argv ); + args=(char*)malloc( strlen(cmd)+1 ); + strcpy( args,cmd ); + + n=0; + p=args; + while( c=*p++ ){ + if( c==' ' ){ + continue; + }else if( c=='\"' ){ + while( *p && *p!='\"' ) ++p; + }else{ + while( *p && *p!=' ' ) ++p; + } + if( *p ) ++p; + ++n; + } + argv=(char**)malloc( (n+1)*sizeof(char*) ); + n=0; + p=args; + while( c=*p++ ){ + if( c==' ' ){ + continue; + }else if( c=='\"' ){ + argv[n]=p; + while( *p && *p!='\"' ) ++p; + }else{ + argv[n]=p-1; + while( *p && *p!=' ' ) ++p; + } + if( *p ) *p++=0; + ++n; + } + argv[n]=0; + return argv; +} + +#define PIPEREAD 0 +#define PIPEWRITE 1 + +static int in[2],out[2],errfd[2]; + +int fdProcess( BBString *bbcmd,int *procin,int *procout,int *procerr,int flags) +{ + char *const*argv; + int procid; + + const char *cmd=bbTmpUTF8String(bbcmd); + + //Set-up interprocess communication + if (pipe(in)) return 0; + if (pipe(out)) return 0; + if (pipe(errfd)) return 0; + + //Fork process (returned value used to distinguish between child and parent process) + procid=vfork(); //vfork() avoids memory overhead of fork() + + //Child process + if (procid==0) + { + #if __linux + setsid(); //Linux doesn't mind setsid() + #else + setpgid(0,0); //but OS X doesn't like it, therefore resort to using setpgid(). + #endif + + dup2(out[PIPEREAD],STDIN_FILENO); + close(out[PIPEWRITE]); + + dup2(in[PIPEWRITE],STDOUT_FILENO); + close(in[PIPEREAD]); + + dup2(errfd[PIPEWRITE],STDERR_FILENO); + close(errfd[PIPEREAD]); + + argv=makeargv(cmd); + execvp(argv[0],argv); + + _exit( -1 ); + + return 0; //Supposedly, we need this for some compilers. + + } + + //Parent process + + if(procid==-1) return 0; //Return if child process couldn't be started. + + close(out[PIPEREAD]); //Close the end of the pipes in that the child + close(in[PIPEWRITE]); //process is using. + close(errfd[PIPEWRITE]); + + *procin=in[PIPEREAD]; //And return the end of the pipes that we should + *procout=out[PIPEWRITE]; //be using. + *procerr=errfd[PIPEREAD]; + + return procid; +} + +#endif + +#ifdef _WIN32 + +extern int _bbusew; + +#define WIN32_LEAN_AND_MEAN +#include +#include + +int TerminateProcessGroup(HANDLE prochandle,int procid) +{ + HANDLE snapshot,child; + PROCESSENTRY32 procinfo; + int gotinfo,res; + + snapshot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); + if (snapshot!=INVALID_HANDLE_VALUE) + { + procinfo.dwSize=sizeof(procinfo); + gotinfo=Process32First(snapshot,&procinfo); + while (gotinfo) + { + if (procinfo.th32ParentProcessID==procid) + { +// printf("process=%x parent=%x module=%x path=%s\n",procinfo.th32ProcessID,procinfo.th32ParentProcessID,procinfo.th32ModuleID,procinfo.szExeFile); + child=OpenProcess(PROCESS_ALL_ACCESS,0,procinfo.th32ProcessID); + if (child) + { + res=TerminateProcess(child,-1); + CloseHandle(child); + } + } + gotinfo=Process32Next(snapshot,&procinfo); + } + CloseHandle(snapshot); + } + res=TerminateProcess(prochandle,-1); + return res; +} + +int fdClose(int fd) +{ + return CloseHandle((HANDLE)fd); +} + +int fdRead(int fd,char *buffer,int bytes) +{ + int res; + long count; + res=ReadFile((HANDLE)fd,buffer,bytes,&count,0); + if (res) return count; + return 0; +} + +int fdWrite(int fd,char *buffer,int bytes) +{ + int res; + long count; + res=WriteFile((HANDLE)fd,buffer,bytes,&count,0); + if (res) return count; + return 0; +} + +int fdFlush(int fd) +{ + int res; + res=FlushFileBuffers((HANDLE)fd); + return res; +} + +int fdAvail(int fd) +{ + int res; + long avail; + res=PeekNamedPipe((HANDLE)fd,0,0,0,&avail,0); + if (res) return avail; + return 0; +} + +//returns 1 for running, 0 for finished +int fdProcessStatus( int pid ){ + + PROCESS_INFORMATION *pi=(PROCESS_INFORMATION *)pid; + + long exitcode; + + if( GetExitCodeProcess( pi->hProcess,&exitcode ) ){ + + if( exitcode==STILL_ACTIVE ) return 1; + + CloseHandle( pi->hProcess ); + free( pi ); + } + return 0; +} + +//returns 0 for success +int fdTerminateProcess( int pid ){ + + PROCESS_INFORMATION *pi=(PROCESS_INFORMATION *)pid; + + int res=TerminateProcessGroup( pi->hProcess,pi->dwProcessId ); + + CloseHandle( pi->hProcess ); + free( pi ); + + return res; +} + +int fdProcess( BBString *cmd,int *procin,int *procout,int *procerr,int flags) +{ + int res; + int pflags=CREATE_NEW_PROCESS_GROUP; + PROCESS_INFORMATION *pi; + SECURITY_ATTRIBUTES sa={sizeof(sa),0,1}; + HANDLE istr,p_ostr; //our in-stream, process out-stream + HANDLE ostr,p_istr; //our out-stream, process in-stream + HANDLE estr,p_estr; //our errin-stream, process errout-stream + + if( !CreatePipe( &istr,&p_ostr,&sa,0 ) ){ + //unable to create pipe + return 0; + } + + if( !CreatePipe( &p_istr,&ostr,&sa,0 ) ){ + CloseHandle( istr ); + CloseHandle( p_ostr ); + //ditto + return 0; + } + + if (!CreatePipe(&estr,&p_estr,&sa,0)) { + CloseHandle( istr ); + CloseHandle( p_ostr ); + CloseHandle( ostr ); + CloseHandle( p_istr ); + //unable to create pipe + return 0; + } + + pi=(PROCESS_INFORMATION*)calloc(1,sizeof(PROCESS_INFORMATION)); + + if( _bbusew ){ + STARTUPINFOW si={sizeof(si)}; + + si.dwFlags=STARTF_USESTDHANDLES; + si.wShowWindow=SW_HIDE; + si.hStdInput=p_istr; + si.hStdOutput=p_ostr; + si.hStdError=p_estr; + if (flags&HIDECONSOLE) { + si.dwFlags|=STARTF_USESHOWWINDOW; + si.wShowWindow=SW_HIDE; + } + else { + pflags|=DETACHED_PROCESS; + } + res=CreateProcessW( 0,bbTmpWString(cmd),0,0,-1,pflags,0,0,&si,pi ); + }else{ + STARTUPINFO si={sizeof(si)}; + + si.dwFlags=STARTF_USESTDHANDLES; + si.wShowWindow=SW_HIDE; + si.hStdInput=p_istr; + si.hStdOutput=p_ostr; + si.hStdError=p_estr; + if (flags&HIDECONSOLE) { + si.dwFlags|=STARTF_USESHOWWINDOW; + si.wShowWindow=SW_HIDE; + } + else { + pflags|=DETACHED_PROCESS; + } + res=CreateProcess( 0,bbTmpCString(cmd),0,0,-1,pflags,0,0,&si,pi ); + } + + if( !res ){ + CloseHandle( istr ); + CloseHandle( ostr ); + CloseHandle( estr ); + CloseHandle( p_istr ); + CloseHandle( p_ostr ); + CloseHandle( p_estr ); + return 0; + } + + CloseHandle( pi->hThread ); + + *procin=(int)istr; + *procout=(int)ostr; + *procerr=(int)estr; + + CloseHandle( p_istr ); + CloseHandle( p_ostr ); + CloseHandle( p_estr ); + + return (int)pi; +} + +#endif diff --git a/mod/pub.mod/freetype.mod/freetype.bmx b/mod/pub.mod/freetype.mod/freetype.bmx new file mode 100644 index 0000000..c0f0a46 --- /dev/null +++ b/mod/pub.mod/freetype.mod/freetype.bmx @@ -0,0 +1,184 @@ + +Strict + +Module Pub.FreeType + +ModuleInfo "Version: 1.08" +ModuleInfo "License: FreeType License" +ModuleInfo "Modserver: BRL" + +ModuleInfo "History: 1.08 Release" +ModuleInfo "History: Updated to FreeType 2.3.11" +ModuleInfo "History: 1.07 Release" +ModuleInfo "History: Linux version now uses installed freetype" +ModuleInfo "History: 1.06 Release" +ModuleInfo "History: Fixed too large fonts crashing" +ModuleInfo "History: Updated to latest FreeType lib version" +ModuleInfo "History: 1.05 Release" +ModuleInfo "History: Fixed Tiger build warnings in ftmac.c" +ModuleInfo "History: 1.04 Release" +ModuleInfo "History: Added stream hooks (new code in 'ftsystem.c')" + +Rem + +Changes to freetype source: + +ftoption.h : Enabled FT_CONFIG_OPTION_SYSTEM_ZLIB define +ftoption.h : FT_RENDER_POOL_SIZE changed to 65536L, was 16384. This appears to be the cause of the 'big font' crashes + +End Rem + +?Linux + +ModuleInfo "CC_OPTS: `freetype-config --cflags`" + +Import "-lfreetype" + +?Not Linux + +Import Pub.ZLib + +Rem +bbox bdf bitmap debug gasp +glyph gxval init lcdfil mm +otval pfr stroke synth system +type1 winfnt xf86 patent +End Rem + +ModuleInfo "CC_OPTS: -DFT2_BUILD_LIBRARY" + +Import "include/*.h" + +Import "src/base/ftbase.c" + +Import "src/base/ftapi.c" +Import "src/base/ftbbox.c" +Import "src/base/ftbdf.c" +Import "src/base/ftbitmap.c" +Import "src/base/ftdebug.c" +Import "src/base/ftgasp.c" +Import "src/base/ftglyph.c" +Import "src/base/ftgxval.c" +Import "src/base/ftinit.c" +Import "src/base/ftlcdfil.c" +Import "src/base/ftmm.c" +Import "src/base/ftotval.c" +Import "src/base/ftpfr.c" +Import "src/base/ftstroke.c" +Import "src/base/ftsynth.c" +Import "src/base/ftsystem.c" +Import "src/base/fttype1.c" +Import "src/base/ftwinfnt.c" +Import "src/base/ftxf86.c" +Import "src/base/ftpatent.c" + +Import "src/autofit/autofit.c" +Import "src/bdf/bdf.c" +Import "src/cache/ftcache.c" +Import "src/cff/cff.c" +Import "src/cid/type1cid.c" +Import "src/gzip/ftgzip.c" +Import "src/lzw/ftlzw.c" +Import "src/otvalid/otvalid.c" +Import "src/pcf/pcf.c" +Import "src/pfr/pfr.c" +Import "src/psaux/psaux.c" +Import "src/pshinter/pshinter.c" +Import "src/psnames/psnames.c" +Import "src/raster/raster.c" +Import "src/sfnt/sfnt.c" +Import "src/smooth/smooth.c" +Import "src/truetype/truetype.c" +Import "src/type1/type1.c" +Import "src/type42/type42.c" +Import "src/winfonts/winfnt.c" + +? + +Extern + +Function FT_Init_FreeType( ft_lib:Byte Ptr Ptr ) + +Function FT_Done_FreeType( ft_lib:Byte Ptr ) +Function FT_Done_Face( ft_face:Byte Ptr ) +Function FT_Done_Glyph( ft_glyph:Byte Ptr ) + +Function FT_New_Face( ft_lib:Byte Ptr,arg$z,faceIndex,ft_face:Byte Ptr Ptr ) +Function FT_New_Memory_Face( ft_lib:Byte Ptr,buf:Byte Ptr,size,faceIndex,ft_face:Byte Ptr Ptr ) + +Function FT_Set_Pixel_Sizes( ft_face:Byte Ptr,width,height ) +Function FT_Get_Char_Index( ft_face:Byte Ptr,index ) +Function FT_Set_Charmap( ft_face:Byte Ptr,charmap ) + +Function FT_Load_Char( ft_face:Byte Ptr,index,flags ) +Function FT_Load_Glyph( ft_face:Byte Ptr,index,flags ) +Function FT_Render_Glyph( ft_glyph:Byte Ptr,mode ) + +End Extern + +Const FT_LOAD_DEFAULT=0 +Const FT_LOAD_NO_SCALE=1 +Const FT_LOAD_NO_HINTING=2 +Const FT_LOAD_RENDER=4 +Const FT_LOAD_NO_BITMAP=8 +Const FT_LOAD_VERTICAL_LAYOUT=$10 +Const FT_LOAD_FORCE_AUTOHINT=$20 +Const FT_LOAD_CROP_BITMAP=$40 +Const FT_LOAD_PEDANTIC=$80 +Const FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH=$200 +Const FT_LOAD_NO_RECURSE=$400 +Const FT_LOAD_IGNORE_TRANSFORM=$800 +Const FT_LOAD_MONOCHROME=$1000 +Const FT_LOAD_LINEAR_DESIGN=$2000 + +Const FT_RENDER_MODE_NORMAL=0 +Const FT_RENDER_MODE_LIGHT=1 +Const FT_RENDER_MODE_MONO=2 +Const FT_RENDER_MODE_LCD=3 +Const FT_RENDER_MODE_LCD_V=4 + + +Type FTFace + Field numfaces,index,flags,style,numglyphs + Field fname:Byte Ptr + Field sname:Byte Ptr + Field numsizes + Field sizes:Int Ptr + Field numcharmaps + Field charmaps:Int Ptr + Field genericdata:Byte Ptr,genericdestructor + Field bx0,by0,bx1,by1 + Field unitsperem:Short + Field ascender:Short + Field descender:Short + Field height:Short + Field maxawidth:Short + Field maxahieght:Short + Field underlinepos:Short + Field underlinethick:Short + Field glyphslot:Int Ptr + Field metrics:Byte Ptr +End Type + +Type FTMetrics + Field mface,mgeneric0,mgeneric1 + Field xppem:Short,yppem:Short + Field xscale,yscale + Field ascend,descend,height,max_advance +End Type + +Type FTGlyph + Field lib,face,nextglyph,reserved + Field genericdata:Byte Ptr,genericdestructor + Field metric_width,metric_height,metric_horibearingx,metric_horibearingy + Field metric_horiadvance,metric_vertbearingx,metric_vertbearingy,metric_vertadvance + Field hadvance,vadvance + Field advancex,advancey + Field glyphformat +'bitmap + Field rows,width,pitch + Field buffer:Byte Ptr + Field numgreys:Short,pixel_mode:Byte,palette_mode:Byte + Field palette:Byte Ptr + Field bitmap_left,bitmap_top +End Type diff --git a/mod/pub.mod/freetype.mod/include/freetype/config/ftconfig.h b/mod/pub.mod/freetype.mod/include/freetype/config/ftconfig.h new file mode 100644 index 0000000..3c0b8b1 --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/config/ftconfig.h @@ -0,0 +1,500 @@ +/***************************************************************************/ +/* */ +/* ftconfig.h */ +/* */ +/* ANSI-specific configuration file (specification only). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This header file contains a number of macro definitions that are used */ + /* by the rest of the engine. Most of the macros here are automatically */ + /* determined at compile time, and you should not need to change it to */ + /* port FreeType, except to compile the library with a non-ANSI */ + /* compiler. */ + /* */ + /* Note however that if some specific modifications are needed, we */ + /* advise you to place a modified copy in your build directory. */ + /* */ + /* The build directory is usually `freetype/builds/', and */ + /* contains system-specific files that are always included first when */ + /* building the library. */ + /* */ + /* This ANSI version should stay in `include/freetype/config'. */ + /* */ + /*************************************************************************/ + + +#ifndef __FTCONFIG_H__ +#define __FTCONFIG_H__ + +#include +#include FT_CONFIG_OPTIONS_H +#include FT_CONFIG_STANDARD_LIBRARY_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* PLATFORM-SPECIFIC CONFIGURATION MACROS */ + /* */ + /* These macros can be toggled to suit a specific system. The current */ + /* ones are defaults used to compile FreeType in an ANSI C environment */ + /* (16bit compilers are also supported). Copy this file to your own */ + /* `freetype/builds/' directory, and edit it to port the engine. */ + /* */ + /*************************************************************************/ + + + /* There are systems (like the Texas Instruments 'C54x) where a `char' */ + /* has 16 bits. ANSI C says that sizeof(char) is always 1. Since an */ + /* `int' has 16 bits also for this system, sizeof(int) gives 1 which */ + /* is probably unexpected. */ + /* */ + /* `CHAR_BIT' (defined in limits.h) gives the number of bits in a */ + /* `char' type. */ + +#ifndef FT_CHAR_BIT +#define FT_CHAR_BIT CHAR_BIT +#endif + + + /* The size of an `int' type. */ +#if FT_UINT_MAX == 0xFFFFUL +#define FT_SIZEOF_INT (16 / FT_CHAR_BIT) +#elif FT_UINT_MAX == 0xFFFFFFFFUL +#define FT_SIZEOF_INT (32 / FT_CHAR_BIT) +#elif FT_UINT_MAX > 0xFFFFFFFFUL && FT_UINT_MAX == 0xFFFFFFFFFFFFFFFFUL +#define FT_SIZEOF_INT (64 / FT_CHAR_BIT) +#else +#error "Unsupported size of `int' type!" +#endif + + /* The size of a `long' type. A five-byte `long' (as used e.g. on the */ + /* DM642) is recognized but avoided. */ +#if FT_ULONG_MAX == 0xFFFFFFFFUL +#define FT_SIZEOF_LONG (32 / FT_CHAR_BIT) +#elif FT_ULONG_MAX > 0xFFFFFFFFUL && FT_ULONG_MAX == 0xFFFFFFFFFFUL +#define FT_SIZEOF_LONG (32 / FT_CHAR_BIT) +#elif FT_ULONG_MAX > 0xFFFFFFFFUL && FT_ULONG_MAX == 0xFFFFFFFFFFFFFFFFUL +#define FT_SIZEOF_LONG (64 / FT_CHAR_BIT) +#else +#error "Unsupported size of `long' type!" +#endif + + + /* Preferred alignment of data */ +#define FT_ALIGNMENT 8 + + + /* FT_UNUSED is a macro used to indicate that a given parameter is not */ + /* used -- this is only used to get rid of unpleasant compiler warnings */ +#ifndef FT_UNUSED +#define FT_UNUSED( arg ) ( (arg) = (arg) ) +#endif + + + /*************************************************************************/ + /* */ + /* AUTOMATIC CONFIGURATION MACROS */ + /* */ + /* These macros are computed from the ones defined above. Don't touch */ + /* their definition, unless you know precisely what you are doing. No */ + /* porter should need to mess with them. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* Mac support */ + /* */ + /* This is the only necessary change, so it is defined here instead */ + /* providing a new configuration file. */ + /* */ +#if ( defined( __APPLE__ ) && !defined( DARWIN_NO_CARBON ) ) || \ + ( defined( __MWERKS__ ) && defined( macintosh ) ) + /* no Carbon frameworks for 64bit 10.4.x */ +#include "AvailabilityMacros.h" +#if defined( __LP64__ ) && \ + ( MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 ) +#define DARWIN_NO_CARBON 1 +#else +#define FT_MACINTOSH 1 +#endif + +#elif defined( __SC__ ) || defined( __MRC__ ) + /* Classic MacOS compilers */ +#include "ConditionalMacros.h" +#if TARGET_OS_MAC +#define FT_MACINTOSH 1 +#endif + +#endif + + + /*************************************************************************/ + /* */ + /*

        */ + /* basic_types */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* */ + /* FT_Int16 */ + /* */ + /* */ + /* A typedef for a 16bit signed integer type. */ + /* */ + typedef signed short FT_Int16; + + + /*************************************************************************/ + /* */ + /* */ + /* FT_UInt16 */ + /* */ + /* */ + /* A typedef for a 16bit unsigned integer type. */ + /* */ + typedef unsigned short FT_UInt16; + + /* */ + + + /* this #if 0 ... #endif clause is for documentation purposes */ +#if 0 + + /*************************************************************************/ + /* */ + /* */ + /* FT_Int32 */ + /* */ + /* */ + /* A typedef for a 32bit signed integer type. The size depends on */ + /* the configuration. */ + /* */ + typedef signed XXX FT_Int32; + + + /*************************************************************************/ + /* */ + /* */ + /* FT_UInt32 */ + /* */ + /* A typedef for a 32bit unsigned integer type. The size depends on */ + /* the configuration. */ + /* */ + typedef unsigned XXX FT_UInt32; + + /* */ + +#endif + +#if FT_SIZEOF_INT == (32 / FT_CHAR_BIT) + + typedef signed int FT_Int32; + typedef unsigned int FT_UInt32; + +#elif FT_SIZEOF_LONG == (32 / FT_CHAR_BIT) + + typedef signed long FT_Int32; + typedef unsigned long FT_UInt32; + +#else +#error "no 32bit type found -- please check your configuration files" +#endif + + + /* look up an integer type that is at least 32 bits */ +#if FT_SIZEOF_INT >= (32 / FT_CHAR_BIT) + + typedef int FT_Fast; + typedef unsigned int FT_UFast; + +#elif FT_SIZEOF_LONG >= (32 / FT_CHAR_BIT) + + typedef long FT_Fast; + typedef unsigned long FT_UFast; + +#endif + + + /* determine whether we have a 64-bit int type for platforms without */ + /* Autoconf */ +#if FT_SIZEOF_LONG == (64 / FT_CHAR_BIT) + + /* FT_LONG64 must be defined if a 64-bit type is available */ +#define FT_LONG64 +#define FT_INT64 long + +#elif defined( _MSC_VER ) && _MSC_VER >= 900 /* Visual C++ (and Intel C++) */ + + /* this compiler provides the __int64 type */ +#define FT_LONG64 +#define FT_INT64 __int64 + +#elif defined( __BORLANDC__ ) /* Borland C++ */ + + /* XXXX: We should probably check the value of __BORLANDC__ in order */ + /* to test the compiler version. */ + + /* this compiler provides the __int64 type */ +#define FT_LONG64 +#define FT_INT64 __int64 + +#elif defined( __WATCOMC__ ) /* Watcom C++ */ + + /* Watcom doesn't provide 64-bit data types */ + +#elif defined( __MWERKS__ ) /* Metrowerks CodeWarrior */ + +#define FT_LONG64 +#define FT_INT64 long long int + +#elif defined( __GNUC__ ) + + /* GCC provides the `long long' type */ +#define FT_LONG64 +#define FT_INT64 long long int + +#endif /* FT_SIZEOF_LONG == (64 / FT_CHAR_BIT) */ + + + /*************************************************************************/ + /* */ + /* A 64-bit data type will create compilation problems if you compile */ + /* in strict ANSI mode. To avoid them, we disable its use if __STDC__ */ + /* is defined. You can however ignore this rule by defining the */ + /* FT_CONFIG_OPTION_FORCE_INT64 configuration macro. */ + /* */ +#if defined( FT_LONG64 ) && !defined( FT_CONFIG_OPTION_FORCE_INT64 ) + +#ifdef __STDC__ + + /* undefine the 64-bit macros in strict ANSI compilation mode */ +#undef FT_LONG64 +#undef FT_INT64 + +#endif /* __STDC__ */ + +#endif /* FT_LONG64 && !FT_CONFIG_OPTION_FORCE_INT64 */ + + +#define FT_BEGIN_STMNT do { +#define FT_END_STMNT } while ( 0 ) +#define FT_DUMMY_STMNT FT_BEGIN_STMNT FT_END_STMNT + + +#ifndef FT_CONFIG_OPTION_NO_ASSEMBLER + /* Provide assembler fragments for performance-critical functions. */ + /* These must be defined `static __inline__' with GCC. */ + +#ifdef __GNUC__ + +#if defined( __arm__ ) && !defined( __thumb__ ) +#define FT_MULFIX_ASSEMBLER FT_MulFix_arm + + /* documentation is in freetype.h */ + + static __inline__ FT_Int32 + FT_MulFix_arm( FT_Int32 a, + FT_Int32 b ) + { + register FT_Int32 t, t2; + + + asm __volatile__ ( + "smull %1, %2, %4, %3\n\t" /* (lo=%1,hi=%2) = a*b */ + "mov %0, %2, asr #31\n\t" /* %0 = (hi >> 31) */ + "add %0, %0, #0x8000\n\t" /* %0 += 0x8000 */ + "adds %1, %1, %0\n\t" /* %1 += %0 */ + "adc %2, %2, #0\n\t" /* %2 += carry */ + "mov %0, %1, lsr #16\n\t" /* %0 = %1 >> 16 */ + "orr %0, %2, lsl #16\n\t" /* %0 |= %2 << 16 */ + : "=r"(a), "=&r"(t2), "=&r"(t) + : "r"(a), "r"(b) ); + return a; + } + +#endif /* __arm__ && !__thumb__ */ + +#if defined( i386 ) +#define FT_MULFIX_ASSEMBLER FT_MulFix_i386 + + /* documentation is in freetype.h */ + + static __inline__ FT_Int32 + FT_MulFix_i386( FT_Int32 a, + FT_Int32 b ) + { + register FT_Int32 result; + + + __asm__ __volatile__ ( + "imul %%edx\n" + "movl %%edx, %%ecx\n" + "sarl $31, %%ecx\n" + "addl $0x8000, %%ecx\n" + "addl %%ecx, %%eax\n" + "adcl $0, %%edx\n" + "shrl $16, %%eax\n" + "shll $16, %%edx\n" + "addl %%edx, %%eax\n" + : "=a"(result), "=d"(b) + : "a"(a), "d"(b) + : "%ecx", "cc" ); + return result; + } + +#endif /* i386 */ + +#endif /* __GNUC__ */ + +#endif /* !FT_CONFIG_OPTION_NO_ASSEMBLER */ + + +#ifdef FT_CONFIG_OPTION_INLINE_MULFIX +#ifdef FT_MULFIX_ASSEMBLER +#define FT_MULFIX_INLINED FT_MULFIX_ASSEMBLER +#endif +#endif + + +#ifdef FT_MAKE_OPTION_SINGLE_OBJECT + +#define FT_LOCAL( x ) static x +#define FT_LOCAL_DEF( x ) static x + +#else + +#ifdef __cplusplus +#define FT_LOCAL( x ) extern "C" x +#define FT_LOCAL_DEF( x ) extern "C" x +#else +#define FT_LOCAL( x ) extern x +#define FT_LOCAL_DEF( x ) x +#endif + +#endif /* FT_MAKE_OPTION_SINGLE_OBJECT */ + + +#ifndef FT_BASE + +#ifdef __cplusplus +#define FT_BASE( x ) extern "C" x +#else +#define FT_BASE( x ) extern x +#endif + +#endif /* !FT_BASE */ + + +#ifndef FT_BASE_DEF + +#ifdef __cplusplus +#define FT_BASE_DEF( x ) x +#else +#define FT_BASE_DEF( x ) x +#endif + +#endif /* !FT_BASE_DEF */ + + +#ifndef FT_EXPORT + +#ifdef __cplusplus +#define FT_EXPORT( x ) extern "C" x +#else +#define FT_EXPORT( x ) extern x +#endif + +#endif /* !FT_EXPORT */ + + +#ifndef FT_EXPORT_DEF + +#ifdef __cplusplus +#define FT_EXPORT_DEF( x ) extern "C" x +#else +#define FT_EXPORT_DEF( x ) extern x +#endif + +#endif /* !FT_EXPORT_DEF */ + + +#ifndef FT_EXPORT_VAR + +#ifdef __cplusplus +#define FT_EXPORT_VAR( x ) extern "C" x +#else +#define FT_EXPORT_VAR( x ) extern x +#endif + +#endif /* !FT_EXPORT_VAR */ + + /* The following macros are needed to compile the library with a */ + /* C++ compiler and with 16bit compilers. */ + /* */ + + /* This is special. Within C++, you must specify `extern "C"' for */ + /* functions which are used via function pointers, and you also */ + /* must do that for structures which contain function pointers to */ + /* assure C linkage -- it's not possible to have (local) anonymous */ + /* functions which are accessed by (global) function pointers. */ + /* */ + /* */ + /* FT_CALLBACK_DEF is used to _define_ a callback function. */ + /* */ + /* FT_CALLBACK_TABLE is used to _declare_ a constant variable that */ + /* contains pointers to callback functions. */ + /* */ + /* FT_CALLBACK_TABLE_DEF is used to _define_ a constant variable */ + /* that contains pointers to callback functions. */ + /* */ + /* */ + /* Some 16bit compilers have to redefine these macros to insert */ + /* the infamous `_cdecl' or `__fastcall' declarations. */ + /* */ +#ifndef FT_CALLBACK_DEF +#ifdef __cplusplus +#define FT_CALLBACK_DEF( x ) extern "C" x +#else +#define FT_CALLBACK_DEF( x ) static x +#endif +#endif /* FT_CALLBACK_DEF */ + +#ifndef FT_CALLBACK_TABLE +#ifdef __cplusplus +#define FT_CALLBACK_TABLE extern "C" +#define FT_CALLBACK_TABLE_DEF extern "C" +#else +#define FT_CALLBACK_TABLE extern +#define FT_CALLBACK_TABLE_DEF /* nothing */ +#endif +#endif /* FT_CALLBACK_TABLE */ + + +FT_END_HEADER + + +#endif /* __FTCONFIG_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/config/ftheader.h b/mod/pub.mod/freetype.mod/include/freetype/config/ftheader.h new file mode 100644 index 0000000..b63945d --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/config/ftheader.h @@ -0,0 +1,780 @@ +/***************************************************************************/ +/* */ +/* ftheader.h */ +/* */ +/* Build macros of the FreeType 2 library. */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + +#ifndef __FT_HEADER_H__ +#define __FT_HEADER_H__ + + + /*@***********************************************************************/ + /* */ + /* */ + /* FT_BEGIN_HEADER */ + /* */ + /* */ + /* This macro is used in association with @FT_END_HEADER in header */ + /* files to ensure that the declarations within are properly */ + /* encapsulated in an `extern "C" { .. }' block when included from a */ + /* C++ compiler. */ + /* */ +#ifdef __cplusplus +#define FT_BEGIN_HEADER extern "C" { +#else +#define FT_BEGIN_HEADER /* nothing */ +#endif + + + /*@***********************************************************************/ + /* */ + /* */ + /* FT_END_HEADER */ + /* */ + /* */ + /* This macro is used in association with @FT_BEGIN_HEADER in header */ + /* files to ensure that the declarations within are properly */ + /* encapsulated in an `extern "C" { .. }' block when included from a */ + /* C++ compiler. */ + /* */ +#ifdef __cplusplus +#define FT_END_HEADER } +#else +#define FT_END_HEADER /* nothing */ +#endif + + + /*************************************************************************/ + /* */ + /* Aliases for the FreeType 2 public and configuration files. */ + /* */ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /*
        */ + /* header_file_macros */ + /* */ + /* */ + /* Header File Macros */ + /* */ + /* <Abstract> */ + /* Macro definitions used to #include specific header files. */ + /* */ + /* <Description> */ + /* The following macros are defined to the name of specific */ + /* FreeType~2 header files. They can be used directly in #include */ + /* statements as in: */ + /* */ + /* { */ + /* #include FT_FREETYPE_H */ + /* #include FT_MULTIPLE_MASTERS_H */ + /* #include FT_GLYPH_H */ + /* } */ + /* */ + /* There are several reasons why we are now using macros to name */ + /* public header files. The first one is that such macros are not */ + /* limited to the infamous 8.3~naming rule required by DOS (and */ + /* `FT_MULTIPLE_MASTERS_H' is a lot more meaningful than `ftmm.h'). */ + /* */ + /* The second reason is that it allows for more flexibility in the */ + /* way FreeType~2 is installed on a given system. */ + /* */ + /*************************************************************************/ + + + /* configuration files */ + + /************************************************************************* + * + * @macro: + * FT_CONFIG_CONFIG_H + * + * @description: + * A macro used in #include statements to name the file containing + * FreeType~2 configuration data. + * + */ +#ifndef FT_CONFIG_CONFIG_H +#define FT_CONFIG_CONFIG_H <freetype/config/ftconfig.h> +#endif + + + /************************************************************************* + * + * @macro: + * FT_CONFIG_STANDARD_LIBRARY_H + * + * @description: + * A macro used in #include statements to name the file containing + * FreeType~2 interface to the standard C library functions. + * + */ +#ifndef FT_CONFIG_STANDARD_LIBRARY_H +#define FT_CONFIG_STANDARD_LIBRARY_H <freetype/config/ftstdlib.h> +#endif + + + /************************************************************************* + * + * @macro: + * FT_CONFIG_OPTIONS_H + * + * @description: + * A macro used in #include statements to name the file containing + * FreeType~2 project-specific configuration options. + * + */ +#ifndef FT_CONFIG_OPTIONS_H +#define FT_CONFIG_OPTIONS_H <freetype/config/ftoption.h> +#endif + + + /************************************************************************* + * + * @macro: + * FT_CONFIG_MODULES_H + * + * @description: + * A macro used in #include statements to name the file containing the + * list of FreeType~2 modules that are statically linked to new library + * instances in @FT_Init_FreeType. + * + */ +#ifndef FT_CONFIG_MODULES_H +#define FT_CONFIG_MODULES_H <freetype/config/ftmodule.h> +#endif + + /* */ + + /* public headers */ + + /************************************************************************* + * + * @macro: + * FT_FREETYPE_H + * + * @description: + * A macro used in #include statements to name the file containing the + * base FreeType~2 API. + * + */ +#define FT_FREETYPE_H <freetype/freetype.h> + + + /************************************************************************* + * + * @macro: + * FT_ERRORS_H + * + * @description: + * A macro used in #include statements to name the file containing the + * list of FreeType~2 error codes (and messages). + * + * It is included by @FT_FREETYPE_H. + * + */ +#define FT_ERRORS_H <freetype/fterrors.h> + + + /************************************************************************* + * + * @macro: + * FT_MODULE_ERRORS_H + * + * @description: + * A macro used in #include statements to name the file containing the + * list of FreeType~2 module error offsets (and messages). + * + */ +#define FT_MODULE_ERRORS_H <freetype/ftmoderr.h> + + + /************************************************************************* + * + * @macro: + * FT_SYSTEM_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType~2 interface to low-level operations (i.e., memory management + * and stream i/o). + * + * It is included by @FT_FREETYPE_H. + * + */ +#define FT_SYSTEM_H <freetype/ftsystem.h> + + + /************************************************************************* + * + * @macro: + * FT_IMAGE_H + * + * @description: + * A macro used in #include statements to name the file containing type + * definitions related to glyph images (i.e., bitmaps, outlines, + * scan-converter parameters). + * + * It is included by @FT_FREETYPE_H. + * + */ +#define FT_IMAGE_H <freetype/ftimage.h> + + + /************************************************************************* + * + * @macro: + * FT_TYPES_H + * + * @description: + * A macro used in #include statements to name the file containing the + * basic data types defined by FreeType~2. + * + * It is included by @FT_FREETYPE_H. + * + */ +#define FT_TYPES_H <freetype/fttypes.h> + + + /************************************************************************* + * + * @macro: + * FT_LIST_H + * + * @description: + * A macro used in #include statements to name the file containing the + * list management API of FreeType~2. + * + * (Most applications will never need to include this file.) + * + */ +#define FT_LIST_H <freetype/ftlist.h> + + + /************************************************************************* + * + * @macro: + * FT_OUTLINE_H + * + * @description: + * A macro used in #include statements to name the file containing the + * scalable outline management API of FreeType~2. + * + */ +#define FT_OUTLINE_H <freetype/ftoutln.h> + + + /************************************************************************* + * + * @macro: + * FT_SIZES_H + * + * @description: + * A macro used in #include statements to name the file containing the + * API which manages multiple @FT_Size objects per face. + * + */ +#define FT_SIZES_H <freetype/ftsizes.h> + + + /************************************************************************* + * + * @macro: + * FT_MODULE_H + * + * @description: + * A macro used in #include statements to name the file containing the + * module management API of FreeType~2. + * + */ +#define FT_MODULE_H <freetype/ftmodapi.h> + + + /************************************************************************* + * + * @macro: + * FT_RENDER_H + * + * @description: + * A macro used in #include statements to name the file containing the + * renderer module management API of FreeType~2. + * + */ +#define FT_RENDER_H <freetype/ftrender.h> + + + /************************************************************************* + * + * @macro: + * FT_TYPE1_TABLES_H + * + * @description: + * A macro used in #include statements to name the file containing the + * types and API specific to the Type~1 format. + * + */ +#define FT_TYPE1_TABLES_H <freetype/t1tables.h> + + + /************************************************************************* + * + * @macro: + * FT_TRUETYPE_IDS_H + * + * @description: + * A macro used in #include statements to name the file containing the + * enumeration values which identify name strings, languages, encodings, + * etc. This file really contains a _large_ set of constant macro + * definitions, taken from the TrueType and OpenType specifications. + * + */ +#define FT_TRUETYPE_IDS_H <freetype/ttnameid.h> + + + /************************************************************************* + * + * @macro: + * FT_TRUETYPE_TABLES_H + * + * @description: + * A macro used in #include statements to name the file containing the + * types and API specific to the TrueType (as well as OpenType) format. + * + */ +#define FT_TRUETYPE_TABLES_H <freetype/tttables.h> + + + /************************************************************************* + * + * @macro: + * FT_TRUETYPE_TAGS_H + * + * @description: + * A macro used in #include statements to name the file containing the + * definitions of TrueType four-byte `tags' which identify blocks in + * SFNT-based font formats (i.e., TrueType and OpenType). + * + */ +#define FT_TRUETYPE_TAGS_H <freetype/tttags.h> + + + /************************************************************************* + * + * @macro: + * FT_BDF_H + * + * @description: + * A macro used in #include statements to name the file containing the + * definitions of an API which accesses BDF-specific strings from a + * face. + * + */ +#define FT_BDF_H <freetype/ftbdf.h> + + + /************************************************************************* + * + * @macro: + * FT_CID_H + * + * @description: + * A macro used in #include statements to name the file containing the + * definitions of an API which access CID font information from a + * face. + * + */ +#define FT_CID_H <freetype/ftcid.h> + + + /************************************************************************* + * + * @macro: + * FT_GZIP_H + * + * @description: + * A macro used in #include statements to name the file containing the + * definitions of an API which supports gzip-compressed files. + * + */ +#define FT_GZIP_H <freetype/ftgzip.h> + + + /************************************************************************* + * + * @macro: + * FT_LZW_H + * + * @description: + * A macro used in #include statements to name the file containing the + * definitions of an API which supports LZW-compressed files. + * + */ +#define FT_LZW_H <freetype/ftlzw.h> + + + /************************************************************************* + * + * @macro: + * FT_WINFONTS_H + * + * @description: + * A macro used in #include statements to name the file containing the + * definitions of an API which supports Windows FNT files. + * + */ +#define FT_WINFONTS_H <freetype/ftwinfnt.h> + + + /************************************************************************* + * + * @macro: + * FT_GLYPH_H + * + * @description: + * A macro used in #include statements to name the file containing the + * API of the optional glyph management component. + * + */ +#define FT_GLYPH_H <freetype/ftglyph.h> + + + /************************************************************************* + * + * @macro: + * FT_BITMAP_H + * + * @description: + * A macro used in #include statements to name the file containing the + * API of the optional bitmap conversion component. + * + */ +#define FT_BITMAP_H <freetype/ftbitmap.h> + + + /************************************************************************* + * + * @macro: + * FT_BBOX_H + * + * @description: + * A macro used in #include statements to name the file containing the + * API of the optional exact bounding box computation routines. + * + */ +#define FT_BBOX_H <freetype/ftbbox.h> + + + /************************************************************************* + * + * @macro: + * FT_CACHE_H + * + * @description: + * A macro used in #include statements to name the file containing the + * API of the optional FreeType~2 cache sub-system. + * + */ +#define FT_CACHE_H <freetype/ftcache.h> + + + /************************************************************************* + * + * @macro: + * FT_CACHE_IMAGE_H + * + * @description: + * A macro used in #include statements to name the file containing the + * `glyph image' API of the FreeType~2 cache sub-system. + * + * It is used to define a cache for @FT_Glyph elements. You can also + * use the API defined in @FT_CACHE_SMALL_BITMAPS_H if you only need to + * store small glyph bitmaps, as it will use less memory. + * + * This macro is deprecated. Simply include @FT_CACHE_H to have all + * glyph image-related cache declarations. + * + */ +#define FT_CACHE_IMAGE_H FT_CACHE_H + + + /************************************************************************* + * + * @macro: + * FT_CACHE_SMALL_BITMAPS_H + * + * @description: + * A macro used in #include statements to name the file containing the + * `small bitmaps' API of the FreeType~2 cache sub-system. + * + * It is used to define a cache for small glyph bitmaps in a relatively + * memory-efficient way. You can also use the API defined in + * @FT_CACHE_IMAGE_H if you want to cache arbitrary glyph images, + * including scalable outlines. + * + * This macro is deprecated. Simply include @FT_CACHE_H to have all + * small bitmaps-related cache declarations. + * + */ +#define FT_CACHE_SMALL_BITMAPS_H FT_CACHE_H + + + /************************************************************************* + * + * @macro: + * FT_CACHE_CHARMAP_H + * + * @description: + * A macro used in #include statements to name the file containing the + * `charmap' API of the FreeType~2 cache sub-system. + * + * This macro is deprecated. Simply include @FT_CACHE_H to have all + * charmap-based cache declarations. + * + */ +#define FT_CACHE_CHARMAP_H FT_CACHE_H + + + /************************************************************************* + * + * @macro: + * FT_MAC_H + * + * @description: + * A macro used in #include statements to name the file containing the + * Macintosh-specific FreeType~2 API. The latter is used to access + * fonts embedded in resource forks. + * + * This header file must be explicitly included by client applications + * compiled on the Mac (note that the base API still works though). + * + */ +#define FT_MAC_H <freetype/ftmac.h> + + + /************************************************************************* + * + * @macro: + * FT_MULTIPLE_MASTERS_H + * + * @description: + * A macro used in #include statements to name the file containing the + * optional multiple-masters management API of FreeType~2. + * + */ +#define FT_MULTIPLE_MASTERS_H <freetype/ftmm.h> + + + /************************************************************************* + * + * @macro: + * FT_SFNT_NAMES_H + * + * @description: + * A macro used in #include statements to name the file containing the + * optional FreeType~2 API which accesses embedded `name' strings in + * SFNT-based font formats (i.e., TrueType and OpenType). + * + */ +#define FT_SFNT_NAMES_H <freetype/ftsnames.h> + + + /************************************************************************* + * + * @macro: + * FT_OPENTYPE_VALIDATE_H + * + * @description: + * A macro used in #include statements to name the file containing the + * optional FreeType~2 API which validates OpenType tables (BASE, GDEF, + * GPOS, GSUB, JSTF). + * + */ +#define FT_OPENTYPE_VALIDATE_H <freetype/ftotval.h> + + + /************************************************************************* + * + * @macro: + * FT_GX_VALIDATE_H + * + * @description: + * A macro used in #include statements to name the file containing the + * optional FreeType~2 API which validates TrueTypeGX/AAT tables (feat, + * mort, morx, bsln, just, kern, opbd, trak, prop). + * + */ +#define FT_GX_VALIDATE_H <freetype/ftgxval.h> + + + /************************************************************************* + * + * @macro: + * FT_PFR_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType~2 API which accesses PFR-specific data. + * + */ +#define FT_PFR_H <freetype/ftpfr.h> + + + /************************************************************************* + * + * @macro: + * FT_STROKER_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType~2 API which provides functions to stroke outline paths. + */ +#define FT_STROKER_H <freetype/ftstroke.h> + + + /************************************************************************* + * + * @macro: + * FT_SYNTHESIS_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType~2 API which performs artificial obliquing and emboldening. + */ +#define FT_SYNTHESIS_H <freetype/ftsynth.h> + + + /************************************************************************* + * + * @macro: + * FT_XFREE86_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType~2 API which provides functions specific to the XFree86 and + * X.Org X11 servers. + */ +#define FT_XFREE86_H <freetype/ftxf86.h> + + + /************************************************************************* + * + * @macro: + * FT_TRIGONOMETRY_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType~2 API which performs trigonometric computations (e.g., + * cosines and arc tangents). + */ +#define FT_TRIGONOMETRY_H <freetype/fttrigon.h> + + + /************************************************************************* + * + * @macro: + * FT_LCD_FILTER_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType~2 API which performs color filtering for subpixel rendering. + */ +#define FT_LCD_FILTER_H <freetype/ftlcdfil.h> + + + /************************************************************************* + * + * @macro: + * FT_UNPATENTED_HINTING_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType~2 API which performs color filtering for subpixel rendering. + */ +#define FT_UNPATENTED_HINTING_H <freetype/ttunpat.h> + + + /************************************************************************* + * + * @macro: + * FT_INCREMENTAL_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType~2 API which performs color filtering for subpixel rendering. + */ +#define FT_INCREMENTAL_H <freetype/ftincrem.h> + + + /************************************************************************* + * + * @macro: + * FT_GASP_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType~2 API which returns entries from the TrueType GASP table. + */ +#define FT_GASP_H <freetype/ftgasp.h> + + + /************************************************************************* + * + * @macro: + * FT_ADVANCES_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType~2 API which returns individual and ranged glyph advances. + */ +#define FT_ADVANCES_H <freetype/ftadvanc.h> + + + /* */ + +#define FT_ERROR_DEFINITIONS_H <freetype/fterrdef.h> + + + /* The internals of the cache sub-system are no longer exposed. We */ + /* default to FT_CACHE_H at the moment just in case, but we know of */ + /* no rogue client that uses them. */ + /* */ +#define FT_CACHE_MANAGER_H <freetype/ftcache.h> +#define FT_CACHE_INTERNAL_MRU_H <freetype/ftcache.h> +#define FT_CACHE_INTERNAL_MANAGER_H <freetype/ftcache.h> +#define FT_CACHE_INTERNAL_CACHE_H <freetype/ftcache.h> +#define FT_CACHE_INTERNAL_GLYPH_H <freetype/ftcache.h> +#define FT_CACHE_INTERNAL_IMAGE_H <freetype/ftcache.h> +#define FT_CACHE_INTERNAL_SBITS_H <freetype/ftcache.h> + + +#define FT_INCREMENTAL_H <freetype/ftincrem.h> + +#define FT_TRUETYPE_UNPATENTED_H <freetype/ttunpat.h> + + + /* + * Include internal headers definitions from <freetype/internal/...> + * only when building the library. + */ +#ifdef FT2_BUILD_LIBRARY +#define FT_INTERNAL_INTERNAL_H <freetype/internal/internal.h> +#include FT_INTERNAL_INTERNAL_H +#endif /* FT2_BUILD_LIBRARY */ + + +#endif /* __FT2_BUILD_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/config/ftmodule.h b/mod/pub.mod/freetype.mod/include/freetype/config/ftmodule.h new file mode 100644 index 0000000..76d271a --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/config/ftmodule.h @@ -0,0 +1,32 @@ +/* + * This file registers the FreeType modules compiled into the library. + * + * If you use GNU make, this file IS NOT USED! Instead, it is created in + * the objects directory (normally `<topdir>/objs/') based on information + * from `<topdir>/modules.cfg'. + * + * Please read `docs/INSTALL.ANY' and `docs/CUSTOMIZE' how to compile + * FreeType without GNU make. + * + */ + +FT_USE_MODULE( FT_Module_Class, autofit_module_class ) +FT_USE_MODULE( FT_Driver_ClassRec, tt_driver_class ) +FT_USE_MODULE( FT_Driver_ClassRec, t1_driver_class ) +FT_USE_MODULE( FT_Driver_ClassRec, cff_driver_class ) +FT_USE_MODULE( FT_Driver_ClassRec, t1cid_driver_class ) +FT_USE_MODULE( FT_Driver_ClassRec, pfr_driver_class ) +FT_USE_MODULE( FT_Driver_ClassRec, t42_driver_class ) +FT_USE_MODULE( FT_Driver_ClassRec, winfnt_driver_class ) +FT_USE_MODULE( FT_Driver_ClassRec, pcf_driver_class ) +FT_USE_MODULE( FT_Module_Class, psaux_module_class ) +FT_USE_MODULE( FT_Module_Class, psnames_module_class ) +FT_USE_MODULE( FT_Module_Class, pshinter_module_class ) +FT_USE_MODULE( FT_Renderer_Class, ft_raster1_renderer_class ) +FT_USE_MODULE( FT_Module_Class, sfnt_module_class ) +FT_USE_MODULE( FT_Renderer_Class, ft_smooth_renderer_class ) +FT_USE_MODULE( FT_Renderer_Class, ft_smooth_lcd_renderer_class ) +FT_USE_MODULE( FT_Renderer_Class, ft_smooth_lcdv_renderer_class ) +FT_USE_MODULE( FT_Driver_ClassRec, bdf_driver_class ) + +/* EOF */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/config/ftoption.h b/mod/pub.mod/freetype.mod/include/freetype/config/ftoption.h new file mode 100644 index 0000000..2e7f870 --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/config/ftoption.h @@ -0,0 +1,708 @@ +/***************************************************************************/ +/* */ +/* ftoption.h */ +/* */ +/* User-selectable configuration macros (specification only). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTOPTION_H__ +#define __FTOPTION_H__ + + +#include <ft2build.h> + + +FT_BEGIN_HEADER + + /*************************************************************************/ + /* */ + /* USER-SELECTABLE CONFIGURATION MACROS */ + /* */ + /* This file contains the default configuration macro definitions for */ + /* a standard build of the FreeType library. There are three ways to */ + /* use this file to build project-specific versions of the library: */ + /* */ + /* - You can modify this file by hand, but this is not recommended in */ + /* cases where you would like to build several versions of the */ + /* library from a single source directory. */ + /* */ + /* - You can put a copy of this file in your build directory, more */ + /* precisely in `$BUILD/freetype/config/ftoption.h', where `$BUILD' */ + /* is the name of a directory that is included _before_ the FreeType */ + /* include path during compilation. */ + /* */ + /* The default FreeType Makefiles and Jamfiles use the build */ + /* directory `builds/<system>' by default, but you can easily change */ + /* that for your own projects. */ + /* */ + /* - Copy the file <ft2build.h> to `$BUILD/ft2build.h' and modify it */ + /* slightly to pre-define the macro FT_CONFIG_OPTIONS_H used to */ + /* locate this file during the build. For example, */ + /* */ + /* #define FT_CONFIG_OPTIONS_H <myftoptions.h> */ + /* #include <freetype/config/ftheader.h> */ + /* */ + /* will use `$BUILD/myftoptions.h' instead of this file for macro */ + /* definitions. */ + /* */ + /* Note also that you can similarly pre-define the macro */ + /* FT_CONFIG_MODULES_H used to locate the file listing of the modules */ + /* that are statically linked to the library at compile time. By */ + /* default, this file is <freetype/config/ftmodule.h>. */ + /* */ + /* We highly recommend using the third method whenever possible. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** G E N E R A L F R E E T Y P E 2 C O N F I G U R A T I O N ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* Uncomment the line below if you want to activate sub-pixel rendering */ + /* (a.k.a. LCD rendering, or ClearType) in this build of the library. */ + /* */ + /* Note that this feature is covered by several Microsoft patents */ + /* and should not be activated in any default build of the library. */ + /* */ + /* This macro has no impact on the FreeType API, only on its */ + /* _implementation_. For example, using FT_RENDER_MODE_LCD when calling */ + /* FT_Render_Glyph still generates a bitmap that is 3 times larger than */ + /* the original size; the difference will be that each triplet of */ + /* subpixels has R=G=B. */ + /* */ + /* This is done to allow FreeType clients to run unmodified, forcing */ + /* them to display normal gray-level anti-aliased glyphs. */ + /* */ +/* #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ + + + /*************************************************************************/ + /* */ + /* Many compilers provide a non-ANSI 64-bit data type that can be used */ + /* by FreeType to speed up some computations. However, this will create */ + /* some problems when compiling the library in strict ANSI mode. */ + /* */ + /* For this reason, the use of 64-bit integers is normally disabled when */ + /* the __STDC__ macro is defined. You can however disable this by */ + /* defining the macro FT_CONFIG_OPTION_FORCE_INT64 here. */ + /* */ + /* For most compilers, this will only create compilation warnings when */ + /* building the library. */ + /* */ + /* ObNote: The compiler-specific 64-bit integers are detected in the */ + /* file `ftconfig.h' either statically or through the */ + /* `configure' script on supported platforms. */ + /* */ +#undef FT_CONFIG_OPTION_FORCE_INT64 + + + /*************************************************************************/ + /* */ + /* If this macro is defined, do not try to use an assembler version of */ + /* performance-critical functions (e.g. FT_MulFix). You should only do */ + /* that to verify that the assembler function works properly, or to */ + /* execute benchmark tests of the various implementations. */ +/* #define FT_CONFIG_OPTION_NO_ASSEMBLER */ + + + /*************************************************************************/ + /* */ + /* If this macro is defined, try to use an inlined assembler version of */ + /* the `FT_MulFix' function, which is a `hotspot' when loading and */ + /* hinting glyphs, and which should be executed as fast as possible. */ + /* */ + /* Note that if your compiler or CPU is not supported, this will default */ + /* to the standard and portable implementation found in `ftcalc.c'. */ + /* */ +#define FT_CONFIG_OPTION_INLINE_MULFIX + + + /*************************************************************************/ + /* */ + /* LZW-compressed file support. */ + /* */ + /* FreeType now handles font files that have been compressed with the */ + /* `compress' program. This is mostly used to parse many of the PCF */ + /* files that come with various X11 distributions. The implementation */ + /* uses NetBSD's `zopen' to partially uncompress the file on the fly */ + /* (see src/lzw/ftgzip.c). */ + /* */ + /* Define this macro if you want to enable this `feature'. */ + /* */ +#define FT_CONFIG_OPTION_USE_LZW + + + /*************************************************************************/ + /* */ + /* Gzip-compressed file support. */ + /* */ + /* FreeType now handles font files that have been compressed with the */ + /* `gzip' program. This is mostly used to parse many of the PCF files */ + /* that come with XFree86. The implementation uses `zlib' to */ + /* partially uncompress the file on the fly (see src/gzip/ftgzip.c). */ + /* */ + /* Define this macro if you want to enable this `feature'. See also */ + /* the macro FT_CONFIG_OPTION_SYSTEM_ZLIB below. */ + /* */ +#define FT_CONFIG_OPTION_USE_ZLIB + + + /*************************************************************************/ + /* */ + /* ZLib library selection */ + /* */ + /* This macro is only used when FT_CONFIG_OPTION_USE_ZLIB is defined. */ + /* It allows FreeType's `ftgzip' component to link to the system's */ + /* installation of the ZLib library. This is useful on systems like */ + /* Unix or VMS where it generally is already available. */ + /* */ + /* If you let it undefined, the component will use its own copy */ + /* of the zlib sources instead. These have been modified to be */ + /* included directly within the component and *not* export external */ + /* function names. This allows you to link any program with FreeType */ + /* _and_ ZLib without linking conflicts. */ + /* */ + /* Do not #undef this macro here since the build system might define */ + /* it for certain configurations only. */ + /* */ +#define FT_CONFIG_OPTION_SYSTEM_ZLIB + + + /*************************************************************************/ + /* */ + /* DLL export compilation */ + /* */ + /* When compiling FreeType as a DLL, some systems/compilers need a */ + /* special keyword in front OR after the return type of function */ + /* declarations. */ + /* */ + /* Two macros are used within the FreeType source code to define */ + /* exported library functions: FT_EXPORT and FT_EXPORT_DEF. */ + /* */ + /* FT_EXPORT( return_type ) */ + /* */ + /* is used in a function declaration, as in */ + /* */ + /* FT_EXPORT( FT_Error ) */ + /* FT_Init_FreeType( FT_Library* alibrary ); */ + /* */ + /* */ + /* FT_EXPORT_DEF( return_type ) */ + /* */ + /* is used in a function definition, as in */ + /* */ + /* FT_EXPORT_DEF( FT_Error ) */ + /* FT_Init_FreeType( FT_Library* alibrary ) */ + /* { */ + /* ... some code ... */ + /* return FT_Err_Ok; */ + /* } */ + /* */ + /* You can provide your own implementation of FT_EXPORT and */ + /* FT_EXPORT_DEF here if you want. If you leave them undefined, they */ + /* will be later automatically defined as `extern return_type' to */ + /* allow normal compilation. */ + /* */ + /* Do not #undef these macros here since the build system might define */ + /* them for certain configurations only. */ + /* */ +/* #define FT_EXPORT(x) extern x */ +/* #define FT_EXPORT_DEF(x) x */ + + + /*************************************************************************/ + /* */ + /* Glyph Postscript Names handling */ + /* */ + /* By default, FreeType 2 is compiled with the `psnames' module. This */ + /* module is in charge of converting a glyph name string into a */ + /* Unicode value, or return a Macintosh standard glyph name for the */ + /* use with the TrueType `post' table. */ + /* */ + /* Undefine this macro if you do not want `psnames' compiled in your */ + /* build of FreeType. This has the following effects: */ + /* */ + /* - The TrueType driver will provide its own set of glyph names, */ + /* if you build it to support postscript names in the TrueType */ + /* `post' table. */ + /* */ + /* - The Type 1 driver will not be able to synthesize a Unicode */ + /* charmap out of the glyphs found in the fonts. */ + /* */ + /* You would normally undefine this configuration macro when building */ + /* a version of FreeType that doesn't contain a Type 1 or CFF driver. */ + /* */ +#define FT_CONFIG_OPTION_POSTSCRIPT_NAMES + + + /*************************************************************************/ + /* */ + /* Postscript Names to Unicode Values support */ + /* */ + /* By default, FreeType 2 is built with the `PSNames' module compiled */ + /* in. Among other things, the module is used to convert a glyph name */ + /* into a Unicode value. This is especially useful in order to */ + /* synthesize on the fly a Unicode charmap from the CFF/Type 1 driver */ + /* through a big table named the `Adobe Glyph List' (AGL). */ + /* */ + /* Undefine this macro if you do not want the Adobe Glyph List */ + /* compiled in your `PSNames' module. The Type 1 driver will not be */ + /* able to synthesize a Unicode charmap out of the glyphs found in the */ + /* fonts. */ + /* */ +#define FT_CONFIG_OPTION_ADOBE_GLYPH_LIST + + + /*************************************************************************/ + /* */ + /* Support for Mac fonts */ + /* */ + /* Define this macro if you want support for outline fonts in Mac */ + /* format (mac dfont, mac resource, macbinary containing a mac */ + /* resource) on non-Mac platforms. */ + /* */ + /* Note that the `FOND' resource isn't checked. */ + /* */ +#define FT_CONFIG_OPTION_MAC_FONTS + + + /*************************************************************************/ + /* */ + /* Guessing methods to access embedded resource forks */ + /* */ + /* Enable extra Mac fonts support on non-Mac platforms (e.g. */ + /* GNU/Linux). */ + /* */ + /* Resource forks which include fonts data are stored sometimes in */ + /* locations which users or developers don't expected. In some cases, */ + /* resource forks start with some offset from the head of a file. In */ + /* other cases, the actual resource fork is stored in file different */ + /* from what the user specifies. If this option is activated, */ + /* FreeType tries to guess whether such offsets or different file */ + /* names must be used. */ + /* */ + /* Note that normal, direct access of resource forks is controlled via */ + /* the FT_CONFIG_OPTION_MAC_FONTS option. */ + /* */ +#ifdef FT_CONFIG_OPTION_MAC_FONTS +#define FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK +#endif + + + /*************************************************************************/ + /* */ + /* Allow the use of FT_Incremental_Interface to load typefaces that */ + /* contain no glyph data, but supply it via a callback function. */ + /* This allows FreeType to be used with the PostScript language, using */ + /* the GhostScript interpreter. */ + /* */ +/* #define FT_CONFIG_OPTION_INCREMENTAL */ + + + /*************************************************************************/ + /* */ + /* The size in bytes of the render pool used by the scan-line converter */ + /* to do all of its work. */ + /* */ + /* This must be greater than 4KByte if you use FreeType to rasterize */ + /* glyphs; otherwise, you may set it to zero to avoid unnecessary */ + /* allocation of the render pool. */ + /* */ +#define FT_RENDER_POOL_SIZE 65536L + + + /*************************************************************************/ + /* */ + /* FT_MAX_MODULES */ + /* */ + /* The maximum number of modules that can be registered in a single */ + /* FreeType library object. 32 is the default. */ + /* */ +#define FT_MAX_MODULES 32 + + + /*************************************************************************/ + /* */ + /* Debug level */ + /* */ + /* FreeType can be compiled in debug or trace mode. In debug mode, */ + /* errors are reported through the `ftdebug' component. In trace */ + /* mode, additional messages are sent to the standard output during */ + /* execution. */ + /* */ + /* Define FT_DEBUG_LEVEL_ERROR to build the library in debug mode. */ + /* Define FT_DEBUG_LEVEL_TRACE to build it in trace mode. */ + /* */ + /* Don't define any of these macros to compile in `release' mode! */ + /* */ + /* Do not #undef these macros here since the build system might define */ + /* them for certain configurations only. */ + /* */ +/* #define FT_DEBUG_LEVEL_ERROR */ +/* #define FT_DEBUG_LEVEL_TRACE */ + + + /*************************************************************************/ + /* */ + /* Memory Debugging */ + /* */ + /* FreeType now comes with an integrated memory debugger that is */ + /* capable of detecting simple errors like memory leaks or double */ + /* deletes. To compile it within your build of the library, you */ + /* should define FT_DEBUG_MEMORY here. */ + /* */ + /* Note that the memory debugger is only activated at runtime when */ + /* when the _environment_ variable `FT2_DEBUG_MEMORY' is defined also! */ + /* */ + /* Do not #undef this macro here since the build system might define */ + /* it for certain configurations only. */ + /* */ +/* #define FT_DEBUG_MEMORY */ + + + /*************************************************************************/ + /* */ + /* Module errors */ + /* */ + /* If this macro is set (which is _not_ the default), the higher byte */ + /* of an error code gives the module in which the error has occurred, */ + /* while the lower byte is the real error code. */ + /* */ + /* Setting this macro makes sense for debugging purposes only, since */ + /* it would break source compatibility of certain programs that use */ + /* FreeType 2. */ + /* */ + /* More details can be found in the files ftmoderr.h and fterrors.h. */ + /* */ +#undef FT_CONFIG_OPTION_USE_MODULE_ERRORS + + + /*************************************************************************/ + /* */ + /* Position Independent Code */ + /* */ + /* If this macro is set (which is _not_ the default), FreeType2 will */ + /* avoid creating constants that require address fixups. Instead the */ + /* constants will be moved into a struct and additional intialization */ + /* code will be used. */ + /* */ + /* Setting this macro is needed for systems that prohibit address */ + /* fixups, such as BREW. */ + /* */ +/* #define FT_CONFIG_OPTION_PIC */ + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** S F N T D R I V E R C O N F I G U R A T I O N ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_EMBEDDED_BITMAPS if you want to support */ + /* embedded bitmaps in all formats using the SFNT module (namely */ + /* TrueType & OpenType). */ + /* */ +#define TT_CONFIG_OPTION_EMBEDDED_BITMAPS + + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_POSTSCRIPT_NAMES if you want to be able to */ + /* load and enumerate the glyph Postscript names in a TrueType or */ + /* OpenType file. */ + /* */ + /* Note that when you do not compile the `PSNames' module by undefining */ + /* the above FT_CONFIG_OPTION_POSTSCRIPT_NAMES, the `sfnt' module will */ + /* contain additional code used to read the PS Names table from a font. */ + /* */ + /* (By default, the module uses `PSNames' to extract glyph names.) */ + /* */ +#define TT_CONFIG_OPTION_POSTSCRIPT_NAMES + + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_SFNT_NAMES if your applications need to */ + /* access the internal name table in a SFNT-based format like TrueType */ + /* or OpenType. The name table contains various strings used to */ + /* describe the font, like family name, copyright, version, etc. It */ + /* does not contain any glyph name though. */ + /* */ + /* Accessing SFNT names is done through the functions declared in */ + /* `freetype/ftsnames.h'. */ + /* */ +#define TT_CONFIG_OPTION_SFNT_NAMES + + + /*************************************************************************/ + /* */ + /* TrueType CMap support */ + /* */ + /* Here you can fine-tune which TrueType CMap table format shall be */ + /* supported. */ +#define TT_CONFIG_CMAP_FORMAT_0 +#define TT_CONFIG_CMAP_FORMAT_2 +#define TT_CONFIG_CMAP_FORMAT_4 +#define TT_CONFIG_CMAP_FORMAT_6 +#define TT_CONFIG_CMAP_FORMAT_8 +#define TT_CONFIG_CMAP_FORMAT_10 +#define TT_CONFIG_CMAP_FORMAT_12 +#define TT_CONFIG_CMAP_FORMAT_13 +#define TT_CONFIG_CMAP_FORMAT_14 + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** T R U E T Y P E D R I V E R C O N F I G U R A T I O N ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_BYTECODE_INTERPRETER if you want to compile */ + /* a bytecode interpreter in the TrueType driver. Note that there are */ + /* important patent issues related to the use of the interpreter. */ + /* */ + /* By undefining this, you will only compile the code necessary to load */ + /* TrueType glyphs without hinting. */ + /* */ + /* Do not #undef this macro here, since the build system might */ + /* define it for certain configurations only. */ + /* */ +/* #define TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ + + + /*************************************************************************/ + /* */ + /* If you define TT_CONFIG_OPTION_UNPATENTED_HINTING, a special version */ + /* of the TrueType bytecode interpreter is used that doesn't implement */ + /* any of the patented opcodes and algorithms. Note that the */ + /* TT_CONFIG_OPTION_UNPATENTED_HINTING macro is *ignored* if you define */ + /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER; in other words, either define */ + /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER or */ + /* TT_CONFIG_OPTION_UNPATENTED_HINTING but not both at the same time. */ + /* */ + /* This macro is only useful for a small number of font files (mostly */ + /* for Asian scripts) that require bytecode interpretation to properly */ + /* load glyphs. For all other fonts, this produces unpleasant results, */ + /* thus the unpatented interpreter is never used to load glyphs from */ + /* TrueType fonts unless one of the following two options is used. */ + /* */ + /* - The unpatented interpreter is explicitly activated by the user */ + /* through the FT_PARAM_TAG_UNPATENTED_HINTING parameter tag */ + /* when opening the FT_Face. */ + /* */ + /* - FreeType detects that the FT_Face corresponds to one of the */ + /* `trick' fonts (e.g., `Mingliu') it knows about. The font engine */ + /* contains a hard-coded list of font names and other matching */ + /* parameters (see function `tt_face_init' in file */ + /* `src/truetype/ttobjs.c'). */ + /* */ + /* Here a sample code snippet for using FT_PARAM_TAG_UNPATENTED_HINTING. */ + /* */ + /* { */ + /* FT_Parameter parameter; */ + /* FT_Open_Args open_args; */ + /* */ + /* */ + /* parameter.tag = FT_PARAM_TAG_UNPATENTED_HINTING; */ + /* */ + /* open_args.flags = FT_OPEN_PATHNAME | FT_OPEN_PARAMS; */ + /* open_args.pathname = my_font_pathname; */ + /* open_args.num_params = 1; */ + /* open_args.params = ¶meter; */ + /* */ + /* error = FT_Open_Face( library, &open_args, index, &face ); */ + /* ... */ + /* } */ + /* */ +#define TT_CONFIG_OPTION_UNPATENTED_HINTING + + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_INTERPRETER_SWITCH to compile the TrueType */ + /* bytecode interpreter with a huge switch statement, rather than a call */ + /* table. This results in smaller and faster code for a number of */ + /* architectures. */ + /* */ + /* Note however that on some compiler/processor combinations, undefining */ + /* this macro will generate faster, though larger, code. */ + /* */ +#define TT_CONFIG_OPTION_INTERPRETER_SWITCH + + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED to compile the */ + /* TrueType glyph loader to use Apple's definition of how to handle */ + /* component offsets in composite glyphs. */ + /* */ + /* Apple and MS disagree on the default behavior of component offsets */ + /* in composites. Apple says that they should be scaled by the scaling */ + /* factors in the transformation matrix (roughly, it's more complex) */ + /* while MS says they should not. OpenType defines two bits in the */ + /* composite flags array which can be used to disambiguate, but old */ + /* fonts will not have them. */ + /* */ + /* http://partners.adobe.com/asn/developer/opentype/glyf.html */ + /* http://fonts.apple.com/TTRefMan/RM06/Chap6glyf.html */ + /* */ +#undef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED + + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_GX_VAR_SUPPORT if you want to include */ + /* support for Apple's distortable font technology (fvar, gvar, cvar, */ + /* and avar tables). This has many similarities to Type 1 Multiple */ + /* Masters support. */ + /* */ +#define TT_CONFIG_OPTION_GX_VAR_SUPPORT + + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_BDF if you want to include support for */ + /* an embedded `BDF ' table within SFNT-based bitmap formats. */ + /* */ +#define TT_CONFIG_OPTION_BDF + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** T Y P E 1 D R I V E R C O N F I G U R A T I O N ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* T1_MAX_DICT_DEPTH is the maximal depth of nest dictionaries and */ + /* arrays in the Type 1 stream (see t1load.c). A minimum of 4 is */ + /* required. */ + /* */ +#define T1_MAX_DICT_DEPTH 5 + + + /*************************************************************************/ + /* */ + /* T1_MAX_SUBRS_CALLS details the maximum number of nested sub-routine */ + /* calls during glyph loading. */ + /* */ +#define T1_MAX_SUBRS_CALLS 16 + + + /*************************************************************************/ + /* */ + /* T1_MAX_CHARSTRING_OPERANDS is the charstring stack's capacity. A */ + /* minimum of 16 is required. */ + /* */ + /* The Chinese font MingTiEG-Medium (CNS 11643 character set) needs 256. */ + /* */ +#define T1_MAX_CHARSTRINGS_OPERANDS 256 + + + /*************************************************************************/ + /* */ + /* Define this configuration macro if you want to prevent the */ + /* compilation of `t1afm', which is in charge of reading Type 1 AFM */ + /* files into an existing face. Note that if set, the T1 driver will be */ + /* unable to produce kerning distances. */ + /* */ +#undef T1_CONFIG_OPTION_NO_AFM + + + /*************************************************************************/ + /* */ + /* Define this configuration macro if you want to prevent the */ + /* compilation of the Multiple Masters font support in the Type 1 */ + /* driver. */ + /* */ +#undef T1_CONFIG_OPTION_NO_MM_SUPPORT + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** A U T O F I T M O D U L E C O N F I G U R A T I O N ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* Compile autofit module with CJK (Chinese, Japanese, Korean) script */ + /* support. */ + /* */ +#define AF_CONFIG_OPTION_CJK + + /*************************************************************************/ + /* */ + /* Compile autofit module with Indic script support. */ + /* */ +#define AF_CONFIG_OPTION_INDIC + + /* */ + + + /* + * Define this variable if you want to keep the layout of internal + * structures that was used prior to FreeType 2.2. This also compiles in + * a few obsolete functions to avoid linking problems on typical Unix + * distributions. + * + * For embedded systems or building a new distribution from scratch, it + * is recommended to disable the macro since it reduces the library's code + * size and activates a few memory-saving optimizations as well. + */ +#define FT_CONFIG_OPTION_OLD_INTERNALS + + + /* + * This macro is defined if either unpatented or native TrueType + * hinting is requested by the definitions above. + */ +#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER +#define TT_USE_BYTECODE_INTERPRETER +#undef TT_CONFIG_OPTION_UNPATENTED_HINTING +#elif defined TT_CONFIG_OPTION_UNPATENTED_HINTING +#define TT_USE_BYTECODE_INTERPRETER +#endif + +FT_END_HEADER + + +#endif /* __FTOPTION_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/config/ftstdlib.h b/mod/pub.mod/freetype.mod/include/freetype/config/ftstdlib.h new file mode 100644 index 0000000..30ec14e --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/config/ftstdlib.h @@ -0,0 +1,173 @@ +/***************************************************************************/ +/* */ +/* ftstdlib.h */ +/* */ +/* ANSI-specific library and header configuration file (specification */ +/* only). */ +/* */ +/* Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file is used to group all #includes to the ANSI C library that */ + /* FreeType normally requires. It also defines macros to rename the */ + /* standard functions within the FreeType source code. */ + /* */ + /* Load a file which defines __FTSTDLIB_H__ before this one to override */ + /* it. */ + /* */ + /*************************************************************************/ + + +#ifndef __FTSTDLIB_H__ +#define __FTSTDLIB_H__ + + +#include <stddef.h> + +#define ft_ptrdiff_t ptrdiff_t + + + /**********************************************************************/ + /* */ + /* integer limits */ + /* */ + /* UINT_MAX and ULONG_MAX are used to automatically compute the size */ + /* of `int' and `long' in bytes at compile-time. So far, this works */ + /* for all platforms the library has been tested on. */ + /* */ + /* Note that on the extremely rare platforms that do not provide */ + /* integer types that are _exactly_ 16 and 32 bits wide (e.g. some */ + /* old Crays where `int' is 36 bits), we do not make any guarantee */ + /* about the correct behaviour of FT2 with all fonts. */ + /* */ + /* In these case, `ftconfig.h' will refuse to compile anyway with a */ + /* message like `couldn't find 32-bit type' or something similar. */ + /* */ + /**********************************************************************/ + + +#include <limits.h> + +#define FT_CHAR_BIT CHAR_BIT +#define FT_INT_MAX INT_MAX +#define FT_INT_MIN INT_MIN +#define FT_UINT_MAX UINT_MAX +#define FT_ULONG_MAX ULONG_MAX + + + /**********************************************************************/ + /* */ + /* character and string processing */ + /* */ + /**********************************************************************/ + + +#include <string.h> + +#define ft_memchr memchr +#define ft_memcmp memcmp +#define ft_memcpy memcpy +#define ft_memmove memmove +#define ft_memset memset +#define ft_strcat strcat +#define ft_strcmp strcmp +#define ft_strcpy strcpy +#define ft_strlen strlen +#define ft_strncmp strncmp +#define ft_strncpy strncpy +#define ft_strrchr strrchr +#define ft_strstr strstr + + + /**********************************************************************/ + /* */ + /* file handling */ + /* */ + /**********************************************************************/ + + +#include <stdio.h> + +#define FT_FILE FILE +#define ft_fclose fclose +#define ft_fopen fopen +#define ft_fread fread +#define ft_fseek fseek +#define ft_ftell ftell +#define ft_sprintf sprintf + + + /**********************************************************************/ + /* */ + /* sorting */ + /* */ + /**********************************************************************/ + + +#include <stdlib.h> + +#define ft_qsort qsort + + + /**********************************************************************/ + /* */ + /* memory allocation */ + /* */ + /**********************************************************************/ + + +#define ft_scalloc calloc +#define ft_sfree free +#define ft_smalloc malloc +#define ft_srealloc realloc + + + /**********************************************************************/ + /* */ + /* miscellaneous */ + /* */ + /**********************************************************************/ + + +#define ft_atol atol +#define ft_labs labs + + + /**********************************************************************/ + /* */ + /* execution control */ + /* */ + /**********************************************************************/ + + +#include <setjmp.h> + +#define ft_jmp_buf jmp_buf /* note: this cannot be a typedef since */ + /* jmp_buf is defined as a macro */ + /* on certain platforms */ + +#define ft_longjmp longjmp +#define ft_setjmp( b ) setjmp( *(jmp_buf*) &(b) ) /* same thing here */ + + + /* the following is only used for debugging purposes, i.e., if */ + /* FT_DEBUG_LEVEL_ERROR or FT_DEBUG_LEVEL_TRACE are defined */ + +#include <stdarg.h> + + +#endif /* __FTSTDLIB_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/freetype.h b/mod/pub.mod/freetype.mod/include/freetype/freetype.h new file mode 100644 index 0000000..9e74f11 --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/freetype.h @@ -0,0 +1,3868 @@ +/***************************************************************************/ +/* */ +/* freetype.h */ +/* */ +/* FreeType high-level API and common types (specification only). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef FT_FREETYPE_H +#error "`ft2build.h' hasn't been included yet!" +#error "Please always use macros to include FreeType header files." +#error "Example:" +#error " #include <ft2build.h>" +#error " #include FT_FREETYPE_H" +#endif + + +#ifndef __FREETYPE_H__ +#define __FREETYPE_H__ + + +#include <ft2build.h> +#include FT_CONFIG_CONFIG_H +#include FT_ERRORS_H +#include FT_TYPES_H + + +FT_BEGIN_HEADER + + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* user_allocation */ + /* */ + /* <Title> */ + /* User allocation */ + /* */ + /* <Abstract> */ + /* How client applications should allocate FreeType data structures. */ + /* */ + /* <Description> */ + /* FreeType assumes that structures allocated by the user and passed */ + /* as arguments are zeroed out except for the actual data. In other */ + /* words, it is recommended to use `calloc' (or variants of it) */ + /* instead of `malloc' for allocation. */ + /* */ + /*************************************************************************/ + + + + /*************************************************************************/ + /*************************************************************************/ + /* */ + /* B A S I C T Y P E S */ + /* */ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* base_interface */ + /* */ + /* <Title> */ + /* Base Interface */ + /* */ + /* <Abstract> */ + /* The FreeType~2 base font interface. */ + /* */ + /* <Description> */ + /* This section describes the public high-level API of FreeType~2. */ + /* */ + /* <Order> */ + /* FT_Library */ + /* FT_Face */ + /* FT_Size */ + /* FT_GlyphSlot */ + /* FT_CharMap */ + /* FT_Encoding */ + /* */ + /* FT_FaceRec */ + /* */ + /* FT_FACE_FLAG_SCALABLE */ + /* FT_FACE_FLAG_FIXED_SIZES */ + /* FT_FACE_FLAG_FIXED_WIDTH */ + /* FT_FACE_FLAG_HORIZONTAL */ + /* FT_FACE_FLAG_VERTICAL */ + /* FT_FACE_FLAG_SFNT */ + /* FT_FACE_FLAG_KERNING */ + /* FT_FACE_FLAG_MULTIPLE_MASTERS */ + /* FT_FACE_FLAG_GLYPH_NAMES */ + /* FT_FACE_FLAG_EXTERNAL_STREAM */ + /* FT_FACE_FLAG_FAST_GLYPHS */ + /* FT_FACE_FLAG_HINTER */ + /* */ + /* FT_STYLE_FLAG_BOLD */ + /* FT_STYLE_FLAG_ITALIC */ + /* */ + /* FT_SizeRec */ + /* FT_Size_Metrics */ + /* */ + /* FT_GlyphSlotRec */ + /* FT_Glyph_Metrics */ + /* FT_SubGlyph */ + /* */ + /* FT_Bitmap_Size */ + /* */ + /* FT_Init_FreeType */ + /* FT_Done_FreeType */ + /* */ + /* FT_New_Face */ + /* FT_Done_Face */ + /* FT_New_Memory_Face */ + /* FT_Open_Face */ + /* FT_Open_Args */ + /* FT_Parameter */ + /* FT_Attach_File */ + /* FT_Attach_Stream */ + /* */ + /* FT_Set_Char_Size */ + /* FT_Set_Pixel_Sizes */ + /* FT_Request_Size */ + /* FT_Select_Size */ + /* FT_Size_Request_Type */ + /* FT_Size_Request */ + /* FT_Set_Transform */ + /* FT_Load_Glyph */ + /* FT_Get_Char_Index */ + /* FT_Get_Name_Index */ + /* FT_Load_Char */ + /* */ + /* FT_OPEN_MEMORY */ + /* FT_OPEN_STREAM */ + /* FT_OPEN_PATHNAME */ + /* FT_OPEN_DRIVER */ + /* FT_OPEN_PARAMS */ + /* */ + /* FT_LOAD_DEFAULT */ + /* FT_LOAD_RENDER */ + /* FT_LOAD_MONOCHROME */ + /* FT_LOAD_LINEAR_DESIGN */ + /* FT_LOAD_NO_SCALE */ + /* FT_LOAD_NO_HINTING */ + /* FT_LOAD_NO_BITMAP */ + /* FT_LOAD_CROP_BITMAP */ + /* */ + /* FT_LOAD_VERTICAL_LAYOUT */ + /* FT_LOAD_IGNORE_TRANSFORM */ + /* FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH */ + /* FT_LOAD_FORCE_AUTOHINT */ + /* FT_LOAD_NO_RECURSE */ + /* FT_LOAD_PEDANTIC */ + /* */ + /* FT_LOAD_TARGET_NORMAL */ + /* FT_LOAD_TARGET_LIGHT */ + /* FT_LOAD_TARGET_MONO */ + /* FT_LOAD_TARGET_LCD */ + /* FT_LOAD_TARGET_LCD_V */ + /* */ + /* FT_Render_Glyph */ + /* FT_Render_Mode */ + /* FT_Get_Kerning */ + /* FT_Kerning_Mode */ + /* FT_Get_Track_Kerning */ + /* FT_Get_Glyph_Name */ + /* FT_Get_Postscript_Name */ + /* */ + /* FT_CharMapRec */ + /* FT_Select_Charmap */ + /* FT_Set_Charmap */ + /* FT_Get_Charmap_Index */ + /* */ + /* FT_FSTYPE_INSTALLABLE_EMBEDDING */ + /* FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING */ + /* FT_FSTYPE_PREVIEW_AND_PRINT_EMBEDDING */ + /* FT_FSTYPE_EDITABLE_EMBEDDING */ + /* FT_FSTYPE_NO_SUBSETTING */ + /* FT_FSTYPE_BITMAP_EMBEDDING_ONLY */ + /* */ + /* FT_Get_FSType_Flags */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Glyph_Metrics */ + /* */ + /* <Description> */ + /* A structure used to model the metrics of a single glyph. The */ + /* values are expressed in 26.6 fractional pixel format; if the flag */ + /* @FT_LOAD_NO_SCALE has been used while loading the glyph, values */ + /* are expressed in font units instead. */ + /* */ + /* <Fields> */ + /* width :: */ + /* The glyph's width. */ + /* */ + /* height :: */ + /* The glyph's height. */ + /* */ + /* horiBearingX :: */ + /* Left side bearing for horizontal layout. */ + /* */ + /* horiBearingY :: */ + /* Top side bearing for horizontal layout. */ + /* */ + /* horiAdvance :: */ + /* Advance width for horizontal layout. */ + /* */ + /* vertBearingX :: */ + /* Left side bearing for vertical layout. */ + /* */ + /* vertBearingY :: */ + /* Top side bearing for vertical layout. */ + /* */ + /* vertAdvance :: */ + /* Advance height for vertical layout. */ + /* */ + typedef struct FT_Glyph_Metrics_ + { + FT_Pos width; + FT_Pos height; + + FT_Pos horiBearingX; + FT_Pos horiBearingY; + FT_Pos horiAdvance; + + FT_Pos vertBearingX; + FT_Pos vertBearingY; + FT_Pos vertAdvance; + + } FT_Glyph_Metrics; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Bitmap_Size */ + /* */ + /* <Description> */ + /* This structure models the metrics of a bitmap strike (i.e., a set */ + /* of glyphs for a given point size and resolution) in a bitmap font. */ + /* It is used for the `available_sizes' field of @FT_Face. */ + /* */ + /* <Fields> */ + /* height :: The vertical distance, in pixels, between two */ + /* consecutive baselines. It is always positive. */ + /* */ + /* width :: The average width, in pixels, of all glyphs in the */ + /* strike. */ + /* */ + /* size :: The nominal size of the strike in 26.6 fractional */ + /* points. This field is not very useful. */ + /* */ + /* x_ppem :: The horizontal ppem (nominal width) in 26.6 fractional */ + /* pixels. */ + /* */ + /* y_ppem :: The vertical ppem (nominal height) in 26.6 fractional */ + /* pixels. */ + /* */ + /* <Note> */ + /* Windows FNT: */ + /* The nominal size given in a FNT font is not reliable. Thus when */ + /* the driver finds it incorrect, it sets `size' to some calculated */ + /* values and sets `x_ppem' and `y_ppem' to the pixel width and */ + /* height given in the font, respectively. */ + /* */ + /* TrueType embedded bitmaps: */ + /* `size', `width', and `height' values are not contained in the */ + /* bitmap strike itself. They are computed from the global font */ + /* parameters. */ + /* */ + typedef struct FT_Bitmap_Size_ + { + FT_Short height; + FT_Short width; + + FT_Pos size; + + FT_Pos x_ppem; + FT_Pos y_ppem; + + } FT_Bitmap_Size; + + + /*************************************************************************/ + /*************************************************************************/ + /* */ + /* O B J E C T C L A S S E S */ + /* */ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Library */ + /* */ + /* <Description> */ + /* A handle to a FreeType library instance. Each `library' is */ + /* completely independent from the others; it is the `root' of a set */ + /* of objects like fonts, faces, sizes, etc. */ + /* */ + /* It also embeds a memory manager (see @FT_Memory), as well as a */ + /* scan-line converter object (see @FT_Raster). */ + /* */ + /* For multi-threading applications each thread should have its own */ + /* FT_Library object. */ + /* */ + /* <Note> */ + /* Library objects are normally created by @FT_Init_FreeType, and */ + /* destroyed with @FT_Done_FreeType. */ + /* */ + typedef struct FT_LibraryRec_ *FT_Library; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Module */ + /* */ + /* <Description> */ + /* A handle to a given FreeType module object. Each module can be a */ + /* font driver, a renderer, or anything else that provides services */ + /* to the formers. */ + /* */ + typedef struct FT_ModuleRec_* FT_Module; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Driver */ + /* */ + /* <Description> */ + /* A handle to a given FreeType font driver object. Each font driver */ + /* is a special module capable of creating faces from font files. */ + /* */ + typedef struct FT_DriverRec_* FT_Driver; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Renderer */ + /* */ + /* <Description> */ + /* A handle to a given FreeType renderer. A renderer is a special */ + /* module in charge of converting a glyph image to a bitmap, when */ + /* necessary. Each renderer supports a given glyph image format, and */ + /* one or more target surface depths. */ + /* */ + typedef struct FT_RendererRec_* FT_Renderer; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Face */ + /* */ + /* <Description> */ + /* A handle to a given typographic face object. A face object models */ + /* a given typeface, in a given style. */ + /* */ + /* <Note> */ + /* Each face object also owns a single @FT_GlyphSlot object, as well */ + /* as one or more @FT_Size objects. */ + /* */ + /* Use @FT_New_Face or @FT_Open_Face to create a new face object from */ + /* a given filepathname or a custom input stream. */ + /* */ + /* Use @FT_Done_Face to destroy it (along with its slot and sizes). */ + /* */ + /* <Also> */ + /* See @FT_FaceRec for the publicly accessible fields of a given face */ + /* object. */ + /* */ + typedef struct FT_FaceRec_* FT_Face; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Size */ + /* */ + /* <Description> */ + /* A handle to an object used to model a face scaled to a given */ + /* character size. */ + /* */ + /* <Note> */ + /* Each @FT_Face has an _active_ @FT_Size object that is used by */ + /* functions like @FT_Load_Glyph to determine the scaling */ + /* transformation which is used to load and hint glyphs and metrics. */ + /* */ + /* You can use @FT_Set_Char_Size, @FT_Set_Pixel_Sizes, */ + /* @FT_Request_Size or even @FT_Select_Size to change the content */ + /* (i.e., the scaling values) of the active @FT_Size. */ + /* */ + /* You can use @FT_New_Size to create additional size objects for a */ + /* given @FT_Face, but they won't be used by other functions until */ + /* you activate it through @FT_Activate_Size. Only one size can be */ + /* activated at any given time per face. */ + /* */ + /* <Also> */ + /* See @FT_SizeRec for the publicly accessible fields of a given size */ + /* object. */ + /* */ + typedef struct FT_SizeRec_* FT_Size; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_GlyphSlot */ + /* */ + /* <Description> */ + /* A handle to a given `glyph slot'. A slot is a container where it */ + /* is possible to load any of the glyphs contained in its parent */ + /* face. */ + /* */ + /* In other words, each time you call @FT_Load_Glyph or */ + /* @FT_Load_Char, the slot's content is erased by the new glyph data, */ + /* i.e., the glyph's metrics, its image (bitmap or outline), and */ + /* other control information. */ + /* */ + /* <Also> */ + /* See @FT_GlyphSlotRec for the publicly accessible glyph fields. */ + /* */ + typedef struct FT_GlyphSlotRec_* FT_GlyphSlot; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_CharMap */ + /* */ + /* <Description> */ + /* A handle to a given character map. A charmap is used to translate */ + /* character codes in a given encoding into glyph indexes for its */ + /* parent's face. Some font formats may provide several charmaps per */ + /* font. */ + /* */ + /* Each face object owns zero or more charmaps, but only one of them */ + /* can be `active' and used by @FT_Get_Char_Index or @FT_Load_Char. */ + /* */ + /* The list of available charmaps in a face is available through the */ + /* `face->num_charmaps' and `face->charmaps' fields of @FT_FaceRec. */ + /* */ + /* The currently active charmap is available as `face->charmap'. */ + /* You should call @FT_Set_Charmap to change it. */ + /* */ + /* <Note> */ + /* When a new face is created (either through @FT_New_Face or */ + /* @FT_Open_Face), the library looks for a Unicode charmap within */ + /* the list and automatically activates it. */ + /* */ + /* <Also> */ + /* See @FT_CharMapRec for the publicly accessible fields of a given */ + /* character map. */ + /* */ + typedef struct FT_CharMapRec_* FT_CharMap; + + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_ENC_TAG */ + /* */ + /* <Description> */ + /* This macro converts four-letter tags into an unsigned long. It is */ + /* used to define `encoding' identifiers (see @FT_Encoding). */ + /* */ + /* <Note> */ + /* Since many 16-bit compilers don't like 32-bit enumerations, you */ + /* should redefine this macro in case of problems to something like */ + /* this: */ + /* */ + /* { */ + /* #define FT_ENC_TAG( value, a, b, c, d ) value */ + /* } */ + /* */ + /* to get a simple enumeration without assigning special numbers. */ + /* */ + +#ifndef FT_ENC_TAG +#define FT_ENC_TAG( value, a, b, c, d ) \ + value = ( ( (FT_UInt32)(a) << 24 ) | \ + ( (FT_UInt32)(b) << 16 ) | \ + ( (FT_UInt32)(c) << 8 ) | \ + (FT_UInt32)(d) ) + +#endif /* FT_ENC_TAG */ + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Encoding */ + /* */ + /* <Description> */ + /* An enumeration used to specify character sets supported by */ + /* charmaps. Used in the @FT_Select_Charmap API function. */ + /* */ + /* <Note> */ + /* Despite the name, this enumeration lists specific character */ + /* repertories (i.e., charsets), and not text encoding methods (e.g., */ + /* UTF-8, UTF-16, etc.). */ + /* */ + /* Other encodings might be defined in the future. */ + /* */ + /* <Values> */ + /* FT_ENCODING_NONE :: */ + /* The encoding value~0 is reserved. */ + /* */ + /* FT_ENCODING_UNICODE :: */ + /* Corresponds to the Unicode character set. This value covers */ + /* all versions of the Unicode repertoire, including ASCII and */ + /* Latin-1. Most fonts include a Unicode charmap, but not all */ + /* of them. */ + /* */ + /* For example, if you want to access Unicode value U+1F028 (and */ + /* the font contains it), use value 0x1F028 as the input value for */ + /* @FT_Get_Char_Index. */ + /* */ + /* FT_ENCODING_MS_SYMBOL :: */ + /* Corresponds to the Microsoft Symbol encoding, used to encode */ + /* mathematical symbols in the 32..255 character code range. For */ + /* more information, see `http://www.ceviz.net/symbol.htm'. */ + /* */ + /* FT_ENCODING_SJIS :: */ + /* Corresponds to Japanese SJIS encoding. More info at */ + /* at `http://langsupport.japanreference.com/encoding.shtml'. */ + /* See note on multi-byte encodings below. */ + /* */ + /* FT_ENCODING_GB2312 :: */ + /* Corresponds to an encoding system for Simplified Chinese as used */ + /* used in mainland China. */ + /* */ + /* FT_ENCODING_BIG5 :: */ + /* Corresponds to an encoding system for Traditional Chinese as */ + /* used in Taiwan and Hong Kong. */ + /* */ + /* FT_ENCODING_WANSUNG :: */ + /* Corresponds to the Korean encoding system known as Wansung. */ + /* For more information see */ + /* `http://www.microsoft.com/typography/unicode/949.txt'. */ + /* */ + /* FT_ENCODING_JOHAB :: */ + /* The Korean standard character set (KS~C 5601-1992), which */ + /* corresponds to MS Windows code page 1361. This character set */ + /* includes all possible Hangeul character combinations. */ + /* */ + /* FT_ENCODING_ADOBE_LATIN_1 :: */ + /* Corresponds to a Latin-1 encoding as defined in a Type~1 */ + /* PostScript font. It is limited to 256 character codes. */ + /* */ + /* FT_ENCODING_ADOBE_STANDARD :: */ + /* Corresponds to the Adobe Standard encoding, as found in Type~1, */ + /* CFF, and OpenType/CFF fonts. It is limited to 256 character */ + /* codes. */ + /* */ + /* FT_ENCODING_ADOBE_EXPERT :: */ + /* Corresponds to the Adobe Expert encoding, as found in Type~1, */ + /* CFF, and OpenType/CFF fonts. It is limited to 256 character */ + /* codes. */ + /* */ + /* FT_ENCODING_ADOBE_CUSTOM :: */ + /* Corresponds to a custom encoding, as found in Type~1, CFF, and */ + /* OpenType/CFF fonts. It is limited to 256 character codes. */ + /* */ + /* FT_ENCODING_APPLE_ROMAN :: */ + /* Corresponds to the 8-bit Apple roman encoding. Many TrueType */ + /* and OpenType fonts contain a charmap for this encoding, since */ + /* older versions of Mac OS are able to use it. */ + /* */ + /* FT_ENCODING_OLD_LATIN_2 :: */ + /* This value is deprecated and was never used nor reported by */ + /* FreeType. Don't use or test for it. */ + /* */ + /* FT_ENCODING_MS_SJIS :: */ + /* Same as FT_ENCODING_SJIS. Deprecated. */ + /* */ + /* FT_ENCODING_MS_GB2312 :: */ + /* Same as FT_ENCODING_GB2312. Deprecated. */ + /* */ + /* FT_ENCODING_MS_BIG5 :: */ + /* Same as FT_ENCODING_BIG5. Deprecated. */ + /* */ + /* FT_ENCODING_MS_WANSUNG :: */ + /* Same as FT_ENCODING_WANSUNG. Deprecated. */ + /* */ + /* FT_ENCODING_MS_JOHAB :: */ + /* Same as FT_ENCODING_JOHAB. Deprecated. */ + /* */ + /* <Note> */ + /* By default, FreeType automatically synthesizes a Unicode charmap */ + /* for PostScript fonts, using their glyph names dictionaries. */ + /* However, it also reports the encodings defined explicitly in the */ + /* font file, for the cases when they are needed, with the Adobe */ + /* values as well. */ + /* */ + /* FT_ENCODING_NONE is set by the BDF and PCF drivers if the charmap */ + /* is neither Unicode nor ISO-8859-1 (otherwise it is set to */ + /* FT_ENCODING_UNICODE). Use @FT_Get_BDF_Charset_ID to find out */ + /* which encoding is really present. If, for example, the */ + /* `cs_registry' field is `KOI8' and the `cs_encoding' field is `R', */ + /* the font is encoded in KOI8-R. */ + /* */ + /* FT_ENCODING_NONE is always set (with a single exception) by the */ + /* winfonts driver. Use @FT_Get_WinFNT_Header and examine the */ + /* `charset' field of the @FT_WinFNT_HeaderRec structure to find out */ + /* which encoding is really present. For example, */ + /* @FT_WinFNT_ID_CP1251 (204) means Windows code page 1251 (for */ + /* Russian). */ + /* */ + /* FT_ENCODING_NONE is set if `platform_id' is @TT_PLATFORM_MACINTOSH */ + /* and `encoding_id' is not @TT_MAC_ID_ROMAN (otherwise it is set to */ + /* FT_ENCODING_APPLE_ROMAN). */ + /* */ + /* If `platform_id' is @TT_PLATFORM_MACINTOSH, use the function */ + /* @FT_Get_CMap_Language_ID to query the Mac language ID which may */ + /* be needed to be able to distinguish Apple encoding variants. See */ + /* */ + /* http://www.unicode.org/Public/MAPPINGS/VENDORS/APPLE/README.TXT */ + /* */ + /* to get an idea how to do that. Basically, if the language ID */ + /* is~0, don't use it, otherwise subtract 1 from the language ID. */ + /* Then examine `encoding_id'. If, for example, `encoding_id' is */ + /* @TT_MAC_ID_ROMAN and the language ID (minus~1) is */ + /* `TT_MAC_LANGID_GREEK', it is the Greek encoding, not Roman. */ + /* @TT_MAC_ID_ARABIC with `TT_MAC_LANGID_FARSI' means the Farsi */ + /* variant the Arabic encoding. */ + /* */ + typedef enum FT_Encoding_ + { + FT_ENC_TAG( FT_ENCODING_NONE, 0, 0, 0, 0 ), + + FT_ENC_TAG( FT_ENCODING_MS_SYMBOL, 's', 'y', 'm', 'b' ), + FT_ENC_TAG( FT_ENCODING_UNICODE, 'u', 'n', 'i', 'c' ), + + FT_ENC_TAG( FT_ENCODING_SJIS, 's', 'j', 'i', 's' ), + FT_ENC_TAG( FT_ENCODING_GB2312, 'g', 'b', ' ', ' ' ), + FT_ENC_TAG( FT_ENCODING_BIG5, 'b', 'i', 'g', '5' ), + FT_ENC_TAG( FT_ENCODING_WANSUNG, 'w', 'a', 'n', 's' ), + FT_ENC_TAG( FT_ENCODING_JOHAB, 'j', 'o', 'h', 'a' ), + + /* for backwards compatibility */ + FT_ENCODING_MS_SJIS = FT_ENCODING_SJIS, + FT_ENCODING_MS_GB2312 = FT_ENCODING_GB2312, + FT_ENCODING_MS_BIG5 = FT_ENCODING_BIG5, + FT_ENCODING_MS_WANSUNG = FT_ENCODING_WANSUNG, + FT_ENCODING_MS_JOHAB = FT_ENCODING_JOHAB, + + FT_ENC_TAG( FT_ENCODING_ADOBE_STANDARD, 'A', 'D', 'O', 'B' ), + FT_ENC_TAG( FT_ENCODING_ADOBE_EXPERT, 'A', 'D', 'B', 'E' ), + FT_ENC_TAG( FT_ENCODING_ADOBE_CUSTOM, 'A', 'D', 'B', 'C' ), + FT_ENC_TAG( FT_ENCODING_ADOBE_LATIN_1, 'l', 'a', 't', '1' ), + + FT_ENC_TAG( FT_ENCODING_OLD_LATIN_2, 'l', 'a', 't', '2' ), + + FT_ENC_TAG( FT_ENCODING_APPLE_ROMAN, 'a', 'r', 'm', 'n' ) + + } FT_Encoding; + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* ft_encoding_xxx */ + /* */ + /* <Description> */ + /* These constants are deprecated; use the corresponding @FT_Encoding */ + /* values instead. */ + /* */ +#define ft_encoding_none FT_ENCODING_NONE +#define ft_encoding_unicode FT_ENCODING_UNICODE +#define ft_encoding_symbol FT_ENCODING_MS_SYMBOL +#define ft_encoding_latin_1 FT_ENCODING_ADOBE_LATIN_1 +#define ft_encoding_latin_2 FT_ENCODING_OLD_LATIN_2 +#define ft_encoding_sjis FT_ENCODING_SJIS +#define ft_encoding_gb2312 FT_ENCODING_GB2312 +#define ft_encoding_big5 FT_ENCODING_BIG5 +#define ft_encoding_wansung FT_ENCODING_WANSUNG +#define ft_encoding_johab FT_ENCODING_JOHAB + +#define ft_encoding_adobe_standard FT_ENCODING_ADOBE_STANDARD +#define ft_encoding_adobe_expert FT_ENCODING_ADOBE_EXPERT +#define ft_encoding_adobe_custom FT_ENCODING_ADOBE_CUSTOM +#define ft_encoding_apple_roman FT_ENCODING_APPLE_ROMAN + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_CharMapRec */ + /* */ + /* <Description> */ + /* The base charmap structure. */ + /* */ + /* <Fields> */ + /* face :: A handle to the parent face object. */ + /* */ + /* encoding :: An @FT_Encoding tag identifying the charmap. Use */ + /* this with @FT_Select_Charmap. */ + /* */ + /* platform_id :: An ID number describing the platform for the */ + /* following encoding ID. This comes directly from */ + /* the TrueType specification and should be emulated */ + /* for other formats. */ + /* */ + /* encoding_id :: A platform specific encoding number. This also */ + /* comes from the TrueType specification and should be */ + /* emulated similarly. */ + /* */ + typedef struct FT_CharMapRec_ + { + FT_Face face; + FT_Encoding encoding; + FT_UShort platform_id; + FT_UShort encoding_id; + + } FT_CharMapRec; + + + /*************************************************************************/ + /*************************************************************************/ + /* */ + /* B A S E O B J E C T C L A S S E S */ + /* */ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Face_Internal */ + /* */ + /* <Description> */ + /* An opaque handle to an `FT_Face_InternalRec' structure, used to */ + /* model private data of a given @FT_Face object. */ + /* */ + /* This structure might change between releases of FreeType~2 and is */ + /* not generally available to client applications. */ + /* */ + typedef struct FT_Face_InternalRec_* FT_Face_Internal; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_FaceRec */ + /* */ + /* <Description> */ + /* FreeType root face class structure. A face object models a */ + /* typeface in a font file. */ + /* */ + /* <Fields> */ + /* num_faces :: The number of faces in the font file. Some */ + /* font formats can have multiple faces in */ + /* a font file. */ + /* */ + /* face_index :: The index of the face in the font file. It */ + /* is set to~0 if there is only one face in */ + /* the font file. */ + /* */ + /* face_flags :: A set of bit flags that give important */ + /* information about the face; see */ + /* @FT_FACE_FLAG_XXX for the details. */ + /* */ + /* style_flags :: A set of bit flags indicating the style of */ + /* the face; see @FT_STYLE_FLAG_XXX for the */ + /* details. */ + /* */ + /* num_glyphs :: The number of glyphs in the face. If the */ + /* face is scalable and has sbits (see */ + /* `num_fixed_sizes'), it is set to the number */ + /* of outline glyphs. */ + /* */ + /* For CID-keyed fonts, this value gives the */ + /* highest CID used in the font. */ + /* */ + /* family_name :: The face's family name. This is an ASCII */ + /* string, usually in English, which describes */ + /* the typeface's family (like `Times New */ + /* Roman', `Bodoni', `Garamond', etc). This */ + /* is a least common denominator used to list */ + /* fonts. Some formats (TrueType & OpenType) */ + /* provide localized and Unicode versions of */ + /* this string. Applications should use the */ + /* format specific interface to access them. */ + /* Can be NULL (e.g., in fonts embedded in a */ + /* PDF file). */ + /* */ + /* style_name :: The face's style name. This is an ASCII */ + /* string, usually in English, which describes */ + /* the typeface's style (like `Italic', */ + /* `Bold', `Condensed', etc). Not all font */ + /* formats provide a style name, so this field */ + /* is optional, and can be set to NULL. As */ + /* for `family_name', some formats provide */ + /* localized and Unicode versions of this */ + /* string. Applications should use the format */ + /* specific interface to access them. */ + /* */ + /* num_fixed_sizes :: The number of bitmap strikes in the face. */ + /* Even if the face is scalable, there might */ + /* still be bitmap strikes, which are called */ + /* `sbits' in that case. */ + /* */ + /* available_sizes :: An array of @FT_Bitmap_Size for all bitmap */ + /* strikes in the face. It is set to NULL if */ + /* there is no bitmap strike. */ + /* */ + /* num_charmaps :: The number of charmaps in the face. */ + /* */ + /* charmaps :: An array of the charmaps of the face. */ + /* */ + /* generic :: A field reserved for client uses. See the */ + /* @FT_Generic type description. */ + /* */ + /* bbox :: The font bounding box. Coordinates are */ + /* expressed in font units (see */ + /* `units_per_EM'). The box is large enough */ + /* to contain any glyph from the font. Thus, */ + /* `bbox.yMax' can be seen as the `maximal */ + /* ascender', and `bbox.yMin' as the `minimal */ + /* descender'. Only relevant for scalable */ + /* formats. */ + /* */ + /* Note that the bounding box might be off by */ + /* (at least) one pixel for hinted fonts. See */ + /* @FT_Size_Metrics for further discussion. */ + /* */ + /* units_per_EM :: The number of font units per EM square for */ + /* this face. This is typically 2048 for */ + /* TrueType fonts, and 1000 for Type~1 fonts. */ + /* Only relevant for scalable formats. */ + /* */ + /* ascender :: The typographic ascender of the face, */ + /* expressed in font units. For font formats */ + /* not having this information, it is set to */ + /* `bbox.yMax'. Only relevant for scalable */ + /* formats. */ + /* */ + /* descender :: The typographic descender of the face, */ + /* expressed in font units. For font formats */ + /* not having this information, it is set to */ + /* `bbox.yMin'. Note that this field is */ + /* usually negative. Only relevant for */ + /* scalable formats. */ + /* */ + /* height :: The height is the vertical distance */ + /* between two consecutive baselines, */ + /* expressed in font units. It is always */ + /* positive. Only relevant for scalable */ + /* formats. */ + /* */ + /* max_advance_width :: The maximal advance width, in font units, */ + /* for all glyphs in this face. This can be */ + /* used to make word wrapping computations */ + /* faster. Only relevant for scalable */ + /* formats. */ + /* */ + /* max_advance_height :: The maximal advance height, in font units, */ + /* for all glyphs in this face. This is only */ + /* relevant for vertical layouts, and is set */ + /* to `height' for fonts that do not provide */ + /* vertical metrics. Only relevant for */ + /* scalable formats. */ + /* */ + /* underline_position :: The position, in font units, of the */ + /* underline line for this face. It is the */ + /* center of the underlining stem. Only */ + /* relevant for scalable formats. */ + /* */ + /* underline_thickness :: The thickness, in font units, of the */ + /* underline for this face. Only relevant for */ + /* scalable formats. */ + /* */ + /* glyph :: The face's associated glyph slot(s). */ + /* */ + /* size :: The current active size for this face. */ + /* */ + /* charmap :: The current active charmap for this face. */ + /* */ + /* <Note> */ + /* Fields may be changed after a call to @FT_Attach_File or */ + /* @FT_Attach_Stream. */ + /* */ + typedef struct FT_FaceRec_ + { + FT_Long num_faces; + FT_Long face_index; + + FT_Long face_flags; + FT_Long style_flags; + + FT_Long num_glyphs; + + FT_String* family_name; + FT_String* style_name; + + FT_Int num_fixed_sizes; + FT_Bitmap_Size* available_sizes; + + FT_Int num_charmaps; + FT_CharMap* charmaps; + + FT_Generic generic; + + /*# The following member variables (down to `underline_thickness') */ + /*# are only relevant to scalable outlines; cf. @FT_Bitmap_Size */ + /*# for bitmap fonts. */ + FT_BBox bbox; + + FT_UShort units_per_EM; + FT_Short ascender; + FT_Short descender; + FT_Short height; + + FT_Short max_advance_width; + FT_Short max_advance_height; + + FT_Short underline_position; + FT_Short underline_thickness; + + FT_GlyphSlot glyph; + FT_Size size; + FT_CharMap charmap; + + /*@private begin */ + + FT_Driver driver; + FT_Memory memory; + FT_Stream stream; + + FT_ListRec sizes_list; + + FT_Generic autohint; + void* extensions; + + FT_Face_Internal internal; + + /*@private end */ + + } FT_FaceRec; + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_FACE_FLAG_XXX */ + /* */ + /* <Description> */ + /* A list of bit flags used in the `face_flags' field of the */ + /* @FT_FaceRec structure. They inform client applications of */ + /* properties of the corresponding face. */ + /* */ + /* <Values> */ + /* FT_FACE_FLAG_SCALABLE :: */ + /* Indicates that the face contains outline glyphs. This doesn't */ + /* prevent bitmap strikes, i.e., a face can have both this and */ + /* and @FT_FACE_FLAG_FIXED_SIZES set. */ + /* */ + /* FT_FACE_FLAG_FIXED_SIZES :: */ + /* Indicates that the face contains bitmap strikes. See also the */ + /* `num_fixed_sizes' and `available_sizes' fields of @FT_FaceRec. */ + /* */ + /* FT_FACE_FLAG_FIXED_WIDTH :: */ + /* Indicates that the face contains fixed-width characters (like */ + /* Courier, Lucido, MonoType, etc.). */ + /* */ + /* FT_FACE_FLAG_SFNT :: */ + /* Indicates that the face uses the `sfnt' storage scheme. For */ + /* now, this means TrueType and OpenType. */ + /* */ + /* FT_FACE_FLAG_HORIZONTAL :: */ + /* Indicates that the face contains horizontal glyph metrics. This */ + /* should be set for all common formats. */ + /* */ + /* FT_FACE_FLAG_VERTICAL :: */ + /* Indicates that the face contains vertical glyph metrics. This */ + /* is only available in some formats, not all of them. */ + /* */ + /* FT_FACE_FLAG_KERNING :: */ + /* Indicates that the face contains kerning information. If set, */ + /* the kerning distance can be retrieved through the function */ + /* @FT_Get_Kerning. Otherwise the function always return the */ + /* vector (0,0). Note that FreeType doesn't handle kerning data */ + /* from the `GPOS' table (as present in some OpenType fonts). */ + /* */ + /* FT_FACE_FLAG_FAST_GLYPHS :: */ + /* THIS FLAG IS DEPRECATED. DO NOT USE OR TEST IT. */ + /* */ + /* FT_FACE_FLAG_MULTIPLE_MASTERS :: */ + /* Indicates that the font contains multiple masters and is capable */ + /* of interpolating between them. See the multiple-masters */ + /* specific API for details. */ + /* */ + /* FT_FACE_FLAG_GLYPH_NAMES :: */ + /* Indicates that the font contains glyph names that can be */ + /* retrieved through @FT_Get_Glyph_Name. Note that some TrueType */ + /* fonts contain broken glyph name tables. Use the function */ + /* @FT_Has_PS_Glyph_Names when needed. */ + /* */ + /* FT_FACE_FLAG_EXTERNAL_STREAM :: */ + /* Used internally by FreeType to indicate that a face's stream was */ + /* provided by the client application and should not be destroyed */ + /* when @FT_Done_Face is called. Don't read or test this flag. */ + /* */ + /* FT_FACE_FLAG_HINTER :: */ + /* Set if the font driver has a hinting machine of its own. For */ + /* example, with TrueType fonts, it makes sense to use data from */ + /* the SFNT `gasp' table only if the native TrueType hinting engine */ + /* (with the bytecode interpreter) is available and active. */ + /* */ + /* FT_FACE_FLAG_CID_KEYED :: */ + /* Set if the font is CID-keyed. In that case, the font is not */ + /* accessed by glyph indices but by CID values. For subsetted */ + /* CID-keyed fonts this has the consequence that not all index */ + /* values are a valid argument to FT_Load_Glyph. Only the CID */ + /* values for which corresponding glyphs in the subsetted font */ + /* exist make FT_Load_Glyph return successfully; in all other cases */ + /* you get an `FT_Err_Invalid_Argument' error. */ + /* */ + /* Note that CID-keyed fonts which are in an SFNT wrapper don't */ + /* have this flag set since the glyphs are accessed in the normal */ + /* way (using contiguous indices); the `CID-ness' isn't visible to */ + /* the application. */ + /* */ + /* FT_FACE_FLAG_TRICKY :: */ + /* Set if the font is `tricky', this is, it always needs the */ + /* font format's native hinting engine to get a reasonable result. */ + /* A typical example is the Chinese font `mingli.ttf' which uses */ + /* TrueType bytecode instructions to move and scale all of its */ + /* subglyphs. */ + /* */ + /* It is not possible to autohint such fonts using */ + /* @FT_LOAD_FORCE_AUTOHINT; it will also ignore */ + /* @FT_LOAD_NO_HINTING. You have to set both FT_LOAD_NO_HINTING */ + /* and @FT_LOAD_NO_AUTOHINT to really disable hinting; however, you */ + /* probably never want this except for demonstration purposes. */ + /* */ + /* Currently, there are six TrueType fonts in the list of tricky */ + /* fonts; they are hard-coded in file `ttobjs.c'. */ + /* */ +#define FT_FACE_FLAG_SCALABLE ( 1L << 0 ) +#define FT_FACE_FLAG_FIXED_SIZES ( 1L << 1 ) +#define FT_FACE_FLAG_FIXED_WIDTH ( 1L << 2 ) +#define FT_FACE_FLAG_SFNT ( 1L << 3 ) +#define FT_FACE_FLAG_HORIZONTAL ( 1L << 4 ) +#define FT_FACE_FLAG_VERTICAL ( 1L << 5 ) +#define FT_FACE_FLAG_KERNING ( 1L << 6 ) +#define FT_FACE_FLAG_FAST_GLYPHS ( 1L << 7 ) +#define FT_FACE_FLAG_MULTIPLE_MASTERS ( 1L << 8 ) +#define FT_FACE_FLAG_GLYPH_NAMES ( 1L << 9 ) +#define FT_FACE_FLAG_EXTERNAL_STREAM ( 1L << 10 ) +#define FT_FACE_FLAG_HINTER ( 1L << 11 ) +#define FT_FACE_FLAG_CID_KEYED ( 1L << 12 ) +#define FT_FACE_FLAG_TRICKY ( 1L << 13 ) + + + /************************************************************************* + * + * @macro: + * FT_HAS_HORIZONTAL( face ) + * + * @description: + * A macro that returns true whenever a face object contains + * horizontal metrics (this is true for all font formats though). + * + * @also: + * @FT_HAS_VERTICAL can be used to check for vertical metrics. + * + */ +#define FT_HAS_HORIZONTAL( face ) \ + ( face->face_flags & FT_FACE_FLAG_HORIZONTAL ) + + + /************************************************************************* + * + * @macro: + * FT_HAS_VERTICAL( face ) + * + * @description: + * A macro that returns true whenever a face object contains vertical + * metrics. + * + */ +#define FT_HAS_VERTICAL( face ) \ + ( face->face_flags & FT_FACE_FLAG_VERTICAL ) + + + /************************************************************************* + * + * @macro: + * FT_HAS_KERNING( face ) + * + * @description: + * A macro that returns true whenever a face object contains kerning + * data that can be accessed with @FT_Get_Kerning. + * + */ +#define FT_HAS_KERNING( face ) \ + ( face->face_flags & FT_FACE_FLAG_KERNING ) + + + /************************************************************************* + * + * @macro: + * FT_IS_SCALABLE( face ) + * + * @description: + * A macro that returns true whenever a face object contains a scalable + * font face (true for TrueType, Type~1, Type~42, CID, OpenType/CFF, + * and PFR font formats. + * + */ +#define FT_IS_SCALABLE( face ) \ + ( face->face_flags & FT_FACE_FLAG_SCALABLE ) + + + /************************************************************************* + * + * @macro: + * FT_IS_SFNT( face ) + * + * @description: + * A macro that returns true whenever a face object contains a font + * whose format is based on the SFNT storage scheme. This usually + * means: TrueType fonts, OpenType fonts, as well as SFNT-based embedded + * bitmap fonts. + * + * If this macro is true, all functions defined in @FT_SFNT_NAMES_H and + * @FT_TRUETYPE_TABLES_H are available. + * + */ +#define FT_IS_SFNT( face ) \ + ( face->face_flags & FT_FACE_FLAG_SFNT ) + + + /************************************************************************* + * + * @macro: + * FT_IS_FIXED_WIDTH( face ) + * + * @description: + * A macro that returns true whenever a face object contains a font face + * that contains fixed-width (or `monospace', `fixed-pitch', etc.) + * glyphs. + * + */ +#define FT_IS_FIXED_WIDTH( face ) \ + ( face->face_flags & FT_FACE_FLAG_FIXED_WIDTH ) + + + /************************************************************************* + * + * @macro: + * FT_HAS_FIXED_SIZES( face ) + * + * @description: + * A macro that returns true whenever a face object contains some + * embedded bitmaps. See the `available_sizes' field of the + * @FT_FaceRec structure. + * + */ +#define FT_HAS_FIXED_SIZES( face ) \ + ( face->face_flags & FT_FACE_FLAG_FIXED_SIZES ) + + + /************************************************************************* + * + * @macro: + * FT_HAS_FAST_GLYPHS( face ) + * + * @description: + * Deprecated. + * + */ +#define FT_HAS_FAST_GLYPHS( face ) 0 + + + /************************************************************************* + * + * @macro: + * FT_HAS_GLYPH_NAMES( face ) + * + * @description: + * A macro that returns true whenever a face object contains some glyph + * names that can be accessed through @FT_Get_Glyph_Name. + * + */ +#define FT_HAS_GLYPH_NAMES( face ) \ + ( face->face_flags & FT_FACE_FLAG_GLYPH_NAMES ) + + + /************************************************************************* + * + * @macro: + * FT_HAS_MULTIPLE_MASTERS( face ) + * + * @description: + * A macro that returns true whenever a face object contains some + * multiple masters. The functions provided by @FT_MULTIPLE_MASTERS_H + * are then available to choose the exact design you want. + * + */ +#define FT_HAS_MULTIPLE_MASTERS( face ) \ + ( face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS ) + + + /************************************************************************* + * + * @macro: + * FT_IS_CID_KEYED( face ) + * + * @description: + * A macro that returns true whenever a face object contains a CID-keyed + * font. See the discussion of @FT_FACE_FLAG_CID_KEYED for more + * details. + * + * If this macro is true, all functions defined in @FT_CID_H are + * available. + * + */ +#define FT_IS_CID_KEYED( face ) \ + ( face->face_flags & FT_FACE_FLAG_CID_KEYED ) + + + /************************************************************************* + * + * @macro: + * FT_IS_TRICKY( face ) + * + * @description: + * A macro that returns true whenever a face represents a `tricky' font. + * See the discussion of @FT_FACE_FLAG_TRICKY for more details. + * + */ +#define FT_IS_TRICKY( face ) \ + ( face->face_flags & FT_FACE_FLAG_TRICKY ) + + + /*************************************************************************/ + /* */ + /* <Const> */ + /* FT_STYLE_FLAG_XXX */ + /* */ + /* <Description> */ + /* A list of bit-flags used to indicate the style of a given face. */ + /* These are used in the `style_flags' field of @FT_FaceRec. */ + /* */ + /* <Values> */ + /* FT_STYLE_FLAG_ITALIC :: */ + /* Indicates that a given face style is italic or oblique. */ + /* */ + /* FT_STYLE_FLAG_BOLD :: */ + /* Indicates that a given face is bold. */ + /* */ + /* <Note> */ + /* The style information as provided by FreeType is very basic. More */ + /* details are beyond the scope and should be done on a higher level */ + /* (for example, by analyzing various fields of the `OS/2' table in */ + /* SFNT based fonts). */ + /* */ +#define FT_STYLE_FLAG_ITALIC ( 1 << 0 ) +#define FT_STYLE_FLAG_BOLD ( 1 << 1 ) + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Size_Internal */ + /* */ + /* <Description> */ + /* An opaque handle to an `FT_Size_InternalRec' structure, used to */ + /* model private data of a given @FT_Size object. */ + /* */ + typedef struct FT_Size_InternalRec_* FT_Size_Internal; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Size_Metrics */ + /* */ + /* <Description> */ + /* The size metrics structure gives the metrics of a size object. */ + /* */ + /* <Fields> */ + /* x_ppem :: The width of the scaled EM square in pixels, hence */ + /* the term `ppem' (pixels per EM). It is also */ + /* referred to as `nominal width'. */ + /* */ + /* y_ppem :: The height of the scaled EM square in pixels, */ + /* hence the term `ppem' (pixels per EM). It is also */ + /* referred to as `nominal height'. */ + /* */ + /* x_scale :: A 16.16 fractional scaling value used to convert */ + /* horizontal metrics from font units to 26.6 */ + /* fractional pixels. Only relevant for scalable */ + /* font formats. */ + /* */ + /* y_scale :: A 16.16 fractional scaling value used to convert */ + /* vertical metrics from font units to 26.6 */ + /* fractional pixels. Only relevant for scalable */ + /* font formats. */ + /* */ + /* ascender :: The ascender in 26.6 fractional pixels. See */ + /* @FT_FaceRec for the details. */ + /* */ + /* descender :: The descender in 26.6 fractional pixels. See */ + /* @FT_FaceRec for the details. */ + /* */ + /* height :: The height in 26.6 fractional pixels. See */ + /* @FT_FaceRec for the details. */ + /* */ + /* max_advance :: The maximal advance width in 26.6 fractional */ + /* pixels. See @FT_FaceRec for the details. */ + /* */ + /* <Note> */ + /* The scaling values, if relevant, are determined first during a */ + /* size changing operation. The remaining fields are then set by the */ + /* driver. For scalable formats, they are usually set to scaled */ + /* values of the corresponding fields in @FT_FaceRec. */ + /* */ + /* Note that due to glyph hinting, these values might not be exact */ + /* for certain fonts. Thus they must be treated as unreliable */ + /* with an error margin of at least one pixel! */ + /* */ + /* Indeed, the only way to get the exact metrics is to render _all_ */ + /* glyphs. As this would be a definite performance hit, it is up to */ + /* client applications to perform such computations. */ + /* */ + /* The FT_Size_Metrics structure is valid for bitmap fonts also. */ + /* */ + typedef struct FT_Size_Metrics_ + { + FT_UShort x_ppem; /* horizontal pixels per EM */ + FT_UShort y_ppem; /* vertical pixels per EM */ + + FT_Fixed x_scale; /* scaling values used to convert font */ + FT_Fixed y_scale; /* units to 26.6 fractional pixels */ + + FT_Pos ascender; /* ascender in 26.6 frac. pixels */ + FT_Pos descender; /* descender in 26.6 frac. pixels */ + FT_Pos height; /* text height in 26.6 frac. pixels */ + FT_Pos max_advance; /* max horizontal advance, in 26.6 pixels */ + + } FT_Size_Metrics; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_SizeRec */ + /* */ + /* <Description> */ + /* FreeType root size class structure. A size object models a face */ + /* object at a given size. */ + /* */ + /* <Fields> */ + /* face :: Handle to the parent face object. */ + /* */ + /* generic :: A typeless pointer, which is unused by the FreeType */ + /* library or any of its drivers. It can be used by */ + /* client applications to link their own data to each size */ + /* object. */ + /* */ + /* metrics :: Metrics for this size object. This field is read-only. */ + /* */ + typedef struct FT_SizeRec_ + { + FT_Face face; /* parent face object */ + FT_Generic generic; /* generic pointer for client uses */ + FT_Size_Metrics metrics; /* size metrics */ + FT_Size_Internal internal; + + } FT_SizeRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_SubGlyph */ + /* */ + /* <Description> */ + /* The subglyph structure is an internal object used to describe */ + /* subglyphs (for example, in the case of composites). */ + /* */ + /* <Note> */ + /* The subglyph implementation is not part of the high-level API, */ + /* hence the forward structure declaration. */ + /* */ + /* You can however retrieve subglyph information with */ + /* @FT_Get_SubGlyph_Info. */ + /* */ + typedef struct FT_SubGlyphRec_* FT_SubGlyph; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Slot_Internal */ + /* */ + /* <Description> */ + /* An opaque handle to an `FT_Slot_InternalRec' structure, used to */ + /* model private data of a given @FT_GlyphSlot object. */ + /* */ + typedef struct FT_Slot_InternalRec_* FT_Slot_Internal; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_GlyphSlotRec */ + /* */ + /* <Description> */ + /* FreeType root glyph slot class structure. A glyph slot is a */ + /* container where individual glyphs can be loaded, be they in */ + /* outline or bitmap format. */ + /* */ + /* <Fields> */ + /* library :: A handle to the FreeType library instance */ + /* this slot belongs to. */ + /* */ + /* face :: A handle to the parent face object. */ + /* */ + /* next :: In some cases (like some font tools), several */ + /* glyph slots per face object can be a good */ + /* thing. As this is rare, the glyph slots are */ + /* listed through a direct, single-linked list */ + /* using its `next' field. */ + /* */ + /* generic :: A typeless pointer which is unused by the */ + /* FreeType library or any of its drivers. It */ + /* can be used by client applications to link */ + /* their own data to each glyph slot object. */ + /* */ + /* metrics :: The metrics of the last loaded glyph in the */ + /* slot. The returned values depend on the last */ + /* load flags (see the @FT_Load_Glyph API */ + /* function) and can be expressed either in 26.6 */ + /* fractional pixels or font units. */ + /* */ + /* Note that even when the glyph image is */ + /* transformed, the metrics are not. */ + /* */ + /* linearHoriAdvance :: The advance width of the unhinted glyph. */ + /* Its value is expressed in 16.16 fractional */ + /* pixels, unless @FT_LOAD_LINEAR_DESIGN is set */ + /* when loading the glyph. This field can be */ + /* important to perform correct WYSIWYG layout. */ + /* Only relevant for outline glyphs. */ + /* */ + /* linearVertAdvance :: The advance height of the unhinted glyph. */ + /* Its value is expressed in 16.16 fractional */ + /* pixels, unless @FT_LOAD_LINEAR_DESIGN is set */ + /* when loading the glyph. This field can be */ + /* important to perform correct WYSIWYG layout. */ + /* Only relevant for outline glyphs. */ + /* */ + /* advance :: This is the transformed advance width for the */ + /* glyph (in 26.6 fractional pixel format). */ + /* */ + /* format :: This field indicates the format of the image */ + /* contained in the glyph slot. Typically */ + /* @FT_GLYPH_FORMAT_BITMAP, */ + /* @FT_GLYPH_FORMAT_OUTLINE, or */ + /* @FT_GLYPH_FORMAT_COMPOSITE, but others are */ + /* possible. */ + /* */ + /* bitmap :: This field is used as a bitmap descriptor */ + /* when the slot format is */ + /* @FT_GLYPH_FORMAT_BITMAP. Note that the */ + /* address and content of the bitmap buffer can */ + /* change between calls of @FT_Load_Glyph and a */ + /* few other functions. */ + /* */ + /* bitmap_left :: This is the bitmap's left bearing expressed */ + /* in integer pixels. Of course, this is only */ + /* valid if the format is */ + /* @FT_GLYPH_FORMAT_BITMAP. */ + /* */ + /* bitmap_top :: This is the bitmap's top bearing expressed in */ + /* integer pixels. Remember that this is the */ + /* distance from the baseline to the top-most */ + /* glyph scanline, upwards y~coordinates being */ + /* *positive*. */ + /* */ + /* outline :: The outline descriptor for the current glyph */ + /* image if its format is */ + /* @FT_GLYPH_FORMAT_OUTLINE. Once a glyph is */ + /* loaded, `outline' can be transformed, */ + /* distorted, embolded, etc. However, it must */ + /* not be freed. */ + /* */ + /* num_subglyphs :: The number of subglyphs in a composite glyph. */ + /* This field is only valid for the composite */ + /* glyph format that should normally only be */ + /* loaded with the @FT_LOAD_NO_RECURSE flag. */ + /* For now this is internal to FreeType. */ + /* */ + /* subglyphs :: An array of subglyph descriptors for */ + /* composite glyphs. There are `num_subglyphs' */ + /* elements in there. Currently internal to */ + /* FreeType. */ + /* */ + /* control_data :: Certain font drivers can also return the */ + /* control data for a given glyph image (e.g. */ + /* TrueType bytecode, Type~1 charstrings, etc.). */ + /* This field is a pointer to such data. */ + /* */ + /* control_len :: This is the length in bytes of the control */ + /* data. */ + /* */ + /* other :: Really wicked formats can use this pointer to */ + /* present their own glyph image to client */ + /* applications. Note that the application */ + /* needs to know about the image format. */ + /* */ + /* lsb_delta :: The difference between hinted and unhinted */ + /* left side bearing while autohinting is */ + /* active. Zero otherwise. */ + /* */ + /* rsb_delta :: The difference between hinted and unhinted */ + /* right side bearing while autohinting is */ + /* active. Zero otherwise. */ + /* */ + /* <Note> */ + /* If @FT_Load_Glyph is called with default flags (see */ + /* @FT_LOAD_DEFAULT) the glyph image is loaded in the glyph slot in */ + /* its native format (e.g., an outline glyph for TrueType and Type~1 */ + /* formats). */ + /* */ + /* This image can later be converted into a bitmap by calling */ + /* @FT_Render_Glyph. This function finds the current renderer for */ + /* the native image's format, then invokes it. */ + /* */ + /* The renderer is in charge of transforming the native image through */ + /* the slot's face transformation fields, then converting it into a */ + /* bitmap that is returned in `slot->bitmap'. */ + /* */ + /* Note that `slot->bitmap_left' and `slot->bitmap_top' are also used */ + /* to specify the position of the bitmap relative to the current pen */ + /* position (e.g., coordinates (0,0) on the baseline). Of course, */ + /* `slot->format' is also changed to @FT_GLYPH_FORMAT_BITMAP. */ + /* */ + /* <Note> */ + /* Here a small pseudo code fragment which shows how to use */ + /* `lsb_delta' and `rsb_delta': */ + /* */ + /* { */ + /* FT_Pos origin_x = 0; */ + /* FT_Pos prev_rsb_delta = 0; */ + /* */ + /* */ + /* for all glyphs do */ + /* <compute kern between current and previous glyph and add it to */ + /* `origin_x'> */ + /* */ + /* <load glyph with `FT_Load_Glyph'> */ + /* */ + /* if ( prev_rsb_delta - face->glyph->lsb_delta >= 32 ) */ + /* origin_x -= 64; */ + /* else if ( prev_rsb_delta - face->glyph->lsb_delta < -32 ) */ + /* origin_x += 64; */ + /* */ + /* prev_rsb_delta = face->glyph->rsb_delta; */ + /* */ + /* <save glyph image, or render glyph, or ...> */ + /* */ + /* origin_x += face->glyph->advance.x; */ + /* endfor */ + /* } */ + /* */ + typedef struct FT_GlyphSlotRec_ + { + FT_Library library; + FT_Face face; + FT_GlyphSlot next; + FT_UInt reserved; /* retained for binary compatibility */ + FT_Generic generic; + + FT_Glyph_Metrics metrics; + FT_Fixed linearHoriAdvance; + FT_Fixed linearVertAdvance; + FT_Vector advance; + + FT_Glyph_Format format; + + FT_Bitmap bitmap; + FT_Int bitmap_left; + FT_Int bitmap_top; + + FT_Outline outline; + + FT_UInt num_subglyphs; + FT_SubGlyph subglyphs; + + void* control_data; + long control_len; + + FT_Pos lsb_delta; + FT_Pos rsb_delta; + + void* other; + + FT_Slot_Internal internal; + + } FT_GlyphSlotRec; + + + /*************************************************************************/ + /*************************************************************************/ + /* */ + /* F U N C T I O N S */ + /* */ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Init_FreeType */ + /* */ + /* <Description> */ + /* Initialize a new FreeType library object. The set of modules */ + /* that are registered by this function is determined at build time. */ + /* */ + /* <Output> */ + /* alibrary :: A handle to a new library object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* In case you want to provide your own memory allocating routines, */ + /* use @FT_New_Library instead, followed by a call to */ + /* @FT_Add_Default_Modules (or a series of calls to @FT_Add_Module). */ + /* */ + FT_EXPORT( FT_Error ) + FT_Init_FreeType( FT_Library *alibrary ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Done_FreeType */ + /* */ + /* <Description> */ + /* Destroy a given FreeType library object and all of its children, */ + /* including resources, drivers, faces, sizes, etc. */ + /* */ + /* <Input> */ + /* library :: A handle to the target library object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Done_FreeType( FT_Library library ); + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_OPEN_XXX */ + /* */ + /* <Description> */ + /* A list of bit-field constants used within the `flags' field of the */ + /* @FT_Open_Args structure. */ + /* */ + /* <Values> */ + /* FT_OPEN_MEMORY :: This is a memory-based stream. */ + /* */ + /* FT_OPEN_STREAM :: Copy the stream from the `stream' field. */ + /* */ + /* FT_OPEN_PATHNAME :: Create a new input stream from a C~path */ + /* name. */ + /* */ + /* FT_OPEN_DRIVER :: Use the `driver' field. */ + /* */ + /* FT_OPEN_PARAMS :: Use the `num_params' and `params' fields. */ + /* */ + /* ft_open_memory :: Deprecated; use @FT_OPEN_MEMORY instead. */ + /* */ + /* ft_open_stream :: Deprecated; use @FT_OPEN_STREAM instead. */ + /* */ + /* ft_open_pathname :: Deprecated; use @FT_OPEN_PATHNAME instead. */ + /* */ + /* ft_open_driver :: Deprecated; use @FT_OPEN_DRIVER instead. */ + /* */ + /* ft_open_params :: Deprecated; use @FT_OPEN_PARAMS instead. */ + /* */ + /* <Note> */ + /* The `FT_OPEN_MEMORY', `FT_OPEN_STREAM', and `FT_OPEN_PATHNAME' */ + /* flags are mutually exclusive. */ + /* */ +#define FT_OPEN_MEMORY 0x1 +#define FT_OPEN_STREAM 0x2 +#define FT_OPEN_PATHNAME 0x4 +#define FT_OPEN_DRIVER 0x8 +#define FT_OPEN_PARAMS 0x10 + +#define ft_open_memory FT_OPEN_MEMORY /* deprecated */ +#define ft_open_stream FT_OPEN_STREAM /* deprecated */ +#define ft_open_pathname FT_OPEN_PATHNAME /* deprecated */ +#define ft_open_driver FT_OPEN_DRIVER /* deprecated */ +#define ft_open_params FT_OPEN_PARAMS /* deprecated */ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Parameter */ + /* */ + /* <Description> */ + /* A simple structure used to pass more or less generic parameters to */ + /* @FT_Open_Face. */ + /* */ + /* <Fields> */ + /* tag :: A four-byte identification tag. */ + /* */ + /* data :: A pointer to the parameter data. */ + /* */ + /* <Note> */ + /* The ID and function of parameters are driver-specific. */ + /* */ + typedef struct FT_Parameter_ + { + FT_ULong tag; + FT_Pointer data; + + } FT_Parameter; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Open_Args */ + /* */ + /* <Description> */ + /* A structure used to indicate how to open a new font file or */ + /* stream. A pointer to such a structure can be used as a parameter */ + /* for the functions @FT_Open_Face and @FT_Attach_Stream. */ + /* */ + /* <Fields> */ + /* flags :: A set of bit flags indicating how to use the */ + /* structure. */ + /* */ + /* memory_base :: The first byte of the file in memory. */ + /* */ + /* memory_size :: The size in bytes of the file in memory. */ + /* */ + /* pathname :: A pointer to an 8-bit file pathname. */ + /* */ + /* stream :: A handle to a source stream object. */ + /* */ + /* driver :: This field is exclusively used by @FT_Open_Face; */ + /* it simply specifies the font driver to use to open */ + /* the face. If set to~0, FreeType tries to load the */ + /* face with each one of the drivers in its list. */ + /* */ + /* num_params :: The number of extra parameters. */ + /* */ + /* params :: Extra parameters passed to the font driver when */ + /* opening a new face. */ + /* */ + /* <Note> */ + /* The stream type is determined by the contents of `flags' which */ + /* are tested in the following order by @FT_Open_Face: */ + /* */ + /* If the `FT_OPEN_MEMORY' bit is set, assume that this is a */ + /* memory file of `memory_size' bytes, located at `memory_address'. */ + /* The data are are not copied, and the client is responsible for */ + /* releasing and destroying them _after_ the corresponding call to */ + /* @FT_Done_Face. */ + /* */ + /* Otherwise, if the `FT_OPEN_STREAM' bit is set, assume that a */ + /* custom input stream `stream' is used. */ + /* */ + /* Otherwise, if the `FT_OPEN_PATHNAME' bit is set, assume that this */ + /* is a normal file and use `pathname' to open it. */ + /* */ + /* If the `FT_OPEN_DRIVER' bit is set, @FT_Open_Face only tries to */ + /* open the file with the driver whose handler is in `driver'. */ + /* */ + /* If the `FT_OPEN_PARAMS' bit is set, the parameters given by */ + /* `num_params' and `params' is used. They are ignored otherwise. */ + /* */ + /* Ideally, both the `pathname' and `params' fields should be tagged */ + /* as `const'; this is missing for API backwards compatibility. In */ + /* other words, applications should treat them as read-only. */ + /* */ + typedef struct FT_Open_Args_ + { + FT_UInt flags; + const FT_Byte* memory_base; + FT_Long memory_size; + FT_String* pathname; + FT_Stream stream; + FT_Module driver; + FT_Int num_params; + FT_Parameter* params; + + } FT_Open_Args; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_Face */ + /* */ + /* <Description> */ + /* This function calls @FT_Open_Face to open a font by its pathname. */ + /* */ + /* <InOut> */ + /* library :: A handle to the library resource. */ + /* */ + /* <Input> */ + /* pathname :: A path to the font file. */ + /* */ + /* face_index :: The index of the face within the font. The first */ + /* face has index~0. */ + /* */ + /* <Output> */ + /* aface :: A handle to a new face object. If `face_index' is */ + /* greater than or equal to zero, it must be non-NULL. */ + /* See @FT_Open_Face for more details. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_New_Face( FT_Library library, + const char* filepathname, + FT_Long face_index, + FT_Face *aface ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_Memory_Face */ + /* */ + /* <Description> */ + /* This function calls @FT_Open_Face to open a font which has been */ + /* loaded into memory. */ + /* */ + /* <InOut> */ + /* library :: A handle to the library resource. */ + /* */ + /* <Input> */ + /* file_base :: A pointer to the beginning of the font data. */ + /* */ + /* file_size :: The size of the memory chunk used by the font data. */ + /* */ + /* face_index :: The index of the face within the font. The first */ + /* face has index~0. */ + /* */ + /* <Output> */ + /* aface :: A handle to a new face object. If `face_index' is */ + /* greater than or equal to zero, it must be non-NULL. */ + /* See @FT_Open_Face for more details. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* You must not deallocate the memory before calling @FT_Done_Face. */ + /* */ + FT_EXPORT( FT_Error ) + FT_New_Memory_Face( FT_Library library, + const FT_Byte* file_base, + FT_Long file_size, + FT_Long face_index, + FT_Face *aface ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Open_Face */ + /* */ + /* <Description> */ + /* Create a face object from a given resource described by */ + /* @FT_Open_Args. */ + /* */ + /* <InOut> */ + /* library :: A handle to the library resource. */ + /* */ + /* <Input> */ + /* args :: A pointer to an `FT_Open_Args' structure which must */ + /* be filled by the caller. */ + /* */ + /* face_index :: The index of the face within the font. The first */ + /* face has index~0. */ + /* */ + /* <Output> */ + /* aface :: A handle to a new face object. If `face_index' is */ + /* greater than or equal to zero, it must be non-NULL. */ + /* See note below. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* Unlike FreeType 1.x, this function automatically creates a glyph */ + /* slot for the face object which can be accessed directly through */ + /* `face->glyph'. */ + /* */ + /* FT_Open_Face can be used to quickly check whether the font */ + /* format of a given font resource is supported by FreeType. If the */ + /* `face_index' field is negative, the function's return value is~0 */ + /* if the font format is recognized, or non-zero otherwise; */ + /* the function returns a more or less empty face handle in `*aface' */ + /* (if `aface' isn't NULL). The only useful field in this special */ + /* case is `face->num_faces' which gives the number of faces within */ + /* the font file. After examination, the returned @FT_Face structure */ + /* should be deallocated with a call to @FT_Done_Face. */ + /* */ + /* Each new face object created with this function also owns a */ + /* default @FT_Size object, accessible as `face->size'. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Open_Face( FT_Library library, + const FT_Open_Args* args, + FT_Long face_index, + FT_Face *aface ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Attach_File */ + /* */ + /* <Description> */ + /* This function calls @FT_Attach_Stream to attach a file. */ + /* */ + /* <InOut> */ + /* face :: The target face object. */ + /* */ + /* <Input> */ + /* filepathname :: The pathname. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Attach_File( FT_Face face, + const char* filepathname ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Attach_Stream */ + /* */ + /* <Description> */ + /* `Attach' data to a face object. Normally, this is used to read */ + /* additional information for the face object. For example, you can */ + /* attach an AFM file that comes with a Type~1 font to get the */ + /* kerning values and other metrics. */ + /* */ + /* <InOut> */ + /* face :: The target face object. */ + /* */ + /* <Input> */ + /* parameters :: A pointer to @FT_Open_Args which must be filled by */ + /* the caller. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The meaning of the `attach' (i.e., what really happens when the */ + /* new file is read) is not fixed by FreeType itself. It really */ + /* depends on the font format (and thus the font driver). */ + /* */ + /* Client applications are expected to know what they are doing */ + /* when invoking this function. Most drivers simply do not implement */ + /* file attachments. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Attach_Stream( FT_Face face, + FT_Open_Args* parameters ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Done_Face */ + /* */ + /* <Description> */ + /* Discard a given face object, as well as all of its child slots and */ + /* sizes. */ + /* */ + /* <Input> */ + /* face :: A handle to a target face object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Done_Face( FT_Face face ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Select_Size */ + /* */ + /* <Description> */ + /* Select a bitmap strike. */ + /* */ + /* <InOut> */ + /* face :: A handle to a target face object. */ + /* */ + /* <Input> */ + /* strike_index :: The index of the bitmap strike in the */ + /* `available_sizes' field of @FT_FaceRec structure. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Select_Size( FT_Face face, + FT_Int strike_index ); + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Size_Request_Type */ + /* */ + /* <Description> */ + /* An enumeration type that lists the supported size request types. */ + /* */ + /* <Values> */ + /* FT_SIZE_REQUEST_TYPE_NOMINAL :: */ + /* The nominal size. The `units_per_EM' field of @FT_FaceRec is */ + /* used to determine both scaling values. */ + /* */ + /* FT_SIZE_REQUEST_TYPE_REAL_DIM :: */ + /* The real dimension. The sum of the the `Ascender' and (minus */ + /* of) the `Descender' fields of @FT_FaceRec are used to determine */ + /* both scaling values. */ + /* */ + /* FT_SIZE_REQUEST_TYPE_BBOX :: */ + /* The font bounding box. The width and height of the `bbox' field */ + /* of @FT_FaceRec are used to determine the horizontal and vertical */ + /* scaling value, respectively. */ + /* */ + /* FT_SIZE_REQUEST_TYPE_CELL :: */ + /* The `max_advance_width' field of @FT_FaceRec is used to */ + /* determine the horizontal scaling value; the vertical scaling */ + /* value is determined the same way as */ + /* @FT_SIZE_REQUEST_TYPE_REAL_DIM does. Finally, both scaling */ + /* values are set to the smaller one. This type is useful if you */ + /* want to specify the font size for, say, a window of a given */ + /* dimension and 80x24 cells. */ + /* */ + /* FT_SIZE_REQUEST_TYPE_SCALES :: */ + /* Specify the scaling values directly. */ + /* */ + /* <Note> */ + /* The above descriptions only apply to scalable formats. For bitmap */ + /* formats, the behaviour is up to the driver. */ + /* */ + /* See the note section of @FT_Size_Metrics if you wonder how size */ + /* requesting relates to scaling values. */ + /* */ + typedef enum FT_Size_Request_Type_ + { + FT_SIZE_REQUEST_TYPE_NOMINAL, + FT_SIZE_REQUEST_TYPE_REAL_DIM, + FT_SIZE_REQUEST_TYPE_BBOX, + FT_SIZE_REQUEST_TYPE_CELL, + FT_SIZE_REQUEST_TYPE_SCALES, + + FT_SIZE_REQUEST_TYPE_MAX + + } FT_Size_Request_Type; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Size_RequestRec */ + /* */ + /* <Description> */ + /* A structure used to model a size request. */ + /* */ + /* <Fields> */ + /* type :: See @FT_Size_Request_Type. */ + /* */ + /* width :: The desired width. */ + /* */ + /* height :: The desired height. */ + /* */ + /* horiResolution :: The horizontal resolution. If set to zero, */ + /* `width' is treated as a 26.6 fractional pixel */ + /* value. */ + /* */ + /* vertResolution :: The vertical resolution. If set to zero, */ + /* `height' is treated as a 26.6 fractional pixel */ + /* value. */ + /* */ + /* <Note> */ + /* If `width' is zero, then the horizontal scaling value is set equal */ + /* to the vertical scaling value, and vice versa. */ + /* */ + typedef struct FT_Size_RequestRec_ + { + FT_Size_Request_Type type; + FT_Long width; + FT_Long height; + FT_UInt horiResolution; + FT_UInt vertResolution; + + } FT_Size_RequestRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Size_Request */ + /* */ + /* <Description> */ + /* A handle to a size request structure. */ + /* */ + typedef struct FT_Size_RequestRec_ *FT_Size_Request; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Request_Size */ + /* */ + /* <Description> */ + /* Resize the scale of the active @FT_Size object in a face. */ + /* */ + /* <InOut> */ + /* face :: A handle to a target face object. */ + /* */ + /* <Input> */ + /* req :: A pointer to a @FT_Size_RequestRec. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* Although drivers may select the bitmap strike matching the */ + /* request, you should not rely on this if you intend to select a */ + /* particular bitmap strike. Use @FT_Select_Size instead in that */ + /* case. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Request_Size( FT_Face face, + FT_Size_Request req ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_Char_Size */ + /* */ + /* <Description> */ + /* This function calls @FT_Request_Size to request the nominal size */ + /* (in points). */ + /* */ + /* <InOut> */ + /* face :: A handle to a target face object. */ + /* */ + /* <Input> */ + /* char_width :: The nominal width, in 26.6 fractional points. */ + /* */ + /* char_height :: The nominal height, in 26.6 fractional points. */ + /* */ + /* horz_resolution :: The horizontal resolution in dpi. */ + /* */ + /* vert_resolution :: The vertical resolution in dpi. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* If either the character width or height is zero, it is set equal */ + /* to the other value. */ + /* */ + /* If either the horizontal or vertical resolution is zero, it is set */ + /* equal to the other value. */ + /* */ + /* A character width or height smaller than 1pt is set to 1pt; if */ + /* both resolution values are zero, they are set to 72dpi. */ + /* */ + /* Don't use this function if you are using the FreeType cache API. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Set_Char_Size( FT_Face face, + FT_F26Dot6 char_width, + FT_F26Dot6 char_height, + FT_UInt horz_resolution, + FT_UInt vert_resolution ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_Pixel_Sizes */ + /* */ + /* <Description> */ + /* This function calls @FT_Request_Size to request the nominal size */ + /* (in pixels). */ + /* */ + /* <InOut> */ + /* face :: A handle to the target face object. */ + /* */ + /* <Input> */ + /* pixel_width :: The nominal width, in pixels. */ + /* */ + /* pixel_height :: The nominal height, in pixels. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Set_Pixel_Sizes( FT_Face face, + FT_UInt pixel_width, + FT_UInt pixel_height ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Load_Glyph */ + /* */ + /* <Description> */ + /* A function used to load a single glyph into the glyph slot of a */ + /* face object. */ + /* */ + /* <InOut> */ + /* face :: A handle to the target face object where the glyph */ + /* is loaded. */ + /* */ + /* <Input> */ + /* glyph_index :: The index of the glyph in the font file. For */ + /* CID-keyed fonts (either in PS or in CFF format) */ + /* this argument specifies the CID value. */ + /* */ + /* load_flags :: A flag indicating what to load for this glyph. The */ + /* @FT_LOAD_XXX constants can be used to control the */ + /* glyph loading process (e.g., whether the outline */ + /* should be scaled, whether to load bitmaps or not, */ + /* whether to hint the outline, etc). */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The loaded glyph may be transformed. See @FT_Set_Transform for */ + /* the details. */ + /* */ + /* For subsetted CID-keyed fonts, `FT_Err_Invalid_Argument' is */ + /* returned for invalid CID values (this is, for CID values which */ + /* don't have a corresponding glyph in the font). See the discussion */ + /* of the @FT_FACE_FLAG_CID_KEYED flag for more details. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Load_Glyph( FT_Face face, + FT_UInt glyph_index, + FT_Int32 load_flags ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Load_Char */ + /* */ + /* <Description> */ + /* A function used to load a single glyph into the glyph slot of a */ + /* face object, according to its character code. */ + /* */ + /* <InOut> */ + /* face :: A handle to a target face object where the glyph */ + /* is loaded. */ + /* */ + /* <Input> */ + /* char_code :: The glyph's character code, according to the */ + /* current charmap used in the face. */ + /* */ + /* load_flags :: A flag indicating what to load for this glyph. The */ + /* @FT_LOAD_XXX constants can be used to control the */ + /* glyph loading process (e.g., whether the outline */ + /* should be scaled, whether to load bitmaps or not, */ + /* whether to hint the outline, etc). */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* This function simply calls @FT_Get_Char_Index and @FT_Load_Glyph. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Load_Char( FT_Face face, + FT_ULong char_code, + FT_Int32 load_flags ); + + + /************************************************************************* + * + * @enum: + * FT_LOAD_XXX + * + * @description: + * A list of bit-field constants used with @FT_Load_Glyph to indicate + * what kind of operations to perform during glyph loading. + * + * @values: + * FT_LOAD_DEFAULT :: + * Corresponding to~0, this value is used as the default glyph load + * operation. In this case, the following happens: + * + * 1. FreeType looks for a bitmap for the glyph corresponding to the + * face's current size. If one is found, the function returns. + * The bitmap data can be accessed from the glyph slot (see note + * below). + * + * 2. If no embedded bitmap is searched or found, FreeType looks for a + * scalable outline. If one is found, it is loaded from the font + * file, scaled to device pixels, then `hinted' to the pixel grid + * in order to optimize it. The outline data can be accessed from + * the glyph slot (see note below). + * + * Note that by default, the glyph loader doesn't render outlines into + * bitmaps. The following flags are used to modify this default + * behaviour to more specific and useful cases. + * + * FT_LOAD_NO_SCALE :: + * Don't scale the outline glyph loaded, but keep it in font units. + * + * This flag implies @FT_LOAD_NO_HINTING and @FT_LOAD_NO_BITMAP, and + * unsets @FT_LOAD_RENDER. + * + * FT_LOAD_NO_HINTING :: + * Disable hinting. This generally generates `blurrier' bitmap glyph + * when the glyph is rendered in any of the anti-aliased modes. See + * also the note below. + * + * This flag is implied by @FT_LOAD_NO_SCALE. + * + * FT_LOAD_RENDER :: + * Call @FT_Render_Glyph after the glyph is loaded. By default, the + * glyph is rendered in @FT_RENDER_MODE_NORMAL mode. This can be + * overridden by @FT_LOAD_TARGET_XXX or @FT_LOAD_MONOCHROME. + * + * This flag is unset by @FT_LOAD_NO_SCALE. + * + * FT_LOAD_NO_BITMAP :: + * Ignore bitmap strikes when loading. Bitmap-only fonts ignore this + * flag. + * + * @FT_LOAD_NO_SCALE always sets this flag. + * + * FT_LOAD_VERTICAL_LAYOUT :: + * Load the glyph for vertical text layout. _Don't_ use it as it is + * problematic currently. + * + * FT_LOAD_FORCE_AUTOHINT :: + * Indicates that the auto-hinter is preferred over the font's native + * hinter. See also the note below. + * + * FT_LOAD_CROP_BITMAP :: + * Indicates that the font driver should crop the loaded bitmap glyph + * (i.e., remove all space around its black bits). Not all drivers + * implement this. + * + * FT_LOAD_PEDANTIC :: + * Indicates that the font driver should perform pedantic verifications + * during glyph loading. This is mostly used to detect broken glyphs + * in fonts. By default, FreeType tries to handle broken fonts also. + * + * FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH :: + * Indicates that the font driver should ignore the global advance + * width defined in the font. By default, that value is used as the + * advance width for all glyphs when the face has + * @FT_FACE_FLAG_FIXED_WIDTH set. + * + * This flag exists for historical reasons (to support buggy CJK + * fonts). + * + * FT_LOAD_NO_RECURSE :: + * This flag is only used internally. It merely indicates that the + * font driver should not load composite glyphs recursively. Instead, + * it should set the `num_subglyph' and `subglyphs' values of the + * glyph slot accordingly, and set `glyph->format' to + * @FT_GLYPH_FORMAT_COMPOSITE. + * + * The description of sub-glyphs is not available to client + * applications for now. + * + * This flag implies @FT_LOAD_NO_SCALE and @FT_LOAD_IGNORE_TRANSFORM. + * + * FT_LOAD_IGNORE_TRANSFORM :: + * Indicates that the transform matrix set by @FT_Set_Transform should + * be ignored. + * + * FT_LOAD_MONOCHROME :: + * This flag is used with @FT_LOAD_RENDER to indicate that you want to + * render an outline glyph to a 1-bit monochrome bitmap glyph, with + * 8~pixels packed into each byte of the bitmap data. + * + * Note that this has no effect on the hinting algorithm used. You + * should rather use @FT_LOAD_TARGET_MONO so that the + * monochrome-optimized hinting algorithm is used. + * + * FT_LOAD_LINEAR_DESIGN :: + * Indicates that the `linearHoriAdvance' and `linearVertAdvance' + * fields of @FT_GlyphSlotRec should be kept in font units. See + * @FT_GlyphSlotRec for details. + * + * FT_LOAD_NO_AUTOHINT :: + * Disable auto-hinter. See also the note below. + * + * @note: + * By default, hinting is enabled and the font's native hinter (see + * @FT_FACE_FLAG_HINTER) is preferred over the auto-hinter. You can + * disable hinting by setting @FT_LOAD_NO_HINTING or change the + * precedence by setting @FT_LOAD_FORCE_AUTOHINT. You can also set + * @FT_LOAD_NO_AUTOHINT in case you don't want the auto-hinter to be + * used at all. + * + * See the description of @FT_FACE_FLAG_TRICKY for a special exception + * (affecting only a handful of Asian fonts). + * + * Besides deciding which hinter to use, you can also decide which + * hinting algorithm to use. See @FT_LOAD_TARGET_XXX for details. + * + */ +#define FT_LOAD_DEFAULT 0x0 +#define FT_LOAD_NO_SCALE 0x1 +#define FT_LOAD_NO_HINTING 0x2 +#define FT_LOAD_RENDER 0x4 +#define FT_LOAD_NO_BITMAP 0x8 +#define FT_LOAD_VERTICAL_LAYOUT 0x10 +#define FT_LOAD_FORCE_AUTOHINT 0x20 +#define FT_LOAD_CROP_BITMAP 0x40 +#define FT_LOAD_PEDANTIC 0x80 +#define FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH 0x200 +#define FT_LOAD_NO_RECURSE 0x400 +#define FT_LOAD_IGNORE_TRANSFORM 0x800 +#define FT_LOAD_MONOCHROME 0x1000 +#define FT_LOAD_LINEAR_DESIGN 0x2000 +#define FT_LOAD_NO_AUTOHINT 0x8000U + + /* */ + + /* used internally only by certain font drivers! */ +#define FT_LOAD_ADVANCE_ONLY 0x100 +#define FT_LOAD_SBITS_ONLY 0x4000 + + + /************************************************************************** + * + * @enum: + * FT_LOAD_TARGET_XXX + * + * @description: + * A list of values that are used to select a specific hinting algorithm + * to use by the hinter. You should OR one of these values to your + * `load_flags' when calling @FT_Load_Glyph. + * + * Note that font's native hinters may ignore the hinting algorithm you + * have specified (e.g., the TrueType bytecode interpreter). You can set + * @FT_LOAD_FORCE_AUTOHINT to ensure that the auto-hinter is used. + * + * Also note that @FT_LOAD_TARGET_LIGHT is an exception, in that it + * always implies @FT_LOAD_FORCE_AUTOHINT. + * + * @values: + * FT_LOAD_TARGET_NORMAL :: + * This corresponds to the default hinting algorithm, optimized for + * standard gray-level rendering. For monochrome output, use + * @FT_LOAD_TARGET_MONO instead. + * + * FT_LOAD_TARGET_LIGHT :: + * A lighter hinting algorithm for non-monochrome modes. Many + * generated glyphs are more fuzzy but better resemble its original + * shape. A bit like rendering on Mac OS~X. + * + * As a special exception, this target implies @FT_LOAD_FORCE_AUTOHINT. + * + * FT_LOAD_TARGET_MONO :: + * Strong hinting algorithm that should only be used for monochrome + * output. The result is probably unpleasant if the glyph is rendered + * in non-monochrome modes. + * + * FT_LOAD_TARGET_LCD :: + * A variant of @FT_LOAD_TARGET_NORMAL optimized for horizontally + * decimated LCD displays. + * + * FT_LOAD_TARGET_LCD_V :: + * A variant of @FT_LOAD_TARGET_NORMAL optimized for vertically + * decimated LCD displays. + * + * @note: + * You should use only _one_ of the FT_LOAD_TARGET_XXX values in your + * `load_flags'. They can't be ORed. + * + * If @FT_LOAD_RENDER is also set, the glyph is rendered in the + * corresponding mode (i.e., the mode which matches the used algorithm + * best) unless @FT_LOAD_MONOCHROME is set. + * + * You can use a hinting algorithm that doesn't correspond to the same + * rendering mode. As an example, it is possible to use the `light' + * hinting algorithm and have the results rendered in horizontal LCD + * pixel mode, with code like + * + * { + * FT_Load_Glyph( face, glyph_index, + * load_flags | FT_LOAD_TARGET_LIGHT ); + * + * FT_Render_Glyph( face->glyph, FT_RENDER_MODE_LCD ); + * } + * + */ +#define FT_LOAD_TARGET_( x ) ( (FT_Int32)( (x) & 15 ) << 16 ) + +#define FT_LOAD_TARGET_NORMAL FT_LOAD_TARGET_( FT_RENDER_MODE_NORMAL ) +#define FT_LOAD_TARGET_LIGHT FT_LOAD_TARGET_( FT_RENDER_MODE_LIGHT ) +#define FT_LOAD_TARGET_MONO FT_LOAD_TARGET_( FT_RENDER_MODE_MONO ) +#define FT_LOAD_TARGET_LCD FT_LOAD_TARGET_( FT_RENDER_MODE_LCD ) +#define FT_LOAD_TARGET_LCD_V FT_LOAD_TARGET_( FT_RENDER_MODE_LCD_V ) + + + /************************************************************************** + * + * @macro: + * FT_LOAD_TARGET_MODE + * + * @description: + * Return the @FT_Render_Mode corresponding to a given + * @FT_LOAD_TARGET_XXX value. + * + */ +#define FT_LOAD_TARGET_MODE( x ) ( (FT_Render_Mode)( ( (x) >> 16 ) & 15 ) ) + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_Transform */ + /* */ + /* <Description> */ + /* A function used to set the transformation that is applied to glyph */ + /* images when they are loaded into a glyph slot through */ + /* @FT_Load_Glyph. */ + /* */ + /* <InOut> */ + /* face :: A handle to the source face object. */ + /* */ + /* <Input> */ + /* matrix :: A pointer to the transformation's 2x2 matrix. Use~0 for */ + /* the identity matrix. */ + /* delta :: A pointer to the translation vector. Use~0 for the null */ + /* vector. */ + /* */ + /* <Note> */ + /* The transformation is only applied to scalable image formats after */ + /* the glyph has been loaded. It means that hinting is unaltered by */ + /* the transformation and is performed on the character size given in */ + /* the last call to @FT_Set_Char_Size or @FT_Set_Pixel_Sizes. */ + /* */ + /* Note that this also transforms the `face.glyph.advance' field, but */ + /* *not* the values in `face.glyph.metrics'. */ + /* */ + FT_EXPORT( void ) + FT_Set_Transform( FT_Face face, + FT_Matrix* matrix, + FT_Vector* delta ); + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Render_Mode */ + /* */ + /* <Description> */ + /* An enumeration type that lists the render modes supported by */ + /* FreeType~2. Each mode corresponds to a specific type of scanline */ + /* conversion performed on the outline. */ + /* */ + /* For bitmap fonts and embedded bitmaps the `bitmap->pixel_mode' */ + /* field in the @FT_GlyphSlotRec structure gives the format of the */ + /* returned bitmap. */ + /* */ + /* All modes except @FT_RENDER_MODE_MONO use 256 levels of opacity. */ + /* */ + /* <Values> */ + /* FT_RENDER_MODE_NORMAL :: */ + /* This is the default render mode; it corresponds to 8-bit */ + /* anti-aliased bitmaps. */ + /* */ + /* FT_RENDER_MODE_LIGHT :: */ + /* This is equivalent to @FT_RENDER_MODE_NORMAL. It is only */ + /* defined as a separate value because render modes are also used */ + /* indirectly to define hinting algorithm selectors. See */ + /* @FT_LOAD_TARGET_XXX for details. */ + /* */ + /* FT_RENDER_MODE_MONO :: */ + /* This mode corresponds to 1-bit bitmaps (with 2~levels of */ + /* opacity). */ + /* */ + /* FT_RENDER_MODE_LCD :: */ + /* This mode corresponds to horizontal RGB and BGR sub-pixel */ + /* displays like LCD screens. It produces 8-bit bitmaps that are */ + /* 3~times the width of the original glyph outline in pixels, and */ + /* which use the @FT_PIXEL_MODE_LCD mode. */ + /* */ + /* FT_RENDER_MODE_LCD_V :: */ + /* This mode corresponds to vertical RGB and BGR sub-pixel displays */ + /* (like PDA screens, rotated LCD displays, etc.). It produces */ + /* 8-bit bitmaps that are 3~times the height of the original */ + /* glyph outline in pixels and use the @FT_PIXEL_MODE_LCD_V mode. */ + /* */ + /* <Note> */ + /* The LCD-optimized glyph bitmaps produced by FT_Render_Glyph can be */ + /* filtered to reduce color-fringes by using @FT_Library_SetLcdFilter */ + /* (not active in the default builds). It is up to the caller to */ + /* either call @FT_Library_SetLcdFilter (if available) or do the */ + /* filtering itself. */ + /* */ + /* The selected render mode only affects vector glyphs of a font. */ + /* Embedded bitmaps often have a different pixel mode like */ + /* @FT_PIXEL_MODE_MONO. You can use @FT_Bitmap_Convert to transform */ + /* them into 8-bit pixmaps. */ + /* */ + typedef enum FT_Render_Mode_ + { + FT_RENDER_MODE_NORMAL = 0, + FT_RENDER_MODE_LIGHT, + FT_RENDER_MODE_MONO, + FT_RENDER_MODE_LCD, + FT_RENDER_MODE_LCD_V, + + FT_RENDER_MODE_MAX + + } FT_Render_Mode; + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* ft_render_mode_xxx */ + /* */ + /* <Description> */ + /* These constants are deprecated. Use the corresponding */ + /* @FT_Render_Mode values instead. */ + /* */ + /* <Values> */ + /* ft_render_mode_normal :: see @FT_RENDER_MODE_NORMAL */ + /* ft_render_mode_mono :: see @FT_RENDER_MODE_MONO */ + /* */ +#define ft_render_mode_normal FT_RENDER_MODE_NORMAL +#define ft_render_mode_mono FT_RENDER_MODE_MONO + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Render_Glyph */ + /* */ + /* <Description> */ + /* Convert a given glyph image to a bitmap. It does so by inspecting */ + /* the glyph image format, finding the relevant renderer, and */ + /* invoking it. */ + /* */ + /* <InOut> */ + /* slot :: A handle to the glyph slot containing the image to */ + /* convert. */ + /* */ + /* <Input> */ + /* render_mode :: This is the render mode used to render the glyph */ + /* image into a bitmap. See @FT_Render_Mode for a */ + /* list of possible values. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Render_Glyph( FT_GlyphSlot slot, + FT_Render_Mode render_mode ); + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Kerning_Mode */ + /* */ + /* <Description> */ + /* An enumeration used to specify which kerning values to return in */ + /* @FT_Get_Kerning. */ + /* */ + /* <Values> */ + /* FT_KERNING_DEFAULT :: Return scaled and grid-fitted kerning */ + /* distances (value is~0). */ + /* */ + /* FT_KERNING_UNFITTED :: Return scaled but un-grid-fitted kerning */ + /* distances. */ + /* */ + /* FT_KERNING_UNSCALED :: Return the kerning vector in original font */ + /* units. */ + /* */ + typedef enum FT_Kerning_Mode_ + { + FT_KERNING_DEFAULT = 0, + FT_KERNING_UNFITTED, + FT_KERNING_UNSCALED + + } FT_Kerning_Mode; + + + /*************************************************************************/ + /* */ + /* <Const> */ + /* ft_kerning_default */ + /* */ + /* <Description> */ + /* This constant is deprecated. Please use @FT_KERNING_DEFAULT */ + /* instead. */ + /* */ +#define ft_kerning_default FT_KERNING_DEFAULT + + + /*************************************************************************/ + /* */ + /* <Const> */ + /* ft_kerning_unfitted */ + /* */ + /* <Description> */ + /* This constant is deprecated. Please use @FT_KERNING_UNFITTED */ + /* instead. */ + /* */ +#define ft_kerning_unfitted FT_KERNING_UNFITTED + + + /*************************************************************************/ + /* */ + /* <Const> */ + /* ft_kerning_unscaled */ + /* */ + /* <Description> */ + /* This constant is deprecated. Please use @FT_KERNING_UNSCALED */ + /* instead. */ + /* */ +#define ft_kerning_unscaled FT_KERNING_UNSCALED + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Kerning */ + /* */ + /* <Description> */ + /* Return the kerning vector between two glyphs of a same face. */ + /* */ + /* <Input> */ + /* face :: A handle to a source face object. */ + /* */ + /* left_glyph :: The index of the left glyph in the kern pair. */ + /* */ + /* right_glyph :: The index of the right glyph in the kern pair. */ + /* */ + /* kern_mode :: See @FT_Kerning_Mode for more information. */ + /* Determines the scale and dimension of the returned */ + /* kerning vector. */ + /* */ + /* <Output> */ + /* akerning :: The kerning vector. This is either in font units */ + /* or in pixels (26.6 format) for scalable formats, */ + /* and in pixels for fixed-sizes formats. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* Only horizontal layouts (left-to-right & right-to-left) are */ + /* supported by this method. Other layouts, or more sophisticated */ + /* kernings, are out of the scope of this API function -- they can be */ + /* implemented through format-specific interfaces. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Kerning( FT_Face face, + FT_UInt left_glyph, + FT_UInt right_glyph, + FT_UInt kern_mode, + FT_Vector *akerning ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Track_Kerning */ + /* */ + /* <Description> */ + /* Return the track kerning for a given face object at a given size. */ + /* */ + /* <Input> */ + /* face :: A handle to a source face object. */ + /* */ + /* point_size :: The point size in 16.16 fractional points. */ + /* */ + /* degree :: The degree of tightness. */ + /* */ + /* <Output> */ + /* akerning :: The kerning in 16.16 fractional points. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Track_Kerning( FT_Face face, + FT_Fixed point_size, + FT_Int degree, + FT_Fixed* akerning ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Glyph_Name */ + /* */ + /* <Description> */ + /* Retrieve the ASCII name of a given glyph in a face. This only */ + /* works for those faces where @FT_HAS_GLYPH_NAMES(face) returns~1. */ + /* */ + /* <Input> */ + /* face :: A handle to a source face object. */ + /* */ + /* glyph_index :: The glyph index. */ + /* */ + /* buffer_max :: The maximal number of bytes available in the */ + /* buffer. */ + /* */ + /* <Output> */ + /* buffer :: A pointer to a target buffer where the name is */ + /* copied to. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* An error is returned if the face doesn't provide glyph names or if */ + /* the glyph index is invalid. In all cases of failure, the first */ + /* byte of `buffer' is set to~0 to indicate an empty name. */ + /* */ + /* The glyph name is truncated to fit within the buffer if it is too */ + /* long. The returned string is always zero-terminated. */ + /* */ + /* This function is not compiled within the library if the config */ + /* macro `FT_CONFIG_OPTION_NO_GLYPH_NAMES' is defined in */ + /* `include/freetype/config/ftoptions.h'. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Glyph_Name( FT_Face face, + FT_UInt glyph_index, + FT_Pointer buffer, + FT_UInt buffer_max ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Postscript_Name */ + /* */ + /* <Description> */ + /* Retrieve the ASCII PostScript name of a given face, if available. */ + /* This only works with PostScript and TrueType fonts. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face object. */ + /* */ + /* <Return> */ + /* A pointer to the face's PostScript name. NULL if unavailable. */ + /* */ + /* <Note> */ + /* The returned pointer is owned by the face and is destroyed with */ + /* it. */ + /* */ + FT_EXPORT( const char* ) + FT_Get_Postscript_Name( FT_Face face ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Select_Charmap */ + /* */ + /* <Description> */ + /* Select a given charmap by its encoding tag (as listed in */ + /* `freetype.h'). */ + /* */ + /* <InOut> */ + /* face :: A handle to the source face object. */ + /* */ + /* <Input> */ + /* encoding :: A handle to the selected encoding. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* This function returns an error if no charmap in the face */ + /* corresponds to the encoding queried here. */ + /* */ + /* Because many fonts contain more than a single cmap for Unicode */ + /* encoding, this function has some special code to select the one */ + /* which covers Unicode best (`best' in the sense that a UCS-4 cmap */ + /* is preferred to a UCS-2 cmap). It is thus preferable to */ + /* @FT_Set_Charmap in this case. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Select_Charmap( FT_Face face, + FT_Encoding encoding ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_Charmap */ + /* */ + /* <Description> */ + /* Select a given charmap for character code to glyph index mapping. */ + /* */ + /* <InOut> */ + /* face :: A handle to the source face object. */ + /* */ + /* <Input> */ + /* charmap :: A handle to the selected charmap. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* This function returns an error if the charmap is not part of */ + /* the face (i.e., if it is not listed in the `face->charmaps' */ + /* table). */ + /* */ + /* It also fails if a type~14 charmap is selected. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Set_Charmap( FT_Face face, + FT_CharMap charmap ); + + + /************************************************************************* + * + * @function: + * FT_Get_Charmap_Index + * + * @description: + * Retrieve index of a given charmap. + * + * @input: + * charmap :: + * A handle to a charmap. + * + * @return: + * The index into the array of character maps within the face to which + * `charmap' belongs. + * + */ + FT_EXPORT( FT_Int ) + FT_Get_Charmap_Index( FT_CharMap charmap ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Char_Index */ + /* */ + /* <Description> */ + /* Return the glyph index of a given character code. This function */ + /* uses a charmap object to do the mapping. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face object. */ + /* */ + /* charcode :: The character code. */ + /* */ + /* <Return> */ + /* The glyph index. 0~means `undefined character code'. */ + /* */ + /* <Note> */ + /* If you use FreeType to manipulate the contents of font files */ + /* directly, be aware that the glyph index returned by this function */ + /* doesn't always correspond to the internal indices used within */ + /* the file. This is done to ensure that value~0 always corresponds */ + /* to the `missing glyph'. */ + /* */ + FT_EXPORT( FT_UInt ) + FT_Get_Char_Index( FT_Face face, + FT_ULong charcode ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_First_Char */ + /* */ + /* <Description> */ + /* This function is used to return the first character code in the */ + /* current charmap of a given face. It also returns the */ + /* corresponding glyph index. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face object. */ + /* */ + /* <Output> */ + /* agindex :: Glyph index of first character code. 0~if charmap is */ + /* empty. */ + /* */ + /* <Return> */ + /* The charmap's first character code. */ + /* */ + /* <Note> */ + /* You should use this function with @FT_Get_Next_Char to be able to */ + /* parse all character codes available in a given charmap. The code */ + /* should look like this: */ + /* */ + /* { */ + /* FT_ULong charcode; */ + /* FT_UInt gindex; */ + /* */ + /* */ + /* charcode = FT_Get_First_Char( face, &gindex ); */ + /* while ( gindex != 0 ) */ + /* { */ + /* ... do something with (charcode,gindex) pair ... */ + /* */ + /* charcode = FT_Get_Next_Char( face, charcode, &gindex ); */ + /* } */ + /* } */ + /* */ + /* Note that `*agindex' is set to~0 if the charmap is empty. The */ + /* result itself can be~0 in two cases: if the charmap is empty or */ + /* if the value~0 is the first valid character code. */ + /* */ + FT_EXPORT( FT_ULong ) + FT_Get_First_Char( FT_Face face, + FT_UInt *agindex ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Next_Char */ + /* */ + /* <Description> */ + /* This function is used to return the next character code in the */ + /* current charmap of a given face following the value `char_code', */ + /* as well as the corresponding glyph index. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face object. */ + /* char_code :: The starting character code. */ + /* */ + /* <Output> */ + /* agindex :: Glyph index of next character code. 0~if charmap */ + /* is empty. */ + /* */ + /* <Return> */ + /* The charmap's next character code. */ + /* */ + /* <Note> */ + /* You should use this function with @FT_Get_First_Char to walk */ + /* over all character codes available in a given charmap. See the */ + /* note for this function for a simple code example. */ + /* */ + /* Note that `*agindex' is set to~0 when there are no more codes in */ + /* the charmap. */ + /* */ + FT_EXPORT( FT_ULong ) + FT_Get_Next_Char( FT_Face face, + FT_ULong char_code, + FT_UInt *agindex ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Name_Index */ + /* */ + /* <Description> */ + /* Return the glyph index of a given glyph name. This function uses */ + /* driver specific objects to do the translation. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face object. */ + /* */ + /* glyph_name :: The glyph name. */ + /* */ + /* <Return> */ + /* The glyph index. 0~means `undefined character code'. */ + /* */ + FT_EXPORT( FT_UInt ) + FT_Get_Name_Index( FT_Face face, + FT_String* glyph_name ); + + + /************************************************************************* + * + * @macro: + * FT_SUBGLYPH_FLAG_XXX + * + * @description: + * A list of constants used to describe subglyphs. Please refer to the + * TrueType specification for the meaning of the various flags. + * + * @values: + * FT_SUBGLYPH_FLAG_ARGS_ARE_WORDS :: + * FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES :: + * FT_SUBGLYPH_FLAG_ROUND_XY_TO_GRID :: + * FT_SUBGLYPH_FLAG_SCALE :: + * FT_SUBGLYPH_FLAG_XY_SCALE :: + * FT_SUBGLYPH_FLAG_2X2 :: + * FT_SUBGLYPH_FLAG_USE_MY_METRICS :: + * + */ +#define FT_SUBGLYPH_FLAG_ARGS_ARE_WORDS 1 +#define FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES 2 +#define FT_SUBGLYPH_FLAG_ROUND_XY_TO_GRID 4 +#define FT_SUBGLYPH_FLAG_SCALE 8 +#define FT_SUBGLYPH_FLAG_XY_SCALE 0x40 +#define FT_SUBGLYPH_FLAG_2X2 0x80 +#define FT_SUBGLYPH_FLAG_USE_MY_METRICS 0x200 + + + /************************************************************************* + * + * @func: + * FT_Get_SubGlyph_Info + * + * @description: + * Retrieve a description of a given subglyph. Only use it if + * `glyph->format' is @FT_GLYPH_FORMAT_COMPOSITE; an error is + * returned otherwise. + * + * @input: + * glyph :: + * The source glyph slot. + * + * sub_index :: + * The index of the subglyph. Must be less than + * `glyph->num_subglyphs'. + * + * @output: + * p_index :: + * The glyph index of the subglyph. + * + * p_flags :: + * The subglyph flags, see @FT_SUBGLYPH_FLAG_XXX. + * + * p_arg1 :: + * The subglyph's first argument (if any). + * + * p_arg2 :: + * The subglyph's second argument (if any). + * + * p_transform :: + * The subglyph transformation (if any). + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The values of `*p_arg1', `*p_arg2', and `*p_transform' must be + * interpreted depending on the flags returned in `*p_flags'. See the + * TrueType specification for details. + * + */ + FT_EXPORT( FT_Error ) + FT_Get_SubGlyph_Info( FT_GlyphSlot glyph, + FT_UInt sub_index, + FT_Int *p_index, + FT_UInt *p_flags, + FT_Int *p_arg1, + FT_Int *p_arg2, + FT_Matrix *p_transform ); + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_FSTYPE_XXX */ + /* */ + /* <Description> */ + /* A list of bit flags used in the `fsType' field of the OS/2 table */ + /* in a TrueType or OpenType font and the `FSType' entry in a */ + /* PostScript font. These bit flags are returned by */ + /* @FT_Get_FSType_Flags; they inform client applications of embedding */ + /* and subsetting restrictions associated with a font. */ + /* */ + /* See http://www.adobe.com/devnet/acrobat/pdfs/FontPolicies.pdf for */ + /* more details. */ + /* */ + /* <Values> */ + /* FT_FSTYPE_INSTALLABLE_EMBEDDING :: */ + /* Fonts with no fsType bit set may be embedded and permanently */ + /* installed on the remote system by an application. */ + /* */ + /* FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING :: */ + /* Fonts that have only this bit set must not be modified, embedded */ + /* or exchanged in any manner without first obtaining permission of */ + /* the font software copyright owner. */ + /* */ + /* FT_FSTYPE_PREVIEW_AND_PRINT_EMBEDDING :: */ + /* If this bit is set, the font may be embedded and temporarily */ + /* loaded on the remote system. Documents containing Preview & */ + /* Print fonts must be opened `read-only'; no edits can be applied */ + /* to the document. */ + /* */ + /* FT_FSTYPE_EDITABLE_EMBEDDING :: */ + /* If this bit is set, the font may be embedded but must only be */ + /* installed temporarily on other systems. In contrast to Preview */ + /* & Print fonts, documents containing editable fonts may be opened */ + /* for reading, editing is permitted, and changes may be saved. */ + /* */ + /* FT_FSTYPE_NO_SUBSETTING :: */ + /* If this bit is set, the font may not be subsetted prior to */ + /* embedding. */ + /* */ + /* FT_FSTYPE_BITMAP_EMBEDDING_ONLY :: */ + /* If this bit is set, only bitmaps contained in the font may be */ + /* embedded; no outline data may be embedded. If there are no */ + /* bitmaps available in the font, then the font is unembeddable. */ + /* */ + /* <Note> */ + /* While the fsType flags can indicate that a font may be embedded, a */ + /* license with the font vendor may be separately required to use the */ + /* font in this way. */ + /* */ +#define FT_FSTYPE_INSTALLABLE_EMBEDDING 0x0000 +#define FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING 0x0002 +#define FT_FSTYPE_PREVIEW_AND_PRINT_EMBEDDING 0x0004 +#define FT_FSTYPE_EDITABLE_EMBEDDING 0x0008 +#define FT_FSTYPE_NO_SUBSETTING 0x0100 +#define FT_FSTYPE_BITMAP_EMBEDDING_ONLY 0x0200 + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_FSType_Flags */ + /* */ + /* <Description> */ + /* Return the fsType flags for a font. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face object. */ + /* */ + /* <Return> */ + /* The fsType flags, @FT_FSTYPE_XXX. */ + /* */ + /* <Note> */ + /* Use this function rather than directly reading the `fs_type' field */ + /* in the @PS_FontInfoRec structure which is only guaranteed to */ + /* return the correct results for Type~1 fonts. */ + /* */ + FT_EXPORT( FT_UShort ) + FT_Get_FSType_Flags( FT_Face face ); + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* glyph_variants */ + /* */ + /* <Title> */ + /* Glyph Variants */ + /* */ + /* <Abstract> */ + /* The FreeType~2 interface to Unicode Ideographic Variation */ + /* Sequences (IVS), using the SFNT cmap format~14. */ + /* */ + /* <Description> */ + /* Many CJK characters have variant forms. They are a sort of grey */ + /* area somewhere between being totally irrelevant and semantically */ + /* distinct; for this reason, the Unicode consortium decided to */ + /* introduce Ideographic Variation Sequences (IVS), consisting of a */ + /* Unicode base character and one of 240 variant selectors */ + /* (U+E0100-U+E01EF), instead of further extending the already huge */ + /* code range for CJK characters. */ + /* */ + /* An IVS is registered and unique; for further details please refer */ + /* to Unicode Technical Report #37, the Ideographic Variation */ + /* Database. To date (October 2007), the character with the most */ + /* variants is U+908A, having 8~such IVS. */ + /* */ + /* Adobe and MS decided to support IVS with a new cmap subtable */ + /* (format~14). It is an odd subtable because it is not a mapping of */ + /* input code points to glyphs, but contains lists of all variants */ + /* supported by the font. */ + /* */ + /* A variant may be either `default' or `non-default'. A default */ + /* variant is the one you will get for that code point if you look it */ + /* up in the standard Unicode cmap. A non-default variant is a */ + /* different glyph. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Face_GetCharVariantIndex */ + /* */ + /* <Description> */ + /* Return the glyph index of a given character code as modified by */ + /* the variation selector. */ + /* */ + /* <Input> */ + /* face :: */ + /* A handle to the source face object. */ + /* */ + /* charcode :: */ + /* The character code point in Unicode. */ + /* */ + /* variantSelector :: */ + /* The Unicode code point of the variation selector. */ + /* */ + /* <Return> */ + /* The glyph index. 0~means either `undefined character code', or */ + /* `undefined selector code', or `no variation selector cmap */ + /* subtable', or `current CharMap is not Unicode'. */ + /* */ + /* <Note> */ + /* If you use FreeType to manipulate the contents of font files */ + /* directly, be aware that the glyph index returned by this function */ + /* doesn't always correspond to the internal indices used within */ + /* the file. This is done to ensure that value~0 always corresponds */ + /* to the `missing glyph'. */ + /* */ + /* This function is only meaningful if */ + /* a) the font has a variation selector cmap sub table, */ + /* and */ + /* b) the current charmap has a Unicode encoding. */ + /* */ + /* <Since> */ + /* 2.3.6 */ + /* */ + FT_EXPORT( FT_UInt ) + FT_Face_GetCharVariantIndex( FT_Face face, + FT_ULong charcode, + FT_ULong variantSelector ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Face_GetCharVariantIsDefault */ + /* */ + /* <Description> */ + /* Check whether this variant of this Unicode character is the one to */ + /* be found in the `cmap'. */ + /* */ + /* <Input> */ + /* face :: */ + /* A handle to the source face object. */ + /* */ + /* charcode :: */ + /* The character codepoint in Unicode. */ + /* */ + /* variantSelector :: */ + /* The Unicode codepoint of the variation selector. */ + /* */ + /* <Return> */ + /* 1~if found in the standard (Unicode) cmap, 0~if found in the */ + /* variation selector cmap, or -1 if it is not a variant. */ + /* */ + /* <Note> */ + /* This function is only meaningful if the font has a variation */ + /* selector cmap subtable. */ + /* */ + /* <Since> */ + /* 2.3.6 */ + /* */ + FT_EXPORT( FT_Int ) + FT_Face_GetCharVariantIsDefault( FT_Face face, + FT_ULong charcode, + FT_ULong variantSelector ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Face_GetVariantSelectors */ + /* */ + /* <Description> */ + /* Return a zero-terminated list of Unicode variant selectors found */ + /* in the font. */ + /* */ + /* <Input> */ + /* face :: */ + /* A handle to the source face object. */ + /* */ + /* <Return> */ + /* A pointer to an array of selector code points, or NULL if there is */ + /* no valid variant selector cmap subtable. */ + /* */ + /* <Note> */ + /* The last item in the array is~0; the array is owned by the */ + /* @FT_Face object but can be overwritten or released on the next */ + /* call to a FreeType function. */ + /* */ + /* <Since> */ + /* 2.3.6 */ + /* */ + FT_EXPORT( FT_UInt32* ) + FT_Face_GetVariantSelectors( FT_Face face ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Face_GetVariantsOfChar */ + /* */ + /* <Description> */ + /* Return a zero-terminated list of Unicode variant selectors found */ + /* for the specified character code. */ + /* */ + /* <Input> */ + /* face :: */ + /* A handle to the source face object. */ + /* */ + /* charcode :: */ + /* The character codepoint in Unicode. */ + /* */ + /* <Return> */ + /* A pointer to an array of variant selector code points which are */ + /* active for the given character, or NULL if the corresponding list */ + /* is empty. */ + /* */ + /* <Note> */ + /* The last item in the array is~0; the array is owned by the */ + /* @FT_Face object but can be overwritten or released on the next */ + /* call to a FreeType function. */ + /* */ + /* <Since> */ + /* 2.3.6 */ + /* */ + FT_EXPORT( FT_UInt32* ) + FT_Face_GetVariantsOfChar( FT_Face face, + FT_ULong charcode ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Face_GetCharsOfVariant */ + /* */ + /* <Description> */ + /* Return a zero-terminated list of Unicode character codes found for */ + /* the specified variant selector. */ + /* */ + /* <Input> */ + /* face :: */ + /* A handle to the source face object. */ + /* */ + /* variantSelector :: */ + /* The variant selector code point in Unicode. */ + /* */ + /* <Return> */ + /* A list of all the code points which are specified by this selector */ + /* (both default and non-default codes are returned) or NULL if there */ + /* is no valid cmap or the variant selector is invalid. */ + /* */ + /* <Note> */ + /* The last item in the array is~0; the array is owned by the */ + /* @FT_Face object but can be overwritten or released on the next */ + /* call to a FreeType function. */ + /* */ + /* <Since> */ + /* 2.3.6 */ + /* */ + FT_EXPORT( FT_UInt32* ) + FT_Face_GetCharsOfVariant( FT_Face face, + FT_ULong variantSelector ); + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* computations */ + /* */ + /* <Title> */ + /* Computations */ + /* */ + /* <Abstract> */ + /* Crunching fixed numbers and vectors. */ + /* */ + /* <Description> */ + /* This section contains various functions used to perform */ + /* computations on 16.16 fixed-float numbers or 2d vectors. */ + /* */ + /* <Order> */ + /* FT_MulDiv */ + /* FT_MulFix */ + /* FT_DivFix */ + /* FT_RoundFix */ + /* FT_CeilFix */ + /* FT_FloorFix */ + /* FT_Vector_Transform */ + /* FT_Matrix_Multiply */ + /* FT_Matrix_Invert */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_MulDiv */ + /* */ + /* <Description> */ + /* A very simple function used to perform the computation `(a*b)/c' */ + /* with maximal accuracy (it uses a 64-bit intermediate integer */ + /* whenever necessary). */ + /* */ + /* This function isn't necessarily as fast as some processor specific */ + /* operations, but is at least completely portable. */ + /* */ + /* <Input> */ + /* a :: The first multiplier. */ + /* b :: The second multiplier. */ + /* c :: The divisor. */ + /* */ + /* <Return> */ + /* The result of `(a*b)/c'. This function never traps when trying to */ + /* divide by zero; it simply returns `MaxInt' or `MinInt' depending */ + /* on the signs of `a' and `b'. */ + /* */ + FT_EXPORT( FT_Long ) + FT_MulDiv( FT_Long a, + FT_Long b, + FT_Long c ); + + + /* */ + + /* The following #if 0 ... #endif is for the documentation formatter, */ + /* hiding the internal `FT_MULFIX_INLINED' macro. */ + +#if 0 + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_MulFix */ + /* */ + /* <Description> */ + /* A very simple function used to perform the computation */ + /* `(a*b)/0x10000' with maximal accuracy. Most of the time this is */ + /* used to multiply a given value by a 16.16 fixed float factor. */ + /* */ + /* <Input> */ + /* a :: The first multiplier. */ + /* b :: The second multiplier. Use a 16.16 factor here whenever */ + /* possible (see note below). */ + /* */ + /* <Return> */ + /* The result of `(a*b)/0x10000'. */ + /* */ + /* <Note> */ + /* This function has been optimized for the case where the absolute */ + /* value of `a' is less than 2048, and `b' is a 16.16 scaling factor. */ + /* As this happens mainly when scaling from notional units to */ + /* fractional pixels in FreeType, it resulted in noticeable speed */ + /* improvements between versions 2.x and 1.x. */ + /* */ + /* As a conclusion, always try to place a 16.16 factor as the */ + /* _second_ argument of this function; this can make a great */ + /* difference. */ + /* */ + FT_EXPORT( FT_Long ) + FT_MulFix( FT_Long a, + FT_Long b ); + + /* */ +#endif + +#ifdef FT_MULFIX_INLINED +#define FT_MulFix( a, b ) FT_MULFIX_INLINED( a, b ) +#else + FT_EXPORT( FT_Long ) + FT_MulFix( FT_Long a, + FT_Long b ); +#endif + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_DivFix */ + /* */ + /* <Description> */ + /* A very simple function used to perform the computation */ + /* `(a*0x10000)/b' with maximal accuracy. Most of the time, this is */ + /* used to divide a given value by a 16.16 fixed float factor. */ + /* */ + /* <Input> */ + /* a :: The first multiplier. */ + /* b :: The second multiplier. Use a 16.16 factor here whenever */ + /* possible (see note below). */ + /* */ + /* <Return> */ + /* The result of `(a*0x10000)/b'. */ + /* */ + /* <Note> */ + /* The optimization for FT_DivFix() is simple: If (a~<<~16) fits in */ + /* 32~bits, then the division is computed directly. Otherwise, we */ + /* use a specialized version of @FT_MulDiv. */ + /* */ + FT_EXPORT( FT_Long ) + FT_DivFix( FT_Long a, + FT_Long b ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_RoundFix */ + /* */ + /* <Description> */ + /* A very simple function used to round a 16.16 fixed number. */ + /* */ + /* <Input> */ + /* a :: The number to be rounded. */ + /* */ + /* <Return> */ + /* The result of `(a + 0x8000) & -0x10000'. */ + /* */ + FT_EXPORT( FT_Fixed ) + FT_RoundFix( FT_Fixed a ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_CeilFix */ + /* */ + /* <Description> */ + /* A very simple function used to compute the ceiling function of a */ + /* 16.16 fixed number. */ + /* */ + /* <Input> */ + /* a :: The number for which the ceiling function is to be computed. */ + /* */ + /* <Return> */ + /* The result of `(a + 0x10000 - 1) & -0x10000'. */ + /* */ + FT_EXPORT( FT_Fixed ) + FT_CeilFix( FT_Fixed a ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_FloorFix */ + /* */ + /* <Description> */ + /* A very simple function used to compute the floor function of a */ + /* 16.16 fixed number. */ + /* */ + /* <Input> */ + /* a :: The number for which the floor function is to be computed. */ + /* */ + /* <Return> */ + /* The result of `a & -0x10000'. */ + /* */ + FT_EXPORT( FT_Fixed ) + FT_FloorFix( FT_Fixed a ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Vector_Transform */ + /* */ + /* <Description> */ + /* Transform a single vector through a 2x2 matrix. */ + /* */ + /* <InOut> */ + /* vector :: The target vector to transform. */ + /* */ + /* <Input> */ + /* matrix :: A pointer to the source 2x2 matrix. */ + /* */ + /* <Note> */ + /* The result is undefined if either `vector' or `matrix' is invalid. */ + /* */ + FT_EXPORT( void ) + FT_Vector_Transform( FT_Vector* vec, + const FT_Matrix* matrix ); + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* version */ + /* */ + /* <Title> */ + /* FreeType Version */ + /* */ + /* <Abstract> */ + /* Functions and macros related to FreeType versions. */ + /* */ + /* <Description> */ + /* Note that those functions and macros are of limited use because */ + /* even a new release of FreeType with only documentation changes */ + /* increases the version number. */ + /* */ + /*************************************************************************/ + + + /************************************************************************* + * + * @enum: + * FREETYPE_XXX + * + * @description: + * These three macros identify the FreeType source code version. + * Use @FT_Library_Version to access them at runtime. + * + * @values: + * FREETYPE_MAJOR :: The major version number. + * FREETYPE_MINOR :: The minor version number. + * FREETYPE_PATCH :: The patch level. + * + * @note: + * The version number of FreeType if built as a dynamic link library + * with the `libtool' package is _not_ controlled by these three + * macros. + * + */ +#define FREETYPE_MAJOR 2 +#define FREETYPE_MINOR 3 +#define FREETYPE_PATCH 11 + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Library_Version */ + /* */ + /* <Description> */ + /* Return the version of the FreeType library being used. This is */ + /* useful when dynamically linking to the library, since one cannot */ + /* use the macros @FREETYPE_MAJOR, @FREETYPE_MINOR, and */ + /* @FREETYPE_PATCH. */ + /* */ + /* <Input> */ + /* library :: A source library handle. */ + /* */ + /* <Output> */ + /* amajor :: The major version number. */ + /* */ + /* aminor :: The minor version number. */ + /* */ + /* apatch :: The patch version number. */ + /* */ + /* <Note> */ + /* The reason why this function takes a `library' argument is because */ + /* certain programs implement library initialization in a custom way */ + /* that doesn't use @FT_Init_FreeType. */ + /* */ + /* In such cases, the library version might not be available before */ + /* the library object has been created. */ + /* */ + FT_EXPORT( void ) + FT_Library_Version( FT_Library library, + FT_Int *amajor, + FT_Int *aminor, + FT_Int *apatch ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Face_CheckTrueTypePatents */ + /* */ + /* <Description> */ + /* Parse all bytecode instructions of a TrueType font file to check */ + /* whether any of the patented opcodes are used. This is only useful */ + /* if you want to be able to use the unpatented hinter with */ + /* fonts that do *not* use these opcodes. */ + /* */ + /* Note that this function parses *all* glyph instructions in the */ + /* font file, which may be slow. */ + /* */ + /* <Input> */ + /* face :: A face handle. */ + /* */ + /* <Return> */ + /* 1~if this is a TrueType font that uses one of the patented */ + /* opcodes, 0~otherwise. */ + /* */ + /* <Since> */ + /* 2.3.5 */ + /* */ + FT_EXPORT( FT_Bool ) + FT_Face_CheckTrueTypePatents( FT_Face face ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Face_SetUnpatentedHinting */ + /* */ + /* <Description> */ + /* Enable or disable the unpatented hinter for a given face. */ + /* Only enable it if you have determined that the face doesn't */ + /* use any patented opcodes (see @FT_Face_CheckTrueTypePatents). */ + /* */ + /* <Input> */ + /* face :: A face handle. */ + /* */ + /* value :: New boolean setting. */ + /* */ + /* <Return> */ + /* The old setting value. This will always be false if this is not */ + /* an SFNT font, or if the unpatented hinter is not compiled in this */ + /* instance of the library. */ + /* */ + /* <Since> */ + /* 2.3.5 */ + /* */ + FT_EXPORT( FT_Bool ) + FT_Face_SetUnpatentedHinting( FT_Face face, + FT_Bool value ); + + /* */ + + +FT_END_HEADER + +#endif /* __FREETYPE_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/ftadvanc.h b/mod/pub.mod/freetype.mod/include/freetype/ftadvanc.h new file mode 100644 index 0000000..b2451be --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/ftadvanc.h @@ -0,0 +1,179 @@ +/***************************************************************************/ +/* */ +/* ftadvanc.h */ +/* */ +/* Quick computation of advance widths (specification only). */ +/* */ +/* Copyright 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTADVANC_H__ +#define __FTADVANC_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /************************************************************************** + * + * @section: + * quick_advance + * + * @title: + * Quick retrieval of advance values + * + * @abstract: + * Retrieve horizontal and vertical advance values without processing + * glyph outlines, if possible. + * + * @description: + * This section contains functions to quickly extract advance values + * without handling glyph outlines, if possible. + */ + + + /*************************************************************************/ + /* */ + /* <Const> */ + /* FT_ADVANCE_FLAG_FAST_ONLY */ + /* */ + /* <Description> */ + /* A bit-flag to be OR-ed with the `flags' parameter of the */ + /* @FT_Get_Advance and @FT_Get_Advances functions. */ + /* */ + /* If set, it indicates that you want these functions to fail if the */ + /* corresponding hinting mode or font driver doesn't allow for very */ + /* quick advance computation. */ + /* */ + /* Typically, glyphs which are either unscaled, unhinted, bitmapped, */ + /* or light-hinted can have their advance width computed very */ + /* quickly. */ + /* */ + /* Normal and bytecode hinted modes, which require loading, scaling, */ + /* and hinting of the glyph outline, are extremely slow by */ + /* comparison. */ + /* */ +#define FT_ADVANCE_FLAG_FAST_ONLY 0x20000000UL + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Advance */ + /* */ + /* <Description> */ + /* Retrieve the advance value of a given glyph outline in an */ + /* @FT_Face. By default, the unhinted advance is returned in font */ + /* units. */ + /* */ + /* <Input> */ + /* face :: The source @FT_Face handle. */ + /* */ + /* gindex :: The glyph index. */ + /* */ + /* load_flags :: A set of bit flags similar to those used when */ + /* calling @FT_Load_Glyph, used to determine what kind */ + /* of advances you need. */ + /* <Output> */ + /* padvance :: The advance value, in either font units or 16.16 */ + /* format. */ + /* */ + /* If @FT_LOAD_VERTICAL_LAYOUT is set, this is the */ + /* vertical advance corresponding to a vertical layout. */ + /* Otherwise, it is the horizontal advance in a */ + /* horizontal layout. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* This function may fail if you use @FT_ADVANCE_FLAG_FAST_ONLY and */ + /* if the corresponding font backend doesn't have a quick way to */ + /* retrieve the advances. */ + /* */ + /* A scaled advance is returned in 16.16 format but isn't transformed */ + /* by the affine transformation specified by @FT_Set_Transform. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Advance( FT_Face face, + FT_UInt gindex, + FT_Int32 load_flags, + FT_Fixed *padvance ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Advances */ + /* */ + /* <Description> */ + /* Retrieve the advance values of several glyph outlines in an */ + /* @FT_Face. By default, the unhinted advances are returned in font */ + /* units. */ + /* */ + /* <Input> */ + /* face :: The source @FT_Face handle. */ + /* */ + /* start :: The first glyph index. */ + /* */ + /* count :: The number of advance values you want to retrieve. */ + /* */ + /* load_flags :: A set of bit flags similar to those used when */ + /* calling @FT_Load_Glyph. */ + /* */ + /* <Output> */ + /* padvance :: The advances, in either font units or 16.16 format. */ + /* This array must contain at least `count' elements. */ + /* */ + /* If @FT_LOAD_VERTICAL_LAYOUT is set, these are the */ + /* vertical advances corresponding to a vertical layout. */ + /* Otherwise, they are the horizontal advances in a */ + /* horizontal layout. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* This function may fail if you use @FT_ADVANCE_FLAG_FAST_ONLY and */ + /* if the corresponding font backend doesn't have a quick way to */ + /* retrieve the advances. */ + /* */ + /* Scaled advances are returned in 16.16 format but aren't */ + /* transformed by the affine transformation specified by */ + /* @FT_Set_Transform. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Advances( FT_Face face, + FT_UInt start, + FT_UInt count, + FT_Int32 load_flags, + FT_Fixed *padvances ); + +/* */ + + +FT_END_HEADER + +#endif /* __FTADVANC_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/ftbbox.h b/mod/pub.mod/freetype.mod/include/freetype/ftbbox.h new file mode 100644 index 0000000..01fe3fb --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/ftbbox.h @@ -0,0 +1,94 @@ +/***************************************************************************/ +/* */ +/* ftbbox.h */ +/* */ +/* FreeType exact bbox computation (specification). */ +/* */ +/* Copyright 1996-2001, 2003, 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This component has a _single_ role: to compute exact outline bounding */ + /* boxes. */ + /* */ + /* It is separated from the rest of the engine for various technical */ + /* reasons. It may well be integrated in `ftoutln' later. */ + /* */ + /*************************************************************************/ + + +#ifndef __FTBBOX_H__ +#define __FTBBOX_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* outline_processing */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Get_BBox */ + /* */ + /* <Description> */ + /* Compute the exact bounding box of an outline. This is slower */ + /* than computing the control box. However, it uses an advanced */ + /* algorithm which returns _very_ quickly when the two boxes */ + /* coincide. Otherwise, the outline Bézier arcs are traversed to */ + /* extract their extrema. */ + /* */ + /* <Input> */ + /* outline :: A pointer to the source outline. */ + /* */ + /* <Output> */ + /* abbox :: The outline's exact bounding box. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_Get_BBox( FT_Outline* outline, + FT_BBox *abbox ); + + + /* */ + + +FT_END_HEADER + +#endif /* __FTBBOX_H__ */ + + +/* END */ + + +/* Local Variables: */ +/* coding: utf-8 */ +/* End: */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/ftbdf.h b/mod/pub.mod/freetype.mod/include/freetype/ftbdf.h new file mode 100644 index 0000000..4f8baf8 --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/ftbdf.h @@ -0,0 +1,209 @@ +/***************************************************************************/ +/* */ +/* ftbdf.h */ +/* */ +/* FreeType API for accessing BDF-specific strings (specification). */ +/* */ +/* Copyright 2002, 2003, 2004, 2006, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTBDF_H__ +#define __FTBDF_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* bdf_fonts */ + /* */ + /* <Title> */ + /* BDF and PCF Files */ + /* */ + /* <Abstract> */ + /* BDF and PCF specific API. */ + /* */ + /* <Description> */ + /* This section contains the declaration of functions specific to BDF */ + /* and PCF fonts. */ + /* */ + /*************************************************************************/ + + + /********************************************************************** + * + * @enum: + * FT_PropertyType + * + * @description: + * A list of BDF property types. + * + * @values: + * BDF_PROPERTY_TYPE_NONE :: + * Value~0 is used to indicate a missing property. + * + * BDF_PROPERTY_TYPE_ATOM :: + * Property is a string atom. + * + * BDF_PROPERTY_TYPE_INTEGER :: + * Property is a 32-bit signed integer. + * + * BDF_PROPERTY_TYPE_CARDINAL :: + * Property is a 32-bit unsigned integer. + */ + typedef enum BDF_PropertyType_ + { + BDF_PROPERTY_TYPE_NONE = 0, + BDF_PROPERTY_TYPE_ATOM = 1, + BDF_PROPERTY_TYPE_INTEGER = 2, + BDF_PROPERTY_TYPE_CARDINAL = 3 + + } BDF_PropertyType; + + + /********************************************************************** + * + * @type: + * BDF_Property + * + * @description: + * A handle to a @BDF_PropertyRec structure to model a given + * BDF/PCF property. + */ + typedef struct BDF_PropertyRec_* BDF_Property; + + + /********************************************************************** + * + * @struct: + * BDF_PropertyRec + * + * @description: + * This structure models a given BDF/PCF property. + * + * @fields: + * type :: + * The property type. + * + * u.atom :: + * The atom string, if type is @BDF_PROPERTY_TYPE_ATOM. + * + * u.integer :: + * A signed integer, if type is @BDF_PROPERTY_TYPE_INTEGER. + * + * u.cardinal :: + * An unsigned integer, if type is @BDF_PROPERTY_TYPE_CARDINAL. + */ + typedef struct BDF_PropertyRec_ + { + BDF_PropertyType type; + union { + const char* atom; + FT_Int32 integer; + FT_UInt32 cardinal; + + } u; + + } BDF_PropertyRec; + + + /********************************************************************** + * + * @function: + * FT_Get_BDF_Charset_ID + * + * @description: + * Retrieve a BDF font character set identity, according to + * the BDF specification. + * + * @input: + * face :: + * A handle to the input face. + * + * @output: + * acharset_encoding :: + * Charset encoding, as a C~string, owned by the face. + * + * acharset_registry :: + * Charset registry, as a C~string, owned by the face. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function only works with BDF faces, returning an error otherwise. + */ + FT_EXPORT( FT_Error ) + FT_Get_BDF_Charset_ID( FT_Face face, + const char* *acharset_encoding, + const char* *acharset_registry ); + + + /********************************************************************** + * + * @function: + * FT_Get_BDF_Property + * + * @description: + * Retrieve a BDF property from a BDF or PCF font file. + * + * @input: + * face :: A handle to the input face. + * + * name :: The property name. + * + * @output: + * aproperty :: The property. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function works with BDF _and_ PCF fonts. It returns an error + * otherwise. It also returns an error if the property is not in the + * font. + * + * A `property' is a either key-value pair within the STARTPROPERTIES + * ... ENDPROPERTIES block of a BDF font or a key-value pair from the + * `info->props' array within a `FontRec' structure of a PCF font. + * + * Integer properties are always stored as `signed' within PCF fonts; + * consequently, @BDF_PROPERTY_TYPE_CARDINAL is a possible return value + * for BDF fonts only. + * + * In case of error, `aproperty->type' is always set to + * @BDF_PROPERTY_TYPE_NONE. + */ + FT_EXPORT( FT_Error ) + FT_Get_BDF_Property( FT_Face face, + const char* prop_name, + BDF_PropertyRec *aproperty ); + + /* */ + +FT_END_HEADER + +#endif /* __FTBDF_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/ftbitmap.h b/mod/pub.mod/freetype.mod/include/freetype/ftbitmap.h new file mode 100644 index 0000000..9274236 --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/ftbitmap.h @@ -0,0 +1,227 @@ +/***************************************************************************/ +/* */ +/* ftbitmap.h */ +/* */ +/* FreeType utility functions for bitmaps (specification). */ +/* */ +/* Copyright 2004, 2005, 2006, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTBITMAP_H__ +#define __FTBITMAP_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* bitmap_handling */ + /* */ + /* <Title> */ + /* Bitmap Handling */ + /* */ + /* <Abstract> */ + /* Handling FT_Bitmap objects. */ + /* */ + /* <Description> */ + /* This section contains functions for converting FT_Bitmap objects. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Bitmap_New */ + /* */ + /* <Description> */ + /* Initialize a pointer to an @FT_Bitmap structure. */ + /* */ + /* <InOut> */ + /* abitmap :: A pointer to the bitmap structure. */ + /* */ + FT_EXPORT( void ) + FT_Bitmap_New( FT_Bitmap *abitmap ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Bitmap_Copy */ + /* */ + /* <Description> */ + /* Copy a bitmap into another one. */ + /* */ + /* <Input> */ + /* library :: A handle to a library object. */ + /* */ + /* source :: A handle to the source bitmap. */ + /* */ + /* <Output> */ + /* target :: A handle to the target bitmap. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Bitmap_Copy( FT_Library library, + const FT_Bitmap *source, + FT_Bitmap *target); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Bitmap_Embolden */ + /* */ + /* <Description> */ + /* Embolden a bitmap. The new bitmap will be about `xStrength' */ + /* pixels wider and `yStrength' pixels higher. The left and bottom */ + /* borders are kept unchanged. */ + /* */ + /* <Input> */ + /* library :: A handle to a library object. */ + /* */ + /* xStrength :: How strong the glyph is emboldened horizontally. */ + /* Expressed in 26.6 pixel format. */ + /* */ + /* yStrength :: How strong the glyph is emboldened vertically. */ + /* Expressed in 26.6 pixel format. */ + /* */ + /* <InOut> */ + /* bitmap :: A handle to the target bitmap. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The current implementation restricts `xStrength' to be less than */ + /* or equal to~8 if bitmap is of pixel_mode @FT_PIXEL_MODE_MONO. */ + /* */ + /* If you want to embolden the bitmap owned by a @FT_GlyphSlotRec, */ + /* you should call @FT_GlyphSlot_Own_Bitmap on the slot first. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Bitmap_Embolden( FT_Library library, + FT_Bitmap* bitmap, + FT_Pos xStrength, + FT_Pos yStrength ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Bitmap_Convert */ + /* */ + /* <Description> */ + /* Convert a bitmap object with depth 1bpp, 2bpp, 4bpp, or 8bpp to a */ + /* bitmap object with depth 8bpp, making the number of used bytes per */ + /* line (a.k.a. the `pitch') a multiple of `alignment'. */ + /* */ + /* <Input> */ + /* library :: A handle to a library object. */ + /* */ + /* source :: The source bitmap. */ + /* */ + /* alignment :: The pitch of the bitmap is a multiple of this */ + /* parameter. Common values are 1, 2, or 4. */ + /* */ + /* <Output> */ + /* target :: The target bitmap. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* It is possible to call @FT_Bitmap_Convert multiple times without */ + /* calling @FT_Bitmap_Done (the memory is simply reallocated). */ + /* */ + /* Use @FT_Bitmap_Done to finally remove the bitmap object. */ + /* */ + /* The `library' argument is taken to have access to FreeType's */ + /* memory handling functions. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Bitmap_Convert( FT_Library library, + const FT_Bitmap *source, + FT_Bitmap *target, + FT_Int alignment ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_GlyphSlot_Own_Bitmap */ + /* */ + /* <Description> */ + /* Make sure that a glyph slot owns `slot->bitmap'. */ + /* */ + /* <Input> */ + /* slot :: The glyph slot. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* This function is to be used in combination with */ + /* @FT_Bitmap_Embolden. */ + /* */ + FT_EXPORT( FT_Error ) + FT_GlyphSlot_Own_Bitmap( FT_GlyphSlot slot ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Bitmap_Done */ + /* */ + /* <Description> */ + /* Destroy a bitmap object created with @FT_Bitmap_New. */ + /* */ + /* <Input> */ + /* library :: A handle to a library object. */ + /* */ + /* bitmap :: The bitmap object to be freed. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The `library' argument is taken to have access to FreeType's */ + /* memory handling functions. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Bitmap_Done( FT_Library library, + FT_Bitmap *bitmap ); + + + /* */ + + +FT_END_HEADER + +#endif /* __FTBITMAP_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/ftcache.h b/mod/pub.mod/freetype.mod/include/freetype/ftcache.h new file mode 100644 index 0000000..0916d70 --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/ftcache.h @@ -0,0 +1,1125 @@ +/***************************************************************************/ +/* */ +/* ftcache.h */ +/* */ +/* FreeType Cache subsystem (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTCACHE_H__ +#define __FTCACHE_H__ + + +#include <ft2build.h> +#include FT_GLYPH_H + + +FT_BEGIN_HEADER + + + /************************************************************************* + * + * <Section> + * cache_subsystem + * + * <Title> + * Cache Sub-System + * + * <Abstract> + * How to cache face, size, and glyph data with FreeType~2. + * + * <Description> + * This section describes the FreeType~2 cache sub-system, which is used + * to limit the number of concurrently opened @FT_Face and @FT_Size + * objects, as well as caching information like character maps and glyph + * images while limiting their maximum memory usage. + * + * Note that all types and functions begin with the `FTC_' prefix. + * + * The cache is highly portable and thus doesn't know anything about the + * fonts installed on your system, or how to access them. This implies + * the following scheme: + * + * First, available or installed font faces are uniquely identified by + * @FTC_FaceID values, provided to the cache by the client. Note that + * the cache only stores and compares these values, and doesn't try to + * interpret them in any way. + * + * Second, the cache calls, only when needed, a client-provided function + * to convert a @FTC_FaceID into a new @FT_Face object. The latter is + * then completely managed by the cache, including its termination + * through @FT_Done_Face. + * + * Clients are free to map face IDs to anything else. The most simple + * usage is to associate them to a (pathname,face_index) pair that is + * used to call @FT_New_Face. However, more complex schemes are also + * possible. + * + * Note that for the cache to work correctly, the face ID values must be + * *persistent*, which means that the contents they point to should not + * change at runtime, or that their value should not become invalid. + * + * If this is unavoidable (e.g., when a font is uninstalled at runtime), + * you should call @FTC_Manager_RemoveFaceID as soon as possible, to let + * the cache get rid of any references to the old @FTC_FaceID it may + * keep internally. Failure to do so will lead to incorrect behaviour + * or even crashes. + * + * To use the cache, start with calling @FTC_Manager_New to create a new + * @FTC_Manager object, which models a single cache instance. You can + * then look up @FT_Face and @FT_Size objects with + * @FTC_Manager_LookupFace and @FTC_Manager_LookupSize, respectively. + * + * If you want to use the charmap caching, call @FTC_CMapCache_New, then + * later use @FTC_CMapCache_Lookup to perform the equivalent of + * @FT_Get_Char_Index, only much faster. + * + * If you want to use the @FT_Glyph caching, call @FTC_ImageCache, then + * later use @FTC_ImageCache_Lookup to retrieve the corresponding + * @FT_Glyph objects from the cache. + * + * If you need lots of small bitmaps, it is much more memory efficient + * to call @FTC_SBitCache_New followed by @FTC_SBitCache_Lookup. This + * returns @FTC_SBitRec structures, which are used to store small + * bitmaps directly. (A small bitmap is one whose metrics and + * dimensions all fit into 8-bit integers). + * + * We hope to also provide a kerning cache in the near future. + * + * + * <Order> + * FTC_Manager + * FTC_FaceID + * FTC_Face_Requester + * + * FTC_Manager_New + * FTC_Manager_Reset + * FTC_Manager_Done + * FTC_Manager_LookupFace + * FTC_Manager_LookupSize + * FTC_Manager_RemoveFaceID + * + * FTC_Node + * FTC_Node_Unref + * + * FTC_ImageCache + * FTC_ImageCache_New + * FTC_ImageCache_Lookup + * + * FTC_SBit + * FTC_SBitCache + * FTC_SBitCache_New + * FTC_SBitCache_Lookup + * + * FTC_CMapCache + * FTC_CMapCache_New + * FTC_CMapCache_Lookup + * + *************************************************************************/ + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** BASIC TYPE DEFINITIONS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /************************************************************************* + * + * @type: FTC_FaceID + * + * @description: + * An opaque pointer type that is used to identity face objects. The + * contents of such objects is application-dependent. + * + * These pointers are typically used to point to a user-defined + * structure containing a font file path, and face index. + * + * @note: + * Never use NULL as a valid @FTC_FaceID. + * + * Face IDs are passed by the client to the cache manager, which calls, + * when needed, the @FTC_Face_Requester to translate them into new + * @FT_Face objects. + * + * If the content of a given face ID changes at runtime, or if the value + * becomes invalid (e.g., when uninstalling a font), you should + * immediately call @FTC_Manager_RemoveFaceID before any other cache + * function. + * + * Failure to do so will result in incorrect behaviour or even + * memory leaks and crashes. + */ + typedef FT_Pointer FTC_FaceID; + + + /************************************************************************ + * + * @functype: + * FTC_Face_Requester + * + * @description: + * A callback function provided by client applications. It is used by + * the cache manager to translate a given @FTC_FaceID into a new valid + * @FT_Face object, on demand. + * + * <Input> + * face_id :: + * The face ID to resolve. + * + * library :: + * A handle to a FreeType library object. + * + * req_data :: + * Application-provided request data (see note below). + * + * <Output> + * aface :: + * A new @FT_Face handle. + * + * <Return> + * FreeType error code. 0~means success. + * + * <Note> + * The third parameter `req_data' is the same as the one passed by the + * client when @FTC_Manager_New is called. + * + * The face requester should not perform funny things on the returned + * face object, like creating a new @FT_Size for it, or setting a + * transformation through @FT_Set_Transform! + */ + typedef FT_Error + (*FTC_Face_Requester)( FTC_FaceID face_id, + FT_Library library, + FT_Pointer request_data, + FT_Face* aface ); + + /* */ + +#define FT_POINTER_TO_ULONG( p ) ( (FT_ULong)(FT_Pointer)(p) ) + +#define FTC_FACE_ID_HASH( i ) \ + ((FT_UInt32)(( FT_POINTER_TO_ULONG( i ) >> 3 ) ^ \ + ( FT_POINTER_TO_ULONG( i ) << 7 ) ) ) + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** CACHE MANAGER OBJECT *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FTC_Manager */ + /* */ + /* <Description> */ + /* This object corresponds to one instance of the cache-subsystem. */ + /* It is used to cache one or more @FT_Face objects, along with */ + /* corresponding @FT_Size objects. */ + /* */ + /* The manager intentionally limits the total number of opened */ + /* @FT_Face and @FT_Size objects to control memory usage. See the */ + /* `max_faces' and `max_sizes' parameters of @FTC_Manager_New. */ + /* */ + /* The manager is also used to cache `nodes' of various types while */ + /* limiting their total memory usage. */ + /* */ + /* All limitations are enforced by keeping lists of managed objects */ + /* in most-recently-used order, and flushing old nodes to make room */ + /* for new ones. */ + /* */ + typedef struct FTC_ManagerRec_* FTC_Manager; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FTC_Node */ + /* */ + /* <Description> */ + /* An opaque handle to a cache node object. Each cache node is */ + /* reference-counted. A node with a count of~0 might be flushed */ + /* out of a full cache whenever a lookup request is performed. */ + /* */ + /* If you lookup nodes, you have the ability to `acquire' them, i.e., */ + /* to increment their reference count. This will prevent the node */ + /* from being flushed out of the cache until you explicitly `release' */ + /* it (see @FTC_Node_Unref). */ + /* */ + /* See also @FTC_SBitCache_Lookup and @FTC_ImageCache_Lookup. */ + /* */ + typedef struct FTC_NodeRec_* FTC_Node; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_Manager_New */ + /* */ + /* <Description> */ + /* Create a new cache manager. */ + /* */ + /* <Input> */ + /* library :: The parent FreeType library handle to use. */ + /* */ + /* max_faces :: Maximum number of opened @FT_Face objects managed by */ + /* this cache instance. Use~0 for defaults. */ + /* */ + /* max_sizes :: Maximum number of opened @FT_Size objects managed by */ + /* this cache instance. Use~0 for defaults. */ + /* */ + /* max_bytes :: Maximum number of bytes to use for cached data nodes. */ + /* Use~0 for defaults. Note that this value does not */ + /* account for managed @FT_Face and @FT_Size objects. */ + /* */ + /* requester :: An application-provided callback used to translate */ + /* face IDs into real @FT_Face objects. */ + /* */ + /* req_data :: A generic pointer that is passed to the requester */ + /* each time it is called (see @FTC_Face_Requester). */ + /* */ + /* <Output> */ + /* amanager :: A handle to a new manager object. 0~in case of */ + /* failure. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FTC_Manager_New( FT_Library library, + FT_UInt max_faces, + FT_UInt max_sizes, + FT_ULong max_bytes, + FTC_Face_Requester requester, + FT_Pointer req_data, + FTC_Manager *amanager ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_Manager_Reset */ + /* */ + /* <Description> */ + /* Empty a given cache manager. This simply gets rid of all the */ + /* currently cached @FT_Face and @FT_Size objects within the manager. */ + /* */ + /* <InOut> */ + /* manager :: A handle to the manager. */ + /* */ + FT_EXPORT( void ) + FTC_Manager_Reset( FTC_Manager manager ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_Manager_Done */ + /* */ + /* <Description> */ + /* Destroy a given manager after emptying it. */ + /* */ + /* <Input> */ + /* manager :: A handle to the target cache manager object. */ + /* */ + FT_EXPORT( void ) + FTC_Manager_Done( FTC_Manager manager ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_Manager_LookupFace */ + /* */ + /* <Description> */ + /* Retrieve the @FT_Face object that corresponds to a given face ID */ + /* through a cache manager. */ + /* */ + /* <Input> */ + /* manager :: A handle to the cache manager. */ + /* */ + /* face_id :: The ID of the face object. */ + /* */ + /* <Output> */ + /* aface :: A handle to the face object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The returned @FT_Face object is always owned by the manager. You */ + /* should never try to discard it yourself. */ + /* */ + /* The @FT_Face object doesn't necessarily have a current size object */ + /* (i.e., face->size can be 0). If you need a specific `font size', */ + /* use @FTC_Manager_LookupSize instead. */ + /* */ + /* Never change the face's transformation matrix (i.e., never call */ + /* the @FT_Set_Transform function) on a returned face! If you need */ + /* to transform glyphs, do it yourself after glyph loading. */ + /* */ + /* When you perform a lookup, out-of-memory errors are detected */ + /* _within_ the lookup and force incremental flushes of the cache */ + /* until enough memory is released for the lookup to succeed. */ + /* */ + /* If a lookup fails with `FT_Err_Out_Of_Memory' the cache has */ + /* already been completely flushed, and still no memory was available */ + /* for the operation. */ + /* */ + FT_EXPORT( FT_Error ) + FTC_Manager_LookupFace( FTC_Manager manager, + FTC_FaceID face_id, + FT_Face *aface ); + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FTC_ScalerRec */ + /* */ + /* <Description> */ + /* A structure used to describe a given character size in either */ + /* pixels or points to the cache manager. See */ + /* @FTC_Manager_LookupSize. */ + /* */ + /* <Fields> */ + /* face_id :: The source face ID. */ + /* */ + /* width :: The character width. */ + /* */ + /* height :: The character height. */ + /* */ + /* pixel :: A Boolean. If 1, the `width' and `height' fields are */ + /* interpreted as integer pixel character sizes. */ + /* Otherwise, they are expressed as 1/64th of points. */ + /* */ + /* x_res :: Only used when `pixel' is value~0 to indicate the */ + /* horizontal resolution in dpi. */ + /* */ + /* y_res :: Only used when `pixel' is value~0 to indicate the */ + /* vertical resolution in dpi. */ + /* */ + /* <Note> */ + /* This type is mainly used to retrieve @FT_Size objects through the */ + /* cache manager. */ + /* */ + typedef struct FTC_ScalerRec_ + { + FTC_FaceID face_id; + FT_UInt width; + FT_UInt height; + FT_Int pixel; + FT_UInt x_res; + FT_UInt y_res; + + } FTC_ScalerRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FTC_Scaler */ + /* */ + /* <Description> */ + /* A handle to an @FTC_ScalerRec structure. */ + /* */ + typedef struct FTC_ScalerRec_* FTC_Scaler; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_Manager_LookupSize */ + /* */ + /* <Description> */ + /* Retrieve the @FT_Size object that corresponds to a given */ + /* @FTC_ScalerRec pointer through a cache manager. */ + /* */ + /* <Input> */ + /* manager :: A handle to the cache manager. */ + /* */ + /* scaler :: A scaler handle. */ + /* */ + /* <Output> */ + /* asize :: A handle to the size object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The returned @FT_Size object is always owned by the manager. You */ + /* should never try to discard it by yourself. */ + /* */ + /* You can access the parent @FT_Face object simply as `size->face' */ + /* if you need it. Note that this object is also owned by the */ + /* manager. */ + /* */ + /* <Note> */ + /* When you perform a lookup, out-of-memory errors are detected */ + /* _within_ the lookup and force incremental flushes of the cache */ + /* until enough memory is released for the lookup to succeed. */ + /* */ + /* If a lookup fails with `FT_Err_Out_Of_Memory' the cache has */ + /* already been completely flushed, and still no memory is available */ + /* for the operation. */ + /* */ + FT_EXPORT( FT_Error ) + FTC_Manager_LookupSize( FTC_Manager manager, + FTC_Scaler scaler, + FT_Size *asize ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_Node_Unref */ + /* */ + /* <Description> */ + /* Decrement a cache node's internal reference count. When the count */ + /* reaches 0, it is not destroyed but becomes eligible for subsequent */ + /* cache flushes. */ + /* */ + /* <Input> */ + /* node :: The cache node handle. */ + /* */ + /* manager :: The cache manager handle. */ + /* */ + FT_EXPORT( void ) + FTC_Node_Unref( FTC_Node node, + FTC_Manager manager ); + + + /************************************************************************* + * + * @function: + * FTC_Manager_RemoveFaceID + * + * @description: + * A special function used to indicate to the cache manager that + * a given @FTC_FaceID is no longer valid, either because its + * content changed, or because it was deallocated or uninstalled. + * + * @input: + * manager :: + * The cache manager handle. + * + * face_id :: + * The @FTC_FaceID to be removed. + * + * @note: + * This function flushes all nodes from the cache corresponding to this + * `face_id', with the exception of nodes with a non-null reference + * count. + * + * Such nodes are however modified internally so as to never appear + * in later lookups with the same `face_id' value, and to be immediately + * destroyed when released by all their users. + * + */ + FT_EXPORT( void ) + FTC_Manager_RemoveFaceID( FTC_Manager manager, + FTC_FaceID face_id ); + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* cache_subsystem */ + /* */ + /*************************************************************************/ + + /************************************************************************* + * + * @type: + * FTC_CMapCache + * + * @description: + * An opaque handle used to model a charmap cache. This cache is to + * hold character codes -> glyph indices mappings. + * + */ + typedef struct FTC_CMapCacheRec_* FTC_CMapCache; + + + /************************************************************************* + * + * @function: + * FTC_CMapCache_New + * + * @description: + * Create a new charmap cache. + * + * @input: + * manager :: + * A handle to the cache manager. + * + * @output: + * acache :: + * A new cache handle. NULL in case of error. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * Like all other caches, this one will be destroyed with the cache + * manager. + * + */ + FT_EXPORT( FT_Error ) + FTC_CMapCache_New( FTC_Manager manager, + FTC_CMapCache *acache ); + + + /************************************************************************ + * + * @function: + * FTC_CMapCache_Lookup + * + * @description: + * Translate a character code into a glyph index, using the charmap + * cache. + * + * @input: + * cache :: + * A charmap cache handle. + * + * face_id :: + * The source face ID. + * + * cmap_index :: + * The index of the charmap in the source face. Any negative value + * means to use the cache @FT_Face's default charmap. + * + * char_code :: + * The character code (in the corresponding charmap). + * + * @return: + * Glyph index. 0~means `no glyph'. + * + */ + FT_EXPORT( FT_UInt ) + FTC_CMapCache_Lookup( FTC_CMapCache cache, + FTC_FaceID face_id, + FT_Int cmap_index, + FT_UInt32 char_code ); + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* cache_subsystem */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** IMAGE CACHE OBJECT *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /************************************************************************* + * + * @struct: + * FTC_ImageTypeRec + * + * @description: + * A structure used to model the type of images in a glyph cache. + * + * @fields: + * face_id :: + * The face ID. + * + * width :: + * The width in pixels. + * + * height :: + * The height in pixels. + * + * flags :: + * The load flags, as in @FT_Load_Glyph. + * + */ + typedef struct FTC_ImageTypeRec_ + { + FTC_FaceID face_id; + FT_Int width; + FT_Int height; + FT_Int32 flags; + + } FTC_ImageTypeRec; + + + /************************************************************************* + * + * @type: + * FTC_ImageType + * + * @description: + * A handle to an @FTC_ImageTypeRec structure. + * + */ + typedef struct FTC_ImageTypeRec_* FTC_ImageType; + + + /* */ + + +#define FTC_IMAGE_TYPE_COMPARE( d1, d2 ) \ + ( (d1)->face_id == (d2)->face_id && \ + (d1)->width == (d2)->width && \ + (d1)->flags == (d2)->flags ) + +#define FTC_IMAGE_TYPE_HASH( d ) \ + (FT_UFast)( FTC_FACE_ID_HASH( (d)->face_id ) ^ \ + ( (d)->width << 8 ) ^ (d)->height ^ \ + ( (d)->flags << 4 ) ) + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FTC_ImageCache */ + /* */ + /* <Description> */ + /* A handle to an glyph image cache object. They are designed to */ + /* hold many distinct glyph images while not exceeding a certain */ + /* memory threshold. */ + /* */ + typedef struct FTC_ImageCacheRec_* FTC_ImageCache; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_ImageCache_New */ + /* */ + /* <Description> */ + /* Create a new glyph image cache. */ + /* */ + /* <Input> */ + /* manager :: The parent manager for the image cache. */ + /* */ + /* <Output> */ + /* acache :: A handle to the new glyph image cache object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FTC_ImageCache_New( FTC_Manager manager, + FTC_ImageCache *acache ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_ImageCache_Lookup */ + /* */ + /* <Description> */ + /* Retrieve a given glyph image from a glyph image cache. */ + /* */ + /* <Input> */ + /* cache :: A handle to the source glyph image cache. */ + /* */ + /* type :: A pointer to a glyph image type descriptor. */ + /* */ + /* gindex :: The glyph index to retrieve. */ + /* */ + /* <Output> */ + /* aglyph :: The corresponding @FT_Glyph object. 0~in case of */ + /* failure. */ + /* */ + /* anode :: Used to return the address of of the corresponding cache */ + /* node after incrementing its reference count (see note */ + /* below). */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The returned glyph is owned and managed by the glyph image cache. */ + /* Never try to transform or discard it manually! You can however */ + /* create a copy with @FT_Glyph_Copy and modify the new one. */ + /* */ + /* If `anode' is _not_ NULL, it receives the address of the cache */ + /* node containing the glyph image, after increasing its reference */ + /* count. This ensures that the node (as well as the @FT_Glyph) will */ + /* always be kept in the cache until you call @FTC_Node_Unref to */ + /* `release' it. */ + /* */ + /* If `anode' is NULL, the cache node is left unchanged, which means */ + /* that the @FT_Glyph could be flushed out of the cache on the next */ + /* call to one of the caching sub-system APIs. Don't assume that it */ + /* is persistent! */ + /* */ + FT_EXPORT( FT_Error ) + FTC_ImageCache_Lookup( FTC_ImageCache cache, + FTC_ImageType type, + FT_UInt gindex, + FT_Glyph *aglyph, + FTC_Node *anode ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_ImageCache_LookupScaler */ + /* */ + /* <Description> */ + /* A variant of @FTC_ImageCache_Lookup that uses an @FTC_ScalerRec */ + /* to specify the face ID and its size. */ + /* */ + /* <Input> */ + /* cache :: A handle to the source glyph image cache. */ + /* */ + /* scaler :: A pointer to a scaler descriptor. */ + /* */ + /* load_flags :: The corresponding load flags. */ + /* */ + /* gindex :: The glyph index to retrieve. */ + /* */ + /* <Output> */ + /* aglyph :: The corresponding @FT_Glyph object. 0~in case of */ + /* failure. */ + /* */ + /* anode :: Used to return the address of of the corresponding */ + /* cache node after incrementing its reference count */ + /* (see note below). */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The returned glyph is owned and managed by the glyph image cache. */ + /* Never try to transform or discard it manually! You can however */ + /* create a copy with @FT_Glyph_Copy and modify the new one. */ + /* */ + /* If `anode' is _not_ NULL, it receives the address of the cache */ + /* node containing the glyph image, after increasing its reference */ + /* count. This ensures that the node (as well as the @FT_Glyph) will */ + /* always be kept in the cache until you call @FTC_Node_Unref to */ + /* `release' it. */ + /* */ + /* If `anode' is NULL, the cache node is left unchanged, which means */ + /* that the @FT_Glyph could be flushed out of the cache on the next */ + /* call to one of the caching sub-system APIs. Don't assume that it */ + /* is persistent! */ + /* */ + /* Calls to @FT_Set_Char_Size and friends have no effect on cached */ + /* glyphs; you should always use the FreeType cache API instead. */ + /* */ + FT_EXPORT( FT_Error ) + FTC_ImageCache_LookupScaler( FTC_ImageCache cache, + FTC_Scaler scaler, + FT_ULong load_flags, + FT_UInt gindex, + FT_Glyph *aglyph, + FTC_Node *anode ); + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FTC_SBit */ + /* */ + /* <Description> */ + /* A handle to a small bitmap descriptor. See the @FTC_SBitRec */ + /* structure for details. */ + /* */ + typedef struct FTC_SBitRec_* FTC_SBit; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FTC_SBitRec */ + /* */ + /* <Description> */ + /* A very compact structure used to describe a small glyph bitmap. */ + /* */ + /* <Fields> */ + /* width :: The bitmap width in pixels. */ + /* */ + /* height :: The bitmap height in pixels. */ + /* */ + /* left :: The horizontal distance from the pen position to the */ + /* left bitmap border (a.k.a. `left side bearing', or */ + /* `lsb'). */ + /* */ + /* top :: The vertical distance from the pen position (on the */ + /* baseline) to the upper bitmap border (a.k.a. `top */ + /* side bearing'). The distance is positive for upwards */ + /* y~coordinates. */ + /* */ + /* format :: The format of the glyph bitmap (monochrome or gray). */ + /* */ + /* max_grays :: Maximum gray level value (in the range 1 to~255). */ + /* */ + /* pitch :: The number of bytes per bitmap line. May be positive */ + /* or negative. */ + /* */ + /* xadvance :: The horizontal advance width in pixels. */ + /* */ + /* yadvance :: The vertical advance height in pixels. */ + /* */ + /* buffer :: A pointer to the bitmap pixels. */ + /* */ + typedef struct FTC_SBitRec_ + { + FT_Byte width; + FT_Byte height; + FT_Char left; + FT_Char top; + + FT_Byte format; + FT_Byte max_grays; + FT_Short pitch; + FT_Char xadvance; + FT_Char yadvance; + + FT_Byte* buffer; + + } FTC_SBitRec; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FTC_SBitCache */ + /* */ + /* <Description> */ + /* A handle to a small bitmap cache. These are special cache objects */ + /* used to store small glyph bitmaps (and anti-aliased pixmaps) in a */ + /* much more efficient way than the traditional glyph image cache */ + /* implemented by @FTC_ImageCache. */ + /* */ + typedef struct FTC_SBitCacheRec_* FTC_SBitCache; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_SBitCache_New */ + /* */ + /* <Description> */ + /* Create a new cache to store small glyph bitmaps. */ + /* */ + /* <Input> */ + /* manager :: A handle to the source cache manager. */ + /* */ + /* <Output> */ + /* acache :: A handle to the new sbit cache. NULL in case of error. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FTC_SBitCache_New( FTC_Manager manager, + FTC_SBitCache *acache ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_SBitCache_Lookup */ + /* */ + /* <Description> */ + /* Look up a given small glyph bitmap in a given sbit cache and */ + /* `lock' it to prevent its flushing from the cache until needed. */ + /* */ + /* <Input> */ + /* cache :: A handle to the source sbit cache. */ + /* */ + /* type :: A pointer to the glyph image type descriptor. */ + /* */ + /* gindex :: The glyph index. */ + /* */ + /* <Output> */ + /* sbit :: A handle to a small bitmap descriptor. */ + /* */ + /* anode :: Used to return the address of of the corresponding cache */ + /* node after incrementing its reference count (see note */ + /* below). */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The small bitmap descriptor and its bit buffer are owned by the */ + /* cache and should never be freed by the application. They might */ + /* as well disappear from memory on the next cache lookup, so don't */ + /* treat them as persistent data. */ + /* */ + /* The descriptor's `buffer' field is set to~0 to indicate a missing */ + /* glyph bitmap. */ + /* */ + /* If `anode' is _not_ NULL, it receives the address of the cache */ + /* node containing the bitmap, after increasing its reference count. */ + /* This ensures that the node (as well as the image) will always be */ + /* kept in the cache until you call @FTC_Node_Unref to `release' it. */ + /* */ + /* If `anode' is NULL, the cache node is left unchanged, which means */ + /* that the bitmap could be flushed out of the cache on the next */ + /* call to one of the caching sub-system APIs. Don't assume that it */ + /* is persistent! */ + /* */ + FT_EXPORT( FT_Error ) + FTC_SBitCache_Lookup( FTC_SBitCache cache, + FTC_ImageType type, + FT_UInt gindex, + FTC_SBit *sbit, + FTC_Node *anode ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_SBitCache_LookupScaler */ + /* */ + /* <Description> */ + /* A variant of @FTC_SBitCache_Lookup that uses an @FTC_ScalerRec */ + /* to specify the face ID and its size. */ + /* */ + /* <Input> */ + /* cache :: A handle to the source sbit cache. */ + /* */ + /* scaler :: A pointer to the scaler descriptor. */ + /* */ + /* load_flags :: The corresponding load flags. */ + /* */ + /* gindex :: The glyph index. */ + /* */ + /* <Output> */ + /* sbit :: A handle to a small bitmap descriptor. */ + /* */ + /* anode :: Used to return the address of of the corresponding */ + /* cache node after incrementing its reference count */ + /* (see note below). */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The small bitmap descriptor and its bit buffer are owned by the */ + /* cache and should never be freed by the application. They might */ + /* as well disappear from memory on the next cache lookup, so don't */ + /* treat them as persistent data. */ + /* */ + /* The descriptor's `buffer' field is set to~0 to indicate a missing */ + /* glyph bitmap. */ + /* */ + /* If `anode' is _not_ NULL, it receives the address of the cache */ + /* node containing the bitmap, after increasing its reference count. */ + /* This ensures that the node (as well as the image) will always be */ + /* kept in the cache until you call @FTC_Node_Unref to `release' it. */ + /* */ + /* If `anode' is NULL, the cache node is left unchanged, which means */ + /* that the bitmap could be flushed out of the cache on the next */ + /* call to one of the caching sub-system APIs. Don't assume that it */ + /* is persistent! */ + /* */ + FT_EXPORT( FT_Error ) + FTC_SBitCache_LookupScaler( FTC_SBitCache cache, + FTC_Scaler scaler, + FT_ULong load_flags, + FT_UInt gindex, + FTC_SBit *sbit, + FTC_Node *anode ); + + + /* */ + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + + /*@***********************************************************************/ + /* */ + /* <Struct> */ + /* FTC_FontRec */ + /* */ + /* <Description> */ + /* A simple structure used to describe a given `font' to the cache */ + /* manager. Note that a `font' is the combination of a given face */ + /* with a given character size. */ + /* */ + /* <Fields> */ + /* face_id :: The ID of the face to use. */ + /* */ + /* pix_width :: The character width in integer pixels. */ + /* */ + /* pix_height :: The character height in integer pixels. */ + /* */ + typedef struct FTC_FontRec_ + { + FTC_FaceID face_id; + FT_UShort pix_width; + FT_UShort pix_height; + + } FTC_FontRec; + + + /* */ + + +#define FTC_FONT_COMPARE( f1, f2 ) \ + ( (f1)->face_id == (f2)->face_id && \ + (f1)->pix_width == (f2)->pix_width && \ + (f1)->pix_height == (f2)->pix_height ) + +#define FTC_FONT_HASH( f ) \ + (FT_UInt32)( FTC_FACE_ID_HASH((f)->face_id) ^ \ + ((f)->pix_width << 8) ^ \ + ((f)->pix_height) ) + + typedef FTC_FontRec* FTC_Font; + + + FT_EXPORT( FT_Error ) + FTC_Manager_Lookup_Face( FTC_Manager manager, + FTC_FaceID face_id, + FT_Face *aface ); + + FT_EXPORT( FT_Error ) + FTC_Manager_Lookup_Size( FTC_Manager manager, + FTC_Font font, + FT_Face *aface, + FT_Size *asize ); + +#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */ + + + /* */ + +FT_END_HEADER + +#endif /* __FTCACHE_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/ftchapters.h b/mod/pub.mod/freetype.mod/include/freetype/ftchapters.h new file mode 100644 index 0000000..7775a6b --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/ftchapters.h @@ -0,0 +1,103 @@ +/***************************************************************************/ +/* */ +/* This file defines the structure of the FreeType reference. */ +/* It is used by the python script which generates the HTML files. */ +/* */ +/***************************************************************************/ + + +/***************************************************************************/ +/* */ +/* <Chapter> */ +/* general_remarks */ +/* */ +/* <Title> */ +/* General Remarks */ +/* */ +/* <Sections> */ +/* user_allocation */ +/* */ +/***************************************************************************/ + + +/***************************************************************************/ +/* */ +/* <Chapter> */ +/* core_api */ +/* */ +/* <Title> */ +/* Core API */ +/* */ +/* <Sections> */ +/* version */ +/* basic_types */ +/* base_interface */ +/* glyph_variants */ +/* glyph_management */ +/* mac_specific */ +/* sizes_management */ +/* header_file_macros */ +/* */ +/***************************************************************************/ + + +/***************************************************************************/ +/* */ +/* <Chapter> */ +/* format_specific */ +/* */ +/* <Title> */ +/* Format-Specific API */ +/* */ +/* <Sections> */ +/* multiple_masters */ +/* truetype_tables */ +/* type1_tables */ +/* sfnt_names */ +/* bdf_fonts */ +/* cid_fonts */ +/* pfr_fonts */ +/* winfnt_fonts */ +/* font_formats */ +/* gasp_table */ +/* */ +/***************************************************************************/ + + +/***************************************************************************/ +/* */ +/* <Chapter> */ +/* cache_subsystem */ +/* */ +/* <Title> */ +/* Cache Sub-System */ +/* */ +/* <Sections> */ +/* cache_subsystem */ +/* */ +/***************************************************************************/ + + +/***************************************************************************/ +/* */ +/* <Chapter> */ +/* support_api */ +/* */ +/* <Title> */ +/* Support API */ +/* */ +/* <Sections> */ +/* computations */ +/* list_processing */ +/* outline_processing */ +/* quick_advance */ +/* bitmap_handling */ +/* raster */ +/* glyph_stroker */ +/* system_interface */ +/* module_management */ +/* gzip */ +/* lzw */ +/* lcd_filtering */ +/* */ +/***************************************************************************/ diff --git a/mod/pub.mod/freetype.mod/include/freetype/ftcid.h b/mod/pub.mod/freetype.mod/include/freetype/ftcid.h new file mode 100644 index 0000000..203a30c --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/ftcid.h @@ -0,0 +1,166 @@ +/***************************************************************************/ +/* */ +/* ftcid.h */ +/* */ +/* FreeType API for accessing CID font information (specification). */ +/* */ +/* Copyright 2007, 2009 by Dereg Clegg, Michael Toftdal. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTCID_H__ +#define __FTCID_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* cid_fonts */ + /* */ + /* <Title> */ + /* CID Fonts */ + /* */ + /* <Abstract> */ + /* CID-keyed font specific API. */ + /* */ + /* <Description> */ + /* This section contains the declaration of CID-keyed font specific */ + /* functions. */ + /* */ + /*************************************************************************/ + + + /********************************************************************** + * + * @function: + * FT_Get_CID_Registry_Ordering_Supplement + * + * @description: + * Retrieve the Registry/Ordering/Supplement triple (also known as the + * "R/O/S") from a CID-keyed font. + * + * @input: + * face :: + * A handle to the input face. + * + * @output: + * registry :: + * The registry, as a C~string, owned by the face. + * + * ordering :: + * The ordering, as a C~string, owned by the face. + * + * supplement :: + * The supplement. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function only works with CID faces, returning an error + * otherwise. + * + * @since: + * 2.3.6 + */ + FT_EXPORT( FT_Error ) + FT_Get_CID_Registry_Ordering_Supplement( FT_Face face, + const char* *registry, + const char* *ordering, + FT_Int *supplement); + + + /********************************************************************** + * + * @function: + * FT_Get_CID_Is_Internally_CID_Keyed + * + * @description: + * Retrieve the type of the input face, CID keyed or not. In + * constrast to the @FT_IS_CID_KEYED macro this function returns + * successfully also for CID-keyed fonts in an SNFT wrapper. + * + * @input: + * face :: + * A handle to the input face. + * + * @output: + * is_cid :: + * The type of the face as an @FT_Bool. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function only works with CID faces and OpenType fonts, + * returning an error otherwise. + * + * @since: + * 2.3.9 + */ + FT_EXPORT( FT_Error ) + FT_Get_CID_Is_Internally_CID_Keyed( FT_Face face, + FT_Bool *is_cid ); + + + /********************************************************************** + * + * @function: + * FT_Get_CID_From_Glyph_Index + * + * @description: + * Retrieve the CID of the input glyph index. + * + * @input: + * face :: + * A handle to the input face. + * + * glyph_index :: + * The input glyph index. + * + * @output: + * cid :: + * The CID as an @FT_UInt. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function only works with CID faces and OpenType fonts, + * returning an error otherwise. + * + * @since: + * 2.3.9 + */ + FT_EXPORT( FT_Error ) + FT_Get_CID_From_Glyph_Index( FT_Face face, + FT_UInt glyph_index, + FT_UInt *cid ); + + /* */ + +FT_END_HEADER + +#endif /* __FTCID_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/fterrdef.h b/mod/pub.mod/freetype.mod/include/freetype/fterrdef.h new file mode 100644 index 0000000..d7ad256 --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/fterrdef.h @@ -0,0 +1,239 @@ +/***************************************************************************/ +/* */ +/* fterrdef.h */ +/* */ +/* FreeType error codes (specification). */ +/* */ +/* Copyright 2002, 2004, 2006, 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*******************************************************************/ + /*******************************************************************/ + /***** *****/ + /***** LIST OF ERROR CODES/MESSAGES *****/ + /***** *****/ + /*******************************************************************/ + /*******************************************************************/ + + + /* You need to define both FT_ERRORDEF_ and FT_NOERRORDEF_ before */ + /* including this file. */ + + + /* generic errors */ + + FT_NOERRORDEF_( Ok, 0x00, \ + "no error" ) + + FT_ERRORDEF_( Cannot_Open_Resource, 0x01, \ + "cannot open resource" ) + FT_ERRORDEF_( Unknown_File_Format, 0x02, \ + "unknown file format" ) + FT_ERRORDEF_( Invalid_File_Format, 0x03, \ + "broken file" ) + FT_ERRORDEF_( Invalid_Version, 0x04, \ + "invalid FreeType version" ) + FT_ERRORDEF_( Lower_Module_Version, 0x05, \ + "module version is too low" ) + FT_ERRORDEF_( Invalid_Argument, 0x06, \ + "invalid argument" ) + FT_ERRORDEF_( Unimplemented_Feature, 0x07, \ + "unimplemented feature" ) + FT_ERRORDEF_( Invalid_Table, 0x08, \ + "broken table" ) + FT_ERRORDEF_( Invalid_Offset, 0x09, \ + "broken offset within table" ) + FT_ERRORDEF_( Array_Too_Large, 0x0A, \ + "array allocation size too large" ) + + /* glyph/character errors */ + + FT_ERRORDEF_( Invalid_Glyph_Index, 0x10, \ + "invalid glyph index" ) + FT_ERRORDEF_( Invalid_Character_Code, 0x11, \ + "invalid character code" ) + FT_ERRORDEF_( Invalid_Glyph_Format, 0x12, \ + "unsupported glyph image format" ) + FT_ERRORDEF_( Cannot_Render_Glyph, 0x13, \ + "cannot render this glyph format" ) + FT_ERRORDEF_( Invalid_Outline, 0x14, \ + "invalid outline" ) + FT_ERRORDEF_( Invalid_Composite, 0x15, \ + "invalid composite glyph" ) + FT_ERRORDEF_( Too_Many_Hints, 0x16, \ + "too many hints" ) + FT_ERRORDEF_( Invalid_Pixel_Size, 0x17, \ + "invalid pixel size" ) + + /* handle errors */ + + FT_ERRORDEF_( Invalid_Handle, 0x20, \ + "invalid object handle" ) + FT_ERRORDEF_( Invalid_Library_Handle, 0x21, \ + "invalid library handle" ) + FT_ERRORDEF_( Invalid_Driver_Handle, 0x22, \ + "invalid module handle" ) + FT_ERRORDEF_( Invalid_Face_Handle, 0x23, \ + "invalid face handle" ) + FT_ERRORDEF_( Invalid_Size_Handle, 0x24, \ + "invalid size handle" ) + FT_ERRORDEF_( Invalid_Slot_Handle, 0x25, \ + "invalid glyph slot handle" ) + FT_ERRORDEF_( Invalid_CharMap_Handle, 0x26, \ + "invalid charmap handle" ) + FT_ERRORDEF_( Invalid_Cache_Handle, 0x27, \ + "invalid cache manager handle" ) + FT_ERRORDEF_( Invalid_Stream_Handle, 0x28, \ + "invalid stream handle" ) + + /* driver errors */ + + FT_ERRORDEF_( Too_Many_Drivers, 0x30, \ + "too many modules" ) + FT_ERRORDEF_( Too_Many_Extensions, 0x31, \ + "too many extensions" ) + + /* memory errors */ + + FT_ERRORDEF_( Out_Of_Memory, 0x40, \ + "out of memory" ) + FT_ERRORDEF_( Unlisted_Object, 0x41, \ + "unlisted object" ) + + /* stream errors */ + + FT_ERRORDEF_( Cannot_Open_Stream, 0x51, \ + "cannot open stream" ) + FT_ERRORDEF_( Invalid_Stream_Seek, 0x52, \ + "invalid stream seek" ) + FT_ERRORDEF_( Invalid_Stream_Skip, 0x53, \ + "invalid stream skip" ) + FT_ERRORDEF_( Invalid_Stream_Read, 0x54, \ + "invalid stream read" ) + FT_ERRORDEF_( Invalid_Stream_Operation, 0x55, \ + "invalid stream operation" ) + FT_ERRORDEF_( Invalid_Frame_Operation, 0x56, \ + "invalid frame operation" ) + FT_ERRORDEF_( Nested_Frame_Access, 0x57, \ + "nested frame access" ) + FT_ERRORDEF_( Invalid_Frame_Read, 0x58, \ + "invalid frame read" ) + + /* raster errors */ + + FT_ERRORDEF_( Raster_Uninitialized, 0x60, \ + "raster uninitialized" ) + FT_ERRORDEF_( Raster_Corrupted, 0x61, \ + "raster corrupted" ) + FT_ERRORDEF_( Raster_Overflow, 0x62, \ + "raster overflow" ) + FT_ERRORDEF_( Raster_Negative_Height, 0x63, \ + "negative height while rastering" ) + + /* cache errors */ + + FT_ERRORDEF_( Too_Many_Caches, 0x70, \ + "too many registered caches" ) + + /* TrueType and SFNT errors */ + + FT_ERRORDEF_( Invalid_Opcode, 0x80, \ + "invalid opcode" ) + FT_ERRORDEF_( Too_Few_Arguments, 0x81, \ + "too few arguments" ) + FT_ERRORDEF_( Stack_Overflow, 0x82, \ + "stack overflow" ) + FT_ERRORDEF_( Code_Overflow, 0x83, \ + "code overflow" ) + FT_ERRORDEF_( Bad_Argument, 0x84, \ + "bad argument" ) + FT_ERRORDEF_( Divide_By_Zero, 0x85, \ + "division by zero" ) + FT_ERRORDEF_( Invalid_Reference, 0x86, \ + "invalid reference" ) + FT_ERRORDEF_( Debug_OpCode, 0x87, \ + "found debug opcode" ) + FT_ERRORDEF_( ENDF_In_Exec_Stream, 0x88, \ + "found ENDF opcode in execution stream" ) + FT_ERRORDEF_( Nested_DEFS, 0x89, \ + "nested DEFS" ) + FT_ERRORDEF_( Invalid_CodeRange, 0x8A, \ + "invalid code range" ) + FT_ERRORDEF_( Execution_Too_Long, 0x8B, \ + "execution context too long" ) + FT_ERRORDEF_( Too_Many_Function_Defs, 0x8C, \ + "too many function definitions" ) + FT_ERRORDEF_( Too_Many_Instruction_Defs, 0x8D, \ + "too many instruction definitions" ) + FT_ERRORDEF_( Table_Missing, 0x8E, \ + "SFNT font table missing" ) + FT_ERRORDEF_( Horiz_Header_Missing, 0x8F, \ + "horizontal header (hhea) table missing" ) + FT_ERRORDEF_( Locations_Missing, 0x90, \ + "locations (loca) table missing" ) + FT_ERRORDEF_( Name_Table_Missing, 0x91, \ + "name table missing" ) + FT_ERRORDEF_( CMap_Table_Missing, 0x92, \ + "character map (cmap) table missing" ) + FT_ERRORDEF_( Hmtx_Table_Missing, 0x93, \ + "horizontal metrics (hmtx) table missing" ) + FT_ERRORDEF_( Post_Table_Missing, 0x94, \ + "PostScript (post) table missing" ) + FT_ERRORDEF_( Invalid_Horiz_Metrics, 0x95, \ + "invalid horizontal metrics" ) + FT_ERRORDEF_( Invalid_CharMap_Format, 0x96, \ + "invalid character map (cmap) format" ) + FT_ERRORDEF_( Invalid_PPem, 0x97, \ + "invalid ppem value" ) + FT_ERRORDEF_( Invalid_Vert_Metrics, 0x98, \ + "invalid vertical metrics" ) + FT_ERRORDEF_( Could_Not_Find_Context, 0x99, \ + "could not find context" ) + FT_ERRORDEF_( Invalid_Post_Table_Format, 0x9A, \ + "invalid PostScript (post) table format" ) + FT_ERRORDEF_( Invalid_Post_Table, 0x9B, \ + "invalid PostScript (post) table" ) + + /* CFF, CID, and Type 1 errors */ + + FT_ERRORDEF_( Syntax_Error, 0xA0, \ + "opcode syntax error" ) + FT_ERRORDEF_( Stack_Underflow, 0xA1, \ + "argument stack underflow" ) + FT_ERRORDEF_( Ignore, 0xA2, \ + "ignore" ) + + /* BDF errors */ + + FT_ERRORDEF_( Missing_Startfont_Field, 0xB0, \ + "`STARTFONT' field missing" ) + FT_ERRORDEF_( Missing_Font_Field, 0xB1, \ + "`FONT' field missing" ) + FT_ERRORDEF_( Missing_Size_Field, 0xB2, \ + "`SIZE' field missing" ) + FT_ERRORDEF_( Missing_Chars_Field, 0xB3, \ + "`CHARS' field missing" ) + FT_ERRORDEF_( Missing_Startchar_Field, 0xB4, \ + "`STARTCHAR' field missing" ) + FT_ERRORDEF_( Missing_Encoding_Field, 0xB5, \ + "`ENCODING' field missing" ) + FT_ERRORDEF_( Missing_Bbx_Field, 0xB6, \ + "`BBX' field missing" ) + FT_ERRORDEF_( Bbx_Too_Big, 0xB7, \ + "`BBX' too big" ) + FT_ERRORDEF_( Corrupted_Font_Header, 0xB8, \ + "Font header corrupted or missing fields" ) + FT_ERRORDEF_( Corrupted_Font_Glyphs, 0xB9, \ + "Font glyphs corrupted or missing fields" ) + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/fterrors.h b/mod/pub.mod/freetype.mod/include/freetype/fterrors.h new file mode 100644 index 0000000..6600dad --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/fterrors.h @@ -0,0 +1,206 @@ +/***************************************************************************/ +/* */ +/* fterrors.h */ +/* */ +/* FreeType error code handling (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2004, 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This special header file is used to define the handling of FT2 */ + /* enumeration constants. It can also be used to generate error message */ + /* strings with a small macro trick explained below. */ + /* */ + /* I - Error Formats */ + /* ----------------- */ + /* */ + /* The configuration macro FT_CONFIG_OPTION_USE_MODULE_ERRORS can be */ + /* defined in ftoption.h in order to make the higher byte indicate */ + /* the module where the error has happened (this is not compatible */ + /* with standard builds of FreeType 2). You can then use the macro */ + /* FT_ERROR_BASE macro to extract the generic error code from an */ + /* FT_Error value. */ + /* */ + /* */ + /* II - Error Message strings */ + /* -------------------------- */ + /* */ + /* The error definitions below are made through special macros that */ + /* allow client applications to build a table of error message strings */ + /* if they need it. The strings are not included in a normal build of */ + /* FreeType 2 to save space (most client applications do not use */ + /* them). */ + /* */ + /* To do so, you have to define the following macros before including */ + /* this file: */ + /* */ + /* FT_ERROR_START_LIST :: */ + /* This macro is called before anything else to define the start of */ + /* the error list. It is followed by several FT_ERROR_DEF calls */ + /* (see below). */ + /* */ + /* FT_ERROR_DEF( e, v, s ) :: */ + /* This macro is called to define one single error. */ + /* `e' is the error code identifier (e.g. FT_Err_Invalid_Argument). */ + /* `v' is the error numerical value. */ + /* `s' is the corresponding error string. */ + /* */ + /* FT_ERROR_END_LIST :: */ + /* This macro ends the list. */ + /* */ + /* Additionally, you have to undefine __FTERRORS_H__ before #including */ + /* this file. */ + /* */ + /* Here is a simple example: */ + /* */ + /* { */ + /* #undef __FTERRORS_H__ */ + /* #define FT_ERRORDEF( e, v, s ) { e, s }, */ + /* #define FT_ERROR_START_LIST { */ + /* #define FT_ERROR_END_LIST { 0, 0 } }; */ + /* */ + /* const struct */ + /* { */ + /* int err_code; */ + /* const char* err_msg; */ + /* } ft_errors[] = */ + /* */ + /* #include FT_ERRORS_H */ + /* } */ + /* */ + /*************************************************************************/ + + +#ifndef __FTERRORS_H__ +#define __FTERRORS_H__ + + + /* include module base error codes */ +#include FT_MODULE_ERRORS_H + + + /*******************************************************************/ + /*******************************************************************/ + /***** *****/ + /***** SETUP MACROS *****/ + /***** *****/ + /*******************************************************************/ + /*******************************************************************/ + + +#undef FT_NEED_EXTERN_C + +#undef FT_ERR_XCAT +#undef FT_ERR_CAT + +#define FT_ERR_XCAT( x, y ) x ## y +#define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y ) + + + /* FT_ERR_PREFIX is used as a prefix for error identifiers. */ + /* By default, we use `FT_Err_'. */ + /* */ +#ifndef FT_ERR_PREFIX +#define FT_ERR_PREFIX FT_Err_ +#endif + + + /* FT_ERR_BASE is used as the base for module-specific errors. */ + /* */ +#ifdef FT_CONFIG_OPTION_USE_MODULE_ERRORS + +#ifndef FT_ERR_BASE +#define FT_ERR_BASE FT_Mod_Err_Base +#endif + +#else + +#undef FT_ERR_BASE +#define FT_ERR_BASE 0 + +#endif /* FT_CONFIG_OPTION_USE_MODULE_ERRORS */ + + + /* If FT_ERRORDEF is not defined, we need to define a simple */ + /* enumeration type. */ + /* */ +#ifndef FT_ERRORDEF + +#define FT_ERRORDEF( e, v, s ) e = v, +#define FT_ERROR_START_LIST enum { +#define FT_ERROR_END_LIST FT_ERR_CAT( FT_ERR_PREFIX, Max ) }; + +#ifdef __cplusplus +#define FT_NEED_EXTERN_C + extern "C" { +#endif + +#endif /* !FT_ERRORDEF */ + + + /* this macro is used to define an error */ +#define FT_ERRORDEF_( e, v, s ) \ + FT_ERRORDEF( FT_ERR_CAT( FT_ERR_PREFIX, e ), v + FT_ERR_BASE, s ) + + /* this is only used for <module>_Err_Ok, which must be 0! */ +#define FT_NOERRORDEF_( e, v, s ) \ + FT_ERRORDEF( FT_ERR_CAT( FT_ERR_PREFIX, e ), v, s ) + + +#ifdef FT_ERROR_START_LIST + FT_ERROR_START_LIST +#endif + + + /* now include the error codes */ +#include FT_ERROR_DEFINITIONS_H + + +#ifdef FT_ERROR_END_LIST + FT_ERROR_END_LIST +#endif + + + /*******************************************************************/ + /*******************************************************************/ + /***** *****/ + /***** SIMPLE CLEANUP *****/ + /***** *****/ + /*******************************************************************/ + /*******************************************************************/ + +#ifdef FT_NEED_EXTERN_C + } +#endif + +#undef FT_ERROR_START_LIST +#undef FT_ERROR_END_LIST + +#undef FT_ERRORDEF +#undef FT_ERRORDEF_ +#undef FT_NOERRORDEF_ + +#undef FT_NEED_EXTERN_C +#undef FT_ERR_CONCAT +#undef FT_ERR_BASE + + /* FT_KEEP_ERR_PREFIX is needed for ftvalid.h */ +#ifndef FT_KEEP_ERR_PREFIX +#undef FT_ERR_PREFIX +#endif + +#endif /* __FTERRORS_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/ftgasp.h b/mod/pub.mod/freetype.mod/include/freetype/ftgasp.h new file mode 100644 index 0000000..91a769e --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/ftgasp.h @@ -0,0 +1,120 @@ +/***************************************************************************/ +/* */ +/* ftgasp.h */ +/* */ +/* Access of TrueType's `gasp' table (specification). */ +/* */ +/* Copyright 2007, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef _FT_GASP_H_ +#define _FT_GASP_H_ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + + /*************************************************************************** + * + * @section: + * gasp_table + * + * @title: + * Gasp Table + * + * @abstract: + * Retrieving TrueType `gasp' table entries. + * + * @description: + * The function @FT_Get_Gasp can be used to query a TrueType or OpenType + * font for specific entries in its `gasp' table, if any. This is + * mainly useful when implementing native TrueType hinting with the + * bytecode interpreter to duplicate the Windows text rendering results. + */ + + /************************************************************************* + * + * @enum: + * FT_GASP_XXX + * + * @description: + * A list of values and/or bit-flags returned by the @FT_Get_Gasp + * function. + * + * @values: + * FT_GASP_NO_TABLE :: + * This special value means that there is no GASP table in this face. + * It is up to the client to decide what to do. + * + * FT_GASP_DO_GRIDFIT :: + * Grid-fitting and hinting should be performed at the specified ppem. + * This *really* means TrueType bytecode interpretation. + * + * FT_GASP_DO_GRAY :: + * Anti-aliased rendering should be performed at the specified ppem. + * + * FT_GASP_SYMMETRIC_SMOOTHING :: + * Smoothing along multiple axes must be used with ClearType. + * + * FT_GASP_SYMMETRIC_GRIDFIT :: + * Grid-fitting must be used with ClearType's symmetric smoothing. + * + * @note: + * `ClearType' is Microsoft's implementation of LCD rendering, partly + * protected by patents. + * + * @since: + * 2.3.0 + */ +#define FT_GASP_NO_TABLE -1 +#define FT_GASP_DO_GRIDFIT 0x01 +#define FT_GASP_DO_GRAY 0x02 +#define FT_GASP_SYMMETRIC_SMOOTHING 0x08 +#define FT_GASP_SYMMETRIC_GRIDFIT 0x10 + + + /************************************************************************* + * + * @func: + * FT_Get_Gasp + * + * @description: + * Read the `gasp' table from a TrueType or OpenType font file and + * return the entry corresponding to a given character pixel size. + * + * @input: + * face :: The source face handle. + * ppem :: The vertical character pixel size. + * + * @return: + * Bit flags (see @FT_GASP_XXX), or @FT_GASP_NO_TABLE if there is no + * `gasp' table in the face. + * + * @since: + * 2.3.0 + */ + FT_EXPORT( FT_Int ) + FT_Get_Gasp( FT_Face face, + FT_UInt ppem ); + +/* */ + +#endif /* _FT_GASP_H_ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/ftglyph.h b/mod/pub.mod/freetype.mod/include/freetype/ftglyph.h new file mode 100644 index 0000000..cacccf0 --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/ftglyph.h @@ -0,0 +1,613 @@ +/***************************************************************************/ +/* */ +/* ftglyph.h */ +/* */ +/* FreeType convenience functions to handle glyphs (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2006, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file contains the definition of several convenience functions */ + /* that can be used by client applications to easily retrieve glyph */ + /* bitmaps and outlines from a given face. */ + /* */ + /* These functions should be optional if you are writing a font server */ + /* or text layout engine on top of FreeType. However, they are pretty */ + /* handy for many other simple uses of the library. */ + /* */ + /*************************************************************************/ + + +#ifndef __FTGLYPH_H__ +#define __FTGLYPH_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* glyph_management */ + /* */ + /* <Title> */ + /* Glyph Management */ + /* */ + /* <Abstract> */ + /* Generic interface to manage individual glyph data. */ + /* */ + /* <Description> */ + /* This section contains definitions used to manage glyph data */ + /* through generic FT_Glyph objects. Each of them can contain a */ + /* bitmap, a vector outline, or even images in other formats. */ + /* */ + /*************************************************************************/ + + + /* forward declaration to a private type */ + typedef struct FT_Glyph_Class_ FT_Glyph_Class; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Glyph */ + /* */ + /* <Description> */ + /* Handle to an object used to model generic glyph images. It is a */ + /* pointer to the @FT_GlyphRec structure and can contain a glyph */ + /* bitmap or pointer. */ + /* */ + /* <Note> */ + /* Glyph objects are not owned by the library. You must thus release */ + /* them manually (through @FT_Done_Glyph) _before_ calling */ + /* @FT_Done_FreeType. */ + /* */ + typedef struct FT_GlyphRec_* FT_Glyph; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_GlyphRec */ + /* */ + /* <Description> */ + /* The root glyph structure contains a given glyph image plus its */ + /* advance width in 16.16 fixed float format. */ + /* */ + /* <Fields> */ + /* library :: A handle to the FreeType library object. */ + /* */ + /* clazz :: A pointer to the glyph's class. Private. */ + /* */ + /* format :: The format of the glyph's image. */ + /* */ + /* advance :: A 16.16 vector that gives the glyph's advance width. */ + /* */ + typedef struct FT_GlyphRec_ + { + FT_Library library; + const FT_Glyph_Class* clazz; + FT_Glyph_Format format; + FT_Vector advance; + + } FT_GlyphRec; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_BitmapGlyph */ + /* */ + /* <Description> */ + /* A handle to an object used to model a bitmap glyph image. This is */ + /* a sub-class of @FT_Glyph, and a pointer to @FT_BitmapGlyphRec. */ + /* */ + typedef struct FT_BitmapGlyphRec_* FT_BitmapGlyph; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_BitmapGlyphRec */ + /* */ + /* <Description> */ + /* A structure used for bitmap glyph images. This really is a */ + /* `sub-class' of @FT_GlyphRec. */ + /* */ + /* <Fields> */ + /* root :: The root @FT_Glyph fields. */ + /* */ + /* left :: The left-side bearing, i.e., the horizontal distance */ + /* from the current pen position to the left border of the */ + /* glyph bitmap. */ + /* */ + /* top :: The top-side bearing, i.e., the vertical distance from */ + /* the current pen position to the top border of the glyph */ + /* bitmap. This distance is positive for upwards~y! */ + /* */ + /* bitmap :: A descriptor for the bitmap. */ + /* */ + /* <Note> */ + /* You can typecast an @FT_Glyph to @FT_BitmapGlyph if you have */ + /* `glyph->format == FT_GLYPH_FORMAT_BITMAP'. This lets you access */ + /* the bitmap's contents easily. */ + /* */ + /* The corresponding pixel buffer is always owned by @FT_BitmapGlyph */ + /* and is thus created and destroyed with it. */ + /* */ + typedef struct FT_BitmapGlyphRec_ + { + FT_GlyphRec root; + FT_Int left; + FT_Int top; + FT_Bitmap bitmap; + + } FT_BitmapGlyphRec; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_OutlineGlyph */ + /* */ + /* <Description> */ + /* A handle to an object used to model an outline glyph image. This */ + /* is a sub-class of @FT_Glyph, and a pointer to @FT_OutlineGlyphRec. */ + /* */ + typedef struct FT_OutlineGlyphRec_* FT_OutlineGlyph; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_OutlineGlyphRec */ + /* */ + /* <Description> */ + /* A structure used for outline (vectorial) glyph images. This */ + /* really is a `sub-class' of @FT_GlyphRec. */ + /* */ + /* <Fields> */ + /* root :: The root @FT_Glyph fields. */ + /* */ + /* outline :: A descriptor for the outline. */ + /* */ + /* <Note> */ + /* You can typecast an @FT_Glyph to @FT_OutlineGlyph if you have */ + /* `glyph->format == FT_GLYPH_FORMAT_OUTLINE'. This lets you access */ + /* the outline's content easily. */ + /* */ + /* As the outline is extracted from a glyph slot, its coordinates are */ + /* expressed normally in 26.6 pixels, unless the flag */ + /* @FT_LOAD_NO_SCALE was used in @FT_Load_Glyph() or @FT_Load_Char(). */ + /* */ + /* The outline's tables are always owned by the object and are */ + /* destroyed with it. */ + /* */ + typedef struct FT_OutlineGlyphRec_ + { + FT_GlyphRec root; + FT_Outline outline; + + } FT_OutlineGlyphRec; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Glyph */ + /* */ + /* <Description> */ + /* A function used to extract a glyph image from a slot. Note that */ + /* the created @FT_Glyph object must be released with @FT_Done_Glyph. */ + /* */ + /* <Input> */ + /* slot :: A handle to the source glyph slot. */ + /* */ + /* <Output> */ + /* aglyph :: A handle to the glyph object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Glyph( FT_GlyphSlot slot, + FT_Glyph *aglyph ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Glyph_Copy */ + /* */ + /* <Description> */ + /* A function used to copy a glyph image. Note that the created */ + /* @FT_Glyph object must be released with @FT_Done_Glyph. */ + /* */ + /* <Input> */ + /* source :: A handle to the source glyph object. */ + /* */ + /* <Output> */ + /* target :: A handle to the target glyph object. 0~in case of */ + /* error. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Glyph_Copy( FT_Glyph source, + FT_Glyph *target ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Glyph_Transform */ + /* */ + /* <Description> */ + /* Transform a glyph image if its format is scalable. */ + /* */ + /* <InOut> */ + /* glyph :: A handle to the target glyph object. */ + /* */ + /* <Input> */ + /* matrix :: A pointer to a 2x2 matrix to apply. */ + /* */ + /* delta :: A pointer to a 2d vector to apply. Coordinates are */ + /* expressed in 1/64th of a pixel. */ + /* */ + /* <Return> */ + /* FreeType error code (if not 0, the glyph format is not scalable). */ + /* */ + /* <Note> */ + /* The 2x2 transformation matrix is also applied to the glyph's */ + /* advance vector. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Glyph_Transform( FT_Glyph glyph, + FT_Matrix* matrix, + FT_Vector* delta ); + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Glyph_BBox_Mode */ + /* */ + /* <Description> */ + /* The mode how the values of @FT_Glyph_Get_CBox are returned. */ + /* */ + /* <Values> */ + /* FT_GLYPH_BBOX_UNSCALED :: */ + /* Return unscaled font units. */ + /* */ + /* FT_GLYPH_BBOX_SUBPIXELS :: */ + /* Return unfitted 26.6 coordinates. */ + /* */ + /* FT_GLYPH_BBOX_GRIDFIT :: */ + /* Return grid-fitted 26.6 coordinates. */ + /* */ + /* FT_GLYPH_BBOX_TRUNCATE :: */ + /* Return coordinates in integer pixels. */ + /* */ + /* FT_GLYPH_BBOX_PIXELS :: */ + /* Return grid-fitted pixel coordinates. */ + /* */ + typedef enum FT_Glyph_BBox_Mode_ + { + FT_GLYPH_BBOX_UNSCALED = 0, + FT_GLYPH_BBOX_SUBPIXELS = 0, + FT_GLYPH_BBOX_GRIDFIT = 1, + FT_GLYPH_BBOX_TRUNCATE = 2, + FT_GLYPH_BBOX_PIXELS = 3 + + } FT_Glyph_BBox_Mode; + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* ft_glyph_bbox_xxx */ + /* */ + /* <Description> */ + /* These constants are deprecated. Use the corresponding */ + /* @FT_Glyph_BBox_Mode values instead. */ + /* */ + /* <Values> */ + /* ft_glyph_bbox_unscaled :: See @FT_GLYPH_BBOX_UNSCALED. */ + /* ft_glyph_bbox_subpixels :: See @FT_GLYPH_BBOX_SUBPIXELS. */ + /* ft_glyph_bbox_gridfit :: See @FT_GLYPH_BBOX_GRIDFIT. */ + /* ft_glyph_bbox_truncate :: See @FT_GLYPH_BBOX_TRUNCATE. */ + /* ft_glyph_bbox_pixels :: See @FT_GLYPH_BBOX_PIXELS. */ + /* */ +#define ft_glyph_bbox_unscaled FT_GLYPH_BBOX_UNSCALED +#define ft_glyph_bbox_subpixels FT_GLYPH_BBOX_SUBPIXELS +#define ft_glyph_bbox_gridfit FT_GLYPH_BBOX_GRIDFIT +#define ft_glyph_bbox_truncate FT_GLYPH_BBOX_TRUNCATE +#define ft_glyph_bbox_pixels FT_GLYPH_BBOX_PIXELS + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Glyph_Get_CBox */ + /* */ + /* <Description> */ + /* Return a glyph's `control box'. The control box encloses all the */ + /* outline's points, including Bézier control points. Though it */ + /* coincides with the exact bounding box for most glyphs, it can be */ + /* slightly larger in some situations (like when rotating an outline */ + /* which contains Bézier outside arcs). */ + /* */ + /* Computing the control box is very fast, while getting the bounding */ + /* box can take much more time as it needs to walk over all segments */ + /* and arcs in the outline. To get the latter, you can use the */ + /* `ftbbox' component which is dedicated to this single task. */ + /* */ + /* <Input> */ + /* glyph :: A handle to the source glyph object. */ + /* */ + /* mode :: The mode which indicates how to interpret the returned */ + /* bounding box values. */ + /* */ + /* <Output> */ + /* acbox :: The glyph coordinate bounding box. Coordinates are */ + /* expressed in 1/64th of pixels if it is grid-fitted. */ + /* */ + /* <Note> */ + /* Coordinates are relative to the glyph origin, using the y~upwards */ + /* convention. */ + /* */ + /* If the glyph has been loaded with @FT_LOAD_NO_SCALE, `bbox_mode' */ + /* must be set to @FT_GLYPH_BBOX_UNSCALED to get unscaled font */ + /* units in 26.6 pixel format. The value @FT_GLYPH_BBOX_SUBPIXELS */ + /* is another name for this constant. */ + /* */ + /* Note that the maximum coordinates are exclusive, which means that */ + /* one can compute the width and height of the glyph image (be it in */ + /* integer or 26.6 pixels) as: */ + /* */ + /* { */ + /* width = bbox.xMax - bbox.xMin; */ + /* height = bbox.yMax - bbox.yMin; */ + /* } */ + /* */ + /* Note also that for 26.6 coordinates, if `bbox_mode' is set to */ + /* @FT_GLYPH_BBOX_GRIDFIT, the coordinates will also be grid-fitted, */ + /* which corresponds to: */ + /* */ + /* { */ + /* bbox.xMin = FLOOR(bbox.xMin); */ + /* bbox.yMin = FLOOR(bbox.yMin); */ + /* bbox.xMax = CEILING(bbox.xMax); */ + /* bbox.yMax = CEILING(bbox.yMax); */ + /* } */ + /* */ + /* To get the bbox in pixel coordinates, set `bbox_mode' to */ + /* @FT_GLYPH_BBOX_TRUNCATE. */ + /* */ + /* To get the bbox in grid-fitted pixel coordinates, set `bbox_mode' */ + /* to @FT_GLYPH_BBOX_PIXELS. */ + /* */ + FT_EXPORT( void ) + FT_Glyph_Get_CBox( FT_Glyph glyph, + FT_UInt bbox_mode, + FT_BBox *acbox ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Glyph_To_Bitmap */ + /* */ + /* <Description> */ + /* Convert a given glyph object to a bitmap glyph object. */ + /* */ + /* <InOut> */ + /* the_glyph :: A pointer to a handle to the target glyph. */ + /* */ + /* <Input> */ + /* render_mode :: An enumeration that describes how the data is */ + /* rendered. */ + /* */ + /* origin :: A pointer to a vector used to translate the glyph */ + /* image before rendering. Can be~0 (if no */ + /* translation). The origin is expressed in */ + /* 26.6 pixels. */ + /* */ + /* destroy :: A boolean that indicates that the original glyph */ + /* image should be destroyed by this function. It is */ + /* never destroyed in case of error. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* This function does nothing if the glyph format isn't scalable. */ + /* */ + /* The glyph image is translated with the `origin' vector before */ + /* rendering. */ + /* */ + /* The first parameter is a pointer to an @FT_Glyph handle, that will */ + /* be _replaced_ by this function (with newly allocated data). */ + /* Typically, you would use (omitting error handling): */ + /* */ + /* */ + /* { */ + /* FT_Glyph glyph; */ + /* FT_BitmapGlyph glyph_bitmap; */ + /* */ + /* */ + /* // load glyph */ + /* error = FT_Load_Char( face, glyph_index, FT_LOAD_DEFAUT ); */ + /* */ + /* // extract glyph image */ + /* error = FT_Get_Glyph( face->glyph, &glyph ); */ + /* */ + /* // convert to a bitmap (default render mode + destroying old) */ + /* if ( glyph->format != FT_GLYPH_FORMAT_BITMAP ) */ + /* { */ + /* error = FT_Glyph_To_Bitmap( &glyph, FT_RENDER_MODE_DEFAULT, */ + /* 0, 1 ); */ + /* if ( error ) // `glyph' unchanged */ + /* ... */ + /* } */ + /* */ + /* // access bitmap content by typecasting */ + /* glyph_bitmap = (FT_BitmapGlyph)glyph; */ + /* */ + /* // do funny stuff with it, like blitting/drawing */ + /* ... */ + /* */ + /* // discard glyph image (bitmap or not) */ + /* FT_Done_Glyph( glyph ); */ + /* } */ + /* */ + /* */ + /* Here another example, again without error handling: */ + /* */ + /* */ + /* { */ + /* FT_Glyph glyphs[MAX_GLYPHS] */ + /* */ + /* */ + /* ... */ + /* */ + /* for ( idx = 0; i < MAX_GLYPHS; i++ ) */ + /* error = FT_Load_Glyph( face, idx, FT_LOAD_DEFAULT ) || */ + /* FT_Get_Glyph ( face->glyph, &glyph[idx] ); */ + /* */ + /* ... */ + /* */ + /* for ( idx = 0; i < MAX_GLYPHS; i++ ) */ + /* { */ + /* FT_Glyph bitmap = glyphs[idx]; */ + /* */ + /* */ + /* ... */ + /* */ + /* // after this call, `bitmap' no longer points into */ + /* // the `glyphs' array (and the old value isn't destroyed) */ + /* FT_Glyph_To_Bitmap( &bitmap, FT_RENDER_MODE_MONO, 0, 0 ); */ + /* */ + /* ... */ + /* */ + /* FT_Done_Glyph( bitmap ); */ + /* } */ + /* */ + /* ... */ + /* */ + /* for ( idx = 0; i < MAX_GLYPHS; i++ ) */ + /* FT_Done_Glyph( glyphs[idx] ); */ + /* } */ + /* */ + FT_EXPORT( FT_Error ) + FT_Glyph_To_Bitmap( FT_Glyph* the_glyph, + FT_Render_Mode render_mode, + FT_Vector* origin, + FT_Bool destroy ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Done_Glyph */ + /* */ + /* <Description> */ + /* Destroy a given glyph. */ + /* */ + /* <Input> */ + /* glyph :: A handle to the target glyph object. */ + /* */ + FT_EXPORT( void ) + FT_Done_Glyph( FT_Glyph glyph ); + + /* */ + + + /* other helpful functions */ + + /*************************************************************************/ + /* */ + /* <Section> */ + /* computations */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Matrix_Multiply */ + /* */ + /* <Description> */ + /* Perform the matrix operation `b = a*b'. */ + /* */ + /* <Input> */ + /* a :: A pointer to matrix `a'. */ + /* */ + /* <InOut> */ + /* b :: A pointer to matrix `b'. */ + /* */ + /* <Note> */ + /* The result is undefined if either `a' or `b' is zero. */ + /* */ + FT_EXPORT( void ) + FT_Matrix_Multiply( const FT_Matrix* a, + FT_Matrix* b ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Matrix_Invert */ + /* */ + /* <Description> */ + /* Invert a 2x2 matrix. Return an error if it can't be inverted. */ + /* */ + /* <InOut> */ + /* matrix :: A pointer to the target matrix. Remains untouched in */ + /* case of error. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Matrix_Invert( FT_Matrix* matrix ); + + + /* */ + + +FT_END_HEADER + +#endif /* __FTGLYPH_H__ */ + + +/* END */ + + +/* Local Variables: */ +/* coding: utf-8 */ +/* End: */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/ftgxval.h b/mod/pub.mod/freetype.mod/include/freetype/ftgxval.h new file mode 100644 index 0000000..497015c --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/ftgxval.h @@ -0,0 +1,358 @@ +/***************************************************************************/ +/* */ +/* ftgxval.h */ +/* */ +/* FreeType API for validating TrueTypeGX/AAT tables (specification). */ +/* */ +/* Copyright 2004, 2005, 2006 by */ +/* Masatake YAMATO, Redhat K.K, */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + +/***************************************************************************/ +/* */ +/* gxvalid is derived from both gxlayout module and otvalid module. */ +/* Development of gxlayout is supported by the Information-technology */ +/* Promotion Agency(IPA), Japan. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTGXVAL_H__ +#define __FTGXVAL_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* gx_validation */ + /* */ + /* <Title> */ + /* TrueTypeGX/AAT Validation */ + /* */ + /* <Abstract> */ + /* An API to validate TrueTypeGX/AAT tables. */ + /* */ + /* <Description> */ + /* This section contains the declaration of functions to validate */ + /* some TrueTypeGX tables (feat, mort, morx, bsln, just, kern, opbd, */ + /* trak, prop, lcar). */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* */ + /* Warning: Use FT_VALIDATE_XXX to validate a table. */ + /* Following definitions are for gxvalid developers. */ + /* */ + /* */ + /*************************************************************************/ + +#define FT_VALIDATE_feat_INDEX 0 +#define FT_VALIDATE_mort_INDEX 1 +#define FT_VALIDATE_morx_INDEX 2 +#define FT_VALIDATE_bsln_INDEX 3 +#define FT_VALIDATE_just_INDEX 4 +#define FT_VALIDATE_kern_INDEX 5 +#define FT_VALIDATE_opbd_INDEX 6 +#define FT_VALIDATE_trak_INDEX 7 +#define FT_VALIDATE_prop_INDEX 8 +#define FT_VALIDATE_lcar_INDEX 9 +#define FT_VALIDATE_GX_LAST_INDEX FT_VALIDATE_lcar_INDEX + + + /************************************************************************* + * + * @macro: + * FT_VALIDATE_GX_LENGTH + * + * @description: + * The number of tables checked in this module. Use it as a parameter + * for the `table-length' argument of function @FT_TrueTypeGX_Validate. + */ +#define FT_VALIDATE_GX_LENGTH (FT_VALIDATE_GX_LAST_INDEX + 1) + + /* */ + + /* Up to 0x1000 is used by otvalid. + Ox2xxx is reserved for feature OT extension. */ +#define FT_VALIDATE_GX_START 0x4000 +#define FT_VALIDATE_GX_BITFIELD( tag ) \ + ( FT_VALIDATE_GX_START << FT_VALIDATE_##tag##_INDEX ) + + + /********************************************************************** + * + * @enum: + * FT_VALIDATE_GXXXX + * + * @description: + * A list of bit-field constants used with @FT_TrueTypeGX_Validate to + * indicate which TrueTypeGX/AAT Type tables should be validated. + * + * @values: + * FT_VALIDATE_feat :: + * Validate `feat' table. + * + * FT_VALIDATE_mort :: + * Validate `mort' table. + * + * FT_VALIDATE_morx :: + * Validate `morx' table. + * + * FT_VALIDATE_bsln :: + * Validate `bsln' table. + * + * FT_VALIDATE_just :: + * Validate `just' table. + * + * FT_VALIDATE_kern :: + * Validate `kern' table. + * + * FT_VALIDATE_opbd :: + * Validate `opbd' table. + * + * FT_VALIDATE_trak :: + * Validate `trak' table. + * + * FT_VALIDATE_prop :: + * Validate `prop' table. + * + * FT_VALIDATE_lcar :: + * Validate `lcar' table. + * + * FT_VALIDATE_GX :: + * Validate all TrueTypeGX tables (feat, mort, morx, bsln, just, kern, + * opbd, trak, prop and lcar). + * + */ + +#define FT_VALIDATE_feat FT_VALIDATE_GX_BITFIELD( feat ) +#define FT_VALIDATE_mort FT_VALIDATE_GX_BITFIELD( mort ) +#define FT_VALIDATE_morx FT_VALIDATE_GX_BITFIELD( morx ) +#define FT_VALIDATE_bsln FT_VALIDATE_GX_BITFIELD( bsln ) +#define FT_VALIDATE_just FT_VALIDATE_GX_BITFIELD( just ) +#define FT_VALIDATE_kern FT_VALIDATE_GX_BITFIELD( kern ) +#define FT_VALIDATE_opbd FT_VALIDATE_GX_BITFIELD( opbd ) +#define FT_VALIDATE_trak FT_VALIDATE_GX_BITFIELD( trak ) +#define FT_VALIDATE_prop FT_VALIDATE_GX_BITFIELD( prop ) +#define FT_VALIDATE_lcar FT_VALIDATE_GX_BITFIELD( lcar ) + +#define FT_VALIDATE_GX ( FT_VALIDATE_feat | \ + FT_VALIDATE_mort | \ + FT_VALIDATE_morx | \ + FT_VALIDATE_bsln | \ + FT_VALIDATE_just | \ + FT_VALIDATE_kern | \ + FT_VALIDATE_opbd | \ + FT_VALIDATE_trak | \ + FT_VALIDATE_prop | \ + FT_VALIDATE_lcar ) + + + /* */ + + /********************************************************************** + * + * @function: + * FT_TrueTypeGX_Validate + * + * @description: + * Validate various TrueTypeGX tables to assure that all offsets and + * indices are valid. The idea is that a higher-level library which + * actually does the text layout can access those tables without + * error checking (which can be quite time consuming). + * + * @input: + * face :: + * A handle to the input face. + * + * validation_flags :: + * A bit field which specifies the tables to be validated. See + * @FT_VALIDATE_GXXXX for possible values. + * + * table_length :: + * The size of the `tables' array. Normally, @FT_VALIDATE_GX_LENGTH + * should be passed. + * + * @output: + * tables :: + * The array where all validated sfnt tables are stored. + * The array itself must be allocated by a client. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function only works with TrueTypeGX fonts, returning an error + * otherwise. + * + * After use, the application should deallocate the buffers pointed to by + * each `tables' element, by calling @FT_TrueTypeGX_Free. A NULL value + * indicates that the table either doesn't exist in the font, the + * application hasn't asked for validation, or the validator doesn't have + * the ability to validate the sfnt table. + */ + FT_EXPORT( FT_Error ) + FT_TrueTypeGX_Validate( FT_Face face, + FT_UInt validation_flags, + FT_Bytes tables[FT_VALIDATE_GX_LENGTH], + FT_UInt table_length ); + + + /* */ + + /********************************************************************** + * + * @function: + * FT_TrueTypeGX_Free + * + * @description: + * Free the buffer allocated by TrueTypeGX validator. + * + * @input: + * face :: + * A handle to the input face. + * + * table :: + * The pointer to the buffer allocated by + * @FT_TrueTypeGX_Validate. + * + * @note: + * This function must be used to free the buffer allocated by + * @FT_TrueTypeGX_Validate only. + */ + FT_EXPORT( void ) + FT_TrueTypeGX_Free( FT_Face face, + FT_Bytes table ); + + + /* */ + + /********************************************************************** + * + * @enum: + * FT_VALIDATE_CKERNXXX + * + * @description: + * A list of bit-field constants used with @FT_ClassicKern_Validate + * to indicate the classic kern dialect or dialects. If the selected + * type doesn't fit, @FT_ClassicKern_Validate regards the table as + * invalid. + * + * @values: + * FT_VALIDATE_MS :: + * Handle the `kern' table as a classic Microsoft kern table. + * + * FT_VALIDATE_APPLE :: + * Handle the `kern' table as a classic Apple kern table. + * + * FT_VALIDATE_CKERN :: + * Handle the `kern' as either classic Apple or Microsoft kern table. + */ +#define FT_VALIDATE_MS ( FT_VALIDATE_GX_START << 0 ) +#define FT_VALIDATE_APPLE ( FT_VALIDATE_GX_START << 1 ) + +#define FT_VALIDATE_CKERN ( FT_VALIDATE_MS | FT_VALIDATE_APPLE ) + + + /* */ + + /********************************************************************** + * + * @function: + * FT_ClassicKern_Validate + * + * @description: + * Validate classic (16-bit format) kern table to assure that the offsets + * and indices are valid. The idea is that a higher-level library which + * actually does the text layout can access those tables without error + * checking (which can be quite time consuming). + * + * The `kern' table validator in @FT_TrueTypeGX_Validate deals with both + * the new 32-bit format and the classic 16-bit format, while + * FT_ClassicKern_Validate only supports the classic 16-bit format. + * + * @input: + * face :: + * A handle to the input face. + * + * validation_flags :: + * A bit field which specifies the dialect to be validated. See + * @FT_VALIDATE_CKERNXXX for possible values. + * + * @output: + * ckern_table :: + * A pointer to the kern table. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * After use, the application should deallocate the buffers pointed to by + * `ckern_table', by calling @FT_ClassicKern_Free. A NULL value + * indicates that the table doesn't exist in the font. + */ + FT_EXPORT( FT_Error ) + FT_ClassicKern_Validate( FT_Face face, + FT_UInt validation_flags, + FT_Bytes *ckern_table ); + + + /* */ + + /********************************************************************** + * + * @function: + * FT_ClassicKern_Free + * + * @description: + * Free the buffer allocated by classic Kern validator. + * + * @input: + * face :: + * A handle to the input face. + * + * table :: + * The pointer to the buffer that is allocated by + * @FT_ClassicKern_Validate. + * + * @note: + * This function must be used to free the buffer allocated by + * @FT_ClassicKern_Validate only. + */ + FT_EXPORT( void ) + FT_ClassicKern_Free( FT_Face face, + FT_Bytes table ); + + + /* */ + + +FT_END_HEADER + +#endif /* __FTGXVAL_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/ftgzip.h b/mod/pub.mod/freetype.mod/include/freetype/ftgzip.h new file mode 100644 index 0000000..acbc4f0 --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/ftgzip.h @@ -0,0 +1,102 @@ +/***************************************************************************/ +/* */ +/* ftgzip.h */ +/* */ +/* Gzip-compressed stream support. */ +/* */ +/* Copyright 2002, 2003, 2004, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTGZIP_H__ +#define __FTGZIP_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + /*************************************************************************/ + /* */ + /* <Section> */ + /* gzip */ + /* */ + /* <Title> */ + /* GZIP Streams */ + /* */ + /* <Abstract> */ + /* Using gzip-compressed font files. */ + /* */ + /* <Description> */ + /* This section contains the declaration of Gzip-specific functions. */ + /* */ + /*************************************************************************/ + + + /************************************************************************ + * + * @function: + * FT_Stream_OpenGzip + * + * @description: + * Open a new stream to parse gzip-compressed font files. This is + * mainly used to support the compressed `*.pcf.gz' fonts that come + * with XFree86. + * + * @input: + * stream :: + * The target embedding stream. + * + * source :: + * The source stream. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The source stream must be opened _before_ calling this function. + * + * Calling the internal function `FT_Stream_Close' on the new stream will + * *not* call `FT_Stream_Close' on the source stream. None of the stream + * objects will be released to the heap. + * + * The stream implementation is very basic and resets the decompression + * process each time seeking backwards is needed within the stream. + * + * In certain builds of the library, gzip compression recognition is + * automatically handled when calling @FT_New_Face or @FT_Open_Face. + * This means that if no font driver is capable of handling the raw + * compressed file, the library will try to open a gzipped stream from + * it and re-open the face with it. + * + * This function may return `FT_Err_Unimplemented_Feature' if your build + * of FreeType was not compiled with zlib support. + */ + FT_EXPORT( FT_Error ) + FT_Stream_OpenGzip( FT_Stream stream, + FT_Stream source ); + + /* */ + + +FT_END_HEADER + +#endif /* __FTGZIP_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/ftimage.h b/mod/pub.mod/freetype.mod/include/freetype/ftimage.h new file mode 100644 index 0000000..2fcc113 --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/ftimage.h @@ -0,0 +1,1285 @@ +/***************************************************************************/ +/* */ +/* ftimage.h */ +/* */ +/* FreeType glyph image formats and default raster interface */ +/* (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + /*************************************************************************/ + /* */ + /* Note: A `raster' is simply a scan-line converter, used to render */ + /* FT_Outlines into FT_Bitmaps. */ + /* */ + /*************************************************************************/ + + +#ifndef __FTIMAGE_H__ +#define __FTIMAGE_H__ + + + /* _STANDALONE_ is from ftgrays.c */ +#ifndef _STANDALONE_ +#include <ft2build.h> +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* basic_types */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Pos */ + /* */ + /* <Description> */ + /* The type FT_Pos is a 32-bit integer used to store vectorial */ + /* coordinates. Depending on the context, these can represent */ + /* distances in integer font units, or 16.16, or 26.6 fixed float */ + /* pixel coordinates. */ + /* */ + typedef signed long FT_Pos; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Vector */ + /* */ + /* <Description> */ + /* A simple structure used to store a 2D vector; coordinates are of */ + /* the FT_Pos type. */ + /* */ + /* <Fields> */ + /* x :: The horizontal coordinate. */ + /* y :: The vertical coordinate. */ + /* */ + typedef struct FT_Vector_ + { + FT_Pos x; + FT_Pos y; + + } FT_Vector; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_BBox */ + /* */ + /* <Description> */ + /* A structure used to hold an outline's bounding box, i.e., the */ + /* coordinates of its extrema in the horizontal and vertical */ + /* directions. */ + /* */ + /* <Fields> */ + /* xMin :: The horizontal minimum (left-most). */ + /* */ + /* yMin :: The vertical minimum (bottom-most). */ + /* */ + /* xMax :: The horizontal maximum (right-most). */ + /* */ + /* yMax :: The vertical maximum (top-most). */ + /* */ + typedef struct FT_BBox_ + { + FT_Pos xMin, yMin; + FT_Pos xMax, yMax; + + } FT_BBox; + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Pixel_Mode */ + /* */ + /* <Description> */ + /* An enumeration type used to describe the format of pixels in a */ + /* given bitmap. Note that additional formats may be added in the */ + /* future. */ + /* */ + /* <Values> */ + /* FT_PIXEL_MODE_NONE :: */ + /* Value~0 is reserved. */ + /* */ + /* FT_PIXEL_MODE_MONO :: */ + /* A monochrome bitmap, using 1~bit per pixel. Note that pixels */ + /* are stored in most-significant order (MSB), which means that */ + /* the left-most pixel in a byte has value 128. */ + /* */ + /* FT_PIXEL_MODE_GRAY :: */ + /* An 8-bit bitmap, generally used to represent anti-aliased glyph */ + /* images. Each pixel is stored in one byte. Note that the number */ + /* of `gray' levels is stored in the `num_grays' field of the */ + /* @FT_Bitmap structure (it generally is 256). */ + /* */ + /* FT_PIXEL_MODE_GRAY2 :: */ + /* A 2-bit per pixel bitmap, used to represent embedded */ + /* anti-aliased bitmaps in font files according to the OpenType */ + /* specification. We haven't found a single font using this */ + /* format, however. */ + /* */ + /* FT_PIXEL_MODE_GRAY4 :: */ + /* A 4-bit per pixel bitmap, representing embedded anti-aliased */ + /* bitmaps in font files according to the OpenType specification. */ + /* We haven't found a single font using this format, however. */ + /* */ + /* FT_PIXEL_MODE_LCD :: */ + /* An 8-bit bitmap, representing RGB or BGR decimated glyph images */ + /* used for display on LCD displays; the bitmap is three times */ + /* wider than the original glyph image. See also */ + /* @FT_RENDER_MODE_LCD. */ + /* */ + /* FT_PIXEL_MODE_LCD_V :: */ + /* An 8-bit bitmap, representing RGB or BGR decimated glyph images */ + /* used for display on rotated LCD displays; the bitmap is three */ + /* times taller than the original glyph image. See also */ + /* @FT_RENDER_MODE_LCD_V. */ + /* */ + typedef enum FT_Pixel_Mode_ + { + FT_PIXEL_MODE_NONE = 0, + FT_PIXEL_MODE_MONO, + FT_PIXEL_MODE_GRAY, + FT_PIXEL_MODE_GRAY2, + FT_PIXEL_MODE_GRAY4, + FT_PIXEL_MODE_LCD, + FT_PIXEL_MODE_LCD_V, + + FT_PIXEL_MODE_MAX /* do not remove */ + + } FT_Pixel_Mode; + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* ft_pixel_mode_xxx */ + /* */ + /* <Description> */ + /* A list of deprecated constants. Use the corresponding */ + /* @FT_Pixel_Mode values instead. */ + /* */ + /* <Values> */ + /* ft_pixel_mode_none :: See @FT_PIXEL_MODE_NONE. */ + /* ft_pixel_mode_mono :: See @FT_PIXEL_MODE_MONO. */ + /* ft_pixel_mode_grays :: See @FT_PIXEL_MODE_GRAY. */ + /* ft_pixel_mode_pal2 :: See @FT_PIXEL_MODE_GRAY2. */ + /* ft_pixel_mode_pal4 :: See @FT_PIXEL_MODE_GRAY4. */ + /* */ +#define ft_pixel_mode_none FT_PIXEL_MODE_NONE +#define ft_pixel_mode_mono FT_PIXEL_MODE_MONO +#define ft_pixel_mode_grays FT_PIXEL_MODE_GRAY +#define ft_pixel_mode_pal2 FT_PIXEL_MODE_GRAY2 +#define ft_pixel_mode_pal4 FT_PIXEL_MODE_GRAY4 + + /* */ + +#if 0 + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Palette_Mode */ + /* */ + /* <Description> */ + /* THIS TYPE IS DEPRECATED. DO NOT USE IT! */ + /* */ + /* An enumeration type to describe the format of a bitmap palette, */ + /* used with ft_pixel_mode_pal4 and ft_pixel_mode_pal8. */ + /* */ + /* <Values> */ + /* ft_palette_mode_rgb :: The palette is an array of 3-byte RGB */ + /* records. */ + /* */ + /* ft_palette_mode_rgba :: The palette is an array of 4-byte RGBA */ + /* records. */ + /* */ + /* <Note> */ + /* As ft_pixel_mode_pal2, pal4 and pal8 are currently unused by */ + /* FreeType, these types are not handled by the library itself. */ + /* */ + typedef enum FT_Palette_Mode_ + { + ft_palette_mode_rgb = 0, + ft_palette_mode_rgba, + + ft_palette_mode_max /* do not remove */ + + } FT_Palette_Mode; + + /* */ + +#endif + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Bitmap */ + /* */ + /* <Description> */ + /* A structure used to describe a bitmap or pixmap to the raster. */ + /* Note that we now manage pixmaps of various depths through the */ + /* `pixel_mode' field. */ + /* */ + /* <Fields> */ + /* rows :: The number of bitmap rows. */ + /* */ + /* width :: The number of pixels in bitmap row. */ + /* */ + /* pitch :: The pitch's absolute value is the number of bytes */ + /* taken by one bitmap row, including padding. */ + /* However, the pitch is positive when the bitmap has */ + /* a `down' flow, and negative when it has an `up' */ + /* flow. In all cases, the pitch is an offset to add */ + /* to a bitmap pointer in order to go down one row. */ + /* */ + /* buffer :: A typeless pointer to the bitmap buffer. This */ + /* value should be aligned on 32-bit boundaries in */ + /* most cases. */ + /* */ + /* num_grays :: This field is only used with */ + /* @FT_PIXEL_MODE_GRAY; it gives the number of gray */ + /* levels used in the bitmap. */ + /* */ + /* pixel_mode :: The pixel mode, i.e., how pixel bits are stored. */ + /* See @FT_Pixel_Mode for possible values. */ + /* */ + /* palette_mode :: This field is intended for paletted pixel modes; */ + /* it indicates how the palette is stored. Not */ + /* used currently. */ + /* */ + /* palette :: A typeless pointer to the bitmap palette; this */ + /* field is intended for paletted pixel modes. Not */ + /* used currently. */ + /* */ + /* <Note> */ + /* For now, the only pixel modes supported by FreeType are mono and */ + /* grays. However, drivers might be added in the future to support */ + /* more `colorful' options. */ + /* */ + typedef struct FT_Bitmap_ + { + int rows; + int width; + int pitch; + unsigned char* buffer; + short num_grays; + char pixel_mode; + char palette_mode; + void* palette; + + } FT_Bitmap; + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* outline_processing */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Outline */ + /* */ + /* <Description> */ + /* This structure is used to describe an outline to the scan-line */ + /* converter. */ + /* */ + /* <Fields> */ + /* n_contours :: The number of contours in the outline. */ + /* */ + /* n_points :: The number of points in the outline. */ + /* */ + /* points :: A pointer to an array of `n_points' @FT_Vector */ + /* elements, giving the outline's point coordinates. */ + /* */ + /* tags :: A pointer to an array of `n_points' chars, giving */ + /* each outline point's type. */ + /* */ + /* If bit~0 is unset, the point is `off' the curve, */ + /* i.e., a Bézier control point, while it is `on' if */ + /* set. */ + /* */ + /* Bit~1 is meaningful for `off' points only. If set, */ + /* it indicates a third-order Bézier arc control point; */ + /* and a second-order control point if unset. */ + /* */ + /* If bit~2 is set, bits 5-7 contain the drop-out mode */ + /* (as defined in the OpenType specification; the value */ + /* is the same as the argument to the SCANMODE */ + /* instruction). */ + /* */ + /* Bits 3 and~4 are reserved for internal purposes. */ + /* */ + /* contours :: An array of `n_contours' shorts, giving the end */ + /* point of each contour within the outline. For */ + /* example, the first contour is defined by the points */ + /* `0' to `contours[0]', the second one is defined by */ + /* the points `contours[0]+1' to `contours[1]', etc. */ + /* */ + /* flags :: A set of bit flags used to characterize the outline */ + /* and give hints to the scan-converter and hinter on */ + /* how to convert/grid-fit it. See @FT_OUTLINE_FLAGS. */ + /* */ + /* <Note> */ + /* The B/W rasterizer only checks bit~2 in the `tags' array for the */ + /* first point of each contour. The drop-out mode as given with */ + /* @FT_OUTLINE_IGNORE_DROPOUTS, @FT_OUTLINE_SMART_DROPOUTS, and */ + /* @FT_OUTLINE_INCLUDE_STUBS in `flags' is then overridden. */ + /* */ + typedef struct FT_Outline_ + { + short n_contours; /* number of contours in glyph */ + short n_points; /* number of points in the glyph */ + + FT_Vector* points; /* the outline's points */ + char* tags; /* the points flags */ + short* contours; /* the contour end points */ + + int flags; /* outline masks */ + + } FT_Outline; + + /* Following limits must be consistent with */ + /* FT_Outline.{n_contours,n_points} */ +#define FT_OUTLINE_CONTOURS_MAX SHRT_MAX +#define FT_OUTLINE_POINTS_MAX SHRT_MAX + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_OUTLINE_FLAGS */ + /* */ + /* <Description> */ + /* A list of bit-field constants use for the flags in an outline's */ + /* `flags' field. */ + /* */ + /* <Values> */ + /* FT_OUTLINE_NONE :: */ + /* Value~0 is reserved. */ + /* */ + /* FT_OUTLINE_OWNER :: */ + /* If set, this flag indicates that the outline's field arrays */ + /* (i.e., `points', `flags', and `contours') are `owned' by the */ + /* outline object, and should thus be freed when it is destroyed. */ + /* */ + /* FT_OUTLINE_EVEN_ODD_FILL :: */ + /* By default, outlines are filled using the non-zero winding rule. */ + /* If set to 1, the outline will be filled using the even-odd fill */ + /* rule (only works with the smooth rasterizer). */ + /* */ + /* FT_OUTLINE_REVERSE_FILL :: */ + /* By default, outside contours of an outline are oriented in */ + /* clock-wise direction, as defined in the TrueType specification. */ + /* This flag is set if the outline uses the opposite direction */ + /* (typically for Type~1 fonts). This flag is ignored by the scan */ + /* converter. */ + /* */ + /* FT_OUTLINE_IGNORE_DROPOUTS :: */ + /* By default, the scan converter will try to detect drop-outs in */ + /* an outline and correct the glyph bitmap to ensure consistent */ + /* shape continuity. If set, this flag hints the scan-line */ + /* converter to ignore such cases. See below for more information. */ + /* */ + /* FT_OUTLINE_SMART_DROPOUTS :: */ + /* Select smart dropout control. If unset, use simple dropout */ + /* control. Ignored if @FT_OUTLINE_IGNORE_DROPOUTS is set. See */ + /* below for more information. */ + /* */ + /* FT_OUTLINE_INCLUDE_STUBS :: */ + /* If set, turn pixels on for `stubs', otherwise exclude them. */ + /* Ignored if @FT_OUTLINE_IGNORE_DROPOUTS is set. See below for */ + /* more information. */ + /* */ + /* FT_OUTLINE_HIGH_PRECISION :: */ + /* This flag indicates that the scan-line converter should try to */ + /* convert this outline to bitmaps with the highest possible */ + /* quality. It is typically set for small character sizes. Note */ + /* that this is only a hint that might be completely ignored by a */ + /* given scan-converter. */ + /* */ + /* FT_OUTLINE_SINGLE_PASS :: */ + /* This flag is set to force a given scan-converter to only use a */ + /* single pass over the outline to render a bitmap glyph image. */ + /* Normally, it is set for very large character sizes. It is only */ + /* a hint that might be completely ignored by a given */ + /* scan-converter. */ + /* */ + /* <Note> */ + /* The flags @FT_OUTLINE_IGNORE_DROPOUTS, @FT_OUTLINE_SMART_DROPOUTS, */ + /* and @FT_OUTLINE_INCLUDE_STUBS are ignored by the smooth */ + /* rasterizer. */ + /* */ + /* There exists a second mechanism to pass the drop-out mode to the */ + /* B/W rasterizer; see the `tags' field in @FT_Outline. */ + /* */ + /* Please refer to the description of the `SCANTYPE' instruction in */ + /* the OpenType specification (in file `ttinst1.doc') how simple */ + /* drop-outs, smart drop-outs, and stubs are defined. */ + /* */ +#define FT_OUTLINE_NONE 0x0 +#define FT_OUTLINE_OWNER 0x1 +#define FT_OUTLINE_EVEN_ODD_FILL 0x2 +#define FT_OUTLINE_REVERSE_FILL 0x4 +#define FT_OUTLINE_IGNORE_DROPOUTS 0x8 +#define FT_OUTLINE_SMART_DROPOUTS 0x10 +#define FT_OUTLINE_INCLUDE_STUBS 0x20 + +#define FT_OUTLINE_HIGH_PRECISION 0x100 +#define FT_OUTLINE_SINGLE_PASS 0x200 + + + /************************************************************************* + * + * @enum: + * ft_outline_flags + * + * @description: + * These constants are deprecated. Please use the corresponding + * @FT_OUTLINE_FLAGS values. + * + * @values: + * ft_outline_none :: See @FT_OUTLINE_NONE. + * ft_outline_owner :: See @FT_OUTLINE_OWNER. + * ft_outline_even_odd_fill :: See @FT_OUTLINE_EVEN_ODD_FILL. + * ft_outline_reverse_fill :: See @FT_OUTLINE_REVERSE_FILL. + * ft_outline_ignore_dropouts :: See @FT_OUTLINE_IGNORE_DROPOUTS. + * ft_outline_high_precision :: See @FT_OUTLINE_HIGH_PRECISION. + * ft_outline_single_pass :: See @FT_OUTLINE_SINGLE_PASS. + */ +#define ft_outline_none FT_OUTLINE_NONE +#define ft_outline_owner FT_OUTLINE_OWNER +#define ft_outline_even_odd_fill FT_OUTLINE_EVEN_ODD_FILL +#define ft_outline_reverse_fill FT_OUTLINE_REVERSE_FILL +#define ft_outline_ignore_dropouts FT_OUTLINE_IGNORE_DROPOUTS +#define ft_outline_high_precision FT_OUTLINE_HIGH_PRECISION +#define ft_outline_single_pass FT_OUTLINE_SINGLE_PASS + + /* */ + +#define FT_CURVE_TAG( flag ) ( flag & 3 ) + +#define FT_CURVE_TAG_ON 1 +#define FT_CURVE_TAG_CONIC 0 +#define FT_CURVE_TAG_CUBIC 2 + +#define FT_CURVE_TAG_HAS_SCANMODE 4 + +#define FT_CURVE_TAG_TOUCH_X 8 /* reserved for the TrueType hinter */ +#define FT_CURVE_TAG_TOUCH_Y 16 /* reserved for the TrueType hinter */ + +#define FT_CURVE_TAG_TOUCH_BOTH ( FT_CURVE_TAG_TOUCH_X | \ + FT_CURVE_TAG_TOUCH_Y ) + +#define FT_Curve_Tag_On FT_CURVE_TAG_ON +#define FT_Curve_Tag_Conic FT_CURVE_TAG_CONIC +#define FT_Curve_Tag_Cubic FT_CURVE_TAG_CUBIC +#define FT_Curve_Tag_Touch_X FT_CURVE_TAG_TOUCH_X +#define FT_Curve_Tag_Touch_Y FT_CURVE_TAG_TOUCH_Y + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Outline_MoveToFunc */ + /* */ + /* <Description> */ + /* A function pointer type used to describe the signature of a `move */ + /* to' function during outline walking/decomposition. */ + /* */ + /* A `move to' is emitted to start a new contour in an outline. */ + /* */ + /* <Input> */ + /* to :: A pointer to the target point of the `move to'. */ + /* */ + /* user :: A typeless pointer which is passed from the caller of the */ + /* decomposition function. */ + /* */ + /* <Return> */ + /* Error code. 0~means success. */ + /* */ + typedef int + (*FT_Outline_MoveToFunc)( const FT_Vector* to, + void* user ); + +#define FT_Outline_MoveTo_Func FT_Outline_MoveToFunc + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Outline_LineToFunc */ + /* */ + /* <Description> */ + /* A function pointer type used to describe the signature of a `line */ + /* to' function during outline walking/decomposition. */ + /* */ + /* A `line to' is emitted to indicate a segment in the outline. */ + /* */ + /* <Input> */ + /* to :: A pointer to the target point of the `line to'. */ + /* */ + /* user :: A typeless pointer which is passed from the caller of the */ + /* decomposition function. */ + /* */ + /* <Return> */ + /* Error code. 0~means success. */ + /* */ + typedef int + (*FT_Outline_LineToFunc)( const FT_Vector* to, + void* user ); + +#define FT_Outline_LineTo_Func FT_Outline_LineToFunc + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Outline_ConicToFunc */ + /* */ + /* <Description> */ + /* A function pointer type use to describe the signature of a `conic */ + /* to' function during outline walking/decomposition. */ + /* */ + /* A `conic to' is emitted to indicate a second-order Bézier arc in */ + /* the outline. */ + /* */ + /* <Input> */ + /* control :: An intermediate control point between the last position */ + /* and the new target in `to'. */ + /* */ + /* to :: A pointer to the target end point of the conic arc. */ + /* */ + /* user :: A typeless pointer which is passed from the caller of */ + /* the decomposition function. */ + /* */ + /* <Return> */ + /* Error code. 0~means success. */ + /* */ + typedef int + (*FT_Outline_ConicToFunc)( const FT_Vector* control, + const FT_Vector* to, + void* user ); + +#define FT_Outline_ConicTo_Func FT_Outline_ConicToFunc + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Outline_CubicToFunc */ + /* */ + /* <Description> */ + /* A function pointer type used to describe the signature of a `cubic */ + /* to' function during outline walking/decomposition. */ + /* */ + /* A `cubic to' is emitted to indicate a third-order Bézier arc. */ + /* */ + /* <Input> */ + /* control1 :: A pointer to the first Bézier control point. */ + /* */ + /* control2 :: A pointer to the second Bézier control point. */ + /* */ + /* to :: A pointer to the target end point. */ + /* */ + /* user :: A typeless pointer which is passed from the caller of */ + /* the decomposition function. */ + /* */ + /* <Return> */ + /* Error code. 0~means success. */ + /* */ + typedef int + (*FT_Outline_CubicToFunc)( const FT_Vector* control1, + const FT_Vector* control2, + const FT_Vector* to, + void* user ); + +#define FT_Outline_CubicTo_Func FT_Outline_CubicToFunc + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Outline_Funcs */ + /* */ + /* <Description> */ + /* A structure to hold various function pointers used during outline */ + /* decomposition in order to emit segments, conic, and cubic Béziers, */ + /* as well as `move to' and `close to' operations. */ + /* */ + /* <Fields> */ + /* move_to :: The `move to' emitter. */ + /* */ + /* line_to :: The segment emitter. */ + /* */ + /* conic_to :: The second-order Bézier arc emitter. */ + /* */ + /* cubic_to :: The third-order Bézier arc emitter. */ + /* */ + /* shift :: The shift that is applied to coordinates before they */ + /* are sent to the emitter. */ + /* */ + /* delta :: The delta that is applied to coordinates before they */ + /* are sent to the emitter, but after the shift. */ + /* */ + /* <Note> */ + /* The point coordinates sent to the emitters are the transformed */ + /* version of the original coordinates (this is important for high */ + /* accuracy during scan-conversion). The transformation is simple: */ + /* */ + /* { */ + /* x' = (x << shift) - delta */ + /* y' = (x << shift) - delta */ + /* } */ + /* */ + /* Set the value of `shift' and `delta' to~0 to get the original */ + /* point coordinates. */ + /* */ + typedef struct FT_Outline_Funcs_ + { + FT_Outline_MoveToFunc move_to; + FT_Outline_LineToFunc line_to; + FT_Outline_ConicToFunc conic_to; + FT_Outline_CubicToFunc cubic_to; + + int shift; + FT_Pos delta; + + } FT_Outline_Funcs; + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* basic_types */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_IMAGE_TAG */ + /* */ + /* <Description> */ + /* This macro converts four-letter tags to an unsigned long type. */ + /* */ + /* <Note> */ + /* Since many 16-bit compilers don't like 32-bit enumerations, you */ + /* should redefine this macro in case of problems to something like */ + /* this: */ + /* */ + /* { */ + /* #define FT_IMAGE_TAG( value, _x1, _x2, _x3, _x4 ) value */ + /* } */ + /* */ + /* to get a simple enumeration without assigning special numbers. */ + /* */ +#ifndef FT_IMAGE_TAG +#define FT_IMAGE_TAG( value, _x1, _x2, _x3, _x4 ) \ + value = ( ( (unsigned long)_x1 << 24 ) | \ + ( (unsigned long)_x2 << 16 ) | \ + ( (unsigned long)_x3 << 8 ) | \ + (unsigned long)_x4 ) +#endif /* FT_IMAGE_TAG */ + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Glyph_Format */ + /* */ + /* <Description> */ + /* An enumeration type used to describe the format of a given glyph */ + /* image. Note that this version of FreeType only supports two image */ + /* formats, even though future font drivers will be able to register */ + /* their own format. */ + /* */ + /* <Values> */ + /* FT_GLYPH_FORMAT_NONE :: */ + /* The value~0 is reserved. */ + /* */ + /* FT_GLYPH_FORMAT_COMPOSITE :: */ + /* The glyph image is a composite of several other images. This */ + /* format is _only_ used with @FT_LOAD_NO_RECURSE, and is used to */ + /* report compound glyphs (like accented characters). */ + /* */ + /* FT_GLYPH_FORMAT_BITMAP :: */ + /* The glyph image is a bitmap, and can be described as an */ + /* @FT_Bitmap. You generally need to access the `bitmap' field of */ + /* the @FT_GlyphSlotRec structure to read it. */ + /* */ + /* FT_GLYPH_FORMAT_OUTLINE :: */ + /* The glyph image is a vectorial outline made of line segments */ + /* and Bézier arcs; it can be described as an @FT_Outline; you */ + /* generally want to access the `outline' field of the */ + /* @FT_GlyphSlotRec structure to read it. */ + /* */ + /* FT_GLYPH_FORMAT_PLOTTER :: */ + /* The glyph image is a vectorial path with no inside and outside */ + /* contours. Some Type~1 fonts, like those in the Hershey family, */ + /* contain glyphs in this format. These are described as */ + /* @FT_Outline, but FreeType isn't currently capable of rendering */ + /* them correctly. */ + /* */ + typedef enum FT_Glyph_Format_ + { + FT_IMAGE_TAG( FT_GLYPH_FORMAT_NONE, 0, 0, 0, 0 ), + + FT_IMAGE_TAG( FT_GLYPH_FORMAT_COMPOSITE, 'c', 'o', 'm', 'p' ), + FT_IMAGE_TAG( FT_GLYPH_FORMAT_BITMAP, 'b', 'i', 't', 's' ), + FT_IMAGE_TAG( FT_GLYPH_FORMAT_OUTLINE, 'o', 'u', 't', 'l' ), + FT_IMAGE_TAG( FT_GLYPH_FORMAT_PLOTTER, 'p', 'l', 'o', 't' ) + + } FT_Glyph_Format; + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* ft_glyph_format_xxx */ + /* */ + /* <Description> */ + /* A list of deprecated constants. Use the corresponding */ + /* @FT_Glyph_Format values instead. */ + /* */ + /* <Values> */ + /* ft_glyph_format_none :: See @FT_GLYPH_FORMAT_NONE. */ + /* ft_glyph_format_composite :: See @FT_GLYPH_FORMAT_COMPOSITE. */ + /* ft_glyph_format_bitmap :: See @FT_GLYPH_FORMAT_BITMAP. */ + /* ft_glyph_format_outline :: See @FT_GLYPH_FORMAT_OUTLINE. */ + /* ft_glyph_format_plotter :: See @FT_GLYPH_FORMAT_PLOTTER. */ + /* */ +#define ft_glyph_format_none FT_GLYPH_FORMAT_NONE +#define ft_glyph_format_composite FT_GLYPH_FORMAT_COMPOSITE +#define ft_glyph_format_bitmap FT_GLYPH_FORMAT_BITMAP +#define ft_glyph_format_outline FT_GLYPH_FORMAT_OUTLINE +#define ft_glyph_format_plotter FT_GLYPH_FORMAT_PLOTTER + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** R A S T E R D E F I N I T I O N S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* A raster is a scan converter, in charge of rendering an outline into */ + /* a a bitmap. This section contains the public API for rasters. */ + /* */ + /* Note that in FreeType 2, all rasters are now encapsulated within */ + /* specific modules called `renderers'. See `freetype/ftrender.h' for */ + /* more details on renderers. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* raster */ + /* */ + /* <Title> */ + /* Scanline Converter */ + /* */ + /* <Abstract> */ + /* How vectorial outlines are converted into bitmaps and pixmaps. */ + /* */ + /* <Description> */ + /* This section contains technical definitions. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Raster */ + /* */ + /* <Description> */ + /* A handle (pointer) to a raster object. Each object can be used */ + /* independently to convert an outline into a bitmap or pixmap. */ + /* */ + typedef struct FT_RasterRec_* FT_Raster; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Span */ + /* */ + /* <Description> */ + /* A structure used to model a single span of gray (or black) pixels */ + /* when rendering a monochrome or anti-aliased bitmap. */ + /* */ + /* <Fields> */ + /* x :: The span's horizontal start position. */ + /* */ + /* len :: The span's length in pixels. */ + /* */ + /* coverage :: The span color/coverage, ranging from 0 (background) */ + /* to 255 (foreground). Only used for anti-aliased */ + /* rendering. */ + /* */ + /* <Note> */ + /* This structure is used by the span drawing callback type named */ + /* @FT_SpanFunc which takes the y~coordinate of the span as a */ + /* a parameter. */ + /* */ + /* The coverage value is always between 0 and 255. If you want less */ + /* gray values, the callback function has to reduce them. */ + /* */ + typedef struct FT_Span_ + { + short x; + unsigned short len; + unsigned char coverage; + + } FT_Span; + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_SpanFunc */ + /* */ + /* <Description> */ + /* A function used as a call-back by the anti-aliased renderer in */ + /* order to let client applications draw themselves the gray pixel */ + /* spans on each scan line. */ + /* */ + /* <Input> */ + /* y :: The scanline's y~coordinate. */ + /* */ + /* count :: The number of spans to draw on this scanline. */ + /* */ + /* spans :: A table of `count' spans to draw on the scanline. */ + /* */ + /* user :: User-supplied data that is passed to the callback. */ + /* */ + /* <Note> */ + /* This callback allows client applications to directly render the */ + /* gray spans of the anti-aliased bitmap to any kind of surfaces. */ + /* */ + /* This can be used to write anti-aliased outlines directly to a */ + /* given background bitmap, and even perform translucency. */ + /* */ + /* Note that the `count' field cannot be greater than a fixed value */ + /* defined by the `FT_MAX_GRAY_SPANS' configuration macro in */ + /* `ftoption.h'. By default, this value is set to~32, which means */ + /* that if there are more than 32~spans on a given scanline, the */ + /* callback is called several times with the same `y' parameter in */ + /* order to draw all callbacks. */ + /* */ + /* Otherwise, the callback is only called once per scan-line, and */ + /* only for those scanlines that do have `gray' pixels on them. */ + /* */ + typedef void + (*FT_SpanFunc)( int y, + int count, + const FT_Span* spans, + void* user ); + +#define FT_Raster_Span_Func FT_SpanFunc + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Raster_BitTest_Func */ + /* */ + /* <Description> */ + /* THIS TYPE IS DEPRECATED. DO NOT USE IT. */ + /* */ + /* A function used as a call-back by the monochrome scan-converter */ + /* to test whether a given target pixel is already set to the drawing */ + /* `color'. These tests are crucial to implement drop-out control */ + /* per-se the TrueType spec. */ + /* */ + /* <Input> */ + /* y :: The pixel's y~coordinate. */ + /* */ + /* x :: The pixel's x~coordinate. */ + /* */ + /* user :: User-supplied data that is passed to the callback. */ + /* */ + /* <Return> */ + /* 1~if the pixel is `set', 0~otherwise. */ + /* */ + typedef int + (*FT_Raster_BitTest_Func)( int y, + int x, + void* user ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Raster_BitSet_Func */ + /* */ + /* <Description> */ + /* THIS TYPE IS DEPRECATED. DO NOT USE IT. */ + /* */ + /* A function used as a call-back by the monochrome scan-converter */ + /* to set an individual target pixel. This is crucial to implement */ + /* drop-out control according to the TrueType specification. */ + /* */ + /* <Input> */ + /* y :: The pixel's y~coordinate. */ + /* */ + /* x :: The pixel's x~coordinate. */ + /* */ + /* user :: User-supplied data that is passed to the callback. */ + /* */ + /* <Return> */ + /* 1~if the pixel is `set', 0~otherwise. */ + /* */ + typedef void + (*FT_Raster_BitSet_Func)( int y, + int x, + void* user ); + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_RASTER_FLAG_XXX */ + /* */ + /* <Description> */ + /* A list of bit flag constants as used in the `flags' field of a */ + /* @FT_Raster_Params structure. */ + /* */ + /* <Values> */ + /* FT_RASTER_FLAG_DEFAULT :: This value is 0. */ + /* */ + /* FT_RASTER_FLAG_AA :: This flag is set to indicate that an */ + /* anti-aliased glyph image should be */ + /* generated. Otherwise, it will be */ + /* monochrome (1-bit). */ + /* */ + /* FT_RASTER_FLAG_DIRECT :: This flag is set to indicate direct */ + /* rendering. In this mode, client */ + /* applications must provide their own span */ + /* callback. This lets them directly */ + /* draw or compose over an existing bitmap. */ + /* If this bit is not set, the target */ + /* pixmap's buffer _must_ be zeroed before */ + /* rendering. */ + /* */ + /* Note that for now, direct rendering is */ + /* only possible with anti-aliased glyphs. */ + /* */ + /* FT_RASTER_FLAG_CLIP :: This flag is only used in direct */ + /* rendering mode. If set, the output will */ + /* be clipped to a box specified in the */ + /* `clip_box' field of the */ + /* @FT_Raster_Params structure. */ + /* */ + /* Note that by default, the glyph bitmap */ + /* is clipped to the target pixmap, except */ + /* in direct rendering mode where all spans */ + /* are generated if no clipping box is set. */ + /* */ +#define FT_RASTER_FLAG_DEFAULT 0x0 +#define FT_RASTER_FLAG_AA 0x1 +#define FT_RASTER_FLAG_DIRECT 0x2 +#define FT_RASTER_FLAG_CLIP 0x4 + + /* deprecated */ +#define ft_raster_flag_default FT_RASTER_FLAG_DEFAULT +#define ft_raster_flag_aa FT_RASTER_FLAG_AA +#define ft_raster_flag_direct FT_RASTER_FLAG_DIRECT +#define ft_raster_flag_clip FT_RASTER_FLAG_CLIP + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Raster_Params */ + /* */ + /* <Description> */ + /* A structure to hold the arguments used by a raster's render */ + /* function. */ + /* */ + /* <Fields> */ + /* target :: The target bitmap. */ + /* */ + /* source :: A pointer to the source glyph image (e.g., an */ + /* @FT_Outline). */ + /* */ + /* flags :: The rendering flags. */ + /* */ + /* gray_spans :: The gray span drawing callback. */ + /* */ + /* black_spans :: The black span drawing callback. UNIMPLEMENTED! */ + /* */ + /* bit_test :: The bit test callback. UNIMPLEMENTED! */ + /* */ + /* bit_set :: The bit set callback. UNIMPLEMENTED! */ + /* */ + /* user :: User-supplied data that is passed to each drawing */ + /* callback. */ + /* */ + /* clip_box :: An optional clipping box. It is only used in */ + /* direct rendering mode. Note that coordinates here */ + /* should be expressed in _integer_ pixels (and not in */ + /* 26.6 fixed-point units). */ + /* */ + /* <Note> */ + /* An anti-aliased glyph bitmap is drawn if the @FT_RASTER_FLAG_AA */ + /* bit flag is set in the `flags' field, otherwise a monochrome */ + /* bitmap is generated. */ + /* */ + /* If the @FT_RASTER_FLAG_DIRECT bit flag is set in `flags', the */ + /* raster will call the `gray_spans' callback to draw gray pixel */ + /* spans, in the case of an aa glyph bitmap, it will call */ + /* `black_spans', and `bit_test' and `bit_set' in the case of a */ + /* monochrome bitmap. This allows direct composition over a */ + /* pre-existing bitmap through user-provided callbacks to perform the */ + /* span drawing/composition. */ + /* */ + /* Note that the `bit_test' and `bit_set' callbacks are required when */ + /* rendering a monochrome bitmap, as they are crucial to implement */ + /* correct drop-out control as defined in the TrueType specification. */ + /* */ + typedef struct FT_Raster_Params_ + { + const FT_Bitmap* target; + const void* source; + int flags; + FT_SpanFunc gray_spans; + FT_SpanFunc black_spans; /* doesn't work! */ + FT_Raster_BitTest_Func bit_test; /* doesn't work! */ + FT_Raster_BitSet_Func bit_set; /* doesn't work! */ + void* user; + FT_BBox clip_box; + + } FT_Raster_Params; + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Raster_NewFunc */ + /* */ + /* <Description> */ + /* A function used to create a new raster object. */ + /* */ + /* <Input> */ + /* memory :: A handle to the memory allocator. */ + /* */ + /* <Output> */ + /* raster :: A handle to the new raster object. */ + /* */ + /* <Return> */ + /* Error code. 0~means success. */ + /* */ + /* <Note> */ + /* The `memory' parameter is a typeless pointer in order to avoid */ + /* un-wanted dependencies on the rest of the FreeType code. In */ + /* practice, it is an @FT_Memory object, i.e., a handle to the */ + /* standard FreeType memory allocator. However, this field can be */ + /* completely ignored by a given raster implementation. */ + /* */ + typedef int + (*FT_Raster_NewFunc)( void* memory, + FT_Raster* raster ); + +#define FT_Raster_New_Func FT_Raster_NewFunc + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Raster_DoneFunc */ + /* */ + /* <Description> */ + /* A function used to destroy a given raster object. */ + /* */ + /* <Input> */ + /* raster :: A handle to the raster object. */ + /* */ + typedef void + (*FT_Raster_DoneFunc)( FT_Raster raster ); + +#define FT_Raster_Done_Func FT_Raster_DoneFunc + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Raster_ResetFunc */ + /* */ + /* <Description> */ + /* FreeType provides an area of memory called the `render pool', */ + /* available to all registered rasters. This pool can be freely used */ + /* during a given scan-conversion but is shared by all rasters. Its */ + /* content is thus transient. */ + /* */ + /* This function is called each time the render pool changes, or just */ + /* after a new raster object is created. */ + /* */ + /* <Input> */ + /* raster :: A handle to the new raster object. */ + /* */ + /* pool_base :: The address in memory of the render pool. */ + /* */ + /* pool_size :: The size in bytes of the render pool. */ + /* */ + /* <Note> */ + /* Rasters can ignore the render pool and rely on dynamic memory */ + /* allocation if they want to (a handle to the memory allocator is */ + /* passed to the raster constructor). However, this is not */ + /* recommended for efficiency purposes. */ + /* */ + typedef void + (*FT_Raster_ResetFunc)( FT_Raster raster, + unsigned char* pool_base, + unsigned long pool_size ); + +#define FT_Raster_Reset_Func FT_Raster_ResetFunc + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Raster_SetModeFunc */ + /* */ + /* <Description> */ + /* This function is a generic facility to change modes or attributes */ + /* in a given raster. This can be used for debugging purposes, or */ + /* simply to allow implementation-specific `features' in a given */ + /* raster module. */ + /* */ + /* <Input> */ + /* raster :: A handle to the new raster object. */ + /* */ + /* mode :: A 4-byte tag used to name the mode or property. */ + /* */ + /* args :: A pointer to the new mode/property to use. */ + /* */ + typedef int + (*FT_Raster_SetModeFunc)( FT_Raster raster, + unsigned long mode, + void* args ); + +#define FT_Raster_Set_Mode_Func FT_Raster_SetModeFunc + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Raster_RenderFunc */ + /* */ + /* <Description> */ + /* Invoke a given raster to scan-convert a given glyph image into a */ + /* target bitmap. */ + /* */ + /* <Input> */ + /* raster :: A handle to the raster object. */ + /* */ + /* params :: A pointer to an @FT_Raster_Params structure used to */ + /* store the rendering parameters. */ + /* */ + /* <Return> */ + /* Error code. 0~means success. */ + /* */ + /* <Note> */ + /* The exact format of the source image depends on the raster's glyph */ + /* format defined in its @FT_Raster_Funcs structure. It can be an */ + /* @FT_Outline or anything else in order to support a large array of */ + /* glyph formats. */ + /* */ + /* Note also that the render function can fail and return a */ + /* `FT_Err_Unimplemented_Feature' error code if the raster used does */ + /* not support direct composition. */ + /* */ + /* XXX: For now, the standard raster doesn't support direct */ + /* composition but this should change for the final release (see */ + /* the files `demos/src/ftgrays.c' and `demos/src/ftgrays2.c' */ + /* for examples of distinct implementations which support direct */ + /* composition). */ + /* */ + typedef int + (*FT_Raster_RenderFunc)( FT_Raster raster, + const FT_Raster_Params* params ); + +#define FT_Raster_Render_Func FT_Raster_RenderFunc + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Raster_Funcs */ + /* */ + /* <Description> */ + /* A structure used to describe a given raster class to the library. */ + /* */ + /* <Fields> */ + /* glyph_format :: The supported glyph format for this raster. */ + /* */ + /* raster_new :: The raster constructor. */ + /* */ + /* raster_reset :: Used to reset the render pool within the raster. */ + /* */ + /* raster_render :: A function to render a glyph into a given bitmap. */ + /* */ + /* raster_done :: The raster destructor. */ + /* */ + typedef struct FT_Raster_Funcs_ + { + FT_Glyph_Format glyph_format; + FT_Raster_NewFunc raster_new; + FT_Raster_ResetFunc raster_reset; + FT_Raster_SetModeFunc raster_set_mode; + FT_Raster_RenderFunc raster_render; + FT_Raster_DoneFunc raster_done; + + } FT_Raster_Funcs; + + + /* */ + + +FT_END_HEADER + +#endif /* __FTIMAGE_H__ */ + + +/* END */ + + +/* Local Variables: */ +/* coding: utf-8 */ +/* End: */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/ftincrem.h b/mod/pub.mod/freetype.mod/include/freetype/ftincrem.h new file mode 100644 index 0000000..96abede --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/ftincrem.h @@ -0,0 +1,349 @@ +/***************************************************************************/ +/* */ +/* ftincrem.h */ +/* */ +/* FreeType incremental loading (specification). */ +/* */ +/* Copyright 2002, 2003, 2006, 2007, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTINCREM_H__ +#define __FTINCREM_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + /*************************************************************************** + * + * @section: + * incremental + * + * @title: + * Incremental Loading + * + * @abstract: + * Custom Glyph Loading. + * + * @description: + * This section contains various functions used to perform so-called + * `incremental' glyph loading. This is a mode where all glyphs loaded + * from a given @FT_Face are provided by the client application, + * + * Apart from that, all other tables are loaded normally from the font + * file. This mode is useful when FreeType is used within another + * engine, e.g., a PostScript Imaging Processor. + * + * To enable this mode, you must use @FT_Open_Face, passing an + * @FT_Parameter with the @FT_PARAM_TAG_INCREMENTAL tag and an + * @FT_Incremental_Interface value. See the comments for + * @FT_Incremental_InterfaceRec for an example. + * + */ + + + /*************************************************************************** + * + * @type: + * FT_Incremental + * + * @description: + * An opaque type describing a user-provided object used to implement + * `incremental' glyph loading within FreeType. This is used to support + * embedded fonts in certain environments (e.g., PostScript interpreters), + * where the glyph data isn't in the font file, or must be overridden by + * different values. + * + * @note: + * It is up to client applications to create and implement @FT_Incremental + * objects, as long as they provide implementations for the methods + * @FT_Incremental_GetGlyphDataFunc, @FT_Incremental_FreeGlyphDataFunc + * and @FT_Incremental_GetGlyphMetricsFunc. + * + * See the description of @FT_Incremental_InterfaceRec to understand how + * to use incremental objects with FreeType. + * + */ + typedef struct FT_IncrementalRec_* FT_Incremental; + + + /*************************************************************************** + * + * @struct: + * FT_Incremental_MetricsRec + * + * @description: + * A small structure used to contain the basic glyph metrics returned + * by the @FT_Incremental_GetGlyphMetricsFunc method. + * + * @fields: + * bearing_x :: + * Left bearing, in font units. + * + * bearing_y :: + * Top bearing, in font units. + * + * advance :: + * Glyph advance, in font units. + * + * @note: + * These correspond to horizontal or vertical metrics depending on the + * value of the `vertical' argument to the function + * @FT_Incremental_GetGlyphMetricsFunc. + * + */ + typedef struct FT_Incremental_MetricsRec_ + { + FT_Long bearing_x; + FT_Long bearing_y; + FT_Long advance; + + } FT_Incremental_MetricsRec; + + + /*************************************************************************** + * + * @struct: + * FT_Incremental_Metrics + * + * @description: + * A handle to an @FT_Incremental_MetricsRec structure. + * + */ + typedef struct FT_Incremental_MetricsRec_* FT_Incremental_Metrics; + + + /*************************************************************************** + * + * @type: + * FT_Incremental_GetGlyphDataFunc + * + * @description: + * A function called by FreeType to access a given glyph's data bytes + * during @FT_Load_Glyph or @FT_Load_Char if incremental loading is + * enabled. + * + * Note that the format of the glyph's data bytes depends on the font + * file format. For TrueType, it must correspond to the raw bytes within + * the `glyf' table. For PostScript formats, it must correspond to the + * *unencrypted* charstring bytes, without any `lenIV' header. It is + * undefined for any other format. + * + * @input: + * incremental :: + * Handle to an opaque @FT_Incremental handle provided by the client + * application. + * + * glyph_index :: + * Index of relevant glyph. + * + * @output: + * adata :: + * A structure describing the returned glyph data bytes (which will be + * accessed as a read-only byte block). + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * If this function returns successfully the method + * @FT_Incremental_FreeGlyphDataFunc will be called later to release + * the data bytes. + * + * Nested calls to @FT_Incremental_GetGlyphDataFunc can happen for + * compound glyphs. + * + */ + typedef FT_Error + (*FT_Incremental_GetGlyphDataFunc)( FT_Incremental incremental, + FT_UInt glyph_index, + FT_Data* adata ); + + + /*************************************************************************** + * + * @type: + * FT_Incremental_FreeGlyphDataFunc + * + * @description: + * A function used to release the glyph data bytes returned by a + * successful call to @FT_Incremental_GetGlyphDataFunc. + * + * @input: + * incremental :: + * A handle to an opaque @FT_Incremental handle provided by the client + * application. + * + * data :: + * A structure describing the glyph data bytes (which will be accessed + * as a read-only byte block). + * + */ + typedef void + (*FT_Incremental_FreeGlyphDataFunc)( FT_Incremental incremental, + FT_Data* data ); + + + /*************************************************************************** + * + * @type: + * FT_Incremental_GetGlyphMetricsFunc + * + * @description: + * A function used to retrieve the basic metrics of a given glyph index + * before accessing its data. This is necessary because, in certain + * formats like TrueType, the metrics are stored in a different place from + * the glyph images proper. + * + * @input: + * incremental :: + * A handle to an opaque @FT_Incremental handle provided by the client + * application. + * + * glyph_index :: + * Index of relevant glyph. + * + * vertical :: + * If true, return vertical metrics. + * + * ametrics :: + * This parameter is used for both input and output. + * The original glyph metrics, if any, in font units. If metrics are + * not available all the values must be set to zero. + * + * @output: + * ametrics :: + * The replacement glyph metrics in font units. + * + */ + typedef FT_Error + (*FT_Incremental_GetGlyphMetricsFunc) + ( FT_Incremental incremental, + FT_UInt glyph_index, + FT_Bool vertical, + FT_Incremental_MetricsRec *ametrics ); + + + /************************************************************************** + * + * @struct: + * FT_Incremental_FuncsRec + * + * @description: + * A table of functions for accessing fonts that load data + * incrementally. Used in @FT_Incremental_InterfaceRec. + * + * @fields: + * get_glyph_data :: + * The function to get glyph data. Must not be null. + * + * free_glyph_data :: + * The function to release glyph data. Must not be null. + * + * get_glyph_metrics :: + * The function to get glyph metrics. May be null if the font does + * not provide overriding glyph metrics. + * + */ + typedef struct FT_Incremental_FuncsRec_ + { + FT_Incremental_GetGlyphDataFunc get_glyph_data; + FT_Incremental_FreeGlyphDataFunc free_glyph_data; + FT_Incremental_GetGlyphMetricsFunc get_glyph_metrics; + + } FT_Incremental_FuncsRec; + + + /*************************************************************************** + * + * @struct: + * FT_Incremental_InterfaceRec + * + * @description: + * A structure to be used with @FT_Open_Face to indicate that the user + * wants to support incremental glyph loading. You should use it with + * @FT_PARAM_TAG_INCREMENTAL as in the following example: + * + * { + * FT_Incremental_InterfaceRec inc_int; + * FT_Parameter parameter; + * FT_Open_Args open_args; + * + * + * // set up incremental descriptor + * inc_int.funcs = my_funcs; + * inc_int.object = my_object; + * + * // set up optional parameter + * parameter.tag = FT_PARAM_TAG_INCREMENTAL; + * parameter.data = &inc_int; + * + * // set up FT_Open_Args structure + * open_args.flags = FT_OPEN_PATHNAME | FT_OPEN_PARAMS; + * open_args.pathname = my_font_pathname; + * open_args.num_params = 1; + * open_args.params = ¶meter; // we use one optional argument + * + * // open the font + * error = FT_Open_Face( library, &open_args, index, &face ); + * ... + * } + * + */ + typedef struct FT_Incremental_InterfaceRec_ + { + const FT_Incremental_FuncsRec* funcs; + FT_Incremental object; + + } FT_Incremental_InterfaceRec; + + + /*************************************************************************** + * + * @type: + * FT_Incremental_Interface + * + * @description: + * A pointer to an @FT_Incremental_InterfaceRec structure. + * + */ + typedef FT_Incremental_InterfaceRec* FT_Incremental_Interface; + + + /*************************************************************************** + * + * @constant: + * FT_PARAM_TAG_INCREMENTAL + * + * @description: + * A constant used as the tag of @FT_Parameter structures to indicate + * an incremental loading object to be used by FreeType. + * + */ +#define FT_PARAM_TAG_INCREMENTAL FT_MAKE_TAG( 'i', 'n', 'c', 'r' ) + + /* */ + +FT_END_HEADER + +#endif /* __FTINCREM_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/ftlcdfil.h b/mod/pub.mod/freetype.mod/include/freetype/ftlcdfil.h new file mode 100644 index 0000000..c6201b3 --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/ftlcdfil.h @@ -0,0 +1,172 @@ +/***************************************************************************/ +/* */ +/* ftlcdfil.h */ +/* */ +/* FreeType API for color filtering of subpixel bitmap glyphs */ +/* (specification). */ +/* */ +/* Copyright 2006, 2007, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FT_LCD_FILTER_H__ +#define __FT_LCD_FILTER_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + /*************************************************************************** + * + * @section: + * lcd_filtering + * + * @title: + * LCD Filtering + * + * @abstract: + * Reduce color fringes of LCD-optimized bitmaps. + * + * @description: + * The @FT_Library_SetLcdFilter API can be used to specify a low-pass + * filter which is then applied to LCD-optimized bitmaps generated + * through @FT_Render_Glyph. This is useful to reduce color fringes + * which would occur with unfiltered rendering. + * + * Note that no filter is active by default, and that this function is + * *not* implemented in default builds of the library. You need to + * #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING in your `ftoption.h' file + * in order to activate it. + */ + + + /**************************************************************************** + * + * @func: + * FT_LcdFilter + * + * @description: + * A list of values to identify various types of LCD filters. + * + * @values: + * FT_LCD_FILTER_NONE :: + * Do not perform filtering. When used with subpixel rendering, this + * results in sometimes severe color fringes. + * + * FT_LCD_FILTER_DEFAULT :: + * The default filter reduces color fringes considerably, at the cost + * of a slight blurriness in the output. + * + * FT_LCD_FILTER_LIGHT :: + * The light filter is a variant that produces less blurriness at the + * cost of slightly more color fringes than the default one. It might + * be better, depending on taste, your monitor, or your personal vision. + * + * FT_LCD_FILTER_LEGACY :: + * This filter corresponds to the original libXft color filter. It + * provides high contrast output but can exhibit really bad color + * fringes if glyphs are not extremely well hinted to the pixel grid. + * In other words, it only works well if the TrueType bytecode + * interpreter is enabled *and* high-quality hinted fonts are used. + * + * This filter is only provided for comparison purposes, and might be + * disabled or stay unsupported in the future. + * + * @since: + * 2.3.0 + */ + typedef enum FT_LcdFilter_ + { + FT_LCD_FILTER_NONE = 0, + FT_LCD_FILTER_DEFAULT = 1, + FT_LCD_FILTER_LIGHT = 2, + FT_LCD_FILTER_LEGACY = 16, + + FT_LCD_FILTER_MAX /* do not remove */ + + } FT_LcdFilter; + + + /************************************************************************** + * + * @func: + * FT_Library_SetLcdFilter + * + * @description: + * This function is used to apply color filtering to LCD decimated + * bitmaps, like the ones used when calling @FT_Render_Glyph with + * @FT_RENDER_MODE_LCD or @FT_RENDER_MODE_LCD_V. + * + * @input: + * library :: + * A handle to the target library instance. + * + * filter :: + * The filter type. + * + * You can use @FT_LCD_FILTER_NONE here to disable this feature, or + * @FT_LCD_FILTER_DEFAULT to use a default filter that should work + * well on most LCD screens. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This feature is always disabled by default. Clients must make an + * explicit call to this function with a `filter' value other than + * @FT_LCD_FILTER_NONE in order to enable it. + * + * Due to *PATENTS* covering subpixel rendering, this function doesn't + * do anything except returning `FT_Err_Unimplemented_Feature' if the + * configuration macro FT_CONFIG_OPTION_SUBPIXEL_RENDERING is not + * defined in your build of the library, which should correspond to all + * default builds of FreeType. + * + * The filter affects glyph bitmaps rendered through @FT_Render_Glyph, + * @FT_Outline_Get_Bitmap, @FT_Load_Glyph, and @FT_Load_Char. + * + * It does _not_ affect the output of @FT_Outline_Render and + * @FT_Outline_Get_Bitmap. + * + * If this feature is activated, the dimensions of LCD glyph bitmaps are + * either larger or taller than the dimensions of the corresponding + * outline with regards to the pixel grid. For example, for + * @FT_RENDER_MODE_LCD, the filter adds up to 3~pixels to the left, and + * up to 3~pixels to the right. + * + * The bitmap offset values are adjusted correctly, so clients shouldn't + * need to modify their layout and glyph positioning code when enabling + * the filter. + * + * @since: + * 2.3.0 + */ + FT_EXPORT( FT_Error ) + FT_Library_SetLcdFilter( FT_Library library, + FT_LcdFilter filter ); + + /* */ + + +FT_END_HEADER + +#endif /* __FT_LCD_FILTER_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/ftlist.h b/mod/pub.mod/freetype.mod/include/freetype/ftlist.h new file mode 100644 index 0000000..93b05fc --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/ftlist.h @@ -0,0 +1,273 @@ +/***************************************************************************/ +/* */ +/* ftlist.h */ +/* */ +/* Generic list support for FreeType (specification). */ +/* */ +/* Copyright 1996-2001, 2003, 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file implements functions relative to list processing. Its */ + /* data structures are defined in `freetype.h'. */ + /* */ + /*************************************************************************/ + + +#ifndef __FTLIST_H__ +#define __FTLIST_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* list_processing */ + /* */ + /* <Title> */ + /* List Processing */ + /* */ + /* <Abstract> */ + /* Simple management of lists. */ + /* */ + /* <Description> */ + /* This section contains various definitions related to list */ + /* processing using doubly-linked nodes. */ + /* */ + /* <Order> */ + /* FT_List */ + /* FT_ListNode */ + /* FT_ListRec */ + /* FT_ListNodeRec */ + /* */ + /* FT_List_Add */ + /* FT_List_Insert */ + /* FT_List_Find */ + /* FT_List_Remove */ + /* FT_List_Up */ + /* FT_List_Iterate */ + /* FT_List_Iterator */ + /* FT_List_Finalize */ + /* FT_List_Destructor */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_List_Find */ + /* */ + /* <Description> */ + /* Find the list node for a given listed object. */ + /* */ + /* <Input> */ + /* list :: A pointer to the parent list. */ + /* data :: The address of the listed object. */ + /* */ + /* <Return> */ + /* List node. NULL if it wasn't found. */ + /* */ + FT_EXPORT( FT_ListNode ) + FT_List_Find( FT_List list, + void* data ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_List_Add */ + /* */ + /* <Description> */ + /* Append an element to the end of a list. */ + /* */ + /* <InOut> */ + /* list :: A pointer to the parent list. */ + /* node :: The node to append. */ + /* */ + FT_EXPORT( void ) + FT_List_Add( FT_List list, + FT_ListNode node ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_List_Insert */ + /* */ + /* <Description> */ + /* Insert an element at the head of a list. */ + /* */ + /* <InOut> */ + /* list :: A pointer to parent list. */ + /* node :: The node to insert. */ + /* */ + FT_EXPORT( void ) + FT_List_Insert( FT_List list, + FT_ListNode node ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_List_Remove */ + /* */ + /* <Description> */ + /* Remove a node from a list. This function doesn't check whether */ + /* the node is in the list! */ + /* */ + /* <Input> */ + /* node :: The node to remove. */ + /* */ + /* <InOut> */ + /* list :: A pointer to the parent list. */ + /* */ + FT_EXPORT( void ) + FT_List_Remove( FT_List list, + FT_ListNode node ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_List_Up */ + /* */ + /* <Description> */ + /* Move a node to the head/top of a list. Used to maintain LRU */ + /* lists. */ + /* */ + /* <InOut> */ + /* list :: A pointer to the parent list. */ + /* node :: The node to move. */ + /* */ + FT_EXPORT( void ) + FT_List_Up( FT_List list, + FT_ListNode node ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_List_Iterator */ + /* */ + /* <Description> */ + /* An FT_List iterator function which is called during a list parse */ + /* by @FT_List_Iterate. */ + /* */ + /* <Input> */ + /* node :: The current iteration list node. */ + /* */ + /* user :: A typeless pointer passed to @FT_List_Iterate. */ + /* Can be used to point to the iteration's state. */ + /* */ + typedef FT_Error + (*FT_List_Iterator)( FT_ListNode node, + void* user ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_List_Iterate */ + /* */ + /* <Description> */ + /* Parse a list and calls a given iterator function on each element. */ + /* Note that parsing is stopped as soon as one of the iterator calls */ + /* returns a non-zero value. */ + /* */ + /* <Input> */ + /* list :: A handle to the list. */ + /* iterator :: An iterator function, called on each node of the list. */ + /* user :: A user-supplied field which is passed as the second */ + /* argument to the iterator. */ + /* */ + /* <Return> */ + /* The result (a FreeType error code) of the last iterator call. */ + /* */ + FT_EXPORT( FT_Error ) + FT_List_Iterate( FT_List list, + FT_List_Iterator iterator, + void* user ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_List_Destructor */ + /* */ + /* <Description> */ + /* An @FT_List iterator function which is called during a list */ + /* finalization by @FT_List_Finalize to destroy all elements in a */ + /* given list. */ + /* */ + /* <Input> */ + /* system :: The current system object. */ + /* */ + /* data :: The current object to destroy. */ + /* */ + /* user :: A typeless pointer passed to @FT_List_Iterate. It can */ + /* be used to point to the iteration's state. */ + /* */ + typedef void + (*FT_List_Destructor)( FT_Memory memory, + void* data, + void* user ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_List_Finalize */ + /* */ + /* <Description> */ + /* Destroy all elements in the list as well as the list itself. */ + /* */ + /* <Input> */ + /* list :: A handle to the list. */ + /* */ + /* destroy :: A list destructor that will be applied to each element */ + /* of the list. */ + /* */ + /* memory :: The current memory object which handles deallocation. */ + /* */ + /* user :: A user-supplied field which is passed as the last */ + /* argument to the destructor. */ + /* */ + FT_EXPORT( void ) + FT_List_Finalize( FT_List list, + FT_List_Destructor destroy, + FT_Memory memory, + void* user ); + + + /* */ + + +FT_END_HEADER + +#endif /* __FTLIST_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/ftlzw.h b/mod/pub.mod/freetype.mod/include/freetype/ftlzw.h new file mode 100644 index 0000000..00d4016 --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/ftlzw.h @@ -0,0 +1,99 @@ +/***************************************************************************/ +/* */ +/* ftlzw.h */ +/* */ +/* LZW-compressed stream support. */ +/* */ +/* Copyright 2004, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTLZW_H__ +#define __FTLZW_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + /*************************************************************************/ + /* */ + /* <Section> */ + /* lzw */ + /* */ + /* <Title> */ + /* LZW Streams */ + /* */ + /* <Abstract> */ + /* Using LZW-compressed font files. */ + /* */ + /* <Description> */ + /* This section contains the declaration of LZW-specific functions. */ + /* */ + /*************************************************************************/ + + /************************************************************************ + * + * @function: + * FT_Stream_OpenLZW + * + * @description: + * Open a new stream to parse LZW-compressed font files. This is + * mainly used to support the compressed `*.pcf.Z' fonts that come + * with XFree86. + * + * @input: + * stream :: The target embedding stream. + * + * source :: The source stream. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The source stream must be opened _before_ calling this function. + * + * Calling the internal function `FT_Stream_Close' on the new stream will + * *not* call `FT_Stream_Close' on the source stream. None of the stream + * objects will be released to the heap. + * + * The stream implementation is very basic and resets the decompression + * process each time seeking backwards is needed within the stream + * + * In certain builds of the library, LZW compression recognition is + * automatically handled when calling @FT_New_Face or @FT_Open_Face. + * This means that if no font driver is capable of handling the raw + * compressed file, the library will try to open a LZW stream from it + * and re-open the face with it. + * + * This function may return `FT_Err_Unimplemented_Feature' if your build + * of FreeType was not compiled with LZW support. + */ + FT_EXPORT( FT_Error ) + FT_Stream_OpenLZW( FT_Stream stream, + FT_Stream source ); + + /* */ + + +FT_END_HEADER + +#endif /* __FTLZW_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/ftmac.h b/mod/pub.mod/freetype.mod/include/freetype/ftmac.h new file mode 100644 index 0000000..ab5bab5 --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/ftmac.h @@ -0,0 +1,274 @@ +/***************************************************************************/ +/* */ +/* ftmac.h */ +/* */ +/* Additional Mac-specific API. */ +/* */ +/* Copyright 1996-2001, 2004, 2006, 2007 by */ +/* Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +/***************************************************************************/ +/* */ +/* NOTE: Include this file after <freetype/freetype.h> and after any */ +/* Mac-specific headers (because this header uses Mac types such as */ +/* Handle, FSSpec, FSRef, etc.) */ +/* */ +/***************************************************************************/ + + +#ifndef __FTMAC_H__ +#define __FTMAC_H__ + + +#include <ft2build.h> + + +FT_BEGIN_HEADER + + +/* gcc-3.4.1 and later can warn about functions tagged as deprecated */ +#ifndef FT_DEPRECATED_ATTRIBUTE +#if defined(__GNUC__) && \ + ((__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1))) +#define FT_DEPRECATED_ATTRIBUTE __attribute__((deprecated)) +#else +#define FT_DEPRECATED_ATTRIBUTE +#endif +#endif + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* mac_specific */ + /* */ + /* <Title> */ + /* Mac Specific Interface */ + /* */ + /* <Abstract> */ + /* Only available on the Macintosh. */ + /* */ + /* <Description> */ + /* The following definitions are only available if FreeType is */ + /* compiled on a Macintosh. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_Face_From_FOND */ + /* */ + /* <Description> */ + /* Create a new face object from a FOND resource. */ + /* */ + /* <InOut> */ + /* library :: A handle to the library resource. */ + /* */ + /* <Input> */ + /* fond :: A FOND resource. */ + /* */ + /* face_index :: Only supported for the -1 `sanity check' special */ + /* case. */ + /* */ + /* <Output> */ + /* aface :: A handle to a new face object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Notes> */ + /* This function can be used to create @FT_Face objects from fonts */ + /* that are installed in the system as follows. */ + /* */ + /* { */ + /* fond = GetResource( 'FOND', fontName ); */ + /* error = FT_New_Face_From_FOND( library, fond, 0, &face ); */ + /* } */ + /* */ + FT_EXPORT( FT_Error ) + FT_New_Face_From_FOND( FT_Library library, + Handle fond, + FT_Long face_index, + FT_Face *aface ) + FT_DEPRECATED_ATTRIBUTE; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_GetFile_From_Mac_Name */ + /* */ + /* <Description> */ + /* Return an FSSpec for the disk file containing the named font. */ + /* */ + /* <Input> */ + /* fontName :: Mac OS name of the font (e.g., Times New Roman */ + /* Bold). */ + /* */ + /* <Output> */ + /* pathSpec :: FSSpec to the file. For passing to */ + /* @FT_New_Face_From_FSSpec. */ + /* */ + /* face_index :: Index of the face. For passing to */ + /* @FT_New_Face_From_FSSpec. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_GetFile_From_Mac_Name( const char* fontName, + FSSpec* pathSpec, + FT_Long* face_index ) + FT_DEPRECATED_ATTRIBUTE; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_GetFile_From_Mac_ATS_Name */ + /* */ + /* <Description> */ + /* Return an FSSpec for the disk file containing the named font. */ + /* */ + /* <Input> */ + /* fontName :: Mac OS name of the font in ATS framework. */ + /* */ + /* <Output> */ + /* pathSpec :: FSSpec to the file. For passing to */ + /* @FT_New_Face_From_FSSpec. */ + /* */ + /* face_index :: Index of the face. For passing to */ + /* @FT_New_Face_From_FSSpec. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_GetFile_From_Mac_ATS_Name( const char* fontName, + FSSpec* pathSpec, + FT_Long* face_index ) + FT_DEPRECATED_ATTRIBUTE; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_GetFilePath_From_Mac_ATS_Name */ + /* */ + /* <Description> */ + /* Return a pathname of the disk file and face index for given font */ + /* name which is handled by ATS framework. */ + /* */ + /* <Input> */ + /* fontName :: Mac OS name of the font in ATS framework. */ + /* */ + /* <Output> */ + /* path :: Buffer to store pathname of the file. For passing */ + /* to @FT_New_Face. The client must allocate this */ + /* buffer before calling this function. */ + /* */ + /* maxPathSize :: Lengths of the buffer `path' that client allocated. */ + /* */ + /* face_index :: Index of the face. For passing to @FT_New_Face. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_GetFilePath_From_Mac_ATS_Name( const char* fontName, + UInt8* path, + UInt32 maxPathSize, + FT_Long* face_index ) + FT_DEPRECATED_ATTRIBUTE; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_Face_From_FSSpec */ + /* */ + /* <Description> */ + /* Create a new face object from a given resource and typeface index */ + /* using an FSSpec to the font file. */ + /* */ + /* <InOut> */ + /* library :: A handle to the library resource. */ + /* */ + /* <Input> */ + /* spec :: FSSpec to the font file. */ + /* */ + /* face_index :: The index of the face within the resource. The */ + /* first face has index~0. */ + /* <Output> */ + /* aface :: A handle to a new face object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* @FT_New_Face_From_FSSpec is identical to @FT_New_Face except */ + /* it accepts an FSSpec instead of a path. */ + /* */ + FT_EXPORT( FT_Error ) + FT_New_Face_From_FSSpec( FT_Library library, + const FSSpec *spec, + FT_Long face_index, + FT_Face *aface ) + FT_DEPRECATED_ATTRIBUTE; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_Face_From_FSRef */ + /* */ + /* <Description> */ + /* Create a new face object from a given resource and typeface index */ + /* using an FSRef to the font file. */ + /* */ + /* <InOut> */ + /* library :: A handle to the library resource. */ + /* */ + /* <Input> */ + /* spec :: FSRef to the font file. */ + /* */ + /* face_index :: The index of the face within the resource. The */ + /* first face has index~0. */ + /* <Output> */ + /* aface :: A handle to a new face object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* @FT_New_Face_From_FSRef is identical to @FT_New_Face except */ + /* it accepts an FSRef instead of a path. */ + /* */ + FT_EXPORT( FT_Error ) + FT_New_Face_From_FSRef( FT_Library library, + const FSRef *ref, + FT_Long face_index, + FT_Face *aface ) + FT_DEPRECATED_ATTRIBUTE; + + /* */ + + +FT_END_HEADER + + +#endif /* __FTMAC_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/ftmm.h b/mod/pub.mod/freetype.mod/include/freetype/ftmm.h new file mode 100644 index 0000000..3aefb9e --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/ftmm.h @@ -0,0 +1,378 @@ +/***************************************************************************/ +/* */ +/* ftmm.h */ +/* */ +/* FreeType Multiple Master font interface (specification). */ +/* */ +/* Copyright 1996-2001, 2003, 2004, 2006, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTMM_H__ +#define __FTMM_H__ + + +#include <ft2build.h> +#include FT_TYPE1_TABLES_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* multiple_masters */ + /* */ + /* <Title> */ + /* Multiple Masters */ + /* */ + /* <Abstract> */ + /* How to manage Multiple Masters fonts. */ + /* */ + /* <Description> */ + /* The following types and functions are used to manage Multiple */ + /* Master fonts, i.e., the selection of specific design instances by */ + /* setting design axis coordinates. */ + /* */ + /* George Williams has extended this interface to make it work with */ + /* both Type~1 Multiple Masters fonts and GX distortable (var) */ + /* fonts. Some of these routines only work with MM fonts, others */ + /* will work with both types. They are similar enough that a */ + /* consistent interface makes sense. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_MM_Axis */ + /* */ + /* <Description> */ + /* A simple structure used to model a given axis in design space for */ + /* Multiple Masters fonts. */ + /* */ + /* This structure can't be used for GX var fonts. */ + /* */ + /* <Fields> */ + /* name :: The axis's name. */ + /* */ + /* minimum :: The axis's minimum design coordinate. */ + /* */ + /* maximum :: The axis's maximum design coordinate. */ + /* */ + typedef struct FT_MM_Axis_ + { + FT_String* name; + FT_Long minimum; + FT_Long maximum; + + } FT_MM_Axis; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Multi_Master */ + /* */ + /* <Description> */ + /* A structure used to model the axes and space of a Multiple Masters */ + /* font. */ + /* */ + /* This structure can't be used for GX var fonts. */ + /* */ + /* <Fields> */ + /* num_axis :: Number of axes. Cannot exceed~4. */ + /* */ + /* num_designs :: Number of designs; should be normally 2^num_axis */ + /* even though the Type~1 specification strangely */ + /* allows for intermediate designs to be present. This */ + /* number cannot exceed~16. */ + /* */ + /* axis :: A table of axis descriptors. */ + /* */ + typedef struct FT_Multi_Master_ + { + FT_UInt num_axis; + FT_UInt num_designs; + FT_MM_Axis axis[T1_MAX_MM_AXIS]; + + } FT_Multi_Master; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Var_Axis */ + /* */ + /* <Description> */ + /* A simple structure used to model a given axis in design space for */ + /* Multiple Masters and GX var fonts. */ + /* */ + /* <Fields> */ + /* name :: The axis's name. */ + /* Not always meaningful for GX. */ + /* */ + /* minimum :: The axis's minimum design coordinate. */ + /* */ + /* def :: The axis's default design coordinate. */ + /* FreeType computes meaningful default values for MM; it */ + /* is then an integer value, not in 16.16 format. */ + /* */ + /* maximum :: The axis's maximum design coordinate. */ + /* */ + /* tag :: The axis's tag (the GX equivalent to `name'). */ + /* FreeType provides default values for MM if possible. */ + /* */ + /* strid :: The entry in `name' table (another GX version of */ + /* `name'). */ + /* Not meaningful for MM. */ + /* */ + typedef struct FT_Var_Axis_ + { + FT_String* name; + + FT_Fixed minimum; + FT_Fixed def; + FT_Fixed maximum; + + FT_ULong tag; + FT_UInt strid; + + } FT_Var_Axis; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Var_Named_Style */ + /* */ + /* <Description> */ + /* A simple structure used to model a named style in a GX var font. */ + /* */ + /* This structure can't be used for MM fonts. */ + /* */ + /* <Fields> */ + /* coords :: The design coordinates for this style. */ + /* This is an array with one entry for each axis. */ + /* */ + /* strid :: The entry in `name' table identifying this style. */ + /* */ + typedef struct FT_Var_Named_Style_ + { + FT_Fixed* coords; + FT_UInt strid; + + } FT_Var_Named_Style; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_MM_Var */ + /* */ + /* <Description> */ + /* A structure used to model the axes and space of a Multiple Masters */ + /* or GX var distortable font. */ + /* */ + /* Some fields are specific to one format and not to the other. */ + /* */ + /* <Fields> */ + /* num_axis :: The number of axes. The maximum value is~4 for */ + /* MM; no limit in GX. */ + /* */ + /* num_designs :: The number of designs; should be normally */ + /* 2^num_axis for MM fonts. Not meaningful for GX */ + /* (where every glyph could have a different */ + /* number of designs). */ + /* */ + /* num_namedstyles :: The number of named styles; only meaningful for */ + /* GX which allows certain design coordinates to */ + /* have a string ID (in the `name' table) */ + /* associated with them. The font can tell the */ + /* user that, for example, Weight=1.5 is `Bold'. */ + /* */ + /* axis :: A table of axis descriptors. */ + /* GX fonts contain slightly more data than MM. */ + /* */ + /* namedstyles :: A table of named styles. */ + /* Only meaningful with GX. */ + /* */ + typedef struct FT_MM_Var_ + { + FT_UInt num_axis; + FT_UInt num_designs; + FT_UInt num_namedstyles; + FT_Var_Axis* axis; + FT_Var_Named_Style* namedstyle; + + } FT_MM_Var; + + + /* */ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Multi_Master */ + /* */ + /* <Description> */ + /* Retrieve the Multiple Master descriptor of a given font. */ + /* */ + /* This function can't be used with GX fonts. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face. */ + /* */ + /* <Output> */ + /* amaster :: The Multiple Masters descriptor. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Multi_Master( FT_Face face, + FT_Multi_Master *amaster ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_MM_Var */ + /* */ + /* <Description> */ + /* Retrieve the Multiple Master/GX var descriptor of a given font. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face. */ + /* */ + /* <Output> */ + /* amaster :: The Multiple Masters/GX var descriptor. */ + /* Allocates a data structure, which the user must free */ + /* (a single call to FT_FREE will do it). */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_MM_Var( FT_Face face, + FT_MM_Var* *amaster ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_MM_Design_Coordinates */ + /* */ + /* <Description> */ + /* For Multiple Masters fonts, choose an interpolated font design */ + /* through design coordinates. */ + /* */ + /* This function can't be used with GX fonts. */ + /* */ + /* <InOut> */ + /* face :: A handle to the source face. */ + /* */ + /* <Input> */ + /* num_coords :: The number of design coordinates (must be equal to */ + /* the number of axes in the font). */ + /* */ + /* coords :: An array of design coordinates. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Set_MM_Design_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Long* coords ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_Var_Design_Coordinates */ + /* */ + /* <Description> */ + /* For Multiple Master or GX Var fonts, choose an interpolated font */ + /* design through design coordinates. */ + /* */ + /* <InOut> */ + /* face :: A handle to the source face. */ + /* */ + /* <Input> */ + /* num_coords :: The number of design coordinates (must be equal to */ + /* the number of axes in the font). */ + /* */ + /* coords :: An array of design coordinates. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Set_Var_Design_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_MM_Blend_Coordinates */ + /* */ + /* <Description> */ + /* For Multiple Masters and GX var fonts, choose an interpolated font */ + /* design through normalized blend coordinates. */ + /* */ + /* <InOut> */ + /* face :: A handle to the source face. */ + /* */ + /* <Input> */ + /* num_coords :: The number of design coordinates (must be equal to */ + /* the number of axes in the font). */ + /* */ + /* coords :: The design coordinates array (each element must be */ + /* between 0 and 1.0). */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Set_MM_Blend_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_Var_Blend_Coordinates */ + /* */ + /* <Description> */ + /* This is another name of @FT_Set_MM_Blend_Coordinates. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Set_Var_Blend_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); + + + /* */ + + +FT_END_HEADER + +#endif /* __FTMM_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/ftmodapi.h b/mod/pub.mod/freetype.mod/include/freetype/ftmodapi.h new file mode 100644 index 0000000..3c9b876 --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/ftmodapi.h @@ -0,0 +1,445 @@ +/***************************************************************************/ +/* */ +/* ftmodapi.h */ +/* */ +/* FreeType modules public interface (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2006, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTMODAPI_H__ +#define __FTMODAPI_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* module_management */ + /* */ + /* <Title> */ + /* Module Management */ + /* */ + /* <Abstract> */ + /* How to add, upgrade, and remove modules from FreeType. */ + /* */ + /* <Description> */ + /* The definitions below are used to manage modules within FreeType. */ + /* Modules can be added, upgraded, and removed at runtime. */ + /* */ + /*************************************************************************/ + + + /* module bit flags */ +#define FT_MODULE_FONT_DRIVER 1 /* this module is a font driver */ +#define FT_MODULE_RENDERER 2 /* this module is a renderer */ +#define FT_MODULE_HINTER 4 /* this module is a glyph hinter */ +#define FT_MODULE_STYLER 8 /* this module is a styler */ + +#define FT_MODULE_DRIVER_SCALABLE 0x100 /* the driver supports */ + /* scalable fonts */ +#define FT_MODULE_DRIVER_NO_OUTLINES 0x200 /* the driver does not */ + /* support vector outlines */ +#define FT_MODULE_DRIVER_HAS_HINTER 0x400 /* the driver provides its */ + /* own hinter */ + + + /* deprecated values */ +#define ft_module_font_driver FT_MODULE_FONT_DRIVER +#define ft_module_renderer FT_MODULE_RENDERER +#define ft_module_hinter FT_MODULE_HINTER +#define ft_module_styler FT_MODULE_STYLER + +#define ft_module_driver_scalable FT_MODULE_DRIVER_SCALABLE +#define ft_module_driver_no_outlines FT_MODULE_DRIVER_NO_OUTLINES +#define ft_module_driver_has_hinter FT_MODULE_DRIVER_HAS_HINTER + + + typedef FT_Pointer FT_Module_Interface; + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Module_Constructor */ + /* */ + /* <Description> */ + /* A function used to initialize (not create) a new module object. */ + /* */ + /* <Input> */ + /* module :: The module to initialize. */ + /* */ + typedef FT_Error + (*FT_Module_Constructor)( FT_Module module ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Module_Destructor */ + /* */ + /* <Description> */ + /* A function used to finalize (not destroy) a given module object. */ + /* */ + /* <Input> */ + /* module :: The module to finalize. */ + /* */ + typedef void + (*FT_Module_Destructor)( FT_Module module ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Module_Requester */ + /* */ + /* <Description> */ + /* A function used to query a given module for a specific interface. */ + /* */ + /* <Input> */ + /* module :: The module to finalize. */ + /* */ + /* name :: The name of the interface in the module. */ + /* */ + typedef FT_Module_Interface + (*FT_Module_Requester)( FT_Module module, + const char* name ); + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Module_Class */ + /* */ + /* <Description> */ + /* The module class descriptor. */ + /* */ + /* <Fields> */ + /* module_flags :: Bit flags describing the module. */ + /* */ + /* module_size :: The size of one module object/instance in */ + /* bytes. */ + /* */ + /* module_name :: The name of the module. */ + /* */ + /* module_version :: The version, as a 16.16 fixed number */ + /* (major.minor). */ + /* */ + /* module_requires :: The version of FreeType this module requires, */ + /* as a 16.16 fixed number (major.minor). Starts */ + /* at version 2.0, i.e., 0x20000. */ + /* */ + /* module_init :: The initializing function. */ + /* */ + /* module_done :: The finalizing function. */ + /* */ + /* get_interface :: The interface requesting function. */ + /* */ + typedef struct FT_Module_Class_ + { + FT_ULong module_flags; + FT_Long module_size; + const FT_String* module_name; + FT_Fixed module_version; + FT_Fixed module_requires; + + const void* module_interface; + + FT_Module_Constructor module_init; + FT_Module_Destructor module_done; + FT_Module_Requester get_interface; + + } FT_Module_Class; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Add_Module */ + /* */ + /* <Description> */ + /* Add a new module to a given library instance. */ + /* */ + /* <InOut> */ + /* library :: A handle to the library object. */ + /* */ + /* <Input> */ + /* clazz :: A pointer to class descriptor for the module. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* An error will be returned if a module already exists by that name, */ + /* or if the module requires a version of FreeType that is too great. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Add_Module( FT_Library library, + const FT_Module_Class* clazz ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Module */ + /* */ + /* <Description> */ + /* Find a module by its name. */ + /* */ + /* <Input> */ + /* library :: A handle to the library object. */ + /* */ + /* module_name :: The module's name (as an ASCII string). */ + /* */ + /* <Return> */ + /* A module handle. 0~if none was found. */ + /* */ + /* <Note> */ + /* FreeType's internal modules aren't documented very well, and you */ + /* should look up the source code for details. */ + /* */ + FT_EXPORT( FT_Module ) + FT_Get_Module( FT_Library library, + const char* module_name ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Remove_Module */ + /* */ + /* <Description> */ + /* Remove a given module from a library instance. */ + /* */ + /* <InOut> */ + /* library :: A handle to a library object. */ + /* */ + /* <Input> */ + /* module :: A handle to a module object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The module object is destroyed by the function in case of success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Remove_Module( FT_Library library, + FT_Module module ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_Library */ + /* */ + /* <Description> */ + /* This function is used to create a new FreeType library instance */ + /* from a given memory object. It is thus possible to use libraries */ + /* with distinct memory allocators within the same program. */ + /* */ + /* Normally, you would call this function (followed by a call to */ + /* @FT_Add_Default_Modules or a series of calls to @FT_Add_Module) */ + /* instead of @FT_Init_FreeType to initialize the FreeType library. */ + /* */ + /* <Input> */ + /* memory :: A handle to the original memory object. */ + /* */ + /* <Output> */ + /* alibrary :: A pointer to handle of a new library object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_New_Library( FT_Memory memory, + FT_Library *alibrary ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Done_Library */ + /* */ + /* <Description> */ + /* Discard a given library object. This closes all drivers and */ + /* discards all resource objects. */ + /* */ + /* <Input> */ + /* library :: A handle to the target library. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Done_Library( FT_Library library ); + +/* */ + + typedef void + (*FT_DebugHook_Func)( void* arg ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_Debug_Hook */ + /* */ + /* <Description> */ + /* Set a debug hook function for debugging the interpreter of a font */ + /* format. */ + /* */ + /* <InOut> */ + /* library :: A handle to the library object. */ + /* */ + /* <Input> */ + /* hook_index :: The index of the debug hook. You should use the */ + /* values defined in `ftobjs.h', e.g., */ + /* `FT_DEBUG_HOOK_TRUETYPE'. */ + /* */ + /* debug_hook :: The function used to debug the interpreter. */ + /* */ + /* <Note> */ + /* Currently, four debug hook slots are available, but only two (for */ + /* the TrueType and the Type~1 interpreter) are defined. */ + /* */ + /* Since the internal headers of FreeType are no longer installed, */ + /* the symbol `FT_DEBUG_HOOK_TRUETYPE' isn't available publicly. */ + /* This is a bug and will be fixed in a forthcoming release. */ + /* */ + FT_EXPORT( void ) + FT_Set_Debug_Hook( FT_Library library, + FT_UInt hook_index, + FT_DebugHook_Func debug_hook ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Add_Default_Modules */ + /* */ + /* <Description> */ + /* Add the set of default drivers to a given library object. */ + /* This is only useful when you create a library object with */ + /* @FT_New_Library (usually to plug a custom memory manager). */ + /* */ + /* <InOut> */ + /* library :: A handle to a new library object. */ + /* */ + FT_EXPORT( void ) + FT_Add_Default_Modules( FT_Library library ); + + + + /************************************************************************** + * + * @section: + * truetype_engine + * + * @title: + * The TrueType Engine + * + * @abstract: + * TrueType bytecode support. + * + * @description: + * This section contains a function used to query the level of TrueType + * bytecode support compiled in this version of the library. + * + */ + + + /************************************************************************** + * + * @enum: + * FT_TrueTypeEngineType + * + * @description: + * A list of values describing which kind of TrueType bytecode + * engine is implemented in a given FT_Library instance. It is used + * by the @FT_Get_TrueType_Engine_Type function. + * + * @values: + * FT_TRUETYPE_ENGINE_TYPE_NONE :: + * The library doesn't implement any kind of bytecode interpreter. + * + * FT_TRUETYPE_ENGINE_TYPE_UNPATENTED :: + * The library implements a bytecode interpreter that doesn't + * support the patented operations of the TrueType virtual machine. + * + * Its main use is to load certain Asian fonts which position and + * scale glyph components with bytecode instructions. It produces + * bad output for most other fonts. + * + * FT_TRUETYPE_ENGINE_TYPE_PATENTED :: + * The library implements a bytecode interpreter that covers + * the full instruction set of the TrueType virtual machine. + * See the file `docs/PATENTS' for legal aspects. + * + * @since: + * 2.2 + * + */ + typedef enum FT_TrueTypeEngineType_ + { + FT_TRUETYPE_ENGINE_TYPE_NONE = 0, + FT_TRUETYPE_ENGINE_TYPE_UNPATENTED, + FT_TRUETYPE_ENGINE_TYPE_PATENTED + + } FT_TrueTypeEngineType; + + + /************************************************************************** + * + * @func: + * FT_Get_TrueType_Engine_Type + * + * @description: + * Return an @FT_TrueTypeEngineType value to indicate which level of + * the TrueType virtual machine a given library instance supports. + * + * @input: + * library :: + * A library instance. + * + * @return: + * A value indicating which level is supported. + * + * @since: + * 2.2 + * + */ + FT_EXPORT( FT_TrueTypeEngineType ) + FT_Get_TrueType_Engine_Type( FT_Library library ); + + + /* */ + + +FT_END_HEADER + +#endif /* __FTMODAPI_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/ftmoderr.h b/mod/pub.mod/freetype.mod/include/freetype/ftmoderr.h new file mode 100644 index 0000000..b0115dd --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/ftmoderr.h @@ -0,0 +1,155 @@ +/***************************************************************************/ +/* */ +/* ftmoderr.h */ +/* */ +/* FreeType module error offsets (specification). */ +/* */ +/* Copyright 2001, 2002, 2003, 2004, 2005 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file is used to define the FreeType module error offsets. */ + /* */ + /* The lower byte gives the error code, the higher byte gives the */ + /* module. The base module has error offset 0. For example, the error */ + /* `FT_Err_Invalid_File_Format' has value 0x003, the error */ + /* `TT_Err_Invalid_File_Format' has value 0x1103, the error */ + /* `T1_Err_Invalid_File_Format' has value 0x1203, etc. */ + /* */ + /* Undefine the macro FT_CONFIG_OPTION_USE_MODULE_ERRORS in ftoption.h */ + /* to make the higher byte always zero (disabling the module error */ + /* mechanism). */ + /* */ + /* It can also be used to create a module error message table easily */ + /* with something like */ + /* */ + /* { */ + /* #undef __FTMODERR_H__ */ + /* #define FT_MODERRDEF( e, v, s ) { FT_Mod_Err_ ## e, s }, */ + /* #define FT_MODERR_START_LIST { */ + /* #define FT_MODERR_END_LIST { 0, 0 } }; */ + /* */ + /* const struct */ + /* { */ + /* int mod_err_offset; */ + /* const char* mod_err_msg */ + /* } ft_mod_errors[] = */ + /* */ + /* #include FT_MODULE_ERRORS_H */ + /* } */ + /* */ + /* To use such a table, all errors must be ANDed with 0xFF00 to remove */ + /* the error code. */ + /* */ + /*************************************************************************/ + + +#ifndef __FTMODERR_H__ +#define __FTMODERR_H__ + + + /*******************************************************************/ + /*******************************************************************/ + /***** *****/ + /***** SETUP MACROS *****/ + /***** *****/ + /*******************************************************************/ + /*******************************************************************/ + + +#undef FT_NEED_EXTERN_C + +#ifndef FT_MODERRDEF + +#ifdef FT_CONFIG_OPTION_USE_MODULE_ERRORS +#define FT_MODERRDEF( e, v, s ) FT_Mod_Err_ ## e = v, +#else +#define FT_MODERRDEF( e, v, s ) FT_Mod_Err_ ## e = 0, +#endif + +#define FT_MODERR_START_LIST enum { +#define FT_MODERR_END_LIST FT_Mod_Err_Max }; + +#ifdef __cplusplus +#define FT_NEED_EXTERN_C + extern "C" { +#endif + +#endif /* !FT_MODERRDEF */ + + + /*******************************************************************/ + /*******************************************************************/ + /***** *****/ + /***** LIST MODULE ERROR BASES *****/ + /***** *****/ + /*******************************************************************/ + /*******************************************************************/ + + +#ifdef FT_MODERR_START_LIST + FT_MODERR_START_LIST +#endif + + + FT_MODERRDEF( Base, 0x000, "base module" ) + FT_MODERRDEF( Autofit, 0x100, "autofitter module" ) + FT_MODERRDEF( BDF, 0x200, "BDF module" ) + FT_MODERRDEF( Cache, 0x300, "cache module" ) + FT_MODERRDEF( CFF, 0x400, "CFF module" ) + FT_MODERRDEF( CID, 0x500, "CID module" ) + FT_MODERRDEF( Gzip, 0x600, "Gzip module" ) + FT_MODERRDEF( LZW, 0x700, "LZW module" ) + FT_MODERRDEF( OTvalid, 0x800, "OpenType validation module" ) + FT_MODERRDEF( PCF, 0x900, "PCF module" ) + FT_MODERRDEF( PFR, 0xA00, "PFR module" ) + FT_MODERRDEF( PSaux, 0xB00, "PS auxiliary module" ) + FT_MODERRDEF( PShinter, 0xC00, "PS hinter module" ) + FT_MODERRDEF( PSnames, 0xD00, "PS names module" ) + FT_MODERRDEF( Raster, 0xE00, "raster module" ) + FT_MODERRDEF( SFNT, 0xF00, "SFNT module" ) + FT_MODERRDEF( Smooth, 0x1000, "smooth raster module" ) + FT_MODERRDEF( TrueType, 0x1100, "TrueType module" ) + FT_MODERRDEF( Type1, 0x1200, "Type 1 module" ) + FT_MODERRDEF( Type42, 0x1300, "Type 42 module" ) + FT_MODERRDEF( Winfonts, 0x1400, "Windows FON/FNT module" ) + + +#ifdef FT_MODERR_END_LIST + FT_MODERR_END_LIST +#endif + + + /*******************************************************************/ + /*******************************************************************/ + /***** *****/ + /***** CLEANUP *****/ + /***** *****/ + /*******************************************************************/ + /*******************************************************************/ + + +#ifdef FT_NEED_EXTERN_C + } +#endif + +#undef FT_MODERR_START_LIST +#undef FT_MODERR_END_LIST +#undef FT_MODERRDEF +#undef FT_NEED_EXTERN_C + + +#endif /* __FTMODERR_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/ftotval.h b/mod/pub.mod/freetype.mod/include/freetype/ftotval.h new file mode 100644 index 0000000..027f2e8 --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/ftotval.h @@ -0,0 +1,203 @@ +/***************************************************************************/ +/* */ +/* ftotval.h */ +/* */ +/* FreeType API for validating OpenType tables (specification). */ +/* */ +/* Copyright 2004, 2005, 2006, 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +/***************************************************************************/ +/* */ +/* */ +/* Warning: This module might be moved to a different library in the */ +/* future to avoid a tight dependency between FreeType and the */ +/* OpenType specification. */ +/* */ +/* */ +/***************************************************************************/ + + +#ifndef __FTOTVAL_H__ +#define __FTOTVAL_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* ot_validation */ + /* */ + /* <Title> */ + /* OpenType Validation */ + /* */ + /* <Abstract> */ + /* An API to validate OpenType tables. */ + /* */ + /* <Description> */ + /* This section contains the declaration of functions to validate */ + /* some OpenType tables (BASE, GDEF, GPOS, GSUB, JSTF, MATH). */ + /* */ + /*************************************************************************/ + + + /********************************************************************** + * + * @enum: + * FT_VALIDATE_OTXXX + * + * @description: + * A list of bit-field constants used with @FT_OpenType_Validate to + * indicate which OpenType tables should be validated. + * + * @values: + * FT_VALIDATE_BASE :: + * Validate BASE table. + * + * FT_VALIDATE_GDEF :: + * Validate GDEF table. + * + * FT_VALIDATE_GPOS :: + * Validate GPOS table. + * + * FT_VALIDATE_GSUB :: + * Validate GSUB table. + * + * FT_VALIDATE_JSTF :: + * Validate JSTF table. + * + * FT_VALIDATE_MATH :: + * Validate MATH table. + * + * FT_VALIDATE_OT :: + * Validate all OpenType tables (BASE, GDEF, GPOS, GSUB, JSTF, MATH). + * + */ +#define FT_VALIDATE_BASE 0x0100 +#define FT_VALIDATE_GDEF 0x0200 +#define FT_VALIDATE_GPOS 0x0400 +#define FT_VALIDATE_GSUB 0x0800 +#define FT_VALIDATE_JSTF 0x1000 +#define FT_VALIDATE_MATH 0x2000 + +#define FT_VALIDATE_OT FT_VALIDATE_BASE | \ + FT_VALIDATE_GDEF | \ + FT_VALIDATE_GPOS | \ + FT_VALIDATE_GSUB | \ + FT_VALIDATE_JSTF | \ + FT_VALIDATE_MATH + + /* */ + + /********************************************************************** + * + * @function: + * FT_OpenType_Validate + * + * @description: + * Validate various OpenType tables to assure that all offsets and + * indices are valid. The idea is that a higher-level library which + * actually does the text layout can access those tables without + * error checking (which can be quite time consuming). + * + * @input: + * face :: + * A handle to the input face. + * + * validation_flags :: + * A bit field which specifies the tables to be validated. See + * @FT_VALIDATE_OTXXX for possible values. + * + * @output: + * BASE_table :: + * A pointer to the BASE table. + * + * GDEF_table :: + * A pointer to the GDEF table. + * + * GPOS_table :: + * A pointer to the GPOS table. + * + * GSUB_table :: + * A pointer to the GSUB table. + * + * JSTF_table :: + * A pointer to the JSTF table. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function only works with OpenType fonts, returning an error + * otherwise. + * + * After use, the application should deallocate the five tables with + * @FT_OpenType_Free. A NULL value indicates that the table either + * doesn't exist in the font, or the application hasn't asked for + * validation. + */ + FT_EXPORT( FT_Error ) + FT_OpenType_Validate( FT_Face face, + FT_UInt validation_flags, + FT_Bytes *BASE_table, + FT_Bytes *GDEF_table, + FT_Bytes *GPOS_table, + FT_Bytes *GSUB_table, + FT_Bytes *JSTF_table ); + + /* */ + + /********************************************************************** + * + * @function: + * FT_OpenType_Free + * + * @description: + * Free the buffer allocated by OpenType validator. + * + * @input: + * face :: + * A handle to the input face. + * + * table :: + * The pointer to the buffer that is allocated by + * @FT_OpenType_Validate. + * + * @note: + * This function must be used to free the buffer allocated by + * @FT_OpenType_Validate only. + */ + FT_EXPORT( void ) + FT_OpenType_Free( FT_Face face, + FT_Bytes table ); + + + /* */ + + +FT_END_HEADER + +#endif /* __FTOTVAL_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/ftoutln.h b/mod/pub.mod/freetype.mod/include/freetype/ftoutln.h new file mode 100644 index 0000000..d7d01e8 --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/ftoutln.h @@ -0,0 +1,538 @@ +/***************************************************************************/ +/* */ +/* ftoutln.h */ +/* */ +/* Support for the FT_Outline type used to store glyph shapes of */ +/* most scalable font formats (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2005, 2006, 2007, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTOUTLN_H__ +#define __FTOUTLN_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* outline_processing */ + /* */ + /* <Title> */ + /* Outline Processing */ + /* */ + /* <Abstract> */ + /* Functions to create, transform, and render vectorial glyph images. */ + /* */ + /* <Description> */ + /* This section contains routines used to create and destroy scalable */ + /* glyph images known as `outlines'. These can also be measured, */ + /* transformed, and converted into bitmaps and pixmaps. */ + /* */ + /* <Order> */ + /* FT_Outline */ + /* FT_OUTLINE_FLAGS */ + /* FT_Outline_New */ + /* FT_Outline_Done */ + /* FT_Outline_Copy */ + /* FT_Outline_Translate */ + /* FT_Outline_Transform */ + /* FT_Outline_Embolden */ + /* FT_Outline_Reverse */ + /* FT_Outline_Check */ + /* */ + /* FT_Outline_Get_CBox */ + /* FT_Outline_Get_BBox */ + /* */ + /* FT_Outline_Get_Bitmap */ + /* FT_Outline_Render */ + /* */ + /* FT_Outline_Decompose */ + /* FT_Outline_Funcs */ + /* FT_Outline_MoveTo_Func */ + /* FT_Outline_LineTo_Func */ + /* FT_Outline_ConicTo_Func */ + /* FT_Outline_CubicTo_Func */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Decompose */ + /* */ + /* <Description> */ + /* Walk over an outline's structure to decompose it into individual */ + /* segments and Bézier arcs. This function is also able to emit */ + /* `move to' and `close to' operations to indicate the start and end */ + /* of new contours in the outline. */ + /* */ + /* <Input> */ + /* outline :: A pointer to the source target. */ + /* */ + /* func_interface :: A table of `emitters', i.e., function pointers */ + /* called during decomposition to indicate path */ + /* operations. */ + /* */ + /* <InOut> */ + /* user :: A typeless pointer which is passed to each */ + /* emitter during the decomposition. It can be */ + /* used to store the state during the */ + /* decomposition. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_Decompose( FT_Outline* outline, + const FT_Outline_Funcs* func_interface, + void* user ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_New */ + /* */ + /* <Description> */ + /* Create a new outline of a given size. */ + /* */ + /* <Input> */ + /* library :: A handle to the library object from where the */ + /* outline is allocated. Note however that the new */ + /* outline will *not* necessarily be *freed*, when */ + /* destroying the library, by @FT_Done_FreeType. */ + /* */ + /* numPoints :: The maximal number of points within the outline. */ + /* */ + /* numContours :: The maximal number of contours within the outline. */ + /* */ + /* <Output> */ + /* anoutline :: A handle to the new outline. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The reason why this function takes a `library' parameter is simply */ + /* to use the library's memory allocator. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_New( FT_Library library, + FT_UInt numPoints, + FT_Int numContours, + FT_Outline *anoutline ); + + + FT_EXPORT( FT_Error ) + FT_Outline_New_Internal( FT_Memory memory, + FT_UInt numPoints, + FT_Int numContours, + FT_Outline *anoutline ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Done */ + /* */ + /* <Description> */ + /* Destroy an outline created with @FT_Outline_New. */ + /* */ + /* <Input> */ + /* library :: A handle of the library object used to allocate the */ + /* outline. */ + /* */ + /* outline :: A pointer to the outline object to be discarded. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* If the outline's `owner' field is not set, only the outline */ + /* descriptor will be released. */ + /* */ + /* The reason why this function takes an `library' parameter is */ + /* simply to use ft_mem_free(). */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_Done( FT_Library library, + FT_Outline* outline ); + + + FT_EXPORT( FT_Error ) + FT_Outline_Done_Internal( FT_Memory memory, + FT_Outline* outline ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Check */ + /* */ + /* <Description> */ + /* Check the contents of an outline descriptor. */ + /* */ + /* <Input> */ + /* outline :: A handle to a source outline. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_Check( FT_Outline* outline ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Get_CBox */ + /* */ + /* <Description> */ + /* Return an outline's `control box'. The control box encloses all */ + /* the outline's points, including Bézier control points. Though it */ + /* coincides with the exact bounding box for most glyphs, it can be */ + /* slightly larger in some situations (like when rotating an outline */ + /* which contains Bézier outside arcs). */ + /* */ + /* Computing the control box is very fast, while getting the bounding */ + /* box can take much more time as it needs to walk over all segments */ + /* and arcs in the outline. To get the latter, you can use the */ + /* `ftbbox' component which is dedicated to this single task. */ + /* */ + /* <Input> */ + /* outline :: A pointer to the source outline descriptor. */ + /* */ + /* <Output> */ + /* acbox :: The outline's control box. */ + /* */ + FT_EXPORT( void ) + FT_Outline_Get_CBox( const FT_Outline* outline, + FT_BBox *acbox ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Translate */ + /* */ + /* <Description> */ + /* Apply a simple translation to the points of an outline. */ + /* */ + /* <InOut> */ + /* outline :: A pointer to the target outline descriptor. */ + /* */ + /* <Input> */ + /* xOffset :: The horizontal offset. */ + /* */ + /* yOffset :: The vertical offset. */ + /* */ + FT_EXPORT( void ) + FT_Outline_Translate( const FT_Outline* outline, + FT_Pos xOffset, + FT_Pos yOffset ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Copy */ + /* */ + /* <Description> */ + /* Copy an outline into another one. Both objects must have the */ + /* same sizes (number of points & number of contours) when this */ + /* function is called. */ + /* */ + /* <Input> */ + /* source :: A handle to the source outline. */ + /* */ + /* <Output> */ + /* target :: A handle to the target outline. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_Copy( const FT_Outline* source, + FT_Outline *target ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Transform */ + /* */ + /* <Description> */ + /* Apply a simple 2x2 matrix to all of an outline's points. Useful */ + /* for applying rotations, slanting, flipping, etc. */ + /* */ + /* <InOut> */ + /* outline :: A pointer to the target outline descriptor. */ + /* */ + /* <Input> */ + /* matrix :: A pointer to the transformation matrix. */ + /* */ + /* <Note> */ + /* You can use @FT_Outline_Translate if you need to translate the */ + /* outline's points. */ + /* */ + FT_EXPORT( void ) + FT_Outline_Transform( const FT_Outline* outline, + const FT_Matrix* matrix ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Embolden */ + /* */ + /* <Description> */ + /* Embolden an outline. The new outline will be at most 4~times */ + /* `strength' pixels wider and higher. You may think of the left and */ + /* bottom borders as unchanged. */ + /* */ + /* Negative `strength' values to reduce the outline thickness are */ + /* possible also. */ + /* */ + /* <InOut> */ + /* outline :: A handle to the target outline. */ + /* */ + /* <Input> */ + /* strength :: How strong the glyph is emboldened. Expressed in */ + /* 26.6 pixel format. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The used algorithm to increase or decrease the thickness of the */ + /* glyph doesn't change the number of points; this means that certain */ + /* situations like acute angles or intersections are sometimes */ + /* handled incorrectly. */ + /* */ + /* If you need `better' metrics values you should call */ + /* @FT_Outline_Get_CBox ot @FT_Outline_Get_BBox. */ + /* */ + /* Example call: */ + /* */ + /* { */ + /* FT_Load_Glyph( face, index, FT_LOAD_DEFAULT ); */ + /* if ( face->slot->format == FT_GLYPH_FORMAT_OUTLINE ) */ + /* FT_Outline_Embolden( &face->slot->outline, strength ); */ + /* } */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_Embolden( FT_Outline* outline, + FT_Pos strength ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Reverse */ + /* */ + /* <Description> */ + /* Reverse the drawing direction of an outline. This is used to */ + /* ensure consistent fill conventions for mirrored glyphs. */ + /* */ + /* <InOut> */ + /* outline :: A pointer to the target outline descriptor. */ + /* */ + /* <Note> */ + /* This function toggles the bit flag @FT_OUTLINE_REVERSE_FILL in */ + /* the outline's `flags' field. */ + /* */ + /* It shouldn't be used by a normal client application, unless it */ + /* knows what it is doing. */ + /* */ + FT_EXPORT( void ) + FT_Outline_Reverse( FT_Outline* outline ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Get_Bitmap */ + /* */ + /* <Description> */ + /* Render an outline within a bitmap. The outline's image is simply */ + /* OR-ed to the target bitmap. */ + /* */ + /* <Input> */ + /* library :: A handle to a FreeType library object. */ + /* */ + /* outline :: A pointer to the source outline descriptor. */ + /* */ + /* <InOut> */ + /* abitmap :: A pointer to the target bitmap descriptor. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* This function does NOT CREATE the bitmap, it only renders an */ + /* outline image within the one you pass to it! Consequently, the */ + /* various fields in `abitmap' should be set accordingly. */ + /* */ + /* It will use the raster corresponding to the default glyph format. */ + /* */ + /* The value of the `num_grays' field in `abitmap' is ignored. If */ + /* you select the gray-level rasterizer, and you want less than 256 */ + /* gray levels, you have to use @FT_Outline_Render directly. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_Get_Bitmap( FT_Library library, + FT_Outline* outline, + const FT_Bitmap *abitmap ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Render */ + /* */ + /* <Description> */ + /* Render an outline within a bitmap using the current scan-convert. */ + /* This function uses an @FT_Raster_Params structure as an argument, */ + /* allowing advanced features like direct composition, translucency, */ + /* etc. */ + /* */ + /* <Input> */ + /* library :: A handle to a FreeType library object. */ + /* */ + /* outline :: A pointer to the source outline descriptor. */ + /* */ + /* <InOut> */ + /* params :: A pointer to an @FT_Raster_Params structure used to */ + /* describe the rendering operation. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* You should know what you are doing and how @FT_Raster_Params works */ + /* to use this function. */ + /* */ + /* The field `params.source' will be set to `outline' before the scan */ + /* converter is called, which means that the value you give to it is */ + /* actually ignored. */ + /* */ + /* The gray-level rasterizer always uses 256 gray levels. If you */ + /* want less gray levels, you have to provide your own span callback. */ + /* See the @FT_RASTER_FLAG_DIRECT value of the `flags' field in the */ + /* @FT_Raster_Params structure for more details. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_Render( FT_Library library, + FT_Outline* outline, + FT_Raster_Params* params ); + + + /************************************************************************** + * + * @enum: + * FT_Orientation + * + * @description: + * A list of values used to describe an outline's contour orientation. + * + * The TrueType and PostScript specifications use different conventions + * to determine whether outline contours should be filled or unfilled. + * + * @values: + * FT_ORIENTATION_TRUETYPE :: + * According to the TrueType specification, clockwise contours must + * be filled, and counter-clockwise ones must be unfilled. + * + * FT_ORIENTATION_POSTSCRIPT :: + * According to the PostScript specification, counter-clockwise contours + * must be filled, and clockwise ones must be unfilled. + * + * FT_ORIENTATION_FILL_RIGHT :: + * This is identical to @FT_ORIENTATION_TRUETYPE, but is used to + * remember that in TrueType, everything that is to the right of + * the drawing direction of a contour must be filled. + * + * FT_ORIENTATION_FILL_LEFT :: + * This is identical to @FT_ORIENTATION_POSTSCRIPT, but is used to + * remember that in PostScript, everything that is to the left of + * the drawing direction of a contour must be filled. + * + * FT_ORIENTATION_NONE :: + * The orientation cannot be determined. That is, different parts of + * the glyph have different orientation. + * + */ + typedef enum FT_Orientation_ + { + FT_ORIENTATION_TRUETYPE = 0, + FT_ORIENTATION_POSTSCRIPT = 1, + FT_ORIENTATION_FILL_RIGHT = FT_ORIENTATION_TRUETYPE, + FT_ORIENTATION_FILL_LEFT = FT_ORIENTATION_POSTSCRIPT, + FT_ORIENTATION_NONE + + } FT_Orientation; + + + /************************************************************************** + * + * @function: + * FT_Outline_Get_Orientation + * + * @description: + * This function analyzes a glyph outline and tries to compute its + * fill orientation (see @FT_Orientation). This is done by computing + * the direction of each global horizontal and/or vertical extrema + * within the outline. + * + * Note that this will return @FT_ORIENTATION_TRUETYPE for empty + * outlines. + * + * @input: + * outline :: + * A handle to the source outline. + * + * @return: + * The orientation. + * + */ + FT_EXPORT( FT_Orientation ) + FT_Outline_Get_Orientation( FT_Outline* outline ); + + + /* */ + + +FT_END_HEADER + +#endif /* __FTOUTLN_H__ */ + + +/* END */ + + +/* Local Variables: */ +/* coding: utf-8 */ +/* End: */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/ftpfr.h b/mod/pub.mod/freetype.mod/include/freetype/ftpfr.h new file mode 100644 index 0000000..0b7b7d4 --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/ftpfr.h @@ -0,0 +1,172 @@ +/***************************************************************************/ +/* */ +/* ftpfr.h */ +/* */ +/* FreeType API for accessing PFR-specific data (specification only). */ +/* */ +/* Copyright 2002, 2003, 2004, 2006, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTPFR_H__ +#define __FTPFR_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* pfr_fonts */ + /* */ + /* <Title> */ + /* PFR Fonts */ + /* */ + /* <Abstract> */ + /* PFR/TrueDoc specific API. */ + /* */ + /* <Description> */ + /* This section contains the declaration of PFR-specific functions. */ + /* */ + /*************************************************************************/ + + + /********************************************************************** + * + * @function: + * FT_Get_PFR_Metrics + * + * @description: + * Return the outline and metrics resolutions of a given PFR face. + * + * @input: + * face :: Handle to the input face. It can be a non-PFR face. + * + * @output: + * aoutline_resolution :: + * Outline resolution. This is equivalent to `face->units_per_EM' + * for non-PFR fonts. Optional (parameter can be NULL). + * + * ametrics_resolution :: + * Metrics resolution. This is equivalent to `outline_resolution' + * for non-PFR fonts. Optional (parameter can be NULL). + * + * ametrics_x_scale :: + * A 16.16 fixed-point number used to scale distance expressed + * in metrics units to device sub-pixels. This is equivalent to + * `face->size->x_scale', but for metrics only. Optional (parameter + * can be NULL). + * + * ametrics_y_scale :: + * Same as `ametrics_x_scale' but for the vertical direction. + * optional (parameter can be NULL). + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * If the input face is not a PFR, this function will return an error. + * However, in all cases, it will return valid values. + */ + FT_EXPORT( FT_Error ) + FT_Get_PFR_Metrics( FT_Face face, + FT_UInt *aoutline_resolution, + FT_UInt *ametrics_resolution, + FT_Fixed *ametrics_x_scale, + FT_Fixed *ametrics_y_scale ); + + + /********************************************************************** + * + * @function: + * FT_Get_PFR_Kerning + * + * @description: + * Return the kerning pair corresponding to two glyphs in a PFR face. + * The distance is expressed in metrics units, unlike the result of + * @FT_Get_Kerning. + * + * @input: + * face :: A handle to the input face. + * + * left :: Index of the left glyph. + * + * right :: Index of the right glyph. + * + * @output: + * avector :: A kerning vector. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function always return distances in original PFR metrics + * units. This is unlike @FT_Get_Kerning with the @FT_KERNING_UNSCALED + * mode, which always returns distances converted to outline units. + * + * You can use the value of the `x_scale' and `y_scale' parameters + * returned by @FT_Get_PFR_Metrics to scale these to device sub-pixels. + */ + FT_EXPORT( FT_Error ) + FT_Get_PFR_Kerning( FT_Face face, + FT_UInt left, + FT_UInt right, + FT_Vector *avector ); + + + /********************************************************************** + * + * @function: + * FT_Get_PFR_Advance + * + * @description: + * Return a given glyph advance, expressed in original metrics units, + * from a PFR font. + * + * @input: + * face :: A handle to the input face. + * + * gindex :: The glyph index. + * + * @output: + * aadvance :: The glyph advance in metrics units. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * You can use the `x_scale' or `y_scale' results of @FT_Get_PFR_Metrics + * to convert the advance to device sub-pixels (i.e., 1/64th of pixels). + */ + FT_EXPORT( FT_Error ) + FT_Get_PFR_Advance( FT_Face face, + FT_UInt gindex, + FT_Pos *aadvance ); + + /* */ + + +FT_END_HEADER + +#endif /* __FTPFR_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/ftrender.h b/mod/pub.mod/freetype.mod/include/freetype/ftrender.h new file mode 100644 index 0000000..41c31ea --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/ftrender.h @@ -0,0 +1,234 @@ +/***************************************************************************/ +/* */ +/* ftrender.h */ +/* */ +/* FreeType renderer modules public interface (specification). */ +/* */ +/* Copyright 1996-2001, 2005, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTRENDER_H__ +#define __FTRENDER_H__ + + +#include <ft2build.h> +#include FT_MODULE_H +#include FT_GLYPH_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* module_management */ + /* */ + /*************************************************************************/ + + + /* create a new glyph object */ + typedef FT_Error + (*FT_Glyph_InitFunc)( FT_Glyph glyph, + FT_GlyphSlot slot ); + + /* destroys a given glyph object */ + typedef void + (*FT_Glyph_DoneFunc)( FT_Glyph glyph ); + + typedef void + (*FT_Glyph_TransformFunc)( FT_Glyph glyph, + const FT_Matrix* matrix, + const FT_Vector* delta ); + + typedef void + (*FT_Glyph_GetBBoxFunc)( FT_Glyph glyph, + FT_BBox* abbox ); + + typedef FT_Error + (*FT_Glyph_CopyFunc)( FT_Glyph source, + FT_Glyph target ); + + typedef FT_Error + (*FT_Glyph_PrepareFunc)( FT_Glyph glyph, + FT_GlyphSlot slot ); + +/* deprecated */ +#define FT_Glyph_Init_Func FT_Glyph_InitFunc +#define FT_Glyph_Done_Func FT_Glyph_DoneFunc +#define FT_Glyph_Transform_Func FT_Glyph_TransformFunc +#define FT_Glyph_BBox_Func FT_Glyph_GetBBoxFunc +#define FT_Glyph_Copy_Func FT_Glyph_CopyFunc +#define FT_Glyph_Prepare_Func FT_Glyph_PrepareFunc + + + struct FT_Glyph_Class_ + { + FT_Long glyph_size; + FT_Glyph_Format glyph_format; + FT_Glyph_InitFunc glyph_init; + FT_Glyph_DoneFunc glyph_done; + FT_Glyph_CopyFunc glyph_copy; + FT_Glyph_TransformFunc glyph_transform; + FT_Glyph_GetBBoxFunc glyph_bbox; + FT_Glyph_PrepareFunc glyph_prepare; + }; + + + typedef FT_Error + (*FT_Renderer_RenderFunc)( FT_Renderer renderer, + FT_GlyphSlot slot, + FT_UInt mode, + const FT_Vector* origin ); + + typedef FT_Error + (*FT_Renderer_TransformFunc)( FT_Renderer renderer, + FT_GlyphSlot slot, + const FT_Matrix* matrix, + const FT_Vector* delta ); + + + typedef void + (*FT_Renderer_GetCBoxFunc)( FT_Renderer renderer, + FT_GlyphSlot slot, + FT_BBox* cbox ); + + + typedef FT_Error + (*FT_Renderer_SetModeFunc)( FT_Renderer renderer, + FT_ULong mode_tag, + FT_Pointer mode_ptr ); + +/* deprecated identifiers */ +#define FTRenderer_render FT_Renderer_RenderFunc +#define FTRenderer_transform FT_Renderer_TransformFunc +#define FTRenderer_getCBox FT_Renderer_GetCBoxFunc +#define FTRenderer_setMode FT_Renderer_SetModeFunc + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Renderer_Class */ + /* */ + /* <Description> */ + /* The renderer module class descriptor. */ + /* */ + /* <Fields> */ + /* root :: The root @FT_Module_Class fields. */ + /* */ + /* glyph_format :: The glyph image format this renderer handles. */ + /* */ + /* render_glyph :: A method used to render the image that is in a */ + /* given glyph slot into a bitmap. */ + /* */ + /* transform_glyph :: A method used to transform the image that is in */ + /* a given glyph slot. */ + /* */ + /* get_glyph_cbox :: A method used to access the glyph's cbox. */ + /* */ + /* set_mode :: A method used to pass additional parameters. */ + /* */ + /* raster_class :: For @FT_GLYPH_FORMAT_OUTLINE renderers only. */ + /* This is a pointer to its raster's class. */ + /* */ + /* raster :: For @FT_GLYPH_FORMAT_OUTLINE renderers only. */ + /* This is a pointer to the corresponding raster */ + /* object, if any. */ + /* */ + typedef struct FT_Renderer_Class_ + { + FT_Module_Class root; + + FT_Glyph_Format glyph_format; + + FT_Renderer_RenderFunc render_glyph; + FT_Renderer_TransformFunc transform_glyph; + FT_Renderer_GetCBoxFunc get_glyph_cbox; + FT_Renderer_SetModeFunc set_mode; + + FT_Raster_Funcs* raster_class; + + } FT_Renderer_Class; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Renderer */ + /* */ + /* <Description> */ + /* Retrieve the current renderer for a given glyph format. */ + /* */ + /* <Input> */ + /* library :: A handle to the library object. */ + /* */ + /* format :: The glyph format. */ + /* */ + /* <Return> */ + /* A renderer handle. 0~if none found. */ + /* */ + /* <Note> */ + /* An error will be returned if a module already exists by that name, */ + /* or if the module requires a version of FreeType that is too great. */ + /* */ + /* To add a new renderer, simply use @FT_Add_Module. To retrieve a */ + /* renderer by its name, use @FT_Get_Module. */ + /* */ + FT_EXPORT( FT_Renderer ) + FT_Get_Renderer( FT_Library library, + FT_Glyph_Format format ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_Renderer */ + /* */ + /* <Description> */ + /* Set the current renderer to use, and set additional mode. */ + /* */ + /* <InOut> */ + /* library :: A handle to the library object. */ + /* */ + /* <Input> */ + /* renderer :: A handle to the renderer object. */ + /* */ + /* num_params :: The number of additional parameters. */ + /* */ + /* parameters :: Additional parameters. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* In case of success, the renderer will be used to convert glyph */ + /* images in the renderer's known format into bitmaps. */ + /* */ + /* This doesn't change the current renderer for other formats. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Set_Renderer( FT_Library library, + FT_Renderer renderer, + FT_UInt num_params, + FT_Parameter* parameters ); + + + /* */ + + +FT_END_HEADER + +#endif /* __FTRENDER_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/ftsizes.h b/mod/pub.mod/freetype.mod/include/freetype/ftsizes.h new file mode 100644 index 0000000..3e548cc --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/ftsizes.h @@ -0,0 +1,159 @@ +/***************************************************************************/ +/* */ +/* ftsizes.h */ +/* */ +/* FreeType size objects management (specification). */ +/* */ +/* Copyright 1996-2001, 2003, 2004, 2006, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* Typical application would normally not need to use these functions. */ + /* However, they have been placed in a public API for the rare cases */ + /* where they are needed. */ + /* */ + /*************************************************************************/ + + +#ifndef __FTSIZES_H__ +#define __FTSIZES_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* sizes_management */ + /* */ + /* <Title> */ + /* Size Management */ + /* */ + /* <Abstract> */ + /* Managing multiple sizes per face. */ + /* */ + /* <Description> */ + /* When creating a new face object (e.g., with @FT_New_Face), an */ + /* @FT_Size object is automatically created and used to store all */ + /* pixel-size dependent information, available in the `face->size' */ + /* field. */ + /* */ + /* It is however possible to create more sizes for a given face, */ + /* mostly in order to manage several character pixel sizes of the */ + /* same font family and style. See @FT_New_Size and @FT_Done_Size. */ + /* */ + /* Note that @FT_Set_Pixel_Sizes and @FT_Set_Char_Size only */ + /* modify the contents of the current `active' size; you thus need */ + /* to use @FT_Activate_Size to change it. */ + /* */ + /* 99% of applications won't need the functions provided here, */ + /* especially if they use the caching sub-system, so be cautious */ + /* when using these. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_Size */ + /* */ + /* <Description> */ + /* Create a new size object from a given face object. */ + /* */ + /* <Input> */ + /* face :: A handle to a parent face object. */ + /* */ + /* <Output> */ + /* asize :: A handle to a new size object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* You need to call @FT_Activate_Size in order to select the new size */ + /* for upcoming calls to @FT_Set_Pixel_Sizes, @FT_Set_Char_Size, */ + /* @FT_Load_Glyph, @FT_Load_Char, etc. */ + /* */ + FT_EXPORT( FT_Error ) + FT_New_Size( FT_Face face, + FT_Size* size ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Done_Size */ + /* */ + /* <Description> */ + /* Discard a given size object. Note that @FT_Done_Face */ + /* automatically discards all size objects allocated with */ + /* @FT_New_Size. */ + /* */ + /* <Input> */ + /* size :: A handle to a target size object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Done_Size( FT_Size size ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Activate_Size */ + /* */ + /* <Description> */ + /* Even though it is possible to create several size objects for a */ + /* given face (see @FT_New_Size for details), functions like */ + /* @FT_Load_Glyph or @FT_Load_Char only use the one which has been */ + /* activated last to determine the `current character pixel size'. */ + /* */ + /* This function can be used to `activate' a previously created size */ + /* object. */ + /* */ + /* <Input> */ + /* size :: A handle to a target size object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* If `face' is the size's parent face object, this function changes */ + /* the value of `face->size' to the input size handle. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Activate_Size( FT_Size size ); + + /* */ + + +FT_END_HEADER + +#endif /* __FTSIZES_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/ftsnames.h b/mod/pub.mod/freetype.mod/include/freetype/ftsnames.h new file mode 100644 index 0000000..f20b409 --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/ftsnames.h @@ -0,0 +1,171 @@ +/***************************************************************************/ +/* */ +/* ftsnames.h */ +/* */ +/* Simple interface to access SFNT name tables (which are used */ +/* to hold font names, copyright info, notices, etc.) (specification). */ +/* */ +/* This is _not_ used to retrieve glyph names! */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2006, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FT_SFNT_NAMES_H__ +#define __FT_SFNT_NAMES_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* sfnt_names */ + /* */ + /* <Title> */ + /* SFNT Names */ + /* */ + /* <Abstract> */ + /* Access the names embedded in TrueType and OpenType files. */ + /* */ + /* <Description> */ + /* The TrueType and OpenType specifications allow the inclusion of */ + /* a special `names table' in font files. This table contains */ + /* textual (and internationalized) information regarding the font, */ + /* like family name, copyright, version, etc. */ + /* */ + /* The definitions below are used to access them if available. */ + /* */ + /* Note that this has nothing to do with glyph names! */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_SfntName */ + /* */ + /* <Description> */ + /* A structure used to model an SFNT `name' table entry. */ + /* */ + /* <Fields> */ + /* platform_id :: The platform ID for `string'. */ + /* */ + /* encoding_id :: The encoding ID for `string'. */ + /* */ + /* language_id :: The language ID for `string'. */ + /* */ + /* name_id :: An identifier for `string'. */ + /* */ + /* string :: The `name' string. Note that its format differs */ + /* depending on the (platform,encoding) pair. It can */ + /* be a Pascal String, a UTF-16 one, etc. */ + /* */ + /* Generally speaking, the string is not */ + /* zero-terminated. Please refer to the TrueType */ + /* specification for details. */ + /* */ + /* string_len :: The length of `string' in bytes. */ + /* */ + /* <Note> */ + /* Possible values for `platform_id', `encoding_id', `language_id', */ + /* and `name_id' are given in the file `ttnameid.h'. For details */ + /* please refer to the TrueType or OpenType specification. */ + /* */ + /* See also @TT_PLATFORM_XXX, @TT_APPLE_ID_XXX, @TT_MAC_ID_XXX, */ + /* @TT_ISO_ID_XXX, and @TT_MS_ID_XXX. */ + /* */ + typedef struct FT_SfntName_ + { + FT_UShort platform_id; + FT_UShort encoding_id; + FT_UShort language_id; + FT_UShort name_id; + + FT_Byte* string; /* this string is *not* null-terminated! */ + FT_UInt string_len; /* in bytes */ + + } FT_SfntName; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Sfnt_Name_Count */ + /* */ + /* <Description> */ + /* Retrieve the number of name strings in the SFNT `name' table. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face. */ + /* */ + /* <Return> */ + /* The number of strings in the `name' table. */ + /* */ + FT_EXPORT( FT_UInt ) + FT_Get_Sfnt_Name_Count( FT_Face face ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Sfnt_Name */ + /* */ + /* <Description> */ + /* Retrieve a string of the SFNT `name' table for a given index. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face. */ + /* */ + /* idx :: The index of the `name' string. */ + /* */ + /* <Output> */ + /* aname :: The indexed @FT_SfntName structure. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The `string' array returned in the `aname' structure is not */ + /* null-terminated. The application should deallocate it if it is no */ + /* longer in use. */ + /* */ + /* Use @FT_Get_Sfnt_Name_Count to get the total number of available */ + /* `name' table entries, then do a loop until you get the right */ + /* platform, encoding, and name ID. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Sfnt_Name( FT_Face face, + FT_UInt idx, + FT_SfntName *aname ); + + + /* */ + + +FT_END_HEADER + +#endif /* __FT_SFNT_NAMES_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/ftstroke.h b/mod/pub.mod/freetype.mod/include/freetype/ftstroke.h new file mode 100644 index 0000000..3afb87d --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/ftstroke.h @@ -0,0 +1,716 @@ +/***************************************************************************/ +/* */ +/* ftstroke.h */ +/* */ +/* FreeType path stroker (specification). */ +/* */ +/* Copyright 2002, 2003, 2004, 2005, 2006, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FT_STROKE_H__ +#define __FT_STROKE_H__ + +#include <ft2build.h> +#include FT_OUTLINE_H +#include FT_GLYPH_H + + +FT_BEGIN_HEADER + + + /************************************************************************ + * + * @section: + * glyph_stroker + * + * @title: + * Glyph Stroker + * + * @abstract: + * Generating bordered and stroked glyphs. + * + * @description: + * This component generates stroked outlines of a given vectorial + * glyph. It also allows you to retrieve the `outside' and/or the + * `inside' borders of the stroke. + * + * This can be useful to generate `bordered' glyph, i.e., glyphs + * displayed with a coloured (and anti-aliased) border around their + * shape. + */ + + + /************************************************************** + * + * @type: + * FT_Stroker + * + * @description: + * Opaque handler to a path stroker object. + */ + typedef struct FT_StrokerRec_* FT_Stroker; + + + /************************************************************** + * + * @enum: + * FT_Stroker_LineJoin + * + * @description: + * These values determine how two joining lines are rendered + * in a stroker. + * + * @values: + * FT_STROKER_LINEJOIN_ROUND :: + * Used to render rounded line joins. Circular arcs are used + * to join two lines smoothly. + * + * FT_STROKER_LINEJOIN_BEVEL :: + * Used to render beveled line joins; i.e., the two joining lines + * are extended until they intersect. + * + * FT_STROKER_LINEJOIN_MITER :: + * Same as beveled rendering, except that an additional line + * break is added if the angle between the two joining lines + * is too closed (this is useful to avoid unpleasant spikes + * in beveled rendering). + */ + typedef enum FT_Stroker_LineJoin_ + { + FT_STROKER_LINEJOIN_ROUND = 0, + FT_STROKER_LINEJOIN_BEVEL, + FT_STROKER_LINEJOIN_MITER + + } FT_Stroker_LineJoin; + + + /************************************************************** + * + * @enum: + * FT_Stroker_LineCap + * + * @description: + * These values determine how the end of opened sub-paths are + * rendered in a stroke. + * + * @values: + * FT_STROKER_LINECAP_BUTT :: + * The end of lines is rendered as a full stop on the last + * point itself. + * + * FT_STROKER_LINECAP_ROUND :: + * The end of lines is rendered as a half-circle around the + * last point. + * + * FT_STROKER_LINECAP_SQUARE :: + * The end of lines is rendered as a square around the + * last point. + */ + typedef enum FT_Stroker_LineCap_ + { + FT_STROKER_LINECAP_BUTT = 0, + FT_STROKER_LINECAP_ROUND, + FT_STROKER_LINECAP_SQUARE + + } FT_Stroker_LineCap; + + + /************************************************************** + * + * @enum: + * FT_StrokerBorder + * + * @description: + * These values are used to select a given stroke border + * in @FT_Stroker_GetBorderCounts and @FT_Stroker_ExportBorder. + * + * @values: + * FT_STROKER_BORDER_LEFT :: + * Select the left border, relative to the drawing direction. + * + * FT_STROKER_BORDER_RIGHT :: + * Select the right border, relative to the drawing direction. + * + * @note: + * Applications are generally interested in the `inside' and `outside' + * borders. However, there is no direct mapping between these and the + * `left' and `right' ones, since this really depends on the glyph's + * drawing orientation, which varies between font formats. + * + * You can however use @FT_Outline_GetInsideBorder and + * @FT_Outline_GetOutsideBorder to get these. + */ + typedef enum FT_StrokerBorder_ + { + FT_STROKER_BORDER_LEFT = 0, + FT_STROKER_BORDER_RIGHT + + } FT_StrokerBorder; + + + /************************************************************** + * + * @function: + * FT_Outline_GetInsideBorder + * + * @description: + * Retrieve the @FT_StrokerBorder value corresponding to the + * `inside' borders of a given outline. + * + * @input: + * outline :: + * The source outline handle. + * + * @return: + * The border index. @FT_STROKER_BORDER_RIGHT for empty or invalid + * outlines. + */ + FT_EXPORT( FT_StrokerBorder ) + FT_Outline_GetInsideBorder( FT_Outline* outline ); + + + /************************************************************** + * + * @function: + * FT_Outline_GetOutsideBorder + * + * @description: + * Retrieve the @FT_StrokerBorder value corresponding to the + * `outside' borders of a given outline. + * + * @input: + * outline :: + * The source outline handle. + * + * @return: + * The border index. @FT_STROKER_BORDER_LEFT for empty or invalid + * outlines. + */ + FT_EXPORT( FT_StrokerBorder ) + FT_Outline_GetOutsideBorder( FT_Outline* outline ); + + + /************************************************************** + * + * @function: + * FT_Stroker_New + * + * @description: + * Create a new stroker object. + * + * @input: + * library :: + * FreeType library handle. + * + * @output: + * astroker :: + * A new stroker object handle. NULL in case of error. + * + * @return: + * FreeType error code. 0~means success. + */ + FT_EXPORT( FT_Error ) + FT_Stroker_New( FT_Library library, + FT_Stroker *astroker ); + + + /************************************************************** + * + * @function: + * FT_Stroker_Set + * + * @description: + * Reset a stroker object's attributes. + * + * @input: + * stroker :: + * The target stroker handle. + * + * radius :: + * The border radius. + * + * line_cap :: + * The line cap style. + * + * line_join :: + * The line join style. + * + * miter_limit :: + * The miter limit for the FT_STROKER_LINEJOIN_MITER style, + * expressed as 16.16 fixed point value. + * + * @note: + * The radius is expressed in the same units as the outline + * coordinates. + */ + FT_EXPORT( void ) + FT_Stroker_Set( FT_Stroker stroker, + FT_Fixed radius, + FT_Stroker_LineCap line_cap, + FT_Stroker_LineJoin line_join, + FT_Fixed miter_limit ); + + + /************************************************************** + * + * @function: + * FT_Stroker_Rewind + * + * @description: + * Reset a stroker object without changing its attributes. + * You should call this function before beginning a new + * series of calls to @FT_Stroker_BeginSubPath or + * @FT_Stroker_EndSubPath. + * + * @input: + * stroker :: + * The target stroker handle. + */ + FT_EXPORT( void ) + FT_Stroker_Rewind( FT_Stroker stroker ); + + + /************************************************************** + * + * @function: + * FT_Stroker_ParseOutline + * + * @description: + * A convenience function used to parse a whole outline with + * the stroker. The resulting outline(s) can be retrieved + * later by functions like @FT_Stroker_GetCounts and @FT_Stroker_Export. + * + * @input: + * stroker :: + * The target stroker handle. + * + * outline :: + * The source outline. + * + * opened :: + * A boolean. If~1, the outline is treated as an open path instead + * of a closed one. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * If `opened' is~0 (the default), the outline is treated as a closed + * path, and the stroker generates two distinct `border' outlines. + * + * If `opened' is~1, the outline is processed as an open path, and the + * stroker generates a single `stroke' outline. + * + * This function calls @FT_Stroker_Rewind automatically. + */ + FT_EXPORT( FT_Error ) + FT_Stroker_ParseOutline( FT_Stroker stroker, + FT_Outline* outline, + FT_Bool opened ); + + + /************************************************************** + * + * @function: + * FT_Stroker_BeginSubPath + * + * @description: + * Start a new sub-path in the stroker. + * + * @input: + * stroker :: + * The target stroker handle. + * + * to :: + * A pointer to the start vector. + * + * open :: + * A boolean. If~1, the sub-path is treated as an open one. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function is useful when you need to stroke a path that is + * not stored as an @FT_Outline object. + */ + FT_EXPORT( FT_Error ) + FT_Stroker_BeginSubPath( FT_Stroker stroker, + FT_Vector* to, + FT_Bool open ); + + + /************************************************************** + * + * @function: + * FT_Stroker_EndSubPath + * + * @description: + * Close the current sub-path in the stroker. + * + * @input: + * stroker :: + * The target stroker handle. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * You should call this function after @FT_Stroker_BeginSubPath. + * If the subpath was not `opened', this function `draws' a + * single line segment to the start position when needed. + */ + FT_EXPORT( FT_Error ) + FT_Stroker_EndSubPath( FT_Stroker stroker ); + + + /************************************************************** + * + * @function: + * FT_Stroker_LineTo + * + * @description: + * `Draw' a single line segment in the stroker's current sub-path, + * from the last position. + * + * @input: + * stroker :: + * The target stroker handle. + * + * to :: + * A pointer to the destination point. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * You should call this function between @FT_Stroker_BeginSubPath and + * @FT_Stroker_EndSubPath. + */ + FT_EXPORT( FT_Error ) + FT_Stroker_LineTo( FT_Stroker stroker, + FT_Vector* to ); + + + /************************************************************** + * + * @function: + * FT_Stroker_ConicTo + * + * @description: + * `Draw' a single quadratic Bézier in the stroker's current sub-path, + * from the last position. + * + * @input: + * stroker :: + * The target stroker handle. + * + * control :: + * A pointer to a Bézier control point. + * + * to :: + * A pointer to the destination point. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * You should call this function between @FT_Stroker_BeginSubPath and + * @FT_Stroker_EndSubPath. + */ + FT_EXPORT( FT_Error ) + FT_Stroker_ConicTo( FT_Stroker stroker, + FT_Vector* control, + FT_Vector* to ); + + + /************************************************************** + * + * @function: + * FT_Stroker_CubicTo + * + * @description: + * `Draw' a single cubic Bézier in the stroker's current sub-path, + * from the last position. + * + * @input: + * stroker :: + * The target stroker handle. + * + * control1 :: + * A pointer to the first Bézier control point. + * + * control2 :: + * A pointer to second Bézier control point. + * + * to :: + * A pointer to the destination point. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * You should call this function between @FT_Stroker_BeginSubPath and + * @FT_Stroker_EndSubPath. + */ + FT_EXPORT( FT_Error ) + FT_Stroker_CubicTo( FT_Stroker stroker, + FT_Vector* control1, + FT_Vector* control2, + FT_Vector* to ); + + + /************************************************************** + * + * @function: + * FT_Stroker_GetBorderCounts + * + * @description: + * Call this function once you have finished parsing your paths + * with the stroker. It returns the number of points and + * contours necessary to export one of the `border' or `stroke' + * outlines generated by the stroker. + * + * @input: + * stroker :: + * The target stroker handle. + * + * border :: + * The border index. + * + * @output: + * anum_points :: + * The number of points. + * + * anum_contours :: + * The number of contours. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * When an outline, or a sub-path, is `closed', the stroker generates + * two independent `border' outlines, named `left' and `right'. + * + * When the outline, or a sub-path, is `opened', the stroker merges + * the `border' outlines with caps. The `left' border receives all + * points, while the `right' border becomes empty. + * + * Use the function @FT_Stroker_GetCounts instead if you want to + * retrieve the counts associated to both borders. + */ + FT_EXPORT( FT_Error ) + FT_Stroker_GetBorderCounts( FT_Stroker stroker, + FT_StrokerBorder border, + FT_UInt *anum_points, + FT_UInt *anum_contours ); + + + /************************************************************** + * + * @function: + * FT_Stroker_ExportBorder + * + * @description: + * Call this function after @FT_Stroker_GetBorderCounts to + * export the corresponding border to your own @FT_Outline + * structure. + * + * Note that this function appends the border points and + * contours to your outline, but does not try to resize its + * arrays. + * + * @input: + * stroker :: + * The target stroker handle. + * + * border :: + * The border index. + * + * outline :: + * The target outline handle. + * + * @note: + * Always call this function after @FT_Stroker_GetBorderCounts to + * get sure that there is enough room in your @FT_Outline object to + * receive all new data. + * + * When an outline, or a sub-path, is `closed', the stroker generates + * two independent `border' outlines, named `left' and `right' + * + * When the outline, or a sub-path, is `opened', the stroker merges + * the `border' outlines with caps. The `left' border receives all + * points, while the `right' border becomes empty. + * + * Use the function @FT_Stroker_Export instead if you want to + * retrieve all borders at once. + */ + FT_EXPORT( void ) + FT_Stroker_ExportBorder( FT_Stroker stroker, + FT_StrokerBorder border, + FT_Outline* outline ); + + + /************************************************************** + * + * @function: + * FT_Stroker_GetCounts + * + * @description: + * Call this function once you have finished parsing your paths + * with the stroker. It returns the number of points and + * contours necessary to export all points/borders from the stroked + * outline/path. + * + * @input: + * stroker :: + * The target stroker handle. + * + * @output: + * anum_points :: + * The number of points. + * + * anum_contours :: + * The number of contours. + * + * @return: + * FreeType error code. 0~means success. + */ + FT_EXPORT( FT_Error ) + FT_Stroker_GetCounts( FT_Stroker stroker, + FT_UInt *anum_points, + FT_UInt *anum_contours ); + + + /************************************************************** + * + * @function: + * FT_Stroker_Export + * + * @description: + * Call this function after @FT_Stroker_GetBorderCounts to + * export all borders to your own @FT_Outline structure. + * + * Note that this function appends the border points and + * contours to your outline, but does not try to resize its + * arrays. + * + * @input: + * stroker :: + * The target stroker handle. + * + * outline :: + * The target outline handle. + */ + FT_EXPORT( void ) + FT_Stroker_Export( FT_Stroker stroker, + FT_Outline* outline ); + + + /************************************************************** + * + * @function: + * FT_Stroker_Done + * + * @description: + * Destroy a stroker object. + * + * @input: + * stroker :: + * A stroker handle. Can be NULL. + */ + FT_EXPORT( void ) + FT_Stroker_Done( FT_Stroker stroker ); + + + /************************************************************** + * + * @function: + * FT_Glyph_Stroke + * + * @description: + * Stroke a given outline glyph object with a given stroker. + * + * @inout: + * pglyph :: + * Source glyph handle on input, new glyph handle on output. + * + * @input: + * stroker :: + * A stroker handle. + * + * destroy :: + * A Boolean. If~1, the source glyph object is destroyed + * on success. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The source glyph is untouched in case of error. + */ + FT_EXPORT( FT_Error ) + FT_Glyph_Stroke( FT_Glyph *pglyph, + FT_Stroker stroker, + FT_Bool destroy ); + + + /************************************************************** + * + * @function: + * FT_Glyph_StrokeBorder + * + * @description: + * Stroke a given outline glyph object with a given stroker, but + * only return either its inside or outside border. + * + * @inout: + * pglyph :: + * Source glyph handle on input, new glyph handle on output. + * + * @input: + * stroker :: + * A stroker handle. + * + * inside :: + * A Boolean. If~1, return the inside border, otherwise + * the outside border. + * + * destroy :: + * A Boolean. If~1, the source glyph object is destroyed + * on success. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The source glyph is untouched in case of error. + */ + FT_EXPORT( FT_Error ) + FT_Glyph_StrokeBorder( FT_Glyph *pglyph, + FT_Stroker stroker, + FT_Bool inside, + FT_Bool destroy ); + + /* */ + +FT_END_HEADER + +#endif /* __FT_STROKE_H__ */ + + +/* END */ + + +/* Local Variables: */ +/* coding: utf-8 */ +/* End: */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/ftsynth.h b/mod/pub.mod/freetype.mod/include/freetype/ftsynth.h new file mode 100644 index 0000000..a068b79 --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/ftsynth.h @@ -0,0 +1,80 @@ +/***************************************************************************/ +/* */ +/* ftsynth.h */ +/* */ +/* FreeType synthesizing code for emboldening and slanting */ +/* (specification). */ +/* */ +/* Copyright 2000-2001, 2003, 2006, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /********* *********/ + /********* WARNING, THIS IS ALPHA CODE! THIS API *********/ + /********* IS DUE TO CHANGE UNTIL STRICTLY NOTIFIED BY THE *********/ + /********* FREETYPE DEVELOPMENT TEAM *********/ + /********* *********/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /* Main reason for not lifting the functions in this module to a */ + /* `standard' API is that the used parameters for emboldening and */ + /* slanting are not configurable. Consider the functions as a */ + /* code resource which should be copied into the application and */ + /* adapted to the particular needs. */ + + +#ifndef __FTSYNTH_H__ +#define __FTSYNTH_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + /* Embolden a glyph by a `reasonable' value (which is highly a matter of */ + /* taste). This function is actually a convenience function, providing */ + /* a wrapper for @FT_Outline_Embolden and @FT_Bitmap_Embolden. */ + /* */ + /* For emboldened outlines the metrics are estimates only; if you need */ + /* precise values you should call @FT_Outline_Get_CBox. */ + FT_EXPORT( void ) + FT_GlyphSlot_Embolden( FT_GlyphSlot slot ); + + /* Slant an outline glyph to the right by about 12 degrees. */ + FT_EXPORT( void ) + FT_GlyphSlot_Oblique( FT_GlyphSlot slot ); + + /* */ + +FT_END_HEADER + +#endif /* __FTSYNTH_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/ftsystem.h b/mod/pub.mod/freetype.mod/include/freetype/ftsystem.h new file mode 100644 index 0000000..a95b2c7 --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/ftsystem.h @@ -0,0 +1,346 @@ +/***************************************************************************/ +/* */ +/* ftsystem.h */ +/* */ +/* FreeType low-level system interface definition (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2005 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTSYSTEM_H__ +#define __FTSYSTEM_H__ + + +#include <ft2build.h> + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* system_interface */ + /* */ + /* <Title> */ + /* System Interface */ + /* */ + /* <Abstract> */ + /* How FreeType manages memory and i/o. */ + /* */ + /* <Description> */ + /* This section contains various definitions related to memory */ + /* management and i/o access. You need to understand this */ + /* information if you want to use a custom memory manager or you own */ + /* i/o streams. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* M E M O R Y M A N A G E M E N T */ + /* */ + /*************************************************************************/ + + + /************************************************************************* + * + * @type: + * FT_Memory + * + * @description: + * A handle to a given memory manager object, defined with an + * @FT_MemoryRec structure. + * + */ + typedef struct FT_MemoryRec_* FT_Memory; + + + /************************************************************************* + * + * @functype: + * FT_Alloc_Func + * + * @description: + * A function used to allocate `size' bytes from `memory'. + * + * @input: + * memory :: + * A handle to the source memory manager. + * + * size :: + * The size in bytes to allocate. + * + * @return: + * Address of new memory block. 0~in case of failure. + * + */ + typedef void* + (*FT_Alloc_Func)( FT_Memory memory, + long size ); + + + /************************************************************************* + * + * @functype: + * FT_Free_Func + * + * @description: + * A function used to release a given block of memory. + * + * @input: + * memory :: + * A handle to the source memory manager. + * + * block :: + * The address of the target memory block. + * + */ + typedef void + (*FT_Free_Func)( FT_Memory memory, + void* block ); + + + /************************************************************************* + * + * @functype: + * FT_Realloc_Func + * + * @description: + * A function used to re-allocate a given block of memory. + * + * @input: + * memory :: + * A handle to the source memory manager. + * + * cur_size :: + * The block's current size in bytes. + * + * new_size :: + * The block's requested new size. + * + * block :: + * The block's current address. + * + * @return: + * New block address. 0~in case of memory shortage. + * + * @note: + * In case of error, the old block must still be available. + * + */ + typedef void* + (*FT_Realloc_Func)( FT_Memory memory, + long cur_size, + long new_size, + void* block ); + + + /************************************************************************* + * + * @struct: + * FT_MemoryRec + * + * @description: + * A structure used to describe a given memory manager to FreeType~2. + * + * @fields: + * user :: + * A generic typeless pointer for user data. + * + * alloc :: + * A pointer type to an allocation function. + * + * free :: + * A pointer type to an memory freeing function. + * + * realloc :: + * A pointer type to a reallocation function. + * + */ + struct FT_MemoryRec_ + { + void* user; + FT_Alloc_Func alloc; + FT_Free_Func free; + FT_Realloc_Func realloc; + }; + + + /*************************************************************************/ + /* */ + /* I / O M A N A G E M E N T */ + /* */ + /*************************************************************************/ + + + /************************************************************************* + * + * @type: + * FT_Stream + * + * @description: + * A handle to an input stream. + * + */ + typedef struct FT_StreamRec_* FT_Stream; + + + /************************************************************************* + * + * @struct: + * FT_StreamDesc + * + * @description: + * A union type used to store either a long or a pointer. This is used + * to store a file descriptor or a `FILE*' in an input stream. + * + */ + typedef union FT_StreamDesc_ + { + long value; + void* pointer; + + } FT_StreamDesc; + + + /************************************************************************* + * + * @functype: + * FT_Stream_IoFunc + * + * @description: + * A function used to seek and read data from a given input stream. + * + * @input: + * stream :: + * A handle to the source stream. + * + * offset :: + * The offset of read in stream (always from start). + * + * buffer :: + * The address of the read buffer. + * + * count :: + * The number of bytes to read from the stream. + * + * @return: + * The number of bytes effectively read by the stream. + * + * @note: + * This function might be called to perform a seek or skip operation + * with a `count' of~0. + * + */ + typedef unsigned long + (*FT_Stream_IoFunc)( FT_Stream stream, + unsigned long offset, + unsigned char* buffer, + unsigned long count ); + + + /************************************************************************* + * + * @functype: + * FT_Stream_CloseFunc + * + * @description: + * A function used to close a given input stream. + * + * @input: + * stream :: + * A handle to the target stream. + * + */ + typedef void + (*FT_Stream_CloseFunc)( FT_Stream stream ); + + + /************************************************************************* + * + * @struct: + * FT_StreamRec + * + * @description: + * A structure used to describe an input stream. + * + * @input: + * base :: + * For memory-based streams, this is the address of the first stream + * byte in memory. This field should always be set to NULL for + * disk-based streams. + * + * size :: + * The stream size in bytes. + * + * pos :: + * The current position within the stream. + * + * descriptor :: + * This field is a union that can hold an integer or a pointer. It is + * used by stream implementations to store file descriptors or `FILE*' + * pointers. + * + * pathname :: + * This field is completely ignored by FreeType. However, it is often + * useful during debugging to use it to store the stream's filename + * (where available). + * + * read :: + * The stream's input function. + * + * close :: + * The stream;s close function. + * + * memory :: + * The memory manager to use to preload frames. This is set + * internally by FreeType and shouldn't be touched by stream + * implementations. + * + * cursor :: + * This field is set and used internally by FreeType when parsing + * frames. + * + * limit :: + * This field is set and used internally by FreeType when parsing + * frames. + * + */ + typedef struct FT_StreamRec_ + { + unsigned char* base; + unsigned long size; + unsigned long pos; + + FT_StreamDesc descriptor; + FT_StreamDesc pathname; + FT_Stream_IoFunc read; + FT_Stream_CloseFunc close; + + FT_Memory memory; + unsigned char* cursor; + unsigned char* limit; + + } FT_StreamRec; + + + /* */ + + +FT_END_HEADER + +#endif /* __FTSYSTEM_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/fttrigon.h b/mod/pub.mod/freetype.mod/include/freetype/fttrigon.h new file mode 100644 index 0000000..6b77d2e --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/fttrigon.h @@ -0,0 +1,350 @@ +/***************************************************************************/ +/* */ +/* fttrigon.h */ +/* */ +/* FreeType trigonometric functions (specification). */ +/* */ +/* Copyright 2001, 2003, 2005, 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTTRIGON_H__ +#define __FTTRIGON_H__ + +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* computations */ + /* */ + /*************************************************************************/ + + + /************************************************************************* + * + * @type: + * FT_Angle + * + * @description: + * This type is used to model angle values in FreeType. Note that the + * angle is a 16.16 fixed float value expressed in degrees. + * + */ + typedef FT_Fixed FT_Angle; + + + /************************************************************************* + * + * @macro: + * FT_ANGLE_PI + * + * @description: + * The angle pi expressed in @FT_Angle units. + * + */ +#define FT_ANGLE_PI ( 180L << 16 ) + + + /************************************************************************* + * + * @macro: + * FT_ANGLE_2PI + * + * @description: + * The angle 2*pi expressed in @FT_Angle units. + * + */ +#define FT_ANGLE_2PI ( FT_ANGLE_PI * 2 ) + + + /************************************************************************* + * + * @macro: + * FT_ANGLE_PI2 + * + * @description: + * The angle pi/2 expressed in @FT_Angle units. + * + */ +#define FT_ANGLE_PI2 ( FT_ANGLE_PI / 2 ) + + + /************************************************************************* + * + * @macro: + * FT_ANGLE_PI4 + * + * @description: + * The angle pi/4 expressed in @FT_Angle units. + * + */ +#define FT_ANGLE_PI4 ( FT_ANGLE_PI / 4 ) + + + /************************************************************************* + * + * @function: + * FT_Sin + * + * @description: + * Return the sinus of a given angle in fixed point format. + * + * @input: + * angle :: + * The input angle. + * + * @return: + * The sinus value. + * + * @note: + * If you need both the sinus and cosinus for a given angle, use the + * function @FT_Vector_Unit. + * + */ + FT_EXPORT( FT_Fixed ) + FT_Sin( FT_Angle angle ); + + + /************************************************************************* + * + * @function: + * FT_Cos + * + * @description: + * Return the cosinus of a given angle in fixed point format. + * + * @input: + * angle :: + * The input angle. + * + * @return: + * The cosinus value. + * + * @note: + * If you need both the sinus and cosinus for a given angle, use the + * function @FT_Vector_Unit. + * + */ + FT_EXPORT( FT_Fixed ) + FT_Cos( FT_Angle angle ); + + + /************************************************************************* + * + * @function: + * FT_Tan + * + * @description: + * Return the tangent of a given angle in fixed point format. + * + * @input: + * angle :: + * The input angle. + * + * @return: + * The tangent value. + * + */ + FT_EXPORT( FT_Fixed ) + FT_Tan( FT_Angle angle ); + + + /************************************************************************* + * + * @function: + * FT_Atan2 + * + * @description: + * Return the arc-tangent corresponding to a given vector (x,y) in + * the 2d plane. + * + * @input: + * x :: + * The horizontal vector coordinate. + * + * y :: + * The vertical vector coordinate. + * + * @return: + * The arc-tangent value (i.e. angle). + * + */ + FT_EXPORT( FT_Angle ) + FT_Atan2( FT_Fixed x, + FT_Fixed y ); + + + /************************************************************************* + * + * @function: + * FT_Angle_Diff + * + * @description: + * Return the difference between two angles. The result is always + * constrained to the ]-PI..PI] interval. + * + * @input: + * angle1 :: + * First angle. + * + * angle2 :: + * Second angle. + * + * @return: + * Constrained value of `value2-value1'. + * + */ + FT_EXPORT( FT_Angle ) + FT_Angle_Diff( FT_Angle angle1, + FT_Angle angle2 ); + + + /************************************************************************* + * + * @function: + * FT_Vector_Unit + * + * @description: + * Return the unit vector corresponding to a given angle. After the + * call, the value of `vec.x' will be `sin(angle)', and the value of + * `vec.y' will be `cos(angle)'. + * + * This function is useful to retrieve both the sinus and cosinus of a + * given angle quickly. + * + * @output: + * vec :: + * The address of target vector. + * + * @input: + * angle :: + * The address of angle. + * + */ + FT_EXPORT( void ) + FT_Vector_Unit( FT_Vector* vec, + FT_Angle angle ); + + + /************************************************************************* + * + * @function: + * FT_Vector_Rotate + * + * @description: + * Rotate a vector by a given angle. + * + * @inout: + * vec :: + * The address of target vector. + * + * @input: + * angle :: + * The address of angle. + * + */ + FT_EXPORT( void ) + FT_Vector_Rotate( FT_Vector* vec, + FT_Angle angle ); + + + /************************************************************************* + * + * @function: + * FT_Vector_Length + * + * @description: + * Return the length of a given vector. + * + * @input: + * vec :: + * The address of target vector. + * + * @return: + * The vector length, expressed in the same units that the original + * vector coordinates. + * + */ + FT_EXPORT( FT_Fixed ) + FT_Vector_Length( FT_Vector* vec ); + + + /************************************************************************* + * + * @function: + * FT_Vector_Polarize + * + * @description: + * Compute both the length and angle of a given vector. + * + * @input: + * vec :: + * The address of source vector. + * + * @output: + * length :: + * The vector length. + * + * angle :: + * The vector angle. + * + */ + FT_EXPORT( void ) + FT_Vector_Polarize( FT_Vector* vec, + FT_Fixed *length, + FT_Angle *angle ); + + + /************************************************************************* + * + * @function: + * FT_Vector_From_Polar + * + * @description: + * Compute vector coordinates from a length and angle. + * + * @output: + * vec :: + * The address of source vector. + * + * @input: + * length :: + * The vector length. + * + * angle :: + * The vector angle. + * + */ + FT_EXPORT( void ) + FT_Vector_From_Polar( FT_Vector* vec, + FT_Fixed length, + FT_Angle angle ); + + /* */ + + +FT_END_HEADER + +#endif /* __FTTRIGON_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/fttypes.h b/mod/pub.mod/freetype.mod/include/freetype/fttypes.h new file mode 100644 index 0000000..a57ffa6 --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/fttypes.h @@ -0,0 +1,588 @@ +/***************************************************************************/ +/* */ +/* fttypes.h */ +/* */ +/* FreeType simple types definitions (specification only). */ +/* */ +/* Copyright 1996-2001, 2002, 2004, 2006, 2007, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTTYPES_H__ +#define __FTTYPES_H__ + + +#include <ft2build.h> +#include FT_CONFIG_CONFIG_H +#include FT_SYSTEM_H +#include FT_IMAGE_H + +#include <stddef.h> + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* basic_types */ + /* */ + /* <Title> */ + /* Basic Data Types */ + /* */ + /* <Abstract> */ + /* The basic data types defined by the library. */ + /* */ + /* <Description> */ + /* This section contains the basic data types defined by FreeType~2, */ + /* ranging from simple scalar types to bitmap descriptors. More */ + /* font-specific structures are defined in a different section. */ + /* */ + /* <Order> */ + /* FT_Byte */ + /* FT_Bytes */ + /* FT_Char */ + /* FT_Int */ + /* FT_UInt */ + /* FT_Int16 */ + /* FT_UInt16 */ + /* FT_Int32 */ + /* FT_UInt32 */ + /* FT_Short */ + /* FT_UShort */ + /* FT_Long */ + /* FT_ULong */ + /* FT_Bool */ + /* FT_Offset */ + /* FT_PtrDist */ + /* FT_String */ + /* FT_Tag */ + /* FT_Error */ + /* FT_Fixed */ + /* FT_Pointer */ + /* FT_Pos */ + /* FT_Vector */ + /* FT_BBox */ + /* FT_Matrix */ + /* FT_FWord */ + /* FT_UFWord */ + /* FT_F2Dot14 */ + /* FT_UnitVector */ + /* FT_F26Dot6 */ + /* */ + /* */ + /* FT_Generic */ + /* FT_Generic_Finalizer */ + /* */ + /* FT_Bitmap */ + /* FT_Pixel_Mode */ + /* FT_Palette_Mode */ + /* FT_Glyph_Format */ + /* FT_IMAGE_TAG */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Bool */ + /* */ + /* <Description> */ + /* A typedef of unsigned char, used for simple booleans. As usual, */ + /* values 1 and~0 represent true and false, respectively. */ + /* */ + typedef unsigned char FT_Bool; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_FWord */ + /* */ + /* <Description> */ + /* A signed 16-bit integer used to store a distance in original font */ + /* units. */ + /* */ + typedef signed short FT_FWord; /* distance in FUnits */ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_UFWord */ + /* */ + /* <Description> */ + /* An unsigned 16-bit integer used to store a distance in original */ + /* font units. */ + /* */ + typedef unsigned short FT_UFWord; /* unsigned distance */ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Char */ + /* */ + /* <Description> */ + /* A simple typedef for the _signed_ char type. */ + /* */ + typedef signed char FT_Char; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Byte */ + /* */ + /* <Description> */ + /* A simple typedef for the _unsigned_ char type. */ + /* */ + typedef unsigned char FT_Byte; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Bytes */ + /* */ + /* <Description> */ + /* A typedef for constant memory areas. */ + /* */ + typedef const FT_Byte* FT_Bytes; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Tag */ + /* */ + /* <Description> */ + /* A typedef for 32-bit tags (as used in the SFNT format). */ + /* */ + typedef FT_UInt32 FT_Tag; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_String */ + /* */ + /* <Description> */ + /* A simple typedef for the char type, usually used for strings. */ + /* */ + typedef char FT_String; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Short */ + /* */ + /* <Description> */ + /* A typedef for signed short. */ + /* */ + typedef signed short FT_Short; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_UShort */ + /* */ + /* <Description> */ + /* A typedef for unsigned short. */ + /* */ + typedef unsigned short FT_UShort; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Int */ + /* */ + /* <Description> */ + /* A typedef for the int type. */ + /* */ + typedef signed int FT_Int; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_UInt */ + /* */ + /* <Description> */ + /* A typedef for the unsigned int type. */ + /* */ + typedef unsigned int FT_UInt; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Long */ + /* */ + /* <Description> */ + /* A typedef for signed long. */ + /* */ + typedef signed long FT_Long; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_ULong */ + /* */ + /* <Description> */ + /* A typedef for unsigned long. */ + /* */ + typedef unsigned long FT_ULong; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_F2Dot14 */ + /* */ + /* <Description> */ + /* A signed 2.14 fixed float type used for unit vectors. */ + /* */ + typedef signed short FT_F2Dot14; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_F26Dot6 */ + /* */ + /* <Description> */ + /* A signed 26.6 fixed float type used for vectorial pixel */ + /* coordinates. */ + /* */ + typedef signed long FT_F26Dot6; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Fixed */ + /* */ + /* <Description> */ + /* This type is used to store 16.16 fixed float values, like scaling */ + /* values or matrix coefficients. */ + /* */ + typedef signed long FT_Fixed; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Error */ + /* */ + /* <Description> */ + /* The FreeType error code type. A value of~0 is always interpreted */ + /* as a successful operation. */ + /* */ + typedef int FT_Error; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Pointer */ + /* */ + /* <Description> */ + /* A simple typedef for a typeless pointer. */ + /* */ + typedef void* FT_Pointer; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Offset */ + /* */ + /* <Description> */ + /* This is equivalent to the ANSI~C `size_t' type, i.e., the largest */ + /* _unsigned_ integer type used to express a file size or position, */ + /* or a memory block size. */ + /* */ + typedef size_t FT_Offset; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_PtrDist */ + /* */ + /* <Description> */ + /* This is equivalent to the ANSI~C `ptrdiff_t' type, i.e., the */ + /* largest _signed_ integer type used to express the distance */ + /* between two pointers. */ + /* */ + typedef ft_ptrdiff_t FT_PtrDist; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_UnitVector */ + /* */ + /* <Description> */ + /* A simple structure used to store a 2D vector unit vector. Uses */ + /* FT_F2Dot14 types. */ + /* */ + /* <Fields> */ + /* x :: Horizontal coordinate. */ + /* */ + /* y :: Vertical coordinate. */ + /* */ + typedef struct FT_UnitVector_ + { + FT_F2Dot14 x; + FT_F2Dot14 y; + + } FT_UnitVector; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Matrix */ + /* */ + /* <Description> */ + /* A simple structure used to store a 2x2 matrix. Coefficients are */ + /* in 16.16 fixed float format. The computation performed is: */ + /* */ + /* { */ + /* x' = x*xx + y*xy */ + /* y' = x*yx + y*yy */ + /* } */ + /* */ + /* <Fields> */ + /* xx :: Matrix coefficient. */ + /* */ + /* xy :: Matrix coefficient. */ + /* */ + /* yx :: Matrix coefficient. */ + /* */ + /* yy :: Matrix coefficient. */ + /* */ + typedef struct FT_Matrix_ + { + FT_Fixed xx, xy; + FT_Fixed yx, yy; + + } FT_Matrix; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Data */ + /* */ + /* <Description> */ + /* Read-only binary data represented as a pointer and a length. */ + /* */ + /* <Fields> */ + /* pointer :: The data. */ + /* */ + /* length :: The length of the data in bytes. */ + /* */ + typedef struct FT_Data_ + { + const FT_Byte* pointer; + FT_Int length; + + } FT_Data; + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Generic_Finalizer */ + /* */ + /* <Description> */ + /* Describe a function used to destroy the `client' data of any */ + /* FreeType object. See the description of the @FT_Generic type for */ + /* details of usage. */ + /* */ + /* <Input> */ + /* The address of the FreeType object which is under finalization. */ + /* Its client data is accessed through its `generic' field. */ + /* */ + typedef void (*FT_Generic_Finalizer)(void* object); + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Generic */ + /* */ + /* <Description> */ + /* Client applications often need to associate their own data to a */ + /* variety of FreeType core objects. For example, a text layout API */ + /* might want to associate a glyph cache to a given size object. */ + /* */ + /* Most FreeType object contains a `generic' field, of type */ + /* FT_Generic, which usage is left to client applications and font */ + /* servers. */ + /* */ + /* It can be used to store a pointer to client-specific data, as well */ + /* as the address of a `finalizer' function, which will be called by */ + /* FreeType when the object is destroyed (for example, the previous */ + /* client example would put the address of the glyph cache destructor */ + /* in the `finalizer' field). */ + /* */ + /* <Fields> */ + /* data :: A typeless pointer to any client-specified data. This */ + /* field is completely ignored by the FreeType library. */ + /* */ + /* finalizer :: A pointer to a `generic finalizer' function, which */ + /* will be called when the object is destroyed. If this */ + /* field is set to NULL, no code will be called. */ + /* */ + typedef struct FT_Generic_ + { + void* data; + FT_Generic_Finalizer finalizer; + + } FT_Generic; + + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_MAKE_TAG */ + /* */ + /* <Description> */ + /* This macro converts four-letter tags which are used to label */ + /* TrueType tables into an unsigned long to be used within FreeType. */ + /* */ + /* <Note> */ + /* The produced values *must* be 32-bit integers. Don't redefine */ + /* this macro. */ + /* */ +#define FT_MAKE_TAG( _x1, _x2, _x3, _x4 ) \ + (FT_Tag) \ + ( ( (FT_ULong)_x1 << 24 ) | \ + ( (FT_ULong)_x2 << 16 ) | \ + ( (FT_ULong)_x3 << 8 ) | \ + (FT_ULong)_x4 ) + + + /*************************************************************************/ + /*************************************************************************/ + /* */ + /* L I S T M A N A G E M E N T */ + /* */ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* list_processing */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_ListNode */ + /* */ + /* <Description> */ + /* Many elements and objects in FreeType are listed through an */ + /* @FT_List record (see @FT_ListRec). As its name suggests, an */ + /* FT_ListNode is a handle to a single list element. */ + /* */ + typedef struct FT_ListNodeRec_* FT_ListNode; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_List */ + /* */ + /* <Description> */ + /* A handle to a list record (see @FT_ListRec). */ + /* */ + typedef struct FT_ListRec_* FT_List; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_ListNodeRec */ + /* */ + /* <Description> */ + /* A structure used to hold a single list element. */ + /* */ + /* <Fields> */ + /* prev :: The previous element in the list. NULL if first. */ + /* */ + /* next :: The next element in the list. NULL if last. */ + /* */ + /* data :: A typeless pointer to the listed object. */ + /* */ + typedef struct FT_ListNodeRec_ + { + FT_ListNode prev; + FT_ListNode next; + void* data; + + } FT_ListNodeRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_ListRec */ + /* */ + /* <Description> */ + /* A structure used to hold a simple doubly-linked list. These are */ + /* used in many parts of FreeType. */ + /* */ + /* <Fields> */ + /* head :: The head (first element) of doubly-linked list. */ + /* */ + /* tail :: The tail (last element) of doubly-linked list. */ + /* */ + typedef struct FT_ListRec_ + { + FT_ListNode head; + FT_ListNode tail; + + } FT_ListRec; + + + /* */ + +#define FT_IS_EMPTY( list ) ( (list).head == 0 ) + + /* return base error code (without module-specific prefix) */ +#define FT_ERROR_BASE( x ) ( (x) & 0xFF ) + + /* return module error code */ +#define FT_ERROR_MODULE( x ) ( (x) & 0xFF00U ) + +#define FT_BOOL( x ) ( (FT_Bool)( x ) ) + +FT_END_HEADER + +#endif /* __FTTYPES_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/ftwinfnt.h b/mod/pub.mod/freetype.mod/include/freetype/ftwinfnt.h new file mode 100644 index 0000000..ea33353 --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/ftwinfnt.h @@ -0,0 +1,274 @@ +/***************************************************************************/ +/* */ +/* ftwinfnt.h */ +/* */ +/* FreeType API for accessing Windows fnt-specific data. */ +/* */ +/* Copyright 2003, 2004, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTWINFNT_H__ +#define __FTWINFNT_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* winfnt_fonts */ + /* */ + /* <Title> */ + /* Window FNT Files */ + /* */ + /* <Abstract> */ + /* Windows FNT specific API. */ + /* */ + /* <Description> */ + /* This section contains the declaration of Windows FNT specific */ + /* functions. */ + /* */ + /*************************************************************************/ + + + /************************************************************************* + * + * @enum: + * FT_WinFNT_ID_XXX + * + * @description: + * A list of valid values for the `charset' byte in + * @FT_WinFNT_HeaderRec. Exact mapping tables for the various cpXXXX + * encodings (except for cp1361) can be found at ftp://ftp.unicode.org + * in the MAPPINGS/VENDORS/MICSFT/WINDOWS subdirectory. cp1361 is + * roughly a superset of MAPPINGS/OBSOLETE/EASTASIA/KSC/JOHAB.TXT. + * + * @values: + * FT_WinFNT_ID_DEFAULT :: + * This is used for font enumeration and font creation as a + * `don't care' value. Valid font files don't contain this value. + * When querying for information about the character set of the font + * that is currently selected into a specified device context, this + * return value (of the related Windows API) simply denotes failure. + * + * FT_WinFNT_ID_SYMBOL :: + * There is no known mapping table available. + * + * FT_WinFNT_ID_MAC :: + * Mac Roman encoding. + * + * FT_WinFNT_ID_OEM :: + * From Michael Pâttgen <michael@poettgen.de>: + * + * The `Windows Font Mapping' article says that FT_WinFNT_ID_OEM + * is used for the charset of vector fonts, like `modern.fon', + * `roman.fon', and `script.fon' on Windows. + * + * The `CreateFont' documentation says: The FT_WinFNT_ID_OEM value + * specifies a character set that is operating-system dependent. + * + * The `IFIMETRICS' documentation from the `Windows Driver + * Development Kit' says: This font supports an OEM-specific + * character set. The OEM character set is system dependent. + * + * In general OEM, as opposed to ANSI (i.e., cp1252), denotes the + * second default codepage that most international versions of + * Windows have. It is one of the OEM codepages from + * + * http://www.microsoft.com/globaldev/reference/cphome.mspx, + * + * and is used for the `DOS boxes', to support legacy applications. + * A German Windows version for example usually uses ANSI codepage + * 1252 and OEM codepage 850. + * + * FT_WinFNT_ID_CP874 :: + * A superset of Thai TIS 620 and ISO 8859-11. + * + * FT_WinFNT_ID_CP932 :: + * A superset of Japanese Shift-JIS (with minor deviations). + * + * FT_WinFNT_ID_CP936 :: + * A superset of simplified Chinese GB 2312-1980 (with different + * ordering and minor deviations). + * + * FT_WinFNT_ID_CP949 :: + * A superset of Korean Hangul KS~C 5601-1987 (with different + * ordering and minor deviations). + * + * FT_WinFNT_ID_CP950 :: + * A superset of traditional Chinese Big~5 ETen (with different + * ordering and minor deviations). + * + * FT_WinFNT_ID_CP1250 :: + * A superset of East European ISO 8859-2 (with slightly different + * ordering). + * + * FT_WinFNT_ID_CP1251 :: + * A superset of Russian ISO 8859-5 (with different ordering). + * + * FT_WinFNT_ID_CP1252 :: + * ANSI encoding. A superset of ISO 8859-1. + * + * FT_WinFNT_ID_CP1253 :: + * A superset of Greek ISO 8859-7 (with minor modifications). + * + * FT_WinFNT_ID_CP1254 :: + * A superset of Turkish ISO 8859-9. + * + * FT_WinFNT_ID_CP1255 :: + * A superset of Hebrew ISO 8859-8 (with some modifications). + * + * FT_WinFNT_ID_CP1256 :: + * A superset of Arabic ISO 8859-6 (with different ordering). + * + * FT_WinFNT_ID_CP1257 :: + * A superset of Baltic ISO 8859-13 (with some deviations). + * + * FT_WinFNT_ID_CP1258 :: + * For Vietnamese. This encoding doesn't cover all necessary + * characters. + * + * FT_WinFNT_ID_CP1361 :: + * Korean (Johab). + */ + +#define FT_WinFNT_ID_CP1252 0 +#define FT_WinFNT_ID_DEFAULT 1 +#define FT_WinFNT_ID_SYMBOL 2 +#define FT_WinFNT_ID_MAC 77 +#define FT_WinFNT_ID_CP932 128 +#define FT_WinFNT_ID_CP949 129 +#define FT_WinFNT_ID_CP1361 130 +#define FT_WinFNT_ID_CP936 134 +#define FT_WinFNT_ID_CP950 136 +#define FT_WinFNT_ID_CP1253 161 +#define FT_WinFNT_ID_CP1254 162 +#define FT_WinFNT_ID_CP1258 163 +#define FT_WinFNT_ID_CP1255 177 +#define FT_WinFNT_ID_CP1256 178 +#define FT_WinFNT_ID_CP1257 186 +#define FT_WinFNT_ID_CP1251 204 +#define FT_WinFNT_ID_CP874 222 +#define FT_WinFNT_ID_CP1250 238 +#define FT_WinFNT_ID_OEM 255 + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_WinFNT_HeaderRec */ + /* */ + /* <Description> */ + /* Windows FNT Header info. */ + /* */ + typedef struct FT_WinFNT_HeaderRec_ + { + FT_UShort version; + FT_ULong file_size; + FT_Byte copyright[60]; + FT_UShort file_type; + FT_UShort nominal_point_size; + FT_UShort vertical_resolution; + FT_UShort horizontal_resolution; + FT_UShort ascent; + FT_UShort internal_leading; + FT_UShort external_leading; + FT_Byte italic; + FT_Byte underline; + FT_Byte strike_out; + FT_UShort weight; + FT_Byte charset; + FT_UShort pixel_width; + FT_UShort pixel_height; + FT_Byte pitch_and_family; + FT_UShort avg_width; + FT_UShort max_width; + FT_Byte first_char; + FT_Byte last_char; + FT_Byte default_char; + FT_Byte break_char; + FT_UShort bytes_per_row; + FT_ULong device_offset; + FT_ULong face_name_offset; + FT_ULong bits_pointer; + FT_ULong bits_offset; + FT_Byte reserved; + FT_ULong flags; + FT_UShort A_space; + FT_UShort B_space; + FT_UShort C_space; + FT_UShort color_table_offset; + FT_ULong reserved1[4]; + + } FT_WinFNT_HeaderRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_WinFNT_Header */ + /* */ + /* <Description> */ + /* A handle to an @FT_WinFNT_HeaderRec structure. */ + /* */ + typedef struct FT_WinFNT_HeaderRec_* FT_WinFNT_Header; + + + /********************************************************************** + * + * @function: + * FT_Get_WinFNT_Header + * + * @description: + * Retrieve a Windows FNT font info header. + * + * @input: + * face :: A handle to the input face. + * + * @output: + * aheader :: The WinFNT header. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function only works with Windows FNT faces, returning an error + * otherwise. + */ + FT_EXPORT( FT_Error ) + FT_Get_WinFNT_Header( FT_Face face, + FT_WinFNT_HeaderRec *aheader ); + + + /* */ + +FT_END_HEADER + +#endif /* __FTWINFNT_H__ */ + + +/* END */ + + +/* Local Variables: */ +/* coding: utf-8 */ +/* End: */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/ftxf86.h b/mod/pub.mod/freetype.mod/include/freetype/ftxf86.h new file mode 100644 index 0000000..8c68afd --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/ftxf86.h @@ -0,0 +1,83 @@ +/***************************************************************************/ +/* */ +/* ftxf86.h */ +/* */ +/* Support functions for X11. */ +/* */ +/* Copyright 2002, 2003, 2004, 2006, 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTXF86_H__ +#define __FTXF86_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* font_formats */ + /* */ + /* <Title> */ + /* Font Formats */ + /* */ + /* <Abstract> */ + /* Getting the font format. */ + /* */ + /* <Description> */ + /* The single function in this section can be used to get the font */ + /* format. Note that this information is not needed normally; */ + /* however, there are special cases (like in PDF devices) where it is */ + /* important to differentiate, in spite of FreeType's uniform API. */ + /* */ + /* This function is in the X11/xf86 namespace for historical reasons */ + /* and in no way depends on that windowing system. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_X11_Font_Format */ + /* */ + /* <Description> */ + /* Return a string describing the format of a given face, using values */ + /* which can be used as an X11 FONT_PROPERTY. Possible values are */ + /* `TrueType', `Type~1', `BDF', `PCF', `Type~42', `CID~Type~1', `CFF', */ + /* `PFR', and `Windows~FNT'. */ + /* */ + /* <Input> */ + /* face :: */ + /* Input face handle. */ + /* */ + /* <Return> */ + /* Font format string. NULL in case of error. */ + /* */ + FT_EXPORT( const char* ) + FT_Get_X11_Font_Format( FT_Face face ); + + /* */ + +FT_END_HEADER + +#endif /* __FTXF86_H__ */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/internal/autohint.h b/mod/pub.mod/freetype.mod/include/freetype/internal/autohint.h new file mode 100644 index 0000000..7e3a08a --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/internal/autohint.h @@ -0,0 +1,231 @@ +/***************************************************************************/ +/* */ +/* autohint.h */ +/* */ +/* High-level `autohint' module-specific interface (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* The auto-hinter is used to load and automatically hint glyphs if a */ + /* format-specific hinter isn't available. */ + /* */ + /*************************************************************************/ + + +#ifndef __AUTOHINT_H__ +#define __AUTOHINT_H__ + + + /*************************************************************************/ + /* */ + /* A small technical note regarding automatic hinting in order to */ + /* clarify this module interface. */ + /* */ + /* An automatic hinter might compute two kinds of data for a given face: */ + /* */ + /* - global hints: Usually some metrics that describe global properties */ + /* of the face. It is computed by scanning more or less */ + /* aggressively the glyphs in the face, and thus can be */ + /* very slow to compute (even if the size of global */ + /* hints is really small). */ + /* */ + /* - glyph hints: These describe some important features of the glyph */ + /* outline, as well as how to align them. They are */ + /* generally much faster to compute than global hints. */ + /* */ + /* The current FreeType auto-hinter does a pretty good job while */ + /* performing fast computations for both global and glyph hints. */ + /* However, we might be interested in introducing more complex and */ + /* powerful algorithms in the future, like the one described in the John */ + /* D. Hobby paper, which unfortunately requires a lot more horsepower. */ + /* */ + /* Because a sufficiently sophisticated font management system would */ + /* typically implement an LRU cache of opened face objects to reduce */ + /* memory usage, it is a good idea to be able to avoid recomputing */ + /* global hints every time the same face is re-opened. */ + /* */ + /* We thus provide the ability to cache global hints outside of the face */ + /* object, in order to speed up font re-opening time. Of course, this */ + /* feature is purely optional, so most client programs won't even notice */ + /* it. */ + /* */ + /* I initially thought that it would be a good idea to cache the glyph */ + /* hints too. However, my general idea now is that if you really need */ + /* to cache these too, you are simply in need of a new font format, */ + /* where all this information could be stored within the font file and */ + /* decoded on the fly. */ + /* */ + /*************************************************************************/ + + +#include <ft2build.h> +#include FT_FREETYPE_H + + +FT_BEGIN_HEADER + + + typedef struct FT_AutoHinterRec_ *FT_AutoHinter; + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_AutoHinter_GlobalGetFunc */ + /* */ + /* <Description> */ + /* Retrieves the global hints computed for a given face object the */ + /* resulting data is dissociated from the face and will survive a */ + /* call to FT_Done_Face(). It must be discarded through the API */ + /* FT_AutoHinter_GlobalDoneFunc(). */ + /* */ + /* <Input> */ + /* hinter :: A handle to the source auto-hinter. */ + /* */ + /* face :: A handle to the source face object. */ + /* */ + /* <Output> */ + /* global_hints :: A typeless pointer to the global hints. */ + /* */ + /* global_len :: The size in bytes of the global hints. */ + /* */ + typedef void + (*FT_AutoHinter_GlobalGetFunc)( FT_AutoHinter hinter, + FT_Face face, + void** global_hints, + long* global_len ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_AutoHinter_GlobalDoneFunc */ + /* */ + /* <Description> */ + /* Discards the global hints retrieved through */ + /* FT_AutoHinter_GlobalGetFunc(). This is the only way these hints */ + /* are freed from memory. */ + /* */ + /* <Input> */ + /* hinter :: A handle to the auto-hinter module. */ + /* */ + /* global :: A pointer to retrieved global hints to discard. */ + /* */ + typedef void + (*FT_AutoHinter_GlobalDoneFunc)( FT_AutoHinter hinter, + void* global ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_AutoHinter_GlobalResetFunc */ + /* */ + /* <Description> */ + /* This function is used to recompute the global metrics in a given */ + /* font. This is useful when global font data changes (e.g. Multiple */ + /* Masters fonts where blend coordinates change). */ + /* */ + /* <Input> */ + /* hinter :: A handle to the source auto-hinter. */ + /* */ + /* face :: A handle to the face. */ + /* */ + typedef void + (*FT_AutoHinter_GlobalResetFunc)( FT_AutoHinter hinter, + FT_Face face ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_AutoHinter_GlyphLoadFunc */ + /* */ + /* <Description> */ + /* This function is used to load, scale, and automatically hint a */ + /* glyph from a given face. */ + /* */ + /* <Input> */ + /* face :: A handle to the face. */ + /* */ + /* glyph_index :: The glyph index. */ + /* */ + /* load_flags :: The load flags. */ + /* */ + /* <Note> */ + /* This function is capable of loading composite glyphs by hinting */ + /* each sub-glyph independently (which improves quality). */ + /* */ + /* It will call the font driver with FT_Load_Glyph(), with */ + /* FT_LOAD_NO_SCALE set. */ + /* */ + typedef FT_Error + (*FT_AutoHinter_GlyphLoadFunc)( FT_AutoHinter hinter, + FT_GlyphSlot slot, + FT_Size size, + FT_UInt glyph_index, + FT_Int32 load_flags ); + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_AutoHinter_ServiceRec */ + /* */ + /* <Description> */ + /* The auto-hinter module's interface. */ + /* */ + typedef struct FT_AutoHinter_ServiceRec_ + { + FT_AutoHinter_GlobalResetFunc reset_face; + FT_AutoHinter_GlobalGetFunc get_global_hints; + FT_AutoHinter_GlobalDoneFunc done_global_hints; + FT_AutoHinter_GlyphLoadFunc load_glyph; + + } FT_AutoHinter_ServiceRec, *FT_AutoHinter_Service; + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_AUTOHINTER_SERVICE(class_, reset_face_, get_global_hints_, \ + done_global_hints_, load_glyph_) \ + FT_CALLBACK_TABLE_DEF \ + const FT_AutoHinter_ServiceRec class_ = \ + { \ + reset_face_, get_global_hints_, done_global_hints_, load_glyph_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_AUTOHINTER_SERVICE(class_, reset_face_, get_global_hints_, \ + done_global_hints_, load_glyph_) \ + void \ + FT_Init_Class_##class_( FT_Library library, \ + FT_AutoHinter_ServiceRec* clazz) \ + { \ + FT_UNUSED(library); \ + clazz->reset_face = reset_face_; \ + clazz->get_global_hints = get_global_hints_; \ + clazz->done_global_hints = done_global_hints_; \ + clazz->load_glyph = load_glyph_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + +FT_END_HEADER + +#endif /* __AUTOHINT_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/internal/ftcalc.h b/mod/pub.mod/freetype.mod/include/freetype/internal/ftcalc.h new file mode 100644 index 0000000..f8b4324 --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/internal/ftcalc.h @@ -0,0 +1,179 @@ +/***************************************************************************/ +/* */ +/* ftcalc.h */ +/* */ +/* Arithmetic computations (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTCALC_H__ +#define __FTCALC_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_FixedSqrt */ + /* */ + /* <Description> */ + /* Computes the square root of a 16.16 fixed point value. */ + /* */ + /* <Input> */ + /* x :: The value to compute the root for. */ + /* */ + /* <Return> */ + /* The result of `sqrt(x)'. */ + /* */ + /* <Note> */ + /* This function is not very fast. */ + /* */ + FT_BASE( FT_Int32 ) + FT_SqrtFixed( FT_Int32 x ); + + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Sqrt32 */ + /* */ + /* <Description> */ + /* Computes the square root of an Int32 integer (which will be */ + /* handled as an unsigned long value). */ + /* */ + /* <Input> */ + /* x :: The value to compute the root for. */ + /* */ + /* <Return> */ + /* The result of `sqrt(x)'. */ + /* */ + FT_EXPORT( FT_Int32 ) + FT_Sqrt32( FT_Int32 x ); + +#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */ + + + /*************************************************************************/ + /* */ + /* FT_MulDiv() and FT_MulFix() are declared in freetype.h. */ + /* */ + /*************************************************************************/ + + +#ifdef TT_USE_BYTECODE_INTERPRETER + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_MulDiv_No_Round */ + /* */ + /* <Description> */ + /* A very simple function used to perform the computation `(a*b)/c' */ + /* (without rounding) with maximal accuracy (it uses a 64-bit */ + /* intermediate integer whenever necessary). */ + /* */ + /* This function isn't necessarily as fast as some processor specific */ + /* operations, but is at least completely portable. */ + /* */ + /* <Input> */ + /* a :: The first multiplier. */ + /* b :: The second multiplier. */ + /* c :: The divisor. */ + /* */ + /* <Return> */ + /* The result of `(a*b)/c'. This function never traps when trying to */ + /* divide by zero; it simply returns `MaxInt' or `MinInt' depending */ + /* on the signs of `a' and `b'. */ + /* */ + FT_BASE( FT_Long ) + FT_MulDiv_No_Round( FT_Long a, + FT_Long b, + FT_Long c ); + +#endif /* TT_USE_BYTECODE_INTERPRETER */ + + + /* + * A variant of FT_Matrix_Multiply which scales its result afterwards. + * The idea is that both `a' and `b' are scaled by factors of 10 so that + * the values are as precise as possible to get a correct result during + * the 64bit multiplication. Let `sa' and `sb' be the scaling factors of + * `a' and `b', respectively, then the scaling factor of the result is + * `sa*sb'. + */ + FT_BASE( void ) + FT_Matrix_Multiply_Scaled( const FT_Matrix* a, + FT_Matrix *b, + FT_Long scaling ); + + + /* + * A variant of FT_Vector_Transform. See comments for + * FT_Matrix_Multiply_Scaled. + */ + + FT_BASE( void ) + FT_Vector_Transform_Scaled( FT_Vector* vector, + const FT_Matrix* matrix, + FT_Long scaling ); + + + /* + * Return -1, 0, or +1, depending on the orientation of a given corner. + * We use the Cartesian coordinate system, with positive vertical values + * going upwards. The function returns +1 if the corner turns to the + * left, -1 to the right, and 0 for undecidable cases. + */ + FT_BASE( FT_Int ) + ft_corner_orientation( FT_Pos in_x, + FT_Pos in_y, + FT_Pos out_x, + FT_Pos out_y ); + + /* + * Return TRUE if a corner is flat or nearly flat. This is equivalent to + * saying that the angle difference between the `in' and `out' vectors is + * very small. + */ + FT_BASE( FT_Int ) + ft_corner_is_flat( FT_Pos in_x, + FT_Pos in_y, + FT_Pos out_x, + FT_Pos out_y ); + + +#define INT_TO_F26DOT6( x ) ( (FT_Long)(x) << 6 ) +#define INT_TO_F2DOT14( x ) ( (FT_Long)(x) << 14 ) +#define INT_TO_FIXED( x ) ( (FT_Long)(x) << 16 ) +#define F2DOT14_TO_FIXED( x ) ( (FT_Long)(x) << 2 ) +#define FLOAT_TO_FIXED( x ) ( (FT_Long)( x * 65536.0 ) ) +#define FIXED_TO_INT( x ) ( FT_RoundFix( x ) >> 16 ) + +#define ROUND_F26DOT6( x ) ( x >= 0 ? ( ( (x) + 32 ) & -64 ) \ + : ( -( ( 32 - (x) ) & -64 ) ) ) + + +FT_END_HEADER + +#endif /* __FTCALC_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/internal/ftdebug.h b/mod/pub.mod/freetype.mod/include/freetype/internal/ftdebug.h new file mode 100644 index 0000000..7baae35 --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/internal/ftdebug.h @@ -0,0 +1,250 @@ +/***************************************************************************/ +/* */ +/* ftdebug.h */ +/* */ +/* Debugging and logging component (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2004, 2006, 2007, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/* */ +/* IMPORTANT: A description of FreeType's debugging support can be */ +/* found in `docs/DEBUG.TXT'. Read it if you need to use or */ +/* understand this code. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTDEBUG_H__ +#define __FTDEBUG_H__ + + +#include <ft2build.h> +#include FT_CONFIG_CONFIG_H +#include FT_FREETYPE_H + + +FT_BEGIN_HEADER + + + /* force the definition of FT_DEBUG_LEVEL_ERROR if FT_DEBUG_LEVEL_TRACE */ + /* is already defined; this simplifies the following #ifdefs */ + /* */ +#ifdef FT_DEBUG_LEVEL_TRACE +#undef FT_DEBUG_LEVEL_ERROR +#define FT_DEBUG_LEVEL_ERROR +#endif + + + /*************************************************************************/ + /* */ + /* Define the trace enums as well as the trace levels array when they */ + /* are needed. */ + /* */ + /*************************************************************************/ + +#ifdef FT_DEBUG_LEVEL_TRACE + +#define FT_TRACE_DEF( x ) trace_ ## x , + + /* defining the enumeration */ + typedef enum FT_Trace_ + { +#include FT_INTERNAL_TRACE_H + trace_count + + } FT_Trace; + + + /* defining the array of trace levels, provided by `src/base/ftdebug.c' */ + extern int ft_trace_levels[trace_count]; + +#undef FT_TRACE_DEF + +#endif /* FT_DEBUG_LEVEL_TRACE */ + + + /*************************************************************************/ + /* */ + /* Define the FT_TRACE macro */ + /* */ + /* IMPORTANT! */ + /* */ + /* Each component must define the macro FT_COMPONENT to a valid FT_Trace */ + /* value before using any TRACE macro. */ + /* */ + /*************************************************************************/ + +#ifdef FT_DEBUG_LEVEL_TRACE + +#define FT_TRACE( level, varformat ) \ + do \ + { \ + if ( ft_trace_levels[FT_COMPONENT] >= level ) \ + FT_Message varformat; \ + } while ( 0 ) + +#else /* !FT_DEBUG_LEVEL_TRACE */ + +#define FT_TRACE( level, varformat ) do { } while ( 0 ) /* nothing */ + +#endif /* !FT_DEBUG_LEVEL_TRACE */ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Trace_Get_Count */ + /* */ + /* <Description> */ + /* Return the number of available trace components. */ + /* */ + /* <Return> */ + /* The number of trace components. 0 if FreeType 2 is not built with */ + /* FT_DEBUG_LEVEL_TRACE definition. */ + /* */ + /* <Note> */ + /* This function may be useful if you want to access elements of */ + /* the internal `ft_trace_levels' array by an index. */ + /* */ + FT_BASE( FT_Int ) + FT_Trace_Get_Count( void ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Trace_Get_Name */ + /* */ + /* <Description> */ + /* Return the name of a trace component. */ + /* */ + /* <Input> */ + /* The index of the trace component. */ + /* */ + /* <Return> */ + /* The name of the trace component. This is a statically allocated */ + /* C string, so do not free it after use. NULL if FreeType 2 is not */ + /* built with FT_DEBUG_LEVEL_TRACE definition. */ + /* */ + /* <Note> */ + /* Use @FT_Trace_Get_Count to get the number of available trace */ + /* components. */ + /* */ + /* This function may be useful if you want to control FreeType 2's */ + /* debug level in your application. */ + /* */ + FT_BASE( const char * ) + FT_Trace_Get_Name( FT_Int idx ); + + + /*************************************************************************/ + /* */ + /* You need two opening and closing parentheses! */ + /* */ + /* Example: FT_TRACE0(( "Value is %i", foo )) */ + /* */ + /* Output of the FT_TRACEX macros is sent to stderr. */ + /* */ + /*************************************************************************/ + +#define FT_TRACE0( varformat ) FT_TRACE( 0, varformat ) +#define FT_TRACE1( varformat ) FT_TRACE( 1, varformat ) +#define FT_TRACE2( varformat ) FT_TRACE( 2, varformat ) +#define FT_TRACE3( varformat ) FT_TRACE( 3, varformat ) +#define FT_TRACE4( varformat ) FT_TRACE( 4, varformat ) +#define FT_TRACE5( varformat ) FT_TRACE( 5, varformat ) +#define FT_TRACE6( varformat ) FT_TRACE( 6, varformat ) +#define FT_TRACE7( varformat ) FT_TRACE( 7, varformat ) + + + /*************************************************************************/ + /* */ + /* Define the FT_ERROR macro. */ + /* */ + /* Output of this macro is sent to stderr. */ + /* */ + /*************************************************************************/ + +#ifdef FT_DEBUG_LEVEL_ERROR + +#define FT_ERROR( varformat ) FT_Message varformat + +#else /* !FT_DEBUG_LEVEL_ERROR */ + +#define FT_ERROR( varformat ) do { } while ( 0 ) /* nothing */ + +#endif /* !FT_DEBUG_LEVEL_ERROR */ + + + /*************************************************************************/ + /* */ + /* Define the FT_ASSERT macro. */ + /* */ + /*************************************************************************/ + +#ifdef FT_DEBUG_LEVEL_ERROR + +#define FT_ASSERT( condition ) \ + do \ + { \ + if ( !( condition ) ) \ + FT_Panic( "assertion failed on line %d of file %s\n", \ + __LINE__, __FILE__ ); \ + } while ( 0 ) + +#else /* !FT_DEBUG_LEVEL_ERROR */ + +#define FT_ASSERT( condition ) do { } while ( 0 ) + +#endif /* !FT_DEBUG_LEVEL_ERROR */ + + + /*************************************************************************/ + /* */ + /* Define `FT_Message' and `FT_Panic' when needed. */ + /* */ + /*************************************************************************/ + +#ifdef FT_DEBUG_LEVEL_ERROR + +#include "stdio.h" /* for vfprintf() */ + + /* print a message */ + FT_BASE( void ) + FT_Message( const char* fmt, + ... ); + + /* print a message and exit */ + FT_BASE( void ) + FT_Panic( const char* fmt, + ... ); + +#endif /* FT_DEBUG_LEVEL_ERROR */ + + + FT_BASE( void ) + ft_debug_init( void ); + + +#if defined( _MSC_VER ) /* Visual C++ (and Intel C++) */ + + /* We disable the warning `conditional expression is constant' here */ + /* in order to compile cleanly with the maximum level of warnings. */ +#pragma warning( disable : 4127 ) + +#endif /* _MSC_VER */ + + +FT_END_HEADER + +#endif /* __FTDEBUG_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/internal/ftdriver.h b/mod/pub.mod/freetype.mod/include/freetype/internal/ftdriver.h new file mode 100644 index 0000000..1d06997 --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/internal/ftdriver.h @@ -0,0 +1,422 @@ +/***************************************************************************/ +/* */ +/* ftdriver.h */ +/* */ +/* FreeType font driver interface (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2006, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTDRIVER_H__ +#define __FTDRIVER_H__ + + +#include <ft2build.h> +#include FT_MODULE_H + + +FT_BEGIN_HEADER + + + typedef FT_Error + (*FT_Face_InitFunc)( FT_Stream stream, + FT_Face face, + FT_Int typeface_index, + FT_Int num_params, + FT_Parameter* parameters ); + + typedef void + (*FT_Face_DoneFunc)( FT_Face face ); + + + typedef FT_Error + (*FT_Size_InitFunc)( FT_Size size ); + + typedef void + (*FT_Size_DoneFunc)( FT_Size size ); + + + typedef FT_Error + (*FT_Slot_InitFunc)( FT_GlyphSlot slot ); + + typedef void + (*FT_Slot_DoneFunc)( FT_GlyphSlot slot ); + + + typedef FT_Error + (*FT_Size_RequestFunc)( FT_Size size, + FT_Size_Request req ); + + typedef FT_Error + (*FT_Size_SelectFunc)( FT_Size size, + FT_ULong size_index ); + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + + typedef FT_Error + (*FT_Size_ResetPointsFunc)( FT_Size size, + FT_F26Dot6 char_width, + FT_F26Dot6 char_height, + FT_UInt horz_resolution, + FT_UInt vert_resolution ); + + typedef FT_Error + (*FT_Size_ResetPixelsFunc)( FT_Size size, + FT_UInt pixel_width, + FT_UInt pixel_height ); + +#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */ + + typedef FT_Error + (*FT_Slot_LoadFunc)( FT_GlyphSlot slot, + FT_Size size, + FT_UInt glyph_index, + FT_Int32 load_flags ); + + + typedef FT_UInt + (*FT_CharMap_CharIndexFunc)( FT_CharMap charmap, + FT_Long charcode ); + + typedef FT_Long + (*FT_CharMap_CharNextFunc)( FT_CharMap charmap, + FT_Long charcode ); + + + typedef FT_Error + (*FT_Face_GetKerningFunc)( FT_Face face, + FT_UInt left_glyph, + FT_UInt right_glyph, + FT_Vector* kerning ); + + + typedef FT_Error + (*FT_Face_AttachFunc)( FT_Face face, + FT_Stream stream ); + + + typedef FT_Error + (*FT_Face_GetAdvancesFunc)( FT_Face face, + FT_UInt first, + FT_UInt count, + FT_Int32 flags, + FT_Fixed* advances ); + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Driver_ClassRec */ + /* */ + /* <Description> */ + /* The font driver class. This structure mostly contains pointers to */ + /* driver methods. */ + /* */ + /* <Fields> */ + /* root :: The parent module. */ + /* */ + /* face_object_size :: The size of a face object in bytes. */ + /* */ + /* size_object_size :: The size of a size object in bytes. */ + /* */ + /* slot_object_size :: The size of a glyph object in bytes. */ + /* */ + /* init_face :: The format-specific face constructor. */ + /* */ + /* done_face :: The format-specific face destructor. */ + /* */ + /* init_size :: The format-specific size constructor. */ + /* */ + /* done_size :: The format-specific size destructor. */ + /* */ + /* init_slot :: The format-specific slot constructor. */ + /* */ + /* done_slot :: The format-specific slot destructor. */ + /* */ + /* */ + /* load_glyph :: A function handle to load a glyph to a slot. */ + /* This field is mandatory! */ + /* */ + /* get_kerning :: A function handle to return the unscaled */ + /* kerning for a given pair of glyphs. Can be */ + /* set to 0 if the format doesn't support */ + /* kerning. */ + /* */ + /* attach_file :: This function handle is used to read */ + /* additional data for a face from another */ + /* file/stream. For example, this can be used to */ + /* add data from AFM or PFM files on a Type 1 */ + /* face, or a CIDMap on a CID-keyed face. */ + /* */ + /* get_advances :: A function handle used to return advance */ + /* widths of `count' glyphs (in font units), */ + /* starting at `first'. The `vertical' flag must */ + /* be set to get vertical advance heights. The */ + /* `advances' buffer is caller-allocated. */ + /* Currently not implemented. The idea of this */ + /* function is to be able to perform */ + /* device-independent text layout without loading */ + /* a single glyph image. */ + /* */ + /* request_size :: A handle to a function used to request the new */ + /* character size. Can be set to 0 if the */ + /* scaling done in the base layer suffices. */ + /* */ + /* select_size :: A handle to a function used to select a new */ + /* fixed size. It is used only if */ + /* @FT_FACE_FLAG_FIXED_SIZES is set. Can be set */ + /* to 0 if the scaling done in the base layer */ + /* suffices. */ + /* <Note> */ + /* Most function pointers, with the exception of `load_glyph', can be */ + /* set to 0 to indicate a default behaviour. */ + /* */ + typedef struct FT_Driver_ClassRec_ + { + FT_Module_Class root; + + FT_Long face_object_size; + FT_Long size_object_size; + FT_Long slot_object_size; + + FT_Face_InitFunc init_face; + FT_Face_DoneFunc done_face; + + FT_Size_InitFunc init_size; + FT_Size_DoneFunc done_size; + + FT_Slot_InitFunc init_slot; + FT_Slot_DoneFunc done_slot; + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + + FT_Size_ResetPointsFunc set_char_sizes; + FT_Size_ResetPixelsFunc set_pixel_sizes; + +#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */ + + FT_Slot_LoadFunc load_glyph; + + FT_Face_GetKerningFunc get_kerning; + FT_Face_AttachFunc attach_file; + FT_Face_GetAdvancesFunc get_advances; + + /* since version 2.2 */ + FT_Size_RequestFunc request_size; + FT_Size_SelectFunc select_size; + + } FT_Driver_ClassRec, *FT_Driver_Class; + + + /* + * The following functions are used as stubs for `set_char_sizes' and + * `set_pixel_sizes'; the code uses `request_size' and `select_size' + * functions instead. + * + * Implementation is in `src/base/ftobjs.c'. + */ +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + + FT_BASE( FT_Error ) + ft_stub_set_char_sizes( FT_Size size, + FT_F26Dot6 width, + FT_F26Dot6 height, + FT_UInt horz_res, + FT_UInt vert_res ); + + FT_BASE( FT_Error ) + ft_stub_set_pixel_sizes( FT_Size size, + FT_UInt width, + FT_UInt height ); + +#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */ + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_DECLARE_DRIVER */ + /* */ + /* <Description> */ + /* Used to create a forward declaration of a */ + /* FT_Driver_ClassRec stract instance. */ + /* */ + /* <Macro> */ + /* FT_DEFINE_DRIVER */ + /* */ + /* <Description> */ + /* Used to initialize an instance of FT_Driver_ClassRec struct. */ + /* */ + /* When FT_CONFIG_OPTION_PIC is defined a Create funtion will need */ + /* to called with a pointer where the allocated stracture is returned.*/ + /* And when it is no longer needed a Destroy function needs */ + /* to be called to release that allocation. */ + /* fcinit.c (ft_create_default_module_classes) already contains */ + /* a mechanism to call these functions for the default modules */ + /* described in ftmodule.h */ + /* */ + /* Notice that the created Create and Destroy functions call */ + /* pic_init and pic_free function to allow you to manually allocate */ + /* and initialize any additional global data, like module specific */ + /* interface, and put them in the global pic container defined in */ + /* ftpic.h. if you don't need them just implement the functions as */ + /* empty to resolve the link error. */ + /* */ + /* When FT_CONFIG_OPTION_PIC is not defined the struct will be */ + /* allocated in the global scope (or the scope where the macro */ + /* is used). */ + /* */ +#ifndef FT_CONFIG_OPTION_PIC + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS +#define FT_DEFINE_DRIVERS_OLD_INTERNALS(a_,b_) \ + a_, b_, +#else + #define FT_DEFINE_DRIVERS_OLD_INTERNALS(a_,b_) +#endif + +#define FT_DECLARE_DRIVER(class_) \ + FT_CALLBACK_TABLE \ + const FT_Driver_ClassRec class_; + +#define FT_DEFINE_DRIVER(class_, \ + flags_, size_, name_, version_, requires_, \ + interface_, init_, done_, get_interface_, \ + face_object_size_, size_object_size_, \ + slot_object_size_, init_face_, done_face_, \ + init_size_, done_size_, init_slot_, done_slot_, \ + old_set_char_sizes_, old_set_pixel_sizes_, \ + load_glyph_, get_kerning_, attach_file_, \ + get_advances_, request_size_, select_size_ ) \ + FT_CALLBACK_TABLE_DEF \ + const FT_Driver_ClassRec class_ = \ + { \ + FT_DEFINE_ROOT_MODULE(flags_,size_,name_,version_,requires_,interface_, \ + init_,done_,get_interface_) \ + \ + face_object_size_, \ + size_object_size_, \ + slot_object_size_, \ + \ + init_face_, \ + done_face_, \ + \ + init_size_, \ + done_size_, \ + \ + init_slot_, \ + done_slot_, \ + \ + FT_DEFINE_DRIVERS_OLD_INTERNALS(old_set_char_sizes_, old_set_pixel_sizes_) \ + \ + load_glyph_, \ + \ + get_kerning_, \ + attach_file_, \ + get_advances_, \ + \ + request_size_, \ + select_size_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS +#define FT_DEFINE_DRIVERS_OLD_INTERNALS(a_,b_) \ + clazz->set_char_sizes = a_; \ + clazz->set_pixel_sizes = b_; +#else + #define FT_DEFINE_DRIVERS_OLD_INTERNALS(a_,b_) +#endif + +#define FT_DECLARE_DRIVER(class_) FT_DECLARE_MODULE(class_) + +#define FT_DEFINE_DRIVER(class_, \ + flags_, size_, name_, version_, requires_, \ + interface_, init_, done_, get_interface_, \ + face_object_size_, size_object_size_, \ + slot_object_size_, init_face_, done_face_, \ + init_size_, done_size_, init_slot_, done_slot_, \ + old_set_char_sizes_, old_set_pixel_sizes_, \ + load_glyph_, get_kerning_, attach_file_, \ + get_advances_, request_size_, select_size_ ) \ + void class_##_pic_free( FT_Library library ); \ + FT_Error class_##_pic_init( FT_Library library ); \ + \ + void \ + FT_Destroy_Class_##class_( FT_Library library, \ + FT_Module_Class* clazz ) \ + { \ + FT_Memory memory = library->memory; \ + FT_Driver_Class dclazz = (FT_Driver_Class)clazz; \ + class_##_pic_free( library ); \ + if ( dclazz ) \ + FT_FREE( dclazz ); \ + } \ + \ + FT_Error \ + FT_Create_Class_##class_( FT_Library library, \ + FT_Module_Class** output_class ) \ + { \ + FT_Driver_Class clazz; \ + FT_Error error; \ + FT_Memory memory = library->memory; \ + \ + if ( FT_ALLOC( clazz, sizeof(*clazz) ) ) \ + return error; \ + \ + error = class_##_pic_init( library ); \ + if(error) \ + { \ + FT_FREE( clazz ); \ + return error; \ + } \ + \ + FT_DEFINE_ROOT_MODULE(flags_,size_,name_,version_,requires_,interface_, \ + init_,done_,get_interface_) \ + \ + clazz->face_object_size = face_object_size_; \ + clazz->size_object_size = size_object_size_; \ + clazz->slot_object_size = slot_object_size_; \ + \ + clazz->init_face = init_face_; \ + clazz->done_face = done_face_; \ + \ + clazz->init_size = init_size_; \ + clazz->done_size = done_size_; \ + \ + clazz->init_slot = init_slot_; \ + clazz->done_slot = done_slot_; \ + \ + FT_DEFINE_DRIVERS_OLD_INTERNALS(old_set_char_sizes_, old_set_pixel_sizes_) \ + \ + clazz->load_glyph = load_glyph_; \ + \ + clazz->get_kerning = get_kerning_; \ + clazz->attach_file = attach_file_; \ + clazz->get_advances = get_advances_; \ + \ + clazz->request_size = request_size_; \ + clazz->select_size = select_size_; \ + \ + *output_class = (FT_Module_Class*)clazz; \ + return FT_Err_Ok; \ + } + + +#endif /* FT_CONFIG_OPTION_PIC */ + +FT_END_HEADER + +#endif /* __FTDRIVER_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/internal/ftgloadr.h b/mod/pub.mod/freetype.mod/include/freetype/internal/ftgloadr.h new file mode 100644 index 0000000..ce4dc6c --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/internal/ftgloadr.h @@ -0,0 +1,168 @@ +/***************************************************************************/ +/* */ +/* ftgloadr.h */ +/* */ +/* The FreeType glyph loader (specification). */ +/* */ +/* Copyright 2002, 2003, 2005, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTGLOADR_H__ +#define __FTGLOADR_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_GlyphLoader */ + /* */ + /* <Description> */ + /* The glyph loader is an internal object used to load several glyphs */ + /* together (for example, in the case of composites). */ + /* */ + /* <Note> */ + /* The glyph loader implementation is not part of the high-level API, */ + /* hence the forward structure declaration. */ + /* */ + typedef struct FT_GlyphLoaderRec_* FT_GlyphLoader ; + + +#if 0 /* moved to freetype.h in version 2.2 */ +#define FT_SUBGLYPH_FLAG_ARGS_ARE_WORDS 1 +#define FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES 2 +#define FT_SUBGLYPH_FLAG_ROUND_XY_TO_GRID 4 +#define FT_SUBGLYPH_FLAG_SCALE 8 +#define FT_SUBGLYPH_FLAG_XY_SCALE 0x40 +#define FT_SUBGLYPH_FLAG_2X2 0x80 +#define FT_SUBGLYPH_FLAG_USE_MY_METRICS 0x200 +#endif + + + typedef struct FT_SubGlyphRec_ + { + FT_Int index; + FT_UShort flags; + FT_Int arg1; + FT_Int arg2; + FT_Matrix transform; + + } FT_SubGlyphRec; + + + typedef struct FT_GlyphLoadRec_ + { + FT_Outline outline; /* outline */ + FT_Vector* extra_points; /* extra points table */ + FT_Vector* extra_points2; /* second extra points table */ + FT_UInt num_subglyphs; /* number of subglyphs */ + FT_SubGlyph subglyphs; /* subglyphs */ + + } FT_GlyphLoadRec, *FT_GlyphLoad; + + + typedef struct FT_GlyphLoaderRec_ + { + FT_Memory memory; + FT_UInt max_points; + FT_UInt max_contours; + FT_UInt max_subglyphs; + FT_Bool use_extra; + + FT_GlyphLoadRec base; + FT_GlyphLoadRec current; + + void* other; /* for possible future extension? */ + + } FT_GlyphLoaderRec; + + + /* create new empty glyph loader */ + FT_BASE( FT_Error ) + FT_GlyphLoader_New( FT_Memory memory, + FT_GlyphLoader *aloader ); + + /* add an extra points table to a glyph loader */ + FT_BASE( FT_Error ) + FT_GlyphLoader_CreateExtra( FT_GlyphLoader loader ); + + /* destroy a glyph loader */ + FT_BASE( void ) + FT_GlyphLoader_Done( FT_GlyphLoader loader ); + + /* reset a glyph loader (frees everything int it) */ + FT_BASE( void ) + FT_GlyphLoader_Reset( FT_GlyphLoader loader ); + + /* rewind a glyph loader */ + FT_BASE( void ) + FT_GlyphLoader_Rewind( FT_GlyphLoader loader ); + + /* check that there is enough space to add `n_points' and `n_contours' */ + /* to the glyph loader */ + FT_BASE( FT_Error ) + FT_GlyphLoader_CheckPoints( FT_GlyphLoader loader, + FT_UInt n_points, + FT_UInt n_contours ); + + +#define FT_GLYPHLOADER_CHECK_P( _loader, _count ) \ + ( (_count) == 0 || ((_loader)->base.outline.n_points + \ + (_loader)->current.outline.n_points + \ + (unsigned long)(_count)) <= (_loader)->max_points ) + +#define FT_GLYPHLOADER_CHECK_C( _loader, _count ) \ + ( (_count) == 0 || ((_loader)->base.outline.n_contours + \ + (_loader)->current.outline.n_contours + \ + (unsigned long)(_count)) <= (_loader)->max_contours ) + +#define FT_GLYPHLOADER_CHECK_POINTS( _loader, _points,_contours ) \ + ( ( FT_GLYPHLOADER_CHECK_P( _loader, _points ) && \ + FT_GLYPHLOADER_CHECK_C( _loader, _contours ) ) \ + ? 0 \ + : FT_GlyphLoader_CheckPoints( (_loader), (_points), (_contours) ) ) + + + /* check that there is enough space to add `n_subs' sub-glyphs to */ + /* a glyph loader */ + FT_BASE( FT_Error ) + FT_GlyphLoader_CheckSubGlyphs( FT_GlyphLoader loader, + FT_UInt n_subs ); + + /* prepare a glyph loader, i.e. empty the current glyph */ + FT_BASE( void ) + FT_GlyphLoader_Prepare( FT_GlyphLoader loader ); + + /* add the current glyph to the base glyph */ + FT_BASE( void ) + FT_GlyphLoader_Add( FT_GlyphLoader loader ); + + /* copy points from one glyph loader to another */ + FT_BASE( FT_Error ) + FT_GlyphLoader_CopyPoints( FT_GlyphLoader target, + FT_GlyphLoader source ); + + /* */ + + +FT_END_HEADER + +#endif /* __FTGLOADR_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/internal/ftmemory.h b/mod/pub.mod/freetype.mod/include/freetype/internal/ftmemory.h new file mode 100644 index 0000000..2010ca9 --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/internal/ftmemory.h @@ -0,0 +1,368 @@ +/***************************************************************************/ +/* */ +/* ftmemory.h */ +/* */ +/* The FreeType memory management macros (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2004, 2005, 2006, 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTMEMORY_H__ +#define __FTMEMORY_H__ + + +#include <ft2build.h> +#include FT_CONFIG_CONFIG_H +#include FT_TYPES_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_SET_ERROR */ + /* */ + /* <Description> */ + /* This macro is used to set an implicit `error' variable to a given */ + /* expression's value (usually a function call), and convert it to a */ + /* boolean which is set whenever the value is != 0. */ + /* */ +#undef FT_SET_ERROR +#define FT_SET_ERROR( expression ) \ + ( ( error = (expression) ) != 0 ) + + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** M E M O R Y ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /* + * C++ refuses to handle statements like p = (void*)anything; where `p' + * is a typed pointer. Since we don't have a `typeof' operator in + * standard C++, we have to use ugly casts. + */ + +#ifdef __cplusplus +#define FT_ASSIGNP( p, val ) *((void**)&(p)) = (val) +#else +#define FT_ASSIGNP( p, val ) (p) = (val) +#endif + + + +#ifdef FT_DEBUG_MEMORY + + FT_BASE( const char* ) _ft_debug_file; + FT_BASE( long ) _ft_debug_lineno; + +#define FT_DEBUG_INNER( exp ) ( _ft_debug_file = __FILE__, \ + _ft_debug_lineno = __LINE__, \ + (exp) ) + +#define FT_ASSIGNP_INNER( p, exp ) ( _ft_debug_file = __FILE__, \ + _ft_debug_lineno = __LINE__, \ + FT_ASSIGNP( p, exp ) ) + +#else /* !FT_DEBUG_MEMORY */ + +#define FT_DEBUG_INNER( exp ) (exp) +#define FT_ASSIGNP_INNER( p, exp ) FT_ASSIGNP( p, exp ) + +#endif /* !FT_DEBUG_MEMORY */ + + + /* + * The allocation functions return a pointer, and the error code + * is written to through the `p_error' parameter. See below for + * for documentation. + */ + + FT_BASE( FT_Pointer ) + ft_mem_alloc( FT_Memory memory, + FT_Long size, + FT_Error *p_error ); + + FT_BASE( FT_Pointer ) + ft_mem_qalloc( FT_Memory memory, + FT_Long size, + FT_Error *p_error ); + + FT_BASE( FT_Pointer ) + ft_mem_realloc( FT_Memory memory, + FT_Long item_size, + FT_Long cur_count, + FT_Long new_count, + void* block, + FT_Error *p_error ); + + FT_BASE( FT_Pointer ) + ft_mem_qrealloc( FT_Memory memory, + FT_Long item_size, + FT_Long cur_count, + FT_Long new_count, + void* block, + FT_Error *p_error ); + + FT_BASE( void ) + ft_mem_free( FT_Memory memory, + const void* P ); + + +#define FT_MEM_ALLOC( ptr, size ) \ + FT_ASSIGNP_INNER( ptr, ft_mem_alloc( memory, (size), &error ) ) + +#define FT_MEM_FREE( ptr ) \ + FT_BEGIN_STMNT \ + ft_mem_free( memory, (ptr) ); \ + (ptr) = NULL; \ + FT_END_STMNT + +#define FT_MEM_NEW( ptr ) \ + FT_MEM_ALLOC( ptr, sizeof ( *(ptr) ) ) + +#define FT_MEM_REALLOC( ptr, cursz, newsz ) \ + FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, 1, \ + (cursz), (newsz), \ + (ptr), &error ) ) + +#define FT_MEM_QALLOC( ptr, size ) \ + FT_ASSIGNP_INNER( ptr, ft_mem_qalloc( memory, (size), &error ) ) + +#define FT_MEM_QNEW( ptr ) \ + FT_MEM_QALLOC( ptr, sizeof ( *(ptr) ) ) + +#define FT_MEM_QREALLOC( ptr, cursz, newsz ) \ + FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, 1, \ + (cursz), (newsz), \ + (ptr), &error ) ) + +#define FT_MEM_QRENEW_ARRAY( ptr, cursz, newsz ) \ + FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, sizeof ( *(ptr) ), \ + (cursz), (newsz), \ + (ptr), &error ) ) + +#define FT_MEM_ALLOC_MULT( ptr, count, item_size ) \ + FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, (item_size), \ + 0, (count), \ + NULL, &error ) ) + +#define FT_MEM_REALLOC_MULT( ptr, oldcnt, newcnt, itmsz ) \ + FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, (itmsz), \ + (oldcnt), (newcnt), \ + (ptr), &error ) ) + +#define FT_MEM_QALLOC_MULT( ptr, count, item_size ) \ + FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, (item_size), \ + 0, (count), \ + NULL, &error ) ) + +#define FT_MEM_QREALLOC_MULT( ptr, oldcnt, newcnt, itmsz) \ + FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, (itmsz), \ + (oldcnt), (newcnt), \ + (ptr), &error ) ) + + +#define FT_MEM_SET_ERROR( cond ) ( (cond), error != 0 ) + + +#define FT_MEM_SET( dest, byte, count ) ft_memset( dest, byte, count ) + +#define FT_MEM_COPY( dest, source, count ) ft_memcpy( dest, source, count ) + +#define FT_MEM_MOVE( dest, source, count ) ft_memmove( dest, source, count ) + + +#define FT_MEM_ZERO( dest, count ) FT_MEM_SET( dest, 0, count ) + +#define FT_ZERO( p ) FT_MEM_ZERO( p, sizeof ( *(p) ) ) + + +#define FT_ARRAY_ZERO( dest, count ) \ + FT_MEM_ZERO( dest, (count) * sizeof ( *(dest) ) ) + +#define FT_ARRAY_COPY( dest, source, count ) \ + FT_MEM_COPY( dest, source, (count) * sizeof ( *(dest) ) ) + +#define FT_ARRAY_MOVE( dest, source, count ) \ + FT_MEM_MOVE( dest, source, (count) * sizeof ( *(dest) ) ) + + + /* + * Return the maximum number of addressable elements in an array. + * We limit ourselves to INT_MAX, rather than UINT_MAX, to avoid + * any problems. + */ +#define FT_ARRAY_MAX( ptr ) ( FT_INT_MAX / sizeof ( *(ptr) ) ) + +#define FT_ARRAY_CHECK( ptr, count ) ( (count) <= FT_ARRAY_MAX( ptr ) ) + + + /*************************************************************************/ + /* */ + /* The following functions macros expect that their pointer argument is */ + /* _typed_ in order to automatically compute array element sizes. */ + /* */ + +#define FT_MEM_NEW_ARRAY( ptr, count ) \ + FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, sizeof ( *(ptr) ), \ + 0, (count), \ + NULL, &error ) ) + +#define FT_MEM_RENEW_ARRAY( ptr, cursz, newsz ) \ + FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, sizeof ( *(ptr) ), \ + (cursz), (newsz), \ + (ptr), &error ) ) + +#define FT_MEM_QNEW_ARRAY( ptr, count ) \ + FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, sizeof ( *(ptr) ), \ + 0, (count), \ + NULL, &error ) ) + +#define FT_MEM_QRENEW_ARRAY( ptr, cursz, newsz ) \ + FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, sizeof ( *(ptr) ), \ + (cursz), (newsz), \ + (ptr), &error ) ) + + +#define FT_ALLOC( ptr, size ) \ + FT_MEM_SET_ERROR( FT_MEM_ALLOC( ptr, size ) ) + +#define FT_REALLOC( ptr, cursz, newsz ) \ + FT_MEM_SET_ERROR( FT_MEM_REALLOC( ptr, cursz, newsz ) ) + +#define FT_ALLOC_MULT( ptr, count, item_size ) \ + FT_MEM_SET_ERROR( FT_MEM_ALLOC_MULT( ptr, count, item_size ) ) + +#define FT_REALLOC_MULT( ptr, oldcnt, newcnt, itmsz ) \ + FT_MEM_SET_ERROR( FT_MEM_REALLOC_MULT( ptr, oldcnt, \ + newcnt, itmsz ) ) + +#define FT_QALLOC( ptr, size ) \ + FT_MEM_SET_ERROR( FT_MEM_QALLOC( ptr, size ) ) + +#define FT_QREALLOC( ptr, cursz, newsz ) \ + FT_MEM_SET_ERROR( FT_MEM_QREALLOC( ptr, cursz, newsz ) ) + +#define FT_QALLOC_MULT( ptr, count, item_size ) \ + FT_MEM_SET_ERROR( FT_MEM_QALLOC_MULT( ptr, count, item_size ) ) + +#define FT_QREALLOC_MULT( ptr, oldcnt, newcnt, itmsz ) \ + FT_MEM_SET_ERROR( FT_MEM_QREALLOC_MULT( ptr, oldcnt, \ + newcnt, itmsz ) ) + +#define FT_FREE( ptr ) FT_MEM_FREE( ptr ) + +#define FT_NEW( ptr ) FT_MEM_SET_ERROR( FT_MEM_NEW( ptr ) ) + +#define FT_NEW_ARRAY( ptr, count ) \ + FT_MEM_SET_ERROR( FT_MEM_NEW_ARRAY( ptr, count ) ) + +#define FT_RENEW_ARRAY( ptr, curcnt, newcnt ) \ + FT_MEM_SET_ERROR( FT_MEM_RENEW_ARRAY( ptr, curcnt, newcnt ) ) + +#define FT_QNEW( ptr ) \ + FT_MEM_SET_ERROR( FT_MEM_QNEW( ptr ) ) + +#define FT_QNEW_ARRAY( ptr, count ) \ + FT_MEM_SET_ERROR( FT_MEM_NEW_ARRAY( ptr, count ) ) + +#define FT_QRENEW_ARRAY( ptr, curcnt, newcnt ) \ + FT_MEM_SET_ERROR( FT_MEM_RENEW_ARRAY( ptr, curcnt, newcnt ) ) + + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + + FT_BASE( FT_Error ) + FT_Alloc( FT_Memory memory, + FT_Long size, + void* *P ); + + FT_BASE( FT_Error ) + FT_QAlloc( FT_Memory memory, + FT_Long size, + void* *p ); + + FT_BASE( FT_Error ) + FT_Realloc( FT_Memory memory, + FT_Long current, + FT_Long size, + void* *P ); + + FT_BASE( FT_Error ) + FT_QRealloc( FT_Memory memory, + FT_Long current, + FT_Long size, + void* *p ); + + FT_BASE( void ) + FT_Free( FT_Memory memory, + void* *P ); + +#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */ + + + FT_BASE( FT_Pointer ) + ft_mem_strdup( FT_Memory memory, + const char* str, + FT_Error *p_error ); + + FT_BASE( FT_Pointer ) + ft_mem_dup( FT_Memory memory, + const void* address, + FT_ULong size, + FT_Error *p_error ); + +#define FT_MEM_STRDUP( dst, str ) \ + (dst) = (char*)ft_mem_strdup( memory, (const char*)(str), &error ) + +#define FT_STRDUP( dst, str ) \ + FT_MEM_SET_ERROR( FT_MEM_STRDUP( dst, str ) ) + +#define FT_MEM_DUP( dst, address, size ) \ + (dst) = ft_mem_dup( memory, (address), (FT_ULong)(size), &error ) + +#define FT_DUP( dst, address, size ) \ + FT_MEM_SET_ERROR( FT_MEM_DUP( dst, address, size ) ) + + + /* Return >= 1 if a truncation occurs. */ + /* Return 0 if the source string fits the buffer. */ + /* This is *not* the same as strlcpy(). */ + FT_BASE( FT_Int ) + ft_mem_strcpyn( char* dst, + const char* src, + FT_ULong size ); + +#define FT_STRCPYN( dst, src, size ) \ + ft_mem_strcpyn( (char*)dst, (const char*)(src), (FT_ULong)(size) ) + + /* */ + + +FT_END_HEADER + +#endif /* __FTMEMORY_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/internal/ftobjs.h b/mod/pub.mod/freetype.mod/include/freetype/internal/ftobjs.h new file mode 100644 index 0000000..574cf58 --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/internal/ftobjs.h @@ -0,0 +1,1401 @@ +/***************************************************************************/ +/* */ +/* ftobjs.h */ +/* */ +/* The FreeType private base classes (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file contains the definition of all internal FreeType classes. */ + /* */ + /*************************************************************************/ + + +#ifndef __FTOBJS_H__ +#define __FTOBJS_H__ + +#include <ft2build.h> +#include FT_RENDER_H +#include FT_SIZES_H +#include FT_LCD_FILTER_H +#include FT_INTERNAL_MEMORY_H +#include FT_INTERNAL_GLYPH_LOADER_H +#include FT_INTERNAL_DRIVER_H +#include FT_INTERNAL_AUTOHINT_H +#include FT_INTERNAL_SERVICE_H +#include FT_INTERNAL_PIC_H + +#ifdef FT_CONFIG_OPTION_INCREMENTAL +#include FT_INCREMENTAL_H +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* Some generic definitions. */ + /* */ +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef NULL +#define NULL (void*)0 +#endif + + + /*************************************************************************/ + /* */ + /* The min and max functions missing in C. As usual, be careful not to */ + /* write things like FT_MIN( a++, b++ ) to avoid side effects. */ + /* */ +#define FT_MIN( a, b ) ( (a) < (b) ? (a) : (b) ) +#define FT_MAX( a, b ) ( (a) > (b) ? (a) : (b) ) + +#define FT_ABS( a ) ( (a) < 0 ? -(a) : (a) ) + + +#define FT_PAD_FLOOR( x, n ) ( (x) & ~((n)-1) ) +#define FT_PAD_ROUND( x, n ) FT_PAD_FLOOR( (x) + ((n)/2), n ) +#define FT_PAD_CEIL( x, n ) FT_PAD_FLOOR( (x) + ((n)-1), n ) + +#define FT_PIX_FLOOR( x ) ( (x) & ~63 ) +#define FT_PIX_ROUND( x ) FT_PIX_FLOOR( (x) + 32 ) +#define FT_PIX_CEIL( x ) FT_PIX_FLOOR( (x) + 63 ) + + + /* + * Return the highest power of 2 that is <= value; this correspond to + * the highest bit in a given 32-bit value. + */ + FT_BASE( FT_UInt32 ) + ft_highpow2( FT_UInt32 value ); + + + /* + * character classification functions -- since these are used to parse + * font files, we must not use those in <ctypes.h> which are + * locale-dependent + */ +#define ft_isdigit( x ) ( ( (unsigned)(x) - '0' ) < 10U ) + +#define ft_isxdigit( x ) ( ( (unsigned)(x) - '0' ) < 10U || \ + ( (unsigned)(x) - 'a' ) < 6U || \ + ( (unsigned)(x) - 'A' ) < 6U ) + + /* the next two macros assume ASCII representation */ +#define ft_isupper( x ) ( ( (unsigned)(x) - 'A' ) < 26U ) +#define ft_islower( x ) ( ( (unsigned)(x) - 'a' ) < 26U ) + +#define ft_isalpha( x ) ( ft_isupper( x ) || ft_islower( x ) ) +#define ft_isalnum( x ) ( ft_isdigit( x ) || ft_isalpha( x ) ) + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** C H A R M A P S ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + /* handle to internal charmap object */ + typedef struct FT_CMapRec_* FT_CMap; + + /* handle to charmap class structure */ + typedef const struct FT_CMap_ClassRec_* FT_CMap_Class; + + /* internal charmap object structure */ + typedef struct FT_CMapRec_ + { + FT_CharMapRec charmap; + FT_CMap_Class clazz; + + } FT_CMapRec; + + /* typecase any pointer to a charmap handle */ +#define FT_CMAP( x ) ((FT_CMap)( x )) + + /* obvious macros */ +#define FT_CMAP_PLATFORM_ID( x ) FT_CMAP( x )->charmap.platform_id +#define FT_CMAP_ENCODING_ID( x ) FT_CMAP( x )->charmap.encoding_id +#define FT_CMAP_ENCODING( x ) FT_CMAP( x )->charmap.encoding +#define FT_CMAP_FACE( x ) FT_CMAP( x )->charmap.face + + + /* class method definitions */ + typedef FT_Error + (*FT_CMap_InitFunc)( FT_CMap cmap, + FT_Pointer init_data ); + + typedef void + (*FT_CMap_DoneFunc)( FT_CMap cmap ); + + typedef FT_UInt + (*FT_CMap_CharIndexFunc)( FT_CMap cmap, + FT_UInt32 char_code ); + + typedef FT_UInt + (*FT_CMap_CharNextFunc)( FT_CMap cmap, + FT_UInt32 *achar_code ); + + typedef FT_UInt + (*FT_CMap_CharVarIndexFunc)( FT_CMap cmap, + FT_CMap unicode_cmap, + FT_UInt32 char_code, + FT_UInt32 variant_selector ); + + typedef FT_Bool + (*FT_CMap_CharVarIsDefaultFunc)( FT_CMap cmap, + FT_UInt32 char_code, + FT_UInt32 variant_selector ); + + typedef FT_UInt32 * + (*FT_CMap_VariantListFunc)( FT_CMap cmap, + FT_Memory mem ); + + typedef FT_UInt32 * + (*FT_CMap_CharVariantListFunc)( FT_CMap cmap, + FT_Memory mem, + FT_UInt32 char_code ); + + typedef FT_UInt32 * + (*FT_CMap_VariantCharListFunc)( FT_CMap cmap, + FT_Memory mem, + FT_UInt32 variant_selector ); + + + typedef struct FT_CMap_ClassRec_ + { + FT_ULong size; + FT_CMap_InitFunc init; + FT_CMap_DoneFunc done; + FT_CMap_CharIndexFunc char_index; + FT_CMap_CharNextFunc char_next; + + /* Subsequent entries are special ones for format 14 -- the variant */ + /* selector subtable which behaves like no other */ + + FT_CMap_CharVarIndexFunc char_var_index; + FT_CMap_CharVarIsDefaultFunc char_var_default; + FT_CMap_VariantListFunc variant_list; + FT_CMap_CharVariantListFunc charvariant_list; + FT_CMap_VariantCharListFunc variantchar_list; + + } FT_CMap_ClassRec; + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DECLARE_CMAP_CLASS(class_) \ + FT_CALLBACK_TABLE const FT_CMap_ClassRec class_; + +#define FT_DEFINE_CMAP_CLASS(class_, size_, init_, done_, char_index_, \ + char_next_, char_var_index_, char_var_default_, variant_list_, \ + charvariant_list_, variantchar_list_) \ + FT_CALLBACK_TABLE_DEF \ + const FT_CMap_ClassRec class_ = \ + { \ + size_, init_, done_, char_index_, char_next_, char_var_index_, \ + char_var_default_, variant_list_, charvariant_list_, variantchar_list_ \ + }; +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DECLARE_CMAP_CLASS(class_) \ + void FT_Init_Class_##class_( FT_Library library, FT_CMap_ClassRec* clazz); + +#define FT_DEFINE_CMAP_CLASS(class_, size_, init_, done_, char_index_, \ + char_next_, char_var_index_, char_var_default_, variant_list_, \ + charvariant_list_, variantchar_list_) \ + void \ + FT_Init_Class_##class_( FT_Library library, \ + FT_CMap_ClassRec* clazz) \ + { \ + FT_UNUSED(library); \ + clazz->size = size_; \ + clazz->init = init_; \ + clazz->done = done_; \ + clazz->char_index = char_index_; \ + clazz->char_next = char_next_; \ + clazz->char_var_index = char_var_index_; \ + clazz->char_var_default = char_var_default_; \ + clazz->variant_list = variant_list_; \ + clazz->charvariant_list = charvariant_list_; \ + clazz->variantchar_list = variantchar_list_; \ + } +#endif /* FT_CONFIG_OPTION_PIC */ + + /* create a new charmap and add it to charmap->face */ + FT_BASE( FT_Error ) + FT_CMap_New( FT_CMap_Class clazz, + FT_Pointer init_data, + FT_CharMap charmap, + FT_CMap *acmap ); + + /* destroy a charmap and remove it from face's list */ + FT_BASE( void ) + FT_CMap_Done( FT_CMap cmap ); + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Face_InternalRec */ + /* */ + /* <Description> */ + /* This structure contains the internal fields of each FT_Face */ + /* object. These fields may change between different releases of */ + /* FreeType. */ + /* */ + /* <Fields> */ + /* max_points :: */ + /* The maximal number of points used to store the vectorial outline */ + /* of any glyph in this face. If this value cannot be known in */ + /* advance, or if the face isn't scalable, this should be set to 0. */ + /* Only relevant for scalable formats. */ + /* */ + /* max_contours :: */ + /* The maximal number of contours used to store the vectorial */ + /* outline of any glyph in this face. If this value cannot be */ + /* known in advance, or if the face isn't scalable, this should be */ + /* set to 0. Only relevant for scalable formats. */ + /* */ + /* transform_matrix :: */ + /* A 2x2 matrix of 16.16 coefficients used to transform glyph */ + /* outlines after they are loaded from the font. Only used by the */ + /* convenience functions. */ + /* */ + /* transform_delta :: */ + /* A translation vector used to transform glyph outlines after they */ + /* are loaded from the font. Only used by the convenience */ + /* functions. */ + /* */ + /* transform_flags :: */ + /* Some flags used to classify the transform. Only used by the */ + /* convenience functions. */ + /* */ + /* services :: */ + /* A cache for frequently used services. It should be only */ + /* accessed with the macro `FT_FACE_LOOKUP_SERVICE'. */ + /* */ + /* incremental_interface :: */ + /* If non-null, the interface through which glyph data and metrics */ + /* are loaded incrementally for faces that do not provide all of */ + /* this data when first opened. This field exists only if */ + /* @FT_CONFIG_OPTION_INCREMENTAL is defined. */ + /* */ + /* ignore_unpatented_hinter :: */ + /* This boolean flag instructs the glyph loader to ignore the */ + /* native font hinter, if one is found. This is exclusively used */ + /* in the case when the unpatented hinter is compiled within the */ + /* library. */ + /* */ + typedef struct FT_Face_InternalRec_ + { +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + FT_UShort reserved1; + FT_Short reserved2; +#endif + FT_Matrix transform_matrix; + FT_Vector transform_delta; + FT_Int transform_flags; + + FT_ServiceCacheRec services; + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + FT_Incremental_InterfaceRec* incremental_interface; +#endif + + FT_Bool ignore_unpatented_hinter; + + } FT_Face_InternalRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Slot_InternalRec */ + /* */ + /* <Description> */ + /* This structure contains the internal fields of each FT_GlyphSlot */ + /* object. These fields may change between different releases of */ + /* FreeType. */ + /* */ + /* <Fields> */ + /* loader :: The glyph loader object used to load outlines */ + /* into the glyph slot. */ + /* */ + /* flags :: Possible values are zero or */ + /* FT_GLYPH_OWN_BITMAP. The latter indicates */ + /* that the FT_GlyphSlot structure owns the */ + /* bitmap buffer. */ + /* */ + /* glyph_transformed :: Boolean. Set to TRUE when the loaded glyph */ + /* must be transformed through a specific */ + /* font transformation. This is _not_ the same */ + /* as the face transform set through */ + /* FT_Set_Transform(). */ + /* */ + /* glyph_matrix :: The 2x2 matrix corresponding to the glyph */ + /* transformation, if necessary. */ + /* */ + /* glyph_delta :: The 2d translation vector corresponding to */ + /* the glyph transformation, if necessary. */ + /* */ + /* glyph_hints :: Format-specific glyph hints management. */ + /* */ + +#define FT_GLYPH_OWN_BITMAP 0x1 + + typedef struct FT_Slot_InternalRec_ + { + FT_GlyphLoader loader; + FT_UInt flags; + FT_Bool glyph_transformed; + FT_Matrix glyph_matrix; + FT_Vector glyph_delta; + void* glyph_hints; + + } FT_GlyphSlot_InternalRec; + + +#if 0 + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Size_InternalRec */ + /* */ + /* <Description> */ + /* This structure contains the internal fields of each FT_Size */ + /* object. Currently, it's empty. */ + /* */ + /*************************************************************************/ + + typedef struct FT_Size_InternalRec_ + { + /* empty */ + + } FT_Size_InternalRec; + +#endif + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** M O D U L E S ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_ModuleRec */ + /* */ + /* <Description> */ + /* A module object instance. */ + /* */ + /* <Fields> */ + /* clazz :: A pointer to the module's class. */ + /* */ + /* library :: A handle to the parent library object. */ + /* */ + /* memory :: A handle to the memory manager. */ + /* */ + /* generic :: A generic structure for user-level extensibility (?). */ + /* */ + typedef struct FT_ModuleRec_ + { + FT_Module_Class* clazz; + FT_Library library; + FT_Memory memory; + FT_Generic generic; + + } FT_ModuleRec; + + + /* typecast an object to a FT_Module */ +#define FT_MODULE( x ) ((FT_Module)( x )) +#define FT_MODULE_CLASS( x ) FT_MODULE( x )->clazz +#define FT_MODULE_LIBRARY( x ) FT_MODULE( x )->library +#define FT_MODULE_MEMORY( x ) FT_MODULE( x )->memory + + +#define FT_MODULE_IS_DRIVER( x ) ( FT_MODULE_CLASS( x )->module_flags & \ + FT_MODULE_FONT_DRIVER ) + +#define FT_MODULE_IS_RENDERER( x ) ( FT_MODULE_CLASS( x )->module_flags & \ + FT_MODULE_RENDERER ) + +#define FT_MODULE_IS_HINTER( x ) ( FT_MODULE_CLASS( x )->module_flags & \ + FT_MODULE_HINTER ) + +#define FT_MODULE_IS_STYLER( x ) ( FT_MODULE_CLASS( x )->module_flags & \ + FT_MODULE_STYLER ) + +#define FT_DRIVER_IS_SCALABLE( x ) ( FT_MODULE_CLASS( x )->module_flags & \ + FT_MODULE_DRIVER_SCALABLE ) + +#define FT_DRIVER_USES_OUTLINES( x ) !( FT_MODULE_CLASS( x )->module_flags & \ + FT_MODULE_DRIVER_NO_OUTLINES ) + +#define FT_DRIVER_HAS_HINTER( x ) ( FT_MODULE_CLASS( x )->module_flags & \ + FT_MODULE_DRIVER_HAS_HINTER ) + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Module_Interface */ + /* */ + /* <Description> */ + /* Finds a module and returns its specific interface as a typeless */ + /* pointer. */ + /* */ + /* <Input> */ + /* library :: A handle to the library object. */ + /* */ + /* module_name :: The module's name (as an ASCII string). */ + /* */ + /* <Return> */ + /* A module-specific interface if available, 0 otherwise. */ + /* */ + /* <Note> */ + /* You should better be familiar with FreeType internals to know */ + /* which module to look for, and what its interface is :-) */ + /* */ + FT_BASE( const void* ) + FT_Get_Module_Interface( FT_Library library, + const char* mod_name ); + + FT_BASE( FT_Pointer ) + ft_module_get_service( FT_Module module, + const char* service_id ); + + /* */ + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** FACE, SIZE & GLYPH SLOT OBJECTS ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + /* a few macros used to perform easy typecasts with minimal brain damage */ + +#define FT_FACE( x ) ((FT_Face)(x)) +#define FT_SIZE( x ) ((FT_Size)(x)) +#define FT_SLOT( x ) ((FT_GlyphSlot)(x)) + +#define FT_FACE_DRIVER( x ) FT_FACE( x )->driver +#define FT_FACE_LIBRARY( x ) FT_FACE_DRIVER( x )->root.library +#define FT_FACE_MEMORY( x ) FT_FACE( x )->memory +#define FT_FACE_STREAM( x ) FT_FACE( x )->stream + +#define FT_SIZE_FACE( x ) FT_SIZE( x )->face +#define FT_SLOT_FACE( x ) FT_SLOT( x )->face + +#define FT_FACE_SLOT( x ) FT_FACE( x )->glyph +#define FT_FACE_SIZE( x ) FT_FACE( x )->size + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_GlyphSlot */ + /* */ + /* <Description> */ + /* It is sometimes useful to have more than one glyph slot for a */ + /* given face object. This function is used to create additional */ + /* slots. All of them are automatically discarded when the face is */ + /* destroyed. */ + /* */ + /* <Input> */ + /* face :: A handle to a parent face object. */ + /* */ + /* <Output> */ + /* aslot :: A handle to a new glyph slot object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_BASE( FT_Error ) + FT_New_GlyphSlot( FT_Face face, + FT_GlyphSlot *aslot ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Done_GlyphSlot */ + /* */ + /* <Description> */ + /* Destroys a given glyph slot. Remember however that all slots are */ + /* automatically destroyed with its parent. Using this function is */ + /* not always mandatory. */ + /* */ + /* <Input> */ + /* slot :: A handle to a target glyph slot. */ + /* */ + FT_BASE( void ) + FT_Done_GlyphSlot( FT_GlyphSlot slot ); + + /* */ + +#define FT_REQUEST_WIDTH( req ) \ + ( (req)->horiResolution \ + ? (FT_Pos)( (req)->width * (req)->horiResolution + 36 ) / 72 \ + : (req)->width ) + +#define FT_REQUEST_HEIGHT( req ) \ + ( (req)->vertResolution \ + ? (FT_Pos)( (req)->height * (req)->vertResolution + 36 ) / 72 \ + : (req)->height ) + + + /* Set the metrics according to a bitmap strike. */ + FT_BASE( void ) + FT_Select_Metrics( FT_Face face, + FT_ULong strike_index ); + + + /* Set the metrics according to a size request. */ + FT_BASE( void ) + FT_Request_Metrics( FT_Face face, + FT_Size_Request req ); + + + /* Match a size request against `available_sizes'. */ + FT_BASE( FT_Error ) + FT_Match_Size( FT_Face face, + FT_Size_Request req, + FT_Bool ignore_width, + FT_ULong* size_index ); + + + /* Use the horizontal metrics to synthesize the vertical metrics. */ + /* If `advance' is zero, it is also synthesized. */ + FT_BASE( void ) + ft_synthesize_vertical_metrics( FT_Glyph_Metrics* metrics, + FT_Pos advance ); + + + /* Free the bitmap of a given glyphslot when needed (i.e., only when it */ + /* was allocated with ft_glyphslot_alloc_bitmap). */ + FT_BASE( void ) + ft_glyphslot_free_bitmap( FT_GlyphSlot slot ); + + + /* Allocate a new bitmap buffer in a glyph slot. */ + FT_BASE( FT_Error ) + ft_glyphslot_alloc_bitmap( FT_GlyphSlot slot, + FT_ULong size ); + + + /* Set the bitmap buffer in a glyph slot to a given pointer. The buffer */ + /* will not be freed by a later call to ft_glyphslot_free_bitmap. */ + FT_BASE( void ) + ft_glyphslot_set_bitmap( FT_GlyphSlot slot, + FT_Byte* buffer ); + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** R E N D E R E R S ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + +#define FT_RENDERER( x ) ((FT_Renderer)( x )) +#define FT_GLYPH( x ) ((FT_Glyph)( x )) +#define FT_BITMAP_GLYPH( x ) ((FT_BitmapGlyph)( x )) +#define FT_OUTLINE_GLYPH( x ) ((FT_OutlineGlyph)( x )) + + + typedef struct FT_RendererRec_ + { + FT_ModuleRec root; + FT_Renderer_Class* clazz; + FT_Glyph_Format glyph_format; + FT_Glyph_Class glyph_class; + + FT_Raster raster; + FT_Raster_Render_Func raster_render; + FT_Renderer_RenderFunc render; + + } FT_RendererRec; + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** F O N T D R I V E R S ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /* typecast a module into a driver easily */ +#define FT_DRIVER( x ) ((FT_Driver)(x)) + + /* typecast a module as a driver, and get its driver class */ +#define FT_DRIVER_CLASS( x ) FT_DRIVER( x )->clazz + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_DriverRec */ + /* */ + /* <Description> */ + /* The root font driver class. A font driver is responsible for */ + /* managing and loading font files of a given format. */ + /* */ + /* <Fields> */ + /* root :: Contains the fields of the root module class. */ + /* */ + /* clazz :: A pointer to the font driver's class. Note that */ + /* this is NOT root.clazz. `class' wasn't used */ + /* as it is a reserved word in C++. */ + /* */ + /* faces_list :: The list of faces currently opened by this */ + /* driver. */ + /* */ + /* extensions :: A typeless pointer to the driver's extensions */ + /* registry, if they are supported through the */ + /* configuration macro FT_CONFIG_OPTION_EXTENSIONS. */ + /* */ + /* glyph_loader :: The glyph loader for all faces managed by this */ + /* driver. This object isn't defined for unscalable */ + /* formats. */ + /* */ + typedef struct FT_DriverRec_ + { + FT_ModuleRec root; + FT_Driver_Class clazz; + + FT_ListRec faces_list; + void* extensions; + + FT_GlyphLoader glyph_loader; + + } FT_DriverRec; + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** L I B R A R I E S ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /* This hook is used by the TrueType debugger. It must be set to an */ + /* alternate truetype bytecode interpreter function. */ +#define FT_DEBUG_HOOK_TRUETYPE 0 + + + /* Set this debug hook to a non-null pointer to force unpatented hinting */ + /* for all faces when both TT_USE_BYTECODE_INTERPRETER and */ + /* TT_CONFIG_OPTION_UNPATENTED_HINTING are defined. This is only used */ + /* during debugging. */ +#define FT_DEBUG_HOOK_UNPATENTED_HINTING 1 + + + typedef void (*FT_Bitmap_LcdFilterFunc)( FT_Bitmap* bitmap, + FT_Render_Mode render_mode, + FT_Library library ); + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_LibraryRec */ + /* */ + /* <Description> */ + /* The FreeType library class. This is the root of all FreeType */ + /* data. Use FT_New_Library() to create a library object, and */ + /* FT_Done_Library() to discard it and all child objects. */ + /* */ + /* <Fields> */ + /* memory :: The library's memory object. Manages memory */ + /* allocation. */ + /* */ + /* generic :: Client data variable. Used to extend the */ + /* Library class by higher levels and clients. */ + /* */ + /* version_major :: The major version number of the library. */ + /* */ + /* version_minor :: The minor version number of the library. */ + /* */ + /* version_patch :: The current patch level of the library. */ + /* */ + /* num_modules :: The number of modules currently registered */ + /* within this library. This is set to 0 for new */ + /* libraries. New modules are added through the */ + /* FT_Add_Module() API function. */ + /* */ + /* modules :: A table used to store handles to the currently */ + /* registered modules. Note that each font driver */ + /* contains a list of its opened faces. */ + /* */ + /* renderers :: The list of renderers currently registered */ + /* within the library. */ + /* */ + /* cur_renderer :: The current outline renderer. This is a */ + /* shortcut used to avoid parsing the list on */ + /* each call to FT_Outline_Render(). It is a */ + /* handle to the current renderer for the */ + /* FT_GLYPH_FORMAT_OUTLINE format. */ + /* */ + /* auto_hinter :: XXX */ + /* */ + /* raster_pool :: The raster object's render pool. This can */ + /* ideally be changed dynamically at run-time. */ + /* */ + /* raster_pool_size :: The size of the render pool in bytes. */ + /* */ + /* debug_hooks :: XXX */ + /* */ + /* pic_container :: Contains global structs and tables, instead */ + /* of defining them globallly. */ + /* */ + + typedef struct FT_LibraryRec_ + { + FT_Memory memory; /* library's memory manager */ + + FT_Generic generic; + + FT_Int version_major; + FT_Int version_minor; + FT_Int version_patch; + + FT_UInt num_modules; + FT_Module modules[FT_MAX_MODULES]; /* module objects */ + + FT_ListRec renderers; /* list of renderers */ + FT_Renderer cur_renderer; /* current outline renderer */ + FT_Module auto_hinter; + + FT_Byte* raster_pool; /* scan-line conversion */ + /* render pool */ + FT_ULong raster_pool_size; /* size of render pool in bytes */ + + FT_DebugHook_Func debug_hooks[4]; + +#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING + FT_LcdFilter lcd_filter; + FT_Int lcd_extra; /* number of extra pixels */ + FT_Byte lcd_weights[7]; /* filter weights, if any */ + FT_Bitmap_LcdFilterFunc lcd_filter_func; /* filtering callback */ +#endif + +#ifdef FT_CONFIG_OPTION_PIC + FT_PIC_Container pic_container; +#endif + + } FT_LibraryRec; + + + FT_BASE( FT_Renderer ) + FT_Lookup_Renderer( FT_Library library, + FT_Glyph_Format format, + FT_ListNode* node ); + + FT_BASE( FT_Error ) + FT_Render_Glyph_Internal( FT_Library library, + FT_GlyphSlot slot, + FT_Render_Mode render_mode ); + + typedef const char* + (*FT_Face_GetPostscriptNameFunc)( FT_Face face ); + + typedef FT_Error + (*FT_Face_GetGlyphNameFunc)( FT_Face face, + FT_UInt glyph_index, + FT_Pointer buffer, + FT_UInt buffer_max ); + + typedef FT_UInt + (*FT_Face_GetGlyphNameIndexFunc)( FT_Face face, + FT_String* glyph_name ); + + +#ifndef FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_Memory */ + /* */ + /* <Description> */ + /* Creates a new memory object. */ + /* */ + /* <Return> */ + /* A pointer to the new memory object. 0 in case of error. */ + /* */ + FT_BASE( FT_Memory ) + FT_New_Memory( void ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Done_Memory */ + /* */ + /* <Description> */ + /* Discards memory manager. */ + /* */ + /* <Input> */ + /* memory :: A handle to the memory manager. */ + /* */ + FT_BASE( void ) + FT_Done_Memory( FT_Memory memory ); + +#endif /* !FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM */ + + + /* Define default raster's interface. The default raster is located in */ + /* `src/base/ftraster.c'. */ + /* */ + /* Client applications can register new rasters through the */ + /* FT_Set_Raster() API. */ + +#ifndef FT_NO_DEFAULT_RASTER + FT_EXPORT_VAR( FT_Raster_Funcs ) ft_default_raster; +#endif + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** PIC-Support Macros for ftimage.h ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_DEFINE_OUTLINE_FUNCS */ + /* */ + /* <Description> */ + /* Used to initialize an instance of FT_Outline_Funcs struct. */ + /* When FT_CONFIG_OPTION_PIC is defined an init funtion will need to */ + /* called with a pre-allocated stracture to be filled. */ + /* When FT_CONFIG_OPTION_PIC is not defined the struct will be */ + /* allocated in the global scope (or the scope where the macro */ + /* is used). */ + /* */ +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_OUTLINE_FUNCS(class_, move_to_, line_to_, conic_to_, \ + cubic_to_, shift_, delta_) \ + static const FT_Outline_Funcs class_ = \ + { \ + move_to_, line_to_, conic_to_, cubic_to_, shift_, delta_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_OUTLINE_FUNCS(class_, move_to_, line_to_, conic_to_, \ + cubic_to_, shift_, delta_) \ + static FT_Error \ + Init_Class_##class_( FT_Outline_Funcs* clazz ) \ + { \ + clazz->move_to = move_to_; \ + clazz->line_to = line_to_; \ + clazz->conic_to = conic_to_; \ + clazz->cubic_to = cubic_to_; \ + clazz->shift = shift_; \ + clazz->delta = delta_; \ + return FT_Err_Ok; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_DEFINE_RASTER_FUNCS */ + /* */ + /* <Description> */ + /* Used to initialize an instance of FT_Raster_Funcs struct. */ + /* When FT_CONFIG_OPTION_PIC is defined an init funtion will need to */ + /* called with a pre-allocated stracture to be filled. */ + /* When FT_CONFIG_OPTION_PIC is not defined the struct will be */ + /* allocated in the global scope (or the scope where the macro */ + /* is used). */ + /* */ +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_RASTER_FUNCS(class_, glyph_format_, raster_new_, \ + raster_reset_, raster_set_mode_, \ + raster_render_, raster_done_) \ + const FT_Raster_Funcs class_ = \ + { \ + glyph_format_, raster_new_, raster_reset_, \ + raster_set_mode_, raster_render_, raster_done_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_RASTER_FUNCS(class_, glyph_format_, raster_new_, \ + raster_reset_, raster_set_mode_, raster_render_, raster_done_) \ + void \ + FT_Init_Class_##class_( FT_Raster_Funcs* clazz ) \ + { \ + clazz->glyph_format = glyph_format_; \ + clazz->raster_new = raster_new_; \ + clazz->raster_reset = raster_reset_; \ + clazz->raster_set_mode = raster_set_mode_; \ + clazz->raster_render = raster_render_; \ + clazz->raster_done = raster_done_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** PIC-Support Macros for ftrender.h ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_DEFINE_GLYPH */ + /* */ + /* <Description> */ + /* Used to initialize an instance of FT_Glyph_Class struct. */ + /* When FT_CONFIG_OPTION_PIC is defined an init funtion will need to */ + /* called with a pre-allocated stracture to be filled. */ + /* When FT_CONFIG_OPTION_PIC is not defined the struct will be */ + /* allocated in the global scope (or the scope where the macro */ + /* is used). */ + /* */ +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_GLYPH(class_, size_, format_, init_, done_, copy_, \ + transform_, bbox_, prepare_) \ + FT_CALLBACK_TABLE_DEF \ + const FT_Glyph_Class class_ = \ + { \ + size_, format_, init_, done_, copy_, transform_, bbox_, prepare_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_GLYPH(class_, size_, format_, init_, done_, copy_, \ + transform_, bbox_, prepare_) \ + void \ + FT_Init_Class_##class_( FT_Glyph_Class* clazz ) \ + { \ + clazz->glyph_size = size_; \ + clazz->glyph_format = format_; \ + clazz->glyph_init = init_; \ + clazz->glyph_done = done_; \ + clazz->glyph_copy = copy_; \ + clazz->glyph_transform = transform_; \ + clazz->glyph_bbox = bbox_; \ + clazz->glyph_prepare = prepare_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_DECLARE_RENDERER */ + /* */ + /* <Description> */ + /* Used to create a forward declaration of a */ + /* FT_Renderer_Class stract instance. */ + /* */ + /* <Macro> */ + /* FT_DEFINE_RENDERER */ + /* */ + /* <Description> */ + /* Used to initialize an instance of FT_Renderer_Class struct. */ + /* */ + /* When FT_CONFIG_OPTION_PIC is defined a Create funtion will need */ + /* to called with a pointer where the allocated stracture is returned.*/ + /* And when it is no longer needed a Destroy function needs */ + /* to be called to release that allocation. */ + /* fcinit.c (ft_create_default_module_classes) already contains */ + /* a mechanism to call these functions for the default modules */ + /* described in ftmodule.h */ + /* */ + /* Notice that the created Create and Destroy functions call */ + /* pic_init and pic_free function to allow you to manually allocate */ + /* and initialize any additional global data, like module specific */ + /* interface, and put them in the global pic container defined in */ + /* ftpic.h. if you don't need them just implement the functions as */ + /* empty to resolve the link error. */ + /* */ + /* When FT_CONFIG_OPTION_PIC is not defined the struct will be */ + /* allocated in the global scope (or the scope where the macro */ + /* is used). */ + /* */ +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DECLARE_RENDERER(class_) \ + FT_EXPORT_VAR( const FT_Renderer_Class ) class_; + +#define FT_DEFINE_RENDERER(class_, \ + flags_, size_, name_, version_, requires_, \ + interface_, init_, done_, get_interface_, \ + glyph_format_, render_glyph_, transform_glyph_, \ + get_glyph_cbox_, set_mode_, raster_class_ ) \ + FT_CALLBACK_TABLE_DEF \ + const FT_Renderer_Class class_ = \ + { \ + FT_DEFINE_ROOT_MODULE(flags_,size_,name_,version_,requires_, \ + interface_,init_,done_,get_interface_) \ + glyph_format_, \ + \ + render_glyph_, \ + transform_glyph_, \ + get_glyph_cbox_, \ + set_mode_, \ + \ + raster_class_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DECLARE_RENDERER(class_) FT_DECLARE_MODULE(class_) + +#define FT_DEFINE_RENDERER(class_, \ + flags_, size_, name_, version_, requires_, \ + interface_, init_, done_, get_interface_, \ + glyph_format_, render_glyph_, transform_glyph_, \ + get_glyph_cbox_, set_mode_, raster_class_ ) \ + void class_##_pic_free( FT_Library library ); \ + FT_Error class_##_pic_init( FT_Library library ); \ + \ + void \ + FT_Destroy_Class_##class_( FT_Library library, \ + FT_Module_Class* clazz ) \ + { \ + FT_Renderer_Class* rclazz = (FT_Renderer_Class*)clazz; \ + FT_Memory memory = library->memory; \ + class_##_pic_free( library ); \ + if ( rclazz ) \ + FT_FREE( rclazz ); \ + } \ + \ + FT_Error \ + FT_Create_Class_##class_( FT_Library library, \ + FT_Module_Class** output_class ) \ + { \ + FT_Renderer_Class* clazz; \ + FT_Error error; \ + FT_Memory memory = library->memory; \ + \ + if ( FT_ALLOC( clazz, sizeof(*clazz) ) ) \ + return error; \ + \ + error = class_##_pic_init( library ); \ + if(error) \ + { \ + FT_FREE( clazz ); \ + return error; \ + } \ + \ + FT_DEFINE_ROOT_MODULE(flags_,size_,name_,version_,requires_, \ + interface_,init_,done_,get_interface_) \ + \ + clazz->glyph_format = glyph_format_; \ + \ + clazz->render_glyph = render_glyph_; \ + clazz->transform_glyph = transform_glyph_; \ + clazz->get_glyph_cbox = get_glyph_cbox_; \ + clazz->set_mode = set_mode_; \ + \ + clazz->raster_class = raster_class_; \ + \ + *output_class = (FT_Module_Class*)clazz; \ + return FT_Err_Ok; \ + } + + + +#endif /* FT_CONFIG_OPTION_PIC */ + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** PIC-Support Macros for ftmodapi.h ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + +#ifdef FT_CONFIG_OPTION_PIC + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Module_Creator */ + /* */ + /* <Description> */ + /* A function used to create (allocate) a new module class object. */ + /* The object's members are initialized, but the module itself is */ + /* not. */ + /* */ + /* <Input> */ + /* memory :: A handle to the memory manager. */ + /* output_class :: Initialized with the newly allocated class. */ + /* */ + typedef FT_Error + (*FT_Module_Creator)( FT_Memory memory, + FT_Module_Class** output_class ); + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Module_Destroyer */ + /* */ + /* <Description> */ + /* A function used to destroy (deallocate) a module class object. */ + /* */ + /* <Input> */ + /* memory :: A handle to the memory manager. */ + /* clazz :: Module class to destroy. */ + /* */ + typedef void + (*FT_Module_Destroyer)( FT_Memory memory, + FT_Module_Class* clazz ); + +#endif + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_DECLARE_MODULE */ + /* */ + /* <Description> */ + /* Used to create a forward declaration of a */ + /* FT_Module_Class stract instance. */ + /* */ + /* <Macro> */ + /* FT_DEFINE_MODULE */ + /* */ + /* <Description> */ + /* Used to initialize an instance of FT_Module_Class struct. */ + /* */ + /* When FT_CONFIG_OPTION_PIC is defined a Create funtion will need */ + /* to called with a pointer where the allocated stracture is returned.*/ + /* And when it is no longer needed a Destroy function needs */ + /* to be called to release that allocation. */ + /* fcinit.c (ft_create_default_module_classes) already contains */ + /* a mechanism to call these functions for the default modules */ + /* described in ftmodule.h */ + /* */ + /* Notice that the created Create and Destroy functions call */ + /* pic_init and pic_free function to allow you to manually allocate */ + /* and initialize any additional global data, like module specific */ + /* interface, and put them in the global pic container defined in */ + /* ftpic.h. if you don't need them just implement the functions as */ + /* empty to resolve the link error. */ + /* */ + /* When FT_CONFIG_OPTION_PIC is not defined the struct will be */ + /* allocated in the global scope (or the scope where the macro */ + /* is used). */ + /* */ + /* <Macro> */ + /* FT_DEFINE_ROOT_MODULE */ + /* */ + /* <Description> */ + /* Used to initialize an instance of FT_Module_Class struct inside */ + /* another stract that contains it or in a function that initializes */ + /* that containing stract */ + /* */ +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DECLARE_MODULE(class_) \ + FT_CALLBACK_TABLE \ + const FT_Module_Class class_; \ + +#define FT_DEFINE_ROOT_MODULE(flags_, size_, name_, version_, requires_, \ + interface_, init_, done_, get_interface_) \ + { \ + flags_, \ + size_, \ + \ + name_, \ + version_, \ + requires_, \ + \ + interface_, \ + \ + init_, \ + done_, \ + get_interface_, \ + }, + +#define FT_DEFINE_MODULE(class_, flags_, size_, name_, version_, requires_, \ + interface_, init_, done_, get_interface_) \ + FT_CALLBACK_TABLE_DEF \ + const FT_Module_Class class_ = \ + { \ + flags_, \ + size_, \ + \ + name_, \ + version_, \ + requires_, \ + \ + interface_, \ + \ + init_, \ + done_, \ + get_interface_, \ + }; + + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DECLARE_MODULE(class_) \ + FT_Error FT_Create_Class_##class_( FT_Library library, \ + FT_Module_Class** output_class ); \ + void FT_Destroy_Class_##class_( FT_Library library, \ + FT_Module_Class* clazz ); + +#define FT_DEFINE_ROOT_MODULE(flags_, size_, name_, version_, requires_, \ + interface_, init_, done_, get_interface_) \ + clazz->root.module_flags = flags_; \ + clazz->root.module_size = size_; \ + clazz->root.module_name = name_; \ + clazz->root.module_version = version_; \ + clazz->root.module_requires = requires_; \ + \ + clazz->root.module_interface = interface_; \ + \ + clazz->root.module_init = init_; \ + clazz->root.module_done = done_; \ + clazz->root.get_interface = get_interface_; + +#define FT_DEFINE_MODULE(class_, flags_, size_, name_, version_, requires_, \ + interface_, init_, done_, get_interface_) \ + void class_##_pic_free( FT_Library library ); \ + FT_Error class_##_pic_init( FT_Library library ); \ + \ + void \ + FT_Destroy_Class_##class_( FT_Library library, \ + FT_Module_Class* clazz ) \ + { \ + FT_Memory memory = library->memory; \ + class_##_pic_free( library ); \ + if ( clazz ) \ + FT_FREE( clazz ); \ + } \ + \ + FT_Error \ + FT_Create_Class_##class_( FT_Library library, \ + FT_Module_Class** output_class ) \ + { \ + FT_Memory memory = library->memory; \ + FT_Module_Class* clazz; \ + FT_Error error; \ + \ + if ( FT_ALLOC( clazz, sizeof(*clazz) ) ) \ + return error; \ + error = class_##_pic_init( library ); \ + if(error) \ + { \ + FT_FREE( clazz ); \ + return error; \ + } \ + \ + clazz->module_flags = flags_; \ + clazz->module_size = size_; \ + clazz->module_name = name_; \ + clazz->module_version = version_; \ + clazz->module_requires = requires_; \ + \ + clazz->module_interface = interface_; \ + \ + clazz->module_init = init_; \ + clazz->module_done = done_; \ + clazz->get_interface = get_interface_; \ + \ + *output_class = clazz; \ + return FT_Err_Ok; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + +FT_END_HEADER + +#endif /* __FTOBJS_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/internal/ftpic.h b/mod/pub.mod/freetype.mod/include/freetype/internal/ftpic.h new file mode 100644 index 0000000..1b31957 --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/internal/ftpic.h @@ -0,0 +1,67 @@ +/***************************************************************************/ +/* */ +/* ftpic.h */ +/* */ +/* The FreeType position independent code services (declaration). */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + /*************************************************************************/ + /* */ + /* Modules that ordinarily have const global data that need address */ + /* can instead define pointers here. */ + /* */ + /*************************************************************************/ + + +#ifndef __FTPIC_H__ +#define __FTPIC_H__ + + +FT_BEGIN_HEADER + +#ifdef FT_CONFIG_OPTION_PIC + + typedef struct FT_PIC_Container_ + { + /* pic containers for base */ + void* base; + /* pic containers for modules */ + void* autofit; + void* cff; + void* pshinter; + void* psnames; + void* raster; + void* sfnt; + void* smooth; + void* truetype; + } FT_PIC_Container; + + /* Initialize the various function tables, structs, etc. stored in the container. */ + FT_BASE( FT_Error ) + ft_pic_container_init( FT_Library library ); + + + /* Destroy the contents of the container. */ + FT_BASE( void ) + ft_pic_container_destroy( FT_Library library ); + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + +FT_END_HEADER + +#endif /* __FTPIC_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/internal/ftrfork.h b/mod/pub.mod/freetype.mod/include/freetype/internal/ftrfork.h new file mode 100644 index 0000000..aa573c8 --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/internal/ftrfork.h @@ -0,0 +1,196 @@ +/***************************************************************************/ +/* */ +/* ftrfork.h */ +/* */ +/* Embedded resource forks accessor (specification). */ +/* */ +/* Copyright 2004, 2006, 2007 by */ +/* Masatake YAMATO and Redhat K.K. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + +/***************************************************************************/ +/* Development of the code in this file is support of */ +/* Information-technology Promotion Agency, Japan. */ +/***************************************************************************/ + + +#ifndef __FTRFORK_H__ +#define __FTRFORK_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H + + +FT_BEGIN_HEADER + + + /* Number of guessing rules supported in `FT_Raccess_Guess'. */ + /* Don't forget to increment the number if you add a new guessing rule. */ +#define FT_RACCESS_N_RULES 9 + + + /* A structure to describe a reference in a resource by its resource ID */ + /* and internal offset. The `POST' resource expects to be concatenated */ + /* by the order of resource IDs instead of its appearance in the file. */ + + typedef struct FT_RFork_Ref_ + { + FT_UShort res_id; + FT_ULong offset; + + } FT_RFork_Ref; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Raccess_Guess */ + /* */ + /* <Description> */ + /* Guess a file name and offset where the actual resource fork is */ + /* stored. The macro FT_RACCESS_N_RULES holds the number of */ + /* guessing rules; the guessed result for the Nth rule is */ + /* represented as a triplet: a new file name (new_names[N]), a file */ + /* offset (offsets[N]), and an error code (errors[N]). */ + /* */ + /* <Input> */ + /* library :: */ + /* A FreeType library instance. */ + /* */ + /* stream :: */ + /* A file stream containing the resource fork. */ + /* */ + /* base_name :: */ + /* The (base) file name of the resource fork used for some */ + /* guessing rules. */ + /* */ + /* <Output> */ + /* new_names :: */ + /* An array of guessed file names in which the resource forks may */ + /* exist. If `new_names[N]' is NULL, the guessed file name is */ + /* equal to `base_name'. */ + /* */ + /* offsets :: */ + /* An array of guessed file offsets. `offsets[N]' holds the file */ + /* offset of the possible start of the resource fork in file */ + /* `new_names[N]'. */ + /* */ + /* errors :: */ + /* An array of FreeType error codes. `errors[N]' is the error */ + /* code of Nth guessing rule function. If `errors[N]' is not */ + /* FT_Err_Ok, `new_names[N]' and `offsets[N]' are meaningless. */ + /* */ + FT_BASE( void ) + FT_Raccess_Guess( FT_Library library, + FT_Stream stream, + char* base_name, + char** new_names, + FT_Long* offsets, + FT_Error* errors ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Raccess_Get_HeaderInfo */ + /* */ + /* <Description> */ + /* Get the information from the header of resource fork. The */ + /* information includes the file offset where the resource map */ + /* starts, and the file offset where the resource data starts. */ + /* `FT_Raccess_Get_DataOffsets' requires these two data. */ + /* */ + /* <Input> */ + /* library :: */ + /* A FreeType library instance. */ + /* */ + /* stream :: */ + /* A file stream containing the resource fork. */ + /* */ + /* rfork_offset :: */ + /* The file offset where the resource fork starts. */ + /* */ + /* <Output> */ + /* map_offset :: */ + /* The file offset where the resource map starts. */ + /* */ + /* rdata_pos :: */ + /* The file offset where the resource data starts. */ + /* */ + /* <Return> */ + /* FreeType error code. FT_Err_Ok means success. */ + /* */ + FT_BASE( FT_Error ) + FT_Raccess_Get_HeaderInfo( FT_Library library, + FT_Stream stream, + FT_Long rfork_offset, + FT_Long *map_offset, + FT_Long *rdata_pos ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Raccess_Get_DataOffsets */ + /* */ + /* <Description> */ + /* Get the data offsets for a tag in a resource fork. Offsets are */ + /* stored in an array because, in some cases, resources in a resource */ + /* fork have the same tag. */ + /* */ + /* <Input> */ + /* library :: */ + /* A FreeType library instance. */ + /* */ + /* stream :: */ + /* A file stream containing the resource fork. */ + /* */ + /* map_offset :: */ + /* The file offset where the resource map starts. */ + /* */ + /* rdata_pos :: */ + /* The file offset where the resource data starts. */ + /* */ + /* tag :: */ + /* The resource tag. */ + /* */ + /* <Output> */ + /* offsets :: */ + /* The stream offsets for the resource data specified by `tag'. */ + /* This array is allocated by the function, so you have to call */ + /* @ft_mem_free after use. */ + /* */ + /* count :: */ + /* The length of offsets array. */ + /* */ + /* <Return> */ + /* FreeType error code. FT_Err_Ok means success. */ + /* */ + /* <Note> */ + /* Normally you should use `FT_Raccess_Get_HeaderInfo' to get the */ + /* value for `map_offset' and `rdata_pos'. */ + /* */ + FT_BASE( FT_Error ) + FT_Raccess_Get_DataOffsets( FT_Library library, + FT_Stream stream, + FT_Long map_offset, + FT_Long rdata_pos, + FT_Long tag, + FT_Long **offsets, + FT_Long *count ); + + +FT_END_HEADER + +#endif /* __FTRFORK_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/internal/ftserv.h b/mod/pub.mod/freetype.mod/include/freetype/internal/ftserv.h new file mode 100644 index 0000000..569b9f7 --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/internal/ftserv.h @@ -0,0 +1,620 @@ +/***************************************************************************/ +/* */ +/* ftserv.h */ +/* */ +/* The FreeType services (specification only). */ +/* */ +/* Copyright 2003, 2004, 2005, 2006, 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + /*************************************************************************/ + /* */ + /* Each module can export one or more `services'. Each service is */ + /* identified by a constant string and modeled by a pointer; the latter */ + /* generally corresponds to a structure containing function pointers. */ + /* */ + /* Note that a service's data cannot be a mere function pointer because */ + /* in C it is possible that function pointers might be implemented */ + /* differently than data pointers (e.g. 48 bits instead of 32). */ + /* */ + /*************************************************************************/ + + +#ifndef __FTSERV_H__ +#define __FTSERV_H__ + + +FT_BEGIN_HEADER + +#if defined( _MSC_VER ) /* Visual C++ (and Intel C++) */ + + /* we disable the warning `conditional expression is constant' here */ + /* in order to compile cleanly with the maximum level of warnings */ +#pragma warning( disable : 4127 ) + +#endif /* _MSC_VER */ + + /* + * @macro: + * FT_FACE_FIND_SERVICE + * + * @description: + * This macro is used to look up a service from a face's driver module. + * + * @input: + * face :: + * The source face handle. + * + * id :: + * A string describing the service as defined in the service's + * header files (e.g. FT_SERVICE_ID_MULTI_MASTERS which expands to + * `multi-masters'). It is automatically prefixed with + * `FT_SERVICE_ID_'. + * + * @output: + * ptr :: + * A variable that receives the service pointer. Will be NULL + * if not found. + */ +#ifdef __cplusplus + +#define FT_FACE_FIND_SERVICE( face, ptr, id ) \ + FT_BEGIN_STMNT \ + FT_Module module = FT_MODULE( FT_FACE( face )->driver ); \ + FT_Pointer _tmp_ = NULL; \ + FT_Pointer* _pptr_ = (FT_Pointer*)&(ptr); \ + \ + \ + if ( module->clazz->get_interface ) \ + _tmp_ = module->clazz->get_interface( module, FT_SERVICE_ID_ ## id ); \ + *_pptr_ = _tmp_; \ + FT_END_STMNT + +#else /* !C++ */ + +#define FT_FACE_FIND_SERVICE( face, ptr, id ) \ + FT_BEGIN_STMNT \ + FT_Module module = FT_MODULE( FT_FACE( face )->driver ); \ + FT_Pointer _tmp_ = NULL; \ + \ + if ( module->clazz->get_interface ) \ + _tmp_ = module->clazz->get_interface( module, FT_SERVICE_ID_ ## id ); \ + ptr = _tmp_; \ + FT_END_STMNT + +#endif /* !C++ */ + + /* + * @macro: + * FT_FACE_FIND_GLOBAL_SERVICE + * + * @description: + * This macro is used to look up a service from all modules. + * + * @input: + * face :: + * The source face handle. + * + * id :: + * A string describing the service as defined in the service's + * header files (e.g. FT_SERVICE_ID_MULTI_MASTERS which expands to + * `multi-masters'). It is automatically prefixed with + * `FT_SERVICE_ID_'. + * + * @output: + * ptr :: + * A variable that receives the service pointer. Will be NULL + * if not found. + */ +#ifdef __cplusplus + +#define FT_FACE_FIND_GLOBAL_SERVICE( face, ptr, id ) \ + FT_BEGIN_STMNT \ + FT_Module module = FT_MODULE( FT_FACE( face )->driver ); \ + FT_Pointer _tmp_; \ + FT_Pointer* _pptr_ = (FT_Pointer*)&(ptr); \ + \ + \ + _tmp_ = ft_module_get_service( module, FT_SERVICE_ID_ ## id ); \ + *_pptr_ = _tmp_; \ + FT_END_STMNT + +#else /* !C++ */ + +#define FT_FACE_FIND_GLOBAL_SERVICE( face, ptr, id ) \ + FT_BEGIN_STMNT \ + FT_Module module = FT_MODULE( FT_FACE( face )->driver ); \ + FT_Pointer _tmp_; \ + \ + \ + _tmp_ = ft_module_get_service( module, FT_SERVICE_ID_ ## id ); \ + ptr = _tmp_; \ + FT_END_STMNT + +#endif /* !C++ */ + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** S E R V I C E D E S C R I P T O R S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* + * The following structure is used to _describe_ a given service + * to the library. This is useful to build simple static service lists. + */ + typedef struct FT_ServiceDescRec_ + { + const char* serv_id; /* service name */ + const void* serv_data; /* service pointer/data */ + + } FT_ServiceDescRec; + + typedef const FT_ServiceDescRec* FT_ServiceDesc; + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_DEFINE_SERVICEDESCREC1 .. FT_DEFINE_SERVICEDESCREC6 */ + /* */ + /* <Description> */ + /* Used to initialize an array of FT_ServiceDescRec structs. */ + /* */ + /* When FT_CONFIG_OPTION_PIC is defined a Create funtion will need */ + /* to called with a pointer where the allocated array is returned. */ + /* And when it is no longer needed a Destroy function needs */ + /* to be called to release that allocation. */ + /* */ + /* These functions should be manyally called from the pic_init and */ + /* pic_free functions of your module (see FT_DEFINE_MODULE) */ + /* */ + /* When FT_CONFIG_OPTION_PIC is not defined the array will be */ + /* allocated in the global scope (or the scope where the macro */ + /* is used). */ + /* */ +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICEDESCREC1(class_, serv_id_1, serv_data_1) \ + static const FT_ServiceDescRec class_[] = \ + { \ + {serv_id_1, serv_data_1}, \ + {NULL, NULL} \ + }; +#define FT_DEFINE_SERVICEDESCREC2(class_, serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2) \ + static const FT_ServiceDescRec class_[] = \ + { \ + {serv_id_1, serv_data_1}, \ + {serv_id_2, serv_data_2}, \ + {NULL, NULL} \ + }; +#define FT_DEFINE_SERVICEDESCREC3(class_, serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, serv_id_3, serv_data_3) \ + static const FT_ServiceDescRec class_[] = \ + { \ + {serv_id_1, serv_data_1}, \ + {serv_id_2, serv_data_2}, \ + {serv_id_3, serv_data_3}, \ + {NULL, NULL} \ + }; +#define FT_DEFINE_SERVICEDESCREC4(class_, serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, serv_id_3, serv_data_3, \ + serv_id_4, serv_data_4) \ + static const FT_ServiceDescRec class_[] = \ + { \ + {serv_id_1, serv_data_1}, \ + {serv_id_2, serv_data_2}, \ + {serv_id_3, serv_data_3}, \ + {serv_id_4, serv_data_4}, \ + {NULL, NULL} \ + }; +#define FT_DEFINE_SERVICEDESCREC5(class_, serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, serv_id_3, serv_data_3, \ + serv_id_4, serv_data_4, serv_id_5, serv_data_5) \ + static const FT_ServiceDescRec class_[] = \ + { \ + {serv_id_1, serv_data_1}, \ + {serv_id_2, serv_data_2}, \ + {serv_id_3, serv_data_3}, \ + {serv_id_4, serv_data_4}, \ + {serv_id_5, serv_data_5}, \ + {NULL, NULL} \ + }; +#define FT_DEFINE_SERVICEDESCREC6(class_, serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, serv_id_3, serv_data_3, \ + serv_id_4, serv_data_4, serv_id_5, serv_data_5, \ + serv_id_6, serv_data_6) \ + static const FT_ServiceDescRec class_[] = \ + { \ + {serv_id_1, serv_data_1}, \ + {serv_id_2, serv_data_2}, \ + {serv_id_3, serv_data_3}, \ + {serv_id_4, serv_data_4}, \ + {serv_id_5, serv_data_5}, \ + {serv_id_6, serv_data_6}, \ + {NULL, NULL} \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICEDESCREC1(class_, serv_id_1, serv_data_1) \ + void \ + FT_Destroy_Class_##class_( FT_Library library, \ + FT_ServiceDescRec* clazz ) \ + { \ + FT_Memory memory = library->memory; \ + if ( clazz ) \ + FT_FREE( clazz ); \ + } \ + \ + FT_Error \ + FT_Create_Class_##class_( FT_Library library, \ + FT_ServiceDescRec** output_class) \ + { \ + FT_ServiceDescRec* clazz; \ + FT_Error error; \ + FT_Memory memory = library->memory; \ + \ + if ( FT_ALLOC( clazz, sizeof(*clazz)*2 ) ) \ + return error; \ + clazz[0].serv_id = serv_id_1; \ + clazz[0].serv_data = serv_data_1; \ + clazz[1].serv_id = NULL; \ + clazz[1].serv_data = NULL; \ + *output_class = clazz; \ + return FT_Err_Ok; \ + } + +#define FT_DEFINE_SERVICEDESCREC2(class_, serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2) \ + void \ + FT_Destroy_Class_##class_( FT_Library library, \ + FT_ServiceDescRec* clazz ) \ + { \ + FT_Memory memory = library->memory; \ + if ( clazz ) \ + FT_FREE( clazz ); \ + } \ + \ + FT_Error \ + FT_Create_Class_##class_( FT_Library library, \ + FT_ServiceDescRec** output_class) \ + { \ + FT_ServiceDescRec* clazz; \ + FT_Error error; \ + FT_Memory memory = library->memory; \ + \ + if ( FT_ALLOC( clazz, sizeof(*clazz)*3 ) ) \ + return error; \ + clazz[0].serv_id = serv_id_1; \ + clazz[0].serv_data = serv_data_1; \ + clazz[1].serv_id = serv_id_2; \ + clazz[1].serv_data = serv_data_2; \ + clazz[2].serv_id = NULL; \ + clazz[2].serv_data = NULL; \ + *output_class = clazz; \ + return FT_Err_Ok; \ + } + +#define FT_DEFINE_SERVICEDESCREC3(class_, serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, serv_id_3, serv_data_3) \ + void \ + FT_Destroy_Class_##class_( FT_Library library, \ + FT_ServiceDescRec* clazz ) \ + { \ + FT_Memory memory = library->memory; \ + if ( clazz ) \ + FT_FREE( clazz ); \ + } \ + \ + FT_Error \ + FT_Create_Class_##class_( FT_Library library, \ + FT_ServiceDescRec** output_class) \ + { \ + FT_ServiceDescRec* clazz; \ + FT_Error error; \ + FT_Memory memory = library->memory; \ + \ + if ( FT_ALLOC( clazz, sizeof(*clazz)*4 ) ) \ + return error; \ + clazz[0].serv_id = serv_id_1; \ + clazz[0].serv_data = serv_data_1; \ + clazz[1].serv_id = serv_id_2; \ + clazz[1].serv_data = serv_data_2; \ + clazz[2].serv_id = serv_id_3; \ + clazz[2].serv_data = serv_data_3; \ + clazz[3].serv_id = NULL; \ + clazz[3].serv_data = NULL; \ + *output_class = clazz; \ + return FT_Err_Ok; \ + } + +#define FT_DEFINE_SERVICEDESCREC4(class_, serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, serv_id_3, serv_data_3, \ + serv_id_4, serv_data_4) \ + void \ + FT_Destroy_Class_##class_( FT_Library library, \ + FT_ServiceDescRec* clazz ) \ + { \ + FT_Memory memory = library->memory; \ + if ( clazz ) \ + FT_FREE( clazz ); \ + } \ + \ + FT_Error \ + FT_Create_Class_##class_( FT_Library library, \ + FT_ServiceDescRec** output_class) \ + { \ + FT_ServiceDescRec* clazz; \ + FT_Error error; \ + FT_Memory memory = library->memory; \ + \ + if ( FT_ALLOC( clazz, sizeof(*clazz)*5 ) ) \ + return error; \ + clazz[0].serv_id = serv_id_1; \ + clazz[0].serv_data = serv_data_1; \ + clazz[1].serv_id = serv_id_2; \ + clazz[1].serv_data = serv_data_2; \ + clazz[2].serv_id = serv_id_3; \ + clazz[2].serv_data = serv_data_3; \ + clazz[3].serv_id = serv_id_4; \ + clazz[3].serv_data = serv_data_4; \ + clazz[4].serv_id = NULL; \ + clazz[4].serv_data = NULL; \ + *output_class = clazz; \ + return FT_Err_Ok; \ + } + +#define FT_DEFINE_SERVICEDESCREC5(class_, serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, serv_id_3, serv_data_3, serv_id_4, \ + serv_data_4, serv_id_5, serv_data_5) \ + void \ + FT_Destroy_Class_##class_( FT_Library library, \ + FT_ServiceDescRec* clazz ) \ + { \ + FT_Memory memory = library->memory; \ + if ( clazz ) \ + FT_FREE( clazz ); \ + } \ + \ + FT_Error \ + FT_Create_Class_##class_( FT_Library library, \ + FT_ServiceDescRec** output_class) \ + { \ + FT_ServiceDescRec* clazz; \ + FT_Error error; \ + FT_Memory memory = library->memory; \ + \ + if ( FT_ALLOC( clazz, sizeof(*clazz)*6 ) ) \ + return error; \ + clazz[0].serv_id = serv_id_1; \ + clazz[0].serv_data = serv_data_1; \ + clazz[1].serv_id = serv_id_2; \ + clazz[1].serv_data = serv_data_2; \ + clazz[2].serv_id = serv_id_3; \ + clazz[2].serv_data = serv_data_3; \ + clazz[3].serv_id = serv_id_4; \ + clazz[3].serv_data = serv_data_4; \ + clazz[4].serv_id = serv_id_5; \ + clazz[4].serv_data = serv_data_5; \ + clazz[5].serv_id = NULL; \ + clazz[5].serv_data = NULL; \ + *output_class = clazz; \ + return FT_Err_Ok; \ + } + +#define FT_DEFINE_SERVICEDESCREC6(class_, serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, serv_id_3, serv_data_3, \ + serv_id_4, serv_data_4, serv_id_5, serv_data_5, \ + serv_id_6, serv_data_6) \ + void \ + FT_Destroy_Class_##class_( FT_Library library, \ + FT_ServiceDescRec* clazz ) \ + { \ + FT_Memory memory = library->memory; \ + if ( clazz ) \ + FT_FREE( clazz ); \ + } \ + \ + FT_Error \ + FT_Create_Class_##class_( FT_Library library, \ + FT_ServiceDescRec** output_class) \ + { \ + FT_ServiceDescRec* clazz; \ + FT_Error error; \ + FT_Memory memory = library->memory; \ + \ + if ( FT_ALLOC( clazz, sizeof(*clazz)*7 ) ) \ + return error; \ + clazz[0].serv_id = serv_id_1; \ + clazz[0].serv_data = serv_data_1; \ + clazz[1].serv_id = serv_id_2; \ + clazz[1].serv_data = serv_data_2; \ + clazz[2].serv_id = serv_id_3; \ + clazz[2].serv_data = serv_data_3; \ + clazz[3].serv_id = serv_id_4; \ + clazz[3].serv_data = serv_data_4; \ + clazz[4].serv_id = serv_id_5; \ + clazz[4].serv_data = serv_data_5; \ + clazz[5].serv_id = serv_id_6; \ + clazz[5].serv_data = serv_data_6; \ + clazz[6].serv_id = NULL; \ + clazz[6].serv_data = NULL; \ + *output_class = clazz; \ + return FT_Err_Ok; \ + } +#endif /* FT_CONFIG_OPTION_PIC */ + + /* + * Parse a list of FT_ServiceDescRec descriptors and look for + * a specific service by ID. Note that the last element in the + * array must be { NULL, NULL }, and that the function should + * return NULL if the service isn't available. + * + * This function can be used by modules to implement their + * `get_service' method. + */ + FT_BASE( FT_Pointer ) + ft_service_list_lookup( FT_ServiceDesc service_descriptors, + const char* service_id ); + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** S E R V I C E S C A C H E *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* + * This structure is used to store a cache for several frequently used + * services. It is the type of `face->internal->services'. You + * should only use FT_FACE_LOOKUP_SERVICE to access it. + * + * All fields should have the type FT_Pointer to relax compilation + * dependencies. We assume the developer isn't completely stupid. + * + * Each field must be named `service_XXXX' where `XXX' corresponds to + * the correct FT_SERVICE_ID_XXXX macro. See the definition of + * FT_FACE_LOOKUP_SERVICE below how this is implemented. + * + */ + typedef struct FT_ServiceCacheRec_ + { + FT_Pointer service_POSTSCRIPT_FONT_NAME; + FT_Pointer service_MULTI_MASTERS; + FT_Pointer service_GLYPH_DICT; + FT_Pointer service_PFR_METRICS; + FT_Pointer service_WINFNT; + + } FT_ServiceCacheRec, *FT_ServiceCache; + + + /* + * A magic number used within the services cache. + */ +#define FT_SERVICE_UNAVAILABLE ((FT_Pointer)-2) /* magic number */ + + + /* + * @macro: + * FT_FACE_LOOKUP_SERVICE + * + * @description: + * This macro is used to lookup a service from a face's driver module + * using its cache. + * + * @input: + * face:: + * The source face handle containing the cache. + * + * field :: + * The field name in the cache. + * + * id :: + * The service ID. + * + * @output: + * ptr :: + * A variable receiving the service data. NULL if not available. + */ +#ifdef __cplusplus + +#define FT_FACE_LOOKUP_SERVICE( face, ptr, id ) \ + FT_BEGIN_STMNT \ + FT_Pointer svc; \ + FT_Pointer* Pptr = (FT_Pointer*)&(ptr); \ + \ + \ + svc = FT_FACE( face )->internal->services. service_ ## id; \ + if ( svc == FT_SERVICE_UNAVAILABLE ) \ + svc = NULL; \ + else if ( svc == NULL ) \ + { \ + FT_FACE_FIND_SERVICE( face, svc, id ); \ + \ + FT_FACE( face )->internal->services. service_ ## id = \ + (FT_Pointer)( svc != NULL ? svc \ + : FT_SERVICE_UNAVAILABLE ); \ + } \ + *Pptr = svc; \ + FT_END_STMNT + +#else /* !C++ */ + +#define FT_FACE_LOOKUP_SERVICE( face, ptr, id ) \ + FT_BEGIN_STMNT \ + FT_Pointer svc; \ + \ + \ + svc = FT_FACE( face )->internal->services. service_ ## id; \ + if ( svc == FT_SERVICE_UNAVAILABLE ) \ + svc = NULL; \ + else if ( svc == NULL ) \ + { \ + FT_FACE_FIND_SERVICE( face, svc, id ); \ + \ + FT_FACE( face )->internal->services. service_ ## id = \ + (FT_Pointer)( svc != NULL ? svc \ + : FT_SERVICE_UNAVAILABLE ); \ + } \ + ptr = svc; \ + FT_END_STMNT + +#endif /* !C++ */ + + /* + * A macro used to define new service structure types. + */ + +#define FT_DEFINE_SERVICE( name ) \ + typedef struct FT_Service_ ## name ## Rec_ \ + FT_Service_ ## name ## Rec ; \ + typedef struct FT_Service_ ## name ## Rec_ \ + const * FT_Service_ ## name ; \ + struct FT_Service_ ## name ## Rec_ + + /* */ + + /* + * The header files containing the services. + */ + +#define FT_SERVICE_BDF_H <freetype/internal/services/svbdf.h> +#define FT_SERVICE_CID_H <freetype/internal/services/svcid.h> +#define FT_SERVICE_GLYPH_DICT_H <freetype/internal/services/svgldict.h> +#define FT_SERVICE_GX_VALIDATE_H <freetype/internal/services/svgxval.h> +#define FT_SERVICE_KERNING_H <freetype/internal/services/svkern.h> +#define FT_SERVICE_MULTIPLE_MASTERS_H <freetype/internal/services/svmm.h> +#define FT_SERVICE_OPENTYPE_VALIDATE_H <freetype/internal/services/svotval.h> +#define FT_SERVICE_PFR_H <freetype/internal/services/svpfr.h> +#define FT_SERVICE_POSTSCRIPT_CMAPS_H <freetype/internal/services/svpscmap.h> +#define FT_SERVICE_POSTSCRIPT_INFO_H <freetype/internal/services/svpsinfo.h> +#define FT_SERVICE_POSTSCRIPT_NAME_H <freetype/internal/services/svpostnm.h> +#define FT_SERVICE_SFNT_H <freetype/internal/services/svsfnt.h> +#define FT_SERVICE_TRUETYPE_ENGINE_H <freetype/internal/services/svtteng.h> +#define FT_SERVICE_TT_CMAP_H <freetype/internal/services/svttcmap.h> +#define FT_SERVICE_WINFNT_H <freetype/internal/services/svwinfnt.h> +#define FT_SERVICE_XFREE86_NAME_H <freetype/internal/services/svxf86nm.h> +#define FT_SERVICE_TRUETYPE_GLYF_H <freetype/internal/services/svttglyf.h> + + /* */ + +FT_END_HEADER + +#endif /* __FTSERV_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/internal/ftstream.h b/mod/pub.mod/freetype.mod/include/freetype/internal/ftstream.h new file mode 100644 index 0000000..a91eb72 --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/internal/ftstream.h @@ -0,0 +1,539 @@ +/***************************************************************************/ +/* */ +/* ftstream.h */ +/* */ +/* Stream handling (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2004, 2005, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTSTREAM_H__ +#define __FTSTREAM_H__ + + +#include <ft2build.h> +#include FT_SYSTEM_H +#include FT_INTERNAL_OBJECTS_H + + +FT_BEGIN_HEADER + + + /* format of an 8-bit frame_op value: */ + /* */ + /* bit 76543210 */ + /* xxxxxxes */ + /* */ + /* s is set to 1 if the value is signed. */ + /* e is set to 1 if the value is little-endian. */ + /* xxx is a command. */ + +#define FT_FRAME_OP_SHIFT 2 +#define FT_FRAME_OP_SIGNED 1 +#define FT_FRAME_OP_LITTLE 2 +#define FT_FRAME_OP_COMMAND( x ) ( x >> FT_FRAME_OP_SHIFT ) + +#define FT_MAKE_FRAME_OP( command, little, sign ) \ + ( ( command << FT_FRAME_OP_SHIFT ) | ( little << 1 ) | sign ) + +#define FT_FRAME_OP_END 0 +#define FT_FRAME_OP_START 1 /* start a new frame */ +#define FT_FRAME_OP_BYTE 2 /* read 1-byte value */ +#define FT_FRAME_OP_SHORT 3 /* read 2-byte value */ +#define FT_FRAME_OP_LONG 4 /* read 4-byte value */ +#define FT_FRAME_OP_OFF3 5 /* read 3-byte value */ +#define FT_FRAME_OP_BYTES 6 /* read a bytes sequence */ + + + typedef enum FT_Frame_Op_ + { + ft_frame_end = 0, + ft_frame_start = FT_MAKE_FRAME_OP( FT_FRAME_OP_START, 0, 0 ), + + ft_frame_byte = FT_MAKE_FRAME_OP( FT_FRAME_OP_BYTE, 0, 0 ), + ft_frame_schar = FT_MAKE_FRAME_OP( FT_FRAME_OP_BYTE, 0, 1 ), + + ft_frame_ushort_be = FT_MAKE_FRAME_OP( FT_FRAME_OP_SHORT, 0, 0 ), + ft_frame_short_be = FT_MAKE_FRAME_OP( FT_FRAME_OP_SHORT, 0, 1 ), + ft_frame_ushort_le = FT_MAKE_FRAME_OP( FT_FRAME_OP_SHORT, 1, 0 ), + ft_frame_short_le = FT_MAKE_FRAME_OP( FT_FRAME_OP_SHORT, 1, 1 ), + + ft_frame_ulong_be = FT_MAKE_FRAME_OP( FT_FRAME_OP_LONG, 0, 0 ), + ft_frame_long_be = FT_MAKE_FRAME_OP( FT_FRAME_OP_LONG, 0, 1 ), + ft_frame_ulong_le = FT_MAKE_FRAME_OP( FT_FRAME_OP_LONG, 1, 0 ), + ft_frame_long_le = FT_MAKE_FRAME_OP( FT_FRAME_OP_LONG, 1, 1 ), + + ft_frame_uoff3_be = FT_MAKE_FRAME_OP( FT_FRAME_OP_OFF3, 0, 0 ), + ft_frame_off3_be = FT_MAKE_FRAME_OP( FT_FRAME_OP_OFF3, 0, 1 ), + ft_frame_uoff3_le = FT_MAKE_FRAME_OP( FT_FRAME_OP_OFF3, 1, 0 ), + ft_frame_off3_le = FT_MAKE_FRAME_OP( FT_FRAME_OP_OFF3, 1, 1 ), + + ft_frame_bytes = FT_MAKE_FRAME_OP( FT_FRAME_OP_BYTES, 0, 0 ), + ft_frame_skip = FT_MAKE_FRAME_OP( FT_FRAME_OP_BYTES, 0, 1 ) + + } FT_Frame_Op; + + + typedef struct FT_Frame_Field_ + { + FT_Byte value; + FT_Byte size; + FT_UShort offset; + + } FT_Frame_Field; + + + /* Construct an FT_Frame_Field out of a structure type and a field name. */ + /* The structure type must be set in the FT_STRUCTURE macro before */ + /* calling the FT_FRAME_START() macro. */ + /* */ +#define FT_FIELD_SIZE( f ) \ + (FT_Byte)sizeof ( ((FT_STRUCTURE*)0)->f ) + +#define FT_FIELD_SIZE_DELTA( f ) \ + (FT_Byte)sizeof ( ((FT_STRUCTURE*)0)->f[0] ) + +#define FT_FIELD_OFFSET( f ) \ + (FT_UShort)( offsetof( FT_STRUCTURE, f ) ) + +#define FT_FRAME_FIELD( frame_op, field ) \ + { \ + frame_op, \ + FT_FIELD_SIZE( field ), \ + FT_FIELD_OFFSET( field ) \ + } + +#define FT_MAKE_EMPTY_FIELD( frame_op ) { frame_op, 0, 0 } + +#define FT_FRAME_START( size ) { ft_frame_start, 0, size } +#define FT_FRAME_END { ft_frame_end, 0, 0 } + +#define FT_FRAME_LONG( f ) FT_FRAME_FIELD( ft_frame_long_be, f ) +#define FT_FRAME_ULONG( f ) FT_FRAME_FIELD( ft_frame_ulong_be, f ) +#define FT_FRAME_SHORT( f ) FT_FRAME_FIELD( ft_frame_short_be, f ) +#define FT_FRAME_USHORT( f ) FT_FRAME_FIELD( ft_frame_ushort_be, f ) +#define FT_FRAME_OFF3( f ) FT_FRAME_FIELD( ft_frame_off3_be, f ) +#define FT_FRAME_UOFF3( f ) FT_FRAME_FIELD( ft_frame_uoff3_be, f ) +#define FT_FRAME_BYTE( f ) FT_FRAME_FIELD( ft_frame_byte, f ) +#define FT_FRAME_CHAR( f ) FT_FRAME_FIELD( ft_frame_schar, f ) + +#define FT_FRAME_LONG_LE( f ) FT_FRAME_FIELD( ft_frame_long_le, f ) +#define FT_FRAME_ULONG_LE( f ) FT_FRAME_FIELD( ft_frame_ulong_le, f ) +#define FT_FRAME_SHORT_LE( f ) FT_FRAME_FIELD( ft_frame_short_le, f ) +#define FT_FRAME_USHORT_LE( f ) FT_FRAME_FIELD( ft_frame_ushort_le, f ) +#define FT_FRAME_OFF3_LE( f ) FT_FRAME_FIELD( ft_frame_off3_le, f ) +#define FT_FRAME_UOFF3_LE( f ) FT_FRAME_FIELD( ft_frame_uoff3_le, f ) + +#define FT_FRAME_SKIP_LONG { ft_frame_long_be, 0, 0 } +#define FT_FRAME_SKIP_SHORT { ft_frame_short_be, 0, 0 } +#define FT_FRAME_SKIP_BYTE { ft_frame_byte, 0, 0 } + +#define FT_FRAME_BYTES( field, count ) \ + { \ + ft_frame_bytes, \ + count, \ + FT_FIELD_OFFSET( field ) \ + } + +#define FT_FRAME_SKIP_BYTES( count ) { ft_frame_skip, count, 0 } + + + /*************************************************************************/ + /* */ + /* Integer extraction macros -- the `buffer' parameter must ALWAYS be of */ + /* type `char*' or equivalent (1-byte elements). */ + /* */ + +#define FT_BYTE_( p, i ) ( ((const FT_Byte*)(p))[(i)] ) +#define FT_INT8_( p, i ) ( ((const FT_Char*)(p))[(i)] ) + +#define FT_INT16( x ) ( (FT_Int16)(x) ) +#define FT_UINT16( x ) ( (FT_UInt16)(x) ) +#define FT_INT32( x ) ( (FT_Int32)(x) ) +#define FT_UINT32( x ) ( (FT_UInt32)(x) ) + +#define FT_BYTE_I16( p, i, s ) ( FT_INT16( FT_BYTE_( p, i ) ) << (s) ) +#define FT_BYTE_U16( p, i, s ) ( FT_UINT16( FT_BYTE_( p, i ) ) << (s) ) +#define FT_BYTE_I32( p, i, s ) ( FT_INT32( FT_BYTE_( p, i ) ) << (s) ) +#define FT_BYTE_U32( p, i, s ) ( FT_UINT32( FT_BYTE_( p, i ) ) << (s) ) + +#define FT_INT8_I16( p, i, s ) ( FT_INT16( FT_INT8_( p, i ) ) << (s) ) +#define FT_INT8_U16( p, i, s ) ( FT_UINT16( FT_INT8_( p, i ) ) << (s) ) +#define FT_INT8_I32( p, i, s ) ( FT_INT32( FT_INT8_( p, i ) ) << (s) ) +#define FT_INT8_U32( p, i, s ) ( FT_UINT32( FT_INT8_( p, i ) ) << (s) ) + + +#define FT_PEEK_SHORT( p ) FT_INT16( FT_INT8_I16( p, 0, 8) | \ + FT_BYTE_I16( p, 1, 0) ) + +#define FT_PEEK_USHORT( p ) FT_UINT16( FT_BYTE_U16( p, 0, 8 ) | \ + FT_BYTE_U16( p, 1, 0 ) ) + +#define FT_PEEK_LONG( p ) FT_INT32( FT_INT8_I32( p, 0, 24 ) | \ + FT_BYTE_I32( p, 1, 16 ) | \ + FT_BYTE_I32( p, 2, 8 ) | \ + FT_BYTE_I32( p, 3, 0 ) ) + +#define FT_PEEK_ULONG( p ) FT_UINT32( FT_BYTE_U32( p, 0, 24 ) | \ + FT_BYTE_U32( p, 1, 16 ) | \ + FT_BYTE_U32( p, 2, 8 ) | \ + FT_BYTE_U32( p, 3, 0 ) ) + +#define FT_PEEK_OFF3( p ) FT_INT32( FT_INT8_I32( p, 0, 16 ) | \ + FT_BYTE_I32( p, 1, 8 ) | \ + FT_BYTE_I32( p, 2, 0 ) ) + +#define FT_PEEK_UOFF3( p ) FT_UINT32( FT_BYTE_U32( p, 0, 16 ) | \ + FT_BYTE_U32( p, 1, 8 ) | \ + FT_BYTE_U32( p, 2, 0 ) ) + +#define FT_PEEK_SHORT_LE( p ) FT_INT16( FT_INT8_I16( p, 1, 8 ) | \ + FT_BYTE_I16( p, 0, 0 ) ) + +#define FT_PEEK_USHORT_LE( p ) FT_UINT16( FT_BYTE_U16( p, 1, 8 ) | \ + FT_BYTE_U16( p, 0, 0 ) ) + +#define FT_PEEK_LONG_LE( p ) FT_INT32( FT_INT8_I32( p, 3, 24 ) | \ + FT_BYTE_I32( p, 2, 16 ) | \ + FT_BYTE_I32( p, 1, 8 ) | \ + FT_BYTE_I32( p, 0, 0 ) ) + +#define FT_PEEK_ULONG_LE( p ) FT_UINT32( FT_BYTE_U32( p, 3, 24 ) | \ + FT_BYTE_U32( p, 2, 16 ) | \ + FT_BYTE_U32( p, 1, 8 ) | \ + FT_BYTE_U32( p, 0, 0 ) ) + +#define FT_PEEK_OFF3_LE( p ) FT_INT32( FT_INT8_I32( p, 2, 16 ) | \ + FT_BYTE_I32( p, 1, 8 ) | \ + FT_BYTE_I32( p, 0, 0 ) ) + +#define FT_PEEK_UOFF3_LE( p ) FT_UINT32( FT_BYTE_U32( p, 2, 16 ) | \ + FT_BYTE_U32( p, 1, 8 ) | \ + FT_BYTE_U32( p, 0, 0 ) ) + + +#define FT_NEXT_CHAR( buffer ) \ + ( (signed char)*buffer++ ) + +#define FT_NEXT_BYTE( buffer ) \ + ( (unsigned char)*buffer++ ) + +#define FT_NEXT_SHORT( buffer ) \ + ( (short)( buffer += 2, FT_PEEK_SHORT( buffer - 2 ) ) ) + +#define FT_NEXT_USHORT( buffer ) \ + ( (unsigned short)( buffer += 2, FT_PEEK_USHORT( buffer - 2 ) ) ) + +#define FT_NEXT_OFF3( buffer ) \ + ( (long)( buffer += 3, FT_PEEK_OFF3( buffer - 3 ) ) ) + +#define FT_NEXT_UOFF3( buffer ) \ + ( (unsigned long)( buffer += 3, FT_PEEK_UOFF3( buffer - 3 ) ) ) + +#define FT_NEXT_LONG( buffer ) \ + ( (long)( buffer += 4, FT_PEEK_LONG( buffer - 4 ) ) ) + +#define FT_NEXT_ULONG( buffer ) \ + ( (unsigned long)( buffer += 4, FT_PEEK_ULONG( buffer - 4 ) ) ) + + +#define FT_NEXT_SHORT_LE( buffer ) \ + ( (short)( buffer += 2, FT_PEEK_SHORT_LE( buffer - 2 ) ) ) + +#define FT_NEXT_USHORT_LE( buffer ) \ + ( (unsigned short)( buffer += 2, FT_PEEK_USHORT_LE( buffer - 2 ) ) ) + +#define FT_NEXT_OFF3_LE( buffer ) \ + ( (long)( buffer += 3, FT_PEEK_OFF3_LE( buffer - 3 ) ) ) + +#define FT_NEXT_UOFF3_LE( buffer ) \ + ( (unsigned long)( buffer += 3, FT_PEEK_UOFF3_LE( buffer - 3 ) ) ) + +#define FT_NEXT_LONG_LE( buffer ) \ + ( (long)( buffer += 4, FT_PEEK_LONG_LE( buffer - 4 ) ) ) + +#define FT_NEXT_ULONG_LE( buffer ) \ + ( (unsigned long)( buffer += 4, FT_PEEK_ULONG_LE( buffer - 4 ) ) ) + + + /*************************************************************************/ + /* */ + /* Each GET_xxxx() macro uses an implicit `stream' variable. */ + /* */ +#if 0 +#define FT_GET_MACRO( type ) FT_NEXT_ ## type ( stream->cursor ) + +#define FT_GET_CHAR() FT_GET_MACRO( CHAR ) +#define FT_GET_BYTE() FT_GET_MACRO( BYTE ) +#define FT_GET_SHORT() FT_GET_MACRO( SHORT ) +#define FT_GET_USHORT() FT_GET_MACRO( USHORT ) +#define FT_GET_OFF3() FT_GET_MACRO( OFF3 ) +#define FT_GET_UOFF3() FT_GET_MACRO( UOFF3 ) +#define FT_GET_LONG() FT_GET_MACRO( LONG ) +#define FT_GET_ULONG() FT_GET_MACRO( ULONG ) +#define FT_GET_TAG4() FT_GET_MACRO( ULONG ) + +#define FT_GET_SHORT_LE() FT_GET_MACRO( SHORT_LE ) +#define FT_GET_USHORT_LE() FT_GET_MACRO( USHORT_LE ) +#define FT_GET_LONG_LE() FT_GET_MACRO( LONG_LE ) +#define FT_GET_ULONG_LE() FT_GET_MACRO( ULONG_LE ) + +#else +#define FT_GET_MACRO( func, type ) ( (type)func( stream ) ) + +#define FT_GET_CHAR() FT_GET_MACRO( FT_Stream_GetChar, FT_Char ) +#define FT_GET_BYTE() FT_GET_MACRO( FT_Stream_GetChar, FT_Byte ) +#define FT_GET_SHORT() FT_GET_MACRO( FT_Stream_GetShort, FT_Short ) +#define FT_GET_USHORT() FT_GET_MACRO( FT_Stream_GetShort, FT_UShort ) +#define FT_GET_OFF3() FT_GET_MACRO( FT_Stream_GetOffset, FT_Long ) +#define FT_GET_UOFF3() FT_GET_MACRO( FT_Stream_GetOffset, FT_ULong ) +#define FT_GET_LONG() FT_GET_MACRO( FT_Stream_GetLong, FT_Long ) +#define FT_GET_ULONG() FT_GET_MACRO( FT_Stream_GetLong, FT_ULong ) +#define FT_GET_TAG4() FT_GET_MACRO( FT_Stream_GetLong, FT_ULong ) + +#define FT_GET_SHORT_LE() FT_GET_MACRO( FT_Stream_GetShortLE, FT_Short ) +#define FT_GET_USHORT_LE() FT_GET_MACRO( FT_Stream_GetShortLE, FT_UShort ) +#define FT_GET_LONG_LE() FT_GET_MACRO( FT_Stream_GetLongLE, FT_Long ) +#define FT_GET_ULONG_LE() FT_GET_MACRO( FT_Stream_GetLongLE, FT_ULong ) +#endif + +#define FT_READ_MACRO( func, type, var ) \ + ( var = (type)func( stream, &error ), \ + error != FT_Err_Ok ) + +#define FT_READ_BYTE( var ) FT_READ_MACRO( FT_Stream_ReadChar, FT_Byte, var ) +#define FT_READ_CHAR( var ) FT_READ_MACRO( FT_Stream_ReadChar, FT_Char, var ) +#define FT_READ_SHORT( var ) FT_READ_MACRO( FT_Stream_ReadShort, FT_Short, var ) +#define FT_READ_USHORT( var ) FT_READ_MACRO( FT_Stream_ReadShort, FT_UShort, var ) +#define FT_READ_OFF3( var ) FT_READ_MACRO( FT_Stream_ReadOffset, FT_Long, var ) +#define FT_READ_UOFF3( var ) FT_READ_MACRO( FT_Stream_ReadOffset, FT_ULong, var ) +#define FT_READ_LONG( var ) FT_READ_MACRO( FT_Stream_ReadLong, FT_Long, var ) +#define FT_READ_ULONG( var ) FT_READ_MACRO( FT_Stream_ReadLong, FT_ULong, var ) + +#define FT_READ_SHORT_LE( var ) FT_READ_MACRO( FT_Stream_ReadShortLE, FT_Short, var ) +#define FT_READ_USHORT_LE( var ) FT_READ_MACRO( FT_Stream_ReadShortLE, FT_UShort, var ) +#define FT_READ_LONG_LE( var ) FT_READ_MACRO( FT_Stream_ReadLongLE, FT_Long, var ) +#define FT_READ_ULONG_LE( var ) FT_READ_MACRO( FT_Stream_ReadLongLE, FT_ULong, var ) + + +#ifndef FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM + + /* initialize a stream for reading a regular system stream */ + FT_BASE( FT_Error ) + FT_Stream_Open( FT_Stream stream, + const char* filepathname ); + +#endif /* FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM */ + + + /* create a new (input) stream from an FT_Open_Args structure */ + FT_BASE( FT_Error ) + FT_Stream_New( FT_Library library, + const FT_Open_Args* args, + FT_Stream *astream ); + + /* free a stream */ + FT_BASE( void ) + FT_Stream_Free( FT_Stream stream, + FT_Int external ); + + /* initialize a stream for reading in-memory data */ + FT_BASE( void ) + FT_Stream_OpenMemory( FT_Stream stream, + const FT_Byte* base, + FT_ULong size ); + + /* close a stream (does not destroy the stream structure) */ + FT_BASE( void ) + FT_Stream_Close( FT_Stream stream ); + + + /* seek within a stream. position is relative to start of stream */ + FT_BASE( FT_Error ) + FT_Stream_Seek( FT_Stream stream, + FT_ULong pos ); + + /* skip bytes in a stream */ + FT_BASE( FT_Error ) + FT_Stream_Skip( FT_Stream stream, + FT_Long distance ); + + /* return current stream position */ + FT_BASE( FT_Long ) + FT_Stream_Pos( FT_Stream stream ); + + /* read bytes from a stream into a user-allocated buffer, returns an */ + /* error if not all bytes could be read. */ + FT_BASE( FT_Error ) + FT_Stream_Read( FT_Stream stream, + FT_Byte* buffer, + FT_ULong count ); + + /* read bytes from a stream at a given position */ + FT_BASE( FT_Error ) + FT_Stream_ReadAt( FT_Stream stream, + FT_ULong pos, + FT_Byte* buffer, + FT_ULong count ); + + /* try to read bytes at the end of a stream; return number of bytes */ + /* really available */ + FT_BASE( FT_ULong ) + FT_Stream_TryRead( FT_Stream stream, + FT_Byte* buffer, + FT_ULong count ); + + /* Enter a frame of `count' consecutive bytes in a stream. Returns an */ + /* error if the frame could not be read/accessed. The caller can use */ + /* the FT_Stream_Get_XXX functions to retrieve frame data without */ + /* error checks. */ + /* */ + /* You must _always_ call FT_Stream_ExitFrame() once you have entered */ + /* a stream frame! */ + /* */ + FT_BASE( FT_Error ) + FT_Stream_EnterFrame( FT_Stream stream, + FT_ULong count ); + + /* exit a stream frame */ + FT_BASE( void ) + FT_Stream_ExitFrame( FT_Stream stream ); + + /* Extract a stream frame. If the stream is disk-based, a heap block */ + /* is allocated and the frame bytes are read into it. If the stream */ + /* is memory-based, this function simply set a pointer to the data. */ + /* */ + /* Useful to optimize access to memory-based streams transparently. */ + /* */ + /* All extracted frames must be `freed' with a call to the function */ + /* FT_Stream_ReleaseFrame(). */ + /* */ + FT_BASE( FT_Error ) + FT_Stream_ExtractFrame( FT_Stream stream, + FT_ULong count, + FT_Byte** pbytes ); + + /* release an extract frame (see FT_Stream_ExtractFrame) */ + FT_BASE( void ) + FT_Stream_ReleaseFrame( FT_Stream stream, + FT_Byte** pbytes ); + + /* read a byte from an entered frame */ + FT_BASE( FT_Char ) + FT_Stream_GetChar( FT_Stream stream ); + + /* read a 16-bit big-endian integer from an entered frame */ + FT_BASE( FT_Short ) + FT_Stream_GetShort( FT_Stream stream ); + + /* read a 24-bit big-endian integer from an entered frame */ + FT_BASE( FT_Long ) + FT_Stream_GetOffset( FT_Stream stream ); + + /* read a 32-bit big-endian integer from an entered frame */ + FT_BASE( FT_Long ) + FT_Stream_GetLong( FT_Stream stream ); + + /* read a 16-bit little-endian integer from an entered frame */ + FT_BASE( FT_Short ) + FT_Stream_GetShortLE( FT_Stream stream ); + + /* read a 32-bit little-endian integer from an entered frame */ + FT_BASE( FT_Long ) + FT_Stream_GetLongLE( FT_Stream stream ); + + + /* read a byte from a stream */ + FT_BASE( FT_Char ) + FT_Stream_ReadChar( FT_Stream stream, + FT_Error* error ); + + /* read a 16-bit big-endian integer from a stream */ + FT_BASE( FT_Short ) + FT_Stream_ReadShort( FT_Stream stream, + FT_Error* error ); + + /* read a 24-bit big-endian integer from a stream */ + FT_BASE( FT_Long ) + FT_Stream_ReadOffset( FT_Stream stream, + FT_Error* error ); + + /* read a 32-bit big-endian integer from a stream */ + FT_BASE( FT_Long ) + FT_Stream_ReadLong( FT_Stream stream, + FT_Error* error ); + + /* read a 16-bit little-endian integer from a stream */ + FT_BASE( FT_Short ) + FT_Stream_ReadShortLE( FT_Stream stream, + FT_Error* error ); + + /* read a 32-bit little-endian integer from a stream */ + FT_BASE( FT_Long ) + FT_Stream_ReadLongLE( FT_Stream stream, + FT_Error* error ); + + /* Read a structure from a stream. The structure must be described */ + /* by an array of FT_Frame_Field records. */ + FT_BASE( FT_Error ) + FT_Stream_ReadFields( FT_Stream stream, + const FT_Frame_Field* fields, + void* structure ); + + +#define FT_STREAM_POS() \ + FT_Stream_Pos( stream ) + +#define FT_STREAM_SEEK( position ) \ + FT_SET_ERROR( FT_Stream_Seek( stream, position ) ) + +#define FT_STREAM_SKIP( distance ) \ + FT_SET_ERROR( FT_Stream_Skip( stream, distance ) ) + +#define FT_STREAM_READ( buffer, count ) \ + FT_SET_ERROR( FT_Stream_Read( stream, \ + (FT_Byte*)buffer, \ + count ) ) + +#define FT_STREAM_READ_AT( position, buffer, count ) \ + FT_SET_ERROR( FT_Stream_ReadAt( stream, \ + position, \ + (FT_Byte*)buffer, \ + count ) ) + +#define FT_STREAM_READ_FIELDS( fields, object ) \ + FT_SET_ERROR( FT_Stream_ReadFields( stream, fields, object ) ) + + +#define FT_FRAME_ENTER( size ) \ + FT_SET_ERROR( \ + FT_DEBUG_INNER( FT_Stream_EnterFrame( stream, size ) ) ) + +#define FT_FRAME_EXIT() \ + FT_DEBUG_INNER( FT_Stream_ExitFrame( stream ) ) + +#define FT_FRAME_EXTRACT( size, bytes ) \ + FT_SET_ERROR( \ + FT_DEBUG_INNER( FT_Stream_ExtractFrame( stream, size, \ + (FT_Byte**)&(bytes) ) ) ) + +#define FT_FRAME_RELEASE( bytes ) \ + FT_DEBUG_INNER( FT_Stream_ReleaseFrame( stream, \ + (FT_Byte**)&(bytes) ) ) + + +FT_END_HEADER + +#endif /* __FTSTREAM_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/internal/fttrace.h b/mod/pub.mod/freetype.mod/include/freetype/internal/fttrace.h new file mode 100644 index 0000000..e9b383a --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/internal/fttrace.h @@ -0,0 +1,139 @@ +/***************************************************************************/ +/* */ +/* fttrace.h */ +/* */ +/* Tracing handling (specification only). */ +/* */ +/* Copyright 2002, 2004, 2005, 2006, 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /* definitions of trace levels for FreeType 2 */ + + /* the first level must always be `trace_any' */ +FT_TRACE_DEF( any ) + + /* base components */ +FT_TRACE_DEF( calc ) /* calculations (ftcalc.c) */ +FT_TRACE_DEF( memory ) /* memory manager (ftobjs.c) */ +FT_TRACE_DEF( stream ) /* stream manager (ftstream.c) */ +FT_TRACE_DEF( io ) /* i/o interface (ftsystem.c) */ +FT_TRACE_DEF( list ) /* list management (ftlist.c) */ +FT_TRACE_DEF( init ) /* initialization (ftinit.c) */ +FT_TRACE_DEF( objs ) /* base objects (ftobjs.c) */ +FT_TRACE_DEF( outline ) /* outline management (ftoutln.c) */ +FT_TRACE_DEF( glyph ) /* glyph management (ftglyph.c) */ +FT_TRACE_DEF( gloader ) /* glyph loader (ftgloadr.c) */ + +FT_TRACE_DEF( raster ) /* monochrome rasterizer (ftraster.c) */ +FT_TRACE_DEF( smooth ) /* anti-aliasing raster (ftgrays.c) */ +FT_TRACE_DEF( mm ) /* MM interface (ftmm.c) */ +FT_TRACE_DEF( raccess ) /* resource fork accessor (ftrfork.c) */ +FT_TRACE_DEF( synth ) /* bold/slant synthesizer (ftsynth.c) */ + + /* Cache sub-system */ +FT_TRACE_DEF( cache ) /* cache sub-system (ftcache.c, etc.) */ + + /* SFNT driver components */ +FT_TRACE_DEF( sfdriver ) /* SFNT font driver (sfdriver.c) */ +FT_TRACE_DEF( sfobjs ) /* SFNT object handler (sfobjs.c) */ +FT_TRACE_DEF( ttcmap ) /* charmap handler (ttcmap.c) */ +FT_TRACE_DEF( ttkern ) /* kerning handler (ttkern.c) */ +FT_TRACE_DEF( ttload ) /* basic TrueType tables (ttload.c) */ +FT_TRACE_DEF( ttmtx ) /* metrics-related tables (ttmtx.c) */ +FT_TRACE_DEF( ttpost ) /* PS table processing (ttpost.c) */ +FT_TRACE_DEF( ttsbit ) /* TrueType sbit handling (ttsbit.c) */ +FT_TRACE_DEF( ttbdf ) /* TrueType embedded BDF (ttbdf.c) */ + + /* TrueType driver components */ +FT_TRACE_DEF( ttdriver ) /* TT font driver (ttdriver.c) */ +FT_TRACE_DEF( ttgload ) /* TT glyph loader (ttgload.c) */ +FT_TRACE_DEF( ttinterp ) /* bytecode interpreter (ttinterp.c) */ +FT_TRACE_DEF( ttobjs ) /* TT objects manager (ttobjs.c) */ +FT_TRACE_DEF( ttpload ) /* TT data/program loader (ttpload.c) */ +FT_TRACE_DEF( ttgxvar ) /* TrueType GX var handler (ttgxvar.c) */ + + /* Type 1 driver components */ +FT_TRACE_DEF( t1afm ) +FT_TRACE_DEF( t1driver ) +FT_TRACE_DEF( t1gload ) +FT_TRACE_DEF( t1hint ) +FT_TRACE_DEF( t1load ) +FT_TRACE_DEF( t1objs ) +FT_TRACE_DEF( t1parse ) + + /* PostScript helper module `psaux' */ +FT_TRACE_DEF( t1decode ) +FT_TRACE_DEF( psobjs ) + + /* PostScript hinting module `pshinter' */ +FT_TRACE_DEF( pshrec ) +FT_TRACE_DEF( pshalgo1 ) +FT_TRACE_DEF( pshalgo2 ) + + /* Type 2 driver components */ +FT_TRACE_DEF( cffdriver ) +FT_TRACE_DEF( cffgload ) +FT_TRACE_DEF( cffload ) +FT_TRACE_DEF( cffobjs ) +FT_TRACE_DEF( cffparse ) + + /* Type 42 driver component */ +FT_TRACE_DEF( t42 ) + + /* CID driver components */ +FT_TRACE_DEF( cidafm ) +FT_TRACE_DEF( ciddriver ) +FT_TRACE_DEF( cidgload ) +FT_TRACE_DEF( cidload ) +FT_TRACE_DEF( cidobjs ) +FT_TRACE_DEF( cidparse ) + + /* Windows font component */ +FT_TRACE_DEF( winfnt ) + + /* PCF font components */ +FT_TRACE_DEF( pcfdriver ) +FT_TRACE_DEF( pcfread ) + + /* BDF font components */ +FT_TRACE_DEF( bdfdriver ) +FT_TRACE_DEF( bdflib ) + + /* PFR font component */ +FT_TRACE_DEF( pfr ) + + /* OpenType validation components */ +FT_TRACE_DEF( otvmodule ) +FT_TRACE_DEF( otvcommon ) +FT_TRACE_DEF( otvbase ) +FT_TRACE_DEF( otvgdef ) +FT_TRACE_DEF( otvgpos ) +FT_TRACE_DEF( otvgsub ) +FT_TRACE_DEF( otvjstf ) +FT_TRACE_DEF( otvmath ) + + /* TrueTypeGX/AAT validation components */ +FT_TRACE_DEF( gxvmodule ) +FT_TRACE_DEF( gxvcommon ) +FT_TRACE_DEF( gxvfeat ) +FT_TRACE_DEF( gxvmort ) +FT_TRACE_DEF( gxvmorx ) +FT_TRACE_DEF( gxvbsln ) +FT_TRACE_DEF( gxvjust ) +FT_TRACE_DEF( gxvkern ) +FT_TRACE_DEF( gxvopbd ) +FT_TRACE_DEF( gxvtrak ) +FT_TRACE_DEF( gxvprop ) +FT_TRACE_DEF( gxvlcar ) + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/internal/ftvalid.h b/mod/pub.mod/freetype.mod/include/freetype/internal/ftvalid.h new file mode 100644 index 0000000..00cd85e --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/internal/ftvalid.h @@ -0,0 +1,150 @@ +/***************************************************************************/ +/* */ +/* ftvalid.h */ +/* */ +/* FreeType validation support (specification). */ +/* */ +/* Copyright 2004 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTVALID_H__ +#define __FTVALID_H__ + +#include <ft2build.h> +#include FT_CONFIG_STANDARD_LIBRARY_H /* for ft_setjmp and ft_longjmp */ + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** V A L I D A T I O N ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + /* handle to a validation object */ + typedef struct FT_ValidatorRec_ volatile* FT_Validator; + + + /*************************************************************************/ + /* */ + /* There are three distinct validation levels defined here: */ + /* */ + /* FT_VALIDATE_DEFAULT :: */ + /* A table that passes this validation level can be used reliably by */ + /* FreeType. It generally means that all offsets have been checked to */ + /* prevent out-of-bound reads, that array counts are correct, etc. */ + /* */ + /* FT_VALIDATE_TIGHT :: */ + /* A table that passes this validation level can be used reliably and */ + /* doesn't contain invalid data. For example, a charmap table that */ + /* returns invalid glyph indices will not pass, even though it can */ + /* be used with FreeType in default mode (the library will simply */ + /* return an error later when trying to load the glyph). */ + /* */ + /* It also checks that fields which must be a multiple of 2, 4, or 8, */ + /* don't have incorrect values, etc. */ + /* */ + /* FT_VALIDATE_PARANOID :: */ + /* Only for font debugging. Checks that a table follows the */ + /* specification by 100%. Very few fonts will be able to pass this */ + /* level anyway but it can be useful for certain tools like font */ + /* editors/converters. */ + /* */ + typedef enum FT_ValidationLevel_ + { + FT_VALIDATE_DEFAULT = 0, + FT_VALIDATE_TIGHT, + FT_VALIDATE_PARANOID + + } FT_ValidationLevel; + + + /* validator structure */ + typedef struct FT_ValidatorRec_ + { + const FT_Byte* base; /* address of table in memory */ + const FT_Byte* limit; /* `base' + sizeof(table) in memory */ + FT_ValidationLevel level; /* validation level */ + FT_Error error; /* error returned. 0 means success */ + + ft_jmp_buf jump_buffer; /* used for exception handling */ + + } FT_ValidatorRec; + + +#define FT_VALIDATOR( x ) ((FT_Validator)( x )) + + + FT_BASE( void ) + ft_validator_init( FT_Validator valid, + const FT_Byte* base, + const FT_Byte* limit, + FT_ValidationLevel level ); + + /* Do not use this. It's broken and will cause your validator to crash */ + /* if you run it on an invalid font. */ + FT_BASE( FT_Int ) + ft_validator_run( FT_Validator valid ); + + /* Sets the error field in a validator, then calls `longjmp' to return */ + /* to high-level caller. Using `setjmp/longjmp' avoids many stupid */ + /* error checks within the validation routines. */ + /* */ + FT_BASE( void ) + ft_validator_error( FT_Validator valid, + FT_Error error ); + + + /* Calls ft_validate_error. Assumes that the `valid' local variable */ + /* holds a pointer to the current validator object. */ + /* */ + /* Use preprocessor prescan to pass FT_ERR_PREFIX. */ + /* */ +#define FT_INVALID( _prefix, _error ) FT_INVALID_( _prefix, _error ) +#define FT_INVALID_( _prefix, _error ) \ + ft_validator_error( valid, _prefix ## _error ) + + /* called when a broken table is detected */ +#define FT_INVALID_TOO_SHORT \ + FT_INVALID( FT_ERR_PREFIX, Invalid_Table ) + + /* called when an invalid offset is detected */ +#define FT_INVALID_OFFSET \ + FT_INVALID( FT_ERR_PREFIX, Invalid_Offset ) + + /* called when an invalid format/value is detected */ +#define FT_INVALID_FORMAT \ + FT_INVALID( FT_ERR_PREFIX, Invalid_Table ) + + /* called when an invalid glyph index is detected */ +#define FT_INVALID_GLYPH_ID \ + FT_INVALID( FT_ERR_PREFIX, Invalid_Glyph_Index ) + + /* called when an invalid field value is detected */ +#define FT_INVALID_DATA \ + FT_INVALID( FT_ERR_PREFIX, Invalid_Table ) + + +FT_END_HEADER + +#endif /* __FTVALID_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/internal/internal.h b/mod/pub.mod/freetype.mod/include/freetype/internal/internal.h new file mode 100644 index 0000000..f500a65 --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/internal/internal.h @@ -0,0 +1,51 @@ +/***************************************************************************/ +/* */ +/* internal.h */ +/* */ +/* Internal header files (specification only). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file is automatically included by `ft2build.h'. */ + /* Do not include it manually! */ + /* */ + /*************************************************************************/ + + +#define FT_INTERNAL_OBJECTS_H <freetype/internal/ftobjs.h> +#define FT_INTERNAL_PIC_H <freetype/internal/ftpic.h> +#define FT_INTERNAL_STREAM_H <freetype/internal/ftstream.h> +#define FT_INTERNAL_MEMORY_H <freetype/internal/ftmemory.h> +#define FT_INTERNAL_DEBUG_H <freetype/internal/ftdebug.h> +#define FT_INTERNAL_CALC_H <freetype/internal/ftcalc.h> +#define FT_INTERNAL_DRIVER_H <freetype/internal/ftdriver.h> +#define FT_INTERNAL_TRACE_H <freetype/internal/fttrace.h> +#define FT_INTERNAL_GLYPH_LOADER_H <freetype/internal/ftgloadr.h> +#define FT_INTERNAL_SFNT_H <freetype/internal/sfnt.h> +#define FT_INTERNAL_SERVICE_H <freetype/internal/ftserv.h> +#define FT_INTERNAL_RFORK_H <freetype/internal/ftrfork.h> +#define FT_INTERNAL_VALIDATE_H <freetype/internal/ftvalid.h> + +#define FT_INTERNAL_TRUETYPE_TYPES_H <freetype/internal/tttypes.h> +#define FT_INTERNAL_TYPE1_TYPES_H <freetype/internal/t1types.h> + +#define FT_INTERNAL_POSTSCRIPT_AUX_H <freetype/internal/psaux.h> +#define FT_INTERNAL_POSTSCRIPT_HINTS_H <freetype/internal/pshints.h> +#define FT_INTERNAL_POSTSCRIPT_GLOBALS_H <freetype/internal/psglobal.h> + +#define FT_INTERNAL_AUTOHINT_H <freetype/internal/autohint.h> + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/internal/pcftypes.h b/mod/pub.mod/freetype.mod/include/freetype/internal/pcftypes.h new file mode 100644 index 0000000..382796f --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/internal/pcftypes.h @@ -0,0 +1,56 @@ +/* pcftypes.h + + FreeType font driver for pcf fonts + + Copyright (C) 2000, 2001, 2002 by + Francesco Zappa Nardelli + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + + +#ifndef __PCFTYPES_H__ +#define __PCFTYPES_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + + +FT_BEGIN_HEADER + + + typedef struct PCF_Public_FaceRec_ + { + FT_FaceRec root; + FT_StreamRec gzip_stream; + FT_Stream gzip_source; + + char* charset_encoding; + char* charset_registry; + + } PCF_Public_FaceRec, *PCF_Public_Face; + + +FT_END_HEADER + +#endif /* __PCFTYPES_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/internal/psaux.h b/mod/pub.mod/freetype.mod/include/freetype/internal/psaux.h new file mode 100644 index 0000000..a96e0df --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/internal/psaux.h @@ -0,0 +1,873 @@ +/***************************************************************************/ +/* */ +/* psaux.h */ +/* */ +/* Auxiliary functions and data structures related to PostScript fonts */ +/* (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __PSAUX_H__ +#define __PSAUX_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_TYPE1_TYPES_H +#include FT_SERVICE_POSTSCRIPT_CMAPS_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** T1_TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + typedef struct PS_TableRec_* PS_Table; + typedef const struct PS_Table_FuncsRec_* PS_Table_Funcs; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* PS_Table_FuncsRec */ + /* */ + /* <Description> */ + /* A set of function pointers to manage PS_Table objects. */ + /* */ + /* <Fields> */ + /* table_init :: Used to initialize a table. */ + /* */ + /* table_done :: Finalizes resp. destroy a given table. */ + /* */ + /* table_add :: Adds a new object to a table. */ + /* */ + /* table_release :: Releases table data, then finalizes it. */ + /* */ + typedef struct PS_Table_FuncsRec_ + { + FT_Error + (*init)( PS_Table table, + FT_Int count, + FT_Memory memory ); + + void + (*done)( PS_Table table ); + + FT_Error + (*add)( PS_Table table, + FT_Int idx, + void* object, + FT_PtrDist length ); + + void + (*release)( PS_Table table ); + + } PS_Table_FuncsRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* PS_TableRec */ + /* */ + /* <Description> */ + /* A PS_Table is a simple object used to store an array of objects in */ + /* a single memory block. */ + /* */ + /* <Fields> */ + /* block :: The address in memory of the growheap's block. This */ + /* can change between two object adds, due to */ + /* reallocation. */ + /* */ + /* cursor :: The current top of the grow heap within its block. */ + /* */ + /* capacity :: The current size of the heap block. Increments by */ + /* 1kByte chunks. */ + /* */ + /* max_elems :: The maximum number of elements in table. */ + /* */ + /* num_elems :: The current number of elements in table. */ + /* */ + /* elements :: A table of element addresses within the block. */ + /* */ + /* lengths :: A table of element sizes within the block. */ + /* */ + /* memory :: The object used for memory operations */ + /* (alloc/realloc). */ + /* */ + /* funcs :: A table of method pointers for this object. */ + /* */ + typedef struct PS_TableRec_ + { + FT_Byte* block; /* current memory block */ + FT_Offset cursor; /* current cursor in memory block */ + FT_Offset capacity; /* current size of memory block */ + FT_Long init; + + FT_Int max_elems; + FT_Int num_elems; + FT_Byte** elements; /* addresses of table elements */ + FT_PtrDist* lengths; /* lengths of table elements */ + + FT_Memory memory; + PS_Table_FuncsRec funcs; + + } PS_TableRec; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** T1 FIELDS & TOKENS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef struct PS_ParserRec_* PS_Parser; + + typedef struct T1_TokenRec_* T1_Token; + + typedef struct T1_FieldRec_* T1_Field; + + + /* simple enumeration type used to identify token types */ + typedef enum T1_TokenType_ + { + T1_TOKEN_TYPE_NONE = 0, + T1_TOKEN_TYPE_ANY, + T1_TOKEN_TYPE_STRING, + T1_TOKEN_TYPE_ARRAY, + T1_TOKEN_TYPE_KEY, /* aka `name' */ + + /* do not remove */ + T1_TOKEN_TYPE_MAX + + } T1_TokenType; + + + /* a simple structure used to identify tokens */ + typedef struct T1_TokenRec_ + { + FT_Byte* start; /* first character of token in input stream */ + FT_Byte* limit; /* first character after the token */ + T1_TokenType type; /* type of token */ + + } T1_TokenRec; + + + /* enumeration type used to identify object fields */ + typedef enum T1_FieldType_ + { + T1_FIELD_TYPE_NONE = 0, + T1_FIELD_TYPE_BOOL, + T1_FIELD_TYPE_INTEGER, + T1_FIELD_TYPE_FIXED, + T1_FIELD_TYPE_FIXED_1000, + T1_FIELD_TYPE_STRING, + T1_FIELD_TYPE_KEY, + T1_FIELD_TYPE_BBOX, + T1_FIELD_TYPE_INTEGER_ARRAY, + T1_FIELD_TYPE_FIXED_ARRAY, + T1_FIELD_TYPE_CALLBACK, + + /* do not remove */ + T1_FIELD_TYPE_MAX + + } T1_FieldType; + + + typedef enum T1_FieldLocation_ + { + T1_FIELD_LOCATION_CID_INFO, + T1_FIELD_LOCATION_FONT_DICT, + T1_FIELD_LOCATION_FONT_EXTRA, + T1_FIELD_LOCATION_FONT_INFO, + T1_FIELD_LOCATION_PRIVATE, + T1_FIELD_LOCATION_BBOX, + T1_FIELD_LOCATION_LOADER, + T1_FIELD_LOCATION_FACE, + T1_FIELD_LOCATION_BLEND, + + /* do not remove */ + T1_FIELD_LOCATION_MAX + + } T1_FieldLocation; + + + typedef void + (*T1_Field_ParseFunc)( FT_Face face, + FT_Pointer parser ); + + + /* structure type used to model object fields */ + typedef struct T1_FieldRec_ + { + const char* ident; /* field identifier */ + T1_FieldLocation location; + T1_FieldType type; /* type of field */ + T1_Field_ParseFunc reader; + FT_UInt offset; /* offset of field in object */ + FT_Byte size; /* size of field in bytes */ + FT_UInt array_max; /* maximal number of elements for */ + /* array */ + FT_UInt count_offset; /* offset of element count for */ + /* arrays; must not be zero if in */ + /* use -- in other words, a */ + /* `num_FOO' element must not */ + /* start the used structure if we */ + /* parse a `FOO' array */ + FT_UInt dict; /* where we expect it */ + } T1_FieldRec; + +#define T1_FIELD_DICT_FONTDICT ( 1 << 0 ) /* also FontInfo and FDArray */ +#define T1_FIELD_DICT_PRIVATE ( 1 << 1 ) + + + +#define T1_NEW_SIMPLE_FIELD( _ident, _type, _fname, _dict ) \ + { \ + _ident, T1CODE, _type, \ + 0, \ + FT_FIELD_OFFSET( _fname ), \ + FT_FIELD_SIZE( _fname ), \ + 0, 0, \ + _dict \ + }, + +#define T1_NEW_CALLBACK_FIELD( _ident, _reader, _dict ) \ + { \ + _ident, T1CODE, T1_FIELD_TYPE_CALLBACK, \ + (T1_Field_ParseFunc)_reader, \ + 0, 0, \ + 0, 0, \ + _dict \ + }, + +#define T1_NEW_TABLE_FIELD( _ident, _type, _fname, _max, _dict ) \ + { \ + _ident, T1CODE, _type, \ + 0, \ + FT_FIELD_OFFSET( _fname ), \ + FT_FIELD_SIZE_DELTA( _fname ), \ + _max, \ + FT_FIELD_OFFSET( num_ ## _fname ), \ + _dict \ + }, + +#define T1_NEW_TABLE_FIELD2( _ident, _type, _fname, _max, _dict ) \ + { \ + _ident, T1CODE, _type, \ + 0, \ + FT_FIELD_OFFSET( _fname ), \ + FT_FIELD_SIZE_DELTA( _fname ), \ + _max, 0, \ + _dict \ + }, + + +#define T1_FIELD_BOOL( _ident, _fname, _dict ) \ + T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_BOOL, _fname, _dict ) + +#define T1_FIELD_NUM( _ident, _fname, _dict ) \ + T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_INTEGER, _fname, _dict ) + +#define T1_FIELD_FIXED( _ident, _fname, _dict ) \ + T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_FIXED, _fname, _dict ) + +#define T1_FIELD_FIXED_1000( _ident, _fname, _dict ) \ + T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_FIXED_1000, _fname, \ + _dict ) + +#define T1_FIELD_STRING( _ident, _fname, _dict ) \ + T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_STRING, _fname, _dict ) + +#define T1_FIELD_KEY( _ident, _fname, _dict ) \ + T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_KEY, _fname, _dict ) + +#define T1_FIELD_BBOX( _ident, _fname, _dict ) \ + T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_BBOX, _fname, _dict ) + + +#define T1_FIELD_NUM_TABLE( _ident, _fname, _fmax, _dict ) \ + T1_NEW_TABLE_FIELD( _ident, T1_FIELD_TYPE_INTEGER_ARRAY, \ + _fname, _fmax, _dict ) + +#define T1_FIELD_FIXED_TABLE( _ident, _fname, _fmax, _dict ) \ + T1_NEW_TABLE_FIELD( _ident, T1_FIELD_TYPE_FIXED_ARRAY, \ + _fname, _fmax, _dict ) + +#define T1_FIELD_NUM_TABLE2( _ident, _fname, _fmax, _dict ) \ + T1_NEW_TABLE_FIELD2( _ident, T1_FIELD_TYPE_INTEGER_ARRAY, \ + _fname, _fmax, _dict ) + +#define T1_FIELD_FIXED_TABLE2( _ident, _fname, _fmax, _dict ) \ + T1_NEW_TABLE_FIELD2( _ident, T1_FIELD_TYPE_FIXED_ARRAY, \ + _fname, _fmax, _dict ) + +#define T1_FIELD_CALLBACK( _ident, _name, _dict ) \ + T1_NEW_CALLBACK_FIELD( _ident, _name, _dict ) + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** T1 PARSER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef const struct PS_Parser_FuncsRec_* PS_Parser_Funcs; + + typedef struct PS_Parser_FuncsRec_ + { + void + (*init)( PS_Parser parser, + FT_Byte* base, + FT_Byte* limit, + FT_Memory memory ); + + void + (*done)( PS_Parser parser ); + + void + (*skip_spaces)( PS_Parser parser ); + void + (*skip_PS_token)( PS_Parser parser ); + + FT_Long + (*to_int)( PS_Parser parser ); + FT_Fixed + (*to_fixed)( PS_Parser parser, + FT_Int power_ten ); + + FT_Error + (*to_bytes)( PS_Parser parser, + FT_Byte* bytes, + FT_Offset max_bytes, + FT_Long* pnum_bytes, + FT_Bool delimiters ); + + FT_Int + (*to_coord_array)( PS_Parser parser, + FT_Int max_coords, + FT_Short* coords ); + FT_Int + (*to_fixed_array)( PS_Parser parser, + FT_Int max_values, + FT_Fixed* values, + FT_Int power_ten ); + + void + (*to_token)( PS_Parser parser, + T1_Token token ); + void + (*to_token_array)( PS_Parser parser, + T1_Token tokens, + FT_UInt max_tokens, + FT_Int* pnum_tokens ); + + FT_Error + (*load_field)( PS_Parser parser, + const T1_Field field, + void** objects, + FT_UInt max_objects, + FT_ULong* pflags ); + + FT_Error + (*load_field_table)( PS_Parser parser, + const T1_Field field, + void** objects, + FT_UInt max_objects, + FT_ULong* pflags ); + + } PS_Parser_FuncsRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* PS_ParserRec */ + /* */ + /* <Description> */ + /* A PS_Parser is an object used to parse a Type 1 font very quickly. */ + /* */ + /* <Fields> */ + /* cursor :: The current position in the text. */ + /* */ + /* base :: Start of the processed text. */ + /* */ + /* limit :: End of the processed text. */ + /* */ + /* error :: The last error returned. */ + /* */ + /* memory :: The object used for memory operations (alloc/realloc). */ + /* */ + /* funcs :: A table of functions for the parser. */ + /* */ + typedef struct PS_ParserRec_ + { + FT_Byte* cursor; + FT_Byte* base; + FT_Byte* limit; + FT_Error error; + FT_Memory memory; + + PS_Parser_FuncsRec funcs; + + } PS_ParserRec; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** T1 BUILDER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + typedef struct T1_BuilderRec_* T1_Builder; + + + typedef FT_Error + (*T1_Builder_Check_Points_Func)( T1_Builder builder, + FT_Int count ); + + typedef void + (*T1_Builder_Add_Point_Func)( T1_Builder builder, + FT_Pos x, + FT_Pos y, + FT_Byte flag ); + + typedef FT_Error + (*T1_Builder_Add_Point1_Func)( T1_Builder builder, + FT_Pos x, + FT_Pos y ); + + typedef FT_Error + (*T1_Builder_Add_Contour_Func)( T1_Builder builder ); + + typedef FT_Error + (*T1_Builder_Start_Point_Func)( T1_Builder builder, + FT_Pos x, + FT_Pos y ); + + typedef void + (*T1_Builder_Close_Contour_Func)( T1_Builder builder ); + + + typedef const struct T1_Builder_FuncsRec_* T1_Builder_Funcs; + + typedef struct T1_Builder_FuncsRec_ + { + void + (*init)( T1_Builder builder, + FT_Face face, + FT_Size size, + FT_GlyphSlot slot, + FT_Bool hinting ); + + void + (*done)( T1_Builder builder ); + + T1_Builder_Check_Points_Func check_points; + T1_Builder_Add_Point_Func add_point; + T1_Builder_Add_Point1_Func add_point1; + T1_Builder_Add_Contour_Func add_contour; + T1_Builder_Start_Point_Func start_point; + T1_Builder_Close_Contour_Func close_contour; + + } T1_Builder_FuncsRec; + + + /* an enumeration type to handle charstring parsing states */ + typedef enum T1_ParseState_ + { + T1_Parse_Start, + T1_Parse_Have_Width, + T1_Parse_Have_Moveto, + T1_Parse_Have_Path + + } T1_ParseState; + + + /*************************************************************************/ + /* */ + /* <Structure> */ + /* T1_BuilderRec */ + /* */ + /* <Description> */ + /* A structure used during glyph loading to store its outline. */ + /* */ + /* <Fields> */ + /* memory :: The current memory object. */ + /* */ + /* face :: The current face object. */ + /* */ + /* glyph :: The current glyph slot. */ + /* */ + /* loader :: XXX */ + /* */ + /* base :: The base glyph outline. */ + /* */ + /* current :: The current glyph outline. */ + /* */ + /* max_points :: maximum points in builder outline */ + /* */ + /* max_contours :: Maximal number of contours in builder outline. */ + /* */ + /* pos_x :: The horizontal translation (if composite glyph). */ + /* */ + /* pos_y :: The vertical translation (if composite glyph). */ + /* */ + /* left_bearing :: The left side bearing point. */ + /* */ + /* advance :: The horizontal advance vector. */ + /* */ + /* bbox :: Unused. */ + /* */ + /* parse_state :: An enumeration which controls the charstring */ + /* parsing state. */ + /* */ + /* load_points :: If this flag is not set, no points are loaded. */ + /* */ + /* no_recurse :: Set but not used. */ + /* */ + /* metrics_only :: A boolean indicating that we only want to compute */ + /* the metrics of a given glyph, not load all of its */ + /* points. */ + /* */ + /* funcs :: An array of function pointers for the builder. */ + /* */ + typedef struct T1_BuilderRec_ + { + FT_Memory memory; + FT_Face face; + FT_GlyphSlot glyph; + FT_GlyphLoader loader; + FT_Outline* base; + FT_Outline* current; + + FT_Pos pos_x; + FT_Pos pos_y; + + FT_Vector left_bearing; + FT_Vector advance; + + FT_BBox bbox; /* bounding box */ + T1_ParseState parse_state; + FT_Bool load_points; + FT_Bool no_recurse; + + FT_Bool metrics_only; + + void* hints_funcs; /* hinter-specific */ + void* hints_globals; /* hinter-specific */ + + T1_Builder_FuncsRec funcs; + + } T1_BuilderRec; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** T1 DECODER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + +#if 0 + + /*************************************************************************/ + /* */ + /* T1_MAX_SUBRS_CALLS details the maximum number of nested sub-routine */ + /* calls during glyph loading. */ + /* */ +#define T1_MAX_SUBRS_CALLS 8 + + + /*************************************************************************/ + /* */ + /* T1_MAX_CHARSTRING_OPERANDS is the charstring stack's capacity. A */ + /* minimum of 16 is required. */ + /* */ +#define T1_MAX_CHARSTRINGS_OPERANDS 32 + +#endif /* 0 */ + + + typedef struct T1_Decoder_ZoneRec_ + { + FT_Byte* cursor; + FT_Byte* base; + FT_Byte* limit; + + } T1_Decoder_ZoneRec, *T1_Decoder_Zone; + + + typedef struct T1_DecoderRec_* T1_Decoder; + typedef const struct T1_Decoder_FuncsRec_* T1_Decoder_Funcs; + + + typedef FT_Error + (*T1_Decoder_Callback)( T1_Decoder decoder, + FT_UInt glyph_index ); + + + typedef struct T1_Decoder_FuncsRec_ + { + FT_Error + (*init)( T1_Decoder decoder, + FT_Face face, + FT_Size size, + FT_GlyphSlot slot, + FT_Byte** glyph_names, + PS_Blend blend, + FT_Bool hinting, + FT_Render_Mode hint_mode, + T1_Decoder_Callback callback ); + + void + (*done)( T1_Decoder decoder ); + + FT_Error + (*parse_charstrings)( T1_Decoder decoder, + FT_Byte* base, + FT_UInt len ); + + } T1_Decoder_FuncsRec; + + + typedef struct T1_DecoderRec_ + { + T1_BuilderRec builder; + + FT_Long stack[T1_MAX_CHARSTRINGS_OPERANDS]; + FT_Long* top; + + T1_Decoder_ZoneRec zones[T1_MAX_SUBRS_CALLS + 1]; + T1_Decoder_Zone zone; + + FT_Service_PsCMaps psnames; /* for seac */ + FT_UInt num_glyphs; + FT_Byte** glyph_names; + + FT_Int lenIV; /* internal for sub routine calls */ + FT_UInt num_subrs; + FT_Byte** subrs; + FT_PtrDist* subrs_len; /* array of subrs length (optional) */ + + FT_Matrix font_matrix; + FT_Vector font_offset; + + FT_Int flex_state; + FT_Int num_flex_vectors; + FT_Vector flex_vectors[7]; + + PS_Blend blend; /* for multiple master support */ + + FT_Render_Mode hint_mode; + + T1_Decoder_Callback parse_callback; + T1_Decoder_FuncsRec funcs; + + FT_Long* buildchar; + FT_UInt len_buildchar; + + FT_Bool seac; + + } T1_DecoderRec; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** AFM PARSER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef struct AFM_ParserRec_* AFM_Parser; + + typedef struct AFM_Parser_FuncsRec_ + { + FT_Error + (*init)( AFM_Parser parser, + FT_Memory memory, + FT_Byte* base, + FT_Byte* limit ); + + void + (*done)( AFM_Parser parser ); + + FT_Error + (*parse)( AFM_Parser parser ); + + } AFM_Parser_FuncsRec; + + + typedef struct AFM_StreamRec_* AFM_Stream; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* AFM_ParserRec */ + /* */ + /* <Description> */ + /* An AFM_Parser is a parser for the AFM files. */ + /* */ + /* <Fields> */ + /* memory :: The object used for memory operations (alloc and */ + /* realloc). */ + /* */ + /* stream :: This is an opaque object. */ + /* */ + /* FontInfo :: The result will be stored here. */ + /* */ + /* get_index :: A user provided function to get a glyph index by its */ + /* name. */ + /* */ + typedef struct AFM_ParserRec_ + { + FT_Memory memory; + AFM_Stream stream; + + AFM_FontInfo FontInfo; + + FT_Int + (*get_index)( const char* name, + FT_Offset len, + void* user_data ); + + void* user_data; + + } AFM_ParserRec; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** TYPE1 CHARMAPS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef const struct T1_CMap_ClassesRec_* T1_CMap_Classes; + + typedef struct T1_CMap_ClassesRec_ + { + FT_CMap_Class standard; + FT_CMap_Class expert; + FT_CMap_Class custom; + FT_CMap_Class unicode; + + } T1_CMap_ClassesRec; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** PSAux Module Interface *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef struct PSAux_ServiceRec_ + { + /* don't use `PS_Table_Funcs' and friends to avoid compiler warnings */ + const PS_Table_FuncsRec* ps_table_funcs; + const PS_Parser_FuncsRec* ps_parser_funcs; + const T1_Builder_FuncsRec* t1_builder_funcs; + const T1_Decoder_FuncsRec* t1_decoder_funcs; + + void + (*t1_decrypt)( FT_Byte* buffer, + FT_Offset length, + FT_UShort seed ); + + T1_CMap_Classes t1_cmap_classes; + + /* fields after this comment line were added after version 2.1.10 */ + const AFM_Parser_FuncsRec* afm_parser_funcs; + + } PSAux_ServiceRec, *PSAux_Service; + + /* backwards-compatible type definition */ + typedef PSAux_ServiceRec PSAux_Interface; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** Some convenience functions *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + +#define IS_PS_NEWLINE( ch ) \ + ( (ch) == '\r' || \ + (ch) == '\n' ) + +#define IS_PS_SPACE( ch ) \ + ( (ch) == ' ' || \ + IS_PS_NEWLINE( ch ) || \ + (ch) == '\t' || \ + (ch) == '\f' || \ + (ch) == '\0' ) + +#define IS_PS_SPECIAL( ch ) \ + ( (ch) == '/' || \ + (ch) == '(' || (ch) == ')' || \ + (ch) == '<' || (ch) == '>' || \ + (ch) == '[' || (ch) == ']' || \ + (ch) == '{' || (ch) == '}' || \ + (ch) == '%' ) + +#define IS_PS_DELIM( ch ) \ + ( IS_PS_SPACE( ch ) || \ + IS_PS_SPECIAL( ch ) ) + +#define IS_PS_DIGIT( ch ) \ + ( (ch) >= '0' && (ch) <= '9' ) + +#define IS_PS_XDIGIT( ch ) \ + ( IS_PS_DIGIT( ch ) || \ + ( (ch) >= 'A' && (ch) <= 'F' ) || \ + ( (ch) >= 'a' && (ch) <= 'f' ) ) + +#define IS_PS_BASE85( ch ) \ + ( (ch) >= '!' && (ch) <= 'u' ) + +#define IS_PS_TOKEN( cur, limit, token ) \ + ( (char)(cur)[0] == (token)[0] && \ + ( (cur) + sizeof ( (token) ) == (limit) || \ + ( (cur) + sizeof( (token) ) < (limit) && \ + IS_PS_DELIM( (cur)[sizeof ( (token) ) - 1] ) ) ) && \ + ft_strncmp( (char*)(cur), (token), sizeof ( (token) ) - 1 ) == 0 ) + + +FT_END_HEADER + +#endif /* __PSAUX_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/internal/pshints.h b/mod/pub.mod/freetype.mod/include/freetype/internal/pshints.h new file mode 100644 index 0000000..0c35765 --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/internal/pshints.h @@ -0,0 +1,712 @@ +/***************************************************************************/ +/* */ +/* pshints.h */ +/* */ +/* Interface to Postscript-specific (Type 1 and Type 2) hints */ +/* recorders (specification only). These are used to support native */ +/* T1/T2 hints in the `type1', `cid', and `cff' font drivers. */ +/* */ +/* Copyright 2001, 2002, 2003, 2005, 2006, 2007, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __PSHINTS_H__ +#define __PSHINTS_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_TYPE1_TABLES_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** INTERNAL REPRESENTATION OF GLOBALS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef struct PSH_GlobalsRec_* PSH_Globals; + + typedef FT_Error + (*PSH_Globals_NewFunc)( FT_Memory memory, + T1_Private* private_dict, + PSH_Globals* aglobals ); + + typedef FT_Error + (*PSH_Globals_SetScaleFunc)( PSH_Globals globals, + FT_Fixed x_scale, + FT_Fixed y_scale, + FT_Fixed x_delta, + FT_Fixed y_delta ); + + typedef void + (*PSH_Globals_DestroyFunc)( PSH_Globals globals ); + + + typedef struct PSH_Globals_FuncsRec_ + { + PSH_Globals_NewFunc create; + PSH_Globals_SetScaleFunc set_scale; + PSH_Globals_DestroyFunc destroy; + + } PSH_Globals_FuncsRec, *PSH_Globals_Funcs; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** PUBLIC TYPE 1 HINTS RECORDER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /************************************************************************* + * + * @type: + * T1_Hints + * + * @description: + * This is a handle to an opaque structure used to record glyph hints + * from a Type 1 character glyph character string. + * + * The methods used to operate on this object are defined by the + * @T1_Hints_FuncsRec structure. Recording glyph hints is normally + * achieved through the following scheme: + * + * - Open a new hint recording session by calling the `open' method. + * This rewinds the recorder and prepare it for new input. + * + * - For each hint found in the glyph charstring, call the corresponding + * method (`stem', `stem3', or `reset'). Note that these functions do + * not return an error code. + * + * - Close the recording session by calling the `close' method. It + * returns an error code if the hints were invalid or something + * strange happened (e.g., memory shortage). + * + * The hints accumulated in the object can later be used by the + * PostScript hinter. + * + */ + typedef struct T1_HintsRec_* T1_Hints; + + + /************************************************************************* + * + * @type: + * T1_Hints_Funcs + * + * @description: + * A pointer to the @T1_Hints_FuncsRec structure that defines the API of + * a given @T1_Hints object. + * + */ + typedef const struct T1_Hints_FuncsRec_* T1_Hints_Funcs; + + + /************************************************************************* + * + * @functype: + * T1_Hints_OpenFunc + * + * @description: + * A method of the @T1_Hints class used to prepare it for a new Type 1 + * hints recording session. + * + * @input: + * hints :: + * A handle to the Type 1 hints recorder. + * + * @note: + * You should always call the @T1_Hints_CloseFunc method in order to + * close an opened recording session. + * + */ + typedef void + (*T1_Hints_OpenFunc)( T1_Hints hints ); + + + /************************************************************************* + * + * @functype: + * T1_Hints_SetStemFunc + * + * @description: + * A method of the @T1_Hints class used to record a new horizontal or + * vertical stem. This corresponds to the Type 1 `hstem' and `vstem' + * operators. + * + * @input: + * hints :: + * A handle to the Type 1 hints recorder. + * + * dimension :: + * 0 for horizontal stems (hstem), 1 for vertical ones (vstem). + * + * coords :: + * Array of 2 coordinates in 16.16 format, used as (position,length) + * stem descriptor. + * + * @note: + * Use vertical coordinates (y) for horizontal stems (dim=0). Use + * horizontal coordinates (x) for vertical stems (dim=1). + * + * `coords[0]' is the absolute stem position (lowest coordinate); + * `coords[1]' is the length. + * + * The length can be negative, in which case it must be either -20 or + * -21. It is interpreted as a `ghost' stem, according to the Type 1 + * specification. + * + * If the length is -21 (corresponding to a bottom ghost stem), then + * the real stem position is `coords[0]+coords[1]'. + * + */ + typedef void + (*T1_Hints_SetStemFunc)( T1_Hints hints, + FT_UInt dimension, + FT_Fixed* coords ); + + + /************************************************************************* + * + * @functype: + * T1_Hints_SetStem3Func + * + * @description: + * A method of the @T1_Hints class used to record three + * counter-controlled horizontal or vertical stems at once. + * + * @input: + * hints :: + * A handle to the Type 1 hints recorder. + * + * dimension :: + * 0 for horizontal stems, 1 for vertical ones. + * + * coords :: + * An array of 6 values in 16.16 format, holding 3 (position,length) + * pairs for the counter-controlled stems. + * + * @note: + * Use vertical coordinates (y) for horizontal stems (dim=0). Use + * horizontal coordinates (x) for vertical stems (dim=1). + * + * The lengths cannot be negative (ghost stems are never + * counter-controlled). + * + */ + typedef void + (*T1_Hints_SetStem3Func)( T1_Hints hints, + FT_UInt dimension, + FT_Fixed* coords ); + + + /************************************************************************* + * + * @functype: + * T1_Hints_ResetFunc + * + * @description: + * A method of the @T1_Hints class used to reset the stems hints in a + * recording session. + * + * @input: + * hints :: + * A handle to the Type 1 hints recorder. + * + * end_point :: + * The index of the last point in the input glyph in which the + * previously defined hints apply. + * + */ + typedef void + (*T1_Hints_ResetFunc)( T1_Hints hints, + FT_UInt end_point ); + + + /************************************************************************* + * + * @functype: + * T1_Hints_CloseFunc + * + * @description: + * A method of the @T1_Hints class used to close a hint recording + * session. + * + * @input: + * hints :: + * A handle to the Type 1 hints recorder. + * + * end_point :: + * The index of the last point in the input glyph. + * + * @return: + * FreeType error code. 0 means success. + * + * @note: + * The error code is set to indicate that an error occurred during the + * recording session. + * + */ + typedef FT_Error + (*T1_Hints_CloseFunc)( T1_Hints hints, + FT_UInt end_point ); + + + /************************************************************************* + * + * @functype: + * T1_Hints_ApplyFunc + * + * @description: + * A method of the @T1_Hints class used to apply hints to the + * corresponding glyph outline. Must be called once all hints have been + * recorded. + * + * @input: + * hints :: + * A handle to the Type 1 hints recorder. + * + * outline :: + * A pointer to the target outline descriptor. + * + * globals :: + * The hinter globals for this font. + * + * hint_mode :: + * Hinting information. + * + * @return: + * FreeType error code. 0 means success. + * + * @note: + * On input, all points within the outline are in font coordinates. On + * output, they are in 1/64th of pixels. + * + * The scaling transformation is taken from the `globals' object which + * must correspond to the same font as the glyph. + * + */ + typedef FT_Error + (*T1_Hints_ApplyFunc)( T1_Hints hints, + FT_Outline* outline, + PSH_Globals globals, + FT_Render_Mode hint_mode ); + + + /************************************************************************* + * + * @struct: + * T1_Hints_FuncsRec + * + * @description: + * The structure used to provide the API to @T1_Hints objects. + * + * @fields: + * hints :: + * A handle to the T1 Hints recorder. + * + * open :: + * The function to open a recording session. + * + * close :: + * The function to close a recording session. + * + * stem :: + * The function to set a simple stem. + * + * stem3 :: + * The function to set counter-controlled stems. + * + * reset :: + * The function to reset stem hints. + * + * apply :: + * The function to apply the hints to the corresponding glyph outline. + * + */ + typedef struct T1_Hints_FuncsRec_ + { + T1_Hints hints; + T1_Hints_OpenFunc open; + T1_Hints_CloseFunc close; + T1_Hints_SetStemFunc stem; + T1_Hints_SetStem3Func stem3; + T1_Hints_ResetFunc reset; + T1_Hints_ApplyFunc apply; + + } T1_Hints_FuncsRec; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** PUBLIC TYPE 2 HINTS RECORDER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /************************************************************************* + * + * @type: + * T2_Hints + * + * @description: + * This is a handle to an opaque structure used to record glyph hints + * from a Type 2 character glyph character string. + * + * The methods used to operate on this object are defined by the + * @T2_Hints_FuncsRec structure. Recording glyph hints is normally + * achieved through the following scheme: + * + * - Open a new hint recording session by calling the `open' method. + * This rewinds the recorder and prepare it for new input. + * + * - For each hint found in the glyph charstring, call the corresponding + * method (`stems', `hintmask', `counters'). Note that these + * functions do not return an error code. + * + * - Close the recording session by calling the `close' method. It + * returns an error code if the hints were invalid or something + * strange happened (e.g., memory shortage). + * + * The hints accumulated in the object can later be used by the + * Postscript hinter. + * + */ + typedef struct T2_HintsRec_* T2_Hints; + + + /************************************************************************* + * + * @type: + * T2_Hints_Funcs + * + * @description: + * A pointer to the @T2_Hints_FuncsRec structure that defines the API of + * a given @T2_Hints object. + * + */ + typedef const struct T2_Hints_FuncsRec_* T2_Hints_Funcs; + + + /************************************************************************* + * + * @functype: + * T2_Hints_OpenFunc + * + * @description: + * A method of the @T2_Hints class used to prepare it for a new Type 2 + * hints recording session. + * + * @input: + * hints :: + * A handle to the Type 2 hints recorder. + * + * @note: + * You should always call the @T2_Hints_CloseFunc method in order to + * close an opened recording session. + * + */ + typedef void + (*T2_Hints_OpenFunc)( T2_Hints hints ); + + + /************************************************************************* + * + * @functype: + * T2_Hints_StemsFunc + * + * @description: + * A method of the @T2_Hints class used to set the table of stems in + * either the vertical or horizontal dimension. Equivalent to the + * `hstem', `vstem', `hstemhm', and `vstemhm' Type 2 operators. + * + * @input: + * hints :: + * A handle to the Type 2 hints recorder. + * + * dimension :: + * 0 for horizontal stems (hstem), 1 for vertical ones (vstem). + * + * count :: + * The number of stems. + * + * coords :: + * An array of `count' (position,length) pairs in 16.16 format. + * + * @note: + * Use vertical coordinates (y) for horizontal stems (dim=0). Use + * horizontal coordinates (x) for vertical stems (dim=1). + * + * There are `2*count' elements in the `coords' array. Each even + * element is an absolute position in font units, each odd element is a + * length in font units. + * + * A length can be negative, in which case it must be either -20 or + * -21. It is interpreted as a `ghost' stem, according to the Type 1 + * specification. + * + */ + typedef void + (*T2_Hints_StemsFunc)( T2_Hints hints, + FT_UInt dimension, + FT_UInt count, + FT_Fixed* coordinates ); + + + /************************************************************************* + * + * @functype: + * T2_Hints_MaskFunc + * + * @description: + * A method of the @T2_Hints class used to set a given hintmask (this + * corresponds to the `hintmask' Type 2 operator). + * + * @input: + * hints :: + * A handle to the Type 2 hints recorder. + * + * end_point :: + * The glyph index of the last point to which the previously defined + * or activated hints apply. + * + * bit_count :: + * The number of bits in the hint mask. + * + * bytes :: + * An array of bytes modelling the hint mask. + * + * @note: + * If the hintmask starts the charstring (before any glyph point + * definition), the value of `end_point' should be 0. + * + * `bit_count' is the number of meaningful bits in the `bytes' array; it + * must be equal to the total number of hints defined so far (i.e., + * horizontal+verticals). + * + * The `bytes' array can come directly from the Type 2 charstring and + * respects the same format. + * + */ + typedef void + (*T2_Hints_MaskFunc)( T2_Hints hints, + FT_UInt end_point, + FT_UInt bit_count, + const FT_Byte* bytes ); + + + /************************************************************************* + * + * @functype: + * T2_Hints_CounterFunc + * + * @description: + * A method of the @T2_Hints class used to set a given counter mask + * (this corresponds to the `hintmask' Type 2 operator). + * + * @input: + * hints :: + * A handle to the Type 2 hints recorder. + * + * end_point :: + * A glyph index of the last point to which the previously defined or + * active hints apply. + * + * bit_count :: + * The number of bits in the hint mask. + * + * bytes :: + * An array of bytes modelling the hint mask. + * + * @note: + * If the hintmask starts the charstring (before any glyph point + * definition), the value of `end_point' should be 0. + * + * `bit_count' is the number of meaningful bits in the `bytes' array; it + * must be equal to the total number of hints defined so far (i.e., + * horizontal+verticals). + * + * The `bytes' array can come directly from the Type 2 charstring and + * respects the same format. + * + */ + typedef void + (*T2_Hints_CounterFunc)( T2_Hints hints, + FT_UInt bit_count, + const FT_Byte* bytes ); + + + /************************************************************************* + * + * @functype: + * T2_Hints_CloseFunc + * + * @description: + * A method of the @T2_Hints class used to close a hint recording + * session. + * + * @input: + * hints :: + * A handle to the Type 2 hints recorder. + * + * end_point :: + * The index of the last point in the input glyph. + * + * @return: + * FreeType error code. 0 means success. + * + * @note: + * The error code is set to indicate that an error occurred during the + * recording session. + * + */ + typedef FT_Error + (*T2_Hints_CloseFunc)( T2_Hints hints, + FT_UInt end_point ); + + + /************************************************************************* + * + * @functype: + * T2_Hints_ApplyFunc + * + * @description: + * A method of the @T2_Hints class used to apply hints to the + * corresponding glyph outline. Must be called after the `close' + * method. + * + * @input: + * hints :: + * A handle to the Type 2 hints recorder. + * + * outline :: + * A pointer to the target outline descriptor. + * + * globals :: + * The hinter globals for this font. + * + * hint_mode :: + * Hinting information. + * + * @return: + * FreeType error code. 0 means success. + * + * @note: + * On input, all points within the outline are in font coordinates. On + * output, they are in 1/64th of pixels. + * + * The scaling transformation is taken from the `globals' object which + * must correspond to the same font than the glyph. + * + */ + typedef FT_Error + (*T2_Hints_ApplyFunc)( T2_Hints hints, + FT_Outline* outline, + PSH_Globals globals, + FT_Render_Mode hint_mode ); + + + /************************************************************************* + * + * @struct: + * T2_Hints_FuncsRec + * + * @description: + * The structure used to provide the API to @T2_Hints objects. + * + * @fields: + * hints :: + * A handle to the T2 hints recorder object. + * + * open :: + * The function to open a recording session. + * + * close :: + * The function to close a recording session. + * + * stems :: + * The function to set the dimension's stems table. + * + * hintmask :: + * The function to set hint masks. + * + * counter :: + * The function to set counter masks. + * + * apply :: + * The function to apply the hints on the corresponding glyph outline. + * + */ + typedef struct T2_Hints_FuncsRec_ + { + T2_Hints hints; + T2_Hints_OpenFunc open; + T2_Hints_CloseFunc close; + T2_Hints_StemsFunc stems; + T2_Hints_MaskFunc hintmask; + T2_Hints_CounterFunc counter; + T2_Hints_ApplyFunc apply; + + } T2_Hints_FuncsRec; + + + /* */ + + + typedef struct PSHinter_Interface_ + { + PSH_Globals_Funcs (*get_globals_funcs)( FT_Module module ); + T1_Hints_Funcs (*get_t1_funcs) ( FT_Module module ); + T2_Hints_Funcs (*get_t2_funcs) ( FT_Module module ); + + } PSHinter_Interface; + + typedef PSHinter_Interface* PSHinter_Service; + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_PSHINTER_INTERFACE(class_, get_globals_funcs_, \ + get_t1_funcs_, get_t2_funcs_) \ + static const PSHinter_Interface class_ = \ + { \ + get_globals_funcs_, get_t1_funcs_, get_t2_funcs_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_PSHINTER_INTERFACE(class_, get_globals_funcs_, \ + get_t1_funcs_, get_t2_funcs_) \ + void \ + FT_Init_Class_##class_( FT_Library library, \ + PSHinter_Interface* clazz) \ + { \ + FT_UNUSED(library); \ + clazz->get_globals_funcs = get_globals_funcs_; \ + clazz->get_t1_funcs = get_t1_funcs_; \ + clazz->get_t2_funcs = get_t2_funcs_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + +FT_END_HEADER + +#endif /* __PSHINTS_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/internal/services/svbdf.h b/mod/pub.mod/freetype.mod/include/freetype/internal/services/svbdf.h new file mode 100644 index 0000000..9264239 --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/internal/services/svbdf.h @@ -0,0 +1,77 @@ +/***************************************************************************/ +/* */ +/* svbdf.h */ +/* */ +/* The FreeType BDF services (specification). */ +/* */ +/* Copyright 2003 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __SVBDF_H__ +#define __SVBDF_H__ + +#include FT_BDF_H +#include FT_INTERNAL_SERVICE_H + + +FT_BEGIN_HEADER + + +#define FT_SERVICE_ID_BDF "bdf" + + typedef FT_Error + (*FT_BDF_GetCharsetIdFunc)( FT_Face face, + const char* *acharset_encoding, + const char* *acharset_registry ); + + typedef FT_Error + (*FT_BDF_GetPropertyFunc)( FT_Face face, + const char* prop_name, + BDF_PropertyRec *aproperty ); + + + FT_DEFINE_SERVICE( BDF ) + { + FT_BDF_GetCharsetIdFunc get_charset_id; + FT_BDF_GetPropertyFunc get_property; + }; + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_BDFRec(class_, get_charset_id_, get_property_) \ + static const FT_Service_BDFRec class_ = \ + { \ + get_charset_id_, get_property_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_BDFRec(class_, get_charset_id_, get_property_) \ + void \ + FT_Init_Class_##class_( FT_Service_BDFRec* clazz ) \ + { \ + clazz->get_charset_id = get_charset_id_; \ + clazz->get_property = get_property_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + + +FT_END_HEADER + + +#endif /* __SVBDF_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/internal/services/svcid.h b/mod/pub.mod/freetype.mod/include/freetype/internal/services/svcid.h new file mode 100644 index 0000000..9b874b5 --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/internal/services/svcid.h @@ -0,0 +1,83 @@ +/***************************************************************************/ +/* */ +/* svcid.h */ +/* */ +/* The FreeType CID font services (specification). */ +/* */ +/* Copyright 2007, 2009 by Derek Clegg, Michael Toftdal. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __SVCID_H__ +#define __SVCID_H__ + +#include FT_INTERNAL_SERVICE_H + + +FT_BEGIN_HEADER + + +#define FT_SERVICE_ID_CID "CID" + + typedef FT_Error + (*FT_CID_GetRegistryOrderingSupplementFunc)( FT_Face face, + const char* *registry, + const char* *ordering, + FT_Int *supplement ); + typedef FT_Error + (*FT_CID_GetIsInternallyCIDKeyedFunc)( FT_Face face, + FT_Bool *is_cid ); + typedef FT_Error + (*FT_CID_GetCIDFromGlyphIndexFunc)( FT_Face face, + FT_UInt glyph_index, + FT_UInt *cid ); + + FT_DEFINE_SERVICE( CID ) + { + FT_CID_GetRegistryOrderingSupplementFunc get_ros; + FT_CID_GetIsInternallyCIDKeyedFunc get_is_cid; + FT_CID_GetCIDFromGlyphIndexFunc get_cid_from_glyph_index; + }; + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_CIDREC(class_, get_ros_, \ + get_is_cid_, get_cid_from_glyph_index_ ) \ + static const FT_Service_CIDRec class_ = \ + { \ + get_ros_, get_is_cid_, get_cid_from_glyph_index_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_CIDREC(class_, get_ros_, \ + get_is_cid_, get_cid_from_glyph_index_ ) \ + void \ + FT_Init_Class_##class_( FT_Library library, \ + FT_Service_CIDRec* clazz) \ + { \ + FT_UNUSED(library); \ + clazz->get_ros = get_ros_; \ + clazz->get_is_cid = get_is_cid_; \ + clazz->get_cid_from_glyph_index = get_cid_from_glyph_index_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + + +FT_END_HEADER + + +#endif /* __SVCID_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/internal/services/svgldict.h b/mod/pub.mod/freetype.mod/include/freetype/internal/services/svgldict.h new file mode 100644 index 0000000..d66a41d --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/internal/services/svgldict.h @@ -0,0 +1,82 @@ +/***************************************************************************/ +/* */ +/* svgldict.h */ +/* */ +/* The FreeType glyph dictionary services (specification). */ +/* */ +/* Copyright 2003 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __SVGLDICT_H__ +#define __SVGLDICT_H__ + +#include FT_INTERNAL_SERVICE_H + + +FT_BEGIN_HEADER + + + /* + * A service used to retrieve glyph names, as well as to find the + * index of a given glyph name in a font. + * + */ + +#define FT_SERVICE_ID_GLYPH_DICT "glyph-dict" + + + typedef FT_Error + (*FT_GlyphDict_GetNameFunc)( FT_Face face, + FT_UInt glyph_index, + FT_Pointer buffer, + FT_UInt buffer_max ); + + typedef FT_UInt + (*FT_GlyphDict_NameIndexFunc)( FT_Face face, + FT_String* glyph_name ); + + + FT_DEFINE_SERVICE( GlyphDict ) + { + FT_GlyphDict_GetNameFunc get_name; + FT_GlyphDict_NameIndexFunc name_index; /* optional */ + }; + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_GLYPHDICTREC(class_, get_name_, name_index_) \ + static const FT_Service_GlyphDictRec class_ = \ + { \ + get_name_, name_index_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_GLYPHDICTREC(class_, get_name_, name_index_) \ + void \ + FT_Init_Class_##class_( FT_Library library, \ + FT_Service_GlyphDictRec* clazz) \ + { \ + FT_UNUSED(library); \ + clazz->get_name = get_name_; \ + clazz->name_index = name_index_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + + +FT_END_HEADER + + +#endif /* __SVGLDICT_H__ */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/internal/services/svgxval.h b/mod/pub.mod/freetype.mod/include/freetype/internal/services/svgxval.h new file mode 100644 index 0000000..2cdab50 --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/internal/services/svgxval.h @@ -0,0 +1,72 @@ +/***************************************************************************/ +/* */ +/* svgxval.h */ +/* */ +/* FreeType API for validating TrueTypeGX/AAT tables (specification). */ +/* */ +/* Copyright 2004, 2005 by */ +/* Masatake YAMATO, Red Hat K.K., */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + +/***************************************************************************/ +/* */ +/* gxvalid is derived from both gxlayout module and otvalid module. */ +/* Development of gxlayout is supported by the Information-technology */ +/* Promotion Agency(IPA), Japan. */ +/* */ +/***************************************************************************/ + + +#ifndef __SVGXVAL_H__ +#define __SVGXVAL_H__ + +#include FT_GX_VALIDATE_H +#include FT_INTERNAL_VALIDATE_H + +FT_BEGIN_HEADER + + +#define FT_SERVICE_ID_GX_VALIDATE "truetypegx-validate" +#define FT_SERVICE_ID_CLASSICKERN_VALIDATE "classickern-validate" + + typedef FT_Error + (*gxv_validate_func)( FT_Face face, + FT_UInt gx_flags, + FT_Bytes tables[FT_VALIDATE_GX_LENGTH], + FT_UInt table_length ); + + + typedef FT_Error + (*ckern_validate_func)( FT_Face face, + FT_UInt ckern_flags, + FT_Bytes *ckern_table ); + + + FT_DEFINE_SERVICE( GXvalidate ) + { + gxv_validate_func validate; + }; + + FT_DEFINE_SERVICE( CKERNvalidate ) + { + ckern_validate_func validate; + }; + + /* */ + + +FT_END_HEADER + + +#endif /* __SVGXVAL_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/internal/services/svkern.h b/mod/pub.mod/freetype.mod/include/freetype/internal/services/svkern.h new file mode 100644 index 0000000..1488adf --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/internal/services/svkern.h @@ -0,0 +1,51 @@ +/***************************************************************************/ +/* */ +/* svkern.h */ +/* */ +/* The FreeType Kerning service (specification). */ +/* */ +/* Copyright 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __SVKERN_H__ +#define __SVKERN_H__ + +#include FT_INTERNAL_SERVICE_H +#include FT_TRUETYPE_TABLES_H + + +FT_BEGIN_HEADER + +#define FT_SERVICE_ID_KERNING "kerning" + + + typedef FT_Error + (*FT_Kerning_TrackGetFunc)( FT_Face face, + FT_Fixed point_size, + FT_Int degree, + FT_Fixed* akerning ); + + FT_DEFINE_SERVICE( Kerning ) + { + FT_Kerning_TrackGetFunc get_track; + }; + + /* */ + + +FT_END_HEADER + + +#endif /* __SVKERN_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/internal/services/svmm.h b/mod/pub.mod/freetype.mod/include/freetype/internal/services/svmm.h new file mode 100644 index 0000000..66e1da2 --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/internal/services/svmm.h @@ -0,0 +1,104 @@ +/***************************************************************************/ +/* */ +/* svmm.h */ +/* */ +/* The FreeType Multiple Masters and GX var services (specification). */ +/* */ +/* Copyright 2003, 2004 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __SVMM_H__ +#define __SVMM_H__ + +#include FT_INTERNAL_SERVICE_H + + +FT_BEGIN_HEADER + + + /* + * A service used to manage multiple-masters data in a given face. + * + * See the related APIs in `ftmm.h' (FT_MULTIPLE_MASTERS_H). + * + */ + +#define FT_SERVICE_ID_MULTI_MASTERS "multi-masters" + + + typedef FT_Error + (*FT_Get_MM_Func)( FT_Face face, + FT_Multi_Master* master ); + + typedef FT_Error + (*FT_Get_MM_Var_Func)( FT_Face face, + FT_MM_Var* *master ); + + typedef FT_Error + (*FT_Set_MM_Design_Func)( FT_Face face, + FT_UInt num_coords, + FT_Long* coords ); + + typedef FT_Error + (*FT_Set_Var_Design_Func)( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); + + typedef FT_Error + (*FT_Set_MM_Blend_Func)( FT_Face face, + FT_UInt num_coords, + FT_Long* coords ); + + + FT_DEFINE_SERVICE( MultiMasters ) + { + FT_Get_MM_Func get_mm; + FT_Set_MM_Design_Func set_mm_design; + FT_Set_MM_Blend_Func set_mm_blend; + FT_Get_MM_Var_Func get_mm_var; + FT_Set_Var_Design_Func set_var_design; + }; + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_MULTIMASTERSREC(class_, get_mm_, set_mm_design_, \ + set_mm_blend_, get_mm_var_, set_var_design_) \ + static const FT_Service_MultiMastersRec class_ = \ + { \ + get_mm_, set_mm_design_, set_mm_blend_, get_mm_var_, set_var_design_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_MULTIMASTERSREC(class_, get_mm_, set_mm_design_, \ + set_mm_blend_, get_mm_var_, set_var_design_) \ + void \ + FT_Init_Class_##class_( FT_Service_MultiMastersRec* clazz ) \ + { \ + clazz->get_mm = get_mm_; \ + clazz->set_mm_design = set_mm_design_; \ + clazz->set_mm_blend = set_mm_blend_; \ + clazz->get_mm_var = get_mm_var_; \ + clazz->set_var_design = set_var_design_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + + +FT_END_HEADER + +#endif /* __SVMM_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/internal/services/svotval.h b/mod/pub.mod/freetype.mod/include/freetype/internal/services/svotval.h new file mode 100644 index 0000000..970bbd5 --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/internal/services/svotval.h @@ -0,0 +1,55 @@ +/***************************************************************************/ +/* */ +/* svotval.h */ +/* */ +/* The FreeType OpenType validation service (specification). */ +/* */ +/* Copyright 2004, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __SVOTVAL_H__ +#define __SVOTVAL_H__ + +#include FT_OPENTYPE_VALIDATE_H +#include FT_INTERNAL_VALIDATE_H + +FT_BEGIN_HEADER + + +#define FT_SERVICE_ID_OPENTYPE_VALIDATE "opentype-validate" + + + typedef FT_Error + (*otv_validate_func)( FT_Face volatile face, + FT_UInt ot_flags, + FT_Bytes *base, + FT_Bytes *gdef, + FT_Bytes *gpos, + FT_Bytes *gsub, + FT_Bytes *jstf ); + + + FT_DEFINE_SERVICE( OTvalidate ) + { + otv_validate_func validate; + }; + + /* */ + + +FT_END_HEADER + + +#endif /* __SVOTVAL_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/internal/services/svpfr.h b/mod/pub.mod/freetype.mod/include/freetype/internal/services/svpfr.h new file mode 100644 index 0000000..462786f --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/internal/services/svpfr.h @@ -0,0 +1,66 @@ +/***************************************************************************/ +/* */ +/* svpfr.h */ +/* */ +/* Internal PFR service functions (specification). */ +/* */ +/* Copyright 2003, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __SVPFR_H__ +#define __SVPFR_H__ + +#include FT_PFR_H +#include FT_INTERNAL_SERVICE_H + + +FT_BEGIN_HEADER + + +#define FT_SERVICE_ID_PFR_METRICS "pfr-metrics" + + + typedef FT_Error + (*FT_PFR_GetMetricsFunc)( FT_Face face, + FT_UInt *aoutline, + FT_UInt *ametrics, + FT_Fixed *ax_scale, + FT_Fixed *ay_scale ); + + typedef FT_Error + (*FT_PFR_GetKerningFunc)( FT_Face face, + FT_UInt left, + FT_UInt right, + FT_Vector *avector ); + + typedef FT_Error + (*FT_PFR_GetAdvanceFunc)( FT_Face face, + FT_UInt gindex, + FT_Pos *aadvance ); + + + FT_DEFINE_SERVICE( PfrMetrics ) + { + FT_PFR_GetMetricsFunc get_metrics; + FT_PFR_GetKerningFunc get_kerning; + FT_PFR_GetAdvanceFunc get_advance; + + }; + + /* */ + +FT_END_HEADER + +#endif /* __SVPFR_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/internal/services/svpostnm.h b/mod/pub.mod/freetype.mod/include/freetype/internal/services/svpostnm.h new file mode 100644 index 0000000..106c54f --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/internal/services/svpostnm.h @@ -0,0 +1,79 @@ +/***************************************************************************/ +/* */ +/* svpostnm.h */ +/* */ +/* The FreeType PostScript name services (specification). */ +/* */ +/* Copyright 2003, 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __SVPOSTNM_H__ +#define __SVPOSTNM_H__ + +#include FT_INTERNAL_SERVICE_H + + +FT_BEGIN_HEADER + + /* + * A trivial service used to retrieve the PostScript name of a given + * font when available. The `get_name' field should never be NULL. + * + * The corresponding function can return NULL to indicate that the + * PostScript name is not available. + * + * The name is owned by the face and will be destroyed with it. + */ + +#define FT_SERVICE_ID_POSTSCRIPT_FONT_NAME "postscript-font-name" + + + typedef const char* + (*FT_PsName_GetFunc)( FT_Face face ); + + + FT_DEFINE_SERVICE( PsFontName ) + { + FT_PsName_GetFunc get_ps_font_name; + }; + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_PSFONTNAMEREC(class_, get_ps_font_name_) \ + static const FT_Service_PsFontNameRec class_ = \ + { \ + get_ps_font_name_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_PSFONTNAMEREC(class_, get_ps_font_name_) \ + void \ + FT_Init_Class_##class_( FT_Library library, \ + FT_Service_PsFontNameRec* clazz) \ + { \ + FT_UNUSED(library); \ + clazz->get_ps_font_name = get_ps_font_name_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + + +FT_END_HEADER + + +#endif /* __SVPOSTNM_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/internal/services/svpscmap.h b/mod/pub.mod/freetype.mod/include/freetype/internal/services/svpscmap.h new file mode 100644 index 0000000..961030c --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/internal/services/svpscmap.h @@ -0,0 +1,164 @@ +/***************************************************************************/ +/* */ +/* svpscmap.h */ +/* */ +/* The FreeType PostScript charmap service (specification). */ +/* */ +/* Copyright 2003, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __SVPSCMAP_H__ +#define __SVPSCMAP_H__ + +#include FT_INTERNAL_OBJECTS_H + + +FT_BEGIN_HEADER + + +#define FT_SERVICE_ID_POSTSCRIPT_CMAPS "postscript-cmaps" + + + /* + * Adobe glyph name to unicode value. + */ + typedef FT_UInt32 + (*PS_Unicode_ValueFunc)( const char* glyph_name ); + + /* + * Macintosh name id to glyph name. NULL if invalid index. + */ + typedef const char* + (*PS_Macintosh_NameFunc)( FT_UInt name_index ); + + /* + * Adobe standard string ID to glyph name. NULL if invalid index. + */ + typedef const char* + (*PS_Adobe_Std_StringsFunc)( FT_UInt string_index ); + + + /* + * Simple unicode -> glyph index charmap built from font glyph names + * table. + */ + typedef struct PS_UniMap_ + { + FT_UInt32 unicode; /* bit 31 set: is glyph variant */ + FT_UInt glyph_index; + + } PS_UniMap; + + + typedef struct PS_UnicodesRec_* PS_Unicodes; + + typedef struct PS_UnicodesRec_ + { + FT_CMapRec cmap; + FT_UInt num_maps; + PS_UniMap* maps; + + } PS_UnicodesRec; + + + /* + * A function which returns a glyph name for a given index. Returns + * NULL if invalid index. + */ + typedef const char* + (*PS_GetGlyphNameFunc)( FT_Pointer data, + FT_UInt string_index ); + + /* + * A function used to release the glyph name returned by + * PS_GetGlyphNameFunc, when needed + */ + typedef void + (*PS_FreeGlyphNameFunc)( FT_Pointer data, + const char* name ); + + typedef FT_Error + (*PS_Unicodes_InitFunc)( FT_Memory memory, + PS_Unicodes unicodes, + FT_UInt num_glyphs, + PS_GetGlyphNameFunc get_glyph_name, + PS_FreeGlyphNameFunc free_glyph_name, + FT_Pointer glyph_data ); + + typedef FT_UInt + (*PS_Unicodes_CharIndexFunc)( PS_Unicodes unicodes, + FT_UInt32 unicode ); + + typedef FT_UInt32 + (*PS_Unicodes_CharNextFunc)( PS_Unicodes unicodes, + FT_UInt32 *unicode ); + + + FT_DEFINE_SERVICE( PsCMaps ) + { + PS_Unicode_ValueFunc unicode_value; + + PS_Unicodes_InitFunc unicodes_init; + PS_Unicodes_CharIndexFunc unicodes_char_index; + PS_Unicodes_CharNextFunc unicodes_char_next; + + PS_Macintosh_NameFunc macintosh_name; + PS_Adobe_Std_StringsFunc adobe_std_strings; + const unsigned short* adobe_std_encoding; + const unsigned short* adobe_expert_encoding; + }; + + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_PSCMAPSREC(class_, unicode_value_, unicodes_init_, \ + unicodes_char_index_, unicodes_char_next_, macintosh_name_, \ + adobe_std_strings_, adobe_std_encoding_, adobe_expert_encoding_) \ + static const FT_Service_PsCMapsRec class_ = \ + { \ + unicode_value_, unicodes_init_, \ + unicodes_char_index_, unicodes_char_next_, macintosh_name_, \ + adobe_std_strings_, adobe_std_encoding_, adobe_expert_encoding_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_PSCMAPSREC(class_, unicode_value_, unicodes_init_, \ + unicodes_char_index_, unicodes_char_next_, macintosh_name_, \ + adobe_std_strings_, adobe_std_encoding_, adobe_expert_encoding_) \ + void \ + FT_Init_Class_##class_( FT_Library library, \ + FT_Service_PsCMapsRec* clazz) \ + { \ + FT_UNUSED(library); \ + clazz->unicode_value = unicode_value_; \ + clazz->unicodes_init = unicodes_init_; \ + clazz->unicodes_char_index = unicodes_char_index_; \ + clazz->unicodes_char_next = unicodes_char_next_; \ + clazz->macintosh_name = macintosh_name_; \ + clazz->adobe_std_strings = adobe_std_strings_; \ + clazz->adobe_std_encoding = adobe_std_encoding_; \ + clazz->adobe_expert_encoding = adobe_expert_encoding_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + + +FT_END_HEADER + + +#endif /* __SVPSCMAP_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/internal/services/svpsinfo.h b/mod/pub.mod/freetype.mod/include/freetype/internal/services/svpsinfo.h new file mode 100644 index 0000000..91ba91e --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/internal/services/svpsinfo.h @@ -0,0 +1,92 @@ +/***************************************************************************/ +/* */ +/* svpsinfo.h */ +/* */ +/* The FreeType PostScript info service (specification). */ +/* */ +/* Copyright 2003, 2004, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __SVPSINFO_H__ +#define __SVPSINFO_H__ + +#include FT_INTERNAL_SERVICE_H +#include FT_INTERNAL_TYPE1_TYPES_H + + +FT_BEGIN_HEADER + + +#define FT_SERVICE_ID_POSTSCRIPT_INFO "postscript-info" + + + typedef FT_Error + (*PS_GetFontInfoFunc)( FT_Face face, + PS_FontInfoRec* afont_info ); + + typedef FT_Error + (*PS_GetFontExtraFunc)( FT_Face face, + PS_FontExtraRec* afont_extra ); + + typedef FT_Int + (*PS_HasGlyphNamesFunc)( FT_Face face ); + + typedef FT_Error + (*PS_GetFontPrivateFunc)( FT_Face face, + PS_PrivateRec* afont_private ); + + + FT_DEFINE_SERVICE( PsInfo ) + { + PS_GetFontInfoFunc ps_get_font_info; + PS_GetFontExtraFunc ps_get_font_extra; + PS_HasGlyphNamesFunc ps_has_glyph_names; + PS_GetFontPrivateFunc ps_get_font_private; + }; + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_PSINFOREC(class_, get_font_info_, \ + ps_get_font_extra_, has_glyph_names_, get_font_private_) \ + static const FT_Service_PsInfoRec class_ = \ + { \ + get_font_info_, ps_get_font_extra_, has_glyph_names_, \ + get_font_private_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_PSINFOREC(class_, get_font_info_, \ + ps_get_font_extra_, has_glyph_names_, get_font_private_) \ + void \ + FT_Init_Class_##class_( FT_Library library, \ + FT_Service_PsInfoRec* clazz) \ + { \ + FT_UNUSED(library); \ + clazz->ps_get_font_info = get_font_info_; \ + clazz->ps_get_font_extra = ps_get_font_extra_; \ + clazz->ps_has_glyph_names = has_glyph_names_; \ + clazz->ps_get_font_private = get_font_private_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + + +FT_END_HEADER + + +#endif /* __SVPSINFO_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/internal/services/svsfnt.h b/mod/pub.mod/freetype.mod/include/freetype/internal/services/svsfnt.h new file mode 100644 index 0000000..30bb162 --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/internal/services/svsfnt.h @@ -0,0 +1,102 @@ +/***************************************************************************/ +/* */ +/* svsfnt.h */ +/* */ +/* The FreeType SFNT table loading service (specification). */ +/* */ +/* Copyright 2003, 2004 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __SVSFNT_H__ +#define __SVSFNT_H__ + +#include FT_INTERNAL_SERVICE_H +#include FT_TRUETYPE_TABLES_H + + +FT_BEGIN_HEADER + + + /* + * SFNT table loading service. + */ + +#define FT_SERVICE_ID_SFNT_TABLE "sfnt-table" + + + /* + * Used to implement FT_Load_Sfnt_Table(). + */ + typedef FT_Error + (*FT_SFNT_TableLoadFunc)( FT_Face face, + FT_ULong tag, + FT_Long offset, + FT_Byte* buffer, + FT_ULong* length ); + + /* + * Used to implement FT_Get_Sfnt_Table(). + */ + typedef void* + (*FT_SFNT_TableGetFunc)( FT_Face face, + FT_Sfnt_Tag tag ); + + + /* + * Used to implement FT_Sfnt_Table_Info(). + */ + typedef FT_Error + (*FT_SFNT_TableInfoFunc)( FT_Face face, + FT_UInt idx, + FT_ULong *tag, + FT_ULong *offset, + FT_ULong *length ); + + + FT_DEFINE_SERVICE( SFNT_Table ) + { + FT_SFNT_TableLoadFunc load_table; + FT_SFNT_TableGetFunc get_table; + FT_SFNT_TableInfoFunc table_info; + }; + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_SFNT_TABLEREC(class_, load_, get_, info_) \ + static const FT_Service_SFNT_TableRec class_ = \ + { \ + load_, get_, info_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_SFNT_TABLEREC(class_, load_, get_, info_) \ + void \ + FT_Init_Class_##class_( FT_Service_SFNT_TableRec* clazz ) \ + { \ + clazz->load_table = load_; \ + clazz->get_table = get_; \ + clazz->table_info = info_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + + +FT_END_HEADER + + +#endif /* __SVSFNT_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/internal/services/svttcmap.h b/mod/pub.mod/freetype.mod/include/freetype/internal/services/svttcmap.h new file mode 100644 index 0000000..8af0035 --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/internal/services/svttcmap.h @@ -0,0 +1,106 @@ +/***************************************************************************/ +/* */ +/* svttcmap.h */ +/* */ +/* The FreeType TrueType/sfnt cmap extra information service. */ +/* */ +/* Copyright 2003 by */ +/* Masatake YAMATO, Redhat K.K. */ +/* */ +/* Copyright 2003, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + +/* Development of this service is support of + Information-technology Promotion Agency, Japan. */ + +#ifndef __SVTTCMAP_H__ +#define __SVTTCMAP_H__ + +#include FT_INTERNAL_SERVICE_H +#include FT_TRUETYPE_TABLES_H + + +FT_BEGIN_HEADER + + +#define FT_SERVICE_ID_TT_CMAP "tt-cmaps" + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_CMapInfo */ + /* */ + /* <Description> */ + /* A structure used to store TrueType/sfnt specific cmap information */ + /* which is not covered by the generic @FT_CharMap structure. This */ + /* structure can be accessed with the @FT_Get_TT_CMap_Info function. */ + /* */ + /* <Fields> */ + /* language :: */ + /* The language ID used in Mac fonts. Definitions of values are in */ + /* freetype/ttnameid.h. */ + /* */ + /* format :: */ + /* The cmap format. OpenType 1.5 defines the formats 0 (byte */ + /* encoding table), 2~(high-byte mapping through table), 4~(segment */ + /* mapping to delta values), 6~(trimmed table mapping), 8~(mixed */ + /* 16-bit and 32-bit coverage), 10~(trimmed array), 12~(segmented */ + /* coverage), and 14 (Unicode Variation Sequences). */ + /* */ + typedef struct TT_CMapInfo_ + { + FT_ULong language; + FT_Long format; + + } TT_CMapInfo; + + + typedef FT_Error + (*TT_CMap_Info_GetFunc)( FT_CharMap charmap, + TT_CMapInfo *cmap_info ); + + + FT_DEFINE_SERVICE( TTCMaps ) + { + TT_CMap_Info_GetFunc get_cmap_info; + }; + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_TTCMAPSREC(class_, get_cmap_info_) \ + static const FT_Service_TTCMapsRec class_ = \ + { \ + get_cmap_info_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_TTCMAPSREC(class_, get_cmap_info_) \ + void \ + FT_Init_Class_##class_( FT_Library library, \ + FT_Service_TTCMapsRec* clazz) \ + { \ + FT_UNUSED(library); \ + clazz->get_cmap_info = get_cmap_info_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + + +FT_END_HEADER + +#endif /* __SVTTCMAP_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/internal/services/svtteng.h b/mod/pub.mod/freetype.mod/include/freetype/internal/services/svtteng.h new file mode 100644 index 0000000..58e02a6 --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/internal/services/svtteng.h @@ -0,0 +1,53 @@ +/***************************************************************************/ +/* */ +/* svtteng.h */ +/* */ +/* The FreeType TrueType engine query service (specification). */ +/* */ +/* Copyright 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __SVTTENG_H__ +#define __SVTTENG_H__ + +#include FT_INTERNAL_SERVICE_H +#include FT_MODULE_H + + +FT_BEGIN_HEADER + + + /* + * SFNT table loading service. + */ + +#define FT_SERVICE_ID_TRUETYPE_ENGINE "truetype-engine" + + /* + * Used to implement FT_Get_TrueType_Engine_Type + */ + + FT_DEFINE_SERVICE( TrueTypeEngine ) + { + FT_TrueTypeEngineType engine_type; + }; + + /* */ + + +FT_END_HEADER + + +#endif /* __SVTTENG_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/internal/services/svttglyf.h b/mod/pub.mod/freetype.mod/include/freetype/internal/services/svttglyf.h new file mode 100644 index 0000000..ab2dc9a --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/internal/services/svttglyf.h @@ -0,0 +1,67 @@ +/***************************************************************************/ +/* */ +/* svttglyf.h */ +/* */ +/* The FreeType TrueType glyph service. */ +/* */ +/* Copyright 2007 by David Turner. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + +#ifndef __SVTTGLYF_H__ +#define __SVTTGLYF_H__ + +#include FT_INTERNAL_SERVICE_H +#include FT_TRUETYPE_TABLES_H + + +FT_BEGIN_HEADER + + +#define FT_SERVICE_ID_TT_GLYF "tt-glyf" + + + typedef FT_ULong + (*TT_Glyf_GetLocationFunc)( FT_Face face, + FT_UInt gindex, + FT_ULong *psize ); + + FT_DEFINE_SERVICE( TTGlyf ) + { + TT_Glyf_GetLocationFunc get_location; + }; + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_TTGLYFREC(class_, get_location_ ) \ + static const FT_Service_TTGlyfRec class_ = \ + { \ + get_location_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_TTGLYFREC(class_, get_location_ ) \ + void \ + FT_Init_Class_##class_( FT_Service_TTGlyfRec* clazz ) \ + { \ + clazz->get_location = get_location_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + + +FT_END_HEADER + +#endif /* __SVTTGLYF_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/internal/services/svwinfnt.h b/mod/pub.mod/freetype.mod/include/freetype/internal/services/svwinfnt.h new file mode 100644 index 0000000..57f7765 --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/internal/services/svwinfnt.h @@ -0,0 +1,50 @@ +/***************************************************************************/ +/* */ +/* svwinfnt.h */ +/* */ +/* The FreeType Windows FNT/FONT service (specification). */ +/* */ +/* Copyright 2003 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __SVWINFNT_H__ +#define __SVWINFNT_H__ + +#include FT_INTERNAL_SERVICE_H +#include FT_WINFONTS_H + + +FT_BEGIN_HEADER + + +#define FT_SERVICE_ID_WINFNT "winfonts" + + typedef FT_Error + (*FT_WinFnt_GetHeaderFunc)( FT_Face face, + FT_WinFNT_HeaderRec *aheader ); + + + FT_DEFINE_SERVICE( WinFnt ) + { + FT_WinFnt_GetHeaderFunc get_header; + }; + + /* */ + + +FT_END_HEADER + + +#endif /* __SVWINFNT_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/internal/services/svxf86nm.h b/mod/pub.mod/freetype.mod/include/freetype/internal/services/svxf86nm.h new file mode 100644 index 0000000..ca5d884 --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/internal/services/svxf86nm.h @@ -0,0 +1,55 @@ +/***************************************************************************/ +/* */ +/* svxf86nm.h */ +/* */ +/* The FreeType XFree86 services (specification only). */ +/* */ +/* Copyright 2003 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __SVXF86NM_H__ +#define __SVXF86NM_H__ + +#include FT_INTERNAL_SERVICE_H + + +FT_BEGIN_HEADER + + + /* + * A trivial service used to return the name of a face's font driver, + * according to the XFree86 nomenclature. Note that the service data + * is a simple constant string pointer. + */ + +#define FT_SERVICE_ID_XF86_NAME "xf86-driver-name" + +#define FT_XF86_FORMAT_TRUETYPE "TrueType" +#define FT_XF86_FORMAT_TYPE_1 "Type 1" +#define FT_XF86_FORMAT_BDF "BDF" +#define FT_XF86_FORMAT_PCF "PCF" +#define FT_XF86_FORMAT_TYPE_42 "Type 42" +#define FT_XF86_FORMAT_CID "CID Type 1" +#define FT_XF86_FORMAT_CFF "CFF" +#define FT_XF86_FORMAT_PFR "PFR" +#define FT_XF86_FORMAT_WINFNT "Windows FNT" + + /* */ + + +FT_END_HEADER + + +#endif /* __SVXF86NM_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/internal/sfnt.h b/mod/pub.mod/freetype.mod/include/freetype/internal/sfnt.h new file mode 100644 index 0000000..6326deb --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/internal/sfnt.h @@ -0,0 +1,897 @@ +/***************************************************************************/ +/* */ +/* sfnt.h */ +/* */ +/* High-level `sfnt' driver interface (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __SFNT_H__ +#define __SFNT_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_DRIVER_H +#include FT_INTERNAL_TRUETYPE_TYPES_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Init_Face_Func */ + /* */ + /* <Description> */ + /* First part of the SFNT face object initialization. This finds */ + /* the face in a SFNT file or collection, and load its format tag in */ + /* face->format_tag. */ + /* */ + /* <Input> */ + /* stream :: The input stream. */ + /* */ + /* face :: A handle to the target face object. */ + /* */ + /* face_index :: The index of the TrueType font, if we are opening a */ + /* collection. */ + /* */ + /* num_params :: The number of additional parameters. */ + /* */ + /* params :: Optional additional parameters. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* The stream cursor must be at the font file's origin. */ + /* */ + /* This function recognizes fonts embedded in a `TrueType */ + /* collection'. */ + /* */ + /* Once the format tag has been validated by the font driver, it */ + /* should then call the TT_Load_Face_Func() callback to read the rest */ + /* of the SFNT tables in the object. */ + /* */ + typedef FT_Error + (*TT_Init_Face_Func)( FT_Stream stream, + TT_Face face, + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Load_Face_Func */ + /* */ + /* <Description> */ + /* Second part of the SFNT face object initialization. This loads */ + /* the common SFNT tables (head, OS/2, maxp, metrics, etc.) in the */ + /* face object. */ + /* */ + /* <Input> */ + /* stream :: The input stream. */ + /* */ + /* face :: A handle to the target face object. */ + /* */ + /* face_index :: The index of the TrueType font, if we are opening a */ + /* collection. */ + /* */ + /* num_params :: The number of additional parameters. */ + /* */ + /* params :: Optional additional parameters. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* This function must be called after TT_Init_Face_Func(). */ + /* */ + typedef FT_Error + (*TT_Load_Face_Func)( FT_Stream stream, + TT_Face face, + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Done_Face_Func */ + /* */ + /* <Description> */ + /* A callback used to delete the common SFNT data from a face. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* <Note> */ + /* This function does NOT destroy the face object. */ + /* */ + typedef void + (*TT_Done_Face_Func)( TT_Face face ); + + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Load_SFNT_HeaderRec_Func */ + /* */ + /* <Description> */ + /* Loads the header of a SFNT font file. Supports collections. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: The input stream. */ + /* */ + /* face_index :: The index of the TrueType font, if we are opening a */ + /* collection. */ + /* */ + /* <Output> */ + /* sfnt :: The SFNT header. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* The stream cursor must be at the font file's origin. */ + /* */ + /* This function recognizes fonts embedded in a `TrueType */ + /* collection'. */ + /* */ + /* This function checks that the header is valid by looking at the */ + /* values of `search_range', `entry_selector', and `range_shift'. */ + /* */ + typedef FT_Error + (*TT_Load_SFNT_HeaderRec_Func)( TT_Face face, + FT_Stream stream, + FT_Long face_index, + SFNT_Header sfnt ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Load_Directory_Func */ + /* */ + /* <Description> */ + /* Loads the table directory into a face object. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: The input stream. */ + /* */ + /* sfnt :: The SFNT header. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* The stream cursor must be on the first byte after the 4-byte font */ + /* format tag. This is the case just after a call to */ + /* TT_Load_Format_Tag(). */ + /* */ + typedef FT_Error + (*TT_Load_Directory_Func)( TT_Face face, + FT_Stream stream, + SFNT_Header sfnt ); + +#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */ + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Load_Any_Func */ + /* */ + /* <Description> */ + /* Load any font table into client memory. */ + /* */ + /* <Input> */ + /* face :: The face object to look for. */ + /* */ + /* tag :: The tag of table to load. Use the value 0 if you want */ + /* to access the whole font file, else set this parameter */ + /* to a valid TrueType table tag that you can forge with */ + /* the MAKE_TT_TAG macro. */ + /* */ + /* offset :: The starting offset in the table (or the file if */ + /* tag == 0). */ + /* */ + /* length :: The address of the decision variable: */ + /* */ + /* If length == NULL: */ + /* Loads the whole table. Returns an error if */ + /* `offset' == 0! */ + /* */ + /* If *length == 0: */ + /* Exits immediately; returning the length of the given */ + /* table or of the font file, depending on the value of */ + /* `tag'. */ + /* */ + /* If *length != 0: */ + /* Loads the next `length' bytes of table or font, */ + /* starting at offset `offset' (in table or font too). */ + /* */ + /* <Output> */ + /* buffer :: The address of target buffer. */ + /* */ + /* <Return> */ + /* TrueType error code. 0 means success. */ + /* */ + typedef FT_Error + (*TT_Load_Any_Func)( TT_Face face, + FT_ULong tag, + FT_Long offset, + FT_Byte *buffer, + FT_ULong* length ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Find_SBit_Image_Func */ + /* */ + /* <Description> */ + /* Check whether an embedded bitmap (an `sbit') exists for a given */ + /* glyph, at a given strike. */ + /* */ + /* <Input> */ + /* face :: The target face object. */ + /* */ + /* glyph_index :: The glyph index. */ + /* */ + /* strike_index :: The current strike index. */ + /* */ + /* <Output> */ + /* arange :: The SBit range containing the glyph index. */ + /* */ + /* astrike :: The SBit strike containing the glyph index. */ + /* */ + /* aglyph_offset :: The offset of the glyph data in `EBDT' table. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. Returns */ + /* SFNT_Err_Invalid_Argument if no sbit exists for the requested */ + /* glyph. */ + /* */ + typedef FT_Error + (*TT_Find_SBit_Image_Func)( TT_Face face, + FT_UInt glyph_index, + FT_ULong strike_index, + TT_SBit_Range *arange, + TT_SBit_Strike *astrike, + FT_ULong *aglyph_offset ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Load_SBit_Metrics_Func */ + /* */ + /* <Description> */ + /* Get the big metrics for a given embedded bitmap. */ + /* */ + /* <Input> */ + /* stream :: The input stream. */ + /* */ + /* range :: The SBit range containing the glyph. */ + /* */ + /* <Output> */ + /* big_metrics :: A big SBit metrics structure for the glyph. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* The stream cursor must be positioned at the glyph's offset within */ + /* the `EBDT' table before the call. */ + /* */ + /* If the image format uses variable metrics, the stream cursor is */ + /* positioned just after the metrics header in the `EBDT' table on */ + /* function exit. */ + /* */ + typedef FT_Error + (*TT_Load_SBit_Metrics_Func)( FT_Stream stream, + TT_SBit_Range range, + TT_SBit_Metrics metrics ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Load_SBit_Image_Func */ + /* */ + /* <Description> */ + /* Load a given glyph sbit image from the font resource. This also */ + /* returns its metrics. */ + /* */ + /* <Input> */ + /* face :: */ + /* The target face object. */ + /* */ + /* strike_index :: */ + /* The strike index. */ + /* */ + /* glyph_index :: */ + /* The current glyph index. */ + /* */ + /* load_flags :: */ + /* The current load flags. */ + /* */ + /* stream :: */ + /* The input stream. */ + /* */ + /* <Output> */ + /* amap :: */ + /* The target pixmap. */ + /* */ + /* ametrics :: */ + /* A big sbit metrics structure for the glyph image. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. Returns an error if no */ + /* glyph sbit exists for the index. */ + /* */ + /* <Note> */ + /* The `map.buffer' field is always freed before the glyph is loaded. */ + /* */ + typedef FT_Error + (*TT_Load_SBit_Image_Func)( TT_Face face, + FT_ULong strike_index, + FT_UInt glyph_index, + FT_UInt load_flags, + FT_Stream stream, + FT_Bitmap *amap, + TT_SBit_MetricsRec *ametrics ); + + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Set_SBit_Strike_OldFunc */ + /* */ + /* <Description> */ + /* Select an sbit strike for a given size request. */ + /* */ + /* <Input> */ + /* face :: The target face object. */ + /* */ + /* req :: The size request. */ + /* */ + /* <Output> */ + /* astrike_index :: The index of the sbit strike. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. Returns an error if no */ + /* sbit strike exists for the selected ppem values. */ + /* */ + typedef FT_Error + (*TT_Set_SBit_Strike_OldFunc)( TT_Face face, + FT_UInt x_ppem, + FT_UInt y_ppem, + FT_ULong* astrike_index ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_CharMap_Load_Func */ + /* */ + /* <Description> */ + /* Loads a given TrueType character map into memory. */ + /* */ + /* <Input> */ + /* face :: A handle to the parent face object. */ + /* */ + /* stream :: A handle to the current stream object. */ + /* */ + /* <InOut> */ + /* cmap :: A pointer to a cmap object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* The function assumes that the stream is already in use (i.e., */ + /* opened). In case of error, all partially allocated tables are */ + /* released. */ + /* */ + typedef FT_Error + (*TT_CharMap_Load_Func)( TT_Face face, + void* cmap, + FT_Stream input ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_CharMap_Free_Func */ + /* */ + /* <Description> */ + /* Destroys a character mapping table. */ + /* */ + /* <Input> */ + /* face :: A handle to the parent face object. */ + /* */ + /* cmap :: A handle to a cmap object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + typedef FT_Error + (*TT_CharMap_Free_Func)( TT_Face face, + void* cmap ); + +#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */ + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Set_SBit_Strike_Func */ + /* */ + /* <Description> */ + /* Select an sbit strike for a given size request. */ + /* */ + /* <Input> */ + /* face :: The target face object. */ + /* */ + /* req :: The size request. */ + /* */ + /* <Output> */ + /* astrike_index :: The index of the sbit strike. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. Returns an error if no */ + /* sbit strike exists for the selected ppem values. */ + /* */ + typedef FT_Error + (*TT_Set_SBit_Strike_Func)( TT_Face face, + FT_Size_Request req, + FT_ULong* astrike_index ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Load_Strike_Metrics_Func */ + /* */ + /* <Description> */ + /* Load the metrics of a given strike. */ + /* */ + /* <Input> */ + /* face :: The target face object. */ + /* */ + /* strike_index :: The strike index. */ + /* */ + /* <Output> */ + /* metrics :: the metrics of the strike. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. Returns an error if no */ + /* such sbit strike exists. */ + /* */ + typedef FT_Error + (*TT_Load_Strike_Metrics_Func)( TT_Face face, + FT_ULong strike_index, + FT_Size_Metrics* metrics ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Get_PS_Name_Func */ + /* */ + /* <Description> */ + /* Get the PostScript glyph name of a glyph. */ + /* */ + /* <Input> */ + /* idx :: The glyph index. */ + /* */ + /* PSname :: The address of a string pointer. Will be NULL in case */ + /* of error, otherwise it is a pointer to the glyph name. */ + /* */ + /* You must not modify the returned string! */ + /* */ + /* <Output> */ + /* FreeType error code. 0 means success. */ + /* */ + typedef FT_Error + (*TT_Get_PS_Name_Func)( TT_Face face, + FT_UInt idx, + FT_String** PSname ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Load_Metrics_Func */ + /* */ + /* <Description> */ + /* Load a metrics table, which is a table with a horizontal and a */ + /* vertical version. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: The input stream. */ + /* */ + /* vertical :: A boolean flag. If set, load the vertical one. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + typedef FT_Error + (*TT_Load_Metrics_Func)( TT_Face face, + FT_Stream stream, + FT_Bool vertical ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Get_Metrics_Func */ + /* */ + /* <Description> */ + /* Load the horizontal or vertical header in a face object. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: The input stream. */ + /* */ + /* vertical :: A boolean flag. If set, load vertical metrics. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + typedef FT_Error + (*TT_Get_Metrics_Func)( TT_Face face, + FT_Bool vertical, + FT_UInt gindex, + FT_Short* abearing, + FT_UShort* aadvance ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Load_Table_Func */ + /* */ + /* <Description> */ + /* Load a given TrueType table. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: The input stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* The function uses `face->goto_table' to seek the stream to the */ + /* start of the table, except while loading the font directory. */ + /* */ + typedef FT_Error + (*TT_Load_Table_Func)( TT_Face face, + FT_Stream stream ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Free_Table_Func */ + /* */ + /* <Description> */ + /* Free a given TrueType table. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + typedef void + (*TT_Free_Table_Func)( TT_Face face ); + + + /* + * @functype: + * TT_Face_GetKerningFunc + * + * @description: + * Return the horizontal kerning value between two glyphs. + * + * @input: + * face :: A handle to the source face object. + * left_glyph :: The left glyph index. + * right_glyph :: The right glyph index. + * + * @return: + * The kerning value in font units. + */ + typedef FT_Int + (*TT_Face_GetKerningFunc)( TT_Face face, + FT_UInt left_glyph, + FT_UInt right_glyph ); + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* SFNT_Interface */ + /* */ + /* <Description> */ + /* This structure holds pointers to the functions used to load and */ + /* free the basic tables that are required in a `sfnt' font file. */ + /* */ + /* <Fields> */ + /* Check the various xxx_Func() descriptions for details. */ + /* */ + typedef struct SFNT_Interface_ + { + TT_Loader_GotoTableFunc goto_table; + + TT_Init_Face_Func init_face; + TT_Load_Face_Func load_face; + TT_Done_Face_Func done_face; + FT_Module_Requester get_interface; + + TT_Load_Any_Func load_any; + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + TT_Load_SFNT_HeaderRec_Func load_sfnt_header; + TT_Load_Directory_Func load_directory; +#endif + + /* these functions are called by `load_face' but they can also */ + /* be called from external modules, if there is a need to do so */ + TT_Load_Table_Func load_head; + TT_Load_Metrics_Func load_hhea; + TT_Load_Table_Func load_cmap; + TT_Load_Table_Func load_maxp; + TT_Load_Table_Func load_os2; + TT_Load_Table_Func load_post; + + TT_Load_Table_Func load_name; + TT_Free_Table_Func free_name; + + /* optional tables */ +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + TT_Load_Table_Func load_hdmx_stub; + TT_Free_Table_Func free_hdmx_stub; +#endif + + /* this field was called `load_kerning' up to version 2.1.10 */ + TT_Load_Table_Func load_kern; + + TT_Load_Table_Func load_gasp; + TT_Load_Table_Func load_pclt; + + /* see `ttload.h'; this field was called `load_bitmap_header' up to */ + /* version 2.1.10 */ + TT_Load_Table_Func load_bhed; + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + + /* see `ttsbit.h' */ + TT_Set_SBit_Strike_OldFunc set_sbit_strike_stub; + TT_Load_Table_Func load_sbits_stub; + + /* + * The following two fields appeared in version 2.1.8, and were placed + * between `load_sbits' and `load_sbit_image'. We support them as a + * special exception since they are used by Xfont library within the + * X.Org xserver, and because the probability that other rogue clients + * use the other version 2.1.7 fields below is _extremely_ low. + * + * Note that this forces us to disable an interesting memory-saving + * optimization though... + */ + + TT_Find_SBit_Image_Func find_sbit_image; + TT_Load_SBit_Metrics_Func load_sbit_metrics; + +#endif + + TT_Load_SBit_Image_Func load_sbit_image; + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + TT_Free_Table_Func free_sbits_stub; +#endif + + /* see `ttpost.h' */ + TT_Get_PS_Name_Func get_psname; + TT_Free_Table_Func free_psnames; + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + TT_CharMap_Load_Func load_charmap_stub; + TT_CharMap_Free_Func free_charmap_stub; +#endif + + /* starting here, the structure differs from version 2.1.7 */ + + /* this field was introduced in version 2.1.8, named `get_psname' */ + TT_Face_GetKerningFunc get_kerning; + + /* new elements introduced after version 2.1.10 */ + + /* load the font directory, i.e., the offset table and */ + /* the table directory */ + TT_Load_Table_Func load_font_dir; + TT_Load_Metrics_Func load_hmtx; + + TT_Load_Table_Func load_eblc; + TT_Free_Table_Func free_eblc; + + TT_Set_SBit_Strike_Func set_sbit_strike; + TT_Load_Strike_Metrics_Func load_strike_metrics; + + TT_Get_Metrics_Func get_metrics; + + } SFNT_Interface; + + + /* transitional */ + typedef SFNT_Interface* SFNT_Service; + +#ifndef FT_CONFIG_OPTION_PIC + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS +#define FT_DEFINE_DRIVERS_OLD_INTERNAL(a) \ + a, +#else + #define FT_DEFINE_DRIVERS_OLD_INTERNAL(a) +#endif +#define FT_INTERNAL(a) \ + a, + +#define FT_DEFINE_SFNT_INTERFACE(class_, \ + goto_table_, init_face_, load_face_, done_face_, get_interface_, \ + load_any_, load_sfnt_header_, load_directory_, load_head_, \ + load_hhea_, load_cmap_, load_maxp_, load_os2_, load_post_, \ + load_name_, free_name_, load_hdmx_stub_, free_hdmx_stub_, \ + load_kern_, load_gasp_, load_pclt_, load_bhed_, \ + set_sbit_strike_stub_, load_sbits_stub_, find_sbit_image_, \ + load_sbit_metrics_, load_sbit_image_, free_sbits_stub_, \ + get_psname_, free_psnames_, load_charmap_stub_, free_charmap_stub_, \ + get_kerning_, load_font_dir_, load_hmtx_, load_eblc_, free_eblc_, \ + set_sbit_strike_, load_strike_metrics_, get_metrics_ ) \ + static const SFNT_Interface class_ = \ + { \ + FT_INTERNAL(goto_table_) \ + FT_INTERNAL(init_face_) \ + FT_INTERNAL(load_face_) \ + FT_INTERNAL(done_face_) \ + FT_INTERNAL(get_interface_) \ + FT_INTERNAL(load_any_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(load_sfnt_header_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(load_directory_) \ + FT_INTERNAL(load_head_) \ + FT_INTERNAL(load_hhea_) \ + FT_INTERNAL(load_cmap_) \ + FT_INTERNAL(load_maxp_) \ + FT_INTERNAL(load_os2_) \ + FT_INTERNAL(load_post_) \ + FT_INTERNAL(load_name_) \ + FT_INTERNAL(free_name_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(load_hdmx_stub_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(free_hdmx_stub_) \ + FT_INTERNAL(load_kern_) \ + FT_INTERNAL(load_gasp_) \ + FT_INTERNAL(load_pclt_) \ + FT_INTERNAL(load_bhed_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(set_sbit_strike_stub_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(load_sbits_stub_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(find_sbit_image_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(load_sbit_metrics_) \ + FT_INTERNAL(load_sbit_image_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(free_sbits_stub_) \ + FT_INTERNAL(get_psname_) \ + FT_INTERNAL(free_psnames_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(load_charmap_stub_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(free_charmap_stub_) \ + FT_INTERNAL(get_kerning_) \ + FT_INTERNAL(load_font_dir_) \ + FT_INTERNAL(load_hmtx_) \ + FT_INTERNAL(load_eblc_) \ + FT_INTERNAL(free_eblc_) \ + FT_INTERNAL(set_sbit_strike_) \ + FT_INTERNAL(load_strike_metrics_) \ + FT_INTERNAL(get_metrics_) \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS +#define FT_DEFINE_DRIVERS_OLD_INTERNAL(a, a_) \ + clazz->a = a_; +#else + #define FT_DEFINE_DRIVERS_OLD_INTERNAL(a, a_) +#endif +#define FT_INTERNAL(a, a_) \ + clazz->a = a_; + +#define FT_DEFINE_SFNT_INTERFACE(class_, \ + goto_table_, init_face_, load_face_, done_face_, get_interface_, \ + load_any_, load_sfnt_header_, load_directory_, load_head_, \ + load_hhea_, load_cmap_, load_maxp_, load_os2_, load_post_, \ + load_name_, free_name_, load_hdmx_stub_, free_hdmx_stub_, \ + load_kern_, load_gasp_, load_pclt_, load_bhed_, \ + set_sbit_strike_stub_, load_sbits_stub_, find_sbit_image_, \ + load_sbit_metrics_, load_sbit_image_, free_sbits_stub_, \ + get_psname_, free_psnames_, load_charmap_stub_, free_charmap_stub_, \ + get_kerning_, load_font_dir_, load_hmtx_, load_eblc_, free_eblc_, \ + set_sbit_strike_, load_strike_metrics_, get_metrics_ ) \ + void \ + FT_Init_Class_##class_( FT_Library library, SFNT_Interface* clazz ) \ + { \ + FT_UNUSED(library); \ + FT_INTERNAL(goto_table,goto_table_) \ + FT_INTERNAL(init_face,init_face_) \ + FT_INTERNAL(load_face,load_face_) \ + FT_INTERNAL(done_face,done_face_) \ + FT_INTERNAL(get_interface,get_interface_) \ + FT_INTERNAL(load_any,load_any_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(load_sfnt_header,load_sfnt_header_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(load_directory,load_directory_) \ + FT_INTERNAL(load_head,load_head_) \ + FT_INTERNAL(load_hhea,load_hhea_) \ + FT_INTERNAL(load_cmap,load_cmap_) \ + FT_INTERNAL(load_maxp,load_maxp_) \ + FT_INTERNAL(load_os2,load_os2_) \ + FT_INTERNAL(load_post,load_post_) \ + FT_INTERNAL(load_name,load_name_) \ + FT_INTERNAL(free_name,free_name_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(load_hdmx_stub,load_hdmx_stub_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(free_hdmx_stub,free_hdmx_stub_) \ + FT_INTERNAL(load_kern,load_kern_) \ + FT_INTERNAL(load_gasp,load_gasp_) \ + FT_INTERNAL(load_pclt,load_pclt_) \ + FT_INTERNAL(load_bhed,load_bhed_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(set_sbit_strike_stub,set_sbit_strike_stub_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(load_sbits_stub,load_sbits_stub_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(find_sbit_image,find_sbit_image_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(load_sbit_metrics,load_sbit_metrics_) \ + FT_INTERNAL(load_sbit_image,load_sbit_image_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(free_sbits_stub,free_sbits_stub_) \ + FT_INTERNAL(get_psname,get_psname_) \ + FT_INTERNAL(free_psnames,free_psnames_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(load_charmap_stub,load_charmap_stub_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(free_charmap_stub,free_charmap_stub_) \ + FT_INTERNAL(get_kerning,get_kerning_) \ + FT_INTERNAL(load_font_dir,load_font_dir_) \ + FT_INTERNAL(load_hmtx,load_hmtx_) \ + FT_INTERNAL(load_eblc,load_eblc_) \ + FT_INTERNAL(free_eblc,free_eblc_) \ + FT_INTERNAL(set_sbit_strike,set_sbit_strike_) \ + FT_INTERNAL(load_strike_metrics,load_strike_metrics_) \ + FT_INTERNAL(get_metrics,get_metrics_) \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + +FT_END_HEADER + +#endif /* __SFNT_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/internal/t1types.h b/mod/pub.mod/freetype.mod/include/freetype/internal/t1types.h new file mode 100644 index 0000000..5f73063 --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/internal/t1types.h @@ -0,0 +1,270 @@ +/***************************************************************************/ +/* */ +/* t1types.h */ +/* */ +/* Basic Type1/Type2 type definitions and interface (specification */ +/* only). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __T1TYPES_H__ +#define __T1TYPES_H__ + + +#include <ft2build.h> +#include FT_TYPE1_TABLES_H +#include FT_INTERNAL_POSTSCRIPT_HINTS_H +#include FT_INTERNAL_SERVICE_H +#include FT_SERVICE_POSTSCRIPT_CMAPS_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*** ***/ + /*** ***/ + /*** REQUIRED TYPE1/TYPE2 TABLES DEFINITIONS ***/ + /*** ***/ + /*** ***/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* T1_EncodingRec */ + /* */ + /* <Description> */ + /* A structure modeling a custom encoding. */ + /* */ + /* <Fields> */ + /* num_chars :: The number of character codes in the encoding. */ + /* Usually 256. */ + /* */ + /* code_first :: The lowest valid character code in the encoding. */ + /* */ + /* code_last :: The highest valid character code in the encoding */ + /* + 1. When equal to code_first there are no valid */ + /* character codes. */ + /* */ + /* char_index :: An array of corresponding glyph indices. */ + /* */ + /* char_name :: An array of corresponding glyph names. */ + /* */ + typedef struct T1_EncodingRecRec_ + { + FT_Int num_chars; + FT_Int code_first; + FT_Int code_last; + + FT_UShort* char_index; + FT_String** char_name; + + } T1_EncodingRec, *T1_Encoding; + + + typedef enum T1_EncodingType_ + { + T1_ENCODING_TYPE_NONE = 0, + T1_ENCODING_TYPE_ARRAY, + T1_ENCODING_TYPE_STANDARD, + T1_ENCODING_TYPE_ISOLATIN1, + T1_ENCODING_TYPE_EXPERT + + } T1_EncodingType; + + + /* used to hold extra data of PS_FontInfoRec that + * cannot be stored in the publicly defined structure. + * + * Note these can't be blended with multiple-masters. + */ + typedef struct PS_FontExtraRec_ + { + FT_UShort fs_type; + + } PS_FontExtraRec; + + + typedef struct T1_FontRec_ + { + PS_FontInfoRec font_info; /* font info dictionary */ + PS_FontExtraRec font_extra; /* font info extra fields */ + PS_PrivateRec private_dict; /* private dictionary */ + FT_String* font_name; /* top-level dictionary */ + + T1_EncodingType encoding_type; + T1_EncodingRec encoding; + + FT_Byte* subrs_block; + FT_Byte* charstrings_block; + FT_Byte* glyph_names_block; + + FT_Int num_subrs; + FT_Byte** subrs; + FT_PtrDist* subrs_len; + + FT_Int num_glyphs; + FT_String** glyph_names; /* array of glyph names */ + FT_Byte** charstrings; /* array of glyph charstrings */ + FT_PtrDist* charstrings_len; + + FT_Byte paint_type; + FT_Byte font_type; + FT_Matrix font_matrix; + FT_Vector font_offset; + FT_BBox font_bbox; + FT_Long font_id; + + FT_Fixed stroke_width; + + } T1_FontRec, *T1_Font; + + + typedef struct CID_SubrsRec_ + { + FT_UInt num_subrs; + FT_Byte** code; + + } CID_SubrsRec, *CID_Subrs; + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*** ***/ + /*** ***/ + /*** AFM FONT INFORMATION STRUCTURES ***/ + /*** ***/ + /*** ***/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + typedef struct AFM_TrackKernRec_ + { + FT_Int degree; + FT_Fixed min_ptsize; + FT_Fixed min_kern; + FT_Fixed max_ptsize; + FT_Fixed max_kern; + + } AFM_TrackKernRec, *AFM_TrackKern; + + typedef struct AFM_KernPairRec_ + { + FT_Int index1; + FT_Int index2; + FT_Int x; + FT_Int y; + + } AFM_KernPairRec, *AFM_KernPair; + + typedef struct AFM_FontInfoRec_ + { + FT_Bool IsCIDFont; + FT_BBox FontBBox; + FT_Fixed Ascender; + FT_Fixed Descender; + AFM_TrackKern TrackKerns; /* free if non-NULL */ + FT_Int NumTrackKern; + AFM_KernPair KernPairs; /* free if non-NULL */ + FT_Int NumKernPair; + + } AFM_FontInfoRec, *AFM_FontInfo; + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*** ***/ + /*** ***/ + /*** ORIGINAL T1_FACE CLASS DEFINITION ***/ + /*** ***/ + /*** ***/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + typedef struct T1_FaceRec_* T1_Face; + typedef struct CID_FaceRec_* CID_Face; + + + typedef struct T1_FaceRec_ + { + FT_FaceRec root; + T1_FontRec type1; + const void* psnames; + const void* psaux; + const void* afm_data; + FT_CharMapRec charmaprecs[2]; + FT_CharMap charmaps[2]; + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + PS_Unicodes unicode_map; +#endif + + /* support for Multiple Masters fonts */ + PS_Blend blend; + + /* undocumented, optional: indices of subroutines that express */ + /* the NormalizeDesignVector and the ConvertDesignVector procedure, */ + /* respectively, as Type 2 charstrings; -1 if keywords not present */ + FT_Int ndv_idx; + FT_Int cdv_idx; + + /* undocumented, optional: has the same meaning as len_buildchar */ + /* for Type 2 fonts; manipulated by othersubrs 19, 24, and 25 */ + FT_UInt len_buildchar; + FT_Long* buildchar; + + /* since version 2.1 - interface to PostScript hinter */ + const void* pshinter; + + } T1_FaceRec; + + + typedef struct CID_FaceRec_ + { + FT_FaceRec root; + void* psnames; + void* psaux; + CID_FaceInfoRec cid; + PS_FontExtraRec font_extra; +#if 0 + void* afm_data; +#endif + CID_Subrs subrs; + + /* since version 2.1 - interface to PostScript hinter */ + void* pshinter; + + /* since version 2.1.8, but was originally positioned after `afm_data' */ + FT_Byte* binary_data; /* used if hex data has been converted */ + FT_Stream cid_stream; + + } CID_FaceRec; + + +FT_END_HEADER + +#endif /* __T1TYPES_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/internal/tttypes.h b/mod/pub.mod/freetype.mod/include/freetype/internal/tttypes.h new file mode 100644 index 0000000..acbb863 --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/internal/tttypes.h @@ -0,0 +1,1543 @@ +/***************************************************************************/ +/* */ +/* tttypes.h */ +/* */ +/* Basic SFNT/TrueType type definitions and interface (specification */ +/* only). */ +/* */ +/* Copyright 1996-2001, 2002, 2004, 2005, 2006, 2007, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __TTTYPES_H__ +#define __TTTYPES_H__ + + +#include <ft2build.h> +#include FT_TRUETYPE_TABLES_H +#include FT_INTERNAL_OBJECTS_H + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT +#include FT_MULTIPLE_MASTERS_H +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*** ***/ + /*** ***/ + /*** REQUIRED TRUETYPE/OPENTYPE TABLES DEFINITIONS ***/ + /*** ***/ + /*** ***/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TTC_HeaderRec */ + /* */ + /* <Description> */ + /* TrueType collection header. This table contains the offsets of */ + /* the font headers of each distinct TrueType face in the file. */ + /* */ + /* <Fields> */ + /* tag :: Must be `ttc ' to indicate a TrueType collection. */ + /* */ + /* version :: The version number. */ + /* */ + /* count :: The number of faces in the collection. The */ + /* specification says this should be an unsigned long, but */ + /* we use a signed long since we need the value -1 for */ + /* specific purposes. */ + /* */ + /* offsets :: The offsets of the font headers, one per face. */ + /* */ + typedef struct TTC_HeaderRec_ + { + FT_ULong tag; + FT_Fixed version; + FT_Long count; + FT_ULong* offsets; + + } TTC_HeaderRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* SFNT_HeaderRec */ + /* */ + /* <Description> */ + /* SFNT file format header. */ + /* */ + /* <Fields> */ + /* format_tag :: The font format tag. */ + /* */ + /* num_tables :: The number of tables in file. */ + /* */ + /* search_range :: Must be `16 * (max power of 2 <= num_tables)'. */ + /* */ + /* entry_selector :: Must be log2 of `search_range / 16'. */ + /* */ + /* range_shift :: Must be `num_tables * 16 - search_range'. */ + /* */ + typedef struct SFNT_HeaderRec_ + { + FT_ULong format_tag; + FT_UShort num_tables; + FT_UShort search_range; + FT_UShort entry_selector; + FT_UShort range_shift; + + FT_ULong offset; /* not in file */ + + } SFNT_HeaderRec, *SFNT_Header; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_TableRec */ + /* */ + /* <Description> */ + /* This structure describes a given table of a TrueType font. */ + /* */ + /* <Fields> */ + /* Tag :: A four-bytes tag describing the table. */ + /* */ + /* CheckSum :: The table checksum. This value can be ignored. */ + /* */ + /* Offset :: The offset of the table from the start of the TrueType */ + /* font in its resource. */ + /* */ + /* Length :: The table length (in bytes). */ + /* */ + typedef struct TT_TableRec_ + { + FT_ULong Tag; /* table type */ + FT_ULong CheckSum; /* table checksum */ + FT_ULong Offset; /* table file offset */ + FT_ULong Length; /* table length */ + + } TT_TableRec, *TT_Table; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_LongMetricsRec */ + /* */ + /* <Description> */ + /* A structure modeling the long metrics of the `hmtx' and `vmtx' */ + /* TrueType tables. The values are expressed in font units. */ + /* */ + /* <Fields> */ + /* advance :: The advance width or height for the glyph. */ + /* */ + /* bearing :: The left-side or top-side bearing for the glyph. */ + /* */ + typedef struct TT_LongMetricsRec_ + { + FT_UShort advance; + FT_Short bearing; + + } TT_LongMetricsRec, *TT_LongMetrics; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* TT_ShortMetrics */ + /* */ + /* <Description> */ + /* A simple type to model the short metrics of the `hmtx' and `vmtx' */ + /* tables. */ + /* */ + typedef FT_Short TT_ShortMetrics; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_NameEntryRec */ + /* */ + /* <Description> */ + /* A structure modeling TrueType name records. Name records are used */ + /* to store important strings like family name, style name, */ + /* copyright, etc. in _localized_ versions (i.e., language, encoding, */ + /* etc). */ + /* */ + /* <Fields> */ + /* platformID :: The ID of the name's encoding platform. */ + /* */ + /* encodingID :: The platform-specific ID for the name's encoding. */ + /* */ + /* languageID :: The platform-specific ID for the name's language. */ + /* */ + /* nameID :: The ID specifying what kind of name this is. */ + /* */ + /* stringLength :: The length of the string in bytes. */ + /* */ + /* stringOffset :: The offset to the string in the `name' table. */ + /* */ + /* string :: A pointer to the string's bytes. Note that these */ + /* are usually UTF-16 encoded characters. */ + /* */ + typedef struct TT_NameEntryRec_ + { + FT_UShort platformID; + FT_UShort encodingID; + FT_UShort languageID; + FT_UShort nameID; + FT_UShort stringLength; + FT_ULong stringOffset; + + /* this last field is not defined in the spec */ + /* but used by the FreeType engine */ + + FT_Byte* string; + + } TT_NameEntryRec, *TT_NameEntry; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_NameTableRec */ + /* */ + /* <Description> */ + /* A structure modeling the TrueType name table. */ + /* */ + /* <Fields> */ + /* format :: The format of the name table. */ + /* */ + /* numNameRecords :: The number of names in table. */ + /* */ + /* storageOffset :: The offset of the name table in the `name' */ + /* TrueType table. */ + /* */ + /* names :: An array of name records. */ + /* */ + /* stream :: the file's input stream. */ + /* */ + typedef struct TT_NameTableRec_ + { + FT_UShort format; + FT_UInt numNameRecords; + FT_UInt storageOffset; + TT_NameEntryRec* names; + FT_Stream stream; + + } TT_NameTableRec, *TT_NameTable; + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*** ***/ + /*** ***/ + /*** OPTIONAL TRUETYPE/OPENTYPE TABLES DEFINITIONS ***/ + /*** ***/ + /*** ***/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_GaspRangeRec */ + /* */ + /* <Description> */ + /* A tiny structure used to model a gasp range according to the */ + /* TrueType specification. */ + /* */ + /* <Fields> */ + /* maxPPEM :: The maximum ppem value to which `gaspFlag' applies. */ + /* */ + /* gaspFlag :: A flag describing the grid-fitting and anti-aliasing */ + /* modes to be used. */ + /* */ + typedef struct TT_GaspRangeRec_ + { + FT_UShort maxPPEM; + FT_UShort gaspFlag; + + } TT_GaspRangeRec, *TT_GaspRange; + + +#define TT_GASP_GRIDFIT 0x01 +#define TT_GASP_DOGRAY 0x02 + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_GaspRec */ + /* */ + /* <Description> */ + /* A structure modeling the TrueType `gasp' table used to specify */ + /* grid-fitting and anti-aliasing behaviour. */ + /* */ + /* <Fields> */ + /* version :: The version number. */ + /* */ + /* numRanges :: The number of gasp ranges in table. */ + /* */ + /* gaspRanges :: An array of gasp ranges. */ + /* */ + typedef struct TT_Gasp_ + { + FT_UShort version; + FT_UShort numRanges; + TT_GaspRange gaspRanges; + + } TT_GaspRec; + + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_HdmxEntryRec */ + /* */ + /* <Description> */ + /* A small structure used to model the pre-computed widths of a given */ + /* size. They are found in the `hdmx' table. */ + /* */ + /* <Fields> */ + /* ppem :: The pixels per EM value at which these metrics apply. */ + /* */ + /* max_width :: The maximum advance width for this metric. */ + /* */ + /* widths :: An array of widths. Note: These are 8-bit bytes. */ + /* */ + typedef struct TT_HdmxEntryRec_ + { + FT_Byte ppem; + FT_Byte max_width; + FT_Byte* widths; + + } TT_HdmxEntryRec, *TT_HdmxEntry; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_HdmxRec */ + /* */ + /* <Description> */ + /* A structure used to model the `hdmx' table, which contains */ + /* pre-computed widths for a set of given sizes/dimensions. */ + /* */ + /* <Fields> */ + /* version :: The version number. */ + /* */ + /* num_records :: The number of hdmx records. */ + /* */ + /* records :: An array of hdmx records. */ + /* */ + typedef struct TT_HdmxRec_ + { + FT_UShort version; + FT_Short num_records; + TT_HdmxEntry records; + + } TT_HdmxRec, *TT_Hdmx; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_Kern0_PairRec */ + /* */ + /* <Description> */ + /* A structure used to model a kerning pair for the kerning table */ + /* format 0. The engine now loads this table if it finds one in the */ + /* font file. */ + /* */ + /* <Fields> */ + /* left :: The index of the left glyph in pair. */ + /* */ + /* right :: The index of the right glyph in pair. */ + /* */ + /* value :: The kerning distance. A positive value spaces the */ + /* glyphs, a negative one makes them closer. */ + /* */ + typedef struct TT_Kern0_PairRec_ + { + FT_UShort left; /* index of left glyph in pair */ + FT_UShort right; /* index of right glyph in pair */ + FT_FWord value; /* kerning value */ + + } TT_Kern0_PairRec, *TT_Kern0_Pair; + +#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */ + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*** ***/ + /*** ***/ + /*** EMBEDDED BITMAPS SUPPORT ***/ + /*** ***/ + /*** ***/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_SBit_MetricsRec */ + /* */ + /* <Description> */ + /* A structure used to hold the big metrics of a given glyph bitmap */ + /* in a TrueType or OpenType font. These are usually found in the */ + /* `EBDT' (Microsoft) or `bloc' (Apple) table. */ + /* */ + /* <Fields> */ + /* height :: The glyph height in pixels. */ + /* */ + /* width :: The glyph width in pixels. */ + /* */ + /* horiBearingX :: The horizontal left bearing. */ + /* */ + /* horiBearingY :: The horizontal top bearing. */ + /* */ + /* horiAdvance :: The horizontal advance. */ + /* */ + /* vertBearingX :: The vertical left bearing. */ + /* */ + /* vertBearingY :: The vertical top bearing. */ + /* */ + /* vertAdvance :: The vertical advance. */ + /* */ + typedef struct TT_SBit_MetricsRec_ + { + FT_Byte height; + FT_Byte width; + + FT_Char horiBearingX; + FT_Char horiBearingY; + FT_Byte horiAdvance; + + FT_Char vertBearingX; + FT_Char vertBearingY; + FT_Byte vertAdvance; + + } TT_SBit_MetricsRec, *TT_SBit_Metrics; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_SBit_SmallMetricsRec */ + /* */ + /* <Description> */ + /* A structure used to hold the small metrics of a given glyph bitmap */ + /* in a TrueType or OpenType font. These are usually found in the */ + /* `EBDT' (Microsoft) or the `bdat' (Apple) table. */ + /* */ + /* <Fields> */ + /* height :: The glyph height in pixels. */ + /* */ + /* width :: The glyph width in pixels. */ + /* */ + /* bearingX :: The left-side bearing. */ + /* */ + /* bearingY :: The top-side bearing. */ + /* */ + /* advance :: The advance width or height. */ + /* */ + typedef struct TT_SBit_Small_Metrics_ + { + FT_Byte height; + FT_Byte width; + + FT_Char bearingX; + FT_Char bearingY; + FT_Byte advance; + + } TT_SBit_SmallMetricsRec, *TT_SBit_SmallMetrics; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_SBit_LineMetricsRec */ + /* */ + /* <Description> */ + /* A structure used to describe the text line metrics of a given */ + /* bitmap strike, for either a horizontal or vertical layout. */ + /* */ + /* <Fields> */ + /* ascender :: The ascender in pixels. */ + /* */ + /* descender :: The descender in pixels. */ + /* */ + /* max_width :: The maximum glyph width in pixels. */ + /* */ + /* caret_slope_enumerator :: Rise of the caret slope, typically set */ + /* to 1 for non-italic fonts. */ + /* */ + /* caret_slope_denominator :: Rise of the caret slope, typically set */ + /* to 0 for non-italic fonts. */ + /* */ + /* caret_offset :: Offset in pixels to move the caret for */ + /* proper positioning. */ + /* */ + /* min_origin_SB :: Minimum of horiBearingX (resp. */ + /* vertBearingY). */ + /* min_advance_SB :: Minimum of */ + /* */ + /* horizontal advance - */ + /* ( horiBearingX + width ) */ + /* */ + /* resp. */ + /* */ + /* vertical advance - */ + /* ( vertBearingY + height ) */ + /* */ + /* max_before_BL :: Maximum of horiBearingY (resp. */ + /* vertBearingY). */ + /* */ + /* min_after_BL :: Minimum of */ + /* */ + /* horiBearingY - height */ + /* */ + /* resp. */ + /* */ + /* vertBearingX - width */ + /* */ + /* pads :: Unused (to make the size of the record */ + /* a multiple of 32 bits. */ + /* */ + typedef struct TT_SBit_LineMetricsRec_ + { + FT_Char ascender; + FT_Char descender; + FT_Byte max_width; + FT_Char caret_slope_numerator; + FT_Char caret_slope_denominator; + FT_Char caret_offset; + FT_Char min_origin_SB; + FT_Char min_advance_SB; + FT_Char max_before_BL; + FT_Char min_after_BL; + FT_Char pads[2]; + + } TT_SBit_LineMetricsRec, *TT_SBit_LineMetrics; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_SBit_RangeRec */ + /* */ + /* <Description> */ + /* A TrueType/OpenType subIndexTable as defined in the `EBLC' */ + /* (Microsoft) or `bloc' (Apple) tables. */ + /* */ + /* <Fields> */ + /* first_glyph :: The first glyph index in the range. */ + /* */ + /* last_glyph :: The last glyph index in the range. */ + /* */ + /* index_format :: The format of index table. Valid values are 1 */ + /* to 5. */ + /* */ + /* image_format :: The format of `EBDT' image data. */ + /* */ + /* image_offset :: The offset to image data in `EBDT'. */ + /* */ + /* image_size :: For index formats 2 and 5. This is the size in */ + /* bytes of each glyph bitmap. */ + /* */ + /* big_metrics :: For index formats 2 and 5. This is the big */ + /* metrics for each glyph bitmap. */ + /* */ + /* num_glyphs :: For index formats 4 and 5. This is the number of */ + /* glyphs in the code array. */ + /* */ + /* glyph_offsets :: For index formats 1 and 3. */ + /* */ + /* glyph_codes :: For index formats 4 and 5. */ + /* */ + /* table_offset :: The offset of the index table in the `EBLC' */ + /* table. Only used during strike loading. */ + /* */ + typedef struct TT_SBit_RangeRec_ + { + FT_UShort first_glyph; + FT_UShort last_glyph; + + FT_UShort index_format; + FT_UShort image_format; + FT_ULong image_offset; + + FT_ULong image_size; + TT_SBit_MetricsRec metrics; + FT_ULong num_glyphs; + + FT_ULong* glyph_offsets; + FT_UShort* glyph_codes; + + FT_ULong table_offset; + + } TT_SBit_RangeRec, *TT_SBit_Range; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_SBit_StrikeRec */ + /* */ + /* <Description> */ + /* A structure used describe a given bitmap strike in the `EBLC' */ + /* (Microsoft) or `bloc' (Apple) tables. */ + /* */ + /* <Fields> */ + /* num_index_ranges :: The number of index ranges. */ + /* */ + /* index_ranges :: An array of glyph index ranges. */ + /* */ + /* color_ref :: Unused. `color_ref' is put in for future */ + /* enhancements, but these fields are already */ + /* in use by other platforms (e.g. Newton). */ + /* For details, please see */ + /* */ + /* http://fonts.apple.com/ */ + /* TTRefMan/RM06/Chap6bloc.html */ + /* */ + /* hori :: The line metrics for horizontal layouts. */ + /* */ + /* vert :: The line metrics for vertical layouts. */ + /* */ + /* start_glyph :: The lowest glyph index for this strike. */ + /* */ + /* end_glyph :: The highest glyph index for this strike. */ + /* */ + /* x_ppem :: The number of horizontal pixels per EM. */ + /* */ + /* y_ppem :: The number of vertical pixels per EM. */ + /* */ + /* bit_depth :: The bit depth. Valid values are 1, 2, 4, */ + /* and 8. */ + /* */ + /* flags :: Is this a vertical or horizontal strike? For */ + /* details, please see */ + /* */ + /* http://fonts.apple.com/ */ + /* TTRefMan/RM06/Chap6bloc.html */ + /* */ + typedef struct TT_SBit_StrikeRec_ + { + FT_Int num_ranges; + TT_SBit_Range sbit_ranges; + FT_ULong ranges_offset; + + FT_ULong color_ref; + + TT_SBit_LineMetricsRec hori; + TT_SBit_LineMetricsRec vert; + + FT_UShort start_glyph; + FT_UShort end_glyph; + + FT_Byte x_ppem; + FT_Byte y_ppem; + + FT_Byte bit_depth; + FT_Char flags; + + } TT_SBit_StrikeRec, *TT_SBit_Strike; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_SBit_ComponentRec */ + /* */ + /* <Description> */ + /* A simple structure to describe a compound sbit element. */ + /* */ + /* <Fields> */ + /* glyph_code :: The element's glyph index. */ + /* */ + /* x_offset :: The element's left bearing. */ + /* */ + /* y_offset :: The element's top bearing. */ + /* */ + typedef struct TT_SBit_ComponentRec_ + { + FT_UShort glyph_code; + FT_Char x_offset; + FT_Char y_offset; + + } TT_SBit_ComponentRec, *TT_SBit_Component; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_SBit_ScaleRec */ + /* */ + /* <Description> */ + /* A structure used describe a given bitmap scaling table, as defined */ + /* in the `EBSC' table. */ + /* */ + /* <Fields> */ + /* hori :: The horizontal line metrics. */ + /* */ + /* vert :: The vertical line metrics. */ + /* */ + /* x_ppem :: The number of horizontal pixels per EM. */ + /* */ + /* y_ppem :: The number of vertical pixels per EM. */ + /* */ + /* x_ppem_substitute :: Substitution x_ppem value. */ + /* */ + /* y_ppem_substitute :: Substitution y_ppem value. */ + /* */ + typedef struct TT_SBit_ScaleRec_ + { + TT_SBit_LineMetricsRec hori; + TT_SBit_LineMetricsRec vert; + + FT_Byte x_ppem; + FT_Byte y_ppem; + + FT_Byte x_ppem_substitute; + FT_Byte y_ppem_substitute; + + } TT_SBit_ScaleRec, *TT_SBit_Scale; + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*** ***/ + /*** ***/ + /*** POSTSCRIPT GLYPH NAMES SUPPORT ***/ + /*** ***/ + /*** ***/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_Post_20Rec */ + /* */ + /* <Description> */ + /* Postscript names sub-table, format 2.0. Stores the PS name of */ + /* each glyph in the font face. */ + /* */ + /* <Fields> */ + /* num_glyphs :: The number of named glyphs in the table. */ + /* */ + /* num_names :: The number of PS names stored in the table. */ + /* */ + /* glyph_indices :: The indices of the glyphs in the names arrays. */ + /* */ + /* glyph_names :: The PS names not in Mac Encoding. */ + /* */ + typedef struct TT_Post_20Rec_ + { + FT_UShort num_glyphs; + FT_UShort num_names; + FT_UShort* glyph_indices; + FT_Char** glyph_names; + + } TT_Post_20Rec, *TT_Post_20; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_Post_25Rec */ + /* */ + /* <Description> */ + /* Postscript names sub-table, format 2.5. Stores the PS name of */ + /* each glyph in the font face. */ + /* */ + /* <Fields> */ + /* num_glyphs :: The number of glyphs in the table. */ + /* */ + /* offsets :: An array of signed offsets in a normal Mac */ + /* Postscript name encoding. */ + /* */ + typedef struct TT_Post_25_ + { + FT_UShort num_glyphs; + FT_Char* offsets; + + } TT_Post_25Rec, *TT_Post_25; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_Post_NamesRec */ + /* */ + /* <Description> */ + /* Postscript names table, either format 2.0 or 2.5. */ + /* */ + /* <Fields> */ + /* loaded :: A flag to indicate whether the PS names are loaded. */ + /* */ + /* format_20 :: The sub-table used for format 2.0. */ + /* */ + /* format_25 :: The sub-table used for format 2.5. */ + /* */ + typedef struct TT_Post_NamesRec_ + { + FT_Bool loaded; + + union + { + TT_Post_20Rec format_20; + TT_Post_25Rec format_25; + + } names; + + } TT_Post_NamesRec, *TT_Post_Names; + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*** ***/ + /*** ***/ + /*** GX VARIATION TABLE SUPPORT ***/ + /*** ***/ + /*** ***/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + typedef struct GX_BlendRec_ *GX_Blend; +#endif + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*** ***/ + /*** ***/ + /*** EMBEDDED BDF PROPERTIES TABLE SUPPORT ***/ + /*** ***/ + /*** ***/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + /* + * These types are used to support a `BDF ' table that isn't part of the + * official TrueType specification. It is mainly used in SFNT-based + * bitmap fonts that were generated from a set of BDF fonts. + * + * The format of the table is as follows. + * + * USHORT version `BDF ' table version number, should be 0x0001. + * USHORT strikeCount Number of strikes (bitmap sizes) in this table. + * ULONG stringTable Offset (from start of BDF table) to string + * table. + * + * This is followed by an array of `strikeCount' descriptors, having the + * following format. + * + * USHORT ppem Vertical pixels per EM for this strike. + * USHORT numItems Number of items for this strike (properties and + * atoms). Maximum is 255. + * + * This array in turn is followed by `strikeCount' value sets. Each + * `value set' is an array of `numItems' items with the following format. + * + * ULONG item_name Offset in string table to item name. + * USHORT item_type The item type. Possible values are + * 0 => string (e.g., COMMENT) + * 1 => atom (e.g., FONT or even SIZE) + * 2 => int32 + * 3 => uint32 + * 0x10 => A flag to indicate a properties. This + * is ORed with the above values. + * ULONG item_value For strings => Offset into string table without + * the corresponding double quotes. + * For atoms => Offset into string table. + * For integers => Direct value. + * + * All strings in the string table consist of bytes and are + * zero-terminated. + * + */ + +#ifdef TT_CONFIG_OPTION_BDF + + typedef struct TT_BDFRec_ + { + FT_Byte* table; + FT_Byte* table_end; + FT_Byte* strings; + FT_ULong strings_size; + FT_UInt num_strikes; + FT_Bool loaded; + + } TT_BDFRec, *TT_BDF; + +#endif /* TT_CONFIG_OPTION_BDF */ + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*** ***/ + /*** ***/ + /*** ORIGINAL TT_FACE CLASS DEFINITION ***/ + /*** ***/ + /*** ***/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This structure/class is defined here because it is common to the */ + /* following formats: TTF, OpenType-TT, and OpenType-CFF. */ + /* */ + /* Note, however, that the classes TT_Size and TT_GlyphSlot are not */ + /* shared between font drivers, and are thus defined in `ttobjs.h'. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* TT_Face */ + /* */ + /* <Description> */ + /* A handle to a TrueType face/font object. A TT_Face encapsulates */ + /* the resolution and scaling independent parts of a TrueType font */ + /* resource. */ + /* */ + /* <Note> */ + /* The TT_Face structure is also used as a `parent class' for the */ + /* OpenType-CFF class (T2_Face). */ + /* */ + typedef struct TT_FaceRec_* TT_Face; + + + /* a function type used for the truetype bytecode interpreter hooks */ + typedef FT_Error + (*TT_Interpreter)( void* exec_context ); + + /* forward declaration */ + typedef struct TT_LoaderRec_* TT_Loader; + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Loader_GotoTableFunc */ + /* */ + /* <Description> */ + /* Seeks a stream to the start of a given TrueType table. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* tag :: A 4-byte tag used to name the table. */ + /* */ + /* stream :: The input stream. */ + /* */ + /* <Output> */ + /* length :: The length of the table in bytes. Set to 0 if not */ + /* needed. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* The stream cursor must be at the font file's origin. */ + /* */ + typedef FT_Error + (*TT_Loader_GotoTableFunc)( TT_Face face, + FT_ULong tag, + FT_Stream stream, + FT_ULong* length ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Loader_StartGlyphFunc */ + /* */ + /* <Description> */ + /* Seeks a stream to the start of a given glyph element, and opens a */ + /* frame for it. */ + /* */ + /* <Input> */ + /* loader :: The current TrueType glyph loader object. */ + /* */ + /* glyph index :: The index of the glyph to access. */ + /* */ + /* offset :: The offset of the glyph according to the */ + /* `locations' table. */ + /* */ + /* byte_count :: The size of the frame in bytes. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* This function is normally equivalent to FT_STREAM_SEEK(offset) */ + /* followed by FT_FRAME_ENTER(byte_count) with the loader's stream, */ + /* but alternative formats (e.g. compressed ones) might use something */ + /* different. */ + /* */ + typedef FT_Error + (*TT_Loader_StartGlyphFunc)( TT_Loader loader, + FT_UInt glyph_index, + FT_ULong offset, + FT_UInt byte_count ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Loader_ReadGlyphFunc */ + /* */ + /* <Description> */ + /* Reads one glyph element (its header, a simple glyph, or a */ + /* composite) from the loader's current stream frame. */ + /* */ + /* <Input> */ + /* loader :: The current TrueType glyph loader object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + typedef FT_Error + (*TT_Loader_ReadGlyphFunc)( TT_Loader loader ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Loader_EndGlyphFunc */ + /* */ + /* <Description> */ + /* Closes the current loader stream frame for the glyph. */ + /* */ + /* <Input> */ + /* loader :: The current TrueType glyph loader object. */ + /* */ + typedef void + (*TT_Loader_EndGlyphFunc)( TT_Loader loader ); + + + /*************************************************************************/ + /* */ + /* TrueType Face Type */ + /* */ + /* <Struct> */ + /* TT_Face */ + /* */ + /* <Description> */ + /* The TrueType face class. These objects model the resolution and */ + /* point-size independent data found in a TrueType font file. */ + /* */ + /* <Fields> */ + /* root :: The base FT_Face structure, managed by the */ + /* base layer. */ + /* */ + /* ttc_header :: The TrueType collection header, used when */ + /* the file is a `ttc' rather than a `ttf'. */ + /* For ordinary font files, the field */ + /* `ttc_header.count' is set to 0. */ + /* */ + /* format_tag :: The font format tag. */ + /* */ + /* num_tables :: The number of TrueType tables in this font */ + /* file. */ + /* */ + /* dir_tables :: The directory of TrueType tables for this */ + /* font file. */ + /* */ + /* header :: The font's font header (`head' table). */ + /* Read on font opening. */ + /* */ + /* horizontal :: The font's horizontal header (`hhea' */ + /* table). This field also contains the */ + /* associated horizontal metrics table */ + /* (`hmtx'). */ + /* */ + /* max_profile :: The font's maximum profile table. Read on */ + /* font opening. Note that some maximum */ + /* values cannot be taken directly from this */ + /* table. We thus define additional fields */ + /* below to hold the computed maxima. */ + /* */ + /* vertical_info :: A boolean which is set when the font file */ + /* contains vertical metrics. If not, the */ + /* value of the `vertical' field is */ + /* undefined. */ + /* */ + /* vertical :: The font's vertical header (`vhea' table). */ + /* This field also contains the associated */ + /* vertical metrics table (`vmtx'), if found. */ + /* IMPORTANT: The contents of this field is */ + /* undefined if the `verticalInfo' field is */ + /* unset. */ + /* */ + /* num_names :: The number of name records within this */ + /* TrueType font. */ + /* */ + /* name_table :: The table of name records (`name'). */ + /* */ + /* os2 :: The font's OS/2 table (`OS/2'). */ + /* */ + /* postscript :: The font's PostScript table (`post' */ + /* table). The PostScript glyph names are */ + /* not loaded by the driver on face opening. */ + /* See the `ttpost' module for more details. */ + /* */ + /* cmap_table :: Address of the face's `cmap' SFNT table */ + /* in memory (it's an extracted frame). */ + /* */ + /* cmap_size :: The size in bytes of the `cmap_table' */ + /* described above. */ + /* */ + /* goto_table :: A function called by each TrueType table */ + /* loader to position a stream's cursor to */ + /* the start of a given table according to */ + /* its tag. It defaults to TT_Goto_Face but */ + /* can be different for strange formats (e.g. */ + /* Type 42). */ + /* */ + /* access_glyph_frame :: A function used to access the frame of a */ + /* given glyph within the face's font file. */ + /* */ + /* forget_glyph_frame :: A function used to forget the frame of a */ + /* given glyph when all data has been loaded. */ + /* */ + /* read_glyph_header :: A function used to read a glyph header. */ + /* It must be called between an `access' and */ + /* `forget'. */ + /* */ + /* read_simple_glyph :: A function used to read a simple glyph. */ + /* It must be called after the header was */ + /* read, and before the `forget'. */ + /* */ + /* read_composite_glyph :: A function used to read a composite glyph. */ + /* It must be called after the header was */ + /* read, and before the `forget'. */ + /* */ + /* sfnt :: A pointer to the SFNT service. */ + /* */ + /* psnames :: A pointer to the PostScript names service. */ + /* */ + /* hdmx :: The face's horizontal device metrics */ + /* (`hdmx' table). This table is optional in */ + /* TrueType/OpenType fonts. */ + /* */ + /* gasp :: The grid-fitting and scaling properties */ + /* table (`gasp'). This table is optional in */ + /* TrueType/OpenType fonts. */ + /* */ + /* pclt :: The `pclt' SFNT table. */ + /* */ + /* num_sbit_strikes :: The number of sbit strikes, i.e., bitmap */ + /* sizes, embedded in this font. */ + /* */ + /* sbit_strikes :: An array of sbit strikes embedded in this */ + /* font. This table is optional in a */ + /* TrueType/OpenType font. */ + /* */ + /* num_sbit_scales :: The number of sbit scales for this font. */ + /* */ + /* sbit_scales :: Array of sbit scales embedded in this */ + /* font. This table is optional in a */ + /* TrueType/OpenType font. */ + /* */ + /* postscript_names :: A table used to store the Postscript names */ + /* of the glyphs for this font. See the */ + /* file `ttconfig.h' for comments on the */ + /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES option. */ + /* */ + /* num_locations :: The number of glyph locations in this */ + /* TrueType file. This should be */ + /* identical to the number of glyphs. */ + /* Ignored for Type 2 fonts. */ + /* */ + /* glyph_locations :: An array of longs. These are offsets to */ + /* glyph data within the `glyf' table. */ + /* Ignored for Type 2 font faces. */ + /* */ + /* glyf_len :: The length of the `glyf' table. Needed */ + /* for malformed `loca' tables. */ + /* */ + /* font_program_size :: Size in bytecodes of the face's font */ + /* program. 0 if none defined. Ignored for */ + /* Type 2 fonts. */ + /* */ + /* font_program :: The face's font program (bytecode stream) */ + /* executed at load time, also used during */ + /* glyph rendering. Comes from the `fpgm' */ + /* table. Ignored for Type 2 font fonts. */ + /* */ + /* cvt_program_size :: The size in bytecodes of the face's cvt */ + /* program. Ignored for Type 2 fonts. */ + /* */ + /* cvt_program :: The face's cvt program (bytecode stream) */ + /* executed each time an instance/size is */ + /* changed/reset. Comes from the `prep' */ + /* table. Ignored for Type 2 fonts. */ + /* */ + /* cvt_size :: Size of the control value table (in */ + /* entries). Ignored for Type 2 fonts. */ + /* */ + /* cvt :: The face's original control value table. */ + /* Coordinates are expressed in unscaled font */ + /* units. Comes from the `cvt ' table. */ + /* Ignored for Type 2 fonts. */ + /* */ + /* num_kern_pairs :: The number of kerning pairs present in the */ + /* font file. The engine only loads the */ + /* first horizontal format 0 kern table it */ + /* finds in the font file. Ignored for */ + /* Type 2 fonts. */ + /* */ + /* kern_table_index :: The index of the kerning table in the font */ + /* kerning directory. Ignored for Type 2 */ + /* fonts. */ + /* */ + /* interpreter :: A pointer to the TrueType bytecode */ + /* interpreters field is also used to hook */ + /* the debugger in `ttdebug'. */ + /* */ + /* unpatented_hinting :: If true, use only unpatented methods in */ + /* the bytecode interpreter. */ + /* */ + /* doblend :: A boolean which is set if the font should */ + /* be blended (this is for GX var). */ + /* */ + /* blend :: Contains the data needed to control GX */ + /* variation tables (rather like Multiple */ + /* Master data). */ + /* */ + /* extra :: Reserved for third-party font drivers. */ + /* */ + /* postscript_name :: The PS name of the font. Used by the */ + /* postscript name service. */ + /* */ + typedef struct TT_FaceRec_ + { + FT_FaceRec root; + + TTC_HeaderRec ttc_header; + + FT_ULong format_tag; + FT_UShort num_tables; + TT_Table dir_tables; + + TT_Header header; /* TrueType header table */ + TT_HoriHeader horizontal; /* TrueType horizontal header */ + + TT_MaxProfile max_profile; +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + FT_ULong max_components; /* stubbed to 0 */ +#endif + + FT_Bool vertical_info; + TT_VertHeader vertical; /* TT Vertical header, if present */ + + FT_UShort num_names; /* number of name records */ + TT_NameTableRec name_table; /* name table */ + + TT_OS2 os2; /* TrueType OS/2 table */ + TT_Postscript postscript; /* TrueType Postscript table */ + + FT_Byte* cmap_table; /* extracted `cmap' table */ + FT_ULong cmap_size; + + TT_Loader_GotoTableFunc goto_table; + + TT_Loader_StartGlyphFunc access_glyph_frame; + TT_Loader_EndGlyphFunc forget_glyph_frame; + TT_Loader_ReadGlyphFunc read_glyph_header; + TT_Loader_ReadGlyphFunc read_simple_glyph; + TT_Loader_ReadGlyphFunc read_composite_glyph; + + /* a typeless pointer to the SFNT_Interface table used to load */ + /* the basic TrueType tables in the face object */ + void* sfnt; + + /* a typeless pointer to the FT_Service_PsCMapsRec table used to */ + /* handle glyph names <-> unicode & Mac values */ + void* psnames; + + + /***********************************************************************/ + /* */ + /* Optional TrueType/OpenType tables */ + /* */ + /***********************************************************************/ + + /* horizontal device metrics */ +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + TT_HdmxRec hdmx; +#endif + + /* grid-fitting and scaling table */ + TT_GaspRec gasp; /* the `gasp' table */ + + /* PCL 5 table */ + TT_PCLT pclt; + + /* embedded bitmaps support */ +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + FT_ULong num_sbit_strikes; + TT_SBit_Strike sbit_strikes; +#endif + + FT_ULong num_sbit_scales; + TT_SBit_Scale sbit_scales; + + /* postscript names table */ + TT_Post_NamesRec postscript_names; + + + /***********************************************************************/ + /* */ + /* TrueType-specific fields (ignored by the OTF-Type2 driver) */ + /* */ + /***********************************************************************/ + + /* the glyph locations */ +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + FT_UShort num_locations_stub; + FT_Long* glyph_locations_stub; +#endif + + /* the font program, if any */ + FT_ULong font_program_size; + FT_Byte* font_program; + + /* the cvt program, if any */ + FT_ULong cvt_program_size; + FT_Byte* cvt_program; + + /* the original, unscaled, control value table */ + FT_ULong cvt_size; + FT_Short* cvt; + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + /* the format 0 kerning table, if any */ + FT_Int num_kern_pairs; + FT_Int kern_table_index; + TT_Kern0_Pair kern_pairs; +#endif + + /* A pointer to the bytecode interpreter to use. This is also */ + /* used to hook the debugger for the `ttdebug' utility. */ + TT_Interpreter interpreter; + +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING + /* Use unpatented hinting only. */ + FT_Bool unpatented_hinting; +#endif + + /***********************************************************************/ + /* */ + /* Other tables or fields. This is used by derivative formats like */ + /* OpenType. */ + /* */ + /***********************************************************************/ + + FT_Generic extra; + + const char* postscript_name; + + /* since version 2.1.8, but was originally placed after */ + /* `glyph_locations_stub' */ + FT_ULong glyf_len; + + /* since version 2.1.8, but was originally placed before `extra' */ +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + FT_Bool doblend; + GX_Blend blend; +#endif + + /* since version 2.2 */ + + FT_Byte* horz_metrics; + FT_ULong horz_metrics_size; + + FT_Byte* vert_metrics; + FT_ULong vert_metrics_size; + + FT_ULong num_locations; /* in broken TTF, gid > 0xFFFF */ + FT_Byte* glyph_locations; + + FT_Byte* hdmx_table; + FT_ULong hdmx_table_size; + FT_UInt hdmx_record_count; + FT_ULong hdmx_record_size; + FT_Byte* hdmx_record_sizes; + + FT_Byte* sbit_table; + FT_ULong sbit_table_size; + FT_UInt sbit_num_strikes; + + FT_Byte* kern_table; + FT_ULong kern_table_size; + FT_UInt num_kern_tables; + FT_UInt32 kern_avail_bits; + FT_UInt32 kern_order_bits; + +#ifdef TT_CONFIG_OPTION_BDF + TT_BDFRec bdf; +#endif /* TT_CONFIG_OPTION_BDF */ + + /* since 2.3.0 */ + FT_ULong horz_metrics_offset; + FT_ULong vert_metrics_offset; + + } TT_FaceRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_GlyphZoneRec */ + /* */ + /* <Description> */ + /* A glyph zone is used to load, scale and hint glyph outline */ + /* coordinates. */ + /* */ + /* <Fields> */ + /* memory :: A handle to the memory manager. */ + /* */ + /* max_points :: The maximal size in points of the zone. */ + /* */ + /* max_contours :: Max size in links contours of the zone. */ + /* */ + /* n_points :: The current number of points in the zone. */ + /* */ + /* n_contours :: The current number of contours in the zone. */ + /* */ + /* org :: The original glyph coordinates (font */ + /* units/scaled). */ + /* */ + /* cur :: The current glyph coordinates (scaled/hinted). */ + /* */ + /* tags :: The point control tags. */ + /* */ + /* contours :: The contours end points. */ + /* */ + /* first_point :: Offset of the current subglyph's first point. */ + /* */ + typedef struct TT_GlyphZoneRec_ + { + FT_Memory memory; + FT_UShort max_points; + FT_UShort max_contours; + FT_UShort n_points; /* number of points in zone */ + FT_Short n_contours; /* number of contours */ + + FT_Vector* org; /* original point coordinates */ + FT_Vector* cur; /* current point coordinates */ + FT_Vector* orus; /* original (unscaled) point coordinates */ + + FT_Byte* tags; /* current touch flags */ + FT_UShort* contours; /* contour end points */ + + FT_UShort first_point; /* offset of first (#0) point */ + + } TT_GlyphZoneRec, *TT_GlyphZone; + + + /* handle to execution context */ + typedef struct TT_ExecContextRec_* TT_ExecContext; + + /* glyph loader structure */ + typedef struct TT_LoaderRec_ + { + FT_Face face; + FT_Size size; + FT_GlyphSlot glyph; + FT_GlyphLoader gloader; + + FT_ULong load_flags; + FT_UInt glyph_index; + + FT_Stream stream; + FT_Int byte_len; + + FT_Short n_contours; + FT_BBox bbox; + FT_Int left_bearing; + FT_Int advance; + FT_Int linear; + FT_Bool linear_def; + FT_Bool preserve_pps; + FT_Vector pp1; + FT_Vector pp2; + + FT_ULong glyf_offset; + + /* the zone where we load our glyphs */ + TT_GlyphZoneRec base; + TT_GlyphZoneRec zone; + + TT_ExecContext exec; + FT_Byte* instructions; + FT_ULong ins_pos; + + /* for possible extensibility in other formats */ + void* other; + + /* since version 2.1.8 */ + FT_Int top_bearing; + FT_Int vadvance; + FT_Vector pp3; + FT_Vector pp4; + + /* since version 2.2.1 */ + FT_Byte* cursor; + FT_Byte* limit; + + } TT_LoaderRec; + + +FT_END_HEADER + +#endif /* __TTTYPES_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/t1tables.h b/mod/pub.mod/freetype.mod/include/freetype/t1tables.h new file mode 100644 index 0000000..5e2a393 --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/t1tables.h @@ -0,0 +1,504 @@ +/***************************************************************************/ +/* */ +/* t1tables.h */ +/* */ +/* Basic Type 1/Type 2 tables definitions and interface (specification */ +/* only). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __T1TABLES_H__ +#define __T1TABLES_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* type1_tables */ + /* */ + /* <Title> */ + /* Type 1 Tables */ + /* */ + /* <Abstract> */ + /* Type~1 (PostScript) specific font tables. */ + /* */ + /* <Description> */ + /* This section contains the definition of Type 1-specific tables, */ + /* including structures related to other PostScript font formats. */ + /* */ + /*************************************************************************/ + + + /* Note that we separate font data in PS_FontInfoRec and PS_PrivateRec */ + /* structures in order to support Multiple Master fonts. */ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* PS_FontInfoRec */ + /* */ + /* <Description> */ + /* A structure used to model a Type~1 or Type~2 FontInfo dictionary. */ + /* Note that for Multiple Master fonts, each instance has its own */ + /* FontInfo dictionary. */ + /* */ + typedef struct PS_FontInfoRec_ + { + FT_String* version; + FT_String* notice; + FT_String* full_name; + FT_String* family_name; + FT_String* weight; + FT_Long italic_angle; + FT_Bool is_fixed_pitch; + FT_Short underline_position; + FT_UShort underline_thickness; + + } PS_FontInfoRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* PS_FontInfo */ + /* */ + /* <Description> */ + /* A handle to a @PS_FontInfoRec structure. */ + /* */ + typedef struct PS_FontInfoRec_* PS_FontInfo; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* T1_FontInfo */ + /* */ + /* <Description> */ + /* This type is equivalent to @PS_FontInfoRec. It is deprecated but */ + /* kept to maintain source compatibility between various versions of */ + /* FreeType. */ + /* */ + typedef PS_FontInfoRec T1_FontInfo; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* PS_PrivateRec */ + /* */ + /* <Description> */ + /* A structure used to model a Type~1 or Type~2 private dictionary. */ + /* Note that for Multiple Master fonts, each instance has its own */ + /* Private dictionary. */ + /* */ + typedef struct PS_PrivateRec_ + { + FT_Int unique_id; + FT_Int lenIV; + + FT_Byte num_blue_values; + FT_Byte num_other_blues; + FT_Byte num_family_blues; + FT_Byte num_family_other_blues; + + FT_Short blue_values[14]; + FT_Short other_blues[10]; + + FT_Short family_blues [14]; + FT_Short family_other_blues[10]; + + FT_Fixed blue_scale; + FT_Int blue_shift; + FT_Int blue_fuzz; + + FT_UShort standard_width[1]; + FT_UShort standard_height[1]; + + FT_Byte num_snap_widths; + FT_Byte num_snap_heights; + FT_Bool force_bold; + FT_Bool round_stem_up; + + FT_Short snap_widths [13]; /* including std width */ + FT_Short snap_heights[13]; /* including std height */ + + FT_Fixed expansion_factor; + + FT_Long language_group; + FT_Long password; + + FT_Short min_feature[2]; + + } PS_PrivateRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* PS_Private */ + /* */ + /* <Description> */ + /* A handle to a @PS_PrivateRec structure. */ + /* */ + typedef struct PS_PrivateRec_* PS_Private; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* T1_Private */ + /* */ + /* <Description> */ + /* This type is equivalent to @PS_PrivateRec. It is deprecated but */ + /* kept to maintain source compatibility between various versions of */ + /* FreeType. */ + /* */ + typedef PS_PrivateRec T1_Private; + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* T1_Blend_Flags */ + /* */ + /* <Description> */ + /* A set of flags used to indicate which fields are present in a */ + /* given blend dictionary (font info or private). Used to support */ + /* Multiple Masters fonts. */ + /* */ + typedef enum T1_Blend_Flags_ + { + /*# required fields in a FontInfo blend dictionary */ + T1_BLEND_UNDERLINE_POSITION = 0, + T1_BLEND_UNDERLINE_THICKNESS, + T1_BLEND_ITALIC_ANGLE, + + /*# required fields in a Private blend dictionary */ + T1_BLEND_BLUE_VALUES, + T1_BLEND_OTHER_BLUES, + T1_BLEND_STANDARD_WIDTH, + T1_BLEND_STANDARD_HEIGHT, + T1_BLEND_STEM_SNAP_WIDTHS, + T1_BLEND_STEM_SNAP_HEIGHTS, + T1_BLEND_BLUE_SCALE, + T1_BLEND_BLUE_SHIFT, + T1_BLEND_FAMILY_BLUES, + T1_BLEND_FAMILY_OTHER_BLUES, + T1_BLEND_FORCE_BOLD, + + /*# never remove */ + T1_BLEND_MAX + + } T1_Blend_Flags; + + /* */ + + + /*# backwards compatible definitions */ +#define t1_blend_underline_position T1_BLEND_UNDERLINE_POSITION +#define t1_blend_underline_thickness T1_BLEND_UNDERLINE_THICKNESS +#define t1_blend_italic_angle T1_BLEND_ITALIC_ANGLE +#define t1_blend_blue_values T1_BLEND_BLUE_VALUES +#define t1_blend_other_blues T1_BLEND_OTHER_BLUES +#define t1_blend_standard_widths T1_BLEND_STANDARD_WIDTH +#define t1_blend_standard_height T1_BLEND_STANDARD_HEIGHT +#define t1_blend_stem_snap_widths T1_BLEND_STEM_SNAP_WIDTHS +#define t1_blend_stem_snap_heights T1_BLEND_STEM_SNAP_HEIGHTS +#define t1_blend_blue_scale T1_BLEND_BLUE_SCALE +#define t1_blend_blue_shift T1_BLEND_BLUE_SHIFT +#define t1_blend_family_blues T1_BLEND_FAMILY_BLUES +#define t1_blend_family_other_blues T1_BLEND_FAMILY_OTHER_BLUES +#define t1_blend_force_bold T1_BLEND_FORCE_BOLD +#define t1_blend_max T1_BLEND_MAX + + + /* maximum number of Multiple Masters designs, as defined in the spec */ +#define T1_MAX_MM_DESIGNS 16 + + /* maximum number of Multiple Masters axes, as defined in the spec */ +#define T1_MAX_MM_AXIS 4 + + /* maximum number of elements in a design map */ +#define T1_MAX_MM_MAP_POINTS 20 + + + /* this structure is used to store the BlendDesignMap entry for an axis */ + typedef struct PS_DesignMap_ + { + FT_Byte num_points; + FT_Long* design_points; + FT_Fixed* blend_points; + + } PS_DesignMapRec, *PS_DesignMap; + + /* backwards-compatible definition */ + typedef PS_DesignMapRec T1_DesignMap; + + + typedef struct PS_BlendRec_ + { + FT_UInt num_designs; + FT_UInt num_axis; + + FT_String* axis_names[T1_MAX_MM_AXIS]; + FT_Fixed* design_pos[T1_MAX_MM_DESIGNS]; + PS_DesignMapRec design_map[T1_MAX_MM_AXIS]; + + FT_Fixed* weight_vector; + FT_Fixed* default_weight_vector; + + PS_FontInfo font_infos[T1_MAX_MM_DESIGNS + 1]; + PS_Private privates [T1_MAX_MM_DESIGNS + 1]; + + FT_ULong blend_bitflags; + + FT_BBox* bboxes [T1_MAX_MM_DESIGNS + 1]; + + /* since 2.3.0 */ + + /* undocumented, optional: the default design instance; */ + /* corresponds to default_weight_vector -- */ + /* num_default_design_vector == 0 means it is not present */ + /* in the font and associated metrics files */ + FT_UInt default_design_vector[T1_MAX_MM_DESIGNS]; + FT_UInt num_default_design_vector; + + } PS_BlendRec, *PS_Blend; + + + /* backwards-compatible definition */ + typedef PS_BlendRec T1_Blend; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* CID_FaceDictRec */ + /* */ + /* <Description> */ + /* A structure used to represent data in a CID top-level dictionary. */ + /* */ + typedef struct CID_FaceDictRec_ + { + PS_PrivateRec private_dict; + + FT_UInt len_buildchar; + FT_Fixed forcebold_threshold; + FT_Pos stroke_width; + FT_Fixed expansion_factor; + + FT_Byte paint_type; + FT_Byte font_type; + FT_Matrix font_matrix; + FT_Vector font_offset; + + FT_UInt num_subrs; + FT_ULong subrmap_offset; + FT_Int sd_bytes; + + } CID_FaceDictRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* CID_FaceDict */ + /* */ + /* <Description> */ + /* A handle to a @CID_FaceDictRec structure. */ + /* */ + typedef struct CID_FaceDictRec_* CID_FaceDict; + + /* */ + + + /* backwards-compatible definition */ + typedef CID_FaceDictRec CID_FontDict; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* CID_FaceInfoRec */ + /* */ + /* <Description> */ + /* A structure used to represent CID Face information. */ + /* */ + typedef struct CID_FaceInfoRec_ + { + FT_String* cid_font_name; + FT_Fixed cid_version; + FT_Int cid_font_type; + + FT_String* registry; + FT_String* ordering; + FT_Int supplement; + + PS_FontInfoRec font_info; + FT_BBox font_bbox; + FT_ULong uid_base; + + FT_Int num_xuid; + FT_ULong xuid[16]; + + FT_ULong cidmap_offset; + FT_Int fd_bytes; + FT_Int gd_bytes; + FT_ULong cid_count; + + FT_Int num_dicts; + CID_FaceDict font_dicts; + + FT_ULong data_offset; + + } CID_FaceInfoRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* CID_FaceInfo */ + /* */ + /* <Description> */ + /* A handle to a @CID_FaceInfoRec structure. */ + /* */ + typedef struct CID_FaceInfoRec_* CID_FaceInfo; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* CID_Info */ + /* */ + /* <Description> */ + /* This type is equivalent to @CID_FaceInfoRec. It is deprecated but */ + /* kept to maintain source compatibility between various versions of */ + /* FreeType. */ + /* */ + typedef CID_FaceInfoRec CID_Info; + + + /************************************************************************ + * + * @function: + * FT_Has_PS_Glyph_Names + * + * @description: + * Return true if a given face provides reliable PostScript glyph + * names. This is similar to using the @FT_HAS_GLYPH_NAMES macro, + * except that certain fonts (mostly TrueType) contain incorrect + * glyph name tables. + * + * When this function returns true, the caller is sure that the glyph + * names returned by @FT_Get_Glyph_Name are reliable. + * + * @input: + * face :: + * face handle + * + * @return: + * Boolean. True if glyph names are reliable. + * + */ + FT_EXPORT( FT_Int ) + FT_Has_PS_Glyph_Names( FT_Face face ); + + + /************************************************************************ + * + * @function: + * FT_Get_PS_Font_Info + * + * @description: + * Retrieve the @PS_FontInfoRec structure corresponding to a given + * PostScript font. + * + * @input: + * face :: + * PostScript face handle. + * + * @output: + * afont_info :: + * Output font info structure pointer. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The string pointers within the font info structure are owned by + * the face and don't need to be freed by the caller. + * + * If the font's format is not PostScript-based, this function will + * return the `FT_Err_Invalid_Argument' error code. + * + */ + FT_EXPORT( FT_Error ) + FT_Get_PS_Font_Info( FT_Face face, + PS_FontInfo afont_info ); + + + /************************************************************************ + * + * @function: + * FT_Get_PS_Font_Private + * + * @description: + * Retrieve the @PS_PrivateRec structure corresponding to a given + * PostScript font. + * + * @input: + * face :: + * PostScript face handle. + * + * @output: + * afont_private :: + * Output private dictionary structure pointer. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The string pointers within the @PS_PrivateRec structure are owned by + * the face and don't need to be freed by the caller. + * + * If the font's format is not PostScript-based, this function returns + * the `FT_Err_Invalid_Argument' error code. + * + */ + FT_EXPORT( FT_Error ) + FT_Get_PS_Font_Private( FT_Face face, + PS_Private afont_private ); + + /* */ + + +FT_END_HEADER + +#endif /* __T1TABLES_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/ttnameid.h b/mod/pub.mod/freetype.mod/include/freetype/ttnameid.h new file mode 100644 index 0000000..cbeac78 --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/ttnameid.h @@ -0,0 +1,1247 @@ +/***************************************************************************/ +/* */ +/* ttnameid.h */ +/* */ +/* TrueType name ID definitions (specification only). */ +/* */ +/* Copyright 1996-2002, 2003, 2004, 2006, 2007, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __TTNAMEID_H__ +#define __TTNAMEID_H__ + + +#include <ft2build.h> + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* truetype_tables */ + /* */ + + + /*************************************************************************/ + /* */ + /* Possible values for the `platform' identifier code in the name */ + /* records of the TTF `name' table. */ + /* */ + /*************************************************************************/ + + + /*********************************************************************** + * + * @enum: + * TT_PLATFORM_XXX + * + * @description: + * A list of valid values for the `platform_id' identifier code in + * @FT_CharMapRec and @FT_SfntName structures. + * + * @values: + * TT_PLATFORM_APPLE_UNICODE :: + * Used by Apple to indicate a Unicode character map and/or name entry. + * See @TT_APPLE_ID_XXX for corresponding `encoding_id' values. Note + * that name entries in this format are coded as big-endian UCS-2 + * character codes _only_. + * + * TT_PLATFORM_MACINTOSH :: + * Used by Apple to indicate a MacOS-specific charmap and/or name entry. + * See @TT_MAC_ID_XXX for corresponding `encoding_id' values. Note that + * most TrueType fonts contain an Apple roman charmap to be usable on + * MacOS systems (even if they contain a Microsoft charmap as well). + * + * TT_PLATFORM_ISO :: + * This value was used to specify Unicode charmaps. It is however + * now deprecated. See @TT_ISO_ID_XXX for a list of corresponding + * `encoding_id' values. + * + * TT_PLATFORM_MICROSOFT :: + * Used by Microsoft to indicate Windows-specific charmaps. See + * @TT_MS_ID_XXX for a list of corresponding `encoding_id' values. + * Note that most fonts contain a Unicode charmap using + * (TT_PLATFORM_MICROSOFT, @TT_MS_ID_UNICODE_CS). + * + * TT_PLATFORM_CUSTOM :: + * Used to indicate application-specific charmaps. + * + * TT_PLATFORM_ADOBE :: + * This value isn't part of any font format specification, but is used + * by FreeType to report Adobe-specific charmaps in an @FT_CharMapRec + * structure. See @TT_ADOBE_ID_XXX. + */ + +#define TT_PLATFORM_APPLE_UNICODE 0 +#define TT_PLATFORM_MACINTOSH 1 +#define TT_PLATFORM_ISO 2 /* deprecated */ +#define TT_PLATFORM_MICROSOFT 3 +#define TT_PLATFORM_CUSTOM 4 +#define TT_PLATFORM_ADOBE 7 /* artificial */ + + + /*********************************************************************** + * + * @enum: + * TT_APPLE_ID_XXX + * + * @description: + * A list of valid values for the `encoding_id' for + * @TT_PLATFORM_APPLE_UNICODE charmaps and name entries. + * + * @values: + * TT_APPLE_ID_DEFAULT :: + * Unicode version 1.0. + * + * TT_APPLE_ID_UNICODE_1_1 :: + * Unicode 1.1; specifies Hangul characters starting at U+34xx. + * + * TT_APPLE_ID_ISO_10646 :: + * Deprecated (identical to preceding). + * + * TT_APPLE_ID_UNICODE_2_0 :: + * Unicode 2.0 and beyond (UTF-16 BMP only). + * + * TT_APPLE_ID_UNICODE_32 :: + * Unicode 3.1 and beyond, using UTF-32. + * + * TT_APPLE_ID_VARIANT_SELECTOR :: + * From Adobe, not Apple. Not a normal cmap. Specifies variations + * on a real cmap. + */ + +#define TT_APPLE_ID_DEFAULT 0 /* Unicode 1.0 */ +#define TT_APPLE_ID_UNICODE_1_1 1 /* specify Hangul at U+34xx */ +#define TT_APPLE_ID_ISO_10646 2 /* deprecated */ +#define TT_APPLE_ID_UNICODE_2_0 3 /* or later */ +#define TT_APPLE_ID_UNICODE_32 4 /* 2.0 or later, full repertoire */ +#define TT_APPLE_ID_VARIANT_SELECTOR 5 /* variation selector data */ + + + /*********************************************************************** + * + * @enum: + * TT_MAC_ID_XXX + * + * @description: + * A list of valid values for the `encoding_id' for + * @TT_PLATFORM_MACINTOSH charmaps and name entries. + * + * @values: + * TT_MAC_ID_ROMAN :: + * TT_MAC_ID_JAPANESE :: + * TT_MAC_ID_TRADITIONAL_CHINESE :: + * TT_MAC_ID_KOREAN :: + * TT_MAC_ID_ARABIC :: + * TT_MAC_ID_HEBREW :: + * TT_MAC_ID_GREEK :: + * TT_MAC_ID_RUSSIAN :: + * TT_MAC_ID_RSYMBOL :: + * TT_MAC_ID_DEVANAGARI :: + * TT_MAC_ID_GURMUKHI :: + * TT_MAC_ID_GUJARATI :: + * TT_MAC_ID_ORIYA :: + * TT_MAC_ID_BENGALI :: + * TT_MAC_ID_TAMIL :: + * TT_MAC_ID_TELUGU :: + * TT_MAC_ID_KANNADA :: + * TT_MAC_ID_MALAYALAM :: + * TT_MAC_ID_SINHALESE :: + * TT_MAC_ID_BURMESE :: + * TT_MAC_ID_KHMER :: + * TT_MAC_ID_THAI :: + * TT_MAC_ID_LAOTIAN :: + * TT_MAC_ID_GEORGIAN :: + * TT_MAC_ID_ARMENIAN :: + * TT_MAC_ID_MALDIVIAN :: + * TT_MAC_ID_SIMPLIFIED_CHINESE :: + * TT_MAC_ID_TIBETAN :: + * TT_MAC_ID_MONGOLIAN :: + * TT_MAC_ID_GEEZ :: + * TT_MAC_ID_SLAVIC :: + * TT_MAC_ID_VIETNAMESE :: + * TT_MAC_ID_SINDHI :: + * TT_MAC_ID_UNINTERP :: + */ + +#define TT_MAC_ID_ROMAN 0 +#define TT_MAC_ID_JAPANESE 1 +#define TT_MAC_ID_TRADITIONAL_CHINESE 2 +#define TT_MAC_ID_KOREAN 3 +#define TT_MAC_ID_ARABIC 4 +#define TT_MAC_ID_HEBREW 5 +#define TT_MAC_ID_GREEK 6 +#define TT_MAC_ID_RUSSIAN 7 +#define TT_MAC_ID_RSYMBOL 8 +#define TT_MAC_ID_DEVANAGARI 9 +#define TT_MAC_ID_GURMUKHI 10 +#define TT_MAC_ID_GUJARATI 11 +#define TT_MAC_ID_ORIYA 12 +#define TT_MAC_ID_BENGALI 13 +#define TT_MAC_ID_TAMIL 14 +#define TT_MAC_ID_TELUGU 15 +#define TT_MAC_ID_KANNADA 16 +#define TT_MAC_ID_MALAYALAM 17 +#define TT_MAC_ID_SINHALESE 18 +#define TT_MAC_ID_BURMESE 19 +#define TT_MAC_ID_KHMER 20 +#define TT_MAC_ID_THAI 21 +#define TT_MAC_ID_LAOTIAN 22 +#define TT_MAC_ID_GEORGIAN 23 +#define TT_MAC_ID_ARMENIAN 24 +#define TT_MAC_ID_MALDIVIAN 25 +#define TT_MAC_ID_SIMPLIFIED_CHINESE 25 +#define TT_MAC_ID_TIBETAN 26 +#define TT_MAC_ID_MONGOLIAN 27 +#define TT_MAC_ID_GEEZ 28 +#define TT_MAC_ID_SLAVIC 29 +#define TT_MAC_ID_VIETNAMESE 30 +#define TT_MAC_ID_SINDHI 31 +#define TT_MAC_ID_UNINTERP 32 + + + /*********************************************************************** + * + * @enum: + * TT_ISO_ID_XXX + * + * @description: + * A list of valid values for the `encoding_id' for + * @TT_PLATFORM_ISO charmaps and name entries. + * + * Their use is now deprecated. + * + * @values: + * TT_ISO_ID_7BIT_ASCII :: + * ASCII. + * TT_ISO_ID_10646 :: + * ISO/10646. + * TT_ISO_ID_8859_1 :: + * Also known as Latin-1. + */ + +#define TT_ISO_ID_7BIT_ASCII 0 +#define TT_ISO_ID_10646 1 +#define TT_ISO_ID_8859_1 2 + + + /*********************************************************************** + * + * @enum: + * TT_MS_ID_XXX + * + * @description: + * A list of valid values for the `encoding_id' for + * @TT_PLATFORM_MICROSOFT charmaps and name entries. + * + * @values: + * TT_MS_ID_SYMBOL_CS :: + * Corresponds to Microsoft symbol encoding. See + * @FT_ENCODING_MS_SYMBOL. + * + * TT_MS_ID_UNICODE_CS :: + * Corresponds to a Microsoft WGL4 charmap, matching Unicode. See + * @FT_ENCODING_UNICODE. + * + * TT_MS_ID_SJIS :: + * Corresponds to SJIS Japanese encoding. See @FT_ENCODING_SJIS. + * + * TT_MS_ID_GB2312 :: + * Corresponds to Simplified Chinese as used in Mainland China. See + * @FT_ENCODING_GB2312. + * + * TT_MS_ID_BIG_5 :: + * Corresponds to Traditional Chinese as used in Taiwan and Hong Kong. + * See @FT_ENCODING_BIG5. + * + * TT_MS_ID_WANSUNG :: + * Corresponds to Korean Wansung encoding. See @FT_ENCODING_WANSUNG. + * + * TT_MS_ID_JOHAB :: + * Corresponds to Johab encoding. See @FT_ENCODING_JOHAB. + * + * TT_MS_ID_UCS_4 :: + * Corresponds to UCS-4 or UTF-32 charmaps. This has been added to + * the OpenType specification version 1.4 (mid-2001.) + */ + +#define TT_MS_ID_SYMBOL_CS 0 +#define TT_MS_ID_UNICODE_CS 1 +#define TT_MS_ID_SJIS 2 +#define TT_MS_ID_GB2312 3 +#define TT_MS_ID_BIG_5 4 +#define TT_MS_ID_WANSUNG 5 +#define TT_MS_ID_JOHAB 6 +#define TT_MS_ID_UCS_4 10 + + + /*********************************************************************** + * + * @enum: + * TT_ADOBE_ID_XXX + * + * @description: + * A list of valid values for the `encoding_id' for + * @TT_PLATFORM_ADOBE charmaps. This is a FreeType-specific extension! + * + * @values: + * TT_ADOBE_ID_STANDARD :: + * Adobe standard encoding. + * TT_ADOBE_ID_EXPERT :: + * Adobe expert encoding. + * TT_ADOBE_ID_CUSTOM :: + * Adobe custom encoding. + * TT_ADOBE_ID_LATIN_1 :: + * Adobe Latin~1 encoding. + */ + +#define TT_ADOBE_ID_STANDARD 0 +#define TT_ADOBE_ID_EXPERT 1 +#define TT_ADOBE_ID_CUSTOM 2 +#define TT_ADOBE_ID_LATIN_1 3 + + + /*************************************************************************/ + /* */ + /* Possible values of the language identifier field in the name records */ + /* of the TTF `name' table if the `platform' identifier code is */ + /* TT_PLATFORM_MACINTOSH. */ + /* */ + /* The canonical source for the Apple assigned Language ID's is at */ + /* */ + /* http://fonts.apple.com/TTRefMan/RM06/Chap6name.html */ + /* */ +#define TT_MAC_LANGID_ENGLISH 0 +#define TT_MAC_LANGID_FRENCH 1 +#define TT_MAC_LANGID_GERMAN 2 +#define TT_MAC_LANGID_ITALIAN 3 +#define TT_MAC_LANGID_DUTCH 4 +#define TT_MAC_LANGID_SWEDISH 5 +#define TT_MAC_LANGID_SPANISH 6 +#define TT_MAC_LANGID_DANISH 7 +#define TT_MAC_LANGID_PORTUGUESE 8 +#define TT_MAC_LANGID_NORWEGIAN 9 +#define TT_MAC_LANGID_HEBREW 10 +#define TT_MAC_LANGID_JAPANESE 11 +#define TT_MAC_LANGID_ARABIC 12 +#define TT_MAC_LANGID_FINNISH 13 +#define TT_MAC_LANGID_GREEK 14 +#define TT_MAC_LANGID_ICELANDIC 15 +#define TT_MAC_LANGID_MALTESE 16 +#define TT_MAC_LANGID_TURKISH 17 +#define TT_MAC_LANGID_CROATIAN 18 +#define TT_MAC_LANGID_CHINESE_TRADITIONAL 19 +#define TT_MAC_LANGID_URDU 20 +#define TT_MAC_LANGID_HINDI 21 +#define TT_MAC_LANGID_THAI 22 +#define TT_MAC_LANGID_KOREAN 23 +#define TT_MAC_LANGID_LITHUANIAN 24 +#define TT_MAC_LANGID_POLISH 25 +#define TT_MAC_LANGID_HUNGARIAN 26 +#define TT_MAC_LANGID_ESTONIAN 27 +#define TT_MAC_LANGID_LETTISH 28 +#define TT_MAC_LANGID_SAAMISK 29 +#define TT_MAC_LANGID_FAEROESE 30 +#define TT_MAC_LANGID_FARSI 31 +#define TT_MAC_LANGID_RUSSIAN 32 +#define TT_MAC_LANGID_CHINESE_SIMPLIFIED 33 +#define TT_MAC_LANGID_FLEMISH 34 +#define TT_MAC_LANGID_IRISH 35 +#define TT_MAC_LANGID_ALBANIAN 36 +#define TT_MAC_LANGID_ROMANIAN 37 +#define TT_MAC_LANGID_CZECH 38 +#define TT_MAC_LANGID_SLOVAK 39 +#define TT_MAC_LANGID_SLOVENIAN 40 +#define TT_MAC_LANGID_YIDDISH 41 +#define TT_MAC_LANGID_SERBIAN 42 +#define TT_MAC_LANGID_MACEDONIAN 43 +#define TT_MAC_LANGID_BULGARIAN 44 +#define TT_MAC_LANGID_UKRAINIAN 45 +#define TT_MAC_LANGID_BYELORUSSIAN 46 +#define TT_MAC_LANGID_UZBEK 47 +#define TT_MAC_LANGID_KAZAKH 48 +#define TT_MAC_LANGID_AZERBAIJANI 49 +#define TT_MAC_LANGID_AZERBAIJANI_CYRILLIC_SCRIPT 49 +#define TT_MAC_LANGID_AZERBAIJANI_ARABIC_SCRIPT 50 +#define TT_MAC_LANGID_ARMENIAN 51 +#define TT_MAC_LANGID_GEORGIAN 52 +#define TT_MAC_LANGID_MOLDAVIAN 53 +#define TT_MAC_LANGID_KIRGHIZ 54 +#define TT_MAC_LANGID_TAJIKI 55 +#define TT_MAC_LANGID_TURKMEN 56 +#define TT_MAC_LANGID_MONGOLIAN 57 +#define TT_MAC_LANGID_MONGOLIAN_MONGOLIAN_SCRIPT 57 +#define TT_MAC_LANGID_MONGOLIAN_CYRILLIC_SCRIPT 58 +#define TT_MAC_LANGID_PASHTO 59 +#define TT_MAC_LANGID_KURDISH 60 +#define TT_MAC_LANGID_KASHMIRI 61 +#define TT_MAC_LANGID_SINDHI 62 +#define TT_MAC_LANGID_TIBETAN 63 +#define TT_MAC_LANGID_NEPALI 64 +#define TT_MAC_LANGID_SANSKRIT 65 +#define TT_MAC_LANGID_MARATHI 66 +#define TT_MAC_LANGID_BENGALI 67 +#define TT_MAC_LANGID_ASSAMESE 68 +#define TT_MAC_LANGID_GUJARATI 69 +#define TT_MAC_LANGID_PUNJABI 70 +#define TT_MAC_LANGID_ORIYA 71 +#define TT_MAC_LANGID_MALAYALAM 72 +#define TT_MAC_LANGID_KANNADA 73 +#define TT_MAC_LANGID_TAMIL 74 +#define TT_MAC_LANGID_TELUGU 75 +#define TT_MAC_LANGID_SINHALESE 76 +#define TT_MAC_LANGID_BURMESE 77 +#define TT_MAC_LANGID_KHMER 78 +#define TT_MAC_LANGID_LAO 79 +#define TT_MAC_LANGID_VIETNAMESE 80 +#define TT_MAC_LANGID_INDONESIAN 81 +#define TT_MAC_LANGID_TAGALOG 82 +#define TT_MAC_LANGID_MALAY_ROMAN_SCRIPT 83 +#define TT_MAC_LANGID_MALAY_ARABIC_SCRIPT 84 +#define TT_MAC_LANGID_AMHARIC 85 +#define TT_MAC_LANGID_TIGRINYA 86 +#define TT_MAC_LANGID_GALLA 87 +#define TT_MAC_LANGID_SOMALI 88 +#define TT_MAC_LANGID_SWAHILI 89 +#define TT_MAC_LANGID_RUANDA 90 +#define TT_MAC_LANGID_RUNDI 91 +#define TT_MAC_LANGID_CHEWA 92 +#define TT_MAC_LANGID_MALAGASY 93 +#define TT_MAC_LANGID_ESPERANTO 94 +#define TT_MAC_LANGID_WELSH 128 +#define TT_MAC_LANGID_BASQUE 129 +#define TT_MAC_LANGID_CATALAN 130 +#define TT_MAC_LANGID_LATIN 131 +#define TT_MAC_LANGID_QUECHUA 132 +#define TT_MAC_LANGID_GUARANI 133 +#define TT_MAC_LANGID_AYMARA 134 +#define TT_MAC_LANGID_TATAR 135 +#define TT_MAC_LANGID_UIGHUR 136 +#define TT_MAC_LANGID_DZONGKHA 137 +#define TT_MAC_LANGID_JAVANESE 138 +#define TT_MAC_LANGID_SUNDANESE 139 + + +#if 0 /* these seem to be errors that have been dropped */ + +#define TT_MAC_LANGID_SCOTTISH_GAELIC 140 +#define TT_MAC_LANGID_IRISH_GAELIC 141 + +#endif + + + /* The following codes are new as of 2000-03-10 */ +#define TT_MAC_LANGID_GALICIAN 140 +#define TT_MAC_LANGID_AFRIKAANS 141 +#define TT_MAC_LANGID_BRETON 142 +#define TT_MAC_LANGID_INUKTITUT 143 +#define TT_MAC_LANGID_SCOTTISH_GAELIC 144 +#define TT_MAC_LANGID_MANX_GAELIC 145 +#define TT_MAC_LANGID_IRISH_GAELIC 146 +#define TT_MAC_LANGID_TONGAN 147 +#define TT_MAC_LANGID_GREEK_POLYTONIC 148 +#define TT_MAC_LANGID_GREELANDIC 149 +#define TT_MAC_LANGID_AZERBAIJANI_ROMAN_SCRIPT 150 + + + /*************************************************************************/ + /* */ + /* Possible values of the language identifier field in the name records */ + /* of the TTF `name' table if the `platform' identifier code is */ + /* TT_PLATFORM_MICROSOFT. */ + /* */ + /* The canonical source for the MS assigned LCID's (seems to) be at */ + /* */ + /* http://www.microsoft.com/globaldev/reference/lcid-all.mspx */ + /* */ + /* It used to be at various places, among them */ + /* */ + /* http://www.microsoft.com/typography/OTSPEC/lcid-cp.txt */ + /* http://www.microsoft.com/globaldev/reference/loclanghome.asp */ + /* http://support.microsoft.com/support/kb/articles/Q224/8/04.ASP */ + /* http://msdn.microsoft.com/library/en-us/passport25/ */ + /* NET_Passport_VBScript_Documentation/Single_Sign_In/ */ + /* Advanced_Single_Sign_In/Localization_and_LCIDs.asp */ + /* */ + /* Hopefully, it seems now that the Globaldev site prevails... */ + /* (updated by Antoine, 2004-02-17) */ + +#define TT_MS_LANGID_ARABIC_GENERAL 0x0001 +#define TT_MS_LANGID_ARABIC_SAUDI_ARABIA 0x0401 +#define TT_MS_LANGID_ARABIC_IRAQ 0x0801 +#define TT_MS_LANGID_ARABIC_EGYPT 0x0c01 +#define TT_MS_LANGID_ARABIC_LIBYA 0x1001 +#define TT_MS_LANGID_ARABIC_ALGERIA 0x1401 +#define TT_MS_LANGID_ARABIC_MOROCCO 0x1801 +#define TT_MS_LANGID_ARABIC_TUNISIA 0x1c01 +#define TT_MS_LANGID_ARABIC_OMAN 0x2001 +#define TT_MS_LANGID_ARABIC_YEMEN 0x2401 +#define TT_MS_LANGID_ARABIC_SYRIA 0x2801 +#define TT_MS_LANGID_ARABIC_JORDAN 0x2c01 +#define TT_MS_LANGID_ARABIC_LEBANON 0x3001 +#define TT_MS_LANGID_ARABIC_KUWAIT 0x3401 +#define TT_MS_LANGID_ARABIC_UAE 0x3801 +#define TT_MS_LANGID_ARABIC_BAHRAIN 0x3c01 +#define TT_MS_LANGID_ARABIC_QATAR 0x4001 +#define TT_MS_LANGID_BULGARIAN_BULGARIA 0x0402 +#define TT_MS_LANGID_CATALAN_SPAIN 0x0403 +#define TT_MS_LANGID_CHINESE_GENERAL 0x0004 +#define TT_MS_LANGID_CHINESE_TAIWAN 0x0404 +#define TT_MS_LANGID_CHINESE_PRC 0x0804 +#define TT_MS_LANGID_CHINESE_HONG_KONG 0x0c04 +#define TT_MS_LANGID_CHINESE_SINGAPORE 0x1004 + +#if 1 /* this looks like the correct value */ +#define TT_MS_LANGID_CHINESE_MACAU 0x1404 +#else /* but beware, Microsoft may change its mind... + the most recent Word reference has the following: */ +#define TT_MS_LANGID_CHINESE_MACAU TT_MS_LANGID_CHINESE_HONG_KONG +#endif + +#if 0 /* used only with .NET `cultures'; commented out */ +#define TT_MS_LANGID_CHINESE_TRADITIONAL 0x7C04 +#endif + +#define TT_MS_LANGID_CZECH_CZECH_REPUBLIC 0x0405 +#define TT_MS_LANGID_DANISH_DENMARK 0x0406 +#define TT_MS_LANGID_GERMAN_GERMANY 0x0407 +#define TT_MS_LANGID_GERMAN_SWITZERLAND 0x0807 +#define TT_MS_LANGID_GERMAN_AUSTRIA 0x0c07 +#define TT_MS_LANGID_GERMAN_LUXEMBOURG 0x1007 +#define TT_MS_LANGID_GERMAN_LIECHTENSTEI 0x1407 +#define TT_MS_LANGID_GREEK_GREECE 0x0408 + + /* don't ask what this one means... It is commented out currently. */ +#if 0 +#define TT_MS_LANGID_GREEK_GREECE2 0x2008 +#endif + +#define TT_MS_LANGID_ENGLISH_GENERAL 0x0009 +#define TT_MS_LANGID_ENGLISH_UNITED_STATES 0x0409 +#define TT_MS_LANGID_ENGLISH_UNITED_KINGDOM 0x0809 +#define TT_MS_LANGID_ENGLISH_AUSTRALIA 0x0c09 +#define TT_MS_LANGID_ENGLISH_CANADA 0x1009 +#define TT_MS_LANGID_ENGLISH_NEW_ZEALAND 0x1409 +#define TT_MS_LANGID_ENGLISH_IRELAND 0x1809 +#define TT_MS_LANGID_ENGLISH_SOUTH_AFRICA 0x1c09 +#define TT_MS_LANGID_ENGLISH_JAMAICA 0x2009 +#define TT_MS_LANGID_ENGLISH_CARIBBEAN 0x2409 +#define TT_MS_LANGID_ENGLISH_BELIZE 0x2809 +#define TT_MS_LANGID_ENGLISH_TRINIDAD 0x2c09 +#define TT_MS_LANGID_ENGLISH_ZIMBABWE 0x3009 +#define TT_MS_LANGID_ENGLISH_PHILIPPINES 0x3409 +#define TT_MS_LANGID_ENGLISH_INDONESIA 0x3809 +#define TT_MS_LANGID_ENGLISH_HONG_KONG 0x3c09 +#define TT_MS_LANGID_ENGLISH_INDIA 0x4009 +#define TT_MS_LANGID_ENGLISH_MALAYSIA 0x4409 +#define TT_MS_LANGID_ENGLISH_SINGAPORE 0x4809 +#define TT_MS_LANGID_SPANISH_SPAIN_TRADITIONAL_SORT 0x040a +#define TT_MS_LANGID_SPANISH_MEXICO 0x080a +#define TT_MS_LANGID_SPANISH_SPAIN_INTERNATIONAL_SORT 0x0c0a +#define TT_MS_LANGID_SPANISH_GUATEMALA 0x100a +#define TT_MS_LANGID_SPANISH_COSTA_RICA 0x140a +#define TT_MS_LANGID_SPANISH_PANAMA 0x180a +#define TT_MS_LANGID_SPANISH_DOMINICAN_REPUBLIC 0x1c0a +#define TT_MS_LANGID_SPANISH_VENEZUELA 0x200a +#define TT_MS_LANGID_SPANISH_COLOMBIA 0x240a +#define TT_MS_LANGID_SPANISH_PERU 0x280a +#define TT_MS_LANGID_SPANISH_ARGENTINA 0x2c0a +#define TT_MS_LANGID_SPANISH_ECUADOR 0x300a +#define TT_MS_LANGID_SPANISH_CHILE 0x340a +#define TT_MS_LANGID_SPANISH_URUGUAY 0x380a +#define TT_MS_LANGID_SPANISH_PARAGUAY 0x3c0a +#define TT_MS_LANGID_SPANISH_BOLIVIA 0x400a +#define TT_MS_LANGID_SPANISH_EL_SALVADOR 0x440a +#define TT_MS_LANGID_SPANISH_HONDURAS 0x480a +#define TT_MS_LANGID_SPANISH_NICARAGUA 0x4c0a +#define TT_MS_LANGID_SPANISH_PUERTO_RICO 0x500a +#define TT_MS_LANGID_SPANISH_UNITED_STATES 0x540a + /* The following ID blatantly violate MS specs by using a */ + /* sublanguage > 0x1F. */ +#define TT_MS_LANGID_SPANISH_LATIN_AMERICA 0xE40aU +#define TT_MS_LANGID_FINNISH_FINLAND 0x040b +#define TT_MS_LANGID_FRENCH_FRANCE 0x040c +#define TT_MS_LANGID_FRENCH_BELGIUM 0x080c +#define TT_MS_LANGID_FRENCH_CANADA 0x0c0c +#define TT_MS_LANGID_FRENCH_SWITZERLAND 0x100c +#define TT_MS_LANGID_FRENCH_LUXEMBOURG 0x140c +#define TT_MS_LANGID_FRENCH_MONACO 0x180c +#define TT_MS_LANGID_FRENCH_WEST_INDIES 0x1c0c +#define TT_MS_LANGID_FRENCH_REUNION 0x200c +#define TT_MS_LANGID_FRENCH_CONGO 0x240c + /* which was formerly: */ +#define TT_MS_LANGID_FRENCH_ZAIRE TT_MS_LANGID_FRENCH_CONGO +#define TT_MS_LANGID_FRENCH_SENEGAL 0x280c +#define TT_MS_LANGID_FRENCH_CAMEROON 0x2c0c +#define TT_MS_LANGID_FRENCH_COTE_D_IVOIRE 0x300c +#define TT_MS_LANGID_FRENCH_MALI 0x340c +#define TT_MS_LANGID_FRENCH_MOROCCO 0x380c +#define TT_MS_LANGID_FRENCH_HAITI 0x3c0c + /* and another violation of the spec (see 0xE40aU) */ +#define TT_MS_LANGID_FRENCH_NORTH_AFRICA 0xE40cU +#define TT_MS_LANGID_HEBREW_ISRAEL 0x040d +#define TT_MS_LANGID_HUNGARIAN_HUNGARY 0x040e +#define TT_MS_LANGID_ICELANDIC_ICELAND 0x040f +#define TT_MS_LANGID_ITALIAN_ITALY 0x0410 +#define TT_MS_LANGID_ITALIAN_SWITZERLAND 0x0810 +#define TT_MS_LANGID_JAPANESE_JAPAN 0x0411 +#define TT_MS_LANGID_KOREAN_EXTENDED_WANSUNG_KOREA 0x0412 +#define TT_MS_LANGID_KOREAN_JOHAB_KOREA 0x0812 +#define TT_MS_LANGID_DUTCH_NETHERLANDS 0x0413 +#define TT_MS_LANGID_DUTCH_BELGIUM 0x0813 +#define TT_MS_LANGID_NORWEGIAN_NORWAY_BOKMAL 0x0414 +#define TT_MS_LANGID_NORWEGIAN_NORWAY_NYNORSK 0x0814 +#define TT_MS_LANGID_POLISH_POLAND 0x0415 +#define TT_MS_LANGID_PORTUGUESE_BRAZIL 0x0416 +#define TT_MS_LANGID_PORTUGUESE_PORTUGAL 0x0816 +#define TT_MS_LANGID_RHAETO_ROMANIC_SWITZERLAND 0x0417 +#define TT_MS_LANGID_ROMANIAN_ROMANIA 0x0418 +#define TT_MS_LANGID_MOLDAVIAN_MOLDAVIA 0x0818 +#define TT_MS_LANGID_RUSSIAN_RUSSIA 0x0419 +#define TT_MS_LANGID_RUSSIAN_MOLDAVIA 0x0819 +#define TT_MS_LANGID_CROATIAN_CROATIA 0x041a +#define TT_MS_LANGID_SERBIAN_SERBIA_LATIN 0x081a +#define TT_MS_LANGID_SERBIAN_SERBIA_CYRILLIC 0x0c1a + +#if 0 /* this used to be this value, but it looks like we were wrong */ +#define TT_MS_LANGID_BOSNIAN_BOSNIA_HERZEGOVINA 0x101a +#else /* current sources say */ +#define TT_MS_LANGID_CROATIAN_BOSNIA_HERZEGOVINA 0x101a +#define TT_MS_LANGID_BOSNIAN_BOSNIA_HERZEGOVINA 0x141a + /* and XPsp2 Platform SDK added (2004-07-26) */ + /* Names are shortened to be significant within 40 chars. */ +#define TT_MS_LANGID_SERBIAN_BOSNIA_HERZ_LATIN 0x181a +#define TT_MS_LANGID_SERBIAN_BOSNIA_HERZ_CYRILLIC 0x181a +#endif + +#define TT_MS_LANGID_SLOVAK_SLOVAKIA 0x041b +#define TT_MS_LANGID_ALBANIAN_ALBANIA 0x041c +#define TT_MS_LANGID_SWEDISH_SWEDEN 0x041d +#define TT_MS_LANGID_SWEDISH_FINLAND 0x081d +#define TT_MS_LANGID_THAI_THAILAND 0x041e +#define TT_MS_LANGID_TURKISH_TURKEY 0x041f +#define TT_MS_LANGID_URDU_PAKISTAN 0x0420 +#define TT_MS_LANGID_URDU_INDIA 0x0820 +#define TT_MS_LANGID_INDONESIAN_INDONESIA 0x0421 +#define TT_MS_LANGID_UKRAINIAN_UKRAINE 0x0422 +#define TT_MS_LANGID_BELARUSIAN_BELARUS 0x0423 +#define TT_MS_LANGID_SLOVENE_SLOVENIA 0x0424 +#define TT_MS_LANGID_ESTONIAN_ESTONIA 0x0425 +#define TT_MS_LANGID_LATVIAN_LATVIA 0x0426 +#define TT_MS_LANGID_LITHUANIAN_LITHUANIA 0x0427 +#define TT_MS_LANGID_CLASSIC_LITHUANIAN_LITHUANIA 0x0827 +#define TT_MS_LANGID_TAJIK_TAJIKISTAN 0x0428 +#define TT_MS_LANGID_FARSI_IRAN 0x0429 +#define TT_MS_LANGID_VIETNAMESE_VIET_NAM 0x042a +#define TT_MS_LANGID_ARMENIAN_ARMENIA 0x042b +#define TT_MS_LANGID_AZERI_AZERBAIJAN_LATIN 0x042c +#define TT_MS_LANGID_AZERI_AZERBAIJAN_CYRILLIC 0x082c +#define TT_MS_LANGID_BASQUE_SPAIN 0x042d +#define TT_MS_LANGID_SORBIAN_GERMANY 0x042e +#define TT_MS_LANGID_MACEDONIAN_MACEDONIA 0x042f +#define TT_MS_LANGID_SUTU_SOUTH_AFRICA 0x0430 +#define TT_MS_LANGID_TSONGA_SOUTH_AFRICA 0x0431 +#define TT_MS_LANGID_TSWANA_SOUTH_AFRICA 0x0432 +#define TT_MS_LANGID_VENDA_SOUTH_AFRICA 0x0433 +#define TT_MS_LANGID_XHOSA_SOUTH_AFRICA 0x0434 +#define TT_MS_LANGID_ZULU_SOUTH_AFRICA 0x0435 +#define TT_MS_LANGID_AFRIKAANS_SOUTH_AFRICA 0x0436 +#define TT_MS_LANGID_GEORGIAN_GEORGIA 0x0437 +#define TT_MS_LANGID_FAEROESE_FAEROE_ISLANDS 0x0438 +#define TT_MS_LANGID_HINDI_INDIA 0x0439 +#define TT_MS_LANGID_MALTESE_MALTA 0x043a + /* Added by XPsp2 Platform SDK (2004-07-26) */ +#define TT_MS_LANGID_SAMI_NORTHERN_NORWAY 0x043b +#define TT_MS_LANGID_SAMI_NORTHERN_SWEDEN 0x083b +#define TT_MS_LANGID_SAMI_NORTHERN_FINLAND 0x0C3b +#define TT_MS_LANGID_SAMI_LULE_NORWAY 0x103b +#define TT_MS_LANGID_SAMI_LULE_SWEDEN 0x143b +#define TT_MS_LANGID_SAMI_SOUTHERN_NORWAY 0x183b +#define TT_MS_LANGID_SAMI_SOUTHERN_SWEDEN 0x1C3b +#define TT_MS_LANGID_SAMI_SKOLT_FINLAND 0x203b +#define TT_MS_LANGID_SAMI_INARI_FINLAND 0x243b + /* ... and we also keep our old identifier... */ +#define TT_MS_LANGID_SAAMI_LAPONIA 0x043b + +#if 0 /* this seems to be a previous inversion */ +#define TT_MS_LANGID_IRISH_GAELIC_IRELAND 0x043c +#define TT_MS_LANGID_SCOTTISH_GAELIC_UNITED_KINGDOM 0x083c +#else +#define TT_MS_LANGID_SCOTTISH_GAELIC_UNITED_KINGDOM 0x083c +#define TT_MS_LANGID_IRISH_GAELIC_IRELAND 0x043c +#endif + +#define TT_MS_LANGID_YIDDISH_GERMANY 0x043d +#define TT_MS_LANGID_MALAY_MALAYSIA 0x043e +#define TT_MS_LANGID_MALAY_BRUNEI_DARUSSALAM 0x083e +#define TT_MS_LANGID_KAZAK_KAZAKSTAN 0x043f +#define TT_MS_LANGID_KIRGHIZ_KIRGHIZSTAN /* Cyrillic*/ 0x0440 + /* alias declared in Windows 2000 */ +#define TT_MS_LANGID_KIRGHIZ_KIRGHIZ_REPUBLIC \ + TT_MS_LANGID_KIRGHIZ_KIRGHIZSTAN + +#define TT_MS_LANGID_SWAHILI_KENYA 0x0441 +#define TT_MS_LANGID_TURKMEN_TURKMENISTAN 0x0442 +#define TT_MS_LANGID_UZBEK_UZBEKISTAN_LATIN 0x0443 +#define TT_MS_LANGID_UZBEK_UZBEKISTAN_CYRILLIC 0x0843 +#define TT_MS_LANGID_TATAR_TATARSTAN 0x0444 +#define TT_MS_LANGID_BENGALI_INDIA 0x0445 +#define TT_MS_LANGID_BENGALI_BANGLADESH 0x0845 +#define TT_MS_LANGID_PUNJABI_INDIA 0x0446 +#define TT_MS_LANGID_PUNJABI_ARABIC_PAKISTAN 0x0846 +#define TT_MS_LANGID_GUJARATI_INDIA 0x0447 +#define TT_MS_LANGID_ORIYA_INDIA 0x0448 +#define TT_MS_LANGID_TAMIL_INDIA 0x0449 +#define TT_MS_LANGID_TELUGU_INDIA 0x044a +#define TT_MS_LANGID_KANNADA_INDIA 0x044b +#define TT_MS_LANGID_MALAYALAM_INDIA 0x044c +#define TT_MS_LANGID_ASSAMESE_INDIA 0x044d +#define TT_MS_LANGID_MARATHI_INDIA 0x044e +#define TT_MS_LANGID_SANSKRIT_INDIA 0x044f +#define TT_MS_LANGID_MONGOLIAN_MONGOLIA /* Cyrillic */ 0x0450 +#define TT_MS_LANGID_MONGOLIAN_MONGOLIA_MONGOLIAN 0x0850 +#define TT_MS_LANGID_TIBETAN_CHINA 0x0451 + /* Don't use the next constant! It has */ + /* (1) the wrong spelling (Dzonghka) */ + /* (2) Microsoft doesn't officially define it -- */ + /* at least it is not in the List of Local */ + /* ID Values. */ + /* (3) Dzongkha is not the same language as */ + /* Tibetan, so merging it is wrong anyway. */ + /* */ + /* TT_MS_LANGID_TIBETAN_BHUTAN is correct, BTW. */ +#define TT_MS_LANGID_DZONGHKA_BHUTAN 0x0851 + +#if 0 + /* the following used to be defined */ +#define TT_MS_LANGID_TIBETAN_BHUTAN 0x0451 + /* ... but it was changed; */ +#else + /* So we will continue to #define it, but with the correct value */ +#define TT_MS_LANGID_TIBETAN_BHUTAN TT_MS_LANGID_DZONGHKA_BHUTAN +#endif + +#define TT_MS_LANGID_WELSH_WALES 0x0452 +#define TT_MS_LANGID_KHMER_CAMBODIA 0x0453 +#define TT_MS_LANGID_LAO_LAOS 0x0454 +#define TT_MS_LANGID_BURMESE_MYANMAR 0x0455 +#define TT_MS_LANGID_GALICIAN_SPAIN 0x0456 +#define TT_MS_LANGID_KONKANI_INDIA 0x0457 +#define TT_MS_LANGID_MANIPURI_INDIA /* Bengali */ 0x0458 +#define TT_MS_LANGID_SINDHI_INDIA /* Arabic */ 0x0459 +#define TT_MS_LANGID_SINDHI_PAKISTAN 0x0859 + /* Missing a LCID for Sindhi in Devanagari script */ +#define TT_MS_LANGID_SYRIAC_SYRIA 0x045a +#define TT_MS_LANGID_SINHALESE_SRI_LANKA 0x045b +#define TT_MS_LANGID_CHEROKEE_UNITED_STATES 0x045c +#define TT_MS_LANGID_INUKTITUT_CANADA 0x045d +#define TT_MS_LANGID_AMHARIC_ETHIOPIA 0x045e +#define TT_MS_LANGID_TAMAZIGHT_MOROCCO /* Arabic */ 0x045f +#define TT_MS_LANGID_TAMAZIGHT_MOROCCO_LATIN 0x085f + /* Missing a LCID for Tifinagh script */ +#define TT_MS_LANGID_KASHMIRI_PAKISTAN /* Arabic */ 0x0460 + /* Spelled this way by XPsp2 Platform SDK (2004-07-26) */ + /* script is yet unclear... might be Arabic, Nagari or Sharada */ +#define TT_MS_LANGID_KASHMIRI_SASIA 0x0860 + /* ... and aliased (by MS) for compatibility reasons. */ +#define TT_MS_LANGID_KASHMIRI_INDIA TT_MS_LANGID_KASHMIRI_SASIA +#define TT_MS_LANGID_NEPALI_NEPAL 0x0461 +#define TT_MS_LANGID_NEPALI_INDIA 0x0861 +#define TT_MS_LANGID_FRISIAN_NETHERLANDS 0x0462 +#define TT_MS_LANGID_PASHTO_AFGHANISTAN 0x0463 +#define TT_MS_LANGID_FILIPINO_PHILIPPINES 0x0464 +#define TT_MS_LANGID_DHIVEHI_MALDIVES 0x0465 + /* alias declared in Windows 2000 */ +#define TT_MS_LANGID_DIVEHI_MALDIVES TT_MS_LANGID_DHIVEHI_MALDIVES +#define TT_MS_LANGID_EDO_NIGERIA 0x0466 +#define TT_MS_LANGID_FULFULDE_NIGERIA 0x0467 +#define TT_MS_LANGID_HAUSA_NIGERIA 0x0468 +#define TT_MS_LANGID_IBIBIO_NIGERIA 0x0469 +#define TT_MS_LANGID_YORUBA_NIGERIA 0x046a +#define TT_MS_LANGID_QUECHUA_BOLIVIA 0x046b +#define TT_MS_LANGID_QUECHUA_ECUADOR 0x086b +#define TT_MS_LANGID_QUECHUA_PERU 0x0c6b +#define TT_MS_LANGID_SEPEDI_SOUTH_AFRICA 0x046c + /* Also spelled by XPsp2 Platform SDK (2004-07-26) */ +#define TT_MS_LANGID_SOTHO_SOUTHERN_SOUTH_AFRICA \ + TT_MS_LANGID_SEPEDI_SOUTH_AFRICA + /* language codes 0x046d, 0x046e and 0x046f are (still) unknown. */ +#define TT_MS_LANGID_IGBO_NIGERIA 0x0470 +#define TT_MS_LANGID_KANURI_NIGERIA 0x0471 +#define TT_MS_LANGID_OROMO_ETHIOPIA 0x0472 +#define TT_MS_LANGID_TIGRIGNA_ETHIOPIA 0x0473 +#define TT_MS_LANGID_TIGRIGNA_ERYTHREA 0x0873 + /* also spelled in the `Passport SDK' list as: */ +#define TT_MS_LANGID_TIGRIGNA_ERYTREA TT_MS_LANGID_TIGRIGNA_ERYTHREA +#define TT_MS_LANGID_GUARANI_PARAGUAY 0x0474 +#define TT_MS_LANGID_HAWAIIAN_UNITED_STATES 0x0475 +#define TT_MS_LANGID_LATIN 0x0476 +#define TT_MS_LANGID_SOMALI_SOMALIA 0x0477 + /* Note: Yi does not have a (proper) ISO 639-2 code, since it is mostly */ + /* not written (but OTOH the peculiar writing system is worth */ + /* studying). */ +#define TT_MS_LANGID_YI_CHINA 0x0478 +#define TT_MS_LANGID_PAPIAMENTU_NETHERLANDS_ANTILLES 0x0479 + /* language codes from 0x047a to 0x047f are (still) unknown. */ +#define TT_MS_LANGID_UIGHUR_CHINA 0x0480 +#define TT_MS_LANGID_MAORI_NEW_ZEALAND 0x0481 + +#if 0 /* not deemed useful for fonts */ +#define TT_MS_LANGID_HUMAN_INTERFACE_DEVICE 0x04ff +#endif + + + /*************************************************************************/ + /* */ + /* Possible values of the `name' identifier field in the name records of */ + /* the TTF `name' table. These values are platform independent. */ + /* */ +#define TT_NAME_ID_COPYRIGHT 0 +#define TT_NAME_ID_FONT_FAMILY 1 +#define TT_NAME_ID_FONT_SUBFAMILY 2 +#define TT_NAME_ID_UNIQUE_ID 3 +#define TT_NAME_ID_FULL_NAME 4 +#define TT_NAME_ID_VERSION_STRING 5 +#define TT_NAME_ID_PS_NAME 6 +#define TT_NAME_ID_TRADEMARK 7 + + /* the following values are from the OpenType spec */ +#define TT_NAME_ID_MANUFACTURER 8 +#define TT_NAME_ID_DESIGNER 9 +#define TT_NAME_ID_DESCRIPTION 10 +#define TT_NAME_ID_VENDOR_URL 11 +#define TT_NAME_ID_DESIGNER_URL 12 +#define TT_NAME_ID_LICENSE 13 +#define TT_NAME_ID_LICENSE_URL 14 + /* number 15 is reserved */ +#define TT_NAME_ID_PREFERRED_FAMILY 16 +#define TT_NAME_ID_PREFERRED_SUBFAMILY 17 +#define TT_NAME_ID_MAC_FULL_NAME 18 + + /* The following code is new as of 2000-01-21 */ +#define TT_NAME_ID_SAMPLE_TEXT 19 + + /* This is new in OpenType 1.3 */ +#define TT_NAME_ID_CID_FINDFONT_NAME 20 + + /* This is new in OpenType 1.5 */ +#define TT_NAME_ID_WWS_FAMILY 21 +#define TT_NAME_ID_WWS_SUBFAMILY 22 + + + /*************************************************************************/ + /* */ + /* Bit mask values for the Unicode Ranges from the TTF `OS2 ' table. */ + /* */ + /* Updated 08-Nov-2008. */ + /* */ + + /* Bit 0 Basic Latin */ +#define TT_UCR_BASIC_LATIN (1L << 0) /* U+0020-U+007E */ + /* Bit 1 C1 Controls and Latin-1 Supplement */ +#define TT_UCR_LATIN1_SUPPLEMENT (1L << 1) /* U+0080-U+00FF */ + /* Bit 2 Latin Extended-A */ +#define TT_UCR_LATIN_EXTENDED_A (1L << 2) /* U+0100-U+017F */ + /* Bit 3 Latin Extended-B */ +#define TT_UCR_LATIN_EXTENDED_B (1L << 3) /* U+0180-U+024F */ + /* Bit 4 IPA Extensions */ + /* Phonetic Extensions */ + /* Phonetic Extensions Supplement */ +#define TT_UCR_IPA_EXTENSIONS (1L << 4) /* U+0250-U+02AF */ + /* U+1D00-U+1D7F */ + /* U+1D80-U+1DBF */ + /* Bit 5 Spacing Modifier Letters */ + /* Modifier Tone Letters */ +#define TT_UCR_SPACING_MODIFIER (1L << 5) /* U+02B0-U+02FF */ + /* U+A700-U+A71F */ + /* Bit 6 Combining Diacritical Marks */ + /* Combining Diacritical Marks Supplement */ +#define TT_UCR_COMBINING_DIACRITICS (1L << 6) /* U+0300-U+036F */ + /* U+1DC0-U+1DFF */ + /* Bit 7 Greek and Coptic */ +#define TT_UCR_GREEK (1L << 7) /* U+0370-U+03FF */ + /* Bit 8 Coptic */ +#define TT_UCR_COPTIC (1L << 8) /* U+2C80-U+2CFF */ + /* Bit 9 Cyrillic */ + /* Cyrillic Supplement */ + /* Cyrillic Extended-A */ + /* Cyrillic Extended-B */ +#define TT_UCR_CYRILLIC (1L << 9) /* U+0400-U+04FF */ + /* U+0500-U+052F */ + /* U+2DE0-U+2DFF */ + /* U+A640-U+A69F */ + /* Bit 10 Armenian */ +#define TT_UCR_ARMENIAN (1L << 10) /* U+0530-U+058F */ + /* Bit 11 Hebrew */ +#define TT_UCR_HEBREW (1L << 11) /* U+0590-U+05FF */ + /* Bit 12 Vai */ +#define TT_UCR_VAI (1L << 12) /* U+A500-U+A63F */ + /* Bit 13 Arabic */ + /* Arabic Supplement */ +#define TT_UCR_ARABIC (1L << 13) /* U+0600-U+06FF */ + /* U+0750-U+077F */ + /* Bit 14 NKo */ +#define TT_UCR_NKO (1L << 14) /* U+07C0-U+07FF */ + /* Bit 15 Devanagari */ +#define TT_UCR_DEVANAGARI (1L << 15) /* U+0900-U+097F */ + /* Bit 16 Bengali */ +#define TT_UCR_BENGALI (1L << 16) /* U+0980-U+09FF */ + /* Bit 17 Gurmukhi */ +#define TT_UCR_GURMUKHI (1L << 17) /* U+0A00-U+0A7F */ + /* Bit 18 Gujarati */ +#define TT_UCR_GUJARATI (1L << 18) /* U+0A80-U+0AFF */ + /* Bit 19 Oriya */ +#define TT_UCR_ORIYA (1L << 19) /* U+0B00-U+0B7F */ + /* Bit 20 Tamil */ +#define TT_UCR_TAMIL (1L << 20) /* U+0B80-U+0BFF */ + /* Bit 21 Telugu */ +#define TT_UCR_TELUGU (1L << 21) /* U+0C00-U+0C7F */ + /* Bit 22 Kannada */ +#define TT_UCR_KANNADA (1L << 22) /* U+0C80-U+0CFF */ + /* Bit 23 Malayalam */ +#define TT_UCR_MALAYALAM (1L << 23) /* U+0D00-U+0D7F */ + /* Bit 24 Thai */ +#define TT_UCR_THAI (1L << 24) /* U+0E00-U+0E7F */ + /* Bit 25 Lao */ +#define TT_UCR_LAO (1L << 25) /* U+0E80-U+0EFF */ + /* Bit 26 Georgian */ + /* Georgian Supplement */ +#define TT_UCR_GEORGIAN (1L << 26) /* U+10A0-U+10FF */ + /* U+2D00-U+2D2F */ + /* Bit 27 Balinese */ +#define TT_UCR_BALINESE (1L << 27) /* U+1B00-U+1B7F */ + /* Bit 28 Hangul Jamo */ +#define TT_UCR_HANGUL_JAMO (1L << 28) /* U+1100-U+11FF */ + /* Bit 29 Latin Extended Additional */ + /* Latin Extended-C */ + /* Latin Extended-D */ +#define TT_UCR_LATIN_EXTENDED_ADDITIONAL (1L << 29) /* U+1E00-U+1EFF */ + /* U+2C60-U+2C7F */ + /* U+A720-U+A7FF */ + /* Bit 30 Greek Extended */ +#define TT_UCR_GREEK_EXTENDED (1L << 30) /* U+1F00-U+1FFF */ + /* Bit 31 General Punctuation */ + /* Supplemental Punctuation */ +#define TT_UCR_GENERAL_PUNCTUATION (1L << 31) /* U+2000-U+206F */ + /* U+2E00-U+2E7F */ + /* Bit 32 Superscripts And Subscripts */ +#define TT_UCR_SUPERSCRIPTS_SUBSCRIPTS (1L << 0) /* U+2070-U+209F */ + /* Bit 33 Currency Symbols */ +#define TT_UCR_CURRENCY_SYMBOLS (1L << 1) /* U+20A0-U+20CF */ + /* Bit 34 Combining Diacritical Marks For Symbols */ +#define TT_UCR_COMBINING_DIACRITICS_SYMB (1L << 2) /* U+20D0-U+20FF */ + /* Bit 35 Letterlike Symbols */ +#define TT_UCR_LETTERLIKE_SYMBOLS (1L << 3) /* U+2100-U+214F */ + /* Bit 36 Number Forms */ +#define TT_UCR_NUMBER_FORMS (1L << 4) /* U+2150-U+218F */ + /* Bit 37 Arrows */ + /* Supplemental Arrows-A */ + /* Supplemental Arrows-B */ + /* Miscellaneous Symbols and Arrows */ +#define TT_UCR_ARROWS (1L << 5) /* U+2190-U+21FF */ + /* U+27F0-U+27FF */ + /* U+2900-U+297F */ + /* U+2B00-U+2BFF */ + /* Bit 38 Mathematical Operators */ + /* Supplemental Mathematical Operators */ + /* Miscellaneous Mathematical Symbols-A */ + /* Miscellaneous Mathematical Symbols-B */ +#define TT_UCR_MATHEMATICAL_OPERATORS (1L << 6) /* U+2200-U+22FF */ + /* U+2A00-U+2AFF */ + /* U+27C0-U+27EF */ + /* U+2980-U+29FF */ + /* Bit 39 Miscellaneous Technical */ +#define TT_UCR_MISCELLANEOUS_TECHNICAL (1L << 7) /* U+2300-U+23FF */ + /* Bit 40 Control Pictures */ +#define TT_UCR_CONTROL_PICTURES (1L << 8) /* U+2400-U+243F */ + /* Bit 41 Optical Character Recognition */ +#define TT_UCR_OCR (1L << 9) /* U+2440-U+245F */ + /* Bit 42 Enclosed Alphanumerics */ +#define TT_UCR_ENCLOSED_ALPHANUMERICS (1L << 10) /* U+2460-U+24FF */ + /* Bit 43 Box Drawing */ +#define TT_UCR_BOX_DRAWING (1L << 11) /* U+2500-U+257F */ + /* Bit 44 Block Elements */ +#define TT_UCR_BLOCK_ELEMENTS (1L << 12) /* U+2580-U+259F */ + /* Bit 45 Geometric Shapes */ +#define TT_UCR_GEOMETRIC_SHAPES (1L << 13) /* U+25A0-U+25FF */ + /* Bit 46 Miscellaneous Symbols */ +#define TT_UCR_MISCELLANEOUS_SYMBOLS (1L << 14) /* U+2600-U+26FF */ + /* Bit 47 Dingbats */ +#define TT_UCR_DINGBATS (1L << 15) /* U+2700-U+27BF */ + /* Bit 48 CJK Symbols and Punctuation */ +#define TT_UCR_CJK_SYMBOLS (1L << 16) /* U+3000-U+303F */ + /* Bit 49 Hiragana */ +#define TT_UCR_HIRAGANA (1L << 17) /* U+3040-U+309F */ + /* Bit 50 Katakana */ + /* Katakana Phonetic Extensions */ +#define TT_UCR_KATAKANA (1L << 18) /* U+30A0-U+30FF */ + /* U+31F0-U+31FF */ + /* Bit 51 Bopomofo */ + /* Bopomofo Extended */ +#define TT_UCR_BOPOMOFO (1L << 19) /* U+3100-U+312F */ + /* U+31A0-U+31BF */ + /* Bit 52 Hangul Compatibility Jamo */ +#define TT_UCR_HANGUL_COMPATIBILITY_JAMO (1L << 20) /* U+3130-U+318F */ + /* Bit 53 Phags-Pa */ +#define TT_UCR_CJK_MISC (1L << 21) /* U+A840-U+A87F */ +#define TT_UCR_KANBUN TT_UCR_CJK_MISC /* deprecated */ +#define TT_UCR_PHAGSPA + /* Bit 54 Enclosed CJK Letters and Months */ +#define TT_UCR_ENCLOSED_CJK_LETTERS_MONTHS (1L << 22) /* U+3200-U+32FF */ + /* Bit 55 CJK Compatibility */ +#define TT_UCR_CJK_COMPATIBILITY (1L << 23) /* U+3300-U+33FF */ + /* Bit 56 Hangul Syllables */ +#define TT_UCR_HANGUL (1L << 24) /* U+AC00-U+D7A3 */ + /* Bit 57 High Surrogates */ + /* High Private Use Surrogates */ + /* Low Surrogates */ + /* */ + /* According to OpenType specs v.1.3+, */ + /* setting bit 57 implies that there is */ + /* at least one codepoint beyond the */ + /* Basic Multilingual Plane that is */ + /* supported by this font. So it really */ + /* means >= U+10000 */ +#define TT_UCR_SURROGATES (1L << 25) /* U+D800-U+DB7F */ + /* U+DB80-U+DBFF */ + /* U+DC00-U+DFFF */ +#define TT_UCR_NON_PLANE_0 TT_UCR_SURROGATES + /* Bit 58 Phoenician */ +#define TT_UCR_PHOENICIAN (1L << 26) /*U+10900-U+1091F*/ + /* Bit 59 CJK Unified Ideographs */ + /* CJK Radicals Supplement */ + /* Kangxi Radicals */ + /* Ideographic Description Characters */ + /* CJK Unified Ideographs Extension A */ + /* CJK Unified Ideographs Extension B */ + /* Kanbun */ +#define TT_UCR_CJK_UNIFIED_IDEOGRAPHS (1L << 27) /* U+4E00-U+9FFF */ + /* U+2E80-U+2EFF */ + /* U+2F00-U+2FDF */ + /* U+2FF0-U+2FFF */ + /* U+3400-U+4DB5 */ + /*U+20000-U+2A6DF*/ + /* U+3190-U+319F */ + /* Bit 60 Private Use */ +#define TT_UCR_PRIVATE_USE (1L << 28) /* U+E000-U+F8FF */ + /* Bit 61 CJK Strokes */ + /* CJK Compatibility Ideographs */ + /* CJK Compatibility Ideographs Supplement */ +#define TT_UCR_CJK_COMPATIBILITY_IDEOGRAPHS (1L << 29) /* U+31C0-U+31EF */ + /* U+F900-U+FAFF */ + /*U+2F800-U+2FA1F*/ + /* Bit 62 Alphabetic Presentation Forms */ +#define TT_UCR_ALPHABETIC_PRESENTATION_FORMS (1L << 30) /* U+FB00-U+FB4F */ + /* Bit 63 Arabic Presentation Forms-A */ +#define TT_UCR_ARABIC_PRESENTATIONS_A (1L << 31) /* U+FB50-U+FDFF */ + /* Bit 64 Combining Half Marks */ +#define TT_UCR_COMBINING_HALF_MARKS (1L << 0) /* U+FE20-U+FE2F */ + /* Bit 65 Vertical forms */ + /* CJK Compatibility Forms */ +#define TT_UCR_CJK_COMPATIBILITY_FORMS (1L << 1) /* U+FE10-U+FE1F */ + /* U+FE30-U+FE4F */ + /* Bit 66 Small Form Variants */ +#define TT_UCR_SMALL_FORM_VARIANTS (1L << 2) /* U+FE50-U+FE6F */ + /* Bit 67 Arabic Presentation Forms-B */ +#define TT_UCR_ARABIC_PRESENTATIONS_B (1L << 3) /* U+FE70-U+FEFE */ + /* Bit 68 Halfwidth and Fullwidth Forms */ +#define TT_UCR_HALFWIDTH_FULLWIDTH_FORMS (1L << 4) /* U+FF00-U+FFEF */ + /* Bit 69 Specials */ +#define TT_UCR_SPECIALS (1L << 5) /* U+FFF0-U+FFFD */ + /* Bit 70 Tibetan */ +#define TT_UCR_TIBETAN (1L << 6) /* U+0F00-U+0FFF */ + /* Bit 71 Syriac */ +#define TT_UCR_SYRIAC (1L << 7) /* U+0700-U+074F */ + /* Bit 72 Thaana */ +#define TT_UCR_THAANA (1L << 8) /* U+0780-U+07BF */ + /* Bit 73 Sinhala */ +#define TT_UCR_SINHALA (1L << 9) /* U+0D80-U+0DFF */ + /* Bit 74 Myanmar */ +#define TT_UCR_MYANMAR (1L << 10) /* U+1000-U+109F */ + /* Bit 75 Ethiopic */ + /* Ethiopic Supplement */ + /* Ethiopic Extended */ +#define TT_UCR_ETHIOPIC (1L << 11) /* U+1200-U+137F */ + /* U+1380-U+139F */ + /* U+2D80-U+2DDF */ + /* Bit 76 Cherokee */ +#define TT_UCR_CHEROKEE (1L << 12) /* U+13A0-U+13FF */ + /* Bit 77 Unified Canadian Aboriginal Syllabics */ +#define TT_UCR_CANADIAN_ABORIGINAL_SYLLABICS (1L << 13) /* U+1400-U+167F */ + /* Bit 78 Ogham */ +#define TT_UCR_OGHAM (1L << 14) /* U+1680-U+169F */ + /* Bit 79 Runic */ +#define TT_UCR_RUNIC (1L << 15) /* U+16A0-U+16FF */ + /* Bit 80 Khmer */ + /* Khmer Symbols */ +#define TT_UCR_KHMER (1L << 16) /* U+1780-U+17FF */ + /* U+19E0-U+19FF */ + /* Bit 81 Mongolian */ +#define TT_UCR_MONGOLIAN (1L << 17) /* U+1800-U+18AF */ + /* Bit 82 Braille Patterns */ +#define TT_UCR_BRAILLE (1L << 18) /* U+2800-U+28FF */ + /* Bit 83 Yi Syllables */ + /* Yi Radicals */ +#define TT_UCR_YI (1L << 19) /* U+A000-U+A48F */ + /* U+A490-U+A4CF */ + /* Bit 84 Tagalog */ + /* Hanunoo */ + /* Buhid */ + /* Tagbanwa */ +#define TT_UCR_PHILIPPINE (1L << 20) /* U+1700-U+171F */ + /* U+1720-U+173F */ + /* U+1740-U+175F */ + /* U+1760-U+177F */ + /* Bit 85 Old Italic */ +#define TT_UCR_OLD_ITALIC (1L << 21) /*U+10300-U+1032F*/ + /* Bit 86 Gothic */ +#define TT_UCR_GOTHIC (1L << 22) /*U+10330-U+1034F*/ + /* Bit 87 Deseret */ +#define TT_UCR_DESERET (1L << 23) /*U+10400-U+1044F*/ + /* Bit 88 Byzantine Musical Symbols */ + /* Musical Symbols */ + /* Ancient Greek Musical Notation */ +#define TT_UCR_MUSICAL_SYMBOLS (1L << 24) /*U+1D000-U+1D0FF*/ + /*U+1D100-U+1D1FF*/ + /*U+1D200-U+1D24F*/ + /* Bit 89 Mathematical Alphanumeric Symbols */ +#define TT_UCR_MATH_ALPHANUMERIC_SYMBOLS (1L << 25) /*U+1D400-U+1D7FF*/ + /* Bit 90 Private Use (plane 15) */ + /* Private Use (plane 16) */ +#define TT_UCR_PRIVATE_USE_SUPPLEMENTARY (1L << 26) /*U+F0000-U+FFFFD*/ + /*U+100000-U+10FFFD*/ + /* Bit 91 Variation Selectors */ + /* Variation Selectors Supplement */ +#define TT_UCR_VARIATION_SELECTORS (1L << 27) /* U+FE00-U+FE0F */ + /*U+E0100-U+E01EF*/ + /* Bit 92 Tags */ +#define TT_UCR_TAGS (1L << 28) /*U+E0000-U+E007F*/ + /* Bit 93 Limbu */ +#define TT_UCR_LIMBU (1L << 29) /* U+1900-U+194F */ + /* Bit 94 Tai Le */ +#define TT_UCR_TAI_LE (1L << 30) /* U+1950-U+197F */ + /* Bit 95 New Tai Lue */ +#define TT_UCR_NEW_TAI_LUE (1L << 31) /* U+1980-U+19DF */ + /* Bit 96 Buginese */ +#define TT_UCR_BUGINESE (1L << 0) /* U+1A00-U+1A1F */ + /* Bit 97 Glagolitic */ +#define TT_UCR_GLAGOLITIC (1L << 1) /* U+2C00-U+2C5F */ + /* Bit 98 Tifinagh */ +#define TT_UCR_TIFINAGH (1L << 2) /* U+2D30-U+2D7F */ + /* Bit 99 Yijing Hexagram Symbols */ +#define TT_UCR_YIJING (1L << 3) /* U+4DC0-U+4DFF */ + /* Bit 100 Syloti Nagri */ +#define TT_UCR_SYLOTI_NAGRI (1L << 4) /* U+A800-U+A82F */ + /* Bit 101 Linear B Syllabary */ + /* Linear B Ideograms */ + /* Aegean Numbers */ +#define TT_UCR_LINEAR_B (1L << 5) /*U+10000-U+1007F*/ + /*U+10080-U+100FF*/ + /*U+10100-U+1013F*/ + /* Bit 102 Ancient Greek Numbers */ +#define TT_UCR_ANCIENT_GREEK_NUMBERS (1L << 6) /*U+10140-U+1018F*/ + /* Bit 103 Ugaritic */ +#define TT_UCR_UGARITIC (1L << 7) /*U+10380-U+1039F*/ + /* Bit 104 Old Persian */ +#define TT_UCR_OLD_PERSIAN (1L << 8) /*U+103A0-U+103DF*/ + /* Bit 105 Shavian */ +#define TT_UCR_SHAVIAN (1L << 9) /*U+10450-U+1047F*/ + /* Bit 106 Osmanya */ +#define TT_UCR_OSMANYA (1L << 10) /*U+10480-U+104AF*/ + /* Bit 107 Cypriot Syllabary */ +#define TT_UCR_CYPRIOT_SYLLABARY (1L << 11) /*U+10800-U+1083F*/ + /* Bit 108 Kharoshthi */ +#define TT_UCR_KHAROSHTHI (1L << 12) /*U+10A00-U+10A5F*/ + /* Bit 109 Tai Xuan Jing Symbols */ +#define TT_UCR_TAI_XUAN_JING (1L << 13) /*U+1D300-U+1D35F*/ + /* Bit 110 Cuneiform */ + /* Cuneiform Numbers and Punctuation */ +#define TT_UCR_CUNEIFORM (1L << 14) /*U+12000-U+123FF*/ + /*U+12400-U+1247F*/ + /* Bit 111 Counting Rod Numerals */ +#define TT_UCR_COUNTING_ROD_NUMERALS (1L << 15) /*U+1D360-U+1D37F*/ + /* Bit 112 Sundanese */ +#define TT_UCR_SUNDANESE (1L << 16) /* U+1B80-U+1BBF */ + /* Bit 113 Lepcha */ +#define TT_UCR_LEPCHA (1L << 17) /* U+1C00-U+1C4F */ + /* Bit 114 Ol Chiki */ +#define TT_UCR_OL_CHIKI (1L << 18) /* U+1C50-U+1C7F */ + /* Bit 115 Saurashtra */ +#define TT_UCR_SAURASHTRA (1L << 19) /* U+A880-U+A8DF */ + /* Bit 116 Kayah Li */ +#define TT_UCR_KAYAH_LI (1L << 20) /* U+A900-U+A92F */ + /* Bit 117 Rejang */ +#define TT_UCR_REJANG (1L << 21) /* U+A930-U+A95F */ + /* Bit 118 Cham */ +#define TT_UCR_CHAM (1L << 22) /* U+AA00-U+AA5F */ + /* Bit 119 Ancient Symbols */ +#define TT_UCR_ANCIENT_SYMBOLS (1L << 23) /*U+10190-U+101CF*/ + /* Bit 120 Phaistos Disc */ +#define TT_UCR_PHAISTOS_DISC (1L << 24) /*U+101D0-U+101FF*/ + /* Bit 121 Carian */ + /* Lycian */ + /* Lydian */ +#define TT_UCR_OLD_ANATOLIAN (1L << 25) /*U+102A0-U+102DF*/ + /*U+10280-U+1029F*/ + /*U+10920-U+1093F*/ + /* Bit 122 Domino Tiles */ + /* Mahjong Tiles */ +#define TT_UCR_GAME_TILES (1L << 26) /*U+1F030-U+1F09F*/ + /*U+1F000-U+1F02F*/ + /* Bit 123-127 Reserved for process-internal usage */ + + + /*************************************************************************/ + /* */ + /* Some compilers have a very limited length of identifiers. */ + /* */ +#if defined( __TURBOC__ ) && __TURBOC__ < 0x0410 || defined( __PACIFIC__ ) +#define HAVE_LIMIT_ON_IDENTS +#endif + + +#ifndef HAVE_LIMIT_ON_IDENTS + + + /*************************************************************************/ + /* */ + /* Here some alias #defines in order to be clearer. */ + /* */ + /* These are not always #defined to stay within the 31~character limit */ + /* which some compilers have. */ + /* */ + /* Credits go to Dave Hoo <dhoo@flash.net> for pointing out that modern */ + /* Borland compilers (read: from BC++ 3.1 on) can increase this limit. */ + /* If you get a warning with such a compiler, use the -i40 switch. */ + /* */ +#define TT_UCR_ARABIC_PRESENTATION_FORMS_A \ + TT_UCR_ARABIC_PRESENTATIONS_A +#define TT_UCR_ARABIC_PRESENTATION_FORMS_B \ + TT_UCR_ARABIC_PRESENTATIONS_B + +#define TT_UCR_COMBINING_DIACRITICAL_MARKS \ + TT_UCR_COMBINING_DIACRITICS +#define TT_UCR_COMBINING_DIACRITICAL_MARKS_SYMB \ + TT_UCR_COMBINING_DIACRITICS_SYMB + + +#endif /* !HAVE_LIMIT_ON_IDENTS */ + + +FT_END_HEADER + +#endif /* __TTNAMEID_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/tttables.h b/mod/pub.mod/freetype.mod/include/freetype/tttables.h new file mode 100644 index 0000000..c12b172 --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/tttables.h @@ -0,0 +1,756 @@ +/***************************************************************************/ +/* */ +/* tttables.h */ +/* */ +/* Basic SFNT/TrueType tables definitions and interface */ +/* (specification only). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __TTTABLES_H__ +#define __TTTABLES_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + /*************************************************************************/ + /* */ + /* <Section> */ + /* truetype_tables */ + /* */ + /* <Title> */ + /* TrueType Tables */ + /* */ + /* <Abstract> */ + /* TrueType specific table types and functions. */ + /* */ + /* <Description> */ + /* This section contains the definition of TrueType-specific tables */ + /* as well as some routines used to access and process them. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_Header */ + /* */ + /* <Description> */ + /* A structure used to model a TrueType font header table. All */ + /* fields follow the TrueType specification. */ + /* */ + typedef struct TT_Header_ + { + FT_Fixed Table_Version; + FT_Fixed Font_Revision; + + FT_Long CheckSum_Adjust; + FT_Long Magic_Number; + + FT_UShort Flags; + FT_UShort Units_Per_EM; + + FT_Long Created [2]; + FT_Long Modified[2]; + + FT_Short xMin; + FT_Short yMin; + FT_Short xMax; + FT_Short yMax; + + FT_UShort Mac_Style; + FT_UShort Lowest_Rec_PPEM; + + FT_Short Font_Direction; + FT_Short Index_To_Loc_Format; + FT_Short Glyph_Data_Format; + + } TT_Header; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_HoriHeader */ + /* */ + /* <Description> */ + /* A structure used to model a TrueType horizontal header, the `hhea' */ + /* table, as well as the corresponding horizontal metrics table, */ + /* i.e., the `hmtx' table. */ + /* */ + /* <Fields> */ + /* Version :: The table version. */ + /* */ + /* Ascender :: The font's ascender, i.e., the distance */ + /* from the baseline to the top-most of all */ + /* glyph points found in the font. */ + /* */ + /* This value is invalid in many fonts, as */ + /* it is usually set by the font designer, */ + /* and often reflects only a portion of the */ + /* glyphs found in the font (maybe ASCII). */ + /* */ + /* You should use the `sTypoAscender' field */ + /* of the OS/2 table instead if you want */ + /* the correct one. */ + /* */ + /* Descender :: The font's descender, i.e., the distance */ + /* from the baseline to the bottom-most of */ + /* all glyph points found in the font. It */ + /* is negative. */ + /* */ + /* This value is invalid in many fonts, as */ + /* it is usually set by the font designer, */ + /* and often reflects only a portion of the */ + /* glyphs found in the font (maybe ASCII). */ + /* */ + /* You should use the `sTypoDescender' */ + /* field of the OS/2 table instead if you */ + /* want the correct one. */ + /* */ + /* Line_Gap :: The font's line gap, i.e., the distance */ + /* to add to the ascender and descender to */ + /* get the BTB, i.e., the */ + /* baseline-to-baseline distance for the */ + /* font. */ + /* */ + /* advance_Width_Max :: This field is the maximum of all advance */ + /* widths found in the font. It can be */ + /* used to compute the maximum width of an */ + /* arbitrary string of text. */ + /* */ + /* min_Left_Side_Bearing :: The minimum left side bearing of all */ + /* glyphs within the font. */ + /* */ + /* min_Right_Side_Bearing :: The minimum right side bearing of all */ + /* glyphs within the font. */ + /* */ + /* xMax_Extent :: The maximum horizontal extent (i.e., the */ + /* `width' of a glyph's bounding box) for */ + /* all glyphs in the font. */ + /* */ + /* caret_Slope_Rise :: The rise coefficient of the cursor's */ + /* slope of the cursor (slope=rise/run). */ + /* */ + /* caret_Slope_Run :: The run coefficient of the cursor's */ + /* slope. */ + /* */ + /* Reserved :: 8~reserved bytes. */ + /* */ + /* metric_Data_Format :: Always~0. */ + /* */ + /* number_Of_HMetrics :: Number of HMetrics entries in the `hmtx' */ + /* table -- this value can be smaller than */ + /* the total number of glyphs in the font. */ + /* */ + /* long_metrics :: A pointer into the `hmtx' table. */ + /* */ + /* short_metrics :: A pointer into the `hmtx' table. */ + /* */ + /* <Note> */ + /* IMPORTANT: The TT_HoriHeader and TT_VertHeader structures should */ + /* be identical except for the names of their fields which */ + /* are different. */ + /* */ + /* This ensures that a single function in the `ttload' */ + /* module is able to read both the horizontal and vertical */ + /* headers. */ + /* */ + typedef struct TT_HoriHeader_ + { + FT_Fixed Version; + FT_Short Ascender; + FT_Short Descender; + FT_Short Line_Gap; + + FT_UShort advance_Width_Max; /* advance width maximum */ + + FT_Short min_Left_Side_Bearing; /* minimum left-sb */ + FT_Short min_Right_Side_Bearing; /* minimum right-sb */ + FT_Short xMax_Extent; /* xmax extents */ + FT_Short caret_Slope_Rise; + FT_Short caret_Slope_Run; + FT_Short caret_Offset; + + FT_Short Reserved[4]; + + FT_Short metric_Data_Format; + FT_UShort number_Of_HMetrics; + + /* The following fields are not defined by the TrueType specification */ + /* but they are used to connect the metrics header to the relevant */ + /* `HMTX' table. */ + + void* long_metrics; + void* short_metrics; + + } TT_HoriHeader; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_VertHeader */ + /* */ + /* <Description> */ + /* A structure used to model a TrueType vertical header, the `vhea' */ + /* table, as well as the corresponding vertical metrics table, i.e., */ + /* the `vmtx' table. */ + /* */ + /* <Fields> */ + /* Version :: The table version. */ + /* */ + /* Ascender :: The font's ascender, i.e., the distance */ + /* from the baseline to the top-most of */ + /* all glyph points found in the font. */ + /* */ + /* This value is invalid in many fonts, as */ + /* it is usually set by the font designer, */ + /* and often reflects only a portion of */ + /* the glyphs found in the font (maybe */ + /* ASCII). */ + /* */ + /* You should use the `sTypoAscender' */ + /* field of the OS/2 table instead if you */ + /* want the correct one. */ + /* */ + /* Descender :: The font's descender, i.e., the */ + /* distance from the baseline to the */ + /* bottom-most of all glyph points found */ + /* in the font. It is negative. */ + /* */ + /* This value is invalid in many fonts, as */ + /* it is usually set by the font designer, */ + /* and often reflects only a portion of */ + /* the glyphs found in the font (maybe */ + /* ASCII). */ + /* */ + /* You should use the `sTypoDescender' */ + /* field of the OS/2 table instead if you */ + /* want the correct one. */ + /* */ + /* Line_Gap :: The font's line gap, i.e., the distance */ + /* to add to the ascender and descender to */ + /* get the BTB, i.e., the */ + /* baseline-to-baseline distance for the */ + /* font. */ + /* */ + /* advance_Height_Max :: This field is the maximum of all */ + /* advance heights found in the font. It */ + /* can be used to compute the maximum */ + /* height of an arbitrary string of text. */ + /* */ + /* min_Top_Side_Bearing :: The minimum top side bearing of all */ + /* glyphs within the font. */ + /* */ + /* min_Bottom_Side_Bearing :: The minimum bottom side bearing of all */ + /* glyphs within the font. */ + /* */ + /* yMax_Extent :: The maximum vertical extent (i.e., the */ + /* `height' of a glyph's bounding box) for */ + /* all glyphs in the font. */ + /* */ + /* caret_Slope_Rise :: The rise coefficient of the cursor's */ + /* slope of the cursor (slope=rise/run). */ + /* */ + /* caret_Slope_Run :: The run coefficient of the cursor's */ + /* slope. */ + /* */ + /* caret_Offset :: The cursor's offset for slanted fonts. */ + /* This value is `reserved' in vmtx */ + /* version 1.0. */ + /* */ + /* Reserved :: 8~reserved bytes. */ + /* */ + /* metric_Data_Format :: Always~0. */ + /* */ + /* number_Of_HMetrics :: Number of VMetrics entries in the */ + /* `vmtx' table -- this value can be */ + /* smaller than the total number of glyphs */ + /* in the font. */ + /* */ + /* long_metrics :: A pointer into the `vmtx' table. */ + /* */ + /* short_metrics :: A pointer into the `vmtx' table. */ + /* */ + /* <Note> */ + /* IMPORTANT: The TT_HoriHeader and TT_VertHeader structures should */ + /* be identical except for the names of their fields which */ + /* are different. */ + /* */ + /* This ensures that a single function in the `ttload' */ + /* module is able to read both the horizontal and vertical */ + /* headers. */ + /* */ + typedef struct TT_VertHeader_ + { + FT_Fixed Version; + FT_Short Ascender; + FT_Short Descender; + FT_Short Line_Gap; + + FT_UShort advance_Height_Max; /* advance height maximum */ + + FT_Short min_Top_Side_Bearing; /* minimum left-sb or top-sb */ + FT_Short min_Bottom_Side_Bearing; /* minimum right-sb or bottom-sb */ + FT_Short yMax_Extent; /* xmax or ymax extents */ + FT_Short caret_Slope_Rise; + FT_Short caret_Slope_Run; + FT_Short caret_Offset; + + FT_Short Reserved[4]; + + FT_Short metric_Data_Format; + FT_UShort number_Of_VMetrics; + + /* The following fields are not defined by the TrueType specification */ + /* but they're used to connect the metrics header to the relevant */ + /* `HMTX' or `VMTX' table. */ + + void* long_metrics; + void* short_metrics; + + } TT_VertHeader; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_OS2 */ + /* */ + /* <Description> */ + /* A structure used to model a TrueType OS/2 table. This is the long */ + /* table version. All fields comply to the TrueType specification. */ + /* */ + /* Note that we now support old Mac fonts which do not include an */ + /* OS/2 table. In this case, the `version' field is always set to */ + /* 0xFFFF. */ + /* */ + typedef struct TT_OS2_ + { + FT_UShort version; /* 0x0001 - more or 0xFFFF */ + FT_Short xAvgCharWidth; + FT_UShort usWeightClass; + FT_UShort usWidthClass; + FT_Short fsType; + FT_Short ySubscriptXSize; + FT_Short ySubscriptYSize; + FT_Short ySubscriptXOffset; + FT_Short ySubscriptYOffset; + FT_Short ySuperscriptXSize; + FT_Short ySuperscriptYSize; + FT_Short ySuperscriptXOffset; + FT_Short ySuperscriptYOffset; + FT_Short yStrikeoutSize; + FT_Short yStrikeoutPosition; + FT_Short sFamilyClass; + + FT_Byte panose[10]; + + FT_ULong ulUnicodeRange1; /* Bits 0-31 */ + FT_ULong ulUnicodeRange2; /* Bits 32-63 */ + FT_ULong ulUnicodeRange3; /* Bits 64-95 */ + FT_ULong ulUnicodeRange4; /* Bits 96-127 */ + + FT_Char achVendID[4]; + + FT_UShort fsSelection; + FT_UShort usFirstCharIndex; + FT_UShort usLastCharIndex; + FT_Short sTypoAscender; + FT_Short sTypoDescender; + FT_Short sTypoLineGap; + FT_UShort usWinAscent; + FT_UShort usWinDescent; + + /* only version 1 tables: */ + + FT_ULong ulCodePageRange1; /* Bits 0-31 */ + FT_ULong ulCodePageRange2; /* Bits 32-63 */ + + /* only version 2 tables: */ + + FT_Short sxHeight; + FT_Short sCapHeight; + FT_UShort usDefaultChar; + FT_UShort usBreakChar; + FT_UShort usMaxContext; + + } TT_OS2; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_Postscript */ + /* */ + /* <Description> */ + /* A structure used to model a TrueType PostScript table. All fields */ + /* comply to the TrueType specification. This structure does not */ + /* reference the PostScript glyph names, which can be nevertheless */ + /* accessed with the `ttpost' module. */ + /* */ + typedef struct TT_Postscript_ + { + FT_Fixed FormatType; + FT_Fixed italicAngle; + FT_Short underlinePosition; + FT_Short underlineThickness; + FT_ULong isFixedPitch; + FT_ULong minMemType42; + FT_ULong maxMemType42; + FT_ULong minMemType1; + FT_ULong maxMemType1; + + /* Glyph names follow in the file, but we don't */ + /* load them by default. See the ttpost.c file. */ + + } TT_Postscript; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_PCLT */ + /* */ + /* <Description> */ + /* A structure used to model a TrueType PCLT table. All fields */ + /* comply to the TrueType specification. */ + /* */ + typedef struct TT_PCLT_ + { + FT_Fixed Version; + FT_ULong FontNumber; + FT_UShort Pitch; + FT_UShort xHeight; + FT_UShort Style; + FT_UShort TypeFamily; + FT_UShort CapHeight; + FT_UShort SymbolSet; + FT_Char TypeFace[16]; + FT_Char CharacterComplement[8]; + FT_Char FileName[6]; + FT_Char StrokeWeight; + FT_Char WidthType; + FT_Byte SerifStyle; + FT_Byte Reserved; + + } TT_PCLT; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_MaxProfile */ + /* */ + /* <Description> */ + /* The maximum profile is a table containing many max values which */ + /* can be used to pre-allocate arrays. This ensures that no memory */ + /* allocation occurs during a glyph load. */ + /* */ + /* <Fields> */ + /* version :: The version number. */ + /* */ + /* numGlyphs :: The number of glyphs in this TrueType */ + /* font. */ + /* */ + /* maxPoints :: The maximum number of points in a */ + /* non-composite TrueType glyph. See also */ + /* the structure element */ + /* `maxCompositePoints'. */ + /* */ + /* maxContours :: The maximum number of contours in a */ + /* non-composite TrueType glyph. See also */ + /* the structure element */ + /* `maxCompositeContours'. */ + /* */ + /* maxCompositePoints :: The maximum number of points in a */ + /* composite TrueType glyph. See also the */ + /* structure element `maxPoints'. */ + /* */ + /* maxCompositeContours :: The maximum number of contours in a */ + /* composite TrueType glyph. See also the */ + /* structure element `maxContours'. */ + /* */ + /* maxZones :: The maximum number of zones used for */ + /* glyph hinting. */ + /* */ + /* maxTwilightPoints :: The maximum number of points in the */ + /* twilight zone used for glyph hinting. */ + /* */ + /* maxStorage :: The maximum number of elements in the */ + /* storage area used for glyph hinting. */ + /* */ + /* maxFunctionDefs :: The maximum number of function */ + /* definitions in the TrueType bytecode for */ + /* this font. */ + /* */ + /* maxInstructionDefs :: The maximum number of instruction */ + /* definitions in the TrueType bytecode for */ + /* this font. */ + /* */ + /* maxStackElements :: The maximum number of stack elements used */ + /* during bytecode interpretation. */ + /* */ + /* maxSizeOfInstructions :: The maximum number of TrueType opcodes */ + /* used for glyph hinting. */ + /* */ + /* maxComponentElements :: The maximum number of simple (i.e., non- */ + /* composite) glyphs in a composite glyph. */ + /* */ + /* maxComponentDepth :: The maximum nesting depth of composite */ + /* glyphs. */ + /* */ + /* <Note> */ + /* This structure is only used during font loading. */ + /* */ + typedef struct TT_MaxProfile_ + { + FT_Fixed version; + FT_UShort numGlyphs; + FT_UShort maxPoints; + FT_UShort maxContours; + FT_UShort maxCompositePoints; + FT_UShort maxCompositeContours; + FT_UShort maxZones; + FT_UShort maxTwilightPoints; + FT_UShort maxStorage; + FT_UShort maxFunctionDefs; + FT_UShort maxInstructionDefs; + FT_UShort maxStackElements; + FT_UShort maxSizeOfInstructions; + FT_UShort maxComponentElements; + FT_UShort maxComponentDepth; + + } TT_MaxProfile; + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Sfnt_Tag */ + /* */ + /* <Description> */ + /* An enumeration used to specify the index of an SFNT table. */ + /* Used in the @FT_Get_Sfnt_Table API function. */ + /* */ + typedef enum FT_Sfnt_Tag_ + { + ft_sfnt_head = 0, + ft_sfnt_maxp = 1, + ft_sfnt_os2 = 2, + ft_sfnt_hhea = 3, + ft_sfnt_vhea = 4, + ft_sfnt_post = 5, + ft_sfnt_pclt = 6, + + sfnt_max /* internal end mark */ + + } FT_Sfnt_Tag; + + /* */ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Sfnt_Table */ + /* */ + /* <Description> */ + /* Return a pointer to a given SFNT table within a face. */ + /* */ + /* <Input> */ + /* face :: A handle to the source. */ + /* */ + /* tag :: The index of the SFNT table. */ + /* */ + /* <Return> */ + /* A type-less pointer to the table. This will be~0 in case of */ + /* error, or if the corresponding table was not found *OR* loaded */ + /* from the file. */ + /* */ + /* <Note> */ + /* The table is owned by the face object and disappears with it. */ + /* */ + /* This function is only useful to access SFNT tables that are loaded */ + /* by the sfnt, truetype, and opentype drivers. See @FT_Sfnt_Tag for */ + /* a list. */ + /* */ + FT_EXPORT( void* ) + FT_Get_Sfnt_Table( FT_Face face, + FT_Sfnt_Tag tag ); + + + /************************************************************************** + * + * @function: + * FT_Load_Sfnt_Table + * + * @description: + * Load any font table into client memory. + * + * @input: + * face :: + * A handle to the source face. + * + * tag :: + * The four-byte tag of the table to load. Use the value~0 if you want + * to access the whole font file. Otherwise, you can use one of the + * definitions found in the @FT_TRUETYPE_TAGS_H file, or forge a new + * one with @FT_MAKE_TAG. + * + * offset :: + * The starting offset in the table (or file if tag == 0). + * + * @output: + * buffer :: + * The target buffer address. The client must ensure that the memory + * array is big enough to hold the data. + * + * @inout: + * length :: + * If the `length' parameter is NULL, then try to load the whole table. + * Return an error code if it fails. + * + * Else, if `*length' is~0, exit immediately while returning the + * table's (or file) full size in it. + * + * Else the number of bytes to read from the table or file, from the + * starting offset. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * If you need to determine the table's length you should first call this + * function with `*length' set to~0, as in the following example: + * + * { + * FT_ULong length = 0; + * + * + * error = FT_Load_Sfnt_Table( face, tag, 0, NULL, &length ); + * if ( error ) { ... table does not exist ... } + * + * buffer = malloc( length ); + * if ( buffer == NULL ) { ... not enough memory ... } + * + * error = FT_Load_Sfnt_Table( face, tag, 0, buffer, &length ); + * if ( error ) { ... could not load table ... } + * } + */ + FT_EXPORT( FT_Error ) + FT_Load_Sfnt_Table( FT_Face face, + FT_ULong tag, + FT_Long offset, + FT_Byte* buffer, + FT_ULong* length ); + + + /************************************************************************** + * + * @function: + * FT_Sfnt_Table_Info + * + * @description: + * Return information on an SFNT table. + * + * @input: + * face :: + * A handle to the source face. + * + * table_index :: + * The index of an SFNT table. The function returns + * FT_Err_Table_Missing for an invalid value. + * + * @output: + * tag :: + * The name tag of the SFNT table. + * + * length :: + * The length of the SFNT table. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * SFNT tables with length zero are treated as missing. + * + */ + FT_EXPORT( FT_Error ) + FT_Sfnt_Table_Info( FT_Face face, + FT_UInt table_index, + FT_ULong *tag, + FT_ULong *length ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_CMap_Language_ID */ + /* */ + /* <Description> */ + /* Return TrueType/sfnt specific cmap language ID. Definitions of */ + /* language ID values are in `freetype/ttnameid.h'. */ + /* */ + /* <Input> */ + /* charmap :: */ + /* The target charmap. */ + /* */ + /* <Return> */ + /* The language ID of `charmap'. If `charmap' doesn't belong to a */ + /* TrueType/sfnt face, just return~0 as the default value. */ + /* */ + FT_EXPORT( FT_ULong ) + FT_Get_CMap_Language_ID( FT_CharMap charmap ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_CMap_Format */ + /* */ + /* <Description> */ + /* Return TrueType/sfnt specific cmap format. */ + /* */ + /* <Input> */ + /* charmap :: */ + /* The target charmap. */ + /* */ + /* <Return> */ + /* The format of `charmap'. If `charmap' doesn't belong to a */ + /* TrueType/sfnt face, return -1. */ + /* */ + FT_EXPORT( FT_Long ) + FT_Get_CMap_Format( FT_CharMap charmap ); + + /* */ + + +FT_END_HEADER + +#endif /* __TTTABLES_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/tttags.h b/mod/pub.mod/freetype.mod/include/freetype/tttags.h new file mode 100644 index 0000000..307ce4b --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/tttags.h @@ -0,0 +1,107 @@ +/***************************************************************************/ +/* */ +/* tttags.h */ +/* */ +/* Tags for TrueType and OpenType tables (specification only). */ +/* */ +/* Copyright 1996-2001, 2004, 2005, 2007, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __TTAGS_H__ +#define __TTAGS_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + +#define TTAG_avar FT_MAKE_TAG( 'a', 'v', 'a', 'r' ) +#define TTAG_BASE FT_MAKE_TAG( 'B', 'A', 'S', 'E' ) +#define TTAG_bdat FT_MAKE_TAG( 'b', 'd', 'a', 't' ) +#define TTAG_BDF FT_MAKE_TAG( 'B', 'D', 'F', ' ' ) +#define TTAG_bhed FT_MAKE_TAG( 'b', 'h', 'e', 'd' ) +#define TTAG_bloc FT_MAKE_TAG( 'b', 'l', 'o', 'c' ) +#define TTAG_bsln FT_MAKE_TAG( 'b', 's', 'l', 'n' ) +#define TTAG_CFF FT_MAKE_TAG( 'C', 'F', 'F', ' ' ) +#define TTAG_CID FT_MAKE_TAG( 'C', 'I', 'D', ' ' ) +#define TTAG_cmap FT_MAKE_TAG( 'c', 'm', 'a', 'p' ) +#define TTAG_cvar FT_MAKE_TAG( 'c', 'v', 'a', 'r' ) +#define TTAG_cvt FT_MAKE_TAG( 'c', 'v', 't', ' ' ) +#define TTAG_DSIG FT_MAKE_TAG( 'D', 'S', 'I', 'G' ) +#define TTAG_EBDT FT_MAKE_TAG( 'E', 'B', 'D', 'T' ) +#define TTAG_EBLC FT_MAKE_TAG( 'E', 'B', 'L', 'C' ) +#define TTAG_EBSC FT_MAKE_TAG( 'E', 'B', 'S', 'C' ) +#define TTAG_feat FT_MAKE_TAG( 'f', 'e', 'a', 't' ) +#define TTAG_FOND FT_MAKE_TAG( 'F', 'O', 'N', 'D' ) +#define TTAG_fpgm FT_MAKE_TAG( 'f', 'p', 'g', 'm' ) +#define TTAG_fvar FT_MAKE_TAG( 'f', 'v', 'a', 'r' ) +#define TTAG_gasp FT_MAKE_TAG( 'g', 'a', 's', 'p' ) +#define TTAG_GDEF FT_MAKE_TAG( 'G', 'D', 'E', 'F' ) +#define TTAG_glyf FT_MAKE_TAG( 'g', 'l', 'y', 'f' ) +#define TTAG_GPOS FT_MAKE_TAG( 'G', 'P', 'O', 'S' ) +#define TTAG_GSUB FT_MAKE_TAG( 'G', 'S', 'U', 'B' ) +#define TTAG_gvar FT_MAKE_TAG( 'g', 'v', 'a', 'r' ) +#define TTAG_hdmx FT_MAKE_TAG( 'h', 'd', 'm', 'x' ) +#define TTAG_head FT_MAKE_TAG( 'h', 'e', 'a', 'd' ) +#define TTAG_hhea FT_MAKE_TAG( 'h', 'h', 'e', 'a' ) +#define TTAG_hmtx FT_MAKE_TAG( 'h', 'm', 't', 'x' ) +#define TTAG_JSTF FT_MAKE_TAG( 'J', 'S', 'T', 'F' ) +#define TTAG_just FT_MAKE_TAG( 'j', 'u', 's', 't' ) +#define TTAG_kern FT_MAKE_TAG( 'k', 'e', 'r', 'n' ) +#define TTAG_lcar FT_MAKE_TAG( 'l', 'c', 'a', 'r' ) +#define TTAG_loca FT_MAKE_TAG( 'l', 'o', 'c', 'a' ) +#define TTAG_LTSH FT_MAKE_TAG( 'L', 'T', 'S', 'H' ) +#define TTAG_LWFN FT_MAKE_TAG( 'L', 'W', 'F', 'N' ) +#define TTAG_MATH FT_MAKE_TAG( 'M', 'A', 'T', 'H' ) +#define TTAG_maxp FT_MAKE_TAG( 'm', 'a', 'x', 'p' ) +#define TTAG_META FT_MAKE_TAG( 'M', 'E', 'T', 'A' ) +#define TTAG_MMFX FT_MAKE_TAG( 'M', 'M', 'F', 'X' ) +#define TTAG_MMSD FT_MAKE_TAG( 'M', 'M', 'S', 'D' ) +#define TTAG_mort FT_MAKE_TAG( 'm', 'o', 'r', 't' ) +#define TTAG_morx FT_MAKE_TAG( 'm', 'o', 'r', 'x' ) +#define TTAG_name FT_MAKE_TAG( 'n', 'a', 'm', 'e' ) +#define TTAG_opbd FT_MAKE_TAG( 'o', 'p', 'b', 'd' ) +#define TTAG_OS2 FT_MAKE_TAG( 'O', 'S', '/', '2' ) +#define TTAG_OTTO FT_MAKE_TAG( 'O', 'T', 'T', 'O' ) +#define TTAG_PCLT FT_MAKE_TAG( 'P', 'C', 'L', 'T' ) +#define TTAG_POST FT_MAKE_TAG( 'P', 'O', 'S', 'T' ) +#define TTAG_post FT_MAKE_TAG( 'p', 'o', 's', 't' ) +#define TTAG_prep FT_MAKE_TAG( 'p', 'r', 'e', 'p' ) +#define TTAG_prop FT_MAKE_TAG( 'p', 'r', 'o', 'p' ) +#define TTAG_sfnt FT_MAKE_TAG( 's', 'f', 'n', 't' ) +#define TTAG_SING FT_MAKE_TAG( 'S', 'I', 'N', 'G' ) +#define TTAG_trak FT_MAKE_TAG( 't', 'r', 'a', 'k' ) +#define TTAG_true FT_MAKE_TAG( 't', 'r', 'u', 'e' ) +#define TTAG_ttc FT_MAKE_TAG( 't', 't', 'c', ' ' ) +#define TTAG_ttcf FT_MAKE_TAG( 't', 't', 'c', 'f' ) +#define TTAG_TYP1 FT_MAKE_TAG( 'T', 'Y', 'P', '1' ) +#define TTAG_typ1 FT_MAKE_TAG( 't', 'y', 'p', '1' ) +#define TTAG_VDMX FT_MAKE_TAG( 'V', 'D', 'M', 'X' ) +#define TTAG_vhea FT_MAKE_TAG( 'v', 'h', 'e', 'a' ) +#define TTAG_vmtx FT_MAKE_TAG( 'v', 'm', 't', 'x' ) + + +FT_END_HEADER + +#endif /* __TTAGS_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/freetype/ttunpat.h b/mod/pub.mod/freetype.mod/include/freetype/ttunpat.h new file mode 100644 index 0000000..a016275 --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/freetype/ttunpat.h @@ -0,0 +1,59 @@ +/***************************************************************************/ +/* */ +/* ttunpat.h */ +/* */ +/* Definitions for the unpatented TrueType hinting system */ +/* */ +/* Copyright 2003, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* Written by Graham Asher <graham.asher@btinternet.com> */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __TTUNPAT_H__ +#define __TTUNPAT_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************** + * + * @constant: + * FT_PARAM_TAG_UNPATENTED_HINTING + * + * @description: + * A constant used as the tag of an @FT_Parameter structure to indicate + * that unpatented methods only should be used by the TrueType bytecode + * interpreter for a typeface opened by @FT_Open_Face. + * + */ +#define FT_PARAM_TAG_UNPATENTED_HINTING FT_MAKE_TAG( 'u', 'n', 'p', 'a' ) + + /* */ + +FT_END_HEADER + + +#endif /* __TTUNPAT_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/include/ft2build.h b/mod/pub.mod/freetype.mod/include/ft2build.h new file mode 100644 index 0000000..923d887 --- /dev/null +++ b/mod/pub.mod/freetype.mod/include/ft2build.h @@ -0,0 +1,39 @@ +/***************************************************************************/ +/* */ +/* ft2build.h */ +/* */ +/* FreeType 2 build and setup macros. */ +/* (Generic version) */ +/* */ +/* Copyright 1996-2001, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file corresponds to the default `ft2build.h' file for */ + /* FreeType 2. It uses the `freetype' include root. */ + /* */ + /* Note that specific platforms might use a different configuration. */ + /* See builds/unix/ft2unix.h for an example. */ + /* */ + /*************************************************************************/ + + +#ifndef __FT2_BUILD_GENERIC_H__ +#define __FT2_BUILD_GENERIC_H__ + +#include <freetype/config/ftheader.h> + +#endif /* __FT2_BUILD_GENERIC_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/autofit/afangles.c b/mod/pub.mod/freetype.mod/src/autofit/afangles.c new file mode 100644 index 0000000..e2360d1 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/autofit/afangles.c @@ -0,0 +1,292 @@ +/***************************************************************************/ +/* */ +/* afangles.c */ +/* */ +/* Routines used to compute vector angles with limited accuracy */ +/* and very high speed. It also contains sorting routines (body). */ +/* */ +/* Copyright 2003, 2004, 2005, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include "aftypes.h" + + +#if 0 + + FT_LOCAL_DEF( FT_Int ) + af_corner_is_flat( FT_Pos x_in, + FT_Pos y_in, + FT_Pos x_out, + FT_Pos y_out ) + { + FT_Pos ax = x_in; + FT_Pos ay = y_in; + + FT_Pos d_in, d_out, d_corner; + + + if ( ax < 0 ) + ax = -ax; + if ( ay < 0 ) + ay = -ay; + d_in = ax + ay; + + ax = x_out; + if ( ax < 0 ) + ax = -ax; + ay = y_out; + if ( ay < 0 ) + ay = -ay; + d_out = ax + ay; + + ax = x_out + x_in; + if ( ax < 0 ) + ax = -ax; + ay = y_out + y_in; + if ( ay < 0 ) + ay = -ay; + d_corner = ax + ay; + + return ( d_in + d_out - d_corner ) < ( d_corner >> 4 ); + } + + + FT_LOCAL_DEF( FT_Int ) + af_corner_orientation( FT_Pos x_in, + FT_Pos y_in, + FT_Pos x_out, + FT_Pos y_out ) + { + FT_Pos delta; + + + delta = x_in * y_out - y_in * x_out; + + if ( delta == 0 ) + return 0; + else + return 1 - 2 * ( delta < 0 ); + } + +#endif + + + /* + * We are not using `af_angle_atan' anymore, but we keep the source + * code below just in case... + */ + + +#if 0 + + + /* + * The trick here is to realize that we don't need a very accurate angle + * approximation. We are going to use the result of `af_angle_atan' to + * only compare the sign of angle differences, or check whether its + * magnitude is very small. + * + * The approximation + * + * dy * PI / (|dx|+|dy|) + * + * should be enough, and much faster to compute. + */ + FT_LOCAL_DEF( AF_Angle ) + af_angle_atan( FT_Fixed dx, + FT_Fixed dy ) + { + AF_Angle angle; + FT_Fixed ax = dx; + FT_Fixed ay = dy; + + + if ( ax < 0 ) + ax = -ax; + if ( ay < 0 ) + ay = -ay; + + ax += ay; + + if ( ax == 0 ) + angle = 0; + else + { + angle = ( AF_ANGLE_PI2 * dy ) / ( ax + ay ); + if ( dx < 0 ) + { + if ( angle >= 0 ) + angle = AF_ANGLE_PI - angle; + else + angle = -AF_ANGLE_PI - angle; + } + } + + return angle; + } + + +#elif 0 + + + /* the following table has been automatically generated with */ + /* the `mather.py' Python script */ + +#define AF_ATAN_BITS 8 + + static const FT_Byte af_arctan[1L << AF_ATAN_BITS] = + { + 0, 0, 1, 1, 1, 2, 2, 2, + 3, 3, 3, 3, 4, 4, 4, 5, + 5, 5, 6, 6, 6, 7, 7, 7, + 8, 8, 8, 9, 9, 9, 10, 10, + 10, 10, 11, 11, 11, 12, 12, 12, + 13, 13, 13, 14, 14, 14, 14, 15, + 15, 15, 16, 16, 16, 17, 17, 17, + 18, 18, 18, 18, 19, 19, 19, 20, + 20, 20, 21, 21, 21, 21, 22, 22, + 22, 23, 23, 23, 24, 24, 24, 24, + 25, 25, 25, 26, 26, 26, 26, 27, + 27, 27, 28, 28, 28, 28, 29, 29, + 29, 30, 30, 30, 30, 31, 31, 31, + 31, 32, 32, 32, 33, 33, 33, 33, + 34, 34, 34, 34, 35, 35, 35, 35, + 36, 36, 36, 36, 37, 37, 37, 38, + 38, 38, 38, 39, 39, 39, 39, 40, + 40, 40, 40, 41, 41, 41, 41, 42, + 42, 42, 42, 42, 43, 43, 43, 43, + 44, 44, 44, 44, 45, 45, 45, 45, + 46, 46, 46, 46, 46, 47, 47, 47, + 47, 48, 48, 48, 48, 48, 49, 49, + 49, 49, 50, 50, 50, 50, 50, 51, + 51, 51, 51, 51, 52, 52, 52, 52, + 52, 53, 53, 53, 53, 53, 54, 54, + 54, 54, 54, 55, 55, 55, 55, 55, + 56, 56, 56, 56, 56, 57, 57, 57, + 57, 57, 57, 58, 58, 58, 58, 58, + 59, 59, 59, 59, 59, 59, 60, 60, + 60, 60, 60, 61, 61, 61, 61, 61, + 61, 62, 62, 62, 62, 62, 62, 63, + 63, 63, 63, 63, 63, 64, 64, 64 + }; + + + FT_LOCAL_DEF( AF_Angle ) + af_angle_atan( FT_Fixed dx, + FT_Fixed dy ) + { + AF_Angle angle; + + + /* check trivial cases */ + if ( dy == 0 ) + { + angle = 0; + if ( dx < 0 ) + angle = AF_ANGLE_PI; + return angle; + } + else if ( dx == 0 ) + { + angle = AF_ANGLE_PI2; + if ( dy < 0 ) + angle = -AF_ANGLE_PI2; + return angle; + } + + angle = 0; + if ( dx < 0 ) + { + dx = -dx; + dy = -dy; + angle = AF_ANGLE_PI; + } + + if ( dy < 0 ) + { + FT_Pos tmp; + + + tmp = dx; + dx = -dy; + dy = tmp; + angle -= AF_ANGLE_PI2; + } + + if ( dx == 0 && dy == 0 ) + return 0; + + if ( dx == dy ) + angle += AF_ANGLE_PI4; + else if ( dx > dy ) + angle += af_arctan[FT_DivFix( dy, dx ) >> ( 16 - AF_ATAN_BITS )]; + else + angle += AF_ANGLE_PI2 - + af_arctan[FT_DivFix( dx, dy ) >> ( 16 - AF_ATAN_BITS )]; + + if ( angle > AF_ANGLE_PI ) + angle -= AF_ANGLE_2PI; + + return angle; + } + + +#endif /* 0 */ + + + FT_LOCAL_DEF( void ) + af_sort_pos( FT_UInt count, + FT_Pos* table ) + { + FT_UInt i, j; + FT_Pos swap; + + + for ( i = 1; i < count; i++ ) + { + for ( j = i; j > 0; j-- ) + { + if ( table[j] > table[j - 1] ) + break; + + swap = table[j]; + table[j] = table[j - 1]; + table[j - 1] = swap; + } + } + } + + + FT_LOCAL_DEF( void ) + af_sort_widths( FT_UInt count, + AF_Width table ) + { + FT_UInt i, j; + AF_WidthRec swap; + + + for ( i = 1; i < count; i++ ) + { + for ( j = i; j > 0; j-- ) + { + if ( table[j].org > table[j - 1].org ) + break; + + swap = table[j]; + table[j] = table[j - 1]; + table[j - 1] = swap; + } + } + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/autofit/afangles.h b/mod/pub.mod/freetype.mod/src/autofit/afangles.h new file mode 100644 index 0000000..f33f9e1 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/autofit/afangles.h @@ -0,0 +1,7 @@ +/* + * afangles.h + * + * This is a dummy file, used to please the build system. It is never + * included by the auto-fitter sources. + * + */ diff --git a/mod/pub.mod/freetype.mod/src/autofit/afcjk.c b/mod/pub.mod/freetype.mod/src/autofit/afcjk.c new file mode 100644 index 0000000..bab0c42 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/autofit/afcjk.c @@ -0,0 +1,1512 @@ +/***************************************************************************/ +/* */ +/* afcjk.c */ +/* */ +/* Auto-fitter hinting routines for CJK script (body). */ +/* */ +/* Copyright 2006, 2007, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + /* + * The algorithm is based on akito's autohint patch, available here: + * + * http://www.kde.gr.jp/~akito/patch/freetype2/ + * + */ + +#include "aftypes.h" +#include "aflatin.h" + + +#ifdef AF_CONFIG_OPTION_CJK + +#include "afcjk.h" +#include "aferrors.h" + + +#ifdef AF_USE_WARPER +#include "afwarp.h" +#endif + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** C J K G L O B A L M E T R I C S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL_DEF( FT_Error ) + af_cjk_metrics_init( AF_LatinMetrics metrics, + FT_Face face ) + { + FT_CharMap oldmap = face->charmap; + + + metrics->units_per_em = face->units_per_EM; + + /* TODO are there blues? */ + + if ( FT_Select_Charmap( face, FT_ENCODING_UNICODE ) ) + face->charmap = NULL; + else + { + /* latin's version would suffice */ + af_latin_metrics_init_widths( metrics, face, 0x7530 ); + af_latin_metrics_check_digits( metrics, face ); + } + + FT_Set_Charmap( face, oldmap ); + + return AF_Err_Ok; + } + + + static void + af_cjk_metrics_scale_dim( AF_LatinMetrics metrics, + AF_Scaler scaler, + AF_Dimension dim ) + { + AF_LatinAxis axis; + + + axis = &metrics->axis[dim]; + + if ( dim == AF_DIMENSION_HORZ ) + { + axis->scale = scaler->x_scale; + axis->delta = scaler->x_delta; + } + else + { + axis->scale = scaler->y_scale; + axis->delta = scaler->y_delta; + } + } + + + FT_LOCAL_DEF( void ) + af_cjk_metrics_scale( AF_LatinMetrics metrics, + AF_Scaler scaler ) + { + metrics->root.scaler = *scaler; + + af_cjk_metrics_scale_dim( metrics, scaler, AF_DIMENSION_HORZ ); + af_cjk_metrics_scale_dim( metrics, scaler, AF_DIMENSION_VERT ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** C J K G L Y P H A N A L Y S I S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static FT_Error + af_cjk_hints_compute_segments( AF_GlyphHints hints, + AF_Dimension dim ) + { + AF_AxisHints axis = &hints->axis[dim]; + AF_Segment segments = axis->segments; + AF_Segment segment_limit = segments + axis->num_segments; + FT_Error error; + AF_Segment seg; + + + error = af_latin_hints_compute_segments( hints, dim ); + if ( error ) + return error; + + /* a segment is round if it doesn't have successive */ + /* on-curve points. */ + for ( seg = segments; seg < segment_limit; seg++ ) + { + AF_Point pt = seg->first; + AF_Point last = seg->last; + AF_Flags f0 = (AF_Flags)(pt->flags & AF_FLAG_CONTROL); + AF_Flags f1; + + + seg->flags &= ~AF_EDGE_ROUND; + + for ( ; pt != last; f0 = f1 ) + { + pt = pt->next; + f1 = (AF_Flags)(pt->flags & AF_FLAG_CONTROL); + + if ( !f0 && !f1 ) + break; + + if ( pt == last ) + seg->flags |= AF_EDGE_ROUND; + } + } + + return AF_Err_Ok; + } + + + static void + af_cjk_hints_link_segments( AF_GlyphHints hints, + AF_Dimension dim ) + { + AF_AxisHints axis = &hints->axis[dim]; + AF_Segment segments = axis->segments; + AF_Segment segment_limit = segments + axis->num_segments; + AF_Direction major_dir = axis->major_dir; + AF_Segment seg1, seg2; + FT_Pos len_threshold; + FT_Pos dist_threshold; + + + len_threshold = AF_LATIN_CONSTANT( hints->metrics, 8 ); + + dist_threshold = ( dim == AF_DIMENSION_HORZ ) ? hints->x_scale + : hints->y_scale; + dist_threshold = FT_DivFix( 64 * 3, dist_threshold ); + + /* now compare each segment to the others */ + for ( seg1 = segments; seg1 < segment_limit; seg1++ ) + { + /* the fake segments are for metrics hinting only */ + if ( seg1->first == seg1->last ) + continue; + + if ( seg1->dir != major_dir ) + continue; + + for ( seg2 = segments; seg2 < segment_limit; seg2++ ) + if ( seg2 != seg1 && seg1->dir + seg2->dir == 0 ) + { + FT_Pos dist = seg2->pos - seg1->pos; + + + if ( dist < 0 ) + continue; + + { + FT_Pos min = seg1->min_coord; + FT_Pos max = seg1->max_coord; + FT_Pos len; + + + if ( min < seg2->min_coord ) + min = seg2->min_coord; + + if ( max > seg2->max_coord ) + max = seg2->max_coord; + + len = max - min; + if ( len >= len_threshold ) + { + if ( dist * 8 < seg1->score * 9 && + ( dist * 8 < seg1->score * 7 || seg1->len < len ) ) + { + seg1->score = dist; + seg1->len = len; + seg1->link = seg2; + } + + if ( dist * 8 < seg2->score * 9 && + ( dist * 8 < seg2->score * 7 || seg2->len < len ) ) + { + seg2->score = dist; + seg2->len = len; + seg2->link = seg1; + } + } + } + } + } + + /* + * now compute the `serif' segments + * + * In Hanzi, some strokes are wider on one or both of the ends. + * We either identify the stems on the ends as serifs or remove + * the linkage, depending on the length of the stems. + * + */ + + { + AF_Segment link1, link2; + + + for ( seg1 = segments; seg1 < segment_limit; seg1++ ) + { + link1 = seg1->link; + if ( !link1 || link1->link != seg1 || link1->pos <= seg1->pos ) + continue; + + if ( seg1->score >= dist_threshold ) + continue; + + for ( seg2 = segments; seg2 < segment_limit; seg2++ ) + { + if ( seg2->pos > seg1->pos || seg1 == seg2 ) + continue; + + link2 = seg2->link; + if ( !link2 || link2->link != seg2 || link2->pos < link1->pos ) + continue; + + if ( seg1->pos == seg2->pos && link1->pos == link2->pos ) + continue; + + if ( seg2->score <= seg1->score || seg1->score * 4 <= seg2->score ) + continue; + + /* seg2 < seg1 < link1 < link2 */ + + if ( seg1->len >= seg2->len * 3 ) + { + AF_Segment seg; + + + for ( seg = segments; seg < segment_limit; seg++ ) + { + AF_Segment link = seg->link; + + + if ( link == seg2 ) + { + seg->link = 0; + seg->serif = link1; + } + else if ( link == link2 ) + { + seg->link = 0; + seg->serif = seg1; + } + } + } + else + { + seg1->link = link1->link = 0; + + break; + } + } + } + } + + for ( seg1 = segments; seg1 < segment_limit; seg1++ ) + { + seg2 = seg1->link; + + if ( seg2 ) + { + seg2->num_linked++; + if ( seg2->link != seg1 ) + { + seg1->link = 0; + + if ( seg2->score < dist_threshold || seg1->score < seg2->score * 4 ) + seg1->serif = seg2->link; + else + seg2->num_linked--; + } + } + } + } + + + static FT_Error + af_cjk_hints_compute_edges( AF_GlyphHints hints, + AF_Dimension dim ) + { + AF_AxisHints axis = &hints->axis[dim]; + FT_Error error = AF_Err_Ok; + FT_Memory memory = hints->memory; + AF_LatinAxis laxis = &((AF_LatinMetrics)hints->metrics)->axis[dim]; + + AF_Segment segments = axis->segments; + AF_Segment segment_limit = segments + axis->num_segments; + AF_Segment seg; + + FT_Fixed scale; + FT_Pos edge_distance_threshold; + + + axis->num_edges = 0; + + scale = ( dim == AF_DIMENSION_HORZ ) ? hints->x_scale + : hints->y_scale; + + /*********************************************************************/ + /* */ + /* We begin by generating a sorted table of edges for the current */ + /* direction. To do so, we simply scan each segment and try to find */ + /* an edge in our table that corresponds to its position. */ + /* */ + /* If no edge is found, we create and insert a new edge in the */ + /* sorted table. Otherwise, we simply add the segment to the edge's */ + /* list which is then processed in the second step to compute the */ + /* edge's properties. */ + /* */ + /* Note that the edges table is sorted along the segment/edge */ + /* position. */ + /* */ + /*********************************************************************/ + + edge_distance_threshold = FT_MulFix( laxis->edge_distance_threshold, + scale ); + if ( edge_distance_threshold > 64 / 4 ) + edge_distance_threshold = FT_DivFix( 64 / 4, scale ); + else + edge_distance_threshold = laxis->edge_distance_threshold; + + for ( seg = segments; seg < segment_limit; seg++ ) + { + AF_Edge found = 0; + FT_Pos best = 0xFFFFU; + FT_Int ee; + + + /* look for an edge corresponding to the segment */ + for ( ee = 0; ee < axis->num_edges; ee++ ) + { + AF_Edge edge = axis->edges + ee; + FT_Pos dist; + + + if ( edge->dir != seg->dir ) + continue; + + dist = seg->pos - edge->fpos; + if ( dist < 0 ) + dist = -dist; + + if ( dist < edge_distance_threshold && dist < best ) + { + AF_Segment link = seg->link; + + + /* check whether all linked segments of the candidate edge */ + /* can make a single edge. */ + if ( link ) + { + AF_Segment seg1 = edge->first; + AF_Segment link1; + FT_Pos dist2 = 0; + + + do + { + link1 = seg1->link; + if ( link1 ) + { + dist2 = AF_SEGMENT_DIST( link, link1 ); + if ( dist2 >= edge_distance_threshold ) + break; + } + + } while ( ( seg1 = seg1->edge_next ) != edge->first ); + + if ( dist2 >= edge_distance_threshold ) + continue; + } + + best = dist; + found = edge; + } + } + + if ( !found ) + { + AF_Edge edge; + + + /* insert a new edge in the list and */ + /* sort according to the position */ + error = af_axis_hints_new_edge( axis, seg->pos, + (AF_Direction)seg->dir, + memory, &edge ); + if ( error ) + goto Exit; + + /* add the segment to the new edge's list */ + FT_ZERO( edge ); + + edge->first = seg; + edge->last = seg; + edge->fpos = seg->pos; + edge->opos = edge->pos = FT_MulFix( seg->pos, scale ); + seg->edge_next = seg; + edge->dir = seg->dir; + } + else + { + /* if an edge was found, simply add the segment to the edge's */ + /* list */ + seg->edge_next = found->first; + found->last->edge_next = seg; + found->last = seg; + } + } + + /*********************************************************************/ + /* */ + /* Good, we now compute each edge's properties according to segments */ + /* found on its position. Basically, these are as follows. */ + /* */ + /* - edge's main direction */ + /* - stem edge, serif edge or both (which defaults to stem then) */ + /* - rounded edge, straight or both (which defaults to straight) */ + /* - link for edge */ + /* */ + /*********************************************************************/ + + /* first of all, set the `edge' field in each segment -- this is */ + /* required in order to compute edge links */ + /* */ + /* Note that removing this loop and setting the `edge' field of each */ + /* segment directly in the code above slows down execution speed for */ + /* some reasons on platforms like the Sun. */ + + { + AF_Edge edges = axis->edges; + AF_Edge edge_limit = edges + axis->num_edges; + AF_Edge edge; + + + for ( edge = edges; edge < edge_limit; edge++ ) + { + seg = edge->first; + if ( seg ) + do + { + seg->edge = edge; + seg = seg->edge_next; + + } while ( seg != edge->first ); + } + + /* now compute each edge properties */ + for ( edge = edges; edge < edge_limit; edge++ ) + { + FT_Int is_round = 0; /* does it contain round segments? */ + FT_Int is_straight = 0; /* does it contain straight segments? */ + + + seg = edge->first; + + do + { + FT_Bool is_serif; + + + /* check for roundness of segment */ + if ( seg->flags & AF_EDGE_ROUND ) + is_round++; + else + is_straight++; + + /* check for links -- if seg->serif is set, then seg->link must */ + /* be ignored */ + is_serif = (FT_Bool)( seg->serif && seg->serif->edge != edge ); + + if ( seg->link || is_serif ) + { + AF_Edge edge2; + AF_Segment seg2; + + + edge2 = edge->link; + seg2 = seg->link; + + if ( is_serif ) + { + seg2 = seg->serif; + edge2 = edge->serif; + } + + if ( edge2 ) + { + FT_Pos edge_delta; + FT_Pos seg_delta; + + + edge_delta = edge->fpos - edge2->fpos; + if ( edge_delta < 0 ) + edge_delta = -edge_delta; + + seg_delta = AF_SEGMENT_DIST( seg, seg2 ); + + if ( seg_delta < edge_delta ) + edge2 = seg2->edge; + } + else + edge2 = seg2->edge; + + if ( is_serif ) + { + edge->serif = edge2; + edge2->flags |= AF_EDGE_SERIF; + } + else + edge->link = edge2; + } + + seg = seg->edge_next; + + } while ( seg != edge->first ); + + /* set the round/straight flags */ + edge->flags = AF_EDGE_NORMAL; + + if ( is_round > 0 && is_round >= is_straight ) + edge->flags |= AF_EDGE_ROUND; + + /* get rid of serifs if link is set */ + /* XXX: This gets rid of many unpleasant artefacts! */ + /* Example: the `c' in cour.pfa at size 13 */ + + if ( edge->serif && edge->link ) + edge->serif = 0; + } + } + + Exit: + return error; + } + + + static FT_Error + af_cjk_hints_detect_features( AF_GlyphHints hints, + AF_Dimension dim ) + { + FT_Error error; + + + error = af_cjk_hints_compute_segments( hints, dim ); + if ( !error ) + { + af_cjk_hints_link_segments( hints, dim ); + + error = af_cjk_hints_compute_edges( hints, dim ); + } + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + af_cjk_hints_init( AF_GlyphHints hints, + AF_LatinMetrics metrics ) + { + FT_Render_Mode mode; + FT_UInt32 scaler_flags, other_flags; + + + af_glyph_hints_rescale( hints, (AF_ScriptMetrics)metrics ); + + /* + * correct x_scale and y_scale when needed, since they may have + * been modified af_cjk_scale_dim above + */ + hints->x_scale = metrics->axis[AF_DIMENSION_HORZ].scale; + hints->x_delta = metrics->axis[AF_DIMENSION_HORZ].delta; + hints->y_scale = metrics->axis[AF_DIMENSION_VERT].scale; + hints->y_delta = metrics->axis[AF_DIMENSION_VERT].delta; + + /* compute flags depending on render mode, etc. */ + mode = metrics->root.scaler.render_mode; + +#ifdef AF_USE_WARPER + if ( mode == FT_RENDER_MODE_LCD || mode == FT_RENDER_MODE_LCD_V ) + metrics->root.scaler.render_mode = mode = FT_RENDER_MODE_NORMAL; +#endif + + scaler_flags = hints->scaler_flags; + other_flags = 0; + + /* + * We snap the width of vertical stems for the monochrome and + * horizontal LCD rendering targets only. + */ + if ( mode == FT_RENDER_MODE_MONO || mode == FT_RENDER_MODE_LCD ) + other_flags |= AF_LATIN_HINTS_HORZ_SNAP; + + /* + * We snap the width of horizontal stems for the monochrome and + * vertical LCD rendering targets only. + */ + if ( mode == FT_RENDER_MODE_MONO || mode == FT_RENDER_MODE_LCD_V ) + other_flags |= AF_LATIN_HINTS_VERT_SNAP; + + /* + * We adjust stems to full pixels only if we don't use the `light' mode. + */ + if ( mode != FT_RENDER_MODE_LIGHT ) + other_flags |= AF_LATIN_HINTS_STEM_ADJUST; + + if ( mode == FT_RENDER_MODE_MONO ) + other_flags |= AF_LATIN_HINTS_MONO; + + scaler_flags |= AF_SCALER_FLAG_NO_ADVANCE; + + hints->scaler_flags = scaler_flags; + hints->other_flags = other_flags; + + return 0; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** C J K G L Y P H G R I D - F I T T I N G *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* snap a given width in scaled coordinates to one of the */ + /* current standard widths */ + + static FT_Pos + af_cjk_snap_width( AF_Width widths, + FT_Int count, + FT_Pos width ) + { + int n; + FT_Pos best = 64 + 32 + 2; + FT_Pos reference = width; + FT_Pos scaled; + + + for ( n = 0; n < count; n++ ) + { + FT_Pos w; + FT_Pos dist; + + + w = widths[n].cur; + dist = width - w; + if ( dist < 0 ) + dist = -dist; + if ( dist < best ) + { + best = dist; + reference = w; + } + } + + scaled = FT_PIX_ROUND( reference ); + + if ( width >= reference ) + { + if ( width < scaled + 48 ) + width = reference; + } + else + { + if ( width > scaled - 48 ) + width = reference; + } + + return width; + } + + + /* compute the snapped width of a given stem */ + + static FT_Pos + af_cjk_compute_stem_width( AF_GlyphHints hints, + AF_Dimension dim, + FT_Pos width, + AF_Edge_Flags base_flags, + AF_Edge_Flags stem_flags ) + { + AF_LatinMetrics metrics = (AF_LatinMetrics) hints->metrics; + AF_LatinAxis axis = & metrics->axis[dim]; + FT_Pos dist = width; + FT_Int sign = 0; + FT_Int vertical = ( dim == AF_DIMENSION_VERT ); + + FT_UNUSED( base_flags ); + FT_UNUSED( stem_flags ); + + + if ( !AF_LATIN_HINTS_DO_STEM_ADJUST( hints ) ) + return width; + + if ( dist < 0 ) + { + dist = -width; + sign = 1; + } + + if ( ( vertical && !AF_LATIN_HINTS_DO_VERT_SNAP( hints ) ) || + ( !vertical && !AF_LATIN_HINTS_DO_HORZ_SNAP( hints ) ) ) + { + /* smooth hinting process: very lightly quantize the stem width */ + + if ( axis->width_count > 0 ) + { + if ( FT_ABS( dist - axis->widths[0].cur ) < 40 ) + { + dist = axis->widths[0].cur; + if ( dist < 48 ) + dist = 48; + + goto Done_Width; + } + } + + if ( dist < 54 ) + dist += ( 54 - dist ) / 2 ; + else if ( dist < 3 * 64 ) + { + FT_Pos delta; + + + delta = dist & 63; + dist &= -64; + + if ( delta < 10 ) + dist += delta; + else if ( delta < 22 ) + dist += 10; + else if ( delta < 42 ) + dist += delta; + else if ( delta < 54 ) + dist += 54; + else + dist += delta; + } + } + else + { + /* strong hinting process: snap the stem width to integer pixels */ + + dist = af_cjk_snap_width( axis->widths, axis->width_count, dist ); + + if ( vertical ) + { + /* in the case of vertical hinting, always round */ + /* the stem heights to integer pixels */ + + if ( dist >= 64 ) + dist = ( dist + 16 ) & ~63; + else + dist = 64; + } + else + { + if ( AF_LATIN_HINTS_DO_MONO( hints ) ) + { + /* monochrome horizontal hinting: snap widths to integer pixels */ + /* with a different threshold */ + + if ( dist < 64 ) + dist = 64; + else + dist = ( dist + 32 ) & ~63; + } + else + { + /* for horizontal anti-aliased hinting, we adopt a more subtle */ + /* approach: we strengthen small stems, round stems whose size */ + /* is between 1 and 2 pixels to an integer, otherwise nothing */ + + if ( dist < 48 ) + dist = ( dist + 64 ) >> 1; + + else if ( dist < 128 ) + dist = ( dist + 22 ) & ~63; + else + /* round otherwise to prevent color fringes in LCD mode */ + dist = ( dist + 32 ) & ~63; + } + } + } + + Done_Width: + if ( sign ) + dist = -dist; + + return dist; + } + + + /* align one stem edge relative to the previous stem edge */ + + static void + af_cjk_align_linked_edge( AF_GlyphHints hints, + AF_Dimension dim, + AF_Edge base_edge, + AF_Edge stem_edge ) + { + FT_Pos dist = stem_edge->opos - base_edge->opos; + + FT_Pos fitted_width = af_cjk_compute_stem_width( + hints, dim, dist, + (AF_Edge_Flags)base_edge->flags, + (AF_Edge_Flags)stem_edge->flags ); + + + stem_edge->pos = base_edge->pos + fitted_width; + } + + + static void + af_cjk_align_serif_edge( AF_GlyphHints hints, + AF_Edge base, + AF_Edge serif ) + { + FT_UNUSED( hints ); + + serif->pos = base->pos + ( serif->opos - base->opos ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** E D G E H I N T I N G ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + +#define AF_LIGHT_MODE_MAX_HORZ_GAP 9 +#define AF_LIGHT_MODE_MAX_VERT_GAP 15 +#define AF_LIGHT_MODE_MAX_DELTA_ABS 14 + + + static FT_Pos + af_hint_normal_stem( AF_GlyphHints hints, + AF_Edge edge, + AF_Edge edge2, + FT_Pos anchor, + AF_Dimension dim ) + { + FT_Pos org_len, cur_len, org_center; + FT_Pos cur_pos1, cur_pos2; + FT_Pos d_off1, u_off1, d_off2, u_off2, delta; + FT_Pos offset; + FT_Pos threshold = 64; + + + if ( !AF_LATIN_HINTS_DO_STEM_ADJUST( hints ) ) + { + if ( ( edge->flags & AF_EDGE_ROUND ) && + ( edge2->flags & AF_EDGE_ROUND ) ) + { + if ( dim == AF_DIMENSION_VERT ) + threshold = 64 - AF_LIGHT_MODE_MAX_HORZ_GAP; + else + threshold = 64 - AF_LIGHT_MODE_MAX_VERT_GAP; + } + else + { + if ( dim == AF_DIMENSION_VERT ) + threshold = 64 - AF_LIGHT_MODE_MAX_HORZ_GAP / 3; + else + threshold = 64 - AF_LIGHT_MODE_MAX_VERT_GAP / 3; + } + } + + org_len = edge2->opos - edge->opos; + cur_len = af_cjk_compute_stem_width( hints, dim, org_len, + (AF_Edge_Flags)edge->flags, + (AF_Edge_Flags)edge2->flags ); + + org_center = ( edge->opos + edge2->opos ) / 2 + anchor; + cur_pos1 = org_center - cur_len / 2; + cur_pos2 = cur_pos1 + cur_len; + d_off1 = cur_pos1 - FT_PIX_FLOOR( cur_pos1 ); + d_off2 = cur_pos2 - FT_PIX_FLOOR( cur_pos2 ); + u_off1 = 64 - d_off1; + u_off2 = 64 - d_off2; + delta = 0; + + + if ( d_off1 == 0 || d_off2 == 0 ) + goto Exit; + + if ( cur_len <= threshold ) + { + if ( d_off2 < cur_len ) + { + if ( u_off1 <= d_off2 ) + delta = u_off1; + else + delta = -d_off2; + } + + goto Exit; + } + + if ( threshold < 64 ) + { + if ( d_off1 >= threshold || u_off1 >= threshold || + d_off2 >= threshold || u_off2 >= threshold ) + goto Exit; + } + + offset = cur_len % 64; + + if ( offset < 32 ) + { + if ( u_off1 <= offset || d_off2 <= offset ) + goto Exit; + } + else + offset = 64 - threshold; + + d_off1 = threshold - u_off1; + u_off1 = u_off1 - offset; + u_off2 = threshold - d_off2; + d_off2 = d_off2 - offset; + + if ( d_off1 <= u_off1 ) + u_off1 = -d_off1; + + if ( d_off2 <= u_off2 ) + u_off2 = -d_off2; + + if ( FT_ABS( u_off1 ) <= FT_ABS( u_off2 ) ) + delta = u_off1; + else + delta = u_off2; + + Exit: + +#if 1 + if ( !AF_LATIN_HINTS_DO_STEM_ADJUST( hints ) ) + { + if ( delta > AF_LIGHT_MODE_MAX_DELTA_ABS ) + delta = AF_LIGHT_MODE_MAX_DELTA_ABS; + else if ( delta < -AF_LIGHT_MODE_MAX_DELTA_ABS ) + delta = -AF_LIGHT_MODE_MAX_DELTA_ABS; + } +#endif + + cur_pos1 += delta; + + if ( edge->opos < edge2->opos ) + { + edge->pos = cur_pos1; + edge2->pos = cur_pos1 + cur_len; + } + else + { + edge->pos = cur_pos1 + cur_len; + edge2->pos = cur_pos1; + } + + return delta; + } + + + static void + af_cjk_hint_edges( AF_GlyphHints hints, + AF_Dimension dim ) + { + AF_AxisHints axis = &hints->axis[dim]; + AF_Edge edges = axis->edges; + AF_Edge edge_limit = edges + axis->num_edges; + FT_PtrDist n_edges; + AF_Edge edge; + AF_Edge anchor = 0; + FT_Pos delta = 0; + FT_Int skipped = 0; + + + /* now we align all stem edges. */ + for ( edge = edges; edge < edge_limit; edge++ ) + { + AF_Edge edge2; + + + if ( edge->flags & AF_EDGE_DONE ) + continue; + + /* skip all non-stem edges */ + edge2 = edge->link; + if ( !edge2 ) + { + skipped++; + continue; + } + + /* now align the stem */ + + if ( edge2 < edge ) + { + af_cjk_align_linked_edge( hints, dim, edge2, edge ); + edge->flags |= AF_EDGE_DONE; + continue; + } + + if ( dim != AF_DIMENSION_VERT && !anchor ) + { + +#if 0 + if ( fixedpitch ) + { + AF_Edge left = edge; + AF_Edge right = edge_limit - 1; + AF_EdgeRec left1, left2, right1, right2; + FT_Pos target, center1, center2; + FT_Pos delta1, delta2, d1, d2; + + + while ( right > left && !right->link ) + right--; + + left1 = *left; + left2 = *left->link; + right1 = *right->link; + right2 = *right; + + delta = ( ( ( hinter->pp2.x + 32 ) & -64 ) - hinter->pp2.x ) / 2; + target = left->opos + ( right->opos - left->opos ) / 2 + delta - 16; + + delta1 = delta; + delta1 += af_hint_normal_stem( hints, left, left->link, + delta1, 0 ); + + if ( left->link != right ) + af_hint_normal_stem( hints, right->link, right, delta1, 0 ); + + center1 = left->pos + ( right->pos - left->pos ) / 2; + + if ( center1 >= target ) + delta2 = delta - 32; + else + delta2 = delta + 32; + + delta2 += af_hint_normal_stem( hints, &left1, &left2, delta2, 0 ); + + if ( delta1 != delta2 ) + { + if ( left->link != right ) + af_hint_normal_stem( hints, &right1, &right2, delta2, 0 ); + + center2 = left1.pos + ( right2.pos - left1.pos ) / 2; + + d1 = center1 - target; + d2 = center2 - target; + + if ( FT_ABS( d2 ) < FT_ABS( d1 ) ) + { + left->pos = left1.pos; + left->link->pos = left2.pos; + + if ( left->link != right ) + { + right->link->pos = right1.pos; + right->pos = right2.pos; + } + + delta1 = delta2; + } + } + + delta = delta1; + right->link->flags |= AF_EDGE_DONE; + right->flags |= AF_EDGE_DONE; + } + else + +#endif /* 0 */ + + delta = af_hint_normal_stem( hints, edge, edge2, 0, + AF_DIMENSION_HORZ ); + } + else + af_hint_normal_stem( hints, edge, edge2, delta, dim ); + +#if 0 + printf( "stem (%d,%d) adjusted (%.1f,%.1f)\n", + edge - edges, edge2 - edges, + ( edge->pos - edge->opos ) / 64.0, + ( edge2->pos - edge2->opos ) / 64.0 ); +#endif + + anchor = edge; + edge->flags |= AF_EDGE_DONE; + edge2->flags |= AF_EDGE_DONE; + } + + /* make sure that lowercase m's maintain their symmetry */ + + /* In general, lowercase m's have six vertical edges if they are sans */ + /* serif, or twelve if they are with serifs. This implementation is */ + /* based on that assumption, and seems to work very well with most */ + /* faces. However, if for a certain face this assumption is not */ + /* true, the m is just rendered like before. In addition, any stem */ + /* correction will only be applied to symmetrical glyphs (even if the */ + /* glyph is not an m), so the potential for unwanted distortion is */ + /* relatively low. */ + + /* We don't handle horizontal edges since we can't easily assure that */ + /* the third (lowest) stem aligns with the base line; it might end up */ + /* one pixel higher or lower. */ + + n_edges = edge_limit - edges; + if ( dim == AF_DIMENSION_HORZ && ( n_edges == 6 || n_edges == 12 ) ) + { + AF_Edge edge1, edge2, edge3; + FT_Pos dist1, dist2, span; + + + if ( n_edges == 6 ) + { + edge1 = edges; + edge2 = edges + 2; + edge3 = edges + 4; + } + else + { + edge1 = edges + 1; + edge2 = edges + 5; + edge3 = edges + 9; + } + + dist1 = edge2->opos - edge1->opos; + dist2 = edge3->opos - edge2->opos; + + span = dist1 - dist2; + if ( span < 0 ) + span = -span; + + if ( edge1->link == edge1 + 1 && + edge2->link == edge2 + 1 && + edge3->link == edge3 + 1 && span < 8 ) + { + delta = edge3->pos - ( 2 * edge2->pos - edge1->pos ); + edge3->pos -= delta; + if ( edge3->link ) + edge3->link->pos -= delta; + + /* move the serifs along with the stem */ + if ( n_edges == 12 ) + { + ( edges + 8 )->pos -= delta; + ( edges + 11 )->pos -= delta; + } + + edge3->flags |= AF_EDGE_DONE; + if ( edge3->link ) + edge3->link->flags |= AF_EDGE_DONE; + } + } + + if ( !skipped ) + return; + + /* + * now hint the remaining edges (serifs and single) in order + * to complete our processing + */ + for ( edge = edges; edge < edge_limit; edge++ ) + { + if ( edge->flags & AF_EDGE_DONE ) + continue; + + if ( edge->serif ) + { + af_cjk_align_serif_edge( hints, edge->serif, edge ); + edge->flags |= AF_EDGE_DONE; + skipped--; + } + } + + if ( !skipped ) + return; + + for ( edge = edges; edge < edge_limit; edge++ ) + { + AF_Edge before, after; + + + if ( edge->flags & AF_EDGE_DONE ) + continue; + + before = after = edge; + + while ( --before >= edges ) + if ( before->flags & AF_EDGE_DONE ) + break; + + while ( ++after < edge_limit ) + if ( after->flags & AF_EDGE_DONE ) + break; + + if ( before >= edges || after < edge_limit ) + { + if ( before < edges ) + af_cjk_align_serif_edge( hints, after, edge ); + else if ( after >= edge_limit ) + af_cjk_align_serif_edge( hints, before, edge ); + else + { + if ( after->fpos == before->fpos ) + edge->pos = before->pos; + else + edge->pos = before->pos + + FT_MulDiv( edge->fpos - before->fpos, + after->pos - before->pos, + after->fpos - before->fpos ); + } + } + } + } + + + static void + af_cjk_align_edge_points( AF_GlyphHints hints, + AF_Dimension dim ) + { + AF_AxisHints axis = & hints->axis[dim]; + AF_Edge edges = axis->edges; + AF_Edge edge_limit = edges + axis->num_edges; + AF_Edge edge; + FT_Bool snapping; + + + snapping = FT_BOOL( ( dim == AF_DIMENSION_HORZ && + AF_LATIN_HINTS_DO_HORZ_SNAP( hints ) ) || + ( dim == AF_DIMENSION_VERT && + AF_LATIN_HINTS_DO_VERT_SNAP( hints ) ) ); + + for ( edge = edges; edge < edge_limit; edge++ ) + { + /* move the points of each segment */ + /* in each edge to the edge's position */ + AF_Segment seg = edge->first; + + + if ( snapping ) + { + do + { + AF_Point point = seg->first; + + + for (;;) + { + if ( dim == AF_DIMENSION_HORZ ) + { + point->x = edge->pos; + point->flags |= AF_FLAG_TOUCH_X; + } + else + { + point->y = edge->pos; + point->flags |= AF_FLAG_TOUCH_Y; + } + + if ( point == seg->last ) + break; + + point = point->next; + } + + seg = seg->edge_next; + + } while ( seg != edge->first ); + } + else + { + FT_Pos delta = edge->pos - edge->opos; + + + do + { + AF_Point point = seg->first; + + + for (;;) + { + if ( dim == AF_DIMENSION_HORZ ) + { + point->x += delta; + point->flags |= AF_FLAG_TOUCH_X; + } + else + { + point->y += delta; + point->flags |= AF_FLAG_TOUCH_Y; + } + + if ( point == seg->last ) + break; + + point = point->next; + } + + seg = seg->edge_next; + + } while ( seg != edge->first ); + } + } + } + + + FT_LOCAL_DEF( FT_Error ) + af_cjk_hints_apply( AF_GlyphHints hints, + FT_Outline* outline, + AF_LatinMetrics metrics ) + { + FT_Error error; + int dim; + + FT_UNUSED( metrics ); + + + error = af_glyph_hints_reload( hints, outline, 0 ); + if ( error ) + goto Exit; + + /* analyze glyph outline */ + if ( AF_HINTS_DO_HORIZONTAL( hints ) ) + { + error = af_cjk_hints_detect_features( hints, AF_DIMENSION_HORZ ); + if ( error ) + goto Exit; + } + + if ( AF_HINTS_DO_VERTICAL( hints ) ) + { + error = af_cjk_hints_detect_features( hints, AF_DIMENSION_VERT ); + if ( error ) + goto Exit; + } + + /* grid-fit the outline */ + for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) + { + if ( ( dim == AF_DIMENSION_HORZ && AF_HINTS_DO_HORIZONTAL( hints ) ) || + ( dim == AF_DIMENSION_VERT && AF_HINTS_DO_VERTICAL( hints ) ) ) + { + +#ifdef AF_USE_WARPER + if ( dim == AF_DIMENSION_HORZ && + metrics->root.scaler.render_mode == FT_RENDER_MODE_NORMAL ) + { + AF_WarperRec warper; + FT_Fixed scale; + FT_Pos delta; + + + af_warper_compute( &warper, hints, dim, &scale, &delta ); + af_glyph_hints_scale_dim( hints, dim, scale, delta ); + continue; + } +#endif /* AF_USE_WARPER */ + + af_cjk_hint_edges( hints, (AF_Dimension)dim ); + af_cjk_align_edge_points( hints, (AF_Dimension)dim ); + af_glyph_hints_align_strong_points( hints, (AF_Dimension)dim ); + af_glyph_hints_align_weak_points( hints, (AF_Dimension)dim ); + } + } + +#if 0 + af_glyph_hints_dump_points( hints ); + af_glyph_hints_dump_segments( hints ); + af_glyph_hints_dump_edges( hints ); +#endif + + af_glyph_hints_save( hints, outline ); + + Exit: + return error; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** C J K S C R I P T C L A S S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + static const AF_Script_UniRangeRec af_cjk_uniranges[] = + { +#if 0 + AF_UNIRANGE_REC( 0x0100UL, 0xFFFFUL ), /* why this? */ +#endif + AF_UNIRANGE_REC( 0x2E80UL, 0x2EFFUL ), /* CJK Radicals Supplement */ + AF_UNIRANGE_REC( 0x2F00UL, 0x2FDFUL ), /* Kangxi Radicals */ + AF_UNIRANGE_REC( 0x3000UL, 0x303FUL ), /* CJK Symbols and Punctuation */ + AF_UNIRANGE_REC( 0x3040UL, 0x309FUL ), /* Hiragana */ + AF_UNIRANGE_REC( 0x30A0UL, 0x30FFUL ), /* Katakana */ + AF_UNIRANGE_REC( 0x3100UL, 0x312FUL ), /* Bopomofo */ + AF_UNIRANGE_REC( 0x3130UL, 0x318FUL ), /* Hangul Compatibility Jamo */ + AF_UNIRANGE_REC( 0x31A0UL, 0x31BFUL ), /* Bopomofo Extended */ + AF_UNIRANGE_REC( 0x31C0UL, 0x31EFUL ), /* CJK Strokes */ + AF_UNIRANGE_REC( 0x31F0UL, 0x31FFUL ), /* Katakana Phonetic Extensions */ + AF_UNIRANGE_REC( 0x3200UL, 0x32FFUL ), /* Enclosed CJK Letters and Months */ + AF_UNIRANGE_REC( 0x3300UL, 0x33FFUL ), /* CJK Compatibility */ + AF_UNIRANGE_REC( 0x3400UL, 0x4DBFUL ), /* CJK Unified Ideographs Extension A */ + AF_UNIRANGE_REC( 0x4DC0UL, 0x4DFFUL ), /* Yijing Hexagram Symbols */ + AF_UNIRANGE_REC( 0x4E00UL, 0x9FFFUL ), /* CJK Unified Ideographs */ + AF_UNIRANGE_REC( 0xF900UL, 0xFAFFUL ), /* CJK Compatibility Ideographs */ + AF_UNIRANGE_REC( 0xFE30UL, 0xFE4FUL ), /* CJK Compatibility Forms */ + AF_UNIRANGE_REC( 0xFF00UL, 0xFFEFUL ), /* Halfwidth and Fullwidth Forms */ + AF_UNIRANGE_REC( 0x20000UL, 0x2A6DFUL ), /* CJK Unified Ideographs Extension B */ + AF_UNIRANGE_REC( 0x2F800UL, 0x2FA1FUL ), /* CJK Compatibility Ideographs Supplement */ + AF_UNIRANGE_REC( 0UL, 0UL ) + }; + + + AF_DEFINE_SCRIPT_CLASS(af_cjk_script_class, + AF_SCRIPT_CJK, + af_cjk_uniranges, + + sizeof( AF_LatinMetricsRec ), + + (AF_Script_InitMetricsFunc) af_cjk_metrics_init, + (AF_Script_ScaleMetricsFunc)af_cjk_metrics_scale, + (AF_Script_DoneMetricsFunc) NULL, + + (AF_Script_InitHintsFunc) af_cjk_hints_init, + (AF_Script_ApplyHintsFunc) af_cjk_hints_apply + ) + +#else /* !AF_CONFIG_OPTION_CJK */ + + static const AF_Script_UniRangeRec af_cjk_uniranges[] = + { + AF_UNIRANGE_REC( 0UL, 0UL ) + }; + + + AF_DEFINE_SCRIPT_CLASS(af_cjk_script_class, + AF_SCRIPT_CJK, + af_cjk_uniranges, + + sizeof( AF_LatinMetricsRec ), + + (AF_Script_InitMetricsFunc) NULL, + (AF_Script_ScaleMetricsFunc)NULL, + (AF_Script_DoneMetricsFunc) NULL, + + (AF_Script_InitHintsFunc) NULL, + (AF_Script_ApplyHintsFunc) NULL + ) + +#endif /* !AF_CONFIG_OPTION_CJK */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/autofit/afcjk.h b/mod/pub.mod/freetype.mod/src/autofit/afcjk.h new file mode 100644 index 0000000..0b20d4a --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/autofit/afcjk.h @@ -0,0 +1,57 @@ +/***************************************************************************/ +/* */ +/* afcjk.h */ +/* */ +/* Auto-fitter hinting routines for CJK script (specification). */ +/* */ +/* Copyright 2006, 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __AFCJK_H__ +#define __AFCJK_H__ + +#include "afhints.h" + + +FT_BEGIN_HEADER + + + /* the CJK-specific script class */ + + AF_DECLARE_SCRIPT_CLASS(af_cjk_script_class) + + + FT_LOCAL( FT_Error ) + af_cjk_metrics_init( AF_LatinMetrics metrics, + FT_Face face ); + + FT_LOCAL( void ) + af_cjk_metrics_scale( AF_LatinMetrics metrics, + AF_Scaler scaler ); + + FT_LOCAL( FT_Error ) + af_cjk_hints_init( AF_GlyphHints hints, + AF_LatinMetrics metrics ); + + FT_LOCAL( FT_Error ) + af_cjk_hints_apply( AF_GlyphHints hints, + FT_Outline* outline, + AF_LatinMetrics metrics ); + +/* */ + +FT_END_HEADER + +#endif /* __AFCJK_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/autofit/afdummy.c b/mod/pub.mod/freetype.mod/src/autofit/afdummy.c new file mode 100644 index 0000000..42b2fcb --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/autofit/afdummy.c @@ -0,0 +1,60 @@ +/***************************************************************************/ +/* */ +/* afdummy.c */ +/* */ +/* Auto-fitter dummy routines to be used if no hinting should be */ +/* performed (body). */ +/* */ +/* Copyright 2003, 2004, 2005 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include "afdummy.h" +#include "afhints.h" + + + static FT_Error + af_dummy_hints_init( AF_GlyphHints hints, + AF_ScriptMetrics metrics ) + { + af_glyph_hints_rescale( hints, + metrics ); + return 0; + } + + + static FT_Error + af_dummy_hints_apply( AF_GlyphHints hints, + FT_Outline* outline ) + { + FT_UNUSED( hints ); + FT_UNUSED( outline ); + + return 0; + } + + + AF_DEFINE_SCRIPT_CLASS(af_dummy_script_class, + AF_SCRIPT_NONE, + NULL, + + sizeof( AF_ScriptMetricsRec ), + + (AF_Script_InitMetricsFunc) NULL, + (AF_Script_ScaleMetricsFunc)NULL, + (AF_Script_DoneMetricsFunc) NULL, + + (AF_Script_InitHintsFunc) af_dummy_hints_init, + (AF_Script_ApplyHintsFunc) af_dummy_hints_apply + ) + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/autofit/afdummy.h b/mod/pub.mod/freetype.mod/src/autofit/afdummy.h new file mode 100644 index 0000000..b69ef43 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/autofit/afdummy.h @@ -0,0 +1,42 @@ +/***************************************************************************/ +/* */ +/* afdummy.h */ +/* */ +/* Auto-fitter dummy routines to be used if no hinting should be */ +/* performed (specification). */ +/* */ +/* Copyright 2003, 2004, 2005 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __AFDUMMY_H__ +#define __AFDUMMY_H__ + +#include "aftypes.h" + + +FT_BEGIN_HEADER + + /* A dummy script metrics class used when no hinting should + * be performed. This is the default for non-latin glyphs! + */ + + AF_DECLARE_SCRIPT_CLASS(af_dummy_script_class) + +/* */ + +FT_END_HEADER + + +#endif /* __AFDUMMY_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/autofit/aferrors.h b/mod/pub.mod/freetype.mod/src/autofit/aferrors.h new file mode 100644 index 0000000..c2ed5fe --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/autofit/aferrors.h @@ -0,0 +1,40 @@ +/***************************************************************************/ +/* */ +/* aferrors.h */ +/* */ +/* Autofitter error codes (specification only). */ +/* */ +/* Copyright 2005 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file is used to define the Autofitter error enumeration */ + /* constants. */ + /* */ + /*************************************************************************/ + +#ifndef __AFERRORS_H__ +#define __AFERRORS_H__ + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#define FT_ERR_PREFIX AF_Err_ +#define FT_ERR_BASE FT_Mod_Err_Autofit + +#include FT_ERRORS_H + +#endif /* __AFERRORS_H__ */ + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/autofit/afglobal.c b/mod/pub.mod/freetype.mod/src/autofit/afglobal.c new file mode 100644 index 0000000..ac29361 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/autofit/afglobal.c @@ -0,0 +1,320 @@ +/***************************************************************************/ +/* */ +/* afglobal.c */ +/* */ +/* Auto-fitter routines to compute global hinting values (body). */ +/* */ +/* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include "afglobal.h" +#include "afdummy.h" +#include "aflatin.h" +#include "afcjk.h" +#include "afindic.h" +#include "afpic.h" + +#include "aferrors.h" + +#ifdef FT_OPTION_AUTOFIT2 +#include "aflatin2.h" +#endif + +#ifndef FT_CONFIG_OPTION_PIC + +/* when updating this table, don't forget to update + AF_SCRIPT_CLASSES_COUNT and autofit_module_class_pic_init */ + + /* populate this list when you add new scripts */ + static AF_ScriptClass const af_script_classes[] = + { + &af_dummy_script_class, +#ifdef FT_OPTION_AUTOFIT2 + &af_latin2_script_class, +#endif + &af_latin_script_class, + &af_cjk_script_class, + &af_indic_script_class, + NULL /* do not remove */ + }; + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* index of default script in `af_script_classes' */ +#define AF_SCRIPT_LIST_DEFAULT 2 + /* a bit mask indicating an uncovered glyph */ +#define AF_SCRIPT_LIST_NONE 0x7F + /* if this flag is set, we have an ASCII digit */ +#define AF_DIGIT 0x80 + + + /* + * Note that glyph_scripts[] is used to map each glyph into + * an index into the `af_script_classes' array. + * + */ + typedef struct AF_FaceGlobalsRec_ + { + FT_Face face; + FT_Long glyph_count; /* same as face->num_glyphs */ + FT_Byte* glyph_scripts; + + AF_ScriptMetrics metrics[AF_SCRIPT_MAX]; + + } AF_FaceGlobalsRec; + + + /* Compute the script index of each glyph within a given face. */ + + static FT_Error + af_face_globals_compute_script_coverage( AF_FaceGlobals globals ) + { + FT_Error error = AF_Err_Ok; + FT_Face face = globals->face; + FT_CharMap old_charmap = face->charmap; + FT_Byte* gscripts = globals->glyph_scripts; + FT_UInt ss, i; + + + /* the value 255 means `uncovered glyph' */ + FT_MEM_SET( globals->glyph_scripts, + AF_SCRIPT_LIST_NONE, + globals->glyph_count ); + + error = FT_Select_Charmap( face, FT_ENCODING_UNICODE ); + if ( error ) + { + /* + * Ignore this error; we simply use the default script. + * XXX: Shouldn't we rather disable hinting? + */ + error = AF_Err_Ok; + goto Exit; + } + + /* scan each script in a Unicode charmap */ + for ( ss = 0; AF_SCRIPT_CLASSES_GET[ss]; ss++ ) + { + AF_ScriptClass clazz = AF_SCRIPT_CLASSES_GET[ss]; + AF_Script_UniRange range; + + + if ( clazz->script_uni_ranges == NULL ) + continue; + + /* + * Scan all unicode points in the range and set the corresponding + * glyph script index. + */ + for ( range = clazz->script_uni_ranges; range->first != 0; range++ ) + { + FT_ULong charcode = range->first; + FT_UInt gindex; + + + gindex = FT_Get_Char_Index( face, charcode ); + + if ( gindex != 0 && + gindex < (FT_ULong)globals->glyph_count && + gscripts[gindex] == AF_SCRIPT_LIST_NONE ) + { + gscripts[gindex] = (FT_Byte)ss; + } + + for (;;) + { + charcode = FT_Get_Next_Char( face, charcode, &gindex ); + + if ( gindex == 0 || charcode > range->last ) + break; + + if ( gindex < (FT_ULong)globals->glyph_count && + gscripts[gindex] == AF_SCRIPT_LIST_NONE ) + { + gscripts[gindex] = (FT_Byte)ss; + } + } + } + } + + /* mark ASCII digits */ + for ( i = 0x30; i <= 0x39; i++ ) + { + FT_UInt gindex = FT_Get_Char_Index( face, i ); + + + if ( gindex != 0 && gindex < (FT_ULong)globals->glyph_count ) + gscripts[gindex] |= AF_DIGIT; + } + + Exit: + /* + * By default, all uncovered glyphs are set to the latin script. + * XXX: Shouldn't we disable hinting or do something similar? + */ + { + FT_Long nn; + + + for ( nn = 0; nn < globals->glyph_count; nn++ ) + { + if ( gscripts[nn] == AF_SCRIPT_LIST_NONE ) + gscripts[nn] = AF_SCRIPT_LIST_DEFAULT; + } + } + + FT_Set_Charmap( face, old_charmap ); + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + af_face_globals_new( FT_Face face, + AF_FaceGlobals *aglobals ) + { + FT_Error error; + FT_Memory memory; + AF_FaceGlobals globals; + + + memory = face->memory; + + if ( !FT_ALLOC( globals, sizeof ( *globals ) + + face->num_glyphs * sizeof ( FT_Byte ) ) ) + { + globals->face = face; + globals->glyph_count = face->num_glyphs; + globals->glyph_scripts = (FT_Byte*)( globals + 1 ); + + error = af_face_globals_compute_script_coverage( globals ); + if ( error ) + { + af_face_globals_free( globals ); + globals = NULL; + } + } + + *aglobals = globals; + return error; + } + + + FT_LOCAL_DEF( void ) + af_face_globals_free( AF_FaceGlobals globals ) + { + if ( globals ) + { + FT_Memory memory = globals->face->memory; + FT_UInt nn; + + + for ( nn = 0; nn < AF_SCRIPT_MAX; nn++ ) + { + if ( globals->metrics[nn] ) + { + AF_ScriptClass clazz = AF_SCRIPT_CLASSES_GET[nn]; + + + FT_ASSERT( globals->metrics[nn]->clazz == clazz ); + + if ( clazz->script_metrics_done ) + clazz->script_metrics_done( globals->metrics[nn] ); + + FT_FREE( globals->metrics[nn] ); + } + } + + globals->glyph_count = 0; + globals->glyph_scripts = NULL; /* no need to free this one! */ + globals->face = NULL; + + FT_FREE( globals ); + } + } + + + FT_LOCAL_DEF( FT_Error ) + af_face_globals_get_metrics( AF_FaceGlobals globals, + FT_UInt gindex, + FT_UInt options, + AF_ScriptMetrics *ametrics ) + { + AF_ScriptMetrics metrics = NULL; + FT_UInt gidx; + AF_ScriptClass clazz; + FT_UInt script = options & 15; + const FT_Offset script_max = sizeof ( AF_SCRIPT_CLASSES_GET ) / + sizeof ( AF_SCRIPT_CLASSES_GET[0] ); + FT_Error error = AF_Err_Ok; + + + if ( gindex >= (FT_ULong)globals->glyph_count ) + { + error = AF_Err_Invalid_Argument; + goto Exit; + } + + gidx = script; + if ( gidx == 0 || gidx + 1 >= script_max ) + gidx = globals->glyph_scripts[gindex] & AF_SCRIPT_LIST_NONE; + + clazz = AF_SCRIPT_CLASSES_GET[gidx]; + if ( script == 0 ) + script = clazz->script; + + metrics = globals->metrics[clazz->script]; + if ( metrics == NULL ) + { + /* create the global metrics object when needed */ + FT_Memory memory = globals->face->memory; + + + if ( FT_ALLOC( metrics, clazz->script_metrics_size ) ) + goto Exit; + + metrics->clazz = clazz; + + if ( clazz->script_metrics_init ) + { + error = clazz->script_metrics_init( metrics, globals->face ); + if ( error ) + { + if ( clazz->script_metrics_done ) + clazz->script_metrics_done( metrics ); + + FT_FREE( metrics ); + goto Exit; + } + } + + globals->metrics[clazz->script] = metrics; + } + + Exit: + *ametrics = metrics; + + return error; + } + + + FT_LOCAL_DEF( FT_Bool ) + af_face_globals_is_digit( AF_FaceGlobals globals, + FT_UInt gindex ) + { + if ( gindex < (FT_ULong)globals->glyph_count ) + return (FT_Bool)( globals->glyph_scripts[gindex] & AF_DIGIT ); + + return (FT_Bool)0; + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/autofit/afglobal.h b/mod/pub.mod/freetype.mod/src/autofit/afglobal.h new file mode 100644 index 0000000..2a68e19 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/autofit/afglobal.h @@ -0,0 +1,71 @@ +/***************************************************************************/ +/* */ +/* afglobal.h */ +/* */ +/* Auto-fitter routines to compute global hinting values */ +/* (specification). */ +/* */ +/* Copyright 2003, 2004, 2005, 2007, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __AF_GLOBAL_H__ +#define __AF_GLOBAL_H__ + + +#include "aftypes.h" + + +FT_BEGIN_HEADER + + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** F A C E G L O B A L S *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + + + /* + * model the global hints data for a given face, decomposed into + * script-specific items + */ + typedef struct AF_FaceGlobalsRec_* AF_FaceGlobals; + + + FT_LOCAL( FT_Error ) + af_face_globals_new( FT_Face face, + AF_FaceGlobals *aglobals ); + + FT_LOCAL( FT_Error ) + af_face_globals_get_metrics( AF_FaceGlobals globals, + FT_UInt gindex, + FT_UInt options, + AF_ScriptMetrics *ametrics ); + + FT_LOCAL( void ) + af_face_globals_free( AF_FaceGlobals globals ); + + FT_LOCAL_DEF( FT_Bool ) + af_face_globals_is_digit( AF_FaceGlobals globals, + FT_UInt gindex ); + + /* */ + + +FT_END_HEADER + +#endif /* __AF_GLOBALS_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/autofit/afhints.c b/mod/pub.mod/freetype.mod/src/autofit/afhints.c new file mode 100644 index 0000000..fe38fba --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/autofit/afhints.c @@ -0,0 +1,1265 @@ +/***************************************************************************/ +/* */ +/* afhints.c */ +/* */ +/* Auto-fitter hinting routines (body). */ +/* */ +/* Copyright 2003, 2004, 2005, 2006, 2007, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include "afhints.h" +#include "aferrors.h" +#include FT_INTERNAL_CALC_H + + + FT_LOCAL_DEF( FT_Error ) + af_axis_hints_new_segment( AF_AxisHints axis, + FT_Memory memory, + AF_Segment *asegment ) + { + FT_Error error = AF_Err_Ok; + AF_Segment segment = NULL; + + + if ( axis->num_segments >= axis->max_segments ) + { + FT_Int old_max = axis->max_segments; + FT_Int new_max = old_max; + FT_Int big_max = (FT_Int)( FT_INT_MAX / sizeof ( *segment ) ); + + + if ( old_max >= big_max ) + { + error = AF_Err_Out_Of_Memory; + goto Exit; + } + + new_max += ( new_max >> 2 ) + 4; + if ( new_max < old_max || new_max > big_max ) + new_max = big_max; + + if ( FT_RENEW_ARRAY( axis->segments, old_max, new_max ) ) + goto Exit; + + axis->max_segments = new_max; + } + + segment = axis->segments + axis->num_segments++; + + Exit: + *asegment = segment; + return error; + } + + + FT_LOCAL( FT_Error ) + af_axis_hints_new_edge( AF_AxisHints axis, + FT_Int fpos, + AF_Direction dir, + FT_Memory memory, + AF_Edge *aedge ) + { + FT_Error error = AF_Err_Ok; + AF_Edge edge = NULL; + AF_Edge edges; + + + if ( axis->num_edges >= axis->max_edges ) + { + FT_Int old_max = axis->max_edges; + FT_Int new_max = old_max; + FT_Int big_max = (FT_Int)( FT_INT_MAX / sizeof ( *edge ) ); + + + if ( old_max >= big_max ) + { + error = AF_Err_Out_Of_Memory; + goto Exit; + } + + new_max += ( new_max >> 2 ) + 4; + if ( new_max < old_max || new_max > big_max ) + new_max = big_max; + + if ( FT_RENEW_ARRAY( axis->edges, old_max, new_max ) ) + goto Exit; + + axis->max_edges = new_max; + } + + edges = axis->edges; + edge = edges + axis->num_edges; + + while ( edge > edges ) + { + if ( edge[-1].fpos < fpos ) + break; + + /* we want the edge with same position and minor direction */ + /* to appear before those in the major one in the list */ + if ( edge[-1].fpos == fpos && dir == axis->major_dir ) + break; + + edge[0] = edge[-1]; + edge--; + } + + axis->num_edges++; + + FT_ZERO( edge ); + edge->fpos = (FT_Short)fpos; + edge->dir = (FT_Char)dir; + + Exit: + *aedge = edge; + return error; + } + + +#ifdef AF_DEBUG + +#include FT_CONFIG_STANDARD_LIBRARY_H + + static const char* + af_dir_str( AF_Direction dir ) + { + const char* result; + + + switch ( dir ) + { + case AF_DIR_UP: + result = "up"; + break; + case AF_DIR_DOWN: + result = "down"; + break; + case AF_DIR_LEFT: + result = "left"; + break; + case AF_DIR_RIGHT: + result = "right"; + break; + default: + result = "none"; + } + + return result; + } + + +#define AF_INDEX_NUM( ptr, base ) ( (ptr) ? ( (ptr) - (base) ) : -1 ) + + + void + af_glyph_hints_dump_points( AF_GlyphHints hints ) + { + AF_Point points = hints->points; + AF_Point limit = points + hints->num_points; + AF_Point point; + + + printf( "Table of points:\n" ); + printf( " [ index | xorg | yorg | xscale | yscale " + "| xfit | yfit | flags ]\n" ); + + for ( point = points; point < limit; point++ ) + { + printf( " [ %5d | %5d | %5d | %-5.2f | %-5.2f " + "| %-5.2f | %-5.2f | %c%c%c%c%c%c ]\n", + point - points, + point->fx, + point->fy, + point->ox/64.0, + point->oy/64.0, + point->x/64.0, + point->y/64.0, + ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) ? 'w' : ' ', + ( point->flags & AF_FLAG_INFLECTION ) ? 'i' : ' ', + ( point->flags & AF_FLAG_EXTREMA_X ) ? '<' : ' ', + ( point->flags & AF_FLAG_EXTREMA_Y ) ? 'v' : ' ', + ( point->flags & AF_FLAG_ROUND_X ) ? '(' : ' ', + ( point->flags & AF_FLAG_ROUND_Y ) ? 'u' : ' '); + } + printf( "\n" ); + } + + + static const char* + af_edge_flags_to_string( AF_Edge_Flags flags ) + { + static char temp[32]; + int pos = 0; + + + if ( flags & AF_EDGE_ROUND ) + { + ft_memcpy( temp + pos, "round", 5 ); + pos += 5; + } + if ( flags & AF_EDGE_SERIF ) + { + if ( pos > 0 ) + temp[pos++] = ' '; + ft_memcpy( temp + pos, "serif", 5 ); + pos += 5; + } + if ( pos == 0 ) + return "normal"; + + temp[pos] = 0; + + return temp; + } + + + /* A function to dump the array of linked segments. */ + void + af_glyph_hints_dump_segments( AF_GlyphHints hints ) + { + FT_Int dimension; + + + for ( dimension = 1; dimension >= 0; dimension-- ) + { + AF_AxisHints axis = &hints->axis[dimension]; + AF_Segment segments = axis->segments; + AF_Segment limit = segments + axis->num_segments; + AF_Segment seg; + + + printf ( "Table of %s segments:\n", + dimension == AF_DIMENSION_HORZ ? "vertical" : "horizontal" ); + printf ( " [ index | pos | dir | link | serif |" + " height | extra | flags ]\n" ); + + for ( seg = segments; seg < limit; seg++ ) + { + printf ( " [ %5d | %5.2g | %5s | %4d | %5d | %5d | %5d | %s ]\n", + seg - segments, + dimension == AF_DIMENSION_HORZ ? (int)seg->first->ox / 64.0 + : (int)seg->first->oy / 64.0, + af_dir_str( (AF_Direction)seg->dir ), + AF_INDEX_NUM( seg->link, segments ), + AF_INDEX_NUM( seg->serif, segments ), + seg->height, + seg->height - ( seg->max_coord - seg->min_coord ), + af_edge_flags_to_string( seg->flags ) ); + } + printf( "\n" ); + } + } + + + void + af_glyph_hints_dump_edges( AF_GlyphHints hints ) + { + FT_Int dimension; + + + for ( dimension = 1; dimension >= 0; dimension-- ) + { + AF_AxisHints axis = &hints->axis[dimension]; + AF_Edge edges = axis->edges; + AF_Edge limit = edges + axis->num_edges; + AF_Edge edge; + + + /* + * note: AF_DIMENSION_HORZ corresponds to _vertical_ edges + * since they have constant a X coordinate. + */ + printf ( "Table of %s edges:\n", + dimension == AF_DIMENSION_HORZ ? "vertical" : "horizontal" ); + printf ( " [ index | pos | dir | link |" + " serif | blue | opos | pos | flags ]\n" ); + + for ( edge = edges; edge < limit; edge++ ) + { + printf ( " [ %5d | %5.2g | %5s | %4d |" + " %5d | %c | %5.2f | %5.2f | %s ]\n", + edge - edges, + (int)edge->opos / 64.0, + af_dir_str( (AF_Direction)edge->dir ), + AF_INDEX_NUM( edge->link, edges ), + AF_INDEX_NUM( edge->serif, edges ), + edge->blue_edge ? 'y' : 'n', + edge->opos / 64.0, + edge->pos / 64.0, + af_edge_flags_to_string( edge->flags ) ); + } + printf( "\n" ); + } + } + +#else /* !AF_DEBUG */ + + /* these empty stubs are only used to link the `ftgrid' test program */ + /* when debugging is disabled */ + + void + af_glyph_hints_dump_points( AF_GlyphHints hints ) + { + FT_UNUSED( hints ); + } + + + void + af_glyph_hints_dump_segments( AF_GlyphHints hints ) + { + FT_UNUSED( hints ); + } + + + void + af_glyph_hints_dump_edges( AF_GlyphHints hints ) + { + FT_UNUSED( hints ); + } + +#endif /* !AF_DEBUG */ + + + /* compute the direction value of a given vector */ + FT_LOCAL_DEF( AF_Direction ) + af_direction_compute( FT_Pos dx, + FT_Pos dy ) + { + FT_Pos ll, ss; /* long and short arm lengths */ + AF_Direction dir; /* candidate direction */ + + + if ( dy >= dx ) + { + if ( dy >= -dx ) + { + dir = AF_DIR_UP; + ll = dy; + ss = dx; + } + else + { + dir = AF_DIR_LEFT; + ll = -dx; + ss = dy; + } + } + else /* dy < dx */ + { + if ( dy >= -dx ) + { + dir = AF_DIR_RIGHT; + ll = dx; + ss = dy; + } + else + { + dir = AF_DIR_DOWN; + ll = dy; + ss = dx; + } + } + + ss *= 14; + if ( FT_ABS( ll ) <= FT_ABS( ss ) ) + dir = AF_DIR_NONE; + + return dir; + } + + + /* compute all inflex points in a given glyph */ + + static void + af_glyph_hints_compute_inflections( AF_GlyphHints hints ) + { + AF_Point* contour = hints->contours; + AF_Point* contour_limit = contour + hints->num_contours; + + + /* do each contour separately */ + for ( ; contour < contour_limit; contour++ ) + { + AF_Point point = contour[0]; + AF_Point first = point; + AF_Point start = point; + AF_Point end = point; + AF_Point before; + AF_Point after; + FT_Pos in_x, in_y, out_x, out_y; + AF_Angle orient_prev, orient_cur; + FT_Int finished = 0; + + + /* compute first segment in contour */ + first = point; + + start = end = first; + do + { + end = end->next; + if ( end == first ) + goto Skip; + + in_x = end->fx - start->fx; + in_y = end->fy - start->fy; + + } while ( in_x == 0 && in_y == 0 ); + + /* extend the segment start whenever possible */ + before = start; + do + { + do + { + start = before; + before = before->prev; + if ( before == first ) + goto Skip; + + out_x = start->fx - before->fx; + out_y = start->fy - before->fy; + + } while ( out_x == 0 && out_y == 0 ); + + orient_prev = ft_corner_orientation( in_x, in_y, out_x, out_y ); + + } while ( orient_prev == 0 ); + + first = start; + + in_x = out_x; + in_y = out_y; + + /* now process all segments in the contour */ + do + { + /* first, extend current segment's end whenever possible */ + after = end; + do + { + do + { + end = after; + after = after->next; + if ( after == first ) + finished = 1; + + out_x = after->fx - end->fx; + out_y = after->fy - end->fy; + + } while ( out_x == 0 && out_y == 0 ); + + orient_cur = ft_corner_orientation( in_x, in_y, out_x, out_y ); + + } while ( orient_cur == 0 ); + + if ( ( orient_prev + orient_cur ) == 0 ) + { + /* we have an inflection point here */ + do + { + start->flags |= AF_FLAG_INFLECTION; + start = start->next; + + } while ( start != end ); + + start->flags |= AF_FLAG_INFLECTION; + } + + start = end; + end = after; + + orient_prev = orient_cur; + in_x = out_x; + in_y = out_y; + + } while ( !finished ); + + Skip: + ; + } + } + + + FT_LOCAL_DEF( void ) + af_glyph_hints_init( AF_GlyphHints hints, + FT_Memory memory ) + { + FT_ZERO( hints ); + hints->memory = memory; + } + + + FT_LOCAL_DEF( void ) + af_glyph_hints_done( AF_GlyphHints hints ) + { + if ( hints && hints->memory ) + { + FT_Memory memory = hints->memory; + int dim; + + + /* + * note that we don't need to free the segment and edge + * buffers, since they are really within the hints->points array + */ + for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) + { + AF_AxisHints axis = &hints->axis[dim]; + + + axis->num_segments = 0; + axis->max_segments = 0; + FT_FREE( axis->segments ); + + axis->num_edges = 0; + axis->max_edges = 0; + FT_FREE( axis->edges ); + } + + FT_FREE( hints->contours ); + hints->max_contours = 0; + hints->num_contours = 0; + + FT_FREE( hints->points ); + hints->num_points = 0; + hints->max_points = 0; + + hints->memory = NULL; + } + } + + + FT_LOCAL_DEF( void ) + af_glyph_hints_rescale( AF_GlyphHints hints, + AF_ScriptMetrics metrics ) + { + hints->metrics = metrics; + hints->scaler_flags = metrics->scaler.flags; + } + + + FT_LOCAL_DEF( FT_Error ) + af_glyph_hints_reload( AF_GlyphHints hints, + FT_Outline* outline, + FT_Bool get_inflections ) + { + FT_Error error = AF_Err_Ok; + AF_Point points; + FT_UInt old_max, new_max; + FT_Fixed x_scale = hints->x_scale; + FT_Fixed y_scale = hints->y_scale; + FT_Pos x_delta = hints->x_delta; + FT_Pos y_delta = hints->y_delta; + FT_Memory memory = hints->memory; + + + hints->num_points = 0; + hints->num_contours = 0; + + hints->axis[0].num_segments = 0; + hints->axis[0].num_edges = 0; + hints->axis[1].num_segments = 0; + hints->axis[1].num_edges = 0; + + /* first of all, reallocate the contours array when necessary */ + new_max = (FT_UInt)outline->n_contours; + old_max = hints->max_contours; + if ( new_max > old_max ) + { + new_max = ( new_max + 3 ) & ~3; + + if ( FT_RENEW_ARRAY( hints->contours, old_max, new_max ) ) + goto Exit; + + hints->max_contours = new_max; + } + + /* + * then reallocate the points arrays if necessary -- + * note that we reserve two additional point positions, used to + * hint metrics appropriately + */ + new_max = (FT_UInt)( outline->n_points + 2 ); + old_max = hints->max_points; + if ( new_max > old_max ) + { + new_max = ( new_max + 2 + 7 ) & ~7; + + if ( FT_RENEW_ARRAY( hints->points, old_max, new_max ) ) + goto Exit; + + hints->max_points = new_max; + } + + hints->num_points = outline->n_points; + hints->num_contours = outline->n_contours; + + /* We can't rely on the value of `FT_Outline.flags' to know the fill */ + /* direction used for a glyph, given that some fonts are broken (e.g., */ + /* the Arphic ones). We thus recompute it each time we need to. */ + /* */ + hints->axis[AF_DIMENSION_HORZ].major_dir = AF_DIR_UP; + hints->axis[AF_DIMENSION_VERT].major_dir = AF_DIR_LEFT; + + if ( FT_Outline_Get_Orientation( outline ) == FT_ORIENTATION_POSTSCRIPT ) + { + hints->axis[AF_DIMENSION_HORZ].major_dir = AF_DIR_DOWN; + hints->axis[AF_DIMENSION_VERT].major_dir = AF_DIR_RIGHT; + } + + hints->x_scale = x_scale; + hints->y_scale = y_scale; + hints->x_delta = x_delta; + hints->y_delta = y_delta; + + hints->xmin_delta = 0; + hints->xmax_delta = 0; + + points = hints->points; + if ( hints->num_points == 0 ) + goto Exit; + + { + AF_Point point; + AF_Point point_limit = points + hints->num_points; + + + /* compute coordinates & Bezier flags, next and prev */ + { + FT_Vector* vec = outline->points; + char* tag = outline->tags; + AF_Point first = points; + AF_Point end = points + outline->contours[0]; + AF_Point prev = end; + FT_Int contour_index = 0; + + + FT_UNUSED( first ); + for ( point = points; point < point_limit; point++, vec++, tag++ ) + { + point->fx = (FT_Short)vec->x; + point->fy = (FT_Short)vec->y; + point->ox = point->x = FT_MulFix( vec->x, x_scale ) + x_delta; + point->oy = point->y = FT_MulFix( vec->y, y_scale ) + y_delta; + + switch ( FT_CURVE_TAG( *tag ) ) + { + case FT_CURVE_TAG_CONIC: + point->flags = AF_FLAG_CONIC; + break; + case FT_CURVE_TAG_CUBIC: + point->flags = AF_FLAG_CUBIC; + break; + default: + point->flags = 0; + } + + point->prev = prev; + prev->next = point; + prev = point; + + if ( point == end ) + { + if ( ++contour_index < outline->n_contours ) + { + first = point + 1; + end = points + outline->contours[contour_index]; + prev = end; + } + } + } + } + + /* set-up the contours array */ + { + AF_Point* contour = hints->contours; + AF_Point* contour_limit = contour + hints->num_contours; + short* end = outline->contours; + short idx = 0; + + + for ( ; contour < contour_limit; contour++, end++ ) + { + contour[0] = points + idx; + idx = (short)( end[0] + 1 ); + } + } + + /* compute directions of in & out vectors */ + { + AF_Point first = points; + AF_Point prev = NULL; + FT_Pos in_x = 0; + FT_Pos in_y = 0; + AF_Direction in_dir = AF_DIR_NONE; + + + for ( point = points; point < point_limit; point++ ) + { + AF_Point next; + FT_Pos out_x, out_y; + + + if ( point == first ) + { + prev = first->prev; + in_x = first->fx - prev->fx; + in_y = first->fy - prev->fy; + in_dir = af_direction_compute( in_x, in_y ); + first = prev + 1; + } + + point->in_dir = (FT_Char)in_dir; + + next = point->next; + out_x = next->fx - point->fx; + out_y = next->fy - point->fy; + + in_dir = af_direction_compute( out_x, out_y ); + point->out_dir = (FT_Char)in_dir; + + if ( point->flags & ( AF_FLAG_CONIC | AF_FLAG_CUBIC ) ) + { + Is_Weak_Point: + point->flags |= AF_FLAG_WEAK_INTERPOLATION; + } + else if ( point->out_dir == point->in_dir ) + { + if ( point->out_dir != AF_DIR_NONE ) + goto Is_Weak_Point; + + if ( ft_corner_is_flat( in_x, in_y, out_x, out_y ) ) + goto Is_Weak_Point; + } + else if ( point->in_dir == -point->out_dir ) + goto Is_Weak_Point; + + in_x = out_x; + in_y = out_y; + prev = point; + } + } + } + + /* compute inflection points -- */ + /* disabled due to no longer perceived benefits */ + if ( 0 && get_inflections ) + af_glyph_hints_compute_inflections( hints ); + + Exit: + return error; + } + + + FT_LOCAL_DEF( void ) + af_glyph_hints_save( AF_GlyphHints hints, + FT_Outline* outline ) + { + AF_Point point = hints->points; + AF_Point limit = point + hints->num_points; + FT_Vector* vec = outline->points; + char* tag = outline->tags; + + + for ( ; point < limit; point++, vec++, tag++ ) + { + vec->x = point->x; + vec->y = point->y; + + if ( point->flags & AF_FLAG_CONIC ) + tag[0] = FT_CURVE_TAG_CONIC; + else if ( point->flags & AF_FLAG_CUBIC ) + tag[0] = FT_CURVE_TAG_CUBIC; + else + tag[0] = FT_CURVE_TAG_ON; + } + } + + + /**************************************************************** + * + * EDGE POINT GRID-FITTING + * + ****************************************************************/ + + + FT_LOCAL_DEF( void ) + af_glyph_hints_align_edge_points( AF_GlyphHints hints, + AF_Dimension dim ) + { + AF_AxisHints axis = & hints->axis[dim]; + AF_Segment segments = axis->segments; + AF_Segment segment_limit = segments + axis->num_segments; + AF_Segment seg; + + + if ( dim == AF_DIMENSION_HORZ ) + { + for ( seg = segments; seg < segment_limit; seg++ ) + { + AF_Edge edge = seg->edge; + AF_Point point, first, last; + + + if ( edge == NULL ) + continue; + + first = seg->first; + last = seg->last; + point = first; + for (;;) + { + point->x = edge->pos; + point->flags |= AF_FLAG_TOUCH_X; + + if ( point == last ) + break; + + point = point->next; + + } + } + } + else + { + for ( seg = segments; seg < segment_limit; seg++ ) + { + AF_Edge edge = seg->edge; + AF_Point point, first, last; + + + if ( edge == NULL ) + continue; + + first = seg->first; + last = seg->last; + point = first; + for (;;) + { + point->y = edge->pos; + point->flags |= AF_FLAG_TOUCH_Y; + + if ( point == last ) + break; + + point = point->next; + } + } + } + } + + + /**************************************************************** + * + * STRONG POINT INTERPOLATION + * + ****************************************************************/ + + + /* hint the strong points -- this is equivalent to the TrueType `IP' */ + /* hinting instruction */ + + FT_LOCAL_DEF( void ) + af_glyph_hints_align_strong_points( AF_GlyphHints hints, + AF_Dimension dim ) + { + AF_Point points = hints->points; + AF_Point point_limit = points + hints->num_points; + AF_AxisHints axis = &hints->axis[dim]; + AF_Edge edges = axis->edges; + AF_Edge edge_limit = edges + axis->num_edges; + AF_Flags touch_flag; + + + if ( dim == AF_DIMENSION_HORZ ) + touch_flag = AF_FLAG_TOUCH_X; + else + touch_flag = AF_FLAG_TOUCH_Y; + + if ( edges < edge_limit ) + { + AF_Point point; + AF_Edge edge; + + + for ( point = points; point < point_limit; point++ ) + { + FT_Pos u, ou, fu; /* point position */ + FT_Pos delta; + + + if ( point->flags & touch_flag ) + continue; + + /* if this point is candidate to weak interpolation, we */ + /* interpolate it after all strong points have been processed */ + + if ( ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) && + !( point->flags & AF_FLAG_INFLECTION ) ) + continue; + + if ( dim == AF_DIMENSION_VERT ) + { + u = point->fy; + ou = point->oy; + } + else + { + u = point->fx; + ou = point->ox; + } + + fu = u; + + /* is the point before the first edge? */ + edge = edges; + delta = edge->fpos - u; + if ( delta >= 0 ) + { + u = edge->pos - ( edge->opos - ou ); + goto Store_Point; + } + + /* is the point after the last edge? */ + edge = edge_limit - 1; + delta = u - edge->fpos; + if ( delta >= 0 ) + { + u = edge->pos + ( ou - edge->opos ); + goto Store_Point; + } + + { + FT_PtrDist min, max, mid; + FT_Pos fpos; + + + /* find enclosing edges */ + min = 0; + max = edge_limit - edges; + +#if 1 + /* for small edge counts, a linear search is better */ + if ( max <= 8 ) + { + FT_PtrDist nn; + + for ( nn = 0; nn < max; nn++ ) + if ( edges[nn].fpos >= u ) + break; + + if ( edges[nn].fpos == u ) + { + u = edges[nn].pos; + goto Store_Point; + } + min = nn; + } + else +#endif + while ( min < max ) + { + mid = ( max + min ) >> 1; + edge = edges + mid; + fpos = edge->fpos; + + if ( u < fpos ) + max = mid; + else if ( u > fpos ) + min = mid + 1; + else + { + /* we are on the edge */ + u = edge->pos; + goto Store_Point; + } + } + + { + AF_Edge before = edges + min - 1; + AF_Edge after = edges + min + 0; + + + /* assert( before && after && before != after ) */ + if ( before->scale == 0 ) + before->scale = FT_DivFix( after->pos - before->pos, + after->fpos - before->fpos ); + + u = before->pos + FT_MulFix( fu - before->fpos, + before->scale ); + } + } + + Store_Point: + /* save the point position */ + if ( dim == AF_DIMENSION_HORZ ) + point->x = u; + else + point->y = u; + + point->flags |= touch_flag; + } + } + } + + + /**************************************************************** + * + * WEAK POINT INTERPOLATION + * + ****************************************************************/ + + + static void + af_iup_shift( AF_Point p1, + AF_Point p2, + AF_Point ref ) + { + AF_Point p; + FT_Pos delta = ref->u - ref->v; + + if ( delta == 0 ) + return; + + for ( p = p1; p < ref; p++ ) + p->u = p->v + delta; + + for ( p = ref + 1; p <= p2; p++ ) + p->u = p->v + delta; + } + + + static void + af_iup_interp( AF_Point p1, + AF_Point p2, + AF_Point ref1, + AF_Point ref2 ) + { + AF_Point p; + FT_Pos u; + FT_Pos v1 = ref1->v; + FT_Pos v2 = ref2->v; + FT_Pos d1 = ref1->u - v1; + FT_Pos d2 = ref2->u - v2; + + + if ( p1 > p2 ) + return; + + if ( v1 == v2 ) + { + for ( p = p1; p <= p2; p++ ) + { + u = p->v; + + if ( u <= v1 ) + u += d1; + else + u += d2; + + p->u = u; + } + return; + } + + if ( v1 < v2 ) + { + for ( p = p1; p <= p2; p++ ) + { + u = p->v; + + if ( u <= v1 ) + u += d1; + else if ( u >= v2 ) + u += d2; + else + u = ref1->u + FT_MulDiv( u - v1, ref2->u - ref1->u, v2 - v1 ); + + p->u = u; + } + } + else + { + for ( p = p1; p <= p2; p++ ) + { + u = p->v; + + if ( u <= v2 ) + u += d2; + else if ( u >= v1 ) + u += d1; + else + u = ref1->u + FT_MulDiv( u - v1, ref2->u - ref1->u, v2 - v1 ); + + p->u = u; + } + } + } + + + FT_LOCAL_DEF( void ) + af_glyph_hints_align_weak_points( AF_GlyphHints hints, + AF_Dimension dim ) + { + AF_Point points = hints->points; + AF_Point point_limit = points + hints->num_points; + AF_Point* contour = hints->contours; + AF_Point* contour_limit = contour + hints->num_contours; + AF_Flags touch_flag; + AF_Point point; + AF_Point end_point; + AF_Point first_point; + + + /* PASS 1: Move segment points to edge positions */ + + if ( dim == AF_DIMENSION_HORZ ) + { + touch_flag = AF_FLAG_TOUCH_X; + + for ( point = points; point < point_limit; point++ ) + { + point->u = point->x; + point->v = point->ox; + } + } + else + { + touch_flag = AF_FLAG_TOUCH_Y; + + for ( point = points; point < point_limit; point++ ) + { + point->u = point->y; + point->v = point->oy; + } + } + + point = points; + + for ( ; contour < contour_limit; contour++ ) + { + AF_Point first_touched, last_touched; + + + point = *contour; + end_point = point->prev; + first_point = point; + + /* find first touched point */ + for (;;) + { + if ( point > end_point ) /* no touched point in contour */ + goto NextContour; + + if ( point->flags & touch_flag ) + break; + + point++; + } + + first_touched = point; + last_touched = point; + + for (;;) + { + FT_ASSERT( point <= end_point && + ( point->flags & touch_flag ) != 0 ); + + /* skip any touched neighbhours */ + while ( point < end_point && ( point[1].flags & touch_flag ) != 0 ) + point++; + + last_touched = point; + + /* find the next touched point, if any */ + point ++; + for (;;) + { + if ( point > end_point ) + goto EndContour; + + if ( ( point->flags & touch_flag ) != 0 ) + break; + + point++; + } + + /* interpolate between last_touched and point */ + af_iup_interp( last_touched + 1, point - 1, + last_touched, point ); + } + + EndContour: + /* special case: only one point was touched */ + if ( last_touched == first_touched ) + { + af_iup_shift( first_point, end_point, first_touched ); + } + else /* interpolate the last part */ + { + if ( last_touched < end_point ) + af_iup_interp( last_touched + 1, end_point, + last_touched, first_touched ); + + if ( first_touched > points ) + af_iup_interp( first_point, first_touched - 1, + last_touched, first_touched ); + } + + NextContour: + ; + } + + /* now save the interpolated values back to x/y */ + if ( dim == AF_DIMENSION_HORZ ) + { + for ( point = points; point < point_limit; point++ ) + point->x = point->u; + } + else + { + for ( point = points; point < point_limit; point++ ) + point->y = point->u; + } + } + + +#ifdef AF_USE_WARPER + + FT_LOCAL_DEF( void ) + af_glyph_hints_scale_dim( AF_GlyphHints hints, + AF_Dimension dim, + FT_Fixed scale, + FT_Pos delta ) + { + AF_Point points = hints->points; + AF_Point points_limit = points + hints->num_points; + AF_Point point; + + + if ( dim == AF_DIMENSION_HORZ ) + { + for ( point = points; point < points_limit; point++ ) + point->x = FT_MulFix( point->fx, scale ) + delta; + } + else + { + for ( point = points; point < points_limit; point++ ) + point->y = FT_MulFix( point->fy, scale ) + delta; + } + } + +#endif /* AF_USE_WARPER */ + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/autofit/afhints.h b/mod/pub.mod/freetype.mod/src/autofit/afhints.h new file mode 100644 index 0000000..6758268 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/autofit/afhints.h @@ -0,0 +1,333 @@ +/***************************************************************************/ +/* */ +/* afhints.h */ +/* */ +/* Auto-fitter hinting routines (specification). */ +/* */ +/* Copyright 2003, 2004, 2005, 2006, 2007, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __AFHINTS_H__ +#define __AFHINTS_H__ + +#include "aftypes.h" + +#define xxAF_SORT_SEGMENTS + +FT_BEGIN_HEADER + + /* + * The definition of outline glyph hints. These are shared by all + * script analysis routines (until now). + */ + + typedef enum AF_Dimension_ + { + AF_DIMENSION_HORZ = 0, /* x coordinates, */ + /* i.e., vertical segments & edges */ + AF_DIMENSION_VERT = 1, /* y coordinates, */ + /* i.e., horizontal segments & edges */ + + AF_DIMENSION_MAX /* do not remove */ + + } AF_Dimension; + + + /* hint directions -- the values are computed so that two vectors are */ + /* in opposite directions iff `dir1 + dir2 == 0' */ + typedef enum AF_Direction_ + { + AF_DIR_NONE = 4, + AF_DIR_RIGHT = 1, + AF_DIR_LEFT = -1, + AF_DIR_UP = 2, + AF_DIR_DOWN = -2 + + } AF_Direction; + + + /* point hint flags */ + typedef enum AF_Flags_ + { + AF_FLAG_NONE = 0, + + /* point type flags */ + AF_FLAG_CONIC = 1 << 0, + AF_FLAG_CUBIC = 1 << 1, + AF_FLAG_CONTROL = AF_FLAG_CONIC | AF_FLAG_CUBIC, + + /* point extremum flags */ + AF_FLAG_EXTREMA_X = 1 << 2, + AF_FLAG_EXTREMA_Y = 1 << 3, + + /* point roundness flags */ + AF_FLAG_ROUND_X = 1 << 4, + AF_FLAG_ROUND_Y = 1 << 5, + + /* point touch flags */ + AF_FLAG_TOUCH_X = 1 << 6, + AF_FLAG_TOUCH_Y = 1 << 7, + + /* candidates for weak interpolation have this flag set */ + AF_FLAG_WEAK_INTERPOLATION = 1 << 8, + + /* all inflection points in the outline have this flag set */ + AF_FLAG_INFLECTION = 1 << 9 + + } AF_Flags; + + + /* edge hint flags */ + typedef enum AF_Edge_Flags_ + { + AF_EDGE_NORMAL = 0, + AF_EDGE_ROUND = 1 << 0, + AF_EDGE_SERIF = 1 << 1, + AF_EDGE_DONE = 1 << 2 + + } AF_Edge_Flags; + + + typedef struct AF_PointRec_* AF_Point; + typedef struct AF_SegmentRec_* AF_Segment; + typedef struct AF_EdgeRec_* AF_Edge; + + + typedef struct AF_PointRec_ + { + FT_UShort flags; /* point flags used by hinter */ + FT_Char in_dir; /* direction of inwards vector */ + FT_Char out_dir; /* direction of outwards vector */ + + FT_Pos ox, oy; /* original, scaled position */ + FT_Short fx, fy; /* original, unscaled position (font units) */ + FT_Pos x, y; /* current position */ + FT_Pos u, v; /* current (x,y) or (y,x) depending on context */ + + AF_Point next; /* next point in contour */ + AF_Point prev; /* previous point in contour */ + + } AF_PointRec; + + + typedef struct AF_SegmentRec_ + { + FT_Byte flags; /* edge/segment flags for this segment */ + FT_Char dir; /* segment direction */ + FT_Short pos; /* position of segment */ + FT_Short min_coord; /* minimum coordinate of segment */ + FT_Short max_coord; /* maximum coordinate of segment */ + FT_Short height; /* the hinted segment height */ + + AF_Edge edge; /* the segment's parent edge */ + AF_Segment edge_next; /* link to next segment in parent edge */ + + AF_Segment link; /* (stem) link segment */ + AF_Segment serif; /* primary segment for serifs */ + FT_Pos num_linked; /* number of linked segments */ + FT_Pos score; /* used during stem matching */ + FT_Pos len; /* used during stem matching */ + + AF_Point first; /* first point in edge segment */ + AF_Point last; /* last point in edge segment */ + AF_Point* contour; /* ptr to first point of segment's contour */ + + } AF_SegmentRec; + + + typedef struct AF_EdgeRec_ + { + FT_Short fpos; /* original, unscaled position (font units) */ + FT_Pos opos; /* original, scaled position */ + FT_Pos pos; /* current position */ + + FT_Byte flags; /* edge flags */ + FT_Char dir; /* edge direction */ + FT_Fixed scale; /* used to speed up interpolation between edges */ + AF_Width blue_edge; /* non-NULL if this is a blue edge */ + + AF_Edge link; + AF_Edge serif; + FT_Short num_linked; + + FT_Int score; + + AF_Segment first; + AF_Segment last; + + } AF_EdgeRec; + + + typedef struct AF_AxisHintsRec_ + { + FT_Int num_segments; + FT_Int max_segments; + AF_Segment segments; +#ifdef AF_SORT_SEGMENTS + FT_Int mid_segments; +#endif + + FT_Int num_edges; + FT_Int max_edges; + AF_Edge edges; + + AF_Direction major_dir; + + } AF_AxisHintsRec, *AF_AxisHints; + + + typedef struct AF_GlyphHintsRec_ + { + FT_Memory memory; + + FT_Fixed x_scale; + FT_Pos x_delta; + + FT_Fixed y_scale; + FT_Pos y_delta; + + FT_Pos edge_distance_threshold; + + FT_Int max_points; + FT_Int num_points; + AF_Point points; + + FT_Int max_contours; + FT_Int num_contours; + AF_Point* contours; + + AF_AxisHintsRec axis[AF_DIMENSION_MAX]; + + FT_UInt32 scaler_flags; /* copy of scaler flags */ + FT_UInt32 other_flags; /* free for script-specific */ + /* implementations */ + AF_ScriptMetrics metrics; + + FT_Pos xmin_delta; /* used for warping */ + FT_Pos xmax_delta; + + } AF_GlyphHintsRec; + + +#define AF_HINTS_TEST_SCALER( h, f ) ( (h)->scaler_flags & (f) ) +#define AF_HINTS_TEST_OTHER( h, f ) ( (h)->other_flags & (f) ) + + +#ifdef AF_DEBUG + +#define AF_HINTS_DO_HORIZONTAL( h ) \ + ( !_af_debug_disable_horz_hints && \ + !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_HORIZONTAL ) ) + +#define AF_HINTS_DO_VERTICAL( h ) \ + ( !_af_debug_disable_vert_hints && \ + !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_VERTICAL ) ) + +#define AF_HINTS_DO_ADVANCE( h ) \ + !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_ADVANCE ) + +#define AF_HINTS_DO_BLUES( h ) ( !_af_debug_disable_blue_hints ) + +#else /* !AF_DEBUG */ + +#define AF_HINTS_DO_HORIZONTAL( h ) \ + !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_HORIZONTAL ) + +#define AF_HINTS_DO_VERTICAL( h ) \ + !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_VERTICAL ) + +#define AF_HINTS_DO_ADVANCE( h ) \ + !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_ADVANCE ) + +#define AF_HINTS_DO_BLUES( h ) 1 + +#endif /* !AF_DEBUG */ + + + FT_LOCAL( AF_Direction ) + af_direction_compute( FT_Pos dx, + FT_Pos dy ); + + + FT_LOCAL( FT_Error ) + af_axis_hints_new_segment( AF_AxisHints axis, + FT_Memory memory, + AF_Segment *asegment ); + + FT_LOCAL( FT_Error) + af_axis_hints_new_edge( AF_AxisHints axis, + FT_Int fpos, + AF_Direction dir, + FT_Memory memory, + AF_Edge *edge ); + + FT_LOCAL( void ) + af_glyph_hints_init( AF_GlyphHints hints, + FT_Memory memory ); + + + + /* + * recompute all AF_Point in a AF_GlyphHints from the definitions + * in a source outline + */ + FT_LOCAL( void ) + af_glyph_hints_rescale( AF_GlyphHints hints, + AF_ScriptMetrics metrics ); + + FT_LOCAL( FT_Error ) + af_glyph_hints_reload( AF_GlyphHints hints, + FT_Outline* outline, + FT_Bool get_inflections ); + + FT_LOCAL( void ) + af_glyph_hints_save( AF_GlyphHints hints, + FT_Outline* outline ); + + FT_LOCAL( void ) + af_glyph_hints_align_edge_points( AF_GlyphHints hints, + AF_Dimension dim ); + + FT_LOCAL( void ) + af_glyph_hints_align_strong_points( AF_GlyphHints hints, + AF_Dimension dim ); + + FT_LOCAL( void ) + af_glyph_hints_align_weak_points( AF_GlyphHints hints, + AF_Dimension dim ); + +#ifdef AF_USE_WARPER + FT_LOCAL( void ) + af_glyph_hints_scale_dim( AF_GlyphHints hints, + AF_Dimension dim, + FT_Fixed scale, + FT_Pos delta ); +#endif + + FT_LOCAL( void ) + af_glyph_hints_done( AF_GlyphHints hints ); + +/* */ + +#define AF_SEGMENT_LEN( seg ) ( (seg)->max_coord - (seg)->min_coord ) + +#define AF_SEGMENT_DIST( seg1, seg2 ) ( ( (seg1)->pos > (seg2)->pos ) \ + ? (seg1)->pos - (seg2)->pos \ + : (seg2)->pos - (seg1)->pos ) + + +FT_END_HEADER + +#endif /* __AFHINTS_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/autofit/afindic.c b/mod/pub.mod/freetype.mod/src/autofit/afindic.c new file mode 100644 index 0000000..1d9e9ea --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/autofit/afindic.c @@ -0,0 +1,130 @@ +/***************************************************************************/ +/* */ +/* afindic.c */ +/* */ +/* Auto-fitter hinting routines for Indic scripts (body). */ +/* */ +/* Copyright 2007 by */ +/* Rahul Bhalerao <rahul.bhalerao@redhat.com>, <b.rahul.pm@gmail.com>. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include "aftypes.h" +#include "aflatin.h" + + +#ifdef AF_CONFIG_OPTION_INDIC + +#include "afindic.h" +#include "aferrors.h" +#include "afcjk.h" + + +#ifdef AF_USE_WARPER +#include "afwarp.h" +#endif + + + static FT_Error + af_indic_metrics_init( AF_LatinMetrics metrics, + FT_Face face ) + { + /* use CJK routines */ + return af_cjk_metrics_init( metrics, face ); + } + + + static void + af_indic_metrics_scale( AF_LatinMetrics metrics, + AF_Scaler scaler ) + { + /* use CJK routines */ + af_cjk_metrics_scale( metrics, scaler ); + } + + + static FT_Error + af_indic_hints_init( AF_GlyphHints hints, + AF_LatinMetrics metrics ) + { + /* use CJK routines */ + return af_cjk_hints_init( hints, metrics ); + } + + + static FT_Error + af_indic_hints_apply( AF_GlyphHints hints, + FT_Outline* outline, + AF_LatinMetrics metrics) + { + /* use CJK routines */ + return af_cjk_hints_apply( hints, outline, metrics ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** I N D I C S C R I P T C L A S S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + static const AF_Script_UniRangeRec af_indic_uniranges[] = + { +#if 0 + AF_UNIRANGE_REC( 0x0100UL, 0xFFFFUL ), /* why this? */ +#endif + AF_UNIRANGE_REC( 0x0900UL, 0x0DFFUL), /* Indic Range */ + AF_UNIRANGE_REC( 0UL, 0UL) + }; + + + AF_DEFINE_SCRIPT_CLASS(af_indic_script_class, + AF_SCRIPT_INDIC, + af_indic_uniranges, + + sizeof( AF_LatinMetricsRec ), + + (AF_Script_InitMetricsFunc) af_indic_metrics_init, + (AF_Script_ScaleMetricsFunc)af_indic_metrics_scale, + (AF_Script_DoneMetricsFunc) NULL, + + (AF_Script_InitHintsFunc) af_indic_hints_init, + (AF_Script_ApplyHintsFunc) af_indic_hints_apply + ) + +#else /* !AF_CONFIG_OPTION_INDIC */ + + static const AF_Script_UniRangeRec af_indic_uniranges[] = + { + { 0, 0 } + }; + + + AF_DEFINE_SCRIPT_CLASS(af_indic_script_class, + AF_SCRIPT_INDIC, + af_indic_uniranges, + + sizeof( AF_LatinMetricsRec ), + + (AF_Script_InitMetricsFunc) NULL, + (AF_Script_ScaleMetricsFunc)NULL, + (AF_Script_DoneMetricsFunc) NULL, + + (AF_Script_InitHintsFunc) NULL, + (AF_Script_ApplyHintsFunc) NULL + ) + +#endif /* !AF_CONFIG_OPTION_INDIC */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/autofit/afindic.h b/mod/pub.mod/freetype.mod/src/autofit/afindic.h new file mode 100644 index 0000000..662a982 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/autofit/afindic.h @@ -0,0 +1,40 @@ +/***************************************************************************/ +/* */ +/* afindic.h */ +/* */ +/* Auto-fitter hinting routines for Indic scripts (specification). */ +/* */ +/* Copyright 2007 by */ +/* Rahul Bhalerao <rahul.bhalerao@redhat.com>, <b.rahul.pm@gmail.com>. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __AFINDIC_H__ +#define __AFINDIC_H__ + +#include "afhints.h" + + +FT_BEGIN_HEADER + + + /* the Indic-specific script class */ + + AF_DECLARE_SCRIPT_CLASS(af_indic_script_class) + + +/* */ + +FT_END_HEADER + +#endif /* __AFINDIC_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/autofit/aflatin.c b/mod/pub.mod/freetype.mod/src/autofit/aflatin.c new file mode 100644 index 0000000..394fb97 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/autofit/aflatin.c @@ -0,0 +1,2227 @@ +/***************************************************************************/ +/* */ +/* aflatin.c */ +/* */ +/* Auto-fitter hinting routines for latin script (body). */ +/* */ +/* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_ADVANCES_H + +#include "aflatin.h" +#include "aferrors.h" + + +#ifdef AF_USE_WARPER +#include "afwarp.h" +#endif + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** L A T I N G L O B A L M E T R I C S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL_DEF( void ) + af_latin_metrics_init_widths( AF_LatinMetrics metrics, + FT_Face face, + FT_ULong charcode ) + { + /* scan the array of segments in each direction */ + AF_GlyphHintsRec hints[1]; + + + af_glyph_hints_init( hints, face->memory ); + + metrics->axis[AF_DIMENSION_HORZ].width_count = 0; + metrics->axis[AF_DIMENSION_VERT].width_count = 0; + + { + FT_Error error; + FT_UInt glyph_index; + int dim; + AF_LatinMetricsRec dummy[1]; + AF_Scaler scaler = &dummy->root.scaler; + + + glyph_index = FT_Get_Char_Index( face, charcode ); + if ( glyph_index == 0 ) + goto Exit; + + error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE ); + if ( error || face->glyph->outline.n_points <= 0 ) + goto Exit; + + FT_ZERO( dummy ); + + dummy->units_per_em = metrics->units_per_em; + scaler->x_scale = scaler->y_scale = 0x10000L; + scaler->x_delta = scaler->y_delta = 0; + scaler->face = face; + scaler->render_mode = FT_RENDER_MODE_NORMAL; + scaler->flags = 0; + + af_glyph_hints_rescale( hints, (AF_ScriptMetrics)dummy ); + + error = af_glyph_hints_reload( hints, &face->glyph->outline, 0 ); + if ( error ) + goto Exit; + + for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) + { + AF_LatinAxis axis = &metrics->axis[dim]; + AF_AxisHints axhints = &hints->axis[dim]; + AF_Segment seg, limit, link; + FT_UInt num_widths = 0; + + + error = af_latin_hints_compute_segments( hints, + (AF_Dimension)dim ); + if ( error ) + goto Exit; + + af_latin_hints_link_segments( hints, + (AF_Dimension)dim ); + + seg = axhints->segments; + limit = seg + axhints->num_segments; + + for ( ; seg < limit; seg++ ) + { + link = seg->link; + + /* we only consider stem segments there! */ + if ( link && link->link == seg && link > seg ) + { + FT_Pos dist; + + + dist = seg->pos - link->pos; + if ( dist < 0 ) + dist = -dist; + + if ( num_widths < AF_LATIN_MAX_WIDTHS ) + axis->widths[ num_widths++ ].org = dist; + } + } + + af_sort_widths( num_widths, axis->widths ); + axis->width_count = num_widths; + } + + Exit: + for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) + { + AF_LatinAxis axis = &metrics->axis[dim]; + FT_Pos stdw; + + + stdw = ( axis->width_count > 0 ) + ? axis->widths[0].org + : AF_LATIN_CONSTANT( metrics, 50 ); + + /* let's try 20% of the smallest width */ + axis->edge_distance_threshold = stdw / 5; + axis->standard_width = stdw; + axis->extra_light = 0; + } + } + + af_glyph_hints_done( hints ); + } + + + +#define AF_LATIN_MAX_TEST_CHARACTERS 12 + + + static const char af_latin_blue_chars[AF_LATIN_MAX_BLUES] + [AF_LATIN_MAX_TEST_CHARACTERS + 1] = + { + "THEZOCQS", + "HEZLOCUS", + "fijkdbh", + "xzroesc", + "xzroesc", + "pqgjy" + }; + + + static void + af_latin_metrics_init_blues( AF_LatinMetrics metrics, + FT_Face face ) + { + FT_Pos flats [AF_LATIN_MAX_TEST_CHARACTERS]; + FT_Pos rounds[AF_LATIN_MAX_TEST_CHARACTERS]; + FT_Int num_flats; + FT_Int num_rounds; + FT_Int bb; + AF_LatinBlue blue; + FT_Error error; + AF_LatinAxis axis = &metrics->axis[AF_DIMENSION_VERT]; + FT_GlyphSlot glyph = face->glyph; + + + /* we compute the blues simply by loading each character from the */ + /* 'af_latin_blue_chars[blues]' string, then compute its top-most or */ + /* bottom-most points (depending on `AF_IS_TOP_BLUE') */ + + AF_LOG(( "blue zones computation\n" )); + AF_LOG(( "------------------------------------------------\n" )); + + for ( bb = 0; bb < AF_LATIN_BLUE_MAX; bb++ ) + { + const char* p = af_latin_blue_chars[bb]; + const char* limit = p + AF_LATIN_MAX_TEST_CHARACTERS; + FT_Pos* blue_ref; + FT_Pos* blue_shoot; + + + AF_LOG(( "blue %3d: ", bb )); + + num_flats = 0; + num_rounds = 0; + + for ( ; p < limit && *p; p++ ) + { + FT_UInt glyph_index; + FT_Pos best_y; /* same as points.y */ + FT_Int best_point, best_first, best_last; + FT_Vector* points; + FT_Bool round = 0; + + + AF_LOG(( "'%c'", *p )); + + /* load the character in the face -- skip unknown or empty ones */ + glyph_index = FT_Get_Char_Index( face, (FT_UInt)*p ); + if ( glyph_index == 0 ) + continue; + + error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE ); + if ( error || glyph->outline.n_points <= 0 ) + continue; + + /* now compute min or max point indices and coordinates */ + points = glyph->outline.points; + best_point = -1; + best_y = 0; /* make compiler happy */ + best_first = 0; /* ditto */ + best_last = 0; /* ditto */ + + { + FT_Int nn; + FT_Int first = 0; + FT_Int last = -1; + + + for ( nn = 0; nn < glyph->outline.n_contours; first = last+1, nn++ ) + { + FT_Int old_best_point = best_point; + FT_Int pp; + + + last = glyph->outline.contours[nn]; + + /* Avoid single-point contours since they are never rasterized. */ + /* In some fonts, they correspond to mark attachment points */ + /* which are way outside of the glyph's real outline. */ + if ( last <= first ) + continue; + + if ( AF_LATIN_IS_TOP_BLUE( bb ) ) + { + for ( pp = first; pp <= last; pp++ ) + if ( best_point < 0 || points[pp].y > best_y ) + { + best_point = pp; + best_y = points[pp].y; + } + } + else + { + for ( pp = first; pp <= last; pp++ ) + if ( best_point < 0 || points[pp].y < best_y ) + { + best_point = pp; + best_y = points[pp].y; + } + } + + if ( best_point != old_best_point ) + { + best_first = first; + best_last = last; + } + } + AF_LOG(( "%5d", best_y )); + } + + /* now check whether the point belongs to a straight or round */ + /* segment; we first need to find in which contour the extremum */ + /* lies, then inspect its previous and next points */ + if ( best_point >= 0 ) + { + FT_Int prev, next; + FT_Pos dist; + + + /* now look for the previous and next points that are not on the */ + /* same Y coordinate. Threshold the `closeness'... */ + prev = best_point; + next = prev; + + do + { + if ( prev > best_first ) + prev--; + else + prev = best_last; + + dist = points[prev].y - best_y; + if ( dist < -5 || dist > 5 ) + break; + + } while ( prev != best_point ); + + do + { + if ( next < best_last ) + next++; + else + next = best_first; + + dist = points[next].y - best_y; + if ( dist < -5 || dist > 5 ) + break; + + } while ( next != best_point ); + + /* now, set the `round' flag depending on the segment's kind */ + round = FT_BOOL( + FT_CURVE_TAG( glyph->outline.tags[prev] ) != FT_CURVE_TAG_ON || + FT_CURVE_TAG( glyph->outline.tags[next] ) != FT_CURVE_TAG_ON ); + + AF_LOG(( "%c ", round ? 'r' : 'f' )); + } + + if ( round ) + rounds[num_rounds++] = best_y; + else + flats[num_flats++] = best_y; + } + + AF_LOG(( "\n" )); + + if ( num_flats == 0 && num_rounds == 0 ) + { + /* + * we couldn't find a single glyph to compute this blue zone, + * we will simply ignore it then + */ + AF_LOG(( "empty\n" )); + continue; + } + + /* we have computed the contents of the `rounds' and `flats' tables, */ + /* now determine the reference and overshoot position of the blue -- */ + /* we simply take the median value after a simple sort */ + af_sort_pos( num_rounds, rounds ); + af_sort_pos( num_flats, flats ); + + blue = & axis->blues[axis->blue_count]; + blue_ref = & blue->ref.org; + blue_shoot = & blue->shoot.org; + + axis->blue_count++; + + if ( num_flats == 0 ) + { + *blue_ref = + *blue_shoot = rounds[num_rounds / 2]; + } + else if ( num_rounds == 0 ) + { + *blue_ref = + *blue_shoot = flats[num_flats / 2]; + } + else + { + *blue_ref = flats[num_flats / 2]; + *blue_shoot = rounds[num_rounds / 2]; + } + + /* there are sometimes problems: if the overshoot position of top */ + /* zones is under its reference position, or the opposite for bottom */ + /* zones. We must thus check everything there and correct the errors */ + if ( *blue_shoot != *blue_ref ) + { + FT_Pos ref = *blue_ref; + FT_Pos shoot = *blue_shoot; + FT_Bool over_ref = FT_BOOL( shoot > ref ); + + + if ( AF_LATIN_IS_TOP_BLUE( bb ) ^ over_ref ) + *blue_shoot = *blue_ref = ( shoot + ref ) / 2; + } + + blue->flags = 0; + if ( AF_LATIN_IS_TOP_BLUE( bb ) ) + blue->flags |= AF_LATIN_BLUE_TOP; + + /* + * The following flag is used later to adjust the y and x scales + * in order to optimize the pixel grid alignment of the top of small + * letters. + */ + if ( bb == AF_LATIN_BLUE_SMALL_TOP ) + blue->flags |= AF_LATIN_BLUE_ADJUSTMENT; + + AF_LOG(( "-- ref = %ld, shoot = %ld\n", *blue_ref, *blue_shoot )); + } + + return; + } + + + FT_LOCAL_DEF( void ) + af_latin_metrics_check_digits( AF_LatinMetrics metrics, + FT_Face face ) + { + FT_UInt i; + FT_Bool started = 0, same_width = 1; + + + /* check whether all ASCII digits have the same advance width; */ + /* digit `0' is 0x30 in all supported charmaps */ + for ( i = 0x30; i <= 0x39; i++ ) + { + FT_UInt glyph_index; + FT_Fixed advance, old_advance = 0; + + + glyph_index = FT_Get_Char_Index( face, i ); + if ( glyph_index == 0 ) + continue; + + if ( FT_Get_Advance( face, glyph_index, + FT_LOAD_NO_SCALE | + FT_LOAD_NO_HINTING | + FT_LOAD_IGNORE_TRANSFORM, + &advance ) ) + continue; + + if ( started ) + { + if ( advance != old_advance ) + { + same_width = 0; + break; + } + } + else + { + old_advance = advance; + started = 1; + } + } + + metrics->root.digits_have_same_width = same_width; + } + + + FT_LOCAL_DEF( FT_Error ) + af_latin_metrics_init( AF_LatinMetrics metrics, + FT_Face face ) + { + FT_Error error = AF_Err_Ok; + FT_CharMap oldmap = face->charmap; + FT_UInt ee; + + static const FT_Encoding latin_encodings[] = + { + FT_ENCODING_UNICODE, + FT_ENCODING_APPLE_ROMAN, + FT_ENCODING_ADOBE_STANDARD, + FT_ENCODING_ADOBE_LATIN_1, + FT_ENCODING_NONE /* end of list */ + }; + + + metrics->units_per_em = face->units_per_EM; + + /* do we have a latin charmap in there? */ + for ( ee = 0; latin_encodings[ee] != FT_ENCODING_NONE; ee++ ) + { + error = FT_Select_Charmap( face, latin_encodings[ee] ); + if ( !error ) + break; + } + + if ( !error ) + { + /* For now, compute the standard width and height from the `o'. */ + af_latin_metrics_init_widths( metrics, face, 'o' ); + af_latin_metrics_init_blues( metrics, face ); + af_latin_metrics_check_digits( metrics, face ); + } + + FT_Set_Charmap( face, oldmap ); + return AF_Err_Ok; + } + + + static void + af_latin_metrics_scale_dim( AF_LatinMetrics metrics, + AF_Scaler scaler, + AF_Dimension dim ) + { + FT_Fixed scale; + FT_Pos delta; + AF_LatinAxis axis; + FT_UInt nn; + + + if ( dim == AF_DIMENSION_HORZ ) + { + scale = scaler->x_scale; + delta = scaler->x_delta; + } + else + { + scale = scaler->y_scale; + delta = scaler->y_delta; + } + + axis = &metrics->axis[dim]; + + if ( axis->org_scale == scale && axis->org_delta == delta ) + return; + + axis->org_scale = scale; + axis->org_delta = delta; + + /* + * correct X and Y scale to optimize the alignment of the top of small + * letters to the pixel grid + */ + { + AF_LatinAxis Axis = &metrics->axis[AF_DIMENSION_VERT]; + AF_LatinBlue blue = NULL; + + + for ( nn = 0; nn < Axis->blue_count; nn++ ) + { + if ( Axis->blues[nn].flags & AF_LATIN_BLUE_ADJUSTMENT ) + { + blue = &Axis->blues[nn]; + break; + } + } + + if ( blue ) + { + FT_Pos scaled = FT_MulFix( blue->shoot.org, scaler->y_scale ); + FT_Pos fitted = ( scaled + 40 ) & ~63; + + + if ( scaled != fitted ) + { +#if 0 + if ( dim == AF_DIMENSION_HORZ ) + { + if ( fitted < scaled ) + scale -= scale / 50; /* scale *= 0.98 */ + } + else +#endif + if ( dim == AF_DIMENSION_VERT ) + { + scale = FT_MulDiv( scale, fitted, scaled ); + } + } + } + } + + axis->scale = scale; + axis->delta = delta; + + if ( dim == AF_DIMENSION_HORZ ) + { + metrics->root.scaler.x_scale = scale; + metrics->root.scaler.x_delta = delta; + } + else + { + metrics->root.scaler.y_scale = scale; + metrics->root.scaler.y_delta = delta; + } + + /* scale the standard widths */ + for ( nn = 0; nn < axis->width_count; nn++ ) + { + AF_Width width = axis->widths + nn; + + + width->cur = FT_MulFix( width->org, scale ); + width->fit = width->cur; + } + + /* an extra-light axis corresponds to a standard width that is */ + /* smaller than 0.75 pixels */ + axis->extra_light = + (FT_Bool)( FT_MulFix( axis->standard_width, scale ) < 32 + 8 ); + + if ( dim == AF_DIMENSION_VERT ) + { + /* scale the blue zones */ + for ( nn = 0; nn < axis->blue_count; nn++ ) + { + AF_LatinBlue blue = &axis->blues[nn]; + FT_Pos dist; + + + blue->ref.cur = FT_MulFix( blue->ref.org, scale ) + delta; + blue->ref.fit = blue->ref.cur; + blue->shoot.cur = FT_MulFix( blue->shoot.org, scale ) + delta; + blue->shoot.fit = blue->shoot.cur; + blue->flags &= ~AF_LATIN_BLUE_ACTIVE; + + /* a blue zone is only active if it is less than 3/4 pixels tall */ + dist = FT_MulFix( blue->ref.org - blue->shoot.org, scale ); + if ( dist <= 48 && dist >= -48 ) + { + FT_Pos delta1, delta2; + + + delta1 = blue->shoot.org - blue->ref.org; + delta2 = delta1; + if ( delta1 < 0 ) + delta2 = -delta2; + + delta2 = FT_MulFix( delta2, scale ); + + if ( delta2 < 32 ) + delta2 = 0; + else if ( delta2 < 64 ) + delta2 = 32 + ( ( ( delta2 - 32 ) + 16 ) & ~31 ); + else + delta2 = FT_PIX_ROUND( delta2 ); + + if ( delta1 < 0 ) + delta2 = -delta2; + + blue->ref.fit = FT_PIX_ROUND( blue->ref.cur ); + blue->shoot.fit = blue->ref.fit + delta2; + + blue->flags |= AF_LATIN_BLUE_ACTIVE; + } + } + } + } + + + FT_LOCAL_DEF( void ) + af_latin_metrics_scale( AF_LatinMetrics metrics, + AF_Scaler scaler ) + { + metrics->root.scaler.render_mode = scaler->render_mode; + metrics->root.scaler.face = scaler->face; + + af_latin_metrics_scale_dim( metrics, scaler, AF_DIMENSION_HORZ ); + af_latin_metrics_scale_dim( metrics, scaler, AF_DIMENSION_VERT ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** L A T I N G L Y P H A N A L Y S I S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL_DEF( FT_Error ) + af_latin_hints_compute_segments( AF_GlyphHints hints, + AF_Dimension dim ) + { + AF_AxisHints axis = &hints->axis[dim]; + FT_Memory memory = hints->memory; + FT_Error error = AF_Err_Ok; + AF_Segment segment = NULL; + AF_SegmentRec seg0; + AF_Point* contour = hints->contours; + AF_Point* contour_limit = contour + hints->num_contours; + AF_Direction major_dir, segment_dir; + + + FT_ZERO( &seg0 ); + seg0.score = 32000; + seg0.flags = AF_EDGE_NORMAL; + + major_dir = (AF_Direction)FT_ABS( axis->major_dir ); + segment_dir = major_dir; + + axis->num_segments = 0; + + /* set up (u,v) in each point */ + if ( dim == AF_DIMENSION_HORZ ) + { + AF_Point point = hints->points; + AF_Point limit = point + hints->num_points; + + + for ( ; point < limit; point++ ) + { + point->u = point->fx; + point->v = point->fy; + } + } + else + { + AF_Point point = hints->points; + AF_Point limit = point + hints->num_points; + + + for ( ; point < limit; point++ ) + { + point->u = point->fy; + point->v = point->fx; + } + } + + /* do each contour separately */ + for ( ; contour < contour_limit; contour++ ) + { + AF_Point point = contour[0]; + AF_Point last = point->prev; + int on_edge = 0; + FT_Pos min_pos = 32000; /* minimum segment pos != min_coord */ + FT_Pos max_pos = -32000; /* maximum segment pos != max_coord */ + FT_Bool passed; + + + if ( point == last ) /* skip singletons -- just in case */ + continue; + + if ( FT_ABS( last->out_dir ) == major_dir && + FT_ABS( point->out_dir ) == major_dir ) + { + /* we are already on an edge, try to locate its start */ + last = point; + + for (;;) + { + point = point->prev; + if ( FT_ABS( point->out_dir ) != major_dir ) + { + point = point->next; + break; + } + if ( point == last ) + break; + } + } + + last = point; + passed = 0; + + for (;;) + { + FT_Pos u, v; + + + if ( on_edge ) + { + u = point->u; + if ( u < min_pos ) + min_pos = u; + if ( u > max_pos ) + max_pos = u; + + if ( point->out_dir != segment_dir || point == last ) + { + /* we are just leaving an edge; record a new segment! */ + segment->last = point; + segment->pos = (FT_Short)( ( min_pos + max_pos ) >> 1 ); + + /* a segment is round if either its first or last point */ + /* is a control point */ + if ( ( segment->first->flags | point->flags ) & + AF_FLAG_CONTROL ) + segment->flags |= AF_EDGE_ROUND; + + /* compute segment size */ + min_pos = max_pos = point->v; + + v = segment->first->v; + if ( v < min_pos ) + min_pos = v; + if ( v > max_pos ) + max_pos = v; + + segment->min_coord = (FT_Short)min_pos; + segment->max_coord = (FT_Short)max_pos; + segment->height = (FT_Short)( segment->max_coord - + segment->min_coord ); + + on_edge = 0; + segment = NULL; + /* fallthrough */ + } + } + + /* now exit if we are at the start/end point */ + if ( point == last ) + { + if ( passed ) + break; + passed = 1; + } + + if ( !on_edge && FT_ABS( point->out_dir ) == major_dir ) + { + /* this is the start of a new segment! */ + segment_dir = (AF_Direction)point->out_dir; + + /* clear all segment fields */ + error = af_axis_hints_new_segment( axis, memory, &segment ); + if ( error ) + goto Exit; + + segment[0] = seg0; + segment->dir = (FT_Char)segment_dir; + min_pos = max_pos = point->u; + segment->first = point; + segment->last = point; + segment->contour = contour; + on_edge = 1; + } + + point = point->next; + } + + } /* contours */ + + + /* now slightly increase the height of segments when this makes */ + /* sense -- this is used to better detect and ignore serifs */ + { + AF_Segment segments = axis->segments; + AF_Segment segments_end = segments + axis->num_segments; + + + for ( segment = segments; segment < segments_end; segment++ ) + { + AF_Point first = segment->first; + AF_Point last = segment->last; + FT_Pos first_v = first->v; + FT_Pos last_v = last->v; + + + if ( first == last ) + continue; + + if ( first_v < last_v ) + { + AF_Point p; + + + p = first->prev; + if ( p->v < first_v ) + segment->height = (FT_Short)( segment->height + + ( ( first_v - p->v ) >> 1 ) ); + + p = last->next; + if ( p->v > last_v ) + segment->height = (FT_Short)( segment->height + + ( ( p->v - last_v ) >> 1 ) ); + } + else + { + AF_Point p; + + + p = first->prev; + if ( p->v > first_v ) + segment->height = (FT_Short)( segment->height + + ( ( p->v - first_v ) >> 1 ) ); + + p = last->next; + if ( p->v < last_v ) + segment->height = (FT_Short)( segment->height + + ( ( last_v - p->v ) >> 1 ) ); + } + } + } + + Exit: + return error; + } + + + FT_LOCAL_DEF( void ) + af_latin_hints_link_segments( AF_GlyphHints hints, + AF_Dimension dim ) + { + AF_AxisHints axis = &hints->axis[dim]; + AF_Segment segments = axis->segments; + AF_Segment segment_limit = segments + axis->num_segments; + FT_Pos len_threshold, len_score; + AF_Segment seg1, seg2; + + + len_threshold = AF_LATIN_CONSTANT( hints->metrics, 8 ); + if ( len_threshold == 0 ) + len_threshold = 1; + + len_score = AF_LATIN_CONSTANT( hints->metrics, 6000 ); + + /* now compare each segment to the others */ + for ( seg1 = segments; seg1 < segment_limit; seg1++ ) + { + /* the fake segments are introduced to hint the metrics -- */ + /* we must never link them to anything */ + if ( seg1->dir != axis->major_dir || seg1->first == seg1->last ) + continue; + + for ( seg2 = segments; seg2 < segment_limit; seg2++ ) + if ( seg1->dir + seg2->dir == 0 && seg2->pos > seg1->pos ) + { + FT_Pos pos1 = seg1->pos; + FT_Pos pos2 = seg2->pos; + FT_Pos dist = pos2 - pos1; + + + if ( dist < 0 ) + dist = -dist; + + { + FT_Pos min = seg1->min_coord; + FT_Pos max = seg1->max_coord; + FT_Pos len, score; + + + if ( min < seg2->min_coord ) + min = seg2->min_coord; + + if ( max > seg2->max_coord ) + max = seg2->max_coord; + + len = max - min; + if ( len >= len_threshold ) + { + score = dist + len_score / len; + + if ( score < seg1->score ) + { + seg1->score = score; + seg1->link = seg2; + } + + if ( score < seg2->score ) + { + seg2->score = score; + seg2->link = seg1; + } + } + } + } + } + + /* now, compute the `serif' segments */ + for ( seg1 = segments; seg1 < segment_limit; seg1++ ) + { + seg2 = seg1->link; + + if ( seg2 ) + { + if ( seg2->link != seg1 ) + { + seg1->link = 0; + seg1->serif = seg2->link; + } + } + } + } + + + FT_LOCAL_DEF( FT_Error ) + af_latin_hints_compute_edges( AF_GlyphHints hints, + AF_Dimension dim ) + { + AF_AxisHints axis = &hints->axis[dim]; + FT_Error error = AF_Err_Ok; + FT_Memory memory = hints->memory; + AF_LatinAxis laxis = &((AF_LatinMetrics)hints->metrics)->axis[dim]; + + AF_Segment segments = axis->segments; + AF_Segment segment_limit = segments + axis->num_segments; + AF_Segment seg; + + AF_Direction up_dir; + FT_Fixed scale; + FT_Pos edge_distance_threshold; + FT_Pos segment_length_threshold; + + + axis->num_edges = 0; + + scale = ( dim == AF_DIMENSION_HORZ ) ? hints->x_scale + : hints->y_scale; + + up_dir = ( dim == AF_DIMENSION_HORZ ) ? AF_DIR_UP + : AF_DIR_RIGHT; + + /* + * We ignore all segments that are less than 1 pixels in length, + * to avoid many problems with serif fonts. We compute the + * corresponding threshold in font units. + */ + if ( dim == AF_DIMENSION_HORZ ) + segment_length_threshold = FT_DivFix( 64, hints->y_scale ); + else + segment_length_threshold = 0; + + /*********************************************************************/ + /* */ + /* We will begin by generating a sorted table of edges for the */ + /* current direction. To do so, we simply scan each segment and try */ + /* to find an edge in our table that corresponds to its position. */ + /* */ + /* If no edge is found, we create and insert a new edge in the */ + /* sorted table. Otherwise, we simply add the segment to the edge's */ + /* list which will be processed in the second step to compute the */ + /* edge's properties. */ + /* */ + /* Note that the edges table is sorted along the segment/edge */ + /* position. */ + /* */ + /*********************************************************************/ + + edge_distance_threshold = FT_MulFix( laxis->edge_distance_threshold, + scale ); + if ( edge_distance_threshold > 64 / 4 ) + edge_distance_threshold = 64 / 4; + + edge_distance_threshold = FT_DivFix( edge_distance_threshold, + scale ); + + for ( seg = segments; seg < segment_limit; seg++ ) + { + AF_Edge found = 0; + FT_Int ee; + + + if ( seg->height < segment_length_threshold ) + continue; + + /* A special case for serif edges: If they are smaller than */ + /* 1.5 pixels we ignore them. */ + if ( seg->serif && + 2 * seg->height < 3 * segment_length_threshold ) + continue; + + /* look for an edge corresponding to the segment */ + for ( ee = 0; ee < axis->num_edges; ee++ ) + { + AF_Edge edge = axis->edges + ee; + FT_Pos dist; + + + dist = seg->pos - edge->fpos; + if ( dist < 0 ) + dist = -dist; + + if ( dist < edge_distance_threshold && edge->dir == seg->dir ) + { + found = edge; + break; + } + } + + if ( !found ) + { + AF_Edge edge; + + + /* insert a new edge in the list and */ + /* sort according to the position */ + error = af_axis_hints_new_edge( axis, seg->pos, + (AF_Direction)seg->dir, + memory, &edge ); + if ( error ) + goto Exit; + + /* add the segment to the new edge's list */ + FT_ZERO( edge ); + + edge->first = seg; + edge->last = seg; + edge->fpos = seg->pos; + edge->dir = seg->dir; + edge->opos = edge->pos = FT_MulFix( seg->pos, scale ); + seg->edge_next = seg; + } + else + { + /* if an edge was found, simply add the segment to the edge's */ + /* list */ + seg->edge_next = found->first; + found->last->edge_next = seg; + found->last = seg; + } + } + + + /*********************************************************************/ + /* */ + /* Good, we will now compute each edge's properties according to */ + /* segments found on its position. Basically, these are: */ + /* */ + /* - edge's main direction */ + /* - stem edge, serif edge or both (which defaults to stem then) */ + /* - rounded edge, straight or both (which defaults to straight) */ + /* - link for edge */ + /* */ + /*********************************************************************/ + + /* first of all, set the `edge' field in each segment -- this is */ + /* required in order to compute edge links */ + + /* + * Note that removing this loop and setting the `edge' field of each + * segment directly in the code above slows down execution speed for + * some reasons on platforms like the Sun. + */ + { + AF_Edge edges = axis->edges; + AF_Edge edge_limit = edges + axis->num_edges; + AF_Edge edge; + + + for ( edge = edges; edge < edge_limit; edge++ ) + { + seg = edge->first; + if ( seg ) + do + { + seg->edge = edge; + seg = seg->edge_next; + + } while ( seg != edge->first ); + } + + /* now, compute each edge properties */ + for ( edge = edges; edge < edge_limit; edge++ ) + { + FT_Int is_round = 0; /* does it contain round segments? */ + FT_Int is_straight = 0; /* does it contain straight segments? */ + FT_Pos ups = 0; /* number of upwards segments */ + FT_Pos downs = 0; /* number of downwards segments */ + + + seg = edge->first; + + do + { + FT_Bool is_serif; + + + /* check for roundness of segment */ + if ( seg->flags & AF_EDGE_ROUND ) + is_round++; + else + is_straight++; + + /* check for segment direction */ + if ( seg->dir == up_dir ) + ups += seg->max_coord-seg->min_coord; + else + downs += seg->max_coord-seg->min_coord; + + /* check for links -- if seg->serif is set, then seg->link must */ + /* be ignored */ + is_serif = (FT_Bool)( seg->serif && + seg->serif->edge && + seg->serif->edge != edge ); + + if ( ( seg->link && seg->link->edge != NULL ) || is_serif ) + { + AF_Edge edge2; + AF_Segment seg2; + + + edge2 = edge->link; + seg2 = seg->link; + + if ( is_serif ) + { + seg2 = seg->serif; + edge2 = edge->serif; + } + + if ( edge2 ) + { + FT_Pos edge_delta; + FT_Pos seg_delta; + + + edge_delta = edge->fpos - edge2->fpos; + if ( edge_delta < 0 ) + edge_delta = -edge_delta; + + seg_delta = seg->pos - seg2->pos; + if ( seg_delta < 0 ) + seg_delta = -seg_delta; + + if ( seg_delta < edge_delta ) + edge2 = seg2->edge; + } + else + edge2 = seg2->edge; + + if ( is_serif ) + { + edge->serif = edge2; + edge2->flags |= AF_EDGE_SERIF; + } + else + edge->link = edge2; + } + + seg = seg->edge_next; + + } while ( seg != edge->first ); + + /* set the round/straight flags */ + edge->flags = AF_EDGE_NORMAL; + + if ( is_round > 0 && is_round >= is_straight ) + edge->flags |= AF_EDGE_ROUND; + +#if 0 + /* set the edge's main direction */ + edge->dir = AF_DIR_NONE; + + if ( ups > downs ) + edge->dir = (FT_Char)up_dir; + + else if ( ups < downs ) + edge->dir = (FT_Char)-up_dir; + + else if ( ups == downs ) + edge->dir = 0; /* both up and down! */ +#endif + + /* gets rid of serifs if link is set */ + /* XXX: This gets rid of many unpleasant artefacts! */ + /* Example: the `c' in cour.pfa at size 13 */ + + if ( edge->serif && edge->link ) + edge->serif = 0; + } + } + + Exit: + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + af_latin_hints_detect_features( AF_GlyphHints hints, + AF_Dimension dim ) + { + FT_Error error; + + + error = af_latin_hints_compute_segments( hints, dim ); + if ( !error ) + { + af_latin_hints_link_segments( hints, dim ); + + error = af_latin_hints_compute_edges( hints, dim ); + } + return error; + } + + + FT_LOCAL_DEF( void ) + af_latin_hints_compute_blue_edges( AF_GlyphHints hints, + AF_LatinMetrics metrics ) + { + AF_AxisHints axis = &hints->axis[ AF_DIMENSION_VERT ]; + AF_Edge edge = axis->edges; + AF_Edge edge_limit = edge + axis->num_edges; + AF_LatinAxis latin = &metrics->axis[ AF_DIMENSION_VERT ]; + FT_Fixed scale = latin->scale; + + + /* compute which blue zones are active, i.e. have their scaled */ + /* size < 3/4 pixels */ + + /* for each horizontal edge search the blue zone which is closest */ + for ( ; edge < edge_limit; edge++ ) + { + FT_Int bb; + AF_Width best_blue = NULL; + FT_Pos best_dist; /* initial threshold */ + + + /* compute the initial threshold as a fraction of the EM size */ + best_dist = FT_MulFix( metrics->units_per_em / 40, scale ); + + if ( best_dist > 64 / 2 ) + best_dist = 64 / 2; + + for ( bb = 0; bb < AF_LATIN_BLUE_MAX; bb++ ) + { + AF_LatinBlue blue = latin->blues + bb; + FT_Bool is_top_blue, is_major_dir; + + + /* skip inactive blue zones (i.e., those that are too small) */ + if ( !( blue->flags & AF_LATIN_BLUE_ACTIVE ) ) + continue; + + /* if it is a top zone, check for right edges -- if it is a bottom */ + /* zone, check for left edges */ + /* */ + /* of course, that's for TrueType */ + is_top_blue = (FT_Byte)( ( blue->flags & AF_LATIN_BLUE_TOP ) != 0 ); + is_major_dir = FT_BOOL( edge->dir == axis->major_dir ); + + /* if it is a top zone, the edge must be against the major */ + /* direction; if it is a bottom zone, it must be in the major */ + /* direction */ + if ( is_top_blue ^ is_major_dir ) + { + FT_Pos dist; + + + /* first of all, compare it to the reference position */ + dist = edge->fpos - blue->ref.org; + if ( dist < 0 ) + dist = -dist; + + dist = FT_MulFix( dist, scale ); + if ( dist < best_dist ) + { + best_dist = dist; + best_blue = & blue->ref; + } + + /* now, compare it to the overshoot position if the edge is */ + /* rounded, and if the edge is over the reference position of a */ + /* top zone, or under the reference position of a bottom zone */ + if ( edge->flags & AF_EDGE_ROUND && dist != 0 ) + { + FT_Bool is_under_ref = FT_BOOL( edge->fpos < blue->ref.org ); + + + if ( is_top_blue ^ is_under_ref ) + { + blue = latin->blues + bb; + dist = edge->fpos - blue->shoot.org; + if ( dist < 0 ) + dist = -dist; + + dist = FT_MulFix( dist, scale ); + if ( dist < best_dist ) + { + best_dist = dist; + best_blue = & blue->shoot; + } + } + } + } + } + + if ( best_blue ) + edge->blue_edge = best_blue; + } + } + + + static FT_Error + af_latin_hints_init( AF_GlyphHints hints, + AF_LatinMetrics metrics ) + { + FT_Render_Mode mode; + FT_UInt32 scaler_flags, other_flags; + FT_Face face = metrics->root.scaler.face; + + + af_glyph_hints_rescale( hints, (AF_ScriptMetrics)metrics ); + + /* + * correct x_scale and y_scale if needed, since they may have + * been modified `af_latin_metrics_scale_dim' above + */ + hints->x_scale = metrics->axis[AF_DIMENSION_HORZ].scale; + hints->x_delta = metrics->axis[AF_DIMENSION_HORZ].delta; + hints->y_scale = metrics->axis[AF_DIMENSION_VERT].scale; + hints->y_delta = metrics->axis[AF_DIMENSION_VERT].delta; + + /* compute flags depending on render mode, etc. */ + mode = metrics->root.scaler.render_mode; + +#if 0 /* #ifdef AF_USE_WARPER */ + if ( mode == FT_RENDER_MODE_LCD || mode == FT_RENDER_MODE_LCD_V ) + { + metrics->root.scaler.render_mode = mode = FT_RENDER_MODE_NORMAL; + } +#endif + + scaler_flags = hints->scaler_flags; + other_flags = 0; + + /* + * We snap the width of vertical stems for the monochrome and + * horizontal LCD rendering targets only. + */ + if ( mode == FT_RENDER_MODE_MONO || mode == FT_RENDER_MODE_LCD ) + other_flags |= AF_LATIN_HINTS_HORZ_SNAP; + + /* + * We snap the width of horizontal stems for the monochrome and + * vertical LCD rendering targets only. + */ + if ( mode == FT_RENDER_MODE_MONO || mode == FT_RENDER_MODE_LCD_V ) + other_flags |= AF_LATIN_HINTS_VERT_SNAP; + + /* + * We adjust stems to full pixels only if we don't use the `light' mode. + */ + if ( mode != FT_RENDER_MODE_LIGHT ) + other_flags |= AF_LATIN_HINTS_STEM_ADJUST; + + if ( mode == FT_RENDER_MODE_MONO ) + other_flags |= AF_LATIN_HINTS_MONO; + + /* + * In `light' hinting mode we disable horizontal hinting completely. + * We also do it if the face is italic. + */ + if ( mode == FT_RENDER_MODE_LIGHT || + (face->style_flags & FT_STYLE_FLAG_ITALIC) != 0 ) + scaler_flags |= AF_SCALER_FLAG_NO_HORIZONTAL; + + hints->scaler_flags = scaler_flags; + hints->other_flags = other_flags; + + return 0; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** L A T I N G L Y P H G R I D - F I T T I N G *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* snap a given width in scaled coordinates to one of the */ + /* current standard widths */ + + static FT_Pos + af_latin_snap_width( AF_Width widths, + FT_Int count, + FT_Pos width ) + { + int n; + FT_Pos best = 64 + 32 + 2; + FT_Pos reference = width; + FT_Pos scaled; + + + for ( n = 0; n < count; n++ ) + { + FT_Pos w; + FT_Pos dist; + + + w = widths[n].cur; + dist = width - w; + if ( dist < 0 ) + dist = -dist; + if ( dist < best ) + { + best = dist; + reference = w; + } + } + + scaled = FT_PIX_ROUND( reference ); + + if ( width >= reference ) + { + if ( width < scaled + 48 ) + width = reference; + } + else + { + if ( width > scaled - 48 ) + width = reference; + } + + return width; + } + + + /* compute the snapped width of a given stem */ + + static FT_Pos + af_latin_compute_stem_width( AF_GlyphHints hints, + AF_Dimension dim, + FT_Pos width, + AF_Edge_Flags base_flags, + AF_Edge_Flags stem_flags ) + { + AF_LatinMetrics metrics = (AF_LatinMetrics) hints->metrics; + AF_LatinAxis axis = & metrics->axis[dim]; + FT_Pos dist = width; + FT_Int sign = 0; + FT_Int vertical = ( dim == AF_DIMENSION_VERT ); + + + if ( !AF_LATIN_HINTS_DO_STEM_ADJUST( hints ) || + axis->extra_light ) + return width; + + if ( dist < 0 ) + { + dist = -width; + sign = 1; + } + + if ( ( vertical && !AF_LATIN_HINTS_DO_VERT_SNAP( hints ) ) || + ( !vertical && !AF_LATIN_HINTS_DO_HORZ_SNAP( hints ) ) ) + { + /* smooth hinting process: very lightly quantize the stem width */ + + /* leave the widths of serifs alone */ + + if ( ( stem_flags & AF_EDGE_SERIF ) && vertical && ( dist < 3 * 64 ) ) + goto Done_Width; + + else if ( ( base_flags & AF_EDGE_ROUND ) ) + { + if ( dist < 80 ) + dist = 64; + } + else if ( dist < 56 ) + dist = 56; + + if ( axis->width_count > 0 ) + { + FT_Pos delta; + + + /* compare to standard width */ + if ( axis->width_count > 0 ) + { + delta = dist - axis->widths[0].cur; + + if ( delta < 0 ) + delta = -delta; + + if ( delta < 40 ) + { + dist = axis->widths[0].cur; + if ( dist < 48 ) + dist = 48; + + goto Done_Width; + } + } + + if ( dist < 3 * 64 ) + { + delta = dist & 63; + dist &= -64; + + if ( delta < 10 ) + dist += delta; + + else if ( delta < 32 ) + dist += 10; + + else if ( delta < 54 ) + dist += 54; + + else + dist += delta; + } + else + dist = ( dist + 32 ) & ~63; + } + } + else + { + /* strong hinting process: snap the stem width to integer pixels */ + FT_Pos org_dist = dist; + + + dist = af_latin_snap_width( axis->widths, axis->width_count, dist ); + + if ( vertical ) + { + /* in the case of vertical hinting, always round */ + /* the stem heights to integer pixels */ + + if ( dist >= 64 ) + dist = ( dist + 16 ) & ~63; + else + dist = 64; + } + else + { + if ( AF_LATIN_HINTS_DO_MONO( hints ) ) + { + /* monochrome horizontal hinting: snap widths to integer pixels */ + /* with a different threshold */ + + if ( dist < 64 ) + dist = 64; + else + dist = ( dist + 32 ) & ~63; + } + else + { + /* for horizontal anti-aliased hinting, we adopt a more subtle */ + /* approach: we strengthen small stems, round stems whose size */ + /* is between 1 and 2 pixels to an integer, otherwise nothing */ + + if ( dist < 48 ) + dist = ( dist + 64 ) >> 1; + + else if ( dist < 128 ) + { + /* We only round to an integer width if the corresponding */ + /* distortion is less than 1/4 pixel. Otherwise this */ + /* makes everything worse since the diagonals, which are */ + /* not hinted, appear a lot bolder or thinner than the */ + /* vertical stems. */ + + FT_Pos delta; + + + dist = ( dist + 22 ) & ~63; + delta = dist - org_dist; + if ( delta < 0 ) + delta = -delta; + + if (delta >= 16) + { + dist = org_dist; + if ( dist < 48 ) + dist = ( dist + 64 ) >> 1; + } + } + else + /* round otherwise to prevent color fringes in LCD mode */ + dist = ( dist + 32 ) & ~63; + } + } + } + + Done_Width: + if ( sign ) + dist = -dist; + + return dist; + } + + + /* align one stem edge relative to the previous stem edge */ + + static void + af_latin_align_linked_edge( AF_GlyphHints hints, + AF_Dimension dim, + AF_Edge base_edge, + AF_Edge stem_edge ) + { + FT_Pos dist = stem_edge->opos - base_edge->opos; + + FT_Pos fitted_width = af_latin_compute_stem_width( + hints, dim, dist, + (AF_Edge_Flags)base_edge->flags, + (AF_Edge_Flags)stem_edge->flags ); + + + stem_edge->pos = base_edge->pos + fitted_width; + + AF_LOG(( "LINK: edge %d (opos=%.2f) linked to (%.2f), " + "dist was %.2f, now %.2f\n", + stem_edge-hints->axis[dim].edges, stem_edge->opos / 64.0, + stem_edge->pos / 64.0, dist / 64.0, fitted_width / 64.0 )); + } + + + static void + af_latin_align_serif_edge( AF_GlyphHints hints, + AF_Edge base, + AF_Edge serif ) + { + FT_UNUSED( hints ); + + serif->pos = base->pos + (serif->opos - base->opos); + } + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** E D G E H I N T I N G ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + FT_LOCAL_DEF( void ) + af_latin_hint_edges( AF_GlyphHints hints, + AF_Dimension dim ) + { + AF_AxisHints axis = &hints->axis[dim]; + AF_Edge edges = axis->edges; + AF_Edge edge_limit = edges + axis->num_edges; + FT_PtrDist n_edges; + AF_Edge edge; + AF_Edge anchor = 0; + FT_Int has_serifs = 0; + + + /* we begin by aligning all stems relative to the blue zone */ + /* if needed -- that's only for horizontal edges */ + + if ( dim == AF_DIMENSION_VERT && AF_HINTS_DO_BLUES( hints ) ) + { + for ( edge = edges; edge < edge_limit; edge++ ) + { + AF_Width blue; + AF_Edge edge1, edge2; + + + if ( edge->flags & AF_EDGE_DONE ) + continue; + + blue = edge->blue_edge; + edge1 = NULL; + edge2 = edge->link; + + if ( blue ) + { + edge1 = edge; + } + else if ( edge2 && edge2->blue_edge ) + { + blue = edge2->blue_edge; + edge1 = edge2; + edge2 = edge; + } + + if ( !edge1 ) + continue; + + AF_LOG(( "BLUE: edge %d (opos=%.2f) snapped to (%.2f), " + "was (%.2f)\n", + edge1-edges, edge1->opos / 64.0, blue->fit / 64.0, + edge1->pos / 64.0 )); + + edge1->pos = blue->fit; + edge1->flags |= AF_EDGE_DONE; + + if ( edge2 && !edge2->blue_edge ) + { + af_latin_align_linked_edge( hints, dim, edge1, edge2 ); + edge2->flags |= AF_EDGE_DONE; + } + + if ( !anchor ) + anchor = edge; + } + } + + /* now we will align all stem edges, trying to maintain the */ + /* relative order of stems in the glyph */ + for ( edge = edges; edge < edge_limit; edge++ ) + { + AF_Edge edge2; + + + if ( edge->flags & AF_EDGE_DONE ) + continue; + + /* skip all non-stem edges */ + edge2 = edge->link; + if ( !edge2 ) + { + has_serifs++; + continue; + } + + /* now align the stem */ + + /* this should not happen, but it's better to be safe */ + if ( edge2->blue_edge ) + { + AF_LOG(( "ASSERTION FAILED for edge %d\n", edge2-edges )); + + af_latin_align_linked_edge( hints, dim, edge2, edge ); + edge->flags |= AF_EDGE_DONE; + continue; + } + + if ( !anchor ) + { + FT_Pos org_len, org_center, cur_len; + FT_Pos cur_pos1, error1, error2, u_off, d_off; + + + org_len = edge2->opos - edge->opos; + cur_len = af_latin_compute_stem_width( + hints, dim, org_len, + (AF_Edge_Flags)edge->flags, + (AF_Edge_Flags)edge2->flags ); + if ( cur_len <= 64 ) + u_off = d_off = 32; + else + { + u_off = 38; + d_off = 26; + } + + if ( cur_len < 96 ) + { + org_center = edge->opos + ( org_len >> 1 ); + + cur_pos1 = FT_PIX_ROUND( org_center ); + + error1 = org_center - ( cur_pos1 - u_off ); + if ( error1 < 0 ) + error1 = -error1; + + error2 = org_center - ( cur_pos1 + d_off ); + if ( error2 < 0 ) + error2 = -error2; + + if ( error1 < error2 ) + cur_pos1 -= u_off; + else + cur_pos1 += d_off; + + edge->pos = cur_pos1 - cur_len / 2; + edge2->pos = edge->pos + cur_len; + } + else + edge->pos = FT_PIX_ROUND( edge->opos ); + + AF_LOG(( "ANCHOR: edge %d (opos=%.2f) and %d (opos=%.2f) " + "snapped to (%.2f) (%.2f)\n", + edge-edges, edge->opos / 64.0, + edge2-edges, edge2->opos / 64.0, + edge->pos / 64.0, edge2->pos / 64.0 )); + anchor = edge; + + edge->flags |= AF_EDGE_DONE; + + af_latin_align_linked_edge( hints, dim, edge, edge2 ); + } + else + { + FT_Pos org_pos, org_len, org_center, cur_len; + FT_Pos cur_pos1, cur_pos2, delta1, delta2; + + + org_pos = anchor->pos + ( edge->opos - anchor->opos ); + org_len = edge2->opos - edge->opos; + org_center = org_pos + ( org_len >> 1 ); + + cur_len = af_latin_compute_stem_width( + hints, dim, org_len, + (AF_Edge_Flags)edge->flags, + (AF_Edge_Flags)edge2->flags ); + + if ( edge2->flags & AF_EDGE_DONE ) + edge->pos = edge2->pos - cur_len; + + else if ( cur_len < 96 ) + { + FT_Pos u_off, d_off; + + + cur_pos1 = FT_PIX_ROUND( org_center ); + + if (cur_len <= 64 ) + u_off = d_off = 32; + else + { + u_off = 38; + d_off = 26; + } + + delta1 = org_center - ( cur_pos1 - u_off ); + if ( delta1 < 0 ) + delta1 = -delta1; + + delta2 = org_center - ( cur_pos1 + d_off ); + if ( delta2 < 0 ) + delta2 = -delta2; + + if ( delta1 < delta2 ) + cur_pos1 -= u_off; + else + cur_pos1 += d_off; + + edge->pos = cur_pos1 - cur_len / 2; + edge2->pos = cur_pos1 + cur_len / 2; + + AF_LOG(( "STEM: %d (opos=%.2f) to %d (opos=%.2f) " + "snapped to (%.2f) and (%.2f)\n", + edge-edges, edge->opos / 64.0, + edge2-edges, edge2->opos / 64.0, + edge->pos / 64.0, edge2->pos / 64.0 )); + } + else + { + org_pos = anchor->pos + ( edge->opos - anchor->opos ); + org_len = edge2->opos - edge->opos; + org_center = org_pos + ( org_len >> 1 ); + + cur_len = af_latin_compute_stem_width( + hints, dim, org_len, + (AF_Edge_Flags)edge->flags, + (AF_Edge_Flags)edge2->flags ); + + cur_pos1 = FT_PIX_ROUND( org_pos ); + delta1 = cur_pos1 + ( cur_len >> 1 ) - org_center; + if ( delta1 < 0 ) + delta1 = -delta1; + + cur_pos2 = FT_PIX_ROUND( org_pos + org_len ) - cur_len; + delta2 = cur_pos2 + ( cur_len >> 1 ) - org_center; + if ( delta2 < 0 ) + delta2 = -delta2; + + edge->pos = ( delta1 < delta2 ) ? cur_pos1 : cur_pos2; + edge2->pos = edge->pos + cur_len; + + AF_LOG(( "STEM: %d (opos=%.2f) to %d (opos=%.2f) " + "snapped to (%.2f) and (%.2f)\n", + edge-edges, edge->opos / 64.0, + edge2-edges, edge2->opos / 64.0, + edge->pos / 64.0, edge2->pos / 64.0 )); + } + + edge->flags |= AF_EDGE_DONE; + edge2->flags |= AF_EDGE_DONE; + + if ( edge > edges && edge->pos < edge[-1].pos ) + { + AF_LOG(( "BOUND: %d (pos=%.2f) to (%.2f)\n", + edge-edges, edge->pos / 64.0, edge[-1].pos / 64.0 )); + edge->pos = edge[-1].pos; + } + } + } + + /* make sure that lowercase m's maintain their symmetry */ + + /* In general, lowercase m's have six vertical edges if they are sans */ + /* serif, or twelve if they are with serifs. This implementation is */ + /* based on that assumption, and seems to work very well with most */ + /* faces. However, if for a certain face this assumption is not */ + /* true, the m is just rendered like before. In addition, any stem */ + /* correction will only be applied to symmetrical glyphs (even if the */ + /* glyph is not an m), so the potential for unwanted distortion is */ + /* relatively low. */ + + /* We don't handle horizontal edges since we can't easily assure that */ + /* the third (lowest) stem aligns with the base line; it might end up */ + /* one pixel higher or lower. */ + + n_edges = edge_limit - edges; + if ( dim == AF_DIMENSION_HORZ && ( n_edges == 6 || n_edges == 12 ) ) + { + AF_Edge edge1, edge2, edge3; + FT_Pos dist1, dist2, span, delta; + + + if ( n_edges == 6 ) + { + edge1 = edges; + edge2 = edges + 2; + edge3 = edges + 4; + } + else + { + edge1 = edges + 1; + edge2 = edges + 5; + edge3 = edges + 9; + } + + dist1 = edge2->opos - edge1->opos; + dist2 = edge3->opos - edge2->opos; + + span = dist1 - dist2; + if ( span < 0 ) + span = -span; + + if ( span < 8 ) + { + delta = edge3->pos - ( 2 * edge2->pos - edge1->pos ); + edge3->pos -= delta; + if ( edge3->link ) + edge3->link->pos -= delta; + + /* move the serifs along with the stem */ + if ( n_edges == 12 ) + { + ( edges + 8 )->pos -= delta; + ( edges + 11 )->pos -= delta; + } + + edge3->flags |= AF_EDGE_DONE; + if ( edge3->link ) + edge3->link->flags |= AF_EDGE_DONE; + } + } + + if ( has_serifs || !anchor ) + { + /* + * now hint the remaining edges (serifs and single) in order + * to complete our processing + */ + for ( edge = edges; edge < edge_limit; edge++ ) + { + FT_Pos delta; + + + if ( edge->flags & AF_EDGE_DONE ) + continue; + + delta = 1000; + + if ( edge->serif ) + { + delta = edge->serif->opos - edge->opos; + if ( delta < 0 ) + delta = -delta; + } + + if ( delta < 64 + 16 ) + { + af_latin_align_serif_edge( hints, edge->serif, edge ); + AF_LOG(( "SERIF: edge %d (opos=%.2f) serif to %d (opos=%.2f) " + "aligned to (%.2f)\n", + edge-edges, edge->opos / 64.0, + edge->serif - edges, edge->serif->opos / 64.0, + edge->pos / 64.0 )); + } + else if ( !anchor ) + { + AF_LOG(( "SERIF_ANCHOR: edge %d (opos=%.2f) snapped to (%.2f)\n", + edge-edges, edge->opos / 64.0, edge->pos / 64.0 )); + edge->pos = FT_PIX_ROUND( edge->opos ); + anchor = edge; + } + else + { + AF_Edge before, after; + + + for ( before = edge - 1; before >= edges; before-- ) + if ( before->flags & AF_EDGE_DONE ) + break; + + for ( after = edge + 1; after < edge_limit; after++ ) + if ( after->flags & AF_EDGE_DONE ) + break; + + if ( before >= edges && before < edge && + after < edge_limit && after > edge ) + { + if ( after->opos == before->opos ) + edge->pos = before->pos; + else + edge->pos = before->pos + + FT_MulDiv( edge->opos - before->opos, + after->pos - before->pos, + after->opos - before->opos ); + AF_LOG(( "SERIF_LINK1: edge %d (opos=%.2f) snapped to (%.2f) " + "from %d (opos=%.2f)\n", + edge-edges, edge->opos / 64.0, + edge->pos / 64.0, before - edges, + before->opos / 64.0 )); + } + else + { + edge->pos = anchor->pos + + ( ( edge->opos - anchor->opos + 16 ) & ~31 ); + AF_LOG(( "SERIF_LINK2: edge %d (opos=%.2f) snapped to (%.2f)\n", + edge-edges, edge->opos / 64.0, edge->pos / 64.0 )); + } + } + + edge->flags |= AF_EDGE_DONE; + + if ( edge > edges && edge->pos < edge[-1].pos ) + edge->pos = edge[-1].pos; + + if ( edge + 1 < edge_limit && + edge[1].flags & AF_EDGE_DONE && + edge->pos > edge[1].pos ) + edge->pos = edge[1].pos; + } + } + } + + + static FT_Error + af_latin_hints_apply( AF_GlyphHints hints, + FT_Outline* outline, + AF_LatinMetrics metrics ) + { + FT_Error error; + int dim; + + + error = af_glyph_hints_reload( hints, outline, 1 ); + if ( error ) + goto Exit; + + /* analyze glyph outline */ +#ifdef AF_USE_WARPER + if ( metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT || + AF_HINTS_DO_HORIZONTAL( hints ) ) +#else + if ( AF_HINTS_DO_HORIZONTAL( hints ) ) +#endif + { + error = af_latin_hints_detect_features( hints, AF_DIMENSION_HORZ ); + if ( error ) + goto Exit; + } + + if ( AF_HINTS_DO_VERTICAL( hints ) ) + { + error = af_latin_hints_detect_features( hints, AF_DIMENSION_VERT ); + if ( error ) + goto Exit; + + af_latin_hints_compute_blue_edges( hints, metrics ); + } + + /* grid-fit the outline */ + for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) + { +#ifdef AF_USE_WARPER + if ( ( dim == AF_DIMENSION_HORZ && + metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT ) ) + { + AF_WarperRec warper; + FT_Fixed scale; + FT_Pos delta; + + + af_warper_compute( &warper, hints, dim, &scale, &delta ); + af_glyph_hints_scale_dim( hints, dim, scale, delta ); + continue; + } +#endif + + if ( ( dim == AF_DIMENSION_HORZ && AF_HINTS_DO_HORIZONTAL( hints ) ) || + ( dim == AF_DIMENSION_VERT && AF_HINTS_DO_VERTICAL( hints ) ) ) + { + af_latin_hint_edges( hints, (AF_Dimension)dim ); + af_glyph_hints_align_edge_points( hints, (AF_Dimension)dim ); + af_glyph_hints_align_strong_points( hints, (AF_Dimension)dim ); + af_glyph_hints_align_weak_points( hints, (AF_Dimension)dim ); + } + } + af_glyph_hints_save( hints, outline ); + + Exit: + return error; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** L A T I N S C R I P T C L A S S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + /* XXX: this should probably fine tuned to differentiate better between */ + /* scripts... */ + + static const AF_Script_UniRangeRec af_latin_uniranges[] = + { + AF_UNIRANGE_REC( 0x0020UL, 0x007FUL ), /* Basic Latin (no control chars) */ + AF_UNIRANGE_REC( 0x00A0UL, 0x00FFUL ), /* Latin-1 Supplement (no control chars) */ + AF_UNIRANGE_REC( 0x0100UL, 0x017FUL ), /* Latin Extended-A */ + AF_UNIRANGE_REC( 0x0180UL, 0x024FUL ), /* Latin Extended-B */ + AF_UNIRANGE_REC( 0x0250UL, 0x02AFUL ), /* IPA Extensions */ + AF_UNIRANGE_REC( 0x02B0UL, 0x02FFUL ), /* Spacing Modifier Letters */ + AF_UNIRANGE_REC( 0x0300UL, 0x036FUL ), /* Combining Diacritical Marks */ + AF_UNIRANGE_REC( 0x0370UL, 0x03FFUL ), /* Greek and Coptic */ + AF_UNIRANGE_REC( 0x0400UL, 0x04FFUL ), /* Cyrillic */ + AF_UNIRANGE_REC( 0x0500UL, 0x052FUL ), /* Cyrillic Supplement */ + AF_UNIRANGE_REC( 0x1D00UL, 0x1D7FUL ), /* Phonetic Extensions */ + AF_UNIRANGE_REC( 0x1D80UL, 0x1DBFUL ), /* Phonetic Extensions Supplement */ + AF_UNIRANGE_REC( 0x1DC0UL, 0x1DFFUL ), /* Combining Diacritical Marks Supplement */ + AF_UNIRANGE_REC( 0x1E00UL, 0x1EFFUL ), /* Latin Extended Additional */ + AF_UNIRANGE_REC( 0x1F00UL, 0x1FFFUL ), /* Greek Extended */ + AF_UNIRANGE_REC( 0x2000UL, 0x206FUL ), /* General Punctuation */ + AF_UNIRANGE_REC( 0x2070UL, 0x209FUL ), /* Superscripts and Subscripts */ + AF_UNIRANGE_REC( 0x20A0UL, 0x20CFUL ), /* Currency Symbols */ + AF_UNIRANGE_REC( 0x2150UL, 0x218FUL ), /* Number Forms */ + AF_UNIRANGE_REC( 0x2460UL, 0x24FFUL ), /* Enclosed Alphanumerics */ + AF_UNIRANGE_REC( 0x2C60UL, 0x2C7FUL ), /* Latin Extended-C */ + AF_UNIRANGE_REC( 0x2DE0UL, 0x2DFFUL ), /* Cyrillic Extended-A */ + AF_UNIRANGE_REC( 0xA640UL, 0xA69FUL ), /* Cyrillic Extended-B */ + AF_UNIRANGE_REC( 0xA720UL, 0xA7FFUL ), /* Latin Extended-D */ + AF_UNIRANGE_REC( 0xFB00UL, 0xFB06UL ), /* Alphab. Present. Forms (Latin Ligs) */ + AF_UNIRANGE_REC( 0x1D400UL, 0x1D7FFUL ), /* Mathematical Alphanumeric Symbols */ + AF_UNIRANGE_REC( 0UL, 0UL ) + }; + + + AF_DEFINE_SCRIPT_CLASS(af_latin_script_class, + AF_SCRIPT_LATIN, + af_latin_uniranges, + + sizeof( AF_LatinMetricsRec ), + + (AF_Script_InitMetricsFunc) af_latin_metrics_init, + (AF_Script_ScaleMetricsFunc)af_latin_metrics_scale, + (AF_Script_DoneMetricsFunc) NULL, + + (AF_Script_InitHintsFunc) af_latin_hints_init, + (AF_Script_ApplyHintsFunc) af_latin_hints_apply + ) + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/autofit/aflatin.h b/mod/pub.mod/freetype.mod/src/autofit/aflatin.h new file mode 100644 index 0000000..660b10c --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/autofit/aflatin.h @@ -0,0 +1,212 @@ +/***************************************************************************/ +/* */ +/* aflatin.h */ +/* */ +/* Auto-fitter hinting routines for latin script (specification). */ +/* */ +/* Copyright 2003, 2004, 2005, 2006, 2007, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __AFLATIN_H__ +#define __AFLATIN_H__ + +#include "afhints.h" + + +FT_BEGIN_HEADER + + + /* the latin-specific script class */ + + AF_DECLARE_SCRIPT_CLASS(af_latin_script_class) + + +/* constants are given with units_per_em == 2048 in mind */ +#define AF_LATIN_CONSTANT( metrics, c ) \ + ( ( (c) * (FT_Long)( (AF_LatinMetrics)(metrics) )->units_per_em ) / 2048 ) + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** L A T I N G L O B A L M E T R I C S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + /* + * The following declarations could be embedded in the file `aflatin.c'; + * they have been made semi-public to allow alternate script hinters to + * re-use some of them. + */ + + + /* Latin (global) metrics management */ + + enum + { + AF_LATIN_BLUE_CAPITAL_TOP, + AF_LATIN_BLUE_CAPITAL_BOTTOM, + AF_LATIN_BLUE_SMALL_F_TOP, + AF_LATIN_BLUE_SMALL_TOP, + AF_LATIN_BLUE_SMALL_BOTTOM, + AF_LATIN_BLUE_SMALL_MINOR, + + AF_LATIN_BLUE_MAX + }; + + +#define AF_LATIN_IS_TOP_BLUE( b ) ( (b) == AF_LATIN_BLUE_CAPITAL_TOP || \ + (b) == AF_LATIN_BLUE_SMALL_F_TOP || \ + (b) == AF_LATIN_BLUE_SMALL_TOP ) + +#define AF_LATIN_MAX_WIDTHS 16 +#define AF_LATIN_MAX_BLUES AF_LATIN_BLUE_MAX + + + enum + { + AF_LATIN_BLUE_ACTIVE = 1 << 0, + AF_LATIN_BLUE_TOP = 1 << 1, + AF_LATIN_BLUE_ADJUSTMENT = 1 << 2, /* used for scale adjustment */ + /* optimization */ + AF_LATIN_BLUE_FLAG_MAX + }; + + + typedef struct AF_LatinBlueRec_ + { + AF_WidthRec ref; + AF_WidthRec shoot; + FT_UInt flags; + + } AF_LatinBlueRec, *AF_LatinBlue; + + + typedef struct AF_LatinAxisRec_ + { + FT_Fixed scale; + FT_Pos delta; + + FT_UInt width_count; + AF_WidthRec widths[AF_LATIN_MAX_WIDTHS]; + FT_Pos edge_distance_threshold; + FT_Pos standard_width; + FT_Bool extra_light; + + /* ignored for horizontal metrics */ + FT_Bool control_overshoot; + FT_UInt blue_count; + AF_LatinBlueRec blues[AF_LATIN_BLUE_MAX]; + + FT_Fixed org_scale; + FT_Pos org_delta; + + } AF_LatinAxisRec, *AF_LatinAxis; + + + typedef struct AF_LatinMetricsRec_ + { + AF_ScriptMetricsRec root; + FT_UInt units_per_em; + AF_LatinAxisRec axis[AF_DIMENSION_MAX]; + + } AF_LatinMetricsRec, *AF_LatinMetrics; + + + FT_LOCAL( FT_Error ) + af_latin_metrics_init( AF_LatinMetrics metrics, + FT_Face face ); + + FT_LOCAL( void ) + af_latin_metrics_scale( AF_LatinMetrics metrics, + AF_Scaler scaler ); + + FT_LOCAL( void ) + af_latin_metrics_init_widths( AF_LatinMetrics metrics, + FT_Face face, + FT_ULong charcode ); + + FT_LOCAL( void ) + af_latin_metrics_check_digits( AF_LatinMetrics metrics, + FT_Face face ); + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** L A T I N G L Y P H A N A L Y S I S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + enum + { + AF_LATIN_HINTS_HORZ_SNAP = 1 << 0, /* enable stem width snapping */ + AF_LATIN_HINTS_VERT_SNAP = 1 << 1, /* enable stem height snapping */ + AF_LATIN_HINTS_STEM_ADJUST = 1 << 2, /* enable stem width/height */ + /* adjustment */ + AF_LATIN_HINTS_MONO = 1 << 3 /* indicate monochrome */ + /* rendering */ + }; + + +#define AF_LATIN_HINTS_DO_HORZ_SNAP( h ) \ + AF_HINTS_TEST_OTHER( h, AF_LATIN_HINTS_HORZ_SNAP ) + +#define AF_LATIN_HINTS_DO_VERT_SNAP( h ) \ + AF_HINTS_TEST_OTHER( h, AF_LATIN_HINTS_VERT_SNAP ) + +#define AF_LATIN_HINTS_DO_STEM_ADJUST( h ) \ + AF_HINTS_TEST_OTHER( h, AF_LATIN_HINTS_STEM_ADJUST ) + +#define AF_LATIN_HINTS_DO_MONO( h ) \ + AF_HINTS_TEST_OTHER( h, AF_LATIN_HINTS_MONO ) + + + /* + * This shouldn't normally be exported. However, other scripts might + * like to use this function as-is. + */ + FT_LOCAL( FT_Error ) + af_latin_hints_compute_segments( AF_GlyphHints hints, + AF_Dimension dim ); + + /* + * This shouldn't normally be exported. However, other scripts might + * want to use this function as-is. + */ + FT_LOCAL( void ) + af_latin_hints_link_segments( AF_GlyphHints hints, + AF_Dimension dim ); + + /* + * This shouldn't normally be exported. However, other scripts might + * want to use this function as-is. + */ + FT_LOCAL( FT_Error ) + af_latin_hints_compute_edges( AF_GlyphHints hints, + AF_Dimension dim ); + + FT_LOCAL( FT_Error ) + af_latin_hints_detect_features( AF_GlyphHints hints, + AF_Dimension dim ); + +/* */ + +FT_END_HEADER + +#endif /* __AFLATIN_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/autofit/aflatin2.c b/mod/pub.mod/freetype.mod/src/autofit/aflatin2.c new file mode 100644 index 0000000..5e2ad48 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/autofit/aflatin2.c @@ -0,0 +1,2344 @@ +/***************************************************************************/ +/* */ +/* aflatin.c */ +/* */ +/* Auto-fitter hinting routines for latin script (body). */ +/* */ +/* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include FT_ADVANCES_H + +#include "aflatin.h" +#include "aflatin2.h" +#include "aferrors.h" + + +#ifdef AF_USE_WARPER +#include "afwarp.h" +#endif + + FT_LOCAL_DEF( FT_Error ) + af_latin2_hints_compute_segments( AF_GlyphHints hints, + AF_Dimension dim ); + + FT_LOCAL_DEF( void ) + af_latin2_hints_link_segments( AF_GlyphHints hints, + AF_Dimension dim ); + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** L A T I N G L O B A L M E T R I C S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL_DEF( void ) + af_latin2_metrics_init_widths( AF_LatinMetrics metrics, + FT_Face face, + FT_ULong charcode ) + { + /* scan the array of segments in each direction */ + AF_GlyphHintsRec hints[1]; + + + af_glyph_hints_init( hints, face->memory ); + + metrics->axis[AF_DIMENSION_HORZ].width_count = 0; + metrics->axis[AF_DIMENSION_VERT].width_count = 0; + + { + FT_Error error; + FT_UInt glyph_index; + int dim; + AF_LatinMetricsRec dummy[1]; + AF_Scaler scaler = &dummy->root.scaler; + + + glyph_index = FT_Get_Char_Index( face, charcode ); + if ( glyph_index == 0 ) + goto Exit; + + error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE ); + if ( error || face->glyph->outline.n_points <= 0 ) + goto Exit; + + FT_ZERO( dummy ); + + dummy->units_per_em = metrics->units_per_em; + scaler->x_scale = scaler->y_scale = 0x10000L; + scaler->x_delta = scaler->y_delta = 0; + scaler->face = face; + scaler->render_mode = FT_RENDER_MODE_NORMAL; + scaler->flags = 0; + + af_glyph_hints_rescale( hints, (AF_ScriptMetrics)dummy ); + + error = af_glyph_hints_reload( hints, &face->glyph->outline, 0 ); + if ( error ) + goto Exit; + + for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) + { + AF_LatinAxis axis = &metrics->axis[dim]; + AF_AxisHints axhints = &hints->axis[dim]; + AF_Segment seg, limit, link; + FT_UInt num_widths = 0; + + + error = af_latin2_hints_compute_segments( hints, + (AF_Dimension)dim ); + if ( error ) + goto Exit; + + af_latin2_hints_link_segments( hints, + (AF_Dimension)dim ); + + seg = axhints->segments; + limit = seg + axhints->num_segments; + + for ( ; seg < limit; seg++ ) + { + link = seg->link; + + /* we only consider stem segments there! */ + if ( link && link->link == seg && link > seg ) + { + FT_Pos dist; + + + dist = seg->pos - link->pos; + if ( dist < 0 ) + dist = -dist; + + if ( num_widths < AF_LATIN_MAX_WIDTHS ) + axis->widths[ num_widths++ ].org = dist; + } + } + + af_sort_widths( num_widths, axis->widths ); + axis->width_count = num_widths; + } + + Exit: + for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) + { + AF_LatinAxis axis = &metrics->axis[dim]; + FT_Pos stdw; + + + stdw = ( axis->width_count > 0 ) + ? axis->widths[0].org + : AF_LATIN_CONSTANT( metrics, 50 ); + + /* let's try 20% of the smallest width */ + axis->edge_distance_threshold = stdw / 5; + axis->standard_width = stdw; + axis->extra_light = 0; + } + } + + af_glyph_hints_done( hints ); + } + + + +#define AF_LATIN_MAX_TEST_CHARACTERS 12 + + + static const char af_latin2_blue_chars[AF_LATIN_MAX_BLUES][AF_LATIN_MAX_TEST_CHARACTERS+1] = + { + "THEZOCQS", + "HEZLOCUS", + "fijkdbh", + "xzroesc", + "xzroesc", + "pqgjy" + }; + + + static void + af_latin2_metrics_init_blues( AF_LatinMetrics metrics, + FT_Face face ) + { + FT_Pos flats [AF_LATIN_MAX_TEST_CHARACTERS]; + FT_Pos rounds[AF_LATIN_MAX_TEST_CHARACTERS]; + FT_Int num_flats; + FT_Int num_rounds; + FT_Int bb; + AF_LatinBlue blue; + FT_Error error; + AF_LatinAxis axis = &metrics->axis[AF_DIMENSION_VERT]; + FT_GlyphSlot glyph = face->glyph; + + + /* we compute the blues simply by loading each character from the */ + /* 'af_latin2_blue_chars[blues]' string, then compute its top-most or */ + /* bottom-most points (depending on `AF_IS_TOP_BLUE') */ + + AF_LOG(( "blue zones computation\n" )); + AF_LOG(( "------------------------------------------------\n" )); + + for ( bb = 0; bb < AF_LATIN_BLUE_MAX; bb++ ) + { + const char* p = af_latin2_blue_chars[bb]; + const char* limit = p + AF_LATIN_MAX_TEST_CHARACTERS; + FT_Pos* blue_ref; + FT_Pos* blue_shoot; + + + AF_LOG(( "blue %3d: ", bb )); + + num_flats = 0; + num_rounds = 0; + + for ( ; p < limit && *p; p++ ) + { + FT_UInt glyph_index; + FT_Int best_point, best_y, best_first, best_last; + FT_Vector* points; + FT_Bool round; + + + AF_LOG(( "'%c'", *p )); + + /* load the character in the face -- skip unknown or empty ones */ + glyph_index = FT_Get_Char_Index( face, (FT_UInt)*p ); + if ( glyph_index == 0 ) + continue; + + error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE ); + if ( error || glyph->outline.n_points <= 0 ) + continue; + + /* now compute min or max point indices and coordinates */ + points = glyph->outline.points; + best_point = -1; + best_y = 0; /* make compiler happy */ + best_first = 0; /* ditto */ + best_last = 0; /* ditto */ + + { + FT_Int nn; + FT_Int first = 0; + FT_Int last = -1; + + + for ( nn = 0; nn < glyph->outline.n_contours; first = last+1, nn++ ) + { + FT_Int old_best_point = best_point; + FT_Int pp; + + + last = glyph->outline.contours[nn]; + + /* Avoid single-point contours since they are never rasterized. */ + /* In some fonts, they correspond to mark attachment points */ + /* which are way outside of the glyph's real outline. */ + if ( last == first ) + continue; + + if ( AF_LATIN_IS_TOP_BLUE( bb ) ) + { + for ( pp = first; pp <= last; pp++ ) + if ( best_point < 0 || points[pp].y > best_y ) + { + best_point = pp; + best_y = points[pp].y; + } + } + else + { + for ( pp = first; pp <= last; pp++ ) + if ( best_point < 0 || points[pp].y < best_y ) + { + best_point = pp; + best_y = points[pp].y; + } + } + + if ( best_point != old_best_point ) + { + best_first = first; + best_last = last; + } + } + AF_LOG(( "%5d", best_y )); + } + + /* now check whether the point belongs to a straight or round */ + /* segment; we first need to find in which contour the extremum */ + /* lies, then inspect its previous and next points */ + { + FT_Int start, end, prev, next; + FT_Pos dist; + + + /* now look for the previous and next points that are not on the */ + /* same Y coordinate. Threshold the `closeness'... */ + start = end = best_point; + + do + { + prev = start-1; + if ( prev < best_first ) + prev = best_last; + + dist = points[prev].y - best_y; + if ( dist < -5 || dist > 5 ) + break; + + start = prev; + + } while ( start != best_point ); + + do + { + next = end+1; + if ( next > best_last ) + next = best_first; + + dist = points[next].y - best_y; + if ( dist < -5 || dist > 5 ) + break; + + end = next; + + } while ( end != best_point ); + + /* now, set the `round' flag depending on the segment's kind */ + round = FT_BOOL( + FT_CURVE_TAG( glyph->outline.tags[start] ) != FT_CURVE_TAG_ON || + FT_CURVE_TAG( glyph->outline.tags[ end ] ) != FT_CURVE_TAG_ON ); + + AF_LOG(( "%c ", round ? 'r' : 'f' )); + } + + if ( round ) + rounds[num_rounds++] = best_y; + else + flats[num_flats++] = best_y; + } + + AF_LOG(( "\n" )); + + if ( num_flats == 0 && num_rounds == 0 ) + { + /* + * we couldn't find a single glyph to compute this blue zone, + * we will simply ignore it then + */ + AF_LOG(( "empty\n" )); + continue; + } + + /* we have computed the contents of the `rounds' and `flats' tables, */ + /* now determine the reference and overshoot position of the blue -- */ + /* we simply take the median value after a simple sort */ + af_sort_pos( num_rounds, rounds ); + af_sort_pos( num_flats, flats ); + + blue = & axis->blues[axis->blue_count]; + blue_ref = & blue->ref.org; + blue_shoot = & blue->shoot.org; + + axis->blue_count++; + + if ( num_flats == 0 ) + { + *blue_ref = + *blue_shoot = rounds[num_rounds / 2]; + } + else if ( num_rounds == 0 ) + { + *blue_ref = + *blue_shoot = flats[num_flats / 2]; + } + else + { + *blue_ref = flats[num_flats / 2]; + *blue_shoot = rounds[num_rounds / 2]; + } + + /* there are sometimes problems: if the overshoot position of top */ + /* zones is under its reference position, or the opposite for bottom */ + /* zones. We must thus check everything there and correct the errors */ + if ( *blue_shoot != *blue_ref ) + { + FT_Pos ref = *blue_ref; + FT_Pos shoot = *blue_shoot; + FT_Bool over_ref = FT_BOOL( shoot > ref ); + + + if ( AF_LATIN_IS_TOP_BLUE( bb ) ^ over_ref ) + *blue_shoot = *blue_ref = ( shoot + ref ) / 2; + } + + blue->flags = 0; + if ( AF_LATIN_IS_TOP_BLUE( bb ) ) + blue->flags |= AF_LATIN_BLUE_TOP; + + /* + * The following flags is used later to adjust the y and x scales + * in order to optimize the pixel grid alignment of the top of small + * letters. + */ + if ( bb == AF_LATIN_BLUE_SMALL_TOP ) + blue->flags |= AF_LATIN_BLUE_ADJUSTMENT; + + AF_LOG(( "-- ref = %ld, shoot = %ld\n", *blue_ref, *blue_shoot )); + } + + return; + } + + + FT_LOCAL_DEF( void ) + af_latin2_metrics_check_digits( AF_LatinMetrics metrics, + FT_Face face ) + { + FT_UInt i; + FT_Bool started = 0, same_width = 1; + + + /* check whether all ASCII digits have the same advance width; */ + /* digit `0' is 0x30 in all supported charmaps */ + for ( i = 0x30; i <= 0x39; i++ ) + { + FT_UInt glyph_index; + FT_Fixed advance, old_advance; + + + glyph_index = FT_Get_Char_Index( face, i ); + if ( glyph_index == 0 ) + continue; + + if ( FT_Get_Advance( face, glyph_index, + FT_LOAD_NO_SCALE | + FT_LOAD_NO_HINTING | + FT_LOAD_IGNORE_TRANSFORM, + &advance ) ) + continue; + + if ( started ) + { + if ( advance != old_advance ) + { + same_width = 0; + break; + } + } + else + { + old_advance = advance; + started = 1; + } + } + + metrics->root.digits_have_same_width = same_width; + } + + + FT_LOCAL_DEF( FT_Error ) + af_latin2_metrics_init( AF_LatinMetrics metrics, + FT_Face face ) + { + FT_Error error = AF_Err_Ok; + FT_CharMap oldmap = face->charmap; + FT_UInt ee; + + static const FT_Encoding latin_encodings[] = + { + FT_ENCODING_UNICODE, + FT_ENCODING_APPLE_ROMAN, + FT_ENCODING_ADOBE_STANDARD, + FT_ENCODING_ADOBE_LATIN_1, + FT_ENCODING_NONE /* end of list */ + }; + + + metrics->units_per_em = face->units_per_EM; + + /* do we have a latin charmap in there? */ + for ( ee = 0; latin_encodings[ee] != FT_ENCODING_NONE; ee++ ) + { + error = FT_Select_Charmap( face, latin_encodings[ee] ); + if ( !error ) + break; + } + + if ( !error ) + { + /* For now, compute the standard width and height from the `o'. */ + af_latin2_metrics_init_widths( metrics, face, 'o' ); + af_latin2_metrics_init_blues( metrics, face ); + af_latin2_metrics_check_digits( metrics, face ); + } + + FT_Set_Charmap( face, oldmap ); + return AF_Err_Ok; + } + + + static void + af_latin2_metrics_scale_dim( AF_LatinMetrics metrics, + AF_Scaler scaler, + AF_Dimension dim ) + { + FT_Fixed scale; + FT_Pos delta; + AF_LatinAxis axis; + FT_UInt nn; + + + if ( dim == AF_DIMENSION_HORZ ) + { + scale = scaler->x_scale; + delta = scaler->x_delta; + } + else + { + scale = scaler->y_scale; + delta = scaler->y_delta; + } + + axis = &metrics->axis[dim]; + + if ( axis->org_scale == scale && axis->org_delta == delta ) + return; + + axis->org_scale = scale; + axis->org_delta = delta; + + /* + * correct Y scale to optimize the alignment of the top of small + * letters to the pixel grid + */ + if ( dim == AF_DIMENSION_VERT ) + { + AF_LatinAxis vaxis = &metrics->axis[AF_DIMENSION_VERT]; + AF_LatinBlue blue = NULL; + + + for ( nn = 0; nn < vaxis->blue_count; nn++ ) + { + if ( vaxis->blues[nn].flags & AF_LATIN_BLUE_ADJUSTMENT ) + { + blue = &vaxis->blues[nn]; + break; + } + } + + if ( blue ) + { + FT_Pos scaled = FT_MulFix( blue->shoot.org, scaler->y_scale ); + FT_Pos fitted = ( scaled + 40 ) & ~63; + +#if 1 + if ( scaled != fitted ) { + scale = FT_MulDiv( scale, fitted, scaled ); + AF_LOG(( "== scaled x-top = %.2g fitted = %.2g, scaling = %.4g\n", scaled/64.0, fitted/64.0, (fitted*1.0)/scaled )); + } +#endif + } + } + + axis->scale = scale; + axis->delta = delta; + + if ( dim == AF_DIMENSION_HORZ ) + { + metrics->root.scaler.x_scale = scale; + metrics->root.scaler.x_delta = delta; + } + else + { + metrics->root.scaler.y_scale = scale; + metrics->root.scaler.y_delta = delta; + } + + /* scale the standard widths */ + for ( nn = 0; nn < axis->width_count; nn++ ) + { + AF_Width width = axis->widths + nn; + + + width->cur = FT_MulFix( width->org, scale ); + width->fit = width->cur; + } + + /* an extra-light axis corresponds to a standard width that is */ + /* smaller than 0.75 pixels */ + axis->extra_light = + (FT_Bool)( FT_MulFix( axis->standard_width, scale ) < 32 + 8 ); + + if ( dim == AF_DIMENSION_VERT ) + { + /* scale the blue zones */ + for ( nn = 0; nn < axis->blue_count; nn++ ) + { + AF_LatinBlue blue = &axis->blues[nn]; + FT_Pos dist; + + + blue->ref.cur = FT_MulFix( blue->ref.org, scale ) + delta; + blue->ref.fit = blue->ref.cur; + blue->shoot.cur = FT_MulFix( blue->shoot.org, scale ) + delta; + blue->shoot.fit = blue->shoot.cur; + blue->flags &= ~AF_LATIN_BLUE_ACTIVE; + + /* a blue zone is only active if it is less than 3/4 pixels tall */ + dist = FT_MulFix( blue->ref.org - blue->shoot.org, scale ); + if ( dist <= 48 && dist >= -48 ) + { + FT_Pos delta1, delta2; + + delta1 = blue->shoot.org - blue->ref.org; + delta2 = delta1; + if ( delta1 < 0 ) + delta2 = -delta2; + + delta2 = FT_MulFix( delta2, scale ); + + if ( delta2 < 32 ) + delta2 = 0; + else if ( delta2 < 64 ) + delta2 = 32 + ( ( ( delta2 - 32 ) + 16 ) & ~31 ); + else + delta2 = FT_PIX_ROUND( delta2 ); + + if ( delta1 < 0 ) + delta2 = -delta2; + + blue->ref.fit = FT_PIX_ROUND( blue->ref.cur ); + blue->shoot.fit = blue->ref.fit + delta2; + + AF_LOG(( ">> activating blue zone %d: ref.cur=%.2g ref.fit=%.2g shoot.cur=%.2g shoot.fit=%.2g\n", + nn, blue->ref.cur/64.0, blue->ref.fit/64.0, + blue->shoot.cur/64.0, blue->shoot.fit/64.0 )); + + blue->flags |= AF_LATIN_BLUE_ACTIVE; + } + } + } + } + + + FT_LOCAL_DEF( void ) + af_latin2_metrics_scale( AF_LatinMetrics metrics, + AF_Scaler scaler ) + { + metrics->root.scaler.render_mode = scaler->render_mode; + metrics->root.scaler.face = scaler->face; + + af_latin2_metrics_scale_dim( metrics, scaler, AF_DIMENSION_HORZ ); + af_latin2_metrics_scale_dim( metrics, scaler, AF_DIMENSION_VERT ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** L A T I N G L Y P H A N A L Y S I S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + +#define SORT_SEGMENTS + + FT_LOCAL_DEF( FT_Error ) + af_latin2_hints_compute_segments( AF_GlyphHints hints, + AF_Dimension dim ) + { + AF_AxisHints axis = &hints->axis[dim]; + FT_Memory memory = hints->memory; + FT_Error error = AF_Err_Ok; + AF_Segment segment = NULL; + AF_SegmentRec seg0; + AF_Point* contour = hints->contours; + AF_Point* contour_limit = contour + hints->num_contours; + AF_Direction major_dir, segment_dir; + + + FT_ZERO( &seg0 ); + seg0.score = 32000; + seg0.flags = AF_EDGE_NORMAL; + + major_dir = (AF_Direction)FT_ABS( axis->major_dir ); + segment_dir = major_dir; + + axis->num_segments = 0; + + /* set up (u,v) in each point */ + if ( dim == AF_DIMENSION_HORZ ) + { + AF_Point point = hints->points; + AF_Point limit = point + hints->num_points; + + + for ( ; point < limit; point++ ) + { + point->u = point->fx; + point->v = point->fy; + } + } + else + { + AF_Point point = hints->points; + AF_Point limit = point + hints->num_points; + + + for ( ; point < limit; point++ ) + { + point->u = point->fy; + point->v = point->fx; + } + } + + /* do each contour separately */ + for ( ; contour < contour_limit; contour++ ) + { + AF_Point point = contour[0]; + AF_Point start = point; + AF_Point last = point->prev; + + + if ( point == last ) /* skip singletons -- just in case */ + continue; + + /* already on an edge ?, backtrack to find its start */ + if ( FT_ABS( point->in_dir ) == major_dir ) + { + point = point->prev; + + while ( point->in_dir == start->in_dir ) + point = point->prev; + } + else /* otherwise, find first segment start, if any */ + { + while ( FT_ABS( point->out_dir ) != major_dir ) + { + point = point->next; + + if ( point == start ) + goto NextContour; + } + } + + start = point; + + for (;;) + { + AF_Point first; + FT_Pos min_u, min_v, max_u, max_v; + + /* we're at the start of a new segment */ + FT_ASSERT( FT_ABS( point->out_dir ) == major_dir && + point->in_dir != point->out_dir ); + first = point; + + min_u = max_u = point->u; + min_v = max_v = point->v; + + point = point->next; + + while ( point->out_dir == first->out_dir ) + { + point = point->next; + + if ( point->u < min_u ) + min_u = point->u; + + if ( point->u > max_u ) + max_u = point->u; + } + + if ( point->v < min_v ) + min_v = point->v; + + if ( point->v > max_v ) + max_v = point->v; + + /* record new segment */ + error = af_axis_hints_new_segment( axis, memory, &segment ); + if ( error ) + goto Exit; + + segment[0] = seg0; + segment->dir = first->out_dir; + segment->first = first; + segment->last = point; + segment->contour = contour; + segment->pos = (FT_Short)(( min_u + max_u ) >> 1); + segment->min_coord = (FT_Short) min_v; + segment->max_coord = (FT_Short) max_v; + segment->height = (FT_Short)(max_v - min_v); + + /* a segment is round if it doesn't have successive */ + /* on-curve points. */ + { + AF_Point pt = first; + AF_Point last = point; + AF_Flags f0 = (AF_Flags)(pt->flags & AF_FLAG_CONTROL); + AF_Flags f1; + + + segment->flags &= ~AF_EDGE_ROUND; + + for ( ; pt != last; f0 = f1 ) + { + pt = pt->next; + f1 = (AF_Flags)(pt->flags & AF_FLAG_CONTROL); + + if ( !f0 && !f1 ) + break; + + if ( pt == last ) + segment->flags |= AF_EDGE_ROUND; + } + } + + /* this can happen in the case of a degenerate contour + * e.g. a 2-point vertical contour + */ + if ( point == start ) + break; + + /* jump to the start of the next segment, if any */ + while ( FT_ABS(point->out_dir) != major_dir ) + { + point = point->next; + + if ( point == start ) + goto NextContour; + } + } + + NextContour: + ; + } /* contours */ + + /* now slightly increase the height of segments when this makes */ + /* sense -- this is used to better detect and ignore serifs */ + { + AF_Segment segments = axis->segments; + AF_Segment segments_end = segments + axis->num_segments; + + + for ( segment = segments; segment < segments_end; segment++ ) + { + AF_Point first = segment->first; + AF_Point last = segment->last; + AF_Point p; + FT_Pos first_v = first->v; + FT_Pos last_v = last->v; + + + if ( first == last ) + continue; + + if ( first_v < last_v ) + { + p = first->prev; + if ( p->v < first_v ) + segment->height = (FT_Short)( segment->height + + ( ( first_v - p->v ) >> 1 ) ); + + p = last->next; + if ( p->v > last_v ) + segment->height = (FT_Short)( segment->height + + ( ( p->v - last_v ) >> 1 ) ); + } + else + { + p = first->prev; + if ( p->v > first_v ) + segment->height = (FT_Short)( segment->height + + ( ( p->v - first_v ) >> 1 ) ); + + p = last->next; + if ( p->v < last_v ) + segment->height = (FT_Short)( segment->height + + ( ( last_v - p->v ) >> 1 ) ); + } + } + } + +#ifdef AF_SORT_SEGMENTS + /* place all segments with a negative direction to the start + * of the array, used to speed up segment linking later... + */ + { + AF_Segment segments = axis->segments; + FT_UInt count = axis->num_segments; + FT_UInt ii, jj; + + for (ii = 0; ii < count; ii++) + { + if ( segments[ii].dir > 0 ) + { + for (jj = ii+1; jj < count; jj++) + { + if ( segments[jj].dir < 0 ) + { + AF_SegmentRec tmp; + + tmp = segments[ii]; + segments[ii] = segments[jj]; + segments[jj] = tmp; + + break; + } + } + + if ( jj == count ) + break; + } + } + axis->mid_segments = ii; + } +#endif + + Exit: + return error; + } + + + FT_LOCAL_DEF( void ) + af_latin2_hints_link_segments( AF_GlyphHints hints, + AF_Dimension dim ) + { + AF_AxisHints axis = &hints->axis[dim]; + AF_Segment segments = axis->segments; + AF_Segment segment_limit = segments + axis->num_segments; +#ifdef AF_SORT_SEGMENTS + AF_Segment segment_mid = segments + axis->mid_segments; +#endif + FT_Pos len_threshold, len_score; + AF_Segment seg1, seg2; + + + len_threshold = AF_LATIN_CONSTANT( hints->metrics, 8 ); + if ( len_threshold == 0 ) + len_threshold = 1; + + len_score = AF_LATIN_CONSTANT( hints->metrics, 6000 ); + +#ifdef AF_SORT_SEGMENTS + for ( seg1 = segments; seg1 < segment_mid; seg1++ ) + { + if ( seg1->dir != axis->major_dir || seg1->first == seg1->last ) + continue; + + for ( seg2 = segment_mid; seg2 < segment_limit; seg2++ ) +#else + /* now compare each segment to the others */ + for ( seg1 = segments; seg1 < segment_limit; seg1++ ) + { + /* the fake segments are introduced to hint the metrics -- */ + /* we must never link them to anything */ + if ( seg1->dir != axis->major_dir || seg1->first == seg1->last ) + continue; + + for ( seg2 = segments; seg2 < segment_limit; seg2++ ) + if ( seg1->dir + seg2->dir == 0 && seg2->pos > seg1->pos ) +#endif + { + FT_Pos pos1 = seg1->pos; + FT_Pos pos2 = seg2->pos; + FT_Pos dist = pos2 - pos1; + + + if ( dist < 0 ) + continue; + + { + FT_Pos min = seg1->min_coord; + FT_Pos max = seg1->max_coord; + FT_Pos len, score; + + + if ( min < seg2->min_coord ) + min = seg2->min_coord; + + if ( max > seg2->max_coord ) + max = seg2->max_coord; + + len = max - min; + if ( len >= len_threshold ) + { + score = dist + len_score / len; + if ( score < seg1->score ) + { + seg1->score = score; + seg1->link = seg2; + } + + if ( score < seg2->score ) + { + seg2->score = score; + seg2->link = seg1; + } + } + } + } + } +#if 0 + } +#endif + + /* now, compute the `serif' segments */ + for ( seg1 = segments; seg1 < segment_limit; seg1++ ) + { + seg2 = seg1->link; + + if ( seg2 ) + { + if ( seg2->link != seg1 ) + { + seg1->link = 0; + seg1->serif = seg2->link; + } + } + } + } + + + FT_LOCAL_DEF( FT_Error ) + af_latin2_hints_compute_edges( AF_GlyphHints hints, + AF_Dimension dim ) + { + AF_AxisHints axis = &hints->axis[dim]; + FT_Error error = AF_Err_Ok; + FT_Memory memory = hints->memory; + AF_LatinAxis laxis = &((AF_LatinMetrics)hints->metrics)->axis[dim]; + + AF_Segment segments = axis->segments; + AF_Segment segment_limit = segments + axis->num_segments; + AF_Segment seg; + + AF_Direction up_dir; + FT_Fixed scale; + FT_Pos edge_distance_threshold; + FT_Pos segment_length_threshold; + + + axis->num_edges = 0; + + scale = ( dim == AF_DIMENSION_HORZ ) ? hints->x_scale + : hints->y_scale; + + up_dir = ( dim == AF_DIMENSION_HORZ ) ? AF_DIR_UP + : AF_DIR_RIGHT; + + /* + * We want to ignore very small (mostly serif) segments, we do that + * by ignoring those that whose length is less than a given fraction + * of the standard width. If there is no standard width, we ignore + * those that are less than a given size in pixels + * + * also, unlink serif segments that are linked to segments farther + * than 50% of the standard width + */ + if ( dim == AF_DIMENSION_HORZ ) + { + if ( laxis->width_count > 0 ) + segment_length_threshold = (laxis->standard_width * 10 ) >> 4; + else + segment_length_threshold = FT_DivFix( 64, hints->y_scale ); + } + else + segment_length_threshold = 0; + + /*********************************************************************/ + /* */ + /* We will begin by generating a sorted table of edges for the */ + /* current direction. To do so, we simply scan each segment and try */ + /* to find an edge in our table that corresponds to its position. */ + /* */ + /* If no edge is found, we create and insert a new edge in the */ + /* sorted table. Otherwise, we simply add the segment to the edge's */ + /* list which will be processed in the second step to compute the */ + /* edge's properties. */ + /* */ + /* Note that the edges table is sorted along the segment/edge */ + /* position. */ + /* */ + /*********************************************************************/ + + edge_distance_threshold = FT_MulFix( laxis->edge_distance_threshold, + scale ); + if ( edge_distance_threshold > 64 / 4 ) + edge_distance_threshold = 64 / 4; + + edge_distance_threshold = FT_DivFix( edge_distance_threshold, + scale ); + + for ( seg = segments; seg < segment_limit; seg++ ) + { + AF_Edge found = 0; + FT_Int ee; + + + if ( seg->height < segment_length_threshold ) + continue; + + /* A special case for serif edges: If they are smaller than */ + /* 1.5 pixels we ignore them. */ + if ( seg->serif ) + { + FT_Pos dist = seg->serif->pos - seg->pos; + + if (dist < 0) + dist = -dist; + + if (dist >= laxis->standard_width >> 1) + { + /* unlink this serif, it is too distant from its reference stem */ + seg->serif = NULL; + } + else if ( 2*seg->height < 3 * segment_length_threshold ) + continue; + } + + /* look for an edge corresponding to the segment */ + for ( ee = 0; ee < axis->num_edges; ee++ ) + { + AF_Edge edge = axis->edges + ee; + FT_Pos dist; + + + dist = seg->pos - edge->fpos; + if ( dist < 0 ) + dist = -dist; + + if ( dist < edge_distance_threshold && edge->dir == seg->dir ) + { + found = edge; + break; + } + } + + if ( !found ) + { + AF_Edge edge; + + + /* insert a new edge in the list and */ + /* sort according to the position */ + error = af_axis_hints_new_edge( axis, seg->pos, seg->dir, memory, &edge ); + if ( error ) + goto Exit; + + /* add the segment to the new edge's list */ + FT_ZERO( edge ); + + edge->first = seg; + edge->last = seg; + edge->fpos = seg->pos; + edge->dir = seg->dir; + edge->opos = edge->pos = FT_MulFix( seg->pos, scale ); + seg->edge_next = seg; + } + else + { + /* if an edge was found, simply add the segment to the edge's */ + /* list */ + seg->edge_next = found->first; + found->last->edge_next = seg; + found->last = seg; + } + } + + + /*********************************************************************/ + /* */ + /* Good, we will now compute each edge's properties according to */ + /* segments found on its position. Basically, these are: */ + /* */ + /* - edge's main direction */ + /* - stem edge, serif edge or both (which defaults to stem then) */ + /* - rounded edge, straight or both (which defaults to straight) */ + /* - link for edge */ + /* */ + /*********************************************************************/ + + /* first of all, set the `edge' field in each segment -- this is */ + /* required in order to compute edge links */ + + /* + * Note that removing this loop and setting the `edge' field of each + * segment directly in the code above slows down execution speed for + * some reasons on platforms like the Sun. + */ + { + AF_Edge edges = axis->edges; + AF_Edge edge_limit = edges + axis->num_edges; + AF_Edge edge; + + + for ( edge = edges; edge < edge_limit; edge++ ) + { + seg = edge->first; + if ( seg ) + do + { + seg->edge = edge; + seg = seg->edge_next; + + } while ( seg != edge->first ); + } + + /* now, compute each edge properties */ + for ( edge = edges; edge < edge_limit; edge++ ) + { + FT_Int is_round = 0; /* does it contain round segments? */ + FT_Int is_straight = 0; /* does it contain straight segments? */ + FT_Pos ups = 0; /* number of upwards segments */ + FT_Pos downs = 0; /* number of downwards segments */ + + + seg = edge->first; + + do + { + FT_Bool is_serif; + + + /* check for roundness of segment */ + if ( seg->flags & AF_EDGE_ROUND ) + is_round++; + else + is_straight++; + + /* check for segment direction */ + if ( seg->dir == up_dir ) + ups += seg->max_coord-seg->min_coord; + else + downs += seg->max_coord-seg->min_coord; + + /* check for links -- if seg->serif is set, then seg->link must */ + /* be ignored */ + is_serif = (FT_Bool)( seg->serif && + seg->serif->edge && + seg->serif->edge != edge ); + + if ( ( seg->link && seg->link->edge != NULL ) || is_serif ) + { + AF_Edge edge2; + AF_Segment seg2; + + + edge2 = edge->link; + seg2 = seg->link; + + if ( is_serif ) + { + seg2 = seg->serif; + edge2 = edge->serif; + } + + if ( edge2 ) + { + FT_Pos edge_delta; + FT_Pos seg_delta; + + + edge_delta = edge->fpos - edge2->fpos; + if ( edge_delta < 0 ) + edge_delta = -edge_delta; + + seg_delta = seg->pos - seg2->pos; + if ( seg_delta < 0 ) + seg_delta = -seg_delta; + + if ( seg_delta < edge_delta ) + edge2 = seg2->edge; + } + else + edge2 = seg2->edge; + + if ( is_serif ) + { + edge->serif = edge2; + edge2->flags |= AF_EDGE_SERIF; + } + else + edge->link = edge2; + } + + seg = seg->edge_next; + + } while ( seg != edge->first ); + + /* set the round/straight flags */ + edge->flags = AF_EDGE_NORMAL; + + if ( is_round > 0 && is_round >= is_straight ) + edge->flags |= AF_EDGE_ROUND; + +#if 0 + /* set the edge's main direction */ + edge->dir = AF_DIR_NONE; + + if ( ups > downs ) + edge->dir = (FT_Char)up_dir; + + else if ( ups < downs ) + edge->dir = (FT_Char)-up_dir; + + else if ( ups == downs ) + edge->dir = 0; /* both up and down! */ +#endif + + /* gets rid of serifs if link is set */ + /* XXX: This gets rid of many unpleasant artefacts! */ + /* Example: the `c' in cour.pfa at size 13 */ + + if ( edge->serif && edge->link ) + edge->serif = 0; + } + } + + Exit: + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + af_latin2_hints_detect_features( AF_GlyphHints hints, + AF_Dimension dim ) + { + FT_Error error; + + + error = af_latin2_hints_compute_segments( hints, dim ); + if ( !error ) + { + af_latin2_hints_link_segments( hints, dim ); + + error = af_latin2_hints_compute_edges( hints, dim ); + } + return error; + } + + + FT_LOCAL_DEF( void ) + af_latin2_hints_compute_blue_edges( AF_GlyphHints hints, + AF_LatinMetrics metrics ) + { + AF_AxisHints axis = &hints->axis[ AF_DIMENSION_VERT ]; + AF_Edge edge = axis->edges; + AF_Edge edge_limit = edge + axis->num_edges; + AF_LatinAxis latin = &metrics->axis[ AF_DIMENSION_VERT ]; + FT_Fixed scale = latin->scale; + FT_Pos best_dist0; /* initial threshold */ + + + /* compute the initial threshold as a fraction of the EM size */ + best_dist0 = FT_MulFix( metrics->units_per_em / 40, scale ); + + if ( best_dist0 > 64 / 2 ) + best_dist0 = 64 / 2; + + /* compute which blue zones are active, i.e. have their scaled */ + /* size < 3/4 pixels */ + + /* for each horizontal edge search the blue zone which is closest */ + for ( ; edge < edge_limit; edge++ ) + { + FT_Int bb; + AF_Width best_blue = NULL; + FT_Pos best_dist = best_dist0; + + for ( bb = 0; bb < AF_LATIN_BLUE_MAX; bb++ ) + { + AF_LatinBlue blue = latin->blues + bb; + FT_Bool is_top_blue, is_major_dir; + + + /* skip inactive blue zones (i.e., those that are too small) */ + if ( !( blue->flags & AF_LATIN_BLUE_ACTIVE ) ) + continue; + + /* if it is a top zone, check for right edges -- if it is a bottom */ + /* zone, check for left edges */ + /* */ + /* of course, that's for TrueType */ + is_top_blue = (FT_Byte)( ( blue->flags & AF_LATIN_BLUE_TOP ) != 0 ); + is_major_dir = FT_BOOL( edge->dir == axis->major_dir ); + + /* if it is a top zone, the edge must be against the major */ + /* direction; if it is a bottom zone, it must be in the major */ + /* direction */ + if ( is_top_blue ^ is_major_dir ) + { + FT_Pos dist; + AF_Width compare; + + + /* if it's a rounded edge, compare it to the overshoot position */ + /* if it's a flat edge, compare it to the reference position */ + if ( edge->flags & AF_EDGE_ROUND ) + compare = &blue->shoot; + else + compare = &blue->ref; + + dist = edge->fpos - compare->org; + if (dist < 0) + dist = -dist; + + dist = FT_MulFix( dist, scale ); + if ( dist < best_dist ) + { + best_dist = dist; + best_blue = compare; + } + +#if 0 + /* now, compare it to the overshoot position if the edge is */ + /* rounded, and if the edge is over the reference position of a */ + /* top zone, or under the reference position of a bottom zone */ + if ( edge->flags & AF_EDGE_ROUND && dist != 0 ) + { + FT_Bool is_under_ref = FT_BOOL( edge->fpos < blue->ref.org ); + + + if ( is_top_blue ^ is_under_ref ) + { + blue = latin->blues + bb; + dist = edge->fpos - blue->shoot.org; + if ( dist < 0 ) + dist = -dist; + + dist = FT_MulFix( dist, scale ); + if ( dist < best_dist ) + { + best_dist = dist; + best_blue = & blue->shoot; + } + } + } +#endif + } + } + + if ( best_blue ) + edge->blue_edge = best_blue; + } + } + + + static FT_Error + af_latin2_hints_init( AF_GlyphHints hints, + AF_LatinMetrics metrics ) + { + FT_Render_Mode mode; + FT_UInt32 scaler_flags, other_flags; + FT_Face face = metrics->root.scaler.face; + + + af_glyph_hints_rescale( hints, (AF_ScriptMetrics)metrics ); + + /* + * correct x_scale and y_scale if needed, since they may have + * been modified `af_latin2_metrics_scale_dim' above + */ + hints->x_scale = metrics->axis[AF_DIMENSION_HORZ].scale; + hints->x_delta = metrics->axis[AF_DIMENSION_HORZ].delta; + hints->y_scale = metrics->axis[AF_DIMENSION_VERT].scale; + hints->y_delta = metrics->axis[AF_DIMENSION_VERT].delta; + + /* compute flags depending on render mode, etc. */ + mode = metrics->root.scaler.render_mode; + +#if 0 /* #ifdef AF_USE_WARPER */ + if ( mode == FT_RENDER_MODE_LCD || mode == FT_RENDER_MODE_LCD_V ) + { + metrics->root.scaler.render_mode = mode = FT_RENDER_MODE_NORMAL; + } +#endif + + scaler_flags = hints->scaler_flags; + other_flags = 0; + + /* + * We snap the width of vertical stems for the monochrome and + * horizontal LCD rendering targets only. + */ + if ( mode == FT_RENDER_MODE_MONO || mode == FT_RENDER_MODE_LCD ) + other_flags |= AF_LATIN_HINTS_HORZ_SNAP; + + /* + * We snap the width of horizontal stems for the monochrome and + * vertical LCD rendering targets only. + */ + if ( mode == FT_RENDER_MODE_MONO || mode == FT_RENDER_MODE_LCD_V ) + other_flags |= AF_LATIN_HINTS_VERT_SNAP; + + /* + * We adjust stems to full pixels only if we don't use the `light' mode. + */ + if ( mode != FT_RENDER_MODE_LIGHT ) + other_flags |= AF_LATIN_HINTS_STEM_ADJUST; + + if ( mode == FT_RENDER_MODE_MONO ) + other_flags |= AF_LATIN_HINTS_MONO; + + /* + * In `light' hinting mode we disable horizontal hinting completely. + * We also do it if the face is italic. + */ + if ( mode == FT_RENDER_MODE_LIGHT || + (face->style_flags & FT_STYLE_FLAG_ITALIC) != 0 ) + scaler_flags |= AF_SCALER_FLAG_NO_HORIZONTAL; + + hints->scaler_flags = scaler_flags; + hints->other_flags = other_flags; + + return 0; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** L A T I N G L Y P H G R I D - F I T T I N G *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* snap a given width in scaled coordinates to one of the */ + /* current standard widths */ + + static FT_Pos + af_latin2_snap_width( AF_Width widths, + FT_Int count, + FT_Pos width ) + { + int n; + FT_Pos best = 64 + 32 + 2; + FT_Pos reference = width; + FT_Pos scaled; + + + for ( n = 0; n < count; n++ ) + { + FT_Pos w; + FT_Pos dist; + + + w = widths[n].cur; + dist = width - w; + if ( dist < 0 ) + dist = -dist; + if ( dist < best ) + { + best = dist; + reference = w; + } + } + + scaled = FT_PIX_ROUND( reference ); + + if ( width >= reference ) + { + if ( width < scaled + 48 ) + width = reference; + } + else + { + if ( width > scaled - 48 ) + width = reference; + } + + return width; + } + + + /* compute the snapped width of a given stem */ + + static FT_Pos + af_latin2_compute_stem_width( AF_GlyphHints hints, + AF_Dimension dim, + FT_Pos width, + AF_Edge_Flags base_flags, + AF_Edge_Flags stem_flags ) + { + AF_LatinMetrics metrics = (AF_LatinMetrics) hints->metrics; + AF_LatinAxis axis = & metrics->axis[dim]; + FT_Pos dist = width; + FT_Int sign = 0; + FT_Int vertical = ( dim == AF_DIMENSION_VERT ); + + + FT_UNUSED(base_flags); + + if ( !AF_LATIN_HINTS_DO_STEM_ADJUST( hints ) || + axis->extra_light ) + return width; + + if ( dist < 0 ) + { + dist = -width; + sign = 1; + } + + if ( ( vertical && !AF_LATIN_HINTS_DO_VERT_SNAP( hints ) ) || + ( !vertical && !AF_LATIN_HINTS_DO_HORZ_SNAP( hints ) ) ) + { + /* smooth hinting process: very lightly quantize the stem width */ + + /* leave the widths of serifs alone */ + + if ( ( stem_flags & AF_EDGE_SERIF ) && vertical && ( dist < 3 * 64 ) ) + goto Done_Width; + +#if 0 + else if ( ( base_flags & AF_EDGE_ROUND ) ) + { + if ( dist < 80 ) + dist = 64; + } + else if ( dist < 56 ) + dist = 56; +#endif + if ( axis->width_count > 0 ) + { + FT_Pos delta; + + + /* compare to standard width */ + if ( axis->width_count > 0 ) + { + delta = dist - axis->widths[0].cur; + + if ( delta < 0 ) + delta = -delta; + + if ( delta < 40 ) + { + dist = axis->widths[0].cur; + if ( dist < 48 ) + dist = 48; + + goto Done_Width; + } + } + + if ( dist < 3 * 64 ) + { + delta = dist & 63; + dist &= -64; + + if ( delta < 10 ) + dist += delta; + + else if ( delta < 32 ) + dist += 10; + + else if ( delta < 54 ) + dist += 54; + + else + dist += delta; + } + else + dist = ( dist + 32 ) & ~63; + } + } + else + { + /* strong hinting process: snap the stem width to integer pixels */ + FT_Pos org_dist = dist; + + + dist = af_latin2_snap_width( axis->widths, axis->width_count, dist ); + + if ( vertical ) + { + /* in the case of vertical hinting, always round */ + /* the stem heights to integer pixels */ + + if ( dist >= 64 ) + dist = ( dist + 16 ) & ~63; + else + dist = 64; + } + else + { + if ( AF_LATIN_HINTS_DO_MONO( hints ) ) + { + /* monochrome horizontal hinting: snap widths to integer pixels */ + /* with a different threshold */ + + if ( dist < 64 ) + dist = 64; + else + dist = ( dist + 32 ) & ~63; + } + else + { + /* for horizontal anti-aliased hinting, we adopt a more subtle */ + /* approach: we strengthen small stems, round stems whose size */ + /* is between 1 and 2 pixels to an integer, otherwise nothing */ + + if ( dist < 48 ) + dist = ( dist + 64 ) >> 1; + + else if ( dist < 128 ) + { + /* We only round to an integer width if the corresponding */ + /* distortion is less than 1/4 pixel. Otherwise this */ + /* makes everything worse since the diagonals, which are */ + /* not hinted, appear a lot bolder or thinner than the */ + /* vertical stems. */ + + FT_Int delta; + + + dist = ( dist + 22 ) & ~63; + delta = dist - org_dist; + if ( delta < 0 ) + delta = -delta; + + if (delta >= 16) + { + dist = org_dist; + if ( dist < 48 ) + dist = ( dist + 64 ) >> 1; + } + } + else + /* round otherwise to prevent color fringes in LCD mode */ + dist = ( dist + 32 ) & ~63; + } + } + } + + Done_Width: + if ( sign ) + dist = -dist; + + return dist; + } + + + /* align one stem edge relative to the previous stem edge */ + + static void + af_latin2_align_linked_edge( AF_GlyphHints hints, + AF_Dimension dim, + AF_Edge base_edge, + AF_Edge stem_edge ) + { + FT_Pos dist = stem_edge->opos - base_edge->opos; + + FT_Pos fitted_width = af_latin2_compute_stem_width( + hints, dim, dist, + (AF_Edge_Flags)base_edge->flags, + (AF_Edge_Flags)stem_edge->flags ); + + + stem_edge->pos = base_edge->pos + fitted_width; + + AF_LOG(( "LINK: edge %d (opos=%.2f) linked to (%.2f), " + "dist was %.2f, now %.2f\n", + stem_edge-hints->axis[dim].edges, stem_edge->opos / 64.0, + stem_edge->pos / 64.0, dist / 64.0, fitted_width / 64.0 )); + } + + + static void + af_latin2_align_serif_edge( AF_GlyphHints hints, + AF_Edge base, + AF_Edge serif ) + { + FT_UNUSED( hints ); + + serif->pos = base->pos + (serif->opos - base->opos); + } + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** E D G E H I N T I N G ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + FT_LOCAL_DEF( void ) + af_latin2_hint_edges( AF_GlyphHints hints, + AF_Dimension dim ) + { + AF_AxisHints axis = &hints->axis[dim]; + AF_Edge edges = axis->edges; + AF_Edge edge_limit = edges + axis->num_edges; + AF_Edge edge; + AF_Edge anchor = 0; + FT_Int has_serifs = 0; + FT_Pos anchor_drift = 0; + + + + AF_LOG(( "==== hinting %s edges =====\n", dim == AF_DIMENSION_HORZ ? "vertical" : "horizontal" )); + + /* we begin by aligning all stems relative to the blue zone */ + /* if needed -- that's only for horizontal edges */ + + if ( dim == AF_DIMENSION_VERT && AF_HINTS_DO_BLUES( hints ) ) + { + for ( edge = edges; edge < edge_limit; edge++ ) + { + AF_Width blue; + AF_Edge edge1, edge2; + + + if ( edge->flags & AF_EDGE_DONE ) + continue; + + blue = edge->blue_edge; + edge1 = NULL; + edge2 = edge->link; + + if ( blue ) + { + edge1 = edge; + } + else if ( edge2 && edge2->blue_edge ) + { + blue = edge2->blue_edge; + edge1 = edge2; + edge2 = edge; + } + + if ( !edge1 ) + continue; + + AF_LOG(( "BLUE: edge %d (opos=%.2f) snapped to (%.2f), " + "was (%.2f)\n", + edge1-edges, edge1->opos / 64.0, blue->fit / 64.0, + edge1->pos / 64.0 )); + + edge1->pos = blue->fit; + edge1->flags |= AF_EDGE_DONE; + + if ( edge2 && !edge2->blue_edge ) + { + af_latin2_align_linked_edge( hints, dim, edge1, edge2 ); + edge2->flags |= AF_EDGE_DONE; + } + + if ( !anchor ) + { + anchor = edge; + + anchor_drift = (anchor->pos - anchor->opos); + if (edge2) + anchor_drift = (anchor_drift + (edge2->pos - edge2->opos)) >> 1; + } + } + } + + /* now we will align all stem edges, trying to maintain the */ + /* relative order of stems in the glyph */ + for ( edge = edges; edge < edge_limit; edge++ ) + { + AF_Edge edge2; + + + if ( edge->flags & AF_EDGE_DONE ) + continue; + + /* skip all non-stem edges */ + edge2 = edge->link; + if ( !edge2 ) + { + has_serifs++; + continue; + } + + /* now align the stem */ + + /* this should not happen, but it's better to be safe */ + if ( edge2->blue_edge ) + { + AF_LOG(( "ASSERTION FAILED for edge %d\n", edge2-edges )); + + af_latin2_align_linked_edge( hints, dim, edge2, edge ); + edge->flags |= AF_EDGE_DONE; + continue; + } + + if ( !anchor ) + { + FT_Pos org_len, org_center, cur_len; + FT_Pos cur_pos1, error1, error2, u_off, d_off; + + + org_len = edge2->opos - edge->opos; + cur_len = af_latin2_compute_stem_width( + hints, dim, org_len, + (AF_Edge_Flags)edge->flags, + (AF_Edge_Flags)edge2->flags ); + if ( cur_len <= 64 ) + u_off = d_off = 32; + else + { + u_off = 38; + d_off = 26; + } + + if ( cur_len < 96 ) + { + org_center = edge->opos + ( org_len >> 1 ); + + cur_pos1 = FT_PIX_ROUND( org_center ); + + error1 = org_center - ( cur_pos1 - u_off ); + if ( error1 < 0 ) + error1 = -error1; + + error2 = org_center - ( cur_pos1 + d_off ); + if ( error2 < 0 ) + error2 = -error2; + + if ( error1 < error2 ) + cur_pos1 -= u_off; + else + cur_pos1 += d_off; + + edge->pos = cur_pos1 - cur_len / 2; + edge2->pos = edge->pos + cur_len; + } + else + edge->pos = FT_PIX_ROUND( edge->opos ); + + AF_LOG(( "ANCHOR: edge %d (opos=%.2f) and %d (opos=%.2f) " + "snapped to (%.2f) (%.2f)\n", + edge-edges, edge->opos / 64.0, + edge2-edges, edge2->opos / 64.0, + edge->pos / 64.0, edge2->pos / 64.0 )); + anchor = edge; + + edge->flags |= AF_EDGE_DONE; + + af_latin2_align_linked_edge( hints, dim, edge, edge2 ); + + edge2->flags |= AF_EDGE_DONE; + + anchor_drift = ( (anchor->pos - anchor->opos) + + (edge2->pos - edge2->opos)) >> 1; + + AF_LOG(( "DRIFT: %.2f\n", anchor_drift/64.0 )); + } + else + { + FT_Pos org_pos, org_len, org_center, cur_center, cur_len; + FT_Pos org_left, org_right; + + + org_pos = edge->opos + anchor_drift; + org_len = edge2->opos - edge->opos; + org_center = org_pos + ( org_len >> 1 ); + + cur_len = af_latin2_compute_stem_width( + hints, dim, org_len, + (AF_Edge_Flags)edge->flags, + (AF_Edge_Flags)edge2->flags ); + + org_left = org_pos + ((org_len - cur_len) >> 1); + org_right = org_pos + ((org_len + cur_len) >> 1); + + AF_LOG(( "ALIGN: left=%.2f right=%.2f ", org_left/64.0, org_right/64.0 )); + cur_center = org_center; + + if ( edge2->flags & AF_EDGE_DONE ) + { + AF_LOG(( "\n" )); + edge->pos = edge2->pos - cur_len; + } + else + { + /* we want to compare several displacement, and choose + * the one that increases fitness while minimizing + * distortion as well + */ + FT_Pos displacements[6], scores[6], org, fit, delta; + FT_UInt count = 0; + + /* note: don't even try to fit tiny stems */ + if ( cur_len < 32 ) + { + AF_LOG(( "tiny stem\n" )); + goto AlignStem; + } + + /* if the span is within a single pixel, don't touch it */ + if ( FT_PIX_FLOOR(org_left) == FT_PIX_CEIL(org_right) ) + { + AF_LOG(( "single pixel stem\n" )); + goto AlignStem; + } + + if (cur_len <= 96) + { + /* we want to avoid the absolute worst case which is + * when the left and right edges of the span each represent + * about 50% of the gray. we'd better want to change this + * to 25/75%, since this is much more pleasant to the eye with + * very acceptable distortion + */ + FT_Pos frac_left = (org_left) & 63; + FT_Pos frac_right = (org_right) & 63; + + if ( frac_left >= 22 && frac_left <= 42 && + frac_right >= 22 && frac_right <= 42 ) + { + org = frac_left; + fit = (org <= 32) ? 16 : 48; + delta = FT_ABS(fit - org); + displacements[count] = fit - org; + scores[count++] = delta; + AF_LOG(( "dispA=%.2f (%d) ", (fit - org)/64.0, delta )); + + org = frac_right; + fit = (org <= 32) ? 16 : 48; + delta = FT_ABS(fit - org); + displacements[count] = fit - org; + scores[count++] = delta; + AF_LOG(( "dispB=%.2f (%d) ", (fit - org)/64.0, delta )); + } + } + + /* snapping the left edge to the grid */ + org = org_left; + fit = FT_PIX_ROUND(org); + delta = FT_ABS(fit - org); + displacements[count] = fit - org; + scores[count++] = delta; + AF_LOG(( "dispC=%.2f (%d) ", (fit - org)/64.0, delta )); + + /* snapping the right edge to the grid */ + org = org_right; + fit = FT_PIX_ROUND(org); + delta = FT_ABS(fit - org); + displacements[count] = fit - org; + scores[count++] = delta; + AF_LOG(( "dispD=%.2f (%d) ", (fit - org)/64.0, delta )); + + /* now find the best displacement */ + { + FT_Pos best_score = scores[0]; + FT_Pos best_disp = displacements[0]; + FT_UInt nn; + + for (nn = 1; nn < count; nn++) + { + if (scores[nn] < best_score) + { + best_score = scores[nn]; + best_disp = displacements[nn]; + } + } + + cur_center = org_center + best_disp; + } + AF_LOG(( "\n" )); + } + + AlignStem: + edge->pos = cur_center - (cur_len >> 1); + edge2->pos = edge->pos + cur_len; + + AF_LOG(( "STEM1: %d (opos=%.2f) to %d (opos=%.2f) " + "snapped to (%.2f) and (%.2f), org_len = %.2f cur_len=%.2f\n", + edge-edges, edge->opos / 64.0, + edge2-edges, edge2->opos / 64.0, + edge->pos / 64.0, edge2->pos / 64.0, + org_len / 64.0, cur_len / 64.0 )); + + edge->flags |= AF_EDGE_DONE; + edge2->flags |= AF_EDGE_DONE; + + if ( edge > edges && edge->pos < edge[-1].pos ) + { + AF_LOG(( "BOUND: %d (pos=%.2f) to (%.2f)\n", + edge-edges, edge->pos / 64.0, edge[-1].pos / 64.0 )); + edge->pos = edge[-1].pos; + } + } + } + + /* make sure that lowercase m's maintain their symmetry */ + + /* In general, lowercase m's have six vertical edges if they are sans */ + /* serif, or twelve if they are with serifs. This implementation is */ + /* based on that assumption, and seems to work very well with most */ + /* faces. However, if for a certain face this assumption is not */ + /* true, the m is just rendered like before. In addition, any stem */ + /* correction will only be applied to symmetrical glyphs (even if the */ + /* glyph is not an m), so the potential for unwanted distortion is */ + /* relatively low. */ + + /* We don't handle horizontal edges since we can't easily assure that */ + /* the third (lowest) stem aligns with the base line; it might end up */ + /* one pixel higher or lower. */ + +#if 0 + { + FT_Int n_edges = edge_limit - edges; + + + if ( dim == AF_DIMENSION_HORZ && ( n_edges == 6 || n_edges == 12 ) ) + { + AF_Edge edge1, edge2, edge3; + FT_Pos dist1, dist2, span, delta; + + + if ( n_edges == 6 ) + { + edge1 = edges; + edge2 = edges + 2; + edge3 = edges + 4; + } + else + { + edge1 = edges + 1; + edge2 = edges + 5; + edge3 = edges + 9; + } + + dist1 = edge2->opos - edge1->opos; + dist2 = edge3->opos - edge2->opos; + + span = dist1 - dist2; + if ( span < 0 ) + span = -span; + + if ( span < 8 ) + { + delta = edge3->pos - ( 2 * edge2->pos - edge1->pos ); + edge3->pos -= delta; + if ( edge3->link ) + edge3->link->pos -= delta; + + /* move the serifs along with the stem */ + if ( n_edges == 12 ) + { + ( edges + 8 )->pos -= delta; + ( edges + 11 )->pos -= delta; + } + + edge3->flags |= AF_EDGE_DONE; + if ( edge3->link ) + edge3->link->flags |= AF_EDGE_DONE; + } + } + } +#endif + + if ( has_serifs || !anchor ) + { + /* + * now hint the remaining edges (serifs and single) in order + * to complete our processing + */ + for ( edge = edges; edge < edge_limit; edge++ ) + { + FT_Pos delta; + + + if ( edge->flags & AF_EDGE_DONE ) + continue; + + delta = 1000; + + if ( edge->serif ) + { + delta = edge->serif->opos - edge->opos; + if ( delta < 0 ) + delta = -delta; + } + + if ( delta < 64 + 16 ) + { + af_latin2_align_serif_edge( hints, edge->serif, edge ); + AF_LOG(( "SERIF: edge %d (opos=%.2f) serif to %d (opos=%.2f) " + "aligned to (%.2f)\n", + edge-edges, edge->opos / 64.0, + edge->serif - edges, edge->serif->opos / 64.0, + edge->pos / 64.0 )); + } + else if ( !anchor ) + { + AF_LOG(( "SERIF_ANCHOR: edge %d (opos=%.2f) snapped to (%.2f)\n", + edge-edges, edge->opos / 64.0, edge->pos / 64.0 )); + edge->pos = FT_PIX_ROUND( edge->opos ); + anchor = edge; + } + else + { + AF_Edge before, after; + + + for ( before = edge - 1; before >= edges; before-- ) + if ( before->flags & AF_EDGE_DONE ) + break; + + for ( after = edge + 1; after < edge_limit; after++ ) + if ( after->flags & AF_EDGE_DONE ) + break; + + if ( before >= edges && before < edge && + after < edge_limit && after > edge ) + { + if ( after->opos == before->opos ) + edge->pos = before->pos; + else + edge->pos = before->pos + + FT_MulDiv( edge->opos - before->opos, + after->pos - before->pos, + after->opos - before->opos ); + AF_LOG(( "SERIF_LINK1: edge %d (opos=%.2f) snapped to (%.2f) from %d (opos=%.2f)\n", + edge-edges, edge->opos / 64.0, edge->pos / 64.0, before - edges, before->opos / 64.0 )); + } + else + { + edge->pos = anchor->pos + (( edge->opos - anchor->opos + 16) & ~31); + + AF_LOG(( "SERIF_LINK2: edge %d (opos=%.2f) snapped to (%.2f)\n", + edge-edges, edge->opos / 64.0, edge->pos / 64.0 )); + } + } + + edge->flags |= AF_EDGE_DONE; + + if ( edge > edges && edge->pos < edge[-1].pos ) + edge->pos = edge[-1].pos; + + if ( edge + 1 < edge_limit && + edge[1].flags & AF_EDGE_DONE && + edge->pos > edge[1].pos ) + edge->pos = edge[1].pos; + } + } + } + + + static FT_Error + af_latin2_hints_apply( AF_GlyphHints hints, + FT_Outline* outline, + AF_LatinMetrics metrics ) + { + FT_Error error; + int dim; + + + error = af_glyph_hints_reload( hints, outline, 1 ); + if ( error ) + goto Exit; + + /* analyze glyph outline */ +#ifdef AF_USE_WARPER + if ( metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT || + AF_HINTS_DO_HORIZONTAL( hints ) ) +#else + if ( AF_HINTS_DO_HORIZONTAL( hints ) ) +#endif + { + error = af_latin2_hints_detect_features( hints, AF_DIMENSION_HORZ ); + if ( error ) + goto Exit; + } + + if ( AF_HINTS_DO_VERTICAL( hints ) ) + { + error = af_latin2_hints_detect_features( hints, AF_DIMENSION_VERT ); + if ( error ) + goto Exit; + + af_latin2_hints_compute_blue_edges( hints, metrics ); + } + + /* grid-fit the outline */ + for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) + { +#ifdef AF_USE_WARPER + if ( ( dim == AF_DIMENSION_HORZ && + metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT ) ) + { + AF_WarperRec warper; + FT_Fixed scale; + FT_Pos delta; + + + af_warper_compute( &warper, hints, dim, &scale, &delta ); + af_glyph_hints_scale_dim( hints, dim, scale, delta ); + continue; + } +#endif + + if ( ( dim == AF_DIMENSION_HORZ && AF_HINTS_DO_HORIZONTAL( hints ) ) || + ( dim == AF_DIMENSION_VERT && AF_HINTS_DO_VERTICAL( hints ) ) ) + { + af_latin2_hint_edges( hints, (AF_Dimension)dim ); + af_glyph_hints_align_edge_points( hints, (AF_Dimension)dim ); + af_glyph_hints_align_strong_points( hints, (AF_Dimension)dim ); + af_glyph_hints_align_weak_points( hints, (AF_Dimension)dim ); + } + } + af_glyph_hints_save( hints, outline ); + + Exit: + return error; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** L A T I N S C R I P T C L A S S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + static const AF_Script_UniRangeRec af_latin2_uniranges[] = + { + AF_UNIRANGE_REC( 32UL, 127UL ), /* XXX: TODO: Add new Unicode ranges here! */ + AF_UNIRANGE_REC( 160UL, 255UL ), + AF_UNIRANGE_REC( 0UL, 0UL ) + }; + + + AF_DEFINE_SCRIPT_CLASS(af_latin2_script_class, + AF_SCRIPT_LATIN2, + af_latin2_uniranges, + + sizeof( AF_LatinMetricsRec ), + + (AF_Script_InitMetricsFunc) af_latin2_metrics_init, + (AF_Script_ScaleMetricsFunc)af_latin2_metrics_scale, + (AF_Script_DoneMetricsFunc) NULL, + + (AF_Script_InitHintsFunc) af_latin2_hints_init, + (AF_Script_ApplyHintsFunc) af_latin2_hints_apply + ) + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/autofit/aflatin2.h b/mod/pub.mod/freetype.mod/src/autofit/aflatin2.h new file mode 100644 index 0000000..925c621 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/autofit/aflatin2.h @@ -0,0 +1,39 @@ +/***************************************************************************/ +/* */ +/* aflatin2.h */ +/* */ +/* Auto-fitter hinting routines for latin script (specification). */ +/* */ +/* Copyright 2003, 2004, 2005, 2006, 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __AFLATIN2_H__ +#define __AFLATIN2_H__ + +#include "afhints.h" + + +FT_BEGIN_HEADER + + + /* the latin-specific script class */ + + AF_DECLARE_SCRIPT_CLASS(af_latin2_script_class) + +/* */ + +FT_END_HEADER + +#endif /* __AFLATIN_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/autofit/afloader.c b/mod/pub.mod/freetype.mod/src/autofit/afloader.c new file mode 100644 index 0000000..6dd9f2a --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/autofit/afloader.c @@ -0,0 +1,539 @@ +/***************************************************************************/ +/* */ +/* afloader.c */ +/* */ +/* Auto-fitter glyph loading routines (body). */ +/* */ +/* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include "afloader.h" +#include "afhints.h" +#include "afglobal.h" +#include "aferrors.h" + + + FT_LOCAL_DEF( FT_Error ) + af_loader_init( AF_Loader loader, + FT_Memory memory ) + { + FT_ZERO( loader ); + + af_glyph_hints_init( &loader->hints, memory ); +#ifdef AF_DEBUG + _af_debug_hints = &loader->hints; +#endif + return FT_GlyphLoader_New( memory, &loader->gloader ); + } + + + FT_LOCAL_DEF( FT_Error ) + af_loader_reset( AF_Loader loader, + FT_Face face ) + { + FT_Error error = AF_Err_Ok; + + + loader->face = face; + loader->globals = (AF_FaceGlobals)face->autohint.data; + + FT_GlyphLoader_Rewind( loader->gloader ); + + if ( loader->globals == NULL ) + { + error = af_face_globals_new( face, &loader->globals ); + if ( !error ) + { + face->autohint.data = + (FT_Pointer)loader->globals; + face->autohint.finalizer = + (FT_Generic_Finalizer)af_face_globals_free; + } + } + + return error; + } + + + FT_LOCAL_DEF( void ) + af_loader_done( AF_Loader loader ) + { + af_glyph_hints_done( &loader->hints ); + + loader->face = NULL; + loader->globals = NULL; + +#ifdef AF_DEBUG + _af_debug_hints = NULL; +#endif + FT_GlyphLoader_Done( loader->gloader ); + loader->gloader = NULL; + } + + + static FT_Error + af_loader_load_g( AF_Loader loader, + AF_Scaler scaler, + FT_UInt glyph_index, + FT_Int32 load_flags, + FT_UInt depth ) + { + FT_Error error; + FT_Face face = loader->face; + FT_GlyphLoader gloader = loader->gloader; + AF_ScriptMetrics metrics = loader->metrics; + AF_GlyphHints hints = &loader->hints; + FT_GlyphSlot slot = face->glyph; + FT_Slot_Internal internal = slot->internal; + + + error = FT_Load_Glyph( face, glyph_index, load_flags ); + if ( error ) + goto Exit; + + loader->transformed = internal->glyph_transformed; + if ( loader->transformed ) + { + FT_Matrix inverse; + + + loader->trans_matrix = internal->glyph_matrix; + loader->trans_delta = internal->glyph_delta; + + inverse = loader->trans_matrix; + FT_Matrix_Invert( &inverse ); + FT_Vector_Transform( &loader->trans_delta, &inverse ); + } + + /* set linear metrics */ + slot->linearHoriAdvance = slot->metrics.horiAdvance; + slot->linearVertAdvance = slot->metrics.vertAdvance; + + switch ( slot->format ) + { + case FT_GLYPH_FORMAT_OUTLINE: + /* translate the loaded glyph when an internal transform is needed */ + if ( loader->transformed ) + FT_Outline_Translate( &slot->outline, + loader->trans_delta.x, + loader->trans_delta.y ); + + /* copy the outline points in the loader's current */ + /* extra points which is used to keep original glyph coordinates */ + error = FT_GLYPHLOADER_CHECK_POINTS( gloader, + slot->outline.n_points + 4, + slot->outline.n_contours ); + if ( error ) + goto Exit; + + FT_ARRAY_COPY( gloader->current.outline.points, + slot->outline.points, + slot->outline.n_points ); + + FT_ARRAY_COPY( gloader->current.outline.contours, + slot->outline.contours, + slot->outline.n_contours ); + + FT_ARRAY_COPY( gloader->current.outline.tags, + slot->outline.tags, + slot->outline.n_points ); + + gloader->current.outline.n_points = slot->outline.n_points; + gloader->current.outline.n_contours = slot->outline.n_contours; + + /* compute original horizontal phantom points (and ignore */ + /* vertical ones) */ + loader->pp1.x = hints->x_delta; + loader->pp1.y = hints->y_delta; + loader->pp2.x = FT_MulFix( slot->metrics.horiAdvance, + hints->x_scale ) + hints->x_delta; + loader->pp2.y = hints->y_delta; + + /* be sure to check for spacing glyphs */ + if ( slot->outline.n_points == 0 ) + goto Hint_Metrics; + + /* now load the slot image into the auto-outline and run the */ + /* automatic hinting process */ + if ( metrics->clazz->script_hints_apply ) + metrics->clazz->script_hints_apply( hints, + &gloader->current.outline, + metrics ); + + /* we now need to hint the metrics according to the change in */ + /* width/positioning that occurred during the hinting process */ + if ( scaler->render_mode != FT_RENDER_MODE_LIGHT ) + { + FT_Pos old_rsb, old_lsb, new_lsb; + FT_Pos pp1x_uh, pp2x_uh; + AF_AxisHints axis = &hints->axis[AF_DIMENSION_HORZ]; + AF_Edge edge1 = axis->edges; /* leftmost edge */ + AF_Edge edge2 = edge1 + + axis->num_edges - 1; /* rightmost edge */ + + + if ( axis->num_edges > 1 && AF_HINTS_DO_ADVANCE( hints ) ) + { + old_rsb = loader->pp2.x - edge2->opos; + old_lsb = edge1->opos; + new_lsb = edge1->pos; + + /* remember unhinted values to later account */ + /* for rounding errors */ + + pp1x_uh = new_lsb - old_lsb; + pp2x_uh = edge2->pos + old_rsb; + + /* prefer too much space over too little space */ + /* for very small sizes */ + + if ( old_lsb < 24 ) + pp1x_uh -= 8; + + if ( old_rsb < 24 ) + pp2x_uh += 8; + + loader->pp1.x = FT_PIX_ROUND( pp1x_uh ); + loader->pp2.x = FT_PIX_ROUND( pp2x_uh ); + + if ( loader->pp1.x >= new_lsb && old_lsb > 0 ) + loader->pp1.x -= 64; + + if ( loader->pp2.x <= edge2->pos && old_rsb > 0 ) + loader->pp2.x += 64; + + slot->lsb_delta = loader->pp1.x - pp1x_uh; + slot->rsb_delta = loader->pp2.x - pp2x_uh; + } + else + { + FT_Pos pp1x = loader->pp1.x; + FT_Pos pp2x = loader->pp2.x; + + + loader->pp1.x = FT_PIX_ROUND( pp1x ); + loader->pp2.x = FT_PIX_ROUND( pp2x ); + + slot->lsb_delta = loader->pp1.x - pp1x; + slot->rsb_delta = loader->pp2.x - pp2x; + } + } + else + { + FT_Pos pp1x = loader->pp1.x; + FT_Pos pp2x = loader->pp2.x; + + + loader->pp1.x = FT_PIX_ROUND( pp1x + hints->xmin_delta ); + loader->pp2.x = FT_PIX_ROUND( pp2x + hints->xmax_delta ); + + slot->lsb_delta = loader->pp1.x - pp1x; + slot->rsb_delta = loader->pp2.x - pp2x; + } + + /* good, we simply add the glyph to our loader's base */ + FT_GlyphLoader_Add( gloader ); + break; + + case FT_GLYPH_FORMAT_COMPOSITE: + { + FT_UInt nn, num_subglyphs = slot->num_subglyphs; + FT_UInt num_base_subgs, start_point; + FT_SubGlyph subglyph; + + + start_point = gloader->base.outline.n_points; + + /* first of all, copy the subglyph descriptors in the glyph loader */ + error = FT_GlyphLoader_CheckSubGlyphs( gloader, num_subglyphs ); + if ( error ) + goto Exit; + + FT_ARRAY_COPY( gloader->current.subglyphs, + slot->subglyphs, + num_subglyphs ); + + gloader->current.num_subglyphs = num_subglyphs; + num_base_subgs = gloader->base.num_subglyphs; + + /* now, read each subglyph independently */ + for ( nn = 0; nn < num_subglyphs; nn++ ) + { + FT_Vector pp1, pp2; + FT_Pos x, y; + FT_UInt num_points, num_new_points, num_base_points; + + + /* gloader.current.subglyphs can change during glyph loading due */ + /* to re-allocation -- we must recompute the current subglyph on */ + /* each iteration */ + subglyph = gloader->base.subglyphs + num_base_subgs + nn; + + pp1 = loader->pp1; + pp2 = loader->pp2; + + num_base_points = gloader->base.outline.n_points; + + error = af_loader_load_g( loader, scaler, subglyph->index, + load_flags, depth + 1 ); + if ( error ) + goto Exit; + + /* recompute subglyph pointer */ + subglyph = gloader->base.subglyphs + num_base_subgs + nn; + + if ( subglyph->flags & FT_SUBGLYPH_FLAG_USE_MY_METRICS ) + { + pp1 = loader->pp1; + pp2 = loader->pp2; + } + else + { + loader->pp1 = pp1; + loader->pp2 = pp2; + } + + num_points = gloader->base.outline.n_points; + num_new_points = num_points - num_base_points; + + /* now perform the transform required for this subglyph */ + + if ( subglyph->flags & ( FT_SUBGLYPH_FLAG_SCALE | + FT_SUBGLYPH_FLAG_XY_SCALE | + FT_SUBGLYPH_FLAG_2X2 ) ) + { + FT_Vector* cur = gloader->base.outline.points + + num_base_points; + FT_Vector* limit = cur + num_new_points; + + + for ( ; cur < limit; cur++ ) + FT_Vector_Transform( cur, &subglyph->transform ); + } + + /* apply offset */ + + if ( !( subglyph->flags & FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES ) ) + { + FT_Int k = subglyph->arg1; + FT_UInt l = subglyph->arg2; + FT_Vector* p1; + FT_Vector* p2; + + + if ( start_point + k >= num_base_points || + l >= (FT_UInt)num_new_points ) + { + error = AF_Err_Invalid_Composite; + goto Exit; + } + + l += num_base_points; + + /* for now, only use the current point coordinates; */ + /* we may consider another approach in the near future */ + p1 = gloader->base.outline.points + start_point + k; + p2 = gloader->base.outline.points + start_point + l; + + x = p1->x - p2->x; + y = p1->y - p2->y; + } + else + { + x = FT_MulFix( subglyph->arg1, hints->x_scale ) + hints->x_delta; + y = FT_MulFix( subglyph->arg2, hints->y_scale ) + hints->y_delta; + + x = FT_PIX_ROUND( x ); + y = FT_PIX_ROUND( y ); + } + + { + FT_Outline dummy = gloader->base.outline; + + + dummy.points += num_base_points; + dummy.n_points = (short)num_new_points; + + FT_Outline_Translate( &dummy, x, y ); + } + } + } + break; + + default: + /* we don't support other formats (yet?) */ + error = AF_Err_Unimplemented_Feature; + } + + Hint_Metrics: + if ( depth == 0 ) + { + FT_BBox bbox; + FT_Vector vvector; + + + vvector.x = slot->metrics.vertBearingX - slot->metrics.horiBearingX; + vvector.y = slot->metrics.vertBearingY - slot->metrics.horiBearingY; + vvector.x = FT_MulFix( vvector.x, metrics->scaler.x_scale ); + vvector.y = FT_MulFix( vvector.y, metrics->scaler.y_scale ); + + /* transform the hinted outline if needed */ + if ( loader->transformed ) + { + FT_Outline_Transform( &gloader->base.outline, &loader->trans_matrix ); + FT_Vector_Transform( &vvector, &loader->trans_matrix ); + } +#if 1 + /* we must translate our final outline by -pp1.x and compute */ + /* the new metrics */ + if ( loader->pp1.x ) + FT_Outline_Translate( &gloader->base.outline, -loader->pp1.x, 0 ); +#endif + FT_Outline_Get_CBox( &gloader->base.outline, &bbox ); + + bbox.xMin = FT_PIX_FLOOR( bbox.xMin ); + bbox.yMin = FT_PIX_FLOOR( bbox.yMin ); + bbox.xMax = FT_PIX_CEIL( bbox.xMax ); + bbox.yMax = FT_PIX_CEIL( bbox.yMax ); + + slot->metrics.width = bbox.xMax - bbox.xMin; + slot->metrics.height = bbox.yMax - bbox.yMin; + slot->metrics.horiBearingX = bbox.xMin; + slot->metrics.horiBearingY = bbox.yMax; + + slot->metrics.vertBearingX = FT_PIX_FLOOR( bbox.xMin + vvector.x ); + slot->metrics.vertBearingY = FT_PIX_FLOOR( bbox.yMax + vvector.y ); + + /* for mono-width fonts (like Andale, Courier, etc.) we need */ + /* to keep the original rounded advance width; ditto for */ + /* digits if all have the same advance width */ +#if 0 + if ( !FT_IS_FIXED_WIDTH( slot->face ) ) + slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x; + else + slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance, + x_scale ); +#else + if ( FT_IS_FIXED_WIDTH( slot->face ) || + ( af_face_globals_is_digit( loader->globals, glyph_index ) && + metrics->digits_have_same_width ) ) + { + slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance, + metrics->scaler.x_scale ); + + /* Set delta values to 0. Otherwise code that uses them is */ + /* going to ruin the fixed advance width. */ + slot->lsb_delta = 0; + slot->rsb_delta = 0; + } + else + { + /* non-spacing glyphs must stay as-is */ + if ( slot->metrics.horiAdvance ) + slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x; + } +#endif + + slot->metrics.vertAdvance = FT_MulFix( slot->metrics.vertAdvance, + metrics->scaler.y_scale ); + + slot->metrics.horiAdvance = FT_PIX_ROUND( slot->metrics.horiAdvance ); + slot->metrics.vertAdvance = FT_PIX_ROUND( slot->metrics.vertAdvance ); + + /* now copy outline into glyph slot */ + FT_GlyphLoader_Rewind( internal->loader ); + error = FT_GlyphLoader_CopyPoints( internal->loader, gloader ); + if ( error ) + goto Exit; + + slot->outline = internal->loader->base.outline; + slot->format = FT_GLYPH_FORMAT_OUTLINE; + } + +#ifdef DEBUG_HINTER + af_debug_hinter = hinter; +#endif + + Exit: + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + af_loader_load_glyph( AF_Loader loader, + FT_Face face, + FT_UInt gindex, + FT_UInt32 load_flags ) + { + FT_Error error; + FT_Size size = face->size; + AF_ScalerRec scaler; + + + if ( !size ) + return AF_Err_Invalid_Argument; + + FT_ZERO( &scaler ); + + scaler.face = face; + scaler.x_scale = size->metrics.x_scale; + scaler.x_delta = 0; /* XXX: TODO: add support for sub-pixel hinting */ + scaler.y_scale = size->metrics.y_scale; + scaler.y_delta = 0; /* XXX: TODO: add support for sub-pixel hinting */ + + scaler.render_mode = FT_LOAD_TARGET_MODE( load_flags ); + scaler.flags = 0; /* XXX: fix this */ + + error = af_loader_reset( loader, face ); + if ( !error ) + { + AF_ScriptMetrics metrics; + FT_UInt options = 0; + + +#ifdef FT_OPTION_AUTOFIT2 + /* XXX: undocumented hook to activate the latin2 hinter */ + if ( load_flags & ( 1UL << 20 ) ) + options = 2; +#endif + + error = af_face_globals_get_metrics( loader->globals, gindex, + options, &metrics ); + if ( !error ) + { + loader->metrics = metrics; + + if ( metrics->clazz->script_metrics_scale ) + metrics->clazz->script_metrics_scale( metrics, &scaler ); + else + metrics->scaler = scaler; + + load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_IGNORE_TRANSFORM; + load_flags &= ~FT_LOAD_RENDER; + + if ( metrics->clazz->script_hints_init ) + { + error = metrics->clazz->script_hints_init( &loader->hints, + metrics ); + if ( error ) + goto Exit; + } + + error = af_loader_load_g( loader, &scaler, gindex, load_flags, 0 ); + } + } + Exit: + return error; + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/autofit/afloader.h b/mod/pub.mod/freetype.mod/src/autofit/afloader.h new file mode 100644 index 0000000..fa67c10 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/autofit/afloader.h @@ -0,0 +1,73 @@ +/***************************************************************************/ +/* */ +/* afloader.h */ +/* */ +/* Auto-fitter glyph loading routines (specification). */ +/* */ +/* Copyright 2003, 2004, 2005 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __AF_LOADER_H__ +#define __AF_LOADER_H__ + +#include "afhints.h" +#include "afglobal.h" + + +FT_BEGIN_HEADER + + typedef struct AF_LoaderRec_ + { + FT_Face face; /* current face */ + AF_FaceGlobals globals; /* current face globals */ + FT_GlyphLoader gloader; /* glyph loader */ + AF_GlyphHintsRec hints; + AF_ScriptMetrics metrics; + FT_Bool transformed; + FT_Matrix trans_matrix; + FT_Vector trans_delta; + FT_Vector pp1; + FT_Vector pp2; + /* we don't handle vertical phantom points */ + + } AF_LoaderRec, *AF_Loader; + + + FT_LOCAL( FT_Error ) + af_loader_init( AF_Loader loader, + FT_Memory memory ); + + + FT_LOCAL( FT_Error ) + af_loader_reset( AF_Loader loader, + FT_Face face ); + + + FT_LOCAL( void ) + af_loader_done( AF_Loader loader ); + + + FT_LOCAL( FT_Error ) + af_loader_load_glyph( AF_Loader loader, + FT_Face face, + FT_UInt gindex, + FT_UInt32 load_flags ); + +/* */ + + +FT_END_HEADER + +#endif /* __AF_LOADER_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/autofit/afmodule.c b/mod/pub.mod/freetype.mod/src/autofit/afmodule.c new file mode 100644 index 0000000..ec2d707 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/autofit/afmodule.c @@ -0,0 +1,94 @@ +/***************************************************************************/ +/* */ +/* afmodule.c */ +/* */ +/* Auto-fitter module implementation (body). */ +/* */ +/* Copyright 2003, 2004, 2005, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include "afmodule.h" +#include "afloader.h" +#include "afpic.h" + +#ifdef AF_DEBUG + int _af_debug; + int _af_debug_disable_horz_hints; + int _af_debug_disable_vert_hints; + int _af_debug_disable_blue_hints; + void* _af_debug_hints; +#endif + +#include FT_INTERNAL_OBJECTS_H + + + typedef struct FT_AutofitterRec_ + { + FT_ModuleRec root; + AF_LoaderRec loader[1]; + + } FT_AutofitterRec, *FT_Autofitter; + + + FT_CALLBACK_DEF( FT_Error ) + af_autofitter_init( FT_Autofitter module ) + { + return af_loader_init( module->loader, module->root.library->memory ); + } + + + FT_CALLBACK_DEF( void ) + af_autofitter_done( FT_Autofitter module ) + { + af_loader_done( module->loader ); + } + + + FT_CALLBACK_DEF( FT_Error ) + af_autofitter_load_glyph( FT_Autofitter module, + FT_GlyphSlot slot, + FT_Size size, + FT_UInt glyph_index, + FT_Int32 load_flags ) + { + FT_UNUSED( size ); + + return af_loader_load_glyph( module->loader, slot->face, + glyph_index, load_flags ); + } + + + FT_DEFINE_AUTOHINTER_SERVICE(af_autofitter_service, + NULL, + NULL, + NULL, + (FT_AutoHinter_GlyphLoadFunc)af_autofitter_load_glyph + ) + + FT_DEFINE_MODULE(autofit_module_class, + + FT_MODULE_HINTER, + sizeof ( FT_AutofitterRec ), + + "autofitter", + 0x10000L, /* version 1.0 of the autofitter */ + 0x20000L, /* requires FreeType 2.0 or above */ + + (const void*)&AF_AF_AUTOFITTER_SERVICE_GET, + + (FT_Module_Constructor)af_autofitter_init, + (FT_Module_Destructor) af_autofitter_done, + (FT_Module_Requester) NULL + ) + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/autofit/afmodule.h b/mod/pub.mod/freetype.mod/src/autofit/afmodule.h new file mode 100644 index 0000000..d979239 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/autofit/afmodule.h @@ -0,0 +1,37 @@ +/***************************************************************************/ +/* */ +/* afmodule.h */ +/* */ +/* Auto-fitter module implementation (specification). */ +/* */ +/* Copyright 2003, 2004, 2005 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __AFMODULE_H__ +#define __AFMODULE_H__ + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H +#include FT_MODULE_H + + +FT_BEGIN_HEADER + +FT_DECLARE_MODULE(autofit_module_class) + + +FT_END_HEADER + +#endif /* __AFMODULE_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/autofit/afpic.c b/mod/pub.mod/freetype.mod/src/autofit/afpic.c new file mode 100644 index 0000000..76822c3 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/autofit/afpic.c @@ -0,0 +1,92 @@ +/***************************************************************************/ +/* */ +/* afpic.c */ +/* */ +/* The FreeType position independent code services for autofit module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include "afpic.h" + +#ifdef FT_CONFIG_OPTION_PIC + + /* forward declaration of PIC init functions from afmodule.c */ + void FT_Init_Class_af_autofitter_service( FT_Library, FT_AutoHinter_ServiceRec*); + + /* forward declaration of PIC init functions from script classes */ +#include "aflatin.h" +#include "aflatin2.h" +#include "afcjk.h" +#include "afdummy.h" +#include "afindic.h" + + void + autofit_module_class_pic_free( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Memory memory = library->memory; + if ( pic_container->autofit ) + { + FT_FREE( pic_container->autofit ); + pic_container->autofit = NULL; + } + } + + FT_Error + autofit_module_class_pic_init( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_UInt ss; + FT_Error error = FT_Err_Ok; + AFModulePIC* container; + FT_Memory memory = library->memory; + + /* allocate pointer, clear and set global container pointer */ + if ( FT_ALLOC ( container, sizeof ( *container ) ) ) + return error; + FT_MEM_SET( container, 0, sizeof(*container) ); + pic_container->autofit = container; + + /* initialize pointer table - this is how the module usually expects this data */ + for ( ss = 0 ; ss < AF_SCRIPT_CLASSES_REC_COUNT ; ss++ ) + { + container->af_script_classes[ss] = &container->af_script_classes_rec[ss]; + } + container->af_script_classes[AF_SCRIPT_CLASSES_COUNT-1] = NULL; + + /* add call to initialization function when you add new scripts */ + ss = 0; + FT_Init_Class_af_dummy_script_class(&container->af_script_classes_rec[ss++]); +#ifdef FT_OPTION_AUTOFIT2 + FT_Init_Class_af_latin2_script_class(&container->af_script_classes_rec[ss++]); +#endif + FT_Init_Class_af_latin_script_class(&container->af_script_classes_rec[ss++]); + FT_Init_Class_af_cjk_script_class(&container->af_script_classes_rec[ss++]); + FT_Init_Class_af_indic_script_class(&container->af_script_classes_rec[ss++]); + + FT_Init_Class_af_autofitter_service(library, &container->af_autofitter_service); + +/*Exit:*/ + if(error) + autofit_module_class_pic_free(library); + return error; + } + + +#endif /* FT_CONFIG_OPTION_PIC */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/autofit/afpic.h b/mod/pub.mod/freetype.mod/src/autofit/afpic.h new file mode 100644 index 0000000..80e62d3 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/autofit/afpic.h @@ -0,0 +1,64 @@ +/***************************************************************************/ +/* */ +/* afpic.h */ +/* */ +/* The FreeType position independent code services for autofit module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __AFPIC_H__ +#define __AFPIC_H__ + + +FT_BEGIN_HEADER + +#include FT_INTERNAL_PIC_H + +#ifndef FT_CONFIG_OPTION_PIC + +#define AF_SCRIPT_CLASSES_GET af_script_classes +#define AF_AF_AUTOFITTER_SERVICE_GET af_autofitter_service + +#else /* FT_CONFIG_OPTION_PIC */ + +#include "aftypes.h" + +/* increase these when you add new scripts, and update autofit_module_class_pic_init */ +#ifdef FT_OPTION_AUTOFIT2 + #define AF_SCRIPT_CLASSES_COUNT 6 +#else + #define AF_SCRIPT_CLASSES_COUNT 5 +#endif +#define AF_SCRIPT_CLASSES_REC_COUNT (AF_SCRIPT_CLASSES_COUNT-1) + + typedef struct AFModulePIC_ + { + AF_ScriptClass af_script_classes[AF_SCRIPT_CLASSES_COUNT]; + AF_ScriptClassRec af_script_classes_rec[AF_SCRIPT_CLASSES_REC_COUNT]; + FT_AutoHinter_ServiceRec af_autofitter_service; + } AFModulePIC; + +#define GET_PIC(lib) ((AFModulePIC*)((lib)->pic_container.autofit)) +#define AF_SCRIPT_CLASSES_GET (GET_PIC(FT_FACE_LIBRARY(globals->face))->af_script_classes) +#define AF_AF_AUTOFITTER_SERVICE_GET (GET_PIC(library)->af_autofitter_service) + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + +FT_END_HEADER + +#endif /* __AFPIC_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/autofit/aftypes.h b/mod/pub.mod/freetype.mod/src/autofit/aftypes.h new file mode 100644 index 0000000..5574f0c --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/autofit/aftypes.h @@ -0,0 +1,403 @@ +/***************************************************************************/ +/* */ +/* aftypes.h */ +/* */ +/* Auto-fitter types (specification only). */ +/* */ +/* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /************************************************************************* + * + * The auto-fitter is a complete rewrite of the old auto-hinter. + * Its main feature is the ability to differentiate between different + * scripts in order to apply language-specific rules. + * + * The code has also been compartmentized into several entities that + * should make algorithmic experimentation easier than with the old + * code. + * + * Finally, we get rid of the Catharon license, since this code is + * released under the FreeType one. + * + *************************************************************************/ + + +#ifndef __AFTYPES_H__ +#define __AFTYPES_H__ + +#include <ft2build.h> + +#include FT_FREETYPE_H +#include FT_OUTLINE_H +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_DEBUG_H + + +FT_BEGIN_HEADER + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** D E B U G G I N G *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + +#define xxAF_USE_WARPER /* only define to use warp hinting */ +#define xxAF_DEBUG + +#ifdef AF_DEBUG + +#include FT_CONFIG_STANDARD_LIBRARY_H + +#define AF_LOG( x ) do { if ( _af_debug ) printf x; } while ( 0 ) + +extern int _af_debug; +extern int _af_debug_disable_horz_hints; +extern int _af_debug_disable_vert_hints; +extern int _af_debug_disable_blue_hints; +extern void* _af_debug_hints; + +#else /* !AF_DEBUG */ + +#define AF_LOG( x ) do { } while ( 0 ) /* nothing */ + +#endif /* !AF_DEBUG */ + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** U T I L I T Y S T U F F *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef struct AF_WidthRec_ + { + FT_Pos org; /* original position/width in font units */ + FT_Pos cur; /* current/scaled position/width in device sub-pixels */ + FT_Pos fit; /* current/fitted position/width in device sub-pixels */ + + } AF_WidthRec, *AF_Width; + + + FT_LOCAL( void ) + af_sort_pos( FT_UInt count, + FT_Pos* table ); + + FT_LOCAL( void ) + af_sort_widths( FT_UInt count, + AF_Width widths ); + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** A N G L E T Y P E S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* + * The auto-fitter doesn't need a very high angular accuracy; + * this allows us to speed up some computations considerably with a + * light Cordic algorithm (see afangles.c). + */ + + typedef FT_Int AF_Angle; + + +#define AF_ANGLE_PI 256 +#define AF_ANGLE_2PI ( AF_ANGLE_PI * 2 ) +#define AF_ANGLE_PI2 ( AF_ANGLE_PI / 2 ) +#define AF_ANGLE_PI4 ( AF_ANGLE_PI / 4 ) + + +#if 0 + /* + * compute the angle of a given 2-D vector + */ + FT_LOCAL( AF_Angle ) + af_angle_atan( FT_Pos dx, + FT_Pos dy ); + + + /* + * compute `angle2 - angle1'; the result is always within + * the range [-AF_ANGLE_PI .. AF_ANGLE_PI - 1] + */ + FT_LOCAL( AF_Angle ) + af_angle_diff( AF_Angle angle1, + AF_Angle angle2 ); +#endif /* 0 */ + + +#define AF_ANGLE_DIFF( result, angle1, angle2 ) \ + FT_BEGIN_STMNT \ + AF_Angle _delta = (angle2) - (angle1); \ + \ + \ + _delta %= AF_ANGLE_2PI; \ + if ( _delta < 0 ) \ + _delta += AF_ANGLE_2PI; \ + \ + if ( _delta > AF_ANGLE_PI ) \ + _delta -= AF_ANGLE_2PI; \ + \ + result = _delta; \ + FT_END_STMNT + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** O U T L I N E S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* opaque handle to glyph-specific hints -- see `afhints.h' for more + * details + */ + typedef struct AF_GlyphHintsRec_* AF_GlyphHints; + + /* This structure is used to model an input glyph outline to + * the auto-hinter. The latter will set the `hints' field + * depending on the glyph's script. + */ + typedef struct AF_OutlineRec_ + { + FT_Face face; + FT_Outline outline; + FT_UInt outline_resolution; + + FT_Int advance; + FT_UInt metrics_resolution; + + AF_GlyphHints hints; + + } AF_OutlineRec; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** S C A L E R S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* + * A scaler models the target pixel device that will receive the + * auto-hinted glyph image. + */ + + typedef enum AF_ScalerFlags_ + { + AF_SCALER_FLAG_NO_HORIZONTAL = 1, /* disable horizontal hinting */ + AF_SCALER_FLAG_NO_VERTICAL = 2, /* disable vertical hinting */ + AF_SCALER_FLAG_NO_ADVANCE = 4 /* disable advance hinting */ + + } AF_ScalerFlags; + + + typedef struct AF_ScalerRec_ + { + FT_Face face; /* source font face */ + FT_Fixed x_scale; /* from font units to 1/64th device pixels */ + FT_Fixed y_scale; /* from font units to 1/64th device pixels */ + FT_Pos x_delta; /* in 1/64th device pixels */ + FT_Pos y_delta; /* in 1/64th device pixels */ + FT_Render_Mode render_mode; /* monochrome, anti-aliased, LCD, etc. */ + FT_UInt32 flags; /* additional control flags, see above */ + + } AF_ScalerRec, *AF_Scaler; + + +#define AF_SCALER_EQUAL_SCALES( a, b ) \ + ( (a)->x_scale == (b)->x_scale && \ + (a)->y_scale == (b)->y_scale && \ + (a)->x_delta == (b)->x_delta && \ + (a)->y_delta == (b)->y_delta ) + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** S C R I P T S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* + * The list of know scripts. Each different script corresponds to the + * following information: + * + * - A set of Unicode ranges to test whether the face supports the + * script. + * + * - A specific global analyzer that will compute global metrics + * specific to the script. + * + * - A specific glyph analyzer that will compute segments and + * edges for each glyph covered by the script. + * + * - A specific grid-fitting algorithm that will distort the + * scaled glyph outline according to the results of the glyph + * analyzer. + * + * Note that a given analyzer and/or grid-fitting algorithm can be + * used by more than one script. + */ + + typedef enum AF_Script_ + { + AF_SCRIPT_NONE = 0, + AF_SCRIPT_LATIN = 1, + AF_SCRIPT_CJK = 2, + AF_SCRIPT_INDIC = 3, +#ifdef FT_OPTION_AUTOFIT2 + AF_SCRIPT_LATIN2, +#endif + + /* add new scripts here. Don't forget to update the list in */ + /* `afglobal.c'. */ + + AF_SCRIPT_MAX /* do not remove */ + + } AF_Script; + + + typedef struct AF_ScriptClassRec_ const* AF_ScriptClass; + + typedef struct AF_ScriptMetricsRec_ + { + AF_ScriptClass clazz; + AF_ScalerRec scaler; + FT_Bool digits_have_same_width; + + } AF_ScriptMetricsRec, *AF_ScriptMetrics; + + + /* This function parses an FT_Face to compute global metrics for + * a specific script. + */ + typedef FT_Error + (*AF_Script_InitMetricsFunc)( AF_ScriptMetrics metrics, + FT_Face face ); + + typedef void + (*AF_Script_ScaleMetricsFunc)( AF_ScriptMetrics metrics, + AF_Scaler scaler ); + + typedef void + (*AF_Script_DoneMetricsFunc)( AF_ScriptMetrics metrics ); + + + typedef FT_Error + (*AF_Script_InitHintsFunc)( AF_GlyphHints hints, + AF_ScriptMetrics metrics ); + + typedef void + (*AF_Script_ApplyHintsFunc)( AF_GlyphHints hints, + FT_Outline* outline, + AF_ScriptMetrics metrics ); + + + typedef struct AF_Script_UniRangeRec_ + { + FT_UInt32 first; + FT_UInt32 last; + + } AF_Script_UniRangeRec; + +#define AF_UNIRANGE_REC( a, b ) { (FT_UInt32)(a), (FT_UInt32)(b) } + + typedef const AF_Script_UniRangeRec *AF_Script_UniRange; + + + typedef struct AF_ScriptClassRec_ + { + AF_Script script; + AF_Script_UniRange script_uni_ranges; /* last must be { 0, 0 } */ + + FT_Offset script_metrics_size; + AF_Script_InitMetricsFunc script_metrics_init; + AF_Script_ScaleMetricsFunc script_metrics_scale; + AF_Script_DoneMetricsFunc script_metrics_done; + + AF_Script_InitHintsFunc script_hints_init; + AF_Script_ApplyHintsFunc script_hints_apply; + + } AF_ScriptClassRec; + +/* Declare and define vtables for classes */ +#ifndef FT_CONFIG_OPTION_PIC + +#define AF_DECLARE_SCRIPT_CLASS(script_class) \ + FT_CALLBACK_TABLE const AF_ScriptClassRec \ + script_class; + +#define AF_DEFINE_SCRIPT_CLASS(script_class, script_, ranges, m_size, \ + m_init, m_scale, m_done, h_init, h_apply) \ + FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec \ + script_class = \ + { \ + script_, \ + ranges, \ + \ + m_size, \ + \ + m_init, \ + m_scale, \ + m_done, \ + \ + h_init, \ + h_apply \ + }; + +#else + +#define AF_DECLARE_SCRIPT_CLASS(script_class) \ + FT_LOCAL(void) \ + FT_Init_Class_##script_class(AF_ScriptClassRec* ac); + +#define AF_DEFINE_SCRIPT_CLASS(script_class, script_, ranges, m_size, \ + m_init, m_scale, m_done, h_init, h_apply) \ + FT_LOCAL_DEF(void) \ + FT_Init_Class_##script_class(AF_ScriptClassRec* ac) \ + { \ + ac->script = script_; \ + ac->script_uni_ranges = ranges; \ + \ + ac->script_metrics_size = m_size; \ + \ + ac->script_metrics_init = m_init; \ + ac->script_metrics_scale = m_scale; \ + ac->script_metrics_done = m_done; \ + \ + ac->script_hints_init = h_init; \ + ac->script_hints_apply = h_apply; \ + } +#endif + + +/* */ + +FT_END_HEADER + +#endif /* __AFTYPES_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/autofit/afwarp.c b/mod/pub.mod/freetype.mod/src/autofit/afwarp.c new file mode 100644 index 0000000..f5bb9b1 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/autofit/afwarp.c @@ -0,0 +1,338 @@ +/***************************************************************************/ +/* */ +/* afwarp.c */ +/* */ +/* Auto-fitter warping algorithm (body). */ +/* */ +/* Copyright 2006, 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include "afwarp.h" + +#ifdef AF_USE_WARPER + +#if 1 + static const AF_WarpScore + af_warper_weights[64] = + { + 35, 32, 30, 25, 20, 15, 12, 10, 5, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, -1, -2, -5, -8,-10,-10,-20,-20,-30,-30, + + -30,-30,-20,-20,-10,-10, -8, -5, -2, -1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 5, 10, 12, 15, 20, 25, 30, 32, + }; +#else + static const AF_WarpScore + af_warper_weights[64] = + { + 30, 20, 10, 5, 4, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -1, -2, -2, -5, -5,-10,-10,-15,-20, + + -20,-15,-15,-10,-10, -5, -5, -2, -2, -1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 4, 5, 10, 20, + }; +#endif + + + static void + af_warper_compute_line_best( AF_Warper warper, + FT_Fixed scale, + FT_Pos delta, + FT_Pos xx1, + FT_Pos xx2, + AF_WarpScore base_distort, + AF_Segment segments, + FT_UInt num_segments ) + { + FT_Int idx_min, idx_max, idx0; + FT_UInt nn; + AF_WarpScore scores[65]; + + + for ( nn = 0; nn < 65; nn++ ) + scores[nn] = 0; + + idx0 = xx1 - warper->t1; + + /* compute minimum and maximum indices */ + { + FT_Pos xx1min = warper->x1min; + FT_Pos xx1max = warper->x1max; + FT_Pos w = xx2 - xx1; + + + if ( xx1min + w < warper->x2min ) + xx1min = warper->x2min - w; + + xx1max = warper->x1max; + if ( xx1max + w > warper->x2max ) + xx1max = warper->x2max - w; + + idx_min = xx1min - warper->t1; + idx_max = xx1max - warper->t1; + + if ( idx_min < 0 || idx_min > idx_max || idx_max > 64 ) + { + AF_LOG(( "invalid indices:\n" + " min=%d max=%d, xx1=%ld xx2=%ld,\n" + " x1min=%ld x1max=%ld, x2min=%ld x2max=%ld\n", + idx_min, idx_max, xx1, xx2, + warper->x1min, warper->x1max, + warper->x2min, warper->x2max )); + return; + } + } + + for ( nn = 0; nn < num_segments; nn++ ) + { + FT_Pos len = segments[nn].max_coord - segments[nn].min_coord; + FT_Pos y0 = FT_MulFix( segments[nn].pos, scale ) + delta; + FT_Pos y = y0 + ( idx_min - idx0 ); + FT_Int idx; + + + for ( idx = idx_min; idx <= idx_max; idx++, y++ ) + scores[idx] += af_warper_weights[y & 63] * len; + } + + /* find best score */ + { + FT_Int idx; + + + for ( idx = idx_min; idx <= idx_max; idx++ ) + { + AF_WarpScore score = scores[idx]; + AF_WarpScore distort = base_distort + ( idx - idx0 ); + + + if ( score > warper->best_score || + ( score == warper->best_score && + distort < warper->best_distort ) ) + { + warper->best_score = score; + warper->best_distort = distort; + warper->best_scale = scale; + warper->best_delta = delta + ( idx - idx0 ); + } + } + } + } + + + FT_LOCAL_DEF( void ) + af_warper_compute( AF_Warper warper, + AF_GlyphHints hints, + AF_Dimension dim, + FT_Fixed *a_scale, + FT_Pos *a_delta ) + { + AF_AxisHints axis; + AF_Point points; + + FT_Fixed org_scale; + FT_Pos org_delta; + + FT_UInt nn, num_points, num_segments; + FT_Int X1, X2; + FT_Int w; + + AF_WarpScore base_distort; + AF_Segment segments; + + + /* get original scaling transformation */ + if ( dim == AF_DIMENSION_VERT ) + { + org_scale = hints->y_scale; + org_delta = hints->y_delta; + } + else + { + org_scale = hints->x_scale; + org_delta = hints->x_delta; + } + + warper->best_scale = org_scale; + warper->best_delta = org_delta; + warper->best_score = INT_MIN; + warper->best_distort = 0; + + axis = &hints->axis[dim]; + segments = axis->segments; + num_segments = axis->num_segments; + points = hints->points; + num_points = hints->num_points; + + *a_scale = org_scale; + *a_delta = org_delta; + + /* get X1 and X2, minimum and maximum in original coordinates */ + if ( num_segments < 1 ) + return; + +#if 1 + X1 = X2 = points[0].fx; + for ( nn = 1; nn < num_points; nn++ ) + { + FT_Int X = points[nn].fx; + + + if ( X < X1 ) + X1 = X; + if ( X > X2 ) + X2 = X; + } +#else + X1 = X2 = segments[0].pos; + for ( nn = 1; nn < num_segments; nn++ ) + { + FT_Int X = segments[nn].pos; + + + if ( X < X1 ) + X1 = X; + if ( X > X2 ) + X2 = X; + } +#endif + + if ( X1 >= X2 ) + return; + + warper->x1 = FT_MulFix( X1, org_scale ) + org_delta; + warper->x2 = FT_MulFix( X2, org_scale ) + org_delta; + + warper->t1 = AF_WARPER_FLOOR( warper->x1 ); + warper->t2 = AF_WARPER_CEIL( warper->x2 ); + + warper->x1min = warper->x1 & ~31; + warper->x1max = warper->x1min + 32; + warper->x2min = warper->x2 & ~31; + warper->x2max = warper->x2min + 32; + + if ( warper->x1max > warper->x2 ) + warper->x1max = warper->x2; + + if ( warper->x2min < warper->x1 ) + warper->x2min = warper->x1; + + warper->w0 = warper->x2 - warper->x1; + + if ( warper->w0 <= 64 ) + { + warper->x1max = warper->x1; + warper->x2min = warper->x2; + } + + warper->wmin = warper->x2min - warper->x1max; + warper->wmax = warper->x2max - warper->x1min; + +#if 1 + { + int margin = 16; + + + if ( warper->w0 <= 128 ) + { + margin = 8; + if ( warper->w0 <= 96 ) + margin = 4; + } + + if ( warper->wmin < warper->w0 - margin ) + warper->wmin = warper->w0 - margin; + + if ( warper->wmax > warper->w0 + margin ) + warper->wmax = warper->w0 + margin; + } + + if ( warper->wmin < warper->w0 * 3 / 4 ) + warper->wmin = warper->w0 * 3 / 4; + + if ( warper->wmax > warper->w0 * 5 / 4 ) + warper->wmax = warper->w0 * 5 / 4; +#else + /* no scaling, just translation */ + warper->wmin = warper->wmax = warper->w0; +#endif + + for ( w = warper->wmin; w <= warper->wmax; w++ ) + { + FT_Fixed new_scale; + FT_Pos new_delta; + FT_Pos xx1, xx2; + + + xx1 = warper->x1; + xx2 = warper->x2; + if ( w >= warper->w0 ) + { + xx1 -= w - warper->w0; + if ( xx1 < warper->x1min ) + { + xx2 += warper->x1min - xx1; + xx1 = warper->x1min; + } + } + else + { + xx1 -= w - warper->w0; + if ( xx1 > warper->x1max ) + { + xx2 -= xx1 - warper->x1max; + xx1 = warper->x1max; + } + } + + if ( xx1 < warper->x1 ) + base_distort = warper->x1 - xx1; + else + base_distort = xx1 - warper->x1; + + if ( xx2 < warper->x2 ) + base_distort += warper->x2 - xx2; + else + base_distort += xx2 - warper->x2; + + base_distort *= 10; + + new_scale = org_scale + FT_DivFix( w - warper->w0, X2 - X1 ); + new_delta = xx1 - FT_MulFix( X1, new_scale ); + + af_warper_compute_line_best( warper, new_scale, new_delta, xx1, xx2, + base_distort, + segments, num_segments ); + } + + { + FT_Fixed best_scale = warper->best_scale; + FT_Pos best_delta = warper->best_delta; + + + hints->xmin_delta = FT_MulFix( X1, best_scale - org_scale ) + + best_delta; + hints->xmax_delta = FT_MulFix( X2, best_scale - org_scale ) + + best_delta; + + *a_scale = best_scale; + *a_delta = best_delta; + } + } + +#else /* !AF_USE_WARPER */ + +char af_warper_dummy = 0; /* make compiler happy */ + +#endif /* !AF_USE_WARPER */ + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/autofit/afwarp.h b/mod/pub.mod/freetype.mod/src/autofit/afwarp.h new file mode 100644 index 0000000..7343fdd --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/autofit/afwarp.h @@ -0,0 +1,64 @@ +/***************************************************************************/ +/* */ +/* afwarp.h */ +/* */ +/* Auto-fitter warping algorithm (specification). */ +/* */ +/* Copyright 2006, 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __AFWARP_H__ +#define __AFWARP_H__ + +#include "afhints.h" + +FT_BEGIN_HEADER + +#define AF_WARPER_SCALE + +#define AF_WARPER_FLOOR( x ) ( (x) & ~63 ) +#define AF_WARPER_CEIL( x ) AF_WARPER_FLOOR( (x) + 63 ) + + + typedef FT_Int32 AF_WarpScore; + + typedef struct AF_WarperRec_ + { + FT_Pos x1, x2; + FT_Pos t1, t2; + FT_Pos x1min, x1max; + FT_Pos x2min, x2max; + FT_Pos w0, wmin, wmax; + + FT_Fixed best_scale; + FT_Pos best_delta; + AF_WarpScore best_score; + AF_WarpScore best_distort; + + } AF_WarperRec, *AF_Warper; + + + FT_LOCAL( void ) + af_warper_compute( AF_Warper warper, + AF_GlyphHints hints, + AF_Dimension dim, + FT_Fixed *a_scale, + FT_Fixed *a_delta ); + + +FT_END_HEADER + + +#endif /* __AFWARP_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/autofit/autofit.c b/mod/pub.mod/freetype.mod/src/autofit/autofit.c new file mode 100644 index 0000000..83b613e --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/autofit/autofit.c @@ -0,0 +1,41 @@ +/***************************************************************************/ +/* */ +/* autofit.c */ +/* */ +/* Auto-fitter module (body). */ +/* */ +/* Copyright 2003, 2004, 2005, 2006, 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#define FT_MAKE_OPTION_SINGLE_OBJECT +#include <ft2build.h> +#include "afpic.c" +#include "afangles.c" +#include "afglobal.c" +#include "afhints.c" + +#include "afdummy.c" +#include "aflatin.c" +#ifdef FT_OPTION_AUTOFIT2 +#include "aflatin2.c" +#endif +#include "afcjk.c" +#include "afindic.c" + +#include "afloader.c" +#include "afmodule.c" + +#ifdef AF_USE_WARPER +#include "afwarp.c" +#endif + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/base/basepic.c b/mod/pub.mod/freetype.mod/src/base/basepic.c new file mode 100644 index 0000000..c0bccb6 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/base/basepic.c @@ -0,0 +1,83 @@ +/***************************************************************************/ +/* */ +/* basepic.c */ +/* */ +/* The FreeType position independent code services for base. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include "basepic.h" + +#ifdef FT_CONFIG_OPTION_PIC + + /* forward declaration of PIC init functions from ftglyph.c */ + void FT_Init_Class_ft_outline_glyph_class(FT_Glyph_Class*); + void FT_Init_Class_ft_bitmap_glyph_class(FT_Glyph_Class*); + + /* forward declaration of PIC init functions from ftinit.c */ + FT_Error ft_create_default_module_classes(FT_Library); + void ft_destroy_default_module_classes(FT_Library); + + void + ft_base_pic_free( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Memory memory = library->memory; + if ( pic_container->base ) + { + /* Destroy default module classes (in case FT_Add_Default_Modules was used) */ + ft_destroy_default_module_classes( library ); + + FT_FREE( pic_container->base ); + pic_container->base = NULL; + } + } + + + FT_Error + ft_base_pic_init( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Error error = FT_Err_Ok; + BasePIC* container; + FT_Memory memory = library->memory; + + /* allocate pointer, clear and set global container pointer */ + if ( FT_ALLOC ( container, sizeof ( *container ) ) ) + return error; + FT_MEM_SET( container, 0, sizeof(*container) ); + pic_container->base = container; + + /* initialize default modules list and pointers */ + error = ft_create_default_module_classes( library ); + if ( error ) + goto Exit; + + /* initialize pointer table - this is how the module usually expects this data */ + FT_Init_Class_ft_outline_glyph_class(&container->ft_outline_glyph_class); + FT_Init_Class_ft_bitmap_glyph_class(&container->ft_bitmap_glyph_class); + +Exit: + if(error) + ft_base_pic_free(library); + return error; + } + + +#endif /* FT_CONFIG_OPTION_PIC */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/base/basepic.h b/mod/pub.mod/freetype.mod/src/base/basepic.h new file mode 100644 index 0000000..bb17745 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/base/basepic.h @@ -0,0 +1,62 @@ +/***************************************************************************/ +/* */ +/* basepic.h */ +/* */ +/* The FreeType position independent code services for base. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __BASEPIC_H__ +#define __BASEPIC_H__ + + +FT_BEGIN_HEADER + +#include FT_INTERNAL_PIC_H + +#ifndef FT_CONFIG_OPTION_PIC +#define FT_OUTLINE_GLYPH_CLASS_GET &ft_outline_glyph_class +#define FT_BITMAP_GLYPH_CLASS_GET &ft_bitmap_glyph_class +#define FT_DEFAULT_MODULES_GET ft_default_modules + +#else /* FT_CONFIG_OPTION_PIC */ + +#include FT_GLYPH_H + + typedef struct BasePIC_ + { + FT_Module_Class** default_module_classes; + FT_Glyph_Class ft_outline_glyph_class; + FT_Glyph_Class ft_bitmap_glyph_class; + } BasePIC; + +#define GET_PIC(lib) ((BasePIC*)((lib)->pic_container.base)) +#define FT_OUTLINE_GLYPH_CLASS_GET (&GET_PIC(library)->ft_outline_glyph_class) +#define FT_BITMAP_GLYPH_CLASS_GET (&GET_PIC(library)->ft_bitmap_glyph_class) +#define FT_DEFAULT_MODULES_GET (GET_PIC(library)->default_module_classes) + + void + ft_base_pic_free( FT_Library library ); + + FT_Error + ft_base_pic_init( FT_Library library ); + +#endif /* FT_CONFIG_OPTION_PIC */ + /* */ + +FT_END_HEADER + +#endif /* __BASEPIC_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/base/ftadvanc.c b/mod/pub.mod/freetype.mod/src/base/ftadvanc.c new file mode 100644 index 0000000..8ab7fcb --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/base/ftadvanc.c @@ -0,0 +1,163 @@ +/***************************************************************************/ +/* */ +/* ftadvanc.c */ +/* */ +/* Quick computation of advance widths (body). */ +/* */ +/* Copyright 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_ADVANCES_H +#include FT_INTERNAL_OBJECTS_H + + + static FT_Error + _ft_face_scale_advances( FT_Face face, + FT_Fixed* advances, + FT_UInt count, + FT_Int32 flags ) + { + FT_Fixed scale; + FT_UInt nn; + + + if ( flags & FT_LOAD_NO_SCALE ) + return FT_Err_Ok; + + if ( face->size == NULL ) + return FT_Err_Invalid_Size_Handle; + + if ( flags & FT_LOAD_VERTICAL_LAYOUT ) + scale = face->size->metrics.y_scale; + else + scale = face->size->metrics.x_scale; + + /* this must be the same scaling as to get linear{Hori,Vert}Advance */ + /* (see `FT_Load_Glyph' implementation in src/base/ftobjs.c) */ + + for ( nn = 0; nn < count; nn++ ) + advances[nn] = FT_MulDiv( advances[nn], scale, 64 ); + + return FT_Err_Ok; + } + + + /* at the moment, we can perform fast advance retrieval only in */ + /* the following cases: */ + /* */ + /* - unscaled load */ + /* - unhinted load */ + /* - light-hinted load */ + +#define LOAD_ADVANCE_FAST_CHECK( flags ) \ + ( flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING ) || \ + FT_LOAD_TARGET_MODE( flags ) == FT_RENDER_MODE_LIGHT ) + + + /* documentation is in ftadvanc.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_Advance( FT_Face face, + FT_UInt gindex, + FT_Int32 flags, + FT_Fixed *padvance ) + { + FT_Face_GetAdvancesFunc func; + + + if ( !face ) + return FT_Err_Invalid_Face_Handle; + + if ( gindex >= (FT_UInt)face->num_glyphs ) + return FT_Err_Invalid_Glyph_Index; + + func = face->driver->clazz->get_advances; + if ( func && LOAD_ADVANCE_FAST_CHECK( flags ) ) + { + FT_Error error; + + + error = func( face, gindex, 1, flags, padvance ); + if ( !error ) + return _ft_face_scale_advances( face, padvance, 1, flags ); + + if ( error != FT_ERROR_BASE( FT_Err_Unimplemented_Feature ) ) + return error; + } + + return FT_Get_Advances( face, gindex, 1, flags, padvance ); + } + + + /* documentation is in ftadvanc.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_Advances( FT_Face face, + FT_UInt start, + FT_UInt count, + FT_Int32 flags, + FT_Fixed *padvances ) + { + FT_Face_GetAdvancesFunc func; + FT_UInt num, end, nn; + FT_Error error = FT_Err_Ok; + + + if ( !face ) + return FT_Err_Invalid_Face_Handle; + + num = (FT_UInt)face->num_glyphs; + end = start + count; + if ( start >= num || end < start || end > num ) + return FT_Err_Invalid_Glyph_Index; + + if ( count == 0 ) + return FT_Err_Ok; + + func = face->driver->clazz->get_advances; + if ( func && LOAD_ADVANCE_FAST_CHECK( flags ) ) + { + error = func( face, start, count, flags, padvances ); + if ( !error ) + goto Exit; + + if ( error != FT_ERROR_BASE( FT_Err_Unimplemented_Feature ) ) + return error; + } + + error = FT_Err_Ok; + + if ( flags & FT_ADVANCE_FLAG_FAST_ONLY ) + return FT_Err_Unimplemented_Feature; + + flags |= (FT_UInt32)FT_LOAD_ADVANCE_ONLY; + for ( nn = 0; nn < count; nn++ ) + { + error = FT_Load_Glyph( face, start + nn, flags ); + if ( error ) + break; + + padvances[nn] = ( flags & FT_LOAD_VERTICAL_LAYOUT ) + ? face->glyph->advance.y + : face->glyph->advance.x; + } + + if ( error ) + return error; + + Exit: + return _ft_face_scale_advances( face, padvances, count, flags ); + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/base/ftapi.c b/mod/pub.mod/freetype.mod/src/base/ftapi.c new file mode 100644 index 0000000..8914d1f --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/base/ftapi.c @@ -0,0 +1,121 @@ +/***************************************************************************/ +/* */ +/* ftapi.c */ +/* */ +/* The FreeType compatibility functions (body). */ +/* */ +/* Copyright 2002 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_LIST_H +#include FT_OUTLINE_H +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_TRUETYPE_TABLES_H +#include FT_OUTLINE_H + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** C O M P A T I B I L I T Y ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + /* backwards compatibility API */ + + FT_BASE_DEF( void ) + FT_New_Memory_Stream( FT_Library library, + FT_Byte* base, + FT_ULong size, + FT_Stream stream ) + { + FT_UNUSED( library ); + + FT_Stream_OpenMemory( stream, base, size ); + } + + + FT_BASE_DEF( FT_Error ) + FT_Seek_Stream( FT_Stream stream, + FT_ULong pos ) + { + return FT_Stream_Seek( stream, pos ); + } + + + FT_BASE_DEF( FT_Error ) + FT_Skip_Stream( FT_Stream stream, + FT_Long distance ) + { + return FT_Stream_Skip( stream, distance ); + } + + + FT_BASE_DEF( FT_Error ) + FT_Read_Stream( FT_Stream stream, + FT_Byte* buffer, + FT_ULong count ) + { + return FT_Stream_Read( stream, buffer, count ); + } + + + FT_BASE_DEF( FT_Error ) + FT_Read_Stream_At( FT_Stream stream, + FT_ULong pos, + FT_Byte* buffer, + FT_ULong count ) + { + return FT_Stream_ReadAt( stream, pos, buffer, count ); + } + + + FT_BASE_DEF( FT_Error ) + FT_Extract_Frame( FT_Stream stream, + FT_ULong count, + FT_Byte** pbytes ) + { + return FT_Stream_ExtractFrame( stream, count, pbytes ); + } + + + FT_BASE_DEF( void ) + FT_Release_Frame( FT_Stream stream, + FT_Byte** pbytes ) + { + FT_Stream_ReleaseFrame( stream, pbytes ); + } + + FT_BASE_DEF( FT_Error ) + FT_Access_Frame( FT_Stream stream, + FT_ULong count ) + { + return FT_Stream_EnterFrame( stream, count ); + } + + + FT_BASE_DEF( void ) + FT_Forget_Frame( FT_Stream stream ) + { + FT_Stream_ExitFrame( stream ); + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/base/ftbase.c b/mod/pub.mod/freetype.mod/src/base/ftbase.c new file mode 100644 index 0000000..6a27ea9 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/base/ftbase.c @@ -0,0 +1,41 @@ +/***************************************************************************/ +/* */ +/* ftbase.c */ +/* */ +/* Single object library component (body only). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> + +#define FT_MAKE_OPTION_SINGLE_OBJECT + +#include "ftpic.c" +#include "basepic.c" +#include "ftadvanc.c" +#include "ftcalc.c" +#include "ftdbgmem.c" +#include "ftgloadr.c" +#include "ftobjs.c" +#include "ftoutln.c" +#include "ftrfork.c" +#include "ftsnames.c" +#include "ftstream.c" +#include "fttrigon.c" +#include "ftutil.c" + +#if defined( FT_MACINTOSH ) && !defined ( DARWIN_NO_CARBON ) +#include "ftmac.c" +#endif + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/base/ftbase.h b/mod/pub.mod/freetype.mod/src/base/ftbase.h new file mode 100644 index 0000000..9cae85d --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/base/ftbase.h @@ -0,0 +1,57 @@ +/***************************************************************************/ +/* */ +/* ftbase.h */ +/* */ +/* The FreeType private functions used in base module (specification). */ +/* */ +/* Copyright 2008 by */ +/* David Turner, Robert Wilhelm, Werner Lemberg, and suzuki toshiya. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTBASE_H__ +#define __FTBASE_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H + + +FT_BEGIN_HEADER + + + /* Assume the stream is sfnt-wrapped PS Type1 or sfnt-wrapped CID-keyed */ + /* font, and try to load a face specified by the face_index. */ + FT_LOCAL_DEF( FT_Error ) + open_face_PS_from_sfnt_stream( FT_Library library, + FT_Stream stream, + FT_Long face_index, + FT_Int num_params, + FT_Parameter *params, + FT_Face *aface ); + + + /* Create a new FT_Face given a buffer and a driver name. */ + /* From ftmac.c. */ + FT_LOCAL_DEF( FT_Error ) + open_face_from_buffer( FT_Library library, + FT_Byte* base, + FT_ULong size, + FT_Long face_index, + const char* driver_name, + FT_Face *aface ); + + +FT_END_HEADER + +#endif /* __FTBASE_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/base/ftbbox.c b/mod/pub.mod/freetype.mod/src/base/ftbbox.c new file mode 100644 index 0000000..8136ccc --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/base/ftbbox.c @@ -0,0 +1,662 @@ +/***************************************************************************/ +/* */ +/* ftbbox.c */ +/* */ +/* FreeType bbox computation (body). */ +/* */ +/* Copyright 1996-2001, 2002, 2004, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used */ +/* modified and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This component has a _single_ role: to compute exact outline bounding */ + /* boxes. */ + /* */ + /*************************************************************************/ + + +#include <ft2build.h> +#include FT_BBOX_H +#include FT_IMAGE_H +#include FT_OUTLINE_H +#include FT_INTERNAL_CALC_H +#include FT_INTERNAL_OBJECTS_H + + + typedef struct TBBox_Rec_ + { + FT_Vector last; + FT_BBox bbox; + + } TBBox_Rec; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* BBox_Move_To */ + /* */ + /* <Description> */ + /* This function is used as a `move_to' and `line_to' emitter during */ + /* FT_Outline_Decompose(). It simply records the destination point */ + /* in `user->last'; no further computations are necessary since we */ + /* use the cbox as the starting bbox which must be refined. */ + /* */ + /* <Input> */ + /* to :: A pointer to the destination vector. */ + /* */ + /* <InOut> */ + /* user :: A pointer to the current walk context. */ + /* */ + /* <Return> */ + /* Always 0. Needed for the interface only. */ + /* */ + static int + BBox_Move_To( FT_Vector* to, + TBBox_Rec* user ) + { + user->last = *to; + + return 0; + } + + +#define CHECK_X( p, bbox ) \ + ( p->x < bbox.xMin || p->x > bbox.xMax ) + +#define CHECK_Y( p, bbox ) \ + ( p->y < bbox.yMin || p->y > bbox.yMax ) + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* BBox_Conic_Check */ + /* */ + /* <Description> */ + /* Finds the extrema of a 1-dimensional conic Bezier curve and update */ + /* a bounding range. This version uses direct computation, as it */ + /* doesn't need square roots. */ + /* */ + /* <Input> */ + /* y1 :: The start coordinate. */ + /* */ + /* y2 :: The coordinate of the control point. */ + /* */ + /* y3 :: The end coordinate. */ + /* */ + /* <InOut> */ + /* min :: The address of the current minimum. */ + /* */ + /* max :: The address of the current maximum. */ + /* */ + static void + BBox_Conic_Check( FT_Pos y1, + FT_Pos y2, + FT_Pos y3, + FT_Pos* min, + FT_Pos* max ) + { + if ( y1 <= y3 && y2 == y1 ) /* flat arc */ + goto Suite; + + if ( y1 < y3 ) + { + if ( y2 >= y1 && y2 <= y3 ) /* ascending arc */ + goto Suite; + } + else + { + if ( y2 >= y3 && y2 <= y1 ) /* descending arc */ + { + y2 = y1; + y1 = y3; + y3 = y2; + goto Suite; + } + } + + y1 = y3 = y1 - FT_MulDiv( y2 - y1, y2 - y1, y1 - 2*y2 + y3 ); + + Suite: + if ( y1 < *min ) *min = y1; + if ( y3 > *max ) *max = y3; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* BBox_Conic_To */ + /* */ + /* <Description> */ + /* This function is used as a `conic_to' emitter during */ + /* FT_Raster_Decompose(). It checks a conic Bezier curve with the */ + /* current bounding box, and computes its extrema if necessary to */ + /* update it. */ + /* */ + /* <Input> */ + /* control :: A pointer to a control point. */ + /* */ + /* to :: A pointer to the destination vector. */ + /* */ + /* <InOut> */ + /* user :: The address of the current walk context. */ + /* */ + /* <Return> */ + /* Always 0. Needed for the interface only. */ + /* */ + /* <Note> */ + /* In the case of a non-monotonous arc, we compute directly the */ + /* extremum coordinates, as it is sufficiently fast. */ + /* */ + static int + BBox_Conic_To( FT_Vector* control, + FT_Vector* to, + TBBox_Rec* user ) + { + /* we don't need to check `to' since it is always an `on' point, thus */ + /* within the bbox */ + + if ( CHECK_X( control, user->bbox ) ) + BBox_Conic_Check( user->last.x, + control->x, + to->x, + &user->bbox.xMin, + &user->bbox.xMax ); + + if ( CHECK_Y( control, user->bbox ) ) + BBox_Conic_Check( user->last.y, + control->y, + to->y, + &user->bbox.yMin, + &user->bbox.yMax ); + + user->last = *to; + + return 0; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* BBox_Cubic_Check */ + /* */ + /* <Description> */ + /* Finds the extrema of a 1-dimensional cubic Bezier curve and */ + /* updates a bounding range. This version uses splitting because we */ + /* don't want to use square roots and extra accuracy. */ + /* */ + /* <Input> */ + /* p1 :: The start coordinate. */ + /* */ + /* p2 :: The coordinate of the first control point. */ + /* */ + /* p3 :: The coordinate of the second control point. */ + /* */ + /* p4 :: The end coordinate. */ + /* */ + /* <InOut> */ + /* min :: The address of the current minimum. */ + /* */ + /* max :: The address of the current maximum. */ + /* */ + +#if 0 + + static void + BBox_Cubic_Check( FT_Pos p1, + FT_Pos p2, + FT_Pos p3, + FT_Pos p4, + FT_Pos* min, + FT_Pos* max ) + { + FT_Pos stack[32*3 + 1], *arc; + + + arc = stack; + + arc[0] = p1; + arc[1] = p2; + arc[2] = p3; + arc[3] = p4; + + do + { + FT_Pos y1 = arc[0]; + FT_Pos y2 = arc[1]; + FT_Pos y3 = arc[2]; + FT_Pos y4 = arc[3]; + + + if ( y1 == y4 ) + { + if ( y1 == y2 && y1 == y3 ) /* flat */ + goto Test; + } + else if ( y1 < y4 ) + { + if ( y2 >= y1 && y2 <= y4 && y3 >= y1 && y3 <= y4 ) /* ascending */ + goto Test; + } + else + { + if ( y2 >= y4 && y2 <= y1 && y3 >= y4 && y3 <= y1 ) /* descending */ + { + y2 = y1; + y1 = y4; + y4 = y2; + goto Test; + } + } + + /* unknown direction -- split the arc in two */ + arc[6] = y4; + arc[1] = y1 = ( y1 + y2 ) / 2; + arc[5] = y4 = ( y4 + y3 ) / 2; + y2 = ( y2 + y3 ) / 2; + arc[2] = y1 = ( y1 + y2 ) / 2; + arc[4] = y4 = ( y4 + y2 ) / 2; + arc[3] = ( y1 + y4 ) / 2; + + arc += 3; + goto Suite; + + Test: + if ( y1 < *min ) *min = y1; + if ( y4 > *max ) *max = y4; + arc -= 3; + + Suite: + ; + } while ( arc >= stack ); + } + +#else + + static void + test_cubic_extrema( FT_Pos y1, + FT_Pos y2, + FT_Pos y3, + FT_Pos y4, + FT_Fixed u, + FT_Pos* min, + FT_Pos* max ) + { + /* FT_Pos a = y4 - 3*y3 + 3*y2 - y1; */ + FT_Pos b = y3 - 2*y2 + y1; + FT_Pos c = y2 - y1; + FT_Pos d = y1; + FT_Pos y; + FT_Fixed uu; + + FT_UNUSED ( y4 ); + + + /* The polynomial is */ + /* */ + /* P(x) = a*x^3 + 3b*x^2 + 3c*x + d , */ + /* */ + /* dP/dx = 3a*x^2 + 6b*x + 3c . */ + /* */ + /* However, we also have */ + /* */ + /* dP/dx(u) = 0 , */ + /* */ + /* which implies by subtraction that */ + /* */ + /* P(u) = b*u^2 + 2c*u + d . */ + + if ( u > 0 && u < 0x10000L ) + { + uu = FT_MulFix( u, u ); + y = d + FT_MulFix( c, 2*u ) + FT_MulFix( b, uu ); + + if ( y < *min ) *min = y; + if ( y > *max ) *max = y; + } + } + + + static void + BBox_Cubic_Check( FT_Pos y1, + FT_Pos y2, + FT_Pos y3, + FT_Pos y4, + FT_Pos* min, + FT_Pos* max ) + { + /* always compare first and last points */ + if ( y1 < *min ) *min = y1; + else if ( y1 > *max ) *max = y1; + + if ( y4 < *min ) *min = y4; + else if ( y4 > *max ) *max = y4; + + /* now, try to see if there are split points here */ + if ( y1 <= y4 ) + { + /* flat or ascending arc test */ + if ( y1 <= y2 && y2 <= y4 && y1 <= y3 && y3 <= y4 ) + return; + } + else /* y1 > y4 */ + { + /* descending arc test */ + if ( y1 >= y2 && y2 >= y4 && y1 >= y3 && y3 >= y4 ) + return; + } + + /* There are some split points. Find them. */ + { + FT_Pos a = y4 - 3*y3 + 3*y2 - y1; + FT_Pos b = y3 - 2*y2 + y1; + FT_Pos c = y2 - y1; + FT_Pos d; + FT_Fixed t; + + + /* We need to solve `ax^2+2bx+c' here, without floating points! */ + /* The trick is to normalize to a different representation in order */ + /* to use our 16.16 fixed point routines. */ + /* */ + /* We compute FT_MulFix(b,b) and FT_MulFix(a,c) after normalization. */ + /* These values must fit into a single 16.16 value. */ + /* */ + /* We normalize a, b, and c to `8.16' fixed float values to ensure */ + /* that its product is held in a `16.16' value. */ + + { + FT_ULong t1, t2; + int shift = 0; + + + /* The following computation is based on the fact that for */ + /* any value `y', if `n' is the position of the most */ + /* significant bit of `abs(y)' (starting from 0 for the */ + /* least significant bit), then `y' is in the range */ + /* */ + /* -2^n..2^n-1 */ + /* */ + /* We want to shift `a', `b', and `c' concurrently in order */ + /* to ensure that they all fit in 8.16 values, which maps */ + /* to the integer range `-2^23..2^23-1'. */ + /* */ + /* Necessarily, we need to shift `a', `b', and `c' so that */ + /* the most significant bit of its absolute values is at */ + /* _most_ at position 23. */ + /* */ + /* We begin by computing `t1' as the bitwise `OR' of the */ + /* absolute values of `a', `b', `c'. */ + + t1 = (FT_ULong)( ( a >= 0 ) ? a : -a ); + t2 = (FT_ULong)( ( b >= 0 ) ? b : -b ); + t1 |= t2; + t2 = (FT_ULong)( ( c >= 0 ) ? c : -c ); + t1 |= t2; + + /* Now we can be sure that the most significant bit of `t1' */ + /* is the most significant bit of either `a', `b', or `c', */ + /* depending on the greatest integer range of the particular */ + /* variable. */ + /* */ + /* Next, we compute the `shift', by shifting `t1' as many */ + /* times as necessary to move its MSB to position 23. This */ + /* corresponds to a value of `t1' that is in the range */ + /* 0x40_0000..0x7F_FFFF. */ + /* */ + /* Finally, we shift `a', `b', and `c' by the same amount. */ + /* This ensures that all values are now in the range */ + /* -2^23..2^23, i.e., they are now expressed as 8.16 */ + /* fixed-float numbers. This also means that we are using */ + /* 24 bits of precision to compute the zeros, independently */ + /* of the range of the original polynomial coefficients. */ + /* */ + /* This algorithm should ensure reasonably accurate values */ + /* for the zeros. Note that they are only expressed with */ + /* 16 bits when computing the extrema (the zeros need to */ + /* be in 0..1 exclusive to be considered part of the arc). */ + + if ( t1 == 0 ) /* all coefficients are 0! */ + return; + + if ( t1 > 0x7FFFFFUL ) + { + do + { + shift++; + t1 >>= 1; + + } while ( t1 > 0x7FFFFFUL ); + + /* this loses some bits of precision, but we use 24 of them */ + /* for the computation anyway */ + a >>= shift; + b >>= shift; + c >>= shift; + } + else if ( t1 < 0x400000UL ) + { + do + { + shift++; + t1 <<= 1; + + } while ( t1 < 0x400000UL ); + + a <<= shift; + b <<= shift; + c <<= shift; + } + } + + /* handle a == 0 */ + if ( a == 0 ) + { + if ( b != 0 ) + { + t = - FT_DivFix( c, b ) / 2; + test_cubic_extrema( y1, y2, y3, y4, t, min, max ); + } + } + else + { + /* solve the equation now */ + d = FT_MulFix( b, b ) - FT_MulFix( a, c ); + if ( d < 0 ) + return; + + if ( d == 0 ) + { + /* there is a single split point at -b/a */ + t = - FT_DivFix( b, a ); + test_cubic_extrema( y1, y2, y3, y4, t, min, max ); + } + else + { + /* there are two solutions; we need to filter them */ + d = FT_SqrtFixed( (FT_Int32)d ); + t = - FT_DivFix( b - d, a ); + test_cubic_extrema( y1, y2, y3, y4, t, min, max ); + + t = - FT_DivFix( b + d, a ); + test_cubic_extrema( y1, y2, y3, y4, t, min, max ); + } + } + } + } + +#endif + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* BBox_Cubic_To */ + /* */ + /* <Description> */ + /* This function is used as a `cubic_to' emitter during */ + /* FT_Raster_Decompose(). It checks a cubic Bezier curve with the */ + /* current bounding box, and computes its extrema if necessary to */ + /* update it. */ + /* */ + /* <Input> */ + /* control1 :: A pointer to the first control point. */ + /* */ + /* control2 :: A pointer to the second control point. */ + /* */ + /* to :: A pointer to the destination vector. */ + /* */ + /* <InOut> */ + /* user :: The address of the current walk context. */ + /* */ + /* <Return> */ + /* Always 0. Needed for the interface only. */ + /* */ + /* <Note> */ + /* In the case of a non-monotonous arc, we don't compute directly */ + /* extremum coordinates, we subdivide instead. */ + /* */ + static int + BBox_Cubic_To( FT_Vector* control1, + FT_Vector* control2, + FT_Vector* to, + TBBox_Rec* user ) + { + /* we don't need to check `to' since it is always an `on' point, thus */ + /* within the bbox */ + + if ( CHECK_X( control1, user->bbox ) || + CHECK_X( control2, user->bbox ) ) + BBox_Cubic_Check( user->last.x, + control1->x, + control2->x, + to->x, + &user->bbox.xMin, + &user->bbox.xMax ); + + if ( CHECK_Y( control1, user->bbox ) || + CHECK_Y( control2, user->bbox ) ) + BBox_Cubic_Check( user->last.y, + control1->y, + control2->y, + to->y, + &user->bbox.yMin, + &user->bbox.yMax ); + + user->last = *to; + + return 0; + } + +FT_DEFINE_OUTLINE_FUNCS(bbox_interface, + (FT_Outline_MoveTo_Func) BBox_Move_To, + (FT_Outline_LineTo_Func) BBox_Move_To, + (FT_Outline_ConicTo_Func)BBox_Conic_To, + (FT_Outline_CubicTo_Func)BBox_Cubic_To, + 0, 0 + ) + + /* documentation is in ftbbox.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Outline_Get_BBox( FT_Outline* outline, + FT_BBox *abbox ) + { + FT_BBox cbox; + FT_BBox bbox; + FT_Vector* vec; + FT_UShort n; + + + if ( !abbox ) + return FT_Err_Invalid_Argument; + + if ( !outline ) + return FT_Err_Invalid_Outline; + + /* if outline is empty, return (0,0,0,0) */ + if ( outline->n_points == 0 || outline->n_contours <= 0 ) + { + abbox->xMin = abbox->xMax = 0; + abbox->yMin = abbox->yMax = 0; + return 0; + } + + /* We compute the control box as well as the bounding box of */ + /* all `on' points in the outline. Then, if the two boxes */ + /* coincide, we exit immediately. */ + + vec = outline->points; + bbox.xMin = bbox.xMax = cbox.xMin = cbox.xMax = vec->x; + bbox.yMin = bbox.yMax = cbox.yMin = cbox.yMax = vec->y; + vec++; + + for ( n = 1; n < outline->n_points; n++ ) + { + FT_Pos x = vec->x; + FT_Pos y = vec->y; + + + /* update control box */ + if ( x < cbox.xMin ) cbox.xMin = x; + if ( x > cbox.xMax ) cbox.xMax = x; + + if ( y < cbox.yMin ) cbox.yMin = y; + if ( y > cbox.yMax ) cbox.yMax = y; + + if ( FT_CURVE_TAG( outline->tags[n] ) == FT_CURVE_TAG_ON ) + { + /* update bbox for `on' points only */ + if ( x < bbox.xMin ) bbox.xMin = x; + if ( x > bbox.xMax ) bbox.xMax = x; + + if ( y < bbox.yMin ) bbox.yMin = y; + if ( y > bbox.yMax ) bbox.yMax = y; + } + + vec++; + } + + /* test two boxes for equality */ + if ( cbox.xMin < bbox.xMin || cbox.xMax > bbox.xMax || + cbox.yMin < bbox.yMin || cbox.yMax > bbox.yMax ) + { + /* the two boxes are different, now walk over the outline to */ + /* get the Bezier arc extrema. */ + + FT_Error error; + TBBox_Rec user; + +#ifdef FT_CONFIG_OPTION_PIC + FT_Outline_Funcs bbox_interface; + Init_Class_bbox_interface(&bbox_interface); +#endif + + user.bbox = bbox; + + error = FT_Outline_Decompose( outline, &bbox_interface, &user ); + if ( error ) + return error; + + *abbox = user.bbox; + } + else + *abbox = bbox; + + return FT_Err_Ok; + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/base/ftbdf.c b/mod/pub.mod/freetype.mod/src/base/ftbdf.c new file mode 100644 index 0000000..d29adf0 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/base/ftbdf.c @@ -0,0 +1,88 @@ +/***************************************************************************/ +/* */ +/* ftbdf.c */ +/* */ +/* FreeType API for accessing BDF-specific strings (body). */ +/* */ +/* Copyright 2002, 2003, 2004 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H +#include FT_SERVICE_BDF_H + + + /* documentation is in ftbdf.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_BDF_Charset_ID( FT_Face face, + const char* *acharset_encoding, + const char* *acharset_registry ) + { + FT_Error error; + const char* encoding = NULL; + const char* registry = NULL; + + + error = FT_Err_Invalid_Argument; + + if ( face ) + { + FT_Service_BDF service; + + + FT_FACE_FIND_SERVICE( face, service, BDF ); + + if ( service && service->get_charset_id ) + error = service->get_charset_id( face, &encoding, ®istry ); + } + + if ( acharset_encoding ) + *acharset_encoding = encoding; + + if ( acharset_registry ) + *acharset_registry = registry; + + return error; + } + + + /* documentation is in ftbdf.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_BDF_Property( FT_Face face, + const char* prop_name, + BDF_PropertyRec *aproperty ) + { + FT_Error error; + + + error = FT_Err_Invalid_Argument; + + aproperty->type = BDF_PROPERTY_TYPE_NONE; + + if ( face ) + { + FT_Service_BDF service; + + + FT_FACE_FIND_SERVICE( face, service, BDF ); + + if ( service && service->get_property ) + error = service->get_property( face, prop_name, aproperty ); + } + + return error; + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/base/ftbitmap.c b/mod/pub.mod/freetype.mod/src/base/ftbitmap.c new file mode 100644 index 0000000..46fcce6 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/base/ftbitmap.c @@ -0,0 +1,663 @@ +/***************************************************************************/ +/* */ +/* ftbitmap.c */ +/* */ +/* FreeType utility functions for bitmaps (body). */ +/* */ +/* Copyright 2004, 2005, 2006, 2007, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_BITMAP_H +#include FT_IMAGE_H +#include FT_INTERNAL_OBJECTS_H + + + static + const FT_Bitmap null_bitmap = { 0, 0, 0, 0, 0, 0, 0, 0 }; + + + /* documentation is in ftbitmap.h */ + + FT_EXPORT_DEF( void ) + FT_Bitmap_New( FT_Bitmap *abitmap ) + { + *abitmap = null_bitmap; + } + + + /* documentation is in ftbitmap.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Bitmap_Copy( FT_Library library, + const FT_Bitmap *source, + FT_Bitmap *target) + { + FT_Memory memory = library->memory; + FT_Error error = FT_Err_Ok; + FT_Int pitch = source->pitch; + FT_ULong size; + + + if ( source == target ) + return FT_Err_Ok; + + if ( source->buffer == NULL ) + { + *target = *source; + + return FT_Err_Ok; + } + + if ( pitch < 0 ) + pitch = -pitch; + size = (FT_ULong)( pitch * source->rows ); + + if ( target->buffer ) + { + FT_Int target_pitch = target->pitch; + FT_ULong target_size; + + + if ( target_pitch < 0 ) + target_pitch = -target_pitch; + target_size = (FT_ULong)( target_pitch * target->rows ); + + if ( target_size != size ) + (void)FT_QREALLOC( target->buffer, target_size, size ); + } + else + (void)FT_QALLOC( target->buffer, size ); + + if ( !error ) + { + unsigned char *p; + + + p = target->buffer; + *target = *source; + target->buffer = p; + + FT_MEM_COPY( target->buffer, source->buffer, size ); + } + + return error; + } + + + static FT_Error + ft_bitmap_assure_buffer( FT_Memory memory, + FT_Bitmap* bitmap, + FT_UInt xpixels, + FT_UInt ypixels ) + { + FT_Error error; + int pitch; + int new_pitch; + FT_UInt bpp; + FT_Int i, width, height; + unsigned char* buffer; + + + width = bitmap->width; + height = bitmap->rows; + pitch = bitmap->pitch; + if ( pitch < 0 ) + pitch = -pitch; + + switch ( bitmap->pixel_mode ) + { + case FT_PIXEL_MODE_MONO: + bpp = 1; + new_pitch = ( width + xpixels + 7 ) >> 3; + break; + case FT_PIXEL_MODE_GRAY2: + bpp = 2; + new_pitch = ( width + xpixels + 3 ) >> 2; + break; + case FT_PIXEL_MODE_GRAY4: + bpp = 4; + new_pitch = ( width + xpixels + 1 ) >> 1; + break; + case FT_PIXEL_MODE_GRAY: + case FT_PIXEL_MODE_LCD: + case FT_PIXEL_MODE_LCD_V: + bpp = 8; + new_pitch = ( width + xpixels ); + break; + default: + return FT_Err_Invalid_Glyph_Format; + } + + /* if no need to allocate memory */ + if ( ypixels == 0 && new_pitch <= pitch ) + { + /* zero the padding */ + FT_Int bit_width = pitch * 8; + FT_Int bit_last = ( width + xpixels ) * bpp; + + + if ( bit_last < bit_width ) + { + FT_Byte* line = bitmap->buffer + ( bit_last >> 3 ); + FT_Byte* end = bitmap->buffer + pitch; + FT_Int shift = bit_last & 7; + FT_UInt mask = 0xFF00U >> shift; + FT_Int count = height; + + + for ( ; count > 0; count--, line += pitch, end += pitch ) + { + FT_Byte* write = line; + + + if ( shift > 0 ) + { + write[0] = (FT_Byte)( write[0] & mask ); + write++; + } + if ( write < end ) + FT_MEM_ZERO( write, end-write ); + } + } + + return FT_Err_Ok; + } + + if ( FT_QALLOC_MULT( buffer, new_pitch, bitmap->rows + ypixels ) ) + return error; + + if ( bitmap->pitch > 0 ) + { + FT_Int len = ( width * bpp + 7 ) >> 3; + + + for ( i = 0; i < bitmap->rows; i++ ) + FT_MEM_COPY( buffer + new_pitch * ( ypixels + i ), + bitmap->buffer + pitch * i, len ); + } + else + { + FT_Int len = ( width * bpp + 7 ) >> 3; + + + for ( i = 0; i < bitmap->rows; i++ ) + FT_MEM_COPY( buffer + new_pitch * i, + bitmap->buffer + pitch * i, len ); + } + + FT_FREE( bitmap->buffer ); + bitmap->buffer = buffer; + + if ( bitmap->pitch < 0 ) + new_pitch = -new_pitch; + + /* set pitch only, width and height are left untouched */ + bitmap->pitch = new_pitch; + + return FT_Err_Ok; + } + + + /* documentation is in ftbitmap.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Bitmap_Embolden( FT_Library library, + FT_Bitmap* bitmap, + FT_Pos xStrength, + FT_Pos yStrength ) + { + FT_Error error; + unsigned char* p; + FT_Int i, x, y, pitch; + FT_Int xstr, ystr; + + + if ( !library ) + return FT_Err_Invalid_Library_Handle; + + if ( !bitmap || !bitmap->buffer ) + return FT_Err_Invalid_Argument; + + if ( ( ( FT_PIX_ROUND( xStrength ) >> 6 ) > FT_INT_MAX ) || + ( ( FT_PIX_ROUND( yStrength ) >> 6 ) > FT_INT_MAX ) ) + return FT_Err_Invalid_Argument; + + xstr = (FT_Int)FT_PIX_ROUND( xStrength ) >> 6; + ystr = (FT_Int)FT_PIX_ROUND( yStrength ) >> 6; + + if ( xstr == 0 && ystr == 0 ) + return FT_Err_Ok; + else if ( xstr < 0 || ystr < 0 ) + return FT_Err_Invalid_Argument; + + switch ( bitmap->pixel_mode ) + { + case FT_PIXEL_MODE_GRAY2: + case FT_PIXEL_MODE_GRAY4: + { + FT_Bitmap tmp; + FT_Int align; + + + if ( bitmap->pixel_mode == FT_PIXEL_MODE_GRAY2 ) + align = ( bitmap->width + xstr + 3 ) / 4; + else + align = ( bitmap->width + xstr + 1 ) / 2; + + FT_Bitmap_New( &tmp ); + + error = FT_Bitmap_Convert( library, bitmap, &tmp, align ); + if ( error ) + return error; + + FT_Bitmap_Done( library, bitmap ); + *bitmap = tmp; + } + break; + + case FT_PIXEL_MODE_MONO: + if ( xstr > 8 ) + xstr = 8; + break; + + case FT_PIXEL_MODE_LCD: + xstr *= 3; + break; + + case FT_PIXEL_MODE_LCD_V: + ystr *= 3; + break; + } + + error = ft_bitmap_assure_buffer( library->memory, bitmap, xstr, ystr ); + if ( error ) + return error; + + pitch = bitmap->pitch; + if ( pitch > 0 ) + p = bitmap->buffer + pitch * ystr; + else + { + pitch = -pitch; + p = bitmap->buffer + pitch * ( bitmap->rows - 1 ); + } + + /* for each row */ + for ( y = 0; y < bitmap->rows ; y++ ) + { + /* + * Horizontally: + * + * From the last pixel on, make each pixel or'ed with the + * `xstr' pixels before it. + */ + for ( x = pitch - 1; x >= 0; x-- ) + { + unsigned char tmp; + + + tmp = p[x]; + for ( i = 1; i <= xstr; i++ ) + { + if ( bitmap->pixel_mode == FT_PIXEL_MODE_MONO ) + { + p[x] |= tmp >> i; + + /* the maximum value of 8 for `xstr' comes from here */ + if ( x > 0 ) + p[x] |= p[x - 1] << ( 8 - i ); + +#if 0 + if ( p[x] == 0xff ) + break; +#endif + } + else + { + if ( x - i >= 0 ) + { + if ( p[x] + p[x - i] > bitmap->num_grays - 1 ) + { + p[x] = (unsigned char)(bitmap->num_grays - 1); + break; + } + else + { + p[x] = (unsigned char)(p[x] + p[x-i]); + if ( p[x] == bitmap->num_grays - 1 ) + break; + } + } + else + break; + } + } + } + + /* + * Vertically: + * + * Make the above `ystr' rows or'ed with it. + */ + for ( x = 1; x <= ystr; x++ ) + { + unsigned char* q; + + + q = p - bitmap->pitch * x; + for ( i = 0; i < pitch; i++ ) + q[i] |= p[i]; + } + + p += bitmap->pitch; + } + + bitmap->width += xstr; + bitmap->rows += ystr; + + return FT_Err_Ok; + } + + + /* documentation is in ftbitmap.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Bitmap_Convert( FT_Library library, + const FT_Bitmap *source, + FT_Bitmap *target, + FT_Int alignment ) + { + FT_Error error = FT_Err_Ok; + FT_Memory memory; + + + if ( !library ) + return FT_Err_Invalid_Library_Handle; + + memory = library->memory; + + switch ( source->pixel_mode ) + { + case FT_PIXEL_MODE_MONO: + case FT_PIXEL_MODE_GRAY: + case FT_PIXEL_MODE_GRAY2: + case FT_PIXEL_MODE_GRAY4: + case FT_PIXEL_MODE_LCD: + case FT_PIXEL_MODE_LCD_V: + { + FT_Int pad; + FT_Long old_size; + + + old_size = target->rows * target->pitch; + if ( old_size < 0 ) + old_size = -old_size; + + target->pixel_mode = FT_PIXEL_MODE_GRAY; + target->rows = source->rows; + target->width = source->width; + + pad = 0; + if ( alignment > 0 ) + { + pad = source->width % alignment; + if ( pad != 0 ) + pad = alignment - pad; + } + + target->pitch = source->width + pad; + + if ( target->rows * target->pitch > old_size && + FT_QREALLOC( target->buffer, + old_size, target->rows * target->pitch ) ) + return error; + } + break; + + default: + error = FT_Err_Invalid_Argument; + } + + switch ( source->pixel_mode ) + { + case FT_PIXEL_MODE_MONO: + { + FT_Byte* s = source->buffer; + FT_Byte* t = target->buffer; + FT_Int i; + + + target->num_grays = 2; + + for ( i = source->rows; i > 0; i-- ) + { + FT_Byte* ss = s; + FT_Byte* tt = t; + FT_Int j; + + + /* get the full bytes */ + for ( j = source->width >> 3; j > 0; j-- ) + { + FT_Int val = ss[0]; /* avoid a byte->int cast on each line */ + + + tt[0] = (FT_Byte)( ( val & 0x80 ) >> 7 ); + tt[1] = (FT_Byte)( ( val & 0x40 ) >> 6 ); + tt[2] = (FT_Byte)( ( val & 0x20 ) >> 5 ); + tt[3] = (FT_Byte)( ( val & 0x10 ) >> 4 ); + tt[4] = (FT_Byte)( ( val & 0x08 ) >> 3 ); + tt[5] = (FT_Byte)( ( val & 0x04 ) >> 2 ); + tt[6] = (FT_Byte)( ( val & 0x02 ) >> 1 ); + tt[7] = (FT_Byte)( val & 0x01 ); + + tt += 8; + ss += 1; + } + + /* get remaining pixels (if any) */ + j = source->width & 7; + if ( j > 0 ) + { + FT_Int val = *ss; + + + for ( ; j > 0; j-- ) + { + tt[0] = (FT_Byte)( ( val & 0x80 ) >> 7); + val <<= 1; + tt += 1; + } + } + + s += source->pitch; + t += target->pitch; + } + } + break; + + + case FT_PIXEL_MODE_GRAY: + case FT_PIXEL_MODE_LCD: + case FT_PIXEL_MODE_LCD_V: + { + FT_Int width = source->width; + FT_Byte* s = source->buffer; + FT_Byte* t = target->buffer; + FT_Int s_pitch = source->pitch; + FT_Int t_pitch = target->pitch; + FT_Int i; + + + target->num_grays = 256; + + for ( i = source->rows; i > 0; i-- ) + { + FT_ARRAY_COPY( t, s, width ); + + s += s_pitch; + t += t_pitch; + } + } + break; + + + case FT_PIXEL_MODE_GRAY2: + { + FT_Byte* s = source->buffer; + FT_Byte* t = target->buffer; + FT_Int i; + + + target->num_grays = 4; + + for ( i = source->rows; i > 0; i-- ) + { + FT_Byte* ss = s; + FT_Byte* tt = t; + FT_Int j; + + + /* get the full bytes */ + for ( j = source->width >> 2; j > 0; j-- ) + { + FT_Int val = ss[0]; + + + tt[0] = (FT_Byte)( ( val & 0xC0 ) >> 6 ); + tt[1] = (FT_Byte)( ( val & 0x30 ) >> 4 ); + tt[2] = (FT_Byte)( ( val & 0x0C ) >> 2 ); + tt[3] = (FT_Byte)( ( val & 0x03 ) ); + + ss += 1; + tt += 4; + } + + j = source->width & 3; + if ( j > 0 ) + { + FT_Int val = ss[0]; + + + for ( ; j > 0; j-- ) + { + tt[0] = (FT_Byte)( ( val & 0xC0 ) >> 6 ); + val <<= 2; + tt += 1; + } + } + + s += source->pitch; + t += target->pitch; + } + } + break; + + + case FT_PIXEL_MODE_GRAY4: + { + FT_Byte* s = source->buffer; + FT_Byte* t = target->buffer; + FT_Int i; + + + target->num_grays = 16; + + for ( i = source->rows; i > 0; i-- ) + { + FT_Byte* ss = s; + FT_Byte* tt = t; + FT_Int j; + + + /* get the full bytes */ + for ( j = source->width >> 1; j > 0; j-- ) + { + FT_Int val = ss[0]; + + + tt[0] = (FT_Byte)( ( val & 0xF0 ) >> 4 ); + tt[1] = (FT_Byte)( ( val & 0x0F ) ); + + ss += 1; + tt += 2; + } + + if ( source->width & 1 ) + tt[0] = (FT_Byte)( ( ss[0] & 0xF0 ) >> 4 ); + + s += source->pitch; + t += target->pitch; + } + } + break; + + + default: + ; + } + + return error; + } + + + /* documentation is in ftbitmap.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_GlyphSlot_Own_Bitmap( FT_GlyphSlot slot ) + { + if ( slot && slot->format == FT_GLYPH_FORMAT_BITMAP && + !( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) ) + { + FT_Bitmap bitmap; + FT_Error error; + + + FT_Bitmap_New( &bitmap ); + error = FT_Bitmap_Copy( slot->library, &slot->bitmap, &bitmap ); + if ( error ) + return error; + + slot->bitmap = bitmap; + slot->internal->flags |= FT_GLYPH_OWN_BITMAP; + } + + return FT_Err_Ok; + } + + + /* documentation is in ftbitmap.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Bitmap_Done( FT_Library library, + FT_Bitmap *bitmap ) + { + FT_Memory memory; + + + if ( !library ) + return FT_Err_Invalid_Library_Handle; + + if ( !bitmap ) + return FT_Err_Invalid_Argument; + + memory = library->memory; + + FT_FREE( bitmap->buffer ); + *bitmap = null_bitmap; + + return FT_Err_Ok; + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/base/ftcalc.c b/mod/pub.mod/freetype.mod/src/base/ftcalc.c new file mode 100644 index 0000000..3892fab --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/base/ftcalc.c @@ -0,0 +1,957 @@ +/***************************************************************************/ +/* */ +/* ftcalc.c */ +/* */ +/* Arithmetic computations (body). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + /*************************************************************************/ + /* */ + /* Support for 1-complement arithmetic has been totally dropped in this */ + /* release. You can still write your own code if you need it. */ + /* */ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* Implementing basic computation routines. */ + /* */ + /* FT_MulDiv(), FT_MulFix(), FT_DivFix(), FT_RoundFix(), FT_CeilFix(), */ + /* and FT_FloorFix() are declared in freetype.h. */ + /* */ + /*************************************************************************/ + + +#include <ft2build.h> +#include FT_GLYPH_H +#include FT_INTERNAL_CALC_H +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_OBJECTS_H + +#ifdef FT_MULFIX_INLINED +#undef FT_MulFix +#endif + +/* we need to define a 64-bits data type here */ + +#ifdef FT_LONG64 + + typedef FT_INT64 FT_Int64; + +#else + + typedef struct FT_Int64_ + { + FT_UInt32 lo; + FT_UInt32 hi; + + } FT_Int64; + +#endif /* FT_LONG64 */ + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_calc + + + /* The following three functions are available regardless of whether */ + /* FT_LONG64 is defined. */ + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Fixed ) + FT_RoundFix( FT_Fixed a ) + { + return ( a >= 0 ) ? ( a + 0x8000L ) & ~0xFFFFL + : -((-a + 0x8000L ) & ~0xFFFFL ); + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Fixed ) + FT_CeilFix( FT_Fixed a ) + { + return ( a >= 0 ) ? ( a + 0xFFFFL ) & ~0xFFFFL + : -((-a + 0xFFFFL ) & ~0xFFFFL ); + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Fixed ) + FT_FloorFix( FT_Fixed a ) + { + return ( a >= 0 ) ? a & ~0xFFFFL + : -((-a) & ~0xFFFFL ); + } + + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + + /* documentation is in ftcalc.h */ + + FT_EXPORT_DEF( FT_Int32 ) + FT_Sqrt32( FT_Int32 x ) + { + FT_UInt32 val, root, newroot, mask; + + + root = 0; + mask = (FT_UInt32)0x40000000UL; + val = (FT_UInt32)x; + + do + { + newroot = root + mask; + if ( newroot <= val ) + { + val -= newroot; + root = newroot + mask; + } + + root >>= 1; + mask >>= 2; + + } while ( mask != 0 ); + + return root; + } + +#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */ + + +#ifdef FT_LONG64 + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Long ) + FT_MulDiv( FT_Long a, + FT_Long b, + FT_Long c ) + { + FT_Int s; + FT_Long d; + + + s = 1; + if ( a < 0 ) { a = -a; s = -1; } + if ( b < 0 ) { b = -b; s = -s; } + if ( c < 0 ) { c = -c; s = -s; } + + d = (FT_Long)( c > 0 ? ( (FT_Int64)a * b + ( c >> 1 ) ) / c + : 0x7FFFFFFFL ); + + return ( s > 0 ) ? d : -d; + } + + +#ifdef TT_USE_BYTECODE_INTERPRETER + + /* documentation is in ftcalc.h */ + + FT_BASE_DEF( FT_Long ) + FT_MulDiv_No_Round( FT_Long a, + FT_Long b, + FT_Long c ) + { + FT_Int s; + FT_Long d; + + + s = 1; + if ( a < 0 ) { a = -a; s = -1; } + if ( b < 0 ) { b = -b; s = -s; } + if ( c < 0 ) { c = -c; s = -s; } + + d = (FT_Long)( c > 0 ? (FT_Int64)a * b / c + : 0x7FFFFFFFL ); + + return ( s > 0 ) ? d : -d; + } + +#endif /* TT_USE_BYTECODE_INTERPRETER */ + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Long ) + FT_MulFix( FT_Long a, + FT_Long b ) + { +#ifdef FT_MULFIX_ASSEMBLER + + return FT_MULFIX_ASSEMBLER( a, b ); + +#else + + FT_Int s = 1; + FT_Long c; + + + if ( a < 0 ) + { + a = -a; + s = -1; + } + + if ( b < 0 ) + { + b = -b; + s = -s; + } + + c = (FT_Long)( ( (FT_Int64)a * b + 0x8000L ) >> 16 ); + + return ( s > 0 ) ? c : -c; + +#endif /* FT_MULFIX_ASSEMBLER */ + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Long ) + FT_DivFix( FT_Long a, + FT_Long b ) + { + FT_Int32 s; + FT_UInt32 q; + + s = 1; + if ( a < 0 ) { a = -a; s = -1; } + if ( b < 0 ) { b = -b; s = -s; } + + if ( b == 0 ) + /* check for division by 0 */ + q = 0x7FFFFFFFL; + else + /* compute result directly */ + q = (FT_UInt32)( ( ( (FT_Int64)a << 16 ) + ( b >> 1 ) ) / b ); + + return ( s < 0 ? -(FT_Long)q : (FT_Long)q ); + } + + +#else /* !FT_LONG64 */ + + + static void + ft_multo64( FT_UInt32 x, + FT_UInt32 y, + FT_Int64 *z ) + { + FT_UInt32 lo1, hi1, lo2, hi2, lo, hi, i1, i2; + + + lo1 = x & 0x0000FFFFU; hi1 = x >> 16; + lo2 = y & 0x0000FFFFU; hi2 = y >> 16; + + lo = lo1 * lo2; + i1 = lo1 * hi2; + i2 = lo2 * hi1; + hi = hi1 * hi2; + + /* Check carry overflow of i1 + i2 */ + i1 += i2; + hi += (FT_UInt32)( i1 < i2 ) << 16; + + hi += i1 >> 16; + i1 = i1 << 16; + + /* Check carry overflow of i1 + lo */ + lo += i1; + hi += ( lo < i1 ); + + z->lo = lo; + z->hi = hi; + } + + + static FT_UInt32 + ft_div64by32( FT_UInt32 hi, + FT_UInt32 lo, + FT_UInt32 y ) + { + FT_UInt32 r, q; + FT_Int i; + + + q = 0; + r = hi; + + if ( r >= y ) + return (FT_UInt32)0x7FFFFFFFL; + + i = 32; + do + { + r <<= 1; + q <<= 1; + r |= lo >> 31; + + if ( r >= (FT_UInt32)y ) + { + r -= y; + q |= 1; + } + lo <<= 1; + } while ( --i ); + + return q; + } + + + static void + FT_Add64( FT_Int64* x, + FT_Int64* y, + FT_Int64 *z ) + { + register FT_UInt32 lo, hi; + + + lo = x->lo + y->lo; + hi = x->hi + y->hi + ( lo < x->lo ); + + z->lo = lo; + z->hi = hi; + } + + + /* documentation is in freetype.h */ + + /* The FT_MulDiv function has been optimized thanks to ideas from */ + /* Graham Asher. The trick is to optimize computation when everything */ + /* fits within 32-bits (a rather common case). */ + /* */ + /* we compute 'a*b+c/2', then divide it by 'c'. (positive values) */ + /* */ + /* 46340 is FLOOR(SQRT(2^31-1)). */ + /* */ + /* if ( a <= 46340 && b <= 46340 ) then ( a*b <= 0x7FFEA810 ) */ + /* */ + /* 0x7FFFFFFF - 0x7FFEA810 = 0x157F0 */ + /* */ + /* if ( c < 0x157F0*2 ) then ( a*b+c/2 <= 0x7FFFFFFF ) */ + /* */ + /* and 2*0x157F0 = 176096 */ + /* */ + + FT_EXPORT_DEF( FT_Long ) + FT_MulDiv( FT_Long a, + FT_Long b, + FT_Long c ) + { + long s; + + + /* XXX: this function does not allow 64-bit arguments */ + if ( a == 0 || b == c ) + return a; + + s = a; a = FT_ABS( a ); + s ^= b; b = FT_ABS( b ); + s ^= c; c = FT_ABS( c ); + + if ( a <= 46340L && b <= 46340L && c <= 176095L && c > 0 ) + a = ( a * b + ( c >> 1 ) ) / c; + + else if ( c > 0 ) + { + FT_Int64 temp, temp2; + + + ft_multo64( (FT_Int32)a, (FT_Int32)b, &temp ); + + temp2.hi = 0; + temp2.lo = (FT_UInt32)(c >> 1); + FT_Add64( &temp, &temp2, &temp ); + a = ft_div64by32( temp.hi, temp.lo, (FT_Int32)c ); + } + else + a = 0x7FFFFFFFL; + + return ( s < 0 ? -a : a ); + } + + +#ifdef TT_USE_BYTECODE_INTERPRETER + + FT_BASE_DEF( FT_Long ) + FT_MulDiv_No_Round( FT_Long a, + FT_Long b, + FT_Long c ) + { + long s; + + + if ( a == 0 || b == c ) + return a; + + s = a; a = FT_ABS( a ); + s ^= b; b = FT_ABS( b ); + s ^= c; c = FT_ABS( c ); + + if ( a <= 46340L && b <= 46340L && c > 0 ) + a = a * b / c; + + else if ( c > 0 ) + { + FT_Int64 temp; + + + ft_multo64( (FT_Int32)a, (FT_Int32)b, &temp ); + a = ft_div64by32( temp.hi, temp.lo, (FT_Int32)c ); + } + else + a = 0x7FFFFFFFL; + + return ( s < 0 ? -a : a ); + } + +#endif /* TT_USE_BYTECODE_INTERPRETER */ + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Long ) + FT_MulFix( FT_Long a, + FT_Long b ) + { +#ifdef FT_MULFIX_ASSEMBLER + + return FT_MULFIX_ASSEMBLER( a, b ); + +#elif 0 + + /* + * This code is nonportable. See comment below. + * + * However, on a platform where right-shift of a signed quantity fills + * the leftmost bits by copying the sign bit, it might be faster. + */ + + FT_Long sa, sb; + FT_ULong ua, ub; + + + if ( a == 0 || b == 0x10000L ) + return a; + + /* + * This is a clever way of converting a signed number `a' into its + * absolute value (stored back into `a') and its sign. The sign is + * stored in `sa'; 0 means `a' was positive or zero, and -1 means `a' + * was negative. (Similarly for `b' and `sb'). + * + * Unfortunately, it doesn't work (at least not portably). + * + * It makes the assumption that right-shift on a negative signed value + * fills the leftmost bits by copying the sign bit. This is wrong. + * According to K&R 2nd ed, section `A7.8 Shift Operators' on page 206, + * the result of right-shift of a negative signed value is + * implementation-defined. At least one implementation fills the + * leftmost bits with 0s (i.e., it is exactly the same as an unsigned + * right shift). This means that when `a' is negative, `sa' ends up + * with the value 1 rather than -1. After that, everything else goes + * wrong. + */ + sa = ( a >> ( sizeof ( a ) * 8 - 1 ) ); + a = ( a ^ sa ) - sa; + sb = ( b >> ( sizeof ( b ) * 8 - 1 ) ); + b = ( b ^ sb ) - sb; + + ua = (FT_ULong)a; + ub = (FT_ULong)b; + + if ( ua <= 2048 && ub <= 1048576L ) + ua = ( ua * ub + 0x8000U ) >> 16; + else + { + FT_ULong al = ua & 0xFFFFU; + + + ua = ( ua >> 16 ) * ub + al * ( ub >> 16 ) + + ( ( al * ( ub & 0xFFFFU ) + 0x8000U ) >> 16 ); + } + + sa ^= sb, + ua = (FT_ULong)(( ua ^ sa ) - sa); + + return (FT_Long)ua; + +#else /* 0 */ + + FT_Long s; + FT_ULong ua, ub; + + + if ( a == 0 || b == 0x10000L ) + return a; + + s = a; a = FT_ABS( a ); + s ^= b; b = FT_ABS( b ); + + ua = (FT_ULong)a; + ub = (FT_ULong)b; + + if ( ua <= 2048 && ub <= 1048576L ) + ua = ( ua * ub + 0x8000UL ) >> 16; + else + { + FT_ULong al = ua & 0xFFFFUL; + + + ua = ( ua >> 16 ) * ub + al * ( ub >> 16 ) + + ( ( al * ( ub & 0xFFFFUL ) + 0x8000UL ) >> 16 ); + } + + return ( s < 0 ? -(FT_Long)ua : (FT_Long)ua ); + +#endif /* 0 */ + + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Long ) + FT_DivFix( FT_Long a, + FT_Long b ) + { + FT_Int32 s; + FT_UInt32 q; + + + /* XXX: this function does not allow 64-bit arguments */ + s = (FT_Int32)a; a = FT_ABS( a ); + s ^= (FT_Int32)b; b = FT_ABS( b ); + + if ( b == 0 ) + { + /* check for division by 0 */ + q = (FT_UInt32)0x7FFFFFFFL; + } + else if ( ( a >> 16 ) == 0 ) + { + /* compute result directly */ + q = (FT_UInt32)( (a << 16) + (b >> 1) ) / (FT_UInt32)b; + } + else + { + /* we need more bits; we have to do it by hand */ + FT_Int64 temp, temp2; + + temp.hi = (FT_Int32) (a >> 16); + temp.lo = (FT_UInt32)(a << 16); + temp2.hi = 0; + temp2.lo = (FT_UInt32)( b >> 1 ); + FT_Add64( &temp, &temp2, &temp ); + q = ft_div64by32( temp.hi, temp.lo, (FT_Int32)b ); + } + + return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); + } + + +#if 0 + + /* documentation is in ftcalc.h */ + + FT_EXPORT_DEF( void ) + FT_MulTo64( FT_Int32 x, + FT_Int32 y, + FT_Int64 *z ) + { + FT_Int32 s; + + + s = x; x = FT_ABS( x ); + s ^= y; y = FT_ABS( y ); + + ft_multo64( x, y, z ); + + if ( s < 0 ) + { + z->lo = (FT_UInt32)-(FT_Int32)z->lo; + z->hi = ~z->hi + !( z->lo ); + } + } + + + /* apparently, the second version of this code is not compiled correctly */ + /* on Mac machines with the MPW C compiler.. tsk, tsk, tsk... */ + +#if 1 + + FT_EXPORT_DEF( FT_Int32 ) + FT_Div64by32( FT_Int64* x, + FT_Int32 y ) + { + FT_Int32 s; + FT_UInt32 q, r, i, lo; + + + s = x->hi; + if ( s < 0 ) + { + x->lo = (FT_UInt32)-(FT_Int32)x->lo; + x->hi = ~x->hi + !x->lo; + } + s ^= y; y = FT_ABS( y ); + + /* Shortcut */ + if ( x->hi == 0 ) + { + if ( y > 0 ) + q = x->lo / y; + else + q = 0x7FFFFFFFL; + + return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); + } + + r = x->hi; + lo = x->lo; + + if ( r >= (FT_UInt32)y ) /* we know y is to be treated as unsigned here */ + return ( s < 0 ? 0x80000001UL : 0x7FFFFFFFUL ); + /* Return Max/Min Int32 if division overflow. */ + /* This includes division by zero! */ + q = 0; + for ( i = 0; i < 32; i++ ) + { + r <<= 1; + q <<= 1; + r |= lo >> 31; + + if ( r >= (FT_UInt32)y ) + { + r -= y; + q |= 1; + } + lo <<= 1; + } + + return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); + } + +#else /* 0 */ + + FT_EXPORT_DEF( FT_Int32 ) + FT_Div64by32( FT_Int64* x, + FT_Int32 y ) + { + FT_Int32 s; + FT_UInt32 q; + + + s = x->hi; + if ( s < 0 ) + { + x->lo = (FT_UInt32)-(FT_Int32)x->lo; + x->hi = ~x->hi + !x->lo; + } + s ^= y; y = FT_ABS( y ); + + /* Shortcut */ + if ( x->hi == 0 ) + { + if ( y > 0 ) + q = ( x->lo + ( y >> 1 ) ) / y; + else + q = 0x7FFFFFFFL; + + return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); + } + + q = ft_div64by32( x->hi, x->lo, y ); + + return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); + } + +#endif /* 0 */ + +#endif /* 0 */ + + +#endif /* FT_LONG64 */ + + + /* documentation is in ftglyph.h */ + + FT_EXPORT_DEF( void ) + FT_Matrix_Multiply( const FT_Matrix* a, + FT_Matrix *b ) + { + FT_Fixed xx, xy, yx, yy; + + + if ( !a || !b ) + return; + + xx = FT_MulFix( a->xx, b->xx ) + FT_MulFix( a->xy, b->yx ); + xy = FT_MulFix( a->xx, b->xy ) + FT_MulFix( a->xy, b->yy ); + yx = FT_MulFix( a->yx, b->xx ) + FT_MulFix( a->yy, b->yx ); + yy = FT_MulFix( a->yx, b->xy ) + FT_MulFix( a->yy, b->yy ); + + b->xx = xx; b->xy = xy; + b->yx = yx; b->yy = yy; + } + + + /* documentation is in ftglyph.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Matrix_Invert( FT_Matrix* matrix ) + { + FT_Pos delta, xx, yy; + + + if ( !matrix ) + return FT_Err_Invalid_Argument; + + /* compute discriminant */ + delta = FT_MulFix( matrix->xx, matrix->yy ) - + FT_MulFix( matrix->xy, matrix->yx ); + + if ( !delta ) + return FT_Err_Invalid_Argument; /* matrix can't be inverted */ + + matrix->xy = - FT_DivFix( matrix->xy, delta ); + matrix->yx = - FT_DivFix( matrix->yx, delta ); + + xx = matrix->xx; + yy = matrix->yy; + + matrix->xx = FT_DivFix( yy, delta ); + matrix->yy = FT_DivFix( xx, delta ); + + return FT_Err_Ok; + } + + + /* documentation is in ftcalc.h */ + + FT_BASE_DEF( void ) + FT_Matrix_Multiply_Scaled( const FT_Matrix* a, + FT_Matrix *b, + FT_Long scaling ) + { + FT_Fixed xx, xy, yx, yy; + + FT_Long val = 0x10000L * scaling; + + + if ( !a || !b ) + return; + + xx = FT_MulDiv( a->xx, b->xx, val ) + FT_MulDiv( a->xy, b->yx, val ); + xy = FT_MulDiv( a->xx, b->xy, val ) + FT_MulDiv( a->xy, b->yy, val ); + yx = FT_MulDiv( a->yx, b->xx, val ) + FT_MulDiv( a->yy, b->yx, val ); + yy = FT_MulDiv( a->yx, b->xy, val ) + FT_MulDiv( a->yy, b->yy, val ); + + b->xx = xx; b->xy = xy; + b->yx = yx; b->yy = yy; + } + + + /* documentation is in ftcalc.h */ + + FT_BASE_DEF( void ) + FT_Vector_Transform_Scaled( FT_Vector* vector, + const FT_Matrix* matrix, + FT_Long scaling ) + { + FT_Pos xz, yz; + + FT_Long val = 0x10000L * scaling; + + + if ( !vector || !matrix ) + return; + + xz = FT_MulDiv( vector->x, matrix->xx, val ) + + FT_MulDiv( vector->y, matrix->xy, val ); + + yz = FT_MulDiv( vector->x, matrix->yx, val ) + + FT_MulDiv( vector->y, matrix->yy, val ); + + vector->x = xz; + vector->y = yz; + } + + + /* documentation is in ftcalc.h */ + + FT_BASE_DEF( FT_Int32 ) + FT_SqrtFixed( FT_Int32 x ) + { + FT_UInt32 root, rem_hi, rem_lo, test_div; + FT_Int count; + + + root = 0; + + if ( x > 0 ) + { + rem_hi = 0; + rem_lo = x; + count = 24; + do + { + rem_hi = ( rem_hi << 2 ) | ( rem_lo >> 30 ); + rem_lo <<= 2; + root <<= 1; + test_div = ( root << 1 ) + 1; + + if ( rem_hi >= test_div ) + { + rem_hi -= test_div; + root += 1; + } + } while ( --count ); + } + + return (FT_Int32)root; + } + + + /* documentation is in ftcalc.h */ + + FT_BASE_DEF( FT_Int ) + ft_corner_orientation( FT_Pos in_x, + FT_Pos in_y, + FT_Pos out_x, + FT_Pos out_y ) + { + FT_Long result; /* avoid overflow on 16-bit system */ + + + /* deal with the trivial cases quickly */ + if ( in_y == 0 ) + { + if ( in_x >= 0 ) + result = out_y; + else + result = -out_y; + } + else if ( in_x == 0 ) + { + if ( in_y >= 0 ) + result = -out_x; + else + result = out_x; + } + else if ( out_y == 0 ) + { + if ( out_x >= 0 ) + result = in_y; + else + result = -in_y; + } + else if ( out_x == 0 ) + { + if ( out_y >= 0 ) + result = -in_x; + else + result = in_x; + } + else /* general case */ + { +#ifdef FT_LONG64 + + FT_Int64 delta = (FT_Int64)in_x * out_y - (FT_Int64)in_y * out_x; + + + if ( delta == 0 ) + result = 0; + else + result = 1 - 2 * ( delta < 0 ); + +#else + + FT_Int64 z1, z2; + + + /* XXX: this function does not allow 64-bit arguments */ + ft_multo64( (FT_Int32)in_x, (FT_Int32)out_y, &z1 ); + ft_multo64( (FT_Int32)in_y, (FT_Int32)out_x, &z2 ); + + if ( z1.hi > z2.hi ) + result = +1; + else if ( z1.hi < z2.hi ) + result = -1; + else if ( z1.lo > z2.lo ) + result = +1; + else if ( z1.lo < z2.lo ) + result = -1; + else + result = 0; + +#endif + } + + /* XXX: only the sign of return value, +1/0/-1 must be used */ + return (FT_Int)result; + } + + + /* documentation is in ftcalc.h */ + + FT_BASE_DEF( FT_Int ) + ft_corner_is_flat( FT_Pos in_x, + FT_Pos in_y, + FT_Pos out_x, + FT_Pos out_y ) + { + FT_Pos ax = in_x; + FT_Pos ay = in_y; + + FT_Pos d_in, d_out, d_corner; + + + if ( ax < 0 ) + ax = -ax; + if ( ay < 0 ) + ay = -ay; + d_in = ax + ay; + + ax = out_x; + if ( ax < 0 ) + ax = -ax; + ay = out_y; + if ( ay < 0 ) + ay = -ay; + d_out = ax + ay; + + ax = out_x + in_x; + if ( ax < 0 ) + ax = -ax; + ay = out_y + in_y; + if ( ay < 0 ) + ay = -ay; + d_corner = ax + ay; + + return ( d_in + d_out - d_corner ) < ( d_corner >> 4 ); + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/base/ftcid.c b/mod/pub.mod/freetype.mod/src/base/ftcid.c new file mode 100644 index 0000000..733aae1 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/base/ftcid.c @@ -0,0 +1,117 @@ +/***************************************************************************/ +/* */ +/* ftcid.c */ +/* */ +/* FreeType API for accessing CID font information. */ +/* */ +/* Copyright 2007, 2009 by Derek Clegg, Michael Toftdal. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_CID_H +#include FT_INTERNAL_OBJECTS_H +#include FT_SERVICE_CID_H + + + /* documentation is in ftcid.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_CID_Registry_Ordering_Supplement( FT_Face face, + const char* *registry, + const char* *ordering, + FT_Int *supplement) + { + FT_Error error; + const char* r = NULL; + const char* o = NULL; + FT_Int s = 0; + + + error = FT_Err_Invalid_Argument; + + if ( face ) + { + FT_Service_CID service; + + + FT_FACE_FIND_SERVICE( face, service, CID ); + + if ( service && service->get_ros ) + error = service->get_ros( face, &r, &o, &s ); + } + + if ( registry ) + *registry = r; + + if ( ordering ) + *ordering = o; + + if ( supplement ) + *supplement = s; + + return error; + } + + + FT_EXPORT_DEF( FT_Error ) + FT_Get_CID_Is_Internally_CID_Keyed( FT_Face face, + FT_Bool *is_cid ) + { + FT_Error error = FT_Err_Invalid_Argument; + FT_Bool ic = 0; + + + if ( face ) + { + FT_Service_CID service; + + + FT_FACE_FIND_SERVICE( face, service, CID ); + + if ( service && service->get_is_cid ) + error = service->get_is_cid( face, &ic); + } + + if ( is_cid ) + *is_cid = ic; + + return error; + } + + + FT_EXPORT_DEF( FT_Error ) + FT_Get_CID_From_Glyph_Index( FT_Face face, + FT_UInt glyph_index, + FT_UInt *cid ) + { + FT_Error error = FT_Err_Invalid_Argument; + FT_UInt c = 0; + + + if ( face ) + { + FT_Service_CID service; + + + FT_FACE_FIND_SERVICE( face, service, CID ); + + if ( service && service->get_cid_from_glyph_index ) + error = service->get_cid_from_glyph_index( face, glyph_index, &c); + } + + if ( cid ) + *cid = c; + + return error; + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/base/ftdbgmem.c b/mod/pub.mod/freetype.mod/src/base/ftdbgmem.c new file mode 100644 index 0000000..677f242 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/base/ftdbgmem.c @@ -0,0 +1,997 @@ +/***************************************************************************/ +/* */ +/* ftdbgmem.c */ +/* */ +/* Memory debugger (body). */ +/* */ +/* Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_CONFIG_CONFIG_H +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_MEMORY_H +#include FT_SYSTEM_H +#include FT_ERRORS_H +#include FT_TYPES_H + + +#ifdef FT_DEBUG_MEMORY + +#define KEEPALIVE /* `Keep alive' means that freed blocks aren't released + * to the heap. This is useful to detect double-frees + * or weird heap corruption, but it uses large amounts of + * memory, however. + */ + +#include FT_CONFIG_STANDARD_LIBRARY_H + + FT_BASE_DEF( const char* ) _ft_debug_file = 0; + FT_BASE_DEF( long ) _ft_debug_lineno = 0; + + extern void + FT_DumpMemory( FT_Memory memory ); + + + typedef struct FT_MemSourceRec_* FT_MemSource; + typedef struct FT_MemNodeRec_* FT_MemNode; + typedef struct FT_MemTableRec_* FT_MemTable; + + +#define FT_MEM_VAL( addr ) ((FT_ULong)(FT_Pointer)( addr )) + + /* + * This structure holds statistics for a single allocation/release + * site. This is useful to know where memory operations happen the + * most. + */ + typedef struct FT_MemSourceRec_ + { + const char* file_name; + long line_no; + + FT_Long cur_blocks; /* current number of allocated blocks */ + FT_Long max_blocks; /* max. number of allocated blocks */ + FT_Long all_blocks; /* total number of blocks allocated */ + + FT_Long cur_size; /* current cumulative allocated size */ + FT_Long max_size; /* maximum cumulative allocated size */ + FT_Long all_size; /* total cumulative allocated size */ + + FT_Long cur_max; /* current maximum allocated size */ + + FT_UInt32 hash; + FT_MemSource link; + + } FT_MemSourceRec; + + + /* + * We don't need a resizable array for the memory sources, because + * their number is pretty limited within FreeType. + */ +#define FT_MEM_SOURCE_BUCKETS 128 + + /* + * This structure holds information related to a single allocated + * memory block. If KEEPALIVE is defined, blocks that are freed by + * FreeType are never released to the system. Instead, their `size' + * field is set to -size. This is mainly useful to detect double frees, + * at the price of large memory footprint during execution. + */ + typedef struct FT_MemNodeRec_ + { + FT_Byte* address; + FT_Long size; /* < 0 if the block was freed */ + + FT_MemSource source; + +#ifdef KEEPALIVE + const char* free_file_name; + FT_Long free_line_no; +#endif + + FT_MemNode link; + + } FT_MemNodeRec; + + + /* + * The global structure, containing compound statistics and all hash + * tables. + */ + typedef struct FT_MemTableRec_ + { + FT_ULong size; + FT_ULong nodes; + FT_MemNode* buckets; + + FT_ULong alloc_total; + FT_ULong alloc_current; + FT_ULong alloc_max; + FT_ULong alloc_count; + + FT_Bool bound_total; + FT_ULong alloc_total_max; + + FT_Bool bound_count; + FT_ULong alloc_count_max; + + FT_MemSource sources[FT_MEM_SOURCE_BUCKETS]; + + FT_Bool keep_alive; + + FT_Memory memory; + FT_Pointer memory_user; + FT_Alloc_Func alloc; + FT_Free_Func free; + FT_Realloc_Func realloc; + + } FT_MemTableRec; + + +#define FT_MEM_SIZE_MIN 7 +#define FT_MEM_SIZE_MAX 13845163 + +#define FT_FILENAME( x ) ((x) ? (x) : "unknown file") + + + /* + * Prime numbers are ugly to handle. It would be better to implement + * L-Hashing, which is 10% faster and doesn't require divisions. + */ + static const FT_UInt ft_mem_primes[] = + { + 7, + 11, + 19, + 37, + 73, + 109, + 163, + 251, + 367, + 557, + 823, + 1237, + 1861, + 2777, + 4177, + 6247, + 9371, + 14057, + 21089, + 31627, + 47431, + 71143, + 106721, + 160073, + 240101, + 360163, + 540217, + 810343, + 1215497, + 1823231, + 2734867, + 4102283, + 6153409, + 9230113, + 13845163, + }; + + + static FT_ULong + ft_mem_closest_prime( FT_ULong num ) + { + FT_UInt i; + + + for ( i = 0; + i < sizeof ( ft_mem_primes ) / sizeof ( ft_mem_primes[0] ); i++ ) + if ( ft_mem_primes[i] > num ) + return ft_mem_primes[i]; + + return FT_MEM_SIZE_MAX; + } + + + extern void + ft_mem_debug_panic( const char* fmt, + ... ) + { + va_list ap; + + + printf( "FreeType.Debug: " ); + + va_start( ap, fmt ); + vprintf( fmt, ap ); + va_end( ap ); + + printf( "\n" ); + exit( EXIT_FAILURE ); + } + + + static FT_Pointer + ft_mem_table_alloc( FT_MemTable table, + FT_Long size ) + { + FT_Memory memory = table->memory; + FT_Pointer block; + + + memory->user = table->memory_user; + block = table->alloc( memory, size ); + memory->user = table; + + return block; + } + + + static void + ft_mem_table_free( FT_MemTable table, + FT_Pointer block ) + { + FT_Memory memory = table->memory; + + + memory->user = table->memory_user; + table->free( memory, block ); + memory->user = table; + } + + + static void + ft_mem_table_resize( FT_MemTable table ) + { + FT_ULong new_size; + + + new_size = ft_mem_closest_prime( table->nodes ); + if ( new_size != table->size ) + { + FT_MemNode* new_buckets; + FT_ULong i; + + + new_buckets = (FT_MemNode *) + ft_mem_table_alloc( table, + new_size * sizeof ( FT_MemNode ) ); + if ( new_buckets == NULL ) + return; + + FT_ARRAY_ZERO( new_buckets, new_size ); + + for ( i = 0; i < table->size; i++ ) + { + FT_MemNode node, next, *pnode; + FT_ULong hash; + + + node = table->buckets[i]; + while ( node ) + { + next = node->link; + hash = FT_MEM_VAL( node->address ) % new_size; + pnode = new_buckets + hash; + + node->link = pnode[0]; + pnode[0] = node; + + node = next; + } + } + + if ( table->buckets ) + ft_mem_table_free( table, table->buckets ); + + table->buckets = new_buckets; + table->size = new_size; + } + } + + + static FT_MemTable + ft_mem_table_new( FT_Memory memory ) + { + FT_MemTable table; + + + table = (FT_MemTable)memory->alloc( memory, sizeof ( *table ) ); + if ( table == NULL ) + goto Exit; + + FT_ZERO( table ); + + table->size = FT_MEM_SIZE_MIN; + table->nodes = 0; + + table->memory = memory; + + table->memory_user = memory->user; + + table->alloc = memory->alloc; + table->realloc = memory->realloc; + table->free = memory->free; + + table->buckets = (FT_MemNode *) + memory->alloc( memory, + table->size * sizeof ( FT_MemNode ) ); + if ( table->buckets ) + FT_ARRAY_ZERO( table->buckets, table->size ); + else + { + memory->free( memory, table ); + table = NULL; + } + + Exit: + return table; + } + + + static void + ft_mem_table_destroy( FT_MemTable table ) + { + FT_ULong i; + + + FT_DumpMemory( table->memory ); + + if ( table ) + { + FT_Long leak_count = 0; + FT_ULong leaks = 0; + + + /* remove all blocks from the table, revealing leaked ones */ + for ( i = 0; i < table->size; i++ ) + { + FT_MemNode *pnode = table->buckets + i, next, node = *pnode; + + + while ( node ) + { + next = node->link; + node->link = 0; + + if ( node->size > 0 ) + { + printf( + "leaked memory block at address %p, size %8ld in (%s:%ld)\n", + node->address, node->size, + FT_FILENAME( node->source->file_name ), + node->source->line_no ); + + leak_count++; + leaks += node->size; + + ft_mem_table_free( table, node->address ); + } + + node->address = NULL; + node->size = 0; + + ft_mem_table_free( table, node ); + node = next; + } + table->buckets[i] = 0; + } + + ft_mem_table_free( table, table->buckets ); + table->buckets = NULL; + + table->size = 0; + table->nodes = 0; + + /* remove all sources */ + for ( i = 0; i < FT_MEM_SOURCE_BUCKETS; i++ ) + { + FT_MemSource source, next; + + + for ( source = table->sources[i]; source != NULL; source = next ) + { + next = source->link; + ft_mem_table_free( table, source ); + } + + table->sources[i] = NULL; + } + + printf( + "FreeType: total memory allocations = %ld\n", table->alloc_total ); + printf( + "FreeType: maximum memory footprint = %ld\n", table->alloc_max ); + + ft_mem_table_free( table, table ); + + if ( leak_count > 0 ) + ft_mem_debug_panic( + "FreeType: %ld bytes of memory leaked in %ld blocks\n", + leaks, leak_count ); + + printf( "FreeType: no memory leaks detected\n" ); + } + } + + + static FT_MemNode* + ft_mem_table_get_nodep( FT_MemTable table, + FT_Byte* address ) + { + FT_ULong hash; + FT_MemNode *pnode, node; + + + hash = FT_MEM_VAL( address ); + pnode = table->buckets + ( hash % table->size ); + + for (;;) + { + node = pnode[0]; + if ( !node ) + break; + + if ( node->address == address ) + break; + + pnode = &node->link; + } + return pnode; + } + + + static FT_MemSource + ft_mem_table_get_source( FT_MemTable table ) + { + FT_UInt32 hash; + FT_MemSource node, *pnode; + + + /* cast to FT_PtrDist first since void* can be larger */ + /* than FT_UInt32 and GCC 4.1.1 emits a warning */ + hash = (FT_UInt32)(FT_PtrDist)(void*)_ft_debug_file + + (FT_UInt32)( 5 * _ft_debug_lineno ); + pnode = &table->sources[hash % FT_MEM_SOURCE_BUCKETS]; + + for ( ;; ) + { + node = *pnode; + if ( node == NULL ) + break; + + if ( node->file_name == _ft_debug_file && + node->line_no == _ft_debug_lineno ) + goto Exit; + + pnode = &node->link; + } + + node = (FT_MemSource)ft_mem_table_alloc( table, sizeof ( *node ) ); + if ( node == NULL ) + ft_mem_debug_panic( + "not enough memory to perform memory debugging\n" ); + + node->file_name = _ft_debug_file; + node->line_no = _ft_debug_lineno; + + node->cur_blocks = 0; + node->max_blocks = 0; + node->all_blocks = 0; + + node->cur_size = 0; + node->max_size = 0; + node->all_size = 0; + + node->cur_max = 0; + + node->link = NULL; + node->hash = hash; + *pnode = node; + + Exit: + return node; + } + + + static void + ft_mem_table_set( FT_MemTable table, + FT_Byte* address, + FT_ULong size, + FT_Long delta ) + { + FT_MemNode *pnode, node; + + + if ( table ) + { + FT_MemSource source; + + + pnode = ft_mem_table_get_nodep( table, address ); + node = *pnode; + if ( node ) + { + if ( node->size < 0 ) + { + /* This block was already freed. Our memory is now completely */ + /* corrupted! */ + /* This can only happen in keep-alive mode. */ + ft_mem_debug_panic( + "memory heap corrupted (allocating freed block)" ); + } + else + { + /* This block was already allocated. This means that our memory */ + /* is also corrupted! */ + ft_mem_debug_panic( + "memory heap corrupted (re-allocating allocated block at" + " %p, of size %ld)\n" + "org=%s:%d new=%s:%d\n", + node->address, node->size, + FT_FILENAME( node->source->file_name ), node->source->line_no, + FT_FILENAME( _ft_debug_file ), _ft_debug_lineno ); + } + } + + /* we need to create a new node in this table */ + node = (FT_MemNode)ft_mem_table_alloc( table, sizeof ( *node ) ); + if ( node == NULL ) + ft_mem_debug_panic( "not enough memory to run memory tests" ); + + node->address = address; + node->size = size; + node->source = source = ft_mem_table_get_source( table ); + + if ( delta == 0 ) + { + /* this is an allocation */ + source->all_blocks++; + source->cur_blocks++; + if ( source->cur_blocks > source->max_blocks ) + source->max_blocks = source->cur_blocks; + } + + if ( size > (FT_ULong)source->cur_max ) + source->cur_max = size; + + if ( delta != 0 ) + { + /* we are growing or shrinking a reallocated block */ + source->cur_size += delta; + table->alloc_current += delta; + } + else + { + /* we are allocating a new block */ + source->cur_size += size; + table->alloc_current += size; + } + + source->all_size += size; + + if ( source->cur_size > source->max_size ) + source->max_size = source->cur_size; + + node->free_file_name = NULL; + node->free_line_no = 0; + + node->link = pnode[0]; + + pnode[0] = node; + table->nodes++; + + table->alloc_total += size; + + if ( table->alloc_current > table->alloc_max ) + table->alloc_max = table->alloc_current; + + if ( table->nodes * 3 < table->size || + table->size * 3 < table->nodes ) + ft_mem_table_resize( table ); + } + } + + + static void + ft_mem_table_remove( FT_MemTable table, + FT_Byte* address, + FT_Long delta ) + { + if ( table ) + { + FT_MemNode *pnode, node; + + + pnode = ft_mem_table_get_nodep( table, address ); + node = *pnode; + if ( node ) + { + FT_MemSource source; + + + if ( node->size < 0 ) + ft_mem_debug_panic( + "freeing memory block at %p more than once at (%s:%ld)\n" + "block allocated at (%s:%ld) and released at (%s:%ld)", + address, + FT_FILENAME( _ft_debug_file ), _ft_debug_lineno, + FT_FILENAME( node->source->file_name ), node->source->line_no, + FT_FILENAME( node->free_file_name ), node->free_line_no ); + + /* scramble the node's content for additional safety */ + FT_MEM_SET( address, 0xF3, node->size ); + + if ( delta == 0 ) + { + source = node->source; + + source->cur_blocks--; + source->cur_size -= node->size; + + table->alloc_current -= node->size; + } + + if ( table->keep_alive ) + { + /* we simply invert the node's size to indicate that the node */ + /* was freed. */ + node->size = -node->size; + node->free_file_name = _ft_debug_file; + node->free_line_no = _ft_debug_lineno; + } + else + { + table->nodes--; + + *pnode = node->link; + + node->size = 0; + node->source = NULL; + + ft_mem_table_free( table, node ); + + if ( table->nodes * 3 < table->size || + table->size * 3 < table->nodes ) + ft_mem_table_resize( table ); + } + } + else + ft_mem_debug_panic( + "trying to free unknown block at %p in (%s:%ld)\n", + address, + FT_FILENAME( _ft_debug_file ), _ft_debug_lineno ); + } + } + + + extern FT_Pointer + ft_mem_debug_alloc( FT_Memory memory, + FT_Long size ) + { + FT_MemTable table = (FT_MemTable)memory->user; + FT_Byte* block; + + + if ( size <= 0 ) + ft_mem_debug_panic( "negative block size allocation (%ld)", size ); + + /* return NULL if the maximum number of allocations was reached */ + if ( table->bound_count && + table->alloc_count >= table->alloc_count_max ) + return NULL; + + /* return NULL if this allocation would overflow the maximum heap size */ + if ( table->bound_total && + table->alloc_total_max - table->alloc_current > (FT_ULong)size ) + return NULL; + + block = (FT_Byte *)ft_mem_table_alloc( table, size ); + if ( block ) + { + ft_mem_table_set( table, block, (FT_ULong)size, 0 ); + + table->alloc_count++; + } + + _ft_debug_file = "<unknown>"; + _ft_debug_lineno = 0; + + return (FT_Pointer)block; + } + + + extern void + ft_mem_debug_free( FT_Memory memory, + FT_Pointer block ) + { + FT_MemTable table = (FT_MemTable)memory->user; + + + if ( block == NULL ) + ft_mem_debug_panic( "trying to free NULL in (%s:%ld)", + FT_FILENAME( _ft_debug_file ), + _ft_debug_lineno ); + + ft_mem_table_remove( table, (FT_Byte*)block, 0 ); + + if ( !table->keep_alive ) + ft_mem_table_free( table, block ); + + table->alloc_count--; + + _ft_debug_file = "<unknown>"; + _ft_debug_lineno = 0; + } + + + extern FT_Pointer + ft_mem_debug_realloc( FT_Memory memory, + FT_Long cur_size, + FT_Long new_size, + FT_Pointer block ) + { + FT_MemTable table = (FT_MemTable)memory->user; + FT_MemNode node, *pnode; + FT_Pointer new_block; + FT_Long delta; + + const char* file_name = FT_FILENAME( _ft_debug_file ); + FT_Long line_no = _ft_debug_lineno; + + + /* unlikely, but possible */ + if ( new_size == cur_size ) + return block; + + /* the following is valid according to ANSI C */ +#if 0 + if ( block == NULL || cur_size == 0 ) + ft_mem_debug_panic( "trying to reallocate NULL in (%s:%ld)", + file_name, line_no ); +#endif + + /* while the following is allowed in ANSI C also, we abort since */ + /* such case should be handled by FreeType. */ + if ( new_size <= 0 ) + ft_mem_debug_panic( + "trying to reallocate %p to size 0 (current is %ld) in (%s:%ld)", + block, cur_size, file_name, line_no ); + + /* check `cur_size' value */ + pnode = ft_mem_table_get_nodep( table, (FT_Byte*)block ); + node = *pnode; + if ( !node ) + ft_mem_debug_panic( + "trying to reallocate unknown block at %p in (%s:%ld)", + block, file_name, line_no ); + + if ( node->size <= 0 ) + ft_mem_debug_panic( + "trying to reallocate freed block at %p in (%s:%ld)", + block, file_name, line_no ); + + if ( node->size != cur_size ) + ft_mem_debug_panic( "invalid ft_realloc request for %p. cur_size is " + "%ld instead of %ld in (%s:%ld)", + block, cur_size, node->size, file_name, line_no ); + + /* return NULL if the maximum number of allocations was reached */ + if ( table->bound_count && + table->alloc_count >= table->alloc_count_max ) + return NULL; + + delta = (FT_Long)( new_size - cur_size ); + + /* return NULL if this allocation would overflow the maximum heap size */ + if ( delta > 0 && + table->bound_total && + table->alloc_current + (FT_ULong)delta > table->alloc_total_max ) + return NULL; + + new_block = (FT_Byte *)ft_mem_table_alloc( table, new_size ); + if ( new_block == NULL ) + return NULL; + + ft_mem_table_set( table, (FT_Byte*)new_block, new_size, delta ); + + ft_memcpy( new_block, block, cur_size < new_size ? cur_size : new_size ); + + ft_mem_table_remove( table, (FT_Byte*)block, delta ); + + _ft_debug_file = "<unknown>"; + _ft_debug_lineno = 0; + + if ( !table->keep_alive ) + ft_mem_table_free( table, block ); + + return new_block; + } + + + extern FT_Int + ft_mem_debug_init( FT_Memory memory ) + { + FT_MemTable table; + FT_Int result = 0; + + + if ( getenv( "FT2_DEBUG_MEMORY" ) ) + { + table = ft_mem_table_new( memory ); + if ( table ) + { + const char* p; + + + memory->user = table; + memory->alloc = ft_mem_debug_alloc; + memory->realloc = ft_mem_debug_realloc; + memory->free = ft_mem_debug_free; + + p = getenv( "FT2_ALLOC_TOTAL_MAX" ); + if ( p != NULL ) + { + FT_Long total_max = ft_atol( p ); + + + if ( total_max > 0 ) + { + table->bound_total = 1; + table->alloc_total_max = (FT_ULong)total_max; + } + } + + p = getenv( "FT2_ALLOC_COUNT_MAX" ); + if ( p != NULL ) + { + FT_Long total_count = ft_atol( p ); + + + if ( total_count > 0 ) + { + table->bound_count = 1; + table->alloc_count_max = (FT_ULong)total_count; + } + } + + p = getenv( "FT2_KEEP_ALIVE" ); + if ( p != NULL ) + { + FT_Long keep_alive = ft_atol( p ); + + + if ( keep_alive > 0 ) + table->keep_alive = 1; + } + + result = 1; + } + } + return result; + } + + + extern void + ft_mem_debug_done( FT_Memory memory ) + { + FT_MemTable table = (FT_MemTable)memory->user; + + + if ( table ) + { + memory->free = table->free; + memory->realloc = table->realloc; + memory->alloc = table->alloc; + + ft_mem_table_destroy( table ); + memory->user = NULL; + } + } + + + + static int + ft_mem_source_compare( const void* p1, + const void* p2 ) + { + FT_MemSource s1 = *(FT_MemSource*)p1; + FT_MemSource s2 = *(FT_MemSource*)p2; + + + if ( s2->max_size > s1->max_size ) + return 1; + else if ( s2->max_size < s1->max_size ) + return -1; + else + return 0; + } + + + extern void + FT_DumpMemory( FT_Memory memory ) + { + FT_MemTable table = (FT_MemTable)memory->user; + + + if ( table ) + { + FT_MemSource* bucket = table->sources; + FT_MemSource* limit = bucket + FT_MEM_SOURCE_BUCKETS; + FT_MemSource* sources; + FT_UInt nn, count; + const char* fmt; + + + count = 0; + for ( ; bucket < limit; bucket++ ) + { + FT_MemSource source = *bucket; + + + for ( ; source; source = source->link ) + count++; + } + + sources = (FT_MemSource*)ft_mem_table_alloc( + table, sizeof ( *sources ) * count ); + + count = 0; + for ( bucket = table->sources; bucket < limit; bucket++ ) + { + FT_MemSource source = *bucket; + + + for ( ; source; source = source->link ) + sources[count++] = source; + } + + ft_qsort( sources, count, sizeof ( *sources ), ft_mem_source_compare ); + + printf( "FreeType Memory Dump: " + "current=%ld max=%ld total=%ld count=%ld\n", + table->alloc_current, table->alloc_max, + table->alloc_total, table->alloc_count ); + printf( " block block sizes sizes sizes source\n" ); + printf( " count high sum highsum max location\n" ); + printf( "-------------------------------------------------\n" ); + + fmt = "%6ld %6ld %8ld %8ld %8ld %s:%d\n"; + + for ( nn = 0; nn < count; nn++ ) + { + FT_MemSource source = sources[nn]; + + + printf( fmt, + source->cur_blocks, source->max_blocks, + source->cur_size, source->max_size, source->cur_max, + FT_FILENAME( source->file_name ), + source->line_no ); + } + printf( "------------------------------------------------\n" ); + + ft_mem_table_free( table, sources ); + } + } + +#else /* !FT_DEBUG_MEMORY */ + + /* ANSI C doesn't like empty source files */ + static const FT_Byte _debug_mem_dummy = 0; + +#endif /* !FT_DEBUG_MEMORY */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/base/ftdebug.c b/mod/pub.mod/freetype.mod/src/base/ftdebug.c new file mode 100644 index 0000000..2adbeab --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/base/ftdebug.c @@ -0,0 +1,246 @@ +/***************************************************************************/ +/* */ +/* ftdebug.c */ +/* */ +/* Debugging and logging component (body). */ +/* */ +/* Copyright 1996-2001, 2002, 2004, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This component contains various macros and functions used to ease the */ + /* debugging of the FreeType engine. Its main purpose is in assertion */ + /* checking, tracing, and error detection. */ + /* */ + /* There are now three debugging modes: */ + /* */ + /* - trace mode */ + /* */ + /* Error and trace messages are sent to the log file (which can be the */ + /* standard error output). */ + /* */ + /* - error mode */ + /* */ + /* Only error messages are generated. */ + /* */ + /* - release mode: */ + /* */ + /* No error message is sent or generated. The code is free from any */ + /* debugging parts. */ + /* */ + /*************************************************************************/ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_INTERNAL_DEBUG_H + + +#ifdef FT_DEBUG_LEVEL_ERROR + + /* documentation is in ftdebug.h */ + + FT_BASE_DEF( void ) + FT_Message( const char* fmt, ... ) + { + va_list ap; + + + va_start( ap, fmt ); + vfprintf( stderr, fmt, ap ); + va_end( ap ); + } + + + /* documentation is in ftdebug.h */ + + FT_BASE_DEF( void ) + FT_Panic( const char* fmt, ... ) + { + va_list ap; + + + va_start( ap, fmt ); + vfprintf( stderr, fmt, ap ); + va_end( ap ); + + exit( EXIT_FAILURE ); + } + +#endif /* FT_DEBUG_LEVEL_ERROR */ + + + +#ifdef FT_DEBUG_LEVEL_TRACE + + /* array of trace levels, initialized to 0 */ + int ft_trace_levels[trace_count]; + + + /* define array of trace toggle names */ +#define FT_TRACE_DEF( x ) #x , + + static const char* ft_trace_toggles[trace_count + 1] = + { +#include FT_INTERNAL_TRACE_H + NULL + }; + +#undef FT_TRACE_DEF + + + /* documentation is in ftdebug.h */ + + FT_BASE_DEF( FT_Int ) + FT_Trace_Get_Count( void ) + { + return trace_count; + } + + + /* documentation is in ftdebug.h */ + + FT_BASE_DEF( const char * ) + FT_Trace_Get_Name( FT_Int idx ) + { + int max = FT_Trace_Get_Count(); + + + if ( idx < max ) + return ft_trace_toggles[idx]; + else + return NULL; + } + + + /*************************************************************************/ + /* */ + /* Initialize the tracing sub-system. This is done by retrieving the */ + /* value of the `FT2_DEBUG' environment variable. It must be a list of */ + /* toggles, separated by spaces, `;', or `,'. Example: */ + /* */ + /* export FT2_DEBUG="any:3 memory:7 stream:5" */ + /* */ + /* This requests that all levels be set to 3, except the trace level for */ + /* the memory and stream components which are set to 7 and 5, */ + /* respectively. */ + /* */ + /* See the file <include/freetype/internal/fttrace.h> for details of the */ + /* available toggle names. */ + /* */ + /* The level must be between 0 and 7; 0 means quiet (except for serious */ + /* runtime errors), and 7 means _very_ verbose. */ + /* */ + FT_BASE_DEF( void ) + ft_debug_init( void ) + { + const char* ft2_debug = getenv( "FT2_DEBUG" ); + + + if ( ft2_debug ) + { + const char* p = ft2_debug; + const char* q; + + + for ( ; *p; p++ ) + { + /* skip leading whitespace and separators */ + if ( *p == ' ' || *p == '\t' || *p == ',' || *p == ';' || *p == '=' ) + continue; + + /* read toggle name, followed by ':' */ + q = p; + while ( *p && *p != ':' ) + p++; + + if ( *p == ':' && p > q ) + { + FT_Int n, i, len = (FT_Int)( p - q ); + FT_Int level = -1, found = -1; + + + for ( n = 0; n < trace_count; n++ ) + { + const char* toggle = ft_trace_toggles[n]; + + + for ( i = 0; i < len; i++ ) + { + if ( toggle[i] != q[i] ) + break; + } + + if ( i == len && toggle[i] == 0 ) + { + found = n; + break; + } + } + + /* read level */ + p++; + if ( *p ) + { + level = *p++ - '0'; + if ( level < 0 || level > 7 ) + level = -1; + } + + if ( found >= 0 && level >= 0 ) + { + if ( found == trace_any ) + { + /* special case for `any' */ + for ( n = 0; n < trace_count; n++ ) + ft_trace_levels[n] = level; + } + else + ft_trace_levels[found] = level; + } + } + } + } + } + + +#else /* !FT_DEBUG_LEVEL_TRACE */ + + + FT_BASE_DEF( void ) + ft_debug_init( void ) + { + /* nothing */ + } + + + FT_BASE_DEF( FT_Int ) + FT_Trace_Get_Count( void ) + { + return 0; + } + + + FT_BASE_DEF( const char * ) + FT_Trace_Get_Name( FT_Int idx ) + { + FT_UNUSED( idx ); + + return NULL; + } + + +#endif /* !FT_DEBUG_LEVEL_TRACE */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/base/ftfstype.c b/mod/pub.mod/freetype.mod/src/base/ftfstype.c new file mode 100644 index 0000000..d0ef7b7 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/base/ftfstype.c @@ -0,0 +1,62 @@ +/***************************************************************************/ +/* */ +/* ftfstype.c */ +/* */ +/* FreeType utility file to access FSType data (body). */ +/* */ +/* Copyright 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + +#include <ft2build.h> +#include FT_TYPE1_TABLES_H +#include FT_TRUETYPE_TABLES_H +#include FT_INTERNAL_SERVICE_H +#include FT_SERVICE_POSTSCRIPT_INFO_H + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_UShort ) + FT_Get_FSType_Flags( FT_Face face ) + { + TT_OS2* os2; + + + /* first, try to get the fs_type directly from the font */ + if ( face ) + { + FT_Service_PsInfo service = NULL; + + + FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO ); + + if ( service && service->ps_get_font_extra ) + { + PS_FontExtraRec extra; + + + if ( !service->ps_get_font_extra( face, &extra ) && + extra.fs_type != 0 ) + return extra.fs_type; + } + } + + /* look at FSType before fsType for Type42 */ + + if ( ( os2 = (TT_OS2*)FT_Get_Sfnt_Table( face, ft_sfnt_os2 ) ) != NULL && + os2->version != 0xFFFFU ) + return os2->fsType; + + return 0; + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/base/ftgasp.c b/mod/pub.mod/freetype.mod/src/base/ftgasp.c new file mode 100644 index 0000000..8485d29 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/base/ftgasp.c @@ -0,0 +1,61 @@ +/***************************************************************************/ +/* */ +/* ftgasp.c */ +/* */ +/* Access of TrueType's `gasp' table (body). */ +/* */ +/* Copyright 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_GASP_H +#include FT_INTERNAL_TRUETYPE_TYPES_H + + + FT_EXPORT_DEF( FT_Int ) + FT_Get_Gasp( FT_Face face, + FT_UInt ppem ) + { + FT_Int result = FT_GASP_NO_TABLE; + + + if ( face && FT_IS_SFNT( face ) ) + { + TT_Face ttface = (TT_Face)face; + + + if ( ttface->gasp.numRanges > 0 ) + { + TT_GaspRange range = ttface->gasp.gaspRanges; + TT_GaspRange range_end = range + ttface->gasp.numRanges; + + + while ( ppem > range->maxPPEM ) + { + range++; + if ( range >= range_end ) + goto Exit; + } + + result = range->gaspFlag; + + /* ensure that we don't have spurious bits */ + if ( ttface->gasp.version == 0 ) + result &= 3; + } + } + Exit: + return result; + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/base/ftgloadr.c b/mod/pub.mod/freetype.mod/src/base/ftgloadr.c new file mode 100644 index 0000000..ac0010d --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/base/ftgloadr.c @@ -0,0 +1,401 @@ +/***************************************************************************/ +/* */ +/* ftgloadr.c */ +/* */ +/* The FreeType glyph loader (body). */ +/* */ +/* Copyright 2002, 2003, 2004, 2005, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_GLYPH_LOADER_H +#include FT_INTERNAL_MEMORY_H +#include FT_INTERNAL_OBJECTS_H + +#undef FT_COMPONENT +#define FT_COMPONENT trace_gloader + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** *****/ + /***** G L Y P H L O A D E R *****/ + /***** *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* The glyph loader is a simple object which is used to load a set of */ + /* glyphs easily. It is critical for the correct loading of composites. */ + /* */ + /* Ideally, one can see it as a stack of abstract `glyph' objects. */ + /* */ + /* loader.base Is really the bottom of the stack. It describes a */ + /* single glyph image made of the juxtaposition of */ + /* several glyphs (those `in the stack'). */ + /* */ + /* loader.current Describes the top of the stack, on which a new */ + /* glyph can be loaded. */ + /* */ + /* Rewind Clears the stack. */ + /* Prepare Set up `loader.current' for addition of a new glyph */ + /* image. */ + /* Add Add the `current' glyph image to the `base' one, */ + /* and prepare for another one. */ + /* */ + /* The glyph loader is now a base object. Each driver used to */ + /* re-implement it in one way or the other, which wasted code and */ + /* energy. */ + /* */ + /*************************************************************************/ + + + /* create a new glyph loader */ + FT_BASE_DEF( FT_Error ) + FT_GlyphLoader_New( FT_Memory memory, + FT_GlyphLoader *aloader ) + { + FT_GlyphLoader loader; + FT_Error error; + + + if ( !FT_NEW( loader ) ) + { + loader->memory = memory; + *aloader = loader; + } + return error; + } + + + /* rewind the glyph loader - reset counters to 0 */ + FT_BASE_DEF( void ) + FT_GlyphLoader_Rewind( FT_GlyphLoader loader ) + { + FT_GlyphLoad base = &loader->base; + FT_GlyphLoad current = &loader->current; + + + base->outline.n_points = 0; + base->outline.n_contours = 0; + base->num_subglyphs = 0; + + *current = *base; + } + + + /* reset the glyph loader, frees all allocated tables */ + /* and starts from zero */ + FT_BASE_DEF( void ) + FT_GlyphLoader_Reset( FT_GlyphLoader loader ) + { + FT_Memory memory = loader->memory; + + + FT_FREE( loader->base.outline.points ); + FT_FREE( loader->base.outline.tags ); + FT_FREE( loader->base.outline.contours ); + FT_FREE( loader->base.extra_points ); + FT_FREE( loader->base.subglyphs ); + + loader->base.extra_points2 = NULL; + + loader->max_points = 0; + loader->max_contours = 0; + loader->max_subglyphs = 0; + + FT_GlyphLoader_Rewind( loader ); + } + + + /* delete a glyph loader */ + FT_BASE_DEF( void ) + FT_GlyphLoader_Done( FT_GlyphLoader loader ) + { + if ( loader ) + { + FT_Memory memory = loader->memory; + + + FT_GlyphLoader_Reset( loader ); + FT_FREE( loader ); + } + } + + + /* re-adjust the `current' outline fields */ + static void + FT_GlyphLoader_Adjust_Points( FT_GlyphLoader loader ) + { + FT_Outline* base = &loader->base.outline; + FT_Outline* current = &loader->current.outline; + + + current->points = base->points + base->n_points; + current->tags = base->tags + base->n_points; + current->contours = base->contours + base->n_contours; + + /* handle extra points table - if any */ + if ( loader->use_extra ) + { + loader->current.extra_points = loader->base.extra_points + + base->n_points; + + loader->current.extra_points2 = loader->base.extra_points2 + + base->n_points; + } + } + + + FT_BASE_DEF( FT_Error ) + FT_GlyphLoader_CreateExtra( FT_GlyphLoader loader ) + { + FT_Error error; + FT_Memory memory = loader->memory; + + + if ( !FT_NEW_ARRAY( loader->base.extra_points, 2 * loader->max_points ) ) + { + loader->use_extra = 1; + loader->base.extra_points2 = loader->base.extra_points + + loader->max_points; + + FT_GlyphLoader_Adjust_Points( loader ); + } + return error; + } + + + /* re-adjust the `current' subglyphs field */ + static void + FT_GlyphLoader_Adjust_Subglyphs( FT_GlyphLoader loader ) + { + FT_GlyphLoad base = &loader->base; + FT_GlyphLoad current = &loader->current; + + + current->subglyphs = base->subglyphs + base->num_subglyphs; + } + + + /* Ensure that we can add `n_points' and `n_contours' to our glyph. */ + /* This function reallocates its outline tables if necessary. Note that */ + /* it DOESN'T change the number of points within the loader! */ + /* */ + FT_BASE_DEF( FT_Error ) + FT_GlyphLoader_CheckPoints( FT_GlyphLoader loader, + FT_UInt n_points, + FT_UInt n_contours ) + { + FT_Memory memory = loader->memory; + FT_Error error = FT_Err_Ok; + FT_Outline* base = &loader->base.outline; + FT_Outline* current = &loader->current.outline; + FT_Bool adjust = 0; + + FT_UInt new_max, old_max; + + + /* check points & tags */ + new_max = base->n_points + current->n_points + n_points; + old_max = loader->max_points; + + if ( new_max > old_max ) + { + new_max = FT_PAD_CEIL( new_max, 8 ); + + if ( new_max > FT_OUTLINE_POINTS_MAX ) + return FT_Err_Array_Too_Large; + + if ( FT_RENEW_ARRAY( base->points, old_max, new_max ) || + FT_RENEW_ARRAY( base->tags, old_max, new_max ) ) + goto Exit; + + if ( loader->use_extra ) + { + if ( FT_RENEW_ARRAY( loader->base.extra_points, + old_max * 2, new_max * 2 ) ) + goto Exit; + + FT_ARRAY_MOVE( loader->base.extra_points + new_max, + loader->base.extra_points + old_max, + old_max ); + + loader->base.extra_points2 = loader->base.extra_points + new_max; + } + + adjust = 1; + loader->max_points = new_max; + } + + /* check contours */ + old_max = loader->max_contours; + new_max = base->n_contours + current->n_contours + + n_contours; + if ( new_max > old_max ) + { + new_max = FT_PAD_CEIL( new_max, 4 ); + + if ( new_max > FT_OUTLINE_CONTOURS_MAX ) + return FT_Err_Array_Too_Large; + + if ( FT_RENEW_ARRAY( base->contours, old_max, new_max ) ) + goto Exit; + + adjust = 1; + loader->max_contours = new_max; + } + + if ( adjust ) + FT_GlyphLoader_Adjust_Points( loader ); + + Exit: + return error; + } + + + /* Ensure that we can add `n_subglyphs' to our glyph. this function */ + /* reallocates its subglyphs table if necessary. Note that it DOES */ + /* NOT change the number of subglyphs within the loader! */ + /* */ + FT_BASE_DEF( FT_Error ) + FT_GlyphLoader_CheckSubGlyphs( FT_GlyphLoader loader, + FT_UInt n_subs ) + { + FT_Memory memory = loader->memory; + FT_Error error = FT_Err_Ok; + FT_UInt new_max, old_max; + + FT_GlyphLoad base = &loader->base; + FT_GlyphLoad current = &loader->current; + + + new_max = base->num_subglyphs + current->num_subglyphs + n_subs; + old_max = loader->max_subglyphs; + if ( new_max > old_max ) + { + new_max = FT_PAD_CEIL( new_max, 2 ); + if ( FT_RENEW_ARRAY( base->subglyphs, old_max, new_max ) ) + goto Exit; + + loader->max_subglyphs = new_max; + + FT_GlyphLoader_Adjust_Subglyphs( loader ); + } + + Exit: + return error; + } + + + /* prepare loader for the addition of a new glyph on top of the base one */ + FT_BASE_DEF( void ) + FT_GlyphLoader_Prepare( FT_GlyphLoader loader ) + { + FT_GlyphLoad current = &loader->current; + + + current->outline.n_points = 0; + current->outline.n_contours = 0; + current->num_subglyphs = 0; + + FT_GlyphLoader_Adjust_Points ( loader ); + FT_GlyphLoader_Adjust_Subglyphs( loader ); + } + + + /* add current glyph to the base image - and prepare for another */ + FT_BASE_DEF( void ) + FT_GlyphLoader_Add( FT_GlyphLoader loader ) + { + FT_GlyphLoad base; + FT_GlyphLoad current; + + FT_UInt n_curr_contours; + FT_UInt n_base_points; + FT_UInt n; + + + if ( !loader ) + return; + + base = &loader->base; + current = &loader->current; + + n_curr_contours = current->outline.n_contours; + n_base_points = base->outline.n_points; + + base->outline.n_points = + (short)( base->outline.n_points + current->outline.n_points ); + base->outline.n_contours = + (short)( base->outline.n_contours + current->outline.n_contours ); + + base->num_subglyphs += current->num_subglyphs; + + /* adjust contours count in newest outline */ + for ( n = 0; n < n_curr_contours; n++ ) + current->outline.contours[n] = + (short)( current->outline.contours[n] + n_base_points ); + + /* prepare for another new glyph image */ + FT_GlyphLoader_Prepare( loader ); + } + + + FT_BASE_DEF( FT_Error ) + FT_GlyphLoader_CopyPoints( FT_GlyphLoader target, + FT_GlyphLoader source ) + { + FT_Error error; + FT_UInt num_points = source->base.outline.n_points; + FT_UInt num_contours = source->base.outline.n_contours; + + + error = FT_GlyphLoader_CheckPoints( target, num_points, num_contours ); + if ( !error ) + { + FT_Outline* out = &target->base.outline; + FT_Outline* in = &source->base.outline; + + + FT_ARRAY_COPY( out->points, in->points, + num_points ); + FT_ARRAY_COPY( out->tags, in->tags, + num_points ); + FT_ARRAY_COPY( out->contours, in->contours, + num_contours ); + + /* do we need to copy the extra points? */ + if ( target->use_extra && source->use_extra ) + { + FT_ARRAY_COPY( target->base.extra_points, source->base.extra_points, + num_points ); + FT_ARRAY_COPY( target->base.extra_points2, source->base.extra_points2, + num_points ); + } + + out->n_points = (short)num_points; + out->n_contours = (short)num_contours; + + FT_GlyphLoader_Adjust_Points( target ); + } + + return error; + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/base/ftglyph.c b/mod/pub.mod/freetype.mod/src/base/ftglyph.c new file mode 100644 index 0000000..ef61d45 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/base/ftglyph.c @@ -0,0 +1,623 @@ +/***************************************************************************/ +/* */ +/* ftglyph.c */ +/* */ +/* FreeType convenience functions to handle glyphs (body). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2007, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + /*************************************************************************/ + /* */ + /* This file contains the definition of several convenience functions */ + /* that can be used by client applications to easily retrieve glyph */ + /* bitmaps and outlines from a given face. */ + /* */ + /* These functions should be optional if you are writing a font server */ + /* or text layout engine on top of FreeType. However, they are pretty */ + /* handy for many other simple uses of the library. */ + /* */ + /*************************************************************************/ + + +#include <ft2build.h> +#include FT_GLYPH_H +#include FT_OUTLINE_H +#include FT_BITMAP_H +#include FT_INTERNAL_OBJECTS_H + +#include "basepic.h" + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_glyph + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** FT_BitmapGlyph support ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_CALLBACK_DEF( FT_Error ) + ft_bitmap_glyph_init( FT_Glyph bitmap_glyph, + FT_GlyphSlot slot ) + { + FT_BitmapGlyph glyph = (FT_BitmapGlyph)bitmap_glyph; + FT_Error error = FT_Err_Ok; + FT_Library library = FT_GLYPH( glyph )->library; + + + if ( slot->format != FT_GLYPH_FORMAT_BITMAP ) + { + error = FT_Err_Invalid_Glyph_Format; + goto Exit; + } + + glyph->left = slot->bitmap_left; + glyph->top = slot->bitmap_top; + + /* do lazy copying whenever possible */ + if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) + { + glyph->bitmap = slot->bitmap; + slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; + } + else + { + FT_Bitmap_New( &glyph->bitmap ); + error = FT_Bitmap_Copy( library, &slot->bitmap, &glyph->bitmap ); + } + + Exit: + return error; + } + + + FT_CALLBACK_DEF( FT_Error ) + ft_bitmap_glyph_copy( FT_Glyph bitmap_source, + FT_Glyph bitmap_target ) + { + FT_Library library = bitmap_source->library; + FT_BitmapGlyph source = (FT_BitmapGlyph)bitmap_source; + FT_BitmapGlyph target = (FT_BitmapGlyph)bitmap_target; + + + target->left = source->left; + target->top = source->top; + + return FT_Bitmap_Copy( library, &source->bitmap, &target->bitmap ); + } + + + FT_CALLBACK_DEF( void ) + ft_bitmap_glyph_done( FT_Glyph bitmap_glyph ) + { + FT_BitmapGlyph glyph = (FT_BitmapGlyph)bitmap_glyph; + FT_Library library = FT_GLYPH( glyph )->library; + + + FT_Bitmap_Done( library, &glyph->bitmap ); + } + + + FT_CALLBACK_DEF( void ) + ft_bitmap_glyph_bbox( FT_Glyph bitmap_glyph, + FT_BBox* cbox ) + { + FT_BitmapGlyph glyph = (FT_BitmapGlyph)bitmap_glyph; + + + cbox->xMin = glyph->left << 6; + cbox->xMax = cbox->xMin + ( glyph->bitmap.width << 6 ); + cbox->yMax = glyph->top << 6; + cbox->yMin = cbox->yMax - ( glyph->bitmap.rows << 6 ); + } + + + FT_DEFINE_GLYPH(ft_bitmap_glyph_class, + sizeof ( FT_BitmapGlyphRec ), + FT_GLYPH_FORMAT_BITMAP, + + ft_bitmap_glyph_init, + ft_bitmap_glyph_done, + ft_bitmap_glyph_copy, + 0, /* FT_Glyph_TransformFunc */ + ft_bitmap_glyph_bbox, + 0 /* FT_Glyph_PrepareFunc */ + ) + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** FT_OutlineGlyph support ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + + FT_CALLBACK_DEF( FT_Error ) + ft_outline_glyph_init( FT_Glyph outline_glyph, + FT_GlyphSlot slot ) + { + FT_OutlineGlyph glyph = (FT_OutlineGlyph)outline_glyph; + FT_Error error = FT_Err_Ok; + FT_Library library = FT_GLYPH( glyph )->library; + FT_Outline* source = &slot->outline; + FT_Outline* target = &glyph->outline; + + + /* check format in glyph slot */ + if ( slot->format != FT_GLYPH_FORMAT_OUTLINE ) + { + error = FT_Err_Invalid_Glyph_Format; + goto Exit; + } + + /* allocate new outline */ + error = FT_Outline_New( library, source->n_points, source->n_contours, + &glyph->outline ); + if ( error ) + goto Exit; + + FT_Outline_Copy( source, target ); + + Exit: + return error; + } + + + FT_CALLBACK_DEF( void ) + ft_outline_glyph_done( FT_Glyph outline_glyph ) + { + FT_OutlineGlyph glyph = (FT_OutlineGlyph)outline_glyph; + + + FT_Outline_Done( FT_GLYPH( glyph )->library, &glyph->outline ); + } + + + FT_CALLBACK_DEF( FT_Error ) + ft_outline_glyph_copy( FT_Glyph outline_source, + FT_Glyph outline_target ) + { + FT_OutlineGlyph source = (FT_OutlineGlyph)outline_source; + FT_OutlineGlyph target = (FT_OutlineGlyph)outline_target; + FT_Error error; + FT_Library library = FT_GLYPH( source )->library; + + + error = FT_Outline_New( library, source->outline.n_points, + source->outline.n_contours, &target->outline ); + if ( !error ) + FT_Outline_Copy( &source->outline, &target->outline ); + + return error; + } + + + FT_CALLBACK_DEF( void ) + ft_outline_glyph_transform( FT_Glyph outline_glyph, + const FT_Matrix* matrix, + const FT_Vector* delta ) + { + FT_OutlineGlyph glyph = (FT_OutlineGlyph)outline_glyph; + + + if ( matrix ) + FT_Outline_Transform( &glyph->outline, matrix ); + + if ( delta ) + FT_Outline_Translate( &glyph->outline, delta->x, delta->y ); + } + + + FT_CALLBACK_DEF( void ) + ft_outline_glyph_bbox( FT_Glyph outline_glyph, + FT_BBox* bbox ) + { + FT_OutlineGlyph glyph = (FT_OutlineGlyph)outline_glyph; + + + FT_Outline_Get_CBox( &glyph->outline, bbox ); + } + + + FT_CALLBACK_DEF( FT_Error ) + ft_outline_glyph_prepare( FT_Glyph outline_glyph, + FT_GlyphSlot slot ) + { + FT_OutlineGlyph glyph = (FT_OutlineGlyph)outline_glyph; + + + slot->format = FT_GLYPH_FORMAT_OUTLINE; + slot->outline = glyph->outline; + slot->outline.flags &= ~FT_OUTLINE_OWNER; + + return FT_Err_Ok; + } + + + FT_DEFINE_GLYPH( ft_outline_glyph_class, + sizeof ( FT_OutlineGlyphRec ), + FT_GLYPH_FORMAT_OUTLINE, + + ft_outline_glyph_init, + ft_outline_glyph_done, + ft_outline_glyph_copy, + ft_outline_glyph_transform, + ft_outline_glyph_bbox, + ft_outline_glyph_prepare + ) + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** FT_Glyph class and API ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + static FT_Error + ft_new_glyph( FT_Library library, + const FT_Glyph_Class* clazz, + FT_Glyph* aglyph ) + { + FT_Memory memory = library->memory; + FT_Error error; + FT_Glyph glyph; + + + *aglyph = 0; + + if ( !FT_ALLOC( glyph, clazz->glyph_size ) ) + { + glyph->library = library; + glyph->clazz = clazz; + glyph->format = clazz->glyph_format; + + *aglyph = glyph; + } + + return error; + } + + + /* documentation is in ftglyph.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Glyph_Copy( FT_Glyph source, + FT_Glyph *target ) + { + FT_Glyph copy; + FT_Error error; + const FT_Glyph_Class* clazz; + + + /* check arguments */ + if ( !target ) + { + error = FT_Err_Invalid_Argument; + goto Exit; + } + + *target = 0; + + if ( !source || !source->clazz ) + { + error = FT_Err_Invalid_Argument; + goto Exit; + } + + clazz = source->clazz; + error = ft_new_glyph( source->library, clazz, © ); + if ( error ) + goto Exit; + + copy->advance = source->advance; + copy->format = source->format; + + if ( clazz->glyph_copy ) + error = clazz->glyph_copy( source, copy ); + + if ( error ) + FT_Done_Glyph( copy ); + else + *target = copy; + + Exit: + return error; + } + + + /* documentation is in ftglyph.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_Glyph( FT_GlyphSlot slot, + FT_Glyph *aglyph ) + { + FT_Library library; + FT_Error error; + FT_Glyph glyph; + + const FT_Glyph_Class* clazz = 0; + + + if ( !slot ) + return FT_Err_Invalid_Slot_Handle; + + library = slot->library; + + if ( !aglyph ) + return FT_Err_Invalid_Argument; + + /* if it is a bitmap, that's easy :-) */ + if ( slot->format == FT_GLYPH_FORMAT_BITMAP ) + clazz = FT_BITMAP_GLYPH_CLASS_GET; + + /* it it is an outline too */ + else if ( slot->format == FT_GLYPH_FORMAT_OUTLINE ) + clazz = FT_OUTLINE_GLYPH_CLASS_GET; + + else + { + /* try to find a renderer that supports the glyph image format */ + FT_Renderer render = FT_Lookup_Renderer( library, slot->format, 0 ); + + + if ( render ) + clazz = &render->glyph_class; + } + + if ( !clazz ) + { + error = FT_Err_Invalid_Glyph_Format; + goto Exit; + } + + /* create FT_Glyph object */ + error = ft_new_glyph( library, clazz, &glyph ); + if ( error ) + goto Exit; + + /* copy advance while converting it to 16.16 format */ + glyph->advance.x = slot->advance.x << 10; + glyph->advance.y = slot->advance.y << 10; + + /* now import the image from the glyph slot */ + error = clazz->glyph_init( glyph, slot ); + + /* if an error occurred, destroy the glyph */ + if ( error ) + FT_Done_Glyph( glyph ); + else + *aglyph = glyph; + + Exit: + return error; + } + + + /* documentation is in ftglyph.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Glyph_Transform( FT_Glyph glyph, + FT_Matrix* matrix, + FT_Vector* delta ) + { + const FT_Glyph_Class* clazz; + FT_Error error = FT_Err_Ok; + + + if ( !glyph || !glyph->clazz ) + error = FT_Err_Invalid_Argument; + else + { + clazz = glyph->clazz; + if ( clazz->glyph_transform ) + { + /* transform glyph image */ + clazz->glyph_transform( glyph, matrix, delta ); + + /* transform advance vector */ + if ( matrix ) + FT_Vector_Transform( &glyph->advance, matrix ); + } + else + error = FT_Err_Invalid_Glyph_Format; + } + return error; + } + + + /* documentation is in ftglyph.h */ + + FT_EXPORT_DEF( void ) + FT_Glyph_Get_CBox( FT_Glyph glyph, + FT_UInt bbox_mode, + FT_BBox *acbox ) + { + const FT_Glyph_Class* clazz; + + + if ( !acbox ) + return; + + acbox->xMin = acbox->yMin = acbox->xMax = acbox->yMax = 0; + + if ( !glyph || !glyph->clazz ) + return; + else + { + clazz = glyph->clazz; + if ( !clazz->glyph_bbox ) + return; + else + { + /* retrieve bbox in 26.6 coordinates */ + clazz->glyph_bbox( glyph, acbox ); + + /* perform grid fitting if needed */ + if ( bbox_mode == FT_GLYPH_BBOX_GRIDFIT || + bbox_mode == FT_GLYPH_BBOX_PIXELS ) + { + acbox->xMin = FT_PIX_FLOOR( acbox->xMin ); + acbox->yMin = FT_PIX_FLOOR( acbox->yMin ); + acbox->xMax = FT_PIX_CEIL( acbox->xMax ); + acbox->yMax = FT_PIX_CEIL( acbox->yMax ); + } + + /* convert to integer pixels if needed */ + if ( bbox_mode == FT_GLYPH_BBOX_TRUNCATE || + bbox_mode == FT_GLYPH_BBOX_PIXELS ) + { + acbox->xMin >>= 6; + acbox->yMin >>= 6; + acbox->xMax >>= 6; + acbox->yMax >>= 6; + } + } + } + return; + } + + + /* documentation is in ftglyph.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Glyph_To_Bitmap( FT_Glyph* the_glyph, + FT_Render_Mode render_mode, + FT_Vector* origin, + FT_Bool destroy ) + { + FT_GlyphSlotRec dummy; + FT_GlyphSlot_InternalRec dummy_internal; + FT_Error error = FT_Err_Ok; + FT_Glyph glyph; + FT_BitmapGlyph bitmap = NULL; + + const FT_Glyph_Class* clazz; + + + /* check argument */ + if ( !the_glyph ) + goto Bad; + + /* we render the glyph into a glyph bitmap using a `dummy' glyph slot */ + /* then calling FT_Render_Glyph_Internal() */ + + glyph = *the_glyph; + if ( !glyph ) + goto Bad; + + clazz = glyph->clazz; + + /* when called with a bitmap glyph, do nothing and return successfully */ + if ( clazz == FT_BITMAP_GLYPH_CLASS_GET ) + goto Exit; + + if ( !clazz || !clazz->glyph_prepare ) + goto Bad; + + FT_MEM_ZERO( &dummy, sizeof ( dummy ) ); + FT_MEM_ZERO( &dummy_internal, sizeof ( dummy_internal ) ); + dummy.internal = &dummy_internal; + dummy.library = glyph->library; + dummy.format = clazz->glyph_format; + + /* create result bitmap glyph */ + error = ft_new_glyph( glyph->library, FT_BITMAP_GLYPH_CLASS_GET, + (FT_Glyph*)(void*)&bitmap ); + if ( error ) + goto Exit; + +#if 1 + /* if `origin' is set, translate the glyph image */ + if ( origin ) + FT_Glyph_Transform( glyph, 0, origin ); +#else + FT_UNUSED( origin ); +#endif + + /* prepare dummy slot for rendering */ + error = clazz->glyph_prepare( glyph, &dummy ); + if ( !error ) + error = FT_Render_Glyph_Internal( glyph->library, &dummy, render_mode ); + +#if 1 + if ( !destroy && origin ) + { + FT_Vector v; + + + v.x = -origin->x; + v.y = -origin->y; + FT_Glyph_Transform( glyph, 0, &v ); + } +#endif + + if ( error ) + goto Exit; + + /* in case of success, copy the bitmap to the glyph bitmap */ + error = ft_bitmap_glyph_init( (FT_Glyph)bitmap, &dummy ); + if ( error ) + goto Exit; + + /* copy advance */ + bitmap->root.advance = glyph->advance; + + if ( destroy ) + FT_Done_Glyph( glyph ); + + *the_glyph = FT_GLYPH( bitmap ); + + Exit: + if ( error && bitmap ) + FT_Done_Glyph( FT_GLYPH( bitmap ) ); + + return error; + + Bad: + error = FT_Err_Invalid_Argument; + goto Exit; + } + + + /* documentation is in ftglyph.h */ + + FT_EXPORT_DEF( void ) + FT_Done_Glyph( FT_Glyph glyph ) + { + if ( glyph ) + { + FT_Memory memory = glyph->library->memory; + const FT_Glyph_Class* clazz = glyph->clazz; + + + if ( clazz->glyph_done ) + clazz->glyph_done( glyph ); + + FT_FREE( glyph ); + } + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/base/ftgxval.c b/mod/pub.mod/freetype.mod/src/base/ftgxval.c new file mode 100644 index 0000000..32662be --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/base/ftgxval.c @@ -0,0 +1,129 @@ +/***************************************************************************/ +/* */ +/* ftgxval.c */ +/* */ +/* FreeType API for validating TrueTyepGX/AAT tables (body). */ +/* */ +/* Copyright 2004, 2005, 2006 by */ +/* Masatake YAMATO, Redhat K.K, */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + +/***************************************************************************/ +/* */ +/* gxvalid is derived from both gxlayout module and otvalid module. */ +/* Development of gxlayout is supported by the Information-technology */ +/* Promotion Agency(IPA), Japan. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H +#include FT_SERVICE_GX_VALIDATE_H + + + /* documentation is in ftgxval.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_TrueTypeGX_Validate( FT_Face face, + FT_UInt validation_flags, + FT_Bytes tables[FT_VALIDATE_GX_LENGTH], + FT_UInt table_length ) + { + FT_Service_GXvalidate service; + FT_Error error; + + + if ( !face ) + { + error = FT_Err_Invalid_Face_Handle; + goto Exit; + } + + if ( tables == NULL ) + { + error = FT_Err_Invalid_Argument; + goto Exit; + } + + FT_FACE_FIND_GLOBAL_SERVICE( face, service, GX_VALIDATE ); + + if ( service ) + error = service->validate( face, + validation_flags, + tables, + table_length ); + else + error = FT_Err_Unimplemented_Feature; + + Exit: + return error; + } + + + FT_EXPORT_DEF( void ) + FT_TrueTypeGX_Free( FT_Face face, + FT_Bytes table ) + { + FT_Memory memory = FT_FACE_MEMORY( face ); + + + FT_FREE( table ); + } + + + FT_EXPORT_DEF( FT_Error ) + FT_ClassicKern_Validate( FT_Face face, + FT_UInt validation_flags, + FT_Bytes *ckern_table ) + { + FT_Service_CKERNvalidate service; + FT_Error error; + + + if ( !face ) + { + error = FT_Err_Invalid_Face_Handle; + goto Exit; + } + + if ( ckern_table == NULL ) + { + error = FT_Err_Invalid_Argument; + goto Exit; + } + + FT_FACE_FIND_GLOBAL_SERVICE( face, service, CLASSICKERN_VALIDATE ); + + if ( service ) + error = service->validate( face, + validation_flags, + ckern_table ); + else + error = FT_Err_Unimplemented_Feature; + + Exit: + return error; + } + + + FT_EXPORT_DEF( void ) + FT_ClassicKern_Free( FT_Face face, + FT_Bytes table ) + { + FT_Memory memory = FT_FACE_MEMORY( face ); + + + FT_FREE( table ); + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/base/ftinit.c b/mod/pub.mod/freetype.mod/src/base/ftinit.c new file mode 100644 index 0000000..ef13503 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/base/ftinit.c @@ -0,0 +1,252 @@ +/***************************************************************************/ +/* */ +/* ftinit.c */ +/* */ +/* FreeType initialization layer (body). */ +/* */ +/* Copyright 1996-2001, 2002, 2005, 2007, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + /*************************************************************************/ + /* */ + /* The purpose of this file is to implement the following two */ + /* functions: */ + /* */ + /* FT_Add_Default_Modules(): */ + /* This function is used to add the set of default modules to a */ + /* fresh new library object. The set is taken from the header file */ + /* `freetype/config/ftmodule.h'. See the document `FreeType 2.0 */ + /* Build System' for more information. */ + /* */ + /* FT_Init_FreeType(): */ + /* This function creates a system object for the current platform, */ + /* builds a library out of it, then calls FT_Default_Drivers(). */ + /* */ + /* Note that even if FT_Init_FreeType() uses the implementation of the */ + /* system object defined at build time, client applications are still */ + /* able to provide their own `ftsystem.c'. */ + /* */ + /*************************************************************************/ + + +#include <ft2build.h> +#include FT_CONFIG_CONFIG_H +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_DEBUG_H +#include FT_MODULE_H +#include "basepic.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_init + +#ifndef FT_CONFIG_OPTION_PIC + +#undef FT_USE_MODULE +#ifdef __cplusplus +#define FT_USE_MODULE( type, x ) extern "C" const type x; +#else +#define FT_USE_MODULE( type, x ) extern const type x; +#endif + + +#include FT_CONFIG_MODULES_H + + +#undef FT_USE_MODULE +#define FT_USE_MODULE( type, x ) (const FT_Module_Class*)&(x), + + static + const FT_Module_Class* const ft_default_modules[] = + { +#include FT_CONFIG_MODULES_H + 0 + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#ifdef __cplusplus +#define FT_EXTERNC extern "C" +#else +#define FT_EXTERNC extern +#endif + + /* declare the module's class creation/destruction functions */ +#undef FT_USE_MODULE +#define FT_USE_MODULE( type, x ) \ + FT_EXTERNC FT_Error FT_Create_Class_##x( FT_Library library, FT_Module_Class** output_class ); \ + FT_EXTERNC void FT_Destroy_Class_##x( FT_Library library, FT_Module_Class* clazz ); + +#include FT_CONFIG_MODULES_H + + + /* count all module classes */ +#undef FT_USE_MODULE +#define FT_USE_MODULE( type, x ) MODULE_CLASS_##x, + + enum { +#include FT_CONFIG_MODULES_H + FT_NUM_MODULE_CLASSES + }; + + /* destroy all module classes */ +#undef FT_USE_MODULE +#define FT_USE_MODULE( type, x ) \ + if ( classes[i] ) { FT_Destroy_Class_##x(library, classes[i]); } \ + i++; \ + + FT_BASE_DEF( void ) + ft_destroy_default_module_classes( FT_Library library ) + { + FT_Module_Class** classes; + FT_Memory memory; + FT_UInt i; + BasePIC* pic_container = library->pic_container.base; + + if ( !pic_container->default_module_classes ) + return; + + memory = library->memory; + classes = pic_container->default_module_classes; + i = 0; + +#include FT_CONFIG_MODULES_H + + FT_FREE( classes ); + pic_container->default_module_classes = 0; + } + + /* initialize all module classes and the pointer table */ +#undef FT_USE_MODULE +#define FT_USE_MODULE( type, x ) \ + error = FT_Create_Class_##x(library, &clazz); \ + if (error) goto Exit; \ + classes[i++] = clazz; + + FT_BASE_DEF( FT_Error ) + ft_create_default_module_classes( FT_Library library ) + { + FT_Error error; + FT_Memory memory; + FT_Module_Class** classes; + FT_Module_Class* clazz; + FT_UInt i; + BasePIC* pic_container = library->pic_container.base; + + memory = library->memory; + pic_container->default_module_classes = 0; + + if ( FT_ALLOC(classes, sizeof(FT_Module_Class*) * (FT_NUM_MODULE_CLASSES + 1) ) ) + return error; + /* initialize all pointers to 0, especially the last one */ + for (i = 0; i < FT_NUM_MODULE_CLASSES; i++) + classes[i] = 0; + classes[FT_NUM_MODULE_CLASSES] = 0; + + i = 0; + +#include FT_CONFIG_MODULES_H + +Exit: + if (error) ft_destroy_default_module_classes( library ); + else pic_container->default_module_classes = classes; + + return error; + } + + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* documentation is in ftmodapi.h */ + + FT_EXPORT_DEF( void ) + FT_Add_Default_Modules( FT_Library library ) + { + FT_Error error; + const FT_Module_Class* const* cur; + + + /* test for valid `library' delayed to FT_Add_Module() */ + + cur = FT_DEFAULT_MODULES_GET; + while ( *cur ) + { + error = FT_Add_Module( library, *cur ); + /* notify errors, but don't stop */ + if ( error ) + FT_TRACE0(( "FT_Add_Default_Module:" + " Cannot install `%s', error = 0x%x\n", + (*cur)->module_name, error )); + cur++; + } + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Init_FreeType( FT_Library *alibrary ) + { + FT_Error error; + FT_Memory memory; + + + /* First of all, allocate a new system object -- this function is part */ + /* of the system-specific component, i.e. `ftsystem.c'. */ + + memory = FT_New_Memory(); + if ( !memory ) + { + FT_ERROR(( "FT_Init_FreeType: cannot find memory manager\n" )); + return FT_Err_Unimplemented_Feature; + } + + /* build a library out of it, then fill it with the set of */ + /* default drivers. */ + + error = FT_New_Library( memory, alibrary ); + if ( error ) + FT_Done_Memory( memory ); + else + FT_Add_Default_Modules( *alibrary ); + + return error; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Done_FreeType( FT_Library library ) + { + if ( library ) + { + FT_Memory memory = library->memory; + + + /* Discard the library object */ + FT_Done_Library( library ); + + /* discard memory manager */ + FT_Done_Memory( memory ); + } + + return FT_Err_Ok; + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/base/ftlcdfil.c b/mod/pub.mod/freetype.mod/src/base/ftlcdfil.c new file mode 100644 index 0000000..8064011 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/base/ftlcdfil.c @@ -0,0 +1,351 @@ +/***************************************************************************/ +/* */ +/* ftlcdfil.c */ +/* */ +/* FreeType API for color filtering of subpixel bitmap glyphs (body). */ +/* */ +/* Copyright 2006, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_LCD_FILTER_H +#include FT_IMAGE_H +#include FT_INTERNAL_OBJECTS_H + + +#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING + +/* define USE_LEGACY to implement the legacy filter */ +#define USE_LEGACY + + /* FIR filter used by the default and light filters */ + static void + _ft_lcd_filter_fir( FT_Bitmap* bitmap, + FT_Render_Mode mode, + FT_Library library ) + { + FT_Byte* weights = library->lcd_weights; + FT_UInt width = (FT_UInt)bitmap->width; + FT_UInt height = (FT_UInt)bitmap->rows; + + + /* horizontal in-place FIR filter */ + if ( mode == FT_RENDER_MODE_LCD && width >= 4 ) + { + FT_Byte* line = bitmap->buffer; + + + for ( ; height > 0; height--, line += bitmap->pitch ) + { + FT_UInt fir[5]; + FT_UInt val1, xx; + + + val1 = line[0]; + fir[0] = weights[2] * val1; + fir[1] = weights[3] * val1; + fir[2] = weights[4] * val1; + fir[3] = 0; + fir[4] = 0; + + val1 = line[1]; + fir[0] += weights[1] * val1; + fir[1] += weights[2] * val1; + fir[2] += weights[3] * val1; + fir[3] += weights[4] * val1; + + for ( xx = 2; xx < width; xx++ ) + { + FT_UInt val, pix; + + + val = line[xx]; + pix = fir[0] + weights[0] * val; + fir[0] = fir[1] + weights[1] * val; + fir[1] = fir[2] + weights[2] * val; + fir[2] = fir[3] + weights[3] * val; + fir[3] = weights[4] * val; + + pix >>= 8; + pix |= -( pix >> 8 ); + line[xx - 2] = (FT_Byte)pix; + } + + { + FT_UInt pix; + + + pix = fir[0] >> 8; + pix |= -( pix >> 8 ); + line[xx - 2] = (FT_Byte)pix; + + pix = fir[1] >> 8; + pix |= -( pix >> 8 ); + line[xx - 1] = (FT_Byte)pix; + } + } + } + + /* vertical in-place FIR filter */ + else if ( mode == FT_RENDER_MODE_LCD_V && height >= 4 ) + { + FT_Byte* column = bitmap->buffer; + FT_Int pitch = bitmap->pitch; + + + for ( ; width > 0; width--, column++ ) + { + FT_Byte* col = column; + FT_UInt fir[5]; + FT_UInt val1, yy; + + + val1 = col[0]; + fir[0] = weights[2] * val1; + fir[1] = weights[3] * val1; + fir[2] = weights[4] * val1; + fir[3] = 0; + fir[4] = 0; + col += pitch; + + val1 = col[0]; + fir[0] += weights[1] * val1; + fir[1] += weights[2] * val1; + fir[2] += weights[3] * val1; + fir[3] += weights[4] * val1; + col += pitch; + + for ( yy = 2; yy < height; yy++ ) + { + FT_UInt val, pix; + + + val = col[0]; + pix = fir[0] + weights[0] * val; + fir[0] = fir[1] + weights[1] * val; + fir[1] = fir[2] + weights[2] * val; + fir[2] = fir[3] + weights[3] * val; + fir[3] = weights[4] * val; + + pix >>= 8; + pix |= -( pix >> 8 ); + col[-2 * pitch] = (FT_Byte)pix; + col += pitch; + } + + { + FT_UInt pix; + + + pix = fir[0] >> 8; + pix |= -( pix >> 8 ); + col[-2 * pitch] = (FT_Byte)pix; + + pix = fir[1] >> 8; + pix |= -( pix >> 8 ); + col[-pitch] = (FT_Byte)pix; + } + } + } + } + + +#ifdef USE_LEGACY + + /* intra-pixel filter used by the legacy filter */ + static void + _ft_lcd_filter_legacy( FT_Bitmap* bitmap, + FT_Render_Mode mode, + FT_Library library ) + { + FT_UInt width = (FT_UInt)bitmap->width; + FT_UInt height = (FT_UInt)bitmap->rows; + FT_Int pitch = bitmap->pitch; + + static const int filters[3][3] = + { + { 65538 * 9/13, 65538 * 1/6, 65538 * 1/13 }, + { 65538 * 3/13, 65538 * 4/6, 65538 * 3/13 }, + { 65538 * 1/13, 65538 * 1/6, 65538 * 9/13 } + }; + + FT_UNUSED( library ); + + + /* horizontal in-place intra-pixel filter */ + if ( mode == FT_RENDER_MODE_LCD && width >= 3 ) + { + FT_Byte* line = bitmap->buffer; + + + for ( ; height > 0; height--, line += pitch ) + { + FT_UInt xx; + + + for ( xx = 0; xx < width; xx += 3 ) + { + FT_UInt r = 0; + FT_UInt g = 0; + FT_UInt b = 0; + FT_UInt p; + + + p = line[xx]; + r += filters[0][0] * p; + g += filters[0][1] * p; + b += filters[0][2] * p; + + p = line[xx + 1]; + r += filters[1][0] * p; + g += filters[1][1] * p; + b += filters[1][2] * p; + + p = line[xx + 2]; + r += filters[2][0] * p; + g += filters[2][1] * p; + b += filters[2][2] * p; + + line[xx] = (FT_Byte)( r / 65536 ); + line[xx + 1] = (FT_Byte)( g / 65536 ); + line[xx + 2] = (FT_Byte)( b / 65536 ); + } + } + } + else if ( mode == FT_RENDER_MODE_LCD_V && height >= 3 ) + { + FT_Byte* column = bitmap->buffer; + + + for ( ; width > 0; width--, column++ ) + { + FT_Byte* col = column; + FT_Byte* col_end = col + height * pitch; + + + for ( ; col < col_end; col += 3 * pitch ) + { + FT_UInt r = 0; + FT_UInt g = 0; + FT_UInt b = 0; + FT_UInt p; + + + p = col[0]; + r += filters[0][0] * p; + g += filters[0][1] * p; + b += filters[0][2] * p; + + p = col[pitch]; + r += filters[1][0] * p; + g += filters[1][1] * p; + b += filters[1][2] * p; + + p = col[pitch * 2]; + r += filters[2][0] * p; + g += filters[2][1] * p; + b += filters[2][2] * p; + + col[0] = (FT_Byte)( r / 65536 ); + col[pitch] = (FT_Byte)( g / 65536 ); + col[2 * pitch] = (FT_Byte)( b / 65536 ); + } + } + } + } + +#endif /* USE_LEGACY */ + + + FT_EXPORT_DEF( FT_Error ) + FT_Library_SetLcdFilter( FT_Library library, + FT_LcdFilter filter ) + { + static const FT_Byte light_filter[5] = + { 0, 85, 86, 85, 0 }; + /* the values here sum up to a value larger than 256, */ + /* providing a cheap gamma correction */ + static const FT_Byte default_filter[5] = + { 0x10, 0x40, 0x70, 0x40, 0x10 }; + + + if ( library == NULL ) + return FT_Err_Invalid_Argument; + + switch ( filter ) + { + case FT_LCD_FILTER_NONE: + library->lcd_filter_func = NULL; + library->lcd_extra = 0; + break; + + case FT_LCD_FILTER_DEFAULT: +#if defined( FT_FORCE_LEGACY_LCD_FILTER ) + + library->lcd_filter_func = _ft_lcd_filter_legacy; + library->lcd_extra = 0; + +#elif defined( FT_FORCE_LIGHT_LCD_FILTER ) + + ft_memcpy( library->lcd_weights, light_filter, 5 ); + library->lcd_filter_func = _ft_lcd_filter_fir; + library->lcd_extra = 2; + +#else + + ft_memcpy( library->lcd_weights, default_filter, 5 ); + library->lcd_filter_func = _ft_lcd_filter_fir; + library->lcd_extra = 2; + +#endif + + break; + + case FT_LCD_FILTER_LIGHT: + ft_memcpy( library->lcd_weights, light_filter, 5 ); + library->lcd_filter_func = _ft_lcd_filter_fir; + library->lcd_extra = 2; + break; + +#ifdef USE_LEGACY + + case FT_LCD_FILTER_LEGACY: + library->lcd_filter_func = _ft_lcd_filter_legacy; + library->lcd_extra = 0; + break; + +#endif + + default: + return FT_Err_Invalid_Argument; + } + + library->lcd_filter = filter; + return 0; + } + +#else /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ + + FT_EXPORT_DEF( FT_Error ) + FT_Library_SetLcdFilter( FT_Library library, + FT_LcdFilter filter ) + { + FT_UNUSED( library ); + FT_UNUSED( filter ); + + return FT_Err_Unimplemented_Feature; + } + +#endif /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/base/ftmac.c b/mod/pub.mod/freetype.mod/src/base/ftmac.c new file mode 100644 index 0000000..63f927d --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/base/ftmac.c @@ -0,0 +1,1057 @@ +/***************************************************************************/ +/* */ +/* ftmac.c */ +/* */ +/* Mac FOND support. Written by just@letterror.com. */ +/* Heavily modified by mpsuzuki, George Williams, and Sean McBride. */ +/* */ +/* This file is for Mac OS X only; see builds/mac/ftoldmac.c for */ +/* classic platforms built by MPW. */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, */ +/* 2009 by */ +/* Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /* + Notes + + Mac suitcase files can (and often do!) contain multiple fonts. To + support this I use the face_index argument of FT_(Open|New)_Face() + functions, and pretend the suitcase file is a collection. + + Warning: fbit and NFNT bitmap resources are not supported yet. In old + sfnt fonts, bitmap glyph data for each size is stored in each `NFNT' + resources instead of the `bdat' table in the sfnt resource. Therefore, + face->num_fixed_sizes is set to 0, because bitmap data in `NFNT' + resource is unavailable at present. + + The Mac FOND support works roughly like this: + + - Check whether the offered stream points to a Mac suitcase file. This + is done by checking the file type: it has to be 'FFIL' or 'tfil'. The + stream that gets passed to our init_face() routine is a stdio stream, + which isn't usable for us, since the FOND resources live in the + resource fork. So we just grab the stream->pathname field. + + - Read the FOND resource into memory, then check whether there is a + TrueType font and/or(!) a Type 1 font available. + + - If there is a Type 1 font available (as a separate `LWFN' file), read + its data into memory, massage it slightly so it becomes PFB data, wrap + it into a memory stream, load the Type 1 driver and delegate the rest + of the work to it by calling FT_Open_Face(). (XXX TODO: after this + has been done, the kerning data from the FOND resource should be + appended to the face: On the Mac there are usually no AFM files + available. However, this is tricky since we need to map Mac char + codes to ps glyph names to glyph ID's...) + + - If there is a TrueType font (an `sfnt' resource), read it into memory, + wrap it into a memory stream, load the TrueType driver and delegate + the rest of the work to it, by calling FT_Open_Face(). + + - Some suitcase fonts (notably Onyx) might point the `LWFN' file to + itself, even though it doesn't contains `POST' resources. To handle + this special case without opening the file an extra time, we just + ignore errors from the `LWFN' and fallback to the `sfnt' if both are + available. + */ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_TRUETYPE_TAGS_H +#include FT_INTERNAL_STREAM_H +#include "ftbase.h" + + /* This is for Mac OS X. Without redefinition, OS_INLINE */ + /* expands to `static inline' which doesn't survive the */ + /* -ansi compilation flag of GCC. */ +#if !HAVE_ANSI_OS_INLINE +#undef OS_INLINE +#define OS_INLINE static __inline__ +#endif + + /* `configure' checks the availability of `ResourceIndex' strictly */ + /* and sets HAVE_TYPE_RESOURCE_INDEX 1 or 0 always. If it is */ + /* not set (e.g., a build without `configure'), the availability */ + /* is guessed from the SDK version. */ +#ifndef HAVE_TYPE_RESOURCE_INDEX +#if !defined( MAC_OS_X_VERSION_10_5 ) || \ + ( MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5 ) +#define HAVE_TYPE_RESOURCE_INDEX 0 +#else +#define HAVE_TYPE_RESOURCE_INDEX 1 +#endif +#endif /* !HAVE_TYPE_RESOURCE_INDEX */ + +#if ( HAVE_TYPE_RESOURCE_INDEX == 0 ) + typedef short ResourceIndex; +#endif + +#include <CoreServices/CoreServices.h> +#include <ApplicationServices/ApplicationServices.h> +#include <sys/syslimits.h> /* PATH_MAX */ + + /* Don't want warnings about our own use of deprecated functions. */ +#define FT_DEPRECATED_ATTRIBUTE + +#include FT_MAC_H + +#ifndef kATSOptionFlagsUnRestrictedScope /* since Mac OS X 10.1 */ +#define kATSOptionFlagsUnRestrictedScope kATSOptionFlagsDefault +#endif + + + /* Set PREFER_LWFN to 1 if LWFN (Type 1) is preferred over + TrueType in case *both* are available (this is not common, + but it *is* possible). */ +#ifndef PREFER_LWFN +#define PREFER_LWFN 1 +#endif + + + /* This function is deprecated because FSSpec is deprecated in Mac OS X */ + FT_EXPORT_DEF( FT_Error ) + FT_GetFile_From_Mac_Name( const char* fontName, + FSSpec* pathSpec, + FT_Long* face_index ) + { + FT_UNUSED( fontName ); + FT_UNUSED( pathSpec ); + FT_UNUSED( face_index ); + + return FT_Err_Unimplemented_Feature; + } + + + /* Private function. */ + /* The FSSpec type has been discouraged for a long time, */ + /* unfortunately an FSRef replacement API for */ + /* ATSFontGetFileSpecification() is only available in */ + /* Mac OS X 10.5 and later. */ + static OSStatus + FT_ATSFontGetFileReference( ATSFontRef ats_font_id, + FSRef* ats_font_ref ) + { +#if defined( MAC_OS_X_VERSION_10_5 ) && \ + ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 ) + + OSStatus err; + + err = ATSFontGetFileReference( ats_font_id, ats_font_ref ); + + return err; +#elif __LP64__ /* No 64bit Carbon API on legacy platforms */ + FT_UNUSED( ats_font_id ); + FT_UNUSED( ats_font_ref ); + + + return fnfErr; +#else /* 32bit Carbon API on legacy platforms */ + OSStatus err; + FSSpec spec; + + + err = ATSFontGetFileSpecification( ats_font_id, &spec ); + if ( noErr == err ) + err = FSpMakeFSRef( &spec, ats_font_ref ); + + return err; +#endif + } + + + static FT_Error + FT_GetFileRef_From_Mac_ATS_Name( const char* fontName, + FSRef* ats_font_ref, + FT_Long* face_index ) + { + CFStringRef cf_fontName; + ATSFontRef ats_font_id; + + + *face_index = 0; + + cf_fontName = CFStringCreateWithCString( NULL, fontName, + kCFStringEncodingMacRoman ); + ats_font_id = ATSFontFindFromName( cf_fontName, + kATSOptionFlagsUnRestrictedScope ); + CFRelease( cf_fontName ); + + if ( ats_font_id == 0 || ats_font_id == 0xFFFFFFFFUL ) + return FT_Err_Unknown_File_Format; + + if ( noErr != FT_ATSFontGetFileReference( ats_font_id, ats_font_ref ) ) + return FT_Err_Unknown_File_Format; + + /* face_index calculation by searching preceding fontIDs */ + /* with same FSRef */ + { + ATSFontRef id2 = ats_font_id - 1; + FSRef ref2; + + + while ( id2 > 0 ) + { + if ( noErr != FT_ATSFontGetFileReference( id2, &ref2 ) ) + break; + if ( noErr != FSCompareFSRefs( ats_font_ref, &ref2 ) ) + break; + + id2 --; + } + *face_index = ats_font_id - ( id2 + 1 ); + } + + return FT_Err_Ok; + } + + + FT_EXPORT_DEF( FT_Error ) + FT_GetFilePath_From_Mac_ATS_Name( const char* fontName, + UInt8* path, + UInt32 maxPathSize, + FT_Long* face_index ) + { + FSRef ref; + FT_Error err; + + + err = FT_GetFileRef_From_Mac_ATS_Name( fontName, &ref, face_index ); + if ( FT_Err_Ok != err ) + return err; + + if ( noErr != FSRefMakePath( &ref, path, maxPathSize ) ) + return FT_Err_Unknown_File_Format; + + return FT_Err_Ok; + } + + + /* This function is deprecated because FSSpec is deprecated in Mac OS X */ + FT_EXPORT_DEF( FT_Error ) + FT_GetFile_From_Mac_ATS_Name( const char* fontName, + FSSpec* pathSpec, + FT_Long* face_index ) + { +#if ( __LP64__ ) || ( defined( MAC_OS_X_VERSION_10_5 ) && \ + ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 ) ) + FT_UNUSED( fontName ); + FT_UNUSED( pathSpec ); + FT_UNUSED( face_index ); + + return FT_Err_Unimplemented_Feature; +#else + FSRef ref; + FT_Error err; + + + err = FT_GetFileRef_From_Mac_ATS_Name( fontName, &ref, face_index ); + if ( FT_Err_Ok != err ) + return err; + + if ( noErr != FSGetCatalogInfo( &ref, kFSCatInfoNone, NULL, NULL, + pathSpec, NULL ) ) + return FT_Err_Unknown_File_Format; + + return FT_Err_Ok; +#endif + } + + + static OSErr + FT_FSPathMakeRes( const UInt8* pathname, + ResFileRefNum* res ) + { + OSErr err; + FSRef ref; + + + if ( noErr != FSPathMakeRef( pathname, &ref, FALSE ) ) + return FT_Err_Cannot_Open_Resource; + + /* at present, no support for dfont format */ + err = FSOpenResourceFile( &ref, 0, NULL, fsRdPerm, res ); + if ( noErr == err ) + return err; + + /* fallback to original resource-fork font */ + *res = FSOpenResFile( &ref, fsRdPerm ); + err = ResError(); + + return err; + } + + + /* Return the file type for given pathname */ + static OSType + get_file_type_from_path( const UInt8* pathname ) + { + FSRef ref; + FSCatalogInfo info; + + + if ( noErr != FSPathMakeRef( pathname, &ref, FALSE ) ) + return ( OSType ) 0; + + if ( noErr != FSGetCatalogInfo( &ref, kFSCatInfoFinderInfo, &info, + NULL, NULL, NULL ) ) + return ( OSType ) 0; + + return ((FInfo *)(info.finderInfo))->fdType; + } + + + /* Given a PostScript font name, create the Macintosh LWFN file name. */ + static void + create_lwfn_name( char* ps_name, + Str255 lwfn_file_name ) + { + int max = 5, count = 0; + FT_Byte* p = lwfn_file_name; + FT_Byte* q = (FT_Byte*)ps_name; + + + lwfn_file_name[0] = 0; + + while ( *q ) + { + if ( ft_isupper( *q ) ) + { + if ( count ) + max = 3; + count = 0; + } + if ( count < max && ( ft_isalnum( *q ) || *q == '_' ) ) + { + *++p = *q; + lwfn_file_name[0]++; + count++; + } + q++; + } + } + + + static short + count_faces_sfnt( char* fond_data ) + { + /* The count is 1 greater than the value in the FOND. */ + /* Isn't that cute? :-) */ + + return EndianS16_BtoN( *( (short*)( fond_data + + sizeof ( FamRec ) ) ) ) + 1; + } + + + static short + count_faces_scalable( char* fond_data ) + { + AsscEntry* assoc; + FamRec* fond; + short i, face, face_all; + + + fond = (FamRec*)fond_data; + face_all = EndianS16_BtoN( *( (short *)( fond_data + + sizeof ( FamRec ) ) ) ) + 1; + assoc = (AsscEntry*)( fond_data + sizeof ( FamRec ) + 2 ); + face = 0; + + for ( i = 0; i < face_all; i++ ) + { + if ( 0 == EndianS16_BtoN( assoc[i].fontSize ) ) + face++; + } + return face; + } + + + /* Look inside the FOND data, answer whether there should be an SFNT + resource, and answer the name of a possible LWFN Type 1 file. + + Thanks to Paul Miller (paulm@profoundeffects.com) for the fix + to load a face OTHER than the first one in the FOND! + */ + + + static void + parse_fond( char* fond_data, + short* have_sfnt, + ResID* sfnt_id, + Str255 lwfn_file_name, + short face_index ) + { + AsscEntry* assoc; + AsscEntry* base_assoc; + FamRec* fond; + + + *sfnt_id = 0; + *have_sfnt = 0; + lwfn_file_name[0] = 0; + + fond = (FamRec*)fond_data; + assoc = (AsscEntry*)( fond_data + sizeof ( FamRec ) + 2 ); + base_assoc = assoc; + + /* the maximum faces in a FOND is 48, size of StyleTable.indexes[] */ + if ( 47 < face_index ) + return; + + /* Let's do a little range checking before we get too excited here */ + if ( face_index < count_faces_sfnt( fond_data ) ) + { + assoc += face_index; /* add on the face_index! */ + + /* if the face at this index is not scalable, + fall back to the first one (old behavior) */ + if ( EndianS16_BtoN( assoc->fontSize ) == 0 ) + { + *have_sfnt = 1; + *sfnt_id = EndianS16_BtoN( assoc->fontID ); + } + else if ( base_assoc->fontSize == 0 ) + { + *have_sfnt = 1; + *sfnt_id = EndianS16_BtoN( base_assoc->fontID ); + } + } + + if ( EndianS32_BtoN( fond->ffStylOff ) ) + { + unsigned char* p = (unsigned char*)fond_data; + StyleTable* style; + unsigned short string_count; + char ps_name[256]; + unsigned char* names[64]; + int i; + + + p += EndianS32_BtoN( fond->ffStylOff ); + style = (StyleTable*)p; + p += sizeof ( StyleTable ); + string_count = EndianS16_BtoN( *(short*)(p) ); + p += sizeof ( short ); + + for ( i = 0; i < string_count && i < 64; i++ ) + { + names[i] = p; + p += names[i][0]; + p++; + } + + { + size_t ps_name_len = (size_t)names[0][0]; + + + if ( ps_name_len != 0 ) + { + ft_memcpy(ps_name, names[0] + 1, ps_name_len); + ps_name[ps_name_len] = 0; + } + if ( style->indexes[face_index] > 1 && + style->indexes[face_index] <= FT_MIN( string_count, 64 ) ) + { + unsigned char* suffixes = names[style->indexes[face_index] - 1]; + + + for ( i = 1; i <= suffixes[0]; i++ ) + { + unsigned char* s; + size_t j = suffixes[i] - 1; + + + if ( j < string_count && ( s = names[j] ) != NULL ) + { + size_t s_len = (size_t)s[0]; + + + if ( s_len != 0 && ps_name_len + s_len < sizeof ( ps_name ) ) + { + ft_memcpy( ps_name + ps_name_len, s + 1, s_len ); + ps_name_len += s_len; + ps_name[ps_name_len] = 0; + } + } + } + } + } + + create_lwfn_name( ps_name, lwfn_file_name ); + } + } + + + static FT_Error + lookup_lwfn_by_fond( const UInt8* path_fond, + ConstStr255Param base_lwfn, + UInt8* path_lwfn, + size_t path_size ) + { + FSRef ref, par_ref; + size_t dirname_len; + + + /* Pathname for FSRef can be in various formats: HFS, HFS+, and POSIX. */ + /* We should not extract parent directory by string manipulation. */ + + if ( noErr != FSPathMakeRef( path_fond, &ref, FALSE ) ) + return FT_Err_Invalid_Argument; + + if ( noErr != FSGetCatalogInfo( &ref, kFSCatInfoNone, + NULL, NULL, NULL, &par_ref ) ) + return FT_Err_Invalid_Argument; + + if ( noErr != FSRefMakePath( &par_ref, path_lwfn, path_size ) ) + return FT_Err_Invalid_Argument; + + if ( ft_strlen( (char *)path_lwfn ) + 1 + base_lwfn[0] > path_size ) + return FT_Err_Invalid_Argument; + + /* now we have absolute dirname in path_lwfn */ + ft_strcat( (char *)path_lwfn, "/" ); + dirname_len = ft_strlen( (char *)path_lwfn ); + ft_strcat( (char *)path_lwfn, (char *)base_lwfn + 1 ); + path_lwfn[dirname_len + base_lwfn[0]] = '\0'; + + if ( noErr != FSPathMakeRef( path_lwfn, &ref, FALSE ) ) + return FT_Err_Cannot_Open_Resource; + + if ( noErr != FSGetCatalogInfo( &ref, kFSCatInfoNone, + NULL, NULL, NULL, NULL ) ) + return FT_Err_Cannot_Open_Resource; + + return FT_Err_Ok; + } + + + static short + count_faces( Handle fond, + const UInt8* pathname ) + { + ResID sfnt_id; + short have_sfnt, have_lwfn; + Str255 lwfn_file_name; + UInt8 buff[PATH_MAX]; + FT_Error err; + short num_faces; + + + have_sfnt = have_lwfn = 0; + + parse_fond( *fond, &have_sfnt, &sfnt_id, lwfn_file_name, 0 ); + + if ( lwfn_file_name[0] ) + { + err = lookup_lwfn_by_fond( pathname, lwfn_file_name, + buff, sizeof ( buff ) ); + if ( FT_Err_Ok == err ) + have_lwfn = 1; + } + + if ( have_lwfn && ( !have_sfnt || PREFER_LWFN ) ) + num_faces = 1; + else + num_faces = count_faces_scalable( *fond ); + + return num_faces; + } + + + /* Read Type 1 data from the POST resources inside the LWFN file, + return a PFB buffer. This is somewhat convoluted because the FT2 + PFB parser wants the ASCII header as one chunk, and the LWFN + chunks are often not organized that way, so we glue chunks + of the same type together. */ + static FT_Error + read_lwfn( FT_Memory memory, + ResFileRefNum res, + FT_Byte** pfb_data, + FT_ULong* size ) + { + FT_Error error = FT_Err_Ok; + ResID res_id; + unsigned char *buffer, *p, *size_p = NULL; + FT_ULong total_size = 0; + FT_ULong old_total_size = 0; + FT_ULong post_size, pfb_chunk_size; + Handle post_data; + char code, last_code; + + + UseResFile( res ); + + /* First pass: load all POST resources, and determine the size of */ + /* the output buffer. */ + res_id = 501; + last_code = -1; + + for (;;) + { + post_data = Get1Resource( TTAG_POST, res_id++ ); + if ( post_data == NULL ) + break; /* we are done */ + + code = (*post_data)[0]; + + if ( code != last_code ) + { + if ( code == 5 ) + total_size += 2; /* just the end code */ + else + total_size += 6; /* code + 4 bytes chunk length */ + } + + total_size += GetHandleSize( post_data ) - 2; + last_code = code; + + /* detect integer overflows */ + if ( total_size < old_total_size ) + { + error = FT_Err_Array_Too_Large; + goto Error; + } + + old_total_size = total_size; + } + + if ( FT_ALLOC( buffer, (FT_Long)total_size ) ) + goto Error; + + /* Second pass: append all POST data to the buffer, add PFB fields. */ + /* Glue all consecutive chunks of the same type together. */ + p = buffer; + res_id = 501; + last_code = -1; + pfb_chunk_size = 0; + + for (;;) + { + post_data = Get1Resource( TTAG_POST, res_id++ ); + if ( post_data == NULL ) + break; /* we are done */ + + post_size = (FT_ULong)GetHandleSize( post_data ) - 2; + code = (*post_data)[0]; + + if ( code != last_code ) + { + if ( last_code != -1 ) + { + /* we are done adding a chunk, fill in the size field */ + if ( size_p != NULL ) + { + *size_p++ = (FT_Byte)( pfb_chunk_size & 0xFF ); + *size_p++ = (FT_Byte)( ( pfb_chunk_size >> 8 ) & 0xFF ); + *size_p++ = (FT_Byte)( ( pfb_chunk_size >> 16 ) & 0xFF ); + *size_p++ = (FT_Byte)( ( pfb_chunk_size >> 24 ) & 0xFF ); + } + pfb_chunk_size = 0; + } + + *p++ = 0x80; + if ( code == 5 ) + *p++ = 0x03; /* the end */ + else if ( code == 2 ) + *p++ = 0x02; /* binary segment */ + else + *p++ = 0x01; /* ASCII segment */ + + if ( code != 5 ) + { + size_p = p; /* save for later */ + p += 4; /* make space for size field */ + } + } + + ft_memcpy( p, *post_data + 2, post_size ); + pfb_chunk_size += post_size; + p += post_size; + last_code = code; + } + + *pfb_data = buffer; + *size = total_size; + + Error: + CloseResFile( res ); + return error; + } + + + /* Create a new FT_Face from a file path to an LWFN file. */ + static FT_Error + FT_New_Face_From_LWFN( FT_Library library, + const UInt8* pathname, + FT_Long face_index, + FT_Face* aface ) + { + FT_Byte* pfb_data; + FT_ULong pfb_size; + FT_Error error; + ResFileRefNum res; + + + if ( noErr != FT_FSPathMakeRes( pathname, &res ) ) + return FT_Err_Cannot_Open_Resource; + + pfb_data = NULL; + pfb_size = 0; + error = read_lwfn( library->memory, res, &pfb_data, &pfb_size ); + CloseResFile( res ); /* PFB is already loaded, useless anymore */ + if ( error ) + return error; + + return open_face_from_buffer( library, + pfb_data, + pfb_size, + face_index, + "type1", + aface ); + } + + + /* Create a new FT_Face from an SFNT resource, specified by res ID. */ + static FT_Error + FT_New_Face_From_SFNT( FT_Library library, + ResID sfnt_id, + FT_Long face_index, + FT_Face* aface ) + { + Handle sfnt = NULL; + FT_Byte* sfnt_data; + size_t sfnt_size; + FT_Error error = FT_Err_Ok; + FT_Memory memory = library->memory; + int is_cff, is_sfnt_ps; + + + sfnt = GetResource( TTAG_sfnt, sfnt_id ); + if ( sfnt == NULL ) + return FT_Err_Invalid_Handle; + + sfnt_size = (FT_ULong)GetHandleSize( sfnt ); + if ( FT_ALLOC( sfnt_data, (FT_Long)sfnt_size ) ) + { + ReleaseResource( sfnt ); + return error; + } + + ft_memcpy( sfnt_data, *sfnt, sfnt_size ); + ReleaseResource( sfnt ); + + is_cff = sfnt_size > 4 && !ft_memcmp( sfnt_data, "OTTO", 4 ); + is_sfnt_ps = sfnt_size > 4 && !ft_memcmp( sfnt_data, "typ1", 4 ); + + if ( is_sfnt_ps ) + { + FT_Stream stream; + + + if ( FT_NEW( stream ) ) + goto Try_OpenType; + + FT_Stream_OpenMemory( stream, sfnt_data, sfnt_size ); + if ( !open_face_PS_from_sfnt_stream( library, + stream, + face_index, + 0, NULL, + aface ) ) + { + FT_Stream_Close( stream ); + FT_FREE( stream ); + FT_FREE( sfnt_data ); + goto Exit; + } + + FT_FREE( stream ); + } + Try_OpenType: + error = open_face_from_buffer( library, + sfnt_data, + sfnt_size, + face_index, + is_cff ? "cff" : "truetype", + aface ); + Exit: + return error; + } + + + /* Create a new FT_Face from a file path to a suitcase file. */ + static FT_Error + FT_New_Face_From_Suitcase( FT_Library library, + const UInt8* pathname, + FT_Long face_index, + FT_Face* aface ) + { + FT_Error error = FT_Err_Cannot_Open_Resource; + ResFileRefNum res_ref; + ResourceIndex res_index; + Handle fond; + short num_faces_in_res, num_faces_in_fond; + + + if ( noErr != FT_FSPathMakeRes( pathname, &res_ref ) ) + return FT_Err_Cannot_Open_Resource; + + UseResFile( res_ref ); + if ( ResError() ) + return FT_Err_Cannot_Open_Resource; + + num_faces_in_res = 0; + for ( res_index = 1; ; ++res_index ) + { + fond = Get1IndResource( TTAG_FOND, res_index ); + if ( ResError() ) + break; + + num_faces_in_fond = count_faces( fond, pathname ); + num_faces_in_res += num_faces_in_fond; + + if ( 0 <= face_index && face_index < num_faces_in_fond && error ) + error = FT_New_Face_From_FOND( library, fond, face_index, aface ); + + face_index -= num_faces_in_fond; + } + + CloseResFile( res_ref ); + if ( FT_Err_Ok == error && NULL != aface && NULL != *aface ) + (*aface)->num_faces = num_faces_in_res; + return error; + } + + + /* documentation is in ftmac.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_New_Face_From_FOND( FT_Library library, + Handle fond, + FT_Long face_index, + FT_Face* aface ) + { + short have_sfnt, have_lwfn = 0; + ResID sfnt_id, fond_id; + OSType fond_type; + Str255 fond_name; + Str255 lwfn_file_name; + UInt8 path_lwfn[PATH_MAX]; + OSErr err; + FT_Error error = FT_Err_Ok; + + + GetResInfo( fond, &fond_id, &fond_type, fond_name ); + if ( ResError() != noErr || fond_type != TTAG_FOND ) + return FT_Err_Invalid_File_Format; + + parse_fond( *fond, &have_sfnt, &sfnt_id, lwfn_file_name, face_index ); + + if ( lwfn_file_name[0] ) + { + ResFileRefNum res; + + + res = HomeResFile( fond ); + if ( noErr != ResError() ) + goto found_no_lwfn_file; + + { + UInt8 path_fond[PATH_MAX]; + FSRef ref; + + + err = FSGetForkCBInfo( res, kFSInvalidVolumeRefNum, + NULL, NULL, NULL, &ref, NULL ); + if ( noErr != err ) + goto found_no_lwfn_file; + + err = FSRefMakePath( &ref, path_fond, sizeof ( path_fond ) ); + if ( noErr != err ) + goto found_no_lwfn_file; + + error = lookup_lwfn_by_fond( path_fond, lwfn_file_name, + path_lwfn, sizeof ( path_lwfn ) ); + if ( FT_Err_Ok == error ) + have_lwfn = 1; + } + } + + if ( have_lwfn && ( !have_sfnt || PREFER_LWFN ) ) + error = FT_New_Face_From_LWFN( library, + path_lwfn, + face_index, + aface ); + else + error = FT_Err_Unknown_File_Format; + + found_no_lwfn_file: + if ( have_sfnt && FT_Err_Ok != error ) + error = FT_New_Face_From_SFNT( library, + sfnt_id, + face_index, + aface ); + + return error; + } + + + /* Common function to load a new FT_Face from a resource file. */ + static FT_Error + FT_New_Face_From_Resource( FT_Library library, + const UInt8* pathname, + FT_Long face_index, + FT_Face* aface ) + { + OSType file_type; + FT_Error error; + + + /* LWFN is a (very) specific file format, check for it explicitly */ + file_type = get_file_type_from_path( pathname ); + if ( file_type == TTAG_LWFN ) + return FT_New_Face_From_LWFN( library, pathname, face_index, aface ); + + /* Otherwise the file type doesn't matter (there are more than */ + /* `FFIL' and `tfil'). Just try opening it as a font suitcase; */ + /* if it works, fine. */ + + error = FT_New_Face_From_Suitcase( library, pathname, face_index, aface ); + if ( error == 0 ) + return error; + + /* let it fall through to normal loader (.ttf, .otf, etc.); */ + /* we signal this by returning no error and no FT_Face */ + *aface = NULL; + return 0; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_Face */ + /* */ + /* <Description> */ + /* This is the Mac-specific implementation of FT_New_Face. In */ + /* addition to the standard FT_New_Face() functionality, it also */ + /* accepts pathnames to Mac suitcase files. For further */ + /* documentation see the original FT_New_Face() in freetype.h. */ + /* */ + FT_EXPORT_DEF( FT_Error ) + FT_New_Face( FT_Library library, + const char* pathname, + FT_Long face_index, + FT_Face* aface ) + { + FT_Open_Args args; + FT_Error error; + + + /* test for valid `library' and `aface' delayed to FT_Open_Face() */ + if ( !pathname ) + return FT_Err_Invalid_Argument; + + error = FT_Err_Ok; + *aface = NULL; + + /* try resourcefork based font: LWFN, FFIL */ + error = FT_New_Face_From_Resource( library, (UInt8 *)pathname, + face_index, aface ); + if ( error != 0 || *aface != NULL ) + return error; + + /* let it fall through to normal loader (.ttf, .otf, etc.) */ + args.flags = FT_OPEN_PATHNAME; + args.pathname = (char*)pathname; + return FT_Open_Face( library, &args, face_index, aface ); + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_Face_From_FSRef */ + /* */ + /* <Description> */ + /* FT_New_Face_From_FSRef is identical to FT_New_Face except it */ + /* accepts an FSRef instead of a path. */ + /* */ + /* This function is deprecated because Carbon data types (FSRef) */ + /* are not cross-platform, and thus not suitable for the freetype API. */ + FT_EXPORT_DEF( FT_Error ) + FT_New_Face_From_FSRef( FT_Library library, + const FSRef* ref, + FT_Long face_index, + FT_Face* aface ) + { + FT_Error error; + FT_Open_Args args; + OSErr err; + UInt8 pathname[PATH_MAX]; + + + if ( !ref ) + return FT_Err_Invalid_Argument; + + err = FSRefMakePath( ref, pathname, sizeof ( pathname ) ); + if ( err ) + error = FT_Err_Cannot_Open_Resource; + + error = FT_New_Face_From_Resource( library, pathname, face_index, aface ); + if ( error != 0 || *aface != NULL ) + return error; + + /* fallback to datafork font */ + args.flags = FT_OPEN_PATHNAME; + args.pathname = (char*)pathname; + return FT_Open_Face( library, &args, face_index, aface ); + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_Face_From_FSSpec */ + /* */ + /* <Description> */ + /* FT_New_Face_From_FSSpec is identical to FT_New_Face except it */ + /* accepts an FSSpec instead of a path. */ + /* */ + /* This function is deprecated because FSSpec is deprecated in Mac OS X */ + FT_EXPORT_DEF( FT_Error ) + FT_New_Face_From_FSSpec( FT_Library library, + const FSSpec* spec, + FT_Long face_index, + FT_Face* aface ) + { +#if ( __LP64__ ) || ( defined( MAC_OS_X_VERSION_10_5 ) && \ + ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 ) ) + FT_UNUSED( library ); + FT_UNUSED( spec ); + FT_UNUSED( face_index ); + FT_UNUSED( aface ); + + return FT_Err_Unimplemented_Feature; +#else + FSRef ref; + + + if ( !spec || FSpMakeFSRef( spec, &ref ) != noErr ) + return FT_Err_Invalid_Argument; + else + return FT_New_Face_From_FSRef( library, &ref, face_index, aface ); +#endif + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/base/ftmm.c b/mod/pub.mod/freetype.mod/src/base/ftmm.c new file mode 100644 index 0000000..0307729 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/base/ftmm.c @@ -0,0 +1,202 @@ +/***************************************************************************/ +/* */ +/* ftmm.c */ +/* */ +/* Multiple Master font support (body). */ +/* */ +/* Copyright 1996-2001, 2003, 2004, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_MULTIPLE_MASTERS_H +#include FT_INTERNAL_OBJECTS_H +#include FT_SERVICE_MULTIPLE_MASTERS_H + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_mm + + + static FT_Error + ft_face_get_mm_service( FT_Face face, + FT_Service_MultiMasters *aservice ) + { + FT_Error error; + + + *aservice = NULL; + + if ( !face ) + return FT_Err_Invalid_Face_Handle; + + error = FT_Err_Invalid_Argument; + + if ( FT_HAS_MULTIPLE_MASTERS( face ) ) + { + FT_FACE_LOOKUP_SERVICE( face, + *aservice, + MULTI_MASTERS ); + + if ( *aservice ) + error = FT_Err_Ok; + } + + return error; + } + + + /* documentation is in ftmm.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_Multi_Master( FT_Face face, + FT_Multi_Master *amaster ) + { + FT_Error error; + FT_Service_MultiMasters service; + + + error = ft_face_get_mm_service( face, &service ); + if ( !error ) + { + error = FT_Err_Invalid_Argument; + if ( service->get_mm ) + error = service->get_mm( face, amaster ); + } + + return error; + } + + + /* documentation is in ftmm.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_MM_Var( FT_Face face, + FT_MM_Var* *amaster ) + { + FT_Error error; + FT_Service_MultiMasters service; + + + error = ft_face_get_mm_service( face, &service ); + if ( !error ) + { + error = FT_Err_Invalid_Argument; + if ( service->get_mm_var ) + error = service->get_mm_var( face, amaster ); + } + + return error; + } + + + /* documentation is in ftmm.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Set_MM_Design_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Long* coords ) + { + FT_Error error; + FT_Service_MultiMasters service; + + + error = ft_face_get_mm_service( face, &service ); + if ( !error ) + { + error = FT_Err_Invalid_Argument; + if ( service->set_mm_design ) + error = service->set_mm_design( face, num_coords, coords ); + } + + return error; + } + + + /* documentation is in ftmm.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Set_Var_Design_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) + { + FT_Error error; + FT_Service_MultiMasters service; + + + error = ft_face_get_mm_service( face, &service ); + if ( !error ) + { + error = FT_Err_Invalid_Argument; + if ( service->set_var_design ) + error = service->set_var_design( face, num_coords, coords ); + } + + return error; + } + + + /* documentation is in ftmm.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Set_MM_Blend_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) + { + FT_Error error; + FT_Service_MultiMasters service; + + + error = ft_face_get_mm_service( face, &service ); + if ( !error ) + { + error = FT_Err_Invalid_Argument; + if ( service->set_mm_blend ) + error = service->set_mm_blend( face, num_coords, coords ); + } + + return error; + } + + + /* documentation is in ftmm.h */ + + /* This is exactly the same as the previous function. It exists for */ + /* orthogonality. */ + + FT_EXPORT_DEF( FT_Error ) + FT_Set_Var_Blend_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) + { + FT_Error error; + FT_Service_MultiMasters service; + + + error = ft_face_get_mm_service( face, &service ); + if ( !error ) + { + error = FT_Err_Invalid_Argument; + if ( service->set_mm_blend ) + error = service->set_mm_blend( face, num_coords, coords ); + } + + return error; + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/base/ftobjs.c b/mod/pub.mod/freetype.mod/src/base/ftobjs.c new file mode 100644 index 0000000..421540c --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/base/ftobjs.c @@ -0,0 +1,4478 @@ +/***************************************************************************/ +/* */ +/* ftobjs.c */ +/* */ +/* The FreeType private base classes (body). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_LIST_H +#include FT_OUTLINE_H +#include FT_INTERNAL_VALIDATE_H +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_RFORK_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_SFNT_H /* for SFNT_Load_Table_Func */ +#include FT_TRUETYPE_TABLES_H +#include FT_TRUETYPE_TAGS_H +#include FT_TRUETYPE_IDS_H +#include FT_OUTLINE_H + +#include FT_SERVICE_SFNT_H +#include FT_SERVICE_POSTSCRIPT_NAME_H +#include FT_SERVICE_GLYPH_DICT_H +#include FT_SERVICE_TT_CMAP_H +#include FT_SERVICE_KERNING_H +#include FT_SERVICE_TRUETYPE_ENGINE_H + +#include "ftbase.h" + +#define GRID_FIT_METRICS + + + FT_BASE_DEF( FT_Pointer ) + ft_service_list_lookup( FT_ServiceDesc service_descriptors, + const char* service_id ) + { + FT_Pointer result = NULL; + FT_ServiceDesc desc = service_descriptors; + + + if ( desc && service_id ) + { + for ( ; desc->serv_id != NULL; desc++ ) + { + if ( ft_strcmp( desc->serv_id, service_id ) == 0 ) + { + result = (FT_Pointer)desc->serv_data; + break; + } + } + } + + return result; + } + + + FT_BASE_DEF( void ) + ft_validator_init( FT_Validator valid, + const FT_Byte* base, + const FT_Byte* limit, + FT_ValidationLevel level ) + { + valid->base = base; + valid->limit = limit; + valid->level = level; + valid->error = FT_Err_Ok; + } + + + FT_BASE_DEF( FT_Int ) + ft_validator_run( FT_Validator valid ) + { + /* This function doesn't work! None should call it. */ + FT_UNUSED( valid ); + + return -1; + } + + + FT_BASE_DEF( void ) + ft_validator_error( FT_Validator valid, + FT_Error error ) + { + /* since the cast below also disables the compiler's */ + /* type check, we introduce a dummy variable, which */ + /* will be optimized away */ + volatile ft_jmp_buf* jump_buffer = &valid->jump_buffer; + + + valid->error = error; + + /* throw away volatileness; use `jump_buffer' or the */ + /* compiler may warn about an unused local variable */ + ft_longjmp( *(ft_jmp_buf*) jump_buffer, 1 ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** S T R E A M ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /* create a new input stream from an FT_Open_Args structure */ + /* */ + FT_BASE_DEF( FT_Error ) + FT_Stream_New( FT_Library library, + const FT_Open_Args* args, + FT_Stream *astream ) + { + FT_Error error; + FT_Memory memory; + FT_Stream stream; + + + *astream = 0; + + if ( !library ) + return FT_Err_Invalid_Library_Handle; + + if ( !args ) + return FT_Err_Invalid_Argument; + + memory = library->memory; + + if ( FT_NEW( stream ) ) + goto Exit; + + stream->memory = memory; + + if ( args->flags & FT_OPEN_MEMORY ) + { + /* create a memory-based stream */ + FT_Stream_OpenMemory( stream, + (const FT_Byte*)args->memory_base, + args->memory_size ); + } + else if ( args->flags & FT_OPEN_PATHNAME ) + { + /* create a normal system stream */ + error = FT_Stream_Open( stream, args->pathname ); + stream->pathname.pointer = args->pathname; + } + else if ( ( args->flags & FT_OPEN_STREAM ) && args->stream ) + { + /* use an existing, user-provided stream */ + + /* in this case, we do not need to allocate a new stream object */ + /* since the caller is responsible for closing it himself */ + FT_FREE( stream ); + stream = args->stream; + } + else + error = FT_Err_Invalid_Argument; + + if ( error ) + FT_FREE( stream ); + else + stream->memory = memory; /* just to be certain */ + + *astream = stream; + + Exit: + return error; + } + + + FT_BASE_DEF( void ) + FT_Stream_Free( FT_Stream stream, + FT_Int external ) + { + if ( stream ) + { + FT_Memory memory = stream->memory; + + + FT_Stream_Close( stream ); + + if ( !external ) + FT_FREE( stream ); + } + } + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_objs + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** FACE, SIZE & GLYPH SLOT OBJECTS ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + static FT_Error + ft_glyphslot_init( FT_GlyphSlot slot ) + { + FT_Driver driver = slot->face->driver; + FT_Driver_Class clazz = driver->clazz; + FT_Memory memory = driver->root.memory; + FT_Error error = FT_Err_Ok; + FT_Slot_Internal internal; + + + slot->library = driver->root.library; + + if ( FT_NEW( internal ) ) + goto Exit; + + slot->internal = internal; + + if ( FT_DRIVER_USES_OUTLINES( driver ) ) + error = FT_GlyphLoader_New( memory, &internal->loader ); + + if ( !error && clazz->init_slot ) + error = clazz->init_slot( slot ); + + Exit: + return error; + } + + + FT_BASE_DEF( void ) + ft_glyphslot_free_bitmap( FT_GlyphSlot slot ) + { + if ( slot->internal && ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) ) + { + FT_Memory memory = FT_FACE_MEMORY( slot->face ); + + + FT_FREE( slot->bitmap.buffer ); + slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; + } + else + { + /* assume that the bitmap buffer was stolen or not */ + /* allocated from the heap */ + slot->bitmap.buffer = NULL; + } + } + + + FT_BASE_DEF( void ) + ft_glyphslot_set_bitmap( FT_GlyphSlot slot, + FT_Byte* buffer ) + { + ft_glyphslot_free_bitmap( slot ); + + slot->bitmap.buffer = buffer; + + FT_ASSERT( (slot->internal->flags & FT_GLYPH_OWN_BITMAP) == 0 ); + } + + + FT_BASE_DEF( FT_Error ) + ft_glyphslot_alloc_bitmap( FT_GlyphSlot slot, + FT_ULong size ) + { + FT_Memory memory = FT_FACE_MEMORY( slot->face ); + FT_Error error; + + + if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) + FT_FREE( slot->bitmap.buffer ); + else + slot->internal->flags |= FT_GLYPH_OWN_BITMAP; + + (void)FT_ALLOC( slot->bitmap.buffer, size ); + return error; + } + + + static void + ft_glyphslot_clear( FT_GlyphSlot slot ) + { + /* free bitmap if needed */ + ft_glyphslot_free_bitmap( slot ); + + /* clear all public fields in the glyph slot */ + FT_ZERO( &slot->metrics ); + FT_ZERO( &slot->outline ); + + slot->bitmap.width = 0; + slot->bitmap.rows = 0; + slot->bitmap.pitch = 0; + slot->bitmap.pixel_mode = 0; + /* `slot->bitmap.buffer' has been handled by ft_glyphslot_free_bitmap */ + + slot->bitmap_left = 0; + slot->bitmap_top = 0; + slot->num_subglyphs = 0; + slot->subglyphs = 0; + slot->control_data = 0; + slot->control_len = 0; + slot->other = 0; + slot->format = FT_GLYPH_FORMAT_NONE; + + slot->linearHoriAdvance = 0; + slot->linearVertAdvance = 0; + slot->lsb_delta = 0; + slot->rsb_delta = 0; + } + + + static void + ft_glyphslot_done( FT_GlyphSlot slot ) + { + FT_Driver driver = slot->face->driver; + FT_Driver_Class clazz = driver->clazz; + FT_Memory memory = driver->root.memory; + + + if ( clazz->done_slot ) + clazz->done_slot( slot ); + + /* free bitmap buffer if needed */ + ft_glyphslot_free_bitmap( slot ); + + /* slot->internal might be NULL in out-of-memory situations */ + if ( slot->internal ) + { + /* free glyph loader */ + if ( FT_DRIVER_USES_OUTLINES( driver ) ) + { + FT_GlyphLoader_Done( slot->internal->loader ); + slot->internal->loader = 0; + } + + FT_FREE( slot->internal ); + } + } + + + /* documentation is in ftobjs.h */ + + FT_BASE_DEF( FT_Error ) + FT_New_GlyphSlot( FT_Face face, + FT_GlyphSlot *aslot ) + { + FT_Error error; + FT_Driver driver; + FT_Driver_Class clazz; + FT_Memory memory; + FT_GlyphSlot slot; + + + if ( !face || !face->driver ) + return FT_Err_Invalid_Argument; + + driver = face->driver; + clazz = driver->clazz; + memory = driver->root.memory; + + FT_TRACE4(( "FT_New_GlyphSlot: Creating new slot object\n" )); + if ( !FT_ALLOC( slot, clazz->slot_object_size ) ) + { + slot->face = face; + + error = ft_glyphslot_init( slot ); + if ( error ) + { + ft_glyphslot_done( slot ); + FT_FREE( slot ); + goto Exit; + } + + slot->next = face->glyph; + face->glyph = slot; + + if ( aslot ) + *aslot = slot; + } + else if ( aslot ) + *aslot = 0; + + + Exit: + FT_TRACE4(( "FT_New_GlyphSlot: Return %d\n", error )); + return error; + } + + + /* documentation is in ftobjs.h */ + + FT_BASE_DEF( void ) + FT_Done_GlyphSlot( FT_GlyphSlot slot ) + { + if ( slot ) + { + FT_Driver driver = slot->face->driver; + FT_Memory memory = driver->root.memory; + FT_GlyphSlot prev; + FT_GlyphSlot cur; + + + /* Remove slot from its parent face's list */ + prev = NULL; + cur = slot->face->glyph; + + while ( cur ) + { + if ( cur == slot ) + { + if ( !prev ) + slot->face->glyph = cur->next; + else + prev->next = cur->next; + + ft_glyphslot_done( slot ); + FT_FREE( slot ); + break; + } + prev = cur; + cur = cur->next; + } + } + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( void ) + FT_Set_Transform( FT_Face face, + FT_Matrix* matrix, + FT_Vector* delta ) + { + FT_Face_Internal internal; + + + if ( !face ) + return; + + internal = face->internal; + + internal->transform_flags = 0; + + if ( !matrix ) + { + internal->transform_matrix.xx = 0x10000L; + internal->transform_matrix.xy = 0; + internal->transform_matrix.yx = 0; + internal->transform_matrix.yy = 0x10000L; + matrix = &internal->transform_matrix; + } + else + internal->transform_matrix = *matrix; + + /* set transform_flags bit flag 0 if `matrix' isn't the identity */ + if ( ( matrix->xy | matrix->yx ) || + matrix->xx != 0x10000L || + matrix->yy != 0x10000L ) + internal->transform_flags |= 1; + + if ( !delta ) + { + internal->transform_delta.x = 0; + internal->transform_delta.y = 0; + delta = &internal->transform_delta; + } + else + internal->transform_delta = *delta; + + /* set transform_flags bit flag 1 if `delta' isn't the null vector */ + if ( delta->x | delta->y ) + internal->transform_flags |= 2; + } + + + static FT_Renderer + ft_lookup_glyph_renderer( FT_GlyphSlot slot ); + + +#ifdef GRID_FIT_METRICS + static void + ft_glyphslot_grid_fit_metrics( FT_GlyphSlot slot, + FT_Bool vertical ) + { + FT_Glyph_Metrics* metrics = &slot->metrics; + FT_Pos right, bottom; + + + if ( vertical ) + { + metrics->horiBearingX = FT_PIX_FLOOR( metrics->horiBearingX ); + metrics->horiBearingY = FT_PIX_CEIL ( metrics->horiBearingY ); + + right = FT_PIX_CEIL( metrics->vertBearingX + metrics->width ); + bottom = FT_PIX_CEIL( metrics->vertBearingY + metrics->height ); + + metrics->vertBearingX = FT_PIX_FLOOR( metrics->vertBearingX ); + metrics->vertBearingY = FT_PIX_FLOOR( metrics->vertBearingY ); + + metrics->width = right - metrics->vertBearingX; + metrics->height = bottom - metrics->vertBearingY; + } + else + { + metrics->vertBearingX = FT_PIX_FLOOR( metrics->vertBearingX ); + metrics->vertBearingY = FT_PIX_FLOOR( metrics->vertBearingY ); + + right = FT_PIX_CEIL ( metrics->horiBearingX + metrics->width ); + bottom = FT_PIX_FLOOR( metrics->horiBearingY - metrics->height ); + + metrics->horiBearingX = FT_PIX_FLOOR( metrics->horiBearingX ); + metrics->horiBearingY = FT_PIX_CEIL ( metrics->horiBearingY ); + + metrics->width = right - metrics->horiBearingX; + metrics->height = metrics->horiBearingY - bottom; + } + + metrics->horiAdvance = FT_PIX_ROUND( metrics->horiAdvance ); + metrics->vertAdvance = FT_PIX_ROUND( metrics->vertAdvance ); + } +#endif /* GRID_FIT_METRICS */ + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Load_Glyph( FT_Face face, + FT_UInt glyph_index, + FT_Int32 load_flags ) + { + FT_Error error; + FT_Driver driver; + FT_GlyphSlot slot; + FT_Library library; + FT_Bool autohint = FALSE; + FT_Module hinter; + + + if ( !face || !face->size || !face->glyph ) + return FT_Err_Invalid_Face_Handle; + + /* The validity test for `glyph_index' is performed by the */ + /* font drivers. */ + + slot = face->glyph; + ft_glyphslot_clear( slot ); + + driver = face->driver; + library = driver->root.library; + hinter = library->auto_hinter; + + /* resolve load flags dependencies */ + + if ( load_flags & FT_LOAD_NO_RECURSE ) + load_flags |= FT_LOAD_NO_SCALE | + FT_LOAD_IGNORE_TRANSFORM; + + if ( load_flags & FT_LOAD_NO_SCALE ) + { + load_flags |= FT_LOAD_NO_HINTING | + FT_LOAD_NO_BITMAP; + + load_flags &= ~FT_LOAD_RENDER; + } + + /* + * Determine whether we need to auto-hint or not. + * The general rules are: + * + * - Do only auto-hinting if we have a hinter module, a scalable font + * format dealing with outlines, and no transforms except simple + * slants and/or rotations by integer multiples of 90 degrees. + * + * - Then, auto-hint if FT_LOAD_FORCE_AUTOHINT is set or if we don't + * have a native font hinter. + * + * - Otherwise, auto-hint for LIGHT hinting mode. + * + * - Exception: The font is `tricky' and requires the native hinter to + * load properly. + */ + + if ( hinter && + !( load_flags & FT_LOAD_NO_HINTING ) && + !( load_flags & FT_LOAD_NO_AUTOHINT ) && + FT_DRIVER_IS_SCALABLE( driver ) && + FT_DRIVER_USES_OUTLINES( driver ) && + !FT_IS_TRICKY( face ) && + ( ( face->internal->transform_matrix.yx == 0 && + face->internal->transform_matrix.xx != 0 ) || + ( face->internal->transform_matrix.xx == 0 && + face->internal->transform_matrix.yx != 0 ) ) ) + { + if ( ( load_flags & FT_LOAD_FORCE_AUTOHINT ) || + !FT_DRIVER_HAS_HINTER( driver ) ) + autohint = TRUE; + else + { + FT_Render_Mode mode = FT_LOAD_TARGET_MODE( load_flags ); + + + if ( mode == FT_RENDER_MODE_LIGHT || + face->internal->ignore_unpatented_hinter ) + autohint = TRUE; + } + } + + if ( autohint ) + { + FT_AutoHinter_Service hinting; + + + /* try to load embedded bitmaps first if available */ + /* */ + /* XXX: This is really a temporary hack that should disappear */ + /* promptly with FreeType 2.1! */ + /* */ + if ( FT_HAS_FIXED_SIZES( face ) && + ( load_flags & FT_LOAD_NO_BITMAP ) == 0 ) + { + error = driver->clazz->load_glyph( slot, face->size, + glyph_index, + load_flags | FT_LOAD_SBITS_ONLY ); + + if ( !error && slot->format == FT_GLYPH_FORMAT_BITMAP ) + goto Load_Ok; + } + + { + FT_Face_Internal internal = face->internal; + FT_Int transform_flags = internal->transform_flags; + + + /* since the auto-hinter calls FT_Load_Glyph by itself, */ + /* make sure that glyphs aren't transformed */ + internal->transform_flags = 0; + + /* load auto-hinted outline */ + hinting = (FT_AutoHinter_Service)hinter->clazz->module_interface; + + error = hinting->load_glyph( (FT_AutoHinter)hinter, + slot, face->size, + glyph_index, load_flags ); + + internal->transform_flags = transform_flags; + } + } + else + { + error = driver->clazz->load_glyph( slot, + face->size, + glyph_index, + load_flags ); + if ( error ) + goto Exit; + + if ( slot->format == FT_GLYPH_FORMAT_OUTLINE ) + { + /* check that the loaded outline is correct */ + error = FT_Outline_Check( &slot->outline ); + if ( error ) + goto Exit; + +#ifdef GRID_FIT_METRICS + if ( !( load_flags & FT_LOAD_NO_HINTING ) ) + ft_glyphslot_grid_fit_metrics( slot, + FT_BOOL( load_flags & FT_LOAD_VERTICAL_LAYOUT ) ); +#endif + } + } + + Load_Ok: + /* compute the advance */ + if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) + { + slot->advance.x = 0; + slot->advance.y = slot->metrics.vertAdvance; + } + else + { + slot->advance.x = slot->metrics.horiAdvance; + slot->advance.y = 0; + } + + /* compute the linear advance in 16.16 pixels */ + if ( ( load_flags & FT_LOAD_LINEAR_DESIGN ) == 0 && + ( FT_IS_SCALABLE( face ) ) ) + { + FT_Size_Metrics* metrics = &face->size->metrics; + + + /* it's tricky! */ + slot->linearHoriAdvance = FT_MulDiv( slot->linearHoriAdvance, + metrics->x_scale, 64 ); + + slot->linearVertAdvance = FT_MulDiv( slot->linearVertAdvance, + metrics->y_scale, 64 ); + } + + if ( ( load_flags & FT_LOAD_IGNORE_TRANSFORM ) == 0 ) + { + FT_Face_Internal internal = face->internal; + + + /* now, transform the glyph image if needed */ + if ( internal->transform_flags ) + { + /* get renderer */ + FT_Renderer renderer = ft_lookup_glyph_renderer( slot ); + + + if ( renderer ) + error = renderer->clazz->transform_glyph( + renderer, slot, + &internal->transform_matrix, + &internal->transform_delta ); + /* transform advance */ + FT_Vector_Transform( &slot->advance, &internal->transform_matrix ); + } + } + + /* do we need to render the image now? */ + if ( !error && + slot->format != FT_GLYPH_FORMAT_BITMAP && + slot->format != FT_GLYPH_FORMAT_COMPOSITE && + load_flags & FT_LOAD_RENDER ) + { + FT_Render_Mode mode = FT_LOAD_TARGET_MODE( load_flags ); + + + if ( mode == FT_RENDER_MODE_NORMAL && + (load_flags & FT_LOAD_MONOCHROME ) ) + mode = FT_RENDER_MODE_MONO; + + error = FT_Render_Glyph( slot, mode ); + } + + Exit: + return error; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Load_Char( FT_Face face, + FT_ULong char_code, + FT_Int32 load_flags ) + { + FT_UInt glyph_index; + + + if ( !face ) + return FT_Err_Invalid_Face_Handle; + + glyph_index = (FT_UInt)char_code; + if ( face->charmap ) + glyph_index = FT_Get_Char_Index( face, char_code ); + + return FT_Load_Glyph( face, glyph_index, load_flags ); + } + + + /* destructor for sizes list */ + static void + destroy_size( FT_Memory memory, + FT_Size size, + FT_Driver driver ) + { + /* finalize client-specific data */ + if ( size->generic.finalizer ) + size->generic.finalizer( size ); + + /* finalize format-specific stuff */ + if ( driver->clazz->done_size ) + driver->clazz->done_size( size ); + + FT_FREE( size->internal ); + FT_FREE( size ); + } + + + static void + ft_cmap_done_internal( FT_CMap cmap ); + + + static void + destroy_charmaps( FT_Face face, + FT_Memory memory ) + { + FT_Int n; + + + if ( !face ) + return; + + for ( n = 0; n < face->num_charmaps; n++ ) + { + FT_CMap cmap = FT_CMAP( face->charmaps[n] ); + + + ft_cmap_done_internal( cmap ); + + face->charmaps[n] = NULL; + } + + FT_FREE( face->charmaps ); + face->num_charmaps = 0; + } + + + /* destructor for faces list */ + static void + destroy_face( FT_Memory memory, + FT_Face face, + FT_Driver driver ) + { + FT_Driver_Class clazz = driver->clazz; + + + /* discard auto-hinting data */ + if ( face->autohint.finalizer ) + face->autohint.finalizer( face->autohint.data ); + + /* Discard glyph slots for this face. */ + /* Beware! FT_Done_GlyphSlot() changes the field `face->glyph' */ + while ( face->glyph ) + FT_Done_GlyphSlot( face->glyph ); + + /* discard all sizes for this face */ + FT_List_Finalize( &face->sizes_list, + (FT_List_Destructor)destroy_size, + memory, + driver ); + face->size = 0; + + /* now discard client data */ + if ( face->generic.finalizer ) + face->generic.finalizer( face ); + + /* discard charmaps */ + destroy_charmaps( face, memory ); + + /* finalize format-specific stuff */ + if ( clazz->done_face ) + clazz->done_face( face ); + + /* close the stream for this face if needed */ + FT_Stream_Free( + face->stream, + ( face->face_flags & FT_FACE_FLAG_EXTERNAL_STREAM ) != 0 ); + + face->stream = 0; + + /* get rid of it */ + if ( face->internal ) + { + FT_FREE( face->internal ); + } + FT_FREE( face ); + } + + + static void + Destroy_Driver( FT_Driver driver ) + { + FT_List_Finalize( &driver->faces_list, + (FT_List_Destructor)destroy_face, + driver->root.memory, + driver ); + + /* check whether we need to drop the driver's glyph loader */ + if ( FT_DRIVER_USES_OUTLINES( driver ) ) + FT_GlyphLoader_Done( driver->glyph_loader ); + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* find_unicode_charmap */ + /* */ + /* <Description> */ + /* This function finds a Unicode charmap, if there is one. */ + /* And if there is more than one, it tries to favour the more */ + /* extensive one, i.e., one that supports UCS-4 against those which */ + /* are limited to the BMP (said UCS-2 encoding.) */ + /* */ + /* This function is called from open_face() (just below), and also */ + /* from FT_Select_Charmap( ..., FT_ENCODING_UNICODE ). */ + /* */ + static FT_Error + find_unicode_charmap( FT_Face face ) + { + FT_CharMap* first; + FT_CharMap* cur; + + + /* caller should have already checked that `face' is valid */ + FT_ASSERT( face ); + + first = face->charmaps; + + if ( !first ) + return FT_Err_Invalid_CharMap_Handle; + + /* + * The original TrueType specification(s) only specified charmap + * formats that are capable of mapping 8 or 16 bit character codes to + * glyph indices. + * + * However, recent updates to the Apple and OpenType specifications + * introduced new formats that are capable of mapping 32-bit character + * codes as well. And these are already used on some fonts, mainly to + * map non-BMP Asian ideographs as defined in Unicode. + * + * For compatibility purposes, these fonts generally come with + * *several* Unicode charmaps: + * + * - One of them in the "old" 16-bit format, that cannot access + * all glyphs in the font. + * + * - Another one in the "new" 32-bit format, that can access all + * the glyphs. + * + * This function has been written to always favor a 32-bit charmap + * when found. Otherwise, a 16-bit one is returned when found. + */ + + /* Since the `interesting' table, with IDs (3,10), is normally the */ + /* last one, we loop backwards. This loses with type1 fonts with */ + /* non-BMP characters (<.0001%), this wins with .ttf with non-BMP */ + /* chars (.01% ?), and this is the same about 99.99% of the time! */ + + cur = first + face->num_charmaps; /* points after the last one */ + + for ( ; --cur >= first; ) + { + if ( cur[0]->encoding == FT_ENCODING_UNICODE ) + { + /* XXX If some new encodings to represent UCS-4 are added, */ + /* they should be added here. */ + if ( ( cur[0]->platform_id == TT_PLATFORM_MICROSOFT && + cur[0]->encoding_id == TT_MS_ID_UCS_4 ) || + ( cur[0]->platform_id == TT_PLATFORM_APPLE_UNICODE && + cur[0]->encoding_id == TT_APPLE_ID_UNICODE_32 ) ) + { + face->charmap = cur[0]; + return FT_Err_Ok; + } + } + } + + /* We do not have any UCS-4 charmap. */ + /* Do the loop again and search for UCS-2 charmaps. */ + cur = first + face->num_charmaps; + + for ( ; --cur >= first; ) + { + if ( cur[0]->encoding == FT_ENCODING_UNICODE ) + { + face->charmap = cur[0]; + return FT_Err_Ok; + } + } + + return FT_Err_Invalid_CharMap_Handle; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* find_variant_selector_charmap */ + /* */ + /* <Description> */ + /* This function finds the variant selector charmap, if there is one. */ + /* There can only be one (platform=0, specific=5, format=14). */ + /* */ + static FT_CharMap + find_variant_selector_charmap( FT_Face face ) + { + FT_CharMap* first; + FT_CharMap* end; + FT_CharMap* cur; + + + /* caller should have already checked that `face' is valid */ + FT_ASSERT( face ); + + first = face->charmaps; + + if ( !first ) + return NULL; + + end = first + face->num_charmaps; /* points after the last one */ + + for ( cur = first; cur < end; ++cur ) + { + if ( cur[0]->platform_id == TT_PLATFORM_APPLE_UNICODE && + cur[0]->encoding_id == TT_APPLE_ID_VARIANT_SELECTOR && + FT_Get_CMap_Format( cur[0] ) == 14 ) + return cur[0]; + } + + return NULL; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* open_face */ + /* */ + /* <Description> */ + /* This function does some work for FT_Open_Face(). */ + /* */ + static FT_Error + open_face( FT_Driver driver, + FT_Stream stream, + FT_Long face_index, + FT_Int num_params, + FT_Parameter* params, + FT_Face *aface ) + { + FT_Memory memory; + FT_Driver_Class clazz; + FT_Face face = 0; + FT_Error error, error2; + FT_Face_Internal internal = NULL; + + + clazz = driver->clazz; + memory = driver->root.memory; + + /* allocate the face object and perform basic initialization */ + if ( FT_ALLOC( face, clazz->face_object_size ) ) + goto Fail; + + if ( FT_NEW( internal ) ) + goto Fail; + + face->internal = internal; + + face->driver = driver; + face->memory = memory; + face->stream = stream; + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + { + int i; + + + face->internal->incremental_interface = 0; + for ( i = 0; i < num_params && !face->internal->incremental_interface; + i++ ) + if ( params[i].tag == FT_PARAM_TAG_INCREMENTAL ) + face->internal->incremental_interface = + (FT_Incremental_Interface)params[i].data; + } +#endif + + if ( clazz->init_face ) + error = clazz->init_face( stream, + face, + (FT_Int)face_index, + num_params, + params ); + if ( error ) + goto Fail; + + /* select Unicode charmap by default */ + error2 = find_unicode_charmap( face ); + + /* if no Unicode charmap can be found, FT_Err_Invalid_CharMap_Handle */ + /* is returned. */ + + /* no error should happen, but we want to play safe */ + if ( error2 && error2 != FT_Err_Invalid_CharMap_Handle ) + { + error = error2; + goto Fail; + } + + *aface = face; + + Fail: + if ( error ) + { + destroy_charmaps( face, memory ); + if ( clazz->done_face ) + clazz->done_face( face ); + FT_FREE( internal ); + FT_FREE( face ); + *aface = 0; + } + + return error; + } + + + /* there's a Mac-specific extended implementation of FT_New_Face() */ + /* in src/base/ftmac.c */ + +#if !defined( FT_MACINTOSH ) || defined( DARWIN_NO_CARBON ) + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_New_Face( FT_Library library, + const char* pathname, + FT_Long face_index, + FT_Face *aface ) + { + FT_Open_Args args; + + + /* test for valid `library' and `aface' delayed to FT_Open_Face() */ + if ( !pathname ) + return FT_Err_Invalid_Argument; + + args.flags = FT_OPEN_PATHNAME; + args.pathname = (char*)pathname; + args.stream = NULL; + + return FT_Open_Face( library, &args, face_index, aface ); + } + +#endif /* defined( FT_MACINTOSH ) && !defined( DARWIN_NO_CARBON ) */ + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_New_Memory_Face( FT_Library library, + const FT_Byte* file_base, + FT_Long file_size, + FT_Long face_index, + FT_Face *aface ) + { + FT_Open_Args args; + + + /* test for valid `library' and `face' delayed to FT_Open_Face() */ + if ( !file_base ) + return FT_Err_Invalid_Argument; + + args.flags = FT_OPEN_MEMORY; + args.memory_base = file_base; + args.memory_size = file_size; + args.stream = NULL; + + return FT_Open_Face( library, &args, face_index, aface ); + } + + +#ifdef FT_CONFIG_OPTION_MAC_FONTS + + /* The behavior here is very similar to that in base/ftmac.c, but it */ + /* is designed to work on non-mac systems, so no mac specific calls. */ + /* */ + /* We look at the file and determine if it is a mac dfont file or a mac */ + /* resource file, or a macbinary file containing a mac resource file. */ + /* */ + /* Unlike ftmac I'm not going to look at a `FOND'. I don't really see */ + /* the point, especially since there may be multiple `FOND' resources. */ + /* Instead I'll just look for `sfnt' and `POST' resources, ordered as */ + /* they occur in the file. */ + /* */ + /* Note that multiple `POST' resources do not mean multiple postscript */ + /* fonts; they all get jammed together to make what is essentially a */ + /* pfb file. */ + /* */ + /* We aren't interested in `NFNT' or `FONT' bitmap resources. */ + /* */ + /* As soon as we get an `sfnt' load it into memory and pass it off to */ + /* FT_Open_Face. */ + /* */ + /* If we have a (set of) `POST' resources, massage them into a (memory) */ + /* pfb file and pass that to FT_Open_Face. (As with ftmac.c I'm not */ + /* going to try to save the kerning info. After all that lives in the */ + /* `FOND' which isn't in the file containing the `POST' resources so */ + /* we don't really have access to it. */ + + + /* Finalizer for a memory stream; gets called by FT_Done_Face(). */ + /* It frees the memory it uses. */ + /* From ftmac.c. */ + static void + memory_stream_close( FT_Stream stream ) + { + FT_Memory memory = stream->memory; + + + FT_FREE( stream->base ); + + stream->size = 0; + stream->base = 0; + stream->close = 0; + } + + + /* Create a new memory stream from a buffer and a size. */ + /* From ftmac.c. */ + static FT_Error + new_memory_stream( FT_Library library, + FT_Byte* base, + FT_ULong size, + FT_Stream_CloseFunc close, + FT_Stream *astream ) + { + FT_Error error; + FT_Memory memory; + FT_Stream stream; + + + if ( !library ) + return FT_Err_Invalid_Library_Handle; + + if ( !base ) + return FT_Err_Invalid_Argument; + + *astream = 0; + memory = library->memory; + if ( FT_NEW( stream ) ) + goto Exit; + + FT_Stream_OpenMemory( stream, base, size ); + + stream->close = close; + + *astream = stream; + + Exit: + return error; + } + + + /* Create a new FT_Face given a buffer and a driver name. */ + /* from ftmac.c */ + FT_LOCAL_DEF( FT_Error ) + open_face_from_buffer( FT_Library library, + FT_Byte* base, + FT_ULong size, + FT_Long face_index, + const char* driver_name, + FT_Face *aface ) + { + FT_Open_Args args; + FT_Error error; + FT_Stream stream = NULL; + FT_Memory memory = library->memory; + + + error = new_memory_stream( library, + base, + size, + memory_stream_close, + &stream ); + if ( error ) + { + FT_FREE( base ); + return error; + } + + args.flags = FT_OPEN_STREAM; + args.stream = stream; + if ( driver_name ) + { + args.flags = args.flags | FT_OPEN_DRIVER; + args.driver = FT_Get_Module( library, driver_name ); + } + +#ifdef FT_MACINTOSH + /* At this point, face_index has served its purpose; */ + /* whoever calls this function has already used it to */ + /* locate the correct font data. We should not propagate */ + /* this index to FT_Open_Face() (unless it is negative). */ + + if ( face_index > 0 ) + face_index = 0; +#endif + + error = FT_Open_Face( library, &args, face_index, aface ); + + if ( error == FT_Err_Ok ) + (*aface)->face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM; + else +#ifdef FT_MACINTOSH + FT_Stream_Free( stream, 0 ); +#else + { + FT_Stream_Close( stream ); + FT_FREE( stream ); + } +#endif + + return error; + } + + + /* Look up `TYP1' or `CID ' table from sfnt table directory. */ + /* `offset' and `length' must exclude the binary header in tables. */ + + /* Type 1 and CID-keyed font drivers should recognize sfnt-wrapped */ + /* format too. Here, since we can't expect that the TrueType font */ + /* driver is loaded unconditially, we must parse the font by */ + /* ourselves. We are only interested in the name of the table and */ + /* the offset. */ + + static FT_Error + ft_lookup_PS_in_sfnt_stream( FT_Stream stream, + FT_Long face_index, + FT_ULong* offset, + FT_ULong* length, + FT_Bool* is_sfnt_cid ) + { + FT_Error error; + FT_UShort numTables; + FT_Long pstable_index; + FT_ULong tag; + int i; + + + *offset = 0; + *length = 0; + *is_sfnt_cid = FALSE; + + /* TODO: support for sfnt-wrapped PS/CID in TTC format */ + + /* version check for 'typ1' (should be ignored?) */ + if ( FT_READ_ULONG( tag ) ) + return error; + if ( tag != TTAG_typ1 ) + return FT_Err_Unknown_File_Format; + + if ( FT_READ_USHORT( numTables ) ) + return error; + if ( FT_STREAM_SKIP( 2 * 3 ) ) /* skip binary search header */ + return error; + + pstable_index = -1; + *is_sfnt_cid = FALSE; + + for ( i = 0; i < numTables; i++ ) + { + if ( FT_READ_ULONG( tag ) || FT_STREAM_SKIP( 4 ) || + FT_READ_ULONG( *offset ) || FT_READ_ULONG( *length ) ) + return error; + + if ( tag == TTAG_CID ) + { + pstable_index++; + *offset += 22; + *length -= 22; + *is_sfnt_cid = TRUE; + if ( face_index < 0 ) + return FT_Err_Ok; + } + else if ( tag == TTAG_TYP1 ) + { + pstable_index++; + *offset += 24; + *length -= 24; + *is_sfnt_cid = FALSE; + if ( face_index < 0 ) + return FT_Err_Ok; + } + if ( face_index >= 0 && pstable_index == face_index ) + return FT_Err_Ok; + } + return FT_Err_Table_Missing; + } + + + FT_LOCAL_DEF( FT_Error ) + open_face_PS_from_sfnt_stream( FT_Library library, + FT_Stream stream, + FT_Long face_index, + FT_Int num_params, + FT_Parameter *params, + FT_Face *aface ) + { + FT_Error error; + FT_Memory memory = library->memory; + FT_ULong offset, length; + FT_Long pos; + FT_Bool is_sfnt_cid; + FT_Byte* sfnt_ps; + + FT_UNUSED( num_params ); + FT_UNUSED( params ); + + + pos = FT_Stream_Pos( stream ); + + error = ft_lookup_PS_in_sfnt_stream( stream, + face_index, + &offset, + &length, + &is_sfnt_cid ); + if ( error ) + goto Exit; + + if ( FT_Stream_Seek( stream, pos + offset ) ) + goto Exit; + + if ( FT_ALLOC( sfnt_ps, (FT_Long)length ) ) + goto Exit; + + error = FT_Stream_Read( stream, (FT_Byte *)sfnt_ps, length ); + if ( error ) + goto Exit; + + error = open_face_from_buffer( library, + sfnt_ps, + length, + face_index < 0 ? face_index : 0, + is_sfnt_cid ? "cid" : "type1", + aface ); + Exit: + { + FT_Error error1; + + + if ( error == FT_Err_Unknown_File_Format ) + { + error1 = FT_Stream_Seek( stream, pos ); + if ( error1 ) + return error1; + } + + return error; + } + } + + +#if !defined( FT_MACINTOSH ) || defined( DARWIN_NO_CARBON ) + + /* The resource header says we've got resource_cnt `POST' (type1) */ + /* resources in this file. They all need to be coalesced into */ + /* one lump which gets passed on to the type1 driver. */ + /* Here can be only one PostScript font in a file so face_index */ + /* must be 0 (or -1). */ + /* */ + static FT_Error + Mac_Read_POST_Resource( FT_Library library, + FT_Stream stream, + FT_Long *offsets, + FT_Long resource_cnt, + FT_Long face_index, + FT_Face *aface ) + { + FT_Error error = FT_Err_Cannot_Open_Resource; + FT_Memory memory = library->memory; + FT_Byte* pfb_data; + int i, type, flags; + FT_Long len; + FT_Long pfb_len, pfb_pos, pfb_lenpos; + FT_Long rlen, temp; + + + if ( face_index == -1 ) + face_index = 0; + if ( face_index != 0 ) + return error; + + /* Find the length of all the POST resources, concatenated. Assume */ + /* worst case (each resource in its own section). */ + pfb_len = 0; + for ( i = 0; i < resource_cnt; ++i ) + { + error = FT_Stream_Seek( stream, offsets[i] ); + if ( error ) + goto Exit; + if ( FT_READ_LONG( temp ) ) + goto Exit; + pfb_len += temp + 6; + } + + if ( FT_ALLOC( pfb_data, (FT_Long)pfb_len + 2 ) ) + goto Exit; + + pfb_data[0] = 0x80; + pfb_data[1] = 1; /* Ascii section */ + pfb_data[2] = 0; /* 4-byte length, fill in later */ + pfb_data[3] = 0; + pfb_data[4] = 0; + pfb_data[5] = 0; + pfb_pos = 6; + pfb_lenpos = 2; + + len = 0; + type = 1; + for ( i = 0; i < resource_cnt; ++i ) + { + error = FT_Stream_Seek( stream, offsets[i] ); + if ( error ) + goto Exit2; + if ( FT_READ_LONG( rlen ) ) + goto Exit; + if ( FT_READ_USHORT( flags ) ) + goto Exit; + rlen -= 2; /* the flags are part of the resource */ + if ( ( flags >> 8 ) == type ) + len += rlen; + else + { + pfb_data[pfb_lenpos ] = (FT_Byte)( len ); + pfb_data[pfb_lenpos + 1] = (FT_Byte)( len >> 8 ); + pfb_data[pfb_lenpos + 2] = (FT_Byte)( len >> 16 ); + pfb_data[pfb_lenpos + 3] = (FT_Byte)( len >> 24 ); + + if ( ( flags >> 8 ) == 5 ) /* End of font mark */ + break; + + pfb_data[pfb_pos++] = 0x80; + + type = flags >> 8; + len = rlen; + + pfb_data[pfb_pos++] = (FT_Byte)type; + pfb_lenpos = pfb_pos; + pfb_data[pfb_pos++] = 0; /* 4-byte length, fill in later */ + pfb_data[pfb_pos++] = 0; + pfb_data[pfb_pos++] = 0; + pfb_data[pfb_pos++] = 0; + } + + error = FT_Stream_Read( stream, (FT_Byte *)pfb_data + pfb_pos, rlen ); + pfb_pos += rlen; + } + + pfb_data[pfb_pos++] = 0x80; + pfb_data[pfb_pos++] = 3; + + pfb_data[pfb_lenpos ] = (FT_Byte)( len ); + pfb_data[pfb_lenpos + 1] = (FT_Byte)( len >> 8 ); + pfb_data[pfb_lenpos + 2] = (FT_Byte)( len >> 16 ); + pfb_data[pfb_lenpos + 3] = (FT_Byte)( len >> 24 ); + + return open_face_from_buffer( library, + pfb_data, + pfb_pos, + face_index, + "type1", + aface ); + + Exit2: + FT_FREE( pfb_data ); + + Exit: + return error; + } + + + /* The resource header says we've got resource_cnt `sfnt' */ + /* (TrueType/OpenType) resources in this file. Look through */ + /* them for the one indicated by face_index, load it into mem, */ + /* pass it on the the truetype driver and return it. */ + /* */ + static FT_Error + Mac_Read_sfnt_Resource( FT_Library library, + FT_Stream stream, + FT_Long *offsets, + FT_Long resource_cnt, + FT_Long face_index, + FT_Face *aface ) + { + FT_Memory memory = library->memory; + FT_Byte* sfnt_data; + FT_Error error; + FT_Long flag_offset; + FT_Long rlen; + int is_cff; + FT_Long face_index_in_resource = 0; + + + if ( face_index == -1 ) + face_index = 0; + if ( face_index >= resource_cnt ) + return FT_Err_Cannot_Open_Resource; + + flag_offset = offsets[face_index]; + error = FT_Stream_Seek( stream, flag_offset ); + if ( error ) + goto Exit; + + if ( FT_READ_LONG( rlen ) ) + goto Exit; + if ( rlen == -1 ) + return FT_Err_Cannot_Open_Resource; + + error = open_face_PS_from_sfnt_stream( library, + stream, + face_index, + 0, NULL, + aface ); + if ( !error ) + goto Exit; + + /* rewind sfnt stream before open_face_PS_from_sfnt_stream() */ + if ( FT_Stream_Seek( stream, flag_offset + 4 ) ) + goto Exit; + + if ( FT_ALLOC( sfnt_data, (FT_Long)rlen ) ) + return error; + error = FT_Stream_Read( stream, (FT_Byte *)sfnt_data, rlen ); + if ( error ) + goto Exit; + + is_cff = rlen > 4 && !ft_memcmp( sfnt_data, "OTTO", 4 ); + error = open_face_from_buffer( library, + sfnt_data, + rlen, + face_index_in_resource, + is_cff ? "cff" : "truetype", + aface ); + + Exit: + return error; + } + + + /* Check for a valid resource fork header, or a valid dfont */ + /* header. In a resource fork the first 16 bytes are repeated */ + /* at the location specified by bytes 4-7. In a dfont bytes */ + /* 4-7 point to 16 bytes of zeroes instead. */ + /* */ + static FT_Error + IsMacResource( FT_Library library, + FT_Stream stream, + FT_Long resource_offset, + FT_Long face_index, + FT_Face *aface ) + { + FT_Memory memory = library->memory; + FT_Error error; + FT_Long map_offset, rdara_pos; + FT_Long *data_offsets; + FT_Long count; + + + error = FT_Raccess_Get_HeaderInfo( library, stream, resource_offset, + &map_offset, &rdara_pos ); + if ( error ) + return error; + + error = FT_Raccess_Get_DataOffsets( library, stream, + map_offset, rdara_pos, + TTAG_POST, + &data_offsets, &count ); + if ( !error ) + { + error = Mac_Read_POST_Resource( library, stream, data_offsets, count, + face_index, aface ); + FT_FREE( data_offsets ); + /* POST exists in an LWFN providing a single face */ + if ( !error ) + (*aface)->num_faces = 1; + return error; + } + + error = FT_Raccess_Get_DataOffsets( library, stream, + map_offset, rdara_pos, + TTAG_sfnt, + &data_offsets, &count ); + if ( !error ) + { + FT_Long face_index_internal = face_index % count; + + + error = Mac_Read_sfnt_Resource( library, stream, data_offsets, count, + face_index_internal, aface ); + FT_FREE( data_offsets ); + if ( !error ) + (*aface)->num_faces = count; + } + + return error; + } + + + /* Check for a valid macbinary header, and if we find one */ + /* check that the (flattened) resource fork in it is valid. */ + /* */ + static FT_Error + IsMacBinary( FT_Library library, + FT_Stream stream, + FT_Long face_index, + FT_Face *aface ) + { + unsigned char header[128]; + FT_Error error; + FT_Long dlen, offset; + + + if ( NULL == stream ) + return FT_Err_Invalid_Stream_Operation; + + error = FT_Stream_Seek( stream, 0 ); + if ( error ) + goto Exit; + + error = FT_Stream_Read( stream, (FT_Byte*)header, 128 ); + if ( error ) + goto Exit; + + if ( header[ 0] != 0 || + header[74] != 0 || + header[82] != 0 || + header[ 1] == 0 || + header[ 1] > 33 || + header[63] != 0 || + header[2 + header[1]] != 0 ) + return FT_Err_Unknown_File_Format; + + dlen = ( header[0x53] << 24 ) | + ( header[0x54] << 16 ) | + ( header[0x55] << 8 ) | + header[0x56]; +#if 0 + rlen = ( header[0x57] << 24 ) | + ( header[0x58] << 16 ) | + ( header[0x59] << 8 ) | + header[0x5a]; +#endif /* 0 */ + offset = 128 + ( ( dlen + 127 ) & ~127 ); + + return IsMacResource( library, stream, offset, face_index, aface ); + + Exit: + return error; + } + + + static FT_Error + load_face_in_embedded_rfork( FT_Library library, + FT_Stream stream, + FT_Long face_index, + FT_Face *aface, + const FT_Open_Args *args ) + { + +#undef FT_COMPONENT +#define FT_COMPONENT trace_raccess + + FT_Memory memory = library->memory; + FT_Error error = FT_Err_Unknown_File_Format; + int i; + + char * file_names[FT_RACCESS_N_RULES]; + FT_Long offsets[FT_RACCESS_N_RULES]; + FT_Error errors[FT_RACCESS_N_RULES]; + + FT_Open_Args args2; + FT_Stream stream2 = 0; + + + FT_Raccess_Guess( library, stream, + args->pathname, file_names, offsets, errors ); + + for ( i = 0; i < FT_RACCESS_N_RULES; i++ ) + { + if ( errors[i] ) + { + FT_TRACE3(( "Error[%d] has occurred in rule %d\n", errors[i], i )); + continue; + } + + args2.flags = FT_OPEN_PATHNAME; + args2.pathname = file_names[i] ? file_names[i] : args->pathname; + + FT_TRACE3(( "Try rule %d: %s (offset=%d) ...", + i, args2.pathname, offsets[i] )); + + error = FT_Stream_New( library, &args2, &stream2 ); + if ( error ) + { + FT_TRACE3(( "failed\n" )); + continue; + } + + error = IsMacResource( library, stream2, offsets[i], + face_index, aface ); + FT_Stream_Free( stream2, 0 ); + + FT_TRACE3(( "%s\n", error ? "failed": "successful" )); + + if ( !error ) + break; + } + + for (i = 0; i < FT_RACCESS_N_RULES; i++) + { + if ( file_names[i] ) + FT_FREE( file_names[i] ); + } + + /* Caller (load_mac_face) requires FT_Err_Unknown_File_Format. */ + if ( error ) + error = FT_Err_Unknown_File_Format; + + return error; + +#undef FT_COMPONENT +#define FT_COMPONENT trace_objs + + } + + + /* Check for some macintosh formats without Carbon framework. */ + /* Is this a macbinary file? If so look at the resource fork. */ + /* Is this a mac dfont file? */ + /* Is this an old style resource fork? (in data) */ + /* Else call load_face_in_embedded_rfork to try extra rules */ + /* (defined in `ftrfork.c'). */ + /* */ + static FT_Error + load_mac_face( FT_Library library, + FT_Stream stream, + FT_Long face_index, + FT_Face *aface, + const FT_Open_Args *args ) + { + FT_Error error; + FT_UNUSED( args ); + + + error = IsMacBinary( library, stream, face_index, aface ); + if ( FT_ERROR_BASE( error ) == FT_Err_Unknown_File_Format ) + { + +#undef FT_COMPONENT +#define FT_COMPONENT trace_raccess + + FT_TRACE3(( "Try as dfont: %s ...", args->pathname )); + + error = IsMacResource( library, stream, 0, face_index, aface ); + + FT_TRACE3(( "%s\n", error ? "failed" : "successful" )); + +#undef FT_COMPONENT +#define FT_COMPONENT trace_objs + + } + + if ( ( FT_ERROR_BASE( error ) == FT_Err_Unknown_File_Format || + FT_ERROR_BASE( error ) == FT_Err_Invalid_Stream_Operation ) && + ( args->flags & FT_OPEN_PATHNAME ) ) + error = load_face_in_embedded_rfork( library, stream, + face_index, aface, args ); + return error; + } +#endif + +#endif /* !FT_MACINTOSH && FT_CONFIG_OPTION_MAC_FONTS */ + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Open_Face( FT_Library library, + const FT_Open_Args* args, + FT_Long face_index, + FT_Face *aface ) + { + FT_Error error; + FT_Driver driver; + FT_Memory memory; + FT_Stream stream = 0; + FT_Face face = 0; + FT_ListNode node = 0; + FT_Bool external_stream; + FT_Module* cur; + FT_Module* limit; + + + /* test for valid `library' delayed to */ + /* FT_Stream_New() */ + + if ( ( !aface && face_index >= 0 ) || !args ) + return FT_Err_Invalid_Argument; + + external_stream = FT_BOOL( ( args->flags & FT_OPEN_STREAM ) && + args->stream ); + + /* create input stream */ + error = FT_Stream_New( library, args, &stream ); + if ( error ) + goto Fail3; + + memory = library->memory; + + /* If the font driver is specified in the `args' structure, use */ + /* it. Otherwise, we scan the list of registered drivers. */ + if ( ( args->flags & FT_OPEN_DRIVER ) && args->driver ) + { + driver = FT_DRIVER( args->driver ); + + /* not all modules are drivers, so check... */ + if ( FT_MODULE_IS_DRIVER( driver ) ) + { + FT_Int num_params = 0; + FT_Parameter* params = 0; + + + if ( args->flags & FT_OPEN_PARAMS ) + { + num_params = args->num_params; + params = args->params; + } + + error = open_face( driver, stream, face_index, + num_params, params, &face ); + if ( !error ) + goto Success; + } + else + error = FT_Err_Invalid_Handle; + + FT_Stream_Free( stream, external_stream ); + goto Fail; + } + else + { + /* check each font driver for an appropriate format */ + cur = library->modules; + limit = cur + library->num_modules; + + + for ( ; cur < limit; cur++ ) + { + /* not all modules are font drivers, so check... */ + if ( FT_MODULE_IS_DRIVER( cur[0] ) ) + { + FT_Int num_params = 0; + FT_Parameter* params = 0; + + + driver = FT_DRIVER( cur[0] ); + + if ( args->flags & FT_OPEN_PARAMS ) + { + num_params = args->num_params; + params = args->params; + } + + error = open_face( driver, stream, face_index, + num_params, params, &face ); + if ( !error ) + goto Success; + +#ifdef FT_CONFIG_OPTION_MAC_FONTS + if ( ft_strcmp( cur[0]->clazz->module_name, "truetype" ) == 0 && + FT_ERROR_BASE( error ) == FT_Err_Table_Missing ) + { + /* TrueType but essential tables are missing */ + if ( FT_Stream_Seek( stream, 0 ) ) + break; + + error = open_face_PS_from_sfnt_stream( library, + stream, + face_index, + num_params, + params, + aface ); + if ( !error ) + { + FT_Stream_Free( stream, external_stream ); + return error; + } + } +#endif + + if ( FT_ERROR_BASE( error ) != FT_Err_Unknown_File_Format ) + goto Fail3; + } + } + + Fail3: + /* If we are on the mac, and we get an FT_Err_Invalid_Stream_Operation */ + /* it may be because we have an empty data fork, so we need to check */ + /* the resource fork. */ + if ( FT_ERROR_BASE( error ) != FT_Err_Cannot_Open_Stream && + FT_ERROR_BASE( error ) != FT_Err_Unknown_File_Format && + FT_ERROR_BASE( error ) != FT_Err_Invalid_Stream_Operation ) + goto Fail2; + +#if !defined( FT_MACINTOSH ) && defined( FT_CONFIG_OPTION_MAC_FONTS ) + error = load_mac_face( library, stream, face_index, aface, args ); + if ( !error ) + { + /* We don't want to go to Success here. We've already done that. */ + /* On the other hand, if we succeeded we still need to close this */ + /* stream (we opened a different stream which extracted the */ + /* interesting information out of this stream here. That stream */ + /* will still be open and the face will point to it). */ + FT_Stream_Free( stream, external_stream ); + return error; + } + + if ( FT_ERROR_BASE( error ) != FT_Err_Unknown_File_Format ) + goto Fail2; +#endif /* !FT_MACINTOSH && FT_CONFIG_OPTION_MAC_FONTS */ + + /* no driver is able to handle this format */ + error = FT_Err_Unknown_File_Format; + + Fail2: + FT_Stream_Free( stream, external_stream ); + goto Fail; + } + + Success: + FT_TRACE4(( "FT_Open_Face: New face object, adding to list\n" )); + + /* set the FT_FACE_FLAG_EXTERNAL_STREAM bit for FT_Done_Face */ + if ( external_stream ) + face->face_flags |= FT_FACE_FLAG_EXTERNAL_STREAM; + + /* add the face object to its driver's list */ + if ( FT_NEW( node ) ) + goto Fail; + + node->data = face; + /* don't assume driver is the same as face->driver, so use */ + /* face->driver instead. */ + FT_List_Add( &face->driver->faces_list, node ); + + /* now allocate a glyph slot object for the face */ + FT_TRACE4(( "FT_Open_Face: Creating glyph slot\n" )); + + if ( face_index >= 0 ) + { + error = FT_New_GlyphSlot( face, NULL ); + if ( error ) + goto Fail; + + /* finally, allocate a size object for the face */ + { + FT_Size size; + + + FT_TRACE4(( "FT_Open_Face: Creating size object\n" )); + + error = FT_New_Size( face, &size ); + if ( error ) + goto Fail; + + face->size = size; + } + } + + /* some checks */ + + if ( FT_IS_SCALABLE( face ) ) + { + if ( face->height < 0 ) + face->height = (FT_Short)-face->height; + + if ( !FT_HAS_VERTICAL( face ) ) + face->max_advance_height = (FT_Short)face->height; + } + + if ( FT_HAS_FIXED_SIZES( face ) ) + { + FT_Int i; + + + for ( i = 0; i < face->num_fixed_sizes; i++ ) + { + FT_Bitmap_Size* bsize = face->available_sizes + i; + + + if ( bsize->height < 0 ) + bsize->height = (FT_Short)-bsize->height; + if ( bsize->x_ppem < 0 ) + bsize->x_ppem = (FT_Short)-bsize->x_ppem; + if ( bsize->y_ppem < 0 ) + bsize->y_ppem = -bsize->y_ppem; + } + } + + /* initialize internal face data */ + { + FT_Face_Internal internal = face->internal; + + + internal->transform_matrix.xx = 0x10000L; + internal->transform_matrix.xy = 0; + internal->transform_matrix.yx = 0; + internal->transform_matrix.yy = 0x10000L; + + internal->transform_delta.x = 0; + internal->transform_delta.y = 0; + } + + if ( aface ) + *aface = face; + else + FT_Done_Face( face ); + + goto Exit; + + Fail: + FT_Done_Face( face ); + + Exit: + FT_TRACE4(( "FT_Open_Face: Return %d\n", error )); + + return error; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Attach_File( FT_Face face, + const char* filepathname ) + { + FT_Open_Args open; + + + /* test for valid `face' delayed to FT_Attach_Stream() */ + + if ( !filepathname ) + return FT_Err_Invalid_Argument; + + open.stream = NULL; + open.flags = FT_OPEN_PATHNAME; + open.pathname = (char*)filepathname; + + return FT_Attach_Stream( face, &open ); + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Attach_Stream( FT_Face face, + FT_Open_Args* parameters ) + { + FT_Stream stream; + FT_Error error; + FT_Driver driver; + + FT_Driver_Class clazz; + + + /* test for valid `parameters' delayed to FT_Stream_New() */ + + if ( !face ) + return FT_Err_Invalid_Face_Handle; + + driver = face->driver; + if ( !driver ) + return FT_Err_Invalid_Driver_Handle; + + error = FT_Stream_New( driver->root.library, parameters, &stream ); + if ( error ) + goto Exit; + + /* we implement FT_Attach_Stream in each driver through the */ + /* `attach_file' interface */ + + error = FT_Err_Unimplemented_Feature; + clazz = driver->clazz; + if ( clazz->attach_file ) + error = clazz->attach_file( face, stream ); + + /* close the attached stream */ + FT_Stream_Free( stream, + (FT_Bool)( parameters->stream && + ( parameters->flags & FT_OPEN_STREAM ) ) ); + + Exit: + return error; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Done_Face( FT_Face face ) + { + FT_Error error; + FT_Driver driver; + FT_Memory memory; + FT_ListNode node; + + + error = FT_Err_Invalid_Face_Handle; + if ( face && face->driver ) + { + driver = face->driver; + memory = driver->root.memory; + + /* find face in driver's list */ + node = FT_List_Find( &driver->faces_list, face ); + if ( node ) + { + /* remove face object from the driver's list */ + FT_List_Remove( &driver->faces_list, node ); + FT_FREE( node ); + + /* now destroy the object proper */ + destroy_face( memory, face, driver ); + error = FT_Err_Ok; + } + } + return error; + } + + + /* documentation is in ftobjs.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_New_Size( FT_Face face, + FT_Size *asize ) + { + FT_Error error; + FT_Memory memory; + FT_Driver driver; + FT_Driver_Class clazz; + + FT_Size size = 0; + FT_ListNode node = 0; + + + if ( !face ) + return FT_Err_Invalid_Face_Handle; + + if ( !asize ) + return FT_Err_Invalid_Size_Handle; + + if ( !face->driver ) + return FT_Err_Invalid_Driver_Handle; + + *asize = 0; + + driver = face->driver; + clazz = driver->clazz; + memory = face->memory; + + /* Allocate new size object and perform basic initialisation */ + if ( FT_ALLOC( size, clazz->size_object_size ) || FT_NEW( node ) ) + goto Exit; + + size->face = face; + + /* for now, do not use any internal fields in size objects */ + size->internal = 0; + + if ( clazz->init_size ) + error = clazz->init_size( size ); + + /* in case of success, add to the face's list */ + if ( !error ) + { + *asize = size; + node->data = size; + FT_List_Add( &face->sizes_list, node ); + } + + Exit: + if ( error ) + { + FT_FREE( node ); + FT_FREE( size ); + } + + return error; + } + + + /* documentation is in ftobjs.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Done_Size( FT_Size size ) + { + FT_Error error; + FT_Driver driver; + FT_Memory memory; + FT_Face face; + FT_ListNode node; + + + if ( !size ) + return FT_Err_Invalid_Size_Handle; + + face = size->face; + if ( !face ) + return FT_Err_Invalid_Face_Handle; + + driver = face->driver; + if ( !driver ) + return FT_Err_Invalid_Driver_Handle; + + memory = driver->root.memory; + + error = FT_Err_Ok; + node = FT_List_Find( &face->sizes_list, size ); + if ( node ) + { + FT_List_Remove( &face->sizes_list, node ); + FT_FREE( node ); + + if ( face->size == size ) + { + face->size = 0; + if ( face->sizes_list.head ) + face->size = (FT_Size)(face->sizes_list.head->data); + } + + destroy_size( memory, size, driver ); + } + else + error = FT_Err_Invalid_Size_Handle; + + return error; + } + + + /* documentation is in ftobjs.h */ + + FT_BASE_DEF( FT_Error ) + FT_Match_Size( FT_Face face, + FT_Size_Request req, + FT_Bool ignore_width, + FT_ULong* size_index ) + { + FT_Int i; + FT_Long w, h; + + + if ( !FT_HAS_FIXED_SIZES( face ) ) + return FT_Err_Invalid_Face_Handle; + + /* FT_Bitmap_Size doesn't provide enough info... */ + if ( req->type != FT_SIZE_REQUEST_TYPE_NOMINAL ) + return FT_Err_Unimplemented_Feature; + + w = FT_REQUEST_WIDTH ( req ); + h = FT_REQUEST_HEIGHT( req ); + + if ( req->width && !req->height ) + h = w; + else if ( !req->width && req->height ) + w = h; + + w = FT_PIX_ROUND( w ); + h = FT_PIX_ROUND( h ); + + for ( i = 0; i < face->num_fixed_sizes; i++ ) + { + FT_Bitmap_Size* bsize = face->available_sizes + i; + + + if ( h != FT_PIX_ROUND( bsize->y_ppem ) ) + continue; + + if ( w == FT_PIX_ROUND( bsize->x_ppem ) || ignore_width ) + { + if ( size_index ) + *size_index = (FT_ULong)i; + + return FT_Err_Ok; + } + } + + return FT_Err_Invalid_Pixel_Size; + } + + + /* documentation is in ftobjs.h */ + + FT_BASE_DEF( void ) + ft_synthesize_vertical_metrics( FT_Glyph_Metrics* metrics, + FT_Pos advance ) + { + FT_Pos height = metrics->height; + + + /* compensate for glyph with bbox above/below the baseline */ + if ( metrics->horiBearingY < 0 ) + { + if ( height < metrics->horiBearingY ) + height = metrics->horiBearingY; + } + else if ( metrics->horiBearingY > 0 ) + height -= metrics->horiBearingY; + + /* the factor 1.2 is a heuristical value */ + if ( !advance ) + advance = height * 12 / 10; + + metrics->vertBearingX = metrics->horiBearingX - metrics->horiAdvance / 2; + metrics->vertBearingY = ( advance - height ) / 2; + metrics->vertAdvance = advance; + } + + + static void + ft_recompute_scaled_metrics( FT_Face face, + FT_Size_Metrics* metrics ) + { + /* Compute root ascender, descender, test height, and max_advance */ + +#ifdef GRID_FIT_METRICS + metrics->ascender = FT_PIX_CEIL( FT_MulFix( face->ascender, + metrics->y_scale ) ); + + metrics->descender = FT_PIX_FLOOR( FT_MulFix( face->descender, + metrics->y_scale ) ); + + metrics->height = FT_PIX_ROUND( FT_MulFix( face->height, + metrics->y_scale ) ); + + metrics->max_advance = FT_PIX_ROUND( FT_MulFix( face->max_advance_width, + metrics->x_scale ) ); +#else /* !GRID_FIT_METRICS */ + metrics->ascender = FT_MulFix( face->ascender, + metrics->y_scale ); + + metrics->descender = FT_MulFix( face->descender, + metrics->y_scale ); + + metrics->height = FT_MulFix( face->height, + metrics->y_scale ); + + metrics->max_advance = FT_MulFix( face->max_advance_width, + metrics->x_scale ); +#endif /* !GRID_FIT_METRICS */ + } + + + FT_BASE_DEF( void ) + FT_Select_Metrics( FT_Face face, + FT_ULong strike_index ) + { + FT_Size_Metrics* metrics; + FT_Bitmap_Size* bsize; + + + metrics = &face->size->metrics; + bsize = face->available_sizes + strike_index; + + metrics->x_ppem = (FT_UShort)( ( bsize->x_ppem + 32 ) >> 6 ); + metrics->y_ppem = (FT_UShort)( ( bsize->y_ppem + 32 ) >> 6 ); + + if ( FT_IS_SCALABLE( face ) ) + { + metrics->x_scale = FT_DivFix( bsize->x_ppem, + face->units_per_EM ); + metrics->y_scale = FT_DivFix( bsize->y_ppem, + face->units_per_EM ); + + ft_recompute_scaled_metrics( face, metrics ); + } + else + { + metrics->x_scale = 1L << 16; + metrics->y_scale = 1L << 16; + metrics->ascender = bsize->y_ppem; + metrics->descender = 0; + metrics->height = bsize->height << 6; + metrics->max_advance = bsize->x_ppem; + } + } + + + FT_BASE_DEF( void ) + FT_Request_Metrics( FT_Face face, + FT_Size_Request req ) + { + FT_Size_Metrics* metrics; + + + metrics = &face->size->metrics; + + if ( FT_IS_SCALABLE( face ) ) + { + FT_Long w = 0, h = 0, scaled_w = 0, scaled_h = 0; + + + switch ( req->type ) + { + case FT_SIZE_REQUEST_TYPE_NOMINAL: + w = h = face->units_per_EM; + break; + + case FT_SIZE_REQUEST_TYPE_REAL_DIM: + w = h = face->ascender - face->descender; + break; + + case FT_SIZE_REQUEST_TYPE_BBOX: + w = face->bbox.xMax - face->bbox.xMin; + h = face->bbox.yMax - face->bbox.yMin; + break; + + case FT_SIZE_REQUEST_TYPE_CELL: + w = face->max_advance_width; + h = face->ascender - face->descender; + break; + + case FT_SIZE_REQUEST_TYPE_SCALES: + metrics->x_scale = (FT_Fixed)req->width; + metrics->y_scale = (FT_Fixed)req->height; + if ( !metrics->x_scale ) + metrics->x_scale = metrics->y_scale; + else if ( !metrics->y_scale ) + metrics->y_scale = metrics->x_scale; + goto Calculate_Ppem; + + case FT_SIZE_REQUEST_TYPE_MAX: + break; + } + + /* to be on the safe side */ + if ( w < 0 ) + w = -w; + + if ( h < 0 ) + h = -h; + + scaled_w = FT_REQUEST_WIDTH ( req ); + scaled_h = FT_REQUEST_HEIGHT( req ); + + /* determine scales */ + if ( req->width ) + { + metrics->x_scale = FT_DivFix( scaled_w, w ); + + if ( req->height ) + { + metrics->y_scale = FT_DivFix( scaled_h, h ); + + if ( req->type == FT_SIZE_REQUEST_TYPE_CELL ) + { + if ( metrics->y_scale > metrics->x_scale ) + metrics->y_scale = metrics->x_scale; + else + metrics->x_scale = metrics->y_scale; + } + } + else + { + metrics->y_scale = metrics->x_scale; + scaled_h = FT_MulDiv( scaled_w, h, w ); + } + } + else + { + metrics->x_scale = metrics->y_scale = FT_DivFix( scaled_h, h ); + scaled_w = FT_MulDiv( scaled_h, w, h ); + } + + Calculate_Ppem: + /* calculate the ppems */ + if ( req->type != FT_SIZE_REQUEST_TYPE_NOMINAL ) + { + scaled_w = FT_MulFix( face->units_per_EM, metrics->x_scale ); + scaled_h = FT_MulFix( face->units_per_EM, metrics->y_scale ); + } + + metrics->x_ppem = (FT_UShort)( ( scaled_w + 32 ) >> 6 ); + metrics->y_ppem = (FT_UShort)( ( scaled_h + 32 ) >> 6 ); + + ft_recompute_scaled_metrics( face, metrics ); + } + else + { + FT_ZERO( metrics ); + metrics->x_scale = 1L << 16; + metrics->y_scale = 1L << 16; + } + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Select_Size( FT_Face face, + FT_Int strike_index ) + { + FT_Driver_Class clazz; + + + if ( !face || !FT_HAS_FIXED_SIZES( face ) ) + return FT_Err_Invalid_Face_Handle; + + if ( strike_index < 0 || strike_index >= face->num_fixed_sizes ) + return FT_Err_Invalid_Argument; + + clazz = face->driver->clazz; + + if ( clazz->select_size ) + return clazz->select_size( face->size, (FT_ULong)strike_index ); + + FT_Select_Metrics( face, (FT_ULong)strike_index ); + + return FT_Err_Ok; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Request_Size( FT_Face face, + FT_Size_Request req ) + { + FT_Driver_Class clazz; + FT_ULong strike_index; + + + if ( !face ) + return FT_Err_Invalid_Face_Handle; + + if ( !req || req->width < 0 || req->height < 0 || + req->type >= FT_SIZE_REQUEST_TYPE_MAX ) + return FT_Err_Invalid_Argument; + + clazz = face->driver->clazz; + + if ( clazz->request_size ) + return clazz->request_size( face->size, req ); + + /* + * The reason that a driver doesn't have `request_size' defined is + * either that the scaling here suffices or that the supported formats + * are bitmap-only and size matching is not implemented. + * + * In the latter case, a simple size matching is done. + */ + if ( !FT_IS_SCALABLE( face ) && FT_HAS_FIXED_SIZES( face ) ) + { + FT_Error error; + + + error = FT_Match_Size( face, req, 0, &strike_index ); + if ( error ) + return error; + + FT_TRACE3(( "FT_Request_Size: bitmap strike %lu matched\n", + strike_index )); + + return FT_Select_Size( face, (FT_Int)strike_index ); + } + + FT_Request_Metrics( face, req ); + + return FT_Err_Ok; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Set_Char_Size( FT_Face face, + FT_F26Dot6 char_width, + FT_F26Dot6 char_height, + FT_UInt horz_resolution, + FT_UInt vert_resolution ) + { + FT_Size_RequestRec req; + + + if ( !char_width ) + char_width = char_height; + else if ( !char_height ) + char_height = char_width; + + if ( !horz_resolution ) + horz_resolution = vert_resolution; + else if ( !vert_resolution ) + vert_resolution = horz_resolution; + + if ( char_width < 1 * 64 ) + char_width = 1 * 64; + if ( char_height < 1 * 64 ) + char_height = 1 * 64; + + if ( !horz_resolution ) + horz_resolution = vert_resolution = 72; + + req.type = FT_SIZE_REQUEST_TYPE_NOMINAL; + req.width = char_width; + req.height = char_height; + req.horiResolution = horz_resolution; + req.vertResolution = vert_resolution; + + return FT_Request_Size( face, &req ); + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Set_Pixel_Sizes( FT_Face face, + FT_UInt pixel_width, + FT_UInt pixel_height ) + { + FT_Size_RequestRec req; + + + if ( pixel_width == 0 ) + pixel_width = pixel_height; + else if ( pixel_height == 0 ) + pixel_height = pixel_width; + + if ( pixel_width < 1 ) + pixel_width = 1; + if ( pixel_height < 1 ) + pixel_height = 1; + + /* use `>=' to avoid potential compiler warning on 16bit platforms */ + if ( pixel_width >= 0xFFFFU ) + pixel_width = 0xFFFFU; + if ( pixel_height >= 0xFFFFU ) + pixel_height = 0xFFFFU; + + req.type = FT_SIZE_REQUEST_TYPE_NOMINAL; + req.width = pixel_width << 6; + req.height = pixel_height << 6; + req.horiResolution = 0; + req.vertResolution = 0; + + return FT_Request_Size( face, &req ); + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_Kerning( FT_Face face, + FT_UInt left_glyph, + FT_UInt right_glyph, + FT_UInt kern_mode, + FT_Vector *akerning ) + { + FT_Error error = FT_Err_Ok; + FT_Driver driver; + + + if ( !face ) + return FT_Err_Invalid_Face_Handle; + + if ( !akerning ) + return FT_Err_Invalid_Argument; + + driver = face->driver; + + akerning->x = 0; + akerning->y = 0; + + if ( driver->clazz->get_kerning ) + { + error = driver->clazz->get_kerning( face, + left_glyph, + right_glyph, + akerning ); + if ( !error ) + { + if ( kern_mode != FT_KERNING_UNSCALED ) + { + akerning->x = FT_MulFix( akerning->x, face->size->metrics.x_scale ); + akerning->y = FT_MulFix( akerning->y, face->size->metrics.y_scale ); + + if ( kern_mode != FT_KERNING_UNFITTED ) + { + /* we scale down kerning values for small ppem values */ + /* to avoid that rounding makes them too big. */ + /* `25' has been determined heuristically. */ + if ( face->size->metrics.x_ppem < 25 ) + akerning->x = FT_MulDiv( akerning->x, + face->size->metrics.x_ppem, 25 ); + if ( face->size->metrics.y_ppem < 25 ) + akerning->y = FT_MulDiv( akerning->y, + face->size->metrics.y_ppem, 25 ); + + akerning->x = FT_PIX_ROUND( akerning->x ); + akerning->y = FT_PIX_ROUND( akerning->y ); + } + } + } + } + + return error; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_Track_Kerning( FT_Face face, + FT_Fixed point_size, + FT_Int degree, + FT_Fixed* akerning ) + { + FT_Service_Kerning service; + FT_Error error = FT_Err_Ok; + + + if ( !face ) + return FT_Err_Invalid_Face_Handle; + + if ( !akerning ) + return FT_Err_Invalid_Argument; + + FT_FACE_FIND_SERVICE( face, service, KERNING ); + if ( !service ) + return FT_Err_Unimplemented_Feature; + + error = service->get_track( face, + point_size, + degree, + akerning ); + + return error; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Select_Charmap( FT_Face face, + FT_Encoding encoding ) + { + FT_CharMap* cur; + FT_CharMap* limit; + + + if ( !face ) + return FT_Err_Invalid_Face_Handle; + + if ( encoding == FT_ENCODING_NONE ) + return FT_Err_Invalid_Argument; + + /* FT_ENCODING_UNICODE is special. We try to find the `best' Unicode */ + /* charmap available, i.e., one with UCS-4 characters, if possible. */ + /* */ + /* This is done by find_unicode_charmap() above, to share code. */ + if ( encoding == FT_ENCODING_UNICODE ) + return find_unicode_charmap( face ); + + cur = face->charmaps; + if ( !cur ) + return FT_Err_Invalid_CharMap_Handle; + + limit = cur + face->num_charmaps; + + for ( ; cur < limit; cur++ ) + { + if ( cur[0]->encoding == encoding ) + { + face->charmap = cur[0]; + return 0; + } + } + + return FT_Err_Invalid_Argument; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Set_Charmap( FT_Face face, + FT_CharMap charmap ) + { + FT_CharMap* cur; + FT_CharMap* limit; + + + if ( !face ) + return FT_Err_Invalid_Face_Handle; + + cur = face->charmaps; + if ( !cur ) + return FT_Err_Invalid_CharMap_Handle; + if ( FT_Get_CMap_Format( charmap ) == 14 ) + return FT_Err_Invalid_Argument; + + limit = cur + face->num_charmaps; + + for ( ; cur < limit; cur++ ) + { + if ( cur[0] == charmap ) + { + face->charmap = cur[0]; + return 0; + } + } + return FT_Err_Invalid_Argument; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Int ) + FT_Get_Charmap_Index( FT_CharMap charmap ) + { + FT_Int i; + + + for ( i = 0; i < charmap->face->num_charmaps; i++ ) + if ( charmap->face->charmaps[i] == charmap ) + break; + + FT_ASSERT( i < charmap->face->num_charmaps ); + + return i; + } + + + static void + ft_cmap_done_internal( FT_CMap cmap ) + { + FT_CMap_Class clazz = cmap->clazz; + FT_Face face = cmap->charmap.face; + FT_Memory memory = FT_FACE_MEMORY(face); + + + if ( clazz->done ) + clazz->done( cmap ); + + FT_FREE( cmap ); + } + + + FT_BASE_DEF( void ) + FT_CMap_Done( FT_CMap cmap ) + { + if ( cmap ) + { + FT_Face face = cmap->charmap.face; + FT_Memory memory = FT_FACE_MEMORY( face ); + FT_Error error; + FT_Int i, j; + + + for ( i = 0; i < face->num_charmaps; i++ ) + { + if ( (FT_CMap)face->charmaps[i] == cmap ) + { + FT_CharMap last_charmap = face->charmaps[face->num_charmaps - 1]; + + + if ( FT_RENEW_ARRAY( face->charmaps, + face->num_charmaps, + face->num_charmaps - 1 ) ) + return; + + /* remove it from our list of charmaps */ + for ( j = i + 1; j < face->num_charmaps; j++ ) + { + if ( j == face->num_charmaps - 1 ) + face->charmaps[j - 1] = last_charmap; + else + face->charmaps[j - 1] = face->charmaps[j]; + } + + face->num_charmaps--; + + if ( (FT_CMap)face->charmap == cmap ) + face->charmap = NULL; + + ft_cmap_done_internal( cmap ); + + break; + } + } + } + } + + + FT_BASE_DEF( FT_Error ) + FT_CMap_New( FT_CMap_Class clazz, + FT_Pointer init_data, + FT_CharMap charmap, + FT_CMap *acmap ) + { + FT_Error error = FT_Err_Ok; + FT_Face face; + FT_Memory memory; + FT_CMap cmap; + + + if ( clazz == NULL || charmap == NULL || charmap->face == NULL ) + return FT_Err_Invalid_Argument; + + face = charmap->face; + memory = FT_FACE_MEMORY( face ); + + if ( !FT_ALLOC( cmap, clazz->size ) ) + { + cmap->charmap = *charmap; + cmap->clazz = clazz; + + if ( clazz->init ) + { + error = clazz->init( cmap, init_data ); + if ( error ) + goto Fail; + } + + /* add it to our list of charmaps */ + if ( FT_RENEW_ARRAY( face->charmaps, + face->num_charmaps, + face->num_charmaps + 1 ) ) + goto Fail; + + face->charmaps[face->num_charmaps++] = (FT_CharMap)cmap; + } + + Exit: + if ( acmap ) + *acmap = cmap; + + return error; + + Fail: + ft_cmap_done_internal( cmap ); + cmap = NULL; + goto Exit; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_UInt ) + FT_Get_Char_Index( FT_Face face, + FT_ULong charcode ) + { + FT_UInt result = 0; + + + if ( face && face->charmap ) + { + FT_CMap cmap = FT_CMAP( face->charmap ); + + + if ( charcode > 0xFFFFFFFFUL ) + { + FT_TRACE1(( "FT_Get_Char_Index: too large charcode" )); + FT_TRACE1(( " 0x%x is truncated\n", charcode )); + } + result = cmap->clazz->char_index( cmap, (FT_UInt32)charcode ); + } + return result; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_ULong ) + FT_Get_First_Char( FT_Face face, + FT_UInt *agindex ) + { + FT_ULong result = 0; + FT_UInt gindex = 0; + + + if ( face && face->charmap ) + { + gindex = FT_Get_Char_Index( face, 0 ); + if ( gindex == 0 ) + result = FT_Get_Next_Char( face, 0, &gindex ); + } + + if ( agindex ) + *agindex = gindex; + + return result; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_ULong ) + FT_Get_Next_Char( FT_Face face, + FT_ULong charcode, + FT_UInt *agindex ) + { + FT_ULong result = 0; + FT_UInt gindex = 0; + + + if ( face && face->charmap ) + { + FT_UInt32 code = (FT_UInt32)charcode; + FT_CMap cmap = FT_CMAP( face->charmap ); + + + gindex = cmap->clazz->char_next( cmap, &code ); + result = ( gindex == 0 ) ? 0 : code; + } + + if ( agindex ) + *agindex = gindex; + + return result; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_UInt ) + FT_Face_GetCharVariantIndex( FT_Face face, + FT_ULong charcode, + FT_ULong variantSelector ) + { + FT_UInt result = 0; + + + if ( face && face->charmap && + face->charmap->encoding == FT_ENCODING_UNICODE ) + { + FT_CharMap charmap = find_variant_selector_charmap( face ); + FT_CMap ucmap = FT_CMAP( face->charmap ); + + + if ( charmap != NULL ) + { + FT_CMap vcmap = FT_CMAP( charmap ); + + + if ( charcode > 0xFFFFFFFFUL ) + { + FT_TRACE1(( "FT_Get_Char_Index: too large charcode" )); + FT_TRACE1(( " 0x%x is truncated\n", charcode )); + } + if ( variantSelector > 0xFFFFFFFFUL ) + { + FT_TRACE1(( "FT_Get_Char_Index: too large variantSelector" )); + FT_TRACE1(( " 0x%x is truncated\n", variantSelector )); + } + + result = vcmap->clazz->char_var_index( vcmap, ucmap, + (FT_UInt32)charcode, + (FT_UInt32)variantSelector ); + } + } + + return result; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Int ) + FT_Face_GetCharVariantIsDefault( FT_Face face, + FT_ULong charcode, + FT_ULong variantSelector ) + { + FT_Int result = -1; + + + if ( face ) + { + FT_CharMap charmap = find_variant_selector_charmap( face ); + + + if ( charmap != NULL ) + { + FT_CMap vcmap = FT_CMAP( charmap ); + + + if ( charcode > 0xFFFFFFFFUL ) + { + FT_TRACE1(( "FT_Get_Char_Index: too large charcode" )); + FT_TRACE1(( " 0x%x is truncated\n", charcode )); + } + if ( variantSelector > 0xFFFFFFFFUL ) + { + FT_TRACE1(( "FT_Get_Char_Index: too large variantSelector" )); + FT_TRACE1(( " 0x%x is truncated\n", variantSelector )); + } + + result = vcmap->clazz->char_var_default( vcmap, + (FT_UInt32)charcode, + (FT_UInt32)variantSelector ); + } + } + + return result; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_UInt32* ) + FT_Face_GetVariantSelectors( FT_Face face ) + { + FT_UInt32 *result = NULL; + + + if ( face ) + { + FT_CharMap charmap = find_variant_selector_charmap( face ); + + + if ( charmap != NULL ) + { + FT_CMap vcmap = FT_CMAP( charmap ); + FT_Memory memory = FT_FACE_MEMORY( face ); + + + result = vcmap->clazz->variant_list( vcmap, memory ); + } + } + + return result; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_UInt32* ) + FT_Face_GetVariantsOfChar( FT_Face face, + FT_ULong charcode ) + { + FT_UInt32 *result = NULL; + + + if ( face ) + { + FT_CharMap charmap = find_variant_selector_charmap( face ); + + + if ( charmap != NULL ) + { + FT_CMap vcmap = FT_CMAP( charmap ); + FT_Memory memory = FT_FACE_MEMORY( face ); + + + if ( charcode > 0xFFFFFFFFUL ) + { + FT_TRACE1(( "FT_Get_Char_Index: too large charcode" )); + FT_TRACE1(( " 0x%x is truncated\n", charcode )); + } + + result = vcmap->clazz->charvariant_list( vcmap, memory, + (FT_UInt32)charcode ); + } + } + return result; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_UInt32* ) + FT_Face_GetCharsOfVariant( FT_Face face, + FT_ULong variantSelector ) + { + FT_UInt32 *result = NULL; + + + if ( face ) + { + FT_CharMap charmap = find_variant_selector_charmap( face ); + + + if ( charmap != NULL ) + { + FT_CMap vcmap = FT_CMAP( charmap ); + FT_Memory memory = FT_FACE_MEMORY( face ); + + + if ( variantSelector > 0xFFFFFFFFUL ) + { + FT_TRACE1(( "FT_Get_Char_Index: too large variantSelector" )); + FT_TRACE1(( " 0x%x is truncated\n", variantSelector )); + } + + result = vcmap->clazz->variantchar_list( vcmap, memory, + (FT_UInt32)variantSelector ); + } + } + + return result; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_UInt ) + FT_Get_Name_Index( FT_Face face, + FT_String* glyph_name ) + { + FT_UInt result = 0; + + + if ( face && FT_HAS_GLYPH_NAMES( face ) ) + { + FT_Service_GlyphDict service; + + + FT_FACE_LOOKUP_SERVICE( face, + service, + GLYPH_DICT ); + + if ( service && service->name_index ) + result = service->name_index( face, glyph_name ); + } + + return result; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_Glyph_Name( FT_Face face, + FT_UInt glyph_index, + FT_Pointer buffer, + FT_UInt buffer_max ) + { + FT_Error error = FT_Err_Invalid_Argument; + + + /* clean up buffer */ + if ( buffer && buffer_max > 0 ) + ((FT_Byte*)buffer)[0] = 0; + + if ( face && + (FT_Long)glyph_index <= face->num_glyphs && + FT_HAS_GLYPH_NAMES( face ) ) + { + FT_Service_GlyphDict service; + + + FT_FACE_LOOKUP_SERVICE( face, + service, + GLYPH_DICT ); + + if ( service && service->get_name ) + error = service->get_name( face, glyph_index, buffer, buffer_max ); + } + + return error; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( const char* ) + FT_Get_Postscript_Name( FT_Face face ) + { + const char* result = NULL; + + + if ( !face ) + goto Exit; + + if ( !result ) + { + FT_Service_PsFontName service; + + + FT_FACE_LOOKUP_SERVICE( face, + service, + POSTSCRIPT_FONT_NAME ); + + if ( service && service->get_ps_font_name ) + result = service->get_ps_font_name( face ); + } + + Exit: + return result; + } + + + /* documentation is in tttables.h */ + + FT_EXPORT_DEF( void* ) + FT_Get_Sfnt_Table( FT_Face face, + FT_Sfnt_Tag tag ) + { + void* table = 0; + FT_Service_SFNT_Table service; + + + if ( face && FT_IS_SFNT( face ) ) + { + FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE ); + if ( service != NULL ) + table = service->get_table( face, tag ); + } + + return table; + } + + + /* documentation is in tttables.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Load_Sfnt_Table( FT_Face face, + FT_ULong tag, + FT_Long offset, + FT_Byte* buffer, + FT_ULong* length ) + { + FT_Service_SFNT_Table service; + + + if ( !face || !FT_IS_SFNT( face ) ) + return FT_Err_Invalid_Face_Handle; + + FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE ); + if ( service == NULL ) + return FT_Err_Unimplemented_Feature; + + return service->load_table( face, tag, offset, buffer, length ); + } + + + /* documentation is in tttables.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Sfnt_Table_Info( FT_Face face, + FT_UInt table_index, + FT_ULong *tag, + FT_ULong *length ) + { + FT_Service_SFNT_Table service; + FT_ULong offset; + + + if ( !face || !FT_IS_SFNT( face ) ) + return FT_Err_Invalid_Face_Handle; + + FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE ); + if ( service == NULL ) + return FT_Err_Unimplemented_Feature; + + return service->table_info( face, table_index, tag, &offset, length ); + } + + + /* documentation is in tttables.h */ + + FT_EXPORT_DEF( FT_ULong ) + FT_Get_CMap_Language_ID( FT_CharMap charmap ) + { + FT_Service_TTCMaps service; + FT_Face face; + TT_CMapInfo cmap_info; + + + if ( !charmap || !charmap->face ) + return 0; + + face = charmap->face; + FT_FACE_FIND_SERVICE( face, service, TT_CMAP ); + if ( service == NULL ) + return 0; + if ( service->get_cmap_info( charmap, &cmap_info )) + return 0; + + return cmap_info.language; + } + + + /* documentation is in tttables.h */ + + FT_EXPORT_DEF( FT_Long ) + FT_Get_CMap_Format( FT_CharMap charmap ) + { + FT_Service_TTCMaps service; + FT_Face face; + TT_CMapInfo cmap_info; + + + if ( !charmap || !charmap->face ) + return -1; + + face = charmap->face; + FT_FACE_FIND_SERVICE( face, service, TT_CMAP ); + if ( service == NULL ) + return -1; + if ( service->get_cmap_info( charmap, &cmap_info )) + return -1; + + return cmap_info.format; + } + + + /* documentation is in ftsizes.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Activate_Size( FT_Size size ) + { + FT_Face face; + + + if ( size == NULL ) + return FT_Err_Invalid_Argument; + + face = size->face; + if ( face == NULL || face->driver == NULL ) + return FT_Err_Invalid_Argument; + + /* we don't need anything more complex than that; all size objects */ + /* are already listed by the face */ + face->size = size; + + return FT_Err_Ok; + } + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** R E N D E R E R S ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + /* lookup a renderer by glyph format in the library's list */ + FT_BASE_DEF( FT_Renderer ) + FT_Lookup_Renderer( FT_Library library, + FT_Glyph_Format format, + FT_ListNode* node ) + { + FT_ListNode cur; + FT_Renderer result = 0; + + + if ( !library ) + goto Exit; + + cur = library->renderers.head; + + if ( node ) + { + if ( *node ) + cur = (*node)->next; + *node = 0; + } + + while ( cur ) + { + FT_Renderer renderer = FT_RENDERER( cur->data ); + + + if ( renderer->glyph_format == format ) + { + if ( node ) + *node = cur; + + result = renderer; + break; + } + cur = cur->next; + } + + Exit: + return result; + } + + + static FT_Renderer + ft_lookup_glyph_renderer( FT_GlyphSlot slot ) + { + FT_Face face = slot->face; + FT_Library library = FT_FACE_LIBRARY( face ); + FT_Renderer result = library->cur_renderer; + + + if ( !result || result->glyph_format != slot->format ) + result = FT_Lookup_Renderer( library, slot->format, 0 ); + + return result; + } + + + static void + ft_set_current_renderer( FT_Library library ) + { + FT_Renderer renderer; + + + renderer = FT_Lookup_Renderer( library, FT_GLYPH_FORMAT_OUTLINE, 0 ); + library->cur_renderer = renderer; + } + + + static FT_Error + ft_add_renderer( FT_Module module ) + { + FT_Library library = module->library; + FT_Memory memory = library->memory; + FT_Error error; + FT_ListNode node; + + + if ( FT_NEW( node ) ) + goto Exit; + + { + FT_Renderer render = FT_RENDERER( module ); + FT_Renderer_Class* clazz = (FT_Renderer_Class*)module->clazz; + + + render->clazz = clazz; + render->glyph_format = clazz->glyph_format; + + /* allocate raster object if needed */ + if ( clazz->glyph_format == FT_GLYPH_FORMAT_OUTLINE && + clazz->raster_class->raster_new ) + { + error = clazz->raster_class->raster_new( memory, &render->raster ); + if ( error ) + goto Fail; + + render->raster_render = clazz->raster_class->raster_render; + render->render = clazz->render_glyph; + } + + /* add to list */ + node->data = module; + FT_List_Add( &library->renderers, node ); + + ft_set_current_renderer( library ); + } + + Fail: + if ( error ) + FT_FREE( node ); + + Exit: + return error; + } + + + static void + ft_remove_renderer( FT_Module module ) + { + FT_Library library = module->library; + FT_Memory memory = library->memory; + FT_ListNode node; + + + node = FT_List_Find( &library->renderers, module ); + if ( node ) + { + FT_Renderer render = FT_RENDERER( module ); + + + /* release raster object, if any */ + if ( render->raster ) + render->clazz->raster_class->raster_done( render->raster ); + + /* remove from list */ + FT_List_Remove( &library->renderers, node ); + FT_FREE( node ); + + ft_set_current_renderer( library ); + } + } + + + /* documentation is in ftrender.h */ + + FT_EXPORT_DEF( FT_Renderer ) + FT_Get_Renderer( FT_Library library, + FT_Glyph_Format format ) + { + /* test for valid `library' delayed to FT_Lookup_Renderer() */ + + return FT_Lookup_Renderer( library, format, 0 ); + } + + + /* documentation is in ftrender.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Set_Renderer( FT_Library library, + FT_Renderer renderer, + FT_UInt num_params, + FT_Parameter* parameters ) + { + FT_ListNode node; + FT_Error error = FT_Err_Ok; + + + if ( !library ) + return FT_Err_Invalid_Library_Handle; + + if ( !renderer ) + return FT_Err_Invalid_Argument; + + node = FT_List_Find( &library->renderers, renderer ); + if ( !node ) + { + error = FT_Err_Invalid_Argument; + goto Exit; + } + + FT_List_Up( &library->renderers, node ); + + if ( renderer->glyph_format == FT_GLYPH_FORMAT_OUTLINE ) + library->cur_renderer = renderer; + + if ( num_params > 0 ) + { + FT_Renderer_SetModeFunc set_mode = renderer->clazz->set_mode; + + + for ( ; num_params > 0; num_params-- ) + { + error = set_mode( renderer, parameters->tag, parameters->data ); + if ( error ) + break; + } + } + + Exit: + return error; + } + + + FT_BASE_DEF( FT_Error ) + FT_Render_Glyph_Internal( FT_Library library, + FT_GlyphSlot slot, + FT_Render_Mode render_mode ) + { + FT_Error error = FT_Err_Ok; + FT_Renderer renderer; + + + /* if it is already a bitmap, no need to do anything */ + switch ( slot->format ) + { + case FT_GLYPH_FORMAT_BITMAP: /* already a bitmap, don't do anything */ + break; + + default: + { + FT_ListNode node = 0; + FT_Bool update = 0; + + + /* small shortcut for the very common case */ + if ( slot->format == FT_GLYPH_FORMAT_OUTLINE ) + { + renderer = library->cur_renderer; + node = library->renderers.head; + } + else + renderer = FT_Lookup_Renderer( library, slot->format, &node ); + + error = FT_Err_Unimplemented_Feature; + while ( renderer ) + { + error = renderer->render( renderer, slot, render_mode, NULL ); + if ( !error || + FT_ERROR_BASE( error ) != FT_Err_Cannot_Render_Glyph ) + break; + + /* FT_Err_Cannot_Render_Glyph is returned if the render mode */ + /* is unsupported by the current renderer for this glyph image */ + /* format. */ + + /* now, look for another renderer that supports the same */ + /* format. */ + renderer = FT_Lookup_Renderer( library, slot->format, &node ); + update = 1; + } + + /* if we changed the current renderer for the glyph image format */ + /* we need to select it as the next current one */ + if ( !error && update && renderer ) + FT_Set_Renderer( library, renderer, 0, 0 ); + } + } + + return error; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Render_Glyph( FT_GlyphSlot slot, + FT_Render_Mode render_mode ) + { + FT_Library library; + + + if ( !slot ) + return FT_Err_Invalid_Argument; + + library = FT_FACE_LIBRARY( slot->face ); + + return FT_Render_Glyph_Internal( library, slot, render_mode ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** M O D U L E S ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Destroy_Module */ + /* */ + /* <Description> */ + /* Destroys a given module object. For drivers, this also destroys */ + /* all child faces. */ + /* */ + /* <InOut> */ + /* module :: A handle to the target driver object. */ + /* */ + /* <Note> */ + /* The driver _must_ be LOCKED! */ + /* */ + static void + Destroy_Module( FT_Module module ) + { + FT_Memory memory = module->memory; + FT_Module_Class* clazz = module->clazz; + FT_Library library = module->library; + + + /* finalize client-data - before anything else */ + if ( module->generic.finalizer ) + module->generic.finalizer( module ); + + if ( library && library->auto_hinter == module ) + library->auto_hinter = 0; + + /* if the module is a renderer */ + if ( FT_MODULE_IS_RENDERER( module ) ) + ft_remove_renderer( module ); + + /* if the module is a font driver, add some steps */ + if ( FT_MODULE_IS_DRIVER( module ) ) + Destroy_Driver( FT_DRIVER( module ) ); + + /* finalize the module object */ + if ( clazz->module_done ) + clazz->module_done( module ); + + /* discard it */ + FT_FREE( module ); + } + + + /* documentation is in ftmodapi.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Add_Module( FT_Library library, + const FT_Module_Class* clazz ) + { + FT_Error error; + FT_Memory memory; + FT_Module module; + FT_UInt nn; + + +#define FREETYPE_VER_FIXED ( ( (FT_Long)FREETYPE_MAJOR << 16 ) | \ + FREETYPE_MINOR ) + + if ( !library ) + return FT_Err_Invalid_Library_Handle; + + if ( !clazz ) + return FT_Err_Invalid_Argument; + + /* check freetype version */ + if ( clazz->module_requires > FREETYPE_VER_FIXED ) + return FT_Err_Invalid_Version; + + /* look for a module with the same name in the library's table */ + for ( nn = 0; nn < library->num_modules; nn++ ) + { + module = library->modules[nn]; + if ( ft_strcmp( module->clazz->module_name, clazz->module_name ) == 0 ) + { + /* this installed module has the same name, compare their versions */ + if ( clazz->module_version <= module->clazz->module_version ) + return FT_Err_Lower_Module_Version; + + /* remove the module from our list, then exit the loop to replace */ + /* it by our new version.. */ + FT_Remove_Module( library, module ); + break; + } + } + + memory = library->memory; + error = FT_Err_Ok; + + if ( library->num_modules >= FT_MAX_MODULES ) + { + error = FT_Err_Too_Many_Drivers; + goto Exit; + } + + /* allocate module object */ + if ( FT_ALLOC( module, clazz->module_size ) ) + goto Exit; + + /* base initialization */ + module->library = library; + module->memory = memory; + module->clazz = (FT_Module_Class*)clazz; + + /* check whether the module is a renderer - this must be performed */ + /* before the normal module initialization */ + if ( FT_MODULE_IS_RENDERER( module ) ) + { + /* add to the renderers list */ + error = ft_add_renderer( module ); + if ( error ) + goto Fail; + } + + /* is the module a auto-hinter? */ + if ( FT_MODULE_IS_HINTER( module ) ) + library->auto_hinter = module; + + /* if the module is a font driver */ + if ( FT_MODULE_IS_DRIVER( module ) ) + { + /* allocate glyph loader if needed */ + FT_Driver driver = FT_DRIVER( module ); + + + driver->clazz = (FT_Driver_Class)module->clazz; + if ( FT_DRIVER_USES_OUTLINES( driver ) ) + { + error = FT_GlyphLoader_New( memory, &driver->glyph_loader ); + if ( error ) + goto Fail; + } + } + + if ( clazz->module_init ) + { + error = clazz->module_init( module ); + if ( error ) + goto Fail; + } + + /* add module to the library's table */ + library->modules[library->num_modules++] = module; + + Exit: + return error; + + Fail: + if ( FT_MODULE_IS_DRIVER( module ) ) + { + FT_Driver driver = FT_DRIVER( module ); + + + if ( FT_DRIVER_USES_OUTLINES( driver ) ) + FT_GlyphLoader_Done( driver->glyph_loader ); + } + + if ( FT_MODULE_IS_RENDERER( module ) ) + { + FT_Renderer renderer = FT_RENDERER( module ); + + + if ( renderer->raster ) + renderer->clazz->raster_class->raster_done( renderer->raster ); + } + + FT_FREE( module ); + goto Exit; + } + + + /* documentation is in ftmodapi.h */ + + FT_EXPORT_DEF( FT_Module ) + FT_Get_Module( FT_Library library, + const char* module_name ) + { + FT_Module result = 0; + FT_Module* cur; + FT_Module* limit; + + + if ( !library || !module_name ) + return result; + + cur = library->modules; + limit = cur + library->num_modules; + + for ( ; cur < limit; cur++ ) + if ( ft_strcmp( cur[0]->clazz->module_name, module_name ) == 0 ) + { + result = cur[0]; + break; + } + + return result; + } + + + /* documentation is in ftobjs.h */ + + FT_BASE_DEF( const void* ) + FT_Get_Module_Interface( FT_Library library, + const char* mod_name ) + { + FT_Module module; + + + /* test for valid `library' delayed to FT_Get_Module() */ + + module = FT_Get_Module( library, mod_name ); + + return module ? module->clazz->module_interface : 0; + } + + + FT_BASE_DEF( FT_Pointer ) + ft_module_get_service( FT_Module module, + const char* service_id ) + { + FT_Pointer result = NULL; + + if ( module ) + { + FT_ASSERT( module->clazz && module->clazz->get_interface ); + + /* first, look for the service in the module + */ + if ( module->clazz->get_interface ) + result = module->clazz->get_interface( module, service_id ); + + if ( result == NULL ) + { + /* we didn't find it, look in all other modules then + */ + FT_Library library = module->library; + FT_Module* cur = library->modules; + FT_Module* limit = cur + library->num_modules; + + for ( ; cur < limit; cur++ ) + { + if ( cur[0] != module ) + { + FT_ASSERT( cur[0]->clazz ); + + if ( cur[0]->clazz->get_interface ) + { + result = cur[0]->clazz->get_interface( cur[0], service_id ); + if ( result != NULL ) + break; + } + } + } + } + } + + return result; + } + + + /* documentation is in ftmodapi.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Remove_Module( FT_Library library, + FT_Module module ) + { + /* try to find the module from the table, then remove it from there */ + + if ( !library ) + return FT_Err_Invalid_Library_Handle; + + if ( module ) + { + FT_Module* cur = library->modules; + FT_Module* limit = cur + library->num_modules; + + + for ( ; cur < limit; cur++ ) + { + if ( cur[0] == module ) + { + /* remove it from the table */ + library->num_modules--; + limit--; + while ( cur < limit ) + { + cur[0] = cur[1]; + cur++; + } + limit[0] = 0; + + /* destroy the module */ + Destroy_Module( module ); + + return FT_Err_Ok; + } + } + } + return FT_Err_Invalid_Driver_Handle; + } + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** L I B R A R Y ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /* documentation is in ftmodapi.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_New_Library( FT_Memory memory, + FT_Library *alibrary ) + { + FT_Library library = 0; + FT_Error error; + + + if ( !memory ) + return FT_Err_Invalid_Argument; + +#ifdef FT_DEBUG_LEVEL_ERROR + /* init debugging support */ + ft_debug_init(); +#endif + + /* first of all, allocate the library object */ + if ( FT_NEW( library ) ) + return error; + + library->memory = memory; + +#ifdef FT_CONFIG_OPTION_PIC + /* initialize position independent code containers */ + error = ft_pic_container_init( library ); + if ( error ) + goto Fail; +#endif + + /* allocate the render pool */ + library->raster_pool_size = FT_RENDER_POOL_SIZE; +#if FT_RENDER_POOL_SIZE > 0 + if ( FT_ALLOC( library->raster_pool, FT_RENDER_POOL_SIZE ) ) + goto Fail; +#endif + + library->version_major = FREETYPE_MAJOR; + library->version_minor = FREETYPE_MINOR; + library->version_patch = FREETYPE_PATCH; + + /* That's ok now */ + *alibrary = library; + + return FT_Err_Ok; + + Fail: +#ifdef FT_CONFIG_OPTION_PIC + ft_pic_container_destroy( library ); +#endif + FT_FREE( library ); + return error; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( void ) + FT_Library_Version( FT_Library library, + FT_Int *amajor, + FT_Int *aminor, + FT_Int *apatch ) + { + FT_Int major = 0; + FT_Int minor = 0; + FT_Int patch = 0; + + + if ( library ) + { + major = library->version_major; + minor = library->version_minor; + patch = library->version_patch; + } + + if ( amajor ) + *amajor = major; + + if ( aminor ) + *aminor = minor; + + if ( apatch ) + *apatch = patch; + } + + + /* documentation is in ftmodapi.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Done_Library( FT_Library library ) + { + FT_Memory memory; + + + if ( !library ) + return FT_Err_Invalid_Library_Handle; + + memory = library->memory; + + /* Discard client-data */ + if ( library->generic.finalizer ) + library->generic.finalizer( library ); + + /* Close all faces in the library. If we don't do + * this, we can have some subtle memory leaks. + * Example: + * + * - the cff font driver uses the pshinter module in cff_size_done + * - if the pshinter module is destroyed before the cff font driver, + * opened FT_Face objects managed by the driver are not properly + * destroyed, resulting in a memory leak + */ + { + FT_UInt n; + + + for ( n = 0; n < library->num_modules; n++ ) + { + FT_Module module = library->modules[n]; + FT_List faces; + + + if ( ( module->clazz->module_flags & FT_MODULE_FONT_DRIVER ) == 0 ) + continue; + + faces = &FT_DRIVER(module)->faces_list; + while ( faces->head ) + { + FT_Done_Face( FT_FACE( faces->head->data ) ); + if ( faces->head ) + FT_TRACE0(( "FT_Done_Library: failed to free some faces\n" )); + } + } + } + + /* Close all other modules in the library */ +#if 1 + /* XXX Modules are removed in the reversed order so that */ + /* type42 module is removed before truetype module. This */ + /* avoids double free in some occasions. It is a hack. */ + while ( library->num_modules > 0 ) + FT_Remove_Module( library, + library->modules[library->num_modules - 1] ); +#else + { + FT_UInt n; + + + for ( n = 0; n < library->num_modules; n++ ) + { + FT_Module module = library->modules[n]; + + + if ( module ) + { + Destroy_Module( module ); + library->modules[n] = 0; + } + } + } +#endif + + /* Destroy raster objects */ + FT_FREE( library->raster_pool ); + library->raster_pool_size = 0; + +#ifdef FT_CONFIG_OPTION_PIC + /* Destroy pic container contents */ + ft_pic_container_destroy( library ); +#endif + + FT_FREE( library ); + return FT_Err_Ok; + } + + + /* documentation is in ftmodapi.h */ + + FT_EXPORT_DEF( void ) + FT_Set_Debug_Hook( FT_Library library, + FT_UInt hook_index, + FT_DebugHook_Func debug_hook ) + { + if ( library && debug_hook && + hook_index < + ( sizeof ( library->debug_hooks ) / sizeof ( void* ) ) ) + library->debug_hooks[hook_index] = debug_hook; + } + + + /* documentation is in ftmodapi.h */ + + FT_EXPORT_DEF( FT_TrueTypeEngineType ) + FT_Get_TrueType_Engine_Type( FT_Library library ) + { + FT_TrueTypeEngineType result = FT_TRUETYPE_ENGINE_TYPE_NONE; + + + if ( library ) + { + FT_Module module = FT_Get_Module( library, "truetype" ); + + + if ( module ) + { + FT_Service_TrueTypeEngine service; + + + service = (FT_Service_TrueTypeEngine) + ft_module_get_service( module, + FT_SERVICE_ID_TRUETYPE_ENGINE ); + if ( service ) + result = service->engine_type; + } + } + + return result; + } + + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + + FT_BASE_DEF( FT_Error ) + ft_stub_set_char_sizes( FT_Size size, + FT_F26Dot6 width, + FT_F26Dot6 height, + FT_UInt horz_res, + FT_UInt vert_res ) + { + FT_Size_RequestRec req; + FT_Driver driver = size->face->driver; + + + if ( driver->clazz->request_size ) + { + req.type = FT_SIZE_REQUEST_TYPE_NOMINAL; + req.width = width; + req.height = height; + + if ( horz_res == 0 ) + horz_res = vert_res; + + if ( vert_res == 0 ) + vert_res = horz_res; + + if ( horz_res == 0 ) + horz_res = vert_res = 72; + + req.horiResolution = horz_res; + req.vertResolution = vert_res; + + return driver->clazz->request_size( size, &req ); + } + + return 0; + } + + + FT_BASE_DEF( FT_Error ) + ft_stub_set_pixel_sizes( FT_Size size, + FT_UInt width, + FT_UInt height ) + { + FT_Size_RequestRec req; + FT_Driver driver = size->face->driver; + + + if ( driver->clazz->request_size ) + { + req.type = FT_SIZE_REQUEST_TYPE_NOMINAL; + req.width = width << 6; + req.height = height << 6; + req.horiResolution = 0; + req.vertResolution = 0; + + return driver->clazz->request_size( size, &req ); + } + + return 0; + } + +#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */ + + + FT_EXPORT_DEF( FT_Error ) + FT_Get_SubGlyph_Info( FT_GlyphSlot glyph, + FT_UInt sub_index, + FT_Int *p_index, + FT_UInt *p_flags, + FT_Int *p_arg1, + FT_Int *p_arg2, + FT_Matrix *p_transform ) + { + FT_Error error = FT_Err_Invalid_Argument; + + + if ( glyph != NULL && + glyph->format == FT_GLYPH_FORMAT_COMPOSITE && + sub_index < glyph->num_subglyphs ) + { + FT_SubGlyph subg = glyph->subglyphs + sub_index; + + + *p_index = subg->index; + *p_flags = subg->flags; + *p_arg1 = subg->arg1; + *p_arg2 = subg->arg2; + *p_transform = subg->transform; + } + + return error; + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/base/ftotval.c b/mod/pub.mod/freetype.mod/src/base/ftotval.c new file mode 100644 index 0000000..20ed686 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/base/ftotval.c @@ -0,0 +1,84 @@ +/***************************************************************************/ +/* */ +/* ftotval.c */ +/* */ +/* FreeType API for validating OpenType tables (body). */ +/* */ +/* Copyright 2004, 2006, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H +#include FT_SERVICE_OPENTYPE_VALIDATE_H +#include FT_OPENTYPE_VALIDATE_H + + + /* documentation is in ftotval.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_OpenType_Validate( FT_Face face, + FT_UInt validation_flags, + FT_Bytes *BASE_table, + FT_Bytes *GDEF_table, + FT_Bytes *GPOS_table, + FT_Bytes *GSUB_table, + FT_Bytes *JSTF_table ) + { + FT_Service_OTvalidate service; + FT_Error error; + + + if ( !face ) + { + error = FT_Err_Invalid_Face_Handle; + goto Exit; + } + + if ( !( BASE_table && + GDEF_table && + GPOS_table && + GSUB_table && + JSTF_table ) ) + { + error = FT_Err_Invalid_Argument; + goto Exit; + } + + FT_FACE_FIND_GLOBAL_SERVICE( face, service, OPENTYPE_VALIDATE ); + + if ( service ) + error = service->validate( face, + validation_flags, + BASE_table, + GDEF_table, + GPOS_table, + GSUB_table, + JSTF_table ); + else + error = FT_Err_Unimplemented_Feature; + + Exit: + return error; + } + + + FT_EXPORT_DEF( void ) + FT_OpenType_Free( FT_Face face, + FT_Bytes table ) + { + FT_Memory memory = FT_FACE_MEMORY( face ); + + + FT_FREE( table ); + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/base/ftoutln.c b/mod/pub.mod/freetype.mod/src/base/ftoutln.c new file mode 100644 index 0000000..49ef82e --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/base/ftoutln.c @@ -0,0 +1,1128 @@ +/***************************************************************************/ +/* */ +/* ftoutln.c */ +/* */ +/* FreeType outline management (body). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* All functions are declared in freetype.h. */ + /* */ + /*************************************************************************/ + + +#include <ft2build.h> +#include FT_OUTLINE_H +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_DEBUG_H +#include FT_TRIGONOMETRY_H + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_outline + + + static + const FT_Outline null_outline = { 0, 0, 0, 0, 0, 0 }; + + + /* documentation is in ftoutln.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Outline_Decompose( FT_Outline* outline, + const FT_Outline_Funcs* func_interface, + void* user ) + { +#undef SCALED +#define SCALED( x ) ( ( (x) << shift ) - delta ) + + FT_Vector v_last; + FT_Vector v_control; + FT_Vector v_start; + + FT_Vector* point; + FT_Vector* limit; + char* tags; + + FT_Error error; + + FT_Int n; /* index of contour in outline */ + FT_UInt first; /* index of first point in contour */ + FT_Int tag; /* current point's state */ + + FT_Int shift; + FT_Pos delta; + + + if ( !outline || !func_interface ) + return FT_Err_Invalid_Argument; + + shift = func_interface->shift; + delta = func_interface->delta; + first = 0; + + for ( n = 0; n < outline->n_contours; n++ ) + { + FT_Int last; /* index of last point in contour */ + + + FT_TRACE5(( "FT_Outline_Decompose: Outline %d\n", n )); + + last = outline->contours[n]; + if ( last < 0 ) + goto Invalid_Outline; + limit = outline->points + last; + + v_start = outline->points[first]; + v_start.x = SCALED( v_start.x ); + v_start.y = SCALED( v_start.y ); + + v_last = outline->points[last]; + v_last.x = SCALED( v_last.x ); + v_last.y = SCALED( v_last.y ); + + v_control = v_start; + + point = outline->points + first; + tags = outline->tags + first; + tag = FT_CURVE_TAG( tags[0] ); + + /* A contour cannot start with a cubic control point! */ + if ( tag == FT_CURVE_TAG_CUBIC ) + goto Invalid_Outline; + + /* check first point to determine origin */ + if ( tag == FT_CURVE_TAG_CONIC ) + { + /* first point is conic control. Yes, this happens. */ + if ( FT_CURVE_TAG( outline->tags[last] ) == FT_CURVE_TAG_ON ) + { + /* start at last point if it is on the curve */ + v_start = v_last; + limit--; + } + else + { + /* if both first and last points are conic, */ + /* start at their middle and record its position */ + /* for closure */ + v_start.x = ( v_start.x + v_last.x ) / 2; + v_start.y = ( v_start.y + v_last.y ) / 2; + + v_last = v_start; + } + point--; + tags--; + } + + FT_TRACE5(( " move to (%.2f, %.2f)\n", + v_start.x / 64.0, v_start.y / 64.0 )); + error = func_interface->move_to( &v_start, user ); + if ( error ) + goto Exit; + + while ( point < limit ) + { + point++; + tags++; + + tag = FT_CURVE_TAG( tags[0] ); + switch ( tag ) + { + case FT_CURVE_TAG_ON: /* emit a single line_to */ + { + FT_Vector vec; + + + vec.x = SCALED( point->x ); + vec.y = SCALED( point->y ); + + FT_TRACE5(( " line to (%.2f, %.2f)\n", + vec.x / 64.0, vec.y / 64.0 )); + error = func_interface->line_to( &vec, user ); + if ( error ) + goto Exit; + continue; + } + + case FT_CURVE_TAG_CONIC: /* consume conic arcs */ + v_control.x = SCALED( point->x ); + v_control.y = SCALED( point->y ); + + Do_Conic: + if ( point < limit ) + { + FT_Vector vec; + FT_Vector v_middle; + + + point++; + tags++; + tag = FT_CURVE_TAG( tags[0] ); + + vec.x = SCALED( point->x ); + vec.y = SCALED( point->y ); + + if ( tag == FT_CURVE_TAG_ON ) + { + FT_TRACE5(( " conic to (%.2f, %.2f)" + " with control (%.2f, %.2f)\n", + vec.x / 64.0, vec.y / 64.0, + v_control.x / 64.0, v_control.y / 64.0 )); + error = func_interface->conic_to( &v_control, &vec, user ); + if ( error ) + goto Exit; + continue; + } + + if ( tag != FT_CURVE_TAG_CONIC ) + goto Invalid_Outline; + + v_middle.x = ( v_control.x + vec.x ) / 2; + v_middle.y = ( v_control.y + vec.y ) / 2; + + FT_TRACE5(( " conic to (%.2f, %.2f)" + " with control (%.2f, %.2f)\n", + v_middle.x / 64.0, v_middle.y / 64.0, + v_control.x / 64.0, v_control.y / 64.0 )); + error = func_interface->conic_to( &v_control, &v_middle, user ); + if ( error ) + goto Exit; + + v_control = vec; + goto Do_Conic; + } + + FT_TRACE5(( " conic to (%.2f, %.2f)" + " with control (%.2f, %.2f)\n", + v_start.x / 64.0, v_start.y / 64.0, + v_control.x / 64.0, v_control.y / 64.0 )); + error = func_interface->conic_to( &v_control, &v_start, user ); + goto Close; + + default: /* FT_CURVE_TAG_CUBIC */ + { + FT_Vector vec1, vec2; + + + if ( point + 1 > limit || + FT_CURVE_TAG( tags[1] ) != FT_CURVE_TAG_CUBIC ) + goto Invalid_Outline; + + point += 2; + tags += 2; + + vec1.x = SCALED( point[-2].x ); + vec1.y = SCALED( point[-2].y ); + + vec2.x = SCALED( point[-1].x ); + vec2.y = SCALED( point[-1].y ); + + if ( point <= limit ) + { + FT_Vector vec; + + + vec.x = SCALED( point->x ); + vec.y = SCALED( point->y ); + + FT_TRACE5(( " cubic to (%.2f, %.2f)" + " with controls (%.2f, %.2f) and (%.2f, %.2f)\n", + vec.x / 64.0, vec.y / 64.0, + vec1.x / 64.0, vec1.y / 64.0, + vec2.x / 64.0, vec2.y / 64.0 )); + error = func_interface->cubic_to( &vec1, &vec2, &vec, user ); + if ( error ) + goto Exit; + continue; + } + + FT_TRACE5(( " cubic to (%.2f, %.2f)" + " with controls (%.2f, %.2f) and (%.2f, %.2f)\n", + v_start.x / 64.0, v_start.y / 64.0, + vec1.x / 64.0, vec1.y / 64.0, + vec2.x / 64.0, vec2.y / 64.0 )); + error = func_interface->cubic_to( &vec1, &vec2, &v_start, user ); + goto Close; + } + } + } + + /* close the contour with a line segment */ + FT_TRACE5(( " line to (%.2f, %.2f)\n", + v_start.x / 64.0, v_start.y / 64.0 )); + error = func_interface->line_to( &v_start, user ); + + Close: + if ( error ) + goto Exit; + + first = last + 1; + } + + FT_TRACE5(( "FT_Outline_Decompose: Done\n", n )); + return FT_Err_Ok; + + Exit: + FT_TRACE5(( "FT_Outline_Decompose: Error %d\n", error )); + return error; + + Invalid_Outline: + return FT_Err_Invalid_Outline; + } + + + FT_EXPORT_DEF( FT_Error ) + FT_Outline_New_Internal( FT_Memory memory, + FT_UInt numPoints, + FT_Int numContours, + FT_Outline *anoutline ) + { + FT_Error error; + + + if ( !anoutline || !memory ) + return FT_Err_Invalid_Argument; + + *anoutline = null_outline; + + if ( FT_NEW_ARRAY( anoutline->points, numPoints * 2L ) || + FT_NEW_ARRAY( anoutline->tags, numPoints ) || + FT_NEW_ARRAY( anoutline->contours, numContours ) ) + goto Fail; + + anoutline->n_points = (FT_UShort)numPoints; + anoutline->n_contours = (FT_Short)numContours; + anoutline->flags |= FT_OUTLINE_OWNER; + + return FT_Err_Ok; + + Fail: + anoutline->flags |= FT_OUTLINE_OWNER; + FT_Outline_Done_Internal( memory, anoutline ); + + return error; + } + + + /* documentation is in ftoutln.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Outline_New( FT_Library library, + FT_UInt numPoints, + FT_Int numContours, + FT_Outline *anoutline ) + { + if ( !library ) + return FT_Err_Invalid_Library_Handle; + + return FT_Outline_New_Internal( library->memory, numPoints, + numContours, anoutline ); + } + + + /* documentation is in ftoutln.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Outline_Check( FT_Outline* outline ) + { + if ( outline ) + { + FT_Int n_points = outline->n_points; + FT_Int n_contours = outline->n_contours; + FT_Int end0, end; + FT_Int n; + + + /* empty glyph? */ + if ( n_points == 0 && n_contours == 0 ) + return 0; + + /* check point and contour counts */ + if ( n_points <= 0 || n_contours <= 0 ) + goto Bad; + + end0 = end = -1; + for ( n = 0; n < n_contours; n++ ) + { + end = outline->contours[n]; + + /* note that we don't accept empty contours */ + if ( end <= end0 || end >= n_points ) + goto Bad; + + end0 = end; + } + + if ( end != n_points - 1 ) + goto Bad; + + /* XXX: check the tags array */ + return 0; + } + + Bad: + return FT_Err_Invalid_Argument; + } + + + /* documentation is in ftoutln.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Outline_Copy( const FT_Outline* source, + FT_Outline *target ) + { + FT_Int is_owner; + + + if ( !source || !target || + source->n_points != target->n_points || + source->n_contours != target->n_contours ) + return FT_Err_Invalid_Argument; + + if ( source == target ) + return FT_Err_Ok; + + FT_ARRAY_COPY( target->points, source->points, source->n_points ); + + FT_ARRAY_COPY( target->tags, source->tags, source->n_points ); + + FT_ARRAY_COPY( target->contours, source->contours, source->n_contours ); + + /* copy all flags, except the `FT_OUTLINE_OWNER' one */ + is_owner = target->flags & FT_OUTLINE_OWNER; + target->flags = source->flags; + + target->flags &= ~FT_OUTLINE_OWNER; + target->flags |= is_owner; + + return FT_Err_Ok; + } + + + FT_EXPORT_DEF( FT_Error ) + FT_Outline_Done_Internal( FT_Memory memory, + FT_Outline* outline ) + { + if ( memory && outline ) + { + if ( outline->flags & FT_OUTLINE_OWNER ) + { + FT_FREE( outline->points ); + FT_FREE( outline->tags ); + FT_FREE( outline->contours ); + } + *outline = null_outline; + + return FT_Err_Ok; + } + else + return FT_Err_Invalid_Argument; + } + + + /* documentation is in ftoutln.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Outline_Done( FT_Library library, + FT_Outline* outline ) + { + /* check for valid `outline' in FT_Outline_Done_Internal() */ + + if ( !library ) + return FT_Err_Invalid_Library_Handle; + + return FT_Outline_Done_Internal( library->memory, outline ); + } + + + /* documentation is in ftoutln.h */ + + FT_EXPORT_DEF( void ) + FT_Outline_Get_CBox( const FT_Outline* outline, + FT_BBox *acbox ) + { + FT_Pos xMin, yMin, xMax, yMax; + + + if ( outline && acbox ) + { + if ( outline->n_points == 0 ) + { + xMin = 0; + yMin = 0; + xMax = 0; + yMax = 0; + } + else + { + FT_Vector* vec = outline->points; + FT_Vector* limit = vec + outline->n_points; + + + xMin = xMax = vec->x; + yMin = yMax = vec->y; + vec++; + + for ( ; vec < limit; vec++ ) + { + FT_Pos x, y; + + + x = vec->x; + if ( x < xMin ) xMin = x; + if ( x > xMax ) xMax = x; + + y = vec->y; + if ( y < yMin ) yMin = y; + if ( y > yMax ) yMax = y; + } + } + acbox->xMin = xMin; + acbox->xMax = xMax; + acbox->yMin = yMin; + acbox->yMax = yMax; + } + } + + + /* documentation is in ftoutln.h */ + + FT_EXPORT_DEF( void ) + FT_Outline_Translate( const FT_Outline* outline, + FT_Pos xOffset, + FT_Pos yOffset ) + { + FT_UShort n; + FT_Vector* vec; + + + if ( !outline ) + return; + + vec = outline->points; + + for ( n = 0; n < outline->n_points; n++ ) + { + vec->x += xOffset; + vec->y += yOffset; + vec++; + } + } + + + /* documentation is in ftoutln.h */ + + FT_EXPORT_DEF( void ) + FT_Outline_Reverse( FT_Outline* outline ) + { + FT_UShort n; + FT_Int first, last; + + + if ( !outline ) + return; + + first = 0; + + for ( n = 0; n < outline->n_contours; n++ ) + { + last = outline->contours[n]; + + /* reverse point table */ + { + FT_Vector* p = outline->points + first; + FT_Vector* q = outline->points + last; + FT_Vector swap; + + + while ( p < q ) + { + swap = *p; + *p = *q; + *q = swap; + p++; + q--; + } + } + + /* reverse tags table */ + { + char* p = outline->tags + first; + char* q = outline->tags + last; + char swap; + + + while ( p < q ) + { + swap = *p; + *p = *q; + *q = swap; + p++; + q--; + } + } + + first = last + 1; + } + + outline->flags ^= FT_OUTLINE_REVERSE_FILL; + } + + + /* documentation is in ftoutln.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Outline_Render( FT_Library library, + FT_Outline* outline, + FT_Raster_Params* params ) + { + FT_Error error; + FT_Bool update = FALSE; + FT_Renderer renderer; + FT_ListNode node; + + + if ( !library ) + return FT_Err_Invalid_Library_Handle; + + if ( !outline || !params ) + return FT_Err_Invalid_Argument; + + renderer = library->cur_renderer; + node = library->renderers.head; + + params->source = (void*)outline; + + error = FT_Err_Cannot_Render_Glyph; + while ( renderer ) + { + error = renderer->raster_render( renderer->raster, params ); + if ( !error || FT_ERROR_BASE( error ) != FT_Err_Cannot_Render_Glyph ) + break; + + /* FT_Err_Cannot_Render_Glyph is returned if the render mode */ + /* is unsupported by the current renderer for this glyph image */ + /* format */ + + /* now, look for another renderer that supports the same */ + /* format */ + renderer = FT_Lookup_Renderer( library, FT_GLYPH_FORMAT_OUTLINE, + &node ); + update = TRUE; + } + + /* if we changed the current renderer for the glyph image format */ + /* we need to select it as the next current one */ + if ( !error && update && renderer ) + FT_Set_Renderer( library, renderer, 0, 0 ); + + return error; + } + + + /* documentation is in ftoutln.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Outline_Get_Bitmap( FT_Library library, + FT_Outline* outline, + const FT_Bitmap *abitmap ) + { + FT_Raster_Params params; + + + if ( !abitmap ) + return FT_Err_Invalid_Argument; + + /* other checks are delayed to FT_Outline_Render() */ + + params.target = abitmap; + params.flags = 0; + + if ( abitmap->pixel_mode == FT_PIXEL_MODE_GRAY || + abitmap->pixel_mode == FT_PIXEL_MODE_LCD || + abitmap->pixel_mode == FT_PIXEL_MODE_LCD_V ) + params.flags |= FT_RASTER_FLAG_AA; + + return FT_Outline_Render( library, outline, ¶ms ); + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( void ) + FT_Vector_Transform( FT_Vector* vector, + const FT_Matrix* matrix ) + { + FT_Pos xz, yz; + + + if ( !vector || !matrix ) + return; + + xz = FT_MulFix( vector->x, matrix->xx ) + + FT_MulFix( vector->y, matrix->xy ); + + yz = FT_MulFix( vector->x, matrix->yx ) + + FT_MulFix( vector->y, matrix->yy ); + + vector->x = xz; + vector->y = yz; + } + + + /* documentation is in ftoutln.h */ + + FT_EXPORT_DEF( void ) + FT_Outline_Transform( const FT_Outline* outline, + const FT_Matrix* matrix ) + { + FT_Vector* vec; + FT_Vector* limit; + + + if ( !outline || !matrix ) + return; + + vec = outline->points; + limit = vec + outline->n_points; + + for ( ; vec < limit; vec++ ) + FT_Vector_Transform( vec, matrix ); + } + + +#if 0 + +#define FT_OUTLINE_GET_CONTOUR( outline, c, first, last ) \ + do { \ + (first) = ( c > 0 ) ? (outline)->points + \ + (outline)->contours[c - 1] + 1 \ + : (outline)->points; \ + (last) = (outline)->points + (outline)->contours[c]; \ + } while ( 0 ) + + + /* Is a point in some contour? */ + /* */ + /* We treat every point of the contour as if it */ + /* it were ON. That is, we allow false positives, */ + /* but disallow false negatives. (XXX really?) */ + static FT_Bool + ft_contour_has( FT_Outline* outline, + FT_Short c, + FT_Vector* point ) + { + FT_Vector* first; + FT_Vector* last; + FT_Vector* a; + FT_Vector* b; + FT_UInt n = 0; + + + FT_OUTLINE_GET_CONTOUR( outline, c, first, last ); + + for ( a = first; a <= last; a++ ) + { + FT_Pos x; + FT_Int intersect; + + + b = ( a == last ) ? first : a + 1; + + intersect = ( a->y - point->y ) ^ ( b->y - point->y ); + + /* a and b are on the same side */ + if ( intersect >= 0 ) + { + if ( intersect == 0 && a->y == point->y ) + { + if ( ( a->x <= point->x && b->x >= point->x ) || + ( a->x >= point->x && b->x <= point->x ) ) + return 1; + } + + continue; + } + + x = a->x + ( b->x - a->x ) * (point->y - a->y ) / ( b->y - a->y ); + + if ( x < point->x ) + n++; + else if ( x == point->x ) + return 1; + } + + return ( n % 2 ); + } + + + static FT_Bool + ft_contour_enclosed( FT_Outline* outline, + FT_UShort c ) + { + FT_Vector* first; + FT_Vector* last; + FT_Short i; + + + FT_OUTLINE_GET_CONTOUR( outline, c, first, last ); + + for ( i = 0; i < outline->n_contours; i++ ) + { + if ( i != c && ft_contour_has( outline, i, first ) ) + { + FT_Vector* pt; + + + for ( pt = first + 1; pt <= last; pt++ ) + if ( !ft_contour_has( outline, i, pt ) ) + return 0; + + return 1; + } + } + + return 0; + } + + + /* This version differs from the public one in that each */ + /* part (contour not enclosed in another contour) of the */ + /* outline is checked for orientation. This is */ + /* necessary for some buggy CJK fonts. */ + static FT_Orientation + ft_outline_get_orientation( FT_Outline* outline ) + { + FT_Short i; + FT_Vector* first; + FT_Vector* last; + FT_Orientation orient = FT_ORIENTATION_NONE; + + + first = outline->points; + for ( i = 0; i < outline->n_contours; i++, first = last + 1 ) + { + FT_Vector* point; + FT_Vector* xmin_point; + FT_Pos xmin; + + + last = outline->points + outline->contours[i]; + + /* skip degenerate contours */ + if ( last < first + 2 ) + continue; + + if ( ft_contour_enclosed( outline, i ) ) + continue; + + xmin = first->x; + xmin_point = first; + + for ( point = first + 1; point <= last; point++ ) + { + if ( point->x < xmin ) + { + xmin = point->x; + xmin_point = point; + } + } + + /* check the orientation of the contour */ + { + FT_Vector* prev; + FT_Vector* next; + FT_Orientation o; + + + prev = ( xmin_point == first ) ? last : xmin_point - 1; + next = ( xmin_point == last ) ? first : xmin_point + 1; + + if ( FT_Atan2( prev->x - xmin_point->x, prev->y - xmin_point->y ) > + FT_Atan2( next->x - xmin_point->x, next->y - xmin_point->y ) ) + o = FT_ORIENTATION_POSTSCRIPT; + else + o = FT_ORIENTATION_TRUETYPE; + + if ( orient == FT_ORIENTATION_NONE ) + orient = o; + else if ( orient != o ) + return FT_ORIENTATION_NONE; + } + } + + return orient; + } + +#endif /* 0 */ + + + /* documentation is in ftoutln.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Outline_Embolden( FT_Outline* outline, + FT_Pos strength ) + { + FT_Vector* points; + FT_Vector v_prev, v_first, v_next, v_cur; + FT_Angle rotate, angle_in, angle_out; + FT_Int c, n, first; + FT_Int orientation; + + + if ( !outline ) + return FT_Err_Invalid_Argument; + + strength /= 2; + if ( strength == 0 ) + return FT_Err_Ok; + + orientation = FT_Outline_Get_Orientation( outline ); + if ( orientation == FT_ORIENTATION_NONE ) + { + if ( outline->n_contours ) + return FT_Err_Invalid_Argument; + else + return FT_Err_Ok; + } + + if ( orientation == FT_ORIENTATION_TRUETYPE ) + rotate = -FT_ANGLE_PI2; + else + rotate = FT_ANGLE_PI2; + + points = outline->points; + + first = 0; + for ( c = 0; c < outline->n_contours; c++ ) + { + int last = outline->contours[c]; + + + v_first = points[first]; + v_prev = points[last]; + v_cur = v_first; + + for ( n = first; n <= last; n++ ) + { + FT_Vector in, out; + FT_Angle angle_diff; + FT_Pos d; + FT_Fixed scale; + + + if ( n < last ) + v_next = points[n + 1]; + else + v_next = v_first; + + /* compute the in and out vectors */ + in.x = v_cur.x - v_prev.x; + in.y = v_cur.y - v_prev.y; + + out.x = v_next.x - v_cur.x; + out.y = v_next.y - v_cur.y; + + angle_in = FT_Atan2( in.x, in.y ); + angle_out = FT_Atan2( out.x, out.y ); + angle_diff = FT_Angle_Diff( angle_in, angle_out ); + scale = FT_Cos( angle_diff / 2 ); + + if ( scale < 0x4000L && scale > -0x4000L ) + in.x = in.y = 0; + else + { + d = FT_DivFix( strength, scale ); + + FT_Vector_From_Polar( &in, d, angle_in + angle_diff / 2 - rotate ); + } + + outline->points[n].x = v_cur.x + strength + in.x; + outline->points[n].y = v_cur.y + strength + in.y; + + v_prev = v_cur; + v_cur = v_next; + } + + first = last + 1; + } + + return FT_Err_Ok; + } + + + /* documentation is in ftoutln.h */ + + FT_EXPORT_DEF( FT_Orientation ) + FT_Outline_Get_Orientation( FT_Outline* outline ) + { + FT_Pos xmin = 32768L; + FT_Pos xmin_ymin = 32768L; + FT_Pos xmin_ymax = -32768L; + FT_Vector* xmin_first = NULL; + FT_Vector* xmin_last = NULL; + + short* contour; + + FT_Vector* first; + FT_Vector* last; + FT_Vector* prev; + FT_Vector* point; + + int i; + FT_Pos ray_y[3]; + FT_Orientation result[3]; + + + if ( !outline || outline->n_points <= 0 ) + return FT_ORIENTATION_TRUETYPE; + + /* We use the nonzero winding rule to find the orientation. */ + /* Since glyph outlines behave much more `regular' than arbitrary */ + /* cubic or quadratic curves, this test deals with the polygon */ + /* only which is spanned up by the control points. */ + + first = outline->points; + for ( contour = outline->contours; + contour < outline->contours + outline->n_contours; + contour++, first = last + 1 ) + { + FT_Pos contour_xmin = 32768L; + FT_Pos contour_xmax = -32768L; + FT_Pos contour_ymin = 32768L; + FT_Pos contour_ymax = -32768L; + + + last = outline->points + *contour; + + /* skip degenerate contours */ + if ( last < first + 2 ) + continue; + + for ( point = first; point <= last; ++point ) + { + if ( point->x < contour_xmin ) + contour_xmin = point->x; + + if ( point->x > contour_xmax ) + contour_xmax = point->x; + + if ( point->y < contour_ymin ) + contour_ymin = point->y; + + if ( point->y > contour_ymax ) + contour_ymax = point->y; + } + + if ( contour_xmin < xmin && + contour_xmin != contour_xmax && + contour_ymin != contour_ymax ) + { + xmin = contour_xmin; + xmin_ymin = contour_ymin; + xmin_ymax = contour_ymax; + xmin_first = first; + xmin_last = last; + } + } + + if ( xmin == 32768L ) + return FT_ORIENTATION_TRUETYPE; + + ray_y[0] = ( xmin_ymin * 3 + xmin_ymax ) >> 2; + ray_y[1] = ( xmin_ymin + xmin_ymax ) >> 1; + ray_y[2] = ( xmin_ymin + xmin_ymax * 3 ) >> 2; + + for ( i = 0; i < 3; i++ ) + { + FT_Pos left_x; + FT_Pos right_x; + FT_Vector* left1; + FT_Vector* left2; + FT_Vector* right1; + FT_Vector* right2; + + + RedoRay: + left_x = 32768L; + right_x = -32768L; + + left1 = left2 = right1 = right2 = NULL; + + prev = xmin_last; + for ( point = xmin_first; point <= xmin_last; prev = point, ++point ) + { + FT_Pos tmp_x; + + + if ( point->y == ray_y[i] || prev->y == ray_y[i] ) + { + ray_y[i]++; + goto RedoRay; + } + + if ( ( point->y < ray_y[i] && prev->y < ray_y[i] ) || + ( point->y > ray_y[i] && prev->y > ray_y[i] ) ) + continue; + + tmp_x = FT_MulDiv( point->x - prev->x, + ray_y[i] - prev->y, + point->y - prev->y ) + prev->x; + + if ( tmp_x < left_x ) + { + left_x = tmp_x; + left1 = prev; + left2 = point; + } + + if ( tmp_x > right_x ) + { + right_x = tmp_x; + right1 = prev; + right2 = point; + } + } + + if ( left1 && right1 ) + { + if ( left1->y < left2->y && right1->y > right2->y ) + result[i] = FT_ORIENTATION_TRUETYPE; + else if ( left1->y > left2->y && right1->y < right2->y ) + result[i] = FT_ORIENTATION_POSTSCRIPT; + else + result[i] = FT_ORIENTATION_NONE; + } + } + + if ( result[0] != FT_ORIENTATION_NONE && + ( result[0] == result[1] || result[0] == result[2] ) ) + return result[0]; + + if ( result[1] != FT_ORIENTATION_NONE && result[1] == result[2] ) + return result[1]; + + return FT_ORIENTATION_TRUETYPE; + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/base/ftpatent.c b/mod/pub.mod/freetype.mod/src/base/ftpatent.c new file mode 100644 index 0000000..236d9a6 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/base/ftpatent.c @@ -0,0 +1,285 @@ +/***************************************************************************/ +/* */ +/* ftpatent.c */ +/* */ +/* FreeType API for checking patented TrueType bytecode instructions */ +/* (body). */ +/* */ +/* Copyright 2007, 2008 by David Turner. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_TRUETYPE_TAGS_H +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_STREAM_H +#include FT_SERVICE_SFNT_H +#include FT_SERVICE_TRUETYPE_GLYF_H + + + static FT_Bool + _tt_check_patents_in_range( FT_Stream stream, + FT_ULong size ) + { + FT_Bool result = FALSE; + FT_Error error; + FT_Bytes p, end; + + + if ( FT_FRAME_ENTER( size ) ) + return 0; + + p = stream->cursor; + end = p + size; + + while ( p < end ) + { + switch (p[0]) + { + case 0x06: /* SPvTL // */ + case 0x07: /* SPvTL + */ + case 0x08: /* SFvTL // */ + case 0x09: /* SFvTL + */ + case 0x0A: /* SPvFS */ + case 0x0B: /* SFvFS */ + result = TRUE; + goto Exit; + + case 0x40: + if ( p + 1 >= end ) + goto Exit; + + p += p[1] + 2; + break; + + case 0x41: + if ( p + 1 >= end ) + goto Exit; + + p += p[1] * 2 + 2; + break; + + case 0x71: /* DELTAP2 */ + case 0x72: /* DELTAP3 */ + case 0x73: /* DELTAC0 */ + case 0x74: /* DELTAC1 */ + case 0x75: /* DELTAC2 */ + result = TRUE; + goto Exit; + + case 0xB0: + case 0xB1: + case 0xB2: + case 0xB3: + case 0xB4: + case 0xB5: + case 0xB6: + case 0xB7: + p += ( p[0] - 0xB0 ) + 2; + break; + + case 0xB8: + case 0xB9: + case 0xBA: + case 0xBB: + case 0xBC: + case 0xBD: + case 0xBE: + case 0xBF: + p += ( p[0] - 0xB8 ) * 2 + 3; + break; + + default: + p += 1; + break; + } + } + + Exit: + FT_UNUSED( error ); + FT_FRAME_EXIT(); + return result; + } + + + static FT_Bool + _tt_check_patents_in_table( FT_Face face, + FT_ULong tag ) + { + FT_Stream stream = face->stream; + FT_Error error = FT_Err_Ok; + FT_Service_SFNT_Table service; + FT_Bool result = FALSE; + + + FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE ); + + if ( service ) + { + FT_UInt i = 0; + FT_ULong tag_i = 0, offset_i, length_i; + + for ( i = 0; !error && tag_i != tag ; i++ ) + error = service->table_info( face, i, + &tag_i, &offset_i, &length_i ); + + if ( error || + FT_STREAM_SEEK( offset_i ) ) + goto Exit; + + result = _tt_check_patents_in_range( stream, length_i ); + } + + Exit: + return result; + } + + + static FT_Bool + _tt_face_check_patents( FT_Face face ) + { + FT_Stream stream = face->stream; + FT_UInt gindex; + FT_Error error; + FT_Bool result; + + FT_Service_TTGlyf service; + + + result = _tt_check_patents_in_table( face, TTAG_fpgm ); + if ( result ) + goto Exit; + + result = _tt_check_patents_in_table( face, TTAG_prep ); + if ( result ) + goto Exit; + + FT_FACE_FIND_SERVICE( face, service, TT_GLYF ); + if ( service == NULL ) + goto Exit; + + for ( gindex = 0; gindex < (FT_UInt)face->num_glyphs; gindex++ ) + { + FT_ULong offset, num_ins, size; + FT_Int num_contours; + + + offset = service->get_location( face, gindex, &size ); + if ( size == 0 ) + continue; + + if ( FT_STREAM_SEEK( offset ) || + FT_READ_SHORT( num_contours ) ) + continue; + + if ( num_contours >= 0 ) /* simple glyph */ + { + if ( FT_STREAM_SKIP( 8 + num_contours * 2 ) ) + continue; + } + else /* compound glyph */ + { + FT_Bool has_instr = 0; + + + if ( FT_STREAM_SKIP( 8 ) ) + continue; + + /* now read each component */ + for (;;) + { + FT_UInt flags, toskip; + + + if( FT_READ_USHORT( flags ) ) + break; + + toskip = 2 + 1 + 1; + + if ( ( flags & ( 1 << 0 ) ) != 0 ) /* ARGS_ARE_WORDS */ + toskip += 2; + + if ( ( flags & ( 1 << 3 ) ) != 0 ) /* WE_HAVE_A_SCALE */ + toskip += 2; + else if ( ( flags & ( 1 << 6 ) ) != 0 ) /* WE_HAVE_X_Y_SCALE */ + toskip += 4; + else if ( ( flags & ( 1 << 7 ) ) != 0 ) /* WE_HAVE_A_2x2 */ + toskip += 8; + + if ( ( flags & ( 1 << 8 ) ) != 0 ) /* WE_HAVE_INSTRUCTIONS */ + has_instr = 1; + + if ( FT_STREAM_SKIP( toskip ) ) + goto NextGlyph; + + if ( ( flags & ( 1 << 5 ) ) == 0 ) /* MORE_COMPONENTS */ + break; + } + + if ( !has_instr ) + goto NextGlyph; + } + + if ( FT_READ_USHORT( num_ins ) ) + continue; + + result = _tt_check_patents_in_range( stream, num_ins ); + if ( result ) + goto Exit; + + NextGlyph: + ; + } + + Exit: + return result; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Bool ) + FT_Face_CheckTrueTypePatents( FT_Face face ) + { + FT_Bool result = FALSE; + + + if ( face && FT_IS_SFNT( face ) ) + result = _tt_face_check_patents( face ); + + return result; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Bool ) + FT_Face_SetUnpatentedHinting( FT_Face face, + FT_Bool value ) + { + FT_Bool result = FALSE; + + +#if defined( TT_CONFIG_OPTION_UNPATENTED_HINTING ) && \ + !defined( TT_CONFIG_OPTION_BYTECODE_INTEPRETER ) + if ( face && FT_IS_SFNT( face ) ) + { + result = !face->internal->ignore_unpatented_hinter; + face->internal->ignore_unpatented_hinter = !value; + } +#else + FT_UNUSED( face ); + FT_UNUSED( value ); +#endif + + return result; + } + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/base/ftpfr.c b/mod/pub.mod/freetype.mod/src/base/ftpfr.c new file mode 100644 index 0000000..f9592bb --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/base/ftpfr.c @@ -0,0 +1,143 @@ +/***************************************************************************/ +/* */ +/* ftpfr.c */ +/* */ +/* FreeType API for accessing PFR-specific data (body). */ +/* */ +/* Copyright 2002, 2003, 2004, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H +#include FT_SERVICE_PFR_H + + + /* check the format */ + static FT_Service_PfrMetrics + ft_pfr_check( FT_Face face ) + { + FT_Service_PfrMetrics service; + + + FT_FACE_LOOKUP_SERVICE( face, service, PFR_METRICS ); + + return service; + } + + + /* documentation is in ftpfr.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_PFR_Metrics( FT_Face face, + FT_UInt *aoutline_resolution, + FT_UInt *ametrics_resolution, + FT_Fixed *ametrics_x_scale, + FT_Fixed *ametrics_y_scale ) + { + FT_Error error = FT_Err_Ok; + FT_Service_PfrMetrics service; + + + if ( !face ) + return FT_Err_Invalid_Argument; + + service = ft_pfr_check( face ); + if ( service ) + { + error = service->get_metrics( face, + aoutline_resolution, + ametrics_resolution, + ametrics_x_scale, + ametrics_y_scale ); + } + else + { + FT_Fixed x_scale, y_scale; + + + /* this is not a PFR font */ + if ( aoutline_resolution ) + *aoutline_resolution = face->units_per_EM; + + if ( ametrics_resolution ) + *ametrics_resolution = face->units_per_EM; + + x_scale = y_scale = 0x10000L; + if ( face->size ) + { + x_scale = face->size->metrics.x_scale; + y_scale = face->size->metrics.y_scale; + } + + if ( ametrics_x_scale ) + *ametrics_x_scale = x_scale; + + if ( ametrics_y_scale ) + *ametrics_y_scale = y_scale; + + error = FT_Err_Unknown_File_Format; + } + + return error; + } + + + /* documentation is in ftpfr.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_PFR_Kerning( FT_Face face, + FT_UInt left, + FT_UInt right, + FT_Vector *avector ) + { + FT_Error error; + FT_Service_PfrMetrics service; + + + if ( !face ) + return FT_Err_Invalid_Argument; + + service = ft_pfr_check( face ); + if ( service ) + error = service->get_kerning( face, left, right, avector ); + else + error = FT_Get_Kerning( face, left, right, + FT_KERNING_UNSCALED, avector ); + + return error; + } + + + /* documentation is in ftpfr.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_PFR_Advance( FT_Face face, + FT_UInt gindex, + FT_Pos *aadvance ) + { + FT_Error error; + FT_Service_PfrMetrics service; + + + service = ft_pfr_check( face ); + if ( service ) + { + error = service->get_advance( face, gindex, aadvance ); + } + else + /* XXX: TODO: PROVIDE ADVANCE-LOADING METHOD TO ALL FONT DRIVERS */ + error = FT_Err_Invalid_Argument; + + return error; + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/base/ftpic.c b/mod/pub.mod/freetype.mod/src/base/ftpic.c new file mode 100644 index 0000000..d5271a9 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/base/ftpic.c @@ -0,0 +1,54 @@ +/***************************************************************************/ +/* */ +/* ftpic.c */ +/* */ +/* The FreeType position independent code services (body). */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include "basepic.h" + +#ifdef FT_CONFIG_OPTION_PIC + + /* documentation is in ftpic.h */ + + FT_BASE_DEF( FT_Error ) + ft_pic_container_init( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Error error = FT_Err_Ok; + + FT_MEM_SET( pic_container, 0, sizeof(*pic_container) ); + + error = ft_base_pic_init( library ); + if(error) + return error; + + return FT_Err_Ok; + } + + + /* Destroy the contents of the container. */ + FT_BASE_DEF( void ) + ft_pic_container_destroy( FT_Library library ) + { + ft_base_pic_free( library ); + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/base/ftrfork.c b/mod/pub.mod/freetype.mod/src/base/ftrfork.c new file mode 100644 index 0000000..133c2de --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/base/ftrfork.c @@ -0,0 +1,821 @@ +/***************************************************************************/ +/* */ +/* ftrfork.c */ +/* */ +/* Embedded resource forks accessor (body). */ +/* */ +/* Copyright 2004, 2005, 2006, 2007, 2008, 2009 by */ +/* Masatake YAMATO and Redhat K.K. */ +/* */ +/* FT_Raccess_Get_HeaderInfo() and raccess_guess_darwin_hfsplus() are */ +/* derived from ftobjs.c. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + +/***************************************************************************/ +/* Development of the code in this file is support of */ +/* Information-technology Promotion Agency, Japan. */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_RFORK_H + + +#undef FT_COMPONENT +#define FT_COMPONENT trace_raccess + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** Resource fork directory access ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + FT_BASE_DEF( FT_Error ) + FT_Raccess_Get_HeaderInfo( FT_Library library, + FT_Stream stream, + FT_Long rfork_offset, + FT_Long *map_offset, + FT_Long *rdata_pos ) + { + FT_Error error; + unsigned char head[16], head2[16]; + FT_Long map_pos, rdata_len; + int allzeros, allmatch, i; + FT_Long type_list; + + FT_UNUSED( library ); + + + error = FT_Stream_Seek( stream, rfork_offset ); + if ( error ) + return error; + + error = FT_Stream_Read( stream, (FT_Byte *)head, 16 ); + if ( error ) + return error; + + *rdata_pos = rfork_offset + ( ( head[0] << 24 ) | + ( head[1] << 16 ) | + ( head[2] << 8 ) | + head[3] ); + map_pos = rfork_offset + ( ( head[4] << 24 ) | + ( head[5] << 16 ) | + ( head[6] << 8 ) | + head[7] ); + rdata_len = ( head[ 8] << 24 ) | + ( head[ 9] << 16 ) | + ( head[10] << 8 ) | + head[11]; + + /* map_len = head[12] .. head[15] */ + + if ( *rdata_pos + rdata_len != map_pos || map_pos == rfork_offset ) + return FT_Err_Unknown_File_Format; + + error = FT_Stream_Seek( stream, map_pos ); + if ( error ) + return error; + + head2[15] = (FT_Byte)( head[15] + 1 ); /* make it be different */ + + error = FT_Stream_Read( stream, (FT_Byte*)head2, 16 ); + if ( error ) + return error; + + allzeros = 1; + allmatch = 1; + for ( i = 0; i < 16; ++i ) + { + if ( head2[i] != 0 ) + allzeros = 0; + if ( head2[i] != head[i] ) + allmatch = 0; + } + if ( !allzeros && !allmatch ) + return FT_Err_Unknown_File_Format; + + /* If we have reached this point then it is probably a mac resource */ + /* file. Now, does it contain any interesting resources? */ + /* Skip handle to next resource map, the file resource number, and */ + /* attributes. */ + (void)FT_STREAM_SKIP( 4 /* skip handle to next resource map */ + + 2 /* skip file resource number */ + + 2 ); /* skip attributes */ + + if ( FT_READ_USHORT( type_list ) ) + return error; + if ( type_list == -1 ) + return FT_Err_Unknown_File_Format; + + error = FT_Stream_Seek( stream, map_pos + type_list ); + if ( error ) + return error; + + *map_offset = map_pos + type_list; + return FT_Err_Ok; + } + + + static int + ft_raccess_sort_ref_by_id( FT_RFork_Ref* a, + FT_RFork_Ref* b ) + { + if ( a->res_id < b->res_id ) + return -1; + else if ( a->res_id > b->res_id ) + return 1; + else + return 0; + } + + + FT_BASE_DEF( FT_Error ) + FT_Raccess_Get_DataOffsets( FT_Library library, + FT_Stream stream, + FT_Long map_offset, + FT_Long rdata_pos, + FT_Long tag, + FT_Long **offsets, + FT_Long *count ) + { + FT_Error error; + int i, j, cnt, subcnt; + FT_Long tag_internal, rpos; + FT_Memory memory = library->memory; + FT_Long temp; + FT_Long *offsets_internal; + FT_RFork_Ref *ref; + + + error = FT_Stream_Seek( stream, map_offset ); + if ( error ) + return error; + + if ( FT_READ_USHORT( cnt ) ) + return error; + cnt++; + + for ( i = 0; i < cnt; ++i ) + { + if ( FT_READ_LONG( tag_internal ) || + FT_READ_USHORT( subcnt ) || + FT_READ_USHORT( rpos ) ) + return error; + + FT_TRACE2(( "Resource tags: %c%c%c%c\n", + (char)( 0xff & ( tag_internal >> 24 ) ), + (char)( 0xff & ( tag_internal >> 16 ) ), + (char)( 0xff & ( tag_internal >> 8 ) ), + (char)( 0xff & ( tag_internal >> 0 ) ) )); + + if ( tag_internal == tag ) + { + *count = subcnt + 1; + rpos += map_offset; + + error = FT_Stream_Seek( stream, rpos ); + if ( error ) + return error; + + if ( FT_NEW_ARRAY( ref, *count ) ) + return error; + + for ( j = 0; j < *count; ++j ) + { + if ( FT_READ_USHORT( ref[j].res_id ) ) + goto Exit; + if ( FT_STREAM_SKIP( 2 ) ) /* resource name */ + goto Exit; + if ( FT_READ_LONG( temp ) ) + goto Exit; + if ( FT_STREAM_SKIP( 4 ) ) /* mbz */ + goto Exit; + + ref[j].offset = temp & 0xFFFFFFL; + } + + ft_qsort( ref, *count, sizeof ( FT_RFork_Ref ), + ( int(*)(const void*, const void*) ) + ft_raccess_sort_ref_by_id ); + + if ( FT_NEW_ARRAY( offsets_internal, *count ) ) + goto Exit; + + /* XXX: duplicated reference ID, + * gap between reference IDs are acceptable? + * further investigation on Apple implementation is needed. + */ + for ( j = 0; j < *count; ++j ) + offsets_internal[j] = rdata_pos + ref[j].offset; + + *offsets = offsets_internal; + error = FT_Err_Ok; + + Exit: + FT_FREE( ref ); + return error; + } + } + + return FT_Err_Cannot_Open_Resource; + } + + +#ifdef FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** Guessing functions ****/ + /**** ****/ + /**** When you add a new guessing function, ****/ + /**** update FT_RACCESS_N_RULES in ftrfork.h. ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + typedef FT_Error + (*raccess_guess_func)( FT_Library library, + FT_Stream stream, + char *base_file_name, + char **result_file_name, + FT_Long *result_offset ); + + + static FT_Error + raccess_guess_apple_double( FT_Library library, + FT_Stream stream, + char *base_file_name, + char **result_file_name, + FT_Long *result_offset ); + + static FT_Error + raccess_guess_apple_single( FT_Library library, + FT_Stream stream, + char *base_file_name, + char **result_file_name, + FT_Long *result_offset ); + + static FT_Error + raccess_guess_darwin_ufs_export( FT_Library library, + FT_Stream stream, + char *base_file_name, + char **result_file_name, + FT_Long *result_offset ); + + static FT_Error + raccess_guess_darwin_newvfs( FT_Library library, + FT_Stream stream, + char *base_file_name, + char **result_file_name, + FT_Long *result_offset ); + + static FT_Error + raccess_guess_darwin_hfsplus( FT_Library library, + FT_Stream stream, + char *base_file_name, + char **result_file_name, + FT_Long *result_offset ); + + static FT_Error + raccess_guess_vfat( FT_Library library, + FT_Stream stream, + char *base_file_name, + char **result_file_name, + FT_Long *result_offset ); + + static FT_Error + raccess_guess_linux_cap( FT_Library library, + FT_Stream stream, + char *base_file_name, + char **result_file_name, + FT_Long *result_offset ); + + static FT_Error + raccess_guess_linux_double( FT_Library library, + FT_Stream stream, + char *base_file_name, + char **result_file_name, + FT_Long *result_offset ); + + static FT_Error + raccess_guess_linux_netatalk( FT_Library library, + FT_Stream stream, + char *base_file_name, + char **result_file_name, + FT_Long *result_offset ); + + + /*************************************************************************/ + /**** ****/ + /**** Helper functions ****/ + /**** ****/ + /*************************************************************************/ + + static FT_Error + raccess_guess_apple_generic( FT_Library library, + FT_Stream stream, + char *base_file_name, + FT_Int32 magic, + FT_Long *result_offset ); + + static FT_Error + raccess_guess_linux_double_from_file_name( FT_Library library, + char * file_name, + FT_Long *result_offset ); + + static char * + raccess_make_file_name( FT_Memory memory, + const char *original_name, + const char *insertion ); + + + FT_BASE_DEF( void ) + FT_Raccess_Guess( FT_Library library, + FT_Stream stream, + char* base_name, + char **new_names, + FT_Long *offsets, + FT_Error *errors ) + { + FT_Long i; + + + raccess_guess_func funcs[FT_RACCESS_N_RULES] = + { + raccess_guess_apple_double, + raccess_guess_apple_single, + raccess_guess_darwin_ufs_export, + raccess_guess_darwin_newvfs, + raccess_guess_darwin_hfsplus, + raccess_guess_vfat, + raccess_guess_linux_cap, + raccess_guess_linux_double, + raccess_guess_linux_netatalk, + }; + + for ( i = 0; i < FT_RACCESS_N_RULES; i++ ) + { + new_names[i] = NULL; + if ( NULL != stream ) + errors[i] = FT_Stream_Seek( stream, 0 ); + else + errors[i] = FT_Err_Ok; + + if ( errors[i] ) + continue ; + + errors[i] = (funcs[i])( library, stream, base_name, + &(new_names[i]), &(offsets[i]) ); + } + + return; + } + + + static FT_Error + raccess_guess_apple_double( FT_Library library, + FT_Stream stream, + char *base_file_name, + char **result_file_name, + FT_Long *result_offset ) + { + FT_Int32 magic = ( 0x00 << 24 ) | + ( 0x05 << 16 ) | + ( 0x16 << 8 ) | + 0x07; + + + *result_file_name = NULL; + if ( NULL == stream ) + return FT_Err_Cannot_Open_Stream; + + return raccess_guess_apple_generic( library, stream, base_file_name, + magic, result_offset ); + } + + + static FT_Error + raccess_guess_apple_single( FT_Library library, + FT_Stream stream, + char *base_file_name, + char **result_file_name, + FT_Long *result_offset ) + { + FT_Int32 magic = ( 0x00 << 24 ) | + ( 0x05 << 16 ) | + ( 0x16 << 8 ) | + 0x00; + + + *result_file_name = NULL; + if ( NULL == stream ) + return FT_Err_Cannot_Open_Stream; + + return raccess_guess_apple_generic( library, stream, base_file_name, + magic, result_offset ); + } + + + static FT_Error + raccess_guess_darwin_ufs_export( FT_Library library, + FT_Stream stream, + char *base_file_name, + char **result_file_name, + FT_Long *result_offset ) + { + char* newpath; + FT_Error error; + FT_Memory memory; + + FT_UNUSED( stream ); + + + memory = library->memory; + newpath = raccess_make_file_name( memory, base_file_name, "._" ); + if ( !newpath ) + return FT_Err_Out_Of_Memory; + + error = raccess_guess_linux_double_from_file_name( library, newpath, + result_offset ); + if ( !error ) + *result_file_name = newpath; + else + FT_FREE( newpath ); + + return error; + } + + + static FT_Error + raccess_guess_darwin_hfsplus( FT_Library library, + FT_Stream stream, + char *base_file_name, + char **result_file_name, + FT_Long *result_offset ) + { + /* + Only meaningful on systems with hfs+ drivers (or Macs). + */ + FT_Error error; + char* newpath; + FT_Memory memory; + FT_Long base_file_len = ft_strlen( base_file_name ); + + FT_UNUSED( stream ); + + + memory = library->memory; + + if ( base_file_len + 6 > FT_INT_MAX ) + return FT_Err_Array_Too_Large; + + if ( FT_ALLOC( newpath, base_file_len + 6 ) ) + return error; + + FT_MEM_COPY( newpath, base_file_name, base_file_len ); + FT_MEM_COPY( newpath + base_file_len, "/rsrc", 6 ); + + *result_file_name = newpath; + *result_offset = 0; + + return FT_Err_Ok; + } + + + static FT_Error + raccess_guess_darwin_newvfs( FT_Library library, + FT_Stream stream, + char *base_file_name, + char **result_file_name, + FT_Long *result_offset ) + { + /* + Only meaningful on systems with Mac OS X (> 10.1). + */ + FT_Error error; + char* newpath; + FT_Memory memory; + FT_Long base_file_len = ft_strlen( base_file_name ); + + FT_UNUSED( stream ); + + + memory = library->memory; + + if ( base_file_len + 18 > FT_INT_MAX ) + return FT_Err_Array_Too_Large; + + if ( FT_ALLOC( newpath, base_file_len + 18 ) ) + return error; + + FT_MEM_COPY( newpath, base_file_name, base_file_len ); + FT_MEM_COPY( newpath + base_file_len, "/..namedfork/rsrc", 18 ); + + *result_file_name = newpath; + *result_offset = 0; + + return FT_Err_Ok; + } + + + static FT_Error + raccess_guess_vfat( FT_Library library, + FT_Stream stream, + char *base_file_name, + char **result_file_name, + FT_Long *result_offset ) + { + char* newpath; + FT_Memory memory; + + FT_UNUSED( stream ); + + + memory = library->memory; + + newpath = raccess_make_file_name( memory, base_file_name, + "resource.frk/" ); + if ( !newpath ) + return FT_Err_Out_Of_Memory; + + *result_file_name = newpath; + *result_offset = 0; + + return FT_Err_Ok; + } + + + static FT_Error + raccess_guess_linux_cap( FT_Library library, + FT_Stream stream, + char *base_file_name, + char **result_file_name, + FT_Long *result_offset ) + { + char* newpath; + FT_Memory memory; + + FT_UNUSED( stream ); + + + memory = library->memory; + + newpath = raccess_make_file_name( memory, base_file_name, ".resource/" ); + if ( !newpath ) + return FT_Err_Out_Of_Memory; + + *result_file_name = newpath; + *result_offset = 0; + + return FT_Err_Ok; + } + + + static FT_Error + raccess_guess_linux_double( FT_Library library, + FT_Stream stream, + char *base_file_name, + char **result_file_name, + FT_Long *result_offset ) + { + char* newpath; + FT_Error error; + FT_Memory memory; + + FT_UNUSED( stream ); + + + memory = library->memory; + + newpath = raccess_make_file_name( memory, base_file_name, "%" ); + if ( !newpath ) + return FT_Err_Out_Of_Memory; + + error = raccess_guess_linux_double_from_file_name( library, newpath, + result_offset ); + if ( !error ) + *result_file_name = newpath; + else + FT_FREE( newpath ); + + return error; + } + + + static FT_Error + raccess_guess_linux_netatalk( FT_Library library, + FT_Stream stream, + char *base_file_name, + char **result_file_name, + FT_Long *result_offset ) + { + char* newpath; + FT_Error error; + FT_Memory memory; + + FT_UNUSED( stream ); + + + memory = library->memory; + + newpath = raccess_make_file_name( memory, base_file_name, + ".AppleDouble/" ); + if ( !newpath ) + return FT_Err_Out_Of_Memory; + + error = raccess_guess_linux_double_from_file_name( library, newpath, + result_offset ); + if ( !error ) + *result_file_name = newpath; + else + FT_FREE( newpath ); + + return error; + } + + + static FT_Error + raccess_guess_apple_generic( FT_Library library, + FT_Stream stream, + char *base_file_name, + FT_Int32 magic, + FT_Long *result_offset ) + { + FT_Int32 magic_from_stream; + FT_Error error; + FT_Int32 version_number = 0; + FT_UShort n_of_entries; + + int i; + FT_UInt32 entry_id, entry_offset, entry_length = 0; + + const FT_UInt32 resource_fork_entry_id = 0x2; + + FT_UNUSED( library ); + FT_UNUSED( base_file_name ); + FT_UNUSED( version_number ); + FT_UNUSED( entry_length ); + + + if ( FT_READ_LONG( magic_from_stream ) ) + return error; + if ( magic_from_stream != magic ) + return FT_Err_Unknown_File_Format; + + if ( FT_READ_LONG( version_number ) ) + return error; + + /* filler */ + error = FT_Stream_Skip( stream, 16 ); + if ( error ) + return error; + + if ( FT_READ_USHORT( n_of_entries ) ) + return error; + if ( n_of_entries == 0 ) + return FT_Err_Unknown_File_Format; + + for ( i = 0; i < n_of_entries; i++ ) + { + if ( FT_READ_LONG( entry_id ) ) + return error; + if ( entry_id == resource_fork_entry_id ) + { + if ( FT_READ_LONG( entry_offset ) || + FT_READ_LONG( entry_length ) ) + continue; + *result_offset = entry_offset; + + return FT_Err_Ok; + } + else + { + error = FT_Stream_Skip( stream, 4 + 4 ); /* offset + length */ + if ( error ) + return error; + } + } + + return FT_Err_Unknown_File_Format; + } + + + static FT_Error + raccess_guess_linux_double_from_file_name( FT_Library library, + char *file_name, + FT_Long *result_offset ) + { + FT_Open_Args args2; + FT_Stream stream2; + char * nouse = NULL; + FT_Error error; + + + args2.flags = FT_OPEN_PATHNAME; + args2.pathname = file_name; + error = FT_Stream_New( library, &args2, &stream2 ); + if ( error ) + return error; + + error = raccess_guess_apple_double( library, stream2, file_name, + &nouse, result_offset ); + + FT_Stream_Free( stream2, 0 ); + + return error; + } + + + static char* + raccess_make_file_name( FT_Memory memory, + const char *original_name, + const char *insertion ) + { + char* new_name; + const char* tmp; + const char* slash; + size_t new_length; + FT_Error error = FT_Err_Ok; + + FT_UNUSED( error ); + + + new_length = ft_strlen( original_name ) + ft_strlen( insertion ); + if ( FT_ALLOC( new_name, new_length + 1 ) ) + return NULL; + + tmp = ft_strrchr( original_name, '/' ); + if ( tmp ) + { + ft_strncpy( new_name, original_name, tmp - original_name + 1 ); + new_name[tmp - original_name + 1] = '\0'; + slash = tmp + 1; + } + else + { + slash = original_name; + new_name[0] = '\0'; + } + + ft_strcat( new_name, insertion ); + ft_strcat( new_name, slash ); + + return new_name; + } + + +#else /* !FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK */ + + + /*************************************************************************/ + /* Dummy function; just sets errors */ + /*************************************************************************/ + + FT_BASE_DEF( void ) + FT_Raccess_Guess( FT_Library library, + FT_Stream stream, + char *base_name, + char **new_names, + FT_Long *offsets, + FT_Error *errors ) + { + int i; + + FT_UNUSED( library ); + FT_UNUSED( stream ); + FT_UNUSED( base_name ); + + + for ( i = 0; i < FT_RACCESS_N_RULES; i++ ) + { + new_names[i] = NULL; + offsets[i] = 0; + errors[i] = FT_Err_Unimplemented_Feature; + } + } + + +#endif /* !FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/base/ftsnames.c b/mod/pub.mod/freetype.mod/src/base/ftsnames.c new file mode 100644 index 0000000..3447888 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/base/ftsnames.c @@ -0,0 +1,94 @@ +/***************************************************************************/ +/* */ +/* ftsnames.c */ +/* */ +/* Simple interface to access SFNT name tables (which are used */ +/* to hold font names, copyright info, notices, etc.) (body). */ +/* */ +/* This is _not_ used to retrieve glyph names! */ +/* */ +/* Copyright 1996-2001, 2002, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_SFNT_NAMES_H +#include FT_INTERNAL_TRUETYPE_TYPES_H +#include FT_INTERNAL_STREAM_H + + +#ifdef TT_CONFIG_OPTION_SFNT_NAMES + + + /* documentation is in ftsnames.h */ + + FT_EXPORT_DEF( FT_UInt ) + FT_Get_Sfnt_Name_Count( FT_Face face ) + { + return ( face && FT_IS_SFNT( face ) ) ? ((TT_Face)face)->num_names : 0; + } + + + /* documentation is in ftsnames.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_Sfnt_Name( FT_Face face, + FT_UInt idx, + FT_SfntName *aname ) + { + FT_Error error = FT_Err_Invalid_Argument; + + + if ( aname && face && FT_IS_SFNT( face ) ) + { + TT_Face ttface = (TT_Face)face; + + + if ( idx < (FT_UInt)ttface->num_names ) + { + TT_NameEntryRec* entry = ttface->name_table.names + idx; + + + /* load name on demand */ + if ( entry->stringLength > 0 && entry->string == NULL ) + { + FT_Memory memory = face->memory; + FT_Stream stream = face->stream; + + + if ( FT_NEW_ARRAY ( entry->string, entry->stringLength ) || + FT_STREAM_SEEK( entry->stringOffset ) || + FT_STREAM_READ( entry->string, entry->stringLength ) ) + { + FT_FREE( entry->string ); + entry->stringLength = 0; + } + } + + aname->platform_id = entry->platformID; + aname->encoding_id = entry->encodingID; + aname->language_id = entry->languageID; + aname->name_id = entry->nameID; + aname->string = (FT_Byte*)entry->string; + aname->string_len = entry->stringLength; + + error = FT_Err_Ok; + } + } + + return error; + } + + +#endif /* TT_CONFIG_OPTION_SFNT_NAMES */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/base/ftstream.c b/mod/pub.mod/freetype.mod/src/base/ftstream.c new file mode 100644 index 0000000..b638599 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/base/ftstream.c @@ -0,0 +1,852 @@ +/***************************************************************************/ +/* */ +/* ftstream.c */ +/* */ +/* I/O stream support (body). */ +/* */ +/* Copyright 2000-2001, 2002, 2004, 2005, 2006, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_DEBUG_H + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_stream + + + FT_BASE_DEF( void ) + FT_Stream_OpenMemory( FT_Stream stream, + const FT_Byte* base, + FT_ULong size ) + { + stream->base = (FT_Byte*) base; + stream->size = size; + stream->pos = 0; + stream->cursor = 0; + stream->read = 0; + stream->close = 0; + } + + + FT_BASE_DEF( void ) + FT_Stream_Close( FT_Stream stream ) + { + if ( stream && stream->close ) + stream->close( stream ); + } + + + FT_BASE_DEF( FT_Error ) + FT_Stream_Seek( FT_Stream stream, + FT_ULong pos ) + { + FT_Error error = FT_Err_Ok; + + + if ( stream->read ) + { + if ( stream->read( stream, pos, 0, 0 ) ) + { + FT_ERROR(( "FT_Stream_Seek:" + " invalid i/o; pos = 0x%lx, size = 0x%lx\n", + pos, stream->size )); + + error = FT_Err_Invalid_Stream_Operation; + } + } + /* note that seeking to the first position after the file is valid */ + else if ( pos > stream->size ) + { + FT_ERROR(( "FT_Stream_Seek:" + " invalid i/o; pos = 0x%lx, size = 0x%lx\n", + pos, stream->size )); + + error = FT_Err_Invalid_Stream_Operation; + } + + if ( !error ) + stream->pos = pos; + + return error; + } + + + FT_BASE_DEF( FT_Error ) + FT_Stream_Skip( FT_Stream stream, + FT_Long distance ) + { + if ( distance < 0 ) + return FT_Err_Invalid_Stream_Operation; + + return FT_Stream_Seek( stream, (FT_ULong)( stream->pos + distance ) ); + } + + + FT_BASE_DEF( FT_Long ) + FT_Stream_Pos( FT_Stream stream ) + { + return stream->pos; + } + + + FT_BASE_DEF( FT_Error ) + FT_Stream_Read( FT_Stream stream, + FT_Byte* buffer, + FT_ULong count ) + { + return FT_Stream_ReadAt( stream, stream->pos, buffer, count ); + } + + + FT_BASE_DEF( FT_Error ) + FT_Stream_ReadAt( FT_Stream stream, + FT_ULong pos, + FT_Byte* buffer, + FT_ULong count ) + { + FT_Error error = FT_Err_Ok; + FT_ULong read_bytes; + + + if ( pos >= stream->size ) + { + FT_ERROR(( "FT_Stream_ReadAt:" + " invalid i/o; pos = 0x%lx, size = 0x%lx\n", + pos, stream->size )); + + return FT_Err_Invalid_Stream_Operation; + } + + if ( stream->read ) + read_bytes = stream->read( stream, pos, buffer, count ); + else + { + read_bytes = stream->size - pos; + if ( read_bytes > count ) + read_bytes = count; + + FT_MEM_COPY( buffer, stream->base + pos, read_bytes ); + } + + stream->pos = pos + read_bytes; + + if ( read_bytes < count ) + { + FT_ERROR(( "FT_Stream_ReadAt:" + " invalid read; expected %lu bytes, got %lu\n", + count, read_bytes )); + + error = FT_Err_Invalid_Stream_Operation; + } + + return error; + } + + + FT_BASE_DEF( FT_ULong ) + FT_Stream_TryRead( FT_Stream stream, + FT_Byte* buffer, + FT_ULong count ) + { + FT_ULong read_bytes = 0; + + + if ( stream->pos >= stream->size ) + goto Exit; + + if ( stream->read ) + read_bytes = stream->read( stream, stream->pos, buffer, count ); + else + { + read_bytes = stream->size - stream->pos; + if ( read_bytes > count ) + read_bytes = count; + + FT_MEM_COPY( buffer, stream->base + stream->pos, read_bytes ); + } + + stream->pos += read_bytes; + + Exit: + return read_bytes; + } + + + FT_BASE_DEF( FT_Error ) + FT_Stream_ExtractFrame( FT_Stream stream, + FT_ULong count, + FT_Byte** pbytes ) + { + FT_Error error; + + + error = FT_Stream_EnterFrame( stream, count ); + if ( !error ) + { + *pbytes = (FT_Byte*)stream->cursor; + + /* equivalent to FT_Stream_ExitFrame(), with no memory block release */ + stream->cursor = 0; + stream->limit = 0; + } + + return error; + } + + + FT_BASE_DEF( void ) + FT_Stream_ReleaseFrame( FT_Stream stream, + FT_Byte** pbytes ) + { + if ( stream && stream->read ) + { + FT_Memory memory = stream->memory; + +#ifdef FT_DEBUG_MEMORY + ft_mem_free( memory, *pbytes ); + *pbytes = NULL; +#else + FT_FREE( *pbytes ); +#endif + } + *pbytes = 0; + } + + + FT_BASE_DEF( FT_Error ) + FT_Stream_EnterFrame( FT_Stream stream, + FT_ULong count ) + { + FT_Error error = FT_Err_Ok; + FT_ULong read_bytes; + + + /* check for nested frame access */ + FT_ASSERT( stream && stream->cursor == 0 ); + + if ( stream->read ) + { + /* allocate the frame in memory */ + FT_Memory memory = stream->memory; + +#ifdef FT_DEBUG_MEMORY + /* assume _ft_debug_file and _ft_debug_lineno are already set */ + stream->base = (unsigned char*)ft_mem_qalloc( memory, count, &error ); + if ( error ) + goto Exit; +#else + if ( FT_QALLOC( stream->base, count ) ) + goto Exit; +#endif + /* read it */ + read_bytes = stream->read( stream, stream->pos, + stream->base, count ); + if ( read_bytes < count ) + { + FT_ERROR(( "FT_Stream_EnterFrame:" + " invalid read; expected %lu bytes, got %lu\n", + count, read_bytes )); + + FT_FREE( stream->base ); + error = FT_Err_Invalid_Stream_Operation; + } + stream->cursor = stream->base; + stream->limit = stream->cursor + count; + stream->pos += read_bytes; + } + else + { + /* check current and new position */ + if ( stream->pos >= stream->size || + stream->pos + count > stream->size ) + { + FT_ERROR(( "FT_Stream_EnterFrame:" + " invalid i/o; pos = 0x%lx, count = %lu, size = 0x%lx\n", + stream->pos, count, stream->size )); + + error = FT_Err_Invalid_Stream_Operation; + goto Exit; + } + + /* set cursor */ + stream->cursor = stream->base + stream->pos; + stream->limit = stream->cursor + count; + stream->pos += count; + } + + Exit: + return error; + } + + + FT_BASE_DEF( void ) + FT_Stream_ExitFrame( FT_Stream stream ) + { + /* IMPORTANT: The assertion stream->cursor != 0 was removed, given */ + /* that it is possible to access a frame of length 0 in */ + /* some weird fonts (usually, when accessing an array of */ + /* 0 records, like in some strange kern tables). */ + /* */ + /* In this case, the loader code handles the 0-length table */ + /* gracefully; however, stream.cursor is really set to 0 by the */ + /* FT_Stream_EnterFrame() call, and this is not an error. */ + /* */ + FT_ASSERT( stream ); + + if ( stream->read ) + { + FT_Memory memory = stream->memory; + +#ifdef FT_DEBUG_MEMORY + ft_mem_free( memory, stream->base ); + stream->base = NULL; +#else + FT_FREE( stream->base ); +#endif + } + stream->cursor = 0; + stream->limit = 0; + } + + + FT_BASE_DEF( FT_Char ) + FT_Stream_GetChar( FT_Stream stream ) + { + FT_Char result; + + + FT_ASSERT( stream && stream->cursor ); + + result = 0; + if ( stream->cursor < stream->limit ) + result = *stream->cursor++; + + return result; + } + + + FT_BASE_DEF( FT_Short ) + FT_Stream_GetShort( FT_Stream stream ) + { + FT_Byte* p; + FT_Short result; + + + FT_ASSERT( stream && stream->cursor ); + + result = 0; + p = stream->cursor; + if ( p + 1 < stream->limit ) + result = FT_NEXT_SHORT( p ); + stream->cursor = p; + + return result; + } + + + FT_BASE_DEF( FT_Short ) + FT_Stream_GetShortLE( FT_Stream stream ) + { + FT_Byte* p; + FT_Short result; + + + FT_ASSERT( stream && stream->cursor ); + + result = 0; + p = stream->cursor; + if ( p + 1 < stream->limit ) + result = FT_NEXT_SHORT_LE( p ); + stream->cursor = p; + + return result; + } + + + FT_BASE_DEF( FT_Long ) + FT_Stream_GetOffset( FT_Stream stream ) + { + FT_Byte* p; + FT_Long result; + + + FT_ASSERT( stream && stream->cursor ); + + result = 0; + p = stream->cursor; + if ( p + 2 < stream->limit ) + result = FT_NEXT_OFF3( p ); + stream->cursor = p; + return result; + } + + + FT_BASE_DEF( FT_Long ) + FT_Stream_GetLong( FT_Stream stream ) + { + FT_Byte* p; + FT_Long result; + + + FT_ASSERT( stream && stream->cursor ); + + result = 0; + p = stream->cursor; + if ( p + 3 < stream->limit ) + result = FT_NEXT_LONG( p ); + stream->cursor = p; + return result; + } + + + FT_BASE_DEF( FT_Long ) + FT_Stream_GetLongLE( FT_Stream stream ) + { + FT_Byte* p; + FT_Long result; + + + FT_ASSERT( stream && stream->cursor ); + + result = 0; + p = stream->cursor; + if ( p + 3 < stream->limit ) + result = FT_NEXT_LONG_LE( p ); + stream->cursor = p; + return result; + } + + + FT_BASE_DEF( FT_Char ) + FT_Stream_ReadChar( FT_Stream stream, + FT_Error* error ) + { + FT_Byte result = 0; + + + FT_ASSERT( stream ); + + *error = FT_Err_Ok; + + if ( stream->read ) + { + if ( stream->read( stream, stream->pos, &result, 1L ) != 1L ) + goto Fail; + } + else + { + if ( stream->pos < stream->size ) + result = stream->base[stream->pos]; + else + goto Fail; + } + stream->pos++; + + return result; + + Fail: + *error = FT_Err_Invalid_Stream_Operation; + FT_ERROR(( "FT_Stream_ReadChar:" + " invalid i/o; pos = 0x%lx, size = 0x%lx\n", + stream->pos, stream->size )); + + return 0; + } + + + FT_BASE_DEF( FT_Short ) + FT_Stream_ReadShort( FT_Stream stream, + FT_Error* error ) + { + FT_Byte reads[2]; + FT_Byte* p = 0; + FT_Short result = 0; + + + FT_ASSERT( stream ); + + *error = FT_Err_Ok; + + if ( stream->pos + 1 < stream->size ) + { + if ( stream->read ) + { + if ( stream->read( stream, stream->pos, reads, 2L ) != 2L ) + goto Fail; + + p = reads; + } + else + { + p = stream->base + stream->pos; + } + + if ( p ) + result = FT_NEXT_SHORT( p ); + } + else + goto Fail; + + stream->pos += 2; + + return result; + + Fail: + *error = FT_Err_Invalid_Stream_Operation; + FT_ERROR(( "FT_Stream_ReadShort:" + " invalid i/o; pos = 0x%lx, size = 0x%lx\n", + stream->pos, stream->size )); + + return 0; + } + + + FT_BASE_DEF( FT_Short ) + FT_Stream_ReadShortLE( FT_Stream stream, + FT_Error* error ) + { + FT_Byte reads[2]; + FT_Byte* p = 0; + FT_Short result = 0; + + + FT_ASSERT( stream ); + + *error = FT_Err_Ok; + + if ( stream->pos + 1 < stream->size ) + { + if ( stream->read ) + { + if ( stream->read( stream, stream->pos, reads, 2L ) != 2L ) + goto Fail; + + p = reads; + } + else + { + p = stream->base + stream->pos; + } + + if ( p ) + result = FT_NEXT_SHORT_LE( p ); + } + else + goto Fail; + + stream->pos += 2; + + return result; + + Fail: + *error = FT_Err_Invalid_Stream_Operation; + FT_ERROR(( "FT_Stream_ReadShortLE:" + " invalid i/o; pos = 0x%lx, size = 0x%lx\n", + stream->pos, stream->size )); + + return 0; + } + + + FT_BASE_DEF( FT_Long ) + FT_Stream_ReadOffset( FT_Stream stream, + FT_Error* error ) + { + FT_Byte reads[3]; + FT_Byte* p = 0; + FT_Long result = 0; + + + FT_ASSERT( stream ); + + *error = FT_Err_Ok; + + if ( stream->pos + 2 < stream->size ) + { + if ( stream->read ) + { + if (stream->read( stream, stream->pos, reads, 3L ) != 3L ) + goto Fail; + + p = reads; + } + else + { + p = stream->base + stream->pos; + } + + if ( p ) + result = FT_NEXT_OFF3( p ); + } + else + goto Fail; + + stream->pos += 3; + + return result; + + Fail: + *error = FT_Err_Invalid_Stream_Operation; + FT_ERROR(( "FT_Stream_ReadOffset:" + " invalid i/o; pos = 0x%lx, size = 0x%lx\n", + stream->pos, stream->size )); + + return 0; + } + + + FT_BASE_DEF( FT_Long ) + FT_Stream_ReadLong( FT_Stream stream, + FT_Error* error ) + { + FT_Byte reads[4]; + FT_Byte* p = 0; + FT_Long result = 0; + + + FT_ASSERT( stream ); + + *error = FT_Err_Ok; + + if ( stream->pos + 3 < stream->size ) + { + if ( stream->read ) + { + if ( stream->read( stream, stream->pos, reads, 4L ) != 4L ) + goto Fail; + + p = reads; + } + else + { + p = stream->base + stream->pos; + } + + if ( p ) + result = FT_NEXT_LONG( p ); + } + else + goto Fail; + + stream->pos += 4; + + return result; + + Fail: + *error = FT_Err_Invalid_Stream_Operation; + FT_ERROR(( "FT_Stream_ReadLong:" + " invalid i/o; pos = 0x%lx, size = 0x%lx\n", + stream->pos, stream->size )); + + return 0; + } + + + FT_BASE_DEF( FT_Long ) + FT_Stream_ReadLongLE( FT_Stream stream, + FT_Error* error ) + { + FT_Byte reads[4]; + FT_Byte* p = 0; + FT_Long result = 0; + + + FT_ASSERT( stream ); + + *error = FT_Err_Ok; + + if ( stream->pos + 3 < stream->size ) + { + if ( stream->read ) + { + if ( stream->read( stream, stream->pos, reads, 4L ) != 4L ) + goto Fail; + + p = reads; + } + else + { + p = stream->base + stream->pos; + } + + if ( p ) + result = FT_NEXT_LONG_LE( p ); + } + else + goto Fail; + + stream->pos += 4; + + return result; + + Fail: + *error = FT_Err_Invalid_Stream_Operation; + FT_ERROR(( "FT_Stream_ReadLongLE:" + " invalid i/o; pos = 0x%lx, size = 0x%lx\n", + stream->pos, stream->size )); + + return 0; + } + + + FT_BASE_DEF( FT_Error ) + FT_Stream_ReadFields( FT_Stream stream, + const FT_Frame_Field* fields, + void* structure ) + { + FT_Error error; + FT_Bool frame_accessed = 0; + FT_Byte* cursor; + + if ( !fields || !stream ) + return FT_Err_Invalid_Argument; + + cursor = stream->cursor; + + error = FT_Err_Ok; + do + { + FT_ULong value; + FT_Int sign_shift; + FT_Byte* p; + + + switch ( fields->value ) + { + case ft_frame_start: /* access a new frame */ + error = FT_Stream_EnterFrame( stream, fields->offset ); + if ( error ) + goto Exit; + + frame_accessed = 1; + cursor = stream->cursor; + fields++; + continue; /* loop! */ + + case ft_frame_bytes: /* read a byte sequence */ + case ft_frame_skip: /* skip some bytes */ + { + FT_UInt len = fields->size; + + + if ( cursor + len > stream->limit ) + { + error = FT_Err_Invalid_Stream_Operation; + goto Exit; + } + + if ( fields->value == ft_frame_bytes ) + { + p = (FT_Byte*)structure + fields->offset; + FT_MEM_COPY( p, cursor, len ); + } + cursor += len; + fields++; + continue; + } + + case ft_frame_byte: + case ft_frame_schar: /* read a single byte */ + value = FT_NEXT_BYTE(cursor); + sign_shift = 24; + break; + + case ft_frame_short_be: + case ft_frame_ushort_be: /* read a 2-byte big-endian short */ + value = FT_NEXT_USHORT(cursor); + sign_shift = 16; + break; + + case ft_frame_short_le: + case ft_frame_ushort_le: /* read a 2-byte little-endian short */ + value = FT_NEXT_USHORT_LE(cursor); + sign_shift = 16; + break; + + case ft_frame_long_be: + case ft_frame_ulong_be: /* read a 4-byte big-endian long */ + value = FT_NEXT_ULONG(cursor); + sign_shift = 0; + break; + + case ft_frame_long_le: + case ft_frame_ulong_le: /* read a 4-byte little-endian long */ + value = FT_NEXT_ULONG_LE(cursor); + sign_shift = 0; + break; + + case ft_frame_off3_be: + case ft_frame_uoff3_be: /* read a 3-byte big-endian long */ + value = FT_NEXT_UOFF3(cursor); + sign_shift = 8; + break; + + case ft_frame_off3_le: + case ft_frame_uoff3_le: /* read a 3-byte little-endian long */ + value = FT_NEXT_UOFF3_LE(cursor); + sign_shift = 8; + break; + + default: + /* otherwise, exit the loop */ + stream->cursor = cursor; + goto Exit; + } + + /* now, compute the signed value is necessary */ + if ( fields->value & FT_FRAME_OP_SIGNED ) + value = (FT_ULong)( (FT_Int32)( value << sign_shift ) >> sign_shift ); + + /* finally, store the value in the object */ + + p = (FT_Byte*)structure + fields->offset; + switch ( fields->size ) + { + case (8 / FT_CHAR_BIT): + *(FT_Byte*)p = (FT_Byte)value; + break; + + case (16 / FT_CHAR_BIT): + *(FT_UShort*)p = (FT_UShort)value; + break; + + case (32 / FT_CHAR_BIT): + *(FT_UInt32*)p = (FT_UInt32)value; + break; + + default: /* for 64-bit systems */ + *(FT_ULong*)p = (FT_ULong)value; + } + + /* go to next field */ + fields++; + } + while ( 1 ); + + Exit: + /* close the frame if it was opened by this read */ + if ( frame_accessed ) + FT_Stream_ExitFrame( stream ); + + return error; + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/base/ftstroke.c b/mod/pub.mod/freetype.mod/src/base/ftstroke.c new file mode 100644 index 0000000..0978b0e --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/base/ftstroke.c @@ -0,0 +1,2041 @@ +/***************************************************************************/ +/* */ +/* ftstroke.c */ +/* */ +/* FreeType path stroker (body). */ +/* */ +/* Copyright 2002, 2003, 2004, 2005, 2006, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_STROKER_H +#include FT_TRIGONOMETRY_H +#include FT_OUTLINE_H +#include FT_INTERNAL_MEMORY_H +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_OBJECTS_H + + + /* documentation is in ftstroke.h */ + + FT_EXPORT_DEF( FT_StrokerBorder ) + FT_Outline_GetInsideBorder( FT_Outline* outline ) + { + FT_Orientation o = FT_Outline_Get_Orientation( outline ); + + + return o == FT_ORIENTATION_TRUETYPE ? FT_STROKER_BORDER_RIGHT + : FT_STROKER_BORDER_LEFT ; + } + + + /* documentation is in ftstroke.h */ + + FT_EXPORT_DEF( FT_StrokerBorder ) + FT_Outline_GetOutsideBorder( FT_Outline* outline ) + { + FT_Orientation o = FT_Outline_Get_Orientation( outline ); + + + return o == FT_ORIENTATION_TRUETYPE ? FT_STROKER_BORDER_LEFT + : FT_STROKER_BORDER_RIGHT ; + } + + + /***************************************************************************/ + /***************************************************************************/ + /***** *****/ + /***** BEZIER COMPUTATIONS *****/ + /***** *****/ + /***************************************************************************/ + /***************************************************************************/ + +#define FT_SMALL_CONIC_THRESHOLD ( FT_ANGLE_PI / 6 ) +#define FT_SMALL_CUBIC_THRESHOLD ( FT_ANGLE_PI / 6 ) +#define FT_EPSILON 2 + +#define FT_IS_SMALL( x ) ( (x) > -FT_EPSILON && (x) < FT_EPSILON ) + + + static FT_Pos + ft_pos_abs( FT_Pos x ) + { + return x >= 0 ? x : -x ; + } + + + static void + ft_conic_split( FT_Vector* base ) + { + FT_Pos a, b; + + + base[4].x = base[2].x; + b = base[1].x; + a = base[3].x = ( base[2].x + b ) / 2; + b = base[1].x = ( base[0].x + b ) / 2; + base[2].x = ( a + b ) / 2; + + base[4].y = base[2].y; + b = base[1].y; + a = base[3].y = ( base[2].y + b ) / 2; + b = base[1].y = ( base[0].y + b ) / 2; + base[2].y = ( a + b ) / 2; + } + + + static FT_Bool + ft_conic_is_small_enough( FT_Vector* base, + FT_Angle *angle_in, + FT_Angle *angle_out ) + { + FT_Vector d1, d2; + FT_Angle theta; + FT_Int close1, close2; + + + d1.x = base[1].x - base[2].x; + d1.y = base[1].y - base[2].y; + d2.x = base[0].x - base[1].x; + d2.y = base[0].y - base[1].y; + + close1 = FT_IS_SMALL( d1.x ) && FT_IS_SMALL( d1.y ); + close2 = FT_IS_SMALL( d2.x ) && FT_IS_SMALL( d2.y ); + + if ( close1 ) + { + if ( close2 ) + *angle_in = *angle_out = 0; + else + *angle_in = *angle_out = FT_Atan2( d2.x, d2.y ); + } + else if ( close2 ) + { + *angle_in = *angle_out = FT_Atan2( d1.x, d1.y ); + } + else + { + *angle_in = FT_Atan2( d1.x, d1.y ); + *angle_out = FT_Atan2( d2.x, d2.y ); + } + + theta = ft_pos_abs( FT_Angle_Diff( *angle_in, *angle_out ) ); + + return FT_BOOL( theta < FT_SMALL_CONIC_THRESHOLD ); + } + + + static void + ft_cubic_split( FT_Vector* base ) + { + FT_Pos a, b, c, d; + + + base[6].x = base[3].x; + c = base[1].x; + d = base[2].x; + base[1].x = a = ( base[0].x + c ) / 2; + base[5].x = b = ( base[3].x + d ) / 2; + c = ( c + d ) / 2; + base[2].x = a = ( a + c ) / 2; + base[4].x = b = ( b + c ) / 2; + base[3].x = ( a + b ) / 2; + + base[6].y = base[3].y; + c = base[1].y; + d = base[2].y; + base[1].y = a = ( base[0].y + c ) / 2; + base[5].y = b = ( base[3].y + d ) / 2; + c = ( c + d ) / 2; + base[2].y = a = ( a + c ) / 2; + base[4].y = b = ( b + c ) / 2; + base[3].y = ( a + b ) / 2; + } + + + static FT_Bool + ft_cubic_is_small_enough( FT_Vector* base, + FT_Angle *angle_in, + FT_Angle *angle_mid, + FT_Angle *angle_out ) + { + FT_Vector d1, d2, d3; + FT_Angle theta1, theta2; + FT_Int close1, close2, close3; + + + d1.x = base[2].x - base[3].x; + d1.y = base[2].y - base[3].y; + d2.x = base[1].x - base[2].x; + d2.y = base[1].y - base[2].y; + d3.x = base[0].x - base[1].x; + d3.y = base[0].y - base[1].y; + + close1 = FT_IS_SMALL( d1.x ) && FT_IS_SMALL( d1.y ); + close2 = FT_IS_SMALL( d2.x ) && FT_IS_SMALL( d2.y ); + close3 = FT_IS_SMALL( d3.x ) && FT_IS_SMALL( d3.y ); + + if ( close1 || close3 ) + { + if ( close2 ) + { + /* basically a point */ + *angle_in = *angle_out = *angle_mid = 0; + } + else if ( close1 ) + { + *angle_in = *angle_mid = FT_Atan2( d2.x, d2.y ); + *angle_out = FT_Atan2( d3.x, d3.y ); + } + else /* close2 */ + { + *angle_in = FT_Atan2( d1.x, d1.y ); + *angle_mid = *angle_out = FT_Atan2( d2.x, d2.y ); + } + } + else if ( close2 ) + { + *angle_in = *angle_mid = FT_Atan2( d1.x, d1.y ); + *angle_out = FT_Atan2( d3.x, d3.y ); + } + else + { + *angle_in = FT_Atan2( d1.x, d1.y ); + *angle_mid = FT_Atan2( d2.x, d2.y ); + *angle_out = FT_Atan2( d3.x, d3.y ); + } + + theta1 = ft_pos_abs( FT_Angle_Diff( *angle_in, *angle_mid ) ); + theta2 = ft_pos_abs( FT_Angle_Diff( *angle_mid, *angle_out ) ); + + return FT_BOOL( theta1 < FT_SMALL_CUBIC_THRESHOLD && + theta2 < FT_SMALL_CUBIC_THRESHOLD ); + } + + + /***************************************************************************/ + /***************************************************************************/ + /***** *****/ + /***** STROKE BORDERS *****/ + /***** *****/ + /***************************************************************************/ + /***************************************************************************/ + + typedef enum FT_StrokeTags_ + { + FT_STROKE_TAG_ON = 1, /* on-curve point */ + FT_STROKE_TAG_CUBIC = 2, /* cubic off-point */ + FT_STROKE_TAG_BEGIN = 4, /* sub-path start */ + FT_STROKE_TAG_END = 8 /* sub-path end */ + + } FT_StrokeTags; + +#define FT_STROKE_TAG_BEGIN_END (FT_STROKE_TAG_BEGIN|FT_STROKE_TAG_END) + + typedef struct FT_StrokeBorderRec_ + { + FT_UInt num_points; + FT_UInt max_points; + FT_Vector* points; + FT_Byte* tags; + FT_Bool movable; + FT_Int start; /* index of current sub-path start point */ + FT_Memory memory; + FT_Bool valid; + + } FT_StrokeBorderRec, *FT_StrokeBorder; + + + static FT_Error + ft_stroke_border_grow( FT_StrokeBorder border, + FT_UInt new_points ) + { + FT_UInt old_max = border->max_points; + FT_UInt new_max = border->num_points + new_points; + FT_Error error = FT_Err_Ok; + + + if ( new_max > old_max ) + { + FT_UInt cur_max = old_max; + FT_Memory memory = border->memory; + + + while ( cur_max < new_max ) + cur_max += ( cur_max >> 1 ) + 16; + + if ( FT_RENEW_ARRAY( border->points, old_max, cur_max ) || + FT_RENEW_ARRAY( border->tags, old_max, cur_max ) ) + goto Exit; + + border->max_points = cur_max; + } + + Exit: + return error; + } + + + static void + ft_stroke_border_close( FT_StrokeBorder border, + FT_Bool reverse ) + { + FT_UInt start = border->start; + FT_UInt count = border->num_points; + + + FT_ASSERT( border->start >= 0 ); + + /* don't record empty paths! */ + if ( count <= start + 1U ) + border->num_points = start; + else + { + /* copy the last point to the start of this sub-path, since */ + /* it contains the `adjusted' starting coordinates */ + border->num_points = --count; + border->points[start] = border->points[count]; + + if ( reverse ) + { + /* reverse the points */ + { + FT_Vector* vec1 = border->points + start + 1; + FT_Vector* vec2 = border->points + count - 1; + + + for ( ; vec1 < vec2; vec1++, vec2-- ) + { + FT_Vector tmp; + + + tmp = *vec1; + *vec1 = *vec2; + *vec2 = tmp; + } + } + + /* then the tags */ + { + FT_Byte* tag1 = border->tags + start + 1; + FT_Byte* tag2 = border->tags + count - 1; + + + for ( ; tag1 < tag2; tag1++, tag2-- ) + { + FT_Byte tmp; + + + tmp = *tag1; + *tag1 = *tag2; + *tag2 = tmp; + } + } + } + + border->tags[start ] |= FT_STROKE_TAG_BEGIN; + border->tags[count - 1] |= FT_STROKE_TAG_END; + } + + border->start = -1; + border->movable = FALSE; + } + + + static FT_Error + ft_stroke_border_lineto( FT_StrokeBorder border, + FT_Vector* to, + FT_Bool movable ) + { + FT_Error error = FT_Err_Ok; + + + FT_ASSERT( border->start >= 0 ); + + if ( border->movable ) + { + /* move last point */ + border->points[border->num_points - 1] = *to; + } + else + { + /* add one point */ + error = ft_stroke_border_grow( border, 1 ); + if ( !error ) + { + FT_Vector* vec = border->points + border->num_points; + FT_Byte* tag = border->tags + border->num_points; + + + vec[0] = *to; + tag[0] = FT_STROKE_TAG_ON; + + border->num_points += 1; + } + } + border->movable = movable; + return error; + } + + + static FT_Error + ft_stroke_border_conicto( FT_StrokeBorder border, + FT_Vector* control, + FT_Vector* to ) + { + FT_Error error; + + + FT_ASSERT( border->start >= 0 ); + + error = ft_stroke_border_grow( border, 2 ); + if ( !error ) + { + FT_Vector* vec = border->points + border->num_points; + FT_Byte* tag = border->tags + border->num_points; + + vec[0] = *control; + vec[1] = *to; + + tag[0] = 0; + tag[1] = FT_STROKE_TAG_ON; + + border->num_points += 2; + } + border->movable = FALSE; + return error; + } + + + static FT_Error + ft_stroke_border_cubicto( FT_StrokeBorder border, + FT_Vector* control1, + FT_Vector* control2, + FT_Vector* to ) + { + FT_Error error; + + + FT_ASSERT( border->start >= 0 ); + + error = ft_stroke_border_grow( border, 3 ); + if ( !error ) + { + FT_Vector* vec = border->points + border->num_points; + FT_Byte* tag = border->tags + border->num_points; + + + vec[0] = *control1; + vec[1] = *control2; + vec[2] = *to; + + tag[0] = FT_STROKE_TAG_CUBIC; + tag[1] = FT_STROKE_TAG_CUBIC; + tag[2] = FT_STROKE_TAG_ON; + + border->num_points += 3; + } + border->movable = FALSE; + return error; + } + + +#define FT_ARC_CUBIC_ANGLE ( FT_ANGLE_PI / 2 ) + + + static FT_Error + ft_stroke_border_arcto( FT_StrokeBorder border, + FT_Vector* center, + FT_Fixed radius, + FT_Angle angle_start, + FT_Angle angle_diff ) + { + FT_Angle total, angle, step, rotate, next, theta; + FT_Vector a, b, a2, b2; + FT_Fixed length; + FT_Error error = FT_Err_Ok; + + + /* compute start point */ + FT_Vector_From_Polar( &a, radius, angle_start ); + a.x += center->x; + a.y += center->y; + + total = angle_diff; + angle = angle_start; + rotate = ( angle_diff >= 0 ) ? FT_ANGLE_PI2 : -FT_ANGLE_PI2; + + while ( total != 0 ) + { + step = total; + if ( step > FT_ARC_CUBIC_ANGLE ) + step = FT_ARC_CUBIC_ANGLE; + + else if ( step < -FT_ARC_CUBIC_ANGLE ) + step = -FT_ARC_CUBIC_ANGLE; + + next = angle + step; + theta = step; + if ( theta < 0 ) + theta = -theta; + + theta >>= 1; + + /* compute end point */ + FT_Vector_From_Polar( &b, radius, next ); + b.x += center->x; + b.y += center->y; + + /* compute first and second control points */ + length = FT_MulDiv( radius, FT_Sin( theta ) * 4, + ( 0x10000L + FT_Cos( theta ) ) * 3 ); + + FT_Vector_From_Polar( &a2, length, angle + rotate ); + a2.x += a.x; + a2.y += a.y; + + FT_Vector_From_Polar( &b2, length, next - rotate ); + b2.x += b.x; + b2.y += b.y; + + /* add cubic arc */ + error = ft_stroke_border_cubicto( border, &a2, &b2, &b ); + if ( error ) + break; + + /* process the rest of the arc ?? */ + a = b; + total -= step; + angle = next; + } + + return error; + } + + + static FT_Error + ft_stroke_border_moveto( FT_StrokeBorder border, + FT_Vector* to ) + { + /* close current open path if any ? */ + if ( border->start >= 0 ) + ft_stroke_border_close( border, FALSE ); + + border->start = border->num_points; + border->movable = FALSE; + + return ft_stroke_border_lineto( border, to, FALSE ); + } + + + static void + ft_stroke_border_init( FT_StrokeBorder border, + FT_Memory memory ) + { + border->memory = memory; + border->points = NULL; + border->tags = NULL; + + border->num_points = 0; + border->max_points = 0; + border->start = -1; + border->valid = FALSE; + } + + + static void + ft_stroke_border_reset( FT_StrokeBorder border ) + { + border->num_points = 0; + border->start = -1; + border->valid = FALSE; + } + + + static void + ft_stroke_border_done( FT_StrokeBorder border ) + { + FT_Memory memory = border->memory; + + + FT_FREE( border->points ); + FT_FREE( border->tags ); + + border->num_points = 0; + border->max_points = 0; + border->start = -1; + border->valid = FALSE; + } + + + static FT_Error + ft_stroke_border_get_counts( FT_StrokeBorder border, + FT_UInt *anum_points, + FT_UInt *anum_contours ) + { + FT_Error error = FT_Err_Ok; + FT_UInt num_points = 0; + FT_UInt num_contours = 0; + + FT_UInt count = border->num_points; + FT_Vector* point = border->points; + FT_Byte* tags = border->tags; + FT_Int in_contour = 0; + + + for ( ; count > 0; count--, num_points++, point++, tags++ ) + { + if ( tags[0] & FT_STROKE_TAG_BEGIN ) + { + if ( in_contour != 0 ) + goto Fail; + + in_contour = 1; + } + else if ( in_contour == 0 ) + goto Fail; + + if ( tags[0] & FT_STROKE_TAG_END ) + { + in_contour = 0; + num_contours++; + } + } + + if ( in_contour != 0 ) + goto Fail; + + border->valid = TRUE; + + Exit: + *anum_points = num_points; + *anum_contours = num_contours; + return error; + + Fail: + num_points = 0; + num_contours = 0; + goto Exit; + } + + + static void + ft_stroke_border_export( FT_StrokeBorder border, + FT_Outline* outline ) + { + /* copy point locations */ + FT_ARRAY_COPY( outline->points + outline->n_points, + border->points, + border->num_points ); + + /* copy tags */ + { + FT_UInt count = border->num_points; + FT_Byte* read = border->tags; + FT_Byte* write = (FT_Byte*)outline->tags + outline->n_points; + + + for ( ; count > 0; count--, read++, write++ ) + { + if ( *read & FT_STROKE_TAG_ON ) + *write = FT_CURVE_TAG_ON; + else if ( *read & FT_STROKE_TAG_CUBIC ) + *write = FT_CURVE_TAG_CUBIC; + else + *write = FT_CURVE_TAG_CONIC; + } + } + + /* copy contours */ + { + FT_UInt count = border->num_points; + FT_Byte* tags = border->tags; + FT_Short* write = outline->contours + outline->n_contours; + FT_Short idx = (FT_Short)outline->n_points; + + + for ( ; count > 0; count--, tags++, idx++ ) + { + if ( *tags & FT_STROKE_TAG_END ) + { + *write++ = idx; + outline->n_contours++; + } + } + } + + outline->n_points = (short)( outline->n_points + border->num_points ); + + FT_ASSERT( FT_Outline_Check( outline ) == 0 ); + } + + + /***************************************************************************/ + /***************************************************************************/ + /***** *****/ + /***** STROKER *****/ + /***** *****/ + /***************************************************************************/ + /***************************************************************************/ + +#define FT_SIDE_TO_ROTATE( s ) ( FT_ANGLE_PI2 - (s) * FT_ANGLE_PI ) + + typedef struct FT_StrokerRec_ + { + FT_Angle angle_in; + FT_Angle angle_out; + FT_Vector center; + FT_Bool first_point; + FT_Bool subpath_open; + FT_Angle subpath_angle; + FT_Vector subpath_start; + + FT_Stroker_LineCap line_cap; + FT_Stroker_LineJoin line_join; + FT_Fixed miter_limit; + FT_Fixed radius; + + FT_Bool valid; + FT_StrokeBorderRec borders[2]; + FT_Library library; + + } FT_StrokerRec; + + + /* documentation is in ftstroke.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Stroker_New( FT_Library library, + FT_Stroker *astroker ) + { + FT_Error error; + FT_Memory memory; + FT_Stroker stroker; + + + if ( !library ) + return FT_Err_Invalid_Argument; + + memory = library->memory; + + if ( !FT_NEW( stroker ) ) + { + stroker->library = library; + + ft_stroke_border_init( &stroker->borders[0], memory ); + ft_stroke_border_init( &stroker->borders[1], memory ); + } + *astroker = stroker; + return error; + } + + + /* documentation is in ftstroke.h */ + + FT_EXPORT_DEF( void ) + FT_Stroker_Set( FT_Stroker stroker, + FT_Fixed radius, + FT_Stroker_LineCap line_cap, + FT_Stroker_LineJoin line_join, + FT_Fixed miter_limit ) + { + stroker->radius = radius; + stroker->line_cap = line_cap; + stroker->line_join = line_join; + stroker->miter_limit = miter_limit; + + FT_Stroker_Rewind( stroker ); + } + + + /* documentation is in ftstroke.h */ + + FT_EXPORT_DEF( void ) + FT_Stroker_Rewind( FT_Stroker stroker ) + { + if ( stroker ) + { + ft_stroke_border_reset( &stroker->borders[0] ); + ft_stroke_border_reset( &stroker->borders[1] ); + } + } + + + /* documentation is in ftstroke.h */ + + FT_EXPORT_DEF( void ) + FT_Stroker_Done( FT_Stroker stroker ) + { + if ( stroker ) + { + FT_Memory memory = stroker->library->memory; + + + ft_stroke_border_done( &stroker->borders[0] ); + ft_stroke_border_done( &stroker->borders[1] ); + + stroker->library = NULL; + FT_FREE( stroker ); + } + } + + + /* creates a circular arc at a corner or cap */ + static FT_Error + ft_stroker_arcto( FT_Stroker stroker, + FT_Int side ) + { + FT_Angle total, rotate; + FT_Fixed radius = stroker->radius; + FT_Error error = FT_Err_Ok; + FT_StrokeBorder border = stroker->borders + side; + + + rotate = FT_SIDE_TO_ROTATE( side ); + + total = FT_Angle_Diff( stroker->angle_in, stroker->angle_out ); + if ( total == FT_ANGLE_PI ) + total = -rotate * 2; + + error = ft_stroke_border_arcto( border, + &stroker->center, + radius, + stroker->angle_in + rotate, + total ); + border->movable = FALSE; + return error; + } + + + /* adds a cap at the end of an opened path */ + static FT_Error + ft_stroker_cap( FT_Stroker stroker, + FT_Angle angle, + FT_Int side ) + { + FT_Error error = FT_Err_Ok; + + + if ( stroker->line_cap == FT_STROKER_LINECAP_ROUND ) + { + /* add a round cap */ + stroker->angle_in = angle; + stroker->angle_out = angle + FT_ANGLE_PI; + error = ft_stroker_arcto( stroker, side ); + } + else if ( stroker->line_cap == FT_STROKER_LINECAP_SQUARE ) + { + /* add a square cap */ + FT_Vector delta, delta2; + FT_Angle rotate = FT_SIDE_TO_ROTATE( side ); + FT_Fixed radius = stroker->radius; + FT_StrokeBorder border = stroker->borders + side; + + + FT_Vector_From_Polar( &delta2, radius, angle + rotate ); + FT_Vector_From_Polar( &delta, radius, angle ); + + delta.x += stroker->center.x + delta2.x; + delta.y += stroker->center.y + delta2.y; + + error = ft_stroke_border_lineto( border, &delta, FALSE ); + if ( error ) + goto Exit; + + FT_Vector_From_Polar( &delta2, radius, angle - rotate ); + FT_Vector_From_Polar( &delta, radius, angle ); + + delta.x += delta2.x + stroker->center.x; + delta.y += delta2.y + stroker->center.y; + + error = ft_stroke_border_lineto( border, &delta, FALSE ); + } + else if ( stroker->line_cap == FT_STROKER_LINECAP_BUTT ) + { + /* add a butt ending */ + FT_Vector delta; + FT_Angle rotate = FT_SIDE_TO_ROTATE( side ); + FT_Fixed radius = stroker->radius; + FT_StrokeBorder border = stroker->borders + side; + + + FT_Vector_From_Polar( &delta, radius, angle + rotate ); + + delta.x += stroker->center.x; + delta.y += stroker->center.y; + + error = ft_stroke_border_lineto( border, &delta, FALSE ); + if ( error ) + goto Exit; + + FT_Vector_From_Polar( &delta, radius, angle - rotate ); + + delta.x += stroker->center.x; + delta.y += stroker->center.y; + + error = ft_stroke_border_lineto( border, &delta, FALSE ); + } + + Exit: + return error; + } + + + /* process an inside corner, i.e. compute intersection */ + static FT_Error + ft_stroker_inside( FT_Stroker stroker, + FT_Int side) + { + FT_StrokeBorder border = stroker->borders + side; + FT_Angle phi, theta, rotate; + FT_Fixed length, thcos, sigma; + FT_Vector delta; + FT_Error error = FT_Err_Ok; + + + rotate = FT_SIDE_TO_ROTATE( side ); + + /* compute median angle */ + theta = FT_Angle_Diff( stroker->angle_in, stroker->angle_out ); + if ( theta == FT_ANGLE_PI ) + theta = rotate; + else + theta = theta / 2; + + phi = stroker->angle_in + theta; + + thcos = FT_Cos( theta ); + sigma = FT_MulFix( stroker->miter_limit, thcos ); + + /* TODO: find better criterion to switch off the optimization */ + if ( sigma < 0x10000L ) + { + FT_Vector_From_Polar( &delta, stroker->radius, + stroker->angle_out + rotate ); + delta.x += stroker->center.x; + delta.y += stroker->center.y; + border->movable = FALSE; + } + else + { + length = FT_DivFix( stroker->radius, thcos ); + + FT_Vector_From_Polar( &delta, length, phi + rotate ); + delta.x += stroker->center.x; + delta.y += stroker->center.y; + } + + error = ft_stroke_border_lineto( border, &delta, FALSE ); + + return error; + } + + + /* process an outside corner, i.e. compute bevel/miter/round */ + static FT_Error + ft_stroker_outside( FT_Stroker stroker, + FT_Int side ) + { + FT_StrokeBorder border = stroker->borders + side; + FT_Error error; + FT_Angle rotate; + + + if ( stroker->line_join == FT_STROKER_LINEJOIN_ROUND ) + error = ft_stroker_arcto( stroker, side ); + else + { + /* this is a mitered or beveled corner */ + FT_Fixed sigma, radius = stroker->radius; + FT_Angle theta, phi; + FT_Fixed thcos; + FT_Bool miter; + + + rotate = FT_SIDE_TO_ROTATE( side ); + miter = FT_BOOL( stroker->line_join == FT_STROKER_LINEJOIN_MITER ); + + theta = FT_Angle_Diff( stroker->angle_in, stroker->angle_out ); + if ( theta == FT_ANGLE_PI ) + { + theta = rotate; + phi = stroker->angle_in; + } + else + { + theta = theta / 2; + phi = stroker->angle_in + theta + rotate; + } + + thcos = FT_Cos( theta ); + sigma = FT_MulFix( stroker->miter_limit, thcos ); + + if ( sigma >= 0x10000L ) + miter = FALSE; + + if ( miter ) /* this is a miter (broken angle) */ + { + FT_Vector middle, delta; + FT_Fixed length; + + + /* compute middle point */ + FT_Vector_From_Polar( &middle, + FT_MulFix( radius, stroker->miter_limit ), + phi ); + middle.x += stroker->center.x; + middle.y += stroker->center.y; + + /* compute first angle point */ + length = FT_MulFix( radius, + FT_DivFix( 0x10000L - sigma, + ft_pos_abs( FT_Sin( theta ) ) ) ); + + FT_Vector_From_Polar( &delta, length, phi + rotate ); + delta.x += middle.x; + delta.y += middle.y; + + error = ft_stroke_border_lineto( border, &delta, FALSE ); + if ( error ) + goto Exit; + + /* compute second angle point */ + FT_Vector_From_Polar( &delta, length, phi - rotate ); + delta.x += middle.x; + delta.y += middle.y; + + error = ft_stroke_border_lineto( border, &delta, FALSE ); + if ( error ) + goto Exit; + + /* finally, add a movable end point */ + FT_Vector_From_Polar( &delta, radius, stroker->angle_out + rotate ); + delta.x += stroker->center.x; + delta.y += stroker->center.y; + + error = ft_stroke_border_lineto( border, &delta, TRUE ); + } + + else /* this is a bevel (intersection) */ + { + FT_Fixed length; + FT_Vector delta; + + + length = FT_DivFix( stroker->radius, thcos ); + + FT_Vector_From_Polar( &delta, length, phi ); + delta.x += stroker->center.x; + delta.y += stroker->center.y; + + error = ft_stroke_border_lineto( border, &delta, FALSE ); + if ( error ) + goto Exit; + + /* now add end point */ + FT_Vector_From_Polar( &delta, stroker->radius, + stroker->angle_out + rotate ); + delta.x += stroker->center.x; + delta.y += stroker->center.y; + + error = ft_stroke_border_lineto( border, &delta, TRUE ); + } + } + + Exit: + return error; + } + + + static FT_Error + ft_stroker_process_corner( FT_Stroker stroker ) + { + FT_Error error = FT_Err_Ok; + FT_Angle turn; + FT_Int inside_side; + + + turn = FT_Angle_Diff( stroker->angle_in, stroker->angle_out ); + + /* no specific corner processing is required if the turn is 0 */ + if ( turn == 0 ) + goto Exit; + + /* when we turn to the right, the inside side is 0 */ + inside_side = 0; + + /* otherwise, the inside side is 1 */ + if ( turn < 0 ) + inside_side = 1; + + /* process the inside side */ + error = ft_stroker_inside( stroker, inside_side ); + if ( error ) + goto Exit; + + /* process the outside side */ + error = ft_stroker_outside( stroker, 1 - inside_side ); + + Exit: + return error; + } + + + /* add two points to the left and right borders corresponding to the */ + /* start of the subpath */ + static FT_Error + ft_stroker_subpath_start( FT_Stroker stroker, + FT_Angle start_angle ) + { + FT_Vector delta; + FT_Vector point; + FT_Error error; + FT_StrokeBorder border; + + + FT_Vector_From_Polar( &delta, stroker->radius, + start_angle + FT_ANGLE_PI2 ); + + point.x = stroker->center.x + delta.x; + point.y = stroker->center.y + delta.y; + + border = stroker->borders; + error = ft_stroke_border_moveto( border, &point ); + if ( error ) + goto Exit; + + point.x = stroker->center.x - delta.x; + point.y = stroker->center.y - delta.y; + + border++; + error = ft_stroke_border_moveto( border, &point ); + + /* save angle for last cap */ + stroker->subpath_angle = start_angle; + stroker->first_point = FALSE; + + Exit: + return error; + } + + + /* documentation is in ftstroke.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Stroker_LineTo( FT_Stroker stroker, + FT_Vector* to ) + { + FT_Error error = FT_Err_Ok; + FT_StrokeBorder border; + FT_Vector delta; + FT_Angle angle; + FT_Int side; + + delta.x = to->x - stroker->center.x; + delta.y = to->y - stroker->center.y; + + angle = FT_Atan2( delta.x, delta.y ); + FT_Vector_From_Polar( &delta, stroker->radius, angle + FT_ANGLE_PI2 ); + + /* process corner if necessary */ + if ( stroker->first_point ) + { + /* This is the first segment of a subpath. We need to */ + /* add a point to each border at their respective starting */ + /* point locations. */ + error = ft_stroker_subpath_start( stroker, angle ); + if ( error ) + goto Exit; + } + else + { + /* process the current corner */ + stroker->angle_out = angle; + error = ft_stroker_process_corner( stroker ); + if ( error ) + goto Exit; + } + + /* now add a line segment to both the `inside' and `outside' paths */ + + for ( border = stroker->borders, side = 1; side >= 0; side--, border++ ) + { + FT_Vector point; + + + point.x = to->x + delta.x; + point.y = to->y + delta.y; + + error = ft_stroke_border_lineto( border, &point, TRUE ); + if ( error ) + goto Exit; + + delta.x = -delta.x; + delta.y = -delta.y; + } + + stroker->angle_in = angle; + stroker->center = *to; + + Exit: + return error; + } + + + /* documentation is in ftstroke.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Stroker_ConicTo( FT_Stroker stroker, + FT_Vector* control, + FT_Vector* to ) + { + FT_Error error = FT_Err_Ok; + FT_Vector bez_stack[34]; + FT_Vector* arc; + FT_Vector* limit = bez_stack + 30; + FT_Angle start_angle; + FT_Bool first_arc = TRUE; + + + arc = bez_stack; + arc[0] = *to; + arc[1] = *control; + arc[2] = stroker->center; + + while ( arc >= bez_stack ) + { + FT_Angle angle_in, angle_out; + + + angle_in = angle_out = 0; /* remove compiler warnings */ + + if ( arc < limit && + !ft_conic_is_small_enough( arc, &angle_in, &angle_out ) ) + { + ft_conic_split( arc ); + arc += 2; + continue; + } + + if ( first_arc ) + { + first_arc = FALSE; + + start_angle = angle_in; + + /* process corner if necessary */ + if ( stroker->first_point ) + error = ft_stroker_subpath_start( stroker, start_angle ); + else + { + stroker->angle_out = start_angle; + error = ft_stroker_process_corner( stroker ); + } + } + + /* the arc's angle is small enough; we can add it directly to each */ + /* border */ + { + FT_Vector ctrl, end; + FT_Angle theta, phi, rotate; + FT_Fixed length; + FT_Int side; + + + theta = FT_Angle_Diff( angle_in, angle_out ) / 2; + phi = angle_in + theta; + length = FT_DivFix( stroker->radius, FT_Cos( theta ) ); + + for ( side = 0; side <= 1; side++ ) + { + rotate = FT_SIDE_TO_ROTATE( side ); + + /* compute control point */ + FT_Vector_From_Polar( &ctrl, length, phi + rotate ); + ctrl.x += arc[1].x; + ctrl.y += arc[1].y; + + /* compute end point */ + FT_Vector_From_Polar( &end, stroker->radius, angle_out + rotate ); + end.x += arc[0].x; + end.y += arc[0].y; + + error = ft_stroke_border_conicto( stroker->borders + side, + &ctrl, &end ); + if ( error ) + goto Exit; + } + } + + arc -= 2; + + if ( arc < bez_stack ) + stroker->angle_in = angle_out; + } + + stroker->center = *to; + + Exit: + return error; + } + + + /* documentation is in ftstroke.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Stroker_CubicTo( FT_Stroker stroker, + FT_Vector* control1, + FT_Vector* control2, + FT_Vector* to ) + { + FT_Error error = FT_Err_Ok; + FT_Vector bez_stack[37]; + FT_Vector* arc; + FT_Vector* limit = bez_stack + 32; + FT_Angle start_angle; + FT_Bool first_arc = TRUE; + + + arc = bez_stack; + arc[0] = *to; + arc[1] = *control2; + arc[2] = *control1; + arc[3] = stroker->center; + + while ( arc >= bez_stack ) + { + FT_Angle angle_in, angle_mid, angle_out; + + + /* remove compiler warnings */ + angle_in = angle_out = angle_mid = 0; + + if ( arc < limit && + !ft_cubic_is_small_enough( arc, &angle_in, + &angle_mid, &angle_out ) ) + { + ft_cubic_split( arc ); + arc += 3; + continue; + } + + if ( first_arc ) + { + first_arc = FALSE; + + /* process corner if necessary */ + start_angle = angle_in; + + if ( stroker->first_point ) + error = ft_stroker_subpath_start( stroker, start_angle ); + else + { + stroker->angle_out = start_angle; + error = ft_stroker_process_corner( stroker ); + } + if ( error ) + goto Exit; + } + + /* the arc's angle is small enough; we can add it directly to each */ + /* border */ + { + FT_Vector ctrl1, ctrl2, end; + FT_Angle theta1, phi1, theta2, phi2, rotate; + FT_Fixed length1, length2; + FT_Int side; + + + theta1 = ft_pos_abs( angle_mid - angle_in ) / 2; + theta2 = ft_pos_abs( angle_out - angle_mid ) / 2; + phi1 = (angle_mid + angle_in ) / 2; + phi2 = (angle_mid + angle_out ) / 2; + length1 = FT_DivFix( stroker->radius, FT_Cos( theta1 ) ); + length2 = FT_DivFix( stroker->radius, FT_Cos(theta2) ); + + for ( side = 0; side <= 1; side++ ) + { + rotate = FT_SIDE_TO_ROTATE( side ); + + /* compute control points */ + FT_Vector_From_Polar( &ctrl1, length1, phi1 + rotate ); + ctrl1.x += arc[2].x; + ctrl1.y += arc[2].y; + + FT_Vector_From_Polar( &ctrl2, length2, phi2 + rotate ); + ctrl2.x += arc[1].x; + ctrl2.y += arc[1].y; + + /* compute end point */ + FT_Vector_From_Polar( &end, stroker->radius, angle_out + rotate ); + end.x += arc[0].x; + end.y += arc[0].y; + + error = ft_stroke_border_cubicto( stroker->borders + side, + &ctrl1, &ctrl2, &end ); + if ( error ) + goto Exit; + } + } + + arc -= 3; + if ( arc < bez_stack ) + stroker->angle_in = angle_out; + } + + stroker->center = *to; + + Exit: + return error; + } + + + /* documentation is in ftstroke.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Stroker_BeginSubPath( FT_Stroker stroker, + FT_Vector* to, + FT_Bool open ) + { + /* We cannot process the first point, because there is not enough */ + /* information regarding its corner/cap. The latter will be processed */ + /* in the `FT_Stroker_EndSubPath' routine. */ + /* */ + stroker->first_point = TRUE; + stroker->center = *to; + stroker->subpath_open = open; + + /* record the subpath start point for each border */ + stroker->subpath_start = *to; + + return FT_Err_Ok; + } + + + static FT_Error + ft_stroker_add_reverse_left( FT_Stroker stroker, + FT_Bool open ) + { + FT_StrokeBorder right = stroker->borders + 0; + FT_StrokeBorder left = stroker->borders + 1; + FT_Int new_points; + FT_Error error = FT_Err_Ok; + + + FT_ASSERT( left->start >= 0 ); + + new_points = left->num_points - left->start; + if ( new_points > 0 ) + { + error = ft_stroke_border_grow( right, (FT_UInt)new_points ); + if ( error ) + goto Exit; + + { + FT_Vector* dst_point = right->points + right->num_points; + FT_Byte* dst_tag = right->tags + right->num_points; + FT_Vector* src_point = left->points + left->num_points - 1; + FT_Byte* src_tag = left->tags + left->num_points - 1; + + while ( src_point >= left->points + left->start ) + { + *dst_point = *src_point; + *dst_tag = *src_tag; + + if ( open ) + dst_tag[0] &= ~FT_STROKE_TAG_BEGIN_END; + else + { + FT_Byte ttag = (FT_Byte)( dst_tag[0] & FT_STROKE_TAG_BEGIN_END ); + + + /* switch begin/end tags if necessary */ + if ( ttag == FT_STROKE_TAG_BEGIN || + ttag == FT_STROKE_TAG_END ) + dst_tag[0] ^= FT_STROKE_TAG_BEGIN_END; + + } + + src_point--; + src_tag--; + dst_point++; + dst_tag++; + } + } + + left->num_points = left->start; + right->num_points += new_points; + + right->movable = FALSE; + left->movable = FALSE; + } + + Exit: + return error; + } + + + /* documentation is in ftstroke.h */ + + /* there's a lot of magic in this function! */ + FT_EXPORT_DEF( FT_Error ) + FT_Stroker_EndSubPath( FT_Stroker stroker ) + { + FT_Error error = FT_Err_Ok; + + + if ( stroker->subpath_open ) + { + FT_StrokeBorder right = stroker->borders; + + /* All right, this is an opened path, we need to add a cap between */ + /* right & left, add the reverse of left, then add a final cap */ + /* between left & right. */ + error = ft_stroker_cap( stroker, stroker->angle_in, 0 ); + if ( error ) + goto Exit; + + /* add reversed points from `left' to `right' */ + error = ft_stroker_add_reverse_left( stroker, TRUE ); + if ( error ) + goto Exit; + + /* now add the final cap */ + stroker->center = stroker->subpath_start; + error = ft_stroker_cap( stroker, + stroker->subpath_angle + FT_ANGLE_PI, 0 ); + if ( error ) + goto Exit; + + /* Now end the right subpath accordingly. The left one is */ + /* rewind and doesn't need further processing. */ + ft_stroke_border_close( right, FALSE ); + } + else + { + FT_Angle turn; + FT_Int inside_side; + + /* close the path if needed */ + if ( stroker->center.x != stroker->subpath_start.x || + stroker->center.y != stroker->subpath_start.y ) + { + error = FT_Stroker_LineTo( stroker, &stroker->subpath_start ); + if ( error ) + goto Exit; + } + + /* process the corner */ + stroker->angle_out = stroker->subpath_angle; + turn = FT_Angle_Diff( stroker->angle_in, + stroker->angle_out ); + + /* no specific corner processing is required if the turn is 0 */ + if ( turn != 0 ) + { + /* when we turn to the right, the inside side is 0 */ + inside_side = 0; + + /* otherwise, the inside side is 1 */ + if ( turn < 0 ) + inside_side = 1; + + error = ft_stroker_inside( stroker, inside_side ); + if ( error ) + goto Exit; + + /* process the outside side */ + error = ft_stroker_outside( stroker, 1 - inside_side ); + if ( error ) + goto Exit; + } + + /* then end our two subpaths */ + ft_stroke_border_close( stroker->borders + 0, TRUE ); + ft_stroke_border_close( stroker->borders + 1, FALSE ); + } + + Exit: + return error; + } + + + /* documentation is in ftstroke.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Stroker_GetBorderCounts( FT_Stroker stroker, + FT_StrokerBorder border, + FT_UInt *anum_points, + FT_UInt *anum_contours ) + { + FT_UInt num_points = 0, num_contours = 0; + FT_Error error; + + + if ( !stroker || border > 1 ) + { + error = FT_Err_Invalid_Argument; + goto Exit; + } + + error = ft_stroke_border_get_counts( stroker->borders + border, + &num_points, &num_contours ); + Exit: + if ( anum_points ) + *anum_points = num_points; + + if ( anum_contours ) + *anum_contours = num_contours; + + return error; + } + + + /* documentation is in ftstroke.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Stroker_GetCounts( FT_Stroker stroker, + FT_UInt *anum_points, + FT_UInt *anum_contours ) + { + FT_UInt count1, count2, num_points = 0; + FT_UInt count3, count4, num_contours = 0; + FT_Error error; + + + error = ft_stroke_border_get_counts( stroker->borders + 0, + &count1, &count2 ); + if ( error ) + goto Exit; + + error = ft_stroke_border_get_counts( stroker->borders + 1, + &count3, &count4 ); + if ( error ) + goto Exit; + + num_points = count1 + count3; + num_contours = count2 + count4; + + Exit: + *anum_points = num_points; + *anum_contours = num_contours; + return error; + } + + + /* documentation is in ftstroke.h */ + + FT_EXPORT_DEF( void ) + FT_Stroker_ExportBorder( FT_Stroker stroker, + FT_StrokerBorder border, + FT_Outline* outline ) + { + if ( border == FT_STROKER_BORDER_LEFT || + border == FT_STROKER_BORDER_RIGHT ) + { + FT_StrokeBorder sborder = & stroker->borders[border]; + + + if ( sborder->valid ) + ft_stroke_border_export( sborder, outline ); + } + } + + + /* documentation is in ftstroke.h */ + + FT_EXPORT_DEF( void ) + FT_Stroker_Export( FT_Stroker stroker, + FT_Outline* outline ) + { + FT_Stroker_ExportBorder( stroker, FT_STROKER_BORDER_LEFT, outline ); + FT_Stroker_ExportBorder( stroker, FT_STROKER_BORDER_RIGHT, outline ); + } + + + /* documentation is in ftstroke.h */ + + /* + * The following is very similar to FT_Outline_Decompose, except + * that we do support opened paths, and do not scale the outline. + */ + FT_EXPORT_DEF( FT_Error ) + FT_Stroker_ParseOutline( FT_Stroker stroker, + FT_Outline* outline, + FT_Bool opened ) + { + FT_Vector v_last; + FT_Vector v_control; + FT_Vector v_start; + + FT_Vector* point; + FT_Vector* limit; + char* tags; + + FT_Error error; + + FT_Int n; /* index of contour in outline */ + FT_UInt first; /* index of first point in contour */ + FT_Int tag; /* current point's state */ + + + if ( !outline || !stroker ) + return FT_Err_Invalid_Argument; + + FT_Stroker_Rewind( stroker ); + + first = 0; + + for ( n = 0; n < outline->n_contours; n++ ) + { + FT_UInt last; /* index of last point in contour */ + + + last = outline->contours[n]; + limit = outline->points + last; + + /* skip empty points; we don't stroke these */ + if ( last <= first ) + { + first = last + 1; + continue; + } + + v_start = outline->points[first]; + v_last = outline->points[last]; + + v_control = v_start; + + point = outline->points + first; + tags = outline->tags + first; + tag = FT_CURVE_TAG( tags[0] ); + + /* A contour cannot start with a cubic control point! */ + if ( tag == FT_CURVE_TAG_CUBIC ) + goto Invalid_Outline; + + /* check first point to determine origin */ + if ( tag == FT_CURVE_TAG_CONIC ) + { + /* First point is conic control. Yes, this happens. */ + if ( FT_CURVE_TAG( outline->tags[last] ) == FT_CURVE_TAG_ON ) + { + /* start at last point if it is on the curve */ + v_start = v_last; + limit--; + } + else + { + /* if both first and last points are conic, */ + /* start at their middle and record its position */ + /* for closure */ + v_start.x = ( v_start.x + v_last.x ) / 2; + v_start.y = ( v_start.y + v_last.y ) / 2; + + v_last = v_start; + } + point--; + tags--; + } + + error = FT_Stroker_BeginSubPath( stroker, &v_start, opened ); + if ( error ) + goto Exit; + + while ( point < limit ) + { + point++; + tags++; + + tag = FT_CURVE_TAG( tags[0] ); + switch ( tag ) + { + case FT_CURVE_TAG_ON: /* emit a single line_to */ + { + FT_Vector vec; + + + vec.x = point->x; + vec.y = point->y; + + error = FT_Stroker_LineTo( stroker, &vec ); + if ( error ) + goto Exit; + continue; + } + + case FT_CURVE_TAG_CONIC: /* consume conic arcs */ + v_control.x = point->x; + v_control.y = point->y; + + Do_Conic: + if ( point < limit ) + { + FT_Vector vec; + FT_Vector v_middle; + + + point++; + tags++; + tag = FT_CURVE_TAG( tags[0] ); + + vec = point[0]; + + if ( tag == FT_CURVE_TAG_ON ) + { + error = FT_Stroker_ConicTo( stroker, &v_control, &vec ); + if ( error ) + goto Exit; + continue; + } + + if ( tag != FT_CURVE_TAG_CONIC ) + goto Invalid_Outline; + + v_middle.x = ( v_control.x + vec.x ) / 2; + v_middle.y = ( v_control.y + vec.y ) / 2; + + error = FT_Stroker_ConicTo( stroker, &v_control, &v_middle ); + if ( error ) + goto Exit; + + v_control = vec; + goto Do_Conic; + } + + error = FT_Stroker_ConicTo( stroker, &v_control, &v_start ); + goto Close; + + default: /* FT_CURVE_TAG_CUBIC */ + { + FT_Vector vec1, vec2; + + + if ( point + 1 > limit || + FT_CURVE_TAG( tags[1] ) != FT_CURVE_TAG_CUBIC ) + goto Invalid_Outline; + + point += 2; + tags += 2; + + vec1 = point[-2]; + vec2 = point[-1]; + + if ( point <= limit ) + { + FT_Vector vec; + + + vec = point[0]; + + error = FT_Stroker_CubicTo( stroker, &vec1, &vec2, &vec ); + if ( error ) + goto Exit; + continue; + } + + error = FT_Stroker_CubicTo( stroker, &vec1, &vec2, &v_start ); + goto Close; + } + } + } + + Close: + if ( error ) + goto Exit; + + error = FT_Stroker_EndSubPath( stroker ); + if ( error ) + goto Exit; + + first = last + 1; + } + + return FT_Err_Ok; + + Exit: + return error; + + Invalid_Outline: + return FT_Err_Invalid_Outline; + } + +/* declare an extern to access ft_outline_glyph_class global allocated + in ftglyph.c, and use the FT_OUTLINE_GLYPH_CLASS_GET macro to access + it when FT_CONFIG_OPTION_PIC is defined */ +#ifndef FT_CONFIG_OPTION_PIC + extern const FT_Glyph_Class ft_outline_glyph_class; +#endif +#include "basepic.h" + + + /* documentation is in ftstroke.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Glyph_Stroke( FT_Glyph *pglyph, + FT_Stroker stroker, + FT_Bool destroy ) + { + FT_Error error = FT_Err_Invalid_Argument; + FT_Glyph glyph = NULL; + FT_Library library = stroker->library; + FT_UNUSED(library); + + if ( pglyph == NULL ) + goto Exit; + + glyph = *pglyph; + if ( glyph == NULL || glyph->clazz != FT_OUTLINE_GLYPH_CLASS_GET ) + goto Exit; + + { + FT_Glyph copy; + + + error = FT_Glyph_Copy( glyph, © ); + if ( error ) + goto Exit; + + glyph = copy; + } + + { + FT_OutlineGlyph oglyph = (FT_OutlineGlyph) glyph; + FT_Outline* outline = &oglyph->outline; + FT_UInt num_points, num_contours; + + + error = FT_Stroker_ParseOutline( stroker, outline, FALSE ); + if ( error ) + goto Fail; + + (void)FT_Stroker_GetCounts( stroker, &num_points, &num_contours ); + + FT_Outline_Done( glyph->library, outline ); + + error = FT_Outline_New( glyph->library, + num_points, num_contours, outline ); + if ( error ) + goto Fail; + + outline->n_points = 0; + outline->n_contours = 0; + + FT_Stroker_Export( stroker, outline ); + } + + if ( destroy ) + FT_Done_Glyph( *pglyph ); + + *pglyph = glyph; + goto Exit; + + Fail: + FT_Done_Glyph( glyph ); + glyph = NULL; + + if ( !destroy ) + *pglyph = NULL; + + Exit: + return error; + } + + + /* documentation is in ftstroke.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Glyph_StrokeBorder( FT_Glyph *pglyph, + FT_Stroker stroker, + FT_Bool inside, + FT_Bool destroy ) + { + FT_Error error = FT_Err_Invalid_Argument; + FT_Glyph glyph = NULL; + FT_Library library = stroker->library; + FT_UNUSED(library); + + if ( pglyph == NULL ) + goto Exit; + + glyph = *pglyph; + if ( glyph == NULL || glyph->clazz != FT_OUTLINE_GLYPH_CLASS_GET ) + goto Exit; + + { + FT_Glyph copy; + + + error = FT_Glyph_Copy( glyph, © ); + if ( error ) + goto Exit; + + glyph = copy; + } + + { + FT_OutlineGlyph oglyph = (FT_OutlineGlyph) glyph; + FT_StrokerBorder border; + FT_Outline* outline = &oglyph->outline; + FT_UInt num_points, num_contours; + + + border = FT_Outline_GetOutsideBorder( outline ); + if ( inside ) + { + if ( border == FT_STROKER_BORDER_LEFT ) + border = FT_STROKER_BORDER_RIGHT; + else + border = FT_STROKER_BORDER_LEFT; + } + + error = FT_Stroker_ParseOutline( stroker, outline, FALSE ); + if ( error ) + goto Fail; + + (void)FT_Stroker_GetBorderCounts( stroker, border, + &num_points, &num_contours ); + + FT_Outline_Done( glyph->library, outline ); + + error = FT_Outline_New( glyph->library, + num_points, + num_contours, + outline ); + if ( error ) + goto Fail; + + outline->n_points = 0; + outline->n_contours = 0; + + FT_Stroker_ExportBorder( stroker, border, outline ); + } + + if ( destroy ) + FT_Done_Glyph( *pglyph ); + + *pglyph = glyph; + goto Exit; + + Fail: + FT_Done_Glyph( glyph ); + glyph = NULL; + + if ( !destroy ) + *pglyph = NULL; + + Exit: + return error; + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/base/ftsynth.c b/mod/pub.mod/freetype.mod/src/base/ftsynth.c new file mode 100644 index 0000000..326d8e7 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/base/ftsynth.c @@ -0,0 +1,160 @@ +/***************************************************************************/ +/* */ +/* ftsynth.c */ +/* */ +/* FreeType synthesizing code for emboldening and slanting (body). */ +/* */ +/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_SYNTHESIS_H +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_OBJECTS_H +#include FT_OUTLINE_H +#include FT_BITMAP_H + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_synth + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** EXPERIMENTAL OBLIQUING SUPPORT ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + /* documentation is in ftsynth.h */ + + FT_EXPORT_DEF( void ) + FT_GlyphSlot_Oblique( FT_GlyphSlot slot ) + { + FT_Matrix transform; + FT_Outline* outline = &slot->outline; + + + /* only oblique outline glyphs */ + if ( slot->format != FT_GLYPH_FORMAT_OUTLINE ) + return; + + /* we don't touch the advance width */ + + /* For italic, simply apply a shear transform, with an angle */ + /* of about 12 degrees. */ + + transform.xx = 0x10000L; + transform.yx = 0x00000L; + + transform.xy = 0x06000L; + transform.yy = 0x10000L; + + FT_Outline_Transform( outline, &transform ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** EXPERIMENTAL EMBOLDENING/OUTLINING SUPPORT ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + + /* documentation is in ftsynth.h */ + + FT_EXPORT_DEF( void ) + FT_GlyphSlot_Embolden( FT_GlyphSlot slot ) + { + FT_Library library = slot->library; + FT_Face face = slot->face; + FT_Error error; + FT_Pos xstr, ystr; + + + if ( slot->format != FT_GLYPH_FORMAT_OUTLINE && + slot->format != FT_GLYPH_FORMAT_BITMAP ) + return; + + /* some reasonable strength */ + xstr = FT_MulFix( face->units_per_EM, + face->size->metrics.y_scale ) / 24; + ystr = xstr; + + if ( slot->format == FT_GLYPH_FORMAT_OUTLINE ) + { + error = FT_Outline_Embolden( &slot->outline, xstr ); + /* ignore error */ + + /* this is more than enough for most glyphs; if you need accurate */ + /* values, you have to call FT_Outline_Get_CBox */ + xstr = xstr * 2; + ystr = xstr; + } + else if ( slot->format == FT_GLYPH_FORMAT_BITMAP ) + { + /* round to full pixels */ + xstr &= ~63; + if ( xstr == 0 ) + xstr = 1 << 6; + ystr &= ~63; + + /* + * XXX: overflow check for 16-bit system, for compatibility + * with FT_GlyphSlot_Embolden() since freetype-2.1.10. + * unfortunately, this function return no informations + * about the cause of error. + */ + if ( ( ystr >> 6 ) > FT_INT_MAX || ( ystr >> 6 ) < FT_INT_MIN ) + { + FT_TRACE1(( "FT_GlyphSlot_Embolden:" )); + FT_TRACE1(( "too strong embolding parameter ystr=%d\n", ystr )); + return; + } + error = FT_GlyphSlot_Own_Bitmap( slot ); + if ( error ) + return; + + error = FT_Bitmap_Embolden( library, &slot->bitmap, xstr, ystr ); + if ( error ) + return; + } + + if ( slot->advance.x ) + slot->advance.x += xstr; + + if ( slot->advance.y ) + slot->advance.y += ystr; + + slot->metrics.width += xstr; + slot->metrics.height += ystr; + slot->metrics.horiBearingY += ystr; + slot->metrics.horiAdvance += xstr; + slot->metrics.vertBearingX -= xstr / 2; + slot->metrics.vertBearingY += ystr; + slot->metrics.vertAdvance += ystr; + + /* XXX: 16-bit overflow case must be excluded before here */ + if ( slot->format == FT_GLYPH_FORMAT_BITMAP ) + slot->bitmap_top += (FT_Int)( ystr >> 6 ); + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/base/ftsystem.c b/mod/pub.mod/freetype.mod/src/base/ftsystem.c new file mode 100644 index 0000000..4d06d6d --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/base/ftsystem.c @@ -0,0 +1,302 @@ +/***************************************************************************/ +/* */ +/* ftsystem.c */ +/* */ +/* ANSI-specific FreeType low-level system interface (body). */ +/* */ +/* Copyright 1996-2001, 2002, 2006, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + /*************************************************************************/ + /* */ + /* This file contains the default interface used by FreeType to access */ + /* low-level, i.e. memory management, i/o access as well as thread */ + /* synchronisation. It can be replaced by user-specific routines if */ + /* necessary. */ + /* */ + /*************************************************************************/ + + +#include <ft2build.h> +#include FT_CONFIG_CONFIG_H +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_SYSTEM_H +#include FT_ERRORS_H +#include FT_TYPES_H + + + /*************************************************************************/ + /* */ + /* MEMORY MANAGEMENT INTERFACE */ + /* */ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* It is not necessary to do any error checking for the */ + /* allocation-related functions. This will be done by the higher level */ + /* routines like ft_mem_alloc() or ft_mem_realloc(). */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* ft_alloc */ + /* */ + /* <Description> */ + /* The memory allocation function. */ + /* */ + /* <Input> */ + /* memory :: A pointer to the memory object. */ + /* */ + /* size :: The requested size in bytes. */ + /* */ + /* <Return> */ + /* The address of newly allocated block. */ + /* */ + FT_CALLBACK_DEF( void* ) + ft_alloc( FT_Memory memory, + long size ) + { + FT_UNUSED( memory ); + + return ft_smalloc( size ); + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* ft_realloc */ + /* */ + /* <Description> */ + /* The memory reallocation function. */ + /* */ + /* <Input> */ + /* memory :: A pointer to the memory object. */ + /* */ + /* cur_size :: The current size of the allocated memory block. */ + /* */ + /* new_size :: The newly requested size in bytes. */ + /* */ + /* block :: The current address of the block in memory. */ + /* */ + /* <Return> */ + /* The address of the reallocated memory block. */ + /* */ + FT_CALLBACK_DEF( void* ) + ft_realloc( FT_Memory memory, + long cur_size, + long new_size, + void* block ) + { + FT_UNUSED( memory ); + FT_UNUSED( cur_size ); + + return ft_srealloc( block, new_size ); + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* ft_free */ + /* */ + /* <Description> */ + /* The memory release function. */ + /* */ + /* <Input> */ + /* memory :: A pointer to the memory object. */ + /* */ + /* block :: The address of block in memory to be freed. */ + /* */ + FT_CALLBACK_DEF( void ) + ft_free( FT_Memory memory, + void* block ) + { + FT_UNUSED( memory ); + + ft_sfree( block ); + } + + + /*************************************************************************/ + /* */ + /* RESOURCE MANAGEMENT INTERFACE */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_io + + /* We use the macro STREAM_FILE for convenience to extract the */ + /* system-specific stream handle from a given FreeType stream object */ +#define STREAM_FILE( stream ) ( (FT_FILE*)stream->descriptor.pointer ) + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* ft_ansi_stream_close */ + /* */ + /* <Description> */ + /* The function to close a stream. */ + /* */ + /* <Input> */ + /* stream :: A pointer to the stream object. */ + /* */ + FT_CALLBACK_DEF( void ) + ft_ansi_stream_close( FT_Stream stream ) + { + ft_fclose( STREAM_FILE( stream ) ); + + stream->descriptor.pointer = NULL; + stream->size = 0; + stream->base = 0; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* ft_ansi_stream_io */ + /* */ + /* <Description> */ + /* The function to open a stream. */ + /* */ + /* <Input> */ + /* stream :: A pointer to the stream object. */ + /* */ + /* offset :: The position in the data stream to start reading. */ + /* */ + /* buffer :: The address of buffer to store the read data. */ + /* */ + /* count :: The number of bytes to read from the stream. */ + /* */ + /* <Return> */ + /* The number of bytes actually read. */ + /* */ + FT_CALLBACK_DEF( unsigned long ) + ft_ansi_stream_io( FT_Stream stream, + unsigned long offset, + unsigned char* buffer, + unsigned long count ) + { + FT_FILE* file; + + + file = STREAM_FILE( stream ); + + if ( stream->pos != offset ) + ft_fseek( file, offset, SEEK_SET ); + + return (unsigned long)ft_fread( buffer, 1, count, file ); + } + + + /* documentation is in ftstream.h */ + + FT_BASE_DEF( FT_Error ) + FT_Stream_Open( FT_Stream stream, + const char* filepathname ) + { + FT_FILE* file; + + + if ( !stream ) + return FT_Err_Invalid_Stream_Handle; + + file = ft_fopen( filepathname, "rb" ); + if ( !file ) + { + FT_ERROR(( "FT_Stream_Open:" + " could not open `%s'\n", filepathname )); + + return FT_Err_Cannot_Open_Resource; + } + + ft_fseek( file, 0, SEEK_END ); + stream->size = ft_ftell( file ); + ft_fseek( file, 0, SEEK_SET ); + + stream->descriptor.pointer = file; + stream->pathname.pointer = (char*)filepathname; + stream->pos = 0; + + stream->read = ft_ansi_stream_io; + stream->close = ft_ansi_stream_close; + + FT_TRACE1(( "FT_Stream_Open:" )); + FT_TRACE1(( " opened `%s' (%d bytes) successfully\n", + filepathname, stream->size )); + + return FT_Err_Ok; + } + + +#ifdef FT_DEBUG_MEMORY + + extern FT_Int + ft_mem_debug_init( FT_Memory memory ); + + extern void + ft_mem_debug_done( FT_Memory memory ); + +#endif + + + /* documentation is in ftobjs.h */ + + FT_BASE_DEF( FT_Memory ) + FT_New_Memory( void ) + { + FT_Memory memory; + + + memory = (FT_Memory)ft_smalloc( sizeof ( *memory ) ); + if ( memory ) + { + memory->user = 0; + memory->alloc = ft_alloc; + memory->realloc = ft_realloc; + memory->free = ft_free; +#ifdef FT_DEBUG_MEMORY + ft_mem_debug_init( memory ); +#endif + } + + return memory; + } + + + /* documentation is in ftobjs.h */ + + FT_BASE_DEF( void ) + FT_Done_Memory( FT_Memory memory ) + { +#ifdef FT_DEBUG_MEMORY + ft_mem_debug_done( memory ); +#endif + ft_sfree( memory ); + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/base/fttrigon.c b/mod/pub.mod/freetype.mod/src/base/fttrigon.c new file mode 100644 index 0000000..fdf433a --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/base/fttrigon.c @@ -0,0 +1,546 @@ +/***************************************************************************/ +/* */ +/* fttrigon.c */ +/* */ +/* FreeType trigonometric functions (body). */ +/* */ +/* Copyright 2001, 2002, 2003, 2004, 2005 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H +#include FT_TRIGONOMETRY_H + + + /* the following is 0.2715717684432231 * 2^30 */ +#define FT_TRIG_COSCALE 0x11616E8EUL + + /* this table was generated for FT_PI = 180L << 16, i.e. degrees */ +#define FT_TRIG_MAX_ITERS 23 + + static const FT_Fixed + ft_trig_arctan_table[24] = + { + 4157273L, 2949120L, 1740967L, 919879L, 466945L, 234379L, 117304L, + 58666L, 29335L, 14668L, 7334L, 3667L, 1833L, 917L, 458L, 229L, 115L, + 57L, 29L, 14L, 7L, 4L, 2L, 1L + }; + + /* the Cordic shrink factor, multiplied by 2^32 */ +#define FT_TRIG_SCALE 1166391785UL /* 0x4585BA38UL */ + + +#ifdef FT_CONFIG_HAS_INT64 + + /* multiply a given value by the CORDIC shrink factor */ + static FT_Fixed + ft_trig_downscale( FT_Fixed val ) + { + FT_Fixed s; + FT_Int64 v; + + + s = val; + val = ( val >= 0 ) ? val : -val; + + v = ( val * (FT_Int64)FT_TRIG_SCALE ) + 0x100000000UL; + val = (FT_Fixed)( v >> 32 ); + + return ( s >= 0 ) ? val : -val; + } + +#else /* !FT_CONFIG_HAS_INT64 */ + + /* multiply a given value by the CORDIC shrink factor */ + static FT_Fixed + ft_trig_downscale( FT_Fixed val ) + { + FT_Fixed s; + FT_UInt32 v1, v2, k1, k2, hi, lo1, lo2, lo3; + + + s = val; + val = ( val >= 0 ) ? val : -val; + + v1 = (FT_UInt32)val >> 16; + v2 = (FT_UInt32)(val & 0xFFFFL); + + k1 = (FT_UInt32)FT_TRIG_SCALE >> 16; /* constant */ + k2 = (FT_UInt32)(FT_TRIG_SCALE & 0xFFFFL); /* constant */ + + hi = k1 * v1; + lo1 = k1 * v2 + k2 * v1; /* can't overflow */ + + lo2 = ( k2 * v2 ) >> 16; + lo3 = ( lo1 >= lo2 ) ? lo1 : lo2; + lo1 += lo2; + + hi += lo1 >> 16; + if ( lo1 < lo3 ) + hi += (FT_UInt32)0x10000UL; + + val = (FT_Fixed)hi; + + return ( s >= 0 ) ? val : -val; + } + +#endif /* !FT_CONFIG_HAS_INT64 */ + + + static FT_Int + ft_trig_prenorm( FT_Vector* vec ) + { + FT_Fixed x, y, z; + FT_Int shift; + + + x = vec->x; + y = vec->y; + + z = ( ( x >= 0 ) ? x : - x ) | ( (y >= 0) ? y : -y ); + shift = 0; + +#if 1 + /* determine msb bit index in `shift' */ + if ( z >= ( 1L << 16 ) ) + { + z >>= 16; + shift += 16; + } + if ( z >= ( 1L << 8 ) ) + { + z >>= 8; + shift += 8; + } + if ( z >= ( 1L << 4 ) ) + { + z >>= 4; + shift += 4; + } + if ( z >= ( 1L << 2 ) ) + { + z >>= 2; + shift += 2; + } + if ( z >= ( 1L << 1 ) ) + { + z >>= 1; + shift += 1; + } + + if ( shift <= 27 ) + { + shift = 27 - shift; + vec->x = x << shift; + vec->y = y << shift; + } + else + { + shift -= 27; + vec->x = x >> shift; + vec->y = y >> shift; + shift = -shift; + } + +#else /* 0 */ + + if ( z < ( 1L << 27 ) ) + { + do + { + shift++; + z <<= 1; + } while ( z < ( 1L << 27 ) ); + vec->x = x << shift; + vec->y = y << shift; + } + else if ( z > ( 1L << 28 ) ) + { + do + { + shift++; + z >>= 1; + } while ( z > ( 1L << 28 ) ); + + vec->x = x >> shift; + vec->y = y >> shift; + shift = -shift; + } + +#endif /* 0 */ + + return shift; + } + + + static void + ft_trig_pseudo_rotate( FT_Vector* vec, + FT_Angle theta ) + { + FT_Int i; + FT_Fixed x, y, xtemp; + const FT_Fixed *arctanptr; + + + x = vec->x; + y = vec->y; + + /* Get angle between -90 and 90 degrees */ + while ( theta <= -FT_ANGLE_PI2 ) + { + x = -x; + y = -y; + theta += FT_ANGLE_PI; + } + + while ( theta > FT_ANGLE_PI2 ) + { + x = -x; + y = -y; + theta -= FT_ANGLE_PI; + } + + /* Initial pseudorotation, with left shift */ + arctanptr = ft_trig_arctan_table; + + if ( theta < 0 ) + { + xtemp = x + ( y << 1 ); + y = y - ( x << 1 ); + x = xtemp; + theta += *arctanptr++; + } + else + { + xtemp = x - ( y << 1 ); + y = y + ( x << 1 ); + x = xtemp; + theta -= *arctanptr++; + } + + /* Subsequent pseudorotations, with right shifts */ + i = 0; + do + { + if ( theta < 0 ) + { + xtemp = x + ( y >> i ); + y = y - ( x >> i ); + x = xtemp; + theta += *arctanptr++; + } + else + { + xtemp = x - ( y >> i ); + y = y + ( x >> i ); + x = xtemp; + theta -= *arctanptr++; + } + } while ( ++i < FT_TRIG_MAX_ITERS ); + + vec->x = x; + vec->y = y; + } + + + static void + ft_trig_pseudo_polarize( FT_Vector* vec ) + { + FT_Fixed theta; + FT_Fixed yi, i; + FT_Fixed x, y; + const FT_Fixed *arctanptr; + + + x = vec->x; + y = vec->y; + + /* Get the vector into the right half plane */ + theta = 0; + if ( x < 0 ) + { + x = -x; + y = -y; + theta = 2 * FT_ANGLE_PI2; + } + + if ( y > 0 ) + theta = - theta; + + arctanptr = ft_trig_arctan_table; + + if ( y < 0 ) + { + /* Rotate positive */ + yi = y + ( x << 1 ); + x = x - ( y << 1 ); + y = yi; + theta -= *arctanptr++; /* Subtract angle */ + } + else + { + /* Rotate negative */ + yi = y - ( x << 1 ); + x = x + ( y << 1 ); + y = yi; + theta += *arctanptr++; /* Add angle */ + } + + i = 0; + do + { + if ( y < 0 ) + { + /* Rotate positive */ + yi = y + ( x >> i ); + x = x - ( y >> i ); + y = yi; + theta -= *arctanptr++; + } + else + { + /* Rotate negative */ + yi = y - ( x >> i ); + x = x + ( y >> i ); + y = yi; + theta += *arctanptr++; + } + } while ( ++i < FT_TRIG_MAX_ITERS ); + + /* round theta */ + if ( theta >= 0 ) + theta = FT_PAD_ROUND( theta, 32 ); + else + theta = -FT_PAD_ROUND( -theta, 32 ); + + vec->x = x; + vec->y = theta; + } + + + /* documentation is in fttrigon.h */ + + FT_EXPORT_DEF( FT_Fixed ) + FT_Cos( FT_Angle angle ) + { + FT_Vector v; + + + v.x = FT_TRIG_COSCALE >> 2; + v.y = 0; + ft_trig_pseudo_rotate( &v, angle ); + + return v.x / ( 1 << 12 ); + } + + + /* documentation is in fttrigon.h */ + + FT_EXPORT_DEF( FT_Fixed ) + FT_Sin( FT_Angle angle ) + { + return FT_Cos( FT_ANGLE_PI2 - angle ); + } + + + /* documentation is in fttrigon.h */ + + FT_EXPORT_DEF( FT_Fixed ) + FT_Tan( FT_Angle angle ) + { + FT_Vector v; + + + v.x = FT_TRIG_COSCALE >> 2; + v.y = 0; + ft_trig_pseudo_rotate( &v, angle ); + + return FT_DivFix( v.y, v.x ); + } + + + /* documentation is in fttrigon.h */ + + FT_EXPORT_DEF( FT_Angle ) + FT_Atan2( FT_Fixed dx, + FT_Fixed dy ) + { + FT_Vector v; + + + if ( dx == 0 && dy == 0 ) + return 0; + + v.x = dx; + v.y = dy; + ft_trig_prenorm( &v ); + ft_trig_pseudo_polarize( &v ); + + return v.y; + } + + + /* documentation is in fttrigon.h */ + + FT_EXPORT_DEF( void ) + FT_Vector_Unit( FT_Vector* vec, + FT_Angle angle ) + { + vec->x = FT_TRIG_COSCALE >> 2; + vec->y = 0; + ft_trig_pseudo_rotate( vec, angle ); + vec->x >>= 12; + vec->y >>= 12; + } + + + /* these macros return 0 for positive numbers, + and -1 for negative ones */ +#define FT_SIGN_LONG( x ) ( (x) >> ( FT_SIZEOF_LONG * 8 - 1 ) ) +#define FT_SIGN_INT( x ) ( (x) >> ( FT_SIZEOF_INT * 8 - 1 ) ) +#define FT_SIGN_INT32( x ) ( (x) >> 31 ) +#define FT_SIGN_INT16( x ) ( (x) >> 15 ) + + + /* documentation is in fttrigon.h */ + + FT_EXPORT_DEF( void ) + FT_Vector_Rotate( FT_Vector* vec, + FT_Angle angle ) + { + FT_Int shift; + FT_Vector v; + + + v.x = vec->x; + v.y = vec->y; + + if ( angle && ( v.x != 0 || v.y != 0 ) ) + { + shift = ft_trig_prenorm( &v ); + ft_trig_pseudo_rotate( &v, angle ); + v.x = ft_trig_downscale( v.x ); + v.y = ft_trig_downscale( v.y ); + + if ( shift > 0 ) + { + FT_Int32 half = (FT_Int32)1L << ( shift - 1 ); + + + vec->x = ( v.x + half + FT_SIGN_LONG( v.x ) ) >> shift; + vec->y = ( v.y + half + FT_SIGN_LONG( v.y ) ) >> shift; + } + else + { + shift = -shift; + vec->x = v.x << shift; + vec->y = v.y << shift; + } + } + } + + + /* documentation is in fttrigon.h */ + + FT_EXPORT_DEF( FT_Fixed ) + FT_Vector_Length( FT_Vector* vec ) + { + FT_Int shift; + FT_Vector v; + + + v = *vec; + + /* handle trivial cases */ + if ( v.x == 0 ) + { + return ( v.y >= 0 ) ? v.y : -v.y; + } + else if ( v.y == 0 ) + { + return ( v.x >= 0 ) ? v.x : -v.x; + } + + /* general case */ + shift = ft_trig_prenorm( &v ); + ft_trig_pseudo_polarize( &v ); + + v.x = ft_trig_downscale( v.x ); + + if ( shift > 0 ) + return ( v.x + ( 1 << ( shift - 1 ) ) ) >> shift; + + return v.x << -shift; + } + + + /* documentation is in fttrigon.h */ + + FT_EXPORT_DEF( void ) + FT_Vector_Polarize( FT_Vector* vec, + FT_Fixed *length, + FT_Angle *angle ) + { + FT_Int shift; + FT_Vector v; + + + v = *vec; + + if ( v.x == 0 && v.y == 0 ) + return; + + shift = ft_trig_prenorm( &v ); + ft_trig_pseudo_polarize( &v ); + + v.x = ft_trig_downscale( v.x ); + + *length = ( shift >= 0 ) ? ( v.x >> shift ) : ( v.x << -shift ); + *angle = v.y; + } + + + /* documentation is in fttrigon.h */ + + FT_EXPORT_DEF( void ) + FT_Vector_From_Polar( FT_Vector* vec, + FT_Fixed length, + FT_Angle angle ) + { + vec->x = length; + vec->y = 0; + + FT_Vector_Rotate( vec, angle ); + } + + + /* documentation is in fttrigon.h */ + + FT_EXPORT_DEF( FT_Angle ) + FT_Angle_Diff( FT_Angle angle1, + FT_Angle angle2 ) + { + FT_Angle delta = angle2 - angle1; + + + delta %= FT_ANGLE_2PI; + if ( delta < 0 ) + delta += FT_ANGLE_2PI; + + if ( delta > FT_ANGLE_PI ) + delta -= FT_ANGLE_2PI; + + return delta; + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/base/fttype1.c b/mod/pub.mod/freetype.mod/src/base/fttype1.c new file mode 100644 index 0000000..3975584 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/base/fttype1.c @@ -0,0 +1,94 @@ +/***************************************************************************/ +/* */ +/* fttype1.c */ +/* */ +/* FreeType utility file for PS names support (body). */ +/* */ +/* Copyright 2002, 2003, 2004 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_SERVICE_H +#include FT_SERVICE_POSTSCRIPT_INFO_H + + + /* documentation is in t1tables.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_PS_Font_Info( FT_Face face, + PS_FontInfoRec* afont_info ) + { + FT_Error error = FT_Err_Invalid_Argument; + + + if ( face ) + { + FT_Service_PsInfo service = NULL; + + + FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO ); + + if ( service && service->ps_get_font_info ) + error = service->ps_get_font_info( face, afont_info ); + } + + return error; + } + + + /* documentation is in t1tables.h */ + + FT_EXPORT_DEF( FT_Int ) + FT_Has_PS_Glyph_Names( FT_Face face ) + { + FT_Int result = 0; + FT_Service_PsInfo service = NULL; + + + if ( face ) + { + FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO ); + + if ( service && service->ps_has_glyph_names ) + result = service->ps_has_glyph_names( face ); + } + + return result; + } + + + /* documentation is in t1tables.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_PS_Font_Private( FT_Face face, + PS_PrivateRec* afont_private ) + { + FT_Error error = FT_Err_Invalid_Argument; + + + if ( face ) + { + FT_Service_PsInfo service = NULL; + + + FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO ); + + if ( service && service->ps_get_font_private ) + error = service->ps_get_font_private( face, afont_private ); + } + + return error; + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/base/ftutil.c b/mod/pub.mod/freetype.mod/src/base/ftutil.c new file mode 100644 index 0000000..5f77be5 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/base/ftutil.c @@ -0,0 +1,501 @@ +/***************************************************************************/ +/* */ +/* ftutil.c */ +/* */ +/* FreeType utility file for memory and list management (body). */ +/* */ +/* Copyright 2002, 2004, 2005, 2006, 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_MEMORY_H +#include FT_INTERNAL_OBJECTS_H +#include FT_LIST_H + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_memory + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** *****/ + /***** M E M O R Y M A N A G E M E N T *****/ + /***** *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + FT_BASE_DEF( FT_Pointer ) + ft_mem_alloc( FT_Memory memory, + FT_Long size, + FT_Error *p_error ) + { + FT_Error error; + FT_Pointer block = ft_mem_qalloc( memory, size, &error ); + + if ( !error && size > 0 ) + FT_MEM_ZERO( block, size ); + + *p_error = error; + return block; + } + + + FT_BASE_DEF( FT_Pointer ) + ft_mem_qalloc( FT_Memory memory, + FT_Long size, + FT_Error *p_error ) + { + FT_Error error = FT_Err_Ok; + FT_Pointer block = NULL; + + + if ( size > 0 ) + { + block = memory->alloc( memory, size ); + if ( block == NULL ) + error = FT_Err_Out_Of_Memory; + } + else if ( size < 0 ) + { + /* may help catch/prevent security issues */ + error = FT_Err_Invalid_Argument; + } + + *p_error = error; + return block; + } + + + FT_BASE_DEF( FT_Pointer ) + ft_mem_realloc( FT_Memory memory, + FT_Long item_size, + FT_Long cur_count, + FT_Long new_count, + void* block, + FT_Error *p_error ) + { + FT_Error error = FT_Err_Ok; + + block = ft_mem_qrealloc( memory, item_size, + cur_count, new_count, block, &error ); + if ( !error && new_count > cur_count ) + FT_MEM_ZERO( (char*)block + cur_count * item_size, + ( new_count - cur_count ) * item_size ); + + *p_error = error; + return block; + } + + + FT_BASE_DEF( FT_Pointer ) + ft_mem_qrealloc( FT_Memory memory, + FT_Long item_size, + FT_Long cur_count, + FT_Long new_count, + void* block, + FT_Error *p_error ) + { + FT_Error error = FT_Err_Ok; + + + /* Note that we now accept `item_size == 0' as a valid parameter, in + * order to cover very weird cases where an ALLOC_MULT macro would be + * called. + */ + if ( cur_count < 0 || new_count < 0 || item_size < 0 ) + { + /* may help catch/prevent nasty security issues */ + error = FT_Err_Invalid_Argument; + } + else if ( new_count == 0 || item_size == 0 ) + { + ft_mem_free( memory, block ); + block = NULL; + } + else if ( new_count > FT_INT_MAX/item_size ) + { + error = FT_Err_Array_Too_Large; + } + else if ( cur_count == 0 ) + { + FT_ASSERT( block == NULL ); + + block = ft_mem_alloc( memory, new_count*item_size, &error ); + } + else + { + FT_Pointer block2; + FT_Long cur_size = cur_count*item_size; + FT_Long new_size = new_count*item_size; + + + block2 = memory->realloc( memory, cur_size, new_size, block ); + if ( block2 == NULL ) + error = FT_Err_Out_Of_Memory; + else + block = block2; + } + + *p_error = error; + return block; + } + + + FT_BASE_DEF( void ) + ft_mem_free( FT_Memory memory, + const void *P ) + { + if ( P ) + memory->free( memory, (void*)P ); + } + + + FT_BASE_DEF( FT_Pointer ) + ft_mem_dup( FT_Memory memory, + const void* address, + FT_ULong size, + FT_Error *p_error ) + { + FT_Error error; + FT_Pointer p = ft_mem_qalloc( memory, size, &error ); + + + if ( !error && address ) + ft_memcpy( p, address, size ); + + *p_error = error; + return p; + } + + + FT_BASE_DEF( FT_Pointer ) + ft_mem_strdup( FT_Memory memory, + const char* str, + FT_Error *p_error ) + { + FT_ULong len = str ? (FT_ULong)ft_strlen( str ) + 1 + : 0; + + + return ft_mem_dup( memory, str, len, p_error ); + } + + + FT_BASE_DEF( FT_Int ) + ft_mem_strcpyn( char* dst, + const char* src, + FT_ULong size ) + { + while ( size > 1 && *src != 0 ) + { + *dst++ = *src++; + size--; + } + + *dst = 0; /* always zero-terminate */ + + return *src != 0; + } + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** *****/ + /***** D O U B L Y L I N K E D L I S T S *****/ + /***** *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + +#undef FT_COMPONENT +#define FT_COMPONENT trace_list + + /* documentation is in ftlist.h */ + + FT_EXPORT_DEF( FT_ListNode ) + FT_List_Find( FT_List list, + void* data ) + { + FT_ListNode cur; + + + cur = list->head; + while ( cur ) + { + if ( cur->data == data ) + return cur; + + cur = cur->next; + } + + return (FT_ListNode)0; + } + + + /* documentation is in ftlist.h */ + + FT_EXPORT_DEF( void ) + FT_List_Add( FT_List list, + FT_ListNode node ) + { + FT_ListNode before = list->tail; + + + node->next = 0; + node->prev = before; + + if ( before ) + before->next = node; + else + list->head = node; + + list->tail = node; + } + + + /* documentation is in ftlist.h */ + + FT_EXPORT_DEF( void ) + FT_List_Insert( FT_List list, + FT_ListNode node ) + { + FT_ListNode after = list->head; + + + node->next = after; + node->prev = 0; + + if ( !after ) + list->tail = node; + else + after->prev = node; + + list->head = node; + } + + + /* documentation is in ftlist.h */ + + FT_EXPORT_DEF( void ) + FT_List_Remove( FT_List list, + FT_ListNode node ) + { + FT_ListNode before, after; + + + before = node->prev; + after = node->next; + + if ( before ) + before->next = after; + else + list->head = after; + + if ( after ) + after->prev = before; + else + list->tail = before; + } + + + /* documentation is in ftlist.h */ + + FT_EXPORT_DEF( void ) + FT_List_Up( FT_List list, + FT_ListNode node ) + { + FT_ListNode before, after; + + + before = node->prev; + after = node->next; + + /* check whether we are already on top of the list */ + if ( !before ) + return; + + before->next = after; + + if ( after ) + after->prev = before; + else + list->tail = before; + + node->prev = 0; + node->next = list->head; + list->head->prev = node; + list->head = node; + } + + + /* documentation is in ftlist.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_List_Iterate( FT_List list, + FT_List_Iterator iterator, + void* user ) + { + FT_ListNode cur = list->head; + FT_Error error = FT_Err_Ok; + + + while ( cur ) + { + FT_ListNode next = cur->next; + + + error = iterator( cur, user ); + if ( error ) + break; + + cur = next; + } + + return error; + } + + + /* documentation is in ftlist.h */ + + FT_EXPORT_DEF( void ) + FT_List_Finalize( FT_List list, + FT_List_Destructor destroy, + FT_Memory memory, + void* user ) + { + FT_ListNode cur; + + + cur = list->head; + while ( cur ) + { + FT_ListNode next = cur->next; + void* data = cur->data; + + + if ( destroy ) + destroy( memory, data, user ); + + FT_FREE( cur ); + cur = next; + } + + list->head = 0; + list->tail = 0; + } + + + FT_BASE_DEF( FT_UInt32 ) + ft_highpow2( FT_UInt32 value ) + { + FT_UInt32 value2; + + + /* + * We simply clear the lowest bit in each iteration. When + * we reach 0, we know that the previous value was our result. + */ + for ( ;; ) + { + value2 = value & (value - 1); /* clear lowest bit */ + if ( value2 == 0 ) + break; + + value = value2; + } + return value; + } + + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + + FT_BASE_DEF( FT_Error ) + FT_Alloc( FT_Memory memory, + FT_Long size, + void* *P ) + { + FT_Error error; + + + (void)FT_ALLOC( *P, size ); + return error; + } + + + FT_BASE_DEF( FT_Error ) + FT_QAlloc( FT_Memory memory, + FT_Long size, + void* *p ) + { + FT_Error error; + + + (void)FT_QALLOC( *p, size ); + return error; + } + + + FT_BASE_DEF( FT_Error ) + FT_Realloc( FT_Memory memory, + FT_Long current, + FT_Long size, + void* *P ) + { + FT_Error error; + + + (void)FT_REALLOC( *P, current, size ); + return error; + } + + + FT_BASE_DEF( FT_Error ) + FT_QRealloc( FT_Memory memory, + FT_Long current, + FT_Long size, + void* *p ) + { + FT_Error error; + + + (void)FT_QREALLOC( *p, current, size ); + return error; + } + + + FT_BASE_DEF( void ) + FT_Free( FT_Memory memory, + void* *P ) + { + if ( *P ) + FT_MEM_FREE( *P ); + } + +#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */ + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/base/ftwinfnt.c b/mod/pub.mod/freetype.mod/src/base/ftwinfnt.c new file mode 100644 index 0000000..bc2e90e --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/base/ftwinfnt.c @@ -0,0 +1,51 @@ +/***************************************************************************/ +/* */ +/* ftwinfnt.c */ +/* */ +/* FreeType API for accessing Windows FNT specific info (body). */ +/* */ +/* Copyright 2003, 2004 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_WINFONTS_H +#include FT_INTERNAL_OBJECTS_H +#include FT_SERVICE_WINFNT_H + + + /* documentation is in ftwinfnt.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_WinFNT_Header( FT_Face face, + FT_WinFNT_HeaderRec *header ) + { + FT_Service_WinFnt service; + FT_Error error; + + + error = FT_Err_Invalid_Argument; + + if ( face != NULL ) + { + FT_FACE_LOOKUP_SERVICE( face, service, WINFNT ); + + if ( service != NULL ) + { + error = service->get_header( face, header ); + } + } + + return error; + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/base/ftxf86.c b/mod/pub.mod/freetype.mod/src/base/ftxf86.c new file mode 100644 index 0000000..a4bf767 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/base/ftxf86.c @@ -0,0 +1,40 @@ +/***************************************************************************/ +/* */ +/* ftxf86.c */ +/* */ +/* FreeType utility file for X11 support (body). */ +/* */ +/* Copyright 2002, 2003, 2004 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_XFREE86_H +#include FT_INTERNAL_OBJECTS_H +#include FT_SERVICE_XFREE86_NAME_H + + + /* documentation is in ftxf86.h */ + + FT_EXPORT_DEF( const char* ) + FT_Get_X11_Font_Format( FT_Face face ) + { + const char* result = NULL; + + + if ( face ) + FT_FACE_FIND_SERVICE( face, result, XF86_NAME ); + + return result; + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/bdf/bdf.c b/mod/pub.mod/freetype.mod/src/bdf/bdf.c new file mode 100644 index 0000000..f95fb76 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/bdf/bdf.c @@ -0,0 +1,34 @@ +/* bdf.c + + FreeType font driver for bdf files + + Copyright (C) 2001, 2002 by + Francesco Zappa Nardelli + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#define FT_MAKE_OPTION_SINGLE_OBJECT + +#include <ft2build.h> +#include "bdflib.c" +#include "bdfdrivr.c" + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/bdf/bdf.h b/mod/pub.mod/freetype.mod/src/bdf/bdf.h new file mode 100644 index 0000000..561b415 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/bdf/bdf.h @@ -0,0 +1,295 @@ +/* + * Copyright 2000 Computing Research Labs, New Mexico State University + * Copyright 2001, 2002, 2003, 2004 Francesco Zappa Nardelli + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT + * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +#ifndef __BDF_H__ +#define __BDF_H__ + + +/* + * Based on bdf.h,v 1.16 2000/03/16 20:08:51 mleisher + */ + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_STREAM_H + + +FT_BEGIN_HEADER + + +/* Imported from bdfP.h */ + +#define _bdf_glyph_modified( map, e ) \ + ( (map)[(e) >> 5] & ( 1 << ( (e) & 31 ) ) ) +#define _bdf_set_glyph_modified( map, e ) \ + ( (map)[(e) >> 5] |= ( 1 << ( (e) & 31 ) ) ) +#define _bdf_clear_glyph_modified( map, e ) \ + ( (map)[(e) >> 5] &= ~( 1 << ( (e) & 31 ) ) ) + +/* end of bdfP.h */ + + + /*************************************************************************/ + /* */ + /* BDF font options macros and types. */ + /* */ + /*************************************************************************/ + + +#define BDF_CORRECT_METRICS 0x01 /* Correct invalid metrics when loading. */ +#define BDF_KEEP_COMMENTS 0x02 /* Preserve the font comments. */ +#define BDF_KEEP_UNENCODED 0x04 /* Keep the unencoded glyphs. */ +#define BDF_PROPORTIONAL 0x08 /* Font has proportional spacing. */ +#define BDF_MONOWIDTH 0x10 /* Font has mono width. */ +#define BDF_CHARCELL 0x20 /* Font has charcell spacing. */ + +#define BDF_ALL_SPACING ( BDF_PROPORTIONAL | \ + BDF_MONOWIDTH | \ + BDF_CHARCELL ) + +#define BDF_DEFAULT_LOAD_OPTIONS ( BDF_CORRECT_METRICS | \ + BDF_KEEP_COMMENTS | \ + BDF_KEEP_UNENCODED | \ + BDF_PROPORTIONAL ) + + + typedef struct bdf_options_t_ + { + int correct_metrics; + int keep_unencoded; + int keep_comments; + int font_spacing; + + } bdf_options_t; + + + /* Callback function type for unknown configuration options. */ + typedef int + (*bdf_options_callback_t)( bdf_options_t* opts, + char** params, + unsigned long nparams, + void* client_data ); + + + /*************************************************************************/ + /* */ + /* BDF font property macros and types. */ + /* */ + /*************************************************************************/ + + +#define BDF_ATOM 1 +#define BDF_INTEGER 2 +#define BDF_CARDINAL 3 + + + /* This structure represents a particular property of a font. */ + /* There are a set of defaults and each font has their own. */ + typedef struct bdf_property_t_ + { + char* name; /* Name of the property. */ + int format; /* Format of the property. */ + int builtin; /* A builtin property. */ + union + { + char* atom; + long l; + unsigned long ul; + + } value; /* Value of the property. */ + + } bdf_property_t; + + + /*************************************************************************/ + /* */ + /* BDF font metric and glyph types. */ + /* */ + /*************************************************************************/ + + + typedef struct bdf_bbx_t_ + { + unsigned short width; + unsigned short height; + + short x_offset; + short y_offset; + + short ascent; + short descent; + + } bdf_bbx_t; + + + typedef struct bdf_glyph_t_ + { + char* name; /* Glyph name. */ + long encoding; /* Glyph encoding. */ + unsigned short swidth; /* Scalable width. */ + unsigned short dwidth; /* Device width. */ + bdf_bbx_t bbx; /* Glyph bounding box. */ + unsigned char* bitmap; /* Glyph bitmap. */ + unsigned long bpr; /* Number of bytes used per row. */ + unsigned short bytes; /* Number of bytes used for the bitmap. */ + + } bdf_glyph_t; + + + typedef struct _hashnode_ + { + const char* key; + size_t data; + + } _hashnode, *hashnode; + + + typedef struct hashtable_ + { + int limit; + int size; + int used; + hashnode* table; + + } hashtable; + + + typedef struct bdf_glyphlist_t_ + { + unsigned short pad; /* Pad to 4-byte boundary. */ + unsigned short bpp; /* Bits per pixel. */ + long start; /* Beginning encoding value of glyphs. */ + long end; /* Ending encoding value of glyphs. */ + bdf_glyph_t* glyphs; /* Glyphs themselves. */ + unsigned long glyphs_size; /* Glyph structures allocated. */ + unsigned long glyphs_used; /* Glyph structures used. */ + bdf_bbx_t bbx; /* Overall bounding box of glyphs. */ + + } bdf_glyphlist_t; + + + typedef struct bdf_font_t_ + { + char* name; /* Name of the font. */ + bdf_bbx_t bbx; /* Font bounding box. */ + + long point_size; /* Point size of the font. */ + unsigned long resolution_x; /* Font horizontal resolution. */ + unsigned long resolution_y; /* Font vertical resolution. */ + + int spacing; /* Font spacing value. */ + + unsigned short monowidth; /* Logical width for monowidth font. */ + + long default_char; /* Encoding of the default glyph. */ + + long font_ascent; /* Font ascent. */ + long font_descent; /* Font descent. */ + + unsigned long glyphs_size; /* Glyph structures allocated. */ + unsigned long glyphs_used; /* Glyph structures used. */ + bdf_glyph_t* glyphs; /* Glyphs themselves. */ + + unsigned long unencoded_size; /* Unencoded glyph struct. allocated. */ + unsigned long unencoded_used; /* Unencoded glyph struct. used. */ + bdf_glyph_t* unencoded; /* Unencoded glyphs themselves. */ + + unsigned long props_size; /* Font properties allocated. */ + unsigned long props_used; /* Font properties used. */ + bdf_property_t* props; /* Font properties themselves. */ + + char* comments; /* Font comments. */ + unsigned long comments_len; /* Length of comment string. */ + + bdf_glyphlist_t overflow; /* Storage used for glyph insertion. */ + + void* internal; /* Internal data for the font. */ + + unsigned long nmod[2048]; /* Bitmap indicating modified glyphs. */ + unsigned long umod[2048]; /* Bitmap indicating modified */ + /* unencoded glyphs. */ + unsigned short modified; /* Boolean indicating font modified. */ + unsigned short bpp; /* Bits per pixel. */ + + FT_Memory memory; + + bdf_property_t* user_props; + unsigned long nuser_props; + hashtable proptbl; + + } bdf_font_t; + + + /*************************************************************************/ + /* */ + /* Types for load/save callbacks. */ + /* */ + /*************************************************************************/ + + + /* Error codes. */ +#define BDF_MISSING_START -1 +#define BDF_MISSING_FONTNAME -2 +#define BDF_MISSING_SIZE -3 +#define BDF_MISSING_CHARS -4 +#define BDF_MISSING_STARTCHAR -5 +#define BDF_MISSING_ENCODING -6 +#define BDF_MISSING_BBX -7 + +#define BDF_OUT_OF_MEMORY -20 + +#define BDF_INVALID_LINE -100 + + + /*************************************************************************/ + /* */ + /* BDF font API. */ + /* */ + /*************************************************************************/ + + FT_LOCAL( FT_Error ) + bdf_load_font( FT_Stream stream, + FT_Memory memory, + bdf_options_t* opts, + bdf_font_t* *font ); + + FT_LOCAL( void ) + bdf_free_font( bdf_font_t* font ); + + FT_LOCAL( bdf_property_t * ) + bdf_get_property( char* name, + bdf_font_t* font ); + + FT_LOCAL( bdf_property_t * ) + bdf_get_font_property( bdf_font_t* font, + const char* name ); + + +FT_END_HEADER + + +#endif /* __BDF_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/bdf/bdfdrivr.c b/mod/pub.mod/freetype.mod/src/bdf/bdfdrivr.c new file mode 100644 index 0000000..631ec46 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/bdf/bdfdrivr.c @@ -0,0 +1,879 @@ +/* bdfdrivr.c + + FreeType font driver for bdf files + + Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by + Francesco Zappa Nardelli + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#include <ft2build.h> + +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_OBJECTS_H +#include FT_BDF_H + +#include FT_SERVICE_BDF_H +#include FT_SERVICE_XFREE86_NAME_H + +#include "bdf.h" +#include "bdfdrivr.h" + +#include "bdferror.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_bdfdriver + + + typedef struct BDF_CMapRec_ + { + FT_CMapRec cmap; + FT_ULong num_encodings; /* ftobjs.h: FT_CMap->clazz->size */ + BDF_encoding_el* encodings; + + } BDF_CMapRec, *BDF_CMap; + + + FT_CALLBACK_DEF( FT_Error ) + bdf_cmap_init( FT_CMap bdfcmap, + FT_Pointer init_data ) + { + BDF_CMap cmap = (BDF_CMap)bdfcmap; + BDF_Face face = (BDF_Face)FT_CMAP_FACE( cmap ); + FT_UNUSED( init_data ); + + + cmap->num_encodings = face->bdffont->glyphs_used; + cmap->encodings = face->en_table; + + return BDF_Err_Ok; + } + + + FT_CALLBACK_DEF( void ) + bdf_cmap_done( FT_CMap bdfcmap ) + { + BDF_CMap cmap = (BDF_CMap)bdfcmap; + + + cmap->encodings = NULL; + cmap->num_encodings = 0; + } + + + FT_CALLBACK_DEF( FT_UInt ) + bdf_cmap_char_index( FT_CMap bdfcmap, + FT_UInt32 charcode ) + { + BDF_CMap cmap = (BDF_CMap)bdfcmap; + BDF_encoding_el* encodings = cmap->encodings; + FT_ULong min, max, mid; /* num_encodings */ + FT_UShort result = 0; /* encodings->glyph */ + + + min = 0; + max = cmap->num_encodings; + + while ( min < max ) + { + FT_ULong code; + + + mid = ( min + max ) >> 1; + code = encodings[mid].enc; + + if ( charcode == code ) + { + /* increase glyph index by 1 -- */ + /* we reserve slot 0 for the undefined glyph */ + result = encodings[mid].glyph + 1; + break; + } + + if ( charcode < code ) + max = mid; + else + min = mid + 1; + } + + return result; + } + + + FT_CALLBACK_DEF( FT_UInt ) + bdf_cmap_char_next( FT_CMap bdfcmap, + FT_UInt32 *acharcode ) + { + BDF_CMap cmap = (BDF_CMap)bdfcmap; + BDF_encoding_el* encodings = cmap->encodings; + FT_ULong min, max, mid; /* num_encodings */ + FT_UShort result = 0; /* encodings->glyph */ + FT_ULong charcode = *acharcode + 1; + + + min = 0; + max = cmap->num_encodings; + + while ( min < max ) + { + FT_ULong code; /* same as BDF_encoding_el.enc */ + + + mid = ( min + max ) >> 1; + code = encodings[mid].enc; + + if ( charcode == code ) + { + /* increase glyph index by 1 -- */ + /* we reserve slot 0 for the undefined glyph */ + result = encodings[mid].glyph + 1; + goto Exit; + } + + if ( charcode < code ) + max = mid; + else + min = mid + 1; + } + + charcode = 0; + if ( min < cmap->num_encodings ) + { + charcode = encodings[min].enc; + result = encodings[min].glyph + 1; + } + + Exit: + if ( charcode > 0xFFFFFFFFUL ) + { + FT_TRACE1(( "bdf_cmap_char_next: charcode 0x%x > 32bit API" )); + *acharcode = 0; + /* XXX: result should be changed to indicate an overflow error */ + } + else + *acharcode = (FT_UInt32)charcode; + return result; + } + + + FT_CALLBACK_TABLE_DEF + const FT_CMap_ClassRec bdf_cmap_class = + { + sizeof ( BDF_CMapRec ), + bdf_cmap_init, + bdf_cmap_done, + bdf_cmap_char_index, + bdf_cmap_char_next, + + NULL, NULL, NULL, NULL, NULL + }; + + + static FT_Error + bdf_interpret_style( BDF_Face bdf ) + { + FT_Error error = BDF_Err_Ok; + FT_Face face = FT_FACE( bdf ); + FT_Memory memory = face->memory; + bdf_font_t* font = bdf->bdffont; + bdf_property_t* prop; + + char* strings[4] = { NULL, NULL, NULL, NULL }; + size_t nn, len, lengths[4]; + + + face->style_flags = 0; + + prop = bdf_get_font_property( font, (char *)"SLANT" ); + if ( prop && prop->format == BDF_ATOM && + prop->value.atom && + ( *(prop->value.atom) == 'O' || *(prop->value.atom) == 'o' || + *(prop->value.atom) == 'I' || *(prop->value.atom) == 'i' ) ) + { + face->style_flags |= FT_STYLE_FLAG_ITALIC; + strings[2] = ( *(prop->value.atom) == 'O' || *(prop->value.atom) == 'o' ) + ? (char *)"Oblique" + : (char *)"Italic"; + } + + prop = bdf_get_font_property( font, (char *)"WEIGHT_NAME" ); + if ( prop && prop->format == BDF_ATOM && + prop->value.atom && + ( *(prop->value.atom) == 'B' || *(prop->value.atom) == 'b' ) ) + { + face->style_flags |= FT_STYLE_FLAG_BOLD; + strings[1] = (char *)"Bold"; + } + + prop = bdf_get_font_property( font, (char *)"SETWIDTH_NAME" ); + if ( prop && prop->format == BDF_ATOM && + prop->value.atom && *(prop->value.atom) && + !( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) ) + strings[3] = (char *)(prop->value.atom); + + prop = bdf_get_font_property( font, (char *)"ADD_STYLE_NAME" ); + if ( prop && prop->format == BDF_ATOM && + prop->value.atom && *(prop->value.atom) && + !( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) ) + strings[0] = (char *)(prop->value.atom); + + len = 0; + + for ( len = 0, nn = 0; nn < 4; nn++ ) + { + lengths[nn] = 0; + if ( strings[nn] ) + { + lengths[nn] = ft_strlen( strings[nn] ); + len += lengths[nn] + 1; + } + } + + if ( len == 0 ) + { + strings[0] = (char *)"Regular"; + lengths[0] = ft_strlen( strings[0] ); + len = lengths[0] + 1; + } + + { + char* s; + + + if ( FT_ALLOC( face->style_name, len ) ) + return error; + + s = face->style_name; + + for ( nn = 0; nn < 4; nn++ ) + { + char* src = strings[nn]; + + + len = lengths[nn]; + + if ( src == NULL ) + continue; + + /* separate elements with a space */ + if ( s != face->style_name ) + *s++ = ' '; + + ft_memcpy( s, src, len ); + + /* need to convert spaces to dashes for */ + /* add_style_name and setwidth_name */ + if ( nn == 0 || nn == 3 ) + { + size_t mm; + + + for ( mm = 0; mm < len; mm++ ) + if ( s[mm] == ' ' ) + s[mm] = '-'; + } + + s += len; + } + *s = 0; + } + + return error; + } + + + FT_CALLBACK_DEF( void ) + BDF_Face_Done( FT_Face bdfface ) /* BDF_Face */ + { + BDF_Face face = (BDF_Face)bdfface; + FT_Memory memory; + + + if ( !face ) + return; + + memory = FT_FACE_MEMORY( face ); + + bdf_free_font( face->bdffont ); + + FT_FREE( face->en_table ); + + FT_FREE( face->charset_encoding ); + FT_FREE( face->charset_registry ); + FT_FREE( bdfface->family_name ); + FT_FREE( bdfface->style_name ); + + FT_FREE( bdfface->available_sizes ); + + FT_FREE( face->bdffont ); + + FT_TRACE4(( "BDF_Face_Done: done face\n" )); + } + + + FT_CALLBACK_DEF( FT_Error ) + BDF_Face_Init( FT_Stream stream, + FT_Face bdfface, /* BDF_Face */ + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ) + { + FT_Error error = BDF_Err_Ok; + BDF_Face face = (BDF_Face)bdfface; + FT_Memory memory = FT_FACE_MEMORY( face ); + + bdf_font_t* font = NULL; + bdf_options_t options; + + FT_UNUSED( num_params ); + FT_UNUSED( params ); + FT_UNUSED( face_index ); + + + if ( FT_STREAM_SEEK( 0 ) ) + goto Exit; + + options.correct_metrics = 1; /* FZ XXX: options semantics */ + options.keep_unencoded = 1; + options.keep_comments = 0; + options.font_spacing = BDF_PROPORTIONAL; + + error = bdf_load_font( stream, memory, &options, &font ); + if ( error == BDF_Err_Missing_Startfont_Field ) + { + FT_TRACE2(( "[not a valid BDF file]\n" )); + goto Fail; + } + else if ( error ) + goto Exit; + + /* we have a bdf font: let's construct the face object */ + face->bdffont = font; + { + bdf_property_t* prop = NULL; + + + FT_TRACE4(( "number of glyphs: %d (%d)\n", + font->glyphs_size, + font->glyphs_used )); + FT_TRACE4(( "number of unencoded glyphs: %d (%d)\n", + font->unencoded_size, + font->unencoded_used )); + + bdfface->num_faces = 1; + bdfface->face_index = 0; + bdfface->face_flags = FT_FACE_FLAG_FIXED_SIZES | + FT_FACE_FLAG_HORIZONTAL | + FT_FACE_FLAG_FAST_GLYPHS; + + prop = bdf_get_font_property( font, "SPACING" ); + if ( prop && prop->format == BDF_ATOM && + prop->value.atom && + ( *(prop->value.atom) == 'M' || *(prop->value.atom) == 'm' || + *(prop->value.atom) == 'C' || *(prop->value.atom) == 'c' ) ) + bdfface->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; + + /* FZ XXX: TO DO: FT_FACE_FLAGS_VERTICAL */ + /* FZ XXX: I need a font to implement this */ + + prop = bdf_get_font_property( font, "FAMILY_NAME" ); + if ( prop && prop->value.atom ) + { + if ( FT_STRDUP( bdfface->family_name, prop->value.atom ) ) + goto Exit; + } + else + bdfface->family_name = 0; + + if ( ( error = bdf_interpret_style( face ) ) != 0 ) + goto Exit; + + /* the number of glyphs (with one slot for the undefined glyph */ + /* at position 0 and all unencoded glyphs) */ + bdfface->num_glyphs = font->glyphs_size + 1; + + bdfface->num_fixed_sizes = 1; + if ( FT_NEW_ARRAY( bdfface->available_sizes, 1 ) ) + goto Exit; + + { + FT_Bitmap_Size* bsize = bdfface->available_sizes; + FT_Short resolution_x = 0, resolution_y = 0; + + + FT_MEM_ZERO( bsize, sizeof ( FT_Bitmap_Size ) ); + + bsize->height = (FT_Short)( font->font_ascent + font->font_descent ); + + prop = bdf_get_font_property( font, "AVERAGE_WIDTH" ); + if ( prop ) + bsize->width = (FT_Short)( ( prop->value.l + 5 ) / 10 ); + else + bsize->width = (FT_Short)( bsize->height * 2/3 ); + + prop = bdf_get_font_property( font, "POINT_SIZE" ); + if ( prop ) + /* convert from 722.7 decipoints to 72 points per inch */ + bsize->size = + (FT_Pos)( ( prop->value.l * 64 * 7200 + 36135L ) / 72270L ); + else + bsize->size = bsize->width << 6; + + prop = bdf_get_font_property( font, "PIXEL_SIZE" ); + if ( prop ) + bsize->y_ppem = (FT_Short)prop->value.l << 6; + + prop = bdf_get_font_property( font, "RESOLUTION_X" ); + if ( prop ) + resolution_x = (FT_Short)prop->value.l; + + prop = bdf_get_font_property( font, "RESOLUTION_Y" ); + if ( prop ) + resolution_y = (FT_Short)prop->value.l; + + if ( bsize->y_ppem == 0 ) + { + bsize->y_ppem = bsize->size; + if ( resolution_y ) + bsize->y_ppem = bsize->y_ppem * resolution_y / 72; + } + if ( resolution_x && resolution_y ) + bsize->x_ppem = bsize->y_ppem * resolution_x / resolution_y; + else + bsize->x_ppem = bsize->y_ppem; + } + + /* encoding table */ + { + bdf_glyph_t* cur = font->glyphs; + unsigned long n; + + + if ( FT_NEW_ARRAY( face->en_table, font->glyphs_size ) ) + goto Exit; + + face->default_glyph = 0; + for ( n = 0; n < font->glyphs_size; n++ ) + { + (face->en_table[n]).enc = cur[n].encoding; + FT_TRACE4(( "idx %d, val 0x%lX\n", n, cur[n].encoding )); + (face->en_table[n]).glyph = (FT_Short)n; + + if ( cur[n].encoding == font->default_char ) + { + if ( n < FT_UINT_MAX ) + face->default_glyph = (FT_UInt)n; + else + FT_TRACE1(( "idx %d is too large for this system\n", n )); + } + } + } + + /* charmaps */ + { + bdf_property_t *charset_registry = 0, *charset_encoding = 0; + FT_Bool unicode_charmap = 0; + + + charset_registry = + bdf_get_font_property( font, "CHARSET_REGISTRY" ); + charset_encoding = + bdf_get_font_property( font, "CHARSET_ENCODING" ); + if ( charset_registry && charset_encoding ) + { + if ( charset_registry->format == BDF_ATOM && + charset_encoding->format == BDF_ATOM && + charset_registry->value.atom && + charset_encoding->value.atom ) + { + const char* s; + + + if ( FT_STRDUP( face->charset_encoding, + charset_encoding->value.atom ) || + FT_STRDUP( face->charset_registry, + charset_registry->value.atom ) ) + goto Exit; + + /* Uh, oh, compare first letters manually to avoid dependency */ + /* on locales. */ + s = face->charset_registry; + if ( ( s[0] == 'i' || s[0] == 'I' ) && + ( s[1] == 's' || s[1] == 'S' ) && + ( s[2] == 'o' || s[2] == 'O' ) ) + { + s += 3; + if ( !ft_strcmp( s, "10646" ) || + ( !ft_strcmp( s, "8859" ) && + !ft_strcmp( face->charset_encoding, "1" ) ) ) + unicode_charmap = 1; + } + + { + FT_CharMapRec charmap; + + + charmap.face = FT_FACE( face ); + charmap.encoding = FT_ENCODING_NONE; + charmap.platform_id = 0; + charmap.encoding_id = 0; + + if ( unicode_charmap ) + { + charmap.encoding = FT_ENCODING_UNICODE; + charmap.platform_id = 3; + charmap.encoding_id = 1; + } + + error = FT_CMap_New( &bdf_cmap_class, NULL, &charmap, NULL ); + +#if 0 + /* Select default charmap */ + if ( bdfface->num_charmaps ) + bdfface->charmap = bdfface->charmaps[0]; +#endif + } + + goto Exit; + } + } + + /* otherwise assume Adobe standard encoding */ + + { + FT_CharMapRec charmap; + + + charmap.face = FT_FACE( face ); + charmap.encoding = FT_ENCODING_ADOBE_STANDARD; + charmap.platform_id = 7; + charmap.encoding_id = 0; + + error = FT_CMap_New( &bdf_cmap_class, NULL, &charmap, NULL ); + + /* Select default charmap */ + if ( bdfface->num_charmaps ) + bdfface->charmap = bdfface->charmaps[0]; + } + } + } + + Exit: + return error; + + Fail: + BDF_Face_Done( bdfface ); + return BDF_Err_Unknown_File_Format; + } + + + FT_CALLBACK_DEF( FT_Error ) + BDF_Size_Select( FT_Size size, + FT_ULong strike_index ) + { + bdf_font_t* bdffont = ( (BDF_Face)size->face )->bdffont; + + + FT_Select_Metrics( size->face, strike_index ); + + size->metrics.ascender = bdffont->font_ascent << 6; + size->metrics.descender = -bdffont->font_descent << 6; + size->metrics.max_advance = bdffont->bbx.width << 6; + + return BDF_Err_Ok; + } + + + FT_CALLBACK_DEF( FT_Error ) + BDF_Size_Request( FT_Size size, + FT_Size_Request req ) + { + FT_Face face = size->face; + FT_Bitmap_Size* bsize = face->available_sizes; + bdf_font_t* bdffont = ( (BDF_Face)face )->bdffont; + FT_Error error = BDF_Err_Invalid_Pixel_Size; + FT_Long height; + + + height = FT_REQUEST_HEIGHT( req ); + height = ( height + 32 ) >> 6; + + switch ( req->type ) + { + case FT_SIZE_REQUEST_TYPE_NOMINAL: + if ( height == ( ( bsize->y_ppem + 32 ) >> 6 ) ) + error = BDF_Err_Ok; + break; + + case FT_SIZE_REQUEST_TYPE_REAL_DIM: + if ( height == ( bdffont->font_ascent + + bdffont->font_descent ) ) + error = BDF_Err_Ok; + break; + + default: + error = BDF_Err_Unimplemented_Feature; + break; + } + + if ( error ) + return error; + else + return BDF_Size_Select( size, 0 ); + } + + + + FT_CALLBACK_DEF( FT_Error ) + BDF_Glyph_Load( FT_GlyphSlot slot, + FT_Size size, + FT_UInt glyph_index, + FT_Int32 load_flags ) + { + BDF_Face bdf = (BDF_Face)FT_SIZE_FACE( size ); + FT_Face face = FT_FACE( bdf ); + FT_Error error = BDF_Err_Ok; + FT_Bitmap* bitmap = &slot->bitmap; + bdf_glyph_t glyph; + int bpp = bdf->bdffont->bpp; + + FT_UNUSED( load_flags ); + + + if ( !face || glyph_index >= (FT_UInt)face->num_glyphs ) + { + error = BDF_Err_Invalid_Argument; + goto Exit; + } + + /* index 0 is the undefined glyph */ + if ( glyph_index == 0 ) + glyph_index = bdf->default_glyph; + else + glyph_index--; + + /* slot, bitmap => freetype, glyph => bdflib */ + glyph = bdf->bdffont->glyphs[glyph_index]; + + bitmap->rows = glyph.bbx.height; + bitmap->width = glyph.bbx.width; + if ( glyph.bpr > INT_MAX ) + FT_TRACE1(( "BDF_Glyph_Load: too large pitch %d is truncated\n", + glyph.bpr )); + bitmap->pitch = (int)glyph.bpr; /* same as FT_Bitmap.pitch */ + + /* note: we don't allocate a new array to hold the bitmap; */ + /* we can simply point to it */ + ft_glyphslot_set_bitmap( slot, glyph.bitmap ); + + switch ( bpp ) + { + case 1: + bitmap->pixel_mode = FT_PIXEL_MODE_MONO; + break; + case 2: + bitmap->pixel_mode = FT_PIXEL_MODE_GRAY2; + break; + case 4: + bitmap->pixel_mode = FT_PIXEL_MODE_GRAY4; + break; + case 8: + bitmap->pixel_mode = FT_PIXEL_MODE_GRAY; + bitmap->num_grays = 256; + break; + } + + slot->format = FT_GLYPH_FORMAT_BITMAP; + slot->bitmap_left = glyph.bbx.x_offset; + slot->bitmap_top = glyph.bbx.ascent; + + slot->metrics.horiAdvance = glyph.dwidth << 6; + slot->metrics.horiBearingX = glyph.bbx.x_offset << 6; + slot->metrics.horiBearingY = glyph.bbx.ascent << 6; + slot->metrics.width = bitmap->width << 6; + slot->metrics.height = bitmap->rows << 6; + + /* + * XXX DWIDTH1 and VVECTOR should be parsed and + * used here, provided such fonts do exist. + */ + ft_synthesize_vertical_metrics( &slot->metrics, + bdf->bdffont->bbx.height << 6 ); + + Exit: + return error; + } + + + /* + * + * BDF SERVICE + * + */ + + static FT_Error + bdf_get_bdf_property( BDF_Face face, + const char* prop_name, + BDF_PropertyRec *aproperty ) + { + bdf_property_t* prop; + + + FT_ASSERT( face && face->bdffont ); + + prop = bdf_get_font_property( face->bdffont, prop_name ); + if ( prop ) + { + switch ( prop->format ) + { + case BDF_ATOM: + aproperty->type = BDF_PROPERTY_TYPE_ATOM; + aproperty->u.atom = prop->value.atom; + break; + + case BDF_INTEGER: + if ( prop->value.l > 0x7FFFFFFFL || prop->value.l < ( -1 - 0x7FFFFFFFL ) ) + { + FT_TRACE1(( "bdf_get_bdf_property: " )); + FT_TRACE1(( "too large integer 0x%x is truncated\n" )); + } + aproperty->type = BDF_PROPERTY_TYPE_INTEGER; + aproperty->u.integer = (FT_Int32)prop->value.l; + break; + + case BDF_CARDINAL: + if ( prop->value.ul > 0xFFFFFFFFUL ) + { + FT_TRACE1(( "bdf_get_bdf_property: " )); + FT_TRACE1(( "too large cardinal 0x%x is truncated\n" )); + } + aproperty->type = BDF_PROPERTY_TYPE_CARDINAL; + aproperty->u.cardinal = (FT_UInt32)prop->value.ul; + break; + + default: + goto Fail; + } + return 0; + } + + Fail: + return BDF_Err_Invalid_Argument; + } + + + static FT_Error + bdf_get_charset_id( BDF_Face face, + const char* *acharset_encoding, + const char* *acharset_registry ) + { + *acharset_encoding = face->charset_encoding; + *acharset_registry = face->charset_registry; + + return 0; + } + + + static const FT_Service_BDFRec bdf_service_bdf = + { + (FT_BDF_GetCharsetIdFunc)bdf_get_charset_id, + (FT_BDF_GetPropertyFunc) bdf_get_bdf_property + }; + + + /* + * + * SERVICES LIST + * + */ + + static const FT_ServiceDescRec bdf_services[] = + { + { FT_SERVICE_ID_BDF, &bdf_service_bdf }, + { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_BDF }, + { NULL, NULL } + }; + + + FT_CALLBACK_DEF( FT_Module_Interface ) + bdf_driver_requester( FT_Module module, + const char* name ) + { + FT_UNUSED( module ); + + return ft_service_list_lookup( bdf_services, name ); + } + + + + FT_CALLBACK_TABLE_DEF + const FT_Driver_ClassRec bdf_driver_class = + { + { + FT_MODULE_FONT_DRIVER | + FT_MODULE_DRIVER_NO_OUTLINES, + sizeof ( FT_DriverRec ), + + "bdf", + 0x10000L, + 0x20000L, + + 0, + + (FT_Module_Constructor)0, + (FT_Module_Destructor) 0, + (FT_Module_Requester) bdf_driver_requester + }, + + sizeof ( BDF_FaceRec ), + sizeof ( FT_SizeRec ), + sizeof ( FT_GlyphSlotRec ), + + BDF_Face_Init, + BDF_Face_Done, + 0, /* FT_Size_InitFunc */ + 0, /* FT_Size_DoneFunc */ + 0, /* FT_Slot_InitFunc */ + 0, /* FT_Slot_DoneFunc */ + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + ft_stub_set_char_sizes, + ft_stub_set_pixel_sizes, +#endif + BDF_Glyph_Load, + + 0, /* FT_Face_GetKerningFunc */ + 0, /* FT_Face_AttachFunc */ + 0, /* FT_Face_GetAdvancesFunc */ + + BDF_Size_Request, + BDF_Size_Select + }; + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/bdf/bdfdrivr.h b/mod/pub.mod/freetype.mod/src/bdf/bdfdrivr.h new file mode 100644 index 0000000..db7093b --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/bdf/bdfdrivr.h @@ -0,0 +1,80 @@ +/* bdfdrivr.h + + FreeType font driver for bdf fonts + + Copyright (C) 2001, 2002, 2003, 2004 by + Francesco Zappa Nardelli + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + + +#ifndef __BDFDRIVR_H__ +#define __BDFDRIVR_H__ + +#include <ft2build.h> +#include FT_INTERNAL_DRIVER_H + +#include "bdf.h" + + +FT_BEGIN_HEADER + +#ifdef FT_CONFIG_OPTION_PIC +#error "this module does not support PIC yet" +#endif + + + typedef struct BDF_encoding_el_ + { + FT_ULong enc; + FT_UShort glyph; + + } BDF_encoding_el; + + + typedef struct BDF_FaceRec_ + { + FT_FaceRec root; + + char* charset_encoding; + char* charset_registry; + + bdf_font_t* bdffont; + + BDF_encoding_el* en_table; + + FT_CharMap charmap_handle; + FT_CharMapRec charmap; /* a single charmap per face */ + + FT_UInt default_glyph; + + } BDF_FaceRec, *BDF_Face; + + + FT_EXPORT_VAR( const FT_Driver_ClassRec ) bdf_driver_class; + + +FT_END_HEADER + + +#endif /* __BDFDRIVR_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/bdf/bdferror.h b/mod/pub.mod/freetype.mod/src/bdf/bdferror.h new file mode 100644 index 0000000..b27fa33 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/bdf/bdferror.h @@ -0,0 +1,44 @@ +/* + * Copyright 2001, 2002 Francesco Zappa Nardelli + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT + * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + /*************************************************************************/ + /* */ + /* This file is used to define the BDF error enumeration constants. */ + /* */ + /*************************************************************************/ + +#ifndef __BDFERROR_H__ +#define __BDFERROR_H__ + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#define FT_ERR_PREFIX BDF_Err_ +#define FT_ERR_BASE FT_Mod_Err_BDF + +#include FT_ERRORS_H + +#endif /* __BDFERROR_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/bdf/bdflib.c b/mod/pub.mod/freetype.mod/src/bdf/bdflib.c new file mode 100644 index 0000000..5fa5868 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/bdf/bdflib.c @@ -0,0 +1,2481 @@ +/* + * Copyright 2000 Computing Research Labs, New Mexico State University + * Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009 + * Francesco Zappa Nardelli + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT + * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + /*************************************************************************/ + /* */ + /* This file is based on bdf.c,v 1.22 2000/03/16 20:08:50 */ + /* */ + /* taken from Mark Leisher's xmbdfed package */ + /* */ + /*************************************************************************/ + + +#include <ft2build.h> + +#include FT_FREETYPE_H +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_OBJECTS_H + +#include "bdf.h" +#include "bdferror.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_bdflib + + + /*************************************************************************/ + /* */ + /* Default BDF font options. */ + /* */ + /*************************************************************************/ + + + static const bdf_options_t _bdf_opts = + { + 1, /* Correct metrics. */ + 1, /* Preserve unencoded glyphs. */ + 0, /* Preserve comments. */ + BDF_PROPORTIONAL /* Default spacing. */ + }; + + + /*************************************************************************/ + /* */ + /* Builtin BDF font properties. */ + /* */ + /*************************************************************************/ + + /* List of most properties that might appear in a font. Doesn't include */ + /* the RAW_* and AXIS_* properties in X11R6 polymorphic fonts. */ + + static const bdf_property_t _bdf_properties[] = + { + { (char *)"ADD_STYLE_NAME", BDF_ATOM, 1, { 0 } }, + { (char *)"AVERAGE_WIDTH", BDF_INTEGER, 1, { 0 } }, + { (char *)"AVG_CAPITAL_WIDTH", BDF_INTEGER, 1, { 0 } }, + { (char *)"AVG_LOWERCASE_WIDTH", BDF_INTEGER, 1, { 0 } }, + { (char *)"CAP_HEIGHT", BDF_INTEGER, 1, { 0 } }, + { (char *)"CHARSET_COLLECTIONS", BDF_ATOM, 1, { 0 } }, + { (char *)"CHARSET_ENCODING", BDF_ATOM, 1, { 0 } }, + { (char *)"CHARSET_REGISTRY", BDF_ATOM, 1, { 0 } }, + { (char *)"COMMENT", BDF_ATOM, 1, { 0 } }, + { (char *)"COPYRIGHT", BDF_ATOM, 1, { 0 } }, + { (char *)"DEFAULT_CHAR", BDF_CARDINAL, 1, { 0 } }, + { (char *)"DESTINATION", BDF_CARDINAL, 1, { 0 } }, + { (char *)"DEVICE_FONT_NAME", BDF_ATOM, 1, { 0 } }, + { (char *)"END_SPACE", BDF_INTEGER, 1, { 0 } }, + { (char *)"FACE_NAME", BDF_ATOM, 1, { 0 } }, + { (char *)"FAMILY_NAME", BDF_ATOM, 1, { 0 } }, + { (char *)"FIGURE_WIDTH", BDF_INTEGER, 1, { 0 } }, + { (char *)"FONT", BDF_ATOM, 1, { 0 } }, + { (char *)"FONTNAME_REGISTRY", BDF_ATOM, 1, { 0 } }, + { (char *)"FONT_ASCENT", BDF_INTEGER, 1, { 0 } }, + { (char *)"FONT_DESCENT", BDF_INTEGER, 1, { 0 } }, + { (char *)"FOUNDRY", BDF_ATOM, 1, { 0 } }, + { (char *)"FULL_NAME", BDF_ATOM, 1, { 0 } }, + { (char *)"ITALIC_ANGLE", BDF_INTEGER, 1, { 0 } }, + { (char *)"MAX_SPACE", BDF_INTEGER, 1, { 0 } }, + { (char *)"MIN_SPACE", BDF_INTEGER, 1, { 0 } }, + { (char *)"NORM_SPACE", BDF_INTEGER, 1, { 0 } }, + { (char *)"NOTICE", BDF_ATOM, 1, { 0 } }, + { (char *)"PIXEL_SIZE", BDF_INTEGER, 1, { 0 } }, + { (char *)"POINT_SIZE", BDF_INTEGER, 1, { 0 } }, + { (char *)"QUAD_WIDTH", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_ASCENT", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_AVERAGE_WIDTH", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_AVG_CAPITAL_WIDTH", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_AVG_LOWERCASE_WIDTH", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_CAP_HEIGHT", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_DESCENT", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_END_SPACE", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_FIGURE_WIDTH", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_MAX_SPACE", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_MIN_SPACE", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_NORM_SPACE", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_PIXEL_SIZE", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_POINT_SIZE", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_PIXELSIZE", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_POINTSIZE", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_QUAD_WIDTH", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_SMALL_CAP_SIZE", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_STRIKEOUT_ASCENT", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_STRIKEOUT_DESCENT", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_SUBSCRIPT_SIZE", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_SUBSCRIPT_X", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_SUBSCRIPT_Y", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_SUPERSCRIPT_SIZE", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_SUPERSCRIPT_X", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_SUPERSCRIPT_Y", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_UNDERLINE_POSITION", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_UNDERLINE_THICKNESS", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_X_HEIGHT", BDF_INTEGER, 1, { 0 } }, + { (char *)"RELATIVE_SETWIDTH", BDF_CARDINAL, 1, { 0 } }, + { (char *)"RELATIVE_WEIGHT", BDF_CARDINAL, 1, { 0 } }, + { (char *)"RESOLUTION", BDF_INTEGER, 1, { 0 } }, + { (char *)"RESOLUTION_X", BDF_CARDINAL, 1, { 0 } }, + { (char *)"RESOLUTION_Y", BDF_CARDINAL, 1, { 0 } }, + { (char *)"SETWIDTH_NAME", BDF_ATOM, 1, { 0 } }, + { (char *)"SLANT", BDF_ATOM, 1, { 0 } }, + { (char *)"SMALL_CAP_SIZE", BDF_INTEGER, 1, { 0 } }, + { (char *)"SPACING", BDF_ATOM, 1, { 0 } }, + { (char *)"STRIKEOUT_ASCENT", BDF_INTEGER, 1, { 0 } }, + { (char *)"STRIKEOUT_DESCENT", BDF_INTEGER, 1, { 0 } }, + { (char *)"SUBSCRIPT_SIZE", BDF_INTEGER, 1, { 0 } }, + { (char *)"SUBSCRIPT_X", BDF_INTEGER, 1, { 0 } }, + { (char *)"SUBSCRIPT_Y", BDF_INTEGER, 1, { 0 } }, + { (char *)"SUPERSCRIPT_SIZE", BDF_INTEGER, 1, { 0 } }, + { (char *)"SUPERSCRIPT_X", BDF_INTEGER, 1, { 0 } }, + { (char *)"SUPERSCRIPT_Y", BDF_INTEGER, 1, { 0 } }, + { (char *)"UNDERLINE_POSITION", BDF_INTEGER, 1, { 0 } }, + { (char *)"UNDERLINE_THICKNESS", BDF_INTEGER, 1, { 0 } }, + { (char *)"WEIGHT", BDF_CARDINAL, 1, { 0 } }, + { (char *)"WEIGHT_NAME", BDF_ATOM, 1, { 0 } }, + { (char *)"X_HEIGHT", BDF_INTEGER, 1, { 0 } }, + { (char *)"_MULE_BASELINE_OFFSET", BDF_INTEGER, 1, { 0 } }, + { (char *)"_MULE_RELATIVE_COMPOSE", BDF_INTEGER, 1, { 0 } }, + }; + + static const unsigned long + _num_bdf_properties = sizeof ( _bdf_properties ) / + sizeof ( _bdf_properties[0] ); + + + /*************************************************************************/ + /* */ + /* Hash table utilities for the properties. */ + /* */ + /*************************************************************************/ + + /* XXX: Replace this with FreeType's hash functions */ + + +#define INITIAL_HT_SIZE 241 + + typedef void + (*hash_free_func)( hashnode node ); + + static hashnode* + hash_bucket( const char* key, + hashtable* ht ) + { + const char* kp = key; + unsigned long res = 0; + hashnode* bp = ht->table, *ndp; + + + /* Mocklisp hash function. */ + while ( *kp ) + res = ( res << 5 ) - res + *kp++; + + ndp = bp + ( res % ht->size ); + while ( *ndp ) + { + kp = (*ndp)->key; + if ( kp[0] == key[0] && ft_strcmp( kp, key ) == 0 ) + break; + ndp--; + if ( ndp < bp ) + ndp = bp + ( ht->size - 1 ); + } + + return ndp; + } + + + static FT_Error + hash_rehash( hashtable* ht, + FT_Memory memory ) + { + hashnode* obp = ht->table, *bp, *nbp; + int i, sz = ht->size; + FT_Error error = BDF_Err_Ok; + + + ht->size <<= 1; + ht->limit = ht->size / 3; + + if ( FT_NEW_ARRAY( ht->table, ht->size ) ) + goto Exit; + + for ( i = 0, bp = obp; i < sz; i++, bp++ ) + { + if ( *bp ) + { + nbp = hash_bucket( (*bp)->key, ht ); + *nbp = *bp; + } + } + FT_FREE( obp ); + + Exit: + return error; + } + + + static FT_Error + hash_init( hashtable* ht, + FT_Memory memory ) + { + int sz = INITIAL_HT_SIZE; + FT_Error error = BDF_Err_Ok; + + + ht->size = sz; + ht->limit = sz / 3; + ht->used = 0; + + if ( FT_NEW_ARRAY( ht->table, sz ) ) + goto Exit; + + Exit: + return error; + } + + + static void + hash_free( hashtable* ht, + FT_Memory memory ) + { + if ( ht != 0 ) + { + int i, sz = ht->size; + hashnode* bp = ht->table; + + + for ( i = 0; i < sz; i++, bp++ ) + FT_FREE( *bp ); + + FT_FREE( ht->table ); + } + } + + + static FT_Error + hash_insert( char* key, + size_t data, + hashtable* ht, + FT_Memory memory ) + { + hashnode nn, *bp = hash_bucket( key, ht ); + FT_Error error = BDF_Err_Ok; + + + nn = *bp; + if ( !nn ) + { + if ( FT_NEW( nn ) ) + goto Exit; + *bp = nn; + + nn->key = key; + nn->data = data; + + if ( ht->used >= ht->limit ) + { + error = hash_rehash( ht, memory ); + if ( error ) + goto Exit; + } + ht->used++; + } + else + nn->data = data; + + Exit: + return error; + } + + + static hashnode + hash_lookup( const char* key, + hashtable* ht ) + { + hashnode *np = hash_bucket( key, ht ); + + + return *np; + } + + + /*************************************************************************/ + /* */ + /* Utility types and functions. */ + /* */ + /*************************************************************************/ + + + /* Function type for parsing lines of a BDF font. */ + + typedef FT_Error + (*_bdf_line_func_t)( char* line, + unsigned long linelen, + unsigned long lineno, + void* call_data, + void* client_data ); + + + /* List structure for splitting lines into fields. */ + + typedef struct _bdf_list_t_ + { + char** field; + unsigned long size; + unsigned long used; + FT_Memory memory; + + } _bdf_list_t; + + + /* Structure used while loading BDF fonts. */ + + typedef struct _bdf_parse_t_ + { + unsigned long flags; + unsigned long cnt; + unsigned long row; + + short minlb; + short maxlb; + short maxrb; + short maxas; + short maxds; + + short rbearing; + + char* glyph_name; + long glyph_enc; + + bdf_font_t* font; + bdf_options_t* opts; + + unsigned long have[2048]; + _bdf_list_t list; + + FT_Memory memory; + + } _bdf_parse_t; + + +#define setsbit( m, cc ) \ + ( m[(FT_Byte)(cc) >> 3] |= (FT_Byte)( 1 << ( (cc) & 7 ) ) ) +#define sbitset( m, cc ) \ + ( m[(FT_Byte)(cc) >> 3] & ( 1 << ( (cc) & 7 ) ) ) + + + static void + _bdf_list_init( _bdf_list_t* list, + FT_Memory memory ) + { + FT_ZERO( list ); + list->memory = memory; + } + + + static void + _bdf_list_done( _bdf_list_t* list ) + { + FT_Memory memory = list->memory; + + + if ( memory ) + { + FT_FREE( list->field ); + FT_ZERO( list ); + } + } + + + static FT_Error + _bdf_list_ensure( _bdf_list_t* list, + unsigned long num_items ) /* same as _bdf_list_t.used */ + { + FT_Error error = BDF_Err_Ok; + + + if ( num_items > list->size ) + { + unsigned long oldsize = list->size; /* same as _bdf_list_t.size */ + unsigned long newsize = oldsize + ( oldsize >> 1 ) + 4; + unsigned long bigsize = (unsigned long)( FT_INT_MAX / sizeof ( char* ) ); + FT_Memory memory = list->memory; + + + if ( oldsize == bigsize ) + { + error = BDF_Err_Out_Of_Memory; + goto Exit; + } + else if ( newsize < oldsize || newsize > bigsize ) + newsize = bigsize; + + if ( FT_RENEW_ARRAY( list->field, oldsize, newsize ) ) + goto Exit; + + list->size = newsize; + } + + Exit: + return error; + } + + + static void + _bdf_list_shift( _bdf_list_t* list, + unsigned long n ) + { + unsigned long i, u; + + + if ( list == 0 || list->used == 0 || n == 0 ) + return; + + if ( n >= list->used ) + { + list->used = 0; + return; + } + + for ( u = n, i = 0; u < list->used; i++, u++ ) + list->field[i] = list->field[u]; + list->used -= n; + } + + + static char * + _bdf_list_join( _bdf_list_t* list, + int c, + unsigned long *alen ) + { + unsigned long i, j; + char *fp, *dp; + + + *alen = 0; + + if ( list == 0 || list->used == 0 ) + return 0; + + dp = list->field[0]; + for ( i = j = 0; i < list->used; i++ ) + { + fp = list->field[i]; + while ( *fp ) + dp[j++] = *fp++; + + if ( i + 1 < list->used ) + dp[j++] = (char)c; + } + dp[j] = 0; + + *alen = j; + return dp; + } + + + /* An empty string for empty fields. */ + + static const char empty[1] = { 0 }; /* XXX eliminate this */ + + + static FT_Error + _bdf_list_split( _bdf_list_t* list, + char* separators, + char* line, + unsigned long linelen ) + { + int mult, final_empty; + char *sp, *ep, *end; + char seps[32]; + FT_Error error = BDF_Err_Ok; + + + /* Initialize the list. */ + list->used = 0; + + /* If the line is empty, then simply return. */ + if ( linelen == 0 || line[0] == 0 ) + goto Exit; + + /* In the original code, if the `separators' parameter is NULL or */ + /* empty, the list is split into individual bytes. We don't need */ + /* this, so an error is signaled. */ + if ( separators == 0 || *separators == 0 ) + { + error = BDF_Err_Invalid_Argument; + goto Exit; + } + + /* Prepare the separator bitmap. */ + FT_MEM_ZERO( seps, 32 ); + + /* If the very last character of the separator string is a plus, then */ + /* set the `mult' flag to indicate that multiple separators should be */ + /* collapsed into one. */ + for ( mult = 0, sp = separators; sp && *sp; sp++ ) + { + if ( *sp == '+' && *( sp + 1 ) == 0 ) + mult = 1; + else + setsbit( seps, *sp ); + } + + /* Break the line up into fields. */ + for ( final_empty = 0, sp = ep = line, end = sp + linelen; + sp < end && *sp; ) + { + /* Collect everything that is not a separator. */ + for ( ; *ep && !sbitset( seps, *ep ); ep++ ) + ; + + /* Resize the list if necessary. */ + if ( list->used == list->size ) + { + error = _bdf_list_ensure( list, list->used + 1 ); + if ( error ) + goto Exit; + } + + /* Assign the field appropriately. */ + list->field[list->used++] = ( ep > sp ) ? sp : (char*)empty; + + sp = ep; + + if ( mult ) + { + /* If multiple separators should be collapsed, do it now by */ + /* setting all the separator characters to 0. */ + for ( ; *ep && sbitset( seps, *ep ); ep++ ) + *ep = 0; + } + else if ( *ep != 0 ) + /* Don't collapse multiple separators by making them 0, so just */ + /* make the one encountered 0. */ + *ep++ = 0; + + final_empty = ( ep > sp && *ep == 0 ); + sp = ep; + } + + /* Finally, NULL-terminate the list. */ + if ( list->used + final_empty >= list->size ) + { + error = _bdf_list_ensure( list, list->used + final_empty + 1 ); + if ( error ) + goto Exit; + } + + if ( final_empty ) + list->field[list->used++] = (char*)empty; + + list->field[list->used] = 0; + + Exit: + return error; + } + + +#define NO_SKIP 256 /* this value cannot be stored in a 'char' */ + + + static FT_Error + _bdf_readstream( FT_Stream stream, + _bdf_line_func_t callback, + void* client_data, + unsigned long *lno ) + { + _bdf_line_func_t cb; + unsigned long lineno, buf_size; + int refill, hold, to_skip; + ptrdiff_t bytes, start, end, cursor, avail; + char* buf = 0; + FT_Memory memory = stream->memory; + FT_Error error = BDF_Err_Ok; + + + if ( callback == 0 ) + { + error = BDF_Err_Invalid_Argument; + goto Exit; + } + + /* initial size and allocation of the input buffer */ + buf_size = 1024; + + if ( FT_NEW_ARRAY( buf, buf_size ) ) + goto Exit; + + cb = callback; + lineno = 1; + buf[0] = 0; + start = 0; + end = 0; + avail = 0; + cursor = 0; + refill = 1; + to_skip = NO_SKIP; + bytes = 0; /* make compiler happy */ + + for (;;) + { + if ( refill ) + { + bytes = (ptrdiff_t)FT_Stream_TryRead( stream, (FT_Byte*)buf + cursor, + (FT_ULong)(buf_size - cursor) ); + avail = cursor + bytes; + cursor = 0; + refill = 0; + } + + end = start; + + /* should we skip an optional character like \n or \r? */ + if ( start < avail && buf[start] == to_skip ) + { + start += 1; + to_skip = NO_SKIP; + continue; + } + + /* try to find the end of the line */ + while ( end < avail && buf[end] != '\n' && buf[end] != '\r' ) + end++; + + /* if we hit the end of the buffer, try shifting its content */ + /* or even resizing it */ + if ( end >= avail ) + { + if ( bytes == 0 ) /* last line in file doesn't end in \r or \n */ + break; /* ignore it then exit */ + + if ( start == 0 ) + { + /* this line is definitely too long; try resizing the input */ + /* buffer a bit to handle it. */ + FT_ULong new_size; + + + if ( buf_size >= 65536UL ) /* limit ourselves to 64KByte */ + { + error = BDF_Err_Invalid_Argument; + goto Exit; + } + + new_size = buf_size * 2; + if ( FT_RENEW_ARRAY( buf, buf_size, new_size ) ) + goto Exit; + + cursor = buf_size; + buf_size = new_size; + } + else + { + bytes = avail - start; + + FT_MEM_COPY( buf, buf + start, bytes ); + + cursor = bytes; + avail -= bytes; + start = 0; + } + refill = 1; + continue; + } + + /* Temporarily NUL-terminate the line. */ + hold = buf[end]; + buf[end] = 0; + + /* XXX: Use encoding independent value for 0x1a */ + if ( buf[start] != '#' && buf[start] != 0x1a && end > start ) + { + error = (*cb)( buf + start, end - start, lineno, + (void*)&cb, client_data ); + if ( error ) + break; + } + + lineno += 1; + buf[end] = (char)hold; + start = end + 1; + + if ( hold == '\n' ) + to_skip = '\r'; + else if ( hold == '\r' ) + to_skip = '\n'; + else + to_skip = NO_SKIP; + } + + *lno = lineno; + + Exit: + FT_FREE( buf ); + return error; + } + + + /* XXX: make this work with EBCDIC also */ + + static const unsigned char a2i[128] = + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + static const unsigned char odigits[32] = + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + + static const unsigned char ddigits[32] = + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + + static const unsigned char hdigits[32] = + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x03, + 0x7e, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + + +#define isdigok( m, d ) (m[(d) >> 3] & ( 1 << ( (d) & 7 ) ) ) + + + /* Routine to convert an ASCII string into an unsigned long integer. */ + static unsigned long + _bdf_atoul( char* s, + char** end, + int base ) + { + unsigned long v; + const unsigned char* dmap; + + + if ( s == 0 || *s == 0 ) + return 0; + + /* Make sure the radix is something recognizable. Default to 10. */ + switch ( base ) + { + case 8: + dmap = odigits; + break; + case 16: + dmap = hdigits; + break; + default: + base = 10; + dmap = ddigits; + break; + } + + /* Check for the special hex prefix. */ + if ( *s == '0' && + ( *( s + 1 ) == 'x' || *( s + 1 ) == 'X' ) ) + { + base = 16; + dmap = hdigits; + s += 2; + } + + for ( v = 0; isdigok( dmap, *s ); s++ ) + v = v * base + a2i[(int)*s]; + + if ( end != 0 ) + *end = s; + + return v; + } + + + /* Routine to convert an ASCII string into an signed long integer. */ + static long + _bdf_atol( char* s, + char** end, + int base ) + { + long v, neg; + const unsigned char* dmap; + + + if ( s == 0 || *s == 0 ) + return 0; + + /* Make sure the radix is something recognizable. Default to 10. */ + switch ( base ) + { + case 8: + dmap = odigits; + break; + case 16: + dmap = hdigits; + break; + default: + base = 10; + dmap = ddigits; + break; + } + + /* Check for a minus sign. */ + neg = 0; + if ( *s == '-' ) + { + s++; + neg = 1; + } + + /* Check for the special hex prefix. */ + if ( *s == '0' && + ( *( s + 1 ) == 'x' || *( s + 1 ) == 'X' ) ) + { + base = 16; + dmap = hdigits; + s += 2; + } + + for ( v = 0; isdigok( dmap, *s ); s++ ) + v = v * base + a2i[(int)*s]; + + if ( end != 0 ) + *end = s; + + return ( !neg ) ? v : -v; + } + + + /* Routine to convert an ASCII string into an signed short integer. */ + static short + _bdf_atos( char* s, + char** end, + int base ) + { + short v, neg; + const unsigned char* dmap; + + + if ( s == 0 || *s == 0 ) + return 0; + + /* Make sure the radix is something recognizable. Default to 10. */ + switch ( base ) + { + case 8: + dmap = odigits; + break; + case 16: + dmap = hdigits; + break; + default: + base = 10; + dmap = ddigits; + break; + } + + /* Check for a minus. */ + neg = 0; + if ( *s == '-' ) + { + s++; + neg = 1; + } + + /* Check for the special hex prefix. */ + if ( *s == '0' && + ( *( s + 1 ) == 'x' || *( s + 1 ) == 'X' ) ) + { + base = 16; + dmap = hdigits; + s += 2; + } + + for ( v = 0; isdigok( dmap, *s ); s++ ) + v = (short)( v * base + a2i[(int)*s] ); + + if ( end != 0 ) + *end = s; + + return (short)( ( !neg ) ? v : -v ); + } + + + /* Routine to compare two glyphs by encoding so they can be sorted. */ + static int + by_encoding( const void* a, + const void* b ) + { + bdf_glyph_t *c1, *c2; + + + c1 = (bdf_glyph_t *)a; + c2 = (bdf_glyph_t *)b; + + if ( c1->encoding < c2->encoding ) + return -1; + + if ( c1->encoding > c2->encoding ) + return 1; + + return 0; + } + + + static FT_Error + bdf_create_property( char* name, + int format, + bdf_font_t* font ) + { + size_t n; + bdf_property_t* p; + FT_Memory memory = font->memory; + FT_Error error = BDF_Err_Ok; + + + /* First check to see if the property has */ + /* already been added or not. If it has, then */ + /* simply ignore it. */ + if ( hash_lookup( name, &(font->proptbl) ) ) + goto Exit; + + if ( FT_RENEW_ARRAY( font->user_props, + font->nuser_props, + font->nuser_props + 1 ) ) + goto Exit; + + p = font->user_props + font->nuser_props; + FT_ZERO( p ); + + n = ft_strlen( name ) + 1; + if ( n > FT_ULONG_MAX ) + return BDF_Err_Invalid_Argument; + + if ( FT_NEW_ARRAY( p->name, n ) ) + goto Exit; + + FT_MEM_COPY( (char *)p->name, name, n ); + + p->format = format; + p->builtin = 0; + + n = _num_bdf_properties + font->nuser_props; + + error = hash_insert( p->name, n, &(font->proptbl), memory ); + if ( error ) + goto Exit; + + font->nuser_props++; + + Exit: + return error; + } + + + FT_LOCAL_DEF( bdf_property_t * ) + bdf_get_property( char* name, + bdf_font_t* font ) + { + hashnode hn; + size_t propid; + + + if ( name == 0 || *name == 0 ) + return 0; + + if ( ( hn = hash_lookup( name, &(font->proptbl) ) ) == 0 ) + return 0; + + propid = hn->data; + if ( propid >= _num_bdf_properties ) + return font->user_props + ( propid - _num_bdf_properties ); + + return (bdf_property_t*)_bdf_properties + propid; + } + + + /*************************************************************************/ + /* */ + /* BDF font file parsing flags and functions. */ + /* */ + /*************************************************************************/ + + + /* Parse flags. */ + +#define _BDF_START 0x0001 +#define _BDF_FONT_NAME 0x0002 +#define _BDF_SIZE 0x0004 +#define _BDF_FONT_BBX 0x0008 +#define _BDF_PROPS 0x0010 +#define _BDF_GLYPHS 0x0020 +#define _BDF_GLYPH 0x0040 +#define _BDF_ENCODING 0x0080 +#define _BDF_SWIDTH 0x0100 +#define _BDF_DWIDTH 0x0200 +#define _BDF_BBX 0x0400 +#define _BDF_BITMAP 0x0800 + +#define _BDF_SWIDTH_ADJ 0x1000 + +#define _BDF_GLYPH_BITS ( _BDF_GLYPH | \ + _BDF_ENCODING | \ + _BDF_SWIDTH | \ + _BDF_DWIDTH | \ + _BDF_BBX | \ + _BDF_BITMAP ) + +#define _BDF_GLYPH_WIDTH_CHECK 0x40000000UL +#define _BDF_GLYPH_HEIGHT_CHECK 0x80000000UL + + + /* Auto correction messages. */ +#define ACMSG1 "FONT_ASCENT property missing. " \ + "Added \"FONT_ASCENT %hd\".\n" +#define ACMSG2 "FONT_DESCENT property missing. " \ + "Added \"FONT_DESCENT %hd\".\n" +#define ACMSG3 "Font width != actual width. Old: %hd New: %hd.\n" +#define ACMSG4 "Font left bearing != actual left bearing. " \ + "Old: %hd New: %hd.\n" +#define ACMSG5 "Font ascent != actual ascent. Old: %hd New: %hd.\n" +#define ACMSG6 "Font descent != actual descent. Old: %hd New: %hd.\n" +#define ACMSG7 "Font height != actual height. Old: %hd New: %hd.\n" +#define ACMSG8 "Glyph scalable width (SWIDTH) adjustments made.\n" +#define ACMSG9 "SWIDTH field missing at line %ld. Set automatically.\n" +#define ACMSG10 "DWIDTH field missing at line %ld. Set to glyph width.\n" +#define ACMSG11 "SIZE bits per pixel field adjusted to %hd.\n" +#define ACMSG12 "Duplicate encoding %ld (%s) changed to unencoded.\n" +#define ACMSG13 "Glyph %ld extra rows removed.\n" +#define ACMSG14 "Glyph %ld extra columns removed.\n" +#define ACMSG15 "Incorrect glyph count: %ld indicated but %ld found.\n" + + /* Error messages. */ +#define ERRMSG1 "[line %ld] Missing \"%s\" line.\n" +#define ERRMSG2 "[line %ld] Font header corrupted or missing fields.\n" +#define ERRMSG3 "[line %ld] Font glyphs corrupted or missing fields.\n" +#define ERRMSG4 "[line %ld] BBX too big.\n" + + + static FT_Error + _bdf_add_comment( bdf_font_t* font, + char* comment, + unsigned long len ) + { + char* cp; + FT_Memory memory = font->memory; + FT_Error error = BDF_Err_Ok; + + + if ( FT_RENEW_ARRAY( font->comments, + font->comments_len, + font->comments_len + len + 1 ) ) + goto Exit; + + cp = font->comments + font->comments_len; + + FT_MEM_COPY( cp, comment, len ); + cp[len] = '\n'; + + font->comments_len += len + 1; + + Exit: + return error; + } + + + /* Set the spacing from the font name if it exists, or set it to the */ + /* default specified in the options. */ + static FT_Error + _bdf_set_default_spacing( bdf_font_t* font, + bdf_options_t* opts ) + { + size_t len; + char name[256]; + _bdf_list_t list; + FT_Memory memory; + FT_Error error = BDF_Err_Ok; + + + if ( font == 0 || font->name == 0 || font->name[0] == 0 ) + { + error = BDF_Err_Invalid_Argument; + goto Exit; + } + + memory = font->memory; + + _bdf_list_init( &list, memory ); + + font->spacing = opts->font_spacing; + + len = ft_strlen( font->name ) + 1; + /* Limit ourselves to 256 characters in the font name. */ + if ( len >= 256 ) + { + error = BDF_Err_Invalid_Argument; + goto Exit; + } + + FT_MEM_COPY( name, font->name, len ); + + error = _bdf_list_split( &list, (char *)"-", name, len ); + if ( error ) + goto Fail; + + if ( list.used == 15 ) + { + switch ( list.field[11][0] ) + { + case 'C': + case 'c': + font->spacing = BDF_CHARCELL; + break; + case 'M': + case 'm': + font->spacing = BDF_MONOWIDTH; + break; + case 'P': + case 'p': + font->spacing = BDF_PROPORTIONAL; + break; + } + } + + Fail: + _bdf_list_done( &list ); + + Exit: + return error; + } + + + /* Determine whether the property is an atom or not. If it is, then */ + /* clean it up so the double quotes are removed if they exist. */ + static int + _bdf_is_atom( char* line, + unsigned long linelen, + char** name, + char** value, + bdf_font_t* font ) + { + int hold; + char *sp, *ep; + bdf_property_t* p; + + + *name = sp = ep = line; + + while ( *ep && *ep != ' ' && *ep != '\t' ) + ep++; + + hold = -1; + if ( *ep ) + { + hold = *ep; + *ep = 0; + } + + p = bdf_get_property( sp, font ); + + /* Restore the character that was saved before any return can happen. */ + if ( hold != -1 ) + *ep = (char)hold; + + /* If the property exists and is not an atom, just return here. */ + if ( p && p->format != BDF_ATOM ) + return 0; + + /* The property is an atom. Trim all leading and trailing whitespace */ + /* and double quotes for the atom value. */ + sp = ep; + ep = line + linelen; + + /* Trim the leading whitespace if it exists. */ + *sp++ = 0; + while ( *sp && + ( *sp == ' ' || *sp == '\t' ) ) + sp++; + + /* Trim the leading double quote if it exists. */ + if ( *sp == '"' ) + sp++; + *value = sp; + + /* Trim the trailing whitespace if it exists. */ + while ( ep > sp && + ( *( ep - 1 ) == ' ' || *( ep - 1 ) == '\t' ) ) + *--ep = 0; + + /* Trim the trailing double quote if it exists. */ + if ( ep > sp && *( ep - 1 ) == '"' ) + *--ep = 0; + + return 1; + } + + + static FT_Error + _bdf_add_property( bdf_font_t* font, + char* name, + char* value ) + { + size_t propid; + hashnode hn; + bdf_property_t *prop, *fp; + FT_Memory memory = font->memory; + FT_Error error = BDF_Err_Ok; + + + /* First, check to see if the property already exists in the font. */ + if ( ( hn = hash_lookup( name, (hashtable *)font->internal ) ) != 0 ) + { + /* The property already exists in the font, so simply replace */ + /* the value of the property with the current value. */ + fp = font->props + hn->data; + + switch ( fp->format ) + { + case BDF_ATOM: + /* Delete the current atom if it exists. */ + FT_FREE( fp->value.atom ); + + if ( value && value[0] != 0 ) + { + if ( FT_STRDUP( fp->value.atom, value ) ) + goto Exit; + } + break; + + case BDF_INTEGER: + fp->value.l = _bdf_atol( value, 0, 10 ); + break; + + case BDF_CARDINAL: + fp->value.ul = _bdf_atoul( value, 0, 10 ); + break; + + default: + ; + } + + goto Exit; + } + + /* See whether this property type exists yet or not. */ + /* If not, create it. */ + hn = hash_lookup( name, &(font->proptbl) ); + if ( hn == 0 ) + { + error = bdf_create_property( name, BDF_ATOM, font ); + if ( error ) + goto Exit; + hn = hash_lookup( name, &(font->proptbl) ); + } + + /* Allocate another property if this is overflow. */ + if ( font->props_used == font->props_size ) + { + if ( font->props_size == 0 ) + { + if ( FT_NEW_ARRAY( font->props, 1 ) ) + goto Exit; + } + else + { + if ( FT_RENEW_ARRAY( font->props, + font->props_size, + font->props_size + 1 ) ) + goto Exit; + } + + fp = font->props + font->props_size; + FT_MEM_ZERO( fp, sizeof ( bdf_property_t ) ); + font->props_size++; + } + + propid = hn->data; + if ( propid >= _num_bdf_properties ) + prop = font->user_props + ( propid - _num_bdf_properties ); + else + prop = (bdf_property_t*)_bdf_properties + propid; + + fp = font->props + font->props_used; + + fp->name = prop->name; + fp->format = prop->format; + fp->builtin = prop->builtin; + + switch ( prop->format ) + { + case BDF_ATOM: + fp->value.atom = 0; + if ( value != 0 && value[0] ) + { + if ( FT_STRDUP( fp->value.atom, value ) ) + goto Exit; + } + break; + + case BDF_INTEGER: + fp->value.l = _bdf_atol( value, 0, 10 ); + break; + + case BDF_CARDINAL: + fp->value.ul = _bdf_atoul( value, 0, 10 ); + break; + } + + /* If the property happens to be a comment, then it doesn't need */ + /* to be added to the internal hash table. */ + if ( ft_memcmp( name, "COMMENT", 7 ) != 0 ) { + /* Add the property to the font property table. */ + error = hash_insert( fp->name, + font->props_used, + (hashtable *)font->internal, + memory ); + if ( error ) + goto Exit; + } + + font->props_used++; + + /* Some special cases need to be handled here. The DEFAULT_CHAR */ + /* property needs to be located if it exists in the property list, the */ + /* FONT_ASCENT and FONT_DESCENT need to be assigned if they are */ + /* present, and the SPACING property should override the default */ + /* spacing. */ + if ( ft_memcmp( name, "DEFAULT_CHAR", 12 ) == 0 ) + font->default_char = fp->value.l; + else if ( ft_memcmp( name, "FONT_ASCENT", 11 ) == 0 ) + font->font_ascent = fp->value.l; + else if ( ft_memcmp( name, "FONT_DESCENT", 12 ) == 0 ) + font->font_descent = fp->value.l; + else if ( ft_memcmp( name, "SPACING", 7 ) == 0 ) + { + if ( !fp->value.atom ) + { + error = BDF_Err_Invalid_File_Format; + goto Exit; + } + + if ( fp->value.atom[0] == 'p' || fp->value.atom[0] == 'P' ) + font->spacing = BDF_PROPORTIONAL; + else if ( fp->value.atom[0] == 'm' || fp->value.atom[0] == 'M' ) + font->spacing = BDF_MONOWIDTH; + else if ( fp->value.atom[0] == 'c' || fp->value.atom[0] == 'C' ) + font->spacing = BDF_CHARCELL; + } + + Exit: + return error; + } + + + static const unsigned char nibble_mask[8] = + { + 0xFF, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE + }; + + + /* Actually parse the glyph info and bitmaps. */ + static FT_Error + _bdf_parse_glyphs( char* line, + unsigned long linelen, + unsigned long lineno, + void* call_data, + void* client_data ) + { + int c, mask_index; + char* s; + unsigned char* bp; + unsigned long i, slen, nibbles; + + _bdf_parse_t* p; + bdf_glyph_t* glyph; + bdf_font_t* font; + + FT_Memory memory; + FT_Error error = BDF_Err_Ok; + + FT_UNUSED( call_data ); + FT_UNUSED( lineno ); /* only used in debug mode */ + + + p = (_bdf_parse_t *)client_data; + + font = p->font; + memory = font->memory; + + /* Check for a comment. */ + if ( ft_memcmp( line, "COMMENT", 7 ) == 0 ) + { + linelen -= 7; + + s = line + 7; + if ( *s != 0 ) + { + s++; + linelen--; + } + error = _bdf_add_comment( p->font, s, linelen ); + goto Exit; + } + + /* The very first thing expected is the number of glyphs. */ + if ( !( p->flags & _BDF_GLYPHS ) ) + { + if ( ft_memcmp( line, "CHARS", 5 ) != 0 ) + { + FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG1, lineno, "CHARS" )); + error = BDF_Err_Missing_Chars_Field; + goto Exit; + } + + error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); + if ( error ) + goto Exit; + p->cnt = font->glyphs_size = _bdf_atoul( p->list.field[1], 0, 10 ); + + /* Make sure the number of glyphs is non-zero. */ + if ( p->cnt == 0 ) + font->glyphs_size = 64; + + /* Limit ourselves to 1,114,112 glyphs in the font (this is the */ + /* number of code points available in Unicode). */ + if ( p->cnt >= 1114112UL ) + { + error = BDF_Err_Invalid_Argument; + goto Exit; + } + + if ( FT_NEW_ARRAY( font->glyphs, font->glyphs_size ) ) + goto Exit; + + p->flags |= _BDF_GLYPHS; + + goto Exit; + } + + /* Check for the ENDFONT field. */ + if ( ft_memcmp( line, "ENDFONT", 7 ) == 0 ) + { + /* Sort the glyphs by encoding. */ + ft_qsort( (char *)font->glyphs, + font->glyphs_used, + sizeof ( bdf_glyph_t ), + by_encoding ); + + p->flags &= ~_BDF_START; + + goto Exit; + } + + /* Check for the ENDCHAR field. */ + if ( ft_memcmp( line, "ENDCHAR", 7 ) == 0 ) + { + p->glyph_enc = 0; + p->flags &= ~_BDF_GLYPH_BITS; + + goto Exit; + } + + /* Check to see whether a glyph is being scanned but should be */ + /* ignored because it is an unencoded glyph. */ + if ( ( p->flags & _BDF_GLYPH ) && + p->glyph_enc == -1 && + p->opts->keep_unencoded == 0 ) + goto Exit; + + /* Check for the STARTCHAR field. */ + if ( ft_memcmp( line, "STARTCHAR", 9 ) == 0 ) + { + /* Set the character name in the parse info first until the */ + /* encoding can be checked for an unencoded character. */ + FT_FREE( p->glyph_name ); + + error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); + if ( error ) + goto Exit; + + _bdf_list_shift( &p->list, 1 ); + + s = _bdf_list_join( &p->list, ' ', &slen ); + + if ( !s ) + { + error = BDF_Err_Invalid_File_Format; + goto Exit; + } + + if ( FT_NEW_ARRAY( p->glyph_name, slen + 1 ) ) + goto Exit; + + FT_MEM_COPY( p->glyph_name, s, slen + 1 ); + + p->flags |= _BDF_GLYPH; + + goto Exit; + } + + /* Check for the ENCODING field. */ + if ( ft_memcmp( line, "ENCODING", 8 ) == 0 ) + { + if ( !( p->flags & _BDF_GLYPH ) ) + { + /* Missing STARTCHAR field. */ + FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG1, lineno, "STARTCHAR" )); + error = BDF_Err_Missing_Startchar_Field; + goto Exit; + } + + error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); + if ( error ) + goto Exit; + + p->glyph_enc = _bdf_atol( p->list.field[1], 0, 10 ); + + /* Check that the encoding is in the range [0,65536] because */ + /* otherwise p->have (a bitmap with static size) overflows. */ + if ( (size_t)p->glyph_enc >= sizeof ( p->have ) * 8 ) + { + error = BDF_Err_Invalid_File_Format; + goto Exit; + } + + /* Check to see whether this encoding has already been encountered. */ + /* If it has then change it to unencoded so it gets added if */ + /* indicated. */ + if ( p->glyph_enc >= 0 ) + { + if ( _bdf_glyph_modified( p->have, p->glyph_enc ) ) + { + /* Emit a message saying a glyph has been moved to the */ + /* unencoded area. */ + FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG12, + p->glyph_enc, p->glyph_name )); + p->glyph_enc = -1; + font->modified = 1; + } + else + _bdf_set_glyph_modified( p->have, p->glyph_enc ); + } + + if ( p->glyph_enc >= 0 ) + { + /* Make sure there are enough glyphs allocated in case the */ + /* number of characters happen to be wrong. */ + if ( font->glyphs_used == font->glyphs_size ) + { + if ( FT_RENEW_ARRAY( font->glyphs, + font->glyphs_size, + font->glyphs_size + 64 ) ) + goto Exit; + + font->glyphs_size += 64; + } + + glyph = font->glyphs + font->glyphs_used++; + glyph->name = p->glyph_name; + glyph->encoding = p->glyph_enc; + + /* Reset the initial glyph info. */ + p->glyph_name = 0; + } + else + { + /* Unencoded glyph. Check to see whether it should */ + /* be added or not. */ + if ( p->opts->keep_unencoded != 0 ) + { + /* Allocate the next unencoded glyph. */ + if ( font->unencoded_used == font->unencoded_size ) + { + if ( FT_RENEW_ARRAY( font->unencoded , + font->unencoded_size, + font->unencoded_size + 4 ) ) + goto Exit; + + font->unencoded_size += 4; + } + + glyph = font->unencoded + font->unencoded_used; + glyph->name = p->glyph_name; + glyph->encoding = font->unencoded_used++; + } + else + /* Free up the glyph name if the unencoded shouldn't be */ + /* kept. */ + FT_FREE( p->glyph_name ); + + p->glyph_name = 0; + } + + /* Clear the flags that might be added when width and height are */ + /* checked for consistency. */ + p->flags &= ~( _BDF_GLYPH_WIDTH_CHECK | _BDF_GLYPH_HEIGHT_CHECK ); + + p->flags |= _BDF_ENCODING; + + goto Exit; + } + + /* Point at the glyph being constructed. */ + if ( p->glyph_enc == -1 ) + glyph = font->unencoded + ( font->unencoded_used - 1 ); + else + glyph = font->glyphs + ( font->glyphs_used - 1 ); + + /* Check to see whether a bitmap is being constructed. */ + if ( p->flags & _BDF_BITMAP ) + { + /* If there are more rows than are specified in the glyph metrics, */ + /* ignore the remaining lines. */ + if ( p->row >= (unsigned long)glyph->bbx.height ) + { + if ( !( p->flags & _BDF_GLYPH_HEIGHT_CHECK ) ) + { + FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG13, glyph->encoding )); + p->flags |= _BDF_GLYPH_HEIGHT_CHECK; + font->modified = 1; + } + + goto Exit; + } + + /* Only collect the number of nibbles indicated by the glyph */ + /* metrics. If there are more columns, they are simply ignored. */ + nibbles = glyph->bpr << 1; + bp = glyph->bitmap + p->row * glyph->bpr; + + for ( i = 0; i < nibbles; i++ ) + { + c = line[i]; + *bp = (FT_Byte)( ( *bp << 4 ) + a2i[c] ); + if ( i + 1 < nibbles && ( i & 1 ) ) + *++bp = 0; + } + + /* Remove possible garbage at the right. */ + mask_index = ( glyph->bbx.width * p->font->bpp ) & 7; + if ( glyph->bbx.width ) + *bp &= nibble_mask[mask_index]; + + /* If any line has extra columns, indicate they have been removed. */ + if ( ( line[nibbles] == '0' || a2i[(int)line[nibbles]] != 0 ) && + !( p->flags & _BDF_GLYPH_WIDTH_CHECK ) ) + { + FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG14, glyph->encoding )); + p->flags |= _BDF_GLYPH_WIDTH_CHECK; + font->modified = 1; + } + + p->row++; + goto Exit; + } + + /* Expect the SWIDTH (scalable width) field next. */ + if ( ft_memcmp( line, "SWIDTH", 6 ) == 0 ) + { + if ( !( p->flags & _BDF_ENCODING ) ) + { + /* Missing ENCODING field. */ + FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG1, lineno, "ENCODING" )); + error = BDF_Err_Missing_Encoding_Field; + goto Exit; + } + + error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); + if ( error ) + goto Exit; + + glyph->swidth = (unsigned short)_bdf_atoul( p->list.field[1], 0, 10 ); + p->flags |= _BDF_SWIDTH; + + goto Exit; + } + + /* Expect the DWIDTH (scalable width) field next. */ + if ( ft_memcmp( line, "DWIDTH", 6 ) == 0 ) + { + error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); + if ( error ) + goto Exit; + + glyph->dwidth = (unsigned short)_bdf_atoul( p->list.field[1], 0, 10 ); + + if ( !( p->flags & _BDF_SWIDTH ) ) + { + /* Missing SWIDTH field. Emit an auto correction message and set */ + /* the scalable width from the device width. */ + FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG9, lineno )); + + glyph->swidth = (unsigned short)FT_MulDiv( + glyph->dwidth, 72000L, + (FT_Long)( font->point_size * + font->resolution_x ) ); + } + + p->flags |= _BDF_DWIDTH; + goto Exit; + } + + /* Expect the BBX field next. */ + if ( ft_memcmp( line, "BBX", 3 ) == 0 ) + { + error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); + if ( error ) + goto Exit; + + glyph->bbx.width = _bdf_atos( p->list.field[1], 0, 10 ); + glyph->bbx.height = _bdf_atos( p->list.field[2], 0, 10 ); + glyph->bbx.x_offset = _bdf_atos( p->list.field[3], 0, 10 ); + glyph->bbx.y_offset = _bdf_atos( p->list.field[4], 0, 10 ); + + /* Generate the ascent and descent of the character. */ + glyph->bbx.ascent = (short)( glyph->bbx.height + glyph->bbx.y_offset ); + glyph->bbx.descent = (short)( -glyph->bbx.y_offset ); + + /* Determine the overall font bounding box as the characters are */ + /* loaded so corrections can be done later if indicated. */ + p->maxas = (short)FT_MAX( glyph->bbx.ascent, p->maxas ); + p->maxds = (short)FT_MAX( glyph->bbx.descent, p->maxds ); + + p->rbearing = (short)( glyph->bbx.width + glyph->bbx.x_offset ); + + p->maxrb = (short)FT_MAX( p->rbearing, p->maxrb ); + p->minlb = (short)FT_MIN( glyph->bbx.x_offset, p->minlb ); + p->maxlb = (short)FT_MAX( glyph->bbx.x_offset, p->maxlb ); + + if ( !( p->flags & _BDF_DWIDTH ) ) + { + /* Missing DWIDTH field. Emit an auto correction message and set */ + /* the device width to the glyph width. */ + FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG10, lineno )); + glyph->dwidth = glyph->bbx.width; + } + + /* If the BDF_CORRECT_METRICS flag is set, then adjust the SWIDTH */ + /* value if necessary. */ + if ( p->opts->correct_metrics != 0 ) + { + /* Determine the point size of the glyph. */ + unsigned short sw = (unsigned short)FT_MulDiv( + glyph->dwidth, 72000L, + (FT_Long)( font->point_size * + font->resolution_x ) ); + + + if ( sw != glyph->swidth ) + { + glyph->swidth = sw; + + if ( p->glyph_enc == -1 ) + _bdf_set_glyph_modified( font->umod, + font->unencoded_used - 1 ); + else + _bdf_set_glyph_modified( font->nmod, glyph->encoding ); + + p->flags |= _BDF_SWIDTH_ADJ; + font->modified = 1; + } + } + + p->flags |= _BDF_BBX; + goto Exit; + } + + /* And finally, gather up the bitmap. */ + if ( ft_memcmp( line, "BITMAP", 6 ) == 0 ) + { + unsigned long bitmap_size; + + + if ( !( p->flags & _BDF_BBX ) ) + { + /* Missing BBX field. */ + FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG1, lineno, "BBX" )); + error = BDF_Err_Missing_Bbx_Field; + goto Exit; + } + + /* Allocate enough space for the bitmap. */ + glyph->bpr = ( glyph->bbx.width * p->font->bpp + 7 ) >> 3; + + bitmap_size = glyph->bpr * glyph->bbx.height; + if ( bitmap_size > 0xFFFFU ) + { + FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG4, lineno )); + error = BDF_Err_Bbx_Too_Big; + goto Exit; + } + else + glyph->bytes = (unsigned short)bitmap_size; + + if ( FT_NEW_ARRAY( glyph->bitmap, glyph->bytes ) ) + goto Exit; + + p->row = 0; + p->flags |= _BDF_BITMAP; + + goto Exit; + } + + error = BDF_Err_Invalid_File_Format; + + Exit: + return error; + } + + + /* Load the font properties. */ + static FT_Error + _bdf_parse_properties( char* line, + unsigned long linelen, + unsigned long lineno, + void* call_data, + void* client_data ) + { + unsigned long vlen; + _bdf_line_func_t* next; + _bdf_parse_t* p; + char* name; + char* value; + char nbuf[128]; + FT_Error error = BDF_Err_Ok; + + FT_UNUSED( lineno ); + + + next = (_bdf_line_func_t *)call_data; + p = (_bdf_parse_t *) client_data; + + /* Check for the end of the properties. */ + if ( ft_memcmp( line, "ENDPROPERTIES", 13 ) == 0 ) + { + /* If the FONT_ASCENT or FONT_DESCENT properties have not been */ + /* encountered yet, then make sure they are added as properties and */ + /* make sure they are set from the font bounding box info. */ + /* */ + /* This is *always* done regardless of the options, because X11 */ + /* requires these two fields to compile fonts. */ + if ( bdf_get_font_property( p->font, "FONT_ASCENT" ) == 0 ) + { + p->font->font_ascent = p->font->bbx.ascent; + ft_sprintf( nbuf, "%hd", p->font->bbx.ascent ); + error = _bdf_add_property( p->font, (char *)"FONT_ASCENT", nbuf ); + if ( error ) + goto Exit; + + FT_TRACE2(( "_bdf_parse_properties: " ACMSG1, p->font->bbx.ascent )); + p->font->modified = 1; + } + + if ( bdf_get_font_property( p->font, "FONT_DESCENT" ) == 0 ) + { + p->font->font_descent = p->font->bbx.descent; + ft_sprintf( nbuf, "%hd", p->font->bbx.descent ); + error = _bdf_add_property( p->font, (char *)"FONT_DESCENT", nbuf ); + if ( error ) + goto Exit; + + FT_TRACE2(( "_bdf_parse_properties: " ACMSG2, p->font->bbx.descent )); + p->font->modified = 1; + } + + p->flags &= ~_BDF_PROPS; + *next = _bdf_parse_glyphs; + + goto Exit; + } + + /* Ignore the _XFREE86_GLYPH_RANGES properties. */ + if ( ft_memcmp( line, "_XFREE86_GLYPH_RANGES", 21 ) == 0 ) + goto Exit; + + /* Handle COMMENT fields and properties in a special way to preserve */ + /* the spacing. */ + if ( ft_memcmp( line, "COMMENT", 7 ) == 0 ) + { + name = value = line; + value += 7; + if ( *value ) + *value++ = 0; + error = _bdf_add_property( p->font, name, value ); + if ( error ) + goto Exit; + } + else if ( _bdf_is_atom( line, linelen, &name, &value, p->font ) ) + { + error = _bdf_add_property( p->font, name, value ); + if ( error ) + goto Exit; + } + else + { + error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); + if ( error ) + goto Exit; + name = p->list.field[0]; + + _bdf_list_shift( &p->list, 1 ); + value = _bdf_list_join( &p->list, ' ', &vlen ); + + error = _bdf_add_property( p->font, name, value ); + if ( error ) + goto Exit; + } + + Exit: + return error; + } + + + /* Load the font header. */ + static FT_Error + _bdf_parse_start( char* line, + unsigned long linelen, + unsigned long lineno, + void* call_data, + void* client_data ) + { + unsigned long slen; + _bdf_line_func_t* next; + _bdf_parse_t* p; + bdf_font_t* font; + char *s; + + FT_Memory memory = NULL; + FT_Error error = BDF_Err_Ok; + + FT_UNUSED( lineno ); /* only used in debug mode */ + + + next = (_bdf_line_func_t *)call_data; + p = (_bdf_parse_t *) client_data; + + if ( p->font ) + memory = p->font->memory; + + /* Check for a comment. This is done to handle those fonts that have */ + /* comments before the STARTFONT line for some reason. */ + if ( ft_memcmp( line, "COMMENT", 7 ) == 0 ) + { + if ( p->opts->keep_comments != 0 && p->font != 0 ) + { + linelen -= 7; + + s = line + 7; + if ( *s != 0 ) + { + s++; + linelen--; + } + + error = _bdf_add_comment( p->font, s, linelen ); + if ( error ) + goto Exit; + /* here font is not defined! */ + } + + goto Exit; + } + + if ( !( p->flags & _BDF_START ) ) + { + memory = p->memory; + + if ( ft_memcmp( line, "STARTFONT", 9 ) != 0 ) + { + /* No STARTFONT field is a good indication of a problem. */ + error = BDF_Err_Missing_Startfont_Field; + goto Exit; + } + + p->flags = _BDF_START; + font = p->font = 0; + + if ( FT_NEW( font ) ) + goto Exit; + p->font = font; + + font->memory = p->memory; + p->memory = 0; + + { /* setup */ + size_t i; + bdf_property_t* prop; + + + error = hash_init( &(font->proptbl), memory ); + if ( error ) + goto Exit; + for ( i = 0, prop = (bdf_property_t*)_bdf_properties; + i < _num_bdf_properties; i++, prop++ ) + { + error = hash_insert( prop->name, i, + &(font->proptbl), memory ); + if ( error ) + goto Exit; + } + } + + if ( FT_ALLOC( p->font->internal, sizeof ( hashtable ) ) ) + goto Exit; + error = hash_init( (hashtable *)p->font->internal,memory ); + if ( error ) + goto Exit; + p->font->spacing = p->opts->font_spacing; + p->font->default_char = -1; + + goto Exit; + } + + /* Check for the start of the properties. */ + if ( ft_memcmp( line, "STARTPROPERTIES", 15 ) == 0 ) + { + error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); + if ( error ) + goto Exit; + /* at this point, `p->font' can't be NULL */ + p->cnt = p->font->props_size = _bdf_atoul( p->list.field[1], 0, 10 ); + + if ( FT_NEW_ARRAY( p->font->props, p->cnt ) ) + goto Exit; + + p->flags |= _BDF_PROPS; + *next = _bdf_parse_properties; + + goto Exit; + } + + /* Check for the FONTBOUNDINGBOX field. */ + if ( ft_memcmp( line, "FONTBOUNDINGBOX", 15 ) == 0 ) + { + if ( !(p->flags & _BDF_SIZE ) ) + { + /* Missing the SIZE field. */ + FT_ERROR(( "_bdf_parse_start: " ERRMSG1, lineno, "SIZE" )); + error = BDF_Err_Missing_Size_Field; + goto Exit; + } + + error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); + if ( error ) + goto Exit; + + p->font->bbx.width = _bdf_atos( p->list.field[1], 0, 10 ); + p->font->bbx.height = _bdf_atos( p->list.field[2], 0, 10 ); + + p->font->bbx.x_offset = _bdf_atos( p->list.field[3], 0, 10 ); + p->font->bbx.y_offset = _bdf_atos( p->list.field[4], 0, 10 ); + + p->font->bbx.ascent = (short)( p->font->bbx.height + + p->font->bbx.y_offset ); + + p->font->bbx.descent = (short)( -p->font->bbx.y_offset ); + + p->flags |= _BDF_FONT_BBX; + + goto Exit; + } + + /* The next thing to check for is the FONT field. */ + if ( ft_memcmp( line, "FONT", 4 ) == 0 ) + { + error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); + if ( error ) + goto Exit; + _bdf_list_shift( &p->list, 1 ); + + s = _bdf_list_join( &p->list, ' ', &slen ); + + if ( !s ) + { + error = BDF_Err_Invalid_File_Format; + goto Exit; + } + + if ( FT_NEW_ARRAY( p->font->name, slen + 1 ) ) + goto Exit; + FT_MEM_COPY( p->font->name, s, slen + 1 ); + + /* If the font name is an XLFD name, set the spacing to the one in */ + /* the font name. If there is no spacing fall back on the default. */ + error = _bdf_set_default_spacing( p->font, p->opts ); + if ( error ) + goto Exit; + + p->flags |= _BDF_FONT_NAME; + + goto Exit; + } + + /* Check for the SIZE field. */ + if ( ft_memcmp( line, "SIZE", 4 ) == 0 ) + { + if ( !( p->flags & _BDF_FONT_NAME ) ) + { + /* Missing the FONT field. */ + FT_ERROR(( "_bdf_parse_start: " ERRMSG1, lineno, "FONT" )); + error = BDF_Err_Missing_Font_Field; + goto Exit; + } + + error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); + if ( error ) + goto Exit; + + p->font->point_size = _bdf_atoul( p->list.field[1], 0, 10 ); + p->font->resolution_x = _bdf_atoul( p->list.field[2], 0, 10 ); + p->font->resolution_y = _bdf_atoul( p->list.field[3], 0, 10 ); + + /* Check for the bits per pixel field. */ + if ( p->list.used == 5 ) + { + unsigned short bitcount, i, shift; + + + p->font->bpp = (unsigned short)_bdf_atos( p->list.field[4], 0, 10 ); + + /* Only values 1, 2, 4, 8 are allowed. */ + shift = p->font->bpp; + bitcount = 0; + for ( i = 0; shift > 0; i++ ) + { + if ( shift & 1 ) + bitcount = i; + shift >>= 1; + } + + shift = (short)( ( bitcount > 3 ) ? 8 : ( 1 << bitcount ) ); + + if ( p->font->bpp > shift || p->font->bpp != shift ) + { + /* select next higher value */ + p->font->bpp = (unsigned short)( shift << 1 ); + FT_TRACE2(( "_bdf_parse_start: " ACMSG11, p->font->bpp )); + } + } + else + p->font->bpp = 1; + + p->flags |= _BDF_SIZE; + + goto Exit; + } + + error = BDF_Err_Invalid_File_Format; + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* API. */ + /* */ + /*************************************************************************/ + + + FT_LOCAL_DEF( FT_Error ) + bdf_load_font( FT_Stream stream, + FT_Memory extmemory, + bdf_options_t* opts, + bdf_font_t* *font ) + { + unsigned long lineno = 0; /* make compiler happy */ + _bdf_parse_t *p; + + FT_Memory memory = extmemory; + FT_Error error = BDF_Err_Ok; + + + if ( FT_NEW( p ) ) + goto Exit; + + memory = NULL; + p->opts = (bdf_options_t*)( ( opts != 0 ) ? opts : &_bdf_opts ); + p->minlb = 32767; + p->memory = extmemory; /* only during font creation */ + + _bdf_list_init( &p->list, extmemory ); + + error = _bdf_readstream( stream, _bdf_parse_start, + (void *)p, &lineno ); + if ( error ) + goto Fail; + + if ( p->font != 0 ) + { + /* If the font is not proportional, set the font's monowidth */ + /* field to the width of the font bounding box. */ + memory = p->font->memory; + + if ( p->font->spacing != BDF_PROPORTIONAL ) + p->font->monowidth = p->font->bbx.width; + + /* If the number of glyphs loaded is not that of the original count, */ + /* indicate the difference. */ + if ( p->cnt != p->font->glyphs_used + p->font->unencoded_used ) + { + FT_TRACE2(( "bdf_load_font: " ACMSG15, p->cnt, + p->font->glyphs_used + p->font->unencoded_used )); + p->font->modified = 1; + } + + /* Once the font has been loaded, adjust the overall font metrics if */ + /* necessary. */ + if ( p->opts->correct_metrics != 0 && + ( p->font->glyphs_used > 0 || p->font->unencoded_used > 0 ) ) + { + if ( p->maxrb - p->minlb != p->font->bbx.width ) + { + FT_TRACE2(( "bdf_load_font: " ACMSG3, + p->font->bbx.width, p->maxrb - p->minlb )); + p->font->bbx.width = (unsigned short)( p->maxrb - p->minlb ); + p->font->modified = 1; + } + + if ( p->font->bbx.x_offset != p->minlb ) + { + FT_TRACE2(( "bdf_load_font: " ACMSG4, + p->font->bbx.x_offset, p->minlb )); + p->font->bbx.x_offset = p->minlb; + p->font->modified = 1; + } + + if ( p->font->bbx.ascent != p->maxas ) + { + FT_TRACE2(( "bdf_load_font: " ACMSG5, + p->font->bbx.ascent, p->maxas )); + p->font->bbx.ascent = p->maxas; + p->font->modified = 1; + } + + if ( p->font->bbx.descent != p->maxds ) + { + FT_TRACE2(( "bdf_load_font: " ACMSG6, + p->font->bbx.descent, p->maxds )); + p->font->bbx.descent = p->maxds; + p->font->bbx.y_offset = (short)( -p->maxds ); + p->font->modified = 1; + } + + if ( p->maxas + p->maxds != p->font->bbx.height ) + { + FT_TRACE2(( "bdf_load_font: " ACMSG7, + p->font->bbx.height, p->maxas + p->maxds )); + p->font->bbx.height = (unsigned short)( p->maxas + p->maxds ); + } + + if ( p->flags & _BDF_SWIDTH_ADJ ) + FT_TRACE2(( "bdf_load_font: " ACMSG8 )); + } + } + + if ( p->flags & _BDF_START ) + { + { + /* The ENDFONT field was never reached or did not exist. */ + if ( !( p->flags & _BDF_GLYPHS ) ) + { + /* Error happened while parsing header. */ + FT_ERROR(( "bdf_load_font: " ERRMSG2, lineno )); + error = BDF_Err_Corrupted_Font_Header; + goto Exit; + } + else + { + /* Error happened when parsing glyphs. */ + FT_ERROR(( "bdf_load_font: " ERRMSG3, lineno )); + error = BDF_Err_Corrupted_Font_Glyphs; + goto Exit; + } + } + } + + if ( p->font != 0 ) + { + /* Make sure the comments are NULL terminated if they exist. */ + memory = p->font->memory; + + if ( p->font->comments_len > 0 ) { + if ( FT_RENEW_ARRAY( p->font->comments, + p->font->comments_len, + p->font->comments_len + 1 ) ) + goto Fail; + + p->font->comments[p->font->comments_len] = 0; + } + } + else if ( error == BDF_Err_Ok ) + error = BDF_Err_Invalid_File_Format; + + *font = p->font; + + Exit: + if ( p ) + { + _bdf_list_done( &p->list ); + + memory = extmemory; + + FT_FREE( p ); + } + + return error; + + Fail: + bdf_free_font( p->font ); + + memory = extmemory; + + FT_FREE( p->font ); + + goto Exit; + } + + + FT_LOCAL_DEF( void ) + bdf_free_font( bdf_font_t* font ) + { + bdf_property_t* prop; + unsigned long i; + bdf_glyph_t* glyphs; + FT_Memory memory; + + + if ( font == 0 ) + return; + + memory = font->memory; + + FT_FREE( font->name ); + + /* Free up the internal hash table of property names. */ + if ( font->internal ) + { + hash_free( (hashtable *)font->internal, memory ); + FT_FREE( font->internal ); + } + + /* Free up the comment info. */ + FT_FREE( font->comments ); + + /* Free up the properties. */ + for ( i = 0; i < font->props_size; i++ ) + { + if ( font->props[i].format == BDF_ATOM ) + FT_FREE( font->props[i].value.atom ); + } + + FT_FREE( font->props ); + + /* Free up the character info. */ + for ( i = 0, glyphs = font->glyphs; + i < font->glyphs_used; i++, glyphs++ ) + { + FT_FREE( glyphs->name ); + FT_FREE( glyphs->bitmap ); + } + + for ( i = 0, glyphs = font->unencoded; i < font->unencoded_used; + i++, glyphs++ ) + { + FT_FREE( glyphs->name ); + FT_FREE( glyphs->bitmap ); + } + + FT_FREE( font->glyphs ); + FT_FREE( font->unencoded ); + + /* Free up the overflow storage if it was used. */ + for ( i = 0, glyphs = font->overflow.glyphs; + i < font->overflow.glyphs_used; i++, glyphs++ ) + { + FT_FREE( glyphs->name ); + FT_FREE( glyphs->bitmap ); + } + + FT_FREE( font->overflow.glyphs ); + + /* bdf_cleanup */ + hash_free( &(font->proptbl), memory ); + + /* Free up the user defined properties. */ + for (prop = font->user_props, i = 0; + i < font->nuser_props; i++, prop++ ) + { + FT_FREE( prop->name ); + if ( prop->format == BDF_ATOM ) + FT_FREE( prop->value.atom ); + } + + FT_FREE( font->user_props ); + + /* FREE( font ); */ /* XXX Fixme */ + } + + + FT_LOCAL_DEF( bdf_property_t * ) + bdf_get_font_property( bdf_font_t* font, + const char* name ) + { + hashnode hn; + + + if ( font == 0 || font->props_size == 0 || name == 0 || *name == 0 ) + return 0; + + hn = hash_lookup( name, (hashtable *)font->internal ); + + return hn ? ( font->props + hn->data ) : 0; + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/cache/ftcache.c b/mod/pub.mod/freetype.mod/src/cache/ftcache.c new file mode 100644 index 0000000..d41e91e --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/cache/ftcache.c @@ -0,0 +1,31 @@ +/***************************************************************************/ +/* */ +/* ftcache.c */ +/* */ +/* The FreeType Caching sub-system (body only). */ +/* */ +/* Copyright 2000-2001, 2003 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#define FT_MAKE_OPTION_SINGLE_OBJECT + +#include <ft2build.h> +#include "ftcmru.c" +#include "ftcmanag.c" +#include "ftccache.c" +#include "ftccmap.c" +#include "ftcglyph.c" +#include "ftcimage.c" +#include "ftcsbits.c" +#include "ftcbasic.c" + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/cache/ftcbasic.c b/mod/pub.mod/freetype.mod/src/cache/ftcbasic.c new file mode 100644 index 0000000..ebc8871 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/cache/ftcbasic.c @@ -0,0 +1,851 @@ +/***************************************************************************/ +/* */ +/* ftcbasic.c */ +/* */ +/* The FreeType basic cache interface (body). */ +/* */ +/* Copyright 2003, 2004, 2005, 2006, 2007, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_CACHE_H +#include "ftcglyph.h" +#include "ftcimage.h" +#include "ftcsbits.h" + +#include "ftccback.h" +#include "ftcerror.h" + +#define FT_COMPONENT trace_cache + + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + + /* + * These structures correspond to the FTC_Font and FTC_ImageDesc types + * that were defined in version 2.1.7. + */ + typedef struct FTC_OldFontRec_ + { + FTC_FaceID face_id; + FT_UShort pix_width; + FT_UShort pix_height; + + } FTC_OldFontRec, *FTC_OldFont; + + + typedef struct FTC_OldImageDescRec_ + { + FTC_OldFontRec font; + FT_UInt32 flags; + + } FTC_OldImageDescRec, *FTC_OldImageDesc; + + + /* + * Notice that FTC_OldImageDescRec and FTC_ImageTypeRec are nearly + * identical, bit-wise. The only difference is that the `width' and + * `height' fields are expressed as 16-bit integers in the old structure, + * and as normal `int' in the new one. + * + * We are going to perform a weird hack to detect which structure is + * being passed to the image and sbit caches. If the new structure's + * `width' is larger than 0x10000, we assume that we are really receiving + * an FTC_OldImageDesc. + */ + +#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */ + + + /* + * Basic Families + * + */ + typedef struct FTC_BasicAttrRec_ + { + FTC_ScalerRec scaler; + FT_UInt load_flags; + + } FTC_BasicAttrRec, *FTC_BasicAttrs; + +#define FTC_BASIC_ATTR_COMPARE( a, b ) \ + FT_BOOL( FTC_SCALER_COMPARE( &(a)->scaler, &(b)->scaler ) && \ + (a)->load_flags == (b)->load_flags ) + +#define FTC_BASIC_ATTR_HASH( a ) \ + ( FTC_SCALER_HASH( &(a)->scaler ) + 31*(a)->load_flags ) + + + typedef struct FTC_BasicQueryRec_ + { + FTC_GQueryRec gquery; + FTC_BasicAttrRec attrs; + + } FTC_BasicQueryRec, *FTC_BasicQuery; + + + typedef struct FTC_BasicFamilyRec_ + { + FTC_FamilyRec family; + FTC_BasicAttrRec attrs; + + } FTC_BasicFamilyRec, *FTC_BasicFamily; + + + FT_CALLBACK_DEF( FT_Bool ) + ftc_basic_family_compare( FTC_MruNode ftcfamily, + FT_Pointer ftcquery ) + { + FTC_BasicFamily family = (FTC_BasicFamily)ftcfamily; + FTC_BasicQuery query = (FTC_BasicQuery)ftcquery; + + + return FTC_BASIC_ATTR_COMPARE( &family->attrs, &query->attrs ); + } + + + FT_CALLBACK_DEF( FT_Error ) + ftc_basic_family_init( FTC_MruNode ftcfamily, + FT_Pointer ftcquery, + FT_Pointer ftccache ) + { + FTC_BasicFamily family = (FTC_BasicFamily)ftcfamily; + FTC_BasicQuery query = (FTC_BasicQuery)ftcquery; + FTC_Cache cache = (FTC_Cache)ftccache; + + + FTC_Family_Init( FTC_FAMILY( family ), cache ); + family->attrs = query->attrs; + return 0; + } + + + FT_CALLBACK_DEF( FT_UInt ) + ftc_basic_family_get_count( FTC_Family ftcfamily, + FTC_Manager manager ) + { + FTC_BasicFamily family = (FTC_BasicFamily)ftcfamily; + FT_Error error; + FT_Face face; + FT_UInt result = 0; + + + error = FTC_Manager_LookupFace( manager, family->attrs.scaler.face_id, + &face ); + + if ( error || !face ) + return result; + + if ( (FT_ULong)face->num_glyphs > FT_UINT_MAX || 0 > face->num_glyphs ) + { + FT_TRACE1(( "ftc_basic_family_get_count: too large number of glyphs " )); + FT_TRACE1(( "in this face, truncated\n", face->num_glyphs )); + } + + if ( !error ) + result = (FT_UInt)face->num_glyphs; + + return result; + } + + + FT_CALLBACK_DEF( FT_Error ) + ftc_basic_family_load_bitmap( FTC_Family ftcfamily, + FT_UInt gindex, + FTC_Manager manager, + FT_Face *aface ) + { + FTC_BasicFamily family = (FTC_BasicFamily)ftcfamily; + FT_Error error; + FT_Size size; + + + error = FTC_Manager_LookupSize( manager, &family->attrs.scaler, &size ); + if ( !error ) + { + FT_Face face = size->face; + + + error = FT_Load_Glyph( face, gindex, + family->attrs.load_flags | FT_LOAD_RENDER ); + if ( !error ) + *aface = face; + } + + return error; + } + + + FT_CALLBACK_DEF( FT_Error ) + ftc_basic_family_load_glyph( FTC_Family ftcfamily, + FT_UInt gindex, + FTC_Cache cache, + FT_Glyph *aglyph ) + { + FTC_BasicFamily family = (FTC_BasicFamily)ftcfamily; + FT_Error error; + FTC_Scaler scaler = &family->attrs.scaler; + FT_Face face; + FT_Size size; + + + /* we will now load the glyph image */ + error = FTC_Manager_LookupSize( cache->manager, + scaler, + &size ); + if ( !error ) + { + face = size->face; + + error = FT_Load_Glyph( face, gindex, family->attrs.load_flags ); + if ( !error ) + { + if ( face->glyph->format == FT_GLYPH_FORMAT_BITMAP || + face->glyph->format == FT_GLYPH_FORMAT_OUTLINE ) + { + /* ok, copy it */ + FT_Glyph glyph; + + + error = FT_Get_Glyph( face->glyph, &glyph ); + if ( !error ) + { + *aglyph = glyph; + goto Exit; + } + } + else + error = FTC_Err_Invalid_Argument; + } + } + + Exit: + return error; + } + + + FT_CALLBACK_DEF( FT_Bool ) + ftc_basic_gnode_compare_faceid( FTC_Node ftcgnode, + FT_Pointer ftcface_id, + FTC_Cache cache ) + { + FTC_GNode gnode = (FTC_GNode)ftcgnode; + FTC_FaceID face_id = (FTC_FaceID)ftcface_id; + FTC_BasicFamily family = (FTC_BasicFamily)gnode->family; + FT_Bool result; + + + result = FT_BOOL( family->attrs.scaler.face_id == face_id ); + if ( result ) + { + /* we must call this function to avoid this node from appearing + * in later lookups with the same face_id! + */ + FTC_GNode_UnselectFamily( gnode, cache ); + } + return result; + } + + + /* + * + * basic image cache + * + */ + + FT_CALLBACK_TABLE_DEF + const FTC_IFamilyClassRec ftc_basic_image_family_class = + { + { + sizeof ( FTC_BasicFamilyRec ), + ftc_basic_family_compare, + ftc_basic_family_init, + 0, /* FTC_MruNode_ResetFunc */ + 0 /* FTC_MruNode_DoneFunc */ + }, + ftc_basic_family_load_glyph + }; + + + FT_CALLBACK_TABLE_DEF + const FTC_GCacheClassRec ftc_basic_image_cache_class = + { + { + ftc_inode_new, + ftc_inode_weight, + ftc_gnode_compare, + ftc_basic_gnode_compare_faceid, + ftc_inode_free, + + sizeof ( FTC_GCacheRec ), + ftc_gcache_init, + ftc_gcache_done + }, + (FTC_MruListClass)&ftc_basic_image_family_class + }; + + + /* documentation is in ftcache.h */ + + FT_EXPORT_DEF( FT_Error ) + FTC_ImageCache_New( FTC_Manager manager, + FTC_ImageCache *acache ) + { + return FTC_GCache_New( manager, &ftc_basic_image_cache_class, + (FTC_GCache*)acache ); + } + + + /* documentation is in ftcache.h */ + + FT_EXPORT_DEF( FT_Error ) + FTC_ImageCache_Lookup( FTC_ImageCache cache, + FTC_ImageType type, + FT_UInt gindex, + FT_Glyph *aglyph, + FTC_Node *anode ) + { + FTC_BasicQueryRec query; + FTC_Node node = 0; /* make compiler happy */ + FT_Error error; + FT_UInt32 hash; + + + /* some argument checks are delayed to FTC_Cache_Lookup */ + if ( !aglyph ) + { + error = FTC_Err_Invalid_Argument; + goto Exit; + } + + *aglyph = NULL; + if ( anode ) + *anode = NULL; + +#if defined( FT_CONFIG_OPTION_OLD_INTERNALS ) && ( FT_INT_MAX > 0xFFFFU ) + + /* + * This one is a major hack used to detect whether we are passed a + * regular FTC_ImageType handle, or a legacy FTC_OldImageDesc one. + */ + if ( (FT_ULong)type->width >= 0x10000L ) + { + FTC_OldImageDesc desc = (FTC_OldImageDesc)type; + + + query.attrs.scaler.face_id = desc->font.face_id; + query.attrs.scaler.width = desc->font.pix_width; + query.attrs.scaler.height = desc->font.pix_height; + query.attrs.load_flags = desc->flags; + } + else + +#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */ + + { + if ( (FT_ULong)(type->flags - FT_INT_MIN) > FT_UINT_MAX ) + { + FT_TRACE1(( "FTC_ImageCache_Lookup: higher bits in load_flags" )); + FT_TRACE1(( "0x%x are dropped\n", (type->flags & ~((FT_ULong)FT_UINT_MAX)) )); + } + + query.attrs.scaler.face_id = type->face_id; + query.attrs.scaler.width = type->width; + query.attrs.scaler.height = type->height; + query.attrs.load_flags = (FT_UInt)type->flags; + } + + query.attrs.scaler.pixel = 1; + query.attrs.scaler.x_res = 0; /* make compilers happy */ + query.attrs.scaler.y_res = 0; + + hash = FTC_BASIC_ATTR_HASH( &query.attrs ) + gindex; + +#if 1 /* inlining is about 50% faster! */ + FTC_GCACHE_LOOKUP_CMP( cache, + ftc_basic_family_compare, + FTC_GNode_Compare, + hash, gindex, + &query, + node, + error ); +#else + error = FTC_GCache_Lookup( FTC_GCACHE( cache ), + hash, gindex, + FTC_GQUERY( &query ), + &node ); +#endif + if ( !error ) + { + *aglyph = FTC_INODE( node )->glyph; + + if ( anode ) + { + *anode = node; + node->ref_count++; + } + } + + Exit: + return error; + } + + + /* documentation is in ftcache.h */ + + FT_EXPORT_DEF( FT_Error ) + FTC_ImageCache_LookupScaler( FTC_ImageCache cache, + FTC_Scaler scaler, + FT_ULong load_flags, + FT_UInt gindex, + FT_Glyph *aglyph, + FTC_Node *anode ) + { + FTC_BasicQueryRec query; + FTC_Node node = 0; /* make compiler happy */ + FT_Error error; + FT_UInt32 hash; + + + /* some argument checks are delayed to FTC_Cache_Lookup */ + if ( !aglyph || !scaler ) + { + error = FTC_Err_Invalid_Argument; + goto Exit; + } + + *aglyph = NULL; + if ( anode ) + *anode = NULL; + + /* FT_Load_Glyph(), FT_Load_Char() take FT_UInt flags */ + if ( load_flags > FT_UINT_MAX ) + { + FT_TRACE1(( "FTC_ImageCache_LookupScaler: higher bits in load_flags" )); + FT_TRACE1(( "0x%x are dropped\n", (load_flags & ~((FT_ULong)FT_UINT_MAX)) )); + } + + query.attrs.scaler = scaler[0]; + query.attrs.load_flags = (FT_UInt)load_flags; + + hash = FTC_BASIC_ATTR_HASH( &query.attrs ) + gindex; + + FTC_GCACHE_LOOKUP_CMP( cache, + ftc_basic_family_compare, + FTC_GNode_Compare, + hash, gindex, + &query, + node, + error ); + if ( !error ) + { + *aglyph = FTC_INODE( node )->glyph; + + if ( anode ) + { + *anode = node; + node->ref_count++; + } + } + + Exit: + return error; + } + + + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + + /* yet another backwards-legacy structure */ + typedef struct FTC_OldImage_Desc_ + { + FTC_FontRec font; + FT_UInt image_type; + + } FTC_OldImage_Desc; + + +#define FTC_OLD_IMAGE_FORMAT( x ) ( (x) & 7 ) + + +#define ftc_old_image_format_bitmap 0x0000 +#define ftc_old_image_format_outline 0x0001 + +#define ftc_old_image_format_mask 0x000F + +#define ftc_old_image_flag_monochrome 0x0010 +#define ftc_old_image_flag_unhinted 0x0020 +#define ftc_old_image_flag_autohinted 0x0040 +#define ftc_old_image_flag_unscaled 0x0080 +#define ftc_old_image_flag_no_sbits 0x0100 + + /* monochrome bitmap */ +#define ftc_old_image_mono ftc_old_image_format_bitmap | \ + ftc_old_image_flag_monochrome + + /* anti-aliased bitmap */ +#define ftc_old_image_grays ftc_old_image_format_bitmap + + /* scaled outline */ +#define ftc_old_image_outline ftc_old_image_format_outline + + + static void + ftc_image_type_from_old_desc( FTC_ImageType typ, + FTC_OldImage_Desc* desc ) + { + typ->face_id = desc->font.face_id; + typ->width = desc->font.pix_width; + typ->height = desc->font.pix_height; + + /* convert image type flags to load flags */ + { + FT_UInt load_flags = FT_LOAD_DEFAULT; + FT_UInt type = desc->image_type; + + + /* determine load flags, depending on the font description's */ + /* image type */ + + if ( FTC_OLD_IMAGE_FORMAT( type ) == ftc_old_image_format_bitmap ) + { + if ( type & ftc_old_image_flag_monochrome ) + load_flags |= FT_LOAD_MONOCHROME; + + /* disable embedded bitmaps loading if necessary */ + if ( type & ftc_old_image_flag_no_sbits ) + load_flags |= FT_LOAD_NO_BITMAP; + } + else + { + /* we want an outline, don't load embedded bitmaps */ + load_flags |= FT_LOAD_NO_BITMAP; + + if ( type & ftc_old_image_flag_unscaled ) + load_flags |= FT_LOAD_NO_SCALE; + } + + /* always render glyphs to bitmaps */ + load_flags |= FT_LOAD_RENDER; + + if ( type & ftc_old_image_flag_unhinted ) + load_flags |= FT_LOAD_NO_HINTING; + + if ( type & ftc_old_image_flag_autohinted ) + load_flags |= FT_LOAD_FORCE_AUTOHINT; + + typ->flags = load_flags; + } + } + + + FT_EXPORT( FT_Error ) + FTC_Image_Cache_New( FTC_Manager manager, + FTC_ImageCache *acache ); + + FT_EXPORT( FT_Error ) + FTC_Image_Cache_Lookup( FTC_ImageCache icache, + FTC_OldImage_Desc* desc, + FT_UInt gindex, + FT_Glyph *aglyph ); + + + FT_EXPORT_DEF( FT_Error ) + FTC_Image_Cache_New( FTC_Manager manager, + FTC_ImageCache *acache ) + { + return FTC_ImageCache_New( manager, (FTC_ImageCache*)acache ); + } + + + + FT_EXPORT_DEF( FT_Error ) + FTC_Image_Cache_Lookup( FTC_ImageCache icache, + FTC_OldImage_Desc* desc, + FT_UInt gindex, + FT_Glyph *aglyph ) + { + FTC_ImageTypeRec type0; + + + if ( !desc ) + return FTC_Err_Invalid_Argument; + + ftc_image_type_from_old_desc( &type0, desc ); + + return FTC_ImageCache_Lookup( (FTC_ImageCache)icache, + &type0, + gindex, + aglyph, + NULL ); + } + +#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */ + + + /* + * + * basic small bitmap cache + * + */ + + + FT_CALLBACK_TABLE_DEF + const FTC_SFamilyClassRec ftc_basic_sbit_family_class = + { + { + sizeof( FTC_BasicFamilyRec ), + ftc_basic_family_compare, + ftc_basic_family_init, + 0, /* FTC_MruNode_ResetFunc */ + 0 /* FTC_MruNode_DoneFunc */ + }, + ftc_basic_family_get_count, + ftc_basic_family_load_bitmap + }; + + + FT_CALLBACK_TABLE_DEF + const FTC_GCacheClassRec ftc_basic_sbit_cache_class = + { + { + ftc_snode_new, + ftc_snode_weight, + ftc_snode_compare, + ftc_basic_gnode_compare_faceid, + ftc_snode_free, + + sizeof ( FTC_GCacheRec ), + ftc_gcache_init, + ftc_gcache_done + }, + (FTC_MruListClass)&ftc_basic_sbit_family_class + }; + + + /* documentation is in ftcache.h */ + + FT_EXPORT_DEF( FT_Error ) + FTC_SBitCache_New( FTC_Manager manager, + FTC_SBitCache *acache ) + { + return FTC_GCache_New( manager, &ftc_basic_sbit_cache_class, + (FTC_GCache*)acache ); + } + + + /* documentation is in ftcache.h */ + + FT_EXPORT_DEF( FT_Error ) + FTC_SBitCache_Lookup( FTC_SBitCache cache, + FTC_ImageType type, + FT_UInt gindex, + FTC_SBit *ansbit, + FTC_Node *anode ) + { + FT_Error error; + FTC_BasicQueryRec query; + FTC_Node node = 0; /* make compiler happy */ + FT_UInt32 hash; + + + if ( anode ) + *anode = NULL; + + /* other argument checks delayed to FTC_Cache_Lookup */ + if ( !ansbit ) + return FTC_Err_Invalid_Argument; + + *ansbit = NULL; + +#if defined( FT_CONFIG_OPTION_OLD_INTERNALS ) && ( FT_INT_MAX > 0xFFFFU ) + + /* This one is a major hack used to detect whether we are passed a + * regular FTC_ImageType handle, or a legacy FTC_OldImageDesc one. + */ + if ( (FT_ULong)type->width >= 0x10000L ) + { + FTC_OldImageDesc desc = (FTC_OldImageDesc)type; + + + query.attrs.scaler.face_id = desc->font.face_id; + query.attrs.scaler.width = desc->font.pix_width; + query.attrs.scaler.height = desc->font.pix_height; + query.attrs.load_flags = desc->flags; + } + else + +#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */ + + { + if ( (FT_ULong)(type->flags - FT_INT_MIN) > FT_UINT_MAX ) + { + FT_TRACE1(( "FTC_ImageCache_Lookup: higher bits in load_flags" )); + FT_TRACE1(( "0x%x are dropped\n", (type->flags & ~((FT_ULong)FT_UINT_MAX)) )); + } + + query.attrs.scaler.face_id = type->face_id; + query.attrs.scaler.width = type->width; + query.attrs.scaler.height = type->height; + query.attrs.load_flags = (FT_UInt)type->flags; + } + + query.attrs.scaler.pixel = 1; + query.attrs.scaler.x_res = 0; /* make compilers happy */ + query.attrs.scaler.y_res = 0; + + /* beware, the hash must be the same for all glyph ranges! */ + hash = FTC_BASIC_ATTR_HASH( &query.attrs ) + + gindex / FTC_SBIT_ITEMS_PER_NODE; + +#if 1 /* inlining is about 50% faster! */ + FTC_GCACHE_LOOKUP_CMP( cache, + ftc_basic_family_compare, + FTC_SNode_Compare, + hash, gindex, + &query, + node, + error ); +#else + error = FTC_GCache_Lookup( FTC_GCACHE( cache ), + hash, + gindex, + FTC_GQUERY( &query ), + &node ); +#endif + if ( error ) + goto Exit; + + *ansbit = FTC_SNODE( node )->sbits + + ( gindex - FTC_GNODE( node )->gindex ); + + if ( anode ) + { + *anode = node; + node->ref_count++; + } + + Exit: + return error; + } + + + /* documentation is in ftcache.h */ + + FT_EXPORT_DEF( FT_Error ) + FTC_SBitCache_LookupScaler( FTC_SBitCache cache, + FTC_Scaler scaler, + FT_ULong load_flags, + FT_UInt gindex, + FTC_SBit *ansbit, + FTC_Node *anode ) + { + FT_Error error; + FTC_BasicQueryRec query; + FTC_Node node = 0; /* make compiler happy */ + FT_UInt32 hash; + + + if ( anode ) + *anode = NULL; + + /* other argument checks delayed to FTC_Cache_Lookup */ + if ( !ansbit || !scaler ) + return FTC_Err_Invalid_Argument; + + *ansbit = NULL; + + /* FT_Load_Glyph(), FT_Load_Char() take FT_UInt flags */ + if ( load_flags > FT_UINT_MAX ) + { + FT_TRACE1(( "FTC_ImageCache_LookupScaler: higher bits in load_flags" )); + FT_TRACE1(( "0x%x are dropped\n", (load_flags & ~((FT_ULong)FT_UINT_MAX)) )); + } + + query.attrs.scaler = scaler[0]; + query.attrs.load_flags = (FT_UInt)load_flags; + + /* beware, the hash must be the same for all glyph ranges! */ + hash = FTC_BASIC_ATTR_HASH( &query.attrs ) + + gindex / FTC_SBIT_ITEMS_PER_NODE; + + FTC_GCACHE_LOOKUP_CMP( cache, + ftc_basic_family_compare, + FTC_SNode_Compare, + hash, gindex, + &query, + node, + error ); + if ( error ) + goto Exit; + + *ansbit = FTC_SNODE( node )->sbits + + ( gindex - FTC_GNODE( node )->gindex ); + + if ( anode ) + { + *anode = node; + node->ref_count++; + } + + Exit: + return error; + } + + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + + FT_EXPORT( FT_Error ) + FTC_SBit_Cache_New( FTC_Manager manager, + FTC_SBitCache *acache ); + + FT_EXPORT( FT_Error ) + FTC_SBit_Cache_Lookup( FTC_SBitCache cache, + FTC_OldImage_Desc* desc, + FT_UInt gindex, + FTC_SBit *ansbit ); + + + FT_EXPORT_DEF( FT_Error ) + FTC_SBit_Cache_New( FTC_Manager manager, + FTC_SBitCache *acache ) + { + return FTC_SBitCache_New( manager, (FTC_SBitCache*)acache ); + } + + + FT_EXPORT_DEF( FT_Error ) + FTC_SBit_Cache_Lookup( FTC_SBitCache cache, + FTC_OldImage_Desc* desc, + FT_UInt gindex, + FTC_SBit *ansbit ) + { + FTC_ImageTypeRec type0; + + + if ( !desc ) + return FT_Err_Invalid_Argument; + + ftc_image_type_from_old_desc( &type0, desc ); + + return FTC_SBitCache_Lookup( (FTC_SBitCache)cache, + &type0, + gindex, + ansbit, + NULL ); + } + +#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/cache/ftccache.c b/mod/pub.mod/freetype.mod/src/cache/ftccache.c new file mode 100644 index 0000000..463addd --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/cache/ftccache.c @@ -0,0 +1,595 @@ +/***************************************************************************/ +/* */ +/* ftccache.c */ +/* */ +/* The FreeType internal cache interface (body). */ +/* */ +/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include "ftcmanag.h" +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_DEBUG_H + +#include "ftccback.h" +#include "ftcerror.h" + +#undef FT_COMPONENT +#define FT_COMPONENT trace_cache + + +#define FTC_HASH_MAX_LOAD 2 +#define FTC_HASH_MIN_LOAD 1 +#define FTC_HASH_SUB_LOAD ( FTC_HASH_MAX_LOAD - FTC_HASH_MIN_LOAD ) + +/* this one _must_ be a power of 2! */ +#define FTC_HASH_INITIAL_SIZE 8 + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** CACHE NODE DEFINITIONS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* add a new node to the head of the manager's circular MRU list */ + static void + ftc_node_mru_link( FTC_Node node, + FTC_Manager manager ) + { + void *nl = &manager->nodes_list; + + + FTC_MruNode_Prepend( (FTC_MruNode*)nl, + (FTC_MruNode)node ); + manager->num_nodes++; + } + + + /* remove a node from the manager's MRU list */ + static void + ftc_node_mru_unlink( FTC_Node node, + FTC_Manager manager ) + { + void *nl = &manager->nodes_list; + + + FTC_MruNode_Remove( (FTC_MruNode*)nl, + (FTC_MruNode)node ); + manager->num_nodes--; + } + + +#ifndef FTC_INLINE + + /* move a node to the head of the manager's MRU list */ + static void + ftc_node_mru_up( FTC_Node node, + FTC_Manager manager ) + { + FTC_MruNode_Up( (FTC_MruNode*)&manager->nodes_list, + (FTC_MruNode)node ); + } + +#endif /* !FTC_INLINE */ + + + /* Note that this function cannot fail. If we cannot re-size the + * buckets array appropriately, we simply degrade the hash table's + * performance! + */ + static void + ftc_cache_resize( FTC_Cache cache ) + { + for (;;) + { + FTC_Node node, *pnode; + FT_UFast p = cache->p; + FT_UFast mask = cache->mask; + FT_UFast count = mask + p + 1; /* number of buckets */ + + + /* do we need to shrink the buckets array? */ + if ( cache->slack < 0 ) + { + FTC_Node new_list = NULL; + + + /* try to expand the buckets array _before_ splitting + * the bucket lists + */ + if ( p >= mask ) + { + FT_Memory memory = cache->memory; + FT_Error error; + + + /* if we can't expand the array, leave immediately */ + if ( FT_RENEW_ARRAY( cache->buckets, (mask+1)*2, (mask+1)*4 ) ) + break; + } + + /* split a single bucket */ + pnode = cache->buckets + p; + + for (;;) + { + node = *pnode; + if ( node == NULL ) + break; + + if ( node->hash & ( mask + 1 ) ) + { + *pnode = node->link; + node->link = new_list; + new_list = node; + } + else + pnode = &node->link; + } + + cache->buckets[p + mask + 1] = new_list; + + cache->slack += FTC_HASH_MAX_LOAD; + + if ( p >= mask ) + { + cache->mask = 2 * mask + 1; + cache->p = 0; + } + else + cache->p = p + 1; + } + + /* do we need to expand the buckets array? */ + else if ( cache->slack > (FT_Long)count * FTC_HASH_SUB_LOAD ) + { + FT_UFast old_index = p + mask; + FTC_Node* pold; + + + if ( old_index + 1 <= FTC_HASH_INITIAL_SIZE ) + break; + + if ( p == 0 ) + { + FT_Memory memory = cache->memory; + FT_Error error; + + + /* if we can't shrink the array, leave immediately */ + if ( FT_RENEW_ARRAY( cache->buckets, + ( mask + 1 ) * 2, mask + 1 ) ) + break; + + cache->mask >>= 1; + p = cache->mask; + } + else + p--; + + pnode = cache->buckets + p; + while ( *pnode ) + pnode = &(*pnode)->link; + + pold = cache->buckets + old_index; + *pnode = *pold; + *pold = NULL; + + cache->slack -= FTC_HASH_MAX_LOAD; + cache->p = p; + } + else /* the hash table is balanced */ + break; + } + } + + + /* remove a node from its cache's hash table */ + static void + ftc_node_hash_unlink( FTC_Node node0, + FTC_Cache cache ) + { + FTC_Node *pnode; + FT_UInt idx; + + + idx = (FT_UInt)( node0->hash & cache->mask ); + if ( idx < cache->p ) + idx = (FT_UInt)( node0->hash & ( 2 * cache->mask + 1 ) ); + + pnode = cache->buckets + idx; + + for (;;) + { + FTC_Node node = *pnode; + + + if ( node == NULL ) + { + FT_TRACE0(( "ftc_node_hash_unlink: unknown node\n" )); + return; + } + + if ( node == node0 ) + break; + + pnode = &(*pnode)->link; + } + + *pnode = node0->link; + node0->link = NULL; + + cache->slack++; + ftc_cache_resize( cache ); + } + + + /* add a node to the `top' of its cache's hash table */ + static void + ftc_node_hash_link( FTC_Node node, + FTC_Cache cache ) + { + FTC_Node *pnode; + FT_UInt idx; + + + idx = (FT_UInt)( node->hash & cache->mask ); + if ( idx < cache->p ) + idx = (FT_UInt)( node->hash & (2 * cache->mask + 1 ) ); + + pnode = cache->buckets + idx; + + node->link = *pnode; + *pnode = node; + + cache->slack--; + ftc_cache_resize( cache ); + } + + + /* remove a node from the cache manager */ +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + FT_BASE_DEF( void ) +#else + FT_LOCAL_DEF( void ) +#endif + ftc_node_destroy( FTC_Node node, + FTC_Manager manager ) + { + FTC_Cache cache; + + +#ifdef FT_DEBUG_ERROR + /* find node's cache */ + if ( node->cache_index >= manager->num_caches ) + { + FT_TRACE0(( "ftc_node_destroy: invalid node handle\n" )); + return; + } +#endif + + cache = manager->caches[node->cache_index]; + +#ifdef FT_DEBUG_ERROR + if ( cache == NULL ) + { + FT_TRACE0(( "ftc_node_destroy: invalid node handle\n" )); + return; + } +#endif + + manager->cur_weight -= cache->clazz.node_weight( node, cache ); + + /* remove node from mru list */ + ftc_node_mru_unlink( node, manager ); + + /* remove node from cache's hash table */ + ftc_node_hash_unlink( node, cache ); + + /* now finalize it */ + cache->clazz.node_free( node, cache ); + +#if 0 + /* check, just in case of general corruption :-) */ + if ( manager->num_nodes == 0 ) + FT_TRACE0(( "ftc_node_destroy: invalid cache node count (%d)\n", + manager->num_nodes )); +#endif + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** ABSTRACT CACHE CLASS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + FT_LOCAL_DEF( FT_Error ) + FTC_Cache_Init( FTC_Cache cache ) + { + return ftc_cache_init( cache ); + } + + + FT_LOCAL_DEF( FT_Error ) + ftc_cache_init( FTC_Cache cache ) + { + FT_Memory memory = cache->memory; + FT_Error error; + + + cache->p = 0; + cache->mask = FTC_HASH_INITIAL_SIZE - 1; + cache->slack = FTC_HASH_INITIAL_SIZE * FTC_HASH_MAX_LOAD; + + (void)FT_NEW_ARRAY( cache->buckets, FTC_HASH_INITIAL_SIZE * 2 ); + return error; + } + + + static void + FTC_Cache_Clear( FTC_Cache cache ) + { + if ( cache ) + { + FTC_Manager manager = cache->manager; + FT_UFast i; + FT_UFast count; + + + count = cache->p + cache->mask + 1; + + for ( i = 0; i < count; i++ ) + { + FTC_Node *pnode = cache->buckets + i, next, node = *pnode; + + + while ( node ) + { + next = node->link; + node->link = NULL; + + /* remove node from mru list */ + ftc_node_mru_unlink( node, manager ); + + /* now finalize it */ + manager->cur_weight -= cache->clazz.node_weight( node, cache ); + + cache->clazz.node_free( node, cache ); + node = next; + } + cache->buckets[i] = NULL; + } + ftc_cache_resize( cache ); + } + } + + + FT_LOCAL_DEF( void ) + ftc_cache_done( FTC_Cache cache ) + { + if ( cache->memory ) + { + FT_Memory memory = cache->memory; + + + FTC_Cache_Clear( cache ); + + FT_FREE( cache->buckets ); + cache->mask = 0; + cache->p = 0; + cache->slack = 0; + + cache->memory = NULL; + } + } + + + FT_LOCAL_DEF( void ) + FTC_Cache_Done( FTC_Cache cache ) + { + ftc_cache_done( cache ); + } + + + static void + ftc_cache_add( FTC_Cache cache, + FT_UInt32 hash, + FTC_Node node ) + { + node->hash = hash; + node->cache_index = (FT_UInt16) cache->index; + node->ref_count = 0; + + ftc_node_hash_link( node, cache ); + ftc_node_mru_link( node, cache->manager ); + + { + FTC_Manager manager = cache->manager; + + + manager->cur_weight += cache->clazz.node_weight( node, cache ); + + if ( manager->cur_weight >= manager->max_weight ) + { + node->ref_count++; + FTC_Manager_Compress( manager ); + node->ref_count--; + } + } + } + + + FT_LOCAL_DEF( FT_Error ) + FTC_Cache_NewNode( FTC_Cache cache, + FT_UInt32 hash, + FT_Pointer query, + FTC_Node *anode ) + { + FT_Error error; + FTC_Node node; + + + /* + * We use the FTC_CACHE_TRYLOOP macros to support out-of-memory + * errors (OOM) correctly, i.e., by flushing the cache progressively + * in order to make more room. + */ + + FTC_CACHE_TRYLOOP( cache ) + { + error = cache->clazz.node_new( &node, query, cache ); + } + FTC_CACHE_TRYLOOP_END(); + + if ( error ) + node = NULL; + else + { + /* don't assume that the cache has the same number of buckets, since + * our allocation request might have triggered global cache flushing + */ + ftc_cache_add( cache, hash, node ); + } + + *anode = node; + return error; + } + + +#ifndef FTC_INLINE + + FT_LOCAL_DEF( FT_Error ) + FTC_Cache_Lookup( FTC_Cache cache, + FT_UInt32 hash, + FT_Pointer query, + FTC_Node *anode ) + { + FT_UFast idx; + FTC_Node* bucket; + FTC_Node* pnode; + FTC_Node node; + FT_Error error = 0; + + FTC_Node_CompareFunc compare = cache->clazz.node_compare; + + + if ( cache == NULL || anode == NULL ) + return FT_Err_Invalid_Argument; + + idx = hash & cache->mask; + if ( idx < cache->p ) + idx = hash & ( cache->mask * 2 + 1 ); + + bucket = cache->buckets + idx; + pnode = bucket; + for (;;) + { + node = *pnode; + if ( node == NULL ) + goto NewNode; + + if ( node->hash == hash && compare( node, query, cache ) ) + break; + + pnode = &node->link; + } + + if ( node != *bucket ) + { + *pnode = node->link; + node->link = *bucket; + *bucket = node; + } + + /* move to head of MRU list */ + { + FTC_Manager manager = cache->manager; + + + if ( node != manager->nodes_list ) + ftc_node_mru_up( node, manager ); + } + *anode = node; + return error; + + NewNode: + return FTC_Cache_NewNode( cache, hash, query, anode ); + } + +#endif /* !FTC_INLINE */ + + + FT_LOCAL_DEF( void ) + FTC_Cache_RemoveFaceID( FTC_Cache cache, + FTC_FaceID face_id ) + { + FT_UFast i, count; + FTC_Manager manager = cache->manager; + FTC_Node frees = NULL; + + + count = cache->p + cache->mask; + for ( i = 0; i < count; i++ ) + { + FTC_Node* bucket = cache->buckets + i; + FTC_Node* pnode = bucket; + + + for ( ;; ) + { + FTC_Node node = *pnode; + + + if ( node == NULL ) + break; + + if ( cache->clazz.node_remove_faceid( node, face_id, cache ) ) + { + *pnode = node->link; + node->link = frees; + frees = node; + } + else + pnode = &node->link; + } + } + + /* remove all nodes in the free list */ + while ( frees ) + { + FTC_Node node; + + + node = frees; + frees = node->link; + + manager->cur_weight -= cache->clazz.node_weight( node, cache ); + ftc_node_mru_unlink( node, manager ); + + cache->clazz.node_free( node, cache ); + + cache->slack++; + } + + ftc_cache_resize( cache ); + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/cache/ftccache.h b/mod/pub.mod/freetype.mod/src/cache/ftccache.h new file mode 100644 index 0000000..2082bc4 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/cache/ftccache.h @@ -0,0 +1,316 @@ +/***************************************************************************/ +/* */ +/* ftccache.h */ +/* */ +/* FreeType internal cache interface (specification). */ +/* */ +/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTCCACHE_H__ +#define __FTCCACHE_H__ + + +#include "ftcmru.h" + +FT_BEGIN_HEADER + + /* handle to cache object */ + typedef struct FTC_CacheRec_* FTC_Cache; + + /* handle to cache class */ + typedef const struct FTC_CacheClassRec_* FTC_CacheClass; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** CACHE NODE DEFINITIONS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* Each cache controls one or more cache nodes. Each node is part of */ + /* the global_lru list of the manager. Its `data' field however is used */ + /* as a reference count for now. */ + /* */ + /* A node can be anything, depending on the type of information held by */ + /* the cache. It can be an individual glyph image, a set of bitmaps */ + /* glyphs for a given size, some metrics, etc. */ + /* */ + /*************************************************************************/ + + /* structure size should be 20 bytes on 32-bits machines */ + typedef struct FTC_NodeRec_ + { + FTC_MruNodeRec mru; /* circular mru list pointer */ + FTC_Node link; /* used for hashing */ + FT_UInt32 hash; /* used for hashing too */ + FT_UShort cache_index; /* index of cache the node belongs to */ + FT_Short ref_count; /* reference count for this node */ + + } FTC_NodeRec; + + +#define FTC_NODE( x ) ( (FTC_Node)(x) ) +#define FTC_NODE_P( x ) ( (FTC_Node*)(x) ) + +#define FTC_NODE__NEXT( x ) FTC_NODE( (x)->mru.next ) +#define FTC_NODE__PREV( x ) FTC_NODE( (x)->mru.prev ) + + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + FT_BASE( void ) + ftc_node_destroy( FTC_Node node, + FTC_Manager manager ); +#endif + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** CACHE DEFINITIONS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* initialize a new cache node */ + typedef FT_Error + (*FTC_Node_NewFunc)( FTC_Node *pnode, + FT_Pointer query, + FTC_Cache cache ); + + typedef FT_Offset + (*FTC_Node_WeightFunc)( FTC_Node node, + FTC_Cache cache ); + + /* compare a node to a given key pair */ + typedef FT_Bool + (*FTC_Node_CompareFunc)( FTC_Node node, + FT_Pointer key, + FTC_Cache cache ); + + + typedef void + (*FTC_Node_FreeFunc)( FTC_Node node, + FTC_Cache cache ); + + typedef FT_Error + (*FTC_Cache_InitFunc)( FTC_Cache cache ); + + typedef void + (*FTC_Cache_DoneFunc)( FTC_Cache cache ); + + + typedef struct FTC_CacheClassRec_ + { + FTC_Node_NewFunc node_new; + FTC_Node_WeightFunc node_weight; + FTC_Node_CompareFunc node_compare; + FTC_Node_CompareFunc node_remove_faceid; + FTC_Node_FreeFunc node_free; + + FT_Offset cache_size; + FTC_Cache_InitFunc cache_init; + FTC_Cache_DoneFunc cache_done; + + } FTC_CacheClassRec; + + + /* each cache really implements a dynamic hash table to manage its nodes */ + typedef struct FTC_CacheRec_ + { + FT_UFast p; + FT_UFast mask; + FT_Long slack; + FTC_Node* buckets; + + FTC_CacheClassRec clazz; /* local copy, for speed */ + + FTC_Manager manager; + FT_Memory memory; + FT_UInt index; /* in manager's table */ + + FTC_CacheClass org_class; /* original class pointer */ + + } FTC_CacheRec; + + +#define FTC_CACHE( x ) ( (FTC_Cache)(x) ) +#define FTC_CACHE_P( x ) ( (FTC_Cache*)(x) ) + + + /* default cache initialize */ + FT_LOCAL( FT_Error ) + FTC_Cache_Init( FTC_Cache cache ); + + /* default cache finalizer */ + FT_LOCAL( void ) + FTC_Cache_Done( FTC_Cache cache ); + + /* Call this function to lookup the cache. If no corresponding + * node is found, a new one is automatically created. This function + * is capable of flushing the cache adequately to make room for the + * new cache object. + */ + +#ifndef FTC_INLINE + FT_LOCAL( FT_Error ) + FTC_Cache_Lookup( FTC_Cache cache, + FT_UInt32 hash, + FT_Pointer query, + FTC_Node *anode ); +#endif + + FT_LOCAL( FT_Error ) + FTC_Cache_NewNode( FTC_Cache cache, + FT_UInt32 hash, + FT_Pointer query, + FTC_Node *anode ); + + /* Remove all nodes that relate to a given face_id. This is useful + * when un-installing fonts. Note that if a cache node relates to + * the face_id, but is locked (i.e., has `ref_count > 0'), the node + * will _not_ be destroyed, but its internal face_id reference will + * be modified. + * + * The final result will be that the node will never come back + * in further lookup requests, and will be flushed on demand from + * the cache normally when its reference count reaches 0. + */ + FT_LOCAL( void ) + FTC_Cache_RemoveFaceID( FTC_Cache cache, + FTC_FaceID face_id ); + + +#ifdef FTC_INLINE + +#define FTC_CACHE_LOOKUP_CMP( cache, nodecmp, hash, query, node, error ) \ + FT_BEGIN_STMNT \ + FTC_Node *_bucket, *_pnode, _node; \ + FTC_Cache _cache = FTC_CACHE(cache); \ + FT_UInt32 _hash = (FT_UInt32)(hash); \ + FTC_Node_CompareFunc _nodcomp = (FTC_Node_CompareFunc)(nodecmp); \ + FT_UFast _idx; \ + \ + \ + error = 0; \ + node = NULL; \ + _idx = _hash & _cache->mask; \ + if ( _idx < _cache->p ) \ + _idx = _hash & ( _cache->mask*2 + 1 ); \ + \ + _bucket = _pnode = _cache->buckets + _idx; \ + for (;;) \ + { \ + _node = *_pnode; \ + if ( _node == NULL ) \ + goto _NewNode; \ + \ + if ( _node->hash == _hash && _nodcomp( _node, query, _cache ) ) \ + break; \ + \ + _pnode = &_node->link; \ + } \ + \ + if ( _node != *_bucket ) \ + { \ + *_pnode = _node->link; \ + _node->link = *_bucket; \ + *_bucket = _node; \ + } \ + \ + { \ + FTC_Manager _manager = _cache->manager; \ + void* _nl = &_manager->nodes_list; \ + \ + \ + if ( _node != _manager->nodes_list ) \ + FTC_MruNode_Up( (FTC_MruNode*)_nl, \ + (FTC_MruNode)_node ); \ + } \ + goto _Ok; \ + \ + _NewNode: \ + error = FTC_Cache_NewNode( _cache, _hash, query, &_node ); \ + \ + _Ok: \ + node = _node; \ + FT_END_STMNT + +#else /* !FTC_INLINE */ + +#define FTC_CACHE_LOOKUP_CMP( cache, nodecmp, hash, query, node, error ) \ + FT_BEGIN_STMNT \ + error = FTC_Cache_Lookup( FTC_CACHE( cache ), hash, query, \ + (FTC_Node*)&(node) ); \ + FT_END_STMNT + +#endif /* !FTC_INLINE */ + + + /* + * This macro, together with FTC_CACHE_TRYLOOP_END, defines a retry + * loop to flush the cache repeatedly in case of memory overflows. + * + * It is used when creating a new cache node, or within a lookup + * that needs to allocate data (e.g., the sbit cache lookup). + * + * Example: + * + * { + * FTC_CACHE_TRYLOOP( cache ) + * error = load_data( ... ); + * FTC_CACHE_TRYLOOP_END() + * } + * + */ +#define FTC_CACHE_TRYLOOP( cache ) \ + { \ + FTC_Manager _try_manager = FTC_CACHE( cache )->manager; \ + FT_UInt _try_count = 4; \ + \ + \ + for (;;) \ + { \ + FT_UInt _try_done; + + +#define FTC_CACHE_TRYLOOP_END() \ + if ( !error || error != FT_Err_Out_Of_Memory ) \ + break; \ + \ + _try_done = FTC_Manager_FlushN( _try_manager, _try_count ); \ + if ( _try_done == 0 ) \ + break; \ + \ + if ( _try_done == _try_count ) \ + { \ + _try_count *= 2; \ + if ( _try_count < _try_done || \ + _try_count > _try_manager->num_nodes ) \ + _try_count = _try_manager->num_nodes; \ + } \ + } \ + } + + /* */ + +FT_END_HEADER + + +#endif /* __FTCCACHE_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/cache/ftccback.h b/mod/pub.mod/freetype.mod/src/cache/ftccback.h new file mode 100644 index 0000000..4d0818d --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/cache/ftccback.h @@ -0,0 +1,90 @@ +/***************************************************************************/ +/* */ +/* ftccback.h */ +/* */ +/* Callback functions of the caching sub-system (specification only). */ +/* */ +/* Copyright 2004, 2005, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + +#ifndef __FTCCBACK_H__ +#define __FTCCBACK_H__ + +#include <ft2build.h> +#include FT_CACHE_H +#include "ftcmru.h" +#include "ftcimage.h" +#include "ftcmanag.h" +#include "ftcglyph.h" +#include "ftcsbits.h" + + + FT_LOCAL( void ) + ftc_inode_free( FTC_Node inode, + FTC_Cache cache ); + + FT_LOCAL( FT_Error ) + ftc_inode_new( FTC_Node *pinode, + FT_Pointer gquery, + FTC_Cache cache ); + + FT_LOCAL( FT_Offset ) + ftc_inode_weight( FTC_Node inode, + FTC_Cache cache ); + + + FT_LOCAL( void ) + ftc_snode_free( FTC_Node snode, + FTC_Cache cache ); + + FT_LOCAL( FT_Error ) + ftc_snode_new( FTC_Node *psnode, + FT_Pointer gquery, + FTC_Cache cache ); + + FT_LOCAL( FT_Offset ) + ftc_snode_weight( FTC_Node snode, + FTC_Cache cache ); + + FT_LOCAL( FT_Bool ) + ftc_snode_compare( FTC_Node snode, + FT_Pointer gquery, + FTC_Cache cache ); + + + FT_LOCAL( FT_Bool ) + ftc_gnode_compare( FTC_Node gnode, + FT_Pointer gquery, + FTC_Cache cache ); + + + FT_LOCAL( FT_Error ) + ftc_gcache_init( FTC_Cache cache ); + + FT_LOCAL( void ) + ftc_gcache_done( FTC_Cache cache ); + + + FT_LOCAL( FT_Error ) + ftc_cache_init( FTC_Cache cache ); + + FT_LOCAL( void ) + ftc_cache_done( FTC_Cache cache ); + +#ifndef FT_CONFIG_OPTION_OLD_INTERNALS + FT_LOCAL( void ) + ftc_node_destroy( FTC_Node node, + FTC_Manager manager ); +#endif + +#endif /* __FTCCBACK_H__ */ + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/cache/ftccmap.c b/mod/pub.mod/freetype.mod/src/cache/ftccmap.c new file mode 100644 index 0000000..a802b05 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/cache/ftccmap.c @@ -0,0 +1,431 @@ +/***************************************************************************/ +/* */ +/* ftccmap.c */ +/* */ +/* FreeType CharMap cache (body) */ +/* */ +/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_CACHE_H +#include "ftcmanag.h" +#include FT_INTERNAL_MEMORY_H +#include FT_INTERNAL_DEBUG_H + +#include "ftccback.h" +#include "ftcerror.h" + +#undef FT_COMPONENT +#define FT_COMPONENT trace_cache + + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + + typedef enum FTC_OldCMapType_ + { + FTC_OLD_CMAP_BY_INDEX = 0, + FTC_OLD_CMAP_BY_ENCODING = 1, + FTC_OLD_CMAP_BY_ID = 2 + + } FTC_OldCMapType; + + + typedef struct FTC_OldCMapIdRec_ + { + FT_UInt platform; + FT_UInt encoding; + + } FTC_OldCMapIdRec, *FTC_OldCMapId; + + + typedef struct FTC_OldCMapDescRec_ + { + FTC_FaceID face_id; + FTC_OldCMapType type; + + union + { + FT_UInt index; + FT_Encoding encoding; + FTC_OldCMapIdRec id; + + } u; + + } FTC_OldCMapDescRec, *FTC_OldCMapDesc; + +#endif /* FT_CONFIG_OLD_INTERNALS */ + + + /*************************************************************************/ + /* */ + /* Each FTC_CMapNode contains a simple array to map a range of character */ + /* codes to equivalent glyph indices. */ + /* */ + /* For now, the implementation is very basic: Each node maps a range of */ + /* 128 consecutive character codes to their corresponding glyph indices. */ + /* */ + /* We could do more complex things, but I don't think it is really very */ + /* useful. */ + /* */ + /*************************************************************************/ + + + /* number of glyph indices / character code per node */ +#define FTC_CMAP_INDICES_MAX 128 + + /* compute a query/node hash */ +#define FTC_CMAP_HASH( faceid, index, charcode ) \ + ( FTC_FACE_ID_HASH( faceid ) + 211 * (index) + \ + ( (charcode) / FTC_CMAP_INDICES_MAX ) ) + + /* the charmap query */ + typedef struct FTC_CMapQueryRec_ + { + FTC_FaceID face_id; + FT_UInt cmap_index; + FT_UInt32 char_code; + + } FTC_CMapQueryRec, *FTC_CMapQuery; + +#define FTC_CMAP_QUERY( x ) ((FTC_CMapQuery)(x)) +#define FTC_CMAP_QUERY_HASH( x ) \ + FTC_CMAP_HASH( (x)->face_id, (x)->cmap_index, (x)->char_code ) + + /* the cmap cache node */ + typedef struct FTC_CMapNodeRec_ + { + FTC_NodeRec node; + FTC_FaceID face_id; + FT_UInt cmap_index; + FT_UInt32 first; /* first character in node */ + FT_UInt16 indices[FTC_CMAP_INDICES_MAX]; /* array of glyph indices */ + + } FTC_CMapNodeRec, *FTC_CMapNode; + +#define FTC_CMAP_NODE( x ) ( (FTC_CMapNode)( x ) ) +#define FTC_CMAP_NODE_HASH( x ) \ + FTC_CMAP_HASH( (x)->face_id, (x)->cmap_index, (x)->first ) + + /* if (indices[n] == FTC_CMAP_UNKNOWN), we assume that the corresponding */ + /* glyph indices haven't been queried through FT_Get_Glyph_Index() yet */ +#define FTC_CMAP_UNKNOWN ( (FT_UInt16)-1 ) + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** CHARMAP NODES *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + FT_CALLBACK_DEF( void ) + ftc_cmap_node_free( FTC_Node ftcnode, + FTC_Cache cache ) + { + FTC_CMapNode node = (FTC_CMapNode)ftcnode; + FT_Memory memory = cache->memory; + + + FT_FREE( node ); + } + + + /* initialize a new cmap node */ + FT_CALLBACK_DEF( FT_Error ) + ftc_cmap_node_new( FTC_Node *ftcanode, + FT_Pointer ftcquery, + FTC_Cache cache ) + { + FTC_CMapNode *anode = (FTC_CMapNode*)ftcanode; + FTC_CMapQuery query = (FTC_CMapQuery)ftcquery; + FT_Error error; + FT_Memory memory = cache->memory; + FTC_CMapNode node; + FT_UInt nn; + + + if ( !FT_NEW( node ) ) + { + node->face_id = query->face_id; + node->cmap_index = query->cmap_index; + node->first = (query->char_code / FTC_CMAP_INDICES_MAX) * + FTC_CMAP_INDICES_MAX; + + for ( nn = 0; nn < FTC_CMAP_INDICES_MAX; nn++ ) + node->indices[nn] = FTC_CMAP_UNKNOWN; + } + + *anode = node; + return error; + } + + + /* compute the weight of a given cmap node */ + FT_CALLBACK_DEF( FT_Offset ) + ftc_cmap_node_weight( FTC_Node cnode, + FTC_Cache cache ) + { + FT_UNUSED( cnode ); + FT_UNUSED( cache ); + + return sizeof ( *cnode ); + } + + + /* compare a cmap node to a given query */ + FT_CALLBACK_DEF( FT_Bool ) + ftc_cmap_node_compare( FTC_Node ftcnode, + FT_Pointer ftcquery, + FTC_Cache cache ) + { + FTC_CMapNode node = (FTC_CMapNode)ftcnode; + FTC_CMapQuery query = (FTC_CMapQuery)ftcquery; + FT_UNUSED( cache ); + + + if ( node->face_id == query->face_id && + node->cmap_index == query->cmap_index ) + { + FT_UInt32 offset = (FT_UInt32)( query->char_code - node->first ); + + + return FT_BOOL( offset < FTC_CMAP_INDICES_MAX ); + } + + return 0; + } + + + FT_CALLBACK_DEF( FT_Bool ) + ftc_cmap_node_remove_faceid( FTC_Node ftcnode, + FT_Pointer ftcface_id, + FTC_Cache cache ) + { + FTC_CMapNode node = (FTC_CMapNode)ftcnode; + FTC_FaceID face_id = (FTC_FaceID)ftcface_id; + FT_UNUSED( cache ); + + return FT_BOOL( node->face_id == face_id ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GLYPH IMAGE CACHE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + FT_CALLBACK_TABLE_DEF + const FTC_CacheClassRec ftc_cmap_cache_class = + { + ftc_cmap_node_new, + ftc_cmap_node_weight, + ftc_cmap_node_compare, + ftc_cmap_node_remove_faceid, + ftc_cmap_node_free, + + sizeof ( FTC_CacheRec ), + ftc_cache_init, + ftc_cache_done, + }; + + + /* documentation is in ftcache.h */ + + FT_EXPORT_DEF( FT_Error ) + FTC_CMapCache_New( FTC_Manager manager, + FTC_CMapCache *acache ) + { + return FTC_Manager_RegisterCache( manager, + &ftc_cmap_cache_class, + FTC_CACHE_P( acache ) ); + } + + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + + /* + * Unfortunately, it is not possible to support binary backwards + * compatibility in the cmap cache. The FTC_CMapCache_Lookup signature + * changes were too deep, and there is no clever hackish way to detect + * what kind of structure we are being passed. + * + * On the other hand it seems that no production code is using this + * function on Unix distributions. + */ + +#endif + + + /* documentation is in ftcache.h */ + + FT_EXPORT_DEF( FT_UInt ) + FTC_CMapCache_Lookup( FTC_CMapCache cmap_cache, + FTC_FaceID face_id, + FT_Int cmap_index, + FT_UInt32 char_code ) + { + FTC_Cache cache = FTC_CACHE( cmap_cache ); + FTC_CMapQueryRec query; + FTC_Node node; + FT_Error error; + FT_UInt gindex = 0; + FT_UInt32 hash; + FT_Int no_cmap_change = 0; + + + if ( cmap_index < 0 ) + { + /* Treat a negative cmap index as a special value, meaning that you */ + /* don't want to change the FT_Face's character map through this */ + /* call. This can be useful if the face requester callback already */ + /* sets the face's charmap to the appropriate value. */ + + no_cmap_change = 1; + cmap_index = 0; + } + + if ( !cache ) + { + FT_TRACE0(( "FTC_CMapCache_Lookup: bad arguments, returning 0\n" )); + return 0; + } + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + + /* + * Detect a call from a rogue client that thinks it is linking + * to FreeType 2.1.7. This is possible because the third parameter + * is then a character code, and we have never seen any font with + * more than a few charmaps, so if the index is very large... + * + * It is also very unlikely that a rogue client is interested + * in Unicode values 0 to 15. + * + * NOTE: The original threshold was 4, but we found a font from the + * Adobe Acrobat Reader Pack, named `KozMinProVI-Regular.otf', + * which contains more than 5 charmaps. + */ + if ( cmap_index >= 16 && !no_cmap_change ) + { + FTC_OldCMapDesc desc = (FTC_OldCMapDesc) face_id; + + + char_code = (FT_UInt32)cmap_index; + query.face_id = desc->face_id; + + + switch ( desc->type ) + { + case FTC_OLD_CMAP_BY_INDEX: + query.cmap_index = desc->u.index; + query.char_code = (FT_UInt32)cmap_index; + break; + + case FTC_OLD_CMAP_BY_ENCODING: + { + FT_Face face; + + + error = FTC_Manager_LookupFace( cache->manager, desc->face_id, + &face ); + if ( error ) + return 0; + + FT_Select_Charmap( face, desc->u.encoding ); + + return FT_Get_Char_Index( face, char_code ); + } + + default: + return 0; + } + } + else + +#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */ + + { + query.face_id = face_id; + query.cmap_index = (FT_UInt)cmap_index; + query.char_code = char_code; + } + + hash = FTC_CMAP_HASH( face_id, cmap_index, char_code ); + +#if 1 + FTC_CACHE_LOOKUP_CMP( cache, ftc_cmap_node_compare, hash, &query, + node, error ); +#else + error = FTC_Cache_Lookup( cache, hash, &query, &node ); +#endif + if ( error ) + goto Exit; + + FT_ASSERT( (FT_UInt)( char_code - FTC_CMAP_NODE( node )->first ) < + FTC_CMAP_INDICES_MAX ); + + /* something rotten can happen with rogue clients */ + if ( (FT_UInt)( char_code - FTC_CMAP_NODE( node )->first >= + FTC_CMAP_INDICES_MAX ) ) + return 0; + + gindex = FTC_CMAP_NODE( node )->indices[char_code - + FTC_CMAP_NODE( node )->first]; + if ( gindex == FTC_CMAP_UNKNOWN ) + { + FT_Face face; + + + gindex = 0; + + error = FTC_Manager_LookupFace( cache->manager, + FTC_CMAP_NODE( node )->face_id, + &face ); + if ( error ) + goto Exit; + + if ( (FT_UInt)cmap_index < (FT_UInt)face->num_charmaps ) + { + FT_CharMap old, cmap = NULL; + + + old = face->charmap; + cmap = face->charmaps[cmap_index]; + + if ( old != cmap && !no_cmap_change ) + FT_Set_Charmap( face, cmap ); + + gindex = FT_Get_Char_Index( face, char_code ); + + if ( old != cmap && !no_cmap_change ) + FT_Set_Charmap( face, old ); + } + + FTC_CMAP_NODE( node )->indices[char_code - + FTC_CMAP_NODE( node )->first] + = (FT_UShort)gindex; + } + + Exit: + return gindex; + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/cache/ftcerror.h b/mod/pub.mod/freetype.mod/src/cache/ftcerror.h new file mode 100644 index 0000000..5998d42 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/cache/ftcerror.h @@ -0,0 +1,40 @@ +/***************************************************************************/ +/* */ +/* ftcerror.h */ +/* */ +/* Caching sub-system error codes (specification only). */ +/* */ +/* Copyright 2001 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file is used to define the caching sub-system error enumeration */ + /* constants. */ + /* */ + /*************************************************************************/ + +#ifndef __FTCERROR_H__ +#define __FTCERROR_H__ + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#define FT_ERR_PREFIX FTC_Err_ +#define FT_ERR_BASE FT_Mod_Err_Cache + +#include FT_ERRORS_H + +#endif /* __FTCERROR_H__ */ + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/cache/ftcglyph.c b/mod/pub.mod/freetype.mod/src/cache/ftcglyph.c new file mode 100644 index 0000000..2f462a2 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/cache/ftcglyph.c @@ -0,0 +1,209 @@ +/***************************************************************************/ +/* */ +/* ftcglyph.c */ +/* */ +/* FreeType Glyph Image (FT_Glyph) cache (body). */ +/* */ +/* Copyright 2000-2001, 2003, 2004, 2006, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_CACHE_H +#include "ftcglyph.h" +#include FT_ERRORS_H + +#include "ftccback.h" +#include "ftcerror.h" + + + /* create a new chunk node, setting its cache index and ref count */ + FT_LOCAL_DEF( void ) + FTC_GNode_Init( FTC_GNode gnode, + FT_UInt gindex, + FTC_Family family ) + { + gnode->family = family; + gnode->gindex = gindex; + family->num_nodes++; + } + + + FT_LOCAL_DEF( void ) + FTC_GNode_UnselectFamily( FTC_GNode gnode, + FTC_Cache cache ) + { + FTC_Family family = gnode->family; + + + gnode->family = NULL; + if ( family && --family->num_nodes == 0 ) + FTC_FAMILY_FREE( family, cache ); + } + + + FT_LOCAL_DEF( void ) + FTC_GNode_Done( FTC_GNode gnode, + FTC_Cache cache ) + { + /* finalize the node */ + gnode->gindex = 0; + + FTC_GNode_UnselectFamily( gnode, cache ); + } + + + FT_LOCAL_DEF( FT_Bool ) + ftc_gnode_compare( FTC_Node ftcgnode, + FT_Pointer ftcgquery, + FTC_Cache cache ) + { + FTC_GNode gnode = (FTC_GNode)ftcgnode; + FTC_GQuery gquery = (FTC_GQuery)ftcgquery; + FT_UNUSED( cache ); + + + return FT_BOOL( gnode->family == gquery->family && + gnode->gindex == gquery->gindex ); + } + + + FT_LOCAL_DEF( FT_Bool ) + FTC_GNode_Compare( FTC_GNode gnode, + FTC_GQuery gquery ) + { + return ftc_gnode_compare( FTC_NODE( gnode ), gquery, NULL ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** CHUNK SETS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL_DEF( void ) + FTC_Family_Init( FTC_Family family, + FTC_Cache cache ) + { + FTC_GCacheClass clazz = FTC_CACHE__GCACHE_CLASS( cache ); + + + family->clazz = clazz->family_class; + family->num_nodes = 0; + family->cache = cache; + } + + + FT_LOCAL_DEF( FT_Error ) + ftc_gcache_init( FTC_Cache ftccache ) + { + FTC_GCache cache = (FTC_GCache)ftccache; + FT_Error error; + + + error = FTC_Cache_Init( FTC_CACHE( cache ) ); + if ( !error ) + { + FTC_GCacheClass clazz = (FTC_GCacheClass)FTC_CACHE( cache )->org_class; + + FTC_MruList_Init( &cache->families, + clazz->family_class, + 0, /* no maximum here! */ + cache, + FTC_CACHE( cache )->memory ); + } + + return error; + } + + +#if 0 + + FT_LOCAL_DEF( FT_Error ) + FTC_GCache_Init( FTC_GCache cache ) + { + return ftc_gcache_init( FTC_CACHE( cache ) ); + } + +#endif /* 0 */ + + + FT_LOCAL_DEF( void ) + ftc_gcache_done( FTC_Cache ftccache ) + { + FTC_GCache cache = (FTC_GCache)ftccache; + + + FTC_Cache_Done( (FTC_Cache)cache ); + FTC_MruList_Done( &cache->families ); + } + + +#if 0 + + FT_LOCAL_DEF( void ) + FTC_GCache_Done( FTC_GCache cache ) + { + ftc_gcache_done( FTC_CACHE( cache ) ); + } + +#endif /* 0 */ + + + FT_LOCAL_DEF( FT_Error ) + FTC_GCache_New( FTC_Manager manager, + FTC_GCacheClass clazz, + FTC_GCache *acache ) + { + return FTC_Manager_RegisterCache( manager, (FTC_CacheClass)clazz, + (FTC_Cache*)acache ); + } + + +#ifndef FTC_INLINE + + FT_LOCAL_DEF( FT_Error ) + FTC_GCache_Lookup( FTC_GCache cache, + FT_UInt32 hash, + FT_UInt gindex, + FTC_GQuery query, + FTC_Node *anode ) + { + FT_Error error; + + + query->gindex = gindex; + + FTC_MRULIST_LOOKUP( &cache->families, query, query->family, error ); + if ( !error ) + { + FTC_Family family = query->family; + + + /* prevent the family from being destroyed too early when an */ + /* out-of-memory condition occurs during glyph node initialization. */ + family->num_nodes++; + + error = FTC_Cache_Lookup( FTC_CACHE( cache ), hash, query, anode ); + + if ( --family->num_nodes == 0 ) + FTC_FAMILY_FREE( family, cache ); + } + return error; + } + +#endif /* !FTC_INLINE */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/cache/ftcglyph.h b/mod/pub.mod/freetype.mod/src/cache/ftcglyph.h new file mode 100644 index 0000000..c18f9c3 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/cache/ftcglyph.h @@ -0,0 +1,323 @@ +/***************************************************************************/ +/* */ +/* ftcglyph.h */ +/* */ +/* FreeType abstract glyph cache (specification). */ +/* */ +/* Copyright 2000-2001, 2003, 2004, 2006, 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /* + * + * FTC_GCache is an _abstract_ cache object optimized to store glyph + * data. It works as follows: + * + * - It manages FTC_GNode objects. Each one of them can hold one or more + * glyph `items'. Item types are not specified in the FTC_GCache but + * in classes that extend it. + * + * - Glyph attributes, like face ID, character size, render mode, etc., + * can be grouped into abstract `glyph families'. This avoids storing + * the attributes within the FTC_GCache, since it is likely that many + * FTC_GNodes will belong to the same family in typical uses. + * + * - Each FTC_GNode is thus an FTC_Node with two additional fields: + * + * * gindex: A glyph index, or the first index in a glyph range. + * * family: A pointer to a glyph `family'. + * + * - Family types are not fully specific in the FTC_Family type, but + * by classes that extend it. + * + * Note that both FTC_ImageCache and FTC_SBitCache extend FTC_GCache. + * They share an FTC_Family sub-class called FTC_BasicFamily which is + * used to store the following data: face ID, pixel/point sizes, load + * flags. For more details see the file `src/cache/ftcbasic.c'. + * + * Client applications can extend FTC_GNode with their own FTC_GNode + * and FTC_Family sub-classes to implement more complex caches (e.g., + * handling automatic synthesis, like obliquing & emboldening, colored + * glyphs, etc.). + * + * See also the FTC_ICache & FTC_SCache classes in `ftcimage.h' and + * `ftcsbits.h', which both extend FTC_GCache with additional + * optimizations. + * + * A typical FTC_GCache implementation must provide at least the + * following: + * + * - FTC_GNode sub-class, e.g. MyNode, with relevant methods: + * my_node_new (must call FTC_GNode_Init) + * my_node_free (must call FTC_GNode_Done) + * my_node_compare (must call FTC_GNode_Compare) + * my_node_remove_faceid (must call ftc_gnode_unselect in case + * of match) + * + * - FTC_Family sub-class, e.g. MyFamily, with relevant methods: + * my_family_compare + * my_family_init + * my_family_reset (optional) + * my_family_done + * + * - FTC_GQuery sub-class, e.g. MyQuery, to hold cache-specific query + * data. + * + * - Constant structures for a FTC_GNodeClass. + * + * - MyCacheNew() can be implemented easily as a call to the convenience + * function FTC_GCache_New. + * + * - MyCacheLookup with a call to FTC_GCache_Lookup. This function will + * automatically: + * + * - Search for the corresponding family in the cache, or create + * a new one if necessary. Put it in FTC_GQUERY(myquery).family + * + * - Call FTC_Cache_Lookup. + * + * If it returns NULL, you should create a new node, then call + * ftc_cache_add as usual. + */ + + + /*************************************************************************/ + /* */ + /* Important: The functions defined in this file are only used to */ + /* implement an abstract glyph cache class. You need to */ + /* provide additional logic to implement a complete cache. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /********* *********/ + /********* WARNING, THIS IS BETA CODE. *********/ + /********* *********/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + +#ifndef __FTCGLYPH_H__ +#define __FTCGLYPH_H__ + + +#include <ft2build.h> +#include "ftcmanag.h" + + +FT_BEGIN_HEADER + + + /* + * We can group glyphs into `families'. Each family correspond to a + * given face ID, character size, transform, etc. + * + * Families are implemented as MRU list nodes. They are + * reference-counted. + */ + + typedef struct FTC_FamilyRec_ + { + FTC_MruNodeRec mrunode; + FT_UInt num_nodes; /* current number of nodes in this family */ + FTC_Cache cache; + FTC_MruListClass clazz; + + } FTC_FamilyRec, *FTC_Family; + +#define FTC_FAMILY(x) ( (FTC_Family)(x) ) +#define FTC_FAMILY_P(x) ( (FTC_Family*)(x) ) + + + typedef struct FTC_GNodeRec_ + { + FTC_NodeRec node; + FTC_Family family; + FT_UInt gindex; + + } FTC_GNodeRec, *FTC_GNode; + +#define FTC_GNODE( x ) ( (FTC_GNode)(x) ) +#define FTC_GNODE_P( x ) ( (FTC_GNode*)(x) ) + + + typedef struct FTC_GQueryRec_ + { + FT_UInt gindex; + FTC_Family family; + + } FTC_GQueryRec, *FTC_GQuery; + +#define FTC_GQUERY( x ) ( (FTC_GQuery)(x) ) + + + /*************************************************************************/ + /* */ + /* These functions are exported so that they can be called from */ + /* user-provided cache classes; otherwise, they are really part of the */ + /* cache sub-system internals. */ + /* */ + + /* must be called by derived FTC_Node_InitFunc routines */ + FT_LOCAL( void ) + FTC_GNode_Init( FTC_GNode node, + FT_UInt gindex, /* glyph index for node */ + FTC_Family family ); + + /* returns TRUE iff the query's glyph index correspond to the node; */ + /* this assumes that the `family' and `hash' fields of the query are */ + /* already correctly set */ + FT_LOCAL( FT_Bool ) + FTC_GNode_Compare( FTC_GNode gnode, + FTC_GQuery gquery ); + + /* call this function to clear a node's family -- this is necessary */ + /* to implement the `node_remove_faceid' cache method correctly */ + FT_LOCAL( void ) + FTC_GNode_UnselectFamily( FTC_GNode gnode, + FTC_Cache cache ); + + /* must be called by derived FTC_Node_DoneFunc routines */ + FT_LOCAL( void ) + FTC_GNode_Done( FTC_GNode node, + FTC_Cache cache ); + + + FT_LOCAL( void ) + FTC_Family_Init( FTC_Family family, + FTC_Cache cache ); + + typedef struct FTC_GCacheRec_ + { + FTC_CacheRec cache; + FTC_MruListRec families; + + } FTC_GCacheRec, *FTC_GCache; + +#define FTC_GCACHE( x ) ((FTC_GCache)(x)) + + +#if 0 + /* can be used as @FTC_Cache_InitFunc */ + FT_LOCAL( FT_Error ) + FTC_GCache_Init( FTC_GCache cache ); +#endif + + +#if 0 + /* can be used as @FTC_Cache_DoneFunc */ + FT_LOCAL( void ) + FTC_GCache_Done( FTC_GCache cache ); +#endif + + + /* the glyph cache class adds fields for the family implementation */ + typedef struct FTC_GCacheClassRec_ + { + FTC_CacheClassRec clazz; + FTC_MruListClass family_class; + + } FTC_GCacheClassRec; + + typedef const FTC_GCacheClassRec* FTC_GCacheClass; + +#define FTC_GCACHE_CLASS( x ) ((FTC_GCacheClass)(x)) + +#define FTC_CACHE__GCACHE_CLASS( x ) \ + FTC_GCACHE_CLASS( FTC_CACHE(x)->org_class ) +#define FTC_CACHE__FAMILY_CLASS( x ) \ + ( (FTC_MruListClass)FTC_CACHE__GCACHE_CLASS( x )->family_class ) + + + /* convenience function; use it instead of FTC_Manager_Register_Cache */ + FT_LOCAL( FT_Error ) + FTC_GCache_New( FTC_Manager manager, + FTC_GCacheClass clazz, + FTC_GCache *acache ); + +#ifndef FTC_INLINE + FT_LOCAL( FT_Error ) + FTC_GCache_Lookup( FTC_GCache cache, + FT_UInt32 hash, + FT_UInt gindex, + FTC_GQuery query, + FTC_Node *anode ); +#endif + + + /* */ + + +#define FTC_FAMILY_FREE( family, cache ) \ + FTC_MruList_Remove( &FTC_GCACHE((cache))->families, \ + (FTC_MruNode)(family) ) + + +#ifdef FTC_INLINE + +#define FTC_GCACHE_LOOKUP_CMP( cache, famcmp, nodecmp, hash, \ + gindex, query, node, error ) \ + FT_BEGIN_STMNT \ + FTC_GCache _gcache = FTC_GCACHE( cache ); \ + FTC_GQuery _gquery = (FTC_GQuery)( query ); \ + FTC_MruNode_CompareFunc _fcompare = (FTC_MruNode_CompareFunc)(famcmp); \ + FTC_MruNode _mrunode; \ + \ + \ + _gquery->gindex = (gindex); \ + \ + FTC_MRULIST_LOOKUP_CMP( &_gcache->families, _gquery, _fcompare, \ + _mrunode, error ); \ + _gquery->family = FTC_FAMILY( _mrunode ); \ + if ( !error ) \ + { \ + FTC_Family _gqfamily = _gquery->family; \ + \ + \ + _gqfamily->num_nodes++; \ + \ + FTC_CACHE_LOOKUP_CMP( cache, nodecmp, hash, query, node, error ); \ + \ + if ( --_gqfamily->num_nodes == 0 ) \ + FTC_FAMILY_FREE( _gqfamily, _gcache ); \ + } \ + FT_END_STMNT + /* */ + +#else /* !FTC_INLINE */ + +#define FTC_GCACHE_LOOKUP_CMP( cache, famcmp, nodecmp, hash, \ + gindex, query, node, error ) \ + FT_BEGIN_STMNT \ + \ + error = FTC_GCache_Lookup( FTC_GCACHE( cache ), hash, gindex, \ + FTC_GQUERY( query ), node ); \ + \ + FT_END_STMNT + +#endif /* !FTC_INLINE */ + + +FT_END_HEADER + + +#endif /* __FTCGLYPH_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/cache/ftcimage.c b/mod/pub.mod/freetype.mod/src/cache/ftcimage.c new file mode 100644 index 0000000..417daf2 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/cache/ftcimage.c @@ -0,0 +1,163 @@ +/***************************************************************************/ +/* */ +/* ftcimage.c */ +/* */ +/* FreeType Image cache (body). */ +/* */ +/* Copyright 2000-2001, 2003, 2004, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_CACHE_H +#include "ftcimage.h" +#include FT_INTERNAL_MEMORY_H + +#include "ftccback.h" +#include "ftcerror.h" + + + /* finalize a given glyph image node */ + FT_LOCAL_DEF( void ) + ftc_inode_free( FTC_Node ftcinode, + FTC_Cache cache ) + { + FTC_INode inode = (FTC_INode)ftcinode; + FT_Memory memory = cache->memory; + + + if ( inode->glyph ) + { + FT_Done_Glyph( inode->glyph ); + inode->glyph = NULL; + } + + FTC_GNode_Done( FTC_GNODE( inode ), cache ); + FT_FREE( inode ); + } + + + FT_LOCAL_DEF( void ) + FTC_INode_Free( FTC_INode inode, + FTC_Cache cache ) + { + ftc_inode_free( FTC_NODE( inode ), cache ); + } + + + /* initialize a new glyph image node */ + FT_LOCAL_DEF( FT_Error ) + FTC_INode_New( FTC_INode *pinode, + FTC_GQuery gquery, + FTC_Cache cache ) + { + FT_Memory memory = cache->memory; + FT_Error error; + FTC_INode inode; + + + if ( !FT_NEW( inode ) ) + { + FTC_GNode gnode = FTC_GNODE( inode ); + FTC_Family family = gquery->family; + FT_UInt gindex = gquery->gindex; + FTC_IFamilyClass clazz = FTC_CACHE__IFAMILY_CLASS( cache ); + + + /* initialize its inner fields */ + FTC_GNode_Init( gnode, gindex, family ); + + /* we will now load the glyph image */ + error = clazz->family_load_glyph( family, gindex, cache, + &inode->glyph ); + if ( error ) + { + FTC_INode_Free( inode, cache ); + inode = NULL; + } + } + + *pinode = inode; + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + ftc_inode_new( FTC_Node *ftcpinode, + FT_Pointer ftcgquery, + FTC_Cache cache ) + { + FTC_INode *pinode = (FTC_INode*)ftcpinode; + FTC_GQuery gquery = (FTC_GQuery)ftcgquery; + + + return FTC_INode_New( pinode, gquery, cache ); + } + + + FT_LOCAL_DEF( FT_Offset ) + ftc_inode_weight( FTC_Node ftcinode, + FTC_Cache ftccache ) + { + FTC_INode inode = (FTC_INode)ftcinode; + FT_Offset size = 0; + FT_Glyph glyph = inode->glyph; + + FT_UNUSED( ftccache ); + + + switch ( glyph->format ) + { + case FT_GLYPH_FORMAT_BITMAP: + { + FT_BitmapGlyph bitg; + + + bitg = (FT_BitmapGlyph)glyph; + size = bitg->bitmap.rows * ft_labs( bitg->bitmap.pitch ) + + sizeof ( *bitg ); + } + break; + + case FT_GLYPH_FORMAT_OUTLINE: + { + FT_OutlineGlyph outg; + + + outg = (FT_OutlineGlyph)glyph; + size = outg->outline.n_points * + ( sizeof ( FT_Vector ) + sizeof ( FT_Byte ) ) + + outg->outline.n_contours * sizeof ( FT_Short ) + + sizeof ( *outg ); + } + break; + + default: + ; + } + + size += sizeof ( *inode ); + return size; + } + + +#if 0 + + FT_LOCAL_DEF( FT_Offset ) + FTC_INode_Weight( FTC_INode inode ) + { + return ftc_inode_weight( FTC_NODE( inode ), NULL ); + } + +#endif /* 0 */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/cache/ftcimage.h b/mod/pub.mod/freetype.mod/src/cache/ftcimage.h new file mode 100644 index 0000000..20d5d3e --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/cache/ftcimage.h @@ -0,0 +1,107 @@ +/***************************************************************************/ +/* */ +/* ftcimage.h */ +/* */ +/* FreeType Generic Image cache (specification) */ +/* */ +/* Copyright 2000-2001, 2002, 2003, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /* + * FTC_ICache is an _abstract_ cache used to store a single FT_Glyph + * image per cache node. + * + * FTC_ICache extends FTC_GCache. For an implementation example, + * see FTC_ImageCache in `src/cache/ftbasic.c'. + */ + + + /*************************************************************************/ + /* */ + /* Each image cache really manages FT_Glyph objects. */ + /* */ + /*************************************************************************/ + + +#ifndef __FTCIMAGE_H__ +#define __FTCIMAGE_H__ + + +#include <ft2build.h> +#include FT_CACHE_H +#include "ftcglyph.h" + +FT_BEGIN_HEADER + + + /* the FT_Glyph image node type - we store only 1 glyph per node */ + typedef struct FTC_INodeRec_ + { + FTC_GNodeRec gnode; + FT_Glyph glyph; + + } FTC_INodeRec, *FTC_INode; + +#define FTC_INODE( x ) ( (FTC_INode)( x ) ) +#define FTC_INODE_GINDEX( x ) FTC_GNODE(x)->gindex +#define FTC_INODE_FAMILY( x ) FTC_GNODE(x)->family + + typedef FT_Error + (*FTC_IFamily_LoadGlyphFunc)( FTC_Family family, + FT_UInt gindex, + FTC_Cache cache, + FT_Glyph *aglyph ); + + typedef struct FTC_IFamilyClassRec_ + { + FTC_MruListClassRec clazz; + FTC_IFamily_LoadGlyphFunc family_load_glyph; + + } FTC_IFamilyClassRec; + + typedef const FTC_IFamilyClassRec* FTC_IFamilyClass; + +#define FTC_IFAMILY_CLASS( x ) ((FTC_IFamilyClass)(x)) + +#define FTC_CACHE__IFAMILY_CLASS( x ) \ + FTC_IFAMILY_CLASS( FTC_CACHE__GCACHE_CLASS(x)->family_class ) + + + /* can be used as a @FTC_Node_FreeFunc */ + FT_LOCAL( void ) + FTC_INode_Free( FTC_INode inode, + FTC_Cache cache ); + + /* Can be used as @FTC_Node_NewFunc. `gquery.index' and `gquery.family' + * must be set correctly. This function will call the `family_load_glyph' + * method to load the FT_Glyph into the cache node. + */ + FT_LOCAL( FT_Error ) + FTC_INode_New( FTC_INode *pinode, + FTC_GQuery gquery, + FTC_Cache cache ); + +#if 0 + /* can be used as @FTC_Node_WeightFunc */ + FT_LOCAL( FT_ULong ) + FTC_INode_Weight( FTC_INode inode ); +#endif + + + /* */ + +FT_END_HEADER + +#endif /* __FTCIMAGE_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/cache/ftcmanag.c b/mod/pub.mod/freetype.mod/src/cache/ftcmanag.c new file mode 100644 index 0000000..f2a298e --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/cache/ftcmanag.c @@ -0,0 +1,743 @@ +/***************************************************************************/ +/* */ +/* ftcmanag.c */ +/* */ +/* FreeType Cache Manager (body). */ +/* */ +/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_CACHE_H +#include "ftcmanag.h" +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_DEBUG_H +#include FT_SIZES_H + +#include "ftccback.h" +#include "ftcerror.h" + +#ifdef FT_CONFIG_OPTION_PIC +#error "cache system does not support PIC yet" +#endif + + +#undef FT_COMPONENT +#define FT_COMPONENT trace_cache + +#define FTC_LRU_GET_MANAGER( lru ) ( (FTC_Manager)(lru)->user_data ) + + + static FT_Error + ftc_scaler_lookup_size( FTC_Manager manager, + FTC_Scaler scaler, + FT_Size *asize ) + { + FT_Face face; + FT_Size size = NULL; + FT_Error error; + + + error = FTC_Manager_LookupFace( manager, scaler->face_id, &face ); + if ( error ) + goto Exit; + + error = FT_New_Size( face, &size ); + if ( error ) + goto Exit; + + FT_Activate_Size( size ); + + if ( scaler->pixel ) + error = FT_Set_Pixel_Sizes( face, scaler->width, scaler->height ); + else + error = FT_Set_Char_Size( face, scaler->width, scaler->height, + scaler->x_res, scaler->y_res ); + if ( error ) + { + FT_Done_Size( size ); + size = NULL; + } + + Exit: + *asize = size; + return error; + } + + + typedef struct FTC_SizeNodeRec_ + { + FTC_MruNodeRec node; + FT_Size size; + FTC_ScalerRec scaler; + + } FTC_SizeNodeRec, *FTC_SizeNode; + +#define FTC_SIZE_NODE( x ) ( (FTC_SizeNode)( x ) ) + + + FT_CALLBACK_DEF( void ) + ftc_size_node_done( FTC_MruNode ftcnode, + FT_Pointer data ) + { + FTC_SizeNode node = (FTC_SizeNode)ftcnode; + FT_Size size = node->size; + FT_UNUSED( data ); + + + if ( size ) + FT_Done_Size( size ); + } + + + FT_CALLBACK_DEF( FT_Bool ) + ftc_size_node_compare( FTC_MruNode ftcnode, + FT_Pointer ftcscaler ) + { + FTC_SizeNode node = (FTC_SizeNode)ftcnode; + FTC_Scaler scaler = (FTC_Scaler)ftcscaler; + FTC_Scaler scaler0 = &node->scaler; + + + if ( FTC_SCALER_COMPARE( scaler0, scaler ) ) + { + FT_Activate_Size( node->size ); + return 1; + } + return 0; + } + + + FT_CALLBACK_DEF( FT_Error ) + ftc_size_node_init( FTC_MruNode ftcnode, + FT_Pointer ftcscaler, + FT_Pointer ftcmanager ) + { + FTC_SizeNode node = (FTC_SizeNode)ftcnode; + FTC_Scaler scaler = (FTC_Scaler)ftcscaler; + FTC_Manager manager = (FTC_Manager)ftcmanager; + + + node->scaler = scaler[0]; + + return ftc_scaler_lookup_size( manager, scaler, &node->size ); + } + + + FT_CALLBACK_DEF( FT_Error ) + ftc_size_node_reset( FTC_MruNode ftcnode, + FT_Pointer ftcscaler, + FT_Pointer ftcmanager ) + { + FTC_SizeNode node = (FTC_SizeNode)ftcnode; + FTC_Scaler scaler = (FTC_Scaler)ftcscaler; + FTC_Manager manager = (FTC_Manager)ftcmanager; + + + FT_Done_Size( node->size ); + + node->scaler = scaler[0]; + + return ftc_scaler_lookup_size( manager, scaler, &node->size ); + } + + + FT_CALLBACK_TABLE_DEF + const FTC_MruListClassRec ftc_size_list_class = + { + sizeof ( FTC_SizeNodeRec ), + ftc_size_node_compare, + ftc_size_node_init, + ftc_size_node_reset, + ftc_size_node_done + }; + + + /* helper function used by ftc_face_node_done */ + static FT_Bool + ftc_size_node_compare_faceid( FTC_MruNode ftcnode, + FT_Pointer ftcface_id ) + { + FTC_SizeNode node = (FTC_SizeNode)ftcnode; + FTC_FaceID face_id = (FTC_FaceID)ftcface_id; + + + return FT_BOOL( node->scaler.face_id == face_id ); + } + + + /* documentation is in ftcache.h */ + + FT_EXPORT_DEF( FT_Error ) + FTC_Manager_LookupSize( FTC_Manager manager, + FTC_Scaler scaler, + FT_Size *asize ) + { + FT_Error error; + FTC_MruNode mrunode; + + + if ( asize == NULL ) + return FTC_Err_Invalid_Argument; + + *asize = NULL; + + if ( !manager ) + return FTC_Err_Invalid_Cache_Handle; + +#ifdef FTC_INLINE + + FTC_MRULIST_LOOKUP_CMP( &manager->sizes, scaler, ftc_size_node_compare, + mrunode, error ); + +#else + error = FTC_MruList_Lookup( &manager->sizes, scaler, &mrunode ); +#endif + + if ( !error ) + *asize = FTC_SIZE_NODE( mrunode )->size; + + return error; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** FACE MRU IMPLEMENTATION *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef struct FTC_FaceNodeRec_ + { + FTC_MruNodeRec node; + FTC_FaceID face_id; + FT_Face face; + + } FTC_FaceNodeRec, *FTC_FaceNode; + +#define FTC_FACE_NODE( x ) ( ( FTC_FaceNode )( x ) ) + + + FT_CALLBACK_DEF( FT_Error ) + ftc_face_node_init( FTC_MruNode ftcnode, + FT_Pointer ftcface_id, + FT_Pointer ftcmanager ) + { + FTC_FaceNode node = (FTC_FaceNode)ftcnode; + FTC_FaceID face_id = (FTC_FaceID)ftcface_id; + FTC_Manager manager = (FTC_Manager)ftcmanager; + FT_Error error; + + + node->face_id = face_id; + + error = manager->request_face( face_id, + manager->library, + manager->request_data, + &node->face ); + if ( !error ) + { + /* destroy initial size object; it will be re-created later */ + if ( node->face->size ) + FT_Done_Size( node->face->size ); + } + + return error; + } + + + FT_CALLBACK_DEF( void ) + ftc_face_node_done( FTC_MruNode ftcnode, + FT_Pointer ftcmanager ) + { + FTC_FaceNode node = (FTC_FaceNode)ftcnode; + FTC_Manager manager = (FTC_Manager)ftcmanager; + + + /* we must begin by removing all scalers for the target face */ + /* from the manager's list */ + FTC_MruList_RemoveSelection( &manager->sizes, + ftc_size_node_compare_faceid, + node->face_id ); + + /* all right, we can discard the face now */ + FT_Done_Face( node->face ); + node->face = NULL; + node->face_id = NULL; + } + + + FT_CALLBACK_DEF( FT_Bool ) + ftc_face_node_compare( FTC_MruNode ftcnode, + FT_Pointer ftcface_id ) + { + FTC_FaceNode node = (FTC_FaceNode)ftcnode; + FTC_FaceID face_id = (FTC_FaceID)ftcface_id; + + + return FT_BOOL( node->face_id == face_id ); + } + + + FT_CALLBACK_TABLE_DEF + const FTC_MruListClassRec ftc_face_list_class = + { + sizeof ( FTC_FaceNodeRec), + + ftc_face_node_compare, + ftc_face_node_init, + 0, /* FTC_MruNode_ResetFunc */ + ftc_face_node_done + }; + + + /* documentation is in ftcache.h */ + + FT_EXPORT_DEF( FT_Error ) + FTC_Manager_LookupFace( FTC_Manager manager, + FTC_FaceID face_id, + FT_Face *aface ) + { + FT_Error error; + FTC_MruNode mrunode; + + + if ( aface == NULL ) + return FTC_Err_Invalid_Argument; + + *aface = NULL; + + if ( !manager ) + return FTC_Err_Invalid_Cache_Handle; + + /* we break encapsulation for the sake of speed */ +#ifdef FTC_INLINE + + FTC_MRULIST_LOOKUP_CMP( &manager->faces, face_id, ftc_face_node_compare, + mrunode, error ); + +#else + error = FTC_MruList_Lookup( &manager->faces, face_id, &mrunode ); +#endif + + if ( !error ) + *aface = FTC_FACE_NODE( mrunode )->face; + + return error; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** CACHE MANAGER ROUTINES *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + /* documentation is in ftcache.h */ + + FT_EXPORT_DEF( FT_Error ) + FTC_Manager_New( FT_Library library, + FT_UInt max_faces, + FT_UInt max_sizes, + FT_ULong max_bytes, + FTC_Face_Requester requester, + FT_Pointer req_data, + FTC_Manager *amanager ) + { + FT_Error error; + FT_Memory memory; + FTC_Manager manager = 0; + + + if ( !library ) + return FTC_Err_Invalid_Library_Handle; + + memory = library->memory; + + if ( FT_NEW( manager ) ) + goto Exit; + + if ( max_faces == 0 ) + max_faces = FTC_MAX_FACES_DEFAULT; + + if ( max_sizes == 0 ) + max_sizes = FTC_MAX_SIZES_DEFAULT; + + if ( max_bytes == 0 ) + max_bytes = FTC_MAX_BYTES_DEFAULT; + + manager->library = library; + manager->memory = memory; + manager->max_weight = max_bytes; + + manager->request_face = requester; + manager->request_data = req_data; + + FTC_MruList_Init( &manager->faces, + &ftc_face_list_class, + max_faces, + manager, + memory ); + + FTC_MruList_Init( &manager->sizes, + &ftc_size_list_class, + max_sizes, + manager, + memory ); + + *amanager = manager; + + Exit: + return error; + } + + + /* documentation is in ftcache.h */ + + FT_EXPORT_DEF( void ) + FTC_Manager_Done( FTC_Manager manager ) + { + FT_Memory memory; + FT_UInt idx; + + + if ( !manager || !manager->library ) + return; + + memory = manager->memory; + + /* now discard all caches */ + for (idx = manager->num_caches; idx-- > 0; ) + { + FTC_Cache cache = manager->caches[idx]; + + + if ( cache ) + { + cache->clazz.cache_done( cache ); + FT_FREE( cache ); + manager->caches[idx] = NULL; + } + } + manager->num_caches = 0; + + /* discard faces and sizes */ + FTC_MruList_Done( &manager->sizes ); + FTC_MruList_Done( &manager->faces ); + + manager->library = NULL; + manager->memory = NULL; + + FT_FREE( manager ); + } + + + /* documentation is in ftcache.h */ + + FT_EXPORT_DEF( void ) + FTC_Manager_Reset( FTC_Manager manager ) + { + if ( manager ) + { + FTC_MruList_Reset( &manager->sizes ); + FTC_MruList_Reset( &manager->faces ); + } + /* XXX: FIXME: flush the caches? */ + } + + +#ifdef FT_DEBUG_ERROR + + static void + FTC_Manager_Check( FTC_Manager manager ) + { + FTC_Node node, first; + + + first = manager->nodes_list; + + /* check node weights */ + if ( first ) + { + FT_ULong weight = 0; + + + node = first; + + do + { + FTC_Cache cache = manager->caches[node->cache_index]; + + + if ( (FT_UInt)node->cache_index >= manager->num_caches ) + FT_TRACE0(( "FTC_Manager_Check: invalid node (cache index = %ld\n", + node->cache_index )); + else + weight += cache->clazz.node_weight( node, cache ); + + node = FTC_NODE__NEXT( node ); + + } while ( node != first ); + + if ( weight != manager->cur_weight ) + FT_TRACE0(( "FTC_Manager_Check: invalid weight %ld instead of %ld\n", + manager->cur_weight, weight )); + } + + /* check circular list */ + if ( first ) + { + FT_UFast count = 0; + + + node = first; + do + { + count++; + node = FTC_NODE__NEXT( node ); + + } while ( node != first ); + + if ( count != manager->num_nodes ) + FT_TRACE0(( "FTC_Manager_Check:" + " invalid cache node count %d instead of %d\n", + manager->num_nodes, count )); + } + } + +#endif /* FT_DEBUG_ERROR */ + + + /* `Compress' the manager's data, i.e., get rid of old cache nodes */ + /* that are not referenced anymore in order to limit the total */ + /* memory used by the cache. */ + + /* documentation is in ftcmanag.h */ + + FT_LOCAL_DEF( void ) + FTC_Manager_Compress( FTC_Manager manager ) + { + FTC_Node node, first; + + + if ( !manager ) + return; + + first = manager->nodes_list; + +#ifdef FT_DEBUG_ERROR + FTC_Manager_Check( manager ); + + FT_TRACE0(( "compressing, weight = %ld, max = %ld, nodes = %d\n", + manager->cur_weight, manager->max_weight, + manager->num_nodes )); +#endif + + if ( manager->cur_weight < manager->max_weight || first == NULL ) + return; + + /* go to last node -- it's a circular list */ + node = FTC_NODE__PREV( first ); + do + { + FTC_Node prev; + + + prev = ( node == first ) ? NULL : FTC_NODE__PREV( node ); + + if ( node->ref_count <= 0 ) + ftc_node_destroy( node, manager ); + + node = prev; + + } while ( node && manager->cur_weight > manager->max_weight ); + } + + + /* documentation is in ftcmanag.h */ + + FT_LOCAL_DEF( FT_Error ) + FTC_Manager_RegisterCache( FTC_Manager manager, + FTC_CacheClass clazz, + FTC_Cache *acache ) + { + FT_Error error = FTC_Err_Invalid_Argument; + FTC_Cache cache = NULL; + + + if ( manager && clazz && acache ) + { + FT_Memory memory = manager->memory; + + + if ( manager->num_caches >= FTC_MAX_CACHES ) + { + error = FTC_Err_Too_Many_Caches; + FT_ERROR(( "FTC_Manager_RegisterCache:" + " too many registered caches\n" )); + goto Exit; + } + + if ( !FT_ALLOC( cache, clazz->cache_size ) ) + { + cache->manager = manager; + cache->memory = memory; + cache->clazz = clazz[0]; + cache->org_class = clazz; + + /* THIS IS VERY IMPORTANT! IT WILL WRETCH THE MANAGER */ + /* IF IT IS NOT SET CORRECTLY */ + cache->index = manager->num_caches; + + error = clazz->cache_init( cache ); + if ( error ) + { + clazz->cache_done( cache ); + FT_FREE( cache ); + goto Exit; + } + + manager->caches[manager->num_caches++] = cache; + } + } + + Exit: + if ( acache ) + *acache = cache; + return error; + } + + + FT_LOCAL_DEF( FT_UInt ) + FTC_Manager_FlushN( FTC_Manager manager, + FT_UInt count ) + { + FTC_Node first = manager->nodes_list; + FTC_Node node; + FT_UInt result; + + + /* try to remove `count' nodes from the list */ + if ( first == NULL ) /* empty list! */ + return 0; + + /* go to last node - it's a circular list */ + node = FTC_NODE__PREV(first); + for ( result = 0; result < count; ) + { + FTC_Node prev = FTC_NODE__PREV( node ); + + + /* don't touch locked nodes */ + if ( node->ref_count <= 0 ) + { + ftc_node_destroy( node, manager ); + result++; + } + + if ( node == first ) + break; + + node = prev; + } + return result; + } + + + /* documentation is in ftcache.h */ + + FT_EXPORT_DEF( void ) + FTC_Manager_RemoveFaceID( FTC_Manager manager, + FTC_FaceID face_id ) + { + FT_UInt nn; + + /* this will remove all FTC_SizeNode that correspond to + * the face_id as well + */ + FTC_MruList_RemoveSelection( &manager->faces, + (FTC_MruNode_CompareFunc)NULL, + face_id ); + + for ( nn = 0; nn < manager->num_caches; nn++ ) + FTC_Cache_RemoveFaceID( manager->caches[nn], face_id ); + } + + + /* documentation is in ftcache.h */ + + FT_EXPORT_DEF( void ) + FTC_Node_Unref( FTC_Node node, + FTC_Manager manager ) + { + if ( node && (FT_UInt)node->cache_index < manager->num_caches ) + node->ref_count--; + } + + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + + FT_EXPORT_DEF( FT_Error ) + FTC_Manager_Lookup_Face( FTC_Manager manager, + FTC_FaceID face_id, + FT_Face *aface ) + { + return FTC_Manager_LookupFace( manager, face_id, aface ); + } + + + FT_EXPORT( FT_Error ) + FTC_Manager_Lookup_Size( FTC_Manager manager, + FTC_Font font, + FT_Face *aface, + FT_Size *asize ) + { + FTC_ScalerRec scaler; + FT_Error error; + FT_Size size; + FT_Face face; + + + scaler.face_id = font->face_id; + scaler.width = font->pix_width; + scaler.height = font->pix_height; + scaler.pixel = TRUE; + scaler.x_res = 0; + scaler.y_res = 0; + + error = FTC_Manager_LookupSize( manager, &scaler, &size ); + if ( error ) + { + face = NULL; + size = NULL; + } + else + face = size->face; + + if ( aface ) + *aface = face; + + if ( asize ) + *asize = size; + + return error; + } + +#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/cache/ftcmanag.h b/mod/pub.mod/freetype.mod/src/cache/ftcmanag.h new file mode 100644 index 0000000..3fdc2c7 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/cache/ftcmanag.h @@ -0,0 +1,175 @@ +/***************************************************************************/ +/* */ +/* ftcmanag.h */ +/* */ +/* FreeType Cache Manager (specification). */ +/* */ +/* Copyright 2000-2001, 2003, 2004, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* A cache manager is in charge of the following: */ + /* */ + /* - Maintain a mapping between generic FTC_FaceIDs and live FT_Face */ + /* objects. The mapping itself is performed through a user-provided */ + /* callback. However, the manager maintains a small cache of FT_Face */ + /* and FT_Size objects in order to speed up things considerably. */ + /* */ + /* - Manage one or more cache objects. Each cache is in charge of */ + /* holding a varying number of `cache nodes'. Each cache node */ + /* represents a minimal amount of individually accessible cached */ + /* data. For example, a cache node can be an FT_Glyph image */ + /* containing a vector outline, or some glyph metrics, or anything */ + /* else. */ + /* */ + /* Each cache node has a certain size in bytes that is added to the */ + /* total amount of `cache memory' within the manager. */ + /* */ + /* All cache nodes are located in a global LRU list, where the oldest */ + /* node is at the tail of the list. */ + /* */ + /* Each node belongs to a single cache, and includes a reference */ + /* count to avoid destroying it (due to caching). */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /********* *********/ + /********* WARNING, THIS IS BETA CODE. *********/ + /********* *********/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + +#ifndef __FTCMANAG_H__ +#define __FTCMANAG_H__ + + +#include <ft2build.h> +#include FT_CACHE_H +#include "ftcmru.h" +#include "ftccache.h" + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* cache_subsystem */ + /* */ + /*************************************************************************/ + + +#define FTC_MAX_FACES_DEFAULT 2 +#define FTC_MAX_SIZES_DEFAULT 4 +#define FTC_MAX_BYTES_DEFAULT 200000L /* ~200kByte by default */ + + /* maximum number of caches registered in a single manager */ +#define FTC_MAX_CACHES 16 + + + typedef struct FTC_ManagerRec_ + { + FT_Library library; + FT_Memory memory; + + FTC_Node nodes_list; + FT_ULong max_weight; + FT_ULong cur_weight; + FT_UInt num_nodes; + + FTC_Cache caches[FTC_MAX_CACHES]; + FT_UInt num_caches; + + FTC_MruListRec faces; + FTC_MruListRec sizes; + + FT_Pointer request_data; + FTC_Face_Requester request_face; + + } FTC_ManagerRec; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_Manager_Compress */ + /* */ + /* <Description> */ + /* This function is used to check the state of the cache manager if */ + /* its `num_bytes' field is greater than its `max_bytes' field. It */ + /* will flush as many old cache nodes as possible (ignoring cache */ + /* nodes with a non-zero reference count). */ + /* */ + /* <InOut> */ + /* manager :: A handle to the cache manager. */ + /* */ + /* <Note> */ + /* Client applications should not call this function directly. It is */ + /* normally invoked by specific cache implementations. */ + /* */ + /* The reason this function is exported is to allow client-specific */ + /* cache classes. */ + /* */ + FT_LOCAL( void ) + FTC_Manager_Compress( FTC_Manager manager ); + + + /* try to flush `count' old nodes from the cache; return the number + * of really flushed nodes + */ + FT_LOCAL( FT_UInt ) + FTC_Manager_FlushN( FTC_Manager manager, + FT_UInt count ); + + + /* this must be used internally for the moment */ + FT_LOCAL( FT_Error ) + FTC_Manager_RegisterCache( FTC_Manager manager, + FTC_CacheClass clazz, + FTC_Cache *acache ); + + /* */ + +#define FTC_SCALER_COMPARE( a, b ) \ + ( (a)->face_id == (b)->face_id && \ + (a)->width == (b)->width && \ + (a)->height == (b)->height && \ + ((a)->pixel != 0) == ((b)->pixel != 0) && \ + ( (a)->pixel || \ + ( (a)->x_res == (b)->x_res && \ + (a)->y_res == (b)->y_res ) ) ) + +#define FTC_SCALER_HASH( q ) \ + ( FTC_FACE_ID_HASH( (q)->face_id ) + \ + (q)->width + (q)->height*7 + \ + ( (q)->pixel ? 0 : ( (q)->x_res*33 ^ (q)->y_res*61 ) ) ) + + /* */ + +FT_END_HEADER + +#endif /* __FTCMANAG_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/cache/ftcmru.c b/mod/pub.mod/freetype.mod/src/cache/ftcmru.c new file mode 100644 index 0000000..9944b58 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/cache/ftcmru.c @@ -0,0 +1,357 @@ +/***************************************************************************/ +/* */ +/* ftcmru.c */ +/* */ +/* FreeType MRU support (body). */ +/* */ +/* Copyright 2003, 2004, 2006, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_CACHE_H +#include "ftcmru.h" +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_DEBUG_H + +#include "ftcerror.h" + + + FT_LOCAL_DEF( void ) + FTC_MruNode_Prepend( FTC_MruNode *plist, + FTC_MruNode node ) + { + FTC_MruNode first = *plist; + + + if ( first ) + { + FTC_MruNode last = first->prev; + + +#ifdef FT_DEBUG_ERROR + { + FTC_MruNode cnode = first; + + + do + { + if ( cnode == node ) + { + fprintf( stderr, "FTC_MruNode_Prepend: invalid action\n" ); + exit( 2 ); + } + cnode = cnode->next; + + } while ( cnode != first ); + } +#endif + + first->prev = node; + last->next = node; + node->next = first; + node->prev = last; + } + else + { + node->next = node; + node->prev = node; + } + *plist = node; + } + + + FT_LOCAL_DEF( void ) + FTC_MruNode_Up( FTC_MruNode *plist, + FTC_MruNode node ) + { + FTC_MruNode first = *plist; + + + FT_ASSERT( first != NULL ); + + if ( first != node ) + { + FTC_MruNode prev, next, last; + + +#ifdef FT_DEBUG_ERROR + { + FTC_MruNode cnode = first; + do + { + if ( cnode == node ) + goto Ok; + cnode = cnode->next; + + } while ( cnode != first ); + + fprintf( stderr, "FTC_MruNode_Up: invalid action\n" ); + exit( 2 ); + Ok: + } +#endif + prev = node->prev; + next = node->next; + + prev->next = next; + next->prev = prev; + + last = first->prev; + + last->next = node; + first->prev = node; + + node->next = first; + node->prev = last; + + *plist = node; + } + } + + + FT_LOCAL_DEF( void ) + FTC_MruNode_Remove( FTC_MruNode *plist, + FTC_MruNode node ) + { + FTC_MruNode first = *plist; + FTC_MruNode prev, next; + + + FT_ASSERT( first != NULL ); + +#ifdef FT_DEBUG_ERROR + { + FTC_MruNode cnode = first; + + + do + { + if ( cnode == node ) + goto Ok; + cnode = cnode->next; + + } while ( cnode != first ); + + fprintf( stderr, "FTC_MruNode_Remove: invalid action\n" ); + exit( 2 ); + Ok: + } +#endif + + prev = node->prev; + next = node->next; + + prev->next = next; + next->prev = prev; + + if ( node == next ) + { + FT_ASSERT( first == node ); + FT_ASSERT( prev == node ); + + *plist = NULL; + } + else if ( node == first ) + *plist = next; + } + + + FT_LOCAL_DEF( void ) + FTC_MruList_Init( FTC_MruList list, + FTC_MruListClass clazz, + FT_UInt max_nodes, + FT_Pointer data, + FT_Memory memory ) + { + list->num_nodes = 0; + list->max_nodes = max_nodes; + list->nodes = NULL; + list->clazz = *clazz; + list->data = data; + list->memory = memory; + } + + + FT_LOCAL_DEF( void ) + FTC_MruList_Reset( FTC_MruList list ) + { + while ( list->nodes ) + FTC_MruList_Remove( list, list->nodes ); + + FT_ASSERT( list->num_nodes == 0 ); + } + + + FT_LOCAL_DEF( void ) + FTC_MruList_Done( FTC_MruList list ) + { + FTC_MruList_Reset( list ); + } + + +#ifndef FTC_INLINE + FT_LOCAL_DEF( FTC_MruNode ) + FTC_MruList_Find( FTC_MruList list, + FT_Pointer key ) + { + FTC_MruNode_CompareFunc compare = list->clazz.node_compare; + FTC_MruNode first, node; + + + first = list->nodes; + node = NULL; + + if ( first ) + { + node = first; + do + { + if ( compare( node, key ) ) + { + if ( node != first ) + FTC_MruNode_Up( &list->nodes, node ); + + return node; + } + + node = node->next; + + } while ( node != first); + } + + return NULL; + } +#endif + + FT_LOCAL_DEF( FT_Error ) + FTC_MruList_New( FTC_MruList list, + FT_Pointer key, + FTC_MruNode *anode ) + { + FT_Error error; + FTC_MruNode node; + FT_Memory memory = list->memory; + + + if ( list->num_nodes >= list->max_nodes && list->max_nodes > 0 ) + { + node = list->nodes->prev; + + FT_ASSERT( node ); + + if ( list->clazz.node_reset ) + { + FTC_MruNode_Up( &list->nodes, node ); + + error = list->clazz.node_reset( node, key, list->data ); + if ( !error ) + goto Exit; + } + + FTC_MruNode_Remove( &list->nodes, node ); + list->num_nodes--; + + if ( list->clazz.node_done ) + list->clazz.node_done( node, list->data ); + } + else if ( FT_ALLOC( node, list->clazz.node_size ) ) + goto Exit; + + error = list->clazz.node_init( node, key, list->data ); + if ( error ) + goto Fail; + + FTC_MruNode_Prepend( &list->nodes, node ); + list->num_nodes++; + + Exit: + *anode = node; + return error; + + Fail: + if ( list->clazz.node_done ) + list->clazz.node_done( node, list->data ); + + FT_FREE( node ); + goto Exit; + } + + +#ifndef FTC_INLINE + FT_LOCAL_DEF( FT_Error ) + FTC_MruList_Lookup( FTC_MruList list, + FT_Pointer key, + FTC_MruNode *anode ) + { + FTC_MruNode node; + + + node = FTC_MruList_Find( list, key ); + if ( node == NULL ) + return FTC_MruList_New( list, key, anode ); + + *anode = node; + return 0; + } +#endif /* FTC_INLINE */ + + FT_LOCAL_DEF( void ) + FTC_MruList_Remove( FTC_MruList list, + FTC_MruNode node ) + { + FTC_MruNode_Remove( &list->nodes, node ); + list->num_nodes--; + + { + FT_Memory memory = list->memory; + + + if ( list->clazz.node_done ) + list->clazz.node_done( node, list->data ); + + FT_FREE( node ); + } + } + + + FT_LOCAL_DEF( void ) + FTC_MruList_RemoveSelection( FTC_MruList list, + FTC_MruNode_CompareFunc selection, + FT_Pointer key ) + { + FTC_MruNode first, node, next; + + + first = list->nodes; + while ( first && ( selection == NULL || selection( first, key ) ) ) + { + FTC_MruList_Remove( list, first ); + first = list->nodes; + } + + if ( first ) + { + node = first->next; + while ( node != first ) + { + next = node->next; + + if ( selection( node, key ) ) + FTC_MruList_Remove( list, node ); + + node = next; + } + } + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/cache/ftcmru.h b/mod/pub.mod/freetype.mod/src/cache/ftcmru.h new file mode 100644 index 0000000..5739439 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/cache/ftcmru.h @@ -0,0 +1,246 @@ +/***************************************************************************/ +/* */ +/* ftcmru.h */ +/* */ +/* Simple MRU list-cache (specification). */ +/* */ +/* Copyright 2000-2001, 2003, 2004, 2005, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* An MRU is a list that cannot hold more than a certain number of */ + /* elements (`max_elements'). All elements in the list are sorted in */ + /* least-recently-used order, i.e., the `oldest' element is at the tail */ + /* of the list. */ + /* */ + /* When doing a lookup (either through `Lookup()' or `Lookup_Node()'), */ + /* the list is searched for an element with the corresponding key. If */ + /* it is found, the element is moved to the head of the list and is */ + /* returned. */ + /* */ + /* If no corresponding element is found, the lookup routine will try to */ + /* obtain a new element with the relevant key. If the list is already */ + /* full, the oldest element from the list is discarded and replaced by a */ + /* new one; a new element is added to the list otherwise. */ + /* */ + /* Note that it is possible to pre-allocate the element list nodes. */ + /* This is handy if `max_elements' is sufficiently small, as it saves */ + /* allocations/releases during the lookup process. */ + /* */ + /*************************************************************************/ + + +#ifndef __FTCMRU_H__ +#define __FTCMRU_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + +#define xxFT_DEBUG_ERROR +#define FTC_INLINE + +FT_BEGIN_HEADER + + typedef struct FTC_MruNodeRec_* FTC_MruNode; + + typedef struct FTC_MruNodeRec_ + { + FTC_MruNode next; + FTC_MruNode prev; + + } FTC_MruNodeRec; + + + FT_LOCAL( void ) + FTC_MruNode_Prepend( FTC_MruNode *plist, + FTC_MruNode node ); + + FT_LOCAL( void ) + FTC_MruNode_Up( FTC_MruNode *plist, + FTC_MruNode node ); + + FT_LOCAL( void ) + FTC_MruNode_Remove( FTC_MruNode *plist, + FTC_MruNode node ); + + + typedef struct FTC_MruListRec_* FTC_MruList; + + typedef struct FTC_MruListClassRec_ const * FTC_MruListClass; + + + typedef FT_Bool + (*FTC_MruNode_CompareFunc)( FTC_MruNode node, + FT_Pointer key ); + + typedef FT_Error + (*FTC_MruNode_InitFunc)( FTC_MruNode node, + FT_Pointer key, + FT_Pointer data ); + + typedef FT_Error + (*FTC_MruNode_ResetFunc)( FTC_MruNode node, + FT_Pointer key, + FT_Pointer data ); + + typedef void + (*FTC_MruNode_DoneFunc)( FTC_MruNode node, + FT_Pointer data ); + + + typedef struct FTC_MruListClassRec_ + { + FT_Offset node_size; + FTC_MruNode_CompareFunc node_compare; + FTC_MruNode_InitFunc node_init; + FTC_MruNode_ResetFunc node_reset; + FTC_MruNode_DoneFunc node_done; + + } FTC_MruListClassRec; + + typedef struct FTC_MruListRec_ + { + FT_UInt num_nodes; + FT_UInt max_nodes; + FTC_MruNode nodes; + FT_Pointer data; + FTC_MruListClassRec clazz; + FT_Memory memory; + + } FTC_MruListRec; + + + FT_LOCAL( void ) + FTC_MruList_Init( FTC_MruList list, + FTC_MruListClass clazz, + FT_UInt max_nodes, + FT_Pointer data, + FT_Memory memory ); + + FT_LOCAL( void ) + FTC_MruList_Reset( FTC_MruList list ); + + + FT_LOCAL( void ) + FTC_MruList_Done( FTC_MruList list ); + + + FT_LOCAL( FT_Error ) + FTC_MruList_New( FTC_MruList list, + FT_Pointer key, + FTC_MruNode *anode ); + + FT_LOCAL( void ) + FTC_MruList_Remove( FTC_MruList list, + FTC_MruNode node ); + + FT_LOCAL( void ) + FTC_MruList_RemoveSelection( FTC_MruList list, + FTC_MruNode_CompareFunc selection, + FT_Pointer key ); + + +#ifdef FTC_INLINE + +#define FTC_MRULIST_LOOKUP_CMP( list, key, compare, node, error ) \ + FT_BEGIN_STMNT \ + FTC_MruNode* _pfirst = &(list)->nodes; \ + FTC_MruNode_CompareFunc _compare = (FTC_MruNode_CompareFunc)(compare); \ + FTC_MruNode _first, _node; \ + \ + \ + error = 0; \ + _first = *(_pfirst); \ + _node = NULL; \ + \ + if ( _first ) \ + { \ + _node = _first; \ + do \ + { \ + if ( _compare( _node, (key) ) ) \ + { \ + if ( _node != _first ) \ + FTC_MruNode_Up( _pfirst, _node ); \ + \ + node = _node; \ + goto _MruOk; \ + } \ + _node = _node->next; \ + \ + } while ( _node != _first) ; \ + } \ + \ + error = FTC_MruList_New( (list), (key), (FTC_MruNode*)(void*)&(node) ); \ + _MruOk: \ + ; \ + FT_END_STMNT + +#define FTC_MRULIST_LOOKUP( list, key, node, error ) \ + FTC_MRULIST_LOOKUP_CMP( list, key, (list)->clazz.node_compare, node, error ) + +#else /* !FTC_INLINE */ + + FT_LOCAL( FTC_MruNode ) + FTC_MruList_Find( FTC_MruList list, + FT_Pointer key ); + + FT_LOCAL( FT_Error ) + FTC_MruList_Lookup( FTC_MruList list, + FT_Pointer key, + FTC_MruNode *pnode ); + +#define FTC_MRULIST_LOOKUP( list, key, node, error ) \ + error = FTC_MruList_Lookup( (list), (key), (FTC_MruNode*)&(node) ) + +#endif /* !FTC_INLINE */ + + +#define FTC_MRULIST_LOOP( list, node ) \ + FT_BEGIN_STMNT \ + FTC_MruNode _first = (list)->nodes; \ + \ + \ + if ( _first ) \ + { \ + FTC_MruNode _node = _first; \ + \ + \ + do \ + { \ + *(FTC_MruNode*)&(node) = _node; + + +#define FTC_MRULIST_LOOP_END() \ + _node = _node->next; \ + \ + } while ( _node != _first ); \ + } \ + FT_END_STMNT + + /* */ + +FT_END_HEADER + + +#endif /* __FTCMRU_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/cache/ftcsbits.c b/mod/pub.mod/freetype.mod/src/cache/ftcsbits.c new file mode 100644 index 0000000..60d46aa --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/cache/ftcsbits.c @@ -0,0 +1,404 @@ +/***************************************************************************/ +/* */ +/* ftcsbits.c */ +/* */ +/* FreeType sbits manager (body). */ +/* */ +/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_CACHE_H +#include "ftcsbits.h" +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_DEBUG_H +#include FT_ERRORS_H + +#include "ftccback.h" +#include "ftcerror.h" + +#undef FT_COMPONENT +#define FT_COMPONENT trace_cache + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** SBIT CACHE NODES *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + static FT_Error + ftc_sbit_copy_bitmap( FTC_SBit sbit, + FT_Bitmap* bitmap, + FT_Memory memory ) + { + FT_Error error; + FT_Int pitch = bitmap->pitch; + FT_ULong size; + + + if ( pitch < 0 ) + pitch = -pitch; + + size = (FT_ULong)( pitch * bitmap->rows ); + + if ( !FT_ALLOC( sbit->buffer, size ) ) + FT_MEM_COPY( sbit->buffer, bitmap->buffer, size ); + + return error; + } + + + FT_LOCAL_DEF( void ) + ftc_snode_free( FTC_Node ftcsnode, + FTC_Cache cache ) + { + FTC_SNode snode = (FTC_SNode)ftcsnode; + FTC_SBit sbit = snode->sbits; + FT_UInt count = snode->count; + FT_Memory memory = cache->memory; + + + for ( ; count > 0; sbit++, count-- ) + FT_FREE( sbit->buffer ); + + FTC_GNode_Done( FTC_GNODE( snode ), cache ); + + FT_FREE( snode ); + } + + + FT_LOCAL_DEF( void ) + FTC_SNode_Free( FTC_SNode snode, + FTC_Cache cache ) + { + ftc_snode_free( FTC_NODE( snode ), cache ); + } + + + /* + * This function tries to load a small bitmap within a given FTC_SNode. + * Note that it returns a non-zero error code _only_ in the case of + * out-of-memory condition. For all other errors (e.g., corresponding + * to a bad font file), this function will mark the sbit as `unavailable' + * and return a value of 0. + * + * You should also read the comment within the @ftc_snode_compare + * function below to see how out-of-memory is handled during a lookup. + */ + static FT_Error + ftc_snode_load( FTC_SNode snode, + FTC_Manager manager, + FT_UInt gindex, + FT_ULong *asize ) + { + FT_Error error; + FTC_GNode gnode = FTC_GNODE( snode ); + FTC_Family family = gnode->family; + FT_Memory memory = manager->memory; + FT_Face face; + FTC_SBit sbit; + FTC_SFamilyClass clazz; + + + if ( (FT_UInt)(gindex - gnode->gindex) >= snode->count ) + { + FT_ERROR(( "ftc_snode_load: invalid glyph index" )); + return FTC_Err_Invalid_Argument; + } + + sbit = snode->sbits + ( gindex - gnode->gindex ); + clazz = (FTC_SFamilyClass)family->clazz; + + sbit->buffer = 0; + + error = clazz->family_load_glyph( family, gindex, manager, &face ); + if ( error ) + goto BadGlyph; + + { + FT_Int temp; + FT_GlyphSlot slot = face->glyph; + FT_Bitmap* bitmap = &slot->bitmap; + FT_Pos xadvance, yadvance; /* FT_GlyphSlot->advance.{x|y} */ + + + if ( slot->format != FT_GLYPH_FORMAT_BITMAP ) + { + FT_TRACE0(( "ftc_snode_load:" + " glyph loaded didn't return a bitmap\n" )); + goto BadGlyph; + } + + /* Check that our values fit into 8-bit containers! */ + /* If this is not the case, our bitmap is too large */ + /* and we will leave it as `missing' with sbit.buffer = 0 */ + +#define CHECK_CHAR( d ) ( temp = (FT_Char)d, temp == d ) +#define CHECK_BYTE( d ) ( temp = (FT_Byte)d, temp == d ) + + /* horizontal advance in pixels */ + xadvance = ( slot->advance.x + 32 ) >> 6; + yadvance = ( slot->advance.y + 32 ) >> 6; + + if ( !CHECK_BYTE( bitmap->rows ) || + !CHECK_BYTE( bitmap->width ) || + !CHECK_CHAR( bitmap->pitch ) || + !CHECK_CHAR( slot->bitmap_left ) || + !CHECK_CHAR( slot->bitmap_top ) || + !CHECK_CHAR( xadvance ) || + !CHECK_CHAR( yadvance ) ) + goto BadGlyph; + + sbit->width = (FT_Byte)bitmap->width; + sbit->height = (FT_Byte)bitmap->rows; + sbit->pitch = (FT_Char)bitmap->pitch; + sbit->left = (FT_Char)slot->bitmap_left; + sbit->top = (FT_Char)slot->bitmap_top; + sbit->xadvance = (FT_Char)xadvance; + sbit->yadvance = (FT_Char)yadvance; + sbit->format = (FT_Byte)bitmap->pixel_mode; + sbit->max_grays = (FT_Byte)(bitmap->num_grays - 1); + + /* copy the bitmap into a new buffer -- ignore error */ + error = ftc_sbit_copy_bitmap( sbit, bitmap, memory ); + + /* now, compute size */ + if ( asize ) + *asize = FT_ABS( sbit->pitch ) * sbit->height; + + } /* glyph loading successful */ + + /* ignore the errors that might have occurred -- */ + /* we mark unloaded glyphs with `sbit.buffer == 0' */ + /* and `width == 255', `height == 0' */ + /* */ + if ( error && error != FTC_Err_Out_Of_Memory ) + { + BadGlyph: + sbit->width = 255; + sbit->height = 0; + sbit->buffer = NULL; + error = 0; + if ( asize ) + *asize = 0; + } + + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + FTC_SNode_New( FTC_SNode *psnode, + FTC_GQuery gquery, + FTC_Cache cache ) + { + FT_Memory memory = cache->memory; + FT_Error error; + FTC_SNode snode = NULL; + FT_UInt gindex = gquery->gindex; + FTC_Family family = gquery->family; + + FTC_SFamilyClass clazz = FTC_CACHE__SFAMILY_CLASS( cache ); + FT_UInt total; + + + total = clazz->family_get_count( family, cache->manager ); + if ( total == 0 || gindex >= total ) + { + error = FT_Err_Invalid_Argument; + goto Exit; + } + + if ( !FT_NEW( snode ) ) + { + FT_UInt count, start; + + + start = gindex - ( gindex % FTC_SBIT_ITEMS_PER_NODE ); + count = total - start; + if ( count > FTC_SBIT_ITEMS_PER_NODE ) + count = FTC_SBIT_ITEMS_PER_NODE; + + FTC_GNode_Init( FTC_GNODE( snode ), start, family ); + + snode->count = count; + + error = ftc_snode_load( snode, + cache->manager, + gindex, + NULL ); + if ( error ) + { + FTC_SNode_Free( snode, cache ); + snode = NULL; + } + } + + Exit: + *psnode = snode; + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + ftc_snode_new( FTC_Node *ftcpsnode, + FT_Pointer ftcgquery, + FTC_Cache cache ) + { + FTC_SNode *psnode = (FTC_SNode*)ftcpsnode; + FTC_GQuery gquery = (FTC_GQuery)ftcgquery; + + + return FTC_SNode_New( psnode, gquery, cache ); + } + + + FT_LOCAL_DEF( FT_Offset ) + ftc_snode_weight( FTC_Node ftcsnode, + FTC_Cache cache ) + { + FTC_SNode snode = (FTC_SNode)ftcsnode; + FT_UInt count = snode->count; + FTC_SBit sbit = snode->sbits; + FT_Int pitch; + FT_Offset size; + + FT_UNUSED( cache ); + + + FT_ASSERT( snode->count <= FTC_SBIT_ITEMS_PER_NODE ); + + /* the node itself */ + size = sizeof ( *snode ); + + for ( ; count > 0; count--, sbit++ ) + { + if ( sbit->buffer ) + { + pitch = sbit->pitch; + if ( pitch < 0 ) + pitch = -pitch; + + /* add the size of a given glyph image */ + size += pitch * sbit->height; + } + } + + return size; + } + + +#if 0 + + FT_LOCAL_DEF( FT_Offset ) + FTC_SNode_Weight( FTC_SNode snode ) + { + return ftc_snode_weight( FTC_NODE( snode ), NULL ); + } + +#endif /* 0 */ + + + FT_LOCAL_DEF( FT_Bool ) + ftc_snode_compare( FTC_Node ftcsnode, + FT_Pointer ftcgquery, + FTC_Cache cache ) + { + FTC_SNode snode = (FTC_SNode)ftcsnode; + FTC_GQuery gquery = (FTC_GQuery)ftcgquery; + FTC_GNode gnode = FTC_GNODE( snode ); + FT_UInt gindex = gquery->gindex; + FT_Bool result; + + + result = FT_BOOL( gnode->family == gquery->family && + (FT_UInt)( gindex - gnode->gindex ) < snode->count ); + if ( result ) + { + /* check if we need to load the glyph bitmap now */ + FTC_SBit sbit = snode->sbits + ( gindex - gnode->gindex ); + + + /* + * The following code illustrates what to do when you want to + * perform operations that may fail within a lookup function. + * + * Here, we want to load a small bitmap on-demand; we thus + * need to call the `ftc_snode_load' function which may return + * a non-zero error code only when we are out of memory (OOM). + * + * The correct thing to do is to use @FTC_CACHE_TRYLOOP and + * @FTC_CACHE_TRYLOOP_END in order to implement a retry loop + * that is capable of flushing the cache incrementally when + * an OOM errors occur. + * + * However, we need to `lock' the node before this operation to + * prevent it from being flushed within the loop. + * + * When we exit the loop, we unlock the node, then check the `error' + * variable. If it is non-zero, this means that the cache was + * completely flushed and that no usable memory was found to load + * the bitmap. + * + * We then prefer to return a value of 0 (i.e., NO MATCH). This + * ensures that the caller will try to allocate a new node. + * This operation consequently _fail_ and the lookup function + * returns the appropriate OOM error code. + * + * Note that `buffer == NULL && width == 255' is a hack used to + * tag `unavailable' bitmaps in the array. We should never try + * to load these. + * + */ + + if ( sbit->buffer == NULL && sbit->width != 255 ) + { + FT_ULong size; + FT_Error error; + + + ftcsnode->ref_count++; /* lock node to prevent flushing */ + /* in retry loop */ + + FTC_CACHE_TRYLOOP( cache ) + { + error = ftc_snode_load( snode, cache->manager, gindex, &size ); + } + FTC_CACHE_TRYLOOP_END(); + + ftcsnode->ref_count--; /* unlock the node */ + + if ( error ) + result = 0; + else + cache->manager->cur_weight += size; + } + } + + return result; + } + + + FT_LOCAL_DEF( FT_Bool ) + FTC_SNode_Compare( FTC_SNode snode, + FTC_GQuery gquery, + FTC_Cache cache ) + { + return ftc_snode_compare( FTC_NODE( snode ), gquery, cache ); + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/cache/ftcsbits.h b/mod/pub.mod/freetype.mod/src/cache/ftcsbits.h new file mode 100644 index 0000000..6261745 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/cache/ftcsbits.h @@ -0,0 +1,98 @@ +/***************************************************************************/ +/* */ +/* ftcsbits.h */ +/* */ +/* A small-bitmap cache (specification). */ +/* */ +/* Copyright 2000-2001, 2002, 2003, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTCSBITS_H__ +#define __FTCSBITS_H__ + + +#include <ft2build.h> +#include FT_CACHE_H +#include "ftcglyph.h" + + +FT_BEGIN_HEADER + +#define FTC_SBIT_ITEMS_PER_NODE 16 + + typedef struct FTC_SNodeRec_ + { + FTC_GNodeRec gnode; + FT_UInt count; + FTC_SBitRec sbits[FTC_SBIT_ITEMS_PER_NODE]; + + } FTC_SNodeRec, *FTC_SNode; + + +#define FTC_SNODE( x ) ( (FTC_SNode)( x ) ) +#define FTC_SNODE_GINDEX( x ) FTC_GNODE( x )->gindex +#define FTC_SNODE_FAMILY( x ) FTC_GNODE( x )->family + + typedef FT_UInt + (*FTC_SFamily_GetCountFunc)( FTC_Family family, + FTC_Manager manager ); + + typedef FT_Error + (*FTC_SFamily_LoadGlyphFunc)( FTC_Family family, + FT_UInt gindex, + FTC_Manager manager, + FT_Face *aface ); + + typedef struct FTC_SFamilyClassRec_ + { + FTC_MruListClassRec clazz; + FTC_SFamily_GetCountFunc family_get_count; + FTC_SFamily_LoadGlyphFunc family_load_glyph; + + } FTC_SFamilyClassRec; + + typedef const FTC_SFamilyClassRec* FTC_SFamilyClass; + +#define FTC_SFAMILY_CLASS( x ) ((FTC_SFamilyClass)(x)) + +#define FTC_CACHE__SFAMILY_CLASS( x ) \ + FTC_SFAMILY_CLASS( FTC_CACHE__GCACHE_CLASS( x )->family_class ) + + + FT_LOCAL( void ) + FTC_SNode_Free( FTC_SNode snode, + FTC_Cache cache ); + + FT_LOCAL( FT_Error ) + FTC_SNode_New( FTC_SNode *psnode, + FTC_GQuery gquery, + FTC_Cache cache ); + +#if 0 + FT_LOCAL( FT_ULong ) + FTC_SNode_Weight( FTC_SNode inode ); +#endif + + + FT_LOCAL( FT_Bool ) + FTC_SNode_Compare( FTC_SNode snode, + FTC_GQuery gquery, + FTC_Cache cache ); + + /* */ + +FT_END_HEADER + +#endif /* __FTCSBITS_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/cff/cff.c b/mod/pub.mod/freetype.mod/src/cff/cff.c new file mode 100644 index 0000000..fccfd44 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/cff/cff.c @@ -0,0 +1,30 @@ +/***************************************************************************/ +/* */ +/* cff.c */ +/* */ +/* FreeType OpenType driver component (body only). */ +/* */ +/* Copyright 1996-2001, 2002 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#define FT_MAKE_OPTION_SINGLE_OBJECT + +#include <ft2build.h> +#include "cffpic.c" +#include "cffdrivr.c" +#include "cffparse.c" +#include "cffload.c" +#include "cffobjs.c" +#include "cffgload.c" +#include "cffcmap.c" + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/cff/cffcmap.c b/mod/pub.mod/freetype.mod/src/cff/cffcmap.c new file mode 100644 index 0000000..46d603e --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/cff/cffcmap.c @@ -0,0 +1,219 @@ +/***************************************************************************/ +/* */ +/* cffcmap.c */ +/* */ +/* CFF character mapping table (cmap) support (body). */ +/* */ +/* Copyright 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include "cffcmap.h" +#include "cffload.h" + +#include "cfferrs.h" + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** CFF STANDARD (AND EXPERT) ENCODING CMAPS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_CALLBACK_DEF( FT_Error ) + cff_cmap_encoding_init( CFF_CMapStd cmap ) + { + TT_Face face = (TT_Face)FT_CMAP_FACE( cmap ); + CFF_Font cff = (CFF_Font)face->extra.data; + CFF_Encoding encoding = &cff->encoding; + + + cmap->gids = encoding->codes; + + return 0; + } + + + FT_CALLBACK_DEF( void ) + cff_cmap_encoding_done( CFF_CMapStd cmap ) + { + cmap->gids = NULL; + } + + + FT_CALLBACK_DEF( FT_UInt ) + cff_cmap_encoding_char_index( CFF_CMapStd cmap, + FT_UInt32 char_code ) + { + FT_UInt result = 0; + + + if ( char_code < 256 ) + result = cmap->gids[char_code]; + + return result; + } + + + FT_CALLBACK_DEF( FT_UInt32 ) + cff_cmap_encoding_char_next( CFF_CMapStd cmap, + FT_UInt32 *pchar_code ) + { + FT_UInt result = 0; + FT_UInt32 char_code = *pchar_code; + + + *pchar_code = 0; + + if ( char_code < 255 ) + { + FT_UInt code = (FT_UInt)(char_code + 1); + + + for (;;) + { + if ( code >= 256 ) + break; + + result = cmap->gids[code]; + if ( result != 0 ) + { + *pchar_code = code; + break; + } + + code++; + } + } + return result; + } + + + FT_DEFINE_CMAP_CLASS(cff_cmap_encoding_class_rec, + sizeof ( CFF_CMapStdRec ), + + (FT_CMap_InitFunc) cff_cmap_encoding_init, + (FT_CMap_DoneFunc) cff_cmap_encoding_done, + (FT_CMap_CharIndexFunc)cff_cmap_encoding_char_index, + (FT_CMap_CharNextFunc) cff_cmap_encoding_char_next, + + NULL, NULL, NULL, NULL, NULL + ) + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** CFF SYNTHETIC UNICODE ENCODING CMAP *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_CALLBACK_DEF( const char* ) + cff_sid_to_glyph_name( TT_Face face, + FT_UInt idx ) + { + CFF_Font cff = (CFF_Font)face->extra.data; + CFF_Charset charset = &cff->charset; + FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)cff->psnames; + FT_UInt sid = charset->sids[idx]; + + + return cff_index_get_sid_string( &cff->string_index, sid, psnames ); + } + + + FT_CALLBACK_DEF( void ) + cff_sid_free_glyph_name( TT_Face face, + const char* gname ) + { + FT_Memory memory = FT_FACE_MEMORY( face ); + + + FT_FREE( gname ); + } + + + FT_CALLBACK_DEF( FT_Error ) + cff_cmap_unicode_init( PS_Unicodes unicodes ) + { + TT_Face face = (TT_Face)FT_CMAP_FACE( unicodes ); + FT_Memory memory = FT_FACE_MEMORY( face ); + CFF_Font cff = (CFF_Font)face->extra.data; + CFF_Charset charset = &cff->charset; + FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)cff->psnames; + + + /* can't build Unicode map for CID-keyed font */ + if ( !charset->sids ) + return CFF_Err_Invalid_Argument; + + return psnames->unicodes_init( memory, + unicodes, + cff->num_glyphs, + (PS_GetGlyphNameFunc)&cff_sid_to_glyph_name, + (PS_FreeGlyphNameFunc)&cff_sid_free_glyph_name, + (FT_Pointer)face ); + } + + + FT_CALLBACK_DEF( void ) + cff_cmap_unicode_done( PS_Unicodes unicodes ) + { + FT_Face face = FT_CMAP_FACE( unicodes ); + FT_Memory memory = FT_FACE_MEMORY( face ); + + + FT_FREE( unicodes->maps ); + unicodes->num_maps = 0; + } + + + FT_CALLBACK_DEF( FT_UInt ) + cff_cmap_unicode_char_index( PS_Unicodes unicodes, + FT_UInt32 char_code ) + { + TT_Face face = (TT_Face)FT_CMAP_FACE( unicodes ); + CFF_Font cff = (CFF_Font)face->extra.data; + FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)cff->psnames; + + + return psnames->unicodes_char_index( unicodes, char_code ); + } + + + FT_CALLBACK_DEF( FT_UInt32 ) + cff_cmap_unicode_char_next( PS_Unicodes unicodes, + FT_UInt32 *pchar_code ) + { + TT_Face face = (TT_Face)FT_CMAP_FACE( unicodes ); + CFF_Font cff = (CFF_Font)face->extra.data; + FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)cff->psnames; + + + return psnames->unicodes_char_next( unicodes, pchar_code ); + } + + + FT_DEFINE_CMAP_CLASS(cff_cmap_unicode_class_rec, + sizeof ( PS_UnicodesRec ), + + (FT_CMap_InitFunc) cff_cmap_unicode_init, + (FT_CMap_DoneFunc) cff_cmap_unicode_done, + (FT_CMap_CharIndexFunc)cff_cmap_unicode_char_index, + (FT_CMap_CharNextFunc) cff_cmap_unicode_char_next, + + NULL, NULL, NULL, NULL, NULL + ) + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/cff/cffcmap.h b/mod/pub.mod/freetype.mod/src/cff/cffcmap.h new file mode 100644 index 0000000..3f7f67b --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/cff/cffcmap.h @@ -0,0 +1,67 @@ +/***************************************************************************/ +/* */ +/* cffcmap.h */ +/* */ +/* CFF character mapping table (cmap) support (specification). */ +/* */ +/* Copyright 2002, 2003, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __CFFCMAP_H__ +#define __CFFCMAP_H__ + +#include "cffobjs.h" + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** TYPE1 STANDARD (AND EXPERT) ENCODING CMAPS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* standard (and expert) encoding cmaps */ + typedef struct CFF_CMapStdRec_* CFF_CMapStd; + + typedef struct CFF_CMapStdRec_ + { + FT_CMapRec cmap; + FT_UShort* gids; /* up to 256 elements */ + + } CFF_CMapStdRec; + + + FT_DECLARE_CMAP_CLASS(cff_cmap_encoding_class_rec) + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** CFF SYNTHETIC UNICODE ENCODING CMAP *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* unicode (synthetic) cmaps */ + + FT_DECLARE_CMAP_CLASS(cff_cmap_unicode_class_rec) + + +FT_END_HEADER + +#endif /* __CFFCMAP_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/cff/cffdrivr.c b/mod/pub.mod/freetype.mod/src/cff/cffdrivr.c new file mode 100644 index 0000000..217adf2 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/cff/cffdrivr.c @@ -0,0 +1,690 @@ +/***************************************************************************/ +/* */ +/* cffdrivr.c */ +/* */ +/* OpenType font driver implementation (body). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_SFNT_H +#include FT_SERVICE_CID_H +#include FT_SERVICE_POSTSCRIPT_CMAPS_H +#include FT_SERVICE_POSTSCRIPT_INFO_H +#include FT_SERVICE_POSTSCRIPT_NAME_H +#include FT_SERVICE_TT_CMAP_H + +#include "cffdrivr.h" +#include "cffgload.h" +#include "cffload.h" +#include "cffcmap.h" +#include "cffparse.h" + +#include "cfferrs.h" +#include "cffpic.h" + +#include FT_SERVICE_XFREE86_NAME_H +#include FT_SERVICE_GLYPH_DICT_H + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_cffdriver + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** F A C E S ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + +#undef PAIR_TAG +#define PAIR_TAG( left, right ) ( ( (FT_ULong)left << 16 ) | \ + (FT_ULong)right ) + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* cff_get_kerning */ + /* */ + /* <Description> */ + /* A driver method used to return the kerning vector between two */ + /* glyphs of the same face. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face object. */ + /* */ + /* left_glyph :: The index of the left glyph in the kern pair. */ + /* */ + /* right_glyph :: The index of the right glyph in the kern pair. */ + /* */ + /* <Output> */ + /* kerning :: The kerning vector. This is in font units for */ + /* scalable formats, and in pixels for fixed-sizes */ + /* formats. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* Only horizontal layouts (left-to-right & right-to-left) are */ + /* supported by this function. Other layouts, or more sophisticated */ + /* kernings, are out of scope of this method (the basic driver */ + /* interface is meant to be simple). */ + /* */ + /* They can be implemented by format-specific interfaces. */ + /* */ + FT_CALLBACK_DEF( FT_Error ) + cff_get_kerning( FT_Face ttface, /* TT_Face */ + FT_UInt left_glyph, + FT_UInt right_glyph, + FT_Vector* kerning ) + { + TT_Face face = (TT_Face)ttface; + SFNT_Service sfnt = (SFNT_Service)face->sfnt; + + + kerning->x = 0; + kerning->y = 0; + + if ( sfnt ) + kerning->x = sfnt->get_kerning( face, left_glyph, right_glyph ); + + return CFF_Err_Ok; + } + + +#undef PAIR_TAG + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Load_Glyph */ + /* */ + /* <Description> */ + /* A driver method used to load a glyph within a given glyph slot. */ + /* */ + /* <Input> */ + /* slot :: A handle to the target slot object where the glyph */ + /* will be loaded. */ + /* */ + /* size :: A handle to the source face size at which the glyph */ + /* must be scaled, loaded, etc. */ + /* */ + /* glyph_index :: The index of the glyph in the font file. */ + /* */ + /* load_flags :: A flag indicating what to load for this glyph. The */ + /* FT_LOAD_??? constants can be used to control the */ + /* glyph loading process (e.g., whether the outline */ + /* should be scaled, whether to load bitmaps or not, */ + /* whether to hint the outline, etc). */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_CALLBACK_DEF( FT_Error ) + Load_Glyph( FT_GlyphSlot cffslot, /* CFF_GlyphSlot */ + FT_Size cffsize, /* CFF_Size */ + FT_UInt glyph_index, + FT_Int32 load_flags ) + { + FT_Error error; + CFF_GlyphSlot slot = (CFF_GlyphSlot)cffslot; + CFF_Size size = (CFF_Size)cffsize; + + + if ( !slot ) + return CFF_Err_Invalid_Slot_Handle; + + /* check whether we want a scaled outline or bitmap */ + if ( !size ) + load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; + + /* reset the size object if necessary */ + if ( load_flags & FT_LOAD_NO_SCALE ) + size = NULL; + + if ( size ) + { + /* these two objects must have the same parent */ + if ( cffsize->face != cffslot->face ) + return CFF_Err_Invalid_Face_Handle; + } + + /* now load the glyph outline if necessary */ + error = cff_slot_load( slot, size, glyph_index, load_flags ); + + /* force drop-out mode to 2 - irrelevant now */ + /* slot->outline.dropout_mode = 2; */ + + return error; + } + + + FT_CALLBACK_DEF( FT_Error ) + cff_get_advances( FT_Face face, + FT_UInt start, + FT_UInt count, + FT_Int32 flags, + FT_Fixed* advances ) + { + FT_UInt nn; + FT_Error error = CFF_Err_Ok; + FT_GlyphSlot slot = face->glyph; + + + flags |= (FT_UInt32)FT_LOAD_ADVANCE_ONLY; + + for ( nn = 0; nn < count; nn++ ) + { + error = Load_Glyph( slot, face->size, start + nn, flags ); + if ( error ) + break; + + advances[nn] = ( flags & FT_LOAD_VERTICAL_LAYOUT ) + ? slot->linearVertAdvance + : slot->linearHoriAdvance; + } + + return error; + } + + + /* + * GLYPH DICT SERVICE + * + */ + + static FT_Error + cff_get_glyph_name( CFF_Face face, + FT_UInt glyph_index, + FT_Pointer buffer, + FT_UInt buffer_max ) + { + CFF_Font font = (CFF_Font)face->extra.data; + FT_Memory memory = FT_FACE_MEMORY( face ); + FT_String* gname; + FT_UShort sid; + FT_Service_PsCMaps psnames; + FT_Error error; + + + FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); + if ( !psnames ) + { + FT_ERROR(( "cff_get_glyph_name:" + " cannot get glyph name from CFF & CEF fonts\n" + " " + " without the `PSNames' module\n" )); + error = CFF_Err_Unknown_File_Format; + goto Exit; + } + + /* first, locate the sid in the charset table */ + sid = font->charset.sids[glyph_index]; + + /* now, lookup the name itself */ + gname = cff_index_get_sid_string( &font->string_index, sid, psnames ); + + if ( gname ) + FT_STRCPYN( buffer, gname, buffer_max ); + + FT_FREE( gname ); + error = CFF_Err_Ok; + + Exit: + return error; + } + + + static FT_UInt + cff_get_name_index( CFF_Face face, + FT_String* glyph_name ) + { + CFF_Font cff; + CFF_Charset charset; + FT_Service_PsCMaps psnames; + FT_Memory memory = FT_FACE_MEMORY( face ); + FT_String* name; + FT_UShort sid; + FT_UInt i; + FT_Int result; + + + cff = (CFF_FontRec *)face->extra.data; + charset = &cff->charset; + + FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); + if ( !psnames ) + return 0; + + for ( i = 0; i < cff->num_glyphs; i++ ) + { + sid = charset->sids[i]; + + if ( sid > 390 ) + name = cff_index_get_name( &cff->string_index, sid - 391 ); + else + name = (FT_String *)psnames->adobe_std_strings( sid ); + + if ( !name ) + continue; + + result = ft_strcmp( glyph_name, name ); + + if ( sid > 390 ) + FT_FREE( name ); + + if ( !result ) + return i; + } + + return 0; + } + + + FT_DEFINE_SERVICE_GLYPHDICTREC(cff_service_glyph_dict, + (FT_GlyphDict_GetNameFunc) cff_get_glyph_name, + (FT_GlyphDict_NameIndexFunc)cff_get_name_index + ) + + + /* + * POSTSCRIPT INFO SERVICE + * + */ + + static FT_Int + cff_ps_has_glyph_names( FT_Face face ) + { + return ( face->face_flags & FT_FACE_FLAG_GLYPH_NAMES ) > 0; + } + + + static FT_Error + cff_ps_get_font_info( CFF_Face face, + PS_FontInfoRec* afont_info ) + { + CFF_Font cff = (CFF_Font)face->extra.data; + FT_Error error = FT_Err_Ok; + + + if ( cff && cff->font_info == NULL ) + { + CFF_FontRecDict dict = &cff->top_font.font_dict; + PS_FontInfoRec *font_info; + FT_Memory memory = face->root.memory; + FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)cff->psnames; + + + if ( FT_ALLOC( font_info, sizeof ( *font_info ) ) ) + goto Fail; + + font_info->version = cff_index_get_sid_string( &cff->string_index, + dict->version, + psnames ); + font_info->notice = cff_index_get_sid_string( &cff->string_index, + dict->notice, + psnames ); + font_info->full_name = cff_index_get_sid_string( &cff->string_index, + dict->full_name, + psnames ); + font_info->family_name = cff_index_get_sid_string( &cff->string_index, + dict->family_name, + psnames ); + font_info->weight = cff_index_get_sid_string( &cff->string_index, + dict->weight, + psnames ); + font_info->italic_angle = dict->italic_angle; + font_info->is_fixed_pitch = dict->is_fixed_pitch; + font_info->underline_position = (FT_Short)dict->underline_position; + font_info->underline_thickness = (FT_Short)dict->underline_thickness; + + cff->font_info = font_info; + } + + if ( cff ) + *afont_info = *cff->font_info; + + Fail: + return error; + } + + + FT_DEFINE_SERVICE_PSINFOREC(cff_service_ps_info, + (PS_GetFontInfoFunc) cff_ps_get_font_info, + (PS_GetFontExtraFunc) NULL, + (PS_HasGlyphNamesFunc) cff_ps_has_glyph_names, + (PS_GetFontPrivateFunc)NULL /* unsupported with CFF fonts */ + ) + + + /* + * POSTSCRIPT NAME SERVICE + * + */ + + static const char* + cff_get_ps_name( CFF_Face face ) + { + CFF_Font cff = (CFF_Font)face->extra.data; + + + return (const char*)cff->font_name; + } + + + FT_DEFINE_SERVICE_PSFONTNAMEREC(cff_service_ps_name, + (FT_PsName_GetFunc)cff_get_ps_name + ) + + + /* + * TT CMAP INFO + * + * If the charmap is a synthetic Unicode encoding cmap or + * a Type 1 standard (or expert) encoding cmap, hide TT CMAP INFO + * service defined in SFNT module. + * + * Otherwise call the service function in the sfnt module. + * + */ + static FT_Error + cff_get_cmap_info( FT_CharMap charmap, + TT_CMapInfo *cmap_info ) + { + FT_CMap cmap = FT_CMAP( charmap ); + FT_Error error = CFF_Err_Ok; + FT_Face face = FT_CMAP_FACE( cmap ); + FT_Library library = FT_FACE_LIBRARY( face ); + + + cmap_info->language = 0; + cmap_info->format = 0; + + if ( cmap->clazz != &FT_CFF_CMAP_ENCODING_CLASS_REC_GET && + cmap->clazz != &FT_CFF_CMAP_UNICODE_CLASS_REC_GET ) + { + FT_Module sfnt = FT_Get_Module( library, "sfnt" ); + FT_Service_TTCMaps service = + (FT_Service_TTCMaps)ft_module_get_service( sfnt, + FT_SERVICE_ID_TT_CMAP ); + + + if ( service && service->get_cmap_info ) + error = service->get_cmap_info( charmap, cmap_info ); + } + + return error; + } + + + FT_DEFINE_SERVICE_TTCMAPSREC(cff_service_get_cmap_info, + (TT_CMap_Info_GetFunc)cff_get_cmap_info + ) + + + /* + * CID INFO SERVICE + * + */ + static FT_Error + cff_get_ros( CFF_Face face, + const char* *registry, + const char* *ordering, + FT_Int *supplement ) + { + FT_Error error = CFF_Err_Ok; + CFF_Font cff = (CFF_Font)face->extra.data; + + + if ( cff ) + { + CFF_FontRecDict dict = &cff->top_font.font_dict; + FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)cff->psnames; + + + if ( dict->cid_registry == 0xFFFFU ) + { + error = CFF_Err_Invalid_Argument; + goto Fail; + } + + if ( registry ) + { + if ( cff->registry == NULL ) + cff->registry = cff_index_get_sid_string( &cff->string_index, + dict->cid_registry, + psnames ); + *registry = cff->registry; + } + + if ( ordering ) + { + if ( cff->ordering == NULL ) + cff->ordering = cff_index_get_sid_string( &cff->string_index, + dict->cid_ordering, + psnames ); + *ordering = cff->ordering; + } + + /* + * XXX: According to Adobe TechNote #5176, the supplement in CFF + * can be a real number. We truncate it to fit public API + * since freetype-2.3.6. + */ + if ( supplement ) + { + if ( dict->cid_supplement < FT_INT_MIN || + dict->cid_supplement > FT_INT_MAX ) + FT_TRACE1(( "cff_get_ros: too large supplement %d is truncated\n", + dict->cid_supplement )); + *supplement = (FT_Int)dict->cid_supplement; + } + } + + Fail: + return error; + } + + + static FT_Error + cff_get_is_cid( CFF_Face face, + FT_Bool *is_cid ) + { + FT_Error error = CFF_Err_Ok; + CFF_Font cff = (CFF_Font)face->extra.data; + + + *is_cid = 0; + + if ( cff ) + { + CFF_FontRecDict dict = &cff->top_font.font_dict; + + + if ( dict->cid_registry != 0xFFFFU ) + *is_cid = 1; + } + + return error; + } + + + static FT_Error + cff_get_cid_from_glyph_index( CFF_Face face, + FT_UInt glyph_index, + FT_UInt *cid ) + { + FT_Error error = CFF_Err_Ok; + CFF_Font cff; + + + cff = (CFF_Font)face->extra.data; + + if ( cff ) + { + FT_UInt c; + CFF_FontRecDict dict = &cff->top_font.font_dict; + + + if ( dict->cid_registry == 0xFFFFU ) + { + error = CFF_Err_Invalid_Argument; + goto Fail; + } + + if ( glyph_index > cff->num_glyphs ) + { + error = CFF_Err_Invalid_Argument; + goto Fail; + } + + c = cff->charset.sids[glyph_index]; + + if ( cid ) + *cid = c; + } + + Fail: + return error; + } + + + FT_DEFINE_SERVICE_CIDREC(cff_service_cid_info, + (FT_CID_GetRegistryOrderingSupplementFunc)cff_get_ros, + (FT_CID_GetIsInternallyCIDKeyedFunc) cff_get_is_cid, + (FT_CID_GetCIDFromGlyphIndexFunc) cff_get_cid_from_glyph_index + ) + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** D R I V E R I N T E R F A C E ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ +#ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES + FT_DEFINE_SERVICEDESCREC6(cff_services, + FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_CFF, + FT_SERVICE_ID_POSTSCRIPT_INFO, &FT_CFF_SERVICE_PS_INFO_GET, + FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_CFF_SERVICE_PS_NAME_GET, + FT_SERVICE_ID_GLYPH_DICT, &FT_CFF_SERVICE_GLYPH_DICT_GET, + FT_SERVICE_ID_TT_CMAP, &FT_CFF_SERVICE_GET_CMAP_INFO_GET, + FT_SERVICE_ID_CID, &FT_CFF_SERVICE_CID_INFO_GET + ) +#else + FT_DEFINE_SERVICEDESCREC5(cff_services, + FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_CFF, + FT_SERVICE_ID_POSTSCRIPT_INFO, &FT_CFF_SERVICE_PS_INFO_GET, + FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_CFF_SERVICE_PS_NAME_GET, + FT_SERVICE_ID_TT_CMAP, &FT_CFF_SERVICE_GET_CMAP_INFO_GET, + FT_SERVICE_ID_CID, &FT_CFF_SERVICE_CID_INFO_GET + ) +#endif + + FT_CALLBACK_DEF( FT_Module_Interface ) + cff_get_interface( FT_Module driver, /* CFF_Driver */ + const char* module_interface ) + { + FT_Module sfnt; + FT_Module_Interface result; + FT_Library library = driver->library; + FT_UNUSED(library); + + + result = ft_service_list_lookup( FT_CFF_SERVICES_GET, module_interface ); + if ( result != NULL ) + return result; + + /* we pass our request to the `sfnt' module */ + sfnt = FT_Get_Module( driver->library, "sfnt" ); + + return sfnt ? sfnt->clazz->get_interface( sfnt, module_interface ) : 0; + } + + + /* The FT_DriverInterface structure is defined in ftdriver.h. */ + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS +#define CFF_SIZE_SELECT cff_size_select +#else +#define CFF_SIZE_SELECT 0 +#endif + + FT_DEFINE_DRIVER(cff_driver_class, + FT_MODULE_FONT_DRIVER | + FT_MODULE_DRIVER_SCALABLE | + FT_MODULE_DRIVER_HAS_HINTER, + + sizeof( CFF_DriverRec ), + "cff", + 0x10000L, + 0x20000L, + + 0, /* module-specific interface */ + + cff_driver_init, + cff_driver_done, + cff_get_interface, + + /* now the specific driver fields */ + sizeof( TT_FaceRec ), + sizeof( CFF_SizeRec ), + sizeof( CFF_GlyphSlotRec ), + + cff_face_init, + cff_face_done, + cff_size_init, + cff_size_done, + cff_slot_init, + cff_slot_done, + + ft_stub_set_char_sizes, /* FT_CONFIG_OPTION_OLD_INTERNALS */ + ft_stub_set_pixel_sizes, /* FT_CONFIG_OPTION_OLD_INTERNALS */ + + Load_Glyph, + + cff_get_kerning, + 0, /* FT_Face_AttachFunc */ + cff_get_advances, /* FT_Face_GetAdvancesFunc */ + + cff_size_request, + + CFF_SIZE_SELECT + ) + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/cff/cffdrivr.h b/mod/pub.mod/freetype.mod/src/cff/cffdrivr.h new file mode 100644 index 0000000..50e8138 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/cff/cffdrivr.h @@ -0,0 +1,38 @@ +/***************************************************************************/ +/* */ +/* cffdrivr.h */ +/* */ +/* High-level OpenType driver interface (specification). */ +/* */ +/* Copyright 1996-2001, 2002 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __CFFDRIVER_H__ +#define __CFFDRIVER_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_DRIVER_H + + +FT_BEGIN_HEADER + + + FT_DECLARE_DRIVER( cff_driver_class ) + + +FT_END_HEADER + +#endif /* __CFFDRIVER_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/cff/cfferrs.h b/mod/pub.mod/freetype.mod/src/cff/cfferrs.h new file mode 100644 index 0000000..1b2a5c9 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/cff/cfferrs.h @@ -0,0 +1,41 @@ +/***************************************************************************/ +/* */ +/* cfferrs.h */ +/* */ +/* CFF error codes (specification only). */ +/* */ +/* Copyright 2001 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file is used to define the CFF error enumeration constants. */ + /* */ + /*************************************************************************/ + +#ifndef __CFFERRS_H__ +#define __CFFERRS_H__ + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#define FT_ERR_PREFIX CFF_Err_ +#define FT_ERR_BASE FT_Mod_Err_CFF + + +#include FT_ERRORS_H + +#endif /* __CFFERRS_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/cff/cffgload.c b/mod/pub.mod/freetype.mod/src/cff/cffgload.c new file mode 100644 index 0000000..40fa20b --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/cff/cffgload.c @@ -0,0 +1,2840 @@ +/***************************************************************************/ +/* */ +/* cffgload.c */ +/* */ +/* OpenType Glyph Loader (body). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_SFNT_H +#include FT_OUTLINE_H +#include FT_INTERNAL_POSTSCRIPT_HINTS_H + +#include "cffobjs.h" +#include "cffload.h" +#include "cffgload.h" + +#include "cfferrs.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_cffgload + + + typedef enum CFF_Operator_ + { + cff_op_unknown = 0, + + cff_op_rmoveto, + cff_op_hmoveto, + cff_op_vmoveto, + + cff_op_rlineto, + cff_op_hlineto, + cff_op_vlineto, + + cff_op_rrcurveto, + cff_op_hhcurveto, + cff_op_hvcurveto, + cff_op_rcurveline, + cff_op_rlinecurve, + cff_op_vhcurveto, + cff_op_vvcurveto, + + cff_op_flex, + cff_op_hflex, + cff_op_hflex1, + cff_op_flex1, + + cff_op_endchar, + + cff_op_hstem, + cff_op_vstem, + cff_op_hstemhm, + cff_op_vstemhm, + + cff_op_hintmask, + cff_op_cntrmask, + cff_op_dotsection, /* deprecated, acts as no-op */ + + cff_op_abs, + cff_op_add, + cff_op_sub, + cff_op_div, + cff_op_neg, + cff_op_random, + cff_op_mul, + cff_op_sqrt, + + cff_op_blend, + + cff_op_drop, + cff_op_exch, + cff_op_index, + cff_op_roll, + cff_op_dup, + + cff_op_put, + cff_op_get, + cff_op_store, + cff_op_load, + + cff_op_and, + cff_op_or, + cff_op_not, + cff_op_eq, + cff_op_ifelse, + + cff_op_callsubr, + cff_op_callgsubr, + cff_op_return, + + /* Type 1 opcodes: invalid but seen in real life */ + cff_op_hsbw, + cff_op_closepath, + cff_op_callothersubr, + cff_op_pop, + + /* do not remove */ + cff_op_max + + } CFF_Operator; + + +#define CFF_COUNT_CHECK_WIDTH 0x80 +#define CFF_COUNT_EXACT 0x40 +#define CFF_COUNT_CLEAR_STACK 0x20 + + /* count values which have the `CFF_COUNT_CHECK_WIDTH' flag set are */ + /* used for checking the width and requested numbers of arguments */ + /* only; they are set to zero afterwards */ + + /* the other two flags are informative only and unused currently */ + + static const FT_Byte cff_argument_counts[] = + { + 0, /* unknown */ + + 2 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT, /* rmoveto */ + 1 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT, + 1 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT, + + 0 | CFF_COUNT_CLEAR_STACK, /* rlineto */ + 0 | CFF_COUNT_CLEAR_STACK, + 0 | CFF_COUNT_CLEAR_STACK, + + 0 | CFF_COUNT_CLEAR_STACK, /* rrcurveto */ + 0 | CFF_COUNT_CLEAR_STACK, + 0 | CFF_COUNT_CLEAR_STACK, + 0 | CFF_COUNT_CLEAR_STACK, + 0 | CFF_COUNT_CLEAR_STACK, + 0 | CFF_COUNT_CLEAR_STACK, + 0 | CFF_COUNT_CLEAR_STACK, + + 13, /* flex */ + 7, + 9, + 11, + + 0 | CFF_COUNT_CHECK_WIDTH, /* endchar */ + + 2 | CFF_COUNT_CHECK_WIDTH, /* hstem */ + 2 | CFF_COUNT_CHECK_WIDTH, + 2 | CFF_COUNT_CHECK_WIDTH, + 2 | CFF_COUNT_CHECK_WIDTH, + + 0 | CFF_COUNT_CHECK_WIDTH, /* hintmask */ + 0 | CFF_COUNT_CHECK_WIDTH, /* cntrmask */ + 0, /* dotsection */ + + 1, /* abs */ + 2, + 2, + 2, + 1, + 0, + 2, + 1, + + 1, /* blend */ + + 1, /* drop */ + 2, + 1, + 2, + 1, + + 2, /* put */ + 1, + 4, + 3, + + 2, /* and */ + 2, + 1, + 2, + 4, + + 1, /* callsubr */ + 1, + 0, + + 2, /* hsbw */ + 0, + 0, + 0 + }; + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /********** *********/ + /********** *********/ + /********** GENERIC CHARSTRING PARSING *********/ + /********** *********/ + /********** *********/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* cff_builder_init */ + /* */ + /* <Description> */ + /* Initializes a given glyph builder. */ + /* */ + /* <InOut> */ + /* builder :: A pointer to the glyph builder to initialize. */ + /* */ + /* <Input> */ + /* face :: The current face object. */ + /* */ + /* size :: The current size object. */ + /* */ + /* glyph :: The current glyph object. */ + /* */ + /* hinting :: Whether hinting is active. */ + /* */ + static void + cff_builder_init( CFF_Builder* builder, + TT_Face face, + CFF_Size size, + CFF_GlyphSlot glyph, + FT_Bool hinting ) + { + builder->path_begun = 0; + builder->load_points = 1; + + builder->face = face; + builder->glyph = glyph; + builder->memory = face->root.memory; + + if ( glyph ) + { + FT_GlyphLoader loader = glyph->root.internal->loader; + + + builder->loader = loader; + builder->base = &loader->base.outline; + builder->current = &loader->current.outline; + FT_GlyphLoader_Rewind( loader ); + + builder->hints_globals = 0; + builder->hints_funcs = 0; + + if ( hinting && size ) + { + CFF_Internal internal = (CFF_Internal)size->root.internal; + + + builder->hints_globals = (void *)internal->topfont; + builder->hints_funcs = glyph->root.internal->glyph_hints; + } + } + + builder->pos_x = 0; + builder->pos_y = 0; + + builder->left_bearing.x = 0; + builder->left_bearing.y = 0; + builder->advance.x = 0; + builder->advance.y = 0; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* cff_builder_done */ + /* */ + /* <Description> */ + /* Finalizes a given glyph builder. Its contents can still be used */ + /* after the call, but the function saves important information */ + /* within the corresponding glyph slot. */ + /* */ + /* <Input> */ + /* builder :: A pointer to the glyph builder to finalize. */ + /* */ + static void + cff_builder_done( CFF_Builder* builder ) + { + CFF_GlyphSlot glyph = builder->glyph; + + + if ( glyph ) + glyph->root.outline = *builder->base; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* cff_compute_bias */ + /* */ + /* <Description> */ + /* Computes the bias value in dependence of the number of glyph */ + /* subroutines. */ + /* */ + /* <Input> */ + /* num_subrs :: The number of glyph subroutines. */ + /* */ + /* <Return> */ + /* The bias value. */ + static FT_Int + cff_compute_bias( FT_UInt num_subrs ) + { + FT_Int result; + + + if ( num_subrs < 1240 ) + result = 107; + else if ( num_subrs < 33900U ) + result = 1131; + else + result = 32768U; + + return result; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* cff_decoder_init */ + /* */ + /* <Description> */ + /* Initializes a given glyph decoder. */ + /* */ + /* <InOut> */ + /* decoder :: A pointer to the glyph builder to initialize. */ + /* */ + /* <Input> */ + /* face :: The current face object. */ + /* */ + /* size :: The current size object. */ + /* */ + /* slot :: The current glyph object. */ + /* */ + /* hinting :: Whether hinting is active. */ + /* */ + /* hint_mode :: The hinting mode. */ + /* */ + FT_LOCAL_DEF( void ) + cff_decoder_init( CFF_Decoder* decoder, + TT_Face face, + CFF_Size size, + CFF_GlyphSlot slot, + FT_Bool hinting, + FT_Render_Mode hint_mode ) + { + CFF_Font cff = (CFF_Font)face->extra.data; + + + /* clear everything */ + FT_MEM_ZERO( decoder, sizeof ( *decoder ) ); + + /* initialize builder */ + cff_builder_init( &decoder->builder, face, size, slot, hinting ); + + /* initialize Type2 decoder */ + decoder->num_globals = cff->num_global_subrs; + decoder->globals = cff->global_subrs; + decoder->globals_bias = cff_compute_bias( decoder->num_globals ); + + decoder->hint_mode = hint_mode; + } + + + /* this function is used to select the subfont */ + /* and the locals subrs array */ + FT_LOCAL_DEF( FT_Error ) + cff_decoder_prepare( CFF_Decoder* decoder, + CFF_Size size, + FT_UInt glyph_index ) + { + CFF_Builder *builder = &decoder->builder; + CFF_Font cff = (CFF_Font)builder->face->extra.data; + CFF_SubFont sub = &cff->top_font; + FT_Error error = CFF_Err_Ok; + + + /* manage CID fonts */ + if ( cff->num_subfonts ) + { + FT_Byte fd_index = cff_fd_select_get( &cff->fd_select, glyph_index ); + + + if ( fd_index >= cff->num_subfonts ) + { + FT_TRACE4(( "cff_decoder_prepare: invalid CID subfont index\n" )); + error = CFF_Err_Invalid_File_Format; + goto Exit; + } + + FT_TRACE4(( "glyph index %d (subfont %d):\n", glyph_index, fd_index )); + + sub = cff->subfonts[fd_index]; + + if ( builder->hints_funcs && size ) + { + CFF_Internal internal = (CFF_Internal)size->root.internal; + + + /* for CFFs without subfonts, this value has already been set */ + builder->hints_globals = (void *)internal->subfonts[fd_index]; + } + } +#ifdef FT_DEBUG_LEVEL_TRACE + else + FT_TRACE4(( "glyph index %d:\n", glyph_index )); +#endif + + decoder->num_locals = sub->num_local_subrs; + decoder->locals = sub->local_subrs; + decoder->locals_bias = cff_compute_bias( decoder->num_locals ); + + decoder->glyph_width = sub->private_dict.default_width; + decoder->nominal_width = sub->private_dict.nominal_width; + + Exit: + return error; + } + + + /* check that there is enough space for `count' more points */ + static FT_Error + check_points( CFF_Builder* builder, + FT_Int count ) + { + return FT_GLYPHLOADER_CHECK_POINTS( builder->loader, count, 0 ); + } + + + /* add a new point, do not check space */ + static void + cff_builder_add_point( CFF_Builder* builder, + FT_Pos x, + FT_Pos y, + FT_Byte flag ) + { + FT_Outline* outline = builder->current; + + + if ( builder->load_points ) + { + FT_Vector* point = outline->points + outline->n_points; + FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points; + + + point->x = x >> 16; + point->y = y >> 16; + *control = (FT_Byte)( flag ? FT_CURVE_TAG_ON : FT_CURVE_TAG_CUBIC ); + } + + outline->n_points++; + } + + + /* check space for a new on-curve point, then add it */ + static FT_Error + cff_builder_add_point1( CFF_Builder* builder, + FT_Pos x, + FT_Pos y ) + { + FT_Error error; + + + error = check_points( builder, 1 ); + if ( !error ) + cff_builder_add_point( builder, x, y, 1 ); + + return error; + } + + + /* check space for a new contour, then add it */ + static FT_Error + cff_builder_add_contour( CFF_Builder* builder ) + { + FT_Outline* outline = builder->current; + FT_Error error; + + + if ( !builder->load_points ) + { + outline->n_contours++; + return CFF_Err_Ok; + } + + error = FT_GLYPHLOADER_CHECK_POINTS( builder->loader, 0, 1 ); + if ( !error ) + { + if ( outline->n_contours > 0 ) + outline->contours[outline->n_contours - 1] = + (short)( outline->n_points - 1 ); + + outline->n_contours++; + } + + return error; + } + + + /* if a path was begun, add its first on-curve point */ + static FT_Error + cff_builder_start_point( CFF_Builder* builder, + FT_Pos x, + FT_Pos y ) + { + FT_Error error = CFF_Err_Ok; + + + /* test whether we are building a new contour */ + if ( !builder->path_begun ) + { + builder->path_begun = 1; + error = cff_builder_add_contour( builder ); + if ( !error ) + error = cff_builder_add_point1( builder, x, y ); + } + + return error; + } + + + /* close the current contour */ + static void + cff_builder_close_contour( CFF_Builder* builder ) + { + FT_Outline* outline = builder->current; + FT_Int first; + + + if ( !outline ) + return; + + first = outline->n_contours <= 1 + ? 0 : outline->contours[outline->n_contours - 2] + 1; + + /* We must not include the last point in the path if it */ + /* is located on the first point. */ + if ( outline->n_points > 1 ) + { + FT_Vector* p1 = outline->points + first; + FT_Vector* p2 = outline->points + outline->n_points - 1; + FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points - 1; + + + /* `delete' last point only if it coincides with the first */ + /* point and if it is not a control point (which can happen). */ + if ( p1->x == p2->x && p1->y == p2->y ) + if ( *control == FT_CURVE_TAG_ON ) + outline->n_points--; + } + + if ( outline->n_contours > 0 ) + { + /* Don't add contours only consisting of one point, i.e., */ + /* check whether begin point and last point are the same. */ + if ( first == outline->n_points - 1 ) + { + outline->n_contours--; + outline->n_points--; + } + else + outline->contours[outline->n_contours - 1] = + (short)( outline->n_points - 1 ); + } + } + + + static FT_Int + cff_lookup_glyph_by_stdcharcode( CFF_Font cff, + FT_Int charcode ) + { + FT_UInt n; + FT_UShort glyph_sid; + + + /* CID-keyed fonts don't have glyph names */ + if ( !cff->charset.sids ) + return -1; + + /* check range of standard char code */ + if ( charcode < 0 || charcode > 255 ) + return -1; + + /* Get code to SID mapping from `cff_standard_encoding'. */ + glyph_sid = cff_get_standard_encoding( (FT_UInt)charcode ); + + for ( n = 0; n < cff->num_glyphs; n++ ) + { + if ( cff->charset.sids[n] == glyph_sid ) + return n; + } + + return -1; + } + + + static FT_Error + cff_get_glyph_data( TT_Face face, + FT_UInt glyph_index, + FT_Byte** pointer, + FT_ULong* length ) + { +#ifdef FT_CONFIG_OPTION_INCREMENTAL + /* For incremental fonts get the character data using the */ + /* callback function. */ + if ( face->root.internal->incremental_interface ) + { + FT_Data data; + FT_Error error = + face->root.internal->incremental_interface->funcs->get_glyph_data( + face->root.internal->incremental_interface->object, + glyph_index, &data ); + + + *pointer = (FT_Byte*)data.pointer; + *length = data.length; + + return error; + } + else +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ + + { + CFF_Font cff = (CFF_Font)(face->extra.data); + + + return cff_index_access_element( &cff->charstrings_index, glyph_index, + pointer, length ); + } + } + + + static void + cff_free_glyph_data( TT_Face face, + FT_Byte** pointer, + FT_ULong length ) + { +#ifndef FT_CONFIG_OPTION_INCREMENTAL + FT_UNUSED( length ); +#endif + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + /* For incremental fonts get the character data using the */ + /* callback function. */ + if ( face->root.internal->incremental_interface ) + { + FT_Data data; + + + data.pointer = *pointer; + data.length = length; + + face->root.internal->incremental_interface->funcs->free_glyph_data( + face->root.internal->incremental_interface->object,&data ); + } + else +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ + + { + CFF_Font cff = (CFF_Font)(face->extra.data); + + + cff_index_forget_element( &cff->charstrings_index, pointer ); + } + } + + + static FT_Error + cff_operator_seac( CFF_Decoder* decoder, + FT_Pos adx, + FT_Pos ady, + FT_Int bchar, + FT_Int achar ) + { + FT_Error error; + CFF_Builder* builder = &decoder->builder; + FT_Int bchar_index, achar_index; + TT_Face face = decoder->builder.face; + FT_Vector left_bearing, advance; + FT_Byte* charstring; + FT_ULong charstring_len; + + + if ( decoder->seac ) + { + FT_ERROR(( "cff_operator_seac: invalid nested seac\n" )); + return CFF_Err_Syntax_Error; + } + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + /* Incremental fonts don't necessarily have valid charsets. */ + /* They use the character code, not the glyph index, in this case. */ + if ( face->root.internal->incremental_interface ) + { + bchar_index = bchar; + achar_index = achar; + } + else +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ + { + CFF_Font cff = (CFF_Font)(face->extra.data); + + + bchar_index = cff_lookup_glyph_by_stdcharcode( cff, bchar ); + achar_index = cff_lookup_glyph_by_stdcharcode( cff, achar ); + } + + if ( bchar_index < 0 || achar_index < 0 ) + { + FT_ERROR(( "cff_operator_seac:" + " invalid seac character code arguments\n" )); + return CFF_Err_Syntax_Error; + } + + /* If we are trying to load a composite glyph, do not load the */ + /* accent character and return the array of subglyphs. */ + if ( builder->no_recurse ) + { + FT_GlyphSlot glyph = (FT_GlyphSlot)builder->glyph; + FT_GlyphLoader loader = glyph->internal->loader; + FT_SubGlyph subg; + + + /* reallocate subglyph array if necessary */ + error = FT_GlyphLoader_CheckSubGlyphs( loader, 2 ); + if ( error ) + goto Exit; + + subg = loader->current.subglyphs; + + /* subglyph 0 = base character */ + subg->index = bchar_index; + subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES | + FT_SUBGLYPH_FLAG_USE_MY_METRICS; + subg->arg1 = 0; + subg->arg2 = 0; + subg++; + + /* subglyph 1 = accent character */ + subg->index = achar_index; + subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES; + subg->arg1 = (FT_Int)( adx >> 16 ); + subg->arg2 = (FT_Int)( ady >> 16 ); + + /* set up remaining glyph fields */ + glyph->num_subglyphs = 2; + glyph->subglyphs = loader->base.subglyphs; + glyph->format = FT_GLYPH_FORMAT_COMPOSITE; + + loader->current.num_subglyphs = 2; + } + + FT_GlyphLoader_Prepare( builder->loader ); + + /* First load `bchar' in builder */ + error = cff_get_glyph_data( face, bchar_index, + &charstring, &charstring_len ); + if ( !error ) + { + /* the seac operator must not be nested */ + decoder->seac = TRUE; + error = cff_decoder_parse_charstrings( decoder, charstring, + charstring_len ); + decoder->seac = FALSE; + + if ( error ) + goto Exit; + + cff_free_glyph_data( face, &charstring, charstring_len ); + } + + /* Save the left bearing and width of the base character */ + /* as they will be erased by the next load. */ + + left_bearing = builder->left_bearing; + advance = builder->advance; + + builder->left_bearing.x = 0; + builder->left_bearing.y = 0; + + builder->pos_x = adx; + builder->pos_y = ady; + + /* Now load `achar' on top of the base outline. */ + error = cff_get_glyph_data( face, achar_index, + &charstring, &charstring_len ); + if ( !error ) + { + /* the seac operator must not be nested */ + decoder->seac = TRUE; + error = cff_decoder_parse_charstrings( decoder, charstring, + charstring_len ); + decoder->seac = FALSE; + + if ( error ) + goto Exit; + + cff_free_glyph_data( face, &charstring, charstring_len ); + } + + /* Restore the left side bearing and advance width */ + /* of the base character. */ + builder->left_bearing = left_bearing; + builder->advance = advance; + + builder->pos_x = 0; + builder->pos_y = 0; + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* cff_decoder_parse_charstrings */ + /* */ + /* <Description> */ + /* Parses a given Type 2 charstrings program. */ + /* */ + /* <InOut> */ + /* decoder :: The current Type 1 decoder. */ + /* */ + /* <Input> */ + /* charstring_base :: The base of the charstring stream. */ + /* */ + /* charstring_len :: The length in bytes of the charstring stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + cff_decoder_parse_charstrings( CFF_Decoder* decoder, + FT_Byte* charstring_base, + FT_ULong charstring_len ) + { + FT_Error error; + CFF_Decoder_Zone* zone; + FT_Byte* ip; + FT_Byte* limit; + CFF_Builder* builder = &decoder->builder; + FT_Pos x, y; + FT_Fixed seed; + FT_Fixed* stack; + + T2_Hints_Funcs hinter; + + + /* set default width */ + decoder->num_hints = 0; + decoder->read_width = 1; + + /* compute random seed from stack address of parameter */ + seed = (FT_Fixed)( ( (FT_PtrDist)(char*)&seed ^ + (FT_PtrDist)(char*)&decoder ^ + (FT_PtrDist)(char*)&charstring_base ) & + FT_ULONG_MAX ) ; + seed = ( seed ^ ( seed >> 10 ) ^ ( seed >> 20 ) ) & 0xFFFFL; + if ( seed == 0 ) + seed = 0x7384; + + /* initialize the decoder */ + decoder->top = decoder->stack; + decoder->zone = decoder->zones; + zone = decoder->zones; + stack = decoder->top; + + hinter = (T2_Hints_Funcs)builder->hints_funcs; + + builder->path_begun = 0; + + zone->base = charstring_base; + limit = zone->limit = charstring_base + charstring_len; + ip = zone->cursor = zone->base; + + error = CFF_Err_Ok; + + x = builder->pos_x; + y = builder->pos_y; + + /* begin hints recording session, if any */ + if ( hinter ) + hinter->open( hinter->hints ); + + /* now execute loop */ + while ( ip < limit ) + { + CFF_Operator op; + FT_Byte v; + + + /********************************************************************/ + /* */ + /* Decode operator or operand */ + /* */ + v = *ip++; + if ( v >= 32 || v == 28 ) + { + FT_Int shift = 16; + FT_Int32 val; + + + /* this is an operand, push it on the stack */ + if ( v == 28 ) + { + if ( ip + 1 >= limit ) + goto Syntax_Error; + val = (FT_Short)( ( (FT_Short)ip[0] << 8 ) | ip[1] ); + ip += 2; + } + else if ( v < 247 ) + val = (FT_Int32)v - 139; + else if ( v < 251 ) + { + if ( ip >= limit ) + goto Syntax_Error; + val = ( (FT_Int32)v - 247 ) * 256 + *ip++ + 108; + } + else if ( v < 255 ) + { + if ( ip >= limit ) + goto Syntax_Error; + val = -( (FT_Int32)v - 251 ) * 256 - *ip++ - 108; + } + else + { + if ( ip + 3 >= limit ) + goto Syntax_Error; + val = ( (FT_Int32)ip[0] << 24 ) | + ( (FT_Int32)ip[1] << 16 ) | + ( (FT_Int32)ip[2] << 8 ) | + ip[3]; + ip += 4; + shift = 0; + } + if ( decoder->top - stack >= CFF_MAX_OPERANDS ) + goto Stack_Overflow; + + val <<= shift; + *decoder->top++ = val; + +#ifdef FT_DEBUG_LEVEL_TRACE + if ( !( val & 0xFFFFL ) ) + FT_TRACE4(( " %ld", (FT_Int32)( val >> 16 ) )); + else + FT_TRACE4(( " %.2f", val / 65536.0 )); +#endif + + } + else + { + /* The specification says that normally arguments are to be taken */ + /* from the bottom of the stack. However, this seems not to be */ + /* correct, at least for Acroread 7.0.8 on GNU/Linux: It pops the */ + /* arguments similar to a PS interpreter. */ + + FT_Fixed* args = decoder->top; + FT_Int num_args = (FT_Int)( args - decoder->stack ); + FT_Int req_args; + + + /* find operator */ + op = cff_op_unknown; + + switch ( v ) + { + case 1: + op = cff_op_hstem; + break; + case 3: + op = cff_op_vstem; + break; + case 4: + op = cff_op_vmoveto; + break; + case 5: + op = cff_op_rlineto; + break; + case 6: + op = cff_op_hlineto; + break; + case 7: + op = cff_op_vlineto; + break; + case 8: + op = cff_op_rrcurveto; + break; + case 9: + op = cff_op_closepath; + break; + case 10: + op = cff_op_callsubr; + break; + case 11: + op = cff_op_return; + break; + case 12: + { + if ( ip >= limit ) + goto Syntax_Error; + v = *ip++; + + switch ( v ) + { + case 0: + op = cff_op_dotsection; + break; + case 3: + op = cff_op_and; + break; + case 4: + op = cff_op_or; + break; + case 5: + op = cff_op_not; + break; + case 8: + op = cff_op_store; + break; + case 9: + op = cff_op_abs; + break; + case 10: + op = cff_op_add; + break; + case 11: + op = cff_op_sub; + break; + case 12: + op = cff_op_div; + break; + case 13: + op = cff_op_load; + break; + case 14: + op = cff_op_neg; + break; + case 15: + op = cff_op_eq; + break; + case 16: + op = cff_op_callothersubr; + break; + case 17: + op = cff_op_pop; + break; + case 18: + op = cff_op_drop; + break; + case 20: + op = cff_op_put; + break; + case 21: + op = cff_op_get; + break; + case 22: + op = cff_op_ifelse; + break; + case 23: + op = cff_op_random; + break; + case 24: + op = cff_op_mul; + break; + case 26: + op = cff_op_sqrt; + break; + case 27: + op = cff_op_dup; + break; + case 28: + op = cff_op_exch; + break; + case 29: + op = cff_op_index; + break; + case 30: + op = cff_op_roll; + break; + case 34: + op = cff_op_hflex; + break; + case 35: + op = cff_op_flex; + break; + case 36: + op = cff_op_hflex1; + break; + case 37: + op = cff_op_flex1; + break; + default: + /* decrement ip for syntax error message */ + ip--; + } + } + break; + case 13: + op = cff_op_hsbw; + break; + case 14: + op = cff_op_endchar; + break; + case 16: + op = cff_op_blend; + break; + case 18: + op = cff_op_hstemhm; + break; + case 19: + op = cff_op_hintmask; + break; + case 20: + op = cff_op_cntrmask; + break; + case 21: + op = cff_op_rmoveto; + break; + case 22: + op = cff_op_hmoveto; + break; + case 23: + op = cff_op_vstemhm; + break; + case 24: + op = cff_op_rcurveline; + break; + case 25: + op = cff_op_rlinecurve; + break; + case 26: + op = cff_op_vvcurveto; + break; + case 27: + op = cff_op_hhcurveto; + break; + case 29: + op = cff_op_callgsubr; + break; + case 30: + op = cff_op_vhcurveto; + break; + case 31: + op = cff_op_hvcurveto; + break; + default: + ; + } + + if ( op == cff_op_unknown ) + goto Syntax_Error; + + /* check arguments */ + req_args = cff_argument_counts[op]; + if ( req_args & CFF_COUNT_CHECK_WIDTH ) + { + if ( num_args > 0 && decoder->read_width ) + { + /* If `nominal_width' is non-zero, the number is really a */ + /* difference against `nominal_width'. Else, the number here */ + /* is truly a width, not a difference against `nominal_width'. */ + /* If the font does not set `nominal_width', then */ + /* `nominal_width' defaults to zero, and so we can set */ + /* `glyph_width' to `nominal_width' plus number on the stack */ + /* -- for either case. */ + + FT_Int set_width_ok; + + + switch ( op ) + { + case cff_op_hmoveto: + case cff_op_vmoveto: + set_width_ok = num_args & 2; + break; + + case cff_op_hstem: + case cff_op_vstem: + case cff_op_hstemhm: + case cff_op_vstemhm: + case cff_op_rmoveto: + case cff_op_hintmask: + case cff_op_cntrmask: + set_width_ok = num_args & 1; + break; + + case cff_op_endchar: + /* If there is a width specified for endchar, we either have */ + /* 1 argument or 5 arguments. We like to argue. */ + set_width_ok = ( num_args == 5 ) || ( num_args == 1 ); + break; + + default: + set_width_ok = 0; + break; + } + + if ( set_width_ok ) + { + decoder->glyph_width = decoder->nominal_width + + ( stack[0] >> 16 ); + + if ( decoder->width_only ) + { + /* we only want the advance width; stop here */ + break; + } + + /* Consumed an argument. */ + num_args--; + } + } + + decoder->read_width = 0; + req_args = 0; + } + + req_args &= 0x000F; + if ( num_args < req_args ) + goto Stack_Underflow; + args -= req_args; + num_args -= req_args; + + /* At this point, `args' points to the first argument of the */ + /* operand in case `req_args' isn't zero. Otherwise, we have */ + /* to adjust `args' manually. */ + + /* Note that we only pop arguments from the stack which we */ + /* really need and can digest so that we can continue in case */ + /* of superfluous stack elements. */ + + switch ( op ) + { + case cff_op_hstem: + case cff_op_vstem: + case cff_op_hstemhm: + case cff_op_vstemhm: + /* the number of arguments is always even here */ + FT_TRACE4(( + op == cff_op_hstem ? " hstem\n" : + ( op == cff_op_vstem ? " vstem\n" : + ( op == cff_op_hstemhm ? " hstemhm\n" : " vstemhm\n" ) ) )); + + if ( hinter ) + hinter->stems( hinter->hints, + ( op == cff_op_hstem || op == cff_op_hstemhm ), + num_args / 2, + args - ( num_args & ~1 ) ); + + decoder->num_hints += num_args / 2; + args = stack; + break; + + case cff_op_hintmask: + case cff_op_cntrmask: + FT_TRACE4(( op == cff_op_hintmask ? " hintmask" : " cntrmask" )); + + /* implement vstem when needed -- */ + /* the specification doesn't say it, but this also works */ + /* with the 'cntrmask' operator */ + /* */ + if ( num_args > 0 ) + { + if ( hinter ) + hinter->stems( hinter->hints, + 0, + num_args / 2, + args - ( num_args & ~1 ) ); + + decoder->num_hints += num_args / 2; + } + + if ( hinter ) + { + if ( op == cff_op_hintmask ) + hinter->hintmask( hinter->hints, + builder->current->n_points, + decoder->num_hints, + ip ); + else + hinter->counter( hinter->hints, + decoder->num_hints, + ip ); + } + +#ifdef FT_DEBUG_LEVEL_TRACE + { + FT_UInt maskbyte; + + + FT_TRACE4(( " (maskbytes: " )); + + for ( maskbyte = 0; + maskbyte < (FT_UInt)(( decoder->num_hints + 7 ) >> 3); + maskbyte++, ip++ ) + FT_TRACE4(( "0x%02X", *ip )); + + FT_TRACE4(( ")\n" )); + } +#else + ip += ( decoder->num_hints + 7 ) >> 3; +#endif + if ( ip >= limit ) + goto Syntax_Error; + args = stack; + break; + + case cff_op_rmoveto: + FT_TRACE4(( " rmoveto\n" )); + + cff_builder_close_contour( builder ); + builder->path_begun = 0; + x += args[-2]; + y += args[-1]; + args = stack; + break; + + case cff_op_vmoveto: + FT_TRACE4(( " vmoveto\n" )); + + cff_builder_close_contour( builder ); + builder->path_begun = 0; + y += args[-1]; + args = stack; + break; + + case cff_op_hmoveto: + FT_TRACE4(( " hmoveto\n" )); + + cff_builder_close_contour( builder ); + builder->path_begun = 0; + x += args[-1]; + args = stack; + break; + + case cff_op_rlineto: + FT_TRACE4(( " rlineto\n" )); + + if ( cff_builder_start_point ( builder, x, y ) || + check_points( builder, num_args / 2 ) ) + goto Fail; + + if ( num_args < 2 ) + goto Stack_Underflow; + + args -= num_args & ~1; + while ( args < decoder->top ) + { + x += args[0]; + y += args[1]; + cff_builder_add_point( builder, x, y, 1 ); + args += 2; + } + args = stack; + break; + + case cff_op_hlineto: + case cff_op_vlineto: + { + FT_Int phase = ( op == cff_op_hlineto ); + + + FT_TRACE4(( op == cff_op_hlineto ? " hlineto\n" + : " vlineto\n" )); + + if ( num_args < 1 ) + goto Stack_Underflow; + + if ( cff_builder_start_point ( builder, x, y ) || + check_points( builder, num_args ) ) + goto Fail; + + args = stack; + while ( args < decoder->top ) + { + if ( phase ) + x += args[0]; + else + y += args[0]; + + if ( cff_builder_add_point1( builder, x, y ) ) + goto Fail; + + args++; + phase ^= 1; + } + args = stack; + } + break; + + case cff_op_rrcurveto: + { + FT_Int nargs; + + + FT_TRACE4(( " rrcurveto\n" )); + + if ( num_args < 6 ) + goto Stack_Underflow; + + nargs = num_args - num_args % 6; + + if ( cff_builder_start_point ( builder, x, y ) || + check_points( builder, nargs / 2 ) ) + goto Fail; + + args -= nargs; + while ( args < decoder->top ) + { + x += args[0]; + y += args[1]; + cff_builder_add_point( builder, x, y, 0 ); + x += args[2]; + y += args[3]; + cff_builder_add_point( builder, x, y, 0 ); + x += args[4]; + y += args[5]; + cff_builder_add_point( builder, x, y, 1 ); + args += 6; + } + args = stack; + } + break; + + case cff_op_vvcurveto: + { + FT_Int nargs; + + + FT_TRACE4(( " vvcurveto\n" )); + + if ( num_args < 4 ) + goto Stack_Underflow; + + /* if num_args isn't of the form 4n or 4n+1, */ + /* we reduce it to 4n+1 */ + + nargs = num_args - num_args % 4; + if ( num_args - nargs > 0 ) + nargs += 1; + + if ( cff_builder_start_point( builder, x, y ) ) + goto Fail; + + args -= nargs; + + if ( nargs & 1 ) + { + x += args[0]; + args++; + nargs--; + } + + if ( check_points( builder, 3 * ( nargs / 4 ) ) ) + goto Fail; + + while ( args < decoder->top ) + { + y += args[0]; + cff_builder_add_point( builder, x, y, 0 ); + x += args[1]; + y += args[2]; + cff_builder_add_point( builder, x, y, 0 ); + y += args[3]; + cff_builder_add_point( builder, x, y, 1 ); + args += 4; + } + args = stack; + } + break; + + case cff_op_hhcurveto: + { + FT_Int nargs; + + + FT_TRACE4(( " hhcurveto\n" )); + + if ( num_args < 4 ) + goto Stack_Underflow; + + /* if num_args isn't of the form 4n or 4n+1, */ + /* we reduce it to 4n+1 */ + + nargs = num_args - num_args % 4; + if ( num_args - nargs > 0 ) + nargs += 1; + + if ( cff_builder_start_point( builder, x, y ) ) + goto Fail; + + args -= nargs; + if ( nargs & 1 ) + { + y += args[0]; + args++; + nargs--; + } + + if ( check_points( builder, 3 * ( nargs / 4 ) ) ) + goto Fail; + + while ( args < decoder->top ) + { + x += args[0]; + cff_builder_add_point( builder, x, y, 0 ); + x += args[1]; + y += args[2]; + cff_builder_add_point( builder, x, y, 0 ); + x += args[3]; + cff_builder_add_point( builder, x, y, 1 ); + args += 4; + } + args = stack; + } + break; + + case cff_op_vhcurveto: + case cff_op_hvcurveto: + { + FT_Int phase; + FT_Int nargs; + + + FT_TRACE4(( op == cff_op_vhcurveto ? " vhcurveto\n" + : " hvcurveto\n" )); + + if ( cff_builder_start_point( builder, x, y ) ) + goto Fail; + + if ( num_args < 4 ) + goto Stack_Underflow; + + /* if num_args isn't of the form 8n, 8n+1, 8n+4, or 8n+5, */ + /* we reduce it to the largest one which fits */ + + nargs = num_args - num_args % 4; + if ( num_args - nargs > 0 ) + nargs += 1; + + args -= nargs; + if ( check_points( builder, ( nargs / 4 ) * 3 ) ) + goto Stack_Underflow; + + phase = ( op == cff_op_hvcurveto ); + + while ( nargs >= 4 ) + { + nargs -= 4; + if ( phase ) + { + x += args[0]; + cff_builder_add_point( builder, x, y, 0 ); + x += args[1]; + y += args[2]; + cff_builder_add_point( builder, x, y, 0 ); + y += args[3]; + if ( nargs == 1 ) + x += args[4]; + cff_builder_add_point( builder, x, y, 1 ); + } + else + { + y += args[0]; + cff_builder_add_point( builder, x, y, 0 ); + x += args[1]; + y += args[2]; + cff_builder_add_point( builder, x, y, 0 ); + x += args[3]; + if ( nargs == 1 ) + y += args[4]; + cff_builder_add_point( builder, x, y, 1 ); + } + args += 4; + phase ^= 1; + } + args = stack; + } + break; + + case cff_op_rlinecurve: + { + FT_Int num_lines; + FT_Int nargs; + + + FT_TRACE4(( " rlinecurve\n" )); + + if ( num_args < 8 ) + goto Stack_Underflow; + + nargs = num_args & ~1; + num_lines = ( nargs - 6 ) / 2; + + if ( cff_builder_start_point( builder, x, y ) || + check_points( builder, num_lines + 3 ) ) + goto Fail; + + args -= nargs; + + /* first, add the line segments */ + while ( num_lines > 0 ) + { + x += args[0]; + y += args[1]; + cff_builder_add_point( builder, x, y, 1 ); + args += 2; + num_lines--; + } + + /* then the curve */ + x += args[0]; + y += args[1]; + cff_builder_add_point( builder, x, y, 0 ); + x += args[2]; + y += args[3]; + cff_builder_add_point( builder, x, y, 0 ); + x += args[4]; + y += args[5]; + cff_builder_add_point( builder, x, y, 1 ); + args = stack; + } + break; + + case cff_op_rcurveline: + { + FT_Int num_curves; + FT_Int nargs; + + + FT_TRACE4(( " rcurveline\n" )); + + if ( num_args < 8 ) + goto Stack_Underflow; + + nargs = num_args - 2; + nargs = nargs - nargs % 6 + 2; + num_curves = ( nargs - 2 ) / 6; + + if ( cff_builder_start_point ( builder, x, y ) || + check_points( builder, num_curves * 3 + 2 ) ) + goto Fail; + + args -= nargs; + + /* first, add the curves */ + while ( num_curves > 0 ) + { + x += args[0]; + y += args[1]; + cff_builder_add_point( builder, x, y, 0 ); + x += args[2]; + y += args[3]; + cff_builder_add_point( builder, x, y, 0 ); + x += args[4]; + y += args[5]; + cff_builder_add_point( builder, x, y, 1 ); + args += 6; + num_curves--; + } + + /* then the final line */ + x += args[0]; + y += args[1]; + cff_builder_add_point( builder, x, y, 1 ); + args = stack; + } + break; + + case cff_op_hflex1: + { + FT_Pos start_y; + + + FT_TRACE4(( " hflex1\n" )); + + /* adding five more points: 4 control points, 1 on-curve point */ + /* -- make sure we have enough space for the start point if it */ + /* needs to be added */ + if ( cff_builder_start_point( builder, x, y ) || + check_points( builder, 6 ) ) + goto Fail; + + /* record the starting point's y position for later use */ + start_y = y; + + /* first control point */ + x += args[0]; + y += args[1]; + cff_builder_add_point( builder, x, y, 0 ); + + /* second control point */ + x += args[2]; + y += args[3]; + cff_builder_add_point( builder, x, y, 0 ); + + /* join point; on curve, with y-value the same as the last */ + /* control point's y-value */ + x += args[4]; + cff_builder_add_point( builder, x, y, 1 ); + + /* third control point, with y-value the same as the join */ + /* point's y-value */ + x += args[5]; + cff_builder_add_point( builder, x, y, 0 ); + + /* fourth control point */ + x += args[6]; + y += args[7]; + cff_builder_add_point( builder, x, y, 0 ); + + /* ending point, with y-value the same as the start */ + x += args[8]; + y = start_y; + cff_builder_add_point( builder, x, y, 1 ); + + args = stack; + break; + } + + case cff_op_hflex: + { + FT_Pos start_y; + + + FT_TRACE4(( " hflex\n" )); + + /* adding six more points; 4 control points, 2 on-curve points */ + if ( cff_builder_start_point( builder, x, y ) || + check_points( builder, 6 ) ) + goto Fail; + + /* record the starting point's y-position for later use */ + start_y = y; + + /* first control point */ + x += args[0]; + cff_builder_add_point( builder, x, y, 0 ); + + /* second control point */ + x += args[1]; + y += args[2]; + cff_builder_add_point( builder, x, y, 0 ); + + /* join point; on curve, with y-value the same as the last */ + /* control point's y-value */ + x += args[3]; + cff_builder_add_point( builder, x, y, 1 ); + + /* third control point, with y-value the same as the join */ + /* point's y-value */ + x += args[4]; + cff_builder_add_point( builder, x, y, 0 ); + + /* fourth control point */ + x += args[5]; + y = start_y; + cff_builder_add_point( builder, x, y, 0 ); + + /* ending point, with y-value the same as the start point's */ + /* y-value -- we don't add this point, though */ + x += args[6]; + cff_builder_add_point( builder, x, y, 1 ); + + args = stack; + break; + } + + case cff_op_flex1: + { + FT_Pos start_x, start_y; /* record start x, y values for */ + /* alter use */ + FT_Fixed dx = 0, dy = 0; /* used in horizontal/vertical */ + /* algorithm below */ + FT_Int horizontal, count; + FT_Fixed* temp; + + + FT_TRACE4(( " flex1\n" )); + + /* adding six more points; 4 control points, 2 on-curve points */ + if ( cff_builder_start_point( builder, x, y ) || + check_points( builder, 6 ) ) + goto Fail; + + /* record the starting point's x, y position for later use */ + start_x = x; + start_y = y; + + /* XXX: figure out whether this is supposed to be a horizontal */ + /* or vertical flex; the Type 2 specification is vague... */ + + temp = args; + + /* grab up to the last argument */ + for ( count = 5; count > 0; count-- ) + { + dx += temp[0]; + dy += temp[1]; + temp += 2; + } + + if ( dx < 0 ) + dx = -dx; + if ( dy < 0 ) + dy = -dy; + + /* strange test, but here it is... */ + horizontal = ( dx > dy ); + + for ( count = 5; count > 0; count-- ) + { + x += args[0]; + y += args[1]; + cff_builder_add_point( builder, x, y, + (FT_Bool)( count == 3 ) ); + args += 2; + } + + /* is last operand an x- or y-delta? */ + if ( horizontal ) + { + x += args[0]; + y = start_y; + } + else + { + x = start_x; + y += args[0]; + } + + cff_builder_add_point( builder, x, y, 1 ); + + args = stack; + break; + } + + case cff_op_flex: + { + FT_UInt count; + + + FT_TRACE4(( " flex\n" )); + + if ( cff_builder_start_point( builder, x, y ) || + check_points( builder, 6 ) ) + goto Fail; + + for ( count = 6; count > 0; count-- ) + { + x += args[0]; + y += args[1]; + cff_builder_add_point( builder, x, y, + (FT_Bool)( count == 4 || count == 1 ) ); + args += 2; + } + + args = stack; + } + break; + + case cff_op_endchar: + FT_TRACE4(( " endchar\n" )); + + /* We are going to emulate the seac operator. */ + if ( num_args >= 4 ) + { + /* Save glyph width so that the subglyphs don't overwrite it. */ + FT_Pos glyph_width = decoder->glyph_width; + + + error = cff_operator_seac( decoder, + args[-4], + args[-3], + (FT_Int)( args[-2] >> 16 ), + (FT_Int)( args[-1] >> 16 ) ); + + decoder->glyph_width = glyph_width; + } + else + { + if ( !error ) + error = CFF_Err_Ok; + + cff_builder_close_contour( builder ); + + /* close hints recording session */ + if ( hinter ) + { + if ( hinter->close( hinter->hints, + builder->current->n_points ) ) + goto Syntax_Error; + + /* apply hints to the loaded glyph outline now */ + hinter->apply( hinter->hints, + builder->current, + (PSH_Globals)builder->hints_globals, + decoder->hint_mode ); + } + + /* add current outline to the glyph slot */ + FT_GlyphLoader_Add( builder->loader ); + } + + /* return now! */ + FT_TRACE4(( "\n" )); + return error; + + case cff_op_abs: + FT_TRACE4(( " abs\n" )); + + if ( args[0] < 0 ) + args[0] = -args[0]; + args++; + break; + + case cff_op_add: + FT_TRACE4(( " add\n" )); + + args[0] += args[1]; + args++; + break; + + case cff_op_sub: + FT_TRACE4(( " sub\n" )); + + args[0] -= args[1]; + args++; + break; + + case cff_op_div: + FT_TRACE4(( " div\n" )); + + args[0] = FT_DivFix( args[0], args[1] ); + args++; + break; + + case cff_op_neg: + FT_TRACE4(( " neg\n" )); + + args[0] = -args[0]; + args++; + break; + + case cff_op_random: + { + FT_Fixed Rand; + + + FT_TRACE4(( " rand\n" )); + + Rand = seed; + if ( Rand >= 0x8000L ) + Rand++; + + args[0] = Rand; + seed = FT_MulFix( seed, 0x10000L - seed ); + if ( seed == 0 ) + seed += 0x2873; + args++; + } + break; + + case cff_op_mul: + FT_TRACE4(( " mul\n" )); + + args[0] = FT_MulFix( args[0], args[1] ); + args++; + break; + + case cff_op_sqrt: + FT_TRACE4(( " sqrt\n" )); + + if ( args[0] > 0 ) + { + FT_Int count = 9; + FT_Fixed root = args[0]; + FT_Fixed new_root; + + + for (;;) + { + new_root = ( root + FT_DivFix( args[0], root ) + 1 ) >> 1; + if ( new_root == root || count <= 0 ) + break; + root = new_root; + } + args[0] = new_root; + } + else + args[0] = 0; + args++; + break; + + case cff_op_drop: + /* nothing */ + FT_TRACE4(( " drop\n" )); + + break; + + case cff_op_exch: + { + FT_Fixed tmp; + + + FT_TRACE4(( " exch\n" )); + + tmp = args[0]; + args[0] = args[1]; + args[1] = tmp; + args += 2; + } + break; + + case cff_op_index: + { + FT_Int idx = (FT_Int)( args[0] >> 16 ); + + + FT_TRACE4(( " index\n" )); + + if ( idx < 0 ) + idx = 0; + else if ( idx > num_args - 2 ) + idx = num_args - 2; + args[0] = args[-( idx + 1 )]; + args++; + } + break; + + case cff_op_roll: + { + FT_Int count = (FT_Int)( args[0] >> 16 ); + FT_Int idx = (FT_Int)( args[1] >> 16 ); + + + FT_TRACE4(( " roll\n" )); + + if ( count <= 0 ) + count = 1; + + args -= count; + if ( args < stack ) + goto Stack_Underflow; + + if ( idx >= 0 ) + { + while ( idx > 0 ) + { + FT_Fixed tmp = args[count - 1]; + FT_Int i; + + + for ( i = count - 2; i >= 0; i-- ) + args[i + 1] = args[i]; + args[0] = tmp; + idx--; + } + } + else + { + while ( idx < 0 ) + { + FT_Fixed tmp = args[0]; + FT_Int i; + + + for ( i = 0; i < count - 1; i++ ) + args[i] = args[i + 1]; + args[count - 1] = tmp; + idx++; + } + } + args += count; + } + break; + + case cff_op_dup: + FT_TRACE4(( " dup\n" )); + + args[1] = args[0]; + args++; + break; + + case cff_op_put: + { + FT_Fixed val = args[0]; + FT_Int idx = (FT_Int)( args[1] >> 16 ); + + + FT_TRACE4(( " put\n" )); + + if ( idx >= 0 && idx < decoder->len_buildchar ) + decoder->buildchar[idx] = val; + } + break; + + case cff_op_get: + { + FT_Int idx = (FT_Int)( args[0] >> 16 ); + FT_Fixed val = 0; + + + FT_TRACE4(( " get\n" )); + + if ( idx >= 0 && idx < decoder->len_buildchar ) + val = decoder->buildchar[idx]; + + args[0] = val; + args++; + } + break; + + case cff_op_store: + FT_TRACE4(( " store\n")); + + goto Unimplemented; + + case cff_op_load: + FT_TRACE4(( " load\n" )); + + goto Unimplemented; + + case cff_op_dotsection: + /* this operator is deprecated and ignored by the parser */ + FT_TRACE4(( " dotsection\n" )); + break; + + case cff_op_closepath: + /* this is an invalid Type 2 operator; however, there */ + /* exist fonts which are incorrectly converted from probably */ + /* Type 1 to CFF, and some parsers seem to accept it */ + + FT_TRACE4(( " closepath (invalid op)\n" )); + + args = stack; + break; + + case cff_op_hsbw: + /* this is an invalid Type 2 operator; however, there */ + /* exist fonts which are incorrectly converted from probably */ + /* Type 1 to CFF, and some parsers seem to accept it */ + + FT_TRACE4(( " hsbw (invalid op)\n" )); + + decoder->glyph_width = decoder->nominal_width + + (args[1] >> 16); + x = args[0]; + y = 0; + args = stack; + break; + + case cff_op_callothersubr: + /* this is an invalid Type 2 operator; however, there */ + /* exist fonts which are incorrectly converted from probably */ + /* Type 1 to CFF, and some parsers seem to accept it */ + + FT_TRACE4(( " callothersubr (invalid op)\n" )); + + /* don't modify stack; handle the subr as `unknown' so that */ + /* following `pop' operands use the arguments on stack */ + break; + + case cff_op_pop: + /* this is an invalid Type 2 operator; however, there */ + /* exist fonts which are incorrectly converted from probably */ + /* Type 1 to CFF, and some parsers seem to accept it */ + + FT_TRACE4(( " pop (invalid op)\n" )); + + args++; + break; + + case cff_op_and: + { + FT_Fixed cond = args[0] && args[1]; + + + FT_TRACE4(( " and\n" )); + + args[0] = cond ? 0x10000L : 0; + args++; + } + break; + + case cff_op_or: + { + FT_Fixed cond = args[0] || args[1]; + + + FT_TRACE4(( " or\n" )); + + args[0] = cond ? 0x10000L : 0; + args++; + } + break; + + case cff_op_eq: + { + FT_Fixed cond = !args[0]; + + + FT_TRACE4(( " eq\n" )); + + args[0] = cond ? 0x10000L : 0; + args++; + } + break; + + case cff_op_ifelse: + { + FT_Fixed cond = ( args[2] <= args[3] ); + + + FT_TRACE4(( " ifelse\n" )); + + if ( !cond ) + args[0] = args[1]; + args++; + } + break; + + case cff_op_callsubr: + { + FT_UInt idx = (FT_UInt)( ( args[0] >> 16 ) + + decoder->locals_bias ); + + + FT_TRACE4(( " callsubr(%d)\n", idx )); + + if ( idx >= decoder->num_locals ) + { + FT_ERROR(( "cff_decoder_parse_charstrings:" + " invalid local subr index\n" )); + goto Syntax_Error; + } + + if ( zone - decoder->zones >= CFF_MAX_SUBRS_CALLS ) + { + FT_ERROR(( "cff_decoder_parse_charstrings:" + " too many nested subrs\n" )); + goto Syntax_Error; + } + + zone->cursor = ip; /* save current instruction pointer */ + + zone++; + zone->base = decoder->locals[idx]; + zone->limit = decoder->locals[idx + 1]; + zone->cursor = zone->base; + + if ( !zone->base || zone->limit == zone->base ) + { + FT_ERROR(( "cff_decoder_parse_charstrings:" + " invoking empty subrs\n" )); + goto Syntax_Error; + } + + decoder->zone = zone; + ip = zone->base; + limit = zone->limit; + } + break; + + case cff_op_callgsubr: + { + FT_UInt idx = (FT_UInt)( ( args[0] >> 16 ) + + decoder->globals_bias ); + + + FT_TRACE4(( " callgsubr(%d)\n", idx )); + + if ( idx >= decoder->num_globals ) + { + FT_ERROR(( "cff_decoder_parse_charstrings:" + " invalid global subr index\n" )); + goto Syntax_Error; + } + + if ( zone - decoder->zones >= CFF_MAX_SUBRS_CALLS ) + { + FT_ERROR(( "cff_decoder_parse_charstrings:" + " too many nested subrs\n" )); + goto Syntax_Error; + } + + zone->cursor = ip; /* save current instruction pointer */ + + zone++; + zone->base = decoder->globals[idx]; + zone->limit = decoder->globals[idx + 1]; + zone->cursor = zone->base; + + if ( !zone->base || zone->limit == zone->base ) + { + FT_ERROR(( "cff_decoder_parse_charstrings:" + " invoking empty subrs\n" )); + goto Syntax_Error; + } + + decoder->zone = zone; + ip = zone->base; + limit = zone->limit; + } + break; + + case cff_op_return: + FT_TRACE4(( " return\n" )); + + if ( decoder->zone <= decoder->zones ) + { + FT_ERROR(( "cff_decoder_parse_charstrings:" + " unexpected return\n" )); + goto Syntax_Error; + } + + decoder->zone--; + zone = decoder->zone; + ip = zone->cursor; + limit = zone->limit; + break; + + default: + Unimplemented: + FT_ERROR(( "Unimplemented opcode: %d", ip[-1] )); + + if ( ip[-1] == 12 ) + FT_ERROR(( " %d", ip[0] )); + FT_ERROR(( "\n" )); + + return CFF_Err_Unimplemented_Feature; + } + + decoder->top = args; + + } /* general operator processing */ + + } /* while ip < limit */ + + FT_TRACE4(( "..end..\n\n" )); + + Fail: + return error; + + Syntax_Error: + FT_TRACE4(( "cff_decoder_parse_charstrings: syntax error\n" )); + return CFF_Err_Invalid_File_Format; + + Stack_Underflow: + FT_TRACE4(( "cff_decoder_parse_charstrings: stack underflow\n" )); + return CFF_Err_Too_Few_Arguments; + + Stack_Overflow: + FT_TRACE4(( "cff_decoder_parse_charstrings: stack overflow\n" )); + return CFF_Err_Stack_Overflow; + } + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /********** *********/ + /********** *********/ + /********** COMPUTE THE MAXIMUM ADVANCE WIDTH *********/ + /********** *********/ + /********** The following code is in charge of computing *********/ + /********** the maximum advance width of the font. It *********/ + /********** quickly processes each glyph charstring to *********/ + /********** extract the value from either a `sbw' or `seac' *********/ + /********** operator. *********/ + /********** *********/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + +#if 0 /* unused until we support pure CFF fonts */ + + + FT_LOCAL_DEF( FT_Error ) + cff_compute_max_advance( TT_Face face, + FT_Int* max_advance ) + { + FT_Error error = CFF_Err_Ok; + CFF_Decoder decoder; + FT_Int glyph_index; + CFF_Font cff = (CFF_Font)face->other; + + + *max_advance = 0; + + /* Initialize load decoder */ + cff_decoder_init( &decoder, face, 0, 0, 0, 0 ); + + decoder.builder.metrics_only = 1; + decoder.builder.load_points = 0; + + /* For each glyph, parse the glyph charstring and extract */ + /* the advance width. */ + for ( glyph_index = 0; glyph_index < face->root.num_glyphs; + glyph_index++ ) + { + FT_Byte* charstring; + FT_ULong charstring_len; + + + /* now get load the unscaled outline */ + error = cff_get_glyph_data( face, glyph_index, + &charstring, &charstring_len ); + if ( !error ) + { + error = cff_decoder_prepare( &decoder, size, glyph_index ); + if ( !error ) + error = cff_decoder_parse_charstrings( &decoder, + charstring, + charstring_len ); + + cff_free_glyph_data( face, &charstring, &charstring_len ); + } + + /* ignore the error if one has occurred -- skip to next glyph */ + error = CFF_Err_Ok; + } + + *max_advance = decoder.builder.advance.x; + + return CFF_Err_Ok; + } + + +#endif /* 0 */ + + + FT_LOCAL_DEF( FT_Error ) + cff_slot_load( CFF_GlyphSlot glyph, + CFF_Size size, + FT_UInt glyph_index, + FT_Int32 load_flags ) + { + FT_Error error; + CFF_Decoder decoder; + TT_Face face = (TT_Face)glyph->root.face; + FT_Bool hinting, force_scaling; + CFF_Font cff = (CFF_Font)face->extra.data; + + FT_Matrix font_matrix; + FT_Vector font_offset; + + + force_scaling = FALSE; + + /* in a CID-keyed font, consider `glyph_index' as a CID and map */ + /* it immediately to the real glyph_index -- if it isn't a */ + /* subsetted font, glyph_indices and CIDs are identical, though */ + if ( cff->top_font.font_dict.cid_registry != 0xFFFFU && + cff->charset.cids ) + { + /* don't handle CID 0 (.notdef) which is directly mapped to GID 0 */ + if ( glyph_index != 0 ) + { + glyph_index = cff_charset_cid_to_gindex( &cff->charset, + glyph_index ); + if ( glyph_index == 0 ) + return CFF_Err_Invalid_Argument; + } + } + else if ( glyph_index >= cff->num_glyphs ) + return CFF_Err_Invalid_Argument; + + if ( load_flags & FT_LOAD_NO_RECURSE ) + load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; + + glyph->x_scale = 0x10000L; + glyph->y_scale = 0x10000L; + if ( size ) + { + glyph->x_scale = size->root.metrics.x_scale; + glyph->y_scale = size->root.metrics.y_scale; + } + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + + /* try to load embedded bitmap if any */ + /* */ + /* XXX: The convention should be emphasized in */ + /* the documents because it can be confusing. */ + if ( size ) + { + CFF_Face cff_face = (CFF_Face)size->root.face; + SFNT_Service sfnt = (SFNT_Service)cff_face->sfnt; + FT_Stream stream = cff_face->root.stream; + + + if ( size->strike_index != 0xFFFFFFFFUL && + sfnt->load_eblc && + ( load_flags & FT_LOAD_NO_BITMAP ) == 0 ) + { + TT_SBit_MetricsRec metrics; + + + error = sfnt->load_sbit_image( face, + size->strike_index, + glyph_index, + (FT_Int)load_flags, + stream, + &glyph->root.bitmap, + &metrics ); + + if ( !error ) + { + glyph->root.outline.n_points = 0; + glyph->root.outline.n_contours = 0; + + glyph->root.metrics.width = (FT_Pos)metrics.width << 6; + glyph->root.metrics.height = (FT_Pos)metrics.height << 6; + + glyph->root.metrics.horiBearingX = (FT_Pos)metrics.horiBearingX << 6; + glyph->root.metrics.horiBearingY = (FT_Pos)metrics.horiBearingY << 6; + glyph->root.metrics.horiAdvance = (FT_Pos)metrics.horiAdvance << 6; + + glyph->root.metrics.vertBearingX = (FT_Pos)metrics.vertBearingX << 6; + glyph->root.metrics.vertBearingY = (FT_Pos)metrics.vertBearingY << 6; + glyph->root.metrics.vertAdvance = (FT_Pos)metrics.vertAdvance << 6; + + glyph->root.format = FT_GLYPH_FORMAT_BITMAP; + + if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) + { + glyph->root.bitmap_left = metrics.vertBearingX; + glyph->root.bitmap_top = metrics.vertBearingY; + } + else + { + glyph->root.bitmap_left = metrics.horiBearingX; + glyph->root.bitmap_top = metrics.horiBearingY; + } + return error; + } + } + } + +#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ + + /* return immediately if we only want the embedded bitmaps */ + if ( load_flags & FT_LOAD_SBITS_ONLY ) + return CFF_Err_Invalid_Argument; + + /* if we have a CID subfont, use its matrix (which has already */ + /* been multiplied with the root matrix) */ + + /* this scaling is only relevant if the PS hinter isn't active */ + if ( cff->num_subfonts ) + { + FT_Byte fd_index = cff_fd_select_get( &cff->fd_select, + glyph_index ); + + FT_ULong top_upm = cff->top_font.font_dict.units_per_em; + FT_ULong sub_upm = cff->subfonts[fd_index]->font_dict.units_per_em; + + + font_matrix = cff->subfonts[fd_index]->font_dict.font_matrix; + font_offset = cff->subfonts[fd_index]->font_dict.font_offset; + + if ( top_upm != sub_upm ) + { + glyph->x_scale = FT_MulDiv( glyph->x_scale, top_upm, sub_upm ); + glyph->y_scale = FT_MulDiv( glyph->y_scale, top_upm, sub_upm ); + + force_scaling = TRUE; + } + } + else + { + font_matrix = cff->top_font.font_dict.font_matrix; + font_offset = cff->top_font.font_dict.font_offset; + } + + glyph->root.outline.n_points = 0; + glyph->root.outline.n_contours = 0; + + hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 && + ( load_flags & FT_LOAD_NO_HINTING ) == 0 ); + + glyph->root.format = FT_GLYPH_FORMAT_OUTLINE; /* by default */ + + { + FT_Byte* charstring; + FT_ULong charstring_len; + + + cff_decoder_init( &decoder, face, size, glyph, hinting, + FT_LOAD_TARGET_MODE( load_flags ) ); + + if ( load_flags & FT_LOAD_ADVANCE_ONLY ) + decoder.width_only = TRUE; + + decoder.builder.no_recurse = + (FT_Bool)( load_flags & FT_LOAD_NO_RECURSE ); + + /* now load the unscaled outline */ + error = cff_get_glyph_data( face, glyph_index, + &charstring, &charstring_len ); + if ( !error ) + { + error = cff_decoder_prepare( &decoder, size, glyph_index ); + if ( !error ) + { + error = cff_decoder_parse_charstrings( &decoder, + charstring, + charstring_len ); + + cff_free_glyph_data( face, &charstring, charstring_len ); + + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + /* Control data and length may not be available for incremental */ + /* fonts. */ + if ( face->root.internal->incremental_interface ) + { + glyph->root.control_data = 0; + glyph->root.control_len = 0; + } + else +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ + + /* We set control_data and control_len if charstrings is loaded. */ + /* See how charstring loads at cff_index_access_element() in */ + /* cffload.c. */ + { + CFF_Index csindex = &cff->charstrings_index; + + + if ( csindex->offsets ) + { + glyph->root.control_data = csindex->bytes + + csindex->offsets[glyph_index] - 1; + glyph->root.control_len = charstring_len; + } + } + } + } + + /* save new glyph tables */ + cff_builder_done( &decoder.builder ); + } + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + + /* Incremental fonts can optionally override the metrics. */ + if ( !error && + face->root.internal->incremental_interface && + face->root.internal->incremental_interface->funcs->get_glyph_metrics ) + { + FT_Incremental_MetricsRec metrics; + + + metrics.bearing_x = decoder.builder.left_bearing.x; + metrics.bearing_y = decoder.builder.left_bearing.y; + metrics.advance = decoder.builder.advance.x; + error = face->root.internal->incremental_interface->funcs->get_glyph_metrics( + face->root.internal->incremental_interface->object, + glyph_index, FALSE, &metrics ); + decoder.builder.left_bearing.x = metrics.bearing_x; + decoder.builder.left_bearing.y = metrics.bearing_y; + decoder.builder.advance.x = metrics.advance; + decoder.builder.advance.y = 0; + } + +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ + + if ( !error ) + { + /* Now, set the metrics -- this is rather simple, as */ + /* the left side bearing is the xMin, and the top side */ + /* bearing the yMax. */ + + /* For composite glyphs, return only left side bearing and */ + /* advance width. */ + if ( load_flags & FT_LOAD_NO_RECURSE ) + { + FT_Slot_Internal internal = glyph->root.internal; + + + glyph->root.metrics.horiBearingX = decoder.builder.left_bearing.x; + glyph->root.metrics.horiAdvance = decoder.glyph_width; + internal->glyph_matrix = font_matrix; + internal->glyph_delta = font_offset; + internal->glyph_transformed = 1; + } + else + { + FT_BBox cbox; + FT_Glyph_Metrics* metrics = &glyph->root.metrics; + FT_Vector advance; + FT_Bool has_vertical_info; + + + /* copy the _unscaled_ advance width */ + metrics->horiAdvance = decoder.glyph_width; + glyph->root.linearHoriAdvance = decoder.glyph_width; + glyph->root.internal->glyph_transformed = 0; + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + has_vertical_info = FT_BOOL( face->vertical_info && + face->vertical.number_Of_VMetrics > 0 && + face->vertical.long_metrics ); +#else + has_vertical_info = FT_BOOL( face->vertical_info && + face->vertical.number_Of_VMetrics > 0 ); +#endif + + /* get the vertical metrics from the vtmx table if we have one */ + if ( has_vertical_info ) + { + FT_Short vertBearingY = 0; + FT_UShort vertAdvance = 0; + + + ( (SFNT_Service)face->sfnt )->get_metrics( face, 1, + glyph_index, + &vertBearingY, + &vertAdvance ); + metrics->vertBearingY = vertBearingY; + metrics->vertAdvance = vertAdvance; + } + else + { + /* make up vertical ones */ + if ( face->os2.version != 0xFFFFU ) + metrics->vertAdvance = (FT_Pos)( face->os2.sTypoAscender - + face->os2.sTypoDescender ); + else + metrics->vertAdvance = (FT_Pos)( face->horizontal.Ascender - + face->horizontal.Descender ); + } + + glyph->root.linearVertAdvance = metrics->vertAdvance; + + glyph->root.format = FT_GLYPH_FORMAT_OUTLINE; + + glyph->root.outline.flags = 0; + if ( size && size->root.metrics.y_ppem < 24 ) + glyph->root.outline.flags |= FT_OUTLINE_HIGH_PRECISION; + + glyph->root.outline.flags |= FT_OUTLINE_REVERSE_FILL; + + if ( !( font_matrix.xx == 0x10000L && + font_matrix.yy == 0x10000L && + font_matrix.xy == 0 && + font_matrix.yx == 0 ) ) + FT_Outline_Transform( &glyph->root.outline, &font_matrix ); + + if ( !( font_offset.x == 0 && + font_offset.y == 0 ) ) + FT_Outline_Translate( &glyph->root.outline, + font_offset.x, font_offset.y ); + + advance.x = metrics->horiAdvance; + advance.y = 0; + FT_Vector_Transform( &advance, &font_matrix ); + metrics->horiAdvance = advance.x + font_offset.x; + + advance.x = 0; + advance.y = metrics->vertAdvance; + FT_Vector_Transform( &advance, &font_matrix ); + metrics->vertAdvance = advance.y + font_offset.y; + + if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 || force_scaling ) + { + /* scale the outline and the metrics */ + FT_Int n; + FT_Outline* cur = &glyph->root.outline; + FT_Vector* vec = cur->points; + FT_Fixed x_scale = glyph->x_scale; + FT_Fixed y_scale = glyph->y_scale; + + + /* First of all, scale the points */ + if ( !hinting || !decoder.builder.hints_funcs ) + for ( n = cur->n_points; n > 0; n--, vec++ ) + { + vec->x = FT_MulFix( vec->x, x_scale ); + vec->y = FT_MulFix( vec->y, y_scale ); + } + + /* Then scale the metrics */ + metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale ); + metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale ); + } + + /* compute the other metrics */ + FT_Outline_Get_CBox( &glyph->root.outline, &cbox ); + + metrics->width = cbox.xMax - cbox.xMin; + metrics->height = cbox.yMax - cbox.yMin; + + metrics->horiBearingX = cbox.xMin; + metrics->horiBearingY = cbox.yMax; + + if ( has_vertical_info ) + metrics->vertBearingX = metrics->horiBearingX - + metrics->horiAdvance / 2; + else + ft_synthesize_vertical_metrics( metrics, + metrics->vertAdvance ); + } + } + + return error; + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/cff/cffgload.h b/mod/pub.mod/freetype.mod/src/cff/cffgload.h new file mode 100644 index 0000000..956817a --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/cff/cffgload.h @@ -0,0 +1,201 @@ +/***************************************************************************/ +/* */ +/* cffgload.h */ +/* */ +/* OpenType Glyph Loader (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __CFFGLOAD_H__ +#define __CFFGLOAD_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include "cffobjs.h" + + +FT_BEGIN_HEADER + + +#define CFF_MAX_OPERANDS 48 +#define CFF_MAX_SUBRS_CALLS 32 + + + /*************************************************************************/ + /* */ + /* <Structure> */ + /* CFF_Builder */ + /* */ + /* <Description> */ + /* A structure used during glyph loading to store its outline. */ + /* */ + /* <Fields> */ + /* memory :: The current memory object. */ + /* */ + /* face :: The current face object. */ + /* */ + /* glyph :: The current glyph slot. */ + /* */ + /* loader :: The current glyph loader. */ + /* */ + /* base :: The base glyph outline. */ + /* */ + /* current :: The current glyph outline. */ + /* */ + /* pos_x :: The horizontal translation (if composite glyph). */ + /* */ + /* pos_y :: The vertical translation (if composite glyph). */ + /* */ + /* left_bearing :: The left side bearing point. */ + /* */ + /* advance :: The horizontal advance vector. */ + /* */ + /* bbox :: Unused. */ + /* */ + /* path_begun :: A flag which indicates that a new path has begun. */ + /* */ + /* load_points :: If this flag is not set, no points are loaded. */ + /* */ + /* no_recurse :: Set but not used. */ + /* */ + /* metrics_only :: A boolean indicating that we only want to compute */ + /* the metrics of a given glyph, not load all of its */ + /* points. */ + /* */ + /* hints_funcs :: Auxiliary pointer for hinting. */ + /* */ + /* hints_globals :: Auxiliary pointer for hinting. */ + /* */ + typedef struct CFF_Builder_ + { + FT_Memory memory; + TT_Face face; + CFF_GlyphSlot glyph; + FT_GlyphLoader loader; + FT_Outline* base; + FT_Outline* current; + + FT_Pos pos_x; + FT_Pos pos_y; + + FT_Vector left_bearing; + FT_Vector advance; + + FT_BBox bbox; /* bounding box */ + FT_Bool path_begun; + FT_Bool load_points; + FT_Bool no_recurse; + + FT_Bool metrics_only; + + void* hints_funcs; /* hinter-specific */ + void* hints_globals; /* hinter-specific */ + + } CFF_Builder; + + + /* execution context charstring zone */ + + typedef struct CFF_Decoder_Zone_ + { + FT_Byte* base; + FT_Byte* limit; + FT_Byte* cursor; + + } CFF_Decoder_Zone; + + + typedef struct CFF_Decoder_ + { + CFF_Builder builder; + CFF_Font cff; + + FT_Fixed stack[CFF_MAX_OPERANDS + 1]; + FT_Fixed* top; + + CFF_Decoder_Zone zones[CFF_MAX_SUBRS_CALLS + 1]; + CFF_Decoder_Zone* zone; + + FT_Int flex_state; + FT_Int num_flex_vectors; + FT_Vector flex_vectors[7]; + + FT_Pos glyph_width; + FT_Pos nominal_width; + + FT_Bool read_width; + FT_Bool width_only; + FT_Int num_hints; + FT_Fixed* buildchar; + FT_Int len_buildchar; + + FT_UInt num_locals; + FT_UInt num_globals; + + FT_Int locals_bias; + FT_Int globals_bias; + + FT_Byte** locals; + FT_Byte** globals; + + FT_Byte** glyph_names; /* for pure CFF fonts only */ + FT_UInt num_glyphs; /* number of glyphs in font */ + + FT_Render_Mode hint_mode; + + FT_Bool seac; + + } CFF_Decoder; + + + FT_LOCAL( void ) + cff_decoder_init( CFF_Decoder* decoder, + TT_Face face, + CFF_Size size, + CFF_GlyphSlot slot, + FT_Bool hinting, + FT_Render_Mode hint_mode ); + + FT_LOCAL( FT_Error ) + cff_decoder_prepare( CFF_Decoder* decoder, + CFF_Size size, + FT_UInt glyph_index ); + +#if 0 /* unused until we support pure CFF fonts */ + + /* Compute the maximum advance width of a font through quick parsing */ + FT_LOCAL( FT_Error ) + cff_compute_max_advance( TT_Face face, + FT_Int* max_advance ); + +#endif /* 0 */ + + FT_LOCAL( FT_Error ) + cff_decoder_parse_charstrings( CFF_Decoder* decoder, + FT_Byte* charstring_base, + FT_ULong charstring_len ); + + FT_LOCAL( FT_Error ) + cff_slot_load( CFF_GlyphSlot glyph, + CFF_Size size, + FT_UInt glyph_index, + FT_Int32 load_flags ); + + +FT_END_HEADER + +#endif /* __CFFGLOAD_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/cff/cffload.c b/mod/pub.mod/freetype.mod/src/cff/cffload.c new file mode 100644 index 0000000..64d1395 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/cff/cffload.c @@ -0,0 +1,1638 @@ +/***************************************************************************/ +/* */ +/* cffload.c */ +/* */ +/* OpenType and CFF data/program tables loader (body). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_STREAM_H +#include FT_SERVICE_POSTSCRIPT_CMAPS_H +#include FT_TRUETYPE_TAGS_H +#include FT_TYPE1_TABLES_H + +#include "cffload.h" +#include "cffparse.h" + +#include "cfferrs.h" + + +#if 1 + + static const FT_UShort cff_isoadobe_charset[229] = + { + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 71, + 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, + 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, + 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, + 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228 + }; + + static const FT_UShort cff_expert_charset[166] = + { + 0, 1, 229, 230, 231, 232, 233, 234, + 235, 236, 237, 238, 13, 14, 15, 99, + 239, 240, 241, 242, 243, 244, 245, 246, + 247, 248, 27, 28, 249, 250, 251, 252, + 253, 254, 255, 256, 257, 258, 259, 260, + 261, 262, 263, 264, 265, 266, 109, 110, + 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, + 283, 284, 285, 286, 287, 288, 289, 290, + 291, 292, 293, 294, 295, 296, 297, 298, + 299, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 314, + 315, 316, 317, 318, 158, 155, 163, 319, + 320, 321, 322, 323, 324, 325, 326, 150, + 164, 169, 327, 328, 329, 330, 331, 332, + 333, 334, 335, 336, 337, 338, 339, 340, + 341, 342, 343, 344, 345, 346, 347, 348, + 349, 350, 351, 352, 353, 354, 355, 356, + 357, 358, 359, 360, 361, 362, 363, 364, + 365, 366, 367, 368, 369, 370, 371, 372, + 373, 374, 375, 376, 377, 378 + }; + + static const FT_UShort cff_expertsubset_charset[87] = + { + 0, 1, 231, 232, 235, 236, 237, 238, + 13, 14, 15, 99, 239, 240, 241, 242, + 243, 244, 245, 246, 247, 248, 27, 28, + 249, 250, 251, 253, 254, 255, 256, 257, + 258, 259, 260, 261, 262, 263, 264, 265, + 266, 109, 110, 267, 268, 269, 270, 272, + 300, 301, 302, 305, 314, 315, 158, 155, + 163, 320, 321, 322, 323, 324, 325, 326, + 150, 164, 169, 327, 328, 329, 330, 331, + 332, 333, 334, 335, 336, 337, 338, 339, + 340, 341, 342, 343, 344, 345, 346 + }; + + static const FT_UShort cff_standard_encoding[256] = + { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 95, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 96, 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 107, 108, 109, 110, + 0, 111, 112, 113, 114, 0, 115, 116, + 117, 118, 119, 120, 121, 122, 0, 123, + 0, 124, 125, 126, 127, 128, 129, 130, + 131, 0, 132, 133, 0, 134, 135, 136, + 137, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 138, 0, 139, 0, 0, 0, 0, + 140, 141, 142, 143, 0, 0, 0, 0, + 0, 144, 0, 0, 0, 145, 0, 0, + 146, 147, 148, 149, 0, 0, 0, 0 + }; + + static const FT_UShort cff_expert_encoding[256] = + { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 229, 230, 0, 231, 232, 233, 234, + 235, 236, 237, 238, 13, 14, 15, 99, + 239, 240, 241, 242, 243, 244, 245, 246, + 247, 248, 27, 28, 249, 250, 251, 252, + 0, 253, 254, 255, 256, 257, 0, 0, + 0, 258, 0, 0, 259, 260, 261, 262, + 0, 0, 263, 264, 265, 0, 266, 109, + 110, 267, 268, 269, 0, 270, 271, 272, + 273, 274, 275, 276, 277, 278, 279, 280, + 281, 282, 283, 284, 285, 286, 287, 288, + 289, 290, 291, 292, 293, 294, 295, 296, + 297, 298, 299, 300, 301, 302, 303, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 304, 305, 306, 0, 0, 307, 308, + 309, 310, 311, 0, 312, 0, 0, 312, + 0, 0, 314, 315, 0, 0, 316, 317, + 318, 0, 0, 0, 158, 155, 163, 319, + 320, 321, 322, 323, 324, 325, 0, 0, + 326, 150, 164, 169, 327, 328, 329, 330, + 331, 332, 333, 334, 335, 336, 337, 338, + 339, 340, 341, 342, 343, 344, 345, 346, + 347, 348, 349, 350, 351, 352, 353, 354, + 355, 356, 357, 358, 359, 360, 361, 362, + 363, 364, 365, 366, 367, 368, 369, 370, + 371, 372, 373, 374, 375, 376, 377, 378 + }; + +#endif /* 1 */ + + + FT_LOCAL_DEF( FT_UShort ) + cff_get_standard_encoding( FT_UInt charcode ) + { + return (FT_UShort)( charcode < 256 ? cff_standard_encoding[charcode] + : 0 ); + } + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_cffload + + + /* read an offset from the index's stream current position */ + static FT_ULong + cff_index_read_offset( CFF_Index idx, + FT_Error *errorp ) + { + FT_Error error; + FT_Stream stream = idx->stream; + FT_Byte tmp[4]; + FT_ULong result = 0; + + + if ( !FT_STREAM_READ( tmp, idx->off_size ) ) + { + FT_Int nn; + + + for ( nn = 0; nn < idx->off_size; nn++ ) + result = ( result << 8 ) | tmp[nn]; + } + + *errorp = error; + return result; + } + + + static FT_Error + cff_index_init( CFF_Index idx, + FT_Stream stream, + FT_Bool load ) + { + FT_Error error; + FT_Memory memory = stream->memory; + FT_UShort count; + + + FT_MEM_ZERO( idx, sizeof ( *idx ) ); + + idx->stream = stream; + idx->start = FT_STREAM_POS(); + if ( !FT_READ_USHORT( count ) && + count > 0 ) + { + FT_Byte offsize; + FT_ULong size; + + + /* there is at least one element; read the offset size, */ + /* then access the offset table to compute the index's total size */ + if ( FT_READ_BYTE( offsize ) ) + goto Exit; + + if ( offsize < 1 || offsize > 4 ) + { + error = FT_Err_Invalid_Table; + goto Exit; + } + + idx->count = count; + idx->off_size = offsize; + size = (FT_ULong)( count + 1 ) * offsize; + + idx->data_offset = idx->start + 3 + size; + + if ( FT_STREAM_SKIP( size - offsize ) ) + goto Exit; + + size = cff_index_read_offset( idx, &error ); + if ( error ) + goto Exit; + + if ( size == 0 ) + { + error = CFF_Err_Invalid_Table; + goto Exit; + } + + idx->data_size = --size; + + if ( load ) + { + /* load the data */ + if ( FT_FRAME_EXTRACT( size, idx->bytes ) ) + goto Exit; + } + else + { + /* skip the data */ + if ( FT_STREAM_SKIP( size ) ) + goto Exit; + } + } + + Exit: + if ( error ) + FT_FREE( idx->offsets ); + + return error; + } + + + static void + cff_index_done( CFF_Index idx ) + { + if ( idx->stream ) + { + FT_Stream stream = idx->stream; + FT_Memory memory = stream->memory; + + + if ( idx->bytes ) + FT_FRAME_RELEASE( idx->bytes ); + + FT_FREE( idx->offsets ); + FT_MEM_ZERO( idx, sizeof ( *idx ) ); + } + } + + + static FT_Error + cff_index_load_offsets( CFF_Index idx ) + { + FT_Error error = CFF_Err_Ok; + FT_Stream stream = idx->stream; + FT_Memory memory = stream->memory; + + + if ( idx->count > 0 && idx->offsets == NULL ) + { + FT_Byte offsize = idx->off_size; + FT_ULong data_size; + FT_Byte* p; + FT_Byte* p_end; + FT_ULong* poff; + + + data_size = (FT_ULong)( idx->count + 1 ) * offsize; + + if ( FT_NEW_ARRAY( idx->offsets, idx->count + 1 ) || + FT_STREAM_SEEK( idx->start + 3 ) || + FT_FRAME_ENTER( data_size ) ) + goto Exit; + + poff = idx->offsets; + p = (FT_Byte*)stream->cursor; + p_end = p + data_size; + + switch ( offsize ) + { + case 1: + for ( ; p < p_end; p++, poff++ ) + poff[0] = p[0]; + break; + + case 2: + for ( ; p < p_end; p += 2, poff++ ) + poff[0] = FT_PEEK_USHORT( p ); + break; + + case 3: + for ( ; p < p_end; p += 3, poff++ ) + poff[0] = FT_PEEK_OFF3( p ); + break; + + default: + for ( ; p < p_end; p += 4, poff++ ) + poff[0] = FT_PEEK_ULONG( p ); + } + + FT_FRAME_EXIT(); + } + + Exit: + if ( error ) + FT_FREE( idx->offsets ); + + return error; + } + + + /* allocate a table containing pointers to an index's elements */ + static FT_Error + cff_index_get_pointers( CFF_Index idx, + FT_Byte*** table ) + { + FT_Error error = CFF_Err_Ok; + FT_Memory memory = idx->stream->memory; + FT_ULong n, offset, old_offset; + FT_Byte** t; + + + *table = 0; + + if ( idx->offsets == NULL ) + { + error = cff_index_load_offsets( idx ); + if ( error ) + goto Exit; + } + + if ( idx->count > 0 && !FT_NEW_ARRAY( t, idx->count + 1 ) ) + { + old_offset = 1; + for ( n = 0; n <= idx->count; n++ ) + { + /* at this point, `idx->offsets' can't be NULL */ + offset = idx->offsets[n]; + if ( !offset ) + offset = old_offset; + + /* two sanity checks for invalid offset tables */ + else if ( offset < old_offset ) + offset = old_offset; + + else if ( offset - 1 >= idx->data_size && n < idx->count ) + offset = old_offset; + + t[n] = idx->bytes + offset - 1; + + old_offset = offset; + } + *table = t; + } + + Exit: + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + cff_index_access_element( CFF_Index idx, + FT_UInt element, + FT_Byte** pbytes, + FT_ULong* pbyte_len ) + { + FT_Error error = CFF_Err_Ok; + + + if ( idx && idx->count > element ) + { + /* compute start and end offsets */ + FT_Stream stream = idx->stream; + FT_ULong off1, off2 = 0; + + + /* load offsets from file or the offset table */ + if ( !idx->offsets ) + { + FT_ULong pos = element * idx->off_size; + + + if ( FT_STREAM_SEEK( idx->start + 3 + pos ) ) + goto Exit; + + off1 = cff_index_read_offset( idx, &error ); + if ( error ) + goto Exit; + + if ( off1 != 0 ) + { + do + { + element++; + off2 = cff_index_read_offset( idx, &error ); + } + while ( off2 == 0 && element < idx->count ); + } + } + else /* use offsets table */ + { + off1 = idx->offsets[element]; + if ( off1 ) + { + do + { + element++; + off2 = idx->offsets[element]; + + } while ( off2 == 0 && element < idx->count ); + } + } + + /* access element */ + if ( off1 && off2 > off1 ) + { + *pbyte_len = off2 - off1; + + if ( idx->bytes ) + { + /* this index was completely loaded in memory, that's easy */ + *pbytes = idx->bytes + off1 - 1; + } + else + { + /* this index is still on disk/file, access it through a frame */ + if ( FT_STREAM_SEEK( idx->data_offset + off1 - 1 ) || + FT_FRAME_EXTRACT( off2 - off1, *pbytes ) ) + goto Exit; + } + } + else + { + /* empty index element */ + *pbytes = 0; + *pbyte_len = 0; + } + } + else + error = CFF_Err_Invalid_Argument; + + Exit: + return error; + } + + + FT_LOCAL_DEF( void ) + cff_index_forget_element( CFF_Index idx, + FT_Byte** pbytes ) + { + if ( idx->bytes == 0 ) + { + FT_Stream stream = idx->stream; + + + FT_FRAME_RELEASE( *pbytes ); + } + } + + + FT_LOCAL_DEF( FT_String* ) + cff_index_get_name( CFF_Index idx, + FT_UInt element ) + { + FT_Memory memory = idx->stream->memory; + FT_Byte* bytes; + FT_ULong byte_len; + FT_Error error; + FT_String* name = 0; + + + error = cff_index_access_element( idx, element, &bytes, &byte_len ); + if ( error ) + goto Exit; + + if ( !FT_ALLOC( name, byte_len + 1 ) ) + { + FT_MEM_COPY( name, bytes, byte_len ); + name[byte_len] = 0; + } + cff_index_forget_element( idx, &bytes ); + + Exit: + return name; + } + + + FT_LOCAL_DEF( FT_String* ) + cff_index_get_sid_string( CFF_Index idx, + FT_UInt sid, + FT_Service_PsCMaps psnames ) + { + /* value 0xFFFFU indicates a missing dictionary entry */ + if ( sid == 0xFFFFU ) + return 0; + + /* if it is not a standard string, return it */ + if ( sid > 390 ) + return cff_index_get_name( idx, sid - 391 ); + + /* CID-keyed CFF fonts don't have glyph names */ + if ( !psnames ) + return 0; + + /* that's a standard string, fetch a copy from the PSName module */ + { + FT_String* name = 0; + const char* adobe_name = psnames->adobe_std_strings( sid ); + + + if ( adobe_name ) + { + FT_Memory memory = idx->stream->memory; + FT_Error error; + + + (void)FT_STRDUP( name, adobe_name ); + + FT_UNUSED( error ); + } + + return name; + } + } + + + /*************************************************************************/ + /*************************************************************************/ + /*** ***/ + /*** FD Select table support ***/ + /*** ***/ + /*************************************************************************/ + /*************************************************************************/ + + + static void + CFF_Done_FD_Select( CFF_FDSelect fdselect, + FT_Stream stream ) + { + if ( fdselect->data ) + FT_FRAME_RELEASE( fdselect->data ); + + fdselect->data_size = 0; + fdselect->format = 0; + fdselect->range_count = 0; + } + + + static FT_Error + CFF_Load_FD_Select( CFF_FDSelect fdselect, + FT_UInt num_glyphs, + FT_Stream stream, + FT_ULong offset ) + { + FT_Error error; + FT_Byte format; + FT_UInt num_ranges; + + + /* read format */ + if ( FT_STREAM_SEEK( offset ) || FT_READ_BYTE( format ) ) + goto Exit; + + fdselect->format = format; + fdselect->cache_count = 0; /* clear cache */ + + switch ( format ) + { + case 0: /* format 0, that's simple */ + fdselect->data_size = num_glyphs; + goto Load_Data; + + case 3: /* format 3, a tad more complex */ + if ( FT_READ_USHORT( num_ranges ) ) + goto Exit; + + fdselect->data_size = num_ranges * 3 + 2; + + Load_Data: + if ( FT_FRAME_EXTRACT( fdselect->data_size, fdselect->data ) ) + goto Exit; + break; + + default: /* hmm... that's wrong */ + error = CFF_Err_Invalid_File_Format; + } + + Exit: + return error; + } + + + FT_LOCAL_DEF( FT_Byte ) + cff_fd_select_get( CFF_FDSelect fdselect, + FT_UInt glyph_index ) + { + FT_Byte fd = 0; + + + switch ( fdselect->format ) + { + case 0: + fd = fdselect->data[glyph_index]; + break; + + case 3: + /* first, compare to cache */ + if ( (FT_UInt)( glyph_index - fdselect->cache_first ) < + fdselect->cache_count ) + { + fd = fdselect->cache_fd; + break; + } + + /* then, lookup the ranges array */ + { + FT_Byte* p = fdselect->data; + FT_Byte* p_limit = p + fdselect->data_size; + FT_Byte fd2; + FT_UInt first, limit; + + + first = FT_NEXT_USHORT( p ); + do + { + if ( glyph_index < first ) + break; + + fd2 = *p++; + limit = FT_NEXT_USHORT( p ); + + if ( glyph_index < limit ) + { + fd = fd2; + + /* update cache */ + fdselect->cache_first = first; + fdselect->cache_count = limit-first; + fdselect->cache_fd = fd2; + break; + } + first = limit; + + } while ( p < p_limit ); + } + break; + + default: + ; + } + + return fd; + } + + + /*************************************************************************/ + /*************************************************************************/ + /*** ***/ + /*** CFF font support ***/ + /*** ***/ + /*************************************************************************/ + /*************************************************************************/ + + static FT_Error + cff_charset_compute_cids( CFF_Charset charset, + FT_UInt num_glyphs, + FT_Memory memory ) + { + FT_Error error = FT_Err_Ok; + FT_UInt i; + FT_Long j; + FT_UShort max_cid = 0; + + + if ( charset->max_cid > 0 ) + goto Exit; + + for ( i = 0; i < num_glyphs; i++ ) + if ( charset->sids[i] > max_cid ) + max_cid = charset->sids[i]; + max_cid++; + + if ( FT_NEW_ARRAY( charset->cids, max_cid ) ) + goto Exit; + + /* When multiple GIDs map to the same CID, we choose the lowest */ + /* GID. This is not described in any spec, but it matches the */ + /* behaviour of recent Acroread versions. */ + for ( j = num_glyphs - 1; j >= 0 ; j-- ) + charset->cids[charset->sids[j]] = (FT_UShort)j; + + charset->max_cid = max_cid; + charset->num_glyphs = num_glyphs; + + Exit: + return error; + } + + + FT_LOCAL_DEF( FT_UInt ) + cff_charset_cid_to_gindex( CFF_Charset charset, + FT_UInt cid ) + { + FT_UInt result = 0; + + + if ( cid < charset->max_cid ) + result = charset->cids[cid]; + + return result; + } + + + static void + cff_charset_free_cids( CFF_Charset charset, + FT_Memory memory ) + { + FT_FREE( charset->cids ); + charset->max_cid = 0; + } + + + static void + cff_charset_done( CFF_Charset charset, + FT_Stream stream ) + { + FT_Memory memory = stream->memory; + + + cff_charset_free_cids( charset, memory ); + + FT_FREE( charset->sids ); + charset->format = 0; + charset->offset = 0; + } + + + static FT_Error + cff_charset_load( CFF_Charset charset, + FT_UInt num_glyphs, + FT_Stream stream, + FT_ULong base_offset, + FT_ULong offset, + FT_Bool invert ) + { + FT_Memory memory = stream->memory; + FT_Error error = CFF_Err_Ok; + FT_UShort glyph_sid; + + + /* If the the offset is greater than 2, we have to parse the */ + /* charset table. */ + if ( offset > 2 ) + { + FT_UInt j; + + + charset->offset = base_offset + offset; + + /* Get the format of the table. */ + if ( FT_STREAM_SEEK( charset->offset ) || + FT_READ_BYTE( charset->format ) ) + goto Exit; + + /* Allocate memory for sids. */ + if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) ) + goto Exit; + + /* assign the .notdef glyph */ + charset->sids[0] = 0; + + switch ( charset->format ) + { + case 0: + if ( num_glyphs > 0 ) + { + if ( FT_FRAME_ENTER( ( num_glyphs - 1 ) * 2 ) ) + goto Exit; + + for ( j = 1; j < num_glyphs; j++ ) + { + FT_UShort sid = FT_GET_USHORT(); + + + /* this constant is given in the CFF specification */ + if ( sid < 65000L ) + charset->sids[j] = sid; + else + { + FT_TRACE0(( "cff_charset_load:" + " invalid SID value %d set to zero\n", sid )); + charset->sids[j] = 0; + } + } + + FT_FRAME_EXIT(); + } + break; + + case 1: + case 2: + { + FT_UInt nleft; + FT_UInt i; + + + j = 1; + + while ( j < num_glyphs ) + { + /* Read the first glyph sid of the range. */ + if ( FT_READ_USHORT( glyph_sid ) ) + goto Exit; + + /* Read the number of glyphs in the range. */ + if ( charset->format == 2 ) + { + if ( FT_READ_USHORT( nleft ) ) + goto Exit; + } + else + { + if ( FT_READ_BYTE( nleft ) ) + goto Exit; + } + + /* check whether the range contains at least one valid glyph; */ + /* the constant is given in the CFF specification */ + if ( glyph_sid >= 65000L ) { + FT_ERROR(( "cff_charset_load: invalid SID range\n" )); + error = CFF_Err_Invalid_File_Format; + goto Exit; + } + + /* try to rescue some of the SIDs if `nleft' is too large */ + if ( nleft > 65000L - 1L || glyph_sid >= 65000L - nleft ) { + FT_ERROR(( "cff_charset_load: invalid SID range trimmed\n" )); + nleft = ( FT_UInt )( 65000L - 1L - glyph_sid ); + } + + /* Fill in the range of sids -- `nleft + 1' glyphs. */ + for ( i = 0; j < num_glyphs && i <= nleft; i++, j++, glyph_sid++ ) + charset->sids[j] = glyph_sid; + } + } + break; + + default: + FT_ERROR(( "cff_charset_load: invalid table format\n" )); + error = CFF_Err_Invalid_File_Format; + goto Exit; + } + } + else + { + /* Parse default tables corresponding to offset == 0, 1, or 2. */ + /* CFF specification intimates the following: */ + /* */ + /* In order to use a predefined charset, the following must be */ + /* true: The charset constructed for the glyphs in the font's */ + /* charstrings dictionary must match the predefined charset in */ + /* the first num_glyphs. */ + + charset->offset = offset; /* record charset type */ + + switch ( (FT_UInt)offset ) + { + case 0: + if ( num_glyphs > 229 ) + { + FT_ERROR(( "cff_charset_load: implicit charset larger than\n" + "predefined charset (Adobe ISO-Latin)\n" )); + error = CFF_Err_Invalid_File_Format; + goto Exit; + } + + /* Allocate memory for sids. */ + if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) ) + goto Exit; + + /* Copy the predefined charset into the allocated memory. */ + FT_ARRAY_COPY( charset->sids, cff_isoadobe_charset, num_glyphs ); + + break; + + case 1: + if ( num_glyphs > 166 ) + { + FT_ERROR(( "cff_charset_load: implicit charset larger than\n" + "predefined charset (Adobe Expert)\n" )); + error = CFF_Err_Invalid_File_Format; + goto Exit; + } + + /* Allocate memory for sids. */ + if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) ) + goto Exit; + + /* Copy the predefined charset into the allocated memory. */ + FT_ARRAY_COPY( charset->sids, cff_expert_charset, num_glyphs ); + + break; + + case 2: + if ( num_glyphs > 87 ) + { + FT_ERROR(( "cff_charset_load: implicit charset larger than\n" + "predefined charset (Adobe Expert Subset)\n" )); + error = CFF_Err_Invalid_File_Format; + goto Exit; + } + + /* Allocate memory for sids. */ + if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) ) + goto Exit; + + /* Copy the predefined charset into the allocated memory. */ + FT_ARRAY_COPY( charset->sids, cff_expertsubset_charset, num_glyphs ); + + break; + + default: + error = CFF_Err_Invalid_File_Format; + goto Exit; + } + } + + /* we have to invert the `sids' array for subsetted CID-keyed fonts */ + if ( invert ) + error = cff_charset_compute_cids( charset, num_glyphs, memory ); + + Exit: + /* Clean up if there was an error. */ + if ( error ) + { + FT_FREE( charset->sids ); + FT_FREE( charset->cids ); + charset->format = 0; + charset->offset = 0; + charset->sids = 0; + } + + return error; + } + + + static void + cff_encoding_done( CFF_Encoding encoding ) + { + encoding->format = 0; + encoding->offset = 0; + encoding->count = 0; + } + + + static FT_Error + cff_encoding_load( CFF_Encoding encoding, + CFF_Charset charset, + FT_UInt num_glyphs, + FT_Stream stream, + FT_ULong base_offset, + FT_ULong offset ) + { + FT_Error error = CFF_Err_Ok; + FT_UInt count; + FT_UInt j; + FT_UShort glyph_sid; + FT_UInt glyph_code; + + + /* Check for charset->sids. If we do not have this, we fail. */ + if ( !charset->sids ) + { + error = CFF_Err_Invalid_File_Format; + goto Exit; + } + + /* Zero out the code to gid/sid mappings. */ + for ( j = 0; j < 256; j++ ) + { + encoding->sids [j] = 0; + encoding->codes[j] = 0; + } + + /* Note: The encoding table in a CFF font is indexed by glyph index; */ + /* the first encoded glyph index is 1. Hence, we read the character */ + /* code (`glyph_code') at index j and make the assignment: */ + /* */ + /* encoding->codes[glyph_code] = j + 1 */ + /* */ + /* We also make the assignment: */ + /* */ + /* encoding->sids[glyph_code] = charset->sids[j + 1] */ + /* */ + /* This gives us both a code to GID and a code to SID mapping. */ + + if ( offset > 1 ) + { + encoding->offset = base_offset + offset; + + /* we need to parse the table to determine its size */ + if ( FT_STREAM_SEEK( encoding->offset ) || + FT_READ_BYTE( encoding->format ) || + FT_READ_BYTE( count ) ) + goto Exit; + + switch ( encoding->format & 0x7F ) + { + case 0: + { + FT_Byte* p; + + + /* By convention, GID 0 is always ".notdef" and is never */ + /* coded in the font. Hence, the number of codes found */ + /* in the table is `count+1'. */ + /* */ + encoding->count = count + 1; + + if ( FT_FRAME_ENTER( count ) ) + goto Exit; + + p = (FT_Byte*)stream->cursor; + + for ( j = 1; j <= count; j++ ) + { + glyph_code = *p++; + + /* Make sure j is not too big. */ + if ( j < num_glyphs ) + { + /* Assign code to GID mapping. */ + encoding->codes[glyph_code] = (FT_UShort)j; + + /* Assign code to SID mapping. */ + encoding->sids[glyph_code] = charset->sids[j]; + } + } + + FT_FRAME_EXIT(); + } + break; + + case 1: + { + FT_UInt nleft; + FT_UInt i = 1; + FT_UInt k; + + + encoding->count = 0; + + /* Parse the Format1 ranges. */ + for ( j = 0; j < count; j++, i += nleft ) + { + /* Read the first glyph code of the range. */ + if ( FT_READ_BYTE( glyph_code ) ) + goto Exit; + + /* Read the number of codes in the range. */ + if ( FT_READ_BYTE( nleft ) ) + goto Exit; + + /* Increment nleft, so we read `nleft + 1' codes/sids. */ + nleft++; + + /* compute max number of character codes */ + if ( (FT_UInt)nleft > encoding->count ) + encoding->count = nleft; + + /* Fill in the range of codes/sids. */ + for ( k = i; k < nleft + i; k++, glyph_code++ ) + { + /* Make sure k is not too big. */ + if ( k < num_glyphs && glyph_code < 256 ) + { + /* Assign code to GID mapping. */ + encoding->codes[glyph_code] = (FT_UShort)k; + + /* Assign code to SID mapping. */ + encoding->sids[glyph_code] = charset->sids[k]; + } + } + } + + /* simple check; one never knows what can be found in a font */ + if ( encoding->count > 256 ) + encoding->count = 256; + } + break; + + default: + FT_ERROR(( "cff_encoding_load: invalid table format\n" )); + error = CFF_Err_Invalid_File_Format; + goto Exit; + } + + /* Parse supplemental encodings, if any. */ + if ( encoding->format & 0x80 ) + { + FT_UInt gindex; + + + /* count supplements */ + if ( FT_READ_BYTE( count ) ) + goto Exit; + + for ( j = 0; j < count; j++ ) + { + /* Read supplemental glyph code. */ + if ( FT_READ_BYTE( glyph_code ) ) + goto Exit; + + /* Read the SID associated with this glyph code. */ + if ( FT_READ_USHORT( glyph_sid ) ) + goto Exit; + + /* Assign code to SID mapping. */ + encoding->sids[glyph_code] = glyph_sid; + + /* First, look up GID which has been assigned to */ + /* SID glyph_sid. */ + for ( gindex = 0; gindex < num_glyphs; gindex++ ) + { + if ( charset->sids[gindex] == glyph_sid ) + { + encoding->codes[glyph_code] = (FT_UShort)gindex; + break; + } + } + } + } + } + else + { + /* We take into account the fact a CFF font can use a predefined */ + /* encoding without containing all of the glyphs encoded by this */ + /* encoding (see the note at the end of section 12 in the CFF */ + /* specification). */ + + switch ( (FT_UInt)offset ) + { + case 0: + /* First, copy the code to SID mapping. */ + FT_ARRAY_COPY( encoding->sids, cff_standard_encoding, 256 ); + goto Populate; + + case 1: + /* First, copy the code to SID mapping. */ + FT_ARRAY_COPY( encoding->sids, cff_expert_encoding, 256 ); + + Populate: + /* Construct code to GID mapping from code to SID mapping */ + /* and charset. */ + + encoding->count = 0; + + error = cff_charset_compute_cids( charset, num_glyphs, + stream->memory ); + if ( error ) + goto Exit; + + for ( j = 0; j < 256; j++ ) + { + FT_UInt sid = encoding->sids[j]; + FT_UInt gid = 0; + + + if ( sid ) + gid = cff_charset_cid_to_gindex( charset, sid ); + + if ( gid != 0 ) + { + encoding->codes[j] = (FT_UShort)gid; + + if ( encoding->count < j + 1 ) + encoding->count = j + 1; + } + else + { + encoding->codes[j] = 0; + encoding->sids [j] = 0; + } + } + break; + + default: + FT_ERROR(( "cff_encoding_load: invalid table format\n" )); + error = CFF_Err_Invalid_File_Format; + goto Exit; + } + } + + Exit: + + /* Clean up if there was an error. */ + return error; + } + + + static FT_Error + cff_subfont_load( CFF_SubFont font, + CFF_Index idx, + FT_UInt font_index, + FT_Stream stream, + FT_ULong base_offset, + FT_Library library ) + { + FT_Error error; + CFF_ParserRec parser; + FT_Byte* dict = NULL; + FT_ULong dict_len; + CFF_FontRecDict top = &font->font_dict; + CFF_Private priv = &font->private_dict; + + + cff_parser_init( &parser, CFF_CODE_TOPDICT, &font->font_dict, library ); + + /* set defaults */ + FT_MEM_ZERO( top, sizeof ( *top ) ); + + top->underline_position = -100L << 16; + top->underline_thickness = 50L << 16; + top->charstring_type = 2; + top->font_matrix.xx = 0x10000L; + top->font_matrix.yy = 0x10000L; + top->cid_count = 8720; + + /* we use the implementation specific SID value 0xFFFF to indicate */ + /* missing entries */ + top->version = 0xFFFFU; + top->notice = 0xFFFFU; + top->copyright = 0xFFFFU; + top->full_name = 0xFFFFU; + top->family_name = 0xFFFFU; + top->weight = 0xFFFFU; + top->embedded_postscript = 0xFFFFU; + + top->cid_registry = 0xFFFFU; + top->cid_ordering = 0xFFFFU; + top->cid_font_name = 0xFFFFU; + + error = cff_index_access_element( idx, font_index, &dict, &dict_len ); + if ( !error ) + error = cff_parser_run( &parser, dict, dict + dict_len ); + + cff_index_forget_element( idx, &dict ); + + if ( error ) + goto Exit; + + /* if it is a CID font, we stop there */ + if ( top->cid_registry != 0xFFFFU ) + goto Exit; + + /* parse the private dictionary, if any */ + if ( top->private_offset && top->private_size ) + { + /* set defaults */ + FT_MEM_ZERO( priv, sizeof ( *priv ) ); + + priv->blue_shift = 7; + priv->blue_fuzz = 1; + priv->lenIV = -1; + priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L ); + priv->blue_scale = (FT_Fixed)( 0.039625 * 0x10000L * 1000 ); + + cff_parser_init( &parser, CFF_CODE_PRIVATE, priv, library ); + + if ( FT_STREAM_SEEK( base_offset + font->font_dict.private_offset ) || + FT_FRAME_ENTER( font->font_dict.private_size ) ) + goto Exit; + + error = cff_parser_run( &parser, + (FT_Byte*)stream->cursor, + (FT_Byte*)stream->limit ); + FT_FRAME_EXIT(); + if ( error ) + goto Exit; + + /* ensure that `num_blue_values' is even */ + priv->num_blue_values &= ~1; + } + + /* read the local subrs, if any */ + if ( priv->local_subrs_offset ) + { + if ( FT_STREAM_SEEK( base_offset + top->private_offset + + priv->local_subrs_offset ) ) + goto Exit; + + error = cff_index_init( &font->local_subrs_index, stream, 1 ); + if ( error ) + goto Exit; + + font->num_local_subrs = font->local_subrs_index.count; + error = cff_index_get_pointers( &font->local_subrs_index, + &font->local_subrs ); + if ( error ) + goto Exit; + } + + Exit: + return error; + } + + + static void + cff_subfont_done( FT_Memory memory, + CFF_SubFont subfont ) + { + if ( subfont ) + { + cff_index_done( &subfont->local_subrs_index ); + FT_FREE( subfont->local_subrs ); + } + } + + + FT_LOCAL_DEF( FT_Error ) + cff_font_load( FT_Library library, + FT_Stream stream, + FT_Int face_index, + CFF_Font font, + FT_Bool pure_cff ) + { + static const FT_Frame_Field cff_header_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE CFF_FontRec + + FT_FRAME_START( 4 ), + FT_FRAME_BYTE( version_major ), + FT_FRAME_BYTE( version_minor ), + FT_FRAME_BYTE( header_size ), + FT_FRAME_BYTE( absolute_offsize ), + FT_FRAME_END + }; + + FT_Error error; + FT_Memory memory = stream->memory; + FT_ULong base_offset; + CFF_FontRecDict dict; + + + FT_ZERO( font ); + + font->stream = stream; + font->memory = memory; + dict = &font->top_font.font_dict; + base_offset = FT_STREAM_POS(); + + /* read CFF font header */ + if ( FT_STREAM_READ_FIELDS( cff_header_fields, font ) ) + goto Exit; + + /* check format */ + if ( font->version_major != 1 || + font->header_size < 4 || + font->absolute_offsize > 4 ) + { + FT_TRACE2(( "[not a CFF font header]\n" )); + error = CFF_Err_Unknown_File_Format; + goto Exit; + } + + /* skip the rest of the header */ + if ( FT_STREAM_SKIP( font->header_size - 4 ) ) + goto Exit; + + /* read the name, top dict, string and global subrs index */ + if ( FT_SET_ERROR( cff_index_init( &font->name_index, + stream, 0 ) ) || + FT_SET_ERROR( cff_index_init( &font->font_dict_index, + stream, 0 ) ) || + FT_SET_ERROR( cff_index_init( &font->string_index, + stream, 0 ) ) || + FT_SET_ERROR( cff_index_init( &font->global_subrs_index, + stream, 1 ) ) ) + goto Exit; + + /* well, we don't really forget the `disabled' fonts... */ + font->num_faces = font->name_index.count; + if ( face_index >= (FT_Int)font->num_faces ) + { + FT_ERROR(( "cff_font_load: incorrect face index = %d\n", + face_index )); + error = CFF_Err_Invalid_Argument; + } + + /* in case of a font format check, simply exit now */ + if ( face_index < 0 ) + goto Exit; + + /* now, parse the top-level font dictionary */ + error = cff_subfont_load( &font->top_font, + &font->font_dict_index, + face_index, + stream, + base_offset, + library ); + if ( error ) + goto Exit; + + if ( FT_STREAM_SEEK( base_offset + dict->charstrings_offset ) ) + goto Exit; + + error = cff_index_init( &font->charstrings_index, stream, 0 ); + if ( error ) + goto Exit; + + /* now, check for a CID font */ + if ( dict->cid_registry != 0xFFFFU ) + { + CFF_IndexRec fd_index; + CFF_SubFont sub; + FT_UInt idx; + + + /* this is a CID-keyed font, we must now allocate a table of */ + /* sub-fonts, then load each of them separately */ + if ( FT_STREAM_SEEK( base_offset + dict->cid_fd_array_offset ) ) + goto Exit; + + error = cff_index_init( &fd_index, stream, 0 ); + if ( error ) + goto Exit; + + if ( fd_index.count > CFF_MAX_CID_FONTS ) + { + FT_TRACE0(( "cff_font_load: FD array too large in CID font\n" )); + goto Fail_CID; + } + + /* allocate & read each font dict independently */ + font->num_subfonts = fd_index.count; + if ( FT_NEW_ARRAY( sub, fd_index.count ) ) + goto Fail_CID; + + /* set up pointer table */ + for ( idx = 0; idx < fd_index.count; idx++ ) + font->subfonts[idx] = sub + idx; + + /* now load each subfont independently */ + for ( idx = 0; idx < fd_index.count; idx++ ) + { + sub = font->subfonts[idx]; + error = cff_subfont_load( sub, &fd_index, idx, + stream, base_offset, library ); + if ( error ) + goto Fail_CID; + } + + /* now load the FD Select array */ + error = CFF_Load_FD_Select( &font->fd_select, + font->charstrings_index.count, + stream, + base_offset + dict->cid_fd_select_offset ); + + Fail_CID: + cff_index_done( &fd_index ); + + if ( error ) + goto Exit; + } + else + font->num_subfonts = 0; + + /* read the charstrings index now */ + if ( dict->charstrings_offset == 0 ) + { + FT_ERROR(( "cff_font_load: no charstrings offset\n" )); + error = CFF_Err_Unknown_File_Format; + goto Exit; + } + + /* explicit the global subrs */ + font->num_global_subrs = font->global_subrs_index.count; + font->num_glyphs = font->charstrings_index.count; + + error = cff_index_get_pointers( &font->global_subrs_index, + &font->global_subrs ) ; + + if ( error ) + goto Exit; + + /* read the Charset and Encoding tables if available */ + if ( font->num_glyphs > 0 ) + { + FT_Bool invert = FT_BOOL( dict->cid_registry != 0xFFFFU && pure_cff ); + + + error = cff_charset_load( &font->charset, font->num_glyphs, stream, + base_offset, dict->charset_offset, invert ); + if ( error ) + goto Exit; + + /* CID-keyed CFFs don't have an encoding */ + if ( dict->cid_registry == 0xFFFFU ) + { + error = cff_encoding_load( &font->encoding, + &font->charset, + font->num_glyphs, + stream, + base_offset, + dict->encoding_offset ); + if ( error ) + goto Exit; + } + } + + /* get the font name (/CIDFontName for CID-keyed fonts, */ + /* /FontName otherwise) */ + font->font_name = cff_index_get_name( &font->name_index, face_index ); + + Exit: + return error; + } + + + FT_LOCAL_DEF( void ) + cff_font_done( CFF_Font font ) + { + FT_Memory memory = font->memory; + FT_UInt idx; + + + cff_index_done( &font->global_subrs_index ); + cff_index_done( &font->string_index ); + cff_index_done( &font->font_dict_index ); + cff_index_done( &font->name_index ); + cff_index_done( &font->charstrings_index ); + + /* release font dictionaries, but only if working with */ + /* a CID keyed CFF font */ + if ( font->num_subfonts > 0 ) + { + for ( idx = 0; idx < font->num_subfonts; idx++ ) + cff_subfont_done( memory, font->subfonts[idx] ); + + /* the subfonts array has been allocated as a single block */ + FT_FREE( font->subfonts[0] ); + } + + cff_encoding_done( &font->encoding ); + cff_charset_done( &font->charset, font->stream ); + + cff_subfont_done( memory, &font->top_font ); + + CFF_Done_FD_Select( &font->fd_select, font->stream ); + + if (font->font_info != NULL) + { + FT_FREE( font->font_info->version ); + FT_FREE( font->font_info->notice ); + FT_FREE( font->font_info->full_name ); + FT_FREE( font->font_info->family_name ); + FT_FREE( font->font_info->weight ); + FT_FREE( font->font_info ); + } + + FT_FREE( font->registry ); + FT_FREE( font->ordering ); + + FT_FREE( font->global_subrs ); + FT_FREE( font->font_name ); + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/cff/cffload.h b/mod/pub.mod/freetype.mod/src/cff/cffload.h new file mode 100644 index 0000000..2b313ac --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/cff/cffload.h @@ -0,0 +1,81 @@ +/***************************************************************************/ +/* */ +/* cffload.h */ +/* */ +/* OpenType & CFF data/program tables loader (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2007, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __CFFLOAD_H__ +#define __CFFLOAD_H__ + + +#include <ft2build.h> +#include "cfftypes.h" +#include FT_SERVICE_POSTSCRIPT_CMAPS_H + + +FT_BEGIN_HEADER + + FT_LOCAL( FT_UShort ) + cff_get_standard_encoding( FT_UInt charcode ); + + + FT_LOCAL( FT_String* ) + cff_index_get_name( CFF_Index idx, + FT_UInt element ); + + FT_LOCAL( FT_String* ) + cff_index_get_sid_string( CFF_Index idx, + FT_UInt sid, + FT_Service_PsCMaps psnames ); + + + FT_LOCAL( FT_Error ) + cff_index_access_element( CFF_Index idx, + FT_UInt element, + FT_Byte** pbytes, + FT_ULong* pbyte_len ); + + FT_LOCAL( void ) + cff_index_forget_element( CFF_Index idx, + FT_Byte** pbytes ); + + + FT_LOCAL( FT_UInt ) + cff_charset_cid_to_gindex( CFF_Charset charset, + FT_UInt cid ); + + + FT_LOCAL( FT_Error ) + cff_font_load( FT_Library library, + FT_Stream stream, + FT_Int face_index, + CFF_Font font, + FT_Bool pure_cff ); + + FT_LOCAL( void ) + cff_font_done( CFF_Font font ); + + + FT_LOCAL( FT_Byte ) + cff_fd_select_get( CFF_FDSelect fdselect, + FT_UInt glyph_index ); + + +FT_END_HEADER + +#endif /* __CFFLOAD_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/cff/cffobjs.c b/mod/pub.mod/freetype.mod/src/cff/cffobjs.c new file mode 100644 index 0000000..e0966e0 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/cff/cffobjs.c @@ -0,0 +1,967 @@ +/***************************************************************************/ +/* */ +/* cffobjs.c */ +/* */ +/* OpenType objects manager (body). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_CALC_H +#include FT_INTERNAL_STREAM_H +#include FT_ERRORS_H +#include FT_TRUETYPE_IDS_H +#include FT_TRUETYPE_TAGS_H +#include FT_INTERNAL_SFNT_H +#include FT_SERVICE_POSTSCRIPT_CMAPS_H +#include FT_INTERNAL_POSTSCRIPT_HINTS_H +#include "cffobjs.h" +#include "cffload.h" +#include "cffcmap.h" +#include "cfferrs.h" +#include "cffpic.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_cffobjs + + + /*************************************************************************/ + /* */ + /* SIZE FUNCTIONS */ + /* */ + /* Note that we store the global hints in the size's `internal' root */ + /* field. */ + /* */ + /*************************************************************************/ + + + static PSH_Globals_Funcs + cff_size_get_globals_funcs( CFF_Size size ) + { + CFF_Face face = (CFF_Face)size->root.face; + CFF_Font font = (CFF_Font)face->extra.data; + PSHinter_Service pshinter = (PSHinter_Service)font->pshinter; + FT_Module module; + + + module = FT_Get_Module( size->root.face->driver->root.library, + "pshinter" ); + return ( module && pshinter && pshinter->get_globals_funcs ) + ? pshinter->get_globals_funcs( module ) + : 0; + } + + + FT_LOCAL_DEF( void ) + cff_size_done( FT_Size cffsize ) /* CFF_Size */ + { + CFF_Size size = (CFF_Size)cffsize; + CFF_Face face = (CFF_Face)size->root.face; + CFF_Font font = (CFF_Font)face->extra.data; + CFF_Internal internal = (CFF_Internal)cffsize->internal; + + + if ( internal ) + { + PSH_Globals_Funcs funcs; + + + funcs = cff_size_get_globals_funcs( size ); + if ( funcs ) + { + FT_UInt i; + + + funcs->destroy( internal->topfont ); + + for ( i = font->num_subfonts; i > 0; i-- ) + funcs->destroy( internal->subfonts[i - 1] ); + } + + /* `internal' is freed by destroy_size (in ftobjs.c) */ + } + } + + + /* CFF and Type 1 private dictionaries have slightly different */ + /* structures; we need to synthesize a Type 1 dictionary on the fly */ + + static void + cff_make_private_dict( CFF_SubFont subfont, + PS_Private priv ) + { + CFF_Private cpriv = &subfont->private_dict; + FT_UInt n, count; + + + FT_MEM_ZERO( priv, sizeof ( *priv ) ); + + count = priv->num_blue_values = cpriv->num_blue_values; + for ( n = 0; n < count; n++ ) + priv->blue_values[n] = (FT_Short)cpriv->blue_values[n]; + + count = priv->num_other_blues = cpriv->num_other_blues; + for ( n = 0; n < count; n++ ) + priv->other_blues[n] = (FT_Short)cpriv->other_blues[n]; + + count = priv->num_family_blues = cpriv->num_family_blues; + for ( n = 0; n < count; n++ ) + priv->family_blues[n] = (FT_Short)cpriv->family_blues[n]; + + count = priv->num_family_other_blues = cpriv->num_family_other_blues; + for ( n = 0; n < count; n++ ) + priv->family_other_blues[n] = (FT_Short)cpriv->family_other_blues[n]; + + priv->blue_scale = cpriv->blue_scale; + priv->blue_shift = (FT_Int)cpriv->blue_shift; + priv->blue_fuzz = (FT_Int)cpriv->blue_fuzz; + + priv->standard_width[0] = (FT_UShort)cpriv->standard_width; + priv->standard_height[0] = (FT_UShort)cpriv->standard_height; + + count = priv->num_snap_widths = cpriv->num_snap_widths; + for ( n = 0; n < count; n++ ) + priv->snap_widths[n] = (FT_Short)cpriv->snap_widths[n]; + + count = priv->num_snap_heights = cpriv->num_snap_heights; + for ( n = 0; n < count; n++ ) + priv->snap_heights[n] = (FT_Short)cpriv->snap_heights[n]; + + priv->force_bold = cpriv->force_bold; + priv->language_group = cpriv->language_group; + priv->lenIV = cpriv->lenIV; + } + + + FT_LOCAL_DEF( FT_Error ) + cff_size_init( FT_Size cffsize ) /* CFF_Size */ + { + CFF_Size size = (CFF_Size)cffsize; + FT_Error error = CFF_Err_Ok; + PSH_Globals_Funcs funcs = cff_size_get_globals_funcs( size ); + + + if ( funcs ) + { + CFF_Face face = (CFF_Face)cffsize->face; + CFF_Font font = (CFF_Font)face->extra.data; + CFF_Internal internal; + + PS_PrivateRec priv; + FT_Memory memory = cffsize->face->memory; + + FT_UInt i; + + + if ( FT_NEW( internal ) ) + goto Exit; + + cff_make_private_dict( &font->top_font, &priv ); + error = funcs->create( cffsize->face->memory, &priv, + &internal->topfont ); + if ( error ) + goto Exit; + + for ( i = font->num_subfonts; i > 0; i-- ) + { + CFF_SubFont sub = font->subfonts[i - 1]; + + + cff_make_private_dict( sub, &priv ); + error = funcs->create( cffsize->face->memory, &priv, + &internal->subfonts[i - 1] ); + if ( error ) + goto Exit; + } + + cffsize->internal = (FT_Size_Internal)(void*)internal; + } + + size->strike_index = 0xFFFFFFFFUL; + + Exit: + return error; + } + + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + + FT_LOCAL_DEF( FT_Error ) + cff_size_select( FT_Size size, + FT_ULong strike_index ) + { + CFF_Size cffsize = (CFF_Size)size; + PSH_Globals_Funcs funcs; + + + cffsize->strike_index = strike_index; + + FT_Select_Metrics( size->face, strike_index ); + + funcs = cff_size_get_globals_funcs( cffsize ); + + if ( funcs ) + { + CFF_Face face = (CFF_Face)size->face; + CFF_Font font = (CFF_Font)face->extra.data; + CFF_Internal internal = (CFF_Internal)size->internal; + + FT_ULong top_upm = font->top_font.font_dict.units_per_em; + FT_UInt i; + + + funcs->set_scale( internal->topfont, + size->metrics.x_scale, size->metrics.y_scale, + 0, 0 ); + + for ( i = font->num_subfonts; i > 0; i-- ) + { + CFF_SubFont sub = font->subfonts[i - 1]; + FT_ULong sub_upm = sub->font_dict.units_per_em; + FT_Pos x_scale, y_scale; + + + if ( top_upm != sub_upm ) + { + x_scale = FT_MulDiv( size->metrics.x_scale, top_upm, sub_upm ); + y_scale = FT_MulDiv( size->metrics.y_scale, top_upm, sub_upm ); + } + else + { + x_scale = size->metrics.x_scale; + y_scale = size->metrics.y_scale; + } + + funcs->set_scale( internal->subfonts[i - 1], + x_scale, y_scale, 0, 0 ); + } + } + + return CFF_Err_Ok; + } + +#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ + + + FT_LOCAL_DEF( FT_Error ) + cff_size_request( FT_Size size, + FT_Size_Request req ) + { + CFF_Size cffsize = (CFF_Size)size; + PSH_Globals_Funcs funcs; + + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + + if ( FT_HAS_FIXED_SIZES( size->face ) ) + { + CFF_Face cffface = (CFF_Face)size->face; + SFNT_Service sfnt = (SFNT_Service)cffface->sfnt; + FT_ULong strike_index; + + + if ( sfnt->set_sbit_strike( cffface, req, &strike_index ) ) + cffsize->strike_index = 0xFFFFFFFFUL; + else + return cff_size_select( size, strike_index ); + } + +#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ + + FT_Request_Metrics( size->face, req ); + + funcs = cff_size_get_globals_funcs( cffsize ); + + if ( funcs ) + { + CFF_Face cffface = (CFF_Face)size->face; + CFF_Font font = (CFF_Font)cffface->extra.data; + CFF_Internal internal = (CFF_Internal)size->internal; + + FT_ULong top_upm = font->top_font.font_dict.units_per_em; + FT_UInt i; + + + funcs->set_scale( internal->topfont, + size->metrics.x_scale, size->metrics.y_scale, + 0, 0 ); + + for ( i = font->num_subfonts; i > 0; i-- ) + { + CFF_SubFont sub = font->subfonts[i - 1]; + FT_ULong sub_upm = sub->font_dict.units_per_em; + FT_Pos x_scale, y_scale; + + + if ( top_upm != sub_upm ) + { + x_scale = FT_MulDiv( size->metrics.x_scale, top_upm, sub_upm ); + y_scale = FT_MulDiv( size->metrics.y_scale, top_upm, sub_upm ); + } + else + { + x_scale = size->metrics.x_scale; + y_scale = size->metrics.y_scale; + } + + funcs->set_scale( internal->subfonts[i - 1], + x_scale, y_scale, 0, 0 ); + } + } + + return CFF_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* SLOT FUNCTIONS */ + /* */ + /*************************************************************************/ + + FT_LOCAL_DEF( void ) + cff_slot_done( FT_GlyphSlot slot ) + { + slot->internal->glyph_hints = 0; + } + + + FT_LOCAL_DEF( FT_Error ) + cff_slot_init( FT_GlyphSlot slot ) + { + CFF_Face face = (CFF_Face)slot->face; + CFF_Font font = (CFF_Font)face->extra.data; + PSHinter_Service pshinter = (PSHinter_Service)font->pshinter; + + + if ( pshinter ) + { + FT_Module module; + + + module = FT_Get_Module( slot->face->driver->root.library, + "pshinter" ); + if ( module ) + { + T2_Hints_Funcs funcs; + + + funcs = pshinter->get_t2_funcs( module ); + slot->internal->glyph_hints = (void*)funcs; + } + } + + return CFF_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* FACE FUNCTIONS */ + /* */ + /*************************************************************************/ + + static FT_String* + cff_strcpy( FT_Memory memory, + const FT_String* source ) + { + FT_Error error; + FT_String* result; + + + (void)FT_STRDUP( result, source ); + + FT_UNUSED( error ); + + return result; + } + + + FT_LOCAL_DEF( FT_Error ) + cff_face_init( FT_Stream stream, + FT_Face cffface, /* CFF_Face */ + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ) + { + CFF_Face face = (CFF_Face)cffface; + FT_Error error; + SFNT_Service sfnt; + FT_Service_PsCMaps psnames; + PSHinter_Service pshinter; + FT_Bool pure_cff = 1; + FT_Bool sfnt_format = 0; + FT_Library library = cffface->driver->root.library; + + +#if 0 + FT_FACE_FIND_GLOBAL_SERVICE( face, sfnt, SFNT ); + FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_NAMES ); + FT_FACE_FIND_GLOBAL_SERVICE( face, pshinter, POSTSCRIPT_HINTER ); + + if ( !sfnt ) + goto Bad_Format; +#else + sfnt = (SFNT_Service)FT_Get_Module_Interface( + library, "sfnt" ); + if ( !sfnt ) + goto Bad_Format; + + FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); + + pshinter = (PSHinter_Service)FT_Get_Module_Interface( + library, "pshinter" ); +#endif + + /* create input stream from resource */ + if ( FT_STREAM_SEEK( 0 ) ) + goto Exit; + + /* check whether we have a valid OpenType file */ + error = sfnt->init_face( stream, face, face_index, num_params, params ); + if ( !error ) + { + if ( face->format_tag != TTAG_OTTO ) /* `OTTO'; OpenType/CFF font */ + { + FT_TRACE2(( "[not a valid OpenType/CFF font]\n" )); + goto Bad_Format; + } + + /* if we are performing a simple font format check, exit immediately */ + if ( face_index < 0 ) + return CFF_Err_Ok; + + /* UNDOCUMENTED! A CFF in an SFNT can have only a single font. */ + if ( face_index > 0 ) + { + FT_ERROR(( "cff_face_init: invalid face index\n" )); + error = CFF_Err_Invalid_Argument; + goto Exit; + } + + sfnt_format = 1; + + /* now, the font can be either an OpenType/CFF font, or an SVG CEF */ + /* font; in the latter case it doesn't have a `head' table */ + error = face->goto_table( face, TTAG_head, stream, 0 ); + if ( !error ) + { + pure_cff = 0; + + /* load font directory */ + error = sfnt->load_face( stream, face, 0, num_params, params ); + if ( error ) + goto Exit; + } + else + { + /* load the `cmap' table explicitly */ + error = sfnt->load_cmap( face, stream ); + if ( error ) + goto Exit; + + /* XXX: we don't load the GPOS table, as OpenType Layout */ + /* support will be added later to a layout library on top of */ + /* FreeType 2 */ + } + + /* now load the CFF part of the file */ + error = face->goto_table( face, TTAG_CFF, stream, 0 ); + if ( error ) + goto Exit; + } + else + { + /* rewind to start of file; we are going to load a pure-CFF font */ + if ( FT_STREAM_SEEK( 0 ) ) + goto Exit; + error = CFF_Err_Ok; + } + + /* now load and parse the CFF table in the file */ + { + CFF_Font cff; + CFF_FontRecDict dict; + FT_Memory memory = cffface->memory; + FT_Int32 flags; + FT_UInt i; + + + if ( FT_NEW( cff ) ) + goto Exit; + + face->extra.data = cff; + error = cff_font_load( library, stream, face_index, cff, pure_cff ); + if ( error ) + goto Exit; + + cff->pshinter = pshinter; + cff->psnames = (void*)psnames; + + cffface->face_index = face_index; + + /* Complement the root flags with some interesting information. */ + /* Note that this is only necessary for pure CFF and CEF fonts; */ + /* SFNT based fonts use the `name' table instead. */ + + cffface->num_glyphs = cff->num_glyphs; + + dict = &cff->top_font.font_dict; + + /* we need the `PSNames' module for CFF and CEF formats */ + /* which aren't CID-keyed */ + if ( dict->cid_registry == 0xFFFFU && !psnames ) + { + FT_ERROR(( "cff_face_init:" + " cannot open CFF & CEF fonts\n" + " " + " without the `PSNames' module\n" )); + goto Bad_Format; + } + + if ( !dict->units_per_em ) + dict->units_per_em = pure_cff ? 1000 : face->root.units_per_EM; + + /* Normalize the font matrix so that `matrix->xx' is 1; the */ + /* scaling is done with `units_per_em' then (at this point, */ + /* it already contains the scaling factor, but without */ + /* normalization of the matrix). */ + /* */ + /* Note that the offsets must be expressed in integer font */ + /* units. */ + + { + FT_Matrix* matrix = &dict->font_matrix; + FT_Vector* offset = &dict->font_offset; + FT_ULong* upm = &dict->units_per_em; + FT_Fixed temp = FT_ABS( matrix->yy ); + + + if ( temp != 0x10000L ) + { + *upm = FT_DivFix( *upm, temp ); + + matrix->xx = FT_DivFix( matrix->xx, temp ); + matrix->yx = FT_DivFix( matrix->yx, temp ); + matrix->xy = FT_DivFix( matrix->xy, temp ); + matrix->yy = FT_DivFix( matrix->yy, temp ); + offset->x = FT_DivFix( offset->x, temp ); + offset->y = FT_DivFix( offset->y, temp ); + } + + offset->x >>= 16; + offset->y >>= 16; + } + + for ( i = cff->num_subfonts; i > 0; i-- ) + { + CFF_FontRecDict sub = &cff->subfonts[i - 1]->font_dict; + CFF_FontRecDict top = &cff->top_font.font_dict; + + FT_Matrix* matrix; + FT_Vector* offset; + FT_ULong* upm; + FT_Fixed temp; + + + if ( sub->units_per_em ) + { + FT_Long scaling; + + + if ( top->units_per_em > 1 && sub->units_per_em > 1 ) + scaling = FT_MIN( top->units_per_em, sub->units_per_em ); + else + scaling = 1; + + FT_Matrix_Multiply_Scaled( &top->font_matrix, + &sub->font_matrix, + scaling ); + FT_Vector_Transform_Scaled( &sub->font_offset, + &top->font_matrix, + scaling ); + + sub->units_per_em = FT_MulDiv( sub->units_per_em, + top->units_per_em, + scaling ); + } + else + { + sub->font_matrix = top->font_matrix; + sub->font_offset = top->font_offset; + + sub->units_per_em = top->units_per_em; + } + + matrix = &sub->font_matrix; + offset = &sub->font_offset; + upm = &sub->units_per_em; + temp = FT_ABS( matrix->yy ); + + if ( temp != 0x10000L ) + { + *upm = FT_DivFix( *upm, temp ); + + /* if *upm is larger than 100*1000 we divide by 1000 -- */ + /* this can happen if e.g. there is no top-font FontMatrix */ + /* and the subfont FontMatrix already contains the complete */ + /* scaling for the subfont (see section 5.11 of the PLRM) */ + + /* 100 is a heuristic value */ + + if ( *upm > 100L * 1000L ) + *upm = ( *upm + 500 ) / 1000; + + matrix->xx = FT_DivFix( matrix->xx, temp ); + matrix->yx = FT_DivFix( matrix->yx, temp ); + matrix->xy = FT_DivFix( matrix->xy, temp ); + matrix->yy = FT_DivFix( matrix->yy, temp ); + offset->x = FT_DivFix( offset->x, temp ); + offset->y = FT_DivFix( offset->y, temp ); + } + + offset->x >>= 16; + offset->y >>= 16; + } + + if ( pure_cff ) + { + char* style_name = NULL; + + + /* set up num_faces */ + cffface->num_faces = cff->num_faces; + + /* compute number of glyphs */ + if ( dict->cid_registry != 0xFFFFU ) + cffface->num_glyphs = cff->charset.max_cid; + else + cffface->num_glyphs = cff->charstrings_index.count; + + /* set global bbox, as well as EM size */ + cffface->bbox.xMin = dict->font_bbox.xMin >> 16; + cffface->bbox.yMin = dict->font_bbox.yMin >> 16; + cffface->bbox.xMax = ( dict->font_bbox.xMax + 0xFFFFU ) >> 16; + cffface->bbox.yMax = ( dict->font_bbox.yMax + 0xFFFFU ) >> 16; + + cffface->units_per_EM = (FT_UShort)( dict->units_per_em ); + + cffface->ascender = (FT_Short)( cffface->bbox.yMax ); + cffface->descender = (FT_Short)( cffface->bbox.yMin ); + + cffface->height = (FT_Short)( ( cffface->units_per_EM * 12 ) / 10 ); + if ( cffface->height < cffface->ascender - cffface->descender ) + cffface->height = (FT_Short)( cffface->ascender - cffface->descender ); + + cffface->underline_position = + (FT_Short)( dict->underline_position >> 16 ); + cffface->underline_thickness = + (FT_Short)( dict->underline_thickness >> 16 ); + + /* retrieve font family & style name */ + cffface->family_name = cff_index_get_name( &cff->name_index, + face_index ); + + if ( cffface->family_name ) + { + char* full = cff_index_get_sid_string( &cff->string_index, + dict->full_name, + psnames ); + char* fullp = full; + char* family = cffface->family_name; + char* family_name = 0; + + + if ( dict->family_name ) + { + family_name = cff_index_get_sid_string( &cff->string_index, + dict->family_name, + psnames); + if ( family_name ) + family = family_name; + } + + /* We try to extract the style name from the full name. */ + /* We need to ignore spaces and dashes during the search. */ + if ( full && family ) + { + while ( *fullp ) + { + /* skip common characters at the start of both strings */ + if ( *fullp == *family ) + { + family++; + fullp++; + continue; + } + + /* ignore spaces and dashes in full name during comparison */ + if ( *fullp == ' ' || *fullp == '-' ) + { + fullp++; + continue; + } + + /* ignore spaces and dashes in family name during comparison */ + if ( *family == ' ' || *family == '-' ) + { + family++; + continue; + } + + if ( !*family && *fullp ) + { + /* The full name begins with the same characters as the */ + /* family name, with spaces and dashes removed. In this */ + /* case, the remaining string in `fullp' will be used as */ + /* the style name. */ + style_name = cff_strcpy( memory, fullp ); + } + break; + } + + if ( family_name ) + FT_FREE( family_name ); + FT_FREE( full ); + } + } + else + { + char *cid_font_name = + cff_index_get_sid_string( &cff->string_index, + dict->cid_font_name, + psnames ); + + + /* do we have a `/FontName' for a CID-keyed font? */ + if ( cid_font_name ) + cffface->family_name = cid_font_name; + } + + if ( style_name ) + cffface->style_name = style_name; + else + /* assume "Regular" style if we don't know better */ + cffface->style_name = cff_strcpy( memory, (char *)"Regular" ); + + /*******************************************************************/ + /* */ + /* Compute face flags. */ + /* */ + flags = (FT_UInt32)( FT_FACE_FLAG_SCALABLE | /* scalable outlines */ + FT_FACE_FLAG_HORIZONTAL | /* horizontal data */ + FT_FACE_FLAG_HINTER ); /* has native hinter */ + + if ( sfnt_format ) + flags |= (FT_UInt32)FT_FACE_FLAG_SFNT; + + /* fixed width font? */ + if ( dict->is_fixed_pitch ) + flags |= (FT_UInt32)FT_FACE_FLAG_FIXED_WIDTH; + + /* XXX: WE DO NOT SUPPORT KERNING METRICS IN THE GPOS TABLE FOR NOW */ +#if 0 + /* kerning available? */ + if ( face->kern_pairs ) + flags |= (FT_UInt32)FT_FACE_FLAG_KERNING; +#endif + + cffface->face_flags = flags; + + /*******************************************************************/ + /* */ + /* Compute style flags. */ + /* */ + flags = 0; + + if ( dict->italic_angle ) + flags |= FT_STYLE_FLAG_ITALIC; + + { + char *weight = cff_index_get_sid_string( &cff->string_index, + dict->weight, + psnames ); + + + if ( weight ) + if ( !ft_strcmp( weight, "Bold" ) || + !ft_strcmp( weight, "Black" ) ) + flags |= FT_STYLE_FLAG_BOLD; + FT_FREE( weight ); + } + + /* double check */ + if ( !(flags & FT_STYLE_FLAG_BOLD) && cffface->style_name ) + if ( !ft_strncmp( cffface->style_name, "Bold", 4 ) || + !ft_strncmp( cffface->style_name, "Black", 5 ) ) + flags |= FT_STYLE_FLAG_BOLD; + + cffface->style_flags = flags; + } + + +#ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES + /* CID-keyed CFF fonts don't have glyph names -- the SFNT loader */ + /* has unset this flag because of the 3.0 `post' table. */ + if ( dict->cid_registry == 0xFFFFU ) + cffface->face_flags |= FT_FACE_FLAG_GLYPH_NAMES; +#endif + + if ( dict->cid_registry != 0xFFFFU && pure_cff ) + cffface->face_flags |= FT_FACE_FLAG_CID_KEYED; + + + /*******************************************************************/ + /* */ + /* Compute char maps. */ + /* */ + + /* Try to synthesize a Unicode charmap if there is none available */ + /* already. If an OpenType font contains a Unicode "cmap", we */ + /* will use it, whatever be in the CFF part of the file. */ + { + FT_CharMapRec cmaprec; + FT_CharMap cmap; + FT_UInt nn; + CFF_Encoding encoding = &cff->encoding; + + + for ( nn = 0; nn < (FT_UInt)cffface->num_charmaps; nn++ ) + { + cmap = cffface->charmaps[nn]; + + /* Windows Unicode (3,1)? */ + if ( cmap->platform_id == 3 && cmap->encoding_id == 1 ) + goto Skip_Unicode; + + /* Deprecated Unicode platform id? */ + if ( cmap->platform_id == 0 ) + goto Skip_Unicode; /* Standard Unicode (deprecated) */ + } + + /* since CID-keyed fonts don't contain glyph names, we can't */ + /* construct a cmap */ + if ( pure_cff && cff->top_font.font_dict.cid_registry != 0xFFFFU ) + goto Exit; + + /* we didn't find a Unicode charmap -- synthesize one */ + cmaprec.face = cffface; + cmaprec.platform_id = 3; + cmaprec.encoding_id = 1; + cmaprec.encoding = FT_ENCODING_UNICODE; + + nn = (FT_UInt)cffface->num_charmaps; + + FT_CMap_New( &FT_CFF_CMAP_UNICODE_CLASS_REC_GET, NULL, &cmaprec, NULL ); + + /* if no Unicode charmap was previously selected, select this one */ + if ( cffface->charmap == NULL && nn != (FT_UInt)cffface->num_charmaps ) + cffface->charmap = cffface->charmaps[nn]; + + Skip_Unicode: + if ( encoding->count > 0 ) + { + FT_CMap_Class clazz; + + + cmaprec.face = cffface; + cmaprec.platform_id = 7; /* Adobe platform id */ + + if ( encoding->offset == 0 ) + { + cmaprec.encoding_id = TT_ADOBE_ID_STANDARD; + cmaprec.encoding = FT_ENCODING_ADOBE_STANDARD; + clazz = &FT_CFF_CMAP_ENCODING_CLASS_REC_GET; + } + else if ( encoding->offset == 1 ) + { + cmaprec.encoding_id = TT_ADOBE_ID_EXPERT; + cmaprec.encoding = FT_ENCODING_ADOBE_EXPERT; + clazz = &FT_CFF_CMAP_ENCODING_CLASS_REC_GET; + } + else + { + cmaprec.encoding_id = TT_ADOBE_ID_CUSTOM; + cmaprec.encoding = FT_ENCODING_ADOBE_CUSTOM; + clazz = &FT_CFF_CMAP_ENCODING_CLASS_REC_GET; + } + + FT_CMap_New( clazz, NULL, &cmaprec, NULL ); + } + } + } + + Exit: + return error; + + Bad_Format: + error = CFF_Err_Unknown_File_Format; + goto Exit; + } + + + FT_LOCAL_DEF( void ) + cff_face_done( FT_Face cffface ) /* CFF_Face */ + { + CFF_Face face = (CFF_Face)cffface; + FT_Memory memory; + SFNT_Service sfnt; + + + if ( !face ) + return; + + memory = cffface->memory; + sfnt = (SFNT_Service)face->sfnt; + + if ( sfnt ) + sfnt->done_face( face ); + + { + CFF_Font cff = (CFF_Font)face->extra.data; + + + if ( cff ) + { + cff_font_done( cff ); + FT_FREE( face->extra.data ); + } + } + } + + + FT_LOCAL_DEF( FT_Error ) + cff_driver_init( FT_Module module ) + { + FT_UNUSED( module ); + + return CFF_Err_Ok; + } + + + FT_LOCAL_DEF( void ) + cff_driver_done( FT_Module module ) + { + FT_UNUSED( module ); + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/cff/cffobjs.h b/mod/pub.mod/freetype.mod/src/cff/cffobjs.h new file mode 100644 index 0000000..3c81cee --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/cff/cffobjs.h @@ -0,0 +1,181 @@ +/***************************************************************************/ +/* */ +/* cffobjs.h */ +/* */ +/* OpenType objects manager (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __CFFOBJS_H__ +#define __CFFOBJS_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H +#include "cfftypes.h" +#include FT_INTERNAL_TRUETYPE_TYPES_H +#include FT_SERVICE_POSTSCRIPT_CMAPS_H +#include FT_INTERNAL_POSTSCRIPT_HINTS_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* CFF_Driver */ + /* */ + /* <Description> */ + /* A handle to an OpenType driver object. */ + /* */ + typedef struct CFF_DriverRec_* CFF_Driver; + + typedef TT_Face CFF_Face; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* CFF_Size */ + /* */ + /* <Description> */ + /* A handle to an OpenType size object. */ + /* */ + typedef struct CFF_SizeRec_ + { + FT_SizeRec root; + FT_ULong strike_index; /* 0xFFFFFFFF to indicate invalid */ + + } CFF_SizeRec, *CFF_Size; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* CFF_GlyphSlot */ + /* */ + /* <Description> */ + /* A handle to an OpenType glyph slot object. */ + /* */ + typedef struct CFF_GlyphSlotRec_ + { + FT_GlyphSlotRec root; + + FT_Bool hint; + FT_Bool scaled; + + FT_Fixed x_scale; + FT_Fixed y_scale; + + } CFF_GlyphSlotRec, *CFF_GlyphSlot; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* CFF_Internal */ + /* */ + /* <Description> */ + /* The interface to the `internal' field of `FT_Size'. */ + /* */ + typedef struct CFF_InternalRec_ + { + PSH_Globals topfont; + PSH_Globals subfonts[CFF_MAX_CID_FONTS]; + + } CFF_InternalRec, *CFF_Internal; + + + /*************************************************************************/ + /* */ + /* Subglyph transformation record. */ + /* */ + typedef struct CFF_Transform_ + { + FT_Fixed xx, xy; /* transformation matrix coefficients */ + FT_Fixed yx, yy; + FT_F26Dot6 ox, oy; /* offsets */ + + } CFF_Transform; + + + /***********************************************************************/ + /* */ + /* TrueType driver class. */ + /* */ + typedef struct CFF_DriverRec_ + { + FT_DriverRec root; + void* extension_component; + + } CFF_DriverRec; + + + FT_LOCAL( FT_Error ) + cff_size_init( FT_Size size ); /* CFF_Size */ + + FT_LOCAL( void ) + cff_size_done( FT_Size size ); /* CFF_Size */ + + FT_LOCAL( FT_Error ) + cff_size_request( FT_Size size, + FT_Size_Request req ); + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + + FT_LOCAL( FT_Error ) + cff_size_select( FT_Size size, + FT_ULong strike_index ); + +#endif + + FT_LOCAL( void ) + cff_slot_done( FT_GlyphSlot slot ); + + FT_LOCAL( FT_Error ) + cff_slot_init( FT_GlyphSlot slot ); + + + /*************************************************************************/ + /* */ + /* Face functions */ + /* */ + FT_LOCAL( FT_Error ) + cff_face_init( FT_Stream stream, + FT_Face face, /* CFF_Face */ + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ); + + FT_LOCAL( void ) + cff_face_done( FT_Face face ); /* CFF_Face */ + + + /*************************************************************************/ + /* */ + /* Driver functions */ + /* */ + FT_LOCAL( FT_Error ) + cff_driver_init( FT_Module module ); + + FT_LOCAL( void ) + cff_driver_done( FT_Module module ); + + +FT_END_HEADER + +#endif /* __CFFOBJS_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/cff/cffparse.c b/mod/pub.mod/freetype.mod/src/cff/cffparse.c new file mode 100644 index 0000000..947ec9d --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/cff/cffparse.c @@ -0,0 +1,917 @@ +/***************************************************************************/ +/* */ +/* cffparse.c */ +/* */ +/* CFF token stream parser (body) */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2007, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include "cffparse.h" +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_DEBUG_H + +#include "cfferrs.h" +#include "cffpic.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_cffparse + + + + + FT_LOCAL_DEF( void ) + cff_parser_init( CFF_Parser parser, + FT_UInt code, + void* object, + FT_Library library) + { + FT_MEM_ZERO( parser, sizeof ( *parser ) ); + + parser->top = parser->stack; + parser->object_code = code; + parser->object = object; + parser->library = library; + } + + + /* read an integer */ + static FT_Long + cff_parse_integer( FT_Byte* start, + FT_Byte* limit ) + { + FT_Byte* p = start; + FT_Int v = *p++; + FT_Long val = 0; + + + if ( v == 28 ) + { + if ( p + 2 > limit ) + goto Bad; + + val = (FT_Short)( ( (FT_Int)p[0] << 8 ) | p[1] ); + p += 2; + } + else if ( v == 29 ) + { + if ( p + 4 > limit ) + goto Bad; + + val = ( (FT_Long)p[0] << 24 ) | + ( (FT_Long)p[1] << 16 ) | + ( (FT_Long)p[2] << 8 ) | + p[3]; + p += 4; + } + else if ( v < 247 ) + { + val = v - 139; + } + else if ( v < 251 ) + { + if ( p + 1 > limit ) + goto Bad; + + val = ( v - 247 ) * 256 + p[0] + 108; + p++; + } + else + { + if ( p + 1 > limit ) + goto Bad; + + val = -( v - 251 ) * 256 - p[0] - 108; + p++; + } + + Exit: + return val; + + Bad: + val = 0; + goto Exit; + } + + + static const FT_Long power_tens[] = + { + 1L, + 10L, + 100L, + 1000L, + 10000L, + 100000L, + 1000000L, + 10000000L, + 100000000L, + 1000000000L + }; + + + /* read a real */ + static FT_Fixed + cff_parse_real( FT_Byte* start, + FT_Byte* limit, + FT_Long power_ten, + FT_Long* scaling ) + { + FT_Byte* p = start; + FT_UInt nib; + FT_UInt phase; + + FT_Long result, number, rest, exponent; + FT_Int sign = 0, exponent_sign = 0; + FT_Long exponent_add, integer_length, fraction_length; + + + if ( scaling ) + *scaling = 0; + + result = 0; + + number = 0; + rest = 0; + exponent = 0; + + exponent_add = 0; + integer_length = 0; + fraction_length = 0; + + FT_UNUSED( rest ); + + /* First of all, read the integer part. */ + phase = 4; + + for (;;) + { + /* If we entered this iteration with phase == 4, we need to */ + /* read a new byte. This also skips past the initial 0x1E. */ + if ( phase ) + { + p++; + + /* Make sure we don't read past the end. */ + if ( p >= limit ) + goto Exit; + } + + /* Get the nibble. */ + nib = ( p[0] >> phase ) & 0xF; + phase = 4 - phase; + + if ( nib == 0xE ) + sign = 1; + else if ( nib > 9 ) + break; + else + { + /* Increase exponent if we can't add the digit. */ + if ( number >= 0xCCCCCCCL ) + exponent_add++; + /* Skip leading zeros. */ + else if ( nib || number ) + { + integer_length++; + number = number * 10 + nib; + } + } + } + + /* Read fraction part, if any. */ + if ( nib == 0xa ) + for (;;) + { + /* If we entered this iteration with phase == 4, we need */ + /* to read a new byte. */ + if ( phase ) + { + p++; + + /* Make sure we don't read past the end. */ + if ( p >= limit ) + goto Exit; + } + + /* Get the nibble. */ + nib = ( p[0] >> phase ) & 0xF; + phase = 4 - phase; + if ( nib >= 10 ) + break; + + /* Skip leading zeros if possible. */ + if ( !nib && !number ) + exponent_add--; + /* Only add digit if we don't overflow. */ + else if ( number < 0xCCCCCCCL && fraction_length < 9 ) + { + fraction_length++; + number = number * 10 + nib; + } + } + + /* Read exponent, if any. */ + if ( nib == 12 ) + { + exponent_sign = 1; + nib = 11; + } + + if ( nib == 11 ) + { + for (;;) + { + /* If we entered this iteration with phase == 4, */ + /* we need to read a new byte. */ + if ( phase ) + { + p++; + + /* Make sure we don't read past the end. */ + if ( p >= limit ) + goto Exit; + } + + /* Get the nibble. */ + nib = ( p[0] >> phase ) & 0xF; + phase = 4 - phase; + if ( nib >= 10 ) + break; + + exponent = exponent * 10 + nib; + + /* Arbitrarily limit exponent. */ + if ( exponent > 1000 ) + goto Exit; + } + + if ( exponent_sign ) + exponent = -exponent; + } + + /* We don't check `power_ten' and `exponent_add'. */ + exponent += power_ten + exponent_add; + + if ( scaling ) + { + /* Only use `fraction_length'. */ + fraction_length += integer_length; + exponent += integer_length; + + if ( fraction_length <= 5 ) + { + if ( number > 0x7FFFL ) + { + result = FT_DivFix( number, 10 ); + *scaling = exponent - fraction_length + 1; + } + else + { + if ( exponent > 0 ) + { + FT_Long new_fraction_length, shift; + + + /* Make `scaling' as small as possible. */ + new_fraction_length = FT_MIN( exponent, 5 ); + exponent -= new_fraction_length; + shift = new_fraction_length - fraction_length; + + number *= power_tens[shift]; + if ( number > 0x7FFFL ) + { + number /= 10; + exponent += 1; + } + } + else + exponent -= fraction_length; + + result = number << 16; + *scaling = exponent; + } + } + else + { + if ( ( number / power_tens[fraction_length - 5] ) > 0x7FFFL ) + { + result = FT_DivFix( number, power_tens[fraction_length - 4] ); + *scaling = exponent - 4; + } + else + { + result = FT_DivFix( number, power_tens[fraction_length - 5] ); + *scaling = exponent - 5; + } + } + } + else + { + integer_length += exponent; + fraction_length -= exponent; + + /* Check for overflow and underflow. */ + if ( FT_ABS( integer_length ) > 5 ) + goto Exit; + + /* Remove non-significant digits. */ + if ( integer_length < 0 ) { + number /= power_tens[-integer_length]; + fraction_length += integer_length; + } + + /* Convert into 16.16 format. */ + if ( fraction_length > 0 ) + { + if ( ( number / power_tens[fraction_length] ) > 0x7FFFL ) + goto Exit; + + result = FT_DivFix( number, power_tens[fraction_length] ); + } + else + { + number *= power_tens[-fraction_length]; + + if ( number > 0x7FFFL ) + goto Exit; + + result = number << 16; + } + } + + if ( sign ) + result = -result; + + Exit: + return result; + } + + + /* read a number, either integer or real */ + static FT_Long + cff_parse_num( FT_Byte** d ) + { + return **d == 30 ? ( cff_parse_real( d[0], d[1], 0, NULL ) >> 16 ) + : cff_parse_integer( d[0], d[1] ); + } + + + /* read a floating point number, either integer or real */ + static FT_Fixed + cff_parse_fixed( FT_Byte** d ) + { + return **d == 30 ? cff_parse_real( d[0], d[1], 0, NULL ) + : cff_parse_integer( d[0], d[1] ) << 16; + } + + + /* read a floating point number, either integer or real, */ + /* but return `10^scaling' times the number read in */ + static FT_Fixed + cff_parse_fixed_scaled( FT_Byte** d, + FT_Long scaling ) + { + return **d == 30 ? cff_parse_real( d[0], d[1], scaling, NULL ) + : ( cff_parse_integer( d[0], d[1] ) * + power_tens[scaling] ) << 16; + } + + + /* read a floating point number, either integer or real, */ + /* and return it as precise as possible -- `scaling' returns */ + /* the scaling factor (as a power of 10) */ + static FT_Fixed + cff_parse_fixed_dynamic( FT_Byte** d, + FT_Long* scaling ) + { + FT_ASSERT( scaling ); + + if ( **d == 30 ) + return cff_parse_real( d[0], d[1], 0, scaling ); + else + { + FT_Long number; + FT_Int integer_length; + + + number = cff_parse_integer( d[0], d[1] ); + + if ( number > 0x7FFFL ) + { + for ( integer_length = 5; integer_length < 10; integer_length++ ) + if ( number < power_tens[integer_length] ) + break; + + if ( ( number / power_tens[integer_length - 5] ) > 0x7FFFL ) + { + *scaling = integer_length - 4; + return FT_DivFix( number, power_tens[integer_length - 4] ); + } + else + { + *scaling = integer_length - 5; + return FT_DivFix( number, power_tens[integer_length - 5] ); + } + } + else + { + *scaling = 0; + return number << 16; + } + } + } + + + static FT_Error + cff_parse_font_matrix( CFF_Parser parser ) + { + CFF_FontRecDict dict = (CFF_FontRecDict)parser->object; + FT_Matrix* matrix = &dict->font_matrix; + FT_Vector* offset = &dict->font_offset; + FT_ULong* upm = &dict->units_per_em; + FT_Byte** data = parser->stack; + FT_Error error = CFF_Err_Stack_Underflow; + + + if ( parser->top >= parser->stack + 6 ) + { + FT_Long scaling; + + + error = CFF_Err_Ok; + + /* We expect a well-formed font matrix, this is, the matrix elements */ + /* `xx' and `yy' are of approximately the same magnitude. To avoid */ + /* loss of precision, we use the magnitude of element `xx' to scale */ + /* all other elements. The scaling factor is then contained in the */ + /* `units_per_em' value. */ + + matrix->xx = cff_parse_fixed_dynamic( data++, &scaling ); + + scaling = -scaling; + + if ( scaling < 0 || scaling > 9 ) + { + /* Return default matrix in case of unlikely values. */ + matrix->xx = 0x10000L; + matrix->yx = 0; + matrix->yx = 0; + matrix->yy = 0x10000L; + offset->x = 0; + offset->y = 0; + *upm = 1; + + goto Exit; + } + + matrix->yx = cff_parse_fixed_scaled( data++, scaling ); + matrix->xy = cff_parse_fixed_scaled( data++, scaling ); + matrix->yy = cff_parse_fixed_scaled( data++, scaling ); + offset->x = cff_parse_fixed_scaled( data++, scaling ); + offset->y = cff_parse_fixed_scaled( data, scaling ); + + *upm = power_tens[scaling]; + } + + Exit: + return error; + } + + + static FT_Error + cff_parse_font_bbox( CFF_Parser parser ) + { + CFF_FontRecDict dict = (CFF_FontRecDict)parser->object; + FT_BBox* bbox = &dict->font_bbox; + FT_Byte** data = parser->stack; + FT_Error error; + + + error = CFF_Err_Stack_Underflow; + + if ( parser->top >= parser->stack + 4 ) + { + bbox->xMin = FT_RoundFix( cff_parse_fixed( data++ ) ); + bbox->yMin = FT_RoundFix( cff_parse_fixed( data++ ) ); + bbox->xMax = FT_RoundFix( cff_parse_fixed( data++ ) ); + bbox->yMax = FT_RoundFix( cff_parse_fixed( data ) ); + error = CFF_Err_Ok; + } + + return error; + } + + + static FT_Error + cff_parse_private_dict( CFF_Parser parser ) + { + CFF_FontRecDict dict = (CFF_FontRecDict)parser->object; + FT_Byte** data = parser->stack; + FT_Error error; + + + error = CFF_Err_Stack_Underflow; + + if ( parser->top >= parser->stack + 2 ) + { + dict->private_size = cff_parse_num( data++ ); + dict->private_offset = cff_parse_num( data ); + error = CFF_Err_Ok; + } + + return error; + } + + + static FT_Error + cff_parse_cid_ros( CFF_Parser parser ) + { + CFF_FontRecDict dict = (CFF_FontRecDict)parser->object; + FT_Byte** data = parser->stack; + FT_Error error; + + + error = CFF_Err_Stack_Underflow; + + if ( parser->top >= parser->stack + 3 ) + { + dict->cid_registry = (FT_UInt)cff_parse_num ( data++ ); + dict->cid_ordering = (FT_UInt)cff_parse_num ( data++ ); + if ( **data == 30 ) + FT_TRACE1(( "cff_parse_cid_ros: real supplement is rounded\n" )); + dict->cid_supplement = cff_parse_num( data ); + if ( dict->cid_supplement < 0 ) + FT_TRACE1(( "cff_parse_cid_ros: negative supplement %d is found\n", + dict->cid_supplement )); + error = CFF_Err_Ok; + } + + return error; + } + + +#define CFF_FIELD_NUM( code, name ) \ + CFF_FIELD( code, name, cff_kind_num ) +#define CFF_FIELD_FIXED( code, name ) \ + CFF_FIELD( code, name, cff_kind_fixed ) +#define CFF_FIELD_FIXED_1000( code, name ) \ + CFF_FIELD( code, name, cff_kind_fixed_thousand ) +#define CFF_FIELD_STRING( code, name ) \ + CFF_FIELD( code, name, cff_kind_string ) +#define CFF_FIELD_BOOL( code, name ) \ + CFF_FIELD( code, name, cff_kind_bool ) +#define CFF_FIELD_DELTA( code, name, max ) \ + CFF_FIELD( code, name, cff_kind_delta ) + +#define CFFCODE_TOPDICT 0x1000 +#define CFFCODE_PRIVATE 0x2000 + +#ifndef FT_CONFIG_OPTION_PIC + +#define CFF_FIELD_CALLBACK( code, name ) \ + { \ + cff_kind_callback, \ + code | CFFCODE, \ + 0, 0, \ + cff_parse_ ## name, \ + 0, 0 \ + }, + +#undef CFF_FIELD +#define CFF_FIELD( code, name, kind ) \ + { \ + kind, \ + code | CFFCODE, \ + FT_FIELD_OFFSET( name ), \ + FT_FIELD_SIZE( name ), \ + 0, 0, 0 \ + }, + +#undef CFF_FIELD_DELTA +#define CFF_FIELD_DELTA( code, name, max ) \ + { \ + cff_kind_delta, \ + code | CFFCODE, \ + FT_FIELD_OFFSET( name ), \ + FT_FIELD_SIZE_DELTA( name ), \ + 0, \ + max, \ + FT_FIELD_OFFSET( num_ ## name ) \ + }, + + static const CFF_Field_Handler cff_field_handlers[] = + { + +#include "cfftoken.h" + + { 0, 0, 0, 0, 0, 0, 0 } + }; + + +#else /* FT_CONFIG_OPTION_PIC */ + + void FT_Destroy_Class_cff_field_handlers(FT_Library library, CFF_Field_Handler* clazz) + { + FT_Memory memory = library->memory; + if ( clazz ) + FT_FREE( clazz ); + } + + FT_Error FT_Create_Class_cff_field_handlers(FT_Library library, CFF_Field_Handler** output_class) + { + CFF_Field_Handler* clazz; + FT_Error error; + FT_Memory memory = library->memory; + int i=0; + +#undef CFF_FIELD +#undef CFF_FIELD_DELTA +#undef CFF_FIELD_CALLBACK +#define CFF_FIELD_CALLBACK( code, name ) i++; +#define CFF_FIELD( code, name, kind ) i++; +#define CFF_FIELD_DELTA( code, name, max ) i++; + +#include "cfftoken.h" + i++;/*{ 0, 0, 0, 0, 0, 0, 0 }*/ + + if ( FT_ALLOC( clazz, sizeof(CFF_Field_Handler)*i ) ) + return error; + + i=0; +#undef CFF_FIELD +#undef CFF_FIELD_DELTA +#undef CFF_FIELD_CALLBACK + +#define CFF_FIELD_CALLBACK( code_, name_ ) \ + clazz[i].kind = cff_kind_callback; \ + clazz[i].code = code_ | CFFCODE; \ + clazz[i].offset = 0; \ + clazz[i].size = 0; \ + clazz[i].reader = cff_parse_ ## name_; \ + clazz[i].array_max = 0; \ + clazz[i].count_offset = 0; \ + i++; + +#undef CFF_FIELD +#define CFF_FIELD( code_, name_, kind_ ) \ + clazz[i].kind = kind_; \ + clazz[i].code = code_ | CFFCODE; \ + clazz[i].offset = FT_FIELD_OFFSET( name_ ); \ + clazz[i].size = FT_FIELD_SIZE( name_ ); \ + clazz[i].reader = 0; \ + clazz[i].array_max = 0; \ + clazz[i].count_offset = 0; \ + i++; \ + +#undef CFF_FIELD_DELTA +#define CFF_FIELD_DELTA( code_, name_, max_ ) \ + clazz[i].kind = cff_kind_delta; \ + clazz[i].code = code_ | CFFCODE; \ + clazz[i].offset = FT_FIELD_OFFSET( name_ ); \ + clazz[i].size = FT_FIELD_SIZE_DELTA( name_ ); \ + clazz[i].reader = 0; \ + clazz[i].array_max = max_; \ + clazz[i].count_offset = FT_FIELD_OFFSET( num_ ## name_ ); \ + i++; + +#include "cfftoken.h" + + clazz[i].kind = 0; + clazz[i].code = 0; + clazz[i].offset = 0; + clazz[i].size = 0; + clazz[i].reader = 0; + clazz[i].array_max = 0; + clazz[i].count_offset = 0; + + *output_class = clazz; + return FT_Err_Ok; + } + + +#endif /* FT_CONFIG_OPTION_PIC */ + + + FT_LOCAL_DEF( FT_Error ) + cff_parser_run( CFF_Parser parser, + FT_Byte* start, + FT_Byte* limit ) + { + FT_Byte* p = start; + FT_Error error = CFF_Err_Ok; + FT_Library library = parser->library; + FT_UNUSED(library); + + + parser->top = parser->stack; + parser->start = start; + parser->limit = limit; + parser->cursor = start; + + while ( p < limit ) + { + FT_UInt v = *p; + + + if ( v >= 27 && v != 31 ) + { + /* it's a number; we will push its position on the stack */ + if ( parser->top - parser->stack >= CFF_MAX_STACK_DEPTH ) + goto Stack_Overflow; + + *parser->top ++ = p; + + /* now, skip it */ + if ( v == 30 ) + { + /* skip real number */ + p++; + for (;;) + { + if ( p >= limit ) + goto Syntax_Error; + v = p[0] >> 4; + if ( v == 15 ) + break; + v = p[0] & 0xF; + if ( v == 15 ) + break; + p++; + } + } + else if ( v == 28 ) + p += 2; + else if ( v == 29 ) + p += 4; + else if ( v > 246 ) + p += 1; + } + else + { + /* This is not a number, hence it's an operator. Compute its code */ + /* and look for it in our current list. */ + + FT_UInt code; + FT_UInt num_args = (FT_UInt) + ( parser->top - parser->stack ); + const CFF_Field_Handler* field; + + + *parser->top = p; + code = v; + if ( v == 12 ) + { + /* two byte operator */ + p++; + if ( p >= limit ) + goto Syntax_Error; + + code = 0x100 | p[0]; + } + code = code | parser->object_code; + + for ( field = FT_CFF_FIELD_HANDLERS_GET; field->kind; field++ ) + { + if ( field->code == (FT_Int)code ) + { + /* we found our field's handler; read it */ + FT_Long val; + FT_Byte* q = (FT_Byte*)parser->object + field->offset; + + + /* check that we have enough arguments -- except for */ + /* delta encoded arrays, which can be empty */ + if ( field->kind != cff_kind_delta && num_args < 1 ) + goto Stack_Underflow; + + switch ( field->kind ) + { + case cff_kind_bool: + case cff_kind_string: + case cff_kind_num: + val = cff_parse_num( parser->stack ); + goto Store_Number; + + case cff_kind_fixed: + val = cff_parse_fixed( parser->stack ); + goto Store_Number; + + case cff_kind_fixed_thousand: + val = cff_parse_fixed_scaled( parser->stack, 3 ); + + Store_Number: + switch ( field->size ) + { + case (8 / FT_CHAR_BIT): + *(FT_Byte*)q = (FT_Byte)val; + break; + + case (16 / FT_CHAR_BIT): + *(FT_Short*)q = (FT_Short)val; + break; + + case (32 / FT_CHAR_BIT): + *(FT_Int32*)q = (FT_Int)val; + break; + + default: /* for 64-bit systems */ + *(FT_Long*)q = val; + } + break; + + case cff_kind_delta: + { + FT_Byte* qcount = (FT_Byte*)parser->object + + field->count_offset; + + FT_Byte** data = parser->stack; + + + if ( num_args > field->array_max ) + num_args = field->array_max; + + /* store count */ + *qcount = (FT_Byte)num_args; + + val = 0; + while ( num_args > 0 ) + { + val += cff_parse_num( data++ ); + switch ( field->size ) + { + case (8 / FT_CHAR_BIT): + *(FT_Byte*)q = (FT_Byte)val; + break; + + case (16 / FT_CHAR_BIT): + *(FT_Short*)q = (FT_Short)val; + break; + + case (32 / FT_CHAR_BIT): + *(FT_Int32*)q = (FT_Int)val; + break; + + default: /* for 64-bit systems */ + *(FT_Long*)q = val; + } + + q += field->size; + num_args--; + } + } + break; + + default: /* callback */ + error = field->reader( parser ); + if ( error ) + goto Exit; + } + goto Found; + } + } + + /* this is an unknown operator, or it is unsupported; */ + /* we will ignore it for now. */ + + Found: + /* clear stack */ + parser->top = parser->stack; + } + p++; + } + + Exit: + return error; + + Stack_Overflow: + error = CFF_Err_Invalid_Argument; + goto Exit; + + Stack_Underflow: + error = CFF_Err_Invalid_Argument; + goto Exit; + + Syntax_Error: + error = CFF_Err_Invalid_Argument; + goto Exit; + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/cff/cffparse.h b/mod/pub.mod/freetype.mod/src/cff/cffparse.h new file mode 100644 index 0000000..7e2c00a --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/cff/cffparse.h @@ -0,0 +1,102 @@ +/***************************************************************************/ +/* */ +/* cffparse.h */ +/* */ +/* CFF token stream parser (specification) */ +/* */ +/* Copyright 1996-2001, 2002, 2003 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __CFF_PARSE_H__ +#define __CFF_PARSE_H__ + + +#include <ft2build.h> +#include "cfftypes.h" +#include FT_INTERNAL_OBJECTS_H + + +FT_BEGIN_HEADER + + +#define CFF_MAX_STACK_DEPTH 96 + +#define CFF_CODE_TOPDICT 0x1000 +#define CFF_CODE_PRIVATE 0x2000 + + + typedef struct CFF_ParserRec_ + { + FT_Library library; + FT_Byte* start; + FT_Byte* limit; + FT_Byte* cursor; + + FT_Byte* stack[CFF_MAX_STACK_DEPTH + 1]; + FT_Byte** top; + + FT_UInt object_code; + void* object; + + } CFF_ParserRec, *CFF_Parser; + + + FT_LOCAL( void ) + cff_parser_init( CFF_Parser parser, + FT_UInt code, + void* object, + FT_Library library); + + FT_LOCAL( FT_Error ) + cff_parser_run( CFF_Parser parser, + FT_Byte* start, + FT_Byte* limit ); + + + enum + { + cff_kind_none = 0, + cff_kind_num, + cff_kind_fixed, + cff_kind_fixed_thousand, + cff_kind_string, + cff_kind_bool, + cff_kind_delta, + cff_kind_callback, + + cff_kind_max /* do not remove */ + }; + + + /* now generate handlers for the most simple fields */ + typedef FT_Error (*CFF_Field_Reader)( CFF_Parser parser ); + + typedef struct CFF_Field_Handler_ + { + int kind; + int code; + FT_UInt offset; + FT_Byte size; + CFF_Field_Reader reader; + FT_UInt array_max; + FT_UInt count_offset; + + } CFF_Field_Handler; + + +FT_END_HEADER + + +#endif /* __CFF_PARSE_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/cff/cffpic.c b/mod/pub.mod/freetype.mod/src/cff/cffpic.c new file mode 100644 index 0000000..568956d --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/cff/cffpic.c @@ -0,0 +1,99 @@ +/***************************************************************************/ +/* */ +/* cffpic.c */ +/* */ +/* The FreeType position independent code services for cff module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include "cffpic.h" + +#ifdef FT_CONFIG_OPTION_PIC + + /* forward declaration of PIC init functions from cffdrivr.c */ + FT_Error FT_Create_Class_cff_services( FT_Library, FT_ServiceDescRec**); + void FT_Destroy_Class_cff_services( FT_Library, FT_ServiceDescRec*); + void FT_Init_Class_cff_service_ps_info( FT_Library, FT_Service_PsInfoRec*); + void FT_Init_Class_cff_service_glyph_dict( FT_Library, FT_Service_GlyphDictRec*); + void FT_Init_Class_cff_service_ps_name( FT_Library, FT_Service_PsFontNameRec*); + void FT_Init_Class_cff_service_get_cmap_info( FT_Library, FT_Service_TTCMapsRec*); + void FT_Init_Class_cff_service_cid_info( FT_Library, FT_Service_CIDRec*); + + /* forward declaration of PIC init functions from cffparse.c */ + FT_Error FT_Create_Class_cff_field_handlers( FT_Library, CFF_Field_Handler**); + void FT_Destroy_Class_cff_field_handlers( FT_Library, CFF_Field_Handler*); + + /* forward declaration of PIC init functions from cffcmap.c */ + void FT_Init_Class_cff_cmap_encoding_class_rec( FT_Library, FT_CMap_ClassRec*); + void FT_Init_Class_cff_cmap_unicode_class_rec( FT_Library, FT_CMap_ClassRec*); + + void + cff_driver_class_pic_free( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Memory memory = library->memory; + if ( pic_container->cff ) + { + CffModulePIC* container = (CffModulePIC*)pic_container->cff; + if(container->cff_services) + FT_Destroy_Class_cff_services(library, container->cff_services); + container->cff_services = NULL; + if(container->cff_field_handlers) + FT_Destroy_Class_cff_field_handlers(library, container->cff_field_handlers); + container->cff_field_handlers = NULL; + FT_FREE( container ); + pic_container->cff = NULL; + } + } + + FT_Error + cff_driver_class_pic_init( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Error error = FT_Err_Ok; + CffModulePIC* container; + FT_Memory memory = library->memory; + + /* allocate pointer, clear and set global container pointer */ + if ( FT_ALLOC ( container, sizeof ( *container ) ) ) + return error; + FT_MEM_SET( container, 0, sizeof(*container) ); + pic_container->cff = container; + + /* initialize pointer table - this is how the module usually expects this data */ + error = FT_Create_Class_cff_services(library, &container->cff_services); + if(error) + goto Exit; + error = FT_Create_Class_cff_field_handlers(library, &container->cff_field_handlers); + if(error) + goto Exit; + FT_Init_Class_cff_service_ps_info(library, &container->cff_service_ps_info); + FT_Init_Class_cff_service_glyph_dict(library, &container->cff_service_glyph_dict); + FT_Init_Class_cff_service_ps_name(library, &container->cff_service_ps_name); + FT_Init_Class_cff_service_get_cmap_info(library, &container->cff_service_get_cmap_info); + FT_Init_Class_cff_service_cid_info(library, &container->cff_service_cid_info); + FT_Init_Class_cff_cmap_encoding_class_rec(library, &container->cff_cmap_encoding_class_rec); + FT_Init_Class_cff_cmap_unicode_class_rec(library, &container->cff_cmap_unicode_class_rec); +Exit: + if(error) + cff_driver_class_pic_free(library); + return error; + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/cff/cffpic.h b/mod/pub.mod/freetype.mod/src/cff/cffpic.h new file mode 100644 index 0000000..e29d068 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/cff/cffpic.h @@ -0,0 +1,80 @@ +/***************************************************************************/ +/* */ +/* cffpic.h */ +/* */ +/* The FreeType position independent code services for cff module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __CFFPIC_H__ +#define __CFFPIC_H__ + + +FT_BEGIN_HEADER + +#include FT_INTERNAL_PIC_H + +#ifndef FT_CONFIG_OPTION_PIC +#define FT_CFF_SERVICE_PS_INFO_GET cff_service_ps_info +#define FT_CFF_SERVICE_GLYPH_DICT_GET cff_service_glyph_dict +#define FT_CFF_SERVICE_PS_NAME_GET cff_service_ps_name +#define FT_CFF_SERVICE_GET_CMAP_INFO_GET cff_service_get_cmap_info +#define FT_CFF_SERVICE_CID_INFO_GET cff_service_cid_info +#define FT_CFF_SERVICES_GET cff_services +#define FT_CFF_CMAP_ENCODING_CLASS_REC_GET cff_cmap_encoding_class_rec +#define FT_CFF_CMAP_UNICODE_CLASS_REC_GET cff_cmap_unicode_class_rec +#define FT_CFF_FIELD_HANDLERS_GET cff_field_handlers + +#else /* FT_CONFIG_OPTION_PIC */ + +#include FT_SERVICE_GLYPH_DICT_H +#include "cffparse.h" +#include FT_SERVICE_POSTSCRIPT_INFO_H +#include FT_SERVICE_POSTSCRIPT_NAME_H +#include FT_SERVICE_TT_CMAP_H +#include FT_SERVICE_CID_H + + typedef struct CffModulePIC_ + { + FT_ServiceDescRec* cff_services; + CFF_Field_Handler* cff_field_handlers; + FT_Service_PsInfoRec cff_service_ps_info; + FT_Service_GlyphDictRec cff_service_glyph_dict; + FT_Service_PsFontNameRec cff_service_ps_name; + FT_Service_TTCMapsRec cff_service_get_cmap_info; + FT_Service_CIDRec cff_service_cid_info; + FT_CMap_ClassRec cff_cmap_encoding_class_rec; + FT_CMap_ClassRec cff_cmap_unicode_class_rec; + } CffModulePIC; + +#define GET_PIC(lib) ((CffModulePIC*)((lib)->pic_container.cff)) +#define FT_CFF_SERVICE_PS_INFO_GET (GET_PIC(library)->cff_service_ps_info) +#define FT_CFF_SERVICE_GLYPH_DICT_GET (GET_PIC(library)->cff_service_glyph_dict) +#define FT_CFF_SERVICE_PS_NAME_GET (GET_PIC(library)->cff_service_ps_name) +#define FT_CFF_SERVICE_GET_CMAP_INFO_GET (GET_PIC(library)->cff_service_get_cmap_info) +#define FT_CFF_SERVICE_CID_INFO_GET (GET_PIC(library)->cff_service_cid_info) +#define FT_CFF_SERVICES_GET (GET_PIC(library)->cff_services) +#define FT_CFF_CMAP_ENCODING_CLASS_REC_GET (GET_PIC(library)->cff_cmap_encoding_class_rec) +#define FT_CFF_CMAP_UNICODE_CLASS_REC_GET (GET_PIC(library)->cff_cmap_unicode_class_rec) +#define FT_CFF_FIELD_HANDLERS_GET (GET_PIC(library)->cff_field_handlers) + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + +FT_END_HEADER + +#endif /* __CFFPIC_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/cff/cfftoken.h b/mod/pub.mod/freetype.mod/src/cff/cfftoken.h new file mode 100644 index 0000000..6bb27d5 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/cff/cfftoken.h @@ -0,0 +1,97 @@ +/***************************************************************************/ +/* */ +/* cfftoken.h */ +/* */ +/* CFF token definitions (specification only). */ +/* */ +/* Copyright 1996-2001, 2002, 2003 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#undef FT_STRUCTURE +#define FT_STRUCTURE CFF_FontRecDictRec + +#undef CFFCODE +#define CFFCODE CFFCODE_TOPDICT + + CFF_FIELD_STRING ( 0, version ) + CFF_FIELD_STRING ( 1, notice ) + CFF_FIELD_STRING ( 0x100, copyright ) + CFF_FIELD_STRING ( 2, full_name ) + CFF_FIELD_STRING ( 3, family_name ) + CFF_FIELD_STRING ( 4, weight ) + CFF_FIELD_BOOL ( 0x101, is_fixed_pitch ) + CFF_FIELD_FIXED ( 0x102, italic_angle ) + CFF_FIELD_FIXED ( 0x103, underline_position ) + CFF_FIELD_FIXED ( 0x104, underline_thickness ) + CFF_FIELD_NUM ( 0x105, paint_type ) + CFF_FIELD_NUM ( 0x106, charstring_type ) + CFF_FIELD_CALLBACK( 0x107, font_matrix ) + CFF_FIELD_NUM ( 13, unique_id ) + CFF_FIELD_CALLBACK( 5, font_bbox ) + CFF_FIELD_NUM ( 0x108, stroke_width ) + CFF_FIELD_NUM ( 15, charset_offset ) + CFF_FIELD_NUM ( 16, encoding_offset ) + CFF_FIELD_NUM ( 17, charstrings_offset ) + CFF_FIELD_CALLBACK( 18, private_dict ) + CFF_FIELD_NUM ( 0x114, synthetic_base ) + CFF_FIELD_STRING ( 0x115, embedded_postscript ) + +#if 0 + CFF_FIELD_STRING ( 0x116, base_font_name ) + CFF_FIELD_DELTA ( 0x117, base_font_blend, 16 ) + CFF_FIELD_CALLBACK( 0x118, multiple_master ) + CFF_FIELD_CALLBACK( 0x119, blend_axis_types ) +#endif + + CFF_FIELD_CALLBACK( 0x11E, cid_ros ) + CFF_FIELD_NUM ( 0x11F, cid_font_version ) + CFF_FIELD_NUM ( 0x120, cid_font_revision ) + CFF_FIELD_NUM ( 0x121, cid_font_type ) + CFF_FIELD_NUM ( 0x122, cid_count ) + CFF_FIELD_NUM ( 0x123, cid_uid_base ) + CFF_FIELD_NUM ( 0x124, cid_fd_array_offset ) + CFF_FIELD_NUM ( 0x125, cid_fd_select_offset ) + CFF_FIELD_STRING ( 0x126, cid_font_name ) + +#if 0 + CFF_FIELD_NUM ( 0x127, chameleon ) +#endif + + +#undef FT_STRUCTURE +#define FT_STRUCTURE CFF_PrivateRec +#undef CFFCODE +#define CFFCODE CFFCODE_PRIVATE + + CFF_FIELD_DELTA ( 6, blue_values, 14 ) + CFF_FIELD_DELTA ( 7, other_blues, 10 ) + CFF_FIELD_DELTA ( 8, family_blues, 14 ) + CFF_FIELD_DELTA ( 9, family_other_blues, 10 ) + CFF_FIELD_FIXED_1000( 0x109, blue_scale ) + CFF_FIELD_NUM ( 0x10A, blue_shift ) + CFF_FIELD_NUM ( 0x10B, blue_fuzz ) + CFF_FIELD_NUM ( 10, standard_width ) + CFF_FIELD_NUM ( 11, standard_height ) + CFF_FIELD_DELTA ( 0x10C, snap_widths, 13 ) + CFF_FIELD_DELTA ( 0x10D, snap_heights, 13 ) + CFF_FIELD_BOOL ( 0x10E, force_bold ) + CFF_FIELD_FIXED ( 0x10F, force_bold_threshold ) + CFF_FIELD_NUM ( 0x110, lenIV ) + CFF_FIELD_NUM ( 0x111, language_group ) + CFF_FIELD_FIXED ( 0x112, expansion_factor ) + CFF_FIELD_NUM ( 0x113, initial_random_seed ) + CFF_FIELD_NUM ( 19, local_subrs_offset ) + CFF_FIELD_NUM ( 20, default_width ) + CFF_FIELD_NUM ( 21, nominal_width ) + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/cff/cfftypes.h b/mod/pub.mod/freetype.mod/src/cff/cfftypes.h new file mode 100644 index 0000000..df92e9a --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/cff/cfftypes.h @@ -0,0 +1,274 @@ +/***************************************************************************/ +/* */ +/* cfftypes.h */ +/* */ +/* Basic OpenType/CFF type definitions and interface (specification */ +/* only). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2006, 2007, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __CFFTYPES_H__ +#define __CFFTYPES_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_TYPE1_TABLES_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* CFF_IndexRec */ + /* */ + /* <Description> */ + /* A structure used to model a CFF Index table. */ + /* */ + /* <Fields> */ + /* stream :: The source input stream. */ + /* */ + /* start :: The position of the first index byte in the */ + /* input stream. */ + /* */ + /* count :: The number of elements in the index. */ + /* */ + /* off_size :: The size in bytes of object offsets in index. */ + /* */ + /* data_offset :: The position of first data byte in the index's */ + /* bytes. */ + /* */ + /* data_size :: The size of the data table in this index. */ + /* */ + /* offsets :: A table of element offsets in the index. Must be */ + /* loaded explicitly. */ + /* */ + /* bytes :: If the index is loaded in memory, its bytes. */ + /* */ + typedef struct CFF_IndexRec_ + { + FT_Stream stream; + FT_ULong start; + FT_UInt count; + FT_Byte off_size; + FT_ULong data_offset; + FT_ULong data_size; + + FT_ULong* offsets; + FT_Byte* bytes; + + } CFF_IndexRec, *CFF_Index; + + + typedef struct CFF_EncodingRec_ + { + FT_UInt format; + FT_ULong offset; + + FT_UInt count; + FT_UShort sids [256]; /* avoid dynamic allocations */ + FT_UShort codes[256]; + + } CFF_EncodingRec, *CFF_Encoding; + + + typedef struct CFF_CharsetRec_ + { + + FT_UInt format; + FT_ULong offset; + + FT_UShort* sids; + FT_UShort* cids; /* the inverse mapping of `sids'; only needed */ + /* for CID-keyed fonts */ + FT_UInt max_cid; + FT_UInt num_glyphs; + + } CFF_CharsetRec, *CFF_Charset; + + + typedef struct CFF_FontRecDictRec_ + { + FT_UInt version; + FT_UInt notice; + FT_UInt copyright; + FT_UInt full_name; + FT_UInt family_name; + FT_UInt weight; + FT_Bool is_fixed_pitch; + FT_Fixed italic_angle; + FT_Fixed underline_position; + FT_Fixed underline_thickness; + FT_Int paint_type; + FT_Int charstring_type; + FT_Matrix font_matrix; + FT_ULong units_per_em; /* temporarily used as scaling value also */ + FT_Vector font_offset; + FT_ULong unique_id; + FT_BBox font_bbox; + FT_Pos stroke_width; + FT_ULong charset_offset; + FT_ULong encoding_offset; + FT_ULong charstrings_offset; + FT_ULong private_offset; + FT_ULong private_size; + FT_Long synthetic_base; + FT_UInt embedded_postscript; + + /* these should only be used for the top-level font dictionary */ + FT_UInt cid_registry; + FT_UInt cid_ordering; + FT_Long cid_supplement; + + FT_Long cid_font_version; + FT_Long cid_font_revision; + FT_Long cid_font_type; + FT_ULong cid_count; + FT_ULong cid_uid_base; + FT_ULong cid_fd_array_offset; + FT_ULong cid_fd_select_offset; + FT_UInt cid_font_name; + + } CFF_FontRecDictRec, *CFF_FontRecDict; + + + typedef struct CFF_PrivateRec_ + { + FT_Byte num_blue_values; + FT_Byte num_other_blues; + FT_Byte num_family_blues; + FT_Byte num_family_other_blues; + + FT_Pos blue_values[14]; + FT_Pos other_blues[10]; + FT_Pos family_blues[14]; + FT_Pos family_other_blues[10]; + + FT_Fixed blue_scale; + FT_Pos blue_shift; + FT_Pos blue_fuzz; + FT_Pos standard_width; + FT_Pos standard_height; + + FT_Byte num_snap_widths; + FT_Byte num_snap_heights; + FT_Pos snap_widths[13]; + FT_Pos snap_heights[13]; + FT_Bool force_bold; + FT_Fixed force_bold_threshold; + FT_Int lenIV; + FT_Int language_group; + FT_Fixed expansion_factor; + FT_Long initial_random_seed; + FT_ULong local_subrs_offset; + FT_Pos default_width; + FT_Pos nominal_width; + + } CFF_PrivateRec, *CFF_Private; + + + typedef struct CFF_FDSelectRec_ + { + FT_Byte format; + FT_UInt range_count; + + /* that's the table, taken from the file `as is' */ + FT_Byte* data; + FT_UInt data_size; + + /* small cache for format 3 only */ + FT_UInt cache_first; + FT_UInt cache_count; + FT_Byte cache_fd; + + } CFF_FDSelectRec, *CFF_FDSelect; + + + /* A SubFont packs a font dict and a private dict together. They are */ + /* needed to support CID-keyed CFF fonts. */ + typedef struct CFF_SubFontRec_ + { + CFF_FontRecDictRec font_dict; + CFF_PrivateRec private_dict; + + CFF_IndexRec local_subrs_index; + FT_UInt num_local_subrs; + FT_Byte** local_subrs; + + } CFF_SubFontRec, *CFF_SubFont; + + + /* maximum number of sub-fonts in a CID-keyed file */ +#define CFF_MAX_CID_FONTS 32 + + + typedef struct CFF_FontRec_ + { + FT_Stream stream; + FT_Memory memory; + FT_UInt num_faces; + FT_UInt num_glyphs; + + FT_Byte version_major; + FT_Byte version_minor; + FT_Byte header_size; + FT_Byte absolute_offsize; + + + CFF_IndexRec name_index; + CFF_IndexRec top_dict_index; + CFF_IndexRec string_index; + CFF_IndexRec global_subrs_index; + + CFF_EncodingRec encoding; + CFF_CharsetRec charset; + + CFF_IndexRec charstrings_index; + CFF_IndexRec font_dict_index; + CFF_IndexRec private_index; + CFF_IndexRec local_subrs_index; + + FT_String* font_name; + FT_UInt num_global_subrs; + FT_Byte** global_subrs; + + CFF_SubFontRec top_font; + FT_UInt num_subfonts; + CFF_SubFont subfonts[CFF_MAX_CID_FONTS]; + + CFF_FDSelectRec fd_select; + + /* interface to PostScript hinter */ + void* pshinter; + + /* interface to Postscript Names service */ + void* psnames; + + /* since version 2.3.0 */ + PS_FontInfoRec* font_info; /* font info dictionary */ + + /* since version 2.3.6 */ + FT_String* registry; + FT_String* ordering; + + } CFF_FontRec, *CFF_Font; + + +FT_END_HEADER + +#endif /* __CFFTYPES_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/cid/ciderrs.h b/mod/pub.mod/freetype.mod/src/cid/ciderrs.h new file mode 100644 index 0000000..01813e1 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/cid/ciderrs.h @@ -0,0 +1,40 @@ +/***************************************************************************/ +/* */ +/* ciderrs.h */ +/* */ +/* CID error codes (specification only). */ +/* */ +/* Copyright 2001 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file is used to define the CID error enumeration constants. */ + /* */ + /*************************************************************************/ + +#ifndef __CIDERRS_H__ +#define __CIDERRS_H__ + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#define FT_ERR_PREFIX CID_Err_ +#define FT_ERR_BASE FT_Mod_Err_CID + +#include FT_ERRORS_H + +#endif /* __CIDERRS_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/cid/cidgload.c b/mod/pub.mod/freetype.mod/src/cid/cidgload.c new file mode 100644 index 0000000..f59035f --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/cid/cidgload.c @@ -0,0 +1,438 @@ +/***************************************************************************/ +/* */ +/* cidgload.c */ +/* */ +/* CID-keyed Type1 Glyph Loader (body). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include "cidload.h" +#include "cidgload.h" +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_OUTLINE_H +#include FT_INTERNAL_CALC_H + +#include "ciderrs.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_cidgload + + + FT_CALLBACK_DEF( FT_Error ) + cid_load_glyph( T1_Decoder decoder, + FT_UInt glyph_index ) + { + CID_Face face = (CID_Face)decoder->builder.face; + CID_FaceInfo cid = &face->cid; + FT_Byte* p; + FT_UInt fd_select; + FT_Stream stream = face->cid_stream; + FT_Error error = CID_Err_Ok; + FT_Byte* charstring = 0; + FT_Memory memory = face->root.memory; + FT_ULong glyph_length = 0; + PSAux_Service psaux = (PSAux_Service)face->psaux; + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + FT_Incremental_InterfaceRec *inc = + face->root.internal->incremental_interface; +#endif + + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + + /* For incremental fonts get the character data using */ + /* the callback function. */ + if ( inc ) + { + FT_Data glyph_data; + + + error = inc->funcs->get_glyph_data( inc->object, + glyph_index, &glyph_data ); + if ( error ) + goto Exit; + + p = (FT_Byte*)glyph_data.pointer; + fd_select = (FT_UInt)cid_get_offset( &p, (FT_Byte)cid->fd_bytes ); + + if ( glyph_data.length != 0 ) + { + glyph_length = glyph_data.length - cid->fd_bytes; + (void)FT_ALLOC( charstring, glyph_length ); + if ( !error ) + ft_memcpy( charstring, glyph_data.pointer + cid->fd_bytes, + glyph_length ); + } + + inc->funcs->free_glyph_data( inc->object, &glyph_data ); + + if ( error ) + goto Exit; + } + + else + +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ + + /* For ordinary fonts read the CID font dictionary index */ + /* and charstring offset from the CIDMap. */ + { + FT_UInt entry_len = cid->fd_bytes + cid->gd_bytes; + FT_ULong off1; + + + if ( FT_STREAM_SEEK( cid->data_offset + cid->cidmap_offset + + glyph_index * entry_len ) || + FT_FRAME_ENTER( 2 * entry_len ) ) + goto Exit; + + p = (FT_Byte*)stream->cursor; + fd_select = (FT_UInt) cid_get_offset( &p, (FT_Byte)cid->fd_bytes ); + off1 = (FT_ULong)cid_get_offset( &p, (FT_Byte)cid->gd_bytes ); + p += cid->fd_bytes; + glyph_length = cid_get_offset( &p, (FT_Byte)cid->gd_bytes ) - off1; + FT_FRAME_EXIT(); + + if ( fd_select >= (FT_UInt)cid->num_dicts ) + { + error = CID_Err_Invalid_Offset; + goto Exit; + } + if ( glyph_length == 0 ) + goto Exit; + if ( FT_ALLOC( charstring, glyph_length ) ) + goto Exit; + if ( FT_STREAM_READ_AT( cid->data_offset + off1, + charstring, glyph_length ) ) + goto Exit; + } + + /* Now set up the subrs array and parse the charstrings. */ + { + CID_FaceDict dict; + CID_Subrs cid_subrs = face->subrs + fd_select; + FT_Int cs_offset; + + + /* Set up subrs */ + decoder->num_subrs = cid_subrs->num_subrs; + decoder->subrs = cid_subrs->code; + decoder->subrs_len = 0; + + /* Set up font matrix */ + dict = cid->font_dicts + fd_select; + + decoder->font_matrix = dict->font_matrix; + decoder->font_offset = dict->font_offset; + decoder->lenIV = dict->private_dict.lenIV; + + /* Decode the charstring. */ + + /* Adjustment for seed bytes. */ + cs_offset = ( decoder->lenIV >= 0 ? decoder->lenIV : 0 ); + + /* Decrypt only if lenIV >= 0. */ + if ( decoder->lenIV >= 0 ) + psaux->t1_decrypt( charstring, glyph_length, 4330 ); + + error = decoder->funcs.parse_charstrings( + decoder, charstring + cs_offset, + (FT_Int)glyph_length - cs_offset ); + } + + FT_FREE( charstring ); + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + + /* Incremental fonts can optionally override the metrics. */ + if ( !error && inc && inc->funcs->get_glyph_metrics ) + { + FT_Incremental_MetricsRec metrics; + + + metrics.bearing_x = FIXED_TO_INT( decoder->builder.left_bearing.x ); + metrics.bearing_y = FIXED_TO_INT( decoder->builder.left_bearing.y ); + metrics.advance = FIXED_TO_INT( decoder->builder.advance.x ); + + error = inc->funcs->get_glyph_metrics( inc->object, + glyph_index, FALSE, &metrics ); + + decoder->builder.left_bearing.x = INT_TO_FIXED( metrics.bearing_x ); + decoder->builder.left_bearing.y = INT_TO_FIXED( metrics.bearing_y ); + decoder->builder.advance.x = INT_TO_FIXED( metrics.advance ); + decoder->builder.advance.y = 0; + } + +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ + + Exit: + return error; + } + + +#if 0 + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /********** *********/ + /********** *********/ + /********** COMPUTE THE MAXIMUM ADVANCE WIDTH *********/ + /********** *********/ + /********** The following code is in charge of computing *********/ + /********** the maximum advance width of the font. It *********/ + /********** quickly processes each glyph charstring to *********/ + /********** extract the value from either a `sbw' or `seac' *********/ + /********** operator. *********/ + /********** *********/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + FT_LOCAL_DEF( FT_Error ) + cid_face_compute_max_advance( CID_Face face, + FT_Int* max_advance ) + { + FT_Error error; + T1_DecoderRec decoder; + FT_Int glyph_index; + + PSAux_Service psaux = (PSAux_Service)face->psaux; + + + *max_advance = 0; + + /* Initialize load decoder */ + error = psaux->t1_decoder_funcs->init( &decoder, + (FT_Face)face, + 0, /* size */ + 0, /* glyph slot */ + 0, /* glyph names! XXX */ + 0, /* blend == 0 */ + 0, /* hinting == 0 */ + cid_load_glyph ); + if ( error ) + return error; + + /* TODO: initialize decoder.len_buildchar and decoder.buildchar */ + /* if we ever support CID-keyed multiple master fonts */ + + decoder.builder.metrics_only = 1; + decoder.builder.load_points = 0; + + /* for each glyph, parse the glyph charstring and extract */ + /* the advance width */ + for ( glyph_index = 0; glyph_index < face->root.num_glyphs; + glyph_index++ ) + { + /* now get load the unscaled outline */ + error = cid_load_glyph( &decoder, glyph_index ); + /* ignore the error if one occurred - skip to next glyph */ + } + + *max_advance = FIXED_TO_INT( decoder.builder.advance.x ); + + psaux->t1_decoder_funcs->done( &decoder ); + + return CID_Err_Ok; + } + + +#endif /* 0 */ + + + FT_LOCAL_DEF( FT_Error ) + cid_slot_load_glyph( FT_GlyphSlot cidglyph, /* CID_GlyphSlot */ + FT_Size cidsize, /* CID_Size */ + FT_UInt glyph_index, + FT_Int32 load_flags ) + { + CID_GlyphSlot glyph = (CID_GlyphSlot)cidglyph; + CID_Size size = (CID_Size)cidsize; + FT_Error error; + T1_DecoderRec decoder; + CID_Face face = (CID_Face)cidglyph->face; + FT_Bool hinting; + + PSAux_Service psaux = (PSAux_Service)face->psaux; + FT_Matrix font_matrix; + FT_Vector font_offset; + + + if ( glyph_index >= (FT_UInt)face->root.num_glyphs ) + { + error = CID_Err_Invalid_Argument; + goto Exit; + } + + if ( load_flags & FT_LOAD_NO_RECURSE ) + load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; + + glyph->x_scale = cidsize->metrics.x_scale; + glyph->y_scale = cidsize->metrics.y_scale; + + cidglyph->outline.n_points = 0; + cidglyph->outline.n_contours = 0; + + hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 && + ( load_flags & FT_LOAD_NO_HINTING ) == 0 ); + + cidglyph->format = FT_GLYPH_FORMAT_OUTLINE; + + error = psaux->t1_decoder_funcs->init( &decoder, + cidglyph->face, + cidsize, + cidglyph, + 0, /* glyph names -- XXX */ + 0, /* blend == 0 */ + hinting, + FT_LOAD_TARGET_MODE( load_flags ), + cid_load_glyph ); + if ( error ) + goto Exit; + + /* TODO: initialize decoder.len_buildchar and decoder.buildchar */ + /* if we ever support CID-keyed multiple master fonts */ + + /* set up the decoder */ + decoder.builder.no_recurse = FT_BOOL( + ( ( load_flags & FT_LOAD_NO_RECURSE ) != 0 ) ); + + error = cid_load_glyph( &decoder, glyph_index ); + if ( error ) + goto Exit; + + font_matrix = decoder.font_matrix; + font_offset = decoder.font_offset; + + /* save new glyph tables */ + psaux->t1_decoder_funcs->done( &decoder ); + + /* now set the metrics -- this is rather simple, as */ + /* the left side bearing is the xMin, and the top side */ + /* bearing the yMax */ + cidglyph->outline.flags &= FT_OUTLINE_OWNER; + cidglyph->outline.flags |= FT_OUTLINE_REVERSE_FILL; + + /* for composite glyphs, return only left side bearing and */ + /* advance width */ + if ( load_flags & FT_LOAD_NO_RECURSE ) + { + FT_Slot_Internal internal = cidglyph->internal; + + + cidglyph->metrics.horiBearingX = + FIXED_TO_INT( decoder.builder.left_bearing.x ); + cidglyph->metrics.horiAdvance = + FIXED_TO_INT( decoder.builder.advance.x ); + + internal->glyph_matrix = font_matrix; + internal->glyph_delta = font_offset; + internal->glyph_transformed = 1; + } + else + { + FT_BBox cbox; + FT_Glyph_Metrics* metrics = &cidglyph->metrics; + FT_Vector advance; + + + /* copy the _unscaled_ advance width */ + metrics->horiAdvance = + FIXED_TO_INT( decoder.builder.advance.x ); + cidglyph->linearHoriAdvance = + FIXED_TO_INT( decoder.builder.advance.x ); + cidglyph->internal->glyph_transformed = 0; + + /* make up vertical ones */ + metrics->vertAdvance = ( face->cid.font_bbox.yMax - + face->cid.font_bbox.yMin ) >> 16; + cidglyph->linearVertAdvance = metrics->vertAdvance; + + cidglyph->format = FT_GLYPH_FORMAT_OUTLINE; + + if ( size && cidsize->metrics.y_ppem < 24 ) + cidglyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION; + + /* apply the font matrix */ + FT_Outline_Transform( &cidglyph->outline, &font_matrix ); + + FT_Outline_Translate( &cidglyph->outline, + font_offset.x, + font_offset.y ); + + advance.x = metrics->horiAdvance; + advance.y = 0; + FT_Vector_Transform( &advance, &font_matrix ); + metrics->horiAdvance = advance.x + font_offset.x; + + advance.x = 0; + advance.y = metrics->vertAdvance; + FT_Vector_Transform( &advance, &font_matrix ); + metrics->vertAdvance = advance.y + font_offset.y; + + if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 ) + { + /* scale the outline and the metrics */ + FT_Int n; + FT_Outline* cur = decoder.builder.base; + FT_Vector* vec = cur->points; + FT_Fixed x_scale = glyph->x_scale; + FT_Fixed y_scale = glyph->y_scale; + + + /* First of all, scale the points */ + if ( !hinting || !decoder.builder.hints_funcs ) + for ( n = cur->n_points; n > 0; n--, vec++ ) + { + vec->x = FT_MulFix( vec->x, x_scale ); + vec->y = FT_MulFix( vec->y, y_scale ); + } + + /* Then scale the metrics */ + metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale ); + metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale ); + } + + /* compute the other metrics */ + FT_Outline_Get_CBox( &cidglyph->outline, &cbox ); + + metrics->width = cbox.xMax - cbox.xMin; + metrics->height = cbox.yMax - cbox.yMin; + + metrics->horiBearingX = cbox.xMin; + metrics->horiBearingY = cbox.yMax; + + /* make up vertical ones */ + ft_synthesize_vertical_metrics( metrics, + metrics->vertAdvance ); + } + + Exit: + return error; + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/cid/cidgload.h b/mod/pub.mod/freetype.mod/src/cid/cidgload.h new file mode 100644 index 0000000..a0a91bf --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/cid/cidgload.h @@ -0,0 +1,51 @@ +/***************************************************************************/ +/* */ +/* cidgload.h */ +/* */ +/* OpenType Glyph Loader (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2004 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __CIDGLOAD_H__ +#define __CIDGLOAD_H__ + + +#include <ft2build.h> +#include "cidobjs.h" + + +FT_BEGIN_HEADER + + +#if 0 + + /* Compute the maximum advance width of a font through quick parsing */ + FT_LOCAL( FT_Error ) + cid_face_compute_max_advance( CID_Face face, + FT_Int* max_advance ); + +#endif /* 0 */ + + FT_LOCAL( FT_Error ) + cid_slot_load_glyph( FT_GlyphSlot glyph, /* CID_Glyph_Slot */ + FT_Size size, /* CID_Size */ + FT_UInt glyph_index, + FT_Int32 load_flags ); + + +FT_END_HEADER + +#endif /* __CIDGLOAD_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/cid/cidload.c b/mod/pub.mod/freetype.mod/src/cid/cidload.c new file mode 100644 index 0000000..3bb3594 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/cid/cidload.c @@ -0,0 +1,672 @@ +/***************************************************************************/ +/* */ +/* cidload.c */ +/* */ +/* CID-keyed Type1 font loader (body). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_CONFIG_CONFIG_H +#include FT_MULTIPLE_MASTERS_H +#include FT_INTERNAL_TYPE1_TYPES_H + +#include "cidload.h" + +#include "ciderrs.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_cidload + + + /* read a single offset */ + FT_LOCAL_DEF( FT_Long ) + cid_get_offset( FT_Byte* *start, + FT_Byte offsize ) + { + FT_Long result; + FT_Byte* p = *start; + + + for ( result = 0; offsize > 0; offsize-- ) + { + result <<= 8; + result |= *p++; + } + + *start = p; + return result; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** TYPE 1 SYMBOL PARSING *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + static FT_Error + cid_load_keyword( CID_Face face, + CID_Loader* loader, + const T1_Field keyword ) + { + FT_Error error; + CID_Parser* parser = &loader->parser; + FT_Byte* object; + void* dummy_object; + CID_FaceInfo cid = &face->cid; + + + /* if the keyword has a dedicated callback, call it */ + if ( keyword->type == T1_FIELD_TYPE_CALLBACK ) + { + keyword->reader( (FT_Face)face, parser ); + error = parser->root.error; + goto Exit; + } + + /* we must now compute the address of our target object */ + switch ( keyword->location ) + { + case T1_FIELD_LOCATION_CID_INFO: + object = (FT_Byte*)cid; + break; + + case T1_FIELD_LOCATION_FONT_INFO: + object = (FT_Byte*)&cid->font_info; + break; + + case T1_FIELD_LOCATION_FONT_EXTRA: + object = (FT_Byte*)&face->font_extra; + break; + + case T1_FIELD_LOCATION_BBOX: + object = (FT_Byte*)&cid->font_bbox; + break; + + default: + { + CID_FaceDict dict; + + + if ( parser->num_dict < 0 ) + { + FT_ERROR(( "cid_load_keyword: invalid use of `%s'\n", + keyword->ident )); + error = CID_Err_Syntax_Error; + goto Exit; + } + + dict = cid->font_dicts + parser->num_dict; + switch ( keyword->location ) + { + case T1_FIELD_LOCATION_PRIVATE: + object = (FT_Byte*)&dict->private_dict; + break; + + default: + object = (FT_Byte*)dict; + } + } + } + + dummy_object = object; + + /* now, load the keyword data in the object's field(s) */ + if ( keyword->type == T1_FIELD_TYPE_INTEGER_ARRAY || + keyword->type == T1_FIELD_TYPE_FIXED_ARRAY ) + error = cid_parser_load_field_table( &loader->parser, keyword, + &dummy_object ); + else + error = cid_parser_load_field( &loader->parser, + keyword, &dummy_object ); + Exit: + return error; + } + + + FT_CALLBACK_DEF( FT_Error ) + parse_font_matrix( CID_Face face, + CID_Parser* parser ) + { + FT_Matrix* matrix; + FT_Vector* offset; + CID_FaceDict dict; + FT_Face root = (FT_Face)&face->root; + FT_Fixed temp[6]; + FT_Fixed temp_scale; + + + if ( parser->num_dict >= 0 ) + { + dict = face->cid.font_dicts + parser->num_dict; + matrix = &dict->font_matrix; + offset = &dict->font_offset; + + (void)cid_parser_to_fixed_array( parser, 6, temp, 3 ); + + temp_scale = FT_ABS( temp[3] ); + + /* Set units per EM based on FontMatrix values. We set the value to */ + /* `1000/temp_scale', because temp_scale was already multiplied by */ + /* 1000 (in `t1_tofixed', from psobjs.c). */ + root->units_per_EM = (FT_UShort)( FT_DivFix( 0x10000L, + FT_DivFix( temp_scale, 1000 ) ) ); + + /* we need to scale the values by 1.0/temp[3] */ + if ( temp_scale != 0x10000L ) + { + temp[0] = FT_DivFix( temp[0], temp_scale ); + temp[1] = FT_DivFix( temp[1], temp_scale ); + temp[2] = FT_DivFix( temp[2], temp_scale ); + temp[4] = FT_DivFix( temp[4], temp_scale ); + temp[5] = FT_DivFix( temp[5], temp_scale ); + temp[3] = 0x10000L; + } + + matrix->xx = temp[0]; + matrix->yx = temp[1]; + matrix->xy = temp[2]; + matrix->yy = temp[3]; + + /* note that the font offsets are expressed in integer font units */ + offset->x = temp[4] >> 16; + offset->y = temp[5] >> 16; + } + + return CID_Err_Ok; /* this is a callback function; */ + /* we must return an error code */ + } + + + FT_CALLBACK_DEF( FT_Error ) + parse_fd_array( CID_Face face, + CID_Parser* parser ) + { + CID_FaceInfo cid = &face->cid; + FT_Memory memory = face->root.memory; + FT_Error error = CID_Err_Ok; + FT_Long num_dicts; + + + num_dicts = cid_parser_to_int( parser ); + + if ( !cid->font_dicts ) + { + FT_Int n; + + + if ( FT_NEW_ARRAY( cid->font_dicts, num_dicts ) ) + goto Exit; + + cid->num_dicts = (FT_UInt)num_dicts; + + /* don't forget to set a few defaults */ + for ( n = 0; n < cid->num_dicts; n++ ) + { + CID_FaceDict dict = cid->font_dicts + n; + + + /* default value for lenIV */ + dict->private_dict.lenIV = 4; + } + } + + Exit: + return error; + } + + + /* by mistake, `expansion_factor' appears both in PS_PrivateRec */ + /* and CID_FaceDictRec (both are public header files and can't */ + /* changed); we simply copy the value */ + + FT_CALLBACK_DEF( FT_Error ) + parse_expansion_factor( CID_Face face, + CID_Parser* parser ) + { + CID_FaceDict dict; + + + if ( parser->num_dict >= 0 ) + { + dict = face->cid.font_dicts + parser->num_dict; + + dict->expansion_factor = cid_parser_to_fixed( parser, 0 ); + dict->private_dict.expansion_factor = dict->expansion_factor; + } + + return CID_Err_Ok; + } + + + static + const T1_FieldRec cid_field_records[] = + { + +#include "cidtoken.h" + + T1_FIELD_CALLBACK( "FDArray", parse_fd_array, 0 ) + T1_FIELD_CALLBACK( "FontMatrix", parse_font_matrix, 0 ) + T1_FIELD_CALLBACK( "ExpansionFactor", parse_expansion_factor, 0 ) + + { 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_TYPE_NONE, 0, 0, 0, 0, 0, 0 } + }; + + + static FT_Error + cid_parse_dict( CID_Face face, + CID_Loader* loader, + FT_Byte* base, + FT_Long size ) + { + CID_Parser* parser = &loader->parser; + + + parser->root.cursor = base; + parser->root.limit = base + size; + parser->root.error = CID_Err_Ok; + + { + FT_Byte* cur = base; + FT_Byte* limit = cur + size; + + + for (;;) + { + FT_Byte* newlimit; + + + parser->root.cursor = cur; + cid_parser_skip_spaces( parser ); + + if ( parser->root.cursor >= limit ) + newlimit = limit - 1 - 17; + else + newlimit = parser->root.cursor - 17; + + /* look for `%ADOBeginFontDict' */ + for ( ; cur < newlimit; cur++ ) + { + if ( *cur == '%' && + ft_strncmp( (char*)cur, "%ADOBeginFontDict", 17 ) == 0 ) + { + /* if /FDArray was found, then cid->num_dicts is > 0, and */ + /* we can start increasing parser->num_dict */ + if ( face->cid.num_dicts > 0 ) + parser->num_dict++; + } + } + + cur = parser->root.cursor; + /* no error can occur in cid_parser_skip_spaces */ + if ( cur >= limit ) + break; + + cid_parser_skip_PS_token( parser ); + if ( parser->root.cursor >= limit || parser->root.error ) + break; + + /* look for immediates */ + if ( *cur == '/' && cur + 2 < limit ) + { + FT_PtrDist len; + + + cur++; + len = parser->root.cursor - cur; + + if ( len > 0 && len < 22 ) + { + /* now compare the immediate name to the keyword table */ + T1_Field keyword = (T1_Field)cid_field_records; + + + for (;;) + { + FT_Byte* name; + + + name = (FT_Byte*)keyword->ident; + if ( !name ) + break; + + if ( cur[0] == name[0] && + len == (FT_PtrDist)ft_strlen( (const char*)name ) ) + { + FT_PtrDist n; + + + for ( n = 1; n < len; n++ ) + if ( cur[n] != name[n] ) + break; + + if ( n >= len ) + { + /* we found it - run the parsing callback */ + parser->root.error = cid_load_keyword( face, + loader, + keyword ); + if ( parser->root.error ) + return parser->root.error; + break; + } + } + keyword++; + } + } + } + + cur = parser->root.cursor; + } + } + return parser->root.error; + } + + + /* read the subrmap and the subrs of each font dict */ + static FT_Error + cid_read_subrs( CID_Face face ) + { + CID_FaceInfo cid = &face->cid; + FT_Memory memory = face->root.memory; + FT_Stream stream = face->cid_stream; + FT_Error error; + FT_Int n; + CID_Subrs subr; + FT_UInt max_offsets = 0; + FT_ULong* offsets = 0; + PSAux_Service psaux = (PSAux_Service)face->psaux; + + + if ( FT_NEW_ARRAY( face->subrs, cid->num_dicts ) ) + goto Exit; + + subr = face->subrs; + for ( n = 0; n < cid->num_dicts; n++, subr++ ) + { + CID_FaceDict dict = cid->font_dicts + n; + FT_Int lenIV = dict->private_dict.lenIV; + FT_UInt count, num_subrs = dict->num_subrs; + FT_ULong data_len; + FT_Byte* p; + + + /* reallocate offsets array if needed */ + if ( num_subrs + 1 > max_offsets ) + { + FT_UInt new_max = FT_PAD_CEIL( num_subrs + 1, 4 ); + + + if ( FT_RENEW_ARRAY( offsets, max_offsets, new_max ) ) + goto Fail; + + max_offsets = new_max; + } + + /* read the subrmap's offsets */ + if ( FT_STREAM_SEEK( cid->data_offset + dict->subrmap_offset ) || + FT_FRAME_ENTER( ( num_subrs + 1 ) * dict->sd_bytes ) ) + goto Fail; + + p = (FT_Byte*)stream->cursor; + for ( count = 0; count <= num_subrs; count++ ) + offsets[count] = cid_get_offset( &p, (FT_Byte)dict->sd_bytes ); + + FT_FRAME_EXIT(); + + /* now, compute the size of subrs charstrings, */ + /* allocate, and read them */ + data_len = offsets[num_subrs] - offsets[0]; + + if ( FT_NEW_ARRAY( subr->code, num_subrs + 1 ) || + FT_ALLOC( subr->code[0], data_len ) ) + goto Fail; + + if ( FT_STREAM_SEEK( cid->data_offset + offsets[0] ) || + FT_STREAM_READ( subr->code[0], data_len ) ) + goto Fail; + + /* set up pointers */ + for ( count = 1; count <= num_subrs; count++ ) + { + FT_ULong len; + + + len = offsets[count] - offsets[count - 1]; + subr->code[count] = subr->code[count - 1] + len; + } + + /* decrypt subroutines, but only if lenIV >= 0 */ + if ( lenIV >= 0 ) + { + for ( count = 0; count < num_subrs; count++ ) + { + FT_ULong len; + + + len = offsets[count + 1] - offsets[count]; + psaux->t1_decrypt( subr->code[count], len, 4330 ); + } + } + + subr->num_subrs = num_subrs; + } + + Exit: + FT_FREE( offsets ); + return error; + + Fail: + if ( face->subrs ) + { + for ( n = 0; n < cid->num_dicts; n++ ) + { + if ( face->subrs[n].code ) + FT_FREE( face->subrs[n].code[0] ); + + FT_FREE( face->subrs[n].code ); + } + FT_FREE( face->subrs ); + } + goto Exit; + } + + + static void + t1_init_loader( CID_Loader* loader, + CID_Face face ) + { + FT_UNUSED( face ); + + FT_MEM_ZERO( loader, sizeof ( *loader ) ); + } + + + static void + t1_done_loader( CID_Loader* loader ) + { + CID_Parser* parser = &loader->parser; + + + /* finalize parser */ + cid_parser_done( parser ); + } + + + static FT_Error + cid_hex_to_binary( FT_Byte* data, + FT_Long data_len, + FT_ULong offset, + CID_Face face ) + { + FT_Stream stream = face->root.stream; + FT_Error error; + + FT_Byte buffer[256]; + FT_Byte *p, *plimit; + FT_Byte *d, *dlimit; + FT_Byte val; + + FT_Bool upper_nibble, done; + + + if ( FT_STREAM_SEEK( offset ) ) + goto Exit; + + d = data; + dlimit = d + data_len; + p = buffer; + plimit = p; + + upper_nibble = 1; + done = 0; + + while ( d < dlimit ) + { + if ( p >= plimit ) + { + FT_ULong oldpos = FT_STREAM_POS(); + FT_ULong size = stream->size - oldpos; + + + if ( size == 0 ) + { + error = CID_Err_Syntax_Error; + goto Exit; + } + + if ( FT_STREAM_READ( buffer, 256 > size ? size : 256 ) ) + goto Exit; + p = buffer; + plimit = p + FT_STREAM_POS() - oldpos; + } + + if ( ft_isdigit( *p ) ) + val = (FT_Byte)( *p - '0' ); + else if ( *p >= 'a' && *p <= 'f' ) + val = (FT_Byte)( *p - 'a' ); + else if ( *p >= 'A' && *p <= 'F' ) + val = (FT_Byte)( *p - 'A' + 10 ); + else if ( *p == ' ' || + *p == '\t' || + *p == '\r' || + *p == '\n' || + *p == '\f' || + *p == '\0' ) + { + p++; + continue; + } + else if ( *p == '>' ) + { + val = 0; + done = 1; + } + else + { + error = CID_Err_Syntax_Error; + goto Exit; + } + + if ( upper_nibble ) + *d = (FT_Byte)( val << 4 ); + else + { + *d = (FT_Byte)( *d + val ); + d++; + } + + upper_nibble = (FT_Byte)( 1 - upper_nibble ); + + if ( done ) + break; + + p++; + } + + error = CID_Err_Ok; + + Exit: + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + cid_face_open( CID_Face face, + FT_Int face_index ) + { + CID_Loader loader; + CID_Parser* parser; + FT_Memory memory = face->root.memory; + FT_Error error; + + + t1_init_loader( &loader, face ); + + parser = &loader.parser; + error = cid_parser_new( parser, face->root.stream, face->root.memory, + (PSAux_Service)face->psaux ); + if ( error ) + goto Exit; + + error = cid_parse_dict( face, &loader, + parser->postscript, + parser->postscript_len ); + if ( error ) + goto Exit; + + if ( face_index < 0 ) + goto Exit; + + if ( FT_NEW( face->cid_stream ) ) + goto Exit; + + if ( parser->binary_length ) + { + /* we must convert the data section from hexadecimal to binary */ + if ( FT_ALLOC( face->binary_data, parser->binary_length ) || + cid_hex_to_binary( face->binary_data, parser->binary_length, + parser->data_offset, face ) ) + goto Exit; + + FT_Stream_OpenMemory( face->cid_stream, + face->binary_data, parser->binary_length ); + face->cid.data_offset = 0; + } + else + { + *face->cid_stream = *face->root.stream; + face->cid.data_offset = loader.parser.data_offset; + } + + error = cid_read_subrs( face ); + + Exit: + t1_done_loader( &loader ); + return error; + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/cid/cidload.h b/mod/pub.mod/freetype.mod/src/cid/cidload.h new file mode 100644 index 0000000..8c172ff --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/cid/cidload.h @@ -0,0 +1,53 @@ +/***************************************************************************/ +/* */ +/* cidload.h */ +/* */ +/* CID-keyed Type1 font loader (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __CIDLOAD_H__ +#define __CIDLOAD_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_STREAM_H +#include "cidparse.h" + + +FT_BEGIN_HEADER + + + typedef struct CID_Loader_ + { + CID_Parser parser; /* parser used to read the stream */ + FT_Int num_chars; /* number of characters in encoding */ + + } CID_Loader; + + + FT_LOCAL( FT_Long ) + cid_get_offset( FT_Byte** start, + FT_Byte offsize ); + + FT_LOCAL( FT_Error ) + cid_face_open( CID_Face face, + FT_Int face_index ); + + +FT_END_HEADER + +#endif /* __CIDLOAD_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/cid/cidobjs.c b/mod/pub.mod/freetype.mod/src/cid/cidobjs.c new file mode 100644 index 0000000..9647d87 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/cid/cidobjs.c @@ -0,0 +1,481 @@ +/***************************************************************************/ +/* */ +/* cidobjs.c */ +/* */ +/* CID objects manager (body). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H + +#include "cidgload.h" +#include "cidload.h" + +#include FT_SERVICE_POSTSCRIPT_CMAPS_H +#include FT_INTERNAL_POSTSCRIPT_AUX_H +#include FT_INTERNAL_POSTSCRIPT_HINTS_H + +#include "ciderrs.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_cidobjs + + + /*************************************************************************/ + /* */ + /* SLOT FUNCTIONS */ + /* */ + /*************************************************************************/ + + FT_LOCAL_DEF( void ) + cid_slot_done( FT_GlyphSlot slot ) + { + slot->internal->glyph_hints = 0; + } + + + FT_LOCAL_DEF( FT_Error ) + cid_slot_init( FT_GlyphSlot slot ) + { + CID_Face face; + PSHinter_Service pshinter; + + + face = (CID_Face)slot->face; + pshinter = (PSHinter_Service)face->pshinter; + + if ( pshinter ) + { + FT_Module module; + + + module = FT_Get_Module( slot->face->driver->root.library, + "pshinter" ); + if ( module ) + { + T1_Hints_Funcs funcs; + + + funcs = pshinter->get_t1_funcs( module ); + slot->internal->glyph_hints = (void*)funcs; + } + } + + return 0; + } + + + /*************************************************************************/ + /* */ + /* SIZE FUNCTIONS */ + /* */ + /*************************************************************************/ + + + static PSH_Globals_Funcs + cid_size_get_globals_funcs( CID_Size size ) + { + CID_Face face = (CID_Face)size->root.face; + PSHinter_Service pshinter = (PSHinter_Service)face->pshinter; + FT_Module module; + + + module = FT_Get_Module( size->root.face->driver->root.library, + "pshinter" ); + return ( module && pshinter && pshinter->get_globals_funcs ) + ? pshinter->get_globals_funcs( module ) + : 0; + } + + + FT_LOCAL_DEF( void ) + cid_size_done( FT_Size cidsize ) /* CID_Size */ + { + CID_Size size = (CID_Size)cidsize; + + + if ( cidsize->internal ) + { + PSH_Globals_Funcs funcs; + + + funcs = cid_size_get_globals_funcs( size ); + if ( funcs ) + funcs->destroy( (PSH_Globals)cidsize->internal ); + + cidsize->internal = 0; + } + } + + + FT_LOCAL_DEF( FT_Error ) + cid_size_init( FT_Size cidsize ) /* CID_Size */ + { + CID_Size size = (CID_Size)cidsize; + FT_Error error = 0; + PSH_Globals_Funcs funcs = cid_size_get_globals_funcs( size ); + + + if ( funcs ) + { + PSH_Globals globals; + CID_Face face = (CID_Face)cidsize->face; + CID_FaceDict dict = face->cid.font_dicts + face->root.face_index; + PS_Private priv = &dict->private_dict; + + + error = funcs->create( cidsize->face->memory, priv, &globals ); + if ( !error ) + cidsize->internal = (FT_Size_Internal)(void*)globals; + } + + return error; + } + + + FT_LOCAL( FT_Error ) + cid_size_request( FT_Size size, + FT_Size_Request req ) + { + PSH_Globals_Funcs funcs; + + + FT_Request_Metrics( size->face, req ); + + funcs = cid_size_get_globals_funcs( (CID_Size)size ); + + if ( funcs ) + funcs->set_scale( (PSH_Globals)size->internal, + size->metrics.x_scale, + size->metrics.y_scale, + 0, 0 ); + + return CID_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* FACE FUNCTIONS */ + /* */ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* <Function> */ + /* cid_face_done */ + /* */ + /* <Description> */ + /* Finalizes a given face object. */ + /* */ + /* <Input> */ + /* face :: A pointer to the face object to destroy. */ + /* */ + FT_LOCAL_DEF( void ) + cid_face_done( FT_Face cidface ) /* CID_Face */ + { + CID_Face face = (CID_Face)cidface; + FT_Memory memory; + CID_FaceInfo cid; + PS_FontInfo info; + + + if ( !face ) + return; + + cid = &face->cid; + info = &cid->font_info; + memory = cidface->memory; + + /* release subrs */ + if ( face->subrs ) + { + FT_Int n; + + + for ( n = 0; n < cid->num_dicts; n++ ) + { + CID_Subrs subr = face->subrs + n; + + + if ( subr->code ) + { + FT_FREE( subr->code[0] ); + FT_FREE( subr->code ); + } + } + + FT_FREE( face->subrs ); + } + + /* release FontInfo strings */ + FT_FREE( info->version ); + FT_FREE( info->notice ); + FT_FREE( info->full_name ); + FT_FREE( info->family_name ); + FT_FREE( info->weight ); + + /* release font dictionaries */ + FT_FREE( cid->font_dicts ); + cid->num_dicts = 0; + + /* release other strings */ + FT_FREE( cid->cid_font_name ); + FT_FREE( cid->registry ); + FT_FREE( cid->ordering ); + + cidface->family_name = 0; + cidface->style_name = 0; + + FT_FREE( face->binary_data ); + FT_FREE( face->cid_stream ); + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* cid_face_init */ + /* */ + /* <Description> */ + /* Initializes a given CID face object. */ + /* */ + /* <Input> */ + /* stream :: The source font stream. */ + /* */ + /* face_index :: The index of the font face in the resource. */ + /* */ + /* num_params :: Number of additional generic parameters. Ignored. */ + /* */ + /* params :: Additional generic parameters. Ignored. */ + /* */ + /* <InOut> */ + /* face :: The newly built face object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + cid_face_init( FT_Stream stream, + FT_Face cidface, /* CID_Face */ + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ) + { + CID_Face face = (CID_Face)cidface; + FT_Error error; + PSAux_Service psaux; + PSHinter_Service pshinter; + + FT_UNUSED( num_params ); + FT_UNUSED( params ); + FT_UNUSED( stream ); + + + cidface->num_faces = 1; + + psaux = (PSAux_Service)face->psaux; + if ( !psaux ) + { + psaux = (PSAux_Service)FT_Get_Module_Interface( + FT_FACE_LIBRARY( face ), "psaux" ); + + face->psaux = psaux; + } + + pshinter = (PSHinter_Service)face->pshinter; + if ( !pshinter ) + { + pshinter = (PSHinter_Service)FT_Get_Module_Interface( + FT_FACE_LIBRARY( face ), "pshinter" ); + + face->pshinter = pshinter; + } + + /* open the tokenizer; this will also check the font format */ + if ( FT_STREAM_SEEK( 0 ) ) + goto Exit; + + error = cid_face_open( face, face_index ); + if ( error ) + goto Exit; + + /* if we just wanted to check the format, leave successfully now */ + if ( face_index < 0 ) + goto Exit; + + /* check the face index */ + /* XXX: handle CID fonts with more than a single face */ + if ( face_index != 0 ) + { + FT_ERROR(( "cid_face_init: invalid face index\n" )); + error = CID_Err_Invalid_Argument; + goto Exit; + } + + /* now load the font program into the face object */ + + /* initialize the face object fields */ + + /* set up root face fields */ + { + CID_FaceInfo cid = &face->cid; + PS_FontInfo info = &cid->font_info; + + + cidface->num_glyphs = cid->cid_count; + cidface->num_charmaps = 0; + + cidface->face_index = face_index; + cidface->face_flags = FT_FACE_FLAG_SCALABLE | /* scalable outlines */ + FT_FACE_FLAG_HORIZONTAL | /* horizontal data */ + FT_FACE_FLAG_HINTER; /* has native hinter */ + + if ( info->is_fixed_pitch ) + cidface->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; + + /* XXX: TODO: add kerning with .afm support */ + + /* get style name -- be careful, some broken fonts only */ + /* have a /FontName dictionary entry! */ + cidface->family_name = info->family_name; + /* assume "Regular" style if we don't know better */ + cidface->style_name = (char *)"Regular"; + if ( cidface->family_name ) + { + char* full = info->full_name; + char* family = cidface->family_name; + + + if ( full ) + { + while ( *full ) + { + if ( *full == *family ) + { + family++; + full++; + } + else + { + if ( *full == ' ' || *full == '-' ) + full++; + else if ( *family == ' ' || *family == '-' ) + family++; + else + { + if ( !*family ) + cidface->style_name = full; + break; + } + } + } + } + } + else + { + /* do we have a `/FontName'? */ + if ( cid->cid_font_name ) + cidface->family_name = cid->cid_font_name; + } + + /* compute style flags */ + cidface->style_flags = 0; + if ( info->italic_angle ) + cidface->style_flags |= FT_STYLE_FLAG_ITALIC; + if ( info->weight ) + { + if ( !ft_strcmp( info->weight, "Bold" ) || + !ft_strcmp( info->weight, "Black" ) ) + cidface->style_flags |= FT_STYLE_FLAG_BOLD; + } + + /* no embedded bitmap support */ + cidface->num_fixed_sizes = 0; + cidface->available_sizes = 0; + + cidface->bbox.xMin = cid->font_bbox.xMin >> 16; + cidface->bbox.yMin = cid->font_bbox.yMin >> 16; + cidface->bbox.xMax = ( cid->font_bbox.xMax + 0xFFFFU ) >> 16; + cidface->bbox.yMax = ( cid->font_bbox.yMax + 0xFFFFU ) >> 16; + + if ( !cidface->units_per_EM ) + cidface->units_per_EM = 1000; + + cidface->ascender = (FT_Short)( cidface->bbox.yMax ); + cidface->descender = (FT_Short)( cidface->bbox.yMin ); + + cidface->height = (FT_Short)( ( cidface->units_per_EM * 12 ) / 10 ); + if ( cidface->height < cidface->ascender - cidface->descender ) + cidface->height = (FT_Short)( cidface->ascender - cidface->descender ); + + cidface->underline_position = (FT_Short)info->underline_position; + cidface->underline_thickness = (FT_Short)info->underline_thickness; + } + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* cid_driver_init */ + /* */ + /* <Description> */ + /* Initializes a given CID driver object. */ + /* */ + /* <Input> */ + /* driver :: A handle to the target driver object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + cid_driver_init( FT_Module driver ) + { + FT_UNUSED( driver ); + + return CID_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* cid_driver_done */ + /* */ + /* <Description> */ + /* Finalizes a given CID driver. */ + /* */ + /* <Input> */ + /* driver :: A handle to the target CID driver. */ + /* */ + FT_LOCAL_DEF( void ) + cid_driver_done( FT_Module driver ) + { + FT_UNUSED( driver ); + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/cid/cidobjs.h b/mod/pub.mod/freetype.mod/src/cid/cidobjs.h new file mode 100644 index 0000000..aee346d --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/cid/cidobjs.h @@ -0,0 +1,154 @@ +/***************************************************************************/ +/* */ +/* cidobjs.h */ +/* */ +/* CID objects manager (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2004, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __CIDOBJS_H__ +#define __CIDOBJS_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H +#include FT_CONFIG_CONFIG_H +#include FT_INTERNAL_TYPE1_TYPES_H + + +FT_BEGIN_HEADER + + + /* The following structures must be defined by the hinter */ + typedef struct CID_Size_Hints_ CID_Size_Hints; + typedef struct CID_Glyph_Hints_ CID_Glyph_Hints; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* CID_Driver */ + /* */ + /* <Description> */ + /* A handle to a Type 1 driver object. */ + /* */ + typedef struct CID_DriverRec_* CID_Driver; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* CID_Size */ + /* */ + /* <Description> */ + /* A handle to a Type 1 size object. */ + /* */ + typedef struct CID_SizeRec_* CID_Size; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* CID_GlyphSlot */ + /* */ + /* <Description> */ + /* A handle to a Type 1 glyph slot object. */ + /* */ + typedef struct CID_GlyphSlotRec_* CID_GlyphSlot; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* CID_CharMap */ + /* */ + /* <Description> */ + /* A handle to a Type 1 character mapping object. */ + /* */ + /* <Note> */ + /* The Type 1 format doesn't use a charmap but an encoding table. */ + /* The driver is responsible for making up charmap objects */ + /* corresponding to these tables. */ + /* */ + typedef struct CID_CharMapRec_* CID_CharMap; + + + /*************************************************************************/ + /* */ + /* HERE BEGINS THE TYPE 1 SPECIFIC STUFF */ + /* */ + /*************************************************************************/ + + + typedef struct CID_SizeRec_ + { + FT_SizeRec root; + FT_Bool valid; + + } CID_SizeRec; + + + typedef struct CID_GlyphSlotRec_ + { + FT_GlyphSlotRec root; + + FT_Bool hint; + FT_Bool scaled; + + FT_Fixed x_scale; + FT_Fixed y_scale; + + } CID_GlyphSlotRec; + + + FT_LOCAL( void ) + cid_slot_done( FT_GlyphSlot slot ); + + FT_LOCAL( FT_Error ) + cid_slot_init( FT_GlyphSlot slot ); + + + FT_LOCAL( void ) + cid_size_done( FT_Size size ); /* CID_Size */ + + FT_LOCAL( FT_Error ) + cid_size_init( FT_Size size ); /* CID_Size */ + + FT_LOCAL( FT_Error ) + cid_size_request( FT_Size size, /* CID_Size */ + FT_Size_Request req ); + + FT_LOCAL( FT_Error ) + cid_face_init( FT_Stream stream, + FT_Face face, /* CID_Face */ + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ); + + FT_LOCAL( void ) + cid_face_done( FT_Face face ); /* CID_Face */ + + + FT_LOCAL( FT_Error ) + cid_driver_init( FT_Module driver ); + + FT_LOCAL( void ) + cid_driver_done( FT_Module driver ); + + +FT_END_HEADER + +#endif /* __CIDOBJS_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/cid/cidparse.c b/mod/pub.mod/freetype.mod/src/cid/cidparse.c new file mode 100644 index 0000000..efed618 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/cid/cidparse.c @@ -0,0 +1,225 @@ +/***************************************************************************/ +/* */ +/* cidparse.c */ +/* */ +/* CID-keyed Type1 parser (body). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_STREAM_H + +#include "cidparse.h" + +#include "ciderrs.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_cidparse + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** INPUT STREAM PARSER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + FT_LOCAL_DEF( FT_Error ) + cid_parser_new( CID_Parser* parser, + FT_Stream stream, + FT_Memory memory, + PSAux_Service psaux ) + { + FT_Error error; + FT_ULong base_offset, offset, ps_len; + FT_Byte *cur, *limit; + FT_Byte *arg1, *arg2; + + + FT_MEM_ZERO( parser, sizeof ( *parser ) ); + psaux->ps_parser_funcs->init( &parser->root, 0, 0, memory ); + + parser->stream = stream; + + base_offset = FT_STREAM_POS(); + + /* first of all, check the font format in the header */ + if ( FT_FRAME_ENTER( 31 ) ) + goto Exit; + + if ( ft_strncmp( (char *)stream->cursor, + "%!PS-Adobe-3.0 Resource-CIDFont", 31 ) ) + { + FT_TRACE2(( "[not a valid CID-keyed font]\n" )); + error = CID_Err_Unknown_File_Format; + } + + FT_FRAME_EXIT(); + if ( error ) + goto Exit; + + Again: + /* now, read the rest of the file until we find */ + /* `StartData' or `/sfnts' */ + { + FT_Byte buffer[256 + 10]; + FT_Long read_len = 256 + 10; /* same as signed FT_Stream->size */ + FT_Byte* p = buffer; + + + for ( offset = FT_STREAM_POS(); ; offset += 256 ) + { + FT_Long stream_len; /* same as signed FT_Stream->size */ + + + stream_len = stream->size - FT_STREAM_POS(); + if ( stream_len == 0 ) + { + FT_TRACE2(( "cid_parser_new: no `StartData' keyword found\n" )); + error = CID_Err_Unknown_File_Format; + goto Exit; + } + + read_len = FT_MIN( read_len, stream_len ); + if ( FT_STREAM_READ( p, read_len ) ) + goto Exit; + + if ( read_len < 256 ) + p[read_len] = '\0'; + + limit = p + read_len - 10; + + for ( p = buffer; p < limit; p++ ) + { + if ( p[0] == 'S' && ft_strncmp( (char*)p, "StartData", 9 ) == 0 ) + { + /* save offset of binary data after `StartData' */ + offset += p - buffer + 10; + goto Found; + } + else if ( p[1] == 's' && ft_strncmp( (char*)p, "/sfnts", 6 ) == 0 ) + { + offset += p - buffer + 7; + goto Found; + } + } + + FT_MEM_MOVE( buffer, p, 10 ); + read_len = 256; + p = buffer + 10; + } + } + + Found: + /* We have found the start of the binary data or the `/sfnts' token. */ + /* Now rewind and extract the frame corresponding to this PostScript */ + /* section. */ + + ps_len = offset - base_offset; + if ( FT_STREAM_SEEK( base_offset ) || + FT_FRAME_EXTRACT( ps_len, parser->postscript ) ) + goto Exit; + + parser->data_offset = offset; + parser->postscript_len = ps_len; + parser->root.base = parser->postscript; + parser->root.cursor = parser->postscript; + parser->root.limit = parser->root.cursor + ps_len; + parser->num_dict = -1; + + /* Finally, we check whether `StartData' or `/sfnts' was real -- */ + /* it could be in a comment or string. We also get the arguments */ + /* of `StartData' to find out whether the data is represented in */ + /* binary or hex format. */ + + arg1 = parser->root.cursor; + cid_parser_skip_PS_token( parser ); + cid_parser_skip_spaces ( parser ); + arg2 = parser->root.cursor; + cid_parser_skip_PS_token( parser ); + cid_parser_skip_spaces ( parser ); + + limit = parser->root.limit; + cur = parser->root.cursor; + + while ( cur < limit ) + { + if ( parser->root.error ) + { + error = parser->root.error; + goto Exit; + } + + if ( cur[0] == 'S' && ft_strncmp( (char*)cur, "StartData", 9 ) == 0 ) + { + if ( ft_strncmp( (char*)arg1, "(Hex)", 5 ) == 0 ) + parser->binary_length = ft_atol( (const char *)arg2 ); + + limit = parser->root.limit; + cur = parser->root.cursor; + goto Exit; + } + else if ( cur[1] == 's' && ft_strncmp( (char*)cur, "/sfnts", 6 ) == 0 ) + { + FT_TRACE2(( "cid_parser_new: cannot handle Type 11 fonts\n" )); + error = CID_Err_Unknown_File_Format; + goto Exit; + } + + cid_parser_skip_PS_token( parser ); + cid_parser_skip_spaces ( parser ); + arg1 = arg2; + arg2 = cur; + cur = parser->root.cursor; + } + + /* we haven't found the correct `StartData'; go back and continue */ + /* searching */ + FT_FRAME_RELEASE( parser->postscript ); + if ( !FT_STREAM_SEEK( offset ) ) + goto Again; + + Exit: + return error; + } + + + FT_LOCAL_DEF( void ) + cid_parser_done( CID_Parser* parser ) + { + /* always free the private dictionary */ + if ( parser->postscript ) + { + FT_Stream stream = parser->stream; + + + FT_FRAME_RELEASE( parser->postscript ); + } + parser->root.funcs.done( &parser->root ); + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/cid/cidparse.h b/mod/pub.mod/freetype.mod/src/cid/cidparse.h new file mode 100644 index 0000000..ca37dea --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/cid/cidparse.h @@ -0,0 +1,123 @@ +/***************************************************************************/ +/* */ +/* cidparse.h */ +/* */ +/* CID-keyed Type1 parser (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __CIDPARSE_H__ +#define __CIDPARSE_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_TYPE1_TYPES_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_POSTSCRIPT_AUX_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* CID_Parser */ + /* */ + /* <Description> */ + /* A CID_Parser is an object used to parse a Type 1 fonts very */ + /* quickly. */ + /* */ + /* <Fields> */ + /* root :: The root PS_ParserRec fields. */ + /* */ + /* stream :: The current input stream. */ + /* */ + /* postscript :: A pointer to the data to be parsed. */ + /* */ + /* postscript_len :: The length of the data to be parsed. */ + /* */ + /* data_offset :: The start position of the binary data (i.e., the */ + /* end of the data to be parsed. */ + /* */ + /* binary_length :: The length of the data after the `StartData' */ + /* command if the data format is hexadecimal. */ + /* */ + /* cid :: A structure which holds the information about */ + /* the current font. */ + /* */ + /* num_dict :: The number of font dictionaries. */ + /* */ + typedef struct CID_Parser_ + { + PS_ParserRec root; + FT_Stream stream; + + FT_Byte* postscript; + FT_Long postscript_len; + + FT_ULong data_offset; + + FT_Long binary_length; + + CID_FaceInfo cid; + FT_Int num_dict; + + } CID_Parser; + + + FT_LOCAL( FT_Error ) + cid_parser_new( CID_Parser* parser, + FT_Stream stream, + FT_Memory memory, + PSAux_Service psaux ); + + FT_LOCAL( void ) + cid_parser_done( CID_Parser* parser ); + + + /*************************************************************************/ + /* */ + /* PARSING ROUTINES */ + /* */ + /*************************************************************************/ + +#define cid_parser_skip_spaces( p ) \ + (p)->root.funcs.skip_spaces( &(p)->root ) +#define cid_parser_skip_PS_token( p ) \ + (p)->root.funcs.skip_PS_token( &(p)->root ) + +#define cid_parser_to_int( p ) (p)->root.funcs.to_int( &(p)->root ) +#define cid_parser_to_fixed( p, t ) (p)->root.funcs.to_fixed( &(p)->root, t ) + +#define cid_parser_to_coord_array( p, m, c ) \ + (p)->root.funcs.to_coord_array( &(p)->root, m, c ) +#define cid_parser_to_fixed_array( p, m, f, t ) \ + (p)->root.funcs.to_fixed_array( &(p)->root, m, f, t ) +#define cid_parser_to_token( p, t ) \ + (p)->root.funcs.to_token( &(p)->root, t ) +#define cid_parser_to_token_array( p, t, m, c ) \ + (p)->root.funcs.to_token_array( &(p)->root, t, m, c ) + +#define cid_parser_load_field( p, f, o ) \ + (p)->root.funcs.load_field( &(p)->root, f, o, 0, 0 ) +#define cid_parser_load_field_table( p, f, o ) \ + (p)->root.funcs.load_field_table( &(p)->root, f, o, 0, 0 ) + + +FT_END_HEADER + +#endif /* __CIDPARSE_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/cid/cidriver.c b/mod/pub.mod/freetype.mod/src/cid/cidriver.c new file mode 100644 index 0000000..3a2d225 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/cid/cidriver.c @@ -0,0 +1,240 @@ +/***************************************************************************/ +/* */ +/* cidriver.c */ +/* */ +/* CID driver interface (body). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include "cidriver.h" +#include "cidgload.h" +#include FT_INTERNAL_DEBUG_H + +#include "ciderrs.h" + +#include FT_SERVICE_POSTSCRIPT_NAME_H +#include FT_SERVICE_XFREE86_NAME_H +#include FT_SERVICE_POSTSCRIPT_INFO_H +#include FT_SERVICE_CID_H + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_ciddriver + + + /* + * POSTSCRIPT NAME SERVICE + * + */ + + static const char* + cid_get_postscript_name( CID_Face face ) + { + const char* result = face->cid.cid_font_name; + + + if ( result && result[0] == '/' ) + result++; + + return result; + } + + + static const FT_Service_PsFontNameRec cid_service_ps_name = + { + (FT_PsName_GetFunc) cid_get_postscript_name + }; + + + /* + * POSTSCRIPT INFO SERVICE + * + */ + + static FT_Error + cid_ps_get_font_info( FT_Face face, + PS_FontInfoRec* afont_info ) + { + *afont_info = ((CID_Face)face)->cid.font_info; + + return CID_Err_Ok; + } + + static FT_Error + cid_ps_get_font_extra( FT_Face face, + PS_FontExtraRec* afont_extra ) + { + *afont_extra = ((CID_Face)face)->font_extra; + + return CID_Err_Ok; + } + + static const FT_Service_PsInfoRec cid_service_ps_info = + { + (PS_GetFontInfoFunc) cid_ps_get_font_info, + (PS_GetFontExtraFunc) cid_ps_get_font_extra, + (PS_HasGlyphNamesFunc) NULL, /* unsupported with CID fonts */ + (PS_GetFontPrivateFunc)NULL /* unsupported */ + }; + + + /* + * CID INFO SERVICE + * + */ + static FT_Error + cid_get_ros( CID_Face face, + const char* *registry, + const char* *ordering, + FT_Int *supplement ) + { + CID_FaceInfo cid = &face->cid; + + + if ( registry ) + *registry = cid->registry; + + if ( ordering ) + *ordering = cid->ordering; + + if ( supplement ) + *supplement = cid->supplement; + + return CID_Err_Ok; + } + + + static FT_Error + cid_get_is_cid( CID_Face face, + FT_Bool *is_cid ) + { + FT_Error error = CID_Err_Ok; + FT_UNUSED( face ); + + + if ( is_cid ) + *is_cid = 1; /* cid driver is only used for CID keyed fonts */ + + return error; + } + + + static FT_Error + cid_get_cid_from_glyph_index( CID_Face face, + FT_UInt glyph_index, + FT_UInt *cid ) + { + FT_Error error = CID_Err_Ok; + FT_UNUSED( face ); + + + if ( cid ) + *cid = glyph_index; /* identity mapping */ + + return error; + } + + + static const FT_Service_CIDRec cid_service_cid_info = + { + (FT_CID_GetRegistryOrderingSupplementFunc)cid_get_ros, + (FT_CID_GetIsInternallyCIDKeyedFunc) cid_get_is_cid, + (FT_CID_GetCIDFromGlyphIndexFunc) cid_get_cid_from_glyph_index + }; + + + /* + * SERVICE LIST + * + */ + + static const FT_ServiceDescRec cid_services[] = + { + { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_CID }, + { FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &cid_service_ps_name }, + { FT_SERVICE_ID_POSTSCRIPT_INFO, &cid_service_ps_info }, + { FT_SERVICE_ID_CID, &cid_service_cid_info }, + { NULL, NULL } + }; + + + FT_CALLBACK_DEF( FT_Module_Interface ) + cid_get_interface( FT_Module module, + const char* cid_interface ) + { + FT_UNUSED( module ); + + return ft_service_list_lookup( cid_services, cid_interface ); + } + + + + FT_CALLBACK_TABLE_DEF + const FT_Driver_ClassRec t1cid_driver_class = + { + /* first of all, the FT_Module_Class fields */ + { + FT_MODULE_FONT_DRIVER | + FT_MODULE_DRIVER_SCALABLE | + FT_MODULE_DRIVER_HAS_HINTER, + + sizeof( FT_DriverRec ), + "t1cid", /* module name */ + 0x10000L, /* version 1.0 of driver */ + 0x20000L, /* requires FreeType 2.0 */ + + 0, + + cid_driver_init, + cid_driver_done, + cid_get_interface + }, + + /* then the other font drivers fields */ + sizeof( CID_FaceRec ), + sizeof( CID_SizeRec ), + sizeof( CID_GlyphSlotRec ), + + cid_face_init, + cid_face_done, + + cid_size_init, + cid_size_done, + cid_slot_init, + cid_slot_done, + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + ft_stub_set_char_sizes, + ft_stub_set_pixel_sizes, +#endif + + cid_slot_load_glyph, + + 0, /* FT_Face_GetKerningFunc */ + 0, /* FT_Face_AttachFunc */ + + 0, /* FT_Face_GetAdvancesFunc */ + + cid_size_request, + 0 /* FT_Size_SelectFunc */ + }; + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/cid/cidriver.h b/mod/pub.mod/freetype.mod/src/cid/cidriver.h new file mode 100644 index 0000000..c7f424b --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/cid/cidriver.h @@ -0,0 +1,43 @@ +/***************************************************************************/ +/* */ +/* cidriver.h */ +/* */ +/* High-level CID driver interface (specification). */ +/* */ +/* Copyright 1996-2001, 2002 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __CIDRIVER_H__ +#define __CIDRIVER_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_DRIVER_H + + +FT_BEGIN_HEADER + +#ifdef FT_CONFIG_OPTION_PIC +#error "this module does not support PIC yet" +#endif + + + FT_CALLBACK_TABLE + const FT_Driver_ClassRec t1cid_driver_class; + + +FT_END_HEADER + +#endif /* __CIDRIVER_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/cid/cidtoken.h b/mod/pub.mod/freetype.mod/src/cid/cidtoken.h new file mode 100644 index 0000000..94a3657 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/cid/cidtoken.h @@ -0,0 +1,112 @@ +/***************************************************************************/ +/* */ +/* cidtoken.h */ +/* */ +/* CID token definitions (specification only). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2006, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#undef FT_STRUCTURE +#define FT_STRUCTURE CID_FaceInfoRec +#undef T1CODE +#define T1CODE T1_FIELD_LOCATION_CID_INFO + + T1_FIELD_KEY ( "CIDFontName", cid_font_name, 0 ) + T1_FIELD_NUM ( "CIDFontVersion", cid_version, 0 ) + T1_FIELD_NUM ( "CIDFontType", cid_font_type, 0 ) + T1_FIELD_STRING( "Registry", registry, 0 ) + T1_FIELD_STRING( "Ordering", ordering, 0 ) + T1_FIELD_NUM ( "Supplement", supplement, 0 ) + T1_FIELD_NUM ( "UIDBase", uid_base, 0 ) + T1_FIELD_NUM ( "CIDMapOffset", cidmap_offset, 0 ) + T1_FIELD_NUM ( "FDBytes", fd_bytes, 0 ) + T1_FIELD_NUM ( "GDBytes", gd_bytes, 0 ) + T1_FIELD_NUM ( "CIDCount", cid_count, 0 ) + + +#undef FT_STRUCTURE +#define FT_STRUCTURE PS_FontInfoRec +#undef T1CODE +#define T1CODE T1_FIELD_LOCATION_FONT_INFO + + T1_FIELD_STRING( "version", version, 0 ) + T1_FIELD_STRING( "Notice", notice, 0 ) + T1_FIELD_STRING( "FullName", full_name, 0 ) + T1_FIELD_STRING( "FamilyName", family_name, 0 ) + T1_FIELD_STRING( "Weight", weight, 0 ) + T1_FIELD_NUM ( "ItalicAngle", italic_angle, 0 ) + T1_FIELD_BOOL ( "isFixedPitch", is_fixed_pitch, 0 ) + T1_FIELD_NUM ( "UnderlinePosition", underline_position, 0 ) + T1_FIELD_NUM ( "UnderlineThickness", underline_thickness, 0 ) + +#undef FT_STRUCTURE +#define FT_STRUCTURE PS_FontExtraRec +#undef T1CODE +#define T1CODE T1_FIELD_LOCATION_FONT_EXTRA + + T1_FIELD_NUM ( "FSType", fs_type, 0 ) + + +#undef FT_STRUCTURE +#define FT_STRUCTURE CID_FaceDictRec +#undef T1CODE +#define T1CODE T1_FIELD_LOCATION_FONT_DICT + + T1_FIELD_NUM ( "PaintType", paint_type, 0 ) + T1_FIELD_NUM ( "FontType", font_type, 0 ) + T1_FIELD_NUM ( "SubrMapOffset", subrmap_offset, 0 ) + T1_FIELD_NUM ( "SDBytes", sd_bytes, 0 ) + T1_FIELD_NUM ( "SubrCount", num_subrs, 0 ) + T1_FIELD_NUM ( "lenBuildCharArray", len_buildchar, 0 ) + T1_FIELD_FIXED( "ForceBoldThreshold", forcebold_threshold, 0 ) + T1_FIELD_FIXED( "StrokeWidth", stroke_width, 0 ) + + +#undef FT_STRUCTURE +#define FT_STRUCTURE PS_PrivateRec +#undef T1CODE +#define T1CODE T1_FIELD_LOCATION_PRIVATE + + T1_FIELD_NUM ( "UniqueID", unique_id, 0 ) + T1_FIELD_NUM ( "lenIV", lenIV, 0 ) + T1_FIELD_NUM ( "LanguageGroup", language_group, 0 ) + T1_FIELD_NUM ( "password", password, 0 ) + + T1_FIELD_FIXED_1000( "BlueScale", blue_scale, 0 ) + T1_FIELD_NUM ( "BlueShift", blue_shift, 0 ) + T1_FIELD_NUM ( "BlueFuzz", blue_fuzz, 0 ) + + T1_FIELD_NUM_TABLE ( "BlueValues", blue_values, 14, 0 ) + T1_FIELD_NUM_TABLE ( "OtherBlues", other_blues, 10, 0 ) + T1_FIELD_NUM_TABLE ( "FamilyBlues", family_blues, 14, 0 ) + T1_FIELD_NUM_TABLE ( "FamilyOtherBlues", family_other_blues, 10, 0 ) + + T1_FIELD_NUM_TABLE2( "StdHW", standard_width, 1, 0 ) + T1_FIELD_NUM_TABLE2( "StdVW", standard_height, 1, 0 ) + T1_FIELD_NUM_TABLE2( "MinFeature", min_feature, 2, 0 ) + + T1_FIELD_NUM_TABLE ( "StemSnapH", snap_widths, 12, 0 ) + T1_FIELD_NUM_TABLE ( "StemSnapV", snap_heights, 12, 0 ) + + T1_FIELD_BOOL ( "ForceBold", force_bold, 0 ) + + +#undef FT_STRUCTURE +#define FT_STRUCTURE FT_BBox +#undef T1CODE +#define T1CODE T1_FIELD_LOCATION_BBOX + + T1_FIELD_BBOX( "FontBBox", xMin, 0 ) + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/cid/type1cid.c b/mod/pub.mod/freetype.mod/src/cid/type1cid.c new file mode 100644 index 0000000..0b866e9 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/cid/type1cid.c @@ -0,0 +1,29 @@ +/***************************************************************************/ +/* */ +/* type1cid.c */ +/* */ +/* FreeType OpenType driver component (body only). */ +/* */ +/* Copyright 1996-2001 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#define FT_MAKE_OPTION_SINGLE_OBJECT + +#include <ft2build.h> +#include "cidparse.c" +#include "cidload.c" +#include "cidobjs.c" +#include "cidriver.c" +#include "cidgload.c" + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/gzip/adler32.c b/mod/pub.mod/freetype.mod/src/gzip/adler32.c new file mode 100644 index 0000000..c53f9dd --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/gzip/adler32.c @@ -0,0 +1,48 @@ +/* adler32.c -- compute the Adler-32 checksum of a data stream + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#include "zlib.h" + +#define BASE 65521L /* largest prime smaller than 65536 */ +#define NMAX 5552 +/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ + +#define DO1(buf,i) {s1 += buf[i]; s2 += s1;} +#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); +#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); +#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); +#define DO16(buf) DO8(buf,0); DO8(buf,8); + +/* ========================================================================= */ +ZEXPORT(uLong) adler32( /* adler, buf, len) */ + uLong adler, + const Bytef *buf, + uInt len ) +{ + unsigned long s1 = adler & 0xffff; + unsigned long s2 = (adler >> 16) & 0xffff; + int k; + + if (buf == Z_NULL) return 1L; + + while (len > 0) { + k = len < NMAX ? len : NMAX; + len -= k; + while (k >= 16) { + DO16(buf); + buf += 16; + k -= 16; + } + if (k != 0) do { + s1 += *buf++; + s2 += s1; + } while (--k); + s1 %= BASE; + s2 %= BASE; + } + return (s2 << 16) | s1; +} diff --git a/mod/pub.mod/freetype.mod/src/gzip/ftgzip.c b/mod/pub.mod/freetype.mod/src/gzip/ftgzip.c new file mode 100644 index 0000000..6f0c515 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/gzip/ftgzip.c @@ -0,0 +1,688 @@ +/***************************************************************************/ +/* */ +/* ftgzip.c */ +/* */ +/* FreeType support for .gz compressed files. */ +/* */ +/* This optional component relies on zlib. It should mainly be used to */ +/* parse compressed PCF fonts, as found with many X11 server */ +/* distributions. */ +/* */ +/* Copyright 2002, 2003, 2004, 2005, 2006, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_MEMORY_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_DEBUG_H +#include FT_GZIP_H +#include FT_CONFIG_STANDARD_LIBRARY_H + + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#define FT_ERR_PREFIX Gzip_Err_ +#define FT_ERR_BASE FT_Mod_Err_Gzip + +#include FT_ERRORS_H + + +#ifdef FT_CONFIG_OPTION_USE_ZLIB + +#ifdef FT_CONFIG_OPTION_PIC +#error "gzip code does not support PIC yet" +#endif + +#ifdef FT_CONFIG_OPTION_SYSTEM_ZLIB + +#include <zlib.h> + +#else /* !FT_CONFIG_OPTION_SYSTEM_ZLIB */ + + /* In this case, we include our own modified sources of the ZLib */ + /* within the "ftgzip" component. The modifications were necessary */ + /* to #include all files without conflicts, as well as preventing */ + /* the definition of "extern" functions that may cause linking */ + /* conflicts when a program is linked with both FreeType and the */ + /* original ZLib. */ + +#define NO_DUMMY_DECL +#ifndef USE_ZLIB_ZCALLOC +#define MY_ZCALLOC /* prevent all zcalloc() & zfree() in zutils.c */ +#endif + +#include "zlib.h" + +#undef SLOW +#define SLOW 1 /* we can't use asm-optimized sources here! */ + + /* Urgh. `inflate_mask' must not be declared twice -- C++ doesn't like + this. We temporarily disable it and load all necessary header files. */ +#define NO_INFLATE_MASK +#include "zutil.h" +#include "inftrees.h" +#include "infblock.h" +#include "infcodes.h" +#include "infutil.h" +#undef NO_INFLATE_MASK + + /* infutil.c must be included before infcodes.c */ +#include "zutil.c" +#include "inftrees.c" +#include "infutil.c" +#include "infcodes.c" +#include "infblock.c" +#include "inflate.c" +#include "adler32.c" + +#endif /* !FT_CONFIG_OPTION_SYSTEM_ZLIB */ + + +/***************************************************************************/ +/***************************************************************************/ +/***** *****/ +/***** Z L I B M E M O R Y M A N A G E M E N T *****/ +/***** *****/ +/***************************************************************************/ +/***************************************************************************/ + + /* it is better to use FreeType memory routines instead of raw + 'malloc/free' */ + + static voidpf + ft_gzip_alloc( FT_Memory memory, + uInt items, + uInt size ) + { + FT_ULong sz = (FT_ULong)size * items; + FT_Error error; + FT_Pointer p; + + + (void)FT_ALLOC( p, sz ); + return p; + } + + + static void + ft_gzip_free( FT_Memory memory, + voidpf address ) + { + FT_MEM_FREE( address ); + } + + +#if !defined( FT_CONFIG_OPTION_SYSTEM_ZLIB ) && !defined( USE_ZLIB_ZCALLOC ) + + local voidpf + zcalloc ( voidpf opaque, + unsigned items, + unsigned size ) + { + return ft_gzip_alloc( (FT_Memory)opaque, items, size ); + } + + local void + zcfree( voidpf opaque, + voidpf ptr ) + { + ft_gzip_free( (FT_Memory)opaque, ptr ); + } + +#endif /* !SYSTEM_ZLIB && !USE_ZLIB_ZCALLOC */ + + +/***************************************************************************/ +/***************************************************************************/ +/***** *****/ +/***** Z L I B F I L E D E S C R I P T O R *****/ +/***** *****/ +/***************************************************************************/ +/***************************************************************************/ + +#define FT_GZIP_BUFFER_SIZE 4096 + + typedef struct FT_GZipFileRec_ + { + FT_Stream source; /* parent/source stream */ + FT_Stream stream; /* embedding stream */ + FT_Memory memory; /* memory allocator */ + z_stream zstream; /* zlib input stream */ + + FT_ULong start; /* starting position, after .gz header */ + FT_Byte input[FT_GZIP_BUFFER_SIZE]; /* input read buffer */ + + FT_Byte buffer[FT_GZIP_BUFFER_SIZE]; /* output buffer */ + FT_ULong pos; /* position in output */ + FT_Byte* cursor; + FT_Byte* limit; + + } FT_GZipFileRec, *FT_GZipFile; + + + /* gzip flag byte */ +#define FT_GZIP_ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ +#define FT_GZIP_HEAD_CRC 0x02 /* bit 1 set: header CRC present */ +#define FT_GZIP_EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ +#define FT_GZIP_ORIG_NAME 0x08 /* bit 3 set: original file name present */ +#define FT_GZIP_COMMENT 0x10 /* bit 4 set: file comment present */ +#define FT_GZIP_RESERVED 0xE0 /* bits 5..7: reserved */ + + + /* check and skip .gz header - we don't support `transparent' compression */ + static FT_Error + ft_gzip_check_header( FT_Stream stream ) + { + FT_Error error; + FT_Byte head[4]; + + + if ( FT_STREAM_SEEK( 0 ) || + FT_STREAM_READ( head, 4 ) ) + goto Exit; + + /* head[0] && head[1] are the magic numbers; */ + /* head[2] is the method, and head[3] the flags */ + if ( head[0] != 0x1f || + head[1] != 0x8b || + head[2] != Z_DEFLATED || + (head[3] & FT_GZIP_RESERVED) ) + { + error = Gzip_Err_Invalid_File_Format; + goto Exit; + } + + /* skip time, xflags and os code */ + (void)FT_STREAM_SKIP( 6 ); + + /* skip the extra field */ + if ( head[3] & FT_GZIP_EXTRA_FIELD ) + { + FT_UInt len; + + + if ( FT_READ_USHORT_LE( len ) || + FT_STREAM_SKIP( len ) ) + goto Exit; + } + + /* skip original file name */ + if ( head[3] & FT_GZIP_ORIG_NAME ) + for (;;) + { + FT_UInt c; + + + if ( FT_READ_BYTE( c ) ) + goto Exit; + + if ( c == 0 ) + break; + } + + /* skip .gz comment */ + if ( head[3] & FT_GZIP_COMMENT ) + for (;;) + { + FT_UInt c; + + + if ( FT_READ_BYTE( c ) ) + goto Exit; + + if ( c == 0 ) + break; + } + + /* skip CRC */ + if ( head[3] & FT_GZIP_HEAD_CRC ) + if ( FT_STREAM_SKIP( 2 ) ) + goto Exit; + + Exit: + return error; + } + + + static FT_Error + ft_gzip_file_init( FT_GZipFile zip, + FT_Stream stream, + FT_Stream source ) + { + z_stream* zstream = &zip->zstream; + FT_Error error = Gzip_Err_Ok; + + + zip->stream = stream; + zip->source = source; + zip->memory = stream->memory; + + zip->limit = zip->buffer + FT_GZIP_BUFFER_SIZE; + zip->cursor = zip->limit; + zip->pos = 0; + + /* check and skip .gz header */ + { + stream = source; + + error = ft_gzip_check_header( stream ); + if ( error ) + goto Exit; + + zip->start = FT_STREAM_POS(); + } + + /* initialize zlib -- there is no zlib header in the compressed stream */ + zstream->zalloc = (alloc_func)ft_gzip_alloc; + zstream->zfree = (free_func) ft_gzip_free; + zstream->opaque = stream->memory; + + zstream->avail_in = 0; + zstream->next_in = zip->buffer; + + if ( inflateInit2( zstream, -MAX_WBITS ) != Z_OK || + zstream->next_in == NULL ) + error = Gzip_Err_Invalid_File_Format; + + Exit: + return error; + } + + + static void + ft_gzip_file_done( FT_GZipFile zip ) + { + z_stream* zstream = &zip->zstream; + + + inflateEnd( zstream ); + + /* clear the rest */ + zstream->zalloc = NULL; + zstream->zfree = NULL; + zstream->opaque = NULL; + zstream->next_in = NULL; + zstream->next_out = NULL; + zstream->avail_in = 0; + zstream->avail_out = 0; + + zip->memory = NULL; + zip->source = NULL; + zip->stream = NULL; + } + + + static FT_Error + ft_gzip_file_reset( FT_GZipFile zip ) + { + FT_Stream stream = zip->source; + FT_Error error; + + + if ( !FT_STREAM_SEEK( zip->start ) ) + { + z_stream* zstream = &zip->zstream; + + + inflateReset( zstream ); + + zstream->avail_in = 0; + zstream->next_in = zip->input; + zstream->avail_out = 0; + zstream->next_out = zip->buffer; + + zip->limit = zip->buffer + FT_GZIP_BUFFER_SIZE; + zip->cursor = zip->limit; + zip->pos = 0; + } + + return error; + } + + + static FT_Error + ft_gzip_file_fill_input( FT_GZipFile zip ) + { + z_stream* zstream = &zip->zstream; + FT_Stream stream = zip->source; + FT_ULong size; + + + if ( stream->read ) + { + size = stream->read( stream, stream->pos, zip->input, + FT_GZIP_BUFFER_SIZE ); + if ( size == 0 ) + return Gzip_Err_Invalid_Stream_Operation; + } + else + { + size = stream->size - stream->pos; + if ( size > FT_GZIP_BUFFER_SIZE ) + size = FT_GZIP_BUFFER_SIZE; + + if ( size == 0 ) + return Gzip_Err_Invalid_Stream_Operation; + + FT_MEM_COPY( zip->input, stream->base + stream->pos, size ); + } + stream->pos += size; + + zstream->next_in = zip->input; + zstream->avail_in = size; + + return Gzip_Err_Ok; + } + + + static FT_Error + ft_gzip_file_fill_output( FT_GZipFile zip ) + { + z_stream* zstream = &zip->zstream; + FT_Error error = 0; + + + zip->cursor = zip->buffer; + zstream->next_out = zip->cursor; + zstream->avail_out = FT_GZIP_BUFFER_SIZE; + + while ( zstream->avail_out > 0 ) + { + int err; + + + if ( zstream->avail_in == 0 ) + { + error = ft_gzip_file_fill_input( zip ); + if ( error ) + break; + } + + err = inflate( zstream, Z_NO_FLUSH ); + + if ( err == Z_STREAM_END ) + { + zip->limit = zstream->next_out; + if ( zip->limit == zip->cursor ) + error = Gzip_Err_Invalid_Stream_Operation; + break; + } + else if ( err != Z_OK ) + { + error = Gzip_Err_Invalid_Stream_Operation; + break; + } + } + + return error; + } + + + /* fill output buffer; `count' must be <= FT_GZIP_BUFFER_SIZE */ + static FT_Error + ft_gzip_file_skip_output( FT_GZipFile zip, + FT_ULong count ) + { + FT_Error error = Gzip_Err_Ok; + FT_ULong delta; + + + for (;;) + { + delta = (FT_ULong)( zip->limit - zip->cursor ); + if ( delta >= count ) + delta = count; + + zip->cursor += delta; + zip->pos += delta; + + count -= delta; + if ( count == 0 ) + break; + + error = ft_gzip_file_fill_output( zip ); + if ( error ) + break; + } + + return error; + } + + + static FT_ULong + ft_gzip_file_io( FT_GZipFile zip, + FT_ULong pos, + FT_Byte* buffer, + FT_ULong count ) + { + FT_ULong result = 0; + FT_Error error; + + + /* Reset inflate stream if we're seeking backwards. */ + /* Yes, that is not too efficient, but it saves memory :-) */ + if ( pos < zip->pos ) + { + error = ft_gzip_file_reset( zip ); + if ( error ) + goto Exit; + } + + /* skip unwanted bytes */ + if ( pos > zip->pos ) + { + error = ft_gzip_file_skip_output( zip, (FT_ULong)( pos - zip->pos ) ); + if ( error ) + goto Exit; + } + + if ( count == 0 ) + goto Exit; + + /* now read the data */ + for (;;) + { + FT_ULong delta; + + + delta = (FT_ULong)( zip->limit - zip->cursor ); + if ( delta >= count ) + delta = count; + + FT_MEM_COPY( buffer, zip->cursor, delta ); + buffer += delta; + result += delta; + zip->cursor += delta; + zip->pos += delta; + + count -= delta; + if ( count == 0 ) + break; + + error = ft_gzip_file_fill_output( zip ); + if ( error ) + break; + } + + Exit: + return result; + } + + +/***************************************************************************/ +/***************************************************************************/ +/***** *****/ +/***** G Z E M B E D D I N G S T R E A M *****/ +/***** *****/ +/***************************************************************************/ +/***************************************************************************/ + + static void + ft_gzip_stream_close( FT_Stream stream ) + { + FT_GZipFile zip = (FT_GZipFile)stream->descriptor.pointer; + FT_Memory memory = stream->memory; + + + if ( zip ) + { + /* finalize gzip file descriptor */ + ft_gzip_file_done( zip ); + + FT_FREE( zip ); + + stream->descriptor.pointer = NULL; + } + } + + + static FT_ULong + ft_gzip_stream_io( FT_Stream stream, + FT_ULong pos, + FT_Byte* buffer, + FT_ULong count ) + { + FT_GZipFile zip = (FT_GZipFile)stream->descriptor.pointer; + + + return ft_gzip_file_io( zip, pos, buffer, count ); + } + + + static FT_ULong + ft_gzip_get_uncompressed_size( FT_Stream stream ) + { + FT_Error error; + FT_ULong old_pos; + FT_ULong result = 0; + + + old_pos = stream->pos; + if ( !FT_Stream_Seek( stream, stream->size - 4 ) ) + { + result = (FT_ULong)FT_Stream_ReadLong( stream, &error ); + if ( error ) + result = 0; + + (void)FT_Stream_Seek( stream, old_pos ); + } + + return result; + } + + + FT_EXPORT_DEF( FT_Error ) + FT_Stream_OpenGzip( FT_Stream stream, + FT_Stream source ) + { + FT_Error error; + FT_Memory memory = source->memory; + FT_GZipFile zip; + + + /* + * check the header right now; this prevents allocating un-necessary + * objects when we don't need them + */ + error = ft_gzip_check_header( source ); + if ( error ) + goto Exit; + + FT_ZERO( stream ); + stream->memory = memory; + + if ( !FT_QNEW( zip ) ) + { + error = ft_gzip_file_init( zip, stream, source ); + if ( error ) + { + FT_FREE( zip ); + goto Exit; + } + + stream->descriptor.pointer = zip; + } + + /* + * We use the following trick to try to dramatically improve the + * performance while dealing with small files. If the original stream + * size is less than a certain threshold, we try to load the whole font + * file into memory. This saves us from using the 32KB buffer needed + * to inflate the file, plus the two 4KB intermediate input/output + * buffers used in the `FT_GZipFile' structure. + */ + { + FT_ULong zip_size = ft_gzip_get_uncompressed_size( source ); + + + if ( zip_size != 0 && zip_size < 40 * 1024 ) + { + FT_Byte* zip_buff; + + + if ( !FT_ALLOC( zip_buff, zip_size ) ) + { + FT_ULong count; + + + count = ft_gzip_file_io( zip, 0, zip_buff, zip_size ); + if ( count == zip_size ) + { + ft_gzip_file_done( zip ); + FT_FREE( zip ); + + stream->descriptor.pointer = NULL; + + stream->size = zip_size; + stream->pos = 0; + stream->base = zip_buff; + stream->read = NULL; + stream->close = ft_gzip_stream_close; + + goto Exit; + } + + ft_gzip_file_io( zip, 0, NULL, 0 ); + FT_FREE( zip_buff ); + } + error = 0; + } + } + + stream->size = 0x7FFFFFFFL; /* don't know the real size! */ + stream->pos = 0; + stream->base = 0; + stream->read = ft_gzip_stream_io; + stream->close = ft_gzip_stream_close; + + Exit: + return error; + } + +#else /* !FT_CONFIG_OPTION_USE_ZLIB */ + + FT_EXPORT_DEF( FT_Error ) + FT_Stream_OpenGzip( FT_Stream stream, + FT_Stream source ) + { + FT_UNUSED( stream ); + FT_UNUSED( source ); + + return Gzip_Err_Unimplemented_Feature; + } + +#endif /* !FT_CONFIG_OPTION_USE_ZLIB */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/gzip/infblock.c b/mod/pub.mod/freetype.mod/src/gzip/infblock.c new file mode 100644 index 0000000..d6e2dc2 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/gzip/infblock.c @@ -0,0 +1,387 @@ +/* infblock.c -- interpret and process block types to last block + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "infblock.h" +#include "inftrees.h" +#include "infcodes.h" +#include "infutil.h" + + +/* simplify the use of the inflate_huft type with some defines */ +#define exop word.what.Exop +#define bits word.what.Bits + +/* Table for deflate from PKZIP's appnote.txt. */ +local const uInt border[] = { /* Order of the bit length code lengths */ + 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + +/* + Notes beyond the 1.93a appnote.txt: + + 1. Distance pointers never point before the beginning of the output + stream. + 2. Distance pointers can point back across blocks, up to 32k away. + 3. There is an implied maximum of 7 bits for the bit length table and + 15 bits for the actual data. + 4. If only one code exists, then it is encoded using one bit. (Zero + would be more efficient, but perhaps a little confusing.) If two + codes exist, they are coded using one bit each (0 and 1). + 5. There is no way of sending zero distance codes--a dummy must be + sent if there are none. (History: a pre 2.0 version of PKZIP would + store blocks with no distance codes, but this was discovered to be + too harsh a criterion.) Valid only for 1.93a. 2.04c does allow + zero distance codes, which is sent as one code of zero bits in + length. + 6. There are up to 286 literal/length codes. Code 256 represents the + end-of-block. Note however that the static length tree defines + 288 codes just to fill out the Huffman codes. Codes 286 and 287 + cannot be used though, since there is no length base or extra bits + defined for them. Similarily, there are up to 30 distance codes. + However, static trees define 32 codes (all 5 bits) to fill out the + Huffman codes, but the last two had better not show up in the data. + 7. Unzip can check dynamic Huffman blocks for complete code sets. + The exception is that a single code would not be complete (see #4). + 8. The five bits following the block type is really the number of + literal codes sent minus 257. + 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits + (1+6+6). Therefore, to output three times the length, you output + three codes (1+1+1), whereas to output four times the same length, + you only need two codes (1+3). Hmm. + 10. In the tree reconstruction algorithm, Code = Code + Increment + only if BitLength(i) is not zero. (Pretty obvious.) + 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19) + 12. Note: length code 284 can represent 227-258, but length code 285 + really is 258. The last length deserves its own, short code + since it gets used a lot in very redundant files. The length + 258 is special since 258 - 3 (the min match length) is 255. + 13. The literal/length and distance code bit lengths are read as a + single stream of lengths. It is possible (and advantageous) for + a repeat code (16, 17, or 18) to go across the boundary between + the two sets of lengths. + */ + + +local void inflate_blocks_reset( /* s, z, c) */ +inflate_blocks_statef *s, +z_streamp z, +uLongf *c ) +{ + if (c != Z_NULL) + *c = s->check; + if (s->mode == BTREE || s->mode == DTREE) + ZFREE(z, s->sub.trees.blens); + if (s->mode == CODES) + inflate_codes_free(s->sub.decode.codes, z); + s->mode = TYPE; + s->bitk = 0; + s->bitb = 0; + s->read = s->write = s->window; + if (s->checkfn != Z_NULL) + z->adler = s->check = (*s->checkfn)(0L, (const Bytef *)Z_NULL, 0); + Tracev((stderr, "inflate: blocks reset\n")); +} + + +local inflate_blocks_statef *inflate_blocks_new( /* z, c, w) */ +z_streamp z, +check_func c, +uInt w ) +{ + inflate_blocks_statef *s; + + if ((s = (inflate_blocks_statef *)ZALLOC + (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL) + return s; + if ((s->hufts = + (inflate_huft *)ZALLOC(z, sizeof(inflate_huft), MANY)) == Z_NULL) + { + ZFREE(z, s); + return Z_NULL; + } + if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL) + { + ZFREE(z, s->hufts); + ZFREE(z, s); + return Z_NULL; + } + s->end = s->window + w; + s->checkfn = c; + s->mode = TYPE; + Tracev((stderr, "inflate: blocks allocated\n")); + inflate_blocks_reset(s, z, Z_NULL); + return s; +} + + +local int inflate_blocks( /* s, z, r) */ +inflate_blocks_statef *s, +z_streamp z, +int r ) +{ + uInt t; /* temporary storage */ + uLong b; /* bit buffer */ + uInt k; /* bits in bit buffer */ + Bytef *p; /* input data pointer */ + uInt n; /* bytes available there */ + Bytef *q; /* output window write pointer */ + uInt m; /* bytes to end of window or read pointer */ + + /* copy input/output information to locals (UPDATE macro restores) */ + LOAD + + /* process input based on current state */ + while (1) switch (s->mode) + { + case TYPE: + NEEDBITS(3) + t = (uInt)b & 7; + s->last = t & 1; + switch (t >> 1) + { + case 0: /* stored */ + Tracev((stderr, "inflate: stored block%s\n", + s->last ? " (last)" : "")); + DUMPBITS(3) + t = k & 7; /* go to byte boundary */ + DUMPBITS(t) + s->mode = LENS; /* get length of stored block */ + break; + case 1: /* fixed */ + Tracev((stderr, "inflate: fixed codes block%s\n", + s->last ? " (last)" : "")); + { + uInt bl, bd; + inflate_huft *tl, *td; + + inflate_trees_fixed(&bl, &bd, (const inflate_huft**)&tl, + (const inflate_huft**)&td, z); + s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z); + if (s->sub.decode.codes == Z_NULL) + { + r = Z_MEM_ERROR; + LEAVE + } + } + DUMPBITS(3) + s->mode = CODES; + break; + case 2: /* dynamic */ + Tracev((stderr, "inflate: dynamic codes block%s\n", + s->last ? " (last)" : "")); + DUMPBITS(3) + s->mode = TABLE; + break; + case 3: /* illegal */ + DUMPBITS(3) + s->mode = BAD; + z->msg = (char*)"invalid block type"; + r = Z_DATA_ERROR; + LEAVE + } + break; + case LENS: + NEEDBITS(32) + if ((((~b) >> 16) & 0xffff) != (b & 0xffff)) + { + s->mode = BAD; + z->msg = (char*)"invalid stored block lengths"; + r = Z_DATA_ERROR; + LEAVE + } + s->sub.left = (uInt)b & 0xffff; + b = k = 0; /* dump bits */ + Tracev((stderr, "inflate: stored length %u\n", s->sub.left)); + s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE); + break; + case STORED: + if (n == 0) + LEAVE + NEEDOUT + t = s->sub.left; + if (t > n) t = n; + if (t > m) t = m; + zmemcpy(q, p, t); + p += t; n -= t; + q += t; m -= t; + if ((s->sub.left -= t) != 0) + break; + Tracev((stderr, "inflate: stored end, %lu total out\n", + z->total_out + (q >= s->read ? q - s->read : + (s->end - s->read) + (q - s->window)))); + s->mode = s->last ? DRY : TYPE; + break; + case TABLE: + NEEDBITS(14) + s->sub.trees.table = t = (uInt)b & 0x3fff; +#ifndef PKZIP_BUG_WORKAROUND + if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) + { + s->mode = BAD; + z->msg = (char*)"too many length or distance symbols"; + r = Z_DATA_ERROR; + LEAVE + } +#endif + t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); + if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL) + { + r = Z_MEM_ERROR; + LEAVE + } + DUMPBITS(14) + s->sub.trees.index = 0; + Tracev((stderr, "inflate: table sizes ok\n")); + s->mode = BTREE; + case BTREE: + while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10)) + { + NEEDBITS(3) + s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7; + DUMPBITS(3) + } + while (s->sub.trees.index < 19) + s->sub.trees.blens[border[s->sub.trees.index++]] = 0; + s->sub.trees.bb = 7; + t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb, + &s->sub.trees.tb, s->hufts, z); + if (t != Z_OK) + { + r = t; + if (r == Z_DATA_ERROR) + { + ZFREE(z, s->sub.trees.blens); + s->mode = BAD; + } + LEAVE + } + s->sub.trees.index = 0; + Tracev((stderr, "inflate: bits tree ok\n")); + s->mode = DTREE; + case DTREE: + while (t = s->sub.trees.table, + s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f)) + { + inflate_huft *h; + uInt i, j, c; + + t = s->sub.trees.bb; + NEEDBITS(t) + h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]); + t = h->bits; + c = h->base; + if (c < 16) + { + DUMPBITS(t) + s->sub.trees.blens[s->sub.trees.index++] = c; + } + else /* c == 16..18 */ + { + i = c == 18 ? 7 : c - 14; + j = c == 18 ? 11 : 3; + NEEDBITS(t + i) + DUMPBITS(t) + j += (uInt)b & inflate_mask[i]; + DUMPBITS(i) + i = s->sub.trees.index; + t = s->sub.trees.table; + if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || + (c == 16 && i < 1)) + { + ZFREE(z, s->sub.trees.blens); + s->mode = BAD; + z->msg = (char*)"invalid bit length repeat"; + r = Z_DATA_ERROR; + LEAVE + } + c = c == 16 ? s->sub.trees.blens[i - 1] : 0; + do { + s->sub.trees.blens[i++] = c; + } while (--j); + s->sub.trees.index = i; + } + } + s->sub.trees.tb = Z_NULL; + { + uInt bl, bd; + inflate_huft *tl, *td; + inflate_codes_statef *c; + + bl = 9; /* must be <= 9 for lookahead assumptions */ + bd = 6; /* must be <= 9 for lookahead assumptions */ + t = s->sub.trees.table; + t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), + s->sub.trees.blens, &bl, &bd, &tl, &td, + s->hufts, z); + if (t != Z_OK) + { + if (t == (uInt)Z_DATA_ERROR) + { + ZFREE(z, s->sub.trees.blens); + s->mode = BAD; + } + r = t; + LEAVE + } + Tracev((stderr, "inflate: trees ok\n")); + if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL) + { + r = Z_MEM_ERROR; + LEAVE + } + s->sub.decode.codes = c; + } + ZFREE(z, s->sub.trees.blens); + s->mode = CODES; + case CODES: + UPDATE + if ((r = inflate_codes(s, z, r)) != Z_STREAM_END) + return inflate_flush(s, z, r); + r = Z_OK; + inflate_codes_free(s->sub.decode.codes, z); + LOAD + Tracev((stderr, "inflate: codes end, %lu total out\n", + z->total_out + (q >= s->read ? q - s->read : + (s->end - s->read) + (q - s->window)))); + if (!s->last) + { + s->mode = TYPE; + break; + } + s->mode = DRY; + case DRY: + FLUSH + if (s->read != s->write) + LEAVE + s->mode = DONE; + case DONE: + r = Z_STREAM_END; + LEAVE + case BAD: + r = Z_DATA_ERROR; + LEAVE + default: + r = Z_STREAM_ERROR; + LEAVE + } +#ifdef NEED_DUMMY_RETURN + return 0; +#endif +} + + +local int inflate_blocks_free( /* s, z) */ +inflate_blocks_statef *s, +z_streamp z ) +{ + inflate_blocks_reset(s, z, Z_NULL); + ZFREE(z, s->window); + ZFREE(z, s->hufts); + ZFREE(z, s); + Tracev((stderr, "inflate: blocks freed\n")); + return Z_OK; +} + + diff --git a/mod/pub.mod/freetype.mod/src/gzip/infblock.h b/mod/pub.mod/freetype.mod/src/gzip/infblock.h new file mode 100644 index 0000000..c2535a1 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/gzip/infblock.h @@ -0,0 +1,36 @@ +/* infblock.h -- header to use infblock.c + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +#ifndef _INFBLOCK_H +#define _INFBLOCK_H + +struct inflate_blocks_state; +typedef struct inflate_blocks_state FAR inflate_blocks_statef; + +local inflate_blocks_statef * inflate_blocks_new OF(( + z_streamp z, + check_func c, /* check function */ + uInt w)); /* window size */ + +local int inflate_blocks OF(( + inflate_blocks_statef *, + z_streamp , + int)); /* initial return code */ + +local void inflate_blocks_reset OF(( + inflate_blocks_statef *, + z_streamp , + uLongf *)); /* check value on output */ + +local int inflate_blocks_free OF(( + inflate_blocks_statef *, + z_streamp)); + +#endif /* _INFBLOCK_H */ diff --git a/mod/pub.mod/freetype.mod/src/gzip/infcodes.c b/mod/pub.mod/freetype.mod/src/gzip/infcodes.c new file mode 100644 index 0000000..f7bfd58 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/gzip/infcodes.c @@ -0,0 +1,250 @@ +/* infcodes.c -- process literals and length/distance pairs + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" +#include "infblock.h" +#include "infcodes.h" +#include "infutil.h" + +/* simplify the use of the inflate_huft type with some defines */ +#define exop word.what.Exop +#define bits word.what.Bits + +typedef enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ + START, /* x: set up for LEN */ + LEN, /* i: get length/literal/eob next */ + LENEXT, /* i: getting length extra (have base) */ + DIST, /* i: get distance next */ + DISTEXT, /* i: getting distance extra */ + COPY, /* o: copying bytes in window, waiting for space */ + LIT, /* o: got literal, waiting for output space */ + WASH, /* o: got eob, possibly still output waiting */ + END, /* x: got eob and all data flushed */ + BADCODE} /* x: got error */ +inflate_codes_mode; + +/* inflate codes private state */ +struct inflate_codes_state { + + /* mode */ + inflate_codes_mode mode; /* current inflate_codes mode */ + + /* mode dependent information */ + uInt len; + union { + struct { + inflate_huft *tree; /* pointer into tree */ + uInt need; /* bits needed */ + } code; /* if LEN or DIST, where in tree */ + uInt lit; /* if LIT, literal */ + struct { + uInt get; /* bits to get for extra */ + uInt dist; /* distance back to copy from */ + } copy; /* if EXT or COPY, where and how much */ + } sub; /* submode */ + + /* mode independent information */ + Byte lbits; /* ltree bits decoded per branch */ + Byte dbits; /* dtree bits decoder per branch */ + inflate_huft *ltree; /* literal/length/eob tree */ + inflate_huft *dtree; /* distance tree */ + +}; + + +local inflate_codes_statef *inflate_codes_new( /* bl, bd, tl, td, z) */ +uInt bl, uInt bd, +inflate_huft *tl, +inflate_huft *td, /* need separate declaration for Borland C++ */ +z_streamp z ) +{ + inflate_codes_statef *c; + + if ((c = (inflate_codes_statef *) + ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL) + { + c->mode = START; + c->lbits = (Byte)bl; + c->dbits = (Byte)bd; + c->ltree = tl; + c->dtree = td; + Tracev((stderr, "inflate: codes new\n")); + } + return c; +} + + +local int inflate_codes( /* s, z, r) */ +inflate_blocks_statef *s, +z_streamp z, +int r ) +{ + uInt j; /* temporary storage */ + inflate_huft *t; /* temporary pointer */ + uInt e; /* extra bits or operation */ + uLong b; /* bit buffer */ + uInt k; /* bits in bit buffer */ + Bytef *p; /* input data pointer */ + uInt n; /* bytes available there */ + Bytef *q; /* output window write pointer */ + uInt m; /* bytes to end of window or read pointer */ + Bytef *f; /* pointer to copy strings from */ + inflate_codes_statef *c = s->sub.decode.codes; /* codes state */ + + /* copy input/output information to locals (UPDATE macro restores) */ + LOAD + + /* process input and output based on current state */ + while (1) switch (c->mode) + { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ + case START: /* x: set up for LEN */ +#ifndef SLOW + if (m >= 258 && n >= 10) + { + UPDATE + r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z); + LOAD + if (r != Z_OK) + { + c->mode = r == Z_STREAM_END ? WASH : BADCODE; + break; + } + } +#endif /* !SLOW */ + c->sub.code.need = c->lbits; + c->sub.code.tree = c->ltree; + c->mode = LEN; + case LEN: /* i: get length/literal/eob next */ + j = c->sub.code.need; + NEEDBITS(j) + t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); + DUMPBITS(t->bits) + e = (uInt)(t->exop); + if (e == 0) /* literal */ + { + c->sub.lit = t->base; + Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", t->base)); + c->mode = LIT; + break; + } + if (e & 16) /* length */ + { + c->sub.copy.get = e & 15; + c->len = t->base; + c->mode = LENEXT; + break; + } + if ((e & 64) == 0) /* next table */ + { + c->sub.code.need = e; + c->sub.code.tree = t + t->base; + break; + } + if (e & 32) /* end of block */ + { + Tracevv((stderr, "inflate: end of block\n")); + c->mode = WASH; + break; + } + c->mode = BADCODE; /* invalid code */ + z->msg = (char*)"invalid literal/length code"; + r = Z_DATA_ERROR; + LEAVE + case LENEXT: /* i: getting length extra (have base) */ + j = c->sub.copy.get; + NEEDBITS(j) + c->len += (uInt)b & inflate_mask[j]; + DUMPBITS(j) + c->sub.code.need = c->dbits; + c->sub.code.tree = c->dtree; + Tracevv((stderr, "inflate: length %u\n", c->len)); + c->mode = DIST; + case DIST: /* i: get distance next */ + j = c->sub.code.need; + NEEDBITS(j) + t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); + DUMPBITS(t->bits) + e = (uInt)(t->exop); + if (e & 16) /* distance */ + { + c->sub.copy.get = e & 15; + c->sub.copy.dist = t->base; + c->mode = DISTEXT; + break; + } + if ((e & 64) == 0) /* next table */ + { + c->sub.code.need = e; + c->sub.code.tree = t + t->base; + break; + } + c->mode = BADCODE; /* invalid code */ + z->msg = (char*)"invalid distance code"; + r = Z_DATA_ERROR; + LEAVE + case DISTEXT: /* i: getting distance extra */ + j = c->sub.copy.get; + NEEDBITS(j) + c->sub.copy.dist += (uInt)b & inflate_mask[j]; + DUMPBITS(j) + Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist)); + c->mode = COPY; + case COPY: /* o: copying bytes in window, waiting for space */ + f = q - c->sub.copy.dist; + while (f < s->window) /* modulo window size-"while" instead */ + f += s->end - s->window; /* of "if" handles invalid distances */ + while (c->len) + { + NEEDOUT + OUTBYTE(*f++) + if (f == s->end) + f = s->window; + c->len--; + } + c->mode = START; + break; + case LIT: /* o: got literal, waiting for output space */ + NEEDOUT + OUTBYTE(c->sub.lit) + c->mode = START; + break; + case WASH: /* o: got eob, possibly more output */ + if (k > 7) /* return unused byte, if any */ + { + Assert(k < 16, "inflate_codes grabbed too many bytes") + k -= 8; + n++; + p--; /* can always return one */ + } + FLUSH + if (s->read != s->write) + LEAVE + c->mode = END; + case END: + r = Z_STREAM_END; + LEAVE + case BADCODE: /* x: got error */ + r = Z_DATA_ERROR; + LEAVE + default: + r = Z_STREAM_ERROR; + LEAVE + } +#ifdef NEED_DUMMY_RETURN + return Z_STREAM_ERROR; /* Some dumb compilers complain without this */ +#endif +} + + +local void inflate_codes_free( /* c, z) */ +inflate_codes_statef *c, +z_streamp z ) +{ + ZFREE(z, c); + Tracev((stderr, "inflate: codes free\n")); +} diff --git a/mod/pub.mod/freetype.mod/src/gzip/infcodes.h b/mod/pub.mod/freetype.mod/src/gzip/infcodes.h new file mode 100644 index 0000000..154d7f8 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/gzip/infcodes.h @@ -0,0 +1,31 @@ +/* infcodes.h -- header to use infcodes.c + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +#ifndef _INFCODES_H +#define _INFCODES_H + +struct inflate_codes_state; +typedef struct inflate_codes_state FAR inflate_codes_statef; + +local inflate_codes_statef *inflate_codes_new OF(( + uInt, uInt, + inflate_huft *, inflate_huft *, + z_streamp )); + +local int inflate_codes OF(( + inflate_blocks_statef *, + z_streamp , + int)); + +local void inflate_codes_free OF(( + inflate_codes_statef *, + z_streamp )); + +#endif /* _INFCODES_H */ diff --git a/mod/pub.mod/freetype.mod/src/gzip/inffixed.h b/mod/pub.mod/freetype.mod/src/gzip/inffixed.h new file mode 100644 index 0000000..4d4760e --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/gzip/inffixed.h @@ -0,0 +1,151 @@ +/* inffixed.h -- table for decoding fixed codes + * Generated automatically by the maketree.c program + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +local const uInt fixed_bl = 9; +local const uInt fixed_bd = 5; +local const inflate_huft fixed_tl[] = { + {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115}, + {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},192}, + {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},160}, + {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},224}, + {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},144}, + {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},208}, + {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},176}, + {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},240}, + {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227}, + {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},200}, + {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},168}, + {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},232}, + {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},152}, + {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},216}, + {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},184}, + {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},248}, + {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163}, + {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},196}, + {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},164}, + {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},228}, + {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},148}, + {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},212}, + {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},180}, + {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},244}, + {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0}, + {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},204}, + {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},172}, + {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},236}, + {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},156}, + {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},220}, + {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},188}, + {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},252}, + {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131}, + {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},194}, + {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},162}, + {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},226}, + {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},146}, + {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},210}, + {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},178}, + {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},242}, + {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258}, + {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},202}, + {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},170}, + {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},234}, + {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},154}, + {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},218}, + {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},186}, + {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},250}, + {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195}, + {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},198}, + {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},166}, + {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},230}, + {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},150}, + {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},214}, + {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},182}, + {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},246}, + {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0}, + {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},206}, + {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},174}, + {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},238}, + {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},158}, + {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},222}, + {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},190}, + {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},254}, + {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115}, + {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},193}, + {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},161}, + {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},225}, + {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},145}, + {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},209}, + {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},177}, + {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},241}, + {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227}, + {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},201}, + {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},169}, + {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},233}, + {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},153}, + {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},217}, + {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},185}, + {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},249}, + {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163}, + {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},197}, + {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},165}, + {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},229}, + {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},149}, + {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},213}, + {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},181}, + {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},245}, + {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0}, + {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},205}, + {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},173}, + {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},237}, + {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},157}, + {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},221}, + {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},189}, + {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},253}, + {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131}, + {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},195}, + {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},163}, + {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},227}, + {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},147}, + {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},211}, + {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},179}, + {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},243}, + {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258}, + {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},203}, + {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},171}, + {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},235}, + {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},155}, + {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},219}, + {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},187}, + {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},251}, + {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195}, + {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},199}, + {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},167}, + {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},231}, + {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},151}, + {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},215}, + {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},183}, + {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},247}, + {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0}, + {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},207}, + {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},175}, + {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},239}, + {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},159}, + {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},223}, + {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},191}, + {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},255} + }; +local const inflate_huft fixed_td[] = { + {{{80,5}},1}, {{{87,5}},257}, {{{83,5}},17}, {{{91,5}},4097}, + {{{81,5}},5}, {{{89,5}},1025}, {{{85,5}},65}, {{{93,5}},16385}, + {{{80,5}},3}, {{{88,5}},513}, {{{84,5}},33}, {{{92,5}},8193}, + {{{82,5}},9}, {{{90,5}},2049}, {{{86,5}},129}, {{{192,5}},24577}, + {{{80,5}},2}, {{{87,5}},385}, {{{83,5}},25}, {{{91,5}},6145}, + {{{81,5}},7}, {{{89,5}},1537}, {{{85,5}},97}, {{{93,5}},24577}, + {{{80,5}},4}, {{{88,5}},769}, {{{84,5}},49}, {{{92,5}},12289}, + {{{82,5}},13}, {{{90,5}},3073}, {{{86,5}},193}, {{{192,5}},24577} + }; diff --git a/mod/pub.mod/freetype.mod/src/gzip/inflate.c b/mod/pub.mod/freetype.mod/src/gzip/inflate.c new file mode 100644 index 0000000..8877fa3 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/gzip/inflate.c @@ -0,0 +1,273 @@ +/* inflate.c -- zlib interface to inflate modules + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "infblock.h" + +#define DONE INFLATE_DONE +#define BAD INFLATE_BAD + +typedef enum { + METHOD, /* waiting for method byte */ + FLAG, /* waiting for flag byte */ + DICT4, /* four dictionary check bytes to go */ + DICT3, /* three dictionary check bytes to go */ + DICT2, /* two dictionary check bytes to go */ + DICT1, /* one dictionary check byte to go */ + DICT0, /* waiting for inflateSetDictionary */ + BLOCKS, /* decompressing blocks */ + CHECK4, /* four check bytes to go */ + CHECK3, /* three check bytes to go */ + CHECK2, /* two check bytes to go */ + CHECK1, /* one check byte to go */ + DONE, /* finished check, done */ + BAD} /* got an error--stay here */ +inflate_mode; + +/* inflate private state */ +struct internal_state { + + /* mode */ + inflate_mode mode; /* current inflate mode */ + + /* mode dependent information */ + union { + uInt method; /* if FLAGS, method byte */ + struct { + uLong was; /* computed check value */ + uLong need; /* stream check value */ + } check; /* if CHECK, check values to compare */ + uInt marker; /* if BAD, inflateSync's marker bytes count */ + } sub; /* submode */ + + /* mode independent information */ + int nowrap; /* flag for no wrapper */ + uInt wbits; /* log2(window size) (8..15, defaults to 15) */ + inflate_blocks_statef + *blocks; /* current inflate_blocks state */ + +}; + + +ZEXPORT(int) inflateReset( /* z) */ +z_streamp z ) +{ + if (z == Z_NULL || z->state == Z_NULL) + return Z_STREAM_ERROR; + z->total_in = z->total_out = 0; + z->msg = Z_NULL; + z->state->mode = z->state->nowrap ? BLOCKS : METHOD; + inflate_blocks_reset(z->state->blocks, z, Z_NULL); + Tracev((stderr, "inflate: reset\n")); + return Z_OK; +} + + +ZEXPORT(int) inflateEnd( /* z) */ +z_streamp z ) +{ + if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL) + return Z_STREAM_ERROR; + if (z->state->blocks != Z_NULL) + inflate_blocks_free(z->state->blocks, z); + ZFREE(z, z->state); + z->state = Z_NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +} + + +ZEXPORT(int) inflateInit2_( /* z, w, version, stream_size) */ +z_streamp z, +int w, +const char *version, +int stream_size ) +{ + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != sizeof(z_stream)) + return Z_VERSION_ERROR; + + /* initialize state */ + if (z == Z_NULL) + return Z_STREAM_ERROR; + z->msg = Z_NULL; + if (z->zalloc == Z_NULL) + { + z->zalloc = zcalloc; + z->opaque = (voidpf)0; + } + if (z->zfree == Z_NULL) z->zfree = zcfree; + if ((z->state = (struct internal_state FAR *) + ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL) + return Z_MEM_ERROR; + z->state->blocks = Z_NULL; + + /* handle undocumented nowrap option (no zlib header or check) */ + z->state->nowrap = 0; + if (w < 0) + { + w = - w; + z->state->nowrap = 1; + } + + /* set window size */ + if (w < 8 || w > 15) + { + inflateEnd(z); + return Z_STREAM_ERROR; + } + z->state->wbits = (uInt)w; + + /* create inflate_blocks state */ + if ((z->state->blocks = + inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w)) + == Z_NULL) + { + inflateEnd(z); + return Z_MEM_ERROR; + } + Tracev((stderr, "inflate: allocated\n")); + + /* reset state */ + inflateReset(z); + return Z_OK; +} + + + +#undef NEEDBYTE +#define NEEDBYTE {if(z->avail_in==0)return r;r=f;} + +#undef NEXTBYTE +#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++) + + +ZEXPORT(int) inflate( /* z, f) */ +z_streamp z, +int f ) +{ + int r; + uInt b; + + if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL) + return Z_STREAM_ERROR; + f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK; + r = Z_BUF_ERROR; + while (1) switch (z->state->mode) + { + case METHOD: + NEEDBYTE + if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED) + { + z->state->mode = BAD; + z->msg = (char*)"unknown compression method"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + if ((z->state->sub.method >> 4) + 8 > z->state->wbits) + { + z->state->mode = BAD; + z->msg = (char*)"invalid window size"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + z->state->mode = FLAG; + case FLAG: + NEEDBYTE + b = NEXTBYTE; + if (((z->state->sub.method << 8) + b) % 31) + { + z->state->mode = BAD; + z->msg = (char*)"incorrect header check"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + Tracev((stderr, "inflate: zlib header ok\n")); + if (!(b & PRESET_DICT)) + { + z->state->mode = BLOCKS; + break; + } + z->state->mode = DICT4; + case DICT4: + NEEDBYTE + z->state->sub.check.need = (uLong)NEXTBYTE << 24; + z->state->mode = DICT3; + case DICT3: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE << 16; + z->state->mode = DICT2; + case DICT2: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE << 8; + z->state->mode = DICT1; + case DICT1: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE; + z->adler = z->state->sub.check.need; + z->state->mode = DICT0; + return Z_NEED_DICT; + case DICT0: + z->state->mode = BAD; + z->msg = (char*)"need dictionary"; + z->state->sub.marker = 0; /* can try inflateSync */ + return Z_STREAM_ERROR; + case BLOCKS: + r = inflate_blocks(z->state->blocks, z, r); + if (r == Z_DATA_ERROR) + { + z->state->mode = BAD; + z->state->sub.marker = 0; /* can try inflateSync */ + break; + } + if (r == Z_OK) + r = f; + if (r != Z_STREAM_END) + return r; + r = f; + inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was); + if (z->state->nowrap) + { + z->state->mode = DONE; + break; + } + z->state->mode = CHECK4; + case CHECK4: + NEEDBYTE + z->state->sub.check.need = (uLong)NEXTBYTE << 24; + z->state->mode = CHECK3; + case CHECK3: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE << 16; + z->state->mode = CHECK2; + case CHECK2: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE << 8; + z->state->mode = CHECK1; + case CHECK1: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE; + + if (z->state->sub.check.was != z->state->sub.check.need) + { + z->state->mode = BAD; + z->msg = (char*)"incorrect data check"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + Tracev((stderr, "inflate: zlib check ok\n")); + z->state->mode = DONE; + case DONE: + return Z_STREAM_END; + case BAD: + return Z_DATA_ERROR; + default: + return Z_STREAM_ERROR; + } +#ifdef NEED_DUMMY_RETURN + return Z_STREAM_ERROR; /* Some dumb compilers complain without this */ +#endif +} + diff --git a/mod/pub.mod/freetype.mod/src/gzip/inftrees.c b/mod/pub.mod/freetype.mod/src/gzip/inftrees.c new file mode 100644 index 0000000..ef53652 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/gzip/inftrees.c @@ -0,0 +1,468 @@ +/* inftrees.c -- generate Huffman trees for efficient decoding + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" + +#if !defined(BUILDFIXED) && !defined(STDC) +# define BUILDFIXED /* non ANSI compilers may not accept inffixed.h */ +#endif + + +#if 0 +local const char inflate_copyright[] = + " inflate 1.1.4 Copyright 1995-2002 Mark Adler "; +#endif +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* simplify the use of the inflate_huft type with some defines */ +#define exop word.what.Exop +#define bits word.what.Bits + + +local int huft_build OF(( + uIntf *, /* code lengths in bits */ + uInt, /* number of codes */ + uInt, /* number of "simple" codes */ + const uIntf *, /* list of base values for non-simple codes */ + const uIntf *, /* list of extra bits for non-simple codes */ + inflate_huft * FAR*,/* result: starting table */ + uIntf *, /* maximum lookup bits (returns actual) */ + inflate_huft *, /* space for trees */ + uInt *, /* hufts used in space */ + uIntf * )); /* space for values */ + +/* Tables for deflate from PKZIP's appnote.txt. */ +local const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; + /* see note #13 above about 258 */ +local const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */ + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, + 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */ +local const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577}; +local const uInt cpdext[30] = { /* Extra bits for distance codes */ + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, + 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, + 12, 12, 13, 13}; + +/* + Huffman code decoding is performed using a multi-level table lookup. + The fastest way to decode is to simply build a lookup table whose + size is determined by the longest code. However, the time it takes + to build this table can also be a factor if the data being decoded + is not very long. The most common codes are necessarily the + shortest codes, so those codes dominate the decoding time, and hence + the speed. The idea is you can have a shorter table that decodes the + shorter, more probable codes, and then point to subsidiary tables for + the longer codes. The time it costs to decode the longer codes is + then traded against the time it takes to make longer tables. + + This results of this trade are in the variables lbits and dbits + below. lbits is the number of bits the first level table for literal/ + length codes can decode in one step, and dbits is the same thing for + the distance codes. Subsequent tables are also less than or equal to + those sizes. These values may be adjusted either when all of the + codes are shorter than that, in which case the longest code length in + bits is used, or when the shortest code is *longer* than the requested + table size, in which case the length of the shortest code in bits is + used. + + There are two different values for the two tables, since they code a + different number of possibilities each. The literal/length table + codes 286 possible values, or in a flat code, a little over eight + bits. The distance table codes 30 possible values, or a little less + than five bits, flat. The optimum values for speed end up being + about one bit more than those, so lbits is 8+1 and dbits is 5+1. + The optimum values may differ though from machine to machine, and + possibly even between compilers. Your mileage may vary. + */ + + +/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */ +#define BMAX 15 /* maximum bit length of any code */ + +local int huft_build( /* b, n, s, d, e, t, m, hp, hn, v) */ +uIntf *b, /* code lengths in bits (all assumed <= BMAX) */ +uInt n, /* number of codes (assumed <= 288) */ +uInt s, /* number of simple-valued codes (0..s-1) */ +const uIntf *d, /* list of base values for non-simple codes */ +const uIntf *e, /* list of extra bits for non-simple codes */ +inflate_huft * FAR *t, /* result: starting table */ +uIntf *m, /* maximum lookup bits, returns actual */ +inflate_huft *hp, /* space for trees */ +uInt *hn, /* hufts used in space */ +uIntf *v /* working area: values in order of bit length */ +/* Given a list of code lengths and a maximum table size, make a set of + tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR + if the given code set is incomplete (the tables are still built in this + case), or Z_DATA_ERROR if the input is invalid. */ +) +{ + + uInt a; /* counter for codes of length k */ + uInt c[BMAX+1]; /* bit length count table */ + uInt f; /* i repeats in table every f entries */ + int g; /* maximum code length */ + int h; /* table level */ + register uInt i; /* counter, current code */ + register uInt j; /* counter */ + register int k; /* number of bits in current code */ + int l; /* bits per table (returned in m) */ + uInt mask; /* (1 << w) - 1, to avoid cc -O bug on HP */ + register uIntf *p; /* pointer into c[], b[], or v[] */ + inflate_huft *q; /* points to current table */ + struct inflate_huft_s r; /* table entry for structure assignment */ + inflate_huft *u[BMAX]; /* table stack */ + register int w; /* bits before this table == (l * h) */ + uInt x[BMAX+1]; /* bit offsets, then code stack */ + uIntf *xp; /* pointer into x */ + int y; /* number of dummy codes added */ + uInt z; /* number of entries in current table */ + + + /* Make compiler happy */ + r.base = 0; + + /* Generate counts for each bit length */ + p = c; +#define C0 *p++ = 0; +#define C2 C0 C0 C0 C0 +#define C4 C2 C2 C2 C2 + C4 /* clear c[]--assume BMAX+1 is 16 */ + p = b; i = n; + do { + c[*p++]++; /* assume all entries <= BMAX */ + } while (--i); + if (c[0] == n) /* null input--all zero length codes */ + { + *t = (inflate_huft *)Z_NULL; + *m = 0; + return Z_OK; + } + + + /* Find minimum and maximum length, bound *m by those */ + l = *m; + for (j = 1; j <= BMAX; j++) + if (c[j]) + break; + k = j; /* minimum code length */ + if ((uInt)l < j) + l = j; + for (i = BMAX; i; i--) + if (c[i]) + break; + g = i; /* maximum code length */ + if ((uInt)l > i) + l = i; + *m = l; + + + /* Adjust last length count to fill out codes, if needed */ + for (y = 1 << j; j < i; j++, y <<= 1) + if ((y -= c[j]) < 0) + return Z_DATA_ERROR; + if ((y -= c[i]) < 0) + return Z_DATA_ERROR; + c[i] += y; + + + /* Generate starting offsets into the value table for each length */ + x[1] = j = 0; + p = c + 1; xp = x + 2; + while (--i) { /* note that i == g from above */ + *xp++ = (j += *p++); + } + + + /* Make a table of values in order of bit lengths */ + p = b; i = 0; + do { + if ((j = *p++) != 0) + v[x[j]++] = i; + } while (++i < n); + n = x[g]; /* set n to length of v */ + + + /* Generate the Huffman codes and for each, make the table entries */ + x[0] = i = 0; /* first Huffman code is zero */ + p = v; /* grab values in bit order */ + h = -1; /* no tables yet--level -1 */ + w = -l; /* bits decoded == (l * h) */ + u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */ + q = (inflate_huft *)Z_NULL; /* ditto */ + z = 0; /* ditto */ + + /* go through the bit lengths (k already is bits in shortest code) */ + for (; k <= g; k++) + { + a = c[k]; + while (a--) + { + /* here i is the Huffman code of length k bits for value *p */ + /* make tables up to required level */ + while (k > w + l) + { + h++; + w += l; /* previous table always l bits */ + + /* compute minimum size table less than or equal to l bits */ + z = g - w; + z = z > (uInt)l ? (uInt)l : z; /* table size upper limit */ + if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ + { /* too few codes for k-w bit table */ + f -= a + 1; /* deduct codes from patterns left */ + xp = c + k; + if (j < z) + while (++j < z) /* try smaller tables up to z bits */ + { + if ((f <<= 1) <= *++xp) + break; /* enough codes to use up j bits */ + f -= *xp; /* else deduct codes from patterns */ + } + } + z = 1 << j; /* table entries for j-bit table */ + + /* allocate new table */ + if (*hn + z > MANY) /* (note: doesn't matter for fixed) */ + return Z_DATA_ERROR; /* overflow of MANY */ + u[h] = q = hp + *hn; + *hn += z; + + /* connect to last table, if there is one */ + if (h) + { + x[h] = i; /* save pattern for backing up */ + r.bits = (Byte)l; /* bits to dump before this table */ + r.exop = (Byte)j; /* bits in this table */ + j = i >> (w - l); + r.base = (uInt)(q - u[h-1] - j); /* offset to this table */ + u[h-1][j] = r; /* connect to last table */ + } + else + *t = q; /* first table is returned result */ + } + + /* set up table entry in r */ + r.bits = (Byte)(k - w); + if (p >= v + n) + r.exop = 128 + 64; /* out of values--invalid code */ + else if (*p < s) + { + r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */ + r.base = *p++; /* simple code is just the value */ + } + else + { + r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */ + r.base = d[*p++ - s]; + } + + /* fill code-like entries with r */ + f = 1 << (k - w); + for (j = i >> w; j < z; j += f) + q[j] = r; + + /* backwards increment the k-bit code i */ + for (j = 1 << (k - 1); i & j; j >>= 1) + i ^= j; + i ^= j; + + /* backup over finished tables */ + mask = (1 << w) - 1; /* needed on HP, cc -O bug */ + while ((i & mask) != x[h]) + { + h--; /* don't need to update q */ + w -= l; + mask = (1 << w) - 1; + } + } + } + + + /* Return Z_BUF_ERROR if we were given an incomplete table */ + return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; +} + + +local int inflate_trees_bits( /* c, bb, tb, hp, z) */ +uIntf *c, /* 19 code lengths */ +uIntf *bb, /* bits tree desired/actual depth */ +inflate_huft * FAR *tb, /* bits tree result */ +inflate_huft *hp, /* space for trees */ +z_streamp z /* for messages */ +) +{ + int r; + uInt hn = 0; /* hufts used in space */ + uIntf *v; /* work area for huft_build */ + + if ((v = (uIntf*)ZALLOC(z, 19, sizeof(uInt))) == Z_NULL) + return Z_MEM_ERROR; + r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL, + tb, bb, hp, &hn, v); + if (r == Z_DATA_ERROR) + z->msg = (char*)"oversubscribed dynamic bit lengths tree"; + else if (r == Z_BUF_ERROR || *bb == 0) + { + z->msg = (char*)"incomplete dynamic bit lengths tree"; + r = Z_DATA_ERROR; + } + ZFREE(z, v); + return r; +} + + +local int inflate_trees_dynamic( /* nl, nd, c, bl, bd, tl, td, hp, z) */ +uInt nl, /* number of literal/length codes */ +uInt nd, /* number of distance codes */ +uIntf *c, /* that many (total) code lengths */ +uIntf *bl, /* literal desired/actual bit depth */ +uIntf *bd, /* distance desired/actual bit depth */ +inflate_huft * FAR *tl, /* literal/length tree result */ +inflate_huft * FAR *td, /* distance tree result */ +inflate_huft *hp, /* space for trees */ +z_streamp z /* for messages */ +) +{ + int r; + uInt hn = 0; /* hufts used in space */ + uIntf *v; /* work area for huft_build */ + + /* allocate work area */ + if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL) + return Z_MEM_ERROR; + + /* build literal/length tree */ + r = huft_build(c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v); + if (r != Z_OK || *bl == 0) + { + if (r == Z_DATA_ERROR) + z->msg = (char*)"oversubscribed literal/length tree"; + else if (r != Z_MEM_ERROR) + { + z->msg = (char*)"incomplete literal/length tree"; + r = Z_DATA_ERROR; + } + ZFREE(z, v); + return r; + } + + /* build distance tree */ + r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v); + if (r != Z_OK || (*bd == 0 && nl > 257)) + { + if (r == Z_DATA_ERROR) + z->msg = (char*)"oversubscribed distance tree"; + else if (r == Z_BUF_ERROR) { +#if 0 + { +#endif +#ifdef PKZIP_BUG_WORKAROUND + r = Z_OK; + } +#else + z->msg = (char*)"incomplete distance tree"; + r = Z_DATA_ERROR; + } + else if (r != Z_MEM_ERROR) + { + z->msg = (char*)"empty distance tree with lengths"; + r = Z_DATA_ERROR; + } + ZFREE(z, v); + return r; +#endif + } + + /* done */ + ZFREE(z, v); + return Z_OK; +} + + +/* build fixed tables only once--keep them here */ +#ifdef BUILDFIXED +local int fixed_built = 0; +#define FIXEDH 544 /* number of hufts used by fixed tables */ +local inflate_huft fixed_mem[FIXEDH]; +local uInt fixed_bl; +local uInt fixed_bd; +local inflate_huft *fixed_tl; +local inflate_huft *fixed_td; +#else +#include "inffixed.h" +#endif + + +local int inflate_trees_fixed( /* bl, bd, tl, td, z) */ +uIntf *bl, /* literal desired/actual bit depth */ +uIntf *bd, /* distance desired/actual bit depth */ +const inflate_huft * FAR *tl, /* literal/length tree result */ +const inflate_huft * FAR *td, /* distance tree result */ +z_streamp z /* for memory allocation */ +) +{ +#ifdef BUILDFIXED + /* build fixed tables if not already */ + if (!fixed_built) + { + int k; /* temporary variable */ + uInt f = 0; /* number of hufts used in fixed_mem */ + uIntf *c; /* length list for huft_build */ + uIntf *v; /* work area for huft_build */ + + /* allocate memory */ + if ((c = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL) + return Z_MEM_ERROR; + if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL) + { + ZFREE(z, c); + return Z_MEM_ERROR; + } + + /* literal table */ + for (k = 0; k < 144; k++) + c[k] = 8; + for (; k < 256; k++) + c[k] = 9; + for (; k < 280; k++) + c[k] = 7; + for (; k < 288; k++) + c[k] = 8; + fixed_bl = 9; + huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl, + fixed_mem, &f, v); + + /* distance table */ + for (k = 0; k < 30; k++) + c[k] = 5; + fixed_bd = 5; + huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd, + fixed_mem, &f, v); + + /* done */ + ZFREE(z, v); + ZFREE(z, c); + fixed_built = 1; + } +#else + FT_UNUSED(z); +#endif + *bl = fixed_bl; + *bd = fixed_bd; + *tl = fixed_tl; + *td = fixed_td; + return Z_OK; +} diff --git a/mod/pub.mod/freetype.mod/src/gzip/inftrees.h b/mod/pub.mod/freetype.mod/src/gzip/inftrees.h new file mode 100644 index 0000000..07bf2aa --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/gzip/inftrees.h @@ -0,0 +1,63 @@ +/* inftrees.h -- header to use inftrees.c + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* Huffman code lookup table entry--this entry is four bytes for machines + that have 16-bit pointers (e.g. PC's in the small or medium model). */ + +#ifndef _INFTREES_H +#define _INFTREES_H + +typedef struct inflate_huft_s FAR inflate_huft; + +struct inflate_huft_s { + union { + struct { + Byte Exop; /* number of extra bits or operation */ + Byte Bits; /* number of bits in this code or subcode */ + } what; + uInt pad; /* pad structure to a power of 2 (4 bytes for */ + } word; /* 16-bit, 8 bytes for 32-bit int's) */ + uInt base; /* literal, length base, distance base, + or table offset */ +}; + +/* Maximum size of dynamic tree. The maximum found in a long but non- + exhaustive search was 1004 huft structures (850 for length/literals + and 154 for distances, the latter actually the result of an + exhaustive search). The actual maximum is not known, but the + value below is more than safe. */ +#define MANY 1440 + +local int inflate_trees_bits OF(( + uIntf *, /* 19 code lengths */ + uIntf *, /* bits tree desired/actual depth */ + inflate_huft * FAR *, /* bits tree result */ + inflate_huft *, /* space for trees */ + z_streamp)); /* for messages */ + +local int inflate_trees_dynamic OF(( + uInt, /* number of literal/length codes */ + uInt, /* number of distance codes */ + uIntf *, /* that many (total) code lengths */ + uIntf *, /* literal desired/actual bit depth */ + uIntf *, /* distance desired/actual bit depth */ + inflate_huft * FAR *, /* literal/length tree result */ + inflate_huft * FAR *, /* distance tree result */ + inflate_huft *, /* space for trees */ + z_streamp)); /* for messages */ + +local int inflate_trees_fixed OF(( + uIntf *, /* literal desired/actual bit depth */ + uIntf *, /* distance desired/actual bit depth */ + const inflate_huft * FAR *, /* literal/length tree result */ + const inflate_huft * FAR *, /* distance tree result */ + z_streamp)); /* for memory allocation */ + +#endif /* _INFTREES_H */ diff --git a/mod/pub.mod/freetype.mod/src/gzip/infutil.c b/mod/pub.mod/freetype.mod/src/gzip/infutil.c new file mode 100644 index 0000000..6087b40 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/gzip/infutil.c @@ -0,0 +1,86 @@ +/* inflate_util.c -- data and routines common to blocks and codes + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "infblock.h" +#include "inftrees.h" +#include "infcodes.h" +#include "infutil.h" + + +/* And'ing with mask[n] masks the lower n bits */ +local const uInt inflate_mask[17] = { + 0x0000, + 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, + 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff +}; + + +/* copy as much as possible from the sliding window to the output area */ +local int inflate_flush( /* s, z, r) */ +inflate_blocks_statef *s, +z_streamp z, +int r ) +{ + uInt n; + Bytef *p; + Bytef *q; + + /* local copies of source and destination pointers */ + p = z->next_out; + q = s->read; + + /* compute number of bytes to copy as far as end of window */ + n = (uInt)((q <= s->write ? s->write : s->end) - q); + if (n > z->avail_out) n = z->avail_out; + if (n && r == Z_BUF_ERROR) r = Z_OK; + + /* update counters */ + z->avail_out -= n; + z->total_out += n; + + /* update check information */ + if (s->checkfn != Z_NULL) + z->adler = s->check = (*s->checkfn)(s->check, q, n); + + /* copy as far as end of window */ + zmemcpy(p, q, n); + p += n; + q += n; + + /* see if more to copy at beginning of window */ + if (q == s->end) + { + /* wrap pointers */ + q = s->window; + if (s->write == s->end) + s->write = s->window; + + /* compute bytes to copy */ + n = (uInt)(s->write - q); + if (n > z->avail_out) n = z->avail_out; + if (n && r == Z_BUF_ERROR) r = Z_OK; + + /* update counters */ + z->avail_out -= n; + z->total_out += n; + + /* update check information */ + if (s->checkfn != Z_NULL) + z->adler = s->check = (*s->checkfn)(s->check, q, n); + + /* copy */ + zmemcpy(p, q, n); + p += n; + q += n; + } + + /* update pointers */ + z->next_out = p; + s->read = q; + + /* done */ + return r; +} diff --git a/mod/pub.mod/freetype.mod/src/gzip/infutil.h b/mod/pub.mod/freetype.mod/src/gzip/infutil.h new file mode 100644 index 0000000..7174b6d --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/gzip/infutil.h @@ -0,0 +1,98 @@ +/* infutil.h -- types and macros common to blocks and codes + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +#ifndef _INFUTIL_H +#define _INFUTIL_H + +typedef enum { + TYPE, /* get type bits (3, including end bit) */ + LENS, /* get lengths for stored */ + STORED, /* processing stored block */ + TABLE, /* get table lengths */ + BTREE, /* get bit lengths tree for a dynamic block */ + DTREE, /* get length, distance trees for a dynamic block */ + CODES, /* processing fixed or dynamic block */ + DRY, /* output remaining window bytes */ + DONE, /* finished last block, done */ + BAD} /* got a data error--stuck here */ +inflate_block_mode; + +/* inflate blocks semi-private state */ +struct inflate_blocks_state { + + /* mode */ + inflate_block_mode mode; /* current inflate_block mode */ + + /* mode dependent information */ + union { + uInt left; /* if STORED, bytes left to copy */ + struct { + uInt table; /* table lengths (14 bits) */ + uInt index; /* index into blens (or border) */ + uIntf *blens; /* bit lengths of codes */ + uInt bb; /* bit length tree depth */ + inflate_huft *tb; /* bit length decoding tree */ + } trees; /* if DTREE, decoding info for trees */ + struct { + inflate_codes_statef + *codes; + } decode; /* if CODES, current state */ + } sub; /* submode */ + uInt last; /* true if this block is the last block */ + + /* mode independent information */ + uInt bitk; /* bits in bit buffer */ + uLong bitb; /* bit buffer */ + inflate_huft *hufts; /* single malloc for tree space */ + Bytef *window; /* sliding window */ + Bytef *end; /* one byte after sliding window */ + Bytef *read; /* window read pointer */ + Bytef *write; /* window write pointer */ + check_func checkfn; /* check function */ + uLong check; /* check on output */ + +}; + + +/* defines for inflate input/output */ +/* update pointers and return */ +#define UPDBITS {s->bitb=b;s->bitk=k;} +#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;} +#define UPDOUT {s->write=q;} +#define UPDATE {UPDBITS UPDIN UPDOUT} +#define LEAVE {UPDATE return inflate_flush(s,z,r);} +/* get bytes and bits */ +#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;} +#define NEEDBYTE {if(n)r=Z_OK;else LEAVE} +#define NEXTBYTE (n--,*p++) +#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}} +#define DUMPBITS(j) {b>>=(j);k-=(j);} +/* output bytes */ +#define WAVAIL (uInt)(q<s->read?s->read-q-1:s->end-q) +#define LOADOUT {q=s->write;m=(uInt)WAVAIL;} +#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}} +#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT} +#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;} +#define OUTBYTE(a) {*q++=(Byte)(a);m--;} +/* load local pointers */ +#define LOAD {LOADIN LOADOUT} + +/* masks for lower bits (size given to avoid silly warnings with Visual C++) */ +#ifndef NO_INFLATE_MASK +local uInt inflate_mask[17]; +#endif + +/* copy as much as possible from the sliding window to the output area */ +local int inflate_flush OF(( + inflate_blocks_statef *, + z_streamp , + int)); + +#endif diff --git a/mod/pub.mod/freetype.mod/src/gzip/zconf.h b/mod/pub.mod/freetype.mod/src/gzip/zconf.h new file mode 100644 index 0000000..3abf0ba --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/gzip/zconf.h @@ -0,0 +1,284 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2002 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#ifndef _ZCONF_H +#define _ZCONF_H + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + */ +#ifdef Z_PREFIX +# define deflateInit_ z_deflateInit_ +# define deflate z_deflate +# define deflateEnd z_deflateEnd +# define inflateInit_ z_inflateInit_ +# define inflate z_inflate +# define inflateEnd z_inflateEnd +# define deflateInit2_ z_deflateInit2_ +# define deflateSetDictionary z_deflateSetDictionary +# define deflateCopy z_deflateCopy +# define deflateReset z_deflateReset +# define deflateParams z_deflateParams +# define inflateInit2_ z_inflateInit2_ +# define inflateSetDictionary z_inflateSetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateReset z_inflateReset +# define compress z_compress +# define compress2 z_compress2 +# define uncompress z_uncompress +# define adler32 z_adler32 +# define crc32 z_crc32 +# define get_crc_table z_get_crc_table + +# define Byte z_Byte +# define uInt z_uInt +# define uLong z_uLong +# define Bytef z_Bytef +# define charf z_charf +# define intf z_intf +# define uIntf z_uIntf +# define uLongf z_uLongf +# define voidpf z_voidpf +# define voidp z_voidp +#endif + +#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) +# define WIN32 +#endif +#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386) +# ifndef __32BIT__ +# define __32BIT__ +# endif +#endif +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif + +/* WinCE doesn't have errno.h */ +#ifdef _WIN32_WCE +# define NO_ERRNO_H +#endif + + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#if defined(MSDOS) && !defined(__32BIT__) +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32)) && !defined(STDC) +# define STDC +#endif +#if defined(__STDC__) || defined(__cplusplus) || defined(__OS2__) +# ifndef STDC +# define STDC +# endif +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const +# endif +#endif + +/* Some Mac compilers merge all .h files incorrectly: */ +#if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__) +# define NO_DUMMY_DECL +#endif + +/* Old Borland C and LCC incorrectly complains about missing returns: */ +#if defined(__BORLANDC__) && (__BORLANDC__ < 0x500) +# define NEED_DUMMY_RETURN +#endif + +#if defined(__LCC__) +# define NEED_DUMMY_RETURN +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +#endif +#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__)) +# ifndef __32BIT__ +# define SMALL_MEDIUM +# define FAR _far +# endif +#endif + +/* Compile with -DZLIB_DLL for Windows DLL support */ +#if defined(ZLIB_DLL) +# if defined(_WINDOWS) || defined(WINDOWS) +# ifdef FAR +# undef FAR +# endif +# include <windows.h> +# define ZEXPORT(x) x WINAPI +# ifdef WIN32 +# define ZEXPORTVA(x) x WINAPIV +# else +# define ZEXPORTVA(x) x FAR _cdecl _export +# endif +# endif +# if defined (__BORLANDC__) +# if (__BORLANDC__ >= 0x0500) && defined (WIN32) +# include <windows.h> +# define ZEXPORT(x) x __declspec(dllexport) WINAPI +# define ZEXPORTRVA(x) x __declspec(dllexport) WINAPIV +# else +# if defined (_Windows) && defined (__DLL__) +# define ZEXPORT(x) x _export +# define ZEXPORTVA(x) x _export +# endif +# endif +# endif +#endif + + +#ifndef ZEXPORT +# define ZEXPORT(x) static x +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA(x) static x +#endif +#ifndef ZEXTERN +# define ZEXTERN(x) static x +#endif +#ifndef ZEXTERNDEF +# define ZEXTERNDEF(x) static x +#endif + +#ifndef FAR +# define FAR +#endif + +#if !defined(MACOS) && !defined(TARGET_OS_MAC) +typedef unsigned char Byte; /* 8 bits */ +#endif +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +#ifdef HAVE_UNISTD_H +# include <sys/types.h> /* for off_t */ +# include <unistd.h> /* for SEEK_* and off_t */ +# define z_off_t off_t +#endif +#ifndef SEEK_SET +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif +#ifndef z_off_t +# define z_off_t long +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) +# pragma map(deflateInit_,"DEIN") +# pragma map(deflateInit2_,"DEIN2") +# pragma map(deflateEnd,"DEEND") +# pragma map(inflateInit_,"ININ") +# pragma map(inflateInit2_,"ININ2") +# pragma map(inflateEnd,"INEND") +# pragma map(inflateSync,"INSY") +# pragma map(inflateSetDictionary,"INSEDI") +# pragma map(inflate_blocks,"INBL") +# pragma map(inflate_blocks_new,"INBLNE") +# pragma map(inflate_blocks_free,"INBLFR") +# pragma map(inflate_blocks_reset,"INBLRE") +# pragma map(inflate_codes_free,"INCOFR") +# pragma map(inflate_codes,"INCO") +# pragma map(inflate_fast,"INFA") +# pragma map(inflate_flush,"INFLU") +# pragma map(inflate_mask,"INMA") +# pragma map(inflate_set_dictionary,"INSEDI2") +# pragma map(inflate_copyright,"INCOPY") +# pragma map(inflate_trees_bits,"INTRBI") +# pragma map(inflate_trees_dynamic,"INTRDY") +# pragma map(inflate_trees_fixed,"INTRFI") +# pragma map(inflate_trees_free,"INTRFR") +#endif + +#endif /* _ZCONF_H */ diff --git a/mod/pub.mod/freetype.mod/src/gzip/zlib.h b/mod/pub.mod/freetype.mod/src/gzip/zlib.h new file mode 100644 index 0000000..50d0d3f --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/gzip/zlib.h @@ -0,0 +1,830 @@ +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 1.1.4, March 11th, 2002 + + Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt + (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). +*/ + +#ifndef _ZLIB_H +#define _ZLIB_H + +#include "zconf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZLIB_VERSION "1.1.4" + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed + data. This version of the library supports only one compression method + (deflation) but other algorithms will be added later and will have the same + stream interface. + + Compression can be done in a single step if the buffers are large + enough (for example if an input file is mmap'ed), or can be done by + repeated calls of the compression function. In the latter case, the + application must provide more input and/or consume the output + (providing more output space) before each call. + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio. + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never + crash even in case of corrupted input. +*/ + +typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); +typedef void (*free_func) OF((voidpf opaque, voidpf address)); + +struct internal_state; + +typedef struct z_stream_s { + Bytef *next_in; /* next input byte */ + uInt avail_in; /* number of bytes available at next_in */ + uLong total_in; /* total nb of input bytes read so far */ + + Bytef *next_out; /* next output byte should be put there */ + uInt avail_out; /* remaining free space at next_out */ + uLong total_out; /* total nb of bytes output so far */ + + char *msg; /* last error message, NULL if no error */ + struct internal_state FAR *state; /* not visible by applications */ + + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + voidpf opaque; /* private data object passed to zalloc and zfree */ + + int data_type; /* best guess about the data type: ascii or binary */ + uLong adler; /* adler32 value of the uncompressed data */ + uLong reserved; /* reserved for future use */ +} z_stream; + +typedef z_stream FAR *z_streamp; + +/* + The application must update next_in and avail_in when avail_in has + dropped to zero. It must update next_out and avail_out when avail_out + has dropped to zero. The application must initialize zalloc, zfree and + opaque before calling the init function. All other fields are set by the + compression library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return Z_NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe. + + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this + if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, + pointers returned by zalloc for objects of exactly 65536 bytes *must* + have their offset normalized to zero. The default allocation function + provided by this library ensures this (see zutil.c). To reduce memory + requirements and avoid any allocation of 64K objects, at the expense of + compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). + + The fields total_in and total_out can be used for statistics or + progress reports. After compression, total_in holds the total size of + the uncompressed data and may be saved for use in the decompressor + (particularly if the decompressor wants to decompress everything in + a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +/* Allowed flush values; see deflate() below for details */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative + * values are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY 0 +#define Z_ASCII 1 +#define Z_UNKNOWN 2 +/* Possible values of the data_type field */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ + + + /* basic functions */ + +/* The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is + not compatible with the zlib.h header file used by the application. + This check is automatically made by deflateInit and inflateInit. + */ + +/* +ZEXTERN(int) deflateInit OF((z_streamp strm, int level)); + + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. + If zalloc and zfree are set to Z_NULL, deflateInit updates them to + use default allocation functions. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at + all (the input data is simply copied a block at a time). + Z_DEFAULT_COMPRESSION requests a default compromise between speed and + compression (currently equivalent to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if level is not a valid compression level, + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). + msg is set to null if there is no error message. deflateInit does not + perform any compression: this will be done by deflate(). +*/ + + +/* + deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce some + output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. deflate performs one or both of the + following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary (in interactive applications). + Some output may be provided even if flush is not set. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating avail_in or avail_out accordingly; avail_out + should never be zero before the call. The application can consume the + compressed output when it wants, for example when the output buffer is full + (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK + and with zero avail_out, it must be called again after making room in the + output buffer because there might be more output pending. + + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In particular + avail_in is zero after the call if enough output space has been provided + before the call.) Flushing may degrade compression for some compression + algorithms and so it should be used only when necessary. + + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + the compression. + + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there + was enough output space; if deflate returns with Z_OK, this function must be + called again with Z_FINISH and more output space (updated avail_out) but no + more input data, until it returns with Z_STREAM_END or an error. After + deflate has returned Z_STREAM_END, the only possible operations on the + stream are deflateReset or deflateEnd. + + Z_FINISH can be used immediately after deflateInit if all the compression + is to be done in a single step. In this case, avail_out must be at least + 0.1% larger than avail_in plus 12 bytes. If deflate does not return + Z_STREAM_END, then it must be called again as described above. + + deflate() sets strm->adler to the adler32 checksum of all input read + so far (that is, total_in bytes). + + deflate() may update data_type if it can make a good guess about + the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered + binary. This field is only for information purposes and does not affect + the compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible + (for example avail_in or avail_out was zero). +*/ + + +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, + msg may be set but then points to a static string (which must not be + deallocated). +*/ + + +/* +ZEXTERN(int) inflateInit OF((z_streamp strm)); + + Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. If next_in is not Z_NULL and avail_in is large enough (the exact + value depends on the compression method), inflateInit determines the + compression method from the zlib header and allocates all data structures + accordingly; otherwise the allocation will be deferred to the first call of + inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to + use default allocation functions. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller. msg is set to null if there is no error + message. inflateInit does not perform any decompression apart from reading + the zlib header if present: this will be done by inflate(). (So next_in and + avail_in may be modified, but next_out and avail_out are unchanged.) +*/ + + +ZEXTERN(int) inflate OF((z_streamp strm, int flush)); +/* + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may some + introduce some output latency (reading input without producing any output) + except when forced to flush. + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in is updated and processing + will resume at this point for the next call of inflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there + is no more input data or no more space in the output buffer (see below + about the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating the next_* and avail_* values accordingly. + The application can consume the uncompressed output when it wants, for + example when the output buffer is full (avail_out == 0), or after each + call of inflate(). If inflate returns Z_OK and with zero avail_out, it + must be called again after making room in the output buffer because there + might be more output pending. + + If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much + output as possible to the output buffer. The flushing behavior of inflate is + not specified for values of the flush parameter other than Z_SYNC_FLUSH + and Z_FINISH, but the current implementation actually flushes as much output + as possible anyway. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step + (a single call of inflate), the parameter flush should be set to + Z_FINISH. In this case all pending input is processed and all pending + output is flushed; avail_out must be large enough to hold all the + uncompressed data. (The size of the uncompressed data may have been saved + by the compressor for this purpose.) The next operation on this stream must + be inflateEnd to deallocate the decompression state. The use of Z_FINISH + is never required, but can be used to inform inflate that a faster routine + may be used for the single inflate() call. + + If a preset dictionary is needed at this point (see inflateSetDictionary + below), inflate sets strm-adler to the adler32 checksum of the + dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise + it sets strm->adler to the adler32 checksum of all output produced + so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or + an error code as described below. At the end of the stream, inflate() + checks that its computed adler32 checksum is equal to that saved by the + compressor and returns Z_STREAM_END only if the checksum is correct. + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect + adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent + (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if no progress is possible or if there was not + enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR + case, the application may then call inflateSync to look for a good + compression block. +*/ + + +ZEXTERN(int) inflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state + was inconsistent. In the error case, msg may be set but then points to a + static string (which must not be deallocated). +*/ + + /* Advanced functions */ + +/* + The following functions are needed only in some special applications. +*/ + +/* +ZEXTERN(int) deflateInit2 OF((z_streamp strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy)); + + This is another version of deflateInit with more compression options. The + fields next_in, zalloc, zfree and opaque must be initialized before by + the caller. + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead. + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but + is slow and reduces compression ratio; memLevel=9 uses maximum memory + for optimal speed. The default value is 8. See zconf.h for total memory + usage as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match). Filtered data consists mostly of small values with a + somewhat random distribution. In this case, the compression algorithm is + tuned to compress them better. The effect of Z_FILTERED is to force more + Huffman coding and less string matching; it is somewhat intermediate + between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects + the compression ratio but not the correctness of the compressed output even + if it is not set appropriately. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid + method). msg is set to null if there is no error message. deflateInit2 does + not perform any compression: this will be done by deflate(). +*/ + +/* + Initializes the compression dictionary from the given byte sequence + without producing any compressed output. This function must be called + immediately after deflateInit, deflateInit2 or deflateReset, before any + call of deflate. The compressor and decompressor must use exactly the same + dictionary (see inflateSetDictionary). + + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy; the data can then be compressed better than + with the default empty dictionary. + + Depending on the size of the compression data structures selected by + deflateInit or deflateInit2, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size in + deflate or deflate2. Thus the strings most likely to be useful should be + put at the end of the dictionary, not at the front. + + Upon return of this function, strm->adler is set to the Adler32 value + of the dictionary; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The Adler32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.) + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if the compression method is bsort). deflateSetDictionary does not + perform any compression: this will be done by deflate(). +*/ + +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and + can consume lots of memory. + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination. +*/ + +/* + This function is equivalent to deflateEnd followed by deflateInit, + but does not free and reallocate all the internal compression state. + The stream will keep the same compression level and any other attributes + that may have been set by deflateInit2. + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +/* + Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in deflateInit2. This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different + strategy. If the compression level is changed, the input available so far + is compressed with the old level (and may be flushed); the new level will + take effect only at the next call of deflate(). + + Before the call of deflateParams, the stream state must be set as for + a call of deflate(), since the currently available input may have to + be compressed and flushed. In particular, strm->avail_out must be non-zero. + + deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source + stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR + if strm->avail_out was zero. +*/ + +/* +ZEXTERN(int) inflateInit2 OF((z_streamp strm, + int windowBits)); + + This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. If a compressed stream with a larger window size is given as + input, inflate() will return with the error code Z_DATA_ERROR instead of + trying to allocate a larger window. + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative + memLevel). msg is set to null if there is no error message. inflateInit2 + does not perform any decompression apart from reading the zlib header if + present: this will be done by inflate(). (So next_in and avail_in may be + modified, but next_out and avail_out are unchanged.) +*/ + +/* + Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of inflate + if this call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the Adler32 value returned by this call of + inflate. The compressor and decompressor must use exactly the same + dictionary (see deflateSetDictionary). + + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect Adler32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate(). +*/ + +/* + Skips invalid compressed data until a full flush point (see above the + description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. + + inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR + if no more input was provided, Z_DATA_ERROR if no flush point has been found, + or Z_STREAM_ERROR if the stream structure was inconsistent. In the success + case, the application may save the current current value of total_in which + indicates where valid compressed data was found. In the error case, the + application may repeatedly call inflateSync, providing more input each time, + until success or end of the input data. +*/ + +ZEXTERN(int) inflateReset OF((z_streamp strm)); +/* + This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate all the internal decompression state. + The stream will keep attributes that may have been set by inflateInit2. + + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + + + /* utility functions */ + +/* + The following utility functions are implemented on top of the + basic stream-oriented functions. To simplify the interface, some + default options are assumed (compression level and memory usage, + standard memory allocation functions). The source code of these + utility functions can easily be modified if you need special options. +*/ + +/* + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be at least 0.1% larger than + sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the + compressed buffer. + This function can be used to compress a whole file at once if the + input file is mmap'ed. + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ + +/* + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least 0.1% larger than sourceLen plus + 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ + +/* + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be large enough to hold the + entire uncompressed data. (The size of the uncompressed data must have + been saved previously by the compressor and transmitted to the decompressor + by some mechanism outside the scope of this compression library.) + Upon exit, destLen is the actual size of the compressed buffer. + This function can be used to decompress a whole file at once if the + input file is mmap'ed. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted. +*/ + + +/* + Opens a gzip (.gz) file for reading or writing. The mode parameter + is as in fopen ("rb" or "wb") but can also include a compression level + ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for + Huffman only compression as in "wb1h". (See the description + of deflateInit2 for more information about the strategy parameter.) + + gzopen can be used to read a file which is not in gzip format; in this + case gzread will directly read from the file without decompression. + + gzopen returns NULL if the file could not be opened or if there was + insufficient memory to allocate the (de)compression state; errno + can be checked to distinguish the two cases (if errno is zero, the + zlib error is Z_MEM_ERROR). */ + +/* + gzdopen() associates a gzFile with the file descriptor fd. File + descriptors are obtained from calls like open, dup, creat, pipe or + fileno (in the file has been previously opened with fopen). + The mode parameter is as in gzopen. + The next call of gzclose on the returned gzFile will also close the + file descriptor fd, just like fclose(fdopen(fd), mode) closes the file + descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode). + gzdopen returns NULL if there was insufficient memory to allocate + the (de)compression state. +*/ + +/* + Dynamically update the compression level or strategy. See the description + of deflateInit2 for the meaning of these parameters. + gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not + opened for writing. +*/ + +/* + Reads the given number of uncompressed bytes from the compressed file. + If the input file was not in gzip format, gzread copies the given number + of bytes into the buffer. + gzread returns the number of uncompressed bytes actually read (0 for + end of file, -1 for error). */ + +/* + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of uncompressed bytes actually written + (0 in case of error). +*/ + +/* + Converts, formats, and writes the args to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written (0 in case of error). +*/ + +/* + Writes the given null-terminated string to the compressed file, excluding + the terminating null character. + gzputs returns the number of characters written, or -1 in case of error. +*/ + +/* + Reads bytes from the compressed file until len-1 characters are read, or + a newline character is read and transferred to buf, or an end-of-file + condition is encountered. The string is then terminated with a null + character. + gzgets returns buf, or Z_NULL in case of error. +*/ + +/* + Writes c, converted to an unsigned char, into the compressed file. + gzputc returns the value that was written, or -1 in case of error. +*/ + +/* + Reads one byte from the compressed file. gzgetc returns this byte + or -1 in case of end of file or error. +*/ + +/* + Flushes all pending output into the compressed file. The parameter + flush is as in the deflate() function. The return value is the zlib + error number (see function gzerror below). gzflush returns Z_OK if + the flush parameter is Z_FINISH and all output could be flushed. + gzflush should be called only when strictly necessary because it can + degrade compression. +*/ + +/* + Sets the starting position for the next gzread or gzwrite on the + given compressed file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); + the value SEEK_END is not supported. + If the file is opened for reading, this function is emulated but can be + extremely slow. If the file is opened for writing, only forward seeks are + supported; gzseek then compresses a sequence of zeroes up to the new + starting position. + + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error, in + particular if the file is opened for writing and the new starting position + would be before the current position. +*/ + +/* + Rewinds the given file. This function is supported only for reading. + + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) +*/ + +/* + Returns the starting position for the next gzread or gzwrite on the + given compressed file. This position represents a number of bytes in the + uncompressed data stream. + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +/* + Returns 1 when EOF has previously been detected reading the given + input stream, otherwise zero. +*/ + +/* + Flushes all pending output if necessary, closes the compressed file + and deallocates all the (de)compression state. The return value is the zlib + error number (see function gzerror below). +*/ + +/* + Returns the error message for the last error which occurred on the + given compressed file. errnum is set to zlib error number. If an + error occurred in the file system and not in the compression library, + errnum is set to Z_ERRNO and the application may consult errno + to get the exact error code. +*/ + + /* checksum functions */ + +/* + These functions are not related to compression but are exported + anyway because they might be useful in applications using the + compression library. +*/ + +ZEXTERN(uLong) adler32 OF((uLong adler, const Bytef *buf, uInt len)); + +/* + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. If buf is NULL, this function returns + the required initial value for the checksum. + An Adler-32 checksum is almost as reliable as a CRC32 but can be computed + much faster. Usage example: + + uLong adler = adler32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + adler = adler32(adler, buffer, length); + } + if (adler != original_adler) error(); +*/ + +/* + Update a running crc with the bytes buf[0..len-1] and return the updated + crc. If buf is NULL, this function returns the required initial value + for the crc. Pre- and post-conditioning (one's complement) is performed + within this function so it shouldn't be done by the application. + Usage example: + + uLong crc = crc32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = crc32(crc, buffer, length); + } + if (crc != original_crc) error(); +*/ + + + /* various hacks, don't look :) */ + +/* deflateInit and inflateInit are macros to allow checking the zlib version + * and the compiler's view of z_stream: + */ +ZEXTERN(int) inflateInit2_ OF((z_streamp strm, int windowBits, + const char *version, int stream_size)); +#define deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) +#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) + + +#ifdef __cplusplus +} +#endif + +#endif /* _ZLIB_H */ diff --git a/mod/pub.mod/freetype.mod/src/gzip/zutil.c b/mod/pub.mod/freetype.mod/src/gzip/zutil.c new file mode 100644 index 0000000..7ad0c1f --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/gzip/zutil.c @@ -0,0 +1,181 @@ +/* zutil.c -- target dependent utility functions for the compression library + * Copyright (C) 1995-2002 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#include "zutil.h" + +#ifndef STDC +extern void exit OF((int)); +#endif + + +#ifndef HAVE_MEMCPY + +void zmemcpy(dest, source, len) + Bytef* dest; + const Bytef* source; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = *source++; /* ??? to be unrolled */ + } while (--len != 0); +} + +int zmemcmp(s1, s2, len) + const Bytef* s1; + const Bytef* s2; + uInt len; +{ + uInt j; + + for (j = 0; j < len; j++) { + if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; + } + return 0; +} + +void zmemzero(dest, len) + Bytef* dest; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = 0; /* ??? to be unrolled */ + } while (--len != 0); +} +#endif + +#if defined( MSDOS ) && defined( __TURBOC__ ) && !defined( MY_ZCALLOC ) +#if (defined( __BORLANDC__) || !defined(SMALL_MEDIUM)) && !defined(__32BIT__) +/* Small and medium model in Turbo C are for now limited to near allocation + * with reduced MAX_WBITS and MAX_MEM_LEVEL + */ +# define MY_ZCALLOC + +/* Turbo C malloc() does not allow dynamic allocation of 64K bytes + * and farmalloc(64K) returns a pointer with an offset of 8, so we + * must fix the pointer. Warning: the pointer must be put back to its + * original form in order to free it, use zcfree(). + */ + +#define MAX_PTR 10 +/* 10*64K = 640K */ + +local int next_ptr = 0; + +typedef struct ptr_table_s { + voidpf org_ptr; + voidpf new_ptr; +} ptr_table; + +local ptr_table table[MAX_PTR]; +/* This table is used to remember the original form of pointers + * to large buffers (64K). Such pointers are normalized with a zero offset. + * Since MSDOS is not a preemptive multitasking OS, this table is not + * protected from concurrent access. This hack doesn't work anyway on + * a protected system like OS/2. Use Microsoft C instead. + */ + +voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) +{ + voidpf buf = opaque; /* just to make some compilers happy */ + ulg bsize = (ulg)items*size; + + /* If we allocate less than 65520 bytes, we assume that farmalloc + * will return a usable pointer which doesn't have to be normalized. + */ + if (bsize < 65520L) { + buf = farmalloc(bsize); + if (*(ush*)&buf != 0) return buf; + } else { + buf = farmalloc(bsize + 16L); + } + if (buf == NULL || next_ptr >= MAX_PTR) return NULL; + table[next_ptr].org_ptr = buf; + + /* Normalize the pointer to seg:0 */ + *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; + *(ush*)&buf = 0; + table[next_ptr++].new_ptr = buf; + return buf; +} + +void zcfree (voidpf opaque, voidpf ptr) +{ + int n; + if (*(ush*)&ptr != 0) { /* object < 64K */ + farfree(ptr); + return; + } + /* Find the original pointer */ + for (n = 0; n < next_ptr; n++) { + if (ptr != table[n].new_ptr) continue; + + farfree(table[n].org_ptr); + while (++n < next_ptr) { + table[n-1] = table[n]; + } + next_ptr--; + return; + } + ptr = opaque; /* just to make some compilers happy */ + Assert(0, "zcfree: ptr not found"); +} +#endif +#endif /* MSDOS && __TURBOC__ */ + + +#if defined(M_I86) && !defined(__32BIT__) && !defined( MY_ZCALLOC ) +/* Microsoft C in 16-bit mode */ + +# define MY_ZCALLOC + +#if (!defined(_MSC_VER) || (_MSC_VER <= 600)) +# define _halloc halloc +# define _hfree hfree +#endif + +voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) +{ + if (opaque) opaque = 0; /* to make compiler happy */ + return _halloc((long)items, size); +} + +void zcfree (voidpf opaque, voidpf ptr) +{ + if (opaque) opaque = 0; /* to make compiler happy */ + _hfree(ptr); +} + +#endif /* MSC */ + + +#ifndef MY_ZCALLOC /* Any system without a special alloc function */ + +#ifndef STDC +extern voidp ft_scalloc OF((uInt items, uInt size)); +extern void ft_sfree OF((voidpf ptr)); +#endif + +voidpf zcalloc (opaque, items, size) + voidpf opaque; + unsigned items; + unsigned size; +{ + if (opaque) items += size - size; /* make compiler happy */ + return (voidpf)ft_scalloc(items, size); +} + +void zcfree (opaque, ptr) + voidpf opaque; + voidpf ptr; +{ + ft_sfree(ptr); + if (opaque) return; /* make compiler happy */ +} + +#endif /* MY_ZCALLOC */ diff --git a/mod/pub.mod/freetype.mod/src/gzip/zutil.h b/mod/pub.mod/freetype.mod/src/gzip/zutil.h new file mode 100644 index 0000000..c9688cd --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/gzip/zutil.h @@ -0,0 +1,215 @@ +/* zutil.h -- internal interface and configuration of the compression library + * Copyright (C) 1995-2002 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id$ */ + +#ifndef _Z_UTIL_H +#define _Z_UTIL_H + +#include "zlib.h" + +#ifdef STDC +# include <stddef.h> +# include <string.h> +# include <stdlib.h> +#endif +#ifdef NO_ERRNO_H + extern int errno; +#else +# include <errno.h> +#endif + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +typedef unsigned char uch; +typedef uch FAR uchf; +typedef unsigned short ush; +typedef ush FAR ushf; +typedef unsigned long ulg; + + +#define ERR_RETURN(strm,err) \ + return (strm->msg = (char*)ERR_MSG(err), (err)) +/* To be used only when the state is known to be valid */ + + /* common constants */ + +#ifndef DEF_WBITS +# define DEF_WBITS MAX_WBITS +#endif +/* default windowBits for decompression. MAX_WBITS is for compression only */ + +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif +/* default memLevel */ + +#define STORED_BLOCK 0 +#define STATIC_TREES 1 +#define DYN_TREES 2 +/* The three kinds of block type */ + +#define MIN_MATCH 3 +#define MAX_MATCH 258 +/* The minimum and maximum match lengths */ + +#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ + + /* target dependencies */ + +#ifdef MSDOS +# define OS_CODE 0x00 +# if defined(__TURBOC__) || defined(__BORLANDC__) +# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) + /* Allow compilation with ANSI keywords only enabled */ + void _Cdecl farfree( void *block ); + void *_Cdecl farmalloc( unsigned long nbytes ); +# else +# include <alloc.h> +# endif +# else /* MSC or DJGPP */ +# endif +#endif + +#ifdef OS2 +# define OS_CODE 0x06 +#endif + +#ifdef WIN32 /* Window 95 & Windows NT */ +# define OS_CODE 0x0b +#endif + +#if defined(VAXC) || defined(VMS) +# define OS_CODE 0x02 +# define F_OPEN(name, mode) \ + ft_fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") +#endif + +#ifdef AMIGA +# define OS_CODE 0x01 +#endif + +#if defined(ATARI) || defined(atarist) +# define OS_CODE 0x05 +#endif + +#if defined(MACOS) || defined(TARGET_OS_MAC) +# define OS_CODE 0x07 +# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os +# include <unix.h> /* for fdopen */ +# else +# ifndef fdopen +# define fdopen(fd,mode) NULL /* No fdopen() */ +# endif +# endif +#endif + +#ifdef __50SERIES /* Prime/PRIMOS */ +# define OS_CODE 0x0F +#endif + +#ifdef TOPS20 +# define OS_CODE 0x0a +#endif + +#if defined(_BEOS_) || defined(RISCOS) +# define fdopen(fd,mode) NULL /* No fdopen() */ +#endif + +#if (defined(_MSC_VER) && (_MSC_VER > 600)) +# define fdopen(fd,type) _fdopen(fd,type) +#endif + + + /* Common defaults */ + +#ifndef OS_CODE +# define OS_CODE 0x03 /* assume Unix */ +#endif + +#ifndef F_OPEN +# define F_OPEN(name, mode) ft_fopen((name), (mode)) +#endif + + /* functions */ + +#ifdef HAVE_STRERROR + extern char *strerror OF((int)); +# define zstrerror(errnum) strerror(errnum) +#else +# define zstrerror(errnum) "" +#endif + +#if defined(pyr) +# define NO_MEMCPY +#endif +#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) + /* Use our own functions for small and medium model with MSC <= 5.0. + * You may have to use the same strategy for Borland C (untested). + * The __SC__ check is for Symantec. + */ +# define NO_MEMCPY +#endif +#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) +# define HAVE_MEMCPY +#endif +#ifdef HAVE_MEMCPY +# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ +# define zmemcpy _fmemcpy +# define zmemcmp _fmemcmp +# define zmemzero(dest, len) _fmemset(dest, 0, len) +# else +# define zmemcpy ft_memcpy +# define zmemcmp ft_memcmp +# define zmemzero(dest, len) ft_memset(dest, 0, len) +# endif +#else + extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); + extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); + extern void zmemzero OF((Bytef* dest, uInt len)); +#endif + +/* Diagnostic functions */ +#ifdef DEBUG +# include <stdio.h> + extern int z_verbose; + extern void z_error OF((char *m)); +# define Assert(cond,msg) {if(!(cond)) z_error(msg);} +# define Trace(x) {if (z_verbose>=0) fprintf x ;} +# define Tracev(x) {if (z_verbose>0) fprintf x ;} +# define Tracevv(x) {if (z_verbose>1) fprintf x ;} +# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} +# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} +#else +# define Assert(cond,msg) +# define Trace(x) +# define Tracev(x) +# define Tracevv(x) +# define Tracec(c,x) +# define Tracecv(c,x) +#endif + + +typedef uLong (*check_func) OF((uLong check, const Bytef *buf, + uInt len)); +local voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); +local void zcfree OF((voidpf opaque, voidpf ptr)); + +#define ZALLOC(strm, items, size) \ + (*((strm)->zalloc))((strm)->opaque, (items), (size)) +#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) +#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} + +#endif /* _Z_UTIL_H */ diff --git a/mod/pub.mod/freetype.mod/src/lzw/ftlzw.c b/mod/pub.mod/freetype.mod/src/lzw/ftlzw.c new file mode 100644 index 0000000..4f601a1 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/lzw/ftlzw.c @@ -0,0 +1,416 @@ +/***************************************************************************/ +/* */ +/* ftlzw.c */ +/* */ +/* FreeType support for .Z compressed files. */ +/* */ +/* This optional component relies on NetBSD's zopen(). It should mainly */ +/* be used to parse compressed PCF fonts, as found with many X11 server */ +/* distributions. */ +/* */ +/* Copyright 2004, 2005, 2006, 2009 by */ +/* Albert Chin-A-Young. */ +/* */ +/* Based on code in src/gzip/ftgzip.c, Copyright 2004 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + +#include <ft2build.h> +#include FT_INTERNAL_MEMORY_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_DEBUG_H +#include FT_LZW_H +#include FT_CONFIG_STANDARD_LIBRARY_H + + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#define FT_ERR_PREFIX LZW_Err_ +#define FT_ERR_BASE FT_Mod_Err_LZW + +#include FT_ERRORS_H + + +#ifdef FT_CONFIG_OPTION_USE_LZW + +#ifdef FT_CONFIG_OPTION_PIC +#error "lzw code does not support PIC yet" +#endif + +#include "ftzopen.h" + + +/***************************************************************************/ +/***************************************************************************/ +/***** *****/ +/***** M E M O R Y M A N A G E M E N T *****/ +/***** *****/ +/***************************************************************************/ +/***************************************************************************/ + +/***************************************************************************/ +/***************************************************************************/ +/***** *****/ +/***** F I L E D E S C R I P T O R *****/ +/***** *****/ +/***************************************************************************/ +/***************************************************************************/ + +#define FT_LZW_BUFFER_SIZE 4096 + + typedef struct FT_LZWFileRec_ + { + FT_Stream source; /* parent/source stream */ + FT_Stream stream; /* embedding stream */ + FT_Memory memory; /* memory allocator */ + FT_LzwStateRec lzw; /* lzw decompressor state */ + + FT_Byte buffer[FT_LZW_BUFFER_SIZE]; /* output buffer */ + FT_ULong pos; /* position in output */ + FT_Byte* cursor; + FT_Byte* limit; + + } FT_LZWFileRec, *FT_LZWFile; + + + /* check and skip .Z header */ + static FT_Error + ft_lzw_check_header( FT_Stream stream ) + { + FT_Error error; + FT_Byte head[2]; + + + if ( FT_STREAM_SEEK( 0 ) || + FT_STREAM_READ( head, 2 ) ) + goto Exit; + + /* head[0] && head[1] are the magic numbers */ + if ( head[0] != 0x1f || + head[1] != 0x9d ) + error = LZW_Err_Invalid_File_Format; + + Exit: + return error; + } + + + static FT_Error + ft_lzw_file_init( FT_LZWFile zip, + FT_Stream stream, + FT_Stream source ) + { + FT_LzwState lzw = &zip->lzw; + FT_Error error = LZW_Err_Ok; + + + zip->stream = stream; + zip->source = source; + zip->memory = stream->memory; + + zip->limit = zip->buffer + FT_LZW_BUFFER_SIZE; + zip->cursor = zip->limit; + zip->pos = 0; + + /* check and skip .Z header */ + { + stream = source; + + error = ft_lzw_check_header( source ); + if ( error ) + goto Exit; + } + + /* initialize internal lzw variable */ + ft_lzwstate_init( lzw, source ); + + Exit: + return error; + } + + + static void + ft_lzw_file_done( FT_LZWFile zip ) + { + /* clear the rest */ + ft_lzwstate_done( &zip->lzw ); + + zip->memory = NULL; + zip->source = NULL; + zip->stream = NULL; + } + + + static FT_Error + ft_lzw_file_reset( FT_LZWFile zip ) + { + FT_Stream stream = zip->source; + FT_Error error; + + + if ( !FT_STREAM_SEEK( 0 ) ) + { + ft_lzwstate_reset( &zip->lzw ); + + zip->limit = zip->buffer + FT_LZW_BUFFER_SIZE; + zip->cursor = zip->limit; + zip->pos = 0; + } + + return error; + } + + + static FT_Error + ft_lzw_file_fill_output( FT_LZWFile zip ) + { + FT_LzwState lzw = &zip->lzw; + FT_ULong count; + FT_Error error = 0; + + + zip->cursor = zip->buffer; + + count = ft_lzwstate_io( lzw, zip->buffer, FT_LZW_BUFFER_SIZE ); + + zip->limit = zip->cursor + count; + + if ( count == 0 ) + error = LZW_Err_Invalid_Stream_Operation; + + return error; + } + + + /* fill output buffer; `count' must be <= FT_LZW_BUFFER_SIZE */ + static FT_Error + ft_lzw_file_skip_output( FT_LZWFile zip, + FT_ULong count ) + { + FT_Error error = LZW_Err_Ok; + + + /* first, we skip what we can from the output buffer */ + { + FT_ULong delta = (FT_ULong)( zip->limit - zip->cursor ); + + + if ( delta >= count ) + delta = count; + + zip->cursor += delta; + zip->pos += delta; + + count -= delta; + } + + /* next, we skip as many bytes remaining as possible */ + while ( count > 0 ) + { + FT_ULong delta = FT_LZW_BUFFER_SIZE; + FT_ULong numread; + + + if ( delta > count ) + delta = count; + + numread = ft_lzwstate_io( &zip->lzw, NULL, delta ); + if ( numread < delta ) + { + /* not enough bytes */ + error = LZW_Err_Invalid_Stream_Operation; + break; + } + + zip->pos += delta; + count -= delta; + } + + return error; + } + + + static FT_ULong + ft_lzw_file_io( FT_LZWFile zip, + FT_ULong pos, + FT_Byte* buffer, + FT_ULong count ) + { + FT_ULong result = 0; + FT_Error error; + + + /* seeking backwards. */ + if ( pos < zip->pos ) + { + /* If the new position is within the output buffer, simply */ + /* decrement pointers, otherwise we reset the stream completely! */ + if ( ( zip->pos - pos ) <= (FT_ULong)( zip->cursor - zip->buffer ) ) + { + zip->cursor -= zip->pos - pos; + zip->pos = pos; + } + else + { + error = ft_lzw_file_reset( zip ); + if ( error ) + goto Exit; + } + } + + /* skip unwanted bytes */ + if ( pos > zip->pos ) + { + error = ft_lzw_file_skip_output( zip, (FT_ULong)( pos - zip->pos ) ); + if ( error ) + goto Exit; + } + + if ( count == 0 ) + goto Exit; + + /* now read the data */ + for (;;) + { + FT_ULong delta; + + + delta = (FT_ULong)( zip->limit - zip->cursor ); + if ( delta >= count ) + delta = count; + + FT_MEM_COPY( buffer + result, zip->cursor, delta ); + result += delta; + zip->cursor += delta; + zip->pos += delta; + + count -= delta; + if ( count == 0 ) + break; + + error = ft_lzw_file_fill_output( zip ); + if ( error ) + break; + } + + Exit: + return result; + } + + +/***************************************************************************/ +/***************************************************************************/ +/***** *****/ +/***** L Z W E M B E D D I N G S T R E A M *****/ +/***** *****/ +/***************************************************************************/ +/***************************************************************************/ + + static void + ft_lzw_stream_close( FT_Stream stream ) + { + FT_LZWFile zip = (FT_LZWFile)stream->descriptor.pointer; + FT_Memory memory = stream->memory; + + + if ( zip ) + { + /* finalize lzw file descriptor */ + ft_lzw_file_done( zip ); + + FT_FREE( zip ); + + stream->descriptor.pointer = NULL; + } + } + + + static FT_ULong + ft_lzw_stream_io( FT_Stream stream, + FT_ULong pos, + FT_Byte* buffer, + FT_ULong count ) + { + FT_LZWFile zip = (FT_LZWFile)stream->descriptor.pointer; + + + return ft_lzw_file_io( zip, pos, buffer, count ); + } + + + FT_EXPORT_DEF( FT_Error ) + FT_Stream_OpenLZW( FT_Stream stream, + FT_Stream source ) + { + FT_Error error; + FT_Memory memory = source->memory; + FT_LZWFile zip; + + + /* + * Check the header right now; this prevents allocation of a huge + * LZWFile object (400 KByte of heap memory) if not necessary. + * + * Did I mention that you should never use .Z compressed font + * files? + */ + error = ft_lzw_check_header( source ); + if ( error ) + goto Exit; + + FT_ZERO( stream ); + stream->memory = memory; + + if ( !FT_NEW( zip ) ) + { + error = ft_lzw_file_init( zip, stream, source ); + if ( error ) + { + FT_FREE( zip ); + goto Exit; + } + + stream->descriptor.pointer = zip; + } + + stream->size = 0x7FFFFFFFL; /* don't know the real size! */ + stream->pos = 0; + stream->base = 0; + stream->read = ft_lzw_stream_io; + stream->close = ft_lzw_stream_close; + + Exit: + return error; + } + + +#include "ftzopen.c" + + +#else /* !FT_CONFIG_OPTION_USE_LZW */ + + + FT_EXPORT_DEF( FT_Error ) + FT_Stream_OpenLZW( FT_Stream stream, + FT_Stream source ) + { + FT_UNUSED( stream ); + FT_UNUSED( source ); + + return LZW_Err_Unimplemented_Feature; + } + + +#endif /* !FT_CONFIG_OPTION_USE_LZW */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/lzw/ftzopen.c b/mod/pub.mod/freetype.mod/src/lzw/ftzopen.c new file mode 100644 index 0000000..8bc65c8 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/lzw/ftzopen.c @@ -0,0 +1,401 @@ +/***************************************************************************/ +/* */ +/* ftzopen.c */ +/* */ +/* FreeType support for .Z compressed files. */ +/* */ +/* This optional component relies on NetBSD's zopen(). It should mainly */ +/* be used to parse compressed PCF fonts, as found with many X11 server */ +/* distributions. */ +/* */ +/* Copyright 2005, 2006, 2007, 2009 by David Turner. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + +#include "ftzopen.h" +#include FT_INTERNAL_MEMORY_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_DEBUG_H + + + static int + ft_lzwstate_refill( FT_LzwState state ) + { + FT_ULong count; + + + if ( state->in_eof ) + return -1; + + count = FT_Stream_TryRead( state->source, + state->buf_tab, + state->num_bits ); /* WHY? */ + + state->buf_size = (FT_UInt)count; + state->buf_total += count; + state->in_eof = FT_BOOL( count < state->num_bits ); + state->buf_offset = 0; + state->buf_size = ( state->buf_size << 3 ) - ( state->num_bits - 1 ); + + if ( count == 0 ) /* end of file */ + return -1; + + return 0; + } + + + static FT_Int32 + ft_lzwstate_get_code( FT_LzwState state ) + { + FT_UInt num_bits = state->num_bits; + FT_Int offset = state->buf_offset; + FT_Byte* p; + FT_Int result; + + + if ( state->buf_clear || + offset >= state->buf_size || + state->free_ent >= state->free_bits ) + { + if ( state->free_ent >= state->free_bits ) + { + state->num_bits = ++num_bits; + state->free_bits = state->num_bits < state->max_bits + ? (FT_UInt)( ( 1UL << num_bits ) - 256 ) + : state->max_free + 1; + } + + if ( state->buf_clear ) + { + state->num_bits = num_bits = LZW_INIT_BITS; + state->free_bits = (FT_UInt)( ( 1UL << num_bits ) - 256 ); + state->buf_clear = 0; + } + + if ( ft_lzwstate_refill( state ) < 0 ) + return -1; + + offset = 0; + } + + state->buf_offset = offset + num_bits; + + p = &state->buf_tab[offset >> 3]; + offset &= 7; + result = *p++ >> offset; + offset = 8 - offset; + num_bits -= offset; + + if ( num_bits >= 8 ) + { + result |= *p++ << offset; + offset += 8; + num_bits -= 8; + } + if ( num_bits > 0 ) + result |= ( *p & LZW_MASK( num_bits ) ) << offset; + + return result; + } + + + /* grow the character stack */ + static int + ft_lzwstate_stack_grow( FT_LzwState state ) + { + if ( state->stack_top >= state->stack_size ) + { + FT_Memory memory = state->memory; + FT_Error error; + FT_Offset old_size = state->stack_size; + FT_Offset new_size = old_size; + + new_size = new_size + ( new_size >> 1 ) + 4; + + if ( state->stack == state->stack_0 ) + { + state->stack = NULL; + old_size = 0; + } + + if ( FT_RENEW_ARRAY( state->stack, old_size, new_size ) ) + return -1; + + state->stack_size = new_size; + } + return 0; + } + + + /* grow the prefix/suffix arrays */ + static int + ft_lzwstate_prefix_grow( FT_LzwState state ) + { + FT_UInt old_size = state->prefix_size; + FT_UInt new_size = old_size; + FT_Memory memory = state->memory; + FT_Error error; + + + if ( new_size == 0 ) /* first allocation -> 9 bits */ + new_size = 512; + else + new_size += new_size >> 2; /* don't grow too fast */ + + /* + * Note that the `suffix' array is located in the same memory block + * pointed to by `prefix'. + * + * I know that sizeof(FT_Byte) == 1 by definition, but it is clearer + * to write it literally. + * + */ + if ( FT_REALLOC_MULT( state->prefix, old_size, new_size, + sizeof ( FT_UShort ) + sizeof ( FT_Byte ) ) ) + return -1; + + /* now adjust `suffix' and move the data accordingly */ + state->suffix = (FT_Byte*)( state->prefix + new_size ); + + FT_MEM_MOVE( state->suffix, + state->prefix + old_size, + old_size * sizeof ( FT_Byte ) ); + + state->prefix_size = new_size; + return 0; + } + + + FT_LOCAL_DEF( void ) + ft_lzwstate_reset( FT_LzwState state ) + { + state->in_eof = 0; + state->buf_offset = 0; + state->buf_size = 0; + state->buf_clear = 0; + state->buf_total = 0; + state->stack_top = 0; + state->num_bits = LZW_INIT_BITS; + state->phase = FT_LZW_PHASE_START; + } + + + FT_LOCAL_DEF( void ) + ft_lzwstate_init( FT_LzwState state, + FT_Stream source ) + { + FT_ZERO( state ); + + state->source = source; + state->memory = source->memory; + + state->prefix = NULL; + state->suffix = NULL; + state->prefix_size = 0; + + state->stack = state->stack_0; + state->stack_size = sizeof ( state->stack_0 ); + + ft_lzwstate_reset( state ); + } + + + FT_LOCAL_DEF( void ) + ft_lzwstate_done( FT_LzwState state ) + { + FT_Memory memory = state->memory; + + + ft_lzwstate_reset( state ); + + if ( state->stack != state->stack_0 ) + FT_FREE( state->stack ); + + FT_FREE( state->prefix ); + state->suffix = NULL; + + FT_ZERO( state ); + } + + +#define FTLZW_STACK_PUSH( c ) \ + FT_BEGIN_STMNT \ + if ( state->stack_top >= state->stack_size && \ + ft_lzwstate_stack_grow( state ) < 0 ) \ + goto Eof; \ + \ + state->stack[state->stack_top++] = (FT_Byte)(c); \ + FT_END_STMNT + + + FT_LOCAL_DEF( FT_ULong ) + ft_lzwstate_io( FT_LzwState state, + FT_Byte* buffer, + FT_ULong out_size ) + { + FT_ULong result = 0; + + FT_UInt old_char = state->old_char; + FT_UInt old_code = state->old_code; + FT_UInt in_code = state->in_code; + + + if ( out_size == 0 ) + goto Exit; + + switch ( state->phase ) + { + case FT_LZW_PHASE_START: + { + FT_Byte max_bits; + FT_Int32 c; + + + /* skip magic bytes, and read max_bits + block_flag */ + if ( FT_Stream_Seek( state->source, 2 ) != 0 || + FT_Stream_TryRead( state->source, &max_bits, 1 ) != 1 ) + goto Eof; + + state->max_bits = max_bits & LZW_BIT_MASK; + state->block_mode = max_bits & LZW_BLOCK_MASK; + state->max_free = (FT_UInt)( ( 1UL << state->max_bits ) - 256 ); + + if ( state->max_bits > LZW_MAX_BITS ) + goto Eof; + + state->num_bits = LZW_INIT_BITS; + state->free_ent = ( state->block_mode ? LZW_FIRST + : LZW_CLEAR ) - 256; + in_code = 0; + + state->free_bits = state->num_bits < state->max_bits + ? (FT_UInt)( ( 1UL << state->num_bits ) - 256 ) + : state->max_free + 1; + + c = ft_lzwstate_get_code( state ); + if ( c < 0 ) + goto Eof; + + old_code = old_char = (FT_UInt)c; + + if ( buffer ) + buffer[result] = (FT_Byte)old_char; + + if ( ++result >= out_size ) + goto Exit; + + state->phase = FT_LZW_PHASE_CODE; + } + /* fall-through */ + + case FT_LZW_PHASE_CODE: + { + FT_Int32 c; + FT_UInt code; + + + NextCode: + c = ft_lzwstate_get_code( state ); + if ( c < 0 ) + goto Eof; + + code = (FT_UInt)c; + + if ( code == LZW_CLEAR && state->block_mode ) + { + /* why not LZW_FIRST-256 ? */ + state->free_ent = ( LZW_FIRST - 1 ) - 256; + state->buf_clear = 1; + c = ft_lzwstate_get_code( state ); + if ( c < 0 ) + goto Eof; + + code = (FT_UInt)c; + } + + in_code = code; /* save code for later */ + + if ( code >= 256U ) + { + /* special case for KwKwKwK */ + if ( code - 256U >= state->free_ent ) + { + FTLZW_STACK_PUSH( old_char ); + code = old_code; + } + + while ( code >= 256U ) + { + if ( !state->prefix ) + goto Eof; + + FTLZW_STACK_PUSH( state->suffix[code - 256] ); + code = state->prefix[code - 256]; + } + } + + old_char = code; + FTLZW_STACK_PUSH( old_char ); + + state->phase = FT_LZW_PHASE_STACK; + } + /* fall-through */ + + case FT_LZW_PHASE_STACK: + { + while ( state->stack_top > 0 ) + { + --state->stack_top; + + if ( buffer ) + buffer[result] = state->stack[state->stack_top]; + + if ( ++result == out_size ) + goto Exit; + } + + /* now create new entry */ + if ( state->free_ent < state->max_free ) + { + if ( state->free_ent >= state->prefix_size && + ft_lzwstate_prefix_grow( state ) < 0 ) + goto Eof; + + FT_ASSERT( state->free_ent < state->prefix_size ); + + state->prefix[state->free_ent] = (FT_UShort)old_code; + state->suffix[state->free_ent] = (FT_Byte) old_char; + + state->free_ent += 1; + } + + old_code = in_code; + + state->phase = FT_LZW_PHASE_CODE; + goto NextCode; + } + + default: /* state == EOF */ + ; + } + + Exit: + state->old_code = old_code; + state->old_char = old_char; + state->in_code = in_code; + + return result; + + Eof: + state->phase = FT_LZW_PHASE_EOF; + goto Exit; + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/lzw/ftzopen.h b/mod/pub.mod/freetype.mod/src/lzw/ftzopen.h new file mode 100644 index 0000000..f7d2936 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/lzw/ftzopen.h @@ -0,0 +1,171 @@ +/***************************************************************************/ +/* */ +/* ftzopen.h */ +/* */ +/* FreeType support for .Z compressed files. */ +/* */ +/* This optional component relies on NetBSD's zopen(). It should mainly */ +/* be used to parse compressed PCF fonts, as found with many X11 server */ +/* distributions. */ +/* */ +/* Copyright 2005, 2006, 2007, 2008 by David Turner. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + +#ifndef __FT_ZOPEN_H__ +#define __FT_ZOPEN_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + + + /* + * This is a complete re-implementation of the LZW file reader, + * since the old one was incredibly badly written, using + * 400 KByte of heap memory before decompressing anything. + * + */ + +#define FT_LZW_IN_BUFF_SIZE 64 +#define FT_LZW_DEFAULT_STACK_SIZE 64 + +#define LZW_INIT_BITS 9 +#define LZW_MAX_BITS 16 + +#define LZW_CLEAR 256 +#define LZW_FIRST 257 + +#define LZW_BIT_MASK 0x1f +#define LZW_BLOCK_MASK 0x80 +#define LZW_MASK( n ) ( ( 1U << (n) ) - 1U ) + + + typedef enum FT_LzwPhase_ + { + FT_LZW_PHASE_START = 0, + FT_LZW_PHASE_CODE, + FT_LZW_PHASE_STACK, + FT_LZW_PHASE_EOF + + } FT_LzwPhase; + + + /* + * state of LZW decompressor + * + * small technical note + * -------------------- + * + * We use a few tricks in this implementation that are explained here to + * ease debugging and maintenance. + * + * - First of all, the `prefix' and `suffix' arrays contain the suffix + * and prefix for codes over 256; this means that + * + * prefix_of(code) == state->prefix[code-256] + * suffix_of(code) == state->suffix[code-256] + * + * Each prefix is a 16-bit code, and each suffix an 8-bit byte. + * + * Both arrays are stored in a single memory block, pointed to by + * `state->prefix'. This means that the following equality is always + * true: + * + * state->suffix == (FT_Byte*)(state->prefix + state->prefix_size) + * + * Of course, state->prefix_size is the number of prefix/suffix slots + * in the arrays, corresponding to codes 256..255+prefix_size. + * + * - `free_ent' is the index of the next free entry in the `prefix' + * and `suffix' arrays. This means that the corresponding `next free + * code' is really `256+free_ent'. + * + * Moreover, `max_free' is the maximum value that `free_ent' can reach. + * + * `max_free' corresponds to `(1 << max_bits) - 256'. Note that this + * value is always <= 0xFF00, which means that both `free_ent' and + * `max_free' can be stored in an FT_UInt variable, even on 16-bit + * machines. + * + * If `free_ent == max_free', you cannot add new codes to the + * prefix/suffix table. + * + * - `num_bits' is the current number of code bits, starting at 9 and + * growing each time `free_ent' reaches the value of `free_bits'. The + * latter is computed as follows + * + * if num_bits < max_bits: + * free_bits = (1 << num_bits)-256 + * else: + * free_bits = max_free + 1 + * + * Since the value of `max_free + 1' can never be reached by + * `free_ent', `num_bits' cannot grow larger than `max_bits'. + */ + + typedef struct FT_LzwStateRec_ + { + FT_LzwPhase phase; + FT_Int in_eof; + + FT_Byte buf_tab[16]; + FT_Int buf_offset; + FT_Int buf_size; + FT_Bool buf_clear; + FT_Offset buf_total; + + FT_UInt max_bits; /* max code bits, from file header */ + FT_Int block_mode; /* block mode flag, from file header */ + FT_UInt max_free; /* (1 << max_bits) - 256 */ + + FT_UInt num_bits; /* current code bit number */ + FT_UInt free_ent; /* index of next free entry */ + FT_UInt free_bits; /* if reached by free_ent, increment num_bits */ + FT_UInt old_code; + FT_UInt old_char; + FT_UInt in_code; + + FT_UShort* prefix; /* always dynamically allocated / reallocated */ + FT_Byte* suffix; /* suffix = (FT_Byte*)(prefix + prefix_size) */ + FT_UInt prefix_size; /* number of slots in `prefix' or `suffix' */ + + FT_Byte* stack; /* character stack */ + FT_UInt stack_top; + FT_Offset stack_size; + FT_Byte stack_0[FT_LZW_DEFAULT_STACK_SIZE]; /* minimize heap alloc */ + + FT_Stream source; /* source stream */ + FT_Memory memory; + + } FT_LzwStateRec, *FT_LzwState; + + + FT_LOCAL( void ) + ft_lzwstate_init( FT_LzwState state, + FT_Stream source ); + + FT_LOCAL( void ) + ft_lzwstate_done( FT_LzwState state ); + + + FT_LOCAL( void ) + ft_lzwstate_reset( FT_LzwState state ); + + + FT_LOCAL( FT_ULong ) + ft_lzwstate_io( FT_LzwState state, + FT_Byte* buffer, + FT_ULong out_size ); + +/* */ + +#endif /* __FT_ZOPEN_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/otvalid/otvalid.c b/mod/pub.mod/freetype.mod/src/otvalid/otvalid.c new file mode 100644 index 0000000..d5c2b75 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/otvalid/otvalid.c @@ -0,0 +1,31 @@ +/***************************************************************************/ +/* */ +/* otvalid.c */ +/* */ +/* FreeType validator for OpenType tables (body only). */ +/* */ +/* Copyright 2004, 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + +#define FT_MAKE_OPTION_SINGLE_OBJECT + +#include <ft2build.h> + +#include "otvbase.c" +#include "otvcommn.c" +#include "otvgdef.c" +#include "otvgpos.c" +#include "otvgsub.c" +#include "otvjstf.c" +#include "otvmath.c" +#include "otvmod.c" + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/otvalid/otvalid.h b/mod/pub.mod/freetype.mod/src/otvalid/otvalid.h new file mode 100644 index 0000000..eb99b9c --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/otvalid/otvalid.h @@ -0,0 +1,78 @@ +/***************************************************************************/ +/* */ +/* otvalid.h */ +/* */ +/* OpenType table validation (specification only). */ +/* */ +/* Copyright 2004, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __OTVALID_H__ +#define __OTVALID_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#include "otverror.h" /* must come before FT_INTERNAL_VALIDATE_H */ + +#include FT_INTERNAL_VALIDATE_H +#include FT_INTERNAL_STREAM_H + + +FT_BEGIN_HEADER + + + FT_LOCAL( void ) + otv_BASE_validate( FT_Bytes table, + FT_Validator valid ); + + /* GSUB and GPOS tables should already be validated; */ + /* if missing, set corresponding argument to 0 */ + FT_LOCAL( void ) + otv_GDEF_validate( FT_Bytes table, + FT_Bytes gsub, + FT_Bytes gpos, + FT_UInt glyph_count, + FT_Validator valid ); + + FT_LOCAL( void ) + otv_GPOS_validate( FT_Bytes table, + FT_UInt glyph_count, + FT_Validator valid ); + + FT_LOCAL( void ) + otv_GSUB_validate( FT_Bytes table, + FT_UInt glyph_count, + FT_Validator valid ); + + /* GSUB and GPOS tables should already be validated; */ + /* if missing, set corresponding argument to 0 */ + FT_LOCAL( void ) + otv_JSTF_validate( FT_Bytes table, + FT_Bytes gsub, + FT_Bytes gpos, + FT_UInt glyph_count, + FT_Validator valid ); + + FT_LOCAL( void ) + otv_MATH_validate( FT_Bytes table, + FT_UInt glyph_count, + FT_Validator ftvalid ); + + +FT_END_HEADER + +#endif /* __OTVALID_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/otvalid/otvbase.c b/mod/pub.mod/freetype.mod/src/otvalid/otvbase.c new file mode 100644 index 0000000..d742d2d --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/otvalid/otvbase.c @@ -0,0 +1,318 @@ +/***************************************************************************/ +/* */ +/* otvbase.c */ +/* */ +/* OpenType BASE table validation (body). */ +/* */ +/* Copyright 2004, 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include "otvalid.h" +#include "otvcommn.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_otvbase + + + static void + otv_BaseCoord_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt BaseCoordFormat; + + + OTV_NAME_ENTER( "BaseCoord" ); + + OTV_LIMIT_CHECK( 4 ); + BaseCoordFormat = FT_NEXT_USHORT( p ); + p += 2; /* skip Coordinate */ + + OTV_TRACE(( " (format %d)\n", BaseCoordFormat )); + + switch ( BaseCoordFormat ) + { + case 1: /* BaseCoordFormat1 */ + break; + + case 2: /* BaseCoordFormat2 */ + OTV_LIMIT_CHECK( 4 ); /* ReferenceGlyph, BaseCoordPoint */ + break; + + case 3: /* BaseCoordFormat3 */ + OTV_LIMIT_CHECK( 2 ); + /* DeviceTable */ + otv_Device_validate( table + FT_NEXT_USHORT( p ), valid ); + break; + + default: + FT_INVALID_FORMAT; + } + + OTV_EXIT; + } + + + static void + otv_BaseTagList_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt BaseTagCount; + + + OTV_NAME_ENTER( "BaseTagList" ); + + OTV_LIMIT_CHECK( 2 ); + + BaseTagCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (BaseTagCount = %d)\n", BaseTagCount )); + + OTV_LIMIT_CHECK( BaseTagCount * 4 ); /* BaselineTag */ + + OTV_EXIT; + } + + + static void + otv_BaseValues_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt BaseCoordCount; + + + OTV_NAME_ENTER( "BaseValues" ); + + OTV_LIMIT_CHECK( 4 ); + + p += 2; /* skip DefaultIndex */ + BaseCoordCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (BaseCoordCount = %d)\n", BaseCoordCount )); + + OTV_LIMIT_CHECK( BaseCoordCount * 2 ); + + /* BaseCoord */ + for ( ; BaseCoordCount > 0; BaseCoordCount-- ) + otv_BaseCoord_validate( table + FT_NEXT_USHORT( p ), valid ); + + OTV_EXIT; + } + + + static void + otv_MinMax_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt table_size; + FT_UInt FeatMinMaxCount; + + OTV_OPTIONAL_TABLE( MinCoord ); + OTV_OPTIONAL_TABLE( MaxCoord ); + + + OTV_NAME_ENTER( "MinMax" ); + + OTV_LIMIT_CHECK( 6 ); + + OTV_OPTIONAL_OFFSET( MinCoord ); + OTV_OPTIONAL_OFFSET( MaxCoord ); + FeatMinMaxCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (FeatMinMaxCount = %d)\n", FeatMinMaxCount )); + + table_size = FeatMinMaxCount * 8 + 6; + + OTV_SIZE_CHECK( MinCoord ); + if ( MinCoord ) + otv_BaseCoord_validate( table + MinCoord, valid ); + + OTV_SIZE_CHECK( MaxCoord ); + if ( MaxCoord ) + otv_BaseCoord_validate( table + MaxCoord, valid ); + + OTV_LIMIT_CHECK( FeatMinMaxCount * 8 ); + + /* FeatMinMaxRecord */ + for ( ; FeatMinMaxCount > 0; FeatMinMaxCount-- ) + { + p += 4; /* skip FeatureTableTag */ + + OTV_OPTIONAL_OFFSET( MinCoord ); + OTV_OPTIONAL_OFFSET( MaxCoord ); + + OTV_SIZE_CHECK( MinCoord ); + if ( MinCoord ) + otv_BaseCoord_validate( table + MinCoord, valid ); + + OTV_SIZE_CHECK( MaxCoord ); + if ( MaxCoord ) + otv_BaseCoord_validate( table + MaxCoord, valid ); + } + + OTV_EXIT; + } + + + static void + otv_BaseScript_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt table_size; + FT_UInt BaseLangSysCount; + + OTV_OPTIONAL_TABLE( BaseValues ); + OTV_OPTIONAL_TABLE( DefaultMinMax ); + + + OTV_NAME_ENTER( "BaseScript" ); + + OTV_LIMIT_CHECK( 6 ); + OTV_OPTIONAL_OFFSET( BaseValues ); + OTV_OPTIONAL_OFFSET( DefaultMinMax ); + BaseLangSysCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (BaseLangSysCount = %d)\n", BaseLangSysCount )); + + table_size = BaseLangSysCount * 6 + 6; + + OTV_SIZE_CHECK( BaseValues ); + if ( BaseValues ) + otv_BaseValues_validate( table + BaseValues, valid ); + + OTV_SIZE_CHECK( DefaultMinMax ); + if ( DefaultMinMax ) + otv_MinMax_validate( table + DefaultMinMax, valid ); + + OTV_LIMIT_CHECK( BaseLangSysCount * 6 ); + + /* BaseLangSysRecord */ + for ( ; BaseLangSysCount > 0; BaseLangSysCount-- ) + { + p += 4; /* skip BaseLangSysTag */ + + otv_MinMax_validate( table + FT_NEXT_USHORT( p ), valid ); + } + + OTV_EXIT; + } + + + static void + otv_BaseScriptList_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt BaseScriptCount; + + + OTV_NAME_ENTER( "BaseScriptList" ); + + OTV_LIMIT_CHECK( 2 ); + BaseScriptCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (BaseScriptCount = %d)\n", BaseScriptCount )); + + OTV_LIMIT_CHECK( BaseScriptCount * 6 ); + + /* BaseScriptRecord */ + for ( ; BaseScriptCount > 0; BaseScriptCount-- ) + { + p += 4; /* skip BaseScriptTag */ + + /* BaseScript */ + otv_BaseScript_validate( table + FT_NEXT_USHORT( p ), valid ); + } + + OTV_EXIT; + } + + + static void + otv_Axis_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt table_size; + + OTV_OPTIONAL_TABLE( BaseTagList ); + + + OTV_NAME_ENTER( "Axis" ); + + OTV_LIMIT_CHECK( 4 ); + OTV_OPTIONAL_OFFSET( BaseTagList ); + + table_size = 4; + + OTV_SIZE_CHECK( BaseTagList ); + if ( BaseTagList ) + otv_BaseTagList_validate( table + BaseTagList, valid ); + + /* BaseScriptList */ + otv_BaseScriptList_validate( table + FT_NEXT_USHORT( p ), valid ); + + OTV_EXIT; + } + + + FT_LOCAL_DEF( void ) + otv_BASE_validate( FT_Bytes table, + FT_Validator ftvalid ) + { + OTV_ValidatorRec validrec; + OTV_Validator valid = &validrec; + FT_Bytes p = table; + FT_UInt table_size; + + OTV_OPTIONAL_TABLE( HorizAxis ); + OTV_OPTIONAL_TABLE( VertAxis ); + + + valid->root = ftvalid; + + FT_TRACE3(( "validating BASE table\n" )); + OTV_INIT; + + OTV_LIMIT_CHECK( 6 ); + + if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */ + FT_INVALID_FORMAT; + + table_size = 6; + + OTV_OPTIONAL_OFFSET( HorizAxis ); + OTV_SIZE_CHECK( HorizAxis ); + if ( HorizAxis ) + otv_Axis_validate( table + HorizAxis, valid ); + + OTV_OPTIONAL_OFFSET( VertAxis ); + OTV_SIZE_CHECK( VertAxis ); + if ( VertAxis ) + otv_Axis_validate( table + VertAxis, valid ); + + FT_TRACE4(( "\n" )); + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/otvalid/otvcommn.c b/mod/pub.mod/freetype.mod/src/otvalid/otvcommn.c new file mode 100644 index 0000000..a4f885b --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/otvalid/otvcommn.c @@ -0,0 +1,1086 @@ +/***************************************************************************/ +/* */ +/* otvcommn.c */ +/* */ +/* OpenType common tables validation (body). */ +/* */ +/* Copyright 2004, 2005, 2006, 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include "otvcommn.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_otvcommon + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** COVERAGE TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL_DEF( void ) + otv_Coverage_validate( FT_Bytes table, + OTV_Validator valid, + FT_Int expected_count ) + { + FT_Bytes p = table; + FT_UInt CoverageFormat; + FT_UInt total = 0; + + + OTV_NAME_ENTER( "Coverage" ); + + OTV_LIMIT_CHECK( 4 ); + CoverageFormat = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (format %d)\n", CoverageFormat )); + + switch ( CoverageFormat ) + { + case 1: /* CoverageFormat1 */ + { + FT_UInt GlyphCount; + FT_UInt i; + + + GlyphCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount )); + + OTV_LIMIT_CHECK( GlyphCount * 2 ); /* GlyphArray */ + + for ( i = 0; i < GlyphCount; ++i ) + { + FT_UInt gid; + + + gid = FT_NEXT_USHORT( p ); + if ( gid >= valid->glyph_count ) + FT_INVALID_GLYPH_ID; + } + + total = GlyphCount; + } + break; + + case 2: /* CoverageFormat2 */ + { + FT_UInt n, RangeCount; + FT_UInt Start, End, StartCoverageIndex, last = 0; + + + RangeCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (RangeCount = %d)\n", RangeCount )); + + OTV_LIMIT_CHECK( RangeCount * 6 ); + + /* RangeRecord */ + for ( n = 0; n < RangeCount; n++ ) + { + Start = FT_NEXT_USHORT( p ); + End = FT_NEXT_USHORT( p ); + StartCoverageIndex = FT_NEXT_USHORT( p ); + + if ( Start > End || StartCoverageIndex != total ) + FT_INVALID_DATA; + + if ( End >= valid->glyph_count ) + FT_INVALID_GLYPH_ID; + + if ( n > 0 && Start <= last ) + FT_INVALID_DATA; + + total += End - Start + 1; + last = End; + } + } + break; + + default: + FT_INVALID_FORMAT; + } + + /* Generally, a coverage table offset has an associated count field. */ + /* The number of glyphs in the table should match this field. If */ + /* there is no associated count, a value of -1 tells us not to check. */ + if ( expected_count != -1 && (FT_UInt)expected_count != total ) + FT_INVALID_DATA; + + OTV_EXIT; + } + + + FT_LOCAL_DEF( FT_UInt ) + otv_Coverage_get_first( FT_Bytes table ) + { + FT_Bytes p = table; + + + p += 4; /* skip CoverageFormat and Glyph/RangeCount */ + + return FT_NEXT_USHORT( p ); + } + + + FT_LOCAL_DEF( FT_UInt ) + otv_Coverage_get_last( FT_Bytes table ) + { + FT_Bytes p = table; + FT_UInt CoverageFormat = FT_NEXT_USHORT( p ); + FT_UInt count = FT_NEXT_USHORT( p ); /* Glyph/RangeCount */ + FT_UInt result = 0; + + + switch ( CoverageFormat ) + { + case 1: + p += ( count - 1 ) * 2; + result = FT_NEXT_USHORT( p ); + break; + + case 2: + p += ( count - 1 ) * 6 + 2; + result = FT_NEXT_USHORT( p ); + break; + + default: + ; + } + + return result; + } + + + FT_LOCAL_DEF( FT_UInt ) + otv_Coverage_get_count( FT_Bytes table ) + { + FT_Bytes p = table; + FT_UInt CoverageFormat = FT_NEXT_USHORT( p ); + FT_UInt count = FT_NEXT_USHORT( p ); /* Glyph/RangeCount */ + FT_UInt result = 0; + + + switch ( CoverageFormat ) + { + case 1: + return count; + + case 2: + { + FT_UInt Start, End; + + + for ( ; count > 0; count-- ) + { + Start = FT_NEXT_USHORT( p ); + End = FT_NEXT_USHORT( p ); + p += 2; /* skip StartCoverageIndex */ + + result += End - Start + 1; + } + } + break; + + default: + ; + } + + return result; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** CLASS DEFINITION TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL_DEF( void ) + otv_ClassDef_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt ClassFormat; + + + OTV_NAME_ENTER( "ClassDef" ); + + OTV_LIMIT_CHECK( 4 ); + ClassFormat = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (format %d)\n", ClassFormat )); + + switch ( ClassFormat ) + { + case 1: /* ClassDefFormat1 */ + { + FT_UInt StartGlyph; + FT_UInt GlyphCount; + + + OTV_LIMIT_CHECK( 4 ); + + StartGlyph = FT_NEXT_USHORT( p ); + GlyphCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount )); + + OTV_LIMIT_CHECK( GlyphCount * 2 ); /* ClassValueArray */ + + if ( StartGlyph + GlyphCount - 1 >= valid->glyph_count ) + FT_INVALID_GLYPH_ID; + } + break; + + case 2: /* ClassDefFormat2 */ + { + FT_UInt n, ClassRangeCount; + FT_UInt Start, End, last = 0; + + + ClassRangeCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (ClassRangeCount = %d)\n", ClassRangeCount )); + + OTV_LIMIT_CHECK( ClassRangeCount * 6 ); + + /* ClassRangeRecord */ + for ( n = 0; n < ClassRangeCount; n++ ) + { + Start = FT_NEXT_USHORT( p ); + End = FT_NEXT_USHORT( p ); + p += 2; /* skip Class */ + + if ( Start > End || ( n > 0 && Start <= last ) ) + FT_INVALID_DATA; + + if ( End >= valid->glyph_count ) + FT_INVALID_GLYPH_ID; + + last = End; + } + } + break; + + default: + FT_INVALID_FORMAT; + } + + /* no need to check glyph indices used as input to class definition */ + /* tables since even invalid glyph indices return a meaningful result */ + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** DEVICE TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL_DEF( void ) + otv_Device_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt StartSize, EndSize, DeltaFormat, count; + + + OTV_NAME_ENTER( "Device" ); + + OTV_LIMIT_CHECK( 8 ); + StartSize = FT_NEXT_USHORT( p ); + EndSize = FT_NEXT_USHORT( p ); + DeltaFormat = FT_NEXT_USHORT( p ); + + if ( DeltaFormat < 1 || DeltaFormat > 3 ) + FT_INVALID_FORMAT; + + if ( EndSize < StartSize ) + FT_INVALID_DATA; + + count = EndSize - StartSize + 1; + OTV_LIMIT_CHECK( ( 1 << DeltaFormat ) * count / 8 ); /* DeltaValue */ + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** LOOKUPS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* uses valid->type_count */ + /* uses valid->type_funcs */ + + FT_LOCAL_DEF( void ) + otv_Lookup_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt LookupType, SubTableCount; + OTV_Validate_Func validate; + + + OTV_NAME_ENTER( "Lookup" ); + + OTV_LIMIT_CHECK( 6 ); + LookupType = FT_NEXT_USHORT( p ); + p += 2; /* skip LookupFlag */ + SubTableCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (type %d)\n", LookupType )); + + if ( LookupType == 0 || LookupType > valid->type_count ) + FT_INVALID_DATA; + + validate = valid->type_funcs[LookupType - 1]; + + OTV_TRACE(( " (SubTableCount = %d)\n", SubTableCount )); + + OTV_LIMIT_CHECK( SubTableCount * 2 ); + + /* SubTable */ + for ( ; SubTableCount > 0; SubTableCount-- ) + validate( table + FT_NEXT_USHORT( p ), valid ); + + OTV_EXIT; + } + + + /* uses valid->lookup_count */ + + FT_LOCAL_DEF( void ) + otv_LookupList_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt LookupCount; + + + OTV_NAME_ENTER( "LookupList" ); + + OTV_LIMIT_CHECK( 2 ); + LookupCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (LookupCount = %d)\n", LookupCount )); + + OTV_LIMIT_CHECK( LookupCount * 2 ); + + valid->lookup_count = LookupCount; + + /* Lookup */ + for ( ; LookupCount > 0; LookupCount-- ) + otv_Lookup_validate( table + FT_NEXT_USHORT( p ), valid ); + + OTV_EXIT; + } + + + static FT_UInt + otv_LookupList_get_count( FT_Bytes table ) + { + return FT_NEXT_USHORT( table ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** FEATURES *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* uses valid->lookup_count */ + + FT_LOCAL_DEF( void ) + otv_Feature_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt LookupCount; + + + OTV_NAME_ENTER( "Feature" ); + + OTV_LIMIT_CHECK( 4 ); + p += 2; /* skip FeatureParams (unused) */ + LookupCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (LookupCount = %d)\n", LookupCount )); + + OTV_LIMIT_CHECK( LookupCount * 2 ); + + /* LookupListIndex */ + for ( ; LookupCount > 0; LookupCount-- ) + if ( FT_NEXT_USHORT( p ) >= valid->lookup_count ) + FT_INVALID_DATA; + + OTV_EXIT; + } + + + static FT_UInt + otv_Feature_get_count( FT_Bytes table ) + { + return FT_NEXT_USHORT( table ); + } + + + /* sets valid->lookup_count */ + + FT_LOCAL_DEF( void ) + otv_FeatureList_validate( FT_Bytes table, + FT_Bytes lookups, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt FeatureCount; + + + OTV_NAME_ENTER( "FeatureList" ); + + OTV_LIMIT_CHECK( 2 ); + FeatureCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (FeatureCount = %d)\n", FeatureCount )); + + OTV_LIMIT_CHECK( FeatureCount * 2 ); + + valid->lookup_count = otv_LookupList_get_count( lookups ); + + /* FeatureRecord */ + for ( ; FeatureCount > 0; FeatureCount-- ) + { + p += 4; /* skip FeatureTag */ + + /* Feature */ + otv_Feature_validate( table + FT_NEXT_USHORT( p ), valid ); + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** LANGUAGE SYSTEM *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + /* uses valid->extra1 (number of features) */ + + FT_LOCAL_DEF( void ) + otv_LangSys_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt ReqFeatureIndex; + FT_UInt FeatureCount; + + + OTV_NAME_ENTER( "LangSys" ); + + OTV_LIMIT_CHECK( 6 ); + p += 2; /* skip LookupOrder (unused) */ + ReqFeatureIndex = FT_NEXT_USHORT( p ); + FeatureCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (ReqFeatureIndex = %d)\n", ReqFeatureIndex )); + OTV_TRACE(( " (FeatureCount = %d)\n", FeatureCount )); + + if ( ReqFeatureIndex != 0xFFFFU && ReqFeatureIndex >= valid->extra1 ) + FT_INVALID_DATA; + + OTV_LIMIT_CHECK( FeatureCount * 2 ); + + /* FeatureIndex */ + for ( ; FeatureCount > 0; FeatureCount-- ) + if ( FT_NEXT_USHORT( p ) >= valid->extra1 ) + FT_INVALID_DATA; + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** SCRIPTS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL_DEF( void ) + otv_Script_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_UInt DefaultLangSys, LangSysCount; + FT_Bytes p = table; + + + OTV_NAME_ENTER( "Script" ); + + OTV_LIMIT_CHECK( 4 ); + DefaultLangSys = FT_NEXT_USHORT( p ); + LangSysCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (LangSysCount = %d)\n", LangSysCount )); + + if ( DefaultLangSys != 0 ) + otv_LangSys_validate( table + DefaultLangSys, valid ); + + OTV_LIMIT_CHECK( LangSysCount * 6 ); + + /* LangSysRecord */ + for ( ; LangSysCount > 0; LangSysCount-- ) + { + p += 4; /* skip LangSysTag */ + + /* LangSys */ + otv_LangSys_validate( table + FT_NEXT_USHORT( p ), valid ); + } + + OTV_EXIT; + } + + + /* sets valid->extra1 (number of features) */ + + FT_LOCAL_DEF( void ) + otv_ScriptList_validate( FT_Bytes table, + FT_Bytes features, + OTV_Validator valid ) + { + FT_UInt ScriptCount; + FT_Bytes p = table; + + + OTV_NAME_ENTER( "ScriptList" ); + + OTV_LIMIT_CHECK( 2 ); + ScriptCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (ScriptCount = %d)\n", ScriptCount )); + + OTV_LIMIT_CHECK( ScriptCount * 6 ); + + valid->extra1 = otv_Feature_get_count( features ); + + /* ScriptRecord */ + for ( ; ScriptCount > 0; ScriptCount-- ) + { + p += 4; /* skip ScriptTag */ + + otv_Script_validate( table + FT_NEXT_USHORT( p ), valid ); /* Script */ + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** UTILITY FUNCTIONS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* + u: uint16 + ux: unit16 [x] + + s: struct + sx: struct [x] + sxy: struct [x], using external y count + + x: uint16 x + + C: Coverage + + O: Offset + On: Offset (NULL) + Ox: Offset [x] + Onx: Offset (NULL) [x] + */ + + FT_LOCAL_DEF( void ) + otv_x_Ox( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt Count; + OTV_Validate_Func func; + + + OTV_ENTER; + + OTV_LIMIT_CHECK( 2 ); + Count = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (Count = %d)\n", Count )); + + OTV_LIMIT_CHECK( Count * 2 ); + + valid->nesting_level++; + func = valid->func[valid->nesting_level]; + + for ( ; Count > 0; Count-- ) + func( table + FT_NEXT_USHORT( p ), valid ); + + valid->nesting_level--; + + OTV_EXIT; + } + + + FT_LOCAL_DEF( void ) + otv_u_C_x_Ox( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt Count, Coverage; + OTV_Validate_Func func; + + + OTV_ENTER; + + p += 2; /* skip Format */ + + OTV_LIMIT_CHECK( 4 ); + Coverage = FT_NEXT_USHORT( p ); + Count = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (Count = %d)\n", Count )); + + otv_Coverage_validate( table + Coverage, valid, Count ); + + OTV_LIMIT_CHECK( Count * 2 ); + + valid->nesting_level++; + func = valid->func[valid->nesting_level]; + + for ( ; Count > 0; Count-- ) + func( table + FT_NEXT_USHORT( p ), valid ); + + valid->nesting_level--; + + OTV_EXIT; + } + + + /* uses valid->extra1 (if > 0: array value limit) */ + + FT_LOCAL_DEF( void ) + otv_x_ux( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt Count; + + + OTV_ENTER; + + OTV_LIMIT_CHECK( 2 ); + Count = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (Count = %d)\n", Count )); + + OTV_LIMIT_CHECK( Count * 2 ); + + if ( valid->extra1 ) + { + for ( ; Count > 0; Count-- ) + if ( FT_NEXT_USHORT( p ) >= valid->extra1 ) + FT_INVALID_DATA; + } + + OTV_EXIT; + } + + + /* `ux' in the function's name is not really correct since only x-1 */ + /* elements are tested */ + + /* uses valid->extra1 (array value limit) */ + + FT_LOCAL_DEF( void ) + otv_x_y_ux_sy( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt Count1, Count2; + + + OTV_ENTER; + + OTV_LIMIT_CHECK( 4 ); + Count1 = FT_NEXT_USHORT( p ); + Count2 = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (Count1 = %d)\n", Count1 )); + OTV_TRACE(( " (Count2 = %d)\n", Count2 )); + + if ( Count1 == 0 ) + FT_INVALID_DATA; + + OTV_LIMIT_CHECK( ( Count1 - 1 ) * 2 + Count2 * 4 ); + p += ( Count1 - 1 ) * 2; + + for ( ; Count2 > 0; Count2-- ) + { + if ( FT_NEXT_USHORT( p ) >= Count1 ) + FT_INVALID_DATA; + + if ( FT_NEXT_USHORT( p ) >= valid->extra1 ) + FT_INVALID_DATA; + } + + OTV_EXIT; + } + + + /* `uy' in the function's name is not really correct since only y-1 */ + /* elements are tested */ + + /* uses valid->extra1 (array value limit) */ + + FT_LOCAL_DEF( void ) + otv_x_ux_y_uy_z_uz_p_sp( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt BacktrackCount, InputCount, LookaheadCount; + FT_UInt Count; + + + OTV_ENTER; + + OTV_LIMIT_CHECK( 2 ); + BacktrackCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (BacktrackCount = %d)\n", BacktrackCount )); + + OTV_LIMIT_CHECK( BacktrackCount * 2 + 2 ); + p += BacktrackCount * 2; + + InputCount = FT_NEXT_USHORT( p ); + if ( InputCount == 0 ) + FT_INVALID_DATA; + + OTV_TRACE(( " (InputCount = %d)\n", InputCount )); + + OTV_LIMIT_CHECK( InputCount * 2 ); + p += ( InputCount - 1 ) * 2; + + LookaheadCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (LookaheadCount = %d)\n", LookaheadCount )); + + OTV_LIMIT_CHECK( LookaheadCount * 2 + 2 ); + p += LookaheadCount * 2; + + Count = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (Count = %d)\n", Count )); + + OTV_LIMIT_CHECK( Count * 4 ); + + for ( ; Count > 0; Count-- ) + { + if ( FT_NEXT_USHORT( p ) >= InputCount ) + FT_INVALID_DATA; + + if ( FT_NEXT_USHORT( p ) >= valid->extra1 ) + FT_INVALID_DATA; + } + + OTV_EXIT; + } + + + /* sets valid->extra1 (valid->lookup_count) */ + + FT_LOCAL_DEF( void ) + otv_u_O_O_x_Onx( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt Coverage, ClassDef, ClassSetCount; + OTV_Validate_Func func; + + + OTV_ENTER; + + p += 2; /* skip Format */ + + OTV_LIMIT_CHECK( 6 ); + Coverage = FT_NEXT_USHORT( p ); + ClassDef = FT_NEXT_USHORT( p ); + ClassSetCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (ClassSetCount = %d)\n", ClassSetCount )); + + otv_Coverage_validate( table + Coverage, valid, -1 ); + otv_ClassDef_validate( table + ClassDef, valid ); + + OTV_LIMIT_CHECK( ClassSetCount * 2 ); + + valid->nesting_level++; + func = valid->func[valid->nesting_level]; + valid->extra1 = valid->lookup_count; + + for ( ; ClassSetCount > 0; ClassSetCount-- ) + { + FT_UInt offset = FT_NEXT_USHORT( p ); + + + if ( offset ) + func( table + offset, valid ); + } + + valid->nesting_level--; + + OTV_EXIT; + } + + + /* uses valid->lookup_count */ + + FT_LOCAL_DEF( void ) + otv_u_x_y_Ox_sy( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt GlyphCount, Count, count1; + + + OTV_ENTER; + + p += 2; /* skip Format */ + + OTV_LIMIT_CHECK( 4 ); + GlyphCount = FT_NEXT_USHORT( p ); + Count = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount )); + OTV_TRACE(( " (Count = %d)\n", Count )); + + OTV_LIMIT_CHECK( GlyphCount * 2 + Count * 4 ); + + for ( count1 = GlyphCount; count1 > 0; count1-- ) + otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 ); + + for ( ; Count > 0; Count-- ) + { + if ( FT_NEXT_USHORT( p ) >= GlyphCount ) + FT_INVALID_DATA; + + if ( FT_NEXT_USHORT( p ) >= valid->lookup_count ) + FT_INVALID_DATA; + } + + OTV_EXIT; + } + + + /* sets valid->extra1 (valid->lookup_count) */ + + FT_LOCAL_DEF( void ) + otv_u_O_O_O_O_x_Onx( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt Coverage; + FT_UInt BacktrackClassDef, InputClassDef, LookaheadClassDef; + FT_UInt ChainClassSetCount; + OTV_Validate_Func func; + + + OTV_ENTER; + + p += 2; /* skip Format */ + + OTV_LIMIT_CHECK( 10 ); + Coverage = FT_NEXT_USHORT( p ); + BacktrackClassDef = FT_NEXT_USHORT( p ); + InputClassDef = FT_NEXT_USHORT( p ); + LookaheadClassDef = FT_NEXT_USHORT( p ); + ChainClassSetCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (ChainClassSetCount = %d)\n", ChainClassSetCount )); + + otv_Coverage_validate( table + Coverage, valid, -1 ); + + otv_ClassDef_validate( table + BacktrackClassDef, valid ); + otv_ClassDef_validate( table + InputClassDef, valid ); + otv_ClassDef_validate( table + LookaheadClassDef, valid ); + + OTV_LIMIT_CHECK( ChainClassSetCount * 2 ); + + valid->nesting_level++; + func = valid->func[valid->nesting_level]; + valid->extra1 = valid->lookup_count; + + for ( ; ChainClassSetCount > 0; ChainClassSetCount-- ) + { + FT_UInt offset = FT_NEXT_USHORT( p ); + + + if ( offset ) + func( table + offset, valid ); + } + + valid->nesting_level--; + + OTV_EXIT; + } + + + /* uses valid->lookup_count */ + + FT_LOCAL_DEF( void ) + otv_u_x_Ox_y_Oy_z_Oz_p_sp( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt BacktrackGlyphCount, InputGlyphCount, LookaheadGlyphCount; + FT_UInt count1, count2; + + + OTV_ENTER; + + p += 2; /* skip Format */ + + OTV_LIMIT_CHECK( 2 ); + BacktrackGlyphCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (BacktrackGlyphCount = %d)\n", BacktrackGlyphCount )); + + OTV_LIMIT_CHECK( BacktrackGlyphCount * 2 + 2 ); + + for ( ; BacktrackGlyphCount > 0; BacktrackGlyphCount-- ) + otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 ); + + InputGlyphCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (InputGlyphCount = %d)\n", InputGlyphCount )); + + OTV_LIMIT_CHECK( InputGlyphCount * 2 + 2 ); + + for ( count1 = InputGlyphCount; count1 > 0; count1-- ) + otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 ); + + LookaheadGlyphCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (LookaheadGlyphCount = %d)\n", LookaheadGlyphCount )); + + OTV_LIMIT_CHECK( LookaheadGlyphCount * 2 + 2 ); + + for ( ; LookaheadGlyphCount > 0; LookaheadGlyphCount-- ) + otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 ); + + count2 = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (Count = %d)\n", count2 )); + + OTV_LIMIT_CHECK( count2 * 4 ); + + for ( ; count2 > 0; count2-- ) + { + if ( FT_NEXT_USHORT( p ) >= InputGlyphCount ) + FT_INVALID_DATA; + + if ( FT_NEXT_USHORT( p ) >= valid->lookup_count ) + FT_INVALID_DATA; + } + + OTV_EXIT; + } + + + FT_LOCAL_DEF( FT_UInt ) + otv_GSUBGPOS_get_Lookup_count( FT_Bytes table ) + { + FT_Bytes p = table + 8; + + + return otv_LookupList_get_count( table + FT_NEXT_USHORT( p ) ); + } + + + FT_LOCAL_DEF( FT_UInt ) + otv_GSUBGPOS_have_MarkAttachmentType_flag( FT_Bytes table ) + { + FT_Bytes p, lookup; + FT_UInt count; + + + if ( !table ) + return 0; + + /* LookupList */ + p = table + 8; + table += FT_NEXT_USHORT( p ); + + /* LookupCount */ + p = table; + count = FT_NEXT_USHORT( p ); + + for ( ; count > 0; count-- ) + { + FT_Bytes oldp; + + + /* Lookup */ + lookup = table + FT_NEXT_USHORT( p ); + + oldp = p; + + /* LookupFlag */ + p = lookup + 2; + if ( FT_NEXT_USHORT( p ) & 0xFF00U ) + return 1; + + p = oldp; + } + + return 0; + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/otvalid/otvcommn.h b/mod/pub.mod/freetype.mod/src/otvalid/otvcommn.h new file mode 100644 index 0000000..898887f --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/otvalid/otvcommn.h @@ -0,0 +1,437 @@ +/***************************************************************************/ +/* */ +/* otvcommn.h */ +/* */ +/* OpenType common tables validation (specification). */ +/* */ +/* Copyright 2004, 2005, 2007, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __OTVCOMMN_H__ +#define __OTVCOMMN_H__ + + +#include <ft2build.h> +#include "otvalid.h" +#include FT_INTERNAL_DEBUG_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** VALIDATION *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef struct OTV_ValidatorRec_* OTV_Validator; + + typedef void (*OTV_Validate_Func)( FT_Bytes table, + OTV_Validator valid ); + + typedef struct OTV_ValidatorRec_ + { + FT_Validator root; + FT_UInt type_count; + OTV_Validate_Func* type_funcs; + + FT_UInt lookup_count; + FT_UInt glyph_count; + + FT_UInt nesting_level; + + OTV_Validate_Func func[3]; + + FT_UInt extra1; /* for passing parameters */ + FT_UInt extra2; + FT_Bytes extra3; + +#ifdef FT_DEBUG_LEVEL_TRACE + FT_UInt debug_indent; + const FT_String* debug_function_name[3]; +#endif + + } OTV_ValidatorRec; + + +#undef FT_INVALID_ +#define FT_INVALID_( _prefix, _error ) \ + ft_validator_error( valid->root, _prefix ## _error ) + +#define OTV_OPTIONAL_TABLE( _table ) FT_UShort _table; \ + FT_Bytes _table ## _p + +#define OTV_OPTIONAL_OFFSET( _offset ) \ + FT_BEGIN_STMNT \ + _offset ## _p = p; \ + _offset = FT_NEXT_USHORT( p ); \ + FT_END_STMNT + +#define OTV_LIMIT_CHECK( _count ) \ + FT_BEGIN_STMNT \ + if ( p + (_count) > valid->root->limit ) \ + FT_INVALID_TOO_SHORT; \ + FT_END_STMNT + +#define OTV_SIZE_CHECK( _size ) \ + FT_BEGIN_STMNT \ + if ( _size > 0 && _size < table_size ) \ + { \ + if ( valid->root->level == FT_VALIDATE_PARANOID ) \ + FT_INVALID_OFFSET; \ + else \ + { \ + /* strip off `const' */ \ + FT_Byte* pp = (FT_Byte*)_size ## _p; \ + \ + \ + FT_TRACE3(( "\n" \ + "Invalid offset to optional table `%s'" \ + " set to zero.\n" \ + "\n", #_size )); \ + \ + /* always assume 16bit entities */ \ + _size = pp[0] = pp[1] = 0; \ + } \ + } \ + FT_END_STMNT + + +#define OTV_NAME_(x) #x +#define OTV_NAME(x) OTV_NAME_(x) + +#define OTV_FUNC_(x) x##Func +#define OTV_FUNC(x) OTV_FUNC_(x) + +#ifdef FT_DEBUG_LEVEL_TRACE + +#define OTV_NEST1( x ) \ + FT_BEGIN_STMNT \ + valid->nesting_level = 0; \ + valid->func[0] = OTV_FUNC( x ); \ + valid->debug_function_name[0] = OTV_NAME( x ); \ + FT_END_STMNT + +#define OTV_NEST2( x, y ) \ + FT_BEGIN_STMNT \ + valid->nesting_level = 0; \ + valid->func[0] = OTV_FUNC( x ); \ + valid->func[1] = OTV_FUNC( y ); \ + valid->debug_function_name[0] = OTV_NAME( x ); \ + valid->debug_function_name[1] = OTV_NAME( y ); \ + FT_END_STMNT + +#define OTV_NEST3( x, y, z ) \ + FT_BEGIN_STMNT \ + valid->nesting_level = 0; \ + valid->func[0] = OTV_FUNC( x ); \ + valid->func[1] = OTV_FUNC( y ); \ + valid->func[2] = OTV_FUNC( z ); \ + valid->debug_function_name[0] = OTV_NAME( x ); \ + valid->debug_function_name[1] = OTV_NAME( y ); \ + valid->debug_function_name[2] = OTV_NAME( z ); \ + FT_END_STMNT + +#define OTV_INIT valid->debug_indent = 0 + +#define OTV_ENTER \ + FT_BEGIN_STMNT \ + valid->debug_indent += 2; \ + FT_TRACE4(( "%*.s", valid->debug_indent, 0 )); \ + FT_TRACE4(( "%s table\n", \ + valid->debug_function_name[valid->nesting_level] )); \ + FT_END_STMNT + +#define OTV_NAME_ENTER( name ) \ + FT_BEGIN_STMNT \ + valid->debug_indent += 2; \ + FT_TRACE4(( "%*.s", valid->debug_indent, 0 )); \ + FT_TRACE4(( "%s table\n", name )); \ + FT_END_STMNT + +#define OTV_EXIT valid->debug_indent -= 2 + +#define OTV_TRACE( s ) \ + FT_BEGIN_STMNT \ + FT_TRACE4(( "%*.s", valid->debug_indent, 0 )); \ + FT_TRACE4( s ); \ + FT_END_STMNT + +#else /* !FT_DEBUG_LEVEL_TRACE */ + +#define OTV_NEST1( x ) \ + FT_BEGIN_STMNT \ + valid->nesting_level = 0; \ + valid->func[0] = OTV_FUNC( x ); \ + FT_END_STMNT + +#define OTV_NEST2( x, y ) \ + FT_BEGIN_STMNT \ + valid->nesting_level = 0; \ + valid->func[0] = OTV_FUNC( x ); \ + valid->func[1] = OTV_FUNC( y ); \ + FT_END_STMNT + +#define OTV_NEST3( x, y, z ) \ + FT_BEGIN_STMNT \ + valid->nesting_level = 0; \ + valid->func[0] = OTV_FUNC( x ); \ + valid->func[1] = OTV_FUNC( y ); \ + valid->func[2] = OTV_FUNC( z ); \ + FT_END_STMNT + +#define OTV_INIT do { } while ( 0 ) +#define OTV_ENTER do { } while ( 0 ) +#define OTV_NAME_ENTER( name ) do { } while ( 0 ) +#define OTV_EXIT do { } while ( 0 ) + +#define OTV_TRACE( s ) do { } while ( 0 ) + +#endif /* !FT_DEBUG_LEVEL_TRACE */ + + +#define OTV_RUN valid->func[0] + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** COVERAGE TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL( void ) + otv_Coverage_validate( FT_Bytes table, + OTV_Validator valid, + FT_Int expected_count ); + + /* return first covered glyph */ + FT_LOCAL( FT_UInt ) + otv_Coverage_get_first( FT_Bytes table ); + + /* return last covered glyph */ + FT_LOCAL( FT_UInt ) + otv_Coverage_get_last( FT_Bytes table ); + + /* return number of covered glyphs */ + FT_LOCAL( FT_UInt ) + otv_Coverage_get_count( FT_Bytes table ); + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** CLASS DEFINITION TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL( void ) + otv_ClassDef_validate( FT_Bytes table, + OTV_Validator valid ); + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** DEVICE TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL( void ) + otv_Device_validate( FT_Bytes table, + OTV_Validator valid ); + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** LOOKUPS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL( void ) + otv_Lookup_validate( FT_Bytes table, + OTV_Validator valid ); + + FT_LOCAL( void ) + otv_LookupList_validate( FT_Bytes table, + OTV_Validator valid ); + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** FEATURES *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL( void ) + otv_Feature_validate( FT_Bytes table, + OTV_Validator valid ); + + /* lookups must already be validated */ + FT_LOCAL( void ) + otv_FeatureList_validate( FT_Bytes table, + FT_Bytes lookups, + OTV_Validator valid ); + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** LANGUAGE SYSTEM *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL( void ) + otv_LangSys_validate( FT_Bytes table, + OTV_Validator valid ); + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** SCRIPTS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL( void ) + otv_Script_validate( FT_Bytes table, + OTV_Validator valid ); + + /* features must already be validated */ + FT_LOCAL( void ) + otv_ScriptList_validate( FT_Bytes table, + FT_Bytes features, + OTV_Validator valid ); + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** UTILITY FUNCTIONS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + +#define ChainPosClassSetFunc otv_x_Ox +#define ChainPosRuleSetFunc otv_x_Ox +#define ChainSubClassSetFunc otv_x_Ox +#define ChainSubRuleSetFunc otv_x_Ox +#define JstfLangSysFunc otv_x_Ox +#define JstfMaxFunc otv_x_Ox +#define LigGlyphFunc otv_x_Ox +#define LigatureArrayFunc otv_x_Ox +#define LigatureSetFunc otv_x_Ox +#define PosClassSetFunc otv_x_Ox +#define PosRuleSetFunc otv_x_Ox +#define SubClassSetFunc otv_x_Ox +#define SubRuleSetFunc otv_x_Ox + + FT_LOCAL( void ) + otv_x_Ox ( FT_Bytes table, + OTV_Validator valid ); + +#define AlternateSubstFormat1Func otv_u_C_x_Ox +#define ChainContextPosFormat1Func otv_u_C_x_Ox +#define ChainContextSubstFormat1Func otv_u_C_x_Ox +#define ContextPosFormat1Func otv_u_C_x_Ox +#define ContextSubstFormat1Func otv_u_C_x_Ox +#define LigatureSubstFormat1Func otv_u_C_x_Ox +#define MultipleSubstFormat1Func otv_u_C_x_Ox + + FT_LOCAL( void ) + otv_u_C_x_Ox( FT_Bytes table, + OTV_Validator valid ); + +#define AlternateSetFunc otv_x_ux +#define AttachPointFunc otv_x_ux +#define ExtenderGlyphFunc otv_x_ux +#define JstfGPOSModListFunc otv_x_ux +#define JstfGSUBModListFunc otv_x_ux +#define SequenceFunc otv_x_ux + + FT_LOCAL( void ) + otv_x_ux( FT_Bytes table, + OTV_Validator valid ); + +#define PosClassRuleFunc otv_x_y_ux_sy +#define PosRuleFunc otv_x_y_ux_sy +#define SubClassRuleFunc otv_x_y_ux_sy +#define SubRuleFunc otv_x_y_ux_sy + + FT_LOCAL( void ) + otv_x_y_ux_sy( FT_Bytes table, + OTV_Validator valid ); + +#define ChainPosClassRuleFunc otv_x_ux_y_uy_z_uz_p_sp +#define ChainPosRuleFunc otv_x_ux_y_uy_z_uz_p_sp +#define ChainSubClassRuleFunc otv_x_ux_y_uy_z_uz_p_sp +#define ChainSubRuleFunc otv_x_ux_y_uy_z_uz_p_sp + + FT_LOCAL( void ) + otv_x_ux_y_uy_z_uz_p_sp( FT_Bytes table, + OTV_Validator valid ); + +#define ContextPosFormat2Func otv_u_O_O_x_Onx +#define ContextSubstFormat2Func otv_u_O_O_x_Onx + + FT_LOCAL( void ) + otv_u_O_O_x_Onx( FT_Bytes table, + OTV_Validator valid ); + +#define ContextPosFormat3Func otv_u_x_y_Ox_sy +#define ContextSubstFormat3Func otv_u_x_y_Ox_sy + + FT_LOCAL( void ) + otv_u_x_y_Ox_sy( FT_Bytes table, + OTV_Validator valid ); + +#define ChainContextPosFormat2Func otv_u_O_O_O_O_x_Onx +#define ChainContextSubstFormat2Func otv_u_O_O_O_O_x_Onx + + FT_LOCAL( void ) + otv_u_O_O_O_O_x_Onx( FT_Bytes table, + OTV_Validator valid ); + +#define ChainContextPosFormat3Func otv_u_x_Ox_y_Oy_z_Oz_p_sp +#define ChainContextSubstFormat3Func otv_u_x_Ox_y_Oy_z_Oz_p_sp + + FT_LOCAL( void ) + otv_u_x_Ox_y_Oy_z_Oz_p_sp( FT_Bytes table, + OTV_Validator valid ); + + + FT_LOCAL( FT_UInt ) + otv_GSUBGPOS_get_Lookup_count( FT_Bytes table ); + + FT_LOCAL( FT_UInt ) + otv_GSUBGPOS_have_MarkAttachmentType_flag( FT_Bytes table ); + + /* */ + +FT_END_HEADER + +#endif /* __OTVCOMMN_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/otvalid/otverror.h b/mod/pub.mod/freetype.mod/src/otvalid/otverror.h new file mode 100644 index 0000000..041b538 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/otvalid/otverror.h @@ -0,0 +1,43 @@ +/***************************************************************************/ +/* */ +/* otverror.h */ +/* */ +/* OpenType validation module error codes (specification only). */ +/* */ +/* Copyright 2004, 2005 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file is used to define the OpenType validation module error */ + /* enumeration constants. */ + /* */ + /*************************************************************************/ + +#ifndef __OTVERROR_H__ +#define __OTVERROR_H__ + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#define FT_ERR_PREFIX OTV_Err_ +#define FT_ERR_BASE FT_Mod_Err_OTvalid + +#define FT_KEEP_ERR_PREFIX + +#include FT_ERRORS_H + +#endif /* __OTVERROR_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/otvalid/otvgdef.c b/mod/pub.mod/freetype.mod/src/otvalid/otvgdef.c new file mode 100644 index 0000000..3633ad0 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/otvalid/otvgdef.c @@ -0,0 +1,224 @@ +/***************************************************************************/ +/* */ +/* otvgdef.c */ +/* */ +/* OpenType GDEF table validation (body). */ +/* */ +/* Copyright 2004, 2005, 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include "otvalid.h" +#include "otvcommn.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_otvgdef + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** UTILITY FUNCTIONS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + +#define AttachListFunc otv_O_x_Ox +#define LigCaretListFunc otv_O_x_Ox + + /* sets valid->extra1 (0) */ + + static void + otv_O_x_Ox( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_Bytes Coverage; + FT_UInt GlyphCount; + OTV_Validate_Func func; + + + OTV_ENTER; + + OTV_LIMIT_CHECK( 4 ); + Coverage = table + FT_NEXT_USHORT( p ); + GlyphCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount )); + + otv_Coverage_validate( Coverage, valid, GlyphCount ); + if ( GlyphCount != otv_Coverage_get_count( Coverage ) ) + FT_INVALID_DATA; + + OTV_LIMIT_CHECK( GlyphCount * 2 ); + + valid->nesting_level++; + func = valid->func[valid->nesting_level]; + valid->extra1 = 0; + + for ( ; GlyphCount > 0; GlyphCount-- ) + func( table + FT_NEXT_USHORT( p ), valid ); + + valid->nesting_level--; + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** LIGATURE CARETS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + +#define CaretValueFunc otv_CaretValue_validate + + static void + otv_CaretValue_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt CaretValueFormat; + + + OTV_ENTER; + + OTV_LIMIT_CHECK( 4 ); + + CaretValueFormat = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (format = %d)\n", CaretValueFormat )); + + switch ( CaretValueFormat ) + { + case 1: /* CaretValueFormat1 */ + /* skip Coordinate, no test */ + break; + + case 2: /* CaretValueFormat2 */ + /* skip CaretValuePoint, no test */ + break; + + case 3: /* CaretValueFormat3 */ + p += 2; /* skip Coordinate */ + + OTV_LIMIT_CHECK( 2 ); + + /* DeviceTable */ + otv_Device_validate( table + FT_NEXT_USHORT( p ), valid ); + break; + + default: + FT_INVALID_FORMAT; + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GDEF TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* sets valid->glyph_count */ + + FT_LOCAL_DEF( void ) + otv_GDEF_validate( FT_Bytes table, + FT_Bytes gsub, + FT_Bytes gpos, + FT_UInt glyph_count, + FT_Validator ftvalid ) + { + OTV_ValidatorRec validrec; + OTV_Validator valid = &validrec; + FT_Bytes p = table; + FT_UInt table_size; + FT_Bool need_MarkAttachClassDef; + + OTV_OPTIONAL_TABLE( GlyphClassDef ); + OTV_OPTIONAL_TABLE( AttachListOffset ); + OTV_OPTIONAL_TABLE( LigCaretListOffset ); + OTV_OPTIONAL_TABLE( MarkAttachClassDef ); + + + valid->root = ftvalid; + + FT_TRACE3(( "validating GDEF table\n" )); + OTV_INIT; + + OTV_LIMIT_CHECK( 12 ); + + if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */ + FT_INVALID_FORMAT; + + /* MarkAttachClassDef has been added to the OpenType */ + /* specification without increasing GDEF's version, */ + /* so we use this ugly hack to find out whether the */ + /* table is needed actually. */ + + need_MarkAttachClassDef = FT_BOOL( + otv_GSUBGPOS_have_MarkAttachmentType_flag( gsub ) || + otv_GSUBGPOS_have_MarkAttachmentType_flag( gpos ) ); + + if ( need_MarkAttachClassDef ) + table_size = 12; /* OpenType >= 1.2 */ + else + table_size = 10; /* OpenType < 1.2 */ + + valid->glyph_count = glyph_count; + + OTV_OPTIONAL_OFFSET( GlyphClassDef ); + OTV_SIZE_CHECK( GlyphClassDef ); + if ( GlyphClassDef ) + otv_ClassDef_validate( table + GlyphClassDef, valid ); + + OTV_OPTIONAL_OFFSET( AttachListOffset ); + OTV_SIZE_CHECK( AttachListOffset ); + if ( AttachListOffset ) + { + OTV_NEST2( AttachList, AttachPoint ); + OTV_RUN( table + AttachListOffset, valid ); + } + + OTV_OPTIONAL_OFFSET( LigCaretListOffset ); + OTV_SIZE_CHECK( LigCaretListOffset ); + if ( LigCaretListOffset ) + { + OTV_NEST3( LigCaretList, LigGlyph, CaretValue ); + OTV_RUN( table + LigCaretListOffset, valid ); + } + + if ( need_MarkAttachClassDef ) + { + OTV_OPTIONAL_OFFSET( MarkAttachClassDef ); + OTV_SIZE_CHECK( MarkAttachClassDef ); + if ( MarkAttachClassDef ) + otv_ClassDef_validate( table + MarkAttachClassDef, valid ); + } + + FT_TRACE4(( "\n" )); + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/otvalid/otvgpos.c b/mod/pub.mod/freetype.mod/src/otvalid/otvgpos.c new file mode 100644 index 0000000..49b4618 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/otvalid/otvgpos.c @@ -0,0 +1,1017 @@ +/***************************************************************************/ +/* */ +/* otvgpos.c */ +/* */ +/* OpenType GPOS table validation (body). */ +/* */ +/* Copyright 2002, 2004, 2005, 2006, 2007, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include "otvalid.h" +#include "otvcommn.h" +#include "otvgpos.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_otvgpos + + + static void + otv_Anchor_validate( FT_Bytes table, + OTV_Validator valid ); + + static void + otv_MarkArray_validate( FT_Bytes table, + OTV_Validator valid ); + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** UTILITY FUNCTIONS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + +#define BaseArrayFunc otv_x_sxy +#define LigatureAttachFunc otv_x_sxy +#define Mark2ArrayFunc otv_x_sxy + + /* uses valid->extra1 (counter) */ + /* uses valid->extra2 (boolean to handle NULL anchor field) */ + + static void + otv_x_sxy( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt Count, count1, table_size; + + + OTV_ENTER; + + OTV_LIMIT_CHECK( 2 ); + + Count = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (Count = %d)\n", Count )); + + OTV_LIMIT_CHECK( Count * valid->extra1 * 2 ); + + table_size = Count * valid->extra1 * 2 + 2; + + for ( ; Count > 0; Count-- ) + for ( count1 = valid->extra1; count1 > 0; count1-- ) + { + OTV_OPTIONAL_TABLE( anchor_offset ); + + + OTV_OPTIONAL_OFFSET( anchor_offset ); + + if ( valid->extra2 ) + { + OTV_SIZE_CHECK( anchor_offset ); + if ( anchor_offset ) + otv_Anchor_validate( table + anchor_offset, valid ); + } + else + otv_Anchor_validate( table + anchor_offset, valid ); + } + + OTV_EXIT; + } + + +#define MarkBasePosFormat1Func otv_u_O_O_u_O_O +#define MarkLigPosFormat1Func otv_u_O_O_u_O_O +#define MarkMarkPosFormat1Func otv_u_O_O_u_O_O + + /* sets valid->extra1 (class count) */ + + static void + otv_u_O_O_u_O_O( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt Coverage1, Coverage2, ClassCount; + FT_UInt Array1, Array2; + OTV_Validate_Func func; + + + OTV_ENTER; + + p += 2; /* skip PosFormat */ + + OTV_LIMIT_CHECK( 10 ); + Coverage1 = FT_NEXT_USHORT( p ); + Coverage2 = FT_NEXT_USHORT( p ); + ClassCount = FT_NEXT_USHORT( p ); + Array1 = FT_NEXT_USHORT( p ); + Array2 = FT_NEXT_USHORT( p ); + + otv_Coverage_validate( table + Coverage1, valid, -1 ); + otv_Coverage_validate( table + Coverage2, valid, -1 ); + + otv_MarkArray_validate( table + Array1, valid ); + + valid->nesting_level++; + func = valid->func[valid->nesting_level]; + valid->extra1 = ClassCount; + + func( table + Array2, valid ); + + valid->nesting_level--; + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** VALUE RECORDS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static FT_UInt + otv_value_length( FT_UInt format ) + { + FT_UInt count; + + + count = ( ( format & 0xAA ) >> 1 ) + ( format & 0x55 ); + count = ( ( count & 0xCC ) >> 2 ) + ( count & 0x33 ); + count = ( ( count & 0xF0 ) >> 4 ) + ( count & 0x0F ); + + return count * 2; + } + + + /* uses valid->extra3 (pointer to base table) */ + + static void + otv_ValueRecord_validate( FT_Bytes table, + FT_UInt format, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt count; + +#ifdef FT_DEBUG_LEVEL_TRACE + FT_Int loop; + FT_ULong res = 0; + + + OTV_NAME_ENTER( "ValueRecord" ); + + /* display `format' in dual representation */ + for ( loop = 7; loop >= 0; loop-- ) + { + res <<= 4; + res += ( format >> loop ) & 1; + } + + OTV_TRACE(( " (format 0b%08lx)\n", res )); +#endif + + if ( format >= 0x100 ) + FT_INVALID_FORMAT; + + for ( count = 4; count > 0; count-- ) + { + if ( format & 1 ) + { + /* XPlacement, YPlacement, XAdvance, YAdvance */ + OTV_LIMIT_CHECK( 2 ); + p += 2; + } + + format >>= 1; + } + + for ( count = 4; count > 0; count-- ) + { + if ( format & 1 ) + { + FT_PtrDist table_size; + + OTV_OPTIONAL_TABLE( device ); + + + /* XPlaDevice, YPlaDevice, XAdvDevice, YAdvDevice */ + OTV_LIMIT_CHECK( 2 ); + OTV_OPTIONAL_OFFSET( device ); + + /* XXX: this value is usually too small, especially if the current */ + /* ValueRecord is part of an array -- getting the correct table */ + /* size is probably not worth the trouble */ + + table_size = p - valid->extra3; + + OTV_SIZE_CHECK( device ); + if ( device ) + otv_Device_validate( valid->extra3 + device, valid ); + } + format >>= 1; + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** ANCHORS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + otv_Anchor_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt AnchorFormat; + + + OTV_NAME_ENTER( "Anchor"); + + OTV_LIMIT_CHECK( 6 ); + AnchorFormat = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (format %d)\n", AnchorFormat )); + + p += 4; /* skip XCoordinate and YCoordinate */ + + switch ( AnchorFormat ) + { + case 1: + break; + + case 2: + OTV_LIMIT_CHECK( 2 ); /* AnchorPoint */ + break; + + case 3: + { + FT_UInt table_size; + + OTV_OPTIONAL_TABLE( XDeviceTable ); + OTV_OPTIONAL_TABLE( YDeviceTable ); + + + OTV_LIMIT_CHECK( 4 ); + OTV_OPTIONAL_OFFSET( XDeviceTable ); + OTV_OPTIONAL_OFFSET( YDeviceTable ); + + table_size = 6 + 4; + + OTV_SIZE_CHECK( XDeviceTable ); + if ( XDeviceTable ) + otv_Device_validate( table + XDeviceTable, valid ); + + OTV_SIZE_CHECK( YDeviceTable ); + if ( YDeviceTable ) + otv_Device_validate( table + YDeviceTable, valid ); + } + break; + + default: + FT_INVALID_FORMAT; + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** MARK ARRAYS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + otv_MarkArray_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt MarkCount; + + + OTV_NAME_ENTER( "MarkArray" ); + + OTV_LIMIT_CHECK( 2 ); + MarkCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (MarkCount = %d)\n", MarkCount )); + + OTV_LIMIT_CHECK( MarkCount * 4 ); + + /* MarkRecord */ + for ( ; MarkCount > 0; MarkCount-- ) + { + p += 2; /* skip Class */ + /* MarkAnchor */ + otv_Anchor_validate( table + FT_NEXT_USHORT( p ), valid ); + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GPOS LOOKUP TYPE 1 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* sets valid->extra3 (pointer to base table) */ + + static void + otv_SinglePos_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt PosFormat; + + + OTV_NAME_ENTER( "SinglePos" ); + + OTV_LIMIT_CHECK( 2 ); + PosFormat = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (format %d)\n", PosFormat )); + + valid->extra3 = table; + + switch ( PosFormat ) + { + case 1: /* SinglePosFormat1 */ + { + FT_UInt Coverage, ValueFormat; + + + OTV_LIMIT_CHECK( 4 ); + Coverage = FT_NEXT_USHORT( p ); + ValueFormat = FT_NEXT_USHORT( p ); + + otv_Coverage_validate( table + Coverage, valid, -1 ); + otv_ValueRecord_validate( p, ValueFormat, valid ); /* Value */ + } + break; + + case 2: /* SinglePosFormat2 */ + { + FT_UInt Coverage, ValueFormat, ValueCount, len_value; + + + OTV_LIMIT_CHECK( 6 ); + Coverage = FT_NEXT_USHORT( p ); + ValueFormat = FT_NEXT_USHORT( p ); + ValueCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (ValueCount = %d)\n", ValueCount )); + + len_value = otv_value_length( ValueFormat ); + + otv_Coverage_validate( table + Coverage, valid, ValueCount ); + + OTV_LIMIT_CHECK( ValueCount * len_value ); + + /* Value */ + for ( ; ValueCount > 0; ValueCount-- ) + { + otv_ValueRecord_validate( p, ValueFormat, valid ); + p += len_value; + } + } + break; + + default: + FT_INVALID_FORMAT; + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GPOS LOOKUP TYPE 2 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + otv_PairSet_validate( FT_Bytes table, + FT_UInt format1, + FT_UInt format2, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt value_len1, value_len2, PairValueCount; + + + OTV_NAME_ENTER( "PairSet" ); + + OTV_LIMIT_CHECK( 2 ); + PairValueCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (PairValueCount = %d)\n", PairValueCount )); + + value_len1 = otv_value_length( format1 ); + value_len2 = otv_value_length( format2 ); + + OTV_LIMIT_CHECK( PairValueCount * ( value_len1 + value_len2 + 2 ) ); + + /* PairValueRecord */ + for ( ; PairValueCount > 0; PairValueCount-- ) + { + p += 2; /* skip SecondGlyph */ + + if ( format1 ) + otv_ValueRecord_validate( p, format1, valid ); /* Value1 */ + p += value_len1; + + if ( format2 ) + otv_ValueRecord_validate( p, format2, valid ); /* Value2 */ + p += value_len2; + } + + OTV_EXIT; + } + + + /* sets valid->extra3 (pointer to base table) */ + + static void + otv_PairPos_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt PosFormat; + + + OTV_NAME_ENTER( "PairPos" ); + + OTV_LIMIT_CHECK( 2 ); + PosFormat = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (format %d)\n", PosFormat )); + + valid->extra3 = table; + + switch ( PosFormat ) + { + case 1: /* PairPosFormat1 */ + { + FT_UInt Coverage, ValueFormat1, ValueFormat2, PairSetCount; + + + OTV_LIMIT_CHECK( 8 ); + Coverage = FT_NEXT_USHORT( p ); + ValueFormat1 = FT_NEXT_USHORT( p ); + ValueFormat2 = FT_NEXT_USHORT( p ); + PairSetCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (PairSetCount = %d)\n", PairSetCount )); + + otv_Coverage_validate( table + Coverage, valid, -1 ); + + OTV_LIMIT_CHECK( PairSetCount * 2 ); + + /* PairSetOffset */ + for ( ; PairSetCount > 0; PairSetCount-- ) + otv_PairSet_validate( table + FT_NEXT_USHORT( p ), + ValueFormat1, ValueFormat2, valid ); + } + break; + + case 2: /* PairPosFormat2 */ + { + FT_UInt Coverage, ValueFormat1, ValueFormat2, ClassDef1, ClassDef2; + FT_UInt ClassCount1, ClassCount2, len_value1, len_value2, count; + + + OTV_LIMIT_CHECK( 14 ); + Coverage = FT_NEXT_USHORT( p ); + ValueFormat1 = FT_NEXT_USHORT( p ); + ValueFormat2 = FT_NEXT_USHORT( p ); + ClassDef1 = FT_NEXT_USHORT( p ); + ClassDef2 = FT_NEXT_USHORT( p ); + ClassCount1 = FT_NEXT_USHORT( p ); + ClassCount2 = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (ClassCount1 = %d)\n", ClassCount1 )); + OTV_TRACE(( " (ClassCount2 = %d)\n", ClassCount2 )); + + len_value1 = otv_value_length( ValueFormat1 ); + len_value2 = otv_value_length( ValueFormat2 ); + + otv_Coverage_validate( table + Coverage, valid, -1 ); + otv_ClassDef_validate( table + ClassDef1, valid ); + otv_ClassDef_validate( table + ClassDef2, valid ); + + OTV_LIMIT_CHECK( ClassCount1 * ClassCount2 * + ( len_value1 + len_value2 ) ); + + /* Class1Record */ + for ( ; ClassCount1 > 0; ClassCount1-- ) + { + /* Class2Record */ + for ( count = ClassCount2; count > 0; count-- ) + { + if ( ValueFormat1 ) + /* Value1 */ + otv_ValueRecord_validate( p, ValueFormat1, valid ); + p += len_value1; + + if ( ValueFormat2 ) + /* Value2 */ + otv_ValueRecord_validate( p, ValueFormat2, valid ); + p += len_value2; + } + } + } + break; + + default: + FT_INVALID_FORMAT; + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GPOS LOOKUP TYPE 3 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + otv_CursivePos_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt PosFormat; + + + OTV_NAME_ENTER( "CursivePos" ); + + OTV_LIMIT_CHECK( 2 ); + PosFormat = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (format %d)\n", PosFormat )); + + switch ( PosFormat ) + { + case 1: /* CursivePosFormat1 */ + { + FT_UInt table_size; + FT_UInt Coverage, EntryExitCount; + + OTV_OPTIONAL_TABLE( EntryAnchor ); + OTV_OPTIONAL_TABLE( ExitAnchor ); + + + OTV_LIMIT_CHECK( 4 ); + Coverage = FT_NEXT_USHORT( p ); + EntryExitCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (EntryExitCount = %d)\n", EntryExitCount )); + + otv_Coverage_validate( table + Coverage, valid, EntryExitCount ); + + OTV_LIMIT_CHECK( EntryExitCount * 4 ); + + table_size = EntryExitCount * 4 + 4; + + /* EntryExitRecord */ + for ( ; EntryExitCount > 0; EntryExitCount-- ) + { + OTV_OPTIONAL_OFFSET( EntryAnchor ); + OTV_OPTIONAL_OFFSET( ExitAnchor ); + + OTV_SIZE_CHECK( EntryAnchor ); + if ( EntryAnchor ) + otv_Anchor_validate( table + EntryAnchor, valid ); + + OTV_SIZE_CHECK( ExitAnchor ); + if ( ExitAnchor ) + otv_Anchor_validate( table + ExitAnchor, valid ); + } + } + break; + + default: + FT_INVALID_FORMAT; + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GPOS LOOKUP TYPE 4 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* UNDOCUMENTED (in OpenType 1.5): */ + /* BaseRecord tables can contain NULL pointers. */ + + /* sets valid->extra2 (1) */ + + static void + otv_MarkBasePos_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt PosFormat; + + + OTV_NAME_ENTER( "MarkBasePos" ); + + OTV_LIMIT_CHECK( 2 ); + PosFormat = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (format %d)\n", PosFormat )); + + switch ( PosFormat ) + { + case 1: + valid->extra2 = 1; + OTV_NEST2( MarkBasePosFormat1, BaseArray ); + OTV_RUN( table, valid ); + break; + + default: + FT_INVALID_FORMAT; + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GPOS LOOKUP TYPE 5 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* sets valid->extra2 (1) */ + + static void + otv_MarkLigPos_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt PosFormat; + + + OTV_NAME_ENTER( "MarkLigPos" ); + + OTV_LIMIT_CHECK( 2 ); + PosFormat = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (format %d)\n", PosFormat )); + + switch ( PosFormat ) + { + case 1: + valid->extra2 = 1; + OTV_NEST3( MarkLigPosFormat1, LigatureArray, LigatureAttach ); + OTV_RUN( table, valid ); + break; + + default: + FT_INVALID_FORMAT; + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GPOS LOOKUP TYPE 6 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* sets valid->extra2 (0) */ + + static void + otv_MarkMarkPos_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt PosFormat; + + + OTV_NAME_ENTER( "MarkMarkPos" ); + + OTV_LIMIT_CHECK( 2 ); + PosFormat = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (format %d)\n", PosFormat )); + + switch ( PosFormat ) + { + case 1: + valid->extra2 = 0; + OTV_NEST2( MarkMarkPosFormat1, Mark2Array ); + OTV_RUN( table, valid ); + break; + + default: + FT_INVALID_FORMAT; + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GPOS LOOKUP TYPE 7 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* sets valid->extra1 (lookup count) */ + + static void + otv_ContextPos_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt PosFormat; + + + OTV_NAME_ENTER( "ContextPos" ); + + OTV_LIMIT_CHECK( 2 ); + PosFormat = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (format %d)\n", PosFormat )); + + switch ( PosFormat ) + { + case 1: + /* no need to check glyph indices/classes used as input for these */ + /* context rules since even invalid glyph indices/classes return */ + /* meaningful results */ + + valid->extra1 = valid->lookup_count; + OTV_NEST3( ContextPosFormat1, PosRuleSet, PosRule ); + OTV_RUN( table, valid ); + break; + + case 2: + /* no need to check glyph indices/classes used as input for these */ + /* context rules since even invalid glyph indices/classes return */ + /* meaningful results */ + + OTV_NEST3( ContextPosFormat2, PosClassSet, PosClassRule ); + OTV_RUN( table, valid ); + break; + + case 3: + OTV_NEST1( ContextPosFormat3 ); + OTV_RUN( table, valid ); + break; + + default: + FT_INVALID_FORMAT; + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GPOS LOOKUP TYPE 8 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* sets valid->extra1 (lookup count) */ + + static void + otv_ChainContextPos_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt PosFormat; + + + OTV_NAME_ENTER( "ChainContextPos" ); + + OTV_LIMIT_CHECK( 2 ); + PosFormat = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (format %d)\n", PosFormat )); + + switch ( PosFormat ) + { + case 1: + /* no need to check glyph indices/classes used as input for these */ + /* context rules since even invalid glyph indices/classes return */ + /* meaningful results */ + + valid->extra1 = valid->lookup_count; + OTV_NEST3( ChainContextPosFormat1, + ChainPosRuleSet, ChainPosRule ); + OTV_RUN( table, valid ); + break; + + case 2: + /* no need to check glyph indices/classes used as input for these */ + /* context rules since even invalid glyph indices/classes return */ + /* meaningful results */ + + OTV_NEST3( ChainContextPosFormat2, + ChainPosClassSet, ChainPosClassRule ); + OTV_RUN( table, valid ); + break; + + case 3: + OTV_NEST1( ChainContextPosFormat3 ); + OTV_RUN( table, valid ); + break; + + default: + FT_INVALID_FORMAT; + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GPOS LOOKUP TYPE 9 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* uses valid->type_funcs */ + + static void + otv_ExtensionPos_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt PosFormat; + + + OTV_NAME_ENTER( "ExtensionPos" ); + + OTV_LIMIT_CHECK( 2 ); + PosFormat = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (format %d)\n", PosFormat )); + + switch ( PosFormat ) + { + case 1: /* ExtensionPosFormat1 */ + { + FT_UInt ExtensionLookupType; + FT_ULong ExtensionOffset; + OTV_Validate_Func validate; + + + OTV_LIMIT_CHECK( 6 ); + ExtensionLookupType = FT_NEXT_USHORT( p ); + ExtensionOffset = FT_NEXT_ULONG( p ); + + if ( ExtensionLookupType == 0 || ExtensionLookupType >= 9 ) + FT_INVALID_DATA; + + validate = valid->type_funcs[ExtensionLookupType - 1]; + validate( table + ExtensionOffset, valid ); + } + break; + + default: + FT_INVALID_FORMAT; + } + + OTV_EXIT; + } + + + static const OTV_Validate_Func otv_gpos_validate_funcs[9] = + { + otv_SinglePos_validate, + otv_PairPos_validate, + otv_CursivePos_validate, + otv_MarkBasePos_validate, + otv_MarkLigPos_validate, + otv_MarkMarkPos_validate, + otv_ContextPos_validate, + otv_ChainContextPos_validate, + otv_ExtensionPos_validate + }; + + + /* sets valid->type_count */ + /* sets valid->type_funcs */ + + FT_LOCAL_DEF( void ) + otv_GPOS_subtable_validate( FT_Bytes table, + OTV_Validator valid ) + { + valid->type_count = 9; + valid->type_funcs = (OTV_Validate_Func*)otv_gpos_validate_funcs; + + otv_Lookup_validate( table, valid ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GPOS TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* sets valid->glyph_count */ + + FT_LOCAL_DEF( void ) + otv_GPOS_validate( FT_Bytes table, + FT_UInt glyph_count, + FT_Validator ftvalid ) + { + OTV_ValidatorRec validrec; + OTV_Validator valid = &validrec; + FT_Bytes p = table; + FT_UInt ScriptList, FeatureList, LookupList; + + + valid->root = ftvalid; + + FT_TRACE3(( "validating GPOS table\n" )); + OTV_INIT; + + OTV_LIMIT_CHECK( 10 ); + + if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */ + FT_INVALID_FORMAT; + + ScriptList = FT_NEXT_USHORT( p ); + FeatureList = FT_NEXT_USHORT( p ); + LookupList = FT_NEXT_USHORT( p ); + + valid->type_count = 9; + valid->type_funcs = (OTV_Validate_Func*)otv_gpos_validate_funcs; + valid->glyph_count = glyph_count; + + otv_LookupList_validate( table + LookupList, + valid ); + otv_FeatureList_validate( table + FeatureList, table + LookupList, + valid ); + otv_ScriptList_validate( table + ScriptList, table + FeatureList, + valid ); + + FT_TRACE4(( "\n" )); + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/otvalid/otvgpos.h b/mod/pub.mod/freetype.mod/src/otvalid/otvgpos.h new file mode 100644 index 0000000..14ca408 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/otvalid/otvgpos.h @@ -0,0 +1,36 @@ +/***************************************************************************/ +/* */ +/* otvgpos.h */ +/* */ +/* OpenType GPOS table validator (specification). */ +/* */ +/* Copyright 2004 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __OTVGPOS_H__ +#define __OTVGPOS_H__ + + +FT_BEGIN_HEADER + + + FT_LOCAL( void ) + otv_GPOS_subtable_validate( FT_Bytes table, + OTV_Validator valid ); + + +FT_END_HEADER + +#endif /* __OTVGPOS_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/otvalid/otvgsub.c b/mod/pub.mod/freetype.mod/src/otvalid/otvgsub.c new file mode 100644 index 0000000..ed499d1 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/otvalid/otvgsub.c @@ -0,0 +1,585 @@ +/***************************************************************************/ +/* */ +/* otvgsub.c */ +/* */ +/* OpenType GSUB table validation (body). */ +/* */ +/* Copyright 2004, 2005, 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include "otvalid.h" +#include "otvcommn.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_otvgsub + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GSUB LOOKUP TYPE 1 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* uses valid->glyph_count */ + + static void + otv_SingleSubst_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt SubstFormat; + + + OTV_NAME_ENTER( "SingleSubst" ); + + OTV_LIMIT_CHECK( 2 ); + SubstFormat = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (format %d)\n", SubstFormat )); + + switch ( SubstFormat ) + { + case 1: /* SingleSubstFormat1 */ + { + FT_Bytes Coverage; + FT_Int DeltaGlyphID; + FT_Long idx; + + + OTV_LIMIT_CHECK( 4 ); + Coverage = table + FT_NEXT_USHORT( p ); + DeltaGlyphID = FT_NEXT_SHORT( p ); + + otv_Coverage_validate( Coverage, valid, -1 ); + + idx = otv_Coverage_get_first( Coverage ) + DeltaGlyphID; + if ( idx < 0 ) + FT_INVALID_DATA; + + idx = otv_Coverage_get_last( Coverage ) + DeltaGlyphID; + if ( (FT_UInt)idx >= valid->glyph_count ) + FT_INVALID_DATA; + } + break; + + case 2: /* SingleSubstFormat2 */ + { + FT_UInt Coverage, GlyphCount; + + + OTV_LIMIT_CHECK( 4 ); + Coverage = FT_NEXT_USHORT( p ); + GlyphCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount )); + + otv_Coverage_validate( table + Coverage, valid, GlyphCount ); + + OTV_LIMIT_CHECK( GlyphCount * 2 ); + + /* Substitute */ + for ( ; GlyphCount > 0; GlyphCount-- ) + if ( FT_NEXT_USHORT( p ) >= valid->glyph_count ) + FT_INVALID_GLYPH_ID; + } + break; + + default: + FT_INVALID_FORMAT; + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GSUB LOOKUP TYPE 2 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* sets valid->extra1 (glyph count) */ + + static void + otv_MultipleSubst_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt SubstFormat; + + + OTV_NAME_ENTER( "MultipleSubst" ); + + OTV_LIMIT_CHECK( 2 ); + SubstFormat = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (format %d)\n", SubstFormat )); + + switch ( SubstFormat ) + { + case 1: + valid->extra1 = valid->glyph_count; + OTV_NEST2( MultipleSubstFormat1, Sequence ); + OTV_RUN( table, valid ); + break; + + default: + FT_INVALID_FORMAT; + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GSUB LOOKUP TYPE 3 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* sets valid->extra1 (glyph count) */ + + static void + otv_AlternateSubst_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt SubstFormat; + + + OTV_NAME_ENTER( "AlternateSubst" ); + + OTV_LIMIT_CHECK( 2 ); + SubstFormat = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (format %d)\n", SubstFormat )); + + switch ( SubstFormat ) + { + case 1: + valid->extra1 = valid->glyph_count; + OTV_NEST2( AlternateSubstFormat1, AlternateSet ); + OTV_RUN( table, valid ); + break; + + default: + FT_INVALID_FORMAT; + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GSUB LOOKUP TYPE 4 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + +#define LigatureFunc otv_Ligature_validate + + /* uses valid->glyph_count */ + + static void + otv_Ligature_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt LigatureGlyph, CompCount; + + + OTV_ENTER; + + OTV_LIMIT_CHECK( 4 ); + LigatureGlyph = FT_NEXT_USHORT( p ); + if ( LigatureGlyph >= valid->glyph_count ) + FT_INVALID_DATA; + + CompCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (CompCount = %d)\n", CompCount )); + + if ( CompCount == 0 ) + FT_INVALID_DATA; + + CompCount--; + + OTV_LIMIT_CHECK( CompCount * 2 ); /* Component */ + + /* no need to check the Component glyph indices */ + + OTV_EXIT; + } + + + static void + otv_LigatureSubst_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt SubstFormat; + + + OTV_NAME_ENTER( "LigatureSubst" ); + + OTV_LIMIT_CHECK( 2 ); + SubstFormat = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (format %d)\n", SubstFormat )); + + switch ( SubstFormat ) + { + case 1: + OTV_NEST3( LigatureSubstFormat1, LigatureSet, Ligature ); + OTV_RUN( table, valid ); + break; + + default: + FT_INVALID_FORMAT; + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GSUB LOOKUP TYPE 5 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* sets valid->extra1 (lookup count) */ + + static void + otv_ContextSubst_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt SubstFormat; + + + OTV_NAME_ENTER( "ContextSubst" ); + + OTV_LIMIT_CHECK( 2 ); + SubstFormat = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (format %d)\n", SubstFormat )); + + switch ( SubstFormat ) + { + case 1: + /* no need to check glyph indices/classes used as input for these */ + /* context rules since even invalid glyph indices/classes return */ + /* meaningful results */ + + valid->extra1 = valid->lookup_count; + OTV_NEST3( ContextSubstFormat1, SubRuleSet, SubRule ); + OTV_RUN( table, valid ); + break; + + case 2: + /* no need to check glyph indices/classes used as input for these */ + /* context rules since even invalid glyph indices/classes return */ + /* meaningful results */ + + OTV_NEST3( ContextSubstFormat2, SubClassSet, SubClassRule ); + OTV_RUN( table, valid ); + break; + + case 3: + OTV_NEST1( ContextSubstFormat3 ); + OTV_RUN( table, valid ); + break; + + default: + FT_INVALID_FORMAT; + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GSUB LOOKUP TYPE 6 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* sets valid->extra1 (lookup count) */ + + static void + otv_ChainContextSubst_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt SubstFormat; + + + OTV_NAME_ENTER( "ChainContextSubst" ); + + OTV_LIMIT_CHECK( 2 ); + SubstFormat = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (format %d)\n", SubstFormat )); + + switch ( SubstFormat ) + { + case 1: + /* no need to check glyph indices/classes used as input for these */ + /* context rules since even invalid glyph indices/classes return */ + /* meaningful results */ + + valid->extra1 = valid->lookup_count; + OTV_NEST3( ChainContextSubstFormat1, + ChainSubRuleSet, ChainSubRule ); + OTV_RUN( table, valid ); + break; + + case 2: + /* no need to check glyph indices/classes used as input for these */ + /* context rules since even invalid glyph indices/classes return */ + /* meaningful results */ + + OTV_NEST3( ChainContextSubstFormat2, + ChainSubClassSet, ChainSubClassRule ); + OTV_RUN( table, valid ); + break; + + case 3: + OTV_NEST1( ChainContextSubstFormat3 ); + OTV_RUN( table, valid ); + break; + + default: + FT_INVALID_FORMAT; + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GSUB LOOKUP TYPE 7 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* uses valid->type_funcs */ + + static void + otv_ExtensionSubst_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt SubstFormat; + + + OTV_NAME_ENTER( "ExtensionSubst" ); + + OTV_LIMIT_CHECK( 2 ); + SubstFormat = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (format %d)\n", SubstFormat )); + + switch ( SubstFormat ) + { + case 1: /* ExtensionSubstFormat1 */ + { + FT_UInt ExtensionLookupType; + FT_ULong ExtensionOffset; + OTV_Validate_Func validate; + + + OTV_LIMIT_CHECK( 6 ); + ExtensionLookupType = FT_NEXT_USHORT( p ); + ExtensionOffset = FT_NEXT_ULONG( p ); + + if ( ExtensionLookupType == 0 || + ExtensionLookupType == 7 || + ExtensionLookupType > 8 ) + FT_INVALID_DATA; + + validate = valid->type_funcs[ExtensionLookupType - 1]; + validate( table + ExtensionOffset, valid ); + } + break; + + default: + FT_INVALID_FORMAT; + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GSUB LOOKUP TYPE 8 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* uses valid->glyph_count */ + + static void + otv_ReverseChainSingleSubst_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table, Coverage; + FT_UInt SubstFormat; + FT_UInt BacktrackGlyphCount, LookaheadGlyphCount, GlyphCount; + + + OTV_NAME_ENTER( "ReverseChainSingleSubst" ); + + OTV_LIMIT_CHECK( 2 ); + SubstFormat = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (format %d)\n", SubstFormat )); + + switch ( SubstFormat ) + { + case 1: /* ReverseChainSingleSubstFormat1 */ + OTV_LIMIT_CHECK( 4 ); + Coverage = table + FT_NEXT_USHORT( p ); + BacktrackGlyphCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (BacktrackGlyphCount = %d)\n", BacktrackGlyphCount )); + + otv_Coverage_validate( Coverage, valid, -1 ); + + OTV_LIMIT_CHECK( BacktrackGlyphCount * 2 + 2 ); + + for ( ; BacktrackGlyphCount > 0; BacktrackGlyphCount-- ) + otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 ); + + LookaheadGlyphCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (LookaheadGlyphCount = %d)\n", LookaheadGlyphCount )); + + OTV_LIMIT_CHECK( LookaheadGlyphCount * 2 + 2 ); + + for ( ; LookaheadGlyphCount > 0; LookaheadGlyphCount-- ) + otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 ); + + GlyphCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount )); + + if ( GlyphCount != otv_Coverage_get_count( Coverage ) ) + FT_INVALID_DATA; + + OTV_LIMIT_CHECK( GlyphCount * 2 ); + + /* Substitute */ + for ( ; GlyphCount > 0; GlyphCount-- ) + if ( FT_NEXT_USHORT( p ) >= valid->glyph_count ) + FT_INVALID_DATA; + + break; + + default: + FT_INVALID_FORMAT; + } + + OTV_EXIT; + } + + + static const OTV_Validate_Func otv_gsub_validate_funcs[8] = + { + otv_SingleSubst_validate, + otv_MultipleSubst_validate, + otv_AlternateSubst_validate, + otv_LigatureSubst_validate, + otv_ContextSubst_validate, + otv_ChainContextSubst_validate, + otv_ExtensionSubst_validate, + otv_ReverseChainSingleSubst_validate + }; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GSUB TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* sets valid->type_count */ + /* sets valid->type_funcs */ + /* sets valid->glyph_count */ + + FT_LOCAL_DEF( void ) + otv_GSUB_validate( FT_Bytes table, + FT_UInt glyph_count, + FT_Validator ftvalid ) + { + OTV_ValidatorRec validrec; + OTV_Validator valid = &validrec; + FT_Bytes p = table; + FT_UInt ScriptList, FeatureList, LookupList; + + + valid->root = ftvalid; + + FT_TRACE3(( "validating GSUB table\n" )); + OTV_INIT; + + OTV_LIMIT_CHECK( 10 ); + + if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */ + FT_INVALID_FORMAT; + + ScriptList = FT_NEXT_USHORT( p ); + FeatureList = FT_NEXT_USHORT( p ); + LookupList = FT_NEXT_USHORT( p ); + + valid->type_count = 8; + valid->type_funcs = (OTV_Validate_Func*)otv_gsub_validate_funcs; + valid->glyph_count = glyph_count; + + otv_LookupList_validate( table + LookupList, + valid ); + otv_FeatureList_validate( table + FeatureList, table + LookupList, + valid ); + otv_ScriptList_validate( table + ScriptList, table + FeatureList, + valid ); + + FT_TRACE4(( "\n" )); + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/otvalid/otvjstf.c b/mod/pub.mod/freetype.mod/src/otvalid/otvjstf.c new file mode 100644 index 0000000..a616a23 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/otvalid/otvjstf.c @@ -0,0 +1,258 @@ +/***************************************************************************/ +/* */ +/* otvjstf.c */ +/* */ +/* OpenType JSTF table validation (body). */ +/* */ +/* Copyright 2004, 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include "otvalid.h" +#include "otvcommn.h" +#include "otvgpos.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_otvjstf + + +#define JstfPriorityFunc otv_JstfPriority_validate +#define JstfLookupFunc otv_GPOS_subtable_validate + + /* uses valid->extra1 (GSUB lookup count) */ + /* uses valid->extra2 (GPOS lookup count) */ + /* sets valid->extra1 (counter) */ + + static void + otv_JstfPriority_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt table_size; + FT_UInt gsub_lookup_count, gpos_lookup_count; + + OTV_OPTIONAL_TABLE( ShrinkageEnableGSUB ); + OTV_OPTIONAL_TABLE( ShrinkageDisableGSUB ); + OTV_OPTIONAL_TABLE( ShrinkageEnableGPOS ); + OTV_OPTIONAL_TABLE( ShrinkageDisableGPOS ); + OTV_OPTIONAL_TABLE( ExtensionEnableGSUB ); + OTV_OPTIONAL_TABLE( ExtensionDisableGSUB ); + OTV_OPTIONAL_TABLE( ExtensionEnableGPOS ); + OTV_OPTIONAL_TABLE( ExtensionDisableGPOS ); + OTV_OPTIONAL_TABLE( ShrinkageJstfMax ); + OTV_OPTIONAL_TABLE( ExtensionJstfMax ); + + + OTV_ENTER; + OTV_TRACE(( "JstfPriority table\n" )); + + OTV_LIMIT_CHECK( 20 ); + + gsub_lookup_count = valid->extra1; + gpos_lookup_count = valid->extra2; + + table_size = 20; + + valid->extra1 = gsub_lookup_count; + + OTV_OPTIONAL_OFFSET( ShrinkageEnableGSUB ); + OTV_SIZE_CHECK( ShrinkageEnableGSUB ); + if ( ShrinkageEnableGSUB ) + otv_x_ux( table + ShrinkageEnableGSUB, valid ); + + OTV_OPTIONAL_OFFSET( ShrinkageDisableGSUB ); + OTV_SIZE_CHECK( ShrinkageDisableGSUB ); + if ( ShrinkageDisableGSUB ) + otv_x_ux( table + ShrinkageDisableGSUB, valid ); + + valid->extra1 = gpos_lookup_count; + + OTV_OPTIONAL_OFFSET( ShrinkageEnableGPOS ); + OTV_SIZE_CHECK( ShrinkageEnableGPOS ); + if ( ShrinkageEnableGPOS ) + otv_x_ux( table + ShrinkageEnableGPOS, valid ); + + OTV_OPTIONAL_OFFSET( ShrinkageDisableGPOS ); + OTV_SIZE_CHECK( ShrinkageDisableGPOS ); + if ( ShrinkageDisableGPOS ) + otv_x_ux( table + ShrinkageDisableGPOS, valid ); + + OTV_OPTIONAL_OFFSET( ShrinkageJstfMax ); + OTV_SIZE_CHECK( ShrinkageJstfMax ); + if ( ShrinkageJstfMax ) + { + /* XXX: check lookup types? */ + OTV_NEST2( JstfMax, JstfLookup ); + OTV_RUN( table + ShrinkageJstfMax, valid ); + } + + valid->extra1 = gsub_lookup_count; + + OTV_OPTIONAL_OFFSET( ExtensionEnableGSUB ); + OTV_SIZE_CHECK( ExtensionEnableGSUB ); + if ( ExtensionEnableGSUB ) + otv_x_ux( table + ExtensionEnableGSUB, valid ); + + OTV_OPTIONAL_OFFSET( ExtensionDisableGSUB ); + OTV_SIZE_CHECK( ExtensionDisableGSUB ); + if ( ExtensionDisableGSUB ) + otv_x_ux( table + ExtensionDisableGSUB, valid ); + + valid->extra1 = gpos_lookup_count; + + OTV_OPTIONAL_OFFSET( ExtensionEnableGPOS ); + OTV_SIZE_CHECK( ExtensionEnableGPOS ); + if ( ExtensionEnableGPOS ) + otv_x_ux( table + ExtensionEnableGPOS, valid ); + + OTV_OPTIONAL_OFFSET( ExtensionDisableGPOS ); + OTV_SIZE_CHECK( ExtensionDisableGPOS ); + if ( ExtensionDisableGPOS ) + otv_x_ux( table + ExtensionDisableGPOS, valid ); + + OTV_OPTIONAL_OFFSET( ExtensionJstfMax ); + OTV_SIZE_CHECK( ExtensionJstfMax ); + if ( ExtensionJstfMax ) + { + /* XXX: check lookup types? */ + OTV_NEST2( JstfMax, JstfLookup ); + OTV_RUN( table + ExtensionJstfMax, valid ); + } + + valid->extra1 = gsub_lookup_count; + valid->extra2 = gpos_lookup_count; + + OTV_EXIT; + } + + + /* sets valid->extra (glyph count) */ + /* sets valid->func1 (otv_JstfPriority_validate) */ + + static void + otv_JstfScript_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt table_size; + FT_UInt JstfLangSysCount; + + OTV_OPTIONAL_TABLE( ExtGlyph ); + OTV_OPTIONAL_TABLE( DefJstfLangSys ); + + + OTV_NAME_ENTER( "JstfScript" ); + + OTV_LIMIT_CHECK( 6 ); + OTV_OPTIONAL_OFFSET( ExtGlyph ); + OTV_OPTIONAL_OFFSET( DefJstfLangSys ); + JstfLangSysCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (JstfLangSysCount = %d)\n", JstfLangSysCount )); + + table_size = JstfLangSysCount * 6 + 6; + + OTV_SIZE_CHECK( ExtGlyph ); + if ( ExtGlyph ) + { + valid->extra1 = valid->glyph_count; + OTV_NEST1( ExtenderGlyph ); + OTV_RUN( table + ExtGlyph, valid ); + } + + OTV_SIZE_CHECK( DefJstfLangSys ); + if ( DefJstfLangSys ) + { + OTV_NEST2( JstfLangSys, JstfPriority ); + OTV_RUN( table + DefJstfLangSys, valid ); + } + + OTV_LIMIT_CHECK( 6 * JstfLangSysCount ); + + /* JstfLangSysRecord */ + OTV_NEST2( JstfLangSys, JstfPriority ); + for ( ; JstfLangSysCount > 0; JstfLangSysCount-- ) + { + p += 4; /* skip JstfLangSysTag */ + + OTV_RUN( table + FT_NEXT_USHORT( p ), valid ); + } + + OTV_EXIT; + } + + + /* sets valid->extra1 (GSUB lookup count) */ + /* sets valid->extra2 (GPOS lookup count) */ + /* sets valid->glyph_count */ + + FT_LOCAL_DEF( void ) + otv_JSTF_validate( FT_Bytes table, + FT_Bytes gsub, + FT_Bytes gpos, + FT_UInt glyph_count, + FT_Validator ftvalid ) + { + OTV_ValidatorRec validrec; + OTV_Validator valid = &validrec; + FT_Bytes p = table; + FT_UInt JstfScriptCount; + + + valid->root = ftvalid; + + FT_TRACE3(( "validating JSTF table\n" )); + OTV_INIT; + + OTV_LIMIT_CHECK( 6 ); + + if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */ + FT_INVALID_FORMAT; + + JstfScriptCount = FT_NEXT_USHORT( p ); + + FT_TRACE3(( " (JstfScriptCount = %d)\n", JstfScriptCount )); + + OTV_LIMIT_CHECK( JstfScriptCount * 6 ); + + if ( gsub ) + valid->extra1 = otv_GSUBGPOS_get_Lookup_count( gsub ); + else + valid->extra1 = 0; + + if ( gpos ) + valid->extra2 = otv_GSUBGPOS_get_Lookup_count( gpos ); + else + valid->extra2 = 0; + + valid->glyph_count = glyph_count; + + /* JstfScriptRecord */ + for ( ; JstfScriptCount > 0; JstfScriptCount-- ) + { + p += 4; /* skip JstfScriptTag */ + + /* JstfScript */ + otv_JstfScript_validate( table + FT_NEXT_USHORT( p ), valid ); + } + + FT_TRACE4(( "\n" )); + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/otvalid/otvmath.c b/mod/pub.mod/freetype.mod/src/otvalid/otvmath.c new file mode 100644 index 0000000..50ed10c --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/otvalid/otvmath.c @@ -0,0 +1,452 @@ +/***************************************************************************/ +/* */ +/* otvmath.c */ +/* */ +/* OpenType MATH table validation (body). */ +/* */ +/* Copyright 2007, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* Written by George Williams. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include "otvalid.h" +#include "otvcommn.h" +#include "otvgpos.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_otvmath + + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** MATH TYPOGRAPHIC CONSTANTS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + otv_MathConstants_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt i; + FT_UInt table_size; + + OTV_OPTIONAL_TABLE( DeviceTableOffset ); + + + OTV_NAME_ENTER( "MathConstants" ); + + /* 56 constants, 51 have device tables */ + OTV_LIMIT_CHECK( 2 * ( 56 + 51 ) ); + table_size = 2 * ( 56 + 51 ); + + p += 4 * 2; /* First 4 constants have no device tables */ + for ( i = 0; i < 51; ++i ) + { + p += 2; /* skip the value */ + OTV_OPTIONAL_OFFSET( DeviceTableOffset ); + OTV_SIZE_CHECK( DeviceTableOffset ); + if ( DeviceTableOffset ) + otv_Device_validate( table + DeviceTableOffset, valid ); + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** MATH ITALICS CORRECTION *****/ + /***** MATH TOP ACCENT ATTACHMENT *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + otv_MathItalicsCorrectionInfo_validate( FT_Bytes table, + OTV_Validator valid, + FT_Int isItalic ) + { + FT_Bytes p = table; + FT_UInt i, cnt, table_size ; + + OTV_OPTIONAL_TABLE( Coverage ); + OTV_OPTIONAL_TABLE( DeviceTableOffset ); + + FT_UNUSED( isItalic ); /* only used if tracing is active */ + + + OTV_NAME_ENTER( isItalic ? "MathItalicsCorrectionInfo" + : "MathTopAccentAttachment" ); + + OTV_LIMIT_CHECK( 4 ); + + OTV_OPTIONAL_OFFSET( Coverage ); + cnt = FT_NEXT_USHORT( p ); + + OTV_LIMIT_CHECK( 4 * cnt ); + table_size = 4 + 4 * cnt; + + OTV_SIZE_CHECK( Coverage ); + otv_Coverage_validate( table + Coverage, valid, cnt ); + + for ( i = 0; i < cnt; ++i ) + { + p += 2; /* Skip the value */ + OTV_OPTIONAL_OFFSET( DeviceTableOffset ); + OTV_SIZE_CHECK( DeviceTableOffset ); + if ( DeviceTableOffset ) + otv_Device_validate( table + DeviceTableOffset, valid ); + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** MATH KERNING *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + otv_MathKern_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt i, cnt, table_size; + + OTV_OPTIONAL_TABLE( DeviceTableOffset ); + + + /* OTV_NAME_ENTER( "MathKern" );*/ + + OTV_LIMIT_CHECK( 2 ); + + cnt = FT_NEXT_USHORT( p ); + + OTV_LIMIT_CHECK( 4 * cnt + 2 ); + table_size = 4 + 4 * cnt; + + /* Heights */ + for ( i = 0; i < cnt; ++i ) + { + p += 2; /* Skip the value */ + OTV_OPTIONAL_OFFSET( DeviceTableOffset ); + OTV_SIZE_CHECK( DeviceTableOffset ); + if ( DeviceTableOffset ) + otv_Device_validate( table + DeviceTableOffset, valid ); + } + + /* One more Kerning value */ + for ( i = 0; i < cnt + 1; ++i ) + { + p += 2; /* Skip the value */ + OTV_OPTIONAL_OFFSET( DeviceTableOffset ); + OTV_SIZE_CHECK( DeviceTableOffset ); + if ( DeviceTableOffset ) + otv_Device_validate( table + DeviceTableOffset, valid ); + } + + OTV_EXIT; + } + + + static void + otv_MathKernInfo_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt i, j, cnt, table_size; + + OTV_OPTIONAL_TABLE( Coverage ); + OTV_OPTIONAL_TABLE( MKRecordOffset ); + + + OTV_NAME_ENTER( "MathKernInfo" ); + + OTV_LIMIT_CHECK( 4 ); + + OTV_OPTIONAL_OFFSET( Coverage ); + cnt = FT_NEXT_USHORT( p ); + + OTV_LIMIT_CHECK( 8 * cnt ); + table_size = 4 + 8 * cnt; + + OTV_SIZE_CHECK( Coverage ); + otv_Coverage_validate( table + Coverage, valid, cnt ); + + for ( i = 0; i < cnt; ++i ) + { + for ( j = 0; j < 4; ++j ) + { + OTV_OPTIONAL_OFFSET( MKRecordOffset ); + OTV_SIZE_CHECK( MKRecordOffset ); + if ( MKRecordOffset ) + otv_MathKern_validate( table + MKRecordOffset, valid ); + } + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** MATH GLYPH INFO *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + otv_MathGlyphInfo_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt MathItalicsCorrectionInfo, MathTopAccentAttachment; + FT_UInt ExtendedShapeCoverage, MathKernInfo; + + + OTV_NAME_ENTER( "MathGlyphInfo" ); + + OTV_LIMIT_CHECK( 8 ); + + MathItalicsCorrectionInfo = FT_NEXT_USHORT( p ); + MathTopAccentAttachment = FT_NEXT_USHORT( p ); + ExtendedShapeCoverage = FT_NEXT_USHORT( p ); + MathKernInfo = FT_NEXT_USHORT( p ); + + if ( MathItalicsCorrectionInfo ) + otv_MathItalicsCorrectionInfo_validate( + table + MathItalicsCorrectionInfo, valid, TRUE ); + + /* Italic correction and Top Accent Attachment have the same format */ + if ( MathTopAccentAttachment ) + otv_MathItalicsCorrectionInfo_validate( + table + MathTopAccentAttachment, valid, FALSE ); + + if ( ExtendedShapeCoverage ) { + OTV_NAME_ENTER( "ExtendedShapeCoverage" ); + otv_Coverage_validate( table + ExtendedShapeCoverage, valid, -1 ); + OTV_EXIT; + } + + if ( MathKernInfo ) + otv_MathKernInfo_validate( table + MathKernInfo, valid ); + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** MATH GLYPH CONSTRUCTION *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + otv_GlyphAssembly_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt pcnt, table_size; + FT_UInt i; + + OTV_OPTIONAL_TABLE( DeviceTableOffset ); + + + /* OTV_NAME_ENTER( "GlyphAssembly" ); */ + + OTV_LIMIT_CHECK( 6 ); + + p += 2; /* Skip the Italics Correction value */ + OTV_OPTIONAL_OFFSET( DeviceTableOffset ); + pcnt = FT_NEXT_USHORT( p ); + + OTV_LIMIT_CHECK( 8 * pcnt ); + table_size = 6 + 8 * pcnt; + + OTV_SIZE_CHECK( DeviceTableOffset ); + if ( DeviceTableOffset ) + otv_Device_validate( table + DeviceTableOffset, valid ); + + for ( i = 0; i < pcnt; ++i ) + { + FT_UInt gid; + + + gid = FT_NEXT_USHORT( p ); + if ( gid >= valid->glyph_count ) + FT_INVALID_GLYPH_ID; + p += 2*4; /* skip the Start, End, Full, and Flags fields */ + } + + /* OTV_EXIT; */ + } + + + static void + otv_MathGlyphConstruction_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt vcnt, table_size; + FT_UInt i; + + OTV_OPTIONAL_TABLE( GlyphAssembly ); + + + /* OTV_NAME_ENTER( "MathGlyphConstruction" ); */ + + OTV_LIMIT_CHECK( 4 ); + + OTV_OPTIONAL_OFFSET( GlyphAssembly ); + vcnt = FT_NEXT_USHORT( p ); + + OTV_LIMIT_CHECK( 4 * vcnt ); + table_size = 4 + 4 * vcnt; + + for ( i = 0; i < vcnt; ++i ) + { + FT_UInt gid; + + + gid = FT_NEXT_USHORT( p ); + if ( gid >= valid->glyph_count ) + FT_INVALID_GLYPH_ID; + p += 2; /* skip the size */ + } + + OTV_SIZE_CHECK( GlyphAssembly ); + if ( GlyphAssembly ) + otv_GlyphAssembly_validate( table+GlyphAssembly, valid ); + + /* OTV_EXIT; */ + } + + + static void + otv_MathVariants_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt vcnt, hcnt, i, table_size; + + OTV_OPTIONAL_TABLE( VCoverage ); + OTV_OPTIONAL_TABLE( HCoverage ); + OTV_OPTIONAL_TABLE( Offset ); + + + OTV_NAME_ENTER( "MathVariants" ); + + OTV_LIMIT_CHECK( 10 ); + + p += 2; /* Skip the MinConnectorOverlap constant */ + OTV_OPTIONAL_OFFSET( VCoverage ); + OTV_OPTIONAL_OFFSET( HCoverage ); + vcnt = FT_NEXT_USHORT( p ); + hcnt = FT_NEXT_USHORT( p ); + + OTV_LIMIT_CHECK( 2 * vcnt + 2 * hcnt ); + table_size = 10 + 2 * vcnt + 2 * hcnt; + + OTV_SIZE_CHECK( VCoverage ); + if ( VCoverage ) + otv_Coverage_validate( table + VCoverage, valid, vcnt ); + + OTV_SIZE_CHECK( HCoverage ); + if ( HCoverage ) + otv_Coverage_validate( table + HCoverage, valid, hcnt ); + + for ( i = 0; i < vcnt; ++i ) + { + OTV_OPTIONAL_OFFSET( Offset ); + OTV_SIZE_CHECK( Offset ); + otv_MathGlyphConstruction_validate( table + Offset, valid ); + } + + for ( i = 0; i < hcnt; ++i ) + { + OTV_OPTIONAL_OFFSET( Offset ); + OTV_SIZE_CHECK( Offset ); + otv_MathGlyphConstruction_validate( table + Offset, valid ); + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** MATH TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* sets valid->glyph_count */ + + FT_LOCAL_DEF( void ) + otv_MATH_validate( FT_Bytes table, + FT_UInt glyph_count, + FT_Validator ftvalid ) + { + OTV_ValidatorRec validrec; + OTV_Validator valid = &validrec; + FT_Bytes p = table; + FT_UInt MathConstants, MathGlyphInfo, MathVariants; + + + valid->root = ftvalid; + + FT_TRACE3(( "validating MATH table\n" )); + OTV_INIT; + + OTV_LIMIT_CHECK( 10 ); + + if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */ + FT_INVALID_FORMAT; + + MathConstants = FT_NEXT_USHORT( p ); + MathGlyphInfo = FT_NEXT_USHORT( p ); + MathVariants = FT_NEXT_USHORT( p ); + + valid->glyph_count = glyph_count; + + otv_MathConstants_validate( table + MathConstants, + valid ); + otv_MathGlyphInfo_validate( table + MathGlyphInfo, + valid ); + otv_MathVariants_validate ( table + MathVariants, + valid ); + + FT_TRACE4(( "\n" )); + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/otvalid/otvmod.c b/mod/pub.mod/freetype.mod/src/otvalid/otvmod.c new file mode 100644 index 0000000..3248564 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/otvalid/otvmod.c @@ -0,0 +1,280 @@ +/***************************************************************************/ +/* */ +/* otvmod.c */ +/* */ +/* FreeType's OpenType validation module implementation (body). */ +/* */ +/* Copyright 2004, 2005, 2006, 2007, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_TRUETYPE_TABLES_H +#include FT_TRUETYPE_TAGS_H +#include FT_OPENTYPE_VALIDATE_H +#include FT_INTERNAL_OBJECTS_H +#include FT_SERVICE_OPENTYPE_VALIDATE_H + +#include "otvmod.h" +#include "otvalid.h" +#include "otvcommn.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_otvmodule + + + static FT_Error + otv_load_table( FT_Face face, + FT_Tag tag, + FT_Byte* volatile* table, + FT_ULong* table_len ) + { + FT_Error error; + FT_Memory memory = FT_FACE_MEMORY( face ); + + + error = FT_Load_Sfnt_Table( face, tag, 0, NULL, table_len ); + if ( error == OTV_Err_Table_Missing ) + return OTV_Err_Ok; + if ( error ) + goto Exit; + + if ( FT_ALLOC( *table, *table_len ) ) + goto Exit; + + error = FT_Load_Sfnt_Table( face, tag, 0, *table, table_len ); + + Exit: + return error; + } + + + static FT_Error + otv_validate( FT_Face volatile face, + FT_UInt ot_flags, + FT_Bytes *ot_base, + FT_Bytes *ot_gdef, + FT_Bytes *ot_gpos, + FT_Bytes *ot_gsub, + FT_Bytes *ot_jstf ) + { + FT_Error error = OTV_Err_Ok; + FT_Byte* volatile base; + FT_Byte* volatile gdef; + FT_Byte* volatile gpos; + FT_Byte* volatile gsub; + FT_Byte* volatile jstf; + FT_Byte* volatile math; + FT_ULong len_base, len_gdef, len_gpos, len_gsub, len_jstf; + FT_ULong len_math; + FT_UInt num_glyphs = (FT_UInt)face->num_glyphs; + FT_ValidatorRec volatile valid; + + + base = gdef = gpos = gsub = jstf = math = NULL; + len_base = len_gdef = len_gpos = len_gsub = len_jstf = len_math = 0; + + /* + * XXX: OpenType tables cannot handle 32-bit glyph index, + * although broken TrueType can have 32-bit glyph index. + */ + if ( face->num_glyphs > 0xFFFFL ) + { + FT_TRACE1(( "otv_validate: Invalid glyphs index (0x0000FFFF - 0x%08x) ", + face->num_glyphs )); + FT_TRACE1(( "are not handled by OpenType tables\n" )); + num_glyphs = 0xFFFF; + } + + /* load tables */ + + if ( ot_flags & FT_VALIDATE_BASE ) + { + error = otv_load_table( face, TTAG_BASE, &base, &len_base ); + if ( error ) + goto Exit; + } + + if ( ot_flags & FT_VALIDATE_GDEF ) + { + error = otv_load_table( face, TTAG_GDEF, &gdef, &len_gdef ); + if ( error ) + goto Exit; + } + + if ( ot_flags & FT_VALIDATE_GPOS ) + { + error = otv_load_table( face, TTAG_GPOS, &gpos, &len_gpos ); + if ( error ) + goto Exit; + } + + if ( ot_flags & FT_VALIDATE_GSUB ) + { + error = otv_load_table( face, TTAG_GSUB, &gsub, &len_gsub ); + if ( error ) + goto Exit; + } + + if ( ot_flags & FT_VALIDATE_JSTF ) + { + error = otv_load_table( face, TTAG_JSTF, &jstf, &len_jstf ); + if ( error ) + goto Exit; + } + + if ( ot_flags & FT_VALIDATE_MATH ) + { + error = otv_load_table( face, TTAG_MATH, &math, &len_math ); + if ( error ) + goto Exit; + } + + /* validate tables */ + + if ( base ) + { + ft_validator_init( &valid, base, base + len_base, FT_VALIDATE_DEFAULT ); + if ( ft_setjmp( valid.jump_buffer ) == 0 ) + otv_BASE_validate( base, &valid ); + error = valid.error; + if ( error ) + goto Exit; + } + + if ( gpos ) + { + ft_validator_init( &valid, gpos, gpos + len_gpos, FT_VALIDATE_DEFAULT ); + if ( ft_setjmp( valid.jump_buffer ) == 0 ) + otv_GPOS_validate( gpos, num_glyphs, &valid ); + error = valid.error; + if ( error ) + goto Exit; + } + + if ( gsub ) + { + ft_validator_init( &valid, gsub, gsub + len_gsub, FT_VALIDATE_DEFAULT ); + if ( ft_setjmp( valid.jump_buffer ) == 0 ) + otv_GSUB_validate( gsub, num_glyphs, &valid ); + error = valid.error; + if ( error ) + goto Exit; + } + + if ( gdef ) + { + ft_validator_init( &valid, gdef, gdef + len_gdef, FT_VALIDATE_DEFAULT ); + if ( ft_setjmp( valid.jump_buffer ) == 0 ) + otv_GDEF_validate( gdef, gsub, gpos, num_glyphs, &valid ); + error = valid.error; + if ( error ) + goto Exit; + } + + if ( jstf ) + { + ft_validator_init( &valid, jstf, jstf + len_jstf, FT_VALIDATE_DEFAULT ); + if ( ft_setjmp( valid.jump_buffer ) == 0 ) + otv_JSTF_validate( jstf, gsub, gpos, num_glyphs, &valid ); + error = valid.error; + if ( error ) + goto Exit; + } + + if ( math ) + { + ft_validator_init( &valid, math, math + len_math, FT_VALIDATE_DEFAULT ); + if ( ft_setjmp( valid.jump_buffer ) == 0 ) + otv_MATH_validate( math, num_glyphs, &valid ); + error = valid.error; + if ( error ) + goto Exit; + } + + *ot_base = (FT_Bytes)base; + *ot_gdef = (FT_Bytes)gdef; + *ot_gpos = (FT_Bytes)gpos; + *ot_gsub = (FT_Bytes)gsub; + *ot_jstf = (FT_Bytes)jstf; + + Exit: + if ( error ) { + FT_Memory memory = FT_FACE_MEMORY( face ); + + + FT_FREE( base ); + FT_FREE( gdef ); + FT_FREE( gpos ); + FT_FREE( gsub ); + FT_FREE( jstf ); + } + { + FT_Memory memory = FT_FACE_MEMORY( face ); + + + FT_FREE( math ); /* Can't return this as API is frozen */ + } + + return error; + } + + + static + const FT_Service_OTvalidateRec otvalid_interface = + { + otv_validate + }; + + + static + const FT_ServiceDescRec otvalid_services[] = + { + { FT_SERVICE_ID_OPENTYPE_VALIDATE, &otvalid_interface }, + { NULL, NULL } + }; + + + static FT_Pointer + otvalid_get_service( FT_Module module, + const char* service_id ) + { + FT_UNUSED( module ); + + return ft_service_list_lookup( otvalid_services, service_id ); + } + + + FT_CALLBACK_TABLE_DEF + const FT_Module_Class otv_module_class = + { + 0, + sizeof( FT_ModuleRec ), + "otvalid", + 0x10000L, + 0x20000L, + + 0, /* module-specific interface */ + + (FT_Module_Constructor)0, + (FT_Module_Destructor) 0, + (FT_Module_Requester) otvalid_get_service + }; + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/otvalid/otvmod.h b/mod/pub.mod/freetype.mod/src/otvalid/otvmod.h new file mode 100644 index 0000000..573b2a0 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/otvalid/otvmod.h @@ -0,0 +1,43 @@ +/***************************************************************************/ +/* */ +/* otvmod.h */ +/* */ +/* FreeType's OpenType validation module implementation */ +/* (specification). */ +/* */ +/* Copyright 2004 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __OTVMOD_H__ +#define __OTVMOD_H__ + + +#include <ft2build.h> +#include FT_MODULE_H + + +FT_BEGIN_HEADER + +#ifdef FT_CONFIG_OPTION_PIC +#error "this module does not support PIC yet" +#endif + + + FT_EXPORT_VAR( const FT_Module_Class ) otv_module_class; + + +FT_END_HEADER + +#endif /* __OTVMOD_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/pcf/pcf.c b/mod/pub.mod/freetype.mod/src/pcf/pcf.c new file mode 100644 index 0000000..11d5b7b --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/pcf/pcf.c @@ -0,0 +1,36 @@ +/* pcf.c + + FreeType font driver for pcf fonts + + Copyright 2000-2001, 2003 by + Francesco Zappa Nardelli + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + + +#define FT_MAKE_OPTION_SINGLE_OBJECT + + +#include <ft2build.h> +#include "pcfutil.c" +#include "pcfread.c" +#include "pcfdrivr.c" + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/pcf/pcf.h b/mod/pub.mod/freetype.mod/src/pcf/pcf.h new file mode 100644 index 0000000..1cd56c1 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/pcf/pcf.h @@ -0,0 +1,237 @@ +/* pcf.h + + FreeType font driver for pcf fonts + + Copyright (C) 2000, 2001, 2002, 2003, 2006 by + Francesco Zappa Nardelli + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + + +#ifndef __PCF_H__ +#define __PCF_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_DRIVER_H +#include FT_INTERNAL_STREAM_H + + +FT_BEGIN_HEADER + + typedef struct PCF_TableRec_ + { + FT_ULong type; + FT_ULong format; + FT_ULong size; + FT_ULong offset; + + } PCF_TableRec, *PCF_Table; + + + typedef struct PCF_TocRec_ + { + FT_ULong version; + FT_ULong count; + PCF_Table tables; + + } PCF_TocRec, *PCF_Toc; + + + typedef struct PCF_ParsePropertyRec_ + { + FT_Long name; + FT_Byte isString; + FT_Long value; + + } PCF_ParsePropertyRec, *PCF_ParseProperty; + + + typedef struct PCF_PropertyRec_ + { + FT_String* name; + FT_Byte isString; + + union + { + FT_String* atom; + FT_Long l; + FT_ULong ul; + + } value; + + } PCF_PropertyRec, *PCF_Property; + + + typedef struct PCF_Compressed_MetricRec_ + { + FT_Byte leftSideBearing; + FT_Byte rightSideBearing; + FT_Byte characterWidth; + FT_Byte ascent; + FT_Byte descent; + + } PCF_Compressed_MetricRec, *PCF_Compressed_Metric; + + + typedef struct PCF_MetricRec_ + { + FT_Short leftSideBearing; + FT_Short rightSideBearing; + FT_Short characterWidth; + FT_Short ascent; + FT_Short descent; + FT_Short attributes; + FT_ULong bits; + + } PCF_MetricRec, *PCF_Metric; + + + typedef struct PCF_AccelRec_ + { + FT_Byte noOverlap; + FT_Byte constantMetrics; + FT_Byte terminalFont; + FT_Byte constantWidth; + FT_Byte inkInside; + FT_Byte inkMetrics; + FT_Byte drawDirection; + FT_Long fontAscent; + FT_Long fontDescent; + FT_Long maxOverlap; + PCF_MetricRec minbounds; + PCF_MetricRec maxbounds; + PCF_MetricRec ink_minbounds; + PCF_MetricRec ink_maxbounds; + + } PCF_AccelRec, *PCF_Accel; + + + typedef struct PCF_EncodingRec_ + { + FT_Long enc; + FT_UShort glyph; + + } PCF_EncodingRec, *PCF_Encoding; + + + typedef struct PCF_FaceRec_ + { + FT_FaceRec root; + + FT_StreamRec gzip_stream; + FT_Stream gzip_source; + + char* charset_encoding; + char* charset_registry; + + PCF_TocRec toc; + PCF_AccelRec accel; + + int nprops; + PCF_Property properties; + + FT_Long nmetrics; + PCF_Metric metrics; + FT_Long nencodings; + PCF_Encoding encodings; + + FT_Short defaultChar; + + FT_ULong bitmapsFormat; + + FT_CharMap charmap_handle; + FT_CharMapRec charmap; /* a single charmap per face */ + + } PCF_FaceRec, *PCF_Face; + + + /* macros for pcf font format */ + +#define LSBFirst 0 +#define MSBFirst 1 + +#define PCF_FILE_VERSION ( ( 'p' << 24 ) | \ + ( 'c' << 16 ) | \ + ( 'f' << 8 ) | 1 ) +#define PCF_FORMAT_MASK 0xFFFFFF00UL + +#define PCF_DEFAULT_FORMAT 0x00000000UL +#define PCF_INKBOUNDS 0x00000200UL +#define PCF_ACCEL_W_INKBOUNDS 0x00000100UL +#define PCF_COMPRESSED_METRICS 0x00000100UL + +#define PCF_FORMAT_MATCH( a, b ) \ + ( ( (a) & PCF_FORMAT_MASK ) == ( (b) & PCF_FORMAT_MASK ) ) + +#define PCF_GLYPH_PAD_MASK ( 3 << 0 ) +#define PCF_BYTE_MASK ( 1 << 2 ) +#define PCF_BIT_MASK ( 1 << 3 ) +#define PCF_SCAN_UNIT_MASK ( 3 << 4 ) + +#define PCF_BYTE_ORDER( f ) \ + ( ( (f) & PCF_BYTE_MASK ) ? MSBFirst : LSBFirst ) +#define PCF_BIT_ORDER( f ) \ + ( ( (f) & PCF_BIT_MASK ) ? MSBFirst : LSBFirst ) +#define PCF_GLYPH_PAD_INDEX( f ) \ + ( (f) & PCF_GLYPH_PAD_MASK ) +#define PCF_GLYPH_PAD( f ) \ + ( 1 << PCF_GLYPH_PAD_INDEX( f ) ) +#define PCF_SCAN_UNIT_INDEX( f ) \ + ( ( (f) & PCF_SCAN_UNIT_MASK ) >> 4 ) +#define PCF_SCAN_UNIT( f ) \ + ( 1 << PCF_SCAN_UNIT_INDEX( f ) ) +#define PCF_FORMAT_BITS( f ) \ + ( (f) & ( PCF_GLYPH_PAD_MASK | \ + PCF_BYTE_MASK | \ + PCF_BIT_MASK | \ + PCF_SCAN_UNIT_MASK ) ) + +#define PCF_SIZE_TO_INDEX( s ) ( (s) == 4 ? 2 : (s) == 2 ? 1 : 0 ) +#define PCF_INDEX_TO_SIZE( b ) ( 1 << b ) + +#define PCF_FORMAT( bit, byte, glyph, scan ) \ + ( ( PCF_SIZE_TO_INDEX( scan ) << 4 ) | \ + ( ( (bit) == MSBFirst ? 1 : 0 ) << 3 ) | \ + ( ( (byte) == MSBFirst ? 1 : 0 ) << 2 ) | \ + ( PCF_SIZE_TO_INDEX( glyph ) << 0 ) ) + +#define PCF_PROPERTIES ( 1 << 0 ) +#define PCF_ACCELERATORS ( 1 << 1 ) +#define PCF_METRICS ( 1 << 2 ) +#define PCF_BITMAPS ( 1 << 3 ) +#define PCF_INK_METRICS ( 1 << 4 ) +#define PCF_BDF_ENCODINGS ( 1 << 5 ) +#define PCF_SWIDTHS ( 1 << 6 ) +#define PCF_GLYPH_NAMES ( 1 << 7 ) +#define PCF_BDF_ACCELERATORS ( 1 << 8 ) + +#define GLYPHPADOPTIONS 4 /* I'm not sure about this */ + + FT_LOCAL( FT_Error ) + pcf_load_font( FT_Stream, + PCF_Face ); + +FT_END_HEADER + +#endif /* __PCF_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/pcf/pcfdrivr.c b/mod/pub.mod/freetype.mod/src/pcf/pcfdrivr.c new file mode 100644 index 0000000..b34e542 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/pcf/pcfdrivr.c @@ -0,0 +1,695 @@ +/* pcfdrivr.c + + FreeType font driver for pcf files + + Copyright (C) 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009 by + Francesco Zappa Nardelli + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + + +#include <ft2build.h> + +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_OBJECTS_H +#include FT_GZIP_H +#include FT_LZW_H +#include FT_ERRORS_H +#include FT_BDF_H + +#include "pcf.h" +#include "pcfdrivr.h" +#include "pcfread.h" + +#include "pcferror.h" +#include "pcfutil.h" + +#undef FT_COMPONENT +#define FT_COMPONENT trace_pcfread + +#include FT_SERVICE_BDF_H +#include FT_SERVICE_XFREE86_NAME_H + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_pcfdriver + + + typedef struct PCF_CMapRec_ + { + FT_CMapRec root; + FT_UInt num_encodings; + PCF_Encoding encodings; + + } PCF_CMapRec, *PCF_CMap; + + + FT_CALLBACK_DEF( FT_Error ) + pcf_cmap_init( FT_CMap pcfcmap, /* PCF_CMap */ + FT_Pointer init_data ) + { + PCF_CMap cmap = (PCF_CMap)pcfcmap; + PCF_Face face = (PCF_Face)FT_CMAP_FACE( pcfcmap ); + + FT_UNUSED( init_data ); + + + cmap->num_encodings = (FT_UInt)face->nencodings; + cmap->encodings = face->encodings; + + return PCF_Err_Ok; + } + + + FT_CALLBACK_DEF( void ) + pcf_cmap_done( FT_CMap pcfcmap ) /* PCF_CMap */ + { + PCF_CMap cmap = (PCF_CMap)pcfcmap; + + + cmap->encodings = NULL; + cmap->num_encodings = 0; + } + + + FT_CALLBACK_DEF( FT_UInt ) + pcf_cmap_char_index( FT_CMap pcfcmap, /* PCF_CMap */ + FT_UInt32 charcode ) + { + PCF_CMap cmap = (PCF_CMap)pcfcmap; + PCF_Encoding encodings = cmap->encodings; + FT_UInt min, max, mid; + FT_UInt result = 0; + + + min = 0; + max = cmap->num_encodings; + + while ( min < max ) + { + FT_ULong code; + + + mid = ( min + max ) >> 1; + code = encodings[mid].enc; + + if ( charcode == code ) + { + result = encodings[mid].glyph + 1; + break; + } + + if ( charcode < code ) + max = mid; + else + min = mid + 1; + } + + return result; + } + + + FT_CALLBACK_DEF( FT_UInt ) + pcf_cmap_char_next( FT_CMap pcfcmap, /* PCF_CMap */ + FT_UInt32 *acharcode ) + { + PCF_CMap cmap = (PCF_CMap)pcfcmap; + PCF_Encoding encodings = cmap->encodings; + FT_UInt min, max, mid; + FT_ULong charcode = *acharcode + 1; + FT_UInt result = 0; + + + min = 0; + max = cmap->num_encodings; + + while ( min < max ) + { + FT_ULong code; + + + mid = ( min + max ) >> 1; + code = encodings[mid].enc; + + if ( charcode == code ) + { + result = encodings[mid].glyph + 1; + goto Exit; + } + + if ( charcode < code ) + max = mid; + else + min = mid + 1; + } + + charcode = 0; + if ( min < cmap->num_encodings ) + { + charcode = encodings[min].enc; + result = encodings[min].glyph + 1; + } + + Exit: + if ( charcode > 0xFFFFFFFFUL ) + { + FT_TRACE1(( "pcf_cmap_char_next: charcode 0x%x > 32bit API" )); + *acharcode = 0; + /* XXX: result should be changed to indicate an overflow error */ + } + else + *acharcode = (FT_UInt32)charcode; + return result; + } + + + FT_CALLBACK_TABLE_DEF + const FT_CMap_ClassRec pcf_cmap_class = + { + sizeof ( PCF_CMapRec ), + pcf_cmap_init, + pcf_cmap_done, + pcf_cmap_char_index, + pcf_cmap_char_next, + + NULL, NULL, NULL, NULL, NULL + }; + + + FT_CALLBACK_DEF( void ) + PCF_Face_Done( FT_Face pcfface ) /* PCF_Face */ + { + PCF_Face face = (PCF_Face)pcfface; + FT_Memory memory; + + + if ( !face ) + return; + + memory = FT_FACE_MEMORY( face ); + + FT_FREE( face->encodings ); + FT_FREE( face->metrics ); + + /* free properties */ + { + PCF_Property prop; + FT_Int i; + + + if ( face->properties ) + { + for ( i = 0; i < face->nprops; i++ ) + { + prop = &face->properties[i]; + + if ( prop ) { + FT_FREE( prop->name ); + if ( prop->isString ) + FT_FREE( prop->value.atom ); + } + } + } + FT_FREE( face->properties ); + } + + FT_FREE( face->toc.tables ); + FT_FREE( pcfface->family_name ); + FT_FREE( pcfface->style_name ); + FT_FREE( pcfface->available_sizes ); + FT_FREE( face->charset_encoding ); + FT_FREE( face->charset_registry ); + + FT_TRACE4(( "PCF_Face_Done: done face\n" )); + + /* close gzip/LZW stream if any */ + if ( pcfface->stream == &face->gzip_stream ) + { + FT_Stream_Close( &face->gzip_stream ); + pcfface->stream = face->gzip_source; + } + } + + + FT_CALLBACK_DEF( FT_Error ) + PCF_Face_Init( FT_Stream stream, + FT_Face pcfface, /* PCF_Face */ + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ) + { + PCF_Face face = (PCF_Face)pcfface; + FT_Error error = PCF_Err_Ok; + + FT_UNUSED( num_params ); + FT_UNUSED( params ); + FT_UNUSED( face_index ); + + + error = pcf_load_font( stream, face ); + if ( error ) + { + PCF_Face_Done( pcfface ); + +#if defined( FT_CONFIG_OPTION_USE_ZLIB ) || \ + defined( FT_CONFIG_OPTION_USE_LZW ) + +#ifdef FT_CONFIG_OPTION_USE_ZLIB + { + FT_Error error2; + + + /* this didn't work, try gzip support! */ + error2 = FT_Stream_OpenGzip( &face->gzip_stream, stream ); + if ( FT_ERROR_BASE( error2 ) == FT_Err_Unimplemented_Feature ) + goto Fail; + + error = error2; + } +#endif /* FT_CONFIG_OPTION_USE_ZLIB */ + +#ifdef FT_CONFIG_OPTION_USE_LZW + if ( error ) + { + FT_Error error3; + + + /* this didn't work, try LZW support! */ + error3 = FT_Stream_OpenLZW( &face->gzip_stream, stream ); + if ( FT_ERROR_BASE( error3 ) == FT_Err_Unimplemented_Feature ) + goto Fail; + + error = error3; + } +#endif /* FT_CONFIG_OPTION_USE_LZW */ + + if ( error ) + goto Fail; + + face->gzip_source = stream; + pcfface->stream = &face->gzip_stream; + + stream = pcfface->stream; + + error = pcf_load_font( stream, face ); + if ( error ) + goto Fail; + +#else /* !(FT_CONFIG_OPTION_USE_ZLIB || FT_CONFIG_OPTION_USE_LZW) */ + + goto Fail; + +#endif + } + + /* set up charmap */ + { + FT_String *charset_registry = face->charset_registry; + FT_String *charset_encoding = face->charset_encoding; + FT_Bool unicode_charmap = 0; + + + if ( charset_registry && charset_encoding ) + { + char* s = charset_registry; + + + /* Uh, oh, compare first letters manually to avoid dependency + on locales. */ + if ( ( s[0] == 'i' || s[0] == 'I' ) && + ( s[1] == 's' || s[1] == 'S' ) && + ( s[2] == 'o' || s[2] == 'O' ) ) + { + s += 3; + if ( !ft_strcmp( s, "10646" ) || + ( !ft_strcmp( s, "8859" ) && + !ft_strcmp( face->charset_encoding, "1" ) ) ) + unicode_charmap = 1; + } + } + + { + FT_CharMapRec charmap; + + + charmap.face = FT_FACE( face ); + charmap.encoding = FT_ENCODING_NONE; + charmap.platform_id = 0; + charmap.encoding_id = 0; + + if ( unicode_charmap ) + { + charmap.encoding = FT_ENCODING_UNICODE; + charmap.platform_id = 3; + charmap.encoding_id = 1; + } + + error = FT_CMap_New( &pcf_cmap_class, NULL, &charmap, NULL ); + +#if 0 + /* Select default charmap */ + if ( pcfface->num_charmaps ) + pcfface->charmap = pcfface->charmaps[0]; +#endif + } + } + + Exit: + return error; + + Fail: + FT_TRACE2(( "[not a valid PCF file]\n" )); + PCF_Face_Done( pcfface ); + error = PCF_Err_Unknown_File_Format; /* error */ + goto Exit; + } + + + FT_CALLBACK_DEF( FT_Error ) + PCF_Size_Select( FT_Size size, + FT_ULong strike_index ) + { + PCF_Accel accel = &( (PCF_Face)size->face )->accel; + + + FT_Select_Metrics( size->face, strike_index ); + + size->metrics.ascender = accel->fontAscent << 6; + size->metrics.descender = -accel->fontDescent << 6; + size->metrics.max_advance = accel->maxbounds.characterWidth << 6; + + return PCF_Err_Ok; + } + + + FT_CALLBACK_DEF( FT_Error ) + PCF_Size_Request( FT_Size size, + FT_Size_Request req ) + { + PCF_Face face = (PCF_Face)size->face; + FT_Bitmap_Size* bsize = size->face->available_sizes; + FT_Error error = PCF_Err_Invalid_Pixel_Size; + FT_Long height; + + + height = FT_REQUEST_HEIGHT( req ); + height = ( height + 32 ) >> 6; + + switch ( req->type ) + { + case FT_SIZE_REQUEST_TYPE_NOMINAL: + if ( height == ( ( bsize->y_ppem + 32 ) >> 6 ) ) + error = PCF_Err_Ok; + break; + + case FT_SIZE_REQUEST_TYPE_REAL_DIM: + if ( height == ( face->accel.fontAscent + + face->accel.fontDescent ) ) + error = PCF_Err_Ok; + break; + + default: + error = PCF_Err_Unimplemented_Feature; + break; + } + + if ( error ) + return error; + else + return PCF_Size_Select( size, 0 ); + } + + + FT_CALLBACK_DEF( FT_Error ) + PCF_Glyph_Load( FT_GlyphSlot slot, + FT_Size size, + FT_UInt glyph_index, + FT_Int32 load_flags ) + { + PCF_Face face = (PCF_Face)FT_SIZE_FACE( size ); + FT_Stream stream; + FT_Error error = PCF_Err_Ok; + FT_Bitmap* bitmap = &slot->bitmap; + PCF_Metric metric; + FT_Offset bytes; + + FT_UNUSED( load_flags ); + + + FT_TRACE4(( "load_glyph %d ---", glyph_index )); + + if ( !face || glyph_index >= (FT_UInt)face->root.num_glyphs ) + { + error = PCF_Err_Invalid_Argument; + goto Exit; + } + + stream = face->root.stream; + + if ( glyph_index > 0 ) + glyph_index--; + + metric = face->metrics + glyph_index; + + bitmap->rows = metric->ascent + metric->descent; + bitmap->width = metric->rightSideBearing - metric->leftSideBearing; + bitmap->num_grays = 1; + bitmap->pixel_mode = FT_PIXEL_MODE_MONO; + + FT_TRACE6(( "BIT_ORDER %d ; BYTE_ORDER %d ; GLYPH_PAD %d\n", + PCF_BIT_ORDER( face->bitmapsFormat ), + PCF_BYTE_ORDER( face->bitmapsFormat ), + PCF_GLYPH_PAD( face->bitmapsFormat ) )); + + switch ( PCF_GLYPH_PAD( face->bitmapsFormat ) ) + { + case 1: + bitmap->pitch = ( bitmap->width + 7 ) >> 3; + break; + + case 2: + bitmap->pitch = ( ( bitmap->width + 15 ) >> 4 ) << 1; + break; + + case 4: + bitmap->pitch = ( ( bitmap->width + 31 ) >> 5 ) << 2; + break; + + case 8: + bitmap->pitch = ( ( bitmap->width + 63 ) >> 6 ) << 3; + break; + + default: + return PCF_Err_Invalid_File_Format; + } + + /* XXX: to do: are there cases that need repadding the bitmap? */ + bytes = bitmap->pitch * bitmap->rows; + + error = ft_glyphslot_alloc_bitmap( slot, bytes ); + if ( error ) + goto Exit; + + if ( FT_STREAM_SEEK( metric->bits ) || + FT_STREAM_READ( bitmap->buffer, bytes ) ) + goto Exit; + + if ( PCF_BIT_ORDER( face->bitmapsFormat ) != MSBFirst ) + BitOrderInvert( bitmap->buffer, bytes ); + + if ( ( PCF_BYTE_ORDER( face->bitmapsFormat ) != + PCF_BIT_ORDER( face->bitmapsFormat ) ) ) + { + switch ( PCF_SCAN_UNIT( face->bitmapsFormat ) ) + { + case 1: + break; + + case 2: + TwoByteSwap( bitmap->buffer, bytes ); + break; + + case 4: + FourByteSwap( bitmap->buffer, bytes ); + break; + } + } + + slot->format = FT_GLYPH_FORMAT_BITMAP; + slot->bitmap_left = metric->leftSideBearing; + slot->bitmap_top = metric->ascent; + + slot->metrics.horiAdvance = metric->characterWidth << 6; + slot->metrics.horiBearingX = metric->leftSideBearing << 6; + slot->metrics.horiBearingY = metric->ascent << 6; + slot->metrics.width = ( metric->rightSideBearing - + metric->leftSideBearing ) << 6; + slot->metrics.height = bitmap->rows << 6; + + ft_synthesize_vertical_metrics( &slot->metrics, + ( face->accel.fontAscent + + face->accel.fontDescent ) << 6 ); + + FT_TRACE4(( " --- ok\n" )); + + Exit: + return error; + } + + + /* + * + * BDF SERVICE + * + */ + + static FT_Error + pcf_get_bdf_property( PCF_Face face, + const char* prop_name, + BDF_PropertyRec *aproperty ) + { + PCF_Property prop; + + + prop = pcf_find_property( face, prop_name ); + if ( prop != NULL ) + { + if ( prop->isString ) + { + aproperty->type = BDF_PROPERTY_TYPE_ATOM; + aproperty->u.atom = prop->value.atom; + } + else + { + if ( prop->value.l > 0x7FFFFFFFL || prop->value.l < ( -1 - 0x7FFFFFFFL ) ) + { + FT_TRACE1(( "pcf_get_bdf_property: " )); + FT_TRACE1(( "too large integer 0x%x is truncated\n" )); + } + /* Apparently, the PCF driver loads all properties as signed integers! + * This really doesn't seem to be a problem, because this is + * sufficient for any meaningful values. + */ + aproperty->type = BDF_PROPERTY_TYPE_INTEGER; + aproperty->u.integer = (FT_Int32)prop->value.l; + } + return 0; + } + + return PCF_Err_Invalid_Argument; + } + + + static FT_Error + pcf_get_charset_id( PCF_Face face, + const char* *acharset_encoding, + const char* *acharset_registry ) + { + *acharset_encoding = face->charset_encoding; + *acharset_registry = face->charset_registry; + + return 0; + } + + + static const FT_Service_BDFRec pcf_service_bdf = + { + (FT_BDF_GetCharsetIdFunc)pcf_get_charset_id, + (FT_BDF_GetPropertyFunc) pcf_get_bdf_property + }; + + + /* + * + * SERVICE LIST + * + */ + + static const FT_ServiceDescRec pcf_services[] = + { + { FT_SERVICE_ID_BDF, &pcf_service_bdf }, + { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_PCF }, + { NULL, NULL } + }; + + + FT_CALLBACK_DEF( FT_Module_Interface ) + pcf_driver_requester( FT_Module module, + const char* name ) + { + FT_UNUSED( module ); + + return ft_service_list_lookup( pcf_services, name ); + } + + + FT_CALLBACK_TABLE_DEF + const FT_Driver_ClassRec pcf_driver_class = + { + { + FT_MODULE_FONT_DRIVER | + FT_MODULE_DRIVER_NO_OUTLINES, + sizeof ( FT_DriverRec ), + + "pcf", + 0x10000L, + 0x20000L, + + 0, + + 0, + 0, + pcf_driver_requester + }, + + sizeof ( PCF_FaceRec ), + sizeof ( FT_SizeRec ), + sizeof ( FT_GlyphSlotRec ), + + PCF_Face_Init, + PCF_Face_Done, + 0, /* FT_Size_InitFunc */ + 0, /* FT_Size_DoneFunc */ + 0, /* FT_Slot_InitFunc */ + 0, /* FT_Slot_DoneFunc */ + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + ft_stub_set_char_sizes, + ft_stub_set_pixel_sizes, +#endif + PCF_Glyph_Load, + + 0, /* FT_Face_GetKerningFunc */ + 0, /* FT_Face_AttachFunc */ + 0, /* FT_Face_GetAdvancesFunc */ + + PCF_Size_Request, + PCF_Size_Select + }; + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/pcf/pcfdrivr.h b/mod/pub.mod/freetype.mod/src/pcf/pcfdrivr.h new file mode 100644 index 0000000..a81d730 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/pcf/pcfdrivr.h @@ -0,0 +1,48 @@ +/* pcfdrivr.h + + FreeType font driver for pcf fonts + + Copyright 2000-2001, 2002 by + Francesco Zappa Nardelli + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + + +#ifndef __PCFDRIVR_H__ +#define __PCFDRIVR_H__ + +#include <ft2build.h> +#include FT_INTERNAL_DRIVER_H + +FT_BEGIN_HEADER + +#ifdef FT_CONFIG_OPTION_PIC +#error "this module does not support PIC yet" +#endif + + FT_EXPORT_VAR( const FT_Driver_ClassRec ) pcf_driver_class; + +FT_END_HEADER + + +#endif /* __PCFDRIVR_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/pcf/pcferror.h b/mod/pub.mod/freetype.mod/src/pcf/pcferror.h new file mode 100644 index 0000000..d75c067 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/pcf/pcferror.h @@ -0,0 +1,40 @@ +/***************************************************************************/ +/* */ +/* pcferror.h */ +/* */ +/* PCF error codes (specification only). */ +/* */ +/* Copyright 2001 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file is used to define the PCF error enumeration constants. */ + /* */ + /*************************************************************************/ + +#ifndef __PCFERROR_H__ +#define __PCFERROR_H__ + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#define FT_ERR_PREFIX PCF_Err_ +#define FT_ERR_BASE FT_Mod_Err_PCF + +#include FT_ERRORS_H + +#endif /* __PCFERROR_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/pcf/pcfread.c b/mod/pub.mod/freetype.mod/src/pcf/pcfread.c new file mode 100644 index 0000000..08becf9 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/pcf/pcfread.c @@ -0,0 +1,1274 @@ +/* pcfread.c + + FreeType font driver for pcf fonts + + Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by + Francesco Zappa Nardelli + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + + +#include <ft2build.h> + +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_OBJECTS_H + +#include "pcf.h" +#include "pcfread.h" + +#include "pcferror.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_pcfread + + +#ifdef FT_DEBUG_LEVEL_TRACE + static const char* const tableNames[] = + { + "prop", "accl", "mtrcs", "bmps", "imtrcs", + "enc", "swidth", "names", "accel" + }; +#endif + + + static + const FT_Frame_Field pcf_toc_header[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE PCF_TocRec + + FT_FRAME_START( 8 ), + FT_FRAME_ULONG_LE( version ), + FT_FRAME_ULONG_LE( count ), + FT_FRAME_END + }; + + + static + const FT_Frame_Field pcf_table_header[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE PCF_TableRec + + FT_FRAME_START( 16 ), + FT_FRAME_ULONG_LE( type ), + FT_FRAME_ULONG_LE( format ), + FT_FRAME_ULONG_LE( size ), + FT_FRAME_ULONG_LE( offset ), + FT_FRAME_END + }; + + + static FT_Error + pcf_read_TOC( FT_Stream stream, + PCF_Face face ) + { + FT_Error error; + PCF_Toc toc = &face->toc; + PCF_Table tables; + + FT_Memory memory = FT_FACE(face)->memory; + FT_UInt n; + + + if ( FT_STREAM_SEEK ( 0 ) || + FT_STREAM_READ_FIELDS ( pcf_toc_header, toc ) ) + return PCF_Err_Cannot_Open_Resource; + + if ( toc->version != PCF_FILE_VERSION || + toc->count > FT_ARRAY_MAX( face->toc.tables ) || + toc->count == 0 ) + return PCF_Err_Invalid_File_Format; + + if ( FT_NEW_ARRAY( face->toc.tables, toc->count ) ) + return PCF_Err_Out_Of_Memory; + + tables = face->toc.tables; + for ( n = 0; n < toc->count; n++ ) + { + if ( FT_STREAM_READ_FIELDS( pcf_table_header, tables ) ) + goto Exit; + tables++; + } + + /* Sort tables and check for overlaps. Because they are almost */ + /* always ordered already, an in-place bubble sort with simultaneous */ + /* boundary checking seems appropriate. */ + tables = face->toc.tables; + + for ( n = 0; n < toc->count - 1; n++ ) + { + FT_UInt i, have_change; + + + have_change = 0; + + for ( i = 0; i < toc->count - 1 - n; i++ ) + { + PCF_TableRec tmp; + + + if ( tables[i].offset > tables[i + 1].offset ) + { + tmp = tables[i]; + tables[i] = tables[i + 1]; + tables[i + 1] = tmp; + + have_change = 1; + } + + if ( ( tables[i].size > tables[i + 1].offset ) || + ( tables[i].offset > tables[i + 1].offset - tables[i].size ) ) + return PCF_Err_Invalid_Offset; + } + + if ( !have_change ) + break; + } + +#ifdef FT_DEBUG_LEVEL_TRACE + + { + FT_UInt i, j; + const char* name = "?"; + + + FT_TRACE4(( "pcf_read_TOC:\n" )); + + FT_TRACE4(( " number of tables: %ld\n", face->toc.count )); + + tables = face->toc.tables; + for ( i = 0; i < toc->count; i++ ) + { + for ( j = 0; j < sizeof ( tableNames ) / sizeof ( tableNames[0] ); + j++ ) + if ( tables[i].type == (FT_UInt)( 1 << j ) ) + name = tableNames[j]; + + FT_TRACE4(( " %d: type=%s, format=0x%X, " + "size=%ld (0x%lX), offset=%ld (0x%lX)\n", + i, name, + tables[i].format, + tables[i].size, tables[i].size, + tables[i].offset, tables[i].offset )); + } + } + +#endif + + return PCF_Err_Ok; + + Exit: + FT_FREE( face->toc.tables ); + return error; + } + + +#define PCF_METRIC_SIZE 12 + + static + const FT_Frame_Field pcf_metric_header[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE PCF_MetricRec + + FT_FRAME_START( PCF_METRIC_SIZE ), + FT_FRAME_SHORT_LE( leftSideBearing ), + FT_FRAME_SHORT_LE( rightSideBearing ), + FT_FRAME_SHORT_LE( characterWidth ), + FT_FRAME_SHORT_LE( ascent ), + FT_FRAME_SHORT_LE( descent ), + FT_FRAME_SHORT_LE( attributes ), + FT_FRAME_END + }; + + + static + const FT_Frame_Field pcf_metric_msb_header[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE PCF_MetricRec + + FT_FRAME_START( PCF_METRIC_SIZE ), + FT_FRAME_SHORT( leftSideBearing ), + FT_FRAME_SHORT( rightSideBearing ), + FT_FRAME_SHORT( characterWidth ), + FT_FRAME_SHORT( ascent ), + FT_FRAME_SHORT( descent ), + FT_FRAME_SHORT( attributes ), + FT_FRAME_END + }; + + +#define PCF_COMPRESSED_METRIC_SIZE 5 + + static + const FT_Frame_Field pcf_compressed_metric_header[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE PCF_Compressed_MetricRec + + FT_FRAME_START( PCF_COMPRESSED_METRIC_SIZE ), + FT_FRAME_BYTE( leftSideBearing ), + FT_FRAME_BYTE( rightSideBearing ), + FT_FRAME_BYTE( characterWidth ), + FT_FRAME_BYTE( ascent ), + FT_FRAME_BYTE( descent ), + FT_FRAME_END + }; + + + static FT_Error + pcf_get_metric( FT_Stream stream, + FT_ULong format, + PCF_Metric metric ) + { + FT_Error error = PCF_Err_Ok; + + + if ( PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) ) + { + const FT_Frame_Field* fields; + + + /* parsing normal metrics */ + fields = PCF_BYTE_ORDER( format ) == MSBFirst + ? pcf_metric_msb_header + : pcf_metric_header; + + /* the following sets `error' but doesn't return in case of failure */ + (void)FT_STREAM_READ_FIELDS( fields, metric ); + } + else + { + PCF_Compressed_MetricRec compr; + + + /* parsing compressed metrics */ + if ( FT_STREAM_READ_FIELDS( pcf_compressed_metric_header, &compr ) ) + goto Exit; + + metric->leftSideBearing = (FT_Short)( compr.leftSideBearing - 0x80 ); + metric->rightSideBearing = (FT_Short)( compr.rightSideBearing - 0x80 ); + metric->characterWidth = (FT_Short)( compr.characterWidth - 0x80 ); + metric->ascent = (FT_Short)( compr.ascent - 0x80 ); + metric->descent = (FT_Short)( compr.descent - 0x80 ); + metric->attributes = 0; + } + + Exit: + return error; + } + + + static FT_Error + pcf_seek_to_table_type( FT_Stream stream, + PCF_Table tables, + FT_ULong ntables, /* same as PCF_Toc->count */ + FT_ULong type, + FT_ULong *aformat, + FT_ULong *asize ) + { + FT_Error error = PCF_Err_Invalid_File_Format; + FT_ULong i; + + + for ( i = 0; i < ntables; i++ ) + if ( tables[i].type == type ) + { + if ( stream->pos > tables[i].offset ) + { + error = PCF_Err_Invalid_Stream_Skip; + goto Fail; + } + + if ( FT_STREAM_SKIP( tables[i].offset - stream->pos ) ) + { + error = PCF_Err_Invalid_Stream_Skip; + goto Fail; + } + + *asize = tables[i].size; + *aformat = tables[i].format; + + return PCF_Err_Ok; + } + + Fail: + *asize = 0; + return error; + } + + + static FT_Bool + pcf_has_table_type( PCF_Table tables, + FT_ULong ntables, /* same as PCF_Toc->count */ + FT_ULong type ) + { + FT_ULong i; + + + for ( i = 0; i < ntables; i++ ) + if ( tables[i].type == type ) + return TRUE; + + return FALSE; + } + + +#define PCF_PROPERTY_SIZE 9 + + static + const FT_Frame_Field pcf_property_header[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE PCF_ParsePropertyRec + + FT_FRAME_START( PCF_PROPERTY_SIZE ), + FT_FRAME_LONG_LE( name ), + FT_FRAME_BYTE ( isString ), + FT_FRAME_LONG_LE( value ), + FT_FRAME_END + }; + + + static + const FT_Frame_Field pcf_property_msb_header[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE PCF_ParsePropertyRec + + FT_FRAME_START( PCF_PROPERTY_SIZE ), + FT_FRAME_LONG( name ), + FT_FRAME_BYTE( isString ), + FT_FRAME_LONG( value ), + FT_FRAME_END + }; + + + FT_LOCAL_DEF( PCF_Property ) + pcf_find_property( PCF_Face face, + const FT_String* prop ) + { + PCF_Property properties = face->properties; + FT_Bool found = 0; + int i; + + + for ( i = 0 ; i < face->nprops && !found; i++ ) + { + if ( !ft_strcmp( properties[i].name, prop ) ) + found = 1; + } + + if ( found ) + return properties + i - 1; + else + return NULL; + } + + + static FT_Error + pcf_get_properties( FT_Stream stream, + PCF_Face face ) + { + PCF_ParseProperty props = 0; + PCF_Property properties; + FT_ULong nprops, i; + FT_ULong format, size; + FT_Error error; + FT_Memory memory = FT_FACE(face)->memory; + FT_ULong string_size; + FT_String* strings = 0; + + + error = pcf_seek_to_table_type( stream, + face->toc.tables, + face->toc.count, + PCF_PROPERTIES, + &format, + &size ); + if ( error ) + goto Bail; + + if ( FT_READ_ULONG_LE( format ) ) + goto Bail; + + FT_TRACE4(( "pcf_get_properties:\n" )); + + FT_TRACE4(( " format = %ld\n", format )); + + if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) ) + goto Bail; + + if ( PCF_BYTE_ORDER( format ) == MSBFirst ) + (void)FT_READ_ULONG( nprops ); + else + (void)FT_READ_ULONG_LE( nprops ); + if ( error ) + goto Bail; + + FT_TRACE4(( " nprop = %d (truncate %d props)\n", + (int)nprops, nprops - (int)nprops )); + + nprops = (int)nprops; + + /* rough estimate */ + if ( nprops > size / PCF_PROPERTY_SIZE ) + { + error = PCF_Err_Invalid_Table; + goto Bail; + } + + face->nprops = (int)nprops; + + if ( FT_NEW_ARRAY( props, nprops ) ) + goto Bail; + + for ( i = 0; i < nprops; i++ ) + { + if ( PCF_BYTE_ORDER( format ) == MSBFirst ) + { + if ( FT_STREAM_READ_FIELDS( pcf_property_msb_header, props + i ) ) + goto Bail; + } + else + { + if ( FT_STREAM_READ_FIELDS( pcf_property_header, props + i ) ) + goto Bail; + } + } + + /* pad the property array */ + /* */ + /* clever here - nprops is the same as the number of odd-units read, */ + /* as only isStringProp are odd length (Keith Packard) */ + /* */ + if ( nprops & 3 ) + { + i = 4 - ( nprops & 3 ); + if ( FT_STREAM_SKIP( i ) ) + { + error = PCF_Err_Invalid_Stream_Skip; + goto Bail; + } + } + + if ( PCF_BYTE_ORDER( format ) == MSBFirst ) + (void)FT_READ_ULONG( string_size ); + else + (void)FT_READ_ULONG_LE( string_size ); + if ( error ) + goto Bail; + + FT_TRACE4(( " string_size = %ld\n", string_size )); + + /* rough estimate */ + if ( string_size > size - nprops * PCF_PROPERTY_SIZE ) + { + error = PCF_Err_Invalid_Table; + goto Bail; + } + + if ( FT_NEW_ARRAY( strings, string_size ) ) + goto Bail; + + error = FT_Stream_Read( stream, (FT_Byte*)strings, string_size ); + if ( error ) + goto Bail; + + if ( FT_NEW_ARRAY( properties, nprops ) ) + goto Bail; + + face->properties = properties; + + for ( i = 0; i < nprops; i++ ) + { + FT_Long name_offset = props[i].name; + + + if ( ( name_offset < 0 ) || + ( (FT_ULong)name_offset > string_size ) ) + { + error = PCF_Err_Invalid_Offset; + goto Bail; + } + + if ( FT_STRDUP( properties[i].name, strings + name_offset ) ) + goto Bail; + + FT_TRACE4(( " %s:", properties[i].name )); + + properties[i].isString = props[i].isString; + + if ( props[i].isString ) + { + FT_Long value_offset = props[i].value; + + + if ( ( value_offset < 0 ) || + ( (FT_ULong)value_offset > string_size ) ) + { + error = PCF_Err_Invalid_Offset; + goto Bail; + } + + if ( FT_STRDUP( properties[i].value.atom, strings + value_offset ) ) + goto Bail; + + FT_TRACE4(( " `%s'\n", properties[i].value.atom )); + } + else + { + properties[i].value.l = props[i].value; + + FT_TRACE4(( " %d\n", properties[i].value.l )); + } + } + + error = PCF_Err_Ok; + + Bail: + FT_FREE( props ); + FT_FREE( strings ); + + return error; + } + + + static FT_Error + pcf_get_metrics( FT_Stream stream, + PCF_Face face ) + { + FT_Error error = PCF_Err_Ok; + FT_Memory memory = FT_FACE(face)->memory; + FT_ULong format, size; + PCF_Metric metrics = 0; + FT_ULong nmetrics, i; + + + error = pcf_seek_to_table_type( stream, + face->toc.tables, + face->toc.count, + PCF_METRICS, + &format, + &size ); + if ( error ) + return error; + + if ( FT_READ_ULONG_LE( format ) ) + goto Bail; + + if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) && + !PCF_FORMAT_MATCH( format, PCF_COMPRESSED_METRICS ) ) + return PCF_Err_Invalid_File_Format; + + if ( PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) ) + { + if ( PCF_BYTE_ORDER( format ) == MSBFirst ) + (void)FT_READ_ULONG( nmetrics ); + else + (void)FT_READ_ULONG_LE( nmetrics ); + } + else + { + if ( PCF_BYTE_ORDER( format ) == MSBFirst ) + (void)FT_READ_USHORT( nmetrics ); + else + (void)FT_READ_USHORT_LE( nmetrics ); + } + if ( error ) + return PCF_Err_Invalid_File_Format; + + face->nmetrics = nmetrics; + + FT_TRACE4(( "pcf_get_metrics:\n" )); + + FT_TRACE4(( " number of metrics: %d\n", nmetrics )); + + /* rough estimate */ + if ( PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) ) + { + if ( nmetrics > size / PCF_METRIC_SIZE ) + return PCF_Err_Invalid_Table; + } + else + { + if ( nmetrics > size / PCF_COMPRESSED_METRIC_SIZE ) + return PCF_Err_Invalid_Table; + } + + if ( FT_NEW_ARRAY( face->metrics, nmetrics ) ) + return PCF_Err_Out_Of_Memory; + + metrics = face->metrics; + for ( i = 0; i < nmetrics; i++ ) + { + error = pcf_get_metric( stream, format, metrics + i ); + + metrics[i].bits = 0; + + FT_TRACE5(( " idx %d: width=%d, " + "lsb=%d, rsb=%d, ascent=%d, descent=%d, swidth=%d\n", + i, + ( metrics + i )->characterWidth, + ( metrics + i )->leftSideBearing, + ( metrics + i )->rightSideBearing, + ( metrics + i )->ascent, + ( metrics + i )->descent, + ( metrics + i )->attributes )); + + if ( error ) + break; + } + + if ( error ) + FT_FREE( face->metrics ); + + Bail: + return error; + } + + + static FT_Error + pcf_get_bitmaps( FT_Stream stream, + PCF_Face face ) + { + FT_Error error = PCF_Err_Ok; + FT_Memory memory = FT_FACE(face)->memory; + FT_Long* offsets; + FT_Long bitmapSizes[GLYPHPADOPTIONS]; + FT_ULong format, size; + FT_ULong nbitmaps, i, sizebitmaps = 0; + + + error = pcf_seek_to_table_type( stream, + face->toc.tables, + face->toc.count, + PCF_BITMAPS, + &format, + &size ); + if ( error ) + return error; + + error = FT_Stream_EnterFrame( stream, 8 ); + if ( error ) + return error; + + format = FT_GET_ULONG_LE(); + if ( PCF_BYTE_ORDER( format ) == MSBFirst ) + nbitmaps = FT_GET_ULONG(); + else + nbitmaps = FT_GET_ULONG_LE(); + + FT_Stream_ExitFrame( stream ); + + if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) ) + return PCF_Err_Invalid_File_Format; + + FT_TRACE4(( "pcf_get_bitmaps:\n" )); + + FT_TRACE4(( " number of bitmaps: %d\n", nbitmaps )); + + /* XXX: PCF_Face->nmetrics is singed FT_Long, see pcf.h */ + if ( face->nmetrics < 0 || nbitmaps != ( FT_ULong )face->nmetrics ) + return PCF_Err_Invalid_File_Format; + + if ( FT_NEW_ARRAY( offsets, nbitmaps ) ) + return error; + + for ( i = 0; i < nbitmaps; i++ ) + { + if ( PCF_BYTE_ORDER( format ) == MSBFirst ) + (void)FT_READ_LONG( offsets[i] ); + else + (void)FT_READ_LONG_LE( offsets[i] ); + + FT_TRACE5(( " bitmap %d: offset %ld (0x%lX)\n", + i, offsets[i], offsets[i] )); + } + if ( error ) + goto Bail; + + for ( i = 0; i < GLYPHPADOPTIONS; i++ ) + { + if ( PCF_BYTE_ORDER( format ) == MSBFirst ) + (void)FT_READ_LONG( bitmapSizes[i] ); + else + (void)FT_READ_LONG_LE( bitmapSizes[i] ); + if ( error ) + goto Bail; + + sizebitmaps = bitmapSizes[PCF_GLYPH_PAD_INDEX( format )]; + + FT_TRACE4(( " padding %d implies a size of %ld\n", i, bitmapSizes[i] )); + } + + FT_TRACE4(( " %d bitmaps, padding index %ld\n", + nbitmaps, + PCF_GLYPH_PAD_INDEX( format ) )); + FT_TRACE4(( " bitmap size = %d\n", sizebitmaps )); + + FT_UNUSED( sizebitmaps ); /* only used for debugging */ + + for ( i = 0; i < nbitmaps; i++ ) + { + /* rough estimate */ + if ( ( offsets[i] < 0 ) || + ( (FT_ULong)offsets[i] > size ) ) + { + FT_TRACE0(( "pcf_get_bitmaps:" + " invalid offset to bitmap data of glyph %d\n", i )); + } + else + face->metrics[i].bits = stream->pos + offsets[i]; + } + + face->bitmapsFormat = format; + + Bail: + FT_FREE( offsets ); + return error; + } + + + static FT_Error + pcf_get_encodings( FT_Stream stream, + PCF_Face face ) + { + FT_Error error = PCF_Err_Ok; + FT_Memory memory = FT_FACE(face)->memory; + FT_ULong format, size; + int firstCol, lastCol; + int firstRow, lastRow; + int nencoding, encodingOffset; + int i, j; + PCF_Encoding tmpEncoding, encoding = 0; + + + error = pcf_seek_to_table_type( stream, + face->toc.tables, + face->toc.count, + PCF_BDF_ENCODINGS, + &format, + &size ); + if ( error ) + return error; + + error = FT_Stream_EnterFrame( stream, 14 ); + if ( error ) + return error; + + format = FT_GET_ULONG_LE(); + + if ( PCF_BYTE_ORDER( format ) == MSBFirst ) + { + firstCol = FT_GET_SHORT(); + lastCol = FT_GET_SHORT(); + firstRow = FT_GET_SHORT(); + lastRow = FT_GET_SHORT(); + face->defaultChar = FT_GET_SHORT(); + } + else + { + firstCol = FT_GET_SHORT_LE(); + lastCol = FT_GET_SHORT_LE(); + firstRow = FT_GET_SHORT_LE(); + lastRow = FT_GET_SHORT_LE(); + face->defaultChar = FT_GET_SHORT_LE(); + } + + FT_Stream_ExitFrame( stream ); + + if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) ) + return PCF_Err_Invalid_File_Format; + + FT_TRACE4(( "pdf_get_encodings:\n" )); + + FT_TRACE4(( " firstCol %d, lastCol %d, firstRow %d, lastRow %d\n", + firstCol, lastCol, firstRow, lastRow )); + + nencoding = ( lastCol - firstCol + 1 ) * ( lastRow - firstRow + 1 ); + + if ( FT_NEW_ARRAY( tmpEncoding, nencoding ) ) + return PCF_Err_Out_Of_Memory; + + error = FT_Stream_EnterFrame( stream, 2 * nencoding ); + if ( error ) + goto Bail; + + for ( i = 0, j = 0 ; i < nencoding; i++ ) + { + if ( PCF_BYTE_ORDER( format ) == MSBFirst ) + encodingOffset = FT_GET_SHORT(); + else + encodingOffset = FT_GET_SHORT_LE(); + + if ( encodingOffset != -1 ) + { + tmpEncoding[j].enc = ( ( ( i / ( lastCol - firstCol + 1 ) ) + + firstRow ) * 256 ) + + ( ( i % ( lastCol - firstCol + 1 ) ) + + firstCol ); + + tmpEncoding[j].glyph = (FT_Short)encodingOffset; + + FT_TRACE5(( " code %d (0x%04X): idx %d\n", + tmpEncoding[j].enc, tmpEncoding[j].enc, + tmpEncoding[j].glyph )); + + j++; + } + } + FT_Stream_ExitFrame( stream ); + + if ( FT_NEW_ARRAY( encoding, j ) ) + goto Bail; + + for ( i = 0; i < j; i++ ) + { + encoding[i].enc = tmpEncoding[i].enc; + encoding[i].glyph = tmpEncoding[i].glyph; + } + + face->nencodings = j; + face->encodings = encoding; + FT_FREE( tmpEncoding ); + + return error; + + Bail: + FT_FREE( encoding ); + FT_FREE( tmpEncoding ); + return error; + } + + + static + const FT_Frame_Field pcf_accel_header[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE PCF_AccelRec + + FT_FRAME_START( 20 ), + FT_FRAME_BYTE ( noOverlap ), + FT_FRAME_BYTE ( constantMetrics ), + FT_FRAME_BYTE ( terminalFont ), + FT_FRAME_BYTE ( constantWidth ), + FT_FRAME_BYTE ( inkInside ), + FT_FRAME_BYTE ( inkMetrics ), + FT_FRAME_BYTE ( drawDirection ), + FT_FRAME_SKIP_BYTES( 1 ), + FT_FRAME_LONG_LE ( fontAscent ), + FT_FRAME_LONG_LE ( fontDescent ), + FT_FRAME_LONG_LE ( maxOverlap ), + FT_FRAME_END + }; + + + static + const FT_Frame_Field pcf_accel_msb_header[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE PCF_AccelRec + + FT_FRAME_START( 20 ), + FT_FRAME_BYTE ( noOverlap ), + FT_FRAME_BYTE ( constantMetrics ), + FT_FRAME_BYTE ( terminalFont ), + FT_FRAME_BYTE ( constantWidth ), + FT_FRAME_BYTE ( inkInside ), + FT_FRAME_BYTE ( inkMetrics ), + FT_FRAME_BYTE ( drawDirection ), + FT_FRAME_SKIP_BYTES( 1 ), + FT_FRAME_LONG ( fontAscent ), + FT_FRAME_LONG ( fontDescent ), + FT_FRAME_LONG ( maxOverlap ), + FT_FRAME_END + }; + + + static FT_Error + pcf_get_accel( FT_Stream stream, + PCF_Face face, + FT_ULong type ) + { + FT_ULong format, size; + FT_Error error = PCF_Err_Ok; + PCF_Accel accel = &face->accel; + + + error = pcf_seek_to_table_type( stream, + face->toc.tables, + face->toc.count, + type, + &format, + &size ); + if ( error ) + goto Bail; + + if ( FT_READ_ULONG_LE( format ) ) + goto Bail; + + if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) && + !PCF_FORMAT_MATCH( format, PCF_ACCEL_W_INKBOUNDS ) ) + goto Bail; + + if ( PCF_BYTE_ORDER( format ) == MSBFirst ) + { + if ( FT_STREAM_READ_FIELDS( pcf_accel_msb_header, accel ) ) + goto Bail; + } + else + { + if ( FT_STREAM_READ_FIELDS( pcf_accel_header, accel ) ) + goto Bail; + } + + error = pcf_get_metric( stream, + format & ( ~PCF_FORMAT_MASK ), + &(accel->minbounds) ); + if ( error ) + goto Bail; + + error = pcf_get_metric( stream, + format & ( ~PCF_FORMAT_MASK ), + &(accel->maxbounds) ); + if ( error ) + goto Bail; + + if ( PCF_FORMAT_MATCH( format, PCF_ACCEL_W_INKBOUNDS ) ) + { + error = pcf_get_metric( stream, + format & ( ~PCF_FORMAT_MASK ), + &(accel->ink_minbounds) ); + if ( error ) + goto Bail; + + error = pcf_get_metric( stream, + format & ( ~PCF_FORMAT_MASK ), + &(accel->ink_maxbounds) ); + if ( error ) + goto Bail; + } + else + { + accel->ink_minbounds = accel->minbounds; /* I'm not sure about this */ + accel->ink_maxbounds = accel->maxbounds; + } + + Bail: + return error; + } + + + static FT_Error + pcf_interpret_style( PCF_Face pcf ) + { + FT_Error error = PCF_Err_Ok; + FT_Face face = FT_FACE( pcf ); + FT_Memory memory = face->memory; + + PCF_Property prop; + + size_t nn, len; + char* strings[4] = { NULL, NULL, NULL, NULL }; + size_t lengths[4]; + + + face->style_flags = 0; + + prop = pcf_find_property( pcf, "SLANT" ); + if ( prop && prop->isString && + ( *(prop->value.atom) == 'O' || *(prop->value.atom) == 'o' || + *(prop->value.atom) == 'I' || *(prop->value.atom) == 'i' ) ) + { + face->style_flags |= FT_STYLE_FLAG_ITALIC; + strings[2] = ( *(prop->value.atom) == 'O' || + *(prop->value.atom) == 'o' ) ? (char *)"Oblique" + : (char *)"Italic"; + } + + prop = pcf_find_property( pcf, "WEIGHT_NAME" ); + if ( prop && prop->isString && + ( *(prop->value.atom) == 'B' || *(prop->value.atom) == 'b' ) ) + { + face->style_flags |= FT_STYLE_FLAG_BOLD; + strings[1] = (char *)"Bold"; + } + + prop = pcf_find_property( pcf, "SETWIDTH_NAME" ); + if ( prop && prop->isString && + *(prop->value.atom) && + !( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) ) + strings[3] = (char *)(prop->value.atom); + + prop = pcf_find_property( pcf, "ADD_STYLE_NAME" ); + if ( prop && prop->isString && + *(prop->value.atom) && + !( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) ) + strings[0] = (char *)(prop->value.atom); + + for ( len = 0, nn = 0; nn < 4; nn++ ) + { + lengths[nn] = 0; + if ( strings[nn] ) + { + lengths[nn] = ft_strlen( strings[nn] ); + len += lengths[nn] + 1; + } + } + + if ( len == 0 ) + { + strings[0] = (char *)"Regular"; + lengths[0] = ft_strlen( strings[0] ); + len = lengths[0] + 1; + } + + { + char* s; + + + if ( FT_ALLOC( face->style_name, len ) ) + return error; + + s = face->style_name; + + for ( nn = 0; nn < 4; nn++ ) + { + char* src = strings[nn]; + + + len = lengths[nn]; + + if ( src == NULL ) + continue; + + /* separate elements with a space */ + if ( s != face->style_name ) + *s++ = ' '; + + ft_memcpy( s, src, len ); + + /* need to convert spaces to dashes for */ + /* add_style_name and setwidth_name */ + if ( nn == 0 || nn == 3 ) + { + size_t mm; + + + for ( mm = 0; mm < len; mm++ ) + if (s[mm] == ' ') + s[mm] = '-'; + } + + s += len; + } + *s = 0; + } + + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + pcf_load_font( FT_Stream stream, + PCF_Face face ) + { + FT_Error error = PCF_Err_Ok; + FT_Memory memory = FT_FACE(face)->memory; + FT_Bool hasBDFAccelerators; + + + error = pcf_read_TOC( stream, face ); + if ( error ) + goto Exit; + + error = pcf_get_properties( stream, face ); + if ( error ) + goto Exit; + + /* Use the old accelerators if no BDF accelerators are in the file. */ + hasBDFAccelerators = pcf_has_table_type( face->toc.tables, + face->toc.count, + PCF_BDF_ACCELERATORS ); + if ( !hasBDFAccelerators ) + { + error = pcf_get_accel( stream, face, PCF_ACCELERATORS ); + if ( error ) + goto Exit; + } + + /* metrics */ + error = pcf_get_metrics( stream, face ); + if ( error ) + goto Exit; + + /* bitmaps */ + error = pcf_get_bitmaps( stream, face ); + if ( error ) + goto Exit; + + /* encodings */ + error = pcf_get_encodings( stream, face ); + if ( error ) + goto Exit; + + /* BDF style accelerators (i.e. bounds based on encoded glyphs) */ + if ( hasBDFAccelerators ) + { + error = pcf_get_accel( stream, face, PCF_BDF_ACCELERATORS ); + if ( error ) + goto Exit; + } + + /* XXX: TO DO: inkmetrics and glyph_names are missing */ + + /* now construct the face object */ + { + FT_Face root = FT_FACE( face ); + PCF_Property prop; + + + root->num_faces = 1; + root->face_index = 0; + root->face_flags = FT_FACE_FLAG_FIXED_SIZES | + FT_FACE_FLAG_HORIZONTAL | + FT_FACE_FLAG_FAST_GLYPHS; + + if ( face->accel.constantWidth ) + root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; + + if ( ( error = pcf_interpret_style( face ) ) != 0 ) + goto Exit; + + prop = pcf_find_property( face, "FAMILY_NAME" ); + if ( prop && prop->isString ) + { + if ( FT_STRDUP( root->family_name, prop->value.atom ) ) + goto Exit; + } + else + root->family_name = NULL; + + /* + * Note: We shift all glyph indices by +1 since we must + * respect the convention that glyph 0 always corresponds + * to the `missing glyph'. + * + * This implies bumping the number of `available' glyphs by 1. + */ + root->num_glyphs = face->nmetrics + 1; + + root->num_fixed_sizes = 1; + if ( FT_NEW_ARRAY( root->available_sizes, 1 ) ) + goto Exit; + + { + FT_Bitmap_Size* bsize = root->available_sizes; + FT_Short resolution_x = 0, resolution_y = 0; + + + FT_MEM_ZERO( bsize, sizeof ( FT_Bitmap_Size ) ); + +#if 0 + bsize->height = face->accel.maxbounds.ascent << 6; +#endif + bsize->height = (FT_Short)( face->accel.fontAscent + + face->accel.fontDescent ); + + prop = pcf_find_property( face, "AVERAGE_WIDTH" ); + if ( prop ) + bsize->width = (FT_Short)( ( prop->value.l + 5 ) / 10 ); + else + bsize->width = (FT_Short)( bsize->height * 2/3 ); + + prop = pcf_find_property( face, "POINT_SIZE" ); + if ( prop ) + /* convert from 722.7 decipoints to 72 points per inch */ + bsize->size = + (FT_Pos)( ( prop->value.l * 64 * 7200 + 36135L ) / 72270L ); + + prop = pcf_find_property( face, "PIXEL_SIZE" ); + if ( prop ) + bsize->y_ppem = (FT_Short)prop->value.l << 6; + + prop = pcf_find_property( face, "RESOLUTION_X" ); + if ( prop ) + resolution_x = (FT_Short)prop->value.l; + + prop = pcf_find_property( face, "RESOLUTION_Y" ); + if ( prop ) + resolution_y = (FT_Short)prop->value.l; + + if ( bsize->y_ppem == 0 ) + { + bsize->y_ppem = bsize->size; + if ( resolution_y ) + bsize->y_ppem = bsize->y_ppem * resolution_y / 72; + } + if ( resolution_x && resolution_y ) + bsize->x_ppem = bsize->y_ppem * resolution_x / resolution_y; + else + bsize->x_ppem = bsize->y_ppem; + } + + /* set up charset */ + { + PCF_Property charset_registry = 0, charset_encoding = 0; + + + charset_registry = pcf_find_property( face, "CHARSET_REGISTRY" ); + charset_encoding = pcf_find_property( face, "CHARSET_ENCODING" ); + + if ( charset_registry && charset_registry->isString && + charset_encoding && charset_encoding->isString ) + { + if ( FT_STRDUP( face->charset_encoding, + charset_encoding->value.atom ) || + FT_STRDUP( face->charset_registry, + charset_registry->value.atom ) ) + goto Exit; + } + } + } + + Exit: + if ( error ) + { + /* This is done to respect the behaviour of the original */ + /* PCF font driver. */ + error = PCF_Err_Invalid_File_Format; + } + + return error; + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/pcf/pcfread.h b/mod/pub.mod/freetype.mod/src/pcf/pcfread.h new file mode 100644 index 0000000..c9524f1 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/pcf/pcfread.h @@ -0,0 +1,45 @@ +/* pcfread.h + + FreeType font driver for pcf fonts + + Copyright 2003 by + Francesco Zappa Nardelli + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + + +#ifndef __PCFREAD_H__ +#define __PCFREAD_H__ + + +#include <ft2build.h> + +FT_BEGIN_HEADER + + FT_LOCAL( PCF_Property ) + pcf_find_property( PCF_Face face, + const FT_String* prop ); + +FT_END_HEADER + +#endif /* __PCFREAD_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/pcf/pcfutil.c b/mod/pub.mod/freetype.mod/src/pcf/pcfutil.c new file mode 100644 index 0000000..b91274f --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/pcf/pcfutil.c @@ -0,0 +1,104 @@ +/* + +Copyright 1990, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ +/* $XFree86: xc/lib/font/util/utilbitmap.c,v 1.3 1999/08/22 08:58:58 dawes Exp $ */ + +/* + * Author: Keith Packard, MIT X Consortium + */ + +/* Modified for use with FreeType */ + + +#include <ft2build.h> +#include "pcfutil.h" + + + /* + * Invert bit order within each BYTE of an array. + */ + + FT_LOCAL_DEF( void ) + BitOrderInvert( unsigned char* buf, + size_t nbytes ) + { + for ( ; nbytes > 0; nbytes--, buf++ ) + { + unsigned int val = *buf; + + + val = ( ( val >> 1 ) & 0x55 ) | ( ( val << 1 ) & 0xAA ); + val = ( ( val >> 2 ) & 0x33 ) | ( ( val << 2 ) & 0xCC ); + val = ( ( val >> 4 ) & 0x0F ) | ( ( val << 4 ) & 0xF0 ); + + *buf = (unsigned char)val; + } + } + + + /* + * Invert byte order within each 16-bits of an array. + */ + + FT_LOCAL_DEF( void ) + TwoByteSwap( unsigned char* buf, + size_t nbytes ) + { + unsigned char c; + + + for ( ; nbytes >= 2; nbytes -= 2, buf += 2 ) + { + c = buf[0]; + buf[0] = buf[1]; + buf[1] = c; + } + } + + /* + * Invert byte order within each 32-bits of an array. + */ + + FT_LOCAL_DEF( void ) + FourByteSwap( unsigned char* buf, + size_t nbytes ) + { + unsigned char c; + + + for ( ; nbytes >= 4; nbytes -= 4, buf += 4 ) + { + c = buf[0]; + buf[0] = buf[3]; + buf[3] = c; + + c = buf[1]; + buf[1] = buf[2]; + buf[2] = c; + } + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/pcf/pcfutil.h b/mod/pub.mod/freetype.mod/src/pcf/pcfutil.h new file mode 100644 index 0000000..ce10fb5 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/pcf/pcfutil.h @@ -0,0 +1,55 @@ +/* pcfutil.h + + FreeType font driver for pcf fonts + + Copyright 2000, 2001, 2004 by + Francesco Zappa Nardelli + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + + +#ifndef __PCFUTIL_H__ +#define __PCFUTIL_H__ + + +#include <ft2build.h> +#include FT_CONFIG_CONFIG_H + + +FT_BEGIN_HEADER + + FT_LOCAL( void ) + BitOrderInvert( unsigned char* buf, + size_t nbytes ); + + FT_LOCAL( void ) + TwoByteSwap( unsigned char* buf, + size_t nbytes ); + + FT_LOCAL( void ) + FourByteSwap( unsigned char* buf, + size_t nbytes ); + +FT_END_HEADER + +#endif /* __PCFUTIL_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/pfr/pfr.c b/mod/pub.mod/freetype.mod/src/pfr/pfr.c new file mode 100644 index 0000000..eb2c4ed --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/pfr/pfr.c @@ -0,0 +1,29 @@ +/***************************************************************************/ +/* */ +/* pfr.c */ +/* */ +/* FreeType PFR driver component. */ +/* */ +/* Copyright 2002 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + +#define FT_MAKE_OPTION_SINGLE_OBJECT + +#include <ft2build.h> + +#include "pfrload.c" +#include "pfrgload.c" +#include "pfrcmap.c" +#include "pfrobjs.c" +#include "pfrdrivr.c" +#include "pfrsbit.c" + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/pfr/pfrcmap.c b/mod/pub.mod/freetype.mod/src/pfr/pfrcmap.c new file mode 100644 index 0000000..9c8f9ed --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/pfr/pfrcmap.c @@ -0,0 +1,166 @@ +/***************************************************************************/ +/* */ +/* pfrcmap.c */ +/* */ +/* FreeType PFR cmap handling (body). */ +/* */ +/* Copyright 2002, 2007, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include "pfrcmap.h" +#include "pfrobjs.h" + +#include "pfrerror.h" + + + FT_CALLBACK_DEF( FT_Error ) + pfr_cmap_init( PFR_CMap cmap ) + { + FT_Error error = PFR_Err_Ok; + PFR_Face face = (PFR_Face)FT_CMAP_FACE( cmap ); + + + cmap->num_chars = face->phy_font.num_chars; + cmap->chars = face->phy_font.chars; + + /* just for safety, check that the character entries are correctly */ + /* sorted in increasing character code order */ + { + FT_UInt n; + + + for ( n = 1; n < cmap->num_chars; n++ ) + { + if ( cmap->chars[n - 1].char_code >= cmap->chars[n].char_code ) + { + error = PFR_Err_Invalid_Table; + goto Exit; + } + } + } + + Exit: + return error; + } + + + FT_CALLBACK_DEF( void ) + pfr_cmap_done( PFR_CMap cmap ) + { + cmap->chars = NULL; + cmap->num_chars = 0; + } + + + FT_CALLBACK_DEF( FT_UInt ) + pfr_cmap_char_index( PFR_CMap cmap, + FT_UInt32 char_code ) + { + FT_UInt min = 0; + FT_UInt max = cmap->num_chars; + FT_UInt mid; + PFR_Char gchar; + + + while ( min < max ) + { + mid = min + ( max - min ) / 2; + gchar = cmap->chars + mid; + + if ( gchar->char_code == char_code ) + return mid + 1; + + if ( gchar->char_code < char_code ) + min = mid + 1; + else + max = mid; + } + return 0; + } + + + FT_CALLBACK_DEF( FT_UInt32 ) + pfr_cmap_char_next( PFR_CMap cmap, + FT_UInt32 *pchar_code ) + { + FT_UInt result = 0; + FT_UInt32 char_code = *pchar_code + 1; + + + Restart: + { + FT_UInt min = 0; + FT_UInt max = cmap->num_chars; + FT_UInt mid; + PFR_Char gchar; + + + while ( min < max ) + { + mid = min + ( ( max - min ) >> 1 ); + gchar = cmap->chars + mid; + + if ( gchar->char_code == char_code ) + { + result = mid; + if ( result != 0 ) + { + result++; + goto Exit; + } + + char_code++; + goto Restart; + } + + if ( gchar->char_code < char_code ) + min = mid+1; + else + max = mid; + } + + /* we didn't find it, but we have a pair just above it */ + char_code = 0; + + if ( min < cmap->num_chars ) + { + gchar = cmap->chars + min; + result = min; + if ( result != 0 ) + { + result++; + char_code = gchar->char_code; + } + } + } + + Exit: + *pchar_code = char_code; + return result; + } + + + FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec + pfr_cmap_class_rec = + { + sizeof ( PFR_CMapRec ), + + (FT_CMap_InitFunc) pfr_cmap_init, + (FT_CMap_DoneFunc) pfr_cmap_done, + (FT_CMap_CharIndexFunc)pfr_cmap_char_index, + (FT_CMap_CharNextFunc) pfr_cmap_char_next, + + NULL, NULL, NULL, NULL, NULL + }; + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/pfr/pfrcmap.h b/mod/pub.mod/freetype.mod/src/pfr/pfrcmap.h new file mode 100644 index 0000000..a626953 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/pfr/pfrcmap.h @@ -0,0 +1,46 @@ +/***************************************************************************/ +/* */ +/* pfrcmap.h */ +/* */ +/* FreeType PFR cmap handling (specification). */ +/* */ +/* Copyright 2002 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __PFRCMAP_H__ +#define __PFRCMAP_H__ + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H +#include "pfrtypes.h" + + +FT_BEGIN_HEADER + + typedef struct PFR_CMapRec_ + { + FT_CMapRec cmap; + FT_UInt num_chars; + PFR_Char chars; + + } PFR_CMapRec, *PFR_CMap; + + + FT_CALLBACK_TABLE const FT_CMap_ClassRec pfr_cmap_class_rec; + +FT_END_HEADER + + +#endif /* __PFRCMAP_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/pfr/pfrdrivr.c b/mod/pub.mod/freetype.mod/src/pfr/pfrdrivr.c new file mode 100644 index 0000000..15cca98 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/pfr/pfrdrivr.c @@ -0,0 +1,214 @@ +/***************************************************************************/ +/* */ +/* pfrdrivr.c */ +/* */ +/* FreeType PFR driver interface (body). */ +/* */ +/* Copyright 2002, 2003, 2004, 2006, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_SERVICE_PFR_H +#include FT_SERVICE_XFREE86_NAME_H +#include "pfrdrivr.h" +#include "pfrobjs.h" + +#include "pfrerror.h" + + + FT_CALLBACK_DEF( FT_Error ) + pfr_get_kerning( FT_Face pfrface, /* PFR_Face */ + FT_UInt left, + FT_UInt right, + FT_Vector *avector ) + { + PFR_Face face = (PFR_Face)pfrface; + PFR_PhyFont phys = &face->phy_font; + + + pfr_face_get_kerning( pfrface, left, right, avector ); + + /* convert from metrics to outline units when necessary */ + if ( phys->outline_resolution != phys->metrics_resolution ) + { + if ( avector->x != 0 ) + avector->x = FT_MulDiv( avector->x, phys->outline_resolution, + phys->metrics_resolution ); + + if ( avector->y != 0 ) + avector->y = FT_MulDiv( avector->x, phys->outline_resolution, + phys->metrics_resolution ); + } + + return PFR_Err_Ok; + } + + + /* + * PFR METRICS SERVICE + * + */ + + FT_CALLBACK_DEF( FT_Error ) + pfr_get_advance( FT_Face pfrface, /* PFR_Face */ + FT_UInt gindex, + FT_Pos *anadvance ) + { + PFR_Face face = (PFR_Face)pfrface; + FT_Error error = PFR_Err_Invalid_Argument; + + + *anadvance = 0; + + if ( !gindex ) + goto Exit; + + gindex--; + + if ( face ) + { + PFR_PhyFont phys = &face->phy_font; + + + if ( gindex < phys->num_chars ) + { + *anadvance = phys->chars[gindex].advance; + error = 0; + } + } + + Exit: + return error; + } + + + FT_CALLBACK_DEF( FT_Error ) + pfr_get_metrics( FT_Face pfrface, /* PFR_Face */ + FT_UInt *anoutline_resolution, + FT_UInt *ametrics_resolution, + FT_Fixed *ametrics_x_scale, + FT_Fixed *ametrics_y_scale ) + { + PFR_Face face = (PFR_Face)pfrface; + PFR_PhyFont phys = &face->phy_font; + FT_Fixed x_scale, y_scale; + FT_Size size = face->root.size; + + + if ( anoutline_resolution ) + *anoutline_resolution = phys->outline_resolution; + + if ( ametrics_resolution ) + *ametrics_resolution = phys->metrics_resolution; + + x_scale = 0x10000L; + y_scale = 0x10000L; + + if ( size ) + { + x_scale = FT_DivFix( size->metrics.x_ppem << 6, + phys->metrics_resolution ); + + y_scale = FT_DivFix( size->metrics.y_ppem << 6, + phys->metrics_resolution ); + } + + if ( ametrics_x_scale ) + *ametrics_x_scale = x_scale; + + if ( ametrics_y_scale ) + *ametrics_y_scale = y_scale; + + return PFR_Err_Ok; + } + + + FT_CALLBACK_TABLE_DEF + const FT_Service_PfrMetricsRec pfr_metrics_service_rec = + { + pfr_get_metrics, + pfr_face_get_kerning, + pfr_get_advance + }; + + + /* + * SERVICE LIST + * + */ + + static const FT_ServiceDescRec pfr_services[] = + { + { FT_SERVICE_ID_PFR_METRICS, &pfr_metrics_service_rec }, + { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_PFR }, + { NULL, NULL } + }; + + + FT_CALLBACK_DEF( FT_Module_Interface ) + pfr_get_service( FT_Module module, + const FT_String* service_id ) + { + FT_UNUSED( module ); + + return ft_service_list_lookup( pfr_services, service_id ); + } + + + FT_CALLBACK_TABLE_DEF + const FT_Driver_ClassRec pfr_driver_class = + { + { + FT_MODULE_FONT_DRIVER | + FT_MODULE_DRIVER_SCALABLE, + + sizeof( FT_DriverRec ), + + "pfr", + 0x10000L, + 0x20000L, + + NULL, + + 0, + 0, + pfr_get_service + }, + + sizeof( PFR_FaceRec ), + sizeof( PFR_SizeRec ), + sizeof( PFR_SlotRec ), + + pfr_face_init, + pfr_face_done, + 0, /* FT_Size_InitFunc */ + 0, /* FT_Size_DoneFunc */ + pfr_slot_init, + pfr_slot_done, + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + ft_stub_set_char_sizes, + ft_stub_set_pixel_sizes, +#endif + pfr_slot_load, + + pfr_get_kerning, + 0, /* FT_Face_AttachFunc */ + 0, /* FT_Face_GetAdvancesFunc */ + 0, /* FT_Size_RequestFunc */ + 0, /* FT_Size_SelectFunc */ + }; + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/pfr/pfrdrivr.h b/mod/pub.mod/freetype.mod/src/pfr/pfrdrivr.h new file mode 100644 index 0000000..da0a1aa --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/pfr/pfrdrivr.h @@ -0,0 +1,43 @@ +/***************************************************************************/ +/* */ +/* pfrdrivr.h */ +/* */ +/* High-level Type PFR driver interface (specification). */ +/* */ +/* Copyright 2002 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __PFRDRIVR_H__ +#define __PFRDRIVR_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_DRIVER_H + + +FT_BEGIN_HEADER + +#ifdef FT_CONFIG_OPTION_PIC +#error "this module does not support PIC yet" +#endif + + + FT_EXPORT_VAR( const FT_Driver_ClassRec ) pfr_driver_class; + + +FT_END_HEADER + + +#endif /* __PFRDRIVR_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/pfr/pfrerror.h b/mod/pub.mod/freetype.mod/src/pfr/pfrerror.h new file mode 100644 index 0000000..2e1c401 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/pfr/pfrerror.h @@ -0,0 +1,40 @@ +/***************************************************************************/ +/* */ +/* pfrerror.h */ +/* */ +/* PFR error codes (specification only). */ +/* */ +/* Copyright 2002 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file is used to define the PFR error enumeration constants. */ + /* */ + /*************************************************************************/ + +#ifndef __PFRERROR_H__ +#define __PFRERROR_H__ + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#define FT_ERR_PREFIX PFR_Err_ +#define FT_ERR_BASE FT_Mod_Err_PFR + +#include FT_ERRORS_H + +#endif /* __PFRERROR_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/pfr/pfrgload.c b/mod/pub.mod/freetype.mod/src/pfr/pfrgload.c new file mode 100644 index 0000000..6fe6e42 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/pfr/pfrgload.c @@ -0,0 +1,828 @@ +/***************************************************************************/ +/* */ +/* pfrgload.c */ +/* */ +/* FreeType PFR glyph loader (body). */ +/* */ +/* Copyright 2002, 2003, 2005, 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include "pfrgload.h" +#include "pfrsbit.h" +#include "pfrload.h" /* for macro definitions */ +#include FT_INTERNAL_DEBUG_H + +#include "pfrerror.h" + +#undef FT_COMPONENT +#define FT_COMPONENT trace_pfr + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** PFR GLYPH BUILDER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + FT_LOCAL_DEF( void ) + pfr_glyph_init( PFR_Glyph glyph, + FT_GlyphLoader loader ) + { + FT_ZERO( glyph ); + + glyph->loader = loader; + glyph->path_begun = 0; + + FT_GlyphLoader_Rewind( loader ); + } + + + FT_LOCAL_DEF( void ) + pfr_glyph_done( PFR_Glyph glyph ) + { + FT_Memory memory = glyph->loader->memory; + + + FT_FREE( glyph->x_control ); + glyph->y_control = NULL; + + glyph->max_xy_control = 0; +#if 0 + glyph->num_x_control = 0; + glyph->num_y_control = 0; +#endif + + FT_FREE( glyph->subs ); + + glyph->max_subs = 0; + glyph->num_subs = 0; + + glyph->loader = NULL; + glyph->path_begun = 0; + } + + + /* close current contour, if any */ + static void + pfr_glyph_close_contour( PFR_Glyph glyph ) + { + FT_GlyphLoader loader = glyph->loader; + FT_Outline* outline = &loader->current.outline; + FT_Int last, first; + + + if ( !glyph->path_begun ) + return; + + /* compute first and last point indices in current glyph outline */ + last = outline->n_points - 1; + first = 0; + if ( outline->n_contours > 0 ) + first = outline->contours[outline->n_contours - 1]; + + /* if the last point falls on the same location than the first one */ + /* we need to delete it */ + if ( last > first ) + { + FT_Vector* p1 = outline->points + first; + FT_Vector* p2 = outline->points + last; + + + if ( p1->x == p2->x && p1->y == p2->y ) + { + outline->n_points--; + last--; + } + } + + /* don't add empty contours */ + if ( last >= first ) + outline->contours[outline->n_contours++] = (short)last; + + glyph->path_begun = 0; + } + + + /* reset glyph to start the loading of a new glyph */ + static void + pfr_glyph_start( PFR_Glyph glyph ) + { + glyph->path_begun = 0; + } + + + static FT_Error + pfr_glyph_line_to( PFR_Glyph glyph, + FT_Vector* to ) + { + FT_GlyphLoader loader = glyph->loader; + FT_Outline* outline = &loader->current.outline; + FT_Error error; + + + /* check that we have begun a new path */ + if ( !glyph->path_begun ) + { + error = PFR_Err_Invalid_Table; + FT_ERROR(( "pfr_glyph_line_to: invalid glyph data\n" )); + goto Exit; + } + + error = FT_GLYPHLOADER_CHECK_POINTS( loader, 1, 0 ); + if ( !error ) + { + FT_UInt n = outline->n_points; + + + outline->points[n] = *to; + outline->tags [n] = FT_CURVE_TAG_ON; + + outline->n_points++; + } + + Exit: + return error; + } + + + static FT_Error + pfr_glyph_curve_to( PFR_Glyph glyph, + FT_Vector* control1, + FT_Vector* control2, + FT_Vector* to ) + { + FT_GlyphLoader loader = glyph->loader; + FT_Outline* outline = &loader->current.outline; + FT_Error error; + + + /* check that we have begun a new path */ + if ( !glyph->path_begun ) + { + error = PFR_Err_Invalid_Table; + FT_ERROR(( "pfr_glyph_line_to: invalid glyph data\n" )); + goto Exit; + } + + error = FT_GLYPHLOADER_CHECK_POINTS( loader, 3, 0 ); + if ( !error ) + { + FT_Vector* vec = outline->points + outline->n_points; + FT_Byte* tag = (FT_Byte*)outline->tags + outline->n_points; + + + vec[0] = *control1; + vec[1] = *control2; + vec[2] = *to; + tag[0] = FT_CURVE_TAG_CUBIC; + tag[1] = FT_CURVE_TAG_CUBIC; + tag[2] = FT_CURVE_TAG_ON; + + outline->n_points = (FT_Short)( outline->n_points + 3 ); + } + + Exit: + return error; + } + + + static FT_Error + pfr_glyph_move_to( PFR_Glyph glyph, + FT_Vector* to ) + { + FT_GlyphLoader loader = glyph->loader; + FT_Error error; + + + /* close current contour if any */ + pfr_glyph_close_contour( glyph ); + + /* indicate that a new contour has started */ + glyph->path_begun = 1; + + /* check that there is space for a new contour and a new point */ + error = FT_GLYPHLOADER_CHECK_POINTS( loader, 1, 1 ); + if ( !error ) + /* add new start point */ + error = pfr_glyph_line_to( glyph, to ); + + return error; + } + + + static void + pfr_glyph_end( PFR_Glyph glyph ) + { + /* close current contour if any */ + pfr_glyph_close_contour( glyph ); + + /* merge the current glyph into the stack */ + FT_GlyphLoader_Add( glyph->loader ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** PFR GLYPH LOADER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + /* load a simple glyph */ + static FT_Error + pfr_glyph_load_simple( PFR_Glyph glyph, + FT_Byte* p, + FT_Byte* limit ) + { + FT_Error error = 0; + FT_Memory memory = glyph->loader->memory; + FT_UInt flags, x_count, y_count, i, count, mask; + FT_Int x; + + + PFR_CHECK( 1 ); + flags = PFR_NEXT_BYTE( p ); + + /* test for composite glyphs */ + if ( flags & PFR_GLYPH_IS_COMPOUND ) + goto Failure; + + x_count = 0; + y_count = 0; + + if ( flags & PFR_GLYPH_1BYTE_XYCOUNT ) + { + PFR_CHECK( 1 ); + count = PFR_NEXT_BYTE( p ); + x_count = ( count & 15 ); + y_count = ( count >> 4 ); + } + else + { + if ( flags & PFR_GLYPH_XCOUNT ) + { + PFR_CHECK( 1 ); + x_count = PFR_NEXT_BYTE( p ); + } + + if ( flags & PFR_GLYPH_YCOUNT ) + { + PFR_CHECK( 1 ); + y_count = PFR_NEXT_BYTE( p ); + } + } + + count = x_count + y_count; + + /* re-allocate array when necessary */ + if ( count > glyph->max_xy_control ) + { + FT_UInt new_max = FT_PAD_CEIL( count, 8 ); + + + if ( FT_RENEW_ARRAY( glyph->x_control, + glyph->max_xy_control, + new_max ) ) + goto Exit; + + glyph->max_xy_control = new_max; + } + + glyph->y_control = glyph->x_control + x_count; + + mask = 0; + x = 0; + + for ( i = 0; i < count; i++ ) + { + if ( ( i & 7 ) == 0 ) + { + PFR_CHECK( 1 ); + mask = PFR_NEXT_BYTE( p ); + } + + if ( mask & 1 ) + { + PFR_CHECK( 2 ); + x = PFR_NEXT_SHORT( p ); + } + else + { + PFR_CHECK( 1 ); + x += PFR_NEXT_BYTE( p ); + } + + glyph->x_control[i] = x; + + mask >>= 1; + } + + /* XXX: for now we ignore the secondary stroke and edge definitions */ + /* since we don't want to support native PFR hinting */ + /* */ + if ( flags & PFR_GLYPH_EXTRA_ITEMS ) + { + error = pfr_extra_items_skip( &p, limit ); + if ( error ) + goto Exit; + } + + pfr_glyph_start( glyph ); + + /* now load a simple glyph */ + { + FT_Vector pos[4]; + FT_Vector* cur; + + + pos[0].x = pos[0].y = 0; + pos[3] = pos[0]; + + for (;;) + { + FT_UInt format, format_low, args_format = 0, args_count, n; + + + /***************************************************************/ + /* read instruction */ + /* */ + PFR_CHECK( 1 ); + format = PFR_NEXT_BYTE( p ); + format_low = format & 15; + + switch ( format >> 4 ) + { + case 0: /* end glyph */ + FT_TRACE6(( "- end glyph" )); + args_count = 0; + break; + + case 1: /* general line operation */ + FT_TRACE6(( "- general line" )); + goto Line1; + + case 4: /* move to inside contour */ + FT_TRACE6(( "- move to inside" )); + goto Line1; + + case 5: /* move to outside contour */ + FT_TRACE6(( "- move to outside" )); + Line1: + args_format = format_low; + args_count = 1; + break; + + case 2: /* horizontal line to */ + FT_TRACE6(( "- horizontal line to cx.%d", format_low )); + if ( format_low > x_count ) + goto Failure; + pos[0].x = glyph->x_control[format_low]; + pos[0].y = pos[3].y; + pos[3] = pos[0]; + args_count = 0; + break; + + case 3: /* vertical line to */ + FT_TRACE6(( "- vertical line to cy.%d", format_low )); + if ( format_low > y_count ) + goto Failure; + pos[0].x = pos[3].x; + pos[0].y = glyph->y_control[format_low]; + pos[3] = pos[0]; + args_count = 0; + break; + + case 6: /* horizontal to vertical curve */ + FT_TRACE6(( "- hv curve " )); + args_format = 0xB8E; + args_count = 3; + break; + + case 7: /* vertical to horizontal curve */ + FT_TRACE6(( "- vh curve" )); + args_format = 0xE2B; + args_count = 3; + break; + + default: /* general curve to */ + FT_TRACE6(( "- general curve" )); + args_count = 4; + args_format = format_low; + } + + /***********************************************************/ + /* now read arguments */ + /* */ + cur = pos; + for ( n = 0; n < args_count; n++ ) + { + FT_UInt idx; + FT_Int delta; + + + /* read the X argument */ + switch ( args_format & 3 ) + { + case 0: /* 8-bit index */ + PFR_CHECK( 1 ); + idx = PFR_NEXT_BYTE( p ); + if ( idx > x_count ) + goto Failure; + cur->x = glyph->x_control[idx]; + FT_TRACE7(( " cx#%d", idx )); + break; + + case 1: /* 16-bit value */ + PFR_CHECK( 2 ); + cur->x = PFR_NEXT_SHORT( p ); + FT_TRACE7(( " x.%d", cur->x )); + break; + + case 2: /* 8-bit delta */ + PFR_CHECK( 1 ); + delta = PFR_NEXT_INT8( p ); + cur->x = pos[3].x + delta; + FT_TRACE7(( " dx.%d", delta )); + break; + + default: + FT_TRACE7(( " |" )); + cur->x = pos[3].x; + } + + /* read the Y argument */ + switch ( ( args_format >> 2 ) & 3 ) + { + case 0: /* 8-bit index */ + PFR_CHECK( 1 ); + idx = PFR_NEXT_BYTE( p ); + if ( idx > y_count ) + goto Failure; + cur->y = glyph->y_control[idx]; + FT_TRACE7(( " cy#%d", idx )); + break; + + case 1: /* 16-bit absolute value */ + PFR_CHECK( 2 ); + cur->y = PFR_NEXT_SHORT( p ); + FT_TRACE7(( " y.%d", cur->y )); + break; + + case 2: /* 8-bit delta */ + PFR_CHECK( 1 ); + delta = PFR_NEXT_INT8( p ); + cur->y = pos[3].y + delta; + FT_TRACE7(( " dy.%d", delta )); + break; + + default: + FT_TRACE7(( " -" )); + cur->y = pos[3].y; + } + + /* read the additional format flag for the general curve */ + if ( n == 0 && args_count == 4 ) + { + PFR_CHECK( 1 ); + args_format = PFR_NEXT_BYTE( p ); + args_count--; + } + else + args_format >>= 4; + + /* save the previous point */ + pos[3] = cur[0]; + cur++; + } + + FT_TRACE7(( "\n" )); + + /***********************************************************/ + /* finally, execute instruction */ + /* */ + switch ( format >> 4 ) + { + case 0: /* end glyph => EXIT */ + pfr_glyph_end( glyph ); + goto Exit; + + case 1: /* line operations */ + case 2: + case 3: + error = pfr_glyph_line_to( glyph, pos ); + goto Test_Error; + + case 4: /* move to inside contour */ + case 5: /* move to outside contour */ + error = pfr_glyph_move_to( glyph, pos ); + goto Test_Error; + + default: /* curve operations */ + error = pfr_glyph_curve_to( glyph, pos, pos + 1, pos + 2 ); + + Test_Error: /* test error condition */ + if ( error ) + goto Exit; + } + } /* for (;;) */ + } + + Exit: + return error; + + Failure: + Too_Short: + error = PFR_Err_Invalid_Table; + FT_ERROR(( "pfr_glyph_load_simple: invalid glyph data\n" )); + goto Exit; + } + + + /* load a composite/compound glyph */ + static FT_Error + pfr_glyph_load_compound( PFR_Glyph glyph, + FT_Byte* p, + FT_Byte* limit ) + { + FT_Error error = 0; + FT_GlyphLoader loader = glyph->loader; + FT_Memory memory = loader->memory; + PFR_SubGlyph subglyph; + FT_UInt flags, i, count, org_count; + FT_Int x_pos, y_pos; + + + PFR_CHECK( 1 ); + flags = PFR_NEXT_BYTE( p ); + + /* test for composite glyphs */ + if ( !( flags & PFR_GLYPH_IS_COMPOUND ) ) + goto Failure; + + count = flags & 0x3F; + + /* ignore extra items when present */ + /* */ + if ( flags & PFR_GLYPH_EXTRA_ITEMS ) + { + error = pfr_extra_items_skip( &p, limit ); + if (error) goto Exit; + } + + /* we can't rely on the FT_GlyphLoader to load sub-glyphs, because */ + /* the PFR format is dumb, using direct file offsets to point to the */ + /* sub-glyphs (instead of glyph indices). Sigh. */ + /* */ + /* For now, we load the list of sub-glyphs into a different array */ + /* but this will prevent us from using the auto-hinter at its best */ + /* quality. */ + /* */ + org_count = glyph->num_subs; + + if ( org_count + count > glyph->max_subs ) + { + FT_UInt new_max = ( org_count + count + 3 ) & (FT_UInt)-4; + + + if ( FT_RENEW_ARRAY( glyph->subs, glyph->max_subs, new_max ) ) + goto Exit; + + glyph->max_subs = new_max; + } + + subglyph = glyph->subs + org_count; + + for ( i = 0; i < count; i++, subglyph++ ) + { + FT_UInt format; + + + x_pos = 0; + y_pos = 0; + + PFR_CHECK( 1 ); + format = PFR_NEXT_BYTE( p ); + + /* read scale when available */ + subglyph->x_scale = 0x10000L; + if ( format & PFR_SUBGLYPH_XSCALE ) + { + PFR_CHECK( 2 ); + subglyph->x_scale = PFR_NEXT_SHORT( p ) << 4; + } + + subglyph->y_scale = 0x10000L; + if ( format & PFR_SUBGLYPH_YSCALE ) + { + PFR_CHECK( 2 ); + subglyph->y_scale = PFR_NEXT_SHORT( p ) << 4; + } + + /* read offset */ + switch ( format & 3 ) + { + case 1: + PFR_CHECK( 2 ); + x_pos = PFR_NEXT_SHORT( p ); + break; + + case 2: + PFR_CHECK( 1 ); + x_pos += PFR_NEXT_INT8( p ); + break; + + default: + ; + } + + switch ( ( format >> 2 ) & 3 ) + { + case 1: + PFR_CHECK( 2 ); + y_pos = PFR_NEXT_SHORT( p ); + break; + + case 2: + PFR_CHECK( 1 ); + y_pos += PFR_NEXT_INT8( p ); + break; + + default: + ; + } + + subglyph->x_delta = x_pos; + subglyph->y_delta = y_pos; + + /* read glyph position and size now */ + if ( format & PFR_SUBGLYPH_2BYTE_SIZE ) + { + PFR_CHECK( 2 ); + subglyph->gps_size = PFR_NEXT_USHORT( p ); + } + else + { + PFR_CHECK( 1 ); + subglyph->gps_size = PFR_NEXT_BYTE( p ); + } + + if ( format & PFR_SUBGLYPH_3BYTE_OFFSET ) + { + PFR_CHECK( 3 ); + subglyph->gps_offset = PFR_NEXT_LONG( p ); + } + else + { + PFR_CHECK( 2 ); + subglyph->gps_offset = PFR_NEXT_USHORT( p ); + } + + glyph->num_subs++; + } + + Exit: + return error; + + Failure: + Too_Short: + error = PFR_Err_Invalid_Table; + FT_ERROR(( "pfr_glyph_load_compound: invalid glyph data\n" )); + goto Exit; + } + + + static FT_Error + pfr_glyph_load_rec( PFR_Glyph glyph, + FT_Stream stream, + FT_ULong gps_offset, + FT_ULong offset, + FT_ULong size ) + { + FT_Error error; + FT_Byte* p; + FT_Byte* limit; + + + if ( FT_STREAM_SEEK( gps_offset + offset ) || + FT_FRAME_ENTER( size ) ) + goto Exit; + + p = (FT_Byte*)stream->cursor; + limit = p + size; + + if ( size > 0 && *p & PFR_GLYPH_IS_COMPOUND ) + { + FT_Int n, old_count, count; + FT_GlyphLoader loader = glyph->loader; + FT_Outline* base = &loader->base.outline; + + + old_count = glyph->num_subs; + + /* this is a compound glyph - load it */ + error = pfr_glyph_load_compound( glyph, p, limit ); + + FT_FRAME_EXIT(); + + if ( error ) + goto Exit; + + count = glyph->num_subs - old_count; + + /* now, load each individual glyph */ + for ( n = 0; n < count; n++ ) + { + FT_Int i, old_points, num_points; + PFR_SubGlyph subglyph; + + + subglyph = glyph->subs + old_count + n; + old_points = base->n_points; + + error = pfr_glyph_load_rec( glyph, stream, gps_offset, + subglyph->gps_offset, + subglyph->gps_size ); + if ( error ) + goto Exit; + + /* note that `glyph->subs' might have been re-allocated */ + subglyph = glyph->subs + old_count + n; + num_points = base->n_points - old_points; + + /* translate and eventually scale the new glyph points */ + if ( subglyph->x_scale != 0x10000L || subglyph->y_scale != 0x10000L ) + { + FT_Vector* vec = base->points + old_points; + + + for ( i = 0; i < num_points; i++, vec++ ) + { + vec->x = FT_MulFix( vec->x, subglyph->x_scale ) + + subglyph->x_delta; + vec->y = FT_MulFix( vec->y, subglyph->y_scale ) + + subglyph->y_delta; + } + } + else + { + FT_Vector* vec = loader->base.outline.points + old_points; + + + for ( i = 0; i < num_points; i++, vec++ ) + { + vec->x += subglyph->x_delta; + vec->y += subglyph->y_delta; + } + } + + /* proceed to next sub-glyph */ + } + } + else + { + /* load a simple glyph */ + error = pfr_glyph_load_simple( glyph, p, limit ); + + FT_FRAME_EXIT(); + } + + Exit: + return error; + } + + + + + + FT_LOCAL_DEF( FT_Error ) + pfr_glyph_load( PFR_Glyph glyph, + FT_Stream stream, + FT_ULong gps_offset, + FT_ULong offset, + FT_ULong size ) + { + /* initialize glyph loader */ + FT_GlyphLoader_Rewind( glyph->loader ); + + glyph->num_subs = 0; + + /* load the glyph, recursively when needed */ + return pfr_glyph_load_rec( glyph, stream, gps_offset, offset, size ); + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/pfr/pfrgload.h b/mod/pub.mod/freetype.mod/src/pfr/pfrgload.h new file mode 100644 index 0000000..7cc7a87 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/pfr/pfrgload.h @@ -0,0 +1,49 @@ +/***************************************************************************/ +/* */ +/* pfrgload.h */ +/* */ +/* FreeType PFR glyph loader (specification). */ +/* */ +/* Copyright 2002 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __PFRGLOAD_H__ +#define __PFRGLOAD_H__ + +#include "pfrtypes.h" + +FT_BEGIN_HEADER + + + FT_LOCAL( void ) + pfr_glyph_init( PFR_Glyph glyph, + FT_GlyphLoader loader ); + + FT_LOCAL( void ) + pfr_glyph_done( PFR_Glyph glyph ); + + + FT_LOCAL( FT_Error ) + pfr_glyph_load( PFR_Glyph glyph, + FT_Stream stream, + FT_ULong gps_offset, + FT_ULong offset, + FT_ULong size ); + + +FT_END_HEADER + + +#endif /* __PFRGLOAD_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/pfr/pfrload.c b/mod/pub.mod/freetype.mod/src/pfr/pfrload.c new file mode 100644 index 0000000..bc5c035 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/pfr/pfrload.c @@ -0,0 +1,941 @@ +/***************************************************************************/ +/* */ +/* pfrload.c */ +/* */ +/* FreeType PFR loader (body). */ +/* */ +/* Copyright 2002, 2003, 2004, 2005, 2007, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include "pfrload.h" +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H + +#include "pfrerror.h" + +#undef FT_COMPONENT +#define FT_COMPONENT trace_pfr + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** EXTRA ITEMS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + FT_LOCAL_DEF( FT_Error ) + pfr_extra_items_skip( FT_Byte* *pp, + FT_Byte* limit ) + { + return pfr_extra_items_parse( pp, limit, NULL, NULL ); + } + + + FT_LOCAL_DEF( FT_Error ) + pfr_extra_items_parse( FT_Byte* *pp, + FT_Byte* limit, + PFR_ExtraItem item_list, + FT_Pointer item_data ) + { + FT_Error error = 0; + FT_Byte* p = *pp; + FT_UInt num_items, item_type, item_size; + + + PFR_CHECK( 1 ); + num_items = PFR_NEXT_BYTE( p ); + + for ( ; num_items > 0; num_items-- ) + { + PFR_CHECK( 2 ); + item_size = PFR_NEXT_BYTE( p ); + item_type = PFR_NEXT_BYTE( p ); + + PFR_CHECK( item_size ); + + if ( item_list ) + { + PFR_ExtraItem extra = item_list; + + + for ( extra = item_list; extra->parser != NULL; extra++ ) + { + if ( extra->type == item_type ) + { + error = extra->parser( p, p + item_size, item_data ); + if ( error ) goto Exit; + + break; + } + } + } + + p += item_size; + } + + Exit: + *pp = p; + return error; + + Too_Short: + FT_ERROR(( "pfr_extra_items_parse: invalid extra items table\n" )); + error = PFR_Err_Invalid_Table; + goto Exit; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** PFR HEADER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static const FT_Frame_Field pfr_header_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE PFR_HeaderRec + + FT_FRAME_START( 58 ), + FT_FRAME_ULONG ( signature ), + FT_FRAME_USHORT( version ), + FT_FRAME_USHORT( signature2 ), + FT_FRAME_USHORT( header_size ), + + FT_FRAME_USHORT( log_dir_size ), + FT_FRAME_USHORT( log_dir_offset ), + + FT_FRAME_USHORT( log_font_max_size ), + FT_FRAME_UOFF3 ( log_font_section_size ), + FT_FRAME_UOFF3 ( log_font_section_offset ), + + FT_FRAME_USHORT( phy_font_max_size ), + FT_FRAME_UOFF3 ( phy_font_section_size ), + FT_FRAME_UOFF3 ( phy_font_section_offset ), + + FT_FRAME_USHORT( gps_max_size ), + FT_FRAME_UOFF3 ( gps_section_size ), + FT_FRAME_UOFF3 ( gps_section_offset ), + + FT_FRAME_BYTE ( max_blue_values ), + FT_FRAME_BYTE ( max_x_orus ), + FT_FRAME_BYTE ( max_y_orus ), + + FT_FRAME_BYTE ( phy_font_max_size_high ), + FT_FRAME_BYTE ( color_flags ), + + FT_FRAME_UOFF3 ( bct_max_size ), + FT_FRAME_UOFF3 ( bct_set_max_size ), + FT_FRAME_UOFF3 ( phy_bct_set_max_size ), + + FT_FRAME_USHORT( num_phy_fonts ), + FT_FRAME_BYTE ( max_vert_stem_snap ), + FT_FRAME_BYTE ( max_horz_stem_snap ), + FT_FRAME_USHORT( max_chars ), + FT_FRAME_END + }; + + + FT_LOCAL_DEF( FT_Error ) + pfr_header_load( PFR_Header header, + FT_Stream stream ) + { + FT_Error error; + + + /* read header directly */ + if ( !FT_STREAM_SEEK( 0 ) && + !FT_STREAM_READ_FIELDS( pfr_header_fields, header ) ) + { + /* make a few adjustments to the header */ + header->phy_font_max_size += + (FT_UInt32)header->phy_font_max_size_high << 16; + } + + return error; + } + + + FT_LOCAL_DEF( FT_Bool ) + pfr_header_check( PFR_Header header ) + { + FT_Bool result = 1; + + + /* check signature and header size */ + if ( header->signature != 0x50465230L || /* "PFR0" */ + header->version > 4 || + header->header_size < 58 || + header->signature2 != 0x0d0a ) /* CR/LF */ + { + result = 0; + } + return result; + } + + + /***********************************************************************/ + /***********************************************************************/ + /***** *****/ + /***** PFR LOGICAL FONTS *****/ + /***** *****/ + /***********************************************************************/ + /***********************************************************************/ + + + FT_LOCAL_DEF( FT_Error ) + pfr_log_font_count( FT_Stream stream, + FT_UInt32 section_offset, + FT_UInt *acount ) + { + FT_Error error; + FT_UInt count; + FT_UInt result = 0; + + + if ( FT_STREAM_SEEK( section_offset ) || FT_READ_USHORT( count ) ) + goto Exit; + + result = count; + + Exit: + *acount = result; + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + pfr_log_font_load( PFR_LogFont log_font, + FT_Stream stream, + FT_UInt idx, + FT_UInt32 section_offset, + FT_Bool size_increment ) + { + FT_UInt num_log_fonts; + FT_UInt flags; + FT_UInt32 offset; + FT_UInt32 size; + FT_Error error; + + + if ( FT_STREAM_SEEK( section_offset ) || + FT_READ_USHORT( num_log_fonts ) ) + goto Exit; + + if ( idx >= num_log_fonts ) + return PFR_Err_Invalid_Argument; + + if ( FT_STREAM_SKIP( idx * 5 ) || + FT_READ_USHORT( size ) || + FT_READ_UOFF3 ( offset ) ) + goto Exit; + + /* save logical font size and offset */ + log_font->size = size; + log_font->offset = offset; + + /* now, check the rest of the table before loading it */ + { + FT_Byte* p; + FT_Byte* limit; + FT_UInt local; + + + if ( FT_STREAM_SEEK( offset ) || FT_FRAME_ENTER( size ) ) + goto Exit; + + p = stream->cursor; + limit = p + size; + + PFR_CHECK(13); + + log_font->matrix[0] = PFR_NEXT_LONG( p ); + log_font->matrix[1] = PFR_NEXT_LONG( p ); + log_font->matrix[2] = PFR_NEXT_LONG( p ); + log_font->matrix[3] = PFR_NEXT_LONG( p ); + + flags = PFR_NEXT_BYTE( p ); + + local = 0; + if ( flags & PFR_LOG_STROKE ) + { + local++; + if ( flags & PFR_LOG_2BYTE_STROKE ) + local++; + + if ( (flags & PFR_LINE_JOIN_MASK) == PFR_LINE_JOIN_MITER ) + local += 3; + } + if ( flags & PFR_LOG_BOLD ) + { + local++; + if ( flags & PFR_LOG_2BYTE_BOLD ) + local++; + } + + PFR_CHECK( local ); + + if ( flags & PFR_LOG_STROKE ) + { + log_font->stroke_thickness = ( flags & PFR_LOG_2BYTE_STROKE ) + ? PFR_NEXT_SHORT( p ) + : PFR_NEXT_BYTE( p ); + + if ( ( flags & PFR_LINE_JOIN_MASK ) == PFR_LINE_JOIN_MITER ) + log_font->miter_limit = PFR_NEXT_LONG( p ); + } + + if ( flags & PFR_LOG_BOLD ) + { + log_font->bold_thickness = ( flags & PFR_LOG_2BYTE_BOLD ) + ? PFR_NEXT_SHORT( p ) + : PFR_NEXT_BYTE( p ); + } + + if ( flags & PFR_LOG_EXTRA_ITEMS ) + { + error = pfr_extra_items_skip( &p, limit ); + if (error) goto Fail; + } + + PFR_CHECK(5); + log_font->phys_size = PFR_NEXT_USHORT( p ); + log_font->phys_offset = PFR_NEXT_ULONG( p ); + if ( size_increment ) + { + PFR_CHECK( 1 ); + log_font->phys_size += (FT_UInt32)PFR_NEXT_BYTE( p ) << 16; + } + } + + Fail: + FT_FRAME_EXIT(); + + Exit: + return error; + + Too_Short: + FT_ERROR(( "pfr_log_font_load: invalid logical font table\n" )); + error = PFR_Err_Invalid_Table; + goto Fail; + } + + + /***********************************************************************/ + /***********************************************************************/ + /***** *****/ + /***** PFR PHYSICAL FONTS *****/ + /***** *****/ + /***********************************************************************/ + /***********************************************************************/ + + + /* load bitmap strikes lists */ + FT_CALLBACK_DEF( FT_Error ) + pfr_extra_item_load_bitmap_info( FT_Byte* p, + FT_Byte* limit, + PFR_PhyFont phy_font ) + { + FT_Memory memory = phy_font->memory; + PFR_Strike strike; + FT_UInt flags0; + FT_UInt n, count, size1; + FT_Error error = 0; + + + PFR_CHECK( 5 ); + + p += 3; /* skip bctSize */ + flags0 = PFR_NEXT_BYTE( p ); + count = PFR_NEXT_BYTE( p ); + + /* re-allocate when needed */ + if ( phy_font->num_strikes + count > phy_font->max_strikes ) + { + FT_UInt new_max = FT_PAD_CEIL( phy_font->num_strikes + count, 4 ); + + + if ( FT_RENEW_ARRAY( phy_font->strikes, + phy_font->num_strikes, + new_max ) ) + goto Exit; + + phy_font->max_strikes = new_max; + } + + size1 = 1 + 1 + 1 + 2 + 2 + 1; + if ( flags0 & PFR_STRIKE_2BYTE_XPPM ) + size1++; + + if ( flags0 & PFR_STRIKE_2BYTE_YPPM ) + size1++; + + if ( flags0 & PFR_STRIKE_3BYTE_SIZE ) + size1++; + + if ( flags0 & PFR_STRIKE_3BYTE_OFFSET ) + size1++; + + if ( flags0 & PFR_STRIKE_2BYTE_COUNT ) + size1++; + + strike = phy_font->strikes + phy_font->num_strikes; + + PFR_CHECK( count * size1 ); + + for ( n = 0; n < count; n++, strike++ ) + { + strike->x_ppm = ( flags0 & PFR_STRIKE_2BYTE_XPPM ) + ? PFR_NEXT_USHORT( p ) + : PFR_NEXT_BYTE( p ); + + strike->y_ppm = ( flags0 & PFR_STRIKE_2BYTE_YPPM ) + ? PFR_NEXT_USHORT( p ) + : PFR_NEXT_BYTE( p ); + + strike->flags = PFR_NEXT_BYTE( p ); + + strike->bct_size = ( flags0 & PFR_STRIKE_3BYTE_SIZE ) + ? PFR_NEXT_ULONG( p ) + : PFR_NEXT_USHORT( p ); + + strike->bct_offset = ( flags0 & PFR_STRIKE_3BYTE_OFFSET ) + ? PFR_NEXT_ULONG( p ) + : PFR_NEXT_USHORT( p ); + + strike->num_bitmaps = ( flags0 & PFR_STRIKE_2BYTE_COUNT ) + ? PFR_NEXT_USHORT( p ) + : PFR_NEXT_BYTE( p ); + } + + phy_font->num_strikes += count; + + Exit: + return error; + + Too_Short: + error = PFR_Err_Invalid_Table; + FT_ERROR(( "pfr_extra_item_load_bitmap_info:" + " invalid bitmap info table\n" )); + goto Exit; + } + + + /* Load font ID. This is a so-called "unique" name that is rather + * long and descriptive (like "Tiresias ScreenFont v7.51"). + * + * Note that a PFR font's family name is contained in an *undocumented* + * string of the "auxiliary data" portion of a physical font record. This + * may also contain the "real" style name! + * + * If no family name is present, the font ID is used instead for the + * family. + */ + FT_CALLBACK_DEF( FT_Error ) + pfr_extra_item_load_font_id( FT_Byte* p, + FT_Byte* limit, + PFR_PhyFont phy_font ) + { + FT_Error error = 0; + FT_Memory memory = phy_font->memory; + FT_PtrDist len = limit - p; + + + if ( phy_font->font_id != NULL ) + goto Exit; + + if ( FT_ALLOC( phy_font->font_id, len + 1 ) ) + goto Exit; + + /* copy font ID name, and terminate it for safety */ + FT_MEM_COPY( phy_font->font_id, p, len ); + phy_font->font_id[len] = 0; + + Exit: + return error; + } + + + /* load stem snap tables */ + FT_CALLBACK_DEF( FT_Error ) + pfr_extra_item_load_stem_snaps( FT_Byte* p, + FT_Byte* limit, + PFR_PhyFont phy_font ) + { + FT_UInt count, num_vert, num_horz; + FT_Int* snaps; + FT_Error error = 0; + FT_Memory memory = phy_font->memory; + + + if ( phy_font->vertical.stem_snaps != NULL ) + goto Exit; + + PFR_CHECK( 1 ); + count = PFR_NEXT_BYTE( p ); + + num_vert = count & 15; + num_horz = count >> 4; + count = num_vert + num_horz; + + PFR_CHECK( count * 2 ); + + if ( FT_NEW_ARRAY( snaps, count ) ) + goto Exit; + + phy_font->vertical.stem_snaps = snaps; + phy_font->horizontal.stem_snaps = snaps + num_vert; + + for ( ; count > 0; count--, snaps++ ) + *snaps = FT_NEXT_SHORT( p ); + + Exit: + return error; + + Too_Short: + error = PFR_Err_Invalid_Table; + FT_ERROR(( "pfr_exta_item_load_stem_snaps:" + " invalid stem snaps table\n" )); + goto Exit; + } + + + + /* load kerning pair data */ + FT_CALLBACK_DEF( FT_Error ) + pfr_extra_item_load_kerning_pairs( FT_Byte* p, + FT_Byte* limit, + PFR_PhyFont phy_font ) + { + PFR_KernItem item; + FT_Error error = 0; + FT_Memory memory = phy_font->memory; + + + FT_TRACE2(( "pfr_extra_item_load_kerning_pairs()\n" )); + + if ( FT_NEW( item ) ) + goto Exit; + + PFR_CHECK( 4 ); + + item->pair_count = PFR_NEXT_BYTE( p ); + item->base_adj = PFR_NEXT_SHORT( p ); + item->flags = PFR_NEXT_BYTE( p ); + item->offset = phy_font->offset + ( p - phy_font->cursor ); + +#ifndef PFR_CONFIG_NO_CHECKS + item->pair_size = 3; + + if ( item->flags & PFR_KERN_2BYTE_CHAR ) + item->pair_size += 2; + + if ( item->flags & PFR_KERN_2BYTE_ADJ ) + item->pair_size += 1; + + PFR_CHECK( item->pair_count * item->pair_size ); +#endif + + /* load first and last pairs into the item to speed up */ + /* lookup later... */ + if ( item->pair_count > 0 ) + { + FT_UInt char1, char2; + FT_Byte* q; + + + if ( item->flags & PFR_KERN_2BYTE_CHAR ) + { + q = p; + char1 = PFR_NEXT_USHORT( q ); + char2 = PFR_NEXT_USHORT( q ); + + item->pair1 = PFR_KERN_INDEX( char1, char2 ); + + q = p + item->pair_size * ( item->pair_count - 1 ); + char1 = PFR_NEXT_USHORT( q ); + char2 = PFR_NEXT_USHORT( q ); + + item->pair2 = PFR_KERN_INDEX( char1, char2 ); + } + else + { + q = p; + char1 = PFR_NEXT_BYTE( q ); + char2 = PFR_NEXT_BYTE( q ); + + item->pair1 = PFR_KERN_INDEX( char1, char2 ); + + q = p + item->pair_size * ( item->pair_count - 1 ); + char1 = PFR_NEXT_BYTE( q ); + char2 = PFR_NEXT_BYTE( q ); + + item->pair2 = PFR_KERN_INDEX( char1, char2 ); + } + + /* add new item to the current list */ + item->next = NULL; + *phy_font->kern_items_tail = item; + phy_font->kern_items_tail = &item->next; + phy_font->num_kern_pairs += item->pair_count; + } + else + { + /* empty item! */ + FT_FREE( item ); + } + + Exit: + return error; + + Too_Short: + FT_FREE( item ); + + error = PFR_Err_Invalid_Table; + FT_ERROR(( "pfr_extra_item_load_kerning_pairs:" + " invalid kerning pairs table\n" )); + goto Exit; + } + + + + static const PFR_ExtraItemRec pfr_phy_font_extra_items[] = + { + { 1, (PFR_ExtraItem_ParseFunc)pfr_extra_item_load_bitmap_info }, + { 2, (PFR_ExtraItem_ParseFunc)pfr_extra_item_load_font_id }, + { 3, (PFR_ExtraItem_ParseFunc)pfr_extra_item_load_stem_snaps }, + { 4, (PFR_ExtraItem_ParseFunc)pfr_extra_item_load_kerning_pairs }, + { 0, NULL } + }; + + + /* Loads a name from the auxiliary data. Since this extracts undocumented + * strings from the font file, we need to be careful here. + */ + static FT_Error + pfr_aux_name_load( FT_Byte* p, + FT_UInt len, + FT_Memory memory, + FT_String* *astring ) + { + FT_Error error = 0; + FT_String* result = NULL; + FT_UInt n, ok; + + + if ( len > 0 && p[len - 1] == 0 ) + len--; + + /* check that each character is ASCII for making sure not to + load garbage + */ + ok = ( len > 0 ); + for ( n = 0; n < len; n++ ) + if ( p[n] < 32 || p[n] > 127 ) + { + ok = 0; + break; + } + + if ( ok ) + { + if ( FT_ALLOC( result, len + 1 ) ) + goto Exit; + + FT_MEM_COPY( result, p, len ); + result[len] = 0; + } + Exit: + *astring = result; + return error; + } + + + FT_LOCAL_DEF( void ) + pfr_phy_font_done( PFR_PhyFont phy_font, + FT_Memory memory ) + { + FT_FREE( phy_font->font_id ); + FT_FREE( phy_font->family_name ); + FT_FREE( phy_font->style_name ); + + FT_FREE( phy_font->vertical.stem_snaps ); + phy_font->vertical.num_stem_snaps = 0; + + phy_font->horizontal.stem_snaps = NULL; + phy_font->horizontal.num_stem_snaps = 0; + + FT_FREE( phy_font->strikes ); + phy_font->num_strikes = 0; + phy_font->max_strikes = 0; + + FT_FREE( phy_font->chars ); + phy_font->num_chars = 0; + phy_font->chars_offset = 0; + + FT_FREE( phy_font->blue_values ); + phy_font->num_blue_values = 0; + + { + PFR_KernItem item, next; + + + item = phy_font->kern_items; + while ( item ) + { + next = item->next; + FT_FREE( item ); + item = next; + } + phy_font->kern_items = NULL; + phy_font->kern_items_tail = NULL; + } + + phy_font->num_kern_pairs = 0; + } + + + FT_LOCAL_DEF( FT_Error ) + pfr_phy_font_load( PFR_PhyFont phy_font, + FT_Stream stream, + FT_UInt32 offset, + FT_UInt32 size ) + { + FT_Error error; + FT_Memory memory = stream->memory; + FT_UInt flags; + FT_ULong num_aux; + FT_Byte* p; + FT_Byte* limit; + + + phy_font->memory = memory; + phy_font->offset = offset; + + phy_font->kern_items = NULL; + phy_font->kern_items_tail = &phy_font->kern_items; + + if ( FT_STREAM_SEEK( offset ) || FT_FRAME_ENTER( size ) ) + goto Exit; + + phy_font->cursor = stream->cursor; + + p = stream->cursor; + limit = p + size; + + PFR_CHECK( 15 ); + phy_font->font_ref_number = PFR_NEXT_USHORT( p ); + phy_font->outline_resolution = PFR_NEXT_USHORT( p ); + phy_font->metrics_resolution = PFR_NEXT_USHORT( p ); + phy_font->bbox.xMin = PFR_NEXT_SHORT( p ); + phy_font->bbox.yMin = PFR_NEXT_SHORT( p ); + phy_font->bbox.xMax = PFR_NEXT_SHORT( p ); + phy_font->bbox.yMax = PFR_NEXT_SHORT( p ); + phy_font->flags = flags = PFR_NEXT_BYTE( p ); + + /* get the standard advance for non-proportional fonts */ + if ( !(flags & PFR_PHY_PROPORTIONAL) ) + { + PFR_CHECK( 2 ); + phy_font->standard_advance = PFR_NEXT_SHORT( p ); + } + + /* load the extra items when present */ + if ( flags & PFR_PHY_EXTRA_ITEMS ) + { + error = pfr_extra_items_parse( &p, limit, + pfr_phy_font_extra_items, phy_font ); + + if ( error ) + goto Fail; + } + + /* In certain fonts, the auxiliary bytes contain interesting */ + /* information. These are not in the specification but can be */ + /* guessed by looking at the content of a few PFR0 fonts. */ + PFR_CHECK( 3 ); + num_aux = PFR_NEXT_ULONG( p ); + + if ( num_aux > 0 ) + { + FT_Byte* q = p; + FT_Byte* q2; + + + PFR_CHECK( num_aux ); + p += num_aux; + + while ( num_aux > 0 ) + { + FT_UInt length, type; + + + if ( q + 4 > p ) + break; + + length = PFR_NEXT_USHORT( q ); + if ( length < 4 || length > num_aux ) + break; + + q2 = q + length - 2; + type = PFR_NEXT_USHORT( q ); + + switch ( type ) + { + case 1: + /* this seems to correspond to the font's family name, + * padded to 16-bits with one zero when necessary + */ + error = pfr_aux_name_load( q, length - 4U, memory, + &phy_font->family_name ); + if ( error ) + goto Exit; + break; + + case 2: + if ( q + 32 > q2 ) + break; + + q += 10; + phy_font->ascent = PFR_NEXT_SHORT( q ); + phy_font->descent = PFR_NEXT_SHORT( q ); + phy_font->leading = PFR_NEXT_SHORT( q ); + q += 16; + break; + + case 3: + /* this seems to correspond to the font's style name, + * padded to 16-bits with one zero when necessary + */ + error = pfr_aux_name_load( q, length - 4U, memory, + &phy_font->style_name ); + if ( error ) + goto Exit; + break; + + default: + ; + } + + q = q2; + num_aux -= length; + } + } + + /* read the blue values */ + { + FT_UInt n, count; + + + PFR_CHECK( 1 ); + phy_font->num_blue_values = count = PFR_NEXT_BYTE( p ); + + PFR_CHECK( count * 2 ); + + if ( FT_NEW_ARRAY( phy_font->blue_values, count ) ) + goto Fail; + + for ( n = 0; n < count; n++ ) + phy_font->blue_values[n] = PFR_NEXT_SHORT( p ); + } + + PFR_CHECK( 8 ); + phy_font->blue_fuzz = PFR_NEXT_BYTE( p ); + phy_font->blue_scale = PFR_NEXT_BYTE( p ); + + phy_font->vertical.standard = PFR_NEXT_USHORT( p ); + phy_font->horizontal.standard = PFR_NEXT_USHORT( p ); + + /* read the character descriptors */ + { + FT_UInt n, count, Size; + + + phy_font->num_chars = count = PFR_NEXT_USHORT( p ); + phy_font->chars_offset = offset + ( p - stream->cursor ); + + if ( FT_NEW_ARRAY( phy_font->chars, count ) ) + goto Fail; + + Size = 1 + 1 + 2; + if ( flags & PFR_PHY_2BYTE_CHARCODE ) + Size += 1; + + if ( flags & PFR_PHY_PROPORTIONAL ) + Size += 2; + + if ( flags & PFR_PHY_ASCII_CODE ) + Size += 1; + + if ( flags & PFR_PHY_2BYTE_GPS_SIZE ) + Size += 1; + + if ( flags & PFR_PHY_3BYTE_GPS_OFFSET ) + Size += 1; + + PFR_CHECK( count * Size ); + + for ( n = 0; n < count; n++ ) + { + PFR_Char cur = &phy_font->chars[n]; + + + cur->char_code = ( flags & PFR_PHY_2BYTE_CHARCODE ) + ? PFR_NEXT_USHORT( p ) + : PFR_NEXT_BYTE( p ); + + cur->advance = ( flags & PFR_PHY_PROPORTIONAL ) + ? PFR_NEXT_SHORT( p ) + : (FT_Int) phy_font->standard_advance; + +#if 0 + cur->ascii = ( flags & PFR_PHY_ASCII_CODE ) + ? PFR_NEXT_BYTE( p ) + : 0; +#else + if ( flags & PFR_PHY_ASCII_CODE ) + p += 1; +#endif + cur->gps_size = ( flags & PFR_PHY_2BYTE_GPS_SIZE ) + ? PFR_NEXT_USHORT( p ) + : PFR_NEXT_BYTE( p ); + + cur->gps_offset = ( flags & PFR_PHY_3BYTE_GPS_OFFSET ) + ? PFR_NEXT_ULONG( p ) + : PFR_NEXT_USHORT( p ); + } + } + + /* that's it! */ + + Fail: + FT_FRAME_EXIT(); + + /* save position of bitmap info */ + phy_font->bct_offset = FT_STREAM_POS(); + phy_font->cursor = NULL; + + Exit: + return error; + + Too_Short: + error = PFR_Err_Invalid_Table; + FT_ERROR(( "pfr_phy_font_load: invalid physical font table\n" )); + goto Fail; + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/pfr/pfrload.h b/mod/pub.mod/freetype.mod/src/pfr/pfrload.h new file mode 100644 index 0000000..ed01071 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/pfr/pfrload.h @@ -0,0 +1,118 @@ +/***************************************************************************/ +/* */ +/* pfrload.h */ +/* */ +/* FreeType PFR loader (specification). */ +/* */ +/* Copyright 2002 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __PFRLOAD_H__ +#define __PFRLOAD_H__ + +#include "pfrobjs.h" +#include FT_INTERNAL_STREAM_H + + +FT_BEGIN_HEADER + +#ifdef PFR_CONFIG_NO_CHECKS +#define PFR_CHECK( x ) do { } while ( 0 ) +#else +#define PFR_CHECK( x ) do \ + { \ + if ( p + (x) > limit ) \ + goto Too_Short; \ + } while ( 0 ) +#endif + +#define PFR_NEXT_BYTE( p ) FT_NEXT_BYTE( p ) +#define PFR_NEXT_INT8( p ) FT_NEXT_CHAR( p ) +#define PFR_NEXT_SHORT( p ) FT_NEXT_SHORT( p ) +#define PFR_NEXT_USHORT( p ) FT_NEXT_USHORT( p ) +#define PFR_NEXT_LONG( p ) FT_NEXT_OFF3( p ) +#define PFR_NEXT_ULONG( p ) FT_NEXT_UOFF3( p ) + + + /* handling extra items */ + + typedef FT_Error + (*PFR_ExtraItem_ParseFunc)( FT_Byte* p, + FT_Byte* limit, + FT_Pointer data ); + + typedef struct PFR_ExtraItemRec_ + { + FT_UInt type; + PFR_ExtraItem_ParseFunc parser; + + } PFR_ExtraItemRec; + + typedef const struct PFR_ExtraItemRec_* PFR_ExtraItem; + + + FT_LOCAL( FT_Error ) + pfr_extra_items_skip( FT_Byte* *pp, + FT_Byte* limit ); + + FT_LOCAL( FT_Error ) + pfr_extra_items_parse( FT_Byte* *pp, + FT_Byte* limit, + PFR_ExtraItem item_list, + FT_Pointer item_data ); + + + /* load a PFR header */ + FT_LOCAL( FT_Error ) + pfr_header_load( PFR_Header header, + FT_Stream stream ); + + /* check a PFR header */ + FT_LOCAL( FT_Bool ) + pfr_header_check( PFR_Header header ); + + + /* return number of logical fonts in this file */ + FT_LOCAL( FT_Error ) + pfr_log_font_count( FT_Stream stream, + FT_UInt32 log_section_offset, + FT_UInt *acount ); + + /* load a pfr logical font entry */ + FT_LOCAL( FT_Error ) + pfr_log_font_load( PFR_LogFont log_font, + FT_Stream stream, + FT_UInt face_index, + FT_UInt32 section_offset, + FT_Bool size_increment ); + + + /* load a physical font entry */ + FT_LOCAL( FT_Error ) + pfr_phy_font_load( PFR_PhyFont phy_font, + FT_Stream stream, + FT_UInt32 offset, + FT_UInt32 size ); + + /* finalize a physical font */ + FT_LOCAL( void ) + pfr_phy_font_done( PFR_PhyFont phy_font, + FT_Memory memory ); + + /* */ + +FT_END_HEADER + +#endif /* __PFRLOAD_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/pfr/pfrobjs.c b/mod/pub.mod/freetype.mod/src/pfr/pfrobjs.c new file mode 100644 index 0000000..56d617d --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/pfr/pfrobjs.c @@ -0,0 +1,581 @@ +/***************************************************************************/ +/* */ +/* pfrobjs.c */ +/* */ +/* FreeType PFR object methods (body). */ +/* */ +/* Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include "pfrobjs.h" +#include "pfrload.h" +#include "pfrgload.h" +#include "pfrcmap.h" +#include "pfrsbit.h" +#include FT_OUTLINE_H +#include FT_INTERNAL_DEBUG_H + +#include "pfrerror.h" + +#undef FT_COMPONENT +#define FT_COMPONENT trace_pfr + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** FACE OBJECT METHODS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL_DEF( void ) + pfr_face_done( FT_Face pfrface ) /* PFR_Face */ + { + PFR_Face face = (PFR_Face)pfrface; + FT_Memory memory; + + + if ( !face ) + return; + + memory = pfrface->driver->root.memory; + + /* we don't want dangling pointers */ + pfrface->family_name = NULL; + pfrface->style_name = NULL; + + /* finalize the physical font record */ + pfr_phy_font_done( &face->phy_font, FT_FACE_MEMORY( face ) ); + + /* no need to finalize the logical font or the header */ + FT_FREE( pfrface->available_sizes ); + } + + + FT_LOCAL_DEF( FT_Error ) + pfr_face_init( FT_Stream stream, + FT_Face pfrface, + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ) + { + PFR_Face face = (PFR_Face)pfrface; + FT_Error error; + + FT_UNUSED( num_params ); + FT_UNUSED( params ); + + + /* load the header and check it */ + error = pfr_header_load( &face->header, stream ); + if ( error ) + goto Exit; + + if ( !pfr_header_check( &face->header ) ) + { + FT_TRACE4(( "pfr_face_init: not a valid PFR font\n" )); + error = PFR_Err_Unknown_File_Format; + goto Exit; + } + + /* check face index */ + { + FT_UInt num_faces; + + + error = pfr_log_font_count( stream, + face->header.log_dir_offset, + &num_faces ); + if ( error ) + goto Exit; + + pfrface->num_faces = num_faces; + } + + if ( face_index < 0 ) + goto Exit; + + if ( face_index >= pfrface->num_faces ) + { + FT_ERROR(( "pfr_face_init: invalid face index\n" )); + error = PFR_Err_Invalid_Argument; + goto Exit; + } + + /* load the face */ + error = pfr_log_font_load( + &face->log_font, stream, face_index, + face->header.log_dir_offset, + FT_BOOL( face->header.phy_font_max_size_high != 0 ) ); + if ( error ) + goto Exit; + + /* now load the physical font descriptor */ + error = pfr_phy_font_load( &face->phy_font, stream, + face->log_font.phys_offset, + face->log_font.phys_size ); + if ( error ) + goto Exit; + + /* now set up all root face fields */ + { + PFR_PhyFont phy_font = &face->phy_font; + + + pfrface->face_index = face_index; + pfrface->num_glyphs = phy_font->num_chars + 1; + pfrface->face_flags = FT_FACE_FLAG_SCALABLE; + + /* if all characters point to the same gps_offset 0, we */ + /* assume that the font only contains bitmaps */ + { + FT_UInt nn; + + + for ( nn = 0; nn < phy_font->num_chars; nn++ ) + if ( phy_font->chars[nn].gps_offset != 0 ) + break; + + if ( nn == phy_font->num_chars ) + pfrface->face_flags = 0; /* not scalable */ + } + + if ( (phy_font->flags & PFR_PHY_PROPORTIONAL) == 0 ) + pfrface->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; + + if ( phy_font->flags & PFR_PHY_VERTICAL ) + pfrface->face_flags |= FT_FACE_FLAG_VERTICAL; + else + pfrface->face_flags |= FT_FACE_FLAG_HORIZONTAL; + + if ( phy_font->num_strikes > 0 ) + pfrface->face_flags |= FT_FACE_FLAG_FIXED_SIZES; + + if ( phy_font->num_kern_pairs > 0 ) + pfrface->face_flags |= FT_FACE_FLAG_KERNING; + + /* If no family name was found in the "undocumented" auxiliary + * data, use the font ID instead. This sucks but is better than + * nothing. + */ + pfrface->family_name = phy_font->family_name; + if ( pfrface->family_name == NULL ) + pfrface->family_name = phy_font->font_id; + + /* note that the style name can be NULL in certain PFR fonts, + * probably meaning "Regular" + */ + pfrface->style_name = phy_font->style_name; + + pfrface->num_fixed_sizes = 0; + pfrface->available_sizes = 0; + + pfrface->bbox = phy_font->bbox; + pfrface->units_per_EM = (FT_UShort)phy_font->outline_resolution; + pfrface->ascender = (FT_Short) phy_font->bbox.yMax; + pfrface->descender = (FT_Short) phy_font->bbox.yMin; + + pfrface->height = (FT_Short)( ( pfrface->units_per_EM * 12 ) / 10 ); + if ( pfrface->height < pfrface->ascender - pfrface->descender ) + pfrface->height = (FT_Short)(pfrface->ascender - pfrface->descender); + + if ( phy_font->num_strikes > 0 ) + { + FT_UInt n, count = phy_font->num_strikes; + FT_Bitmap_Size* size; + PFR_Strike strike; + FT_Memory memory = pfrface->stream->memory; + + + if ( FT_NEW_ARRAY( pfrface->available_sizes, count ) ) + goto Exit; + + size = pfrface->available_sizes; + strike = phy_font->strikes; + for ( n = 0; n < count; n++, size++, strike++ ) + { + size->height = (FT_UShort)strike->y_ppm; + size->width = (FT_UShort)strike->x_ppm; + size->size = strike->y_ppm << 6; + size->x_ppem = strike->x_ppm << 6; + size->y_ppem = strike->y_ppm << 6; + } + pfrface->num_fixed_sizes = count; + } + + /* now compute maximum advance width */ + if ( ( phy_font->flags & PFR_PHY_PROPORTIONAL ) == 0 ) + pfrface->max_advance_width = (FT_Short)phy_font->standard_advance; + else + { + FT_Int max = 0; + FT_UInt count = phy_font->num_chars; + PFR_Char gchar = phy_font->chars; + + + for ( ; count > 0; count--, gchar++ ) + { + if ( max < gchar->advance ) + max = gchar->advance; + } + + pfrface->max_advance_width = (FT_Short)max; + } + + pfrface->max_advance_height = pfrface->height; + + pfrface->underline_position = (FT_Short)( -pfrface->units_per_EM / 10 ); + pfrface->underline_thickness = (FT_Short)( pfrface->units_per_EM / 30 ); + + /* create charmap */ + { + FT_CharMapRec charmap; + + + charmap.face = pfrface; + charmap.platform_id = 3; + charmap.encoding_id = 1; + charmap.encoding = FT_ENCODING_UNICODE; + + FT_CMap_New( &pfr_cmap_class_rec, NULL, &charmap, NULL ); + +#if 0 + /* Select default charmap */ + if ( pfrface->num_charmaps ) + pfrface->charmap = pfrface->charmaps[0]; +#endif + } + + /* check whether we've loaded any kerning pairs */ + if ( phy_font->num_kern_pairs ) + pfrface->face_flags |= FT_FACE_FLAG_KERNING; + } + + Exit: + return error; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** SLOT OBJECT METHOD *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL_DEF( FT_Error ) + pfr_slot_init( FT_GlyphSlot pfrslot ) /* PFR_Slot */ + { + PFR_Slot slot = (PFR_Slot)pfrslot; + FT_GlyphLoader loader = pfrslot->internal->loader; + + + pfr_glyph_init( &slot->glyph, loader ); + + return 0; + } + + + FT_LOCAL_DEF( void ) + pfr_slot_done( FT_GlyphSlot pfrslot ) /* PFR_Slot */ + { + PFR_Slot slot = (PFR_Slot)pfrslot; + + + pfr_glyph_done( &slot->glyph ); + } + + + FT_LOCAL_DEF( FT_Error ) + pfr_slot_load( FT_GlyphSlot pfrslot, /* PFR_Slot */ + FT_Size pfrsize, /* PFR_Size */ + FT_UInt gindex, + FT_Int32 load_flags ) + { + PFR_Slot slot = (PFR_Slot)pfrslot; + PFR_Size size = (PFR_Size)pfrsize; + FT_Error error; + PFR_Face face = (PFR_Face)pfrslot->face; + PFR_Char gchar; + FT_Outline* outline = &pfrslot->outline; + FT_ULong gps_offset; + + + if ( gindex > 0 ) + gindex--; + + if ( !face || gindex >= face->phy_font.num_chars ) + { + error = PFR_Err_Invalid_Argument; + goto Exit; + } + + /* try to load an embedded bitmap */ + if ( ( load_flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP ) ) == 0 ) + { + error = pfr_slot_load_bitmap( slot, size, gindex ); + if ( error == 0 ) + goto Exit; + } + + if ( load_flags & FT_LOAD_SBITS_ONLY ) + { + error = PFR_Err_Invalid_Argument; + goto Exit; + } + + gchar = face->phy_font.chars + gindex; + pfrslot->format = FT_GLYPH_FORMAT_OUTLINE; + outline->n_points = 0; + outline->n_contours = 0; + gps_offset = face->header.gps_section_offset; + + /* load the glyph outline (FT_LOAD_NO_RECURSE isn't supported) */ + error = pfr_glyph_load( &slot->glyph, face->root.stream, + gps_offset, gchar->gps_offset, gchar->gps_size ); + + if ( !error ) + { + FT_BBox cbox; + FT_Glyph_Metrics* metrics = &pfrslot->metrics; + FT_Pos advance; + FT_Int em_metrics, em_outline; + FT_Bool scaling; + + + scaling = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 ); + + /* copy outline data */ + *outline = slot->glyph.loader->base.outline; + + outline->flags &= ~FT_OUTLINE_OWNER; + outline->flags |= FT_OUTLINE_REVERSE_FILL; + + if ( size && pfrsize->metrics.y_ppem < 24 ) + outline->flags |= FT_OUTLINE_HIGH_PRECISION; + + /* compute the advance vector */ + metrics->horiAdvance = 0; + metrics->vertAdvance = 0; + + advance = gchar->advance; + em_metrics = face->phy_font.metrics_resolution; + em_outline = face->phy_font.outline_resolution; + + if ( em_metrics != em_outline ) + advance = FT_MulDiv( advance, em_outline, em_metrics ); + + if ( face->phy_font.flags & PFR_PHY_VERTICAL ) + metrics->vertAdvance = advance; + else + metrics->horiAdvance = advance; + + pfrslot->linearHoriAdvance = metrics->horiAdvance; + pfrslot->linearVertAdvance = metrics->vertAdvance; + + /* make-up vertical metrics(?) */ + metrics->vertBearingX = 0; + metrics->vertBearingY = 0; + +#if 0 /* some fonts seem to be broken here! */ + + /* Apply the font matrix, if any. */ + /* TODO: Test existing fonts with unusual matrix */ + /* whether we have to adjust Units per EM. */ + { + FT_Matrix font_matrix; + + + font_matrix.xx = face->log_font.matrix[0] << 8; + font_matrix.yx = face->log_font.matrix[1] << 8; + font_matrix.xy = face->log_font.matrix[2] << 8; + font_matrix.yy = face->log_font.matrix[3] << 8; + + FT_Outline_Transform( outline, &font_matrix ); + } +#endif + + /* scale when needed */ + if ( scaling ) + { + FT_Int n; + FT_Fixed x_scale = pfrsize->metrics.x_scale; + FT_Fixed y_scale = pfrsize->metrics.y_scale; + FT_Vector* vec = outline->points; + + + /* scale outline points */ + for ( n = 0; n < outline->n_points; n++, vec++ ) + { + vec->x = FT_MulFix( vec->x, x_scale ); + vec->y = FT_MulFix( vec->y, y_scale ); + } + + /* scale the advance */ + metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale ); + metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale ); + } + + /* compute the rest of the metrics */ + FT_Outline_Get_CBox( outline, &cbox ); + + metrics->width = cbox.xMax - cbox.xMin; + metrics->height = cbox.yMax - cbox.yMin; + metrics->horiBearingX = cbox.xMin; + metrics->horiBearingY = cbox.yMax - metrics->height; + } + + Exit: + return error; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** KERNING METHOD *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL_DEF( FT_Error ) + pfr_face_get_kerning( FT_Face pfrface, /* PFR_Face */ + FT_UInt glyph1, + FT_UInt glyph2, + FT_Vector* kerning ) + { + PFR_Face face = (PFR_Face)pfrface; + FT_Error error = PFR_Err_Ok; + PFR_PhyFont phy_font = &face->phy_font; + FT_UInt32 code1, code2, pair; + + + kerning->x = 0; + kerning->y = 0; + + if ( glyph1 > 0 ) + glyph1--; + + if ( glyph2 > 0 ) + glyph2--; + + /* convert glyph indices to character codes */ + if ( glyph1 > phy_font->num_chars || + glyph2 > phy_font->num_chars ) + goto Exit; + + code1 = phy_font->chars[glyph1].char_code; + code2 = phy_font->chars[glyph2].char_code; + pair = PFR_KERN_INDEX( code1, code2 ); + + /* now search the list of kerning items */ + { + PFR_KernItem item = phy_font->kern_items; + FT_Stream stream = pfrface->stream; + + + for ( ; item; item = item->next ) + { + if ( pair >= item->pair1 && pair <= item->pair2 ) + goto FoundPair; + } + goto Exit; + + FoundPair: /* we found an item, now parse it and find the value if any */ + if ( FT_STREAM_SEEK( item->offset ) || + FT_FRAME_ENTER( item->pair_count * item->pair_size ) ) + goto Exit; + + { + FT_UInt count = item->pair_count; + FT_UInt size = item->pair_size; + FT_UInt power = (FT_UInt)ft_highpow2( (FT_UInt32)count ); + FT_UInt probe = power * size; + FT_UInt extra = count - power; + FT_Byte* base = stream->cursor; + FT_Bool twobytes = FT_BOOL( item->flags & 1 ); + FT_Bool twobyte_adj = FT_BOOL( item->flags & 2 ); + FT_Byte* p; + FT_UInt32 cpair; + + + if ( extra > 0 ) + { + p = base + extra * size; + + if ( twobytes ) + cpair = FT_NEXT_ULONG( p ); + else + cpair = PFR_NEXT_KPAIR( p ); + + if ( cpair == pair ) + goto Found; + + if ( cpair < pair ) + { + if ( twobyte_adj ) + p += 2; + else + p++; + base = p; + } + } + + while ( probe > size ) + { + probe >>= 1; + p = base + probe; + + if ( twobytes ) + cpair = FT_NEXT_ULONG( p ); + else + cpair = PFR_NEXT_KPAIR( p ); + + if ( cpair == pair ) + goto Found; + + if ( cpair < pair ) + base += probe; + } + + p = base; + + if ( twobytes ) + cpair = FT_NEXT_ULONG( p ); + else + cpair = PFR_NEXT_KPAIR( p ); + + if ( cpair == pair ) + { + FT_Int value; + + + Found: + if ( twobyte_adj ) + value = FT_PEEK_SHORT( p ); + else + value = p[0]; + + kerning->x = item->base_adj + value; + } + } + + FT_FRAME_EXIT(); + } + + Exit: + return error; + } + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/pfr/pfrobjs.h b/mod/pub.mod/freetype.mod/src/pfr/pfrobjs.h new file mode 100644 index 0000000..f6aa8b4 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/pfr/pfrobjs.h @@ -0,0 +1,96 @@ +/***************************************************************************/ +/* */ +/* pfrobjs.h */ +/* */ +/* FreeType PFR object methods (specification). */ +/* */ +/* Copyright 2002, 2003, 2004 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __PFROBJS_H__ +#define __PFROBJS_H__ + +#include "pfrtypes.h" + + +FT_BEGIN_HEADER + + typedef struct PFR_FaceRec_* PFR_Face; + + typedef struct PFR_SizeRec_* PFR_Size; + + typedef struct PFR_SlotRec_* PFR_Slot; + + + typedef struct PFR_FaceRec_ + { + FT_FaceRec root; + PFR_HeaderRec header; + PFR_LogFontRec log_font; + PFR_PhyFontRec phy_font; + + } PFR_FaceRec; + + + typedef struct PFR_SizeRec_ + { + FT_SizeRec root; + + } PFR_SizeRec; + + + typedef struct PFR_SlotRec_ + { + FT_GlyphSlotRec root; + PFR_GlyphRec glyph; + + } PFR_SlotRec; + + + FT_LOCAL( FT_Error ) + pfr_face_init( FT_Stream stream, + FT_Face face, /* PFR_Face */ + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ); + + FT_LOCAL( void ) + pfr_face_done( FT_Face face ); /* PFR_Face */ + + + FT_LOCAL( FT_Error ) + pfr_face_get_kerning( FT_Face face, /* PFR_Face */ + FT_UInt glyph1, + FT_UInt glyph2, + FT_Vector* kerning ); + + + FT_LOCAL( FT_Error ) + pfr_slot_init( FT_GlyphSlot slot ); /* PFR_Slot */ + + FT_LOCAL( void ) + pfr_slot_done( FT_GlyphSlot slot ); /* PFR_Slot */ + + + FT_LOCAL( FT_Error ) + pfr_slot_load( FT_GlyphSlot slot, /* PFR_Slot */ + FT_Size size, /* PFR_Size */ + FT_UInt gindex, + FT_Int32 load_flags ); + + +FT_END_HEADER + +#endif /* __PFROBJS_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/pfr/pfrsbit.c b/mod/pub.mod/freetype.mod/src/pfr/pfrsbit.c new file mode 100644 index 0000000..8a38bec --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/pfr/pfrsbit.c @@ -0,0 +1,698 @@ +/***************************************************************************/ +/* */ +/* pfrsbit.c */ +/* */ +/* FreeType PFR bitmap loader (body). */ +/* */ +/* Copyright 2002, 2003, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include "pfrsbit.h" +#include "pfrload.h" +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H + +#include "pfrerror.h" + +#undef FT_COMPONENT +#define FT_COMPONENT trace_pfr + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** PFR BIT WRITER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef struct PFR_BitWriter_ + { + FT_Byte* line; /* current line start */ + FT_Int pitch; /* line size in bytes */ + FT_Int width; /* width in pixels/bits */ + FT_Int rows; /* number of remaining rows to scan */ + FT_Int total; /* total number of bits to draw */ + + } PFR_BitWriterRec, *PFR_BitWriter; + + + static void + pfr_bitwriter_init( PFR_BitWriter writer, + FT_Bitmap* target, + FT_Bool decreasing ) + { + writer->line = target->buffer; + writer->pitch = target->pitch; + writer->width = target->width; + writer->rows = target->rows; + writer->total = writer->width * writer->rows; + + if ( !decreasing ) + { + writer->line += writer->pitch * ( target->rows-1 ); + writer->pitch = -writer->pitch; + } + } + + + static void + pfr_bitwriter_decode_bytes( PFR_BitWriter writer, + FT_Byte* p, + FT_Byte* limit ) + { + FT_Int n, reload; + FT_Int left = writer->width; + FT_Byte* cur = writer->line; + FT_UInt mask = 0x80; + FT_UInt val = 0; + FT_UInt c = 0; + + + n = (FT_Int)( limit - p ) * 8; + if ( n > writer->total ) + n = writer->total; + + reload = n & 7; + + for ( ; n > 0; n-- ) + { + if ( ( n & 7 ) == reload ) + val = *p++; + + if ( val & 0x80 ) + c |= mask; + + val <<= 1; + mask >>= 1; + + if ( --left <= 0 ) + { + cur[0] = (FT_Byte)c; + left = writer->width; + mask = 0x80; + + writer->line += writer->pitch; + cur = writer->line; + c = 0; + } + else if ( mask == 0 ) + { + cur[0] = (FT_Byte)c; + mask = 0x80; + c = 0; + cur ++; + } + } + + if ( mask != 0x80 ) + cur[0] = (FT_Byte)c; + } + + + static void + pfr_bitwriter_decode_rle1( PFR_BitWriter writer, + FT_Byte* p, + FT_Byte* limit ) + { + FT_Int n, phase, count, counts[2], reload; + FT_Int left = writer->width; + FT_Byte* cur = writer->line; + FT_UInt mask = 0x80; + FT_UInt c = 0; + + + n = writer->total; + + phase = 1; + counts[0] = 0; + counts[1] = 0; + count = 0; + reload = 1; + + for ( ; n > 0; n-- ) + { + if ( reload ) + { + do + { + if ( phase ) + { + FT_Int v; + + + if ( p >= limit ) + break; + + v = *p++; + counts[0] = v >> 4; + counts[1] = v & 15; + phase = 0; + count = counts[0]; + } + else + { + phase = 1; + count = counts[1]; + } + + } while ( count == 0 ); + } + + if ( phase ) + c |= mask; + + mask >>= 1; + + if ( --left <= 0 ) + { + cur[0] = (FT_Byte) c; + left = writer->width; + mask = 0x80; + + writer->line += writer->pitch; + cur = writer->line; + c = 0; + } + else if ( mask == 0 ) + { + cur[0] = (FT_Byte)c; + mask = 0x80; + c = 0; + cur ++; + } + + reload = ( --count <= 0 ); + } + + if ( mask != 0x80 ) + cur[0] = (FT_Byte) c; + } + + + static void + pfr_bitwriter_decode_rle2( PFR_BitWriter writer, + FT_Byte* p, + FT_Byte* limit ) + { + FT_Int n, phase, count, reload; + FT_Int left = writer->width; + FT_Byte* cur = writer->line; + FT_UInt mask = 0x80; + FT_UInt c = 0; + + + n = writer->total; + + phase = 1; + count = 0; + reload = 1; + + for ( ; n > 0; n-- ) + { + if ( reload ) + { + do + { + if ( p >= limit ) + break; + + count = *p++; + phase = phase ^ 1; + + } while ( count == 0 ); + } + + if ( phase ) + c |= mask; + + mask >>= 1; + + if ( --left <= 0 ) + { + cur[0] = (FT_Byte) c; + c = 0; + mask = 0x80; + left = writer->width; + + writer->line += writer->pitch; + cur = writer->line; + } + else if ( mask == 0 ) + { + cur[0] = (FT_Byte)c; + c = 0; + mask = 0x80; + cur ++; + } + + reload = ( --count <= 0 ); + } + + if ( mask != 0x80 ) + cur[0] = (FT_Byte) c; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** BITMAP DATA DECODING *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + pfr_lookup_bitmap_data( FT_Byte* base, + FT_Byte* limit, + FT_UInt count, + FT_UInt flags, + FT_UInt char_code, + FT_ULong* found_offset, + FT_ULong* found_size ) + { + FT_UInt left, right, char_len; + FT_Bool two = FT_BOOL( flags & 1 ); + FT_Byte* buff; + + + char_len = 4; + if ( two ) char_len += 1; + if ( flags & 2 ) char_len += 1; + if ( flags & 4 ) char_len += 1; + + left = 0; + right = count; + + while ( left < right ) + { + FT_UInt middle, code; + + + middle = ( left + right ) >> 1; + buff = base + middle * char_len; + + /* check that we are not outside of the table -- */ + /* this is possible with broken fonts... */ + if ( buff + char_len > limit ) + goto Fail; + + if ( two ) + code = PFR_NEXT_USHORT( buff ); + else + code = PFR_NEXT_BYTE( buff ); + + if ( code == char_code ) + goto Found_It; + + if ( code < char_code ) + left = middle; + else + right = middle; + } + + Fail: + /* Not found */ + *found_size = 0; + *found_offset = 0; + return; + + Found_It: + if ( flags & 2 ) + *found_size = PFR_NEXT_USHORT( buff ); + else + *found_size = PFR_NEXT_BYTE( buff ); + + if ( flags & 4 ) + *found_offset = PFR_NEXT_ULONG( buff ); + else + *found_offset = PFR_NEXT_USHORT( buff ); + } + + + /* load bitmap metrics. "*padvance" must be set to the default value */ + /* before calling this function... */ + /* */ + static FT_Error + pfr_load_bitmap_metrics( FT_Byte** pdata, + FT_Byte* limit, + FT_Long scaled_advance, + FT_Long *axpos, + FT_Long *aypos, + FT_UInt *axsize, + FT_UInt *aysize, + FT_Long *aadvance, + FT_UInt *aformat ) + { + FT_Error error = 0; + FT_Byte flags; + FT_Char b; + FT_Byte* p = *pdata; + FT_Long xpos, ypos, advance; + FT_UInt xsize, ysize; + + + PFR_CHECK( 1 ); + flags = PFR_NEXT_BYTE( p ); + + xpos = 0; + ypos = 0; + xsize = 0; + ysize = 0; + advance = 0; + + switch ( flags & 3 ) + { + case 0: + PFR_CHECK( 1 ); + b = PFR_NEXT_INT8( p ); + xpos = b >> 4; + ypos = ( (FT_Char)( b << 4 ) ) >> 4; + break; + + case 1: + PFR_CHECK( 2 ); + xpos = PFR_NEXT_INT8( p ); + ypos = PFR_NEXT_INT8( p ); + break; + + case 2: + PFR_CHECK( 4 ); + xpos = PFR_NEXT_SHORT( p ); + ypos = PFR_NEXT_SHORT( p ); + break; + + case 3: + PFR_CHECK( 6 ); + xpos = PFR_NEXT_LONG( p ); + ypos = PFR_NEXT_LONG( p ); + break; + + default: + ; + } + + flags >>= 2; + switch ( flags & 3 ) + { + case 0: + /* blank image */ + xsize = 0; + ysize = 0; + break; + + case 1: + PFR_CHECK( 1 ); + b = PFR_NEXT_BYTE( p ); + xsize = ( b >> 4 ) & 0xF; + ysize = b & 0xF; + break; + + case 2: + PFR_CHECK( 2 ); + xsize = PFR_NEXT_BYTE( p ); + ysize = PFR_NEXT_BYTE( p ); + break; + + case 3: + PFR_CHECK( 4 ); + xsize = PFR_NEXT_USHORT( p ); + ysize = PFR_NEXT_USHORT( p ); + break; + + default: + ; + } + + flags >>= 2; + switch ( flags & 3 ) + { + case 0: + advance = scaled_advance; + break; + + case 1: + PFR_CHECK( 1 ); + advance = PFR_NEXT_INT8( p ) << 8; + break; + + case 2: + PFR_CHECK( 2 ); + advance = PFR_NEXT_SHORT( p ); + break; + + case 3: + PFR_CHECK( 3 ); + advance = PFR_NEXT_LONG( p ); + break; + + default: + ; + } + + *axpos = xpos; + *aypos = ypos; + *axsize = xsize; + *aysize = ysize; + *aadvance = advance; + *aformat = flags >> 2; + *pdata = p; + + Exit: + return error; + + Too_Short: + error = PFR_Err_Invalid_Table; + FT_ERROR(( "pfr_load_bitmap_metrics: invalid glyph data\n" )); + goto Exit; + } + + + static FT_Error + pfr_load_bitmap_bits( FT_Byte* p, + FT_Byte* limit, + FT_UInt format, + FT_Bool decreasing, + FT_Bitmap* target ) + { + FT_Error error = 0; + PFR_BitWriterRec writer; + + + if ( target->rows > 0 && target->width > 0 ) + { + pfr_bitwriter_init( &writer, target, decreasing ); + + switch ( format ) + { + case 0: /* packed bits */ + pfr_bitwriter_decode_bytes( &writer, p, limit ); + break; + + case 1: /* RLE1 */ + pfr_bitwriter_decode_rle1( &writer, p, limit ); + break; + + case 2: /* RLE2 */ + pfr_bitwriter_decode_rle2( &writer, p, limit ); + break; + + default: + FT_ERROR(( "pfr_read_bitmap_data: invalid image type\n" )); + error = PFR_Err_Invalid_File_Format; + } + } + + return error; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** BITMAP LOADING *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL( FT_Error ) + pfr_slot_load_bitmap( PFR_Slot glyph, + PFR_Size size, + FT_UInt glyph_index ) + { + FT_Error error; + PFR_Face face = (PFR_Face) glyph->root.face; + FT_Stream stream = face->root.stream; + PFR_PhyFont phys = &face->phy_font; + FT_ULong gps_offset; + FT_ULong gps_size; + PFR_Char character; + PFR_Strike strike; + + + character = &phys->chars[glyph_index]; + + /* Look-up a bitmap strike corresponding to the current */ + /* character dimensions */ + { + FT_UInt n; + + + strike = phys->strikes; + for ( n = 0; n < phys->num_strikes; n++ ) + { + if ( strike->x_ppm == (FT_UInt)size->root.metrics.x_ppem && + strike->y_ppm == (FT_UInt)size->root.metrics.y_ppem ) + { + goto Found_Strike; + } + + strike++; + } + + /* couldn't find it */ + return PFR_Err_Invalid_Argument; + } + + Found_Strike: + + /* Now lookup the glyph's position within the file */ + { + FT_UInt char_len; + + + char_len = 4; + if ( strike->flags & 1 ) char_len += 1; + if ( strike->flags & 2 ) char_len += 1; + if ( strike->flags & 4 ) char_len += 1; + + /* Access data directly in the frame to speed lookups */ + if ( FT_STREAM_SEEK( phys->bct_offset + strike->bct_offset ) || + FT_FRAME_ENTER( char_len * strike->num_bitmaps ) ) + goto Exit; + + pfr_lookup_bitmap_data( stream->cursor, + stream->limit, + strike->num_bitmaps, + strike->flags, + character->char_code, + &gps_offset, + &gps_size ); + + FT_FRAME_EXIT(); + + if ( gps_size == 0 ) + { + /* Could not find a bitmap program string for this glyph */ + error = PFR_Err_Invalid_Argument; + goto Exit; + } + } + + /* get the bitmap metrics */ + { + FT_Long xpos, ypos, advance; + FT_UInt xsize, ysize, format; + FT_Byte* p; + + + /* compute linear advance */ + advance = character->advance; + if ( phys->metrics_resolution != phys->outline_resolution ) + advance = FT_MulDiv( advance, + phys->outline_resolution, + phys->metrics_resolution ); + + glyph->root.linearHoriAdvance = advance; + + /* compute default advance, i.e., scaled advance. This can be */ + /* overridden in the bitmap header of certain glyphs. */ + advance = FT_MulDiv( (FT_Fixed)size->root.metrics.x_ppem << 8, + character->advance, + phys->metrics_resolution ); + + if ( FT_STREAM_SEEK( face->header.gps_section_offset + gps_offset ) || + FT_FRAME_ENTER( gps_size ) ) + goto Exit; + + p = stream->cursor; + error = pfr_load_bitmap_metrics( &p, stream->limit, + advance, + &xpos, &ypos, + &xsize, &ysize, + &advance, &format ); + + /* + * XXX: on 16bit system, we return an error for huge bitmap + * which causes a size truncation, because truncated + * size properties makes bitmap glyph broken. + */ + if ( xpos > FT_INT_MAX || ( ypos + ysize ) > FT_INT_MAX ) + { + FT_TRACE1(( "pfr_slot_load_bitmap:" )); + FT_TRACE1(( "huge bitmap glyph %dx%d over FT_GlyphSlot\n", + xpos, ypos )); + error = PFR_Err_Invalid_Pixel_Size; + } + + if ( !error ) + { + glyph->root.format = FT_GLYPH_FORMAT_BITMAP; + + /* Set up glyph bitmap and metrics */ + + /* XXX: needs casts to fit FT_Bitmap.{width|rows|pitch} */ + glyph->root.bitmap.width = (FT_Int)xsize; + glyph->root.bitmap.rows = (FT_Int)ysize; + glyph->root.bitmap.pitch = (FT_Int)( xsize + 7 ) >> 3; + glyph->root.bitmap.pixel_mode = FT_PIXEL_MODE_MONO; + + /* XXX: needs casts to fit FT_Glyph_Metrics.{width|height} */ + glyph->root.metrics.width = (FT_Pos)xsize << 6; + glyph->root.metrics.height = (FT_Pos)ysize << 6; + glyph->root.metrics.horiBearingX = xpos << 6; + glyph->root.metrics.horiBearingY = ypos << 6; + glyph->root.metrics.horiAdvance = FT_PIX_ROUND( ( advance >> 2 ) ); + glyph->root.metrics.vertBearingX = - glyph->root.metrics.width >> 1; + glyph->root.metrics.vertBearingY = 0; + glyph->root.metrics.vertAdvance = size->root.metrics.height; + + /* XXX: needs casts fit FT_GlyphSlotRec.bitmap_{left|top} */ + glyph->root.bitmap_left = (FT_Int)xpos; + glyph->root.bitmap_top = (FT_Int)(ypos + ysize); + + /* Allocate and read bitmap data */ + { + FT_ULong len = glyph->root.bitmap.pitch * ysize; + + + error = ft_glyphslot_alloc_bitmap( &glyph->root, len ); + if ( !error ) + { + error = pfr_load_bitmap_bits( + p, + stream->limit, + format, + FT_BOOL(face->header.color_flags & 2), + &glyph->root.bitmap ); + } + } + } + + FT_FRAME_EXIT(); + } + + Exit: + return error; + } + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/pfr/pfrsbit.h b/mod/pub.mod/freetype.mod/src/pfr/pfrsbit.h new file mode 100644 index 0000000..015e9e6 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/pfr/pfrsbit.h @@ -0,0 +1,36 @@ +/***************************************************************************/ +/* */ +/* pfrsbit.h */ +/* */ +/* FreeType PFR bitmap loader (specification). */ +/* */ +/* Copyright 2002 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __PFRSBIT_H__ +#define __PFRSBIT_H__ + +#include "pfrobjs.h" + +FT_BEGIN_HEADER + + FT_LOCAL( FT_Error ) + pfr_slot_load_bitmap( PFR_Slot glyph, + PFR_Size size, + FT_UInt glyph_index ); + +FT_END_HEADER + +#endif /* __PFR_SBIT_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/pfr/pfrtypes.h b/mod/pub.mod/freetype.mod/src/pfr/pfrtypes.h new file mode 100644 index 0000000..9183108 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/pfr/pfrtypes.h @@ -0,0 +1,362 @@ +/***************************************************************************/ +/* */ +/* pfrtypes.h */ +/* */ +/* FreeType PFR data structures (specification only). */ +/* */ +/* Copyright 2002, 2003, 2005, 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __PFRTYPES_H__ +#define __PFRTYPES_H__ + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H + +FT_BEGIN_HEADER + + /************************************************************************/ + + /* the PFR Header structure */ + typedef struct PFR_HeaderRec_ + { + FT_UInt32 signature; + FT_UInt version; + FT_UInt signature2; + FT_UInt header_size; + + FT_UInt log_dir_size; + FT_UInt log_dir_offset; + + FT_UInt log_font_max_size; + FT_UInt32 log_font_section_size; + FT_UInt32 log_font_section_offset; + + FT_UInt32 phy_font_max_size; + FT_UInt32 phy_font_section_size; + FT_UInt32 phy_font_section_offset; + + FT_UInt gps_max_size; + FT_UInt32 gps_section_size; + FT_UInt32 gps_section_offset; + + FT_UInt max_blue_values; + FT_UInt max_x_orus; + FT_UInt max_y_orus; + + FT_UInt phy_font_max_size_high; + FT_UInt color_flags; + + FT_UInt32 bct_max_size; + FT_UInt32 bct_set_max_size; + FT_UInt32 phy_bct_set_max_size; + + FT_UInt num_phy_fonts; + FT_UInt max_vert_stem_snap; + FT_UInt max_horz_stem_snap; + FT_UInt max_chars; + + } PFR_HeaderRec, *PFR_Header; + + + /* used in `color_flags' field of the PFR_Header */ + typedef enum PFR_HeaderFlags_ + { + PFR_FLAG_BLACK_PIXEL = 1, + PFR_FLAG_INVERT_BITMAP = 2 + + } PFR_HeaderFlags; + + + /************************************************************************/ + + typedef struct PFR_LogFontRec_ + { + FT_UInt32 size; + FT_UInt32 offset; + + FT_Int32 matrix[4]; + FT_UInt stroke_flags; + FT_Int stroke_thickness; + FT_Int bold_thickness; + FT_Int32 miter_limit; + + FT_UInt32 phys_size; + FT_UInt32 phys_offset; + + } PFR_LogFontRec, *PFR_LogFont; + + + typedef enum PFR_LogFlags_ + { + PFR_LOG_EXTRA_ITEMS = 0x40, + PFR_LOG_2BYTE_BOLD = 0x20, + PFR_LOG_BOLD = 0x10, + PFR_LOG_2BYTE_STROKE = 8, + PFR_LOG_STROKE = 4, + PFR_LINE_JOIN_MASK = 3 + + } PFR_LogFlags; + + + typedef enum PFR_LineJoinFlags_ + { + PFR_LINE_JOIN_MITER = 0, + PFR_LINE_JOIN_ROUND = 1, + PFR_LINE_JOIN_BEVEL = 2 + + } PFR_LineJoinFlags; + + + /************************************************************************/ + + typedef enum PFR_BitmapFlags_ + { + PFR_BITMAP_3BYTE_OFFSET = 4, + PFR_BITMAP_2BYTE_SIZE = 2, + PFR_BITMAP_2BYTE_CHARCODE = 1 + + } PFR_BitmapFlags; + + + typedef struct PFR_BitmapCharRec_ + { + FT_UInt char_code; + FT_UInt gps_size; + FT_UInt32 gps_offset; + + } PFR_BitmapCharRec, *PFR_BitmapChar; + + + typedef enum PFR_StrikeFlags_ + { + PFR_STRIKE_2BYTE_COUNT = 0x10, + PFR_STRIKE_3BYTE_OFFSET = 0x08, + PFR_STRIKE_3BYTE_SIZE = 0x04, + PFR_STRIKE_2BYTE_YPPM = 0x02, + PFR_STRIKE_2BYTE_XPPM = 0x01 + + } PFR_StrikeFlags; + + + typedef struct PFR_StrikeRec_ + { + FT_UInt x_ppm; + FT_UInt y_ppm; + FT_UInt flags; + + FT_UInt32 gps_size; + FT_UInt32 gps_offset; + + FT_UInt32 bct_size; + FT_UInt32 bct_offset; + + /* optional */ + FT_UInt num_bitmaps; + PFR_BitmapChar bitmaps; + + } PFR_StrikeRec, *PFR_Strike; + + + /************************************************************************/ + + typedef struct PFR_CharRec_ + { + FT_UInt char_code; + FT_Int advance; + FT_UInt gps_size; + FT_UInt32 gps_offset; + + } PFR_CharRec, *PFR_Char; + + + /************************************************************************/ + + typedef struct PFR_DimensionRec_ + { + FT_UInt standard; + FT_UInt num_stem_snaps; + FT_Int* stem_snaps; + + } PFR_DimensionRec, *PFR_Dimension; + + /************************************************************************/ + + typedef struct PFR_KernItemRec_* PFR_KernItem; + + typedef struct PFR_KernItemRec_ + { + PFR_KernItem next; + FT_Byte pair_count; + FT_Byte flags; + FT_Short base_adj; + FT_UInt pair_size; + FT_Offset offset; + FT_UInt32 pair1; + FT_UInt32 pair2; + + } PFR_KernItemRec; + + +#define PFR_KERN_INDEX( g1, g2 ) \ + ( ( (FT_UInt32)(g1) << 16 ) | (FT_UInt16)(g2) ) + +#define PFR_KERN_PAIR_INDEX( pair ) \ + PFR_KERN_INDEX( (pair)->glyph1, (pair)->glyph2 ) + +#define PFR_NEXT_KPAIR( p ) ( p += 2, \ + ( (FT_UInt32)p[-2] << 16 ) | p[-1] ) + + + /************************************************************************/ + + typedef struct PFR_PhyFontRec_ + { + FT_Memory memory; + FT_UInt32 offset; + + FT_UInt font_ref_number; + FT_UInt outline_resolution; + FT_UInt metrics_resolution; + FT_BBox bbox; + FT_UInt flags; + FT_UInt standard_advance; + + FT_Int ascent; /* optional, bbox.yMax if not present */ + FT_Int descent; /* optional, bbox.yMin if not present */ + FT_Int leading; /* optional, 0 if not present */ + + PFR_DimensionRec horizontal; + PFR_DimensionRec vertical; + + FT_String* font_id; + FT_String* family_name; + FT_String* style_name; + + FT_UInt num_strikes; + FT_UInt max_strikes; + PFR_StrikeRec* strikes; + + FT_UInt num_blue_values; + FT_Int *blue_values; + FT_UInt blue_fuzz; + FT_UInt blue_scale; + + FT_UInt num_chars; + FT_Offset chars_offset; + PFR_Char chars; + + FT_UInt num_kern_pairs; + PFR_KernItem kern_items; + PFR_KernItem* kern_items_tail; + + /* not part of the spec, but used during load */ + FT_Long bct_offset; + FT_Byte* cursor; + + } PFR_PhyFontRec, *PFR_PhyFont; + + + typedef enum PFR_PhyFlags_ + { + PFR_PHY_EXTRA_ITEMS = 0x80, + PFR_PHY_3BYTE_GPS_OFFSET = 0x20, + PFR_PHY_2BYTE_GPS_SIZE = 0x10, + PFR_PHY_ASCII_CODE = 0x08, + PFR_PHY_PROPORTIONAL = 0x04, + PFR_PHY_2BYTE_CHARCODE = 0x02, + PFR_PHY_VERTICAL = 0x01 + + } PFR_PhyFlags; + + + typedef enum PFR_KernFlags_ + { + PFR_KERN_2BYTE_CHAR = 0x01, + PFR_KERN_2BYTE_ADJ = 0x02 + + } PFR_KernFlags; + + + /************************************************************************/ + + typedef enum PFR_GlyphFlags_ + { + PFR_GLYPH_IS_COMPOUND = 0x80, + PFR_GLYPH_EXTRA_ITEMS = 0x08, + PFR_GLYPH_1BYTE_XYCOUNT = 0x04, + PFR_GLYPH_XCOUNT = 0x02, + PFR_GLYPH_YCOUNT = 0x01 + + } PFR_GlyphFlags; + + + /* controlled coordinate */ + typedef struct PFR_CoordRec_ + { + FT_UInt org; + FT_UInt cur; + + } PFR_CoordRec, *PFR_Coord; + + + typedef struct PFR_SubGlyphRec_ + { + FT_Fixed x_scale; + FT_Fixed y_scale; + FT_Int x_delta; + FT_Int y_delta; + FT_UInt32 gps_offset; + FT_UInt gps_size; + + } PFR_SubGlyphRec, *PFR_SubGlyph; + + + typedef enum PFR_SubgGlyphFlags_ + { + PFR_SUBGLYPH_3BYTE_OFFSET = 0x80, + PFR_SUBGLYPH_2BYTE_SIZE = 0x40, + PFR_SUBGLYPH_YSCALE = 0x20, + PFR_SUBGLYPH_XSCALE = 0x10 + + } PFR_SubGlyphFlags; + + + typedef struct PFR_GlyphRec_ + { + FT_Byte format; + +#if 0 + FT_UInt num_x_control; + FT_UInt num_y_control; +#endif + FT_UInt max_xy_control; + FT_Pos* x_control; + FT_Pos* y_control; + + + FT_UInt num_subs; + FT_UInt max_subs; + PFR_SubGlyphRec* subs; + + FT_GlyphLoader loader; + FT_Bool path_begun; + + } PFR_GlyphRec, *PFR_Glyph; + + +FT_END_HEADER + +#endif /* __PFRTYPES_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/psaux/afmparse.c b/mod/pub.mod/freetype.mod/src/psaux/afmparse.c new file mode 100644 index 0000000..91a17e2 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/psaux/afmparse.c @@ -0,0 +1,964 @@ +/***************************************************************************/ +/* */ +/* afmparse.c */ +/* */ +/* AFM parser (body). */ +/* */ +/* Copyright 2006, 2007, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_INTERNAL_POSTSCRIPT_AUX_H + +#include "afmparse.h" +#include "psconv.h" + +#include "psauxerr.h" + + +/***************************************************************************/ +/* */ +/* AFM_Stream */ +/* */ +/* The use of AFM_Stream is largely inspired by parseAFM.[ch] from t1lib. */ +/* */ +/* */ + + enum + { + AFM_STREAM_STATUS_NORMAL, + AFM_STREAM_STATUS_EOC, + AFM_STREAM_STATUS_EOL, + AFM_STREAM_STATUS_EOF + }; + + + typedef struct AFM_StreamRec_ + { + FT_Byte* cursor; + FT_Byte* base; + FT_Byte* limit; + + FT_Int status; + + } AFM_StreamRec; + + +#ifndef EOF +#define EOF -1 +#endif + + + /* this works because empty lines are ignored */ +#define AFM_IS_NEWLINE( ch ) ( (ch) == '\r' || (ch) == '\n' ) + +#define AFM_IS_EOF( ch ) ( (ch) == EOF || (ch) == '\x1a' ) +#define AFM_IS_SPACE( ch ) ( (ch) == ' ' || (ch) == '\t' ) + + /* column separator; there is no `column' in the spec actually */ +#define AFM_IS_SEP( ch ) ( (ch) == ';' ) + +#define AFM_GETC() \ + ( ( (stream)->cursor < (stream)->limit ) ? *(stream)->cursor++ \ + : EOF ) + +#define AFM_STREAM_KEY_BEGIN( stream ) \ + (char*)( (stream)->cursor - 1 ) + +#define AFM_STREAM_KEY_LEN( stream, key ) \ + ( (char*)(stream)->cursor - key - 1 ) + +#define AFM_STATUS_EOC( stream ) \ + ( (stream)->status >= AFM_STREAM_STATUS_EOC ) + +#define AFM_STATUS_EOL( stream ) \ + ( (stream)->status >= AFM_STREAM_STATUS_EOL ) + +#define AFM_STATUS_EOF( stream ) \ + ( (stream)->status >= AFM_STREAM_STATUS_EOF ) + + + static int + afm_stream_skip_spaces( AFM_Stream stream ) + { + int ch = 0; /* make stupid compiler happy */ + + + if ( AFM_STATUS_EOC( stream ) ) + return ';'; + + while ( 1 ) + { + ch = AFM_GETC(); + if ( !AFM_IS_SPACE( ch ) ) + break; + } + + if ( AFM_IS_NEWLINE( ch ) ) + stream->status = AFM_STREAM_STATUS_EOL; + else if ( AFM_IS_SEP( ch ) ) + stream->status = AFM_STREAM_STATUS_EOC; + else if ( AFM_IS_EOF( ch ) ) + stream->status = AFM_STREAM_STATUS_EOF; + + return ch; + } + + + /* read a key or value in current column */ + static char* + afm_stream_read_one( AFM_Stream stream ) + { + char* str; + int ch; + + + afm_stream_skip_spaces( stream ); + if ( AFM_STATUS_EOC( stream ) ) + return NULL; + + str = AFM_STREAM_KEY_BEGIN( stream ); + + while ( 1 ) + { + ch = AFM_GETC(); + if ( AFM_IS_SPACE( ch ) ) + break; + else if ( AFM_IS_NEWLINE( ch ) ) + { + stream->status = AFM_STREAM_STATUS_EOL; + break; + } + else if ( AFM_IS_SEP( ch ) ) + { + stream->status = AFM_STREAM_STATUS_EOC; + break; + } + else if ( AFM_IS_EOF( ch ) ) + { + stream->status = AFM_STREAM_STATUS_EOF; + break; + } + } + + return str; + } + + + /* read a string (i.e., read to EOL) */ + static char* + afm_stream_read_string( AFM_Stream stream ) + { + char* str; + int ch; + + + afm_stream_skip_spaces( stream ); + if ( AFM_STATUS_EOL( stream ) ) + return NULL; + + str = AFM_STREAM_KEY_BEGIN( stream ); + + /* scan to eol */ + while ( 1 ) + { + ch = AFM_GETC(); + if ( AFM_IS_NEWLINE( ch ) ) + { + stream->status = AFM_STREAM_STATUS_EOL; + break; + } + else if ( AFM_IS_EOF( ch ) ) + { + stream->status = AFM_STREAM_STATUS_EOF; + break; + } + } + + return str; + } + + + /*************************************************************************/ + /* */ + /* AFM_Parser */ + /* */ + /* */ + + /* all keys defined in Ch. 7-10 of 5004.AFM_Spec.pdf */ + typedef enum AFM_Token_ + { + AFM_TOKEN_ASCENDER, + AFM_TOKEN_AXISLABEL, + AFM_TOKEN_AXISTYPE, + AFM_TOKEN_B, + AFM_TOKEN_BLENDAXISTYPES, + AFM_TOKEN_BLENDDESIGNMAP, + AFM_TOKEN_BLENDDESIGNPOSITIONS, + AFM_TOKEN_C, + AFM_TOKEN_CC, + AFM_TOKEN_CH, + AFM_TOKEN_CAPHEIGHT, + AFM_TOKEN_CHARWIDTH, + AFM_TOKEN_CHARACTERSET, + AFM_TOKEN_CHARACTERS, + AFM_TOKEN_DESCENDER, + AFM_TOKEN_ENCODINGSCHEME, + AFM_TOKEN_ENDAXIS, + AFM_TOKEN_ENDCHARMETRICS, + AFM_TOKEN_ENDCOMPOSITES, + AFM_TOKEN_ENDDIRECTION, + AFM_TOKEN_ENDFONTMETRICS, + AFM_TOKEN_ENDKERNDATA, + AFM_TOKEN_ENDKERNPAIRS, + AFM_TOKEN_ENDTRACKKERN, + AFM_TOKEN_ESCCHAR, + AFM_TOKEN_FAMILYNAME, + AFM_TOKEN_FONTBBOX, + AFM_TOKEN_FONTNAME, + AFM_TOKEN_FULLNAME, + AFM_TOKEN_ISBASEFONT, + AFM_TOKEN_ISCIDFONT, + AFM_TOKEN_ISFIXEDPITCH, + AFM_TOKEN_ISFIXEDV, + AFM_TOKEN_ITALICANGLE, + AFM_TOKEN_KP, + AFM_TOKEN_KPH, + AFM_TOKEN_KPX, + AFM_TOKEN_KPY, + AFM_TOKEN_L, + AFM_TOKEN_MAPPINGSCHEME, + AFM_TOKEN_METRICSSETS, + AFM_TOKEN_N, + AFM_TOKEN_NOTICE, + AFM_TOKEN_PCC, + AFM_TOKEN_STARTAXIS, + AFM_TOKEN_STARTCHARMETRICS, + AFM_TOKEN_STARTCOMPOSITES, + AFM_TOKEN_STARTDIRECTION, + AFM_TOKEN_STARTFONTMETRICS, + AFM_TOKEN_STARTKERNDATA, + AFM_TOKEN_STARTKERNPAIRS, + AFM_TOKEN_STARTKERNPAIRS0, + AFM_TOKEN_STARTKERNPAIRS1, + AFM_TOKEN_STARTTRACKKERN, + AFM_TOKEN_STDHW, + AFM_TOKEN_STDVW, + AFM_TOKEN_TRACKKERN, + AFM_TOKEN_UNDERLINEPOSITION, + AFM_TOKEN_UNDERLINETHICKNESS, + AFM_TOKEN_VV, + AFM_TOKEN_VVECTOR, + AFM_TOKEN_VERSION, + AFM_TOKEN_W, + AFM_TOKEN_W0, + AFM_TOKEN_W0X, + AFM_TOKEN_W0Y, + AFM_TOKEN_W1, + AFM_TOKEN_W1X, + AFM_TOKEN_W1Y, + AFM_TOKEN_WX, + AFM_TOKEN_WY, + AFM_TOKEN_WEIGHT, + AFM_TOKEN_WEIGHTVECTOR, + AFM_TOKEN_XHEIGHT, + N_AFM_TOKENS, + AFM_TOKEN_UNKNOWN + + } AFM_Token; + + + static const char* const afm_key_table[N_AFM_TOKENS] = + { + "Ascender", + "AxisLabel", + "AxisType", + "B", + "BlendAxisTypes", + "BlendDesignMap", + "BlendDesignPositions", + "C", + "CC", + "CH", + "CapHeight", + "CharWidth", + "CharacterSet", + "Characters", + "Descender", + "EncodingScheme", + "EndAxis", + "EndCharMetrics", + "EndComposites", + "EndDirection", + "EndFontMetrics", + "EndKernData", + "EndKernPairs", + "EndTrackKern", + "EscChar", + "FamilyName", + "FontBBox", + "FontName", + "FullName", + "IsBaseFont", + "IsCIDFont", + "IsFixedPitch", + "IsFixedV", + "ItalicAngle", + "KP", + "KPH", + "KPX", + "KPY", + "L", + "MappingScheme", + "MetricsSets", + "N", + "Notice", + "PCC", + "StartAxis", + "StartCharMetrics", + "StartComposites", + "StartDirection", + "StartFontMetrics", + "StartKernData", + "StartKernPairs", + "StartKernPairs0", + "StartKernPairs1", + "StartTrackKern", + "StdHW", + "StdVW", + "TrackKern", + "UnderlinePosition", + "UnderlineThickness", + "VV", + "VVector", + "Version", + "W", + "W0", + "W0X", + "W0Y", + "W1", + "W1X", + "W1Y", + "WX", + "WY", + "Weight", + "WeightVector", + "XHeight" + }; + + + /* + * `afm_parser_read_vals' and `afm_parser_next_key' provide + * high-level operations to an AFM_Stream. The rest of the + * parser functions should use them without accessing the + * AFM_Stream directly. + */ + + FT_LOCAL_DEF( FT_Int ) + afm_parser_read_vals( AFM_Parser parser, + AFM_Value vals, + FT_UInt n ) + { + AFM_Stream stream = parser->stream; + char* str; + FT_UInt i; + + + if ( n > AFM_MAX_ARGUMENTS ) + return 0; + + for ( i = 0; i < n; i++ ) + { + FT_Offset len; + AFM_Value val = vals + i; + + + if ( val->type == AFM_VALUE_TYPE_STRING ) + str = afm_stream_read_string( stream ); + else + str = afm_stream_read_one( stream ); + + if ( !str ) + break; + + len = AFM_STREAM_KEY_LEN( stream, str ); + + switch ( val->type ) + { + case AFM_VALUE_TYPE_STRING: + case AFM_VALUE_TYPE_NAME: + { + FT_Memory memory = parser->memory; + FT_Error error; + + + if ( !FT_QALLOC( val->u.s, len + 1 ) ) + { + ft_memcpy( val->u.s, str, len ); + val->u.s[len] = '\0'; + } + } + break; + + case AFM_VALUE_TYPE_FIXED: + val->u.f = PS_Conv_ToFixed( (FT_Byte**)(void*)&str, + (FT_Byte*)str + len, 0 ); + break; + + case AFM_VALUE_TYPE_INTEGER: + val->u.i = PS_Conv_ToInt( (FT_Byte**)(void*)&str, + (FT_Byte*)str + len ); + break; + + case AFM_VALUE_TYPE_BOOL: + val->u.b = FT_BOOL( len == 4 && + !ft_strncmp( str, "true", 4 ) ); + break; + + case AFM_VALUE_TYPE_INDEX: + if ( parser->get_index ) + val->u.i = parser->get_index( str, len, parser->user_data ); + else + val->u.i = 0; + break; + } + } + + return i; + } + + + FT_LOCAL_DEF( char* ) + afm_parser_next_key( AFM_Parser parser, + FT_Bool line, + FT_Offset* len ) + { + AFM_Stream stream = parser->stream; + char* key = 0; /* make stupid compiler happy */ + + + if ( line ) + { + while ( 1 ) + { + /* skip current line */ + if ( !AFM_STATUS_EOL( stream ) ) + afm_stream_read_string( stream ); + + stream->status = AFM_STREAM_STATUS_NORMAL; + key = afm_stream_read_one( stream ); + + /* skip empty line */ + if ( !key && + !AFM_STATUS_EOF( stream ) && + AFM_STATUS_EOL( stream ) ) + continue; + + break; + } + } + else + { + while ( 1 ) + { + /* skip current column */ + while ( !AFM_STATUS_EOC( stream ) ) + afm_stream_read_one( stream ); + + stream->status = AFM_STREAM_STATUS_NORMAL; + key = afm_stream_read_one( stream ); + + /* skip empty column */ + if ( !key && + !AFM_STATUS_EOF( stream ) && + AFM_STATUS_EOC( stream ) ) + continue; + + break; + } + } + + if ( len ) + *len = ( key ) ? (FT_Offset)AFM_STREAM_KEY_LEN( stream, key ) + : 0; + + return key; + } + + + static AFM_Token + afm_tokenize( const char* key, + FT_Offset len ) + { + int n; + + + for ( n = 0; n < N_AFM_TOKENS; n++ ) + { + if ( *( afm_key_table[n] ) == *key ) + { + for ( ; n < N_AFM_TOKENS; n++ ) + { + if ( *( afm_key_table[n] ) != *key ) + return AFM_TOKEN_UNKNOWN; + + if ( ft_strncmp( afm_key_table[n], key, len ) == 0 ) + return (AFM_Token) n; + } + } + } + + return AFM_TOKEN_UNKNOWN; + } + + + FT_LOCAL_DEF( FT_Error ) + afm_parser_init( AFM_Parser parser, + FT_Memory memory, + FT_Byte* base, + FT_Byte* limit ) + { + AFM_Stream stream; + FT_Error error; + + + if ( FT_NEW( stream ) ) + return error; + + stream->cursor = stream->base = base; + stream->limit = limit; + + /* don't skip the first line during the first call */ + stream->status = AFM_STREAM_STATUS_EOL; + + parser->memory = memory; + parser->stream = stream; + parser->FontInfo = NULL; + parser->get_index = NULL; + + return PSaux_Err_Ok; + } + + + FT_LOCAL( void ) + afm_parser_done( AFM_Parser parser ) + { + FT_Memory memory = parser->memory; + + + FT_FREE( parser->stream ); + } + + + FT_LOCAL_DEF( FT_Error ) + afm_parser_read_int( AFM_Parser parser, + FT_Int* aint ) + { + AFM_ValueRec val; + + + val.type = AFM_VALUE_TYPE_INTEGER; + + if ( afm_parser_read_vals( parser, &val, 1 ) == 1 ) + { + *aint = val.u.i; + + return PSaux_Err_Ok; + } + else + return PSaux_Err_Syntax_Error; + } + + + static FT_Error + afm_parse_track_kern( AFM_Parser parser ) + { + AFM_FontInfo fi = parser->FontInfo; + AFM_TrackKern tk; + char* key; + FT_Offset len; + int n = -1; + + + if ( afm_parser_read_int( parser, &fi->NumTrackKern ) ) + goto Fail; + + if ( fi->NumTrackKern ) + { + FT_Memory memory = parser->memory; + FT_Error error; + + + if ( FT_QNEW_ARRAY( fi->TrackKerns, fi->NumTrackKern ) ) + return error; + } + + while ( ( key = afm_parser_next_key( parser, 1, &len ) ) != 0 ) + { + AFM_ValueRec shared_vals[5]; + + + switch ( afm_tokenize( key, len ) ) + { + case AFM_TOKEN_TRACKKERN: + n++; + + if ( n >= fi->NumTrackKern ) + goto Fail; + + tk = fi->TrackKerns + n; + + shared_vals[0].type = AFM_VALUE_TYPE_INTEGER; + shared_vals[1].type = AFM_VALUE_TYPE_FIXED; + shared_vals[2].type = AFM_VALUE_TYPE_FIXED; + shared_vals[3].type = AFM_VALUE_TYPE_FIXED; + shared_vals[4].type = AFM_VALUE_TYPE_FIXED; + if ( afm_parser_read_vals( parser, shared_vals, 5 ) != 5 ) + goto Fail; + + tk->degree = shared_vals[0].u.i; + tk->min_ptsize = shared_vals[1].u.f; + tk->min_kern = shared_vals[2].u.f; + tk->max_ptsize = shared_vals[3].u.f; + tk->max_kern = shared_vals[4].u.f; + + /* is this correct? */ + if ( tk->degree < 0 && tk->min_kern > 0 ) + tk->min_kern = -tk->min_kern; + break; + + case AFM_TOKEN_ENDTRACKKERN: + case AFM_TOKEN_ENDKERNDATA: + case AFM_TOKEN_ENDFONTMETRICS: + fi->NumTrackKern = n + 1; + return PSaux_Err_Ok; + + case AFM_TOKEN_UNKNOWN: + break; + + default: + goto Fail; + } + } + + Fail: + return PSaux_Err_Syntax_Error; + } + + +#undef KERN_INDEX +#define KERN_INDEX( g1, g2 ) ( ( (FT_ULong)g1 << 16 ) | g2 ) + + + /* compare two kerning pairs */ + FT_CALLBACK_DEF( int ) + afm_compare_kern_pairs( const void* a, + const void* b ) + { + AFM_KernPair kp1 = (AFM_KernPair)a; + AFM_KernPair kp2 = (AFM_KernPair)b; + + FT_ULong index1 = KERN_INDEX( kp1->index1, kp1->index2 ); + FT_ULong index2 = KERN_INDEX( kp2->index1, kp2->index2 ); + + + if ( index1 > index2 ) + return 1; + else if ( index1 < index2 ) + return -1; + else + return 0; + } + + + static FT_Error + afm_parse_kern_pairs( AFM_Parser parser ) + { + AFM_FontInfo fi = parser->FontInfo; + AFM_KernPair kp; + char* key; + FT_Offset len; + int n = -1; + + + if ( afm_parser_read_int( parser, &fi->NumKernPair ) ) + goto Fail; + + if ( fi->NumKernPair ) + { + FT_Memory memory = parser->memory; + FT_Error error; + + + if ( FT_QNEW_ARRAY( fi->KernPairs, fi->NumKernPair ) ) + return error; + } + + while ( ( key = afm_parser_next_key( parser, 1, &len ) ) != 0 ) + { + AFM_Token token = afm_tokenize( key, len ); + + + switch ( token ) + { + case AFM_TOKEN_KP: + case AFM_TOKEN_KPX: + case AFM_TOKEN_KPY: + { + FT_Int r; + AFM_ValueRec shared_vals[4]; + + + n++; + + if ( n >= fi->NumKernPair ) + goto Fail; + + kp = fi->KernPairs + n; + + shared_vals[0].type = AFM_VALUE_TYPE_INDEX; + shared_vals[1].type = AFM_VALUE_TYPE_INDEX; + shared_vals[2].type = AFM_VALUE_TYPE_INTEGER; + shared_vals[3].type = AFM_VALUE_TYPE_INTEGER; + r = afm_parser_read_vals( parser, shared_vals, 4 ); + if ( r < 3 ) + goto Fail; + + kp->index1 = shared_vals[0].u.i; + kp->index2 = shared_vals[1].u.i; + if ( token == AFM_TOKEN_KPY ) + { + kp->x = 0; + kp->y = shared_vals[2].u.i; + } + else + { + kp->x = shared_vals[2].u.i; + kp->y = ( token == AFM_TOKEN_KP && r == 4 ) + ? shared_vals[3].u.i : 0; + } + } + break; + + case AFM_TOKEN_ENDKERNPAIRS: + case AFM_TOKEN_ENDKERNDATA: + case AFM_TOKEN_ENDFONTMETRICS: + fi->NumKernPair = n + 1; + ft_qsort( fi->KernPairs, fi->NumKernPair, + sizeof( AFM_KernPairRec ), + afm_compare_kern_pairs ); + return PSaux_Err_Ok; + + case AFM_TOKEN_UNKNOWN: + break; + + default: + goto Fail; + } + } + + Fail: + return PSaux_Err_Syntax_Error; + } + + + static FT_Error + afm_parse_kern_data( AFM_Parser parser ) + { + FT_Error error; + char* key; + FT_Offset len; + + + while ( ( key = afm_parser_next_key( parser, 1, &len ) ) != 0 ) + { + switch ( afm_tokenize( key, len ) ) + { + case AFM_TOKEN_STARTTRACKKERN: + error = afm_parse_track_kern( parser ); + if ( error ) + return error; + break; + + case AFM_TOKEN_STARTKERNPAIRS: + case AFM_TOKEN_STARTKERNPAIRS0: + error = afm_parse_kern_pairs( parser ); + if ( error ) + return error; + break; + + case AFM_TOKEN_ENDKERNDATA: + case AFM_TOKEN_ENDFONTMETRICS: + return PSaux_Err_Ok; + + case AFM_TOKEN_UNKNOWN: + break; + + default: + goto Fail; + } + } + + Fail: + return PSaux_Err_Syntax_Error; + } + + + static FT_Error + afm_parser_skip_section( AFM_Parser parser, + FT_UInt n, + AFM_Token end_section ) + { + char* key; + FT_Offset len; + + + while ( n-- > 0 ) + { + key = afm_parser_next_key( parser, 1, NULL ); + if ( !key ) + goto Fail; + } + + while ( ( key = afm_parser_next_key( parser, 1, &len ) ) != 0 ) + { + AFM_Token token = afm_tokenize( key, len ); + + + if ( token == end_section || token == AFM_TOKEN_ENDFONTMETRICS ) + return PSaux_Err_Ok; + } + + Fail: + return PSaux_Err_Syntax_Error; + } + + + FT_LOCAL_DEF( FT_Error ) + afm_parser_parse( AFM_Parser parser ) + { + FT_Memory memory = parser->memory; + AFM_FontInfo fi = parser->FontInfo; + FT_Error error = PSaux_Err_Syntax_Error; + char* key; + FT_Offset len; + FT_Int metrics_sets = 0; + + + if ( !fi ) + return PSaux_Err_Invalid_Argument; + + key = afm_parser_next_key( parser, 1, &len ); + if ( !key || len != 16 || + ft_strncmp( key, "StartFontMetrics", 16 ) != 0 ) + return PSaux_Err_Unknown_File_Format; + + while ( ( key = afm_parser_next_key( parser, 1, &len ) ) != 0 ) + { + AFM_ValueRec shared_vals[4]; + + + switch ( afm_tokenize( key, len ) ) + { + case AFM_TOKEN_METRICSSETS: + if ( afm_parser_read_int( parser, &metrics_sets ) ) + goto Fail; + + if ( metrics_sets != 0 && metrics_sets != 2 ) + { + error = PSaux_Err_Unimplemented_Feature; + + goto Fail; + } + break; + + case AFM_TOKEN_ISCIDFONT: + shared_vals[0].type = AFM_VALUE_TYPE_BOOL; + if ( afm_parser_read_vals( parser, shared_vals, 1 ) != 1 ) + goto Fail; + + fi->IsCIDFont = shared_vals[0].u.b; + break; + + case AFM_TOKEN_FONTBBOX: + shared_vals[0].type = AFM_VALUE_TYPE_FIXED; + shared_vals[1].type = AFM_VALUE_TYPE_FIXED; + shared_vals[2].type = AFM_VALUE_TYPE_FIXED; + shared_vals[3].type = AFM_VALUE_TYPE_FIXED; + if ( afm_parser_read_vals( parser, shared_vals, 4 ) != 4 ) + goto Fail; + + fi->FontBBox.xMin = shared_vals[0].u.f; + fi->FontBBox.yMin = shared_vals[1].u.f; + fi->FontBBox.xMax = shared_vals[2].u.f; + fi->FontBBox.yMax = shared_vals[3].u.f; + break; + + case AFM_TOKEN_ASCENDER: + shared_vals[0].type = AFM_VALUE_TYPE_FIXED; + if ( afm_parser_read_vals( parser, shared_vals, 1 ) != 1 ) + goto Fail; + + fi->Ascender = shared_vals[0].u.f; + break; + + case AFM_TOKEN_DESCENDER: + shared_vals[0].type = AFM_VALUE_TYPE_FIXED; + if ( afm_parser_read_vals( parser, shared_vals, 1 ) != 1 ) + goto Fail; + + fi->Descender = shared_vals[0].u.f; + break; + + case AFM_TOKEN_STARTCHARMETRICS: + { + FT_Int n = 0; + + + if ( afm_parser_read_int( parser, &n ) ) + goto Fail; + + error = afm_parser_skip_section( parser, n, + AFM_TOKEN_ENDCHARMETRICS ); + if ( error ) + return error; + } + break; + + case AFM_TOKEN_STARTKERNDATA: + error = afm_parse_kern_data( parser ); + if ( error ) + goto Fail; + /* fall through since we only support kern data */ + + case AFM_TOKEN_ENDFONTMETRICS: + return PSaux_Err_Ok; + + default: + break; + } + } + + Fail: + FT_FREE( fi->TrackKerns ); + fi->NumTrackKern = 0; + + FT_FREE( fi->KernPairs ); + fi->NumKernPair = 0; + + fi->IsCIDFont = 0; + + return error; + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/psaux/afmparse.h b/mod/pub.mod/freetype.mod/src/psaux/afmparse.h new file mode 100644 index 0000000..de2a530 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/psaux/afmparse.h @@ -0,0 +1,87 @@ +/***************************************************************************/ +/* */ +/* afmparse.h */ +/* */ +/* AFM parser (specification). */ +/* */ +/* Copyright 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __AFMPARSE_H__ +#define __AFMPARSE_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_POSTSCRIPT_AUX_H + + +FT_BEGIN_HEADER + + + FT_LOCAL( FT_Error ) + afm_parser_init( AFM_Parser parser, + FT_Memory memory, + FT_Byte* base, + FT_Byte* limit ); + + + FT_LOCAL( void ) + afm_parser_done( AFM_Parser parser ); + + + FT_LOCAL( FT_Error ) + afm_parser_parse( AFM_Parser parser ); + + + enum AFM_ValueType_ + { + AFM_VALUE_TYPE_STRING, + AFM_VALUE_TYPE_NAME, + AFM_VALUE_TYPE_FIXED, /* real number */ + AFM_VALUE_TYPE_INTEGER, + AFM_VALUE_TYPE_BOOL, + AFM_VALUE_TYPE_INDEX /* glyph index */ + }; + + + typedef struct AFM_ValueRec_ + { + enum AFM_ValueType_ type; + union { + char* s; + FT_Fixed f; + FT_Int i; + FT_Bool b; + + } u; + + } AFM_ValueRec, *AFM_Value; + +#define AFM_MAX_ARGUMENTS 5 + + FT_LOCAL( FT_Int ) + afm_parser_read_vals( AFM_Parser parser, + AFM_Value vals, + FT_UInt n ); + + /* read the next key from the next line or column */ + FT_LOCAL( char* ) + afm_parser_next_key( AFM_Parser parser, + FT_Bool line, + FT_Offset* len ); + +FT_END_HEADER + +#endif /* __AFMPARSE_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/psaux/psaux.c b/mod/pub.mod/freetype.mod/src/psaux/psaux.c new file mode 100644 index 0000000..a4b9c5c --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/psaux/psaux.c @@ -0,0 +1,34 @@ +/***************************************************************************/ +/* */ +/* psaux.c */ +/* */ +/* FreeType auxiliary PostScript driver component (body only). */ +/* */ +/* Copyright 1996-2001, 2002, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#define FT_MAKE_OPTION_SINGLE_OBJECT + +#include <ft2build.h> +#include "psobjs.c" +#include "psauxmod.c" +#include "t1decode.c" +#include "t1cmap.c" + +#ifndef T1_CONFIG_OPTION_NO_AFM +#include "afmparse.c" +#endif + +#include "psconv.c" + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/psaux/psauxerr.h b/mod/pub.mod/freetype.mod/src/psaux/psauxerr.h new file mode 100644 index 0000000..d0baa3c --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/psaux/psauxerr.h @@ -0,0 +1,41 @@ +/***************************************************************************/ +/* */ +/* psauxerr.h */ +/* */ +/* PS auxiliary module error codes (specification only). */ +/* */ +/* Copyright 2001 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file is used to define the PS auxiliary module error enumeration */ + /* constants. */ + /* */ + /*************************************************************************/ + +#ifndef __PSAUXERR_H__ +#define __PSAUXERR_H__ + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#define FT_ERR_PREFIX PSaux_Err_ +#define FT_ERR_BASE FT_Mod_Err_PSaux + +#include FT_ERRORS_H + +#endif /* __PSAUXERR_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/psaux/psauxmod.c b/mod/pub.mod/freetype.mod/src/psaux/psauxmod.c new file mode 100644 index 0000000..4c3579f --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/psaux/psauxmod.c @@ -0,0 +1,139 @@ +/***************************************************************************/ +/* */ +/* psauxmod.c */ +/* */ +/* FreeType auxiliary PostScript module implementation (body). */ +/* */ +/* Copyright 2000-2001, 2002, 2003, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include "psauxmod.h" +#include "psobjs.h" +#include "t1decode.h" +#include "t1cmap.h" + +#ifndef T1_CONFIG_OPTION_NO_AFM +#include "afmparse.h" +#endif + + + FT_CALLBACK_TABLE_DEF + const PS_Table_FuncsRec ps_table_funcs = + { + ps_table_new, + ps_table_done, + ps_table_add, + ps_table_release + }; + + + FT_CALLBACK_TABLE_DEF + const PS_Parser_FuncsRec ps_parser_funcs = + { + ps_parser_init, + ps_parser_done, + ps_parser_skip_spaces, + ps_parser_skip_PS_token, + ps_parser_to_int, + ps_parser_to_fixed, + ps_parser_to_bytes, + ps_parser_to_coord_array, + ps_parser_to_fixed_array, + ps_parser_to_token, + ps_parser_to_token_array, + ps_parser_load_field, + ps_parser_load_field_table + }; + + + FT_CALLBACK_TABLE_DEF + const T1_Builder_FuncsRec t1_builder_funcs = + { + t1_builder_init, + t1_builder_done, + t1_builder_check_points, + t1_builder_add_point, + t1_builder_add_point1, + t1_builder_add_contour, + t1_builder_start_point, + t1_builder_close_contour + }; + + + FT_CALLBACK_TABLE_DEF + const T1_Decoder_FuncsRec t1_decoder_funcs = + { + t1_decoder_init, + t1_decoder_done, + t1_decoder_parse_charstrings + }; + + +#ifndef T1_CONFIG_OPTION_NO_AFM + FT_CALLBACK_TABLE_DEF + const AFM_Parser_FuncsRec afm_parser_funcs = + { + afm_parser_init, + afm_parser_done, + afm_parser_parse + }; +#endif + + + FT_CALLBACK_TABLE_DEF + const T1_CMap_ClassesRec t1_cmap_classes = + { + &t1_cmap_standard_class_rec, + &t1_cmap_expert_class_rec, + &t1_cmap_custom_class_rec, + &t1_cmap_unicode_class_rec + }; + + + static + const PSAux_Interface psaux_interface = + { + &ps_table_funcs, + &ps_parser_funcs, + &t1_builder_funcs, + &t1_decoder_funcs, + t1_decrypt, + + (const T1_CMap_ClassesRec*) &t1_cmap_classes, + +#ifndef T1_CONFIG_OPTION_NO_AFM + &afm_parser_funcs, +#else + 0, +#endif + }; + + + FT_CALLBACK_TABLE_DEF + const FT_Module_Class psaux_module_class = + { + 0, + sizeof( FT_ModuleRec ), + "psaux", + 0x20000L, + 0x20000L, + + &psaux_interface, /* module-specific interface */ + + (FT_Module_Constructor)0, + (FT_Module_Destructor) 0, + (FT_Module_Requester) 0 + }; + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/psaux/psauxmod.h b/mod/pub.mod/freetype.mod/src/psaux/psauxmod.h new file mode 100644 index 0000000..35e042d --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/psaux/psauxmod.h @@ -0,0 +1,42 @@ +/***************************************************************************/ +/* */ +/* psauxmod.h */ +/* */ +/* FreeType auxiliary PostScript module implementation (specification). */ +/* */ +/* Copyright 2000-2001 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __PSAUXMOD_H__ +#define __PSAUXMOD_H__ + + +#include <ft2build.h> +#include FT_MODULE_H + + +FT_BEGIN_HEADER + +#ifdef FT_CONFIG_OPTION_PIC +#error "this module does not support PIC yet" +#endif + + + FT_EXPORT_VAR( const FT_Module_Class ) psaux_driver_class; + + +FT_END_HEADER + +#endif /* __PSAUXMOD_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/psaux/psconv.c b/mod/pub.mod/freetype.mod/src/psaux/psconv.c new file mode 100644 index 0000000..1531d8f --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/psaux/psconv.c @@ -0,0 +1,472 @@ +/***************************************************************************/ +/* */ +/* psconv.c */ +/* */ +/* Some convenience conversions (body). */ +/* */ +/* Copyright 2006, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_POSTSCRIPT_AUX_H + +#include "psconv.h" +#include "psauxerr.h" + + + /* The following array is used by various functions to quickly convert */ + /* digits (both decimal and non-decimal) into numbers. */ + +#if 'A' == 65 + /* ASCII */ + + static const FT_Char ft_char_table[128] = + { + /* 0x00 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, + -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, + -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, + }; + + /* no character >= 0x80 can represent a valid number */ +#define OP >= + +#endif /* 'A' == 65 */ + +#if 'A' == 193 + /* EBCDIC */ + + static const FT_Char ft_char_table[128] = + { + /* 0x80 */ + -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, -1, -1, -1, -1, -1, -1, + -1, 19, 20, 21, 22, 23, 24, 25, 26, 27, -1, -1, -1, -1, -1, -1, + -1, -1, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, -1, -1, -1, -1, -1, -1, + -1, 19, 20, 21, 22, 23, 24, 25, 26, 27, -1, -1, -1, -1, -1, -1, + -1, -1, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, -1, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, + }; + + /* no character < 0x80 can represent a valid number */ +#define OP < + +#endif /* 'A' == 193 */ + + + FT_LOCAL_DEF( FT_Int ) + PS_Conv_Strtol( FT_Byte** cursor, + FT_Byte* limit, + FT_Int base ) + { + FT_Byte* p = *cursor; + FT_Int num = 0; + FT_Bool sign = 0; + + + if ( p == limit || base < 2 || base > 36 ) + return 0; + + if ( *p == '-' || *p == '+' ) + { + sign = FT_BOOL( *p == '-' ); + + p++; + if ( p == limit ) + return 0; + } + + for ( ; p < limit; p++ ) + { + FT_Char c; + + + if ( IS_PS_SPACE( *p ) || *p OP 0x80 ) + break; + + c = ft_char_table[*p & 0x7f]; + + if ( c < 0 || c >= base ) + break; + + num = num * base + c; + } + + if ( sign ) + num = -num; + + *cursor = p; + + return num; + } + + + FT_LOCAL_DEF( FT_Int ) + PS_Conv_ToInt( FT_Byte** cursor, + FT_Byte* limit ) + + { + FT_Byte* p; + FT_Int num; + + + num = PS_Conv_Strtol( cursor, limit, 10 ); + p = *cursor; + + if ( p < limit && *p == '#' ) + { + *cursor = p + 1; + + return PS_Conv_Strtol( cursor, limit, num ); + } + else + return num; + } + + + FT_LOCAL_DEF( FT_Fixed ) + PS_Conv_ToFixed( FT_Byte** cursor, + FT_Byte* limit, + FT_Int power_ten ) + { + FT_Byte* p = *cursor; + FT_Fixed integral; + FT_Long decimal = 0, divider = 1; + FT_Bool sign = 0; + + + if ( p == limit ) + return 0; + + if ( *p == '-' || *p == '+' ) + { + sign = FT_BOOL( *p == '-' ); + + p++; + if ( p == limit ) + return 0; + } + + if ( *p != '.' ) + integral = PS_Conv_ToInt( &p, limit ) << 16; + else + integral = 0; + + /* read the decimal part */ + if ( p < limit && *p == '.' ) + { + p++; + + for ( ; p < limit; p++ ) + { + FT_Char c; + + + if ( IS_PS_SPACE( *p ) || *p OP 0x80 ) + break; + + c = ft_char_table[*p & 0x7f]; + + if ( c < 0 || c >= 10 ) + break; + + if ( !integral && power_ten > 0 ) + { + power_ten--; + decimal = decimal * 10 + c; + } + else + { + if ( divider < 10000000L ) + { + decimal = decimal * 10 + c; + divider *= 10; + } + } + } + } + + /* read exponent, if any */ + if ( p + 1 < limit && ( *p == 'e' || *p == 'E' ) ) + { + p++; + power_ten += PS_Conv_ToInt( &p, limit ); + } + + while ( power_ten > 0 ) + { + integral *= 10; + decimal *= 10; + power_ten--; + } + + while ( power_ten < 0 ) + { + integral /= 10; + divider *= 10; + power_ten++; + } + + if ( decimal ) + integral += FT_DivFix( decimal, divider ); + + if ( sign ) + integral = -integral; + + *cursor = p; + + return integral; + } + + +#if 0 + FT_LOCAL_DEF( FT_UInt ) + PS_Conv_StringDecode( FT_Byte** cursor, + FT_Byte* limit, + FT_Byte* buffer, + FT_Offset n ) + { + FT_Byte* p; + FT_UInt r = 0; + + + for ( p = *cursor; r < n && p < limit; p++ ) + { + FT_Byte b; + + + if ( *p != '\\' ) + { + buffer[r++] = *p; + + continue; + } + + p++; + + switch ( *p ) + { + case 'n': + b = '\n'; + break; + case 'r': + b = '\r'; + break; + case 't': + b = '\t'; + break; + case 'b': + b = '\b'; + break; + case 'f': + b = '\f'; + break; + case '\r': + p++; + if ( *p != '\n' ) + { + b = *p; + + break; + } + /* no break */ + case '\n': + continue; + break; + default: + if ( IS_PS_DIGIT( *p ) ) + { + b = *p - '0'; + + p++; + + if ( IS_PS_DIGIT( *p ) ) + { + b = b * 8 + *p - '0'; + + p++; + + if ( IS_PS_DIGIT( *p ) ) + b = b * 8 + *p - '0'; + else + { + buffer[r++] = b; + b = *p; + } + } + else + { + buffer[r++] = b; + b = *p; + } + } + else + b = *p; + break; + } + + buffer[r++] = b; + } + + *cursor = p; + + return r; + } +#endif /* 0 */ + + + FT_LOCAL_DEF( FT_UInt ) + PS_Conv_ASCIIHexDecode( FT_Byte** cursor, + FT_Byte* limit, + FT_Byte* buffer, + FT_Offset n ) + { + FT_Byte* p; + FT_UInt r = 0; + FT_UInt w = 0; + FT_UInt pad = 0x01; + + + n *= 2; + +#if 1 + + p = *cursor; + if ( n > (FT_UInt)( limit - p ) ) + n = (FT_UInt)( limit - p ); + + /* we try to process two nibbles at a time to be as fast as possible */ + for ( ; r < n; r++ ) + { + FT_UInt c = p[r]; + + + if ( IS_PS_SPACE( c ) ) + continue; + + if ( c OP 0x80 ) + break; + + c = ft_char_table[c & 0x7F]; + if ( (unsigned)c >= 16 ) + break; + + pad = ( pad << 4 ) | c; + if ( pad & 0x100 ) + { + buffer[w++] = (FT_Byte)pad; + pad = 0x01; + } + } + + if ( pad != 0x01 ) + buffer[w++] = (FT_Byte)( pad << 4 ); + + *cursor = p + r; + + return w; + +#else /* 0 */ + + for ( r = 0; r < n; r++ ) + { + FT_Char c; + + + if ( IS_PS_SPACE( *p ) ) + continue; + + if ( *p OP 0x80 ) + break; + + c = ft_char_table[*p & 0x7f]; + + if ( (unsigned)c >= 16 ) + break; + + if ( r & 1 ) + { + *buffer = (FT_Byte)(*buffer + c); + buffer++; + } + else + *buffer = (FT_Byte)(c << 4); + + r++; + } + + *cursor = p; + + return ( r + 1 ) / 2; + +#endif /* 0 */ + + } + + + FT_LOCAL_DEF( FT_UInt ) + PS_Conv_EexecDecode( FT_Byte** cursor, + FT_Byte* limit, + FT_Byte* buffer, + FT_Offset n, + FT_UShort* seed ) + { + FT_Byte* p; + FT_UInt r; + FT_UInt s = *seed; + + +#if 1 + + p = *cursor; + if ( n > (FT_UInt)(limit - p) ) + n = (FT_UInt)(limit - p); + + for ( r = 0; r < n; r++ ) + { + FT_UInt val = p[r]; + FT_UInt b = ( val ^ ( s >> 8 ) ); + + + s = ( (val + s)*52845U + 22719 ) & 0xFFFFU; + buffer[r] = (FT_Byte) b; + } + + *cursor = p + n; + *seed = (FT_UShort)s; + +#else /* 0 */ + + for ( r = 0, p = *cursor; r < n && p < limit; r++, p++ ) + { + FT_Byte b = (FT_Byte)( *p ^ ( s >> 8 ) ); + + + s = (FT_UShort)( ( *p + s ) * 52845U + 22719 ); + *buffer++ = b; + } + *cursor = p; + *seed = s; + +#endif /* 0 */ + + return r; + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/psaux/psconv.h b/mod/pub.mod/freetype.mod/src/psaux/psconv.h new file mode 100644 index 0000000..84854ba --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/psaux/psconv.h @@ -0,0 +1,71 @@ +/***************************************************************************/ +/* */ +/* psconv.h */ +/* */ +/* Some convenience conversions (specification). */ +/* */ +/* Copyright 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __PSCONV_H__ +#define __PSCONV_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_POSTSCRIPT_AUX_H + +FT_BEGIN_HEADER + + + FT_LOCAL( FT_Int ) + PS_Conv_Strtol( FT_Byte** cursor, + FT_Byte* limit, + FT_Int base ); + + + FT_LOCAL( FT_Int ) + PS_Conv_ToInt( FT_Byte** cursor, + FT_Byte* limit ); + + FT_LOCAL( FT_Fixed ) + PS_Conv_ToFixed( FT_Byte** cursor, + FT_Byte* limit, + FT_Int power_ten ); + +#if 0 + FT_LOCAL( FT_UInt ) + PS_Conv_StringDecode( FT_Byte** cursor, + FT_Byte* limit, + FT_Byte* buffer, + FT_Offset n ); +#endif + + FT_LOCAL( FT_UInt ) + PS_Conv_ASCIIHexDecode( FT_Byte** cursor, + FT_Byte* limit, + FT_Byte* buffer, + FT_Offset n ); + + FT_LOCAL( FT_UInt ) + PS_Conv_EexecDecode( FT_Byte** cursor, + FT_Byte* limit, + FT_Byte* buffer, + FT_Offset n, + FT_UShort* seed ); + + +FT_END_HEADER + +#endif /* __PSCONV_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/psaux/psobjs.c b/mod/pub.mod/freetype.mod/src/psaux/psobjs.c new file mode 100644 index 0000000..fe8398a --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/psaux/psobjs.c @@ -0,0 +1,1703 @@ +/***************************************************************************/ +/* */ +/* psobjs.c */ +/* */ +/* Auxiliary functions for PostScript fonts (body). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_POSTSCRIPT_AUX_H +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_CALC_H + +#include "psobjs.h" +#include "psconv.h" + +#include "psauxerr.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_psobjs + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** PS_TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* <Function> */ + /* ps_table_new */ + /* */ + /* <Description> */ + /* Initializes a PS_Table. */ + /* */ + /* <InOut> */ + /* table :: The address of the target table. */ + /* */ + /* <Input> */ + /* count :: The table size = the maximum number of elements. */ + /* */ + /* memory :: The memory object to use for all subsequent */ + /* reallocations. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + ps_table_new( PS_Table table, + FT_Int count, + FT_Memory memory ) + { + FT_Error error; + + + table->memory = memory; + if ( FT_NEW_ARRAY( table->elements, count ) || + FT_NEW_ARRAY( table->lengths, count ) ) + goto Exit; + + table->max_elems = count; + table->init = 0xDEADBEEFUL; + table->num_elems = 0; + table->block = 0; + table->capacity = 0; + table->cursor = 0; + + *(PS_Table_FuncsRec*)&table->funcs = ps_table_funcs; + + Exit: + if ( error ) + FT_FREE( table->elements ); + + return error; + } + + + static void + shift_elements( PS_Table table, + FT_Byte* old_base ) + { + FT_PtrDist delta = table->block - old_base; + FT_Byte** offset = table->elements; + FT_Byte** limit = offset + table->max_elems; + + + for ( ; offset < limit; offset++ ) + { + if ( offset[0] ) + offset[0] += delta; + } + } + + + static FT_Error + reallocate_t1_table( PS_Table table, + FT_Long new_size ) + { + FT_Memory memory = table->memory; + FT_Byte* old_base = table->block; + FT_Error error; + + + /* allocate new base block */ + if ( FT_ALLOC( table->block, new_size ) ) + { + table->block = old_base; + return error; + } + + /* copy elements and shift offsets */ + if ( old_base ) + { + FT_MEM_COPY( table->block, old_base, table->capacity ); + shift_elements( table, old_base ); + FT_FREE( old_base ); + } + + table->capacity = new_size; + + return PSaux_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* ps_table_add */ + /* */ + /* <Description> */ + /* Adds an object to a PS_Table, possibly growing its memory block. */ + /* */ + /* <InOut> */ + /* table :: The target table. */ + /* */ + /* <Input> */ + /* idx :: The index of the object in the table. */ + /* */ + /* object :: The address of the object to copy in memory. */ + /* */ + /* length :: The length in bytes of the source object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. An error is returned if a */ + /* reallocation fails. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + ps_table_add( PS_Table table, + FT_Int idx, + void* object, + FT_PtrDist length ) + { + if ( idx < 0 || idx >= table->max_elems ) + { + FT_ERROR(( "ps_table_add: invalid index\n" )); + return PSaux_Err_Invalid_Argument; + } + + if ( length < 0 ) + { + FT_ERROR(( "ps_table_add: invalid length\n" )); + return PSaux_Err_Invalid_Argument; + } + + /* grow the base block if needed */ + if ( table->cursor + length > table->capacity ) + { + FT_Error error; + FT_Offset new_size = table->capacity; + FT_Long in_offset; + + + in_offset = (FT_Long)((FT_Byte*)object - table->block); + if ( (FT_ULong)in_offset >= table->capacity ) + in_offset = -1; + + while ( new_size < table->cursor + length ) + { + /* increase size by 25% and round up to the nearest multiple + of 1024 */ + new_size += ( new_size >> 2 ) + 1; + new_size = FT_PAD_CEIL( new_size, 1024 ); + } + + error = reallocate_t1_table( table, new_size ); + if ( error ) + return error; + + if ( in_offset >= 0 ) + object = table->block + in_offset; + } + + /* add the object to the base block and adjust offset */ + table->elements[idx] = table->block + table->cursor; + table->lengths [idx] = length; + FT_MEM_COPY( table->block + table->cursor, object, length ); + + table->cursor += length; + return PSaux_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* ps_table_done */ + /* */ + /* <Description> */ + /* Finalizes a PS_TableRec (i.e., reallocate it to its current */ + /* cursor). */ + /* */ + /* <InOut> */ + /* table :: The target table. */ + /* */ + /* <Note> */ + /* This function does NOT release the heap's memory block. It is up */ + /* to the caller to clean it, or reference it in its own structures. */ + /* */ + FT_LOCAL_DEF( void ) + ps_table_done( PS_Table table ) + { + FT_Memory memory = table->memory; + FT_Error error; + FT_Byte* old_base = table->block; + + + /* should never fail, because rec.cursor <= rec.size */ + if ( !old_base ) + return; + + if ( FT_ALLOC( table->block, table->cursor ) ) + return; + FT_MEM_COPY( table->block, old_base, table->cursor ); + shift_elements( table, old_base ); + + table->capacity = table->cursor; + FT_FREE( old_base ); + + FT_UNUSED( error ); + } + + + FT_LOCAL_DEF( void ) + ps_table_release( PS_Table table ) + { + FT_Memory memory = table->memory; + + + if ( (FT_ULong)table->init == 0xDEADBEEFUL ) + { + FT_FREE( table->block ); + FT_FREE( table->elements ); + FT_FREE( table->lengths ); + table->init = 0; + } + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** T1 PARSER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + /* first character must be already part of the comment */ + + static void + skip_comment( FT_Byte* *acur, + FT_Byte* limit ) + { + FT_Byte* cur = *acur; + + + while ( cur < limit ) + { + if ( IS_PS_NEWLINE( *cur ) ) + break; + cur++; + } + + *acur = cur; + } + + + static void + skip_spaces( FT_Byte* *acur, + FT_Byte* limit ) + { + FT_Byte* cur = *acur; + + + while ( cur < limit ) + { + if ( !IS_PS_SPACE( *cur ) ) + { + if ( *cur == '%' ) + /* According to the PLRM, a comment is equal to a space. */ + skip_comment( &cur, limit ); + else + break; + } + cur++; + } + + *acur = cur; + } + + +#define IS_OCTAL_DIGIT( c ) ( '0' <= (c) && (c) <= '7' ) + + + /* first character must be `('; */ + /* *acur is positioned at the character after the closing `)' */ + + static FT_Error + skip_literal_string( FT_Byte* *acur, + FT_Byte* limit ) + { + FT_Byte* cur = *acur; + FT_Int embed = 0; + FT_Error error = PSaux_Err_Invalid_File_Format; + unsigned int i; + + + while ( cur < limit ) + { + FT_Byte c = *cur; + + + ++cur; + + if ( c == '\\' ) + { + /* Red Book 3rd ed., section `Literal Text Strings', p. 29: */ + /* A backslash can introduce three different types */ + /* of escape sequences: */ + /* - a special escaped char like \r, \n, etc. */ + /* - a one-, two-, or three-digit octal number */ + /* - none of the above in which case the backslash is ignored */ + + if ( cur == limit ) + /* error (or to be ignored?) */ + break; + + switch ( *cur ) + { + /* skip `special' escape */ + case 'n': + case 'r': + case 't': + case 'b': + case 'f': + case '\\': + case '(': + case ')': + ++cur; + break; + + default: + /* skip octal escape or ignore backslash */ + for ( i = 0; i < 3 && cur < limit; ++i ) + { + if ( !IS_OCTAL_DIGIT( *cur ) ) + break; + + ++cur; + } + } + } + else if ( c == '(' ) + embed++; + else if ( c == ')' ) + { + embed--; + if ( embed == 0 ) + { + error = PSaux_Err_Ok; + break; + } + } + } + + *acur = cur; + + return error; + } + + + /* first character must be `<' */ + + static FT_Error + skip_string( FT_Byte* *acur, + FT_Byte* limit ) + { + FT_Byte* cur = *acur; + FT_Error err = PSaux_Err_Ok; + + + while ( ++cur < limit ) + { + /* All whitespace characters are ignored. */ + skip_spaces( &cur, limit ); + if ( cur >= limit ) + break; + + if ( !IS_PS_XDIGIT( *cur ) ) + break; + } + + if ( cur < limit && *cur != '>' ) + { + FT_ERROR(( "skip_string: missing closing delimiter `>'\n" )); + err = PSaux_Err_Invalid_File_Format; + } + else + cur++; + + *acur = cur; + return err; + } + + + /* first character must be the opening brace that */ + /* starts the procedure */ + + /* NB: [ and ] need not match: */ + /* `/foo {[} def' is a valid PostScript fragment, */ + /* even within a Type1 font */ + + static FT_Error + skip_procedure( FT_Byte* *acur, + FT_Byte* limit ) + { + FT_Byte* cur; + FT_Int embed = 0; + FT_Error error = PSaux_Err_Ok; + + + FT_ASSERT( **acur == '{' ); + + for ( cur = *acur; cur < limit && error == PSaux_Err_Ok; ++cur ) + { + switch ( *cur ) + { + case '{': + ++embed; + break; + + case '}': + --embed; + if ( embed == 0 ) + { + ++cur; + goto end; + } + break; + + case '(': + error = skip_literal_string( &cur, limit ); + break; + + case '<': + error = skip_string( &cur, limit ); + break; + + case '%': + skip_comment( &cur, limit ); + break; + } + } + + end: + if ( embed != 0 ) + error = PSaux_Err_Invalid_File_Format; + + *acur = cur; + + return error; + } + + + /***********************************************************************/ + /* */ + /* All exported parsing routines handle leading whitespace and stop at */ + /* the first character which isn't part of the just handled token. */ + /* */ + /***********************************************************************/ + + + FT_LOCAL_DEF( void ) + ps_parser_skip_PS_token( PS_Parser parser ) + { + /* Note: PostScript allows any non-delimiting, non-whitespace */ + /* character in a name (PS Ref Manual, 3rd ed, p31). */ + /* PostScript delimiters are (, ), <, >, [, ], {, }, /, and %. */ + + FT_Byte* cur = parser->cursor; + FT_Byte* limit = parser->limit; + FT_Error error = PSaux_Err_Ok; + + + skip_spaces( &cur, limit ); /* this also skips comments */ + if ( cur >= limit ) + goto Exit; + + /* self-delimiting, single-character tokens */ + if ( *cur == '[' || *cur == ']' ) + { + cur++; + goto Exit; + } + + /* skip balanced expressions (procedures and strings) */ + + if ( *cur == '{' ) /* {...} */ + { + error = skip_procedure( &cur, limit ); + goto Exit; + } + + if ( *cur == '(' ) /* (...) */ + { + error = skip_literal_string( &cur, limit ); + goto Exit; + } + + if ( *cur == '<' ) /* <...> */ + { + if ( cur + 1 < limit && *(cur + 1) == '<' ) /* << */ + { + cur++; + cur++; + } + else + error = skip_string( &cur, limit ); + + goto Exit; + } + + if ( *cur == '>' ) + { + cur++; + if ( cur >= limit || *cur != '>' ) /* >> */ + { + FT_ERROR(( "ps_parser_skip_PS_token:" + " unexpected closing delimiter `>'\n" )); + error = PSaux_Err_Invalid_File_Format; + goto Exit; + } + cur++; + goto Exit; + } + + if ( *cur == '/' ) + cur++; + + /* anything else */ + while ( cur < limit ) + { + /* *cur might be invalid (e.g., ')' or '}'), but this */ + /* is handled by the test `cur == parser->cursor' below */ + if ( IS_PS_DELIM( *cur ) ) + break; + + cur++; + } + + Exit: + if ( cur == parser->cursor ) + { + FT_ERROR(( "ps_parser_skip_PS_token:" + " current token is `%c' which is self-delimiting\n" + " " + " but invalid at this point\n", + *cur )); + + error = PSaux_Err_Invalid_File_Format; + } + + parser->error = error; + parser->cursor = cur; + } + + + FT_LOCAL_DEF( void ) + ps_parser_skip_spaces( PS_Parser parser ) + { + skip_spaces( &parser->cursor, parser->limit ); + } + + + /* `token' here means either something between balanced delimiters */ + /* or the next token; the delimiters are not removed. */ + + FT_LOCAL_DEF( void ) + ps_parser_to_token( PS_Parser parser, + T1_Token token ) + { + FT_Byte* cur; + FT_Byte* limit; + FT_Int embed; + + + token->type = T1_TOKEN_TYPE_NONE; + token->start = 0; + token->limit = 0; + + /* first of all, skip leading whitespace */ + ps_parser_skip_spaces( parser ); + + cur = parser->cursor; + limit = parser->limit; + + if ( cur >= limit ) + return; + + switch ( *cur ) + { + /************* check for literal string *****************/ + case '(': + token->type = T1_TOKEN_TYPE_STRING; + token->start = cur; + + if ( skip_literal_string( &cur, limit ) == PSaux_Err_Ok ) + token->limit = cur; + break; + + /************* check for programs/array *****************/ + case '{': + token->type = T1_TOKEN_TYPE_ARRAY; + token->start = cur; + + if ( skip_procedure( &cur, limit ) == PSaux_Err_Ok ) + token->limit = cur; + break; + + /************* check for table/array ********************/ + /* XXX: in theory we should also look for "<<" */ + /* since this is semantically equivalent to "["; */ + /* in practice it doesn't matter (?) */ + case '[': + token->type = T1_TOKEN_TYPE_ARRAY; + embed = 1; + token->start = cur++; + + /* we need this to catch `[ ]' */ + parser->cursor = cur; + ps_parser_skip_spaces( parser ); + cur = parser->cursor; + + while ( cur < limit && !parser->error ) + { + /* XXX: this is wrong because it does not */ + /* skip comments, procedures, and strings */ + if ( *cur == '[' ) + embed++; + else if ( *cur == ']' ) + { + embed--; + if ( embed <= 0 ) + { + token->limit = ++cur; + break; + } + } + + parser->cursor = cur; + ps_parser_skip_PS_token( parser ); + /* we need this to catch `[XXX ]' */ + ps_parser_skip_spaces ( parser ); + cur = parser->cursor; + } + break; + + /* ************ otherwise, it is any token **************/ + default: + token->start = cur; + token->type = ( *cur == '/' ? T1_TOKEN_TYPE_KEY : T1_TOKEN_TYPE_ANY ); + ps_parser_skip_PS_token( parser ); + cur = parser->cursor; + if ( !parser->error ) + token->limit = cur; + } + + if ( !token->limit ) + { + token->start = 0; + token->type = T1_TOKEN_TYPE_NONE; + } + + parser->cursor = cur; + } + + + /* NB: `tokens' can be NULL if we only want to count */ + /* the number of array elements */ + + FT_LOCAL_DEF( void ) + ps_parser_to_token_array( PS_Parser parser, + T1_Token tokens, + FT_UInt max_tokens, + FT_Int* pnum_tokens ) + { + T1_TokenRec master; + + + *pnum_tokens = -1; + + /* this also handles leading whitespace */ + ps_parser_to_token( parser, &master ); + + if ( master.type == T1_TOKEN_TYPE_ARRAY ) + { + FT_Byte* old_cursor = parser->cursor; + FT_Byte* old_limit = parser->limit; + T1_Token cur = tokens; + T1_Token limit = cur + max_tokens; + + + /* don't include outermost delimiters */ + parser->cursor = master.start + 1; + parser->limit = master.limit - 1; + + while ( parser->cursor < parser->limit ) + { + T1_TokenRec token; + + + ps_parser_to_token( parser, &token ); + if ( !token.type ) + break; + + if ( tokens != NULL && cur < limit ) + *cur = token; + + cur++; + } + + *pnum_tokens = (FT_Int)( cur - tokens ); + + parser->cursor = old_cursor; + parser->limit = old_limit; + } + } + + + /* first character must be a delimiter or a part of a number */ + /* NB: `coords' can be NULL if we just want to skip the */ + /* array; in this case we ignore `max_coords' */ + + static FT_Int + ps_tocoordarray( FT_Byte* *acur, + FT_Byte* limit, + FT_Int max_coords, + FT_Short* coords ) + { + FT_Byte* cur = *acur; + FT_Int count = 0; + FT_Byte c, ender; + + + if ( cur >= limit ) + goto Exit; + + /* check for the beginning of an array; otherwise, only one number */ + /* will be read */ + c = *cur; + ender = 0; + + if ( c == '[' ) + ender = ']'; + else if ( c == '{' ) + ender = '}'; + + if ( ender ) + cur++; + + /* now, read the coordinates */ + while ( cur < limit ) + { + FT_Short dummy; + FT_Byte* old_cur; + + + /* skip whitespace in front of data */ + skip_spaces( &cur, limit ); + if ( cur >= limit ) + goto Exit; + + if ( *cur == ender ) + { + cur++; + break; + } + + old_cur = cur; + + if ( coords != NULL && count >= max_coords ) + break; + + /* call PS_Conv_ToFixed() even if coords == NULL */ + /* to properly parse number at `cur' */ + *( coords != NULL ? &coords[count] : &dummy ) = + (FT_Short)( PS_Conv_ToFixed( &cur, limit, 0 ) >> 16 ); + + if ( old_cur == cur ) + { + count = -1; + goto Exit; + } + else + count++; + + if ( !ender ) + break; + } + + Exit: + *acur = cur; + return count; + } + + + /* first character must be a delimiter or a part of a number */ + /* NB: `values' can be NULL if we just want to skip the */ + /* array; in this case we ignore `max_values' */ + + static FT_Int + ps_tofixedarray( FT_Byte* *acur, + FT_Byte* limit, + FT_Int max_values, + FT_Fixed* values, + FT_Int power_ten ) + { + FT_Byte* cur = *acur; + FT_Int count = 0; + FT_Byte c, ender; + + + if ( cur >= limit ) + goto Exit; + + /* Check for the beginning of an array. Otherwise, only one number */ + /* will be read. */ + c = *cur; + ender = 0; + + if ( c == '[' ) + ender = ']'; + else if ( c == '{' ) + ender = '}'; + + if ( ender ) + cur++; + + /* now, read the values */ + while ( cur < limit ) + { + FT_Fixed dummy; + FT_Byte* old_cur; + + + /* skip whitespace in front of data */ + skip_spaces( &cur, limit ); + if ( cur >= limit ) + goto Exit; + + if ( *cur == ender ) + { + cur++; + break; + } + + old_cur = cur; + + if ( values != NULL && count >= max_values ) + break; + + /* call PS_Conv_ToFixed() even if coords == NULL */ + /* to properly parse number at `cur' */ + *( values != NULL ? &values[count] : &dummy ) = + PS_Conv_ToFixed( &cur, limit, power_ten ); + + if ( old_cur == cur ) + { + count = -1; + goto Exit; + } + else + count++; + + if ( !ender ) + break; + } + + Exit: + *acur = cur; + return count; + } + + +#if 0 + + static FT_String* + ps_tostring( FT_Byte** cursor, + FT_Byte* limit, + FT_Memory memory ) + { + FT_Byte* cur = *cursor; + FT_PtrDist len = 0; + FT_Int count; + FT_String* result; + FT_Error error; + + + /* XXX: some stupid fonts have a `Notice' or `Copyright' string */ + /* that simply doesn't begin with an opening parenthesis, even */ + /* though they have a closing one! E.g. "amuncial.pfb" */ + /* */ + /* We must deal with these ill-fated cases there. Note that */ + /* these fonts didn't work with the old Type 1 driver as the */ + /* notice/copyright was not recognized as a valid string token */ + /* and made the old token parser commit errors. */ + + while ( cur < limit && ( *cur == ' ' || *cur == '\t' ) ) + cur++; + if ( cur + 1 >= limit ) + return 0; + + if ( *cur == '(' ) + cur++; /* skip the opening parenthesis, if there is one */ + + *cursor = cur; + count = 0; + + /* then, count its length */ + for ( ; cur < limit; cur++ ) + { + if ( *cur == '(' ) + count++; + + else if ( *cur == ')' ) + { + count--; + if ( count < 0 ) + break; + } + } + + len = cur - *cursor; + if ( cur >= limit || FT_ALLOC( result, len + 1 ) ) + return 0; + + /* now copy the string */ + FT_MEM_COPY( result, *cursor, len ); + result[len] = '\0'; + *cursor = cur; + return result; + } + +#endif /* 0 */ + + + static int + ps_tobool( FT_Byte* *acur, + FT_Byte* limit ) + { + FT_Byte* cur = *acur; + FT_Bool result = 0; + + + /* return 1 if we find `true', 0 otherwise */ + if ( cur + 3 < limit && + cur[0] == 't' && + cur[1] == 'r' && + cur[2] == 'u' && + cur[3] == 'e' ) + { + result = 1; + cur += 5; + } + else if ( cur + 4 < limit && + cur[0] == 'f' && + cur[1] == 'a' && + cur[2] == 'l' && + cur[3] == 's' && + cur[4] == 'e' ) + { + result = 0; + cur += 6; + } + + *acur = cur; + return result; + } + + + /* load a simple field (i.e. non-table) into the current list of objects */ + + FT_LOCAL_DEF( FT_Error ) + ps_parser_load_field( PS_Parser parser, + const T1_Field field, + void** objects, + FT_UInt max_objects, + FT_ULong* pflags ) + { + T1_TokenRec token; + FT_Byte* cur; + FT_Byte* limit; + FT_UInt count; + FT_UInt idx; + FT_Error error; + + + /* this also skips leading whitespace */ + ps_parser_to_token( parser, &token ); + if ( !token.type ) + goto Fail; + + count = 1; + idx = 0; + cur = token.start; + limit = token.limit; + + /* we must detect arrays in /FontBBox */ + if ( field->type == T1_FIELD_TYPE_BBOX ) + { + T1_TokenRec token2; + FT_Byte* old_cur = parser->cursor; + FT_Byte* old_limit = parser->limit; + + + /* don't include delimiters */ + parser->cursor = token.start + 1; + parser->limit = token.limit - 1; + + ps_parser_to_token( parser, &token2 ); + parser->cursor = old_cur; + parser->limit = old_limit; + + if ( token2.type == T1_TOKEN_TYPE_ARRAY ) + goto FieldArray; + } + else if ( token.type == T1_TOKEN_TYPE_ARRAY ) + { + FieldArray: + /* if this is an array and we have no blend, an error occurs */ + if ( max_objects == 0 ) + goto Fail; + + count = max_objects; + idx = 1; + + /* don't include delimiters */ + cur++; + limit--; + } + + for ( ; count > 0; count--, idx++ ) + { + FT_Byte* q = (FT_Byte*)objects[idx] + field->offset; + FT_Long val; + FT_String* string; + + + skip_spaces( &cur, limit ); + + switch ( field->type ) + { + case T1_FIELD_TYPE_BOOL: + val = ps_tobool( &cur, limit ); + goto Store_Integer; + + case T1_FIELD_TYPE_FIXED: + val = PS_Conv_ToFixed( &cur, limit, 0 ); + goto Store_Integer; + + case T1_FIELD_TYPE_FIXED_1000: + val = PS_Conv_ToFixed( &cur, limit, 3 ); + goto Store_Integer; + + case T1_FIELD_TYPE_INTEGER: + val = PS_Conv_ToInt( &cur, limit ); + /* fall through */ + + Store_Integer: + switch ( field->size ) + { + case (8 / FT_CHAR_BIT): + *(FT_Byte*)q = (FT_Byte)val; + break; + + case (16 / FT_CHAR_BIT): + *(FT_UShort*)q = (FT_UShort)val; + break; + + case (32 / FT_CHAR_BIT): + *(FT_UInt32*)q = (FT_UInt32)val; + break; + + default: /* for 64-bit systems */ + *(FT_Long*)q = val; + } + break; + + case T1_FIELD_TYPE_STRING: + case T1_FIELD_TYPE_KEY: + { + FT_Memory memory = parser->memory; + FT_UInt len = (FT_UInt)( limit - cur ); + + + if ( cur >= limit ) + break; + + /* we allow both a string or a name */ + /* for cases like /FontName (foo) def */ + if ( token.type == T1_TOKEN_TYPE_KEY ) + { + /* don't include leading `/' */ + len--; + cur++; + } + else if ( token.type == T1_TOKEN_TYPE_STRING ) + { + /* don't include delimiting parentheses */ + /* XXX we don't handle <<...>> here */ + /* XXX should we convert octal escapes? */ + /* if so, what encoding should we use? */ + cur++; + len -= 2; + } + else + { + FT_ERROR(( "ps_parser_load_field:" + " expected a name or string\n" + " " + " but found token of type %d instead\n", + token.type )); + error = PSaux_Err_Invalid_File_Format; + goto Exit; + } + + /* for this to work (FT_String**)q must have been */ + /* initialized to NULL */ + if ( *(FT_String**)q != NULL ) + { + FT_TRACE0(( "ps_parser_load_field: overwriting field %s\n", + field->ident )); + FT_FREE( *(FT_String**)q ); + *(FT_String**)q = NULL; + } + + if ( FT_ALLOC( string, len + 1 ) ) + goto Exit; + + FT_MEM_COPY( string, cur, len ); + string[len] = 0; + + *(FT_String**)q = string; + } + break; + + case T1_FIELD_TYPE_BBOX: + { + FT_Fixed temp[4]; + FT_BBox* bbox = (FT_BBox*)q; + FT_Int result; + + + result = ps_tofixedarray( &cur, limit, 4, temp, 0 ); + + if ( result < 0 ) + { + FT_ERROR(( "ps_parser_load_field:" + " expected four integers in bounding box\n" )); + error = PSaux_Err_Invalid_File_Format; + goto Exit; + } + + bbox->xMin = FT_RoundFix( temp[0] ); + bbox->yMin = FT_RoundFix( temp[1] ); + bbox->xMax = FT_RoundFix( temp[2] ); + bbox->yMax = FT_RoundFix( temp[3] ); + } + break; + + default: + /* an error occurred */ + goto Fail; + } + } + +#if 0 /* obsolete -- keep for reference */ + if ( pflags ) + *pflags |= 1L << field->flag_bit; +#else + FT_UNUSED( pflags ); +#endif + + error = PSaux_Err_Ok; + + Exit: + return error; + + Fail: + error = PSaux_Err_Invalid_File_Format; + goto Exit; + } + + +#define T1_MAX_TABLE_ELEMENTS 32 + + + FT_LOCAL_DEF( FT_Error ) + ps_parser_load_field_table( PS_Parser parser, + const T1_Field field, + void** objects, + FT_UInt max_objects, + FT_ULong* pflags ) + { + T1_TokenRec elements[T1_MAX_TABLE_ELEMENTS]; + T1_Token token; + FT_Int num_elements; + FT_Error error = PSaux_Err_Ok; + FT_Byte* old_cursor; + FT_Byte* old_limit; + T1_FieldRec fieldrec = *(T1_Field)field; + + + fieldrec.type = T1_FIELD_TYPE_INTEGER; + if ( field->type == T1_FIELD_TYPE_FIXED_ARRAY || + field->type == T1_FIELD_TYPE_BBOX ) + fieldrec.type = T1_FIELD_TYPE_FIXED; + + ps_parser_to_token_array( parser, elements, + T1_MAX_TABLE_ELEMENTS, &num_elements ); + if ( num_elements < 0 ) + { + error = PSaux_Err_Ignore; + goto Exit; + } + if ( (FT_UInt)num_elements > field->array_max ) + num_elements = field->array_max; + + old_cursor = parser->cursor; + old_limit = parser->limit; + + /* we store the elements count if necessary; */ + /* we further assume that `count_offset' can't be zero */ + if ( field->type != T1_FIELD_TYPE_BBOX && field->count_offset != 0 ) + *(FT_Byte*)( (FT_Byte*)objects[0] + field->count_offset ) = + (FT_Byte)num_elements; + + /* we now load each element, adjusting the field.offset on each one */ + token = elements; + for ( ; num_elements > 0; num_elements--, token++ ) + { + parser->cursor = token->start; + parser->limit = token->limit; + ps_parser_load_field( parser, &fieldrec, objects, max_objects, 0 ); + fieldrec.offset += fieldrec.size; + } + +#if 0 /* obsolete -- keep for reference */ + if ( pflags ) + *pflags |= 1L << field->flag_bit; +#else + FT_UNUSED( pflags ); +#endif + + parser->cursor = old_cursor; + parser->limit = old_limit; + + Exit: + return error; + } + + + FT_LOCAL_DEF( FT_Long ) + ps_parser_to_int( PS_Parser parser ) + { + ps_parser_skip_spaces( parser ); + return PS_Conv_ToInt( &parser->cursor, parser->limit ); + } + + + /* first character must be `<' if `delimiters' is non-zero */ + + FT_LOCAL_DEF( FT_Error ) + ps_parser_to_bytes( PS_Parser parser, + FT_Byte* bytes, + FT_Offset max_bytes, + FT_Long* pnum_bytes, + FT_Bool delimiters ) + { + FT_Error error = PSaux_Err_Ok; + FT_Byte* cur; + + + ps_parser_skip_spaces( parser ); + cur = parser->cursor; + + if ( cur >= parser->limit ) + goto Exit; + + if ( delimiters ) + { + if ( *cur != '<' ) + { + FT_ERROR(( "ps_parser_to_bytes: Missing starting delimiter `<'\n" )); + error = PSaux_Err_Invalid_File_Format; + goto Exit; + } + + cur++; + } + + *pnum_bytes = PS_Conv_ASCIIHexDecode( &cur, + parser->limit, + bytes, + max_bytes ); + + if ( delimiters ) + { + if ( cur < parser->limit && *cur != '>' ) + { + FT_ERROR(( "ps_parser_to_bytes: Missing closing delimiter `>'\n" )); + error = PSaux_Err_Invalid_File_Format; + goto Exit; + } + + cur++; + } + + parser->cursor = cur; + + Exit: + return error; + } + + + FT_LOCAL_DEF( FT_Fixed ) + ps_parser_to_fixed( PS_Parser parser, + FT_Int power_ten ) + { + ps_parser_skip_spaces( parser ); + return PS_Conv_ToFixed( &parser->cursor, parser->limit, power_ten ); + } + + + FT_LOCAL_DEF( FT_Int ) + ps_parser_to_coord_array( PS_Parser parser, + FT_Int max_coords, + FT_Short* coords ) + { + ps_parser_skip_spaces( parser ); + return ps_tocoordarray( &parser->cursor, parser->limit, + max_coords, coords ); + } + + + FT_LOCAL_DEF( FT_Int ) + ps_parser_to_fixed_array( PS_Parser parser, + FT_Int max_values, + FT_Fixed* values, + FT_Int power_ten ) + { + ps_parser_skip_spaces( parser ); + return ps_tofixedarray( &parser->cursor, parser->limit, + max_values, values, power_ten ); + } + + +#if 0 + + FT_LOCAL_DEF( FT_String* ) + T1_ToString( PS_Parser parser ) + { + return ps_tostring( &parser->cursor, parser->limit, parser->memory ); + } + + + FT_LOCAL_DEF( FT_Bool ) + T1_ToBool( PS_Parser parser ) + { + return ps_tobool( &parser->cursor, parser->limit ); + } + +#endif /* 0 */ + + + FT_LOCAL_DEF( void ) + ps_parser_init( PS_Parser parser, + FT_Byte* base, + FT_Byte* limit, + FT_Memory memory ) + { + parser->error = PSaux_Err_Ok; + parser->base = base; + parser->limit = limit; + parser->cursor = base; + parser->memory = memory; + parser->funcs = ps_parser_funcs; + } + + + FT_LOCAL_DEF( void ) + ps_parser_done( PS_Parser parser ) + { + FT_UNUSED( parser ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** T1 BUILDER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* <Function> */ + /* t1_builder_init */ + /* */ + /* <Description> */ + /* Initializes a given glyph builder. */ + /* */ + /* <InOut> */ + /* builder :: A pointer to the glyph builder to initialize. */ + /* */ + /* <Input> */ + /* face :: The current face object. */ + /* */ + /* size :: The current size object. */ + /* */ + /* glyph :: The current glyph object. */ + /* */ + /* hinting :: Whether hinting should be applied. */ + /* */ + FT_LOCAL_DEF( void ) + t1_builder_init( T1_Builder builder, + FT_Face face, + FT_Size size, + FT_GlyphSlot glyph, + FT_Bool hinting ) + { + builder->parse_state = T1_Parse_Start; + builder->load_points = 1; + + builder->face = face; + builder->glyph = glyph; + builder->memory = face->memory; + + if ( glyph ) + { + FT_GlyphLoader loader = glyph->internal->loader; + + + builder->loader = loader; + builder->base = &loader->base.outline; + builder->current = &loader->current.outline; + FT_GlyphLoader_Rewind( loader ); + + builder->hints_globals = size->internal; + builder->hints_funcs = 0; + + if ( hinting ) + builder->hints_funcs = glyph->internal->glyph_hints; + } + + builder->pos_x = 0; + builder->pos_y = 0; + + builder->left_bearing.x = 0; + builder->left_bearing.y = 0; + builder->advance.x = 0; + builder->advance.y = 0; + + builder->funcs = t1_builder_funcs; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* t1_builder_done */ + /* */ + /* <Description> */ + /* Finalizes a given glyph builder. Its contents can still be used */ + /* after the call, but the function saves important information */ + /* within the corresponding glyph slot. */ + /* */ + /* <Input> */ + /* builder :: A pointer to the glyph builder to finalize. */ + /* */ + FT_LOCAL_DEF( void ) + t1_builder_done( T1_Builder builder ) + { + FT_GlyphSlot glyph = builder->glyph; + + + if ( glyph ) + glyph->outline = *builder->base; + } + + + /* check that there is enough space for `count' more points */ + FT_LOCAL_DEF( FT_Error ) + t1_builder_check_points( T1_Builder builder, + FT_Int count ) + { + return FT_GLYPHLOADER_CHECK_POINTS( builder->loader, count, 0 ); + } + + + /* add a new point, do not check space */ + FT_LOCAL_DEF( void ) + t1_builder_add_point( T1_Builder builder, + FT_Pos x, + FT_Pos y, + FT_Byte flag ) + { + FT_Outline* outline = builder->current; + + + if ( builder->load_points ) + { + FT_Vector* point = outline->points + outline->n_points; + FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points; + + + point->x = FIXED_TO_INT( x ); + point->y = FIXED_TO_INT( y ); + *control = (FT_Byte)( flag ? FT_CURVE_TAG_ON : FT_CURVE_TAG_CUBIC ); + } + outline->n_points++; + } + + + /* check space for a new on-curve point, then add it */ + FT_LOCAL_DEF( FT_Error ) + t1_builder_add_point1( T1_Builder builder, + FT_Pos x, + FT_Pos y ) + { + FT_Error error; + + + error = t1_builder_check_points( builder, 1 ); + if ( !error ) + t1_builder_add_point( builder, x, y, 1 ); + + return error; + } + + + /* check space for a new contour, then add it */ + FT_LOCAL_DEF( FT_Error ) + t1_builder_add_contour( T1_Builder builder ) + { + FT_Outline* outline = builder->current; + FT_Error error; + + + if ( !builder->load_points ) + { + outline->n_contours++; + return PSaux_Err_Ok; + } + + error = FT_GLYPHLOADER_CHECK_POINTS( builder->loader, 0, 1 ); + if ( !error ) + { + if ( outline->n_contours > 0 ) + outline->contours[outline->n_contours - 1] = + (short)( outline->n_points - 1 ); + + outline->n_contours++; + } + + return error; + } + + + /* if a path was begun, add its first on-curve point */ + FT_LOCAL_DEF( FT_Error ) + t1_builder_start_point( T1_Builder builder, + FT_Pos x, + FT_Pos y ) + { + FT_Error error = PSaux_Err_Invalid_File_Format; + + + /* test whether we are building a new contour */ + + if ( builder->parse_state == T1_Parse_Have_Path ) + error = PSaux_Err_Ok; + else if ( builder->parse_state == T1_Parse_Have_Moveto ) + { + builder->parse_state = T1_Parse_Have_Path; + error = t1_builder_add_contour( builder ); + if ( !error ) + error = t1_builder_add_point1( builder, x, y ); + } + + return error; + } + + + /* close the current contour */ + FT_LOCAL_DEF( void ) + t1_builder_close_contour( T1_Builder builder ) + { + FT_Outline* outline = builder->current; + FT_Int first; + + + if ( !outline ) + return; + + first = outline->n_contours <= 1 + ? 0 : outline->contours[outline->n_contours - 2] + 1; + + /* We must not include the last point in the path if it */ + /* is located on the first point. */ + if ( outline->n_points > 1 ) + { + FT_Vector* p1 = outline->points + first; + FT_Vector* p2 = outline->points + outline->n_points - 1; + FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points - 1; + + + /* `delete' last point only if it coincides with the first */ + /* point and it is not a control point (which can happen). */ + if ( p1->x == p2->x && p1->y == p2->y ) + if ( *control == FT_CURVE_TAG_ON ) + outline->n_points--; + } + + if ( outline->n_contours > 0 ) + { + /* Don't add contours only consisting of one point, i.e., */ + /* check whether the first and the last point is the same. */ + if ( first == outline->n_points - 1 ) + { + outline->n_contours--; + outline->n_points--; + } + else + outline->contours[outline->n_contours - 1] = + (short)( outline->n_points - 1 ); + } + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** OTHER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL_DEF( void ) + t1_decrypt( FT_Byte* buffer, + FT_Offset length, + FT_UShort seed ) + { + PS_Conv_EexecDecode( &buffer, + buffer + length, + buffer, + length, + &seed ); + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/psaux/psobjs.h b/mod/pub.mod/freetype.mod/src/psaux/psobjs.h new file mode 100644 index 0000000..e380c60 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/psaux/psobjs.h @@ -0,0 +1,212 @@ +/***************************************************************************/ +/* */ +/* psobjs.h */ +/* */ +/* Auxiliary functions for PostScript fonts (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2003 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __PSOBJS_H__ +#define __PSOBJS_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_POSTSCRIPT_AUX_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** T1_TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + FT_CALLBACK_TABLE + const PS_Table_FuncsRec ps_table_funcs; + + FT_CALLBACK_TABLE + const PS_Parser_FuncsRec ps_parser_funcs; + + FT_CALLBACK_TABLE + const T1_Builder_FuncsRec t1_builder_funcs; + + + FT_LOCAL( FT_Error ) + ps_table_new( PS_Table table, + FT_Int count, + FT_Memory memory ); + + FT_LOCAL( FT_Error ) + ps_table_add( PS_Table table, + FT_Int idx, + void* object, + FT_PtrDist length ); + + FT_LOCAL( void ) + ps_table_done( PS_Table table ); + + + FT_LOCAL( void ) + ps_table_release( PS_Table table ); + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** T1 PARSER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + FT_LOCAL( void ) + ps_parser_skip_spaces( PS_Parser parser ); + + FT_LOCAL( void ) + ps_parser_skip_PS_token( PS_Parser parser ); + + FT_LOCAL( void ) + ps_parser_to_token( PS_Parser parser, + T1_Token token ); + + FT_LOCAL( void ) + ps_parser_to_token_array( PS_Parser parser, + T1_Token tokens, + FT_UInt max_tokens, + FT_Int* pnum_tokens ); + + FT_LOCAL( FT_Error ) + ps_parser_load_field( PS_Parser parser, + const T1_Field field, + void** objects, + FT_UInt max_objects, + FT_ULong* pflags ); + + FT_LOCAL( FT_Error ) + ps_parser_load_field_table( PS_Parser parser, + const T1_Field field, + void** objects, + FT_UInt max_objects, + FT_ULong* pflags ); + + FT_LOCAL( FT_Long ) + ps_parser_to_int( PS_Parser parser ); + + + FT_LOCAL( FT_Error ) + ps_parser_to_bytes( PS_Parser parser, + FT_Byte* bytes, + FT_Offset max_bytes, + FT_Long* pnum_bytes, + FT_Bool delimiters ); + + + FT_LOCAL( FT_Fixed ) + ps_parser_to_fixed( PS_Parser parser, + FT_Int power_ten ); + + + FT_LOCAL( FT_Int ) + ps_parser_to_coord_array( PS_Parser parser, + FT_Int max_coords, + FT_Short* coords ); + + FT_LOCAL( FT_Int ) + ps_parser_to_fixed_array( PS_Parser parser, + FT_Int max_values, + FT_Fixed* values, + FT_Int power_ten ); + + + FT_LOCAL( void ) + ps_parser_init( PS_Parser parser, + FT_Byte* base, + FT_Byte* limit, + FT_Memory memory ); + + FT_LOCAL( void ) + ps_parser_done( PS_Parser parser ); + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** T1 BUILDER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL( void ) + t1_builder_init( T1_Builder builder, + FT_Face face, + FT_Size size, + FT_GlyphSlot glyph, + FT_Bool hinting ); + + FT_LOCAL( void ) + t1_builder_done( T1_Builder builder ); + + FT_LOCAL( FT_Error ) + t1_builder_check_points( T1_Builder builder, + FT_Int count ); + + FT_LOCAL( void ) + t1_builder_add_point( T1_Builder builder, + FT_Pos x, + FT_Pos y, + FT_Byte flag ); + + FT_LOCAL( FT_Error ) + t1_builder_add_point1( T1_Builder builder, + FT_Pos x, + FT_Pos y ); + + FT_LOCAL( FT_Error ) + t1_builder_add_contour( T1_Builder builder ); + + + FT_LOCAL( FT_Error ) + t1_builder_start_point( T1_Builder builder, + FT_Pos x, + FT_Pos y ); + + + FT_LOCAL( void ) + t1_builder_close_contour( T1_Builder builder ); + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** OTHER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL( void ) + t1_decrypt( FT_Byte* buffer, + FT_Offset length, + FT_UShort seed ); + + +FT_END_HEADER + +#endif /* __PSOBJS_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/psaux/t1cmap.c b/mod/pub.mod/freetype.mod/src/psaux/t1cmap.c new file mode 100644 index 0000000..f933e4d --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/psaux/t1cmap.c @@ -0,0 +1,341 @@ +/***************************************************************************/ +/* */ +/* t1cmap.c */ +/* */ +/* Type 1 character map support (body). */ +/* */ +/* Copyright 2002, 2003, 2006, 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include "t1cmap.h" + +#include FT_INTERNAL_DEBUG_H + +#include "psauxerr.h" + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** TYPE1 STANDARD (AND EXPERT) ENCODING CMAPS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + t1_cmap_std_init( T1_CMapStd cmap, + FT_Int is_expert ) + { + T1_Face face = (T1_Face)FT_CMAP_FACE( cmap ); + FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames; + + + cmap->num_glyphs = face->type1.num_glyphs; + cmap->glyph_names = (const char* const*)face->type1.glyph_names; + cmap->sid_to_string = psnames->adobe_std_strings; + cmap->code_to_sid = is_expert ? psnames->adobe_expert_encoding + : psnames->adobe_std_encoding; + + FT_ASSERT( cmap->code_to_sid != NULL ); + } + + + FT_CALLBACK_DEF( void ) + t1_cmap_std_done( T1_CMapStd cmap ) + { + cmap->num_glyphs = 0; + cmap->glyph_names = NULL; + cmap->sid_to_string = NULL; + cmap->code_to_sid = NULL; + } + + + FT_CALLBACK_DEF( FT_UInt ) + t1_cmap_std_char_index( T1_CMapStd cmap, + FT_UInt32 char_code ) + { + FT_UInt result = 0; + + + if ( char_code < 256 ) + { + FT_UInt code, n; + const char* glyph_name; + + + /* convert character code to Adobe SID string */ + code = cmap->code_to_sid[char_code]; + glyph_name = cmap->sid_to_string( code ); + + /* look for the corresponding glyph name */ + for ( n = 0; n < cmap->num_glyphs; n++ ) + { + const char* gname = cmap->glyph_names[n]; + + + if ( gname && gname[0] == glyph_name[0] && + ft_strcmp( gname, glyph_name ) == 0 ) + { + result = n; + break; + } + } + } + + return result; + } + + + FT_CALLBACK_DEF( FT_UInt32 ) + t1_cmap_std_char_next( T1_CMapStd cmap, + FT_UInt32 *pchar_code ) + { + FT_UInt result = 0; + FT_UInt32 char_code = *pchar_code + 1; + + + while ( char_code < 256 ) + { + result = t1_cmap_std_char_index( cmap, char_code ); + if ( result != 0 ) + goto Exit; + + char_code++; + } + char_code = 0; + + Exit: + *pchar_code = char_code; + return result; + } + + + FT_CALLBACK_DEF( FT_Error ) + t1_cmap_standard_init( T1_CMapStd cmap ) + { + t1_cmap_std_init( cmap, 0 ); + return 0; + } + + + FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec + t1_cmap_standard_class_rec = + { + sizeof ( T1_CMapStdRec ), + + (FT_CMap_InitFunc) t1_cmap_standard_init, + (FT_CMap_DoneFunc) t1_cmap_std_done, + (FT_CMap_CharIndexFunc)t1_cmap_std_char_index, + (FT_CMap_CharNextFunc) t1_cmap_std_char_next, + + NULL, NULL, NULL, NULL, NULL + }; + + + FT_CALLBACK_DEF( FT_Error ) + t1_cmap_expert_init( T1_CMapStd cmap ) + { + t1_cmap_std_init( cmap, 1 ); + return 0; + } + + FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec + t1_cmap_expert_class_rec = + { + sizeof ( T1_CMapStdRec ), + + (FT_CMap_InitFunc) t1_cmap_expert_init, + (FT_CMap_DoneFunc) t1_cmap_std_done, + (FT_CMap_CharIndexFunc)t1_cmap_std_char_index, + (FT_CMap_CharNextFunc) t1_cmap_std_char_next, + + NULL, NULL, NULL, NULL, NULL + }; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** TYPE1 CUSTOM ENCODING CMAP *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + FT_CALLBACK_DEF( FT_Error ) + t1_cmap_custom_init( T1_CMapCustom cmap ) + { + T1_Face face = (T1_Face)FT_CMAP_FACE( cmap ); + T1_Encoding encoding = &face->type1.encoding; + + + cmap->first = encoding->code_first; + cmap->count = (FT_UInt)( encoding->code_last - cmap->first ); + cmap->indices = encoding->char_index; + + FT_ASSERT( cmap->indices != NULL ); + FT_ASSERT( encoding->code_first <= encoding->code_last ); + + return 0; + } + + + FT_CALLBACK_DEF( void ) + t1_cmap_custom_done( T1_CMapCustom cmap ) + { + cmap->indices = NULL; + cmap->first = 0; + cmap->count = 0; + } + + + FT_CALLBACK_DEF( FT_UInt ) + t1_cmap_custom_char_index( T1_CMapCustom cmap, + FT_UInt32 char_code ) + { + FT_UInt result = 0; + + + if ( ( char_code >= cmap->first ) && + ( char_code < ( cmap->first + cmap->count ) ) ) + result = cmap->indices[char_code]; + + return result; + } + + + FT_CALLBACK_DEF( FT_UInt32 ) + t1_cmap_custom_char_next( T1_CMapCustom cmap, + FT_UInt32 *pchar_code ) + { + FT_UInt result = 0; + FT_UInt32 char_code = *pchar_code; + + + ++char_code; + + if ( char_code < cmap->first ) + char_code = cmap->first; + + for ( ; char_code < ( cmap->first + cmap->count ); char_code++ ) + { + result = cmap->indices[char_code]; + if ( result != 0 ) + goto Exit; + } + + char_code = 0; + + Exit: + *pchar_code = char_code; + return result; + } + + + FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec + t1_cmap_custom_class_rec = + { + sizeof ( T1_CMapCustomRec ), + + (FT_CMap_InitFunc) t1_cmap_custom_init, + (FT_CMap_DoneFunc) t1_cmap_custom_done, + (FT_CMap_CharIndexFunc)t1_cmap_custom_char_index, + (FT_CMap_CharNextFunc) t1_cmap_custom_char_next, + + NULL, NULL, NULL, NULL, NULL + }; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** TYPE1 SYNTHETIC UNICODE ENCODING CMAP *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_CALLBACK_DEF( const char * ) + t1_get_glyph_name( T1_Face face, + FT_UInt idx ) + { + return face->type1.glyph_names[idx]; + } + + + FT_CALLBACK_DEF( FT_Error ) + t1_cmap_unicode_init( PS_Unicodes unicodes ) + { + T1_Face face = (T1_Face)FT_CMAP_FACE( unicodes ); + FT_Memory memory = FT_FACE_MEMORY( face ); + FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames; + + + return psnames->unicodes_init( memory, + unicodes, + face->type1.num_glyphs, + (PS_GetGlyphNameFunc)&t1_get_glyph_name, + (PS_FreeGlyphNameFunc)NULL, + (FT_Pointer)face ); + } + + + FT_CALLBACK_DEF( void ) + t1_cmap_unicode_done( PS_Unicodes unicodes ) + { + FT_Face face = FT_CMAP_FACE( unicodes ); + FT_Memory memory = FT_FACE_MEMORY( face ); + + + FT_FREE( unicodes->maps ); + unicodes->num_maps = 0; + } + + + FT_CALLBACK_DEF( FT_UInt ) + t1_cmap_unicode_char_index( PS_Unicodes unicodes, + FT_UInt32 char_code ) + { + T1_Face face = (T1_Face)FT_CMAP_FACE( unicodes ); + FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames; + + + return psnames->unicodes_char_index( unicodes, char_code ); + } + + + FT_CALLBACK_DEF( FT_UInt32 ) + t1_cmap_unicode_char_next( PS_Unicodes unicodes, + FT_UInt32 *pchar_code ) + { + T1_Face face = (T1_Face)FT_CMAP_FACE( unicodes ); + FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames; + + + return psnames->unicodes_char_next( unicodes, pchar_code ); + } + + + FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec + t1_cmap_unicode_class_rec = + { + sizeof ( PS_UnicodesRec ), + + (FT_CMap_InitFunc) t1_cmap_unicode_init, + (FT_CMap_DoneFunc) t1_cmap_unicode_done, + (FT_CMap_CharIndexFunc)t1_cmap_unicode_char_index, + (FT_CMap_CharNextFunc) t1_cmap_unicode_char_next, + + NULL, NULL, NULL, NULL, NULL + }; + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/psaux/t1cmap.h b/mod/pub.mod/freetype.mod/src/psaux/t1cmap.h new file mode 100644 index 0000000..7ae65d2 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/psaux/t1cmap.h @@ -0,0 +1,105 @@ +/***************************************************************************/ +/* */ +/* t1cmap.h */ +/* */ +/* Type 1 character map support (specification). */ +/* */ +/* Copyright 2002, 2003, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __T1CMAP_H__ +#define __T1CMAP_H__ + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_TYPE1_TYPES_H + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** TYPE1 STANDARD (AND EXPERT) ENCODING CMAPS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* standard (and expert) encoding cmaps */ + typedef struct T1_CMapStdRec_* T1_CMapStd; + + typedef struct T1_CMapStdRec_ + { + FT_CMapRec cmap; + + const FT_UShort* code_to_sid; + PS_Adobe_Std_StringsFunc sid_to_string; + + FT_UInt num_glyphs; + const char* const* glyph_names; + + } T1_CMapStdRec; + + + FT_CALLBACK_TABLE const FT_CMap_ClassRec + t1_cmap_standard_class_rec; + + FT_CALLBACK_TABLE const FT_CMap_ClassRec + t1_cmap_expert_class_rec; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** TYPE1 CUSTOM ENCODING CMAP *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef struct T1_CMapCustomRec_* T1_CMapCustom; + + typedef struct T1_CMapCustomRec_ + { + FT_CMapRec cmap; + FT_UInt first; + FT_UInt count; + FT_UShort* indices; + + } T1_CMapCustomRec; + + + FT_CALLBACK_TABLE const FT_CMap_ClassRec + t1_cmap_custom_class_rec; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** TYPE1 SYNTHETIC UNICODE ENCODING CMAP *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* unicode (synthetic) cmaps */ + + FT_CALLBACK_TABLE const FT_CMap_ClassRec + t1_cmap_unicode_class_rec; + + /* */ + + +FT_END_HEADER + +#endif /* __T1CMAP_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/psaux/t1decode.c b/mod/pub.mod/freetype.mod/src/psaux/t1decode.c new file mode 100644 index 0000000..b3245a6 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/psaux/t1decode.c @@ -0,0 +1,1577 @@ +/***************************************************************************/ +/* */ +/* t1decode.c */ +/* */ +/* PostScript Type 1 decoding routines (body). */ +/* */ +/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_CALC_H +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_POSTSCRIPT_HINTS_H +#include FT_OUTLINE_H + +#include "t1decode.h" +#include "psobjs.h" + +#include "psauxerr.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_t1decode + + + typedef enum T1_Operator_ + { + op_none = 0, + op_endchar, + op_hsbw, + op_seac, + op_sbw, + op_closepath, + op_hlineto, + op_hmoveto, + op_hvcurveto, + op_rlineto, + op_rmoveto, + op_rrcurveto, + op_vhcurveto, + op_vlineto, + op_vmoveto, + op_dotsection, + op_hstem, + op_hstem3, + op_vstem, + op_vstem3, + op_div, + op_callothersubr, + op_callsubr, + op_pop, + op_return, + op_setcurrentpoint, + op_unknown15, + + op_max /* never remove this one */ + + } T1_Operator; + + + static + const FT_Int t1_args_count[op_max] = + { + 0, /* none */ + 0, /* endchar */ + 2, /* hsbw */ + 5, /* seac */ + 4, /* sbw */ + 0, /* closepath */ + 1, /* hlineto */ + 1, /* hmoveto */ + 4, /* hvcurveto */ + 2, /* rlineto */ + 2, /* rmoveto */ + 6, /* rrcurveto */ + 4, /* vhcurveto */ + 1, /* vlineto */ + 1, /* vmoveto */ + 0, /* dotsection */ + 2, /* hstem */ + 6, /* hstem3 */ + 2, /* vstem */ + 6, /* vstem3 */ + 2, /* div */ + -1, /* callothersubr */ + 1, /* callsubr */ + 0, /* pop */ + 0, /* return */ + 2, /* setcurrentpoint */ + 2 /* opcode 15 (undocumented and obsolete) */ + }; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* t1_lookup_glyph_by_stdcharcode */ + /* */ + /* <Description> */ + /* Looks up a given glyph by its StandardEncoding charcode. Used to */ + /* implement the SEAC Type 1 operator. */ + /* */ + /* <Input> */ + /* face :: The current face object. */ + /* */ + /* charcode :: The character code to look for. */ + /* */ + /* <Return> */ + /* A glyph index in the font face. Returns -1 if the corresponding */ + /* glyph wasn't found. */ + /* */ + static FT_Int + t1_lookup_glyph_by_stdcharcode( T1_Decoder decoder, + FT_Int charcode ) + { + FT_UInt n; + const FT_String* glyph_name; + FT_Service_PsCMaps psnames = decoder->psnames; + + + /* check range of standard char code */ + if ( charcode < 0 || charcode > 255 ) + return -1; + + glyph_name = psnames->adobe_std_strings( + psnames->adobe_std_encoding[charcode]); + + for ( n = 0; n < decoder->num_glyphs; n++ ) + { + FT_String* name = (FT_String*)decoder->glyph_names[n]; + + + if ( name && + name[0] == glyph_name[0] && + ft_strcmp( name, glyph_name ) == 0 ) + return n; + } + + return -1; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* t1operator_seac */ + /* */ + /* <Description> */ + /* Implements the `seac' Type 1 operator for a Type 1 decoder. */ + /* */ + /* <Input> */ + /* decoder :: The current CID decoder. */ + /* */ + /* asb :: The accent's side bearing. */ + /* */ + /* adx :: The horizontal offset of the accent. */ + /* */ + /* ady :: The vertical offset of the accent. */ + /* */ + /* bchar :: The base character's StandardEncoding charcode. */ + /* */ + /* achar :: The accent character's StandardEncoding charcode. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + static FT_Error + t1operator_seac( T1_Decoder decoder, + FT_Pos asb, + FT_Pos adx, + FT_Pos ady, + FT_Int bchar, + FT_Int achar ) + { + FT_Error error; + FT_Int bchar_index, achar_index; +#if 0 + FT_Int n_base_points; + FT_Outline* base = decoder->builder.base; +#endif + FT_Vector left_bearing, advance; + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + T1_Face face = (T1_Face)decoder->builder.face; +#endif + + + if ( decoder->seac ) + { + FT_ERROR(( "t1operator_seac: invalid nested seac\n" )); + return PSaux_Err_Syntax_Error; + } + + /* seac weirdness */ + adx += decoder->builder.left_bearing.x; + + /* `glyph_names' is set to 0 for CID fonts which do not */ + /* include an encoding. How can we deal with these? */ + if ( decoder->glyph_names == 0 ) + { + FT_ERROR(( "t1operator_seac:" + " glyph names table not available in this font\n" )); + return PSaux_Err_Syntax_Error; + } + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + if ( face->root.internal->incremental_interface ) + { + /* the caller must handle the font encoding also */ + bchar_index = bchar; + achar_index = achar; + } + else +#endif + { + bchar_index = t1_lookup_glyph_by_stdcharcode( decoder, bchar ); + achar_index = t1_lookup_glyph_by_stdcharcode( decoder, achar ); + } + + if ( bchar_index < 0 || achar_index < 0 ) + { + FT_ERROR(( "t1operator_seac:" + " invalid seac character code arguments\n" )); + return PSaux_Err_Syntax_Error; + } + + /* if we are trying to load a composite glyph, do not load the */ + /* accent character and return the array of subglyphs. */ + if ( decoder->builder.no_recurse ) + { + FT_GlyphSlot glyph = (FT_GlyphSlot)decoder->builder.glyph; + FT_GlyphLoader loader = glyph->internal->loader; + FT_SubGlyph subg; + + + /* reallocate subglyph array if necessary */ + error = FT_GlyphLoader_CheckSubGlyphs( loader, 2 ); + if ( error ) + goto Exit; + + subg = loader->current.subglyphs; + + /* subglyph 0 = base character */ + subg->index = bchar_index; + subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES | + FT_SUBGLYPH_FLAG_USE_MY_METRICS; + subg->arg1 = 0; + subg->arg2 = 0; + subg++; + + /* subglyph 1 = accent character */ + subg->index = achar_index; + subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES; + subg->arg1 = (FT_Int)FIXED_TO_INT( adx - asb ); + subg->arg2 = (FT_Int)FIXED_TO_INT( ady ); + + /* set up remaining glyph fields */ + glyph->num_subglyphs = 2; + glyph->subglyphs = loader->base.subglyphs; + glyph->format = FT_GLYPH_FORMAT_COMPOSITE; + + loader->current.num_subglyphs = 2; + goto Exit; + } + + /* First load `bchar' in builder */ + /* now load the unscaled outline */ + + FT_GlyphLoader_Prepare( decoder->builder.loader ); /* prepare loader */ + + /* the seac operator must not be nested */ + decoder->seac = TRUE; + error = t1_decoder_parse_glyph( decoder, bchar_index ); + decoder->seac = FALSE; + if ( error ) + goto Exit; + + /* save the left bearing and width of the base character */ + /* as they will be erased by the next load. */ + + left_bearing = decoder->builder.left_bearing; + advance = decoder->builder.advance; + + decoder->builder.left_bearing.x = 0; + decoder->builder.left_bearing.y = 0; + + decoder->builder.pos_x = adx - asb; + decoder->builder.pos_y = ady; + + /* Now load `achar' on top of */ + /* the base outline */ + + /* the seac operator must not be nested */ + decoder->seac = TRUE; + error = t1_decoder_parse_glyph( decoder, achar_index ); + decoder->seac = FALSE; + if ( error ) + goto Exit; + + /* restore the left side bearing and */ + /* advance width of the base character */ + + decoder->builder.left_bearing = left_bearing; + decoder->builder.advance = advance; + + decoder->builder.pos_x = 0; + decoder->builder.pos_y = 0; + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* t1_decoder_parse_charstrings */ + /* */ + /* <Description> */ + /* Parses a given Type 1 charstrings program. */ + /* */ + /* <Input> */ + /* decoder :: The current Type 1 decoder. */ + /* */ + /* charstring_base :: The base address of the charstring stream. */ + /* */ + /* charstring_len :: The length in bytes of the charstring stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + t1_decoder_parse_charstrings( T1_Decoder decoder, + FT_Byte* charstring_base, + FT_UInt charstring_len ) + { + FT_Error error; + T1_Decoder_Zone zone; + FT_Byte* ip; + FT_Byte* limit; + T1_Builder builder = &decoder->builder; + FT_Pos x, y, orig_x, orig_y; + FT_Int known_othersubr_result_cnt = 0; + FT_Int unknown_othersubr_result_cnt = 0; + FT_Bool large_int; + FT_Fixed seed; + + T1_Hints_Funcs hinter; + +#ifdef FT_DEBUG_LEVEL_TRACE + FT_Bool bol = TRUE; +#endif + + + /* we don't want to touch the source code -- use macro trick */ +#define start_point t1_builder_start_point +#define check_points t1_builder_check_points +#define add_point t1_builder_add_point +#define add_point1 t1_builder_add_point1 +#define add_contour t1_builder_add_contour +#define close_contour t1_builder_close_contour + + + /* compute random seed from stack address of parameter */ + seed = (FT_Fixed)( ( (FT_PtrDist)(char*)&seed ^ + (FT_PtrDist)(char*)&decoder ^ + (FT_PtrDist)(char*)&charstring_base ) & + FT_ULONG_MAX ) ; + seed = ( seed ^ ( seed >> 10 ) ^ ( seed >> 20 ) ) & 0xFFFFL; + if ( seed == 0 ) + seed = 0x7384; + + /* First of all, initialize the decoder */ + decoder->top = decoder->stack; + decoder->zone = decoder->zones; + zone = decoder->zones; + + builder->parse_state = T1_Parse_Start; + + hinter = (T1_Hints_Funcs)builder->hints_funcs; + + /* a font that reads BuildCharArray without setting */ + /* its values first is buggy, but ... */ + FT_ASSERT( ( decoder->len_buildchar == 0 ) == + ( decoder->buildchar == NULL ) ); + + if ( decoder->len_buildchar > 0 ) + ft_memset( &decoder->buildchar[0], + 0, + sizeof( decoder->buildchar[0] ) * decoder->len_buildchar ); + + FT_TRACE4(( "\n" + "Start charstring\n" )); + + zone->base = charstring_base; + limit = zone->limit = charstring_base + charstring_len; + ip = zone->cursor = zone->base; + + error = PSaux_Err_Ok; + + x = orig_x = builder->pos_x; + y = orig_y = builder->pos_y; + + /* begin hints recording session, if any */ + if ( hinter ) + hinter->open( hinter->hints ); + + large_int = FALSE; + + /* now, execute loop */ + while ( ip < limit ) + { + FT_Long* top = decoder->top; + T1_Operator op = op_none; + FT_Int32 value = 0; + + + FT_ASSERT( known_othersubr_result_cnt == 0 || + unknown_othersubr_result_cnt == 0 ); + +#ifdef FT_DEBUG_LEVEL_TRACE + if ( bol ) + { + FT_TRACE5(( " (%d)", decoder->top - decoder->stack )); + bol = FALSE; + } +#endif + + /*********************************************************************/ + /* */ + /* Decode operator or operand */ + /* */ + /* */ + + /* first of all, decompress operator or value */ + switch ( *ip++ ) + { + case 1: + op = op_hstem; + break; + + case 3: + op = op_vstem; + break; + case 4: + op = op_vmoveto; + break; + case 5: + op = op_rlineto; + break; + case 6: + op = op_hlineto; + break; + case 7: + op = op_vlineto; + break; + case 8: + op = op_rrcurveto; + break; + case 9: + op = op_closepath; + break; + case 10: + op = op_callsubr; + break; + case 11: + op = op_return; + break; + + case 13: + op = op_hsbw; + break; + case 14: + op = op_endchar; + break; + + case 15: /* undocumented, obsolete operator */ + op = op_unknown15; + break; + + case 21: + op = op_rmoveto; + break; + case 22: + op = op_hmoveto; + break; + + case 30: + op = op_vhcurveto; + break; + case 31: + op = op_hvcurveto; + break; + + case 12: + if ( ip > limit ) + { + FT_ERROR(( "t1_decoder_parse_charstrings:" + " invalid escape (12+EOF)\n" )); + goto Syntax_Error; + } + + switch ( *ip++ ) + { + case 0: + op = op_dotsection; + break; + case 1: + op = op_vstem3; + break; + case 2: + op = op_hstem3; + break; + case 6: + op = op_seac; + break; + case 7: + op = op_sbw; + break; + case 12: + op = op_div; + break; + case 16: + op = op_callothersubr; + break; + case 17: + op = op_pop; + break; + case 33: + op = op_setcurrentpoint; + break; + + default: + FT_ERROR(( "t1_decoder_parse_charstrings:" + " invalid escape (12+%d)\n", + ip[-1] )); + goto Syntax_Error; + } + break; + + case 255: /* four bytes integer */ + if ( ip + 4 > limit ) + { + FT_ERROR(( "t1_decoder_parse_charstrings:" + " unexpected EOF in integer\n" )); + goto Syntax_Error; + } + + value = (FT_Int32)( ( (FT_Long)ip[0] << 24 ) | + ( (FT_Long)ip[1] << 16 ) | + ( (FT_Long)ip[2] << 8 ) | + ip[3] ); + ip += 4; + + /* According to the specification, values > 32000 or < -32000 must */ + /* be followed by a `div' operator to make the result be in the */ + /* range [-32000;32000]. We expect that the second argument of */ + /* `div' is not a large number. Additionally, we don't handle */ + /* stuff like `<large1> <large2> <num> div <num> div' or */ + /* <large1> <large2> <num> div div'. This is probably not allowed */ + /* anyway. */ + if ( value > 32000 || value < -32000 ) + { + if ( large_int ) + { + FT_ERROR(( "t1_decoder_parse_charstrings:" + " no `div' after large integer\n" )); + } + else + large_int = TRUE; + } + else + { + if ( !large_int ) + value <<= 16; + } + + break; + + default: + if ( ip[-1] >= 32 ) + { + if ( ip[-1] < 247 ) + value = (FT_Int32)ip[-1] - 139; + else + { + if ( ++ip > limit ) + { + FT_ERROR(( "t1_decoder_parse_charstrings:" + " unexpected EOF in integer\n" )); + goto Syntax_Error; + } + + if ( ip[-2] < 251 ) + value = ( ( (FT_Int32)ip[-2] - 247 ) << 8 ) + ip[-1] + 108; + else + value = -( ( ( (FT_Int32)ip[-2] - 251 ) << 8 ) + ip[-1] + 108 ); + } + + if ( !large_int ) + value <<= 16; + } + else + { + FT_ERROR(( "t1_decoder_parse_charstrings:" + " invalid byte (%d)\n", ip[-1] )); + goto Syntax_Error; + } + } + + if ( unknown_othersubr_result_cnt > 0 ) + { + switch ( op ) + { + case op_callsubr: + case op_return: + case op_none: + case op_pop: + break; + + default: + /* all operands have been transferred by previous pops */ + unknown_othersubr_result_cnt = 0; + break; + } + } + + if ( large_int && !( op == op_none || op == op_div ) ) + { + FT_ERROR(( "t1_decoder_parse_charstrings:" + " no `div' after large integer\n" )); + + large_int = FALSE; + } + + /*********************************************************************/ + /* */ + /* Push value on stack, or process operator */ + /* */ + /* */ + if ( op == op_none ) + { + if ( top - decoder->stack >= T1_MAX_CHARSTRINGS_OPERANDS ) + { + FT_ERROR(( "t1_decoder_parse_charstrings: stack overflow\n" )); + goto Syntax_Error; + } + +#ifdef FT_DEBUG_LEVEL_TRACE + if ( large_int ) + FT_TRACE4(( " %ld", value )); + else + FT_TRACE4(( " %ld", (FT_Int32)( value >> 16 ) )); +#endif + + *top++ = value; + decoder->top = top; + } + else if ( op == op_callothersubr ) /* callothersubr */ + { + FT_Int subr_no; + FT_Int arg_cnt; + + +#ifdef FT_DEBUG_LEVEL_TRACE + FT_TRACE4(( " callothersubr\n" )); + bol = TRUE; +#endif + + if ( top - decoder->stack < 2 ) + goto Stack_Underflow; + + top -= 2; + + subr_no = (FT_Int)( top[1] >> 16 ); + arg_cnt = (FT_Int)( top[0] >> 16 ); + + /***********************************************************/ + /* */ + /* remove all operands to callothersubr from the stack */ + /* */ + /* for handled othersubrs, where we know the number of */ + /* arguments, we increase the stack by the value of */ + /* known_othersubr_result_cnt */ + /* */ + /* for unhandled othersubrs the following pops adjust the */ + /* stack pointer as necessary */ + + if ( arg_cnt > top - decoder->stack ) + goto Stack_Underflow; + + top -= arg_cnt; + + known_othersubr_result_cnt = 0; + unknown_othersubr_result_cnt = 0; + + /* XXX TODO: The checks to `arg_count == <whatever>' */ + /* might not be correct; an othersubr expects a certain */ + /* number of operands on the PostScript stack (as opposed */ + /* to the T1 stack) but it doesn't have to put them there */ + /* by itself; previous othersubrs might have left the */ + /* operands there if they were not followed by an */ + /* appropriate number of pops */ + /* */ + /* On the other hand, Adobe Reader 7.0.8 for Linux doesn't */ + /* accept a font that contains charstrings like */ + /* */ + /* 100 200 2 20 callothersubr */ + /* 300 1 20 callothersubr pop */ + /* */ + /* Perhaps this is the reason why BuildCharArray exists. */ + + switch ( subr_no ) + { + case 1: /* start flex feature */ + if ( arg_cnt != 0 ) + goto Unexpected_OtherSubr; + + decoder->flex_state = 1; + decoder->num_flex_vectors = 0; + if ( start_point( builder, x, y ) || + check_points( builder, 6 ) ) + goto Fail; + break; + + case 2: /* add flex vectors */ + { + FT_Int idx; + + + if ( arg_cnt != 0 ) + goto Unexpected_OtherSubr; + + /* note that we should not add a point for index 0; */ + /* this will move our current position to the flex */ + /* point without adding any point to the outline */ + idx = decoder->num_flex_vectors++; + if ( idx > 0 && idx < 7 ) + add_point( builder, + x, + y, + (FT_Byte)( idx == 3 || idx == 6 ) ); + } + break; + + case 0: /* end flex feature */ + if ( arg_cnt != 3 ) + goto Unexpected_OtherSubr; + + if ( decoder->flex_state == 0 || + decoder->num_flex_vectors != 7 ) + { + FT_ERROR(( "t1_decoder_parse_charstrings:" + " unexpected flex end\n" )); + goto Syntax_Error; + } + + /* the two `results' are popped by the following setcurrentpoint */ + known_othersubr_result_cnt = 2; + break; + + case 3: /* change hints */ + if ( arg_cnt != 1 ) + goto Unexpected_OtherSubr; + + known_othersubr_result_cnt = 1; + + if ( hinter ) + hinter->reset( hinter->hints, builder->current->n_points ); + break; + + case 12: + case 13: + /* counter control hints, clear stack */ + top = decoder->stack; + break; + + case 14: + case 15: + case 16: + case 17: + case 18: /* multiple masters */ + { + PS_Blend blend = decoder->blend; + FT_UInt num_points, nn, mm; + FT_Long* delta; + FT_Long* values; + + + if ( !blend ) + { + FT_ERROR(( "t1_decoder_parse_charstrings:" + " unexpected multiple masters operator\n" )); + goto Syntax_Error; + } + + num_points = (FT_UInt)subr_no - 13 + ( subr_no == 18 ); + if ( arg_cnt != (FT_Int)( num_points * blend->num_designs ) ) + { + FT_ERROR(( "t1_decoder_parse_charstrings:" + " incorrect number of multiple masters arguments\n" )); + goto Syntax_Error; + } + + /* we want to compute: */ + /* */ + /* a0*w0 + a1*w1 + ... + ak*wk */ + /* */ + /* but we only have the a0, a1-a0, a2-a0, .. ak-a0 */ + /* however, given that w0 + w1 + ... + wk == 1, we can */ + /* rewrite it easily as: */ + /* */ + /* a0 + (a1-a0)*w1 + (a2-a0)*w2 + .. + (ak-a0)*wk */ + /* */ + /* where k == num_designs-1 */ + /* */ + /* I guess that's why it's written in this `compact' */ + /* form. */ + /* */ + delta = top + num_points; + values = top; + for ( nn = 0; nn < num_points; nn++ ) + { + FT_Long tmp = values[0]; + + + for ( mm = 1; mm < blend->num_designs; mm++ ) + tmp += FT_MulFix( *delta++, blend->weight_vector[mm] ); + + *values++ = tmp; + } + + known_othersubr_result_cnt = num_points; + break; + } + + case 19: + /* <idx> 1 19 callothersubr */ + /* => replace elements starting from index cvi( <idx> ) */ + /* of BuildCharArray with WeightVector */ + { + FT_Int idx; + PS_Blend blend = decoder->blend; + + + if ( arg_cnt != 1 || blend == NULL ) + goto Unexpected_OtherSubr; + + idx = (FT_Int)( top[0] >> 16 ); + + if ( idx < 0 || + idx + blend->num_designs > decoder->len_buildchar ) + goto Unexpected_OtherSubr; + + ft_memcpy( &decoder->buildchar[idx], + blend->weight_vector, + blend->num_designs * + sizeof( blend->weight_vector[0] ) ); + } + break; + + case 20: + /* <arg1> <arg2> 2 20 callothersubr pop */ + /* ==> push <arg1> + <arg2> onto T1 stack */ + if ( arg_cnt != 2 ) + goto Unexpected_OtherSubr; + + top[0] += top[1]; /* XXX (over|under)flow */ + + known_othersubr_result_cnt = 1; + break; + + case 21: + /* <arg1> <arg2> 2 21 callothersubr pop */ + /* ==> push <arg1> - <arg2> onto T1 stack */ + if ( arg_cnt != 2 ) + goto Unexpected_OtherSubr; + + top[0] -= top[1]; /* XXX (over|under)flow */ + + known_othersubr_result_cnt = 1; + break; + + case 22: + /* <arg1> <arg2> 2 22 callothersubr pop */ + /* ==> push <arg1> * <arg2> onto T1 stack */ + if ( arg_cnt != 2 ) + goto Unexpected_OtherSubr; + + top[0] = FT_MulFix( top[0], top[1] ); + + known_othersubr_result_cnt = 1; + break; + + case 23: + /* <arg1> <arg2> 2 23 callothersubr pop */ + /* ==> push <arg1> / <arg2> onto T1 stack */ + if ( arg_cnt != 2 || top[1] == 0 ) + goto Unexpected_OtherSubr; + + top[0] = FT_DivFix( top[0], top[1] ); + + known_othersubr_result_cnt = 1; + break; + + case 24: + /* <val> <idx> 2 24 callothersubr */ + /* ==> set BuildCharArray[cvi( <idx> )] = <val> */ + { + FT_Int idx; + PS_Blend blend = decoder->blend; + + + if ( arg_cnt != 2 || blend == NULL ) + goto Unexpected_OtherSubr; + + idx = (FT_Int)( top[1] >> 16 ); + + if ( idx < 0 || (FT_UInt) idx >= decoder->len_buildchar ) + goto Unexpected_OtherSubr; + + decoder->buildchar[idx] = top[0]; + } + break; + + case 25: + /* <idx> 1 25 callothersubr pop */ + /* ==> push BuildCharArray[cvi( idx )] */ + /* onto T1 stack */ + { + FT_Int idx; + PS_Blend blend = decoder->blend; + + + if ( arg_cnt != 1 || blend == NULL ) + goto Unexpected_OtherSubr; + + idx = (FT_Int)( top[0] >> 16 ); + + if ( idx < 0 || (FT_UInt) idx >= decoder->len_buildchar ) + goto Unexpected_OtherSubr; + + top[0] = decoder->buildchar[idx]; + } + + known_othersubr_result_cnt = 1; + break; + +#if 0 + case 26: + /* <val> mark <idx> ==> set BuildCharArray[cvi( <idx> )] = <val>, */ + /* leave mark on T1 stack */ + /* <val> <idx> ==> set BuildCharArray[cvi( <idx> )] = <val> */ + XXX which routine has left its mark on the (PostScript) stack?; + break; +#endif + + case 27: + /* <res1> <res2> <val1> <val2> 4 27 callothersubr pop */ + /* ==> push <res1> onto T1 stack if <val1> <= <val2>, */ + /* otherwise push <res2> */ + if ( arg_cnt != 4 ) + goto Unexpected_OtherSubr; + + if ( top[2] > top[3] ) + top[0] = top[1]; + + known_othersubr_result_cnt = 1; + break; + + case 28: + /* 0 28 callothersubr pop */ + /* => push random value from interval [0, 1) onto stack */ + if ( arg_cnt != 0 ) + goto Unexpected_OtherSubr; + + { + FT_Fixed Rand; + + + Rand = seed; + if ( Rand >= 0x8000L ) + Rand++; + + top[0] = Rand; + + seed = FT_MulFix( seed, 0x10000L - seed ); + if ( seed == 0 ) + seed += 0x2873; + } + + known_othersubr_result_cnt = 1; + break; + + default: + FT_ERROR(( "t1_decoder_parse_charstrings:" + " unknown othersubr [%d %d], wish me luck\n", + arg_cnt, subr_no )); + unknown_othersubr_result_cnt = arg_cnt; + break; + + Unexpected_OtherSubr: + FT_ERROR(( "t1_decoder_parse_charstrings:" + " invalid othersubr [%d %d]\n", arg_cnt, subr_no )); + goto Syntax_Error; + } + + top += known_othersubr_result_cnt; + + decoder->top = top; + } + else /* general operator */ + { + FT_Int num_args = t1_args_count[op]; + + + FT_ASSERT( num_args >= 0 ); + + if ( top - decoder->stack < num_args ) + goto Stack_Underflow; + + /* XXX Operators usually take their operands from the */ + /* bottom of the stack, i.e., the operands are */ + /* decoder->stack[0], ..., decoder->stack[num_args - 1]; */ + /* only div, callsubr, and callothersubr are different. */ + /* In practice it doesn't matter (?). */ + +#ifdef FT_DEBUG_LEVEL_TRACE + + switch ( op ) + { + case op_callsubr: + case op_div: + case op_callothersubr: + case op_pop: + case op_return: + break; + + default: + if ( top - decoder->stack != num_args ) + FT_TRACE0(( "t1_decoder_parse_charstrings:" + " too much operands on the stack" + " (seen %d, expected %d)\n", + top - decoder->stack, num_args )); + break; + } + +#endif /* FT_DEBUG_LEVEL_TRACE */ + + top -= num_args; + + switch ( op ) + { + case op_endchar: + FT_TRACE4(( " endchar\n" )); + + close_contour( builder ); + + /* close hints recording session */ + if ( hinter ) + { + if ( hinter->close( hinter->hints, builder->current->n_points ) ) + goto Syntax_Error; + + /* apply hints to the loaded glyph outline now */ + hinter->apply( hinter->hints, + builder->current, + (PSH_Globals)builder->hints_globals, + decoder->hint_mode ); + } + + /* add current outline to the glyph slot */ + FT_GlyphLoader_Add( builder->loader ); + + /* the compiler should optimize away this empty loop but ... */ + +#ifdef FT_DEBUG_LEVEL_TRACE + + if ( decoder->len_buildchar > 0 ) + { + FT_UInt i; + + + FT_TRACE4(( "BuildCharArray = [ " )); + + for ( i = 0; i < decoder->len_buildchar; ++i ) + FT_TRACE4(( "%d ", decoder->buildchar[ i ] )); + + FT_TRACE4(( "]\n" )); + } + +#endif /* FT_DEBUG_LEVEL_TRACE */ + + FT_TRACE4(( "\n" )); + + /* return now! */ + return PSaux_Err_Ok; + + case op_hsbw: + FT_TRACE4(( " hsbw" )); + + builder->parse_state = T1_Parse_Have_Width; + + builder->left_bearing.x += top[0]; + builder->advance.x = top[1]; + builder->advance.y = 0; + + orig_x = x = builder->pos_x + top[0]; + orig_y = y = builder->pos_y; + + FT_UNUSED( orig_y ); + + /* the `metrics_only' indicates that we only want to compute */ + /* the glyph's metrics (lsb + advance width), not load the */ + /* rest of it; so exit immediately */ + if ( builder->metrics_only ) + return PSaux_Err_Ok; + + break; + + case op_seac: + return t1operator_seac( decoder, + top[0], + top[1], + top[2], + (FT_Int)( top[3] >> 16 ), + (FT_Int)( top[4] >> 16 ) ); + + case op_sbw: + FT_TRACE4(( " sbw" )); + + builder->parse_state = T1_Parse_Have_Width; + + builder->left_bearing.x += top[0]; + builder->left_bearing.y += top[1]; + builder->advance.x = top[2]; + builder->advance.y = top[3]; + + x = builder->pos_x + top[0]; + y = builder->pos_y + top[1]; + + /* the `metrics_only' indicates that we only want to compute */ + /* the glyph's metrics (lsb + advance width), not load the */ + /* rest of it; so exit immediately */ + if ( builder->metrics_only ) + return PSaux_Err_Ok; + + break; + + case op_closepath: + FT_TRACE4(( " closepath" )); + + /* if there is no path, `closepath' is a no-op */ + if ( builder->parse_state == T1_Parse_Have_Path || + builder->parse_state == T1_Parse_Have_Moveto ) + close_contour( builder ); + + builder->parse_state = T1_Parse_Have_Width; + break; + + case op_hlineto: + FT_TRACE4(( " hlineto" )); + + if ( start_point( builder, x, y ) ) + goto Fail; + + x += top[0]; + goto Add_Line; + + case op_hmoveto: + FT_TRACE4(( " hmoveto" )); + + x += top[0]; + if ( !decoder->flex_state ) + { + if ( builder->parse_state == T1_Parse_Start ) + goto Syntax_Error; + builder->parse_state = T1_Parse_Have_Moveto; + } + break; + + case op_hvcurveto: + FT_TRACE4(( " hvcurveto" )); + + if ( start_point( builder, x, y ) || + check_points( builder, 3 ) ) + goto Fail; + + x += top[0]; + add_point( builder, x, y, 0 ); + x += top[1]; + y += top[2]; + add_point( builder, x, y, 0 ); + y += top[3]; + add_point( builder, x, y, 1 ); + break; + + case op_rlineto: + FT_TRACE4(( " rlineto" )); + + if ( start_point( builder, x, y ) ) + goto Fail; + + x += top[0]; + y += top[1]; + + Add_Line: + if ( add_point1( builder, x, y ) ) + goto Fail; + break; + + case op_rmoveto: + FT_TRACE4(( " rmoveto" )); + + x += top[0]; + y += top[1]; + if ( !decoder->flex_state ) + { + if ( builder->parse_state == T1_Parse_Start ) + goto Syntax_Error; + builder->parse_state = T1_Parse_Have_Moveto; + } + break; + + case op_rrcurveto: + FT_TRACE4(( " rrcurveto" )); + + if ( start_point( builder, x, y ) || + check_points( builder, 3 ) ) + goto Fail; + + x += top[0]; + y += top[1]; + add_point( builder, x, y, 0 ); + + x += top[2]; + y += top[3]; + add_point( builder, x, y, 0 ); + + x += top[4]; + y += top[5]; + add_point( builder, x, y, 1 ); + break; + + case op_vhcurveto: + FT_TRACE4(( " vhcurveto" )); + + if ( start_point( builder, x, y ) || + check_points( builder, 3 ) ) + goto Fail; + + y += top[0]; + add_point( builder, x, y, 0 ); + x += top[1]; + y += top[2]; + add_point( builder, x, y, 0 ); + x += top[3]; + add_point( builder, x, y, 1 ); + break; + + case op_vlineto: + FT_TRACE4(( " vlineto" )); + + if ( start_point( builder, x, y ) ) + goto Fail; + + y += top[0]; + goto Add_Line; + + case op_vmoveto: + FT_TRACE4(( " vmoveto" )); + + y += top[0]; + if ( !decoder->flex_state ) + { + if ( builder->parse_state == T1_Parse_Start ) + goto Syntax_Error; + builder->parse_state = T1_Parse_Have_Moveto; + } + break; + + case op_div: + FT_TRACE4(( " div" )); + + /* if `large_int' is set, we divide unscaled numbers; */ + /* otherwise, we divide numbers in 16.16 format -- */ + /* in both cases, it is the same operation */ + *top = FT_DivFix( top[0], top[1] ); + ++top; + + large_int = FALSE; + break; + + case op_callsubr: + { + FT_Int idx; + + + FT_TRACE4(( " callsubr" )); + + idx = (FT_Int)( top[0] >> 16 ); + if ( idx < 0 || idx >= (FT_Int)decoder->num_subrs ) + { + FT_ERROR(( "t1_decoder_parse_charstrings:" + " invalid subrs index\n" )); + goto Syntax_Error; + } + + if ( zone - decoder->zones >= T1_MAX_SUBRS_CALLS ) + { + FT_ERROR(( "t1_decoder_parse_charstrings:" + " too many nested subrs\n" )); + goto Syntax_Error; + } + + zone->cursor = ip; /* save current instruction pointer */ + + zone++; + + /* The Type 1 driver stores subroutines without the seed bytes. */ + /* The CID driver stores subroutines with seed bytes. This */ + /* case is taken care of when decoder->subrs_len == 0. */ + zone->base = decoder->subrs[idx]; + + if ( decoder->subrs_len ) + zone->limit = zone->base + decoder->subrs_len[idx]; + else + { + /* We are using subroutines from a CID font. We must adjust */ + /* for the seed bytes. */ + zone->base += ( decoder->lenIV >= 0 ? decoder->lenIV : 0 ); + zone->limit = decoder->subrs[idx + 1]; + } + + zone->cursor = zone->base; + + if ( !zone->base ) + { + FT_ERROR(( "t1_decoder_parse_charstrings:" + " invoking empty subrs\n" )); + goto Syntax_Error; + } + + decoder->zone = zone; + ip = zone->base; + limit = zone->limit; + break; + } + + case op_pop: + FT_TRACE4(( " pop" )); + + if ( known_othersubr_result_cnt > 0 ) + { + known_othersubr_result_cnt--; + /* ignore, we pushed the operands ourselves */ + break; + } + + if ( unknown_othersubr_result_cnt == 0 ) + { + FT_ERROR(( "t1_decoder_parse_charstrings:" + " no more operands for othersubr\n" )); + goto Syntax_Error; + } + + unknown_othersubr_result_cnt--; + top++; /* `push' the operand to callothersubr onto the stack */ + break; + + case op_return: + FT_TRACE4(( " return" )); + + if ( zone <= decoder->zones ) + { + FT_ERROR(( "t1_decoder_parse_charstrings:" + " unexpected return\n" )); + goto Syntax_Error; + } + + zone--; + ip = zone->cursor; + limit = zone->limit; + decoder->zone = zone; + break; + + case op_dotsection: + FT_TRACE4(( " dotsection" )); + + break; + + case op_hstem: + FT_TRACE4(( " hstem" )); + + /* record horizontal hint */ + if ( hinter ) + { + /* top[0] += builder->left_bearing.y; */ + hinter->stem( hinter->hints, 1, top ); + } + break; + + case op_hstem3: + FT_TRACE4(( " hstem3" )); + + /* record horizontal counter-controlled hints */ + if ( hinter ) + hinter->stem3( hinter->hints, 1, top ); + break; + + case op_vstem: + FT_TRACE4(( " vstem" )); + + /* record vertical hint */ + if ( hinter ) + { + top[0] += orig_x; + hinter->stem( hinter->hints, 0, top ); + } + break; + + case op_vstem3: + FT_TRACE4(( " vstem3" )); + + /* record vertical counter-controlled hints */ + if ( hinter ) + { + FT_Pos dx = orig_x; + + + top[0] += dx; + top[2] += dx; + top[4] += dx; + hinter->stem3( hinter->hints, 0, top ); + } + break; + + case op_setcurrentpoint: + FT_TRACE4(( " setcurrentpoint" )); + + /* From the T1 specs, section 6.4: */ + /* */ + /* The setcurrentpoint command is used only in */ + /* conjunction with results from OtherSubrs procedures. */ + + /* known_othersubr_result_cnt != 0 is already handled above */ + if ( decoder->flex_state != 1 ) + { + FT_ERROR(( "t1_decoder_parse_charstrings:" + " unexpected `setcurrentpoint'\n" )); + goto Syntax_Error; + } + else + decoder->flex_state = 0; + break; + + case op_unknown15: + FT_TRACE4(( " opcode_15" )); + /* nothing to do except to pop the two arguments */ + break; + + default: + FT_ERROR(( "t1_decoder_parse_charstrings:" + " unhandled opcode %d\n", op )); + goto Syntax_Error; + } + + /* XXX Operators usually clear the operand stack; */ + /* only div, callsubr, callothersubr, pop, and */ + /* return are different. */ + /* In practice it doesn't matter (?). */ + + decoder->top = top; + +#ifdef FT_DEBUG_LEVEL_TRACE + FT_TRACE4(( "\n" )); + bol = TRUE; +#endif + + } /* general operator processing */ + + } /* while ip < limit */ + + FT_TRACE4(( "..end..\n\n" )); + + Fail: + return error; + + Syntax_Error: + return PSaux_Err_Syntax_Error; + + Stack_Underflow: + return PSaux_Err_Stack_Underflow; + } + + + /* parse a single Type 1 glyph */ + FT_LOCAL_DEF( FT_Error ) + t1_decoder_parse_glyph( T1_Decoder decoder, + FT_UInt glyph ) + { + return decoder->parse_callback( decoder, glyph ); + } + + + /* initialize T1 decoder */ + FT_LOCAL_DEF( FT_Error ) + t1_decoder_init( T1_Decoder decoder, + FT_Face face, + FT_Size size, + FT_GlyphSlot slot, + FT_Byte** glyph_names, + PS_Blend blend, + FT_Bool hinting, + FT_Render_Mode hint_mode, + T1_Decoder_Callback parse_callback ) + { + FT_MEM_ZERO( decoder, sizeof ( *decoder ) ); + + /* retrieve PSNames interface from list of current modules */ + { + FT_Service_PsCMaps psnames = 0; + + + FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); + if ( !psnames ) + { + FT_ERROR(( "t1_decoder_init:" + " the `psnames' module is not available\n" )); + return PSaux_Err_Unimplemented_Feature; + } + + decoder->psnames = psnames; + } + + t1_builder_init( &decoder->builder, face, size, slot, hinting ); + + /* decoder->buildchar and decoder->len_buildchar have to be */ + /* initialized by the caller since we cannot know the length */ + /* of the BuildCharArray */ + + decoder->num_glyphs = (FT_UInt)face->num_glyphs; + decoder->glyph_names = glyph_names; + decoder->hint_mode = hint_mode; + decoder->blend = blend; + decoder->parse_callback = parse_callback; + + decoder->funcs = t1_decoder_funcs; + + return PSaux_Err_Ok; + } + + + /* finalize T1 decoder */ + FT_LOCAL_DEF( void ) + t1_decoder_done( T1_Decoder decoder ) + { + t1_builder_done( &decoder->builder ); + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/psaux/t1decode.h b/mod/pub.mod/freetype.mod/src/psaux/t1decode.h new file mode 100644 index 0000000..00728db --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/psaux/t1decode.h @@ -0,0 +1,64 @@ +/***************************************************************************/ +/* */ +/* t1decode.h */ +/* */ +/* PostScript Type 1 decoding routines (specification). */ +/* */ +/* Copyright 2000-2001, 2002, 2003 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __T1DECODE_H__ +#define __T1DECODE_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_POSTSCRIPT_AUX_H +#include FT_INTERNAL_TYPE1_TYPES_H + + +FT_BEGIN_HEADER + + + FT_CALLBACK_TABLE + const T1_Decoder_FuncsRec t1_decoder_funcs; + + + FT_LOCAL( FT_Error ) + t1_decoder_parse_glyph( T1_Decoder decoder, + FT_UInt glyph_index ); + + FT_LOCAL( FT_Error ) + t1_decoder_parse_charstrings( T1_Decoder decoder, + FT_Byte* base, + FT_UInt len ); + + FT_LOCAL( FT_Error ) + t1_decoder_init( T1_Decoder decoder, + FT_Face face, + FT_Size size, + FT_GlyphSlot slot, + FT_Byte** glyph_names, + PS_Blend blend, + FT_Bool hinting, + FT_Render_Mode hint_mode, + T1_Decoder_Callback parse_glyph ); + + FT_LOCAL( void ) + t1_decoder_done( T1_Decoder decoder ); + + +FT_END_HEADER + +#endif /* __T1DECODE_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/pshinter/pshalgo.c b/mod/pub.mod/freetype.mod/src/pshinter/pshalgo.c new file mode 100644 index 0000000..417dcee --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/pshinter/pshalgo.c @@ -0,0 +1,2302 @@ +/***************************************************************************/ +/* */ +/* pshalgo.c */ +/* */ +/* PostScript hinting algorithm (body). */ +/* */ +/* Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used */ +/* modified and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_CALC_H +#include "pshalgo.h" + +#include "pshnterr.h" + + +#undef FT_COMPONENT +#define FT_COMPONENT trace_pshalgo2 + + +#ifdef DEBUG_HINTER + PSH_Hint_Table ps_debug_hint_table = 0; + PSH_HintFunc ps_debug_hint_func = 0; + PSH_Glyph ps_debug_glyph = 0; +#endif + + +#define COMPUTE_INFLEXS /* compute inflection points to optimize `S' */ + /* and similar glyphs */ +#define STRONGER /* slightly increase the contrast of smooth */ + /* hinting */ + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** BASIC HINTS RECORDINGS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* return true if two stem hints overlap */ + static FT_Int + psh_hint_overlap( PSH_Hint hint1, + PSH_Hint hint2 ) + { + return hint1->org_pos + hint1->org_len >= hint2->org_pos && + hint2->org_pos + hint2->org_len >= hint1->org_pos; + } + + + /* destroy hints table */ + static void + psh_hint_table_done( PSH_Hint_Table table, + FT_Memory memory ) + { + FT_FREE( table->zones ); + table->num_zones = 0; + table->zone = 0; + + FT_FREE( table->sort ); + FT_FREE( table->hints ); + table->num_hints = 0; + table->max_hints = 0; + table->sort_global = 0; + } + + + /* deactivate all hints in a table */ + static void + psh_hint_table_deactivate( PSH_Hint_Table table ) + { + FT_UInt count = table->max_hints; + PSH_Hint hint = table->hints; + + + for ( ; count > 0; count--, hint++ ) + { + psh_hint_deactivate( hint ); + hint->order = -1; + } + } + + + /* internal function to record a new hint */ + static void + psh_hint_table_record( PSH_Hint_Table table, + FT_UInt idx ) + { + PSH_Hint hint = table->hints + idx; + + + if ( idx >= table->max_hints ) + { + FT_TRACE0(( "psh_hint_table_record: invalid hint index %d\n", idx )); + return; + } + + /* ignore active hints */ + if ( psh_hint_is_active( hint ) ) + return; + + psh_hint_activate( hint ); + + /* now scan the current active hint set to check */ + /* whether `hint' overlaps with another hint */ + { + PSH_Hint* sorted = table->sort_global; + FT_UInt count = table->num_hints; + PSH_Hint hint2; + + + hint->parent = 0; + for ( ; count > 0; count--, sorted++ ) + { + hint2 = sorted[0]; + + if ( psh_hint_overlap( hint, hint2 ) ) + { + hint->parent = hint2; + break; + } + } + } + + if ( table->num_hints < table->max_hints ) + table->sort_global[table->num_hints++] = hint; + else + FT_TRACE0(( "psh_hint_table_record: too many sorted hints! BUG!\n" )); + } + + + static void + psh_hint_table_record_mask( PSH_Hint_Table table, + PS_Mask hint_mask ) + { + FT_Int mask = 0, val = 0; + FT_Byte* cursor = hint_mask->bytes; + FT_UInt idx, limit; + + + limit = hint_mask->num_bits; + + for ( idx = 0; idx < limit; idx++ ) + { + if ( mask == 0 ) + { + val = *cursor++; + mask = 0x80; + } + + if ( val & mask ) + psh_hint_table_record( table, idx ); + + mask >>= 1; + } + } + + + /* create hints table */ + static FT_Error + psh_hint_table_init( PSH_Hint_Table table, + PS_Hint_Table hints, + PS_Mask_Table hint_masks, + PS_Mask_Table counter_masks, + FT_Memory memory ) + { + FT_UInt count; + FT_Error error; + + FT_UNUSED( counter_masks ); + + + count = hints->num_hints; + + /* allocate our tables */ + if ( FT_NEW_ARRAY( table->sort, 2 * count ) || + FT_NEW_ARRAY( table->hints, count ) || + FT_NEW_ARRAY( table->zones, 2 * count + 1 ) ) + goto Exit; + + table->max_hints = count; + table->sort_global = table->sort + count; + table->num_hints = 0; + table->num_zones = 0; + table->zone = 0; + + /* initialize the `table->hints' array */ + { + PSH_Hint write = table->hints; + PS_Hint read = hints->hints; + + + for ( ; count > 0; count--, write++, read++ ) + { + write->org_pos = read->pos; + write->org_len = read->len; + write->flags = read->flags; + } + } + + /* we now need to determine the initial `parent' stems; first */ + /* activate the hints that are given by the initial hint masks */ + if ( hint_masks ) + { + PS_Mask mask = hint_masks->masks; + + + count = hint_masks->num_masks; + table->hint_masks = hint_masks; + + for ( ; count > 0; count--, mask++ ) + psh_hint_table_record_mask( table, mask ); + } + + /* finally, do a linear parse in case some hints were left alone */ + if ( table->num_hints != table->max_hints ) + { + FT_UInt idx; + + + FT_TRACE0(( "psh_hint_table_init: missing/incorrect hint masks\n" )); + + count = table->max_hints; + for ( idx = 0; idx < count; idx++ ) + psh_hint_table_record( table, idx ); + } + + Exit: + return error; + } + + + static void + psh_hint_table_activate_mask( PSH_Hint_Table table, + PS_Mask hint_mask ) + { + FT_Int mask = 0, val = 0; + FT_Byte* cursor = hint_mask->bytes; + FT_UInt idx, limit, count; + + + limit = hint_mask->num_bits; + count = 0; + + psh_hint_table_deactivate( table ); + + for ( idx = 0; idx < limit; idx++ ) + { + if ( mask == 0 ) + { + val = *cursor++; + mask = 0x80; + } + + if ( val & mask ) + { + PSH_Hint hint = &table->hints[idx]; + + + if ( !psh_hint_is_active( hint ) ) + { + FT_UInt count2; + +#if 0 + PSH_Hint* sort = table->sort; + PSH_Hint hint2; + + + for ( count2 = count; count2 > 0; count2--, sort++ ) + { + hint2 = sort[0]; + if ( psh_hint_overlap( hint, hint2 ) ) + FT_TRACE0(( "psh_hint_table_activate_mask:" + " found overlapping hints\n" )) + } +#else + count2 = 0; +#endif + + if ( count2 == 0 ) + { + psh_hint_activate( hint ); + if ( count < table->max_hints ) + table->sort[count++] = hint; + else + FT_TRACE0(( "psh_hint_tableactivate_mask:" + " too many active hints\n" )); + } + } + } + + mask >>= 1; + } + table->num_hints = count; + + /* now, sort the hints; they are guaranteed to not overlap */ + /* so we can compare their "org_pos" field directly */ + { + FT_Int i1, i2; + PSH_Hint hint1, hint2; + PSH_Hint* sort = table->sort; + + + /* a simple bubble sort will do, since in 99% of cases, the hints */ + /* will be already sorted -- and the sort will be linear */ + for ( i1 = 1; i1 < (FT_Int)count; i1++ ) + { + hint1 = sort[i1]; + for ( i2 = i1 - 1; i2 >= 0; i2-- ) + { + hint2 = sort[i2]; + + if ( hint2->org_pos < hint1->org_pos ) + break; + + sort[i2 + 1] = hint2; + sort[i2] = hint1; + } + } + } + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** HINTS GRID-FITTING AND OPTIMIZATION *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + +#if 1 + static FT_Pos + psh_dimension_quantize_len( PSH_Dimension dim, + FT_Pos len, + FT_Bool do_snapping ) + { + if ( len <= 64 ) + len = 64; + else + { + FT_Pos delta = len - dim->stdw.widths[0].cur; + + + if ( delta < 0 ) + delta = -delta; + + if ( delta < 40 ) + { + len = dim->stdw.widths[0].cur; + if ( len < 48 ) + len = 48; + } + + if ( len < 3 * 64 ) + { + delta = ( len & 63 ); + len &= -64; + + if ( delta < 10 ) + len += delta; + + else if ( delta < 32 ) + len += 10; + + else if ( delta < 54 ) + len += 54; + + else + len += delta; + } + else + len = FT_PIX_ROUND( len ); + } + + if ( do_snapping ) + len = FT_PIX_ROUND( len ); + + return len; + } +#endif /* 0 */ + + +#ifdef DEBUG_HINTER + + static void + ps_simple_scale( PSH_Hint_Table table, + FT_Fixed scale, + FT_Fixed delta, + FT_Int dimension ) + { + PSH_Hint hint; + FT_UInt count; + + + for ( count = 0; count < table->max_hints; count++ ) + { + hint = table->hints + count; + + hint->cur_pos = FT_MulFix( hint->org_pos, scale ) + delta; + hint->cur_len = FT_MulFix( hint->org_len, scale ); + + if ( ps_debug_hint_func ) + ps_debug_hint_func( hint, dimension ); + } + } + +#endif /* DEBUG_HINTER */ + + + static FT_Fixed + psh_hint_snap_stem_side_delta( FT_Fixed pos, + FT_Fixed len ) + { + FT_Fixed delta1 = FT_PIX_ROUND( pos ) - pos; + FT_Fixed delta2 = FT_PIX_ROUND( pos + len ) - pos - len; + + + if ( FT_ABS( delta1 ) <= FT_ABS( delta2 ) ) + return delta1; + else + return delta2; + } + + + static void + psh_hint_align( PSH_Hint hint, + PSH_Globals globals, + FT_Int dimension, + PSH_Glyph glyph ) + { + PSH_Dimension dim = &globals->dimension[dimension]; + FT_Fixed scale = dim->scale_mult; + FT_Fixed delta = dim->scale_delta; + + + if ( !psh_hint_is_fitted( hint ) ) + { + FT_Pos pos = FT_MulFix( hint->org_pos, scale ) + delta; + FT_Pos len = FT_MulFix( hint->org_len, scale ); + + FT_Int do_snapping; + FT_Pos fit_len; + PSH_AlignmentRec align; + + + /* ignore stem alignments when requested through the hint flags */ + if ( ( dimension == 0 && !glyph->do_horz_hints ) || + ( dimension == 1 && !glyph->do_vert_hints ) ) + { + hint->cur_pos = pos; + hint->cur_len = len; + + psh_hint_set_fitted( hint ); + return; + } + + /* perform stem snapping when requested - this is necessary + * for monochrome and LCD hinting modes only + */ + do_snapping = ( dimension == 0 && glyph->do_horz_snapping ) || + ( dimension == 1 && glyph->do_vert_snapping ); + + hint->cur_len = fit_len = len; + + /* check blue zones for horizontal stems */ + align.align = PSH_BLUE_ALIGN_NONE; + align.align_bot = align.align_top = 0; + + if ( dimension == 1 ) + psh_blues_snap_stem( &globals->blues, + hint->org_pos + hint->org_len, + hint->org_pos, + &align ); + + switch ( align.align ) + { + case PSH_BLUE_ALIGN_TOP: + /* the top of the stem is aligned against a blue zone */ + hint->cur_pos = align.align_top - fit_len; + break; + + case PSH_BLUE_ALIGN_BOT: + /* the bottom of the stem is aligned against a blue zone */ + hint->cur_pos = align.align_bot; + break; + + case PSH_BLUE_ALIGN_TOP | PSH_BLUE_ALIGN_BOT: + /* both edges of the stem are aligned against blue zones */ + hint->cur_pos = align.align_bot; + hint->cur_len = align.align_top - align.align_bot; + break; + + default: + { + PSH_Hint parent = hint->parent; + + + if ( parent ) + { + FT_Pos par_org_center, par_cur_center; + FT_Pos cur_org_center, cur_delta; + + + /* ensure that parent is already fitted */ + if ( !psh_hint_is_fitted( parent ) ) + psh_hint_align( parent, globals, dimension, glyph ); + + /* keep original relation between hints, this is, use the */ + /* scaled distance between the centers of the hints to */ + /* compute the new position */ + par_org_center = parent->org_pos + ( parent->org_len >> 1 ); + par_cur_center = parent->cur_pos + ( parent->cur_len >> 1 ); + cur_org_center = hint->org_pos + ( hint->org_len >> 1 ); + + cur_delta = FT_MulFix( cur_org_center - par_org_center, scale ); + pos = par_cur_center + cur_delta - ( len >> 1 ); + } + + hint->cur_pos = pos; + hint->cur_len = fit_len; + + /* Stem adjustment tries to snap stem widths to standard + * ones. This is important to prevent unpleasant rounding + * artefacts. + */ + if ( glyph->do_stem_adjust ) + { + if ( len <= 64 ) + { + /* the stem is less than one pixel; we will center it + * around the nearest pixel center + */ + if ( len >= 32 ) + { + /* This is a special case where we also widen the stem + * and align it to the pixel grid. + * + * stem_center = pos + (len/2) + * nearest_pixel_center = FT_ROUND(stem_center-32)+32 + * new_pos = nearest_pixel_center-32 + * = FT_ROUND(stem_center-32) + * = FT_FLOOR(stem_center-32+32) + * = FT_FLOOR(stem_center) + * new_len = 64 + */ + pos = FT_PIX_FLOOR( pos + ( len >> 1 ) ); + len = 64; + } + else if ( len > 0 ) + { + /* This is a very small stem; we simply align it to the + * pixel grid, trying to find the minimal displacement. + * + * left = pos + * right = pos + len + * left_nearest_edge = ROUND(pos) + * right_nearest_edge = ROUND(right) + * + * if ( ABS(left_nearest_edge - left) <= + * ABS(right_nearest_edge - right) ) + * new_pos = left + * else + * new_pos = right + */ + FT_Pos left_nearest = FT_PIX_ROUND( pos ); + FT_Pos right_nearest = FT_PIX_ROUND( pos + len ); + FT_Pos left_disp = left_nearest - pos; + FT_Pos right_disp = right_nearest - ( pos + len ); + + + if ( left_disp < 0 ) + left_disp = -left_disp; + if ( right_disp < 0 ) + right_disp = -right_disp; + if ( left_disp <= right_disp ) + pos = left_nearest; + else + pos = right_nearest; + } + else + { + /* this is a ghost stem; we simply round it */ + pos = FT_PIX_ROUND( pos ); + } + } + else + { + len = psh_dimension_quantize_len( dim, len, 0 ); + } + } + + /* now that we have a good hinted stem width, try to position */ + /* the stem along a pixel grid integer coordinate */ + hint->cur_pos = pos + psh_hint_snap_stem_side_delta( pos, len ); + hint->cur_len = len; + } + } + + if ( do_snapping ) + { + pos = hint->cur_pos; + len = hint->cur_len; + + if ( len < 64 ) + len = 64; + else + len = FT_PIX_ROUND( len ); + + switch ( align.align ) + { + case PSH_BLUE_ALIGN_TOP: + hint->cur_pos = align.align_top - len; + hint->cur_len = len; + break; + + case PSH_BLUE_ALIGN_BOT: + hint->cur_len = len; + break; + + case PSH_BLUE_ALIGN_BOT | PSH_BLUE_ALIGN_TOP: + /* don't touch */ + break; + + + default: + hint->cur_len = len; + if ( len & 64 ) + pos = FT_PIX_FLOOR( pos + ( len >> 1 ) ) + 32; + else + pos = FT_PIX_ROUND( pos + ( len >> 1 ) ); + + hint->cur_pos = pos - ( len >> 1 ); + hint->cur_len = len; + } + } + + psh_hint_set_fitted( hint ); + +#ifdef DEBUG_HINTER + if ( ps_debug_hint_func ) + ps_debug_hint_func( hint, dimension ); +#endif + } + } + + +#if 0 /* not used for now, experimental */ + + /* + * A variant to perform "light" hinting (i.e. FT_RENDER_MODE_LIGHT) + * of stems + */ + static void + psh_hint_align_light( PSH_Hint hint, + PSH_Globals globals, + FT_Int dimension, + PSH_Glyph glyph ) + { + PSH_Dimension dim = &globals->dimension[dimension]; + FT_Fixed scale = dim->scale_mult; + FT_Fixed delta = dim->scale_delta; + + + if ( !psh_hint_is_fitted( hint ) ) + { + FT_Pos pos = FT_MulFix( hint->org_pos, scale ) + delta; + FT_Pos len = FT_MulFix( hint->org_len, scale ); + + FT_Pos fit_len; + + PSH_AlignmentRec align; + + + /* ignore stem alignments when requested through the hint flags */ + if ( ( dimension == 0 && !glyph->do_horz_hints ) || + ( dimension == 1 && !glyph->do_vert_hints ) ) + { + hint->cur_pos = pos; + hint->cur_len = len; + + psh_hint_set_fitted( hint ); + return; + } + + fit_len = len; + + hint->cur_len = fit_len; + + /* check blue zones for horizontal stems */ + align.align = PSH_BLUE_ALIGN_NONE; + align.align_bot = align.align_top = 0; + + if ( dimension == 1 ) + psh_blues_snap_stem( &globals->blues, + hint->org_pos + hint->org_len, + hint->org_pos, + &align ); + + switch ( align.align ) + { + case PSH_BLUE_ALIGN_TOP: + /* the top of the stem is aligned against a blue zone */ + hint->cur_pos = align.align_top - fit_len; + break; + + case PSH_BLUE_ALIGN_BOT: + /* the bottom of the stem is aligned against a blue zone */ + hint->cur_pos = align.align_bot; + break; + + case PSH_BLUE_ALIGN_TOP | PSH_BLUE_ALIGN_BOT: + /* both edges of the stem are aligned against blue zones */ + hint->cur_pos = align.align_bot; + hint->cur_len = align.align_top - align.align_bot; + break; + + default: + { + PSH_Hint parent = hint->parent; + + + if ( parent ) + { + FT_Pos par_org_center, par_cur_center; + FT_Pos cur_org_center, cur_delta; + + + /* ensure that parent is already fitted */ + if ( !psh_hint_is_fitted( parent ) ) + psh_hint_align_light( parent, globals, dimension, glyph ); + + par_org_center = parent->org_pos + ( parent->org_len / 2 ); + par_cur_center = parent->cur_pos + ( parent->cur_len / 2 ); + cur_org_center = hint->org_pos + ( hint->org_len / 2 ); + + cur_delta = FT_MulFix( cur_org_center - par_org_center, scale ); + pos = par_cur_center + cur_delta - ( len >> 1 ); + } + + /* Stems less than one pixel wide are easy -- we want to + * make them as dark as possible, so they must fall within + * one pixel. If the stem is split between two pixels + * then snap the edge that is nearer to the pixel boundary + * to the pixel boundary. + */ + if ( len <= 64 ) + { + if ( ( pos + len + 63 ) / 64 != pos / 64 + 1 ) + pos += psh_hint_snap_stem_side_delta ( pos, len ); + } + + /* Position stems other to minimize the amount of mid-grays. + * There are, in general, two positions that do this, + * illustrated as A) and B) below. + * + * + + + + + * + * A) |--------------------------------| + * B) |--------------------------------| + * C) |--------------------------------| + * + * Position A) (split the excess stem equally) should be better + * for stems of width N + f where f < 0.5. + * + * Position B) (split the deficiency equally) should be better + * for stems of width N + f where f > 0.5. + * + * It turns out though that minimizing the total number of lit + * pixels is also important, so position C), with one edge + * aligned with a pixel boundary is actually preferable + * to A). There are also more possibile positions for C) than + * for A) or B), so it involves less distortion of the overall + * character shape. + */ + else /* len > 64 */ + { + FT_Fixed frac_len = len & 63; + FT_Fixed center = pos + ( len >> 1 ); + FT_Fixed delta_a, delta_b; + + + if ( ( len / 64 ) & 1 ) + { + delta_a = FT_PIX_FLOOR( center ) + 32 - center; + delta_b = FT_PIX_ROUND( center ) - center; + } + else + { + delta_a = FT_PIX_ROUND( center ) - center; + delta_b = FT_PIX_FLOOR( center ) + 32 - center; + } + + /* We choose between B) and C) above based on the amount + * of fractinal stem width; for small amounts, choose + * C) always, for large amounts, B) always, and inbetween, + * pick whichever one involves less stem movement. + */ + if ( frac_len < 32 ) + { + pos += psh_hint_snap_stem_side_delta ( pos, len ); + } + else if ( frac_len < 48 ) + { + FT_Fixed side_delta = psh_hint_snap_stem_side_delta ( pos, + len ); + + if ( FT_ABS( side_delta ) < FT_ABS( delta_b ) ) + pos += side_delta; + else + pos += delta_b; + } + else + { + pos += delta_b; + } + } + + hint->cur_pos = pos; + } + } /* switch */ + + psh_hint_set_fitted( hint ); + +#ifdef DEBUG_HINTER + if ( ps_debug_hint_func ) + ps_debug_hint_func( hint, dimension ); +#endif + } + } + +#endif /* 0 */ + + + static void + psh_hint_table_align_hints( PSH_Hint_Table table, + PSH_Globals globals, + FT_Int dimension, + PSH_Glyph glyph ) + { + PSH_Hint hint; + FT_UInt count; + +#ifdef DEBUG_HINTER + + PSH_Dimension dim = &globals->dimension[dimension]; + FT_Fixed scale = dim->scale_mult; + FT_Fixed delta = dim->scale_delta; + + + if ( ps_debug_no_vert_hints && dimension == 0 ) + { + ps_simple_scale( table, scale, delta, dimension ); + return; + } + + if ( ps_debug_no_horz_hints && dimension == 1 ) + { + ps_simple_scale( table, scale, delta, dimension ); + return; + } + +#endif /* DEBUG_HINTER*/ + + hint = table->hints; + count = table->max_hints; + + for ( ; count > 0; count--, hint++ ) + psh_hint_align( hint, globals, dimension, glyph ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** POINTS INTERPOLATION ROUTINES *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + +#define PSH_ZONE_MIN -3200000L +#define PSH_ZONE_MAX +3200000L + +#define xxDEBUG_ZONES + + +#ifdef DEBUG_ZONES + +#include FT_CONFIG_STANDARD_LIBRARY_H + + static void + psh_print_zone( PSH_Zone zone ) + { + printf( "zone [scale,delta,min,max] = [%.3f,%.3f,%d,%d]\n", + zone->scale / 65536.0, + zone->delta / 64.0, + zone->min, + zone->max ); + } + +#else + +#define psh_print_zone( x ) do { } while ( 0 ) + +#endif /* DEBUG_ZONES */ + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** HINTER GLYPH MANAGEMENT *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + +#if 1 + +#define psh_corner_is_flat ft_corner_is_flat +#define psh_corner_orientation ft_corner_orientation + +#else + + FT_LOCAL_DEF( FT_Int ) + psh_corner_is_flat( FT_Pos x_in, + FT_Pos y_in, + FT_Pos x_out, + FT_Pos y_out ) + { + FT_Pos ax = x_in; + FT_Pos ay = y_in; + + FT_Pos d_in, d_out, d_corner; + + + if ( ax < 0 ) + ax = -ax; + if ( ay < 0 ) + ay = -ay; + d_in = ax + ay; + + ax = x_out; + if ( ax < 0 ) + ax = -ax; + ay = y_out; + if ( ay < 0 ) + ay = -ay; + d_out = ax + ay; + + ax = x_out + x_in; + if ( ax < 0 ) + ax = -ax; + ay = y_out + y_in; + if ( ay < 0 ) + ay = -ay; + d_corner = ax + ay; + + return ( d_in + d_out - d_corner ) < ( d_corner >> 4 ); + } + + static FT_Int + psh_corner_orientation( FT_Pos in_x, + FT_Pos in_y, + FT_Pos out_x, + FT_Pos out_y ) + { + FT_Int result; + + + /* deal with the trivial cases quickly */ + if ( in_y == 0 ) + { + if ( in_x >= 0 ) + result = out_y; + else + result = -out_y; + } + else if ( in_x == 0 ) + { + if ( in_y >= 0 ) + result = -out_x; + else + result = out_x; + } + else if ( out_y == 0 ) + { + if ( out_x >= 0 ) + result = in_y; + else + result = -in_y; + } + else if ( out_x == 0 ) + { + if ( out_y >= 0 ) + result = -in_x; + else + result = in_x; + } + else /* general case */ + { + long long delta = (long long)in_x * out_y - (long long)in_y * out_x; + + if ( delta == 0 ) + result = 0; + else + result = 1 - 2 * ( delta < 0 ); + } + + return result; + } + +#endif /* !1 */ + + +#ifdef COMPUTE_INFLEXS + + /* compute all inflex points in a given glyph */ + static void + psh_glyph_compute_inflections( PSH_Glyph glyph ) + { + FT_UInt n; + + + for ( n = 0; n < glyph->num_contours; n++ ) + { + PSH_Point first, start, end, before, after; + FT_Pos in_x, in_y, out_x, out_y; + FT_Int orient_prev, orient_cur; + FT_Int finished = 0; + + + /* we need at least 4 points to create an inflection point */ + if ( glyph->contours[n].count < 4 ) + continue; + + /* compute first segment in contour */ + first = glyph->contours[n].start; + + start = end = first; + do + { + end = end->next; + if ( end == first ) + goto Skip; + + in_x = end->org_u - start->org_u; + in_y = end->org_v - start->org_v; + + } while ( in_x == 0 && in_y == 0 ); + + /* extend the segment start whenever possible */ + before = start; + do + { + do + { + start = before; + before = before->prev; + if ( before == first ) + goto Skip; + + out_x = start->org_u - before->org_u; + out_y = start->org_v - before->org_v; + + } while ( out_x == 0 && out_y == 0 ); + + orient_prev = psh_corner_orientation( in_x, in_y, out_x, out_y ); + + } while ( orient_prev == 0 ); + + first = start; + in_x = out_x; + in_y = out_y; + + /* now, process all segments in the contour */ + do + { + /* first, extend current segment's end whenever possible */ + after = end; + do + { + do + { + end = after; + after = after->next; + if ( after == first ) + finished = 1; + + out_x = after->org_u - end->org_u; + out_y = after->org_v - end->org_v; + + } while ( out_x == 0 && out_y == 0 ); + + orient_cur = psh_corner_orientation( in_x, in_y, out_x, out_y ); + + } while ( orient_cur == 0 ); + + if ( ( orient_cur ^ orient_prev ) < 0 ) + { + do + { + psh_point_set_inflex( start ); + start = start->next; + } + while ( start != end ); + + psh_point_set_inflex( start ); + } + + start = end; + end = after; + orient_prev = orient_cur; + in_x = out_x; + in_y = out_y; + + } while ( !finished ); + + Skip: + ; + } + } + +#endif /* COMPUTE_INFLEXS */ + + + static void + psh_glyph_done( PSH_Glyph glyph ) + { + FT_Memory memory = glyph->memory; + + + psh_hint_table_done( &glyph->hint_tables[1], memory ); + psh_hint_table_done( &glyph->hint_tables[0], memory ); + + FT_FREE( glyph->points ); + FT_FREE( glyph->contours ); + + glyph->num_points = 0; + glyph->num_contours = 0; + + glyph->memory = 0; + } + + + static int + psh_compute_dir( FT_Pos dx, + FT_Pos dy ) + { + FT_Pos ax, ay; + int result = PSH_DIR_NONE; + + + ax = ( dx >= 0 ) ? dx : -dx; + ay = ( dy >= 0 ) ? dy : -dy; + + if ( ay * 12 < ax ) + { + /* |dy| <<< |dx| means a near-horizontal segment */ + result = ( dx >= 0 ) ? PSH_DIR_RIGHT : PSH_DIR_LEFT; + } + else if ( ax * 12 < ay ) + { + /* |dx| <<< |dy| means a near-vertical segment */ + result = ( dy >= 0 ) ? PSH_DIR_UP : PSH_DIR_DOWN; + } + + return result; + } + + + /* load outline point coordinates into hinter glyph */ + static void + psh_glyph_load_points( PSH_Glyph glyph, + FT_Int dimension ) + { + FT_Vector* vec = glyph->outline->points; + PSH_Point point = glyph->points; + FT_UInt count = glyph->num_points; + + + for ( ; count > 0; count--, point++, vec++ ) + { + point->flags2 = 0; + point->hint = NULL; + if ( dimension == 0 ) + { + point->org_u = vec->x; + point->org_v = vec->y; + } + else + { + point->org_u = vec->y; + point->org_v = vec->x; + } + +#ifdef DEBUG_HINTER + point->org_x = vec->x; + point->org_y = vec->y; +#endif + + } + } + + + /* save hinted point coordinates back to outline */ + static void + psh_glyph_save_points( PSH_Glyph glyph, + FT_Int dimension ) + { + FT_UInt n; + PSH_Point point = glyph->points; + FT_Vector* vec = glyph->outline->points; + char* tags = glyph->outline->tags; + + + for ( n = 0; n < glyph->num_points; n++ ) + { + if ( dimension == 0 ) + vec[n].x = point->cur_u; + else + vec[n].y = point->cur_u; + + if ( psh_point_is_strong( point ) ) + tags[n] |= (char)( ( dimension == 0 ) ? 32 : 64 ); + +#ifdef DEBUG_HINTER + + if ( dimension == 0 ) + { + point->cur_x = point->cur_u; + point->flags_x = point->flags2 | point->flags; + } + else + { + point->cur_y = point->cur_u; + point->flags_y = point->flags2 | point->flags; + } + +#endif + + point++; + } + } + + + static FT_Error + psh_glyph_init( PSH_Glyph glyph, + FT_Outline* outline, + PS_Hints ps_hints, + PSH_Globals globals ) + { + FT_Error error; + FT_Memory memory; + + + /* clear all fields */ + FT_MEM_ZERO( glyph, sizeof ( *glyph ) ); + + memory = glyph->memory = globals->memory; + + /* allocate and setup points + contours arrays */ + if ( FT_NEW_ARRAY( glyph->points, outline->n_points ) || + FT_NEW_ARRAY( glyph->contours, outline->n_contours ) ) + goto Exit; + + glyph->num_points = outline->n_points; + glyph->num_contours = outline->n_contours; + + { + FT_UInt first = 0, next, n; + PSH_Point points = glyph->points; + PSH_Contour contour = glyph->contours; + + + for ( n = 0; n < glyph->num_contours; n++ ) + { + FT_Int count; + PSH_Point point; + + + next = outline->contours[n] + 1; + count = next - first; + + contour->start = points + first; + contour->count = (FT_UInt)count; + + if ( count > 0 ) + { + point = points + first; + + point->prev = points + next - 1; + point->contour = contour; + + for ( ; count > 1; count-- ) + { + point[0].next = point + 1; + point[1].prev = point; + point++; + point->contour = contour; + } + point->next = points + first; + } + + contour++; + first = next; + } + } + + { + PSH_Point points = glyph->points; + PSH_Point point = points; + FT_Vector* vec = outline->points; + FT_UInt n; + + + for ( n = 0; n < glyph->num_points; n++, point++ ) + { + FT_Int n_prev = (FT_Int)( point->prev - points ); + FT_Int n_next = (FT_Int)( point->next - points ); + FT_Pos dxi, dyi, dxo, dyo; + + + if ( !( outline->tags[n] & FT_CURVE_TAG_ON ) ) + point->flags = PSH_POINT_OFF; + + dxi = vec[n].x - vec[n_prev].x; + dyi = vec[n].y - vec[n_prev].y; + + point->dir_in = (FT_Char)psh_compute_dir( dxi, dyi ); + + dxo = vec[n_next].x - vec[n].x; + dyo = vec[n_next].y - vec[n].y; + + point->dir_out = (FT_Char)psh_compute_dir( dxo, dyo ); + + /* detect smooth points */ + if ( point->flags & PSH_POINT_OFF ) + point->flags |= PSH_POINT_SMOOTH; + + else if ( point->dir_in == point->dir_out ) + { + if ( point->dir_out != PSH_DIR_NONE || + psh_corner_is_flat( dxi, dyi, dxo, dyo ) ) + point->flags |= PSH_POINT_SMOOTH; + } + } + } + + glyph->outline = outline; + glyph->globals = globals; + +#ifdef COMPUTE_INFLEXS + psh_glyph_load_points( glyph, 0 ); + psh_glyph_compute_inflections( glyph ); +#endif /* COMPUTE_INFLEXS */ + + /* now deal with hints tables */ + error = psh_hint_table_init( &glyph->hint_tables [0], + &ps_hints->dimension[0].hints, + &ps_hints->dimension[0].masks, + &ps_hints->dimension[0].counters, + memory ); + if ( error ) + goto Exit; + + error = psh_hint_table_init( &glyph->hint_tables [1], + &ps_hints->dimension[1].hints, + &ps_hints->dimension[1].masks, + &ps_hints->dimension[1].counters, + memory ); + if ( error ) + goto Exit; + + Exit: + return error; + } + + + /* compute all extrema in a glyph for a given dimension */ + static void + psh_glyph_compute_extrema( PSH_Glyph glyph ) + { + FT_UInt n; + + + /* first of all, compute all local extrema */ + for ( n = 0; n < glyph->num_contours; n++ ) + { + PSH_Point first = glyph->contours[n].start; + PSH_Point point, before, after; + + + if ( glyph->contours[n].count == 0 ) + continue; + + point = first; + before = point; + after = point; + + do + { + before = before->prev; + if ( before == first ) + goto Skip; + + } while ( before->org_u == point->org_u ); + + first = point = before->next; + + for (;;) + { + after = point; + do + { + after = after->next; + if ( after == first ) + goto Next; + + } while ( after->org_u == point->org_u ); + + if ( before->org_u < point->org_u ) + { + if ( after->org_u < point->org_u ) + { + /* local maximum */ + goto Extremum; + } + } + else /* before->org_u > point->org_u */ + { + if ( after->org_u > point->org_u ) + { + /* local minimum */ + Extremum: + do + { + psh_point_set_extremum( point ); + point = point->next; + + } while ( point != after ); + } + } + + before = after->prev; + point = after; + + } /* for */ + + Next: + ; + } + + /* for each extremum, determine its direction along the */ + /* orthogonal axis */ + for ( n = 0; n < glyph->num_points; n++ ) + { + PSH_Point point, before, after; + + + point = &glyph->points[n]; + before = point; + after = point; + + if ( psh_point_is_extremum( point ) ) + { + do + { + before = before->prev; + if ( before == point ) + goto Skip; + + } while ( before->org_v == point->org_v ); + + do + { + after = after->next; + if ( after == point ) + goto Skip; + + } while ( after->org_v == point->org_v ); + } + + if ( before->org_v < point->org_v && + after->org_v > point->org_v ) + { + psh_point_set_positive( point ); + } + else if ( before->org_v > point->org_v && + after->org_v < point->org_v ) + { + psh_point_set_negative( point ); + } + + Skip: + ; + } + } + + + /* major_dir is the direction for points on the bottom/left of the stem; */ + /* Points on the top/right of the stem will have a direction of */ + /* -major_dir. */ + + static void + psh_hint_table_find_strong_points( PSH_Hint_Table table, + PSH_Point point, + FT_UInt count, + FT_Int threshold, + FT_Int major_dir ) + { + PSH_Hint* sort = table->sort; + FT_UInt num_hints = table->num_hints; + + + for ( ; count > 0; count--, point++ ) + { + FT_Int point_dir = 0; + FT_Pos org_u = point->org_u; + + + if ( psh_point_is_strong( point ) ) + continue; + + if ( PSH_DIR_COMPARE( point->dir_in, major_dir ) ) + point_dir = point->dir_in; + + else if ( PSH_DIR_COMPARE( point->dir_out, major_dir ) ) + point_dir = point->dir_out; + + if ( point_dir ) + { + if ( point_dir == major_dir ) + { + FT_UInt nn; + + + for ( nn = 0; nn < num_hints; nn++ ) + { + PSH_Hint hint = sort[nn]; + FT_Pos d = org_u - hint->org_pos; + + + if ( d < threshold && -d < threshold ) + { + psh_point_set_strong( point ); + point->flags2 |= PSH_POINT_EDGE_MIN; + point->hint = hint; + break; + } + } + } + else if ( point_dir == -major_dir ) + { + FT_UInt nn; + + + for ( nn = 0; nn < num_hints; nn++ ) + { + PSH_Hint hint = sort[nn]; + FT_Pos d = org_u - hint->org_pos - hint->org_len; + + + if ( d < threshold && -d < threshold ) + { + psh_point_set_strong( point ); + point->flags2 |= PSH_POINT_EDGE_MAX; + point->hint = hint; + break; + } + } + } + } + +#if 1 + else if ( psh_point_is_extremum( point ) ) + { + /* treat extrema as special cases for stem edge alignment */ + FT_UInt nn, min_flag, max_flag; + + + if ( major_dir == PSH_DIR_HORIZONTAL ) + { + min_flag = PSH_POINT_POSITIVE; + max_flag = PSH_POINT_NEGATIVE; + } + else + { + min_flag = PSH_POINT_NEGATIVE; + max_flag = PSH_POINT_POSITIVE; + } + + if ( point->flags2 & min_flag ) + { + for ( nn = 0; nn < num_hints; nn++ ) + { + PSH_Hint hint = sort[nn]; + FT_Pos d = org_u - hint->org_pos; + + + if ( d < threshold && -d < threshold ) + { + point->flags2 |= PSH_POINT_EDGE_MIN; + point->hint = hint; + psh_point_set_strong( point ); + break; + } + } + } + else if ( point->flags2 & max_flag ) + { + for ( nn = 0; nn < num_hints; nn++ ) + { + PSH_Hint hint = sort[nn]; + FT_Pos d = org_u - hint->org_pos - hint->org_len; + + + if ( d < threshold && -d < threshold ) + { + point->flags2 |= PSH_POINT_EDGE_MAX; + point->hint = hint; + psh_point_set_strong( point ); + break; + } + } + } + + if ( point->hint == NULL ) + { + for ( nn = 0; nn < num_hints; nn++ ) + { + PSH_Hint hint = sort[nn]; + + + if ( org_u >= hint->org_pos && + org_u <= hint->org_pos + hint->org_len ) + { + point->hint = hint; + break; + } + } + } + } + +#endif /* 1 */ + } + } + + + /* the accepted shift for strong points in fractional pixels */ +#define PSH_STRONG_THRESHOLD 32 + + /* the maximum shift value in font units */ +#define PSH_STRONG_THRESHOLD_MAXIMUM 30 + + + /* find strong points in a glyph */ + static void + psh_glyph_find_strong_points( PSH_Glyph glyph, + FT_Int dimension ) + { + /* a point is `strong' if it is located on a stem edge and */ + /* has an `in' or `out' tangent parallel to the hint's direction */ + + PSH_Hint_Table table = &glyph->hint_tables[dimension]; + PS_Mask mask = table->hint_masks->masks; + FT_UInt num_masks = table->hint_masks->num_masks; + FT_UInt first = 0; + FT_Int major_dir = dimension == 0 ? PSH_DIR_VERTICAL + : PSH_DIR_HORIZONTAL; + PSH_Dimension dim = &glyph->globals->dimension[dimension]; + FT_Fixed scale = dim->scale_mult; + FT_Int threshold; + + + threshold = (FT_Int)FT_DivFix( PSH_STRONG_THRESHOLD, scale ); + if ( threshold > PSH_STRONG_THRESHOLD_MAXIMUM ) + threshold = PSH_STRONG_THRESHOLD_MAXIMUM; + + /* process secondary hints to `selected' points */ + if ( num_masks > 1 && glyph->num_points > 0 ) + { + first = mask->end_point; + mask++; + for ( ; num_masks > 1; num_masks--, mask++ ) + { + FT_UInt next; + FT_Int count; + + + next = mask->end_point; + count = next - first; + if ( count > 0 ) + { + PSH_Point point = glyph->points + first; + + + psh_hint_table_activate_mask( table, mask ); + + psh_hint_table_find_strong_points( table, point, count, + threshold, major_dir ); + } + first = next; + } + } + + /* process primary hints for all points */ + if ( num_masks == 1 ) + { + FT_UInt count = glyph->num_points; + PSH_Point point = glyph->points; + + + psh_hint_table_activate_mask( table, table->hint_masks->masks ); + + psh_hint_table_find_strong_points( table, point, count, + threshold, major_dir ); + } + + /* now, certain points may have been attached to a hint and */ + /* not marked as strong; update their flags then */ + { + FT_UInt count = glyph->num_points; + PSH_Point point = glyph->points; + + + for ( ; count > 0; count--, point++ ) + if ( point->hint && !psh_point_is_strong( point ) ) + psh_point_set_strong( point ); + } + } + + + /* find points in a glyph which are in a blue zone and have `in' or */ + /* `out' tangents parallel to the horizontal axis */ + static void + psh_glyph_find_blue_points( PSH_Blues blues, + PSH_Glyph glyph ) + { + PSH_Blue_Table table; + PSH_Blue_Zone zone; + FT_UInt glyph_count = glyph->num_points; + FT_UInt blue_count; + PSH_Point point = glyph->points; + + + for ( ; glyph_count > 0; glyph_count--, point++ ) + { + FT_Pos y; + + + /* check tangents */ + if ( !PSH_DIR_COMPARE( point->dir_in, PSH_DIR_HORIZONTAL ) && + !PSH_DIR_COMPARE( point->dir_out, PSH_DIR_HORIZONTAL ) ) + continue; + + /* skip strong points */ + if ( psh_point_is_strong( point ) ) + continue; + + y = point->org_u; + + /* look up top zones */ + table = &blues->normal_top; + blue_count = table->count; + zone = table->zones; + + for ( ; blue_count > 0; blue_count--, zone++ ) + { + FT_Pos delta = y - zone->org_bottom; + + + if ( delta < -blues->blue_fuzz ) + break; + + if ( y <= zone->org_top + blues->blue_fuzz ) + if ( blues->no_overshoots || delta <= blues->blue_threshold ) + { + point->cur_u = zone->cur_bottom; + psh_point_set_strong( point ); + psh_point_set_fitted( point ); + } + } + + /* look up bottom zones */ + table = &blues->normal_bottom; + blue_count = table->count; + zone = table->zones + blue_count - 1; + + for ( ; blue_count > 0; blue_count--, zone-- ) + { + FT_Pos delta = zone->org_top - y; + + + if ( delta < -blues->blue_fuzz ) + break; + + if ( y >= zone->org_bottom - blues->blue_fuzz ) + if ( blues->no_overshoots || delta < blues->blue_threshold ) + { + point->cur_u = zone->cur_top; + psh_point_set_strong( point ); + psh_point_set_fitted( point ); + } + } + } + } + + + /* interpolate strong points with the help of hinted coordinates */ + static void + psh_glyph_interpolate_strong_points( PSH_Glyph glyph, + FT_Int dimension ) + { + PSH_Dimension dim = &glyph->globals->dimension[dimension]; + FT_Fixed scale = dim->scale_mult; + + FT_UInt count = glyph->num_points; + PSH_Point point = glyph->points; + + + for ( ; count > 0; count--, point++ ) + { + PSH_Hint hint = point->hint; + + + if ( hint ) + { + FT_Pos delta; + + + if ( psh_point_is_edge_min( point ) ) + point->cur_u = hint->cur_pos; + + else if ( psh_point_is_edge_max( point ) ) + point->cur_u = hint->cur_pos + hint->cur_len; + + else + { + delta = point->org_u - hint->org_pos; + + if ( delta <= 0 ) + point->cur_u = hint->cur_pos + FT_MulFix( delta, scale ); + + else if ( delta >= hint->org_len ) + point->cur_u = hint->cur_pos + hint->cur_len + + FT_MulFix( delta - hint->org_len, scale ); + + else if ( hint->org_len > 0 ) + point->cur_u = hint->cur_pos + + FT_MulDiv( delta, hint->cur_len, + hint->org_len ); + else + point->cur_u = hint->cur_pos; + } + psh_point_set_fitted( point ); + } + } + } + + +#define PSH_MAX_STRONG_INTERNAL 16 + + static void + psh_glyph_interpolate_normal_points( PSH_Glyph glyph, + FT_Int dimension ) + { + +#if 1 + /* first technique: a point is strong if it is a local extremum */ + + PSH_Dimension dim = &glyph->globals->dimension[dimension]; + FT_Fixed scale = dim->scale_mult; + FT_Memory memory = glyph->memory; + + PSH_Point* strongs = NULL; + PSH_Point strongs_0[PSH_MAX_STRONG_INTERNAL]; + FT_UInt num_strongs = 0; + + PSH_Point points = glyph->points; + PSH_Point points_end = points + glyph->num_points; + PSH_Point point; + + + /* first count the number of strong points */ + for ( point = points; point < points_end; point++ ) + { + if ( psh_point_is_strong( point ) ) + num_strongs++; + } + + if ( num_strongs == 0 ) /* nothing to do here */ + return; + + /* allocate an array to store a list of points, */ + /* stored in increasing org_u order */ + if ( num_strongs <= PSH_MAX_STRONG_INTERNAL ) + strongs = strongs_0; + else + { + FT_Error error; + + + if ( FT_NEW_ARRAY( strongs, num_strongs ) ) + return; + } + + num_strongs = 0; + for ( point = points; point < points_end; point++ ) + { + PSH_Point* insert; + + + if ( !psh_point_is_strong( point ) ) + continue; + + for ( insert = strongs + num_strongs; insert > strongs; insert-- ) + { + if ( insert[-1]->org_u <= point->org_u ) + break; + + insert[0] = insert[-1]; + } + insert[0] = point; + num_strongs++; + } + + /* now try to interpolate all normal points */ + for ( point = points; point < points_end; point++ ) + { + if ( psh_point_is_strong( point ) ) + continue; + + /* sometimes, some local extrema are smooth points */ + if ( psh_point_is_smooth( point ) ) + { + if ( point->dir_in == PSH_DIR_NONE || + point->dir_in != point->dir_out ) + continue; + + if ( !psh_point_is_extremum( point ) && + !psh_point_is_inflex( point ) ) + continue; + + point->flags &= ~PSH_POINT_SMOOTH; + } + + /* find best enclosing point coordinates then interpolate */ + { + PSH_Point before, after; + FT_UInt nn; + + + for ( nn = 0; nn < num_strongs; nn++ ) + if ( strongs[nn]->org_u > point->org_u ) + break; + + if ( nn == 0 ) /* point before the first strong point */ + { + after = strongs[0]; + + point->cur_u = after->cur_u + + FT_MulFix( point->org_u - after->org_u, + scale ); + } + else + { + before = strongs[nn - 1]; + + for ( nn = num_strongs; nn > 0; nn-- ) + if ( strongs[nn - 1]->org_u < point->org_u ) + break; + + if ( nn == num_strongs ) /* point is after last strong point */ + { + before = strongs[nn - 1]; + + point->cur_u = before->cur_u + + FT_MulFix( point->org_u - before->org_u, + scale ); + } + else + { + FT_Pos u; + + + after = strongs[nn]; + + /* now interpolate point between before and after */ + u = point->org_u; + + if ( u == before->org_u ) + point->cur_u = before->cur_u; + + else if ( u == after->org_u ) + point->cur_u = after->cur_u; + + else + point->cur_u = before->cur_u + + FT_MulDiv( u - before->org_u, + after->cur_u - before->cur_u, + after->org_u - before->org_u ); + } + } + psh_point_set_fitted( point ); + } + } + + if ( strongs != strongs_0 ) + FT_FREE( strongs ); + +#endif /* 1 */ + + } + + + /* interpolate other points */ + static void + psh_glyph_interpolate_other_points( PSH_Glyph glyph, + FT_Int dimension ) + { + PSH_Dimension dim = &glyph->globals->dimension[dimension]; + FT_Fixed scale = dim->scale_mult; + FT_Fixed delta = dim->scale_delta; + PSH_Contour contour = glyph->contours; + FT_UInt num_contours = glyph->num_contours; + + + for ( ; num_contours > 0; num_contours--, contour++ ) + { + PSH_Point start = contour->start; + PSH_Point first, next, point; + FT_UInt fit_count; + + + /* count the number of strong points in this contour */ + next = start + contour->count; + fit_count = 0; + first = 0; + + for ( point = start; point < next; point++ ) + if ( psh_point_is_fitted( point ) ) + { + if ( !first ) + first = point; + + fit_count++; + } + + /* if there are less than 2 fitted points in the contour, we */ + /* simply scale and eventually translate the contour points */ + if ( fit_count < 2 ) + { + if ( fit_count == 1 ) + delta = first->cur_u - FT_MulFix( first->org_u, scale ); + + for ( point = start; point < next; point++ ) + if ( point != first ) + point->cur_u = FT_MulFix( point->org_u, scale ) + delta; + + goto Next_Contour; + } + + /* there are more than 2 strong points in this contour; we */ + /* need to interpolate weak points between them */ + start = first; + do + { + point = first; + + /* skip consecutive fitted points */ + for (;;) + { + next = first->next; + if ( next == start ) + goto Next_Contour; + + if ( !psh_point_is_fitted( next ) ) + break; + + first = next; + } + + /* find next fitted point after unfitted one */ + for (;;) + { + next = next->next; + if ( psh_point_is_fitted( next ) ) + break; + } + + /* now interpolate between them */ + { + FT_Pos org_a, org_ab, cur_a, cur_ab; + FT_Pos org_c, org_ac, cur_c; + FT_Fixed scale_ab; + + + if ( first->org_u <= next->org_u ) + { + org_a = first->org_u; + cur_a = first->cur_u; + org_ab = next->org_u - org_a; + cur_ab = next->cur_u - cur_a; + } + else + { + org_a = next->org_u; + cur_a = next->cur_u; + org_ab = first->org_u - org_a; + cur_ab = first->cur_u - cur_a; + } + + scale_ab = 0x10000L; + if ( org_ab > 0 ) + scale_ab = FT_DivFix( cur_ab, org_ab ); + + point = first->next; + do + { + org_c = point->org_u; + org_ac = org_c - org_a; + + if ( org_ac <= 0 ) + { + /* on the left of the interpolation zone */ + cur_c = cur_a + FT_MulFix( org_ac, scale ); + } + else if ( org_ac >= org_ab ) + { + /* on the right on the interpolation zone */ + cur_c = cur_a + cur_ab + FT_MulFix( org_ac - org_ab, scale ); + } + else + { + /* within the interpolation zone */ + cur_c = cur_a + FT_MulFix( org_ac, scale_ab ); + } + + point->cur_u = cur_c; + + point = point->next; + + } while ( point != next ); + } + + /* keep going until all points in the contours have been processed */ + first = next; + + } while ( first != start ); + + Next_Contour: + ; + } + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** HIGH-LEVEL INTERFACE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_Error + ps_hints_apply( PS_Hints ps_hints, + FT_Outline* outline, + PSH_Globals globals, + FT_Render_Mode hint_mode ) + { + PSH_GlyphRec glyphrec; + PSH_Glyph glyph = &glyphrec; + FT_Error error; +#ifdef DEBUG_HINTER + FT_Memory memory; +#endif + FT_Int dimension; + + + /* something to do? */ + if ( outline->n_points == 0 || outline->n_contours == 0 ) + return PSH_Err_Ok; + +#ifdef DEBUG_HINTER + + memory = globals->memory; + + if ( ps_debug_glyph ) + { + psh_glyph_done( ps_debug_glyph ); + FT_FREE( ps_debug_glyph ); + } + + if ( FT_NEW( glyph ) ) + return error; + + ps_debug_glyph = glyph; + +#endif /* DEBUG_HINTER */ + + error = psh_glyph_init( glyph, outline, ps_hints, globals ); + if ( error ) + goto Exit; + + /* try to optimize the y_scale so that the top of non-capital letters + * is aligned on a pixel boundary whenever possible + */ + { + PSH_Dimension dim_x = &glyph->globals->dimension[0]; + PSH_Dimension dim_y = &glyph->globals->dimension[1]; + + FT_Fixed x_scale = dim_x->scale_mult; + FT_Fixed y_scale = dim_y->scale_mult; + + FT_Fixed old_x_scale = x_scale; + FT_Fixed old_y_scale = y_scale; + + FT_Fixed scaled; + FT_Fixed fitted; + + FT_Bool rescale = FALSE; + + + scaled = FT_MulFix( globals->blues.normal_top.zones->org_ref, y_scale ); + fitted = FT_PIX_ROUND( scaled ); + + if ( fitted != 0 && scaled != fitted ) + { + rescale = TRUE; + + y_scale = FT_MulDiv( y_scale, fitted, scaled ); + + if ( fitted < scaled ) + x_scale -= x_scale / 50; + + psh_globals_set_scale( glyph->globals, x_scale, y_scale, 0, 0 ); + } + + glyph->do_horz_hints = 1; + glyph->do_vert_hints = 1; + + glyph->do_horz_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_MONO || + hint_mode == FT_RENDER_MODE_LCD ); + + glyph->do_vert_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_MONO || + hint_mode == FT_RENDER_MODE_LCD_V ); + + glyph->do_stem_adjust = FT_BOOL( hint_mode != FT_RENDER_MODE_LIGHT ); + + for ( dimension = 0; dimension < 2; dimension++ ) + { + /* load outline coordinates into glyph */ + psh_glyph_load_points( glyph, dimension ); + + /* compute local extrema */ + psh_glyph_compute_extrema( glyph ); + + /* compute aligned stem/hints positions */ + psh_hint_table_align_hints( &glyph->hint_tables[dimension], + glyph->globals, + dimension, + glyph ); + + /* find strong points, align them, then interpolate others */ + psh_glyph_find_strong_points( glyph, dimension ); + if ( dimension == 1 ) + psh_glyph_find_blue_points( &globals->blues, glyph ); + psh_glyph_interpolate_strong_points( glyph, dimension ); + psh_glyph_interpolate_normal_points( glyph, dimension ); + psh_glyph_interpolate_other_points( glyph, dimension ); + + /* save hinted coordinates back to outline */ + psh_glyph_save_points( glyph, dimension ); + + if ( rescale ) + psh_globals_set_scale( glyph->globals, + old_x_scale, old_y_scale, 0, 0 ); + } + } + + Exit: + +#ifndef DEBUG_HINTER + psh_glyph_done( glyph ); +#endif + + return error; + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/pshinter/pshalgo.h b/mod/pub.mod/freetype.mod/src/pshinter/pshalgo.h new file mode 100644 index 0000000..1a248a7 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/pshinter/pshalgo.h @@ -0,0 +1,255 @@ +/***************************************************************************/ +/* */ +/* pshalgo.h */ +/* */ +/* PostScript hinting algorithm (specification). */ +/* */ +/* Copyright 2001, 2002, 2003, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __PSHALGO_H__ +#define __PSHALGO_H__ + + +#include "pshrec.h" +#include "pshglob.h" +#include FT_TRIGONOMETRY_H + + +FT_BEGIN_HEADER + + + /* handle to Hint structure */ + typedef struct PSH_HintRec_* PSH_Hint; + + /* hint bit-flags */ + typedef enum PSH_Hint_Flags_ + { + PSH_HINT_GHOST = PS_HINT_FLAG_GHOST, + PSH_HINT_BOTTOM = PS_HINT_FLAG_BOTTOM, + PSH_HINT_ACTIVE = 4, + PSH_HINT_FITTED = 8 + + } PSH_Hint_Flags; + + +#define psh_hint_is_active( x ) ( ( (x)->flags & PSH_HINT_ACTIVE ) != 0 ) +#define psh_hint_is_ghost( x ) ( ( (x)->flags & PSH_HINT_GHOST ) != 0 ) +#define psh_hint_is_fitted( x ) ( ( (x)->flags & PSH_HINT_FITTED ) != 0 ) + +#define psh_hint_activate( x ) (x)->flags |= PSH_HINT_ACTIVE +#define psh_hint_deactivate( x ) (x)->flags &= ~PSH_HINT_ACTIVE +#define psh_hint_set_fitted( x ) (x)->flags |= PSH_HINT_FITTED + + /* hint structure */ + typedef struct PSH_HintRec_ + { + FT_Int org_pos; + FT_Int org_len; + FT_Pos cur_pos; + FT_Pos cur_len; + FT_UInt flags; + PSH_Hint parent; + FT_Int order; + + } PSH_HintRec; + + + /* this is an interpolation zone used for strong points; */ + /* weak points are interpolated according to their strong */ + /* neighbours */ + typedef struct PSH_ZoneRec_ + { + FT_Fixed scale; + FT_Fixed delta; + FT_Pos min; + FT_Pos max; + + } PSH_ZoneRec, *PSH_Zone; + + + typedef struct PSH_Hint_TableRec_ + { + FT_UInt max_hints; + FT_UInt num_hints; + PSH_Hint hints; + PSH_Hint* sort; + PSH_Hint* sort_global; + FT_UInt num_zones; + PSH_ZoneRec* zones; + PSH_Zone zone; + PS_Mask_Table hint_masks; + PS_Mask_Table counter_masks; + + } PSH_Hint_TableRec, *PSH_Hint_Table; + + + typedef struct PSH_PointRec_* PSH_Point; + typedef struct PSH_ContourRec_* PSH_Contour; + + enum + { + PSH_DIR_NONE = 4, + PSH_DIR_UP = -1, + PSH_DIR_DOWN = 1, + PSH_DIR_LEFT = -2, + PSH_DIR_RIGHT = 2 + }; + +#define PSH_DIR_HORIZONTAL 2 +#define PSH_DIR_VERTICAL 1 + +#define PSH_DIR_COMPARE( d1, d2 ) ( (d1) == (d2) || (d1) == -(d2) ) +#define PSH_DIR_IS_HORIZONTAL( d ) PSH_DIR_COMPARE( d, PSH_DIR_HORIZONTAL ) +#define PSH_DIR_IS_VERTICAL( d ) PSH_DIR_COMPARE( d, PSH_DIR_VERTICAL ) + + + /* the following bit-flags are computed once by the glyph */ + /* analyzer, for both dimensions */ + enum + { + PSH_POINT_OFF = 1, /* point is off the curve */ + PSH_POINT_SMOOTH = 2, /* point is smooth */ + PSH_POINT_INFLEX = 4 /* point is inflection */ + }; + +#define psh_point_is_smooth( p ) ( (p)->flags & PSH_POINT_SMOOTH ) +#define psh_point_is_off( p ) ( (p)->flags & PSH_POINT_OFF ) +#define psh_point_is_inflex( p ) ( (p)->flags & PSH_POINT_INFLEX ) + +#define psh_point_set_smooth( p ) (p)->flags |= PSH_POINT_SMOOTH +#define psh_point_set_off( p ) (p)->flags |= PSH_POINT_OFF +#define psh_point_set_inflex( p ) (p)->flags |= PSH_POINT_INFLEX + + /* the following bit-flags are re-computed for each dimension */ + enum + { + PSH_POINT_STRONG = 16, /* point is strong */ + PSH_POINT_FITTED = 32, /* point is already fitted */ + PSH_POINT_EXTREMUM = 64, /* point is local extremum */ + PSH_POINT_POSITIVE = 128, /* extremum has positive contour flow */ + PSH_POINT_NEGATIVE = 256, /* extremum has negative contour flow */ + PSH_POINT_EDGE_MIN = 512, /* point is aligned to left/bottom stem edge */ + PSH_POINT_EDGE_MAX = 1024 /* point is aligned to top/right stem edge */ + }; + +#define psh_point_is_strong( p ) ( (p)->flags2 & PSH_POINT_STRONG ) +#define psh_point_is_fitted( p ) ( (p)->flags2 & PSH_POINT_FITTED ) +#define psh_point_is_extremum( p ) ( (p)->flags2 & PSH_POINT_EXTREMUM ) +#define psh_point_is_positive( p ) ( (p)->flags2 & PSH_POINT_POSITIVE ) +#define psh_point_is_negative( p ) ( (p)->flags2 & PSH_POINT_NEGATIVE ) +#define psh_point_is_edge_min( p ) ( (p)->flags2 & PSH_POINT_EDGE_MIN ) +#define psh_point_is_edge_max( p ) ( (p)->flags2 & PSH_POINT_EDGE_MAX ) + +#define psh_point_set_strong( p ) (p)->flags2 |= PSH_POINT_STRONG +#define psh_point_set_fitted( p ) (p)->flags2 |= PSH_POINT_FITTED +#define psh_point_set_extremum( p ) (p)->flags2 |= PSH_POINT_EXTREMUM +#define psh_point_set_positive( p ) (p)->flags2 |= PSH_POINT_POSITIVE +#define psh_point_set_negative( p ) (p)->flags2 |= PSH_POINT_NEGATIVE +#define psh_point_set_edge_min( p ) (p)->flags2 |= PSH_POINT_EDGE_MIN +#define psh_point_set_edge_max( p ) (p)->flags2 |= PSH_POINT_EDGE_MAX + + + typedef struct PSH_PointRec_ + { + PSH_Point prev; + PSH_Point next; + PSH_Contour contour; + FT_UInt flags; + FT_UInt flags2; + FT_Char dir_in; + FT_Char dir_out; + FT_Angle angle_in; + FT_Angle angle_out; + PSH_Hint hint; + FT_Pos org_u; + FT_Pos org_v; + FT_Pos cur_u; +#ifdef DEBUG_HINTER + FT_Pos org_x; + FT_Pos cur_x; + FT_Pos org_y; + FT_Pos cur_y; + FT_UInt flags_x; + FT_UInt flags_y; +#endif + + } PSH_PointRec; + + +#define PSH_POINT_EQUAL_ORG( a, b ) ( (a)->org_u == (b)->org_u && \ + (a)->org_v == (b)->org_v ) + +#define PSH_POINT_ANGLE( a, b ) FT_Atan2( (b)->org_u - (a)->org_u, \ + (b)->org_v - (a)->org_v ) + + typedef struct PSH_ContourRec_ + { + PSH_Point start; + FT_UInt count; + + } PSH_ContourRec; + + + typedef struct PSH_GlyphRec_ + { + FT_UInt num_points; + FT_UInt num_contours; + + PSH_Point points; + PSH_Contour contours; + + FT_Memory memory; + FT_Outline* outline; + PSH_Globals globals; + PSH_Hint_TableRec hint_tables[2]; + + FT_Bool vertical; + FT_Int major_dir; + FT_Int minor_dir; + + FT_Bool do_horz_hints; + FT_Bool do_vert_hints; + FT_Bool do_horz_snapping; + FT_Bool do_vert_snapping; + FT_Bool do_stem_adjust; + + } PSH_GlyphRec, *PSH_Glyph; + + +#ifdef DEBUG_HINTER + extern PSH_Hint_Table ps_debug_hint_table; + + typedef void + (*PSH_HintFunc)( PSH_Hint hint, + FT_Bool vertical ); + + extern PSH_HintFunc ps_debug_hint_func; + + extern PSH_Glyph ps_debug_glyph; +#endif + + + extern FT_Error + ps_hints_apply( PS_Hints ps_hints, + FT_Outline* outline, + PSH_Globals globals, + FT_Render_Mode hint_mode ); + + +FT_END_HEADER + + +#endif /* __PSHALGO_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/pshinter/pshglob.c b/mod/pub.mod/freetype.mod/src/pshinter/pshglob.c new file mode 100644 index 0000000..8a69aa1 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/pshinter/pshglob.c @@ -0,0 +1,750 @@ +/***************************************************************************/ +/* */ +/* pshglob.c */ +/* */ +/* PostScript hinter global hinting management (body). */ +/* Inspired by the new auto-hinter module. */ +/* */ +/* Copyright 2001, 2002, 2003, 2004, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used */ +/* modified and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include "pshglob.h" + +#ifdef DEBUG_HINTER + PSH_Globals ps_debug_globals = 0; +#endif + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** STANDARD WIDTHS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + /* scale the widths/heights table */ + static void + psh_globals_scale_widths( PSH_Globals globals, + FT_UInt direction ) + { + PSH_Dimension dim = &globals->dimension[direction]; + PSH_Widths stdw = &dim->stdw; + FT_UInt count = stdw->count; + PSH_Width width = stdw->widths; + PSH_Width stand = width; /* standard width/height */ + FT_Fixed scale = dim->scale_mult; + + + if ( count > 0 ) + { + width->cur = FT_MulFix( width->org, scale ); + width->fit = FT_PIX_ROUND( width->cur ); + + width++; + count--; + + for ( ; count > 0; count--, width++ ) + { + FT_Pos w, dist; + + + w = FT_MulFix( width->org, scale ); + dist = w - stand->cur; + + if ( dist < 0 ) + dist = -dist; + + if ( dist < 128 ) + w = stand->cur; + + width->cur = w; + width->fit = FT_PIX_ROUND( w ); + } + } + } + + +#if 0 + + /* org_width is is font units, result in device pixels, 26.6 format */ + FT_LOCAL_DEF( FT_Pos ) + psh_dimension_snap_width( PSH_Dimension dimension, + FT_Int org_width ) + { + FT_UInt n; + FT_Pos width = FT_MulFix( org_width, dimension->scale_mult ); + FT_Pos best = 64 + 32 + 2; + FT_Pos reference = width; + + + for ( n = 0; n < dimension->stdw.count; n++ ) + { + FT_Pos w; + FT_Pos dist; + + + w = dimension->stdw.widths[n].cur; + dist = width - w; + if ( dist < 0 ) + dist = -dist; + if ( dist < best ) + { + best = dist; + reference = w; + } + } + + if ( width >= reference ) + { + width -= 0x21; + if ( width < reference ) + width = reference; + } + else + { + width += 0x21; + if ( width > reference ) + width = reference; + } + + return width; + } + +#endif /* 0 */ + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** BLUE ZONES *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + psh_blues_set_zones_0( PSH_Blues target, + FT_Bool is_others, + FT_UInt read_count, + FT_Short* read, + PSH_Blue_Table top_table, + PSH_Blue_Table bot_table ) + { + FT_UInt count_top = top_table->count; + FT_UInt count_bot = bot_table->count; + FT_Bool first = 1; + + FT_UNUSED( target ); + + + for ( ; read_count > 1; read_count -= 2 ) + { + FT_Int reference, delta; + FT_UInt count; + PSH_Blue_Zone zones, zone; + FT_Bool top; + + + /* read blue zone entry, and select target top/bottom zone */ + top = 0; + if ( first || is_others ) + { + reference = read[1]; + delta = read[0] - reference; + + zones = bot_table->zones; + count = count_bot; + first = 0; + } + else + { + reference = read[0]; + delta = read[1] - reference; + + zones = top_table->zones; + count = count_top; + top = 1; + } + + /* insert into sorted table */ + zone = zones; + for ( ; count > 0; count--, zone++ ) + { + if ( reference < zone->org_ref ) + break; + + if ( reference == zone->org_ref ) + { + FT_Int delta0 = zone->org_delta; + + + /* we have two zones on the same reference position -- */ + /* only keep the largest one */ + if ( delta < 0 ) + { + if ( delta < delta0 ) + zone->org_delta = delta; + } + else + { + if ( delta > delta0 ) + zone->org_delta = delta; + } + goto Skip; + } + } + + for ( ; count > 0; count-- ) + zone[count] = zone[count-1]; + + zone->org_ref = reference; + zone->org_delta = delta; + + if ( top ) + count_top++; + else + count_bot++; + + Skip: + read += 2; + } + + top_table->count = count_top; + bot_table->count = count_bot; + } + + + /* Re-read blue zones from the original fonts and store them into out */ + /* private structure. This function re-orders, sanitizes and */ + /* fuzz-expands the zones as well. */ + static void + psh_blues_set_zones( PSH_Blues target, + FT_UInt count, + FT_Short* blues, + FT_UInt count_others, + FT_Short* other_blues, + FT_Int fuzz, + FT_Int family ) + { + PSH_Blue_Table top_table, bot_table; + FT_Int count_top, count_bot; + + + if ( family ) + { + top_table = &target->family_top; + bot_table = &target->family_bottom; + } + else + { + top_table = &target->normal_top; + bot_table = &target->normal_bottom; + } + + /* read the input blue zones, and build two sorted tables */ + /* (one for the top zones, the other for the bottom zones) */ + top_table->count = 0; + bot_table->count = 0; + + /* first, the blues */ + psh_blues_set_zones_0( target, 0, + count, blues, top_table, bot_table ); + psh_blues_set_zones_0( target, 1, + count_others, other_blues, top_table, bot_table ); + + count_top = top_table->count; + count_bot = bot_table->count; + + /* sanitize top table */ + if ( count_top > 0 ) + { + PSH_Blue_Zone zone = top_table->zones; + + + for ( count = count_top; count > 0; count--, zone++ ) + { + FT_Int delta; + + + if ( count > 1 ) + { + delta = zone[1].org_ref - zone[0].org_ref; + if ( zone->org_delta > delta ) + zone->org_delta = delta; + } + + zone->org_bottom = zone->org_ref; + zone->org_top = zone->org_delta + zone->org_ref; + } + } + + /* sanitize bottom table */ + if ( count_bot > 0 ) + { + PSH_Blue_Zone zone = bot_table->zones; + + + for ( count = count_bot; count > 0; count--, zone++ ) + { + FT_Int delta; + + + if ( count > 1 ) + { + delta = zone[0].org_ref - zone[1].org_ref; + if ( zone->org_delta < delta ) + zone->org_delta = delta; + } + + zone->org_top = zone->org_ref; + zone->org_bottom = zone->org_delta + zone->org_ref; + } + } + + /* expand top and bottom tables with blue fuzz */ + { + FT_Int dim, top, bot, delta; + PSH_Blue_Zone zone; + + + zone = top_table->zones; + count = count_top; + + for ( dim = 1; dim >= 0; dim-- ) + { + if ( count > 0 ) + { + /* expand the bottom of the lowest zone normally */ + zone->org_bottom -= fuzz; + + /* expand the top and bottom of intermediate zones; */ + /* checking that the interval is smaller than the fuzz */ + top = zone->org_top; + + for ( count--; count > 0; count-- ) + { + bot = zone[1].org_bottom; + delta = bot - top; + + if ( delta < 2 * fuzz ) + zone[0].org_top = zone[1].org_bottom = top + delta / 2; + else + { + zone[0].org_top = top + fuzz; + zone[1].org_bottom = bot - fuzz; + } + + zone++; + top = zone->org_top; + } + + /* expand the top of the highest zone normally */ + zone->org_top = top + fuzz; + } + zone = bot_table->zones; + count = count_bot; + } + } + } + + + /* reset the blues table when the device transform changes */ + static void + psh_blues_scale_zones( PSH_Blues blues, + FT_Fixed scale, + FT_Pos delta ) + { + FT_UInt count; + FT_UInt num; + PSH_Blue_Table table = 0; + + /* */ + /* Determine whether we need to suppress overshoots or */ + /* not. We simply need to compare the vertical scale */ + /* parameter to the raw bluescale value. Here is why: */ + /* */ + /* We need to suppress overshoots for all pointsizes. */ + /* At 300dpi that satisfies: */ + /* */ + /* pointsize < 240*bluescale + 0.49 */ + /* */ + /* This corresponds to: */ + /* */ + /* pixelsize < 1000*bluescale + 49/24 */ + /* */ + /* scale*EM_Size < 1000*bluescale + 49/24 */ + /* */ + /* However, for normal Type 1 fonts, EM_Size is 1000! */ + /* We thus only check: */ + /* */ + /* scale < bluescale + 49/24000 */ + /* */ + /* which we shorten to */ + /* */ + /* "scale < bluescale" */ + /* */ + /* Note that `blue_scale' is stored 1000 times its real */ + /* value, and that `scale' converts from font units to */ + /* fractional pixels. */ + /* */ + + /* 1000 / 64 = 125 / 8 */ + if ( scale >= 0x20C49BAL ) + blues->no_overshoots = FT_BOOL( scale < blues->blue_scale * 8 / 125 ); + else + blues->no_overshoots = FT_BOOL( scale * 125 < blues->blue_scale * 8 ); + + /* */ + /* The blue threshold is the font units distance under */ + /* which overshoots are suppressed due to the BlueShift */ + /* even if the scale is greater than BlueScale. */ + /* */ + /* It is the smallest distance such that */ + /* */ + /* dist <= BlueShift && dist*scale <= 0.5 pixels */ + /* */ + { + FT_Int threshold = blues->blue_shift; + + + while ( threshold > 0 && FT_MulFix( threshold, scale ) > 32 ) + threshold--; + + blues->blue_threshold = threshold; + } + + for ( num = 0; num < 4; num++ ) + { + PSH_Blue_Zone zone; + + + switch ( num ) + { + case 0: + table = &blues->normal_top; + break; + case 1: + table = &blues->normal_bottom; + break; + case 2: + table = &blues->family_top; + break; + default: + table = &blues->family_bottom; + break; + } + + zone = table->zones; + count = table->count; + for ( ; count > 0; count--, zone++ ) + { + zone->cur_top = FT_MulFix( zone->org_top, scale ) + delta; + zone->cur_bottom = FT_MulFix( zone->org_bottom, scale ) + delta; + zone->cur_ref = FT_MulFix( zone->org_ref, scale ) + delta; + zone->cur_delta = FT_MulFix( zone->org_delta, scale ); + + /* round scaled reference position */ + zone->cur_ref = FT_PIX_ROUND( zone->cur_ref ); + +#if 0 + if ( zone->cur_ref > zone->cur_top ) + zone->cur_ref -= 64; + else if ( zone->cur_ref < zone->cur_bottom ) + zone->cur_ref += 64; +#endif + } + } + + /* process the families now */ + + for ( num = 0; num < 2; num++ ) + { + PSH_Blue_Zone zone1, zone2; + FT_UInt count1, count2; + PSH_Blue_Table normal, family; + + + switch ( num ) + { + case 0: + normal = &blues->normal_top; + family = &blues->family_top; + break; + + default: + normal = &blues->normal_bottom; + family = &blues->family_bottom; + } + + zone1 = normal->zones; + count1 = normal->count; + + for ( ; count1 > 0; count1--, zone1++ ) + { + /* try to find a family zone whose reference position is less */ + /* than 1 pixel far from the current zone */ + zone2 = family->zones; + count2 = family->count; + + for ( ; count2 > 0; count2--, zone2++ ) + { + FT_Pos Delta; + + + Delta = zone1->org_ref - zone2->org_ref; + if ( Delta < 0 ) + Delta = -Delta; + + if ( FT_MulFix( Delta, scale ) < 64 ) + { + zone1->cur_top = zone2->cur_top; + zone1->cur_bottom = zone2->cur_bottom; + zone1->cur_ref = zone2->cur_ref; + zone1->cur_delta = zone2->cur_delta; + break; + } + } + } + } + } + + + FT_LOCAL_DEF( void ) + psh_blues_snap_stem( PSH_Blues blues, + FT_Int stem_top, + FT_Int stem_bot, + PSH_Alignment alignment ) + { + PSH_Blue_Table table; + FT_UInt count; + FT_Pos delta; + PSH_Blue_Zone zone; + FT_Int no_shoots; + + + alignment->align = PSH_BLUE_ALIGN_NONE; + + no_shoots = blues->no_overshoots; + + /* look up stem top in top zones table */ + table = &blues->normal_top; + count = table->count; + zone = table->zones; + + for ( ; count > 0; count--, zone++ ) + { + delta = stem_top - zone->org_bottom; + if ( delta < -blues->blue_fuzz ) + break; + + if ( stem_top <= zone->org_top + blues->blue_fuzz ) + { + if ( no_shoots || delta <= blues->blue_threshold ) + { + alignment->align |= PSH_BLUE_ALIGN_TOP; + alignment->align_top = zone->cur_ref; + } + break; + } + } + + /* look up stem bottom in bottom zones table */ + table = &blues->normal_bottom; + count = table->count; + zone = table->zones + count-1; + + for ( ; count > 0; count--, zone-- ) + { + delta = zone->org_top - stem_bot; + if ( delta < -blues->blue_fuzz ) + break; + + if ( stem_bot >= zone->org_bottom - blues->blue_fuzz ) + { + if ( no_shoots || delta < blues->blue_threshold ) + { + alignment->align |= PSH_BLUE_ALIGN_BOT; + alignment->align_bot = zone->cur_ref; + } + break; + } + } + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GLOBAL HINTS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + psh_globals_destroy( PSH_Globals globals ) + { + if ( globals ) + { + FT_Memory memory; + + + memory = globals->memory; + globals->dimension[0].stdw.count = 0; + globals->dimension[1].stdw.count = 0; + + globals->blues.normal_top.count = 0; + globals->blues.normal_bottom.count = 0; + globals->blues.family_top.count = 0; + globals->blues.family_bottom.count = 0; + + FT_FREE( globals ); + +#ifdef DEBUG_HINTER + ps_debug_globals = 0; +#endif + } + } + + + static FT_Error + psh_globals_new( FT_Memory memory, + T1_Private* priv, + PSH_Globals *aglobals ) + { + PSH_Globals globals; + FT_Error error; + + + if ( !FT_NEW( globals ) ) + { + FT_UInt count; + FT_Short* read; + + + globals->memory = memory; + + /* copy standard widths */ + { + PSH_Dimension dim = &globals->dimension[1]; + PSH_Width write = dim->stdw.widths; + + + write->org = priv->standard_width[0]; + write++; + + read = priv->snap_widths; + for ( count = priv->num_snap_widths; count > 0; count-- ) + { + write->org = *read; + write++; + read++; + } + + dim->stdw.count = priv->num_snap_widths + 1; + } + + /* copy standard heights */ + { + PSH_Dimension dim = &globals->dimension[0]; + PSH_Width write = dim->stdw.widths; + + + write->org = priv->standard_height[0]; + write++; + read = priv->snap_heights; + for ( count = priv->num_snap_heights; count > 0; count-- ) + { + write->org = *read; + write++; + read++; + } + + dim->stdw.count = priv->num_snap_heights + 1; + } + + /* copy blue zones */ + psh_blues_set_zones( &globals->blues, priv->num_blue_values, + priv->blue_values, priv->num_other_blues, + priv->other_blues, priv->blue_fuzz, 0 ); + + psh_blues_set_zones( &globals->blues, priv->num_family_blues, + priv->family_blues, priv->num_family_other_blues, + priv->family_other_blues, priv->blue_fuzz, 1 ); + + globals->blues.blue_scale = priv->blue_scale; + globals->blues.blue_shift = priv->blue_shift; + globals->blues.blue_fuzz = priv->blue_fuzz; + + globals->dimension[0].scale_mult = 0; + globals->dimension[0].scale_delta = 0; + globals->dimension[1].scale_mult = 0; + globals->dimension[1].scale_delta = 0; + +#ifdef DEBUG_HINTER + ps_debug_globals = globals; +#endif + } + + *aglobals = globals; + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + psh_globals_set_scale( PSH_Globals globals, + FT_Fixed x_scale, + FT_Fixed y_scale, + FT_Fixed x_delta, + FT_Fixed y_delta ) + { + PSH_Dimension dim = &globals->dimension[0]; + + + dim = &globals->dimension[0]; + if ( x_scale != dim->scale_mult || + x_delta != dim->scale_delta ) + { + dim->scale_mult = x_scale; + dim->scale_delta = x_delta; + + psh_globals_scale_widths( globals, 0 ); + } + + dim = &globals->dimension[1]; + if ( y_scale != dim->scale_mult || + y_delta != dim->scale_delta ) + { + dim->scale_mult = y_scale; + dim->scale_delta = y_delta; + + psh_globals_scale_widths( globals, 1 ); + psh_blues_scale_zones( &globals->blues, y_scale, y_delta ); + } + + return 0; + } + + + FT_LOCAL_DEF( void ) + psh_globals_funcs_init( PSH_Globals_FuncsRec* funcs ) + { + funcs->create = psh_globals_new; + funcs->set_scale = psh_globals_set_scale; + funcs->destroy = psh_globals_destroy; + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/pshinter/pshglob.h b/mod/pub.mod/freetype.mod/src/pshinter/pshglob.h new file mode 100644 index 0000000..c511626 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/pshinter/pshglob.h @@ -0,0 +1,196 @@ +/***************************************************************************/ +/* */ +/* pshglob.h */ +/* */ +/* PostScript hinter global hinting management. */ +/* */ +/* Copyright 2001, 2002, 2003 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __PSHGLOB_H__ +#define __PSHGLOB_H__ + + +#include FT_FREETYPE_H +#include FT_INTERNAL_POSTSCRIPT_HINTS_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GLOBAL HINTS INTERNALS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* @constant: */ + /* PS_GLOBALS_MAX_BLUE_ZONES */ + /* */ + /* @description: */ + /* The maximum number of blue zones in a font global hints structure. */ + /* See @PS_Globals_BluesRec. */ + /* */ +#define PS_GLOBALS_MAX_BLUE_ZONES 16 + + + /*************************************************************************/ + /* */ + /* @constant: */ + /* PS_GLOBALS_MAX_STD_WIDTHS */ + /* */ + /* @description: */ + /* The maximum number of standard and snap widths in either the */ + /* horizontal or vertical direction. See @PS_Globals_WidthsRec. */ + /* */ +#define PS_GLOBALS_MAX_STD_WIDTHS 16 + + + /* standard and snap width */ + typedef struct PSH_WidthRec_ + { + FT_Int org; + FT_Pos cur; + FT_Pos fit; + + } PSH_WidthRec, *PSH_Width; + + + /* standard and snap widths table */ + typedef struct PSH_WidthsRec_ + { + FT_UInt count; + PSH_WidthRec widths[PS_GLOBALS_MAX_STD_WIDTHS]; + + } PSH_WidthsRec, *PSH_Widths; + + + typedef struct PSH_DimensionRec_ + { + PSH_WidthsRec stdw; + FT_Fixed scale_mult; + FT_Fixed scale_delta; + + } PSH_DimensionRec, *PSH_Dimension; + + + /* blue zone descriptor */ + typedef struct PSH_Blue_ZoneRec_ + { + FT_Int org_ref; + FT_Int org_delta; + FT_Int org_top; + FT_Int org_bottom; + + FT_Pos cur_ref; + FT_Pos cur_delta; + FT_Pos cur_bottom; + FT_Pos cur_top; + + } PSH_Blue_ZoneRec, *PSH_Blue_Zone; + + + typedef struct PSH_Blue_TableRec_ + { + FT_UInt count; + PSH_Blue_ZoneRec zones[PS_GLOBALS_MAX_BLUE_ZONES]; + + } PSH_Blue_TableRec, *PSH_Blue_Table; + + + /* blue zones table */ + typedef struct PSH_BluesRec_ + { + PSH_Blue_TableRec normal_top; + PSH_Blue_TableRec normal_bottom; + PSH_Blue_TableRec family_top; + PSH_Blue_TableRec family_bottom; + + FT_Fixed blue_scale; + FT_Int blue_shift; + FT_Int blue_threshold; + FT_Int blue_fuzz; + FT_Bool no_overshoots; + + } PSH_BluesRec, *PSH_Blues; + + + /* font globals. */ + /* dimension 0 => X coordinates + vertical hints/stems */ + /* dimension 1 => Y coordinates + horizontal hints/stems */ + typedef struct PSH_GlobalsRec_ + { + FT_Memory memory; + PSH_DimensionRec dimension[2]; + PSH_BluesRec blues; + + } PSH_GlobalsRec; + + +#define PSH_BLUE_ALIGN_NONE 0 +#define PSH_BLUE_ALIGN_TOP 1 +#define PSH_BLUE_ALIGN_BOT 2 + + + typedef struct PSH_AlignmentRec_ + { + int align; + FT_Pos align_top; + FT_Pos align_bot; + + } PSH_AlignmentRec, *PSH_Alignment; + + + FT_LOCAL( void ) + psh_globals_funcs_init( PSH_Globals_FuncsRec* funcs ); + + +#if 0 + /* snap a stem width to fitter coordinates. `org_width' is in font */ + /* units. The result is in device pixels (26.6 format). */ + FT_LOCAL( FT_Pos ) + psh_dimension_snap_width( PSH_Dimension dimension, + FT_Int org_width ); +#endif + + FT_LOCAL( FT_Error ) + psh_globals_set_scale( PSH_Globals globals, + FT_Fixed x_scale, + FT_Fixed y_scale, + FT_Fixed x_delta, + FT_Fixed y_delta ); + + /* snap a stem to one or two blue zones */ + FT_LOCAL( void ) + psh_blues_snap_stem( PSH_Blues blues, + FT_Int stem_top, + FT_Int stem_bot, + PSH_Alignment alignment ); + /* */ + +#ifdef DEBUG_HINTER + extern PSH_Globals ps_debug_globals; +#endif + + +FT_END_HEADER + + +#endif /* __PSHGLOB_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/pshinter/pshinter.c b/mod/pub.mod/freetype.mod/src/pshinter/pshinter.c new file mode 100644 index 0000000..b35a2a9 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/pshinter/pshinter.c @@ -0,0 +1,29 @@ +/***************************************************************************/ +/* */ +/* pshinter.c */ +/* */ +/* FreeType PostScript Hinting module */ +/* */ +/* Copyright 2001, 2003 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#define FT_MAKE_OPTION_SINGLE_OBJECT + +#include <ft2build.h> +#include "pshpic.c" +#include "pshrec.c" +#include "pshglob.c" +#include "pshalgo.c" +#include "pshmod.c" + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/pshinter/pshmod.c b/mod/pub.mod/freetype.mod/src/pshinter/pshmod.c new file mode 100644 index 0000000..91da5d7 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/pshinter/pshmod.c @@ -0,0 +1,118 @@ +/***************************************************************************/ +/* */ +/* pshmod.c */ +/* */ +/* FreeType PostScript hinter module implementation (body). */ +/* */ +/* Copyright 2001, 2002, 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H +#include "pshrec.h" +#include "pshalgo.h" +#include "pshpic.h" + + + /* the Postscript Hinter module structure */ + typedef struct PS_Hinter_Module_Rec_ + { + FT_ModuleRec root; + PS_HintsRec ps_hints; + + PSH_Globals_FuncsRec globals_funcs; + T1_Hints_FuncsRec t1_funcs; + T2_Hints_FuncsRec t2_funcs; + + } PS_Hinter_ModuleRec, *PS_Hinter_Module; + + + /* finalize module */ + FT_CALLBACK_DEF( void ) + ps_hinter_done( PS_Hinter_Module module ) + { + module->t1_funcs.hints = NULL; + module->t2_funcs.hints = NULL; + + ps_hints_done( &module->ps_hints ); + } + + + /* initialize module, create hints recorder and the interface */ + FT_CALLBACK_DEF( FT_Error ) + ps_hinter_init( PS_Hinter_Module module ) + { + FT_Memory memory = module->root.memory; + void* ph = &module->ps_hints; + + + ps_hints_init( &module->ps_hints, memory ); + + psh_globals_funcs_init( &module->globals_funcs ); + + t1_hints_funcs_init( &module->t1_funcs ); + module->t1_funcs.hints = (T1_Hints)ph; + + t2_hints_funcs_init( &module->t2_funcs ); + module->t2_funcs.hints = (T2_Hints)ph; + + return 0; + } + + + /* returns global hints interface */ + FT_CALLBACK_DEF( PSH_Globals_Funcs ) + pshinter_get_globals_funcs( FT_Module module ) + { + return &((PS_Hinter_Module)module)->globals_funcs; + } + + + /* return Type 1 hints interface */ + FT_CALLBACK_DEF( T1_Hints_Funcs ) + pshinter_get_t1_funcs( FT_Module module ) + { + return &((PS_Hinter_Module)module)->t1_funcs; + } + + + /* return Type 2 hints interface */ + FT_CALLBACK_DEF( T2_Hints_Funcs ) + pshinter_get_t2_funcs( FT_Module module ) + { + return &((PS_Hinter_Module)module)->t2_funcs; + } + + + FT_DEFINE_PSHINTER_INTERFACE(pshinter_interface, + pshinter_get_globals_funcs, + pshinter_get_t1_funcs, + pshinter_get_t2_funcs + ) + + + FT_DEFINE_MODULE(pshinter_module_class, + + 0, + sizeof ( PS_Hinter_ModuleRec ), + "pshinter", + 0x10000L, + 0x20000L, + + &FTPSHINTER_INTERFACE_GET, /* module-specific interface */ + + (FT_Module_Constructor)ps_hinter_init, + (FT_Module_Destructor) ps_hinter_done, + (FT_Module_Requester) 0 /* no additional interface for now */ + ) + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/pshinter/pshmod.h b/mod/pub.mod/freetype.mod/src/pshinter/pshmod.h new file mode 100644 index 0000000..0ae7e96 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/pshinter/pshmod.h @@ -0,0 +1,39 @@ +/***************************************************************************/ +/* */ +/* pshmod.h */ +/* */ +/* PostScript hinter module interface (specification). */ +/* */ +/* Copyright 2001 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __PSHMOD_H__ +#define __PSHMOD_H__ + + +#include <ft2build.h> +#include FT_MODULE_H + + +FT_BEGIN_HEADER + + + FT_DECLARE_MODULE( pshinter_module_class ) + + +FT_END_HEADER + + +#endif /* __PSHMOD_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/pshinter/pshnterr.h b/mod/pub.mod/freetype.mod/src/pshinter/pshnterr.h new file mode 100644 index 0000000..3c0029f --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/pshinter/pshnterr.h @@ -0,0 +1,40 @@ +/***************************************************************************/ +/* */ +/* pshnterr.h */ +/* */ +/* PS Hinter error codes (specification only). */ +/* */ +/* Copyright 2003 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file is used to define the PSHinter error enumeration constants. */ + /* */ + /*************************************************************************/ + +#ifndef __PSHNTERR_H__ +#define __PSHNTERR_H__ + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#define FT_ERR_PREFIX PSH_Err_ +#define FT_ERR_BASE FT_Mod_Err_PShinter + +#include FT_ERRORS_H + +#endif /* __PSHNTERR_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/pshinter/pshpic.c b/mod/pub.mod/freetype.mod/src/pshinter/pshpic.c new file mode 100644 index 0000000..51a0879 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/pshinter/pshpic.c @@ -0,0 +1,67 @@ +/***************************************************************************/ +/* */ +/* pshpic.c */ +/* */ +/* The FreeType position independent code services for pshinter module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include "pshpic.h" + +#ifdef FT_CONFIG_OPTION_PIC + + /* forward declaration of PIC init functions from pshmod.c */ + void FT_Init_Class_pshinter_interface( FT_Library, PSHinter_Interface*); + + void + pshinter_module_class_pic_free( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Memory memory = library->memory; + if ( pic_container->pshinter ) + { + FT_FREE( pic_container->pshinter ); + pic_container->pshinter = NULL; + } + } + + FT_Error + pshinter_module_class_pic_init( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Error error = FT_Err_Ok; + PSHinterPIC* container; + FT_Memory memory = library->memory; + + /* allocate pointer, clear and set global container pointer */ + if ( FT_ALLOC ( container, sizeof ( *container ) ) ) + return error; + FT_MEM_SET( container, 0, sizeof(*container) ); + pic_container->pshinter = container; + + /* add call to initialization function when you add new scripts */ + FT_Init_Class_pshinter_interface(library, &container->pshinter_interface); + +/*Exit:*/ + if(error) + pshinter_module_class_pic_free(library); + return error; + } + + +#endif /* FT_CONFIG_OPTION_PIC */ + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/pshinter/pshpic.h b/mod/pub.mod/freetype.mod/src/pshinter/pshpic.h new file mode 100644 index 0000000..3555d8e --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/pshinter/pshpic.h @@ -0,0 +1,53 @@ +/***************************************************************************/ +/* */ +/* pshpic.h */ +/* */ +/* The FreeType position independent code services for pshinter module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __PSHPIC_H__ +#define __PSHPIC_H__ + + +FT_BEGIN_HEADER + +#include FT_INTERNAL_PIC_H + +#ifndef FT_CONFIG_OPTION_PIC + +#define FTPSHINTER_INTERFACE_GET pshinter_interface + +#else /* FT_CONFIG_OPTION_PIC */ + +#include FT_INTERNAL_POSTSCRIPT_HINTS_H + + typedef struct PSHinterPIC_ + { + PSHinter_Interface pshinter_interface; + } PSHinterPIC; + +#define GET_PIC(lib) ((PSHinterPIC*)((lib)->pic_container.autofit)) +#define FTPSHINTER_INTERFACE_GET (GET_PIC(library)->pshinter_interface) + + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + +FT_END_HEADER + +#endif /* __PSHPIC_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/pshinter/pshrec.c b/mod/pub.mod/freetype.mod/src/pshinter/pshrec.c new file mode 100644 index 0000000..0910cc5 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/pshinter/pshrec.c @@ -0,0 +1,1224 @@ +/***************************************************************************/ +/* */ +/* pshrec.c */ +/* */ +/* FreeType PostScript hints recorder (body). */ +/* */ +/* Copyright 2001, 2002, 2003, 2004, 2007, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_CALC_H + +#include "pshrec.h" +#include "pshalgo.h" + +#include "pshnterr.h" + +#undef FT_COMPONENT +#define FT_COMPONENT trace_pshrec + +#ifdef DEBUG_HINTER + PS_Hints ps_debug_hints = 0; + int ps_debug_no_horz_hints = 0; + int ps_debug_no_vert_hints = 0; +#endif + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** PS_HINT MANAGEMENT *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* destroy hints table */ + static void + ps_hint_table_done( PS_Hint_Table table, + FT_Memory memory ) + { + FT_FREE( table->hints ); + table->num_hints = 0; + table->max_hints = 0; + } + + + /* ensure that a table can contain "count" elements */ + static FT_Error + ps_hint_table_ensure( PS_Hint_Table table, + FT_UInt count, + FT_Memory memory ) + { + FT_UInt old_max = table->max_hints; + FT_UInt new_max = count; + FT_Error error = PSH_Err_Ok; + + + if ( new_max > old_max ) + { + /* try to grow the table */ + new_max = FT_PAD_CEIL( new_max, 8 ); + if ( !FT_RENEW_ARRAY( table->hints, old_max, new_max ) ) + table->max_hints = new_max; + } + return error; + } + + + static FT_Error + ps_hint_table_alloc( PS_Hint_Table table, + FT_Memory memory, + PS_Hint *ahint ) + { + FT_Error error = PSH_Err_Ok; + FT_UInt count; + PS_Hint hint = 0; + + + count = table->num_hints; + count++; + + if ( count >= table->max_hints ) + { + error = ps_hint_table_ensure( table, count, memory ); + if ( error ) + goto Exit; + } + + hint = table->hints + count - 1; + hint->pos = 0; + hint->len = 0; + hint->flags = 0; + + table->num_hints = count; + + Exit: + *ahint = hint; + return error; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** PS_MASK MANAGEMENT *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* destroy mask */ + static void + ps_mask_done( PS_Mask mask, + FT_Memory memory ) + { + FT_FREE( mask->bytes ); + mask->num_bits = 0; + mask->max_bits = 0; + mask->end_point = 0; + } + + + /* ensure that a mask can contain "count" bits */ + static FT_Error + ps_mask_ensure( PS_Mask mask, + FT_UInt count, + FT_Memory memory ) + { + FT_UInt old_max = ( mask->max_bits + 7 ) >> 3; + FT_UInt new_max = ( count + 7 ) >> 3; + FT_Error error = PSH_Err_Ok; + + + if ( new_max > old_max ) + { + new_max = FT_PAD_CEIL( new_max, 8 ); + if ( !FT_RENEW_ARRAY( mask->bytes, old_max, new_max ) ) + mask->max_bits = new_max * 8; + } + return error; + } + + + /* test a bit value in a given mask */ + static FT_Int + ps_mask_test_bit( PS_Mask mask, + FT_Int idx ) + { + if ( (FT_UInt)idx >= mask->num_bits ) + return 0; + + return mask->bytes[idx >> 3] & ( 0x80 >> ( idx & 7 ) ); + } + + + /* clear a given bit */ + static void + ps_mask_clear_bit( PS_Mask mask, + FT_Int idx ) + { + FT_Byte* p; + + + if ( (FT_UInt)idx >= mask->num_bits ) + return; + + p = mask->bytes + ( idx >> 3 ); + p[0] = (FT_Byte)( p[0] & ~( 0x80 >> ( idx & 7 ) ) ); + } + + + /* set a given bit, possibly grow the mask */ + static FT_Error + ps_mask_set_bit( PS_Mask mask, + FT_Int idx, + FT_Memory memory ) + { + FT_Error error = PSH_Err_Ok; + FT_Byte* p; + + + if ( idx < 0 ) + goto Exit; + + if ( (FT_UInt)idx >= mask->num_bits ) + { + error = ps_mask_ensure( mask, idx + 1, memory ); + if ( error ) + goto Exit; + + mask->num_bits = idx + 1; + } + + p = mask->bytes + ( idx >> 3 ); + p[0] = (FT_Byte)( p[0] | ( 0x80 >> ( idx & 7 ) ) ); + + Exit: + return error; + } + + + /* destroy mask table */ + static void + ps_mask_table_done( PS_Mask_Table table, + FT_Memory memory ) + { + FT_UInt count = table->max_masks; + PS_Mask mask = table->masks; + + + for ( ; count > 0; count--, mask++ ) + ps_mask_done( mask, memory ); + + FT_FREE( table->masks ); + table->num_masks = 0; + table->max_masks = 0; + } + + + /* ensure that a mask table can contain "count" masks */ + static FT_Error + ps_mask_table_ensure( PS_Mask_Table table, + FT_UInt count, + FT_Memory memory ) + { + FT_UInt old_max = table->max_masks; + FT_UInt new_max = count; + FT_Error error = PSH_Err_Ok; + + + if ( new_max > old_max ) + { + new_max = FT_PAD_CEIL( new_max, 8 ); + if ( !FT_RENEW_ARRAY( table->masks, old_max, new_max ) ) + table->max_masks = new_max; + } + return error; + } + + + /* allocate a new mask in a table */ + static FT_Error + ps_mask_table_alloc( PS_Mask_Table table, + FT_Memory memory, + PS_Mask *amask ) + { + FT_UInt count; + FT_Error error = PSH_Err_Ok; + PS_Mask mask = 0; + + + count = table->num_masks; + count++; + + if ( count > table->max_masks ) + { + error = ps_mask_table_ensure( table, count, memory ); + if ( error ) + goto Exit; + } + + mask = table->masks + count - 1; + mask->num_bits = 0; + mask->end_point = 0; + table->num_masks = count; + + Exit: + *amask = mask; + return error; + } + + + /* return last hint mask in a table, create one if the table is empty */ + static FT_Error + ps_mask_table_last( PS_Mask_Table table, + FT_Memory memory, + PS_Mask *amask ) + { + FT_Error error = PSH_Err_Ok; + FT_UInt count; + PS_Mask mask; + + + count = table->num_masks; + if ( count == 0 ) + { + error = ps_mask_table_alloc( table, memory, &mask ); + if ( error ) + goto Exit; + } + else + mask = table->masks + count - 1; + + Exit: + *amask = mask; + return error; + } + + + /* set a new mask to a given bit range */ + static FT_Error + ps_mask_table_set_bits( PS_Mask_Table table, + const FT_Byte* source, + FT_UInt bit_pos, + FT_UInt bit_count, + FT_Memory memory ) + { + FT_Error error = PSH_Err_Ok; + PS_Mask mask; + + + error = ps_mask_table_last( table, memory, &mask ); + if ( error ) + goto Exit; + + error = ps_mask_ensure( mask, bit_count, memory ); + if ( error ) + goto Exit; + + mask->num_bits = bit_count; + + /* now, copy bits */ + { + FT_Byte* read = (FT_Byte*)source + ( bit_pos >> 3 ); + FT_Int rmask = 0x80 >> ( bit_pos & 7 ); + FT_Byte* write = mask->bytes; + FT_Int wmask = 0x80; + FT_Int val; + + + for ( ; bit_count > 0; bit_count-- ) + { + val = write[0] & ~wmask; + + if ( read[0] & rmask ) + val |= wmask; + + write[0] = (FT_Byte)val; + + rmask >>= 1; + if ( rmask == 0 ) + { + read++; + rmask = 0x80; + } + + wmask >>= 1; + if ( wmask == 0 ) + { + write++; + wmask = 0x80; + } + } + } + + Exit: + return error; + } + + + /* test whether two masks in a table intersect */ + static FT_Int + ps_mask_table_test_intersect( PS_Mask_Table table, + FT_Int index1, + FT_Int index2 ) + { + PS_Mask mask1 = table->masks + index1; + PS_Mask mask2 = table->masks + index2; + FT_Byte* p1 = mask1->bytes; + FT_Byte* p2 = mask2->bytes; + FT_UInt count1 = mask1->num_bits; + FT_UInt count2 = mask2->num_bits; + FT_UInt count; + + + count = ( count1 <= count2 ) ? count1 : count2; + for ( ; count >= 8; count -= 8 ) + { + if ( p1[0] & p2[0] ) + return 1; + + p1++; + p2++; + } + + if ( count == 0 ) + return 0; + + return ( p1[0] & p2[0] ) & ~( 0xFF >> count ); + } + + + /* merge two masks, used by ps_mask_table_merge_all */ + static FT_Error + ps_mask_table_merge( PS_Mask_Table table, + FT_Int index1, + FT_Int index2, + FT_Memory memory ) + { + FT_UInt temp; + FT_Error error = PSH_Err_Ok; + + + /* swap index1 and index2 so that index1 < index2 */ + if ( index1 > index2 ) + { + temp = index1; + index1 = index2; + index2 = temp; + } + + if ( index1 < index2 && index1 >= 0 && index2 < (FT_Int)table->num_masks ) + { + /* we need to merge the bitsets of index1 and index2 with a */ + /* simple union */ + PS_Mask mask1 = table->masks + index1; + PS_Mask mask2 = table->masks + index2; + FT_UInt count1 = mask1->num_bits; + FT_UInt count2 = mask2->num_bits; + FT_Int delta; + + + if ( count2 > 0 ) + { + FT_UInt pos; + FT_Byte* read; + FT_Byte* write; + + + /* if "count2" is greater than "count1", we need to grow the */ + /* first bitset, and clear the highest bits */ + if ( count2 > count1 ) + { + error = ps_mask_ensure( mask1, count2, memory ); + if ( error ) + goto Exit; + + for ( pos = count1; pos < count2; pos++ ) + ps_mask_clear_bit( mask1, pos ); + } + + /* merge (unite) the bitsets */ + read = mask2->bytes; + write = mask1->bytes; + pos = (FT_UInt)( ( count2 + 7 ) >> 3 ); + + for ( ; pos > 0; pos-- ) + { + write[0] = (FT_Byte)( write[0] | read[0] ); + write++; + read++; + } + } + + /* Now, remove "mask2" from the list. We need to keep the masks */ + /* sorted in order of importance, so move table elements. */ + mask2->num_bits = 0; + mask2->end_point = 0; + + delta = table->num_masks - 1 - index2; /* number of masks to move */ + if ( delta > 0 ) + { + /* move to end of table for reuse */ + PS_MaskRec dummy = *mask2; + + + ft_memmove( mask2, mask2 + 1, delta * sizeof ( PS_MaskRec ) ); + + mask2[delta] = dummy; + } + + table->num_masks--; + } + else + FT_TRACE0(( "ps_mask_table_merge: ignoring invalid indices (%d,%d)\n", + index1, index2 )); + + Exit: + return error; + } + + + /* Try to merge all masks in a given table. This is used to merge */ + /* all counter masks into independent counter "paths". */ + /* */ + static FT_Error + ps_mask_table_merge_all( PS_Mask_Table table, + FT_Memory memory ) + { + FT_Int index1, index2; + FT_Error error = PSH_Err_Ok; + + + for ( index1 = table->num_masks - 1; index1 > 0; index1-- ) + { + for ( index2 = index1 - 1; index2 >= 0; index2-- ) + { + if ( ps_mask_table_test_intersect( table, index1, index2 ) ) + { + error = ps_mask_table_merge( table, index2, index1, memory ); + if ( error ) + goto Exit; + + break; + } + } + } + + Exit: + return error; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** PS_DIMENSION MANAGEMENT *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + /* finalize a given dimension */ + static void + ps_dimension_done( PS_Dimension dimension, + FT_Memory memory ) + { + ps_mask_table_done( &dimension->counters, memory ); + ps_mask_table_done( &dimension->masks, memory ); + ps_hint_table_done( &dimension->hints, memory ); + } + + + /* initialize a given dimension */ + static void + ps_dimension_init( PS_Dimension dimension ) + { + dimension->hints.num_hints = 0; + dimension->masks.num_masks = 0; + dimension->counters.num_masks = 0; + } + + +#if 0 + + /* set a bit at a given index in the current hint mask */ + static FT_Error + ps_dimension_set_mask_bit( PS_Dimension dim, + FT_UInt idx, + FT_Memory memory ) + { + PS_Mask mask; + FT_Error error = PSH_Err_Ok; + + + /* get last hint mask */ + error = ps_mask_table_last( &dim->masks, memory, &mask ); + if ( error ) + goto Exit; + + error = ps_mask_set_bit( mask, idx, memory ); + + Exit: + return error; + } + +#endif + + /* set the end point in a mask, called from "End" & "Reset" methods */ + static void + ps_dimension_end_mask( PS_Dimension dim, + FT_UInt end_point ) + { + FT_UInt count = dim->masks.num_masks; + PS_Mask mask; + + + if ( count > 0 ) + { + mask = dim->masks.masks + count - 1; + mask->end_point = end_point; + } + } + + + /* set the end point in the current mask, then create a new empty one */ + /* (called by "Reset" method) */ + static FT_Error + ps_dimension_reset_mask( PS_Dimension dim, + FT_UInt end_point, + FT_Memory memory ) + { + PS_Mask mask; + + + /* end current mask */ + ps_dimension_end_mask( dim, end_point ); + + /* allocate new one */ + return ps_mask_table_alloc( &dim->masks, memory, &mask ); + } + + + /* set a new mask, called from the "T2Stem" method */ + static FT_Error + ps_dimension_set_mask_bits( PS_Dimension dim, + const FT_Byte* source, + FT_UInt source_pos, + FT_UInt source_bits, + FT_UInt end_point, + FT_Memory memory ) + { + FT_Error error = PSH_Err_Ok; + + + /* reset current mask, if any */ + error = ps_dimension_reset_mask( dim, end_point, memory ); + if ( error ) + goto Exit; + + /* set bits in new mask */ + error = ps_mask_table_set_bits( &dim->masks, source, + source_pos, source_bits, memory ); + + Exit: + return error; + } + + + /* add a new single stem (called from "T1Stem" method) */ + static FT_Error + ps_dimension_add_t1stem( PS_Dimension dim, + FT_Int pos, + FT_Int len, + FT_Memory memory, + FT_Int *aindex ) + { + FT_Error error = PSH_Err_Ok; + FT_UInt flags = 0; + + + /* detect ghost stem */ + if ( len < 0 ) + { + flags |= PS_HINT_FLAG_GHOST; + if ( len == -21 ) + { + flags |= PS_HINT_FLAG_BOTTOM; + pos += len; + } + len = 0; + } + + if ( aindex ) + *aindex = -1; + + /* now, lookup stem in the current hints table */ + { + PS_Mask mask; + FT_UInt idx; + FT_UInt max = dim->hints.num_hints; + PS_Hint hint = dim->hints.hints; + + + for ( idx = 0; idx < max; idx++, hint++ ) + { + if ( hint->pos == pos && hint->len == len ) + break; + } + + /* we need to create a new hint in the table */ + if ( idx >= max ) + { + error = ps_hint_table_alloc( &dim->hints, memory, &hint ); + if ( error ) + goto Exit; + + hint->pos = pos; + hint->len = len; + hint->flags = flags; + } + + /* now, store the hint in the current mask */ + error = ps_mask_table_last( &dim->masks, memory, &mask ); + if ( error ) + goto Exit; + + error = ps_mask_set_bit( mask, idx, memory ); + if ( error ) + goto Exit; + + if ( aindex ) + *aindex = (FT_Int)idx; + } + + Exit: + return error; + } + + + /* add a "hstem3/vstem3" counter to our dimension table */ + static FT_Error + ps_dimension_add_counter( PS_Dimension dim, + FT_Int hint1, + FT_Int hint2, + FT_Int hint3, + FT_Memory memory ) + { + FT_Error error = PSH_Err_Ok; + FT_UInt count = dim->counters.num_masks; + PS_Mask counter = dim->counters.masks; + + + /* try to find an existing counter mask that already uses */ + /* one of these stems here */ + for ( ; count > 0; count--, counter++ ) + { + if ( ps_mask_test_bit( counter, hint1 ) || + ps_mask_test_bit( counter, hint2 ) || + ps_mask_test_bit( counter, hint3 ) ) + break; + } + + /* create a new counter when needed */ + if ( count == 0 ) + { + error = ps_mask_table_alloc( &dim->counters, memory, &counter ); + if ( error ) + goto Exit; + } + + /* now, set the bits for our hints in the counter mask */ + error = ps_mask_set_bit( counter, hint1, memory ); + if ( error ) + goto Exit; + + error = ps_mask_set_bit( counter, hint2, memory ); + if ( error ) + goto Exit; + + error = ps_mask_set_bit( counter, hint3, memory ); + if ( error ) + goto Exit; + + Exit: + return error; + } + + + /* end of recording session for a given dimension */ + static FT_Error + ps_dimension_end( PS_Dimension dim, + FT_UInt end_point, + FT_Memory memory ) + { + /* end hint mask table */ + ps_dimension_end_mask( dim, end_point ); + + /* merge all counter masks into independent "paths" */ + return ps_mask_table_merge_all( &dim->counters, memory ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** PS_RECORDER MANAGEMENT *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + /* destroy hints */ + FT_LOCAL( void ) + ps_hints_done( PS_Hints hints ) + { + FT_Memory memory = hints->memory; + + + ps_dimension_done( &hints->dimension[0], memory ); + ps_dimension_done( &hints->dimension[1], memory ); + + hints->error = PSH_Err_Ok; + hints->memory = 0; + } + + + FT_LOCAL( FT_Error ) + ps_hints_init( PS_Hints hints, + FT_Memory memory ) + { + FT_MEM_ZERO( hints, sizeof ( *hints ) ); + hints->memory = memory; + return PSH_Err_Ok; + } + + + /* initialize a hints for a new session */ + static void + ps_hints_open( PS_Hints hints, + PS_Hint_Type hint_type ) + { + switch ( hint_type ) + { + case PS_HINT_TYPE_1: + case PS_HINT_TYPE_2: + hints->error = PSH_Err_Ok; + hints->hint_type = hint_type; + + ps_dimension_init( &hints->dimension[0] ); + ps_dimension_init( &hints->dimension[1] ); + break; + + default: + hints->error = PSH_Err_Invalid_Argument; + hints->hint_type = hint_type; + + FT_TRACE0(( "ps_hints_open: invalid charstring type\n" )); + break; + } + } + + + /* add one or more stems to the current hints table */ + static void + ps_hints_stem( PS_Hints hints, + FT_Int dimension, + FT_UInt count, + FT_Long* stems ) + { + if ( !hints->error ) + { + /* limit "dimension" to 0..1 */ + if ( dimension < 0 || dimension > 1 ) + { + FT_TRACE0(( "ps_hints_stem: invalid dimension (%d) used\n", + dimension )); + dimension = ( dimension != 0 ); + } + + /* record the stems in the current hints/masks table */ + switch ( hints->hint_type ) + { + case PS_HINT_TYPE_1: /* Type 1 "hstem" or "vstem" operator */ + case PS_HINT_TYPE_2: /* Type 2 "hstem" or "vstem" operator */ + { + PS_Dimension dim = &hints->dimension[dimension]; + + + for ( ; count > 0; count--, stems += 2 ) + { + FT_Error error; + FT_Memory memory = hints->memory; + + + error = ps_dimension_add_t1stem( + dim, (FT_Int)stems[0], (FT_Int)stems[1], + memory, NULL ); + if ( error ) + { + FT_ERROR(( "ps_hints_stem: could not add stem" + " (%d,%d) to hints table\n", stems[0], stems[1] )); + + hints->error = error; + return; + } + } + break; + } + + default: + FT_TRACE0(( "ps_hints_stem: called with invalid hint type (%d)\n", + hints->hint_type )); + break; + } + } + } + + + /* add one Type1 counter stem to the current hints table */ + static void + ps_hints_t1stem3( PS_Hints hints, + FT_Int dimension, + FT_Fixed* stems ) + { + FT_Error error = PSH_Err_Ok; + + + if ( !hints->error ) + { + PS_Dimension dim; + FT_Memory memory = hints->memory; + FT_Int count; + FT_Int idx[3]; + + + /* limit "dimension" to 0..1 */ + if ( dimension < 0 || dimension > 1 ) + { + FT_TRACE0(( "ps_hints_t1stem3: invalid dimension (%d) used\n", + dimension )); + dimension = ( dimension != 0 ); + } + + dim = &hints->dimension[dimension]; + + /* there must be 6 elements in the 'stem' array */ + if ( hints->hint_type == PS_HINT_TYPE_1 ) + { + /* add the three stems to our hints/masks table */ + for ( count = 0; count < 3; count++, stems += 2 ) + { + error = ps_dimension_add_t1stem( dim, + (FT_Int)FIXED_TO_INT( stems[0] ), + (FT_Int)FIXED_TO_INT( stems[1] ), + memory, &idx[count] ); + if ( error ) + goto Fail; + } + + /* now, add the hints to the counters table */ + error = ps_dimension_add_counter( dim, idx[0], idx[1], idx[2], + memory ); + if ( error ) + goto Fail; + } + else + { + FT_ERROR(( "ps_hints_t1stem3: called with invalid hint type\n" )); + error = PSH_Err_Invalid_Argument; + goto Fail; + } + } + + return; + + Fail: + FT_ERROR(( "ps_hints_t1stem3: could not add counter stems to table\n" )); + hints->error = error; + } + + + /* reset hints (only with Type 1 hints) */ + static void + ps_hints_t1reset( PS_Hints hints, + FT_UInt end_point ) + { + FT_Error error = PSH_Err_Ok; + + + if ( !hints->error ) + { + FT_Memory memory = hints->memory; + + + if ( hints->hint_type == PS_HINT_TYPE_1 ) + { + error = ps_dimension_reset_mask( &hints->dimension[0], + end_point, memory ); + if ( error ) + goto Fail; + + error = ps_dimension_reset_mask( &hints->dimension[1], + end_point, memory ); + if ( error ) + goto Fail; + } + else + { + /* invalid hint type */ + error = PSH_Err_Invalid_Argument; + goto Fail; + } + } + return; + + Fail: + hints->error = error; + } + + + /* Type2 "hintmask" operator, add a new hintmask to each direction */ + static void + ps_hints_t2mask( PS_Hints hints, + FT_UInt end_point, + FT_UInt bit_count, + const FT_Byte* bytes ) + { + FT_Error error; + + + if ( !hints->error ) + { + PS_Dimension dim = hints->dimension; + FT_Memory memory = hints->memory; + FT_UInt count1 = dim[0].hints.num_hints; + FT_UInt count2 = dim[1].hints.num_hints; + + + /* check bit count; must be equal to current total hint count */ + if ( bit_count != count1 + count2 ) + { + FT_TRACE0(( "ps_hints_t2mask:" + " called with invalid bitcount %d (instead of %d)\n", + bit_count, count1 + count2 )); + + /* simply ignore the operator */ + return; + } + + /* set-up new horizontal and vertical hint mask now */ + error = ps_dimension_set_mask_bits( &dim[0], bytes, count2, count1, + end_point, memory ); + if ( error ) + goto Fail; + + error = ps_dimension_set_mask_bits( &dim[1], bytes, 0, count2, + end_point, memory ); + if ( error ) + goto Fail; + } + return; + + Fail: + hints->error = error; + } + + + static void + ps_hints_t2counter( PS_Hints hints, + FT_UInt bit_count, + const FT_Byte* bytes ) + { + FT_Error error; + + + if ( !hints->error ) + { + PS_Dimension dim = hints->dimension; + FT_Memory memory = hints->memory; + FT_UInt count1 = dim[0].hints.num_hints; + FT_UInt count2 = dim[1].hints.num_hints; + + + /* check bit count, must be equal to current total hint count */ + if ( bit_count != count1 + count2 ) + { + FT_TRACE0(( "ps_hints_t2counter:" + " called with invalid bitcount %d (instead of %d)\n", + bit_count, count1 + count2 )); + + /* simply ignore the operator */ + return; + } + + /* set-up new horizontal and vertical hint mask now */ + error = ps_dimension_set_mask_bits( &dim[0], bytes, 0, count1, + 0, memory ); + if ( error ) + goto Fail; + + error = ps_dimension_set_mask_bits( &dim[1], bytes, count1, count2, + 0, memory ); + if ( error ) + goto Fail; + } + return; + + Fail: + hints->error = error; + } + + + /* end recording session */ + static FT_Error + ps_hints_close( PS_Hints hints, + FT_UInt end_point ) + { + FT_Error error; + + + error = hints->error; + if ( !error ) + { + FT_Memory memory = hints->memory; + PS_Dimension dim = hints->dimension; + + + error = ps_dimension_end( &dim[0], end_point, memory ); + if ( !error ) + { + error = ps_dimension_end( &dim[1], end_point, memory ); + } + } + +#ifdef DEBUG_HINTER + if ( !error ) + ps_debug_hints = hints; +#endif + return error; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** TYPE 1 HINTS RECORDING INTERFACE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + t1_hints_open( T1_Hints hints ) + { + ps_hints_open( (PS_Hints)hints, PS_HINT_TYPE_1 ); + } + + static void + t1_hints_stem( T1_Hints hints, + FT_Int dimension, + FT_Fixed* coords ) + { + FT_Pos stems[2]; + + + stems[0] = FIXED_TO_INT( coords[0] ); + stems[1] = FIXED_TO_INT( coords[1] ); + + ps_hints_stem( (PS_Hints)hints, dimension, 1, stems ); + } + + + FT_LOCAL_DEF( void ) + t1_hints_funcs_init( T1_Hints_FuncsRec* funcs ) + { + FT_MEM_ZERO( (char*)funcs, sizeof ( *funcs ) ); + + funcs->open = (T1_Hints_OpenFunc) t1_hints_open; + funcs->close = (T1_Hints_CloseFunc) ps_hints_close; + funcs->stem = (T1_Hints_SetStemFunc) t1_hints_stem; + funcs->stem3 = (T1_Hints_SetStem3Func)ps_hints_t1stem3; + funcs->reset = (T1_Hints_ResetFunc) ps_hints_t1reset; + funcs->apply = (T1_Hints_ApplyFunc) ps_hints_apply; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** TYPE 2 HINTS RECORDING INTERFACE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + t2_hints_open( T2_Hints hints ) + { + ps_hints_open( (PS_Hints)hints, PS_HINT_TYPE_2 ); + } + + + static void + t2_hints_stems( T2_Hints hints, + FT_Int dimension, + FT_Int count, + FT_Fixed* coords ) + { + FT_Pos stems[32], y, n; + FT_Int total = count; + + + y = 0; + while ( total > 0 ) + { + /* determine number of stems to write */ + count = total; + if ( count > 16 ) + count = 16; + + /* compute integer stem positions in font units */ + for ( n = 0; n < count * 2; n++ ) + { + y += coords[n]; + stems[n] = FIXED_TO_INT( y ); + } + + /* compute lengths */ + for ( n = 0; n < count * 2; n += 2 ) + stems[n + 1] = stems[n + 1] - stems[n]; + + /* add them to the current dimension */ + ps_hints_stem( (PS_Hints)hints, dimension, count, stems ); + + total -= count; + } + } + + + FT_LOCAL_DEF( void ) + t2_hints_funcs_init( T2_Hints_FuncsRec* funcs ) + { + FT_MEM_ZERO( funcs, sizeof ( *funcs ) ); + + funcs->open = (T2_Hints_OpenFunc) t2_hints_open; + funcs->close = (T2_Hints_CloseFunc) ps_hints_close; + funcs->stems = (T2_Hints_StemsFunc) t2_hints_stems; + funcs->hintmask= (T2_Hints_MaskFunc) ps_hints_t2mask; + funcs->counter = (T2_Hints_CounterFunc)ps_hints_t2counter; + funcs->apply = (T2_Hints_ApplyFunc) ps_hints_apply; + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/pshinter/pshrec.h b/mod/pub.mod/freetype.mod/src/pshinter/pshrec.h new file mode 100644 index 0000000..dcb3197 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/pshinter/pshrec.h @@ -0,0 +1,176 @@ +/***************************************************************************/ +/* */ +/* pshrec.h */ +/* */ +/* Postscript (Type1/Type2) hints recorder (specification). */ +/* */ +/* Copyright 2001, 2002, 2003, 2006, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /**************************************************************************/ + /* */ + /* The functions defined here are called from the Type 1, CID and CFF */ + /* font drivers to record the hints of a given character/glyph. */ + /* */ + /* The hints are recorded in a unified format, and are later processed */ + /* by the `optimizer' and `fitter' to adjust the outlines to the pixel */ + /* grid. */ + /* */ + /**************************************************************************/ + + +#ifndef __PSHREC_H__ +#define __PSHREC_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_POSTSCRIPT_HINTS_H +#include "pshglob.h" + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GLYPH HINTS RECORDER INTERNALS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* handle to hint record */ + typedef struct PS_HintRec_* PS_Hint; + + /* hint types */ + typedef enum PS_Hint_Type_ + { + PS_HINT_TYPE_1 = 1, + PS_HINT_TYPE_2 = 2 + + } PS_Hint_Type; + + + /* hint flags */ + typedef enum PS_Hint_Flags_ + { + PS_HINT_FLAG_GHOST = 1, + PS_HINT_FLAG_BOTTOM = 2 + + } PS_Hint_Flags; + + + /* hint descriptor */ + typedef struct PS_HintRec_ + { + FT_Int pos; + FT_Int len; + FT_UInt flags; + + } PS_HintRec; + + +#define ps_hint_is_active( x ) ( (x)->flags & PS_HINT_FLAG_ACTIVE ) +#define ps_hint_is_ghost( x ) ( (x)->flags & PS_HINT_FLAG_GHOST ) +#define ps_hint_is_bottom( x ) ( (x)->flags & PS_HINT_FLAG_BOTTOM ) + + + /* hints table descriptor */ + typedef struct PS_Hint_TableRec_ + { + FT_UInt num_hints; + FT_UInt max_hints; + PS_Hint hints; + + } PS_Hint_TableRec, *PS_Hint_Table; + + + /* hint and counter mask descriptor */ + typedef struct PS_MaskRec_ + { + FT_UInt num_bits; + FT_UInt max_bits; + FT_Byte* bytes; + FT_UInt end_point; + + } PS_MaskRec, *PS_Mask; + + + /* masks and counters table descriptor */ + typedef struct PS_Mask_TableRec_ + { + FT_UInt num_masks; + FT_UInt max_masks; + PS_Mask masks; + + } PS_Mask_TableRec, *PS_Mask_Table; + + + /* dimension-specific hints descriptor */ + typedef struct PS_DimensionRec_ + { + PS_Hint_TableRec hints; + PS_Mask_TableRec masks; + PS_Mask_TableRec counters; + + } PS_DimensionRec, *PS_Dimension; + + + /* glyph hints descriptor */ + /* dimension 0 => X coordinates + vertical hints/stems */ + /* dimension 1 => Y coordinates + horizontal hints/stems */ + typedef struct PS_HintsRec_ + { + FT_Memory memory; + FT_Error error; + FT_UInt32 magic; + PS_Hint_Type hint_type; + PS_DimensionRec dimension[2]; + + } PS_HintsRec, *PS_Hints; + + /* */ + + /* initialize hints recorder */ + FT_LOCAL( FT_Error ) + ps_hints_init( PS_Hints hints, + FT_Memory memory ); + + /* finalize hints recorder */ + FT_LOCAL( void ) + ps_hints_done( PS_Hints hints ); + + /* initialize Type1 hints recorder interface */ + FT_LOCAL( void ) + t1_hints_funcs_init( T1_Hints_FuncsRec* funcs ); + + /* initialize Type2 hints recorder interface */ + FT_LOCAL( void ) + t2_hints_funcs_init( T2_Hints_FuncsRec* funcs ); + + +#ifdef DEBUG_HINTER + extern PS_Hints ps_debug_hints; + extern int ps_debug_no_horz_hints; + extern int ps_debug_no_vert_hints; +#endif + + /* */ + + +FT_END_HEADER + + +#endif /* __PS_HINTER_RECORD_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/psnames/psmodule.c b/mod/pub.mod/freetype.mod/src/psnames/psmodule.c new file mode 100644 index 0000000..3518850 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/psnames/psmodule.c @@ -0,0 +1,596 @@ +/***************************************************************************/ +/* */ +/* psmodule.c */ +/* */ +/* PSNames module implementation (body). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2005, 2006, 2007, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H +#include FT_SERVICE_POSTSCRIPT_CMAPS_H + +#include "psmodule.h" +#include "pstables.h" + +#include "psnamerr.h" +#include "pspic.h" + + +#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES + + +#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST + + +#define VARIANT_BIT 0x80000000UL +#define BASE_GLYPH( code ) ( (FT_UInt32)( (code) & ~VARIANT_BIT ) ) + + + /* Return the Unicode value corresponding to a given glyph. Note that */ + /* we do deal with glyph variants by detecting a non-initial dot in */ + /* the name, as in `A.swash' or `e.final'; in this case, the */ + /* VARIANT_BIT is set in the return value. */ + /* */ + static FT_UInt32 + ps_unicode_value( const char* glyph_name ) + { + /* If the name begins with `uni', then the glyph name may be a */ + /* hard-coded unicode character code. */ + if ( glyph_name[0] == 'u' && + glyph_name[1] == 'n' && + glyph_name[2] == 'i' ) + { + /* determine whether the next four characters following are */ + /* hexadecimal. */ + + /* XXX: Add code to deal with ligatures, i.e. glyph names like */ + /* `uniXXXXYYYYZZZZ'... */ + + FT_Int count; + FT_UInt32 value = 0; + const char* p = glyph_name + 3; + + + for ( count = 4; count > 0; count--, p++ ) + { + char c = *p; + unsigned int d; + + + d = (unsigned char)c - '0'; + if ( d >= 10 ) + { + d = (unsigned char)c - 'A'; + if ( d >= 6 ) + d = 16; + else + d += 10; + } + + /* Exit if a non-uppercase hexadecimal character was found */ + /* -- this also catches character codes below `0' since such */ + /* negative numbers cast to `unsigned int' are far too big. */ + if ( d >= 16 ) + break; + + value = ( value << 4 ) + d; + } + + /* there must be exactly four hex digits */ + if ( count == 0 ) + { + if ( *p == '\0' ) + return value; + if ( *p == '.' ) + return (FT_UInt32)( value | VARIANT_BIT ); + } + } + + /* If the name begins with `u', followed by four to six uppercase */ + /* hexadecimal digits, it is a hard-coded unicode character code. */ + if ( glyph_name[0] == 'u' ) + { + FT_Int count; + FT_UInt32 value = 0; + const char* p = glyph_name + 1; + + + for ( count = 6; count > 0; count--, p++ ) + { + char c = *p; + unsigned int d; + + + d = (unsigned char)c - '0'; + if ( d >= 10 ) + { + d = (unsigned char)c - 'A'; + if ( d >= 6 ) + d = 16; + else + d += 10; + } + + if ( d >= 16 ) + break; + + value = ( value << 4 ) + d; + } + + if ( count <= 2 ) + { + if ( *p == '\0' ) + return value; + if ( *p == '.' ) + return (FT_UInt32)( value | VARIANT_BIT ); + } + } + + /* Look for a non-initial dot in the glyph name in order to */ + /* find variants like `A.swash', `e.final', etc. */ + { + const char* p = glyph_name; + const char* dot = NULL; + + + for ( ; *p; p++ ) + { + if ( *p == '.' && p > glyph_name ) + { + dot = p; + break; + } + } + + /* now look up the glyph in the Adobe Glyph List */ + if ( !dot ) + return (FT_UInt32)ft_get_adobe_glyph_index( glyph_name, p ); + else + return (FT_UInt32)( ft_get_adobe_glyph_index( glyph_name, dot ) | + VARIANT_BIT ); + } + } + + + /* ft_qsort callback to sort the unicode map */ + FT_CALLBACK_DEF( int ) + compare_uni_maps( const void* a, + const void* b ) + { + PS_UniMap* map1 = (PS_UniMap*)a; + PS_UniMap* map2 = (PS_UniMap*)b; + FT_UInt32 unicode1 = BASE_GLYPH( map1->unicode ); + FT_UInt32 unicode2 = BASE_GLYPH( map2->unicode ); + + + /* sort base glyphs before glyph variants */ + if ( unicode1 == unicode2 ) + { + if ( map1->unicode > map2->unicode ) + return 1; + else if ( map1->unicode < map2->unicode ) + return -1; + else + return 0; + } + else + { + if ( unicode1 > unicode2 ) + return 1; + else if ( unicode1 < unicode2 ) + return -1; + else + return 0; + } + } + + + /* support for extra glyphs not handled (well) in AGL; */ + /* we add extra mappings for them if necessary */ + +#define EXTRA_GLYPH_LIST_SIZE 10 + + static const FT_UInt32 ft_extra_glyph_unicodes[EXTRA_GLYPH_LIST_SIZE] = + { + /* WGL 4 */ + 0x0394, + 0x03A9, + 0x2215, + 0x00AD, + 0x02C9, + 0x03BC, + 0x2219, + 0x00A0, + /* Romanian */ + 0x021A, + 0x021B + }; + + static const char ft_extra_glyph_names[] = + { + 'D','e','l','t','a',0, + 'O','m','e','g','a',0, + 'f','r','a','c','t','i','o','n',0, + 'h','y','p','h','e','n',0, + 'm','a','c','r','o','n',0, + 'm','u',0, + 'p','e','r','i','o','d','c','e','n','t','e','r','e','d',0, + 's','p','a','c','e',0, + 'T','c','o','m','m','a','a','c','c','e','n','t',0, + 't','c','o','m','m','a','a','c','c','e','n','t',0 + }; + + static const FT_Int + ft_extra_glyph_name_offsets[EXTRA_GLYPH_LIST_SIZE] = + { + 0, + 6, + 12, + 21, + 28, + 35, + 38, + 53, + 59, + 72 + }; + + + static void + ps_check_extra_glyph_name( const char* gname, + FT_UInt glyph, + FT_UInt* extra_glyphs, + FT_UInt *states ) + { + FT_UInt n; + + + for ( n = 0; n < EXTRA_GLYPH_LIST_SIZE; n++ ) + { + if ( ft_strcmp( ft_extra_glyph_names + + ft_extra_glyph_name_offsets[n], gname ) == 0 ) + { + if ( states[n] == 0 ) + { + /* mark this extra glyph as a candidate for the cmap */ + states[n] = 1; + extra_glyphs[n] = glyph; + } + + return; + } + } + } + + + static void + ps_check_extra_glyph_unicode( FT_UInt32 uni_char, + FT_UInt *states ) + { + FT_UInt n; + + + for ( n = 0; n < EXTRA_GLYPH_LIST_SIZE; n++ ) + { + if ( uni_char == ft_extra_glyph_unicodes[n] ) + { + /* disable this extra glyph from being added to the cmap */ + states[n] = 2; + + return; + } + } + } + + + /* Build a table that maps Unicode values to glyph indices. */ + static FT_Error + ps_unicodes_init( FT_Memory memory, + PS_Unicodes table, + FT_UInt num_glyphs, + PS_GetGlyphNameFunc get_glyph_name, + PS_FreeGlyphNameFunc free_glyph_name, + FT_Pointer glyph_data ) + { + FT_Error error; + + FT_UInt extra_glyph_list_states[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + FT_UInt extra_glyphs[EXTRA_GLYPH_LIST_SIZE]; + + + /* we first allocate the table */ + table->num_maps = 0; + table->maps = 0; + + if ( !FT_NEW_ARRAY( table->maps, num_glyphs + EXTRA_GLYPH_LIST_SIZE ) ) + { + FT_UInt n; + FT_UInt count; + PS_UniMap* map; + FT_UInt32 uni_char; + + + map = table->maps; + + for ( n = 0; n < num_glyphs; n++ ) + { + const char* gname = get_glyph_name( glyph_data, n ); + + + if ( gname ) + { + ps_check_extra_glyph_name( gname, n, + extra_glyphs, extra_glyph_list_states ); + uni_char = ps_unicode_value( gname ); + + if ( BASE_GLYPH( uni_char ) != 0 ) + { + ps_check_extra_glyph_unicode( uni_char, + extra_glyph_list_states ); + map->unicode = uni_char; + map->glyph_index = n; + map++; + } + + if ( free_glyph_name ) + free_glyph_name( glyph_data, gname ); + } + } + + for ( n = 0; n < EXTRA_GLYPH_LIST_SIZE; n++ ) + { + if ( extra_glyph_list_states[n] == 1 ) + { + /* This glyph name has an additional representation. */ + /* Add it to the cmap. */ + + map->unicode = ft_extra_glyph_unicodes[n]; + map->glyph_index = extra_glyphs[n]; + map++; + } + } + + /* now compress the table a bit */ + count = (FT_UInt)( map - table->maps ); + + if ( count == 0 ) + { + FT_FREE( table->maps ); + if ( !error ) + error = PSnames_Err_Invalid_Argument; /* No unicode chars here! */ + } + else { + /* Reallocate if the number of used entries is much smaller. */ + if ( count < num_glyphs / 2 ) + { + (void)FT_RENEW_ARRAY( table->maps, num_glyphs, count ); + error = PSnames_Err_Ok; + } + + /* Sort the table in increasing order of unicode values, */ + /* taking care of glyph variants. */ + ft_qsort( table->maps, count, sizeof ( PS_UniMap ), + compare_uni_maps ); + } + + table->num_maps = count; + } + + return error; + } + + + static FT_UInt + ps_unicodes_char_index( PS_Unicodes table, + FT_UInt32 unicode ) + { + PS_UniMap *min, *max, *mid, *result = NULL; + + + /* Perform a binary search on the table. */ + + min = table->maps; + max = min + table->num_maps - 1; + + while ( min <= max ) + { + FT_UInt32 base_glyph; + + + mid = min + ( ( max - min ) >> 1 ); + + if ( mid->unicode == unicode ) + { + result = mid; + break; + } + + base_glyph = BASE_GLYPH( mid->unicode ); + + if ( base_glyph == unicode ) + result = mid; /* remember match but continue search for base glyph */ + + if ( min == max ) + break; + + if ( base_glyph < unicode ) + min = mid + 1; + else + max = mid - 1; + } + + if ( result ) + return result->glyph_index; + else + return 0; + } + + + static FT_UInt32 + ps_unicodes_char_next( PS_Unicodes table, + FT_UInt32 *unicode ) + { + FT_UInt result = 0; + FT_UInt32 char_code = *unicode + 1; + + + { + FT_UInt min = 0; + FT_UInt max = table->num_maps; + FT_UInt mid; + PS_UniMap* map; + FT_UInt32 base_glyph; + + + while ( min < max ) + { + mid = min + ( ( max - min ) >> 1 ); + map = table->maps + mid; + + if ( map->unicode == char_code ) + { + result = map->glyph_index; + goto Exit; + } + + base_glyph = BASE_GLYPH( map->unicode ); + + if ( base_glyph == char_code ) + result = map->glyph_index; + + if ( base_glyph < char_code ) + min = mid + 1; + else + max = mid; + } + + if ( result ) + goto Exit; /* we have a variant glyph */ + + /* we didn't find it; check whether we have a map just above it */ + char_code = 0; + + if ( min < table->num_maps ) + { + map = table->maps + min; + result = map->glyph_index; + char_code = BASE_GLYPH( map->unicode ); + } + } + + Exit: + *unicode = char_code; + return result; + } + + +#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ + + + static const char* + ps_get_macintosh_name( FT_UInt name_index ) + { + if ( name_index >= FT_NUM_MAC_NAMES ) + name_index = 0; + + return ft_standard_glyph_names + ft_mac_names[name_index]; + } + + + static const char* + ps_get_standard_strings( FT_UInt sid ) + { + if ( sid >= FT_NUM_SID_NAMES ) + return 0; + + return ft_standard_glyph_names + ft_sid_names[sid]; + } + + +#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST + FT_DEFINE_SERVICE_PSCMAPSREC(pscmaps_interface, + (PS_Unicode_ValueFunc) ps_unicode_value, + (PS_Unicodes_InitFunc) ps_unicodes_init, + (PS_Unicodes_CharIndexFunc)ps_unicodes_char_index, + (PS_Unicodes_CharNextFunc) ps_unicodes_char_next, + + (PS_Macintosh_NameFunc) ps_get_macintosh_name, + (PS_Adobe_Std_StringsFunc) ps_get_standard_strings, + + t1_standard_encoding, + t1_expert_encoding + ) + +#else + + FT_DEFINE_SERVICE_PSCMAPSREC(pscmaps_interface, + 0, + 0, + 0, + 0, + + (PS_Macintosh_NameFunc) ps_get_macintosh_name, + (PS_Adobe_Std_StringsFunc) ps_get_standard_strings, + + t1_standard_encoding, + t1_expert_encoding + ) + +#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ + + + FT_DEFINE_SERVICEDESCREC1(pscmaps_services, + FT_SERVICE_ID_POSTSCRIPT_CMAPS, &FT_PSCMAPS_INTERFACE_GET + ) + + + + + static FT_Pointer + psnames_get_service( FT_Module module, + const char* service_id ) + { + FT_Library library = module->library; + FT_UNUSED(library); + + return ft_service_list_lookup( FT_PSCMAPS_SERVICES_GET, service_id ); + } + +#endif /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */ + + +#ifndef FT_CONFIG_OPTION_POSTSCRIPT_NAMES +#define PUT_PS_NAMES_SERVICE(a) 0 +#else +#define PUT_PS_NAMES_SERVICE(a) a +#endif + + FT_DEFINE_MODULE(psnames_module_class, + + 0, /* this is not a font driver, nor a renderer */ + sizeof ( FT_ModuleRec ), + + "psnames", /* driver name */ + 0x10000L, /* driver version */ + 0x20000L, /* driver requires FreeType 2 or above */ + + PUT_PS_NAMES_SERVICE((void*)&FT_PSCMAPS_INTERFACE_GET), /* module specific interface */ + (FT_Module_Constructor)0, + (FT_Module_Destructor) 0, + (FT_Module_Requester) PUT_PS_NAMES_SERVICE(psnames_get_service) + ) + + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/psnames/psmodule.h b/mod/pub.mod/freetype.mod/src/psnames/psmodule.h new file mode 100644 index 0000000..28fa148 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/psnames/psmodule.h @@ -0,0 +1,38 @@ +/***************************************************************************/ +/* */ +/* psmodule.h */ +/* */ +/* High-level PSNames module interface (specification). */ +/* */ +/* Copyright 1996-2001 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __PSMODULE_H__ +#define __PSMODULE_H__ + + +#include <ft2build.h> +#include FT_MODULE_H + + +FT_BEGIN_HEADER + + + FT_DECLARE_MODULE( psnames_module_class ) + + +FT_END_HEADER + +#endif /* __PSMODULE_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/psnames/psnamerr.h b/mod/pub.mod/freetype.mod/src/psnames/psnamerr.h new file mode 100644 index 0000000..ae1541d --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/psnames/psnamerr.h @@ -0,0 +1,41 @@ +/***************************************************************************/ +/* */ +/* psnamerr.h */ +/* */ +/* PS names module error codes (specification only). */ +/* */ +/* Copyright 2001 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file is used to define the PS names module error enumeration */ + /* constants. */ + /* */ + /*************************************************************************/ + +#ifndef __PSNAMERR_H__ +#define __PSNAMERR_H__ + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#define FT_ERR_PREFIX PSnames_Err_ +#define FT_ERR_BASE FT_Mod_Err_PSnames + +#include FT_ERRORS_H + +#endif /* __PSNAMERR_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/psnames/psnames.c b/mod/pub.mod/freetype.mod/src/psnames/psnames.c new file mode 100644 index 0000000..1ede225 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/psnames/psnames.c @@ -0,0 +1,26 @@ +/***************************************************************************/ +/* */ +/* psnames.c */ +/* */ +/* FreeType PSNames module component (body only). */ +/* */ +/* Copyright 1996-2001 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#define FT_MAKE_OPTION_SINGLE_OBJECT + +#include <ft2build.h> +#include "pspic.c" +#include "psmodule.c" + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/psnames/pspic.c b/mod/pub.mod/freetype.mod/src/psnames/pspic.c new file mode 100644 index 0000000..ed7dadd --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/psnames/pspic.c @@ -0,0 +1,77 @@ +/***************************************************************************/ +/* */ +/* pspic.c */ +/* */ +/* The FreeType position independent code services for psnames module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include "pspic.h" + +#ifdef FT_CONFIG_OPTION_PIC + + /* forward declaration of PIC init functions from psmodule.c */ + FT_Error FT_Create_Class_pscmaps_services( FT_Library, FT_ServiceDescRec**); + void FT_Destroy_Class_pscmaps_services( FT_Library, FT_ServiceDescRec*); + void FT_Init_Class_pscmaps_interface( FT_Library, FT_Service_PsCMapsRec*); + + void + psnames_module_class_pic_free( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Memory memory = library->memory; + if ( pic_container->psnames ) + { + PSModulePIC* container = (PSModulePIC*)pic_container->psnames; + if(container->pscmaps_services) + FT_Destroy_Class_pscmaps_services(library, container->pscmaps_services); + container->pscmaps_services = NULL; + FT_FREE( container ); + pic_container->psnames = NULL; + } + } + + FT_Error + psnames_module_class_pic_init( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Error error = FT_Err_Ok; + PSModulePIC* container; + FT_Memory memory = library->memory; + + /* allocate pointer, clear and set global container pointer */ + if ( FT_ALLOC ( container, sizeof ( *container ) ) ) + return error; + FT_MEM_SET( container, 0, sizeof(*container) ); + pic_container->psnames = container; + + /* initialize pointer table - this is how the module usually expects this data */ + error = FT_Create_Class_pscmaps_services(library, &container->pscmaps_services); + if(error) + goto Exit; + FT_Init_Class_pscmaps_interface(library, &container->pscmaps_interface); + +Exit: + if(error) + psnames_module_class_pic_free(library); + return error; + } + + +#endif /* FT_CONFIG_OPTION_PIC */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/psnames/pspic.h b/mod/pub.mod/freetype.mod/src/psnames/pspic.h new file mode 100644 index 0000000..75a14fd --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/psnames/pspic.h @@ -0,0 +1,54 @@ +/***************************************************************************/ +/* */ +/* pspic.h */ +/* */ +/* The FreeType position independent code services for psnames module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __PSPIC_H__ +#define __PSPIC_H__ + + +FT_BEGIN_HEADER + +#include FT_INTERNAL_PIC_H + +#ifndef FT_CONFIG_OPTION_PIC +#define FT_PSCMAPS_SERVICES_GET pscmaps_services +#define FT_PSCMAPS_INTERFACE_GET pscmaps_interface + +#else /* FT_CONFIG_OPTION_PIC */ + +#include FT_SERVICE_POSTSCRIPT_CMAPS_H + + typedef struct PSModulePIC_ + { + FT_ServiceDescRec* pscmaps_services; + FT_Service_PsCMapsRec pscmaps_interface; + } PSModulePIC; + +#define GET_PIC(lib) ((PSModulePIC*)((lib)->pic_container.psnames)) +#define FT_PSCMAPS_SERVICES_GET (GET_PIC(library)->pscmaps_services) +#define FT_PSCMAPS_INTERFACE_GET (GET_PIC(library)->pscmaps_interface) + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + +FT_END_HEADER + +#endif /* __PSPIC_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/psnames/pstables.h b/mod/pub.mod/freetype.mod/src/psnames/pstables.h new file mode 100644 index 0000000..1521e9c --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/psnames/pstables.h @@ -0,0 +1,4095 @@ +/***************************************************************************/ +/* */ +/* pstables.h */ +/* */ +/* PostScript glyph names. */ +/* */ +/* Copyright 2005, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /* This file has been generated automatically -- do not edit! */ + + + static const char ft_standard_glyph_names[3696] = + { + '.','n','u','l','l', 0, + 'n','o','n','m','a','r','k','i','n','g','r','e','t','u','r','n', 0, + 'n','o','t','e','q','u','a','l', 0, + 'i','n','f','i','n','i','t','y', 0, + 'l','e','s','s','e','q','u','a','l', 0, + 'g','r','e','a','t','e','r','e','q','u','a','l', 0, + 'p','a','r','t','i','a','l','d','i','f','f', 0, + 's','u','m','m','a','t','i','o','n', 0, + 'p','r','o','d','u','c','t', 0, + 'p','i', 0, + 'i','n','t','e','g','r','a','l', 0, + 'O','m','e','g','a', 0, + 'r','a','d','i','c','a','l', 0, + 'a','p','p','r','o','x','e','q','u','a','l', 0, + 'D','e','l','t','a', 0, + 'n','o','n','b','r','e','a','k','i','n','g','s','p','a','c','e', 0, + 'l','o','z','e','n','g','e', 0, + 'a','p','p','l','e', 0, + 'f','r','a','n','c', 0, + 'G','b','r','e','v','e', 0, + 'g','b','r','e','v','e', 0, + 'I','d','o','t','a','c','c','e','n','t', 0, + 'S','c','e','d','i','l','l','a', 0, + 's','c','e','d','i','l','l','a', 0, + 'C','a','c','u','t','e', 0, + 'c','a','c','u','t','e', 0, + 'C','c','a','r','o','n', 0, + 'c','c','a','r','o','n', 0, + 'd','c','r','o','a','t', 0, + '.','n','o','t','d','e','f', 0, + 's','p','a','c','e', 0, + 'e','x','c','l','a','m', 0, + 'q','u','o','t','e','d','b','l', 0, + 'n','u','m','b','e','r','s','i','g','n', 0, + 'd','o','l','l','a','r', 0, + 'p','e','r','c','e','n','t', 0, + 'a','m','p','e','r','s','a','n','d', 0, + 'q','u','o','t','e','r','i','g','h','t', 0, + 'p','a','r','e','n','l','e','f','t', 0, + 'p','a','r','e','n','r','i','g','h','t', 0, + 'a','s','t','e','r','i','s','k', 0, + 'p','l','u','s', 0, + 'c','o','m','m','a', 0, + 'h','y','p','h','e','n', 0, + 'p','e','r','i','o','d', 0, + 's','l','a','s','h', 0, + 'z','e','r','o', 0, + 'o','n','e', 0, + 't','w','o', 0, + 't','h','r','e','e', 0, + 'f','o','u','r', 0, + 'f','i','v','e', 0, + 's','i','x', 0, + 's','e','v','e','n', 0, + 'e','i','g','h','t', 0, + 'n','i','n','e', 0, + 'c','o','l','o','n', 0, + 's','e','m','i','c','o','l','o','n', 0, + 'l','e','s','s', 0, + 'e','q','u','a','l', 0, + 'g','r','e','a','t','e','r', 0, + 'q','u','e','s','t','i','o','n', 0, + 'a','t', 0, + 'A', 0, + 'B', 0, + 'C', 0, + 'D', 0, + 'E', 0, + 'F', 0, + 'G', 0, + 'H', 0, + 'I', 0, + 'J', 0, + 'K', 0, + 'L', 0, + 'M', 0, + 'N', 0, + 'O', 0, + 'P', 0, + 'Q', 0, + 'R', 0, + 'S', 0, + 'T', 0, + 'U', 0, + 'V', 0, + 'W', 0, + 'X', 0, + 'Y', 0, + 'Z', 0, + 'b','r','a','c','k','e','t','l','e','f','t', 0, + 'b','a','c','k','s','l','a','s','h', 0, + 'b','r','a','c','k','e','t','r','i','g','h','t', 0, + 'a','s','c','i','i','c','i','r','c','u','m', 0, + 'u','n','d','e','r','s','c','o','r','e', 0, + 'q','u','o','t','e','l','e','f','t', 0, + 'a', 0, + 'b', 0, + 'c', 0, + 'd', 0, + 'e', 0, + 'f', 0, + 'g', 0, + 'h', 0, + 'i', 0, + 'j', 0, + 'k', 0, + 'l', 0, + 'm', 0, + 'n', 0, + 'o', 0, + 'p', 0, + 'q', 0, + 'r', 0, + 's', 0, + 't', 0, + 'u', 0, + 'v', 0, + 'w', 0, + 'x', 0, + 'y', 0, + 'z', 0, + 'b','r','a','c','e','l','e','f','t', 0, + 'b','a','r', 0, + 'b','r','a','c','e','r','i','g','h','t', 0, + 'a','s','c','i','i','t','i','l','d','e', 0, + 'e','x','c','l','a','m','d','o','w','n', 0, + 'c','e','n','t', 0, + 's','t','e','r','l','i','n','g', 0, + 'f','r','a','c','t','i','o','n', 0, + 'y','e','n', 0, + 'f','l','o','r','i','n', 0, + 's','e','c','t','i','o','n', 0, + 'c','u','r','r','e','n','c','y', 0, + 'q','u','o','t','e','s','i','n','g','l','e', 0, + 'q','u','o','t','e','d','b','l','l','e','f','t', 0, + 'g','u','i','l','l','e','m','o','t','l','e','f','t', 0, + 'g','u','i','l','s','i','n','g','l','l','e','f','t', 0, + 'g','u','i','l','s','i','n','g','l','r','i','g','h','t', 0, + 'f','i', 0, + 'f','l', 0, + 'e','n','d','a','s','h', 0, + 'd','a','g','g','e','r', 0, + 'd','a','g','g','e','r','d','b','l', 0, + 'p','e','r','i','o','d','c','e','n','t','e','r','e','d', 0, + 'p','a','r','a','g','r','a','p','h', 0, + 'b','u','l','l','e','t', 0, + 'q','u','o','t','e','s','i','n','g','l','b','a','s','e', 0, + 'q','u','o','t','e','d','b','l','b','a','s','e', 0, + 'q','u','o','t','e','d','b','l','r','i','g','h','t', 0, + 'g','u','i','l','l','e','m','o','t','r','i','g','h','t', 0, + 'e','l','l','i','p','s','i','s', 0, + 'p','e','r','t','h','o','u','s','a','n','d', 0, + 'q','u','e','s','t','i','o','n','d','o','w','n', 0, + 'g','r','a','v','e', 0, + 'a','c','u','t','e', 0, + 'c','i','r','c','u','m','f','l','e','x', 0, + 't','i','l','d','e', 0, + 'm','a','c','r','o','n', 0, + 'b','r','e','v','e', 0, + 'd','o','t','a','c','c','e','n','t', 0, + 'd','i','e','r','e','s','i','s', 0, + 'r','i','n','g', 0, + 'c','e','d','i','l','l','a', 0, + 'h','u','n','g','a','r','u','m','l','a','u','t', 0, + 'o','g','o','n','e','k', 0, + 'c','a','r','o','n', 0, + 'e','m','d','a','s','h', 0, + 'A','E', 0, + 'o','r','d','f','e','m','i','n','i','n','e', 0, + 'L','s','l','a','s','h', 0, + 'O','s','l','a','s','h', 0, + 'O','E', 0, + 'o','r','d','m','a','s','c','u','l','i','n','e', 0, + 'a','e', 0, + 'd','o','t','l','e','s','s','i', 0, + 'l','s','l','a','s','h', 0, + 'o','s','l','a','s','h', 0, + 'o','e', 0, + 'g','e','r','m','a','n','d','b','l','s', 0, + 'o','n','e','s','u','p','e','r','i','o','r', 0, + 'l','o','g','i','c','a','l','n','o','t', 0, + 'm','u', 0, + 't','r','a','d','e','m','a','r','k', 0, + 'E','t','h', 0, + 'o','n','e','h','a','l','f', 0, + 'p','l','u','s','m','i','n','u','s', 0, + 'T','h','o','r','n', 0, + 'o','n','e','q','u','a','r','t','e','r', 0, + 'd','i','v','i','d','e', 0, + 'b','r','o','k','e','n','b','a','r', 0, + 'd','e','g','r','e','e', 0, + 't','h','o','r','n', 0, + 't','h','r','e','e','q','u','a','r','t','e','r','s', 0, + 't','w','o','s','u','p','e','r','i','o','r', 0, + 'r','e','g','i','s','t','e','r','e','d', 0, + 'm','i','n','u','s', 0, + 'e','t','h', 0, + 'm','u','l','t','i','p','l','y', 0, + 't','h','r','e','e','s','u','p','e','r','i','o','r', 0, + 'c','o','p','y','r','i','g','h','t', 0, + 'A','a','c','u','t','e', 0, + 'A','c','i','r','c','u','m','f','l','e','x', 0, + 'A','d','i','e','r','e','s','i','s', 0, + 'A','g','r','a','v','e', 0, + 'A','r','i','n','g', 0, + 'A','t','i','l','d','e', 0, + 'C','c','e','d','i','l','l','a', 0, + 'E','a','c','u','t','e', 0, + 'E','c','i','r','c','u','m','f','l','e','x', 0, + 'E','d','i','e','r','e','s','i','s', 0, + 'E','g','r','a','v','e', 0, + 'I','a','c','u','t','e', 0, + 'I','c','i','r','c','u','m','f','l','e','x', 0, + 'I','d','i','e','r','e','s','i','s', 0, + 'I','g','r','a','v','e', 0, + 'N','t','i','l','d','e', 0, + 'O','a','c','u','t','e', 0, + 'O','c','i','r','c','u','m','f','l','e','x', 0, + 'O','d','i','e','r','e','s','i','s', 0, + 'O','g','r','a','v','e', 0, + 'O','t','i','l','d','e', 0, + 'S','c','a','r','o','n', 0, + 'U','a','c','u','t','e', 0, + 'U','c','i','r','c','u','m','f','l','e','x', 0, + 'U','d','i','e','r','e','s','i','s', 0, + 'U','g','r','a','v','e', 0, + 'Y','a','c','u','t','e', 0, + 'Y','d','i','e','r','e','s','i','s', 0, + 'Z','c','a','r','o','n', 0, + 'a','a','c','u','t','e', 0, + 'a','c','i','r','c','u','m','f','l','e','x', 0, + 'a','d','i','e','r','e','s','i','s', 0, + 'a','g','r','a','v','e', 0, + 'a','r','i','n','g', 0, + 'a','t','i','l','d','e', 0, + 'c','c','e','d','i','l','l','a', 0, + 'e','a','c','u','t','e', 0, + 'e','c','i','r','c','u','m','f','l','e','x', 0, + 'e','d','i','e','r','e','s','i','s', 0, + 'e','g','r','a','v','e', 0, + 'i','a','c','u','t','e', 0, + 'i','c','i','r','c','u','m','f','l','e','x', 0, + 'i','d','i','e','r','e','s','i','s', 0, + 'i','g','r','a','v','e', 0, + 'n','t','i','l','d','e', 0, + 'o','a','c','u','t','e', 0, + 'o','c','i','r','c','u','m','f','l','e','x', 0, + 'o','d','i','e','r','e','s','i','s', 0, + 'o','g','r','a','v','e', 0, + 'o','t','i','l','d','e', 0, + 's','c','a','r','o','n', 0, + 'u','a','c','u','t','e', 0, + 'u','c','i','r','c','u','m','f','l','e','x', 0, + 'u','d','i','e','r','e','s','i','s', 0, + 'u','g','r','a','v','e', 0, + 'y','a','c','u','t','e', 0, + 'y','d','i','e','r','e','s','i','s', 0, + 'z','c','a','r','o','n', 0, + 'e','x','c','l','a','m','s','m','a','l','l', 0, + 'H','u','n','g','a','r','u','m','l','a','u','t','s','m','a','l','l', 0, + 'd','o','l','l','a','r','o','l','d','s','t','y','l','e', 0, + 'd','o','l','l','a','r','s','u','p','e','r','i','o','r', 0, + 'a','m','p','e','r','s','a','n','d','s','m','a','l','l', 0, + 'A','c','u','t','e','s','m','a','l','l', 0, + 'p','a','r','e','n','l','e','f','t','s','u','p','e','r','i','o','r', 0, + 'p','a','r','e','n','r','i','g','h','t','s','u','p','e','r','i','o','r', 0, + 't','w','o','d','o','t','e','n','l','e','a','d','e','r', 0, + 'o','n','e','d','o','t','e','n','l','e','a','d','e','r', 0, + 'z','e','r','o','o','l','d','s','t','y','l','e', 0, + 'o','n','e','o','l','d','s','t','y','l','e', 0, + 't','w','o','o','l','d','s','t','y','l','e', 0, + 't','h','r','e','e','o','l','d','s','t','y','l','e', 0, + 'f','o','u','r','o','l','d','s','t','y','l','e', 0, + 'f','i','v','e','o','l','d','s','t','y','l','e', 0, + 's','i','x','o','l','d','s','t','y','l','e', 0, + 's','e','v','e','n','o','l','d','s','t','y','l','e', 0, + 'e','i','g','h','t','o','l','d','s','t','y','l','e', 0, + 'n','i','n','e','o','l','d','s','t','y','l','e', 0, + 'c','o','m','m','a','s','u','p','e','r','i','o','r', 0, + 't','h','r','e','e','q','u','a','r','t','e','r','s','e','m','d','a','s','h', 0, + 'p','e','r','i','o','d','s','u','p','e','r','i','o','r', 0, + 'q','u','e','s','t','i','o','n','s','m','a','l','l', 0, + 'a','s','u','p','e','r','i','o','r', 0, + 'b','s','u','p','e','r','i','o','r', 0, + 'c','e','n','t','s','u','p','e','r','i','o','r', 0, + 'd','s','u','p','e','r','i','o','r', 0, + 'e','s','u','p','e','r','i','o','r', 0, + 'i','s','u','p','e','r','i','o','r', 0, + 'l','s','u','p','e','r','i','o','r', 0, + 'm','s','u','p','e','r','i','o','r', 0, + 'n','s','u','p','e','r','i','o','r', 0, + 'o','s','u','p','e','r','i','o','r', 0, + 'r','s','u','p','e','r','i','o','r', 0, + 's','s','u','p','e','r','i','o','r', 0, + 't','s','u','p','e','r','i','o','r', 0, + 'f','f', 0, + 'f','f','i', 0, + 'f','f','l', 0, + 'p','a','r','e','n','l','e','f','t','i','n','f','e','r','i','o','r', 0, + 'p','a','r','e','n','r','i','g','h','t','i','n','f','e','r','i','o','r', 0, + 'C','i','r','c','u','m','f','l','e','x','s','m','a','l','l', 0, + 'h','y','p','h','e','n','s','u','p','e','r','i','o','r', 0, + 'G','r','a','v','e','s','m','a','l','l', 0, + 'A','s','m','a','l','l', 0, + 'B','s','m','a','l','l', 0, + 'C','s','m','a','l','l', 0, + 'D','s','m','a','l','l', 0, + 'E','s','m','a','l','l', 0, + 'F','s','m','a','l','l', 0, + 'G','s','m','a','l','l', 0, + 'H','s','m','a','l','l', 0, + 'I','s','m','a','l','l', 0, + 'J','s','m','a','l','l', 0, + 'K','s','m','a','l','l', 0, + 'L','s','m','a','l','l', 0, + 'M','s','m','a','l','l', 0, + 'N','s','m','a','l','l', 0, + 'O','s','m','a','l','l', 0, + 'P','s','m','a','l','l', 0, + 'Q','s','m','a','l','l', 0, + 'R','s','m','a','l','l', 0, + 'S','s','m','a','l','l', 0, + 'T','s','m','a','l','l', 0, + 'U','s','m','a','l','l', 0, + 'V','s','m','a','l','l', 0, + 'W','s','m','a','l','l', 0, + 'X','s','m','a','l','l', 0, + 'Y','s','m','a','l','l', 0, + 'Z','s','m','a','l','l', 0, + 'c','o','l','o','n','m','o','n','e','t','a','r','y', 0, + 'o','n','e','f','i','t','t','e','d', 0, + 'r','u','p','i','a','h', 0, + 'T','i','l','d','e','s','m','a','l','l', 0, + 'e','x','c','l','a','m','d','o','w','n','s','m','a','l','l', 0, + 'c','e','n','t','o','l','d','s','t','y','l','e', 0, + 'L','s','l','a','s','h','s','m','a','l','l', 0, + 'S','c','a','r','o','n','s','m','a','l','l', 0, + 'Z','c','a','r','o','n','s','m','a','l','l', 0, + 'D','i','e','r','e','s','i','s','s','m','a','l','l', 0, + 'B','r','e','v','e','s','m','a','l','l', 0, + 'C','a','r','o','n','s','m','a','l','l', 0, + 'D','o','t','a','c','c','e','n','t','s','m','a','l','l', 0, + 'M','a','c','r','o','n','s','m','a','l','l', 0, + 'f','i','g','u','r','e','d','a','s','h', 0, + 'h','y','p','h','e','n','i','n','f','e','r','i','o','r', 0, + 'O','g','o','n','e','k','s','m','a','l','l', 0, + 'R','i','n','g','s','m','a','l','l', 0, + 'C','e','d','i','l','l','a','s','m','a','l','l', 0, + 'q','u','e','s','t','i','o','n','d','o','w','n','s','m','a','l','l', 0, + 'o','n','e','e','i','g','h','t','h', 0, + 't','h','r','e','e','e','i','g','h','t','h','s', 0, + 'f','i','v','e','e','i','g','h','t','h','s', 0, + 's','e','v','e','n','e','i','g','h','t','h','s', 0, + 'o','n','e','t','h','i','r','d', 0, + 't','w','o','t','h','i','r','d','s', 0, + 'z','e','r','o','s','u','p','e','r','i','o','r', 0, + 'f','o','u','r','s','u','p','e','r','i','o','r', 0, + 'f','i','v','e','s','u','p','e','r','i','o','r', 0, + 's','i','x','s','u','p','e','r','i','o','r', 0, + 's','e','v','e','n','s','u','p','e','r','i','o','r', 0, + 'e','i','g','h','t','s','u','p','e','r','i','o','r', 0, + 'n','i','n','e','s','u','p','e','r','i','o','r', 0, + 'z','e','r','o','i','n','f','e','r','i','o','r', 0, + 'o','n','e','i','n','f','e','r','i','o','r', 0, + 't','w','o','i','n','f','e','r','i','o','r', 0, + 't','h','r','e','e','i','n','f','e','r','i','o','r', 0, + 'f','o','u','r','i','n','f','e','r','i','o','r', 0, + 'f','i','v','e','i','n','f','e','r','i','o','r', 0, + 's','i','x','i','n','f','e','r','i','o','r', 0, + 's','e','v','e','n','i','n','f','e','r','i','o','r', 0, + 'e','i','g','h','t','i','n','f','e','r','i','o','r', 0, + 'n','i','n','e','i','n','f','e','r','i','o','r', 0, + 'c','e','n','t','i','n','f','e','r','i','o','r', 0, + 'd','o','l','l','a','r','i','n','f','e','r','i','o','r', 0, + 'p','e','r','i','o','d','i','n','f','e','r','i','o','r', 0, + 'c','o','m','m','a','i','n','f','e','r','i','o','r', 0, + 'A','g','r','a','v','e','s','m','a','l','l', 0, + 'A','a','c','u','t','e','s','m','a','l','l', 0, + 'A','c','i','r','c','u','m','f','l','e','x','s','m','a','l','l', 0, + 'A','t','i','l','d','e','s','m','a','l','l', 0, + 'A','d','i','e','r','e','s','i','s','s','m','a','l','l', 0, + 'A','r','i','n','g','s','m','a','l','l', 0, + 'A','E','s','m','a','l','l', 0, + 'C','c','e','d','i','l','l','a','s','m','a','l','l', 0, + 'E','g','r','a','v','e','s','m','a','l','l', 0, + 'E','a','c','u','t','e','s','m','a','l','l', 0, + 'E','c','i','r','c','u','m','f','l','e','x','s','m','a','l','l', 0, + 'E','d','i','e','r','e','s','i','s','s','m','a','l','l', 0, + 'I','g','r','a','v','e','s','m','a','l','l', 0, + 'I','a','c','u','t','e','s','m','a','l','l', 0, + 'I','c','i','r','c','u','m','f','l','e','x','s','m','a','l','l', 0, + 'I','d','i','e','r','e','s','i','s','s','m','a','l','l', 0, + 'E','t','h','s','m','a','l','l', 0, + 'N','t','i','l','d','e','s','m','a','l','l', 0, + 'O','g','r','a','v','e','s','m','a','l','l', 0, + 'O','a','c','u','t','e','s','m','a','l','l', 0, + 'O','c','i','r','c','u','m','f','l','e','x','s','m','a','l','l', 0, + 'O','t','i','l','d','e','s','m','a','l','l', 0, + 'O','d','i','e','r','e','s','i','s','s','m','a','l','l', 0, + 'O','E','s','m','a','l','l', 0, + 'O','s','l','a','s','h','s','m','a','l','l', 0, + 'U','g','r','a','v','e','s','m','a','l','l', 0, + 'U','a','c','u','t','e','s','m','a','l','l', 0, + 'U','c','i','r','c','u','m','f','l','e','x','s','m','a','l','l', 0, + 'U','d','i','e','r','e','s','i','s','s','m','a','l','l', 0, + 'Y','a','c','u','t','e','s','m','a','l','l', 0, + 'T','h','o','r','n','s','m','a','l','l', 0, + 'Y','d','i','e','r','e','s','i','s','s','m','a','l','l', 0, + '0','0','1','.','0','0','0', 0, + '0','0','1','.','0','0','1', 0, + '0','0','1','.','0','0','2', 0, + '0','0','1','.','0','0','3', 0, + 'B','l','a','c','k', 0, + 'B','o','l','d', 0, + 'B','o','o','k', 0, + 'L','i','g','h','t', 0, + 'M','e','d','i','u','m', 0, + 'R','e','g','u','l','a','r', 0, + 'R','o','m','a','n', 0, + 'S','e','m','i','b','o','l','d', 0, + }; + + +#define FT_NUM_MAC_NAMES 258 + + /* Values are offsets into the `ft_standard_glyph_names' table */ + + static const short ft_mac_names[FT_NUM_MAC_NAMES] = + { + 253, 0, 6, 261, 267, 274, 283, 294, 301, 309, 758, 330, 340, 351, + 360, 365, 371, 378, 385, 391, 396, 400, 404, 410, 415, 420, 424, 430, + 436, 441, 447, 457, 462, 468, 476, 485, 488, 490, 492, 494, 496, 498, + 500, 502, 504, 506, 508, 510, 512, 514, 516, 518, 520, 522, 524, 526, + 528, 530, 532, 534, 536, 538, 540, 552, 562, 575, 587, 979, 608, 610, + 612, 614, 616, 618, 620, 622, 624, 626, 628, 630, 632, 634, 636, 638, + 640, 642, 644, 646, 648, 650, 652, 654, 656, 658, 660, 670, 674, 685, + 1375,1392,1405,1414,1486,1512,1562,1603,1632,1610,1622,1645,1639,1652, + 1661,1690,1668,1680,1697,1726,1704,1716,1733,1740,1769,1747,1759,1776, + 1790,1819,1797,1809, 839,1263, 707, 712, 741, 881, 871,1160,1302,1346, + 1197, 985,1031, 23,1086,1108, 32,1219, 41, 51, 730,1194, 64, 76, + 86, 94, 97,1089,1118, 106,1131,1150, 966, 696,1183, 112, 734, 120, + 132, 783, 930, 945, 138,1385,1398,1529,1115,1157, 832,1079, 770, 916, + 598, 319,1246, 155,1833,1586, 721, 749, 797, 811, 826, 829, 846, 856, + 888, 903, 954,1363,1421,1356,1433,1443,1450,1457,1469,1479,1493,1500, + 163,1522,1543,1550,1572,1134, 991,1002,1008,1015,1021,1040,1045,1053, + 1066,1073,1101,1143,1536,1783,1596,1843,1253,1207,1319,1579,1826,1229, + 1270,1313,1323,1171,1290,1332,1211,1235,1276, 169, 175, 182, 189, 200, + 209, 218, 225, 232, 239, 246 + }; + + +#define FT_NUM_SID_NAMES 391 + + /* Values are offsets into the `ft_standard_glyph_names' table */ + + static const short ft_sid_names[FT_NUM_SID_NAMES] = + { + 253, 261, 267, 274, 283, 294, 301, 309, 319, 330, 340, 351, 360, 365, + 371, 378, 385, 391, 396, 400, 404, 410, 415, 420, 424, 430, 436, 441, + 447, 457, 462, 468, 476, 485, 488, 490, 492, 494, 496, 498, 500, 502, + 504, 506, 508, 510, 512, 514, 516, 518, 520, 522, 524, 526, 528, 530, + 532, 534, 536, 538, 540, 552, 562, 575, 587, 598, 608, 610, 612, 614, + 616, 618, 620, 622, 624, 626, 628, 630, 632, 634, 636, 638, 640, 642, + 644, 646, 648, 650, 652, 654, 656, 658, 660, 670, 674, 685, 696, 707, + 712, 721, 730, 734, 741, 749, 758, 770, 783, 797, 811, 826, 829, 832, + 839, 846, 856, 871, 881, 888, 903, 916, 930, 945, 954, 966, 979, 985, + 991,1002,1008,1015,1021,1031,1040,1045,1053,1066,1073,1079,1086,1089, + 1101,1108,1115,1118,1131,1134,1143,1150,1157,1160,1171,1183,1194,1197, + 1207,1211,1219,1229,1235,1246,1253,1263,1270,1276,1290,1302,1313,1319, + 1323,1332,1346,1356,1363,1375,1385,1392,1398,1405,1414,1421,1433,1443, + 1450,1457,1469,1479,1486,1493,1500,1512,1522,1529,1536,1543,1550,1562, + 1572,1579,1586,1596,1603,1610,1622,1632,1639,1645,1652,1661,1668,1680, + 1690,1697,1704,1716,1726,1733,1740,1747,1759,1769,1776,1783,1790,1797, + 1809,1819,1826,1833,1843,1850,1862,1880,1895,1910,1925,1936,1954,1973, + 1988,2003,2016,2028,2040,2054,2067,2080,2092,2106,2120,2133,2147,2167, + 2182,2196,2206,2216,2229,2239,2249,2259,2269,2279,2289,2299,2309,2319, + 2329,2332,2336,2340,2358,2377,2393,2408,2419,2426,2433,2440,2447,2454, + 2461,2468,2475,2482,2489,2496,2503,2510,2517,2524,2531,2538,2545,2552, + 2559,2566,2573,2580,2587,2594,2601,2615,2625,2632,2643,2659,2672,2684, + 2696,2708,2722,2733,2744,2759,2771,2782,2797,2809,2819,2832,2850,2860, + 2873,2885,2898,2907,2917,2930,2943,2956,2968,2982,2996,3009,3022,3034, + 3046,3060,3073,3086,3098,3112,3126,3139,3152,3167,3182,3196,3208,3220, + 3237,3249,3264,3275,3283,3297,3309,3321,3338,3353,3365,3377,3394,3409, + 3418,3430,3442,3454,3471,3483,3498,3506,3518,3530,3542,3559,3574,3586, + 3597,3612,3620,3628,3636,3644,3650,3655,3660,3666,3673,3681,3687 + }; + + + /* the following are indices into the SID name table */ + static const unsigned short t1_standard_encoding[256] = + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110, + 0,111,112,113,114, 0,115,116,117,118,119,120,121,122, 0,123, + 0,124,125,126,127,128,129,130,131, 0,132,133, 0,134,135,136, + 137, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,138, 0,139, 0, 0, 0, 0,140,141,142,143, 0, 0, 0, 0, + 0,144, 0, 0, 0,145, 0, 0,146,147,148,149, 0, 0, 0, 0 + }; + + + /* the following are indices into the SID name table */ + static const unsigned short t1_expert_encoding[256] = + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1,229,230, 0,231,232,233,234,235,236,237,238, 13, 14, 15, 99, + 239,240,241,242,243,244,245,246,247,248, 27, 28,249,250,251,252, + 0,253,254,255,256,257, 0, 0, 0,258, 0, 0,259,260,261,262, + 0, 0,263,264,265, 0,266,109,110,267,268,269, 0,270,271,272, + 273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288, + 289,290,291,292,293,294,295,296,297,298,299,300,301,302,303, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,304,305,306, 0, 0,307,308,309,310,311, 0,312, 0, 0,313, + 0, 0,314,315, 0, 0,316,317,318, 0, 0, 0,158,155,163,319, + 320,321,322,323,324,325, 0, 0,326,150,164,169,327,328,329,330, + 331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346, + 347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362, + 363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378 + }; + + + /* + * This table is a compressed version of the Adobe Glyph List (AGL), + * optimized for efficient searching. It has been generated by the + * `glnames.py' python script located in the `src/tools' directory. + * + * The lookup function to get the Unicode value for a given string + * is defined below the table. + */ + +#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST + + static const unsigned char ft_adobe_glyph_list[54791L] = + { + 0, 52, 0,106, 2,167, 3, 63, 4,220, 6,125, 9,143, 10, 23, + 11,137, 12,199, 14,246, 15, 87, 16,233, 17,219, 18,104, 19, 88, + 22,110, 23, 32, 23, 71, 24, 77, 27,156, 29, 73, 31,247, 32,107, + 32,222, 33, 55, 34,154, 35,218, 53, 84, 59,196, 68, 6, 75,183, + 83,178, 88,135, 93,242,101,165,109,185,111, 55,117,254,123, 73, + 130,238,138,206,145, 31,153,182,156,189,163,249,178,221,193, 17, + 197, 99,199,240,204, 27,204,155,210,100, 65,143, 0, 65, 0,140, + 0,175, 0,193, 1, 15, 1,147, 1,233, 1,251, 2, 7, 2, 40, + 2, 57, 2, 82, 2, 91, 2,128, 2,136, 2,154, 69,131, 0,198, + 0,150, 0,158, 0,167,225,227,245,244,101,128, 1,252,237,225, + 227,242,239,110,128, 1,226,243,237,225,236,108,128,247,230,225, + 227,245,244,101,129, 0,193, 0,185,243,237,225,236,108,128,247, + 225,226,242,229,246,101,134, 1, 2, 0,213, 0,221, 0,232, 0, + 243, 0,251, 1, 7,225,227,245,244,101,128, 30,174,227,249,242, + 233,236,236,233, 99,128, 4,208,228,239,244,226,229,236,239,119, + 128, 30,182,231,242,225,246,101,128, 30,176,232,239,239,235,225, + 226,239,246,101,128, 30,178,244,233,236,228,101,128, 30,180, 99, + 4, 1, 25, 1, 32, 1,121, 1,137,225,242,239,110,128, 1,205, + 233,242, 99, 2, 1, 40, 1, 45,236,101,128, 36,182,245,237,230, + 236,229,120,134, 0,194, 1, 66, 1, 74, 1, 85, 1, 93, 1,105, + 1,113,225,227,245,244,101,128, 30,164,228,239,244,226,229,236, + 239,119,128, 30,172,231,242,225,246,101,128, 30,166,232,239,239, + 235,225,226,239,246,101,128, 30,168,243,237,225,236,108,128,247, + 226,244,233,236,228,101,128, 30,170,245,244,101,129,246,201, 1, + 129,243,237,225,236,108,128,247,180,249,242,233,236,236,233, 99, + 128, 4, 16,100, 3, 1,155, 1,165, 1,209,226,236,231,242,225, + 246,101,128, 2, 0,233,229,242,229,243,233,115,131, 0,196, 1, + 181, 1,192, 1,201,227,249,242,233,236,236,233, 99,128, 4,210, + 237,225,227,242,239,110,128, 1,222,243,237,225,236,108,128,247, + 228,239,116, 2, 1,216, 1,224,226,229,236,239,119,128, 30,160, + 237,225,227,242,239,110,128, 1,224,231,242,225,246,101,129, 0, + 192, 1,243,243,237,225,236,108,128,247,224,232,239,239,235,225, + 226,239,246,101,128, 30,162,105, 2, 2, 13, 2, 25,229,227,249, + 242,233,236,236,233, 99,128, 4,212,238,246,229,242,244,229,228, + 226,242,229,246,101,128, 2, 2,236,240,232, 97,129, 3,145, 2, + 49,244,239,238,239,115,128, 3,134,109, 2, 2, 63, 2, 71,225, + 227,242,239,110,128, 1, 0,239,238,239,243,240,225,227,101,128, + 255, 33,239,231,239,238,229,107,128, 1, 4,242,233,238,103,131, + 0,197, 2,104, 2,112, 2,120,225,227,245,244,101,128, 1,250, + 226,229,236,239,119,128, 30, 0,243,237,225,236,108,128,247,229, + 243,237,225,236,108,128,247, 97,244,233,236,228,101,129, 0,195, + 2,146,243,237,225,236,108,128,247,227,249,226,225,242,237,229, + 238,233,225,110,128, 5, 49, 66,137, 0, 66, 2,189, 2,198, 2, + 223, 3, 3, 3, 10, 3, 22, 3, 34, 3, 46, 3, 54,227,233,242, + 227,236,101,128, 36,183,228,239,116, 2, 2,206, 2,215,225,227, + 227,229,238,116,128, 30, 2,226,229,236,239,119,128, 30, 4,101, + 3, 2,231, 2,242, 2,254,227,249,242,233,236,236,233, 99,128, + 4, 17,238,225,242,237,229,238,233,225,110,128, 5, 50,244, 97, + 128, 3,146,232,239,239,107,128, 1,129,236,233,238,229,226,229, + 236,239,119,128, 30, 6,237,239,238,239,243,240,225,227,101,128, + 255, 34,242,229,246,229,243,237,225,236,108,128,246,244,243,237, + 225,236,108,128,247, 98,244,239,240,226,225,114,128, 1,130, 67, + 137, 0, 67, 3, 85, 3,127, 3,193, 3,210, 3,224, 4,171, 4, + 188, 4,200, 4,212, 97, 3, 3, 93, 3,104, 3,111,225,242,237, + 229,238,233,225,110,128, 5, 62,227,245,244,101,128, 1, 6,242, + 239,110,129,246,202, 3,119,243,237,225,236,108,128,246,245, 99, + 3, 3,135, 3,142, 3,171,225,242,239,110,128, 1, 12,229,228, + 233,236,236, 97,130, 0,199, 3,155, 3,163,225,227,245,244,101, + 128, 30, 8,243,237,225,236,108,128,247,231,233,242, 99, 2, 3, + 179, 3,184,236,101,128, 36,184,245,237,230,236,229,120,128, 1, + 8,228,239,116,129, 1, 10, 3,201,225,227,227,229,238,116,128, + 1, 10,229,228,233,236,236,225,243,237,225,236,108,128,247,184, + 104, 4, 3,234, 3,246, 4,161, 4,165,225,225,242,237,229,238, + 233,225,110,128, 5, 73,101, 6, 4, 4, 4, 24, 4, 35, 4,103, + 4,115, 4,136,225,226,235,232,225,243,233,225,238,227,249,242, + 233,236,236,233, 99,128, 4,188,227,249,242,233,236,236,233, 99, + 128, 4, 39,100, 2, 4, 41, 4, 85,229,243,227,229,238,228,229, + 114, 2, 4, 54, 4, 74,225,226,235,232,225,243,233,225,238,227, + 249,242,233,236,236,233, 99,128, 4,190,227,249,242,233,236,236, + 233, 99,128, 4,182,233,229,242,229,243,233,243,227,249,242,233, + 236,236,233, 99,128, 4,244,232,225,242,237,229,238,233,225,110, + 128, 5, 67,235,232,225,235,225,243,243,233,225,238,227,249,242, + 233,236,236,233, 99,128, 4,203,246,229,242,244,233,227,225,236, + 243,244,242,239,235,229,227,249,242,233,236,236,233, 99,128, 4, + 184,105,128, 3,167,239,239,107,128, 1,135,233,242,227,245,237, + 230,236,229,248,243,237,225,236,108,128,246,246,237,239,238,239, + 243,240,225,227,101,128,255, 35,239,225,242,237,229,238,233,225, + 110,128, 5, 81,243,237,225,236,108,128,247, 99, 68,142, 0, 68, + 4,252, 5, 10, 5, 36, 5, 96, 5,121, 5,166, 5,173, 5,231, + 5,244, 6, 0, 6, 12, 6, 28, 6, 48, 6, 57, 90,129, 1,241, + 5, 2,227,225,242,239,110,128, 1,196, 97, 2, 5, 16, 5, 27, + 225,242,237,229,238,233,225,110,128, 5, 52,230,242,233,227,225, + 110,128, 1,137, 99, 4, 5, 46, 5, 53, 5, 62, 5, 89,225,242, + 239,110,128, 1, 14,229,228,233,236,236, 97,128, 30, 16,233,242, + 99, 2, 5, 70, 5, 75,236,101,128, 36,185,245,237,230,236,229, + 248,226,229,236,239,119,128, 30, 18,242,239,225,116,128, 1, 16, + 228,239,116, 2, 5,104, 5,113,225,227,227,229,238,116,128, 30, + 10,226,229,236,239,119,128, 30, 12,101, 3, 5,129, 5,140, 5, + 150,227,249,242,233,236,236,233, 99,128, 4, 20,233,227,239,240, + 244,233, 99,128, 3,238,236,244, 97,129, 34, 6, 5,158,231,242, + 229,229,107,128, 3,148,232,239,239,107,128, 1,138,105, 2, 5, + 179, 5,218,229,242,229,243,233,115,131,246,203, 5,194, 5,202, + 5,210,193,227,245,244,101,128,246,204,199,242,225,246,101,128, + 246,205,243,237,225,236,108,128,247,168,231,225,237,237,225,231, + 242,229,229,107,128, 3,220,234,229,227,249,242,233,236,236,233, + 99,128, 4, 2,236,233,238,229,226,229,236,239,119,128, 30, 14, + 237,239,238,239,243,240,225,227,101,128,255, 36,239,244,225,227, + 227,229,238,244,243,237,225,236,108,128,246,247,115, 2, 6, 34, + 6, 41,236,225,243,104,128, 1, 16,237,225,236,108,128,247,100, + 244,239,240,226,225,114,128, 1,139,122,131, 1,242, 6, 67, 6, + 75, 6,112,227,225,242,239,110,128, 1,197,101, 2, 6, 81, 6, + 101,225,226,235,232,225,243,233,225,238,227,249,242,233,236,236, + 233, 99,128, 4,224,227,249,242,233,236,236,233, 99,128, 4, 5, + 232,229,227,249,242,233,236,236,233, 99,128, 4, 15, 69,146, 0, + 69, 6,165, 6,183, 6,191, 7, 89, 7,153, 7,165, 7,183, 7, + 211, 8, 7, 8, 36, 8, 94, 8,169, 8,189, 8,208, 8,248, 9, + 44, 9,109, 9,115,225,227,245,244,101,129, 0,201, 6,175,243, + 237,225,236,108,128,247,233,226,242,229,246,101,128, 1, 20, 99, + 5, 6,203, 6,210, 6,224, 6,236, 7, 79,225,242,239,110,128, + 1, 26,229,228,233,236,236,225,226,242,229,246,101,128, 30, 28, + 232,225,242,237,229,238,233,225,110,128, 5, 53,233,242, 99, 2, + 6,244, 6,249,236,101,128, 36,186,245,237,230,236,229,120,135, + 0,202, 7, 16, 7, 24, 7, 32, 7, 43, 7, 51, 7, 63, 7, 71, + 225,227,245,244,101,128, 30,190,226,229,236,239,119,128, 30, 24, + 228,239,244,226,229,236,239,119,128, 30,198,231,242,225,246,101, + 128, 30,192,232,239,239,235,225,226,239,246,101,128, 30,194,243, + 237,225,236,108,128,247,234,244,233,236,228,101,128, 30,196,249, + 242,233,236,236,233, 99,128, 4, 4,100, 3, 7, 97, 7,107, 7, + 127,226,236,231,242,225,246,101,128, 2, 4,233,229,242,229,243, + 233,115,129, 0,203, 7,119,243,237,225,236,108,128,247,235,239, + 116,130, 1, 22, 7,136, 7,145,225,227,227,229,238,116,128, 1, + 22,226,229,236,239,119,128, 30,184,230,227,249,242,233,236,236, + 233, 99,128, 4, 36,231,242,225,246,101,129, 0,200, 7,175,243, + 237,225,236,108,128,247,232,104, 2, 7,189, 7,200,225,242,237, + 229,238,233,225,110,128, 5, 55,239,239,235,225,226,239,246,101, + 128, 30,186,105, 3, 7,219, 7,230, 7,245,231,232,244,242,239, + 237,225,110,128, 33,103,238,246,229,242,244,229,228,226,242,229, + 246,101,128, 2, 6,239,244,233,230,233,229,228,227,249,242,233, + 236,236,233, 99,128, 4,100,108, 2, 8, 13, 8, 24,227,249,242, + 233,236,236,233, 99,128, 4, 27,229,246,229,238,242,239,237,225, + 110,128, 33,106,109, 3, 8, 44, 8, 72, 8, 83,225,227,242,239, + 110,130, 1, 18, 8, 56, 8, 64,225,227,245,244,101,128, 30, 22, + 231,242,225,246,101,128, 30, 20,227,249,242,233,236,236,233, 99, + 128, 4, 28,239,238,239,243,240,225,227,101,128,255, 37,110, 4, + 8,104, 8,115, 8,135, 8,154,227,249,242,233,236,236,233, 99, + 128, 4, 29,228,229,243,227,229,238,228,229,242,227,249,242,233, + 236,236,233, 99,128, 4,162,103,129, 1, 74, 8,141,232,229,227, + 249,242,233,236,236,233, 99,128, 4,164,232,239,239,235,227,249, + 242,233,236,236,233, 99,128, 4,199,111, 2, 8,175, 8,183,231, + 239,238,229,107,128, 1, 24,240,229,110,128, 1,144,240,243,233, + 236,239,110,129, 3,149, 8,200,244,239,238,239,115,128, 3,136, + 114, 2, 8,214, 8,225,227,249,242,233,236,236,233, 99,128, 4, + 32,229,246,229,242,243,229,100,129, 1,142, 8,237,227,249,242, + 233,236,236,233, 99,128, 4, 45,115, 4, 9, 2, 9, 13, 9, 33, + 9, 37,227,249,242,233,236,236,233, 99,128, 4, 33,228,229,243, + 227,229,238,228,229,242,227,249,242,233,236,236,233, 99,128, 4, + 170,104,128, 1,169,237,225,236,108,128,247,101,116, 3, 9, 52, + 9, 78, 9, 92, 97,130, 3,151, 9, 60, 9, 70,242,237,229,238, + 233,225,110,128, 5, 56,244,239,238,239,115,128, 3,137,104,129, + 0,208, 9, 84,243,237,225,236,108,128,247,240,233,236,228,101, + 129, 30,188, 9,101,226,229,236,239,119,128, 30, 26,245,242,111, + 128, 32,172,250,104,130, 1,183, 9,124, 9,132,227,225,242,239, + 110,128, 1,238,242,229,246,229,242,243,229,100,128, 1,184, 70, + 136, 0, 70, 9,163, 9,172, 9,184, 9,212, 9,219, 9,248, 10, + 4, 10, 15,227,233,242,227,236,101,128, 36,187,228,239,244,225, + 227,227,229,238,116,128, 30, 30,101, 2, 9,190, 9,202,232,225, + 242,237,229,238,233,225,110,128, 5, 86,233,227,239,240,244,233, + 99,128, 3,228,232,239,239,107,128, 1,145,105, 2, 9,225, 9, + 238,244,225,227,249,242,233,236,236,233, 99,128, 4,114,246,229, + 242,239,237,225,110,128, 33,100,237,239,238,239,243,240,225,227, + 101,128,255, 38,239,245,242,242,239,237,225,110,128, 33, 99,243, + 237,225,236,108,128,247,102, 71,140, 0, 71, 10, 51, 10, 61, 10, + 107, 10,115, 10,176, 10,193, 10,205, 11, 39, 11, 52, 11, 65, 11, + 90, 11,107,194,243,241,245,225,242,101,128, 51,135, 97, 3, 10, + 69, 10, 76, 10, 94,227,245,244,101,128, 1,244,237,237, 97,129, + 3,147, 10, 84,225,230,242,233,227,225,110,128, 1,148,238,231, + 233,225,227,239,240,244,233, 99,128, 3,234,226,242,229,246,101, + 128, 1, 30, 99, 4, 10,125, 10,132, 10,141, 10,163,225,242,239, + 110,128, 1,230,229,228,233,236,236, 97,128, 1, 34,233,242, 99, + 2, 10,149, 10,154,236,101,128, 36,188,245,237,230,236,229,120, + 128, 1, 28,239,237,237,225,225,227,227,229,238,116,128, 1, 34, + 228,239,116,129, 1, 32, 10,184,225,227,227,229,238,116,128, 1, + 32,229,227,249,242,233,236,236,233, 99,128, 4, 19,104, 3, 10, + 213, 10,226, 11, 33,225,228,225,242,237,229,238,233,225,110,128, + 5, 66,101, 3, 10,234, 10,255, 11, 16,237,233,228,228,236,229, + 232,239,239,235,227,249,242,233,236,236,233, 99,128, 4,148,243, + 244,242,239,235,229,227,249,242,233,236,236,233, 99,128, 4,146, + 245,240,244,245,242,238,227,249,242,233,236,236,233, 99,128, 4, + 144,239,239,107,128, 1,147,233,237,225,242,237,229,238,233,225, + 110,128, 5, 51,234,229,227,249,242,233,236,236,233, 99,128, 4, + 3,109, 2, 11, 71, 11, 79,225,227,242,239,110,128, 30, 32,239, + 238,239,243,240,225,227,101,128,255, 39,242,225,246,101,129,246, + 206, 11, 99,243,237,225,236,108,128,247, 96,115, 2, 11,113, 11, + 129,237,225,236,108,129,247,103, 11,122,232,239,239,107,128, 2, + 155,244,242,239,235,101,128, 1,228, 72,140, 0, 72, 11,165, 11, + 190, 11,198, 11,208, 12, 17, 12, 40, 12, 77, 12,117, 12,129, 12, + 157, 12,165, 12,189,177,184, 53, 3, 11,175, 11,180, 11,185,179, + 51,128, 37,207,180, 51,128, 37,170,181, 49,128, 37,171,178,178, + 176,183, 51,128, 37,161,208,243,241,245,225,242,101,128, 51,203, + 97, 3, 11,216, 11,236, 12, 0,225,226,235,232,225,243,233,225, + 238,227,249,242,233,236,236,233, 99,128, 4,168,228,229,243,227, + 229,238,228,229,242,227,249,242,233,236,236,233, 99,128, 4,178, + 242,228,243,233,231,238,227,249,242,233,236,236,233, 99,128, 4, + 42, 98, 2, 12, 23, 12, 28,225,114,128, 1, 38,242,229,246,229, + 226,229,236,239,119,128, 30, 42, 99, 2, 12, 46, 12, 55,229,228, + 233,236,236, 97,128, 30, 40,233,242, 99, 2, 12, 63, 12, 68,236, + 101,128, 36,189,245,237,230,236,229,120,128, 1, 36,100, 2, 12, + 83, 12, 93,233,229,242,229,243,233,115,128, 30, 38,239,116, 2, + 12,100, 12,109,225,227,227,229,238,116,128, 30, 34,226,229,236, + 239,119,128, 30, 36,237,239,238,239,243,240,225,227,101,128,255, + 40,111, 2, 12,135, 12,146,225,242,237,229,238,233,225,110,128, + 5, 64,242,233,227,239,240,244,233, 99,128, 3,232,243,237,225, + 236,108,128,247,104,245,238,231,225,242,245,237,236,225,245,116, + 129,246,207, 12,181,243,237,225,236,108,128,246,248,250,243,241, + 245,225,242,101,128, 51,144, 73,146, 0, 73, 12,239, 12,251, 12, + 255, 13, 11, 13, 29, 13, 37, 13, 94, 13,181, 13,214, 13,224, 13, + 242, 13,254, 14, 48, 14, 86, 14, 99, 14,166, 14,187, 14,205,193, + 227,249,242,233,236,236,233, 99,128, 4, 47, 74,128, 1, 50,213, + 227,249,242,233,236,236,233, 99,128, 4, 46,225,227,245,244,101, + 129, 0,205, 13, 21,243,237,225,236,108,128,247,237,226,242,229, + 246,101,128, 1, 44, 99, 3, 13, 45, 13, 52, 13, 84,225,242,239, + 110,128, 1,207,233,242, 99, 2, 13, 60, 13, 65,236,101,128, 36, + 190,245,237,230,236,229,120,129, 0,206, 13, 76,243,237,225,236, + 108,128,247,238,249,242,233,236,236,233, 99,128, 4, 6,100, 3, + 13,102, 13,112, 13,155,226,236,231,242,225,246,101,128, 2, 8, + 233,229,242,229,243,233,115,131, 0,207, 13,128, 13,136, 13,147, + 225,227,245,244,101,128, 30, 46,227,249,242,233,236,236,233, 99, + 128, 4,228,243,237,225,236,108,128,247,239,239,116,130, 1, 48, + 13,164, 13,173,225,227,227,229,238,116,128, 1, 48,226,229,236, + 239,119,128, 30,202,101, 2, 13,187, 13,203,226,242,229,246,229, + 227,249,242,233,236,236,233, 99,128, 4,214,227,249,242,233,236, + 236,233, 99,128, 4, 21,230,242,225,235,244,245,114,128, 33, 17, + 231,242,225,246,101,129, 0,204, 13,234,243,237,225,236,108,128, + 247,236,232,239,239,235,225,226,239,246,101,128, 30,200,105, 3, + 14, 6, 14, 17, 14, 32,227,249,242,233,236,236,233, 99,128, 4, + 24,238,246,229,242,244,229,228,226,242,229,246,101,128, 2, 10, + 243,232,239,242,244,227,249,242,233,236,236,233, 99,128, 4, 25, + 109, 2, 14, 54, 14, 75,225,227,242,239,110,129, 1, 42, 14, 64, + 227,249,242,233,236,236,233, 99,128, 4,226,239,238,239,243,240, + 225,227,101,128,255, 41,238,233,225,242,237,229,238,233,225,110, + 128, 5, 59,111, 3, 14,107, 14,118, 14,126,227,249,242,233,236, + 236,233, 99,128, 4, 1,231,239,238,229,107,128, 1, 46,244, 97, + 131, 3,153, 14,137, 14,147, 14,158,225,230,242,233,227,225,110, + 128, 1,150,228,233,229,242,229,243,233,115,128, 3,170,244,239, + 238,239,115,128, 3,138,115, 2, 14,172, 14,179,237,225,236,108, + 128,247,105,244,242,239,235,101,128, 1,151,244,233,236,228,101, + 129, 1, 40, 14,197,226,229,236,239,119,128, 30, 44,250,232,233, + 244,243, 97, 2, 14,216, 14,227,227,249,242,233,236,236,233, 99, + 128, 4,116,228,226,236,231,242,225,246,229,227,249,242,233,236, + 236,233, 99,128, 4,118, 74,134, 0, 74, 15, 6, 15, 18, 15, 41, + 15, 53, 15, 67, 15, 79,225,225,242,237,229,238,233,225,110,128, + 5, 65,227,233,242, 99, 2, 15, 27, 15, 32,236,101,128, 36,191, + 245,237,230,236,229,120,128, 1, 52,229,227,249,242,233,236,236, + 233, 99,128, 4, 8,232,229,232,225,242,237,229,238,233,225,110, + 128, 5, 75,237,239,238,239,243,240,225,227,101,128,255, 42,243, + 237,225,236,108,128,247,106, 75,140, 0, 75, 15,115, 15,125, 15, + 135, 16, 18, 16, 65, 16, 76, 16,106, 16,143, 16,156, 16,168, 16, + 180, 16,208,194,243,241,245,225,242,101,128, 51,133,203,243,241, + 245,225,242,101,128, 51,205, 97, 7, 15,151, 15,169, 15,191, 15, + 211, 15,226, 15,232, 15,249,226,225,243,232,235,233,242,227,249, + 242,233,236,236,233, 99,128, 4,160, 99, 2, 15,175, 15,181,245, + 244,101,128, 30, 48,249,242,233,236,236,233, 99,128, 4, 26,228, + 229,243,227,229,238,228,229,242,227,249,242,233,236,236,233, 99, + 128, 4,154,232,239,239,235,227,249,242,233,236,236,233, 99,128, + 4,195,240,240, 97,128, 3,154,243,244,242,239,235,229,227,249, + 242,233,236,236,233, 99,128, 4,158,246,229,242,244,233,227,225, + 236,243,244,242,239,235,229,227,249,242,233,236,236,233, 99,128, + 4,156, 99, 4, 16, 28, 16, 35, 16, 44, 16, 52,225,242,239,110, + 128, 1,232,229,228,233,236,236, 97,128, 1, 54,233,242,227,236, + 101,128, 36,192,239,237,237,225,225,227,227,229,238,116,128, 1, + 54,228,239,244,226,229,236,239,119,128, 30, 50,101, 2, 16, 82, + 16, 94,232,225,242,237,229,238,233,225,110,128, 5, 84,238,225, + 242,237,229,238,233,225,110,128, 5, 63,104, 3, 16,114, 16,126, + 16,137,225,227,249,242,233,236,236,233, 99,128, 4, 37,229,233, + 227,239,240,244,233, 99,128, 3,230,239,239,107,128, 1,152,234, + 229,227,249,242,233,236,236,233, 99,128, 4, 12,236,233,238,229, + 226,229,236,239,119,128, 30, 52,237,239,238,239,243,240,225,227, + 101,128,255, 43,239,240,240, 97, 2, 16,189, 16,200,227,249,242, + 233,236,236,233, 99,128, 4,128,231,242,229,229,107,128, 3,222, + 115, 2, 16,214, 16,226,233,227,249,242,233,236,236,233, 99,128, + 4,110,237,225,236,108,128,247,107, 76,138, 0, 76, 17, 1, 17, + 5, 17, 9, 17, 29, 17, 95, 17,133, 17,147, 17,165, 17,177, 17, + 189, 74,128, 1,199, 76,128,246,191, 97, 2, 17, 15, 17, 22,227, + 245,244,101,128, 1, 57,237,226,228, 97,128, 3,155, 99, 4, 17, + 39, 17, 46, 17, 55, 17, 82,225,242,239,110,128, 1, 61,229,228, + 233,236,236, 97,128, 1, 59,233,242, 99, 2, 17, 63, 17, 68,236, + 101,128, 36,193,245,237,230,236,229,248,226,229,236,239,119,128, + 30, 60,239,237,237,225,225,227,227,229,238,116,128, 1, 59,228, + 239,116,130, 1, 63, 17,105, 17,114,225,227,227,229,238,116,128, + 1, 63,226,229,236,239,119,129, 30, 54, 17,124,237,225,227,242, + 239,110,128, 30, 56,233,247,238,225,242,237,229,238,233,225,110, + 128, 5, 60,106,129, 1,200, 17,153,229,227,249,242,233,236,236, + 233, 99,128, 4, 9,236,233,238,229,226,229,236,239,119,128, 30, + 58,237,239,238,239,243,240,225,227,101,128,255, 44,115, 2, 17, + 195, 17,212,236,225,243,104,129, 1, 65, 17,204,243,237,225,236, + 108,128,246,249,237,225,236,108,128,247,108, 77,137, 0, 77, 17, + 241, 17,251, 18, 24, 18, 33, 18, 58, 18, 71, 18, 83, 18, 91, 18, + 100,194,243,241,245,225,242,101,128, 51,134,225, 99, 2, 18, 2, + 18, 18,242,239,110,129,246,208, 18, 10,243,237,225,236,108,128, + 247,175,245,244,101,128, 30, 62,227,233,242,227,236,101,128, 36, + 194,228,239,116, 2, 18, 41, 18, 50,225,227,227,229,238,116,128, + 30, 64,226,229,236,239,119,128, 30, 66,229,238,225,242,237,229, + 238,233,225,110,128, 5, 68,237,239,238,239,243,240,225,227,101, + 128,255, 45,243,237,225,236,108,128,247,109,244,245,242,238,229, + 100,128, 1,156,117,128, 3,156, 78,141, 0, 78, 18,134, 18,138, + 18,146, 18,212, 18,237, 18,248, 19, 3, 19, 21, 19, 33, 19, 45, + 19, 58, 19, 66, 19, 84, 74,128, 1,202,225,227,245,244,101,128, + 1, 67, 99, 4, 18,156, 18,163, 18,172, 18,199,225,242,239,110, + 128, 1, 71,229,228,233,236,236, 97,128, 1, 69,233,242, 99, 2, + 18,180, 18,185,236,101,128, 36,195,245,237,230,236,229,248,226, + 229,236,239,119,128, 30, 74,239,237,237,225,225,227,227,229,238, + 116,128, 1, 69,228,239,116, 2, 18,220, 18,229,225,227,227,229, + 238,116,128, 30, 68,226,229,236,239,119,128, 30, 70,232,239,239, + 235,236,229,230,116,128, 1,157,233,238,229,242,239,237,225,110, + 128, 33,104,106,129, 1,203, 19, 9,229,227,249,242,233,236,236, + 233, 99,128, 4, 10,236,233,238,229,226,229,236,239,119,128, 30, + 72,237,239,238,239,243,240,225,227,101,128,255, 46,239,247,225, + 242,237,229,238,233,225,110,128, 5, 70,243,237,225,236,108,128, + 247,110,244,233,236,228,101,129, 0,209, 19, 76,243,237,225,236, + 108,128,247,241,117,128, 3,157, 79,141, 0, 79, 19,118, 19,132, + 19,150, 19,203, 20, 78, 20,152, 20,187, 21, 48, 21, 69, 21,213, + 21,223, 21,254, 22, 53, 69,129, 1, 82, 19,124,243,237,225,236, + 108,128,246,250,225,227,245,244,101,129, 0,211, 19,142,243,237, + 225,236,108,128,247,243, 98, 2, 19,156, 19,196,225,242,242,229, + 100, 2, 19,166, 19,177,227,249,242,233,236,236,233, 99,128, 4, + 232,228,233,229,242,229,243,233,243,227,249,242,233,236,236,233, + 99,128, 4,234,242,229,246,101,128, 1, 78, 99, 4, 19,213, 19, + 220, 19,235, 20, 68,225,242,239,110,128, 1,209,229,238,244,229, + 242,229,228,244,233,236,228,101,128, 1,159,233,242, 99, 2, 19, + 243, 19,248,236,101,128, 36,196,245,237,230,236,229,120,134, 0, + 212, 20, 13, 20, 21, 20, 32, 20, 40, 20, 52, 20, 60,225,227,245, + 244,101,128, 30,208,228,239,244,226,229,236,239,119,128, 30,216, + 231,242,225,246,101,128, 30,210,232,239,239,235,225,226,239,246, + 101,128, 30,212,243,237,225,236,108,128,247,244,244,233,236,228, + 101,128, 30,214,249,242,233,236,236,233, 99,128, 4, 30,100, 3, + 20, 86, 20,109, 20,142,226,108, 2, 20, 93, 20,101,225,227,245, + 244,101,128, 1, 80,231,242,225,246,101,128, 2, 12,233,229,242, + 229,243,233,115,130, 0,214, 20,123, 20,134,227,249,242,233,236, + 236,233, 99,128, 4,230,243,237,225,236,108,128,247,246,239,244, + 226,229,236,239,119,128, 30,204,103, 2, 20,158, 20,170,239,238, + 229,235,243,237,225,236,108,128,246,251,242,225,246,101,129, 0, + 210, 20,179,243,237,225,236,108,128,247,242,104, 4, 20,197, 20, + 208, 20,212, 21, 34,225,242,237,229,238,233,225,110,128, 5, 85, + 109,128, 33, 38,111, 2, 20,218, 20,228,239,235,225,226,239,246, + 101,128, 30,206,242,110,133, 1,160, 20,243, 20,251, 21, 6, 21, + 14, 21, 26,225,227,245,244,101,128, 30,218,228,239,244,226,229, + 236,239,119,128, 30,226,231,242,225,246,101,128, 30,220,232,239, + 239,235,225,226,239,246,101,128, 30,222,244,233,236,228,101,128, + 30,224,245,238,231,225,242,245,237,236,225,245,116,128, 1, 80, + 105,129, 1,162, 21, 54,238,246,229,242,244,229,228,226,242,229, + 246,101,128, 2, 14,109, 4, 21, 79, 21,107, 21,184, 21,202,225, + 227,242,239,110,130, 1, 76, 21, 91, 21, 99,225,227,245,244,101, + 128, 30, 82,231,242,225,246,101,128, 30, 80,229,231, 97,132, 33, + 38, 21,121, 21,132, 21,140, 21,156,227,249,242,233,236,236,233, + 99,128, 4, 96,231,242,229,229,107,128, 3,169,242,239,245,238, + 228,227,249,242,233,236,236,233, 99,128, 4,122,116, 2, 21,162, + 21,177,233,244,236,239,227,249,242,233,236,236,233, 99,128, 4, + 124,239,238,239,115,128, 3,143,233,227,242,239,110,129, 3,159, + 21,194,244,239,238,239,115,128, 3,140,239,238,239,243,240,225, + 227,101,128,255, 47,238,229,242,239,237,225,110,128, 33, 96,111, + 2, 21,229, 21,248,231,239,238,229,107,129, 1,234, 21,239,237, + 225,227,242,239,110,128, 1,236,240,229,110,128, 1,134,115, 3, + 22, 6, 22, 33, 22, 40,236,225,243,104,130, 0,216, 22, 17, 22, + 25,225,227,245,244,101,128, 1,254,243,237,225,236,108,128,247, + 248,237,225,236,108,128,247,111,244,242,239,235,229,225,227,245, + 244,101,128, 1,254,116, 2, 22, 59, 22, 70,227,249,242,233,236, + 236,233, 99,128, 4,126,233,236,228,101,131, 0,213, 22, 83, 22, + 91, 22,102,225,227,245,244,101,128, 30, 76,228,233,229,242,229, + 243,233,115,128, 30, 78,243,237,225,236,108,128,247,245, 80,136, + 0, 80, 22,130, 22,138, 22,147, 22,159, 22,211, 22,227, 22,246, + 23, 2,225,227,245,244,101,128, 30, 84,227,233,242,227,236,101, + 128, 36,197,228,239,244,225,227,227,229,238,116,128, 30, 86,101, + 3, 22,167, 22,178, 22,190,227,249,242,233,236,236,233, 99,128, + 4, 31,232,225,242,237,229,238,233,225,110,128, 5, 74,237,233, + 228,228,236,229,232,239,239,235,227,249,242,233,236,236,233, 99, + 128, 4,166,104, 2, 22,217, 22,221,105,128, 3,166,239,239,107, + 128, 1,164,105,129, 3,160, 22,233,247,242,225,242,237,229,238, + 233,225,110,128, 5, 83,237,239,238,239,243,240,225,227,101,128, + 255, 48,115, 2, 23, 8, 23, 25,105,129, 3,168, 23, 14,227,249, + 242,233,236,236,233, 99,128, 4,112,237,225,236,108,128,247,112, + 81,131, 0, 81, 23, 42, 23, 51, 23, 63,227,233,242,227,236,101, + 128, 36,198,237,239,238,239,243,240,225,227,101,128,255, 49,243, + 237,225,236,108,128,247,113, 82,138, 0, 82, 23, 95, 23,119, 23, + 166, 23,217, 23,230, 23,240, 23,245, 24, 19, 24, 31, 24, 43, 97, + 2, 23,101, 23,112,225,242,237,229,238,233,225,110,128, 5, 76, + 227,245,244,101,128, 1, 84, 99, 4, 23,129, 23,136, 23,145, 23, + 153,225,242,239,110,128, 1, 88,229,228,233,236,236, 97,128, 1, + 86,233,242,227,236,101,128, 36,199,239,237,237,225,225,227,227, + 229,238,116,128, 1, 86,100, 2, 23,172, 23,182,226,236,231,242, + 225,246,101,128, 2, 16,239,116, 2, 23,189, 23,198,225,227,227, + 229,238,116,128, 30, 88,226,229,236,239,119,129, 30, 90, 23,208, + 237,225,227,242,239,110,128, 30, 92,229,232,225,242,237,229,238, + 233,225,110,128, 5, 80,230,242,225,235,244,245,114,128, 33, 28, + 232,111,128, 3,161,233,110, 2, 23,252, 24, 5,231,243,237,225, + 236,108,128,246,252,246,229,242,244,229,228,226,242,229,246,101, + 128, 2, 18,236,233,238,229,226,229,236,239,119,128, 30, 94,237, + 239,238,239,243,240,225,227,101,128,255, 50,243,237,225,236,108, + 129,247,114, 24, 53,233,238,246,229,242,244,229,100,129, 2,129, + 24, 66,243,245,240,229,242,233,239,114,128, 2,182, 83,139, 0, + 83, 24,103, 26, 17, 26, 55, 26,182, 26,221, 26,250, 27, 84, 27, + 105, 27,117, 27,135, 27,143, 70, 6, 24,117, 24,209, 24,241, 25, + 77, 25,119, 25,221, 48, 9, 24,137, 24,145, 24,153, 24,161, 24, + 169, 24,177, 24,185, 24,193, 24,201,177,176,176,176, 48,128, 37, + 12,178,176,176,176, 48,128, 37, 20,179,176,176,176, 48,128, 37, + 16,180,176,176,176, 48,128, 37, 24,181,176,176,176, 48,128, 37, + 60,182,176,176,176, 48,128, 37, 44,183,176,176,176, 48,128, 37, + 52,184,176,176,176, 48,128, 37, 28,185,176,176,176, 48,128, 37, + 36, 49, 3, 24,217, 24,225, 24,233,176,176,176,176, 48,128, 37, + 0,177,176,176,176, 48,128, 37, 2,185,176,176,176, 48,128, 37, + 97, 50, 9, 25, 5, 25, 13, 25, 21, 25, 29, 25, 37, 25, 45, 25, + 53, 25, 61, 25, 69,176,176,176,176, 48,128, 37, 98,177,176,176, + 176, 48,128, 37, 86,178,176,176,176, 48,128, 37, 85,179,176,176, + 176, 48,128, 37, 99,180,176,176,176, 48,128, 37, 81,181,176,176, + 176, 48,128, 37, 87,182,176,176,176, 48,128, 37, 93,183,176,176, + 176, 48,128, 37, 92,184,176,176,176, 48,128, 37, 91, 51, 4, 25, + 87, 25, 95, 25,103, 25,111,182,176,176,176, 48,128, 37, 94,183, + 176,176,176, 48,128, 37, 95,184,176,176,176, 48,128, 37, 90,185, + 176,176,176, 48,128, 37, 84, 52, 10, 25,141, 25,149, 25,157, 25, + 165, 25,173, 25,181, 25,189, 25,197, 25,205, 25,213,176,176,176, + 176, 48,128, 37,105,177,176,176,176, 48,128, 37,102,178,176,176, + 176, 48,128, 37, 96,179,176,176,176, 48,128, 37, 80,180,176,176, + 176, 48,128, 37,108,181,176,176,176, 48,128, 37,103,182,176,176, + 176, 48,128, 37,104,183,176,176,176, 48,128, 37,100,184,176,176, + 176, 48,128, 37,101,185,176,176,176, 48,128, 37, 89, 53, 5, 25, + 233, 25,241, 25,249, 26, 1, 26, 9,176,176,176,176, 48,128, 37, + 88,177,176,176,176, 48,128, 37, 82,178,176,176,176, 48,128, 37, + 83,179,176,176,176, 48,128, 37,107,180,176,176,176, 48,128, 37, + 106, 97, 2, 26, 23, 26, 44,227,245,244,101,129, 1, 90, 26, 32, + 228,239,244,225,227,227,229,238,116,128, 30,100,237,240,233,231, + 242,229,229,107,128, 3,224, 99, 5, 26, 67, 26, 98, 26,107, 26, + 147, 26,169,225,242,239,110,130, 1, 96, 26, 78, 26, 90,228,239, + 244,225,227,227,229,238,116,128, 30,102,243,237,225,236,108,128, + 246,253,229,228,233,236,236, 97,128, 1, 94,232,247, 97,130, 1, + 143, 26,117, 26,128,227,249,242,233,236,236,233, 99,128, 4,216, + 228,233,229,242,229,243,233,243,227,249,242,233,236,236,233, 99, + 128, 4,218,233,242, 99, 2, 26,155, 26,160,236,101,128, 36,200, + 245,237,230,236,229,120,128, 1, 92,239,237,237,225,225,227,227, + 229,238,116,128, 2, 24,228,239,116, 2, 26,190, 26,199,225,227, + 227,229,238,116,128, 30, 96,226,229,236,239,119,129, 30, 98, 26, + 209,228,239,244,225,227,227,229,238,116,128, 30,104,101, 2, 26, + 227, 26,239,232,225,242,237,229,238,233,225,110,128, 5, 77,246, + 229,238,242,239,237,225,110,128, 33,102,104, 5, 27, 6, 27, 34, + 27, 48, 27, 59, 27, 72, 97, 2, 27, 12, 27, 23,225,242,237,229, + 238,233,225,110,128, 5, 71,227,249,242,233,236,236,233, 99,128, + 4, 40,227,232,225,227,249,242,233,236,236,233, 99,128, 4, 41, + 229,233,227,239,240,244,233, 99,128, 3,226,232,225,227,249,242, + 233,236,236,233, 99,128, 4,186,233,237,225,227,239,240,244,233, + 99,128, 3,236,105, 2, 27, 90, 27, 96,231,237, 97,128, 3,163, + 248,242,239,237,225,110,128, 33,101,237,239,238,239,243,240,225, + 227,101,128,255, 51,239,230,244,243,233,231,238,227,249,242,233, + 236,236,233, 99,128, 4, 44,243,237,225,236,108,128,247,115,244, + 233,231,237,225,231,242,229,229,107,128, 3,218, 84,141, 0, 84, + 27,186, 27,191, 27,197, 28, 7, 28, 32, 28, 96, 28,147, 28,177, + 28,189, 28,201, 28,246, 29, 6, 29, 46,225,117,128, 3,164,226, + 225,114,128, 1,102, 99, 4, 27,207, 27,214, 27,223, 27,250,225, + 242,239,110,128, 1,100,229,228,233,236,236, 97,128, 1, 98,233, + 242, 99, 2, 27,231, 27,236,236,101,128, 36,201,245,237,230,236, + 229,248,226,229,236,239,119,128, 30,112,239,237,237,225,225,227, + 227,229,238,116,128, 1, 98,228,239,116, 2, 28, 15, 28, 24,225, + 227,227,229,238,116,128, 30,106,226,229,236,239,119,128, 30,108, + 101, 4, 28, 42, 28, 53, 28, 73, 28, 82,227,249,242,233,236,236, + 233, 99,128, 4, 34,228,229,243,227,229,238,228,229,242,227,249, + 242,233,236,236,233, 99,128, 4,172,238,242,239,237,225,110,128, + 33,105,244,243,229,227,249,242,233,236,236,233, 99,128, 4,180, + 104, 3, 28,104, 28,110, 28,136,229,244, 97,128, 3,152,111, 2, + 28,116, 28,121,239,107,128, 1,172,242,110,129, 0,222, 28,128, + 243,237,225,236,108,128,247,254,242,229,229,242,239,237,225,110, + 128, 33, 98,105, 2, 28,153, 28,164,236,228,229,243,237,225,236, + 108,128,246,254,247,238,225,242,237,229,238,233,225,110,128, 5, + 79,236,233,238,229,226,229,236,239,119,128, 30,110,237,239,238, + 239,243,240,225,227,101,128,255, 52,111, 2, 28,207, 28,218,225, + 242,237,229,238,233,225,110,128, 5, 57,238,101, 3, 28,227, 28, + 234, 28,240,230,233,246,101,128, 1,188,243,233,120,128, 1,132, + 244,247,111,128, 1,167,242,229,244,242,239,230,236,229,248,232, + 239,239,107,128, 1,174,115, 3, 29, 14, 29, 26, 29, 39,229,227, + 249,242,233,236,236,233, 99,128, 4, 38,232,229,227,249,242,233, + 236,236,233, 99,128, 4, 11,237,225,236,108,128,247,116,119, 2, + 29, 52, 29, 64,229,236,246,229,242,239,237,225,110,128, 33,107, + 239,242,239,237,225,110,128, 33, 97, 85,142, 0, 85, 29,105, 29, + 123, 29,131, 29,198, 30, 69, 30, 87, 30,198, 30,214, 30,226, 31, + 21, 31, 30, 31,142, 31,149, 31,219,225,227,245,244,101,129, 0, + 218, 29,115,243,237,225,236,108,128,247,250,226,242,229,246,101, + 128, 1,108, 99, 3, 29,139, 29,146, 29,188,225,242,239,110,128, + 1,211,233,242, 99, 2, 29,154, 29,159,236,101,128, 36,202,245, + 237,230,236,229,120,130, 0,219, 29,172, 29,180,226,229,236,239, + 119,128, 30,118,243,237,225,236,108,128,247,251,249,242,233,236, + 236,233, 99,128, 4, 35,100, 3, 29,206, 29,229, 30, 59,226,108, + 2, 29,213, 29,221,225,227,245,244,101,128, 1,112,231,242,225, + 246,101,128, 2, 20,233,229,242,229,243,233,115,134, 0,220, 29, + 251, 30, 3, 30, 11, 30, 34, 30, 42, 30, 51,225,227,245,244,101, + 128, 1,215,226,229,236,239,119,128, 30,114, 99, 2, 30, 17, 30, + 24,225,242,239,110,128, 1,217,249,242,233,236,236,233, 99,128, + 4,240,231,242,225,246,101,128, 1,219,237,225,227,242,239,110, + 128, 1,213,243,237,225,236,108,128,247,252,239,244,226,229,236, + 239,119,128, 30,228,231,242,225,246,101,129, 0,217, 30, 79,243, + 237,225,236,108,128,247,249,104, 2, 30, 93, 30,171,111, 2, 30, + 99, 30,109,239,235,225,226,239,246,101,128, 30,230,242,110,133, + 1,175, 30,124, 30,132, 30,143, 30,151, 30,163,225,227,245,244, + 101,128, 30,232,228,239,244,226,229,236,239,119,128, 30,240,231, + 242,225,246,101,128, 30,234,232,239,239,235,225,226,239,246,101, + 128, 30,236,244,233,236,228,101,128, 30,238,245,238,231,225,242, + 245,237,236,225,245,116,129, 1,112, 30,187,227,249,242,233,236, + 236,233, 99,128, 4,242,233,238,246,229,242,244,229,228,226,242, + 229,246,101,128, 2, 22,235,227,249,242,233,236,236,233, 99,128, + 4,120,109, 2, 30,232, 31, 10,225,227,242,239,110,130, 1,106, + 30,244, 30,255,227,249,242,233,236,236,233, 99,128, 4,238,228, + 233,229,242,229,243,233,115,128, 30,122,239,238,239,243,240,225, + 227,101,128,255, 53,239,231,239,238,229,107,128, 1,114,240,243, + 233,236,239,110,133, 3,165, 31, 49, 31, 53, 31, 90, 31,121, 31, + 134, 49,128, 3,210, 97, 2, 31, 59, 31, 81,227,245,244,229,232, + 239,239,235,243,249,237,226,239,236,231,242,229,229,107,128, 3, + 211,230,242,233,227,225,110,128, 1,177,228,233,229,242,229,243, + 233,115,129, 3,171, 31,103,232,239,239,235,243,249,237,226,239, + 236,231,242,229,229,107,128, 3,212,232,239,239,235,243,249,237, + 226,239,108,128, 3,210,244,239,238,239,115,128, 3,142,242,233, + 238,103,128, 1,110,115, 3, 31,157, 31,172, 31,179,232,239,242, + 244,227,249,242,233,236,236,233, 99,128, 4, 14,237,225,236,108, + 128,247,117,244,242,225,233,231,232,116, 2, 31,191, 31,202,227, + 249,242,233,236,236,233, 99,128, 4,174,243,244,242,239,235,229, + 227,249,242,233,236,236,233, 99,128, 4,176,244,233,236,228,101, + 130, 1,104, 31,231, 31,239,225,227,245,244,101,128, 30,120,226, + 229,236,239,119,128, 30,116, 86,136, 0, 86, 32, 11, 32, 20, 32, + 31, 32, 60, 32, 67, 32, 79, 32, 91, 32, 99,227,233,242,227,236, + 101,128, 36,203,228,239,244,226,229,236,239,119,128, 30,126,101, + 2, 32, 37, 32, 48,227,249,242,233,236,236,233, 99,128, 4, 18, + 247,225,242,237,229,238,233,225,110,128, 5, 78,232,239,239,107, + 128, 1,178,237,239,238,239,243,240,225,227,101,128,255, 54,239, + 225,242,237,229,238,233,225,110,128, 5, 72,243,237,225,236,108, + 128,247,118,244,233,236,228,101,128, 30,124, 87,134, 0, 87, 32, + 123, 32,131, 32,154, 32,194, 32,202, 32,214,225,227,245,244,101, + 128, 30,130,227,233,242, 99, 2, 32,140, 32,145,236,101,128, 36, + 204,245,237,230,236,229,120,128, 1,116,100, 2, 32,160, 32,170, + 233,229,242,229,243,233,115,128, 30,132,239,116, 2, 32,177, 32, + 186,225,227,227,229,238,116,128, 30,134,226,229,236,239,119,128, + 30,136,231,242,225,246,101,128, 30,128,237,239,238,239,243,240, + 225,227,101,128,255, 55,243,237,225,236,108,128,247,119, 88,134, + 0, 88, 32,238, 32,247, 33, 18, 33, 31, 33, 35, 33, 47,227,233, + 242,227,236,101,128, 36,205,100, 2, 32,253, 33, 7,233,229,242, + 229,243,233,115,128, 30,140,239,244,225,227,227,229,238,116,128, + 30,138,229,232,225,242,237,229,238,233,225,110,128, 5, 61,105, + 128, 3,158,237,239,238,239,243,240,225,227,101,128,255, 56,243, + 237,225,236,108,128,247,120, 89,139, 0, 89, 33, 81, 33,116, 33, + 139, 33,189, 33,228, 33,236, 33,253, 34, 40, 34, 52, 34, 60, 34, + 68, 97, 2, 33, 87, 33,104,227,245,244,101,129, 0,221, 33, 96, + 243,237,225,236,108,128,247,253,244,227,249,242,233,236,236,233, + 99,128, 4, 98,227,233,242, 99, 2, 33,125, 33,130,236,101,128, + 36,206,245,237,230,236,229,120,128, 1,118,100, 2, 33,145, 33, + 165,233,229,242,229,243,233,115,129, 1,120, 33,157,243,237,225, + 236,108,128,247,255,239,116, 2, 33,172, 33,181,225,227,227,229, + 238,116,128, 30,142,226,229,236,239,119,128, 30,244,229,114, 2, + 33,196, 33,208,233,227,249,242,233,236,236,233, 99,128, 4, 43, + 245,228,233,229,242,229,243,233,243,227,249,242,233,236,236,233, + 99,128, 4,248,231,242,225,246,101,128, 30,242,232,239,239,107, + 129, 1,179, 33,245,225,226,239,246,101,128, 30,246,105, 3, 34, + 5, 34, 16, 34, 27,225,242,237,229,238,233,225,110,128, 5, 69, + 227,249,242,233,236,236,233, 99,128, 4, 7,247,238,225,242,237, + 229,238,233,225,110,128, 5, 82,237,239,238,239,243,240,225,227, + 101,128,255, 57,243,237,225,236,108,128,247,121,244,233,236,228, + 101,128, 30,248,245,115, 2, 34, 75, 34,113,226,233,103, 2, 34, + 83, 34, 94,227,249,242,233,236,236,233, 99,128, 4,106,233,239, + 244,233,230,233,229,228,227,249,242,233,236,236,233, 99,128, 4, + 108,236,233,244,244,236,101, 2, 34,124, 34,135,227,249,242,233, + 236,236,233, 99,128, 4,102,233,239,244,233,230,233,229,228,227, + 249,242,233,236,236,233, 99,128, 4,104, 90,136, 0, 90, 34,174, + 34,198, 34,243, 35, 14, 35, 81, 35,173, 35,185, 35,197, 97, 2, + 34,180, 34,191,225,242,237,229,238,233,225,110,128, 5, 54,227, + 245,244,101,128, 1,121, 99, 2, 34,204, 34,221,225,242,239,110, + 129, 1,125, 34,213,243,237,225,236,108,128,246,255,233,242, 99, + 2, 34,229, 34,234,236,101,128, 36,207,245,237,230,236,229,120, + 128, 30,144,228,239,116,130, 1,123, 34,253, 35, 6,225,227,227, + 229,238,116,128, 1,123,226,229,236,239,119,128, 30,146,101, 3, + 35, 22, 35, 33, 35, 76,227,249,242,233,236,236,233, 99,128, 4, + 23,100, 2, 35, 39, 35, 58,229,243,227,229,238,228,229,242,227, + 249,242,233,236,236,233, 99,128, 4,152,233,229,242,229,243,233, + 243,227,249,242,233,236,236,233, 99,128, 4,222,244, 97,128, 3, + 150,232,101, 4, 35, 92, 35,103, 35,119, 35,130,225,242,237,229, + 238,233,225,110,128, 5, 58,226,242,229,246,229,227,249,242,233, + 236,236,233, 99,128, 4,193,227,249,242,233,236,236,233, 99,128, + 4, 22,100, 2, 35,136, 35,155,229,243,227,229,238,228,229,242, + 227,249,242,233,236,236,233, 99,128, 4,150,233,229,242,229,243, + 233,243,227,249,242,233,236,236,233, 99,128, 4,220,236,233,238, + 229,226,229,236,239,119,128, 30,148,237,239,238,239,243,240,225, + 227,101,128,255, 58,115, 2, 35,203, 35,210,237,225,236,108,128, + 247,122,244,242,239,235,101,128, 1,181, 97,149, 0, 97, 36, 8, + 36,144, 37, 35, 37,211, 38, 55, 38, 91, 45, 10, 45, 47, 45, 74, + 46, 43, 46, 81, 47,170, 47,242, 48,197, 48,206, 49, 79, 51, 87, + 52, 77, 52,124, 53, 19, 53, 33, 97, 7, 36, 24, 36, 34, 36, 41, + 36, 48, 36, 73, 36, 89, 36,100,226,229,238,231,225,236,105,128, + 9,134,227,245,244,101,128, 0,225,228,229,246, 97,128, 9, 6, + 231,117, 2, 36, 55, 36, 64,234,225,242,225,244,105,128, 10,134, + 242,237,245,235,232,105,128, 10, 6,237,225,244,242,225,231,245, + 242,237,245,235,232,105,128, 10, 62,242,245,243,241,245,225,242, + 101,128, 51, 3,246,239,247,229,236,243,233,231,110, 3, 36,116, + 36,126, 36,133,226,229,238,231,225,236,105,128, 9,190,228,229, + 246, 97,128, 9, 62,231,245,234,225,242,225,244,105,128, 10,190, + 98, 4, 36,154, 36,195, 36,204, 36,214,226,242,229,246,233,225, + 244,233,239,110, 2, 36,169, 36,184,237,225,242,235,225,242,237, + 229,238,233,225,110,128, 5, 95,243,233,231,238,228,229,246, 97, + 128, 9,112,229,238,231,225,236,105,128, 9,133,239,240,239,237, + 239,230,111,128, 49, 26,242,229,246,101,134, 1, 3, 36,233, 36, + 241, 36,252, 37, 7, 37, 15, 37, 27,225,227,245,244,101,128, 30, + 175,227,249,242,233,236,236,233, 99,128, 4,209,228,239,244,226, + 229,236,239,119,128, 30,183,231,242,225,246,101,128, 30,177,232, + 239,239,235,225,226,239,246,101,128, 30,179,244,233,236,228,101, + 128, 30,181, 99, 4, 37, 45, 37, 52, 37,131, 37,201,225,242,239, + 110,128, 1,206,233,242, 99, 2, 37, 60, 37, 65,236,101,128, 36, + 208,245,237,230,236,229,120,133, 0,226, 37, 84, 37, 92, 37,103, + 37,111, 37,123,225,227,245,244,101,128, 30,165,228,239,244,226, + 229,236,239,119,128, 30,173,231,242,225,246,101,128, 30,167,232, + 239,239,235,225,226,239,246,101,128, 30,169,244,233,236,228,101, + 128, 30,171,245,244,101,133, 0,180, 37,147, 37,158, 37,175, 37, + 182, 37,191,226,229,236,239,247,227,237, 98,128, 3, 23, 99, 2, + 37,164, 37,169,237, 98,128, 3, 1,239,237, 98,128, 3, 1,228, + 229,246, 97,128, 9, 84,236,239,247,237,239,100,128, 2,207,244, + 239,238,229,227,237, 98,128, 3, 65,249,242,233,236,236,233, 99, + 128, 4, 48,100, 5, 37,223, 37,233, 37,247, 37,253, 38, 31,226, + 236,231,242,225,246,101,128, 2, 1,228,225,235,231,245,242,237, + 245,235,232,105,128, 10,113,229,246, 97,128, 9, 5,233,229,242, + 229,243,233,115,130, 0,228, 38, 11, 38, 22,227,249,242,233,236, + 236,233, 99,128, 4,211,237,225,227,242,239,110,128, 1,223,239, + 116, 2, 38, 38, 38, 46,226,229,236,239,119,128, 30,161,237,225, + 227,242,239,110,128, 1,225,101,131, 0,230, 38, 65, 38, 73, 38, + 82,225,227,245,244,101,128, 1,253,235,239,242,229,225,110,128, + 49, 80,237,225,227,242,239,110,128, 1,227,230,233,105, 6, 38, + 107, 38,127, 41, 64, 41, 70, 41, 85, 44,185, 48, 2, 38,113, 38, + 120,176,178,176, 56,128, 32, 21,184,185,180, 49,128, 32,164,177, + 48, 3, 38,136, 40,160, 41, 39, 48, 9, 38,156, 38,176, 38,238, + 39, 44, 39,106, 39,168, 39,230, 40, 36, 40, 98, 49, 3, 38,164, + 38,168, 38,172, 55,128, 4, 16, 56,128, 4, 17, 57,128, 4, 18, + 50, 10, 38,198, 38,202, 38,206, 38,210, 38,214, 38,218, 38,222, + 38,226, 38,230, 38,234, 48,128, 4, 19, 49,128, 4, 20, 50,128, + 4, 21, 51,128, 4, 1, 52,128, 4, 22, 53,128, 4, 23, 54,128, + 4, 24, 55,128, 4, 25, 56,128, 4, 26, 57,128, 4, 27, 51, 10, + 39, 4, 39, 8, 39, 12, 39, 16, 39, 20, 39, 24, 39, 28, 39, 32, + 39, 36, 39, 40, 48,128, 4, 28, 49,128, 4, 29, 50,128, 4, 30, + 51,128, 4, 31, 52,128, 4, 32, 53,128, 4, 33, 54,128, 4, 34, + 55,128, 4, 35, 56,128, 4, 36, 57,128, 4, 37, 52, 10, 39, 66, + 39, 70, 39, 74, 39, 78, 39, 82, 39, 86, 39, 90, 39, 94, 39, 98, + 39,102, 48,128, 4, 38, 49,128, 4, 39, 50,128, 4, 40, 51,128, + 4, 41, 52,128, 4, 42, 53,128, 4, 43, 54,128, 4, 44, 55,128, + 4, 45, 56,128, 4, 46, 57,128, 4, 47, 53, 10, 39,128, 39,132, + 39,136, 39,140, 39,144, 39,148, 39,152, 39,156, 39,160, 39,164, + 48,128, 4,144, 49,128, 4, 2, 50,128, 4, 3, 51,128, 4, 4, + 52,128, 4, 5, 53,128, 4, 6, 54,128, 4, 7, 55,128, 4, 8, + 56,128, 4, 9, 57,128, 4, 10, 54, 10, 39,190, 39,194, 39,198, + 39,202, 39,206, 39,210, 39,214, 39,218, 39,222, 39,226, 48,128, + 4, 11, 49,128, 4, 12, 50,128, 4, 14, 51,128,246,196, 52,128, + 246,197, 53,128, 4, 48, 54,128, 4, 49, 55,128, 4, 50, 56,128, + 4, 51, 57,128, 4, 52, 55, 10, 39,252, 40, 0, 40, 4, 40, 8, + 40, 12, 40, 16, 40, 20, 40, 24, 40, 28, 40, 32, 48,128, 4, 53, + 49,128, 4, 81, 50,128, 4, 54, 51,128, 4, 55, 52,128, 4, 56, + 53,128, 4, 57, 54,128, 4, 58, 55,128, 4, 59, 56,128, 4, 60, + 57,128, 4, 61, 56, 10, 40, 58, 40, 62, 40, 66, 40, 70, 40, 74, + 40, 78, 40, 82, 40, 86, 40, 90, 40, 94, 48,128, 4, 62, 49,128, + 4, 63, 50,128, 4, 64, 51,128, 4, 65, 52,128, 4, 66, 53,128, + 4, 67, 54,128, 4, 68, 55,128, 4, 69, 56,128, 4, 70, 57,128, + 4, 71, 57, 10, 40,120, 40,124, 40,128, 40,132, 40,136, 40,140, + 40,144, 40,148, 40,152, 40,156, 48,128, 4, 72, 49,128, 4, 73, + 50,128, 4, 74, 51,128, 4, 75, 52,128, 4, 76, 53,128, 4, 77, + 54,128, 4, 78, 55,128, 4, 79, 56,128, 4,145, 57,128, 4, 82, + 49, 4, 40,170, 40,232, 40,237, 41, 7, 48, 10, 40,192, 40,196, + 40,200, 40,204, 40,208, 40,212, 40,216, 40,220, 40,224, 40,228, + 48,128, 4, 83, 49,128, 4, 84, 50,128, 4, 85, 51,128, 4, 86, + 52,128, 4, 87, 53,128, 4, 88, 54,128, 4, 89, 55,128, 4, 90, + 56,128, 4, 91, 57,128, 4, 92,177, 48,128, 4, 94, 52, 4, 40, + 247, 40,251, 40,255, 41, 3, 53,128, 4, 15, 54,128, 4, 98, 55, + 128, 4,114, 56,128, 4,116, 57, 5, 41, 19, 41, 23, 41, 27, 41, + 31, 41, 35, 50,128,246,198, 51,128, 4, 95, 52,128, 4, 99, 53, + 128, 4,115, 54,128, 4,117, 56, 2, 41, 45, 41, 59, 51, 2, 41, + 51, 41, 55, 49,128,246,199, 50,128,246,200,180, 54,128, 4,217, + 178,185, 57,128, 32, 14,179, 48, 2, 41, 77, 41, 81, 48,128, 32, + 15, 49,128, 32, 13,181, 55, 7, 41,102, 41,172, 42,237, 43, 58, + 44, 15, 44,108, 44,179, 51, 2, 41,108, 41,122, 56, 2, 41,114, + 41,118, 49,128, 6,106, 56,128, 6, 12, 57, 8, 41,140, 41,144, + 41,148, 41,152, 41,156, 41,160, 41,164, 41,168, 50,128, 6, 96, + 51,128, 6, 97, 52,128, 6, 98, 53,128, 6, 99, 54,128, 6,100, + 55,128, 6,101, 56,128, 6,102, 57,128, 6,103, 52, 7, 41,188, + 41,220, 42, 26, 42, 88, 42,120, 42,176, 42,232, 48, 5, 41,200, + 41,204, 41,208, 41,212, 41,216, 48,128, 6,104, 49,128, 6,105, + 51,128, 6, 27, 55,128, 6, 31, 57,128, 6, 33, 49, 10, 41,242, + 41,246, 41,250, 41,254, 42, 2, 42, 6, 42, 10, 42, 14, 42, 18, + 42, 22, 48,128, 6, 34, 49,128, 6, 35, 50,128, 6, 36, 51,128, + 6, 37, 52,128, 6, 38, 53,128, 6, 39, 54,128, 6, 40, 55,128, + 6, 41, 56,128, 6, 42, 57,128, 6, 43, 50, 10, 42, 48, 42, 52, + 42, 56, 42, 60, 42, 64, 42, 68, 42, 72, 42, 76, 42, 80, 42, 84, + 48,128, 6, 44, 49,128, 6, 45, 50,128, 6, 46, 51,128, 6, 47, + 52,128, 6, 48, 53,128, 6, 49, 54,128, 6, 50, 55,128, 6, 51, + 56,128, 6, 52, 57,128, 6, 53, 51, 5, 42,100, 42,104, 42,108, + 42,112, 42,116, 48,128, 6, 54, 49,128, 6, 55, 50,128, 6, 56, + 51,128, 6, 57, 52,128, 6, 58, 52, 9, 42,140, 42,144, 42,148, + 42,152, 42,156, 42,160, 42,164, 42,168, 42,172, 48,128, 6, 64, + 49,128, 6, 65, 50,128, 6, 66, 51,128, 6, 67, 52,128, 6, 68, + 53,128, 6, 69, 54,128, 6, 70, 56,128, 6, 72, 57,128, 6, 73, + 53, 9, 42,196, 42,200, 42,204, 42,208, 42,212, 42,216, 42,220, + 42,224, 42,228, 48,128, 6, 74, 49,128, 6, 75, 50,128, 6, 76, + 51,128, 6, 77, 52,128, 6, 78, 53,128, 6, 79, 54,128, 6, 80, + 55,128, 6, 81, 56,128, 6, 82,183, 48,128, 6, 71, 53, 3, 42, + 245, 43, 21, 43, 53, 48, 5, 43, 1, 43, 5, 43, 9, 43, 13, 43, + 17, 53,128, 6,164, 54,128, 6,126, 55,128, 6,134, 56,128, 6, + 152, 57,128, 6,175, 49, 5, 43, 33, 43, 37, 43, 41, 43, 45, 43, + 49, 49,128, 6,121, 50,128, 6,136, 51,128, 6,145, 52,128, 6, + 186, 57,128, 6,210,179, 52,128, 6,213, 54, 7, 43, 74, 43, 79, + 43, 84, 43, 89, 43,127, 43,189, 43,251,179, 54,128, 32,170,180, + 53,128, 5,190,181, 56,128, 5,195, 54, 6, 43,103, 43,107, 43, + 111, 43,115, 43,119, 43,123, 52,128, 5,208, 53,128, 5,209, 54, + 128, 5,210, 55,128, 5,211, 56,128, 5,212, 57,128, 5,213, 55, + 10, 43,149, 43,153, 43,157, 43,161, 43,165, 43,169, 43,173, 43, + 177, 43,181, 43,185, 48,128, 5,214, 49,128, 5,215, 50,128, 5, + 216, 51,128, 5,217, 52,128, 5,218, 53,128, 5,219, 54,128, 5, + 220, 55,128, 5,221, 56,128, 5,222, 57,128, 5,223, 56, 10, 43, + 211, 43,215, 43,219, 43,223, 43,227, 43,231, 43,235, 43,239, 43, + 243, 43,247, 48,128, 5,224, 49,128, 5,225, 50,128, 5,226, 51, + 128, 5,227, 52,128, 5,228, 53,128, 5,229, 54,128, 5,230, 55, + 128, 5,231, 56,128, 5,232, 57,128, 5,233, 57, 3, 44, 3, 44, + 7, 44, 11, 48,128, 5,234, 52,128,251, 42, 53,128,251, 43, 55, + 4, 44, 25, 44, 39, 44, 59, 44, 64, 48, 2, 44, 31, 44, 35, 48, + 128,251, 75, 53,128,251, 31, 49, 3, 44, 47, 44, 51, 44, 55, 54, + 128, 5,240, 55,128, 5,241, 56,128, 5,242,178, 51,128,251, 53, + 57, 7, 44, 80, 44, 84, 44, 88, 44, 92, 44, 96, 44,100, 44,104, + 51,128, 5,180, 52,128, 5,181, 53,128, 5,182, 54,128, 5,187, + 55,128, 5,184, 56,128, 5,183, 57,128, 5,176, 56, 3, 44,116, + 44,160, 44,165, 48, 7, 44,132, 44,136, 44,140, 44,144, 44,148, + 44,152, 44,156, 48,128, 5,178, 49,128, 5,177, 50,128, 5,179, + 51,128, 5,194, 52,128, 5,193, 54,128, 5,185, 55,128, 5,188, + 179, 57,128, 5,189, 52, 2, 44,171, 44,175, 49,128, 5,191, 50, + 128, 5,192,185,178, 57,128, 2,188, 54, 3, 44,193, 44,252, 45, + 3, 49, 4, 44,203, 44,219, 44,225, 44,246, 50, 2, 44,209, 44, + 214,180, 56,128, 33, 5,184, 57,128, 33, 19,179,181, 50,128, 33, + 22,181, 55, 3, 44,234, 44,238, 44,242, 51,128, 32, 44, 52,128, + 32, 45, 53,128, 32, 46,182,182, 52,128, 32, 12,179,177,182, 55, + 128, 6,109,180,185,179, 55,128, 2,189,103, 2, 45, 16, 45, 23, + 242,225,246,101,128, 0,224,117, 2, 45, 29, 45, 38,234,225,242, + 225,244,105,128, 10,133,242,237,245,235,232,105,128, 10, 5,104, + 2, 45, 53, 45, 63,233,242,225,231,225,238, 97,128, 48, 66,239, + 239,235,225,226,239,246,101,128, 30,163,105, 7, 45, 90, 45,115, + 45,122, 45,134, 45,159, 45,175, 45,255, 98, 2, 45, 96, 45,105, + 229,238,231,225,236,105,128, 9,144,239,240,239,237,239,230,111, + 128, 49, 30,228,229,246, 97,128, 9, 16,229,227,249,242,233,236, + 236,233, 99,128, 4,213,231,117, 2, 45,141, 45,150,234,225,242, + 225,244,105,128, 10,144,242,237,245,235,232,105,128, 10, 16,237, + 225,244,242,225,231,245,242,237,245,235,232,105,128, 10, 72,110, + 5, 45,187, 45,196, 45,210, 45,226, 45,241,225,242,225,226,233, + 99,128, 6, 57,230,233,238,225,236,225,242,225,226,233, 99,128, + 254,202,233,238,233,244,233,225,236,225,242,225,226,233, 99,128, + 254,203,237,229,228,233,225,236,225,242,225,226,233, 99,128,254, + 204,246,229,242,244,229,228,226,242,229,246,101,128, 2, 3,246, + 239,247,229,236,243,233,231,110, 3, 46, 15, 46, 25, 46, 32,226, + 229,238,231,225,236,105,128, 9,200,228,229,246, 97,128, 9, 72, + 231,245,234,225,242,225,244,105,128, 10,200,107, 2, 46, 49, 46, + 73,225,244,225,235,225,238, 97,129, 48,162, 46, 61,232,225,236, + 230,247,233,228,244,104,128,255,113,239,242,229,225,110,128, 49, + 79,108, 3, 46, 89, 47,145, 47,154,101, 2, 46, 95, 47,140,102, + 136, 5,208, 46,115, 46,124, 46,139, 46,153, 46,242, 47, 0, 47, + 111, 47,125,225,242,225,226,233, 99,128, 6, 39,228,225,231,229, + 243,232,232,229,226,242,229,119,128,251, 48,230,233,238,225,236, + 225,242,225,226,233, 99,128,254,142,104, 2, 46,159, 46,234,225, + 237,250, 97, 2, 46,168, 46,201,225,226,239,246,101, 2, 46,178, + 46,187,225,242,225,226,233, 99,128, 6, 35,230,233,238,225,236, + 225,242,225,226,233, 99,128,254,132,226,229,236,239,119, 2, 46, + 211, 46,220,225,242,225,226,233, 99,128, 6, 37,230,233,238,225, + 236,225,242,225,226,233, 99,128,254,136,229,226,242,229,119,128, + 5,208,236,225,237,229,228,232,229,226,242,229,119,128,251, 79, + 237, 97, 2, 47, 7, 47, 43,228,228,225,225,226,239,246,101, 2, + 47, 20, 47, 29,225,242,225,226,233, 99,128, 6, 34,230,233,238, + 225,236,225,242,225,226,233, 99,128,254,130,235,243,245,242, 97, + 4, 47, 57, 47, 66, 47, 80, 47, 96,225,242,225,226,233, 99,128, + 6, 73,230,233,238,225,236,225,242,225,226,233, 99,128,254,240, + 233,238,233,244,233,225,236,225,242,225,226,233, 99,128,254,243, + 237,229,228,233,225,236,225,242,225,226,233, 99,128,254,244,240, + 225,244,225,232,232,229,226,242,229,119,128,251, 46,241,225,237, + 225,244,243,232,229,226,242,229,119,128,251, 47,240,104,128, 33, + 53,236,229,241,245,225,108,128, 34, 76,240,232, 97,129, 3,177, + 47,162,244,239,238,239,115,128, 3,172,109, 4, 47,180, 47,188, + 47,199, 47,233,225,227,242,239,110,128, 1, 1,239,238,239,243, + 240,225,227,101,128,255, 65,240,229,242,243,225,238,100,130, 0, + 38, 47,213, 47,225,237,239,238,239,243,240,225,227,101,128,255, + 6,243,237,225,236,108,128,247, 38,243,241,245,225,242,101,128, + 51,194,110, 4, 47,252, 48, 7, 48,129, 48,139,226,239,240,239, + 237,239,230,111,128, 49, 34,103, 4, 48, 17, 48, 28, 48, 42, 48, + 121,226,239,240,239,237,239,230,111,128, 49, 36,235,232,225,238, + 235,232,245,244,232,225,105,128, 14, 90,236,101,131, 34, 32, 48, + 53, 48,106, 48,113,226,242,225,227,235,229,116, 2, 48, 65, 48, + 85,236,229,230,116,129, 48, 8, 48, 74,246,229,242,244,233,227, + 225,108,128,254, 63,242,233,231,232,116,129, 48, 9, 48, 95,246, + 229,242,244,233,227,225,108,128,254, 64,236,229,230,116,128, 35, + 41,242,233,231,232,116,128, 35, 42,243,244,242,239,109,128, 33, + 43,239,244,229,236,229,233, 97,128, 3,135,117, 2, 48,145, 48, + 157,228,225,244,244,225,228,229,246, 97,128, 9, 82,243,246,225, + 242, 97, 3, 48,169, 48,179, 48,186,226,229,238,231,225,236,105, + 128, 9,130,228,229,246, 97,128, 9, 2,231,245,234,225,242,225, + 244,105,128, 10,130,239,231,239,238,229,107,128, 1, 5,112, 3, + 48,214, 48,238, 49, 12, 97, 2, 48,220, 48,232,225,244,239,243, + 241,245,225,242,101,128, 51, 0,242,229,110,128, 36,156,239,243, + 244,242,239,240,232,101, 2, 48,251, 49, 6,225,242,237,229,238, + 233,225,110,128, 5, 90,237,239,100,128, 2,188,112, 2, 49, 18, + 49, 23,236,101,128,248,255,242,111, 2, 49, 30, 49, 38,225,227, + 232,229,115,128, 34, 80,120, 2, 49, 44, 49, 64,229,241,245,225, + 108,129, 34, 72, 49, 54,239,242,233,237,225,231,101,128, 34, 82, + 233,237,225,244,229,236,249,229,241,245,225,108,128, 34, 69,114, + 4, 49, 89, 49,116, 49,120, 49,165,225,229, 97, 2, 49, 97, 49, + 107,229,235,239,242,229,225,110,128, 49,142,235,239,242,229,225, + 110,128, 49,141, 99,128, 35, 18,105, 2, 49,126, 49,140,231,232, + 244,232,225,236,230,242,233,238,103,128, 30,154,238,103,130, 0, + 229, 49,149, 49,157,225,227,245,244,101,128, 1,251,226,229,236, + 239,119,128, 30, 1,242,239,119, 8, 49,185, 49,192, 50, 65, 50, + 131, 50,181, 50,236, 51, 3, 51, 78,226,239,244,104,128, 33,148, + 100, 3, 49,200, 49,239, 50, 30,225,243,104, 4, 49,212, 49,219, + 49,226, 49,234,228,239,247,110,128, 33,227,236,229,230,116,128, + 33,224,242,233,231,232,116,128, 33,226,245,112,128, 33,225,226, + 108, 5, 49,252, 50, 3, 50, 10, 50, 17, 50, 25,226,239,244,104, + 128, 33,212,228,239,247,110,128, 33,211,236,229,230,116,128, 33, + 208,242,233,231,232,116,128, 33,210,245,112,128, 33,209,239,247, + 110,131, 33,147, 50, 42, 50, 49, 50, 57,236,229,230,116,128, 33, + 153,242,233,231,232,116,128, 33,152,247,232,233,244,101,128, 33, + 233,104, 2, 50, 71, 50,122,229,225,100, 4, 50, 83, 50, 93, 50, + 103, 50,114,228,239,247,238,237,239,100,128, 2,197,236,229,230, + 244,237,239,100,128, 2,194,242,233,231,232,244,237,239,100,128, + 2,195,245,240,237,239,100,128, 2,196,239,242,233,250,229,120, + 128,248,231,236,229,230,116,131, 33,144, 50,144, 50,161, 50,173, + 228,226,108,129, 33,208, 50,152,243,244,242,239,235,101,128, 33, + 205,239,246,229,242,242,233,231,232,116,128, 33,198,247,232,233, + 244,101,128, 33,230,242,233,231,232,116,132, 33,146, 50,197, 50, + 209, 50,217, 50,228,228,226,236,243,244,242,239,235,101,128, 33, + 207,232,229,225,246,121,128, 39,158,239,246,229,242,236,229,230, + 116,128, 33,196,247,232,233,244,101,128, 33,232,244,225, 98, 2, + 50,244, 50,251,236,229,230,116,128, 33,228,242,233,231,232,116, + 128, 33,229,245,112,132, 33,145, 51, 16, 51, 44, 51, 62, 51, 70, + 100, 2, 51, 22, 51, 34,110,129, 33,149, 51, 28,226,243,101,128, + 33,168,239,247,238,226,225,243,101,128, 33,168,236,229,230,116, + 129, 33,150, 51, 53,239,230,228,239,247,110,128, 33,197,242,233, + 231,232,116,128, 33,151,247,232,233,244,101,128, 33,231,246,229, + 242,244,229,120,128,248,230,115, 5, 51, 99, 51,175, 51,220, 52, + 47, 52, 57, 99, 2, 51,105, 51,157,233,105, 2, 51,112, 51,135, + 227,233,242,227,245,109,129, 0, 94, 51,123,237,239,238,239,243, + 240,225,227,101,128,255, 62,244,233,236,228,101,129, 0,126, 51, + 145,237,239,238,239,243,240,225,227,101,128,255, 94,242,233,240, + 116,129, 2, 81, 51,166,244,245,242,238,229,100,128, 2, 82,237, + 225,236,108, 2, 51,184, 51,195,232,233,242,225,231,225,238, 97, + 128, 48, 65,235,225,244,225,235,225,238, 97,129, 48,161, 51,208, + 232,225,236,230,247,233,228,244,104,128,255,103,244,229,242,233, + 115, 2, 51,230, 52, 43,107,131, 0, 42, 51,240, 52, 12, 52, 35, + 97, 2, 51,246, 52, 4,236,244,239,238,229,225,242,225,226,233, + 99,128, 6,109,242,225,226,233, 99,128, 6,109,109, 2, 52, 18, + 52, 24,225,244,104,128, 34, 23,239,238,239,243,240,225,227,101, + 128,255, 10,243,237,225,236,108,128,254, 97,109,128, 32, 66,245, + 240,229,242,233,239,114,128,246,233,249,237,240,244,239,244,233, + 227,225,236,236,249,229,241,245,225,108,128, 34, 67,116,132, 0, + 64, 52, 89, 52, 96, 52,108, 52,116,233,236,228,101,128, 0,227, + 237,239,238,239,243,240,225,227,101,128,255, 32,243,237,225,236, + 108,128,254,107,245,242,238,229,100,128, 2, 80,117, 6, 52,138, + 52,163, 52,170, 52,195, 52,215, 52,231, 98, 2, 52,144, 52,153, + 229,238,231,225,236,105,128, 9,148,239,240,239,237,239,230,111, + 128, 49, 32,228,229,246, 97,128, 9, 20,231,117, 2, 52,177, 52, + 186,234,225,242,225,244,105,128, 10,148,242,237,245,235,232,105, + 128, 10, 20,236,229,238,231,244,232,237,225,242,235,226,229,238, + 231,225,236,105,128, 9,215,237,225,244,242,225,231,245,242,237, + 245,235,232,105,128, 10, 76,246,239,247,229,236,243,233,231,110, + 3, 52,247, 53, 1, 53, 8,226,229,238,231,225,236,105,128, 9, + 204,228,229,246, 97,128, 9, 76,231,245,234,225,242,225,244,105, + 128, 10,204,246,225,231,242,225,232,225,228,229,246, 97,128, 9, + 61,121, 2, 53, 39, 53, 51,226,225,242,237,229,238,233,225,110, + 128, 5, 97,233,110,130, 5,226, 53, 60, 53, 75,225,236,244,239, + 238,229,232,229,226,242,229,119,128,251, 32,232,229,226,242,229, + 119,128, 5,226, 98,144, 0, 98, 53,120, 53,255, 54, 10, 54, 19, + 54, 44, 55, 85, 55,147, 55,220, 57,146, 57,158, 57,201, 57,209, + 57,219, 59, 89, 59,113, 59,122, 97, 7, 53,136, 53,146, 53,170, + 53,177, 53,202, 53,226, 53,237,226,229,238,231,225,236,105,128, + 9,172,227,235,243,236,225,243,104,129, 0, 92, 53,158,237,239, + 238,239,243,240,225,227,101,128,255, 60,228,229,246, 97,128, 9, + 44,231,117, 2, 53,184, 53,193,234,225,242,225,244,105,128, 10, + 172,242,237,245,235,232,105,128, 10, 44,104, 2, 53,208, 53,218, + 233,242,225,231,225,238, 97,128, 48,112,244,244,232,225,105,128, + 14, 63,235,225,244,225,235,225,238, 97,128, 48,208,114,129, 0, + 124, 53,243,237,239,238,239,243,240,225,227,101,128,255, 92,226, + 239,240,239,237,239,230,111,128, 49, 5,227,233,242,227,236,101, + 128, 36,209,228,239,116, 2, 54, 27, 54, 36,225,227,227,229,238, + 116,128, 30, 3,226,229,236,239,119,128, 30, 5,101, 6, 54, 58, + 54, 79, 54,102, 54,244, 54,255, 55, 11,225,237,229,228,243,233, + 248,244,229,229,238,244,232,238,239,244,229,115,128, 38,108, 99, + 2, 54, 85, 54, 92,225,245,243,101,128, 34, 53,249,242,233,236, + 236,233, 99,128, 4, 49,104, 5, 54,114, 54,123, 54,137, 54,167, + 54,226,225,242,225,226,233, 99,128, 6, 40,230,233,238,225,236, + 225,242,225,226,233, 99,128,254,144,105, 2, 54,143, 54,158,238, + 233,244,233,225,236,225,242,225,226,233, 99,128,254,145,242,225, + 231,225,238, 97,128, 48,121,237,101, 2, 54,174, 54,187,228,233, + 225,236,225,242,225,226,233, 99,128,254,146,229,237,105, 2, 54, + 195, 54,210,238,233,244,233,225,236,225,242,225,226,233, 99,128, + 252,159,243,239,236,225,244,229,228,225,242,225,226,233, 99,128, + 252, 8,238,239,239,238,230,233,238,225,236,225,242,225,226,233, + 99,128,252,109,235,225,244,225,235,225,238, 97,128, 48,217,238, + 225,242,237,229,238,233,225,110,128, 5, 98,116,132, 5,209, 55, + 23, 55, 43, 55, 63, 55, 72, 97,129, 3,178, 55, 29,243,249,237, + 226,239,236,231,242,229,229,107,128, 3,208,228,225,231,229,243, + 104,129,251, 49, 55, 54,232,229,226,242,229,119,128,251, 49,232, + 229,226,242,229,119,128, 5,209,242,225,230,229,232,229,226,242, + 229,119,128,251, 76,104, 2, 55, 91, 55,141, 97, 3, 55, 99, 55, + 109, 55,116,226,229,238,231,225,236,105,128, 9,173,228,229,246, + 97,128, 9, 45,231,117, 2, 55,123, 55,132,234,225,242,225,244, + 105,128, 10,173,242,237,245,235,232,105,128, 10, 45,239,239,107, + 128, 2, 83,105, 5, 55,159, 55,170, 55,181, 55,195, 55,209,232, + 233,242,225,231,225,238, 97,128, 48,115,235,225,244,225,235,225, + 238, 97,128, 48,211,236,225,226,233,225,236,227,236,233,227,107, + 128, 2,152,238,228,233,231,245,242,237,245,235,232,105,128, 10, + 2,242,245,243,241,245,225,242,101,128, 51, 49,108, 3, 55,228, + 57,129, 57,140, 97, 2, 55,234, 57,124,227,107, 6, 55,249, 56, + 2, 56, 39, 56,188, 56,243, 57, 39,227,233,242,227,236,101,128, + 37,207,100, 2, 56, 8, 56, 17,233,225,237,239,238,100,128, 37, + 198,239,247,238,240,239,233,238,244,233,238,231,244,242,233,225, + 238,231,236,101,128, 37,188,108, 2, 56, 45, 56,148,101, 2, 56, + 51, 56, 87,230,244,240,239,233,238,244,233,238,103, 2, 56, 66, + 56, 76,240,239,233,238,244,229,114,128, 37,196,244,242,233,225, + 238,231,236,101,128, 37,192,238,244,233,227,245,236,225,242,226, + 242,225,227,235,229,116, 2, 56,107, 56,127,236,229,230,116,129, + 48, 16, 56,116,246,229,242,244,233,227,225,108,128,254, 59,242, + 233,231,232,116,129, 48, 17, 56,137,246,229,242,244,233,227,225, + 108,128,254, 60,239,247,229,114, 2, 56,157, 56,172,236,229,230, + 244,244,242,233,225,238,231,236,101,128, 37,227,242,233,231,232, + 244,244,242,233,225,238,231,236,101,128, 37,226,114, 2, 56,194, + 56,205,229,227,244,225,238,231,236,101,128, 37,172,233,231,232, + 244,240,239,233,238,244,233,238,103, 2, 56,222, 56,232,240,239, + 233,238,244,229,114,128, 37,186,244,242,233,225,238,231,236,101, + 128, 37,182,115, 3, 56,251, 57, 25, 57, 33,109, 2, 57, 1, 57, + 13,225,236,236,243,241,245,225,242,101,128, 37,170,233,236,233, + 238,231,230,225,227,101,128, 38, 59,241,245,225,242,101,128, 37, + 160,244,225,114,128, 38, 5,245,240,112, 2, 57, 47, 57, 85,229, + 114, 2, 57, 54, 57, 69,236,229,230,244,244,242,233,225,238,231, + 236,101,128, 37,228,242,233,231,232,244,244,242,233,225,238,231, + 236,101,128, 37,229,239,233,238,244,233,238,103, 2, 57, 97, 57, + 113,243,237,225,236,236,244,242,233,225,238,231,236,101,128, 37, + 180,244,242,233,225,238,231,236,101,128, 37,178,238,107,128, 36, + 35,233,238,229,226,229,236,239,119,128, 30, 7,239,227,107,128, + 37,136,237,239,238,239,243,240,225,227,101,128,255, 66,111, 3, + 57,166, 57,179, 57,190,226,225,233,237,225,233,244,232,225,105, + 128, 14, 26,232,233,242,225,231,225,238, 97,128, 48,124,235,225, + 244,225,235,225,238, 97,128, 48,220,240,225,242,229,110,128, 36, + 157,241,243,241,245,225,242,101,128, 51,195,114, 4, 57,229, 58, + 223, 59, 40, 59, 79,225, 99, 2, 57,236, 58,130,101, 3, 57,244, + 57,249, 58, 61,229,120,128,248,244,236,229,230,116,133, 0,123, + 58, 10, 58, 15, 58, 37, 58, 45, 58, 50,226,116,128,248,243,109, + 2, 58, 21, 58, 26,233,100,128,248,242,239,238,239,243,240,225, + 227,101,128,255, 91,243,237,225,236,108,128,254, 91,244,112,128, + 248,241,246,229,242,244,233,227,225,108,128,254, 55,242,233,231, + 232,116,133, 0,125, 58, 79, 58, 84, 58,106, 58,114, 58,119,226, + 116,128,248,254,109, 2, 58, 90, 58, 95,233,100,128,248,253,239, + 238,239,243,240,225,227,101,128,255, 93,243,237,225,236,108,128, + 254, 92,244,112,128,248,252,246,229,242,244,233,227,225,108,128, + 254, 56,235,229,116, 2, 58,138, 58,180,236,229,230,116,132, 0, + 91, 58,153, 58,158, 58,163, 58,175,226,116,128,248,240,229,120, + 128,248,239,237,239,238,239,243,240,225,227,101,128,255, 59,244, + 112,128,248,238,242,233,231,232,116,132, 0, 93, 58,196, 58,201, + 58,206, 58,218,226,116,128,248,251,229,120,128,248,250,237,239, + 238,239,243,240,225,227,101,128,255, 61,244,112,128,248,249,229, + 246,101,131, 2,216, 58,235, 58,246, 58,252,226,229,236,239,247, + 227,237, 98,128, 3, 46,227,237, 98,128, 3, 6,233,238,246,229, + 242,244,229,100, 3, 59, 11, 59, 22, 59, 28,226,229,236,239,247, + 227,237, 98,128, 3, 47,227,237, 98,128, 3, 17,228,239,245,226, + 236,229,227,237, 98,128, 3, 97,233,228,231,101, 2, 59, 49, 59, + 60,226,229,236,239,247,227,237, 98,128, 3, 42,233,238,246,229, + 242,244,229,228,226,229,236,239,247,227,237, 98,128, 3, 58,239, + 235,229,238,226,225,114,128, 0,166,115, 2, 59, 95, 59,103,244, + 242,239,235,101,128, 1,128,245,240,229,242,233,239,114,128,246, + 234,244,239,240,226,225,114,128, 1,131,117, 3, 59,130, 59,141, + 59,152,232,233,242,225,231,225,238, 97,128, 48,118,235,225,244, + 225,235,225,238, 97,128, 48,214,236,108, 2, 59,159, 59,189,229, + 116,130, 32, 34, 59,168, 59,178,233,238,246,229,242,243,101,128, + 37,216,239,240,229,242,225,244,239,114,128, 34, 25,243,229,249, + 101,128, 37,206, 99,143, 0, 99, 59,230, 60,179, 60,190, 60,254, + 61, 29, 61,122, 63, 33, 64, 17, 64,117, 64,166, 67,158, 67,166, + 67,176, 67,188, 67,221, 97, 9, 59,250, 60, 5, 60, 15, 60, 22, + 60, 29, 60, 54, 60, 64, 60,116, 60,125,225,242,237,229,238,233, + 225,110,128, 5,110,226,229,238,231,225,236,105,128, 9,154,227, + 245,244,101,128, 1, 7,228,229,246, 97,128, 9, 26,231,117, 2, + 60, 36, 60, 45,234,225,242,225,244,105,128, 10,154,242,237,245, + 235,232,105,128, 10, 26,236,243,241,245,225,242,101,128, 51,136, + 238,228,242,225,226,233,238,228,117, 4, 60, 82, 60, 92, 60, 98, + 60,105,226,229,238,231,225,236,105,128, 9,129,227,237, 98,128, + 3, 16,228,229,246, 97,128, 9, 1,231,245,234,225,242,225,244, + 105,128, 10,129,240,243,236,239,227,107,128, 33,234,114, 3, 60, + 133, 60,139, 60,165,229,239,102,128, 33, 5,239,110,130, 2,199, + 60,148, 60,159,226,229,236,239,247,227,237, 98,128, 3, 44,227, + 237, 98,128, 3, 12,242,233,225,231,229,242,229,244,245,242,110, + 128, 33,181,226,239,240,239,237,239,230,111,128, 49, 24, 99, 4, + 60,200, 60,207, 60,226, 60,248,225,242,239,110,128, 1, 13,229, + 228,233,236,236, 97,129, 0,231, 60,218,225,227,245,244,101,128, + 30, 9,233,242, 99, 2, 60,234, 60,239,236,101,128, 36,210,245, + 237,230,236,229,120,128, 1, 9,245,242,108,128, 2, 85,100, 2, + 61, 4, 61, 20,239,116,129, 1, 11, 61, 11,225,227,227,229,238, + 116,128, 1, 11,243,241,245,225,242,101,128, 51,197,101, 2, 61, + 35, 61, 51,228,233,236,236, 97,129, 0,184, 61, 45,227,237, 98, + 128, 3, 39,238,116,132, 0,162, 61, 64, 61, 88, 61,100, 61,111, + 105, 2, 61, 70, 61, 78,231,242,225,228,101,128, 33, 3,238,230, + 229,242,233,239,114,128,246,223,237,239,238,239,243,240,225,227, + 101,128,255,224,239,236,228,243,244,249,236,101,128,247,162,243, + 245,240,229,242,233,239,114,128,246,224,104, 5, 61,134, 61,197, + 61,208, 62,136, 62,228, 97, 4, 61,144, 61,155, 61,165, 61,172, + 225,242,237,229,238,233,225,110,128, 5,121,226,229,238,231,225, + 236,105,128, 9,155,228,229,246, 97,128, 9, 27,231,117, 2, 61, + 179, 61,188,234,225,242,225,244,105,128, 10,155,242,237,245,235, + 232,105,128, 10, 27,226,239,240,239,237,239,230,111,128, 49, 20, + 101, 6, 61,222, 61,242, 62, 10, 62, 78, 62, 90, 62,111,225,226, + 235,232,225,243,233,225,238,227,249,242,233,236,236,233, 99,128, + 4,189, 99, 2, 61,248, 62, 0,235,237,225,242,107,128, 39, 19, + 249,242,233,236,236,233, 99,128, 4, 71,100, 2, 62, 16, 62, 60, + 229,243,227,229,238,228,229,114, 2, 62, 29, 62, 49,225,226,235, + 232,225,243,233,225,238,227,249,242,233,236,236,233, 99,128, 4, + 191,227,249,242,233,236,236,233, 99,128, 4,183,233,229,242,229, + 243,233,243,227,249,242,233,236,236,233, 99,128, 4,245,232,225, + 242,237,229,238,233,225,110,128, 5,115,235,232,225,235,225,243, + 243,233,225,238,227,249,242,233,236,236,233, 99,128, 4,204,246, + 229,242,244,233,227,225,236,243,244,242,239,235,229,227,249,242, + 233,236,236,233, 99,128, 4,185,105,129, 3,199, 62,142,229,245, + 227,104, 4, 62,155, 62,190, 62,205, 62,214, 97, 2, 62,161, 62, + 176,227,233,242,227,236,229,235,239,242,229,225,110,128, 50,119, + 240,225,242,229,238,235,239,242,229,225,110,128, 50, 23,227,233, + 242,227,236,229,235,239,242,229,225,110,128, 50,105,235,239,242, + 229,225,110,128, 49, 74,240,225,242,229,238,235,239,242,229,225, + 110,128, 50, 9,111, 2, 62,234, 63, 28,227,104, 3, 62,243, 63, + 9, 63, 19,225,110, 2, 62,250, 63, 2,231,244,232,225,105,128, + 14, 10,244,232,225,105,128, 14, 8,233,238,231,244,232,225,105, + 128, 14, 9,239,229,244,232,225,105,128, 14, 12,239,107,128, 1, + 136,105, 2, 63, 39, 63,141,229,245, 99, 5, 63, 53, 63, 88, 63, + 103, 63,112, 63,126, 97, 2, 63, 59, 63, 74,227,233,242,227,236, + 229,235,239,242,229,225,110,128, 50,118,240,225,242,229,238,235, + 239,242,229,225,110,128, 50, 22,227,233,242,227,236,229,235,239, + 242,229,225,110,128, 50,104,235,239,242,229,225,110,128, 49, 72, + 240,225,242,229,238,235,239,242,229,225,110,128, 50, 8,245,240, + 225,242,229,238,235,239,242,229,225,110,128, 50, 28,242, 99, 2, + 63,148, 63,243,236,101,132, 37,203, 63,161, 63,172, 63,177, 63, + 201,237,245,236,244,233,240,236,121,128, 34,151,239,116,128, 34, + 153,112, 2, 63,183, 63,189,236,245,115,128, 34,149,239,243,244, + 225,236,237,225,242,107,128, 48, 54,247,233,244,104, 2, 63,210, + 63,226,236,229,230,244,232,225,236,230,226,236,225,227,107,128, + 37,208,242,233,231,232,244,232,225,236,230,226,236,225,227,107, + 128, 37,209,245,237,230,236,229,120,130, 2,198, 64, 0, 64, 11, + 226,229,236,239,247,227,237, 98,128, 3, 45,227,237, 98,128, 3, + 2,108, 3, 64, 25, 64, 31, 64, 85,229,225,114,128, 35, 39,233, + 227,107, 4, 64, 43, 64, 54, 64, 63, 64, 73,225,236,246,229,239, + 236,225,114,128, 1,194,228,229,238,244,225,108,128, 1,192,236, + 225,244,229,242,225,108,128, 1,193,242,229,244,242,239,230,236, + 229,120,128, 1,195,245, 98,129, 38, 99, 64, 92,243,245,233,116, + 2, 64,101, 64,109,226,236,225,227,107,128, 38, 99,247,232,233, + 244,101,128, 38,103,109, 3, 64,125, 64,139, 64,150,227,245,226, + 229,228,243,241,245,225,242,101,128, 51,164,239,238,239,243,240, + 225,227,101,128,255, 67,243,241,245,225,242,229,228,243,241,245, + 225,242,101,128, 51,160,111, 8, 64,184, 64,195, 65, 26, 65,224, + 66,253, 67, 28, 67,135, 67,144,225,242,237,229,238,233,225,110, + 128, 5,129,236,239,110,131, 0, 58, 64,207, 64,232, 64,251,237, + 239,110, 2, 64,215, 64,223,229,244,225,242,121,128, 32,161,239, + 243,240,225,227,101,128,255, 26,115, 2, 64,238, 64,244,233,231, + 110,128, 32,161,237,225,236,108,128,254, 85,244,242,233,225,238, + 231,245,236,225,114, 2, 65, 10, 65, 20,232,225,236,230,237,239, + 100,128, 2,209,237,239,100,128, 2,208,109, 2, 65, 32, 65,217, + 237, 97,134, 0, 44, 65, 49, 65,113, 65,124, 65,136, 65,166, 65, + 189, 97, 3, 65, 57, 65, 83, 65, 91,226,239,246,101, 2, 65, 66, + 65, 72,227,237, 98,128, 3, 19,242,233,231,232,244,227,237, 98, + 128, 3, 21,227,227,229,238,116,128,246,195,114, 2, 65, 97, 65, + 104,225,226,233, 99,128, 6, 12,237,229,238,233,225,110,128, 5, + 93,233,238,230,229,242,233,239,114,128,246,225,237,239,238,239, + 243,240,225,227,101,128,255, 12,242,229,246,229,242,243,229,100, + 2, 65,149, 65,160,225,226,239,246,229,227,237, 98,128, 3, 20, + 237,239,100,128, 2,189,115, 2, 65,172, 65,179,237,225,236,108, + 128,254, 80,245,240,229,242,233,239,114,128,246,226,244,245,242, + 238,229,100, 2, 65,200, 65,211,225,226,239,246,229,227,237, 98, + 128, 3, 18,237,239,100,128, 2,187,240,225,243,115,128, 38, 60, + 110, 2, 65,230, 65,239,231,242,245,229,238,116,128, 34, 69,116, + 2, 65,245, 66, 3,239,245,242,233,238,244,229,231,242,225,108, + 128, 34, 46,242,239,108,142, 35, 3, 66, 37, 66, 43, 66, 58, 66, + 73, 66,117, 66,162, 66,176, 66,181, 66,186, 66,191, 66,197, 66, + 202, 66,243, 66,248,193,195, 75,128, 0, 6, 66, 2, 66, 49, 66, + 54,197, 76,128, 0, 7, 83,128, 0, 8, 67, 2, 66, 64, 66, 69, + 193, 78,128, 0, 24, 82,128, 0, 13, 68, 3, 66, 81, 66,107, 66, + 112, 67, 4, 66, 91, 66, 95, 66, 99, 66,103, 49,128, 0, 17, 50, + 128, 0, 18, 51,128, 0, 19, 52,128, 0, 20,197, 76,128, 0,127, + 204, 69,128, 0, 16, 69, 5, 66,129, 66,133, 66,138, 66,143, 66, + 148, 77,128, 0, 25,206, 81,128, 0, 5,207, 84,128, 0, 4,211, + 67,128, 0, 27, 84, 2, 66,154, 66,158, 66,128, 0, 23, 88,128, + 0, 3, 70, 2, 66,168, 66,172, 70,128, 0, 12, 83,128, 0, 28, + 199, 83,128, 0, 29,200, 84,128, 0, 9,204, 70,128, 0, 10,206, + 193, 75,128, 0, 21,210, 83,128, 0, 30, 83, 5, 66,214, 66,218, + 66,228, 66,233, 66,238, 73,128, 0, 15, 79,129, 0, 14, 66,224, + 84,128, 0, 2,212, 88,128, 0, 1,213, 66,128, 0, 26,217, 78, + 128, 0, 22,213, 83,128, 0, 31,214, 84,128, 0, 11,240,249,242, + 233,231,232,116,129, 0,169, 67, 9,115, 2, 67, 15, 67, 21,225, + 238,115,128,248,233,229,242,233,102,128,246,217,114, 2, 67, 34, + 67,118,238,229,242,226,242,225,227,235,229,116, 2, 67, 49, 67, + 83,236,229,230,116,130, 48, 12, 67, 60, 67, 72,232,225,236,230, + 247,233,228,244,104,128,255, 98,246,229,242,244,233,227,225,108, + 128,254, 65,242,233,231,232,116,130, 48, 13, 67, 95, 67,107,232, + 225,236,230,247,233,228,244,104,128,255, 99,246,229,242,244,233, + 227,225,108,128,254, 66,240,239,242,225,244,233,239,238,243,241, + 245,225,242,101,128, 51,127,243,241,245,225,242,101,128, 51,199, + 246,229,242,235,231,243,241,245,225,242,101,128, 51,198,240,225, + 242,229,110,128, 36,158,242,245,250,229,233,242,111,128, 32,162, + 243,244,242,229,244,227,232,229,100,128, 2,151,245,114, 2, 67, + 195, 67,213,236,121, 2, 67,202, 67,208,225,238,100,128, 34,207, + 239,114,128, 34,206,242,229,238,227,121,128, 0,164,249,114, 4, + 67,232, 67,240, 67,247, 67,255,194,242,229,246,101,128,246,209, + 198,236,229,120,128,246,210,226,242,229,246,101,128,246,212,230, + 236,229,120,128,246,213,100,146, 0,100, 68, 46, 69,184, 70,208, + 71, 12, 71,188, 72,142, 72,204, 73,133, 73,146, 73,155, 73,181, + 73,206, 73,215, 75, 26, 75, 34, 75, 45, 75, 65, 75, 93, 97, 11, + 68, 70, 68, 81, 68, 91, 68,163, 68,226, 68,237, 68,248, 69, 61, + 69,123, 69,129, 69,159,225,242,237,229,238,233,225,110,128, 5, + 100,226,229,238,231,225,236,105,128, 9,166,100, 5, 68,103, 68, + 112, 68,118, 68,132, 68,148,225,242,225,226,233, 99,128, 6, 54, + 229,246, 97,128, 9, 38,230,233,238,225,236,225,242,225,226,233, + 99,128,254,190,233,238,233,244,233,225,236,225,242,225,226,233, + 99,128,254,191,237,229,228,233,225,236,225,242,225,226,233, 99, + 128,254,192,103, 3, 68,171, 68,188, 68,202,229,243,104,129, 5, + 188, 68,179,232,229,226,242,229,119,128, 5,188,231,229,114,129, + 32, 32, 68,196,228,226,108,128, 32, 33,117, 2, 68,208, 68,217, + 234,225,242,225,244,105,128, 10,166,242,237,245,235,232,105,128, + 10, 38,232,233,242,225,231,225,238, 97,128, 48, 96,235,225,244, + 225,235,225,238, 97,128, 48,192,108, 3, 69, 0, 69, 9, 69, 47, + 225,242,225,226,233, 99,128, 6, 47,229,116,130, 5,211, 69, 18, + 69, 38,228,225,231,229,243,104,129,251, 51, 69, 29,232,229,226, + 242,229,119,128,251, 51,232,229,226,242,229,119,128, 5,211,230, + 233,238,225,236,225,242,225,226,233, 99,128,254,170,237,237, 97, + 3, 69, 71, 69, 80, 69, 92,225,242,225,226,233, 99,128, 6, 79, + 236,239,247,225,242,225,226,233, 99,128, 6, 79,244,225,238, 97, + 2, 69,101, 69,115,236,244,239,238,229,225,242,225,226,233, 99, + 128, 6, 76,242,225,226,233, 99,128, 6, 76,238,228, 97,128, 9, + 100,242,231, 97, 2, 69,137, 69,146,232,229,226,242,229,119,128, + 5,167,236,229,230,244,232,229,226,242,229,119,128, 5,167,243, + 233,225,240,238,229,245,237,225,244,225,227,249,242,233,236,236, + 233,227,227,237, 98,128, 4,133, 98, 3, 69,192, 70,189, 70,199, + 108, 9, 69,212, 69,220, 70, 77, 70, 85, 70,101, 70,112, 70,130, + 70,144, 70,155,199,242,225,246,101,128,246,211, 97, 2, 69,226, + 70, 27,238,231,236,229,226,242,225,227,235,229,116, 2, 69,242, + 70, 6,236,229,230,116,129, 48, 10, 69,251,246,229,242,244,233, + 227,225,108,128,254, 61,242,233,231,232,116,129, 48, 11, 70, 16, + 246,229,242,244,233,227,225,108,128,254, 62,114, 2, 70, 33, 70, + 54,227,232,233,238,246,229,242,244,229,228,226,229,236,239,247, + 227,237, 98,128, 3, 43,242,239,119, 2, 70, 62, 70, 69,236,229, + 230,116,128, 33,212,242,233,231,232,116,128, 33,210,228,225,238, + 228, 97,128, 9,101,231,242,225,246,101,129,246,214, 70, 95,227, + 237, 98,128, 3, 15,233,238,244,229,231,242,225,108,128, 34, 44, + 236,239,247,236,233,238,101,129, 32, 23, 70,124,227,237, 98,128, + 3, 51,239,246,229,242,236,233,238,229,227,237, 98,128, 3, 63, + 240,242,233,237,229,237,239,100,128, 2,186,246,229,242,244,233, + 227,225,108, 2, 70,168, 70,174,226,225,114,128, 32, 22,236,233, + 238,229,225,226,239,246,229,227,237, 98,128, 3, 14,239,240,239, + 237,239,230,111,128, 49, 9,243,241,245,225,242,101,128, 51,200, + 99, 4, 70,218, 70,225, 70,234, 71, 5,225,242,239,110,128, 1, + 15,229,228,233,236,236, 97,128, 30, 17,233,242, 99, 2, 70,242, + 70,247,236,101,128, 36,211,245,237,230,236,229,248,226,229,236, + 239,119,128, 30, 19,242,239,225,116,128, 1, 17,100, 4, 71, 22, + 71,103, 71,113, 71,164, 97, 4, 71, 32, 71, 42, 71, 49, 71, 74, + 226,229,238,231,225,236,105,128, 9,161,228,229,246, 97,128, 9, + 33,231,117, 2, 71, 56, 71, 65,234,225,242,225,244,105,128, 10, + 161,242,237,245,235,232,105,128, 10, 33,108, 2, 71, 80, 71, 89, + 225,242,225,226,233, 99,128, 6,136,230,233,238,225,236,225,242, + 225,226,233, 99,128,251,137,228,232,225,228,229,246, 97,128, 9, + 92,232, 97, 3, 71,122, 71,132, 71,139,226,229,238,231,225,236, + 105,128, 9,162,228,229,246, 97,128, 9, 34,231,117, 2, 71,146, + 71,155,234,225,242,225,244,105,128, 10,162,242,237,245,235,232, + 105,128, 10, 34,239,116, 2, 71,171, 71,180,225,227,227,229,238, + 116,128, 30, 11,226,229,236,239,119,128, 30, 13,101, 8, 71,206, + 72, 3, 72, 10, 72, 35, 72, 45, 72, 56, 72,101, 72,137, 99, 2, + 71,212, 71,249,233,237,225,236,243,229,240,225,242,225,244,239, + 114, 2, 71,230, 71,239,225,242,225,226,233, 99,128, 6,107,240, + 229,242,243,233,225,110,128, 6,107,249,242,233,236,236,233, 99, + 128, 4, 52,231,242,229,101,128, 0,176,232,105, 2, 72, 17, 72, + 26,232,229,226,242,229,119,128, 5,173,242,225,231,225,238, 97, + 128, 48,103,233,227,239,240,244,233, 99,128, 3,239,235,225,244, + 225,235,225,238, 97,128, 48,199,108, 2, 72, 62, 72, 85,229,244, + 101, 2, 72, 70, 72, 77,236,229,230,116,128, 35, 43,242,233,231, + 232,116,128, 35, 38,244, 97,129, 3,180, 72, 92,244,245,242,238, + 229,100,128, 1,141,238,239,237,233,238,225,244,239,242,237,233, + 238,245,243,239,238,229,238,245,237,229,242,225,244,239,242,226, + 229,238,231,225,236,105,128, 9,248,250,104,128, 2,164,104, 2, + 72,148, 72,198, 97, 3, 72,156, 72,166, 72,173,226,229,238,231, + 225,236,105,128, 9,167,228,229,246, 97,128, 9, 39,231,117, 2, + 72,180, 72,189,234,225,242,225,244,105,128, 10,167,242,237,245, + 235,232,105,128, 10, 39,239,239,107,128, 2, 87,105, 6, 72,218, + 73, 11, 73, 71, 73, 82, 73, 93, 73,103, 97, 2, 72,224, 72,246, + 236,249,244,233,235,225,244,239,238,239,115,129, 3,133, 72,240, + 227,237, 98,128, 3, 68,237,239,238,100,129, 38,102, 72,255,243, + 245,233,244,247,232,233,244,101,128, 38, 98,229,242,229,243,233, + 115,133, 0,168, 73, 30, 73, 38, 73, 49, 73, 55, 73, 63,225,227, + 245,244,101,128,246,215,226,229,236,239,247,227,237, 98,128, 3, + 36,227,237, 98,128, 3, 8,231,242,225,246,101,128,246,216,244, + 239,238,239,115,128, 3,133,232,233,242,225,231,225,238, 97,128, + 48, 98,235,225,244,225,235,225,238, 97,128, 48,194,244,244,239, + 237,225,242,107,128, 48, 3,246,105, 2, 73,110, 73,121,228,101, + 129, 0,247, 73,117,115,128, 34, 35,243,233,239,238,243,236,225, + 243,104,128, 34, 21,234,229,227,249,242,233,236,236,233, 99,128, + 4, 82,235,243,232,225,228,101,128, 37,147,108, 2, 73,161, 73, + 172,233,238,229,226,229,236,239,119,128, 30, 15,243,241,245,225, + 242,101,128, 51,151,109, 2, 73,187, 73,195,225,227,242,239,110, + 128, 1, 17,239,238,239,243,240,225,227,101,128,255, 68,238,226, + 236,239,227,107,128, 37,132,111, 10, 73,237, 73,249, 74, 3, 74, + 14, 74, 25, 74, 97, 74,102, 74,113, 74,228, 74,254,227,232,225, + 228,225,244,232,225,105,128, 14, 14,228,229,235,244,232,225,105, + 128, 14, 20,232,233,242,225,231,225,238, 97,128, 48,105,235,225, + 244,225,235,225,238, 97,128, 48,201,236,236,225,114,132, 0, 36, + 74, 40, 74, 51, 74, 63, 74, 74,233,238,230,229,242,233,239,114, + 128,246,227,237,239,238,239,243,240,225,227,101,128,255, 4,239, + 236,228,243,244,249,236,101,128,247, 36,115, 2, 74, 80, 74, 87, + 237,225,236,108,128,254,105,245,240,229,242,233,239,114,128,246, + 228,238,103,128, 32,171,242,245,243,241,245,225,242,101,128, 51, + 38,116, 6, 74,127, 74,144, 74,166, 74,177, 74,209, 74,216,225, + 227,227,229,238,116,129, 2,217, 74,138,227,237, 98,128, 3, 7, + 226,229,236,239,247, 99, 2, 74,155, 74,160,237, 98,128, 3, 35, + 239,237, 98,128, 3, 35,235,225,244,225,235,225,238, 97,128, 48, + 251,236,229,243,115, 2, 74,186, 74,190,105,128, 1, 49,106,129, + 246,190, 74,196,243,244,242,239,235,229,232,239,239,107,128, 2, + 132,237,225,244,104,128, 34,197,244,229,228,227,233,242,227,236, + 101,128, 37,204,245,226,236,229,249,239,228,240,225,244,225,104, + 129,251, 31, 74,245,232,229,226,242,229,119,128,251, 31,247,238, + 244,225,227,107, 2, 75, 9, 75, 20,226,229,236,239,247,227,237, + 98,128, 3, 30,237,239,100,128, 2,213,240,225,242,229,110,128, + 36,159,243,245,240,229,242,233,239,114,128,246,235,116, 2, 75, + 51, 75, 57,225,233,108,128, 2, 86,239,240,226,225,114,128, 1, + 140,117, 2, 75, 71, 75, 82,232,233,242,225,231,225,238, 97,128, + 48,101,235,225,244,225,235,225,238, 97,128, 48,197,122,132, 1, + 243, 75,105, 75,114, 75,133, 75,170,225,236,244,239,238,101,128, + 2,163, 99, 2, 75,120, 75,127,225,242,239,110,128, 1,198,245, + 242,108,128, 2,165,101, 2, 75,139, 75,159,225,226,235,232,225, + 243,233,225,238,227,249,242,233,236,236,233, 99,128, 4,225,227, + 249,242,233,236,236,233, 99,128, 4, 85,232,229,227,249,242,233, + 236,236,233, 99,128, 4, 95,101,151, 0,101, 75,233, 75,252, 76, + 30, 77, 4, 77, 66, 77, 99, 77,111, 77,134, 77,187, 79, 43, 79, + 101, 79,203, 80, 63, 80,198, 81, 17, 81, 48, 81,110, 81,163, 82, + 98, 82,231, 82,251, 83, 39, 83,130, 97, 2, 75,239, 75,246,227, + 245,244,101,128, 0,233,242,244,104,128, 38, 65, 98, 3, 76, 4, + 76, 13, 76, 23,229,238,231,225,236,105,128, 9,143,239,240,239, + 237,239,230,111,128, 49, 28,242,229,246,101,128, 1, 21, 99, 5, + 76, 42, 76,115, 76,129, 76,161, 76,250, 97, 2, 76, 48, 76,109, + 238,228,242, 97, 3, 76, 59, 76, 66, 76, 77,228,229,246, 97,128, + 9, 13,231,245,234,225,242,225,244,105,128, 10,141,246,239,247, + 229,236,243,233,231,110, 2, 76, 91, 76, 98,228,229,246, 97,128, + 9, 69,231,245,234,225,242,225,244,105,128, 10,197,242,239,110, + 128, 1, 27,229,228,233,236,236,225,226,242,229,246,101,128, 30, + 29,104, 2, 76,135, 76,146,225,242,237,229,238,233,225,110,128, + 5,101,249,233,247,238,225,242,237,229,238,233,225,110,128, 5, + 135,233,242, 99, 2, 76,169, 76,174,236,101,128, 36,212,245,237, + 230,236,229,120,134, 0,234, 76,195, 76,203, 76,211, 76,222, 76, + 230, 76,242,225,227,245,244,101,128, 30,191,226,229,236,239,119, + 128, 30, 25,228,239,244,226,229,236,239,119,128, 30,199,231,242, + 225,246,101,128, 30,193,232,239,239,235,225,226,239,246,101,128, + 30,195,244,233,236,228,101,128, 30,197,249,242,233,236,236,233, + 99,128, 4, 84,100, 4, 77, 14, 77, 24, 77, 30, 77, 40,226,236, + 231,242,225,246,101,128, 2, 5,229,246, 97,128, 9, 15,233,229, + 242,229,243,233,115,128, 0,235,239,116,130, 1, 23, 77, 49, 77, + 58,225,227,227,229,238,116,128, 1, 23,226,229,236,239,119,128, + 30,185,101, 2, 77, 72, 77, 83,231,245,242,237,245,235,232,105, + 128, 10, 15,237,225,244,242,225,231,245,242,237,245,235,232,105, + 128, 10, 71,230,227,249,242,233,236,236,233, 99,128, 4, 68,103, + 2, 77,117, 77,124,242,225,246,101,128, 0,232,245,234,225,242, + 225,244,105,128, 10,143,104, 4, 77,144, 77,155, 77,166, 77,176, + 225,242,237,229,238,233,225,110,128, 5,103,226,239,240,239,237, + 239,230,111,128, 49, 29,233,242,225,231,225,238, 97,128, 48, 72, + 239,239,235,225,226,239,246,101,128, 30,187,105, 4, 77,197, 77, + 208, 79, 10, 79, 25,226,239,240,239,237,239,230,111,128, 49, 31, + 231,232,116,142, 0, 56, 77,242, 77,251, 78, 5, 78, 35, 78, 42, + 78, 80, 78,105, 78,150, 78,184, 78,196, 78,207, 78,240, 78,248, + 79, 3,225,242,225,226,233, 99,128, 6,104,226,229,238,231,225, + 236,105,128, 9,238,227,233,242,227,236,101,129, 36,103, 78, 16, + 233,238,246,229,242,243,229,243,225,238,243,243,229,242,233,102, + 128, 39,145,228,229,246, 97,128, 9,110,229,229,110, 2, 78, 50, + 78, 59,227,233,242,227,236,101,128, 36,113,112, 2, 78, 65, 78, + 72,225,242,229,110,128, 36,133,229,242,233,239,100,128, 36,153, + 231,117, 2, 78, 87, 78, 96,234,225,242,225,244,105,128, 10,238, + 242,237,245,235,232,105,128, 10,110,104, 2, 78,111, 78,137, 97, + 2, 78,117, 78,128,227,235,225,242,225,226,233, 99,128, 6,104, + 238,231,250,232,239,117,128, 48, 40,238,239,244,229,226,229,225, + 237,229,100,128, 38,107,105, 2, 78,156, 78,174,228,229,239,231, + 242,225,240,232,233,227,240,225,242,229,110,128, 50, 39,238,230, + 229,242,233,239,114,128, 32,136,237,239,238,239,243,240,225,227, + 101,128,255, 24,239,236,228,243,244,249,236,101,128,247, 56,112, + 2, 78,213, 78,220,225,242,229,110,128, 36,123,229,114, 2, 78, + 227, 78,233,233,239,100,128, 36,143,243,233,225,110,128, 6,248, + 242,239,237,225,110,128, 33,119,243,245,240,229,242,233,239,114, + 128, 32,120,244,232,225,105,128, 14, 88,238,246,229,242,244,229, + 228,226,242,229,246,101,128, 2, 7,239,244,233,230,233,229,228, + 227,249,242,233,236,236,233, 99,128, 4,101,107, 2, 79, 49, 79, + 73,225,244,225,235,225,238, 97,129, 48,168, 79, 61,232,225,236, + 230,247,233,228,244,104,128,255,116,111, 2, 79, 79, 79, 94,238, + 235,225,242,231,245,242,237,245,235,232,105,128, 10,116,242,229, + 225,110,128, 49, 84,108, 3, 79,109, 79,120, 79,181,227,249,242, + 233,236,236,233, 99,128, 4, 59,101, 2, 79,126, 79,133,237,229, + 238,116,128, 34, 8,246,229,110, 3, 79,143, 79,152, 79,173,227, + 233,242,227,236,101,128, 36,106,112, 2, 79,158, 79,165,225,242, + 229,110,128, 36,126,229,242,233,239,100,128, 36,146,242,239,237, + 225,110,128, 33,122,236,233,240,243,233,115,129, 32, 38, 79,192, + 246,229,242,244,233,227,225,108,128, 34,238,109, 5, 79,215, 79, + 243, 79,254, 80, 18, 80, 29,225,227,242,239,110,130, 1, 19, 79, + 227, 79,235,225,227,245,244,101,128, 30, 23,231,242,225,246,101, + 128, 30, 21,227,249,242,233,236,236,233, 99,128, 4, 60,228,225, + 243,104,129, 32, 20, 80, 7,246,229,242,244,233,227,225,108,128, + 254, 49,239,238,239,243,240,225,227,101,128,255, 69,112, 2, 80, + 35, 80, 55,232,225,243,233,243,237,225,242,235,225,242,237,229, + 238,233,225,110,128, 5, 91,244,249,243,229,116,128, 34, 5,110, + 6, 80, 77, 80, 88, 80, 99, 80,143, 80,175, 80,190,226,239,240, + 239,237,239,230,111,128, 49, 35,227,249,242,233,236,236,233, 99, + 128, 4, 61,100, 2, 80,105, 80,124,225,243,104,129, 32, 19, 80, + 113,246,229,242,244,233,227,225,108,128,254, 50,229,243,227,229, + 238,228,229,242,227,249,242,233,236,236,233, 99,128, 4,163,103, + 130, 1, 75, 80,151, 80,162,226,239,240,239,237,239,230,111,128, + 49, 37,232,229,227,249,242,233,236,236,233, 99,128, 4,165,232, + 239,239,235,227,249,242,233,236,236,233, 99,128, 4,200,243,240, + 225,227,101,128, 32, 2,111, 3, 80,206, 80,214, 80,223,231,239, + 238,229,107,128, 1, 25,235,239,242,229,225,110,128, 49, 83,240, + 229,110,130, 2, 91, 80,233, 80,242,227,236,239,243,229,100,128, + 2,154,242,229,246,229,242,243,229,100,130, 2, 92, 81, 1, 81, + 10,227,236,239,243,229,100,128, 2, 94,232,239,239,107,128, 2, + 93,112, 2, 81, 23, 81, 30,225,242,229,110,128, 36,160,243,233, + 236,239,110,129, 3,181, 81, 40,244,239,238,239,115,128, 3,173, + 241,117, 2, 81, 55, 81, 99,225,108,130, 0, 61, 81, 64, 81, 76, + 237,239,238,239,243,240,225,227,101,128,255, 29,115, 2, 81, 82, + 81, 89,237,225,236,108,128,254,102,245,240,229,242,233,239,114, + 128, 32,124,233,246,225,236,229,238,227,101,128, 34, 97,114, 3, + 81,118, 81,129, 81,140,226,239,240,239,237,239,230,111,128, 49, + 38,227,249,242,233,236,236,233, 99,128, 4, 64,229,246,229,242, + 243,229,100,129, 2, 88, 81,152,227,249,242,233,236,236,233, 99, + 128, 4, 77,115, 6, 81,177, 81,188, 81,208, 82, 33, 82, 78, 82, + 88,227,249,242,233,236,236,233, 99,128, 4, 65,228,229,243,227, + 229,238,228,229,242,227,249,242,233,236,236,233, 99,128, 4,171, + 104,132, 2,131, 81,220, 81,227, 82, 2, 82, 17,227,245,242,108, + 128, 2,134,239,242,116, 2, 81,235, 81,242,228,229,246, 97,128, + 9, 14,246,239,247,229,236,243,233,231,238,228,229,246, 97,128, + 9, 70,242,229,246,229,242,243,229,228,236,239,239,112,128, 1, + 170,243,241,245,225,244,242,229,246,229,242,243,229,100,128, 2, + 133,237,225,236,108, 2, 82, 42, 82, 53,232,233,242,225,231,225, + 238, 97,128, 48, 71,235,225,244,225,235,225,238, 97,129, 48,167, + 82, 66,232,225,236,230,247,233,228,244,104,128,255,106,244,233, + 237,225,244,229,100,128, 33, 46,245,240,229,242,233,239,114,128, + 246,236,116, 5, 82,110, 82,136, 82,140, 82,157, 82,223, 97,130, + 3,183, 82,118, 82,128,242,237,229,238,233,225,110,128, 5,104, + 244,239,238,239,115,128, 3,174,104,128, 0,240,233,236,228,101, + 129, 30,189, 82,149,226,229,236,239,119,128, 30, 27,238,225,232, + 244, 97, 3, 82,169, 82,201, 82,210,230,239,245,235,104, 2, 82, + 179, 82,188,232,229,226,242,229,119,128, 5,145,236,229,230,244, + 232,229,226,242,229,119,128, 5,145,232,229,226,242,229,119,128, + 5,145,236,229,230,244,232,229,226,242,229,119,128, 5,145,245, + 242,238,229,100,128, 1,221,117, 2, 82,237, 82,246,235,239,242, + 229,225,110,128, 49, 97,242,111,128, 32,172,246,239,247,229,236, + 243,233,231,110, 3, 83, 11, 83, 21, 83, 28,226,229,238,231,225, + 236,105,128, 9,199,228,229,246, 97,128, 9, 71,231,245,234,225, + 242,225,244,105,128, 10,199,120, 2, 83, 45, 83,118,227,236,225, + 109,132, 0, 33, 83, 60, 83, 71, 83, 98, 83,110,225,242,237,229, + 238,233,225,110,128, 5, 92,100, 2, 83, 77, 83, 82,226,108,128, + 32, 60,239,247,110,129, 0,161, 83, 90,243,237,225,236,108,128, + 247,161,237,239,238,239,243,240,225,227,101,128,255, 1,243,237, + 225,236,108,128,247, 33,233,243,244,229,238,244,233,225,108,128, + 34, 3,250,104,131, 2,146, 83,141, 83,160, 83,171, 99, 2, 83, + 147, 83,154,225,242,239,110,128, 1,239,245,242,108,128, 2,147, + 242,229,246,229,242,243,229,100,128, 1,185,244,225,233,108,128, + 1,186,102,140, 0,102, 83,206, 84, 32, 84, 43, 84, 52, 84, 64, + 84,167, 84,183, 86,191, 86,204, 86,230, 88,107, 88,115, 97, 4, + 83,216, 83,223, 83,234, 83,245,228,229,246, 97,128, 9, 94,231, + 245,242,237,245,235,232,105,128, 10, 94,232,242,229,238,232,229, + 233,116,128, 33, 9,244,232, 97, 3, 83,255, 84, 8, 84, 20,225, + 242,225,226,233, 99,128, 6, 78,236,239,247,225,242,225,226,233, + 99,128, 6, 78,244,225,238,225,242,225,226,233, 99,128, 6, 75, + 226,239,240,239,237,239,230,111,128, 49, 8,227,233,242,227,236, + 101,128, 36,213,228,239,244,225,227,227,229,238,116,128, 30, 31, + 101, 3, 84, 72, 84,150, 84,160,104, 4, 84, 82, 84,105, 84,119, + 84,135,225,114, 2, 84, 89, 84, 96,225,226,233, 99,128, 6, 65, + 237,229,238,233,225,110,128, 5,134,230,233,238,225,236,225,242, + 225,226,233, 99,128,254,210,233,238,233,244,233,225,236,225,242, + 225,226,233, 99,128,254,211,237,229,228,233,225,236,225,242,225, + 226,233, 99,128,254,212,233,227,239,240,244,233, 99,128, 3,229, + 237,225,236,101,128, 38, 64,102,130,251, 0, 84,175, 84,179,105, + 128,251, 3,108,128,251, 4,105,136,251, 1, 84,203, 84,243, 84, + 254, 85, 20, 85,142, 85,159, 85,167, 85,180,230,244,229,229,110, + 2, 84,213, 84,222,227,233,242,227,236,101,128, 36,110,112, 2, + 84,228, 84,235,225,242,229,110,128, 36,130,229,242,233,239,100, + 128, 36,150,231,245,242,229,228,225,243,104,128, 32, 18,236,236, + 229,100, 2, 85, 7, 85, 13,226,239,120,128, 37,160,242,229,227, + 116,128, 37,172,238,225,108, 5, 85, 34, 85, 73, 85, 90, 85,107, + 85,123,235,225,102,130, 5,218, 85, 44, 85, 64,228,225,231,229, + 243,104,129,251, 58, 85, 55,232,229,226,242,229,119,128,251, 58, + 232,229,226,242,229,119,128, 5,218,237,229,109,129, 5,221, 85, + 81,232,229,226,242,229,119,128, 5,221,238,245,110,129, 5,223, + 85, 98,232,229,226,242,229,119,128, 5,223,240,101,129, 5,227, + 85,114,232,229,226,242,229,119,128, 5,227,244,243,225,228,105, + 129, 5,229, 85,133,232,229,226,242,229,119,128, 5,229,242,243, + 244,244,239,238,229,227,232,233,238,229,243,101,128, 2,201,243, + 232,229,249,101,128, 37,201,244,225,227,249,242,233,236,236,233, + 99,128, 4,115,246,101,142, 0, 53, 85,213, 85,222, 85,232, 86, + 6, 86, 13, 86, 23, 86, 48, 86, 75, 86,109, 86,121, 86,132, 86, + 165, 86,173, 86,184,225,242,225,226,233, 99,128, 6,101,226,229, + 238,231,225,236,105,128, 9,235,227,233,242,227,236,101,129, 36, + 100, 85,243,233,238,246,229,242,243,229,243,225,238,243,243,229, + 242,233,102,128, 39,142,228,229,246, 97,128, 9,107,229,233,231, + 232,244,232,115,128, 33, 93,231,117, 2, 86, 30, 86, 39,234,225, + 242,225,244,105,128, 10,235,242,237,245,235,232,105,128, 10,107, + 232, 97, 2, 86, 55, 86, 66,227,235,225,242,225,226,233, 99,128, + 6,101,238,231,250,232,239,117,128, 48, 37,105, 2, 86, 81, 86, + 99,228,229,239,231,242,225,240,232,233,227,240,225,242,229,110, + 128, 50, 36,238,230,229,242,233,239,114,128, 32,133,237,239,238, + 239,243,240,225,227,101,128,255, 21,239,236,228,243,244,249,236, + 101,128,247, 53,112, 2, 86,138, 86,145,225,242,229,110,128, 36, + 120,229,114, 2, 86,152, 86,158,233,239,100,128, 36,140,243,233, + 225,110,128, 6,245,242,239,237,225,110,128, 33,116,243,245,240, + 229,242,233,239,114,128, 32,117,244,232,225,105,128, 14, 85,108, + 129,251, 2, 86,197,239,242,233,110,128, 1,146,109, 2, 86,210, + 86,221,239,238,239,243,240,225,227,101,128,255, 70,243,241,245, + 225,242,101,128, 51,153,111, 4, 86,240, 87, 6, 87, 18, 87, 25, + 230, 97, 2, 86,247, 86,255,238,244,232,225,105,128, 14, 31,244, + 232,225,105,128, 14, 29,238,231,237,225,238,244,232,225,105,128, + 14, 79,242,225,236,108,128, 34, 0,245,114,142, 0, 52, 87, 58, + 87, 67, 87, 77, 87,107, 87,114, 87,139, 87,166, 87,200, 87,212, + 87,231, 87,242, 88, 19, 88, 27, 88, 38,225,242,225,226,233, 99, + 128, 6,100,226,229,238,231,225,236,105,128, 9,234,227,233,242, + 227,236,101,129, 36, 99, 87, 88,233,238,246,229,242,243,229,243, + 225,238,243,243,229,242,233,102,128, 39,141,228,229,246, 97,128, + 9,106,231,117, 2, 87,121, 87,130,234,225,242,225,244,105,128, + 10,234,242,237,245,235,232,105,128, 10,106,232, 97, 2, 87,146, + 87,157,227,235,225,242,225,226,233, 99,128, 6,100,238,231,250, + 232,239,117,128, 48, 36,105, 2, 87,172, 87,190,228,229,239,231, + 242,225,240,232,233,227,240,225,242,229,110,128, 50, 35,238,230, + 229,242,233,239,114,128, 32,132,237,239,238,239,243,240,225,227, + 101,128,255, 20,238,245,237,229,242,225,244,239,242,226,229,238, + 231,225,236,105,128, 9,247,239,236,228,243,244,249,236,101,128, + 247, 52,112, 2, 87,248, 87,255,225,242,229,110,128, 36,119,229, + 114, 2, 88, 6, 88, 12,233,239,100,128, 36,139,243,233,225,110, + 128, 6,244,242,239,237,225,110,128, 33,115,243,245,240,229,242, + 233,239,114,128, 32,116,116, 2, 88, 44, 88, 82,229,229,110, 2, + 88, 52, 88, 61,227,233,242,227,236,101,128, 36,109,112, 2, 88, + 67, 88, 74,225,242,229,110,128, 36,129,229,242,233,239,100,128, + 36,149,104, 2, 88, 88, 88, 93,225,105,128, 14, 84,244,239,238, + 229,227,232,233,238,229,243,101,128, 2,203,240,225,242,229,110, + 128, 36,161,242, 97, 2, 88,122, 88,130,227,244,233,239,110,128, + 32, 68,238, 99,128, 32,163,103,144, 0,103, 88,171, 89,117, 89, + 140, 89,201, 89,218, 90,139, 91,132, 91,217, 91,230, 92, 88, 92, + 113, 92,141, 92,163, 93,108, 93,130, 93,232, 97, 9, 88,191, 88, + 201, 88,208, 88,215, 89, 23, 89, 48, 89, 59, 89, 70, 89,104,226, + 229,238,231,225,236,105,128, 9,151,227,245,244,101,128, 1,245, + 228,229,246, 97,128, 9, 23,102, 4, 88,225, 88,234, 88,248, 89, + 8,225,242,225,226,233, 99,128, 6,175,230,233,238,225,236,225, + 242,225,226,233, 99,128,251,147,233,238,233,244,233,225,236,225, + 242,225,226,233, 99,128,251,148,237,229,228,233,225,236,225,242, + 225,226,233, 99,128,251,149,231,117, 2, 89, 30, 89, 39,234,225, + 242,225,244,105,128, 10,151,242,237,245,235,232,105,128, 10, 23, + 232,233,242,225,231,225,238, 97,128, 48, 76,235,225,244,225,235, + 225,238, 97,128, 48,172,237,237, 97,130, 3,179, 89, 80, 89, 93, + 236,225,244,233,238,243,237,225,236,108,128, 2, 99,243,245,240, + 229,242,233,239,114,128, 2,224,238,231,233,225,227,239,240,244, + 233, 99,128, 3,235, 98, 2, 89,123, 89,133,239,240,239,237,239, + 230,111,128, 49, 13,242,229,246,101,128, 1, 31, 99, 4, 89,150, + 89,157, 89,166, 89,188,225,242,239,110,128, 1,231,229,228,233, + 236,236, 97,128, 1, 35,233,242, 99, 2, 89,174, 89,179,236,101, + 128, 36,214,245,237,230,236,229,120,128, 1, 29,239,237,237,225, + 225,227,227,229,238,116,128, 1, 35,228,239,116,129, 1, 33, 89, + 209,225,227,227,229,238,116,128, 1, 33,101, 6, 89,232, 89,243, + 89,254, 90, 9, 90, 28, 90,130,227,249,242,233,236,236,233, 99, + 128, 4, 51,232,233,242,225,231,225,238, 97,128, 48, 82,235,225, + 244,225,235,225,238, 97,128, 48,178,239,237,229,244,242,233,227, + 225,236,236,249,229,241,245,225,108,128, 34, 81,114, 3, 90, 36, + 90, 85, 90, 95,229,243,104, 3, 90, 46, 90, 61, 90, 70,225,227, + 227,229,238,244,232,229,226,242,229,119,128, 5,156,232,229,226, + 242,229,119,128, 5,243,237,245,241,228,225,237,232,229,226,242, + 229,119,128, 5,157,237,225,238,228,226,236,115,128, 0,223,243, + 232,225,249,233,109, 2, 90,106, 90,121,225,227,227,229,238,244, + 232,229,226,242,229,119,128, 5,158,232,229,226,242,229,119,128, + 5,244,244,225,237,225,242,107,128, 48, 19,104, 5, 90,151, 91, + 28, 91, 91, 91,116, 91,122, 97, 4, 90,161, 90,171, 90,194, 90, + 219,226,229,238,231,225,236,105,128, 9,152,100, 2, 90,177, 90, + 188,225,242,237,229,238,233,225,110,128, 5,114,229,246, 97,128, + 9, 24,231,117, 2, 90,201, 90,210,234,225,242,225,244,105,128, + 10,152,242,237,245,235,232,105,128, 10, 24,233,110, 4, 90,230, + 90,239, 90,253, 91, 13,225,242,225,226,233, 99,128, 6, 58,230, + 233,238,225,236,225,242,225,226,233, 99,128,254,206,233,238,233, + 244,233,225,236,225,242,225,226,233, 99,128,254,207,237,229,228, + 233,225,236,225,242,225,226,233, 99,128,254,208,101, 3, 91, 36, + 91, 57, 91, 74,237,233,228,228,236,229,232,239,239,235,227,249, + 242,233,236,236,233, 99,128, 4,149,243,244,242,239,235,229,227, + 249,242,233,236,236,233, 99,128, 4,147,245,240,244,245,242,238, + 227,249,242,233,236,236,233, 99,128, 4,145,232, 97, 2, 91, 98, + 91,105,228,229,246, 97,128, 9, 90,231,245,242,237,245,235,232, + 105,128, 10, 90,239,239,107,128, 2, 96,250,243,241,245,225,242, + 101,128, 51,147,105, 3, 91,140, 91,151, 91,162,232,233,242,225, + 231,225,238, 97,128, 48, 78,235,225,244,225,235,225,238, 97,128, + 48,174,109, 2, 91,168, 91,179,225,242,237,229,238,233,225,110, + 128, 5, 99,229,108,130, 5,210, 91,188, 91,208,228,225,231,229, + 243,104,129,251, 50, 91,199,232,229,226,242,229,119,128,251, 50, + 232,229,226,242,229,119,128, 5,210,234,229,227,249,242,233,236, + 236,233, 99,128, 4, 83,236,239,244,244,225,108, 2, 91,241, 92, + 2,233,238,246,229,242,244,229,228,243,244,242,239,235,101,128, + 1,190,243,244,239,112,132, 2,148, 92, 17, 92, 28, 92, 34, 92, + 66,233,238,246,229,242,244,229,100,128, 2,150,237,239,100,128, + 2,192,242,229,246,229,242,243,229,100,130, 2,149, 92, 49, 92, + 55,237,239,100,128, 2,193,243,245,240,229,242,233,239,114,128, + 2,228,243,244,242,239,235,101,129, 2,161, 92, 77,242,229,246, + 229,242,243,229,100,128, 2,162,109, 2, 92, 94, 92,102,225,227, + 242,239,110,128, 30, 33,239,238,239,243,240,225,227,101,128,255, + 71,111, 2, 92,119, 92,130,232,233,242,225,231,225,238, 97,128, + 48, 84,235,225,244,225,235,225,238, 97,128, 48,180,240, 97, 2, + 92,148, 92,154,242,229,110,128, 36,162,243,241,245,225,242,101, + 128, 51,172,114, 2, 92,169, 93, 10, 97, 2, 92,175, 92,183,228, + 233,229,238,116,128, 34, 7,246,101,134, 0, 96, 92,200, 92,211, + 92,228, 92,235, 92,244, 93, 0,226,229,236,239,247,227,237, 98, + 128, 3, 22, 99, 2, 92,217, 92,222,237, 98,128, 3, 0,239,237, + 98,128, 3, 0,228,229,246, 97,128, 9, 83,236,239,247,237,239, + 100,128, 2,206,237,239,238,239,243,240,225,227,101,128,255, 64, + 244,239,238,229,227,237, 98,128, 3, 64,229,225,244,229,114,132, + 0, 62, 93, 26, 93, 45, 93, 57, 93,100,229,241,245,225,108,129, + 34,101, 93, 36,239,242,236,229,243,115,128, 34,219,237,239,238, + 239,243,240,225,227,101,128,255, 30,111, 2, 93, 63, 93, 89,114, + 2, 93, 69, 93, 82,229,241,245,233,246,225,236,229,238,116,128, + 34,115,236,229,243,115,128, 34,119,246,229,242,229,241,245,225, + 108,128, 34,103,243,237,225,236,108,128,254,101,115, 2, 93,114, + 93,122,227,242,233,240,116,128, 2, 97,244,242,239,235,101,128, + 1,229,117, 4, 93,140, 93,151, 93,208, 93,219,232,233,242,225, + 231,225,238, 97,128, 48, 80,233,108, 2, 93,158, 93,183,236,229, + 237,239,116, 2, 93,168, 93,175,236,229,230,116,128, 0,171,242, + 233,231,232,116,128, 0,187,243,233,238,231,108, 2, 93,193, 93, + 200,236,229,230,116,128, 32, 57,242,233,231,232,116,128, 32, 58, + 235,225,244,225,235,225,238, 97,128, 48,176,242,225,237,245,243, + 241,245,225,242,101,128, 51, 24,249,243,241,245,225,242,101,128, + 51,201,104,144, 0,104, 94, 22, 96,164, 96,199, 96,236, 97, 20, + 98,164, 98,184, 99,149, 99,161, 99,173,100,241,100,249,101, 4, + 101, 13,101, 93,101, 97, 97, 13, 94, 50, 94, 89, 94, 99, 94,129, + 94,154, 94,232, 94,244, 95, 13, 95, 28, 95, 57, 95, 70, 95,128, + 95,137, 97, 2, 94, 56, 94, 75,226,235,232,225,243,233,225,238, + 227,249,242,233,236,236,233, 99,128, 4,169,236,244,239,238,229, + 225,242,225,226,233, 99,128, 6,193,226,229,238,231,225,236,105, + 128, 9,185,228,101, 2, 94,106, 94,124,243,227,229,238,228,229, + 242,227,249,242,233,236,236,233, 99,128, 4,179,246, 97,128, 9, + 57,231,117, 2, 94,136, 94,145,234,225,242,225,244,105,128, 10, + 185,242,237,245,235,232,105,128, 10, 57,104, 4, 94,164, 94,173, + 94,187, 94,217,225,242,225,226,233, 99,128, 6, 45,230,233,238, + 225,236,225,242,225,226,233, 99,128,254,162,105, 2, 94,193, 94, + 208,238,233,244,233,225,236,225,242,225,226,233, 99,128,254,163, + 242,225,231,225,238, 97,128, 48,111,237,229,228,233,225,236,225, + 242,225,226,233, 99,128,254,164,233,244,245,243,241,245,225,242, + 101,128, 51, 42,235,225,244,225,235,225,238, 97,129, 48,207, 95, + 1,232,225,236,230,247,233,228,244,104,128,255,138,236,225,238, + 244,231,245,242,237,245,235,232,105,128, 10, 77,237,250, 97, 2, + 95, 36, 95, 45,225,242,225,226,233, 99,128, 6, 33,236,239,247, + 225,242,225,226,233, 99,128, 6, 33,238,231,245,236,230,233,236, + 236,229,114,128, 49,100,114, 2, 95, 76, 95, 92,228,243,233,231, + 238,227,249,242,233,236,236,233, 99,128, 4, 74,240,239,239,110, + 2, 95,101, 95,114,236,229,230,244,226,225,242,226,245,112,128, + 33,188,242,233,231,232,244,226,225,242,226,245,112,128, 33,192, + 243,241,245,225,242,101,128, 51,202,244,225,102, 3, 95,147, 95, + 239, 96, 74,240,225,244,225,104,134, 5,178, 95,167, 95,172, 95, + 186, 95,195, 95,210, 95,226,177, 54,128, 5,178, 50, 2, 95,178, + 95,182, 51,128, 5,178,102,128, 5,178,232,229,226,242,229,119, + 128, 5,178,238,225,242,242,239,247,232,229,226,242,229,119,128, + 5,178,241,245,225,242,244,229,242,232,229,226,242,229,119,128, + 5,178,247,233,228,229,232,229,226,242,229,119,128, 5,178,241, + 225,237,225,244,115,135, 5,179, 96, 6, 96, 11, 96, 16, 96, 21, + 96, 30, 96, 45, 96, 61,177, 98,128, 5,179,178, 56,128, 5,179, + 179, 52,128, 5,179,232,229,226,242,229,119,128, 5,179,238,225, + 242,242,239,247,232,229,226,242,229,119,128, 5,179,241,245,225, + 242,244,229,242,232,229,226,242,229,119,128, 5,179,247,233,228, + 229,232,229,226,242,229,119,128, 5,179,243,229,231,239,108,135, + 5,177, 96, 96, 96,101, 96,106, 96,111, 96,120, 96,135, 96,151, + 177, 55,128, 5,177,178, 52,128, 5,177,179, 48,128, 5,177,232, + 229,226,242,229,119,128, 5,177,238,225,242,242,239,247,232,229, + 226,242,229,119,128, 5,177,241,245,225,242,244,229,242,232,229, + 226,242,229,119,128, 5,177,247,233,228,229,232,229,226,242,229, + 119,128, 5,177, 98, 3, 96,172, 96,177, 96,187,225,114,128, 1, + 39,239,240,239,237,239,230,111,128, 49, 15,242,229,246,229,226, + 229,236,239,119,128, 30, 43, 99, 2, 96,205, 96,214,229,228,233, + 236,236, 97,128, 30, 41,233,242, 99, 2, 96,222, 96,227,236,101, + 128, 36,215,245,237,230,236,229,120,128, 1, 37,100, 2, 96,242, + 96,252,233,229,242,229,243,233,115,128, 30, 39,239,116, 2, 97, + 3, 97, 12,225,227,227,229,238,116,128, 30, 35,226,229,236,239, + 119,128, 30, 37,101,136, 5,212, 97, 40, 97, 73, 97, 93, 98, 66, + 98, 82, 98,127, 98,136, 98,149,225,242,116,129, 38,101, 97, 48, + 243,245,233,116, 2, 97, 57, 97, 65,226,236,225,227,107,128, 38, + 101,247,232,233,244,101,128, 38, 97,228,225,231,229,243,104,129, + 251, 52, 97, 84,232,229,226,242,229,119,128,251, 52,104, 6, 97, + 107, 97,135, 97,143, 97,193, 97,239, 98, 32, 97, 2, 97,113, 97, + 127,236,244,239,238,229,225,242,225,226,233, 99,128, 6,193,242, + 225,226,233, 99,128, 6, 71,229,226,242,229,119,128, 5,212,230, + 233,238,225,236, 97, 2, 97,154, 97,185,236,116, 2, 97,161, 97, + 173,239,238,229,225,242,225,226,233, 99,128,251,167,244,247,239, + 225,242,225,226,233, 99,128,254,234,242,225,226,233, 99,128,254, + 234,232,225,237,250,225,225,226,239,246,101, 2, 97,208, 97,222, + 230,233,238,225,236,225,242,225,226,233, 99,128,251,165,233,243, + 239,236,225,244,229,228,225,242,225,226,233, 99,128,251,164,105, + 2, 97,245, 98, 23,238,233,244,233,225,236, 97, 2, 98, 1, 98, + 15,236,244,239,238,229,225,242,225,226,233, 99,128,251,168,242, + 225,226,233, 99,128,254,235,242,225,231,225,238, 97,128, 48,120, + 237,229,228,233,225,236, 97, 2, 98, 44, 98, 58,236,244,239,238, + 229,225,242,225,226,233, 99,128,251,169,242,225,226,233, 99,128, + 254,236,233,243,229,233,229,242,225,243,241,245,225,242,101,128, + 51,123,107, 2, 98, 88, 98,112,225,244,225,235,225,238, 97,129, + 48,216, 98,100,232,225,236,230,247,233,228,244,104,128,255,141, + 245,244,225,225,242,245,243,241,245,225,242,101,128, 51, 54,238, + 231,232,239,239,107,128, 2,103,242,245,244,245,243,241,245,225, + 242,101,128, 51, 57,116,129, 5,215, 98,155,232,229,226,242,229, + 119,128, 5,215,232,239,239,107,129, 2,102, 98,173,243,245,240, + 229,242,233,239,114,128, 2,177,105, 4, 98,194, 99, 23, 99, 34, + 99, 59,229,245,104, 4, 98,206, 98,241, 99, 0, 99, 9, 97, 2, + 98,212, 98,227,227,233,242,227,236,229,235,239,242,229,225,110, + 128, 50,123,240,225,242,229,238,235,239,242,229,225,110,128, 50, + 27,227,233,242,227,236,229,235,239,242,229,225,110,128, 50,109, + 235,239,242,229,225,110,128, 49, 78,240,225,242,229,238,235,239, + 242,229,225,110,128, 50, 13,232,233,242,225,231,225,238, 97,128, + 48,114,235,225,244,225,235,225,238, 97,129, 48,210, 99, 47,232, + 225,236,230,247,233,228,244,104,128,255,139,242,233,113,134, 5, + 180, 99, 77, 99, 82, 99, 96, 99,105, 99,120, 99,136,177, 52,128, + 5,180, 50, 2, 99, 88, 99, 92, 49,128, 5,180,100,128, 5,180, + 232,229,226,242,229,119,128, 5,180,238,225,242,242,239,247,232, + 229,226,242,229,119,128, 5,180,241,245,225,242,244,229,242,232, + 229,226,242,229,119,128, 5,180,247,233,228,229,232,229,226,242, + 229,119,128, 5,180,236,233,238,229,226,229,236,239,119,128, 30, + 150,237,239,238,239,243,240,225,227,101,128,255, 72,111, 9, 99, + 193, 99,204, 99,228, 99,253,100, 85,100, 98,100,184,100,224,100, + 235,225,242,237,229,238,233,225,110,128, 5,112,232,105, 2, 99, + 211, 99,219,240,244,232,225,105,128, 14, 43,242,225,231,225,238, + 97,128, 48,123,235,225,244,225,235,225,238, 97,129, 48,219, 99, + 241,232,225,236,230,247,233,228,244,104,128,255,142,236,225,109, + 135, 5,185,100, 17,100, 22,100, 27,100, 32,100, 41,100, 56,100, + 72,177, 57,128, 5,185,178, 54,128, 5,185,179, 50,128, 5,185, + 232,229,226,242,229,119,128, 5,185,238,225,242,242,239,247,232, + 229,226,242,229,119,128, 5,185,241,245,225,242,244,229,242,232, + 229,226,242,229,119,128, 5,185,247,233,228,229,232,229,226,242, + 229,119,128, 5,185,238,239,235,232,245,235,244,232,225,105,128, + 14, 46,111, 2,100,104,100,174,107, 4,100,114,100,126,100,132, + 100,154,225,226,239,246,229,227,239,237, 98,128, 3, 9,227,237, + 98,128, 3, 9,240,225,236,225,244,225,236,233,250,229,228,226, + 229,236,239,247,227,237, 98,128, 3, 33,242,229,244,242,239,230, + 236,229,248,226,229,236,239,247,227,237, 98,128, 3, 34,238,243, + 241,245,225,242,101,128, 51, 66,114, 2,100,190,100,217,105, 2, + 100,196,100,205,227,239,240,244,233, 99,128, 3,233,250,239,238, + 244,225,236,226,225,114,128, 32, 21,238,227,237, 98,128, 3, 27, + 244,243,240,242,233,238,231,115,128, 38,104,245,243,101,128, 35, + 2,240,225,242,229,110,128, 36,163,243,245,240,229,242,233,239, + 114,128, 2,176,244,245,242,238,229,100,128, 2,101,117, 4,101, + 23,101, 34,101, 47,101, 72,232,233,242,225,231,225,238, 97,128, + 48,117,233,233,244,239,243,241,245,225,242,101,128, 51, 51,235, + 225,244,225,235,225,238, 97,129, 48,213,101, 60,232,225,236,230, + 247,233,228,244,104,128,255,140,238,231,225,242,245,237,236,225, + 245,116,129, 2,221,101, 87,227,237, 98,128, 3, 11,118,128, 1, + 149,249,240,232,229,110,132, 0, 45,101,113,101,124,101,136,101, + 159,233,238,230,229,242,233,239,114,128,246,229,237,239,238,239, + 243,240,225,227,101,128,255, 13,115, 2,101,142,101,149,237,225, + 236,108,128,254, 99,245,240,229,242,233,239,114,128,246,230,244, + 247,111,128, 32, 16,105,149, 0,105,101,211,101,234,102, 12,102, + 59,105,197,106, 61,106, 98,106,125,107, 31,107, 35,107, 73,107, + 95,107,179,108, 88,108,163,108,171,108,184,109, 15,109, 72,109, + 100,109,144,225, 99, 2,101,218,101,224,245,244,101,128, 0,237, + 249,242,233,236,236,233, 99,128, 4, 79, 98, 3,101,242,101,251, + 102, 5,229,238,231,225,236,105,128, 9,135,239,240,239,237,239, + 230,111,128, 49, 39,242,229,246,101,128, 1, 45, 99, 3,102, 20, + 102, 27,102, 49,225,242,239,110,128, 1,208,233,242, 99, 2,102, + 35,102, 40,236,101,128, 36,216,245,237,230,236,229,120,128, 0, + 238,249,242,233,236,236,233, 99,128, 4, 86,100, 4,102, 69,102, + 79,105,154,105,187,226,236,231,242,225,246,101,128, 2, 9,101, + 2,102, 85,105,149,239,231,242,225,240,104, 7,102,106,102,120, + 102,133,105, 62,105, 93,105,106,105,118,229,225,242,244,232,227, + 233,242,227,236,101,128, 50,143,230,233,242,229,227,233,242,227, + 236,101,128, 50,139,233, 99, 14,102,164,102,180,103, 23,103, 77, + 103,143,103,172,103,188,103,245,104, 38,104, 50,104, 77,104,144, + 105, 26,105, 55,225,236,236,233,225,238,227,229,240,225,242,229, + 110,128, 50, 63, 99, 4,102,190,102,201,102,215,102,222,225,236, + 236,240,225,242,229,110,128, 50, 58,229,238,244,242,229,227,233, + 242,227,236,101,128, 50,165,236,239,243,101,128, 48, 6,111, 3, + 102,230,102,245,103, 9,237,237, 97,129, 48, 1,102,238,236,229, + 230,116,128,255,100,238,231,242,225,244,245,236,225,244,233,239, + 238,240,225,242,229,110,128, 50, 55,242,242,229,227,244,227,233, + 242,227,236,101,128, 50,163,101, 3,103, 31,103, 43,103, 60,225, + 242,244,232,240,225,242,229,110,128, 50, 47,238,244,229,242,240, + 242,233,243,229,240,225,242,229,110,128, 50, 61,248,227,229,236, + 236,229,238,244,227,233,242,227,236,101,128, 50,157,102, 2,103, + 83,103, 98,229,243,244,233,246,225,236,240,225,242,229,110,128, + 50, 64,105, 2,103,104,103,133,238,225,238,227,233,225,108, 2, + 103,116,103,125,227,233,242,227,236,101,128, 50,150,240,225,242, + 229,110,128, 50, 54,242,229,240,225,242,229,110,128, 50, 43,104, + 2,103,149,103,160,225,246,229,240,225,242,229,110,128, 50, 50, + 233,231,232,227,233,242,227,236,101,128, 50,164,233,244,229,242, + 225,244,233,239,238,237,225,242,107,128, 48, 5,108, 3,103,196, + 103,222,103,234,225,226,239,114, 2,103,205,103,214,227,233,242, + 227,236,101,128, 50,152,240,225,242,229,110,128, 50, 56,229,230, + 244,227,233,242,227,236,101,128, 50,167,239,247,227,233,242,227, + 236,101,128, 50,166,109, 2,103,251,104, 27,101, 2,104, 1,104, + 16,228,233,227,233,238,229,227,233,242,227,236,101,128, 50,169, + 244,225,236,240,225,242,229,110,128, 50, 46,239,239,238,240,225, + 242,229,110,128, 50, 42,238,225,237,229,240,225,242,229,110,128, + 50, 52,112, 2,104, 56,104, 64,229,242,233,239,100,128, 48, 2, + 242,233,238,244,227,233,242,227,236,101,128, 50,158,114, 2,104, + 83,104,131,101, 3,104, 91,104,102,104,117,225,227,232,240,225, + 242,229,110,128, 50, 67,240,242,229,243,229,238,244,240,225,242, + 229,110,128, 50, 57,243,239,245,242,227,229,240,225,242,229,110, + 128, 50, 62,233,231,232,244,227,233,242,227,236,101,128, 50,168, + 115, 5,104,156,104,185,104,199,104,224,104,252,101, 2,104,162, + 104,175,227,242,229,244,227,233,242,227,236,101,128, 50,153,236, + 230,240,225,242,229,110,128, 50, 66,239,227,233,229,244,249,240, + 225,242,229,110,128, 50, 51,112, 2,104,205,104,211,225,227,101, + 128, 48, 0,229,227,233,225,236,240,225,242,229,110,128, 50, 53, + 116, 2,104,230,104,241,239,227,235,240,225,242,229,110,128, 50, + 49,245,228,249,240,225,242,229,110,128, 50, 59,117, 2,105, 2, + 105, 11,238,240,225,242,229,110,128, 50, 48,240,229,242,246,233, + 243,229,240,225,242,229,110,128, 50, 60,119, 2,105, 32,105, 44, + 225,244,229,242,240,225,242,229,110,128, 50, 44,239,239,228,240, + 225,242,229,110,128, 50, 45,250,229,242,111,128, 48, 7,109, 2, + 105, 68,105, 81,229,244,225,236,227,233,242,227,236,101,128, 50, + 142,239,239,238,227,233,242,227,236,101,128, 50,138,238,225,237, + 229,227,233,242,227,236,101,128, 50,148,243,245,238,227,233,242, + 227,236,101,128, 50,144,119, 2,105,124,105,137,225,244,229,242, + 227,233,242,227,236,101,128, 50,140,239,239,228,227,233,242,227, + 236,101,128, 50,141,246, 97,128, 9, 7,233,229,242,229,243,233, + 115,130, 0,239,105,168,105,176,225,227,245,244,101,128, 30, 47, + 227,249,242,233,236,236,233, 99,128, 4,229,239,244,226,229,236, + 239,119,128, 30,203,101, 3,105,205,105,221,105,232,226,242,229, + 246,229,227,249,242,233,236,236,233, 99,128, 4,215,227,249,242, + 233,236,236,233, 99,128, 4, 53,245,238,103, 4,105,244,106, 23, + 106, 38,106, 47, 97, 2,105,250,106, 9,227,233,242,227,236,229, + 235,239,242,229,225,110,128, 50,117,240,225,242,229,238,235,239, + 242,229,225,110,128, 50, 21,227,233,242,227,236,229,235,239,242, + 229,225,110,128, 50,103,235,239,242,229,225,110,128, 49, 71,240, + 225,242,229,238,235,239,242,229,225,110,128, 50, 7,103, 2,106, + 67,106, 74,242,225,246,101,128, 0,236,117, 2,106, 80,106, 89, + 234,225,242,225,244,105,128, 10,135,242,237,245,235,232,105,128, + 10, 7,104, 2,106,104,106,114,233,242,225,231,225,238, 97,128, + 48, 68,239,239,235,225,226,239,246,101,128, 30,201,105, 8,106, + 143,106,153,106,164,106,171,106,196,106,212,106,227,106,243,226, + 229,238,231,225,236,105,128, 9,136,227,249,242,233,236,236,233, + 99,128, 4, 56,228,229,246, 97,128, 9, 8,231,117, 2,106,178, + 106,187,234,225,242,225,244,105,128, 10,136,242,237,245,235,232, + 105,128, 10, 8,237,225,244,242,225,231,245,242,237,245,235,232, + 105,128, 10, 64,238,246,229,242,244,229,228,226,242,229,246,101, + 128, 2, 11,243,232,239,242,244,227,249,242,233,236,236,233, 99, + 128, 4, 57,246,239,247,229,236,243,233,231,110, 3,107, 3,107, + 13,107, 20,226,229,238,231,225,236,105,128, 9,192,228,229,246, + 97,128, 9, 64,231,245,234,225,242,225,244,105,128, 10,192,106, + 128, 1, 51,107, 2,107, 41,107, 65,225,244,225,235,225,238, 97, + 129, 48,164,107, 53,232,225,236,230,247,233,228,244,104,128,255, + 114,239,242,229,225,110,128, 49, 99,108, 2,107, 79,107, 84,228, + 101,128, 2,220,245,249,232,229,226,242,229,119,128, 5,172,109, + 2,107,101,107,168, 97, 3,107,109,107,129,107,154,227,242,239, + 110,129, 1, 43,107,118,227,249,242,233,236,236,233, 99,128, 4, + 227,231,229,239,242,225,240,240,242,239,248,233,237,225,244,229, + 236,249,229,241,245,225,108,128, 34, 83,244,242,225,231,245,242, + 237,245,235,232,105,128, 10, 63,239,238,239,243,240,225,227,101, + 128,255, 73,110, 5,107,191,107,201,107,210,107,222,108, 50,227, + 242,229,237,229,238,116,128, 34, 6,230,233,238,233,244,121,128, + 34, 30,233,225,242,237,229,238,233,225,110,128, 5,107,116, 2, + 107,228,108, 40,101, 2,107,234,108, 29,231,242,225,108,131, 34, + 43,107,247,108, 9,108, 14, 98, 2,107,253,108, 5,239,244,244, + 239,109,128, 35, 33,116,128, 35, 33,229,120,128,248,245,116, 2, + 108, 20,108, 25,239,112,128, 35, 32,112,128, 35, 32,242,243,229, + 227,244,233,239,110,128, 34, 41,233,243,241,245,225,242,101,128, + 51, 5,118, 3,108, 58,108, 67,108, 76,226,245,236,236,229,116, + 128, 37,216,227,233,242,227,236,101,128, 37,217,243,237,233,236, + 229,230,225,227,101,128, 38, 59,111, 3,108, 96,108,107,108,115, + 227,249,242,233,236,236,233, 99,128, 4, 81,231,239,238,229,107, + 128, 1, 47,244, 97,131, 3,185,108,126,108,147,108,155,228,233, + 229,242,229,243,233,115,129, 3,202,108,139,244,239,238,239,115, + 128, 3,144,236,225,244,233,110,128, 2,105,244,239,238,239,115, + 128, 3,175,240,225,242,229,110,128, 36,164,242,233,231,245,242, + 237,245,235,232,105,128, 10,114,115, 4,108,194,108,239,108,253, + 109, 5,237,225,236,108, 2,108,203,108,214,232,233,242,225,231, + 225,238, 97,128, 48, 67,235,225,244,225,235,225,238, 97,129, 48, + 163,108,227,232,225,236,230,247,233,228,244,104,128,255,104,243, + 232,225,242,226,229,238,231,225,236,105,128, 9,250,244,242,239, + 235,101,128, 2,104,245,240,229,242,233,239,114,128,246,237,116, + 2,109, 21,109, 55,229,242,225,244,233,239,110, 2,109, 33,109, + 44,232,233,242,225,231,225,238, 97,128, 48,157,235,225,244,225, + 235,225,238, 97,128, 48,253,233,236,228,101,129, 1, 41,109, 64, + 226,229,236,239,119,128, 30, 45,117, 2,109, 78,109, 89,226,239, + 240,239,237,239,230,111,128, 49, 41,227,249,242,233,236,236,233, + 99,128, 4, 78,246,239,247,229,236,243,233,231,110, 3,109,116, + 109,126,109,133,226,229,238,231,225,236,105,128, 9,191,228,229, + 246, 97,128, 9, 63,231,245,234,225,242,225,244,105,128, 10,191, + 250,232,233,244,243, 97, 2,109,155,109,166,227,249,242,233,236, + 236,233, 99,128, 4,117,228,226,236,231,242,225,246,229,227,249, + 242,233,236,236,233, 99,128, 4,119,106,138, 0,106,109,209,110, + 16,110, 27,110, 77,110, 93,110,206,111, 19,111, 24,111, 36,111, + 44, 97, 4,109,219,109,230,109,240,109,247,225,242,237,229,238, + 233,225,110,128, 5,113,226,229,238,231,225,236,105,128, 9,156, + 228,229,246, 97,128, 9, 28,231,117, 2,109,254,110, 7,234,225, + 242,225,244,105,128, 10,156,242,237,245,235,232,105,128, 10, 28, + 226,239,240,239,237,239,230,111,128, 49, 16, 99, 3,110, 35,110, + 42,110, 64,225,242,239,110,128, 1,240,233,242, 99, 2,110, 50, + 110, 55,236,101,128, 36,217,245,237,230,236,229,120,128, 1, 53, + 242,239,243,243,229,228,244,225,233,108,128, 2,157,228,239,244, + 236,229,243,243,243,244,242,239,235,101,128, 2, 95,101, 3,110, + 101,110,112,110,177,227,249,242,233,236,236,233, 99,128, 4, 88, + 229,109, 4,110,123,110,132,110,146,110,162,225,242,225,226,233, + 99,128, 6, 44,230,233,238,225,236,225,242,225,226,233, 99,128, + 254,158,233,238,233,244,233,225,236,225,242,225,226,233, 99,128, + 254,159,237,229,228,233,225,236,225,242,225,226,233, 99,128,254, + 160,104, 2,110,183,110,192,225,242,225,226,233, 99,128, 6,152, + 230,233,238,225,236,225,242,225,226,233, 99,128,251,139,104, 2, + 110,212,111, 6, 97, 3,110,220,110,230,110,237,226,229,238,231, + 225,236,105,128, 9,157,228,229,246, 97,128, 9, 29,231,117, 2, + 110,244,110,253,234,225,242,225,244,105,128, 10,157,242,237,245, + 235,232,105,128, 10, 29,229,232,225,242,237,229,238,233,225,110, + 128, 5,123,233,115,128, 48, 4,237,239,238,239,243,240,225,227, + 101,128,255, 74,240,225,242,229,110,128, 36,165,243,245,240,229, + 242,233,239,114,128, 2,178,107,146, 0,107,111, 95,113,184,113, + 195,114, 1,114, 12,114,102,114,116,115,224,116,164,116,177,116, + 203,116,252,117,134,117,156,117,169,117,192,117,234,117,244, 97, + 12,111,121,111,153,111,175,111,205,112, 63,112, 88,112,118,112, + 143,112,249,113, 7,113,130,113,159, 98, 2,111,127,111,144,225, + 243,232,235,233,242,227,249,242,233,236,236,233, 99,128, 4,161, + 229,238,231,225,236,105,128, 9,149, 99, 2,111,159,111,165,245, + 244,101,128, 30, 49,249,242,233,236,236,233, 99,128, 4, 58,228, + 101, 2,111,182,111,200,243,227,229,238,228,229,242,227,249,242, + 233,236,236,233, 99,128, 4,155,246, 97,128, 9, 21,102,135, 5, + 219,111,223,111,232,111,252,112, 10,112, 19,112, 35,112, 50,225, + 242,225,226,233, 99,128, 6, 67,228,225,231,229,243,104,129,251, + 59,111,243,232,229,226,242,229,119,128,251, 59,230,233,238,225, + 236,225,242,225,226,233, 99,128,254,218,232,229,226,242,229,119, + 128, 5,219,233,238,233,244,233,225,236,225,242,225,226,233, 99, + 128,254,219,237,229,228,233,225,236,225,242,225,226,233, 99,128, + 254,220,242,225,230,229,232,229,226,242,229,119,128,251, 77,231, + 117, 2,112, 70,112, 79,234,225,242,225,244,105,128, 10,149,242, + 237,245,235,232,105,128, 10, 21,104, 2,112, 94,112,104,233,242, + 225,231,225,238, 97,128, 48, 75,239,239,235,227,249,242,233,236, + 236,233, 99,128, 4,196,235,225,244,225,235,225,238, 97,129, 48, + 171,112,131,232,225,236,230,247,233,228,244,104,128,255,118,112, + 2,112,149,112,170,240, 97,129, 3,186,112,156,243,249,237,226, + 239,236,231,242,229,229,107,128, 3,240,249,229,239,245,110, 3, + 112,182,112,196,112,230,237,233,229,245,237,235,239,242,229,225, + 110,128, 49,113,112, 2,112,202,112,217,232,233,229,245,240,232, + 235,239,242,229,225,110,128, 49,132,233,229,245,240,235,239,242, + 229,225,110,128, 49,120,243,243,225,238,231,240,233,229,245,240, + 235,239,242,229,225,110,128, 49,121,242,239,242,233,233,243,241, + 245,225,242,101,128, 51, 13,115, 5,113, 19,113, 63,113, 78,113, + 86,113,114,232,233,228,225,225,245,244,111, 2,113, 32,113, 41, + 225,242,225,226,233, 99,128, 6, 64,238,239,243,233,228,229,226, + 229,225,242,233,238,231,225,242,225,226,233, 99,128, 6, 64,237, + 225,236,236,235,225,244,225,235,225,238, 97,128, 48,245,241,245, + 225,242,101,128, 51,132,242, 97, 2,113, 93,113,102,225,242,225, + 226,233, 99,128, 6, 80,244,225,238,225,242,225,226,233, 99,128, + 6, 77,244,242,239,235,229,227,249,242,233,236,236,233, 99,128, + 4,159,244,225,232,233,242,225,240,242,239,236,239,238,231,237, + 225,242,235,232,225,236,230,247,233,228,244,104,128,255,112,246, + 229,242,244,233,227,225,236,243,244,242,239,235,229,227,249,242, + 233,236,236,233, 99,128, 4,157,226,239,240,239,237,239,230,111, + 128, 49, 14, 99, 4,113,205,113,227,113,236,113,244, 97, 2,113, + 211,113,221,236,243,241,245,225,242,101,128, 51,137,242,239,110, + 128, 1,233,229,228,233,236,236, 97,128, 1, 55,233,242,227,236, + 101,128, 36,218,239,237,237,225,225,227,227,229,238,116,128, 1, + 55,228,239,244,226,229,236,239,119,128, 30, 51,101, 4,114, 22, + 114, 49,114, 74,114, 86,104, 2,114, 28,114, 39,225,242,237,229, + 238,233,225,110,128, 5,132,233,242,225,231,225,238, 97,128, 48, + 81,235,225,244,225,235,225,238, 97,129, 48,177,114, 62,232,225, + 236,230,247,233,228,244,104,128,255,121,238,225,242,237,229,238, + 233,225,110,128, 5,111,243,237,225,236,236,235,225,244,225,235, + 225,238, 97,128, 48,246,231,242,229,229,238,236,225,238,228,233, + 99,128, 1, 56,104, 6,114,130,115, 3,115, 14,115, 39,115,126, + 115,214, 97, 5,114,142,114,152,114,163,114,170,114,195,226,229, + 238,231,225,236,105,128, 9,150,227,249,242,233,236,236,233, 99, + 128, 4, 69,228,229,246, 97,128, 9, 22,231,117, 2,114,177,114, + 186,234,225,242,225,244,105,128, 10,150,242,237,245,235,232,105, + 128, 10, 22,104, 4,114,205,114,214,114,228,114,244,225,242,225, + 226,233, 99,128, 6, 46,230,233,238,225,236,225,242,225,226,233, + 99,128,254,166,233,238,233,244,233,225,236,225,242,225,226,233, + 99,128,254,167,237,229,228,233,225,236,225,242,225,226,233, 99, + 128,254,168,229,233,227,239,240,244,233, 99,128, 3,231,232, 97, + 2,115, 21,115, 28,228,229,246, 97,128, 9, 89,231,245,242,237, + 245,235,232,105,128, 10, 89,233,229,245,235,104, 4,115, 53,115, + 88,115,103,115,112, 97, 2,115, 59,115, 74,227,233,242,227,236, + 229,235,239,242,229,225,110,128, 50,120,240,225,242,229,238,235, + 239,242,229,225,110,128, 50, 24,227,233,242,227,236,229,235,239, + 242,229,225,110,128, 50,106,235,239,242,229,225,110,128, 49, 75, + 240,225,242,229,238,235,239,242,229,225,110,128, 50, 10,111, 4, + 115,136,115,185,115,195,115,200,235,104, 4,115,147,115,156,115, + 165,115,175,225,233,244,232,225,105,128, 14, 2,239,238,244,232, + 225,105,128, 14, 5,245,225,244,244,232,225,105,128, 14, 3,247, + 225,233,244,232,225,105,128, 14, 4,237,245,244,244,232,225,105, + 128, 14, 91,239,107,128, 1,153,242,225,235,232,225,238,231,244, + 232,225,105,128, 14, 6,250,243,241,245,225,242,101,128, 51,145, + 105, 4,115,234,115,245,116, 14,116, 63,232,233,242,225,231,225, + 238, 97,128, 48, 77,235,225,244,225,235,225,238, 97,129, 48,173, + 116, 2,232,225,236,230,247,233,228,244,104,128,255,119,242,111, + 3,116, 23,116, 38,116, 54,231,245,242,225,237,245,243,241,245, + 225,242,101,128, 51, 21,237,229,229,244,239,242,245,243,241,245, + 225,242,101,128, 51, 22,243,241,245,225,242,101,128, 51, 20,249, + 229,239,107, 5,116, 78,116,113,116,128,116,137,116,151, 97, 2, + 116, 84,116, 99,227,233,242,227,236,229,235,239,242,229,225,110, + 128, 50,110,240,225,242,229,238,235,239,242,229,225,110,128, 50, + 14,227,233,242,227,236,229,235,239,242,229,225,110,128, 50, 96, + 235,239,242,229,225,110,128, 49, 49,240,225,242,229,238,235,239, + 242,229,225,110,128, 50, 0,243,233,239,243,235,239,242,229,225, + 110,128, 49, 51,234,229,227,249,242,233,236,236,233, 99,128, 4, + 92,108, 2,116,183,116,194,233,238,229,226,229,236,239,119,128, + 30, 53,243,241,245,225,242,101,128, 51,152,109, 3,116,211,116, + 225,116,236,227,245,226,229,228,243,241,245,225,242,101,128, 51, + 166,239,238,239,243,240,225,227,101,128,255, 75,243,241,245,225, + 242,229,228,243,241,245,225,242,101,128, 51,162,111, 5,117, 8, + 117, 34,117, 72,117, 84,117, 98,104, 2,117, 14,117, 24,233,242, + 225,231,225,238, 97,128, 48, 83,237,243,241,245,225,242,101,128, + 51,192,235, 97, 2,117, 41,117, 49,233,244,232,225,105,128, 14, + 1,244,225,235,225,238, 97,129, 48,179,117, 60,232,225,236,230, + 247,233,228,244,104,128,255,122,239,240,239,243,241,245,225,242, + 101,128, 51, 30,240,240,225,227,249,242,233,236,236,233, 99,128, + 4,129,114, 2,117,104,117,124,229,225,238,243,244,225,238,228, + 225,242,228,243,249,237,226,239,108,128, 50,127,239,238,233,243, + 227,237, 98,128, 3, 67,240, 97, 2,117,141,117,147,242,229,110, + 128, 36,166,243,241,245,225,242,101,128, 51,170,243,233,227,249, + 242,233,236,236,233, 99,128, 4,111,116, 2,117,175,117,184,243, + 241,245,225,242,101,128, 51,207,245,242,238,229,100,128, 2,158, + 117, 2,117,198,117,209,232,233,242,225,231,225,238, 97,128, 48, + 79,235,225,244,225,235,225,238, 97,129, 48,175,117,222,232,225, + 236,230,247,233,228,244,104,128,255,120,246,243,241,245,225,242, + 101,128, 51,184,247,243,241,245,225,242,101,128, 51,190,108,146, + 0,108,118, 38,120, 65,120, 94,120,160,120,198,121, 94,121,103, + 121,119,121,143,121,161,122, 23,122, 64,122,199,122,207,122,240, + 122,249,123, 1,123, 63, 97, 7,118, 54,118, 64,118, 71,118, 78, + 118,103,118,119,120, 53,226,229,238,231,225,236,105,128, 9,178, + 227,245,244,101,128, 1, 58,228,229,246, 97,128, 9, 50,231,117, + 2,118, 85,118, 94,234,225,242,225,244,105,128, 10,178,242,237, + 245,235,232,105,128, 10, 50,235,235,232,225,238,231,249,225,239, + 244,232,225,105,128, 14, 69,109, 10,118,141,119, 80,119, 97,119, + 135,119,149,119,168,119,184,119,204,119,224,119,247, 97, 2,118, + 147,119, 72,236,229,102, 4,118,159,118,173,119, 9,119, 26,230, + 233,238,225,236,225,242,225,226,233, 99,128,254,252,232,225,237, + 250, 97, 2,118,183,118,224,225,226,239,246,101, 2,118,193,118, + 207,230,233,238,225,236,225,242,225,226,233, 99,128,254,248,233, + 243,239,236,225,244,229,228,225,242,225,226,233, 99,128,254,247, + 226,229,236,239,119, 2,118,234,118,248,230,233,238,225,236,225, + 242,225,226,233, 99,128,254,250,233,243,239,236,225,244,229,228, + 225,242,225,226,233, 99,128,254,249,233,243,239,236,225,244,229, + 228,225,242,225,226,233, 99,128,254,251,237,225,228,228,225,225, + 226,239,246,101, 2,119, 41,119, 55,230,233,238,225,236,225,242, + 225,226,233, 99,128,254,246,233,243,239,236,225,244,229,228,225, + 242,225,226,233, 99,128,254,245,242,225,226,233, 99,128, 6, 68, + 226,228, 97,129, 3,187,119, 88,243,244,242,239,235,101,128, 1, + 155,229,100,130, 5,220,119,106,119,126,228,225,231,229,243,104, + 129,251, 60,119,117,232,229,226,242,229,119,128,251, 60,232,229, + 226,242,229,119,128, 5,220,230,233,238,225,236,225,242,225,226, + 233, 99,128,254,222,232,225,232,233,238,233,244,233,225,236,225, + 242,225,226,233, 99,128,252,202,233,238,233,244,233,225,236,225, + 242,225,226,233, 99,128,254,223,234,229,229,237,233,238,233,244, + 233,225,236,225,242,225,226,233, 99,128,252,201,235,232,225,232, + 233,238,233,244,233,225,236,225,242,225,226,233, 99,128,252,203, + 236,225,237,232,229,232,233,243,239,236,225,244,229,228,225,242, + 225,226,233, 99,128,253,242,237,101, 2,119,254,120, 11,228,233, + 225,236,225,242,225,226,233, 99,128,254,224,229,109, 2,120, 18, + 120, 37,232,225,232,233,238,233,244,233,225,236,225,242,225,226, + 233, 99,128,253,136,233,238,233,244,233,225,236,225,242,225,226, + 233, 99,128,252,204,242,231,229,227,233,242,227,236,101,128, 37, + 239, 98, 3,120, 73,120, 78,120, 84,225,114,128, 1,154,229,236, + 116,128, 2,108,239,240,239,237,239,230,111,128, 49, 12, 99, 4, + 120,104,120,111,120,120,120,147,225,242,239,110,128, 1, 62,229, + 228,233,236,236, 97,128, 1, 60,233,242, 99, 2,120,128,120,133, + 236,101,128, 36,219,245,237,230,236,229,248,226,229,236,239,119, + 128, 30, 61,239,237,237,225,225,227,227,229,238,116,128, 1, 60, + 228,239,116,130, 1, 64,120,170,120,179,225,227,227,229,238,116, + 128, 1, 64,226,229,236,239,119,129, 30, 55,120,189,237,225,227, + 242,239,110,128, 30, 57,101, 3,120,206,120,244,121, 89,230,116, + 2,120,213,120,229,225,238,231,236,229,225,226,239,246,229,227, + 237, 98,128, 3, 26,244,225,227,235,226,229,236,239,247,227,237, + 98,128, 3, 24,243,115,132, 0, 60,121, 1,121, 23,121, 35,121, + 81,229,241,245,225,108,129, 34,100,121, 11,239,242,231,242,229, + 225,244,229,114,128, 34,218,237,239,238,239,243,240,225,227,101, + 128,255, 28,111, 2,121, 41,121, 70,114, 2,121, 47,121, 60,229, + 241,245,233,246,225,236,229,238,116,128, 34,114,231,242,229,225, + 244,229,114,128, 34,118,246,229,242,229,241,245,225,108,128, 34, + 102,243,237,225,236,108,128,254,100,250,104,128, 2,110,230,226, + 236,239,227,107,128, 37,140,232,239,239,235,242,229,244,242,239, + 230,236,229,120,128, 2,109,105, 2,121,125,121,130,242, 97,128, + 32,164,247,238,225,242,237,229,238,233,225,110,128, 5,108,106, + 129, 1,201,121,149,229,227,249,242,233,236,236,233, 99,128, 4, + 89,108,132,246,192,121,173,121,197,121,208,121,217, 97, 2,121, + 179,121,186,228,229,246, 97,128, 9, 51,231,245,234,225,242,225, + 244,105,128, 10,179,233,238,229,226,229,236,239,119,128, 30, 59, + 236,225,228,229,246, 97,128, 9, 52,246,239,227,225,236,233, 99, + 3,121,231,121,241,121,248,226,229,238,231,225,236,105,128, 9, + 225,228,229,246, 97,128, 9, 97,246,239,247,229,236,243,233,231, + 110, 2,122, 6,122, 16,226,229,238,231,225,236,105,128, 9,227, + 228,229,246, 97,128, 9, 99,109, 3,122, 31,122, 44,122, 55,233, + 228,228,236,229,244,233,236,228,101,128, 2,107,239,238,239,243, + 240,225,227,101,128,255, 76,243,241,245,225,242,101,128, 51,208, + 111, 6,122, 78,122, 90,122,132,122,143,122,149,122,191,227,232, + 245,236,225,244,232,225,105,128, 14, 44,231,233,227,225,108, 3, + 122,102,122,108,122,127,225,238,100,128, 34, 39,238,239,116,129, + 0,172,122,116,242,229,246,229,242,243,229,100,128, 35, 16,239, + 114,128, 34, 40,236,233,238,231,244,232,225,105,128, 14, 37,238, + 231,115,128, 1,127,247,236,233,238,101, 2,122,159,122,182, 99, + 2,122,165,122,177,229,238,244,229,242,236,233,238,101,128,254, + 78,237, 98,128, 3, 50,228,225,243,232,229,100,128,254, 77,250, + 229,238,231,101,128, 37,202,240,225,242,229,110,128, 36,167,115, + 3,122,215,122,222,122,230,236,225,243,104,128, 1, 66,241,245, + 225,242,101,128, 33, 19,245,240,229,242,233,239,114,128,246,238, + 244,243,232,225,228,101,128, 37,145,245,244,232,225,105,128, 14, + 38,246,239,227,225,236,233, 99, 3,123, 15,123, 25,123, 32,226, + 229,238,231,225,236,105,128, 9,140,228,229,246, 97,128, 9, 12, + 246,239,247,229,236,243,233,231,110, 2,123, 46,123, 56,226,229, + 238,231,225,236,105,128, 9,226,228,229,246, 97,128, 9, 98,248, + 243,241,245,225,242,101,128, 51,211,109,144, 0,109,123,109,125, + 218,125,243,126, 14,126, 39,127, 92,127,114,128,169,128,199,128, + 248,129, 99,129,121,129,146,129,155,130,182,130,210, 97, 12,123, + 135,123,145,123,209,123,216,123,241,124, 33,125,125,125,150,125, + 155,125,169,125,181,125,186,226,229,238,231,225,236,105,128, 9, + 174, 99, 2,123,151,123,203,242,239,110,132, 0,175,123,165,123, + 176,123,182,123,191,226,229,236,239,247,227,237, 98,128, 3, 49, + 227,237, 98,128, 3, 4,236,239,247,237,239,100,128, 2,205,237, + 239,238,239,243,240,225,227,101,128,255,227,245,244,101,128, 30, + 63,228,229,246, 97,128, 9, 46,231,117, 2,123,223,123,232,234, + 225,242,225,244,105,128, 10,174,242,237,245,235,232,105,128, 10, + 46,104, 2,123,247,124, 23,225,240,225,235,104, 2,124, 1,124, + 10,232,229,226,242,229,119,128, 5,164,236,229,230,244,232,229, + 226,242,229,119,128, 5,164,233,242,225,231,225,238, 97,128, 48, + 126,105, 5,124, 45,124,114,124,177,124,207,125,113,227,232,225, + 244,244,225,247, 97, 3,124, 60,124, 91,124, 98,236,239,119, 2, + 124, 68,124, 79,236,229,230,244,244,232,225,105,128,248,149,242, + 233,231,232,244,244,232,225,105,128,248,148,244,232,225,105,128, + 14, 75,245,240,240,229,242,236,229,230,244,244,232,225,105,128, + 248,147,229,107, 3,124,123,124,154,124,161,236,239,119, 2,124, + 131,124,142,236,229,230,244,244,232,225,105,128,248,140,242,233, + 231,232,244,244,232,225,105,128,248,139,244,232,225,105,128, 14, + 72,245,240,240,229,242,236,229,230,244,244,232,225,105,128,248, + 138,232,225,238,225,235,225,116, 2,124,189,124,200,236,229,230, + 244,244,232,225,105,128,248,132,244,232,225,105,128, 14, 49,116, + 3,124,215,124,243,125, 50,225,233,235,232,117, 2,124,225,124, + 236,236,229,230,244,244,232,225,105,128,248,137,244,232,225,105, + 128, 14, 71,232,111, 3,124,252,125, 27,125, 34,236,239,119, 2, + 125, 4,125, 15,236,229,230,244,244,232,225,105,128,248,143,242, + 233,231,232,244,244,232,225,105,128,248,142,244,232,225,105,128, + 14, 73,245,240,240,229,242,236,229,230,244,244,232,225,105,128, + 248,141,242,105, 3,125, 59,125, 90,125, 97,236,239,119, 2,125, + 67,125, 78,236,229,230,244,244,232,225,105,128,248,146,242,233, + 231,232,244,244,232,225,105,128,248,145,244,232,225,105,128, 14, + 74,245,240,240,229,242,236,229,230,244,244,232,225,105,128,248, + 144,249,225,237,239,235,244,232,225,105,128, 14, 70,235,225,244, + 225,235,225,238, 97,129, 48,222,125,138,232,225,236,230,247,233, + 228,244,104,128,255,143,236,101,128, 38, 66,238,243,249,239,238, + 243,241,245,225,242,101,128, 51, 71,241,225,230,232,229,226,242, + 229,119,128, 5,190,242,115,128, 38, 66,115, 2,125,192,125,210, + 239,242,225,227,233,242,227,236,229,232,229,226,242,229,119,128, + 5,175,241,245,225,242,101,128, 51,131, 98, 2,125,224,125,234, + 239,240,239,237,239,230,111,128, 49, 7,243,241,245,225,242,101, + 128, 51,212, 99, 2,125,249,126, 1,233,242,227,236,101,128, 36, + 220,245,226,229,228,243,241,245,225,242,101,128, 51,165,228,239, + 116, 2,126, 22,126, 31,225,227,227,229,238,116,128, 30, 65,226, + 229,236,239,119,128, 30, 67,101, 7,126, 55,126,182,126,193,126, + 208,126,233,127, 14,127, 26,101, 2,126, 61,126,169,109, 4,126, + 71,126, 80,126, 94,126,110,225,242,225,226,233, 99,128, 6, 69, + 230,233,238,225,236,225,242,225,226,233, 99,128,254,226,233,238, + 233,244,233,225,236,225,242,225,226,233, 99,128,254,227,237,101, + 2,126,117,126,130,228,233,225,236,225,242,225,226,233, 99,128, + 254,228,229,237,105, 2,126,138,126,153,238,233,244,233,225,236, + 225,242,225,226,233, 99,128,252,209,243,239,236,225,244,229,228, + 225,242,225,226,233, 99,128,252, 72,244,239,242,245,243,241,245, + 225,242,101,128, 51, 77,232,233,242,225,231,225,238, 97,128, 48, + 129,233,250,233,229,242,225,243,241,245,225,242,101,128, 51,126, + 235,225,244,225,235,225,238, 97,129, 48,225,126,221,232,225,236, + 230,247,233,228,244,104,128,255,146,109,130, 5,222,126,241,127, + 5,228,225,231,229,243,104,129,251, 62,126,252,232,229,226,242, + 229,119,128,251, 62,232,229,226,242,229,119,128, 5,222,238,225, + 242,237,229,238,233,225,110,128, 5,116,242,235,232, 97, 3,127, + 37,127, 46,127, 79,232,229,226,242,229,119,128, 5,165,235,229, + 230,245,236, 97, 2,127, 57,127, 66,232,229,226,242,229,119,128, + 5,166,236,229,230,244,232,229,226,242,229,119,128, 5,166,236, + 229,230,244,232,229,226,242,229,119,128, 5,165,104, 2,127, 98, + 127,104,239,239,107,128, 2,113,250,243,241,245,225,242,101,128, + 51,146,105, 6,127,128,127,165,128, 46,128, 57,128, 82,128,139, + 228,100, 2,127,135,127,160,236,229,228,239,244,235,225,244,225, + 235,225,238,225,232,225,236,230,247,233,228,244,104,128,255,101, + 239,116,128, 0,183,229,245,109, 5,127,179,127,214,127,229,127, + 238,128, 33, 97, 2,127,185,127,200,227,233,242,227,236,229,235, + 239,242,229,225,110,128, 50,114,240,225,242,229,238,235,239,242, + 229,225,110,128, 50, 18,227,233,242,227,236,229,235,239,242,229, + 225,110,128, 50,100,235,239,242,229,225,110,128, 49, 65,112, 2, + 127,244,128, 20, 97, 2,127,250,128, 8,238,243,233,239,243,235, + 239,242,229,225,110,128, 49,112,242,229,238,235,239,242,229,225, + 110,128, 50, 4,233,229,245,240,235,239,242,229,225,110,128, 49, + 110,243,233,239,243,235,239,242,229,225,110,128, 49,111,232,233, + 242,225,231,225,238, 97,128, 48,127,235,225,244,225,235,225,238, + 97,129, 48,223,128, 70,232,225,236,230,247,233,228,244,104,128, + 255,144,238,117, 2,128, 89,128,134,115,132, 34, 18,128,101,128, + 112,128,121,128,127,226,229,236,239,247,227,237, 98,128, 3, 32, + 227,233,242,227,236,101,128, 34,150,237,239,100,128, 2,215,240, + 236,245,115,128, 34, 19,244,101,128, 32, 50,242,105, 2,128,146, + 128,160,226,225,225,242,245,243,241,245,225,242,101,128, 51, 74, + 243,241,245,225,242,101,128, 51, 73,108, 2,128,175,128,190,239, + 238,231,236,229,231,244,245,242,238,229,100,128, 2,112,243,241, + 245,225,242,101,128, 51,150,109, 3,128,207,128,221,128,232,227, + 245,226,229,228,243,241,245,225,242,101,128, 51,163,239,238,239, + 243,240,225,227,101,128,255, 77,243,241,245,225,242,229,228,243, + 241,245,225,242,101,128, 51,159,111, 5,129, 4,129, 30,129, 55, + 129, 65,129, 74,104, 2,129, 10,129, 20,233,242,225,231,225,238, + 97,128, 48,130,237,243,241,245,225,242,101,128, 51,193,235,225, + 244,225,235,225,238, 97,129, 48,226,129, 43,232,225,236,230,247, + 233,228,244,104,128,255,147,236,243,241,245,225,242,101,128, 51, + 214,237,225,244,232,225,105,128, 14, 33,246,229,242,243,243,241, + 245,225,242,101,129, 51,167,129, 89,228,243,241,245,225,242,101, + 128, 51,168,240, 97, 2,129,106,129,112,242,229,110,128, 36,168, + 243,241,245,225,242,101,128, 51,171,115, 2,129,127,129,136,243, + 241,245,225,242,101,128, 51,179,245,240,229,242,233,239,114,128, + 246,239,244,245,242,238,229,100,128, 2,111,117,141, 0,181,129, + 185,129,189,129,199,129,223,129,233,129,255,130, 10,130, 35,130, + 58,130, 68,130, 98,130,162,130,172, 49,128, 0,181,225,243,241, + 245,225,242,101,128, 51,130,227,104, 2,129,206,129,216,231,242, + 229,225,244,229,114,128, 34,107,236,229,243,115,128, 34,106,230, + 243,241,245,225,242,101,128, 51,140,103, 2,129,239,129,246,242, + 229,229,107,128, 3,188,243,241,245,225,242,101,128, 51,141,232, + 233,242,225,231,225,238, 97,128, 48,128,235,225,244,225,235,225, + 238, 97,129, 48,224,130, 23,232,225,236,230,247,233,228,244,104, + 128,255,145,108, 2,130, 41,130, 50,243,241,245,225,242,101,128, + 51,149,244,233,240,236,121,128, 0,215,237,243,241,245,225,242, + 101,128, 51,155,238,225,104, 2,130, 76,130, 85,232,229,226,242, + 229,119,128, 5,163,236,229,230,244,232,229,226,242,229,119,128, + 5,163,115, 2,130,104,130,153,233, 99, 3,130,113,130,130,130, + 141,225,236,238,239,244,101,129, 38,106,130,124,228,226,108,128, + 38,107,230,236,225,244,243,233,231,110,128, 38,109,243,232,225, + 242,240,243,233,231,110,128, 38,111,243,241,245,225,242,101,128, + 51,178,246,243,241,245,225,242,101,128, 51,182,247,243,241,245, + 225,242,101,128, 51,188,118, 2,130,188,130,201,237,229,231,225, + 243,241,245,225,242,101,128, 51,185,243,241,245,225,242,101,128, + 51,183,119, 2,130,216,130,229,237,229,231,225,243,241,245,225, + 242,101,128, 51,191,243,241,245,225,242,101,128, 51,189,110,150, + 0,110,131, 30,131,164,131,188,131,254,132, 23,132, 81,132, 91, + 132,158,132,201,134,235,134,253,135, 22,135, 53,135, 79,135,144, + 137,126,137,134,137,159,137,167,138,135,138,145,138,155, 97, 8, + 131, 48,131, 68,131, 75,131, 82,131,107,131,118,131,143,131,155, + 98, 2,131, 54,131, 63,229,238,231,225,236,105,128, 9,168,236, + 97,128, 34, 7,227,245,244,101,128, 1, 68,228,229,246, 97,128, + 9, 40,231,117, 2,131, 89,131, 98,234,225,242,225,244,105,128, + 10,168,242,237,245,235,232,105,128, 10, 40,232,233,242,225,231, + 225,238, 97,128, 48,106,235,225,244,225,235,225,238, 97,129, 48, + 202,131,131,232,225,236,230,247,233,228,244,104,128,255,133,240, + 239,243,244,242,239,240,232,101,128, 1, 73,243,241,245,225,242, + 101,128, 51,129, 98, 2,131,170,131,180,239,240,239,237,239,230, + 111,128, 49, 11,243,240,225,227,101,128, 0,160, 99, 4,131,198, + 131,205,131,214,131,241,225,242,239,110,128, 1, 72,229,228,233, + 236,236, 97,128, 1, 70,233,242, 99, 2,131,222,131,227,236,101, + 128, 36,221,245,237,230,236,229,248,226,229,236,239,119,128, 30, + 75,239,237,237,225,225,227,227,229,238,116,128, 1, 70,228,239, + 116, 2,132, 6,132, 15,225,227,227,229,238,116,128, 30, 69,226, + 229,236,239,119,128, 30, 71,101, 3,132, 31,132, 42,132, 67,232, + 233,242,225,231,225,238, 97,128, 48,109,235,225,244,225,235,225, + 238, 97,129, 48,205,132, 55,232,225,236,230,247,233,228,244,104, + 128,255,136,247,243,232,229,241,229,236,243,233,231,110,128, 32, + 170,230,243,241,245,225,242,101,128, 51,139,103, 2,132, 97,132, + 147, 97, 3,132,105,132,115,132,122,226,229,238,231,225,236,105, + 128, 9,153,228,229,246, 97,128, 9, 25,231,117, 2,132,129,132, + 138,234,225,242,225,244,105,128, 10,153,242,237,245,235,232,105, + 128, 10, 25,239,238,231,245,244,232,225,105,128, 14, 7,104, 2, + 132,164,132,174,233,242,225,231,225,238, 97,128, 48,147,239,239, + 107, 2,132,182,132,189,236,229,230,116,128, 2,114,242,229,244, + 242,239,230,236,229,120,128, 2,115,105, 4,132,211,133,124,133, + 135,133,193,229,245,110, 7,132,229,133, 8,133, 40,133, 54,133, + 63,133, 96,133,109, 97, 2,132,235,132,250,227,233,242,227,236, + 229,235,239,242,229,225,110,128, 50,111,240,225,242,229,238,235, + 239,242,229,225,110,128, 50, 15,227,105, 2,133, 15,133, 27,229, + 245,227,235,239,242,229,225,110,128, 49, 53,242,227,236,229,235, + 239,242,229,225,110,128, 50, 97,232,233,229,245,232,235,239,242, + 229,225,110,128, 49, 54,235,239,242,229,225,110,128, 49, 52,240, + 97, 2,133, 70,133, 84,238,243,233,239,243,235,239,242,229,225, + 110,128, 49,104,242,229,238,235,239,242,229,225,110,128, 50, 1, + 243,233,239,243,235,239,242,229,225,110,128, 49,103,244,233,235, + 229,245,244,235,239,242,229,225,110,128, 49,102,232,233,242,225, + 231,225,238, 97,128, 48,107,107, 2,133,141,133,165,225,244,225, + 235,225,238, 97,129, 48,203,133,153,232,225,236,230,247,233,228, + 244,104,128,255,134,232,225,232,233,116, 2,133,175,133,186,236, + 229,230,244,244,232,225,105,128,248,153,244,232,225,105,128, 14, + 77,238,101,141, 0, 57,133,224,133,233,133,243,134, 17,134, 24, + 134, 49,134, 76,134,110,134,122,134,133,134,166,134,174,134,185, + 225,242,225,226,233, 99,128, 6,105,226,229,238,231,225,236,105, + 128, 9,239,227,233,242,227,236,101,129, 36,104,133,254,233,238, + 246,229,242,243,229,243,225,238,243,243,229,242,233,102,128, 39, + 146,228,229,246, 97,128, 9,111,231,117, 2,134, 31,134, 40,234, + 225,242,225,244,105,128, 10,239,242,237,245,235,232,105,128, 10, + 111,232, 97, 2,134, 56,134, 67,227,235,225,242,225,226,233, 99, + 128, 6,105,238,231,250,232,239,117,128, 48, 41,105, 2,134, 82, + 134,100,228,229,239,231,242,225,240,232,233,227,240,225,242,229, + 110,128, 50, 40,238,230,229,242,233,239,114,128, 32,137,237,239, + 238,239,243,240,225,227,101,128,255, 25,239,236,228,243,244,249, + 236,101,128,247, 57,112, 2,134,139,134,146,225,242,229,110,128, + 36,124,229,114, 2,134,153,134,159,233,239,100,128, 36,144,243, + 233,225,110,128, 6,249,242,239,237,225,110,128, 33,120,243,245, + 240,229,242,233,239,114,128, 32,121,116, 2,134,191,134,229,229, + 229,110, 2,134,199,134,208,227,233,242,227,236,101,128, 36,114, + 112, 2,134,214,134,221,225,242,229,110,128, 36,134,229,242,233, + 239,100,128, 36,154,232,225,105,128, 14, 89,106,129, 1,204,134, + 241,229,227,249,242,233,236,236,233, 99,128, 4, 90,235,225,244, + 225,235,225,238, 97,129, 48,243,135, 10,232,225,236,230,247,233, + 228,244,104,128,255,157,108, 2,135, 28,135, 42,229,231,242,233, + 231,232,244,236,239,238,103,128, 1,158,233,238,229,226,229,236, + 239,119,128, 30, 73,109, 2,135, 59,135, 70,239,238,239,243,240, + 225,227,101,128,255, 78,243,241,245,225,242,101,128, 51,154,110, + 2,135, 85,135,135, 97, 3,135, 93,135,103,135,110,226,229,238, + 231,225,236,105,128, 9,163,228,229,246, 97,128, 9, 35,231,117, + 2,135,117,135,126,234,225,242,225,244,105,128, 10,163,242,237, + 245,235,232,105,128, 10, 35,238,225,228,229,246, 97,128, 9, 41, + 111, 6,135,158,135,169,135,194,135,235,136,187,137,114,232,233, + 242,225,231,225,238, 97,128, 48,110,235,225,244,225,235,225,238, + 97,129, 48,206,135,182,232,225,236,230,247,233,228,244,104,128, + 255,137,110, 3,135,202,135,218,135,227,226,242,229,225,235,233, + 238,231,243,240,225,227,101,128, 0,160,229,238,244,232,225,105, + 128, 14, 19,245,244,232,225,105,128, 14, 25,239,110, 7,135,252, + 136, 5,136, 19,136, 53,136, 69,136,110,136,169,225,242,225,226, + 233, 99,128, 6, 70,230,233,238,225,236,225,242,225,226,233, 99, + 128,254,230,231,232,245,238,238, 97, 2,136, 30,136, 39,225,242, + 225,226,233, 99,128, 6,186,230,233,238,225,236,225,242,225,226, + 233, 99,128,251,159,233,238,233,244,233,225,236,225,242,225,226, + 233, 99,128,254,231,234,229,229,237,105, 2,136, 79,136, 94,238, + 233,244,233,225,236,225,242,225,226,233, 99,128,252,210,243,239, + 236,225,244,229,228,225,242,225,226,233, 99,128,252, 75,237,101, + 2,136,117,136,130,228,233,225,236,225,242,225,226,233, 99,128, + 254,232,229,237,105, 2,136,138,136,153,238,233,244,233,225,236, + 225,242,225,226,233, 99,128,252,213,243,239,236,225,244,229,228, + 225,242,225,226,233, 99,128,252, 78,238,239,239,238,230,233,238, + 225,236,225,242,225,226,233, 99,128,252,141,116, 7,136,203,136, + 214,136,243,137, 22,137, 34,137, 54,137, 80,227,239,238,244,225, + 233,238,115,128, 34, 12,101, 2,136,220,136,236,236,229,237,229, + 238,116,129, 34, 9,136,231,239,102,128, 34, 9,241,245,225,108, + 128, 34, 96,231,242,229,225,244,229,114,129, 34,111,136,255,238, + 239,114, 2,137, 7,137, 15,229,241,245,225,108,128, 34,113,236, + 229,243,115,128, 34,121,233,228,229,238,244,233,227,225,108,128, + 34, 98,236,229,243,115,129, 34,110,137, 43,238,239,242,229,241, + 245,225,108,128, 34,112,112, 2,137, 60,137, 70,225,242,225,236, + 236,229,108,128, 34, 38,242,229,227,229,228,229,115,128, 34,128, + 243,117, 3,137, 89,137, 96,137,105,226,243,229,116,128, 34,132, + 227,227,229,229,228,115,128, 34,129,240,229,242,243,229,116,128, + 34,133,247,225,242,237,229,238,233,225,110,128, 5,118,240,225, + 242,229,110,128, 36,169,115, 2,137,140,137,149,243,241,245,225, + 242,101,128, 51,177,245,240,229,242,233,239,114,128, 32,127,244, + 233,236,228,101,128, 0,241,117,132, 3,189,137,179,137,190,138, + 15,138, 98,232,233,242,225,231,225,238, 97,128, 48,108,107, 2, + 137,196,137,220,225,244,225,235,225,238, 97,129, 48,204,137,208, + 232,225,236,230,247,233,228,244,104,128,255,135,244, 97, 3,137, + 229,137,239,137,246,226,229,238,231,225,236,105,128, 9,188,228, + 229,246, 97,128, 9, 60,231,117, 2,137,253,138, 6,234,225,242, + 225,244,105,128, 10,188,242,237,245,235,232,105,128, 10, 60,109, + 2,138, 21,138, 55,226,229,242,243,233,231,110,130, 0, 35,138, + 35,138, 47,237,239,238,239,243,240,225,227,101,128,255, 3,243, + 237,225,236,108,128,254, 95,229,114, 2,138, 62,138, 94,225,236, + 243,233,231,110, 2,138, 73,138, 81,231,242,229,229,107,128, 3, + 116,236,239,247,229,242,231,242,229,229,107,128, 3,117,111,128, + 33, 22,110,130, 5,224,138,106,138,126,228,225,231,229,243,104, + 129,251, 64,138,117,232,229,226,242,229,119,128,251, 64,232,229, + 226,242,229,119,128, 5,224,246,243,241,245,225,242,101,128, 51, + 181,247,243,241,245,225,242,101,128, 51,187,249, 97, 3,138,164, + 138,174,138,181,226,229,238,231,225,236,105,128, 9,158,228,229, + 246, 97,128, 9, 30,231,117, 2,138,188,138,197,234,225,242,225, + 244,105,128, 10,158,242,237,245,235,232,105,128, 10, 30,111,147, + 0,111,138,248,139, 14,139, 92,140, 6,140, 78,140, 93,140,133, + 141, 0,141, 21,141, 59,141, 70,141,248,143, 82,143,146,143,179, + 143,225,144, 98,144,145,144,157, 97, 2,138,254,139, 5,227,245, + 244,101,128, 0,243,238,231,244,232,225,105,128, 14, 45, 98, 4, + 139, 24,139, 66,139, 75,139, 85,225,242,242,229,100,130, 2,117, + 139, 36,139, 47,227,249,242,233,236,236,233, 99,128, 4,233,228, + 233,229,242,229,243,233,243,227,249,242,233,236,236,233, 99,128, + 4,235,229,238,231,225,236,105,128, 9,147,239,240,239,237,239, + 230,111,128, 49, 27,242,229,246,101,128, 1, 79, 99, 3,139,100, + 139,173,139,252, 97, 2,139,106,139,167,238,228,242, 97, 3,139, + 117,139,124,139,135,228,229,246, 97,128, 9, 17,231,245,234,225, + 242,225,244,105,128, 10,145,246,239,247,229,236,243,233,231,110, + 2,139,149,139,156,228,229,246, 97,128, 9, 73,231,245,234,225, + 242,225,244,105,128, 10,201,242,239,110,128, 1,210,233,242, 99, + 2,139,181,139,186,236,101,128, 36,222,245,237,230,236,229,120, + 133, 0,244,139,205,139,213,139,224,139,232,139,244,225,227,245, + 244,101,128, 30,209,228,239,244,226,229,236,239,119,128, 30,217, + 231,242,225,246,101,128, 30,211,232,239,239,235,225,226,239,246, + 101,128, 30,213,244,233,236,228,101,128, 30,215,249,242,233,236, + 236,233, 99,128, 4, 62,100, 4,140, 16,140, 39,140, 45,140, 68, + 226,108, 2,140, 23,140, 31,225,227,245,244,101,128, 1, 81,231, + 242,225,246,101,128, 2, 13,229,246, 97,128, 9, 19,233,229,242, + 229,243,233,115,129, 0,246,140, 57,227,249,242,233,236,236,233, + 99,128, 4,231,239,244,226,229,236,239,119,128, 30,205,101,129, + 1, 83,140, 84,235,239,242,229,225,110,128, 49, 90,103, 3,140, + 101,140,116,140,123,239,238,229,107,129, 2,219,140,110,227,237, + 98,128, 3, 40,242,225,246,101,128, 0,242,245,234,225,242,225, + 244,105,128, 10,147,104, 4,140,143,140,154,140,164,140,242,225, + 242,237,229,238,233,225,110,128, 5,133,233,242,225,231,225,238, + 97,128, 48, 74,111, 2,140,170,140,180,239,235,225,226,239,246, + 101,128, 30,207,242,110,133, 1,161,140,195,140,203,140,214,140, + 222,140,234,225,227,245,244,101,128, 30,219,228,239,244,226,229, + 236,239,119,128, 30,227,231,242,225,246,101,128, 30,221,232,239, + 239,235,225,226,239,246,101,128, 30,223,244,233,236,228,101,128, + 30,225,245,238,231,225,242,245,237,236,225,245,116,128, 1, 81, + 105,129, 1,163,141, 6,238,246,229,242,244,229,228,226,242,229, + 246,101,128, 2, 15,107, 2,141, 27,141, 51,225,244,225,235,225, + 238, 97,129, 48,170,141, 39,232,225,236,230,247,233,228,244,104, + 128,255,117,239,242,229,225,110,128, 49, 87,236,229,232,229,226, + 242,229,119,128, 5,171,109, 6,141, 84,141,112,141,119,141,208, + 141,219,141,237,225,227,242,239,110,130, 1, 77,141, 96,141,104, + 225,227,245,244,101,128, 30, 83,231,242,225,246,101,128, 30, 81, + 228,229,246, 97,128, 9, 80,229,231, 97,133, 3,201,141,135,141, + 139,141,150,141,164,141,180, 49,128, 3,214,227,249,242,233,236, + 236,233, 99,128, 4, 97,236,225,244,233,238,227,236,239,243,229, + 100,128, 2,119,242,239,245,238,228,227,249,242,233,236,236,233, + 99,128, 4,123,116, 2,141,186,141,201,233,244,236,239,227,249, + 242,233,236,236,233, 99,128, 4,125,239,238,239,115,128, 3,206, + 231,245,234,225,242,225,244,105,128, 10,208,233,227,242,239,110, + 129, 3,191,141,229,244,239,238,239,115,128, 3,204,239,238,239, + 243,240,225,227,101,128,255, 79,238,101,145, 0, 49,142, 31,142, + 40,142, 50,142, 80,142,105,142,114,142,123,142,148,142,182,142, + 216,142,228,142,247,143, 2,143, 35,143, 45,143, 53,143, 64,225, + 242,225,226,233, 99,128, 6, 97,226,229,238,231,225,236,105,128, + 9,231,227,233,242,227,236,101,129, 36, 96,142, 61,233,238,246, + 229,242,243,229,243,225,238,243,243,229,242,233,102,128, 39,138, + 100, 2,142, 86,142, 92,229,246, 97,128, 9,103,239,244,229,238, + 236,229,225,228,229,114,128, 32, 36,229,233,231,232,244,104,128, + 33, 91,230,233,244,244,229,100,128,246,220,231,117, 2,142,130, + 142,139,234,225,242,225,244,105,128, 10,231,242,237,245,235,232, + 105,128, 10,103,232, 97, 3,142,157,142,168,142,173,227,235,225, + 242,225,226,233, 99,128, 6, 97,236,102,128, 0,189,238,231,250, + 232,239,117,128, 48, 33,105, 2,142,188,142,206,228,229,239,231, + 242,225,240,232,233,227,240,225,242,229,110,128, 50, 32,238,230, + 229,242,233,239,114,128, 32,129,237,239,238,239,243,240,225,227, + 101,128,255, 17,238,245,237,229,242,225,244,239,242,226,229,238, + 231,225,236,105,128, 9,244,239,236,228,243,244,249,236,101,128, + 247, 49,112, 2,143, 8,143, 15,225,242,229,110,128, 36,116,229, + 114, 2,143, 22,143, 28,233,239,100,128, 36,136,243,233,225,110, + 128, 6,241,241,245,225,242,244,229,114,128, 0,188,242,239,237, + 225,110,128, 33,112,243,245,240,229,242,233,239,114,128, 0,185, + 244,104, 2,143, 71,143, 76,225,105,128, 14, 81,233,242,100,128, + 33, 83,111, 3,143, 90,143,124,143,140,103, 2,143, 96,143,114, + 239,238,229,107,129, 1,235,143,105,237,225,227,242,239,110,128, + 1,237,245,242,237,245,235,232,105,128, 10, 19,237,225,244,242, + 225,231,245,242,237,245,235,232,105,128, 10, 75,240,229,110,128, + 2, 84,112, 3,143,154,143,161,143,172,225,242,229,110,128, 36, + 170,229,238,226,245,236,236,229,116,128, 37,230,244,233,239,110, + 128, 35, 37,114, 2,143,185,143,214,100, 2,143,191,143,202,230, + 229,237,233,238,233,238,101,128, 0,170,237,225,243,227,245,236, + 233,238,101,128, 0,186,244,232,239,231,239,238,225,108,128, 34, + 31,115, 5,143,237,144, 13,144, 30,144, 75,144, 88,232,239,242, + 116, 2,143,246,143,253,228,229,246, 97,128, 9, 18,246,239,247, + 229,236,243,233,231,238,228,229,246, 97,128, 9, 74,236,225,243, + 104,129, 0,248,144, 22,225,227,245,244,101,128, 1,255,237,225, + 236,108, 2,144, 39,144, 50,232,233,242,225,231,225,238, 97,128, + 48, 73,235,225,244,225,235,225,238, 97,129, 48,169,144, 63,232, + 225,236,230,247,233,228,244,104,128,255,107,244,242,239,235,229, + 225,227,245,244,101,128, 1,255,245,240,229,242,233,239,114,128, + 246,240,116, 2,144,104,144,115,227,249,242,233,236,236,233, 99, + 128, 4,127,233,236,228,101,130, 0,245,144,126,144,134,225,227, + 245,244,101,128, 30, 77,228,233,229,242,229,243,233,115,128, 30, + 79,245,226,239,240,239,237,239,230,111,128, 49, 33,118, 2,144, + 163,144,244,229,114, 2,144,170,144,236,236,233,238,101,131, 32, + 62,144,183,144,206,144,229, 99, 2,144,189,144,201,229,238,244, + 229,242,236,233,238,101,128,254, 74,237, 98,128, 3, 5,100, 2, + 144,212,144,220,225,243,232,229,100,128,254, 73,226,236,247,225, + 246,121,128,254, 76,247,225,246,121,128,254, 75,243,227,239,242, + 101,128, 0,175,239,247,229,236,243,233,231,110, 3,145, 3,145, + 13,145, 20,226,229,238,231,225,236,105,128, 9,203,228,229,246, + 97,128, 9, 75,231,245,234,225,242,225,244,105,128, 10,203,112, + 145, 0,112,145, 69,147,197,147,208,147,217,147,229,149,154,149, + 164,150,156,151,175,152, 9,152, 35,152,166,152,174,153, 76,153, + 134,153,162,153,172, 97, 14,145, 99,145,131,145,141,145,148,145, + 155,145,203,145,214,145,228,145,239,146, 30,146, 44,147, 56,147, + 95,147,185, 97, 2,145,105,145,117,237,240,243,243,241,245,225, + 242,101,128, 51,128,243,229,238,244,239,243,241,245,225,242,101, + 128, 51, 43,226,229,238,231,225,236,105,128, 9,170,227,245,244, + 101,128, 30, 85,228,229,246, 97,128, 9, 42,103, 2,145,161,145, + 179,101, 2,145,167,145,174,228,239,247,110,128, 33,223,245,112, + 128, 33,222,117, 2,145,185,145,194,234,225,242,225,244,105,128, + 10,170,242,237,245,235,232,105,128, 10, 42,232,233,242,225,231, + 225,238, 97,128, 48,113,233,249,225,238,238,239,233,244,232,225, + 105,128, 14, 47,235,225,244,225,235,225,238, 97,128, 48,209,108, + 2,145,245,146, 14,225,244,225,236,233,250,225,244,233,239,238, + 227,249,242,233,236,236,233,227,227,237, 98,128, 4,132,239,227, + 232,235,225,227,249,242,233,236,236,233, 99,128, 4,192,238,243, + 233,239,243,235,239,242,229,225,110,128, 49,127,114, 3,146, 52, + 146, 73,147, 45, 97, 2,146, 58,146, 66,231,242,225,240,104,128, + 0,182,236,236,229,108,128, 34, 37,229,110, 2,146, 80,146,190, + 236,229,230,116,136, 0, 40,146,103,146,118,146,123,146,128,146, + 139,146,151,146,174,146,179,225,236,244,239,238,229,225,242,225, + 226,233, 99,128,253, 62,226,116,128,248,237,229,120,128,248,236, + 233,238,230,229,242,233,239,114,128, 32,141,237,239,238,239,243, + 240,225,227,101,128,255, 8,115, 2,146,157,146,164,237,225,236, + 108,128,254, 89,245,240,229,242,233,239,114,128, 32,125,244,112, + 128,248,235,246,229,242,244,233,227,225,108,128,254, 53,242,233, + 231,232,116,136, 0, 41,146,214,146,229,146,234,146,239,146,250, + 147, 6,147, 29,147, 34,225,236,244,239,238,229,225,242,225,226, + 233, 99,128,253, 63,226,116,128,248,248,229,120,128,248,247,233, + 238,230,229,242,233,239,114,128, 32,142,237,239,238,239,243,240, + 225,227,101,128,255, 9,115, 2,147, 12,147, 19,237,225,236,108, + 128,254, 90,245,240,229,242,233,239,114,128, 32,126,244,112,128, + 248,246,246,229,242,244,233,227,225,108,128,254, 54,244,233,225, + 236,228,233,230,102,128, 34, 2,115, 3,147, 64,147, 75,147, 87, + 229,241,232,229,226,242,229,119,128, 5,192,232,244,225,232,229, + 226,242,229,119,128, 5,153,241,245,225,242,101,128, 51,169,244, + 225,104,134, 5,183,147,113,147,127,147,132,147,141,147,156,147, + 172, 49, 2,147,119,147,123, 49,128, 5,183,100,128, 5,183,178, + 97,128, 5,183,232,229,226,242,229,119,128, 5,183,238,225,242, + 242,239,247,232,229,226,242,229,119,128, 5,183,241,245,225,242, + 244,229,242,232,229,226,242,229,119,128, 5,183,247,233,228,229, + 232,229,226,242,229,119,128, 5,183,250,229,242,232,229,226,242, + 229,119,128, 5,161,226,239,240,239,237,239,230,111,128, 49, 6, + 227,233,242,227,236,101,128, 36,223,228,239,244,225,227,227,229, + 238,116,128, 30, 87,101,137, 5,228,147,251,148, 6,148, 26,148, + 38,148, 58,148,160,148,171,148,192,149,147,227,249,242,233,236, + 236,233, 99,128, 4, 63,228,225,231,229,243,104,129,251, 68,148, + 17,232,229,226,242,229,119,128,251, 68,229,250,233,243,241,245, + 225,242,101,128, 51, 59,230,233,238,225,236,228,225,231,229,243, + 232,232,229,226,242,229,119,128,251, 67,104, 5,148, 70,148, 93, + 148,101,148,115,148,145,225,114, 2,148, 77,148, 84,225,226,233, + 99,128, 6,126,237,229,238,233,225,110,128, 5,122,229,226,242, + 229,119,128, 5,228,230,233,238,225,236,225,242,225,226,233, 99, + 128,251, 87,105, 2,148,121,148,136,238,233,244,233,225,236,225, + 242,225,226,233, 99,128,251, 88,242,225,231,225,238, 97,128, 48, + 122,237,229,228,233,225,236,225,242,225,226,233, 99,128,251, 89, + 235,225,244,225,235,225,238, 97,128, 48,218,237,233,228,228,236, + 229,232,239,239,235,227,249,242,233,236,236,233, 99,128, 4,167, + 114, 5,148,204,148,216,149, 2,149,123,149,136,225,230,229,232, + 229,226,242,229,119,128,251, 78,227,229,238,116,131, 0, 37,148, + 229,148,238,148,250,225,242,225,226,233, 99,128, 6,106,237,239, + 238,239,243,240,225,227,101,128,255, 5,243,237,225,236,108,128, + 254,106,105, 2,149, 8,149,105,239,100,134, 0, 46,149, 25,149, + 36,149, 47,149, 59,149, 70,149, 82,225,242,237,229,238,233,225, + 110,128, 5,137,227,229,238,244,229,242,229,100,128, 0,183,232, + 225,236,230,247,233,228,244,104,128,255, 97,233,238,230,229,242, + 233,239,114,128,246,231,237,239,238,239,243,240,225,227,101,128, + 255, 14,115, 2,149, 88,149, 95,237,225,236,108,128,254, 82,245, + 240,229,242,233,239,114,128,246,232,243,240,239,237,229,238,233, + 231,242,229,229,235,227,237, 98,128, 3, 66,240,229,238,228,233, + 227,245,236,225,114,128, 34,165,244,232,239,245,243,225,238,100, + 128, 32, 48,243,229,244, 97,128, 32,167,230,243,241,245,225,242, + 101,128, 51,138,104, 3,149,172,149,222,150,103, 97, 3,149,180, + 149,190,149,197,226,229,238,231,225,236,105,128, 9,171,228,229, + 246, 97,128, 9, 43,231,117, 2,149,204,149,213,234,225,242,225, + 244,105,128, 10,171,242,237,245,235,232,105,128, 10, 43,105,133, + 3,198,149,236,149,240,150, 70,150, 78,150, 89, 49,128, 3,213, + 229,245,240,104, 4,149,253,150, 32,150, 47,150, 56, 97, 2,150, + 3,150, 18,227,233,242,227,236,229,235,239,242,229,225,110,128, + 50,122,240,225,242,229,238,235,239,242,229,225,110,128, 50, 26, + 227,233,242,227,236,229,235,239,242,229,225,110,128, 50,108,235, + 239,242,229,225,110,128, 49, 77,240,225,242,229,238,235,239,242, + 229,225,110,128, 50, 12,236,225,244,233,110,128, 2,120,238,244, + 232,245,244,232,225,105,128, 14, 58,243,249,237,226,239,236,231, + 242,229,229,107,128, 3,213,111, 3,150,111,150,116,150,142,239, + 107,128, 1,165,240,104, 2,150,123,150,132,225,238,244,232,225, + 105,128, 14, 30,245,238,231,244,232,225,105,128, 14, 28,243,225, + 237,240,232,225,239,244,232,225,105,128, 14, 32,105,133, 3,192, + 150,170,151,126,151,137,151,148,151,162,229,245,112, 6,150,186, + 150,221,150,253,151, 25,151, 39,151, 91, 97, 2,150,192,150,207, + 227,233,242,227,236,229,235,239,242,229,225,110,128, 50,115,240, + 225,242,229,238,235,239,242,229,225,110,128, 50, 19,227,105, 2, + 150,228,150,240,229,245,227,235,239,242,229,225,110,128, 49,118, + 242,227,236,229,235,239,242,229,225,110,128, 50,101,107, 2,151, + 3,151, 17,233,249,229,239,235,235,239,242,229,225,110,128, 49, + 114,239,242,229,225,110,128, 49, 66,240,225,242,229,238,235,239, + 242,229,225,110,128, 50, 5,243,233,239,115, 2,151, 48,151, 76, + 107, 2,151, 54,151, 68,233,249,229,239,235,235,239,242,229,225, + 110,128, 49,116,239,242,229,225,110,128, 49, 68,244,233,235,229, + 245,244,235,239,242,229,225,110,128, 49,117,116, 2,151, 97,151, + 112,232,233,229,245,244,232,235,239,242,229,225,110,128, 49,119, + 233,235,229,245,244,235,239,242,229,225,110,128, 49,115,232,233, + 242,225,231,225,238, 97,128, 48,116,235,225,244,225,235,225,238, + 97,128, 48,212,243,249,237,226,239,236,231,242,229,229,107,128, + 3,214,247,242,225,242,237,229,238,233,225,110,128, 5,131,236, + 245,115,132, 0, 43,151,189,151,200,151,209,151,242,226,229,236, + 239,247,227,237, 98,128, 3, 31,227,233,242,227,236,101,128, 34, + 149,109, 2,151,215,151,222,233,238,245,115,128, 0,177,111, 2, + 151,228,151,232,100,128, 2,214,238,239,243,240,225,227,101,128, + 255, 11,115, 2,151,248,151,255,237,225,236,108,128,254, 98,245, + 240,229,242,233,239,114,128, 32,122,109, 2,152, 15,152, 26,239, + 238,239,243,240,225,227,101,128,255, 80,243,241,245,225,242,101, + 128, 51,216,111, 5,152, 47,152, 58,152,125,152,136,152,146,232, + 233,242,225,231,225,238, 97,128, 48,125,233,238,244,233,238,231, + 233,238,228,229,120, 4,152, 78,152, 90,152,102,152,115,228,239, + 247,238,247,232,233,244,101,128, 38, 31,236,229,230,244,247,232, + 233,244,101,128, 38, 28,242,233,231,232,244,247,232,233,244,101, + 128, 38, 30,245,240,247,232,233,244,101,128, 38, 29,235,225,244, + 225,235,225,238, 97,128, 48,221,240,236,225,244,232,225,105,128, + 14, 27,243,244,225,236,237,225,242,107,129, 48, 18,152,159,230, + 225,227,101,128, 48, 32,240,225,242,229,110,128, 36,171,114, 3, + 152,182,152,208,152,233,101, 2,152,188,152,196,227,229,228,229, + 115,128, 34,122,243,227,242,233,240,244,233,239,110,128, 33, 30, + 233,237,101, 2,152,216,152,222,237,239,100,128, 2,185,242,229, + 246,229,242,243,229,100,128, 32, 53,111, 4,152,243,152,250,153, + 4,153, 17,228,245,227,116,128, 34, 15,234,229,227,244,233,246, + 101,128, 35, 5,236,239,238,231,229,228,235,225,238, 97,128, 48, + 252,112, 2,153, 23,153, 60,101, 2,153, 29,153, 36,236,236,239, + 114,128, 35, 24,242,243,117, 2,153, 44,153, 51,226,243,229,116, + 128, 34,130,240,229,242,243,229,116,128, 34,131,239,242,244,233, + 239,110,129, 34, 55,153, 71,225,108,128, 34, 29,115, 2,153, 82, + 153,125,105,130, 3,200,153, 90,153,101,227,249,242,233,236,236, + 233, 99,128, 4,113,236,233,240,238,229,245,237,225,244,225,227, + 249,242,233,236,236,233,227,227,237, 98,128, 4,134,243,241,245, + 225,242,101,128, 51,176,117, 2,153,140,153,151,232,233,242,225, + 231,225,238, 97,128, 48,119,235,225,244,225,235,225,238, 97,128, + 48,215,246,243,241,245,225,242,101,128, 51,180,247,243,241,245, + 225,242,101,128, 51,186,113,136, 0,113,153,202,154,251,155, 6, + 155, 15,155, 22,155, 34,155, 72,155, 80, 97, 4,153,212,153,235, + 154, 43,154,234,100, 2,153,218,153,224,229,246, 97,128, 9, 88, + 237,225,232,229,226,242,229,119,128, 5,168,102, 4,153,245,153, + 254,154, 12,154, 28,225,242,225,226,233, 99,128, 6, 66,230,233, + 238,225,236,225,242,225,226,233, 99,128,254,214,233,238,233,244, + 233,225,236,225,242,225,226,233, 99,128,254,215,237,229,228,233, + 225,236,225,242,225,226,233, 99,128,254,216,237,225,244,115,136, + 5,184,154, 66,154, 86,154,100,154,105,154,110,154,119,154,134, + 154,221, 49, 3,154, 74,154, 78,154, 82, 48,128, 5,184, 97,128, + 5,184, 99,128, 5,184, 50, 2,154, 92,154, 96, 55,128, 5,184, + 57,128, 5,184,179, 51,128, 5,184,228,101,128, 5,184,232,229, + 226,242,229,119,128, 5,184,238,225,242,242,239,247,232,229,226, + 242,229,119,128, 5,184,113, 2,154,140,154,206,225,244,225,110, + 4,154,153,154,162,154,177,154,193,232,229,226,242,229,119,128, + 5,184,238,225,242,242,239,247,232,229,226,242,229,119,128, 5, + 184,241,245,225,242,244,229,242,232,229,226,242,229,119,128, 5, + 184,247,233,228,229,232,229,226,242,229,119,128, 5,184,245,225, + 242,244,229,242,232,229,226,242,229,119,128, 5,184,247,233,228, + 229,232,229,226,242,229,119,128, 5,184,242,238,229,249,240,225, + 242,225,232,229,226,242,229,119,128, 5,159,226,239,240,239,237, + 239,230,111,128, 49, 17,227,233,242,227,236,101,128, 36,224,232, + 239,239,107,128, 2,160,237,239,238,239,243,240,225,227,101,128, + 255, 81,239,102,130, 5,231,155, 43,155, 63,228,225,231,229,243, + 104,129,251, 71,155, 54,232,229,226,242,229,119,128,251, 71,232, + 229,226,242,229,119,128, 5,231,240,225,242,229,110,128, 36,172, + 117, 4,155, 90,155,102,155,191,156, 22,225,242,244,229,242,238, + 239,244,101,128, 38,105,226,245,244,115,135, 5,187,155,123,155, + 128,155,133,155,138,155,147,155,162,155,178,177, 56,128, 5,187, + 178, 53,128, 5,187,179, 49,128, 5,187,232,229,226,242,229,119, + 128, 5,187,238,225,242,242,239,247,232,229,226,242,229,119,128, + 5,187,241,245,225,242,244,229,242,232,229,226,242,229,119,128, + 5,187,247,233,228,229,232,229,226,242,229,119,128, 5,187,229, + 243,244,233,239,110,133, 0, 63,155,210,155,233,155,250,156, 2, + 156, 14,225,114, 2,155,217,155,224,225,226,233, 99,128, 6, 31, + 237,229,238,233,225,110,128, 5, 94,228,239,247,110,129, 0,191, + 155,242,243,237,225,236,108,128,247,191,231,242,229,229,107,128, + 3,126,237,239,238,239,243,240,225,227,101,128,255, 31,243,237, + 225,236,108,128,247, 63,239,244,101, 4,156, 34,156,105,156,125, + 156,154,228,226,108,133, 0, 34,156, 50,156, 57,156, 64,156, 76, + 156, 97,226,225,243,101,128, 32, 30,236,229,230,116,128, 32, 28, + 237,239,238,239,243,240,225,227,101,128,255, 2,240,242,233,237, + 101,129, 48, 30,156, 86,242,229,246,229,242,243,229,100,128, 48, + 29,242,233,231,232,116,128, 32, 29,236,229,230,116,129, 32, 24, + 156,114,242,229,246,229,242,243,229,100,128, 32, 27,114, 2,156, + 131,156,141,229,246,229,242,243,229,100,128, 32, 27,233,231,232, + 116,129, 32, 25,156,150,110,128, 1, 73,243,233,238,231,108, 2, + 156,164,156,171,226,225,243,101,128, 32, 26,101,129, 0, 39,156, + 177,237,239,238,239,243,240,225,227,101,128,255, 7,114,145, 0, + 114,156,227,157,231,157,242,158, 33,158, 84,159,101,159,125,159, + 220,161,254,162, 35,162, 47,162,101,162,109,163, 15,163, 26,163, + 61,163,161, 97, 11,156,251,157, 6,157, 16,157, 23,157, 88,157, + 104,157,129,157,140,157,165,157,188,157,225,225,242,237,229,238, + 233,225,110,128, 5,124,226,229,238,231,225,236,105,128, 9,176, + 227,245,244,101,128, 1, 85,100, 4,157, 33,157, 39,157, 53,157, + 79,229,246, 97,128, 9, 48,233,227,225,108,129, 34, 26,157, 48, + 229,120,128,248,229,239,246,229,242,243,243,241,245,225,242,101, + 129, 51,174,157, 69,228,243,241,245,225,242,101,128, 51,175,243, + 241,245,225,242,101,128, 51,173,230,101,129, 5,191,157, 95,232, + 229,226,242,229,119,128, 5,191,231,117, 2,157,111,157,120,234, + 225,242,225,244,105,128, 10,176,242,237,245,235,232,105,128, 10, + 48,232,233,242,225,231,225,238, 97,128, 48,137,235,225,244,225, + 235,225,238, 97,129, 48,233,157,153,232,225,236,230,247,233,228, + 244,104,128,255,151,236,239,247,229,242,228,233,225,231,239,238, + 225,236,226,229,238,231,225,236,105,128, 9,241,109, 2,157,194, + 157,217,233,228,228,236,229,228,233,225,231,239,238,225,236,226, + 229,238,231,225,236,105,128, 9,240,243,232,239,242,110,128, 2, + 100,244,233,111,128, 34, 54,226,239,240,239,237,239,230,111,128, + 49, 22, 99, 4,157,252,158, 3,158, 12,158, 20,225,242,239,110, + 128, 1, 89,229,228,233,236,236, 97,128, 1, 87,233,242,227,236, + 101,128, 36,225,239,237,237,225,225,227,227,229,238,116,128, 1, + 87,100, 2,158, 39,158, 49,226,236,231,242,225,246,101,128, 2, + 17,239,116, 2,158, 56,158, 65,225,227,227,229,238,116,128, 30, + 89,226,229,236,239,119,129, 30, 91,158, 75,237,225,227,242,239, + 110,128, 30, 93,101, 6,158, 98,158,143,158,178,158,233,159, 2, + 159, 35,102, 2,158,104,158,117,229,242,229,238,227,229,237,225, + 242,107,128, 32, 59,236,229,248,243,117, 2,158,127,158,134,226, + 243,229,116,128, 34,134,240,229,242,243,229,116,128, 34,135,231, + 233,243,244,229,114, 2,158,154,158,159,229,100,128, 0,174,115, + 2,158,165,158,171,225,238,115,128,248,232,229,242,233,102,128, + 246,218,104, 3,158,186,158,209,158,223,225,114, 2,158,193,158, + 200,225,226,233, 99,128, 6, 49,237,229,238,233,225,110,128, 5, + 128,230,233,238,225,236,225,242,225,226,233, 99,128,254,174,233, + 242,225,231,225,238, 97,128, 48,140,235,225,244,225,235,225,238, + 97,129, 48,236,158,246,232,225,236,230,247,233,228,244,104,128, + 255,154,243,104,130, 5,232,159, 11,159, 26,228,225,231,229,243, + 232,232,229,226,242,229,119,128,251, 72,232,229,226,242,229,119, + 128, 5,232,118, 3,159, 43,159, 56,159, 88,229,242,243,229,228, + 244,233,236,228,101,128, 34, 61,233, 97, 2,159, 63,159, 72,232, + 229,226,242,229,119,128, 5,151,237,245,231,242,225,243,232,232, + 229,226,242,229,119,128, 5,151,236,239,231,233,227,225,236,238, + 239,116,128, 35, 16,230,233,243,232,232,239,239,107,129, 2,126, + 159,114,242,229,246,229,242,243,229,100,128, 2,127,104, 2,159, + 131,159,154, 97, 2,159,137,159,147,226,229,238,231,225,236,105, + 128, 9,221,228,229,246, 97,128, 9, 93,111,131, 3,193,159,164, + 159,193,159,207,239,107,129, 2,125,159,171,244,245,242,238,229, + 100,129, 2,123,159,182,243,245,240,229,242,233,239,114,128, 2, + 181,243,249,237,226,239,236,231,242,229,229,107,128, 3,241,244, + 233,227,232,239,239,235,237,239,100,128, 2,222,105, 6,159,234, + 161, 22,161, 68,161, 79,161,104,161,240,229,245,108, 9,160, 0, + 160, 35,160, 50,160, 64,160,110,160,124,160,210,160,223,161, 2, + 97, 2,160, 6,160, 21,227,233,242,227,236,229,235,239,242,229, + 225,110,128, 50,113,240,225,242,229,238,235,239,242,229,225,110, + 128, 50, 17,227,233,242,227,236,229,235,239,242,229,225,110,128, + 50, 99,232,233,229,245,232,235,239,242,229,225,110,128, 49, 64, + 107, 2,160, 70,160,102,233,249,229,239,107, 2,160, 80,160, 89, + 235,239,242,229,225,110,128, 49, 58,243,233,239,243,235,239,242, + 229,225,110,128, 49,105,239,242,229,225,110,128, 49, 57,237,233, + 229,245,237,235,239,242,229,225,110,128, 49, 59,112, 3,160,132, + 160,164,160,179, 97, 2,160,138,160,152,238,243,233,239,243,235, + 239,242,229,225,110,128, 49,108,242,229,238,235,239,242,229,225, + 110,128, 50, 3,232,233,229,245,240,232,235,239,242,229,225,110, + 128, 49, 63,233,229,245,112, 2,160,188,160,197,235,239,242,229, + 225,110,128, 49, 60,243,233,239,243,235,239,242,229,225,110,128, + 49,107,243,233,239,243,235,239,242,229,225,110,128, 49, 61,116, + 2,160,229,160,244,232,233,229,245,244,232,235,239,242,229,225, + 110,128, 49, 62,233,235,229,245,244,235,239,242,229,225,110,128, + 49,106,249,229,239,242,233,238,232,233,229,245,232,235,239,242, + 229,225,110,128, 49,109,231,232,116, 2,161, 30,161, 38,225,238, + 231,236,101,128, 34, 31,116, 2,161, 44,161, 58,225,227,235,226, + 229,236,239,247,227,237, 98,128, 3, 25,242,233,225,238,231,236, + 101,128, 34,191,232,233,242,225,231,225,238, 97,128, 48,138,235, + 225,244,225,235,225,238, 97,129, 48,234,161, 92,232,225,236,230, + 247,233,228,244,104,128,255,152,110, 2,161,110,161,226,103,131, + 2,218,161,120,161,131,161,137,226,229,236,239,247,227,237, 98, + 128, 3, 37,227,237, 98,128, 3, 10,232,225,236,102, 2,161,146, + 161,192,236,229,230,116,131, 2,191,161,159,161,170,161,181,225, + 242,237,229,238,233,225,110,128, 5, 89,226,229,236,239,247,227, + 237, 98,128, 3, 28,227,229,238,244,229,242,229,100,128, 2,211, + 242,233,231,232,116,130, 2,190,161,204,161,215,226,229,236,239, + 247,227,237, 98,128, 3, 57,227,229,238,244,229,242,229,100,128, + 2,210,246,229,242,244,229,228,226,242,229,246,101,128, 2, 19, + 244,244,239,242,245,243,241,245,225,242,101,128, 51, 81,108, 2, + 162, 4,162, 15,233,238,229,226,229,236,239,119,128, 30, 95,239, + 238,231,236,229,103,129, 2,124,162, 26,244,245,242,238,229,100, + 128, 2,122,237,239,238,239,243,240,225,227,101,128,255, 82,111, + 3,162, 55,162, 66,162, 91,232,233,242,225,231,225,238, 97,128, + 48,141,235,225,244,225,235,225,238, 97,129, 48,237,162, 79,232, + 225,236,230,247,233,228,244,104,128,255,155,242,245,225,244,232, + 225,105,128, 14, 35,240,225,242,229,110,128, 36,173,114, 3,162, + 117,162,153,162,183, 97, 3,162,125,162,135,162,142,226,229,238, + 231,225,236,105,128, 9,220,228,229,246, 97,128, 9, 49,231,245, + 242,237,245,235,232,105,128, 10, 92,229,104, 2,162,160,162,169, + 225,242,225,226,233, 99,128, 6,145,230,233,238,225,236,225,242, + 225,226,233, 99,128,251,141,246,239,227,225,236,233, 99, 4,162, + 199,162,209,162,216,162,227,226,229,238,231,225,236,105,128, 9, + 224,228,229,246, 97,128, 9, 96,231,245,234,225,242,225,244,105, + 128, 10,224,246,239,247,229,236,243,233,231,110, 3,162,243,162, + 253,163, 4,226,229,238,231,225,236,105,128, 9,196,228,229,246, + 97,128, 9, 68,231,245,234,225,242,225,244,105,128, 10,196,243, + 245,240,229,242,233,239,114,128,246,241,116, 2,163, 32,163, 40, + 226,236,239,227,107,128, 37,144,245,242,238,229,100,129, 2,121, + 163, 50,243,245,240,229,242,233,239,114,128, 2,180,117, 4,163, + 71,163, 82,163,107,163,154,232,233,242,225,231,225,238, 97,128, + 48,139,235,225,244,225,235,225,238, 97,129, 48,235,163, 95,232, + 225,236,230,247,233,228,244,104,128,255,153,112, 2,163,113,163, + 148,229,101, 2,163,120,163,134,237,225,242,235,226,229,238,231, + 225,236,105,128, 9,242,243,233,231,238,226,229,238,231,225,236, + 105,128, 9,243,233,225,104,128,246,221,244,232,225,105,128, 14, + 36,246,239,227,225,236,233, 99, 4,163,177,163,187,163,194,163, + 205,226,229,238,231,225,236,105,128, 9,139,228,229,246, 97,128, + 9, 11,231,245,234,225,242,225,244,105,128, 10,139,246,239,247, + 229,236,243,233,231,110, 3,163,221,163,231,163,238,226,229,238, + 231,225,236,105,128, 9,195,228,229,246, 97,128, 9, 67,231,245, + 234,225,242,225,244,105,128, 10,195,115,147, 0,115,164, 35,166, + 5,166, 16,166,142,166,181,169,123,169,134,172, 21,174,159,174, + 205,174,232,175,167,175,234,177, 11,177, 21,177,207,178, 24,178, + 194,178,204, 97, 9,164, 55,164, 65,164, 86,164,158,164,183,164, + 194,164,219,164,251,165, 35,226,229,238,231,225,236,105,128, 9, + 184,227,245,244,101,129, 1, 91,164, 74,228,239,244,225,227,227, + 229,238,116,128, 30,101,100, 5,164, 98,164,107,164,113,164,127, + 164,143,225,242,225,226,233, 99,128, 6, 53,229,246, 97,128, 9, + 56,230,233,238,225,236,225,242,225,226,233, 99,128,254,186,233, + 238,233,244,233,225,236,225,242,225,226,233, 99,128,254,187,237, + 229,228,233,225,236,225,242,225,226,233, 99,128,254,188,231,117, + 2,164,165,164,174,234,225,242,225,244,105,128, 10,184,242,237, + 245,235,232,105,128, 10, 56,232,233,242,225,231,225,238, 97,128, + 48, 85,235,225,244,225,235,225,238, 97,129, 48,181,164,207,232, + 225,236,230,247,233,228,244,104,128,255,123,236,236,225,236,236, + 225,232,239,245,225,236,225,249,232,229,247,225,243,225,236,236, + 225,237,225,242,225,226,233, 99,128,253,250,237,229,235,104,130, + 5,225,165, 6,165, 26,228,225,231,229,243,104,129,251, 65,165, + 17,232,229,226,242,229,119,128,251, 65,232,229,226,242,229,119, + 128, 5,225,242, 97, 5,165, 48,165,122,165,130,165,180,165,188, + 97, 5,165, 60,165, 68,165, 76,165,107,165,115,225,244,232,225, + 105,128, 14, 50,229,244,232,225,105,128, 14, 65,233,237,225,233, + 109, 2,165, 86,165, 97,225,236,225,233,244,232,225,105,128, 14, + 68,245,225,238,244,232,225,105,128, 14, 67,237,244,232,225,105, + 128, 14, 51,244,232,225,105,128, 14, 48,229,244,232,225,105,128, + 14, 64,105, 3,165,138,165,162,165,173,105, 2,165,144,165,155, + 236,229,230,244,244,232,225,105,128,248,134,244,232,225,105,128, + 14, 53,236,229,230,244,244,232,225,105,128,248,133,244,232,225, + 105,128, 14, 52,239,244,232,225,105,128, 14, 66,117, 3,165,196, + 165,246,165,253,101, 3,165,204,165,228,165,239,101, 2,165,210, + 165,221,236,229,230,244,244,232,225,105,128,248,136,244,232,225, + 105,128, 14, 55,236,229,230,244,244,232,225,105,128,248,135,244, + 232,225,105,128, 14, 54,244,232,225,105,128, 14, 56,245,244,232, + 225,105,128, 14, 57,226,239,240,239,237,239,230,111,128, 49, 25, + 99, 5,166, 28,166, 49,166, 58,166,107,166,129,225,242,239,110, + 129, 1, 97,166, 37,228,239,244,225,227,227,229,238,116,128, 30, + 103,229,228,233,236,236, 97,128, 1, 95,232,247, 97,131, 2, 89, + 166, 70,166, 81,166,100,227,249,242,233,236,236,233, 99,128, 4, + 217,228,233,229,242,229,243,233,243,227,249,242,233,236,236,233, + 99,128, 4,219,232,239,239,107,128, 2, 90,233,242, 99, 2,166, + 115,166,120,236,101,128, 36,226,245,237,230,236,229,120,128, 1, + 93,239,237,237,225,225,227,227,229,238,116,128, 2, 25,228,239, + 116, 2,166,150,166,159,225,227,227,229,238,116,128, 30, 97,226, + 229,236,239,119,129, 30, 99,166,169,228,239,244,225,227,227,229, + 238,116,128, 30,105,101, 9,166,201,166,217,166,252,167, 61,167, + 164,167,191,167,216,168, 41,168, 68,225,231,245,236,236,226,229, + 236,239,247,227,237, 98,128, 3, 60, 99, 2,166,223,166,245,239, + 238,100,129, 32, 51,166,231,244,239,238,229,227,232,233,238,229, + 243,101,128, 2,202,244,233,239,110,128, 0,167,229,110, 4,167, + 7,167, 16,167, 30,167, 46,225,242,225,226,233, 99,128, 6, 51, + 230,233,238,225,236,225,242,225,226,233, 99,128,254,178,233,238, + 233,244,233,225,236,225,242,225,226,233, 99,128,254,179,237,229, + 228,233,225,236,225,242,225,226,233, 99,128,254,180,231,239,108, + 135, 5,182,167, 81,167, 95,167,100,167,109,167,124,167,140,167, + 151, 49, 2,167, 87,167, 91, 51,128, 5,182,102,128, 5,182,178, + 99,128, 5,182,232,229,226,242,229,119,128, 5,182,238,225,242, + 242,239,247,232,229,226,242,229,119,128, 5,182,241,245,225,242, + 244,229,242,232,229,226,242,229,119,128, 5,182,244,225,232,229, + 226,242,229,119,128, 5,146,247,233,228,229,232,229,226,242,229, + 119,128, 5,182,104, 2,167,170,167,181,225,242,237,229,238,233, + 225,110,128, 5,125,233,242,225,231,225,238, 97,128, 48, 91,235, + 225,244,225,235,225,238, 97,129, 48,187,167,204,232,225,236,230, + 247,233,228,244,104,128,255,126,237,105, 2,167,223,168, 10,227, + 239,236,239,110,131, 0, 59,167,237,167,246,168, 2,225,242,225, + 226,233, 99,128, 6, 27,237,239,238,239,243,240,225,227,101,128, + 255, 27,243,237,225,236,108,128,254, 84,246,239,233,227,229,228, + 237,225,242,235,235,225,238, 97,129, 48,156,168, 29,232,225,236, + 230,247,233,228,244,104,128,255,159,238,116, 2,168, 48,168, 58, + 233,243,241,245,225,242,101,128, 51, 34,239,243,241,245,225,242, + 101,128, 51, 35,246,229,110,142, 0, 55,168,102,168,111,168,121, + 168,151,168,158,168,168,168,193,168,220,168,254,169, 10,169, 21, + 169, 54,169, 62,169, 73,225,242,225,226,233, 99,128, 6,103,226, + 229,238,231,225,236,105,128, 9,237,227,233,242,227,236,101,129, + 36,102,168,132,233,238,246,229,242,243,229,243,225,238,243,243, + 229,242,233,102,128, 39,144,228,229,246, 97,128, 9,109,229,233, + 231,232,244,232,115,128, 33, 94,231,117, 2,168,175,168,184,234, + 225,242,225,244,105,128, 10,237,242,237,245,235,232,105,128, 10, + 109,232, 97, 2,168,200,168,211,227,235,225,242,225,226,233, 99, + 128, 6,103,238,231,250,232,239,117,128, 48, 39,105, 2,168,226, + 168,244,228,229,239,231,242,225,240,232,233,227,240,225,242,229, + 110,128, 50, 38,238,230,229,242,233,239,114,128, 32,135,237,239, + 238,239,243,240,225,227,101,128,255, 23,239,236,228,243,244,249, + 236,101,128,247, 55,112, 2,169, 27,169, 34,225,242,229,110,128, + 36,122,229,114, 2,169, 41,169, 47,233,239,100,128, 36,142,243, + 233,225,110,128, 6,247,242,239,237,225,110,128, 33,118,243,245, + 240,229,242,233,239,114,128, 32,119,116, 2,169, 79,169,117,229, + 229,110, 2,169, 87,169, 96,227,233,242,227,236,101,128, 36,112, + 112, 2,169,102,169,109,225,242,229,110,128, 36,132,229,242,233, + 239,100,128, 36,152,232,225,105,128, 14, 87,230,244,232,249,240, + 232,229,110,128, 0,173,104, 7,169,150,170,124,170,135,170,149, + 171, 94,171,107,172, 15, 97, 6,169,164,169,175,169,185,169,196, + 170, 83,170,108,225,242,237,229,238,233,225,110,128, 5,119,226, + 229,238,231,225,236,105,128, 9,182,227,249,242,233,236,236,233, + 99,128, 4, 72,100, 2,169,202,170, 42,228, 97, 4,169,213,169, + 222,169,253,170, 11,225,242,225,226,233, 99,128, 6, 81,228,225, + 237,237, 97, 2,169,232,169,241,225,242,225,226,233, 99,128,252, + 97,244,225,238,225,242,225,226,233, 99,128,252, 94,230,225,244, + 232,225,225,242,225,226,233, 99,128,252, 96,235,225,243,242, 97, + 2,170, 21,170, 30,225,242,225,226,233, 99,128,252, 98,244,225, + 238,225,242,225,226,233, 99,128,252, 95,101,132, 37,146,170, 54, + 170, 61,170, 69,170, 78,228,225,242,107,128, 37,147,236,233,231, + 232,116,128, 37,145,237,229,228,233,245,109,128, 37,146,246, 97, + 128, 9, 54,231,117, 2,170, 90,170, 99,234,225,242,225,244,105, + 128, 10,182,242,237,245,235,232,105,128, 10, 54,236,243,232,229, + 236,229,244,232,229,226,242,229,119,128, 5,147,226,239,240,239, + 237,239,230,111,128, 49, 21,227,232,225,227,249,242,233,236,236, + 233, 99,128, 4, 73,101, 4,170,159,170,224,170,234,170,251,229, + 110, 4,170,170,170,179,170,193,170,209,225,242,225,226,233, 99, + 128, 6, 52,230,233,238,225,236,225,242,225,226,233, 99,128,254, + 182,233,238,233,244,233,225,236,225,242,225,226,233, 99,128,254, + 183,237,229,228,233,225,236,225,242,225,226,233, 99,128,254,184, + 233,227,239,240,244,233, 99,128, 3,227,241,229,108,129, 32,170, + 170,242,232,229,226,242,229,119,128, 32,170,246, 97,134, 5,176, + 171, 12,171, 27,171, 41,171, 50,171, 65,171, 81, 49, 2,171, 18, + 171, 23,177, 53,128, 5,176, 53,128, 5,176, 50, 2,171, 33,171, + 37, 50,128, 5,176,101,128, 5,176,232,229,226,242,229,119,128, + 5,176,238,225,242,242,239,247,232,229,226,242,229,119,128, 5, + 176,241,245,225,242,244,229,242,232,229,226,242,229,119,128, 5, + 176,247,233,228,229,232,229,226,242,229,119,128, 5,176,232,225, + 227,249,242,233,236,236,233, 99,128, 4,187,105, 2,171,113,171, + 124,237,225,227,239,240,244,233, 99,128, 3,237,110,131, 5,233, + 171,134,171,217,171,226,100, 2,171,140,171,206,225,231,229,243, + 104,130,251, 73,171,152,171,161,232,229,226,242,229,119,128,251, + 73,115, 2,171,167,171,187,232,233,238,228,239,116,129,251, 44, + 171,178,232,229,226,242,229,119,128,251, 44,233,238,228,239,116, + 129,251, 45,171,197,232,229,226,242,229,119,128,251, 45,239,244, + 232,229,226,242,229,119,128, 5,193,232,229,226,242,229,119,128, + 5,233,115, 2,171,232,171,252,232,233,238,228,239,116,129,251, + 42,171,243,232,229,226,242,229,119,128,251, 42,233,238,228,239, + 116,129,251, 43,172, 6,232,229,226,242,229,119,128,251, 43,239, + 239,107,128, 2,130,105, 8,172, 39,172, 83,172, 94,172,119,172, + 149,172,157,172,170,173, 85,231,237, 97,131, 3,195,172, 51,172, + 55,172, 63, 49,128, 3,194,230,233,238,225,108,128, 3,194,236, + 245,238,225,244,229,243,249,237,226,239,236,231,242,229,229,107, + 128, 3,242,232,233,242,225,231,225,238, 97,128, 48, 87,235,225, + 244,225,235,225,238, 97,129, 48,183,172,107,232,225,236,230,247, + 233,228,244,104,128,255,124,236,245,113, 2,172,127,172,136,232, + 229,226,242,229,119,128, 5,189,236,229,230,244,232,229,226,242, + 229,119,128, 5,189,237,233,236,225,114,128, 34, 60,238,228,239, + 244,232,229,226,242,229,119,128, 5,194,239,115, 6,172,185,172, + 220,172,252,173, 24,173, 38,173, 70, 97, 2,172,191,172,206,227, + 233,242,227,236,229,235,239,242,229,225,110,128, 50,116,240,225, + 242,229,238,235,239,242,229,225,110,128, 50, 20,227,105, 2,172, + 227,172,239,229,245,227,235,239,242,229,225,110,128, 49,126,242, + 227,236,229,235,239,242,229,225,110,128, 50,102,107, 2,173, 2, + 173, 16,233,249,229,239,235,235,239,242,229,225,110,128, 49,122, + 239,242,229,225,110,128, 49, 69,238,233,229,245,238,235,239,242, + 229,225,110,128, 49,123,112, 2,173, 44,173, 57,225,242,229,238, + 235,239,242,229,225,110,128, 50, 6,233,229,245,240,235,239,242, + 229,225,110,128, 49,125,244,233,235,229,245,244,235,239,242,229, + 225,110,128, 49,124,120,141, 0, 54,173,115,173,124,173,134,173, + 164,173,171,173,196,173,223,174, 1,174, 13,174, 24,174, 57,174, + 65,174, 76,225,242,225,226,233, 99,128, 6,102,226,229,238,231, + 225,236,105,128, 9,236,227,233,242,227,236,101,129, 36,101,173, + 145,233,238,246,229,242,243,229,243,225,238,243,243,229,242,233, + 102,128, 39,143,228,229,246, 97,128, 9,108,231,117, 2,173,178, + 173,187,234,225,242,225,244,105,128, 10,236,242,237,245,235,232, + 105,128, 10,108,232, 97, 2,173,203,173,214,227,235,225,242,225, + 226,233, 99,128, 6,102,238,231,250,232,239,117,128, 48, 38,105, + 2,173,229,173,247,228,229,239,231,242,225,240,232,233,227,240, + 225,242,229,110,128, 50, 37,238,230,229,242,233,239,114,128, 32, + 134,237,239,238,239,243,240,225,227,101,128,255, 22,239,236,228, + 243,244,249,236,101,128,247, 54,112, 2,174, 30,174, 37,225,242, + 229,110,128, 36,121,229,114, 2,174, 44,174, 50,233,239,100,128, + 36,141,243,233,225,110,128, 6,246,242,239,237,225,110,128, 33, + 117,243,245,240,229,242,233,239,114,128, 32,118,116, 2,174, 82, + 174,153,229,229,110, 2,174, 90,174,132, 99, 2,174, 96,174,104, + 233,242,227,236,101,128, 36,111,245,242,242,229,238,227,249,228, + 229,238,239,237,233,238,225,244,239,242,226,229,238,231,225,236, + 105,128, 9,249,112, 2,174,138,174,145,225,242,229,110,128, 36, + 131,229,242,233,239,100,128, 36,151,232,225,105,128, 14, 86,108, + 2,174,165,174,185,225,243,104,129, 0, 47,174,173,237,239,238, + 239,243,240,225,227,101,128,255, 15,239,238,103,129, 1,127,174, + 193,228,239,244,225,227,227,229,238,116,128, 30,155,109, 2,174, + 211,174,221,233,236,229,230,225,227,101,128, 38, 58,239,238,239, + 243,240,225,227,101,128,255, 83,111, 6,174,246,175, 40,175, 51, + 175, 76,175,121,175,132,102, 2,174,252,175, 10,240,225,243,245, + 241,232,229,226,242,229,119,128, 5,195,116, 2,175, 16,175, 25, + 232,249,240,232,229,110,128, 0,173,243,233,231,238,227,249,242, + 233,236,236,233, 99,128, 4, 76,232,233,242,225,231,225,238, 97, + 128, 48, 93,235,225,244,225,235,225,238, 97,129, 48,189,175, 64, + 232,225,236,230,247,233,228,244,104,128,255,127,236,233,228,245, + 115, 2,175, 86,175,103,236,239,238,231,239,246,229,242,236,225, + 249,227,237, 98,128, 3, 56,243,232,239,242,244,239,246,229,242, + 236,225,249,227,237, 98,128, 3, 55,242,245,243,233,244,232,225, + 105,128, 14, 41,115, 3,175,140,175,150,175,158,225,236,225,244, + 232,225,105,128, 14, 40,239,244,232,225,105,128, 14, 11,245,225, + 244,232,225,105,128, 14, 42,240, 97, 3,175,176,175,196,175,228, + 227,101,129, 0, 32,175,183,232,225,227,235,225,242,225,226,233, + 99,128, 0, 32,228,101,129, 38, 96,175,203,243,245,233,116, 2, + 175,212,175,220,226,236,225,227,107,128, 38, 96,247,232,233,244, + 101,128, 38,100,242,229,110,128, 36,174,241,245,225,242,101, 11, + 176, 6,176, 17,176, 31,176, 56,176, 73,176, 99,176,114,176,147, + 176,174,176,230,176,245,226,229,236,239,247,227,237, 98,128, 3, + 59, 99, 2,176, 23,176, 27, 99,128, 51,196,109,128, 51,157,228, + 233,225,231,239,238,225,236,227,242,239,243,243,232,225,244,227, + 232,230,233,236,108,128, 37,169,232,239,242,233,250,239,238,244, + 225,236,230,233,236,108,128, 37,164,107, 2,176, 79,176, 83,103, + 128, 51,143,109,129, 51,158,176, 89,227,225,240,233,244,225,108, + 128, 51,206,108, 2,176,105,176,109,110,128, 51,209,239,103,128, + 51,210,109, 4,176,124,176,128,176,133,176,137,103,128, 51,142, + 233,108,128, 51,213,109,128, 51,156,243,241,245,225,242,229,100, + 128, 51,161,239,242,244,232,239,231,239,238,225,236,227,242,239, + 243,243,232,225,244,227,232,230,233,236,108,128, 37,166,245,240, + 240,229,114, 2,176,184,176,207,236,229,230,244,244,239,236,239, + 247,229,242,242,233,231,232,244,230,233,236,108,128, 37,167,242, + 233,231,232,244,244,239,236,239,247,229,242,236,229,230,244,230, + 233,236,108,128, 37,168,246,229,242,244,233,227,225,236,230,233, + 236,108,128, 37,165,247,232,233,244,229,247,233,244,232,243,237, + 225,236,236,226,236,225,227,107,128, 37,163,242,243,241,245,225, + 242,101,128, 51,219,115, 2,177, 27,177,197, 97, 4,177, 37,177, + 47,177, 54,177, 65,226,229,238,231,225,236,105,128, 9,183,228, + 229,246, 97,128, 9, 55,231,245,234,225,242,225,244,105,128, 10, + 183,238,103, 8,177, 84,177, 98,177,112,177,126,177,141,177,155, + 177,169,177,182,227,233,229,245,227,235,239,242,229,225,110,128, + 49, 73,232,233,229,245,232,235,239,242,229,225,110,128, 49,133, + 233,229,245,238,231,235,239,242,229,225,110,128, 49,128,235,233, + 249,229,239,235,235,239,242,229,225,110,128, 49, 50,238,233,229, + 245,238,235,239,242,229,225,110,128, 49,101,240,233,229,245,240, + 235,239,242,229,225,110,128, 49, 67,243,233,239,243,235,239,242, + 229,225,110,128, 49, 70,244,233,235,229,245,244,235,239,242,229, + 225,110,128, 49, 56,245,240,229,242,233,239,114,128,246,242,116, + 2,177,213,177,236,229,242,236,233,238,103,129, 0,163,177,224, + 237,239,238,239,243,240,225,227,101,128,255,225,242,239,235,101, + 2,177,245,178, 6,236,239,238,231,239,246,229,242,236,225,249, + 227,237, 98,128, 3, 54,243,232,239,242,244,239,246,229,242,236, + 225,249,227,237, 98,128, 3, 53,117, 7,178, 40,178, 72,178, 94, + 178,105,178,146,178,156,178,160,226,243,229,116,130, 34,130,178, + 51,178, 62,238,239,244,229,241,245,225,108,128, 34,138,239,242, + 229,241,245,225,108,128, 34,134, 99, 2,178, 78,178, 86,227,229, + 229,228,115,128, 34,123,232,244,232,225,116,128, 34, 11,232,233, + 242,225,231,225,238, 97,128, 48, 89,107, 2,178,111,178,135,225, + 244,225,235,225,238, 97,129, 48,185,178,123,232,225,236,230,247, + 233,228,244,104,128,255,125,245,238,225,242,225,226,233, 99,128, + 6, 82,237,237,225,244,233,239,110,128, 34, 17,110,128, 38, 60, + 240,229,242,243,229,116,130, 34,131,178,173,178,184,238,239,244, + 229,241,245,225,108,128, 34,139,239,242,229,241,245,225,108,128, + 34,135,246,243,241,245,225,242,101,128, 51,220,249,239,245,247, + 225,229,242,225,243,241,245,225,242,101,128, 51,124,116,144, 0, + 116,179, 1,180, 10,180, 31,180,174,180,214,183, 6,186,144,187, + 219,187,231,187,243,189, 20,189, 45,189,131,190, 55,190,239,191, + 73, 97, 10,179, 23,179, 33,179, 54,179, 61,179, 86,179,164,179, + 181,179,206,179,220,179,224,226,229,238,231,225,236,105,128, 9, + 164,227,107, 2,179, 40,179, 47,228,239,247,110,128, 34,164,236, + 229,230,116,128, 34,163,228,229,246, 97,128, 9, 36,231,117, 2, + 179, 68,179, 77,234,225,242,225,244,105,128, 10,164,242,237,245, + 235,232,105,128, 10, 36,104, 4,179, 96,179,105,179,119,179,149, + 225,242,225,226,233, 99,128, 6, 55,230,233,238,225,236,225,242, + 225,226,233, 99,128,254,194,105, 2,179,125,179,140,238,233,244, + 233,225,236,225,242,225,226,233, 99,128,254,195,242,225,231,225, + 238, 97,128, 48, 95,237,229,228,233,225,236,225,242,225,226,233, + 99,128,254,196,233,243,249,239,245,229,242,225,243,241,245,225, + 242,101,128, 51,125,235,225,244,225,235,225,238, 97,129, 48,191, + 179,194,232,225,236,230,247,233,228,244,104,128,255,128,244,247, + 229,229,236,225,242,225,226,233, 99,128, 6, 64,117,128, 3,196, + 118,130, 5,234,179,232,180, 1,228,225,231,229,115,129,251, 74, + 179,242,104,129,251, 74,179,248,232,229,226,242,229,119,128,251, + 74,232,229,226,242,229,119,128, 5,234, 98, 2,180, 16,180, 21, + 225,114,128, 1,103,239,240,239,237,239,230,111,128, 49, 10, 99, + 6,180, 45,180, 52,180, 59,180, 68,180,134,180,161,225,242,239, + 110,128, 1,101,227,245,242,108,128, 2,168,229,228,233,236,236, + 97,128, 1, 99,232,229,104, 4,180, 80,180, 89,180,103,180,119, + 225,242,225,226,233, 99,128, 6,134,230,233,238,225,236,225,242, + 225,226,233, 99,128,251,123,233,238,233,244,233,225,236,225,242, + 225,226,233, 99,128,251,124,237,229,228,233,225,236,225,242,225, + 226,233, 99,128,251,125,233,242, 99, 2,180,142,180,147,236,101, + 128, 36,227,245,237,230,236,229,248,226,229,236,239,119,128, 30, + 113,239,237,237,225,225,227,227,229,238,116,128, 1, 99,100, 2, + 180,180,180,190,233,229,242,229,243,233,115,128, 30,151,239,116, + 2,180,197,180,206,225,227,227,229,238,116,128, 30,107,226,229, + 236,239,119,128, 30,109,101, 9,180,234,180,245,181, 9,182, 19, + 182, 44,182,108,182,175,182,180,182,232,227,249,242,233,236,236, + 233, 99,128, 4, 66,228,229,243,227,229,238,228,229,242,227,249, + 242,233,236,236,233, 99,128, 4,173,104, 7,181, 25,181, 34,181, + 48,181, 88,181,118,181,159,182, 1,225,242,225,226,233, 99,128, + 6, 42,230,233,238,225,236,225,242,225,226,233, 99,128,254,150, + 232,225,232,105, 2,181, 57,181, 72,238,233,244,233,225,236,225, + 242,225,226,233, 99,128,252,162,243,239,236,225,244,229,228,225, + 242,225,226,233, 99,128,252, 12,105, 2,181, 94,181,109,238,233, + 244,233,225,236,225,242,225,226,233, 99,128,254,151,242,225,231, + 225,238, 97,128, 48,102,234,229,229,237,105, 2,181,128,181,143, + 238,233,244,233,225,236,225,242,225,226,233, 99,128,252,161,243, + 239,236,225,244,229,228,225,242,225,226,233, 99,128,252, 11,109, + 2,181,165,181,199,225,242,226,245,244, 97, 2,181,176,181,185, + 225,242,225,226,233, 99,128, 6, 41,230,233,238,225,236,225,242, + 225,226,233, 99,128,254,148,101, 2,181,205,181,218,228,233,225, + 236,225,242,225,226,233, 99,128,254,152,229,237,105, 2,181,226, + 181,241,238,233,244,233,225,236,225,242,225,226,233, 99,128,252, + 164,243,239,236,225,244,229,228,225,242,225,226,233, 99,128,252, + 14,238,239,239,238,230,233,238,225,236,225,242,225,226,233, 99, + 128,252,115,235,225,244,225,235,225,238, 97,129, 48,198,182, 32, + 232,225,236,230,247,233,228,244,104,128,255,131,108, 2,182, 50, + 182, 69,229,240,232,239,238,101,129, 33, 33,182, 61,226,236,225, + 227,107,128, 38, 14,233,243,232, 97, 2,182, 78,182, 93,231,229, + 228,239,236,225,232,229,226,242,229,119,128, 5,160,241,229,244, + 225,238,225,232,229,226,242,229,119,128, 5,169,110, 4,182,118, + 182,127,182,146,182,167,227,233,242,227,236,101,128, 36,105,233, + 228,229,239,231,242,225,240,232,233,227,240,225,242,229,110,128, + 50, 41,112, 2,182,152,182,159,225,242,229,110,128, 36,125,229, + 242,233,239,100,128, 36,145,242,239,237,225,110,128, 33,121,243, + 104,128, 2,167,116,131, 5,216,182,190,182,210,182,219,228,225, + 231,229,243,104,129,251, 56,182,201,232,229,226,242,229,119,128, + 251, 56,232,229,226,242,229,119,128, 5,216,243,229,227,249,242, + 233,236,236,233, 99,128, 4,181,246,233,114, 2,182,240,182,249, + 232,229,226,242,229,119,128, 5,155,236,229,230,244,232,229,226, + 242,229,119,128, 5,155,104, 6,183, 20,183,172,184, 38,184,170, + 185, 77,186,134, 97, 5,183, 32,183, 42,183, 49,183, 74,183,103, + 226,229,238,231,225,236,105,128, 9,165,228,229,246, 97,128, 9, + 37,231,117, 2,183, 56,183, 65,234,225,242,225,244,105,128, 10, + 165,242,237,245,235,232,105,128, 10, 37,108, 2,183, 80,183, 89, + 225,242,225,226,233, 99,128, 6, 48,230,233,238,225,236,225,242, + 225,226,233, 99,128,254,172,238,244,232,225,235,232,225,116, 3, + 183,118,183,149,183,156,236,239,119, 2,183,126,183,137,236,229, + 230,244,244,232,225,105,128,248,152,242,233,231,232,244,244,232, + 225,105,128,248,151,244,232,225,105,128, 14, 76,245,240,240,229, + 242,236,229,230,244,244,232,225,105,128,248,150,101, 3,183,180, + 183,244,184, 11,104, 4,183,190,183,199,183,213,183,229,225,242, + 225,226,233, 99,128, 6, 43,230,233,238,225,236,225,242,225,226, + 233, 99,128,254,154,233,238,233,244,233,225,236,225,242,225,226, + 233, 99,128,254,155,237,229,228,233,225,236,225,242,225,226,233, + 99,128,254,156,242,101, 2,183,251,184, 4,229,248,233,243,244, + 115,128, 34, 3,230,239,242,101,128, 34, 52,244, 97,130, 3,184, + 184, 20,184, 24, 49,128, 3,209,243,249,237,226,239,236,231,242, + 229,229,107,128, 3,209,105, 2,184, 44,184,130,229,245,244,104, + 4,184, 57,184, 92,184,107,184,116, 97, 2,184, 63,184, 78,227, + 233,242,227,236,229,235,239,242,229,225,110,128, 50,121,240,225, + 242,229,238,235,239,242,229,225,110,128, 50, 25,227,233,242,227, + 236,229,235,239,242,229,225,110,128, 50,107,235,239,242,229,225, + 110,128, 49, 76,240,225,242,229,238,235,239,242,229,225,110,128, + 50, 11,242,244,229,229,110, 2,184,140,184,149,227,233,242,227, + 236,101,128, 36,108,112, 2,184,155,184,162,225,242,229,110,128, + 36,128,229,242,233,239,100,128, 36,148,111, 6,184,184,184,201, + 184,206,184,220,184,225,185, 22,238,225,238,231,237,239,238,244, + 232,239,244,232,225,105,128, 14, 17,239,107,128, 1,173,240,232, + 245,244,232,225,239,244,232,225,105,128, 14, 18,242,110,128, 0, + 254,244,104, 3,184,234,185, 2,185, 12, 97, 2,184,240,184,250, + 232,225,238,244,232,225,105,128, 14, 23,238,244,232,225,105,128, + 14, 16,239,238,231,244,232,225,105,128, 14, 24,245,238,231,244, + 232,225,105,128, 14, 22,245,243,225,238,100, 2,185, 32,185, 43, + 227,249,242,233,236,236,233, 99,128, 4,130,243,243,229,240,225, + 242,225,244,239,114, 2,185, 58,185, 67,225,242,225,226,233, 99, + 128, 6,108,240,229,242,243,233,225,110,128, 6,108,242,229,101, + 144, 0, 51,185,115,185,124,185,134,185,164,185,171,185,181,185, + 206,185,233,186, 11,186, 23,186, 42,186, 53,186, 86,186,108,186, + 116,186,127,225,242,225,226,233, 99,128, 6, 99,226,229,238,231, + 225,236,105,128, 9,233,227,233,242,227,236,101,129, 36, 98,185, + 145,233,238,246,229,242,243,229,243,225,238,243,243,229,242,233, + 102,128, 39,140,228,229,246, 97,128, 9,105,229,233,231,232,244, + 232,115,128, 33, 92,231,117, 2,185,188,185,197,234,225,242,225, + 244,105,128, 10,233,242,237,245,235,232,105,128, 10,105,232, 97, + 2,185,213,185,224,227,235,225,242,225,226,233, 99,128, 6, 99, + 238,231,250,232,239,117,128, 48, 35,105, 2,185,239,186, 1,228, + 229,239,231,242,225,240,232,233,227,240,225,242,229,110,128, 50, + 34,238,230,229,242,233,239,114,128, 32,131,237,239,238,239,243, + 240,225,227,101,128,255, 19,238,245,237,229,242,225,244,239,242, + 226,229,238,231,225,236,105,128, 9,246,239,236,228,243,244,249, + 236,101,128,247, 51,112, 2,186, 59,186, 66,225,242,229,110,128, + 36,118,229,114, 2,186, 73,186, 79,233,239,100,128, 36,138,243, + 233,225,110,128, 6,243,241,245,225,242,244,229,242,115,129, 0, + 190,186, 99,229,237,228,225,243,104,128,246,222,242,239,237,225, + 110,128, 33,114,243,245,240,229,242,233,239,114,128, 0,179,244, + 232,225,105,128, 14, 83,250,243,241,245,225,242,101,128, 51,148, + 105, 7,186,160,186,171,187, 30,187,128,187,140,187,189,187,206, + 232,233,242,225,231,225,238, 97,128, 48, 97,107, 2,186,177,186, + 201,225,244,225,235,225,238, 97,129, 48,193,186,189,232,225,236, + 230,247,233,228,244,104,128,255,129,229,245,116, 4,186,213,186, + 248,187, 7,187, 16, 97, 2,186,219,186,234,227,233,242,227,236, + 229,235,239,242,229,225,110,128, 50,112,240,225,242,229,238,235, + 239,242,229,225,110,128, 50, 16,227,233,242,227,236,229,235,239, + 242,229,225,110,128, 50, 98,235,239,242,229,225,110,128, 49, 55, + 240,225,242,229,238,235,239,242,229,225,110,128, 50, 2,236,228, + 101,133, 2,220,187, 46,187, 57,187, 74,187, 86,187,114,226,229, + 236,239,247,227,237, 98,128, 3, 48, 99, 2,187, 63,187, 68,237, + 98,128, 3, 3,239,237, 98,128, 3, 3,228,239,245,226,236,229, + 227,237, 98,128, 3, 96,111, 2,187, 92,187,102,240,229,242,225, + 244,239,114,128, 34, 60,246,229,242,236,225,249,227,237, 98,128, + 3, 52,246,229,242,244,233,227,225,236,227,237, 98,128, 3, 62, + 237,229,243,227,233,242,227,236,101,128, 34,151,112, 2,187,146, + 187,176,229,232, 97, 2,187,154,187,163,232,229,226,242,229,119, + 128, 5,150,236,229,230,244,232,229,226,242,229,119,128, 5,150, + 240,233,231,245,242,237,245,235,232,105,128, 10,112,244,236,239, + 227,249,242,233,236,236,233,227,227,237, 98,128, 4,131,247,238, + 225,242,237,229,238,233,225,110,128, 5,127,236,233,238,229,226, + 229,236,239,119,128, 30,111,237,239,238,239,243,240,225,227,101, + 128,255, 84,111, 7,188, 3,188, 14,188, 25,188, 50,188,170,188, + 182,189, 10,225,242,237,229,238,233,225,110,128, 5,105,232,233, + 242,225,231,225,238, 97,128, 48,104,235,225,244,225,235,225,238, + 97,129, 48,200,188, 38,232,225,236,230,247,233,228,244,104,128, + 255,132,110, 3,188, 58,188,156,188,161,101, 4,188, 68,188,137, + 188,144,188,150,226,225,114, 4,188, 80,188,109,188,119,188,128, + 229,248,244,242, 97, 2,188, 90,188,100,232,233,231,232,237,239, + 100,128, 2,229,236,239,247,237,239,100,128, 2,233,232,233,231, + 232,237,239,100,128, 2,230,236,239,247,237,239,100,128, 2,232, + 237,233,228,237,239,100,128, 2,231,230,233,246,101,128, 1,189, + 243,233,120,128, 1,133,244,247,111,128, 1,168,239,115,128, 3, + 132,243,241,245,225,242,101,128, 51, 39,240,225,244,225,235,244, + 232,225,105,128, 14, 15,242,244,239,233,243,229,243,232,229,236, + 236,226,242,225,227,235,229,116, 2,188,205,188,235,236,229,230, + 116,130, 48, 20,188,216,188,224,243,237,225,236,108,128,254, 93, + 246,229,242,244,233,227,225,108,128,254, 57,242,233,231,232,116, + 130, 48, 21,188,247,188,255,243,237,225,236,108,128,254, 94,246, + 229,242,244,233,227,225,108,128,254, 58,244,225,239,244,232,225, + 105,128, 14, 21,240, 97, 2,189, 27,189, 39,236,225,244,225,236, + 232,239,239,107,128, 1,171,242,229,110,128, 36,175,114, 3,189, + 53,189, 84,189, 99,225,228,229,237,225,242,107,129, 33, 34,189, + 65,115, 2,189, 71,189, 77,225,238,115,128,248,234,229,242,233, + 102,128,246,219,229,244,242,239,230,236,229,248,232,239,239,107, + 128, 2,136,233,225,103, 4,189,111,189,116,189,121,189,126,228, + 110,128, 37,188,236,102,128, 37,196,242,116,128, 37,186,245,112, + 128, 37,178,115,132, 2,166,189,143,189,182,190, 32,190, 45,225, + 228,105,130, 5,230,189,153,189,173,228,225,231,229,243,104,129, + 251, 70,189,164,232,229,226,242,229,119,128,251, 70,232,229,226, + 242,229,119,128, 5,230,101, 2,189,188,189,199,227,249,242,233, + 236,236,233, 99,128, 4, 70,242,101,134, 5,181,189,216,189,230, + 189,235,189,244,190, 3,190, 19, 49, 2,189,222,189,226, 50,128, + 5,181,101,128, 5,181,178, 98,128, 5,181,232,229,226,242,229, + 119,128, 5,181,238,225,242,242,239,247,232,229,226,242,229,119, + 128, 5,181,241,245,225,242,244,229,242,232,229,226,242,229,119, + 128, 5,181,247,233,228,229,232,229,226,242,229,119,128, 5,181, + 232,229,227,249,242,233,236,236,233, 99,128, 4, 91,245,240,229, + 242,233,239,114,128,246,243,116, 4,190, 65,190,115,190,180,190, + 231, 97, 3,190, 73,190, 83,190, 90,226,229,238,231,225,236,105, + 128, 9,159,228,229,246, 97,128, 9, 31,231,117, 2,190, 97,190, + 106,234,225,242,225,244,105,128, 10,159,242,237,245,235,232,105, + 128, 10, 31,229,104, 4,190,126,190,135,190,149,190,165,225,242, + 225,226,233, 99,128, 6,121,230,233,238,225,236,225,242,225,226, + 233, 99,128,251,103,233,238,233,244,233,225,236,225,242,225,226, + 233, 99,128,251,104,237,229,228,233,225,236,225,242,225,226,233, + 99,128,251,105,232, 97, 3,190,189,190,199,190,206,226,229,238, + 231,225,236,105,128, 9,160,228,229,246, 97,128, 9, 32,231,117, + 2,190,213,190,222,234,225,242,225,244,105,128, 10,160,242,237, + 245,235,232,105,128, 10, 32,245,242,238,229,100,128, 2,135,117, + 3,190,247,191, 2,191, 27,232,233,242,225,231,225,238, 97,128, + 48,100,235,225,244,225,235,225,238, 97,129, 48,196,191, 15,232, + 225,236,230,247,233,228,244,104,128,255,130,243,237,225,236,108, + 2,191, 37,191, 48,232,233,242,225,231,225,238, 97,128, 48, 99, + 235,225,244,225,235,225,238, 97,129, 48,195,191, 61,232,225,236, + 230,247,233,228,244,104,128,255,111,119, 2,191, 79,191,184,101, + 2,191, 85,191,133,236,246,101, 3,191, 95,191,104,191,125,227, + 233,242,227,236,101,128, 36,107,112, 2,191,110,191,117,225,242, + 229,110,128, 36,127,229,242,233,239,100,128, 36,147,242,239,237, + 225,110,128, 33,123,238,244,121, 3,191,143,191,152,191,163,227, + 233,242,227,236,101,128, 36,115,232,225,238,231,250,232,239,117, + 128, 83, 68,112, 2,191,169,191,176,225,242,229,110,128, 36,135, + 229,242,233,239,100,128, 36,155,111,142, 0, 50,191,216,191,225, + 191,235,192, 9,192, 61,192, 86,192,113,192,147,192,159,192,178, + 192,189,192,222,192,230,192,254,225,242,225,226,233, 99,128, 6, + 98,226,229,238,231,225,236,105,128, 9,232,227,233,242,227,236, + 101,129, 36, 97,191,246,233,238,246,229,242,243,229,243,225,238, + 243,243,229,242,233,102,128, 39,139,100, 2,192, 15,192, 21,229, + 246, 97,128, 9,104,239,116, 2,192, 28,192, 39,229,238,236,229, + 225,228,229,114,128, 32, 37,236,229,225,228,229,114,129, 32, 37, + 192, 50,246,229,242,244,233,227,225,108,128,254, 48,231,117, 2, + 192, 68,192, 77,234,225,242,225,244,105,128, 10,232,242,237,245, + 235,232,105,128, 10,104,232, 97, 2,192, 93,192,104,227,235,225, + 242,225,226,233, 99,128, 6, 98,238,231,250,232,239,117,128, 48, + 34,105, 2,192,119,192,137,228,229,239,231,242,225,240,232,233, + 227,240,225,242,229,110,128, 50, 33,238,230,229,242,233,239,114, + 128, 32,130,237,239,238,239,243,240,225,227,101,128,255, 18,238, + 245,237,229,242,225,244,239,242,226,229,238,231,225,236,105,128, + 9,245,239,236,228,243,244,249,236,101,128,247, 50,112, 2,192, + 195,192,202,225,242,229,110,128, 36,117,229,114, 2,192,209,192, + 215,233,239,100,128, 36,137,243,233,225,110,128, 6,242,242,239, + 237,225,110,128, 33,113,115, 2,192,236,192,244,244,242,239,235, + 101,128, 1,187,245,240,229,242,233,239,114,128, 0,178,244,104, + 2,193, 5,193, 10,225,105,128, 14, 82,233,242,228,115,128, 33, + 84,117,145, 0,117,193, 55,193, 63,193,104,193,161,194, 43,194, + 80,194,203,194,219,195, 14,195, 84,195,165,195,174,196, 37,196, + 61,196,169,196,197,197, 55,225,227,245,244,101,128, 0,250, 98, + 4,193, 73,193, 78,193, 87,193, 97,225,114,128, 2,137,229,238, + 231,225,236,105,128, 9,137,239,240,239,237,239,230,111,128, 49, + 40,242,229,246,101,128, 1,109, 99, 3,193,112,193,119,193,151, + 225,242,239,110,128, 1,212,233,242, 99, 2,193,127,193,132,236, + 101,128, 36,228,245,237,230,236,229,120,129, 0,251,193,143,226, + 229,236,239,119,128, 30,119,249,242,233,236,236,233, 99,128, 4, + 67,100, 5,193,173,193,184,193,207,193,213,194, 33,225,244,244, + 225,228,229,246, 97,128, 9, 81,226,108, 2,193,191,193,199,225, + 227,245,244,101,128, 1,113,231,242,225,246,101,128, 2, 21,229, + 246, 97,128, 9, 9,233,229,242,229,243,233,115,133, 0,252,193, + 233,193,241,193,249,194, 16,194, 24,225,227,245,244,101,128, 1, + 216,226,229,236,239,119,128, 30,115, 99, 2,193,255,194, 6,225, + 242,239,110,128, 1,218,249,242,233,236,236,233, 99,128, 4,241, + 231,242,225,246,101,128, 1,220,237,225,227,242,239,110,128, 1, + 214,239,244,226,229,236,239,119,128, 30,229,103, 2,194, 49,194, + 56,242,225,246,101,128, 0,249,117, 2,194, 62,194, 71,234,225, + 242,225,244,105,128, 10,137,242,237,245,235,232,105,128, 10, 9, + 104, 3,194, 88,194, 98,194,176,233,242,225,231,225,238, 97,128, + 48, 70,111, 2,194,104,194,114,239,235,225,226,239,246,101,128, + 30,231,242,110,133, 1,176,194,129,194,137,194,148,194,156,194, + 168,225,227,245,244,101,128, 30,233,228,239,244,226,229,236,239, + 119,128, 30,241,231,242,225,246,101,128, 30,235,232,239,239,235, + 225,226,239,246,101,128, 30,237,244,233,236,228,101,128, 30,239, + 245,238,231,225,242,245,237,236,225,245,116,129, 1,113,194,192, + 227,249,242,233,236,236,233, 99,128, 4,243,233,238,246,229,242, + 244,229,228,226,242,229,246,101,128, 2, 23,107, 3,194,227,194, + 251,195, 6,225,244,225,235,225,238, 97,129, 48,166,194,239,232, + 225,236,230,247,233,228,244,104,128,255,115,227,249,242,233,236, + 236,233, 99,128, 4,121,239,242,229,225,110,128, 49, 92,109, 2, + 195, 20,195, 73, 97, 2,195, 26,195, 59,227,242,239,110,130, 1, + 107,195, 37,195, 48,227,249,242,233,236,236,233, 99,128, 4,239, + 228,233,229,242,229,243,233,115,128, 30,123,244,242,225,231,245, + 242,237,245,235,232,105,128, 10, 65,239,238,239,243,240,225,227, + 101,128,255, 85,110, 2,195, 90,195,145,228,229,242,243,227,239, + 242,101,132, 0, 95,195,109,195,115,195,127,195,138,228,226,108, + 128, 32, 23,237,239,238,239,243,240,225,227,101,128,255, 63,246, + 229,242,244,233,227,225,108,128,254, 51,247,225,246,121,128,254, + 79,105, 2,195,151,195,156,239,110,128, 34, 42,246,229,242,243, + 225,108,128, 34, 0,239,231,239,238,229,107,128, 1,115,112, 5, + 195,186,195,193,195,201,195,216,196, 11,225,242,229,110,128, 36, + 176,226,236,239,227,107,128, 37,128,240,229,242,228,239,244,232, + 229,226,242,229,119,128, 5,196,243,233,236,239,110,131, 3,197, + 195,230,195,251,196, 3,228,233,229,242,229,243,233,115,129, 3, + 203,195,243,244,239,238,239,115,128, 3,176,236,225,244,233,110, + 128, 2,138,244,239,238,239,115,128, 3,205,244,225,227,107, 2, + 196, 20,196, 31,226,229,236,239,247,227,237, 98,128, 3, 29,237, + 239,100,128, 2,212,114, 2,196, 43,196, 55,225,231,245,242,237, + 245,235,232,105,128, 10,115,233,238,103,128, 1,111,115, 3,196, + 69,196, 84,196,129,232,239,242,244,227,249,242,233,236,236,233, + 99,128, 4, 94,237,225,236,108, 2,196, 93,196,104,232,233,242, + 225,231,225,238, 97,128, 48, 69,235,225,244,225,235,225,238, 97, + 129, 48,165,196,117,232,225,236,230,247,233,228,244,104,128,255, + 105,244,242,225,233,231,232,116, 2,196,141,196,152,227,249,242, + 233,236,236,233, 99,128, 4,175,243,244,242,239,235,229,227,249, + 242,233,236,236,233, 99,128, 4,177,244,233,236,228,101,130, 1, + 105,196,181,196,189,225,227,245,244,101,128, 30,121,226,229,236, + 239,119,128, 30,117,117, 5,196,209,196,219,196,226,196,251,197, + 11,226,229,238,231,225,236,105,128, 9,138,228,229,246, 97,128, + 9, 10,231,117, 2,196,233,196,242,234,225,242,225,244,105,128, + 10,138,242,237,245,235,232,105,128, 10, 10,237,225,244,242,225, + 231,245,242,237,245,235,232,105,128, 10, 66,246,239,247,229,236, + 243,233,231,110, 3,197, 27,197, 37,197, 44,226,229,238,231,225, + 236,105,128, 9,194,228,229,246, 97,128, 9, 66,231,245,234,225, + 242,225,244,105,128, 10,194,246,239,247,229,236,243,233,231,110, + 3,197, 71,197, 81,197, 88,226,229,238,231,225,236,105,128, 9, + 193,228,229,246, 97,128, 9, 65,231,245,234,225,242,225,244,105, + 128, 10,193,118,139, 0,118,197,125,198, 17,198, 26,198, 37,198, + 222,198,229,199, 71,199, 83,199,183,199,191,199,212, 97, 4,197, + 135,197,142,197,167,197,178,228,229,246, 97,128, 9, 53,231,117, + 2,197,149,197,158,234,225,242,225,244,105,128, 10,181,242,237, + 245,235,232,105,128, 10, 53,235,225,244,225,235,225,238, 97,128, + 48,247,118,132, 5,213,197,190,197,217,197,249,198, 5,228,225, + 231,229,243,104,130,251, 53,197,203,197,208,182, 53,128,251, 53, + 232,229,226,242,229,119,128,251, 53,104, 2,197,223,197,231,229, + 226,242,229,119,128, 5,213,239,236,225,109,129,251, 75,197,240, + 232,229,226,242,229,119,128,251, 75,246,225,246,232,229,226,242, + 229,119,128, 5,240,249,239,228,232,229,226,242,229,119,128, 5, + 241,227,233,242,227,236,101,128, 36,229,228,239,244,226,229,236, + 239,119,128, 30,127,101, 6,198, 51,198, 62,198,126,198,137,198, + 143,198,210,227,249,242,233,236,236,233, 99,128, 4, 50,104, 4, + 198, 72,198, 81,198, 95,198,111,225,242,225,226,233, 99,128, 6, + 164,230,233,238,225,236,225,242,225,226,233, 99,128,251,107,233, + 238,233,244,233,225,236,225,242,225,226,233, 99,128,251,108,237, + 229,228,233,225,236,225,242,225,226,233, 99,128,251,109,235,225, + 244,225,235,225,238, 97,128, 48,249,238,245,115,128, 38, 64,242, + 244,233,227,225,108, 2,198,154,198,160,226,225,114,128, 0,124, + 236,233,238,101, 4,198,173,198,184,198,195,198,204,225,226,239, + 246,229,227,237, 98,128, 3, 13,226,229,236,239,247,227,237, 98, + 128, 3, 41,236,239,247,237,239,100,128, 2,204,237,239,100,128, + 2,200,247,225,242,237,229,238,233,225,110,128, 5,126,232,239, + 239,107,128, 2,139,105, 3,198,237,198,248,199, 31,235,225,244, + 225,235,225,238, 97,128, 48,248,242,225,237, 97, 3,199, 3,199, + 13,199, 20,226,229,238,231,225,236,105,128, 9,205,228,229,246, + 97,128, 9, 77,231,245,234,225,242,225,244,105,128, 10,205,243, + 225,242,231, 97, 3,199, 43,199, 53,199, 60,226,229,238,231,225, + 236,105,128, 9,131,228,229,246, 97,128, 9, 3,231,245,234,225, + 242,225,244,105,128, 10,131,237,239,238,239,243,240,225,227,101, + 128,255, 86,111, 3,199, 91,199,102,199,172,225,242,237,229,238, + 233,225,110,128, 5,120,233,227,229,100, 2,199,111,199,147,233, + 244,229,242,225,244,233,239,110, 2,199,125,199,136,232,233,242, + 225,231,225,238, 97,128, 48,158,235,225,244,225,235,225,238, 97, + 128, 48,254,237,225,242,235,235,225,238, 97,129, 48,155,199,160, + 232,225,236,230,247,233,228,244,104,128,255,158,235,225,244,225, + 235,225,238, 97,128, 48,250,240,225,242,229,110,128, 36,177,116, + 2,199,197,199,204,233,236,228,101,128, 30,125,245,242,238,229, + 100,128, 2,140,117, 2,199,218,199,229,232,233,242,225,231,225, + 238, 97,128, 48,148,235,225,244,225,235,225,238, 97,128, 48,244, + 119,143, 0,119,200, 18,200,251,201, 5,201, 28,201, 68,201,135, + 201,143,203,114,203,155,203,167,203,242,203,250,204, 1,204, 12, + 204, 21, 97, 8,200, 36,200, 43,200, 53,200, 64,200,102,200,134, + 200,146,200,182,227,245,244,101,128, 30,131,229,235,239,242,229, + 225,110,128, 49, 89,232,233,242,225,231,225,238, 97,128, 48,143, + 107, 2,200, 70,200, 94,225,244,225,235,225,238, 97,129, 48,239, + 200, 82,232,225,236,230,247,233,228,244,104,128,255,156,239,242, + 229,225,110,128, 49, 88,243,237,225,236,108, 2,200,112,200,123, + 232,233,242,225,231,225,238, 97,128, 48,142,235,225,244,225,235, + 225,238, 97,128, 48,238,244,244,239,243,241,245,225,242,101,128, + 51, 87,118, 2,200,152,200,160,229,228,225,243,104,128, 48, 28, + 249,245,238,228,229,242,243,227,239,242,229,246,229,242,244,233, + 227,225,108,128,254, 52,119, 3,200,190,200,199,200,213,225,242, + 225,226,233, 99,128, 6, 72,230,233,238,225,236,225,242,225,226, + 233, 99,128,254,238,232,225,237,250,225,225,226,239,246,101, 2, + 200,228,200,237,225,242,225,226,233, 99,128, 6, 36,230,233,238, + 225,236,225,242,225,226,233, 99,128,254,134,226,243,241,245,225, + 242,101,128, 51,221,227,233,242, 99, 2,201, 14,201, 19,236,101, + 128, 36,230,245,237,230,236,229,120,128, 1,117,100, 2,201, 34, + 201, 44,233,229,242,229,243,233,115,128, 30,133,239,116, 2,201, + 51,201, 60,225,227,227,229,238,116,128, 30,135,226,229,236,239, + 119,128, 30,137,101, 4,201, 78,201, 89,201,101,201,125,232,233, + 242,225,231,225,238, 97,128, 48,145,233,229,242,243,244,242,225, + 243,115,128, 33, 24,107, 2,201,107,201,117,225,244,225,235,225, + 238, 97,128, 48,241,239,242,229,225,110,128, 49, 94,239,235,239, + 242,229,225,110,128, 49, 93,231,242,225,246,101,128, 30,129,232, + 233,244,101, 8,201,164,201,173,202, 1,202, 91,202,175,202,220, + 203, 16,203, 72,226,245,236,236,229,116,128, 37,230, 99, 2,201, + 179,201,199,233,242,227,236,101,129, 37,203,201,189,233,238,246, + 229,242,243,101,128, 37,217,239,242,238,229,242,226,242,225,227, + 235,229,116, 2,201,216,201,236,236,229,230,116,129, 48, 14,201, + 225,246,229,242,244,233,227,225,108,128,254, 67,242,233,231,232, + 116,129, 48, 15,201,246,246,229,242,244,233,227,225,108,128,254, + 68,100, 2,202, 7,202, 48,233,225,237,239,238,100,129, 37,199, + 202, 18,227,239,238,244,225,233,238,233,238,231,226,236,225,227, + 235,243,237,225,236,236,228,233,225,237,239,238,100,128, 37,200, + 239,247,238,240,239,233,238,244,233,238,103, 2,202, 64,202, 80, + 243,237,225,236,236,244,242,233,225,238,231,236,101,128, 37,191, + 244,242,233,225,238,231,236,101,128, 37,189,236,101, 2,202, 98, + 202,140,230,244,240,239,233,238,244,233,238,103, 2,202,113,202, + 129,243,237,225,236,236,244,242,233,225,238,231,236,101,128, 37, + 195,244,242,233,225,238,231,236,101,128, 37,193,238,244,233,227, + 245,236,225,242,226,242,225,227,235,229,116, 2,202,160,202,167, + 236,229,230,116,128, 48, 22,242,233,231,232,116,128, 48, 23,242, + 233,231,232,244,240,239,233,238,244,233,238,103, 2,202,193,202, + 209,243,237,225,236,236,244,242,233,225,238,231,236,101,128, 37, + 185,244,242,233,225,238,231,236,101,128, 37,183,115, 3,202,228, + 203, 2,203, 10,109, 2,202,234,202,246,225,236,236,243,241,245, + 225,242,101,128, 37,171,233,236,233,238,231,230,225,227,101,128, + 38, 58,241,245,225,242,101,128, 37,161,244,225,114,128, 38, 6, + 116, 2,203, 22,203, 33,229,236,229,240,232,239,238,101,128, 38, + 15,239,242,244,239,233,243,229,243,232,229,236,236,226,242,225, + 227,235,229,116, 2,203, 57,203, 64,236,229,230,116,128, 48, 24, + 242,233,231,232,116,128, 48, 25,245,240,240,239,233,238,244,233, + 238,103, 2,203, 87,203,103,243,237,225,236,236,244,242,233,225, + 238,231,236,101,128, 37,181,244,242,233,225,238,231,236,101,128, + 37,179,105, 2,203,120,203,131,232,233,242,225,231,225,238, 97, + 128, 48,144,107, 2,203,137,203,147,225,244,225,235,225,238, 97, + 128, 48,240,239,242,229,225,110,128, 49, 95,237,239,238,239,243, + 240,225,227,101,128,255, 87,111, 4,203,177,203,188,203,213,203, + 231,232,233,242,225,231,225,238, 97,128, 48,146,235,225,244,225, + 235,225,238, 97,129, 48,242,203,201,232,225,236,230,247,233,228, + 244,104,128,255,102,110,129, 32,169,203,219,237,239,238,239,243, + 240,225,227,101,128,255,230,247,225,229,238,244,232,225,105,128, + 14, 39,240,225,242,229,110,128, 36,178,242,233,238,103,128, 30, + 152,243,245,240,229,242,233,239,114,128, 2,183,244,245,242,238, + 229,100,128, 2,141,249,238,110,128, 1,191,120,137, 0,120,204, + 49,204, 60,204, 71,204, 80,204,107,204,120,204,124,204,136,204, + 144,225,226,239,246,229,227,237, 98,128, 3, 61,226,239,240,239, + 237,239,230,111,128, 49, 18,227,233,242,227,236,101,128, 36,231, + 100, 2,204, 86,204, 96,233,229,242,229,243,233,115,128, 30,141, + 239,244,225,227,227,229,238,116,128, 30,139,229,232,225,242,237, + 229,238,233,225,110,128, 5,109,105,128, 3,190,237,239,238,239, + 243,240,225,227,101,128,255, 88,240,225,242,229,110,128, 36,179, + 243,245,240,229,242,233,239,114,128, 2,227,121,143, 0,121,204, + 189,205,148,205,171,205,211,207,177,207,185,207,202,208, 10,208, + 22,209, 19,209, 59,209, 71,209, 82,209,103,210, 76, 97, 11,204, + 213,204,225,204,235,204,242,204,249,205, 3,205, 28,205, 39,205, + 77,205, 90,205,136,225,228,239,243,241,245,225,242,101,128, 51, + 78,226,229,238,231,225,236,105,128, 9,175,227,245,244,101,128, + 0,253,228,229,246, 97,128, 9, 47,229,235,239,242,229,225,110, + 128, 49, 82,231,117, 2,205, 10,205, 19,234,225,242,225,244,105, + 128, 10,175,242,237,245,235,232,105,128, 10, 47,232,233,242,225, + 231,225,238, 97,128, 48,132,107, 2,205, 45,205, 69,225,244,225, + 235,225,238, 97,129, 48,228,205, 57,232,225,236,230,247,233,228, + 244,104,128,255,148,239,242,229,225,110,128, 49, 81,237,225,235, + 235,225,238,244,232,225,105,128, 14, 78,243,237,225,236,108, 2, + 205,100,205,111,232,233,242,225,231,225,238, 97,128, 48,131,235, + 225,244,225,235,225,238, 97,129, 48,227,205,124,232,225,236,230, + 247,233,228,244,104,128,255,108,244,227,249,242,233,236,236,233, + 99,128, 4, 99,227,233,242, 99, 2,205,157,205,162,236,101,128, + 36,232,245,237,230,236,229,120,128, 1,119,100, 2,205,177,205, + 187,233,229,242,229,243,233,115,128, 0,255,239,116, 2,205,194, + 205,203,225,227,227,229,238,116,128, 30,143,226,229,236,239,119, + 128, 30,245,101, 7,205,227,206,235,206,244,207, 6,207, 38,207, + 114,207,165,104, 8,205,245,205,254,206, 32,206, 46,206,119,206, + 135,206,194,206,212,225,242,225,226,233, 99,128, 6, 74,226,225, + 242,242,229,101, 2,206, 9,206, 18,225,242,225,226,233, 99,128, + 6,210,230,233,238,225,236,225,242,225,226,233, 99,128,251,175, + 230,233,238,225,236,225,242,225,226,233, 99,128,254,242,232,225, + 237,250,225,225,226,239,246,101, 4,206, 65,206, 74,206, 88,206, + 104,225,242,225,226,233, 99,128, 6, 38,230,233,238,225,236,225, + 242,225,226,233, 99,128,254,138,233,238,233,244,233,225,236,225, + 242,225,226,233, 99,128,254,139,237,229,228,233,225,236,225,242, + 225,226,233, 99,128,254,140,233,238,233,244,233,225,236,225,242, + 225,226,233, 99,128,254,243,237,101, 2,206,142,206,155,228,233, + 225,236,225,242,225,226,233, 99,128,254,244,229,237,105, 2,206, + 163,206,178,238,233,244,233,225,236,225,242,225,226,233, 99,128, + 252,221,243,239,236,225,244,229,228,225,242,225,226,233, 99,128, + 252, 88,238,239,239,238,230,233,238,225,236,225,242,225,226,233, + 99,128,252,148,244,232,242,229,229,228,239,244,243,226,229,236, + 239,247,225,242,225,226,233, 99,128, 6,209,235,239,242,229,225, + 110,128, 49, 86,110,129, 0,165,206,250,237,239,238,239,243,240, + 225,227,101,128,255,229,111, 2,207, 12,207, 21,235,239,242,229, + 225,110,128, 49, 85,242,233,238,232,233,229,245,232,235,239,242, + 229,225,110,128, 49,134,114, 3,207, 46,207, 82,207, 94,225,232, + 226,229,238,249,239,237,111, 2,207, 60,207, 69,232,229,226,242, + 229,119,128, 5,170,236,229,230,244,232,229,226,242,229,119,128, + 5,170,233,227,249,242,233,236,236,233, 99,128, 4, 75,245,228, + 233,229,242,229,243,233,243,227,249,242,233,236,236,233, 99,128, + 4,249,243,233,229,245,238,103, 3,207,127,207,136,207,152,235, + 239,242,229,225,110,128, 49,129,240,225,238,243,233,239,243,235, + 239,242,229,225,110,128, 49,131,243,233,239,243,235,239,242,229, + 225,110,128, 49,130,244,233,246,232,229,226,242,229,119,128, 5, + 154,231,242,225,246,101,128, 30,243,232,239,239,107,129, 1,180, + 207,194,225,226,239,246,101,128, 30,247,105, 5,207,214,207,225, + 207,236,207,245,207,253,225,242,237,229,238,233,225,110,128, 5, + 117,227,249,242,233,236,236,233, 99,128, 4, 87,235,239,242,229, + 225,110,128, 49, 98,238,249,225,238,103,128, 38, 47,247,238,225, + 242,237,229,238,233,225,110,128, 5,130,237,239,238,239,243,240, + 225,227,101,128,255, 89,111, 7,208, 38,208,108,208,119,208,129, + 208,167,208,213,208,222,100,131, 5,217,208, 48,208, 68,208, 77, + 228,225,231,229,243,104,129,251, 57,208, 59,232,229,226,242,229, + 119,128,251, 57,232,229,226,242,229,119,128, 5,217,249,239,100, + 2,208, 85,208, 94,232,229,226,242,229,119,128, 5,242,240,225, + 244,225,232,232,229,226,242,229,119,128,251, 31,232,233,242,225, + 231,225,238, 97,128, 48,136,233,235,239,242,229,225,110,128, 49, + 137,107, 2,208,135,208,159,225,244,225,235,225,238, 97,129, 48, + 232,208,147,232,225,236,230,247,233,228,244,104,128,255,150,239, + 242,229,225,110,128, 49, 91,243,237,225,236,108, 2,208,177,208, + 188,232,233,242,225,231,225,238, 97,128, 48,135,235,225,244,225, + 235,225,238, 97,129, 48,231,208,201,232,225,236,230,247,233,228, + 244,104,128,255,110,244,231,242,229,229,107,128, 3,243,121, 2, + 208,228,209, 9, 97, 2,208,234,208,244,229,235,239,242,229,225, + 110,128, 49,136,107, 2,208,250,209, 2,239,242,229,225,110,128, + 49,135,244,232,225,105,128, 14, 34,233,238,231,244,232,225,105, + 128, 14, 13,112, 2,209, 25,209, 32,225,242,229,110,128, 36,180, + 239,231,229,231,242,225,237,237,229,238,105,129, 3,122,209, 48, + 231,242,229,229,235,227,237, 98,128, 3, 69,114,129, 1,166,209, + 65,233,238,103,128, 30,153,243,245,240,229,242,233,239,114,128, + 2,184,116, 2,209, 88,209, 95,233,236,228,101,128, 30,249,245, + 242,238,229,100,128, 2,142,117, 5,209,115,209,126,209,136,209, + 174,210, 50,232,233,242,225,231,225,238, 97,128, 48,134,233,235, + 239,242,229,225,110,128, 49,140,107, 2,209,142,209,166,225,244, + 225,235,225,238, 97,129, 48,230,209,154,232,225,236,230,247,233, + 228,244,104,128,255,149,239,242,229,225,110,128, 49, 96,115, 3, + 209,182,209,220,210, 5,226,233,103, 2,209,190,209,201,227,249, + 242,233,236,236,233, 99,128, 4,107,233,239,244,233,230,233,229, + 228,227,249,242,233,236,236,233, 99,128, 4,109,236,233,244,244, + 236,101, 2,209,231,209,242,227,249,242,233,236,236,233, 99,128, + 4,103,233,239,244,233,230,233,229,228,227,249,242,233,236,236, + 233, 99,128, 4,105,237,225,236,108, 2,210, 14,210, 25,232,233, + 242,225,231,225,238, 97,128, 48,133,235,225,244,225,235,225,238, + 97,129, 48,229,210, 38,232,225,236,230,247,233,228,244,104,128, + 255,109,249,101, 2,210, 57,210, 66,235,239,242,229,225,110,128, + 49,139,239,235,239,242,229,225,110,128, 49,138,249, 97, 2,210, + 83,210, 93,226,229,238,231,225,236,105,128, 9,223,228,229,246, + 97,128, 9, 95,122,142, 0,122,210,132,211,140,211,151,211,194, + 211,221,213, 0,213,108,213,150,213,162,213,174,213,202,213,210, + 213,226,213,235, 97, 10,210,154,210,165,210,172,210,179,210,190, + 211, 12,211, 42,211, 53,211, 89,211,101,225,242,237,229,238,233, + 225,110,128, 5,102,227,245,244,101,128, 1,122,228,229,246, 97, + 128, 9, 91,231,245,242,237,245,235,232,105,128, 10, 91,104, 4, + 210,200,210,209,210,223,210,253,225,242,225,226,233, 99,128, 6, + 56,230,233,238,225,236,225,242,225,226,233, 99,128,254,198,105, + 2,210,229,210,244,238,233,244,233,225,236,225,242,225,226,233, + 99,128,254,199,242,225,231,225,238, 97,128, 48, 86,237,229,228, + 233,225,236,225,242,225,226,233, 99,128,254,200,233,110, 2,211, + 19,211, 28,225,242,225,226,233, 99,128, 6, 50,230,233,238,225, + 236,225,242,225,226,233, 99,128,254,176,235,225,244,225,235,225, + 238, 97,128, 48,182,241,229,102, 2,211, 61,211, 75,231,225,228, + 239,236,232,229,226,242,229,119,128, 5,149,241,225,244,225,238, + 232,229,226,242,229,119,128, 5,148,242,241,225,232,229,226,242, + 229,119,128, 5,152,249,233,110,130, 5,214,211,111,211,131,228, + 225,231,229,243,104,129,251, 54,211,122,232,229,226,242,229,119, + 128,251, 54,232,229,226,242,229,119,128, 5,214,226,239,240,239, + 237,239,230,111,128, 49, 23, 99, 3,211,159,211,166,211,188,225, + 242,239,110,128, 1,126,233,242, 99, 2,211,174,211,179,236,101, + 128, 36,233,245,237,230,236,229,120,128, 30,145,245,242,108,128, + 2,145,228,239,116,130, 1,124,211,204,211,213,225,227,227,229, + 238,116,128, 1,124,226,229,236,239,119,128, 30,147,101, 6,211, + 235,211,246,212, 33,212, 44,212, 55,212,251,227,249,242,233,236, + 236,233, 99,128, 4, 55,100, 2,211,252,212, 15,229,243,227,229, + 238,228,229,242,227,249,242,233,236,236,233, 99,128, 4,153,233, + 229,242,229,243,233,243,227,249,242,233,236,236,233, 99,128, 4, + 223,232,233,242,225,231,225,238, 97,128, 48, 92,235,225,244,225, + 235,225,238, 97,128, 48,188,242,111,140, 0, 48,212, 84,212, 93, + 212,103,212,110,212,135,212,148,212,159,212,171,212,182,212,192, + 212,203,212,210,225,242,225,226,233, 99,128, 6, 96,226,229,238, + 231,225,236,105,128, 9,230,228,229,246, 97,128, 9,102,231,117, + 2,212,117,212,126,234,225,242,225,244,105,128, 10,230,242,237, + 245,235,232,105,128, 10,102,232,225,227,235,225,242,225,226,233, + 99,128, 6, 96,233,238,230,229,242,233,239,114,128, 32,128,237, + 239,238,239,243,240,225,227,101,128,255, 16,239,236,228,243,244, + 249,236,101,128,247, 48,240,229,242,243,233,225,110,128, 6,240, + 243,245,240,229,242,233,239,114,128, 32,112,244,232,225,105,128, + 14, 80,247,233,228,244,104, 3,212,222,212,231,212,243,234,239, + 233,238,229,114,128,254,255,238,239,238,234,239,233,238,229,114, + 128, 32, 12,243,240,225,227,101,128, 32, 11,244, 97,128, 3,182, + 104, 2,213, 6,213, 17,226,239,240,239,237,239,230,111,128, 49, + 19,101, 4,213, 27,213, 38,213, 54,213, 65,225,242,237,229,238, + 233,225,110,128, 5,106,226,242,229,246,229,227,249,242,233,236, + 236,233, 99,128, 4,194,227,249,242,233,236,236,233, 99,128, 4, + 54,100, 2,213, 71,213, 90,229,243,227,229,238,228,229,242,227, + 249,242,233,236,236,233, 99,128, 4,151,233,229,242,229,243,233, + 243,227,249,242,233,236,236,233, 99,128, 4,221,105, 3,213,116, + 213,127,213,138,232,233,242,225,231,225,238, 97,128, 48, 88,235, + 225,244,225,235,225,238, 97,128, 48,184,238,239,242,232,229,226, + 242,229,119,128, 5,174,236,233,238,229,226,229,236,239,119,128, + 30,149,237,239,238,239,243,240,225,227,101,128,255, 90,111, 2, + 213,180,213,191,232,233,242,225,231,225,238, 97,128, 48, 94,235, + 225,244,225,235,225,238, 97,128, 48,190,240,225,242,229,110,128, + 36,181,242,229,244,242,239,230,236,229,248,232,239,239,107,128, + 2,144,243,244,242,239,235,101,128, 1,182,117, 2,213,241,213, + 252,232,233,242,225,231,225,238, 97,128, 48, 90,235,225,244,225, + 235,225,238, 97,128, 48,186 + }; + + + /* + * This function searches the compressed table efficiently. + */ + static unsigned long + ft_get_adobe_glyph_index( const char* name, + const char* limit ) + { + int c = 0; + int count, min, max; + const unsigned char* p = ft_adobe_glyph_list; + + + if ( name == 0 || name >= limit ) + goto NotFound; + + c = *name++; + count = p[1]; + p += 2; + + min = 0; + max = count; + + while ( min < max ) + { + int mid = ( min + max ) >> 1; + const unsigned char* q = p + mid * 2; + int c2; + + + q = ft_adobe_glyph_list + ( ( (int)q[0] << 8 ) | q[1] ); + + c2 = q[0] & 127; + if ( c2 == c ) + { + p = q; + goto Found; + } + if ( c2 < c ) + min = mid + 1; + else + max = mid; + } + goto NotFound; + + Found: + for (;;) + { + /* assert (*p & 127) == c */ + + if ( name >= limit ) + { + if ( (p[0] & 128) == 0 && + (p[1] & 128) != 0 ) + return (unsigned long)( ( (int)p[2] << 8 ) | p[3] ); + + goto NotFound; + } + c = *name++; + if ( p[0] & 128 ) + { + p++; + if ( c != (p[0] & 127) ) + goto NotFound; + + continue; + } + + p++; + count = p[0] & 127; + if ( p[0] & 128 ) + p += 2; + + p++; + + for ( ; count > 0; count--, p += 2 ) + { + int offset = ( (int)p[0] << 8 ) | p[1]; + const unsigned char* q = ft_adobe_glyph_list + offset; + + if ( c == ( q[0] & 127 ) ) + { + p = q; + goto NextIter; + } + } + goto NotFound; + + NextIter: + ; + } + + NotFound: + return 0; + } + +#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/raster/ftmisc.h b/mod/pub.mod/freetype.mod/src/raster/ftmisc.h new file mode 100644 index 0000000..f04b540 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/raster/ftmisc.h @@ -0,0 +1,109 @@ +/***************************************************************************/ +/* */ +/* ftmisc.h */ +/* */ +/* Miscellaneous macros for stand-alone rasterizer (specification */ +/* only). */ +/* */ +/* Copyright 2005, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used */ +/* modified and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /***************************************************/ + /* */ + /* This file is *not* portable! You have to adapt */ + /* its definitions to your platform. */ + /* */ + /***************************************************/ + +#ifndef __FTMISC_H__ +#define __FTMISC_H__ + + /* memset */ +#include FT_CONFIG_STANDARD_LIBRARY_H + +#define FT_BEGIN_HEADER +#define FT_END_HEADER + +#define FT_LOCAL_DEF( x ) static x + + /* from include/freetype2/fttypes.h */ + + typedef unsigned char FT_Byte; + typedef signed int FT_Int; + typedef unsigned int FT_UInt; + typedef signed long FT_Long; + typedef unsigned long FT_ULong; + typedef signed long FT_F26Dot6; + typedef int FT_Error; + +#define FT_MAKE_TAG( _x1, _x2, _x3, _x4 ) \ + ( ( (FT_ULong)_x1 << 24 ) | \ + ( (FT_ULong)_x2 << 16 ) | \ + ( (FT_ULong)_x3 << 8 ) | \ + (FT_ULong)_x4 ) + + + /* from include/freetype2/ftsystem.h */ + + typedef struct FT_MemoryRec_* FT_Memory; + + typedef void* (*FT_Alloc_Func)( FT_Memory memory, + long size ); + + typedef void (*FT_Free_Func)( FT_Memory memory, + void* block ); + + typedef void* (*FT_Realloc_Func)( FT_Memory memory, + long cur_size, + long new_size, + void* block ); + + typedef struct FT_MemoryRec_ + { + void* user; + + FT_Alloc_Func alloc; + FT_Free_Func free; + FT_Realloc_Func realloc; + + } FT_MemoryRec; + + /* from src/ftcalc.c */ + +#include <inttypes.h> + + typedef int64_t FT_Int64; + + static FT_Long + FT_MulDiv( FT_Long a, + FT_Long b, + FT_Long c ) + { + FT_Int s; + FT_Long d; + + + s = 1; + if ( a < 0 ) { a = -a; s = -1; } + if ( b < 0 ) { b = -b; s = -s; } + if ( c < 0 ) { c = -c; s = -s; } + + d = (FT_Long)( c > 0 ? ( (FT_Int64)a * b + ( c >> 1 ) ) / c + : 0x7FFFFFFFL ); + + return ( s > 0 ) ? d : -d; + } + +#endif /* __FTMISC_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/raster/ftraster.c b/mod/pub.mod/freetype.mod/src/raster/ftraster.c new file mode 100644 index 0000000..23ad592 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/raster/ftraster.c @@ -0,0 +1,3563 @@ +/***************************************************************************/ +/* */ +/* ftraster.c */ +/* */ +/* The FreeType glyph rasterizer (body). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2005, 2007, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + /*************************************************************************/ + /* */ + /* This file can be compiled without the rest of the FreeType engine, by */ + /* defining the _STANDALONE_ macro when compiling it. You also need to */ + /* put the files `ftimage.h' and `ftmisc.h' into the $(incdir) */ + /* directory. Typically, you should do something like */ + /* */ + /* - copy `src/raster/ftraster.c' (this file) to your current directory */ + /* */ + /* - copy `include/freetype/ftimage.h' and `src/raster/ftmisc.h' */ + /* to your current directory */ + /* */ + /* - compile `ftraster' with the _STANDALONE_ macro defined, as in */ + /* */ + /* cc -c -D_STANDALONE_ ftraster.c */ + /* */ + /* The renderer can be initialized with a call to */ + /* `ft_standard_raster.raster_new'; a bitmap can be generated */ + /* with a call to `ft_standard_raster.raster_render'. */ + /* */ + /* See the comments and documentation in the file `ftimage.h' for more */ + /* details on how the raster works. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This is a rewrite of the FreeType 1.x scan-line converter */ + /* */ + /*************************************************************************/ + +#ifdef _STANDALONE_ + +#define FT_CONFIG_STANDARD_LIBRARY_H <stdlib.h> + +#include <string.h> /* for memset */ + +#include "ftmisc.h" +#include "ftimage.h" + +#else /* !_STANDALONE_ */ + +#include <ft2build.h> +#include "ftraster.h" +#include FT_INTERNAL_CALC_H /* for FT_MulDiv only */ + +#include "rastpic.h" + +#endif /* !_STANDALONE_ */ + + + /*************************************************************************/ + /* */ + /* A simple technical note on how the raster works */ + /* ----------------------------------------------- */ + /* */ + /* Converting an outline into a bitmap is achieved in several steps: */ + /* */ + /* 1 - Decomposing the outline into successive `profiles'. Each */ + /* profile is simply an array of scanline intersections on a given */ + /* dimension. A profile's main attributes are */ + /* */ + /* o its scanline position boundaries, i.e. `Ymin' and `Ymax' */ + /* */ + /* o an array of intersection coordinates for each scanline */ + /* between `Ymin' and `Ymax' */ + /* */ + /* o a direction, indicating whether it was built going `up' or */ + /* `down', as this is very important for filling rules */ + /* */ + /* o its drop-out mode */ + /* */ + /* 2 - Sweeping the target map's scanlines in order to compute segment */ + /* `spans' which are then filled. Additionally, this pass */ + /* performs drop-out control. */ + /* */ + /* The outline data is parsed during step 1 only. The profiles are */ + /* built from the bottom of the render pool, used as a stack. The */ + /* following graphics shows the profile list under construction: */ + /* */ + /* __________________________________________________________ _ _ */ + /* | | | | | */ + /* | profile | coordinates for | profile | coordinates for |--> */ + /* | 1 | profile 1 | 2 | profile 2 |--> */ + /* |_________|_________________|_________|_________________|__ _ _ */ + /* */ + /* ^ ^ */ + /* | | */ + /* start of render pool top */ + /* */ + /* The top of the profile stack is kept in the `top' variable. */ + /* */ + /* As you can see, a profile record is pushed on top of the render */ + /* pool, which is then followed by its coordinates/intersections. If */ + /* a change of direction is detected in the outline, a new profile is */ + /* generated until the end of the outline. */ + /* */ + /* Note that when all profiles have been generated, the function */ + /* Finalize_Profile_Table() is used to record, for each profile, its */ + /* bottom-most scanline as well as the scanline above its upmost */ + /* boundary. These positions are called `y-turns' because they (sort */ + /* of) correspond to local extrema. They are stored in a sorted list */ + /* built from the top of the render pool as a downwards stack: */ + /* */ + /* _ _ _______________________________________ */ + /* | | */ + /* <--| sorted list of | */ + /* <--| extrema scanlines | */ + /* _ _ __________________|____________________| */ + /* */ + /* ^ ^ */ + /* | | */ + /* maxBuff sizeBuff = end of pool */ + /* */ + /* This list is later used during the sweep phase in order to */ + /* optimize performance (see technical note on the sweep below). */ + /* */ + /* Of course, the raster detects whether the two stacks collide and */ + /* handles the situation properly. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /*************************************************************************/ + /** **/ + /** CONFIGURATION MACROS **/ + /** **/ + /*************************************************************************/ + /*************************************************************************/ + + /* define DEBUG_RASTER if you want to compile a debugging version */ +/* #define DEBUG_RASTER */ + + /* define FT_RASTER_OPTION_ANTI_ALIASING if you want to support */ + /* 5-levels anti-aliasing */ +/* #define FT_RASTER_OPTION_ANTI_ALIASING */ + + /* The size of the two-lines intermediate bitmap used */ + /* for anti-aliasing, in bytes. */ +#define RASTER_GRAY_LINES 2048 + + + /*************************************************************************/ + /*************************************************************************/ + /** **/ + /** OTHER MACROS (do not change) **/ + /** **/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_raster + + +#ifdef _STANDALONE_ + + + /* This macro is used to indicate that a function parameter is unused. */ + /* Its purpose is simply to reduce compiler warnings. Note also that */ + /* simply defining it as `(void)x' doesn't avoid warnings with certain */ + /* ANSI compilers (e.g. LCC). */ +#define FT_UNUSED( x ) (x) = (x) + + /* Disable the tracing mechanism for simplicity -- developers can */ + /* activate it easily by redefining these two macros. */ +#ifndef FT_ERROR +#define FT_ERROR( x ) do { } while ( 0 ) /* nothing */ +#endif + +#ifndef FT_TRACE +#define FT_TRACE( x ) do { } while ( 0 ) /* nothing */ +#define FT_TRACE1( x ) do { } while ( 0 ) /* nothing */ +#define FT_TRACE6( x ) do { } while ( 0 ) /* nothing */ +#endif + +#define Raster_Err_None 0 +#define Raster_Err_Not_Ini -1 +#define Raster_Err_Overflow -2 +#define Raster_Err_Neg_Height -3 +#define Raster_Err_Invalid -4 +#define Raster_Err_Unsupported -5 + +#define ft_memset memset + +#define FT_DEFINE_RASTER_FUNCS( class_, glyph_format_, raster_new_, \ + raster_reset_, raster_set_mode_, \ + raster_render_, raster_done_ ) \ + const FT_Raster_Funcs class_ = \ + { \ + glyph_format_, \ + raster_new_, \ + raster_reset_, \ + raster_set_mode_, \ + raster_render_, \ + raster_done_ \ + }; + +#else /* !_STANDALONE_ */ + + +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_DEBUG_H /* for FT_TRACE() and FT_ERROR() */ + +#include "rasterrs.h" + +#define Raster_Err_None Raster_Err_Ok +#define Raster_Err_Not_Ini Raster_Err_Raster_Uninitialized +#define Raster_Err_Overflow Raster_Err_Raster_Overflow +#define Raster_Err_Neg_Height Raster_Err_Raster_Negative_Height +#define Raster_Err_Invalid Raster_Err_Invalid_Outline +#define Raster_Err_Unsupported Raster_Err_Cannot_Render_Glyph + + +#endif /* !_STANDALONE_ */ + + +#ifndef FT_MEM_SET +#define FT_MEM_SET( d, s, c ) ft_memset( d, s, c ) +#endif + +#ifndef FT_MEM_ZERO +#define FT_MEM_ZERO( dest, count ) FT_MEM_SET( dest, 0, count ) +#endif + + /* FMulDiv means `Fast MulDiv'; it is used in case where `b' is */ + /* typically a small value and the result of a*b is known to fit into */ + /* 32 bits. */ +#define FMulDiv( a, b, c ) ( (a) * (b) / (c) ) + + /* On the other hand, SMulDiv means `Slow MulDiv', and is used typically */ + /* for clipping computations. It simply uses the FT_MulDiv() function */ + /* defined in `ftcalc.h'. */ +#define SMulDiv FT_MulDiv + + /* The rasterizer is a very general purpose component; please leave */ + /* the following redefinitions there (you never know your target */ + /* environment). */ + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef NULL +#define NULL (void*)0 +#endif + +#ifndef SUCCESS +#define SUCCESS 0 +#endif + +#ifndef FAILURE +#define FAILURE 1 +#endif + + +#define MaxBezier 32 /* The maximum number of stacked Bezier curves. */ + /* Setting this constant to more than 32 is a */ + /* pure waste of space. */ + +#define Pixel_Bits 6 /* fractional bits of *input* coordinates */ + + + /*************************************************************************/ + /*************************************************************************/ + /** **/ + /** SIMPLE TYPE DECLARATIONS **/ + /** **/ + /*************************************************************************/ + /*************************************************************************/ + + typedef int Int; + typedef unsigned int UInt; + typedef short Short; + typedef unsigned short UShort, *PUShort; + typedef long Long, *PLong; + typedef unsigned long ULong; + + typedef unsigned char Byte, *PByte; + typedef char Bool; + + + typedef union Alignment_ + { + long l; + void* p; + void (*f)(void); + + } Alignment, *PAlignment; + + + typedef struct TPoint_ + { + Long x; + Long y; + + } TPoint; + + + /* values for the `flags' bit field */ +#define Flow_Up 0x8 +#define Overshoot_Top 0x10 +#define Overshoot_Bottom 0x20 + + + /* States of each line, arc, and profile */ + typedef enum TStates_ + { + Unknown_State, + Ascending_State, + Descending_State, + Flat_State + + } TStates; + + + typedef struct TProfile_ TProfile; + typedef TProfile* PProfile; + + struct TProfile_ + { + FT_F26Dot6 X; /* current coordinate during sweep */ + PProfile link; /* link to next profile (various purposes) */ + PLong offset; /* start of profile's data in render pool */ + unsigned flags; /* Bit 0-2: drop-out mode */ + /* Bit 3: profile orientation (up/down) */ + /* Bit 4: is top profile? */ + /* Bit 5: is bottom profile? */ + long height; /* profile's height in scanlines */ + long start; /* profile's starting scanline */ + + unsigned countL; /* number of lines to step before this */ + /* profile becomes drawable */ + + PProfile next; /* next profile in same contour, used */ + /* during drop-out control */ + }; + + typedef PProfile TProfileList; + typedef PProfile* PProfileList; + + + /* Simple record used to implement a stack of bands, required */ + /* by the sub-banding mechanism */ + typedef struct TBand_ + { + Short y_min; /* band's minimum */ + Short y_max; /* band's maximum */ + + } TBand; + + +#define AlignProfileSize \ + ( ( sizeof ( TProfile ) + sizeof ( Alignment ) - 1 ) / sizeof ( long ) ) + + +#ifdef FT_STATIC_RASTER + + +#define RAS_ARGS /* void */ +#define RAS_ARG /* void */ + +#define RAS_VARS /* void */ +#define RAS_VAR /* void */ + +#define FT_UNUSED_RASTER do { } while ( 0 ) + + +#else /* !FT_STATIC_RASTER */ + + +#define RAS_ARGS PWorker worker, +#define RAS_ARG PWorker worker + +#define RAS_VARS worker, +#define RAS_VAR worker + +#define FT_UNUSED_RASTER FT_UNUSED( worker ) + + +#endif /* !FT_STATIC_RASTER */ + + + typedef struct TWorker_ TWorker, *PWorker; + + + /* prototypes used for sweep function dispatch */ + typedef void + Function_Sweep_Init( RAS_ARGS Short* min, + Short* max ); + + typedef void + Function_Sweep_Span( RAS_ARGS Short y, + FT_F26Dot6 x1, + FT_F26Dot6 x2, + PProfile left, + PProfile right ); + + typedef void + Function_Sweep_Step( RAS_ARG ); + + + /* NOTE: These operations are only valid on 2's complement processors */ + +#define FLOOR( x ) ( (x) & -ras.precision ) +#define CEILING( x ) ( ( (x) + ras.precision - 1 ) & -ras.precision ) +#define TRUNC( x ) ( (signed long)(x) >> ras.precision_bits ) +#define FRAC( x ) ( (x) & ( ras.precision - 1 ) ) +#define SCALED( x ) ( ( (x) << ras.scale_shift ) - ras.precision_half ) + +#define IS_BOTTOM_OVERSHOOT( x ) ( CEILING( x ) - x >= ras.precision_half ) +#define IS_TOP_OVERSHOOT( x ) ( x - FLOOR( x ) >= ras.precision_half ) + + /* The most used variables are positioned at the top of the structure. */ + /* Thus, their offset can be coded with less opcodes, resulting in a */ + /* smaller executable. */ + + struct TWorker_ + { + Int precision_bits; /* precision related variables */ + Int precision; + Int precision_half; + Long precision_mask; + Int precision_shift; + Int precision_step; + Int precision_jitter; + + Int scale_shift; /* == precision_shift for bitmaps */ + /* == precision_shift+1 for pixmaps */ + + PLong buff; /* The profiles buffer */ + PLong sizeBuff; /* Render pool size */ + PLong maxBuff; /* Profiles buffer size */ + PLong top; /* Current cursor in buffer */ + + FT_Error error; + + Int numTurns; /* number of Y-turns in outline */ + + TPoint* arc; /* current Bezier arc pointer */ + + UShort bWidth; /* target bitmap width */ + PByte bTarget; /* target bitmap buffer */ + PByte gTarget; /* target pixmap buffer */ + + Long lastX, lastY; + Long minY, maxY; + + UShort num_Profs; /* current number of profiles */ + + Bool fresh; /* signals a fresh new profile which */ + /* `start' field must be completed */ + Bool joint; /* signals that the last arc ended */ + /* exactly on a scanline. Allows */ + /* removal of doublets */ + PProfile cProfile; /* current profile */ + PProfile fProfile; /* head of linked list of profiles */ + PProfile gProfile; /* contour's first profile in case */ + /* of impact */ + + TStates state; /* rendering state */ + + FT_Bitmap target; /* description of target bit/pixmap */ + FT_Outline outline; + + Long traceOfs; /* current offset in target bitmap */ + Long traceG; /* current offset in target pixmap */ + + Short traceIncr; /* sweep's increment in target bitmap */ + + Short gray_min_x; /* current min x during gray rendering */ + Short gray_max_x; /* current max x during gray rendering */ + + /* dispatch variables */ + + Function_Sweep_Init* Proc_Sweep_Init; + Function_Sweep_Span* Proc_Sweep_Span; + Function_Sweep_Span* Proc_Sweep_Drop; + Function_Sweep_Step* Proc_Sweep_Step; + + Byte dropOutControl; /* current drop_out control method */ + + Bool second_pass; /* indicates whether a horizontal pass */ + /* should be performed to control */ + /* drop-out accurately when calling */ + /* Render_Glyph. Note that there is */ + /* no horizontal pass during gray */ + /* rendering. */ + + TPoint arcs[3 * MaxBezier + 1]; /* The Bezier stack */ + + TBand band_stack[16]; /* band stack used for sub-banding */ + Int band_top; /* band stack top */ + +#ifdef FT_RASTER_OPTION_ANTI_ALIASING + + Byte* grays; + + Byte gray_lines[RASTER_GRAY_LINES]; + /* Intermediate table used to render the */ + /* graylevels pixmaps. */ + /* gray_lines is a buffer holding two */ + /* monochrome scanlines */ + + Short gray_width; /* width in bytes of one monochrome */ + /* intermediate scanline of gray_lines. */ + /* Each gray pixel takes 2 bits long there */ + + /* The gray_lines must hold 2 lines, thus with size */ + /* in bytes of at least `gray_width*2'. */ + +#endif /* FT_RASTER_ANTI_ALIASING */ + + }; + + + typedef struct TRaster_ + { + char* buffer; + long buffer_size; + void* memory; + PWorker worker; + Byte grays[5]; + Short gray_width; + + } TRaster, *PRaster; + +#ifdef FT_STATIC_RASTER + + static TWorker cur_ras; +#define ras cur_ras + +#else /* !FT_STATIC_RASTER */ + +#define ras (*worker) + +#endif /* !FT_STATIC_RASTER */ + + +#ifdef FT_RASTER_OPTION_ANTI_ALIASING + + /* A lookup table used to quickly count set bits in four gray 2x2 */ + /* cells. The values of the table have been produced with the */ + /* following code: */ + /* */ + /* for ( i = 0; i < 256; i++ ) */ + /* { */ + /* l = 0; */ + /* j = i; */ + /* */ + /* for ( c = 0; c < 4; c++ ) */ + /* { */ + /* l <<= 4; */ + /* */ + /* if ( j & 0x80 ) l++; */ + /* if ( j & 0x40 ) l++; */ + /* */ + /* j = ( j << 2 ) & 0xFF; */ + /* } */ + /* printf( "0x%04X", l ); */ + /* } */ + /* */ + + static const short count_table[256] = + { + 0x0000, 0x0001, 0x0001, 0x0002, 0x0010, 0x0011, 0x0011, 0x0012, + 0x0010, 0x0011, 0x0011, 0x0012, 0x0020, 0x0021, 0x0021, 0x0022, + 0x0100, 0x0101, 0x0101, 0x0102, 0x0110, 0x0111, 0x0111, 0x0112, + 0x0110, 0x0111, 0x0111, 0x0112, 0x0120, 0x0121, 0x0121, 0x0122, + 0x0100, 0x0101, 0x0101, 0x0102, 0x0110, 0x0111, 0x0111, 0x0112, + 0x0110, 0x0111, 0x0111, 0x0112, 0x0120, 0x0121, 0x0121, 0x0122, + 0x0200, 0x0201, 0x0201, 0x0202, 0x0210, 0x0211, 0x0211, 0x0212, + 0x0210, 0x0211, 0x0211, 0x0212, 0x0220, 0x0221, 0x0221, 0x0222, + 0x1000, 0x1001, 0x1001, 0x1002, 0x1010, 0x1011, 0x1011, 0x1012, + 0x1010, 0x1011, 0x1011, 0x1012, 0x1020, 0x1021, 0x1021, 0x1022, + 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112, + 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122, + 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112, + 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122, + 0x1200, 0x1201, 0x1201, 0x1202, 0x1210, 0x1211, 0x1211, 0x1212, + 0x1210, 0x1211, 0x1211, 0x1212, 0x1220, 0x1221, 0x1221, 0x1222, + 0x1000, 0x1001, 0x1001, 0x1002, 0x1010, 0x1011, 0x1011, 0x1012, + 0x1010, 0x1011, 0x1011, 0x1012, 0x1020, 0x1021, 0x1021, 0x1022, + 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112, + 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122, + 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112, + 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122, + 0x1200, 0x1201, 0x1201, 0x1202, 0x1210, 0x1211, 0x1211, 0x1212, + 0x1210, 0x1211, 0x1211, 0x1212, 0x1220, 0x1221, 0x1221, 0x1222, + 0x2000, 0x2001, 0x2001, 0x2002, 0x2010, 0x2011, 0x2011, 0x2012, + 0x2010, 0x2011, 0x2011, 0x2012, 0x2020, 0x2021, 0x2021, 0x2022, + 0x2100, 0x2101, 0x2101, 0x2102, 0x2110, 0x2111, 0x2111, 0x2112, + 0x2110, 0x2111, 0x2111, 0x2112, 0x2120, 0x2121, 0x2121, 0x2122, + 0x2100, 0x2101, 0x2101, 0x2102, 0x2110, 0x2111, 0x2111, 0x2112, + 0x2110, 0x2111, 0x2111, 0x2112, 0x2120, 0x2121, 0x2121, 0x2122, + 0x2200, 0x2201, 0x2201, 0x2202, 0x2210, 0x2211, 0x2211, 0x2212, + 0x2210, 0x2211, 0x2211, 0x2212, 0x2220, 0x2221, 0x2221, 0x2222 + }; + +#endif /* FT_RASTER_OPTION_ANTI_ALIASING */ + + + + /*************************************************************************/ + /*************************************************************************/ + /** **/ + /** PROFILES COMPUTATION **/ + /** **/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Set_High_Precision */ + /* */ + /* <Description> */ + /* Set precision variables according to param flag. */ + /* */ + /* <Input> */ + /* High :: Set to True for high precision (typically for ppem < 18), */ + /* false otherwise. */ + /* */ + static void + Set_High_Precision( RAS_ARGS Int High ) + { + if ( High ) + { + ras.precision_bits = 12; + ras.precision_step = 256; + ras.precision_jitter = 50; + } + else + { + ras.precision_bits = 6; + ras.precision_step = 32; + ras.precision_jitter = 2; + } + + FT_TRACE6(( "Set_High_Precision(%s)\n", High ? "true" : "false" )); + + ras.precision = 1 << ras.precision_bits; + ras.precision_half = ras.precision / 2; + ras.precision_shift = ras.precision_bits - Pixel_Bits; + ras.precision_mask = -ras.precision; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* New_Profile */ + /* */ + /* <Description> */ + /* Create a new profile in the render pool. */ + /* */ + /* <Input> */ + /* aState :: The state/orientation of the new profile. */ + /* */ + /* overshoot :: Whether the profile's unrounded start position */ + /* differs by at least a half pixel. */ + /* */ + /* <Return> */ + /* SUCCESS on success. FAILURE in case of overflow or of incoherent */ + /* profile. */ + /* */ + static Bool + New_Profile( RAS_ARGS TStates aState, + Bool overshoot ) + { + if ( !ras.fProfile ) + { + ras.cProfile = (PProfile)ras.top; + ras.fProfile = ras.cProfile; + ras.top += AlignProfileSize; + } + + if ( ras.top >= ras.maxBuff ) + { + ras.error = Raster_Err_Overflow; + return FAILURE; + } + + ras.cProfile->flags = 0; + ras.cProfile->start = 0; + ras.cProfile->height = 0; + ras.cProfile->offset = ras.top; + ras.cProfile->link = (PProfile)0; + ras.cProfile->next = (PProfile)0; + ras.cProfile->flags = ras.dropOutControl; + + switch ( aState ) + { + case Ascending_State: + ras.cProfile->flags |= Flow_Up; + if ( overshoot ) + ras.cProfile->flags |= Overshoot_Bottom; + + FT_TRACE6(( "New ascending profile = %lx\n", (long)ras.cProfile )); + break; + + case Descending_State: + if ( overshoot ) + ras.cProfile->flags |= Overshoot_Top; + FT_TRACE6(( "New descending profile = %lx\n", (long)ras.cProfile )); + break; + + default: + FT_ERROR(( "New_Profile: invalid profile direction\n" )); + ras.error = Raster_Err_Invalid; + return FAILURE; + } + + if ( !ras.gProfile ) + ras.gProfile = ras.cProfile; + + ras.state = aState; + ras.fresh = TRUE; + ras.joint = FALSE; + + return SUCCESS; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* End_Profile */ + /* */ + /* <Description> */ + /* Finalize the current profile. */ + /* */ + /* <Input> */ + /* overshoot :: Whether the profile's unrounded end position differs */ + /* by at least a half pixel. */ + /* */ + /* <Return> */ + /* SUCCESS on success. FAILURE in case of overflow or incoherency. */ + /* */ + static Bool + End_Profile( RAS_ARGS Bool overshoot ) + { + Long h; + PProfile oldProfile; + + + h = (Long)( ras.top - ras.cProfile->offset ); + + if ( h < 0 ) + { + FT_ERROR(( "End_Profile: negative height encountered\n" )); + ras.error = Raster_Err_Neg_Height; + return FAILURE; + } + + if ( h > 0 ) + { + FT_TRACE6(( "Ending profile %lx, start = %ld, height = %ld\n", + (long)ras.cProfile, ras.cProfile->start, h )); + + ras.cProfile->height = h; + if ( overshoot ) + { + if ( ras.cProfile->flags & Flow_Up ) + ras.cProfile->flags |= Overshoot_Top; + else + ras.cProfile->flags |= Overshoot_Bottom; + } + + oldProfile = ras.cProfile; + ras.cProfile = (PProfile)ras.top; + + ras.top += AlignProfileSize; + + ras.cProfile->height = 0; + ras.cProfile->offset = ras.top; + + oldProfile->next = ras.cProfile; + ras.num_Profs++; + } + + if ( ras.top >= ras.maxBuff ) + { + FT_TRACE1(( "overflow in End_Profile\n" )); + ras.error = Raster_Err_Overflow; + return FAILURE; + } + + ras.joint = FALSE; + + return SUCCESS; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Insert_Y_Turn */ + /* */ + /* <Description> */ + /* Insert a salient into the sorted list placed on top of the render */ + /* pool. */ + /* */ + /* <Input> */ + /* New y scanline position. */ + /* */ + /* <Return> */ + /* SUCCESS on success. FAILURE in case of overflow. */ + /* */ + static Bool + Insert_Y_Turn( RAS_ARGS Int y ) + { + PLong y_turns; + Int y2, n; + + + n = ras.numTurns - 1; + y_turns = ras.sizeBuff - ras.numTurns; + + /* look for first y value that is <= */ + while ( n >= 0 && y < y_turns[n] ) + n--; + + /* if it is <, simply insert it, ignore if == */ + if ( n >= 0 && y > y_turns[n] ) + while ( n >= 0 ) + { + y2 = (Int)y_turns[n]; + y_turns[n] = y; + y = y2; + n--; + } + + if ( n < 0 ) + { + ras.maxBuff--; + if ( ras.maxBuff <= ras.top ) + { + ras.error = Raster_Err_Overflow; + return FAILURE; + } + ras.numTurns++; + ras.sizeBuff[-ras.numTurns] = y; + } + + return SUCCESS; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Finalize_Profile_Table */ + /* */ + /* <Description> */ + /* Adjust all links in the profiles list. */ + /* */ + /* <Return> */ + /* SUCCESS on success. FAILURE in case of overflow. */ + /* */ + static Bool + Finalize_Profile_Table( RAS_ARG ) + { + Int bottom, top; + UShort n; + PProfile p; + + + n = ras.num_Profs; + p = ras.fProfile; + + if ( n > 1 && p ) + { + while ( n > 0 ) + { + if ( n > 1 ) + p->link = (PProfile)( p->offset + p->height ); + else + p->link = NULL; + + if ( p->flags & Flow_Up ) + { + bottom = (Int)p->start; + top = (Int)( p->start + p->height - 1 ); + } + else + { + bottom = (Int)( p->start - p->height + 1 ); + top = (Int)p->start; + p->start = bottom; + p->offset += p->height - 1; + } + + if ( Insert_Y_Turn( RAS_VARS bottom ) || + Insert_Y_Turn( RAS_VARS top + 1 ) ) + return FAILURE; + + p = p->link; + n--; + } + } + else + ras.fProfile = NULL; + + return SUCCESS; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Split_Conic */ + /* */ + /* <Description> */ + /* Subdivide one conic Bezier into two joint sub-arcs in the Bezier */ + /* stack. */ + /* */ + /* <Input> */ + /* None (subdivided Bezier is taken from the top of the stack). */ + /* */ + /* <Note> */ + /* This routine is the `beef' of this component. It is _the_ inner */ + /* loop that should be optimized to hell to get the best performance. */ + /* */ + static void + Split_Conic( TPoint* base ) + { + Long a, b; + + + base[4].x = base[2].x; + b = base[1].x; + a = base[3].x = ( base[2].x + b ) / 2; + b = base[1].x = ( base[0].x + b ) / 2; + base[2].x = ( a + b ) / 2; + + base[4].y = base[2].y; + b = base[1].y; + a = base[3].y = ( base[2].y + b ) / 2; + b = base[1].y = ( base[0].y + b ) / 2; + base[2].y = ( a + b ) / 2; + + /* hand optimized. gcc doesn't seem to be too good at common */ + /* expression substitution and instruction scheduling ;-) */ + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Split_Cubic */ + /* */ + /* <Description> */ + /* Subdivide a third-order Bezier arc into two joint sub-arcs in the */ + /* Bezier stack. */ + /* */ + /* <Note> */ + /* This routine is the `beef' of the component. It is one of _the_ */ + /* inner loops that should be optimized like hell to get the best */ + /* performance. */ + /* */ + static void + Split_Cubic( TPoint* base ) + { + Long a, b, c, d; + + + base[6].x = base[3].x; + c = base[1].x; + d = base[2].x; + base[1].x = a = ( base[0].x + c + 1 ) >> 1; + base[5].x = b = ( base[3].x + d + 1 ) >> 1; + c = ( c + d + 1 ) >> 1; + base[2].x = a = ( a + c + 1 ) >> 1; + base[4].x = b = ( b + c + 1 ) >> 1; + base[3].x = ( a + b + 1 ) >> 1; + + base[6].y = base[3].y; + c = base[1].y; + d = base[2].y; + base[1].y = a = ( base[0].y + c + 1 ) >> 1; + base[5].y = b = ( base[3].y + d + 1 ) >> 1; + c = ( c + d + 1 ) >> 1; + base[2].y = a = ( a + c + 1 ) >> 1; + base[4].y = b = ( b + c + 1 ) >> 1; + base[3].y = ( a + b + 1 ) >> 1; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Line_Up */ + /* */ + /* <Description> */ + /* Compute the x-coordinates of an ascending line segment and store */ + /* them in the render pool. */ + /* */ + /* <Input> */ + /* x1 :: The x-coordinate of the segment's start point. */ + /* */ + /* y1 :: The y-coordinate of the segment's start point. */ + /* */ + /* x2 :: The x-coordinate of the segment's end point. */ + /* */ + /* y2 :: The y-coordinate of the segment's end point. */ + /* */ + /* miny :: A lower vertical clipping bound value. */ + /* */ + /* maxy :: An upper vertical clipping bound value. */ + /* */ + /* <Return> */ + /* SUCCESS on success, FAILURE on render pool overflow. */ + /* */ + static Bool + Line_Up( RAS_ARGS Long x1, + Long y1, + Long x2, + Long y2, + Long miny, + Long maxy ) + { + Long Dx, Dy; + Int e1, e2, f1, f2, size; /* XXX: is `Short' sufficient? */ + Long Ix, Rx, Ax; + + PLong top; + + + Dx = x2 - x1; + Dy = y2 - y1; + + if ( Dy <= 0 || y2 < miny || y1 > maxy ) + return SUCCESS; + + if ( y1 < miny ) + { + /* Take care: miny-y1 can be a very large value; we use */ + /* a slow MulDiv function to avoid clipping bugs */ + x1 += SMulDiv( Dx, miny - y1, Dy ); + e1 = (Int)TRUNC( miny ); + f1 = 0; + } + else + { + e1 = (Int)TRUNC( y1 ); + f1 = (Int)FRAC( y1 ); + } + + if ( y2 > maxy ) + { + /* x2 += FMulDiv( Dx, maxy - y2, Dy ); UNNECESSARY */ + e2 = (Int)TRUNC( maxy ); + f2 = 0; + } + else + { + e2 = (Int)TRUNC( y2 ); + f2 = (Int)FRAC( y2 ); + } + + if ( f1 > 0 ) + { + if ( e1 == e2 ) + return SUCCESS; + else + { + x1 += FMulDiv( Dx, ras.precision - f1, Dy ); + e1 += 1; + } + } + else + if ( ras.joint ) + { + ras.top--; + ras.joint = FALSE; + } + + ras.joint = (char)( f2 == 0 ); + + if ( ras.fresh ) + { + ras.cProfile->start = e1; + ras.fresh = FALSE; + } + + size = e2 - e1 + 1; + if ( ras.top + size >= ras.maxBuff ) + { + ras.error = Raster_Err_Overflow; + return FAILURE; + } + + if ( Dx > 0 ) + { + Ix = ( ras.precision * Dx ) / Dy; + Rx = ( ras.precision * Dx ) % Dy; + Dx = 1; + } + else + { + Ix = -( ( ras.precision * -Dx ) / Dy ); + Rx = ( ras.precision * -Dx ) % Dy; + Dx = -1; + } + + Ax = -Dy; + top = ras.top; + + while ( size > 0 ) + { + *top++ = x1; + + x1 += Ix; + Ax += Rx; + if ( Ax >= 0 ) + { + Ax -= Dy; + x1 += Dx; + } + size--; + } + + ras.top = top; + return SUCCESS; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Line_Down */ + /* */ + /* <Description> */ + /* Compute the x-coordinates of an descending line segment and store */ + /* them in the render pool. */ + /* */ + /* <Input> */ + /* x1 :: The x-coordinate of the segment's start point. */ + /* */ + /* y1 :: The y-coordinate of the segment's start point. */ + /* */ + /* x2 :: The x-coordinate of the segment's end point. */ + /* */ + /* y2 :: The y-coordinate of the segment's end point. */ + /* */ + /* miny :: A lower vertical clipping bound value. */ + /* */ + /* maxy :: An upper vertical clipping bound value. */ + /* */ + /* <Return> */ + /* SUCCESS on success, FAILURE on render pool overflow. */ + /* */ + static Bool + Line_Down( RAS_ARGS Long x1, + Long y1, + Long x2, + Long y2, + Long miny, + Long maxy ) + { + Bool result, fresh; + + + fresh = ras.fresh; + + result = Line_Up( RAS_VARS x1, -y1, x2, -y2, -maxy, -miny ); + + if ( fresh && !ras.fresh ) + ras.cProfile->start = -ras.cProfile->start; + + return result; + } + + + /* A function type describing the functions used to split Bezier arcs */ + typedef void (*TSplitter)( TPoint* base ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Bezier_Up */ + /* */ + /* <Description> */ + /* Compute the x-coordinates of an ascending Bezier arc and store */ + /* them in the render pool. */ + /* */ + /* <Input> */ + /* degree :: The degree of the Bezier arc (either 2 or 3). */ + /* */ + /* splitter :: The function to split Bezier arcs. */ + /* */ + /* miny :: A lower vertical clipping bound value. */ + /* */ + /* maxy :: An upper vertical clipping bound value. */ + /* */ + /* <Return> */ + /* SUCCESS on success, FAILURE on render pool overflow. */ + /* */ + static Bool + Bezier_Up( RAS_ARGS Int degree, + TSplitter splitter, + Long miny, + Long maxy ) + { + Long y1, y2, e, e2, e0; + Short f1; + + TPoint* arc; + TPoint* start_arc; + + PLong top; + + + arc = ras.arc; + y1 = arc[degree].y; + y2 = arc[0].y; + top = ras.top; + + if ( y2 < miny || y1 > maxy ) + goto Fin; + + e2 = FLOOR( y2 ); + + if ( e2 > maxy ) + e2 = maxy; + + e0 = miny; + + if ( y1 < miny ) + e = miny; + else + { + e = CEILING( y1 ); + f1 = (Short)( FRAC( y1 ) ); + e0 = e; + + if ( f1 == 0 ) + { + if ( ras.joint ) + { + top--; + ras.joint = FALSE; + } + + *top++ = arc[degree].x; + + e += ras.precision; + } + } + + if ( ras.fresh ) + { + ras.cProfile->start = TRUNC( e0 ); + ras.fresh = FALSE; + } + + if ( e2 < e ) + goto Fin; + + if ( ( top + TRUNC( e2 - e ) + 1 ) >= ras.maxBuff ) + { + ras.top = top; + ras.error = Raster_Err_Overflow; + return FAILURE; + } + + start_arc = arc; + + while ( arc >= start_arc && e <= e2 ) + { + ras.joint = FALSE; + + y2 = arc[0].y; + + if ( y2 > e ) + { + y1 = arc[degree].y; + if ( y2 - y1 >= ras.precision_step ) + { + splitter( arc ); + arc += degree; + } + else + { + *top++ = arc[degree].x + FMulDiv( arc[0].x - arc[degree].x, + e - y1, y2 - y1 ); + arc -= degree; + e += ras.precision; + } + } + else + { + if ( y2 == e ) + { + ras.joint = TRUE; + *top++ = arc[0].x; + + e += ras.precision; + } + arc -= degree; + } + } + + Fin: + ras.top = top; + ras.arc -= degree; + return SUCCESS; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Bezier_Down */ + /* */ + /* <Description> */ + /* Compute the x-coordinates of an descending Bezier arc and store */ + /* them in the render pool. */ + /* */ + /* <Input> */ + /* degree :: The degree of the Bezier arc (either 2 or 3). */ + /* */ + /* splitter :: The function to split Bezier arcs. */ + /* */ + /* miny :: A lower vertical clipping bound value. */ + /* */ + /* maxy :: An upper vertical clipping bound value. */ + /* */ + /* <Return> */ + /* SUCCESS on success, FAILURE on render pool overflow. */ + /* */ + static Bool + Bezier_Down( RAS_ARGS Int degree, + TSplitter splitter, + Long miny, + Long maxy ) + { + TPoint* arc = ras.arc; + Bool result, fresh; + + + arc[0].y = -arc[0].y; + arc[1].y = -arc[1].y; + arc[2].y = -arc[2].y; + if ( degree > 2 ) + arc[3].y = -arc[3].y; + + fresh = ras.fresh; + + result = Bezier_Up( RAS_VARS degree, splitter, -maxy, -miny ); + + if ( fresh && !ras.fresh ) + ras.cProfile->start = -ras.cProfile->start; + + arc[0].y = -arc[0].y; + return result; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Line_To */ + /* */ + /* <Description> */ + /* Inject a new line segment and adjust the Profiles list. */ + /* */ + /* <Input> */ + /* x :: The x-coordinate of the segment's end point (its start point */ + /* is stored in `lastX'). */ + /* */ + /* y :: The y-coordinate of the segment's end point (its start point */ + /* is stored in `lastY'). */ + /* */ + /* <Return> */ + /* SUCCESS on success, FAILURE on render pool overflow or incorrect */ + /* profile. */ + /* */ + static Bool + Line_To( RAS_ARGS Long x, + Long y ) + { + /* First, detect a change of direction */ + + switch ( ras.state ) + { + case Unknown_State: + if ( y > ras.lastY ) + { + if ( New_Profile( RAS_VARS Ascending_State, + IS_BOTTOM_OVERSHOOT( ras.lastY ) ) ) + return FAILURE; + } + else + { + if ( y < ras.lastY ) + if ( New_Profile( RAS_VARS Descending_State, + IS_TOP_OVERSHOOT( ras.lastY ) ) ) + return FAILURE; + } + break; + + case Ascending_State: + if ( y < ras.lastY ) + { + if ( End_Profile( RAS_VARS IS_TOP_OVERSHOOT( ras.lastY ) ) || + New_Profile( RAS_VARS Descending_State, + IS_TOP_OVERSHOOT( ras.lastY ) ) ) + return FAILURE; + } + break; + + case Descending_State: + if ( y > ras.lastY ) + { + if ( End_Profile( RAS_VARS IS_BOTTOM_OVERSHOOT( ras.lastY ) ) || + New_Profile( RAS_VARS Ascending_State, + IS_BOTTOM_OVERSHOOT( ras.lastY ) ) ) + return FAILURE; + } + break; + + default: + ; + } + + /* Then compute the lines */ + + switch ( ras.state ) + { + case Ascending_State: + if ( Line_Up( RAS_VARS ras.lastX, ras.lastY, + x, y, ras.minY, ras.maxY ) ) + return FAILURE; + break; + + case Descending_State: + if ( Line_Down( RAS_VARS ras.lastX, ras.lastY, + x, y, ras.minY, ras.maxY ) ) + return FAILURE; + break; + + default: + ; + } + + ras.lastX = x; + ras.lastY = y; + + return SUCCESS; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Conic_To */ + /* */ + /* <Description> */ + /* Inject a new conic arc and adjust the profile list. */ + /* */ + /* <Input> */ + /* cx :: The x-coordinate of the arc's new control point. */ + /* */ + /* cy :: The y-coordinate of the arc's new control point. */ + /* */ + /* x :: The x-coordinate of the arc's end point (its start point is */ + /* stored in `lastX'). */ + /* */ + /* y :: The y-coordinate of the arc's end point (its start point is */ + /* stored in `lastY'). */ + /* */ + /* <Return> */ + /* SUCCESS on success, FAILURE on render pool overflow or incorrect */ + /* profile. */ + /* */ + static Bool + Conic_To( RAS_ARGS Long cx, + Long cy, + Long x, + Long y ) + { + Long y1, y2, y3, x3, ymin, ymax; + TStates state_bez; + + + ras.arc = ras.arcs; + ras.arc[2].x = ras.lastX; + ras.arc[2].y = ras.lastY; + ras.arc[1].x = cx; + ras.arc[1].y = cy; + ras.arc[0].x = x; + ras.arc[0].y = y; + + do + { + y1 = ras.arc[2].y; + y2 = ras.arc[1].y; + y3 = ras.arc[0].y; + x3 = ras.arc[0].x; + + /* first, categorize the Bezier arc */ + + if ( y1 <= y3 ) + { + ymin = y1; + ymax = y3; + } + else + { + ymin = y3; + ymax = y1; + } + + if ( y2 < ymin || y2 > ymax ) + { + /* this arc has no given direction, split it! */ + Split_Conic( ras.arc ); + ras.arc += 2; + } + else if ( y1 == y3 ) + { + /* this arc is flat, ignore it and pop it from the Bezier stack */ + ras.arc -= 2; + } + else + { + /* the arc is y-monotonous, either ascending or descending */ + /* detect a change of direction */ + state_bez = y1 < y3 ? Ascending_State : Descending_State; + if ( ras.state != state_bez ) + { + Bool o = state_bez == Ascending_State ? IS_BOTTOM_OVERSHOOT( y1 ) + : IS_TOP_OVERSHOOT( y1 ); + + + /* finalize current profile if any */ + if ( ras.state != Unknown_State && + End_Profile( RAS_VARS o ) ) + goto Fail; + + /* create a new profile */ + if ( New_Profile( RAS_VARS state_bez, o ) ) + goto Fail; + } + + /* now call the appropriate routine */ + if ( state_bez == Ascending_State ) + { + if ( Bezier_Up( RAS_VARS 2, Split_Conic, ras.minY, ras.maxY ) ) + goto Fail; + } + else + if ( Bezier_Down( RAS_VARS 2, Split_Conic, ras.minY, ras.maxY ) ) + goto Fail; + } + + } while ( ras.arc >= ras.arcs ); + + ras.lastX = x3; + ras.lastY = y3; + + return SUCCESS; + + Fail: + return FAILURE; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Cubic_To */ + /* */ + /* <Description> */ + /* Inject a new cubic arc and adjust the profile list. */ + /* */ + /* <Input> */ + /* cx1 :: The x-coordinate of the arc's first new control point. */ + /* */ + /* cy1 :: The y-coordinate of the arc's first new control point. */ + /* */ + /* cx2 :: The x-coordinate of the arc's second new control point. */ + /* */ + /* cy2 :: The y-coordinate of the arc's second new control point. */ + /* */ + /* x :: The x-coordinate of the arc's end point (its start point is */ + /* stored in `lastX'). */ + /* */ + /* y :: The y-coordinate of the arc's end point (its start point is */ + /* stored in `lastY'). */ + /* */ + /* <Return> */ + /* SUCCESS on success, FAILURE on render pool overflow or incorrect */ + /* profile. */ + /* */ + static Bool + Cubic_To( RAS_ARGS Long cx1, + Long cy1, + Long cx2, + Long cy2, + Long x, + Long y ) + { + Long y1, y2, y3, y4, x4, ymin1, ymax1, ymin2, ymax2; + TStates state_bez; + + + ras.arc = ras.arcs; + ras.arc[3].x = ras.lastX; + ras.arc[3].y = ras.lastY; + ras.arc[2].x = cx1; + ras.arc[2].y = cy1; + ras.arc[1].x = cx2; + ras.arc[1].y = cy2; + ras.arc[0].x = x; + ras.arc[0].y = y; + + do + { + y1 = ras.arc[3].y; + y2 = ras.arc[2].y; + y3 = ras.arc[1].y; + y4 = ras.arc[0].y; + x4 = ras.arc[0].x; + + /* first, categorize the Bezier arc */ + + if ( y1 <= y4 ) + { + ymin1 = y1; + ymax1 = y4; + } + else + { + ymin1 = y4; + ymax1 = y1; + } + + if ( y2 <= y3 ) + { + ymin2 = y2; + ymax2 = y3; + } + else + { + ymin2 = y3; + ymax2 = y2; + } + + if ( ymin2 < ymin1 || ymax2 > ymax1 ) + { + /* this arc has no given direction, split it! */ + Split_Cubic( ras.arc ); + ras.arc += 3; + } + else if ( y1 == y4 ) + { + /* this arc is flat, ignore it and pop it from the Bezier stack */ + ras.arc -= 3; + } + else + { + state_bez = ( y1 <= y4 ) ? Ascending_State : Descending_State; + + /* detect a change of direction */ + if ( ras.state != state_bez ) + { + Bool o = state_bez == Ascending_State ? IS_BOTTOM_OVERSHOOT( y1 ) + : IS_TOP_OVERSHOOT( y1 ); + + + /* finalize current profile if any */ + if ( ras.state != Unknown_State && + End_Profile( RAS_VARS o ) ) + goto Fail; + + if ( New_Profile( RAS_VARS state_bez, o ) ) + goto Fail; + } + + /* compute intersections */ + if ( state_bez == Ascending_State ) + { + if ( Bezier_Up( RAS_VARS 3, Split_Cubic, ras.minY, ras.maxY ) ) + goto Fail; + } + else + if ( Bezier_Down( RAS_VARS 3, Split_Cubic, ras.minY, ras.maxY ) ) + goto Fail; + } + + } while ( ras.arc >= ras.arcs ); + + ras.lastX = x4; + ras.lastY = y4; + + return SUCCESS; + + Fail: + return FAILURE; + } + + +#undef SWAP_ +#define SWAP_( x, y ) do \ + { \ + Long swap = x; \ + \ + \ + x = y; \ + y = swap; \ + } while ( 0 ) + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Decompose_Curve */ + /* */ + /* <Description> */ + /* Scan the outline arrays in order to emit individual segments and */ + /* Beziers by calling Line_To() and Bezier_To(). It handles all */ + /* weird cases, like when the first point is off the curve, or when */ + /* there are simply no `on' points in the contour! */ + /* */ + /* <Input> */ + /* first :: The index of the first point in the contour. */ + /* */ + /* last :: The index of the last point in the contour. */ + /* */ + /* flipped :: If set, flip the direction of the curve. */ + /* */ + /* <Return> */ + /* SUCCESS on success, FAILURE on error. */ + /* */ + static Bool + Decompose_Curve( RAS_ARGS UShort first, + UShort last, + int flipped ) + { + FT_Vector v_last; + FT_Vector v_control; + FT_Vector v_start; + + FT_Vector* points; + FT_Vector* point; + FT_Vector* limit; + char* tags; + + unsigned tag; /* current point's state */ + + + points = ras.outline.points; + limit = points + last; + + v_start.x = SCALED( points[first].x ); + v_start.y = SCALED( points[first].y ); + v_last.x = SCALED( points[last].x ); + v_last.y = SCALED( points[last].y ); + + if ( flipped ) + { + SWAP_( v_start.x, v_start.y ); + SWAP_( v_last.x, v_last.y ); + } + + v_control = v_start; + + point = points + first; + tags = ras.outline.tags + first; + + /* set scan mode if necessary */ + if ( tags[0] & FT_CURVE_TAG_HAS_SCANMODE ) + ras.dropOutControl = (Byte)tags[0] >> 5; + + tag = FT_CURVE_TAG( tags[0] ); + + /* A contour cannot start with a cubic control point! */ + if ( tag == FT_CURVE_TAG_CUBIC ) + goto Invalid_Outline; + + /* check first point to determine origin */ + if ( tag == FT_CURVE_TAG_CONIC ) + { + /* first point is conic control. Yes, this happens. */ + if ( FT_CURVE_TAG( ras.outline.tags[last] ) == FT_CURVE_TAG_ON ) + { + /* start at last point if it is on the curve */ + v_start = v_last; + limit--; + } + else + { + /* if both first and last points are conic, */ + /* start at their middle and record its position */ + /* for closure */ + v_start.x = ( v_start.x + v_last.x ) / 2; + v_start.y = ( v_start.y + v_last.y ) / 2; + + v_last = v_start; + } + point--; + tags--; + } + + ras.lastX = v_start.x; + ras.lastY = v_start.y; + + while ( point < limit ) + { + point++; + tags++; + + tag = FT_CURVE_TAG( tags[0] ); + + switch ( tag ) + { + case FT_CURVE_TAG_ON: /* emit a single line_to */ + { + Long x, y; + + + x = SCALED( point->x ); + y = SCALED( point->y ); + if ( flipped ) + SWAP_( x, y ); + + if ( Line_To( RAS_VARS x, y ) ) + goto Fail; + continue; + } + + case FT_CURVE_TAG_CONIC: /* consume conic arcs */ + v_control.x = SCALED( point[0].x ); + v_control.y = SCALED( point[0].y ); + + if ( flipped ) + SWAP_( v_control.x, v_control.y ); + + Do_Conic: + if ( point < limit ) + { + FT_Vector v_middle; + Long x, y; + + + point++; + tags++; + tag = FT_CURVE_TAG( tags[0] ); + + x = SCALED( point[0].x ); + y = SCALED( point[0].y ); + + if ( flipped ) + SWAP_( x, y ); + + if ( tag == FT_CURVE_TAG_ON ) + { + if ( Conic_To( RAS_VARS v_control.x, v_control.y, x, y ) ) + goto Fail; + continue; + } + + if ( tag != FT_CURVE_TAG_CONIC ) + goto Invalid_Outline; + + v_middle.x = ( v_control.x + x ) / 2; + v_middle.y = ( v_control.y + y ) / 2; + + if ( Conic_To( RAS_VARS v_control.x, v_control.y, + v_middle.x, v_middle.y ) ) + goto Fail; + + v_control.x = x; + v_control.y = y; + + goto Do_Conic; + } + + if ( Conic_To( RAS_VARS v_control.x, v_control.y, + v_start.x, v_start.y ) ) + goto Fail; + + goto Close; + + default: /* FT_CURVE_TAG_CUBIC */ + { + Long x1, y1, x2, y2, x3, y3; + + + if ( point + 1 > limit || + FT_CURVE_TAG( tags[1] ) != FT_CURVE_TAG_CUBIC ) + goto Invalid_Outline; + + point += 2; + tags += 2; + + x1 = SCALED( point[-2].x ); + y1 = SCALED( point[-2].y ); + x2 = SCALED( point[-1].x ); + y2 = SCALED( point[-1].y ); + x3 = SCALED( point[ 0].x ); + y3 = SCALED( point[ 0].y ); + + if ( flipped ) + { + SWAP_( x1, y1 ); + SWAP_( x2, y2 ); + SWAP_( x3, y3 ); + } + + if ( point <= limit ) + { + if ( Cubic_To( RAS_VARS x1, y1, x2, y2, x3, y3 ) ) + goto Fail; + continue; + } + + if ( Cubic_To( RAS_VARS x1, y1, x2, y2, v_start.x, v_start.y ) ) + goto Fail; + goto Close; + } + } + } + + /* close the contour with a line segment */ + if ( Line_To( RAS_VARS v_start.x, v_start.y ) ) + goto Fail; + + Close: + return SUCCESS; + + Invalid_Outline: + ras.error = Raster_Err_Invalid; + + Fail: + return FAILURE; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Convert_Glyph */ + /* */ + /* <Description> */ + /* Convert a glyph into a series of segments and arcs and make a */ + /* profiles list with them. */ + /* */ + /* <Input> */ + /* flipped :: If set, flip the direction of curve. */ + /* */ + /* <Return> */ + /* SUCCESS on success, FAILURE if any error was encountered during */ + /* rendering. */ + /* */ + static Bool + Convert_Glyph( RAS_ARGS int flipped ) + { + int i; + unsigned start; + + PProfile lastProfile; + + + ras.fProfile = NULL; + ras.joint = FALSE; + ras.fresh = FALSE; + + ras.maxBuff = ras.sizeBuff - AlignProfileSize; + + ras.numTurns = 0; + + ras.cProfile = (PProfile)ras.top; + ras.cProfile->offset = ras.top; + ras.num_Profs = 0; + + start = 0; + + for ( i = 0; i < ras.outline.n_contours; i++ ) + { + Bool o; + + + ras.state = Unknown_State; + ras.gProfile = NULL; + + if ( Decompose_Curve( RAS_VARS (unsigned short)start, + ras.outline.contours[i], + flipped ) ) + return FAILURE; + + start = ras.outline.contours[i] + 1; + + /* we must now check whether the extreme arcs join or not */ + if ( FRAC( ras.lastY ) == 0 && + ras.lastY >= ras.minY && + ras.lastY <= ras.maxY ) + if ( ras.gProfile && + ( ras.gProfile->flags & Flow_Up ) == + ( ras.cProfile->flags & Flow_Up ) ) + ras.top--; + /* Note that ras.gProfile can be nil if the contour was too small */ + /* to be drawn. */ + + lastProfile = ras.cProfile; + if ( ras.cProfile->flags & Flow_Up ) + o = IS_TOP_OVERSHOOT( ras.lastY ); + else + o = IS_BOTTOM_OVERSHOOT( ras.lastY ); + if ( End_Profile( RAS_VARS o ) ) + return FAILURE; + + /* close the `next profile in contour' linked list */ + if ( ras.gProfile ) + lastProfile->next = ras.gProfile; + } + + if ( Finalize_Profile_Table( RAS_VAR ) ) + return FAILURE; + + return (Bool)( ras.top < ras.maxBuff ? SUCCESS : FAILURE ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /** **/ + /** SCAN-LINE SWEEPS AND DRAWING **/ + /** **/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* Init_Linked */ + /* */ + /* Initializes an empty linked list. */ + /* */ + static void + Init_Linked( TProfileList* l ) + { + *l = NULL; + } + + + /*************************************************************************/ + /* */ + /* InsNew */ + /* */ + /* Inserts a new profile in a linked list. */ + /* */ + static void + InsNew( PProfileList list, + PProfile profile ) + { + PProfile *old, current; + Long x; + + + old = list; + current = *old; + x = profile->X; + + while ( current ) + { + if ( x < current->X ) + break; + old = ¤t->link; + current = *old; + } + + profile->link = current; + *old = profile; + } + + + /*************************************************************************/ + /* */ + /* DelOld */ + /* */ + /* Removes an old profile from a linked list. */ + /* */ + static void + DelOld( PProfileList list, + PProfile profile ) + { + PProfile *old, current; + + + old = list; + current = *old; + + while ( current ) + { + if ( current == profile ) + { + *old = current->link; + return; + } + + old = ¤t->link; + current = *old; + } + + /* we should never get there, unless the profile was not part of */ + /* the list. */ + } + + + /*************************************************************************/ + /* */ + /* Sort */ + /* */ + /* Sorts a trace list. In 95%, the list is already sorted. We need */ + /* an algorithm which is fast in this case. Bubble sort is enough */ + /* and simple. */ + /* */ + static void + Sort( PProfileList list ) + { + PProfile *old, current, next; + + + /* First, set the new X coordinate of each profile */ + current = *list; + while ( current ) + { + current->X = *current->offset; + current->offset += current->flags & Flow_Up ? 1 : -1; + current->height--; + current = current->link; + } + + /* Then sort them */ + old = list; + current = *old; + + if ( !current ) + return; + + next = current->link; + + while ( next ) + { + if ( current->X <= next->X ) + { + old = ¤t->link; + current = *old; + + if ( !current ) + return; + } + else + { + *old = next; + current->link = next->link; + next->link = current; + + old = list; + current = *old; + } + + next = current->link; + } + } + + + /*************************************************************************/ + /* */ + /* Vertical Sweep Procedure Set */ + /* */ + /* These four routines are used during the vertical black/white sweep */ + /* phase by the generic Draw_Sweep() function. */ + /* */ + /*************************************************************************/ + + static void + Vertical_Sweep_Init( RAS_ARGS Short* min, + Short* max ) + { + Long pitch = ras.target.pitch; + + FT_UNUSED( max ); + + + ras.traceIncr = (Short)-pitch; + ras.traceOfs = -*min * pitch; + if ( pitch > 0 ) + ras.traceOfs += ( ras.target.rows - 1 ) * pitch; + + ras.gray_min_x = 0; + ras.gray_max_x = 0; + } + + + static void + Vertical_Sweep_Span( RAS_ARGS Short y, + FT_F26Dot6 x1, + FT_F26Dot6 x2, + PProfile left, + PProfile right ) + { + Long e1, e2; + int c1, c2; + Byte f1, f2; + Byte* target; + + FT_UNUSED( y ); + FT_UNUSED( left ); + FT_UNUSED( right ); + + + /* Drop-out control */ + + e1 = TRUNC( CEILING( x1 ) ); + + if ( x2 - x1 - ras.precision <= ras.precision_jitter ) + e2 = e1; + else + e2 = TRUNC( FLOOR( x2 ) ); + + if ( e2 >= 0 && e1 < ras.bWidth ) + { + if ( e1 < 0 ) + e1 = 0; + if ( e2 >= ras.bWidth ) + e2 = ras.bWidth - 1; + + c1 = (Short)( e1 >> 3 ); + c2 = (Short)( e2 >> 3 ); + + f1 = (Byte) ( 0xFF >> ( e1 & 7 ) ); + f2 = (Byte) ~( 0x7F >> ( e2 & 7 ) ); + + if ( ras.gray_min_x > c1 ) + ras.gray_min_x = (short)c1; + if ( ras.gray_max_x < c2 ) + ras.gray_max_x = (short)c2; + + target = ras.bTarget + ras.traceOfs + c1; + c2 -= c1; + + if ( c2 > 0 ) + { + target[0] |= f1; + + /* memset() is slower than the following code on many platforms. */ + /* This is due to the fact that, in the vast majority of cases, */ + /* the span length in bytes is relatively small. */ + c2--; + while ( c2 > 0 ) + { + *(++target) = 0xFF; + c2--; + } + target[1] |= f2; + } + else + *target |= ( f1 & f2 ); + } + } + + + static void + Vertical_Sweep_Drop( RAS_ARGS Short y, + FT_F26Dot6 x1, + FT_F26Dot6 x2, + PProfile left, + PProfile right ) + { + Long e1, e2, pxl; + Short c1, f1; + + + /* Drop-out control */ + + /* e2 x2 x1 e1 */ + /* */ + /* ^ | */ + /* | | */ + /* +-------------+---------------------+------------+ */ + /* | | */ + /* | v */ + /* */ + /* pixel contour contour pixel */ + /* center center */ + + /* drop-out mode scan conversion rules (as defined in OpenType) */ + /* --------------------------------------------------------------- */ + /* 0 1, 2, 3 */ + /* 1 1, 2, 4 */ + /* 2 1, 2 */ + /* 3 same as mode 2 */ + /* 4 1, 2, 5 */ + /* 5 1, 2, 6 */ + /* 6, 7 same as mode 2 */ + + e1 = CEILING( x1 ); + e2 = FLOOR ( x2 ); + pxl = e1; + + if ( e1 > e2 ) + { + Int dropOutControl = left->flags & 7; + + + if ( e1 == e2 + ras.precision ) + { + switch ( dropOutControl ) + { + case 0: /* simple drop-outs including stubs */ + pxl = e2; + break; + + case 4: /* smart drop-outs including stubs */ + pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); + break; + + case 1: /* simple drop-outs excluding stubs */ + case 5: /* smart drop-outs excluding stubs */ + + /* Drop-out Control Rules #4 and #6 */ + + /* The specification neither provides an exact definition */ + /* of a `stub' nor gives exact rules to exclude them. */ + /* */ + /* Here the constraints we use to recognize a stub. */ + /* */ + /* upper stub: */ + /* */ + /* - P_Left and P_Right are in the same contour */ + /* - P_Right is the successor of P_Left in that contour */ + /* - y is the top of P_Left and P_Right */ + /* */ + /* lower stub: */ + /* */ + /* - P_Left and P_Right are in the same contour */ + /* - P_Left is the successor of P_Right in that contour */ + /* - y is the bottom of P_Left */ + /* */ + /* We draw a stub if the following constraints are met. */ + /* */ + /* - for an upper or lower stub, there is top or bottom */ + /* overshoot, respectively */ + /* - the covered interval is greater or equal to a half */ + /* pixel */ + + /* upper stub test */ + if ( left->next == right && + left->height <= 0 && + !( left->flags & Overshoot_Top && + x2 - x1 >= ras.precision_half ) ) + return; + + /* lower stub test */ + if ( right->next == left && + left->start == y && + !( left->flags & Overshoot_Bottom && + x2 - x1 >= ras.precision_half ) ) + return; + + if ( dropOutControl == 1 ) + pxl = e2; + else + pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); + break; + + default: /* modes 2, 3, 6, 7 */ + return; /* no drop-out control */ + } + + /* check that the other pixel isn't set */ + e1 = pxl == e1 ? e2 : e1; + + e1 = TRUNC( e1 ); + + c1 = (Short)( e1 >> 3 ); + f1 = (Short)( e1 & 7 ); + + if ( e1 >= 0 && e1 < ras.bWidth && + ras.bTarget[ras.traceOfs + c1] & ( 0x80 >> f1 ) ) + return; + } + else + return; + } + + e1 = TRUNC( pxl ); + + if ( e1 >= 0 && e1 < ras.bWidth ) + { + c1 = (Short)( e1 >> 3 ); + f1 = (Short)( e1 & 7 ); + + if ( ras.gray_min_x > c1 ) + ras.gray_min_x = c1; + if ( ras.gray_max_x < c1 ) + ras.gray_max_x = c1; + + ras.bTarget[ras.traceOfs + c1] |= (char)( 0x80 >> f1 ); + } + } + + + static void + Vertical_Sweep_Step( RAS_ARG ) + { + ras.traceOfs += ras.traceIncr; + } + + + /***********************************************************************/ + /* */ + /* Horizontal Sweep Procedure Set */ + /* */ + /* These four routines are used during the horizontal black/white */ + /* sweep phase by the generic Draw_Sweep() function. */ + /* */ + /***********************************************************************/ + + static void + Horizontal_Sweep_Init( RAS_ARGS Short* min, + Short* max ) + { + /* nothing, really */ + FT_UNUSED_RASTER; + FT_UNUSED( min ); + FT_UNUSED( max ); + } + + + static void + Horizontal_Sweep_Span( RAS_ARGS Short y, + FT_F26Dot6 x1, + FT_F26Dot6 x2, + PProfile left, + PProfile right ) + { + Long e1, e2; + PByte bits; + Byte f1; + + FT_UNUSED( left ); + FT_UNUSED( right ); + + + if ( x2 - x1 < ras.precision ) + { + e1 = CEILING( x1 ); + e2 = FLOOR ( x2 ); + + if ( e1 == e2 ) + { + bits = ras.bTarget + ( y >> 3 ); + f1 = (Byte)( 0x80 >> ( y & 7 ) ); + + e1 = TRUNC( e1 ); + + if ( e1 >= 0 && e1 < ras.target.rows ) + { + PByte p; + + + p = bits - e1*ras.target.pitch; + if ( ras.target.pitch > 0 ) + p += ( ras.target.rows - 1 ) * ras.target.pitch; + + p[0] |= f1; + } + } + } + } + + + static void + Horizontal_Sweep_Drop( RAS_ARGS Short y, + FT_F26Dot6 x1, + FT_F26Dot6 x2, + PProfile left, + PProfile right ) + { + Long e1, e2, pxl; + PByte bits; + Byte f1; + + + /* During the horizontal sweep, we only take care of drop-outs */ + + /* e1 + <-- pixel center */ + /* | */ + /* x1 ---+--> <-- contour */ + /* | */ + /* | */ + /* x2 <--+--- <-- contour */ + /* | */ + /* | */ + /* e2 + <-- pixel center */ + + e1 = CEILING( x1 ); + e2 = FLOOR ( x2 ); + pxl = e1; + + if ( e1 > e2 ) + { + Int dropOutControl = left->flags & 7; + + + if ( e1 == e2 + ras.precision ) + { + switch ( dropOutControl ) + { + case 0: /* simple drop-outs including stubs */ + pxl = e2; + break; + + case 4: /* smart drop-outs including stubs */ + pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); + break; + + case 1: /* simple drop-outs excluding stubs */ + case 5: /* smart drop-outs excluding stubs */ + /* see Vertical_Sweep_Drop for details */ + + /* rightmost stub test */ + if ( left->next == right && + left->height <= 0 && + !( left->flags & Overshoot_Top && + x2 - x1 >= ras.precision_half ) ) + return; + + /* leftmost stub test */ + if ( right->next == left && + left->start == y && + !( left->flags & Overshoot_Bottom && + x2 - x1 >= ras.precision_half ) ) + return; + + if ( dropOutControl == 1 ) + pxl = e2; + else + pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); + break; + + default: /* modes 2, 3, 6, 7 */ + return; /* no drop-out control */ + } + + /* check that the other pixel isn't set */ + e1 = pxl == e1 ? e2 : e1; + + e1 = TRUNC( e1 ); + + bits = ras.bTarget + ( y >> 3 ); + f1 = (Byte)( 0x80 >> ( y & 7 ) ); + + bits -= e1 * ras.target.pitch; + if ( ras.target.pitch > 0 ) + bits += ( ras.target.rows - 1 ) * ras.target.pitch; + + if ( e1 >= 0 && + e1 < ras.target.rows && + *bits & f1 ) + return; + } + else + return; + } + + bits = ras.bTarget + ( y >> 3 ); + f1 = (Byte)( 0x80 >> ( y & 7 ) ); + + e1 = TRUNC( pxl ); + + if ( e1 >= 0 && e1 < ras.target.rows ) + { + bits -= e1 * ras.target.pitch; + if ( ras.target.pitch > 0 ) + bits += ( ras.target.rows - 1 ) * ras.target.pitch; + + bits[0] |= f1; + } + } + + + static void + Horizontal_Sweep_Step( RAS_ARG ) + { + /* Nothing, really */ + FT_UNUSED_RASTER; + } + + +#ifdef FT_RASTER_OPTION_ANTI_ALIASING + + + /*************************************************************************/ + /* */ + /* Vertical Gray Sweep Procedure Set */ + /* */ + /* These two routines are used during the vertical gray-levels sweep */ + /* phase by the generic Draw_Sweep() function. */ + /* */ + /* NOTES */ + /* */ + /* - The target pixmap's width *must* be a multiple of 4. */ + /* */ + /* - You have to use the function Vertical_Sweep_Span() for the gray */ + /* span call. */ + /* */ + /*************************************************************************/ + + static void + Vertical_Gray_Sweep_Init( RAS_ARGS Short* min, + Short* max ) + { + Long pitch, byte_len; + + + *min = *min & -2; + *max = ( *max + 3 ) & -2; + + ras.traceOfs = 0; + pitch = ras.target.pitch; + byte_len = -pitch; + ras.traceIncr = (Short)byte_len; + ras.traceG = ( *min / 2 ) * byte_len; + + if ( pitch > 0 ) + { + ras.traceG += ( ras.target.rows - 1 ) * pitch; + byte_len = -byte_len; + } + + ras.gray_min_x = (Short)byte_len; + ras.gray_max_x = -(Short)byte_len; + } + + + static void + Vertical_Gray_Sweep_Step( RAS_ARG ) + { + Int c1, c2; + PByte pix, bit, bit2; + short* count = (short*)count_table; + Byte* grays; + + + ras.traceOfs += ras.gray_width; + + if ( ras.traceOfs > ras.gray_width ) + { + pix = ras.gTarget + ras.traceG + ras.gray_min_x * 4; + grays = ras.grays; + + if ( ras.gray_max_x >= 0 ) + { + Long last_pixel = ras.target.width - 1; + Int last_cell = last_pixel >> 2; + Int last_bit = last_pixel & 3; + Bool over = 0; + + + if ( ras.gray_max_x >= last_cell && last_bit != 3 ) + { + ras.gray_max_x = last_cell - 1; + over = 1; + } + + if ( ras.gray_min_x < 0 ) + ras.gray_min_x = 0; + + bit = ras.bTarget + ras.gray_min_x; + bit2 = bit + ras.gray_width; + + c1 = ras.gray_max_x - ras.gray_min_x; + + while ( c1 >= 0 ) + { + c2 = count[*bit] + count[*bit2]; + + if ( c2 ) + { + pix[0] = grays[(c2 >> 12) & 0x000F]; + pix[1] = grays[(c2 >> 8 ) & 0x000F]; + pix[2] = grays[(c2 >> 4 ) & 0x000F]; + pix[3] = grays[ c2 & 0x000F]; + + *bit = 0; + *bit2 = 0; + } + + bit++; + bit2++; + pix += 4; + c1--; + } + + if ( over ) + { + c2 = count[*bit] + count[*bit2]; + if ( c2 ) + { + switch ( last_bit ) + { + case 2: + pix[2] = grays[(c2 >> 4 ) & 0x000F]; + case 1: + pix[1] = grays[(c2 >> 8 ) & 0x000F]; + default: + pix[0] = grays[(c2 >> 12) & 0x000F]; + } + + *bit = 0; + *bit2 = 0; + } + } + } + + ras.traceOfs = 0; + ras.traceG += ras.traceIncr; + + ras.gray_min_x = 32000; + ras.gray_max_x = -32000; + } + } + + + static void + Horizontal_Gray_Sweep_Span( RAS_ARGS Short y, + FT_F26Dot6 x1, + FT_F26Dot6 x2, + PProfile left, + PProfile right ) + { + /* nothing, really */ + FT_UNUSED_RASTER; + FT_UNUSED( y ); + FT_UNUSED( x1 ); + FT_UNUSED( x2 ); + FT_UNUSED( left ); + FT_UNUSED( right ); + } + + + static void + Horizontal_Gray_Sweep_Drop( RAS_ARGS Short y, + FT_F26Dot6 x1, + FT_F26Dot6 x2, + PProfile left, + PProfile right ) + { + Long e1, e2; + PByte pixel; + Byte color; + + + /* During the horizontal sweep, we only take care of drop-outs */ + + e1 = CEILING( x1 ); + e2 = FLOOR ( x2 ); + + if ( e1 > e2 ) + { + Int dropOutControl = left->flags & 7; + + + if ( e1 == e2 + ras.precision ) + { + switch ( dropOutControl ) + { + case 0: /* simple drop-outs including stubs */ + e1 = e2; + break; + + case 4: /* smart drop-outs including stubs */ + e1 = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); + break; + + case 1: /* simple drop-outs excluding stubs */ + case 5: /* smart drop-outs excluding stubs */ + /* see Vertical_Sweep_Drop for details */ + + /* rightmost stub test */ + if ( left->next == right && left->height <= 0 ) + return; + + /* leftmost stub test */ + if ( right->next == left && left->start == y ) + return; + + if ( dropOutControl == 1 ) + e1 = e2; + else + e1 = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); + + break; + + default: /* modes 2, 3, 6, 7 */ + return; /* no drop-out control */ + } + } + else + return; + } + + if ( e1 >= 0 ) + { + if ( x2 - x1 >= ras.precision_half ) + color = ras.grays[2]; + else + color = ras.grays[1]; + + e1 = TRUNC( e1 ) / 2; + if ( e1 < ras.target.rows ) + { + pixel = ras.gTarget - e1 * ras.target.pitch + y / 2; + if ( ras.target.pitch > 0 ) + pixel += ( ras.target.rows - 1 ) * ras.target.pitch; + + if ( pixel[0] == ras.grays[0] ) + pixel[0] = color; + } + } + } + + +#endif /* FT_RASTER_OPTION_ANTI_ALIASING */ + + + /*************************************************************************/ + /* */ + /* Generic Sweep Drawing routine */ + /* */ + /*************************************************************************/ + + static Bool + Draw_Sweep( RAS_ARG ) + { + Short y, y_change, y_height; + + PProfile P, Q, P_Left, P_Right; + + Short min_Y, max_Y, top, bottom, dropouts; + + Long x1, x2, xs, e1, e2; + + TProfileList waiting; + TProfileList draw_left, draw_right; + + + /* initialize empty linked lists */ + + Init_Linked( &waiting ); + + Init_Linked( &draw_left ); + Init_Linked( &draw_right ); + + /* first, compute min and max Y */ + + P = ras.fProfile; + max_Y = (Short)TRUNC( ras.minY ); + min_Y = (Short)TRUNC( ras.maxY ); + + while ( P ) + { + Q = P->link; + + bottom = (Short)P->start; + top = (Short)( P->start + P->height - 1 ); + + if ( min_Y > bottom ) + min_Y = bottom; + if ( max_Y < top ) + max_Y = top; + + P->X = 0; + InsNew( &waiting, P ); + + P = Q; + } + + /* check the Y-turns */ + if ( ras.numTurns == 0 ) + { + ras.error = Raster_Err_Invalid; + return FAILURE; + } + + /* now initialize the sweep */ + + ras.Proc_Sweep_Init( RAS_VARS &min_Y, &max_Y ); + + /* then compute the distance of each profile from min_Y */ + + P = waiting; + + while ( P ) + { + P->countL = (UShort)( P->start - min_Y ); + P = P->link; + } + + /* let's go */ + + y = min_Y; + y_height = 0; + + if ( ras.numTurns > 0 && + ras.sizeBuff[-ras.numTurns] == min_Y ) + ras.numTurns--; + + while ( ras.numTurns > 0 ) + { + /* check waiting list for new activations */ + + P = waiting; + + while ( P ) + { + Q = P->link; + P->countL -= y_height; + if ( P->countL == 0 ) + { + DelOld( &waiting, P ); + + if ( P->flags & Flow_Up ) + InsNew( &draw_left, P ); + else + InsNew( &draw_right, P ); + } + + P = Q; + } + + /* sort the drawing lists */ + + Sort( &draw_left ); + Sort( &draw_right ); + + y_change = (Short)ras.sizeBuff[-ras.numTurns--]; + y_height = (Short)( y_change - y ); + + while ( y < y_change ) + { + /* let's trace */ + + dropouts = 0; + + P_Left = draw_left; + P_Right = draw_right; + + while ( P_Left ) + { + x1 = P_Left ->X; + x2 = P_Right->X; + + if ( x1 > x2 ) + { + xs = x1; + x1 = x2; + x2 = xs; + } + + e1 = FLOOR( x1 ); + e2 = CEILING( x2 ); + + if ( x2 - x1 <= ras.precision && + e1 != x1 && e2 != x2 ) + { + if ( e1 > e2 || e2 == e1 + ras.precision ) + { + Int dropOutControl = P_Left->flags & 7; + + + if ( dropOutControl != 2 ) + { + /* a drop-out was detected */ + + P_Left ->X = x1; + P_Right->X = x2; + + /* mark profile for drop-out processing */ + P_Left->countL = 1; + dropouts++; + } + + goto Skip_To_Next; + } + } + + ras.Proc_Sweep_Span( RAS_VARS y, x1, x2, P_Left, P_Right ); + + Skip_To_Next: + + P_Left = P_Left->link; + P_Right = P_Right->link; + } + + /* handle drop-outs _after_ the span drawing -- */ + /* drop-out processing has been moved out of the loop */ + /* for performance tuning */ + if ( dropouts > 0 ) + goto Scan_DropOuts; + + Next_Line: + + ras.Proc_Sweep_Step( RAS_VAR ); + + y++; + + if ( y < y_change ) + { + Sort( &draw_left ); + Sort( &draw_right ); + } + } + + /* now finalize the profiles that need it */ + + P = draw_left; + while ( P ) + { + Q = P->link; + if ( P->height == 0 ) + DelOld( &draw_left, P ); + P = Q; + } + + P = draw_right; + while ( P ) + { + Q = P->link; + if ( P->height == 0 ) + DelOld( &draw_right, P ); + P = Q; + } + } + + /* for gray-scaling, flush the bitmap scanline cache */ + while ( y <= max_Y ) + { + ras.Proc_Sweep_Step( RAS_VAR ); + y++; + } + + return SUCCESS; + + Scan_DropOuts: + + P_Left = draw_left; + P_Right = draw_right; + + while ( P_Left ) + { + if ( P_Left->countL ) + { + P_Left->countL = 0; +#if 0 + dropouts--; /* -- this is useful when debugging only */ +#endif + ras.Proc_Sweep_Drop( RAS_VARS y, + P_Left->X, + P_Right->X, + P_Left, + P_Right ); + } + + P_Left = P_Left->link; + P_Right = P_Right->link; + } + + goto Next_Line; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Render_Single_Pass */ + /* */ + /* <Description> */ + /* Perform one sweep with sub-banding. */ + /* */ + /* <Input> */ + /* flipped :: If set, flip the direction of the outline. */ + /* */ + /* <Return> */ + /* Renderer error code. */ + /* */ + static int + Render_Single_Pass( RAS_ARGS Bool flipped ) + { + Short i, j, k; + + + while ( ras.band_top >= 0 ) + { + ras.maxY = (Long)ras.band_stack[ras.band_top].y_max * ras.precision; + ras.minY = (Long)ras.band_stack[ras.band_top].y_min * ras.precision; + + ras.top = ras.buff; + + ras.error = Raster_Err_None; + + if ( Convert_Glyph( RAS_VARS flipped ) ) + { + if ( ras.error != Raster_Err_Overflow ) + return FAILURE; + + ras.error = Raster_Err_None; + + /* sub-banding */ + +#ifdef DEBUG_RASTER + ClearBand( RAS_VARS TRUNC( ras.minY ), TRUNC( ras.maxY ) ); +#endif + + i = ras.band_stack[ras.band_top].y_min; + j = ras.band_stack[ras.band_top].y_max; + + k = (Short)( ( i + j ) / 2 ); + + if ( ras.band_top >= 7 || k < i ) + { + ras.band_top = 0; + ras.error = Raster_Err_Invalid; + + return ras.error; + } + + ras.band_stack[ras.band_top + 1].y_min = k; + ras.band_stack[ras.band_top + 1].y_max = j; + + ras.band_stack[ras.band_top].y_max = (Short)( k - 1 ); + + ras.band_top++; + } + else + { + if ( ras.fProfile ) + if ( Draw_Sweep( RAS_VAR ) ) + return ras.error; + ras.band_top--; + } + } + + return SUCCESS; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Render_Glyph */ + /* */ + /* <Description> */ + /* Render a glyph in a bitmap. Sub-banding if needed. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + Render_Glyph( RAS_ARG ) + { + FT_Error error; + + + Set_High_Precision( RAS_VARS ras.outline.flags & + FT_OUTLINE_HIGH_PRECISION ); + ras.scale_shift = ras.precision_shift; + + if ( ras.outline.flags & FT_OUTLINE_IGNORE_DROPOUTS ) + ras.dropOutControl = 2; + else + { + if ( ras.outline.flags & FT_OUTLINE_SMART_DROPOUTS ) + ras.dropOutControl = 4; + else + ras.dropOutControl = 0; + + if ( !( ras.outline.flags & FT_OUTLINE_INCLUDE_STUBS ) ) + ras.dropOutControl += 1; + } + + ras.second_pass = (FT_Byte)( !( ras.outline.flags & + FT_OUTLINE_SINGLE_PASS ) ); + + /* Vertical Sweep */ + ras.Proc_Sweep_Init = Vertical_Sweep_Init; + ras.Proc_Sweep_Span = Vertical_Sweep_Span; + ras.Proc_Sweep_Drop = Vertical_Sweep_Drop; + ras.Proc_Sweep_Step = Vertical_Sweep_Step; + + ras.band_top = 0; + ras.band_stack[0].y_min = 0; + ras.band_stack[0].y_max = (short)( ras.target.rows - 1 ); + + ras.bWidth = (unsigned short)ras.target.width; + ras.bTarget = (Byte*)ras.target.buffer; + + if ( ( error = Render_Single_Pass( RAS_VARS 0 ) ) != 0 ) + return error; + + /* Horizontal Sweep */ + if ( ras.second_pass && ras.dropOutControl != 2 ) + { + ras.Proc_Sweep_Init = Horizontal_Sweep_Init; + ras.Proc_Sweep_Span = Horizontal_Sweep_Span; + ras.Proc_Sweep_Drop = Horizontal_Sweep_Drop; + ras.Proc_Sweep_Step = Horizontal_Sweep_Step; + + ras.band_top = 0; + ras.band_stack[0].y_min = 0; + ras.band_stack[0].y_max = (short)( ras.target.width - 1 ); + + if ( ( error = Render_Single_Pass( RAS_VARS 1 ) ) != 0 ) + return error; + } + + return Raster_Err_None; + } + + +#ifdef FT_RASTER_OPTION_ANTI_ALIASING + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Render_Gray_Glyph */ + /* */ + /* <Description> */ + /* Render a glyph with grayscaling. Sub-banding if needed. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + Render_Gray_Glyph( RAS_ARG ) + { + Long pixel_width; + FT_Error error; + + + Set_High_Precision( RAS_VARS ras.outline.flags & + FT_OUTLINE_HIGH_PRECISION ); + ras.scale_shift = ras.precision_shift + 1; + + if ( ras.outline.flags & FT_OUTLINE_IGNORE_DROPOUTS ) + ras.dropOutControl = 2; + else + { + if ( ras.outline.flags & FT_OUTLINE_SMART_DROPOUTS ) + ras.dropOutControl = 4; + else + ras.dropOutControl = 0; + + if ( !( ras.outline.flags & FT_OUTLINE_INCLUDE_STUBS ) ) + ras.dropOutControl += 1; + } + + ras.second_pass = !( ras.outline.flags & FT_OUTLINE_SINGLE_PASS ); + + /* Vertical Sweep */ + + ras.band_top = 0; + ras.band_stack[0].y_min = 0; + ras.band_stack[0].y_max = 2 * ras.target.rows - 1; + + ras.bWidth = ras.gray_width; + pixel_width = 2 * ( ( ras.target.width + 3 ) >> 2 ); + + if ( ras.bWidth > pixel_width ) + ras.bWidth = pixel_width; + + ras.bWidth = ras.bWidth * 8; + ras.bTarget = (Byte*)ras.gray_lines; + ras.gTarget = (Byte*)ras.target.buffer; + + ras.Proc_Sweep_Init = Vertical_Gray_Sweep_Init; + ras.Proc_Sweep_Span = Vertical_Sweep_Span; + ras.Proc_Sweep_Drop = Vertical_Sweep_Drop; + ras.Proc_Sweep_Step = Vertical_Gray_Sweep_Step; + + error = Render_Single_Pass( RAS_VARS 0 ); + if ( error ) + return error; + + /* Horizontal Sweep */ + if ( ras.second_pass && ras.dropOutControl != 2 ) + { + ras.Proc_Sweep_Init = Horizontal_Sweep_Init; + ras.Proc_Sweep_Span = Horizontal_Gray_Sweep_Span; + ras.Proc_Sweep_Drop = Horizontal_Gray_Sweep_Drop; + ras.Proc_Sweep_Step = Horizontal_Sweep_Step; + + ras.band_top = 0; + ras.band_stack[0].y_min = 0; + ras.band_stack[0].y_max = ras.target.width * 2 - 1; + + error = Render_Single_Pass( RAS_VARS 1 ); + if ( error ) + return error; + } + + return Raster_Err_None; + } + +#else /* !FT_RASTER_OPTION_ANTI_ALIASING */ + + FT_LOCAL_DEF( FT_Error ) + Render_Gray_Glyph( RAS_ARG ) + { + FT_UNUSED_RASTER; + + return Raster_Err_Unsupported; + } + +#endif /* !FT_RASTER_OPTION_ANTI_ALIASING */ + + + static void + ft_black_init( PRaster raster ) + { +#ifdef FT_RASTER_OPTION_ANTI_ALIASING + FT_UInt n; + + + /* set default 5-levels gray palette */ + for ( n = 0; n < 5; n++ ) + raster->grays[n] = n * 255 / 4; + + raster->gray_width = RASTER_GRAY_LINES / 2; +#else + FT_UNUSED( raster ); +#endif + } + + + /**** RASTER OBJECT CREATION: In standalone mode, we simply use *****/ + /**** a static object. *****/ + + +#ifdef _STANDALONE_ + + + static int + ft_black_new( void* memory, + FT_Raster *araster ) + { + static TRaster the_raster; + + + *araster = (FT_Raster)&the_raster; + FT_MEM_ZERO( &the_raster, sizeof ( the_raster ) ); + ft_black_init( &the_raster ); + + return 0; + } + + + static void + ft_black_done( FT_Raster raster ) + { + /* nothing */ + FT_UNUSED( raster ); + } + + +#else /* _STANDALONE_ */ + + + static int + ft_black_new( FT_Memory memory, + PRaster *araster ) + { + FT_Error error; + PRaster raster; + + + *araster = 0; + if ( !FT_NEW( raster ) ) + { + raster->memory = memory; + ft_black_init( raster ); + + *araster = raster; + } + + return error; + } + + + static void + ft_black_done( PRaster raster ) + { + FT_Memory memory = (FT_Memory)raster->memory; + FT_FREE( raster ); + } + + +#endif /* _STANDALONE_ */ + + + static void + ft_black_reset( PRaster raster, + char* pool_base, + long pool_size ) + { + if ( raster ) + { + if ( pool_base && pool_size >= (long)sizeof(TWorker) + 2048 ) + { + PWorker worker = (PWorker)pool_base; + + + raster->buffer = pool_base + ( (sizeof ( *worker ) + 7 ) & ~7 ); + raster->buffer_size = ( ( pool_base + pool_size ) - + (char*)raster->buffer ) / sizeof ( Long ); + raster->worker = worker; + } + else + { + raster->buffer = NULL; + raster->buffer_size = 0; + raster->worker = NULL; + } + } + } + + + static void + ft_black_set_mode( PRaster raster, + unsigned long mode, + const char* palette ) + { +#ifdef FT_RASTER_OPTION_ANTI_ALIASING + + if ( mode == FT_MAKE_TAG( 'p', 'a', 'l', '5' ) ) + { + /* set 5-levels gray palette */ + raster->grays[0] = palette[0]; + raster->grays[1] = palette[1]; + raster->grays[2] = palette[2]; + raster->grays[3] = palette[3]; + raster->grays[4] = palette[4]; + } + +#else + + FT_UNUSED( raster ); + FT_UNUSED( mode ); + FT_UNUSED( palette ); + +#endif + } + + + static int + ft_black_render( PRaster raster, + const FT_Raster_Params* params ) + { + const FT_Outline* outline = (const FT_Outline*)params->source; + const FT_Bitmap* target_map = params->target; + PWorker worker; + + + if ( !raster || !raster->buffer || !raster->buffer_size ) + return Raster_Err_Not_Ini; + + if ( !outline ) + return Raster_Err_Invalid; + + /* return immediately if the outline is empty */ + if ( outline->n_points == 0 || outline->n_contours <= 0 ) + return Raster_Err_None; + + if ( !outline->contours || !outline->points ) + return Raster_Err_Invalid; + + if ( outline->n_points != + outline->contours[outline->n_contours - 1] + 1 ) + return Raster_Err_Invalid; + + worker = raster->worker; + + /* this version of the raster does not support direct rendering, sorry */ + if ( params->flags & FT_RASTER_FLAG_DIRECT ) + return Raster_Err_Unsupported; + + if ( !target_map ) + return Raster_Err_Invalid; + + /* nothing to do */ + if ( !target_map->width || !target_map->rows ) + return Raster_Err_None; + + if ( !target_map->buffer ) + return Raster_Err_Invalid; + + ras.outline = *outline; + ras.target = *target_map; + + worker->buff = (PLong) raster->buffer; + worker->sizeBuff = worker->buff + + raster->buffer_size / sizeof ( Long ); +#ifdef FT_RASTER_OPTION_ANTI_ALIASING + worker->grays = raster->grays; + worker->gray_width = raster->gray_width; + + FT_MEM_ZERO( worker->gray_lines, worker->gray_width * 2 ); +#endif + + return ( params->flags & FT_RASTER_FLAG_AA ) + ? Render_Gray_Glyph( RAS_VAR ) + : Render_Glyph( RAS_VAR ); + } + + + FT_DEFINE_RASTER_FUNCS( ft_standard_raster, + FT_GLYPH_FORMAT_OUTLINE, + (FT_Raster_New_Func) ft_black_new, + (FT_Raster_Reset_Func) ft_black_reset, + (FT_Raster_Set_Mode_Func)ft_black_set_mode, + (FT_Raster_Render_Func) ft_black_render, + (FT_Raster_Done_Func) ft_black_done + ) + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/raster/ftraster.h b/mod/pub.mod/freetype.mod/src/raster/ftraster.h new file mode 100644 index 0000000..80fe46d --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/raster/ftraster.h @@ -0,0 +1,46 @@ +/***************************************************************************/ +/* */ +/* ftraster.h */ +/* */ +/* The FreeType glyph rasterizer (specification). */ +/* */ +/* Copyright 1996-2001 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used */ +/* modified and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTRASTER_H__ +#define __FTRASTER_H__ + + +#include <ft2build.h> +#include FT_CONFIG_CONFIG_H +#include FT_IMAGE_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* Uncomment the following line if you are using ftraster.c as a */ + /* standalone module, fully independent of FreeType. */ + /* */ +/* #define _STANDALONE_ */ + + FT_EXPORT_VAR( const FT_Raster_Funcs ) ft_standard_raster; + + +FT_END_HEADER + +#endif /* __FTRASTER_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/raster/ftrend1.c b/mod/pub.mod/freetype.mod/src/raster/ftrend1.c new file mode 100644 index 0000000..1ed8af6 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/raster/ftrend1.c @@ -0,0 +1,291 @@ +/***************************************************************************/ +/* */ +/* ftrend1.c */ +/* */ +/* The FreeType glyph rasterizer interface (body). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2005, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H +#include FT_OUTLINE_H +#include "ftrend1.h" +#include "ftraster.h" +#include "rastpic.h" + +#include "rasterrs.h" + + + /* initialize renderer -- init its raster */ + static FT_Error + ft_raster1_init( FT_Renderer render ) + { + FT_Library library = FT_MODULE_LIBRARY( render ); + + + render->clazz->raster_class->raster_reset( render->raster, + library->raster_pool, + library->raster_pool_size ); + + return Raster_Err_Ok; + } + + + /* set render-specific mode */ + static FT_Error + ft_raster1_set_mode( FT_Renderer render, + FT_ULong mode_tag, + FT_Pointer data ) + { + /* we simply pass it to the raster */ + return render->clazz->raster_class->raster_set_mode( render->raster, + mode_tag, + data ); + } + + + /* transform a given glyph image */ + static FT_Error + ft_raster1_transform( FT_Renderer render, + FT_GlyphSlot slot, + const FT_Matrix* matrix, + const FT_Vector* delta ) + { + FT_Error error = Raster_Err_Ok; + + + if ( slot->format != render->glyph_format ) + { + error = Raster_Err_Invalid_Argument; + goto Exit; + } + + if ( matrix ) + FT_Outline_Transform( &slot->outline, matrix ); + + if ( delta ) + FT_Outline_Translate( &slot->outline, delta->x, delta->y ); + + Exit: + return error; + } + + + /* return the glyph's control box */ + static void + ft_raster1_get_cbox( FT_Renderer render, + FT_GlyphSlot slot, + FT_BBox* cbox ) + { + FT_MEM_ZERO( cbox, sizeof ( *cbox ) ); + + if ( slot->format == render->glyph_format ) + FT_Outline_Get_CBox( &slot->outline, cbox ); + } + + + /* convert a slot's glyph image into a bitmap */ + static FT_Error + ft_raster1_render( FT_Renderer render, + FT_GlyphSlot slot, + FT_Render_Mode mode, + const FT_Vector* origin ) + { + FT_Error error; + FT_Outline* outline; + FT_BBox cbox; + FT_UInt width, height, pitch; + FT_Bitmap* bitmap; + FT_Memory memory; + + FT_Raster_Params params; + + + /* check glyph image format */ + if ( slot->format != render->glyph_format ) + { + error = Raster_Err_Invalid_Argument; + goto Exit; + } + + /* check rendering mode */ +#ifndef FT_CONFIG_OPTION_PIC + if ( mode != FT_RENDER_MODE_MONO ) + { + /* raster1 is only capable of producing monochrome bitmaps */ + if ( render->clazz == &ft_raster1_renderer_class ) + return Raster_Err_Cannot_Render_Glyph; + } + else + { + /* raster5 is only capable of producing 5-gray-levels bitmaps */ + if ( render->clazz == &ft_raster5_renderer_class ) + return Raster_Err_Cannot_Render_Glyph; + } +#else /* FT_CONFIG_OPTION_PIC */ + /* When PIC is enabled, we cannot get to the class object */ + /* so instead we check the final character in the class name */ + /* ("raster5" or "raster1"). Yes this is a hack. */ + /* The "correct" thing to do is have different render function */ + /* for each of the classes. */ + if ( mode != FT_RENDER_MODE_MONO ) + { + /* raster1 is only capable of producing monochrome bitmaps */ + if ( render->clazz->root.module_name[6] == '1' ) + return Raster_Err_Cannot_Render_Glyph; + } + else + { + /* raster5 is only capable of producing 5-gray-levels bitmaps */ + if ( render->clazz->root.module_name[6] == '5' ) + return Raster_Err_Cannot_Render_Glyph; + } +#endif /* FT_CONFIG_OPTION_PIC */ + + outline = &slot->outline; + + /* translate the outline to the new origin if needed */ + if ( origin ) + FT_Outline_Translate( outline, origin->x, origin->y ); + + /* compute the control box, and grid fit it */ + FT_Outline_Get_CBox( outline, &cbox ); + + cbox.xMin = FT_PIX_FLOOR( cbox.xMin ); + cbox.yMin = FT_PIX_FLOOR( cbox.yMin ); + cbox.xMax = FT_PIX_CEIL( cbox.xMax ); + cbox.yMax = FT_PIX_CEIL( cbox.yMax ); + + width = (FT_UInt)( ( cbox.xMax - cbox.xMin ) >> 6 ); + height = (FT_UInt)( ( cbox.yMax - cbox.yMin ) >> 6 ); + bitmap = &slot->bitmap; + memory = render->root.memory; + + /* release old bitmap buffer */ + if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) + { + FT_FREE( bitmap->buffer ); + slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; + } + + /* allocate new one, depends on pixel format */ + if ( !( mode & FT_RENDER_MODE_MONO ) ) + { + /* we pad to 32 bits, only for backwards compatibility with FT 1.x */ + pitch = FT_PAD_CEIL( width, 4 ); + bitmap->pixel_mode = FT_PIXEL_MODE_GRAY; + bitmap->num_grays = 256; + } + else + { + pitch = ( ( width + 15 ) >> 4 ) << 1; + bitmap->pixel_mode = FT_PIXEL_MODE_MONO; + } + + bitmap->width = width; + bitmap->rows = height; + bitmap->pitch = pitch; + + if ( FT_ALLOC_MULT( bitmap->buffer, pitch, height ) ) + goto Exit; + + slot->internal->flags |= FT_GLYPH_OWN_BITMAP; + + /* translate outline to render it into the bitmap */ + FT_Outline_Translate( outline, -cbox.xMin, -cbox.yMin ); + + /* set up parameters */ + params.target = bitmap; + params.source = outline; + params.flags = 0; + + if ( bitmap->pixel_mode == FT_PIXEL_MODE_GRAY ) + params.flags |= FT_RASTER_FLAG_AA; + + /* render outline into the bitmap */ + error = render->raster_render( render->raster, ¶ms ); + + FT_Outline_Translate( outline, cbox.xMin, cbox.yMin ); + + if ( error ) + goto Exit; + + slot->format = FT_GLYPH_FORMAT_BITMAP; + slot->bitmap_left = (FT_Int)( cbox.xMin >> 6 ); + slot->bitmap_top = (FT_Int)( cbox.yMax >> 6 ); + + Exit: + return error; + } + + + FT_DEFINE_RENDERER(ft_raster1_renderer_class, + + FT_MODULE_RENDERER, + sizeof( FT_RendererRec ), + + "raster1", + 0x10000L, + 0x20000L, + + 0, /* module specific interface */ + + (FT_Module_Constructor)ft_raster1_init, + (FT_Module_Destructor) 0, + (FT_Module_Requester) 0 + , + + FT_GLYPH_FORMAT_OUTLINE, + + (FT_Renderer_RenderFunc) ft_raster1_render, + (FT_Renderer_TransformFunc)ft_raster1_transform, + (FT_Renderer_GetCBoxFunc) ft_raster1_get_cbox, + (FT_Renderer_SetModeFunc) ft_raster1_set_mode, + + (FT_Raster_Funcs*) &FT_STANDARD_RASTER_GET + ) + + + /* This renderer is _NOT_ part of the default modules; you will need */ + /* to register it by hand in your application. It should only be */ + /* used for backwards-compatibility with FT 1.x anyway. */ + /* */ + FT_DEFINE_RENDERER(ft_raster5_renderer_class, + + + FT_MODULE_RENDERER, + sizeof( FT_RendererRec ), + + "raster5", + 0x10000L, + 0x20000L, + + 0, /* module specific interface */ + + (FT_Module_Constructor)ft_raster1_init, + (FT_Module_Destructor) 0, + (FT_Module_Requester) 0 + , + + FT_GLYPH_FORMAT_OUTLINE, + + (FT_Renderer_RenderFunc) ft_raster1_render, + (FT_Renderer_TransformFunc)ft_raster1_transform, + (FT_Renderer_GetCBoxFunc) ft_raster1_get_cbox, + (FT_Renderer_SetModeFunc) ft_raster1_set_mode, + + (FT_Raster_Funcs*) &FT_STANDARD_RASTER_GET + ) + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/raster/ftrend1.h b/mod/pub.mod/freetype.mod/src/raster/ftrend1.h new file mode 100644 index 0000000..4cf1286 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/raster/ftrend1.h @@ -0,0 +1,44 @@ +/***************************************************************************/ +/* */ +/* ftrend1.h */ +/* */ +/* The FreeType glyph rasterizer interface (specification). */ +/* */ +/* Copyright 1996-2001 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTREND1_H__ +#define __FTREND1_H__ + + +#include <ft2build.h> +#include FT_RENDER_H + + +FT_BEGIN_HEADER + + + FT_DECLARE_RENDERER( ft_raster1_renderer_class ) + + /* this renderer is _NOT_ part of the default modules, you'll need */ + /* to register it by hand in your application. It should only be */ + /* used for backwards-compatibility with FT 1.x anyway. */ + /* */ + FT_DECLARE_RENDERER( ft_raster5_renderer_class ) + + +FT_END_HEADER + +#endif /* __FTREND1_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/raster/raster.c b/mod/pub.mod/freetype.mod/src/raster/raster.c new file mode 100644 index 0000000..1202a11 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/raster/raster.c @@ -0,0 +1,27 @@ +/***************************************************************************/ +/* */ +/* raster.c */ +/* */ +/* FreeType monochrome rasterer module component (body only). */ +/* */ +/* Copyright 1996-2001 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#define FT_MAKE_OPTION_SINGLE_OBJECT + +#include <ft2build.h> +#include "rastpic.c" +#include "ftraster.c" +#include "ftrend1.c" + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/raster/rasterrs.h b/mod/pub.mod/freetype.mod/src/raster/rasterrs.h new file mode 100644 index 0000000..5df9a7a --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/raster/rasterrs.h @@ -0,0 +1,41 @@ +/***************************************************************************/ +/* */ +/* rasterrs.h */ +/* */ +/* monochrome renderer error codes (specification only). */ +/* */ +/* Copyright 2001 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file is used to define the monochrome renderer error enumeration */ + /* constants. */ + /* */ + /*************************************************************************/ + +#ifndef __RASTERRS_H__ +#define __RASTERRS_H__ + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#define FT_ERR_PREFIX Raster_Err_ +#define FT_ERR_BASE FT_Mod_Err_Raster + +#include FT_ERRORS_H + +#endif /* __RASTERRS_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/raster/rastpic.c b/mod/pub.mod/freetype.mod/src/raster/rastpic.c new file mode 100644 index 0000000..3c26487 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/raster/rastpic.c @@ -0,0 +1,89 @@ +/***************************************************************************/ +/* */ +/* rastpic.c */ +/* */ +/* The FreeType position independent code services for raster module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include "rastpic.h" + +#ifdef FT_CONFIG_OPTION_PIC + + /* forward declaration of PIC init functions from ftraster.c */ + void FT_Init_Class_ft_standard_raster(FT_Raster_Funcs*); + + void + ft_raster1_renderer_class_pic_free( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Memory memory = library->memory; + if ( pic_container->raster ) + { + RasterPIC* container = (RasterPIC*)pic_container->raster; + if(--container->ref_count) + return; + FT_FREE( container ); + pic_container->raster = NULL; + } + } + + + FT_Error + ft_raster1_renderer_class_pic_init( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Error error = FT_Err_Ok; + RasterPIC* container; + FT_Memory memory = library->memory; + + /* since this function also serve raster5 renderer, + it implements reference counting */ + if(pic_container->raster) + { + ((RasterPIC*)pic_container->raster)->ref_count++; + return error; + } + + /* allocate pointer, clear and set global container pointer */ + if ( FT_ALLOC ( container, sizeof ( *container ) ) ) + return error; + FT_MEM_SET( container, 0, sizeof(*container) ); + pic_container->raster = container; + container->ref_count = 1; + + /* initialize pointer table - this is how the module usually expects this data */ + FT_Init_Class_ft_standard_raster(&container->ft_standard_raster); +/*Exit:*/ + if(error) + ft_raster1_renderer_class_pic_free(library); + return error; + } + + /* re-route these init and free functions to the above functions */ + FT_Error ft_raster5_renderer_class_pic_init(FT_Library library) + { + return ft_raster1_renderer_class_pic_init(library); + } + void ft_raster5_renderer_class_pic_free(FT_Library library) + { + ft_raster1_renderer_class_pic_free(library); + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/raster/rastpic.h b/mod/pub.mod/freetype.mod/src/raster/rastpic.h new file mode 100644 index 0000000..dcd82b8 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/raster/rastpic.h @@ -0,0 +1,50 @@ +/***************************************************************************/ +/* */ +/* rastpic.h */ +/* */ +/* The FreeType position independent code services for raster module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __RASTPIC_H__ +#define __RASTPIC_H__ + + +FT_BEGIN_HEADER + +#include FT_INTERNAL_PIC_H + +#ifndef FT_CONFIG_OPTION_PIC +#define FT_STANDARD_RASTER_GET ft_standard_raster + +#else /* FT_CONFIG_OPTION_PIC */ + + typedef struct RasterPIC_ + { + int ref_count; + FT_Raster_Funcs ft_standard_raster; + } RasterPIC; + +#define GET_PIC(lib) ((RasterPIC*)((lib)->pic_container.raster)) +#define FT_STANDARD_RASTER_GET (GET_PIC(library)->ft_standard_raster) + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + +FT_END_HEADER + +#endif /* __RASTPIC_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/sfnt/sfdriver.c b/mod/pub.mod/freetype.mod/src/sfnt/sfdriver.c new file mode 100644 index 0000000..1d157b7 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/sfnt/sfdriver.c @@ -0,0 +1,653 @@ +/***************************************************************************/ +/* */ +/* sfdriver.c */ +/* */ +/* High-level SFNT driver interface (body). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_SFNT_H +#include FT_INTERNAL_OBJECTS_H + +#include "sfdriver.h" +#include "ttload.h" +#include "sfobjs.h" +#include "sfntpic.h" + +#include "sferrors.h" + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS +#include "ttsbit.h" +#endif + +#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES +#include "ttpost.h" +#endif + +#ifdef TT_CONFIG_OPTION_BDF +#include "ttbdf.h" +#include FT_SERVICE_BDF_H +#endif + +#include "ttcmap.h" +#include "ttkern.h" +#include "ttmtx.h" + +#include FT_SERVICE_GLYPH_DICT_H +#include FT_SERVICE_POSTSCRIPT_NAME_H +#include FT_SERVICE_SFNT_H +#include FT_SERVICE_TT_CMAP_H + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_sfdriver + + + /* + * SFNT TABLE SERVICE + * + */ + + static void* + get_sfnt_table( TT_Face face, + FT_Sfnt_Tag tag ) + { + void* table; + + + switch ( tag ) + { + case ft_sfnt_head: + table = &face->header; + break; + + case ft_sfnt_hhea: + table = &face->horizontal; + break; + + case ft_sfnt_vhea: + table = face->vertical_info ? &face->vertical : 0; + break; + + case ft_sfnt_os2: + table = face->os2.version == 0xFFFFU ? 0 : &face->os2; + break; + + case ft_sfnt_post: + table = &face->postscript; + break; + + case ft_sfnt_maxp: + table = &face->max_profile; + break; + + case ft_sfnt_pclt: + table = face->pclt.Version ? &face->pclt : 0; + break; + + default: + table = 0; + } + + return table; + } + + + static FT_Error + sfnt_table_info( TT_Face face, + FT_UInt idx, + FT_ULong *tag, + FT_ULong *offset, + FT_ULong *length ) + { + if ( !tag || !offset || !length ) + return SFNT_Err_Invalid_Argument; + + if ( idx >= face->num_tables ) + return SFNT_Err_Table_Missing; + + *tag = face->dir_tables[idx].Tag; + *offset = face->dir_tables[idx].Offset; + *length = face->dir_tables[idx].Length; + + return SFNT_Err_Ok; + } + + + FT_DEFINE_SERVICE_SFNT_TABLEREC(sfnt_service_sfnt_table, + (FT_SFNT_TableLoadFunc)tt_face_load_any, + (FT_SFNT_TableGetFunc) get_sfnt_table, + (FT_SFNT_TableInfoFunc)sfnt_table_info + ) + + +#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES + + /* + * GLYPH DICT SERVICE + * + */ + + static FT_Error + sfnt_get_glyph_name( TT_Face face, + FT_UInt glyph_index, + FT_Pointer buffer, + FT_UInt buffer_max ) + { + FT_String* gname; + FT_Error error; + + + error = tt_face_get_ps_name( face, glyph_index, &gname ); + if ( !error ) + FT_STRCPYN( buffer, gname, buffer_max ); + + return error; + } + + + static FT_UInt + sfnt_get_name_index( TT_Face face, + FT_String* glyph_name ) + { + FT_Face root = &face->root; + FT_UInt i, max_gid = FT_UINT_MAX; + + + if ( root->num_glyphs < 0 ) + return 0; + else if ( ( FT_ULong ) root->num_glyphs < FT_UINT_MAX ) + max_gid = ( FT_UInt ) root->num_glyphs; + else + FT_TRACE0(( "Ignore glyph names for invalid GID 0x%08x - 0x%08x\n", + FT_UINT_MAX, root->num_glyphs )); + + for ( i = 0; i < max_gid; i++ ) + { + FT_String* gname; + FT_Error error = tt_face_get_ps_name( face, i, &gname ); + + + if ( error ) + continue; + + if ( !ft_strcmp( glyph_name, gname ) ) + return i; + } + + return 0; + } + + + FT_DEFINE_SERVICE_GLYPHDICTREC(sfnt_service_glyph_dict, + (FT_GlyphDict_GetNameFunc) sfnt_get_glyph_name, + (FT_GlyphDict_NameIndexFunc)sfnt_get_name_index + ) + +#endif /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */ + + + /* + * POSTSCRIPT NAME SERVICE + * + */ + + static const char* + sfnt_get_ps_name( TT_Face face ) + { + FT_Int n, found_win, found_apple; + const char* result = NULL; + + + /* shouldn't happen, but just in case to avoid memory leaks */ + if ( face->postscript_name ) + return face->postscript_name; + + /* scan the name table to see whether we have a Postscript name here, */ + /* either in Macintosh or Windows platform encodings */ + found_win = -1; + found_apple = -1; + + for ( n = 0; n < face->num_names; n++ ) + { + TT_NameEntryRec* name = face->name_table.names + n; + + + if ( name->nameID == 6 && name->stringLength > 0 ) + { + if ( name->platformID == 3 && + name->encodingID == 1 && + name->languageID == 0x409 ) + found_win = n; + + if ( name->platformID == 1 && + name->encodingID == 0 && + name->languageID == 0 ) + found_apple = n; + } + } + + if ( found_win != -1 ) + { + FT_Memory memory = face->root.memory; + TT_NameEntryRec* name = face->name_table.names + found_win; + FT_UInt len = name->stringLength / 2; + FT_Error error = SFNT_Err_Ok; + + FT_UNUSED( error ); + + + if ( !FT_ALLOC( result, name->stringLength + 1 ) ) + { + FT_Stream stream = face->name_table.stream; + FT_String* r = (FT_String*)result; + FT_Byte* p = (FT_Byte*)name->string; + + + if ( FT_STREAM_SEEK( name->stringOffset ) || + FT_FRAME_ENTER( name->stringLength ) ) + { + FT_FREE( result ); + name->stringLength = 0; + name->stringOffset = 0; + FT_FREE( name->string ); + + goto Exit; + } + + p = (FT_Byte*)stream->cursor; + + for ( ; len > 0; len--, p += 2 ) + { + if ( p[0] == 0 && p[1] >= 32 && p[1] < 128 ) + *r++ = p[1]; + } + *r = '\0'; + + FT_FRAME_EXIT(); + } + goto Exit; + } + + if ( found_apple != -1 ) + { + FT_Memory memory = face->root.memory; + TT_NameEntryRec* name = face->name_table.names + found_apple; + FT_UInt len = name->stringLength; + FT_Error error = SFNT_Err_Ok; + + FT_UNUSED( error ); + + + if ( !FT_ALLOC( result, len + 1 ) ) + { + FT_Stream stream = face->name_table.stream; + + + if ( FT_STREAM_SEEK( name->stringOffset ) || + FT_STREAM_READ( result, len ) ) + { + name->stringOffset = 0; + name->stringLength = 0; + FT_FREE( name->string ); + FT_FREE( result ); + goto Exit; + } + ((char*)result)[len] = '\0'; + } + } + + Exit: + face->postscript_name = result; + return result; + } + + FT_DEFINE_SERVICE_PSFONTNAMEREC(sfnt_service_ps_name, + (FT_PsName_GetFunc)sfnt_get_ps_name + ) + + + /* + * TT CMAP INFO + */ + FT_DEFINE_SERVICE_TTCMAPSREC(tt_service_get_cmap_info, + (TT_CMap_Info_GetFunc)tt_get_cmap_info + ) + + +#ifdef TT_CONFIG_OPTION_BDF + + static FT_Error + sfnt_get_charset_id( TT_Face face, + const char* *acharset_encoding, + const char* *acharset_registry ) + { + BDF_PropertyRec encoding, registry; + FT_Error error; + + + /* XXX: I don't know whether this is correct, since + * tt_face_find_bdf_prop only returns something correct if we have + * previously selected a size that is listed in the BDF table. + * Should we change the BDF table format to include single offsets + * for `CHARSET_REGISTRY' and `CHARSET_ENCODING'? + */ + error = tt_face_find_bdf_prop( face, "CHARSET_REGISTRY", ®istry ); + if ( !error ) + { + error = tt_face_find_bdf_prop( face, "CHARSET_ENCODING", &encoding ); + if ( !error ) + { + if ( registry.type == BDF_PROPERTY_TYPE_ATOM && + encoding.type == BDF_PROPERTY_TYPE_ATOM ) + { + *acharset_encoding = encoding.u.atom; + *acharset_registry = registry.u.atom; + } + else + error = FT_Err_Invalid_Argument; + } + } + + return error; + } + + + FT_DEFINE_SERVICE_BDFRec(sfnt_service_bdf, + (FT_BDF_GetCharsetIdFunc) sfnt_get_charset_id, + (FT_BDF_GetPropertyFunc) tt_face_find_bdf_prop + ) + +#endif /* TT_CONFIG_OPTION_BDF */ + + + /* + * SERVICE LIST + */ + +#if defined TT_CONFIG_OPTION_POSTSCRIPT_NAMES && defined TT_CONFIG_OPTION_BDF + FT_DEFINE_SERVICEDESCREC5(sfnt_services, + FT_SERVICE_ID_SFNT_TABLE, &FT_SFNT_SERVICE_SFNT_TABLE_GET, + FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_SFNT_SERVICE_PS_NAME_GET, + FT_SERVICE_ID_GLYPH_DICT, &FT_SFNT_SERVICE_GLYPH_DICT_GET, + FT_SERVICE_ID_BDF, &FT_SFNT_SERVICE_BDF_GET, + FT_SERVICE_ID_TT_CMAP, &FT_TT_SERVICE_GET_CMAP_INFO_GET + ) +#elif defined TT_CONFIG_OPTION_POSTSCRIPT_NAMES + FT_DEFINE_SERVICEDESCREC4(sfnt_services, + FT_SERVICE_ID_SFNT_TABLE, &FT_SFNT_SERVICE_SFNT_TABLE_GET, + FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_SFNT_SERVICE_PS_NAME_GET, + FT_SERVICE_ID_GLYPH_DICT, &FT_SFNT_SERVICE_GLYPH_DICT_GET, + FT_SERVICE_ID_TT_CMAP, &FT_TT_SERVICE_GET_CMAP_INFO_GET + ) +#elif defined TT_CONFIG_OPTION_BDF + FT_DEFINE_SERVICEDESCREC4(sfnt_services, + FT_SERVICE_ID_SFNT_TABLE, &FT_SFNT_SERVICE_SFNT_TABLE_GET, + FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_SFNT_SERVICE_PS_NAME_GET, + FT_SERVICE_ID_BDF, &FT_SFNT_SERVICE_BDF_GET, + FT_SERVICE_ID_TT_CMAP, &FT_TT_SERVICE_GET_CMAP_INFO_GET + ) +#else + FT_DEFINE_SERVICEDESCREC3(sfnt_services, + FT_SERVICE_ID_SFNT_TABLE, &FT_SFNT_SERVICE_SFNT_TABLE_GET, + FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_SFNT_SERVICE_PS_NAME_GET, + FT_SERVICE_ID_TT_CMAP, &FT_TT_SERVICE_GET_CMAP_INFO_GET + ) +#endif + + + FT_CALLBACK_DEF( FT_Module_Interface ) + sfnt_get_interface( FT_Module module, + const char* module_interface ) + { + FT_Library library = module->library; + FT_UNUSED(library); + FT_UNUSED( module ); + + return ft_service_list_lookup( FT_SFNT_SERVICES_GET, module_interface ); + } + + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + + FT_CALLBACK_DEF( FT_Error ) + tt_face_load_sfnt_header_stub( TT_Face face, + FT_Stream stream, + FT_Long face_index, + SFNT_Header header ) + { + FT_UNUSED( face ); + FT_UNUSED( stream ); + FT_UNUSED( face_index ); + FT_UNUSED( header ); + + return FT_Err_Unimplemented_Feature; + } + + + FT_CALLBACK_DEF( FT_Error ) + tt_face_load_directory_stub( TT_Face face, + FT_Stream stream, + SFNT_Header header ) + { + FT_UNUSED( face ); + FT_UNUSED( stream ); + FT_UNUSED( header ); + + return FT_Err_Unimplemented_Feature; + } + + + FT_CALLBACK_DEF( FT_Error ) + tt_face_load_hdmx_stub( TT_Face face, + FT_Stream stream ) + { + FT_UNUSED( face ); + FT_UNUSED( stream ); + + return FT_Err_Unimplemented_Feature; + } + + + FT_CALLBACK_DEF( void ) + tt_face_free_hdmx_stub( TT_Face face ) + { + FT_UNUSED( face ); + } + + + FT_CALLBACK_DEF( FT_Error ) + tt_face_set_sbit_strike_stub( TT_Face face, + FT_UInt x_ppem, + FT_UInt y_ppem, + FT_ULong* astrike_index ) + { + /* + * We simply forge a FT_Size_Request and call the real function + * that does all the work. + * + * This stub might be called by libXfont in the X.Org Xserver, + * compiled against version 2.1.8 or newer. + */ + + FT_Size_RequestRec req; + + + req.type = FT_SIZE_REQUEST_TYPE_NOMINAL; + req.width = (FT_F26Dot6)x_ppem; + req.height = (FT_F26Dot6)y_ppem; + req.horiResolution = 0; + req.vertResolution = 0; + + *astrike_index = 0x7FFFFFFFUL; + + return tt_face_set_sbit_strike( face, &req, astrike_index ); + } + + + FT_CALLBACK_DEF( FT_Error ) + tt_face_load_sbit_stub( TT_Face face, + FT_Stream stream ) + { + FT_UNUSED( face ); + FT_UNUSED( stream ); + + /* + * This function was originally implemented to load the sbit table. + * However, it has been replaced by `tt_face_load_eblc', and this stub + * is only there for some rogue clients which would want to call it + * directly (which doesn't make much sense). + */ + return FT_Err_Unimplemented_Feature; + } + + + FT_CALLBACK_DEF( void ) + tt_face_free_sbit_stub( TT_Face face ) + { + /* nothing to do in this stub */ + FT_UNUSED( face ); + } + + + FT_CALLBACK_DEF( FT_Error ) + tt_face_load_charmap_stub( TT_Face face, + void* cmap, + FT_Stream input ) + { + FT_UNUSED( face ); + FT_UNUSED( cmap ); + FT_UNUSED( input ); + + return FT_Err_Unimplemented_Feature; + } + + + FT_CALLBACK_DEF( FT_Error ) + tt_face_free_charmap_stub( TT_Face face, + void* cmap ) + { + FT_UNUSED( face ); + FT_UNUSED( cmap ); + + return 0; + } + +#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */ + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS +#define PUT_EMBEDDED_BITMAPS(a) a +#else +#define PUT_EMBEDDED_BITMAPS(a) 0 +#endif +#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES +#define PUT_PS_NAMES(a) a +#else +#define PUT_PS_NAMES(a) 0 +#endif + + FT_DEFINE_SFNT_INTERFACE(sfnt_interface, + tt_face_goto_table, + + sfnt_init_face, + sfnt_load_face, + sfnt_done_face, + sfnt_get_interface, + + tt_face_load_any, + + tt_face_load_sfnt_header_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */ + tt_face_load_directory_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */ + + tt_face_load_head, + tt_face_load_hhea, + tt_face_load_cmap, + tt_face_load_maxp, + tt_face_load_os2, + tt_face_load_post, + + tt_face_load_name, + tt_face_free_name, + + tt_face_load_hdmx_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */ + tt_face_free_hdmx_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */ + + tt_face_load_kern, + tt_face_load_gasp, + tt_face_load_pclt, + + /* see `ttload.h' */ + PUT_EMBEDDED_BITMAPS(tt_face_load_bhed), + + tt_face_set_sbit_strike_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */ + tt_face_load_sbit_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */ + + tt_find_sbit_image, /* FT_CONFIG_OPTION_OLD_INTERNALS */ + tt_load_sbit_metrics, /* FT_CONFIG_OPTION_OLD_INTERNALS */ + + PUT_EMBEDDED_BITMAPS(tt_face_load_sbit_image), + + tt_face_free_sbit_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */ + + /* see `ttpost.h' */ + PUT_PS_NAMES(tt_face_get_ps_name), + PUT_PS_NAMES(tt_face_free_ps_names), + + tt_face_load_charmap_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */ + tt_face_free_charmap_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */ + + /* since version 2.1.8 */ + + tt_face_get_kerning, + + /* since version 2.2 */ + + tt_face_load_font_dir, + tt_face_load_hmtx, + + /* see `ttsbit.h' and `sfnt.h' */ + PUT_EMBEDDED_BITMAPS(tt_face_load_eblc), + PUT_EMBEDDED_BITMAPS(tt_face_free_eblc), + + PUT_EMBEDDED_BITMAPS(tt_face_set_sbit_strike), + PUT_EMBEDDED_BITMAPS(tt_face_load_strike_metrics), + + tt_face_get_metrics + ) + + + FT_DEFINE_MODULE(sfnt_module_class, + + 0, /* not a font driver or renderer */ + sizeof( FT_ModuleRec ), + + "sfnt", /* driver name */ + 0x10000L, /* driver version 1.0 */ + 0x20000L, /* driver requires FreeType 2.0 or higher */ + + (const void*)&FT_SFNT_INTERFACE_GET, /* module specific interface */ + + (FT_Module_Constructor)0, + (FT_Module_Destructor) 0, + (FT_Module_Requester) sfnt_get_interface + ) + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/sfnt/sfdriver.h b/mod/pub.mod/freetype.mod/src/sfnt/sfdriver.h new file mode 100644 index 0000000..5de25d5 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/sfnt/sfdriver.h @@ -0,0 +1,38 @@ +/***************************************************************************/ +/* */ +/* sfdriver.h */ +/* */ +/* High-level SFNT driver interface (specification). */ +/* */ +/* Copyright 1996-2001 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __SFDRIVER_H__ +#define __SFDRIVER_H__ + + +#include <ft2build.h> +#include FT_MODULE_H + + +FT_BEGIN_HEADER + + + FT_DECLARE_MODULE( sfnt_module_class ) + + +FT_END_HEADER + +#endif /* __SFDRIVER_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/sfnt/sferrors.h b/mod/pub.mod/freetype.mod/src/sfnt/sferrors.h new file mode 100644 index 0000000..27f90de --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/sfnt/sferrors.h @@ -0,0 +1,41 @@ +/***************************************************************************/ +/* */ +/* sferrors.h */ +/* */ +/* SFNT error codes (specification only). */ +/* */ +/* Copyright 2001, 2004 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file is used to define the SFNT error enumeration constants. */ + /* */ + /*************************************************************************/ + +#ifndef __SFERRORS_H__ +#define __SFERRORS_H__ + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#define FT_ERR_PREFIX SFNT_Err_ +#define FT_ERR_BASE FT_Mod_Err_SFNT + +#define FT_KEEP_ERR_PREFIX + +#include FT_ERRORS_H + +#endif /* __SFERRORS_H__ */ + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/sfnt/sfnt.c b/mod/pub.mod/freetype.mod/src/sfnt/sfnt.c new file mode 100644 index 0000000..fc507b4 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/sfnt/sfnt.c @@ -0,0 +1,42 @@ +/***************************************************************************/ +/* */ +/* sfnt.c */ +/* */ +/* Single object library component. */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#define FT_MAKE_OPTION_SINGLE_OBJECT + +#include <ft2build.h> +#include "sfntpic.c" +#include "ttload.c" +#include "ttmtx.c" +#include "ttcmap.c" +#include "ttkern.c" +#include "sfobjs.c" +#include "sfdriver.c" + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS +#include "ttsbit.c" +#endif + +#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES +#include "ttpost.c" +#endif + +#ifdef TT_CONFIG_OPTION_BDF +#include "ttbdf.c" +#endif + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/sfnt/sfntpic.c b/mod/pub.mod/freetype.mod/src/sfnt/sfntpic.c new file mode 100644 index 0000000..fd3cf4e --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/sfnt/sfntpic.c @@ -0,0 +1,101 @@ +/***************************************************************************/ +/* */ +/* sfntpic.c */ +/* */ +/* The FreeType position independent code services for sfnt module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include "sfntpic.h" + +#ifdef FT_CONFIG_OPTION_PIC + + /* forward declaration of PIC init functions from sfdriver.c */ + FT_Error FT_Create_Class_sfnt_services( FT_Library, FT_ServiceDescRec**); + void FT_Destroy_Class_sfnt_services( FT_Library, FT_ServiceDescRec*); + void FT_Init_Class_sfnt_service_bdf( FT_Service_BDFRec*); + void FT_Init_Class_sfnt_interface( FT_Library, SFNT_Interface*); + void FT_Init_Class_sfnt_service_glyph_dict( FT_Library, FT_Service_GlyphDictRec*); + void FT_Init_Class_sfnt_service_ps_name( FT_Library, FT_Service_PsFontNameRec*); + void FT_Init_Class_tt_service_get_cmap_info( FT_Library, FT_Service_TTCMapsRec*); + void FT_Init_Class_sfnt_service_sfnt_table( FT_Service_SFNT_TableRec*); + + /* forward declaration of PIC init functions from ttcmap.c */ + FT_Error FT_Create_Class_tt_cmap_classes( FT_Library, TT_CMap_Class**); + void FT_Destroy_Class_tt_cmap_classes( FT_Library, TT_CMap_Class*); + + void + sfnt_module_class_pic_free( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Memory memory = library->memory; + if ( pic_container->sfnt ) + { + sfntModulePIC* container = (sfntModulePIC*)pic_container->sfnt; + if(container->sfnt_services) + FT_Destroy_Class_sfnt_services(library, container->sfnt_services); + container->sfnt_services = NULL; + if(container->tt_cmap_classes) + FT_Destroy_Class_tt_cmap_classes(library, container->tt_cmap_classes); + container->tt_cmap_classes = NULL; + FT_FREE( container ); + pic_container->sfnt = NULL; + } + } + + + FT_Error + sfnt_module_class_pic_init( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Error error = FT_Err_Ok; + sfntModulePIC* container; + FT_Memory memory = library->memory; + + /* allocate pointer, clear and set global container pointer */ + if ( FT_ALLOC ( container, sizeof ( *container ) ) ) + return error; + FT_MEM_SET( container, 0, sizeof(*container) ); + pic_container->sfnt = container; + + /* initialize pointer table - this is how the module usually expects this data */ + error = FT_Create_Class_sfnt_services(library, &container->sfnt_services); + if(error) + goto Exit; + error = FT_Create_Class_tt_cmap_classes(library, &container->tt_cmap_classes); + if(error) + goto Exit; + FT_Init_Class_sfnt_service_glyph_dict(library, &container->sfnt_service_glyph_dict); + FT_Init_Class_sfnt_service_ps_name(library, &container->sfnt_service_ps_name); + FT_Init_Class_tt_service_get_cmap_info(library, &container->tt_service_get_cmap_info); + FT_Init_Class_sfnt_service_sfnt_table(&container->sfnt_service_sfnt_table); +#ifdef TT_CONFIG_OPTION_BDF + FT_Init_Class_sfnt_service_bdf(&container->sfnt_service_bdf); +#endif + FT_Init_Class_sfnt_interface(library, &container->sfnt_interface); + +Exit: + if(error) + sfnt_module_class_pic_free(library); + return error; + } + + + +#endif /* FT_CONFIG_OPTION_PIC */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/sfnt/sfntpic.h b/mod/pub.mod/freetype.mod/src/sfnt/sfntpic.h new file mode 100644 index 0000000..6943b42 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/sfnt/sfntpic.h @@ -0,0 +1,88 @@ +/***************************************************************************/ +/* */ +/* sfntpic.h */ +/* */ +/* The FreeType position independent code services for sfnt module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __SFNTPIC_H__ +#define __SFNTPIC_H__ + + +FT_BEGIN_HEADER + +#include FT_INTERNAL_PIC_H + + #ifndef FT_CONFIG_OPTION_PIC +#define FT_SFNT_SERVICES_GET sfnt_services +#define FT_SFNT_SERVICE_GLYPH_DICT_GET sfnt_service_glyph_dict +#define FT_SFNT_SERVICE_PS_NAME_GET sfnt_service_ps_name +#define FT_TT_SERVICE_GET_CMAP_INFO_GET tt_service_get_cmap_info +#define FT_SFNT_SERVICES_GET sfnt_services +#define FT_TT_CMAP_CLASSES_GET tt_cmap_classes +#define FT_SFNT_SERVICE_SFNT_TABLE_GET sfnt_service_sfnt_table +#define FT_SFNT_SERVICE_BDF_GET sfnt_service_bdf +#define FT_SFNT_INTERFACE_GET sfnt_interface + +#else /* FT_CONFIG_OPTION_PIC */ + +/* some include files required for members of sfntModulePIC */ +#include FT_SERVICE_GLYPH_DICT_H +#include FT_SERVICE_POSTSCRIPT_NAME_H +#include FT_SERVICE_SFNT_H +#include FT_SERVICE_TT_CMAP_H +#ifdef TT_CONFIG_OPTION_BDF +#include "ttbdf.h" +#include FT_SERVICE_BDF_H +#endif +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_SFNT_H +#include "ttcmap.h" + +typedef struct sfntModulePIC_ + { + FT_ServiceDescRec* sfnt_services; + FT_Service_GlyphDictRec sfnt_service_glyph_dict; + FT_Service_PsFontNameRec sfnt_service_ps_name; + FT_Service_TTCMapsRec tt_service_get_cmap_info; + TT_CMap_Class* tt_cmap_classes; + FT_Service_SFNT_TableRec sfnt_service_sfnt_table; +#ifdef TT_CONFIG_OPTION_BDF + FT_Service_BDFRec sfnt_service_bdf; +#endif + SFNT_Interface sfnt_interface; + } sfntModulePIC; + +#define GET_PIC(lib) ((sfntModulePIC*)((lib)->pic_container.sfnt)) +#define FT_SFNT_SERVICES_GET (GET_PIC(library)->sfnt_services) +#define FT_SFNT_SERVICE_GLYPH_DICT_GET (GET_PIC(library)->sfnt_service_glyph_dict) +#define FT_SFNT_SERVICE_PS_NAME_GET (GET_PIC(library)->sfnt_service_ps_name) +#define FT_TT_SERVICE_GET_CMAP_INFO_GET (GET_PIC(library)->tt_service_get_cmap_info) +#define FT_SFNT_SERVICES_GET (GET_PIC(library)->sfnt_services) +#define FT_TT_CMAP_CLASSES_GET (GET_PIC(library)->tt_cmap_classes) +#define FT_SFNT_SERVICE_SFNT_TABLE_GET (GET_PIC(library)->sfnt_service_sfnt_table) +#define FT_SFNT_SERVICE_BDF_GET (GET_PIC(library)->sfnt_service_bdf) +#define FT_SFNT_INTERFACE_GET (GET_PIC(library)->sfnt_interface) + +#endif /* FT_CONFIG_OPTION_PIC */ + +/* */ + +FT_END_HEADER + +#endif /* __SFNTPIC_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/sfnt/sfobjs.c b/mod/pub.mod/freetype.mod/src/sfnt/sfobjs.c new file mode 100644 index 0000000..cef3cd9 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/sfnt/sfobjs.c @@ -0,0 +1,1130 @@ +/***************************************************************************/ +/* */ +/* sfobjs.c */ +/* */ +/* SFNT object management (base). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include "sfobjs.h" +#include "ttload.h" +#include "ttcmap.h" +#include "ttkern.h" +#include FT_INTERNAL_SFNT_H +#include FT_INTERNAL_DEBUG_H +#include FT_TRUETYPE_IDS_H +#include FT_TRUETYPE_TAGS_H +#include FT_SERVICE_POSTSCRIPT_CMAPS_H +#include "sferrors.h" + +#ifdef TT_CONFIG_OPTION_BDF +#include "ttbdf.h" +#endif + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_sfobjs + + + + /* convert a UTF-16 name entry to ASCII */ + static FT_String* + tt_name_entry_ascii_from_utf16( TT_NameEntry entry, + FT_Memory memory ) + { + FT_String* string; + FT_UInt len, code, n; + FT_Byte* read = (FT_Byte*)entry->string; + FT_Error error; + + + len = (FT_UInt)entry->stringLength / 2; + + if ( FT_NEW_ARRAY( string, len + 1 ) ) + return NULL; + + for ( n = 0; n < len; n++ ) + { + code = FT_NEXT_USHORT( read ); + if ( code < 32 || code > 127 ) + code = '?'; + + string[n] = (char)code; + } + + string[len] = 0; + + return string; + } + + + /* convert an Apple Roman or symbol name entry to ASCII */ + static FT_String* + tt_name_entry_ascii_from_other( TT_NameEntry entry, + FT_Memory memory ) + { + FT_String* string; + FT_UInt len, code, n; + FT_Byte* read = (FT_Byte*)entry->string; + FT_Error error; + + + len = (FT_UInt)entry->stringLength; + + if ( FT_NEW_ARRAY( string, len + 1 ) ) + return NULL; + + for ( n = 0; n < len; n++ ) + { + code = *read++; + if ( code < 32 || code > 127 ) + code = '?'; + + string[n] = (char)code; + } + + string[len] = 0; + + return string; + } + + + typedef FT_String* (*TT_NameEntry_ConvertFunc)( TT_NameEntry entry, + FT_Memory memory ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_get_name */ + /* */ + /* <Description> */ + /* Returns a given ENGLISH name record in ASCII. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face object. */ + /* */ + /* nameid :: The name id of the name record to return. */ + /* */ + /* <InOut> */ + /* name :: The address of a string pointer. NULL if no name is */ + /* present. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + static FT_Error + tt_face_get_name( TT_Face face, + FT_UShort nameid, + FT_String** name ) + { + FT_Memory memory = face->root.memory; + FT_Error error = SFNT_Err_Ok; + FT_String* result = NULL; + FT_UShort n; + TT_NameEntryRec* rec; + FT_Int found_apple = -1; + FT_Int found_apple_roman = -1; + FT_Int found_apple_english = -1; + FT_Int found_win = -1; + FT_Int found_unicode = -1; + + FT_Bool is_english = 0; + + TT_NameEntry_ConvertFunc convert; + + + FT_ASSERT( name ); + + rec = face->name_table.names; + for ( n = 0; n < face->num_names; n++, rec++ ) + { + /* According to the OpenType 1.3 specification, only Microsoft or */ + /* Apple platform IDs might be used in the `name' table. The */ + /* `Unicode' platform is reserved for the `cmap' table, and the */ + /* `Iso' one is deprecated. */ + /* */ + /* However, the Apple TrueType specification doesn't say the same */ + /* thing and goes to suggest that all Unicode `name' table entries */ + /* should be coded in UTF-16 (in big-endian format I suppose). */ + /* */ + if ( rec->nameID == nameid && rec->stringLength > 0 ) + { + switch ( rec->platformID ) + { + case TT_PLATFORM_APPLE_UNICODE: + case TT_PLATFORM_ISO: + /* there is `languageID' to check there. We should use this */ + /* field only as a last solution when nothing else is */ + /* available. */ + /* */ + found_unicode = n; + break; + + case TT_PLATFORM_MACINTOSH: + /* This is a bit special because some fonts will use either */ + /* an English language id, or a Roman encoding id, to indicate */ + /* the English version of its font name. */ + /* */ + if ( rec->languageID == TT_MAC_LANGID_ENGLISH ) + found_apple_english = n; + else if ( rec->encodingID == TT_MAC_ID_ROMAN ) + found_apple_roman = n; + break; + + case TT_PLATFORM_MICROSOFT: + /* we only take a non-English name when there is nothing */ + /* else available in the font */ + /* */ + if ( found_win == -1 || ( rec->languageID & 0x3FF ) == 0x009 ) + { + switch ( rec->encodingID ) + { + case TT_MS_ID_SYMBOL_CS: + case TT_MS_ID_UNICODE_CS: + case TT_MS_ID_UCS_4: + is_english = FT_BOOL( ( rec->languageID & 0x3FF ) == 0x009 ); + found_win = n; + break; + + default: + ; + } + } + break; + + default: + ; + } + } + } + + found_apple = found_apple_roman; + if ( found_apple_english >= 0 ) + found_apple = found_apple_english; + + /* some fonts contain invalid Unicode or Macintosh formatted entries; */ + /* we will thus favor names encoded in Windows formats if available */ + /* (provided it is an English name) */ + /* */ + convert = NULL; + if ( found_win >= 0 && !( found_apple >= 0 && !is_english ) ) + { + rec = face->name_table.names + found_win; + switch ( rec->encodingID ) + { + /* all Unicode strings are encoded using UTF-16BE */ + case TT_MS_ID_UNICODE_CS: + case TT_MS_ID_SYMBOL_CS: + convert = tt_name_entry_ascii_from_utf16; + break; + + case TT_MS_ID_UCS_4: + /* Apparently, if this value is found in a name table entry, it is */ + /* documented as `full Unicode repertoire'. Experience with the */ + /* MsGothic font shipped with Windows Vista shows that this really */ + /* means UTF-16 encoded names (UCS-4 values are only used within */ + /* charmaps). */ + convert = tt_name_entry_ascii_from_utf16; + break; + + default: + ; + } + } + else if ( found_apple >= 0 ) + { + rec = face->name_table.names + found_apple; + convert = tt_name_entry_ascii_from_other; + } + else if ( found_unicode >= 0 ) + { + rec = face->name_table.names + found_unicode; + convert = tt_name_entry_ascii_from_utf16; + } + + if ( rec && convert ) + { + if ( rec->string == NULL ) + { + FT_Stream stream = face->name_table.stream; + + + if ( FT_QNEW_ARRAY ( rec->string, rec->stringLength ) || + FT_STREAM_SEEK( rec->stringOffset ) || + FT_STREAM_READ( rec->string, rec->stringLength ) ) + { + FT_FREE( rec->string ); + rec->stringLength = 0; + result = NULL; + goto Exit; + } + } + + result = convert( rec, memory ); + } + + Exit: + *name = result; + return error; + } + + + static FT_Encoding + sfnt_find_encoding( int platform_id, + int encoding_id ) + { + typedef struct TEncoding_ + { + int platform_id; + int encoding_id; + FT_Encoding encoding; + + } TEncoding; + + static + const TEncoding tt_encodings[] = + { + { TT_PLATFORM_ISO, -1, FT_ENCODING_UNICODE }, + + { TT_PLATFORM_APPLE_UNICODE, -1, FT_ENCODING_UNICODE }, + + { TT_PLATFORM_MACINTOSH, TT_MAC_ID_ROMAN, FT_ENCODING_APPLE_ROMAN }, + + { TT_PLATFORM_MICROSOFT, TT_MS_ID_SYMBOL_CS, FT_ENCODING_MS_SYMBOL }, + { TT_PLATFORM_MICROSOFT, TT_MS_ID_UCS_4, FT_ENCODING_UNICODE }, + { TT_PLATFORM_MICROSOFT, TT_MS_ID_UNICODE_CS, FT_ENCODING_UNICODE }, + { TT_PLATFORM_MICROSOFT, TT_MS_ID_SJIS, FT_ENCODING_SJIS }, + { TT_PLATFORM_MICROSOFT, TT_MS_ID_GB2312, FT_ENCODING_GB2312 }, + { TT_PLATFORM_MICROSOFT, TT_MS_ID_BIG_5, FT_ENCODING_BIG5 }, + { TT_PLATFORM_MICROSOFT, TT_MS_ID_WANSUNG, FT_ENCODING_WANSUNG }, + { TT_PLATFORM_MICROSOFT, TT_MS_ID_JOHAB, FT_ENCODING_JOHAB } + }; + + const TEncoding *cur, *limit; + + + cur = tt_encodings; + limit = cur + sizeof ( tt_encodings ) / sizeof ( tt_encodings[0] ); + + for ( ; cur < limit; cur++ ) + { + if ( cur->platform_id == platform_id ) + { + if ( cur->encoding_id == encoding_id || + cur->encoding_id == -1 ) + return cur->encoding; + } + } + + return FT_ENCODING_NONE; + } + + + /* Fill in face->ttc_header. If the font is not a TTC, it is */ + /* synthesized into a TTC with one offset table. */ + static FT_Error + sfnt_open_font( FT_Stream stream, + TT_Face face ) + { + FT_Memory memory = stream->memory; + FT_Error error; + FT_ULong tag, offset; + + static const FT_Frame_Field ttc_header_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE TTC_HeaderRec + + FT_FRAME_START( 8 ), + FT_FRAME_LONG( version ), + FT_FRAME_LONG( count ), + FT_FRAME_END + }; + + + face->ttc_header.tag = 0; + face->ttc_header.version = 0; + face->ttc_header.count = 0; + + offset = FT_STREAM_POS(); + + if ( FT_READ_ULONG( tag ) ) + return error; + + if ( tag != 0x00010000UL && + tag != TTAG_ttcf && + tag != TTAG_OTTO && + tag != TTAG_true && + tag != TTAG_typ1 && + tag != 0x00020000UL ) + return SFNT_Err_Unknown_File_Format; + + face->ttc_header.tag = TTAG_ttcf; + + if ( tag == TTAG_ttcf ) + { + FT_Int n; + + + FT_TRACE3(( "sfnt_open_font: file is a collection\n" )); + + if ( FT_STREAM_READ_FIELDS( ttc_header_fields, &face->ttc_header ) ) + return error; + + /* now read the offsets of each font in the file */ + if ( FT_NEW_ARRAY( face->ttc_header.offsets, face->ttc_header.count ) ) + return error; + + if ( FT_FRAME_ENTER( face->ttc_header.count * 4L ) ) + return error; + + for ( n = 0; n < face->ttc_header.count; n++ ) + face->ttc_header.offsets[n] = FT_GET_ULONG(); + + FT_FRAME_EXIT(); + } + else + { + FT_TRACE3(( "sfnt_open_font: synthesize TTC\n" )); + + face->ttc_header.version = 1 << 16; + face->ttc_header.count = 1; + + if ( FT_NEW( face->ttc_header.offsets ) ) + return error; + + face->ttc_header.offsets[0] = offset; + } + + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + sfnt_init_face( FT_Stream stream, + TT_Face face, + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ) + { + FT_Error error; + FT_Library library = face->root.driver->root.library; + SFNT_Service sfnt; + + + /* for now, parameters are unused */ + FT_UNUSED( num_params ); + FT_UNUSED( params ); + + + sfnt = (SFNT_Service)face->sfnt; + if ( !sfnt ) + { + sfnt = (SFNT_Service)FT_Get_Module_Interface( library, "sfnt" ); + if ( !sfnt ) + return SFNT_Err_Invalid_File_Format; + + face->sfnt = sfnt; + face->goto_table = sfnt->goto_table; + } + + FT_FACE_FIND_GLOBAL_SERVICE( face, face->psnames, POSTSCRIPT_CMAPS ); + + error = sfnt_open_font( stream, face ); + if ( error ) + return error; + + FT_TRACE2(( "sfnt_init_face: %08p, %ld\n", face, face_index )); + + if ( face_index < 0 ) + face_index = 0; + + if ( face_index >= face->ttc_header.count ) + return SFNT_Err_Invalid_Argument; + + if ( FT_STREAM_SEEK( face->ttc_header.offsets[face_index] ) ) + return error; + + /* check that we have a valid TrueType file */ + error = sfnt->load_font_dir( face, stream ); + if ( error ) + return error; + + face->root.num_faces = face->ttc_header.count; + face->root.face_index = face_index; + + return error; + } + + +#define LOAD_( x ) \ + do { \ + FT_TRACE2(( "`" #x "' " )); \ + FT_TRACE3(( "-->\n" )); \ + \ + error = sfnt->load_##x( face, stream ); \ + \ + FT_TRACE2(( "%s\n", ( !error ) \ + ? "loaded" \ + : ( error == SFNT_Err_Table_Missing ) \ + ? "missing" \ + : "failed to load" )); \ + FT_TRACE3(( "\n" )); \ + } while ( 0 ) + +#define LOADM_( x, vertical ) \ + do { \ + FT_TRACE2(( "`%s" #x "' ", \ + vertical ? "vertical " : "" )); \ + FT_TRACE3(( "-->\n" )); \ + \ + error = sfnt->load_##x( face, stream, vertical ); \ + \ + FT_TRACE2(( "%s\n", ( !error ) \ + ? "loaded" \ + : ( error == SFNT_Err_Table_Missing ) \ + ? "missing" \ + : "failed to load" )); \ + FT_TRACE3(( "\n" )); \ + } while ( 0 ) + +#define GET_NAME( id, field ) \ + do { \ + error = tt_face_get_name( face, TT_NAME_ID_##id, field ); \ + if ( error ) \ + goto Exit; \ + } while ( 0 ) + + + FT_LOCAL_DEF( FT_Error ) + sfnt_load_face( FT_Stream stream, + TT_Face face, + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ) + { + FT_Error error; +#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES + FT_Error psnames_error; +#endif + FT_Bool has_outline; + FT_Bool is_apple_sbit; + + SFNT_Service sfnt = (SFNT_Service)face->sfnt; + + FT_UNUSED( face_index ); + FT_UNUSED( num_params ); + FT_UNUSED( params ); + + + /* Load tables */ + + /* We now support two SFNT-based bitmapped font formats. They */ + /* are recognized easily as they do not include a `glyf' */ + /* table. */ + /* */ + /* The first format comes from Apple, and uses a table named */ + /* `bhed' instead of `head' to store the font header (using */ + /* the same format). It also doesn't include horizontal and */ + /* vertical metrics tables (i.e. `hhea' and `vhea' tables are */ + /* missing). */ + /* */ + /* The other format comes from Microsoft, and is used with */ + /* WinCE/PocketPC. It looks like a standard TTF, except that */ + /* it doesn't contain outlines. */ + /* */ + + FT_TRACE2(( "sfnt_load_face: %08p\n\n", face )); + + /* do we have outlines in there? */ +#ifdef FT_CONFIG_OPTION_INCREMENTAL + has_outline = FT_BOOL( face->root.internal->incremental_interface != 0 || + tt_face_lookup_table( face, TTAG_glyf ) != 0 || + tt_face_lookup_table( face, TTAG_CFF ) != 0 ); +#else + has_outline = FT_BOOL( tt_face_lookup_table( face, TTAG_glyf ) != 0 || + tt_face_lookup_table( face, TTAG_CFF ) != 0 ); +#endif + + is_apple_sbit = 0; + + /* if this font doesn't contain outlines, we try to load */ + /* a `bhed' table */ + if ( !has_outline && sfnt->load_bhed ) + { + LOAD_( bhed ); + is_apple_sbit = FT_BOOL( !error ); + } + + /* load the font header (`head' table) if this isn't an Apple */ + /* sbit font file */ + if ( !is_apple_sbit ) + { + LOAD_( head ); + if ( error ) + goto Exit; + } + + if ( face->header.Units_Per_EM == 0 ) + { + error = SFNT_Err_Invalid_Table; + + goto Exit; + } + + /* the following tables are often not present in embedded TrueType */ + /* fonts within PDF documents, so don't check for them. */ + LOAD_( maxp ); + LOAD_( cmap ); + + /* the following tables are optional in PCL fonts -- */ + /* don't check for errors */ + LOAD_( name ); + LOAD_( post ); + +#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES + psnames_error = error; +#endif + + /* do not load the metrics headers and tables if this is an Apple */ + /* sbit font file */ + if ( !is_apple_sbit ) + { + /* load the `hhea' and `hmtx' tables */ + LOADM_( hhea, 0 ); + if ( !error ) + { + LOADM_( hmtx, 0 ); + if ( error == SFNT_Err_Table_Missing ) + { + error = SFNT_Err_Hmtx_Table_Missing; + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + /* If this is an incrementally loaded font and there are */ + /* overriding metrics, tolerate a missing `hmtx' table. */ + if ( face->root.internal->incremental_interface && + face->root.internal->incremental_interface->funcs-> + get_glyph_metrics ) + { + face->horizontal.number_Of_HMetrics = 0; + error = SFNT_Err_Ok; + } +#endif + } + } + else if ( error == SFNT_Err_Table_Missing ) + { + /* No `hhea' table necessary for SFNT Mac fonts. */ + if ( face->format_tag == TTAG_true ) + { + FT_TRACE2(( "This is an SFNT Mac font.\n" )); + has_outline = 0; + error = SFNT_Err_Ok; + } + else + { + error = SFNT_Err_Horiz_Header_Missing; + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + /* If this is an incrementally loaded font and there are */ + /* overriding metrics, tolerate a missing `hhea' table. */ + if ( face->root.internal->incremental_interface && + face->root.internal->incremental_interface->funcs-> + get_glyph_metrics ) + { + face->horizontal.number_Of_HMetrics = 0; + error = SFNT_Err_Ok; + } +#endif + + } + } + + if ( error ) + goto Exit; + + /* try to load the `vhea' and `vmtx' tables */ + LOADM_( hhea, 1 ); + if ( !error ) + { + LOADM_( hmtx, 1 ); + if ( !error ) + face->vertical_info = 1; + } + + if ( error && error != SFNT_Err_Table_Missing ) + goto Exit; + + LOAD_( os2 ); + if ( error ) + { + if ( error != SFNT_Err_Table_Missing ) + goto Exit; + + face->os2.version = 0xFFFFU; + } + } + + /* the optional tables */ + + /* embedded bitmap support */ + if ( sfnt->load_eblc ) + { + LOAD_( eblc ); + if ( error ) + { + /* a font which contains neither bitmaps nor outlines is */ + /* still valid (although rather useless in most cases); */ + /* however, you can find such stripped fonts in PDFs */ + if ( error == SFNT_Err_Table_Missing ) + error = SFNT_Err_Ok; + else + goto Exit; + } + } + + LOAD_( pclt ); + if ( error ) + { + if ( error != SFNT_Err_Table_Missing ) + goto Exit; + + face->pclt.Version = 0; + } + + /* consider the kerning and gasp tables as optional */ + LOAD_( gasp ); + LOAD_( kern ); + + face->root.num_glyphs = face->max_profile.numGlyphs; + + /* Bit 8 of the `fsSelection' field in the `OS/2' table denotes */ + /* a WWS-only font face. `WWS' stands for `weight', width', and */ + /* `slope', a term used by Microsoft's Windows Presentation */ + /* Foundation (WPF). This flag has been introduced in version */ + /* 1.5 of the OpenType specification (May 2008). */ + + if ( face->os2.version != 0xFFFFU && face->os2.fsSelection & 256 ) + { + GET_NAME( PREFERRED_FAMILY, &face->root.family_name ); + if ( !face->root.family_name ) + GET_NAME( FONT_FAMILY, &face->root.family_name ); + + GET_NAME( PREFERRED_SUBFAMILY, &face->root.style_name ); + if ( !face->root.style_name ) + GET_NAME( FONT_SUBFAMILY, &face->root.style_name ); + } + else + { + GET_NAME( WWS_FAMILY, &face->root.family_name ); + if ( !face->root.family_name ) + GET_NAME( PREFERRED_FAMILY, &face->root.family_name ); + if ( !face->root.family_name ) + GET_NAME( FONT_FAMILY, &face->root.family_name ); + + GET_NAME( WWS_SUBFAMILY, &face->root.style_name ); + if ( !face->root.style_name ) + GET_NAME( PREFERRED_SUBFAMILY, &face->root.style_name ); + if ( !face->root.style_name ) + GET_NAME( FONT_SUBFAMILY, &face->root.style_name ); + } + + /* now set up root fields */ + { + FT_Face root = &face->root; + FT_Long flags = root->face_flags; + + + /*********************************************************************/ + /* */ + /* Compute face flags. */ + /* */ + if ( has_outline == TRUE ) + flags |= FT_FACE_FLAG_SCALABLE; /* scalable outlines */ + + /* The sfnt driver only supports bitmap fonts natively, thus we */ + /* don't set FT_FACE_FLAG_HINTER. */ + flags |= FT_FACE_FLAG_SFNT | /* SFNT file format */ + FT_FACE_FLAG_HORIZONTAL; /* horizontal data */ + +#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES + if ( psnames_error == SFNT_Err_Ok && + face->postscript.FormatType != 0x00030000L ) + flags |= FT_FACE_FLAG_GLYPH_NAMES; +#endif + + /* fixed width font? */ + if ( face->postscript.isFixedPitch ) + flags |= FT_FACE_FLAG_FIXED_WIDTH; + + /* vertical information? */ + if ( face->vertical_info ) + flags |= FT_FACE_FLAG_VERTICAL; + + /* kerning available ? */ + if ( TT_FACE_HAS_KERNING( face ) ) + flags |= FT_FACE_FLAG_KERNING; + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + /* Don't bother to load the tables unless somebody asks for them. */ + /* No need to do work which will (probably) not be used. */ + if ( tt_face_lookup_table( face, TTAG_glyf ) != 0 && + tt_face_lookup_table( face, TTAG_fvar ) != 0 && + tt_face_lookup_table( face, TTAG_gvar ) != 0 ) + flags |= FT_FACE_FLAG_MULTIPLE_MASTERS; +#endif + + root->face_flags = flags; + + /*********************************************************************/ + /* */ + /* Compute style flags. */ + /* */ + + flags = 0; + if ( has_outline == TRUE && face->os2.version != 0xFFFFU ) + { + /* We have an OS/2 table; use the `fsSelection' field. Bit 9 */ + /* indicates an oblique font face. This flag has been */ + /* introduced in version 1.5 of the OpenType specification. */ + + if ( face->os2.fsSelection & 512 ) /* bit 9 */ + flags |= FT_STYLE_FLAG_ITALIC; + else if ( face->os2.fsSelection & 1 ) /* bit 0 */ + flags |= FT_STYLE_FLAG_ITALIC; + + if ( face->os2.fsSelection & 32 ) /* bit 5 */ + flags |= FT_STYLE_FLAG_BOLD; + } + else + { + /* this is an old Mac font, use the header field */ + + if ( face->header.Mac_Style & 1 ) + flags |= FT_STYLE_FLAG_BOLD; + + if ( face->header.Mac_Style & 2 ) + flags |= FT_STYLE_FLAG_ITALIC; + } + + root->style_flags = flags; + + /*********************************************************************/ + /* */ + /* Polish the charmaps. */ + /* */ + /* Try to set the charmap encoding according to the platform & */ + /* encoding ID of each charmap. */ + /* */ + + tt_face_build_cmaps( face ); /* ignore errors */ + + + /* set the encoding fields */ + { + FT_Int m; + + + for ( m = 0; m < root->num_charmaps; m++ ) + { + FT_CharMap charmap = root->charmaps[m]; + + + charmap->encoding = sfnt_find_encoding( charmap->platform_id, + charmap->encoding_id ); + +#if 0 + if ( root->charmap == NULL && + charmap->encoding == FT_ENCODING_UNICODE ) + { + /* set 'root->charmap' to the first Unicode encoding we find */ + root->charmap = charmap; + } +#endif + } + } + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + + /* + * Now allocate the root array of FT_Bitmap_Size records and + * populate them. Unfortunately, it isn't possible to indicate bit + * depths in the FT_Bitmap_Size record. This is a design error. + */ + { + FT_UInt i, count; + + +#ifndef FT_CONFIG_OPTION_OLD_INTERNALS + count = face->sbit_num_strikes; +#else + count = (FT_UInt)face->num_sbit_strikes; +#endif + + if ( count > 0 ) + { + FT_Memory memory = face->root.stream->memory; + FT_UShort em_size = face->header.Units_Per_EM; + FT_Short avgwidth = face->os2.xAvgCharWidth; + FT_Size_Metrics metrics; + + + if ( em_size == 0 || face->os2.version == 0xFFFFU ) + { + avgwidth = 0; + em_size = 1; + } + + if ( FT_NEW_ARRAY( root->available_sizes, count ) ) + goto Exit; + + for ( i = 0; i < count; i++ ) + { + FT_Bitmap_Size* bsize = root->available_sizes + i; + + + error = sfnt->load_strike_metrics( face, i, &metrics ); + if ( error ) + goto Exit; + + bsize->height = (FT_Short)( metrics.height >> 6 ); + bsize->width = (FT_Short)( + ( avgwidth * metrics.x_ppem + em_size / 2 ) / em_size ); + + bsize->x_ppem = metrics.x_ppem << 6; + bsize->y_ppem = metrics.y_ppem << 6; + + /* assume 72dpi */ + bsize->size = metrics.y_ppem << 6; + } + + root->face_flags |= FT_FACE_FLAG_FIXED_SIZES; + root->num_fixed_sizes = (FT_Int)count; + } + } + +#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ + + /* a font with no bitmaps and no outlines is scalable; */ + /* it has only empty glyphs then */ + if ( !FT_HAS_FIXED_SIZES( root ) && !FT_IS_SCALABLE( root ) ) + root->face_flags |= FT_FACE_FLAG_SCALABLE; + + + /*********************************************************************/ + /* */ + /* Set up metrics. */ + /* */ + if ( FT_IS_SCALABLE( root ) ) + { + /* XXX What about if outline header is missing */ + /* (e.g. sfnt wrapped bitmap)? */ + root->bbox.xMin = face->header.xMin; + root->bbox.yMin = face->header.yMin; + root->bbox.xMax = face->header.xMax; + root->bbox.yMax = face->header.yMax; + root->units_per_EM = face->header.Units_Per_EM; + + + /* XXX: Computing the ascender/descender/height is very different */ + /* from what the specification tells you. Apparently, we */ + /* must be careful because */ + /* */ + /* - not all fonts have an OS/2 table; in this case, we take */ + /* the values in the horizontal header. However, these */ + /* values very often are not reliable. */ + /* */ + /* - otherwise, the correct typographic values are in the */ + /* sTypoAscender, sTypoDescender & sTypoLineGap fields. */ + /* */ + /* However, certain fonts have these fields set to 0. */ + /* Rather, they have usWinAscent & usWinDescent correctly */ + /* set (but with different values). */ + /* */ + /* As an example, Arial Narrow is implemented through four */ + /* files ARIALN.TTF, ARIALNI.TTF, ARIALNB.TTF & ARIALNBI.TTF */ + /* */ + /* Strangely, all fonts have the same values in their */ + /* sTypoXXX fields, except ARIALNB which sets them to 0. */ + /* */ + /* On the other hand, they all have different */ + /* usWinAscent/Descent values -- as a conclusion, the OS/2 */ + /* table cannot be used to compute the text height reliably! */ + /* */ + + /* The ascender/descender/height are computed from the OS/2 table */ + /* when found. Otherwise, they're taken from the horizontal */ + /* header. */ + /* */ + + root->ascender = face->horizontal.Ascender; + root->descender = face->horizontal.Descender; + + root->height = (FT_Short)( root->ascender - root->descender + + face->horizontal.Line_Gap ); + +#if 0 + /* if the line_gap is 0, we add an extra 15% to the text height -- */ + /* this computation is based on various versions of Times New Roman */ + if ( face->horizontal.Line_Gap == 0 ) + root->height = (FT_Short)( ( root->height * 115 + 50 ) / 100 ); +#endif /* 0 */ + +#if 0 + /* some fonts have the OS/2 "sTypoAscender", "sTypoDescender" & */ + /* "sTypoLineGap" fields set to 0, like ARIALNB.TTF */ + if ( face->os2.version != 0xFFFFU && root->ascender ) + { + FT_Int height; + + + root->ascender = face->os2.sTypoAscender; + root->descender = -face->os2.sTypoDescender; + + height = root->ascender + root->descender + face->os2.sTypoLineGap; + if ( height > root->height ) + root->height = height; + } +#endif /* 0 */ + + root->max_advance_width = face->horizontal.advance_Width_Max; + root->max_advance_height = (FT_Short)( face->vertical_info + ? face->vertical.advance_Height_Max + : root->height ); + + /* See http://www.microsoft.com/OpenType/OTSpec/post.htm -- */ + /* Adjust underline position from top edge to centre of */ + /* stroke to convert TrueType meaning to FreeType meaning. */ + root->underline_position = face->postscript.underlinePosition - + face->postscript.underlineThickness / 2; + root->underline_thickness = face->postscript.underlineThickness; + } + + } + + Exit: + FT_TRACE2(( "sfnt_load_face: done\n" )); + + return error; + } + + +#undef LOAD_ +#undef LOADM_ +#undef GET_NAME + + + FT_LOCAL_DEF( void ) + sfnt_done_face( TT_Face face ) + { + FT_Memory memory; + SFNT_Service sfnt; + + + if ( !face ) + return; + + memory = face->root.memory; + sfnt = (SFNT_Service)face->sfnt; + + if ( sfnt ) + { + /* destroy the postscript names table if it is loaded */ + if ( sfnt->free_psnames ) + sfnt->free_psnames( face ); + + /* destroy the embedded bitmaps table if it is loaded */ + if ( sfnt->free_eblc ) + sfnt->free_eblc( face ); + } + +#ifdef TT_CONFIG_OPTION_BDF + /* freeing the embedded BDF properties */ + tt_face_free_bdf_props( face ); +#endif + + /* freeing the kerning table */ + tt_face_done_kern( face ); + + /* freeing the collection table */ + FT_FREE( face->ttc_header.offsets ); + face->ttc_header.count = 0; + + /* freeing table directory */ + FT_FREE( face->dir_tables ); + face->num_tables = 0; + + { + FT_Stream stream = FT_FACE_STREAM( face ); + + + /* simply release the 'cmap' table frame */ + FT_FRAME_RELEASE( face->cmap_table ); + face->cmap_size = 0; + } + + /* freeing the horizontal metrics */ +#ifndef FT_CONFIG_OPTION_OLD_INTERNALS + { + FT_Stream stream = FT_FACE_STREAM( face ); + + + FT_FRAME_RELEASE( face->horz_metrics ); + FT_FRAME_RELEASE( face->vert_metrics ); + face->horz_metrics_size = 0; + face->vert_metrics_size = 0; + } +#else + FT_FREE( face->horizontal.long_metrics ); + FT_FREE( face->horizontal.short_metrics ); +#endif + + /* freeing the vertical ones, if any */ + if ( face->vertical_info ) + { + FT_FREE( face->vertical.long_metrics ); + FT_FREE( face->vertical.short_metrics ); + face->vertical_info = 0; + } + + /* freeing the gasp table */ + FT_FREE( face->gasp.gaspRanges ); + face->gasp.numRanges = 0; + + /* freeing the name table */ + if ( sfnt ) + sfnt->free_name( face ); + + /* freeing family and style name */ + FT_FREE( face->root.family_name ); + FT_FREE( face->root.style_name ); + + /* freeing sbit size table */ + FT_FREE( face->root.available_sizes ); + face->root.num_fixed_sizes = 0; + + FT_FREE( face->postscript_name ); + + face->sfnt = 0; + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/sfnt/sfobjs.h b/mod/pub.mod/freetype.mod/src/sfnt/sfobjs.h new file mode 100644 index 0000000..6241c93 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/sfnt/sfobjs.h @@ -0,0 +1,54 @@ +/***************************************************************************/ +/* */ +/* sfobjs.h */ +/* */ +/* SFNT object management (specification). */ +/* */ +/* Copyright 1996-2001, 2002 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __SFOBJS_H__ +#define __SFOBJS_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_SFNT_H +#include FT_INTERNAL_OBJECTS_H + + +FT_BEGIN_HEADER + + + FT_LOCAL( FT_Error ) + sfnt_init_face( FT_Stream stream, + TT_Face face, + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ); + + FT_LOCAL( FT_Error ) + sfnt_load_face( FT_Stream stream, + TT_Face face, + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ); + + FT_LOCAL( void ) + sfnt_done_face( TT_Face face ); + + +FT_END_HEADER + +#endif /* __SFDRIVER_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/sfnt/ttbdf.c b/mod/pub.mod/freetype.mod/src/sfnt/ttbdf.c new file mode 100644 index 0000000..206cece --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/sfnt/ttbdf.c @@ -0,0 +1,250 @@ +/***************************************************************************/ +/* */ +/* ttbdf.c */ +/* */ +/* TrueType and OpenType embedded BDF properties (body). */ +/* */ +/* Copyright 2005, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_TRUETYPE_TAGS_H +#include "ttbdf.h" + +#include "sferrors.h" + + +#ifdef TT_CONFIG_OPTION_BDF + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_ttbdf + + + FT_LOCAL_DEF( void ) + tt_face_free_bdf_props( TT_Face face ) + { + TT_BDF bdf = &face->bdf; + + + if ( bdf->loaded ) + { + FT_Stream stream = FT_FACE(face)->stream; + + + if ( bdf->table != NULL ) + FT_FRAME_RELEASE( bdf->table ); + + bdf->table_end = NULL; + bdf->strings = NULL; + bdf->strings_size = 0; + } + } + + + static FT_Error + tt_face_load_bdf_props( TT_Face face, + FT_Stream stream ) + { + TT_BDF bdf = &face->bdf; + FT_ULong length; + FT_Error error; + + + FT_ZERO( bdf ); + + error = tt_face_goto_table( face, TTAG_BDF, stream, &length ); + if ( error || + length < 8 || + FT_FRAME_EXTRACT( length, bdf->table ) ) + { + error = FT_Err_Invalid_Table; + goto Exit; + } + + bdf->table_end = bdf->table + length; + + { + FT_Byte* p = bdf->table; + FT_UInt version = FT_NEXT_USHORT( p ); + FT_UInt num_strikes = FT_NEXT_USHORT( p ); + FT_ULong strings = FT_NEXT_ULONG ( p ); + FT_UInt count; + FT_Byte* strike; + + + if ( version != 0x0001 || + strings < 8 || + ( strings - 8 ) / 4 < num_strikes || + strings + 1 > length ) + { + goto BadTable; + } + + bdf->num_strikes = num_strikes; + bdf->strings = bdf->table + strings; + bdf->strings_size = length - strings; + + count = bdf->num_strikes; + p = bdf->table + 8; + strike = p + count * 4; + + + for ( ; count > 0; count-- ) + { + FT_UInt num_items = FT_PEEK_USHORT( p + 2 ); + + /* + * We don't need to check the value sets themselves, since this + * is done later. + */ + strike += 10 * num_items; + + p += 4; + } + + if ( strike > bdf->strings ) + goto BadTable; + } + + bdf->loaded = 1; + + Exit: + return error; + + BadTable: + FT_FRAME_RELEASE( bdf->table ); + FT_ZERO( bdf ); + error = FT_Err_Invalid_Table; + goto Exit; + } + + + FT_LOCAL_DEF( FT_Error ) + tt_face_find_bdf_prop( TT_Face face, + const char* property_name, + BDF_PropertyRec *aprop ) + { + TT_BDF bdf = &face->bdf; + FT_Size size = FT_FACE(face)->size; + FT_Error error = 0; + FT_Byte* p; + FT_UInt count; + FT_Byte* strike; + FT_Offset property_len; + + + aprop->type = BDF_PROPERTY_TYPE_NONE; + + if ( bdf->loaded == 0 ) + { + error = tt_face_load_bdf_props( face, FT_FACE( face )->stream ); + if ( error ) + goto Exit; + } + + count = bdf->num_strikes; + p = bdf->table + 8; + strike = p + 4 * count; + + error = FT_Err_Invalid_Argument; + + if ( size == NULL || property_name == NULL ) + goto Exit; + + property_len = ft_strlen( property_name ); + if ( property_len == 0 ) + goto Exit; + + for ( ; count > 0; count-- ) + { + FT_UInt _ppem = FT_NEXT_USHORT( p ); + FT_UInt _count = FT_NEXT_USHORT( p ); + + if ( _ppem == size->metrics.y_ppem ) + { + count = _count; + goto FoundStrike; + } + + strike += 10 * _count; + } + goto Exit; + + FoundStrike: + p = strike; + for ( ; count > 0; count-- ) + { + FT_UInt type = FT_PEEK_USHORT( p + 4 ); + + if ( ( type & 0x10 ) != 0 ) + { + FT_UInt32 name_offset = FT_PEEK_ULONG( p ); + FT_UInt32 value = FT_PEEK_ULONG( p + 6 ); + + /* be a bit paranoid for invalid entries here */ + if ( name_offset < bdf->strings_size && + property_len < bdf->strings_size - name_offset && + ft_strncmp( property_name, + (const char*)bdf->strings + name_offset, + bdf->strings_size - name_offset ) == 0 ) + { + switch ( type & 0x0F ) + { + case 0x00: /* string */ + case 0x01: /* atoms */ + /* check that the content is really 0-terminated */ + if ( value < bdf->strings_size && + ft_memchr( bdf->strings + value, 0, bdf->strings_size ) ) + { + aprop->type = BDF_PROPERTY_TYPE_ATOM; + aprop->u.atom = (const char*)bdf->strings + value; + error = 0; + goto Exit; + } + break; + + case 0x02: + aprop->type = BDF_PROPERTY_TYPE_INTEGER; + aprop->u.integer = (FT_Int32)value; + error = 0; + goto Exit; + + case 0x03: + aprop->type = BDF_PROPERTY_TYPE_CARDINAL; + aprop->u.cardinal = value; + error = 0; + goto Exit; + + default: + ; + } + } + } + p += 10; + } + + Exit: + return error; + } + +#endif /* TT_CONFIG_OPTION_BDF */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/sfnt/ttbdf.h b/mod/pub.mod/freetype.mod/src/sfnt/ttbdf.h new file mode 100644 index 0000000..48a10d6 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/sfnt/ttbdf.h @@ -0,0 +1,46 @@ +/***************************************************************************/ +/* */ +/* ttbdf.h */ +/* */ +/* TrueType and OpenType embedded BDF properties (specification). */ +/* */ +/* Copyright 2005 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __TTBDF_H__ +#define __TTBDF_H__ + + +#include <ft2build.h> +#include "ttload.h" +#include FT_BDF_H + + +FT_BEGIN_HEADER + + + FT_LOCAL( void ) + tt_face_free_bdf_props( TT_Face face ); + + + FT_LOCAL( FT_Error ) + tt_face_find_bdf_prop( TT_Face face, + const char* property_name, + BDF_PropertyRec *aprop ); + + +FT_END_HEADER + +#endif /* __TTBDF_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/sfnt/ttcmap.c b/mod/pub.mod/freetype.mod/src/sfnt/ttcmap.c new file mode 100644 index 0000000..26ea83c --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/sfnt/ttcmap.c @@ -0,0 +1,3507 @@ +/***************************************************************************/ +/* */ +/* ttcmap.c */ +/* */ +/* TrueType character mapping table (cmap) support (body). */ +/* */ +/* Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H + +#include "sferrors.h" /* must come before FT_INTERNAL_VALIDATE_H */ + +#include FT_INTERNAL_VALIDATE_H +#include FT_INTERNAL_STREAM_H +#include "ttload.h" +#include "ttcmap.h" +#include "sfntpic.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_ttcmap + + +#define TT_PEEK_SHORT FT_PEEK_SHORT +#define TT_PEEK_USHORT FT_PEEK_USHORT +#define TT_PEEK_UINT24 FT_PEEK_UOFF3 +#define TT_PEEK_LONG FT_PEEK_LONG +#define TT_PEEK_ULONG FT_PEEK_ULONG + +#define TT_NEXT_SHORT FT_NEXT_SHORT +#define TT_NEXT_USHORT FT_NEXT_USHORT +#define TT_NEXT_UINT24 FT_NEXT_UOFF3 +#define TT_NEXT_LONG FT_NEXT_LONG +#define TT_NEXT_ULONG FT_NEXT_ULONG + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap_init( TT_CMap cmap, + FT_Byte* table ) + { + cmap->data = table; + return SFNT_Err_Ok; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** FORMAT 0 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* TABLE OVERVIEW */ + /* -------------- */ + /* */ + /* NAME OFFSET TYPE DESCRIPTION */ + /* */ + /* format 0 USHORT must be 0 */ + /* length 2 USHORT table length in bytes */ + /* language 4 USHORT Mac language code */ + /* glyph_ids 6 BYTE[256] array of glyph indices */ + /* 262 */ + /* */ + +#ifdef TT_CONFIG_CMAP_FORMAT_0 + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap0_validate( FT_Byte* table, + FT_Validator valid ) + { + FT_Byte* p = table + 2; + FT_UInt length = TT_NEXT_USHORT( p ); + + + if ( table + length > valid->limit || length < 262 ) + FT_INVALID_TOO_SHORT; + + /* check glyph indices whenever necessary */ + if ( valid->level >= FT_VALIDATE_TIGHT ) + { + FT_UInt n, idx; + + + p = table + 6; + for ( n = 0; n < 256; n++ ) + { + idx = *p++; + if ( idx >= TT_VALID_GLYPH_COUNT( valid ) ) + FT_INVALID_GLYPH_ID; + } + } + + return SFNT_Err_Ok; + } + + + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap0_char_index( TT_CMap cmap, + FT_UInt32 char_code ) + { + FT_Byte* table = cmap->data; + + + return char_code < 256 ? table[6 + char_code] : 0; + } + + + FT_CALLBACK_DEF( FT_UInt32 ) + tt_cmap0_char_next( TT_CMap cmap, + FT_UInt32 *pchar_code ) + { + FT_Byte* table = cmap->data; + FT_UInt32 charcode = *pchar_code; + FT_UInt32 result = 0; + FT_UInt gindex = 0; + + + table += 6; /* go to glyph IDs */ + while ( ++charcode < 256 ) + { + gindex = table[charcode]; + if ( gindex != 0 ) + { + result = charcode; + break; + } + } + + *pchar_code = result; + return gindex; + } + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap0_get_info( TT_CMap cmap, + TT_CMapInfo *cmap_info ) + { + FT_Byte* p = cmap->data + 4; + + + cmap_info->format = 0; + cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p ); + + return SFNT_Err_Ok; + } + + + FT_DEFINE_TT_CMAP(tt_cmap0_class_rec, + sizeof ( TT_CMapRec ), + + (FT_CMap_InitFunc) tt_cmap_init, + (FT_CMap_DoneFunc) NULL, + (FT_CMap_CharIndexFunc)tt_cmap0_char_index, + (FT_CMap_CharNextFunc) tt_cmap0_char_next, + + NULL, NULL, NULL, NULL, NULL + , + 0, + (TT_CMap_ValidateFunc) tt_cmap0_validate, + (TT_CMap_Info_GetFunc) tt_cmap0_get_info + ) + +#endif /* TT_CONFIG_CMAP_FORMAT_0 */ + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** FORMAT 2 *****/ + /***** *****/ + /***** This is used for certain CJK encodings that encode text in a *****/ + /***** mixed 8/16 bits encoding along the following lines: *****/ + /***** *****/ + /***** * Certain byte values correspond to an 8-bit character code *****/ + /***** (typically in the range 0..127 for ASCII compatibility). *****/ + /***** *****/ + /***** * Certain byte values signal the first byte of a 2-byte *****/ + /***** character code (but these values are also valid as the *****/ + /***** second byte of a 2-byte character). *****/ + /***** *****/ + /***** The following charmap lookup and iteration functions all *****/ + /***** assume that the value "charcode" correspond to following: *****/ + /***** *****/ + /***** - For one byte characters, "charcode" is simply the *****/ + /***** character code. *****/ + /***** *****/ + /***** - For two byte characters, "charcode" is the 2-byte *****/ + /***** character code in big endian format. More exactly: *****/ + /***** *****/ + /***** (charcode >> 8) is the first byte value *****/ + /***** (charcode & 0xFF) is the second byte value *****/ + /***** *****/ + /***** Note that not all values of "charcode" are valid according *****/ + /***** to these rules, and the function moderately check the *****/ + /***** arguments. *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* TABLE OVERVIEW */ + /* -------------- */ + /* */ + /* NAME OFFSET TYPE DESCRIPTION */ + /* */ + /* format 0 USHORT must be 2 */ + /* length 2 USHORT table length in bytes */ + /* language 4 USHORT Mac language code */ + /* keys 6 USHORT[256] sub-header keys */ + /* subs 518 SUBHEAD[NSUBS] sub-headers array */ + /* glyph_ids 518+NSUB*8 USHORT[] glyph ID array */ + /* */ + /* The `keys' table is used to map charcode high-bytes to sub-headers. */ + /* The value of `NSUBS' is the number of sub-headers defined in the */ + /* table and is computed by finding the maximum of the `keys' table. */ + /* */ + /* Note that for any n, `keys[n]' is a byte offset within the `subs' */ + /* table, i.e., it is the corresponding sub-header index multiplied */ + /* by 8. */ + /* */ + /* Each sub-header has the following format: */ + /* */ + /* NAME OFFSET TYPE DESCRIPTION */ + /* */ + /* first 0 USHORT first valid low-byte */ + /* count 2 USHORT number of valid low-bytes */ + /* delta 4 SHORT see below */ + /* offset 6 USHORT see below */ + /* */ + /* A sub-header defines, for each high-byte, the range of valid */ + /* low-bytes within the charmap. Note that the range defined by `first' */ + /* and `count' must be completely included in the interval [0..255] */ + /* according to the specification. */ + /* */ + /* If a character code is contained within a given sub-header, then */ + /* mapping it to a glyph index is done as follows: */ + /* */ + /* * The value of `offset' is read. This is a _byte_ distance from the */ + /* location of the `offset' field itself into a slice of the */ + /* `glyph_ids' table. Let's call it `slice' (it is a USHORT[] too). */ + /* */ + /* * The value `slice[char.lo - first]' is read. If it is 0, there is */ + /* no glyph for the charcode. Otherwise, the value of `delta' is */ + /* added to it (modulo 65536) to form a new glyph index. */ + /* */ + /* It is up to the validation routine to check that all offsets fall */ + /* within the glyph IDs table (and not within the `subs' table itself or */ + /* outside of the CMap). */ + /* */ + +#ifdef TT_CONFIG_CMAP_FORMAT_2 + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap2_validate( FT_Byte* table, + FT_Validator valid ) + { + FT_Byte* p = table + 2; /* skip format */ + FT_UInt length = TT_PEEK_USHORT( p ); + FT_UInt n, max_subs; + FT_Byte* keys; /* keys table */ + FT_Byte* subs; /* sub-headers */ + FT_Byte* glyph_ids; /* glyph ID array */ + + + if ( table + length > valid->limit || length < 6 + 512 ) + FT_INVALID_TOO_SHORT; + + keys = table + 6; + + /* parse keys to compute sub-headers count */ + p = keys; + max_subs = 0; + for ( n = 0; n < 256; n++ ) + { + FT_UInt idx = TT_NEXT_USHORT( p ); + + + /* value must be multiple of 8 */ + if ( valid->level >= FT_VALIDATE_PARANOID && ( idx & 7 ) != 0 ) + FT_INVALID_DATA; + + idx >>= 3; + + if ( idx > max_subs ) + max_subs = idx; + } + + FT_ASSERT( p == table + 518 ); + + subs = p; + glyph_ids = subs + (max_subs + 1) * 8; + if ( glyph_ids > valid->limit ) + FT_INVALID_TOO_SHORT; + + /* parse sub-headers */ + for ( n = 0; n <= max_subs; n++ ) + { + FT_UInt first_code, code_count, offset; + FT_Int delta; + FT_Byte* ids; + + + first_code = TT_NEXT_USHORT( p ); + code_count = TT_NEXT_USHORT( p ); + delta = TT_NEXT_SHORT( p ); + offset = TT_NEXT_USHORT( p ); + + /* many Dynalab fonts have empty sub-headers */ + if ( code_count == 0 ) + continue; + + /* check range within 0..255 */ + if ( valid->level >= FT_VALIDATE_PARANOID ) + { + if ( first_code >= 256 || first_code + code_count > 256 ) + FT_INVALID_DATA; + } + + /* check offset */ + if ( offset != 0 ) + { + ids = p - 2 + offset; + if ( ids < glyph_ids || ids + code_count*2 > table + length ) + FT_INVALID_OFFSET; + + /* check glyph IDs */ + if ( valid->level >= FT_VALIDATE_TIGHT ) + { + FT_Byte* limit = p + code_count * 2; + FT_UInt idx; + + + for ( ; p < limit; ) + { + idx = TT_NEXT_USHORT( p ); + if ( idx != 0 ) + { + idx = ( idx + delta ) & 0xFFFFU; + if ( idx >= TT_VALID_GLYPH_COUNT( valid ) ) + FT_INVALID_GLYPH_ID; + } + } + } + } + } + + return SFNT_Err_Ok; + } + + + /* return sub header corresponding to a given character code */ + /* NULL on invalid charcode */ + static FT_Byte* + tt_cmap2_get_subheader( FT_Byte* table, + FT_UInt32 char_code ) + { + FT_Byte* result = NULL; + + + if ( char_code < 0x10000UL ) + { + FT_UInt char_lo = (FT_UInt)( char_code & 0xFF ); + FT_UInt char_hi = (FT_UInt)( char_code >> 8 ); + FT_Byte* p = table + 6; /* keys table */ + FT_Byte* subs = table + 518; /* subheaders table */ + FT_Byte* sub; + + + if ( char_hi == 0 ) + { + /* an 8-bit character code -- we use subHeader 0 in this case */ + /* to test whether the character code is in the charmap */ + /* */ + sub = subs; /* jump to first sub-header */ + + /* check that the sub-header for this byte is 0, which */ + /* indicates that it is really a valid one-byte value */ + /* Otherwise, return 0 */ + /* */ + p += char_lo * 2; + if ( TT_PEEK_USHORT( p ) != 0 ) + goto Exit; + } + else + { + /* a 16-bit character code */ + + /* jump to key entry */ + p += char_hi * 2; + /* jump to sub-header */ + sub = subs + ( FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 8 ) ); + + /* check that the high byte isn't a valid one-byte value */ + if ( sub == subs ) + goto Exit; + } + result = sub; + } + Exit: + return result; + } + + + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap2_char_index( TT_CMap cmap, + FT_UInt32 char_code ) + { + FT_Byte* table = cmap->data; + FT_UInt result = 0; + FT_Byte* subheader; + + + subheader = tt_cmap2_get_subheader( table, char_code ); + if ( subheader ) + { + FT_Byte* p = subheader; + FT_UInt idx = (FT_UInt)(char_code & 0xFF); + FT_UInt start, count; + FT_Int delta; + FT_UInt offset; + + + start = TT_NEXT_USHORT( p ); + count = TT_NEXT_USHORT( p ); + delta = TT_NEXT_SHORT ( p ); + offset = TT_PEEK_USHORT( p ); + + idx -= start; + if ( idx < count && offset != 0 ) + { + p += offset + 2 * idx; + idx = TT_PEEK_USHORT( p ); + + if ( idx != 0 ) + result = (FT_UInt)( idx + delta ) & 0xFFFFU; + } + } + return result; + } + + + FT_CALLBACK_DEF( FT_UInt32 ) + tt_cmap2_char_next( TT_CMap cmap, + FT_UInt32 *pcharcode ) + { + FT_Byte* table = cmap->data; + FT_UInt gindex = 0; + FT_UInt32 result = 0; + FT_UInt32 charcode = *pcharcode + 1; + FT_Byte* subheader; + + + while ( charcode < 0x10000UL ) + { + subheader = tt_cmap2_get_subheader( table, charcode ); + if ( subheader ) + { + FT_Byte* p = subheader; + FT_UInt start = TT_NEXT_USHORT( p ); + FT_UInt count = TT_NEXT_USHORT( p ); + FT_Int delta = TT_NEXT_SHORT ( p ); + FT_UInt offset = TT_PEEK_USHORT( p ); + FT_UInt char_lo = (FT_UInt)( charcode & 0xFF ); + FT_UInt pos, idx; + + + if ( offset == 0 ) + goto Next_SubHeader; + + if ( char_lo < start ) + { + char_lo = start; + pos = 0; + } + else + pos = (FT_UInt)( char_lo - start ); + + p += offset + pos * 2; + charcode = FT_PAD_FLOOR( charcode, 256 ) + char_lo; + + for ( ; pos < count; pos++, charcode++ ) + { + idx = TT_NEXT_USHORT( p ); + + if ( idx != 0 ) + { + gindex = ( idx + delta ) & 0xFFFFU; + if ( gindex != 0 ) + { + result = charcode; + goto Exit; + } + } + } + } + + /* jump to next sub-header, i.e. higher byte value */ + Next_SubHeader: + charcode = FT_PAD_FLOOR( charcode, 256 ) + 256; + } + + Exit: + *pcharcode = result; + + return gindex; + } + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap2_get_info( TT_CMap cmap, + TT_CMapInfo *cmap_info ) + { + FT_Byte* p = cmap->data + 4; + + + cmap_info->format = 2; + cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p ); + + return SFNT_Err_Ok; + } + + + FT_DEFINE_TT_CMAP(tt_cmap2_class_rec, + sizeof ( TT_CMapRec ), + + (FT_CMap_InitFunc) tt_cmap_init, + (FT_CMap_DoneFunc) NULL, + (FT_CMap_CharIndexFunc)tt_cmap2_char_index, + (FT_CMap_CharNextFunc) tt_cmap2_char_next, + + NULL, NULL, NULL, NULL, NULL + , + 2, + (TT_CMap_ValidateFunc) tt_cmap2_validate, + (TT_CMap_Info_GetFunc) tt_cmap2_get_info + ) + +#endif /* TT_CONFIG_CMAP_FORMAT_2 */ + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** FORMAT 4 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* TABLE OVERVIEW */ + /* -------------- */ + /* */ + /* NAME OFFSET TYPE DESCRIPTION */ + /* */ + /* format 0 USHORT must be 4 */ + /* length 2 USHORT table length */ + /* in bytes */ + /* language 4 USHORT Mac language code */ + /* */ + /* segCountX2 6 USHORT 2*NUM_SEGS */ + /* searchRange 8 USHORT 2*(1 << LOG_SEGS) */ + /* entrySelector 10 USHORT LOG_SEGS */ + /* rangeShift 12 USHORT segCountX2 - */ + /* searchRange */ + /* */ + /* endCount 14 USHORT[NUM_SEGS] end charcode for */ + /* each segment; last */ + /* is 0xFFFF */ + /* */ + /* pad 14+NUM_SEGS*2 USHORT padding */ + /* */ + /* startCount 16+NUM_SEGS*2 USHORT[NUM_SEGS] first charcode for */ + /* each segment */ + /* */ + /* idDelta 16+NUM_SEGS*4 SHORT[NUM_SEGS] delta for each */ + /* segment */ + /* idOffset 16+NUM_SEGS*6 SHORT[NUM_SEGS] range offset for */ + /* each segment; can be */ + /* zero */ + /* */ + /* glyphIds 16+NUM_SEGS*8 USHORT[] array of glyph ID */ + /* ranges */ + /* */ + /* Character codes are modelled by a series of ordered (increasing) */ + /* intervals called segments. Each segment has start and end codes, */ + /* provided by the `startCount' and `endCount' arrays. Segments must */ + /* not overlap, and the last segment should always contain the value */ + /* 0xFFFF for `endCount'. */ + /* */ + /* The fields `searchRange', `entrySelector' and `rangeShift' are better */ + /* ignored (they are traces of over-engineering in the TrueType */ + /* specification). */ + /* */ + /* Each segment also has a signed `delta', as well as an optional offset */ + /* within the `glyphIds' table. */ + /* */ + /* If a segment's idOffset is 0, the glyph index corresponding to any */ + /* charcode within the segment is obtained by adding the value of */ + /* `idDelta' directly to the charcode, modulo 65536. */ + /* */ + /* Otherwise, a glyph index is taken from the glyph IDs sub-array for */ + /* the segment, and the value of `idDelta' is added to it. */ + /* */ + /* */ + /* Finally, note that a lot of fonts contain an invalid last segment, */ + /* where `start' and `end' are correctly set to 0xFFFF but both `delta' */ + /* and `offset' are incorrect (e.g., `opens___.ttf' which comes with */ + /* OpenOffice.org). We need special code to deal with them correctly. */ + /* */ + +#ifdef TT_CONFIG_CMAP_FORMAT_4 + + typedef struct TT_CMap4Rec_ + { + TT_CMapRec cmap; + FT_UInt32 cur_charcode; /* current charcode */ + FT_UInt cur_gindex; /* current glyph index */ + + FT_UInt num_ranges; + FT_UInt cur_range; + FT_UInt cur_start; + FT_UInt cur_end; + FT_Int cur_delta; + FT_Byte* cur_values; + + } TT_CMap4Rec, *TT_CMap4; + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap4_init( TT_CMap4 cmap, + FT_Byte* table ) + { + FT_Byte* p; + + + cmap->cmap.data = table; + + p = table + 6; + cmap->num_ranges = FT_PEEK_USHORT( p ) >> 1; + cmap->cur_charcode = (FT_UInt32)0xFFFFFFFFUL; + cmap->cur_gindex = 0; + + return SFNT_Err_Ok; + } + + + static FT_Int + tt_cmap4_set_range( TT_CMap4 cmap, + FT_UInt range_index ) + { + FT_Byte* table = cmap->cmap.data; + FT_Byte* p; + FT_UInt num_ranges = cmap->num_ranges; + + + while ( range_index < num_ranges ) + { + FT_UInt offset; + + + p = table + 14 + range_index * 2; + cmap->cur_end = FT_PEEK_USHORT( p ); + + p += 2 + num_ranges * 2; + cmap->cur_start = FT_PEEK_USHORT( p ); + + p += num_ranges * 2; + cmap->cur_delta = FT_PEEK_SHORT( p ); + + p += num_ranges * 2; + offset = FT_PEEK_USHORT( p ); + + /* some fonts have an incorrect last segment; */ + /* we have to catch it */ + if ( range_index >= num_ranges - 1 && + cmap->cur_start == 0xFFFFU && + cmap->cur_end == 0xFFFFU ) + { + TT_Face face = (TT_Face)cmap->cmap.cmap.charmap.face; + FT_Byte* limit = face->cmap_table + face->cmap_size; + + + if ( offset && p + offset + 2 > limit ) + { + cmap->cur_delta = 1; + offset = 0; + } + } + + if ( offset != 0xFFFFU ) + { + cmap->cur_values = offset ? p + offset : NULL; + cmap->cur_range = range_index; + return 0; + } + + /* we skip empty segments */ + range_index++; + } + + return -1; + } + + + /* search the index of the charcode next to cmap->cur_charcode; */ + /* caller should call tt_cmap4_set_range with proper range */ + /* before calling this function */ + /* */ + static void + tt_cmap4_next( TT_CMap4 cmap ) + { + FT_UInt charcode; + + + if ( cmap->cur_charcode >= 0xFFFFUL ) + goto Fail; + + charcode = (FT_UInt)cmap->cur_charcode + 1; + + if ( charcode < cmap->cur_start ) + charcode = cmap->cur_start; + + for ( ;; ) + { + FT_Byte* values = cmap->cur_values; + FT_UInt end = cmap->cur_end; + FT_Int delta = cmap->cur_delta; + + + if ( charcode <= end ) + { + if ( values ) + { + FT_Byte* p = values + 2 * ( charcode - cmap->cur_start ); + + + do + { + FT_UInt gindex = FT_NEXT_USHORT( p ); + + + if ( gindex != 0 ) + { + gindex = (FT_UInt)( ( gindex + delta ) & 0xFFFFU ); + if ( gindex != 0 ) + { + cmap->cur_charcode = charcode; + cmap->cur_gindex = gindex; + return; + } + } + } while ( ++charcode <= end ); + } + else + { + do + { + FT_UInt gindex = (FT_UInt)( ( charcode + delta ) & 0xFFFFU ); + + + if ( gindex != 0 ) + { + cmap->cur_charcode = charcode; + cmap->cur_gindex = gindex; + return; + } + } while ( ++charcode <= end ); + } + } + + /* we need to find another range */ + if ( tt_cmap4_set_range( cmap, cmap->cur_range + 1 ) < 0 ) + break; + + if ( charcode < cmap->cur_start ) + charcode = cmap->cur_start; + } + + Fail: + cmap->cur_charcode = (FT_UInt32)0xFFFFFFFFUL; + cmap->cur_gindex = 0; + } + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap4_validate( FT_Byte* table, + FT_Validator valid ) + { + FT_Byte* p = table + 2; /* skip format */ + FT_UInt length = TT_NEXT_USHORT( p ); + FT_Byte *ends, *starts, *offsets, *deltas, *glyph_ids; + FT_UInt num_segs; + FT_Error error = SFNT_Err_Ok; + + + if ( length < 16 ) + FT_INVALID_TOO_SHORT; + + /* in certain fonts, the `length' field is invalid and goes */ + /* out of bound. We try to correct this here... */ + if ( table + length > valid->limit ) + { + if ( valid->level >= FT_VALIDATE_TIGHT ) + FT_INVALID_TOO_SHORT; + + length = (FT_UInt)( valid->limit - table ); + } + + p = table + 6; + num_segs = TT_NEXT_USHORT( p ); /* read segCountX2 */ + + if ( valid->level >= FT_VALIDATE_PARANOID ) + { + /* check that we have an even value here */ + if ( num_segs & 1 ) + FT_INVALID_DATA; + } + + num_segs /= 2; + + if ( length < 16 + num_segs * 2 * 4 ) + FT_INVALID_TOO_SHORT; + + /* check the search parameters - even though we never use them */ + /* */ + if ( valid->level >= FT_VALIDATE_PARANOID ) + { + /* check the values of `searchRange', `entrySelector', `rangeShift' */ + FT_UInt search_range = TT_NEXT_USHORT( p ); + FT_UInt entry_selector = TT_NEXT_USHORT( p ); + FT_UInt range_shift = TT_NEXT_USHORT( p ); + + + if ( ( search_range | range_shift ) & 1 ) /* must be even values */ + FT_INVALID_DATA; + + search_range /= 2; + range_shift /= 2; + + /* `search range' is the greatest power of 2 that is <= num_segs */ + + if ( search_range > num_segs || + search_range * 2 < num_segs || + search_range + range_shift != num_segs || + search_range != ( 1U << entry_selector ) ) + FT_INVALID_DATA; + } + + ends = table + 14; + starts = table + 16 + num_segs * 2; + deltas = starts + num_segs * 2; + offsets = deltas + num_segs * 2; + glyph_ids = offsets + num_segs * 2; + + /* check last segment; its end count value must be 0xFFFF */ + if ( valid->level >= FT_VALIDATE_PARANOID ) + { + p = ends + ( num_segs - 1 ) * 2; + if ( TT_PEEK_USHORT( p ) != 0xFFFFU ) + FT_INVALID_DATA; + } + + { + FT_UInt start, end, offset, n; + FT_UInt last_start = 0, last_end = 0; + FT_Int delta; + FT_Byte* p_start = starts; + FT_Byte* p_end = ends; + FT_Byte* p_delta = deltas; + FT_Byte* p_offset = offsets; + + + for ( n = 0; n < num_segs; n++ ) + { + p = p_offset; + start = TT_NEXT_USHORT( p_start ); + end = TT_NEXT_USHORT( p_end ); + delta = TT_NEXT_SHORT( p_delta ); + offset = TT_NEXT_USHORT( p_offset ); + + if ( start > end ) + FT_INVALID_DATA; + + /* this test should be performed at default validation level; */ + /* unfortunately, some popular Asian fonts have overlapping */ + /* ranges in their charmaps */ + /* */ + if ( start <= last_end && n > 0 ) + { + if ( valid->level >= FT_VALIDATE_TIGHT ) + FT_INVALID_DATA; + else + { + /* allow overlapping segments, provided their start points */ + /* and end points, respectively, are in ascending order */ + /* */ + if ( last_start > start || last_end > end ) + error |= TT_CMAP_FLAG_UNSORTED; + else + error |= TT_CMAP_FLAG_OVERLAPPING; + } + } + + if ( offset && offset != 0xFFFFU ) + { + p += offset; /* start of glyph ID array */ + + /* check that we point within the glyph IDs table only */ + if ( valid->level >= FT_VALIDATE_TIGHT ) + { + if ( p < glyph_ids || + p + ( end - start + 1 ) * 2 > table + length ) + FT_INVALID_DATA; + } + /* Some fonts handle the last segment incorrectly. In */ + /* theory, 0xFFFF might point to an ordinary glyph -- */ + /* a cmap 4 is versatile and could be used for any */ + /* encoding, not only Unicode. However, reality shows */ + /* that far too many fonts are sloppy and incorrectly */ + /* set all fields but `start' and `end' for the last */ + /* segment if it contains only a single character. */ + /* */ + /* We thus omit the test here, delaying it to the */ + /* routines which actually access the cmap. */ + else if ( n != num_segs - 1 || + !( start == 0xFFFFU && end == 0xFFFFU ) ) + { + if ( p < glyph_ids || + p + ( end - start + 1 ) * 2 > valid->limit ) + FT_INVALID_DATA; + } + + /* check glyph indices within the segment range */ + if ( valid->level >= FT_VALIDATE_TIGHT ) + { + FT_UInt i, idx; + + + for ( i = start; i < end; i++ ) + { + idx = FT_NEXT_USHORT( p ); + if ( idx != 0 ) + { + idx = (FT_UInt)( idx + delta ) & 0xFFFFU; + + if ( idx >= TT_VALID_GLYPH_COUNT( valid ) ) + FT_INVALID_GLYPH_ID; + } + } + } + } + else if ( offset == 0xFFFFU ) + { + /* some fonts (erroneously?) use a range offset of 0xFFFF */ + /* to mean missing glyph in cmap table */ + /* */ + if ( valid->level >= FT_VALIDATE_PARANOID || + n != num_segs - 1 || + !( start == 0xFFFFU && end == 0xFFFFU ) ) + FT_INVALID_DATA; + } + + last_start = start; + last_end = end; + } + } + + return error; + } + + + static FT_UInt + tt_cmap4_char_map_linear( TT_CMap cmap, + FT_UInt32* pcharcode, + FT_Bool next ) + { + FT_UInt num_segs2, start, end, offset; + FT_Int delta; + FT_UInt i, num_segs; + FT_UInt32 charcode = *pcharcode; + FT_UInt gindex = 0; + FT_Byte* p; + + + p = cmap->data + 6; + num_segs2 = FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 2 ); + + num_segs = num_segs2 >> 1; + + if ( !num_segs ) + return 0; + + if ( next ) + charcode++; + + /* linear search */ + for ( ; charcode <= 0xFFFFU; charcode++ ) + { + FT_Byte* q; + + + p = cmap->data + 14; /* ends table */ + q = cmap->data + 16 + num_segs2; /* starts table */ + + for ( i = 0; i < num_segs; i++ ) + { + end = TT_NEXT_USHORT( p ); + start = TT_NEXT_USHORT( q ); + + if ( charcode >= start && charcode <= end ) + { + p = q - 2 + num_segs2; + delta = TT_PEEK_SHORT( p ); + p += num_segs2; + offset = TT_PEEK_USHORT( p ); + + /* some fonts have an incorrect last segment; */ + /* we have to catch it */ + if ( i >= num_segs - 1 && + start == 0xFFFFU && end == 0xFFFFU ) + { + TT_Face face = (TT_Face)cmap->cmap.charmap.face; + FT_Byte* limit = face->cmap_table + face->cmap_size; + + + if ( offset && p + offset + 2 > limit ) + { + delta = 1; + offset = 0; + } + } + + if ( offset == 0xFFFFU ) + continue; + + if ( offset ) + { + p += offset + ( charcode - start ) * 2; + gindex = TT_PEEK_USHORT( p ); + if ( gindex != 0 ) + gindex = (FT_UInt)( gindex + delta ) & 0xFFFFU; + } + else + gindex = (FT_UInt)( charcode + delta ) & 0xFFFFU; + + break; + } + } + + if ( !next || gindex ) + break; + } + + if ( next && gindex ) + *pcharcode = charcode; + + return gindex; + } + + + static FT_UInt + tt_cmap4_char_map_binary( TT_CMap cmap, + FT_UInt32* pcharcode, + FT_Bool next ) + { + FT_UInt num_segs2, start, end, offset; + FT_Int delta; + FT_UInt max, min, mid, num_segs; + FT_UInt charcode = (FT_UInt)*pcharcode; + FT_UInt gindex = 0; + FT_Byte* p; + + + p = cmap->data + 6; + num_segs2 = FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 2 ); + + if ( !num_segs2 ) + return 0; + + num_segs = num_segs2 >> 1; + + /* make compiler happy */ + mid = num_segs; + end = 0xFFFFU; + + if ( next ) + charcode++; + + min = 0; + max = num_segs; + + /* binary search */ + while ( min < max ) + { + mid = ( min + max ) >> 1; + p = cmap->data + 14 + mid * 2; + end = TT_PEEK_USHORT( p ); + p += 2 + num_segs2; + start = TT_PEEK_USHORT( p ); + + if ( charcode < start ) + max = mid; + else if ( charcode > end ) + min = mid + 1; + else + { + p += num_segs2; + delta = TT_PEEK_SHORT( p ); + p += num_segs2; + offset = TT_PEEK_USHORT( p ); + + /* some fonts have an incorrect last segment; */ + /* we have to catch it */ + if ( mid >= num_segs - 1 && + start == 0xFFFFU && end == 0xFFFFU ) + { + TT_Face face = (TT_Face)cmap->cmap.charmap.face; + FT_Byte* limit = face->cmap_table + face->cmap_size; + + + if ( offset && p + offset + 2 > limit ) + { + delta = 1; + offset = 0; + } + } + + /* search the first segment containing `charcode' */ + if ( cmap->flags & TT_CMAP_FLAG_OVERLAPPING ) + { + FT_UInt i; + + + /* call the current segment `max' */ + max = mid; + + if ( offset == 0xFFFFU ) + mid = max + 1; + + /* search in segments before the current segment */ + for ( i = max ; i > 0; i-- ) + { + FT_UInt prev_end; + FT_Byte* old_p; + + + old_p = p; + p = cmap->data + 14 + ( i - 1 ) * 2; + prev_end = TT_PEEK_USHORT( p ); + + if ( charcode > prev_end ) + { + p = old_p; + break; + } + + end = prev_end; + p += 2 + num_segs2; + start = TT_PEEK_USHORT( p ); + p += num_segs2; + delta = TT_PEEK_SHORT( p ); + p += num_segs2; + offset = TT_PEEK_USHORT( p ); + + if ( offset != 0xFFFFU ) + mid = i - 1; + } + + /* no luck */ + if ( mid == max + 1 ) + { + if ( i != max ) + { + p = cmap->data + 14 + max * 2; + end = TT_PEEK_USHORT( p ); + p += 2 + num_segs2; + start = TT_PEEK_USHORT( p ); + p += num_segs2; + delta = TT_PEEK_SHORT( p ); + p += num_segs2; + offset = TT_PEEK_USHORT( p ); + } + + mid = max; + + /* search in segments after the current segment */ + for ( i = max + 1; i < num_segs; i++ ) + { + FT_UInt next_end, next_start; + + + p = cmap->data + 14 + i * 2; + next_end = TT_PEEK_USHORT( p ); + p += 2 + num_segs2; + next_start = TT_PEEK_USHORT( p ); + + if ( charcode < next_start ) + break; + + end = next_end; + start = next_start; + p += num_segs2; + delta = TT_PEEK_SHORT( p ); + p += num_segs2; + offset = TT_PEEK_USHORT( p ); + + if ( offset != 0xFFFFU ) + mid = i; + } + i--; + + /* still no luck */ + if ( mid == max ) + { + mid = i; + + break; + } + } + + /* end, start, delta, and offset are for the i'th segment */ + if ( mid != i ) + { + p = cmap->data + 14 + mid * 2; + end = TT_PEEK_USHORT( p ); + p += 2 + num_segs2; + start = TT_PEEK_USHORT( p ); + p += num_segs2; + delta = TT_PEEK_SHORT( p ); + p += num_segs2; + offset = TT_PEEK_USHORT( p ); + } + } + else + { + if ( offset == 0xFFFFU ) + break; + } + + if ( offset ) + { + p += offset + ( charcode - start ) * 2; + gindex = TT_PEEK_USHORT( p ); + if ( gindex != 0 ) + gindex = (FT_UInt)( gindex + delta ) & 0xFFFFU; + } + else + gindex = (FT_UInt)( charcode + delta ) & 0xFFFFU; + + break; + } + } + + if ( next ) + { + TT_CMap4 cmap4 = (TT_CMap4)cmap; + + + /* if `charcode' is not in any segment, then `mid' is */ + /* the segment nearest to `charcode' */ + /* */ + + if ( charcode > end ) + { + mid++; + if ( mid == num_segs ) + return 0; + } + + if ( tt_cmap4_set_range( cmap4, mid ) ) + { + if ( gindex ) + *pcharcode = charcode; + } + else + { + cmap4->cur_charcode = charcode; + + if ( gindex ) + cmap4->cur_gindex = gindex; + else + { + cmap4->cur_charcode = charcode; + tt_cmap4_next( cmap4 ); + gindex = cmap4->cur_gindex; + } + + if ( gindex ) + *pcharcode = cmap4->cur_charcode; + } + } + + return gindex; + } + + + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap4_char_index( TT_CMap cmap, + FT_UInt32 char_code ) + { + if ( char_code >= 0x10000UL ) + return 0; + + if ( cmap->flags & TT_CMAP_FLAG_UNSORTED ) + return tt_cmap4_char_map_linear( cmap, &char_code, 0 ); + else + return tt_cmap4_char_map_binary( cmap, &char_code, 0 ); + } + + + FT_CALLBACK_DEF( FT_UInt32 ) + tt_cmap4_char_next( TT_CMap cmap, + FT_UInt32 *pchar_code ) + { + FT_UInt gindex; + + + if ( *pchar_code >= 0xFFFFU ) + return 0; + + if ( cmap->flags & TT_CMAP_FLAG_UNSORTED ) + gindex = tt_cmap4_char_map_linear( cmap, pchar_code, 1 ); + else + { + TT_CMap4 cmap4 = (TT_CMap4)cmap; + + + /* no need to search */ + if ( *pchar_code == cmap4->cur_charcode ) + { + tt_cmap4_next( cmap4 ); + gindex = cmap4->cur_gindex; + if ( gindex ) + *pchar_code = cmap4->cur_charcode; + } + else + gindex = tt_cmap4_char_map_binary( cmap, pchar_code, 1 ); + } + + return gindex; + } + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap4_get_info( TT_CMap cmap, + TT_CMapInfo *cmap_info ) + { + FT_Byte* p = cmap->data + 4; + + + cmap_info->format = 4; + cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p ); + + return SFNT_Err_Ok; + } + + + FT_DEFINE_TT_CMAP(tt_cmap4_class_rec, + sizeof ( TT_CMap4Rec ), + (FT_CMap_InitFunc) tt_cmap4_init, + (FT_CMap_DoneFunc) NULL, + (FT_CMap_CharIndexFunc)tt_cmap4_char_index, + (FT_CMap_CharNextFunc) tt_cmap4_char_next, + + NULL, NULL, NULL, NULL, NULL + , + 4, + (TT_CMap_ValidateFunc) tt_cmap4_validate, + (TT_CMap_Info_GetFunc) tt_cmap4_get_info + ) + +#endif /* TT_CONFIG_CMAP_FORMAT_4 */ + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** FORMAT 6 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* TABLE OVERVIEW */ + /* -------------- */ + /* */ + /* NAME OFFSET TYPE DESCRIPTION */ + /* */ + /* format 0 USHORT must be 4 */ + /* length 2 USHORT table length in bytes */ + /* language 4 USHORT Mac language code */ + /* */ + /* first 6 USHORT first segment code */ + /* count 8 USHORT segment size in chars */ + /* glyphIds 10 USHORT[count] glyph IDs */ + /* */ + /* A very simplified segment mapping. */ + /* */ + +#ifdef TT_CONFIG_CMAP_FORMAT_6 + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap6_validate( FT_Byte* table, + FT_Validator valid ) + { + FT_Byte* p; + FT_UInt length, count; + + + if ( table + 10 > valid->limit ) + FT_INVALID_TOO_SHORT; + + p = table + 2; + length = TT_NEXT_USHORT( p ); + + p = table + 8; /* skip language and start index */ + count = TT_NEXT_USHORT( p ); + + if ( table + length > valid->limit || length < 10 + count * 2 ) + FT_INVALID_TOO_SHORT; + + /* check glyph indices */ + if ( valid->level >= FT_VALIDATE_TIGHT ) + { + FT_UInt gindex; + + + for ( ; count > 0; count-- ) + { + gindex = TT_NEXT_USHORT( p ); + if ( gindex >= TT_VALID_GLYPH_COUNT( valid ) ) + FT_INVALID_GLYPH_ID; + } + } + + return SFNT_Err_Ok; + } + + + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap6_char_index( TT_CMap cmap, + FT_UInt32 char_code ) + { + FT_Byte* table = cmap->data; + FT_UInt result = 0; + FT_Byte* p = table + 6; + FT_UInt start = TT_NEXT_USHORT( p ); + FT_UInt count = TT_NEXT_USHORT( p ); + FT_UInt idx = (FT_UInt)( char_code - start ); + + + if ( idx < count ) + { + p += 2 * idx; + result = TT_PEEK_USHORT( p ); + } + return result; + } + + + FT_CALLBACK_DEF( FT_UInt32 ) + tt_cmap6_char_next( TT_CMap cmap, + FT_UInt32 *pchar_code ) + { + FT_Byte* table = cmap->data; + FT_UInt32 result = 0; + FT_UInt32 char_code = *pchar_code + 1; + FT_UInt gindex = 0; + + FT_Byte* p = table + 6; + FT_UInt start = TT_NEXT_USHORT( p ); + FT_UInt count = TT_NEXT_USHORT( p ); + FT_UInt idx; + + + if ( char_code >= 0x10000UL ) + goto Exit; + + if ( char_code < start ) + char_code = start; + + idx = (FT_UInt)( char_code - start ); + p += 2 * idx; + + for ( ; idx < count; idx++ ) + { + gindex = TT_NEXT_USHORT( p ); + if ( gindex != 0 ) + { + result = char_code; + break; + } + char_code++; + } + + Exit: + *pchar_code = result; + return gindex; + } + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap6_get_info( TT_CMap cmap, + TT_CMapInfo *cmap_info ) + { + FT_Byte* p = cmap->data + 4; + + + cmap_info->format = 6; + cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p ); + + return SFNT_Err_Ok; + } + + + FT_DEFINE_TT_CMAP(tt_cmap6_class_rec, + sizeof ( TT_CMapRec ), + + (FT_CMap_InitFunc) tt_cmap_init, + (FT_CMap_DoneFunc) NULL, + (FT_CMap_CharIndexFunc)tt_cmap6_char_index, + (FT_CMap_CharNextFunc) tt_cmap6_char_next, + + NULL, NULL, NULL, NULL, NULL + , + 6, + (TT_CMap_ValidateFunc) tt_cmap6_validate, + (TT_CMap_Info_GetFunc) tt_cmap6_get_info + ) + +#endif /* TT_CONFIG_CMAP_FORMAT_6 */ + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** FORMAT 8 *****/ + /***** *****/ + /***** It is hard to completely understand what the OpenType spec *****/ + /***** says about this format, but here is my conclusion. *****/ + /***** *****/ + /***** The purpose of this format is to easily map UTF-16 text to *****/ + /***** glyph indices. Basically, the `char_code' must be in one of *****/ + /***** the following formats: *****/ + /***** *****/ + /***** - A 16-bit value that isn't part of the Unicode Surrogates *****/ + /***** Area (i.e. U+D800-U+DFFF). *****/ + /***** *****/ + /***** - A 32-bit value, made of two surrogate values, i.e.. if *****/ + /***** `char_code = (char_hi << 16) | char_lo', then both *****/ + /***** `char_hi' and `char_lo' must be in the Surrogates Area. *****/ + /***** Area. *****/ + /***** *****/ + /***** The `is32' table embedded in the charmap indicates whether a *****/ + /***** given 16-bit value is in the surrogates area or not. *****/ + /***** *****/ + /***** So, for any given `char_code', we can assert the following: *****/ + /***** *****/ + /***** If `char_hi == 0' then we must have `is32[char_lo] == 0'. *****/ + /***** *****/ + /***** If `char_hi != 0' then we must have both *****/ + /***** `is32[char_hi] != 0' and `is32[char_lo] != 0'. *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* TABLE OVERVIEW */ + /* -------------- */ + /* */ + /* NAME OFFSET TYPE DESCRIPTION */ + /* */ + /* format 0 USHORT must be 8 */ + /* reserved 2 USHORT reserved */ + /* length 4 ULONG length in bytes */ + /* language 8 ULONG Mac language code */ + /* is32 12 BYTE[8192] 32-bitness bitmap */ + /* count 8204 ULONG number of groups */ + /* */ + /* This header is followed by `count' groups of the following format: */ + /* */ + /* start 0 ULONG first charcode */ + /* end 4 ULONG last charcode */ + /* startId 8 ULONG start glyph ID for the group */ + /* */ + +#ifdef TT_CONFIG_CMAP_FORMAT_8 + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap8_validate( FT_Byte* table, + FT_Validator valid ) + { + FT_Byte* p = table + 4; + FT_Byte* is32; + FT_UInt32 length; + FT_UInt32 num_groups; + + + if ( table + 16 + 8192 > valid->limit ) + FT_INVALID_TOO_SHORT; + + length = TT_NEXT_ULONG( p ); + if ( length > (FT_UInt32)( valid->limit - table ) || length < 8192 + 16 ) + FT_INVALID_TOO_SHORT; + + is32 = table + 12; + p = is32 + 8192; /* skip `is32' array */ + num_groups = TT_NEXT_ULONG( p ); + + if ( p + num_groups * 12 > valid->limit ) + FT_INVALID_TOO_SHORT; + + /* check groups, they must be in increasing order */ + { + FT_UInt32 n, start, end, start_id, count, last = 0; + + + for ( n = 0; n < num_groups; n++ ) + { + FT_UInt hi, lo; + + + start = TT_NEXT_ULONG( p ); + end = TT_NEXT_ULONG( p ); + start_id = TT_NEXT_ULONG( p ); + + if ( start > end ) + FT_INVALID_DATA; + + if ( n > 0 && start <= last ) + FT_INVALID_DATA; + + if ( valid->level >= FT_VALIDATE_TIGHT ) + { + if ( start_id + end - start >= TT_VALID_GLYPH_COUNT( valid ) ) + FT_INVALID_GLYPH_ID; + + count = (FT_UInt32)( end - start + 1 ); + + if ( start & ~0xFFFFU ) + { + /* start_hi != 0; check that is32[i] is 1 for each i in */ + /* the `hi' and `lo' of the range [start..end] */ + for ( ; count > 0; count--, start++ ) + { + hi = (FT_UInt)( start >> 16 ); + lo = (FT_UInt)( start & 0xFFFFU ); + + if ( (is32[hi >> 3] & ( 0x80 >> ( hi & 7 ) ) ) == 0 ) + FT_INVALID_DATA; + + if ( (is32[lo >> 3] & ( 0x80 >> ( lo & 7 ) ) ) == 0 ) + FT_INVALID_DATA; + } + } + else + { + /* start_hi == 0; check that is32[i] is 0 for each i in */ + /* the range [start..end] */ + + /* end_hi cannot be != 0! */ + if ( end & ~0xFFFFU ) + FT_INVALID_DATA; + + for ( ; count > 0; count--, start++ ) + { + lo = (FT_UInt)( start & 0xFFFFU ); + + if ( (is32[lo >> 3] & ( 0x80 >> ( lo & 7 ) ) ) != 0 ) + FT_INVALID_DATA; + } + } + } + + last = end; + } + } + + return SFNT_Err_Ok; + } + + + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap8_char_index( TT_CMap cmap, + FT_UInt32 char_code ) + { + FT_Byte* table = cmap->data; + FT_UInt result = 0; + FT_Byte* p = table + 8204; + FT_UInt32 num_groups = TT_NEXT_ULONG( p ); + FT_UInt32 start, end, start_id; + + + for ( ; num_groups > 0; num_groups-- ) + { + start = TT_NEXT_ULONG( p ); + end = TT_NEXT_ULONG( p ); + start_id = TT_NEXT_ULONG( p ); + + if ( char_code < start ) + break; + + if ( char_code <= end ) + { + result = (FT_UInt)( start_id + char_code - start ); + break; + } + } + return result; + } + + + FT_CALLBACK_DEF( FT_UInt32 ) + tt_cmap8_char_next( TT_CMap cmap, + FT_UInt32 *pchar_code ) + { + FT_UInt32 result = 0; + FT_UInt32 char_code = *pchar_code + 1; + FT_UInt gindex = 0; + FT_Byte* table = cmap->data; + FT_Byte* p = table + 8204; + FT_UInt32 num_groups = TT_NEXT_ULONG( p ); + FT_UInt32 start, end, start_id; + + + p = table + 8208; + + for ( ; num_groups > 0; num_groups-- ) + { + start = TT_NEXT_ULONG( p ); + end = TT_NEXT_ULONG( p ); + start_id = TT_NEXT_ULONG( p ); + + if ( char_code < start ) + char_code = start; + + if ( char_code <= end ) + { + gindex = (FT_UInt)( char_code - start + start_id ); + if ( gindex != 0 ) + { + result = char_code; + goto Exit; + } + } + } + + Exit: + *pchar_code = result; + return gindex; + } + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap8_get_info( TT_CMap cmap, + TT_CMapInfo *cmap_info ) + { + FT_Byte* p = cmap->data + 8; + + + cmap_info->format = 8; + cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p ); + + return SFNT_Err_Ok; + } + + + FT_DEFINE_TT_CMAP(tt_cmap8_class_rec, + sizeof ( TT_CMapRec ), + + (FT_CMap_InitFunc) tt_cmap_init, + (FT_CMap_DoneFunc) NULL, + (FT_CMap_CharIndexFunc)tt_cmap8_char_index, + (FT_CMap_CharNextFunc) tt_cmap8_char_next, + + NULL, NULL, NULL, NULL, NULL + , + 8, + (TT_CMap_ValidateFunc) tt_cmap8_validate, + (TT_CMap_Info_GetFunc) tt_cmap8_get_info + ) + +#endif /* TT_CONFIG_CMAP_FORMAT_8 */ + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** FORMAT 10 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* TABLE OVERVIEW */ + /* -------------- */ + /* */ + /* NAME OFFSET TYPE DESCRIPTION */ + /* */ + /* format 0 USHORT must be 10 */ + /* reserved 2 USHORT reserved */ + /* length 4 ULONG length in bytes */ + /* language 8 ULONG Mac language code */ + /* */ + /* start 12 ULONG first char in range */ + /* count 16 ULONG number of chars in range */ + /* glyphIds 20 USHORT[count] glyph indices covered */ + /* */ + +#ifdef TT_CONFIG_CMAP_FORMAT_10 + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap10_validate( FT_Byte* table, + FT_Validator valid ) + { + FT_Byte* p = table + 4; + FT_ULong length, count; + + + if ( table + 20 > valid->limit ) + FT_INVALID_TOO_SHORT; + + length = TT_NEXT_ULONG( p ); + p = table + 16; + count = TT_NEXT_ULONG( p ); + + if ( length > (FT_ULong)( valid->limit - table ) || + length < 20 + count * 2 ) + FT_INVALID_TOO_SHORT; + + /* check glyph indices */ + if ( valid->level >= FT_VALIDATE_TIGHT ) + { + FT_UInt gindex; + + + for ( ; count > 0; count-- ) + { + gindex = TT_NEXT_USHORT( p ); + if ( gindex >= TT_VALID_GLYPH_COUNT( valid ) ) + FT_INVALID_GLYPH_ID; + } + } + + return SFNT_Err_Ok; + } + + + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap10_char_index( TT_CMap cmap, + FT_UInt32 char_code ) + { + FT_Byte* table = cmap->data; + FT_UInt result = 0; + FT_Byte* p = table + 12; + FT_UInt32 start = TT_NEXT_ULONG( p ); + FT_UInt32 count = TT_NEXT_ULONG( p ); + FT_UInt32 idx = (FT_ULong)( char_code - start ); + + + if ( idx < count ) + { + p += 2 * idx; + result = TT_PEEK_USHORT( p ); + } + return result; + } + + + FT_CALLBACK_DEF( FT_UInt32 ) + tt_cmap10_char_next( TT_CMap cmap, + FT_UInt32 *pchar_code ) + { + FT_Byte* table = cmap->data; + FT_UInt32 char_code = *pchar_code + 1; + FT_UInt gindex = 0; + FT_Byte* p = table + 12; + FT_UInt32 start = TT_NEXT_ULONG( p ); + FT_UInt32 count = TT_NEXT_ULONG( p ); + FT_UInt32 idx; + + + if ( char_code < start ) + char_code = start; + + idx = (FT_UInt32)( char_code - start ); + p += 2 * idx; + + for ( ; idx < count; idx++ ) + { + gindex = TT_NEXT_USHORT( p ); + if ( gindex != 0 ) + break; + char_code++; + } + + *pchar_code = char_code; + return gindex; + } + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap10_get_info( TT_CMap cmap, + TT_CMapInfo *cmap_info ) + { + FT_Byte* p = cmap->data + 8; + + + cmap_info->format = 10; + cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p ); + + return SFNT_Err_Ok; + } + + + FT_DEFINE_TT_CMAP(tt_cmap10_class_rec, + sizeof ( TT_CMapRec ), + + (FT_CMap_InitFunc) tt_cmap_init, + (FT_CMap_DoneFunc) NULL, + (FT_CMap_CharIndexFunc)tt_cmap10_char_index, + (FT_CMap_CharNextFunc) tt_cmap10_char_next, + + NULL, NULL, NULL, NULL, NULL + , + 10, + (TT_CMap_ValidateFunc) tt_cmap10_validate, + (TT_CMap_Info_GetFunc) tt_cmap10_get_info + ) + +#endif /* TT_CONFIG_CMAP_FORMAT_10 */ + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** FORMAT 12 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* TABLE OVERVIEW */ + /* -------------- */ + /* */ + /* NAME OFFSET TYPE DESCRIPTION */ + /* */ + /* format 0 USHORT must be 12 */ + /* reserved 2 USHORT reserved */ + /* length 4 ULONG length in bytes */ + /* language 8 ULONG Mac language code */ + /* count 12 ULONG number of groups */ + /* 16 */ + /* */ + /* This header is followed by `count' groups of the following format: */ + /* */ + /* start 0 ULONG first charcode */ + /* end 4 ULONG last charcode */ + /* startId 8 ULONG start glyph ID for the group */ + /* */ + +#ifdef TT_CONFIG_CMAP_FORMAT_12 + + typedef struct TT_CMap12Rec_ + { + TT_CMapRec cmap; + FT_Bool valid; + FT_ULong cur_charcode; + FT_UInt cur_gindex; + FT_ULong cur_group; + FT_ULong num_groups; + + } TT_CMap12Rec, *TT_CMap12; + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap12_init( TT_CMap12 cmap, + FT_Byte* table ) + { + cmap->cmap.data = table; + + table += 12; + cmap->num_groups = FT_PEEK_ULONG( table ); + + cmap->valid = 0; + + return SFNT_Err_Ok; + } + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap12_validate( FT_Byte* table, + FT_Validator valid ) + { + FT_Byte* p; + FT_ULong length; + FT_ULong num_groups; + + + if ( table + 16 > valid->limit ) + FT_INVALID_TOO_SHORT; + + p = table + 4; + length = TT_NEXT_ULONG( p ); + + p = table + 12; + num_groups = TT_NEXT_ULONG( p ); + + if ( length > (FT_ULong)( valid->limit - table ) || + length < 16 + 12 * num_groups ) + FT_INVALID_TOO_SHORT; + + /* check groups, they must be in increasing order */ + { + FT_ULong n, start, end, start_id, last = 0; + + + for ( n = 0; n < num_groups; n++ ) + { + start = TT_NEXT_ULONG( p ); + end = TT_NEXT_ULONG( p ); + start_id = TT_NEXT_ULONG( p ); + + if ( start > end ) + FT_INVALID_DATA; + + if ( n > 0 && start <= last ) + FT_INVALID_DATA; + + if ( valid->level >= FT_VALIDATE_TIGHT ) + { + if ( start_id + end - start >= TT_VALID_GLYPH_COUNT( valid ) ) + FT_INVALID_GLYPH_ID; + } + + last = end; + } + } + + return SFNT_Err_Ok; + } + + + /* search the index of the charcode next to cmap->cur_charcode */ + /* cmap->cur_group should be set up properly by caller */ + /* */ + static void + tt_cmap12_next( TT_CMap12 cmap ) + { + FT_Byte* p; + FT_ULong start, end, start_id, char_code; + FT_ULong n; + FT_UInt gindex; + + + if ( cmap->cur_charcode >= 0xFFFFFFFFUL ) + goto Fail; + + char_code = cmap->cur_charcode + 1; + + n = cmap->cur_group; + + for ( n = cmap->cur_group; n < cmap->num_groups; n++ ) + { + p = cmap->cmap.data + 16 + 12 * n; + start = TT_NEXT_ULONG( p ); + end = TT_NEXT_ULONG( p ); + start_id = TT_PEEK_ULONG( p ); + + if ( char_code < start ) + char_code = start; + + for ( ; char_code <= end; char_code++ ) + { + gindex = (FT_UInt)( start_id + char_code - start ); + + if ( gindex ) + { + cmap->cur_charcode = char_code;; + cmap->cur_gindex = gindex; + cmap->cur_group = n; + + return; + } + } + } + + Fail: + cmap->valid = 0; + } + + + static FT_UInt + tt_cmap12_char_map_binary( TT_CMap cmap, + FT_UInt32* pchar_code, + FT_Bool next ) + { + FT_UInt gindex = 0; + FT_Byte* p = cmap->data + 12; + FT_UInt32 num_groups = TT_PEEK_ULONG( p ); + FT_UInt32 char_code = *pchar_code; + FT_UInt32 start, end, start_id; + FT_UInt32 max, min, mid; + + + if ( !num_groups ) + return 0; + + /* make compiler happy */ + mid = num_groups; + end = 0xFFFFFFFFUL; + + if ( next ) + char_code++; + + min = 0; + max = num_groups; + + /* binary search */ + while ( min < max ) + { + mid = ( min + max ) >> 1; + p = cmap->data + 16 + 12 * mid; + + start = TT_NEXT_ULONG( p ); + end = TT_NEXT_ULONG( p ); + + if ( char_code < start ) + max = mid; + else if ( char_code > end ) + min = mid + 1; + else + { + start_id = TT_PEEK_ULONG( p ); + gindex = (FT_UInt)( start_id + char_code - start ); + + break; + } + } + + if ( next ) + { + TT_CMap12 cmap12 = (TT_CMap12)cmap; + + + /* if `char_code' is not in any group, then `mid' is */ + /* the group nearest to `char_code' */ + /* */ + + if ( char_code > end ) + { + mid++; + if ( mid == num_groups ) + return 0; + } + + cmap12->valid = 1; + cmap12->cur_charcode = char_code; + cmap12->cur_group = mid; + + if ( !gindex ) + { + tt_cmap12_next( cmap12 ); + + if ( cmap12->valid ) + gindex = cmap12->cur_gindex; + } + else + cmap12->cur_gindex = gindex; + + if ( gindex ) + *pchar_code = cmap12->cur_charcode; + } + + return gindex; + } + + + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap12_char_index( TT_CMap cmap, + FT_UInt32 char_code ) + { + return tt_cmap12_char_map_binary( cmap, &char_code, 0 ); + } + + + FT_CALLBACK_DEF( FT_UInt32 ) + tt_cmap12_char_next( TT_CMap cmap, + FT_UInt32 *pchar_code ) + { + TT_CMap12 cmap12 = (TT_CMap12)cmap; + FT_ULong gindex; + + + if ( cmap12->cur_charcode >= 0xFFFFFFFFUL ) + return 0; + + /* no need to search */ + if ( cmap12->valid && cmap12->cur_charcode == *pchar_code ) + { + tt_cmap12_next( cmap12 ); + if ( cmap12->valid ) + { + gindex = cmap12->cur_gindex; + + /* XXX: check cur_charcode overflow is expected */ + if ( gindex ) + *pchar_code = (FT_UInt32)cmap12->cur_charcode; + } + else + gindex = 0; + } + else + gindex = tt_cmap12_char_map_binary( cmap, pchar_code, 1 ); + + /* XXX: check gindex overflow is expected */ + return (FT_UInt32)gindex; + } + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap12_get_info( TT_CMap cmap, + TT_CMapInfo *cmap_info ) + { + FT_Byte* p = cmap->data + 8; + + + cmap_info->format = 12; + cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p ); + + return SFNT_Err_Ok; + } + + + FT_DEFINE_TT_CMAP(tt_cmap12_class_rec, + sizeof ( TT_CMap12Rec ), + + (FT_CMap_InitFunc) tt_cmap12_init, + (FT_CMap_DoneFunc) NULL, + (FT_CMap_CharIndexFunc)tt_cmap12_char_index, + (FT_CMap_CharNextFunc) tt_cmap12_char_next, + + NULL, NULL, NULL, NULL, NULL + , + 12, + (TT_CMap_ValidateFunc) tt_cmap12_validate, + (TT_CMap_Info_GetFunc) tt_cmap12_get_info + ) + +#endif /* TT_CONFIG_CMAP_FORMAT_12 */ + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** FORMAT 13 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* TABLE OVERVIEW */ + /* -------------- */ + /* */ + /* NAME OFFSET TYPE DESCRIPTION */ + /* */ + /* format 0 USHORT must be 13 */ + /* reserved 2 USHORT reserved */ + /* length 4 ULONG length in bytes */ + /* language 8 ULONG Mac language code */ + /* count 12 ULONG number of groups */ + /* 16 */ + /* */ + /* This header is followed by `count' groups of the following format: */ + /* */ + /* start 0 ULONG first charcode */ + /* end 4 ULONG last charcode */ + /* glyphId 8 ULONG glyph ID for the whole group */ + /* */ + +#ifdef TT_CONFIG_CMAP_FORMAT_13 + + typedef struct TT_CMap13Rec_ + { + TT_CMapRec cmap; + FT_Bool valid; + FT_ULong cur_charcode; + FT_UInt cur_gindex; + FT_ULong cur_group; + FT_ULong num_groups; + + } TT_CMap13Rec, *TT_CMap13; + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap13_init( TT_CMap13 cmap, + FT_Byte* table ) + { + cmap->cmap.data = table; + + table += 12; + cmap->num_groups = FT_PEEK_ULONG( table ); + + cmap->valid = 0; + + return SFNT_Err_Ok; + } + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap13_validate( FT_Byte* table, + FT_Validator valid ) + { + FT_Byte* p; + FT_ULong length; + FT_ULong num_groups; + + + if ( table + 16 > valid->limit ) + FT_INVALID_TOO_SHORT; + + p = table + 4; + length = TT_NEXT_ULONG( p ); + + p = table + 12; + num_groups = TT_NEXT_ULONG( p ); + + if ( length > (FT_ULong)( valid->limit - table ) || + length < 16 + 12 * num_groups ) + FT_INVALID_TOO_SHORT; + + /* check groups, they must be in increasing order */ + { + FT_ULong n, start, end, glyph_id, last = 0; + + + for ( n = 0; n < num_groups; n++ ) + { + start = TT_NEXT_ULONG( p ); + end = TT_NEXT_ULONG( p ); + glyph_id = TT_NEXT_ULONG( p ); + + if ( start > end ) + FT_INVALID_DATA; + + if ( n > 0 && start <= last ) + FT_INVALID_DATA; + + if ( valid->level >= FT_VALIDATE_TIGHT ) + { + if ( glyph_id >= TT_VALID_GLYPH_COUNT( valid ) ) + FT_INVALID_GLYPH_ID; + } + + last = end; + } + } + + return SFNT_Err_Ok; + } + + + /* search the index of the charcode next to cmap->cur_charcode */ + /* cmap->cur_group should be set up properly by caller */ + /* */ + static void + tt_cmap13_next( TT_CMap13 cmap ) + { + FT_Byte* p; + FT_ULong start, end, glyph_id, char_code; + FT_ULong n; + FT_UInt gindex; + + + if ( cmap->cur_charcode >= 0xFFFFFFFFUL ) + goto Fail; + + char_code = cmap->cur_charcode + 1; + + n = cmap->cur_group; + + for ( n = cmap->cur_group; n < cmap->num_groups; n++ ) + { + p = cmap->cmap.data + 16 + 12 * n; + start = TT_NEXT_ULONG( p ); + end = TT_NEXT_ULONG( p ); + glyph_id = TT_PEEK_ULONG( p ); + + if ( char_code < start ) + char_code = start; + + if ( char_code <= end ) + { + gindex = (FT_UInt)glyph_id; + + if ( gindex ) + { + cmap->cur_charcode = char_code;; + cmap->cur_gindex = gindex; + cmap->cur_group = n; + + return; + } + } + } + + Fail: + cmap->valid = 0; + } + + + static FT_UInt + tt_cmap13_char_map_binary( TT_CMap cmap, + FT_UInt32* pchar_code, + FT_Bool next ) + { + FT_UInt gindex = 0; + FT_Byte* p = cmap->data + 12; + FT_UInt32 num_groups = TT_PEEK_ULONG( p ); + FT_UInt32 char_code = *pchar_code; + FT_UInt32 start, end; + FT_UInt32 max, min, mid; + + + if ( !num_groups ) + return 0; + + /* make compiler happy */ + mid = num_groups; + end = 0xFFFFFFFFUL; + + if ( next ) + char_code++; + + min = 0; + max = num_groups; + + /* binary search */ + while ( min < max ) + { + mid = ( min + max ) >> 1; + p = cmap->data + 16 + 12 * mid; + + start = TT_NEXT_ULONG( p ); + end = TT_NEXT_ULONG( p ); + + if ( char_code < start ) + max = mid; + else if ( char_code > end ) + min = mid + 1; + else + { + gindex = (FT_UInt)TT_PEEK_ULONG( p ); + + break; + } + } + + if ( next ) + { + TT_CMap13 cmap13 = (TT_CMap13)cmap; + + + /* if `char_code' is not in any group, then `mid' is */ + /* the group nearest to `char_code' */ + /* */ + + if ( char_code > end ) + { + mid++; + if ( mid == num_groups ) + return 0; + } + + cmap13->valid = 1; + cmap13->cur_charcode = char_code; + cmap13->cur_group = mid; + + if ( !gindex ) + { + tt_cmap13_next( cmap13 ); + + if ( cmap13->valid ) + gindex = cmap13->cur_gindex; + } + else + cmap13->cur_gindex = gindex; + + if ( gindex ) + *pchar_code = cmap13->cur_charcode; + } + + return gindex; + } + + + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap13_char_index( TT_CMap cmap, + FT_UInt32 char_code ) + { + return tt_cmap13_char_map_binary( cmap, &char_code, 0 ); + } + + + FT_CALLBACK_DEF( FT_UInt32 ) + tt_cmap13_char_next( TT_CMap cmap, + FT_UInt32 *pchar_code ) + { + TT_CMap13 cmap13 = (TT_CMap13)cmap; + FT_UInt gindex; + + + if ( cmap13->cur_charcode >= 0xFFFFFFFFUL ) + return 0; + + /* no need to search */ + if ( cmap13->valid && cmap13->cur_charcode == *pchar_code ) + { + tt_cmap13_next( cmap13 ); + if ( cmap13->valid ) + { + gindex = cmap13->cur_gindex; + if ( gindex ) + *pchar_code = cmap13->cur_charcode; + } + else + gindex = 0; + } + else + gindex = tt_cmap13_char_map_binary( cmap, pchar_code, 1 ); + + return gindex; + } + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap13_get_info( TT_CMap cmap, + TT_CMapInfo *cmap_info ) + { + FT_Byte* p = cmap->data + 8; + + + cmap_info->format = 13; + cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p ); + + return SFNT_Err_Ok; + } + + + FT_CALLBACK_TABLE_DEF + const TT_CMap_ClassRec tt_cmap13_class_rec = + { + { + sizeof ( TT_CMap13Rec ), + + (FT_CMap_InitFunc) tt_cmap13_init, + (FT_CMap_DoneFunc) NULL, + (FT_CMap_CharIndexFunc)tt_cmap13_char_index, + (FT_CMap_CharNextFunc) tt_cmap13_char_next, + + NULL, NULL, NULL, NULL, NULL + }, + 13, + (TT_CMap_ValidateFunc) tt_cmap13_validate, + (TT_CMap_Info_GetFunc) tt_cmap13_get_info + }; + +#endif /* TT_CONFIG_CMAP_FORMAT_13 */ + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** FORMAT 14 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* TABLE OVERVIEW */ + /* -------------- */ + /* */ + /* NAME OFFSET TYPE DESCRIPTION */ + /* */ + /* format 0 USHORT must be 14 */ + /* length 2 ULONG table length in bytes */ + /* numSelector 6 ULONG number of variation sel. records */ + /* */ + /* Followed by numSelector records, each of which looks like */ + /* */ + /* varSelector 0 UINT24 Unicode codepoint of sel. */ + /* defaultOff 3 ULONG offset to a default UVS table */ + /* describing any variants to be found in */ + /* the normal Unicode subtable. */ + /* nonDefOff 7 ULONG offset to a non-default UVS table */ + /* describing any variants not in the */ + /* standard cmap, with GIDs here */ + /* (either offset may be 0 NULL) */ + /* */ + /* Selectors are sorted by code point. */ + /* */ + /* A default Unicode Variation Selector (UVS) subtable is just a list of */ + /* ranges of code points which are to be found in the standard cmap. No */ + /* glyph IDs (GIDs) here. */ + /* */ + /* numRanges 0 ULONG number of ranges following */ + /* */ + /* A range looks like */ + /* */ + /* uniStart 0 UINT24 code point of the first character in */ + /* this range */ + /* additionalCnt 3 UBYTE count of additional characters in this */ + /* range (zero means a range of a single */ + /* character) */ + /* */ + /* Ranges are sorted by `uniStart'. */ + /* */ + /* A non-default Unicode Variation Selector (UVS) subtable is a list of */ + /* mappings from codepoint to GID. */ + /* */ + /* numMappings 0 ULONG number of mappings */ + /* */ + /* A range looks like */ + /* */ + /* uniStart 0 UINT24 code point of the first character in */ + /* this range */ + /* GID 3 USHORT and its GID */ + /* */ + /* Ranges are sorted by `uniStart'. */ + +#ifdef TT_CONFIG_CMAP_FORMAT_14 + + typedef struct TT_CMap14Rec_ + { + TT_CMapRec cmap; + FT_ULong num_selectors; + + /* This array is used to store the results of various + * cmap 14 query functions. The data is overwritten + * on each call to these functions. + */ + FT_UInt32 max_results; + FT_UInt32* results; + FT_Memory memory; + + } TT_CMap14Rec, *TT_CMap14; + + + FT_CALLBACK_DEF( void ) + tt_cmap14_done( TT_CMap14 cmap ) + { + FT_Memory memory = cmap->memory; + + + cmap->max_results = 0; + if ( memory != NULL && cmap->results != NULL ) + FT_FREE( cmap->results ); + } + + + static FT_Error + tt_cmap14_ensure( TT_CMap14 cmap, + FT_UInt32 num_results, + FT_Memory memory ) + { + FT_UInt32 old_max = cmap->max_results; + FT_Error error = 0; + + + if ( num_results > cmap->max_results ) + { + cmap->memory = memory; + + if ( FT_QRENEW_ARRAY( cmap->results, old_max, num_results ) ) + return error; + + cmap->max_results = num_results; + } + + return error; + } + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap14_init( TT_CMap14 cmap, + FT_Byte* table ) + { + cmap->cmap.data = table; + + table += 6; + cmap->num_selectors = FT_PEEK_ULONG( table ); + cmap->max_results = 0; + cmap->results = NULL; + + return SFNT_Err_Ok; + } + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap14_validate( FT_Byte* table, + FT_Validator valid ) + { + FT_Byte* p = table + 2; + FT_ULong length = TT_NEXT_ULONG( p ); + FT_ULong num_selectors = TT_NEXT_ULONG( p ); + + + if ( length > (FT_ULong)( valid->limit - table ) || + length < 10 + 11 * num_selectors ) + FT_INVALID_TOO_SHORT; + + /* check selectors, they must be in increasing order */ + { + /* we start lastVarSel at 1 because a variant selector value of 0 + * isn't valid. + */ + FT_ULong n, lastVarSel = 1; + + + for ( n = 0; n < num_selectors; n++ ) + { + FT_ULong varSel = TT_NEXT_UINT24( p ); + FT_ULong defOff = TT_NEXT_ULONG( p ); + FT_ULong nondefOff = TT_NEXT_ULONG( p ); + + + if ( defOff >= length || nondefOff >= length ) + FT_INVALID_TOO_SHORT; + + if ( varSel < lastVarSel ) + FT_INVALID_DATA; + + lastVarSel = varSel + 1; + + /* check the default table (these glyphs should be reached */ + /* through the normal Unicode cmap, no GIDs, just check order) */ + if ( defOff != 0 ) + { + FT_Byte* defp = table + defOff; + FT_ULong numRanges = TT_NEXT_ULONG( defp ); + FT_ULong i; + FT_ULong lastBase = 0; + + + if ( defp + numRanges * 4 > valid->limit ) + FT_INVALID_TOO_SHORT; + + for ( i = 0; i < numRanges; ++i ) + { + FT_ULong base = TT_NEXT_UINT24( defp ); + FT_ULong cnt = FT_NEXT_BYTE( defp ); + + + if ( base + cnt >= 0x110000UL ) /* end of Unicode */ + FT_INVALID_DATA; + + if ( base < lastBase ) + FT_INVALID_DATA; + + lastBase = base + cnt + 1U; + } + } + + /* and the non-default table (these glyphs are specified here) */ + if ( nondefOff != 0 ) { + FT_Byte* ndp = table + nondefOff; + FT_ULong numMappings = TT_NEXT_ULONG( ndp ); + FT_ULong i, lastUni = 0; + + + if ( numMappings * 4 > (FT_ULong)( valid->limit - ndp ) ) + FT_INVALID_TOO_SHORT; + + for ( i = 0; i < numMappings; ++i ) + { + FT_ULong uni = TT_NEXT_UINT24( ndp ); + FT_ULong gid = TT_NEXT_USHORT( ndp ); + + + if ( uni >= 0x110000UL ) /* end of Unicode */ + FT_INVALID_DATA; + + if ( uni < lastUni ) + FT_INVALID_DATA; + + lastUni = uni + 1U; + + if ( valid->level >= FT_VALIDATE_TIGHT && + gid >= TT_VALID_GLYPH_COUNT( valid ) ) + FT_INVALID_GLYPH_ID; + } + } + } + } + + return SFNT_Err_Ok; + } + + + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap14_char_index( TT_CMap cmap, + FT_UInt32 char_code ) + { + FT_UNUSED( cmap ); + FT_UNUSED( char_code ); + + /* This can't happen */ + return 0; + } + + + FT_CALLBACK_DEF( FT_UInt32 ) + tt_cmap14_char_next( TT_CMap cmap, + FT_UInt32 *pchar_code ) + { + FT_UNUSED( cmap ); + + /* This can't happen */ + *pchar_code = 0; + return 0; + } + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap14_get_info( TT_CMap cmap, + TT_CMapInfo *cmap_info ) + { + FT_UNUSED( cmap ); + + cmap_info->format = 14; + /* subtable 14 does not define a language field */ + cmap_info->language = 0xFFFFFFFFUL; + + return SFNT_Err_Ok; + } + + + static FT_UInt + tt_cmap14_char_map_def_binary( FT_Byte *base, + FT_UInt32 char_code ) + { + FT_UInt32 numRanges = TT_PEEK_ULONG( base ); + FT_UInt32 max, min; + + + min = 0; + max = numRanges; + + base += 4; + + /* binary search */ + while ( min < max ) + { + FT_UInt32 mid = ( min + max ) >> 1; + FT_Byte* p = base + 4 * mid; + FT_ULong start = TT_NEXT_UINT24( p ); + FT_UInt cnt = FT_NEXT_BYTE( p ); + + + if ( char_code < start ) + max = mid; + else if ( char_code > start+cnt ) + min = mid + 1; + else + return TRUE; + } + + return FALSE; + } + + + static FT_UInt + tt_cmap14_char_map_nondef_binary( FT_Byte *base, + FT_UInt32 char_code ) + { + FT_UInt32 numMappings = TT_PEEK_ULONG( base ); + FT_UInt32 max, min; + + + min = 0; + max = numMappings; + + base += 4; + + /* binary search */ + while ( min < max ) + { + FT_UInt32 mid = ( min + max ) >> 1; + FT_Byte* p = base + 5 * mid; + FT_UInt32 uni = (FT_UInt32)TT_NEXT_UINT24( p ); + + + if ( char_code < uni ) + max = mid; + else if ( char_code > uni ) + min = mid + 1; + else + return TT_PEEK_USHORT( p ); + } + + return 0; + } + + + static FT_Byte* + tt_cmap14_find_variant( FT_Byte *base, + FT_UInt32 variantCode ) + { + FT_UInt32 numVar = TT_PEEK_ULONG( base ); + FT_UInt32 max, min; + + + min = 0; + max = numVar; + + base += 4; + + /* binary search */ + while ( min < max ) + { + FT_UInt32 mid = ( min + max ) >> 1; + FT_Byte* p = base + 11 * mid; + FT_ULong varSel = TT_NEXT_UINT24( p ); + + + if ( variantCode < varSel ) + max = mid; + else if ( variantCode > varSel ) + min = mid + 1; + else + return p; + } + + return NULL; + } + + + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap14_char_var_index( TT_CMap cmap, + TT_CMap ucmap, + FT_UInt32 charcode, + FT_UInt32 variantSelector) + { + FT_Byte* p = tt_cmap14_find_variant( cmap->data + 6, variantSelector ); + FT_ULong defOff; + FT_ULong nondefOff; + + + if ( !p ) + return 0; + + defOff = TT_NEXT_ULONG( p ); + nondefOff = TT_PEEK_ULONG( p ); + + if ( defOff != 0 && + tt_cmap14_char_map_def_binary( cmap->data + defOff, charcode ) ) + { + /* This is the default variant of this charcode. GID not stored */ + /* here; stored in the normal Unicode charmap instead. */ + return ucmap->cmap.clazz->char_index( &ucmap->cmap, charcode ); + } + + if ( nondefOff != 0 ) + return tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff, + charcode ); + + return 0; + } + + + FT_CALLBACK_DEF( FT_Int ) + tt_cmap14_char_var_isdefault( TT_CMap cmap, + FT_UInt32 charcode, + FT_UInt32 variantSelector ) + { + FT_Byte* p = tt_cmap14_find_variant( cmap->data + 6, variantSelector ); + FT_ULong defOff; + FT_ULong nondefOff; + + + if ( !p ) + return -1; + + defOff = TT_NEXT_ULONG( p ); + nondefOff = TT_NEXT_ULONG( p ); + + if ( defOff != 0 && + tt_cmap14_char_map_def_binary( cmap->data + defOff, charcode ) ) + return 1; + + if ( nondefOff != 0 && + tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff, + charcode ) != 0 ) + return 0; + + return -1; + } + + + FT_CALLBACK_DEF( FT_UInt32* ) + tt_cmap14_variants( TT_CMap cmap, + FT_Memory memory ) + { + TT_CMap14 cmap14 = (TT_CMap14)cmap; + FT_UInt32 count = cmap14->num_selectors; + FT_Byte* p = cmap->data + 10; + FT_UInt32* result; + FT_UInt32 i; + + + if ( tt_cmap14_ensure( cmap14, ( count + 1 ), memory ) ) + return NULL; + + result = cmap14->results; + for ( i = 0; i < count; ++i ) + { + result[i] = (FT_UInt32)TT_NEXT_UINT24( p ); + p += 8; + } + result[i] = 0; + + return result; + } + + + FT_CALLBACK_DEF( FT_UInt32 * ) + tt_cmap14_char_variants( TT_CMap cmap, + FT_Memory memory, + FT_UInt32 charCode ) + { + TT_CMap14 cmap14 = (TT_CMap14) cmap; + FT_UInt32 count = cmap14->num_selectors; + FT_Byte* p = cmap->data + 10; + FT_UInt32* q; + + + if ( tt_cmap14_ensure( cmap14, ( count + 1 ), memory ) ) + return NULL; + + for ( q = cmap14->results; count > 0; --count ) + { + FT_UInt32 varSel = TT_NEXT_UINT24( p ); + FT_ULong defOff = TT_NEXT_ULONG( p ); + FT_ULong nondefOff = TT_NEXT_ULONG( p ); + + + if ( ( defOff != 0 && + tt_cmap14_char_map_def_binary( cmap->data + defOff, + charCode ) ) || + ( nondefOff != 0 && + tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff, + charCode ) != 0 ) ) + { + q[0] = varSel; + q++; + } + } + q[0] = 0; + + return cmap14->results; + } + + + static FT_UInt + tt_cmap14_def_char_count( FT_Byte *p ) + { + FT_UInt32 numRanges = (FT_UInt32)TT_NEXT_ULONG( p ); + FT_UInt tot = 0; + + + p += 3; /* point to the first `cnt' field */ + for ( ; numRanges > 0; numRanges-- ) + { + tot += 1 + p[0]; + p += 4; + } + + return tot; + } + + + static FT_UInt32* + tt_cmap14_get_def_chars( TT_CMap cmap, + FT_Byte* p, + FT_Memory memory ) + { + TT_CMap14 cmap14 = (TT_CMap14) cmap; + FT_UInt32 numRanges; + FT_UInt cnt; + FT_UInt32* q; + + + cnt = tt_cmap14_def_char_count( p ); + numRanges = (FT_UInt32)TT_NEXT_ULONG( p ); + + if ( tt_cmap14_ensure( cmap14, ( cnt + 1 ), memory ) ) + return NULL; + + for ( q = cmap14->results; numRanges > 0; --numRanges ) + { + FT_UInt32 uni = (FT_UInt32)TT_NEXT_UINT24( p ); + + + cnt = FT_NEXT_BYTE( p ) + 1; + do + { + q[0] = uni; + uni += 1; + q += 1; + } while ( --cnt != 0 ); + } + q[0] = 0; + + return cmap14->results; + } + + + static FT_UInt32* + tt_cmap14_get_nondef_chars( TT_CMap cmap, + FT_Byte *p, + FT_Memory memory ) + { + TT_CMap14 cmap14 = (TT_CMap14) cmap; + FT_UInt32 numMappings; + FT_UInt i; + FT_UInt32 *ret; + + + numMappings = (FT_UInt32)TT_NEXT_ULONG( p ); + + if ( tt_cmap14_ensure( cmap14, ( numMappings + 1 ), memory ) ) + return NULL; + + ret = cmap14->results; + for ( i = 0; i < numMappings; ++i ) + { + ret[i] = (FT_UInt32)TT_NEXT_UINT24( p ); + p += 2; + } + ret[i] = 0; + + return ret; + } + + + FT_CALLBACK_DEF( FT_UInt32 * ) + tt_cmap14_variant_chars( TT_CMap cmap, + FT_Memory memory, + FT_UInt32 variantSelector ) + { + FT_Byte *p = tt_cmap14_find_variant( cmap->data + 6, + variantSelector ); + FT_UInt32 *ret; + FT_Int i; + FT_ULong defOff; + FT_ULong nondefOff; + + + if ( !p ) + return NULL; + + defOff = TT_NEXT_ULONG( p ); + nondefOff = TT_NEXT_ULONG( p ); + + if ( defOff == 0 && nondefOff == 0 ) + return NULL; + + if ( defOff == 0 ) + return tt_cmap14_get_nondef_chars( cmap, cmap->data + nondefOff, + memory ); + else if ( nondefOff == 0 ) + return tt_cmap14_get_def_chars( cmap, cmap->data + defOff, + memory ); + else + { + /* Both a default and a non-default glyph set? That's probably not */ + /* good font design, but the spec allows for it... */ + TT_CMap14 cmap14 = (TT_CMap14) cmap; + FT_UInt32 numRanges; + FT_UInt32 numMappings; + FT_UInt32 duni; + FT_UInt32 dcnt; + FT_UInt32 nuni; + FT_Byte* dp; + FT_UInt di, ni, k; + + + p = cmap->data + nondefOff; + dp = cmap->data + defOff; + + numMappings = (FT_UInt32)TT_NEXT_ULONG( p ); + dcnt = tt_cmap14_def_char_count( dp ); + numRanges = (FT_UInt32)TT_NEXT_ULONG( dp ); + + if ( numMappings == 0 ) + return tt_cmap14_get_def_chars( cmap, cmap->data + defOff, + memory ); + if ( dcnt == 0 ) + return tt_cmap14_get_nondef_chars( cmap, cmap->data + nondefOff, + memory ); + + if ( tt_cmap14_ensure( cmap14, ( dcnt + numMappings + 1 ), memory ) ) + return NULL; + + ret = cmap14->results; + duni = (FT_UInt32)TT_NEXT_UINT24( dp ); + dcnt = FT_NEXT_BYTE( dp ); + di = 1; + nuni = (FT_UInt32)TT_NEXT_UINT24( p ); + p += 2; + ni = 1; + i = 0; + + for ( ;; ) + { + if ( nuni > duni + dcnt ) + { + for ( k = 0; k <= dcnt; ++k ) + ret[i++] = duni + k; + + ++di; + + if ( di > numRanges ) + break; + + duni = (FT_UInt32)TT_NEXT_UINT24( dp ); + dcnt = FT_NEXT_BYTE( dp ); + } + else + { + if ( nuni < duni ) + ret[i++] = nuni; + /* If it is within the default range then ignore it -- */ + /* that should not have happened */ + ++ni; + if ( ni > numMappings ) + break; + + nuni = (FT_UInt32)TT_NEXT_UINT24( p ); + p += 2; + } + } + + if ( ni <= numMappings ) + { + /* If we get here then we have run out of all default ranges. */ + /* We have read one non-default mapping which we haven't stored */ + /* and there may be others that need to be read. */ + ret[i++] = nuni; + while ( ni < numMappings ) + { + ret[i++] = (FT_UInt32)TT_NEXT_UINT24( p ); + p += 2; + ++ni; + } + } + else if ( di <= numRanges ) + { + /* If we get here then we have run out of all non-default */ + /* mappings. We have read one default range which we haven't */ + /* stored and there may be others that need to be read. */ + for ( k = 0; k <= dcnt; ++k ) + ret[i++] = duni + k; + + while ( di < numRanges ) + { + duni = (FT_UInt32)TT_NEXT_UINT24( dp ); + dcnt = FT_NEXT_BYTE( dp ); + + for ( k = 0; k <= dcnt; ++k ) + ret[i++] = duni + k; + ++di; + } + } + + ret[i] = 0; + + return ret; + } + } + + + FT_DEFINE_TT_CMAP(tt_cmap14_class_rec, + sizeof ( TT_CMap14Rec ), + + (FT_CMap_InitFunc) tt_cmap14_init, + (FT_CMap_DoneFunc) tt_cmap14_done, + (FT_CMap_CharIndexFunc)tt_cmap14_char_index, + (FT_CMap_CharNextFunc) tt_cmap14_char_next, + + /* Format 14 extension functions */ + (FT_CMap_CharVarIndexFunc) tt_cmap14_char_var_index, + (FT_CMap_CharVarIsDefaultFunc)tt_cmap14_char_var_isdefault, + (FT_CMap_VariantListFunc) tt_cmap14_variants, + (FT_CMap_CharVariantListFunc) tt_cmap14_char_variants, + (FT_CMap_VariantCharListFunc) tt_cmap14_variant_chars + , + 14, + (TT_CMap_ValidateFunc)tt_cmap14_validate, + (TT_CMap_Info_GetFunc)tt_cmap14_get_info + ) + +#endif /* TT_CONFIG_CMAP_FORMAT_14 */ + + +#ifndef FT_CONFIG_OPTION_PIC + + static const TT_CMap_Class tt_cmap_classes[] = + { +#define TTCMAPCITEM(a) &a, +#include "ttcmapc.h" + NULL, + }; + +#else /*FT_CONFIG_OPTION_PIC*/ + + void FT_Destroy_Class_tt_cmap_classes(FT_Library library, TT_CMap_Class* clazz) + { + FT_Memory memory = library->memory; + if ( clazz ) + FT_FREE( clazz ); + } + + FT_Error FT_Create_Class_tt_cmap_classes(FT_Library library, TT_CMap_Class** output_class) + { + TT_CMap_Class* clazz; + TT_CMap_ClassRec* recs; + FT_Error error; + FT_Memory memory = library->memory; + int i = 0; + +#define TTCMAPCITEM(a) i++; +#include "ttcmapc.h" + + /* allocate enough space for both the pointers +terminator and the class instances */ + if ( FT_ALLOC( clazz, sizeof(*clazz)*(i+1)+sizeof(TT_CMap_ClassRec)*i ) ) + return error; + + /* the location of the class instances follows the array of pointers */ + recs = (TT_CMap_ClassRec*) (((char*)clazz)+(sizeof(*clazz)*(i+1))); + i=0; + +#undef TTCMAPCITEM +#define TTCMAPCITEM(a) \ + FT_Init_Class_##a(&recs[i]); \ + clazz[i] = &recs[i]; \ + i++; +#include "ttcmapc.h" + + clazz[i] = NULL; + + *output_class = clazz; + return FT_Err_Ok; + } + +#endif /*FT_CONFIG_OPTION_PIC*/ + + + /* parse the `cmap' table and build the corresponding TT_CMap objects */ + /* in the current face */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_build_cmaps( TT_Face face ) + { + FT_Byte* table = face->cmap_table; + FT_Byte* limit = table + face->cmap_size; + FT_UInt volatile num_cmaps; + FT_Byte* volatile p = table; + FT_Library library = FT_FACE_LIBRARY(face); + FT_UNUSED(library); + + + if ( p + 4 > limit ) + return SFNT_Err_Invalid_Table; + + /* only recognize format 0 */ + if ( TT_NEXT_USHORT( p ) != 0 ) + { + p -= 2; + FT_ERROR(( "tt_face_build_cmaps:" + " unsupported `cmap' table format = %d\n", + TT_PEEK_USHORT( p ) )); + return SFNT_Err_Invalid_Table; + } + + num_cmaps = TT_NEXT_USHORT( p ); + + for ( ; num_cmaps > 0 && p + 8 <= limit; num_cmaps-- ) + { + FT_CharMapRec charmap; + FT_UInt32 offset; + + + charmap.platform_id = TT_NEXT_USHORT( p ); + charmap.encoding_id = TT_NEXT_USHORT( p ); + charmap.face = FT_FACE( face ); + charmap.encoding = FT_ENCODING_NONE; /* will be filled later */ + offset = TT_NEXT_ULONG( p ); + + if ( offset && offset <= face->cmap_size - 2 ) + { + FT_Byte* volatile cmap = table + offset; + volatile FT_UInt format = TT_PEEK_USHORT( cmap ); + const TT_CMap_Class* volatile pclazz = FT_TT_CMAP_CLASSES_GET; + TT_CMap_Class volatile clazz; + + + for ( ; *pclazz; pclazz++ ) + { + clazz = *pclazz; + if ( clazz->format == format ) + { + volatile TT_ValidatorRec valid; + volatile FT_Error error = SFNT_Err_Ok; + + + ft_validator_init( FT_VALIDATOR( &valid ), cmap, limit, + FT_VALIDATE_DEFAULT ); + + valid.num_glyphs = (FT_UInt)face->max_profile.numGlyphs; + + if ( ft_setjmp( + *((ft_jmp_buf*)&FT_VALIDATOR( &valid )->jump_buffer) ) == 0 ) + { + /* validate this cmap sub-table */ + error = clazz->validate( cmap, FT_VALIDATOR( &valid ) ); + } + + if ( valid.validator.error == 0 ) + { + FT_CMap ttcmap; + + + /* It might make sense to store the single variation selector */ + /* cmap somewhere special. But it would have to be in the */ + /* public FT_FaceRec, and we can't change that. */ + + if ( !FT_CMap_New( (FT_CMap_Class)clazz, + cmap, &charmap, &ttcmap ) ) + { + /* it is simpler to directly set `flags' than adding */ + /* a parameter to FT_CMap_New */ + ((TT_CMap)ttcmap)->flags = (FT_Int)error; + } + } + else + { + FT_TRACE0(( "tt_face_build_cmaps:" + " broken cmap sub-table ignored\n" )); + } + break; + } + } + + if ( *pclazz == NULL ) + { + FT_TRACE0(( "tt_face_build_cmaps:" + " unsupported cmap sub-table ignored\n" )); + } + } + } + + return SFNT_Err_Ok; + } + + + FT_LOCAL( FT_Error ) + tt_get_cmap_info( FT_CharMap charmap, + TT_CMapInfo *cmap_info ) + { + FT_CMap cmap = (FT_CMap)charmap; + TT_CMap_Class clazz = (TT_CMap_Class)cmap->clazz; + + + return clazz->get_cmap_info( charmap, cmap_info ); + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/sfnt/ttcmap.h b/mod/pub.mod/freetype.mod/src/sfnt/ttcmap.h new file mode 100644 index 0000000..15a4a21 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/sfnt/ttcmap.h @@ -0,0 +1,125 @@ +/***************************************************************************/ +/* */ +/* ttcmap.h */ +/* */ +/* TrueType character mapping table (cmap) support (specification). */ +/* */ +/* Copyright 2002, 2003, 2004, 2005 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __TTCMAP_H__ +#define __TTCMAP_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_TRUETYPE_TYPES_H +#include FT_INTERNAL_VALIDATE_H +#include FT_SERVICE_TT_CMAP_H + +FT_BEGIN_HEADER + + +#define TT_CMAP_FLAG_UNSORTED 1 +#define TT_CMAP_FLAG_OVERLAPPING 2 + + typedef struct TT_CMapRec_ + { + FT_CMapRec cmap; + FT_Byte* data; /* pointer to in-memory cmap table */ + FT_Int flags; /* for format 4 only */ + + } TT_CMapRec, *TT_CMap; + + typedef const struct TT_CMap_ClassRec_* TT_CMap_Class; + + + typedef FT_Error + (*TT_CMap_ValidateFunc)( FT_Byte* data, + FT_Validator valid ); + + typedef struct TT_CMap_ClassRec_ + { + FT_CMap_ClassRec clazz; + FT_UInt format; + TT_CMap_ValidateFunc validate; + TT_CMap_Info_GetFunc get_cmap_info; + + } TT_CMap_ClassRec; + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_TT_CMAP(class_, size_, init_, done_, char_index_, \ + char_next_, char_var_index_, char_var_default_, variant_list_, \ + charvariant_list_,variantchar_list_, \ + format_, validate_, get_cmap_info_) \ + FT_CALLBACK_TABLE_DEF \ + const TT_CMap_ClassRec class_ = \ + { \ + {size_, init_, done_, char_index_, \ + char_next_, char_var_index_, char_var_default_, variant_list_, \ + charvariant_list_, variantchar_list_}, \ + format_, validate_, get_cmap_info_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_TT_CMAP(class_, size_, init_, done_, char_index_, \ + char_next_, char_var_index_, char_var_default_, variant_list_, \ + charvariant_list_,variantchar_list_, \ + format_, validate_, get_cmap_info_) \ + void \ + FT_Init_Class_##class_( TT_CMap_ClassRec* clazz ) \ + { \ + clazz->clazz.size = size_; \ + clazz->clazz.init = init_; \ + clazz->clazz.done = done_; \ + clazz->clazz.char_index = char_index_; \ + clazz->clazz.char_next = char_next_; \ + clazz->clazz.char_var_index = char_var_index_; \ + clazz->clazz.char_var_default = char_var_default_; \ + clazz->clazz.variant_list = variant_list_; \ + clazz->clazz.charvariant_list = charvariant_list_; \ + clazz->clazz.variantchar_list = variantchar_list_; \ + clazz->format = format_; \ + clazz->validate = validate_; \ + clazz->get_cmap_info = get_cmap_info_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + typedef struct TT_ValidatorRec_ + { + FT_ValidatorRec validator; + FT_UInt num_glyphs; + + } TT_ValidatorRec, *TT_Validator; + + +#define TT_VALIDATOR( x ) ((TT_Validator)( x )) +#define TT_VALID_GLYPH_COUNT( x ) TT_VALIDATOR( x )->num_glyphs + + + FT_LOCAL( FT_Error ) + tt_face_build_cmaps( TT_Face face ); + + /* used in tt-cmaps service */ + FT_LOCAL( FT_Error ) + tt_get_cmap_info( FT_CharMap charmap, + TT_CMapInfo *cmap_info ); + + +FT_END_HEADER + +#endif /* __TTCMAP_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/sfnt/ttcmapc.h b/mod/pub.mod/freetype.mod/src/sfnt/ttcmapc.h new file mode 100644 index 0000000..4c9c6a5 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/sfnt/ttcmapc.h @@ -0,0 +1,55 @@ +/***************************************************************************/ +/* */ +/* ttcmapc.h */ +/* */ +/* TT CMAP classes definitions (specification only). */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifdef TT_CONFIG_CMAP_FORMAT_0 + TTCMAPCITEM(tt_cmap0_class_rec) +#endif + +#ifdef TT_CONFIG_CMAP_FORMAT_2 + TTCMAPCITEM(tt_cmap2_class_rec) +#endif + +#ifdef TT_CONFIG_CMAP_FORMAT_4 + TTCMAPCITEM(tt_cmap4_class_rec) +#endif + +#ifdef TT_CONFIG_CMAP_FORMAT_6 + TTCMAPCITEM(tt_cmap6_class_rec) +#endif + +#ifdef TT_CONFIG_CMAP_FORMAT_8 + TTCMAPCITEM(tt_cmap8_class_rec) +#endif + +#ifdef TT_CONFIG_CMAP_FORMAT_10 + TTCMAPCITEM(tt_cmap10_class_rec) +#endif + +#ifdef TT_CONFIG_CMAP_FORMAT_12 + TTCMAPCITEM(tt_cmap12_class_rec) +#endif + +#ifdef TT_CONFIG_CMAP_FORMAT_13 + TTCMAPCITEM(tt_cmap13_class_rec) +#endif + +#ifdef TT_CONFIG_CMAP_FORMAT_14 + TTCMAPCITEM(tt_cmap14_class_rec) +#endif + + /* END */ diff --git a/mod/pub.mod/freetype.mod/src/sfnt/ttkern.c b/mod/pub.mod/freetype.mod/src/sfnt/ttkern.c new file mode 100644 index 0000000..c154080 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/sfnt/ttkern.c @@ -0,0 +1,306 @@ +/***************************************************************************/ +/* */ +/* ttkern.c */ +/* */ +/* Load the basic TrueType kerning table. This doesn't handle */ +/* kerning data within the GPOS table at the moment. */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_TRUETYPE_TAGS_H +#include "ttkern.h" + +#include "sferrors.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_ttkern + + +#undef TT_KERN_INDEX +#define TT_KERN_INDEX( g1, g2 ) ( ( (FT_ULong)(g1) << 16 ) | (g2) ) + + + FT_LOCAL_DEF( FT_Error ) + tt_face_load_kern( TT_Face face, + FT_Stream stream ) + { + FT_Error error; + FT_ULong table_size; + FT_Byte* p; + FT_Byte* p_limit; + FT_UInt nn, num_tables; + FT_UInt32 avail = 0, ordered = 0; + + + /* the kern table is optional; exit silently if it is missing */ + error = face->goto_table( face, TTAG_kern, stream, &table_size ); + if ( error ) + goto Exit; + + if ( table_size < 4 ) /* the case of a malformed table */ + { + FT_ERROR(( "tt_face_load_kern:" + " kerning table is too small - ignored\n" )); + error = SFNT_Err_Table_Missing; + goto Exit; + } + + if ( FT_FRAME_EXTRACT( table_size, face->kern_table ) ) + { + FT_ERROR(( "tt_face_load_kern:" + " could not extract kerning table\n" )); + goto Exit; + } + + face->kern_table_size = table_size; + + p = face->kern_table; + p_limit = p + table_size; + + p += 2; /* skip version */ + num_tables = FT_NEXT_USHORT( p ); + + if ( num_tables > 32 ) /* we only support up to 32 sub-tables */ + num_tables = 32; + + for ( nn = 0; nn < num_tables; nn++ ) + { + FT_UInt num_pairs, length, coverage; + FT_Byte* p_next; + FT_UInt32 mask = (FT_UInt32)1UL << nn; + + + if ( p + 6 > p_limit ) + break; + + p_next = p; + + p += 2; /* skip version */ + length = FT_NEXT_USHORT( p ); + coverage = FT_NEXT_USHORT( p ); + + if ( length <= 6 ) + break; + + p_next += length; + + if ( p_next > p_limit ) /* handle broken table */ + p_next = p_limit; + + /* only use horizontal kerning tables */ + if ( ( coverage & ~8 ) != 0x0001 || + p + 8 > p_limit ) + goto NextTable; + + num_pairs = FT_NEXT_USHORT( p ); + p += 6; + + if ( ( p_next - p ) / 6 < (int)num_pairs ) /* handle broken count */ + num_pairs = (FT_UInt)( ( p_next - p ) / 6 ); + + avail |= mask; + + /* + * Now check whether the pairs in this table are ordered. + * We then can use binary search. + */ + if ( num_pairs > 0 ) + { + FT_ULong count; + FT_ULong old_pair; + + + old_pair = FT_NEXT_ULONG( p ); + p += 2; + + for ( count = num_pairs - 1; count > 0; count-- ) + { + FT_UInt32 cur_pair; + + + cur_pair = FT_NEXT_ULONG( p ); + if ( cur_pair <= old_pair ) + break; + + p += 2; + old_pair = cur_pair; + } + + if ( count == 0 ) + ordered |= mask; + } + + NextTable: + p = p_next; + } + + face->num_kern_tables = nn; + face->kern_avail_bits = avail; + face->kern_order_bits = ordered; + + Exit: + return error; + } + + + FT_LOCAL_DEF( void ) + tt_face_done_kern( TT_Face face ) + { + FT_Stream stream = face->root.stream; + + + FT_FRAME_RELEASE( face->kern_table ); + face->kern_table_size = 0; + face->num_kern_tables = 0; + face->kern_avail_bits = 0; + face->kern_order_bits = 0; + } + + + FT_LOCAL_DEF( FT_Int ) + tt_face_get_kerning( TT_Face face, + FT_UInt left_glyph, + FT_UInt right_glyph ) + { + FT_Int result = 0; + FT_UInt count, mask = 1; + FT_Byte* p = face->kern_table; + FT_Byte* p_limit = p + face->kern_table_size; + + + p += 4; + mask = 0x0001; + + for ( count = face->num_kern_tables; + count > 0 && p + 6 <= p_limit; + count--, mask <<= 1 ) + { + FT_Byte* base = p; + FT_Byte* next = base; + FT_UInt version = FT_NEXT_USHORT( p ); + FT_UInt length = FT_NEXT_USHORT( p ); + FT_UInt coverage = FT_NEXT_USHORT( p ); + FT_UInt num_pairs; + FT_Int value = 0; + + FT_UNUSED( version ); + + + next = base + length; + + if ( next > p_limit ) /* handle broken table */ + next = p_limit; + + if ( ( face->kern_avail_bits & mask ) == 0 ) + goto NextTable; + + if ( p + 8 > next ) + goto NextTable; + + num_pairs = FT_NEXT_USHORT( p ); + p += 6; + + if ( ( next - p ) / 6 < (int)num_pairs ) /* handle broken count */ + num_pairs = (FT_UInt)( ( next - p ) / 6 ); + + switch ( coverage >> 8 ) + { + case 0: + { + FT_ULong key0 = TT_KERN_INDEX( left_glyph, right_glyph ); + + + if ( face->kern_order_bits & mask ) /* binary search */ + { + FT_UInt min = 0; + FT_UInt max = num_pairs; + + + while ( min < max ) + { + FT_UInt mid = ( min + max ) >> 1; + FT_Byte* q = p + 6 * mid; + FT_ULong key; + + + key = FT_NEXT_ULONG( q ); + + if ( key == key0 ) + { + value = FT_PEEK_SHORT( q ); + goto Found; + } + if ( key < key0 ) + min = mid + 1; + else + max = mid; + } + } + else /* linear search */ + { + FT_UInt count2; + + + for ( count2 = num_pairs; count2 > 0; count2-- ) + { + FT_ULong key = FT_NEXT_ULONG( p ); + + + if ( key == key0 ) + { + value = FT_PEEK_SHORT( p ); + goto Found; + } + p += 2; + } + } + } + break; + + /* + * We don't support format 2 because we haven't seen a single font + * using it in real life... + */ + + default: + ; + } + + goto NextTable; + + Found: + if ( coverage & 8 ) /* override or add */ + result = value; + else + result += value; + + NextTable: + p = next; + } + + return result; + } + +#undef TT_KERN_INDEX + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/sfnt/ttkern.h b/mod/pub.mod/freetype.mod/src/sfnt/ttkern.h new file mode 100644 index 0000000..df1da9b --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/sfnt/ttkern.h @@ -0,0 +1,52 @@ +/***************************************************************************/ +/* */ +/* ttkern.h */ +/* */ +/* Load the basic TrueType kerning table. This doesn't handle */ +/* kerning data within the GPOS table at the moment. */ +/* */ +/* Copyright 1996-2001, 2002, 2005, 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __TTKERN_H__ +#define __TTKERN_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_TRUETYPE_TYPES_H + + +FT_BEGIN_HEADER + + + FT_LOCAL( FT_Error ) + tt_face_load_kern( TT_Face face, + FT_Stream stream ); + + FT_LOCAL( void ) + tt_face_done_kern( TT_Face face ); + + FT_LOCAL( FT_Int ) + tt_face_get_kerning( TT_Face face, + FT_UInt left_glyph, + FT_UInt right_glyph ); + +#define TT_FACE_HAS_KERNING( face ) ( (face)->kern_avail_bits != 0 ) + + +FT_END_HEADER + +#endif /* __TTKERN_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/sfnt/ttload.c b/mod/pub.mod/freetype.mod/src/sfnt/ttload.c new file mode 100644 index 0000000..f08f640 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/sfnt/ttload.c @@ -0,0 +1,1251 @@ +/***************************************************************************/ +/* */ +/* ttload.c */ +/* */ +/* Load the basic TrueType tables, i.e., tables that can be either in */ +/* TTF or OTF fonts (body). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_TRUETYPE_TAGS_H +#include "ttload.h" + +#include "sferrors.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_ttload + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_lookup_table */ + /* */ + /* <Description> */ + /* Looks for a TrueType table by name. */ + /* */ + /* <Input> */ + /* face :: A face object handle. */ + /* */ + /* tag :: The searched tag. */ + /* */ + /* <Return> */ + /* A pointer to the table directory entry. 0 if not found. */ + /* */ + FT_LOCAL_DEF( TT_Table ) + tt_face_lookup_table( TT_Face face, + FT_ULong tag ) + { + TT_Table entry; + TT_Table limit; +#ifdef FT_DEBUG_LEVEL_TRACE + FT_Bool zero_length = FALSE; +#endif + + + FT_TRACE4(( "tt_face_lookup_table: %08p, `%c%c%c%c' -- ", + face, + (FT_Char)( tag >> 24 ), + (FT_Char)( tag >> 16 ), + (FT_Char)( tag >> 8 ), + (FT_Char)( tag ) )); + + entry = face->dir_tables; + limit = entry + face->num_tables; + + for ( ; entry < limit; entry++ ) + { + /* For compatibility with Windows, we consider */ + /* zero-length tables the same as missing tables. */ + if ( entry->Tag == tag ) { + if ( entry->Length != 0 ) + { + FT_TRACE4(( "found table.\n" )); + return entry; + } +#ifdef FT_DEBUG_LEVEL_TRACE + zero_length = TRUE; +#endif + } + } + +#ifdef FT_DEBUG_LEVEL_TRACE + if ( zero_length ) + FT_TRACE4(( "ignoring empty table\n" )); + else + FT_TRACE4(( "could not find table\n" )); +#endif + + return NULL; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_goto_table */ + /* */ + /* <Description> */ + /* Looks for a TrueType table by name, then seek a stream to it. */ + /* */ + /* <Input> */ + /* face :: A face object handle. */ + /* */ + /* tag :: The searched tag. */ + /* */ + /* stream :: The stream to seek when the table is found. */ + /* */ + /* <Output> */ + /* length :: The length of the table if found, undefined otherwise. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_goto_table( TT_Face face, + FT_ULong tag, + FT_Stream stream, + FT_ULong* length ) + { + TT_Table table; + FT_Error error; + + + table = tt_face_lookup_table( face, tag ); + if ( table ) + { + if ( length ) + *length = table->Length; + + if ( FT_STREAM_SEEK( table->Offset ) ) + goto Exit; + } + else + error = SFNT_Err_Table_Missing; + + Exit: + return error; + } + + + /* Here, we */ + /* */ + /* - check that `num_tables' is valid (and adjust it if necessary) */ + /* */ + /* - look for a `head' table, check its size, and parse it to check */ + /* whether its `magic' field is correctly set */ + /* */ + /* - errors (except errors returned by stream handling) */ + /* */ + /* SFNT_Err_Unknown_File_Format: */ + /* no table is defined in directory, it is not sfnt-wrapped */ + /* data */ + /* SFNT_Err_Table_Missing: */ + /* table directory is valid, but essential tables */ + /* (head/bhed/SING) are missing */ + /* */ + static FT_Error + check_table_dir( SFNT_Header sfnt, + FT_Stream stream ) + { + FT_Error error; + FT_UInt nn, valid_entries = 0; + FT_UInt has_head = 0, has_sing = 0, has_meta = 0; + FT_ULong offset = sfnt->offset + 12; + + static const FT_Frame_Field table_dir_entry_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE TT_TableRec + + FT_FRAME_START( 16 ), + FT_FRAME_ULONG( Tag ), + FT_FRAME_ULONG( CheckSum ), + FT_FRAME_ULONG( Offset ), + FT_FRAME_ULONG( Length ), + FT_FRAME_END + }; + + + if ( FT_STREAM_SEEK( offset ) ) + goto Exit; + + for ( nn = 0; nn < sfnt->num_tables; nn++ ) + { + TT_TableRec table; + + + if ( FT_STREAM_READ_FIELDS( table_dir_entry_fields, &table ) ) + { + nn--; + FT_TRACE2(( "check_table_dir:" + " can read only %d table%s in font (instead of %d)\n", + nn, nn == 1 ? "" : "s", sfnt->num_tables )); + sfnt->num_tables = nn; + break; + } + + /* we ignore invalid tables */ + if ( table.Offset + table.Length > stream->size ) + { + FT_TRACE2(( "check_table_dir: table entry %d invalid\n", nn )); + continue; + } + else + valid_entries++; + + if ( table.Tag == TTAG_head || table.Tag == TTAG_bhed ) + { + FT_UInt32 magic; + + +#ifndef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + if ( table.Tag == TTAG_head ) +#endif + has_head = 1; + + /* + * The table length should be 0x36, but certain font tools make it + * 0x38, so we will just check that it is greater. + * + * Note that according to the specification, the table must be + * padded to 32-bit lengths, but this doesn't apply to the value of + * its `Length' field! + * + */ + if ( table.Length < 0x36 ) + { + FT_TRACE2(( "check_table_dir: `head' table too small\n" )); + error = SFNT_Err_Table_Missing; + goto Exit; + } + + if ( FT_STREAM_SEEK( table.Offset + 12 ) || + FT_READ_ULONG( magic ) ) + goto Exit; + + if ( magic != 0x5F0F3CF5UL ) + { + FT_TRACE2(( "check_table_dir:" + " no magic number found in `head' table\n")); + error = SFNT_Err_Table_Missing; + goto Exit; + } + + if ( FT_STREAM_SEEK( offset + ( nn + 1 ) * 16 ) ) + goto Exit; + } + else if ( table.Tag == TTAG_SING ) + has_sing = 1; + else if ( table.Tag == TTAG_META ) + has_meta = 1; + } + + sfnt->num_tables = valid_entries; + + if ( sfnt->num_tables == 0 ) + { + FT_TRACE2(( "check_table_dir: no tables found\n" )); + error = SFNT_Err_Unknown_File_Format; + goto Exit; + } + + /* if `sing' and `meta' tables are present, there is no `head' table */ + if ( has_head || ( has_sing && has_meta ) ) + { + error = SFNT_Err_Ok; + goto Exit; + } + else + { + FT_TRACE2(( "check_table_dir:" )); +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + FT_TRACE2(( " neither `head', `bhed', nor `sing' table found\n" )); +#else + FT_TRACE2(( " neither `head' nor `sing' table found\n" )); +#endif + error = SFNT_Err_Table_Missing; + } + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_load_font_dir */ + /* */ + /* <Description> */ + /* Loads the header of a SFNT font file. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: The input stream. */ + /* */ + /* <Output> */ + /* sfnt :: The SFNT header. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* The stream cursor must be at the beginning of the font directory. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_load_font_dir( TT_Face face, + FT_Stream stream ) + { + SFNT_HeaderRec sfnt; + FT_Error error; + FT_Memory memory = stream->memory; + TT_TableRec* entry; + FT_Int nn; + + static const FT_Frame_Field offset_table_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE SFNT_HeaderRec + + FT_FRAME_START( 8 ), + FT_FRAME_USHORT( num_tables ), + FT_FRAME_USHORT( search_range ), + FT_FRAME_USHORT( entry_selector ), + FT_FRAME_USHORT( range_shift ), + FT_FRAME_END + }; + + + FT_TRACE2(( "tt_face_load_font_dir: %08p\n", face )); + + /* read the offset table */ + + sfnt.offset = FT_STREAM_POS(); + + if ( FT_READ_ULONG( sfnt.format_tag ) || + FT_STREAM_READ_FIELDS( offset_table_fields, &sfnt ) ) + goto Exit; + + /* many fonts don't have these fields set correctly */ +#if 0 + if ( sfnt.search_range != 1 << ( sfnt.entry_selector + 4 ) || + sfnt.search_range + sfnt.range_shift != sfnt.num_tables << 4 ) + return SFNT_Err_Unknown_File_Format; +#endif + + /* load the table directory */ + + FT_TRACE2(( "-- Number of tables: %10u\n", sfnt.num_tables )); + FT_TRACE2(( "-- Format version: 0x%08lx\n", sfnt.format_tag )); + + /* check first */ + error = check_table_dir( &sfnt, stream ); + if ( error ) + { + FT_TRACE2(( "tt_face_load_font_dir:" + " invalid table directory for TrueType\n" )); + + goto Exit; + } + + face->num_tables = sfnt.num_tables; + face->format_tag = sfnt.format_tag; + + if ( FT_QNEW_ARRAY( face->dir_tables, face->num_tables ) ) + goto Exit; + + if ( FT_STREAM_SEEK( sfnt.offset + 12 ) || + FT_FRAME_ENTER( face->num_tables * 16L ) ) + goto Exit; + + entry = face->dir_tables; + + for ( nn = 0; nn < sfnt.num_tables; nn++ ) + { + entry->Tag = FT_GET_TAG4(); + entry->CheckSum = FT_GET_ULONG(); + entry->Offset = FT_GET_LONG(); + entry->Length = FT_GET_LONG(); + + /* ignore invalid tables */ + if ( entry->Offset + entry->Length > stream->size ) + continue; + else + { + FT_TRACE2(( " %c%c%c%c - %08lx - %08lx\n", + (FT_Char)( entry->Tag >> 24 ), + (FT_Char)( entry->Tag >> 16 ), + (FT_Char)( entry->Tag >> 8 ), + (FT_Char)( entry->Tag ), + entry->Offset, + entry->Length )); + entry++; + } + } + + FT_FRAME_EXIT(); + + FT_TRACE2(( "table directory loaded\n\n" )); + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_load_any */ + /* */ + /* <Description> */ + /* Loads any font table into client memory. */ + /* */ + /* <Input> */ + /* face :: The face object to look for. */ + /* */ + /* tag :: The tag of table to load. Use the value 0 if you want */ + /* to access the whole font file, else set this parameter */ + /* to a valid TrueType table tag that you can forge with */ + /* the MAKE_TT_TAG macro. */ + /* */ + /* offset :: The starting offset in the table (or the file if */ + /* tag == 0). */ + /* */ + /* length :: The address of the decision variable: */ + /* */ + /* If length == NULL: */ + /* Loads the whole table. Returns an error if */ + /* `offset' == 0! */ + /* */ + /* If *length == 0: */ + /* Exits immediately; returning the length of the given */ + /* table or of the font file, depending on the value of */ + /* `tag'. */ + /* */ + /* If *length != 0: */ + /* Loads the next `length' bytes of table or font, */ + /* starting at offset `offset' (in table or font too). */ + /* */ + /* <Output> */ + /* buffer :: The address of target buffer. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_load_any( TT_Face face, + FT_ULong tag, + FT_Long offset, + FT_Byte* buffer, + FT_ULong* length ) + { + FT_Error error; + FT_Stream stream; + TT_Table table; + FT_ULong size; + + + if ( tag != 0 ) + { + /* look for tag in font directory */ + table = tt_face_lookup_table( face, tag ); + if ( !table ) + { + error = SFNT_Err_Table_Missing; + goto Exit; + } + + offset += table->Offset; + size = table->Length; + } + else + /* tag == 0 -- the user wants to access the font file directly */ + size = face->root.stream->size; + + if ( length && *length == 0 ) + { + *length = size; + + return SFNT_Err_Ok; + } + + if ( length ) + size = *length; + + stream = face->root.stream; + /* the `if' is syntactic sugar for picky compilers */ + if ( FT_STREAM_READ_AT( offset, buffer, size ) ) + goto Exit; + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_load_generic_header */ + /* */ + /* <Description> */ + /* Loads the TrueType table `head' or `bhed'. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: The input stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + static FT_Error + tt_face_load_generic_header( TT_Face face, + FT_Stream stream, + FT_ULong tag ) + { + FT_Error error; + TT_Header* header; + + static const FT_Frame_Field header_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE TT_Header + + FT_FRAME_START( 54 ), + FT_FRAME_ULONG ( Table_Version ), + FT_FRAME_ULONG ( Font_Revision ), + FT_FRAME_LONG ( CheckSum_Adjust ), + FT_FRAME_LONG ( Magic_Number ), + FT_FRAME_USHORT( Flags ), + FT_FRAME_USHORT( Units_Per_EM ), + FT_FRAME_LONG ( Created[0] ), + FT_FRAME_LONG ( Created[1] ), + FT_FRAME_LONG ( Modified[0] ), + FT_FRAME_LONG ( Modified[1] ), + FT_FRAME_SHORT ( xMin ), + FT_FRAME_SHORT ( yMin ), + FT_FRAME_SHORT ( xMax ), + FT_FRAME_SHORT ( yMax ), + FT_FRAME_USHORT( Mac_Style ), + FT_FRAME_USHORT( Lowest_Rec_PPEM ), + FT_FRAME_SHORT ( Font_Direction ), + FT_FRAME_SHORT ( Index_To_Loc_Format ), + FT_FRAME_SHORT ( Glyph_Data_Format ), + FT_FRAME_END + }; + + + error = face->goto_table( face, tag, stream, 0 ); + if ( error ) + goto Exit; + + header = &face->header; + + if ( FT_STREAM_READ_FIELDS( header_fields, header ) ) + goto Exit; + + FT_TRACE3(( "Units per EM: %4u\n", header->Units_Per_EM )); + FT_TRACE3(( "IndexToLoc: %4d\n", header->Index_To_Loc_Format )); + + Exit: + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + tt_face_load_head( TT_Face face, + FT_Stream stream ) + { + return tt_face_load_generic_header( face, stream, TTAG_head ); + } + + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + + FT_LOCAL_DEF( FT_Error ) + tt_face_load_bhed( TT_Face face, + FT_Stream stream ) + { + return tt_face_load_generic_header( face, stream, TTAG_bhed ); + } + +#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_load_max_profile */ + /* */ + /* <Description> */ + /* Loads the maximum profile into a face object. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: The input stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_load_maxp( TT_Face face, + FT_Stream stream ) + { + FT_Error error; + TT_MaxProfile* maxProfile = &face->max_profile; + + const FT_Frame_Field maxp_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE TT_MaxProfile + + FT_FRAME_START( 6 ), + FT_FRAME_LONG ( version ), + FT_FRAME_USHORT( numGlyphs ), + FT_FRAME_END + }; + + const FT_Frame_Field maxp_fields_extra[] = + { + FT_FRAME_START( 26 ), + FT_FRAME_USHORT( maxPoints ), + FT_FRAME_USHORT( maxContours ), + FT_FRAME_USHORT( maxCompositePoints ), + FT_FRAME_USHORT( maxCompositeContours ), + FT_FRAME_USHORT( maxZones ), + FT_FRAME_USHORT( maxTwilightPoints ), + FT_FRAME_USHORT( maxStorage ), + FT_FRAME_USHORT( maxFunctionDefs ), + FT_FRAME_USHORT( maxInstructionDefs ), + FT_FRAME_USHORT( maxStackElements ), + FT_FRAME_USHORT( maxSizeOfInstructions ), + FT_FRAME_USHORT( maxComponentElements ), + FT_FRAME_USHORT( maxComponentDepth ), + FT_FRAME_END + }; + + + error = face->goto_table( face, TTAG_maxp, stream, 0 ); + if ( error ) + goto Exit; + + if ( FT_STREAM_READ_FIELDS( maxp_fields, maxProfile ) ) + goto Exit; + + maxProfile->maxPoints = 0; + maxProfile->maxContours = 0; + maxProfile->maxCompositePoints = 0; + maxProfile->maxCompositeContours = 0; + maxProfile->maxZones = 0; + maxProfile->maxTwilightPoints = 0; + maxProfile->maxStorage = 0; + maxProfile->maxFunctionDefs = 0; + maxProfile->maxInstructionDefs = 0; + maxProfile->maxStackElements = 0; + maxProfile->maxSizeOfInstructions = 0; + maxProfile->maxComponentElements = 0; + maxProfile->maxComponentDepth = 0; + + if ( maxProfile->version >= 0x10000L ) + { + if ( FT_STREAM_READ_FIELDS( maxp_fields_extra, maxProfile ) ) + goto Exit; + + /* XXX: an adjustment that is necessary to load certain */ + /* broken fonts like `Keystrokes MT' :-( */ + /* */ + /* We allocate 64 function entries by default when */ + /* the maxFunctionDefs field is null. */ + + if ( maxProfile->maxFunctionDefs == 0 ) + maxProfile->maxFunctionDefs = 64; + + /* we add 4 phantom points later */ + if ( maxProfile->maxTwilightPoints > ( 0xFFFFU - 4 ) ) + { + FT_TRACE0(( "tt_face_load_maxp:" + " too much twilight points in `maxp' table;\n" + " " + " some glyphs might be rendered incorrectly\n" )); + + maxProfile->maxTwilightPoints = 0xFFFFU - 4; + } + } + + FT_TRACE3(( "numGlyphs: %u\n", maxProfile->numGlyphs )); + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_load_names */ + /* */ + /* <Description> */ + /* Loads the name records. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: The input stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_load_name( TT_Face face, + FT_Stream stream ) + { + FT_Error error; + FT_Memory memory = stream->memory; + FT_ULong table_pos, table_len; + FT_ULong storage_start, storage_limit; + FT_UInt count; + TT_NameTable table; + + static const FT_Frame_Field name_table_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE TT_NameTableRec + + FT_FRAME_START( 6 ), + FT_FRAME_USHORT( format ), + FT_FRAME_USHORT( numNameRecords ), + FT_FRAME_USHORT( storageOffset ), + FT_FRAME_END + }; + + static const FT_Frame_Field name_record_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE TT_NameEntryRec + + /* no FT_FRAME_START */ + FT_FRAME_USHORT( platformID ), + FT_FRAME_USHORT( encodingID ), + FT_FRAME_USHORT( languageID ), + FT_FRAME_USHORT( nameID ), + FT_FRAME_USHORT( stringLength ), + FT_FRAME_USHORT( stringOffset ), + FT_FRAME_END + }; + + + table = &face->name_table; + table->stream = stream; + + error = face->goto_table( face, TTAG_name, stream, &table_len ); + if ( error ) + goto Exit; + + table_pos = FT_STREAM_POS(); + + + if ( FT_STREAM_READ_FIELDS( name_table_fields, table ) ) + goto Exit; + + /* Some popular Asian fonts have an invalid `storageOffset' value */ + /* (it should be at least "6 + 12*num_names"). However, the string */ + /* offsets, computed as "storageOffset + entry->stringOffset", are */ + /* valid pointers within the name table... */ + /* */ + /* We thus can't check `storageOffset' right now. */ + /* */ + storage_start = table_pos + 6 + 12*table->numNameRecords; + storage_limit = table_pos + table_len; + + if ( storage_start > storage_limit ) + { + FT_ERROR(( "tt_face_load_name: invalid `name' table\n" )); + error = SFNT_Err_Name_Table_Missing; + goto Exit; + } + + /* Allocate the array of name records. */ + count = table->numNameRecords; + table->numNameRecords = 0; + + if ( FT_NEW_ARRAY( table->names, count ) || + FT_FRAME_ENTER( count * 12 ) ) + goto Exit; + + /* Load the name records and determine how much storage is needed */ + /* to hold the strings themselves. */ + { + TT_NameEntryRec* entry = table->names; + + + for ( ; count > 0; count-- ) + { + if ( FT_STREAM_READ_FIELDS( name_record_fields, entry ) ) + continue; + + /* check that the name is not empty */ + if ( entry->stringLength == 0 ) + continue; + + /* check that the name string is within the table */ + entry->stringOffset += table_pos + table->storageOffset; + if ( entry->stringOffset < storage_start || + entry->stringOffset + entry->stringLength > storage_limit ) + { + /* invalid entry - ignore it */ + entry->stringOffset = 0; + entry->stringLength = 0; + continue; + } + + entry++; + } + + table->numNameRecords = (FT_UInt)( entry - table->names ); + } + + FT_FRAME_EXIT(); + + /* everything went well, update face->num_names */ + face->num_names = (FT_UShort) table->numNameRecords; + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_free_names */ + /* */ + /* <Description> */ + /* Frees the name records. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + FT_LOCAL_DEF( void ) + tt_face_free_name( TT_Face face ) + { + FT_Memory memory = face->root.driver->root.memory; + TT_NameTable table = &face->name_table; + TT_NameEntry entry = table->names; + FT_UInt count = table->numNameRecords; + + + if ( table->names ) + { + for ( ; count > 0; count--, entry++ ) + { + FT_FREE( entry->string ); + entry->stringLength = 0; + } + + /* free strings table */ + FT_FREE( table->names ); + } + + table->numNameRecords = 0; + table->format = 0; + table->storageOffset = 0; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_load_cmap */ + /* */ + /* <Description> */ + /* Loads the cmap directory in a face object. The cmaps themselves */ + /* are loaded on demand in the `ttcmap.c' module. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: A handle to the input stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + + FT_LOCAL_DEF( FT_Error ) + tt_face_load_cmap( TT_Face face, + FT_Stream stream ) + { + FT_Error error; + + + error = face->goto_table( face, TTAG_cmap, stream, &face->cmap_size ); + if ( error ) + goto Exit; + + if ( FT_FRAME_EXTRACT( face->cmap_size, face->cmap_table ) ) + face->cmap_size = 0; + + Exit: + return error; + } + + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_load_os2 */ + /* */ + /* <Description> */ + /* Loads the OS2 table. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: A handle to the input stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_load_os2( TT_Face face, + FT_Stream stream ) + { + FT_Error error; + TT_OS2* os2; + + const FT_Frame_Field os2_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE TT_OS2 + + FT_FRAME_START( 78 ), + FT_FRAME_USHORT( version ), + FT_FRAME_SHORT ( xAvgCharWidth ), + FT_FRAME_USHORT( usWeightClass ), + FT_FRAME_USHORT( usWidthClass ), + FT_FRAME_SHORT ( fsType ), + FT_FRAME_SHORT ( ySubscriptXSize ), + FT_FRAME_SHORT ( ySubscriptYSize ), + FT_FRAME_SHORT ( ySubscriptXOffset ), + FT_FRAME_SHORT ( ySubscriptYOffset ), + FT_FRAME_SHORT ( ySuperscriptXSize ), + FT_FRAME_SHORT ( ySuperscriptYSize ), + FT_FRAME_SHORT ( ySuperscriptXOffset ), + FT_FRAME_SHORT ( ySuperscriptYOffset ), + FT_FRAME_SHORT ( yStrikeoutSize ), + FT_FRAME_SHORT ( yStrikeoutPosition ), + FT_FRAME_SHORT ( sFamilyClass ), + FT_FRAME_BYTE ( panose[0] ), + FT_FRAME_BYTE ( panose[1] ), + FT_FRAME_BYTE ( panose[2] ), + FT_FRAME_BYTE ( panose[3] ), + FT_FRAME_BYTE ( panose[4] ), + FT_FRAME_BYTE ( panose[5] ), + FT_FRAME_BYTE ( panose[6] ), + FT_FRAME_BYTE ( panose[7] ), + FT_FRAME_BYTE ( panose[8] ), + FT_FRAME_BYTE ( panose[9] ), + FT_FRAME_ULONG ( ulUnicodeRange1 ), + FT_FRAME_ULONG ( ulUnicodeRange2 ), + FT_FRAME_ULONG ( ulUnicodeRange3 ), + FT_FRAME_ULONG ( ulUnicodeRange4 ), + FT_FRAME_BYTE ( achVendID[0] ), + FT_FRAME_BYTE ( achVendID[1] ), + FT_FRAME_BYTE ( achVendID[2] ), + FT_FRAME_BYTE ( achVendID[3] ), + + FT_FRAME_USHORT( fsSelection ), + FT_FRAME_USHORT( usFirstCharIndex ), + FT_FRAME_USHORT( usLastCharIndex ), + FT_FRAME_SHORT ( sTypoAscender ), + FT_FRAME_SHORT ( sTypoDescender ), + FT_FRAME_SHORT ( sTypoLineGap ), + FT_FRAME_USHORT( usWinAscent ), + FT_FRAME_USHORT( usWinDescent ), + FT_FRAME_END + }; + + const FT_Frame_Field os2_fields_extra[] = + { + FT_FRAME_START( 8 ), + FT_FRAME_ULONG( ulCodePageRange1 ), + FT_FRAME_ULONG( ulCodePageRange2 ), + FT_FRAME_END + }; + + const FT_Frame_Field os2_fields_extra2[] = + { + FT_FRAME_START( 10 ), + FT_FRAME_SHORT ( sxHeight ), + FT_FRAME_SHORT ( sCapHeight ), + FT_FRAME_USHORT( usDefaultChar ), + FT_FRAME_USHORT( usBreakChar ), + FT_FRAME_USHORT( usMaxContext ), + FT_FRAME_END + }; + + + /* We now support old Mac fonts where the OS/2 table doesn't */ + /* exist. Simply put, we set the `version' field to 0xFFFF */ + /* and test this value each time we need to access the table. */ + error = face->goto_table( face, TTAG_OS2, stream, 0 ); + if ( error ) + goto Exit; + + os2 = &face->os2; + + if ( FT_STREAM_READ_FIELDS( os2_fields, os2 ) ) + goto Exit; + + os2->ulCodePageRange1 = 0; + os2->ulCodePageRange2 = 0; + os2->sxHeight = 0; + os2->sCapHeight = 0; + os2->usDefaultChar = 0; + os2->usBreakChar = 0; + os2->usMaxContext = 0; + + if ( os2->version >= 0x0001 ) + { + /* only version 1 tables */ + if ( FT_STREAM_READ_FIELDS( os2_fields_extra, os2 ) ) + goto Exit; + + if ( os2->version >= 0x0002 ) + { + /* only version 2 tables */ + if ( FT_STREAM_READ_FIELDS( os2_fields_extra2, os2 ) ) + goto Exit; + } + } + + FT_TRACE3(( "sTypoAscender: %4d\n", os2->sTypoAscender )); + FT_TRACE3(( "sTypoDescender: %4d\n", os2->sTypoDescender )); + FT_TRACE3(( "usWinAscent: %4u\n", os2->usWinAscent )); + FT_TRACE3(( "usWinDescent: %4u\n", os2->usWinDescent )); + FT_TRACE3(( "fsSelection: 0x%2x\n", os2->fsSelection )); + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_load_postscript */ + /* */ + /* <Description> */ + /* Loads the Postscript table. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: A handle to the input stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_load_post( TT_Face face, + FT_Stream stream ) + { + FT_Error error; + TT_Postscript* post = &face->postscript; + + static const FT_Frame_Field post_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE TT_Postscript + + FT_FRAME_START( 32 ), + FT_FRAME_ULONG( FormatType ), + FT_FRAME_ULONG( italicAngle ), + FT_FRAME_SHORT( underlinePosition ), + FT_FRAME_SHORT( underlineThickness ), + FT_FRAME_ULONG( isFixedPitch ), + FT_FRAME_ULONG( minMemType42 ), + FT_FRAME_ULONG( maxMemType42 ), + FT_FRAME_ULONG( minMemType1 ), + FT_FRAME_ULONG( maxMemType1 ), + FT_FRAME_END + }; + + + error = face->goto_table( face, TTAG_post, stream, 0 ); + if ( error ) + return error; + + if ( FT_STREAM_READ_FIELDS( post_fields, post ) ) + return error; + + /* we don't load the glyph names, we do that in another */ + /* module (ttpost). */ + + FT_TRACE3(( "FormatType: 0x%x\n", post->FormatType )); + FT_TRACE3(( "isFixedPitch: %s\n", post->isFixedPitch + ? " yes" : " no" )); + + return SFNT_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_load_pclt */ + /* */ + /* <Description> */ + /* Loads the PCL 5 Table. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: A handle to the input stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_load_pclt( TT_Face face, + FT_Stream stream ) + { + static const FT_Frame_Field pclt_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE TT_PCLT + + FT_FRAME_START( 54 ), + FT_FRAME_ULONG ( Version ), + FT_FRAME_ULONG ( FontNumber ), + FT_FRAME_USHORT( Pitch ), + FT_FRAME_USHORT( xHeight ), + FT_FRAME_USHORT( Style ), + FT_FRAME_USHORT( TypeFamily ), + FT_FRAME_USHORT( CapHeight ), + FT_FRAME_BYTES ( TypeFace, 16 ), + FT_FRAME_BYTES ( CharacterComplement, 8 ), + FT_FRAME_BYTES ( FileName, 6 ), + FT_FRAME_CHAR ( StrokeWeight ), + FT_FRAME_CHAR ( WidthType ), + FT_FRAME_BYTE ( SerifStyle ), + FT_FRAME_BYTE ( Reserved ), + FT_FRAME_END + }; + + FT_Error error; + TT_PCLT* pclt = &face->pclt; + + + /* optional table */ + error = face->goto_table( face, TTAG_PCLT, stream, 0 ); + if ( error ) + goto Exit; + + if ( FT_STREAM_READ_FIELDS( pclt_fields, pclt ) ) + goto Exit; + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_load_gasp */ + /* */ + /* <Description> */ + /* Loads the `gasp' table into a face object. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: The input stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_load_gasp( TT_Face face, + FT_Stream stream ) + { + FT_Error error; + FT_Memory memory = stream->memory; + + FT_UInt j,num_ranges; + TT_GaspRange gaspranges; + + + /* the gasp table is optional */ + error = face->goto_table( face, TTAG_gasp, stream, 0 ); + if ( error ) + goto Exit; + + if ( FT_FRAME_ENTER( 4L ) ) + goto Exit; + + face->gasp.version = FT_GET_USHORT(); + face->gasp.numRanges = FT_GET_USHORT(); + + FT_FRAME_EXIT(); + + /* only support versions 0 and 1 of the table */ + if ( face->gasp.version >= 2 ) + { + face->gasp.numRanges = 0; + error = SFNT_Err_Invalid_Table; + goto Exit; + } + + num_ranges = face->gasp.numRanges; + FT_TRACE3(( "numRanges: %u\n", num_ranges )); + + if ( FT_QNEW_ARRAY( gaspranges, num_ranges ) || + FT_FRAME_ENTER( num_ranges * 4L ) ) + goto Exit; + + face->gasp.gaspRanges = gaspranges; + + for ( j = 0; j < num_ranges; j++ ) + { + gaspranges[j].maxPPEM = FT_GET_USHORT(); + gaspranges[j].gaspFlag = FT_GET_USHORT(); + + FT_TRACE3(( "gaspRange %d: rangeMaxPPEM %5d, rangeGaspBehavior 0x%x\n", + j, + gaspranges[j].maxPPEM, + gaspranges[j].gaspFlag )); + } + + FT_FRAME_EXIT(); + + Exit: + return error; + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/sfnt/ttload.h b/mod/pub.mod/freetype.mod/src/sfnt/ttload.h new file mode 100644 index 0000000..49a1aee --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/sfnt/ttload.h @@ -0,0 +1,112 @@ +/***************************************************************************/ +/* */ +/* ttload.h */ +/* */ +/* Load the basic TrueType tables, i.e., tables that can be either in */ +/* TTF or OTF fonts (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2005, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __TTLOAD_H__ +#define __TTLOAD_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_TRUETYPE_TYPES_H + + +FT_BEGIN_HEADER + + + FT_LOCAL( TT_Table ) + tt_face_lookup_table( TT_Face face, + FT_ULong tag ); + + FT_LOCAL( FT_Error ) + tt_face_goto_table( TT_Face face, + FT_ULong tag, + FT_Stream stream, + FT_ULong* length ); + + + FT_LOCAL( FT_Error ) + tt_face_load_font_dir( TT_Face face, + FT_Stream stream ); + + + FT_LOCAL( FT_Error ) + tt_face_load_any( TT_Face face, + FT_ULong tag, + FT_Long offset, + FT_Byte* buffer, + FT_ULong* length ); + + + FT_LOCAL( FT_Error ) + tt_face_load_head( TT_Face face, + FT_Stream stream ); + + + FT_LOCAL( FT_Error ) + tt_face_load_cmap( TT_Face face, + FT_Stream stream ); + + + FT_LOCAL( FT_Error ) + tt_face_load_maxp( TT_Face face, + FT_Stream stream ); + + + FT_LOCAL( FT_Error ) + tt_face_load_name( TT_Face face, + FT_Stream stream ); + + + FT_LOCAL( FT_Error ) + tt_face_load_os2( TT_Face face, + FT_Stream stream ); + + + FT_LOCAL( FT_Error ) + tt_face_load_post( TT_Face face, + FT_Stream stream ); + + + FT_LOCAL( FT_Error ) + tt_face_load_pclt( TT_Face face, + FT_Stream stream ); + + FT_LOCAL( void ) + tt_face_free_name( TT_Face face ); + + + FT_LOCAL( FT_Error ) + tt_face_load_gasp( TT_Face face, + FT_Stream stream ); + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + + FT_LOCAL( FT_Error ) + tt_face_load_bhed( TT_Face face, + FT_Stream stream ); + +#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ + + +FT_END_HEADER + +#endif /* __TTLOAD_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/sfnt/ttmtx.c b/mod/pub.mod/freetype.mod/src/sfnt/ttmtx.c new file mode 100644 index 0000000..53e6ac7 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/sfnt/ttmtx.c @@ -0,0 +1,468 @@ +/***************************************************************************/ +/* */ +/* ttmtx.c */ +/* */ +/* Load the metrics tables common to TTF and OTF fonts (body). */ +/* */ +/* Copyright 2006, 2007, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_TRUETYPE_TAGS_H +#include "ttmtx.h" + +#include "sferrors.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_ttmtx + + + /* + * Unfortunately, we can't enable our memory optimizations if + * FT_CONFIG_OPTION_OLD_INTERNALS is defined. This is because at least + * one rogue client (libXfont in the X.Org XServer) is directly accessing + * the metrics. + */ + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_load_hmtx */ + /* */ + /* <Description> */ + /* Load the `hmtx' or `vmtx' table into a face object. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: The input stream. */ + /* */ + /* vertical :: A boolean flag. If set, load `vmtx'. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ +#ifndef FT_CONFIG_OPTION_OLD_INTERNALS + + FT_LOCAL_DEF( FT_Error ) + tt_face_load_hmtx( TT_Face face, + FT_Stream stream, + FT_Bool vertical ) + { + FT_Error error; + FT_ULong tag, table_size; + FT_ULong* ptable_offset; + FT_ULong* ptable_size; + + + if ( vertical ) + { + tag = TTAG_vmtx; + ptable_offset = &face->vert_metrics_offset; + ptable_size = &face->vert_metrics_size; + } + else + { + tag = TTAG_hmtx; + ptable_offset = &face->horz_metrics_offset; + ptable_size = &face->horz_metrics_size; + } + + error = face->goto_table( face, tag, stream, &table_size ); + if ( error ) + goto Fail; + + *ptable_size = table_size; + *ptable_offset = FT_STREAM_POS(); + + Fail: + return error; + } + +#else /* !FT_CONFIG_OPTION_OLD_INTERNALS */ + + FT_LOCAL_DEF( FT_Error ) + tt_face_load_hmtx( TT_Face face, + FT_Stream stream, + FT_Bool vertical ) + { + FT_Error error; + FT_Memory memory = stream->memory; + + FT_ULong table_len; + FT_Long num_shorts, num_longs, num_shorts_checked; + + TT_LongMetrics* longs; + TT_ShortMetrics** shorts; + FT_Byte* p; + + + if ( vertical ) + { + void* lm = &face->vertical.long_metrics; + void** sm = &face->vertical.short_metrics; + + + error = face->goto_table( face, TTAG_vmtx, stream, &table_len ); + if ( error ) + goto Fail; + + num_longs = face->vertical.number_Of_VMetrics; + if ( (FT_ULong)num_longs > table_len / 4 ) + num_longs = (FT_Long)( table_len / 4 ); + + face->vertical.number_Of_VMetrics = 0; + + longs = (TT_LongMetrics*)lm; + shorts = (TT_ShortMetrics**)sm; + } + else + { + void* lm = &face->horizontal.long_metrics; + void** sm = &face->horizontal.short_metrics; + + + error = face->goto_table( face, TTAG_hmtx, stream, &table_len ); + if ( error ) + goto Fail; + + num_longs = face->horizontal.number_Of_HMetrics; + if ( (FT_ULong)num_longs > table_len / 4 ) + num_longs = (FT_Long)( table_len / 4 ); + + face->horizontal.number_Of_HMetrics = 0; + + longs = (TT_LongMetrics*)lm; + shorts = (TT_ShortMetrics**)sm; + } + + /* never trust derived values */ + + num_shorts = face->max_profile.numGlyphs - num_longs; + num_shorts_checked = ( table_len - num_longs * 4L ) / 2; + + if ( num_shorts < 0 ) + { + FT_TRACE0(( "tt_face_load_hmtx:" + " %cmtx has more metrics than glyphs.\n", + vertical ? "v" : "h" )); + + /* Adobe simply ignores this problem. So we shall do the same. */ +#if 0 + error = vertical ? SFNT_Err_Invalid_Vert_Metrics + : SFNT_Err_Invalid_Horiz_Metrics; + goto Exit; +#else + num_shorts = 0; +#endif + } + + if ( FT_QNEW_ARRAY( *longs, num_longs ) || + FT_QNEW_ARRAY( *shorts, num_shorts ) ) + goto Fail; + + if ( FT_FRAME_ENTER( table_len ) ) + goto Fail; + + p = stream->cursor; + + { + TT_LongMetrics cur = *longs; + TT_LongMetrics limit = cur + num_longs; + + + for ( ; cur < limit; cur++ ) + { + cur->advance = FT_NEXT_USHORT( p ); + cur->bearing = FT_NEXT_SHORT( p ); + } + } + + /* do we have an inconsistent number of metric values? */ + { + TT_ShortMetrics* cur = *shorts; + TT_ShortMetrics* limit = cur + + FT_MIN( num_shorts, num_shorts_checked ); + + + for ( ; cur < limit; cur++ ) + *cur = FT_NEXT_SHORT( p ); + + /* We fill up the missing left side bearings with the */ + /* last valid value. Since this will occur for buggy CJK */ + /* fonts usually only, nothing serious will happen. */ + if ( num_shorts > num_shorts_checked && num_shorts_checked > 0 ) + { + FT_Short val = (*shorts)[num_shorts_checked - 1]; + + + limit = *shorts + num_shorts; + for ( ; cur < limit; cur++ ) + *cur = val; + } + } + + FT_FRAME_EXIT(); + + if ( vertical ) + face->vertical.number_Of_VMetrics = (FT_UShort)num_longs; + else + face->horizontal.number_Of_HMetrics = (FT_UShort)num_longs; + + Fail: + return error; + } + +#endif /* !FT_CONFIG_OPTION_OLD_INTERNALS */ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_load_hhea */ + /* */ + /* <Description> */ + /* Load the `hhea' or 'vhea' table into a face object. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: The input stream. */ + /* */ + /* vertical :: A boolean flag. If set, load `vhea'. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_load_hhea( TT_Face face, + FT_Stream stream, + FT_Bool vertical ) + { + FT_Error error; + TT_HoriHeader* header; + + const FT_Frame_Field metrics_header_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE TT_HoriHeader + + FT_FRAME_START( 36 ), + FT_FRAME_ULONG ( Version ), + FT_FRAME_SHORT ( Ascender ), + FT_FRAME_SHORT ( Descender ), + FT_FRAME_SHORT ( Line_Gap ), + FT_FRAME_USHORT( advance_Width_Max ), + FT_FRAME_SHORT ( min_Left_Side_Bearing ), + FT_FRAME_SHORT ( min_Right_Side_Bearing ), + FT_FRAME_SHORT ( xMax_Extent ), + FT_FRAME_SHORT ( caret_Slope_Rise ), + FT_FRAME_SHORT ( caret_Slope_Run ), + FT_FRAME_SHORT ( caret_Offset ), + FT_FRAME_SHORT ( Reserved[0] ), + FT_FRAME_SHORT ( Reserved[1] ), + FT_FRAME_SHORT ( Reserved[2] ), + FT_FRAME_SHORT ( Reserved[3] ), + FT_FRAME_SHORT ( metric_Data_Format ), + FT_FRAME_USHORT( number_Of_HMetrics ), + FT_FRAME_END + }; + + + if ( vertical ) + { + void *v = &face->vertical; + + + error = face->goto_table( face, TTAG_vhea, stream, 0 ); + if ( error ) + goto Fail; + + header = (TT_HoriHeader*)v; + } + else + { + error = face->goto_table( face, TTAG_hhea, stream, 0 ); + if ( error ) + goto Fail; + + header = &face->horizontal; + } + + if ( FT_STREAM_READ_FIELDS( metrics_header_fields, header ) ) + goto Fail; + + FT_TRACE3(( "Ascender: %5d\n", header->Ascender )); + FT_TRACE3(( "Descender: %5d\n", header->Descender )); + FT_TRACE3(( "number_Of_Metrics: %5u\n", header->number_Of_HMetrics )); + + header->long_metrics = NULL; + header->short_metrics = NULL; + + Fail: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_get_metrics */ + /* */ + /* <Description> */ + /* Returns the horizontal or vertical metrics in font units for a */ + /* given glyph. The metrics are the left side bearing (resp. top */ + /* side bearing) and advance width (resp. advance height). */ + /* */ + /* <Input> */ + /* header :: A pointer to either the horizontal or vertical metrics */ + /* structure. */ + /* */ + /* idx :: The glyph index. */ + /* */ + /* <Output> */ + /* bearing :: The bearing, either left side or top side. */ + /* */ + /* advance :: The advance width resp. advance height. */ + /* */ +#ifndef FT_CONFIG_OPTION_OLD_INTERNALS + + FT_LOCAL_DEF( FT_Error ) + tt_face_get_metrics( TT_Face face, + FT_Bool vertical, + FT_UInt gindex, + FT_Short *abearing, + FT_UShort *aadvance ) + { + FT_Error error; + FT_Stream stream = face->root.stream; + TT_HoriHeader* header; + FT_ULong table_pos, table_size, table_end; + FT_UShort k; + + + if ( vertical ) + { + void* v = &face->vertical; + + + header = (TT_HoriHeader*)v; + table_pos = face->vert_metrics_offset; + table_size = face->vert_metrics_size; + } + else + { + header = &face->horizontal; + table_pos = face->horz_metrics_offset; + table_size = face->horz_metrics_size; + } + + table_end = table_pos + table_size; + + k = header->number_Of_HMetrics; + + if ( k > 0 ) + { + if ( gindex < (FT_UInt)k ) + { + table_pos += 4 * gindex; + if ( table_pos + 4 > table_end ) + goto NoData; + + if ( FT_STREAM_SEEK( table_pos ) || + FT_READ_USHORT( *aadvance ) || + FT_READ_SHORT( *abearing ) ) + goto NoData; + } + else + { + table_pos += 4 * ( k - 1 ); + if ( table_pos + 4 > table_end ) + goto NoData; + + if ( FT_STREAM_SEEK( table_pos ) || + FT_READ_USHORT( *aadvance ) ) + goto NoData; + + table_pos += 4 + 2 * ( gindex - k ); + if ( table_pos + 2 > table_end ) + *abearing = 0; + else + { + if ( !FT_STREAM_SEEK( table_pos ) ) + (void)FT_READ_SHORT( *abearing ); + } + } + } + else + { + NoData: + *abearing = 0; + *aadvance = 0; + } + + return SFNT_Err_Ok; + } + +#else /* !FT_CONFIG_OPTION_OLD_INTERNALS */ + + FT_LOCAL_DEF( FT_Error ) + tt_face_get_metrics( TT_Face face, + FT_Bool vertical, + FT_UInt gindex, + FT_Short* abearing, + FT_UShort* aadvance ) + { + void* v = &face->vertical; + void* h = &face->horizontal; + TT_HoriHeader* header = vertical ? (TT_HoriHeader*)v + : (TT_HoriHeader*)h; + TT_LongMetrics longs_m; + FT_UShort k = header->number_Of_HMetrics; + + + if ( k == 0 || + !header->long_metrics || + gindex >= (FT_UInt)face->max_profile.numGlyphs ) + { + *abearing = *aadvance = 0; + return SFNT_Err_Ok; + } + + if ( gindex < (FT_UInt)k ) + { + longs_m = (TT_LongMetrics)header->long_metrics + gindex; + *abearing = longs_m->bearing; + *aadvance = longs_m->advance; + } + else + { + *abearing = ((TT_ShortMetrics*)header->short_metrics)[gindex - k]; + *aadvance = ((TT_LongMetrics)header->long_metrics)[k - 1].advance; + } + + return SFNT_Err_Ok; + } + +#endif /* !FT_CONFIG_OPTION_OLD_INTERNALS */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/sfnt/ttmtx.h b/mod/pub.mod/freetype.mod/src/sfnt/ttmtx.h new file mode 100644 index 0000000..8b91a11 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/sfnt/ttmtx.h @@ -0,0 +1,55 @@ +/***************************************************************************/ +/* */ +/* ttmtx.h */ +/* */ +/* Load the metrics tables common to TTF and OTF fonts (specification). */ +/* */ +/* Copyright 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __TTMTX_H__ +#define __TTMTX_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_TRUETYPE_TYPES_H + + +FT_BEGIN_HEADER + + + FT_LOCAL( FT_Error ) + tt_face_load_hhea( TT_Face face, + FT_Stream stream, + FT_Bool vertical ); + + + FT_LOCAL( FT_Error ) + tt_face_load_hmtx( TT_Face face, + FT_Stream stream, + FT_Bool vertical ); + + + FT_LOCAL( FT_Error ) + tt_face_get_metrics( TT_Face face, + FT_Bool vertical, + FT_UInt gindex, + FT_Short* abearing, + FT_UShort* aadvance ); + +FT_END_HEADER + +#endif /* __TTMTX_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/sfnt/ttpost.c b/mod/pub.mod/freetype.mod/src/sfnt/ttpost.c new file mode 100644 index 0000000..aa0bf1e --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/sfnt/ttpost.c @@ -0,0 +1,521 @@ +/***************************************************************************/ +/* */ +/* ttpost.c */ +/* */ +/* Postcript name table processing for TrueType and OpenType fonts */ +/* (body). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2006, 2007, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + /*************************************************************************/ + /* */ + /* The post table is not completely loaded by the core engine. This */ + /* file loads the missing PS glyph names and implements an API to access */ + /* them. */ + /* */ + /*************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_STREAM_H +#include FT_TRUETYPE_TAGS_H +#include "ttpost.h" + +#include "sferrors.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_ttpost + + + /* If this configuration macro is defined, we rely on the `PSNames' */ + /* module to grab the glyph names. */ + +#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES + + +#include FT_SERVICE_POSTSCRIPT_CMAPS_H + +#define MAC_NAME( x ) ( (FT_String*)psnames->macintosh_name( x ) ) + + +#else /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */ + + + /* Otherwise, we ignore the `PSNames' module, and provide our own */ + /* table of Mac names. Thus, it is possible to build a version of */ + /* FreeType without the Type 1 driver & PSNames module. */ + +#define MAC_NAME( x ) ( (FT_String*)tt_post_default_names[x] ) + + /* the 258 default Mac PS glyph names */ + + static const FT_String* const tt_post_default_names[258] = + { + /* 0 */ + ".notdef", ".null", "CR", "space", "exclam", + "quotedbl", "numbersign", "dollar", "percent", "ampersand", + /* 10 */ + "quotesingle", "parenleft", "parenright", "asterisk", "plus", + "comma", "hyphen", "period", "slash", "zero", + /* 20 */ + "one", "two", "three", "four", "five", + "six", "seven", "eight", "nine", "colon", + /* 30 */ + "semicolon", "less", "equal", "greater", "question", + "at", "A", "B", "C", "D", + /* 40 */ + "E", "F", "G", "H", "I", + "J", "K", "L", "M", "N", + /* 50 */ + "O", "P", "Q", "R", "S", + "T", "U", "V", "W", "X", + /* 60 */ + "Y", "Z", "bracketleft", "backslash", "bracketright", + "asciicircum", "underscore", "grave", "a", "b", + /* 70 */ + "c", "d", "e", "f", "g", + "h", "i", "j", "k", "l", + /* 80 */ + "m", "n", "o", "p", "q", + "r", "s", "t", "u", "v", + /* 90 */ + "w", "x", "y", "z", "braceleft", + "bar", "braceright", "asciitilde", "Adieresis", "Aring", + /* 100 */ + "Ccedilla", "Eacute", "Ntilde", "Odieresis", "Udieresis", + "aacute", "agrave", "acircumflex", "adieresis", "atilde", + /* 110 */ + "aring", "ccedilla", "eacute", "egrave", "ecircumflex", + "edieresis", "iacute", "igrave", "icircumflex", "idieresis", + /* 120 */ + "ntilde", "oacute", "ograve", "ocircumflex", "odieresis", + "otilde", "uacute", "ugrave", "ucircumflex", "udieresis", + /* 130 */ + "dagger", "degree", "cent", "sterling", "section", + "bullet", "paragraph", "germandbls", "registered", "copyright", + /* 140 */ + "trademark", "acute", "dieresis", "notequal", "AE", + "Oslash", "infinity", "plusminus", "lessequal", "greaterequal", + /* 150 */ + "yen", "mu", "partialdiff", "summation", "product", + "pi", "integral", "ordfeminine", "ordmasculine", "Omega", + /* 160 */ + "ae", "oslash", "questiondown", "exclamdown", "logicalnot", + "radical", "florin", "approxequal", "Delta", "guillemotleft", + /* 170 */ + "guillemotright", "ellipsis", "nbspace", "Agrave", "Atilde", + "Otilde", "OE", "oe", "endash", "emdash", + /* 180 */ + "quotedblleft", "quotedblright", "quoteleft", "quoteright", "divide", + "lozenge", "ydieresis", "Ydieresis", "fraction", "currency", + /* 190 */ + "guilsinglleft", "guilsinglright", "fi", "fl", "daggerdbl", + "periodcentered", "quotesinglbase", "quotedblbase", "perthousand", "Acircumflex", + /* 200 */ + "Ecircumflex", "Aacute", "Edieresis", "Egrave", "Iacute", + "Icircumflex", "Idieresis", "Igrave", "Oacute", "Ocircumflex", + /* 210 */ + "apple", "Ograve", "Uacute", "Ucircumflex", "Ugrave", + "dotlessi", "circumflex", "tilde", "macron", "breve", + /* 220 */ + "dotaccent", "ring", "cedilla", "hungarumlaut", "ogonek", + "caron", "Lslash", "lslash", "Scaron", "scaron", + /* 230 */ + "Zcaron", "zcaron", "brokenbar", "Eth", "eth", + "Yacute", "yacute", "Thorn", "thorn", "minus", + /* 240 */ + "multiply", "onesuperior", "twosuperior", "threesuperior", "onehalf", + "onequarter", "threequarters", "franc", "Gbreve", "gbreve", + /* 250 */ + "Idot", "Scedilla", "scedilla", "Cacute", "cacute", + "Ccaron", "ccaron", "dmacron", + }; + + +#endif /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */ + + + static FT_Error + load_format_20( TT_Face face, + FT_Stream stream ) + { + FT_Memory memory = stream->memory; + FT_Error error; + + FT_Int num_glyphs; + FT_UShort num_names; + + FT_UShort* glyph_indices = 0; + FT_Char** name_strings = 0; + + + if ( FT_READ_USHORT( num_glyphs ) ) + goto Exit; + + /* UNDOCUMENTED! The number of glyphs in this table can be smaller */ + /* than the value in the maxp table (cf. cyberbit.ttf). */ + + /* There already exist fonts which have more than 32768 glyph names */ + /* in this table, so the test for this threshold has been dropped. */ + + if ( num_glyphs > face->max_profile.numGlyphs ) + { + error = SFNT_Err_Invalid_File_Format; + goto Exit; + } + + /* load the indices */ + { + FT_Int n; + + + if ( FT_NEW_ARRAY ( glyph_indices, num_glyphs ) || + FT_FRAME_ENTER( num_glyphs * 2L ) ) + goto Fail; + + for ( n = 0; n < num_glyphs; n++ ) + glyph_indices[n] = FT_GET_USHORT(); + + FT_FRAME_EXIT(); + } + + /* compute number of names stored in table */ + { + FT_Int n; + + + num_names = 0; + + for ( n = 0; n < num_glyphs; n++ ) + { + FT_Int idx; + + + idx = glyph_indices[n]; + if ( idx >= 258 ) + { + idx -= 257; + if ( idx > num_names ) + num_names = (FT_UShort)idx; + } + } + } + + /* now load the name strings */ + { + FT_UShort n; + + + if ( FT_NEW_ARRAY( name_strings, num_names ) ) + goto Fail; + + for ( n = 0; n < num_names; n++ ) + { + FT_UInt len; + + + if ( FT_READ_BYTE ( len ) || + FT_NEW_ARRAY( name_strings[n], len + 1 ) || + FT_STREAM_READ ( name_strings[n], len ) ) + goto Fail1; + + name_strings[n][len] = '\0'; + } + } + + /* all right, set table fields and exit successfully */ + { + TT_Post_20 table = &face->postscript_names.names.format_20; + + + table->num_glyphs = (FT_UShort)num_glyphs; + table->num_names = (FT_UShort)num_names; + table->glyph_indices = glyph_indices; + table->glyph_names = name_strings; + } + return SFNT_Err_Ok; + + Fail1: + { + FT_UShort n; + + + for ( n = 0; n < num_names; n++ ) + FT_FREE( name_strings[n] ); + } + + Fail: + FT_FREE( name_strings ); + FT_FREE( glyph_indices ); + + Exit: + return error; + } + + + static FT_Error + load_format_25( TT_Face face, + FT_Stream stream ) + { + FT_Memory memory = stream->memory; + FT_Error error; + + FT_Int num_glyphs; + FT_Char* offset_table = 0; + + + /* UNDOCUMENTED! This value appears only in the Apple TT specs. */ + if ( FT_READ_USHORT( num_glyphs ) ) + goto Exit; + + /* check the number of glyphs */ + if ( num_glyphs > face->max_profile.numGlyphs || num_glyphs > 258 ) + { + error = SFNT_Err_Invalid_File_Format; + goto Exit; + } + + if ( FT_NEW_ARRAY( offset_table, num_glyphs ) || + FT_STREAM_READ( offset_table, num_glyphs ) ) + goto Fail; + + /* now check the offset table */ + { + FT_Int n; + + + for ( n = 0; n < num_glyphs; n++ ) + { + FT_Long idx = (FT_Long)n + offset_table[n]; + + + if ( idx < 0 || idx > num_glyphs ) + { + error = SFNT_Err_Invalid_File_Format; + goto Fail; + } + } + } + + /* OK, set table fields and exit successfully */ + { + TT_Post_25 table = &face->postscript_names.names.format_25; + + + table->num_glyphs = (FT_UShort)num_glyphs; + table->offsets = offset_table; + } + + return SFNT_Err_Ok; + + Fail: + FT_FREE( offset_table ); + + Exit: + return error; + } + + + static FT_Error + load_post_names( TT_Face face ) + { + FT_Stream stream; + FT_Error error; + FT_Fixed format; + + + /* get a stream for the face's resource */ + stream = face->root.stream; + + /* seek to the beginning of the PS names table */ + error = face->goto_table( face, TTAG_post, stream, 0 ); + if ( error ) + goto Exit; + + format = face->postscript.FormatType; + + /* go to beginning of subtable */ + if ( FT_STREAM_SKIP( 32 ) ) + goto Exit; + + /* now read postscript table */ + if ( format == 0x00020000L ) + error = load_format_20( face, stream ); + else if ( format == 0x00028000L ) + error = load_format_25( face, stream ); + else + error = SFNT_Err_Invalid_File_Format; + + face->postscript_names.loaded = 1; + + Exit: + return error; + } + + + FT_LOCAL_DEF( void ) + tt_face_free_ps_names( TT_Face face ) + { + FT_Memory memory = face->root.memory; + TT_Post_Names names = &face->postscript_names; + FT_Fixed format; + + + if ( names->loaded ) + { + format = face->postscript.FormatType; + + if ( format == 0x00020000L ) + { + TT_Post_20 table = &names->names.format_20; + FT_UShort n; + + + FT_FREE( table->glyph_indices ); + table->num_glyphs = 0; + + for ( n = 0; n < table->num_names; n++ ) + FT_FREE( table->glyph_names[n] ); + + FT_FREE( table->glyph_names ); + table->num_names = 0; + } + else if ( format == 0x00028000L ) + { + TT_Post_25 table = &names->names.format_25; + + + FT_FREE( table->offsets ); + table->num_glyphs = 0; + } + } + names->loaded = 0; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_get_ps_name */ + /* */ + /* <Description> */ + /* Get the PostScript glyph name of a glyph. */ + /* */ + /* <Input> */ + /* face :: A handle to the parent face. */ + /* */ + /* idx :: The glyph index. */ + /* */ + /* <InOut> */ + /* PSname :: The address of a string pointer. Will be NULL in case */ + /* of error, otherwise it is a pointer to the glyph name. */ + /* */ + /* You must not modify the returned string! */ + /* */ + /* <Output> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_get_ps_name( TT_Face face, + FT_UInt idx, + FT_String** PSname ) + { + FT_Error error; + TT_Post_Names names; + FT_Fixed format; + +#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES + FT_Service_PsCMaps psnames; +#endif + + + if ( !face ) + return SFNT_Err_Invalid_Face_Handle; + + if ( idx >= (FT_UInt)face->max_profile.numGlyphs ) + return SFNT_Err_Invalid_Glyph_Index; + +#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES + psnames = (FT_Service_PsCMaps)face->psnames; + if ( !psnames ) + return SFNT_Err_Unimplemented_Feature; +#endif + + names = &face->postscript_names; + + /* `.notdef' by default */ + *PSname = MAC_NAME( 0 ); + + format = face->postscript.FormatType; + + if ( format == 0x00010000L ) + { + if ( idx < 258 ) /* paranoid checking */ + *PSname = MAC_NAME( idx ); + } + else if ( format == 0x00020000L ) + { + TT_Post_20 table = &names->names.format_20; + + + if ( !names->loaded ) + { + error = load_post_names( face ); + if ( error ) + goto End; + } + + if ( idx < (FT_UInt)table->num_glyphs ) + { + FT_UShort name_index = table->glyph_indices[idx]; + + + if ( name_index < 258 ) + *PSname = MAC_NAME( name_index ); + else + *PSname = (FT_String*)table->glyph_names[name_index - 258]; + } + } + else if ( format == 0x00028000L ) + { + TT_Post_25 table = &names->names.format_25; + + + if ( !names->loaded ) + { + error = load_post_names( face ); + if ( error ) + goto End; + } + + if ( idx < (FT_UInt)table->num_glyphs ) /* paranoid checking */ + { + idx += table->offsets[idx]; + *PSname = MAC_NAME( idx ); + } + } + + /* nothing to do for format == 0x00030000L */ + + End: + return SFNT_Err_Ok; + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/sfnt/ttpost.h b/mod/pub.mod/freetype.mod/src/sfnt/ttpost.h new file mode 100644 index 0000000..6f06d75 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/sfnt/ttpost.h @@ -0,0 +1,46 @@ +/***************************************************************************/ +/* */ +/* ttpost.h */ +/* */ +/* Postcript name table processing for TrueType and OpenType fonts */ +/* (specification). */ +/* */ +/* Copyright 1996-2001, 2002 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __TTPOST_H__ +#define __TTPOST_H__ + + +#include <ft2build.h> +#include FT_CONFIG_CONFIG_H +#include FT_INTERNAL_TRUETYPE_TYPES_H + + +FT_BEGIN_HEADER + + + FT_LOCAL( FT_Error ) + tt_face_get_ps_name( TT_Face face, + FT_UInt idx, + FT_String** PSname ); + + FT_LOCAL( void ) + tt_face_free_ps_names( TT_Face face ); + + +FT_END_HEADER + +#endif /* __TTPOST_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/sfnt/ttsbit.c b/mod/pub.mod/freetype.mod/src/sfnt/ttsbit.c new file mode 100644 index 0000000..833bb2a --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/sfnt/ttsbit.c @@ -0,0 +1,1507 @@ +/***************************************************************************/ +/* */ +/* ttsbit.c */ +/* */ +/* TrueType and OpenType embedded bitmap support (body). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_TRUETYPE_TAGS_H + + /* + * Alas, the memory-optimized sbit loader can't be used when implementing + * the `old internals' hack + */ +#ifndef FT_CONFIG_OPTION_OLD_INTERNALS + +#include "ttsbit0.c" + +#else /* FT_CONFIG_OPTION_OLD_INTERNALS */ + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_TRUETYPE_TAGS_H +#include "ttsbit.h" + +#include "sferrors.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_ttsbit + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* blit_sbit */ + /* */ + /* <Description> */ + /* Blits a bitmap from an input stream into a given target. Supports */ + /* x and y offsets as well as byte padded lines. */ + /* */ + /* <Input> */ + /* target :: The target bitmap/pixmap. */ + /* */ + /* source :: The input packed bitmap data. */ + /* */ + /* line_bits :: The number of bits per line. */ + /* */ + /* byte_padded :: A flag which is true if lines are byte-padded. */ + /* */ + /* x_offset :: The horizontal offset. */ + /* */ + /* y_offset :: The vertical offset. */ + /* */ + /* <Note> */ + /* IMPORTANT: The x and y offsets are relative to the top corner of */ + /* the target bitmap (unlike the normal TrueType */ + /* convention). A positive y offset indicates a downwards */ + /* direction! */ + /* */ + static void + blit_sbit( FT_Bitmap* target, + FT_Byte* source, + FT_Int line_bits, + FT_Bool byte_padded, + FT_Int x_offset, + FT_Int y_offset, + FT_Int source_height ) + { + FT_Byte* line_buff; + FT_Int line_incr; + FT_Int height; + + FT_UShort acc; + FT_UInt loaded; + + + /* first of all, compute starting write position */ + line_incr = target->pitch; + line_buff = target->buffer; + + if ( line_incr < 0 ) + line_buff -= line_incr * ( target->rows - 1 ); + + line_buff += ( x_offset >> 3 ) + y_offset * line_incr; + + /***********************************************************************/ + /* */ + /* We use the extra-classic `accumulator' trick to extract the bits */ + /* from the source byte stream. */ + /* */ + /* Namely, the variable `acc' is a 16-bit accumulator containing the */ + /* last `loaded' bits from the input stream. The bits are shifted to */ + /* the upmost position in `acc'. */ + /* */ + /***********************************************************************/ + + acc = 0; /* clear accumulator */ + loaded = 0; /* no bits were loaded */ + + for ( height = source_height; height > 0; height-- ) + { + FT_Byte* cur = line_buff; /* current write cursor */ + FT_Int count = line_bits; /* # of bits to extract per line */ + FT_Byte shift = (FT_Byte)( x_offset & 7 ); /* current write shift */ + FT_Byte space = (FT_Byte)( 8 - shift ); + + + /* first of all, read individual source bytes */ + if ( count >= 8 ) + { + count -= 8; + { + do + { + FT_Byte val; + + + /* ensure that there are at least 8 bits in the accumulator */ + if ( loaded < 8 ) + { + acc |= (FT_UShort)((FT_UShort)*source++ << ( 8 - loaded )); + loaded += 8; + } + + /* now write one byte */ + val = (FT_Byte)( acc >> 8 ); + if ( shift ) + { + cur[0] |= (FT_Byte)( val >> shift ); + cur[1] |= (FT_Byte)( val << space ); + } + else + cur[0] |= val; + + cur++; + acc <<= 8; /* remove bits from accumulator */ + loaded -= 8; + count -= 8; + + } while ( count >= 0 ); + } + + /* restore `count' to correct value */ + count += 8; + } + + /* now write remaining bits (count < 8) */ + if ( count > 0 ) + { + FT_Byte val; + + + /* ensure that there are at least `count' bits in the accumulator */ + if ( (FT_Int)loaded < count ) + { + acc |= (FT_UShort)((FT_UShort)*source++ << ( 8 - loaded )); + loaded += 8; + } + + /* now write remaining bits */ + val = (FT_Byte)( ( (FT_Byte)( acc >> 8 ) ) & ~( 0xFF >> count ) ); + cur[0] |= (FT_Byte)( val >> shift ); + + if ( count > space ) + cur[1] |= (FT_Byte)( val << space ); + + acc <<= count; + loaded -= count; + } + + /* now, skip to next line */ + if ( byte_padded ) + { + acc = 0; + loaded = 0; /* clear accumulator on byte-padded lines */ + } + + line_buff += line_incr; + } + } + + + static const FT_Frame_Field sbit_metrics_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE TT_SBit_MetricsRec + + FT_FRAME_START( 8 ), + FT_FRAME_BYTE( height ), + FT_FRAME_BYTE( width ), + + FT_FRAME_CHAR( horiBearingX ), + FT_FRAME_CHAR( horiBearingY ), + FT_FRAME_BYTE( horiAdvance ), + + FT_FRAME_CHAR( vertBearingX ), + FT_FRAME_CHAR( vertBearingY ), + FT_FRAME_BYTE( vertAdvance ), + FT_FRAME_END + }; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Load_SBit_Const_Metrics */ + /* */ + /* <Description> */ + /* Loads the metrics for `EBLC' index tables format 2 and 5. */ + /* */ + /* <Input> */ + /* range :: The target range. */ + /* */ + /* stream :: The input stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + static FT_Error + Load_SBit_Const_Metrics( TT_SBit_Range range, + FT_Stream stream ) + { + FT_Error error; + + + if ( FT_READ_ULONG( range->image_size ) ) + return error; + + return FT_STREAM_READ_FIELDS( sbit_metrics_fields, &range->metrics ); + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Load_SBit_Range_Codes */ + /* */ + /* <Description> */ + /* Loads the range codes for `EBLC' index tables format 4 and 5. */ + /* */ + /* <Input> */ + /* range :: The target range. */ + /* */ + /* stream :: The input stream. */ + /* */ + /* load_offsets :: A flag whether to load the glyph offset table. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + static FT_Error + Load_SBit_Range_Codes( TT_SBit_Range range, + FT_Stream stream, + FT_Bool load_offsets ) + { + FT_Error error; + FT_ULong count, n, size; + FT_Memory memory = stream->memory; + + + if ( FT_READ_ULONG( count ) ) + goto Exit; + + range->num_glyphs = count; + + /* Allocate glyph offsets table if needed */ + if ( load_offsets ) + { + if ( FT_NEW_ARRAY( range->glyph_offsets, count ) ) + goto Exit; + + size = count * 4L; + } + else + size = count * 2L; + + /* Allocate glyph codes table and access frame */ + if ( FT_NEW_ARRAY ( range->glyph_codes, count ) || + FT_FRAME_ENTER( size ) ) + goto Exit; + + for ( n = 0; n < count; n++ ) + { + range->glyph_codes[n] = FT_GET_USHORT(); + + if ( load_offsets ) + range->glyph_offsets[n] = (FT_ULong)range->image_offset + + FT_GET_USHORT(); + } + + FT_FRAME_EXIT(); + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Load_SBit_Range */ + /* */ + /* <Description> */ + /* Loads a given `EBLC' index/range table. */ + /* */ + /* <Input> */ + /* range :: The target range. */ + /* */ + /* stream :: The input stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + static FT_Error + Load_SBit_Range( TT_SBit_Range range, + FT_Stream stream ) + { + FT_Error error; + FT_Memory memory = stream->memory; + + + switch( range->index_format ) + { + case 1: /* variable metrics with 4-byte offsets */ + case 3: /* variable metrics with 2-byte offsets */ + { + FT_ULong num_glyphs, n; + FT_Int size_elem; + FT_Bool large = FT_BOOL( range->index_format == 1 ); + + + + if ( range->last_glyph < range->first_glyph ) + { + error = SFNT_Err_Invalid_File_Format; + goto Exit; + } + + num_glyphs = range->last_glyph - range->first_glyph + 1L; + range->num_glyphs = num_glyphs; + num_glyphs++; /* XXX: BEWARE - see spec */ + + size_elem = large ? 4 : 2; + + if ( FT_NEW_ARRAY( range->glyph_offsets, num_glyphs ) || + FT_FRAME_ENTER( num_glyphs * size_elem ) ) + goto Exit; + + for ( n = 0; n < num_glyphs; n++ ) + range->glyph_offsets[n] = (FT_ULong)( range->image_offset + + ( large ? FT_GET_ULONG() + : FT_GET_USHORT() ) ); + FT_FRAME_EXIT(); + } + break; + + case 2: /* all glyphs have identical metrics */ + error = Load_SBit_Const_Metrics( range, stream ); + break; + + case 4: + error = Load_SBit_Range_Codes( range, stream, 1 ); + break; + + case 5: + error = Load_SBit_Const_Metrics( range, stream ); + if ( !error ) + error = Load_SBit_Range_Codes( range, stream, 0 ); + break; + + default: + error = SFNT_Err_Invalid_File_Format; + } + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_load_eblc */ + /* */ + /* <Description> */ + /* Loads the table of embedded bitmap sizes for this face. */ + /* */ + /* <Input> */ + /* face :: The target face object. */ + /* */ + /* stream :: The input stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_load_eblc( TT_Face face, + FT_Stream stream ) + { + FT_Error error = 0; + FT_Memory memory = stream->memory; + FT_Fixed version; + FT_ULong num_strikes; + FT_ULong table_base; + + static const FT_Frame_Field sbit_line_metrics_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE TT_SBit_LineMetricsRec + + /* no FT_FRAME_START */ + FT_FRAME_CHAR( ascender ), + FT_FRAME_CHAR( descender ), + FT_FRAME_BYTE( max_width ), + + FT_FRAME_CHAR( caret_slope_numerator ), + FT_FRAME_CHAR( caret_slope_denominator ), + FT_FRAME_CHAR( caret_offset ), + + FT_FRAME_CHAR( min_origin_SB ), + FT_FRAME_CHAR( min_advance_SB ), + FT_FRAME_CHAR( max_before_BL ), + FT_FRAME_CHAR( min_after_BL ), + FT_FRAME_CHAR( pads[0] ), + FT_FRAME_CHAR( pads[1] ), + FT_FRAME_END + }; + + static const FT_Frame_Field strike_start_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE TT_SBit_StrikeRec + + /* no FT_FRAME_START */ + FT_FRAME_ULONG( ranges_offset ), + FT_FRAME_SKIP_LONG, + FT_FRAME_ULONG( num_ranges ), + FT_FRAME_ULONG( color_ref ), + FT_FRAME_END + }; + + static const FT_Frame_Field strike_end_fields[] = + { + /* no FT_FRAME_START */ + FT_FRAME_USHORT( start_glyph ), + FT_FRAME_USHORT( end_glyph ), + FT_FRAME_BYTE ( x_ppem ), + FT_FRAME_BYTE ( y_ppem ), + FT_FRAME_BYTE ( bit_depth ), + FT_FRAME_CHAR ( flags ), + FT_FRAME_END + }; + + + face->num_sbit_strikes = 0; + + /* this table is optional */ + error = face->goto_table( face, TTAG_EBLC, stream, 0 ); + if ( error ) + error = face->goto_table( face, TTAG_bloc, stream, 0 ); + if ( error ) + goto Exit; + + table_base = FT_STREAM_POS(); + if ( FT_FRAME_ENTER( 8L ) ) + goto Exit; + + version = FT_GET_LONG(); + num_strikes = FT_GET_ULONG(); + + FT_FRAME_EXIT(); + + /* check version number and strike count */ + if ( version != 0x00020000L || + num_strikes >= 0x10000L ) + { + FT_ERROR(( "tt_face_load_sbit_strikes: invalid table version\n" )); + error = SFNT_Err_Invalid_File_Format; + + goto Exit; + } + + /* allocate the strikes table */ + if ( FT_NEW_ARRAY( face->sbit_strikes, num_strikes ) ) + goto Exit; + + face->num_sbit_strikes = num_strikes; + + /* now read each strike table separately */ + { + TT_SBit_Strike strike = face->sbit_strikes; + FT_ULong count = num_strikes; + + + if ( FT_FRAME_ENTER( 48L * num_strikes ) ) + goto Exit; + + while ( count > 0 ) + { + if ( FT_STREAM_READ_FIELDS( strike_start_fields, strike ) || + FT_STREAM_READ_FIELDS( sbit_line_metrics_fields, &strike->hori ) || + FT_STREAM_READ_FIELDS( sbit_line_metrics_fields, &strike->vert ) || + FT_STREAM_READ_FIELDS( strike_end_fields, strike ) ) + break; + + count--; + strike++; + } + + FT_FRAME_EXIT(); + } + + /* allocate the index ranges for each strike table */ + { + TT_SBit_Strike strike = face->sbit_strikes; + FT_ULong count = num_strikes; + + + while ( count > 0 ) + { + TT_SBit_Range range; + FT_ULong count2 = strike->num_ranges; + + + /* read each range */ + if ( FT_STREAM_SEEK( table_base + strike->ranges_offset ) || + FT_FRAME_ENTER( strike->num_ranges * 8L ) ) + goto Exit; + + if ( FT_NEW_ARRAY( strike->sbit_ranges, strike->num_ranges ) ) + goto Exit; + + range = strike->sbit_ranges; + while ( count2 > 0 ) + { + range->first_glyph = FT_GET_USHORT(); + range->last_glyph = FT_GET_USHORT(); + range->table_offset = table_base + strike->ranges_offset + + FT_GET_ULONG(); + count2--; + range++; + } + + FT_FRAME_EXIT(); + + /* Now, read each index table */ + count2 = strike->num_ranges; + range = strike->sbit_ranges; + while ( count2 > 0 ) + { + /* Read the header */ + if ( FT_STREAM_SEEK( range->table_offset ) || + FT_FRAME_ENTER( 8L ) ) + goto Exit; + + range->index_format = FT_GET_USHORT(); + range->image_format = FT_GET_USHORT(); + range->image_offset = FT_GET_ULONG(); + + FT_FRAME_EXIT(); + + error = Load_SBit_Range( range, stream ); + if ( error ) + goto Exit; + + count2--; + range++; + } + + count--; + strike++; + } + } + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_free_eblc */ + /* */ + /* <Description> */ + /* Releases the embedded bitmap tables. */ + /* */ + /* <Input> */ + /* face :: The target face object. */ + /* */ + FT_LOCAL_DEF( void ) + tt_face_free_eblc( TT_Face face ) + { + FT_Memory memory = face->root.memory; + TT_SBit_Strike strike = face->sbit_strikes; + TT_SBit_Strike strike_limit = strike + face->num_sbit_strikes; + + + if ( strike ) + { + for ( ; strike < strike_limit; strike++ ) + { + TT_SBit_Range range = strike->sbit_ranges; + TT_SBit_Range range_limit = range + strike->num_ranges; + + + if ( range ) + { + for ( ; range < range_limit; range++ ) + { + /* release the glyph offsets and codes tables */ + /* where appropriate */ + FT_FREE( range->glyph_offsets ); + FT_FREE( range->glyph_codes ); + } + } + FT_FREE( strike->sbit_ranges ); + strike->num_ranges = 0; + } + FT_FREE( face->sbit_strikes ); + } + face->num_sbit_strikes = 0; + } + + + FT_LOCAL_DEF( FT_Error ) + tt_face_set_sbit_strike( TT_Face face, + FT_Size_Request req, + FT_ULong* astrike_index ) + { + return FT_Match_Size( (FT_Face)face, req, 0, astrike_index ); + } + + + FT_LOCAL_DEF( FT_Error ) + tt_face_load_strike_metrics( TT_Face face, + FT_ULong strike_index, + FT_Size_Metrics* metrics ) + { + TT_SBit_Strike strike; + + + if ( strike_index >= face->num_sbit_strikes ) + return SFNT_Err_Invalid_Argument; + + strike = face->sbit_strikes + strike_index; + + metrics->x_ppem = strike->x_ppem; + metrics->y_ppem = strike->y_ppem; + + metrics->ascender = strike->hori.ascender << 6; + metrics->descender = strike->hori.descender << 6; + + /* XXX: Is this correct? */ + metrics->max_advance = ( strike->hori.min_origin_SB + + strike->hori.max_width + + strike->hori.min_advance_SB ) << 6; + + metrics->height = metrics->ascender - metrics->descender; + + return SFNT_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* find_sbit_range */ + /* */ + /* <Description> */ + /* Scans a given strike's ranges and return, for a given glyph */ + /* index, the corresponding sbit range, and `EBDT' offset. */ + /* */ + /* <Input> */ + /* glyph_index :: The glyph index. */ + /* */ + /* strike :: The source/current sbit strike. */ + /* */ + /* <Output> */ + /* arange :: The sbit range containing the glyph index. */ + /* */ + /* aglyph_offset :: The offset of the glyph data in `EBDT' table. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means the glyph index was found. */ + /* */ + static FT_Error + find_sbit_range( FT_UInt glyph_index, + TT_SBit_Strike strike, + TT_SBit_Range *arange, + FT_ULong *aglyph_offset ) + { + TT_SBit_RangeRec *range, *range_limit; + + + /* check whether the glyph index is within this strike's */ + /* glyph range */ + if ( glyph_index < (FT_UInt)strike->start_glyph || + glyph_index > (FT_UInt)strike->end_glyph ) + goto Fail; + + /* scan all ranges in strike */ + range = strike->sbit_ranges; + range_limit = range + strike->num_ranges; + if ( !range ) + goto Fail; + + for ( ; range < range_limit; range++ ) + { + if ( glyph_index >= (FT_UInt)range->first_glyph && + glyph_index <= (FT_UInt)range->last_glyph ) + { + FT_UShort delta = (FT_UShort)( glyph_index - range->first_glyph ); + + + switch ( range->index_format ) + { + case 1: + case 3: + *aglyph_offset = range->glyph_offsets[delta]; + break; + + case 2: + *aglyph_offset = range->image_offset + + range->image_size * delta; + break; + + case 4: + case 5: + { + FT_ULong n; + + + for ( n = 0; n < range->num_glyphs; n++ ) + { + if ( (FT_UInt)range->glyph_codes[n] == glyph_index ) + { + if ( range->index_format == 4 ) + *aglyph_offset = range->glyph_offsets[n]; + else + *aglyph_offset = range->image_offset + + n * range->image_size; + goto Found; + } + } + } + + /* fall-through */ + default: + goto Fail; + } + + Found: + /* return successfully! */ + *arange = range; + return SFNT_Err_Ok; + } + } + + Fail: + *arange = 0; + *aglyph_offset = 0; + + return SFNT_Err_Invalid_Argument; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_find_sbit_image */ + /* */ + /* <Description> */ + /* Checks whether an embedded bitmap (an `sbit') exists for a given */ + /* glyph, at a given strike. */ + /* */ + /* <Input> */ + /* face :: The target face object. */ + /* */ + /* glyph_index :: The glyph index. */ + /* */ + /* strike_index :: The current strike index. */ + /* */ + /* <Output> */ + /* arange :: The SBit range containing the glyph index. */ + /* */ + /* astrike :: The SBit strike containing the glyph index. */ + /* */ + /* aglyph_offset :: The offset of the glyph data in `EBDT' table. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. Returns */ + /* SFNT_Err_Invalid_Argument if no sbit exists for the requested */ + /* glyph. */ + /* */ + FT_LOCAL( FT_Error ) + tt_find_sbit_image( TT_Face face, + FT_UInt glyph_index, + FT_ULong strike_index, + TT_SBit_Range *arange, + TT_SBit_Strike *astrike, + FT_ULong *aglyph_offset ) + { + FT_Error error; + TT_SBit_Strike strike; + + + if ( !face->sbit_strikes || + ( face->num_sbit_strikes <= strike_index ) ) + goto Fail; + + strike = &face->sbit_strikes[strike_index]; + + error = find_sbit_range( glyph_index, strike, + arange, aglyph_offset ); + if ( error ) + goto Fail; + + *astrike = strike; + + return SFNT_Err_Ok; + + Fail: + /* no embedded bitmap for this glyph in face */ + *arange = 0; + *astrike = 0; + *aglyph_offset = 0; + + return SFNT_Err_Invalid_Argument; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_load_sbit_metrics */ + /* */ + /* <Description> */ + /* Gets the big metrics for a given SBit. */ + /* */ + /* <Input> */ + /* stream :: The input stream. */ + /* */ + /* range :: The SBit range containing the glyph. */ + /* */ + /* <Output> */ + /* big_metrics :: A big SBit metrics structure for the glyph. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* The stream cursor must be positioned at the glyph's offset within */ + /* the `EBDT' table before the call. */ + /* */ + /* If the image format uses variable metrics, the stream cursor is */ + /* positioned just after the metrics header in the `EBDT' table on */ + /* function exit. */ + /* */ + FT_LOCAL( FT_Error ) + tt_load_sbit_metrics( FT_Stream stream, + TT_SBit_Range range, + TT_SBit_Metrics metrics ) + { + FT_Error error = SFNT_Err_Ok; + + + switch ( range->image_format ) + { + case 1: + case 2: + case 8: + /* variable small metrics */ + { + TT_SBit_SmallMetricsRec smetrics; + + static const FT_Frame_Field sbit_small_metrics_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE TT_SBit_SmallMetricsRec + + FT_FRAME_START( 5 ), + FT_FRAME_BYTE( height ), + FT_FRAME_BYTE( width ), + FT_FRAME_CHAR( bearingX ), + FT_FRAME_CHAR( bearingY ), + FT_FRAME_BYTE( advance ), + FT_FRAME_END + }; + + + /* read small metrics */ + if ( FT_STREAM_READ_FIELDS( sbit_small_metrics_fields, &smetrics ) ) + goto Exit; + + /* convert it to a big metrics */ + metrics->height = smetrics.height; + metrics->width = smetrics.width; + metrics->horiBearingX = smetrics.bearingX; + metrics->horiBearingY = smetrics.bearingY; + metrics->horiAdvance = smetrics.advance; + + /* these metrics are made up at a higher level when */ + /* needed. */ + metrics->vertBearingX = 0; + metrics->vertBearingY = 0; + metrics->vertAdvance = 0; + } + break; + + case 6: + case 7: + case 9: + /* variable big metrics */ + if ( FT_STREAM_READ_FIELDS( sbit_metrics_fields, metrics ) ) + goto Exit; + break; + + case 5: + default: /* constant metrics */ + if ( range->index_format == 2 || range->index_format == 5 ) + *metrics = range->metrics; + else + return SFNT_Err_Invalid_File_Format; + } + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* crop_bitmap */ + /* */ + /* <Description> */ + /* Crops a bitmap to its tightest bounding box, and adjusts its */ + /* metrics. */ + /* */ + /* <InOut> */ + /* map :: The bitmap. */ + /* */ + /* metrics :: The corresponding metrics structure. */ + /* */ + static void + crop_bitmap( FT_Bitmap* map, + TT_SBit_Metrics metrics ) + { + /***********************************************************************/ + /* */ + /* In this situation, some bounding boxes of embedded bitmaps are too */ + /* large. We need to crop it to a reasonable size. */ + /* */ + /* --------- */ + /* | | ----- */ + /* | *** | |***| */ + /* | * | | * | */ + /* | * | ------> | * | */ + /* | * | | * | */ + /* | * | | * | */ + /* | *** | |***| */ + /* --------- ----- */ + /* */ + /***********************************************************************/ + + FT_Int rows, count; + FT_Long line_len; + FT_Byte* line; + + + /***********************************************************************/ + /* */ + /* first of all, check the top-most lines of the bitmap, and remove */ + /* them if they're empty. */ + /* */ + { + line = (FT_Byte*)map->buffer; + rows = map->rows; + line_len = map->pitch; + + + for ( count = 0; count < rows; count++ ) + { + FT_Byte* cur = line; + FT_Byte* limit = line + line_len; + + + for ( ; cur < limit; cur++ ) + if ( cur[0] ) + goto Found_Top; + + /* the current line was empty - skip to next one */ + line = limit; + } + + Found_Top: + /* check that we have at least one filled line */ + if ( count >= rows ) + goto Empty_Bitmap; + + /* now, crop the empty upper lines */ + if ( count > 0 ) + { + line = (FT_Byte*)map->buffer; + + FT_MEM_MOVE( line, line + count * line_len, + ( rows - count ) * line_len ); + + metrics->height = (FT_Byte)( metrics->height - count ); + metrics->horiBearingY = (FT_Char)( metrics->horiBearingY - count ); + metrics->vertBearingY = (FT_Char)( metrics->vertBearingY - count ); + + map->rows -= count; + rows -= count; + } + } + + /***********************************************************************/ + /* */ + /* second, crop the lower lines */ + /* */ + { + line = (FT_Byte*)map->buffer + ( rows - 1 ) * line_len; + + for ( count = 0; count < rows; count++ ) + { + FT_Byte* cur = line; + FT_Byte* limit = line + line_len; + + + for ( ; cur < limit; cur++ ) + if ( cur[0] ) + goto Found_Bottom; + + /* the current line was empty - skip to previous one */ + line -= line_len; + } + + Found_Bottom: + if ( count > 0 ) + { + metrics->height = (FT_Byte)( metrics->height - count ); + rows -= count; + map->rows -= count; + } + } + + /***********************************************************************/ + /* */ + /* third, get rid of the space on the left side of the glyph */ + /* */ + do + { + FT_Byte* limit; + + + line = (FT_Byte*)map->buffer; + limit = line + rows * line_len; + + for ( ; line < limit; line += line_len ) + if ( line[0] & 0x80 ) + goto Found_Left; + + /* shift the whole glyph one pixel to the left */ + line = (FT_Byte*)map->buffer; + limit = line + rows * line_len; + + for ( ; line < limit; line += line_len ) + { + FT_Int n, width = map->width; + FT_Byte old; + FT_Byte* cur = line; + + + old = (FT_Byte)(cur[0] << 1); + for ( n = 8; n < width; n += 8 ) + { + FT_Byte val; + + + val = cur[1]; + cur[0] = (FT_Byte)( old | ( val >> 7 ) ); + old = (FT_Byte)( val << 1 ); + cur++; + } + cur[0] = old; + } + + map->width--; + metrics->horiBearingX++; + metrics->vertBearingX++; + metrics->width--; + + } while ( map->width > 0 ); + + Found_Left: + + /***********************************************************************/ + /* */ + /* finally, crop the bitmap width to get rid of the space on the right */ + /* side of the glyph. */ + /* */ + do + { + FT_Int right = map->width - 1; + FT_Byte* limit; + FT_Byte mask; + + + line = (FT_Byte*)map->buffer + ( right >> 3 ); + limit = line + rows * line_len; + mask = (FT_Byte)( 0x80 >> ( right & 7 ) ); + + for ( ; line < limit; line += line_len ) + if ( line[0] & mask ) + goto Found_Right; + + /* crop the whole glyph to the right */ + map->width--; + metrics->width--; + + } while ( map->width > 0 ); + + Found_Right: + /* all right, the bitmap was cropped */ + return; + + Empty_Bitmap: + map->width = 0; + map->rows = 0; + map->pitch = 0; + map->pixel_mode = FT_PIXEL_MODE_MONO; + } + + + static FT_Error + Load_SBit_Single( FT_Bitmap* map, + FT_Int x_offset, + FT_Int y_offset, + FT_Int pix_bits, + FT_UShort image_format, + TT_SBit_Metrics metrics, + FT_Stream stream ) + { + FT_Error error; + + + /* check that the source bitmap fits into the target pixmap */ + if ( x_offset < 0 || x_offset + metrics->width > map->width || + y_offset < 0 || y_offset + metrics->height > map->rows ) + { + error = SFNT_Err_Invalid_Argument; + + goto Exit; + } + + { + FT_Int glyph_width = metrics->width; + FT_Int glyph_height = metrics->height; + FT_Int glyph_size; + FT_Int line_bits = pix_bits * glyph_width; + FT_Bool pad_bytes = 0; + + + /* compute size of glyph image */ + switch ( image_format ) + { + case 1: /* byte-padded formats */ + case 6: + { + FT_Int line_length; + + + switch ( pix_bits ) + { + case 1: + line_length = ( glyph_width + 7 ) >> 3; + break; + case 2: + line_length = ( glyph_width + 3 ) >> 2; + break; + case 4: + line_length = ( glyph_width + 1 ) >> 1; + break; + default: + line_length = glyph_width; + } + + glyph_size = glyph_height * line_length; + pad_bytes = 1; + } + break; + + case 2: + case 5: + case 7: + line_bits = glyph_width * pix_bits; + glyph_size = ( glyph_height * line_bits + 7 ) >> 3; + break; + + default: /* invalid format */ + return SFNT_Err_Invalid_File_Format; + } + + /* Now read data and draw glyph into target pixmap */ + if ( FT_FRAME_ENTER( glyph_size ) ) + goto Exit; + + /* don't forget to multiply `x_offset' by `map->pix_bits' as */ + /* the sbit blitter doesn't make a difference between pixmap */ + /* depths. */ + blit_sbit( map, (FT_Byte*)stream->cursor, line_bits, pad_bytes, + x_offset * pix_bits, y_offset, metrics->height ); + + FT_FRAME_EXIT(); + } + + Exit: + return error; + } + + + static FT_Error + Load_SBit_Image( TT_SBit_Strike strike, + TT_SBit_Range range, + FT_ULong ebdt_pos, + FT_ULong glyph_offset, + FT_GlyphSlot slot, + FT_Int x_offset, + FT_Int y_offset, + FT_Stream stream, + TT_SBit_Metrics metrics, + FT_Int depth ) + { + FT_Memory memory = stream->memory; + FT_Bitmap* map = &slot->bitmap; + FT_Error error; + + + /* place stream at beginning of glyph data and read metrics */ + if ( FT_STREAM_SEEK( ebdt_pos + glyph_offset ) ) + goto Exit; + + error = tt_load_sbit_metrics( stream, range, metrics ); + if ( error ) + goto Exit; + + /* This function is recursive. At the top-level call, we */ + /* compute the dimensions of the higher-level glyph to */ + /* allocate the final pixmap buffer. */ + if ( depth == 0 ) + { + FT_Long size; + + + map->width = metrics->width; + map->rows = metrics->height; + + switch ( strike->bit_depth ) + { + case 1: + map->pixel_mode = FT_PIXEL_MODE_MONO; + map->pitch = ( map->width + 7 ) >> 3; + break; + + case 2: + map->pixel_mode = FT_PIXEL_MODE_GRAY2; + map->pitch = ( map->width + 3 ) >> 2; + break; + + case 4: + map->pixel_mode = FT_PIXEL_MODE_GRAY4; + map->pitch = ( map->width + 1 ) >> 1; + break; + + case 8: + map->pixel_mode = FT_PIXEL_MODE_GRAY; + map->pitch = map->width; + break; + + default: + return SFNT_Err_Invalid_File_Format; + } + + size = map->rows * map->pitch; + + /* check that there is no empty image */ + if ( size == 0 ) + goto Exit; /* exit successfully! */ + + error = ft_glyphslot_alloc_bitmap( slot, size ); + if (error) + goto Exit; + } + + switch ( range->image_format ) + { + case 1: /* single sbit image - load it */ + case 2: + case 5: + case 6: + case 7: + return Load_SBit_Single( map, x_offset, y_offset, strike->bit_depth, + range->image_format, metrics, stream ); + + case 8: /* compound format */ + if ( FT_STREAM_SKIP( 1L ) ) + { + error = SFNT_Err_Invalid_Stream_Skip; + goto Exit; + } + /* fallthrough */ + + case 9: + break; + + default: /* invalid image format */ + return SFNT_Err_Invalid_File_Format; + } + + /* All right, we have a compound format. First of all, read */ + /* the array of elements. */ + { + TT_SBit_Component components; + TT_SBit_Component comp; + FT_UShort num_components, count; + + + if ( FT_READ_USHORT( num_components ) || + FT_NEW_ARRAY( components, num_components ) ) + goto Exit; + + count = num_components; + + if ( FT_FRAME_ENTER( 4L * num_components ) ) + goto Fail_Memory; + + for ( comp = components; count > 0; count--, comp++ ) + { + comp->glyph_code = FT_GET_USHORT(); + comp->x_offset = FT_GET_CHAR(); + comp->y_offset = FT_GET_CHAR(); + } + + FT_FRAME_EXIT(); + + /* Now recursively load each element glyph */ + count = num_components; + comp = components; + for ( ; count > 0; count--, comp++ ) + { + TT_SBit_Range elem_range; + TT_SBit_MetricsRec elem_metrics; + FT_ULong elem_offset; + + + /* find the range for this element */ + error = find_sbit_range( comp->glyph_code, + strike, + &elem_range, + &elem_offset ); + if ( error ) + goto Fail_Memory; + + /* now load the element, recursively */ + error = Load_SBit_Image( strike, + elem_range, + ebdt_pos, + elem_offset, + slot, + x_offset + comp->x_offset, + y_offset + comp->y_offset, + stream, + &elem_metrics, + depth + 1 ); + if ( error ) + goto Fail_Memory; + } + + Fail_Memory: + FT_FREE( components ); + } + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_load_sbit_image */ + /* */ + /* <Description> */ + /* Loads a given glyph sbit image from the font resource. This also */ + /* returns its metrics. */ + /* */ + /* <Input> */ + /* face :: The target face object. */ + /* */ + /* strike_index :: The current strike index. */ + /* */ + /* glyph_index :: The current glyph index. */ + /* */ + /* load_flags :: The glyph load flags (the code checks for the flag */ + /* FT_LOAD_CROP_BITMAP). */ + /* */ + /* stream :: The input stream. */ + /* */ + /* <Output> */ + /* map :: The target pixmap. */ + /* */ + /* metrics :: A big sbit metrics structure for the glyph image. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. Returns an error if no */ + /* glyph sbit exists for the index. */ + /* */ + /* <Note> */ + /* The `map.buffer' field is always freed before the glyph is loaded. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_load_sbit_image( TT_Face face, + FT_ULong strike_index, + FT_UInt glyph_index, + FT_UInt load_flags, + FT_Stream stream, + FT_Bitmap *map, + TT_SBit_MetricsRec *metrics ) + { + FT_Error error; + FT_ULong ebdt_pos, glyph_offset; + + TT_SBit_Strike strike; + TT_SBit_Range range; + + + /* Check whether there is a glyph sbit for the current index */ + error = tt_find_sbit_image( face, glyph_index, strike_index, + &range, &strike, &glyph_offset ); + if ( error ) + goto Exit; + + /* now, find the location of the `EBDT' table in */ + /* the font file */ + error = face->goto_table( face, TTAG_EBDT, stream, 0 ); + if ( error ) + error = face->goto_table( face, TTAG_bdat, stream, 0 ); + if ( error ) + goto Exit; + + ebdt_pos = FT_STREAM_POS(); + + error = Load_SBit_Image( strike, range, ebdt_pos, glyph_offset, + face->root.glyph, 0, 0, stream, metrics, 0 ); + if ( error ) + goto Exit; + + /* setup vertical metrics if needed */ + if ( strike->flags & 1 ) + { + /* in case of a horizontal strike only */ + FT_Int advance; + + + advance = strike->hori.ascender - strike->hori.descender; + + /* some heuristic values */ + + metrics->vertBearingX = (FT_Char)(-metrics->width / 2 ); + metrics->vertBearingY = (FT_Char)( ( advance - metrics->height ) / 2 ); + metrics->vertAdvance = (FT_Char)( advance * 12 / 10 ); + } + + /* Crop the bitmap now, unless specified otherwise */ + if ( load_flags & FT_LOAD_CROP_BITMAP ) + crop_bitmap( map, metrics ); + + Exit: + return error; + } + +#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/sfnt/ttsbit.h b/mod/pub.mod/freetype.mod/src/sfnt/ttsbit.h new file mode 100644 index 0000000..7ea2af1 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/sfnt/ttsbit.h @@ -0,0 +1,79 @@ +/***************************************************************************/ +/* */ +/* ttsbit.h */ +/* */ +/* TrueType and OpenType embedded bitmap support (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __TTSBIT_H__ +#define __TTSBIT_H__ + + +#include <ft2build.h> +#include "ttload.h" + + +FT_BEGIN_HEADER + + + FT_LOCAL( FT_Error ) + tt_face_load_eblc( TT_Face face, + FT_Stream stream ); + + FT_LOCAL( void ) + tt_face_free_eblc( TT_Face face ); + + + FT_LOCAL( FT_Error ) + tt_face_set_sbit_strike( TT_Face face, + FT_Size_Request req, + FT_ULong* astrike_index ); + + FT_LOCAL( FT_Error ) + tt_face_load_strike_metrics( TT_Face face, + FT_ULong strike_index, + FT_Size_Metrics* metrics ); + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + FT_LOCAL( FT_Error ) + tt_find_sbit_image( TT_Face face, + FT_UInt glyph_index, + FT_ULong strike_index, + TT_SBit_Range *arange, + TT_SBit_Strike *astrike, + FT_ULong *aglyph_offset ); + + FT_LOCAL( FT_Error ) + tt_load_sbit_metrics( FT_Stream stream, + TT_SBit_Range range, + TT_SBit_Metrics metrics ); + +#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */ + + FT_LOCAL( FT_Error ) + tt_face_load_sbit_image( TT_Face face, + FT_ULong strike_index, + FT_UInt glyph_index, + FT_UInt load_flags, + FT_Stream stream, + FT_Bitmap *map, + TT_SBit_MetricsRec *metrics ); + + +FT_END_HEADER + +#endif /* __TTSBIT_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/sfnt/ttsbit0.c b/mod/pub.mod/freetype.mod/src/sfnt/ttsbit0.c new file mode 100644 index 0000000..38bcf21 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/sfnt/ttsbit0.c @@ -0,0 +1,1011 @@ +/***************************************************************************/ +/* */ +/* ttsbit0.c */ +/* */ +/* TrueType and OpenType embedded bitmap support (body). */ +/* This is a heap-optimized version. */ +/* */ +/* Copyright 2005, 2006, 2007, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +/* This file is included by ttsbit.c */ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_TRUETYPE_TAGS_H +#include "ttsbit.h" + +#include "sferrors.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_ttsbit + + + FT_LOCAL_DEF( FT_Error ) + tt_face_load_eblc( TT_Face face, + FT_Stream stream ) + { + FT_Error error = SFNT_Err_Ok; + FT_Fixed version; + FT_ULong num_strikes, table_size; + FT_Byte* p; + FT_Byte* p_limit; + FT_UInt count; + + + face->sbit_num_strikes = 0; + + /* this table is optional */ + error = face->goto_table( face, TTAG_EBLC, stream, &table_size ); + if ( error ) + error = face->goto_table( face, TTAG_bloc, stream, &table_size ); + if ( error ) + goto Exit; + + if ( table_size < 8 ) + { + FT_ERROR(( "tt_face_load_sbit_strikes: table too short\n" )); + error = SFNT_Err_Invalid_File_Format; + goto Exit; + } + + if ( FT_FRAME_EXTRACT( table_size, face->sbit_table ) ) + goto Exit; + + face->sbit_table_size = table_size; + + p = face->sbit_table; + p_limit = p + table_size; + + version = FT_NEXT_ULONG( p ); + num_strikes = FT_NEXT_ULONG( p ); + + if ( version != 0x00020000UL || num_strikes >= 0x10000UL ) + { + FT_ERROR(( "tt_face_load_sbit_strikes: invalid table version\n" )); + error = SFNT_Err_Invalid_File_Format; + goto Fail; + } + + /* + * Count the number of strikes available in the table. We are a bit + * paranoid there and don't trust the data. + */ + count = (FT_UInt)num_strikes; + if ( 8 + 48UL * count > table_size ) + count = (FT_UInt)( ( p_limit - p ) / 48 ); + + face->sbit_num_strikes = count; + + FT_TRACE3(( "sbit_num_strikes: %u\n", count )); + Exit: + return error; + + Fail: + FT_FRAME_RELEASE( face->sbit_table ); + face->sbit_table_size = 0; + goto Exit; + } + + + FT_LOCAL_DEF( void ) + tt_face_free_eblc( TT_Face face ) + { + FT_Stream stream = face->root.stream; + + + FT_FRAME_RELEASE( face->sbit_table ); + face->sbit_table_size = 0; + face->sbit_num_strikes = 0; + } + + + FT_LOCAL_DEF( FT_Error ) + tt_face_set_sbit_strike( TT_Face face, + FT_Size_Request req, + FT_ULong* astrike_index ) + { + return FT_Match_Size( (FT_Face)face, req, 0, astrike_index ); + } + + + FT_LOCAL_DEF( FT_Error ) + tt_face_load_strike_metrics( TT_Face face, + FT_ULong strike_index, + FT_Size_Metrics* metrics ) + { + FT_Byte* strike; + + + if ( strike_index >= (FT_ULong)face->sbit_num_strikes ) + return SFNT_Err_Invalid_Argument; + + strike = face->sbit_table + 8 + strike_index * 48; + + metrics->x_ppem = (FT_UShort)strike[44]; + metrics->y_ppem = (FT_UShort)strike[45]; + + metrics->ascender = (FT_Char)strike[16] << 6; /* hori.ascender */ + metrics->descender = (FT_Char)strike[17] << 6; /* hori.descender */ + metrics->height = metrics->ascender - metrics->descender; + + /* XXX: Is this correct? */ + metrics->max_advance = ( (FT_Char)strike[22] + /* min_origin_SB */ + strike[18] + /* max_width */ + (FT_Char)strike[23] /* min_advance_SB */ + ) << 6; + + return SFNT_Err_Ok; + } + + + typedef struct TT_SBitDecoderRec_ + { + TT_Face face; + FT_Stream stream; + FT_Bitmap* bitmap; + TT_SBit_Metrics metrics; + FT_Bool metrics_loaded; + FT_Bool bitmap_allocated; + FT_Byte bit_depth; + + FT_ULong ebdt_start; + FT_ULong ebdt_size; + + FT_ULong strike_index_array; + FT_ULong strike_index_count; + FT_Byte* eblc_base; + FT_Byte* eblc_limit; + + } TT_SBitDecoderRec, *TT_SBitDecoder; + + + static FT_Error + tt_sbit_decoder_init( TT_SBitDecoder decoder, + TT_Face face, + FT_ULong strike_index, + TT_SBit_MetricsRec* metrics ) + { + FT_Error error; + FT_Stream stream = face->root.stream; + FT_ULong ebdt_size; + + + error = face->goto_table( face, TTAG_EBDT, stream, &ebdt_size ); + if ( error ) + error = face->goto_table( face, TTAG_bdat, stream, &ebdt_size ); + if ( error ) + goto Exit; + + decoder->face = face; + decoder->stream = stream; + decoder->bitmap = &face->root.glyph->bitmap; + decoder->metrics = metrics; + + decoder->metrics_loaded = 0; + decoder->bitmap_allocated = 0; + + decoder->ebdt_start = FT_STREAM_POS(); + decoder->ebdt_size = ebdt_size; + + decoder->eblc_base = face->sbit_table; + decoder->eblc_limit = face->sbit_table + face->sbit_table_size; + + /* now find the strike corresponding to the index */ + { + FT_Byte* p; + + + if ( 8 + 48 * strike_index + 3 * 4 + 34 + 1 > face->sbit_table_size ) + { + error = SFNT_Err_Invalid_File_Format; + goto Exit; + } + + p = decoder->eblc_base + 8 + 48 * strike_index; + + decoder->strike_index_array = FT_NEXT_ULONG( p ); + p += 4; + decoder->strike_index_count = FT_NEXT_ULONG( p ); + p += 34; + decoder->bit_depth = *p; + + if ( decoder->strike_index_array > face->sbit_table_size || + decoder->strike_index_array + 8 * decoder->strike_index_count > + face->sbit_table_size ) + error = SFNT_Err_Invalid_File_Format; + } + + Exit: + return error; + } + + + static void + tt_sbit_decoder_done( TT_SBitDecoder decoder ) + { + FT_UNUSED( decoder ); + } + + + static FT_Error + tt_sbit_decoder_alloc_bitmap( TT_SBitDecoder decoder ) + { + FT_Error error = SFNT_Err_Ok; + FT_UInt width, height; + FT_Bitmap* map = decoder->bitmap; + FT_Long size; + + + if ( !decoder->metrics_loaded ) + { + error = SFNT_Err_Invalid_Argument; + goto Exit; + } + + width = decoder->metrics->width; + height = decoder->metrics->height; + + map->width = (int)width; + map->rows = (int)height; + + switch ( decoder->bit_depth ) + { + case 1: + map->pixel_mode = FT_PIXEL_MODE_MONO; + map->pitch = ( map->width + 7 ) >> 3; + break; + + case 2: + map->pixel_mode = FT_PIXEL_MODE_GRAY2; + map->pitch = ( map->width + 3 ) >> 2; + break; + + case 4: + map->pixel_mode = FT_PIXEL_MODE_GRAY4; + map->pitch = ( map->width + 1 ) >> 1; + break; + + case 8: + map->pixel_mode = FT_PIXEL_MODE_GRAY; + map->pitch = map->width; + break; + + default: + error = SFNT_Err_Invalid_File_Format; + goto Exit; + } + + size = map->rows * map->pitch; + + /* check that there is no empty image */ + if ( size == 0 ) + goto Exit; /* exit successfully! */ + + error = ft_glyphslot_alloc_bitmap( decoder->face->root.glyph, size ); + if ( error ) + goto Exit; + + decoder->bitmap_allocated = 1; + + Exit: + return error; + } + + + static FT_Error + tt_sbit_decoder_load_metrics( TT_SBitDecoder decoder, + FT_Byte* *pp, + FT_Byte* limit, + FT_Bool big ) + { + FT_Byte* p = *pp; + TT_SBit_Metrics metrics = decoder->metrics; + + + if ( p + 5 > limit ) + goto Fail; + + metrics->height = p[0]; + metrics->width = p[1]; + metrics->horiBearingX = (FT_Char)p[2]; + metrics->horiBearingY = (FT_Char)p[3]; + metrics->horiAdvance = p[4]; + + p += 5; + if ( big ) + { + if ( p + 3 > limit ) + goto Fail; + + metrics->vertBearingX = (FT_Char)p[0]; + metrics->vertBearingY = (FT_Char)p[1]; + metrics->vertAdvance = p[2]; + + p += 3; + } + + decoder->metrics_loaded = 1; + *pp = p; + return SFNT_Err_Ok; + + Fail: + return SFNT_Err_Invalid_Argument; + } + + + /* forward declaration */ + static FT_Error + tt_sbit_decoder_load_image( TT_SBitDecoder decoder, + FT_UInt glyph_index, + FT_Int x_pos, + FT_Int y_pos ); + + typedef FT_Error (*TT_SBitDecoder_LoadFunc)( TT_SBitDecoder decoder, + FT_Byte* p, + FT_Byte* plimit, + FT_Int x_pos, + FT_Int y_pos ); + + + static FT_Error + tt_sbit_decoder_load_byte_aligned( TT_SBitDecoder decoder, + FT_Byte* p, + FT_Byte* limit, + FT_Int x_pos, + FT_Int y_pos ) + { + FT_Error error = SFNT_Err_Ok; + FT_Byte* line; + FT_Int bit_height, bit_width, pitch, width, height, h; + FT_Bitmap* bitmap; + + + if ( !decoder->bitmap_allocated ) + { + error = tt_sbit_decoder_alloc_bitmap( decoder ); + if ( error ) + goto Exit; + } + + /* check that we can write the glyph into the bitmap */ + bitmap = decoder->bitmap; + bit_width = bitmap->width; + bit_height = bitmap->rows; + pitch = bitmap->pitch; + line = bitmap->buffer; + + width = decoder->metrics->width; + height = decoder->metrics->height; + + if ( x_pos < 0 || x_pos + width > bit_width || + y_pos < 0 || y_pos + height > bit_height ) + { + error = SFNT_Err_Invalid_File_Format; + goto Exit; + } + + if ( p + ( ( width + 7 ) >> 3 ) * height > limit ) + { + error = SFNT_Err_Invalid_File_Format; + goto Exit; + } + + /* now do the blit */ + line += y_pos * pitch + ( x_pos >> 3 ); + x_pos &= 7; + + if ( x_pos == 0 ) /* the easy one */ + { + for ( h = height; h > 0; h--, line += pitch ) + { + FT_Byte* write = line; + FT_Int w; + + + for ( w = width; w >= 8; w -= 8 ) + { + write[0] = (FT_Byte)( write[0] | *p++ ); + write += 1; + } + + if ( w > 0 ) + write[0] = (FT_Byte)( write[0] | ( *p++ & ( 0xFF00U >> w ) ) ); + } + } + else /* x_pos > 0 */ + { + for ( h = height; h > 0; h--, line += pitch ) + { + FT_Byte* write = line; + FT_Int w; + FT_UInt wval = 0; + + + for ( w = width; w >= 8; w -= 8 ) + { + wval = (FT_UInt)( wval | *p++ ); + write[0] = (FT_Byte)( write[0] | ( wval >> x_pos ) ); + write += 1; + wval <<= 8; + } + + if ( w > 0 ) + wval = (FT_UInt)( wval | ( *p++ & ( 0xFF00U >> w ) ) ); + + /* all bits read and there are `x_pos + w' bits to be written */ + + write[0] = (FT_Byte)( write[0] | ( wval >> x_pos ) ); + + if ( x_pos + w > 8 ) + { + write++; + wval <<= 8; + write[0] = (FT_Byte)( write[0] | ( wval >> x_pos ) ); + } + } + } + + Exit: + return error; + } + + + /* + * Load a bit-aligned bitmap (with pointer `p') into a line-aligned bitmap + * (with pointer `write'). In the example below, the width is 3 pixel, + * and `x_pos' is 1 pixel. + * + * p p+1 + * | | | + * | 7 6 5 4 3 2 1 0 | 7 6 5 4 3 2 1 0 |... + * | | | + * +-------+ +-------+ +-------+ ... + * . . . + * . . . + * v . . + * +-------+ . . + * | | . + * | 7 6 5 4 3 2 1 0 | . + * | | . + * write . . + * . . + * v . + * +-------+ . + * | | + * | 7 6 5 4 3 2 1 0 | + * | | + * write+1 . + * . + * v + * +-------+ + * | | + * | 7 6 5 4 3 2 1 0 | + * | | + * write+2 + * + */ + + static FT_Error + tt_sbit_decoder_load_bit_aligned( TT_SBitDecoder decoder, + FT_Byte* p, + FT_Byte* limit, + FT_Int x_pos, + FT_Int y_pos ) + { + FT_Error error = SFNT_Err_Ok; + FT_Byte* line; + FT_Int bit_height, bit_width, pitch, width, height, h, nbits; + FT_Bitmap* bitmap; + FT_UShort rval; + + + if ( !decoder->bitmap_allocated ) + { + error = tt_sbit_decoder_alloc_bitmap( decoder ); + if ( error ) + goto Exit; + } + + /* check that we can write the glyph into the bitmap */ + bitmap = decoder->bitmap; + bit_width = bitmap->width; + bit_height = bitmap->rows; + pitch = bitmap->pitch; + line = bitmap->buffer; + + width = decoder->metrics->width; + height = decoder->metrics->height; + + if ( x_pos < 0 || x_pos + width > bit_width || + y_pos < 0 || y_pos + height > bit_height ) + { + error = SFNT_Err_Invalid_File_Format; + goto Exit; + } + + if ( p + ( ( width * height + 7 ) >> 3 ) > limit ) + { + error = SFNT_Err_Invalid_File_Format; + goto Exit; + } + + /* now do the blit */ + + /* adjust `line' to point to the first byte of the bitmap */ + line += y_pos * pitch + ( x_pos >> 3 ); + x_pos &= 7; + + /* the higher byte of `rval' is used as a buffer */ + rval = 0; + nbits = 0; + + for ( h = height; h > 0; h--, line += pitch ) + { + FT_Byte* write = line; + FT_Int w = width; + + + /* handle initial byte (in target bitmap) specially if necessary */ + if ( x_pos ) + { + w = ( width < 8 - x_pos ) ? width : 8 - x_pos; + + if ( h == height ) + { + rval = *p++; + nbits = x_pos; + } + else if ( nbits < w ) + { + if ( p < limit ) + rval |= *p++; + nbits += 8 - w; + } + else + { + rval >>= 8; + nbits -= w; + } + + *write++ |= ( ( rval >> nbits ) & 0xFF ) & + ( ~( 0xFF << w ) << ( 8 - w - x_pos ) ); + rval <<= 8; + + w = width - w; + } + + /* handle medial bytes */ + for ( ; w >= 8; w -= 8 ) + { + rval |= *p++; + *write++ |= ( rval >> nbits ) & 0xFF; + + rval <<= 8; + } + + /* handle final byte if necessary */ + if ( w > 0 ) + { + if ( nbits < w ) + { + if ( p < limit ) + rval |= *p++; + *write |= ( ( rval >> nbits ) & 0xFF ) & ( 0xFF00U >> w ); + nbits += 8 - w; + + rval <<= 8; + } + else + { + *write |= ( ( rval >> nbits ) & 0xFF ) & ( 0xFF00U >> w ); + nbits -= w; + } + } + } + + Exit: + return error; + } + + + static FT_Error + tt_sbit_decoder_load_compound( TT_SBitDecoder decoder, + FT_Byte* p, + FT_Byte* limit, + FT_Int x_pos, + FT_Int y_pos ) + { + FT_Error error = SFNT_Err_Ok; + FT_UInt num_components, nn; + + FT_Char horiBearingX = decoder->metrics->horiBearingX; + FT_Char horiBearingY = decoder->metrics->horiBearingY; + FT_Byte horiAdvance = decoder->metrics->horiAdvance; + FT_Char vertBearingX = decoder->metrics->vertBearingX; + FT_Char vertBearingY = decoder->metrics->vertBearingY; + FT_Byte vertAdvance = decoder->metrics->vertAdvance; + + + if ( p + 2 > limit ) + goto Fail; + + num_components = FT_NEXT_USHORT( p ); + if ( p + 4 * num_components > limit ) + goto Fail; + + if ( !decoder->bitmap_allocated ) + { + error = tt_sbit_decoder_alloc_bitmap( decoder ); + if ( error ) + goto Exit; + } + + for ( nn = 0; nn < num_components; nn++ ) + { + FT_UInt gindex = FT_NEXT_USHORT( p ); + FT_Byte dx = FT_NEXT_BYTE( p ); + FT_Byte dy = FT_NEXT_BYTE( p ); + + + /* NB: a recursive call */ + error = tt_sbit_decoder_load_image( decoder, gindex, + x_pos + dx, y_pos + dy ); + if ( error ) + break; + } + + decoder->metrics->horiBearingX = horiBearingX; + decoder->metrics->horiBearingY = horiBearingY; + decoder->metrics->horiAdvance = horiAdvance; + decoder->metrics->vertBearingX = vertBearingX; + decoder->metrics->vertBearingY = vertBearingY; + decoder->metrics->vertAdvance = vertAdvance; + decoder->metrics->width = (FT_UInt)decoder->bitmap->width; + decoder->metrics->height = (FT_UInt)decoder->bitmap->rows; + + Exit: + return error; + + Fail: + error = SFNT_Err_Invalid_File_Format; + goto Exit; + } + + + static FT_Error + tt_sbit_decoder_load_bitmap( TT_SBitDecoder decoder, + FT_UInt glyph_format, + FT_ULong glyph_start, + FT_ULong glyph_size, + FT_Int x_pos, + FT_Int y_pos ) + { + FT_Error error; + FT_Stream stream = decoder->stream; + FT_Byte* p; + FT_Byte* p_limit; + FT_Byte* data; + + + /* seek into the EBDT table now */ + if ( glyph_start + glyph_size > decoder->ebdt_size ) + { + error = SFNT_Err_Invalid_Argument; + goto Exit; + } + + if ( FT_STREAM_SEEK( decoder->ebdt_start + glyph_start ) || + FT_FRAME_EXTRACT( glyph_size, data ) ) + goto Exit; + + p = data; + p_limit = p + glyph_size; + + /* read the data, depending on the glyph format */ + switch ( glyph_format ) + { + case 1: + case 2: + case 8: + error = tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 0 ); + break; + + case 6: + case 7: + case 9: + error = tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ); + break; + + default: + error = SFNT_Err_Ok; + } + + if ( error ) + goto Fail; + + { + TT_SBitDecoder_LoadFunc loader; + + + switch ( glyph_format ) + { + case 1: + case 6: + loader = tt_sbit_decoder_load_byte_aligned; + break; + + case 2: + case 5: + case 7: + loader = tt_sbit_decoder_load_bit_aligned; + break; + + case 8: + if ( p + 1 > p_limit ) + goto Fail; + + p += 1; /* skip padding */ + /* fall-through */ + + case 9: + loader = tt_sbit_decoder_load_compound; + break; + + default: + goto Fail; + } + + error = loader( decoder, p, p_limit, x_pos, y_pos ); + } + + Fail: + FT_FRAME_RELEASE( data ); + + Exit: + return error; + } + + + static FT_Error + tt_sbit_decoder_load_image( TT_SBitDecoder decoder, + FT_UInt glyph_index, + FT_Int x_pos, + FT_Int y_pos ) + { + /* + * First, we find the correct strike range that applies to this + * glyph index. + */ + + FT_Byte* p = decoder->eblc_base + decoder->strike_index_array; + FT_Byte* p_limit = decoder->eblc_limit; + FT_ULong num_ranges = decoder->strike_index_count; + FT_UInt start, end, index_format, image_format; + FT_ULong image_start = 0, image_end = 0, image_offset; + + + for ( ; num_ranges > 0; num_ranges-- ) + { + start = FT_NEXT_USHORT( p ); + end = FT_NEXT_USHORT( p ); + + if ( glyph_index >= start && glyph_index <= end ) + goto FoundRange; + + p += 4; /* ignore index offset */ + } + goto NoBitmap; + + FoundRange: + image_offset = FT_NEXT_ULONG( p ); + + /* overflow check */ + if ( decoder->eblc_base + decoder->strike_index_array + image_offset < + decoder->eblc_base ) + goto Failure; + + p = decoder->eblc_base + decoder->strike_index_array + image_offset; + if ( p + 8 > p_limit ) + goto NoBitmap; + + /* now find the glyph's location and extend within the ebdt table */ + index_format = FT_NEXT_USHORT( p ); + image_format = FT_NEXT_USHORT( p ); + image_offset = FT_NEXT_ULONG ( p ); + + switch ( index_format ) + { + case 1: /* 4-byte offsets relative to `image_offset' */ + { + p += 4 * ( glyph_index - start ); + if ( p + 8 > p_limit ) + goto NoBitmap; + + image_start = FT_NEXT_ULONG( p ); + image_end = FT_NEXT_ULONG( p ); + + if ( image_start == image_end ) /* missing glyph */ + goto NoBitmap; + } + break; + + case 2: /* big metrics, constant image size */ + { + FT_ULong image_size; + + + if ( p + 12 > p_limit ) + goto NoBitmap; + + image_size = FT_NEXT_ULONG( p ); + + if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) ) + goto NoBitmap; + + image_start = image_size * ( glyph_index - start ); + image_end = image_start + image_size; + } + break; + + case 3: /* 2-byte offsets relative to 'image_offset' */ + { + p += 2 * ( glyph_index - start ); + if ( p + 4 > p_limit ) + goto NoBitmap; + + image_start = FT_NEXT_USHORT( p ); + image_end = FT_NEXT_USHORT( p ); + + if ( image_start == image_end ) /* missing glyph */ + goto NoBitmap; + } + break; + + case 4: /* sparse glyph array with (glyph,offset) pairs */ + { + FT_ULong mm, num_glyphs; + + + if ( p + 4 > p_limit ) + goto NoBitmap; + + num_glyphs = FT_NEXT_ULONG( p ); + + /* overflow check */ + if ( p + ( num_glyphs + 1 ) * 4 < p ) + goto Failure; + + if ( p + ( num_glyphs + 1 ) * 4 > p_limit ) + goto NoBitmap; + + for ( mm = 0; mm < num_glyphs; mm++ ) + { + FT_UInt gindex = FT_NEXT_USHORT( p ); + + + if ( gindex == glyph_index ) + { + image_start = FT_NEXT_USHORT( p ); + p += 2; + image_end = FT_PEEK_USHORT( p ); + break; + } + p += 2; + } + + if ( mm >= num_glyphs ) + goto NoBitmap; + } + break; + + case 5: /* constant metrics with sparse glyph codes */ + { + FT_ULong image_size, mm, num_glyphs; + + + if ( p + 16 > p_limit ) + goto NoBitmap; + + image_size = FT_NEXT_ULONG( p ); + + if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) ) + goto NoBitmap; + + num_glyphs = FT_NEXT_ULONG( p ); + + /* overflow check */ + if ( p + 2 * num_glyphs < p ) + goto Failure; + + if ( p + 2 * num_glyphs > p_limit ) + goto NoBitmap; + + for ( mm = 0; mm < num_glyphs; mm++ ) + { + FT_UInt gindex = FT_NEXT_USHORT( p ); + + + if ( gindex == glyph_index ) + break; + } + + if ( mm >= num_glyphs ) + goto NoBitmap; + + image_start = image_size * mm; + image_end = image_start + image_size; + } + break; + + default: + goto NoBitmap; + } + + if ( image_start > image_end ) + goto NoBitmap; + + image_end -= image_start; + image_start = image_offset + image_start; + + return tt_sbit_decoder_load_bitmap( decoder, + image_format, + image_start, + image_end, + x_pos, + y_pos ); + + Failure: + return SFNT_Err_Invalid_Table; + + NoBitmap: + return SFNT_Err_Invalid_Argument; + } + + + FT_LOCAL( FT_Error ) + tt_face_load_sbit_image( TT_Face face, + FT_ULong strike_index, + FT_UInt glyph_index, + FT_UInt load_flags, + FT_Stream stream, + FT_Bitmap *map, + TT_SBit_MetricsRec *metrics ) + { + TT_SBitDecoderRec decoder[1]; + FT_Error error; + + FT_UNUSED( load_flags ); + FT_UNUSED( stream ); + FT_UNUSED( map ); + + + error = tt_sbit_decoder_init( decoder, face, strike_index, metrics ); + if ( !error ) + { + error = tt_sbit_decoder_load_image( decoder, glyph_index, 0, 0 ); + tt_sbit_decoder_done( decoder ); + } + + return error; + } + +/* EOF */ diff --git a/mod/pub.mod/freetype.mod/src/smooth/ftgrays.c b/mod/pub.mod/freetype.mod/src/smooth/ftgrays.c new file mode 100644 index 0000000..846e454 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/smooth/ftgrays.c @@ -0,0 +1,2090 @@ +/***************************************************************************/ +/* */ +/* ftgrays.c */ +/* */ +/* A new `perfect' anti-aliasing renderer (body). */ +/* */ +/* Copyright 2000-2001, 2002, 2003, 2005, 2006, 2007, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + /*************************************************************************/ + /* */ + /* This file can be compiled without the rest of the FreeType engine, by */ + /* defining the _STANDALONE_ macro when compiling it. You also need to */ + /* put the files `ftgrays.h' and `ftimage.h' into the current */ + /* compilation directory. Typically, you could do something like */ + /* */ + /* - copy `src/smooth/ftgrays.c' (this file) to your current directory */ + /* */ + /* - copy `include/freetype/ftimage.h' and `src/smooth/ftgrays.h' to the */ + /* same directory */ + /* */ + /* - compile `ftgrays' with the _STANDALONE_ macro defined, as in */ + /* */ + /* cc -c -D_STANDALONE_ ftgrays.c */ + /* */ + /* The renderer can be initialized with a call to */ + /* `ft_gray_raster.raster_new'; an anti-aliased bitmap can be generated */ + /* with a call to `ft_gray_raster.raster_render'. */ + /* */ + /* See the comments and documentation in the file `ftimage.h' for more */ + /* details on how the raster works. */ + /* */ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* This is a new anti-aliasing scan-converter for FreeType 2. The */ + /* algorithm used here is _very_ different from the one in the standard */ + /* `ftraster' module. Actually, `ftgrays' computes the _exact_ */ + /* coverage of the outline on each pixel cell. */ + /* */ + /* It is based on ideas that I initially found in Raph Levien's */ + /* excellent LibArt graphics library (see http://www.levien.com/libart */ + /* for more information, though the web pages do not tell anything */ + /* about the renderer; you'll have to dive into the source code to */ + /* understand how it works). */ + /* */ + /* Note, however, that this is a _very_ different implementation */ + /* compared to Raph's. Coverage information is stored in a very */ + /* different way, and I don't use sorted vector paths. Also, it doesn't */ + /* use floating point values. */ + /* */ + /* This renderer has the following advantages: */ + /* */ + /* - It doesn't need an intermediate bitmap. Instead, one can supply a */ + /* callback function that will be called by the renderer to draw gray */ + /* spans on any target surface. You can thus do direct composition on */ + /* any kind of bitmap, provided that you give the renderer the right */ + /* callback. */ + /* */ + /* - A perfect anti-aliaser, i.e., it computes the _exact_ coverage on */ + /* each pixel cell. */ + /* */ + /* - It performs a single pass on the outline (the `standard' FT2 */ + /* renderer makes two passes). */ + /* */ + /* - It can easily be modified to render to _any_ number of gray levels */ + /* cheaply. */ + /* */ + /* - For small (< 20) pixel sizes, it is faster than the standard */ + /* renderer. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_smooth + + +#ifdef _STANDALONE_ + + + /* define this to dump debugging information */ +/* #define FT_DEBUG_LEVEL_TRACE */ + + +#ifdef FT_DEBUG_LEVEL_TRACE +#include <stdio.h> +#include <stdarg.h> +#endif + +#include <string.h> +#include <setjmp.h> +#include <limits.h> +#define FT_UINT_MAX UINT_MAX + +#define ft_memset memset + +#define ft_setjmp setjmp +#define ft_longjmp longjmp +#define ft_jmp_buf jmp_buf + + +#define ErrRaster_Invalid_Mode -2 +#define ErrRaster_Invalid_Outline -1 +#define ErrRaster_Invalid_Argument -3 +#define ErrRaster_Memory_Overflow -4 + +#define FT_BEGIN_HEADER +#define FT_END_HEADER + +#include "ftimage.h" +#include "ftgrays.h" + + + /* This macro is used to indicate that a function parameter is unused. */ + /* Its purpose is simply to reduce compiler warnings. Note also that */ + /* simply defining it as `(void)x' doesn't avoid warnings with certain */ + /* ANSI compilers (e.g. LCC). */ +#define FT_UNUSED( x ) (x) = (x) + + + /* we only use level 5 & 7 tracing messages; cf. ftdebug.h */ + +#ifdef FT_DEBUG_LEVEL_TRACE + + void + FT_Message( const char* fmt, + ... ) + { + va_list ap; + + + va_start( ap, fmt ); + vfprintf( stderr, fmt, ap ); + va_end( ap ); + } + + /* we don't handle tracing levels in stand-alone mode; */ +#ifndef FT_TRACE5 +#define FT_TRACE5( varformat ) FT_Message varformat +#endif +#ifndef FT_TRACE7 +#define FT_TRACE7( varformat ) FT_Message varformat +#endif +#ifndef FT_ERROR +#define FT_ERROR( varformat ) FT_Message varformat +#endif + +#else /* !FT_DEBUG_LEVEL_TRACE */ + +#define FT_TRACE5( x ) do { } while ( 0 ) /* nothing */ +#define FT_TRACE7( x ) do { } while ( 0 ) /* nothing */ +#define FT_ERROR( x ) do { } while ( 0 ) /* nothing */ + +#endif /* !FT_DEBUG_LEVEL_TRACE */ + + +#define FT_DEFINE_OUTLINE_FUNCS( class_, \ + move_to_, line_to_, \ + conic_to_, cubic_to_, \ + shift_, delta_ ) \ + static const FT_Outline_Funcs class_ = \ + { \ + move_to_, \ + line_to_, \ + conic_to_, \ + cubic_to_, \ + shift_, \ + delta_ \ + }; + +#define FT_DEFINE_RASTER_FUNCS( class_, glyph_format_, \ + raster_new_, raster_reset_, \ + raster_set_mode_, raster_render_, \ + raster_done_ ) \ + const FT_Raster_Funcs class_ = \ + { \ + glyph_format_, \ + raster_new_, \ + raster_reset_, \ + raster_set_mode_, \ + raster_render_, \ + raster_done_ \ + }; + +#else /* !_STANDALONE_ */ + + +#include <ft2build.h> +#include "ftgrays.h" +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_DEBUG_H +#include FT_OUTLINE_H + +#include "ftsmerrs.h" + +#include "ftspic.h" + +#define ErrRaster_Invalid_Mode Smooth_Err_Cannot_Render_Glyph +#define ErrRaster_Invalid_Outline Smooth_Err_Invalid_Outline +#define ErrRaster_Memory_Overflow Smooth_Err_Out_Of_Memory +#define ErrRaster_Invalid_Argument Smooth_Err_Invalid_Argument + +#endif /* !_STANDALONE_ */ + +#ifndef FT_MEM_SET +#define FT_MEM_SET( d, s, c ) ft_memset( d, s, c ) +#endif + +#ifndef FT_MEM_ZERO +#define FT_MEM_ZERO( dest, count ) FT_MEM_SET( dest, 0, count ) +#endif + + /* as usual, for the speed hungry :-) */ + +#ifndef FT_STATIC_RASTER + +#define RAS_ARG PWorker worker +#define RAS_ARG_ PWorker worker, + +#define RAS_VAR worker +#define RAS_VAR_ worker, + +#else /* FT_STATIC_RASTER */ + +#define RAS_ARG /* empty */ +#define RAS_ARG_ /* empty */ +#define RAS_VAR /* empty */ +#define RAS_VAR_ /* empty */ + +#endif /* FT_STATIC_RASTER */ + + + /* must be at least 6 bits! */ +#define PIXEL_BITS 8 + +#define ONE_PIXEL ( 1L << PIXEL_BITS ) +#define PIXEL_MASK ( -1L << PIXEL_BITS ) +#define TRUNC( x ) ( (TCoord)( (x) >> PIXEL_BITS ) ) +#define SUBPIXELS( x ) ( (TPos)(x) << PIXEL_BITS ) +#define FLOOR( x ) ( (x) & -ONE_PIXEL ) +#define CEILING( x ) ( ( (x) + ONE_PIXEL - 1 ) & -ONE_PIXEL ) +#define ROUND( x ) ( ( (x) + ONE_PIXEL / 2 ) & -ONE_PIXEL ) + +#if PIXEL_BITS >= 6 +#define UPSCALE( x ) ( (x) << ( PIXEL_BITS - 6 ) ) +#define DOWNSCALE( x ) ( (x) >> ( PIXEL_BITS - 6 ) ) +#else +#define UPSCALE( x ) ( (x) >> ( 6 - PIXEL_BITS ) ) +#define DOWNSCALE( x ) ( (x) << ( 6 - PIXEL_BITS ) ) +#endif + + + /*************************************************************************/ + /* */ + /* TYPE DEFINITIONS */ + /* */ + + /* don't change the following types to FT_Int or FT_Pos, since we might */ + /* need to define them to "float" or "double" when experimenting with */ + /* new algorithms */ + + typedef long TCoord; /* integer scanline/pixel coordinate */ + typedef long TPos; /* sub-pixel coordinate */ + + /* determine the type used to store cell areas. This normally takes at */ + /* least PIXEL_BITS*2 + 1 bits. On 16-bit systems, we need to use */ + /* `long' instead of `int', otherwise bad things happen */ + +#if PIXEL_BITS <= 7 + + typedef int TArea; + +#else /* PIXEL_BITS >= 8 */ + + /* approximately determine the size of integers using an ANSI-C header */ +#if FT_UINT_MAX == 0xFFFFU + typedef long TArea; +#else + typedef int TArea; +#endif + +#endif /* PIXEL_BITS >= 8 */ + + + /* maximal number of gray spans in a call to the span callback */ +#define FT_MAX_GRAY_SPANS 32 + + + typedef struct TCell_* PCell; + + typedef struct TCell_ + { + TPos x; /* same with TWorker.ex */ + TCoord cover; /* same with TWorker.cover */ + TArea area; + PCell next; + + } TCell; + + + typedef struct TWorker_ + { + TCoord ex, ey; + TPos min_ex, max_ex; + TPos min_ey, max_ey; + TPos count_ex, count_ey; + + TArea area; + TCoord cover; + int invalid; + + PCell cells; + FT_PtrDist max_cells; + FT_PtrDist num_cells; + + TCoord cx, cy; + TPos x, y; + + TPos last_ey; + + FT_Vector bez_stack[32 * 3 + 1]; + int lev_stack[32]; + + FT_Outline outline; + FT_Bitmap target; + FT_BBox clip_box; + + FT_Span gray_spans[FT_MAX_GRAY_SPANS]; + int num_gray_spans; + + FT_Raster_Span_Func render_span; + void* render_span_data; + int span_y; + + int band_size; + int band_shoot; + int conic_level; + int cubic_level; + + ft_jmp_buf jump_buffer; + + void* buffer; + long buffer_size; + + PCell* ycells; + TPos ycount; + + } TWorker, *PWorker; + + +#ifndef FT_STATIC_RASTER +#define ras (*worker) +#else + static TWorker ras; +#endif + + + typedef struct TRaster_ + { + void* buffer; + long buffer_size; + int band_size; + void* memory; + PWorker worker; + + } TRaster, *PRaster; + + + + /*************************************************************************/ + /* */ + /* Initialize the cells table. */ + /* */ + static void + gray_init_cells( RAS_ARG_ void* buffer, + long byte_size ) + { + ras.buffer = buffer; + ras.buffer_size = byte_size; + + ras.ycells = (PCell*) buffer; + ras.cells = NULL; + ras.max_cells = 0; + ras.num_cells = 0; + ras.area = 0; + ras.cover = 0; + ras.invalid = 1; + } + + + /*************************************************************************/ + /* */ + /* Compute the outline bounding box. */ + /* */ + static void + gray_compute_cbox( RAS_ARG ) + { + FT_Outline* outline = &ras.outline; + FT_Vector* vec = outline->points; + FT_Vector* limit = vec + outline->n_points; + + + if ( outline->n_points <= 0 ) + { + ras.min_ex = ras.max_ex = 0; + ras.min_ey = ras.max_ey = 0; + return; + } + + ras.min_ex = ras.max_ex = vec->x; + ras.min_ey = ras.max_ey = vec->y; + + vec++; + + for ( ; vec < limit; vec++ ) + { + TPos x = vec->x; + TPos y = vec->y; + + + if ( x < ras.min_ex ) ras.min_ex = x; + if ( x > ras.max_ex ) ras.max_ex = x; + if ( y < ras.min_ey ) ras.min_ey = y; + if ( y > ras.max_ey ) ras.max_ey = y; + } + + /* truncate the bounding box to integer pixels */ + ras.min_ex = ras.min_ex >> 6; + ras.min_ey = ras.min_ey >> 6; + ras.max_ex = ( ras.max_ex + 63 ) >> 6; + ras.max_ey = ( ras.max_ey + 63 ) >> 6; + } + + + /*************************************************************************/ + /* */ + /* Record the current cell in the table. */ + /* */ + static PCell + gray_find_cell( RAS_ARG ) + { + PCell *pcell, cell; + TPos x = ras.ex; + + + if ( x > ras.count_ex ) + x = ras.count_ex; + + pcell = &ras.ycells[ras.ey]; + for (;;) + { + cell = *pcell; + if ( cell == NULL || cell->x > x ) + break; + + if ( cell->x == x ) + goto Exit; + + pcell = &cell->next; + } + + if ( ras.num_cells >= ras.max_cells ) + ft_longjmp( ras.jump_buffer, 1 ); + + cell = ras.cells + ras.num_cells++; + cell->x = x; + cell->area = 0; + cell->cover = 0; + + cell->next = *pcell; + *pcell = cell; + + Exit: + return cell; + } + + + static void + gray_record_cell( RAS_ARG ) + { + if ( !ras.invalid && ( ras.area | ras.cover ) ) + { + PCell cell = gray_find_cell( RAS_VAR ); + + + cell->area += ras.area; + cell->cover += ras.cover; + } + } + + + /*************************************************************************/ + /* */ + /* Set the current cell to a new position. */ + /* */ + static void + gray_set_cell( RAS_ARG_ TCoord ex, + TCoord ey ) + { + /* Move the cell pointer to a new position. We set the `invalid' */ + /* flag to indicate that the cell isn't part of those we're interested */ + /* in during the render phase. This means that: */ + /* */ + /* . the new vertical position must be within min_ey..max_ey-1. */ + /* . the new horizontal position must be strictly less than max_ex */ + /* */ + /* Note that if a cell is to the left of the clipping region, it is */ + /* actually set to the (min_ex-1) horizontal position. */ + + /* All cells that are on the left of the clipping region go to the */ + /* min_ex - 1 horizontal position. */ + ey -= ras.min_ey; + + if ( ex > ras.max_ex ) + ex = ras.max_ex; + + ex -= ras.min_ex; + if ( ex < 0 ) + ex = -1; + + /* are we moving to a different cell ? */ + if ( ex != ras.ex || ey != ras.ey ) + { + /* record the current one if it is valid */ + if ( !ras.invalid ) + gray_record_cell( RAS_VAR ); + + ras.area = 0; + ras.cover = 0; + } + + ras.ex = ex; + ras.ey = ey; + ras.invalid = ( (unsigned)ey >= (unsigned)ras.count_ey || + ex >= ras.count_ex ); + } + + + /*************************************************************************/ + /* */ + /* Start a new contour at a given cell. */ + /* */ + static void + gray_start_cell( RAS_ARG_ TCoord ex, + TCoord ey ) + { + if ( ex > ras.max_ex ) + ex = (TCoord)( ras.max_ex ); + + if ( ex < ras.min_ex ) + ex = (TCoord)( ras.min_ex - 1 ); + + ras.area = 0; + ras.cover = 0; + ras.ex = ex - ras.min_ex; + ras.ey = ey - ras.min_ey; + ras.last_ey = SUBPIXELS( ey ); + ras.invalid = 0; + + gray_set_cell( RAS_VAR_ ex, ey ); + } + + + /*************************************************************************/ + /* */ + /* Render a scanline as one or more cells. */ + /* */ + static void + gray_render_scanline( RAS_ARG_ TCoord ey, + TPos x1, + TCoord y1, + TPos x2, + TCoord y2 ) + { + TCoord ex1, ex2, fx1, fx2, delta, mod, lift, rem; + long p, first, dx; + int incr; + + + dx = x2 - x1; + + ex1 = TRUNC( x1 ); + ex2 = TRUNC( x2 ); + fx1 = (TCoord)( x1 - SUBPIXELS( ex1 ) ); + fx2 = (TCoord)( x2 - SUBPIXELS( ex2 ) ); + + /* trivial case. Happens often */ + if ( y1 == y2 ) + { + gray_set_cell( RAS_VAR_ ex2, ey ); + return; + } + + /* everything is located in a single cell. That is easy! */ + /* */ + if ( ex1 == ex2 ) + { + delta = y2 - y1; + ras.area += (TArea)(( fx1 + fx2 ) * delta); + ras.cover += delta; + return; + } + + /* ok, we'll have to render a run of adjacent cells on the same */ + /* scanline... */ + /* */ + p = ( ONE_PIXEL - fx1 ) * ( y2 - y1 ); + first = ONE_PIXEL; + incr = 1; + + if ( dx < 0 ) + { + p = fx1 * ( y2 - y1 ); + first = 0; + incr = -1; + dx = -dx; + } + + delta = (TCoord)( p / dx ); + mod = (TCoord)( p % dx ); + if ( mod < 0 ) + { + delta--; + mod += (TCoord)dx; + } + + ras.area += (TArea)(( fx1 + first ) * delta); + ras.cover += delta; + + ex1 += incr; + gray_set_cell( RAS_VAR_ ex1, ey ); + y1 += delta; + + if ( ex1 != ex2 ) + { + p = ONE_PIXEL * ( y2 - y1 + delta ); + lift = (TCoord)( p / dx ); + rem = (TCoord)( p % dx ); + if ( rem < 0 ) + { + lift--; + rem += (TCoord)dx; + } + + mod -= (int)dx; + + while ( ex1 != ex2 ) + { + delta = lift; + mod += rem; + if ( mod >= 0 ) + { + mod -= (TCoord)dx; + delta++; + } + + ras.area += (TArea)(ONE_PIXEL * delta); + ras.cover += delta; + y1 += delta; + ex1 += incr; + gray_set_cell( RAS_VAR_ ex1, ey ); + } + } + + delta = y2 - y1; + ras.area += (TArea)(( fx2 + ONE_PIXEL - first ) * delta); + ras.cover += delta; + } + + + /*************************************************************************/ + /* */ + /* Render a given line as a series of scanlines. */ + /* */ + static void + gray_render_line( RAS_ARG_ TPos to_x, + TPos to_y ) + { + TCoord ey1, ey2, fy1, fy2, mod; + TPos dx, dy, x, x2; + long p, first; + int delta, rem, lift, incr; + + + ey1 = TRUNC( ras.last_ey ); + ey2 = TRUNC( to_y ); /* if (ey2 >= ras.max_ey) ey2 = ras.max_ey-1; */ + fy1 = (TCoord)( ras.y - ras.last_ey ); + fy2 = (TCoord)( to_y - SUBPIXELS( ey2 ) ); + + dx = to_x - ras.x; + dy = to_y - ras.y; + + /* XXX: we should do something about the trivial case where dx == 0, */ + /* as it happens very often! */ + + /* perform vertical clipping */ + { + TCoord min, max; + + + min = ey1; + max = ey2; + if ( ey1 > ey2 ) + { + min = ey2; + max = ey1; + } + if ( min >= ras.max_ey || max < ras.min_ey ) + goto End; + } + + /* everything is on a single scanline */ + if ( ey1 == ey2 ) + { + gray_render_scanline( RAS_VAR_ ey1, ras.x, fy1, to_x, fy2 ); + goto End; + } + + /* vertical line - avoid calling gray_render_scanline */ + incr = 1; + + if ( dx == 0 ) + { + TCoord ex = TRUNC( ras.x ); + TCoord two_fx = (TCoord)( ( ras.x - SUBPIXELS( ex ) ) << 1 ); + TArea area; + + + first = ONE_PIXEL; + if ( dy < 0 ) + { + first = 0; + incr = -1; + } + + delta = (int)( first - fy1 ); + ras.area += (TArea)two_fx * delta; + ras.cover += delta; + ey1 += incr; + + gray_set_cell( RAS_VAR_ ex, ey1 ); + + delta = (int)( first + first - ONE_PIXEL ); + area = (TArea)two_fx * delta; + while ( ey1 != ey2 ) + { + ras.area += area; + ras.cover += delta; + ey1 += incr; + + gray_set_cell( RAS_VAR_ ex, ey1 ); + } + + delta = (int)( fy2 - ONE_PIXEL + first ); + ras.area += (TArea)two_fx * delta; + ras.cover += delta; + + goto End; + } + + /* ok, we have to render several scanlines */ + p = ( ONE_PIXEL - fy1 ) * dx; + first = ONE_PIXEL; + incr = 1; + + if ( dy < 0 ) + { + p = fy1 * dx; + first = 0; + incr = -1; + dy = -dy; + } + + delta = (int)( p / dy ); + mod = (int)( p % dy ); + if ( mod < 0 ) + { + delta--; + mod += (TCoord)dy; + } + + x = ras.x + delta; + gray_render_scanline( RAS_VAR_ ey1, ras.x, fy1, x, (TCoord)first ); + + ey1 += incr; + gray_set_cell( RAS_VAR_ TRUNC( x ), ey1 ); + + if ( ey1 != ey2 ) + { + p = ONE_PIXEL * dx; + lift = (int)( p / dy ); + rem = (int)( p % dy ); + if ( rem < 0 ) + { + lift--; + rem += (int)dy; + } + mod -= (int)dy; + + while ( ey1 != ey2 ) + { + delta = lift; + mod += rem; + if ( mod >= 0 ) + { + mod -= (int)dy; + delta++; + } + + x2 = x + delta; + gray_render_scanline( RAS_VAR_ ey1, x, + (TCoord)( ONE_PIXEL - first ), x2, + (TCoord)first ); + x = x2; + + ey1 += incr; + gray_set_cell( RAS_VAR_ TRUNC( x ), ey1 ); + } + } + + gray_render_scanline( RAS_VAR_ ey1, x, + (TCoord)( ONE_PIXEL - first ), to_x, + fy2 ); + + End: + ras.x = to_x; + ras.y = to_y; + ras.last_ey = SUBPIXELS( ey2 ); + } + + + static void + gray_split_conic( FT_Vector* base ) + { + TPos a, b; + + + base[4].x = base[2].x; + b = base[1].x; + a = base[3].x = ( base[2].x + b ) / 2; + b = base[1].x = ( base[0].x + b ) / 2; + base[2].x = ( a + b ) / 2; + + base[4].y = base[2].y; + b = base[1].y; + a = base[3].y = ( base[2].y + b ) / 2; + b = base[1].y = ( base[0].y + b ) / 2; + base[2].y = ( a + b ) / 2; + } + + + static void + gray_render_conic( RAS_ARG_ const FT_Vector* control, + const FT_Vector* to ) + { + TPos dx, dy; + int top, level; + int* levels; + FT_Vector* arc; + + + dx = DOWNSCALE( ras.x ) + to->x - ( control->x << 1 ); + if ( dx < 0 ) + dx = -dx; + dy = DOWNSCALE( ras.y ) + to->y - ( control->y << 1 ); + if ( dy < 0 ) + dy = -dy; + if ( dx < dy ) + dx = dy; + + level = 1; + dx = dx / ras.conic_level; + while ( dx > 0 ) + { + dx >>= 2; + level++; + } + + /* a shortcut to speed things up */ + if ( level <= 1 ) + { + /* we compute the mid-point directly in order to avoid */ + /* calling gray_split_conic() */ + TPos to_x, to_y, mid_x, mid_y; + + + to_x = UPSCALE( to->x ); + to_y = UPSCALE( to->y ); + mid_x = ( ras.x + to_x + 2 * UPSCALE( control->x ) ) / 4; + mid_y = ( ras.y + to_y + 2 * UPSCALE( control->y ) ) / 4; + + gray_render_line( RAS_VAR_ mid_x, mid_y ); + gray_render_line( RAS_VAR_ to_x, to_y ); + + return; + } + + arc = ras.bez_stack; + levels = ras.lev_stack; + top = 0; + levels[0] = level; + + arc[0].x = UPSCALE( to->x ); + arc[0].y = UPSCALE( to->y ); + arc[1].x = UPSCALE( control->x ); + arc[1].y = UPSCALE( control->y ); + arc[2].x = ras.x; + arc[2].y = ras.y; + + while ( top >= 0 ) + { + level = levels[top]; + if ( level > 1 ) + { + /* check that the arc crosses the current band */ + TPos min, max, y; + + + min = max = arc[0].y; + + y = arc[1].y; + if ( y < min ) min = y; + if ( y > max ) max = y; + + y = arc[2].y; + if ( y < min ) min = y; + if ( y > max ) max = y; + + if ( TRUNC( min ) >= ras.max_ey || TRUNC( max ) < ras.min_ey ) + goto Draw; + + gray_split_conic( arc ); + arc += 2; + top++; + levels[top] = levels[top - 1] = level - 1; + continue; + } + + Draw: + { + TPos to_x, to_y, mid_x, mid_y; + + + to_x = arc[0].x; + to_y = arc[0].y; + mid_x = ( ras.x + to_x + 2 * arc[1].x ) / 4; + mid_y = ( ras.y + to_y + 2 * arc[1].y ) / 4; + + gray_render_line( RAS_VAR_ mid_x, mid_y ); + gray_render_line( RAS_VAR_ to_x, to_y ); + + top--; + arc -= 2; + } + } + + return; + } + + + static void + gray_split_cubic( FT_Vector* base ) + { + TPos a, b, c, d; + + + base[6].x = base[3].x; + c = base[1].x; + d = base[2].x; + base[1].x = a = ( base[0].x + c ) / 2; + base[5].x = b = ( base[3].x + d ) / 2; + c = ( c + d ) / 2; + base[2].x = a = ( a + c ) / 2; + base[4].x = b = ( b + c ) / 2; + base[3].x = ( a + b ) / 2; + + base[6].y = base[3].y; + c = base[1].y; + d = base[2].y; + base[1].y = a = ( base[0].y + c ) / 2; + base[5].y = b = ( base[3].y + d ) / 2; + c = ( c + d ) / 2; + base[2].y = a = ( a + c ) / 2; + base[4].y = b = ( b + c ) / 2; + base[3].y = ( a + b ) / 2; + } + + + static void + gray_render_cubic( RAS_ARG_ const FT_Vector* control1, + const FT_Vector* control2, + const FT_Vector* to ) + { + TPos dx, dy, da, db; + int top, level; + int* levels; + FT_Vector* arc; + + + dx = DOWNSCALE( ras.x ) + to->x - ( control1->x << 1 ); + if ( dx < 0 ) + dx = -dx; + dy = DOWNSCALE( ras.y ) + to->y - ( control1->y << 1 ); + if ( dy < 0 ) + dy = -dy; + if ( dx < dy ) + dx = dy; + da = dx; + + dx = DOWNSCALE( ras.x ) + to->x - 3 * ( control1->x + control2->x ); + if ( dx < 0 ) + dx = -dx; + dy = DOWNSCALE( ras.y ) + to->y - 3 * ( control1->x + control2->y ); + if ( dy < 0 ) + dy = -dy; + if ( dx < dy ) + dx = dy; + db = dx; + + level = 1; + da = da / ras.cubic_level; + db = db / ras.conic_level; + while ( da > 0 || db > 0 ) + { + da >>= 2; + db >>= 3; + level++; + } + + if ( level <= 1 ) + { + TPos to_x, to_y, mid_x, mid_y; + + + to_x = UPSCALE( to->x ); + to_y = UPSCALE( to->y ); + mid_x = ( ras.x + to_x + + 3 * UPSCALE( control1->x + control2->x ) ) / 8; + mid_y = ( ras.y + to_y + + 3 * UPSCALE( control1->y + control2->y ) ) / 8; + + gray_render_line( RAS_VAR_ mid_x, mid_y ); + gray_render_line( RAS_VAR_ to_x, to_y ); + return; + } + + arc = ras.bez_stack; + arc[0].x = UPSCALE( to->x ); + arc[0].y = UPSCALE( to->y ); + arc[1].x = UPSCALE( control2->x ); + arc[1].y = UPSCALE( control2->y ); + arc[2].x = UPSCALE( control1->x ); + arc[2].y = UPSCALE( control1->y ); + arc[3].x = ras.x; + arc[3].y = ras.y; + + levels = ras.lev_stack; + top = 0; + levels[0] = level; + + while ( top >= 0 ) + { + level = levels[top]; + if ( level > 1 ) + { + /* check that the arc crosses the current band */ + TPos min, max, y; + + + min = max = arc[0].y; + y = arc[1].y; + if ( y < min ) min = y; + if ( y > max ) max = y; + y = arc[2].y; + if ( y < min ) min = y; + if ( y > max ) max = y; + y = arc[3].y; + if ( y < min ) min = y; + if ( y > max ) max = y; + if ( TRUNC( min ) >= ras.max_ey || TRUNC( max ) < 0 ) + goto Draw; + gray_split_cubic( arc ); + arc += 3; + top ++; + levels[top] = levels[top - 1] = level - 1; + continue; + } + + Draw: + { + TPos to_x, to_y, mid_x, mid_y; + + + to_x = arc[0].x; + to_y = arc[0].y; + mid_x = ( ras.x + to_x + 3 * ( arc[1].x + arc[2].x ) ) / 8; + mid_y = ( ras.y + to_y + 3 * ( arc[1].y + arc[2].y ) ) / 8; + + gray_render_line( RAS_VAR_ mid_x, mid_y ); + gray_render_line( RAS_VAR_ to_x, to_y ); + top --; + arc -= 3; + } + } + + return; + } + + + + static int + gray_move_to( const FT_Vector* to, + PWorker worker ) + { + TPos x, y; + + + /* record current cell, if any */ + gray_record_cell( RAS_VAR ); + + /* start to a new position */ + x = UPSCALE( to->x ); + y = UPSCALE( to->y ); + + gray_start_cell( RAS_VAR_ TRUNC( x ), TRUNC( y ) ); + + worker->x = x; + worker->y = y; + return 0; + } + + + static int + gray_line_to( const FT_Vector* to, + PWorker worker ) + { + gray_render_line( RAS_VAR_ UPSCALE( to->x ), UPSCALE( to->y ) ); + return 0; + } + + + static int + gray_conic_to( const FT_Vector* control, + const FT_Vector* to, + PWorker worker ) + { + gray_render_conic( RAS_VAR_ control, to ); + return 0; + } + + + static int + gray_cubic_to( const FT_Vector* control1, + const FT_Vector* control2, + const FT_Vector* to, + PWorker worker ) + { + gray_render_cubic( RAS_VAR_ control1, control2, to ); + return 0; + } + + + static void + gray_render_span( int y, + int count, + const FT_Span* spans, + PWorker worker ) + { + unsigned char* p; + FT_Bitmap* map = &worker->target; + + + /* first of all, compute the scanline offset */ + p = (unsigned char*)map->buffer - y * map->pitch; + if ( map->pitch >= 0 ) + p += ( map->rows - 1 ) * map->pitch; + + for ( ; count > 0; count--, spans++ ) + { + unsigned char coverage = spans->coverage; + + + if ( coverage ) + { + /* For small-spans it is faster to do it by ourselves than + * calling `memset'. This is mainly due to the cost of the + * function call. + */ + if ( spans->len >= 8 ) + FT_MEM_SET( p + spans->x, (unsigned char)coverage, spans->len ); + else + { + unsigned char* q = p + spans->x; + + + switch ( spans->len ) + { + case 7: *q++ = (unsigned char)coverage; + case 6: *q++ = (unsigned char)coverage; + case 5: *q++ = (unsigned char)coverage; + case 4: *q++ = (unsigned char)coverage; + case 3: *q++ = (unsigned char)coverage; + case 2: *q++ = (unsigned char)coverage; + case 1: *q = (unsigned char)coverage; + default: + ; + } + } + } + } + } + + + static void + gray_hline( RAS_ARG_ TCoord x, + TCoord y, + TPos area, + TCoord acount ) + { + FT_Span* span; + int count; + int coverage; + + + /* compute the coverage line's coverage, depending on the */ + /* outline fill rule */ + /* */ + /* the coverage percentage is area/(PIXEL_BITS*PIXEL_BITS*2) */ + /* */ + coverage = (int)( area >> ( PIXEL_BITS * 2 + 1 - 8 ) ); + /* use range 0..256 */ + if ( coverage < 0 ) + coverage = -coverage; + + if ( ras.outline.flags & FT_OUTLINE_EVEN_ODD_FILL ) + { + coverage &= 511; + + if ( coverage > 256 ) + coverage = 512 - coverage; + else if ( coverage == 256 ) + coverage = 255; + } + else + { + /* normal non-zero winding rule */ + if ( coverage >= 256 ) + coverage = 255; + } + + y += (TCoord)ras.min_ey; + x += (TCoord)ras.min_ex; + + /* FT_Span.x is a 16-bit short, so limit our coordinates appropriately */ + if ( x >= 32767 ) + x = 32767; + + /* FT_Span.y is an integer, so limit our coordinates appropriately */ + if ( y >= FT_INT_MAX ) + y = FT_INT_MAX; + + if ( coverage ) + { + /* see whether we can add this span to the current list */ + count = ras.num_gray_spans; + span = ras.gray_spans + count - 1; + if ( count > 0 && + ras.span_y == y && + (int)span->x + span->len == (int)x && + span->coverage == coverage ) + { + span->len = (unsigned short)( span->len + acount ); + return; + } + + if ( ras.span_y != y || count >= FT_MAX_GRAY_SPANS ) + { + if ( ras.render_span && count > 0 ) + ras.render_span( ras.span_y, count, ras.gray_spans, + ras.render_span_data ); + +#ifdef FT_DEBUG_LEVEL_TRACE + + if ( count > 0 ) + { + int n; + + + FT_TRACE7(( "y = %3d ", ras.span_y )); + span = ras.gray_spans; + for ( n = 0; n < count; n++, span++ ) + FT_TRACE7(( "[%d..%d]:%02x ", + span->x, span->x + span->len - 1, span->coverage )); + FT_TRACE7(( "\n" )); + } + +#endif /* FT_DEBUG_LEVEL_TRACE */ + + ras.num_gray_spans = 0; + ras.span_y = (int)y; + + count = 0; + span = ras.gray_spans; + } + else + span++; + + /* add a gray span to the current list */ + span->x = (short)x; + span->len = (unsigned short)acount; + span->coverage = (unsigned char)coverage; + + ras.num_gray_spans++; + } + } + + +#ifdef FT_DEBUG_LEVEL_TRACE + + /* to be called while in the debugger -- */ + /* this function causes a compiler warning since it is unused otherwise */ + static void + gray_dump_cells( RAS_ARG ) + { + int yindex; + + + for ( yindex = 0; yindex < ras.ycount; yindex++ ) + { + PCell cell; + + + printf( "%3d:", yindex ); + + for ( cell = ras.ycells[yindex]; cell != NULL; cell = cell->next ) + printf( " (%3ld, c:%4ld, a:%6d)", cell->x, cell->cover, cell->area ); + printf( "\n" ); + } + } + +#endif /* FT_DEBUG_LEVEL_TRACE */ + + + static void + gray_sweep( RAS_ARG_ const FT_Bitmap* target ) + { + int yindex; + + FT_UNUSED( target ); + + + if ( ras.num_cells == 0 ) + return; + + ras.num_gray_spans = 0; + + FT_TRACE7(( "gray_sweep: start\n" )); + + for ( yindex = 0; yindex < ras.ycount; yindex++ ) + { + PCell cell = ras.ycells[yindex]; + TCoord cover = 0; + TCoord x = 0; + + + for ( ; cell != NULL; cell = cell->next ) + { + TPos area; + + + if ( cell->x > x && cover != 0 ) + gray_hline( RAS_VAR_ x, yindex, cover * ( ONE_PIXEL * 2 ), + cell->x - x ); + + cover += cell->cover; + area = cover * ( ONE_PIXEL * 2 ) - cell->area; + + if ( area != 0 && cell->x >= 0 ) + gray_hline( RAS_VAR_ cell->x, yindex, area, 1 ); + + x = cell->x + 1; + } + + if ( cover != 0 ) + gray_hline( RAS_VAR_ x, yindex, cover * ( ONE_PIXEL * 2 ), + ras.count_ex - x ); + } + + if ( ras.render_span && ras.num_gray_spans > 0 ) + ras.render_span( ras.span_y, ras.num_gray_spans, + ras.gray_spans, ras.render_span_data ); + + FT_TRACE7(( "gray_sweep: end\n" )); + } + + +#ifdef _STANDALONE_ + + /*************************************************************************/ + /* */ + /* The following function should only compile in stand-alone mode, */ + /* i.e., when building this component without the rest of FreeType. */ + /* */ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Decompose */ + /* */ + /* <Description> */ + /* Walk over an outline's structure to decompose it into individual */ + /* segments and Bézier arcs. This function is also able to emit */ + /* `move to' and `close to' operations to indicate the start and end */ + /* of new contours in the outline. */ + /* */ + /* <Input> */ + /* outline :: A pointer to the source target. */ + /* */ + /* func_interface :: A table of `emitters', i.e., function pointers */ + /* called during decomposition to indicate path */ + /* operations. */ + /* */ + /* <InOut> */ + /* user :: A typeless pointer which is passed to each */ + /* emitter during the decomposition. It can be */ + /* used to store the state during the */ + /* decomposition. */ + /* */ + /* <Return> */ + /* Error code. 0 means success. */ + /* */ + static int + FT_Outline_Decompose( const FT_Outline* outline, + const FT_Outline_Funcs* func_interface, + void* user ) + { +#undef SCALED +#define SCALED( x ) ( ( (x) << shift ) - delta ) + + FT_Vector v_last; + FT_Vector v_control; + FT_Vector v_start; + + FT_Vector* point; + FT_Vector* limit; + char* tags; + + int error; + + int n; /* index of contour in outline */ + int first; /* index of first point in contour */ + char tag; /* current point's state */ + + int shift; + TPos delta; + + + if ( !outline || !func_interface ) + return ErrRaster_Invalid_Argument; + + shift = func_interface->shift; + delta = func_interface->delta; + first = 0; + + for ( n = 0; n < outline->n_contours; n++ ) + { + int last; /* index of last point in contour */ + + + FT_TRACE5(( "FT_Outline_Decompose: Outline %d\n", n )); + + last = outline->contours[n]; + if ( last < 0 ) + goto Invalid_Outline; + limit = outline->points + last; + + v_start = outline->points[first]; + v_start.x = SCALED( v_start.x ); + v_start.y = SCALED( v_start.y ); + + v_last = outline->points[last]; + v_last.x = SCALED( v_last.x ); + v_last.y = SCALED( v_last.y ); + + v_control = v_start; + + point = outline->points + first; + tags = outline->tags + first; + tag = FT_CURVE_TAG( tags[0] ); + + /* A contour cannot start with a cubic control point! */ + if ( tag == FT_CURVE_TAG_CUBIC ) + goto Invalid_Outline; + + /* check first point to determine origin */ + if ( tag == FT_CURVE_TAG_CONIC ) + { + /* first point is conic control. Yes, this happens. */ + if ( FT_CURVE_TAG( outline->tags[last] ) == FT_CURVE_TAG_ON ) + { + /* start at last point if it is on the curve */ + v_start = v_last; + limit--; + } + else + { + /* if both first and last points are conic, */ + /* start at their middle and record its position */ + /* for closure */ + v_start.x = ( v_start.x + v_last.x ) / 2; + v_start.y = ( v_start.y + v_last.y ) / 2; + + v_last = v_start; + } + point--; + tags--; + } + + FT_TRACE5(( " move to (%.2f, %.2f)\n", + v_start.x / 64.0, v_start.y / 64.0 )); + error = func_interface->move_to( &v_start, user ); + if ( error ) + goto Exit; + + while ( point < limit ) + { + point++; + tags++; + + tag = FT_CURVE_TAG( tags[0] ); + switch ( tag ) + { + case FT_CURVE_TAG_ON: /* emit a single line_to */ + { + FT_Vector vec; + + + vec.x = SCALED( point->x ); + vec.y = SCALED( point->y ); + + FT_TRACE5(( " line to (%.2f, %.2f)\n", + vec.x / 64.0, vec.y / 64.0 )); + error = func_interface->line_to( &vec, user ); + if ( error ) + goto Exit; + continue; + } + + case FT_CURVE_TAG_CONIC: /* consume conic arcs */ + v_control.x = SCALED( point->x ); + v_control.y = SCALED( point->y ); + + Do_Conic: + if ( point < limit ) + { + FT_Vector vec; + FT_Vector v_middle; + + + point++; + tags++; + tag = FT_CURVE_TAG( tags[0] ); + + vec.x = SCALED( point->x ); + vec.y = SCALED( point->y ); + + if ( tag == FT_CURVE_TAG_ON ) + { + FT_TRACE5(( " conic to (%.2f, %.2f)" + " with control (%.2f, %.2f)\n", + vec.x / 64.0, vec.y / 64.0, + v_control.x / 64.0, v_control.y / 64.0 )); + error = func_interface->conic_to( &v_control, &vec, user ); + if ( error ) + goto Exit; + continue; + } + + if ( tag != FT_CURVE_TAG_CONIC ) + goto Invalid_Outline; + + v_middle.x = ( v_control.x + vec.x ) / 2; + v_middle.y = ( v_control.y + vec.y ) / 2; + + FT_TRACE5(( " conic to (%.2f, %.2f)" + " with control (%.2f, %.2f)\n", + v_middle.x / 64.0, v_middle.y / 64.0, + v_control.x / 64.0, v_control.y / 64.0 )); + error = func_interface->conic_to( &v_control, &v_middle, user ); + if ( error ) + goto Exit; + + v_control = vec; + goto Do_Conic; + } + + FT_TRACE5(( " conic to (%.2f, %.2f)" + " with control (%.2f, %.2f)\n", + v_start.x / 64.0, v_start.y / 64.0, + v_control.x / 64.0, v_control.y / 64.0 )); + error = func_interface->conic_to( &v_control, &v_start, user ); + goto Close; + + default: /* FT_CURVE_TAG_CUBIC */ + { + FT_Vector vec1, vec2; + + + if ( point + 1 > limit || + FT_CURVE_TAG( tags[1] ) != FT_CURVE_TAG_CUBIC ) + goto Invalid_Outline; + + point += 2; + tags += 2; + + vec1.x = SCALED( point[-2].x ); + vec1.y = SCALED( point[-2].y ); + + vec2.x = SCALED( point[-1].x ); + vec2.y = SCALED( point[-1].y ); + + if ( point <= limit ) + { + FT_Vector vec; + + + vec.x = SCALED( point->x ); + vec.y = SCALED( point->y ); + + FT_TRACE5(( " cubic to (%.2f, %.2f)" + " with controls (%.2f, %.2f) and (%.2f, %.2f)\n", + vec.x / 64.0, vec.y / 64.0, + vec1.x / 64.0, vec1.y / 64.0, + vec2.x / 64.0, vec2.y / 64.0 )); + error = func_interface->cubic_to( &vec1, &vec2, &vec, user ); + if ( error ) + goto Exit; + continue; + } + + FT_TRACE5(( " cubic to (%.2f, %.2f)" + " with controls (%.2f, %.2f) and (%.2f, %.2f)\n", + v_start.x / 64.0, v_start.y / 64.0, + vec1.x / 64.0, vec1.y / 64.0, + vec2.x / 64.0, vec2.y / 64.0 )); + error = func_interface->cubic_to( &vec1, &vec2, &v_start, user ); + goto Close; + } + } + } + + /* close the contour with a line segment */ + FT_TRACE5(( " line to (%.2f, %.2f)\n", + v_start.x / 64.0, v_start.y / 64.0 )); + error = func_interface->line_to( &v_start, user ); + + Close: + if ( error ) + goto Exit; + + first = last + 1; + } + + FT_TRACE5(( "FT_Outline_Decompose: Done\n", n )); + return 0; + + Exit: + FT_TRACE5(( "FT_Outline_Decompose: Error %d\n", error )); + return error; + + Invalid_Outline: + return ErrRaster_Invalid_Outline; + } + +#endif /* _STANDALONE_ */ + + + typedef struct TBand_ + { + TPos min, max; + + } TBand; + + FT_DEFINE_OUTLINE_FUNCS(func_interface, + (FT_Outline_MoveTo_Func) gray_move_to, + (FT_Outline_LineTo_Func) gray_line_to, + (FT_Outline_ConicTo_Func)gray_conic_to, + (FT_Outline_CubicTo_Func)gray_cubic_to, + 0, + 0 + ) + + static int + gray_convert_glyph_inner( RAS_ARG ) + { + + volatile int error = 0; + +#ifdef FT_CONFIG_OPTION_PIC + FT_Outline_Funcs func_interface; + Init_Class_func_interface(&func_interface); +#endif + + if ( ft_setjmp( ras.jump_buffer ) == 0 ) + { + error = FT_Outline_Decompose( &ras.outline, &func_interface, &ras ); + gray_record_cell( RAS_VAR ); + } + else + error = ErrRaster_Memory_Overflow; + + return error; + } + + + static int + gray_convert_glyph( RAS_ARG ) + { + TBand bands[40]; + TBand* volatile band; + int volatile n, num_bands; + TPos volatile min, max, max_y; + FT_BBox* clip; + + + /* Set up state in the raster object */ + gray_compute_cbox( RAS_VAR ); + + /* clip to target bitmap, exit if nothing to do */ + clip = &ras.clip_box; + + if ( ras.max_ex <= clip->xMin || ras.min_ex >= clip->xMax || + ras.max_ey <= clip->yMin || ras.min_ey >= clip->yMax ) + return 0; + + if ( ras.min_ex < clip->xMin ) ras.min_ex = clip->xMin; + if ( ras.min_ey < clip->yMin ) ras.min_ey = clip->yMin; + + if ( ras.max_ex > clip->xMax ) ras.max_ex = clip->xMax; + if ( ras.max_ey > clip->yMax ) ras.max_ey = clip->yMax; + + ras.count_ex = ras.max_ex - ras.min_ex; + ras.count_ey = ras.max_ey - ras.min_ey; + + /* simple heuristic used to speed up the bezier decomposition -- see */ + /* the code in gray_render_conic() and gray_render_cubic() for more */ + /* details */ + ras.conic_level = 32; + ras.cubic_level = 16; + + { + int level = 0; + + + if ( ras.count_ex > 24 || ras.count_ey > 24 ) + level++; + if ( ras.count_ex > 120 || ras.count_ey > 120 ) + level++; + + ras.conic_level <<= level; + ras.cubic_level <<= level; + } + + /* set up vertical bands */ + num_bands = (int)( ( ras.max_ey - ras.min_ey ) / ras.band_size ); + if ( num_bands == 0 ) + num_bands = 1; + if ( num_bands >= 39 ) + num_bands = 39; + + ras.band_shoot = 0; + + min = ras.min_ey; + max_y = ras.max_ey; + + for ( n = 0; n < num_bands; n++, min = max ) + { + max = min + ras.band_size; + if ( n == num_bands - 1 || max > max_y ) + max = max_y; + + bands[0].min = min; + bands[0].max = max; + band = bands; + + while ( band >= bands ) + { + TPos bottom, top, middle; + int error; + + { + PCell cells_max; + int yindex; + long cell_start, cell_end, cell_mod; + + + ras.ycells = (PCell*)ras.buffer; + ras.ycount = band->max - band->min; + + cell_start = sizeof ( PCell ) * ras.ycount; + cell_mod = cell_start % sizeof ( TCell ); + if ( cell_mod > 0 ) + cell_start += sizeof ( TCell ) - cell_mod; + + cell_end = ras.buffer_size; + cell_end -= cell_end % sizeof( TCell ); + + cells_max = (PCell)( (char*)ras.buffer + cell_end ); + ras.cells = (PCell)( (char*)ras.buffer + cell_start ); + if ( ras.cells >= cells_max ) + goto ReduceBands; + + ras.max_cells = cells_max - ras.cells; + if ( ras.max_cells < 2 ) + goto ReduceBands; + + for ( yindex = 0; yindex < ras.ycount; yindex++ ) + ras.ycells[yindex] = NULL; + } + + ras.num_cells = 0; + ras.invalid = 1; + ras.min_ey = band->min; + ras.max_ey = band->max; + ras.count_ey = band->max - band->min; + + error = gray_convert_glyph_inner( RAS_VAR ); + + if ( !error ) + { + gray_sweep( RAS_VAR_ &ras.target ); + band--; + continue; + } + else if ( error != ErrRaster_Memory_Overflow ) + return 1; + + ReduceBands: + /* render pool overflow; we will reduce the render band by half */ + bottom = band->min; + top = band->max; + middle = bottom + ( ( top - bottom ) >> 1 ); + + /* This is too complex for a single scanline; there must */ + /* be some problems. */ + if ( middle == bottom ) + { +#ifdef FT_DEBUG_LEVEL_TRACE + FT_TRACE7(( "gray_convert_glyph: rotten glyph\n" )); +#endif + return 1; + } + + if ( bottom-top >= ras.band_size ) + ras.band_shoot++; + + band[1].min = bottom; + band[1].max = middle; + band[0].min = middle; + band[0].max = top; + band++; + } + } + + if ( ras.band_shoot > 8 && ras.band_size > 16 ) + ras.band_size = ras.band_size / 2; + + return 0; + } + + + static int + gray_raster_render( PRaster raster, + const FT_Raster_Params* params ) + { + const FT_Outline* outline = (const FT_Outline*)params->source; + const FT_Bitmap* target_map = params->target; + PWorker worker; + + + if ( !raster || !raster->buffer || !raster->buffer_size ) + return ErrRaster_Invalid_Argument; + + if ( !outline ) + return ErrRaster_Invalid_Outline; + + /* return immediately if the outline is empty */ + if ( outline->n_points == 0 || outline->n_contours <= 0 ) + return 0; + + if ( !outline->contours || !outline->points ) + return ErrRaster_Invalid_Outline; + + if ( outline->n_points != + outline->contours[outline->n_contours - 1] + 1 ) + return ErrRaster_Invalid_Outline; + + worker = raster->worker; + + /* if direct mode is not set, we must have a target bitmap */ + if ( !( params->flags & FT_RASTER_FLAG_DIRECT ) ) + { + if ( !target_map ) + return ErrRaster_Invalid_Argument; + + /* nothing to do */ + if ( !target_map->width || !target_map->rows ) + return 0; + + if ( !target_map->buffer ) + return ErrRaster_Invalid_Argument; + } + + /* this version does not support monochrome rendering */ + if ( !( params->flags & FT_RASTER_FLAG_AA ) ) + return ErrRaster_Invalid_Mode; + + /* compute clipping box */ + if ( !( params->flags & FT_RASTER_FLAG_DIRECT ) ) + { + /* compute clip box from target pixmap */ + ras.clip_box.xMin = 0; + ras.clip_box.yMin = 0; + ras.clip_box.xMax = target_map->width; + ras.clip_box.yMax = target_map->rows; + } + else if ( params->flags & FT_RASTER_FLAG_CLIP ) + ras.clip_box = params->clip_box; + else + { + ras.clip_box.xMin = -32768L; + ras.clip_box.yMin = -32768L; + ras.clip_box.xMax = 32767L; + ras.clip_box.yMax = 32767L; + } + + gray_init_cells( RAS_VAR_ raster->buffer, raster->buffer_size ); + + ras.outline = *outline; + ras.num_cells = 0; + ras.invalid = 1; + ras.band_size = raster->band_size; + ras.num_gray_spans = 0; + + if ( params->flags & FT_RASTER_FLAG_DIRECT ) + { + ras.render_span = (FT_Raster_Span_Func)params->gray_spans; + ras.render_span_data = params->user; + } + else + { + ras.target = *target_map; + ras.render_span = (FT_Raster_Span_Func)gray_render_span; + ras.render_span_data = &ras; + } + + return gray_convert_glyph( RAS_VAR ); + } + + + /**** RASTER OBJECT CREATION: In stand-alone mode, we simply use *****/ + /**** a static object. *****/ + +#ifdef _STANDALONE_ + + static int + gray_raster_new( void* memory, + FT_Raster* araster ) + { + static TRaster the_raster; + + FT_UNUSED( memory ); + + + *araster = (FT_Raster)&the_raster; + FT_MEM_ZERO( &the_raster, sizeof ( the_raster ) ); + + return 0; + } + + + static void + gray_raster_done( FT_Raster raster ) + { + /* nothing */ + FT_UNUSED( raster ); + } + +#else /* _STANDALONE_ */ + + static int + gray_raster_new( FT_Memory memory, + FT_Raster* araster ) + { + FT_Error error; + PRaster raster; + + + *araster = 0; + if ( !FT_ALLOC( raster, sizeof ( TRaster ) ) ) + { + raster->memory = memory; + *araster = (FT_Raster)raster; + } + + return error; + } + + + static void + gray_raster_done( FT_Raster raster ) + { + FT_Memory memory = (FT_Memory)((PRaster)raster)->memory; + + + FT_FREE( raster ); + } + +#endif /* _STANDALONE_ */ + + + static void + gray_raster_reset( FT_Raster raster, + char* pool_base, + long pool_size ) + { + PRaster rast = (PRaster)raster; + + + if ( raster ) + { + if ( pool_base && pool_size >= (long)sizeof ( TWorker ) + 2048 ) + { + PWorker worker = (PWorker)pool_base; + + + rast->worker = worker; + rast->buffer = pool_base + + ( ( sizeof ( TWorker ) + sizeof ( TCell ) - 1 ) & + ~( sizeof ( TCell ) - 1 ) ); + rast->buffer_size = (long)( ( pool_base + pool_size ) - + (char*)rast->buffer ) & + ~( sizeof ( TCell ) - 1 ); + rast->band_size = (int)( rast->buffer_size / + ( sizeof ( TCell ) * 8 ) ); + } + else + { + rast->buffer = NULL; + rast->buffer_size = 0; + rast->worker = NULL; + } + } + } + + + FT_DEFINE_RASTER_FUNCS(ft_grays_raster, + FT_GLYPH_FORMAT_OUTLINE, + + (FT_Raster_New_Func) gray_raster_new, + (FT_Raster_Reset_Func) gray_raster_reset, + (FT_Raster_Set_Mode_Func)0, + (FT_Raster_Render_Func) gray_raster_render, + (FT_Raster_Done_Func) gray_raster_done + ) + + +/* END */ + + +/* Local Variables: */ +/* coding: utf-8 */ +/* End: */ diff --git a/mod/pub.mod/freetype.mod/src/smooth/ftgrays.h b/mod/pub.mod/freetype.mod/src/smooth/ftgrays.h new file mode 100644 index 0000000..f20f55f --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/smooth/ftgrays.h @@ -0,0 +1,58 @@ +/***************************************************************************/ +/* */ +/* ftgrays.h */ +/* */ +/* FreeType smooth renderer declaration */ +/* */ +/* Copyright 1996-2001 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTGRAYS_H__ +#define __FTGRAYS_H__ + +#ifdef __cplusplus + extern "C" { +#endif + + +#ifdef _STANDALONE_ +#include "ftimage.h" +#else +#include <ft2build.h> +#include FT_CONFIG_CONFIG_H /* for FT_CONFIG_OPTION_PIC */ +#include FT_IMAGE_H +#endif + + + /*************************************************************************/ + /* */ + /* To make ftgrays.h independent from configuration files we check */ + /* whether FT_EXPORT_VAR has been defined already. */ + /* */ + /* On some systems and compilers (Win32 mostly), an extra keyword is */ + /* necessary to compile the library as a DLL. */ + /* */ +#ifndef FT_EXPORT_VAR +#define FT_EXPORT_VAR( x ) extern x +#endif + + FT_EXPORT_VAR( const FT_Raster_Funcs ) ft_grays_raster; + + +#ifdef __cplusplus + } +#endif + +#endif /* __FTGRAYS_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/smooth/ftsmerrs.h b/mod/pub.mod/freetype.mod/src/smooth/ftsmerrs.h new file mode 100644 index 0000000..0c2a2ec --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/smooth/ftsmerrs.h @@ -0,0 +1,41 @@ +/***************************************************************************/ +/* */ +/* ftsmerrs.h */ +/* */ +/* smooth renderer error codes (specification only). */ +/* */ +/* Copyright 2001 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file is used to define the smooth renderer error enumeration */ + /* constants. */ + /* */ + /*************************************************************************/ + +#ifndef __FTSMERRS_H__ +#define __FTSMERRS_H__ + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#define FT_ERR_PREFIX Smooth_Err_ +#define FT_ERR_BASE FT_Mod_Err_Smooth + +#include FT_ERRORS_H + +#endif /* __FTSMERRS_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/smooth/ftsmooth.c b/mod/pub.mod/freetype.mod/src/smooth/ftsmooth.c new file mode 100644 index 0000000..eed6353 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/smooth/ftsmooth.c @@ -0,0 +1,481 @@ +/***************************************************************************/ +/* */ +/* ftsmooth.c */ +/* */ +/* Anti-aliasing renderer interface (body). */ +/* */ +/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_OBJECTS_H +#include FT_OUTLINE_H +#include "ftsmooth.h" +#include "ftgrays.h" +#include "ftspic.h" + +#include "ftsmerrs.h" + + + /* initialize renderer -- init its raster */ + static FT_Error + ft_smooth_init( FT_Renderer render ) + { + FT_Library library = FT_MODULE_LIBRARY( render ); + + + render->clazz->raster_class->raster_reset( render->raster, + library->raster_pool, + library->raster_pool_size ); + + return 0; + } + + + /* sets render-specific mode */ + static FT_Error + ft_smooth_set_mode( FT_Renderer render, + FT_ULong mode_tag, + FT_Pointer data ) + { + /* we simply pass it to the raster */ + return render->clazz->raster_class->raster_set_mode( render->raster, + mode_tag, + data ); + } + + /* transform a given glyph image */ + static FT_Error + ft_smooth_transform( FT_Renderer render, + FT_GlyphSlot slot, + const FT_Matrix* matrix, + const FT_Vector* delta ) + { + FT_Error error = Smooth_Err_Ok; + + + if ( slot->format != render->glyph_format ) + { + error = Smooth_Err_Invalid_Argument; + goto Exit; + } + + if ( matrix ) + FT_Outline_Transform( &slot->outline, matrix ); + + if ( delta ) + FT_Outline_Translate( &slot->outline, delta->x, delta->y ); + + Exit: + return error; + } + + + /* return the glyph's control box */ + static void + ft_smooth_get_cbox( FT_Renderer render, + FT_GlyphSlot slot, + FT_BBox* cbox ) + { + FT_MEM_ZERO( cbox, sizeof ( *cbox ) ); + + if ( slot->format == render->glyph_format ) + FT_Outline_Get_CBox( &slot->outline, cbox ); + } + + + /* convert a slot's glyph image into a bitmap */ + static FT_Error + ft_smooth_render_generic( FT_Renderer render, + FT_GlyphSlot slot, + FT_Render_Mode mode, + const FT_Vector* origin, + FT_Render_Mode required_mode ) + { + FT_Error error; + FT_Outline* outline = NULL; + FT_BBox cbox; + FT_UInt width, height, height_org, width_org, pitch; + FT_Bitmap* bitmap; + FT_Memory memory; + FT_Int hmul = mode == FT_RENDER_MODE_LCD; + FT_Int vmul = mode == FT_RENDER_MODE_LCD_V; + FT_Pos x_shift, y_shift, x_left, y_top; + + FT_Raster_Params params; + + + /* check glyph image format */ + if ( slot->format != render->glyph_format ) + { + error = Smooth_Err_Invalid_Argument; + goto Exit; + } + + /* check mode */ + if ( mode != required_mode ) + return Smooth_Err_Cannot_Render_Glyph; + + outline = &slot->outline; + + /* translate the outline to the new origin if needed */ + if ( origin ) + FT_Outline_Translate( outline, origin->x, origin->y ); + + /* compute the control box, and grid fit it */ + FT_Outline_Get_CBox( outline, &cbox ); + + cbox.xMin = FT_PIX_FLOOR( cbox.xMin ); + cbox.yMin = FT_PIX_FLOOR( cbox.yMin ); + cbox.xMax = FT_PIX_CEIL( cbox.xMax ); + cbox.yMax = FT_PIX_CEIL( cbox.yMax ); + + width = (FT_UInt)( ( cbox.xMax - cbox.xMin ) >> 6 ); + height = (FT_UInt)( ( cbox.yMax - cbox.yMin ) >> 6 ); + bitmap = &slot->bitmap; + memory = render->root.memory; + + width_org = width; + height_org = height; + + /* release old bitmap buffer */ + if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) + { + FT_FREE( bitmap->buffer ); + slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; + } + + /* allocate new one */ + pitch = width; + if ( hmul ) + { + width = width * 3; + pitch = FT_PAD_CEIL( width, 4 ); + } + + if ( vmul ) + height *= 3; + + x_shift = (FT_Int) cbox.xMin; + y_shift = (FT_Int) cbox.yMin; + x_left = (FT_Int)( cbox.xMin >> 6 ); + y_top = (FT_Int)( cbox.yMax >> 6 ); + +#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING + + if ( slot->library->lcd_filter_func ) + { + FT_Int extra = slot->library->lcd_extra; + + + if ( hmul ) + { + x_shift -= 64 * ( extra >> 1 ); + width += 3 * extra; + pitch = FT_PAD_CEIL( width, 4 ); + x_left -= extra >> 1; + } + + if ( vmul ) + { + y_shift -= 64 * ( extra >> 1 ); + height += 3 * extra; + y_top += extra >> 1; + } + } + +#endif + +#if FT_UINT_MAX > 0xFFFFU + + /* Required check is ( pitch * height < FT_ULONG_MAX ), */ + /* but we care realistic cases only. Always pitch <= width. */ + if ( width > 0xFFFFU || height > 0xFFFFU ) + { + FT_ERROR(( "ft_smooth_render_generic: glyph too large: %d x %d\n", + width, height )); + return Smooth_Err_Raster_Overflow; + } + +#endif + + bitmap->pixel_mode = FT_PIXEL_MODE_GRAY; + bitmap->num_grays = 256; + bitmap->width = width; + bitmap->rows = height; + bitmap->pitch = pitch; + + /* translate outline to render it into the bitmap */ + FT_Outline_Translate( outline, -x_shift, -y_shift ); + + if ( FT_ALLOC( bitmap->buffer, (FT_ULong)pitch * height ) ) + goto Exit; + + slot->internal->flags |= FT_GLYPH_OWN_BITMAP; + + /* set up parameters */ + params.target = bitmap; + params.source = outline; + params.flags = FT_RASTER_FLAG_AA; + +#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING + + /* implode outline if needed */ + { + FT_Vector* points = outline->points; + FT_Vector* points_end = points + outline->n_points; + FT_Vector* vec; + + + if ( hmul ) + for ( vec = points; vec < points_end; vec++ ) + vec->x *= 3; + + if ( vmul ) + for ( vec = points; vec < points_end; vec++ ) + vec->y *= 3; + } + + /* render outline into the bitmap */ + error = render->raster_render( render->raster, ¶ms ); + + /* deflate outline if needed */ + { + FT_Vector* points = outline->points; + FT_Vector* points_end = points + outline->n_points; + FT_Vector* vec; + + + if ( hmul ) + for ( vec = points; vec < points_end; vec++ ) + vec->x /= 3; + + if ( vmul ) + for ( vec = points; vec < points_end; vec++ ) + vec->y /= 3; + } + + if ( slot->library->lcd_filter_func ) + slot->library->lcd_filter_func( bitmap, mode, slot->library ); + +#else /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ + + /* render outline into bitmap */ + error = render->raster_render( render->raster, ¶ms ); + + /* expand it horizontally */ + if ( hmul ) + { + FT_Byte* line = bitmap->buffer; + FT_UInt hh; + + + for ( hh = height_org; hh > 0; hh--, line += pitch ) + { + FT_UInt xx; + FT_Byte* end = line + width; + + + for ( xx = width_org; xx > 0; xx-- ) + { + FT_UInt pixel = line[xx-1]; + + + end[-3] = (FT_Byte)pixel; + end[-2] = (FT_Byte)pixel; + end[-1] = (FT_Byte)pixel; + end -= 3; + } + } + } + + /* expand it vertically */ + if ( vmul ) + { + FT_Byte* read = bitmap->buffer + ( height - height_org ) * pitch; + FT_Byte* write = bitmap->buffer; + FT_UInt hh; + + + for ( hh = height_org; hh > 0; hh-- ) + { + ft_memcpy( write, read, pitch ); + write += pitch; + + ft_memcpy( write, read, pitch ); + write += pitch; + + ft_memcpy( write, read, pitch ); + write += pitch; + read += pitch; + } + } + +#endif /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ + + FT_Outline_Translate( outline, x_shift, y_shift ); + + /* + * XXX: on 16bit system, we return an error for huge bitmap + * to prevent an overflow. + */ + if ( x_left > FT_INT_MAX || y_top > FT_INT_MAX ) + return Smooth_Err_Invalid_Pixel_Size; + + if ( error ) + goto Exit; + + slot->format = FT_GLYPH_FORMAT_BITMAP; + slot->bitmap_left = (FT_Int)x_left; + slot->bitmap_top = (FT_Int)y_top; + + Exit: + if ( outline && origin ) + FT_Outline_Translate( outline, -origin->x, -origin->y ); + + return error; + } + + + /* convert a slot's glyph image into a bitmap */ + static FT_Error + ft_smooth_render( FT_Renderer render, + FT_GlyphSlot slot, + FT_Render_Mode mode, + const FT_Vector* origin ) + { + if ( mode == FT_RENDER_MODE_LIGHT ) + mode = FT_RENDER_MODE_NORMAL; + + return ft_smooth_render_generic( render, slot, mode, origin, + FT_RENDER_MODE_NORMAL ); + } + + + /* convert a slot's glyph image into a horizontal LCD bitmap */ + static FT_Error + ft_smooth_render_lcd( FT_Renderer render, + FT_GlyphSlot slot, + FT_Render_Mode mode, + const FT_Vector* origin ) + { + FT_Error error; + + error = ft_smooth_render_generic( render, slot, mode, origin, + FT_RENDER_MODE_LCD ); + if ( !error ) + slot->bitmap.pixel_mode = FT_PIXEL_MODE_LCD; + + return error; + } + + + /* convert a slot's glyph image into a vertical LCD bitmap */ + static FT_Error + ft_smooth_render_lcd_v( FT_Renderer render, + FT_GlyphSlot slot, + FT_Render_Mode mode, + const FT_Vector* origin ) + { + FT_Error error; + + error = ft_smooth_render_generic( render, slot, mode, origin, + FT_RENDER_MODE_LCD_V ); + if ( !error ) + slot->bitmap.pixel_mode = FT_PIXEL_MODE_LCD_V; + + return error; + } + + + FT_DEFINE_RENDERER(ft_smooth_renderer_class, + + FT_MODULE_RENDERER, + sizeof( FT_RendererRec ), + + "smooth", + 0x10000L, + 0x20000L, + + 0, /* module specific interface */ + + (FT_Module_Constructor)ft_smooth_init, + (FT_Module_Destructor) 0, + (FT_Module_Requester) 0 + , + + FT_GLYPH_FORMAT_OUTLINE, + + (FT_Renderer_RenderFunc) ft_smooth_render, + (FT_Renderer_TransformFunc)ft_smooth_transform, + (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, + (FT_Renderer_SetModeFunc) ft_smooth_set_mode, + + (FT_Raster_Funcs*) &FT_GRAYS_RASTER_GET + ) + + + FT_DEFINE_RENDERER(ft_smooth_lcd_renderer_class, + + FT_MODULE_RENDERER, + sizeof( FT_RendererRec ), + + "smooth-lcd", + 0x10000L, + 0x20000L, + + 0, /* module specific interface */ + + (FT_Module_Constructor)ft_smooth_init, + (FT_Module_Destructor) 0, + (FT_Module_Requester) 0 + , + + FT_GLYPH_FORMAT_OUTLINE, + + (FT_Renderer_RenderFunc) ft_smooth_render_lcd, + (FT_Renderer_TransformFunc)ft_smooth_transform, + (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, + (FT_Renderer_SetModeFunc) ft_smooth_set_mode, + + (FT_Raster_Funcs*) &FT_GRAYS_RASTER_GET + ) + + FT_DEFINE_RENDERER(ft_smooth_lcdv_renderer_class, + + FT_MODULE_RENDERER, + sizeof( FT_RendererRec ), + + "smooth-lcdv", + 0x10000L, + 0x20000L, + + 0, /* module specific interface */ + + (FT_Module_Constructor)ft_smooth_init, + (FT_Module_Destructor) 0, + (FT_Module_Requester) 0 + , + + FT_GLYPH_FORMAT_OUTLINE, + + (FT_Renderer_RenderFunc) ft_smooth_render_lcd_v, + (FT_Renderer_TransformFunc)ft_smooth_transform, + (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, + (FT_Renderer_SetModeFunc) ft_smooth_set_mode, + + (FT_Raster_Funcs*) &FT_GRAYS_RASTER_GET + ) + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/smooth/ftsmooth.h b/mod/pub.mod/freetype.mod/src/smooth/ftsmooth.h new file mode 100644 index 0000000..3708790 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/smooth/ftsmooth.h @@ -0,0 +1,49 @@ +/***************************************************************************/ +/* */ +/* ftsmooth.h */ +/* */ +/* Anti-aliasing renderer interface (specification). */ +/* */ +/* Copyright 1996-2001 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTSMOOTH_H__ +#define __FTSMOOTH_H__ + + +#include <ft2build.h> +#include FT_RENDER_H + + +FT_BEGIN_HEADER + + +#ifndef FT_CONFIG_OPTION_NO_STD_RASTER + FT_DECLARE_RENDERER( ft_std_renderer_class ) +#endif + +#ifndef FT_CONFIG_OPTION_NO_SMOOTH_RASTER + FT_DECLARE_RENDERER( ft_smooth_renderer_class ) + + FT_DECLARE_RENDERER( ft_smooth_lcd_renderer_class ) + + FT_DECLARE_RENDERER( ft_smooth_lcd_v_renderer_class ) +#endif + + + +FT_END_HEADER + +#endif /* __FTSMOOTH_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/smooth/ftspic.c b/mod/pub.mod/freetype.mod/src/smooth/ftspic.c new file mode 100644 index 0000000..aa547fc --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/smooth/ftspic.c @@ -0,0 +1,97 @@ +/***************************************************************************/ +/* */ +/* ftspic.c */ +/* */ +/* The FreeType position independent code services for smooth module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include "ftspic.h" + +#ifdef FT_CONFIG_OPTION_PIC + + /* forward declaration of PIC init functions from ftgrays.c */ + void FT_Init_Class_ft_grays_raster(FT_Raster_Funcs*); + + void + ft_smooth_renderer_class_pic_free( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Memory memory = library->memory; + if ( pic_container->smooth ) + { + SmoothPIC* container = (SmoothPIC*)pic_container->smooth; + if(--container->ref_count) + return; + FT_FREE( container ); + pic_container->smooth = NULL; + } + } + + + FT_Error + ft_smooth_renderer_class_pic_init( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Error error = FT_Err_Ok; + SmoothPIC* container; + FT_Memory memory = library->memory; + + /* since this function also serve smooth_lcd and smooth_lcdv renderers, + it implements reference counting */ + if(pic_container->smooth) + { + ((SmoothPIC*)pic_container->smooth)->ref_count++; + return error; + } + + /* allocate pointer, clear and set global container pointer */ + if ( FT_ALLOC ( container, sizeof ( *container ) ) ) + return error; + FT_MEM_SET( container, 0, sizeof(*container) ); + pic_container->smooth = container; + container->ref_count = 1; + + /* initialize pointer table - this is how the module usually expects this data */ + FT_Init_Class_ft_grays_raster(&container->ft_grays_raster); +/*Exit:*/ + if(error) + ft_smooth_renderer_class_pic_free(library); + return error; + } + + /* re-route these init and free functions to the above functions */ + FT_Error ft_smooth_lcd_renderer_class_pic_init(FT_Library library) + { + return ft_smooth_renderer_class_pic_init(library); + } + void ft_smooth_lcd_renderer_class_pic_free(FT_Library library) + { + ft_smooth_renderer_class_pic_free(library); + } + FT_Error ft_smooth_lcdv_renderer_class_pic_init(FT_Library library) + { + return ft_smooth_renderer_class_pic_init(library); + } + void ft_smooth_lcdv_renderer_class_pic_free(FT_Library library) + { + ft_smooth_renderer_class_pic_free(library); + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/smooth/ftspic.h b/mod/pub.mod/freetype.mod/src/smooth/ftspic.h new file mode 100644 index 0000000..c7e0ce9 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/smooth/ftspic.h @@ -0,0 +1,50 @@ +/***************************************************************************/ +/* */ +/* ftspic.h */ +/* */ +/* The FreeType position independent code services for smooth module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTSPIC_H__ +#define __FTSPIC_H__ + + +FT_BEGIN_HEADER + +#include FT_INTERNAL_PIC_H + +#ifndef FT_CONFIG_OPTION_PIC +#define FT_GRAYS_RASTER_GET ft_grays_raster + +#else /* FT_CONFIG_OPTION_PIC */ + + typedef struct SmoothPIC_ + { + int ref_count; + FT_Raster_Funcs ft_grays_raster; + } SmoothPIC; + +#define GET_PIC(lib) ((SmoothPIC*)((lib)->pic_container.smooth)) +#define FT_GRAYS_RASTER_GET (GET_PIC(library)->ft_grays_raster) + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + +FT_END_HEADER + +#endif /* __FTSPIC_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/smooth/smooth.c b/mod/pub.mod/freetype.mod/src/smooth/smooth.c new file mode 100644 index 0000000..a8ac51f --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/smooth/smooth.c @@ -0,0 +1,27 @@ +/***************************************************************************/ +/* */ +/* smooth.c */ +/* */ +/* FreeType anti-aliasing rasterer module component (body only). */ +/* */ +/* Copyright 1996-2001 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#define FT_MAKE_OPTION_SINGLE_OBJECT + +#include <ft2build.h> +#include "ftspic.c" +#include "ftgrays.c" +#include "ftsmooth.c" + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/truetype/truetype.c b/mod/pub.mod/freetype.mod/src/truetype/truetype.c new file mode 100644 index 0000000..4bd1209 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/truetype/truetype.c @@ -0,0 +1,37 @@ +/***************************************************************************/ +/* */ +/* truetype.c */ +/* */ +/* FreeType TrueType driver component (body only). */ +/* */ +/* Copyright 1996-2001, 2004, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#define FT_MAKE_OPTION_SINGLE_OBJECT + +#include <ft2build.h> +#include "ttpic.c" +#include "ttdriver.c" /* driver interface */ +#include "ttpload.c" /* tables loader */ +#include "ttgload.c" /* glyph loader */ +#include "ttobjs.c" /* object manager */ + +#ifdef TT_USE_BYTECODE_INTERPRETER +#include "ttinterp.c" +#endif + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT +#include "ttgxvar.c" /* gx distortable font */ +#endif + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/truetype/ttdriver.c b/mod/pub.mod/freetype.mod/src/truetype/ttdriver.c new file mode 100644 index 0000000..dca009a --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/truetype/ttdriver.c @@ -0,0 +1,477 @@ +/***************************************************************************/ +/* */ +/* ttdriver.c */ +/* */ +/* TrueType font driver implementation (body). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_SFNT_H +#include FT_SERVICE_XFREE86_NAME_H + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT +#include FT_MULTIPLE_MASTERS_H +#include FT_SERVICE_MULTIPLE_MASTERS_H +#endif + +#include FT_SERVICE_TRUETYPE_ENGINE_H +#include FT_SERVICE_TRUETYPE_GLYF_H + +#include "ttdriver.h" +#include "ttgload.h" +#include "ttpload.h" + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT +#include "ttgxvar.h" +#endif + +#include "tterrors.h" + +#include "ttpic.h" + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_ttdriver + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** F A C E S ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + +#undef PAIR_TAG +#define PAIR_TAG( left, right ) ( ( (FT_ULong)left << 16 ) | \ + (FT_ULong)right ) + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_get_kerning */ + /* */ + /* <Description> */ + /* A driver method used to return the kerning vector between two */ + /* glyphs of the same face. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face object. */ + /* */ + /* left_glyph :: The index of the left glyph in the kern pair. */ + /* */ + /* right_glyph :: The index of the right glyph in the kern pair. */ + /* */ + /* <Output> */ + /* kerning :: The kerning vector. This is in font units for */ + /* scalable formats, and in pixels for fixed-sizes */ + /* formats. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* Only horizontal layouts (left-to-right & right-to-left) are */ + /* supported by this function. Other layouts, or more sophisticated */ + /* kernings, are out of scope of this method (the basic driver */ + /* interface is meant to be simple). */ + /* */ + /* They can be implemented by format-specific interfaces. */ + /* */ + static FT_Error + tt_get_kerning( FT_Face ttface, /* TT_Face */ + FT_UInt left_glyph, + FT_UInt right_glyph, + FT_Vector* kerning ) + { + TT_Face face = (TT_Face)ttface; + SFNT_Service sfnt = (SFNT_Service)face->sfnt; + + + kerning->x = 0; + kerning->y = 0; + + if ( sfnt ) + kerning->x = sfnt->get_kerning( face, left_glyph, right_glyph ); + + return 0; + } + + +#undef PAIR_TAG + + + static FT_Error + tt_get_advances( FT_Face ttface, + FT_UInt start, + FT_UInt count, + FT_Int32 flags, + FT_Fixed *advances ) + { + FT_UInt nn; + TT_Face face = (TT_Face) ttface; + FT_Bool check = FT_BOOL( + !( flags & FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ) ); + + + /* XXX: TODO: check for sbits */ + + if ( flags & FT_LOAD_VERTICAL_LAYOUT ) + { + for ( nn = 0; nn < count; nn++ ) + { + FT_Short tsb; + FT_UShort ah; + + + TT_Get_VMetrics( face, start + nn, check, &tsb, &ah ); + advances[nn] = ah; + } + } + else + { + for ( nn = 0; nn < count; nn++ ) + { + FT_Short lsb; + FT_UShort aw; + + + TT_Get_HMetrics( face, start + nn, check, &lsb, &aw ); + advances[nn] = aw; + } + } + + return TT_Err_Ok; + } + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** S I Z E S ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + + static FT_Error + tt_size_select( FT_Size size, + FT_ULong strike_index ) + { + TT_Face ttface = (TT_Face)size->face; + TT_Size ttsize = (TT_Size)size; + FT_Error error = TT_Err_Ok; + + + ttsize->strike_index = strike_index; + + if ( FT_IS_SCALABLE( size->face ) ) + { + /* use the scaled metrics, even when tt_size_reset fails */ + FT_Select_Metrics( size->face, strike_index ); + + tt_size_reset( ttsize ); + } + else + { + SFNT_Service sfnt = (SFNT_Service) ttface->sfnt; + FT_Size_Metrics* metrics = &size->metrics; + + + error = sfnt->load_strike_metrics( ttface, strike_index, metrics ); + if ( error ) + ttsize->strike_index = 0xFFFFFFFFUL; + } + + return error; + } + +#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ + + + static FT_Error + tt_size_request( FT_Size size, + FT_Size_Request req ) + { + TT_Size ttsize = (TT_Size)size; + FT_Error error = TT_Err_Ok; + + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + + if ( FT_HAS_FIXED_SIZES( size->face ) ) + { + TT_Face ttface = (TT_Face)size->face; + SFNT_Service sfnt = (SFNT_Service) ttface->sfnt; + FT_ULong strike_index; + + + error = sfnt->set_sbit_strike( ttface, req, &strike_index ); + + if ( error ) + ttsize->strike_index = 0xFFFFFFFFUL; + else + return tt_size_select( size, strike_index ); + } + +#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ + + FT_Request_Metrics( size->face, req ); + + if ( FT_IS_SCALABLE( size->face ) ) + error = tt_size_reset( ttsize ); + + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Load_Glyph */ + /* */ + /* <Description> */ + /* A driver method used to load a glyph within a given glyph slot. */ + /* */ + /* <Input> */ + /* slot :: A handle to the target slot object where the glyph */ + /* will be loaded. */ + /* */ + /* size :: A handle to the source face size at which the glyph */ + /* must be scaled, loaded, etc. */ + /* */ + /* glyph_index :: The index of the glyph in the font file. */ + /* */ + /* load_flags :: A flag indicating what to load for this glyph. The */ + /* FT_LOAD_XXX constants can be used to control the */ + /* glyph loading process (e.g., whether the outline */ + /* should be scaled, whether to load bitmaps or not, */ + /* whether to hint the outline, etc). */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + static FT_Error + Load_Glyph( FT_GlyphSlot ttslot, /* TT_GlyphSlot */ + FT_Size ttsize, /* TT_Size */ + FT_UInt glyph_index, + FT_Int32 load_flags ) + { + TT_GlyphSlot slot = (TT_GlyphSlot)ttslot; + TT_Size size = (TT_Size)ttsize; + FT_Face face = ttslot->face; + FT_Error error; + + + if ( !slot ) + return TT_Err_Invalid_Slot_Handle; + + if ( !size ) + return TT_Err_Invalid_Size_Handle; + + if ( !face || glyph_index >= (FT_UInt)face->num_glyphs ) + return TT_Err_Invalid_Argument; + + if ( load_flags & FT_LOAD_NO_HINTING ) + { + /* both FT_LOAD_NO_HINTING and FT_LOAD_NO_AUTOHINT */ + /* are necessary to disable hinting for tricky fonts */ + + if ( FT_IS_TRICKY( face ) ) + load_flags &= ~FT_LOAD_NO_HINTING; + + if ( load_flags & FT_LOAD_NO_AUTOHINT ) + load_flags |= FT_LOAD_NO_HINTING; + } + + if ( load_flags & ( FT_LOAD_NO_RECURSE | FT_LOAD_NO_SCALE ) ) + { + load_flags |= FT_LOAD_NO_BITMAP | FT_LOAD_NO_SCALE; + + if ( !FT_IS_TRICKY( face ) ) + load_flags |= FT_LOAD_NO_HINTING; + } + + /* now load the glyph outline if necessary */ + error = TT_Load_Glyph( size, slot, glyph_index, load_flags ); + + /* force drop-out mode to 2 - irrelevant now */ + /* slot->outline.dropout_mode = 2; */ + + return error; + } + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** D R I V E R I N T E R F A C E ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + FT_DEFINE_SERVICE_MULTIMASTERSREC(tt_service_gx_multi_masters, + (FT_Get_MM_Func) NULL, + (FT_Set_MM_Design_Func) NULL, + (FT_Set_MM_Blend_Func) TT_Set_MM_Blend, + (FT_Get_MM_Var_Func) TT_Get_MM_Var, + (FT_Set_Var_Design_Func)TT_Set_Var_Design + ) +#endif + + static const FT_Service_TrueTypeEngineRec tt_service_truetype_engine = + { +#ifdef TT_USE_BYTECODE_INTERPRETER + +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING + FT_TRUETYPE_ENGINE_TYPE_UNPATENTED +#else + FT_TRUETYPE_ENGINE_TYPE_PATENTED +#endif + +#else /* !TT_USE_BYTECODE_INTERPRETER */ + + FT_TRUETYPE_ENGINE_TYPE_NONE + +#endif /* TT_USE_BYTECODE_INTERPRETER */ + }; + + FT_DEFINE_SERVICE_TTGLYFREC(tt_service_truetype_glyf, + (TT_Glyf_GetLocationFunc)tt_face_get_location + ) + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + FT_DEFINE_SERVICEDESCREC4(tt_services, + FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_TRUETYPE, + FT_SERVICE_ID_MULTI_MASTERS, &FT_TT_SERVICE_GX_MULTI_MASTERS_GET, + FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine, + FT_SERVICE_ID_TT_GLYF, &FT_TT_SERVICE_TRUETYPE_GLYF_GET + ) +#else + FT_DEFINE_SERVICEDESCREC3(tt_services, + FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_TRUETYPE, + FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine, + FT_SERVICE_ID_TT_GLYF, &FT_TT_SERVICE_TRUETYPE_GLYF_GET + ) +#endif + + FT_CALLBACK_DEF( FT_Module_Interface ) + tt_get_interface( FT_Module driver, /* TT_Driver */ + const char* tt_interface ) + { + FT_Library library = driver->library; + FT_Module_Interface result; + FT_Module sfntd; + SFNT_Service sfnt; + FT_UNUSED(library); + + result = ft_service_list_lookup( FT_TT_SERVICES_GET, tt_interface ); + if ( result != NULL ) + return result; + + /* only return the default interface from the SFNT module */ + sfntd = FT_Get_Module( driver->library, "sfnt" ); + if ( sfntd ) + { + sfnt = (SFNT_Service)( sfntd->clazz->module_interface ); + if ( sfnt ) + return sfnt->get_interface( driver, tt_interface ); + } + + return 0; + } + + + /* The FT_DriverInterface structure is defined in ftdriver.h. */ + +#ifdef TT_USE_BYTECODE_INTERPRETER +#define TT_HINTER_FLAG FT_MODULE_DRIVER_HAS_HINTER +#else +#define TT_HINTER_FLAG 0 +#endif + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS +#define TT_SIZE_SELECT tt_size_select +#else +#define TT_SIZE_SELECT 0 +#endif + + FT_DEFINE_DRIVER(tt_driver_class, + + + FT_MODULE_FONT_DRIVER | + FT_MODULE_DRIVER_SCALABLE | + TT_HINTER_FLAG, + + sizeof ( TT_DriverRec ), + + "truetype", /* driver name */ + 0x10000L, /* driver version == 1.0 */ + 0x20000L, /* driver requires FreeType 2.0 or above */ + + (void*)0, /* driver specific interface */ + + tt_driver_init, + tt_driver_done, + tt_get_interface, + + sizeof ( TT_FaceRec ), + sizeof ( TT_SizeRec ), + sizeof ( FT_GlyphSlotRec ), + + tt_face_init, + tt_face_done, + tt_size_init, + tt_size_done, + tt_slot_init, + 0, /* FT_Slot_DoneFunc */ + + ft_stub_set_char_sizes, /* FT_CONFIG_OPTION_OLD_INTERNALS */ + ft_stub_set_pixel_sizes, /* FT_CONFIG_OPTION_OLD_INTERNALS */ + + Load_Glyph, + + tt_get_kerning, + 0, /* FT_Face_AttachFunc */ + tt_get_advances, + + tt_size_request, + TT_SIZE_SELECT + ) + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/truetype/ttdriver.h b/mod/pub.mod/freetype.mod/src/truetype/ttdriver.h new file mode 100644 index 0000000..aae00f2 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/truetype/ttdriver.h @@ -0,0 +1,38 @@ +/***************************************************************************/ +/* */ +/* ttdriver.h */ +/* */ +/* High-level TrueType driver interface (specification). */ +/* */ +/* Copyright 1996-2001, 2002 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __TTDRIVER_H__ +#define __TTDRIVER_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_DRIVER_H + + +FT_BEGIN_HEADER + + + FT_DECLARE_DRIVER( tt_driver_class ) + + +FT_END_HEADER + +#endif /* __TTDRIVER_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/truetype/tterrors.h b/mod/pub.mod/freetype.mod/src/truetype/tterrors.h new file mode 100644 index 0000000..d317c70 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/truetype/tterrors.h @@ -0,0 +1,40 @@ +/***************************************************************************/ +/* */ +/* tterrors.h */ +/* */ +/* TrueType error codes (specification only). */ +/* */ +/* Copyright 2001 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file is used to define the TrueType error enumeration */ + /* constants. */ + /* */ + /*************************************************************************/ + +#ifndef __TTERRORS_H__ +#define __TTERRORS_H__ + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#define FT_ERR_PREFIX TT_Err_ +#define FT_ERR_BASE FT_Mod_Err_TrueType + +#include FT_ERRORS_H + +#endif /* __TTERRORS_H__ */ + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/truetype/ttgload.c b/mod/pub.mod/freetype.mod/src/truetype/ttgload.c new file mode 100644 index 0000000..28ddb99 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/truetype/ttgload.c @@ -0,0 +1,2037 @@ +/***************************************************************************/ +/* */ +/* ttgload.c */ +/* */ +/* TrueType Glyph Loader (body). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_CALC_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_SFNT_H +#include FT_TRUETYPE_TAGS_H +#include FT_OUTLINE_H + +#include "ttgload.h" +#include "ttpload.h" + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT +#include "ttgxvar.h" +#endif + +#include "tterrors.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_ttgload + + + /*************************************************************************/ + /* */ + /* Composite font flags. */ + /* */ +#define ARGS_ARE_WORDS 0x0001 +#define ARGS_ARE_XY_VALUES 0x0002 +#define ROUND_XY_TO_GRID 0x0004 +#define WE_HAVE_A_SCALE 0x0008 +/* reserved 0x0010 */ +#define MORE_COMPONENTS 0x0020 +#define WE_HAVE_AN_XY_SCALE 0x0040 +#define WE_HAVE_A_2X2 0x0080 +#define WE_HAVE_INSTR 0x0100 +#define USE_MY_METRICS 0x0200 +#define OVERLAP_COMPOUND 0x0400 +#define SCALED_COMPONENT_OFFSET 0x0800 +#define UNSCALED_COMPONENT_OFFSET 0x1000 + + + /*************************************************************************/ + /* */ + /* Returns the horizontal metrics in font units for a given glyph. If */ + /* `check' is true, take care of monospaced fonts by returning the */ + /* advance width maximum. */ + /* */ + FT_LOCAL_DEF(void) + TT_Get_HMetrics( TT_Face face, + FT_UInt idx, + FT_Bool check, + FT_Short* lsb, + FT_UShort* aw ) + { + ( (SFNT_Service)face->sfnt )->get_metrics( face, 0, idx, lsb, aw ); + + if ( check && face->postscript.isFixedPitch ) + *aw = face->horizontal.advance_Width_Max; + } + + + /*************************************************************************/ + /* */ + /* Returns the vertical metrics in font units for a given glyph. */ + /* Greg Hitchcock from Microsoft told us that if there were no `vmtx' */ + /* table, typoAscender/Descender from the `OS/2' table would be used */ + /* instead, and if there were no `OS/2' table, use ascender/descender */ + /* from the `hhea' table. But that is not what Microsoft's rasterizer */ + /* apparently does: It uses the ppem value as the advance height, and */ + /* sets the top side bearing to be zero. */ + /* */ + /* The monospace `check' is probably not meaningful here, but we leave */ + /* it in for a consistent interface. */ + /* */ + FT_LOCAL_DEF(void) + TT_Get_VMetrics( TT_Face face, + FT_UInt idx, + FT_Bool check, + FT_Short* tsb, + FT_UShort* ah ) + { + FT_UNUSED( check ); + + if ( face->vertical_info ) + ( (SFNT_Service)face->sfnt )->get_metrics( face, 1, idx, tsb, ah ); + +#if 1 /* Empirically determined, at variance with what MS said */ + + else + { + *tsb = 0; + *ah = face->root.units_per_EM; + } + +#else /* This is what MS said to do. It isn't what they do, however. */ + + else if ( face->os2.version != 0xFFFFU ) + { + *tsb = face->os2.sTypoAscender; + *ah = face->os2.sTypoAscender - face->os2.sTypoDescender; + } + else + { + *tsb = face->horizontal.Ascender; + *ah = face->horizontal.Ascender - face->horizontal.Descender; + } + +#endif + + } + + + /*************************************************************************/ + /* */ + /* Translates an array of coordinates. */ + /* */ + static void + translate_array( FT_UInt n, + FT_Vector* coords, + FT_Pos delta_x, + FT_Pos delta_y ) + { + FT_UInt k; + + + if ( delta_x ) + for ( k = 0; k < n; k++ ) + coords[k].x += delta_x; + + if ( delta_y ) + for ( k = 0; k < n; k++ ) + coords[k].y += delta_y; + } + + +#undef IS_HINTED +#define IS_HINTED( flags ) ( ( flags & FT_LOAD_NO_HINTING ) == 0 ) + + + /*************************************************************************/ + /* */ + /* The following functions are used by default with TrueType fonts. */ + /* However, they can be replaced by alternatives if we need to support */ + /* TrueType-compressed formats (like MicroType) in the future. */ + /* */ + /*************************************************************************/ + + FT_CALLBACK_DEF( FT_Error ) + TT_Access_Glyph_Frame( TT_Loader loader, + FT_UInt glyph_index, + FT_ULong offset, + FT_UInt byte_count ) + { + FT_Error error; + FT_Stream stream = loader->stream; + + /* for non-debug mode */ + FT_UNUSED( glyph_index ); + + + FT_TRACE5(( "Glyph %ld\n", glyph_index )); + + /* the following line sets the `error' variable through macros! */ + if ( FT_STREAM_SEEK( offset ) || FT_FRAME_ENTER( byte_count ) ) + return error; + + loader->cursor = stream->cursor; + loader->limit = stream->limit; + + return TT_Err_Ok; + } + + + FT_CALLBACK_DEF( void ) + TT_Forget_Glyph_Frame( TT_Loader loader ) + { + FT_Stream stream = loader->stream; + + + FT_FRAME_EXIT(); + } + + + FT_CALLBACK_DEF( FT_Error ) + TT_Load_Glyph_Header( TT_Loader loader ) + { + FT_Byte* p = loader->cursor; + FT_Byte* limit = loader->limit; + + + if ( p + 10 > limit ) + return TT_Err_Invalid_Outline; + + loader->n_contours = FT_NEXT_SHORT( p ); + + loader->bbox.xMin = FT_NEXT_SHORT( p ); + loader->bbox.yMin = FT_NEXT_SHORT( p ); + loader->bbox.xMax = FT_NEXT_SHORT( p ); + loader->bbox.yMax = FT_NEXT_SHORT( p ); + + FT_TRACE5(( " # of contours: %d\n", loader->n_contours )); + FT_TRACE5(( " xMin: %4d xMax: %4d\n", loader->bbox.xMin, + loader->bbox.xMax )); + FT_TRACE5(( " yMin: %4d yMax: %4d\n", loader->bbox.yMin, + loader->bbox.yMax )); + loader->cursor = p; + + return TT_Err_Ok; + } + + + FT_CALLBACK_DEF( FT_Error ) + TT_Load_Simple_Glyph( TT_Loader load ) + { + FT_Error error; + FT_Byte* p = load->cursor; + FT_Byte* limit = load->limit; + FT_GlyphLoader gloader = load->gloader; + FT_Int n_contours = load->n_contours; + FT_Outline* outline; + TT_Face face = (TT_Face)load->face; + FT_UShort n_ins; + FT_Int n_points; + + FT_Byte *flag, *flag_limit; + FT_Byte c, count; + FT_Vector *vec, *vec_limit; + FT_Pos x; + FT_Short *cont, *cont_limit, prev_cont; + FT_Int xy_size = 0; + + + /* check that we can add the contours to the glyph */ + error = FT_GLYPHLOADER_CHECK_POINTS( gloader, 0, n_contours ); + if ( error ) + goto Fail; + + /* reading the contours' endpoints & number of points */ + cont = gloader->current.outline.contours; + cont_limit = cont + n_contours; + + /* check space for contours array + instructions count */ + if ( n_contours >= 0xFFF || p + ( n_contours + 1 ) * 2 > limit ) + goto Invalid_Outline; + + prev_cont = FT_NEXT_USHORT( p ); + + if ( n_contours > 0 ) + cont[0] = prev_cont; + + for ( cont++; cont < cont_limit; cont++ ) + { + cont[0] = FT_NEXT_USHORT( p ); + if ( cont[0] <= prev_cont ) + { + /* unordered contours: this is invalid */ + error = FT_Err_Invalid_Table; + goto Fail; + } + prev_cont = cont[0]; + } + + n_points = 0; + if ( n_contours > 0 ) + { + n_points = cont[-1] + 1; + if ( n_points < 0 ) + goto Invalid_Outline; + } + + /* note that we will add four phantom points later */ + error = FT_GLYPHLOADER_CHECK_POINTS( gloader, n_points + 4, 0 ); + if ( error ) + goto Fail; + + /* we'd better check the contours table right now */ + outline = &gloader->current.outline; + + for ( cont = outline->contours + 1; cont < cont_limit; cont++ ) + if ( cont[-1] >= cont[0] ) + goto Invalid_Outline; + + /* reading the bytecode instructions */ + load->glyph->control_len = 0; + load->glyph->control_data = 0; + + if ( p + 2 > limit ) + goto Invalid_Outline; + + n_ins = FT_NEXT_USHORT( p ); + + FT_TRACE5(( " Instructions size: %u\n", n_ins )); + + if ( n_ins > face->max_profile.maxSizeOfInstructions ) + { + FT_TRACE0(( "TT_Load_Simple_Glyph: too many instructions (%d)\n", + n_ins )); + error = TT_Err_Too_Many_Hints; + goto Fail; + } + + if ( ( limit - p ) < n_ins ) + { + FT_TRACE0(( "TT_Load_Simple_Glyph: instruction count mismatch\n" )); + error = TT_Err_Too_Many_Hints; + goto Fail; + } + +#ifdef TT_USE_BYTECODE_INTERPRETER + + if ( IS_HINTED( load->load_flags ) ) + { + load->glyph->control_len = n_ins; + load->glyph->control_data = load->exec->glyphIns; + + FT_MEM_COPY( load->exec->glyphIns, p, (FT_Long)n_ins ); + } + +#endif /* TT_USE_BYTECODE_INTERPRETER */ + + p += n_ins; + + /* reading the point tags */ + flag = (FT_Byte*)outline->tags; + flag_limit = flag + n_points; + + FT_ASSERT( flag != NULL ); + + while ( flag < flag_limit ) + { + if ( p + 1 > limit ) + goto Invalid_Outline; + + *flag++ = c = FT_NEXT_BYTE( p ); + if ( c & 8 ) + { + if ( p + 1 > limit ) + goto Invalid_Outline; + + count = FT_NEXT_BYTE( p ); + if ( flag + (FT_Int)count > flag_limit ) + goto Invalid_Outline; + + for ( ; count > 0; count-- ) + *flag++ = c; + } + } + + /* reading the X coordinates */ + + vec = outline->points; + vec_limit = vec + n_points; + flag = (FT_Byte*)outline->tags; + x = 0; + + if ( p + xy_size > limit ) + goto Invalid_Outline; + + for ( ; vec < vec_limit; vec++, flag++ ) + { + FT_Pos y = 0; + FT_Byte f = *flag; + + + if ( f & 2 ) + { + if ( p + 1 > limit ) + goto Invalid_Outline; + + y = (FT_Pos)FT_NEXT_BYTE( p ); + if ( ( f & 16 ) == 0 ) + y = -y; + } + else if ( ( f & 16 ) == 0 ) + { + if ( p + 2 > limit ) + goto Invalid_Outline; + + y = (FT_Pos)FT_NEXT_SHORT( p ); + } + + x += y; + vec->x = x; + /* the cast is for stupid compilers */ + *flag = (FT_Byte)( f & ~( 2 | 16 ) ); + } + + /* reading the Y coordinates */ + + vec = gloader->current.outline.points; + vec_limit = vec + n_points; + flag = (FT_Byte*)outline->tags; + x = 0; + + for ( ; vec < vec_limit; vec++, flag++ ) + { + FT_Pos y = 0; + FT_Byte f = *flag; + + + if ( f & 4 ) + { + if ( p + 1 > limit ) + goto Invalid_Outline; + + y = (FT_Pos)FT_NEXT_BYTE( p ); + if ( ( f & 32 ) == 0 ) + y = -y; + } + else if ( ( f & 32 ) == 0 ) + { + if ( p + 2 > limit ) + goto Invalid_Outline; + + y = (FT_Pos)FT_NEXT_SHORT( p ); + } + + x += y; + vec->y = x; + /* the cast is for stupid compilers */ + *flag = (FT_Byte)( f & FT_CURVE_TAG_ON ); + } + + outline->n_points = (FT_UShort)n_points; + outline->n_contours = (FT_Short) n_contours; + + load->cursor = p; + + Fail: + return error; + + Invalid_Outline: + error = TT_Err_Invalid_Outline; + goto Fail; + } + + + FT_CALLBACK_DEF( FT_Error ) + TT_Load_Composite_Glyph( TT_Loader loader ) + { + FT_Error error; + FT_Byte* p = loader->cursor; + FT_Byte* limit = loader->limit; + FT_GlyphLoader gloader = loader->gloader; + FT_SubGlyph subglyph; + FT_UInt num_subglyphs; + + + num_subglyphs = 0; + + do + { + FT_Fixed xx, xy, yy, yx; + FT_UInt count; + + + /* check that we can load a new subglyph */ + error = FT_GlyphLoader_CheckSubGlyphs( gloader, num_subglyphs + 1 ); + if ( error ) + goto Fail; + + /* check space */ + if ( p + 4 > limit ) + goto Invalid_Composite; + + subglyph = gloader->current.subglyphs + num_subglyphs; + + subglyph->arg1 = subglyph->arg2 = 0; + + subglyph->flags = FT_NEXT_USHORT( p ); + subglyph->index = FT_NEXT_USHORT( p ); + + /* check space */ + count = 2; + if ( subglyph->flags & ARGS_ARE_WORDS ) + count += 2; + if ( subglyph->flags & WE_HAVE_A_SCALE ) + count += 2; + else if ( subglyph->flags & WE_HAVE_AN_XY_SCALE ) + count += 4; + else if ( subglyph->flags & WE_HAVE_A_2X2 ) + count += 8; + + if ( p + count > limit ) + goto Invalid_Composite; + + /* read arguments */ + if ( subglyph->flags & ARGS_ARE_WORDS ) + { + subglyph->arg1 = FT_NEXT_SHORT( p ); + subglyph->arg2 = FT_NEXT_SHORT( p ); + } + else + { + subglyph->arg1 = FT_NEXT_CHAR( p ); + subglyph->arg2 = FT_NEXT_CHAR( p ); + } + + /* read transform */ + xx = yy = 0x10000L; + xy = yx = 0; + + if ( subglyph->flags & WE_HAVE_A_SCALE ) + { + xx = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; + yy = xx; + } + else if ( subglyph->flags & WE_HAVE_AN_XY_SCALE ) + { + xx = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; + yy = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; + } + else if ( subglyph->flags & WE_HAVE_A_2X2 ) + { + xx = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; + yx = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; + xy = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; + yy = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; + } + + subglyph->transform.xx = xx; + subglyph->transform.xy = xy; + subglyph->transform.yx = yx; + subglyph->transform.yy = yy; + + num_subglyphs++; + + } while ( subglyph->flags & MORE_COMPONENTS ); + + gloader->current.num_subglyphs = num_subglyphs; + +#ifdef TT_USE_BYTECODE_INTERPRETER + + { + FT_Stream stream = loader->stream; + + + /* we must undo the FT_FRAME_ENTER in order to point */ + /* to the composite instructions, if we find some. */ + /* We will process them later. */ + /* */ + loader->ins_pos = (FT_ULong)( FT_STREAM_POS() + + p - limit ); + } + +#endif + + loader->cursor = p; + + Fail: + return error; + + Invalid_Composite: + error = TT_Err_Invalid_Composite; + goto Fail; + } + + + FT_LOCAL_DEF( void ) + TT_Init_Glyph_Loading( TT_Face face ) + { + face->access_glyph_frame = TT_Access_Glyph_Frame; + face->read_glyph_header = TT_Load_Glyph_Header; + face->read_simple_glyph = TT_Load_Simple_Glyph; + face->read_composite_glyph = TT_Load_Composite_Glyph; + face->forget_glyph_frame = TT_Forget_Glyph_Frame; + } + + + static void + tt_prepare_zone( TT_GlyphZone zone, + FT_GlyphLoad load, + FT_UInt start_point, + FT_UInt start_contour ) + { + zone->n_points = (FT_UShort)( load->outline.n_points - start_point ); + zone->n_contours = (FT_Short) ( load->outline.n_contours - + start_contour ); + zone->org = load->extra_points + start_point; + zone->cur = load->outline.points + start_point; + zone->orus = load->extra_points2 + start_point; + zone->tags = (FT_Byte*)load->outline.tags + start_point; + zone->contours = (FT_UShort*)load->outline.contours + start_contour; + zone->first_point = (FT_UShort)start_point; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* TT_Hint_Glyph */ + /* */ + /* <Description> */ + /* Hint the glyph using the zone prepared by the caller. Note that */ + /* the zone is supposed to include four phantom points. */ + /* */ + static FT_Error + TT_Hint_Glyph( TT_Loader loader, + FT_Bool is_composite ) + { + TT_GlyphZone zone = &loader->zone; + FT_Pos origin; + +#ifdef TT_USE_BYTECODE_INTERPRETER + FT_UInt n_ins; +#else + FT_UNUSED( is_composite ); +#endif + + +#ifdef TT_USE_BYTECODE_INTERPRETER + if ( loader->glyph->control_len > 0xFFFFL ) + { + FT_TRACE1(( "TT_Hint_Glyph: too long instructions " )); + FT_TRACE1(( "(0x%lx byte) is truncated\n", + loader->glyph->control_len )); + } + n_ins = (FT_UInt)( loader->glyph->control_len ); +#endif + + origin = zone->cur[zone->n_points - 4].x; + origin = FT_PIX_ROUND( origin ) - origin; + if ( origin ) + translate_array( zone->n_points, zone->cur, origin, 0 ); + +#ifdef TT_USE_BYTECODE_INTERPRETER + /* save original point position in org */ + if ( n_ins > 0 ) + FT_ARRAY_COPY( zone->org, zone->cur, zone->n_points ); + + /* Reset graphics state. */ + loader->exec->GS = ((TT_Size)loader->size)->GS; + + /* XXX: UNDOCUMENTED! Hinting instructions of a composite glyph */ + /* completely refer to the (already) hinted subglyphs. */ + if ( is_composite ) + { + loader->exec->metrics.x_scale = 1 << 16; + loader->exec->metrics.y_scale = 1 << 16; + + FT_ARRAY_COPY( zone->orus, zone->cur, zone->n_points ); + } + else + { + loader->exec->metrics.x_scale = + ((TT_Size)loader->size)->metrics.x_scale; + loader->exec->metrics.y_scale = + ((TT_Size)loader->size)->metrics.y_scale; + } +#endif + + /* round pp2 and pp4 */ + zone->cur[zone->n_points - 3].x = + FT_PIX_ROUND( zone->cur[zone->n_points - 3].x ); + zone->cur[zone->n_points - 1].y = + FT_PIX_ROUND( zone->cur[zone->n_points - 1].y ); + +#ifdef TT_USE_BYTECODE_INTERPRETER + + if ( n_ins > 0 ) + { + FT_Bool debug; + FT_Error error; + + FT_GlyphLoader gloader = loader->gloader; + FT_Outline current_outline = gloader->current.outline; + + + error = TT_Set_CodeRange( loader->exec, tt_coderange_glyph, + loader->exec->glyphIns, n_ins ); + if ( error ) + return error; + + loader->exec->is_composite = is_composite; + loader->exec->pts = *zone; + + debug = FT_BOOL( !( loader->load_flags & FT_LOAD_NO_SCALE ) && + ((TT_Size)loader->size)->debug ); + + error = TT_Run_Context( loader->exec, debug ); + if ( error && loader->exec->pedantic_hinting ) + return error; + + /* store drop-out mode in bits 5-7; set bit 2 also as a marker */ + current_outline.tags[0] |= + ( loader->exec->GS.scan_type << 5 ) | FT_CURVE_TAG_HAS_SCANMODE; + } + +#endif + + /* save glyph phantom points */ + if ( !loader->preserve_pps ) + { + loader->pp1 = zone->cur[zone->n_points - 4]; + loader->pp2 = zone->cur[zone->n_points - 3]; + loader->pp3 = zone->cur[zone->n_points - 2]; + loader->pp4 = zone->cur[zone->n_points - 1]; + } + + return TT_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* TT_Process_Simple_Glyph */ + /* */ + /* <Description> */ + /* Once a simple glyph has been loaded, it needs to be processed. */ + /* Usually, this means scaling and hinting through bytecode */ + /* interpretation. */ + /* */ + static FT_Error + TT_Process_Simple_Glyph( TT_Loader loader ) + { + FT_GlyphLoader gloader = loader->gloader; + FT_Error error = TT_Err_Ok; + FT_Outline* outline; + FT_Int n_points; + + + outline = &gloader->current.outline; + n_points = outline->n_points; + + /* set phantom points */ + + outline->points[n_points ] = loader->pp1; + outline->points[n_points + 1] = loader->pp2; + outline->points[n_points + 2] = loader->pp3; + outline->points[n_points + 3] = loader->pp4; + + outline->tags[n_points ] = 0; + outline->tags[n_points + 1] = 0; + outline->tags[n_points + 2] = 0; + outline->tags[n_points + 3] = 0; + + n_points += 4; + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + + if ( ((TT_Face)loader->face)->doblend ) + { + /* Deltas apply to the unscaled data. */ + FT_Vector* deltas; + FT_Memory memory = loader->face->memory; + FT_Int i; + + + error = TT_Vary_Get_Glyph_Deltas( (TT_Face)(loader->face), + loader->glyph_index, + &deltas, + n_points ); + if ( error ) + return error; + + for ( i = 0; i < n_points; ++i ) + { + outline->points[i].x += deltas[i].x; + outline->points[i].y += deltas[i].y; + } + + FT_FREE( deltas ); + } + +#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ + + if ( IS_HINTED( loader->load_flags ) ) + { + tt_prepare_zone( &loader->zone, &gloader->current, 0, 0 ); + + FT_ARRAY_COPY( loader->zone.orus, loader->zone.cur, + loader->zone.n_points + 4 ); + } + + /* scale the glyph */ + if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) + { + FT_Vector* vec = outline->points; + FT_Vector* limit = outline->points + n_points; + FT_Fixed x_scale = ((TT_Size)loader->size)->metrics.x_scale; + FT_Fixed y_scale = ((TT_Size)loader->size)->metrics.y_scale; + + + for ( ; vec < limit; vec++ ) + { + vec->x = FT_MulFix( vec->x, x_scale ); + vec->y = FT_MulFix( vec->y, y_scale ); + } + + loader->pp1 = outline->points[n_points - 4]; + loader->pp2 = outline->points[n_points - 3]; + loader->pp3 = outline->points[n_points - 2]; + loader->pp4 = outline->points[n_points - 1]; + } + + if ( IS_HINTED( loader->load_flags ) ) + { + loader->zone.n_points += 4; + + error = TT_Hint_Glyph( loader, 0 ); + } + + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* TT_Process_Composite_Component */ + /* */ + /* <Description> */ + /* Once a composite component has been loaded, it needs to be */ + /* processed. Usually, this means transforming and translating. */ + /* */ + static FT_Error + TT_Process_Composite_Component( TT_Loader loader, + FT_SubGlyph subglyph, + FT_UInt start_point, + FT_UInt num_base_points ) + { + FT_GlyphLoader gloader = loader->gloader; + FT_Vector* base_vec = gloader->base.outline.points; + FT_UInt num_points = gloader->base.outline.n_points; + FT_Bool have_scale; + FT_Pos x, y; + + + have_scale = FT_BOOL( subglyph->flags & ( WE_HAVE_A_SCALE | + WE_HAVE_AN_XY_SCALE | + WE_HAVE_A_2X2 ) ); + + /* perform the transform required for this subglyph */ + if ( have_scale ) + { + FT_UInt i; + + + for ( i = num_base_points; i < num_points; i++ ) + FT_Vector_Transform( base_vec + i, &subglyph->transform ); + } + + /* get offset */ + if ( !( subglyph->flags & ARGS_ARE_XY_VALUES ) ) + { + FT_UInt k = subglyph->arg1; + FT_UInt l = subglyph->arg2; + FT_Vector* p1; + FT_Vector* p2; + + + /* match l-th point of the newly loaded component to the k-th point */ + /* of the previously loaded components. */ + + /* change to the point numbers used by our outline */ + k += start_point; + l += num_base_points; + if ( k >= num_base_points || + l >= num_points ) + return TT_Err_Invalid_Composite; + + p1 = gloader->base.outline.points + k; + p2 = gloader->base.outline.points + l; + + x = p1->x - p2->x; + y = p1->y - p2->y; + } + else + { + x = subglyph->arg1; + y = subglyph->arg2; + + if ( !x && !y ) + return TT_Err_Ok; + + /* Use a default value dependent on */ + /* TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED. This is useful for old TT */ + /* fonts which don't set the xxx_COMPONENT_OFFSET bit. */ + + if ( have_scale && +#ifdef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED + !( subglyph->flags & UNSCALED_COMPONENT_OFFSET ) ) +#else + ( subglyph->flags & SCALED_COMPONENT_OFFSET ) ) +#endif + { + +#if 0 + + /*************************************************************************/ + /* */ + /* This algorithm is what Apple documents. But it doesn't work. */ + /* */ + int a = subglyph->transform.xx > 0 ? subglyph->transform.xx + : -subglyph->transform.xx; + int b = subglyph->transform.yx > 0 ? subglyph->transform.yx + : -subglyph->transform.yx; + int c = subglyph->transform.xy > 0 ? subglyph->transform.xy + : -subglyph->transform.xy; + int d = subglyph->transform.yy > 0 ? subglyph->transform.yy + : -subglyph->transform.yy; + int m = a > b ? a : b; + int n = c > d ? c : d; + + + if ( a - b <= 33 && a - b >= -33 ) + m *= 2; + if ( c - d <= 33 && c - d >= -33 ) + n *= 2; + x = FT_MulFix( x, m ); + y = FT_MulFix( y, n ); + +#else /* 0 */ + + /*************************************************************************/ + /* */ + /* This algorithm is a guess and works much better than the above. */ + /* */ + FT_Fixed mac_xscale = FT_SqrtFixed( + (FT_Int32)FT_MulFix( subglyph->transform.xx, + subglyph->transform.xx ) + + (FT_Int32)FT_MulFix( subglyph->transform.xy, + subglyph->transform.xy ) ); + FT_Fixed mac_yscale = FT_SqrtFixed( + (FT_Int32)FT_MulFix( subglyph->transform.yy, + subglyph->transform.yy ) + + (FT_Int32)FT_MulFix( subglyph->transform.yx, + subglyph->transform.yx ) ); + + + x = FT_MulFix( x, mac_xscale ); + y = FT_MulFix( y, mac_yscale ); + +#endif /* 0 */ + + } + + if ( !( loader->load_flags & FT_LOAD_NO_SCALE ) ) + { + FT_Fixed x_scale = ((TT_Size)loader->size)->metrics.x_scale; + FT_Fixed y_scale = ((TT_Size)loader->size)->metrics.y_scale; + + + x = FT_MulFix( x, x_scale ); + y = FT_MulFix( y, y_scale ); + + if ( subglyph->flags & ROUND_XY_TO_GRID ) + { + x = FT_PIX_ROUND( x ); + y = FT_PIX_ROUND( y ); + } + } + } + + if ( x || y ) + translate_array( num_points - num_base_points, + base_vec + num_base_points, + x, y ); + + return TT_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* TT_Process_Composite_Glyph */ + /* */ + /* <Description> */ + /* This is slightly different from TT_Process_Simple_Glyph, in that */ + /* its sole purpose is to hint the glyph. Thus this function is */ + /* only available when bytecode interpreter is enabled. */ + /* */ + static FT_Error + TT_Process_Composite_Glyph( TT_Loader loader, + FT_UInt start_point, + FT_UInt start_contour ) + { + FT_Error error; + FT_Outline* outline; + FT_UInt i; + + + outline = &loader->gloader->base.outline; + + /* make room for phantom points */ + error = FT_GLYPHLOADER_CHECK_POINTS( loader->gloader, + outline->n_points + 4, + 0 ); + if ( error ) + return error; + + outline->points[outline->n_points ] = loader->pp1; + outline->points[outline->n_points + 1] = loader->pp2; + outline->points[outline->n_points + 2] = loader->pp3; + outline->points[outline->n_points + 3] = loader->pp4; + + outline->tags[outline->n_points ] = 0; + outline->tags[outline->n_points + 1] = 0; + outline->tags[outline->n_points + 2] = 0; + outline->tags[outline->n_points + 3] = 0; + +#ifdef TT_USE_BYTECODE_INTERPRETER + + { + FT_Stream stream = loader->stream; + FT_UShort n_ins; + + + /* TT_Load_Composite_Glyph only gives us the offset of instructions */ + /* so we read them here */ + if ( FT_STREAM_SEEK( loader->ins_pos ) || + FT_READ_USHORT( n_ins ) ) + return error; + + FT_TRACE5(( " Instructions size = %d\n", n_ins )); + + /* check it */ + if ( n_ins > ((TT_Face)loader->face)->max_profile.maxSizeOfInstructions ) + { + FT_TRACE0(( "TT_Process_Composite_Glyph: too many instructions (%d)\n", + n_ins )); + + return TT_Err_Too_Many_Hints; + } + else if ( n_ins == 0 ) + return TT_Err_Ok; + + if ( FT_STREAM_READ( loader->exec->glyphIns, n_ins ) ) + return error; + + loader->glyph->control_data = loader->exec->glyphIns; + loader->glyph->control_len = n_ins; + } + +#endif + + tt_prepare_zone( &loader->zone, &loader->gloader->base, + start_point, start_contour ); + + /* Some points are likely touched during execution of */ + /* instructions on components. So let's untouch them. */ + for ( i = start_point; i < loader->zone.n_points; i++ ) + loader->zone.tags[i] &= ~FT_CURVE_TAG_TOUCH_BOTH; + + loader->zone.n_points += 4; + + return TT_Hint_Glyph( loader, 1 ); + } + + + /* Calculate the four phantom points. */ + /* The first two stand for horizontal origin and advance. */ + /* The last two stand for vertical origin and advance. */ +#define TT_LOADER_SET_PP( loader ) \ + do { \ + (loader)->pp1.x = (loader)->bbox.xMin - (loader)->left_bearing; \ + (loader)->pp1.y = 0; \ + (loader)->pp2.x = (loader)->pp1.x + (loader)->advance; \ + (loader)->pp2.y = 0; \ + (loader)->pp3.x = 0; \ + (loader)->pp3.y = (loader)->top_bearing + (loader)->bbox.yMax; \ + (loader)->pp4.x = 0; \ + (loader)->pp4.y = (loader)->pp3.y - (loader)->vadvance; \ + } while ( 0 ) + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* load_truetype_glyph */ + /* */ + /* <Description> */ + /* Loads a given truetype glyph. Handles composites and uses a */ + /* TT_Loader object. */ + /* */ + static FT_Error + load_truetype_glyph( TT_Loader loader, + FT_UInt glyph_index, + FT_UInt recurse_count ) + { + FT_Error error; + FT_Fixed x_scale, y_scale; + FT_ULong offset; + TT_Face face = (TT_Face)loader->face; + FT_GlyphLoader gloader = loader->gloader; + FT_Bool opened_frame = 0; + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + FT_Vector* deltas = NULL; +#endif + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + FT_StreamRec inc_stream; + FT_Data glyph_data; + FT_Bool glyph_data_loaded = 0; +#endif + + + /* some fonts have an incorrect value of `maxComponentDepth', */ + /* thus we allow depth 1 to catch the majority of them */ + if ( recurse_count > 1 && + recurse_count > face->max_profile.maxComponentDepth ) + { + error = TT_Err_Invalid_Composite; + goto Exit; + } + + /* check glyph index */ + if ( glyph_index >= (FT_UInt)face->root.num_glyphs ) + { + error = TT_Err_Invalid_Glyph_Index; + goto Exit; + } + + loader->glyph_index = glyph_index; + + if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) + { + x_scale = ((TT_Size)loader->size)->metrics.x_scale; + y_scale = ((TT_Size)loader->size)->metrics.y_scale; + } + else + { + x_scale = 0x10000L; + y_scale = 0x10000L; + } + + /* get metrics, horizontal and vertical */ + { + FT_Short left_bearing = 0, top_bearing = 0; + FT_UShort advance_width = 0, advance_height = 0; + + + TT_Get_HMetrics( face, glyph_index, + (FT_Bool)!( loader->load_flags & + FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ), + &left_bearing, + &advance_width ); + TT_Get_VMetrics( face, glyph_index, + (FT_Bool)!( loader->load_flags & + FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ), + &top_bearing, + &advance_height ); + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + + /* If this is an incrementally loaded font see if there are */ + /* overriding metrics for this glyph. */ + if ( face->root.internal->incremental_interface && + face->root.internal->incremental_interface->funcs->get_glyph_metrics ) + { + FT_Incremental_MetricsRec metrics; + + + metrics.bearing_x = left_bearing; + metrics.bearing_y = 0; + metrics.advance = advance_width; + error = face->root.internal->incremental_interface->funcs->get_glyph_metrics( + face->root.internal->incremental_interface->object, + glyph_index, FALSE, &metrics ); + if ( error ) + goto Exit; + left_bearing = (FT_Short)metrics.bearing_x; + advance_width = (FT_UShort)metrics.advance; + +#if 0 + + /* GWW: Do I do the same for vertical metrics? */ + metrics.bearing_x = 0; + metrics.bearing_y = top_bearing; + metrics.advance = advance_height; + error = face->root.internal->incremental_interface->funcs->get_glyph_metrics( + face->root.internal->incremental_interface->object, + glyph_index, TRUE, &metrics ); + if ( error ) + goto Exit; + top_bearing = (FT_Short)metrics.bearing_y; + advance_height = (FT_UShort)metrics.advance; + +#endif /* 0 */ + + } + +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ + + loader->left_bearing = left_bearing; + loader->advance = advance_width; + loader->top_bearing = top_bearing; + loader->vadvance = advance_height; + + if ( !loader->linear_def ) + { + loader->linear_def = 1; + loader->linear = advance_width; + } + } + + /* Set `offset' to the start of the glyph relative to the start of */ + /* the `glyf' table, and `byte_len' to the length of the glyph in */ + /* bytes. */ + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + + /* If we are loading glyph data via the incremental interface, set */ + /* the loader stream to a memory stream reading the data returned */ + /* by the interface. */ + if ( face->root.internal->incremental_interface ) + { + error = face->root.internal->incremental_interface->funcs->get_glyph_data( + face->root.internal->incremental_interface->object, + glyph_index, &glyph_data ); + if ( error ) + goto Exit; + + glyph_data_loaded = 1; + offset = 0; + loader->byte_len = glyph_data.length; + + FT_MEM_ZERO( &inc_stream, sizeof ( inc_stream ) ); + FT_Stream_OpenMemory( &inc_stream, + glyph_data.pointer, glyph_data.length ); + + loader->stream = &inc_stream; + } + else + +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ + + offset = tt_face_get_location( face, glyph_index, + (FT_UInt*)&loader->byte_len ); + + if ( loader->byte_len > 0 ) + { + if ( !loader->glyf_offset ) + { + FT_TRACE2(( "no `glyf' table but non-zero `loca' entry\n" )); + error = TT_Err_Invalid_Table; + goto Exit; + } + + error = face->access_glyph_frame( loader, glyph_index, + loader->glyf_offset + offset, + loader->byte_len ); + if ( error ) + goto Exit; + + opened_frame = 1; + + /* read first glyph header */ + error = face->read_glyph_header( loader ); + if ( error ) + goto Exit; + } + + if ( loader->byte_len == 0 || loader->n_contours == 0 ) + { + loader->bbox.xMin = 0; + loader->bbox.xMax = 0; + loader->bbox.yMin = 0; + loader->bbox.yMax = 0; + + TT_LOADER_SET_PP( loader ); + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + + if ( ((TT_Face)(loader->face))->doblend ) + { + /* this must be done before scaling */ + FT_Memory memory = loader->face->memory; + + + error = TT_Vary_Get_Glyph_Deltas( (TT_Face)(loader->face), + glyph_index, &deltas, 4 ); + if ( error ) + goto Exit; + + loader->pp1.x += deltas[0].x; loader->pp1.y += deltas[0].y; + loader->pp2.x += deltas[1].x; loader->pp2.y += deltas[1].y; + loader->pp3.x += deltas[2].x; loader->pp3.y += deltas[2].y; + loader->pp4.x += deltas[3].x; loader->pp4.y += deltas[3].y; + + FT_FREE( deltas ); + } + +#endif + + if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) + { + loader->pp1.x = FT_MulFix( loader->pp1.x, x_scale ); + loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale ); + loader->pp3.y = FT_MulFix( loader->pp3.y, y_scale ); + loader->pp4.y = FT_MulFix( loader->pp4.y, y_scale ); + } + + error = TT_Err_Ok; + goto Exit; + } + + TT_LOADER_SET_PP( loader ); + + /***********************************************************************/ + /***********************************************************************/ + /***********************************************************************/ + + /* if it is a simple glyph, load it */ + + if ( loader->n_contours > 0 ) + { + error = face->read_simple_glyph( loader ); + if ( error ) + goto Exit; + + /* all data have been read */ + face->forget_glyph_frame( loader ); + opened_frame = 0; + + error = TT_Process_Simple_Glyph( loader ); + if ( error ) + goto Exit; + + FT_GlyphLoader_Add( gloader ); + } + + /***********************************************************************/ + /***********************************************************************/ + /***********************************************************************/ + + /* otherwise, load a composite! */ + else if ( loader->n_contours == -1 ) + { + FT_UInt start_point; + FT_UInt start_contour; + FT_ULong ins_pos; /* position of composite instructions, if any */ + + + start_point = gloader->base.outline.n_points; + start_contour = gloader->base.outline.n_contours; + + /* for each subglyph, read composite header */ + error = face->read_composite_glyph( loader ); + if ( error ) + goto Exit; + + /* store the offset of instructions */ + ins_pos = loader->ins_pos; + + /* all data we need are read */ + face->forget_glyph_frame( loader ); + opened_frame = 0; + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + + if ( face->doblend ) + { + FT_Int i, limit; + FT_SubGlyph subglyph; + FT_Memory memory = face->root.memory; + + + /* this provides additional offsets */ + /* for each component's translation */ + + if ( ( error = TT_Vary_Get_Glyph_Deltas( + face, + glyph_index, + &deltas, + gloader->current.num_subglyphs + 4 )) != 0 ) + goto Exit; + + subglyph = gloader->current.subglyphs + gloader->base.num_subglyphs; + limit = gloader->current.num_subglyphs; + + for ( i = 0; i < limit; ++i, ++subglyph ) + { + if ( subglyph->flags & ARGS_ARE_XY_VALUES ) + { + /* XXX: overflow check for subglyph->{arg1,arg2}. */ + /* deltas[i].{x,y} must be within signed 16-bit, */ + /* but the restriction of summed delta is not clear */ + subglyph->arg1 += (FT_Int16)deltas[i].x; + subglyph->arg2 += (FT_Int16)deltas[i].y; + } + } + + loader->pp1.x += deltas[i + 0].x; loader->pp1.y += deltas[i + 0].y; + loader->pp2.x += deltas[i + 1].x; loader->pp2.y += deltas[i + 1].y; + loader->pp3.x += deltas[i + 2].x; loader->pp3.y += deltas[i + 2].y; + loader->pp4.x += deltas[i + 3].x; loader->pp4.y += deltas[i + 3].y; + + FT_FREE( deltas ); + } + +#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ + + if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) + { + loader->pp1.x = FT_MulFix( loader->pp1.x, x_scale ); + loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale ); + loader->pp3.y = FT_MulFix( loader->pp3.y, y_scale ); + loader->pp4.y = FT_MulFix( loader->pp4.y, y_scale ); + } + + /* if the flag FT_LOAD_NO_RECURSE is set, we return the subglyph */ + /* `as is' in the glyph slot (the client application will be */ + /* responsible for interpreting these data)... */ + if ( loader->load_flags & FT_LOAD_NO_RECURSE ) + { + FT_GlyphLoader_Add( gloader ); + loader->glyph->format = FT_GLYPH_FORMAT_COMPOSITE; + + goto Exit; + } + + /*********************************************************************/ + /*********************************************************************/ + /*********************************************************************/ + + { + FT_UInt n, num_base_points; + FT_SubGlyph subglyph = 0; + + FT_UInt num_points = start_point; + FT_UInt num_subglyphs = gloader->current.num_subglyphs; + FT_UInt num_base_subgs = gloader->base.num_subglyphs; + + FT_Stream old_stream = loader->stream; + + + FT_GlyphLoader_Add( gloader ); + + /* read each subglyph independently */ + for ( n = 0; n < num_subglyphs; n++ ) + { + FT_Vector pp[4]; + + + /* Each time we call load_truetype_glyph in this loop, the */ + /* value of `gloader.base.subglyphs' can change due to table */ + /* reallocations. We thus need to recompute the subglyph */ + /* pointer on each iteration. */ + subglyph = gloader->base.subglyphs + num_base_subgs + n; + + pp[0] = loader->pp1; + pp[1] = loader->pp2; + pp[2] = loader->pp3; + pp[3] = loader->pp4; + + num_base_points = gloader->base.outline.n_points; + + error = load_truetype_glyph( loader, subglyph->index, + recurse_count + 1 ); + if ( error ) + goto Exit; + + /* restore subglyph pointer */ + subglyph = gloader->base.subglyphs + num_base_subgs + n; + + if ( !( subglyph->flags & USE_MY_METRICS ) ) + { + loader->pp1 = pp[0]; + loader->pp2 = pp[1]; + loader->pp3 = pp[2]; + loader->pp4 = pp[3]; + } + + num_points = gloader->base.outline.n_points; + + if ( num_points == num_base_points ) + continue; + + /* gloader->base.outline consists of three parts: */ + /* 0 -(1)-> start_point -(2)-> num_base_points -(3)-> n_points. */ + /* */ + /* (1): exists from the beginning */ + /* (2): components that have been loaded so far */ + /* (3): the newly loaded component */ + TT_Process_Composite_Component( loader, subglyph, start_point, + num_base_points ); + } + + loader->stream = old_stream; + + /* process the glyph */ + loader->ins_pos = ins_pos; + if ( IS_HINTED( loader->load_flags ) && + +#ifdef TT_USE_BYTECODE_INTERPRETER + + subglyph->flags & WE_HAVE_INSTR && + +#endif + + num_points > start_point ) + TT_Process_Composite_Glyph( loader, start_point, start_contour ); + + } + } + else + { + /* invalid composite count (negative but not -1) */ + error = TT_Err_Invalid_Outline; + goto Exit; + } + + /***********************************************************************/ + /***********************************************************************/ + /***********************************************************************/ + + Exit: + + if ( opened_frame ) + face->forget_glyph_frame( loader ); + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + + if ( glyph_data_loaded ) + face->root.internal->incremental_interface->funcs->free_glyph_data( + face->root.internal->incremental_interface->object, + &glyph_data ); + +#endif + + return error; + } + + + static FT_Error + compute_glyph_metrics( TT_Loader loader, + FT_UInt glyph_index ) + { + FT_BBox bbox; + TT_Face face = (TT_Face)loader->face; + FT_Fixed y_scale; + TT_GlyphSlot glyph = loader->glyph; + TT_Size size = (TT_Size)loader->size; + + + y_scale = 0x10000L; + if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) + y_scale = size->root.metrics.y_scale; + + if ( glyph->format != FT_GLYPH_FORMAT_COMPOSITE ) + FT_Outline_Get_CBox( &glyph->outline, &bbox ); + else + bbox = loader->bbox; + + /* get the device-independent horizontal advance; it is scaled later */ + /* by the base layer. */ + { + FT_Pos advance = loader->linear; + + + /* the flag FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH was introduced to */ + /* correctly support DynaLab fonts, which have an incorrect */ + /* `advance_Width_Max' field! It is used, to my knowledge, */ + /* exclusively in the X-TrueType font server. */ + /* */ + if ( face->postscript.isFixedPitch && + ( loader->load_flags & FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ) == 0 ) + advance = face->horizontal.advance_Width_Max; + + /* we need to return the advance in font units in linearHoriAdvance, */ + /* it will be scaled later by the base layer. */ + glyph->linearHoriAdvance = advance; + } + + glyph->metrics.horiBearingX = bbox.xMin; + glyph->metrics.horiBearingY = bbox.yMax; + glyph->metrics.horiAdvance = loader->pp2.x - loader->pp1.x; + + /* adjust advance width to the value contained in the hdmx table */ + if ( !face->postscript.isFixedPitch && + IS_HINTED( loader->load_flags ) ) + { + FT_Byte* widthp; + + + widthp = tt_face_get_device_metrics( face, + size->root.metrics.x_ppem, + glyph_index ); + + if ( widthp ) + glyph->metrics.horiAdvance = *widthp << 6; + } + + /* set glyph dimensions */ + glyph->metrics.width = bbox.xMax - bbox.xMin; + glyph->metrics.height = bbox.yMax - bbox.yMin; + + /* Now take care of vertical metrics. In the case where there is */ + /* no vertical information within the font (relatively common), */ + /* create some metrics manually */ + { + FT_Pos top; /* scaled vertical top side bearing */ + FT_Pos advance; /* scaled vertical advance height */ + + + /* Get the unscaled top bearing and advance height. */ + if ( face->vertical_info && + face->vertical.number_Of_VMetrics > 0 ) + { + top = (FT_Short)FT_DivFix( loader->pp3.y - bbox.yMax, + y_scale ); + + if ( loader->pp3.y <= loader->pp4.y ) + advance = 0; + else + advance = (FT_UShort)FT_DivFix( loader->pp3.y - loader->pp4.y, + y_scale ); + } + else + { + FT_Pos height; + + + /* XXX Compute top side bearing and advance height in */ + /* Get_VMetrics instead of here. */ + + /* NOTE: The OS/2 values are the only `portable' ones, */ + /* which is why we use them, if there is an OS/2 */ + /* table in the font. Otherwise, we use the */ + /* values defined in the horizontal header. */ + + height = (FT_Short)FT_DivFix( bbox.yMax - bbox.yMin, + y_scale ); + if ( face->os2.version != 0xFFFFU ) + advance = (FT_Pos)( face->os2.sTypoAscender - + face->os2.sTypoDescender ); + else + advance = (FT_Pos)( face->horizontal.Ascender - + face->horizontal.Descender ); + + top = ( advance - height ) / 2; + } + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + { + FT_Incremental_InterfaceRec* incr; + FT_Incremental_MetricsRec metrics; + FT_Error error; + + + incr = face->root.internal->incremental_interface; + + /* If this is an incrementally loaded font see if there are */ + /* overriding metrics for this glyph. */ + if ( incr && incr->funcs->get_glyph_metrics ) + { + metrics.bearing_x = 0; + metrics.bearing_y = top; + metrics.advance = advance; + + error = incr->funcs->get_glyph_metrics( incr->object, + glyph_index, + TRUE, + &metrics ); + if ( error ) + return error; + + top = metrics.bearing_y; + advance = metrics.advance; + } + } + + /* GWW: Do vertical metrics get loaded incrementally too? */ + +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ + + glyph->linearVertAdvance = advance; + + /* scale the metrics */ + if ( !( loader->load_flags & FT_LOAD_NO_SCALE ) ) + { + top = FT_MulFix( top, y_scale ); + advance = FT_MulFix( advance, y_scale ); + } + + /* XXX: for now, we have no better algorithm for the lsb, but it */ + /* should work fine. */ + /* */ + glyph->metrics.vertBearingX = glyph->metrics.horiBearingX - + glyph->metrics.horiAdvance / 2; + glyph->metrics.vertBearingY = top; + glyph->metrics.vertAdvance = advance; + } + + return 0; + } + + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + + static FT_Error + load_sbit_image( TT_Size size, + TT_GlyphSlot glyph, + FT_UInt glyph_index, + FT_Int32 load_flags ) + { + TT_Face face; + SFNT_Service sfnt; + FT_Stream stream; + FT_Error error; + TT_SBit_MetricsRec metrics; + + + face = (TT_Face)glyph->face; + sfnt = (SFNT_Service)face->sfnt; + stream = face->root.stream; + + error = sfnt->load_sbit_image( face, + size->strike_index, + glyph_index, + (FT_Int)load_flags, + stream, + &glyph->bitmap, + &metrics ); + if ( !error ) + { + glyph->outline.n_points = 0; + glyph->outline.n_contours = 0; + + glyph->metrics.width = (FT_Pos)metrics.width << 6; + glyph->metrics.height = (FT_Pos)metrics.height << 6; + + glyph->metrics.horiBearingX = (FT_Pos)metrics.horiBearingX << 6; + glyph->metrics.horiBearingY = (FT_Pos)metrics.horiBearingY << 6; + glyph->metrics.horiAdvance = (FT_Pos)metrics.horiAdvance << 6; + + glyph->metrics.vertBearingX = (FT_Pos)metrics.vertBearingX << 6; + glyph->metrics.vertBearingY = (FT_Pos)metrics.vertBearingY << 6; + glyph->metrics.vertAdvance = (FT_Pos)metrics.vertAdvance << 6; + + glyph->format = FT_GLYPH_FORMAT_BITMAP; + if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) + { + glyph->bitmap_left = metrics.vertBearingX; + glyph->bitmap_top = metrics.vertBearingY; + } + else + { + glyph->bitmap_left = metrics.horiBearingX; + glyph->bitmap_top = metrics.horiBearingY; + } + } + + return error; + } + +#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ + + + static FT_Error + tt_loader_init( TT_Loader loader, + TT_Size size, + TT_GlyphSlot glyph, + FT_Int32 load_flags ) + { + TT_Face face; + FT_Stream stream; + + + face = (TT_Face)glyph->face; + stream = face->root.stream; + + FT_MEM_ZERO( loader, sizeof ( TT_LoaderRec ) ); + +#ifdef TT_USE_BYTECODE_INTERPRETER + + /* load execution context */ + if ( IS_HINTED( load_flags ) ) + { + TT_ExecContext exec; + FT_Bool grayscale; + + + if ( !size->cvt_ready ) + { + FT_Error error = tt_size_ready_bytecode( size ); + if ( error ) + return error; + } + + /* query new execution context */ + exec = size->debug ? size->context + : ( (TT_Driver)FT_FACE_DRIVER( face ) )->context; + if ( !exec ) + return TT_Err_Could_Not_Find_Context; + + grayscale = + FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != FT_RENDER_MODE_MONO ); + + TT_Load_Context( exec, face, size ); + + /* a change from mono to grayscale rendering (and vice versa) */ + /* requires a re-execution of the CVT program */ + if ( grayscale != exec->grayscale ) + { + FT_UInt i; + + + exec->grayscale = grayscale; + + for ( i = 0; i < size->cvt_size; i++ ) + size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale ); + tt_size_run_prep( size ); + } + + /* see whether the cvt program has disabled hinting */ + if ( exec->GS.instruct_control & 1 ) + load_flags |= FT_LOAD_NO_HINTING; + + /* load default graphics state -- if needed */ + if ( exec->GS.instruct_control & 2 ) + exec->GS = tt_default_graphics_state; + + exec->pedantic_hinting = FT_BOOL( load_flags & FT_LOAD_PEDANTIC ); + loader->exec = exec; + loader->instructions = exec->glyphIns; + } + +#endif /* TT_USE_BYTECODE_INTERPRETER */ + + /* seek to the beginning of the glyph table -- for Type 42 fonts */ + /* the table might be accessed from a Postscript stream or something */ + /* else... */ + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + + if ( face->root.internal->incremental_interface ) + loader->glyf_offset = 0; + else + +#endif + + { + FT_Error error = face->goto_table( face, TTAG_glyf, stream, 0 ); + + + if ( error == TT_Err_Table_Missing ) + loader->glyf_offset = 0; + else if ( error ) + { + FT_ERROR(( "tt_loader_init: could not access glyph table\n" )); + return error; + } + else + loader->glyf_offset = FT_STREAM_POS(); + } + + /* get face's glyph loader */ + { + FT_GlyphLoader gloader = glyph->internal->loader; + + + FT_GlyphLoader_Rewind( gloader ); + loader->gloader = gloader; + } + + loader->load_flags = load_flags; + + loader->face = (FT_Face)face; + loader->size = (FT_Size)size; + loader->glyph = (FT_GlyphSlot)glyph; + loader->stream = stream; + + return TT_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* TT_Load_Glyph */ + /* */ + /* <Description> */ + /* A function used to load a single glyph within a given glyph slot, */ + /* for a given size. */ + /* */ + /* <Input> */ + /* glyph :: A handle to a target slot object where the glyph */ + /* will be loaded. */ + /* */ + /* size :: A handle to the source face size at which the glyph */ + /* must be scaled/loaded. */ + /* */ + /* glyph_index :: The index of the glyph in the font file. */ + /* */ + /* load_flags :: A flag indicating what to load for this glyph. The */ + /* FT_LOAD_XXX constants can be used to control the */ + /* glyph loading process (e.g., whether the outline */ + /* should be scaled, whether to load bitmaps or not, */ + /* whether to hint the outline, etc). */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + TT_Load_Glyph( TT_Size size, + TT_GlyphSlot glyph, + FT_UInt glyph_index, + FT_Int32 load_flags ) + { + TT_Face face; + FT_Error error; + TT_LoaderRec loader; + + + face = (TT_Face)glyph->face; + error = TT_Err_Ok; + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + + /* try to load embedded bitmap if any */ + /* */ + /* XXX: The convention should be emphasized in */ + /* the documents because it can be confusing. */ + if ( size->strike_index != 0xFFFFFFFFUL && + ( load_flags & FT_LOAD_NO_BITMAP ) == 0 ) + { + error = load_sbit_image( size, glyph, glyph_index, load_flags ); + if ( !error ) + return TT_Err_Ok; + } + +#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ + + /* if FT_LOAD_NO_SCALE is not set, `ttmetrics' must be valid */ + if ( !( load_flags & FT_LOAD_NO_SCALE ) && !size->ttmetrics.valid ) + return TT_Err_Invalid_Size_Handle; + + if ( load_flags & FT_LOAD_SBITS_ONLY ) + return TT_Err_Invalid_Argument; + + error = tt_loader_init( &loader, size, glyph, load_flags ); + if ( error ) + return error; + + glyph->format = FT_GLYPH_FORMAT_OUTLINE; + glyph->num_subglyphs = 0; + glyph->outline.flags = 0; + + /* main loading loop */ + error = load_truetype_glyph( &loader, glyph_index, 0 ); + if ( !error ) + { + if ( glyph->format == FT_GLYPH_FORMAT_COMPOSITE ) + { + glyph->num_subglyphs = loader.gloader->base.num_subglyphs; + glyph->subglyphs = loader.gloader->base.subglyphs; + } + else + { + glyph->outline = loader.gloader->base.outline; + glyph->outline.flags &= ~FT_OUTLINE_SINGLE_PASS; + + /* In case bit 1 of the `flags' field in the `head' table isn't */ + /* set, translate array so that (0,0) is the glyph's origin. */ + if ( ( face->header.Flags & 2 ) == 0 && loader.pp1.x ) + FT_Outline_Translate( &glyph->outline, -loader.pp1.x, 0 ); + } + +#ifdef TT_USE_BYTECODE_INTERPRETER + + if ( IS_HINTED( load_flags ) ) + { + if ( loader.exec->GS.scan_control ) + { + /* convert scan conversion mode to FT_OUTLINE_XXX flags */ + switch ( loader.exec->GS.scan_type ) + { + case 0: /* simple drop-outs including stubs */ + glyph->outline.flags |= FT_OUTLINE_INCLUDE_STUBS; + break; + case 1: /* simple drop-outs excluding stubs */ + /* nothing; it's the default rendering mode */ + break; + case 4: /* smart drop-outs including stubs */ + glyph->outline.flags |= FT_OUTLINE_SMART_DROPOUTS | + FT_OUTLINE_INCLUDE_STUBS; + break; + case 5: /* smart drop-outs excluding stubs */ + glyph->outline.flags |= FT_OUTLINE_SMART_DROPOUTS; + break; + + default: /* no drop-out control */ + glyph->outline.flags |= FT_OUTLINE_IGNORE_DROPOUTS; + break; + } + } + else + glyph->outline.flags |= FT_OUTLINE_IGNORE_DROPOUTS; + } + +#endif /* TT_USE_BYTECODE_INTERPRETER */ + + compute_glyph_metrics( &loader, glyph_index ); + } + + /* Set the `high precision' bit flag. */ + /* This is _critical_ to get correct output for monochrome */ + /* TrueType glyphs at all sizes using the bytecode interpreter. */ + /* */ + if ( !( load_flags & FT_LOAD_NO_SCALE ) && + size->root.metrics.y_ppem < 24 ) + glyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION; + + return error; + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/truetype/ttgload.h b/mod/pub.mod/freetype.mod/src/truetype/ttgload.h new file mode 100644 index 0000000..958d67d --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/truetype/ttgload.h @@ -0,0 +1,63 @@ +/***************************************************************************/ +/* */ +/* ttgload.h */ +/* */ +/* TrueType Glyph Loader (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __TTGLOAD_H__ +#define __TTGLOAD_H__ + + +#include <ft2build.h> +#include "ttobjs.h" + +#ifdef TT_USE_BYTECODE_INTERPRETER +#include "ttinterp.h" +#endif + + +FT_BEGIN_HEADER + + + FT_LOCAL( void ) + TT_Init_Glyph_Loading( TT_Face face ); + + FT_LOCAL( void ) + TT_Get_HMetrics( TT_Face face, + FT_UInt idx, + FT_Bool check, + FT_Short* lsb, + FT_UShort* aw ); + + FT_LOCAL( void ) + TT_Get_VMetrics( TT_Face face, + FT_UInt idx, + FT_Bool check, + FT_Short* tsb, + FT_UShort* ah ); + + FT_LOCAL( FT_Error ) + TT_Load_Glyph( TT_Size size, + TT_GlyphSlot glyph, + FT_UInt glyph_index, + FT_Int32 load_flags ); + + +FT_END_HEADER + +#endif /* __TTGLOAD_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/truetype/ttgxvar.c b/mod/pub.mod/freetype.mod/src/truetype/ttgxvar.c new file mode 100644 index 0000000..1456a8c --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/truetype/ttgxvar.c @@ -0,0 +1,1547 @@ +/***************************************************************************/ +/* */ +/* ttgxvar.c */ +/* */ +/* TrueType GX Font Variation loader */ +/* */ +/* Copyright 2004, 2005, 2006, 2007, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, Werner Lemberg, and George Williams. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* Apple documents the `fvar', `gvar', `cvar', and `avar' tables at */ + /* */ + /* http://developer.apple.com/fonts/TTRefMan/RM06/Chap6[fgca]var.html */ + /* */ + /* The documentation for `fvar' is inconsistent. At one point it says */ + /* that `countSizePairs' should be 3, at another point 2. It should */ + /* be 2. */ + /* */ + /* The documentation for `gvar' is not intelligible; `cvar' refers you */ + /* to `gvar' and is thus also incomprehensible. */ + /* */ + /* The documentation for `avar' appears correct, but Apple has no fonts */ + /* with an `avar' table, so it is hard to test. */ + /* */ + /* Many thanks to John Jenkins (at Apple) in figuring this out. */ + /* */ + /* */ + /* Apple's `kern' table has some references to tuple indices, but as */ + /* there is no indication where these indices are defined, nor how to */ + /* interpolate the kerning values (different tuples have different */ + /* classes) this issue is ignored. */ + /* */ + /*************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_CONFIG_CONFIG_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_SFNT_H +#include FT_TRUETYPE_TAGS_H +#include FT_MULTIPLE_MASTERS_H + +#include "ttpload.h" +#include "ttgxvar.h" + +#include "tterrors.h" + + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + + +#define FT_Stream_FTell( stream ) \ + ( (stream)->cursor - (stream)->base ) +#define FT_Stream_SeekSet( stream, off ) \ + ( (stream)->cursor = (stream)->base+(off) ) + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_ttgxvar + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** Internal Routines *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* The macro ALL_POINTS is used in `ft_var_readpackedpoints'. It */ + /* indicates that there is a delta for every point without needing to */ + /* enumerate all of them. */ + /* */ +#define ALL_POINTS (FT_UShort*)( -1 ) + + + enum + { + GX_PT_POINTS_ARE_WORDS = 0x80, + GX_PT_POINT_RUN_COUNT_MASK = 0x7F + }; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* ft_var_readpackedpoints */ + /* */ + /* <Description> */ + /* Read a set of points to which the following deltas will apply. */ + /* Points are packed with a run length encoding. */ + /* */ + /* <Input> */ + /* stream :: The data stream. */ + /* */ + /* <Output> */ + /* point_cnt :: The number of points read. A zero value means that */ + /* all points in the glyph will be affected, without */ + /* enumerating them individually. */ + /* */ + /* <Return> */ + /* An array of FT_UShort containing the affected points or the */ + /* special value ALL_POINTS. */ + /* */ + static FT_UShort* + ft_var_readpackedpoints( FT_Stream stream, + FT_UInt *point_cnt ) + { + FT_UShort *points; + FT_Int n; + FT_Int runcnt; + FT_Int i; + FT_Int j; + FT_Int first; + FT_Memory memory = stream->memory; + FT_Error error = TT_Err_Ok; + + FT_UNUSED( error ); + + + *point_cnt = n = FT_GET_BYTE(); + if ( n == 0 ) + return ALL_POINTS; + + if ( n & GX_PT_POINTS_ARE_WORDS ) + n = FT_GET_BYTE() | ( ( n & GX_PT_POINT_RUN_COUNT_MASK ) << 8 ); + + if ( FT_NEW_ARRAY( points, n ) ) + return NULL; + + i = 0; + while ( i < n ) + { + runcnt = FT_GET_BYTE(); + if ( runcnt & GX_PT_POINTS_ARE_WORDS ) + { + runcnt = runcnt & GX_PT_POINT_RUN_COUNT_MASK; + first = points[i++] = FT_GET_USHORT(); + + if ( runcnt < 1 ) + goto Exit; + + /* first point not included in runcount */ + for ( j = 0; j < runcnt; ++j ) + points[i++] = (FT_UShort)( first += FT_GET_USHORT() ); + } + else + { + first = points[i++] = FT_GET_BYTE(); + + if ( runcnt < 1 ) + goto Exit; + + for ( j = 0; j < runcnt; ++j ) + points[i++] = (FT_UShort)( first += FT_GET_BYTE() ); + } + } + + Exit: + return points; + } + + + enum + { + GX_DT_DELTAS_ARE_ZERO = 0x80, + GX_DT_DELTAS_ARE_WORDS = 0x40, + GX_DT_DELTA_RUN_COUNT_MASK = 0x3F + }; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* ft_var_readpackeddeltas */ + /* */ + /* <Description> */ + /* Read a set of deltas. These are packed slightly differently than */ + /* points. In particular there is no overall count. */ + /* */ + /* <Input> */ + /* stream :: The data stream. */ + /* */ + /* delta_cnt :: The number of to be read. */ + /* */ + /* <Return> */ + /* An array of FT_Short containing the deltas for the affected */ + /* points. (This only gets the deltas for one dimension. It will */ + /* generally be called twice, once for x, once for y. When used in */ + /* cvt table, it will only be called once.) */ + /* */ + static FT_Short* + ft_var_readpackeddeltas( FT_Stream stream, + FT_Offset delta_cnt ) + { + FT_Short *deltas; + FT_Int runcnt; + FT_Offset i; + FT_Offset j; + FT_Memory memory = stream->memory; + FT_Error error = TT_Err_Ok; + + FT_UNUSED( error ); + + + if ( FT_NEW_ARRAY( deltas, delta_cnt ) ) + return NULL; + + i = 0; + while ( i < delta_cnt ) + { + runcnt = FT_GET_BYTE(); + if ( runcnt & GX_DT_DELTAS_ARE_ZERO ) + { + /* runcnt zeroes get added */ + for ( j = 0; + j <= ( runcnt & GX_DT_DELTA_RUN_COUNT_MASK ) && i < delta_cnt; + ++j ) + deltas[i++] = 0; + } + else if ( runcnt & GX_DT_DELTAS_ARE_WORDS ) + { + /* runcnt shorts from the stack */ + for ( j = 0; + j <= ( runcnt & GX_DT_DELTA_RUN_COUNT_MASK ) && i < delta_cnt; + ++j ) + deltas[i++] = FT_GET_SHORT(); + } + else + { + /* runcnt signed bytes from the stack */ + for ( j = 0; + j <= ( runcnt & GX_DT_DELTA_RUN_COUNT_MASK ) && i < delta_cnt; + ++j ) + deltas[i++] = FT_GET_CHAR(); + } + + if ( j <= ( runcnt & GX_DT_DELTA_RUN_COUNT_MASK ) ) + { + /* Bad format */ + FT_FREE( deltas ); + return NULL; + } + } + + return deltas; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* ft_var_load_avar */ + /* */ + /* <Description> */ + /* Parse the `avar' table if present. It need not be, so we return */ + /* nothing. */ + /* */ + /* <InOut> */ + /* face :: The font face. */ + /* */ + static void + ft_var_load_avar( TT_Face face ) + { + FT_Stream stream = FT_FACE_STREAM(face); + FT_Memory memory = stream->memory; + GX_Blend blend = face->blend; + GX_AVarSegment segment; + FT_Error error = TT_Err_Ok; + FT_ULong version; + FT_Long axisCount; + FT_Int i, j; + FT_ULong table_len; + + FT_UNUSED( error ); + + + blend->avar_checked = TRUE; + if ( (error = face->goto_table( face, TTAG_avar, stream, &table_len )) != 0 ) + return; + + if ( FT_FRAME_ENTER( table_len ) ) + return; + + version = FT_GET_LONG(); + axisCount = FT_GET_LONG(); + + if ( version != 0x00010000L || + axisCount != (FT_Long)blend->mmvar->num_axis ) + goto Exit; + + if ( FT_NEW_ARRAY( blend->avar_segment, axisCount ) ) + goto Exit; + + segment = &blend->avar_segment[0]; + for ( i = 0; i < axisCount; ++i, ++segment ) + { + segment->pairCount = FT_GET_USHORT(); + if ( FT_NEW_ARRAY( segment->correspondence, segment->pairCount ) ) + { + /* Failure. Free everything we have done so far. We must do */ + /* it right now since loading the `avar' table is optional. */ + + for ( j = i - 1; j >= 0; --j ) + FT_FREE( blend->avar_segment[j].correspondence ); + + FT_FREE( blend->avar_segment ); + blend->avar_segment = NULL; + goto Exit; + } + + for ( j = 0; j < segment->pairCount; ++j ) + { + segment->correspondence[j].fromCoord = + FT_GET_SHORT() << 2; /* convert to Fixed */ + segment->correspondence[j].toCoord = + FT_GET_SHORT()<<2; /* convert to Fixed */ + } + } + + Exit: + FT_FRAME_EXIT(); + } + + + typedef struct GX_GVar_Head_ + { + FT_Long version; + FT_UShort axisCount; + FT_UShort globalCoordCount; + FT_ULong offsetToCoord; + FT_UShort glyphCount; + FT_UShort flags; + FT_ULong offsetToData; + + } GX_GVar_Head; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* ft_var_load_gvar */ + /* */ + /* <Description> */ + /* Parses the `gvar' table if present. If `fvar' is there, `gvar' */ + /* had better be there too. */ + /* */ + /* <InOut> */ + /* face :: The font face. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + static FT_Error + ft_var_load_gvar( TT_Face face ) + { + FT_Stream stream = FT_FACE_STREAM(face); + FT_Memory memory = stream->memory; + GX_Blend blend = face->blend; + FT_Error error; + FT_UInt i, j; + FT_ULong table_len; + FT_ULong gvar_start; + FT_ULong offsetToData; + GX_GVar_Head gvar_head; + + static const FT_Frame_Field gvar_fields[] = + { + +#undef FT_STRUCTURE +#define FT_STRUCTURE GX_GVar_Head + + FT_FRAME_START( 20 ), + FT_FRAME_LONG ( version ), + FT_FRAME_USHORT( axisCount ), + FT_FRAME_USHORT( globalCoordCount ), + FT_FRAME_ULONG ( offsetToCoord ), + FT_FRAME_USHORT( glyphCount ), + FT_FRAME_USHORT( flags ), + FT_FRAME_ULONG ( offsetToData ), + FT_FRAME_END + }; + + if ( (error = face->goto_table( face, TTAG_gvar, stream, &table_len )) != 0 ) + goto Exit; + + gvar_start = FT_STREAM_POS( ); + if ( FT_STREAM_READ_FIELDS( gvar_fields, &gvar_head ) ) + goto Exit; + + blend->tuplecount = gvar_head.globalCoordCount; + blend->gv_glyphcnt = gvar_head.glyphCount; + offsetToData = gvar_start + gvar_head.offsetToData; + + if ( gvar_head.version != (FT_Long)0x00010000L || + gvar_head.axisCount != (FT_UShort)blend->mmvar->num_axis ) + { + error = TT_Err_Invalid_Table; + goto Exit; + } + + if ( FT_NEW_ARRAY( blend->glyphoffsets, blend->gv_glyphcnt + 1 ) ) + goto Exit; + + if ( gvar_head.flags & 1 ) + { + /* long offsets (one more offset than glyphs, to mark size of last) */ + if ( FT_FRAME_ENTER( ( blend->gv_glyphcnt + 1 ) * 4L ) ) + goto Exit; + + for ( i = 0; i <= blend->gv_glyphcnt; ++i ) + blend->glyphoffsets[i] = offsetToData + FT_GET_LONG(); + + FT_FRAME_EXIT(); + } + else + { + /* short offsets (one more offset than glyphs, to mark size of last) */ + if ( FT_FRAME_ENTER( ( blend->gv_glyphcnt + 1 ) * 2L ) ) + goto Exit; + + for ( i = 0; i <= blend->gv_glyphcnt; ++i ) + blend->glyphoffsets[i] = offsetToData + FT_GET_USHORT() * 2; + /* XXX: Undocumented: `*2'! */ + + FT_FRAME_EXIT(); + } + + if ( blend->tuplecount != 0 ) + { + if ( FT_NEW_ARRAY( blend->tuplecoords, + gvar_head.axisCount * blend->tuplecount ) ) + goto Exit; + + if ( FT_STREAM_SEEK( gvar_start + gvar_head.offsetToCoord ) || + FT_FRAME_ENTER( blend->tuplecount * gvar_head.axisCount * 2L ) ) + goto Exit; + + for ( i = 0; i < blend->tuplecount; ++i ) + for ( j = 0 ; j < (FT_UInt)gvar_head.axisCount; ++j ) + blend->tuplecoords[i * gvar_head.axisCount + j] = + FT_GET_SHORT() << 2; /* convert to FT_Fixed */ + + FT_FRAME_EXIT(); + } + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* ft_var_apply_tuple */ + /* */ + /* <Description> */ + /* Figure out whether a given tuple (design) applies to the current */ + /* blend, and if so, what is the scaling factor. */ + /* */ + /* <Input> */ + /* blend :: The current blend of the font. */ + /* */ + /* tupleIndex :: A flag saying whether this is an intermediate */ + /* tuple or not. */ + /* */ + /* tuple_coords :: The coordinates of the tuple in normalized axis */ + /* units. */ + /* */ + /* im_start_coords :: The initial coordinates where this tuple starts */ + /* to apply (for intermediate coordinates). */ + /* */ + /* im_end_coords :: The final coordinates after which this tuple no */ + /* longer applies (for intermediate coordinates). */ + /* */ + /* <Return> */ + /* An FT_Fixed value containing the scaling factor. */ + /* */ + static FT_Fixed + ft_var_apply_tuple( GX_Blend blend, + FT_UShort tupleIndex, + FT_Fixed* tuple_coords, + FT_Fixed* im_start_coords, + FT_Fixed* im_end_coords ) + { + FT_UInt i; + FT_Fixed apply; + FT_Fixed temp; + + + apply = 0x10000L; + for ( i = 0; i < blend->num_axis; ++i ) + { + if ( tuple_coords[i] == 0 ) + /* It's not clear why (for intermediate tuples) we don't need */ + /* to check against start/end -- the documentation says we don't. */ + /* Similarly, it's unclear why we don't need to scale along the */ + /* axis. */ + continue; + + else if ( blend->normalizedcoords[i] == 0 || + ( blend->normalizedcoords[i] < 0 && tuple_coords[i] > 0 ) || + ( blend->normalizedcoords[i] > 0 && tuple_coords[i] < 0 ) ) + { + apply = 0; + break; + } + + else if ( !( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) ) + /* not an intermediate tuple */ + apply = FT_MulDiv( apply, + blend->normalizedcoords[i] > 0 + ? blend->normalizedcoords[i] + : -blend->normalizedcoords[i], + 0x10000L ); + + else if ( blend->normalizedcoords[i] <= im_start_coords[i] || + blend->normalizedcoords[i] >= im_end_coords[i] ) + { + apply = 0; + break; + } + + else if ( blend->normalizedcoords[i] < tuple_coords[i] ) + { + temp = FT_MulDiv( blend->normalizedcoords[i] - im_start_coords[i], + 0x10000L, + tuple_coords[i] - im_start_coords[i]); + apply = FT_MulDiv( apply, temp, 0x10000L ); + } + + else + { + temp = FT_MulDiv( im_end_coords[i] - blend->normalizedcoords[i], + 0x10000L, + im_end_coords[i] - tuple_coords[i] ); + apply = FT_MulDiv( apply, temp, 0x10000L ); + } + } + + return apply; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** MULTIPLE MASTERS SERVICE FUNCTIONS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + typedef struct GX_FVar_Head_ + { + FT_Long version; + FT_UShort offsetToData; + FT_UShort countSizePairs; + FT_UShort axisCount; + FT_UShort axisSize; + FT_UShort instanceCount; + FT_UShort instanceSize; + + } GX_FVar_Head; + + + typedef struct fvar_axis_ + { + FT_ULong axisTag; + FT_ULong minValue; + FT_ULong defaultValue; + FT_ULong maxValue; + FT_UShort flags; + FT_UShort nameID; + + } GX_FVar_Axis; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* TT_Get_MM_Var */ + /* */ + /* <Description> */ + /* Check that the font's `fvar' table is valid, parse it, and return */ + /* those data. */ + /* */ + /* <InOut> */ + /* face :: The font face. */ + /* TT_Get_MM_Var initializes the blend structure. */ + /* */ + /* <Output> */ + /* master :: The `fvar' data (must be freed by caller). */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + TT_Get_MM_Var( TT_Face face, + FT_MM_Var* *master ) + { + FT_Stream stream = face->root.stream; + FT_Memory memory = face->root.memory; + FT_ULong table_len; + FT_Error error = TT_Err_Ok; + FT_ULong fvar_start; + FT_Int i, j; + FT_MM_Var* mmvar; + FT_Fixed* next_coords; + FT_String* next_name; + FT_Var_Axis* a; + FT_Var_Named_Style* ns; + GX_FVar_Head fvar_head; + + static const FT_Frame_Field fvar_fields[] = + { + +#undef FT_STRUCTURE +#define FT_STRUCTURE GX_FVar_Head + + FT_FRAME_START( 16 ), + FT_FRAME_LONG ( version ), + FT_FRAME_USHORT( offsetToData ), + FT_FRAME_USHORT( countSizePairs ), + FT_FRAME_USHORT( axisCount ), + FT_FRAME_USHORT( axisSize ), + FT_FRAME_USHORT( instanceCount ), + FT_FRAME_USHORT( instanceSize ), + FT_FRAME_END + }; + + static const FT_Frame_Field fvaraxis_fields[] = + { + +#undef FT_STRUCTURE +#define FT_STRUCTURE GX_FVar_Axis + + FT_FRAME_START( 20 ), + FT_FRAME_ULONG ( axisTag ), + FT_FRAME_ULONG ( minValue ), + FT_FRAME_ULONG ( defaultValue ), + FT_FRAME_ULONG ( maxValue ), + FT_FRAME_USHORT( flags ), + FT_FRAME_USHORT( nameID ), + FT_FRAME_END + }; + + + if ( face->blend == NULL ) + { + /* both `fvar' and `gvar' must be present */ + if ( (error = face->goto_table( face, TTAG_gvar, + stream, &table_len )) != 0 ) + goto Exit; + + if ( (error = face->goto_table( face, TTAG_fvar, + stream, &table_len )) != 0 ) + goto Exit; + + fvar_start = FT_STREAM_POS( ); + + if ( FT_STREAM_READ_FIELDS( fvar_fields, &fvar_head ) ) + goto Exit; + + if ( fvar_head.version != (FT_Long)0x00010000L || + fvar_head.countSizePairs != 2 || + fvar_head.axisSize != 20 || + fvar_head.instanceSize != 4 + 4 * fvar_head.axisCount || + fvar_head.offsetToData + fvar_head.axisCount * 20U + + fvar_head.instanceCount * fvar_head.instanceSize > table_len ) + { + error = TT_Err_Invalid_Table; + goto Exit; + } + + if ( FT_NEW( face->blend ) ) + goto Exit; + + /* XXX: TODO - check for overflows */ + face->blend->mmvar_len = + sizeof ( FT_MM_Var ) + + fvar_head.axisCount * sizeof ( FT_Var_Axis ) + + fvar_head.instanceCount * sizeof ( FT_Var_Named_Style ) + + fvar_head.instanceCount * fvar_head.axisCount * sizeof ( FT_Fixed ) + + 5 * fvar_head.axisCount; + + if ( FT_ALLOC( mmvar, face->blend->mmvar_len ) ) + goto Exit; + face->blend->mmvar = mmvar; + + mmvar->num_axis = + fvar_head.axisCount; + mmvar->num_designs = + (FT_UInt)-1; /* meaningless in this context; each glyph */ + /* may have a different number of designs */ + /* (or tuples, as called by Apple) */ + mmvar->num_namedstyles = + fvar_head.instanceCount; + mmvar->axis = + (FT_Var_Axis*)&(mmvar[1]); + mmvar->namedstyle = + (FT_Var_Named_Style*)&(mmvar->axis[fvar_head.axisCount]); + + next_coords = + (FT_Fixed*)&(mmvar->namedstyle[fvar_head.instanceCount]); + for ( i = 0; i < fvar_head.instanceCount; ++i ) + { + mmvar->namedstyle[i].coords = next_coords; + next_coords += fvar_head.axisCount; + } + + next_name = (FT_String*)next_coords; + for ( i = 0; i < fvar_head.axisCount; ++i ) + { + mmvar->axis[i].name = next_name; + next_name += 5; + } + + if ( FT_STREAM_SEEK( fvar_start + fvar_head.offsetToData ) ) + goto Exit; + + a = mmvar->axis; + for ( i = 0; i < fvar_head.axisCount; ++i ) + { + GX_FVar_Axis axis_rec; + + + if ( FT_STREAM_READ_FIELDS( fvaraxis_fields, &axis_rec ) ) + goto Exit; + a->tag = axis_rec.axisTag; + a->minimum = axis_rec.minValue; /* A Fixed */ + a->def = axis_rec.defaultValue; /* A Fixed */ + a->maximum = axis_rec.maxValue; /* A Fixed */ + a->strid = axis_rec.nameID; + + a->name[0] = (FT_String)( a->tag >> 24 ); + a->name[1] = (FT_String)( ( a->tag >> 16 ) & 0xFF ); + a->name[2] = (FT_String)( ( a->tag >> 8 ) & 0xFF ); + a->name[3] = (FT_String)( ( a->tag ) & 0xFF ); + a->name[4] = 0; + + ++a; + } + + ns = mmvar->namedstyle; + for ( i = 0; i < fvar_head.instanceCount; ++i, ++ns ) + { + if ( FT_FRAME_ENTER( 4L + 4L * fvar_head.axisCount ) ) + goto Exit; + + ns->strid = FT_GET_USHORT(); + (void) /* flags = */ FT_GET_USHORT(); + + for ( j = 0; j < fvar_head.axisCount; ++j ) + ns->coords[j] = FT_GET_ULONG(); /* A Fixed */ + + FT_FRAME_EXIT(); + } + } + + if ( master != NULL ) + { + FT_UInt n; + + + if ( FT_ALLOC( mmvar, face->blend->mmvar_len ) ) + goto Exit; + FT_MEM_COPY( mmvar, face->blend->mmvar, face->blend->mmvar_len ); + + mmvar->axis = + (FT_Var_Axis*)&(mmvar[1]); + mmvar->namedstyle = + (FT_Var_Named_Style*)&(mmvar->axis[mmvar->num_axis]); + next_coords = + (FT_Fixed*)&(mmvar->namedstyle[mmvar->num_namedstyles]); + + for ( n = 0; n < mmvar->num_namedstyles; ++n ) + { + mmvar->namedstyle[n].coords = next_coords; + next_coords += mmvar->num_axis; + } + + a = mmvar->axis; + next_name = (FT_String*)next_coords; + for ( n = 0; n < mmvar->num_axis; ++n ) + { + a->name = next_name; + + /* standard PostScript names for some standard apple tags */ + if ( a->tag == TTAG_wght ) + a->name = (char *)"Weight"; + else if ( a->tag == TTAG_wdth ) + a->name = (char *)"Width"; + else if ( a->tag == TTAG_opsz ) + a->name = (char *)"OpticalSize"; + else if ( a->tag == TTAG_slnt ) + a->name = (char *)"Slant"; + + next_name += 5; + ++a; + } + + *master = mmvar; + } + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* TT_Set_MM_Blend */ + /* */ + /* <Description> */ + /* Set the blend (normalized) coordinates for this instance of the */ + /* font. Check that the `gvar' table is reasonable and does some */ + /* initial preparation. */ + /* */ + /* <InOut> */ + /* face :: The font. */ + /* Initialize the blend structure with `gvar' data. */ + /* */ + /* <Input> */ + /* num_coords :: Must be the axis count of the font. */ + /* */ + /* coords :: An array of num_coords, each between [-1,1]. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + TT_Set_MM_Blend( TT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) + { + FT_Error error = TT_Err_Ok; + GX_Blend blend; + FT_MM_Var* mmvar; + FT_UInt i; + FT_Memory memory = face->root.memory; + + enum + { + mcvt_retain, + mcvt_modify, + mcvt_load + + } manageCvt; + + + face->doblend = FALSE; + + if ( face->blend == NULL ) + { + if ( (error = TT_Get_MM_Var( face, NULL)) != 0 ) + goto Exit; + } + + blend = face->blend; + mmvar = blend->mmvar; + + if ( num_coords != mmvar->num_axis ) + { + error = TT_Err_Invalid_Argument; + goto Exit; + } + + for ( i = 0; i < num_coords; ++i ) + if ( coords[i] < -0x00010000L || coords[i] > 0x00010000L ) + { + error = TT_Err_Invalid_Argument; + goto Exit; + } + + if ( blend->glyphoffsets == NULL ) + if ( (error = ft_var_load_gvar( face )) != 0 ) + goto Exit; + + if ( blend->normalizedcoords == NULL ) + { + if ( FT_NEW_ARRAY( blend->normalizedcoords, num_coords ) ) + goto Exit; + + manageCvt = mcvt_modify; + + /* If we have not set the blend coordinates before this, then the */ + /* cvt table will still be what we read from the `cvt ' table and */ + /* we don't need to reload it. We may need to change it though... */ + } + else + { + manageCvt = mcvt_retain; + for ( i = 0; i < num_coords; ++i ) + { + if ( blend->normalizedcoords[i] != coords[i] ) + { + manageCvt = mcvt_load; + break; + } + } + + /* If we don't change the blend coords then we don't need to do */ + /* anything to the cvt table. It will be correct. Otherwise we */ + /* no longer have the original cvt (it was modified when we set */ + /* the blend last time), so we must reload and then modify it. */ + } + + blend->num_axis = num_coords; + FT_MEM_COPY( blend->normalizedcoords, + coords, + num_coords * sizeof ( FT_Fixed ) ); + + face->doblend = TRUE; + + if ( face->cvt != NULL ) + { + switch ( manageCvt ) + { + case mcvt_load: + /* The cvt table has been loaded already; every time we change the */ + /* blend we may need to reload and remodify the cvt table. */ + FT_FREE( face->cvt ); + face->cvt = NULL; + + tt_face_load_cvt( face, face->root.stream ); + break; + + case mcvt_modify: + /* The original cvt table is in memory. All we need to do is */ + /* apply the `cvar' table (if any). */ + tt_face_vary_cvt( face, face->root.stream ); + break; + + case mcvt_retain: + /* The cvt table is correct for this set of coordinates. */ + break; + } + } + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* TT_Set_Var_Design */ + /* */ + /* <Description> */ + /* Set the coordinates for the instance, measured in the user */ + /* coordinate system. Parse the `avar' table (if present) to convert */ + /* from user to normalized coordinates. */ + /* */ + /* <InOut> */ + /* face :: The font face. */ + /* Initialize the blend struct with `gvar' data. */ + /* */ + /* <Input> */ + /* num_coords :: This must be the axis count of the font. */ + /* */ + /* coords :: A coordinate array with `num_coords' elements. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + TT_Set_Var_Design( TT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) + { + FT_Error error = TT_Err_Ok; + FT_Fixed* normalized = NULL; + GX_Blend blend; + FT_MM_Var* mmvar; + FT_UInt i, j; + FT_Var_Axis* a; + GX_AVarSegment av; + FT_Memory memory = face->root.memory; + + + if ( face->blend == NULL ) + { + if ( (error = TT_Get_MM_Var( face, NULL )) != 0 ) + goto Exit; + } + + blend = face->blend; + mmvar = blend->mmvar; + + if ( num_coords != mmvar->num_axis ) + { + error = TT_Err_Invalid_Argument; + goto Exit; + } + + /* Axis normalization is a two stage process. First we normalize */ + /* based on the [min,def,max] values for the axis to be [-1,0,1]. */ + /* Then, if there's an `avar' table, we renormalize this range. */ + + if ( FT_NEW_ARRAY( normalized, mmvar->num_axis ) ) + goto Exit; + + a = mmvar->axis; + for ( i = 0; i < mmvar->num_axis; ++i, ++a ) + { + if ( coords[i] > a->maximum || coords[i] < a->minimum ) + { + error = TT_Err_Invalid_Argument; + goto Exit; + } + + if ( coords[i] < a->def ) + { + normalized[i] = -FT_MulDiv( coords[i] - a->def, + 0x10000L, + a->minimum - a->def ); + } + else if ( a->maximum == a->def ) + normalized[i] = 0; + else + { + normalized[i] = FT_MulDiv( coords[i] - a->def, + 0x10000L, + a->maximum - a->def ); + } + } + + if ( !blend->avar_checked ) + ft_var_load_avar( face ); + + if ( blend->avar_segment != NULL ) + { + av = blend->avar_segment; + for ( i = 0; i < mmvar->num_axis; ++i, ++av ) + { + for ( j = 1; j < (FT_UInt)av->pairCount; ++j ) + if ( normalized[i] < av->correspondence[j].fromCoord ) + { + normalized[i] = + FT_MulDiv( + FT_MulDiv( + normalized[i] - av->correspondence[j - 1].fromCoord, + 0x10000L, + av->correspondence[j].fromCoord - + av->correspondence[j - 1].fromCoord ), + av->correspondence[j].toCoord - + av->correspondence[j - 1].toCoord, + 0x10000L ) + + av->correspondence[j - 1].toCoord; + break; + } + } + } + + error = TT_Set_MM_Blend( face, num_coords, normalized ); + + Exit: + FT_FREE( normalized ); + return error; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GX VAR PARSING ROUTINES *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_vary_cvt */ + /* */ + /* <Description> */ + /* Modify the loaded cvt table according to the `cvar' table and the */ + /* font's blend. */ + /* */ + /* <InOut> */ + /* face :: A handle to the target face object. */ + /* */ + /* <Input> */ + /* stream :: A handle to the input stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* Most errors are ignored. It is perfectly valid not to have a */ + /* `cvar' table even if there is a `gvar' and `fvar' table. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_vary_cvt( TT_Face face, + FT_Stream stream ) + { + FT_Error error; + FT_Memory memory = stream->memory; + FT_ULong table_start; + FT_ULong table_len; + FT_UInt tupleCount; + FT_ULong offsetToData; + FT_ULong here; + FT_UInt i, j; + FT_Fixed* tuple_coords = NULL; + FT_Fixed* im_start_coords = NULL; + FT_Fixed* im_end_coords = NULL; + GX_Blend blend = face->blend; + FT_UInt point_count; + FT_UShort* localpoints; + FT_Short* deltas; + + + FT_TRACE2(( "CVAR " )); + + if ( blend == NULL ) + { + FT_TRACE2(( "tt_face_vary_cvt: no blend specified\n" )); + + error = TT_Err_Ok; + goto Exit; + } + + if ( face->cvt == NULL ) + { + FT_TRACE2(( "tt_face_vary_cvt: no `cvt ' table\n" )); + + error = TT_Err_Ok; + goto Exit; + } + + error = face->goto_table( face, TTAG_cvar, stream, &table_len ); + if ( error ) + { + FT_TRACE2(( "is missing\n" )); + + error = TT_Err_Ok; + goto Exit; + } + + if ( FT_FRAME_ENTER( table_len ) ) + { + error = TT_Err_Ok; + goto Exit; + } + + table_start = FT_Stream_FTell( stream ); + if ( FT_GET_LONG() != 0x00010000L ) + { + FT_TRACE2(( "bad table version\n" )); + + error = TT_Err_Ok; + goto FExit; + } + + if ( FT_NEW_ARRAY( tuple_coords, blend->num_axis ) || + FT_NEW_ARRAY( im_start_coords, blend->num_axis ) || + FT_NEW_ARRAY( im_end_coords, blend->num_axis ) ) + goto FExit; + + tupleCount = FT_GET_USHORT(); + offsetToData = table_start + FT_GET_USHORT(); + + /* The documentation implies there are flags packed into the */ + /* tuplecount, but John Jenkins says that shared points don't apply */ + /* to `cvar', and no other flags are defined. */ + + for ( i = 0; i < ( tupleCount & 0xFFF ); ++i ) + { + FT_UInt tupleDataSize; + FT_UInt tupleIndex; + FT_Fixed apply; + + + tupleDataSize = FT_GET_USHORT(); + tupleIndex = FT_GET_USHORT(); + + /* There is no provision here for a global tuple coordinate section, */ + /* so John says. There are no tuple indices, just embedded tuples. */ + + if ( tupleIndex & GX_TI_EMBEDDED_TUPLE_COORD ) + { + for ( j = 0; j < blend->num_axis; ++j ) + tuple_coords[j] = FT_GET_SHORT() << 2; /* convert from */ + /* short frac to fixed */ + } + else + { + /* skip this tuple; it makes no sense */ + + if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) + for ( j = 0; j < 2 * blend->num_axis; ++j ) + (void)FT_GET_SHORT(); + + offsetToData += tupleDataSize; + continue; + } + + if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) + { + for ( j = 0; j < blend->num_axis; ++j ) + im_start_coords[j] = FT_GET_SHORT() << 2; + for ( j = 0; j < blend->num_axis; ++j ) + im_end_coords[j] = FT_GET_SHORT() << 2; + } + + apply = ft_var_apply_tuple( blend, + (FT_UShort)tupleIndex, + tuple_coords, + im_start_coords, + im_end_coords ); + if ( /* tuple isn't active for our blend */ + apply == 0 || + /* global points not allowed, */ + /* if they aren't local, makes no sense */ + !( tupleIndex & GX_TI_PRIVATE_POINT_NUMBERS ) ) + { + offsetToData += tupleDataSize; + continue; + } + + here = FT_Stream_FTell( stream ); + + FT_Stream_SeekSet( stream, offsetToData ); + + localpoints = ft_var_readpackedpoints( stream, &point_count ); + deltas = ft_var_readpackeddeltas( stream, + point_count == 0 ? face->cvt_size + : point_count ); + if ( localpoints == NULL || deltas == NULL ) + /* failure, ignore it */; + + else if ( localpoints == ALL_POINTS ) + { + /* this means that there are deltas for every entry in cvt */ + for ( j = 0; j < face->cvt_size; ++j ) + face->cvt[j] = (FT_Short)( face->cvt[j] + + FT_MulFix( deltas[j], apply ) ); + } + + else + { + for ( j = 0; j < point_count; ++j ) + { + int pindex = localpoints[j]; + + face->cvt[pindex] = (FT_Short)( face->cvt[pindex] + + FT_MulFix( deltas[j], apply ) ); + } + } + + if ( localpoints != ALL_POINTS ) + FT_FREE( localpoints ); + FT_FREE( deltas ); + + offsetToData += tupleDataSize; + + FT_Stream_SeekSet( stream, here ); + } + + FExit: + FT_FRAME_EXIT(); + + Exit: + FT_FREE( tuple_coords ); + FT_FREE( im_start_coords ); + FT_FREE( im_end_coords ); + + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* TT_Vary_Get_Glyph_Deltas */ + /* */ + /* <Description> */ + /* Load the appropriate deltas for the current glyph. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* glyph_index :: The index of the glyph being modified. */ + /* */ + /* n_points :: The number of the points in the glyph, including */ + /* phantom points. */ + /* */ + /* <Output> */ + /* deltas :: The array of points to change. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + TT_Vary_Get_Glyph_Deltas( TT_Face face, + FT_UInt glyph_index, + FT_Vector* *deltas, + FT_UInt n_points ) + { + FT_Stream stream = face->root.stream; + FT_Memory memory = stream->memory; + GX_Blend blend = face->blend; + FT_Vector* delta_xy; + + FT_Error error; + FT_ULong glyph_start; + FT_UInt tupleCount; + FT_ULong offsetToData; + FT_ULong here; + FT_UInt i, j; + FT_Fixed* tuple_coords = NULL; + FT_Fixed* im_start_coords = NULL; + FT_Fixed* im_end_coords = NULL; + FT_UInt point_count, spoint_count = 0; + FT_UShort* sharedpoints = NULL; + FT_UShort* localpoints = NULL; + FT_UShort* points; + FT_Short *deltas_x, *deltas_y; + + + if ( !face->doblend || blend == NULL ) + return TT_Err_Invalid_Argument; + + /* to be freed by the caller */ + if ( FT_NEW_ARRAY( delta_xy, n_points ) ) + goto Exit; + *deltas = delta_xy; + + if ( glyph_index >= blend->gv_glyphcnt || + blend->glyphoffsets[glyph_index] == + blend->glyphoffsets[glyph_index + 1] ) + return TT_Err_Ok; /* no variation data for this glyph */ + + if ( FT_STREAM_SEEK( blend->glyphoffsets[glyph_index] ) || + FT_FRAME_ENTER( blend->glyphoffsets[glyph_index + 1] - + blend->glyphoffsets[glyph_index] ) ) + goto Fail1; + + glyph_start = FT_Stream_FTell( stream ); + + /* each set of glyph variation data is formatted similarly to `cvar' */ + /* (except we get shared points and global tuples) */ + + if ( FT_NEW_ARRAY( tuple_coords, blend->num_axis ) || + FT_NEW_ARRAY( im_start_coords, blend->num_axis ) || + FT_NEW_ARRAY( im_end_coords, blend->num_axis ) ) + goto Fail2; + + tupleCount = FT_GET_USHORT(); + offsetToData = glyph_start + FT_GET_USHORT(); + + if ( tupleCount & GX_TC_TUPLES_SHARE_POINT_NUMBERS ) + { + here = FT_Stream_FTell( stream ); + + FT_Stream_SeekSet( stream, offsetToData ); + + sharedpoints = ft_var_readpackedpoints( stream, &spoint_count ); + offsetToData = FT_Stream_FTell( stream ); + + FT_Stream_SeekSet( stream, here ); + } + + for ( i = 0; i < ( tupleCount & GX_TC_TUPLE_COUNT_MASK ); ++i ) + { + FT_UInt tupleDataSize; + FT_UInt tupleIndex; + FT_Fixed apply; + + + tupleDataSize = FT_GET_USHORT(); + tupleIndex = FT_GET_USHORT(); + + if ( tupleIndex & GX_TI_EMBEDDED_TUPLE_COORD ) + { + for ( j = 0; j < blend->num_axis; ++j ) + tuple_coords[j] = FT_GET_SHORT() << 2; /* convert from */ + /* short frac to fixed */ + } + else if ( ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) >= blend->tuplecount ) + { + error = TT_Err_Invalid_Table; + goto Fail3; + } + else + { + FT_MEM_COPY( + tuple_coords, + &blend->tuplecoords[(tupleIndex & 0xFFF) * blend->num_axis], + blend->num_axis * sizeof ( FT_Fixed ) ); + } + + if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) + { + for ( j = 0; j < blend->num_axis; ++j ) + im_start_coords[j] = FT_GET_SHORT() << 2; + for ( j = 0; j < blend->num_axis; ++j ) + im_end_coords[j] = FT_GET_SHORT() << 2; + } + + apply = ft_var_apply_tuple( blend, + (FT_UShort)tupleIndex, + tuple_coords, + im_start_coords, + im_end_coords ); + + if ( apply == 0 ) /* tuple isn't active for our blend */ + { + offsetToData += tupleDataSize; + continue; + } + + here = FT_Stream_FTell( stream ); + + if ( tupleIndex & GX_TI_PRIVATE_POINT_NUMBERS ) + { + FT_Stream_SeekSet( stream, offsetToData ); + + localpoints = ft_var_readpackedpoints( stream, &point_count ); + points = localpoints; + } + else + { + points = sharedpoints; + point_count = spoint_count; + } + + deltas_x = ft_var_readpackeddeltas( stream, + point_count == 0 ? n_points + : point_count ); + deltas_y = ft_var_readpackeddeltas( stream, + point_count == 0 ? n_points + : point_count ); + + if ( points == NULL || deltas_y == NULL || deltas_x == NULL ) + ; /* failure, ignore it */ + + else if ( points == ALL_POINTS ) + { + /* this means that there are deltas for every point in the glyph */ + for ( j = 0; j < n_points; ++j ) + { + delta_xy[j].x += FT_MulFix( deltas_x[j], apply ); + delta_xy[j].y += FT_MulFix( deltas_y[j], apply ); + } + } + + else + { + for ( j = 0; j < point_count; ++j ) + { + delta_xy[localpoints[j]].x += FT_MulFix( deltas_x[j], apply ); + delta_xy[localpoints[j]].y += FT_MulFix( deltas_y[j], apply ); + } + } + + if ( localpoints != ALL_POINTS ) + FT_FREE( localpoints ); + FT_FREE( deltas_x ); + FT_FREE( deltas_y ); + + offsetToData += tupleDataSize; + + FT_Stream_SeekSet( stream, here ); + } + + Fail3: + FT_FREE( tuple_coords ); + FT_FREE( im_start_coords ); + FT_FREE( im_end_coords ); + + Fail2: + FT_FRAME_EXIT(); + + Fail1: + if ( error ) + { + FT_FREE( delta_xy ); + *deltas = NULL; + } + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_done_blend */ + /* */ + /* <Description> */ + /* Frees the blend internal data structure. */ + /* */ + FT_LOCAL_DEF( void ) + tt_done_blend( FT_Memory memory, + GX_Blend blend ) + { + if ( blend != NULL ) + { + FT_UInt i; + + + FT_FREE( blend->normalizedcoords ); + FT_FREE( blend->mmvar ); + + if ( blend->avar_segment != NULL ) + { + for ( i = 0; i < blend->num_axis; ++i ) + FT_FREE( blend->avar_segment[i].correspondence ); + FT_FREE( blend->avar_segment ); + } + + FT_FREE( blend->tuplecoords ); + FT_FREE( blend->glyphoffsets ); + FT_FREE( blend ); + } + } + +#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/truetype/ttgxvar.h b/mod/pub.mod/freetype.mod/src/truetype/ttgxvar.h new file mode 100644 index 0000000..82dfc44 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/truetype/ttgxvar.h @@ -0,0 +1,182 @@ +/***************************************************************************/ +/* */ +/* ttgxvar.h */ +/* */ +/* TrueType GX Font Variation loader (specification) */ +/* */ +/* Copyright 2004 by */ +/* David Turner, Robert Wilhelm, Werner Lemberg and George Williams. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __TTGXVAR_H__ +#define __TTGXVAR_H__ + + +#include <ft2build.h> +#include "ttobjs.h" + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* GX_AVarCorrespondenceRec */ + /* */ + /* <Description> */ + /* A data structure representing `shortFracCorrespondence' in `avar' */ + /* table according to the specifications from Apple. */ + /* */ + typedef struct GX_AVarCorrespondenceRec_ + { + FT_Fixed fromCoord; + FT_Fixed toCoord; + + } GX_AVarCorrespondenceRec_, *GX_AVarCorrespondence; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* GX_AVarRec */ + /* */ + /* <Description> */ + /* Data from the segment field of `avar' table. */ + /* There is one of these for each axis. */ + /* */ + typedef struct GX_AVarSegmentRec_ + { + FT_UShort pairCount; + GX_AVarCorrespondence correspondence; /* array with pairCount entries */ + + } GX_AVarSegmentRec, *GX_AVarSegment; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* GX_BlendRec */ + /* */ + /* <Description> */ + /* Data for interpolating a font from a distortable font specified */ + /* by the GX *var tables ([fgca]var). */ + /* */ + /* <Fields> */ + /* num_axis :: The number of axes along which interpolation */ + /* may happen */ + /* */ + /* normalizedcoords :: A normalized value (between [-1,1]) indicating */ + /* the contribution along each axis to the final */ + /* interpolated font. */ + /* */ + typedef struct GX_BlendRec_ + { + FT_UInt num_axis; + FT_Fixed* normalizedcoords; + + FT_MM_Var* mmvar; + FT_Offset mmvar_len; + + FT_Bool avar_checked; + GX_AVarSegment avar_segment; + + FT_UInt tuplecount; /* shared tuples in `gvar' */ + FT_Fixed* tuplecoords; /* tuplecoords[tuplecount][num_axis] */ + + FT_UInt gv_glyphcnt; + FT_ULong* glyphoffsets; + + } GX_BlendRec; + + + /*************************************************************************/ + /* */ + /* <enum> */ + /* GX_TupleCountFlags */ + /* */ + /* <Description> */ + /* Flags used within the `TupleCount' field of the `gvar' table. */ + /* */ + typedef enum GX_TupleCountFlags_ + { + GX_TC_TUPLES_SHARE_POINT_NUMBERS = 0x8000, + GX_TC_RESERVED_TUPLE_FLAGS = 0x7000, + GX_TC_TUPLE_COUNT_MASK = 0x0FFF + + } GX_TupleCountFlags; + + + /*************************************************************************/ + /* */ + /* <enum> */ + /* GX_TupleIndexFlags */ + /* */ + /* <Description> */ + /* Flags used within the `TupleIndex' field of the `gvar' and `cvar' */ + /* tables. */ + /* */ + typedef enum GX_TupleIndexFlags_ + { + GX_TI_EMBEDDED_TUPLE_COORD = 0x8000, + GX_TI_INTERMEDIATE_TUPLE = 0x4000, + GX_TI_PRIVATE_POINT_NUMBERS = 0x2000, + GX_TI_RESERVED_TUPLE_FLAG = 0x1000, + GX_TI_TUPLE_INDEX_MASK = 0x0FFF + + } GX_TupleIndexFlags; + + +#define TTAG_wght FT_MAKE_TAG( 'w', 'g', 'h', 't' ) +#define TTAG_wdth FT_MAKE_TAG( 'w', 'd', 't', 'h' ) +#define TTAG_opsz FT_MAKE_TAG( 'o', 'p', 's', 'z' ) +#define TTAG_slnt FT_MAKE_TAG( 's', 'l', 'n', 't' ) + + + FT_LOCAL( FT_Error ) + TT_Set_MM_Blend( TT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); + + FT_LOCAL( FT_Error ) + TT_Set_Var_Design( TT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); + + FT_LOCAL( FT_Error ) + TT_Get_MM_Var( TT_Face face, + FT_MM_Var* *master ); + + + FT_LOCAL( FT_Error ) + tt_face_vary_cvt( TT_Face face, + FT_Stream stream ); + + + FT_LOCAL( FT_Error ) + TT_Vary_Get_Glyph_Deltas( TT_Face face, + FT_UInt glyph_index, + FT_Vector* *deltas, + FT_UInt n_points ); + + + FT_LOCAL( void ) + tt_done_blend( FT_Memory memory, + GX_Blend blend ); + + +FT_END_HEADER + + +#endif /* __TTGXVAR_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/truetype/ttinterp.c b/mod/pub.mod/freetype.mod/src/truetype/ttinterp.c new file mode 100644 index 0000000..13aa9a2 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/truetype/ttinterp.c @@ -0,0 +1,7844 @@ +/***************************************************************************/ +/* */ +/* ttinterp.c */ +/* */ +/* TrueType bytecode interpreter (body). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_CALC_H +#include FT_TRIGONOMETRY_H +#include FT_SYSTEM_H + +#include "ttinterp.h" + +#include "tterrors.h" + + +#ifdef TT_USE_BYTECODE_INTERPRETER + + +#define TT_MULFIX FT_MulFix +#define TT_MULDIV FT_MulDiv +#define TT_MULDIV_NO_ROUND FT_MulDiv_No_Round + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_ttinterp + + /*************************************************************************/ + /* */ + /* In order to detect infinite loops in the code, we set up a counter */ + /* within the run loop. A single stroke of interpretation is now */ + /* limited to a maximal number of opcodes defined below. */ + /* */ +#define MAX_RUNNABLE_OPCODES 1000000L + + + /*************************************************************************/ + /* */ + /* There are two kinds of implementations: */ + /* */ + /* a. static implementation */ + /* */ + /* The current execution context is a static variable, which fields */ + /* are accessed directly by the interpreter during execution. The */ + /* context is named `cur'. */ + /* */ + /* This version is non-reentrant, of course. */ + /* */ + /* b. indirect implementation */ + /* */ + /* The current execution context is passed to _each_ function as its */ + /* first argument, and each field is thus accessed indirectly. */ + /* */ + /* This version is fully re-entrant. */ + /* */ + /* The idea is that an indirect implementation may be slower to execute */ + /* on low-end processors that are used in some systems (like 386s or */ + /* even 486s). */ + /* */ + /* As a consequence, the indirect implementation is now the default, as */ + /* its performance costs can be considered negligible in our context. */ + /* Note, however, that we kept the same source with macros because: */ + /* */ + /* - The code is kept very close in design to the Pascal code used for */ + /* development. */ + /* */ + /* - It's much more readable that way! */ + /* */ + /* - It's still open to experimentation and tuning. */ + /* */ + /*************************************************************************/ + + +#ifndef TT_CONFIG_OPTION_STATIC_INTERPRETER /* indirect implementation */ + +#define CUR (*exc) /* see ttobjs.h */ + + /*************************************************************************/ + /* */ + /* This macro is used whenever `exec' is unused in a function, to avoid */ + /* stupid warnings from pedantic compilers. */ + /* */ +#define FT_UNUSED_EXEC FT_UNUSED( exc ) + +#else /* static implementation */ + +#define CUR cur + +#define FT_UNUSED_EXEC int __dummy = __dummy + + static + TT_ExecContextRec cur; /* static exec. context variable */ + + /* apparently, we have a _lot_ of direct indexing when accessing */ + /* the static `cur', which makes the code bigger (due to all the */ + /* four bytes addresses). */ + +#endif /* TT_CONFIG_OPTION_STATIC_INTERPRETER */ + + + /*************************************************************************/ + /* */ + /* The instruction argument stack. */ + /* */ +#define INS_ARG EXEC_OP_ FT_Long* args /* see ttobjs.h for EXEC_OP_ */ + + + /*************************************************************************/ + /* */ + /* This macro is used whenever `args' is unused in a function, to avoid */ + /* stupid warnings from pedantic compilers. */ + /* */ +#define FT_UNUSED_ARG FT_UNUSED_EXEC; FT_UNUSED( args ) + + + /*************************************************************************/ + /* */ + /* The following macros hide the use of EXEC_ARG and EXEC_ARG_ to */ + /* increase readability of the code. */ + /* */ + /*************************************************************************/ + + +#define SKIP_Code() \ + SkipCode( EXEC_ARG ) + +#define GET_ShortIns() \ + GetShortIns( EXEC_ARG ) + +#define NORMalize( x, y, v ) \ + Normalize( EXEC_ARG_ x, y, v ) + +#define SET_SuperRound( scale, flags ) \ + SetSuperRound( EXEC_ARG_ scale, flags ) + +#define ROUND_None( d, c ) \ + Round_None( EXEC_ARG_ d, c ) + +#define INS_Goto_CodeRange( range, ip ) \ + Ins_Goto_CodeRange( EXEC_ARG_ range, ip ) + +#define CUR_Func_move( z, p, d ) \ + CUR.func_move( EXEC_ARG_ z, p, d ) + +#define CUR_Func_move_orig( z, p, d ) \ + CUR.func_move_orig( EXEC_ARG_ z, p, d ) + +#define CUR_Func_round( d, c ) \ + CUR.func_round( EXEC_ARG_ d, c ) + +#define CUR_Func_read_cvt( index ) \ + CUR.func_read_cvt( EXEC_ARG_ index ) + +#define CUR_Func_write_cvt( index, val ) \ + CUR.func_write_cvt( EXEC_ARG_ index, val ) + +#define CUR_Func_move_cvt( index, val ) \ + CUR.func_move_cvt( EXEC_ARG_ index, val ) + +#define CURRENT_Ratio() \ + Current_Ratio( EXEC_ARG ) + +#define CURRENT_Ppem() \ + Current_Ppem( EXEC_ARG ) + +#define CUR_Ppem() \ + Cur_PPEM( EXEC_ARG ) + +#define INS_SxVTL( a, b, c, d ) \ + Ins_SxVTL( EXEC_ARG_ a, b, c, d ) + +#define COMPUTE_Funcs() \ + Compute_Funcs( EXEC_ARG ) + +#define COMPUTE_Round( a ) \ + Compute_Round( EXEC_ARG_ a ) + +#define COMPUTE_Point_Displacement( a, b, c, d ) \ + Compute_Point_Displacement( EXEC_ARG_ a, b, c, d ) + +#define MOVE_Zp2_Point( a, b, c, t ) \ + Move_Zp2_Point( EXEC_ARG_ a, b, c, t ) + + +#define CUR_Func_project( v1, v2 ) \ + CUR.func_project( EXEC_ARG_ (v1)->x - (v2)->x, (v1)->y - (v2)->y ) + +#define CUR_Func_dualproj( v1, v2 ) \ + CUR.func_dualproj( EXEC_ARG_ (v1)->x - (v2)->x, (v1)->y - (v2)->y ) + +#define CUR_fast_project( v ) \ + CUR.func_project( EXEC_ARG_ (v)->x, (v)->y ) + +#define CUR_fast_dualproj( v ) \ + CUR.func_dualproj( EXEC_ARG_ (v)->x, (v)->y ) + + + /*************************************************************************/ + /* */ + /* Instruction dispatch function, as used by the interpreter. */ + /* */ + typedef void (*TInstruction_Function)( INS_ARG ); + + + /*************************************************************************/ + /* */ + /* A simple bounds-checking macro. */ + /* */ +#define BOUNDS( x, n ) ( (FT_UInt)(x) >= (FT_UInt)(n) ) + +#undef SUCCESS +#define SUCCESS 0 + +#undef FAILURE +#define FAILURE 1 + +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING +#define GUESS_VECTOR( V ) \ + if ( CUR.face->unpatented_hinting ) \ + { \ + CUR.GS.V.x = (FT_F2Dot14)( CUR.GS.both_x_axis ? 0x4000 : 0 ); \ + CUR.GS.V.y = (FT_F2Dot14)( CUR.GS.both_x_axis ? 0 : 0x4000 ); \ + } +#else +#define GUESS_VECTOR( V ) +#endif + + /*************************************************************************/ + /* */ + /* CODERANGE FUNCTIONS */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* TT_Goto_CodeRange */ + /* */ + /* <Description> */ + /* Switches to a new code range (updates the code related elements in */ + /* `exec', and `IP'). */ + /* */ + /* <Input> */ + /* range :: The new execution code range. */ + /* */ + /* IP :: The new IP in the new code range. */ + /* */ + /* <InOut> */ + /* exec :: The target execution context. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + TT_Goto_CodeRange( TT_ExecContext exec, + FT_Int range, + FT_Long IP ) + { + TT_CodeRange* coderange; + + + FT_ASSERT( range >= 1 && range <= 3 ); + + coderange = &exec->codeRangeTable[range - 1]; + + FT_ASSERT( coderange->base != NULL ); + + /* NOTE: Because the last instruction of a program may be a CALL */ + /* which will return to the first byte *after* the code */ + /* range, we test for IP <= Size instead of IP < Size. */ + /* */ + FT_ASSERT( (FT_ULong)IP <= coderange->size ); + + exec->code = coderange->base; + exec->codeSize = coderange->size; + exec->IP = IP; + exec->curRange = range; + + return TT_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* TT_Set_CodeRange */ + /* */ + /* <Description> */ + /* Sets a code range. */ + /* */ + /* <Input> */ + /* range :: The code range index. */ + /* */ + /* base :: The new code base. */ + /* */ + /* length :: The range size in bytes. */ + /* */ + /* <InOut> */ + /* exec :: The target execution context. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + TT_Set_CodeRange( TT_ExecContext exec, + FT_Int range, + void* base, + FT_Long length ) + { + FT_ASSERT( range >= 1 && range <= 3 ); + + exec->codeRangeTable[range - 1].base = (FT_Byte*)base; + exec->codeRangeTable[range - 1].size = length; + + return TT_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* TT_Clear_CodeRange */ + /* */ + /* <Description> */ + /* Clears a code range. */ + /* */ + /* <Input> */ + /* range :: The code range index. */ + /* */ + /* <InOut> */ + /* exec :: The target execution context. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* Does not set the Error variable. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + TT_Clear_CodeRange( TT_ExecContext exec, + FT_Int range ) + { + FT_ASSERT( range >= 1 && range <= 3 ); + + exec->codeRangeTable[range - 1].base = NULL; + exec->codeRangeTable[range - 1].size = 0; + + return TT_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* EXECUTION CONTEXT ROUTINES */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* TT_Done_Context */ + /* */ + /* <Description> */ + /* Destroys a given context. */ + /* */ + /* <Input> */ + /* exec :: A handle to the target execution context. */ + /* */ + /* memory :: A handle to the parent memory object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* Only the glyph loader and debugger should call this function. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + TT_Done_Context( TT_ExecContext exec ) + { + FT_Memory memory = exec->memory; + + + /* points zone */ + exec->maxPoints = 0; + exec->maxContours = 0; + + /* free stack */ + FT_FREE( exec->stack ); + exec->stackSize = 0; + + /* free call stack */ + FT_FREE( exec->callStack ); + exec->callSize = 0; + exec->callTop = 0; + + /* free glyph code range */ + FT_FREE( exec->glyphIns ); + exec->glyphSize = 0; + + exec->size = NULL; + exec->face = NULL; + + FT_FREE( exec ); + + return TT_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Init_Context */ + /* */ + /* <Description> */ + /* Initializes a context object. */ + /* */ + /* <Input> */ + /* memory :: A handle to the parent memory object. */ + /* */ + /* <InOut> */ + /* exec :: A handle to the target execution context. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + static FT_Error + Init_Context( TT_ExecContext exec, + FT_Memory memory ) + { + FT_Error error; + + + FT_TRACE1(( "Init_Context: new object at 0x%08p\n", exec )); + + exec->memory = memory; + exec->callSize = 32; + + if ( FT_NEW_ARRAY( exec->callStack, exec->callSize ) ) + goto Fail_Memory; + + /* all values in the context are set to 0 already, but this is */ + /* here as a remainder */ + exec->maxPoints = 0; + exec->maxContours = 0; + + exec->stackSize = 0; + exec->glyphSize = 0; + + exec->stack = NULL; + exec->glyphIns = NULL; + + exec->face = NULL; + exec->size = NULL; + + return TT_Err_Ok; + + Fail_Memory: + FT_ERROR(( "Init_Context: not enough memory for 0x%08lx\n", + (FT_Long)exec )); + TT_Done_Context( exec ); + + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Update_Max */ + /* */ + /* <Description> */ + /* Checks the size of a buffer and reallocates it if necessary. */ + /* */ + /* <Input> */ + /* memory :: A handle to the parent memory object. */ + /* */ + /* multiplier :: The size in bytes of each element in the buffer. */ + /* */ + /* new_max :: The new capacity (size) of the buffer. */ + /* */ + /* <InOut> */ + /* size :: The address of the buffer's current size expressed */ + /* in elements. */ + /* */ + /* buff :: The address of the buffer base pointer. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + static FT_Error + Update_Max( FT_Memory memory, + FT_ULong* size, + FT_Long multiplier, + void* _pbuff, + FT_ULong new_max ) + { + FT_Error error; + void** pbuff = (void**)_pbuff; + + + if ( *size < new_max ) + { + if ( FT_REALLOC( *pbuff, *size * multiplier, new_max * multiplier ) ) + return error; + *size = new_max; + } + + return TT_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* TT_Load_Context */ + /* */ + /* <Description> */ + /* Prepare an execution context for glyph hinting. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face object. */ + /* */ + /* size :: A handle to the source size object. */ + /* */ + /* <InOut> */ + /* exec :: A handle to the target execution context. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* Only the glyph loader and debugger should call this function. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + TT_Load_Context( TT_ExecContext exec, + TT_Face face, + TT_Size size ) + { + FT_Int i; + FT_ULong tmp; + TT_MaxProfile* maxp; + FT_Error error; + + + exec->face = face; + maxp = &face->max_profile; + exec->size = size; + + if ( size ) + { + exec->numFDefs = size->num_function_defs; + exec->maxFDefs = size->max_function_defs; + exec->numIDefs = size->num_instruction_defs; + exec->maxIDefs = size->max_instruction_defs; + exec->FDefs = size->function_defs; + exec->IDefs = size->instruction_defs; + exec->tt_metrics = size->ttmetrics; + exec->metrics = size->metrics; + + exec->maxFunc = size->max_func; + exec->maxIns = size->max_ins; + + for ( i = 0; i < TT_MAX_CODE_RANGES; i++ ) + exec->codeRangeTable[i] = size->codeRangeTable[i]; + + /* set graphics state */ + exec->GS = size->GS; + + exec->cvtSize = size->cvt_size; + exec->cvt = size->cvt; + + exec->storeSize = size->storage_size; + exec->storage = size->storage; + + exec->twilight = size->twilight; + } + + /* XXX: We reserve a little more elements on the stack to deal safely */ + /* with broken fonts like arialbs, courbs, timesbs, etc. */ + tmp = exec->stackSize; + error = Update_Max( exec->memory, + &tmp, + sizeof ( FT_F26Dot6 ), + (void*)&exec->stack, + maxp->maxStackElements + 32 ); + exec->stackSize = (FT_UInt)tmp; + if ( error ) + return error; + + tmp = exec->glyphSize; + error = Update_Max( exec->memory, + &tmp, + sizeof ( FT_Byte ), + (void*)&exec->glyphIns, + maxp->maxSizeOfInstructions ); + exec->glyphSize = (FT_UShort)tmp; + if ( error ) + return error; + + exec->pts.n_points = 0; + exec->pts.n_contours = 0; + + exec->zp1 = exec->pts; + exec->zp2 = exec->pts; + exec->zp0 = exec->pts; + + exec->instruction_trap = FALSE; + + return TT_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* TT_Save_Context */ + /* */ + /* <Description> */ + /* Saves the code ranges in a `size' object. */ + /* */ + /* <Input> */ + /* exec :: A handle to the source execution context. */ + /* */ + /* <InOut> */ + /* size :: A handle to the target size object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* Only the glyph loader and debugger should call this function. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + TT_Save_Context( TT_ExecContext exec, + TT_Size size ) + { + FT_Int i; + + + /* XXXX: Will probably disappear soon with all the code range */ + /* management, which is now rather obsolete. */ + /* */ + size->num_function_defs = exec->numFDefs; + size->num_instruction_defs = exec->numIDefs; + + size->max_func = exec->maxFunc; + size->max_ins = exec->maxIns; + + for ( i = 0; i < TT_MAX_CODE_RANGES; i++ ) + size->codeRangeTable[i] = exec->codeRangeTable[i]; + + return TT_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* TT_Run_Context */ + /* */ + /* <Description> */ + /* Executes one or more instructions in the execution context. */ + /* */ + /* <Input> */ + /* debug :: A Boolean flag. If set, the function sets some internal */ + /* variables and returns immediately, otherwise TT_RunIns() */ + /* is called. */ + /* */ + /* This is commented out currently. */ + /* */ + /* <Input> */ + /* exec :: A handle to the target execution context. */ + /* */ + /* <Return> */ + /* TrueType error code. 0 means success. */ + /* */ + /* <Note> */ + /* Only the glyph loader and debugger should call this function. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + TT_Run_Context( TT_ExecContext exec, + FT_Bool debug ) + { + FT_Error error; + + + if ( ( error = TT_Goto_CodeRange( exec, tt_coderange_glyph, 0 ) ) + != TT_Err_Ok ) + return error; + + exec->zp0 = exec->pts; + exec->zp1 = exec->pts; + exec->zp2 = exec->pts; + + exec->GS.gep0 = 1; + exec->GS.gep1 = 1; + exec->GS.gep2 = 1; + + exec->GS.projVector.x = 0x4000; + exec->GS.projVector.y = 0x0000; + + exec->GS.freeVector = exec->GS.projVector; + exec->GS.dualVector = exec->GS.projVector; + +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING + exec->GS.both_x_axis = TRUE; +#endif + + exec->GS.round_state = 1; + exec->GS.loop = 1; + + /* some glyphs leave something on the stack. so we clean it */ + /* before a new execution. */ + exec->top = 0; + exec->callTop = 0; + +#if 1 + FT_UNUSED( debug ); + + return exec->face->interpreter( exec ); +#else + if ( !debug ) + return TT_RunIns( exec ); + else + return TT_Err_Ok; +#endif + } + + + /* The default value for `scan_control' is documented as FALSE in the */ + /* TrueType specification. This is confusing since it implies a */ + /* Boolean value. However, this is not the case, thus both the */ + /* default values of our `scan_type' and `scan_control' fields (which */ + /* the documentation's `scan_control' variable is split into) are */ + /* zero. */ + + const TT_GraphicsState tt_default_graphics_state = + { + 0, 0, 0, + { 0x4000, 0 }, + { 0x4000, 0 }, + { 0x4000, 0 }, + +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING + TRUE, +#endif + + 1, 64, 1, + TRUE, 68, 0, 0, 9, 3, + 0, FALSE, 0, 1, 1, 1 + }; + + + /* documentation is in ttinterp.h */ + + FT_EXPORT_DEF( TT_ExecContext ) + TT_New_Context( TT_Driver driver ) + { + TT_ExecContext exec; + FT_Memory memory; + + + memory = driver->root.root.memory; + exec = driver->context; + + if ( !driver->context ) + { + FT_Error error; + + + /* allocate object */ + if ( FT_NEW( exec ) ) + goto Fail; + + /* initialize it; in case of error this deallocates `exec' too */ + error = Init_Context( exec, memory ); + if ( error ) + goto Fail; + + /* store it into the driver */ + driver->context = exec; + } + + return driver->context; + + Fail: + return NULL; + } + + + /*************************************************************************/ + /* */ + /* Before an opcode is executed, the interpreter verifies that there are */ + /* enough arguments on the stack, with the help of the `Pop_Push_Count' */ + /* table. */ + /* */ + /* For each opcode, the first column gives the number of arguments that */ + /* are popped from the stack; the second one gives the number of those */ + /* that are pushed in result. */ + /* */ + /* Opcodes which have a varying number of parameters in the data stream */ + /* (NPUSHB, NPUSHW) are handled specially; they have a negative value in */ + /* the `opcode_length' table, and the value in `Pop_Push_Count' is set */ + /* to zero. */ + /* */ + /*************************************************************************/ + + +#undef PACK +#define PACK( x, y ) ( ( x << 4 ) | y ) + + + static + const FT_Byte Pop_Push_Count[256] = + { + /* opcodes are gathered in groups of 16 */ + /* please keep the spaces as they are */ + + /* SVTCA y */ PACK( 0, 0 ), + /* SVTCA x */ PACK( 0, 0 ), + /* SPvTCA y */ PACK( 0, 0 ), + /* SPvTCA x */ PACK( 0, 0 ), + /* SFvTCA y */ PACK( 0, 0 ), + /* SFvTCA x */ PACK( 0, 0 ), + /* SPvTL // */ PACK( 2, 0 ), + /* SPvTL + */ PACK( 2, 0 ), + /* SFvTL // */ PACK( 2, 0 ), + /* SFvTL + */ PACK( 2, 0 ), + /* SPvFS */ PACK( 2, 0 ), + /* SFvFS */ PACK( 2, 0 ), + /* GPV */ PACK( 0, 2 ), + /* GFV */ PACK( 0, 2 ), + /* SFvTPv */ PACK( 0, 0 ), + /* ISECT */ PACK( 5, 0 ), + + /* SRP0 */ PACK( 1, 0 ), + /* SRP1 */ PACK( 1, 0 ), + /* SRP2 */ PACK( 1, 0 ), + /* SZP0 */ PACK( 1, 0 ), + /* SZP1 */ PACK( 1, 0 ), + /* SZP2 */ PACK( 1, 0 ), + /* SZPS */ PACK( 1, 0 ), + /* SLOOP */ PACK( 1, 0 ), + /* RTG */ PACK( 0, 0 ), + /* RTHG */ PACK( 0, 0 ), + /* SMD */ PACK( 1, 0 ), + /* ELSE */ PACK( 0, 0 ), + /* JMPR */ PACK( 1, 0 ), + /* SCvTCi */ PACK( 1, 0 ), + /* SSwCi */ PACK( 1, 0 ), + /* SSW */ PACK( 1, 0 ), + + /* DUP */ PACK( 1, 2 ), + /* POP */ PACK( 1, 0 ), + /* CLEAR */ PACK( 0, 0 ), + /* SWAP */ PACK( 2, 2 ), + /* DEPTH */ PACK( 0, 1 ), + /* CINDEX */ PACK( 1, 1 ), + /* MINDEX */ PACK( 1, 0 ), + /* AlignPTS */ PACK( 2, 0 ), + /* INS_$28 */ PACK( 0, 0 ), + /* UTP */ PACK( 1, 0 ), + /* LOOPCALL */ PACK( 2, 0 ), + /* CALL */ PACK( 1, 0 ), + /* FDEF */ PACK( 1, 0 ), + /* ENDF */ PACK( 0, 0 ), + /* MDAP[0] */ PACK( 1, 0 ), + /* MDAP[1] */ PACK( 1, 0 ), + + /* IUP[0] */ PACK( 0, 0 ), + /* IUP[1] */ PACK( 0, 0 ), + /* SHP[0] */ PACK( 0, 0 ), + /* SHP[1] */ PACK( 0, 0 ), + /* SHC[0] */ PACK( 1, 0 ), + /* SHC[1] */ PACK( 1, 0 ), + /* SHZ[0] */ PACK( 1, 0 ), + /* SHZ[1] */ PACK( 1, 0 ), + /* SHPIX */ PACK( 1, 0 ), + /* IP */ PACK( 0, 0 ), + /* MSIRP[0] */ PACK( 2, 0 ), + /* MSIRP[1] */ PACK( 2, 0 ), + /* AlignRP */ PACK( 0, 0 ), + /* RTDG */ PACK( 0, 0 ), + /* MIAP[0] */ PACK( 2, 0 ), + /* MIAP[1] */ PACK( 2, 0 ), + + /* NPushB */ PACK( 0, 0 ), + /* NPushW */ PACK( 0, 0 ), + /* WS */ PACK( 2, 0 ), + /* RS */ PACK( 1, 1 ), + /* WCvtP */ PACK( 2, 0 ), + /* RCvt */ PACK( 1, 1 ), + /* GC[0] */ PACK( 1, 1 ), + /* GC[1] */ PACK( 1, 1 ), + /* SCFS */ PACK( 2, 0 ), + /* MD[0] */ PACK( 2, 1 ), + /* MD[1] */ PACK( 2, 1 ), + /* MPPEM */ PACK( 0, 1 ), + /* MPS */ PACK( 0, 1 ), + /* FlipON */ PACK( 0, 0 ), + /* FlipOFF */ PACK( 0, 0 ), + /* DEBUG */ PACK( 1, 0 ), + + /* LT */ PACK( 2, 1 ), + /* LTEQ */ PACK( 2, 1 ), + /* GT */ PACK( 2, 1 ), + /* GTEQ */ PACK( 2, 1 ), + /* EQ */ PACK( 2, 1 ), + /* NEQ */ PACK( 2, 1 ), + /* ODD */ PACK( 1, 1 ), + /* EVEN */ PACK( 1, 1 ), + /* IF */ PACK( 1, 0 ), + /* EIF */ PACK( 0, 0 ), + /* AND */ PACK( 2, 1 ), + /* OR */ PACK( 2, 1 ), + /* NOT */ PACK( 1, 1 ), + /* DeltaP1 */ PACK( 1, 0 ), + /* SDB */ PACK( 1, 0 ), + /* SDS */ PACK( 1, 0 ), + + /* ADD */ PACK( 2, 1 ), + /* SUB */ PACK( 2, 1 ), + /* DIV */ PACK( 2, 1 ), + /* MUL */ PACK( 2, 1 ), + /* ABS */ PACK( 1, 1 ), + /* NEG */ PACK( 1, 1 ), + /* FLOOR */ PACK( 1, 1 ), + /* CEILING */ PACK( 1, 1 ), + /* ROUND[0] */ PACK( 1, 1 ), + /* ROUND[1] */ PACK( 1, 1 ), + /* ROUND[2] */ PACK( 1, 1 ), + /* ROUND[3] */ PACK( 1, 1 ), + /* NROUND[0] */ PACK( 1, 1 ), + /* NROUND[1] */ PACK( 1, 1 ), + /* NROUND[2] */ PACK( 1, 1 ), + /* NROUND[3] */ PACK( 1, 1 ), + + /* WCvtF */ PACK( 2, 0 ), + /* DeltaP2 */ PACK( 1, 0 ), + /* DeltaP3 */ PACK( 1, 0 ), + /* DeltaCn[0] */ PACK( 1, 0 ), + /* DeltaCn[1] */ PACK( 1, 0 ), + /* DeltaCn[2] */ PACK( 1, 0 ), + /* SROUND */ PACK( 1, 0 ), + /* S45Round */ PACK( 1, 0 ), + /* JROT */ PACK( 2, 0 ), + /* JROF */ PACK( 2, 0 ), + /* ROFF */ PACK( 0, 0 ), + /* INS_$7B */ PACK( 0, 0 ), + /* RUTG */ PACK( 0, 0 ), + /* RDTG */ PACK( 0, 0 ), + /* SANGW */ PACK( 1, 0 ), + /* AA */ PACK( 1, 0 ), + + /* FlipPT */ PACK( 0, 0 ), + /* FlipRgON */ PACK( 2, 0 ), + /* FlipRgOFF */ PACK( 2, 0 ), + /* INS_$83 */ PACK( 0, 0 ), + /* INS_$84 */ PACK( 0, 0 ), + /* ScanCTRL */ PACK( 1, 0 ), + /* SDVPTL[0] */ PACK( 2, 0 ), + /* SDVPTL[1] */ PACK( 2, 0 ), + /* GetINFO */ PACK( 1, 1 ), + /* IDEF */ PACK( 1, 0 ), + /* ROLL */ PACK( 3, 3 ), + /* MAX */ PACK( 2, 1 ), + /* MIN */ PACK( 2, 1 ), + /* ScanTYPE */ PACK( 1, 0 ), + /* InstCTRL */ PACK( 2, 0 ), + /* INS_$8F */ PACK( 0, 0 ), + + /* INS_$90 */ PACK( 0, 0 ), + /* INS_$91 */ PACK( 0, 0 ), + /* INS_$92 */ PACK( 0, 0 ), + /* INS_$93 */ PACK( 0, 0 ), + /* INS_$94 */ PACK( 0, 0 ), + /* INS_$95 */ PACK( 0, 0 ), + /* INS_$96 */ PACK( 0, 0 ), + /* INS_$97 */ PACK( 0, 0 ), + /* INS_$98 */ PACK( 0, 0 ), + /* INS_$99 */ PACK( 0, 0 ), + /* INS_$9A */ PACK( 0, 0 ), + /* INS_$9B */ PACK( 0, 0 ), + /* INS_$9C */ PACK( 0, 0 ), + /* INS_$9D */ PACK( 0, 0 ), + /* INS_$9E */ PACK( 0, 0 ), + /* INS_$9F */ PACK( 0, 0 ), + + /* INS_$A0 */ PACK( 0, 0 ), + /* INS_$A1 */ PACK( 0, 0 ), + /* INS_$A2 */ PACK( 0, 0 ), + /* INS_$A3 */ PACK( 0, 0 ), + /* INS_$A4 */ PACK( 0, 0 ), + /* INS_$A5 */ PACK( 0, 0 ), + /* INS_$A6 */ PACK( 0, 0 ), + /* INS_$A7 */ PACK( 0, 0 ), + /* INS_$A8 */ PACK( 0, 0 ), + /* INS_$A9 */ PACK( 0, 0 ), + /* INS_$AA */ PACK( 0, 0 ), + /* INS_$AB */ PACK( 0, 0 ), + /* INS_$AC */ PACK( 0, 0 ), + /* INS_$AD */ PACK( 0, 0 ), + /* INS_$AE */ PACK( 0, 0 ), + /* INS_$AF */ PACK( 0, 0 ), + + /* PushB[0] */ PACK( 0, 1 ), + /* PushB[1] */ PACK( 0, 2 ), + /* PushB[2] */ PACK( 0, 3 ), + /* PushB[3] */ PACK( 0, 4 ), + /* PushB[4] */ PACK( 0, 5 ), + /* PushB[5] */ PACK( 0, 6 ), + /* PushB[6] */ PACK( 0, 7 ), + /* PushB[7] */ PACK( 0, 8 ), + /* PushW[0] */ PACK( 0, 1 ), + /* PushW[1] */ PACK( 0, 2 ), + /* PushW[2] */ PACK( 0, 3 ), + /* PushW[3] */ PACK( 0, 4 ), + /* PushW[4] */ PACK( 0, 5 ), + /* PushW[5] */ PACK( 0, 6 ), + /* PushW[6] */ PACK( 0, 7 ), + /* PushW[7] */ PACK( 0, 8 ), + + /* MDRP[00] */ PACK( 1, 0 ), + /* MDRP[01] */ PACK( 1, 0 ), + /* MDRP[02] */ PACK( 1, 0 ), + /* MDRP[03] */ PACK( 1, 0 ), + /* MDRP[04] */ PACK( 1, 0 ), + /* MDRP[05] */ PACK( 1, 0 ), + /* MDRP[06] */ PACK( 1, 0 ), + /* MDRP[07] */ PACK( 1, 0 ), + /* MDRP[08] */ PACK( 1, 0 ), + /* MDRP[09] */ PACK( 1, 0 ), + /* MDRP[10] */ PACK( 1, 0 ), + /* MDRP[11] */ PACK( 1, 0 ), + /* MDRP[12] */ PACK( 1, 0 ), + /* MDRP[13] */ PACK( 1, 0 ), + /* MDRP[14] */ PACK( 1, 0 ), + /* MDRP[15] */ PACK( 1, 0 ), + + /* MDRP[16] */ PACK( 1, 0 ), + /* MDRP[17] */ PACK( 1, 0 ), + /* MDRP[18] */ PACK( 1, 0 ), + /* MDRP[19] */ PACK( 1, 0 ), + /* MDRP[20] */ PACK( 1, 0 ), + /* MDRP[21] */ PACK( 1, 0 ), + /* MDRP[22] */ PACK( 1, 0 ), + /* MDRP[23] */ PACK( 1, 0 ), + /* MDRP[24] */ PACK( 1, 0 ), + /* MDRP[25] */ PACK( 1, 0 ), + /* MDRP[26] */ PACK( 1, 0 ), + /* MDRP[27] */ PACK( 1, 0 ), + /* MDRP[28] */ PACK( 1, 0 ), + /* MDRP[29] */ PACK( 1, 0 ), + /* MDRP[30] */ PACK( 1, 0 ), + /* MDRP[31] */ PACK( 1, 0 ), + + /* MIRP[00] */ PACK( 2, 0 ), + /* MIRP[01] */ PACK( 2, 0 ), + /* MIRP[02] */ PACK( 2, 0 ), + /* MIRP[03] */ PACK( 2, 0 ), + /* MIRP[04] */ PACK( 2, 0 ), + /* MIRP[05] */ PACK( 2, 0 ), + /* MIRP[06] */ PACK( 2, 0 ), + /* MIRP[07] */ PACK( 2, 0 ), + /* MIRP[08] */ PACK( 2, 0 ), + /* MIRP[09] */ PACK( 2, 0 ), + /* MIRP[10] */ PACK( 2, 0 ), + /* MIRP[11] */ PACK( 2, 0 ), + /* MIRP[12] */ PACK( 2, 0 ), + /* MIRP[13] */ PACK( 2, 0 ), + /* MIRP[14] */ PACK( 2, 0 ), + /* MIRP[15] */ PACK( 2, 0 ), + + /* MIRP[16] */ PACK( 2, 0 ), + /* MIRP[17] */ PACK( 2, 0 ), + /* MIRP[18] */ PACK( 2, 0 ), + /* MIRP[19] */ PACK( 2, 0 ), + /* MIRP[20] */ PACK( 2, 0 ), + /* MIRP[21] */ PACK( 2, 0 ), + /* MIRP[22] */ PACK( 2, 0 ), + /* MIRP[23] */ PACK( 2, 0 ), + /* MIRP[24] */ PACK( 2, 0 ), + /* MIRP[25] */ PACK( 2, 0 ), + /* MIRP[26] */ PACK( 2, 0 ), + /* MIRP[27] */ PACK( 2, 0 ), + /* MIRP[28] */ PACK( 2, 0 ), + /* MIRP[29] */ PACK( 2, 0 ), + /* MIRP[30] */ PACK( 2, 0 ), + /* MIRP[31] */ PACK( 2, 0 ) + }; + + + static + const FT_Char opcode_length[256] = + { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + -1,-2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 3, 4, 5, 6, 7, 8, 9, 3, 5, 7, 9, 11,13,15,17, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 + }; + +#undef PACK + +#if 1 + + static FT_Int32 + TT_MulFix14( FT_Int32 a, + FT_Int b ) + { + FT_Int32 sign; + FT_UInt32 ah, al, mid, lo, hi; + + + sign = a ^ b; + + if ( a < 0 ) + a = -a; + if ( b < 0 ) + b = -b; + + ah = (FT_UInt32)( ( a >> 16 ) & 0xFFFFU ); + al = (FT_UInt32)( a & 0xFFFFU ); + + lo = al * b; + mid = ah * b; + hi = mid >> 16; + mid = ( mid << 16 ) + ( 1 << 13 ); /* rounding */ + lo += mid; + if ( lo < mid ) + hi += 1; + + mid = ( lo >> 14 ) | ( hi << 18 ); + + return sign >= 0 ? (FT_Int32)mid : -(FT_Int32)mid; + } + +#else + + /* compute (a*b)/2^14 with maximal accuracy and rounding */ + static FT_Int32 + TT_MulFix14( FT_Int32 a, + FT_Int b ) + { + FT_Int32 m, s, hi; + FT_UInt32 l, lo; + + + /* compute ax*bx as 64-bit value */ + l = (FT_UInt32)( ( a & 0xFFFFU ) * b ); + m = ( a >> 16 ) * b; + + lo = l + (FT_UInt32)( m << 16 ); + hi = ( m >> 16 ) + ( (FT_Int32)l >> 31 ) + ( lo < l ); + + /* divide the result by 2^14 with rounding */ + s = hi >> 31; + l = lo + (FT_UInt32)s; + hi += s + ( l < lo ); + lo = l; + + l = lo + 0x2000U; + hi += l < lo; + + return ( hi << 18 ) | ( l >> 14 ); + } +#endif + + + /* compute (ax*bx+ay*by)/2^14 with maximal accuracy and rounding */ + static FT_Int32 + TT_DotFix14( FT_Int32 ax, + FT_Int32 ay, + FT_Int bx, + FT_Int by ) + { + FT_Int32 m, s, hi1, hi2, hi; + FT_UInt32 l, lo1, lo2, lo; + + + /* compute ax*bx as 64-bit value */ + l = (FT_UInt32)( ( ax & 0xFFFFU ) * bx ); + m = ( ax >> 16 ) * bx; + + lo1 = l + (FT_UInt32)( m << 16 ); + hi1 = ( m >> 16 ) + ( (FT_Int32)l >> 31 ) + ( lo1 < l ); + + /* compute ay*by as 64-bit value */ + l = (FT_UInt32)( ( ay & 0xFFFFU ) * by ); + m = ( ay >> 16 ) * by; + + lo2 = l + (FT_UInt32)( m << 16 ); + hi2 = ( m >> 16 ) + ( (FT_Int32)l >> 31 ) + ( lo2 < l ); + + /* add them */ + lo = lo1 + lo2; + hi = hi1 + hi2 + ( lo < lo1 ); + + /* divide the result by 2^14 with rounding */ + s = hi >> 31; + l = lo + (FT_UInt32)s; + hi += s + ( l < lo ); + lo = l; + + l = lo + 0x2000U; + hi += ( l < lo ); + + return ( hi << 18 ) | ( l >> 14 ); + } + + + /* return length of given vector */ + +#if 0 + + static FT_Int32 + TT_VecLen( FT_Int32 x, + FT_Int32 y ) + { + FT_Int32 m, hi1, hi2, hi; + FT_UInt32 l, lo1, lo2, lo; + + + /* compute x*x as 64-bit value */ + lo = (FT_UInt32)( x & 0xFFFFU ); + hi = x >> 16; + + l = lo * lo; + m = hi * lo; + hi = hi * hi; + + lo1 = l + (FT_UInt32)( m << 17 ); + hi1 = hi + ( m >> 15 ) + ( lo1 < l ); + + /* compute y*y as 64-bit value */ + lo = (FT_UInt32)( y & 0xFFFFU ); + hi = y >> 16; + + l = lo * lo; + m = hi * lo; + hi = hi * hi; + + lo2 = l + (FT_UInt32)( m << 17 ); + hi2 = hi + ( m >> 15 ) + ( lo2 < l ); + + /* add them to get 'x*x+y*y' as 64-bit value */ + lo = lo1 + lo2; + hi = hi1 + hi2 + ( lo < lo1 ); + + /* compute the square root of this value */ + { + FT_UInt32 root, rem, test_div; + FT_Int count; + + + root = 0; + + { + rem = 0; + count = 32; + do + { + rem = ( rem << 2 ) | ( (FT_UInt32)hi >> 30 ); + hi = ( hi << 2 ) | ( lo >> 30 ); + lo <<= 2; + root <<= 1; + test_div = ( root << 1 ) + 1; + + if ( rem >= test_div ) + { + rem -= test_div; + root += 1; + } + } while ( --count ); + } + + return (FT_Int32)root; + } + } + +#else + + /* this version uses FT_Vector_Length which computes the same value */ + /* much, much faster.. */ + /* */ + static FT_F26Dot6 + TT_VecLen( FT_F26Dot6 X, + FT_F26Dot6 Y ) + { + FT_Vector v; + + + v.x = X; + v.y = Y; + + return FT_Vector_Length( &v ); + } + +#endif + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Current_Ratio */ + /* */ + /* <Description> */ + /* Returns the current aspect ratio scaling factor depending on the */ + /* projection vector's state and device resolutions. */ + /* */ + /* <Return> */ + /* The aspect ratio in 16.16 format, always <= 1.0 . */ + /* */ + static FT_Long + Current_Ratio( EXEC_OP ) + { + if ( !CUR.tt_metrics.ratio ) + { +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING + if ( CUR.face->unpatented_hinting ) + { + if ( CUR.GS.both_x_axis ) + CUR.tt_metrics.ratio = CUR.tt_metrics.x_ratio; + else + CUR.tt_metrics.ratio = CUR.tt_metrics.y_ratio; + } + else +#endif + { + if ( CUR.GS.projVector.y == 0 ) + CUR.tt_metrics.ratio = CUR.tt_metrics.x_ratio; + + else if ( CUR.GS.projVector.x == 0 ) + CUR.tt_metrics.ratio = CUR.tt_metrics.y_ratio; + + else + { + FT_Long x, y; + + + x = TT_MULDIV( CUR.GS.projVector.x, + CUR.tt_metrics.x_ratio, 0x4000 ); + y = TT_MULDIV( CUR.GS.projVector.y, + CUR.tt_metrics.y_ratio, 0x4000 ); + CUR.tt_metrics.ratio = TT_VecLen( x, y ); + } + } + } + return CUR.tt_metrics.ratio; + } + + + static FT_Long + Current_Ppem( EXEC_OP ) + { + return TT_MULFIX( CUR.tt_metrics.ppem, CURRENT_Ratio() ); + } + + + /*************************************************************************/ + /* */ + /* Functions related to the control value table (CVT). */ + /* */ + /*************************************************************************/ + + + FT_CALLBACK_DEF( FT_F26Dot6 ) + Read_CVT( EXEC_OP_ FT_ULong idx ) + { + return CUR.cvt[idx]; + } + + + FT_CALLBACK_DEF( FT_F26Dot6 ) + Read_CVT_Stretched( EXEC_OP_ FT_ULong idx ) + { + return TT_MULFIX( CUR.cvt[idx], CURRENT_Ratio() ); + } + + + FT_CALLBACK_DEF( void ) + Write_CVT( EXEC_OP_ FT_ULong idx, + FT_F26Dot6 value ) + { + CUR.cvt[idx] = value; + } + + + FT_CALLBACK_DEF( void ) + Write_CVT_Stretched( EXEC_OP_ FT_ULong idx, + FT_F26Dot6 value ) + { + CUR.cvt[idx] = FT_DivFix( value, CURRENT_Ratio() ); + } + + + FT_CALLBACK_DEF( void ) + Move_CVT( EXEC_OP_ FT_ULong idx, + FT_F26Dot6 value ) + { + CUR.cvt[idx] += value; + } + + + FT_CALLBACK_DEF( void ) + Move_CVT_Stretched( EXEC_OP_ FT_ULong idx, + FT_F26Dot6 value ) + { + CUR.cvt[idx] += FT_DivFix( value, CURRENT_Ratio() ); + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* GetShortIns */ + /* */ + /* <Description> */ + /* Returns a short integer taken from the instruction stream at */ + /* address IP. */ + /* */ + /* <Return> */ + /* Short read at code[IP]. */ + /* */ + /* <Note> */ + /* This one could become a macro. */ + /* */ + static FT_Short + GetShortIns( EXEC_OP ) + { + /* Reading a byte stream so there is no endianess (DaveP) */ + CUR.IP += 2; + return (FT_Short)( ( CUR.code[CUR.IP - 2] << 8 ) + + CUR.code[CUR.IP - 1] ); + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Ins_Goto_CodeRange */ + /* */ + /* <Description> */ + /* Goes to a certain code range in the instruction stream. */ + /* */ + /* <Input> */ + /* aRange :: The index of the code range. */ + /* */ + /* aIP :: The new IP address in the code range. */ + /* */ + /* <Return> */ + /* SUCCESS or FAILURE. */ + /* */ + static FT_Bool + Ins_Goto_CodeRange( EXEC_OP_ FT_Int aRange, + FT_ULong aIP ) + { + TT_CodeRange* range; + + + if ( aRange < 1 || aRange > 3 ) + { + CUR.error = TT_Err_Bad_Argument; + return FAILURE; + } + + range = &CUR.codeRangeTable[aRange - 1]; + + if ( range->base == NULL ) /* invalid coderange */ + { + CUR.error = TT_Err_Invalid_CodeRange; + return FAILURE; + } + + /* NOTE: Because the last instruction of a program may be a CALL */ + /* which will return to the first byte *after* the code */ + /* range, we test for AIP <= Size, instead of AIP < Size. */ + + if ( aIP > range->size ) + { + CUR.error = TT_Err_Code_Overflow; + return FAILURE; + } + + CUR.code = range->base; + CUR.codeSize = range->size; + CUR.IP = aIP; + CUR.curRange = aRange; + + return SUCCESS; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Direct_Move */ + /* */ + /* <Description> */ + /* Moves a point by a given distance along the freedom vector. The */ + /* point will be `touched'. */ + /* */ + /* <Input> */ + /* point :: The index of the point to move. */ + /* */ + /* distance :: The distance to apply. */ + /* */ + /* <InOut> */ + /* zone :: The affected glyph zone. */ + /* */ + static void + Direct_Move( EXEC_OP_ TT_GlyphZone zone, + FT_UShort point, + FT_F26Dot6 distance ) + { + FT_F26Dot6 v; + + +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING + FT_ASSERT( !CUR.face->unpatented_hinting ); +#endif + + v = CUR.GS.freeVector.x; + + if ( v != 0 ) + { + zone->cur[point].x += TT_MULDIV( distance, + v * 0x10000L, + CUR.F_dot_P ); + + zone->tags[point] |= FT_CURVE_TAG_TOUCH_X; + } + + v = CUR.GS.freeVector.y; + + if ( v != 0 ) + { + zone->cur[point].y += TT_MULDIV( distance, + v * 0x10000L, + CUR.F_dot_P ); + + zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y; + } + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Direct_Move_Orig */ + /* */ + /* <Description> */ + /* Moves the *original* position of a point by a given distance along */ + /* the freedom vector. Obviously, the point will not be `touched'. */ + /* */ + /* <Input> */ + /* point :: The index of the point to move. */ + /* */ + /* distance :: The distance to apply. */ + /* */ + /* <InOut> */ + /* zone :: The affected glyph zone. */ + /* */ + static void + Direct_Move_Orig( EXEC_OP_ TT_GlyphZone zone, + FT_UShort point, + FT_F26Dot6 distance ) + { + FT_F26Dot6 v; + + +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING + FT_ASSERT( !CUR.face->unpatented_hinting ); +#endif + + v = CUR.GS.freeVector.x; + + if ( v != 0 ) + zone->org[point].x += TT_MULDIV( distance, + v * 0x10000L, + CUR.F_dot_P ); + + v = CUR.GS.freeVector.y; + + if ( v != 0 ) + zone->org[point].y += TT_MULDIV( distance, + v * 0x10000L, + CUR.F_dot_P ); + } + + + /*************************************************************************/ + /* */ + /* Special versions of Direct_Move() */ + /* */ + /* The following versions are used whenever both vectors are both */ + /* along one of the coordinate unit vectors, i.e. in 90% of the cases. */ + /* */ + /*************************************************************************/ + + + static void + Direct_Move_X( EXEC_OP_ TT_GlyphZone zone, + FT_UShort point, + FT_F26Dot6 distance ) + { + FT_UNUSED_EXEC; + + zone->cur[point].x += distance; + zone->tags[point] |= FT_CURVE_TAG_TOUCH_X; + } + + + static void + Direct_Move_Y( EXEC_OP_ TT_GlyphZone zone, + FT_UShort point, + FT_F26Dot6 distance ) + { + FT_UNUSED_EXEC; + + zone->cur[point].y += distance; + zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y; + } + + + /*************************************************************************/ + /* */ + /* Special versions of Direct_Move_Orig() */ + /* */ + /* The following versions are used whenever both vectors are both */ + /* along one of the coordinate unit vectors, i.e. in 90% of the cases. */ + /* */ + /*************************************************************************/ + + + static void + Direct_Move_Orig_X( EXEC_OP_ TT_GlyphZone zone, + FT_UShort point, + FT_F26Dot6 distance ) + { + FT_UNUSED_EXEC; + + zone->org[point].x += distance; + } + + + static void + Direct_Move_Orig_Y( EXEC_OP_ TT_GlyphZone zone, + FT_UShort point, + FT_F26Dot6 distance ) + { + FT_UNUSED_EXEC; + + zone->org[point].y += distance; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Round_None */ + /* */ + /* <Description> */ + /* Does not round, but adds engine compensation. */ + /* */ + /* <Input> */ + /* distance :: The distance (not) to round. */ + /* */ + /* compensation :: The engine compensation. */ + /* */ + /* <Return> */ + /* The compensated distance. */ + /* */ + /* <Note> */ + /* The TrueType specification says very few about the relationship */ + /* between rounding and engine compensation. However, it seems from */ + /* the description of super round that we should add the compensation */ + /* before rounding. */ + /* */ + static FT_F26Dot6 + Round_None( EXEC_OP_ FT_F26Dot6 distance, + FT_F26Dot6 compensation ) + { + FT_F26Dot6 val; + + FT_UNUSED_EXEC; + + + if ( distance >= 0 ) + { + val = distance + compensation; + if ( distance && val < 0 ) + val = 0; + } + else { + val = distance - compensation; + if ( val > 0 ) + val = 0; + } + return val; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Round_To_Grid */ + /* */ + /* <Description> */ + /* Rounds value to grid after adding engine compensation. */ + /* */ + /* <Input> */ + /* distance :: The distance to round. */ + /* */ + /* compensation :: The engine compensation. */ + /* */ + /* <Return> */ + /* Rounded distance. */ + /* */ + static FT_F26Dot6 + Round_To_Grid( EXEC_OP_ FT_F26Dot6 distance, + FT_F26Dot6 compensation ) + { + FT_F26Dot6 val; + + FT_UNUSED_EXEC; + + + if ( distance >= 0 ) + { + val = distance + compensation + 32; + if ( distance && val > 0 ) + val &= ~63; + else + val = 0; + } + else + { + val = -FT_PIX_ROUND( compensation - distance ); + if ( val > 0 ) + val = 0; + } + + return val; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Round_To_Half_Grid */ + /* */ + /* <Description> */ + /* Rounds value to half grid after adding engine compensation. */ + /* */ + /* <Input> */ + /* distance :: The distance to round. */ + /* */ + /* compensation :: The engine compensation. */ + /* */ + /* <Return> */ + /* Rounded distance. */ + /* */ + static FT_F26Dot6 + Round_To_Half_Grid( EXEC_OP_ FT_F26Dot6 distance, + FT_F26Dot6 compensation ) + { + FT_F26Dot6 val; + + FT_UNUSED_EXEC; + + + if ( distance >= 0 ) + { + val = FT_PIX_FLOOR( distance + compensation ) + 32; + if ( distance && val < 0 ) + val = 0; + } + else + { + val = -( FT_PIX_FLOOR( compensation - distance ) + 32 ); + if ( val > 0 ) + val = 0; + } + + return val; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Round_Down_To_Grid */ + /* */ + /* <Description> */ + /* Rounds value down to grid after adding engine compensation. */ + /* */ + /* <Input> */ + /* distance :: The distance to round. */ + /* */ + /* compensation :: The engine compensation. */ + /* */ + /* <Return> */ + /* Rounded distance. */ + /* */ + static FT_F26Dot6 + Round_Down_To_Grid( EXEC_OP_ FT_F26Dot6 distance, + FT_F26Dot6 compensation ) + { + FT_F26Dot6 val; + + FT_UNUSED_EXEC; + + + if ( distance >= 0 ) + { + val = distance + compensation; + if ( distance && val > 0 ) + val &= ~63; + else + val = 0; + } + else + { + val = -( ( compensation - distance ) & -64 ); + if ( val > 0 ) + val = 0; + } + + return val; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Round_Up_To_Grid */ + /* */ + /* <Description> */ + /* Rounds value up to grid after adding engine compensation. */ + /* */ + /* <Input> */ + /* distance :: The distance to round. */ + /* */ + /* compensation :: The engine compensation. */ + /* */ + /* <Return> */ + /* Rounded distance. */ + /* */ + static FT_F26Dot6 + Round_Up_To_Grid( EXEC_OP_ FT_F26Dot6 distance, + FT_F26Dot6 compensation ) + { + FT_F26Dot6 val; + + FT_UNUSED_EXEC; + + + if ( distance >= 0 ) + { + val = distance + compensation + 63; + if ( distance && val > 0 ) + val &= ~63; + else + val = 0; + } + else + { + val = - FT_PIX_CEIL( compensation - distance ); + if ( val > 0 ) + val = 0; + } + + return val; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Round_To_Double_Grid */ + /* */ + /* <Description> */ + /* Rounds value to double grid after adding engine compensation. */ + /* */ + /* <Input> */ + /* distance :: The distance to round. */ + /* */ + /* compensation :: The engine compensation. */ + /* */ + /* <Return> */ + /* Rounded distance. */ + /* */ + static FT_F26Dot6 + Round_To_Double_Grid( EXEC_OP_ FT_F26Dot6 distance, + FT_F26Dot6 compensation ) + { + FT_F26Dot6 val; + + FT_UNUSED_EXEC; + + + if ( distance >= 0 ) + { + val = distance + compensation + 16; + if ( distance && val > 0 ) + val &= ~31; + else + val = 0; + } + else + { + val = -FT_PAD_ROUND( compensation - distance, 32 ); + if ( val > 0 ) + val = 0; + } + + return val; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Round_Super */ + /* */ + /* <Description> */ + /* Super-rounds value to grid after adding engine compensation. */ + /* */ + /* <Input> */ + /* distance :: The distance to round. */ + /* */ + /* compensation :: The engine compensation. */ + /* */ + /* <Return> */ + /* Rounded distance. */ + /* */ + /* <Note> */ + /* The TrueType specification says very few about the relationship */ + /* between rounding and engine compensation. However, it seems from */ + /* the description of super round that we should add the compensation */ + /* before rounding. */ + /* */ + static FT_F26Dot6 + Round_Super( EXEC_OP_ FT_F26Dot6 distance, + FT_F26Dot6 compensation ) + { + FT_F26Dot6 val; + + + if ( distance >= 0 ) + { + val = ( distance - CUR.phase + CUR.threshold + compensation ) & + -CUR.period; + if ( distance && val < 0 ) + val = 0; + val += CUR.phase; + } + else + { + val = -( ( CUR.threshold - CUR.phase - distance + compensation ) & + -CUR.period ); + if ( val > 0 ) + val = 0; + val -= CUR.phase; + } + + return val; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Round_Super_45 */ + /* */ + /* <Description> */ + /* Super-rounds value to grid after adding engine compensation. */ + /* */ + /* <Input> */ + /* distance :: The distance to round. */ + /* */ + /* compensation :: The engine compensation. */ + /* */ + /* <Return> */ + /* Rounded distance. */ + /* */ + /* <Note> */ + /* There is a separate function for Round_Super_45() as we may need */ + /* greater precision. */ + /* */ + static FT_F26Dot6 + Round_Super_45( EXEC_OP_ FT_F26Dot6 distance, + FT_F26Dot6 compensation ) + { + FT_F26Dot6 val; + + + if ( distance >= 0 ) + { + val = ( ( distance - CUR.phase + CUR.threshold + compensation ) / + CUR.period ) * CUR.period; + if ( distance && val < 0 ) + val = 0; + val += CUR.phase; + } + else + { + val = -( ( ( CUR.threshold - CUR.phase - distance + compensation ) / + CUR.period ) * CUR.period ); + if ( val > 0 ) + val = 0; + val -= CUR.phase; + } + + return val; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Compute_Round */ + /* */ + /* <Description> */ + /* Sets the rounding mode. */ + /* */ + /* <Input> */ + /* round_mode :: The rounding mode to be used. */ + /* */ + static void + Compute_Round( EXEC_OP_ FT_Byte round_mode ) + { + switch ( round_mode ) + { + case TT_Round_Off: + CUR.func_round = (TT_Round_Func)Round_None; + break; + + case TT_Round_To_Grid: + CUR.func_round = (TT_Round_Func)Round_To_Grid; + break; + + case TT_Round_Up_To_Grid: + CUR.func_round = (TT_Round_Func)Round_Up_To_Grid; + break; + + case TT_Round_Down_To_Grid: + CUR.func_round = (TT_Round_Func)Round_Down_To_Grid; + break; + + case TT_Round_To_Half_Grid: + CUR.func_round = (TT_Round_Func)Round_To_Half_Grid; + break; + + case TT_Round_To_Double_Grid: + CUR.func_round = (TT_Round_Func)Round_To_Double_Grid; + break; + + case TT_Round_Super: + CUR.func_round = (TT_Round_Func)Round_Super; + break; + + case TT_Round_Super_45: + CUR.func_round = (TT_Round_Func)Round_Super_45; + break; + } + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* SetSuperRound */ + /* */ + /* <Description> */ + /* Sets Super Round parameters. */ + /* */ + /* <Input> */ + /* GridPeriod :: Grid period */ + /* selector :: SROUND opcode */ + /* */ + static void + SetSuperRound( EXEC_OP_ FT_F26Dot6 GridPeriod, + FT_Long selector ) + { + switch ( (FT_Int)( selector & 0xC0 ) ) + { + case 0: + CUR.period = GridPeriod / 2; + break; + + case 0x40: + CUR.period = GridPeriod; + break; + + case 0x80: + CUR.period = GridPeriod * 2; + break; + + /* This opcode is reserved, but... */ + + case 0xC0: + CUR.period = GridPeriod; + break; + } + + switch ( (FT_Int)( selector & 0x30 ) ) + { + case 0: + CUR.phase = 0; + break; + + case 0x10: + CUR.phase = CUR.period / 4; + break; + + case 0x20: + CUR.phase = CUR.period / 2; + break; + + case 0x30: + CUR.phase = CUR.period * 3 / 4; + break; + } + + if ( ( selector & 0x0F ) == 0 ) + CUR.threshold = CUR.period - 1; + else + CUR.threshold = ( (FT_Int)( selector & 0x0F ) - 4 ) * CUR.period / 8; + + CUR.period /= 256; + CUR.phase /= 256; + CUR.threshold /= 256; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Project */ + /* */ + /* <Description> */ + /* Computes the projection of vector given by (v2-v1) along the */ + /* current projection vector. */ + /* */ + /* <Input> */ + /* v1 :: First input vector. */ + /* v2 :: Second input vector. */ + /* */ + /* <Return> */ + /* The distance in F26dot6 format. */ + /* */ + static FT_F26Dot6 + Project( EXEC_OP_ FT_Pos dx, + FT_Pos dy ) + { +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING + FT_ASSERT( !CUR.face->unpatented_hinting ); +#endif + + return TT_DotFix14( (FT_UInt32)dx, (FT_UInt32)dy, + CUR.GS.projVector.x, + CUR.GS.projVector.y ); + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Dual_Project */ + /* */ + /* <Description> */ + /* Computes the projection of the vector given by (v2-v1) along the */ + /* current dual vector. */ + /* */ + /* <Input> */ + /* v1 :: First input vector. */ + /* v2 :: Second input vector. */ + /* */ + /* <Return> */ + /* The distance in F26dot6 format. */ + /* */ + static FT_F26Dot6 + Dual_Project( EXEC_OP_ FT_Pos dx, + FT_Pos dy ) + { + return TT_DotFix14( (FT_UInt32)dx, (FT_UInt32)dy, + CUR.GS.dualVector.x, + CUR.GS.dualVector.y ); + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Project_x */ + /* */ + /* <Description> */ + /* Computes the projection of the vector given by (v2-v1) along the */ + /* horizontal axis. */ + /* */ + /* <Input> */ + /* v1 :: First input vector. */ + /* v2 :: Second input vector. */ + /* */ + /* <Return> */ + /* The distance in F26dot6 format. */ + /* */ + static FT_F26Dot6 + Project_x( EXEC_OP_ FT_Pos dx, + FT_Pos dy ) + { + FT_UNUSED_EXEC; + FT_UNUSED( dy ); + + return dx; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Project_y */ + /* */ + /* <Description> */ + /* Computes the projection of the vector given by (v2-v1) along the */ + /* vertical axis. */ + /* */ + /* <Input> */ + /* v1 :: First input vector. */ + /* v2 :: Second input vector. */ + /* */ + /* <Return> */ + /* The distance in F26dot6 format. */ + /* */ + static FT_F26Dot6 + Project_y( EXEC_OP_ FT_Pos dx, + FT_Pos dy ) + { + FT_UNUSED_EXEC; + FT_UNUSED( dx ); + + return dy; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Compute_Funcs */ + /* */ + /* <Description> */ + /* Computes the projection and movement function pointers according */ + /* to the current graphics state. */ + /* */ + static void + Compute_Funcs( EXEC_OP ) + { +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING + if ( CUR.face->unpatented_hinting ) + { + /* If both vectors point rightwards along the x axis, set */ + /* `both-x-axis' true, otherwise set it false. The x values only */ + /* need be tested because the vector has been normalised to a unit */ + /* vector of length 0x4000 = unity. */ + CUR.GS.both_x_axis = (FT_Bool)( CUR.GS.projVector.x == 0x4000 && + CUR.GS.freeVector.x == 0x4000 ); + + /* Throw away projection and freedom vector information */ + /* because the patents don't allow them to be stored. */ + /* The relevant US Patents are 5155805 and 5325479. */ + CUR.GS.projVector.x = 0; + CUR.GS.projVector.y = 0; + CUR.GS.freeVector.x = 0; + CUR.GS.freeVector.y = 0; + + if ( CUR.GS.both_x_axis ) + { + CUR.func_project = Project_x; + CUR.func_move = Direct_Move_X; + CUR.func_move_orig = Direct_Move_Orig_X; + } + else + { + CUR.func_project = Project_y; + CUR.func_move = Direct_Move_Y; + CUR.func_move_orig = Direct_Move_Orig_Y; + } + + if ( CUR.GS.dualVector.x == 0x4000 ) + CUR.func_dualproj = Project_x; + else + { + if ( CUR.GS.dualVector.y == 0x4000 ) + CUR.func_dualproj = Project_y; + else + CUR.func_dualproj = Dual_Project; + } + + /* Force recalculation of cached aspect ratio */ + CUR.tt_metrics.ratio = 0; + + return; + } +#endif /* TT_CONFIG_OPTION_UNPATENTED_HINTING */ + + if ( CUR.GS.freeVector.x == 0x4000 ) + CUR.F_dot_P = CUR.GS.projVector.x * 0x10000L; + else + { + if ( CUR.GS.freeVector.y == 0x4000 ) + CUR.F_dot_P = CUR.GS.projVector.y * 0x10000L; + else + CUR.F_dot_P = (FT_Long)CUR.GS.projVector.x * CUR.GS.freeVector.x * 4 + + (FT_Long)CUR.GS.projVector.y * CUR.GS.freeVector.y * 4; + } + + if ( CUR.GS.projVector.x == 0x4000 ) + CUR.func_project = (TT_Project_Func)Project_x; + else + { + if ( CUR.GS.projVector.y == 0x4000 ) + CUR.func_project = (TT_Project_Func)Project_y; + else + CUR.func_project = (TT_Project_Func)Project; + } + + if ( CUR.GS.dualVector.x == 0x4000 ) + CUR.func_dualproj = (TT_Project_Func)Project_x; + else + { + if ( CUR.GS.dualVector.y == 0x4000 ) + CUR.func_dualproj = (TT_Project_Func)Project_y; + else + CUR.func_dualproj = (TT_Project_Func)Dual_Project; + } + + CUR.func_move = (TT_Move_Func)Direct_Move; + CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig; + + if ( CUR.F_dot_P == 0x40000000L ) + { + if ( CUR.GS.freeVector.x == 0x4000 ) + { + CUR.func_move = (TT_Move_Func)Direct_Move_X; + CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig_X; + } + else + { + if ( CUR.GS.freeVector.y == 0x4000 ) + { + CUR.func_move = (TT_Move_Func)Direct_Move_Y; + CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig_Y; + } + } + } + + /* at small sizes, F_dot_P can become too small, resulting */ + /* in overflows and `spikes' in a number of glyphs like `w'. */ + + if ( FT_ABS( CUR.F_dot_P ) < 0x4000000L ) + CUR.F_dot_P = 0x40000000L; + + /* Disable cached aspect ratio */ + CUR.tt_metrics.ratio = 0; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Normalize */ + /* */ + /* <Description> */ + /* Norms a vector. */ + /* */ + /* <Input> */ + /* Vx :: The horizontal input vector coordinate. */ + /* Vy :: The vertical input vector coordinate. */ + /* */ + /* <Output> */ + /* R :: The normed unit vector. */ + /* */ + /* <Return> */ + /* Returns FAILURE if a vector parameter is zero. */ + /* */ + /* <Note> */ + /* In case Vx and Vy are both zero, Normalize() returns SUCCESS, and */ + /* R is undefined. */ + /* */ + + + static FT_Bool + Normalize( EXEC_OP_ FT_F26Dot6 Vx, + FT_F26Dot6 Vy, + FT_UnitVector* R ) + { + FT_F26Dot6 W; + FT_Bool S1, S2; + + FT_UNUSED_EXEC; + + + if ( FT_ABS( Vx ) < 0x10000L && FT_ABS( Vy ) < 0x10000L ) + { + Vx *= 0x100; + Vy *= 0x100; + + W = TT_VecLen( Vx, Vy ); + + if ( W == 0 ) + { + /* XXX: UNDOCUMENTED! It seems that it is possible to try */ + /* to normalize the vector (0,0). Return immediately. */ + return SUCCESS; + } + + R->x = (FT_F2Dot14)FT_MulDiv( Vx, 0x4000L, W ); + R->y = (FT_F2Dot14)FT_MulDiv( Vy, 0x4000L, W ); + + return SUCCESS; + } + + W = TT_VecLen( Vx, Vy ); + + Vx = FT_MulDiv( Vx, 0x4000L, W ); + Vy = FT_MulDiv( Vy, 0x4000L, W ); + + W = Vx * Vx + Vy * Vy; + + /* Now, we want that Sqrt( W ) = 0x4000 */ + /* Or 0x10000000 <= W < 0x10004000 */ + + if ( Vx < 0 ) + { + Vx = -Vx; + S1 = TRUE; + } + else + S1 = FALSE; + + if ( Vy < 0 ) + { + Vy = -Vy; + S2 = TRUE; + } + else + S2 = FALSE; + + while ( W < 0x10000000L ) + { + /* We need to increase W by a minimal amount */ + if ( Vx < Vy ) + Vx++; + else + Vy++; + + W = Vx * Vx + Vy * Vy; + } + + while ( W >= 0x10004000L ) + { + /* We need to decrease W by a minimal amount */ + if ( Vx < Vy ) + Vx--; + else + Vy--; + + W = Vx * Vx + Vy * Vy; + } + + /* Note that in various cases, we can only */ + /* compute a Sqrt(W) of 0x3FFF, eg. Vx = Vy */ + + if ( S1 ) + Vx = -Vx; + + if ( S2 ) + Vy = -Vy; + + R->x = (FT_F2Dot14)Vx; /* Type conversion */ + R->y = (FT_F2Dot14)Vy; /* Type conversion */ + + return SUCCESS; + } + + + /*************************************************************************/ + /* */ + /* Here we start with the implementation of the various opcodes. */ + /* */ + /*************************************************************************/ + + + static FT_Bool + Ins_SxVTL( EXEC_OP_ FT_UShort aIdx1, + FT_UShort aIdx2, + FT_Int aOpc, + FT_UnitVector* Vec ) + { + FT_Long A, B, C; + FT_Vector* p1; + FT_Vector* p2; + + + if ( BOUNDS( aIdx1, CUR.zp2.n_points ) || + BOUNDS( aIdx2, CUR.zp1.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return FAILURE; + } + + p1 = CUR.zp1.cur + aIdx2; + p2 = CUR.zp2.cur + aIdx1; + + A = p1->x - p2->x; + B = p1->y - p2->y; + + if ( ( aOpc & 1 ) != 0 ) + { + C = B; /* counter clockwise rotation */ + B = A; + A = -C; + } + + NORMalize( A, B, Vec ); + + return SUCCESS; + } + + + /* When not using the big switch statements, the interpreter uses a */ + /* call table defined later below in this source. Each opcode must */ + /* thus have a corresponding function, even trivial ones. */ + /* */ + /* They are all defined there. */ + +#define DO_SVTCA \ + { \ + FT_Short A, B; \ + \ + \ + A = (FT_Short)( CUR.opcode & 1 ) << 14; \ + B = A ^ (FT_Short)0x4000; \ + \ + CUR.GS.freeVector.x = A; \ + CUR.GS.projVector.x = A; \ + CUR.GS.dualVector.x = A; \ + \ + CUR.GS.freeVector.y = B; \ + CUR.GS.projVector.y = B; \ + CUR.GS.dualVector.y = B; \ + \ + COMPUTE_Funcs(); \ + } + + +#define DO_SPVTCA \ + { \ + FT_Short A, B; \ + \ + \ + A = (FT_Short)( CUR.opcode & 1 ) << 14; \ + B = A ^ (FT_Short)0x4000; \ + \ + CUR.GS.projVector.x = A; \ + CUR.GS.dualVector.x = A; \ + \ + CUR.GS.projVector.y = B; \ + CUR.GS.dualVector.y = B; \ + \ + GUESS_VECTOR( freeVector ); \ + \ + COMPUTE_Funcs(); \ + } + + +#define DO_SFVTCA \ + { \ + FT_Short A, B; \ + \ + \ + A = (FT_Short)( CUR.opcode & 1 ) << 14; \ + B = A ^ (FT_Short)0x4000; \ + \ + CUR.GS.freeVector.x = A; \ + CUR.GS.freeVector.y = B; \ + \ + GUESS_VECTOR( projVector ); \ + \ + COMPUTE_Funcs(); \ + } + + +#define DO_SPVTL \ + if ( INS_SxVTL( (FT_UShort)args[1], \ + (FT_UShort)args[0], \ + CUR.opcode, \ + &CUR.GS.projVector ) == SUCCESS ) \ + { \ + CUR.GS.dualVector = CUR.GS.projVector; \ + GUESS_VECTOR( freeVector ); \ + COMPUTE_Funcs(); \ + } + + +#define DO_SFVTL \ + if ( INS_SxVTL( (FT_UShort)args[1], \ + (FT_UShort)args[0], \ + CUR.opcode, \ + &CUR.GS.freeVector ) == SUCCESS ) \ + { \ + GUESS_VECTOR( projVector ); \ + COMPUTE_Funcs(); \ + } + + +#define DO_SFVTPV \ + GUESS_VECTOR( projVector ); \ + CUR.GS.freeVector = CUR.GS.projVector; \ + COMPUTE_Funcs(); + + +#define DO_SPVFS \ + { \ + FT_Short S; \ + FT_Long X, Y; \ + \ + \ + /* Only use low 16bits, then sign extend */ \ + S = (FT_Short)args[1]; \ + Y = (FT_Long)S; \ + S = (FT_Short)args[0]; \ + X = (FT_Long)S; \ + \ + NORMalize( X, Y, &CUR.GS.projVector ); \ + \ + CUR.GS.dualVector = CUR.GS.projVector; \ + GUESS_VECTOR( freeVector ); \ + COMPUTE_Funcs(); \ + } + + +#define DO_SFVFS \ + { \ + FT_Short S; \ + FT_Long X, Y; \ + \ + \ + /* Only use low 16bits, then sign extend */ \ + S = (FT_Short)args[1]; \ + Y = (FT_Long)S; \ + S = (FT_Short)args[0]; \ + X = S; \ + \ + NORMalize( X, Y, &CUR.GS.freeVector ); \ + GUESS_VECTOR( projVector ); \ + COMPUTE_Funcs(); \ + } + + +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING +#define DO_GPV \ + if ( CUR.face->unpatented_hinting ) \ + { \ + args[0] = CUR.GS.both_x_axis ? 0x4000 : 0; \ + args[1] = CUR.GS.both_x_axis ? 0 : 0x4000; \ + } \ + else \ + { \ + args[0] = CUR.GS.projVector.x; \ + args[1] = CUR.GS.projVector.y; \ + } +#else +#define DO_GPV \ + args[0] = CUR.GS.projVector.x; \ + args[1] = CUR.GS.projVector.y; +#endif + + +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING +#define DO_GFV \ + if ( CUR.face->unpatented_hinting ) \ + { \ + args[0] = CUR.GS.both_x_axis ? 0x4000 : 0; \ + args[1] = CUR.GS.both_x_axis ? 0 : 0x4000; \ + } \ + else \ + { \ + args[0] = CUR.GS.freeVector.x; \ + args[1] = CUR.GS.freeVector.y; \ + } +#else +#define DO_GFV \ + args[0] = CUR.GS.freeVector.x; \ + args[1] = CUR.GS.freeVector.y; +#endif + + +#define DO_SRP0 \ + CUR.GS.rp0 = (FT_UShort)args[0]; + + +#define DO_SRP1 \ + CUR.GS.rp1 = (FT_UShort)args[0]; + + +#define DO_SRP2 \ + CUR.GS.rp2 = (FT_UShort)args[0]; + + +#define DO_RTHG \ + CUR.GS.round_state = TT_Round_To_Half_Grid; \ + CUR.func_round = (TT_Round_Func)Round_To_Half_Grid; + + +#define DO_RTG \ + CUR.GS.round_state = TT_Round_To_Grid; \ + CUR.func_round = (TT_Round_Func)Round_To_Grid; + + +#define DO_RTDG \ + CUR.GS.round_state = TT_Round_To_Double_Grid; \ + CUR.func_round = (TT_Round_Func)Round_To_Double_Grid; + + +#define DO_RUTG \ + CUR.GS.round_state = TT_Round_Up_To_Grid; \ + CUR.func_round = (TT_Round_Func)Round_Up_To_Grid; + + +#define DO_RDTG \ + CUR.GS.round_state = TT_Round_Down_To_Grid; \ + CUR.func_round = (TT_Round_Func)Round_Down_To_Grid; + + +#define DO_ROFF \ + CUR.GS.round_state = TT_Round_Off; \ + CUR.func_round = (TT_Round_Func)Round_None; + + +#define DO_SROUND \ + SET_SuperRound( 0x4000, args[0] ); \ + CUR.GS.round_state = TT_Round_Super; \ + CUR.func_round = (TT_Round_Func)Round_Super; + + +#define DO_S45ROUND \ + SET_SuperRound( 0x2D41, args[0] ); \ + CUR.GS.round_state = TT_Round_Super_45; \ + CUR.func_round = (TT_Round_Func)Round_Super_45; + + +#define DO_SLOOP \ + if ( args[0] < 0 ) \ + CUR.error = TT_Err_Bad_Argument; \ + else \ + CUR.GS.loop = args[0]; + + +#define DO_SMD \ + CUR.GS.minimum_distance = args[0]; + + +#define DO_SCVTCI \ + CUR.GS.control_value_cutin = (FT_F26Dot6)args[0]; + + +#define DO_SSWCI \ + CUR.GS.single_width_cutin = (FT_F26Dot6)args[0]; + + + /* XXX: UNDOCUMENTED! or bug in the Windows engine? */ + /* */ + /* It seems that the value that is read here is */ + /* expressed in 16.16 format rather than in font */ + /* units. */ + /* */ +#define DO_SSW \ + CUR.GS.single_width_value = (FT_F26Dot6)( args[0] >> 10 ); + + +#define DO_FLIPON \ + CUR.GS.auto_flip = TRUE; + + +#define DO_FLIPOFF \ + CUR.GS.auto_flip = FALSE; + + +#define DO_SDB \ + CUR.GS.delta_base = (FT_Short)args[0]; + + +#define DO_SDS \ + CUR.GS.delta_shift = (FT_Short)args[0]; + + +#define DO_MD /* nothing */ + + +#define DO_MPPEM \ + args[0] = CURRENT_Ppem(); + + + /* Note: The pointSize should be irrelevant in a given font program; */ + /* we thus decide to return only the ppem. */ +#if 0 + +#define DO_MPS \ + args[0] = CUR.metrics.pointSize; + +#else + +#define DO_MPS \ + args[0] = CURRENT_Ppem(); + +#endif /* 0 */ + + +#define DO_DUP \ + args[1] = args[0]; + + +#define DO_CLEAR \ + CUR.new_top = 0; + + +#define DO_SWAP \ + { \ + FT_Long L; \ + \ + \ + L = args[0]; \ + args[0] = args[1]; \ + args[1] = L; \ + } + + +#define DO_DEPTH \ + args[0] = CUR.top; + + +#define DO_CINDEX \ + { \ + FT_Long L; \ + \ + \ + L = args[0]; \ + \ + if ( L <= 0 || L > CUR.args ) \ + CUR.error = TT_Err_Invalid_Reference; \ + else \ + args[0] = CUR.stack[CUR.args - L]; \ + } + + +#define DO_JROT \ + if ( args[1] != 0 ) \ + { \ + CUR.IP += args[0]; \ + CUR.step_ins = FALSE; \ + } + + +#define DO_JMPR \ + CUR.IP += args[0]; \ + CUR.step_ins = FALSE; + + +#define DO_JROF \ + if ( args[1] == 0 ) \ + { \ + CUR.IP += args[0]; \ + CUR.step_ins = FALSE; \ + } + + +#define DO_LT \ + args[0] = ( args[0] < args[1] ); + + +#define DO_LTEQ \ + args[0] = ( args[0] <= args[1] ); + + +#define DO_GT \ + args[0] = ( args[0] > args[1] ); + + +#define DO_GTEQ \ + args[0] = ( args[0] >= args[1] ); + + +#define DO_EQ \ + args[0] = ( args[0] == args[1] ); + + +#define DO_NEQ \ + args[0] = ( args[0] != args[1] ); + + +#define DO_ODD \ + args[0] = ( ( CUR_Func_round( args[0], 0 ) & 127 ) == 64 ); + + +#define DO_EVEN \ + args[0] = ( ( CUR_Func_round( args[0], 0 ) & 127 ) == 0 ); + + +#define DO_AND \ + args[0] = ( args[0] && args[1] ); + + +#define DO_OR \ + args[0] = ( args[0] || args[1] ); + + +#define DO_NOT \ + args[0] = !args[0]; + + +#define DO_ADD \ + args[0] += args[1]; + + +#define DO_SUB \ + args[0] -= args[1]; + + +#define DO_DIV \ + if ( args[1] == 0 ) \ + CUR.error = TT_Err_Divide_By_Zero; \ + else \ + args[0] = TT_MULDIV_NO_ROUND( args[0], 64L, args[1] ); + + +#define DO_MUL \ + args[0] = TT_MULDIV( args[0], args[1], 64L ); + + +#define DO_ABS \ + args[0] = FT_ABS( args[0] ); + + +#define DO_NEG \ + args[0] = -args[0]; + + +#define DO_FLOOR \ + args[0] = FT_PIX_FLOOR( args[0] ); + + +#define DO_CEILING \ + args[0] = FT_PIX_CEIL( args[0] ); + + +#define DO_RS \ + { \ + FT_ULong I = (FT_ULong)args[0]; \ + \ + \ + if ( BOUNDS( I, CUR.storeSize ) ) \ + { \ + if ( CUR.pedantic_hinting ) \ + { \ + ARRAY_BOUND_ERROR; \ + } \ + else \ + args[0] = 0; \ + } \ + else \ + args[0] = CUR.storage[I]; \ + } + + +#define DO_WS \ + { \ + FT_ULong I = (FT_ULong)args[0]; \ + \ + \ + if ( BOUNDS( I, CUR.storeSize ) ) \ + { \ + if ( CUR.pedantic_hinting ) \ + { \ + ARRAY_BOUND_ERROR; \ + } \ + } \ + else \ + CUR.storage[I] = args[1]; \ + } + + +#define DO_RCVT \ + { \ + FT_ULong I = (FT_ULong)args[0]; \ + \ + \ + if ( BOUNDS( I, CUR.cvtSize ) ) \ + { \ + if ( CUR.pedantic_hinting ) \ + { \ + ARRAY_BOUND_ERROR; \ + } \ + else \ + args[0] = 0; \ + } \ + else \ + args[0] = CUR_Func_read_cvt( I ); \ + } + + +#define DO_WCVTP \ + { \ + FT_ULong I = (FT_ULong)args[0]; \ + \ + \ + if ( BOUNDS( I, CUR.cvtSize ) ) \ + { \ + if ( CUR.pedantic_hinting ) \ + { \ + ARRAY_BOUND_ERROR; \ + } \ + } \ + else \ + CUR_Func_write_cvt( I, args[1] ); \ + } + + +#define DO_WCVTF \ + { \ + FT_ULong I = (FT_ULong)args[0]; \ + \ + \ + if ( BOUNDS( I, CUR.cvtSize ) ) \ + { \ + if ( CUR.pedantic_hinting ) \ + { \ + ARRAY_BOUND_ERROR; \ + } \ + } \ + else \ + CUR.cvt[I] = TT_MULFIX( args[1], CUR.tt_metrics.scale ); \ + } + + +#define DO_DEBUG \ + CUR.error = TT_Err_Debug_OpCode; + + +#define DO_ROUND \ + args[0] = CUR_Func_round( \ + args[0], \ + CUR.tt_metrics.compensations[CUR.opcode - 0x68] ); + + +#define DO_NROUND \ + args[0] = ROUND_None( args[0], \ + CUR.tt_metrics.compensations[CUR.opcode - 0x6C] ); + + +#define DO_MAX \ + if ( args[1] > args[0] ) \ + args[0] = args[1]; + + +#define DO_MIN \ + if ( args[1] < args[0] ) \ + args[0] = args[1]; + + +#ifndef TT_CONFIG_OPTION_INTERPRETER_SWITCH + + +#undef ARRAY_BOUND_ERROR +#define ARRAY_BOUND_ERROR \ + { \ + CUR.error = TT_Err_Invalid_Reference; \ + return; \ + } + + + /*************************************************************************/ + /* */ + /* SVTCA[a]: Set (F and P) Vectors to Coordinate Axis */ + /* Opcode range: 0x00-0x01 */ + /* Stack: --> */ + /* */ + static void + Ins_SVTCA( INS_ARG ) + { + DO_SVTCA + } + + + /*************************************************************************/ + /* */ + /* SPVTCA[a]: Set PVector to Coordinate Axis */ + /* Opcode range: 0x02-0x03 */ + /* Stack: --> */ + /* */ + static void + Ins_SPVTCA( INS_ARG ) + { + DO_SPVTCA + } + + + /*************************************************************************/ + /* */ + /* SFVTCA[a]: Set FVector to Coordinate Axis */ + /* Opcode range: 0x04-0x05 */ + /* Stack: --> */ + /* */ + static void + Ins_SFVTCA( INS_ARG ) + { + DO_SFVTCA + } + + + /*************************************************************************/ + /* */ + /* SPVTL[a]: Set PVector To Line */ + /* Opcode range: 0x06-0x07 */ + /* Stack: uint32 uint32 --> */ + /* */ + static void + Ins_SPVTL( INS_ARG ) + { + DO_SPVTL + } + + + /*************************************************************************/ + /* */ + /* SFVTL[a]: Set FVector To Line */ + /* Opcode range: 0x08-0x09 */ + /* Stack: uint32 uint32 --> */ + /* */ + static void + Ins_SFVTL( INS_ARG ) + { + DO_SFVTL + } + + + /*************************************************************************/ + /* */ + /* SFVTPV[]: Set FVector To PVector */ + /* Opcode range: 0x0E */ + /* Stack: --> */ + /* */ + static void + Ins_SFVTPV( INS_ARG ) + { + DO_SFVTPV + } + + + /*************************************************************************/ + /* */ + /* SPVFS[]: Set PVector From Stack */ + /* Opcode range: 0x0A */ + /* Stack: f2.14 f2.14 --> */ + /* */ + static void + Ins_SPVFS( INS_ARG ) + { + DO_SPVFS + } + + + /*************************************************************************/ + /* */ + /* SFVFS[]: Set FVector From Stack */ + /* Opcode range: 0x0B */ + /* Stack: f2.14 f2.14 --> */ + /* */ + static void + Ins_SFVFS( INS_ARG ) + { + DO_SFVFS + } + + + /*************************************************************************/ + /* */ + /* GPV[]: Get Projection Vector */ + /* Opcode range: 0x0C */ + /* Stack: ef2.14 --> ef2.14 */ + /* */ + static void + Ins_GPV( INS_ARG ) + { + DO_GPV + } + + + /*************************************************************************/ + /* GFV[]: Get Freedom Vector */ + /* Opcode range: 0x0D */ + /* Stack: ef2.14 --> ef2.14 */ + /* */ + static void + Ins_GFV( INS_ARG ) + { + DO_GFV + } + + + /*************************************************************************/ + /* */ + /* SRP0[]: Set Reference Point 0 */ + /* Opcode range: 0x10 */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_SRP0( INS_ARG ) + { + DO_SRP0 + } + + + /*************************************************************************/ + /* */ + /* SRP1[]: Set Reference Point 1 */ + /* Opcode range: 0x11 */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_SRP1( INS_ARG ) + { + DO_SRP1 + } + + + /*************************************************************************/ + /* */ + /* SRP2[]: Set Reference Point 2 */ + /* Opcode range: 0x12 */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_SRP2( INS_ARG ) + { + DO_SRP2 + } + + + /*************************************************************************/ + /* */ + /* RTHG[]: Round To Half Grid */ + /* Opcode range: 0x19 */ + /* Stack: --> */ + /* */ + static void + Ins_RTHG( INS_ARG ) + { + DO_RTHG + } + + + /*************************************************************************/ + /* */ + /* RTG[]: Round To Grid */ + /* Opcode range: 0x18 */ + /* Stack: --> */ + /* */ + static void + Ins_RTG( INS_ARG ) + { + DO_RTG + } + + + /*************************************************************************/ + /* RTDG[]: Round To Double Grid */ + /* Opcode range: 0x3D */ + /* Stack: --> */ + /* */ + static void + Ins_RTDG( INS_ARG ) + { + DO_RTDG + } + + + /*************************************************************************/ + /* RUTG[]: Round Up To Grid */ + /* Opcode range: 0x7C */ + /* Stack: --> */ + /* */ + static void + Ins_RUTG( INS_ARG ) + { + DO_RUTG + } + + + /*************************************************************************/ + /* */ + /* RDTG[]: Round Down To Grid */ + /* Opcode range: 0x7D */ + /* Stack: --> */ + /* */ + static void + Ins_RDTG( INS_ARG ) + { + DO_RDTG + } + + + /*************************************************************************/ + /* */ + /* ROFF[]: Round OFF */ + /* Opcode range: 0x7A */ + /* Stack: --> */ + /* */ + static void + Ins_ROFF( INS_ARG ) + { + DO_ROFF + } + + + /*************************************************************************/ + /* */ + /* SROUND[]: Super ROUND */ + /* Opcode range: 0x76 */ + /* Stack: Eint8 --> */ + /* */ + static void + Ins_SROUND( INS_ARG ) + { + DO_SROUND + } + + + /*************************************************************************/ + /* */ + /* S45ROUND[]: Super ROUND 45 degrees */ + /* Opcode range: 0x77 */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_S45ROUND( INS_ARG ) + { + DO_S45ROUND + } + + + /*************************************************************************/ + /* */ + /* SLOOP[]: Set LOOP variable */ + /* Opcode range: 0x17 */ + /* Stack: int32? --> */ + /* */ + static void + Ins_SLOOP( INS_ARG ) + { + DO_SLOOP + } + + + /*************************************************************************/ + /* */ + /* SMD[]: Set Minimum Distance */ + /* Opcode range: 0x1A */ + /* Stack: f26.6 --> */ + /* */ + static void + Ins_SMD( INS_ARG ) + { + DO_SMD + } + + + /*************************************************************************/ + /* */ + /* SCVTCI[]: Set Control Value Table Cut In */ + /* Opcode range: 0x1D */ + /* Stack: f26.6 --> */ + /* */ + static void + Ins_SCVTCI( INS_ARG ) + { + DO_SCVTCI + } + + + /*************************************************************************/ + /* */ + /* SSWCI[]: Set Single Width Cut In */ + /* Opcode range: 0x1E */ + /* Stack: f26.6 --> */ + /* */ + static void + Ins_SSWCI( INS_ARG ) + { + DO_SSWCI + } + + + /*************************************************************************/ + /* */ + /* SSW[]: Set Single Width */ + /* Opcode range: 0x1F */ + /* Stack: int32? --> */ + /* */ + static void + Ins_SSW( INS_ARG ) + { + DO_SSW + } + + + /*************************************************************************/ + /* */ + /* FLIPON[]: Set auto-FLIP to ON */ + /* Opcode range: 0x4D */ + /* Stack: --> */ + /* */ + static void + Ins_FLIPON( INS_ARG ) + { + DO_FLIPON + } + + + /*************************************************************************/ + /* */ + /* FLIPOFF[]: Set auto-FLIP to OFF */ + /* Opcode range: 0x4E */ + /* Stack: --> */ + /* */ + static void + Ins_FLIPOFF( INS_ARG ) + { + DO_FLIPOFF + } + + + /*************************************************************************/ + /* */ + /* SANGW[]: Set ANGle Weight */ + /* Opcode range: 0x7E */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_SANGW( INS_ARG ) + { + /* instruction not supported anymore */ + } + + + /*************************************************************************/ + /* */ + /* SDB[]: Set Delta Base */ + /* Opcode range: 0x5E */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_SDB( INS_ARG ) + { + DO_SDB + } + + + /*************************************************************************/ + /* */ + /* SDS[]: Set Delta Shift */ + /* Opcode range: 0x5F */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_SDS( INS_ARG ) + { + DO_SDS + } + + + /*************************************************************************/ + /* */ + /* MPPEM[]: Measure Pixel Per EM */ + /* Opcode range: 0x4B */ + /* Stack: --> Euint16 */ + /* */ + static void + Ins_MPPEM( INS_ARG ) + { + DO_MPPEM + } + + + /*************************************************************************/ + /* */ + /* MPS[]: Measure Point Size */ + /* Opcode range: 0x4C */ + /* Stack: --> Euint16 */ + /* */ + static void + Ins_MPS( INS_ARG ) + { + DO_MPS + } + + + /*************************************************************************/ + /* */ + /* DUP[]: DUPlicate the top stack's element */ + /* Opcode range: 0x20 */ + /* Stack: StkElt --> StkElt StkElt */ + /* */ + static void + Ins_DUP( INS_ARG ) + { + DO_DUP + } + + + /*************************************************************************/ + /* */ + /* POP[]: POP the stack's top element */ + /* Opcode range: 0x21 */ + /* Stack: StkElt --> */ + /* */ + static void + Ins_POP( INS_ARG ) + { + /* nothing to do */ + } + + + /*************************************************************************/ + /* */ + /* CLEAR[]: CLEAR the entire stack */ + /* Opcode range: 0x22 */ + /* Stack: StkElt... --> */ + /* */ + static void + Ins_CLEAR( INS_ARG ) + { + DO_CLEAR + } + + + /*************************************************************************/ + /* */ + /* SWAP[]: SWAP the stack's top two elements */ + /* Opcode range: 0x23 */ + /* Stack: 2 * StkElt --> 2 * StkElt */ + /* */ + static void + Ins_SWAP( INS_ARG ) + { + DO_SWAP + } + + + /*************************************************************************/ + /* */ + /* DEPTH[]: return the stack DEPTH */ + /* Opcode range: 0x24 */ + /* Stack: --> uint32 */ + /* */ + static void + Ins_DEPTH( INS_ARG ) + { + DO_DEPTH + } + + + /*************************************************************************/ + /* */ + /* CINDEX[]: Copy INDEXed element */ + /* Opcode range: 0x25 */ + /* Stack: int32 --> StkElt */ + /* */ + static void + Ins_CINDEX( INS_ARG ) + { + DO_CINDEX + } + + + /*************************************************************************/ + /* */ + /* EIF[]: End IF */ + /* Opcode range: 0x59 */ + /* Stack: --> */ + /* */ + static void + Ins_EIF( INS_ARG ) + { + /* nothing to do */ + } + + + /*************************************************************************/ + /* */ + /* JROT[]: Jump Relative On True */ + /* Opcode range: 0x78 */ + /* Stack: StkElt int32 --> */ + /* */ + static void + Ins_JROT( INS_ARG ) + { + DO_JROT + } + + + /*************************************************************************/ + /* */ + /* JMPR[]: JuMP Relative */ + /* Opcode range: 0x1C */ + /* Stack: int32 --> */ + /* */ + static void + Ins_JMPR( INS_ARG ) + { + DO_JMPR + } + + + /*************************************************************************/ + /* */ + /* JROF[]: Jump Relative On False */ + /* Opcode range: 0x79 */ + /* Stack: StkElt int32 --> */ + /* */ + static void + Ins_JROF( INS_ARG ) + { + DO_JROF + } + + + /*************************************************************************/ + /* */ + /* LT[]: Less Than */ + /* Opcode range: 0x50 */ + /* Stack: int32? int32? --> bool */ + /* */ + static void + Ins_LT( INS_ARG ) + { + DO_LT + } + + + /*************************************************************************/ + /* */ + /* LTEQ[]: Less Than or EQual */ + /* Opcode range: 0x51 */ + /* Stack: int32? int32? --> bool */ + /* */ + static void + Ins_LTEQ( INS_ARG ) + { + DO_LTEQ + } + + + /*************************************************************************/ + /* */ + /* GT[]: Greater Than */ + /* Opcode range: 0x52 */ + /* Stack: int32? int32? --> bool */ + /* */ + static void + Ins_GT( INS_ARG ) + { + DO_GT + } + + + /*************************************************************************/ + /* */ + /* GTEQ[]: Greater Than or EQual */ + /* Opcode range: 0x53 */ + /* Stack: int32? int32? --> bool */ + /* */ + static void + Ins_GTEQ( INS_ARG ) + { + DO_GTEQ + } + + + /*************************************************************************/ + /* */ + /* EQ[]: EQual */ + /* Opcode range: 0x54 */ + /* Stack: StkElt StkElt --> bool */ + /* */ + static void + Ins_EQ( INS_ARG ) + { + DO_EQ + } + + + /*************************************************************************/ + /* */ + /* NEQ[]: Not EQual */ + /* Opcode range: 0x55 */ + /* Stack: StkElt StkElt --> bool */ + /* */ + static void + Ins_NEQ( INS_ARG ) + { + DO_NEQ + } + + + /*************************************************************************/ + /* */ + /* ODD[]: Is ODD */ + /* Opcode range: 0x56 */ + /* Stack: f26.6 --> bool */ + /* */ + static void + Ins_ODD( INS_ARG ) + { + DO_ODD + } + + + /*************************************************************************/ + /* */ + /* EVEN[]: Is EVEN */ + /* Opcode range: 0x57 */ + /* Stack: f26.6 --> bool */ + /* */ + static void + Ins_EVEN( INS_ARG ) + { + DO_EVEN + } + + + /*************************************************************************/ + /* */ + /* AND[]: logical AND */ + /* Opcode range: 0x5A */ + /* Stack: uint32 uint32 --> uint32 */ + /* */ + static void + Ins_AND( INS_ARG ) + { + DO_AND + } + + + /*************************************************************************/ + /* */ + /* OR[]: logical OR */ + /* Opcode range: 0x5B */ + /* Stack: uint32 uint32 --> uint32 */ + /* */ + static void + Ins_OR( INS_ARG ) + { + DO_OR + } + + + /*************************************************************************/ + /* */ + /* NOT[]: logical NOT */ + /* Opcode range: 0x5C */ + /* Stack: StkElt --> uint32 */ + /* */ + static void + Ins_NOT( INS_ARG ) + { + DO_NOT + } + + + /*************************************************************************/ + /* */ + /* ADD[]: ADD */ + /* Opcode range: 0x60 */ + /* Stack: f26.6 f26.6 --> f26.6 */ + /* */ + static void + Ins_ADD( INS_ARG ) + { + DO_ADD + } + + + /*************************************************************************/ + /* */ + /* SUB[]: SUBtract */ + /* Opcode range: 0x61 */ + /* Stack: f26.6 f26.6 --> f26.6 */ + /* */ + static void + Ins_SUB( INS_ARG ) + { + DO_SUB + } + + + /*************************************************************************/ + /* */ + /* DIV[]: DIVide */ + /* Opcode range: 0x62 */ + /* Stack: f26.6 f26.6 --> f26.6 */ + /* */ + static void + Ins_DIV( INS_ARG ) + { + DO_DIV + } + + + /*************************************************************************/ + /* */ + /* MUL[]: MULtiply */ + /* Opcode range: 0x63 */ + /* Stack: f26.6 f26.6 --> f26.6 */ + /* */ + static void + Ins_MUL( INS_ARG ) + { + DO_MUL + } + + + /*************************************************************************/ + /* */ + /* ABS[]: ABSolute value */ + /* Opcode range: 0x64 */ + /* Stack: f26.6 --> f26.6 */ + /* */ + static void + Ins_ABS( INS_ARG ) + { + DO_ABS + } + + + /*************************************************************************/ + /* */ + /* NEG[]: NEGate */ + /* Opcode range: 0x65 */ + /* Stack: f26.6 --> f26.6 */ + /* */ + static void + Ins_NEG( INS_ARG ) + { + DO_NEG + } + + + /*************************************************************************/ + /* */ + /* FLOOR[]: FLOOR */ + /* Opcode range: 0x66 */ + /* Stack: f26.6 --> f26.6 */ + /* */ + static void + Ins_FLOOR( INS_ARG ) + { + DO_FLOOR + } + + + /*************************************************************************/ + /* */ + /* CEILING[]: CEILING */ + /* Opcode range: 0x67 */ + /* Stack: f26.6 --> f26.6 */ + /* */ + static void + Ins_CEILING( INS_ARG ) + { + DO_CEILING + } + + + /*************************************************************************/ + /* */ + /* RS[]: Read Store */ + /* Opcode range: 0x43 */ + /* Stack: uint32 --> uint32 */ + /* */ + static void + Ins_RS( INS_ARG ) + { + DO_RS + } + + + /*************************************************************************/ + /* */ + /* WS[]: Write Store */ + /* Opcode range: 0x42 */ + /* Stack: uint32 uint32 --> */ + /* */ + static void + Ins_WS( INS_ARG ) + { + DO_WS + } + + + /*************************************************************************/ + /* */ + /* WCVTP[]: Write CVT in Pixel units */ + /* Opcode range: 0x44 */ + /* Stack: f26.6 uint32 --> */ + /* */ + static void + Ins_WCVTP( INS_ARG ) + { + DO_WCVTP + } + + + /*************************************************************************/ + /* */ + /* WCVTF[]: Write CVT in Funits */ + /* Opcode range: 0x70 */ + /* Stack: uint32 uint32 --> */ + /* */ + static void + Ins_WCVTF( INS_ARG ) + { + DO_WCVTF + } + + + /*************************************************************************/ + /* */ + /* RCVT[]: Read CVT */ + /* Opcode range: 0x45 */ + /* Stack: uint32 --> f26.6 */ + /* */ + static void + Ins_RCVT( INS_ARG ) + { + DO_RCVT + } + + + /*************************************************************************/ + /* */ + /* AA[]: Adjust Angle */ + /* Opcode range: 0x7F */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_AA( INS_ARG ) + { + /* intentionally no longer supported */ + } + + + /*************************************************************************/ + /* */ + /* DEBUG[]: DEBUG. Unsupported. */ + /* Opcode range: 0x4F */ + /* Stack: uint32 --> */ + /* */ + /* Note: The original instruction pops a value from the stack. */ + /* */ + static void + Ins_DEBUG( INS_ARG ) + { + DO_DEBUG + } + + + /*************************************************************************/ + /* */ + /* ROUND[ab]: ROUND value */ + /* Opcode range: 0x68-0x6B */ + /* Stack: f26.6 --> f26.6 */ + /* */ + static void + Ins_ROUND( INS_ARG ) + { + DO_ROUND + } + + + /*************************************************************************/ + /* */ + /* NROUND[ab]: No ROUNDing of value */ + /* Opcode range: 0x6C-0x6F */ + /* Stack: f26.6 --> f26.6 */ + /* */ + static void + Ins_NROUND( INS_ARG ) + { + DO_NROUND + } + + + /*************************************************************************/ + /* */ + /* MAX[]: MAXimum */ + /* Opcode range: 0x68 */ + /* Stack: int32? int32? --> int32 */ + /* */ + static void + Ins_MAX( INS_ARG ) + { + DO_MAX + } + + + /*************************************************************************/ + /* */ + /* MIN[]: MINimum */ + /* Opcode range: 0x69 */ + /* Stack: int32? int32? --> int32 */ + /* */ + static void + Ins_MIN( INS_ARG ) + { + DO_MIN + } + + +#endif /* !TT_CONFIG_OPTION_INTERPRETER_SWITCH */ + + + /*************************************************************************/ + /* */ + /* The following functions are called as is within the switch statement. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* MINDEX[]: Move INDEXed element */ + /* Opcode range: 0x26 */ + /* Stack: int32? --> StkElt */ + /* */ + static void + Ins_MINDEX( INS_ARG ) + { + FT_Long L, K; + + + L = args[0]; + + if ( L <= 0 || L > CUR.args ) + { + CUR.error = TT_Err_Invalid_Reference; + return; + } + + K = CUR.stack[CUR.args - L]; + + FT_ARRAY_MOVE( &CUR.stack[CUR.args - L ], + &CUR.stack[CUR.args - L + 1], + ( L - 1 ) ); + + CUR.stack[CUR.args - 1] = K; + } + + + /*************************************************************************/ + /* */ + /* ROLL[]: ROLL top three elements */ + /* Opcode range: 0x8A */ + /* Stack: 3 * StkElt --> 3 * StkElt */ + /* */ + static void + Ins_ROLL( INS_ARG ) + { + FT_Long A, B, C; + + FT_UNUSED_EXEC; + + + A = args[2]; + B = args[1]; + C = args[0]; + + args[2] = C; + args[1] = A; + args[0] = B; + } + + + /*************************************************************************/ + /* */ + /* MANAGING THE FLOW OF CONTROL */ + /* */ + /* Instructions appear in the specification's order. */ + /* */ + /*************************************************************************/ + + + static FT_Bool + SkipCode( EXEC_OP ) + { + CUR.IP += CUR.length; + + if ( CUR.IP < CUR.codeSize ) + { + CUR.opcode = CUR.code[CUR.IP]; + + CUR.length = opcode_length[CUR.opcode]; + if ( CUR.length < 0 ) + { + if ( CUR.IP + 1 > CUR.codeSize ) + goto Fail_Overflow; + CUR.length = 2 - CUR.length * CUR.code[CUR.IP + 1]; + } + + if ( CUR.IP + CUR.length <= CUR.codeSize ) + return SUCCESS; + } + + Fail_Overflow: + CUR.error = TT_Err_Code_Overflow; + return FAILURE; + } + + + /*************************************************************************/ + /* */ + /* IF[]: IF test */ + /* Opcode range: 0x58 */ + /* Stack: StkElt --> */ + /* */ + static void + Ins_IF( INS_ARG ) + { + FT_Int nIfs; + FT_Bool Out; + + + if ( args[0] != 0 ) + return; + + nIfs = 1; + Out = 0; + + do + { + if ( SKIP_Code() == FAILURE ) + return; + + switch ( CUR.opcode ) + { + case 0x58: /* IF */ + nIfs++; + break; + + case 0x1B: /* ELSE */ + Out = FT_BOOL( nIfs == 1 ); + break; + + case 0x59: /* EIF */ + nIfs--; + Out = FT_BOOL( nIfs == 0 ); + break; + } + } while ( Out == 0 ); + } + + + /*************************************************************************/ + /* */ + /* ELSE[]: ELSE */ + /* Opcode range: 0x1B */ + /* Stack: --> */ + /* */ + static void + Ins_ELSE( INS_ARG ) + { + FT_Int nIfs; + + FT_UNUSED_ARG; + + + nIfs = 1; + + do + { + if ( SKIP_Code() == FAILURE ) + return; + + switch ( CUR.opcode ) + { + case 0x58: /* IF */ + nIfs++; + break; + + case 0x59: /* EIF */ + nIfs--; + break; + } + } while ( nIfs != 0 ); + } + + + /*************************************************************************/ + /* */ + /* DEFINING AND USING FUNCTIONS AND INSTRUCTIONS */ + /* */ + /* Instructions appear in the specification's order. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* FDEF[]: Function DEFinition */ + /* Opcode range: 0x2C */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_FDEF( INS_ARG ) + { + FT_ULong n; + TT_DefRecord* rec; + TT_DefRecord* limit; + + + /* some font programs are broken enough to redefine functions! */ + /* We will then parse the current table. */ + + rec = CUR.FDefs; + limit = rec + CUR.numFDefs; + n = args[0]; + + for ( ; rec < limit; rec++ ) + { + if ( rec->opc == n ) + break; + } + + if ( rec == limit ) + { + /* check that there is enough room for new functions */ + if ( CUR.numFDefs >= CUR.maxFDefs ) + { + CUR.error = TT_Err_Too_Many_Function_Defs; + return; + } + CUR.numFDefs++; + } + + /* Although FDEF takes unsigned 32-bit integer, */ + /* func # must be within unsigned 16-bit integer */ + if ( n > 0xFFFFU ) + { + CUR.error = TT_Err_Too_Many_Function_Defs; + return; + } + + rec->range = CUR.curRange; + rec->opc = (FT_UInt16)n; + rec->start = CUR.IP + 1; + rec->active = TRUE; + + if ( n > CUR.maxFunc ) + CUR.maxFunc = (FT_UInt16)n; + + /* Now skip the whole function definition. */ + /* We don't allow nested IDEFS & FDEFs. */ + + while ( SKIP_Code() == SUCCESS ) + { + switch ( CUR.opcode ) + { + case 0x89: /* IDEF */ + case 0x2C: /* FDEF */ + CUR.error = TT_Err_Nested_DEFS; + return; + + case 0x2D: /* ENDF */ + return; + } + } + } + + + /*************************************************************************/ + /* */ + /* ENDF[]: END Function definition */ + /* Opcode range: 0x2D */ + /* Stack: --> */ + /* */ + static void + Ins_ENDF( INS_ARG ) + { + TT_CallRec* pRec; + + FT_UNUSED_ARG; + + + if ( CUR.callTop <= 0 ) /* We encountered an ENDF without a call */ + { + CUR.error = TT_Err_ENDF_In_Exec_Stream; + return; + } + + CUR.callTop--; + + pRec = &CUR.callStack[CUR.callTop]; + + pRec->Cur_Count--; + + CUR.step_ins = FALSE; + + if ( pRec->Cur_Count > 0 ) + { + CUR.callTop++; + CUR.IP = pRec->Cur_Restart; + } + else + /* Loop through the current function */ + INS_Goto_CodeRange( pRec->Caller_Range, + pRec->Caller_IP ); + + /* Exit the current call frame. */ + + /* NOTE: If the last instruction of a program is a */ + /* CALL or LOOPCALL, the return address is */ + /* always out of the code range. This is a */ + /* valid address, and it is why we do not test */ + /* the result of Ins_Goto_CodeRange() here! */ + } + + + /*************************************************************************/ + /* */ + /* CALL[]: CALL function */ + /* Opcode range: 0x2B */ + /* Stack: uint32? --> */ + /* */ + static void + Ins_CALL( INS_ARG ) + { + FT_ULong F; + TT_CallRec* pCrec; + TT_DefRecord* def; + + + /* first of all, check the index */ + + F = args[0]; + if ( BOUNDS( F, CUR.maxFunc + 1 ) ) + goto Fail; + + /* Except for some old Apple fonts, all functions in a TrueType */ + /* font are defined in increasing order, starting from 0. This */ + /* means that we normally have */ + /* */ + /* CUR.maxFunc+1 == CUR.numFDefs */ + /* CUR.FDefs[n].opc == n for n in 0..CUR.maxFunc */ + /* */ + /* If this isn't true, we need to look up the function table. */ + + def = CUR.FDefs + F; + if ( CUR.maxFunc + 1 != CUR.numFDefs || def->opc != F ) + { + /* look up the FDefs table */ + TT_DefRecord* limit; + + + def = CUR.FDefs; + limit = def + CUR.numFDefs; + + while ( def < limit && def->opc != F ) + def++; + + if ( def == limit ) + goto Fail; + } + + /* check that the function is active */ + if ( !def->active ) + goto Fail; + + /* check the call stack */ + if ( CUR.callTop >= CUR.callSize ) + { + CUR.error = TT_Err_Stack_Overflow; + return; + } + + pCrec = CUR.callStack + CUR.callTop; + + pCrec->Caller_Range = CUR.curRange; + pCrec->Caller_IP = CUR.IP + 1; + pCrec->Cur_Count = 1; + pCrec->Cur_Restart = def->start; + + CUR.callTop++; + + INS_Goto_CodeRange( def->range, + def->start ); + + CUR.step_ins = FALSE; + return; + + Fail: + CUR.error = TT_Err_Invalid_Reference; + } + + + /*************************************************************************/ + /* */ + /* LOOPCALL[]: LOOP and CALL function */ + /* Opcode range: 0x2A */ + /* Stack: uint32? Eint16? --> */ + /* */ + static void + Ins_LOOPCALL( INS_ARG ) + { + FT_ULong F; + TT_CallRec* pCrec; + TT_DefRecord* def; + + + /* first of all, check the index */ + F = args[1]; + if ( BOUNDS( F, CUR.maxFunc + 1 ) ) + goto Fail; + + /* Except for some old Apple fonts, all functions in a TrueType */ + /* font are defined in increasing order, starting from 0. This */ + /* means that we normally have */ + /* */ + /* CUR.maxFunc+1 == CUR.numFDefs */ + /* CUR.FDefs[n].opc == n for n in 0..CUR.maxFunc */ + /* */ + /* If this isn't true, we need to look up the function table. */ + + def = CUR.FDefs + F; + if ( CUR.maxFunc + 1 != CUR.numFDefs || def->opc != F ) + { + /* look up the FDefs table */ + TT_DefRecord* limit; + + + def = CUR.FDefs; + limit = def + CUR.numFDefs; + + while ( def < limit && def->opc != F ) + def++; + + if ( def == limit ) + goto Fail; + } + + /* check that the function is active */ + if ( !def->active ) + goto Fail; + + /* check stack */ + if ( CUR.callTop >= CUR.callSize ) + { + CUR.error = TT_Err_Stack_Overflow; + return; + } + + if ( args[0] > 0 ) + { + pCrec = CUR.callStack + CUR.callTop; + + pCrec->Caller_Range = CUR.curRange; + pCrec->Caller_IP = CUR.IP + 1; + pCrec->Cur_Count = (FT_Int)args[0]; + pCrec->Cur_Restart = def->start; + + CUR.callTop++; + + INS_Goto_CodeRange( def->range, def->start ); + + CUR.step_ins = FALSE; + } + return; + + Fail: + CUR.error = TT_Err_Invalid_Reference; + } + + + /*************************************************************************/ + /* */ + /* IDEF[]: Instruction DEFinition */ + /* Opcode range: 0x89 */ + /* Stack: Eint8 --> */ + /* */ + static void + Ins_IDEF( INS_ARG ) + { + TT_DefRecord* def; + TT_DefRecord* limit; + + + /* First of all, look for the same function in our table */ + + def = CUR.IDefs; + limit = def + CUR.numIDefs; + + for ( ; def < limit; def++ ) + if ( def->opc == (FT_ULong)args[0] ) + break; + + if ( def == limit ) + { + /* check that there is enough room for a new instruction */ + if ( CUR.numIDefs >= CUR.maxIDefs ) + { + CUR.error = TT_Err_Too_Many_Instruction_Defs; + return; + } + CUR.numIDefs++; + } + + /* opcode must be unsigned 8-bit integer */ + if ( 0 > args[0] || args[0] > 0x00FF ) + { + CUR.error = TT_Err_Too_Many_Instruction_Defs; + return; + } + + def->opc = (FT_Byte)args[0]; + def->start = CUR.IP+1; + def->range = CUR.curRange; + def->active = TRUE; + + if ( (FT_ULong)args[0] > CUR.maxIns ) + CUR.maxIns = (FT_Byte)args[0]; + + /* Now skip the whole function definition. */ + /* We don't allow nested IDEFs & FDEFs. */ + + while ( SKIP_Code() == SUCCESS ) + { + switch ( CUR.opcode ) + { + case 0x89: /* IDEF */ + case 0x2C: /* FDEF */ + CUR.error = TT_Err_Nested_DEFS; + return; + case 0x2D: /* ENDF */ + return; + } + } + } + + + /*************************************************************************/ + /* */ + /* PUSHING DATA ONTO THE INTERPRETER STACK */ + /* */ + /* Instructions appear in the specification's order. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* NPUSHB[]: PUSH N Bytes */ + /* Opcode range: 0x40 */ + /* Stack: --> uint32... */ + /* */ + static void + Ins_NPUSHB( INS_ARG ) + { + FT_UShort L, K; + + + L = (FT_UShort)CUR.code[CUR.IP + 1]; + + if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) ) + { + CUR.error = TT_Err_Stack_Overflow; + return; + } + + for ( K = 1; K <= L; K++ ) + args[K - 1] = CUR.code[CUR.IP + K + 1]; + + CUR.new_top += L; + } + + + /*************************************************************************/ + /* */ + /* NPUSHW[]: PUSH N Words */ + /* Opcode range: 0x41 */ + /* Stack: --> int32... */ + /* */ + static void + Ins_NPUSHW( INS_ARG ) + { + FT_UShort L, K; + + + L = (FT_UShort)CUR.code[CUR.IP + 1]; + + if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) ) + { + CUR.error = TT_Err_Stack_Overflow; + return; + } + + CUR.IP += 2; + + for ( K = 0; K < L; K++ ) + args[K] = GET_ShortIns(); + + CUR.step_ins = FALSE; + CUR.new_top += L; + } + + + /*************************************************************************/ + /* */ + /* PUSHB[abc]: PUSH Bytes */ + /* Opcode range: 0xB0-0xB7 */ + /* Stack: --> uint32... */ + /* */ + static void + Ins_PUSHB( INS_ARG ) + { + FT_UShort L, K; + + + L = (FT_UShort)( CUR.opcode - 0xB0 + 1 ); + + if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) ) + { + CUR.error = TT_Err_Stack_Overflow; + return; + } + + for ( K = 1; K <= L; K++ ) + args[K - 1] = CUR.code[CUR.IP + K]; + } + + + /*************************************************************************/ + /* */ + /* PUSHW[abc]: PUSH Words */ + /* Opcode range: 0xB8-0xBF */ + /* Stack: --> int32... */ + /* */ + static void + Ins_PUSHW( INS_ARG ) + { + FT_UShort L, K; + + + L = (FT_UShort)( CUR.opcode - 0xB8 + 1 ); + + if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) ) + { + CUR.error = TT_Err_Stack_Overflow; + return; + } + + CUR.IP++; + + for ( K = 0; K < L; K++ ) + args[K] = GET_ShortIns(); + + CUR.step_ins = FALSE; + } + + + /*************************************************************************/ + /* */ + /* MANAGING THE GRAPHICS STATE */ + /* */ + /* Instructions appear in the specs' order. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* GC[a]: Get Coordinate projected onto */ + /* Opcode range: 0x46-0x47 */ + /* Stack: uint32 --> f26.6 */ + /* */ + /* BULLSHIT: Measures from the original glyph must be taken along the */ + /* dual projection vector! */ + /* */ + static void + Ins_GC( INS_ARG ) + { + FT_ULong L; + FT_F26Dot6 R; + + + L = (FT_ULong)args[0]; + + if ( BOUNDS( L, CUR.zp2.n_points ) ) + { + if ( CUR.pedantic_hinting ) + { + CUR.error = TT_Err_Invalid_Reference; + return; + } + else + R = 0; + } + else + { + if ( CUR.opcode & 1 ) + R = CUR_fast_dualproj( &CUR.zp2.org[L] ); + else + R = CUR_fast_project( &CUR.zp2.cur[L] ); + } + + args[0] = R; + } + + + /*************************************************************************/ + /* */ + /* SCFS[]: Set Coordinate From Stack */ + /* Opcode range: 0x48 */ + /* Stack: f26.6 uint32 --> */ + /* */ + /* Formula: */ + /* */ + /* OA := OA + ( value - OA.p )/( f.p ) * f */ + /* */ + static void + Ins_SCFS( INS_ARG ) + { + FT_Long K; + FT_UShort L; + + + L = (FT_UShort)args[0]; + + if ( BOUNDS( L, CUR.zp2.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + K = CUR_fast_project( &CUR.zp2.cur[L] ); + + CUR_Func_move( &CUR.zp2, L, args[1] - K ); + + /* not part of the specs, but here for safety */ + + if ( CUR.GS.gep2 == 0 ) + CUR.zp2.org[L] = CUR.zp2.cur[L]; + } + + + /*************************************************************************/ + /* */ + /* MD[a]: Measure Distance */ + /* Opcode range: 0x49-0x4A */ + /* Stack: uint32 uint32 --> f26.6 */ + /* */ + /* BULLSHIT: Measure taken in the original glyph must be along the dual */ + /* projection vector. */ + /* */ + /* Second BULLSHIT: Flag attributes are inverted! */ + /* 0 => measure distance in original outline */ + /* 1 => measure distance in grid-fitted outline */ + /* */ + /* Third one: `zp0 - zp1', and not `zp2 - zp1! */ + /* */ + static void + Ins_MD( INS_ARG ) + { + FT_UShort K, L; + FT_F26Dot6 D; + + + K = (FT_UShort)args[1]; + L = (FT_UShort)args[0]; + + if( BOUNDS( L, CUR.zp0.n_points ) || + BOUNDS( K, CUR.zp1.n_points ) ) + { + if ( CUR.pedantic_hinting ) + { + CUR.error = TT_Err_Invalid_Reference; + return; + } + D = 0; + } + else + { + if ( CUR.opcode & 1 ) + D = CUR_Func_project( CUR.zp0.cur + L, CUR.zp1.cur + K ); + else + { + FT_Vector* vec1 = CUR.zp0.orus + L; + FT_Vector* vec2 = CUR.zp1.orus + K; + + + if ( CUR.metrics.x_scale == CUR.metrics.y_scale ) + { + /* this should be faster */ + D = CUR_Func_dualproj( vec1, vec2 ); + D = TT_MULFIX( D, CUR.metrics.x_scale ); + } + else + { + FT_Vector vec; + + + vec.x = TT_MULFIX( vec1->x - vec2->x, CUR.metrics.x_scale ); + vec.y = TT_MULFIX( vec1->y - vec2->y, CUR.metrics.y_scale ); + + D = CUR_fast_dualproj( &vec ); + } + } + } + + args[0] = D; + } + + + /*************************************************************************/ + /* */ + /* SDPVTL[a]: Set Dual PVector to Line */ + /* Opcode range: 0x86-0x87 */ + /* Stack: uint32 uint32 --> */ + /* */ + static void + Ins_SDPVTL( INS_ARG ) + { + FT_Long A, B, C; + FT_UShort p1, p2; /* was FT_Int in pas type ERROR */ + + + p1 = (FT_UShort)args[1]; + p2 = (FT_UShort)args[0]; + + if ( BOUNDS( p2, CUR.zp1.n_points ) || + BOUNDS( p1, CUR.zp2.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + { + FT_Vector* v1 = CUR.zp1.org + p2; + FT_Vector* v2 = CUR.zp2.org + p1; + + + A = v1->x - v2->x; + B = v1->y - v2->y; + } + + if ( ( CUR.opcode & 1 ) != 0 ) + { + C = B; /* counter clockwise rotation */ + B = A; + A = -C; + } + + NORMalize( A, B, &CUR.GS.dualVector ); + + { + FT_Vector* v1 = CUR.zp1.cur + p2; + FT_Vector* v2 = CUR.zp2.cur + p1; + + + A = v1->x - v2->x; + B = v1->y - v2->y; + } + + if ( ( CUR.opcode & 1 ) != 0 ) + { + C = B; /* counter clockwise rotation */ + B = A; + A = -C; + } + + NORMalize( A, B, &CUR.GS.projVector ); + + GUESS_VECTOR( freeVector ); + + COMPUTE_Funcs(); + } + + + /*************************************************************************/ + /* */ + /* SZP0[]: Set Zone Pointer 0 */ + /* Opcode range: 0x13 */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_SZP0( INS_ARG ) + { + switch ( (FT_Int)args[0] ) + { + case 0: + CUR.zp0 = CUR.twilight; + break; + + case 1: + CUR.zp0 = CUR.pts; + break; + + default: + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + CUR.GS.gep0 = (FT_UShort)args[0]; + } + + + /*************************************************************************/ + /* */ + /* SZP1[]: Set Zone Pointer 1 */ + /* Opcode range: 0x14 */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_SZP1( INS_ARG ) + { + switch ( (FT_Int)args[0] ) + { + case 0: + CUR.zp1 = CUR.twilight; + break; + + case 1: + CUR.zp1 = CUR.pts; + break; + + default: + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + CUR.GS.gep1 = (FT_UShort)args[0]; + } + + + /*************************************************************************/ + /* */ + /* SZP2[]: Set Zone Pointer 2 */ + /* Opcode range: 0x15 */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_SZP2( INS_ARG ) + { + switch ( (FT_Int)args[0] ) + { + case 0: + CUR.zp2 = CUR.twilight; + break; + + case 1: + CUR.zp2 = CUR.pts; + break; + + default: + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + CUR.GS.gep2 = (FT_UShort)args[0]; + } + + + /*************************************************************************/ + /* */ + /* SZPS[]: Set Zone PointerS */ + /* Opcode range: 0x16 */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_SZPS( INS_ARG ) + { + switch ( (FT_Int)args[0] ) + { + case 0: + CUR.zp0 = CUR.twilight; + break; + + case 1: + CUR.zp0 = CUR.pts; + break; + + default: + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + CUR.zp1 = CUR.zp0; + CUR.zp2 = CUR.zp0; + + CUR.GS.gep0 = (FT_UShort)args[0]; + CUR.GS.gep1 = (FT_UShort)args[0]; + CUR.GS.gep2 = (FT_UShort)args[0]; + } + + + /*************************************************************************/ + /* */ + /* INSTCTRL[]: INSTruction ConTRoL */ + /* Opcode range: 0x8e */ + /* Stack: int32 int32 --> */ + /* */ + static void + Ins_INSTCTRL( INS_ARG ) + { + FT_Long K, L; + + + K = args[1]; + L = args[0]; + + if ( K < 1 || K > 2 ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + if ( L != 0 ) + L = K; + + CUR.GS.instruct_control = FT_BOOL( + ( (FT_Byte)CUR.GS.instruct_control & ~(FT_Byte)K ) | (FT_Byte)L ); + } + + + /*************************************************************************/ + /* */ + /* SCANCTRL[]: SCAN ConTRoL */ + /* Opcode range: 0x85 */ + /* Stack: uint32? --> */ + /* */ + static void + Ins_SCANCTRL( INS_ARG ) + { + FT_Int A; + + + /* Get Threshold */ + A = (FT_Int)( args[0] & 0xFF ); + + if ( A == 0xFF ) + { + CUR.GS.scan_control = TRUE; + return; + } + else if ( A == 0 ) + { + CUR.GS.scan_control = FALSE; + return; + } + + if ( ( args[0] & 0x100 ) != 0 && CUR.tt_metrics.ppem <= A ) + CUR.GS.scan_control = TRUE; + + if ( ( args[0] & 0x200 ) != 0 && CUR.tt_metrics.rotated ) + CUR.GS.scan_control = TRUE; + + if ( ( args[0] & 0x400 ) != 0 && CUR.tt_metrics.stretched ) + CUR.GS.scan_control = TRUE; + + if ( ( args[0] & 0x800 ) != 0 && CUR.tt_metrics.ppem > A ) + CUR.GS.scan_control = FALSE; + + if ( ( args[0] & 0x1000 ) != 0 && CUR.tt_metrics.rotated ) + CUR.GS.scan_control = FALSE; + + if ( ( args[0] & 0x2000 ) != 0 && CUR.tt_metrics.stretched ) + CUR.GS.scan_control = FALSE; + } + + + /*************************************************************************/ + /* */ + /* SCANTYPE[]: SCAN TYPE */ + /* Opcode range: 0x8D */ + /* Stack: uint32? --> */ + /* */ + static void + Ins_SCANTYPE( INS_ARG ) + { + if ( args[0] >= 0 ) + CUR.GS.scan_type = (FT_Int)args[0]; + } + + + /*************************************************************************/ + /* */ + /* MANAGING OUTLINES */ + /* */ + /* Instructions appear in the specification's order. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* FLIPPT[]: FLIP PoinT */ + /* Opcode range: 0x80 */ + /* Stack: uint32... --> */ + /* */ + static void + Ins_FLIPPT( INS_ARG ) + { + FT_UShort point; + + FT_UNUSED_ARG; + + + if ( CUR.top < CUR.GS.loop ) + { + CUR.error = TT_Err_Too_Few_Arguments; + return; + } + + while ( CUR.GS.loop > 0 ) + { + CUR.args--; + + point = (FT_UShort)CUR.stack[CUR.args]; + + if ( BOUNDS( point, CUR.pts.n_points ) ) + { + if ( CUR.pedantic_hinting ) + { + CUR.error = TT_Err_Invalid_Reference; + return; + } + } + else + CUR.pts.tags[point] ^= FT_CURVE_TAG_ON; + + CUR.GS.loop--; + } + + CUR.GS.loop = 1; + CUR.new_top = CUR.args; + } + + + /*************************************************************************/ + /* */ + /* FLIPRGON[]: FLIP RanGe ON */ + /* Opcode range: 0x81 */ + /* Stack: uint32 uint32 --> */ + /* */ + static void + Ins_FLIPRGON( INS_ARG ) + { + FT_UShort I, K, L; + + + K = (FT_UShort)args[1]; + L = (FT_UShort)args[0]; + + if ( BOUNDS( K, CUR.pts.n_points ) || + BOUNDS( L, CUR.pts.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + for ( I = L; I <= K; I++ ) + CUR.pts.tags[I] |= FT_CURVE_TAG_ON; + } + + + /*************************************************************************/ + /* */ + /* FLIPRGOFF: FLIP RanGe OFF */ + /* Opcode range: 0x82 */ + /* Stack: uint32 uint32 --> */ + /* */ + static void + Ins_FLIPRGOFF( INS_ARG ) + { + FT_UShort I, K, L; + + + K = (FT_UShort)args[1]; + L = (FT_UShort)args[0]; + + if ( BOUNDS( K, CUR.pts.n_points ) || + BOUNDS( L, CUR.pts.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + for ( I = L; I <= K; I++ ) + CUR.pts.tags[I] &= ~FT_CURVE_TAG_ON; + } + + + static FT_Bool + Compute_Point_Displacement( EXEC_OP_ FT_F26Dot6* x, + FT_F26Dot6* y, + TT_GlyphZone zone, + FT_UShort* refp ) + { + TT_GlyphZoneRec zp; + FT_UShort p; + FT_F26Dot6 d; + + + if ( CUR.opcode & 1 ) + { + zp = CUR.zp0; + p = CUR.GS.rp1; + } + else + { + zp = CUR.zp1; + p = CUR.GS.rp2; + } + + if ( BOUNDS( p, zp.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + *refp = 0; + return FAILURE; + } + + *zone = zp; + *refp = p; + + d = CUR_Func_project( zp.cur + p, zp.org + p ); + +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING + if ( CUR.face->unpatented_hinting ) + { + if ( CUR.GS.both_x_axis ) + { + *x = d; + *y = 0; + } + else + { + *x = 0; + *y = d; + } + } + else +#endif + { + *x = TT_MULDIV( d, + (FT_Long)CUR.GS.freeVector.x * 0x10000L, + CUR.F_dot_P ); + *y = TT_MULDIV( d, + (FT_Long)CUR.GS.freeVector.y * 0x10000L, + CUR.F_dot_P ); + } + + return SUCCESS; + } + + + static void + Move_Zp2_Point( EXEC_OP_ FT_UShort point, + FT_F26Dot6 dx, + FT_F26Dot6 dy, + FT_Bool touch ) + { +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING + if ( CUR.face->unpatented_hinting ) + { + if ( CUR.GS.both_x_axis ) + { + CUR.zp2.cur[point].x += dx; + if ( touch ) + CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X; + } + else + { + CUR.zp2.cur[point].y += dy; + if ( touch ) + CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y; + } + return; + } +#endif + + if ( CUR.GS.freeVector.x != 0 ) + { + CUR.zp2.cur[point].x += dx; + if ( touch ) + CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X; + } + + if ( CUR.GS.freeVector.y != 0 ) + { + CUR.zp2.cur[point].y += dy; + if ( touch ) + CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y; + } + } + + + /*************************************************************************/ + /* */ + /* SHP[a]: SHift Point by the last point */ + /* Opcode range: 0x32-0x33 */ + /* Stack: uint32... --> */ + /* */ + static void + Ins_SHP( INS_ARG ) + { + TT_GlyphZoneRec zp; + FT_UShort refp; + + FT_F26Dot6 dx, + dy; + FT_UShort point; + + FT_UNUSED_ARG; + + + if ( CUR.top < CUR.GS.loop ) + { + CUR.error = TT_Err_Invalid_Reference; + return; + } + + if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) ) + return; + + while ( CUR.GS.loop > 0 ) + { + CUR.args--; + point = (FT_UShort)CUR.stack[CUR.args]; + + if ( BOUNDS( point, CUR.zp2.n_points ) ) + { + if ( CUR.pedantic_hinting ) + { + CUR.error = TT_Err_Invalid_Reference; + return; + } + } + else + /* XXX: UNDOCUMENTED! SHP touches the points */ + MOVE_Zp2_Point( point, dx, dy, TRUE ); + + CUR.GS.loop--; + } + + CUR.GS.loop = 1; + CUR.new_top = CUR.args; + } + + + /*************************************************************************/ + /* */ + /* SHC[a]: SHift Contour */ + /* Opcode range: 0x34-35 */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_SHC( INS_ARG ) + { + TT_GlyphZoneRec zp; + FT_UShort refp; + FT_F26Dot6 dx, + dy; + + FT_Short contour; + FT_UShort first_point, last_point, i; + + + contour = (FT_UShort)args[0]; + + if ( BOUNDS( contour, CUR.pts.n_contours ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) ) + return; + + if ( contour == 0 ) + first_point = 0; + else + first_point = (FT_UShort)( CUR.pts.contours[contour - 1] + 1 - + CUR.pts.first_point ); + + last_point = (FT_UShort)( CUR.pts.contours[contour] - + CUR.pts.first_point ); + + /* XXX: this is probably wrong... at least it prevents memory */ + /* corruption when zp2 is the twilight zone */ + if ( BOUNDS( last_point, CUR.zp2.n_points ) ) + { + if ( CUR.zp2.n_points > 0 ) + last_point = (FT_UShort)(CUR.zp2.n_points - 1); + else + last_point = 0; + } + + /* XXX: UNDOCUMENTED! SHC touches the points */ + for ( i = first_point; i <= last_point; i++ ) + { + if ( zp.cur != CUR.zp2.cur || refp != i ) + MOVE_Zp2_Point( i, dx, dy, TRUE ); + } + } + + + /*************************************************************************/ + /* */ + /* SHZ[a]: SHift Zone */ + /* Opcode range: 0x36-37 */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_SHZ( INS_ARG ) + { + TT_GlyphZoneRec zp; + FT_UShort refp; + FT_F26Dot6 dx, + dy; + + FT_UShort last_point, i; + + + if ( BOUNDS( args[0], 2 ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) ) + return; + + /* XXX: UNDOCUMENTED! SHZ doesn't move the phantom points. */ + /* Twilight zone has no contours, so use `n_points'. */ + /* Normal zone's `n_points' includes phantoms, so must */ + /* use end of last contour. */ + if ( CUR.GS.gep2 == 0 && CUR.zp2.n_points > 0 ) + last_point = (FT_UShort)( CUR.zp2.n_points - 1 ); + else if ( CUR.GS.gep2 == 1 && CUR.zp2.n_contours > 0 ) + last_point = (FT_UShort)( CUR.zp2.contours[CUR.zp2.n_contours - 1] ); + else + last_point = 0; + + /* XXX: UNDOCUMENTED! SHZ doesn't touch the points */ + for ( i = 0; i <= last_point; i++ ) + { + if ( zp.cur != CUR.zp2.cur || refp != i ) + MOVE_Zp2_Point( i, dx, dy, FALSE ); + } + } + + + /*************************************************************************/ + /* */ + /* SHPIX[]: SHift points by a PIXel amount */ + /* Opcode range: 0x38 */ + /* Stack: f26.6 uint32... --> */ + /* */ + static void + Ins_SHPIX( INS_ARG ) + { + FT_F26Dot6 dx, dy; + FT_UShort point; + + + if ( CUR.top < CUR.GS.loop + 1 ) + { + CUR.error = TT_Err_Invalid_Reference; + return; + } + +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING + if ( CUR.face->unpatented_hinting ) + { + if ( CUR.GS.both_x_axis ) + { + dx = TT_MulFix14( (FT_UInt32)args[0], 0x4000 ); + dy = 0; + } + else + { + dx = 0; + dy = TT_MulFix14( (FT_UInt32)args[0], 0x4000 ); + } + } + else +#endif + { + dx = TT_MulFix14( (FT_UInt32)args[0], CUR.GS.freeVector.x ); + dy = TT_MulFix14( (FT_UInt32)args[0], CUR.GS.freeVector.y ); + } + + while ( CUR.GS.loop > 0 ) + { + CUR.args--; + + point = (FT_UShort)CUR.stack[CUR.args]; + + if ( BOUNDS( point, CUR.zp2.n_points ) ) + { + if ( CUR.pedantic_hinting ) + { + CUR.error = TT_Err_Invalid_Reference; + return; + } + } + else + MOVE_Zp2_Point( point, dx, dy, TRUE ); + + CUR.GS.loop--; + } + + CUR.GS.loop = 1; + CUR.new_top = CUR.args; + } + + + /*************************************************************************/ + /* */ + /* MSIRP[a]: Move Stack Indirect Relative Position */ + /* Opcode range: 0x3A-0x3B */ + /* Stack: f26.6 uint32 --> */ + /* */ + static void + Ins_MSIRP( INS_ARG ) + { + FT_UShort point; + FT_F26Dot6 distance; + + + point = (FT_UShort)args[0]; + + if ( BOUNDS( point, CUR.zp1.n_points ) || + BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + /* XXX: UNDOCUMENTED! behaviour */ + if ( CUR.GS.gep1 == 0 ) /* if the point that is to be moved */ + /* is in twilight zone */ + { + CUR.zp1.org[point] = CUR.zp0.org[CUR.GS.rp0]; + CUR_Func_move_orig( &CUR.zp1, point, args[1] ); + CUR.zp1.cur[point] = CUR.zp1.org[point]; + } + + distance = CUR_Func_project( CUR.zp1.cur + point, + CUR.zp0.cur + CUR.GS.rp0 ); + + CUR_Func_move( &CUR.zp1, point, args[1] - distance ); + + CUR.GS.rp1 = CUR.GS.rp0; + CUR.GS.rp2 = point; + + if ( ( CUR.opcode & 1 ) != 0 ) + CUR.GS.rp0 = point; + } + + + /*************************************************************************/ + /* */ + /* MDAP[a]: Move Direct Absolute Point */ + /* Opcode range: 0x2E-0x2F */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_MDAP( INS_ARG ) + { + FT_UShort point; + FT_F26Dot6 cur_dist, + distance; + + + point = (FT_UShort)args[0]; + + if ( BOUNDS( point, CUR.zp0.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + /* XXX: Is there some undocumented feature while in the */ + /* twilight zone? ? */ + if ( ( CUR.opcode & 1 ) != 0 ) + { + cur_dist = CUR_fast_project( &CUR.zp0.cur[point] ); + distance = CUR_Func_round( cur_dist, + CUR.tt_metrics.compensations[0] ) - cur_dist; + } + else + distance = 0; + + CUR_Func_move( &CUR.zp0, point, distance ); + + CUR.GS.rp0 = point; + CUR.GS.rp1 = point; + } + + + /*************************************************************************/ + /* */ + /* MIAP[a]: Move Indirect Absolute Point */ + /* Opcode range: 0x3E-0x3F */ + /* Stack: uint32 uint32 --> */ + /* */ + static void + Ins_MIAP( INS_ARG ) + { + FT_ULong cvtEntry; + FT_UShort point; + FT_F26Dot6 distance, + org_dist; + + + cvtEntry = (FT_ULong)args[1]; + point = (FT_UShort)args[0]; + + if ( BOUNDS( point, CUR.zp0.n_points ) || + BOUNDS( cvtEntry, CUR.cvtSize ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + /* XXX: UNDOCUMENTED! */ + /* */ + /* The behaviour of an MIAP instruction is quite */ + /* different when used in the twilight zone. */ + /* */ + /* First, no control value cut-in test is performed */ + /* as it would fail anyway. Second, the original */ + /* point, i.e. (org_x,org_y) of zp0.point, is set */ + /* to the absolute, unrounded distance found in */ + /* the CVT. */ + /* */ + /* This is used in the CVT programs of the Microsoft */ + /* fonts Arial, Times, etc., in order to re-adjust */ + /* some key font heights. It allows the use of the */ + /* IP instruction in the twilight zone, which */ + /* otherwise would be `illegal' according to the */ + /* specification. */ + /* */ + /* We implement it with a special sequence for the */ + /* twilight zone. This is a bad hack, but it seems */ + /* to work. */ + + distance = CUR_Func_read_cvt( cvtEntry ); + + if ( CUR.GS.gep0 == 0 ) /* If in twilight zone */ + { + CUR.zp0.org[point].x = TT_MulFix14( (FT_UInt32)distance, CUR.GS.freeVector.x ); + CUR.zp0.org[point].y = TT_MulFix14( (FT_UInt32)distance, CUR.GS.freeVector.y ), + CUR.zp0.cur[point] = CUR.zp0.org[point]; + } + + org_dist = CUR_fast_project( &CUR.zp0.cur[point] ); + + if ( ( CUR.opcode & 1 ) != 0 ) /* rounding and control cutin flag */ + { + if ( FT_ABS( distance - org_dist ) > CUR.GS.control_value_cutin ) + distance = org_dist; + + distance = CUR_Func_round( distance, CUR.tt_metrics.compensations[0] ); + } + + CUR_Func_move( &CUR.zp0, point, distance - org_dist ); + + CUR.GS.rp0 = point; + CUR.GS.rp1 = point; + } + + + /*************************************************************************/ + /* */ + /* MDRP[abcde]: Move Direct Relative Point */ + /* Opcode range: 0xC0-0xDF */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_MDRP( INS_ARG ) + { + FT_UShort point; + FT_F26Dot6 org_dist, distance; + + + point = (FT_UShort)args[0]; + + if ( BOUNDS( point, CUR.zp1.n_points ) || + BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + /* XXX: Is there some undocumented feature while in the */ + /* twilight zone? */ + + /* XXX: UNDOCUMENTED: twilight zone special case */ + + if ( CUR.GS.gep0 == 0 || CUR.GS.gep1 == 0 ) + { + FT_Vector* vec1 = &CUR.zp1.org[point]; + FT_Vector* vec2 = &CUR.zp0.org[CUR.GS.rp0]; + + + org_dist = CUR_Func_dualproj( vec1, vec2 ); + } + else + { + FT_Vector* vec1 = &CUR.zp1.orus[point]; + FT_Vector* vec2 = &CUR.zp0.orus[CUR.GS.rp0]; + + + if ( CUR.metrics.x_scale == CUR.metrics.y_scale ) + { + /* this should be faster */ + org_dist = CUR_Func_dualproj( vec1, vec2 ); + org_dist = TT_MULFIX( org_dist, CUR.metrics.x_scale ); + } + else + { + FT_Vector vec; + + + vec.x = TT_MULFIX( vec1->x - vec2->x, CUR.metrics.x_scale ); + vec.y = TT_MULFIX( vec1->y - vec2->y, CUR.metrics.y_scale ); + + org_dist = CUR_fast_dualproj( &vec ); + } + } + + /* single width cut-in test */ + + if ( FT_ABS( org_dist - CUR.GS.single_width_value ) < + CUR.GS.single_width_cutin ) + { + if ( org_dist >= 0 ) + org_dist = CUR.GS.single_width_value; + else + org_dist = -CUR.GS.single_width_value; + } + + /* round flag */ + + if ( ( CUR.opcode & 4 ) != 0 ) + distance = CUR_Func_round( + org_dist, + CUR.tt_metrics.compensations[CUR.opcode & 3] ); + else + distance = ROUND_None( + org_dist, + CUR.tt_metrics.compensations[CUR.opcode & 3] ); + + /* minimum distance flag */ + + if ( ( CUR.opcode & 8 ) != 0 ) + { + if ( org_dist >= 0 ) + { + if ( distance < CUR.GS.minimum_distance ) + distance = CUR.GS.minimum_distance; + } + else + { + if ( distance > -CUR.GS.minimum_distance ) + distance = -CUR.GS.minimum_distance; + } + } + + /* now move the point */ + + org_dist = CUR_Func_project( CUR.zp1.cur + point, + CUR.zp0.cur + CUR.GS.rp0 ); + + CUR_Func_move( &CUR.zp1, point, distance - org_dist ); + + CUR.GS.rp1 = CUR.GS.rp0; + CUR.GS.rp2 = point; + + if ( ( CUR.opcode & 16 ) != 0 ) + CUR.GS.rp0 = point; + } + + + /*************************************************************************/ + /* */ + /* MIRP[abcde]: Move Indirect Relative Point */ + /* Opcode range: 0xE0-0xFF */ + /* Stack: int32? uint32 --> */ + /* */ + static void + Ins_MIRP( INS_ARG ) + { + FT_UShort point; + FT_ULong cvtEntry; + + FT_F26Dot6 cvt_dist, + distance, + cur_dist, + org_dist; + + + point = (FT_UShort)args[0]; + cvtEntry = (FT_ULong)( args[1] + 1 ); + + /* XXX: UNDOCUMENTED! cvt[-1] = 0 always */ + + if ( BOUNDS( point, CUR.zp1.n_points ) || + BOUNDS( cvtEntry, CUR.cvtSize + 1 ) || + BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + if ( !cvtEntry ) + cvt_dist = 0; + else + cvt_dist = CUR_Func_read_cvt( cvtEntry - 1 ); + + /* single width test */ + + if ( FT_ABS( cvt_dist - CUR.GS.single_width_value ) < + CUR.GS.single_width_cutin ) + { + if ( cvt_dist >= 0 ) + cvt_dist = CUR.GS.single_width_value; + else + cvt_dist = -CUR.GS.single_width_value; + } + + /* XXX: UNDOCUMENTED! -- twilight zone */ + + if ( CUR.GS.gep1 == 0 ) + { + CUR.zp1.org[point].x = CUR.zp0.org[CUR.GS.rp0].x + + TT_MulFix14( (FT_UInt32)cvt_dist, + CUR.GS.freeVector.x ); + + CUR.zp1.org[point].y = CUR.zp0.org[CUR.GS.rp0].y + + TT_MulFix14( (FT_UInt32)cvt_dist, + CUR.GS.freeVector.y ); + + CUR.zp1.cur[point] = CUR.zp0.cur[point]; + } + + org_dist = CUR_Func_dualproj( &CUR.zp1.org[point], + &CUR.zp0.org[CUR.GS.rp0] ); + cur_dist = CUR_Func_project ( &CUR.zp1.cur[point], + &CUR.zp0.cur[CUR.GS.rp0] ); + + /* auto-flip test */ + + if ( CUR.GS.auto_flip ) + { + if ( ( org_dist ^ cvt_dist ) < 0 ) + cvt_dist = -cvt_dist; + } + + /* control value cutin and round */ + + if ( ( CUR.opcode & 4 ) != 0 ) + { + /* XXX: UNDOCUMENTED! Only perform cut-in test when both points */ + /* refer to the same zone. */ + + if ( CUR.GS.gep0 == CUR.GS.gep1 ) + if ( FT_ABS( cvt_dist - org_dist ) >= CUR.GS.control_value_cutin ) + cvt_dist = org_dist; + + distance = CUR_Func_round( + cvt_dist, + CUR.tt_metrics.compensations[CUR.opcode & 3] ); + } + else + distance = ROUND_None( + cvt_dist, + CUR.tt_metrics.compensations[CUR.opcode & 3] ); + + /* minimum distance test */ + + if ( ( CUR.opcode & 8 ) != 0 ) + { + if ( org_dist >= 0 ) + { + if ( distance < CUR.GS.minimum_distance ) + distance = CUR.GS.minimum_distance; + } + else + { + if ( distance > -CUR.GS.minimum_distance ) + distance = -CUR.GS.minimum_distance; + } + } + + CUR_Func_move( &CUR.zp1, point, distance - cur_dist ); + + CUR.GS.rp1 = CUR.GS.rp0; + + if ( ( CUR.opcode & 16 ) != 0 ) + CUR.GS.rp0 = point; + + /* XXX: UNDOCUMENTED! */ + CUR.GS.rp2 = point; + } + + + /*************************************************************************/ + /* */ + /* ALIGNRP[]: ALIGN Relative Point */ + /* Opcode range: 0x3C */ + /* Stack: uint32 uint32... --> */ + /* */ + static void + Ins_ALIGNRP( INS_ARG ) + { + FT_UShort point; + FT_F26Dot6 distance; + + FT_UNUSED_ARG; + + + if ( CUR.top < CUR.GS.loop || + BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + while ( CUR.GS.loop > 0 ) + { + CUR.args--; + + point = (FT_UShort)CUR.stack[CUR.args]; + + if ( BOUNDS( point, CUR.zp1.n_points ) ) + { + if ( CUR.pedantic_hinting ) + { + CUR.error = TT_Err_Invalid_Reference; + return; + } + } + else + { + distance = CUR_Func_project( CUR.zp1.cur + point, + CUR.zp0.cur + CUR.GS.rp0 ); + + CUR_Func_move( &CUR.zp1, point, -distance ); + } + + CUR.GS.loop--; + } + + CUR.GS.loop = 1; + CUR.new_top = CUR.args; + } + + + /*************************************************************************/ + /* */ + /* ISECT[]: moves point to InterSECTion */ + /* Opcode range: 0x0F */ + /* Stack: 5 * uint32 --> */ + /* */ + static void + Ins_ISECT( INS_ARG ) + { + FT_UShort point, + a0, a1, + b0, b1; + + FT_F26Dot6 discriminant; + + FT_F26Dot6 dx, dy, + dax, day, + dbx, dby; + + FT_F26Dot6 val; + + FT_Vector R; + + + point = (FT_UShort)args[0]; + + a0 = (FT_UShort)args[1]; + a1 = (FT_UShort)args[2]; + b0 = (FT_UShort)args[3]; + b1 = (FT_UShort)args[4]; + + if ( BOUNDS( b0, CUR.zp0.n_points ) || + BOUNDS( b1, CUR.zp0.n_points ) || + BOUNDS( a0, CUR.zp1.n_points ) || + BOUNDS( a1, CUR.zp1.n_points ) || + BOUNDS( point, CUR.zp2.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + dbx = CUR.zp0.cur[b1].x - CUR.zp0.cur[b0].x; + dby = CUR.zp0.cur[b1].y - CUR.zp0.cur[b0].y; + + dax = CUR.zp1.cur[a1].x - CUR.zp1.cur[a0].x; + day = CUR.zp1.cur[a1].y - CUR.zp1.cur[a0].y; + + dx = CUR.zp0.cur[b0].x - CUR.zp1.cur[a0].x; + dy = CUR.zp0.cur[b0].y - CUR.zp1.cur[a0].y; + + CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_BOTH; + + discriminant = TT_MULDIV( dax, -dby, 0x40 ) + + TT_MULDIV( day, dbx, 0x40 ); + + if ( FT_ABS( discriminant ) >= 0x40 ) + { + val = TT_MULDIV( dx, -dby, 0x40 ) + TT_MULDIV( dy, dbx, 0x40 ); + + R.x = TT_MULDIV( val, dax, discriminant ); + R.y = TT_MULDIV( val, day, discriminant ); + + CUR.zp2.cur[point].x = CUR.zp1.cur[a0].x + R.x; + CUR.zp2.cur[point].y = CUR.zp1.cur[a0].y + R.y; + } + else + { + /* else, take the middle of the middles of A and B */ + + CUR.zp2.cur[point].x = ( CUR.zp1.cur[a0].x + + CUR.zp1.cur[a1].x + + CUR.zp0.cur[b0].x + + CUR.zp0.cur[b1].x ) / 4; + CUR.zp2.cur[point].y = ( CUR.zp1.cur[a0].y + + CUR.zp1.cur[a1].y + + CUR.zp0.cur[b0].y + + CUR.zp0.cur[b1].y ) / 4; + } + } + + + /*************************************************************************/ + /* */ + /* ALIGNPTS[]: ALIGN PoinTS */ + /* Opcode range: 0x27 */ + /* Stack: uint32 uint32 --> */ + /* */ + static void + Ins_ALIGNPTS( INS_ARG ) + { + FT_UShort p1, p2; + FT_F26Dot6 distance; + + + p1 = (FT_UShort)args[0]; + p2 = (FT_UShort)args[1]; + + if ( BOUNDS( args[0], CUR.zp1.n_points ) || + BOUNDS( args[1], CUR.zp0.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + distance = CUR_Func_project( CUR.zp0.cur + p2, + CUR.zp1.cur + p1 ) / 2; + + CUR_Func_move( &CUR.zp1, p1, distance ); + CUR_Func_move( &CUR.zp0, p2, -distance ); + } + + + /*************************************************************************/ + /* */ + /* IP[]: Interpolate Point */ + /* Opcode range: 0x39 */ + /* Stack: uint32... --> */ + /* */ + + /* SOMETIMES, DUMBER CODE IS BETTER CODE */ + + static void + Ins_IP( INS_ARG ) + { + FT_F26Dot6 old_range, cur_range; + FT_Vector* orus_base; + FT_Vector* cur_base; + FT_Int twilight; + + FT_UNUSED_ARG; + + + if ( CUR.top < CUR.GS.loop ) + { + CUR.error = TT_Err_Invalid_Reference; + return; + } + + /* + * We need to deal in a special way with the twilight zone. + * Otherwise, by definition, the value of CUR.twilight.orus[n] is (0,0), + * for every n. + */ + twilight = CUR.GS.gep0 == 0 || CUR.GS.gep1 == 0 || CUR.GS.gep2 == 0; + + if ( BOUNDS( CUR.GS.rp1, CUR.zp0.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + if ( twilight ) + orus_base = &CUR.zp0.org[CUR.GS.rp1]; + else + orus_base = &CUR.zp0.orus[CUR.GS.rp1]; + + cur_base = &CUR.zp0.cur[CUR.GS.rp1]; + + /* XXX: There are some glyphs in some braindead but popular */ + /* fonts out there (e.g. [aeu]grave in monotype.ttf) */ + /* calling IP[] with bad values of rp[12]. */ + /* Do something sane when this odd thing happens. */ + if ( BOUNDS( CUR.GS.rp1, CUR.zp0.n_points ) || + BOUNDS( CUR.GS.rp2, CUR.zp1.n_points ) ) + { + old_range = 0; + cur_range = 0; + } + else + { + if ( twilight ) + old_range = CUR_Func_dualproj( &CUR.zp1.org[CUR.GS.rp2], + orus_base ); + else + old_range = CUR_Func_dualproj( &CUR.zp1.orus[CUR.GS.rp2], + orus_base ); + + cur_range = CUR_Func_project ( &CUR.zp1.cur[CUR.GS.rp2], cur_base ); + } + + for ( ; CUR.GS.loop > 0; --CUR.GS.loop ) + { + FT_UInt point = (FT_UInt)CUR.stack[--CUR.args]; + FT_F26Dot6 org_dist, cur_dist, new_dist; + + + /* check point bounds */ + if ( BOUNDS( point, CUR.zp2.n_points ) ) + { + if ( CUR.pedantic_hinting ) + { + CUR.error = TT_Err_Invalid_Reference; + return; + } + continue; + } + + if ( twilight ) + org_dist = CUR_Func_dualproj( &CUR.zp2.org[point], orus_base ); + else + org_dist = CUR_Func_dualproj( &CUR.zp2.orus[point], orus_base ); + + cur_dist = CUR_Func_project ( &CUR.zp2.cur[point], cur_base ); + + if ( org_dist ) + new_dist = ( old_range != 0 ) + ? TT_MULDIV( org_dist, cur_range, old_range ) + : cur_dist; + else + new_dist = 0; + + CUR_Func_move( &CUR.zp2, (FT_UShort)point, new_dist - cur_dist ); + } + CUR.GS.loop = 1; + CUR.new_top = CUR.args; + } + + + /*************************************************************************/ + /* */ + /* UTP[a]: UnTouch Point */ + /* Opcode range: 0x29 */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_UTP( INS_ARG ) + { + FT_UShort point; + FT_Byte mask; + + + point = (FT_UShort)args[0]; + + if ( BOUNDS( point, CUR.zp0.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + mask = 0xFF; + + if ( CUR.GS.freeVector.x != 0 ) + mask &= ~FT_CURVE_TAG_TOUCH_X; + + if ( CUR.GS.freeVector.y != 0 ) + mask &= ~FT_CURVE_TAG_TOUCH_Y; + + CUR.zp0.tags[point] &= mask; + } + + + /* Local variables for Ins_IUP: */ + typedef struct IUP_WorkerRec_ + { + FT_Vector* orgs; /* original and current coordinate */ + FT_Vector* curs; /* arrays */ + FT_Vector* orus; + FT_UInt max_points; + + } IUP_WorkerRec, *IUP_Worker; + + + static void + _iup_worker_shift( IUP_Worker worker, + FT_UInt p1, + FT_UInt p2, + FT_UInt p ) + { + FT_UInt i; + FT_F26Dot6 dx; + + + dx = worker->curs[p].x - worker->orgs[p].x; + if ( dx != 0 ) + { + for ( i = p1; i < p; i++ ) + worker->curs[i].x += dx; + + for ( i = p + 1; i <= p2; i++ ) + worker->curs[i].x += dx; + } + } + + + static void + _iup_worker_interpolate( IUP_Worker worker, + FT_UInt p1, + FT_UInt p2, + FT_UInt ref1, + FT_UInt ref2 ) + { + FT_UInt i; + FT_F26Dot6 orus1, orus2, org1, org2, delta1, delta2; + + + if ( p1 > p2 ) + return; + + if ( BOUNDS( ref1, worker->max_points ) || + BOUNDS( ref2, worker->max_points ) ) + return; + + orus1 = worker->orus[ref1].x; + orus2 = worker->orus[ref2].x; + + if ( orus1 > orus2 ) + { + FT_F26Dot6 tmp_o; + FT_UInt tmp_r; + + + tmp_o = orus1; + orus1 = orus2; + orus2 = tmp_o; + + tmp_r = ref1; + ref1 = ref2; + ref2 = tmp_r; + } + + org1 = worker->orgs[ref1].x; + org2 = worker->orgs[ref2].x; + delta1 = worker->curs[ref1].x - org1; + delta2 = worker->curs[ref2].x - org2; + + if ( orus1 == orus2 ) + { + /* simple shift of untouched points */ + for ( i = p1; i <= p2; i++ ) + { + FT_F26Dot6 x = worker->orgs[i].x; + + + if ( x <= org1 ) + x += delta1; + else + x += delta2; + + worker->curs[i].x = x; + } + } + else + { + FT_Fixed scale = 0; + FT_Bool scale_valid = 0; + + + /* interpolation */ + for ( i = p1; i <= p2; i++ ) + { + FT_F26Dot6 x = worker->orgs[i].x; + + + if ( x <= org1 ) + x += delta1; + + else if ( x >= org2 ) + x += delta2; + + else + { + if ( !scale_valid ) + { + scale_valid = 1; + scale = TT_MULDIV( org2 + delta2 - ( org1 + delta1 ), + 0x10000L, orus2 - orus1 ); + } + + x = ( org1 + delta1 ) + + TT_MULFIX( worker->orus[i].x - orus1, scale ); + } + worker->curs[i].x = x; + } + } + } + + + /*************************************************************************/ + /* */ + /* IUP[a]: Interpolate Untouched Points */ + /* Opcode range: 0x30-0x31 */ + /* Stack: --> */ + /* */ + static void + Ins_IUP( INS_ARG ) + { + IUP_WorkerRec V; + FT_Byte mask; + + FT_UInt first_point; /* first point of contour */ + FT_UInt end_point; /* end point (last+1) of contour */ + + FT_UInt first_touched; /* first touched point in contour */ + FT_UInt cur_touched; /* current touched point in contour */ + + FT_UInt point; /* current point */ + FT_Short contour; /* current contour */ + + FT_UNUSED_ARG; + + + /* ignore empty outlines */ + if ( CUR.pts.n_contours == 0 ) + return; + + if ( CUR.opcode & 1 ) + { + mask = FT_CURVE_TAG_TOUCH_X; + V.orgs = CUR.pts.org; + V.curs = CUR.pts.cur; + V.orus = CUR.pts.orus; + } + else + { + mask = FT_CURVE_TAG_TOUCH_Y; + V.orgs = (FT_Vector*)( (FT_Pos*)CUR.pts.org + 1 ); + V.curs = (FT_Vector*)( (FT_Pos*)CUR.pts.cur + 1 ); + V.orus = (FT_Vector*)( (FT_Pos*)CUR.pts.orus + 1 ); + } + V.max_points = CUR.pts.n_points; + + contour = 0; + point = 0; + + do + { + end_point = CUR.pts.contours[contour] - CUR.pts.first_point; + first_point = point; + + if ( CUR.pts.n_points <= end_point ) + end_point = CUR.pts.n_points; + + while ( point <= end_point && ( CUR.pts.tags[point] & mask ) == 0 ) + point++; + + if ( point <= end_point ) + { + first_touched = point; + cur_touched = point; + + point++; + + while ( point <= end_point ) + { + if ( ( CUR.pts.tags[point] & mask ) != 0 ) + { + if ( point > 0 ) + _iup_worker_interpolate( &V, + cur_touched + 1, + point - 1, + cur_touched, + point ); + cur_touched = point; + } + + point++; + } + + if ( cur_touched == first_touched ) + _iup_worker_shift( &V, first_point, end_point, cur_touched ); + else + { + _iup_worker_interpolate( &V, + (FT_UShort)( cur_touched + 1 ), + end_point, + cur_touched, + first_touched ); + + if ( first_touched > 0 ) + _iup_worker_interpolate( &V, + first_point, + first_touched - 1, + cur_touched, + first_touched ); + } + } + contour++; + } while ( contour < CUR.pts.n_contours ); + } + + + /*************************************************************************/ + /* */ + /* DELTAPn[]: DELTA exceptions P1, P2, P3 */ + /* Opcode range: 0x5D,0x71,0x72 */ + /* Stack: uint32 (2 * uint32)... --> */ + /* */ + static void + Ins_DELTAP( INS_ARG ) + { + FT_ULong k, nump; + FT_UShort A; + FT_ULong C; + FT_Long B; + + +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING + /* Delta hinting is covered by US Patent 5159668. */ + if ( CUR.face->unpatented_hinting ) + { + FT_Long n = args[0] * 2; + + + if ( CUR.args < n ) + { + CUR.error = TT_Err_Too_Few_Arguments; + return; + } + + CUR.args -= n; + CUR.new_top = CUR.args; + return; + } +#endif + + nump = (FT_ULong)args[0]; /* some points theoretically may occur more + than once, thus UShort isn't enough */ + + for ( k = 1; k <= nump; k++ ) + { + if ( CUR.args < 2 ) + { + CUR.error = TT_Err_Too_Few_Arguments; + return; + } + + CUR.args -= 2; + + A = (FT_UShort)CUR.stack[CUR.args + 1]; + B = CUR.stack[CUR.args]; + + /* XXX: Because some popular fonts contain some invalid DeltaP */ + /* instructions, we simply ignore them when the stacked */ + /* point reference is off limit, rather than returning an */ + /* error. As a delta instruction doesn't change a glyph */ + /* in great ways, this shouldn't be a problem. */ + + if ( !BOUNDS( A, CUR.zp0.n_points ) ) + { + C = ( (FT_ULong)B & 0xF0 ) >> 4; + + switch ( CUR.opcode ) + { + case 0x5D: + break; + + case 0x71: + C += 16; + break; + + case 0x72: + C += 32; + break; + } + + C += CUR.GS.delta_base; + + if ( CURRENT_Ppem() == (FT_Long)C ) + { + B = ( (FT_ULong)B & 0xF ) - 8; + if ( B >= 0 ) + B++; + B = B * 64 / ( 1L << CUR.GS.delta_shift ); + + CUR_Func_move( &CUR.zp0, A, B ); + } + } + else + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + } + + CUR.new_top = CUR.args; + } + + + /*************************************************************************/ + /* */ + /* DELTACn[]: DELTA exceptions C1, C2, C3 */ + /* Opcode range: 0x73,0x74,0x75 */ + /* Stack: uint32 (2 * uint32)... --> */ + /* */ + static void + Ins_DELTAC( INS_ARG ) + { + FT_ULong nump, k; + FT_ULong A, C; + FT_Long B; + + +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING + /* Delta hinting is covered by US Patent 5159668. */ + if ( CUR.face->unpatented_hinting ) + { + FT_Long n = args[0] * 2; + + + if ( CUR.args < n ) + { + CUR.error = TT_Err_Too_Few_Arguments; + return; + } + + CUR.args -= n; + CUR.new_top = CUR.args; + return; + } +#endif + + nump = (FT_ULong)args[0]; + + for ( k = 1; k <= nump; k++ ) + { + if ( CUR.args < 2 ) + { + CUR.error = TT_Err_Too_Few_Arguments; + return; + } + + CUR.args -= 2; + + A = (FT_ULong)CUR.stack[CUR.args + 1]; + B = CUR.stack[CUR.args]; + + if ( BOUNDS( A, CUR.cvtSize ) ) + { + if ( CUR.pedantic_hinting ) + { + CUR.error = TT_Err_Invalid_Reference; + return; + } + } + else + { + C = ( (FT_ULong)B & 0xF0 ) >> 4; + + switch ( CUR.opcode ) + { + case 0x73: + break; + + case 0x74: + C += 16; + break; + + case 0x75: + C += 32; + break; + } + + C += CUR.GS.delta_base; + + if ( CURRENT_Ppem() == (FT_Long)C ) + { + B = ( (FT_ULong)B & 0xF ) - 8; + if ( B >= 0 ) + B++; + B = B * 64 / ( 1L << CUR.GS.delta_shift ); + + CUR_Func_move_cvt( A, B ); + } + } + } + + CUR.new_top = CUR.args; + } + + + /*************************************************************************/ + /* */ + /* MISC. INSTRUCTIONS */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* GETINFO[]: GET INFOrmation */ + /* Opcode range: 0x88 */ + /* Stack: uint32 --> uint32 */ + /* */ + static void + Ins_GETINFO( INS_ARG ) + { + FT_Long K; + + + K = 0; + + /* We return MS rasterizer version 1.7 for the font scaler. */ + if ( ( args[0] & 1 ) != 0 ) + K = 35; + + /* Has the glyph been rotated? */ + if ( ( args[0] & 2 ) != 0 && CUR.tt_metrics.rotated ) + K |= 0x80; + + /* Has the glyph been stretched? */ + if ( ( args[0] & 4 ) != 0 && CUR.tt_metrics.stretched ) + K |= 1 << 8; + + /* Are we hinting for grayscale? */ + if ( ( args[0] & 32 ) != 0 && CUR.grayscale ) + K |= 1 << 12; + + args[0] = K; + } + + + static void + Ins_UNKNOWN( INS_ARG ) + { + TT_DefRecord* def = CUR.IDefs; + TT_DefRecord* limit = def + CUR.numIDefs; + + FT_UNUSED_ARG; + + + for ( ; def < limit; def++ ) + { + if ( (FT_Byte)def->opc == CUR.opcode && def->active ) + { + TT_CallRec* call; + + + if ( CUR.callTop >= CUR.callSize ) + { + CUR.error = TT_Err_Stack_Overflow; + return; + } + + call = CUR.callStack + CUR.callTop++; + + call->Caller_Range = CUR.curRange; + call->Caller_IP = CUR.IP+1; + call->Cur_Count = 1; + call->Cur_Restart = def->start; + + INS_Goto_CodeRange( def->range, def->start ); + + CUR.step_ins = FALSE; + return; + } + } + + CUR.error = TT_Err_Invalid_Opcode; + } + + +#ifndef TT_CONFIG_OPTION_INTERPRETER_SWITCH + + + static + TInstruction_Function Instruct_Dispatch[256] = + { + /* Opcodes are gathered in groups of 16. */ + /* Please keep the spaces as they are. */ + + /* SVTCA y */ Ins_SVTCA, + /* SVTCA x */ Ins_SVTCA, + /* SPvTCA y */ Ins_SPVTCA, + /* SPvTCA x */ Ins_SPVTCA, + /* SFvTCA y */ Ins_SFVTCA, + /* SFvTCA x */ Ins_SFVTCA, + /* SPvTL // */ Ins_SPVTL, + /* SPvTL + */ Ins_SPVTL, + /* SFvTL // */ Ins_SFVTL, + /* SFvTL + */ Ins_SFVTL, + /* SPvFS */ Ins_SPVFS, + /* SFvFS */ Ins_SFVFS, + /* GPV */ Ins_GPV, + /* GFV */ Ins_GFV, + /* SFvTPv */ Ins_SFVTPV, + /* ISECT */ Ins_ISECT, + + /* SRP0 */ Ins_SRP0, + /* SRP1 */ Ins_SRP1, + /* SRP2 */ Ins_SRP2, + /* SZP0 */ Ins_SZP0, + /* SZP1 */ Ins_SZP1, + /* SZP2 */ Ins_SZP2, + /* SZPS */ Ins_SZPS, + /* SLOOP */ Ins_SLOOP, + /* RTG */ Ins_RTG, + /* RTHG */ Ins_RTHG, + /* SMD */ Ins_SMD, + /* ELSE */ Ins_ELSE, + /* JMPR */ Ins_JMPR, + /* SCvTCi */ Ins_SCVTCI, + /* SSwCi */ Ins_SSWCI, + /* SSW */ Ins_SSW, + + /* DUP */ Ins_DUP, + /* POP */ Ins_POP, + /* CLEAR */ Ins_CLEAR, + /* SWAP */ Ins_SWAP, + /* DEPTH */ Ins_DEPTH, + /* CINDEX */ Ins_CINDEX, + /* MINDEX */ Ins_MINDEX, + /* AlignPTS */ Ins_ALIGNPTS, + /* INS_0x28 */ Ins_UNKNOWN, + /* UTP */ Ins_UTP, + /* LOOPCALL */ Ins_LOOPCALL, + /* CALL */ Ins_CALL, + /* FDEF */ Ins_FDEF, + /* ENDF */ Ins_ENDF, + /* MDAP[0] */ Ins_MDAP, + /* MDAP[1] */ Ins_MDAP, + + /* IUP[0] */ Ins_IUP, + /* IUP[1] */ Ins_IUP, + /* SHP[0] */ Ins_SHP, + /* SHP[1] */ Ins_SHP, + /* SHC[0] */ Ins_SHC, + /* SHC[1] */ Ins_SHC, + /* SHZ[0] */ Ins_SHZ, + /* SHZ[1] */ Ins_SHZ, + /* SHPIX */ Ins_SHPIX, + /* IP */ Ins_IP, + /* MSIRP[0] */ Ins_MSIRP, + /* MSIRP[1] */ Ins_MSIRP, + /* AlignRP */ Ins_ALIGNRP, + /* RTDG */ Ins_RTDG, + /* MIAP[0] */ Ins_MIAP, + /* MIAP[1] */ Ins_MIAP, + + /* NPushB */ Ins_NPUSHB, + /* NPushW */ Ins_NPUSHW, + /* WS */ Ins_WS, + /* RS */ Ins_RS, + /* WCvtP */ Ins_WCVTP, + /* RCvt */ Ins_RCVT, + /* GC[0] */ Ins_GC, + /* GC[1] */ Ins_GC, + /* SCFS */ Ins_SCFS, + /* MD[0] */ Ins_MD, + /* MD[1] */ Ins_MD, + /* MPPEM */ Ins_MPPEM, + /* MPS */ Ins_MPS, + /* FlipON */ Ins_FLIPON, + /* FlipOFF */ Ins_FLIPOFF, + /* DEBUG */ Ins_DEBUG, + + /* LT */ Ins_LT, + /* LTEQ */ Ins_LTEQ, + /* GT */ Ins_GT, + /* GTEQ */ Ins_GTEQ, + /* EQ */ Ins_EQ, + /* NEQ */ Ins_NEQ, + /* ODD */ Ins_ODD, + /* EVEN */ Ins_EVEN, + /* IF */ Ins_IF, + /* EIF */ Ins_EIF, + /* AND */ Ins_AND, + /* OR */ Ins_OR, + /* NOT */ Ins_NOT, + /* DeltaP1 */ Ins_DELTAP, + /* SDB */ Ins_SDB, + /* SDS */ Ins_SDS, + + /* ADD */ Ins_ADD, + /* SUB */ Ins_SUB, + /* DIV */ Ins_DIV, + /* MUL */ Ins_MUL, + /* ABS */ Ins_ABS, + /* NEG */ Ins_NEG, + /* FLOOR */ Ins_FLOOR, + /* CEILING */ Ins_CEILING, + /* ROUND[0] */ Ins_ROUND, + /* ROUND[1] */ Ins_ROUND, + /* ROUND[2] */ Ins_ROUND, + /* ROUND[3] */ Ins_ROUND, + /* NROUND[0] */ Ins_NROUND, + /* NROUND[1] */ Ins_NROUND, + /* NROUND[2] */ Ins_NROUND, + /* NROUND[3] */ Ins_NROUND, + + /* WCvtF */ Ins_WCVTF, + /* DeltaP2 */ Ins_DELTAP, + /* DeltaP3 */ Ins_DELTAP, + /* DeltaCn[0] */ Ins_DELTAC, + /* DeltaCn[1] */ Ins_DELTAC, + /* DeltaCn[2] */ Ins_DELTAC, + /* SROUND */ Ins_SROUND, + /* S45Round */ Ins_S45ROUND, + /* JROT */ Ins_JROT, + /* JROF */ Ins_JROF, + /* ROFF */ Ins_ROFF, + /* INS_0x7B */ Ins_UNKNOWN, + /* RUTG */ Ins_RUTG, + /* RDTG */ Ins_RDTG, + /* SANGW */ Ins_SANGW, + /* AA */ Ins_AA, + + /* FlipPT */ Ins_FLIPPT, + /* FlipRgON */ Ins_FLIPRGON, + /* FlipRgOFF */ Ins_FLIPRGOFF, + /* INS_0x83 */ Ins_UNKNOWN, + /* INS_0x84 */ Ins_UNKNOWN, + /* ScanCTRL */ Ins_SCANCTRL, + /* SDPVTL[0] */ Ins_SDPVTL, + /* SDPVTL[1] */ Ins_SDPVTL, + /* GetINFO */ Ins_GETINFO, + /* IDEF */ Ins_IDEF, + /* ROLL */ Ins_ROLL, + /* MAX */ Ins_MAX, + /* MIN */ Ins_MIN, + /* ScanTYPE */ Ins_SCANTYPE, + /* InstCTRL */ Ins_INSTCTRL, + /* INS_0x8F */ Ins_UNKNOWN, + + /* INS_0x90 */ Ins_UNKNOWN, + /* INS_0x91 */ Ins_UNKNOWN, + /* INS_0x92 */ Ins_UNKNOWN, + /* INS_0x93 */ Ins_UNKNOWN, + /* INS_0x94 */ Ins_UNKNOWN, + /* INS_0x95 */ Ins_UNKNOWN, + /* INS_0x96 */ Ins_UNKNOWN, + /* INS_0x97 */ Ins_UNKNOWN, + /* INS_0x98 */ Ins_UNKNOWN, + /* INS_0x99 */ Ins_UNKNOWN, + /* INS_0x9A */ Ins_UNKNOWN, + /* INS_0x9B */ Ins_UNKNOWN, + /* INS_0x9C */ Ins_UNKNOWN, + /* INS_0x9D */ Ins_UNKNOWN, + /* INS_0x9E */ Ins_UNKNOWN, + /* INS_0x9F */ Ins_UNKNOWN, + + /* INS_0xA0 */ Ins_UNKNOWN, + /* INS_0xA1 */ Ins_UNKNOWN, + /* INS_0xA2 */ Ins_UNKNOWN, + /* INS_0xA3 */ Ins_UNKNOWN, + /* INS_0xA4 */ Ins_UNKNOWN, + /* INS_0xA5 */ Ins_UNKNOWN, + /* INS_0xA6 */ Ins_UNKNOWN, + /* INS_0xA7 */ Ins_UNKNOWN, + /* INS_0xA8 */ Ins_UNKNOWN, + /* INS_0xA9 */ Ins_UNKNOWN, + /* INS_0xAA */ Ins_UNKNOWN, + /* INS_0xAB */ Ins_UNKNOWN, + /* INS_0xAC */ Ins_UNKNOWN, + /* INS_0xAD */ Ins_UNKNOWN, + /* INS_0xAE */ Ins_UNKNOWN, + /* INS_0xAF */ Ins_UNKNOWN, + + /* PushB[0] */ Ins_PUSHB, + /* PushB[1] */ Ins_PUSHB, + /* PushB[2] */ Ins_PUSHB, + /* PushB[3] */ Ins_PUSHB, + /* PushB[4] */ Ins_PUSHB, + /* PushB[5] */ Ins_PUSHB, + /* PushB[6] */ Ins_PUSHB, + /* PushB[7] */ Ins_PUSHB, + /* PushW[0] */ Ins_PUSHW, + /* PushW[1] */ Ins_PUSHW, + /* PushW[2] */ Ins_PUSHW, + /* PushW[3] */ Ins_PUSHW, + /* PushW[4] */ Ins_PUSHW, + /* PushW[5] */ Ins_PUSHW, + /* PushW[6] */ Ins_PUSHW, + /* PushW[7] */ Ins_PUSHW, + + /* MDRP[00] */ Ins_MDRP, + /* MDRP[01] */ Ins_MDRP, + /* MDRP[02] */ Ins_MDRP, + /* MDRP[03] */ Ins_MDRP, + /* MDRP[04] */ Ins_MDRP, + /* MDRP[05] */ Ins_MDRP, + /* MDRP[06] */ Ins_MDRP, + /* MDRP[07] */ Ins_MDRP, + /* MDRP[08] */ Ins_MDRP, + /* MDRP[09] */ Ins_MDRP, + /* MDRP[10] */ Ins_MDRP, + /* MDRP[11] */ Ins_MDRP, + /* MDRP[12] */ Ins_MDRP, + /* MDRP[13] */ Ins_MDRP, + /* MDRP[14] */ Ins_MDRP, + /* MDRP[15] */ Ins_MDRP, + + /* MDRP[16] */ Ins_MDRP, + /* MDRP[17] */ Ins_MDRP, + /* MDRP[18] */ Ins_MDRP, + /* MDRP[19] */ Ins_MDRP, + /* MDRP[20] */ Ins_MDRP, + /* MDRP[21] */ Ins_MDRP, + /* MDRP[22] */ Ins_MDRP, + /* MDRP[23] */ Ins_MDRP, + /* MDRP[24] */ Ins_MDRP, + /* MDRP[25] */ Ins_MDRP, + /* MDRP[26] */ Ins_MDRP, + /* MDRP[27] */ Ins_MDRP, + /* MDRP[28] */ Ins_MDRP, + /* MDRP[29] */ Ins_MDRP, + /* MDRP[30] */ Ins_MDRP, + /* MDRP[31] */ Ins_MDRP, + + /* MIRP[00] */ Ins_MIRP, + /* MIRP[01] */ Ins_MIRP, + /* MIRP[02] */ Ins_MIRP, + /* MIRP[03] */ Ins_MIRP, + /* MIRP[04] */ Ins_MIRP, + /* MIRP[05] */ Ins_MIRP, + /* MIRP[06] */ Ins_MIRP, + /* MIRP[07] */ Ins_MIRP, + /* MIRP[08] */ Ins_MIRP, + /* MIRP[09] */ Ins_MIRP, + /* MIRP[10] */ Ins_MIRP, + /* MIRP[11] */ Ins_MIRP, + /* MIRP[12] */ Ins_MIRP, + /* MIRP[13] */ Ins_MIRP, + /* MIRP[14] */ Ins_MIRP, + /* MIRP[15] */ Ins_MIRP, + + /* MIRP[16] */ Ins_MIRP, + /* MIRP[17] */ Ins_MIRP, + /* MIRP[18] */ Ins_MIRP, + /* MIRP[19] */ Ins_MIRP, + /* MIRP[20] */ Ins_MIRP, + /* MIRP[21] */ Ins_MIRP, + /* MIRP[22] */ Ins_MIRP, + /* MIRP[23] */ Ins_MIRP, + /* MIRP[24] */ Ins_MIRP, + /* MIRP[25] */ Ins_MIRP, + /* MIRP[26] */ Ins_MIRP, + /* MIRP[27] */ Ins_MIRP, + /* MIRP[28] */ Ins_MIRP, + /* MIRP[29] */ Ins_MIRP, + /* MIRP[30] */ Ins_MIRP, + /* MIRP[31] */ Ins_MIRP + }; + + +#endif /* !TT_CONFIG_OPTION_INTERPRETER_SWITCH */ + + + /*************************************************************************/ + /* */ + /* RUN */ + /* */ + /* This function executes a run of opcodes. It will exit in the */ + /* following cases: */ + /* */ + /* - Errors (in which case it returns FALSE). */ + /* */ + /* - Reaching the end of the main code range (returns TRUE). */ + /* Reaching the end of a code range within a function call is an */ + /* error. */ + /* */ + /* - After executing one single opcode, if the flag `Instruction_Trap' */ + /* is set to TRUE (returns TRUE). */ + /* */ + /* On exit with TRUE, test IP < CodeSize to know whether it comes from */ + /* an instruction trap or a normal termination. */ + /* */ + /* */ + /* Note: The documented DEBUG opcode pops a value from the stack. This */ + /* behaviour is unsupported; here a DEBUG opcode is always an */ + /* error. */ + /* */ + /* */ + /* THIS IS THE INTERPRETER'S MAIN LOOP. */ + /* */ + /* Instructions appear in the specification's order. */ + /* */ + /*************************************************************************/ + + + /* documentation is in ttinterp.h */ + + FT_EXPORT_DEF( FT_Error ) + TT_RunIns( TT_ExecContext exc ) + { + FT_Long ins_counter = 0; /* executed instructions counter */ + + +#ifdef TT_CONFIG_OPTION_STATIC_RASTER + cur = *exc; +#endif + + /* set CVT functions */ + CUR.tt_metrics.ratio = 0; + if ( CUR.metrics.x_ppem != CUR.metrics.y_ppem ) + { + /* non-square pixels, use the stretched routines */ + CUR.func_read_cvt = Read_CVT_Stretched; + CUR.func_write_cvt = Write_CVT_Stretched; + CUR.func_move_cvt = Move_CVT_Stretched; + } + else + { + /* square pixels, use normal routines */ + CUR.func_read_cvt = Read_CVT; + CUR.func_write_cvt = Write_CVT; + CUR.func_move_cvt = Move_CVT; + } + + COMPUTE_Funcs(); + COMPUTE_Round( (FT_Byte)exc->GS.round_state ); + + do + { + CUR.opcode = CUR.code[CUR.IP]; + + if ( ( CUR.length = opcode_length[CUR.opcode] ) < 0 ) + { + if ( CUR.IP + 1 > CUR.codeSize ) + goto LErrorCodeOverflow_; + + CUR.length = 2 - CUR.length * CUR.code[CUR.IP + 1]; + } + + if ( CUR.IP + CUR.length > CUR.codeSize ) + goto LErrorCodeOverflow_; + + /* First, let's check for empty stack and overflow */ + CUR.args = CUR.top - ( Pop_Push_Count[CUR.opcode] >> 4 ); + + /* `args' is the top of the stack once arguments have been popped. */ + /* One can also interpret it as the index of the last argument. */ + if ( CUR.args < 0 ) + { + CUR.error = TT_Err_Too_Few_Arguments; + goto LErrorLabel_; + } + + CUR.new_top = CUR.args + ( Pop_Push_Count[CUR.opcode] & 15 ); + + /* `new_top' is the new top of the stack, after the instruction's */ + /* execution. `top' will be set to `new_top' after the `switch' */ + /* statement. */ + if ( CUR.new_top > CUR.stackSize ) + { + CUR.error = TT_Err_Stack_Overflow; + goto LErrorLabel_; + } + + CUR.step_ins = TRUE; + CUR.error = TT_Err_Ok; + +#ifdef TT_CONFIG_OPTION_INTERPRETER_SWITCH + + { + FT_Long* args = CUR.stack + CUR.args; + FT_Byte opcode = CUR.opcode; + + +#undef ARRAY_BOUND_ERROR +#define ARRAY_BOUND_ERROR goto Set_Invalid_Ref + + + switch ( opcode ) + { + case 0x00: /* SVTCA y */ + case 0x01: /* SVTCA x */ + case 0x02: /* SPvTCA y */ + case 0x03: /* SPvTCA x */ + case 0x04: /* SFvTCA y */ + case 0x05: /* SFvTCA x */ + { + FT_Short AA, BB; + + + AA = (FT_Short)( ( opcode & 1 ) << 14 ); + BB = (FT_Short)( AA ^ 0x4000 ); + + if ( opcode < 4 ) + { + CUR.GS.projVector.x = AA; + CUR.GS.projVector.y = BB; + + CUR.GS.dualVector.x = AA; + CUR.GS.dualVector.y = BB; + } + else + { + GUESS_VECTOR( projVector ); + } + + if ( ( opcode & 2 ) == 0 ) + { + CUR.GS.freeVector.x = AA; + CUR.GS.freeVector.y = BB; + } + else + { + GUESS_VECTOR( freeVector ); + } + + COMPUTE_Funcs(); + } + break; + + case 0x06: /* SPvTL // */ + case 0x07: /* SPvTL + */ + DO_SPVTL + break; + + case 0x08: /* SFvTL // */ + case 0x09: /* SFvTL + */ + DO_SFVTL + break; + + case 0x0A: /* SPvFS */ + DO_SPVFS + break; + + case 0x0B: /* SFvFS */ + DO_SFVFS + break; + + case 0x0C: /* GPV */ + DO_GPV + break; + + case 0x0D: /* GFV */ + DO_GFV + break; + + case 0x0E: /* SFvTPv */ + DO_SFVTPV + break; + + case 0x0F: /* ISECT */ + Ins_ISECT( EXEC_ARG_ args ); + break; + + case 0x10: /* SRP0 */ + DO_SRP0 + break; + + case 0x11: /* SRP1 */ + DO_SRP1 + break; + + case 0x12: /* SRP2 */ + DO_SRP2 + break; + + case 0x13: /* SZP0 */ + Ins_SZP0( EXEC_ARG_ args ); + break; + + case 0x14: /* SZP1 */ + Ins_SZP1( EXEC_ARG_ args ); + break; + + case 0x15: /* SZP2 */ + Ins_SZP2( EXEC_ARG_ args ); + break; + + case 0x16: /* SZPS */ + Ins_SZPS( EXEC_ARG_ args ); + break; + + case 0x17: /* SLOOP */ + DO_SLOOP + break; + + case 0x18: /* RTG */ + DO_RTG + break; + + case 0x19: /* RTHG */ + DO_RTHG + break; + + case 0x1A: /* SMD */ + DO_SMD + break; + + case 0x1B: /* ELSE */ + Ins_ELSE( EXEC_ARG_ args ); + break; + + case 0x1C: /* JMPR */ + DO_JMPR + break; + + case 0x1D: /* SCVTCI */ + DO_SCVTCI + break; + + case 0x1E: /* SSWCI */ + DO_SSWCI + break; + + case 0x1F: /* SSW */ + DO_SSW + break; + + case 0x20: /* DUP */ + DO_DUP + break; + + case 0x21: /* POP */ + /* nothing :-) */ + break; + + case 0x22: /* CLEAR */ + DO_CLEAR + break; + + case 0x23: /* SWAP */ + DO_SWAP + break; + + case 0x24: /* DEPTH */ + DO_DEPTH + break; + + case 0x25: /* CINDEX */ + DO_CINDEX + break; + + case 0x26: /* MINDEX */ + Ins_MINDEX( EXEC_ARG_ args ); + break; + + case 0x27: /* ALIGNPTS */ + Ins_ALIGNPTS( EXEC_ARG_ args ); + break; + + case 0x28: /* ???? */ + Ins_UNKNOWN( EXEC_ARG_ args ); + break; + + case 0x29: /* UTP */ + Ins_UTP( EXEC_ARG_ args ); + break; + + case 0x2A: /* LOOPCALL */ + Ins_LOOPCALL( EXEC_ARG_ args ); + break; + + case 0x2B: /* CALL */ + Ins_CALL( EXEC_ARG_ args ); + break; + + case 0x2C: /* FDEF */ + Ins_FDEF( EXEC_ARG_ args ); + break; + + case 0x2D: /* ENDF */ + Ins_ENDF( EXEC_ARG_ args ); + break; + + case 0x2E: /* MDAP */ + case 0x2F: /* MDAP */ + Ins_MDAP( EXEC_ARG_ args ); + break; + + + case 0x30: /* IUP */ + case 0x31: /* IUP */ + Ins_IUP( EXEC_ARG_ args ); + break; + + case 0x32: /* SHP */ + case 0x33: /* SHP */ + Ins_SHP( EXEC_ARG_ args ); + break; + + case 0x34: /* SHC */ + case 0x35: /* SHC */ + Ins_SHC( EXEC_ARG_ args ); + break; + + case 0x36: /* SHZ */ + case 0x37: /* SHZ */ + Ins_SHZ( EXEC_ARG_ args ); + break; + + case 0x38: /* SHPIX */ + Ins_SHPIX( EXEC_ARG_ args ); + break; + + case 0x39: /* IP */ + Ins_IP( EXEC_ARG_ args ); + break; + + case 0x3A: /* MSIRP */ + case 0x3B: /* MSIRP */ + Ins_MSIRP( EXEC_ARG_ args ); + break; + + case 0x3C: /* AlignRP */ + Ins_ALIGNRP( EXEC_ARG_ args ); + break; + + case 0x3D: /* RTDG */ + DO_RTDG + break; + + case 0x3E: /* MIAP */ + case 0x3F: /* MIAP */ + Ins_MIAP( EXEC_ARG_ args ); + break; + + case 0x40: /* NPUSHB */ + Ins_NPUSHB( EXEC_ARG_ args ); + break; + + case 0x41: /* NPUSHW */ + Ins_NPUSHW( EXEC_ARG_ args ); + break; + + case 0x42: /* WS */ + DO_WS + break; + + Set_Invalid_Ref: + CUR.error = TT_Err_Invalid_Reference; + break; + + case 0x43: /* RS */ + DO_RS + break; + + case 0x44: /* WCVTP */ + DO_WCVTP + break; + + case 0x45: /* RCVT */ + DO_RCVT + break; + + case 0x46: /* GC */ + case 0x47: /* GC */ + Ins_GC( EXEC_ARG_ args ); + break; + + case 0x48: /* SCFS */ + Ins_SCFS( EXEC_ARG_ args ); + break; + + case 0x49: /* MD */ + case 0x4A: /* MD */ + Ins_MD( EXEC_ARG_ args ); + break; + + case 0x4B: /* MPPEM */ + DO_MPPEM + break; + + case 0x4C: /* MPS */ + DO_MPS + break; + + case 0x4D: /* FLIPON */ + DO_FLIPON + break; + + case 0x4E: /* FLIPOFF */ + DO_FLIPOFF + break; + + case 0x4F: /* DEBUG */ + DO_DEBUG + break; + + case 0x50: /* LT */ + DO_LT + break; + + case 0x51: /* LTEQ */ + DO_LTEQ + break; + + case 0x52: /* GT */ + DO_GT + break; + + case 0x53: /* GTEQ */ + DO_GTEQ + break; + + case 0x54: /* EQ */ + DO_EQ + break; + + case 0x55: /* NEQ */ + DO_NEQ + break; + + case 0x56: /* ODD */ + DO_ODD + break; + + case 0x57: /* EVEN */ + DO_EVEN + break; + + case 0x58: /* IF */ + Ins_IF( EXEC_ARG_ args ); + break; + + case 0x59: /* EIF */ + /* do nothing */ + break; + + case 0x5A: /* AND */ + DO_AND + break; + + case 0x5B: /* OR */ + DO_OR + break; + + case 0x5C: /* NOT */ + DO_NOT + break; + + case 0x5D: /* DELTAP1 */ + Ins_DELTAP( EXEC_ARG_ args ); + break; + + case 0x5E: /* SDB */ + DO_SDB + break; + + case 0x5F: /* SDS */ + DO_SDS + break; + + case 0x60: /* ADD */ + DO_ADD + break; + + case 0x61: /* SUB */ + DO_SUB + break; + + case 0x62: /* DIV */ + DO_DIV + break; + + case 0x63: /* MUL */ + DO_MUL + break; + + case 0x64: /* ABS */ + DO_ABS + break; + + case 0x65: /* NEG */ + DO_NEG + break; + + case 0x66: /* FLOOR */ + DO_FLOOR + break; + + case 0x67: /* CEILING */ + DO_CEILING + break; + + case 0x68: /* ROUND */ + case 0x69: /* ROUND */ + case 0x6A: /* ROUND */ + case 0x6B: /* ROUND */ + DO_ROUND + break; + + case 0x6C: /* NROUND */ + case 0x6D: /* NROUND */ + case 0x6E: /* NRRUND */ + case 0x6F: /* NROUND */ + DO_NROUND + break; + + case 0x70: /* WCVTF */ + DO_WCVTF + break; + + case 0x71: /* DELTAP2 */ + case 0x72: /* DELTAP3 */ + Ins_DELTAP( EXEC_ARG_ args ); + break; + + case 0x73: /* DELTAC0 */ + case 0x74: /* DELTAC1 */ + case 0x75: /* DELTAC2 */ + Ins_DELTAC( EXEC_ARG_ args ); + break; + + case 0x76: /* SROUND */ + DO_SROUND + break; + + case 0x77: /* S45Round */ + DO_S45ROUND + break; + + case 0x78: /* JROT */ + DO_JROT + break; + + case 0x79: /* JROF */ + DO_JROF + break; + + case 0x7A: /* ROFF */ + DO_ROFF + break; + + case 0x7B: /* ???? */ + Ins_UNKNOWN( EXEC_ARG_ args ); + break; + + case 0x7C: /* RUTG */ + DO_RUTG + break; + + case 0x7D: /* RDTG */ + DO_RDTG + break; + + case 0x7E: /* SANGW */ + case 0x7F: /* AA */ + /* nothing - obsolete */ + break; + + case 0x80: /* FLIPPT */ + Ins_FLIPPT( EXEC_ARG_ args ); + break; + + case 0x81: /* FLIPRGON */ + Ins_FLIPRGON( EXEC_ARG_ args ); + break; + + case 0x82: /* FLIPRGOFF */ + Ins_FLIPRGOFF( EXEC_ARG_ args ); + break; + + case 0x83: /* UNKNOWN */ + case 0x84: /* UNKNOWN */ + Ins_UNKNOWN( EXEC_ARG_ args ); + break; + + case 0x85: /* SCANCTRL */ + Ins_SCANCTRL( EXEC_ARG_ args ); + break; + + case 0x86: /* SDPVTL */ + case 0x87: /* SDPVTL */ + Ins_SDPVTL( EXEC_ARG_ args ); + break; + + case 0x88: /* GETINFO */ + Ins_GETINFO( EXEC_ARG_ args ); + break; + + case 0x89: /* IDEF */ + Ins_IDEF( EXEC_ARG_ args ); + break; + + case 0x8A: /* ROLL */ + Ins_ROLL( EXEC_ARG_ args ); + break; + + case 0x8B: /* MAX */ + DO_MAX + break; + + case 0x8C: /* MIN */ + DO_MIN + break; + + case 0x8D: /* SCANTYPE */ + Ins_SCANTYPE( EXEC_ARG_ args ); + break; + + case 0x8E: /* INSTCTRL */ + Ins_INSTCTRL( EXEC_ARG_ args ); + break; + + case 0x8F: + Ins_UNKNOWN( EXEC_ARG_ args ); + break; + + default: + if ( opcode >= 0xE0 ) + Ins_MIRP( EXEC_ARG_ args ); + else if ( opcode >= 0xC0 ) + Ins_MDRP( EXEC_ARG_ args ); + else if ( opcode >= 0xB8 ) + Ins_PUSHW( EXEC_ARG_ args ); + else if ( opcode >= 0xB0 ) + Ins_PUSHB( EXEC_ARG_ args ); + else + Ins_UNKNOWN( EXEC_ARG_ args ); + } + + } + +#else + + Instruct_Dispatch[CUR.opcode]( EXEC_ARG_ &CUR.stack[CUR.args] ); + +#endif /* TT_CONFIG_OPTION_INTERPRETER_SWITCH */ + + if ( CUR.error != TT_Err_Ok ) + { + switch ( CUR.error ) + { + case TT_Err_Invalid_Opcode: /* looking for redefined instructions */ + { + TT_DefRecord* def = CUR.IDefs; + TT_DefRecord* limit = def + CUR.numIDefs; + + + for ( ; def < limit; def++ ) + { + if ( def->active && CUR.opcode == (FT_Byte)def->opc ) + { + TT_CallRec* callrec; + + + if ( CUR.callTop >= CUR.callSize ) + { + CUR.error = TT_Err_Invalid_Reference; + goto LErrorLabel_; + } + + callrec = &CUR.callStack[CUR.callTop]; + + callrec->Caller_Range = CUR.curRange; + callrec->Caller_IP = CUR.IP + 1; + callrec->Cur_Count = 1; + callrec->Cur_Restart = def->start; + + if ( INS_Goto_CodeRange( def->range, def->start ) == FAILURE ) + goto LErrorLabel_; + + goto LSuiteLabel_; + } + } + } + + CUR.error = TT_Err_Invalid_Opcode; + goto LErrorLabel_; + +#if 0 + break; /* Unreachable code warning suppression. */ + /* Leave to remind in case a later change the editor */ + /* to consider break; */ +#endif + + default: + goto LErrorLabel_; + +#if 0 + break; +#endif + } + } + + CUR.top = CUR.new_top; + + if ( CUR.step_ins ) + CUR.IP += CUR.length; + + /* increment instruction counter and check if we didn't */ + /* run this program for too long (e.g. infinite loops). */ + if ( ++ins_counter > MAX_RUNNABLE_OPCODES ) + return TT_Err_Execution_Too_Long; + + LSuiteLabel_: + if ( CUR.IP >= CUR.codeSize ) + { + if ( CUR.callTop > 0 ) + { + CUR.error = TT_Err_Code_Overflow; + goto LErrorLabel_; + } + else + goto LNo_Error_; + } + } while ( !CUR.instruction_trap ); + + LNo_Error_: + +#ifdef TT_CONFIG_OPTION_STATIC_RASTER + *exc = cur; +#endif + + return TT_Err_Ok; + + LErrorCodeOverflow_: + CUR.error = TT_Err_Code_Overflow; + + LErrorLabel_: + +#ifdef TT_CONFIG_OPTION_STATIC_RASTER + *exc = cur; +#endif + + return CUR.error; + } + + +#endif /* TT_USE_BYTECODE_INTERPRETER */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/truetype/ttinterp.h b/mod/pub.mod/freetype.mod/src/truetype/ttinterp.h new file mode 100644 index 0000000..07a8972 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/truetype/ttinterp.h @@ -0,0 +1,311 @@ +/***************************************************************************/ +/* */ +/* ttinterp.h */ +/* */ +/* TrueType bytecode interpreter (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __TTINTERP_H__ +#define __TTINTERP_H__ + +#include <ft2build.h> +#include "ttobjs.h" + + +FT_BEGIN_HEADER + + +#ifndef TT_CONFIG_OPTION_STATIC_INTERPRETER /* indirect implementation */ + +#define EXEC_OP_ TT_ExecContext exc, +#define EXEC_OP TT_ExecContext exc +#define EXEC_ARG_ exc, +#define EXEC_ARG exc + +#else /* static implementation */ + +#define EXEC_OP_ /* void */ +#define EXEC_OP /* void */ +#define EXEC_ARG_ /* void */ +#define EXEC_ARG /* void */ + +#endif /* TT_CONFIG_OPTION_STATIC_INTERPRETER */ + + + /*************************************************************************/ + /* */ + /* Rounding mode constants. */ + /* */ +#define TT_Round_Off 5 +#define TT_Round_To_Half_Grid 0 +#define TT_Round_To_Grid 1 +#define TT_Round_To_Double_Grid 2 +#define TT_Round_Up_To_Grid 4 +#define TT_Round_Down_To_Grid 3 +#define TT_Round_Super 6 +#define TT_Round_Super_45 7 + + + /*************************************************************************/ + /* */ + /* Function types used by the interpreter, depending on various modes */ + /* (e.g. the rounding mode, whether to render a vertical or horizontal */ + /* line etc). */ + /* */ + /*************************************************************************/ + + /* Rounding function */ + typedef FT_F26Dot6 + (*TT_Round_Func)( EXEC_OP_ FT_F26Dot6 distance, + FT_F26Dot6 compensation ); + + /* Point displacement along the freedom vector routine */ + typedef void + (*TT_Move_Func)( EXEC_OP_ TT_GlyphZone zone, + FT_UShort point, + FT_F26Dot6 distance ); + + /* Distance projection along one of the projection vectors */ + typedef FT_F26Dot6 + (*TT_Project_Func)( EXEC_OP_ FT_Pos dx, + FT_Pos dy ); + + /* reading a cvt value. Take care of non-square pixels if necessary */ + typedef FT_F26Dot6 + (*TT_Get_CVT_Func)( EXEC_OP_ FT_ULong idx ); + + /* setting or moving a cvt value. Take care of non-square pixels */ + /* if necessary */ + typedef void + (*TT_Set_CVT_Func)( EXEC_OP_ FT_ULong idx, + FT_F26Dot6 value ); + + + /*************************************************************************/ + /* */ + /* This structure defines a call record, used to manage function calls. */ + /* */ + typedef struct TT_CallRec_ + { + FT_Int Caller_Range; + FT_Long Caller_IP; + FT_Long Cur_Count; + FT_Long Cur_Restart; + + } TT_CallRec, *TT_CallStack; + + + /*************************************************************************/ + /* */ + /* The main structure for the interpreter which collects all necessary */ + /* variables and states. */ + /* */ + typedef struct TT_ExecContextRec_ + { + TT_Face face; + TT_Size size; + FT_Memory memory; + + /* instructions state */ + + FT_Error error; /* last execution error */ + + FT_Long top; /* top of exec. stack */ + + FT_UInt stackSize; /* size of exec. stack */ + FT_Long* stack; /* current exec. stack */ + + FT_Long args; + FT_UInt new_top; /* new top after exec. */ + + TT_GlyphZoneRec zp0, /* zone records */ + zp1, + zp2, + pts, + twilight; + + FT_Size_Metrics metrics; + TT_Size_Metrics tt_metrics; /* size metrics */ + + TT_GraphicsState GS; /* current graphics state */ + + FT_Int curRange; /* current code range number */ + FT_Byte* code; /* current code range */ + FT_Long IP; /* current instruction pointer */ + FT_Long codeSize; /* size of current range */ + + FT_Byte opcode; /* current opcode */ + FT_Int length; /* length of current opcode */ + + FT_Bool step_ins; /* true if the interpreter must */ + /* increment IP after ins. exec */ + FT_Long cvtSize; + FT_Long* cvt; + + FT_UInt glyphSize; /* glyph instructions buffer size */ + FT_Byte* glyphIns; /* glyph instructions buffer */ + + FT_UInt numFDefs; /* number of function defs */ + FT_UInt maxFDefs; /* maximum number of function defs */ + TT_DefArray FDefs; /* table of FDefs entries */ + + FT_UInt numIDefs; /* number of instruction defs */ + FT_UInt maxIDefs; /* maximum number of ins defs */ + TT_DefArray IDefs; /* table of IDefs entries */ + + FT_UInt maxFunc; /* maximum function index */ + FT_UInt maxIns; /* maximum instruction index */ + + FT_Int callTop, /* top of call stack during execution */ + callSize; /* size of call stack */ + TT_CallStack callStack; /* call stack */ + + FT_UShort maxPoints; /* capacity of this context's `pts' */ + FT_Short maxContours; /* record, expressed in points and */ + /* contours. */ + + TT_CodeRangeTable codeRangeTable; /* table of valid code ranges */ + /* useful for the debugger */ + + FT_UShort storeSize; /* size of current storage */ + FT_Long* storage; /* storage area */ + + FT_F26Dot6 period; /* values used for the */ + FT_F26Dot6 phase; /* `SuperRounding' */ + FT_F26Dot6 threshold; + +#if 0 + /* this seems to be unused */ + FT_Int cur_ppem; /* ppem along the current proj vector */ +#endif + + FT_Bool instruction_trap; /* If `True', the interpreter will */ + /* exit after each instruction */ + + TT_GraphicsState default_GS; /* graphics state resulting from */ + /* the prep program */ + FT_Bool is_composite; /* true if the glyph is composite */ + FT_Bool pedantic_hinting; /* true if pedantic interpretation */ + + /* latest interpreter additions */ + + FT_Long F_dot_P; /* dot product of freedom and projection */ + /* vectors */ + TT_Round_Func func_round; /* current rounding function */ + + TT_Project_Func func_project, /* current projection function */ + func_dualproj, /* current dual proj. function */ + func_freeProj; /* current freedom proj. func */ + + TT_Move_Func func_move; /* current point move function */ + TT_Move_Func func_move_orig; /* move original position function */ + + TT_Get_CVT_Func func_read_cvt; /* read a cvt entry */ + TT_Set_CVT_Func func_write_cvt; /* write a cvt entry (in pixels) */ + TT_Set_CVT_Func func_move_cvt; /* incr a cvt entry (in pixels) */ + + FT_Bool grayscale; /* are we hinting for grayscale? */ + + } TT_ExecContextRec; + + + extern const TT_GraphicsState tt_default_graphics_state; + + + FT_LOCAL( FT_Error ) + TT_Goto_CodeRange( TT_ExecContext exec, + FT_Int range, + FT_Long IP ); + + FT_LOCAL( FT_Error ) + TT_Set_CodeRange( TT_ExecContext exec, + FT_Int range, + void* base, + FT_Long length ); + + FT_LOCAL( FT_Error ) + TT_Clear_CodeRange( TT_ExecContext exec, + FT_Int range ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* TT_New_Context */ + /* */ + /* <Description> */ + /* Queries the face context for a given font. Note that there is */ + /* now a _single_ execution context in the TrueType driver which is */ + /* shared among faces. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face object. */ + /* */ + /* <Return> */ + /* A handle to the execution context. Initialized for `face'. */ + /* */ + /* <Note> */ + /* Only the glyph loader and debugger should call this function. */ + /* */ + FT_EXPORT( TT_ExecContext ) + TT_New_Context( TT_Driver driver ); + + FT_LOCAL( FT_Error ) + TT_Done_Context( TT_ExecContext exec ); + + FT_LOCAL( FT_Error ) + TT_Load_Context( TT_ExecContext exec, + TT_Face face, + TT_Size size ); + + FT_LOCAL( FT_Error ) + TT_Save_Context( TT_ExecContext exec, + TT_Size ins ); + + FT_LOCAL( FT_Error ) + TT_Run_Context( TT_ExecContext exec, + FT_Bool debug ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* TT_RunIns */ + /* */ + /* <Description> */ + /* Executes one or more instruction in the execution context. This */ + /* is the main function of the TrueType opcode interpreter. */ + /* */ + /* <Input> */ + /* exec :: A handle to the target execution context. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* Only the object manager and debugger should call this function. */ + /* */ + /* This function is publicly exported because it is directly */ + /* invoked by the TrueType debugger. */ + /* */ + FT_EXPORT( FT_Error ) + TT_RunIns( TT_ExecContext exec ); + + +FT_END_HEADER + +#endif /* __TTINTERP_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/truetype/ttobjs.c b/mod/pub.mod/freetype.mod/src/truetype/ttobjs.c new file mode 100644 index 0000000..11d662d --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/truetype/ttobjs.c @@ -0,0 +1,951 @@ +/***************************************************************************/ +/* */ +/* ttobjs.c */ +/* */ +/* Objects manager (body). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_TRUETYPE_TAGS_H +#include FT_INTERNAL_SFNT_H + +#include "ttgload.h" +#include "ttpload.h" + +#include "tterrors.h" + +#ifdef TT_USE_BYTECODE_INTERPRETER +#include "ttinterp.h" +#endif + +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING +#include FT_TRUETYPE_UNPATENTED_H +#endif + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT +#include "ttgxvar.h" +#endif + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_ttobjs + + +#ifdef TT_USE_BYTECODE_INTERPRETER + + /*************************************************************************/ + /* */ + /* GLYPH ZONE FUNCTIONS */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_glyphzone_done */ + /* */ + /* <Description> */ + /* Deallocate a glyph zone. */ + /* */ + /* <Input> */ + /* zone :: A pointer to the target glyph zone. */ + /* */ + FT_LOCAL_DEF( void ) + tt_glyphzone_done( TT_GlyphZone zone ) + { + FT_Memory memory = zone->memory; + + + if ( memory ) + { + FT_FREE( zone->contours ); + FT_FREE( zone->tags ); + FT_FREE( zone->cur ); + FT_FREE( zone->org ); + FT_FREE( zone->orus ); + + zone->max_points = zone->n_points = 0; + zone->max_contours = zone->n_contours = 0; + zone->memory = NULL; + } + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_glyphzone_new */ + /* */ + /* <Description> */ + /* Allocate a new glyph zone. */ + /* */ + /* <Input> */ + /* memory :: A handle to the current memory object. */ + /* */ + /* maxPoints :: The capacity of glyph zone in points. */ + /* */ + /* maxContours :: The capacity of glyph zone in contours. */ + /* */ + /* <Output> */ + /* zone :: A pointer to the target glyph zone record. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_glyphzone_new( FT_Memory memory, + FT_UShort maxPoints, + FT_Short maxContours, + TT_GlyphZone zone ) + { + FT_Error error; + + + FT_MEM_ZERO( zone, sizeof ( *zone ) ); + zone->memory = memory; + + if ( FT_NEW_ARRAY( zone->org, maxPoints ) || + FT_NEW_ARRAY( zone->cur, maxPoints ) || + FT_NEW_ARRAY( zone->orus, maxPoints ) || + FT_NEW_ARRAY( zone->tags, maxPoints ) || + FT_NEW_ARRAY( zone->contours, maxContours ) ) + { + tt_glyphzone_done( zone ); + } + else + { + zone->max_points = maxPoints; + zone->max_contours = maxContours; + } + + return error; + } +#endif /* TT_USE_BYTECODE_INTERPRETER */ + + + /* Compare the face with a list of well-known `tricky' fonts. */ + /* This list shall be expanded as we find more of them. */ + + static FT_Bool + tt_check_trickyness( FT_String* name ) + { +#define TRICK_NAMES_MAX_CHARACTERS 16 +#define TRICK_NAMES_COUNT 7 + static const char trick_names[TRICK_NAMES_COUNT][TRICK_NAMES_MAX_CHARACTERS+1] = + { + "DFKaiSho-SB", /* dfkaisb.ttf */ + "DFKaiShu", + "DFKai-SB", /* kaiu.ttf */ + "HuaTianSongTi?", /* htst3.ttf */ + "MingLiU", /* mingliu.ttf & mingliu.ttc */ + "PMingLiU", /* mingliu.ttc */ + "MingLi43", /* mingli.ttf */ + }; + int nn; + + + if ( !name ) + return FALSE; + + /* Note that we only check the face name at the moment; it might */ + /* be worth to do more checks for a few special cases. */ + for ( nn = 0; nn < TRICK_NAMES_COUNT; nn++ ) + if ( ft_strstr( name, trick_names[nn] ) ) + return TRUE; + + return FALSE; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_init */ + /* */ + /* <Description> */ + /* Initialize a given TrueType face object. */ + /* */ + /* <Input> */ + /* stream :: The source font stream. */ + /* */ + /* face_index :: The index of the font face in the resource. */ + /* */ + /* num_params :: Number of additional generic parameters. Ignored. */ + /* */ + /* params :: Additional generic parameters. Ignored. */ + /* */ + /* <InOut> */ + /* face :: The newly built face object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_init( FT_Stream stream, + FT_Face ttface, /* TT_Face */ + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ) + { + FT_Error error; + FT_Library library; + SFNT_Service sfnt; + TT_Face face = (TT_Face)ttface; + + + library = ttface->driver->root.library; + sfnt = (SFNT_Service)FT_Get_Module_Interface( library, "sfnt" ); + if ( !sfnt ) + goto Bad_Format; + + /* create input stream from resource */ + if ( FT_STREAM_SEEK( 0 ) ) + goto Exit; + + /* check that we have a valid TrueType file */ + error = sfnt->init_face( stream, face, face_index, num_params, params ); + if ( error ) + goto Exit; + + /* We must also be able to accept Mac/GX fonts, as well as OT ones. */ + /* The 0x00020000 tag is completely undocumented; some fonts from */ + /* Arphic made for Chinese Windows 3.1 have this. */ + if ( face->format_tag != 0x00010000L && /* MS fonts */ + face->format_tag != 0x00020000L && /* CJK fonts for Win 3.1 */ + face->format_tag != TTAG_true ) /* Mac fonts */ + { + FT_TRACE2(( "[not a valid TTF font]\n" )); + goto Bad_Format; + } + +#ifdef TT_USE_BYTECODE_INTERPRETER + ttface->face_flags |= FT_FACE_FLAG_HINTER; +#endif + + /* If we are performing a simple font format check, exit immediately. */ + if ( face_index < 0 ) + return TT_Err_Ok; + + /* Load font directory */ + error = sfnt->load_face( stream, face, face_index, num_params, params ); + if ( error ) + goto Exit; + + if ( tt_check_trickyness( ttface->family_name ) ) + ttface->face_flags |= FT_FACE_FLAG_TRICKY; + + error = tt_face_load_hdmx( face, stream ); + if ( error ) + goto Exit; + + if ( FT_IS_SCALABLE( ttface ) ) + { + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + + if ( !ttface->internal->incremental_interface ) + error = tt_face_load_loca( face, stream ); + if ( !error ) + error = tt_face_load_cvt( face, stream ); + if ( !error ) + error = tt_face_load_fpgm( face, stream ); + if ( !error ) + error = tt_face_load_prep( face, stream ); + +#else + + if ( !error ) + error = tt_face_load_loca( face, stream ); + if ( !error ) + error = tt_face_load_cvt( face, stream ); + if ( !error ) + error = tt_face_load_fpgm( face, stream ); + if ( !error ) + error = tt_face_load_prep( face, stream ); + +#endif + + } + +#if defined( TT_CONFIG_OPTION_UNPATENTED_HINTING ) && \ + !defined( TT_CONFIG_OPTION_BYTECODE_INTERPRETER ) + + { + FT_Bool unpatented_hinting; + int i; + + + /* Determine whether unpatented hinting is to be used for this face. */ + unpatented_hinting = FT_BOOL + ( library->debug_hooks[FT_DEBUG_HOOK_UNPATENTED_HINTING] != NULL ); + + for ( i = 0; i < num_params && !face->unpatented_hinting; i++ ) + if ( params[i].tag == FT_PARAM_TAG_UNPATENTED_HINTING ) + unpatented_hinting = TRUE; + + if ( !unpatented_hinting ) + ttface->internal->ignore_unpatented_hinter = TRUE; + } + +#endif /* TT_CONFIG_OPTION_UNPATENTED_HINTING && + !TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ + + /* initialize standard glyph loading routines */ + TT_Init_Glyph_Loading( face ); + + Exit: + return error; + + Bad_Format: + error = TT_Err_Unknown_File_Format; + goto Exit; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_done */ + /* */ + /* <Description> */ + /* Finalize a given face object. */ + /* */ + /* <Input> */ + /* face :: A pointer to the face object to destroy. */ + /* */ + FT_LOCAL_DEF( void ) + tt_face_done( FT_Face ttface ) /* TT_Face */ + { + TT_Face face = (TT_Face)ttface; + FT_Memory memory; + FT_Stream stream; + SFNT_Service sfnt; + + + if ( !face ) + return; + + memory = ttface->memory; + stream = ttface->stream; + sfnt = (SFNT_Service)face->sfnt; + + /* for `extended TrueType formats' (i.e. compressed versions) */ + if ( face->extra.finalizer ) + face->extra.finalizer( face->extra.data ); + + if ( sfnt ) + sfnt->done_face( face ); + + /* freeing the locations table */ + tt_face_done_loca( face ); + + tt_face_free_hdmx( face ); + + /* freeing the CVT */ + FT_FREE( face->cvt ); + face->cvt_size = 0; + + /* freeing the programs */ + FT_FRAME_RELEASE( face->font_program ); + FT_FRAME_RELEASE( face->cvt_program ); + face->font_program_size = 0; + face->cvt_program_size = 0; + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + tt_done_blend( memory, face->blend ); + face->blend = NULL; +#endif + } + + + /*************************************************************************/ + /* */ + /* SIZE FUNCTIONS */ + /* */ + /*************************************************************************/ + +#ifdef TT_USE_BYTECODE_INTERPRETER + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_size_run_fpgm */ + /* */ + /* <Description> */ + /* Run the font program. */ + /* */ + /* <Input> */ + /* size :: A handle to the size object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_size_run_fpgm( TT_Size size ) + { + TT_Face face = (TT_Face)size->root.face; + TT_ExecContext exec; + FT_Error error; + + + /* debugging instances have their own context */ + if ( size->debug ) + exec = size->context; + else + exec = ( (TT_Driver)FT_FACE_DRIVER( face ) )->context; + + if ( !exec ) + return TT_Err_Could_Not_Find_Context; + + TT_Load_Context( exec, face, size ); + + exec->callTop = 0; + exec->top = 0; + + exec->period = 64; + exec->phase = 0; + exec->threshold = 0; + + exec->instruction_trap = FALSE; + exec->F_dot_P = 0x10000L; + + { + FT_Size_Metrics* metrics = &exec->metrics; + TT_Size_Metrics* tt_metrics = &exec->tt_metrics; + + + metrics->x_ppem = 0; + metrics->y_ppem = 0; + metrics->x_scale = 0; + metrics->y_scale = 0; + + tt_metrics->ppem = 0; + tt_metrics->scale = 0; + tt_metrics->ratio = 0x10000L; + } + + /* allow font program execution */ + TT_Set_CodeRange( exec, + tt_coderange_font, + face->font_program, + face->font_program_size ); + + /* disable CVT and glyph programs coderange */ + TT_Clear_CodeRange( exec, tt_coderange_cvt ); + TT_Clear_CodeRange( exec, tt_coderange_glyph ); + + if ( face->font_program_size > 0 ) + { + error = TT_Goto_CodeRange( exec, tt_coderange_font, 0 ); + + if ( !error ) + error = face->interpreter( exec ); + } + else + error = TT_Err_Ok; + + if ( !error ) + TT_Save_Context( exec, size ); + + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_size_run_prep */ + /* */ + /* <Description> */ + /* Run the control value program. */ + /* */ + /* <Input> */ + /* size :: A handle to the size object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_size_run_prep( TT_Size size ) + { + TT_Face face = (TT_Face)size->root.face; + TT_ExecContext exec; + FT_Error error; + + + /* debugging instances have their own context */ + if ( size->debug ) + exec = size->context; + else + exec = ( (TT_Driver)FT_FACE_DRIVER( face ) )->context; + + if ( !exec ) + return TT_Err_Could_Not_Find_Context; + + TT_Load_Context( exec, face, size ); + + exec->callTop = 0; + exec->top = 0; + + exec->instruction_trap = FALSE; + + TT_Set_CodeRange( exec, + tt_coderange_cvt, + face->cvt_program, + face->cvt_program_size ); + + TT_Clear_CodeRange( exec, tt_coderange_glyph ); + + if ( face->cvt_program_size > 0 ) + { + error = TT_Goto_CodeRange( exec, tt_coderange_cvt, 0 ); + + if ( !error && !size->debug ) + error = face->interpreter( exec ); + } + else + error = TT_Err_Ok; + + /* save as default graphics state */ + size->GS = exec->GS; + + TT_Save_Context( exec, size ); + + return error; + } + +#endif /* TT_USE_BYTECODE_INTERPRETER */ + + +#ifdef TT_USE_BYTECODE_INTERPRETER + + static void + tt_size_done_bytecode( FT_Size ftsize ) + { + TT_Size size = (TT_Size)ftsize; + TT_Face face = (TT_Face)ftsize->face; + FT_Memory memory = face->root.memory; + + + if ( size->debug ) + { + /* the debug context must be deleted by the debugger itself */ + size->context = NULL; + size->debug = FALSE; + } + + FT_FREE( size->cvt ); + size->cvt_size = 0; + + /* free storage area */ + FT_FREE( size->storage ); + size->storage_size = 0; + + /* twilight zone */ + tt_glyphzone_done( &size->twilight ); + + FT_FREE( size->function_defs ); + FT_FREE( size->instruction_defs ); + + size->num_function_defs = 0; + size->max_function_defs = 0; + size->num_instruction_defs = 0; + size->max_instruction_defs = 0; + + size->max_func = 0; + size->max_ins = 0; + + size->bytecode_ready = 0; + size->cvt_ready = 0; + } + + + /* Initialize bytecode-related fields in the size object. */ + /* We do this only if bytecode interpretation is really needed. */ + static FT_Error + tt_size_init_bytecode( FT_Size ftsize ) + { + FT_Error error; + TT_Size size = (TT_Size)ftsize; + TT_Face face = (TT_Face)ftsize->face; + FT_Memory memory = face->root.memory; + FT_Int i; + + FT_UShort n_twilight; + TT_MaxProfile* maxp = &face->max_profile; + + + size->bytecode_ready = 1; + size->cvt_ready = 0; + + size->max_function_defs = maxp->maxFunctionDefs; + size->max_instruction_defs = maxp->maxInstructionDefs; + + size->num_function_defs = 0; + size->num_instruction_defs = 0; + + size->max_func = 0; + size->max_ins = 0; + + size->cvt_size = face->cvt_size; + size->storage_size = maxp->maxStorage; + + /* Set default metrics */ + { + TT_Size_Metrics* metrics = &size->ttmetrics; + + + metrics->rotated = FALSE; + metrics->stretched = FALSE; + + /* set default compensation (all 0) */ + for ( i = 0; i < 4; i++ ) + metrics->compensations[i] = 0; + } + + /* allocate function defs, instruction defs, cvt, and storage area */ + if ( FT_NEW_ARRAY( size->function_defs, size->max_function_defs ) || + FT_NEW_ARRAY( size->instruction_defs, size->max_instruction_defs ) || + FT_NEW_ARRAY( size->cvt, size->cvt_size ) || + FT_NEW_ARRAY( size->storage, size->storage_size ) ) + goto Exit; + + /* reserve twilight zone */ + n_twilight = maxp->maxTwilightPoints; + + /* there are 4 phantom points (do we need this?) */ + n_twilight += 4; + + error = tt_glyphzone_new( memory, n_twilight, 0, &size->twilight ); + if ( error ) + goto Exit; + + size->twilight.n_points = n_twilight; + + size->GS = tt_default_graphics_state; + + /* set `face->interpreter' according to the debug hook present */ + { + FT_Library library = face->root.driver->root.library; + + + face->interpreter = (TT_Interpreter) + library->debug_hooks[FT_DEBUG_HOOK_TRUETYPE]; + if ( !face->interpreter ) + face->interpreter = (TT_Interpreter)TT_RunIns; + } + + /* Fine, now run the font program! */ + error = tt_size_run_fpgm( size ); + + Exit: + if ( error ) + tt_size_done_bytecode( ftsize ); + + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + tt_size_ready_bytecode( TT_Size size ) + { + FT_Error error = TT_Err_Ok; + + + if ( !size->bytecode_ready ) + { + error = tt_size_init_bytecode( (FT_Size)size ); + if ( error ) + goto Exit; + } + + /* rescale CVT when needed */ + if ( !size->cvt_ready ) + { + FT_UInt i; + TT_Face face = (TT_Face)size->root.face; + + + /* Scale the cvt values to the new ppem. */ + /* We use by default the y ppem to scale the CVT. */ + for ( i = 0; i < size->cvt_size; i++ ) + size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale ); + + /* all twilight points are originally zero */ + for ( i = 0; i < (FT_UInt)size->twilight.n_points; i++ ) + { + size->twilight.org[i].x = 0; + size->twilight.org[i].y = 0; + size->twilight.cur[i].x = 0; + size->twilight.cur[i].y = 0; + } + + /* clear storage area */ + for ( i = 0; i < (FT_UInt)size->storage_size; i++ ) + size->storage[i] = 0; + + size->GS = tt_default_graphics_state; + + error = tt_size_run_prep( size ); + if ( !error ) + size->cvt_ready = 1; + } + + Exit: + return error; + } + +#endif /* TT_USE_BYTECODE_INTERPRETER */ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_size_init */ + /* */ + /* <Description> */ + /* Initialize a new TrueType size object. */ + /* */ + /* <InOut> */ + /* size :: A handle to the size object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_size_init( FT_Size ttsize ) /* TT_Size */ + { + TT_Size size = (TT_Size)ttsize; + FT_Error error = TT_Err_Ok; + +#ifdef TT_USE_BYTECODE_INTERPRETER + size->bytecode_ready = 0; + size->cvt_ready = 0; +#endif + + size->ttmetrics.valid = FALSE; + size->strike_index = 0xFFFFFFFFUL; + + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_size_done */ + /* */ + /* <Description> */ + /* The TrueType size object finalizer. */ + /* */ + /* <Input> */ + /* size :: A handle to the target size object. */ + /* */ + FT_LOCAL_DEF( void ) + tt_size_done( FT_Size ttsize ) /* TT_Size */ + { + TT_Size size = (TT_Size)ttsize; + + +#ifdef TT_USE_BYTECODE_INTERPRETER + if ( size->bytecode_ready ) + tt_size_done_bytecode( ttsize ); +#endif + + size->ttmetrics.valid = FALSE; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_size_reset */ + /* */ + /* <Description> */ + /* Reset a TrueType size when resolutions and character dimensions */ + /* have been changed. */ + /* */ + /* <Input> */ + /* size :: A handle to the target size object. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_size_reset( TT_Size size ) + { + TT_Face face; + FT_Error error = TT_Err_Ok; + FT_Size_Metrics* metrics; + + + size->ttmetrics.valid = FALSE; + + face = (TT_Face)size->root.face; + + metrics = &size->metrics; + + /* copy the result from base layer */ + *metrics = size->root.metrics; + + if ( metrics->x_ppem < 1 || metrics->y_ppem < 1 ) + return TT_Err_Invalid_PPem; + + /* This bit flag, if set, indicates that the ppems must be */ + /* rounded to integers. Nearly all TrueType fonts have this bit */ + /* set, as hinting won't work really well otherwise. */ + /* */ + if ( face->header.Flags & 8 ) + { + metrics->x_scale = FT_DivFix( metrics->x_ppem << 6, + face->root.units_per_EM ); + metrics->y_scale = FT_DivFix( metrics->y_ppem << 6, + face->root.units_per_EM ); + + metrics->ascender = + FT_PIX_ROUND( FT_MulFix( face->root.ascender, metrics->y_scale ) ); + metrics->descender = + FT_PIX_ROUND( FT_MulFix( face->root.descender, metrics->y_scale ) ); + metrics->height = + FT_PIX_ROUND( FT_MulFix( face->root.height, metrics->y_scale ) ); + metrics->max_advance = + FT_PIX_ROUND( FT_MulFix( face->root.max_advance_width, + metrics->x_scale ) ); + } + + /* compute new transformation */ + if ( metrics->x_ppem >= metrics->y_ppem ) + { + size->ttmetrics.scale = metrics->x_scale; + size->ttmetrics.ppem = metrics->x_ppem; + size->ttmetrics.x_ratio = 0x10000L; + size->ttmetrics.y_ratio = FT_MulDiv( metrics->y_ppem, + 0x10000L, + metrics->x_ppem ); + } + else + { + size->ttmetrics.scale = metrics->y_scale; + size->ttmetrics.ppem = metrics->y_ppem; + size->ttmetrics.x_ratio = FT_MulDiv( metrics->x_ppem, + 0x10000L, + metrics->y_ppem ); + size->ttmetrics.y_ratio = 0x10000L; + } + +#ifdef TT_USE_BYTECODE_INTERPRETER + size->cvt_ready = 0; +#endif /* TT_USE_BYTECODE_INTERPRETER */ + + if ( !error ) + size->ttmetrics.valid = TRUE; + + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_driver_init */ + /* */ + /* <Description> */ + /* Initialize a given TrueType driver object. */ + /* */ + /* <Input> */ + /* driver :: A handle to the target driver object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_driver_init( FT_Module ttdriver ) /* TT_Driver */ + { + +#ifdef TT_USE_BYTECODE_INTERPRETER + + TT_Driver driver = (TT_Driver)ttdriver; + + + if ( !TT_New_Context( driver ) ) + return TT_Err_Could_Not_Find_Context; + +#else + + FT_UNUSED( ttdriver ); + +#endif + + return TT_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_driver_done */ + /* */ + /* <Description> */ + /* Finalize a given TrueType driver. */ + /* */ + /* <Input> */ + /* driver :: A handle to the target TrueType driver. */ + /* */ + FT_LOCAL_DEF( void ) + tt_driver_done( FT_Module ttdriver ) /* TT_Driver */ + { +#ifdef TT_USE_BYTECODE_INTERPRETER + TT_Driver driver = (TT_Driver)ttdriver; + + + /* destroy the execution context */ + if ( driver->context ) + { + TT_Done_Context( driver->context ); + driver->context = NULL; + } +#else + FT_UNUSED( ttdriver ); +#endif + + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_slot_init */ + /* */ + /* <Description> */ + /* Initialize a new slot object. */ + /* */ + /* <InOut> */ + /* slot :: A handle to the slot object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_slot_init( FT_GlyphSlot slot ) + { + return FT_GlyphLoader_CreateExtra( slot->internal->loader ); + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/truetype/ttobjs.h b/mod/pub.mod/freetype.mod/src/truetype/ttobjs.h new file mode 100644 index 0000000..30c8669 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/truetype/ttobjs.h @@ -0,0 +1,431 @@ +/***************************************************************************/ +/* */ +/* ttobjs.h */ +/* */ +/* Objects manager (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __TTOBJS_H__ +#define __TTOBJS_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_TRUETYPE_TYPES_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* TT_Driver */ + /* */ + /* <Description> */ + /* A handle to a TrueType driver object. */ + /* */ + typedef struct TT_DriverRec_* TT_Driver; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* TT_Instance */ + /* */ + /* <Description> */ + /* A handle to a TrueType size object. */ + /* */ + typedef struct TT_SizeRec_* TT_Size; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* TT_GlyphSlot */ + /* */ + /* <Description> */ + /* A handle to a TrueType glyph slot object. */ + /* */ + /* <Note> */ + /* This is a direct typedef of FT_GlyphSlot, as there is nothing */ + /* specific about the TrueType glyph slot. */ + /* */ + typedef FT_GlyphSlot TT_GlyphSlot; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_GraphicsState */ + /* */ + /* <Description> */ + /* The TrueType graphics state used during bytecode interpretation. */ + /* */ + typedef struct TT_GraphicsState_ + { + FT_UShort rp0; + FT_UShort rp1; + FT_UShort rp2; + + FT_UnitVector dualVector; + FT_UnitVector projVector; + FT_UnitVector freeVector; + +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING + FT_Bool both_x_axis; +#endif + + FT_Long loop; + FT_F26Dot6 minimum_distance; + FT_Int round_state; + + FT_Bool auto_flip; + FT_F26Dot6 control_value_cutin; + FT_F26Dot6 single_width_cutin; + FT_F26Dot6 single_width_value; + FT_Short delta_base; + FT_Short delta_shift; + + FT_Byte instruct_control; + /* According to Greg Hitchcock from Microsoft, the `scan_control' */ + /* variable as documented in the TrueType specification is a 32-bit */ + /* integer; the high-word part holds the SCANTYPE value, the low-word */ + /* part the SCANCTRL value. We separate it into two fields. */ + FT_Bool scan_control; + FT_Int scan_type; + + FT_UShort gep0; + FT_UShort gep1; + FT_UShort gep2; + + } TT_GraphicsState; + + +#ifdef TT_USE_BYTECODE_INTERPRETER + + FT_LOCAL( void ) + tt_glyphzone_done( TT_GlyphZone zone ); + + FT_LOCAL( FT_Error ) + tt_glyphzone_new( FT_Memory memory, + FT_UShort maxPoints, + FT_Short maxContours, + TT_GlyphZone zone ); + +#endif /* TT_USE_BYTECODE_INTERPRETER */ + + + + /*************************************************************************/ + /* */ + /* EXECUTION SUBTABLES */ + /* */ + /* These sub-tables relate to instruction execution. */ + /* */ + /*************************************************************************/ + + +#define TT_MAX_CODE_RANGES 3 + + + /*************************************************************************/ + /* */ + /* There can only be 3 active code ranges at once: */ + /* - the Font Program */ + /* - the CVT Program */ + /* - a glyph's instructions set */ + /* */ + typedef enum TT_CodeRange_Tag_ + { + tt_coderange_none = 0, + tt_coderange_font, + tt_coderange_cvt, + tt_coderange_glyph + + } TT_CodeRange_Tag; + + + typedef struct TT_CodeRange_ + { + FT_Byte* base; + FT_ULong size; + + } TT_CodeRange; + + typedef TT_CodeRange TT_CodeRangeTable[TT_MAX_CODE_RANGES]; + + + /*************************************************************************/ + /* */ + /* Defines a function/instruction definition record. */ + /* */ + typedef struct TT_DefRecord_ + { + FT_Int range; /* in which code range is it located? */ + FT_Long start; /* where does it start? */ + FT_UInt opc; /* function #, or instruction code */ + FT_Bool active; /* is it active? */ + + } TT_DefRecord, *TT_DefArray; + + + /*************************************************************************/ + /* */ + /* Subglyph transformation record. */ + /* */ + typedef struct TT_Transform_ + { + FT_Fixed xx, xy; /* transformation matrix coefficients */ + FT_Fixed yx, yy; + FT_F26Dot6 ox, oy; /* offsets */ + + } TT_Transform; + + + /*************************************************************************/ + /* */ + /* A note regarding non-squared pixels: */ + /* */ + /* (This text will probably go into some docs at some time; for now, it */ + /* is kept here to explain some definitions in the TT_Size_Metrics */ + /* record). */ + /* */ + /* The CVT is a one-dimensional array containing values that control */ + /* certain important characteristics in a font, like the height of all */ + /* capitals, all lowercase letter, default spacing or stem width/height. */ + /* */ + /* These values are found in FUnits in the font file, and must be scaled */ + /* to pixel coordinates before being used by the CVT and glyph programs. */ + /* Unfortunately, when using distinct x and y resolutions (or distinct x */ + /* and y pointsizes), there are two possible scalings. */ + /* */ + /* A first try was to implement a `lazy' scheme where all values were */ + /* scaled when first used. However, while some values are always used */ + /* in the same direction, some others are used under many different */ + /* circumstances and orientations. */ + /* */ + /* I have found a simpler way to do the same, and it even seems to work */ + /* in most of the cases: */ + /* */ + /* - All CVT values are scaled to the maximum ppem size. */ + /* */ + /* - When performing a read or write in the CVT, a ratio factor is used */ + /* to perform adequate scaling. Example: */ + /* */ + /* x_ppem = 14 */ + /* y_ppem = 10 */ + /* */ + /* We choose ppem = x_ppem = 14 as the CVT scaling size. All cvt */ + /* entries are scaled to it. */ + /* */ + /* x_ratio = 1.0 */ + /* y_ratio = y_ppem/ppem (< 1.0) */ + /* */ + /* We compute the current ratio like: */ + /* */ + /* - If projVector is horizontal, */ + /* ratio = x_ratio = 1.0 */ + /* */ + /* - if projVector is vertical, */ + /* ratio = y_ratio */ + /* */ + /* - else, */ + /* ratio = sqrt( (proj.x * x_ratio) ^ 2 + (proj.y * y_ratio) ^ 2 ) */ + /* */ + /* Reading a cvt value returns */ + /* ratio * cvt[index] */ + /* */ + /* Writing a cvt value in pixels: */ + /* cvt[index] / ratio */ + /* */ + /* The current ppem is simply */ + /* ratio * ppem */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* Metrics used by the TrueType size and context objects. */ + /* */ + typedef struct TT_Size_Metrics_ + { + /* for non-square pixels */ + FT_Long x_ratio; + FT_Long y_ratio; + + FT_UShort ppem; /* maximum ppem size */ + FT_Long ratio; /* current ratio */ + FT_Fixed scale; + + FT_F26Dot6 compensations[4]; /* device-specific compensations */ + + FT_Bool valid; + + FT_Bool rotated; /* `is the glyph rotated?'-flag */ + FT_Bool stretched; /* `is the glyph stretched?'-flag */ + + } TT_Size_Metrics; + + + /*************************************************************************/ + /* */ + /* TrueType size class. */ + /* */ + typedef struct TT_SizeRec_ + { + FT_SizeRec root; + + /* we have our own copy of metrics so that we can modify */ + /* it without affecting auto-hinting (when used) */ + FT_Size_Metrics metrics; + + TT_Size_Metrics ttmetrics; + + FT_ULong strike_index; /* 0xFFFFFFFF to indicate invalid */ + +#ifdef TT_USE_BYTECODE_INTERPRETER + + FT_UInt num_function_defs; /* number of function definitions */ + FT_UInt max_function_defs; + TT_DefArray function_defs; /* table of function definitions */ + + FT_UInt num_instruction_defs; /* number of ins. definitions */ + FT_UInt max_instruction_defs; + TT_DefArray instruction_defs; /* table of ins. definitions */ + + FT_UInt max_func; + FT_UInt max_ins; + + TT_CodeRangeTable codeRangeTable; + + TT_GraphicsState GS; + + FT_ULong cvt_size; /* the scaled control value table */ + FT_Long* cvt; + + FT_UShort storage_size; /* The storage area is now part of */ + FT_Long* storage; /* the instance */ + + TT_GlyphZoneRec twilight; /* The instance's twilight zone */ + + /* debugging variables */ + + /* When using the debugger, we must keep the */ + /* execution context tied to the instance */ + /* object rather than asking it on demand. */ + + FT_Bool debug; + TT_ExecContext context; + + FT_Bool bytecode_ready; + FT_Bool cvt_ready; + +#endif /* TT_USE_BYTECODE_INTERPRETER */ + + } TT_SizeRec; + + + /*************************************************************************/ + /* */ + /* TrueType driver class. */ + /* */ + typedef struct TT_DriverRec_ + { + FT_DriverRec root; + TT_ExecContext context; /* execution context */ + TT_GlyphZoneRec zone; /* glyph loader points zone */ + + void* extension_component; + + } TT_DriverRec; + + + /* Note: All of the functions below (except tt_size_reset()) are used */ + /* as function pointers in a FT_Driver_ClassRec. Therefore their */ + /* parameters are of types FT_Face, FT_Size, etc., rather than TT_Face, */ + /* TT_Size, etc., so that the compiler can confirm that the types and */ + /* number of parameters are correct. In all cases the FT_xxx types are */ + /* cast to their TT_xxx counterparts inside the functions since FreeType */ + /* will always use the TT driver to create them. */ + + + /*************************************************************************/ + /* */ + /* Face functions */ + /* */ + FT_LOCAL( FT_Error ) + tt_face_init( FT_Stream stream, + FT_Face ttface, /* TT_Face */ + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ); + + FT_LOCAL( void ) + tt_face_done( FT_Face ttface ); /* TT_Face */ + + + /*************************************************************************/ + /* */ + /* Size functions */ + /* */ + FT_LOCAL( FT_Error ) + tt_size_init( FT_Size ttsize ); /* TT_Size */ + + FT_LOCAL( void ) + tt_size_done( FT_Size ttsize ); /* TT_Size */ + +#ifdef TT_USE_BYTECODE_INTERPRETER + + FT_LOCAL( FT_Error ) + tt_size_run_fpgm( TT_Size size ); + + FT_LOCAL( FT_Error ) + tt_size_run_prep( TT_Size size ); + + FT_LOCAL( FT_Error ) + tt_size_ready_bytecode( TT_Size size ); + +#endif /* TT_USE_BYTECODE_INTERPRETER */ + + FT_LOCAL( FT_Error ) + tt_size_reset( TT_Size size ); + + + /*************************************************************************/ + /* */ + /* Driver functions */ + /* */ + FT_LOCAL( FT_Error ) + tt_driver_init( FT_Module ttdriver ); /* TT_Driver */ + + FT_LOCAL( void ) + tt_driver_done( FT_Module ttdriver ); /* TT_Driver */ + + + /*************************************************************************/ + /* */ + /* Slot functions */ + /* */ + FT_LOCAL( FT_Error ) + tt_slot_init( FT_GlyphSlot slot ); + + +FT_END_HEADER + +#endif /* __TTOBJS_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/truetype/ttpic.c b/mod/pub.mod/freetype.mod/src/truetype/ttpic.c new file mode 100644 index 0000000..27ec4a1 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/truetype/ttpic.c @@ -0,0 +1,79 @@ +/***************************************************************************/ +/* */ +/* ttpic.c */ +/* */ +/* The FreeType position independent code services for truetype module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include "ttpic.h" + +#ifdef FT_CONFIG_OPTION_PIC + + /* forward declaration of PIC init functions from ttdriver.c */ + FT_Error FT_Create_Class_tt_services( FT_Library, FT_ServiceDescRec**); + void FT_Destroy_Class_tt_services( FT_Library, FT_ServiceDescRec*); + void FT_Init_Class_tt_service_gx_multi_masters(FT_Service_MultiMastersRec*); + void FT_Init_Class_tt_service_truetype_glyf(FT_Service_TTGlyfRec*); + + void + tt_driver_class_pic_free( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Memory memory = library->memory; + if ( pic_container->truetype ) + { + TTModulePIC* container = (TTModulePIC*)pic_container->truetype; + if(container->tt_services) + FT_Destroy_Class_tt_services(library, container->tt_services); + container->tt_services = NULL; + FT_FREE( container ); + pic_container->truetype = NULL; + } + } + + FT_Error + tt_driver_class_pic_init( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Error error = FT_Err_Ok; + TTModulePIC* container; + FT_Memory memory = library->memory; + + /* allocate pointer, clear and set global container pointer */ + if ( FT_ALLOC ( container, sizeof ( *container ) ) ) + return error; + FT_MEM_SET( container, 0, sizeof(*container) ); + pic_container->truetype = container; + + /* initialize pointer table - this is how the module usually expects this data */ + error = FT_Create_Class_tt_services(library, &container->tt_services); + if(error) + goto Exit; +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + FT_Init_Class_tt_service_gx_multi_masters(&container->tt_service_gx_multi_masters); +#endif + FT_Init_Class_tt_service_truetype_glyf(&container->tt_service_truetype_glyf); +Exit: + if(error) + tt_driver_class_pic_free(library); + return error; + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/truetype/ttpic.h b/mod/pub.mod/freetype.mod/src/truetype/ttpic.h new file mode 100644 index 0000000..84de0fe --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/truetype/ttpic.h @@ -0,0 +1,59 @@ +/***************************************************************************/ +/* */ +/* ttpic.h */ +/* */ +/* The FreeType position independent code services for truetype module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __TTPIC_H__ +#define __TTPIC_H__ + + +FT_BEGIN_HEADER + +#ifndef FT_CONFIG_OPTION_PIC +#define FT_TT_SERVICES_GET tt_services +#define FT_TT_SERVICE_GX_MULTI_MASTERS_GET tt_service_gx_multi_masters +#define FT_TT_SERVICE_TRUETYPE_GLYF_GET tt_service_truetype_glyf + +#else /* FT_CONFIG_OPTION_PIC */ + +#include FT_MULTIPLE_MASTERS_H +#include FT_SERVICE_MULTIPLE_MASTERS_H +#include FT_SERVICE_TRUETYPE_GLYF_H + + typedef struct TTModulePIC_ + { + FT_ServiceDescRec* tt_services; +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + FT_Service_MultiMastersRec tt_service_gx_multi_masters; +#endif + FT_Service_TTGlyfRec tt_service_truetype_glyf; + } TTModulePIC; + +#define GET_PIC(lib) ((TTModulePIC*)((lib)->pic_container.truetype)) +#define FT_TT_SERVICES_GET (GET_PIC(library)->tt_services) +#define FT_TT_SERVICE_GX_MULTI_MASTERS_GET (GET_PIC(library)->tt_service_gx_multi_masters) +#define FT_TT_SERVICE_TRUETYPE_GLYF_GET (GET_PIC(library)->tt_service_truetype_glyf) + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + +FT_END_HEADER + +#endif /* __TTPIC_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/truetype/ttpload.c b/mod/pub.mod/freetype.mod/src/truetype/ttpload.c new file mode 100644 index 0000000..a311b03 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/truetype/ttpload.c @@ -0,0 +1,572 @@ +/***************************************************************************/ +/* */ +/* ttpload.c */ +/* */ +/* TrueType-specific tables loader (body). */ +/* */ +/* Copyright 1996-2001, 2002, 2004, 2005, 2006, 2007, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_STREAM_H +#include FT_TRUETYPE_TAGS_H + +#include "ttpload.h" + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT +#include "ttgxvar.h" +#endif + +#include "tterrors.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_ttpload + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_load_loca */ + /* */ + /* <Description> */ + /* Load the locations table. */ + /* */ + /* <InOut> */ + /* face :: A handle to the target face object. */ + /* */ + /* <Input> */ + /* stream :: The input stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_load_loca( TT_Face face, + FT_Stream stream ) + { + FT_Error error; + FT_ULong table_len; + FT_Int shift; + + + /* we need the size of the `glyf' table for malformed `loca' tables */ + error = face->goto_table( face, TTAG_glyf, stream, &face->glyf_len ); + + /* it is possible that a font doesn't have a glyf table at all */ + /* or its size is zero */ + if ( error == TT_Err_Table_Missing ) + face->glyf_len = 0; + else if ( error ) + goto Exit; + + FT_TRACE2(( "Locations " )); + error = face->goto_table( face, TTAG_loca, stream, &table_len ); + if ( error ) + { + error = TT_Err_Locations_Missing; + goto Exit; + } + + if ( face->header.Index_To_Loc_Format != 0 ) + { + shift = 2; + + if ( table_len >= 0x40000L ) + { + FT_TRACE2(( "table too large\n" )); + error = TT_Err_Invalid_Table; + goto Exit; + } + face->num_locations = table_len >> shift; + } + else + { + shift = 1; + + if ( table_len >= 0x20000L ) + { + FT_TRACE2(( "table too large\n" )); + error = TT_Err_Invalid_Table; + goto Exit; + } + face->num_locations = table_len >> shift; + } + + if ( face->num_locations != (FT_ULong)face->root.num_glyphs ) + { + FT_TRACE2(( "glyph count mismatch! loca: %d, maxp: %d\n", + face->num_locations, face->root.num_glyphs )); + + /* we only handle the case where `maxp' gives a larger value */ + if ( face->num_locations < (FT_ULong)face->root.num_glyphs ) + { + FT_Long new_loca_len = (FT_Long)face->root.num_glyphs << shift; + + TT_Table entry = face->dir_tables; + TT_Table limit = entry + face->num_tables; + + FT_Long pos = FT_Stream_Pos( stream ); + FT_Long dist = 0x7FFFFFFFL; + + + /* compute the distance to next table in font file */ + for ( ; entry < limit; entry++ ) + { + FT_Long diff = entry->Offset - pos; + + + if ( diff > 0 && diff < dist ) + dist = diff; + } + + if ( new_loca_len <= dist ) + { + face->num_locations = face->root.num_glyphs; + table_len = new_loca_len; + + FT_TRACE2(( "adjusting num_locations to %d\n", + face->num_locations )); + } + } + } + + /* + * Extract the frame. We don't need to decompress it since + * we are able to parse it directly. + */ + if ( FT_FRAME_EXTRACT( table_len, face->glyph_locations ) ) + goto Exit; + + FT_TRACE2(( "loaded\n" )); + + Exit: + return error; + } + + + FT_LOCAL_DEF( FT_ULong ) + tt_face_get_location( TT_Face face, + FT_UInt gindex, + FT_UInt *asize ) + { + FT_ULong pos1, pos2; + FT_Byte* p; + FT_Byte* p_limit; + + + pos1 = pos2 = 0; + + if ( gindex < face->num_locations ) + { + if ( face->header.Index_To_Loc_Format != 0 ) + { + p = face->glyph_locations + gindex * 4; + p_limit = face->glyph_locations + face->num_locations * 4; + + pos1 = FT_NEXT_ULONG( p ); + pos2 = pos1; + + if ( p + 4 <= p_limit ) + pos2 = FT_NEXT_ULONG( p ); + } + else + { + p = face->glyph_locations + gindex * 2; + p_limit = face->glyph_locations + face->num_locations * 2; + + pos1 = FT_NEXT_USHORT( p ); + pos2 = pos1; + + if ( p + 2 <= p_limit ) + pos2 = FT_NEXT_USHORT( p ); + + pos1 <<= 1; + pos2 <<= 1; + } + } + + /* The `loca' table must be ordered; it refers to the length of */ + /* an entry as the difference between the current and the next */ + /* position. However, there do exist (malformed) fonts which */ + /* don't obey this rule, so we are only able to provide an */ + /* upper bound for the size. */ + /* */ + /* We get (intentionally) a wrong, non-zero result in case the */ + /* `glyf' table is missing. */ + if ( pos2 >= pos1 ) + *asize = (FT_UInt)( pos2 - pos1 ); + else + *asize = (FT_UInt)( face->glyf_len - pos1 ); + + return pos1; + } + + + FT_LOCAL_DEF( void ) + tt_face_done_loca( TT_Face face ) + { + FT_Stream stream = face->root.stream; + + + FT_FRAME_RELEASE( face->glyph_locations ); + face->num_locations = 0; + } + + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_load_cvt */ + /* */ + /* <Description> */ + /* Load the control value table into a face object. */ + /* */ + /* <InOut> */ + /* face :: A handle to the target face object. */ + /* */ + /* <Input> */ + /* stream :: A handle to the input stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_load_cvt( TT_Face face, + FT_Stream stream ) + { +#ifdef TT_USE_BYTECODE_INTERPRETER + + FT_Error error; + FT_Memory memory = stream->memory; + FT_ULong table_len; + + + FT_TRACE2(( "CVT " )); + + error = face->goto_table( face, TTAG_cvt, stream, &table_len ); + if ( error ) + { + FT_TRACE2(( "is missing\n" )); + + face->cvt_size = 0; + face->cvt = NULL; + error = TT_Err_Ok; + + goto Exit; + } + + face->cvt_size = table_len / 2; + + if ( FT_NEW_ARRAY( face->cvt, face->cvt_size ) ) + goto Exit; + + if ( FT_FRAME_ENTER( face->cvt_size * 2L ) ) + goto Exit; + + { + FT_Short* cur = face->cvt; + FT_Short* limit = cur + face->cvt_size; + + + for ( ; cur < limit; cur++ ) + *cur = FT_GET_SHORT(); + } + + FT_FRAME_EXIT(); + FT_TRACE2(( "loaded\n" )); + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + if ( face->doblend ) + error = tt_face_vary_cvt( face, stream ); +#endif + + Exit: + return error; + +#else /* !TT_USE_BYTECODE_INTERPRETER */ + + FT_UNUSED( face ); + FT_UNUSED( stream ); + + return TT_Err_Ok; + +#endif + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_load_fpgm */ + /* */ + /* <Description> */ + /* Load the font program. */ + /* */ + /* <InOut> */ + /* face :: A handle to the target face object. */ + /* */ + /* <Input> */ + /* stream :: A handle to the input stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_load_fpgm( TT_Face face, + FT_Stream stream ) + { +#ifdef TT_USE_BYTECODE_INTERPRETER + + FT_Error error; + FT_ULong table_len; + + + FT_TRACE2(( "Font program " )); + + /* The font program is optional */ + error = face->goto_table( face, TTAG_fpgm, stream, &table_len ); + if ( error ) + { + face->font_program = NULL; + face->font_program_size = 0; + error = TT_Err_Ok; + + FT_TRACE2(( "is missing\n" )); + } + else + { + face->font_program_size = table_len; + if ( FT_FRAME_EXTRACT( table_len, face->font_program ) ) + goto Exit; + + FT_TRACE2(( "loaded, %12d bytes\n", face->font_program_size )); + } + + Exit: + return error; + +#else /* !TT_USE_BYTECODE_INTERPRETER */ + + FT_UNUSED( face ); + FT_UNUSED( stream ); + + return TT_Err_Ok; + +#endif + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_load_prep */ + /* */ + /* <Description> */ + /* Load the cvt program. */ + /* */ + /* <InOut> */ + /* face :: A handle to the target face object. */ + /* */ + /* <Input> */ + /* stream :: A handle to the input stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_load_prep( TT_Face face, + FT_Stream stream ) + { +#ifdef TT_USE_BYTECODE_INTERPRETER + + FT_Error error; + FT_ULong table_len; + + + FT_TRACE2(( "Prep program " )); + + error = face->goto_table( face, TTAG_prep, stream, &table_len ); + if ( error ) + { + face->cvt_program = NULL; + face->cvt_program_size = 0; + error = TT_Err_Ok; + + FT_TRACE2(( "is missing\n" )); + } + else + { + face->cvt_program_size = table_len; + if ( FT_FRAME_EXTRACT( table_len, face->cvt_program ) ) + goto Exit; + + FT_TRACE2(( "loaded, %12d bytes\n", face->cvt_program_size )); + } + + Exit: + return error; + +#else /* !TT_USE_BYTECODE_INTERPRETER */ + + FT_UNUSED( face ); + FT_UNUSED( stream ); + + return TT_Err_Ok; + +#endif + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_load_hdmx */ + /* */ + /* <Description> */ + /* Load the `hdmx' table into the face object. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: A handle to the input stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + + FT_LOCAL_DEF( FT_Error ) + tt_face_load_hdmx( TT_Face face, + FT_Stream stream ) + { + FT_Error error; + FT_Memory memory = stream->memory; + FT_UInt version, nn, num_records; + FT_ULong table_size, record_size; + FT_Byte* p; + FT_Byte* limit; + + + /* this table is optional */ + error = face->goto_table( face, TTAG_hdmx, stream, &table_size ); + if ( error || table_size < 8 ) + return TT_Err_Ok; + + if ( FT_FRAME_EXTRACT( table_size, face->hdmx_table ) ) + goto Exit; + + p = face->hdmx_table; + limit = p + table_size; + + version = FT_NEXT_USHORT( p ); + num_records = FT_NEXT_USHORT( p ); + record_size = FT_NEXT_ULONG( p ); + + /* The maximum number of bytes in an hdmx device record is the */ + /* maximum number of glyphs + 2; this is 0xFFFF + 2; this is */ + /* the reason why `record_size' is a long (which we read as */ + /* unsigned long for convenience). In practice, two bytes */ + /* sufficient to hold the size value. */ + /* */ + /* There are at least two fonts, HANNOM-A and HANNOM-B version */ + /* 2.0 (2005), which get this wrong: The upper two bytes of */ + /* the size value are set to 0xFF instead of 0x00. We catch */ + /* and fix this. */ + + if ( record_size >= 0xFFFF0000UL ) + record_size &= 0xFFFFU; + + /* The limit for `num_records' is a heuristic value. */ + + if ( version != 0 || num_records > 255 || record_size > 0x10001L ) + { + error = TT_Err_Invalid_File_Format; + goto Fail; + } + + if ( FT_NEW_ARRAY( face->hdmx_record_sizes, num_records ) ) + goto Fail; + + for ( nn = 0; nn < num_records; nn++ ) + { + if ( p + record_size > limit ) + break; + + face->hdmx_record_sizes[nn] = p[0]; + p += record_size; + } + + face->hdmx_record_count = nn; + face->hdmx_table_size = table_size; + face->hdmx_record_size = record_size; + + Exit: + return error; + + Fail: + FT_FRAME_RELEASE( face->hdmx_table ); + face->hdmx_table_size = 0; + goto Exit; + } + + + FT_LOCAL_DEF( void ) + tt_face_free_hdmx( TT_Face face ) + { + FT_Stream stream = face->root.stream; + FT_Memory memory = stream->memory; + + + FT_FREE( face->hdmx_record_sizes ); + FT_FRAME_RELEASE( face->hdmx_table ); + } + + + /*************************************************************************/ + /* */ + /* Return the advance width table for a given pixel size if it is found */ + /* in the font's `hdmx' table (if any). */ + /* */ + FT_LOCAL_DEF( FT_Byte* ) + tt_face_get_device_metrics( TT_Face face, + FT_UInt ppem, + FT_UInt gindex ) + { + FT_UInt nn; + FT_Byte* result = NULL; + FT_ULong record_size = face->hdmx_record_size; + FT_Byte* record = face->hdmx_table + 8; + + + for ( nn = 0; nn < face->hdmx_record_count; nn++ ) + if ( face->hdmx_record_sizes[nn] == ppem ) + { + gindex += 2; + if ( gindex < record_size ) + result = record + nn * record_size + gindex; + break; + } + + return result; + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/truetype/ttpload.h b/mod/pub.mod/freetype.mod/src/truetype/ttpload.h new file mode 100644 index 0000000..f61ac07 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/truetype/ttpload.h @@ -0,0 +1,75 @@ +/***************************************************************************/ +/* */ +/* ttpload.h */ +/* */ +/* TrueType-specific tables loader (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2005, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __TTPLOAD_H__ +#define __TTPLOAD_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_TRUETYPE_TYPES_H + + +FT_BEGIN_HEADER + + + FT_LOCAL( FT_Error ) + tt_face_load_loca( TT_Face face, + FT_Stream stream ); + + FT_LOCAL( FT_ULong ) + tt_face_get_location( TT_Face face, + FT_UInt gindex, + FT_UInt *asize ); + + FT_LOCAL( void ) + tt_face_done_loca( TT_Face face ); + + FT_LOCAL( FT_Error ) + tt_face_load_cvt( TT_Face face, + FT_Stream stream ); + + FT_LOCAL( FT_Error ) + tt_face_load_fpgm( TT_Face face, + FT_Stream stream ); + + + FT_LOCAL( FT_Error ) + tt_face_load_prep( TT_Face face, + FT_Stream stream ); + + + FT_LOCAL( FT_Error ) + tt_face_load_hdmx( TT_Face face, + FT_Stream stream ); + + + FT_LOCAL( void ) + tt_face_free_hdmx( TT_Face face ); + + + FT_LOCAL( FT_Byte* ) + tt_face_get_device_metrics( TT_Face face, + FT_UInt ppem, + FT_UInt gindex ); + +FT_END_HEADER + +#endif /* __TTPLOAD_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/type1/t1afm.c b/mod/pub.mod/freetype.mod/src/type1/t1afm.c new file mode 100644 index 0000000..16dc471 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/type1/t1afm.c @@ -0,0 +1,394 @@ +/***************************************************************************/ +/* */ +/* t1afm.c */ +/* */ +/* AFM support for Type 1 fonts (body). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include "t1afm.h" +#include "t1errors.h" +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_POSTSCRIPT_AUX_H + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_t1afm + + + FT_LOCAL_DEF( void ) + T1_Done_Metrics( FT_Memory memory, + AFM_FontInfo fi ) + { + FT_FREE( fi->KernPairs ); + fi->NumKernPair = 0; + + FT_FREE( fi->TrackKerns ); + fi->NumTrackKern = 0; + + FT_FREE( fi ); + } + + + /* read a glyph name and return the equivalent glyph index */ + static FT_Int + t1_get_index( const char* name, + FT_Offset len, + void* user_data ) + { + T1_Font type1 = (T1_Font)user_data; + FT_Int n; + + + /* PS string/name length must be < 16-bit */ + if ( ( len - 0xFFFFU ) > 0 ) + return 0; + + for ( n = 0; n < type1->num_glyphs; n++ ) + { + char* gname = (char*)type1->glyph_names[n]; + + + if ( gname && gname[0] == name[0] && + ft_strlen( gname ) == len && + ft_strncmp( gname, name, len ) == 0 ) + return n; + } + + return 0; + } + + +#undef KERN_INDEX +#define KERN_INDEX( g1, g2 ) ( ( (FT_ULong)(g1) << 16 ) | (g2) ) + + + /* compare two kerning pairs */ + FT_CALLBACK_DEF( int ) + compare_kern_pairs( const void* a, + const void* b ) + { + AFM_KernPair pair1 = (AFM_KernPair)a; + AFM_KernPair pair2 = (AFM_KernPair)b; + + FT_ULong index1 = KERN_INDEX( pair1->index1, pair1->index2 ); + FT_ULong index2 = KERN_INDEX( pair2->index1, pair2->index2 ); + + + if ( index1 > index2 ) + return 1; + else if ( index1 < index2 ) + return -1; + else + return 0; + } + + + /* parse a PFM file -- for now, only read the kerning pairs */ + static FT_Error + T1_Read_PFM( FT_Face t1_face, + FT_Stream stream, + AFM_FontInfo fi ) + { + FT_Error error = T1_Err_Ok; + FT_Memory memory = stream->memory; + FT_Byte* start; + FT_Byte* limit; + FT_Byte* p; + AFM_KernPair kp; + FT_Int width_table_length; + FT_CharMap oldcharmap; + FT_CharMap charmap; + FT_Int n; + + + start = (FT_Byte*)stream->cursor; + limit = (FT_Byte*)stream->limit; + p = start; + + /* Figure out how long the width table is. */ + /* This info is a little-endian short at offset 99. */ + p = start + 99; + if ( p + 2 > limit ) + { + error = T1_Err_Unknown_File_Format; + goto Exit; + } + width_table_length = FT_PEEK_USHORT_LE( p ); + + p += 18 + width_table_length; + if ( p + 0x12 > limit || FT_PEEK_USHORT_LE( p ) < 0x12 ) + /* extension table is probably optional */ + goto Exit; + + /* Kerning offset is 14 bytes from start of extensions table. */ + p += 14; + p = start + FT_PEEK_ULONG_LE( p ); + + if ( p == start ) + /* zero offset means no table */ + goto Exit; + + if ( p + 2 > limit ) + { + error = T1_Err_Unknown_File_Format; + goto Exit; + } + + fi->NumKernPair = FT_PEEK_USHORT_LE( p ); + p += 2; + if ( p + 4 * fi->NumKernPair > limit ) + { + error = T1_Err_Unknown_File_Format; + goto Exit; + } + + /* Actually, kerning pairs are simply optional! */ + if ( fi->NumKernPair == 0 ) + goto Exit; + + /* allocate the pairs */ + if ( FT_QNEW_ARRAY( fi->KernPairs, fi->NumKernPair ) ) + goto Exit; + + /* now, read each kern pair */ + kp = fi->KernPairs; + limit = p + 4 * fi->NumKernPair; + + /* PFM kerning data are stored by encoding rather than glyph index, */ + /* so find the PostScript charmap of this font and install it */ + /* temporarily. If we find no PostScript charmap, then just use */ + /* the default and hope it is the right one. */ + oldcharmap = t1_face->charmap; + charmap = NULL; + + for ( n = 0; n < t1_face->num_charmaps; n++ ) + { + charmap = t1_face->charmaps[n]; + /* check against PostScript pseudo platform */ + if ( charmap->platform_id == 7 ) + { + error = FT_Set_Charmap( t1_face, charmap ); + if ( error ) + goto Exit; + break; + } + } + + /* Kerning info is stored as: */ + /* */ + /* encoding of first glyph (1 byte) */ + /* encoding of second glyph (1 byte) */ + /* offset (little-endian short) */ + for ( ; p < limit ; p += 4 ) + { + kp->index1 = FT_Get_Char_Index( t1_face, p[0] ); + kp->index2 = FT_Get_Char_Index( t1_face, p[1] ); + + kp->x = (FT_Int)FT_PEEK_SHORT_LE(p + 2); + kp->y = 0; + + kp++; + } + + if ( oldcharmap != NULL ) + error = FT_Set_Charmap( t1_face, oldcharmap ); + if ( error ) + goto Exit; + + /* now, sort the kern pairs according to their glyph indices */ + ft_qsort( fi->KernPairs, fi->NumKernPair, sizeof ( AFM_KernPairRec ), + compare_kern_pairs ); + + Exit: + if ( error ) + { + FT_FREE( fi->KernPairs ); + fi->NumKernPair = 0; + } + + return error; + } + + + /* parse a metrics file -- either AFM or PFM depending on what */ + /* it turns out to be */ + FT_LOCAL_DEF( FT_Error ) + T1_Read_Metrics( FT_Face t1_face, + FT_Stream stream ) + { + PSAux_Service psaux; + FT_Memory memory = stream->memory; + AFM_ParserRec parser; + AFM_FontInfo fi; + FT_Error error = T1_Err_Unknown_File_Format; + T1_Font t1_font = &( (T1_Face)t1_face )->type1; + + + if ( FT_NEW( fi ) || + FT_FRAME_ENTER( stream->size ) ) + goto Exit; + + fi->FontBBox = t1_font->font_bbox; + fi->Ascender = t1_font->font_bbox.yMax; + fi->Descender = t1_font->font_bbox.yMin; + + psaux = (PSAux_Service)( (T1_Face)t1_face )->psaux; + if ( psaux && psaux->afm_parser_funcs ) + { + error = psaux->afm_parser_funcs->init( &parser, + stream->memory, + stream->cursor, + stream->limit ); + + if ( !error ) + { + parser.FontInfo = fi; + parser.get_index = t1_get_index; + parser.user_data = t1_font; + + error = psaux->afm_parser_funcs->parse( &parser ); + psaux->afm_parser_funcs->done( &parser ); + } + } + + if ( error == T1_Err_Unknown_File_Format ) + { + FT_Byte* start = stream->cursor; + + + /* MS Windows allows versions up to 0x3FF without complaining */ + if ( stream->size > 6 && + start[1] < 4 && + FT_PEEK_ULONG_LE( start + 2 ) == stream->size ) + error = T1_Read_PFM( t1_face, stream, fi ); + } + + if ( !error ) + { + t1_font->font_bbox = fi->FontBBox; + + t1_face->bbox.xMin = fi->FontBBox.xMin >> 16; + t1_face->bbox.yMin = fi->FontBBox.yMin >> 16; + t1_face->bbox.xMax = ( fi->FontBBox.xMax + 0xFFFFU ) >> 16; + t1_face->bbox.yMax = ( fi->FontBBox.yMax + 0xFFFFU ) >> 16; + + t1_face->ascender = (FT_Short)( ( fi->Ascender + 0x8000U ) >> 16 ); + t1_face->descender = (FT_Short)( ( fi->Descender + 0x8000U ) >> 16 ); + + if ( fi->NumKernPair ) + { + t1_face->face_flags |= FT_FACE_FLAG_KERNING; + ( (T1_Face)t1_face )->afm_data = fi; + fi = NULL; + } + } + + FT_FRAME_EXIT(); + + Exit: + if ( fi != NULL ) + T1_Done_Metrics( memory, fi ); + + return error; + } + + + /* find the kerning for a given glyph pair */ + FT_LOCAL_DEF( void ) + T1_Get_Kerning( AFM_FontInfo fi, + FT_UInt glyph1, + FT_UInt glyph2, + FT_Vector* kerning ) + { + AFM_KernPair min, mid, max; + FT_ULong idx = KERN_INDEX( glyph1, glyph2 ); + + + /* simple binary search */ + min = fi->KernPairs; + max = min + fi->NumKernPair - 1; + + while ( min <= max ) + { + FT_ULong midi; + + + mid = min + ( max - min ) / 2; + midi = KERN_INDEX( mid->index1, mid->index2 ); + + if ( midi == idx ) + { + kerning->x = mid->x; + kerning->y = mid->y; + + return; + } + + if ( midi < idx ) + min = mid + 1; + else + max = mid - 1; + } + + kerning->x = 0; + kerning->y = 0; + } + + + FT_LOCAL_DEF( FT_Error ) + T1_Get_Track_Kerning( FT_Face face, + FT_Fixed ptsize, + FT_Int degree, + FT_Fixed* kerning ) + { + AFM_FontInfo fi = (AFM_FontInfo)( (T1_Face)face )->afm_data; + FT_Int i; + + + if ( !fi ) + return T1_Err_Invalid_Argument; + + for ( i = 0; i < fi->NumTrackKern; i++ ) + { + AFM_TrackKern tk = fi->TrackKerns + i; + + + if ( tk->degree != degree ) + continue; + + if ( ptsize < tk->min_ptsize ) + *kerning = tk->min_kern; + else if ( ptsize > tk->max_ptsize ) + *kerning = tk->max_kern; + else + { + *kerning = FT_MulDiv( ptsize - tk->min_ptsize, + tk->max_kern - tk->min_kern, + tk->max_ptsize - tk->min_ptsize ) + + tk->min_kern; + } + } + + return T1_Err_Ok; + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/type1/t1afm.h b/mod/pub.mod/freetype.mod/src/type1/t1afm.h new file mode 100644 index 0000000..8eb1764 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/type1/t1afm.h @@ -0,0 +1,54 @@ +/***************************************************************************/ +/* */ +/* t1afm.h */ +/* */ +/* AFM support for Type 1 fonts (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __T1AFM_H__ +#define __T1AFM_H__ + +#include <ft2build.h> +#include "t1objs.h" +#include FT_INTERNAL_TYPE1_TYPES_H + +FT_BEGIN_HEADER + + + FT_LOCAL( FT_Error ) + T1_Read_Metrics( FT_Face face, + FT_Stream stream ); + + FT_LOCAL( void ) + T1_Done_Metrics( FT_Memory memory, + AFM_FontInfo fi ); + + FT_LOCAL( void ) + T1_Get_Kerning( AFM_FontInfo fi, + FT_UInt glyph1, + FT_UInt glyph2, + FT_Vector* kerning ); + + FT_LOCAL( FT_Error ) + T1_Get_Track_Kerning( FT_Face face, + FT_Fixed ptsize, + FT_Int degree, + FT_Fixed* kerning ); + +FT_END_HEADER + +#endif /* __T1AFM_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/type1/t1driver.c b/mod/pub.mod/freetype.mod/src/type1/t1driver.c new file mode 100644 index 0000000..8c398ee --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/type1/t1driver.c @@ -0,0 +1,331 @@ +/***************************************************************************/ +/* */ +/* t1driver.c */ +/* */ +/* Type 1 driver interface (body). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include "t1driver.h" +#include "t1gload.h" +#include "t1load.h" + +#include "t1errors.h" + +#ifndef T1_CONFIG_OPTION_NO_AFM +#include "t1afm.h" +#endif + +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H + +#include FT_SERVICE_MULTIPLE_MASTERS_H +#include FT_SERVICE_GLYPH_DICT_H +#include FT_SERVICE_XFREE86_NAME_H +#include FT_SERVICE_POSTSCRIPT_NAME_H +#include FT_SERVICE_POSTSCRIPT_CMAPS_H +#include FT_SERVICE_POSTSCRIPT_INFO_H +#include FT_SERVICE_KERNING_H + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_t1driver + + /* + * GLYPH DICT SERVICE + * + */ + + static FT_Error + t1_get_glyph_name( T1_Face face, + FT_UInt glyph_index, + FT_Pointer buffer, + FT_UInt buffer_max ) + { + FT_STRCPYN( buffer, face->type1.glyph_names[glyph_index], buffer_max ); + + return T1_Err_Ok; + } + + + static FT_UInt + t1_get_name_index( T1_Face face, + FT_String* glyph_name ) + { + FT_Int i; + FT_String* gname; + + + for ( i = 0; i < face->type1.num_glyphs; i++ ) + { + gname = face->type1.glyph_names[i]; + + if ( !ft_strcmp( glyph_name, gname ) ) + return (FT_UInt)i; + } + + return 0; + } + + + static const FT_Service_GlyphDictRec t1_service_glyph_dict = + { + (FT_GlyphDict_GetNameFunc) t1_get_glyph_name, + (FT_GlyphDict_NameIndexFunc)t1_get_name_index + }; + + + /* + * POSTSCRIPT NAME SERVICE + * + */ + + static const char* + t1_get_ps_name( T1_Face face ) + { + return (const char*) face->type1.font_name; + } + + + static const FT_Service_PsFontNameRec t1_service_ps_name = + { + (FT_PsName_GetFunc)t1_get_ps_name + }; + + + /* + * MULTIPLE MASTERS SERVICE + * + */ + +#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT + static const FT_Service_MultiMastersRec t1_service_multi_masters = + { + (FT_Get_MM_Func) T1_Get_Multi_Master, + (FT_Set_MM_Design_Func) T1_Set_MM_Design, + (FT_Set_MM_Blend_Func) T1_Set_MM_Blend, + (FT_Get_MM_Var_Func) T1_Get_MM_Var, + (FT_Set_Var_Design_Func)T1_Set_Var_Design + }; +#endif + + + /* + * POSTSCRIPT INFO SERVICE + * + */ + + static FT_Error + t1_ps_get_font_info( FT_Face face, + PS_FontInfoRec* afont_info ) + { + *afont_info = ((T1_Face)face)->type1.font_info; + + return T1_Err_Ok; + } + + + static FT_Error + t1_ps_get_font_extra( FT_Face face, + PS_FontExtraRec* afont_extra ) + { + *afont_extra = ((T1_Face)face)->type1.font_extra; + + return T1_Err_Ok; + } + + + static FT_Int + t1_ps_has_glyph_names( FT_Face face ) + { + FT_UNUSED( face ); + + return 1; + } + + + static FT_Error + t1_ps_get_font_private( FT_Face face, + PS_PrivateRec* afont_private ) + { + *afont_private = ((T1_Face)face)->type1.private_dict; + + return T1_Err_Ok; + } + + + static const FT_Service_PsInfoRec t1_service_ps_info = + { + (PS_GetFontInfoFunc) t1_ps_get_font_info, + (PS_GetFontExtraFunc) t1_ps_get_font_extra, + (PS_HasGlyphNamesFunc) t1_ps_has_glyph_names, + (PS_GetFontPrivateFunc)t1_ps_get_font_private, + }; + + +#ifndef T1_CONFIG_OPTION_NO_AFM + static const FT_Service_KerningRec t1_service_kerning = + { + T1_Get_Track_Kerning, + }; +#endif + + + /* + * SERVICE LIST + * + */ + + static const FT_ServiceDescRec t1_services[] = + { + { FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &t1_service_ps_name }, + { FT_SERVICE_ID_GLYPH_DICT, &t1_service_glyph_dict }, + { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_TYPE_1 }, + { FT_SERVICE_ID_POSTSCRIPT_INFO, &t1_service_ps_info }, + +#ifndef T1_CONFIG_OPTION_NO_AFM + { FT_SERVICE_ID_KERNING, &t1_service_kerning }, +#endif + +#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT + { FT_SERVICE_ID_MULTI_MASTERS, &t1_service_multi_masters }, +#endif + { NULL, NULL } + }; + + + static FT_Module_Interface + Get_Interface( FT_Driver driver, + const FT_String* t1_interface ) + { + FT_UNUSED( driver ); + + return ft_service_list_lookup( t1_services, t1_interface ); + } + + +#ifndef T1_CONFIG_OPTION_NO_AFM + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Get_Kerning */ + /* */ + /* <Description> */ + /* A driver method used to return the kerning vector between two */ + /* glyphs of the same face. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face object. */ + /* */ + /* left_glyph :: The index of the left glyph in the kern pair. */ + /* */ + /* right_glyph :: The index of the right glyph in the kern pair. */ + /* */ + /* <Output> */ + /* kerning :: The kerning vector. This is in font units for */ + /* scalable formats, and in pixels for fixed-sizes */ + /* formats. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* Only horizontal layouts (left-to-right & right-to-left) are */ + /* supported by this function. Other layouts, or more sophisticated */ + /* kernings are out of scope of this method (the basic driver */ + /* interface is meant to be simple). */ + /* */ + /* They can be implemented by format-specific interfaces. */ + /* */ + static FT_Error + Get_Kerning( T1_Face face, + FT_UInt left_glyph, + FT_UInt right_glyph, + FT_Vector* kerning ) + { + kerning->x = 0; + kerning->y = 0; + + if ( face->afm_data ) + T1_Get_Kerning( (AFM_FontInfo)face->afm_data, + left_glyph, + right_glyph, + kerning ); + + return T1_Err_Ok; + } + + +#endif /* T1_CONFIG_OPTION_NO_AFM */ + + + FT_CALLBACK_TABLE_DEF + const FT_Driver_ClassRec t1_driver_class = + { + { + FT_MODULE_FONT_DRIVER | + FT_MODULE_DRIVER_SCALABLE | + FT_MODULE_DRIVER_HAS_HINTER, + + sizeof( FT_DriverRec ), + + "type1", + 0x10000L, + 0x20000L, + + 0, /* format interface */ + + (FT_Module_Constructor)T1_Driver_Init, + (FT_Module_Destructor) T1_Driver_Done, + (FT_Module_Requester) Get_Interface, + }, + + sizeof( T1_FaceRec ), + sizeof( T1_SizeRec ), + sizeof( T1_GlyphSlotRec ), + + (FT_Face_InitFunc) T1_Face_Init, + (FT_Face_DoneFunc) T1_Face_Done, + (FT_Size_InitFunc) T1_Size_Init, + (FT_Size_DoneFunc) T1_Size_Done, + (FT_Slot_InitFunc) T1_GlyphSlot_Init, + (FT_Slot_DoneFunc) T1_GlyphSlot_Done, + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + ft_stub_set_char_sizes, + ft_stub_set_pixel_sizes, +#endif + (FT_Slot_LoadFunc) T1_Load_Glyph, + +#ifdef T1_CONFIG_OPTION_NO_AFM + (FT_Face_GetKerningFunc) 0, + (FT_Face_AttachFunc) 0, +#else + (FT_Face_GetKerningFunc) Get_Kerning, + (FT_Face_AttachFunc) T1_Read_Metrics, +#endif + (FT_Face_GetAdvancesFunc) T1_Get_Advances, + (FT_Size_RequestFunc) T1_Size_Request, + (FT_Size_SelectFunc) 0 + }; + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/type1/t1driver.h b/mod/pub.mod/freetype.mod/src/type1/t1driver.h new file mode 100644 index 0000000..9fecbeb --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/type1/t1driver.h @@ -0,0 +1,42 @@ +/***************************************************************************/ +/* */ +/* t1driver.h */ +/* */ +/* High-level Type 1 driver interface (specification). */ +/* */ +/* Copyright 1996-2001, 2002 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __T1DRIVER_H__ +#define __T1DRIVER_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_DRIVER_H + + +FT_BEGIN_HEADER + +#ifdef FT_CONFIG_OPTION_PIC +#error "this module does not support PIC yet" +#endif + + + FT_EXPORT_VAR( const FT_Driver_ClassRec ) t1_driver_class; + + +FT_END_HEADER + +#endif /* __T1DRIVER_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/type1/t1errors.h b/mod/pub.mod/freetype.mod/src/type1/t1errors.h new file mode 100644 index 0000000..81221c3 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/type1/t1errors.h @@ -0,0 +1,40 @@ +/***************************************************************************/ +/* */ +/* t1errors.h */ +/* */ +/* Type 1 error codes (specification only). */ +/* */ +/* Copyright 2001 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file is used to define the Type 1 error enumeration constants. */ + /* */ + /*************************************************************************/ + +#ifndef __T1ERRORS_H__ +#define __T1ERRORS_H__ + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#define FT_ERR_PREFIX T1_Err_ +#define FT_ERR_BASE FT_Mod_Err_Type1 + +#include FT_ERRORS_H + +#endif /* __T1ERRORS_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/type1/t1gload.c b/mod/pub.mod/freetype.mod/src/type1/t1gload.c new file mode 100644 index 0000000..1658615 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/type1/t1gload.c @@ -0,0 +1,497 @@ +/***************************************************************************/ +/* */ +/* t1gload.c */ +/* */ +/* Type 1 Glyph Loader (body). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include "t1gload.h" +#include FT_INTERNAL_CALC_H +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_OUTLINE_H +#include FT_INTERNAL_POSTSCRIPT_AUX_H + +#include "t1errors.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_t1gload + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /********** *********/ + /********** COMPUTE THE MAXIMUM ADVANCE WIDTH *********/ + /********** *********/ + /********** The following code is in charge of computing *********/ + /********** the maximum advance width of the font. It *********/ + /********** quickly processes each glyph charstring to *********/ + /********** extract the value from either a `sbw' or `seac' *********/ + /********** operator. *********/ + /********** *********/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + FT_LOCAL_DEF( FT_Error ) + T1_Parse_Glyph_And_Get_Char_String( T1_Decoder decoder, + FT_UInt glyph_index, + FT_Data* char_string ) + { + T1_Face face = (T1_Face)decoder->builder.face; + T1_Font type1 = &face->type1; + FT_Error error = T1_Err_Ok; + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + FT_Incremental_InterfaceRec *inc = + face->root.internal->incremental_interface; +#endif + + + decoder->font_matrix = type1->font_matrix; + decoder->font_offset = type1->font_offset; + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + + /* For incremental fonts get the character data using the */ + /* callback function. */ + if ( inc ) + error = inc->funcs->get_glyph_data( inc->object, + glyph_index, char_string ); + else + +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ + + /* For ordinary fonts get the character data stored in the face record. */ + { + char_string->pointer = type1->charstrings[glyph_index]; + char_string->length = (FT_Int)type1->charstrings_len[glyph_index]; + } + + if ( !error ) + error = decoder->funcs.parse_charstrings( + decoder, (FT_Byte*)char_string->pointer, + char_string->length ); + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + + /* Incremental fonts can optionally override the metrics. */ + if ( !error && inc && inc->funcs->get_glyph_metrics ) + { + FT_Incremental_MetricsRec metrics; + + + metrics.bearing_x = FIXED_TO_INT( decoder->builder.left_bearing.x ); + metrics.bearing_y = FIXED_TO_INT( decoder->builder.left_bearing.y ); + metrics.advance = FIXED_TO_INT( decoder->builder.advance.x ); + + error = inc->funcs->get_glyph_metrics( inc->object, + glyph_index, FALSE, &metrics ); + + decoder->builder.left_bearing.x = INT_TO_FIXED( metrics.bearing_x ); + decoder->builder.left_bearing.y = INT_TO_FIXED( metrics.bearing_y ); + decoder->builder.advance.x = INT_TO_FIXED( metrics.advance ); + decoder->builder.advance.y = 0; + } + +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ + + return error; + } + + + FT_CALLBACK_DEF( FT_Error ) + T1_Parse_Glyph( T1_Decoder decoder, + FT_UInt glyph_index ) + { + FT_Data glyph_data; + FT_Error error = T1_Parse_Glyph_And_Get_Char_String( + decoder, glyph_index, &glyph_data ); + + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + + if ( !error ) + { + T1_Face face = (T1_Face)decoder->builder.face; + + + if ( face->root.internal->incremental_interface ) + face->root.internal->incremental_interface->funcs->free_glyph_data( + face->root.internal->incremental_interface->object, + &glyph_data ); + } + +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ + + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + T1_Compute_Max_Advance( T1_Face face, + FT_Pos* max_advance ) + { + FT_Error error; + T1_DecoderRec decoder; + FT_Int glyph_index; + T1_Font type1 = &face->type1; + PSAux_Service psaux = (PSAux_Service)face->psaux; + + + FT_ASSERT( ( face->len_buildchar == 0 ) == ( face->buildchar == NULL ) ); + + *max_advance = 0; + + /* initialize load decoder */ + error = psaux->t1_decoder_funcs->init( &decoder, + (FT_Face)face, + 0, /* size */ + 0, /* glyph slot */ + (FT_Byte**)type1->glyph_names, + face->blend, + 0, + FT_RENDER_MODE_NORMAL, + T1_Parse_Glyph ); + if ( error ) + return error; + + decoder.builder.metrics_only = 1; + decoder.builder.load_points = 0; + + decoder.num_subrs = type1->num_subrs; + decoder.subrs = type1->subrs; + decoder.subrs_len = type1->subrs_len; + + decoder.buildchar = face->buildchar; + decoder.len_buildchar = face->len_buildchar; + + *max_advance = 0; + + /* for each glyph, parse the glyph charstring and extract */ + /* the advance width */ + for ( glyph_index = 0; glyph_index < type1->num_glyphs; glyph_index++ ) + { + /* now get load the unscaled outline */ + error = T1_Parse_Glyph( &decoder, glyph_index ); + if ( glyph_index == 0 || decoder.builder.advance.x > *max_advance ) + *max_advance = decoder.builder.advance.x; + + /* ignore the error if one occurred - skip to next glyph */ + } + + psaux->t1_decoder_funcs->done( &decoder ); + + return T1_Err_Ok; + } + + + FT_LOCAL_DEF( FT_Error ) + T1_Get_Advances( T1_Face face, + FT_UInt first, + FT_UInt count, + FT_ULong load_flags, + FT_Fixed* advances ) + { + T1_DecoderRec decoder; + T1_Font type1 = &face->type1; + PSAux_Service psaux = (PSAux_Service)face->psaux; + FT_UInt nn; + FT_Error error; + + + if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) + { + for ( nn = 0; nn < count; nn++ ) + advances[nn] = 0; + + return T1_Err_Ok; + } + + error = psaux->t1_decoder_funcs->init( &decoder, + (FT_Face)face, + 0, /* size */ + 0, /* glyph slot */ + (FT_Byte**)type1->glyph_names, + face->blend, + 0, + FT_RENDER_MODE_NORMAL, + T1_Parse_Glyph ); + if ( error ) + return error; + + decoder.builder.metrics_only = 1; + decoder.builder.load_points = 0; + + decoder.num_subrs = type1->num_subrs; + decoder.subrs = type1->subrs; + decoder.subrs_len = type1->subrs_len; + + decoder.buildchar = face->buildchar; + decoder.len_buildchar = face->len_buildchar; + + for ( nn = 0; nn < count; nn++ ) + { + error = T1_Parse_Glyph( &decoder, first + nn ); + if ( !error ) + advances[nn] = FIXED_TO_INT( decoder.builder.advance.x ); + else + advances[nn] = 0; + } + + return T1_Err_Ok; + } + + + FT_LOCAL_DEF( FT_Error ) + T1_Load_Glyph( T1_GlyphSlot glyph, + T1_Size size, + FT_UInt glyph_index, + FT_Int32 load_flags ) + { + FT_Error error; + T1_DecoderRec decoder; + T1_Face face = (T1_Face)glyph->root.face; + FT_Bool hinting; + T1_Font type1 = &face->type1; + PSAux_Service psaux = (PSAux_Service)face->psaux; + const T1_Decoder_Funcs decoder_funcs = psaux->t1_decoder_funcs; + + FT_Matrix font_matrix; + FT_Vector font_offset; + FT_Data glyph_data; + FT_Bool must_finish_decoder = FALSE; +#ifdef FT_CONFIG_OPTION_INCREMENTAL + FT_Bool glyph_data_loaded = 0; +#endif + + + if ( glyph_index >= (FT_UInt)face->root.num_glyphs ) + { + error = T1_Err_Invalid_Argument; + goto Exit; + } + + FT_ASSERT( ( face->len_buildchar == 0 ) == ( face->buildchar == NULL ) ); + + if ( load_flags & FT_LOAD_NO_RECURSE ) + load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; + + if ( size ) + { + glyph->x_scale = size->root.metrics.x_scale; + glyph->y_scale = size->root.metrics.y_scale; + } + else + { + glyph->x_scale = 0x10000L; + glyph->y_scale = 0x10000L; + } + + glyph->root.outline.n_points = 0; + glyph->root.outline.n_contours = 0; + + hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 && + ( load_flags & FT_LOAD_NO_HINTING ) == 0 ); + + glyph->root.format = FT_GLYPH_FORMAT_OUTLINE; + + error = decoder_funcs->init( &decoder, + (FT_Face)face, + (FT_Size)size, + (FT_GlyphSlot)glyph, + (FT_Byte**)type1->glyph_names, + face->blend, + FT_BOOL( hinting ), + FT_LOAD_TARGET_MODE( load_flags ), + T1_Parse_Glyph ); + if ( error ) + goto Exit; + + must_finish_decoder = TRUE; + + decoder.builder.no_recurse = FT_BOOL( + ( load_flags & FT_LOAD_NO_RECURSE ) != 0 ); + + decoder.num_subrs = type1->num_subrs; + decoder.subrs = type1->subrs; + decoder.subrs_len = type1->subrs_len; + + decoder.buildchar = face->buildchar; + decoder.len_buildchar = face->len_buildchar; + + /* now load the unscaled outline */ + error = T1_Parse_Glyph_And_Get_Char_String( &decoder, glyph_index, + &glyph_data ); + if ( error ) + goto Exit; +#ifdef FT_CONFIG_OPTION_INCREMENTAL + glyph_data_loaded = 1; +#endif + + font_matrix = decoder.font_matrix; + font_offset = decoder.font_offset; + + /* save new glyph tables */ + decoder_funcs->done( &decoder ); + + must_finish_decoder = FALSE; + + /* now, set the metrics -- this is rather simple, as */ + /* the left side bearing is the xMin, and the top side */ + /* bearing the yMax */ + if ( !error ) + { + glyph->root.outline.flags &= FT_OUTLINE_OWNER; + glyph->root.outline.flags |= FT_OUTLINE_REVERSE_FILL; + + /* for composite glyphs, return only left side bearing and */ + /* advance width */ + if ( load_flags & FT_LOAD_NO_RECURSE ) + { + FT_Slot_Internal internal = glyph->root.internal; + + + glyph->root.metrics.horiBearingX = + FIXED_TO_INT( decoder.builder.left_bearing.x ); + glyph->root.metrics.horiAdvance = + FIXED_TO_INT( decoder.builder.advance.x ); + + internal->glyph_matrix = font_matrix; + internal->glyph_delta = font_offset; + internal->glyph_transformed = 1; + } + else + { + FT_BBox cbox; + FT_Glyph_Metrics* metrics = &glyph->root.metrics; + FT_Vector advance; + + + /* copy the _unscaled_ advance width */ + metrics->horiAdvance = + FIXED_TO_INT( decoder.builder.advance.x ); + glyph->root.linearHoriAdvance = + FIXED_TO_INT( decoder.builder.advance.x ); + glyph->root.internal->glyph_transformed = 0; + + /* make up vertical ones */ + metrics->vertAdvance = ( face->type1.font_bbox.yMax - + face->type1.font_bbox.yMin ) >> 16; + glyph->root.linearVertAdvance = metrics->vertAdvance; + + glyph->root.format = FT_GLYPH_FORMAT_OUTLINE; + + if ( size && size->root.metrics.y_ppem < 24 ) + glyph->root.outline.flags |= FT_OUTLINE_HIGH_PRECISION; + +#if 1 + /* apply the font matrix, if any */ + if ( font_matrix.xx != 0x10000L || font_matrix.yy != font_matrix.xx || + font_matrix.xy != 0 || font_matrix.yx != 0 ) + FT_Outline_Transform( &glyph->root.outline, &font_matrix ); + + if ( font_offset.x || font_offset.y ) + FT_Outline_Translate( &glyph->root.outline, + font_offset.x, + font_offset.y ); + + advance.x = metrics->horiAdvance; + advance.y = 0; + FT_Vector_Transform( &advance, &font_matrix ); + metrics->horiAdvance = advance.x + font_offset.x; + advance.x = 0; + advance.y = metrics->vertAdvance; + FT_Vector_Transform( &advance, &font_matrix ); + metrics->vertAdvance = advance.y + font_offset.y; +#endif + + if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 ) + { + /* scale the outline and the metrics */ + FT_Int n; + FT_Outline* cur = decoder.builder.base; + FT_Vector* vec = cur->points; + FT_Fixed x_scale = glyph->x_scale; + FT_Fixed y_scale = glyph->y_scale; + + + /* First of all, scale the points, if we are not hinting */ + if ( !hinting || ! decoder.builder.hints_funcs ) + for ( n = cur->n_points; n > 0; n--, vec++ ) + { + vec->x = FT_MulFix( vec->x, x_scale ); + vec->y = FT_MulFix( vec->y, y_scale ); + } + + /* Then scale the metrics */ + metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale ); + metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale ); + } + + /* compute the other metrics */ + FT_Outline_Get_CBox( &glyph->root.outline, &cbox ); + + metrics->width = cbox.xMax - cbox.xMin; + metrics->height = cbox.yMax - cbox.yMin; + + metrics->horiBearingX = cbox.xMin; + metrics->horiBearingY = cbox.yMax; + + /* make up vertical ones */ + ft_synthesize_vertical_metrics( metrics, + metrics->vertAdvance ); + } + + /* Set control data to the glyph charstrings. Note that this is */ + /* _not_ zero-terminated. */ + glyph->root.control_data = (FT_Byte*)glyph_data.pointer; + glyph->root.control_len = glyph_data.length; + } + + + Exit: + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + if ( glyph_data_loaded && face->root.internal->incremental_interface ) + { + face->root.internal->incremental_interface->funcs->free_glyph_data( + face->root.internal->incremental_interface->object, + &glyph_data ); + + /* Set the control data to null - it is no longer available if */ + /* loaded incrementally. */ + glyph->root.control_data = 0; + glyph->root.control_len = 0; + } +#endif + + if ( must_finish_decoder ) + decoder_funcs->done( &decoder ); + + return error; + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/type1/t1gload.h b/mod/pub.mod/freetype.mod/src/type1/t1gload.h new file mode 100644 index 0000000..100df06 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/type1/t1gload.h @@ -0,0 +1,53 @@ +/***************************************************************************/ +/* */ +/* t1gload.h */ +/* */ +/* Type 1 Glyph Loader (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __T1GLOAD_H__ +#define __T1GLOAD_H__ + + +#include <ft2build.h> +#include "t1objs.h" + + +FT_BEGIN_HEADER + + + FT_LOCAL( FT_Error ) + T1_Compute_Max_Advance( T1_Face face, + FT_Pos* max_advance ); + + FT_LOCAL( FT_Error ) + T1_Get_Advances( T1_Face face, + FT_UInt first, + FT_UInt count, + FT_ULong load_flags, + FT_Fixed* advances ); + + FT_LOCAL( FT_Error ) + T1_Load_Glyph( T1_GlyphSlot glyph, + T1_Size size, + FT_UInt glyph_index, + FT_Int32 load_flags ); + + +FT_END_HEADER + +#endif /* __T1GLOAD_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/type1/t1load.c b/mod/pub.mod/freetype.mod/src/type1/t1load.c new file mode 100644 index 0000000..d867e94 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/type1/t1load.c @@ -0,0 +1,2231 @@ +/***************************************************************************/ +/* */ +/* t1load.c */ +/* */ +/* Type 1 font loader (body). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This is the new and improved Type 1 data loader for FreeType 2. The */ + /* old loader has several problems: it is slow, complex, difficult to */ + /* maintain, and contains incredible hacks to make it accept some */ + /* ill-formed Type 1 fonts without hiccup-ing. Moreover, about 5% of */ + /* the Type 1 fonts on my machine still aren't loaded correctly by it. */ + /* */ + /* This version is much simpler, much faster and also easier to read and */ + /* maintain by a great order of magnitude. The idea behind it is to */ + /* _not_ try to read the Type 1 token stream with a state machine (i.e. */ + /* a Postscript-like interpreter) but rather to perform simple pattern */ + /* matching. */ + /* */ + /* Indeed, nearly all data definitions follow a simple pattern like */ + /* */ + /* ... /Field <data> ... */ + /* */ + /* where <data> can be a number, a boolean, a string, or an array of */ + /* numbers. There are a few exceptions, namely the encoding, font name, */ + /* charstrings, and subrs; they are handled with a special pattern */ + /* matching routine. */ + /* */ + /* All other common cases are handled very simply. The matching rules */ + /* are defined in the file `t1tokens.h' through the use of several */ + /* macros calls PARSE_XXX. This file is included twice here; the first */ + /* time to generate parsing callback functions, the second time to */ + /* generate a table of keywords (with pointers to the associated */ + /* callback functions). */ + /* */ + /* The function `parse_dict' simply scans *linearly* a given dictionary */ + /* (either the top-level or private one) and calls the appropriate */ + /* callback when it encounters an immediate keyword. */ + /* */ + /* This is by far the fastest way one can find to parse and read all */ + /* data. */ + /* */ + /* This led to tremendous code size reduction. Note that later, the */ + /* glyph loader will also be _greatly_ simplified, and the automatic */ + /* hinter will replace the clumsy `t1hinter'. */ + /* */ + /*************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_CONFIG_CONFIG_H +#include FT_MULTIPLE_MASTERS_H +#include FT_INTERNAL_TYPE1_TYPES_H +#include FT_INTERNAL_CALC_H + +#include "t1load.h" +#include "t1errors.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_t1load + + +#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** MULTIPLE MASTERS SUPPORT *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static FT_Error + t1_allocate_blend( T1_Face face, + FT_UInt num_designs, + FT_UInt num_axis ) + { + PS_Blend blend; + FT_Memory memory = face->root.memory; + FT_Error error = T1_Err_Ok; + + + blend = face->blend; + if ( !blend ) + { + if ( FT_NEW( blend ) ) + goto Exit; + + blend->num_default_design_vector = 0; + + face->blend = blend; + } + + /* allocate design data if needed */ + if ( num_designs > 0 ) + { + if ( blend->num_designs == 0 ) + { + FT_UInt nn; + + + /* allocate the blend `private' and `font_info' dictionaries */ + if ( FT_NEW_ARRAY( blend->font_infos[1], num_designs ) || + FT_NEW_ARRAY( blend->privates[1], num_designs ) || + FT_NEW_ARRAY( blend->bboxes[1], num_designs ) || + FT_NEW_ARRAY( blend->weight_vector, num_designs * 2 ) ) + goto Exit; + + blend->default_weight_vector = blend->weight_vector + num_designs; + + blend->font_infos[0] = &face->type1.font_info; + blend->privates [0] = &face->type1.private_dict; + blend->bboxes [0] = &face->type1.font_bbox; + + for ( nn = 2; nn <= num_designs; nn++ ) + { + blend->privates[nn] = blend->privates [nn - 1] + 1; + blend->font_infos[nn] = blend->font_infos[nn - 1] + 1; + blend->bboxes[nn] = blend->bboxes [nn - 1] + 1; + } + + blend->num_designs = num_designs; + } + else if ( blend->num_designs != num_designs ) + goto Fail; + } + + /* allocate axis data if needed */ + if ( num_axis > 0 ) + { + if ( blend->num_axis != 0 && blend->num_axis != num_axis ) + goto Fail; + + blend->num_axis = num_axis; + } + + /* allocate the blend design pos table if needed */ + num_designs = blend->num_designs; + num_axis = blend->num_axis; + if ( num_designs && num_axis && blend->design_pos[0] == 0 ) + { + FT_UInt n; + + + if ( FT_NEW_ARRAY( blend->design_pos[0], num_designs * num_axis ) ) + goto Exit; + + for ( n = 1; n < num_designs; n++ ) + blend->design_pos[n] = blend->design_pos[0] + num_axis * n; + } + + Exit: + return error; + + Fail: + error = T1_Err_Invalid_File_Format; + goto Exit; + } + + + FT_LOCAL_DEF( FT_Error ) + T1_Get_Multi_Master( T1_Face face, + FT_Multi_Master* master ) + { + PS_Blend blend = face->blend; + FT_UInt n; + FT_Error error; + + + error = T1_Err_Invalid_Argument; + + if ( blend ) + { + master->num_axis = blend->num_axis; + master->num_designs = blend->num_designs; + + for ( n = 0; n < blend->num_axis; n++ ) + { + FT_MM_Axis* axis = master->axis + n; + PS_DesignMap map = blend->design_map + n; + + + axis->name = blend->axis_names[n]; + axis->minimum = map->design_points[0]; + axis->maximum = map->design_points[map->num_points - 1]; + } + + error = T1_Err_Ok; + } + + return error; + } + + + /*************************************************************************/ + /* */ + /* Given a normalized (blend) coordinate, figure out the design */ + /* coordinate appropriate for that value. */ + /* */ + FT_LOCAL_DEF( FT_Fixed ) + mm_axis_unmap( PS_DesignMap axismap, + FT_Fixed ncv ) + { + int j; + + + if ( ncv <= axismap->blend_points[0] ) + return INT_TO_FIXED( axismap->design_points[0] ); + + for ( j = 1; j < axismap->num_points; ++j ) + { + if ( ncv <= axismap->blend_points[j] ) + { + FT_Fixed t = FT_MulDiv( ncv - axismap->blend_points[j - 1], + 0x10000L, + axismap->blend_points[j] - + axismap->blend_points[j - 1] ); + + return INT_TO_FIXED( axismap->design_points[j - 1] ) + + FT_MulDiv( t, + axismap->design_points[j] - + axismap->design_points[j - 1], + 1L ); + } + } + + return INT_TO_FIXED( axismap->design_points[axismap->num_points - 1] ); + } + + + /*************************************************************************/ + /* */ + /* Given a vector of weights, one for each design, figure out the */ + /* normalized axis coordinates which gave rise to those weights. */ + /* */ + FT_LOCAL_DEF( void ) + mm_weights_unmap( FT_Fixed* weights, + FT_Fixed* axiscoords, + FT_UInt axis_count ) + { + FT_ASSERT( axis_count <= T1_MAX_MM_AXIS ); + + if ( axis_count == 1 ) + axiscoords[0] = weights[1]; + + else if ( axis_count == 2 ) + { + axiscoords[0] = weights[3] + weights[1]; + axiscoords[1] = weights[3] + weights[2]; + } + + else if ( axis_count == 3 ) + { + axiscoords[0] = weights[7] + weights[5] + weights[3] + weights[1]; + axiscoords[1] = weights[7] + weights[6] + weights[3] + weights[2]; + axiscoords[2] = weights[7] + weights[6] + weights[5] + weights[4]; + } + + else + { + axiscoords[0] = weights[15] + weights[13] + weights[11] + weights[9] + + weights[7] + weights[5] + weights[3] + weights[1]; + axiscoords[1] = weights[15] + weights[14] + weights[11] + weights[10] + + weights[7] + weights[6] + weights[3] + weights[2]; + axiscoords[2] = weights[15] + weights[14] + weights[13] + weights[12] + + weights[7] + weights[6] + weights[5] + weights[4]; + axiscoords[3] = weights[15] + weights[14] + weights[13] + weights[12] + + weights[11] + weights[10] + weights[9] + weights[8]; + } + } + + + /*************************************************************************/ + /* */ + /* Just a wrapper around T1_Get_Multi_Master to support the different */ + /* arguments needed by the GX var distortable fonts. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + T1_Get_MM_Var( T1_Face face, + FT_MM_Var* *master ) + { + FT_Memory memory = face->root.memory; + FT_MM_Var *mmvar; + FT_Multi_Master mmaster; + FT_Error error; + FT_UInt i; + FT_Fixed axiscoords[T1_MAX_MM_AXIS]; + PS_Blend blend = face->blend; + + + error = T1_Get_Multi_Master( face, &mmaster ); + if ( error ) + goto Exit; + if ( FT_ALLOC( mmvar, + sizeof ( FT_MM_Var ) + + mmaster.num_axis * sizeof ( FT_Var_Axis ) ) ) + goto Exit; + + mmvar->num_axis = mmaster.num_axis; + mmvar->num_designs = mmaster.num_designs; + mmvar->num_namedstyles = (FT_UInt)-1; /* Does not apply */ + mmvar->axis = (FT_Var_Axis*)&mmvar[1]; + /* Point to axes after MM_Var struct */ + mmvar->namedstyle = NULL; + + for ( i = 0 ; i < mmaster.num_axis; ++i ) + { + mmvar->axis[i].name = mmaster.axis[i].name; + mmvar->axis[i].minimum = INT_TO_FIXED( mmaster.axis[i].minimum); + mmvar->axis[i].maximum = INT_TO_FIXED( mmaster.axis[i].maximum); + mmvar->axis[i].def = ( mmvar->axis[i].minimum + + mmvar->axis[i].maximum ) / 2; + /* Does not apply. But this value is in range */ + mmvar->axis[i].strid = (FT_UInt)-1; /* Does not apply */ + mmvar->axis[i].tag = (FT_ULong)-1; /* Does not apply */ + + if ( ft_strcmp( mmvar->axis[i].name, "Weight" ) == 0 ) + mmvar->axis[i].tag = FT_MAKE_TAG( 'w', 'g', 'h', 't' ); + else if ( ft_strcmp( mmvar->axis[i].name, "Width" ) == 0 ) + mmvar->axis[i].tag = FT_MAKE_TAG( 'w', 'd', 't', 'h' ); + else if ( ft_strcmp( mmvar->axis[i].name, "OpticalSize" ) == 0 ) + mmvar->axis[i].tag = FT_MAKE_TAG( 'o', 'p', 's', 'z' ); + } + + if ( blend->num_designs == ( 1U << blend->num_axis ) ) + { + mm_weights_unmap( blend->default_weight_vector, + axiscoords, + blend->num_axis ); + + for ( i = 0; i < mmaster.num_axis; ++i ) + mmvar->axis[i].def = mm_axis_unmap( &blend->design_map[i], + axiscoords[i] ); + } + + *master = mmvar; + + Exit: + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + T1_Set_MM_Blend( T1_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) + { + PS_Blend blend = face->blend; + FT_Error error; + FT_UInt n, m; + + + error = T1_Err_Invalid_Argument; + + if ( blend && blend->num_axis == num_coords ) + { + /* recompute the weight vector from the blend coordinates */ + error = T1_Err_Ok; + + for ( n = 0; n < blend->num_designs; n++ ) + { + FT_Fixed result = 0x10000L; /* 1.0 fixed */ + + + for ( m = 0; m < blend->num_axis; m++ ) + { + FT_Fixed factor; + + + /* get current blend axis position */ + factor = coords[m]; + if ( factor < 0 ) factor = 0; + if ( factor > 0x10000L ) factor = 0x10000L; + + if ( ( n & ( 1 << m ) ) == 0 ) + factor = 0x10000L - factor; + + result = FT_MulFix( result, factor ); + } + blend->weight_vector[n] = result; + } + + error = T1_Err_Ok; + } + + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + T1_Set_MM_Design( T1_Face face, + FT_UInt num_coords, + FT_Long* coords ) + { + PS_Blend blend = face->blend; + FT_Error error; + FT_UInt n, p; + + + error = T1_Err_Invalid_Argument; + if ( blend && blend->num_axis == num_coords ) + { + /* compute the blend coordinates through the blend design map */ + FT_Fixed final_blends[T1_MAX_MM_DESIGNS]; + + + for ( n = 0; n < blend->num_axis; n++ ) + { + FT_Long design = coords[n]; + FT_Fixed the_blend; + PS_DesignMap map = blend->design_map + n; + FT_Long* designs = map->design_points; + FT_Fixed* blends = map->blend_points; + FT_Int before = -1, after = -1; + + + for ( p = 0; p < (FT_UInt)map->num_points; p++ ) + { + FT_Long p_design = designs[p]; + + + /* exact match? */ + if ( design == p_design ) + { + the_blend = blends[p]; + goto Found; + } + + if ( design < p_design ) + { + after = p; + break; + } + + before = p; + } + + /* now interpolate if necessary */ + if ( before < 0 ) + the_blend = blends[0]; + + else if ( after < 0 ) + the_blend = blends[map->num_points - 1]; + + else + the_blend = FT_MulDiv( design - designs[before], + blends [after] - blends [before], + designs[after] - designs[before] ); + + Found: + final_blends[n] = the_blend; + } + + error = T1_Set_MM_Blend( face, num_coords, final_blends ); + } + + return error; + } + + + /*************************************************************************/ + /* */ + /* Just a wrapper around T1_Set_MM_Design to support the different */ + /* arguments needed by the GX var distortable fonts. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + T1_Set_Var_Design( T1_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) + { + FT_Long lcoords[4]; /* maximum axis count is 4 */ + FT_UInt i; + FT_Error error; + + + error = T1_Err_Invalid_Argument; + if ( num_coords <= 4 && num_coords > 0 ) + { + for ( i = 0; i < num_coords; ++i ) + lcoords[i] = FIXED_TO_INT( coords[i] ); + error = T1_Set_MM_Design( face, num_coords, lcoords ); + } + + return error; + } + + + FT_LOCAL_DEF( void ) + T1_Done_Blend( T1_Face face ) + { + FT_Memory memory = face->root.memory; + PS_Blend blend = face->blend; + + + if ( blend ) + { + FT_UInt num_designs = blend->num_designs; + FT_UInt num_axis = blend->num_axis; + FT_UInt n; + + + /* release design pos table */ + FT_FREE( blend->design_pos[0] ); + for ( n = 1; n < num_designs; n++ ) + blend->design_pos[n] = 0; + + /* release blend `private' and `font info' dictionaries */ + FT_FREE( blend->privates[1] ); + FT_FREE( blend->font_infos[1] ); + FT_FREE( blend->bboxes[1] ); + + for ( n = 0; n < num_designs; n++ ) + { + blend->privates [n] = 0; + blend->font_infos[n] = 0; + blend->bboxes [n] = 0; + } + + /* release weight vectors */ + FT_FREE( blend->weight_vector ); + blend->default_weight_vector = 0; + + /* release axis names */ + for ( n = 0; n < num_axis; n++ ) + FT_FREE( blend->axis_names[n] ); + + /* release design map */ + for ( n = 0; n < num_axis; n++ ) + { + PS_DesignMap dmap = blend->design_map + n; + + + FT_FREE( dmap->design_points ); + dmap->num_points = 0; + } + + FT_FREE( face->blend ); + } + } + + + static void + parse_blend_axis_types( T1_Face face, + T1_Loader loader ) + { + T1_TokenRec axis_tokens[T1_MAX_MM_AXIS]; + FT_Int n, num_axis; + FT_Error error = T1_Err_Ok; + PS_Blend blend; + FT_Memory memory; + + + /* take an array of objects */ + T1_ToTokenArray( &loader->parser, axis_tokens, + T1_MAX_MM_AXIS, &num_axis ); + if ( num_axis < 0 ) + { + error = T1_Err_Ignore; + goto Exit; + } + if ( num_axis == 0 || num_axis > T1_MAX_MM_AXIS ) + { + FT_ERROR(( "parse_blend_axis_types: incorrect number of axes: %d\n", + num_axis )); + error = T1_Err_Invalid_File_Format; + goto Exit; + } + + /* allocate blend if necessary */ + error = t1_allocate_blend( face, 0, (FT_UInt)num_axis ); + if ( error ) + goto Exit; + + blend = face->blend; + memory = face->root.memory; + + /* each token is an immediate containing the name of the axis */ + for ( n = 0; n < num_axis; n++ ) + { + T1_Token token = axis_tokens + n; + FT_Byte* name; + FT_PtrDist len; + + + /* skip first slash, if any */ + if ( token->start[0] == '/' ) + token->start++; + + len = token->limit - token->start; + if ( len == 0 ) + { + error = T1_Err_Invalid_File_Format; + goto Exit; + } + + if ( FT_ALLOC( blend->axis_names[n], len + 1 ) ) + goto Exit; + + name = (FT_Byte*)blend->axis_names[n]; + FT_MEM_COPY( name, token->start, len ); + name[len] = 0; + } + + Exit: + loader->parser.root.error = error; + } + + + static void + parse_blend_design_positions( T1_Face face, + T1_Loader loader ) + { + T1_TokenRec design_tokens[T1_MAX_MM_DESIGNS]; + FT_Int num_designs; + FT_Int num_axis; + T1_Parser parser = &loader->parser; + + FT_Error error = T1_Err_Ok; + PS_Blend blend; + + + /* get the array of design tokens -- compute number of designs */ + T1_ToTokenArray( parser, design_tokens, + T1_MAX_MM_DESIGNS, &num_designs ); + if ( num_designs < 0 ) + { + error = T1_Err_Ignore; + goto Exit; + } + if ( num_designs == 0 || num_designs > T1_MAX_MM_DESIGNS ) + { + FT_ERROR(( "parse_blend_design_positions:" + " incorrect number of designs: %d\n", + num_designs )); + error = T1_Err_Invalid_File_Format; + goto Exit; + } + + { + FT_Byte* old_cursor = parser->root.cursor; + FT_Byte* old_limit = parser->root.limit; + FT_Int n; + + + blend = face->blend; + num_axis = 0; /* make compiler happy */ + + for ( n = 0; n < num_designs; n++ ) + { + T1_TokenRec axis_tokens[T1_MAX_MM_AXIS]; + T1_Token token; + FT_Int axis, n_axis; + + + /* read axis/coordinates tokens */ + token = design_tokens + n; + parser->root.cursor = token->start; + parser->root.limit = token->limit; + T1_ToTokenArray( parser, axis_tokens, T1_MAX_MM_AXIS, &n_axis ); + + if ( n == 0 ) + { + if ( n_axis <= 0 || n_axis > T1_MAX_MM_AXIS ) + { + FT_ERROR(( "parse_blend_design_positions:" + " invalid number of axes: %d\n", + n_axis )); + error = T1_Err_Invalid_File_Format; + goto Exit; + } + + num_axis = n_axis; + error = t1_allocate_blend( face, num_designs, num_axis ); + if ( error ) + goto Exit; + blend = face->blend; + } + else if ( n_axis != num_axis ) + { + FT_ERROR(( "parse_blend_design_positions: incorrect table\n" )); + error = T1_Err_Invalid_File_Format; + goto Exit; + } + + /* now read each axis token into the design position */ + for ( axis = 0; axis < n_axis; axis++ ) + { + T1_Token token2 = axis_tokens + axis; + + + parser->root.cursor = token2->start; + parser->root.limit = token2->limit; + blend->design_pos[n][axis] = T1_ToFixed( parser, 0 ); + } + } + + loader->parser.root.cursor = old_cursor; + loader->parser.root.limit = old_limit; + } + + Exit: + loader->parser.root.error = error; + } + + + static void + parse_blend_design_map( T1_Face face, + T1_Loader loader ) + { + FT_Error error = T1_Err_Ok; + T1_Parser parser = &loader->parser; + PS_Blend blend; + T1_TokenRec axis_tokens[T1_MAX_MM_AXIS]; + FT_Int n, num_axis; + FT_Byte* old_cursor; + FT_Byte* old_limit; + FT_Memory memory = face->root.memory; + + + T1_ToTokenArray( parser, axis_tokens, + T1_MAX_MM_AXIS, &num_axis ); + if ( num_axis < 0 ) + { + error = T1_Err_Ignore; + goto Exit; + } + if ( num_axis == 0 || num_axis > T1_MAX_MM_AXIS ) + { + FT_ERROR(( "parse_blend_design_map: incorrect number of axes: %d\n", + num_axis )); + error = T1_Err_Invalid_File_Format; + goto Exit; + } + + old_cursor = parser->root.cursor; + old_limit = parser->root.limit; + + error = t1_allocate_blend( face, 0, num_axis ); + if ( error ) + goto Exit; + blend = face->blend; + + /* now read each axis design map */ + for ( n = 0; n < num_axis; n++ ) + { + PS_DesignMap map = blend->design_map + n; + T1_Token axis_token; + T1_TokenRec point_tokens[T1_MAX_MM_MAP_POINTS]; + FT_Int p, num_points; + + + axis_token = axis_tokens + n; + + parser->root.cursor = axis_token->start; + parser->root.limit = axis_token->limit; + T1_ToTokenArray( parser, point_tokens, + T1_MAX_MM_MAP_POINTS, &num_points ); + + if ( num_points <= 0 || num_points > T1_MAX_MM_MAP_POINTS ) + { + FT_ERROR(( "parse_blend_design_map: incorrect table\n" )); + error = T1_Err_Invalid_File_Format; + goto Exit; + } + + /* allocate design map data */ + if ( FT_NEW_ARRAY( map->design_points, num_points * 2 ) ) + goto Exit; + map->blend_points = map->design_points + num_points; + map->num_points = (FT_Byte)num_points; + + for ( p = 0; p < num_points; p++ ) + { + T1_Token point_token; + + + point_token = point_tokens + p; + + /* don't include delimiting brackets */ + parser->root.cursor = point_token->start + 1; + parser->root.limit = point_token->limit - 1; + + map->design_points[p] = T1_ToInt( parser ); + map->blend_points [p] = T1_ToFixed( parser, 0 ); + } + } + + parser->root.cursor = old_cursor; + parser->root.limit = old_limit; + + Exit: + parser->root.error = error; + } + + + static void + parse_weight_vector( T1_Face face, + T1_Loader loader ) + { + T1_TokenRec design_tokens[T1_MAX_MM_DESIGNS]; + FT_Int num_designs; + FT_Error error = T1_Err_Ok; + T1_Parser parser = &loader->parser; + PS_Blend blend = face->blend; + T1_Token token; + FT_Int n; + FT_Byte* old_cursor; + FT_Byte* old_limit; + + + T1_ToTokenArray( parser, design_tokens, + T1_MAX_MM_DESIGNS, &num_designs ); + if ( num_designs < 0 ) + { + error = T1_Err_Ignore; + goto Exit; + } + if ( num_designs == 0 || num_designs > T1_MAX_MM_DESIGNS ) + { + FT_ERROR(( "parse_weight_vector:" + " incorrect number of designs: %d\n", + num_designs )); + error = T1_Err_Invalid_File_Format; + goto Exit; + } + + if ( !blend || !blend->num_designs ) + { + error = t1_allocate_blend( face, num_designs, 0 ); + if ( error ) + goto Exit; + blend = face->blend; + } + else if ( blend->num_designs != (FT_UInt)num_designs ) + { + FT_ERROR(( "parse_weight_vector:" + " /BlendDesignPosition and /WeightVector have\n" + " " + " different number of elements\n" )); + error = T1_Err_Invalid_File_Format; + goto Exit; + } + + old_cursor = parser->root.cursor; + old_limit = parser->root.limit; + + for ( n = 0; n < num_designs; n++ ) + { + token = design_tokens + n; + parser->root.cursor = token->start; + parser->root.limit = token->limit; + + blend->default_weight_vector[n] = + blend->weight_vector[n] = T1_ToFixed( parser, 0 ); + } + + parser->root.cursor = old_cursor; + parser->root.limit = old_limit; + + Exit: + parser->root.error = error; + } + + + /* e.g., /BuildCharArray [0 0 0 0 0 0 0 0] def */ + /* we're only interested in the number of array elements */ + static void + parse_buildchar( T1_Face face, + T1_Loader loader ) + { + face->len_buildchar = T1_ToFixedArray( &loader->parser, 0, NULL, 0 ); + + return; + } + + +#endif /* T1_CONFIG_OPTION_NO_MM_SUPPORT */ + + + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** TYPE 1 SYMBOL PARSING *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static FT_Error + t1_load_keyword( T1_Face face, + T1_Loader loader, + const T1_Field field ) + { + FT_Error error; + void* dummy_object; + void** objects; + FT_UInt max_objects; + PS_Blend blend = face->blend; + + + /* if the keyword has a dedicated callback, call it */ + if ( field->type == T1_FIELD_TYPE_CALLBACK ) + { + field->reader( (FT_Face)face, loader ); + error = loader->parser.root.error; + goto Exit; + } + + /* now, the keyword is either a simple field, or a table of fields; */ + /* we are now going to take care of it */ + switch ( field->location ) + { + case T1_FIELD_LOCATION_FONT_INFO: + dummy_object = &face->type1.font_info; + objects = &dummy_object; + max_objects = 0; + + if ( blend ) + { + objects = (void**)blend->font_infos; + max_objects = blend->num_designs; + } + break; + + case T1_FIELD_LOCATION_FONT_EXTRA: + dummy_object = &face->type1.font_extra; + objects = &dummy_object; + max_objects = 0; + break; + + case T1_FIELD_LOCATION_PRIVATE: + dummy_object = &face->type1.private_dict; + objects = &dummy_object; + max_objects = 0; + + if ( blend ) + { + objects = (void**)blend->privates; + max_objects = blend->num_designs; + } + break; + + case T1_FIELD_LOCATION_BBOX: + dummy_object = &face->type1.font_bbox; + objects = &dummy_object; + max_objects = 0; + + if ( blend ) + { + objects = (void**)blend->bboxes; + max_objects = blend->num_designs; + } + break; + + case T1_FIELD_LOCATION_LOADER: + dummy_object = loader; + objects = &dummy_object; + max_objects = 0; + break; + + case T1_FIELD_LOCATION_FACE: + dummy_object = face; + objects = &dummy_object; + max_objects = 0; + break; + +#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT + case T1_FIELD_LOCATION_BLEND: + dummy_object = face->blend; + objects = &dummy_object; + max_objects = 0; + break; +#endif + + default: + dummy_object = &face->type1; + objects = &dummy_object; + max_objects = 0; + } + + if ( field->type == T1_FIELD_TYPE_INTEGER_ARRAY || + field->type == T1_FIELD_TYPE_FIXED_ARRAY ) + error = T1_Load_Field_Table( &loader->parser, field, + objects, max_objects, 0 ); + else + error = T1_Load_Field( &loader->parser, field, + objects, max_objects, 0 ); + + Exit: + return error; + } + + + static void + parse_private( T1_Face face, + T1_Loader loader ) + { + FT_UNUSED( face ); + + loader->keywords_encountered |= T1_PRIVATE; + } + + + static int + read_binary_data( T1_Parser parser, + FT_Long* size, + FT_Byte** base ) + { + FT_Byte* cur; + FT_Byte* limit = parser->root.limit; + + + /* the binary data has one of the following formats */ + /* */ + /* `size' [white*] RD white ....... ND */ + /* `size' [white*] -| white ....... |- */ + /* */ + + T1_Skip_Spaces( parser ); + + cur = parser->root.cursor; + + if ( cur < limit && ft_isdigit( *cur ) ) + { + *size = T1_ToInt( parser ); + + T1_Skip_PS_Token( parser ); /* `RD' or `-|' or something else */ + + /* there is only one whitespace char after the */ + /* `RD' or `-|' token */ + *base = parser->root.cursor + 1; + + parser->root.cursor += *size + 1; + return !parser->root.error; + } + + FT_ERROR(( "read_binary_data: invalid size field\n" )); + parser->root.error = T1_Err_Invalid_File_Format; + return 0; + } + + + /* We now define the routines to handle the `/Encoding', `/Subrs', */ + /* and `/CharStrings' dictionaries. */ + + static void + parse_font_matrix( T1_Face face, + T1_Loader loader ) + { + T1_Parser parser = &loader->parser; + FT_Matrix* matrix = &face->type1.font_matrix; + FT_Vector* offset = &face->type1.font_offset; + FT_Face root = (FT_Face)&face->root; + FT_Fixed temp[6]; + FT_Fixed temp_scale; + FT_Int result; + + + result = T1_ToFixedArray( parser, 6, temp, 3 ); + + if ( result < 0 ) + { + parser->root.error = T1_Err_Invalid_File_Format; + return; + } + + temp_scale = FT_ABS( temp[3] ); + + if ( temp_scale == 0 ) + { + FT_ERROR(( "parse_font_matrix: invalid font matrix\n" )); + parser->root.error = T1_Err_Invalid_File_Format; + return; + } + + /* Set Units per EM based on FontMatrix values. We set the value to */ + /* 1000 / temp_scale, because temp_scale was already multiplied by */ + /* 1000 (in t1_tofixed, from psobjs.c). */ + + root->units_per_EM = (FT_UShort)( FT_DivFix( 1000 * 0x10000L, + temp_scale ) >> 16 ); + + /* we need to scale the values by 1.0/temp_scale */ + if ( temp_scale != 0x10000L ) + { + temp[0] = FT_DivFix( temp[0], temp_scale ); + temp[1] = FT_DivFix( temp[1], temp_scale ); + temp[2] = FT_DivFix( temp[2], temp_scale ); + temp[4] = FT_DivFix( temp[4], temp_scale ); + temp[5] = FT_DivFix( temp[5], temp_scale ); + temp[3] = 0x10000L; + } + + matrix->xx = temp[0]; + matrix->yx = temp[1]; + matrix->xy = temp[2]; + matrix->yy = temp[3]; + + /* note that the offsets must be expressed in integer font units */ + offset->x = temp[4] >> 16; + offset->y = temp[5] >> 16; + } + + + static void + parse_encoding( T1_Face face, + T1_Loader loader ) + { + T1_Parser parser = &loader->parser; + FT_Byte* cur; + FT_Byte* limit = parser->root.limit; + + PSAux_Service psaux = (PSAux_Service)face->psaux; + + + T1_Skip_Spaces( parser ); + cur = parser->root.cursor; + if ( cur >= limit ) + { + FT_ERROR(( "parse_encoding: out of bounds\n" )); + parser->root.error = T1_Err_Invalid_File_Format; + return; + } + + /* if we have a number or `[', the encoding is an array, */ + /* and we must load it now */ + if ( ft_isdigit( *cur ) || *cur == '[' ) + { + T1_Encoding encode = &face->type1.encoding; + FT_Int count, n; + PS_Table char_table = &loader->encoding_table; + FT_Memory memory = parser->root.memory; + FT_Error error; + FT_Bool only_immediates = 0; + + + /* read the number of entries in the encoding; should be 256 */ + if ( *cur == '[' ) + { + count = 256; + only_immediates = 1; + parser->root.cursor++; + } + else + count = (FT_Int)T1_ToInt( parser ); + + T1_Skip_Spaces( parser ); + if ( parser->root.cursor >= limit ) + return; + + /* we use a T1_Table to store our charnames */ + loader->num_chars = encode->num_chars = count; + if ( FT_NEW_ARRAY( encode->char_index, count ) || + FT_NEW_ARRAY( encode->char_name, count ) || + FT_SET_ERROR( psaux->ps_table_funcs->init( + char_table, count, memory ) ) ) + { + parser->root.error = error; + return; + } + + /* We need to `zero' out encoding_table.elements */ + for ( n = 0; n < count; n++ ) + { + char* notdef = (char *)".notdef"; + + + T1_Add_Table( char_table, n, notdef, 8 ); + } + + /* Now we need to read records of the form */ + /* */ + /* ... charcode /charname ... */ + /* */ + /* for each entry in our table. */ + /* */ + /* We simply look for a number followed by an immediate */ + /* name. Note that this ignores correctly the sequence */ + /* that is often seen in type1 fonts: */ + /* */ + /* 0 1 255 { 1 index exch /.notdef put } for dup */ + /* */ + /* used to clean the encoding array before anything else. */ + /* */ + /* Alternatively, if the array is directly given as */ + /* */ + /* /Encoding [ ... ] */ + /* */ + /* we only read immediates. */ + + n = 0; + T1_Skip_Spaces( parser ); + + while ( parser->root.cursor < limit ) + { + cur = parser->root.cursor; + + /* we stop when we encounter a `def' or `]' */ + if ( *cur == 'd' && cur + 3 < limit ) + { + if ( cur[1] == 'e' && + cur[2] == 'f' && + IS_PS_DELIM( cur[3] ) ) + { + FT_TRACE6(( "encoding end\n" )); + cur += 3; + break; + } + } + if ( *cur == ']' ) + { + FT_TRACE6(( "encoding end\n" )); + cur++; + break; + } + + /* check whether we've found an entry */ + if ( ft_isdigit( *cur ) || only_immediates ) + { + FT_Int charcode; + + + if ( only_immediates ) + charcode = n; + else + { + charcode = (FT_Int)T1_ToInt( parser ); + T1_Skip_Spaces( parser ); + } + + cur = parser->root.cursor; + + if ( *cur == '/' && cur + 2 < limit && n < count ) + { + FT_PtrDist len; + + + cur++; + + parser->root.cursor = cur; + T1_Skip_PS_Token( parser ); + if ( parser->root.error ) + return; + + len = parser->root.cursor - cur; + + parser->root.error = T1_Add_Table( char_table, charcode, + cur, len + 1 ); + if ( parser->root.error ) + return; + char_table->elements[charcode][len] = '\0'; + + n++; + } + else if ( only_immediates ) + { + /* Since the current position is not updated for */ + /* immediates-only mode we would get an infinite loop if */ + /* we don't do anything here. */ + /* */ + /* This encoding array is not valid according to the type1 */ + /* specification (it might be an encoding for a CID type1 */ + /* font, however), so we conclude that this font is NOT a */ + /* type1 font. */ + parser->root.error = FT_Err_Unknown_File_Format; + return; + } + } + else + { + T1_Skip_PS_Token( parser ); + if ( parser->root.error ) + return; + } + + T1_Skip_Spaces( parser ); + } + + face->type1.encoding_type = T1_ENCODING_TYPE_ARRAY; + parser->root.cursor = cur; + } + + /* Otherwise, we should have either `StandardEncoding', */ + /* `ExpertEncoding', or `ISOLatin1Encoding' */ + else + { + if ( cur + 17 < limit && + ft_strncmp( (const char*)cur, "StandardEncoding", 16 ) == 0 ) + face->type1.encoding_type = T1_ENCODING_TYPE_STANDARD; + + else if ( cur + 15 < limit && + ft_strncmp( (const char*)cur, "ExpertEncoding", 14 ) == 0 ) + face->type1.encoding_type = T1_ENCODING_TYPE_EXPERT; + + else if ( cur + 18 < limit && + ft_strncmp( (const char*)cur, "ISOLatin1Encoding", 17 ) == 0 ) + face->type1.encoding_type = T1_ENCODING_TYPE_ISOLATIN1; + + else + parser->root.error = T1_Err_Ignore; + } + } + + + static void + parse_subrs( T1_Face face, + T1_Loader loader ) + { + T1_Parser parser = &loader->parser; + PS_Table table = &loader->subrs; + FT_Memory memory = parser->root.memory; + FT_Error error; + FT_Int num_subrs; + + PSAux_Service psaux = (PSAux_Service)face->psaux; + + + T1_Skip_Spaces( parser ); + + /* test for empty array */ + if ( parser->root.cursor < parser->root.limit && + *parser->root.cursor == '[' ) + { + T1_Skip_PS_Token( parser ); + T1_Skip_Spaces ( parser ); + if ( parser->root.cursor >= parser->root.limit || + *parser->root.cursor != ']' ) + parser->root.error = T1_Err_Invalid_File_Format; + return; + } + + num_subrs = (FT_Int)T1_ToInt( parser ); + + /* position the parser right before the `dup' of the first subr */ + T1_Skip_PS_Token( parser ); /* `array' */ + if ( parser->root.error ) + return; + T1_Skip_Spaces( parser ); + + /* initialize subrs array -- with synthetic fonts it is possible */ + /* we get here twice */ + if ( !loader->num_subrs ) + { + error = psaux->ps_table_funcs->init( table, num_subrs, memory ); + if ( error ) + goto Fail; + } + + /* the format is simple: */ + /* */ + /* `index' + binary data */ + /* */ + for (;;) + { + FT_Long idx, size; + FT_Byte* base; + + + /* If the next token isn't `dup' we are done. */ + if ( ft_strncmp( (char*)parser->root.cursor, "dup", 3 ) != 0 ) + break; + + T1_Skip_PS_Token( parser ); /* `dup' */ + + idx = T1_ToInt( parser ); + + if ( !read_binary_data( parser, &size, &base ) ) + return; + + /* The binary string is followed by one token, e.g. `NP' */ + /* (bound to `noaccess put') or by two separate tokens: */ + /* `noaccess' & `put'. We position the parser right */ + /* before the next `dup', if any. */ + T1_Skip_PS_Token( parser ); /* `NP' or `|' or `noaccess' */ + if ( parser->root.error ) + return; + T1_Skip_Spaces ( parser ); + + if ( ft_strncmp( (char*)parser->root.cursor, "put", 3 ) == 0 ) + { + T1_Skip_PS_Token( parser ); /* skip `put' */ + T1_Skip_Spaces ( parser ); + } + + /* with synthetic fonts it is possible we get here twice */ + if ( loader->num_subrs ) + continue; + + /* some fonts use a value of -1 for lenIV to indicate that */ + /* the charstrings are unencoded */ + /* */ + /* thanks to Tom Kacvinsky for pointing this out */ + /* */ + if ( face->type1.private_dict.lenIV >= 0 ) + { + FT_Byte* temp; + + + /* some fonts define empty subr records -- this is not totally */ + /* compliant to the specification (which says they should at */ + /* least contain a `return'), but we support them anyway */ + if ( size < face->type1.private_dict.lenIV ) + { + error = T1_Err_Invalid_File_Format; + goto Fail; + } + + /* t1_decrypt() shouldn't write to base -- make temporary copy */ + if ( FT_ALLOC( temp, size ) ) + goto Fail; + FT_MEM_COPY( temp, base, size ); + psaux->t1_decrypt( temp, size, 4330 ); + size -= face->type1.private_dict.lenIV; + error = T1_Add_Table( table, (FT_Int)idx, + temp + face->type1.private_dict.lenIV, size ); + FT_FREE( temp ); + } + else + error = T1_Add_Table( table, (FT_Int)idx, base, size ); + if ( error ) + goto Fail; + } + + if ( !loader->num_subrs ) + loader->num_subrs = num_subrs; + + return; + + Fail: + parser->root.error = error; + } + + +#define TABLE_EXTEND 5 + + + static void + parse_charstrings( T1_Face face, + T1_Loader loader ) + { + T1_Parser parser = &loader->parser; + PS_Table code_table = &loader->charstrings; + PS_Table name_table = &loader->glyph_names; + PS_Table swap_table = &loader->swap_table; + FT_Memory memory = parser->root.memory; + FT_Error error; + + PSAux_Service psaux = (PSAux_Service)face->psaux; + + FT_Byte* cur; + FT_Byte* limit = parser->root.limit; + FT_Int n, num_glyphs; + FT_UInt notdef_index = 0; + FT_Byte notdef_found = 0; + + + num_glyphs = (FT_Int)T1_ToInt( parser ); + /* some fonts like Optima-Oblique not only define the /CharStrings */ + /* array but access it also */ + if ( num_glyphs == 0 || parser->root.error ) + return; + + /* initialize tables, leaving space for addition of .notdef, */ + /* if necessary, and a few other glyphs to handle buggy */ + /* fonts which have more glyphs than specified. */ + + /* for some non-standard fonts like `Optima' which provides */ + /* different outlines depending on the resolution it is */ + /* possible to get here twice */ + if ( !loader->num_glyphs ) + { + error = psaux->ps_table_funcs->init( + code_table, num_glyphs + 1 + TABLE_EXTEND, memory ); + if ( error ) + goto Fail; + + error = psaux->ps_table_funcs->init( + name_table, num_glyphs + 1 + TABLE_EXTEND, memory ); + if ( error ) + goto Fail; + + /* Initialize table for swapping index notdef_index and */ + /* index 0 names and codes (if necessary). */ + + error = psaux->ps_table_funcs->init( swap_table, 4, memory ); + if ( error ) + goto Fail; + } + + n = 0; + + for (;;) + { + FT_Long size; + FT_Byte* base; + + + /* the format is simple: */ + /* `/glyphname' + binary data */ + + T1_Skip_Spaces( parser ); + + cur = parser->root.cursor; + if ( cur >= limit ) + break; + + /* we stop when we find a `def' or `end' keyword */ + if ( cur + 3 < limit && IS_PS_DELIM( cur[3] ) ) + { + if ( cur[0] == 'd' && + cur[1] == 'e' && + cur[2] == 'f' ) + { + /* There are fonts which have this: */ + /* */ + /* /CharStrings 118 dict def */ + /* Private begin */ + /* CharStrings begin */ + /* ... */ + /* */ + /* To catch this we ignore `def' if */ + /* no charstring has actually been */ + /* seen. */ + if ( n ) + break; + } + + if ( cur[0] == 'e' && + cur[1] == 'n' && + cur[2] == 'd' ) + break; + } + + T1_Skip_PS_Token( parser ); + if ( parser->root.error ) + return; + + if ( *cur == '/' ) + { + FT_PtrDist len; + + + if ( cur + 1 >= limit ) + { + error = T1_Err_Invalid_File_Format; + goto Fail; + } + + cur++; /* skip `/' */ + len = parser->root.cursor - cur; + + if ( !read_binary_data( parser, &size, &base ) ) + return; + + /* for some non-standard fonts like `Optima' which provides */ + /* different outlines depending on the resolution it is */ + /* possible to get here twice */ + if ( loader->num_glyphs ) + continue; + + error = T1_Add_Table( name_table, n, cur, len + 1 ); + if ( error ) + goto Fail; + + /* add a trailing zero to the name table */ + name_table->elements[n][len] = '\0'; + + /* record index of /.notdef */ + if ( *cur == '.' && + ft_strcmp( ".notdef", + (const char*)(name_table->elements[n]) ) == 0 ) + { + notdef_index = n; + notdef_found = 1; + } + + if ( face->type1.private_dict.lenIV >= 0 && + n < num_glyphs + TABLE_EXTEND ) + { + FT_Byte* temp; + + + if ( size <= face->type1.private_dict.lenIV ) + { + error = T1_Err_Invalid_File_Format; + goto Fail; + } + + /* t1_decrypt() shouldn't write to base -- make temporary copy */ + if ( FT_ALLOC( temp, size ) ) + goto Fail; + FT_MEM_COPY( temp, base, size ); + psaux->t1_decrypt( temp, size, 4330 ); + size -= face->type1.private_dict.lenIV; + error = T1_Add_Table( code_table, n, + temp + face->type1.private_dict.lenIV, size ); + FT_FREE( temp ); + } + else + error = T1_Add_Table( code_table, n, base, size ); + if ( error ) + goto Fail; + + n++; + } + } + + loader->num_glyphs = n; + + /* if /.notdef is found but does not occupy index 0, do our magic. */ + if ( notdef_found && + ft_strcmp( ".notdef", (const char*)name_table->elements[0] ) ) + { + /* Swap glyph in index 0 with /.notdef glyph. First, add index 0 */ + /* name and code entries to swap_table. Then place notdef_index */ + /* name and code entries into swap_table. Then swap name and code */ + /* entries at indices notdef_index and 0 using values stored in */ + /* swap_table. */ + + /* Index 0 name */ + error = T1_Add_Table( swap_table, 0, + name_table->elements[0], + name_table->lengths [0] ); + if ( error ) + goto Fail; + + /* Index 0 code */ + error = T1_Add_Table( swap_table, 1, + code_table->elements[0], + code_table->lengths [0] ); + if ( error ) + goto Fail; + + /* Index notdef_index name */ + error = T1_Add_Table( swap_table, 2, + name_table->elements[notdef_index], + name_table->lengths [notdef_index] ); + if ( error ) + goto Fail; + + /* Index notdef_index code */ + error = T1_Add_Table( swap_table, 3, + code_table->elements[notdef_index], + code_table->lengths [notdef_index] ); + if ( error ) + goto Fail; + + error = T1_Add_Table( name_table, notdef_index, + swap_table->elements[0], + swap_table->lengths [0] ); + if ( error ) + goto Fail; + + error = T1_Add_Table( code_table, notdef_index, + swap_table->elements[1], + swap_table->lengths [1] ); + if ( error ) + goto Fail; + + error = T1_Add_Table( name_table, 0, + swap_table->elements[2], + swap_table->lengths [2] ); + if ( error ) + goto Fail; + + error = T1_Add_Table( code_table, 0, + swap_table->elements[3], + swap_table->lengths [3] ); + if ( error ) + goto Fail; + + } + else if ( !notdef_found ) + { + /* notdef_index is already 0, or /.notdef is undefined in */ + /* charstrings dictionary. Worry about /.notdef undefined. */ + /* We take index 0 and add it to the end of the table(s) */ + /* and add our own /.notdef glyph to index 0. */ + + /* 0 333 hsbw endchar */ + FT_Byte notdef_glyph[] = { 0x8B, 0xF7, 0xE1, 0x0D, 0x0E }; + char* notdef_name = (char *)".notdef"; + + + error = T1_Add_Table( swap_table, 0, + name_table->elements[0], + name_table->lengths [0] ); + if ( error ) + goto Fail; + + error = T1_Add_Table( swap_table, 1, + code_table->elements[0], + code_table->lengths [0] ); + if ( error ) + goto Fail; + + error = T1_Add_Table( name_table, 0, notdef_name, 8 ); + if ( error ) + goto Fail; + + error = T1_Add_Table( code_table, 0, notdef_glyph, 5 ); + + if ( error ) + goto Fail; + + error = T1_Add_Table( name_table, n, + swap_table->elements[0], + swap_table->lengths [0] ); + if ( error ) + goto Fail; + + error = T1_Add_Table( code_table, n, + swap_table->elements[1], + swap_table->lengths [1] ); + if ( error ) + goto Fail; + + /* we added a glyph. */ + loader->num_glyphs += 1; + } + + return; + + Fail: + parser->root.error = error; + } + + + /*************************************************************************/ + /* */ + /* Define the token field static variables. This is a set of */ + /* T1_FieldRec variables. */ + /* */ + /*************************************************************************/ + + + static + const T1_FieldRec t1_keywords[] = + { + +#include "t1tokens.h" + + /* now add the special functions... */ + T1_FIELD_CALLBACK( "FontMatrix", parse_font_matrix, + T1_FIELD_DICT_FONTDICT ) + T1_FIELD_CALLBACK( "Encoding", parse_encoding, + T1_FIELD_DICT_FONTDICT ) + T1_FIELD_CALLBACK( "Subrs", parse_subrs, + T1_FIELD_DICT_PRIVATE ) + T1_FIELD_CALLBACK( "CharStrings", parse_charstrings, + T1_FIELD_DICT_PRIVATE ) + T1_FIELD_CALLBACK( "Private", parse_private, + T1_FIELD_DICT_FONTDICT ) + +#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT + T1_FIELD_CALLBACK( "BlendDesignPositions", parse_blend_design_positions, + T1_FIELD_DICT_FONTDICT ) + T1_FIELD_CALLBACK( "BlendDesignMap", parse_blend_design_map, + T1_FIELD_DICT_FONTDICT ) + T1_FIELD_CALLBACK( "BlendAxisTypes", parse_blend_axis_types, + T1_FIELD_DICT_FONTDICT ) + T1_FIELD_CALLBACK( "WeightVector", parse_weight_vector, + T1_FIELD_DICT_FONTDICT ) + T1_FIELD_CALLBACK( "BuildCharArray", parse_buildchar, + T1_FIELD_DICT_PRIVATE ) +#endif + + { 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_TYPE_NONE, 0, 0, 0, 0, 0, 0 } + }; + + +#define T1_FIELD_COUNT \ + ( sizeof ( t1_keywords ) / sizeof ( t1_keywords[0] ) ) + + + static FT_Error + parse_dict( T1_Face face, + T1_Loader loader, + FT_Byte* base, + FT_Long size ) + { + T1_Parser parser = &loader->parser; + FT_Byte *limit, *start_binary = NULL; + FT_Bool have_integer = 0; + + + parser->root.cursor = base; + parser->root.limit = base + size; + parser->root.error = T1_Err_Ok; + + limit = parser->root.limit; + + T1_Skip_Spaces( parser ); + + while ( parser->root.cursor < limit ) + { + FT_Byte* cur; + + + cur = parser->root.cursor; + + /* look for `eexec' */ + if ( IS_PS_TOKEN( cur, limit, "eexec" ) ) + break; + + /* look for `closefile' which ends the eexec section */ + else if ( IS_PS_TOKEN( cur, limit, "closefile" ) ) + break; + + /* in a synthetic font the base font starts after a */ + /* `FontDictionary' token that is placed after a Private dict */ + else if ( IS_PS_TOKEN( cur, limit, "FontDirectory" ) ) + { + if ( loader->keywords_encountered & T1_PRIVATE ) + loader->keywords_encountered |= + T1_FONTDIR_AFTER_PRIVATE; + parser->root.cursor += 13; + } + + /* check whether we have an integer */ + else if ( ft_isdigit( *cur ) ) + { + start_binary = cur; + T1_Skip_PS_Token( parser ); + if ( parser->root.error ) + goto Exit; + have_integer = 1; + } + + /* in valid Type 1 fonts we don't see `RD' or `-|' directly */ + /* since those tokens are handled by parse_subrs and */ + /* parse_charstrings */ + else if ( *cur == 'R' && cur + 6 < limit && *(cur + 1) == 'D' && + have_integer ) + { + FT_Long s; + FT_Byte* b; + + + parser->root.cursor = start_binary; + if ( !read_binary_data( parser, &s, &b ) ) + return T1_Err_Invalid_File_Format; + have_integer = 0; + } + + else if ( *cur == '-' && cur + 6 < limit && *(cur + 1) == '|' && + have_integer ) + { + FT_Long s; + FT_Byte* b; + + + parser->root.cursor = start_binary; + if ( !read_binary_data( parser, &s, &b ) ) + return T1_Err_Invalid_File_Format; + have_integer = 0; + } + + /* look for immediates */ + else if ( *cur == '/' && cur + 2 < limit ) + { + FT_PtrDist len; + + + cur++; + + parser->root.cursor = cur; + T1_Skip_PS_Token( parser ); + if ( parser->root.error ) + goto Exit; + + len = parser->root.cursor - cur; + + if ( len > 0 && len < 22 && parser->root.cursor < limit ) + { + /* now compare the immediate name to the keyword table */ + T1_Field keyword = (T1_Field)t1_keywords; + + + for (;;) + { + FT_Byte* name; + + + name = (FT_Byte*)keyword->ident; + if ( !name ) + break; + + if ( cur[0] == name[0] && + len == (FT_PtrDist)ft_strlen( (const char *)name ) && + ft_memcmp( cur, name, len ) == 0 ) + { + /* We found it -- run the parsing callback! */ + /* We record every instance of every field */ + /* (until we reach the base font of a */ + /* synthetic font) to deal adequately with */ + /* multiple master fonts; this is also */ + /* necessary because later PostScript */ + /* definitions override earlier ones. */ + + /* Once we encounter `FontDirectory' after */ + /* `/Private', we know that this is a synthetic */ + /* font; except for `/CharStrings' we are not */ + /* interested in anything that follows this */ + /* `FontDirectory'. */ + + /* MM fonts have more than one /Private token at */ + /* the top level; let's hope that all the junk */ + /* that follows the first /Private token is not */ + /* interesting to us. */ + + /* According to Adobe Tech Note #5175 (CID-Keyed */ + /* Font Installation for ATM Software) a `begin' */ + /* must be followed by exactly one `end', and */ + /* `begin' -- `end' pairs must be accurately */ + /* paired. We could use this to distinguish */ + /* between the global Private and the Private */ + /* dict that is a member of the Blend dict. */ + + const FT_UInt dict = + ( loader->keywords_encountered & T1_PRIVATE ) + ? T1_FIELD_DICT_PRIVATE + : T1_FIELD_DICT_FONTDICT; + + if ( !( dict & keyword->dict ) ) + { + FT_TRACE1(( "parse_dict: found %s but ignoring it " + "since it is in the wrong dictionary\n", + keyword->ident )); + break; + } + + if ( !( loader->keywords_encountered & + T1_FONTDIR_AFTER_PRIVATE ) || + ft_strcmp( (const char*)name, "CharStrings" ) == 0 ) + { + parser->root.error = t1_load_keyword( face, + loader, + keyword ); + if ( parser->root.error != T1_Err_Ok ) + { + if ( FT_ERROR_BASE( parser->root.error ) == FT_Err_Ignore ) + parser->root.error = T1_Err_Ok; + else + return parser->root.error; + } + } + break; + } + + keyword++; + } + } + + have_integer = 0; + } + else + { + T1_Skip_PS_Token( parser ); + if ( parser->root.error ) + goto Exit; + have_integer = 0; + } + + T1_Skip_Spaces( parser ); + } + + Exit: + return parser->root.error; + } + + + static void + t1_init_loader( T1_Loader loader, + T1_Face face ) + { + FT_UNUSED( face ); + + FT_MEM_ZERO( loader, sizeof ( *loader ) ); + loader->num_glyphs = 0; + loader->num_chars = 0; + + /* initialize the tables -- simply set their `init' field to 0 */ + loader->encoding_table.init = 0; + loader->charstrings.init = 0; + loader->glyph_names.init = 0; + loader->subrs.init = 0; + loader->swap_table.init = 0; + loader->fontdata = 0; + loader->keywords_encountered = 0; + } + + + static void + t1_done_loader( T1_Loader loader ) + { + T1_Parser parser = &loader->parser; + + + /* finalize tables */ + T1_Release_Table( &loader->encoding_table ); + T1_Release_Table( &loader->charstrings ); + T1_Release_Table( &loader->glyph_names ); + T1_Release_Table( &loader->swap_table ); + T1_Release_Table( &loader->subrs ); + + /* finalize parser */ + T1_Finalize_Parser( parser ); + } + + + FT_LOCAL_DEF( FT_Error ) + T1_Open_Face( T1_Face face ) + { + T1_LoaderRec loader; + T1_Parser parser; + T1_Font type1 = &face->type1; + PS_Private priv = &type1->private_dict; + FT_Error error; + + PSAux_Service psaux = (PSAux_Service)face->psaux; + + + t1_init_loader( &loader, face ); + + /* default values */ + face->ndv_idx = -1; + face->cdv_idx = -1; + face->len_buildchar = 0; + + priv->blue_shift = 7; + priv->blue_fuzz = 1; + priv->lenIV = 4; + priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L ); + priv->blue_scale = (FT_Fixed)( 0.039625 * 0x10000L * 1000 ); + + parser = &loader.parser; + error = T1_New_Parser( parser, + face->root.stream, + face->root.memory, + psaux ); + if ( error ) + goto Exit; + + error = parse_dict( face, &loader, + parser->base_dict, parser->base_len ); + if ( error ) + goto Exit; + + error = T1_Get_Private_Dict( parser, psaux ); + if ( error ) + goto Exit; + + error = parse_dict( face, &loader, + parser->private_dict, parser->private_len ); + if ( error ) + goto Exit; + + /* ensure even-ness of `num_blue_values' */ + priv->num_blue_values &= ~1; + +#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT + + if ( face->blend && + face->blend->num_default_design_vector != 0 && + face->blend->num_default_design_vector != face->blend->num_axis ) + { + /* we don't use it currently so just warn, reset, and ignore */ + FT_ERROR(( "T1_Open_Face(): /DesignVector contains %u entries " + "while there are %u axes.\n", + face->blend->num_default_design_vector, + face->blend->num_axis )); + + face->blend->num_default_design_vector = 0; + } + + /* the following can happen for MM instances; we then treat the */ + /* font as a normal PS font */ + if ( face->blend && + ( !face->blend->num_designs || !face->blend->num_axis ) ) + T1_Done_Blend( face ); + + /* another safety check */ + if ( face->blend ) + { + FT_UInt i; + + + for ( i = 0; i < face->blend->num_axis; i++ ) + if ( !face->blend->design_map[i].num_points ) + { + T1_Done_Blend( face ); + break; + } + } + + if ( face->blend ) + { + if ( face->len_buildchar > 0 ) + { + FT_Memory memory = face->root.memory; + + + if ( FT_NEW_ARRAY( face->buildchar, face->len_buildchar ) ) + { + FT_ERROR(( "T1_Open_Face: cannot allocate BuildCharArray\n" )); + face->len_buildchar = 0; + goto Exit; + } + } + } + +#endif /* T1_CONFIG_OPTION_NO_MM_SUPPORT */ + + /* now, propagate the subrs, charstrings, and glyphnames tables */ + /* to the Type1 data */ + type1->num_glyphs = loader.num_glyphs; + + if ( loader.subrs.init ) + { + loader.subrs.init = 0; + type1->num_subrs = loader.num_subrs; + type1->subrs_block = loader.subrs.block; + type1->subrs = loader.subrs.elements; + type1->subrs_len = loader.subrs.lengths; + } + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + if ( !face->root.internal->incremental_interface ) +#endif + if ( !loader.charstrings.init ) + { + FT_ERROR(( "T1_Open_Face: no `/CharStrings' array in face\n" )); + error = T1_Err_Invalid_File_Format; + } + + loader.charstrings.init = 0; + type1->charstrings_block = loader.charstrings.block; + type1->charstrings = loader.charstrings.elements; + type1->charstrings_len = loader.charstrings.lengths; + + /* we copy the glyph names `block' and `elements' fields; */ + /* the `lengths' field must be released later */ + type1->glyph_names_block = loader.glyph_names.block; + type1->glyph_names = (FT_String**)loader.glyph_names.elements; + loader.glyph_names.block = 0; + loader.glyph_names.elements = 0; + + /* we must now build type1.encoding when we have a custom array */ + if ( type1->encoding_type == T1_ENCODING_TYPE_ARRAY ) + { + FT_Int charcode, idx, min_char, max_char; + FT_Byte* char_name; + FT_Byte* glyph_name; + + + /* OK, we do the following: for each element in the encoding */ + /* table, look up the index of the glyph having the same name */ + /* the index is then stored in type1.encoding.char_index, and */ + /* a the name to type1.encoding.char_name */ + + min_char = 0; + max_char = 0; + + charcode = 0; + for ( ; charcode < loader.encoding_table.max_elems; charcode++ ) + { + type1->encoding.char_index[charcode] = 0; + type1->encoding.char_name [charcode] = (char *)".notdef"; + + char_name = loader.encoding_table.elements[charcode]; + if ( char_name ) + for ( idx = 0; idx < type1->num_glyphs; idx++ ) + { + glyph_name = (FT_Byte*)type1->glyph_names[idx]; + if ( ft_strcmp( (const char*)char_name, + (const char*)glyph_name ) == 0 ) + { + type1->encoding.char_index[charcode] = (FT_UShort)idx; + type1->encoding.char_name [charcode] = (char*)glyph_name; + + /* Change min/max encoded char only if glyph name is */ + /* not /.notdef */ + if ( ft_strcmp( (const char*)".notdef", + (const char*)glyph_name ) != 0 ) + { + if ( charcode < min_char ) + min_char = charcode; + if ( charcode >= max_char ) + max_char = charcode + 1; + } + break; + } + } + } + + type1->encoding.code_first = min_char; + type1->encoding.code_last = max_char; + type1->encoding.num_chars = loader.num_chars; + } + + Exit: + t1_done_loader( &loader ); + return error; + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/type1/t1load.h b/mod/pub.mod/freetype.mod/src/type1/t1load.h new file mode 100644 index 0000000..546fc33 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/type1/t1load.h @@ -0,0 +1,102 @@ +/***************************************************************************/ +/* */ +/* t1load.h */ +/* */ +/* Type 1 font loader (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2004, 2006, 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __T1LOAD_H__ +#define __T1LOAD_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_POSTSCRIPT_AUX_H +#include FT_MULTIPLE_MASTERS_H + +#include "t1parse.h" + + +FT_BEGIN_HEADER + + + typedef struct T1_Loader_ + { + T1_ParserRec parser; /* parser used to read the stream */ + + FT_Int num_chars; /* number of characters in encoding */ + PS_TableRec encoding_table; /* PS_Table used to store the */ + /* encoding character names */ + + FT_Int num_glyphs; + PS_TableRec glyph_names; + PS_TableRec charstrings; + PS_TableRec swap_table; /* For moving .notdef glyph to index 0. */ + + FT_Int num_subrs; + PS_TableRec subrs; + FT_Bool fontdata; + + FT_UInt keywords_encountered; /* T1_LOADER_ENCOUNTERED_XXX */ + + } T1_LoaderRec, *T1_Loader; + + + /* treatment of some keywords differs depending on whether */ + /* they precede or follow certain other keywords */ + +#define T1_PRIVATE ( 1 << 0 ) +#define T1_FONTDIR_AFTER_PRIVATE ( 1 << 1 ) + + + FT_LOCAL( FT_Error ) + T1_Open_Face( T1_Face face ); + +#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT + + FT_LOCAL( FT_Error ) + T1_Get_Multi_Master( T1_Face face, + FT_Multi_Master* master ); + + FT_LOCAL_DEF( FT_Error ) + T1_Get_MM_Var( T1_Face face, + FT_MM_Var* *master ); + + FT_LOCAL( FT_Error ) + T1_Set_MM_Blend( T1_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); + + FT_LOCAL( FT_Error ) + T1_Set_MM_Design( T1_Face face, + FT_UInt num_coords, + FT_Long* coords ); + + FT_LOCAL_DEF( FT_Error ) + T1_Set_Var_Design( T1_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); + + FT_LOCAL( void ) + T1_Done_Blend( T1_Face face ); + +#endif /* !T1_CONFIG_OPTION_NO_MM_SUPPORT */ + + +FT_END_HEADER + +#endif /* __T1LOAD_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/type1/t1objs.c b/mod/pub.mod/freetype.mod/src/type1/t1objs.c new file mode 100644 index 0000000..e9357e6 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/type1/t1objs.c @@ -0,0 +1,593 @@ +/***************************************************************************/ +/* */ +/* t1objs.c */ +/* */ +/* Type 1 objects manager (body). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_CALC_H +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_TRUETYPE_IDS_H + +#include "t1gload.h" +#include "t1load.h" + +#include "t1errors.h" + +#ifndef T1_CONFIG_OPTION_NO_AFM +#include "t1afm.h" +#endif + +#include FT_SERVICE_POSTSCRIPT_CMAPS_H +#include FT_INTERNAL_POSTSCRIPT_AUX_H + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_t1objs + + + /*************************************************************************/ + /* */ + /* SIZE FUNCTIONS */ + /* */ + /* note that we store the global hints in the size's "internal" root */ + /* field */ + /* */ + /*************************************************************************/ + + + static PSH_Globals_Funcs + T1_Size_Get_Globals_Funcs( T1_Size size ) + { + T1_Face face = (T1_Face)size->root.face; + PSHinter_Service pshinter = (PSHinter_Service)face->pshinter; + FT_Module module; + + + module = FT_Get_Module( size->root.face->driver->root.library, + "pshinter" ); + return ( module && pshinter && pshinter->get_globals_funcs ) + ? pshinter->get_globals_funcs( module ) + : 0 ; + } + + + FT_LOCAL_DEF( void ) + T1_Size_Done( T1_Size size ) + { + if ( size->root.internal ) + { + PSH_Globals_Funcs funcs; + + + funcs = T1_Size_Get_Globals_Funcs( size ); + if ( funcs ) + funcs->destroy( (PSH_Globals)size->root.internal ); + + size->root.internal = 0; + } + } + + + FT_LOCAL_DEF( FT_Error ) + T1_Size_Init( T1_Size size ) + { + FT_Error error = T1_Err_Ok; + PSH_Globals_Funcs funcs = T1_Size_Get_Globals_Funcs( size ); + + + if ( funcs ) + { + PSH_Globals globals; + T1_Face face = (T1_Face)size->root.face; + + + error = funcs->create( size->root.face->memory, + &face->type1.private_dict, &globals ); + if ( !error ) + size->root.internal = (FT_Size_Internal)(void*)globals; + } + + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + T1_Size_Request( T1_Size size, + FT_Size_Request req ) + { + PSH_Globals_Funcs funcs = T1_Size_Get_Globals_Funcs( size ); + + + FT_Request_Metrics( size->root.face, req ); + + if ( funcs ) + funcs->set_scale( (PSH_Globals)size->root.internal, + size->root.metrics.x_scale, + size->root.metrics.y_scale, + 0, 0 ); + + return T1_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* SLOT FUNCTIONS */ + /* */ + /*************************************************************************/ + + FT_LOCAL_DEF( void ) + T1_GlyphSlot_Done( T1_GlyphSlot slot ) + { + slot->root.internal->glyph_hints = 0; + } + + + FT_LOCAL_DEF( FT_Error ) + T1_GlyphSlot_Init( T1_GlyphSlot slot ) + { + T1_Face face; + PSHinter_Service pshinter; + + + face = (T1_Face)slot->root.face; + pshinter = (PSHinter_Service)face->pshinter; + + if ( pshinter ) + { + FT_Module module; + + + module = FT_Get_Module( slot->root.face->driver->root.library, "pshinter" ); + if (module) + { + T1_Hints_Funcs funcs; + + funcs = pshinter->get_t1_funcs( module ); + slot->root.internal->glyph_hints = (void*)funcs; + } + } + return 0; + } + + + /*************************************************************************/ + /* */ + /* FACE FUNCTIONS */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* T1_Face_Done */ + /* */ + /* <Description> */ + /* The face object destructor. */ + /* */ + /* <Input> */ + /* face :: A typeless pointer to the face object to destroy. */ + /* */ + FT_LOCAL_DEF( void ) + T1_Face_Done( T1_Face face ) + { + FT_Memory memory; + T1_Font type1; + + + if ( !face ) + return; + + memory = face->root.memory; + type1 = &face->type1; + +#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT + /* release multiple masters information */ + FT_ASSERT( ( face->len_buildchar == 0 ) == ( face->buildchar == NULL ) ); + + if ( face->buildchar ) + { + FT_FREE( face->buildchar ); + + face->buildchar = NULL; + face->len_buildchar = 0; + } + + T1_Done_Blend( face ); + face->blend = 0; +#endif + + /* release font info strings */ + { + PS_FontInfo info = &type1->font_info; + + + FT_FREE( info->version ); + FT_FREE( info->notice ); + FT_FREE( info->full_name ); + FT_FREE( info->family_name ); + FT_FREE( info->weight ); + } + + /* release top dictionary */ + FT_FREE( type1->charstrings_len ); + FT_FREE( type1->charstrings ); + FT_FREE( type1->glyph_names ); + + FT_FREE( type1->subrs ); + FT_FREE( type1->subrs_len ); + + FT_FREE( type1->subrs_block ); + FT_FREE( type1->charstrings_block ); + FT_FREE( type1->glyph_names_block ); + + FT_FREE( type1->encoding.char_index ); + FT_FREE( type1->encoding.char_name ); + FT_FREE( type1->font_name ); + +#ifndef T1_CONFIG_OPTION_NO_AFM + /* release afm data if present */ + if ( face->afm_data ) + T1_Done_Metrics( memory, (AFM_FontInfo)face->afm_data ); +#endif + + /* release unicode map, if any */ +#if 0 + FT_FREE( face->unicode_map_rec.maps ); + face->unicode_map_rec.num_maps = 0; + face->unicode_map = NULL; +#endif + + face->root.family_name = NULL; + face->root.style_name = NULL; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* T1_Face_Init */ + /* */ + /* <Description> */ + /* The face object constructor. */ + /* */ + /* <Input> */ + /* stream :: input stream where to load font data. */ + /* */ + /* face_index :: The index of the font face in the resource. */ + /* */ + /* num_params :: Number of additional generic parameters. Ignored. */ + /* */ + /* params :: Additional generic parameters. Ignored. */ + /* */ + /* <InOut> */ + /* face :: The face record to build. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + T1_Face_Init( FT_Stream stream, + T1_Face face, + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ) + { + FT_Error error; + FT_Service_PsCMaps psnames; + PSAux_Service psaux; + T1_Font type1 = &face->type1; + PS_FontInfo info = &type1->font_info; + + FT_UNUSED( num_params ); + FT_UNUSED( params ); + FT_UNUSED( stream ); + + + face->root.num_faces = 1; + + FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); + face->psnames = psnames; + + face->psaux = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ), + "psaux" ); + psaux = (PSAux_Service)face->psaux; + + face->pshinter = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ), + "pshinter" ); + + /* open the tokenizer; this will also check the font format */ + error = T1_Open_Face( face ); + if ( error ) + goto Exit; + + /* if we just wanted to check the format, leave successfully now */ + if ( face_index < 0 ) + goto Exit; + + /* check the face index */ + if ( face_index > 0 ) + { + FT_ERROR(( "T1_Face_Init: invalid face index\n" )); + error = T1_Err_Invalid_Argument; + goto Exit; + } + + /* now load the font program into the face object */ + + /* initialize the face object fields */ + + /* set up root face fields */ + { + FT_Face root = (FT_Face)&face->root; + + + root->num_glyphs = type1->num_glyphs; + root->face_index = 0; + + root->face_flags = FT_FACE_FLAG_SCALABLE | + FT_FACE_FLAG_HORIZONTAL | + FT_FACE_FLAG_GLYPH_NAMES | + FT_FACE_FLAG_HINTER; + + if ( info->is_fixed_pitch ) + root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; + + if ( face->blend ) + root->face_flags |= FT_FACE_FLAG_MULTIPLE_MASTERS; + + /* XXX: TODO -- add kerning with .afm support */ + + + /* The following code to extract the family and the style is very */ + /* simplistic and might get some things wrong. For a full-featured */ + /* algorithm you might have a look at the whitepaper given at */ + /* */ + /* http://blogs.msdn.com/text/archive/2007/04/23/wpf-font-selection-model.aspx */ + + /* get style name -- be careful, some broken fonts only */ + /* have a `/FontName' dictionary entry! */ + root->family_name = info->family_name; + root->style_name = NULL; + + if ( root->family_name ) + { + char* full = info->full_name; + char* family = root->family_name; + + + if ( full ) + { + FT_Bool the_same = TRUE; + + + while ( *full ) + { + if ( *full == *family ) + { + family++; + full++; + } + else + { + if ( *full == ' ' || *full == '-' ) + full++; + else if ( *family == ' ' || *family == '-' ) + family++; + else + { + the_same = FALSE; + + if ( !*family ) + root->style_name = full; + break; + } + } + } + + if ( the_same ) + root->style_name = (char *)"Regular"; + } + } + else + { + /* do we have a `/FontName'? */ + if ( type1->font_name ) + root->family_name = type1->font_name; + } + + if ( !root->style_name ) + { + if ( info->weight ) + root->style_name = info->weight; + else + /* assume `Regular' style because we don't know better */ + root->style_name = (char *)"Regular"; + } + + /* compute style flags */ + root->style_flags = 0; + if ( info->italic_angle ) + root->style_flags |= FT_STYLE_FLAG_ITALIC; + if ( info->weight ) + { + if ( !ft_strcmp( info->weight, "Bold" ) || + !ft_strcmp( info->weight, "Black" ) ) + root->style_flags |= FT_STYLE_FLAG_BOLD; + } + + /* no embedded bitmap support */ + root->num_fixed_sizes = 0; + root->available_sizes = 0; + + root->bbox.xMin = type1->font_bbox.xMin >> 16; + root->bbox.yMin = type1->font_bbox.yMin >> 16; + root->bbox.xMax = ( type1->font_bbox.xMax + 0xFFFFU ) >> 16; + root->bbox.yMax = ( type1->font_bbox.yMax + 0xFFFFU ) >> 16; + + /* Set units_per_EM if we didn't set it in parse_font_matrix. */ + if ( !root->units_per_EM ) + root->units_per_EM = 1000; + + root->ascender = (FT_Short)( root->bbox.yMax ); + root->descender = (FT_Short)( root->bbox.yMin ); + + root->height = (FT_Short)( ( root->units_per_EM * 12 ) / 10 ); + if ( root->height < root->ascender - root->descender ) + root->height = (FT_Short)( root->ascender - root->descender ); + + /* now compute the maximum advance width */ + root->max_advance_width = + (FT_Short)( root->bbox.xMax ); + { + FT_Pos max_advance; + + + error = T1_Compute_Max_Advance( face, &max_advance ); + + /* in case of error, keep the standard width */ + if ( !error ) + root->max_advance_width = (FT_Short)FIXED_TO_INT( max_advance ); + else + error = T1_Err_Ok; /* clear error */ + } + + root->max_advance_height = root->height; + + root->underline_position = (FT_Short)info->underline_position; + root->underline_thickness = (FT_Short)info->underline_thickness; + } + + { + FT_Face root = &face->root; + + + if ( psnames && psaux ) + { + FT_CharMapRec charmap; + T1_CMap_Classes cmap_classes = psaux->t1_cmap_classes; + FT_CMap_Class clazz; + + + charmap.face = root; + + /* first of all, try to synthesize a Unicode charmap */ + charmap.platform_id = 3; + charmap.encoding_id = 1; + charmap.encoding = FT_ENCODING_UNICODE; + + FT_CMap_New( cmap_classes->unicode, NULL, &charmap, NULL ); + + /* now, generate an Adobe Standard encoding when appropriate */ + charmap.platform_id = 7; + clazz = NULL; + + switch ( type1->encoding_type ) + { + case T1_ENCODING_TYPE_STANDARD: + charmap.encoding = FT_ENCODING_ADOBE_STANDARD; + charmap.encoding_id = TT_ADOBE_ID_STANDARD; + clazz = cmap_classes->standard; + break; + + case T1_ENCODING_TYPE_EXPERT: + charmap.encoding = FT_ENCODING_ADOBE_EXPERT; + charmap.encoding_id = TT_ADOBE_ID_EXPERT; + clazz = cmap_classes->expert; + break; + + case T1_ENCODING_TYPE_ARRAY: + charmap.encoding = FT_ENCODING_ADOBE_CUSTOM; + charmap.encoding_id = TT_ADOBE_ID_CUSTOM; + clazz = cmap_classes->custom; + break; + + case T1_ENCODING_TYPE_ISOLATIN1: + charmap.encoding = FT_ENCODING_ADOBE_LATIN_1; + charmap.encoding_id = TT_ADOBE_ID_LATIN_1; + clazz = cmap_classes->unicode; + break; + + default: + ; + } + + if ( clazz ) + FT_CMap_New( clazz, NULL, &charmap, NULL ); + +#if 0 + /* Select default charmap */ + if (root->num_charmaps) + root->charmap = root->charmaps[0]; +#endif + } + } + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* T1_Driver_Init */ + /* */ + /* <Description> */ + /* Initializes a given Type 1 driver object. */ + /* */ + /* <Input> */ + /* driver :: A handle to the target driver object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + T1_Driver_Init( T1_Driver driver ) + { + FT_UNUSED( driver ); + + return T1_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* T1_Driver_Done */ + /* */ + /* <Description> */ + /* Finalizes a given Type 1 driver. */ + /* */ + /* <Input> */ + /* driver :: A handle to the target Type 1 driver. */ + /* */ + FT_LOCAL_DEF( void ) + T1_Driver_Done( T1_Driver driver ) + { + FT_UNUSED( driver ); + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/type1/t1objs.h b/mod/pub.mod/freetype.mod/src/type1/t1objs.h new file mode 100644 index 0000000..e5e9029 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/type1/t1objs.h @@ -0,0 +1,171 @@ +/***************************************************************************/ +/* */ +/* t1objs.h */ +/* */ +/* Type 1 objects manager (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __T1OBJS_H__ +#define __T1OBJS_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H +#include FT_CONFIG_CONFIG_H +#include FT_INTERNAL_TYPE1_TYPES_H + + +FT_BEGIN_HEADER + + + /* The following structures must be defined by the hinter */ + typedef struct T1_Size_Hints_ T1_Size_Hints; + typedef struct T1_Glyph_Hints_ T1_Glyph_Hints; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* T1_Driver */ + /* */ + /* <Description> */ + /* A handle to a Type 1 driver object. */ + /* */ + typedef struct T1_DriverRec_ *T1_Driver; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* T1_Size */ + /* */ + /* <Description> */ + /* A handle to a Type 1 size object. */ + /* */ + typedef struct T1_SizeRec_* T1_Size; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* T1_GlyphSlot */ + /* */ + /* <Description> */ + /* A handle to a Type 1 glyph slot object. */ + /* */ + typedef struct T1_GlyphSlotRec_* T1_GlyphSlot; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* T1_CharMap */ + /* */ + /* <Description> */ + /* A handle to a Type 1 character mapping object. */ + /* */ + /* <Note> */ + /* The Type 1 format doesn't use a charmap but an encoding table. */ + /* The driver is responsible for making up charmap objects */ + /* corresponding to these tables. */ + /* */ + typedef struct T1_CharMapRec_* T1_CharMap; + + + /*************************************************************************/ + /* */ + /* HERE BEGINS THE TYPE1 SPECIFIC STUFF */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* T1_SizeRec */ + /* */ + /* <Description> */ + /* Type 1 size record. */ + /* */ + typedef struct T1_SizeRec_ + { + FT_SizeRec root; + + } T1_SizeRec; + + + FT_LOCAL( void ) + T1_Size_Done( T1_Size size ); + + FT_LOCAL( FT_Error ) + T1_Size_Request( T1_Size size, + FT_Size_Request req ); + + FT_LOCAL( FT_Error ) + T1_Size_Init( T1_Size size ); + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* T1_GlyphSlotRec */ + /* */ + /* <Description> */ + /* Type 1 glyph slot record. */ + /* */ + typedef struct T1_GlyphSlotRec_ + { + FT_GlyphSlotRec root; + + FT_Bool hint; + FT_Bool scaled; + + FT_Int max_points; + FT_Int max_contours; + + FT_Fixed x_scale; + FT_Fixed y_scale; + + } T1_GlyphSlotRec; + + + FT_LOCAL( FT_Error ) + T1_Face_Init( FT_Stream stream, + T1_Face face, + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ); + + FT_LOCAL( void ) + T1_Face_Done( T1_Face face ); + + FT_LOCAL( FT_Error ) + T1_GlyphSlot_Init( T1_GlyphSlot slot ); + + FT_LOCAL( void ) + T1_GlyphSlot_Done( T1_GlyphSlot slot ); + + FT_LOCAL( FT_Error ) + T1_Driver_Init( T1_Driver driver ); + + FT_LOCAL( void ) + T1_Driver_Done( T1_Driver driver ); + + +FT_END_HEADER + +#endif /* __T1OBJS_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/type1/t1parse.c b/mod/pub.mod/freetype.mod/src/type1/t1parse.c new file mode 100644 index 0000000..1bef56b --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/type1/t1parse.c @@ -0,0 +1,483 @@ +/***************************************************************************/ +/* */ +/* t1parse.c */ +/* */ +/* Type 1 parser (body). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* The Type 1 parser is in charge of the following: */ + /* */ + /* - provide an implementation of a growing sequence of objects called */ + /* a `T1_Table' (used to build various tables needed by the loader). */ + /* */ + /* - opening .pfb and .pfa files to extract their top-level and private */ + /* dictionaries. */ + /* */ + /* - read numbers, arrays & strings from any dictionary. */ + /* */ + /* See `t1load.c' to see how data is loaded from the font file. */ + /* */ + /*************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_POSTSCRIPT_AUX_H + +#include "t1parse.h" + +#include "t1errors.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_t1parse + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** INPUT STREAM PARSER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /* see Adobe Technical Note 5040.Download_Fonts.pdf */ + + static FT_Error + read_pfb_tag( FT_Stream stream, + FT_UShort *atag, + FT_ULong *asize ) + { + FT_Error error; + FT_UShort tag; + FT_ULong size; + + + *atag = 0; + *asize = 0; + + if ( !FT_READ_USHORT( tag ) ) + { + if ( tag == 0x8001U || tag == 0x8002U ) + { + if ( !FT_READ_ULONG_LE( size ) ) + *asize = size; + } + + *atag = tag; + } + + return error; + } + + + static FT_Error + check_type1_format( FT_Stream stream, + const char* header_string, + size_t header_length ) + { + FT_Error error; + FT_UShort tag; + FT_ULong dummy; + + + if ( FT_STREAM_SEEK( 0 ) ) + goto Exit; + + error = read_pfb_tag( stream, &tag, &dummy ); + if ( error ) + goto Exit; + + /* We assume that the first segment in a PFB is always encoded as */ + /* text. This might be wrong (and the specification doesn't insist */ + /* on that), but we have never seen a counterexample. */ + if ( tag != 0x8001U && FT_STREAM_SEEK( 0 ) ) + goto Exit; + + if ( !FT_FRAME_ENTER( header_length ) ) + { + error = T1_Err_Ok; + + if ( ft_memcmp( stream->cursor, header_string, header_length ) != 0 ) + error = T1_Err_Unknown_File_Format; + + FT_FRAME_EXIT(); + } + + Exit: + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + T1_New_Parser( T1_Parser parser, + FT_Stream stream, + FT_Memory memory, + PSAux_Service psaux ) + { + FT_Error error; + FT_UShort tag; + FT_ULong size; + + + psaux->ps_parser_funcs->init( &parser->root, 0, 0, memory ); + + parser->stream = stream; + parser->base_len = 0; + parser->base_dict = 0; + parser->private_len = 0; + parser->private_dict = 0; + parser->in_pfb = 0; + parser->in_memory = 0; + parser->single_block = 0; + + /* check the header format */ + error = check_type1_format( stream, "%!PS-AdobeFont", 14 ); + if ( error ) + { + if ( error != T1_Err_Unknown_File_Format ) + goto Exit; + + error = check_type1_format( stream, "%!FontType", 10 ); + if ( error ) + { + FT_TRACE2(( "[not a Type1 font]\n" )); + goto Exit; + } + } + + /******************************************************************/ + /* */ + /* Here a short summary of what is going on: */ + /* */ + /* When creating a new Type 1 parser, we try to locate and load */ + /* the base dictionary if this is possible (i.e., for PFB */ + /* files). Otherwise, we load the whole font into memory. */ + /* */ + /* When `loading' the base dictionary, we only setup pointers */ + /* in the case of a memory-based stream. Otherwise, we */ + /* allocate and load the base dictionary in it. */ + /* */ + /* parser->in_pfb is set if we are in a binary (`.pfb') font. */ + /* parser->in_memory is set if we have a memory stream. */ + /* */ + + /* try to compute the size of the base dictionary; */ + /* look for a Postscript binary file tag, i.e., 0x8001 */ + if ( FT_STREAM_SEEK( 0L ) ) + goto Exit; + + error = read_pfb_tag( stream, &tag, &size ); + if ( error ) + goto Exit; + + if ( tag != 0x8001U ) + { + /* assume that this is a PFA file for now; an error will */ + /* be produced later when more things are checked */ + if ( FT_STREAM_SEEK( 0L ) ) + goto Exit; + size = stream->size; + } + else + parser->in_pfb = 1; + + /* now, try to load `size' bytes of the `base' dictionary we */ + /* found previously */ + + /* if it is a memory-based resource, set up pointers */ + if ( !stream->read ) + { + parser->base_dict = (FT_Byte*)stream->base + stream->pos; + parser->base_len = size; + parser->in_memory = 1; + + /* check that the `size' field is valid */ + if ( FT_STREAM_SKIP( size ) ) + goto Exit; + } + else + { + /* read segment in memory -- this is clumsy, but so does the format */ + if ( FT_ALLOC( parser->base_dict, size ) || + FT_STREAM_READ( parser->base_dict, size ) ) + goto Exit; + parser->base_len = size; + } + + parser->root.base = parser->base_dict; + parser->root.cursor = parser->base_dict; + parser->root.limit = parser->root.cursor + parser->base_len; + + Exit: + if ( error && !parser->in_memory ) + FT_FREE( parser->base_dict ); + + return error; + } + + + FT_LOCAL_DEF( void ) + T1_Finalize_Parser( T1_Parser parser ) + { + FT_Memory memory = parser->root.memory; + + + /* always free the private dictionary */ + FT_FREE( parser->private_dict ); + + /* free the base dictionary only when we have a disk stream */ + if ( !parser->in_memory ) + FT_FREE( parser->base_dict ); + + parser->root.funcs.done( &parser->root ); + } + + + FT_LOCAL_DEF( FT_Error ) + T1_Get_Private_Dict( T1_Parser parser, + PSAux_Service psaux ) + { + FT_Stream stream = parser->stream; + FT_Memory memory = parser->root.memory; + FT_Error error = T1_Err_Ok; + FT_ULong size; + + + if ( parser->in_pfb ) + { + /* in the case of the PFB format, the private dictionary can be */ + /* made of several segments. We thus first read the number of */ + /* segments to compute the total size of the private dictionary */ + /* then re-read them into memory. */ + FT_Long start_pos = FT_STREAM_POS(); + FT_UShort tag; + + + parser->private_len = 0; + for (;;) + { + error = read_pfb_tag( stream, &tag, &size ); + if ( error ) + goto Fail; + + if ( tag != 0x8002U ) + break; + + parser->private_len += size; + + if ( FT_STREAM_SKIP( size ) ) + goto Fail; + } + + /* Check that we have a private dictionary there */ + /* and allocate private dictionary buffer */ + if ( parser->private_len == 0 ) + { + FT_ERROR(( "T1_Get_Private_Dict:" + " invalid private dictionary section\n" )); + error = T1_Err_Invalid_File_Format; + goto Fail; + } + + if ( FT_STREAM_SEEK( start_pos ) || + FT_ALLOC( parser->private_dict, parser->private_len ) ) + goto Fail; + + parser->private_len = 0; + for (;;) + { + error = read_pfb_tag( stream, &tag, &size ); + if ( error || tag != 0x8002U ) + { + error = T1_Err_Ok; + break; + } + + if ( FT_STREAM_READ( parser->private_dict + parser->private_len, + size ) ) + goto Fail; + + parser->private_len += size; + } + } + else + { + /* We have already `loaded' the whole PFA font file into memory; */ + /* if this is a memory resource, allocate a new block to hold */ + /* the private dict. Otherwise, simply overwrite into the base */ + /* dictionary block in the heap. */ + + /* first of all, look at the `eexec' keyword */ + FT_Byte* cur = parser->base_dict; + FT_Byte* limit = cur + parser->base_len; + FT_Byte c; + + + Again: + for (;;) + { + c = cur[0]; + if ( c == 'e' && cur + 9 < limit ) /* 9 = 5 letters for `eexec' + */ + /* newline + 4 chars */ + { + if ( cur[1] == 'e' && + cur[2] == 'x' && + cur[3] == 'e' && + cur[4] == 'c' ) + break; + } + cur++; + if ( cur >= limit ) + { + FT_ERROR(( "T1_Get_Private_Dict:" + " could not find `eexec' keyword\n" )); + error = T1_Err_Invalid_File_Format; + goto Exit; + } + } + + /* check whether `eexec' was real -- it could be in a comment */ + /* or string (as e.g. in u003043t.gsf from ghostscript) */ + + parser->root.cursor = parser->base_dict; + parser->root.limit = cur + 9; + + cur = parser->root.cursor; + limit = parser->root.limit; + + while ( cur < limit ) + { + if ( *cur == 'e' && ft_strncmp( (char*)cur, "eexec", 5 ) == 0 ) + goto Found; + + T1_Skip_PS_Token( parser ); + if ( parser->root.error ) + break; + T1_Skip_Spaces ( parser ); + cur = parser->root.cursor; + } + + /* we haven't found the correct `eexec'; go back and continue */ + /* searching */ + + cur = limit; + limit = parser->base_dict + parser->base_len; + goto Again; + + /* now determine where to write the _encrypted_ binary private */ + /* dictionary. We overwrite the base dictionary for disk-based */ + /* resources and allocate a new block otherwise */ + + Found: + parser->root.limit = parser->base_dict + parser->base_len; + + T1_Skip_PS_Token( parser ); + cur = parser->root.cursor; + if ( *cur == '\r' ) + { + cur++; + if ( *cur == '\n' ) + cur++; + } + else if ( *cur == '\n' ) + cur++; + else + { + FT_ERROR(( "T1_Get_Private_Dict:" + " `eexec' not properly terminated\n" )); + error = T1_Err_Invalid_File_Format; + goto Exit; + } + + size = parser->base_len - ( cur - parser->base_dict ); + + if ( parser->in_memory ) + { + /* note that we allocate one more byte to put a terminating `0' */ + if ( FT_ALLOC( parser->private_dict, size + 1 ) ) + goto Fail; + parser->private_len = size; + } + else + { + parser->single_block = 1; + parser->private_dict = parser->base_dict; + parser->private_len = size; + parser->base_dict = 0; + parser->base_len = 0; + } + + /* now determine whether the private dictionary is encoded in binary */ + /* or hexadecimal ASCII format -- decode it accordingly */ + + /* we need to access the next 4 bytes (after the final \r following */ + /* the `eexec' keyword); if they all are hexadecimal digits, then */ + /* we have a case of ASCII storage */ + + if ( ft_isxdigit( cur[0] ) && ft_isxdigit( cur[1] ) && + ft_isxdigit( cur[2] ) && ft_isxdigit( cur[3] ) ) + { + /* ASCII hexadecimal encoding */ + FT_Long len; + + + parser->root.cursor = cur; + (void)psaux->ps_parser_funcs->to_bytes( &parser->root, + parser->private_dict, + parser->private_len, + &len, + 0 ); + parser->private_len = len; + + /* put a safeguard */ + parser->private_dict[len] = '\0'; + } + else + /* binary encoding -- copy the private dict */ + FT_MEM_MOVE( parser->private_dict, cur, size ); + } + + /* we now decrypt the encoded binary private dictionary */ + psaux->t1_decrypt( parser->private_dict, parser->private_len, 55665U ); + + /* replace the four random bytes at the beginning with whitespace */ + parser->private_dict[0] = ' '; + parser->private_dict[1] = ' '; + parser->private_dict[2] = ' '; + parser->private_dict[3] = ' '; + + parser->root.base = parser->private_dict; + parser->root.cursor = parser->private_dict; + parser->root.limit = parser->root.cursor + parser->private_len; + + Fail: + Exit: + return error; + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/type1/t1parse.h b/mod/pub.mod/freetype.mod/src/type1/t1parse.h new file mode 100644 index 0000000..fb1c8a8 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/type1/t1parse.h @@ -0,0 +1,135 @@ +/***************************************************************************/ +/* */ +/* t1parse.h */ +/* */ +/* Type 1 parser (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __T1PARSE_H__ +#define __T1PARSE_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_TYPE1_TYPES_H +#include FT_INTERNAL_STREAM_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* T1_ParserRec */ + /* */ + /* <Description> */ + /* A PS_ParserRec is an object used to parse a Type 1 fonts very */ + /* quickly. */ + /* */ + /* <Fields> */ + /* root :: The root parser. */ + /* */ + /* stream :: The current input stream. */ + /* */ + /* base_dict :: A pointer to the top-level dictionary. */ + /* */ + /* base_len :: The length in bytes of the top dictionary. */ + /* */ + /* private_dict :: A pointer to the private dictionary. */ + /* */ + /* private_len :: The length in bytes of the private dictionary. */ + /* */ + /* in_pfb :: A boolean. Indicates that we are handling a PFB */ + /* file. */ + /* */ + /* in_memory :: A boolean. Indicates a memory-based stream. */ + /* */ + /* single_block :: A boolean. Indicates that the private dictionary */ + /* is stored in lieu of the base dictionary. */ + /* */ + typedef struct T1_ParserRec_ + { + PS_ParserRec root; + FT_Stream stream; + + FT_Byte* base_dict; + FT_ULong base_len; + + FT_Byte* private_dict; + FT_ULong private_len; + + FT_Bool in_pfb; + FT_Bool in_memory; + FT_Bool single_block; + + } T1_ParserRec, *T1_Parser; + + +#define T1_Add_Table( p, i, o, l ) (p)->funcs.add( (p), i, o, l ) +#define T1_Done_Table( p ) \ + do \ + { \ + if ( (p)->funcs.done ) \ + (p)->funcs.done( p ); \ + } while ( 0 ) +#define T1_Release_Table( p ) \ + do \ + { \ + if ( (p)->funcs.release ) \ + (p)->funcs.release( p ); \ + } while ( 0 ) + + +#define T1_Skip_Spaces( p ) (p)->root.funcs.skip_spaces( &(p)->root ) +#define T1_Skip_PS_Token( p ) (p)->root.funcs.skip_PS_token( &(p)->root ) + +#define T1_ToInt( p ) (p)->root.funcs.to_int( &(p)->root ) +#define T1_ToFixed( p, t ) (p)->root.funcs.to_fixed( &(p)->root, t ) + +#define T1_ToCoordArray( p, m, c ) \ + (p)->root.funcs.to_coord_array( &(p)->root, m, c ) +#define T1_ToFixedArray( p, m, f, t ) \ + (p)->root.funcs.to_fixed_array( &(p)->root, m, f, t ) +#define T1_ToToken( p, t ) \ + (p)->root.funcs.to_token( &(p)->root, t ) +#define T1_ToTokenArray( p, t, m, c ) \ + (p)->root.funcs.to_token_array( &(p)->root, t, m, c ) + +#define T1_Load_Field( p, f, o, m, pf ) \ + (p)->root.funcs.load_field( &(p)->root, f, o, m, pf ) + +#define T1_Load_Field_Table( p, f, o, m, pf ) \ + (p)->root.funcs.load_field_table( &(p)->root, f, o, m, pf ) + + + FT_LOCAL( FT_Error ) + T1_New_Parser( T1_Parser parser, + FT_Stream stream, + FT_Memory memory, + PSAux_Service psaux ); + + FT_LOCAL( FT_Error ) + T1_Get_Private_Dict( T1_Parser parser, + PSAux_Service psaux ); + + FT_LOCAL( void ) + T1_Finalize_Parser( T1_Parser parser ); + + +FT_END_HEADER + +#endif /* __T1PARSE_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/type1/t1tokens.h b/mod/pub.mod/freetype.mod/src/type1/t1tokens.h new file mode 100644 index 0000000..2d692f0 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/type1/t1tokens.h @@ -0,0 +1,143 @@ +/***************************************************************************/ +/* */ +/* t1tokens.h */ +/* */ +/* Type 1 tokenizer (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#undef FT_STRUCTURE +#define FT_STRUCTURE PS_FontInfoRec +#undef T1CODE +#define T1CODE T1_FIELD_LOCATION_FONT_INFO + + T1_FIELD_STRING( "version", version, + T1_FIELD_DICT_FONTDICT ) + T1_FIELD_STRING( "Notice", notice, + T1_FIELD_DICT_FONTDICT ) + T1_FIELD_STRING( "FullName", full_name, + T1_FIELD_DICT_FONTDICT ) + T1_FIELD_STRING( "FamilyName", family_name, + T1_FIELD_DICT_FONTDICT ) + T1_FIELD_STRING( "Weight", weight, + T1_FIELD_DICT_FONTDICT ) + + /* we use pointers to detect modifications made by synthetic fonts */ + T1_FIELD_NUM ( "ItalicAngle", italic_angle, + T1_FIELD_DICT_FONTDICT ) + T1_FIELD_BOOL ( "isFixedPitch", is_fixed_pitch, + T1_FIELD_DICT_FONTDICT ) + T1_FIELD_NUM ( "UnderlinePosition", underline_position, + T1_FIELD_DICT_FONTDICT ) + T1_FIELD_NUM ( "UnderlineThickness", underline_thickness, + T1_FIELD_DICT_FONTDICT ) + +#undef FT_STRUCTURE +#define FT_STRUCTURE PS_FontExtraRec +#undef T1CODE +#define T1CODE T1_FIELD_LOCATION_FONT_EXTRA + + T1_FIELD_NUM ( "FSType", fs_type, + T1_FIELD_DICT_FONTDICT ) + +#undef FT_STRUCTURE +#define FT_STRUCTURE PS_PrivateRec +#undef T1CODE +#define T1CODE T1_FIELD_LOCATION_PRIVATE + + T1_FIELD_NUM ( "UniqueID", unique_id, + T1_FIELD_DICT_FONTDICT | T1_FIELD_DICT_PRIVATE ) + T1_FIELD_NUM ( "lenIV", lenIV, + T1_FIELD_DICT_PRIVATE ) + T1_FIELD_NUM ( "LanguageGroup", language_group, + T1_FIELD_DICT_PRIVATE ) + T1_FIELD_NUM ( "password", password, + T1_FIELD_DICT_PRIVATE ) + + T1_FIELD_FIXED_1000( "BlueScale", blue_scale, + T1_FIELD_DICT_PRIVATE ) + T1_FIELD_NUM ( "BlueShift", blue_shift, + T1_FIELD_DICT_PRIVATE ) + T1_FIELD_NUM ( "BlueFuzz", blue_fuzz, + T1_FIELD_DICT_PRIVATE ) + + T1_FIELD_NUM_TABLE ( "BlueValues", blue_values, 14, + T1_FIELD_DICT_PRIVATE ) + T1_FIELD_NUM_TABLE ( "OtherBlues", other_blues, 10, + T1_FIELD_DICT_PRIVATE ) + T1_FIELD_NUM_TABLE ( "FamilyBlues", family_blues, 14, + T1_FIELD_DICT_PRIVATE ) + T1_FIELD_NUM_TABLE ( "FamilyOtherBlues", family_other_blues, 10, + T1_FIELD_DICT_PRIVATE ) + + T1_FIELD_NUM_TABLE2( "StdHW", standard_width, 1, + T1_FIELD_DICT_PRIVATE ) + T1_FIELD_NUM_TABLE2( "StdVW", standard_height, 1, + T1_FIELD_DICT_PRIVATE ) + T1_FIELD_NUM_TABLE2( "MinFeature", min_feature, 2, + T1_FIELD_DICT_PRIVATE ) + + T1_FIELD_NUM_TABLE ( "StemSnapH", snap_widths, 12, + T1_FIELD_DICT_PRIVATE ) + T1_FIELD_NUM_TABLE ( "StemSnapV", snap_heights, 12, + T1_FIELD_DICT_PRIVATE ) + + T1_FIELD_FIXED ( "ExpansionFactor", expansion_factor, + T1_FIELD_DICT_PRIVATE ) + T1_FIELD_BOOL ( "ForceBold", force_bold, + T1_FIELD_DICT_PRIVATE ) + + +#undef FT_STRUCTURE +#define FT_STRUCTURE T1_FontRec +#undef T1CODE +#define T1CODE T1_FIELD_LOCATION_FONT_DICT + + T1_FIELD_KEY ( "FontName", font_name, T1_FIELD_DICT_FONTDICT ) + T1_FIELD_NUM ( "PaintType", paint_type, T1_FIELD_DICT_FONTDICT ) + T1_FIELD_NUM ( "FontType", font_type, T1_FIELD_DICT_FONTDICT ) + T1_FIELD_FIXED( "StrokeWidth", stroke_width, T1_FIELD_DICT_FONTDICT ) + + +#undef FT_STRUCTURE +#define FT_STRUCTURE FT_BBox +#undef T1CODE +#define T1CODE T1_FIELD_LOCATION_BBOX + + T1_FIELD_BBOX( "FontBBox", xMin, T1_FIELD_DICT_FONTDICT ) + + +#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT + +#undef FT_STRUCTURE +#define FT_STRUCTURE T1_FaceRec +#undef T1CODE +#define T1CODE T1_FIELD_LOCATION_FACE + + T1_FIELD_NUM( "NDV", ndv_idx, T1_FIELD_DICT_PRIVATE ) + T1_FIELD_NUM( "CDV", cdv_idx, T1_FIELD_DICT_PRIVATE ) + + +#undef FT_STRUCTURE +#define FT_STRUCTURE PS_BlendRec +#undef T1CODE +#define T1CODE T1_FIELD_LOCATION_BLEND + + T1_FIELD_NUM_TABLE( "DesignVector", default_design_vector, + T1_MAX_MM_DESIGNS, T1_FIELD_DICT_FONTDICT ) + + +#endif /* T1_CONFIG_OPTION_NO_MM_SUPPORT */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/type1/type1.c b/mod/pub.mod/freetype.mod/src/type1/type1.c new file mode 100644 index 0000000..ccc12be --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/type1/type1.c @@ -0,0 +1,33 @@ +/***************************************************************************/ +/* */ +/* type1.c */ +/* */ +/* FreeType Type 1 driver component (body only). */ +/* */ +/* Copyright 1996-2001 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#define FT_MAKE_OPTION_SINGLE_OBJECT + +#include <ft2build.h> +#include "t1parse.c" +#include "t1load.c" +#include "t1objs.c" +#include "t1driver.c" +#include "t1gload.c" + +#ifndef T1_CONFIG_OPTION_NO_AFM +#include "t1afm.c" +#endif + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/type42/t42drivr.c b/mod/pub.mod/freetype.mod/src/type42/t42drivr.c new file mode 100644 index 0000000..820c679 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/type42/t42drivr.c @@ -0,0 +1,246 @@ +/***************************************************************************/ +/* */ +/* t42drivr.c */ +/* */ +/* High-level Type 42 driver interface (body). */ +/* */ +/* Copyright 2002, 2003, 2004, 2006, 2007, 2009 by Roberto Alameda. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This driver implements Type42 fonts as described in the */ + /* Technical Note #5012 from Adobe, with these limitations: */ + /* */ + /* 1) CID Fonts are not currently supported. */ + /* 2) Incremental fonts making use of the GlyphDirectory keyword */ + /* will be loaded, but the rendering will be using the TrueType */ + /* tables. */ + /* 3) As for Type1 fonts, CDevProc is not supported. */ + /* 4) The Metrics dictionary is not supported. */ + /* 5) AFM metrics are not supported. */ + /* */ + /* In other words, this driver supports Type42 fonts derived from */ + /* TrueType fonts in a non-CID manner, as done by usual conversion */ + /* programs. */ + /* */ + /*************************************************************************/ + + +#include "t42drivr.h" +#include "t42objs.h" +#include "t42error.h" +#include FT_INTERNAL_DEBUG_H + +#include FT_SERVICE_XFREE86_NAME_H +#include FT_SERVICE_GLYPH_DICT_H +#include FT_SERVICE_POSTSCRIPT_NAME_H +#include FT_SERVICE_POSTSCRIPT_INFO_H + +#undef FT_COMPONENT +#define FT_COMPONENT trace_t42 + + + /* + * + * GLYPH DICT SERVICE + * + */ + + static FT_Error + t42_get_glyph_name( T42_Face face, + FT_UInt glyph_index, + FT_Pointer buffer, + FT_UInt buffer_max ) + { + FT_STRCPYN( buffer, face->type1.glyph_names[glyph_index], buffer_max ); + + return T42_Err_Ok; + } + + + static FT_UInt + t42_get_name_index( T42_Face face, + FT_String* glyph_name ) + { + FT_Int i; + FT_String* gname; + + + for ( i = 0; i < face->type1.num_glyphs; i++ ) + { + gname = face->type1.glyph_names[i]; + + if ( glyph_name[0] == gname[0] && !ft_strcmp( glyph_name, gname ) ) + return (FT_UInt)ft_atol( (const char *)face->type1.charstrings[i] ); + } + + return 0; + } + + + static const FT_Service_GlyphDictRec t42_service_glyph_dict = + { + (FT_GlyphDict_GetNameFunc) t42_get_glyph_name, + (FT_GlyphDict_NameIndexFunc)t42_get_name_index + }; + + + /* + * + * POSTSCRIPT NAME SERVICE + * + */ + + static const char* + t42_get_ps_font_name( T42_Face face ) + { + return (const char*)face->type1.font_name; + } + + + static const FT_Service_PsFontNameRec t42_service_ps_font_name = + { + (FT_PsName_GetFunc)t42_get_ps_font_name + }; + + + /* + * + * POSTSCRIPT INFO SERVICE + * + */ + + static FT_Error + t42_ps_get_font_info( FT_Face face, + PS_FontInfoRec* afont_info ) + { + *afont_info = ((T42_Face)face)->type1.font_info; + + return T42_Err_Ok; + } + + + static FT_Error + t42_ps_get_font_extra( FT_Face face, + PS_FontExtraRec* afont_extra ) + { + *afont_extra = ((T42_Face)face)->type1.font_extra; + + return T42_Err_Ok; + } + + + static FT_Int + t42_ps_has_glyph_names( FT_Face face ) + { + FT_UNUSED( face ); + + return 1; + } + + + static FT_Error + t42_ps_get_font_private( FT_Face face, + PS_PrivateRec* afont_private ) + { + *afont_private = ((T42_Face)face)->type1.private_dict; + + return T42_Err_Ok; + } + + + static const FT_Service_PsInfoRec t42_service_ps_info = + { + (PS_GetFontInfoFunc) t42_ps_get_font_info, + (PS_GetFontExtraFunc) t42_ps_get_font_extra, + (PS_HasGlyphNamesFunc) t42_ps_has_glyph_names, + (PS_GetFontPrivateFunc)t42_ps_get_font_private + }; + + + /* + * + * SERVICE LIST + * + */ + + static const FT_ServiceDescRec t42_services[] = + { + { FT_SERVICE_ID_GLYPH_DICT, &t42_service_glyph_dict }, + { FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &t42_service_ps_font_name }, + { FT_SERVICE_ID_POSTSCRIPT_INFO, &t42_service_ps_info }, + { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_TYPE_42 }, + { NULL, NULL } + }; + + + static FT_Module_Interface + T42_Get_Interface( FT_Driver driver, + const FT_String* t42_interface ) + { + FT_UNUSED( driver ); + + return ft_service_list_lookup( t42_services, t42_interface ); + } + + + const FT_Driver_ClassRec t42_driver_class = + { + { + FT_MODULE_FONT_DRIVER | + FT_MODULE_DRIVER_SCALABLE | +#ifdef TT_USE_BYTECODE_INTERPRETER + FT_MODULE_DRIVER_HAS_HINTER, +#else + 0, +#endif + + sizeof ( T42_DriverRec ), + + "type42", + 0x10000L, + 0x20000L, + + 0, /* format interface */ + + (FT_Module_Constructor)T42_Driver_Init, + (FT_Module_Destructor) T42_Driver_Done, + (FT_Module_Requester) T42_Get_Interface, + }, + + sizeof ( T42_FaceRec ), + sizeof ( T42_SizeRec ), + sizeof ( T42_GlyphSlotRec ), + + (FT_Face_InitFunc) T42_Face_Init, + (FT_Face_DoneFunc) T42_Face_Done, + (FT_Size_InitFunc) T42_Size_Init, + (FT_Size_DoneFunc) T42_Size_Done, + (FT_Slot_InitFunc) T42_GlyphSlot_Init, + (FT_Slot_DoneFunc) T42_GlyphSlot_Done, + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + ft_stub_set_char_sizes, + ft_stub_set_pixel_sizes, +#endif + (FT_Slot_LoadFunc) T42_GlyphSlot_Load, + + (FT_Face_GetKerningFunc) 0, + (FT_Face_AttachFunc) 0, + + (FT_Face_GetAdvancesFunc) 0, + (FT_Size_RequestFunc) T42_Size_Request, + (FT_Size_SelectFunc) T42_Size_Select + }; + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/type42/t42drivr.h b/mod/pub.mod/freetype.mod/src/type42/t42drivr.h new file mode 100644 index 0000000..4717e46 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/type42/t42drivr.h @@ -0,0 +1,42 @@ +/***************************************************************************/ +/* */ +/* t42drivr.h */ +/* */ +/* High-level Type 42 driver interface (specification). */ +/* */ +/* Copyright 2002 by Roberto Alameda. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __T42DRIVR_H__ +#define __T42DRIVR_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_DRIVER_H + + +FT_BEGIN_HEADER + +#ifdef FT_CONFIG_OPTION_PIC +#error "this module does not support PIC yet" +#endif + + + FT_EXPORT_VAR( const FT_Driver_ClassRec ) t42_driver_class; + + +FT_END_HEADER + + +#endif /* __T42DRIVR_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/type42/t42error.h b/mod/pub.mod/freetype.mod/src/type42/t42error.h new file mode 100644 index 0000000..b230910 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/type42/t42error.h @@ -0,0 +1,40 @@ +/***************************************************************************/ +/* */ +/* t42error.h */ +/* */ +/* Type 42 error codes (specification only). */ +/* */ +/* Copyright 2002, 2003 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file is used to define the Type 42 error enumeration constants. */ + /* */ + /*************************************************************************/ + +#ifndef __T42ERROR_H__ +#define __T42ERROR_H__ + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#define FT_ERR_PREFIX T42_Err_ +#define FT_ERR_BASE FT_Mod_Err_Type42 + +#include FT_ERRORS_H + +#endif /* __T42ERROR_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/type42/t42objs.c b/mod/pub.mod/freetype.mod/src/type42/t42objs.c new file mode 100644 index 0000000..9081ffc --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/type42/t42objs.c @@ -0,0 +1,648 @@ +/***************************************************************************/ +/* */ +/* t42objs.c */ +/* */ +/* Type 42 objects manager (body). */ +/* */ +/* Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 */ +/* by Roberto Alameda. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include "t42objs.h" +#include "t42parse.h" +#include "t42error.h" +#include FT_INTERNAL_DEBUG_H +#include FT_LIST_H + + +#undef FT_COMPONENT +#define FT_COMPONENT trace_t42 + + + static FT_Error + T42_Open_Face( T42_Face face ) + { + T42_LoaderRec loader; + T42_Parser parser; + T1_Font type1 = &face->type1; + FT_Memory memory = face->root.memory; + FT_Error error; + + PSAux_Service psaux = (PSAux_Service)face->psaux; + + + t42_loader_init( &loader, face ); + + parser = &loader.parser; + + if ( FT_ALLOC( face->ttf_data, 12 ) ) + goto Exit; + + error = t42_parser_init( parser, + face->root.stream, + memory, + psaux); + if ( error ) + goto Exit; + + error = t42_parse_dict( face, &loader, + parser->base_dict, parser->base_len ); + if ( error ) + goto Exit; + + if ( type1->font_type != 42 ) + { + error = T42_Err_Unknown_File_Format; + goto Exit; + } + + /* now, propagate the charstrings and glyphnames tables */ + /* to the Type1 data */ + type1->num_glyphs = loader.num_glyphs; + + if ( !loader.charstrings.init ) + { + FT_ERROR(( "T42_Open_Face: no charstrings array in face\n" )); + error = T42_Err_Invalid_File_Format; + } + + loader.charstrings.init = 0; + type1->charstrings_block = loader.charstrings.block; + type1->charstrings = loader.charstrings.elements; + type1->charstrings_len = loader.charstrings.lengths; + + /* we copy the glyph names `block' and `elements' fields; */ + /* the `lengths' field must be released later */ + type1->glyph_names_block = loader.glyph_names.block; + type1->glyph_names = (FT_String**)loader.glyph_names.elements; + loader.glyph_names.block = 0; + loader.glyph_names.elements = 0; + + /* we must now build type1.encoding when we have a custom array */ + if ( type1->encoding_type == T1_ENCODING_TYPE_ARRAY ) + { + FT_Int charcode, idx, min_char, max_char; + FT_Byte* char_name; + FT_Byte* glyph_name; + + + /* OK, we do the following: for each element in the encoding */ + /* table, look up the index of the glyph having the same name */ + /* as defined in the CharStrings array. */ + /* The index is then stored in type1.encoding.char_index, and */ + /* the name in type1.encoding.char_name */ + + min_char = 0; + max_char = 0; + + charcode = 0; + for ( ; charcode < loader.encoding_table.max_elems; charcode++ ) + { + type1->encoding.char_index[charcode] = 0; + type1->encoding.char_name [charcode] = (char *)".notdef"; + + char_name = loader.encoding_table.elements[charcode]; + if ( char_name ) + for ( idx = 0; idx < type1->num_glyphs; idx++ ) + { + glyph_name = (FT_Byte*)type1->glyph_names[idx]; + if ( ft_strcmp( (const char*)char_name, + (const char*)glyph_name ) == 0 ) + { + type1->encoding.char_index[charcode] = (FT_UShort)idx; + type1->encoding.char_name [charcode] = (char*)glyph_name; + + /* Change min/max encoded char only if glyph name is */ + /* not /.notdef */ + if ( ft_strcmp( (const char*)".notdef", + (const char*)glyph_name ) != 0 ) + { + if ( charcode < min_char ) + min_char = charcode; + if ( charcode >= max_char ) + max_char = charcode + 1; + } + break; + } + } + } + + type1->encoding.code_first = min_char; + type1->encoding.code_last = max_char; + type1->encoding.num_chars = loader.num_chars; + } + + Exit: + t42_loader_done( &loader ); + return error; + } + + + /***************** Driver Functions *************/ + + + FT_LOCAL_DEF( FT_Error ) + T42_Face_Init( FT_Stream stream, + T42_Face face, + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ) + { + FT_Error error; + FT_Service_PsCMaps psnames; + PSAux_Service psaux; + FT_Face root = (FT_Face)&face->root; + T1_Font type1 = &face->type1; + PS_FontInfo info = &type1->font_info; + + FT_UNUSED( num_params ); + FT_UNUSED( params ); + FT_UNUSED( face_index ); + FT_UNUSED( stream ); + + + face->ttf_face = NULL; + face->root.num_faces = 1; + + FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); + face->psnames = psnames; + + face->psaux = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ), + "psaux" ); + psaux = (PSAux_Service)face->psaux; + + /* open the tokenizer, this will also check the font format */ + error = T42_Open_Face( face ); + if ( error ) + goto Exit; + + /* if we just wanted to check the format, leave successfully now */ + if ( face_index < 0 ) + goto Exit; + + /* check the face index */ + if ( face_index > 0 ) + { + FT_ERROR(( "T42_Face_Init: invalid face index\n" )); + error = T42_Err_Invalid_Argument; + goto Exit; + } + + /* Now load the font program into the face object */ + + /* Init the face object fields */ + /* Now set up root face fields */ + + root->num_glyphs = type1->num_glyphs; + root->num_charmaps = 0; + root->face_index = 0; + + root->face_flags = FT_FACE_FLAG_SCALABLE | + FT_FACE_FLAG_HORIZONTAL | + FT_FACE_FLAG_GLYPH_NAMES; + + if ( info->is_fixed_pitch ) + root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; + + /* We only set this flag if we have the patented bytecode interpreter. */ + /* There are no known `tricky' Type42 fonts that could be loaded with */ + /* the unpatented interpreter. */ +#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER + root->face_flags |= FT_FACE_FLAG_HINTER; +#endif + + /* XXX: TODO -- add kerning with .afm support */ + + /* get style name -- be careful, some broken fonts only */ + /* have a `/FontName' dictionary entry! */ + root->family_name = info->family_name; + /* assume "Regular" style if we don't know better */ + root->style_name = (char *)"Regular"; + if ( root->family_name ) + { + char* full = info->full_name; + char* family = root->family_name; + + + if ( full ) + { + while ( *full ) + { + if ( *full == *family ) + { + family++; + full++; + } + else + { + if ( *full == ' ' || *full == '-' ) + full++; + else if ( *family == ' ' || *family == '-' ) + family++; + else + { + if ( !*family ) + root->style_name = full; + break; + } + } + } + } + } + else + { + /* do we have a `/FontName'? */ + if ( type1->font_name ) + root->family_name = type1->font_name; + } + + /* no embedded bitmap support */ + root->num_fixed_sizes = 0; + root->available_sizes = 0; + + /* Load the TTF font embedded in the T42 font */ + { + FT_Open_Args args; + + + args.flags = FT_OPEN_MEMORY; + args.memory_base = face->ttf_data; + args.memory_size = face->ttf_size; + + if ( num_params ) + { + args.flags |= FT_OPEN_PARAMS; + args.num_params = num_params; + args.params = params; + } + + error = FT_Open_Face( FT_FACE_LIBRARY( face ), + &args, 0, &face->ttf_face ); + } + + if ( error ) + goto Exit; + + FT_Done_Size( face->ttf_face->size ); + + /* Ignore info in FontInfo dictionary and use the info from the */ + /* loaded TTF font. The PostScript interpreter also ignores it. */ + root->bbox = face->ttf_face->bbox; + root->units_per_EM = face->ttf_face->units_per_EM; + + root->ascender = face->ttf_face->ascender; + root->descender = face->ttf_face->descender; + root->height = face->ttf_face->height; + + root->max_advance_width = face->ttf_face->max_advance_width; + root->max_advance_height = face->ttf_face->max_advance_height; + + root->underline_position = (FT_Short)info->underline_position; + root->underline_thickness = (FT_Short)info->underline_thickness; + + /* compute style flags */ + root->style_flags = 0; + if ( info->italic_angle ) + root->style_flags |= FT_STYLE_FLAG_ITALIC; + + if ( face->ttf_face->style_flags & FT_STYLE_FLAG_BOLD ) + root->style_flags |= FT_STYLE_FLAG_BOLD; + + if ( face->ttf_face->face_flags & FT_FACE_FLAG_VERTICAL ) + root->face_flags |= FT_FACE_FLAG_VERTICAL; + + { + if ( psnames && psaux ) + { + FT_CharMapRec charmap; + T1_CMap_Classes cmap_classes = psaux->t1_cmap_classes; + FT_CMap_Class clazz; + + + charmap.face = root; + + /* first of all, try to synthesize a Unicode charmap */ + charmap.platform_id = 3; + charmap.encoding_id = 1; + charmap.encoding = FT_ENCODING_UNICODE; + + FT_CMap_New( cmap_classes->unicode, NULL, &charmap, NULL ); + + /* now, generate an Adobe Standard encoding when appropriate */ + charmap.platform_id = 7; + clazz = NULL; + + switch ( type1->encoding_type ) + { + case T1_ENCODING_TYPE_STANDARD: + charmap.encoding = FT_ENCODING_ADOBE_STANDARD; + charmap.encoding_id = 0; + clazz = cmap_classes->standard; + break; + + case T1_ENCODING_TYPE_EXPERT: + charmap.encoding = FT_ENCODING_ADOBE_EXPERT; + charmap.encoding_id = 1; + clazz = cmap_classes->expert; + break; + + case T1_ENCODING_TYPE_ARRAY: + charmap.encoding = FT_ENCODING_ADOBE_CUSTOM; + charmap.encoding_id = 2; + clazz = cmap_classes->custom; + break; + + case T1_ENCODING_TYPE_ISOLATIN1: + charmap.encoding = FT_ENCODING_ADOBE_LATIN_1; + charmap.encoding_id = 3; + clazz = cmap_classes->unicode; + break; + + default: + ; + } + + if ( clazz ) + FT_CMap_New( clazz, NULL, &charmap, NULL ); + +#if 0 + /* Select default charmap */ + if ( root->num_charmaps ) + root->charmap = root->charmaps[0]; +#endif + } + } + Exit: + return error; + } + + + FT_LOCAL_DEF( void ) + T42_Face_Done( T42_Face face ) + { + T1_Font type1; + PS_FontInfo info; + FT_Memory memory; + + + if ( !face ) + return; + + type1 = &face->type1; + info = &type1->font_info; + memory = face->root.memory; + + /* delete internal ttf face prior to freeing face->ttf_data */ + if ( face->ttf_face ) + FT_Done_Face( face->ttf_face ); + + /* release font info strings */ + FT_FREE( info->version ); + FT_FREE( info->notice ); + FT_FREE( info->full_name ); + FT_FREE( info->family_name ); + FT_FREE( info->weight ); + + /* release top dictionary */ + FT_FREE( type1->charstrings_len ); + FT_FREE( type1->charstrings ); + FT_FREE( type1->glyph_names ); + + FT_FREE( type1->charstrings_block ); + FT_FREE( type1->glyph_names_block ); + + FT_FREE( type1->encoding.char_index ); + FT_FREE( type1->encoding.char_name ); + FT_FREE( type1->font_name ); + + FT_FREE( face->ttf_data ); + +#if 0 + /* release afm data if present */ + if ( face->afm_data ) + T1_Done_AFM( memory, (T1_AFM*)face->afm_data ); +#endif + + /* release unicode map, if any */ + FT_FREE( face->unicode_map.maps ); + face->unicode_map.num_maps = 0; + + face->root.family_name = 0; + face->root.style_name = 0; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* T42_Driver_Init */ + /* */ + /* <Description> */ + /* Initializes a given Type 42 driver object. */ + /* */ + /* <Input> */ + /* driver :: A handle to the target driver object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + T42_Driver_Init( T42_Driver driver ) + { + FT_Module ttmodule; + + + ttmodule = FT_Get_Module( FT_MODULE(driver)->library, "truetype" ); + driver->ttclazz = (FT_Driver_Class)ttmodule->clazz; + + return T42_Err_Ok; + } + + + FT_LOCAL_DEF( void ) + T42_Driver_Done( T42_Driver driver ) + { + FT_UNUSED( driver ); + } + + + FT_LOCAL_DEF( FT_Error ) + T42_Size_Init( T42_Size size ) + { + FT_Face face = size->root.face; + T42_Face t42face = (T42_Face)face; + FT_Size ttsize; + FT_Error error = T42_Err_Ok; + + + error = FT_New_Size( t42face->ttf_face, &ttsize ); + size->ttsize = ttsize; + + FT_Activate_Size( ttsize ); + + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + T42_Size_Request( T42_Size size, + FT_Size_Request req ) + { + T42_Face face = (T42_Face)size->root.face; + FT_Error error; + + + FT_Activate_Size( size->ttsize ); + + error = FT_Request_Size( face->ttf_face, req ); + if ( !error ) + ( (FT_Size)size )->metrics = face->ttf_face->size->metrics; + + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + T42_Size_Select( T42_Size size, + FT_ULong strike_index ) + { + T42_Face face = (T42_Face)size->root.face; + FT_Error error; + + + FT_Activate_Size( size->ttsize ); + + error = FT_Select_Size( face->ttf_face, (FT_Int)strike_index ); + if ( !error ) + ( (FT_Size)size )->metrics = face->ttf_face->size->metrics; + + return error; + + } + + + FT_LOCAL_DEF( void ) + T42_Size_Done( T42_Size size ) + { + FT_Face face = size->root.face; + T42_Face t42face = (T42_Face)face; + FT_ListNode node; + + + node = FT_List_Find( &t42face->ttf_face->sizes_list, size->ttsize ); + if ( node ) + { + FT_Done_Size( size->ttsize ); + size->ttsize = NULL; + } + } + + + FT_LOCAL_DEF( FT_Error ) + T42_GlyphSlot_Init( T42_GlyphSlot slot ) + { + FT_Face face = slot->root.face; + T42_Face t42face = (T42_Face)face; + FT_GlyphSlot ttslot; + FT_Error error = T42_Err_Ok; + + + if ( face->glyph == NULL ) + { + /* First glyph slot for this face */ + slot->ttslot = t42face->ttf_face->glyph; + } + else + { + error = FT_New_GlyphSlot( t42face->ttf_face, &ttslot ); + slot->ttslot = ttslot; + } + + return error; + } + + + FT_LOCAL_DEF( void ) + T42_GlyphSlot_Done( T42_GlyphSlot slot ) + { + FT_Done_GlyphSlot( slot->ttslot ); + } + + + static void + t42_glyphslot_clear( FT_GlyphSlot slot ) + { + /* free bitmap if needed */ + ft_glyphslot_free_bitmap( slot ); + + /* clear all public fields in the glyph slot */ + FT_ZERO( &slot->metrics ); + FT_ZERO( &slot->outline ); + FT_ZERO( &slot->bitmap ); + + slot->bitmap_left = 0; + slot->bitmap_top = 0; + slot->num_subglyphs = 0; + slot->subglyphs = 0; + slot->control_data = 0; + slot->control_len = 0; + slot->other = 0; + slot->format = FT_GLYPH_FORMAT_NONE; + + slot->linearHoriAdvance = 0; + slot->linearVertAdvance = 0; + } + + + FT_LOCAL_DEF( FT_Error ) + T42_GlyphSlot_Load( FT_GlyphSlot glyph, + FT_Size size, + FT_UInt glyph_index, + FT_Int32 load_flags ) + { + FT_Error error; + T42_GlyphSlot t42slot = (T42_GlyphSlot)glyph; + T42_Size t42size = (T42_Size)size; + FT_Driver_Class ttclazz = ((T42_Driver)glyph->face->driver)->ttclazz; + + + t42_glyphslot_clear( t42slot->ttslot ); + error = ttclazz->load_glyph( t42slot->ttslot, + t42size->ttsize, + glyph_index, + load_flags | FT_LOAD_NO_BITMAP ); + + if ( !error ) + { + glyph->metrics = t42slot->ttslot->metrics; + + glyph->linearHoriAdvance = t42slot->ttslot->linearHoriAdvance; + glyph->linearVertAdvance = t42slot->ttslot->linearVertAdvance; + + glyph->format = t42slot->ttslot->format; + glyph->outline = t42slot->ttslot->outline; + + glyph->bitmap = t42slot->ttslot->bitmap; + glyph->bitmap_left = t42slot->ttslot->bitmap_left; + glyph->bitmap_top = t42slot->ttslot->bitmap_top; + + glyph->num_subglyphs = t42slot->ttslot->num_subglyphs; + glyph->subglyphs = t42slot->ttslot->subglyphs; + + glyph->control_data = t42slot->ttslot->control_data; + glyph->control_len = t42slot->ttslot->control_len; + } + + return error; + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/type42/t42objs.h b/mod/pub.mod/freetype.mod/src/type42/t42objs.h new file mode 100644 index 0000000..289dedc --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/type42/t42objs.h @@ -0,0 +1,124 @@ +/***************************************************************************/ +/* */ +/* t42objs.h */ +/* */ +/* Type 42 objects manager (specification). */ +/* */ +/* Copyright 2002, 2003, 2006, 2007 by Roberto Alameda. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __T42OBJS_H__ +#define __T42OBJS_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_TYPE1_TABLES_H +#include FT_INTERNAL_TYPE1_TYPES_H +#include "t42types.h" +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_DRIVER_H +#include FT_SERVICE_POSTSCRIPT_CMAPS_H +#include FT_INTERNAL_POSTSCRIPT_HINTS_H + + +FT_BEGIN_HEADER + + + /* Type42 size */ + typedef struct T42_SizeRec_ + { + FT_SizeRec root; + FT_Size ttsize; + + } T42_SizeRec, *T42_Size; + + + /* Type42 slot */ + typedef struct T42_GlyphSlotRec_ + { + FT_GlyphSlotRec root; + FT_GlyphSlot ttslot; + + } T42_GlyphSlotRec, *T42_GlyphSlot; + + + /* Type 42 driver */ + typedef struct T42_DriverRec_ + { + FT_DriverRec root; + FT_Driver_Class ttclazz; + void* extension_component; + + } T42_DriverRec, *T42_Driver; + + + /* */ + + + FT_LOCAL( FT_Error ) + T42_Face_Init( FT_Stream stream, + T42_Face face, + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ); + + + FT_LOCAL( void ) + T42_Face_Done( T42_Face face ); + + + FT_LOCAL( FT_Error ) + T42_Size_Init( T42_Size size ); + + + FT_LOCAL( FT_Error ) + T42_Size_Request( T42_Size size, + FT_Size_Request req ); + + + FT_LOCAL( FT_Error ) + T42_Size_Select( T42_Size size, + FT_ULong strike_index ); + + + FT_LOCAL( void ) + T42_Size_Done( T42_Size size ); + + + FT_LOCAL( FT_Error ) + T42_GlyphSlot_Init( T42_GlyphSlot slot ); + + + FT_LOCAL( FT_Error ) + T42_GlyphSlot_Load( FT_GlyphSlot glyph, + FT_Size size, + FT_UInt glyph_index, + FT_Int32 load_flags ); + + FT_LOCAL( void ) + T42_GlyphSlot_Done( T42_GlyphSlot slot ); + + + FT_LOCAL( FT_Error ) + T42_Driver_Init( T42_Driver driver ); + + FT_LOCAL( void ) + T42_Driver_Done( T42_Driver driver ); + + /* */ + +FT_END_HEADER + + +#endif /* __T42OBJS_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/type42/t42parse.c b/mod/pub.mod/freetype.mod/src/type42/t42parse.c new file mode 100644 index 0000000..13bda64 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/type42/t42parse.c @@ -0,0 +1,1178 @@ +/***************************************************************************/ +/* */ +/* t42parse.c */ +/* */ +/* Type 42 font parser (body). */ +/* */ +/* Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ +/* Roberto Alameda. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include "t42parse.h" +#include "t42error.h" +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_POSTSCRIPT_AUX_H + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_t42 + + + static void + t42_parse_font_matrix( T42_Face face, + T42_Loader loader ); + static void + t42_parse_encoding( T42_Face face, + T42_Loader loader ); + + static void + t42_parse_charstrings( T42_Face face, + T42_Loader loader ); + + static void + t42_parse_sfnts( T42_Face face, + T42_Loader loader ); + + + /* as Type42 fonts have no Private dict, */ + /* we set the last argument of T1_FIELD_XXX to 0 */ + static const + T1_FieldRec t42_keywords[] = { + +#undef FT_STRUCTURE +#define FT_STRUCTURE T1_FontInfo +#undef T1CODE +#define T1CODE T1_FIELD_LOCATION_FONT_INFO + + T1_FIELD_STRING( "version", version, 0 ) + T1_FIELD_STRING( "Notice", notice, 0 ) + T1_FIELD_STRING( "FullName", full_name, 0 ) + T1_FIELD_STRING( "FamilyName", family_name, 0 ) + T1_FIELD_STRING( "Weight", weight, 0 ) + T1_FIELD_NUM ( "ItalicAngle", italic_angle, 0 ) + T1_FIELD_BOOL ( "isFixedPitch", is_fixed_pitch, 0 ) + T1_FIELD_NUM ( "UnderlinePosition", underline_position, 0 ) + T1_FIELD_NUM ( "UnderlineThickness", underline_thickness, 0 ) + +#undef FT_STRUCTURE +#define FT_STRUCTURE PS_FontExtraRec +#undef T1CODE +#define T1CODE T1_FIELD_LOCATION_FONT_EXTRA + + T1_FIELD_NUM ( "FSType", fs_type, 0 ) + +#undef FT_STRUCTURE +#define FT_STRUCTURE T1_FontRec +#undef T1CODE +#define T1CODE T1_FIELD_LOCATION_FONT_DICT + + T1_FIELD_KEY ( "FontName", font_name, 0 ) + T1_FIELD_NUM ( "PaintType", paint_type, 0 ) + T1_FIELD_NUM ( "FontType", font_type, 0 ) + T1_FIELD_FIXED( "StrokeWidth", stroke_width, 0 ) + +#undef FT_STRUCTURE +#define FT_STRUCTURE FT_BBox +#undef T1CODE +#define T1CODE T1_FIELD_LOCATION_BBOX + + T1_FIELD_BBOX("FontBBox", xMin, 0 ) + + T1_FIELD_CALLBACK( "FontMatrix", t42_parse_font_matrix, 0 ) + T1_FIELD_CALLBACK( "Encoding", t42_parse_encoding, 0 ) + T1_FIELD_CALLBACK( "CharStrings", t42_parse_charstrings, 0 ) + T1_FIELD_CALLBACK( "sfnts", t42_parse_sfnts, 0 ) + + { 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_TYPE_NONE, 0, 0, 0, 0, 0, 0 } + }; + + +#define T1_Add_Table( p, i, o, l ) (p)->funcs.add( (p), i, o, l ) +#define T1_Done_Table( p ) \ + do \ + { \ + if ( (p)->funcs.done ) \ + (p)->funcs.done( p ); \ + } while ( 0 ) +#define T1_Release_Table( p ) \ + do \ + { \ + if ( (p)->funcs.release ) \ + (p)->funcs.release( p ); \ + } while ( 0 ) + +#define T1_Skip_Spaces( p ) (p)->root.funcs.skip_spaces( &(p)->root ) +#define T1_Skip_PS_Token( p ) (p)->root.funcs.skip_PS_token( &(p)->root ) + +#define T1_ToInt( p ) \ + (p)->root.funcs.to_int( &(p)->root ) +#define T1_ToBytes( p, b, m, n, d ) \ + (p)->root.funcs.to_bytes( &(p)->root, b, m, n, d ) + +#define T1_ToFixedArray( p, m, f, t ) \ + (p)->root.funcs.to_fixed_array( &(p)->root, m, f, t ) +#define T1_ToToken( p, t ) \ + (p)->root.funcs.to_token( &(p)->root, t ) + +#define T1_Load_Field( p, f, o, m, pf ) \ + (p)->root.funcs.load_field( &(p)->root, f, o, m, pf ) +#define T1_Load_Field_Table( p, f, o, m, pf ) \ + (p)->root.funcs.load_field_table( &(p)->root, f, o, m, pf ) + + + /********************* Parsing Functions ******************/ + + FT_LOCAL_DEF( FT_Error ) + t42_parser_init( T42_Parser parser, + FT_Stream stream, + FT_Memory memory, + PSAux_Service psaux ) + { + FT_Error error = T42_Err_Ok; + FT_Long size; + + + psaux->ps_parser_funcs->init( &parser->root, 0, 0, memory ); + + parser->stream = stream; + parser->base_len = 0; + parser->base_dict = 0; + parser->in_memory = 0; + + /*******************************************************************/ + /* */ + /* Here a short summary of what is going on: */ + /* */ + /* When creating a new Type 42 parser, we try to locate and load */ + /* the base dictionary, loading the whole font into memory. */ + /* */ + /* When `loading' the base dictionary, we only set up pointers */ + /* in the case of a memory-based stream. Otherwise, we allocate */ + /* and load the base dictionary in it. */ + /* */ + /* parser->in_memory is set if we have a memory stream. */ + /* */ + + if ( FT_STREAM_SEEK( 0L ) || + FT_FRAME_ENTER( 17 ) ) + goto Exit; + + if ( ft_memcmp( stream->cursor, "%!PS-TrueTypeFont", 17 ) != 0 ) + { + FT_TRACE2(( "not a Type42 font\n" )); + error = T42_Err_Unknown_File_Format; + } + + FT_FRAME_EXIT(); + + if ( error || FT_STREAM_SEEK( 0 ) ) + goto Exit; + + size = stream->size; + + /* now, try to load `size' bytes of the `base' dictionary we */ + /* found previously */ + + /* if it is a memory-based resource, set up pointers */ + if ( !stream->read ) + { + parser->base_dict = (FT_Byte*)stream->base + stream->pos; + parser->base_len = size; + parser->in_memory = 1; + + /* check that the `size' field is valid */ + if ( FT_STREAM_SKIP( size ) ) + goto Exit; + } + else + { + /* read segment in memory */ + if ( FT_ALLOC( parser->base_dict, size ) || + FT_STREAM_READ( parser->base_dict, size ) ) + goto Exit; + + parser->base_len = size; + } + + parser->root.base = parser->base_dict; + parser->root.cursor = parser->base_dict; + parser->root.limit = parser->root.cursor + parser->base_len; + + Exit: + if ( error && !parser->in_memory ) + FT_FREE( parser->base_dict ); + + return error; + } + + + FT_LOCAL_DEF( void ) + t42_parser_done( T42_Parser parser ) + { + FT_Memory memory = parser->root.memory; + + + /* free the base dictionary only when we have a disk stream */ + if ( !parser->in_memory ) + FT_FREE( parser->base_dict ); + + parser->root.funcs.done( &parser->root ); + } + + + static int + t42_is_space( FT_Byte c ) + { + return ( c == ' ' || c == '\t' || + c == '\r' || c == '\n' || c == '\f' || + c == '\0' ); + } + + + static void + t42_parse_font_matrix( T42_Face face, + T42_Loader loader ) + { + T42_Parser parser = &loader->parser; + FT_Matrix* matrix = &face->type1.font_matrix; + FT_Vector* offset = &face->type1.font_offset; + FT_Face root = (FT_Face)&face->root; + FT_Fixed temp[6]; + FT_Fixed temp_scale; + + + (void)T1_ToFixedArray( parser, 6, temp, 3 ); + + temp_scale = FT_ABS( temp[3] ); + + /* Set Units per EM based on FontMatrix values. We set the value to */ + /* 1000 / temp_scale, because temp_scale was already multiplied by */ + /* 1000 (in t1_tofixed, from psobjs.c). */ + + root->units_per_EM = (FT_UShort)( FT_DivFix( 1000 * 0x10000L, + temp_scale ) >> 16 ); + + /* we need to scale the values by 1.0/temp_scale */ + if ( temp_scale != 0x10000L ) { + temp[0] = FT_DivFix( temp[0], temp_scale ); + temp[1] = FT_DivFix( temp[1], temp_scale ); + temp[2] = FT_DivFix( temp[2], temp_scale ); + temp[4] = FT_DivFix( temp[4], temp_scale ); + temp[5] = FT_DivFix( temp[5], temp_scale ); + temp[3] = 0x10000L; + } + + matrix->xx = temp[0]; + matrix->yx = temp[1]; + matrix->xy = temp[2]; + matrix->yy = temp[3]; + + /* note that the offsets must be expressed in integer font units */ + offset->x = temp[4] >> 16; + offset->y = temp[5] >> 16; + } + + + static void + t42_parse_encoding( T42_Face face, + T42_Loader loader ) + { + T42_Parser parser = &loader->parser; + FT_Byte* cur; + FT_Byte* limit = parser->root.limit; + + PSAux_Service psaux = (PSAux_Service)face->psaux; + + + T1_Skip_Spaces( parser ); + cur = parser->root.cursor; + if ( cur >= limit ) + { + FT_ERROR(( "t42_parse_encoding: out of bounds\n" )); + parser->root.error = T42_Err_Invalid_File_Format; + return; + } + + /* if we have a number or `[', the encoding is an array, */ + /* and we must load it now */ + if ( ft_isdigit( *cur ) || *cur == '[' ) + { + T1_Encoding encode = &face->type1.encoding; + FT_UInt count, n; + PS_Table char_table = &loader->encoding_table; + FT_Memory memory = parser->root.memory; + FT_Error error; + FT_Bool only_immediates = 0; + + + /* read the number of entries in the encoding; should be 256 */ + if ( *cur == '[' ) + { + count = 256; + only_immediates = 1; + parser->root.cursor++; + } + else + count = (FT_UInt)T1_ToInt( parser ); + + T1_Skip_Spaces( parser ); + if ( parser->root.cursor >= limit ) + return; + + /* we use a T1_Table to store our charnames */ + loader->num_chars = encode->num_chars = count; + if ( FT_NEW_ARRAY( encode->char_index, count ) || + FT_NEW_ARRAY( encode->char_name, count ) || + FT_SET_ERROR( psaux->ps_table_funcs->init( + char_table, count, memory ) ) ) + { + parser->root.error = error; + return; + } + + /* We need to `zero' out encoding_table.elements */ + for ( n = 0; n < count; n++ ) + { + char* notdef = (char *)".notdef"; + + + T1_Add_Table( char_table, n, notdef, 8 ); + } + + /* Now we need to read records of the form */ + /* */ + /* ... charcode /charname ... */ + /* */ + /* for each entry in our table. */ + /* */ + /* We simply look for a number followed by an immediate */ + /* name. Note that this ignores correctly the sequence */ + /* that is often seen in type42 fonts: */ + /* */ + /* 0 1 255 { 1 index exch /.notdef put } for dup */ + /* */ + /* used to clean the encoding array before anything else. */ + /* */ + /* Alternatively, if the array is directly given as */ + /* */ + /* /Encoding [ ... ] */ + /* */ + /* we only read immediates. */ + + n = 0; + T1_Skip_Spaces( parser ); + + while ( parser->root.cursor < limit ) + { + cur = parser->root.cursor; + + /* we stop when we encounter `def' or `]' */ + if ( *cur == 'd' && cur + 3 < limit ) + { + if ( cur[1] == 'e' && + cur[2] == 'f' && + t42_is_space( cur[3] ) ) + { + FT_TRACE6(( "encoding end\n" )); + cur += 3; + break; + } + } + if ( *cur == ']' ) + { + FT_TRACE6(( "encoding end\n" )); + cur++; + break; + } + + /* check whether we have found an entry */ + if ( ft_isdigit( *cur ) || only_immediates ) + { + FT_Int charcode; + + + if ( only_immediates ) + charcode = n; + else + { + charcode = (FT_Int)T1_ToInt( parser ); + T1_Skip_Spaces( parser ); + } + + cur = parser->root.cursor; + + if ( *cur == '/' && cur + 2 < limit && n < count ) + { + FT_PtrDist len; + + + cur++; + + parser->root.cursor = cur; + T1_Skip_PS_Token( parser ); + if ( parser->root.error ) + return; + + len = parser->root.cursor - cur; + + parser->root.error = T1_Add_Table( char_table, charcode, + cur, len + 1 ); + if ( parser->root.error ) + return; + char_table->elements[charcode][len] = '\0'; + + n++; + } + } + else + { + T1_Skip_PS_Token( parser ); + if ( parser->root.error ) + return; + } + + T1_Skip_Spaces( parser ); + } + + face->type1.encoding_type = T1_ENCODING_TYPE_ARRAY; + parser->root.cursor = cur; + } + + /* Otherwise, we should have either `StandardEncoding', */ + /* `ExpertEncoding', or `ISOLatin1Encoding' */ + else + { + if ( cur + 17 < limit && + ft_strncmp( (const char*)cur, "StandardEncoding", 16 ) == 0 ) + face->type1.encoding_type = T1_ENCODING_TYPE_STANDARD; + + else if ( cur + 15 < limit && + ft_strncmp( (const char*)cur, "ExpertEncoding", 14 ) == 0 ) + face->type1.encoding_type = T1_ENCODING_TYPE_EXPERT; + + else if ( cur + 18 < limit && + ft_strncmp( (const char*)cur, "ISOLatin1Encoding", 17 ) == 0 ) + face->type1.encoding_type = T1_ENCODING_TYPE_ISOLATIN1; + + else + { + FT_ERROR(( "t42_parse_encoding: invalid token\n" )); + parser->root.error = T42_Err_Invalid_File_Format; + } + } + } + + + typedef enum T42_Load_Status_ + { + BEFORE_START, + BEFORE_TABLE_DIR, + OTHER_TABLES + + } T42_Load_Status; + + + static void + t42_parse_sfnts( T42_Face face, + T42_Loader loader ) + { + T42_Parser parser = &loader->parser; + FT_Memory memory = parser->root.memory; + FT_Byte* cur; + FT_Byte* limit = parser->root.limit; + FT_Error error; + FT_Int num_tables = 0; + FT_ULong count, ttf_size = 0; + + FT_Long n, string_size, old_string_size, real_size; + FT_Byte* string_buf = NULL; + FT_Bool allocated = 0; + + T42_Load_Status status; + + + /* The format is */ + /* */ + /* /sfnts [ <hexstring> <hexstring> ... ] def */ + /* */ + /* or */ + /* */ + /* /sfnts [ */ + /* <num_bin_bytes> RD <binary data> */ + /* <num_bin_bytes> RD <binary data> */ + /* ... */ + /* ] def */ + /* */ + /* with exactly one space after the `RD' token. */ + + T1_Skip_Spaces( parser ); + + if ( parser->root.cursor >= limit || *parser->root.cursor++ != '[' ) + { + FT_ERROR(( "t42_parse_sfnts: can't find begin of sfnts vector\n" )); + error = T42_Err_Invalid_File_Format; + goto Fail; + } + + T1_Skip_Spaces( parser ); + status = BEFORE_START; + string_size = 0; + old_string_size = 0; + count = 0; + + while ( parser->root.cursor < limit ) + { + cur = parser->root.cursor; + + if ( *cur == ']' ) + { + parser->root.cursor++; + goto Exit; + } + + else if ( *cur == '<' ) + { + T1_Skip_PS_Token( parser ); + if ( parser->root.error ) + goto Exit; + + /* don't include delimiters */ + string_size = (FT_Long)( ( parser->root.cursor - cur - 2 + 1 ) / 2 ); + if ( FT_REALLOC( string_buf, old_string_size, string_size ) ) + goto Fail; + + allocated = 1; + + parser->root.cursor = cur; + (void)T1_ToBytes( parser, string_buf, string_size, &real_size, 1 ); + old_string_size = string_size; + string_size = real_size; + } + + else if ( ft_isdigit( *cur ) ) + { + if ( allocated ) + { + FT_ERROR(( "t42_parse_sfnts: " + "can't handle mixed binary and hex strings\n" )); + error = T42_Err_Invalid_File_Format; + goto Fail; + } + + string_size = T1_ToInt( parser ); + + T1_Skip_PS_Token( parser ); /* `RD' */ + if ( parser->root.error ) + return; + + string_buf = parser->root.cursor + 1; /* one space after `RD' */ + + parser->root.cursor += string_size + 1; + if ( parser->root.cursor >= limit ) + { + FT_ERROR(( "t42_parse_sfnts: too many binary data\n" )); + error = T42_Err_Invalid_File_Format; + goto Fail; + } + } + + if ( !string_buf ) + { + FT_ERROR(( "t42_parse_sfnts: invalid data in sfnts array\n" )); + error = T42_Err_Invalid_File_Format; + goto Fail; + } + + /* A string can have a trailing zero byte for padding. Ignore it. */ + if ( string_buf[string_size - 1] == 0 && ( string_size % 2 == 1 ) ) + string_size--; + + if ( !string_size ) + { + FT_ERROR(( "t42_parse_sfnts: invalid string\n" )); + error = T42_Err_Invalid_File_Format; + goto Fail; + } + + for ( n = 0; n < string_size; n++ ) + { + switch ( status ) + { + case BEFORE_START: + /* load offset table, 12 bytes */ + if ( count < 12 ) + { + face->ttf_data[count++] = string_buf[n]; + continue; + } + else + { + num_tables = 16 * face->ttf_data[4] + face->ttf_data[5]; + status = BEFORE_TABLE_DIR; + ttf_size = 12 + 16 * num_tables; + + if ( FT_REALLOC( face->ttf_data, 12, ttf_size ) ) + goto Fail; + } + /* fall through */ + + case BEFORE_TABLE_DIR: + /* the offset table is read; read the table directory */ + if ( count < ttf_size ) + { + face->ttf_data[count++] = string_buf[n]; + continue; + } + else + { + int i; + FT_ULong len; + + + for ( i = 0; i < num_tables; i++ ) + { + FT_Byte* p = face->ttf_data + 12 + 16 * i + 12; + + + len = FT_PEEK_ULONG( p ); + + /* Pad to a 4-byte boundary length */ + ttf_size += ( len + 3 ) & ~3; + } + + status = OTHER_TABLES; + face->ttf_size = ttf_size; + + /* there are no more than 256 tables, so no size check here */ + if ( FT_REALLOC( face->ttf_data, 12 + 16 * num_tables, + ttf_size + 1 ) ) + goto Fail; + } + /* fall through */ + + case OTHER_TABLES: + /* all other tables are just copied */ + if ( count >= ttf_size ) + { + FT_ERROR(( "t42_parse_sfnts: too many binary data\n" )); + error = T42_Err_Invalid_File_Format; + goto Fail; + } + face->ttf_data[count++] = string_buf[n]; + } + } + + T1_Skip_Spaces( parser ); + } + + /* if control reaches this point, the format was not valid */ + error = T42_Err_Invalid_File_Format; + + Fail: + parser->root.error = error; + + Exit: + if ( allocated ) + FT_FREE( string_buf ); + } + + + static void + t42_parse_charstrings( T42_Face face, + T42_Loader loader ) + { + T42_Parser parser = &loader->parser; + PS_Table code_table = &loader->charstrings; + PS_Table name_table = &loader->glyph_names; + PS_Table swap_table = &loader->swap_table; + FT_Memory memory = parser->root.memory; + FT_Error error; + + PSAux_Service psaux = (PSAux_Service)face->psaux; + + FT_Byte* cur; + FT_Byte* limit = parser->root.limit; + FT_UInt n; + FT_UInt notdef_index = 0; + FT_Byte notdef_found = 0; + + + T1_Skip_Spaces( parser ); + + if ( parser->root.cursor >= limit ) + { + FT_ERROR(( "t42_parse_charstrings: out of bounds\n" )); + error = T42_Err_Invalid_File_Format; + goto Fail; + } + + if ( ft_isdigit( *parser->root.cursor ) ) + { + loader->num_glyphs = (FT_UInt)T1_ToInt( parser ); + if ( parser->root.error ) + return; + } + else if ( *parser->root.cursor == '<' ) + { + /* We have `<< ... >>'. Count the number of `/' in the dictionary */ + /* to get its size. */ + FT_UInt count = 0; + + + T1_Skip_PS_Token( parser ); + if ( parser->root.error ) + return; + T1_Skip_Spaces( parser ); + cur = parser->root.cursor; + + while ( parser->root.cursor < limit ) + { + if ( *parser->root.cursor == '/' ) + count++; + else if ( *parser->root.cursor == '>' ) + { + loader->num_glyphs = count; + parser->root.cursor = cur; /* rewind */ + break; + } + T1_Skip_PS_Token( parser ); + if ( parser->root.error ) + return; + T1_Skip_Spaces( parser ); + } + } + else + { + FT_ERROR(( "t42_parse_charstrings: invalid token\n" )); + error = T42_Err_Invalid_File_Format; + goto Fail; + } + + if ( parser->root.cursor >= limit ) + { + FT_ERROR(( "t42_parse_charstrings: out of bounds\n" )); + error = T42_Err_Invalid_File_Format; + goto Fail; + } + + /* initialize tables */ + + error = psaux->ps_table_funcs->init( code_table, + loader->num_glyphs, + memory ); + if ( error ) + goto Fail; + + error = psaux->ps_table_funcs->init( name_table, + loader->num_glyphs, + memory ); + if ( error ) + goto Fail; + + /* Initialize table for swapping index notdef_index and */ + /* index 0 names and codes (if necessary). */ + + error = psaux->ps_table_funcs->init( swap_table, 4, memory ); + if ( error ) + goto Fail; + + n = 0; + + for (;;) + { + /* The format is simple: */ + /* `/glyphname' + index [+ def] */ + + T1_Skip_Spaces( parser ); + + cur = parser->root.cursor; + if ( cur >= limit ) + break; + + /* We stop when we find an `end' keyword or '>' */ + if ( *cur == 'e' && + cur + 3 < limit && + cur[1] == 'n' && + cur[2] == 'd' && + t42_is_space( cur[3] ) ) + break; + if ( *cur == '>' ) + break; + + T1_Skip_PS_Token( parser ); + if ( parser->root.error ) + return; + + if ( *cur == '/' ) + { + FT_PtrDist len; + + + if ( cur + 1 >= limit ) + { + FT_ERROR(( "t42_parse_charstrings: out of bounds\n" )); + error = T42_Err_Invalid_File_Format; + goto Fail; + } + + cur++; /* skip `/' */ + len = parser->root.cursor - cur; + + error = T1_Add_Table( name_table, n, cur, len + 1 ); + if ( error ) + goto Fail; + + /* add a trailing zero to the name table */ + name_table->elements[n][len] = '\0'; + + /* record index of /.notdef */ + if ( *cur == '.' && + ft_strcmp( ".notdef", + (const char*)(name_table->elements[n]) ) == 0 ) + { + notdef_index = n; + notdef_found = 1; + } + + T1_Skip_Spaces( parser ); + + cur = parser->root.cursor; + + (void)T1_ToInt( parser ); + if ( parser->root.cursor >= limit ) + { + FT_ERROR(( "t42_parse_charstrings: out of bounds\n" )); + error = T42_Err_Invalid_File_Format; + goto Fail; + } + + len = parser->root.cursor - cur; + + error = T1_Add_Table( code_table, n, cur, len + 1 ); + if ( error ) + goto Fail; + + code_table->elements[n][len] = '\0'; + + n++; + if ( n >= loader->num_glyphs ) + break; + } + } + + loader->num_glyphs = n; + + if ( !notdef_found ) + { + FT_ERROR(( "t42_parse_charstrings: no /.notdef glyph\n" )); + error = T42_Err_Invalid_File_Format; + goto Fail; + } + + /* if /.notdef does not occupy index 0, do our magic. */ + if ( ft_strcmp( (const char*)".notdef", + (const char*)name_table->elements[0] ) ) + { + /* Swap glyph in index 0 with /.notdef glyph. First, add index 0 */ + /* name and code entries to swap_table. Then place notdef_index */ + /* name and code entries into swap_table. Then swap name and code */ + /* entries at indices notdef_index and 0 using values stored in */ + /* swap_table. */ + + /* Index 0 name */ + error = T1_Add_Table( swap_table, 0, + name_table->elements[0], + name_table->lengths [0] ); + if ( error ) + goto Fail; + + /* Index 0 code */ + error = T1_Add_Table( swap_table, 1, + code_table->elements[0], + code_table->lengths [0] ); + if ( error ) + goto Fail; + + /* Index notdef_index name */ + error = T1_Add_Table( swap_table, 2, + name_table->elements[notdef_index], + name_table->lengths [notdef_index] ); + if ( error ) + goto Fail; + + /* Index notdef_index code */ + error = T1_Add_Table( swap_table, 3, + code_table->elements[notdef_index], + code_table->lengths [notdef_index] ); + if ( error ) + goto Fail; + + error = T1_Add_Table( name_table, notdef_index, + swap_table->elements[0], + swap_table->lengths [0] ); + if ( error ) + goto Fail; + + error = T1_Add_Table( code_table, notdef_index, + swap_table->elements[1], + swap_table->lengths [1] ); + if ( error ) + goto Fail; + + error = T1_Add_Table( name_table, 0, + swap_table->elements[2], + swap_table->lengths [2] ); + if ( error ) + goto Fail; + + error = T1_Add_Table( code_table, 0, + swap_table->elements[3], + swap_table->lengths [3] ); + if ( error ) + goto Fail; + + } + + return; + + Fail: + parser->root.error = error; + } + + + static FT_Error + t42_load_keyword( T42_Face face, + T42_Loader loader, + T1_Field field ) + { + FT_Error error; + void* dummy_object; + void** objects; + FT_UInt max_objects = 0; + + + /* if the keyword has a dedicated callback, call it */ + if ( field->type == T1_FIELD_TYPE_CALLBACK ) + { + field->reader( (FT_Face)face, loader ); + error = loader->parser.root.error; + goto Exit; + } + + /* now the keyword is either a simple field or a table of fields; */ + /* we are now going to take care of it */ + + switch ( field->location ) + { + case T1_FIELD_LOCATION_FONT_INFO: + dummy_object = &face->type1.font_info; + break; + + case T1_FIELD_LOCATION_FONT_EXTRA: + dummy_object = &face->type1.font_extra; + break; + + case T1_FIELD_LOCATION_BBOX: + dummy_object = &face->type1.font_bbox; + break; + + default: + dummy_object = &face->type1; + } + + objects = &dummy_object; + + if ( field->type == T1_FIELD_TYPE_INTEGER_ARRAY || + field->type == T1_FIELD_TYPE_FIXED_ARRAY ) + error = T1_Load_Field_Table( &loader->parser, field, + objects, max_objects, 0 ); + else + error = T1_Load_Field( &loader->parser, field, + objects, max_objects, 0 ); + + Exit: + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + t42_parse_dict( T42_Face face, + T42_Loader loader, + FT_Byte* base, + FT_Long size ) + { + T42_Parser parser = &loader->parser; + FT_Byte* limit; + FT_Int n_keywords = (FT_Int)( sizeof ( t42_keywords ) / + sizeof ( t42_keywords[0] ) ); + + + parser->root.cursor = base; + parser->root.limit = base + size; + parser->root.error = T42_Err_Ok; + + limit = parser->root.limit; + + T1_Skip_Spaces( parser ); + + while ( parser->root.cursor < limit ) + { + FT_Byte* cur; + + + cur = parser->root.cursor; + + /* look for `FontDirectory' which causes problems for some fonts */ + if ( *cur == 'F' && cur + 25 < limit && + ft_strncmp( (char*)cur, "FontDirectory", 13 ) == 0 ) + { + FT_Byte* cur2; + + + /* skip the `FontDirectory' keyword */ + T1_Skip_PS_Token( parser ); + T1_Skip_Spaces ( parser ); + cur = cur2 = parser->root.cursor; + + /* look up the `known' keyword */ + while ( cur < limit ) + { + if ( *cur == 'k' && cur + 5 < limit && + ft_strncmp( (char*)cur, "known", 5 ) == 0 ) + break; + + T1_Skip_PS_Token( parser ); + if ( parser->root.error ) + goto Exit; + T1_Skip_Spaces ( parser ); + cur = parser->root.cursor; + } + + if ( cur < limit ) + { + T1_TokenRec token; + + + /* skip the `known' keyword and the token following it */ + T1_Skip_PS_Token( parser ); + T1_ToToken( parser, &token ); + + /* if the last token was an array, skip it! */ + if ( token.type == T1_TOKEN_TYPE_ARRAY ) + cur2 = parser->root.cursor; + } + parser->root.cursor = cur2; + } + + /* look for immediates */ + else if ( *cur == '/' && cur + 2 < limit ) + { + FT_PtrDist len; + + + cur++; + + parser->root.cursor = cur; + T1_Skip_PS_Token( parser ); + if ( parser->root.error ) + goto Exit; + + len = parser->root.cursor - cur; + + if ( len > 0 && len < 22 && parser->root.cursor < limit ) + { + int i; + + + /* now compare the immediate name to the keyword table */ + + /* loop through all known keywords */ + for ( i = 0; i < n_keywords; i++ ) + { + T1_Field keyword = (T1_Field)&t42_keywords[i]; + FT_Byte *name = (FT_Byte*)keyword->ident; + + + if ( !name ) + continue; + + if ( cur[0] == name[0] && + len == (FT_PtrDist)ft_strlen( (const char *)name ) && + ft_memcmp( cur, name, len ) == 0 ) + { + /* we found it -- run the parsing callback! */ + parser->root.error = t42_load_keyword( face, + loader, + keyword ); + if ( parser->root.error ) + return parser->root.error; + break; + } + } + } + } + else + { + T1_Skip_PS_Token( parser ); + if ( parser->root.error ) + goto Exit; + } + + T1_Skip_Spaces( parser ); + } + + Exit: + return parser->root.error; + } + + + FT_LOCAL_DEF( void ) + t42_loader_init( T42_Loader loader, + T42_Face face ) + { + FT_UNUSED( face ); + + FT_MEM_ZERO( loader, sizeof ( *loader ) ); + loader->num_glyphs = 0; + loader->num_chars = 0; + + /* initialize the tables -- simply set their `init' field to 0 */ + loader->encoding_table.init = 0; + loader->charstrings.init = 0; + loader->glyph_names.init = 0; + } + + + FT_LOCAL_DEF( void ) + t42_loader_done( T42_Loader loader ) + { + T42_Parser parser = &loader->parser; + + + /* finalize tables */ + T1_Release_Table( &loader->encoding_table ); + T1_Release_Table( &loader->charstrings ); + T1_Release_Table( &loader->glyph_names ); + T1_Release_Table( &loader->swap_table ); + + /* finalize parser */ + t42_parser_done( parser ); + } + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/type42/t42parse.h b/mod/pub.mod/freetype.mod/src/type42/t42parse.h new file mode 100644 index 0000000..f77ec4a --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/type42/t42parse.h @@ -0,0 +1,90 @@ +/***************************************************************************/ +/* */ +/* t42parse.h */ +/* */ +/* Type 42 font parser (specification). */ +/* */ +/* Copyright 2002, 2003 by Roberto Alameda. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __T42PARSE_H__ +#define __T42PARSE_H__ + + +#include "t42objs.h" +#include FT_INTERNAL_POSTSCRIPT_AUX_H + + +FT_BEGIN_HEADER + + typedef struct T42_ParserRec_ + { + PS_ParserRec root; + FT_Stream stream; + + FT_Byte* base_dict; + FT_Long base_len; + + FT_Bool in_memory; + + } T42_ParserRec, *T42_Parser; + + + typedef struct T42_Loader_ + { + T42_ParserRec parser; /* parser used to read the stream */ + + FT_UInt num_chars; /* number of characters in encoding */ + PS_TableRec encoding_table; /* PS_Table used to store the */ + /* encoding character names */ + + FT_UInt num_glyphs; + PS_TableRec glyph_names; + PS_TableRec charstrings; + PS_TableRec swap_table; /* For moving .notdef glyph to index 0. */ + + } T42_LoaderRec, *T42_Loader; + + + FT_LOCAL( FT_Error ) + t42_parser_init( T42_Parser parser, + FT_Stream stream, + FT_Memory memory, + PSAux_Service psaux ); + + FT_LOCAL( void ) + t42_parser_done( T42_Parser parser ); + + + FT_LOCAL( FT_Error ) + t42_parse_dict( T42_Face face, + T42_Loader loader, + FT_Byte* base, + FT_Long size ); + + + FT_LOCAL( void ) + t42_loader_init( T42_Loader loader, + T42_Face face ); + + FT_LOCAL( void ) + t42_loader_done( T42_Loader loader ); + + + /* */ + +FT_END_HEADER + + +#endif /* __T42PARSE_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/type42/t42types.h b/mod/pub.mod/freetype.mod/src/type42/t42types.h new file mode 100644 index 0000000..c7c2db4 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/type42/t42types.h @@ -0,0 +1,56 @@ +/***************************************************************************/ +/* */ +/* t42types.h */ +/* */ +/* Type 42 font data types (specification only). */ +/* */ +/* Copyright 2002, 2003, 2006, 2008 by Roberto Alameda. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __T42TYPES_H__ +#define __T42TYPES_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_TYPE1_TABLES_H +#include FT_INTERNAL_TYPE1_TYPES_H +#include FT_INTERNAL_POSTSCRIPT_HINTS_H + + +FT_BEGIN_HEADER + + + typedef struct T42_FaceRec_ + { + FT_FaceRec root; + T1_FontRec type1; + const void* psnames; + const void* psaux; +#if 0 + const void* afm_data; +#endif + FT_Byte* ttf_data; + FT_ULong ttf_size; + FT_Face ttf_face; + FT_CharMapRec charmaprecs[2]; + FT_CharMap charmaps[2]; + PS_UnicodesRec unicode_map; + + } T42_FaceRec, *T42_Face; + + +FT_END_HEADER + +#endif /* __T42TYPES_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/type42/type42.c b/mod/pub.mod/freetype.mod/src/type42/type42.c new file mode 100644 index 0000000..d13df56 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/type42/type42.c @@ -0,0 +1,25 @@ +/***************************************************************************/ +/* */ +/* type42.c */ +/* */ +/* FreeType Type 42 driver component. */ +/* */ +/* Copyright 2002 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + +#define FT_MAKE_OPTION_SINGLE_OBJECT + +#include <ft2build.h> +#include "t42objs.c" +#include "t42parse.c" +#include "t42drivr.c" + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/winfonts/fnterrs.h b/mod/pub.mod/freetype.mod/src/winfonts/fnterrs.h new file mode 100644 index 0000000..ea80909 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/winfonts/fnterrs.h @@ -0,0 +1,41 @@ +/***************************************************************************/ +/* */ +/* fnterrs.h */ +/* */ +/* Win FNT/FON error codes (specification only). */ +/* */ +/* Copyright 2001 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file is used to define the Windows FNT/FON error enumeration */ + /* constants. */ + /* */ + /*************************************************************************/ + +#ifndef __FNTERRS_H__ +#define __FNTERRS_H__ + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#define FT_ERR_PREFIX FNT_Err_ +#define FT_ERR_BASE FT_Mod_Err_Winfonts + +#include FT_ERRORS_H + +#endif /* __FNTERRS_H__ */ + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/winfonts/winfnt.c b/mod/pub.mod/freetype.mod/src/winfonts/winfnt.c new file mode 100644 index 0000000..6b3a4e1 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/winfonts/winfnt.c @@ -0,0 +1,1135 @@ +/***************************************************************************/ +/* */ +/* winfnt.c */ +/* */ +/* FreeType font driver for Windows FNT/FON files */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* Copyright 2003 Huw D M Davies for Codeweavers */ +/* Copyright 2007 Dmitry Timoshkov for Codeweavers */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_WINFONTS_H +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_OBJECTS_H + +#include "winfnt.h" +#include "fnterrs.h" +#include FT_SERVICE_WINFNT_H +#include FT_SERVICE_XFREE86_NAME_H + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_winfnt + + + static const FT_Frame_Field winmz_header_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE WinMZ_HeaderRec + + FT_FRAME_START( 64 ), + FT_FRAME_USHORT_LE ( magic ), + FT_FRAME_SKIP_BYTES( 29 * 2 ), + FT_FRAME_ULONG_LE ( lfanew ), + FT_FRAME_END + }; + + static const FT_Frame_Field winne_header_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE WinNE_HeaderRec + + FT_FRAME_START( 40 ), + FT_FRAME_USHORT_LE ( magic ), + FT_FRAME_SKIP_BYTES( 34 ), + FT_FRAME_USHORT_LE ( resource_tab_offset ), + FT_FRAME_USHORT_LE ( rname_tab_offset ), + FT_FRAME_END + }; + + static const FT_Frame_Field winpe32_header_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE WinPE32_HeaderRec + + FT_FRAME_START( 248 ), + FT_FRAME_ULONG_LE ( magic ), /* PE00 */ + FT_FRAME_USHORT_LE ( machine ), /* 0x014c - i386 */ + FT_FRAME_USHORT_LE ( number_of_sections ), + FT_FRAME_SKIP_BYTES( 12 ), + FT_FRAME_USHORT_LE ( size_of_optional_header ), + FT_FRAME_SKIP_BYTES( 2 ), + FT_FRAME_USHORT_LE ( magic32 ), /* 0x10b */ + FT_FRAME_SKIP_BYTES( 110 ), + FT_FRAME_ULONG_LE ( rsrc_virtual_address ), + FT_FRAME_ULONG_LE ( rsrc_size ), + FT_FRAME_SKIP_BYTES( 104 ), + FT_FRAME_END + }; + + static const FT_Frame_Field winpe32_section_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE WinPE32_SectionRec + + FT_FRAME_START( 40 ), + FT_FRAME_BYTES ( name, 8 ), + FT_FRAME_SKIP_BYTES( 4 ), + FT_FRAME_ULONG_LE ( virtual_address ), + FT_FRAME_ULONG_LE ( size_of_raw_data ), + FT_FRAME_ULONG_LE ( pointer_to_raw_data ), + FT_FRAME_SKIP_BYTES( 16 ), + FT_FRAME_END + }; + + static const FT_Frame_Field winpe_rsrc_dir_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE WinPE_RsrcDirRec + + FT_FRAME_START( 16 ), + FT_FRAME_ULONG_LE ( characteristics ), + FT_FRAME_ULONG_LE ( time_date_stamp ), + FT_FRAME_USHORT_LE( major_version ), + FT_FRAME_USHORT_LE( minor_version ), + FT_FRAME_USHORT_LE( number_of_named_entries ), + FT_FRAME_USHORT_LE( number_of_id_entries ), + FT_FRAME_END + }; + + static const FT_Frame_Field winpe_rsrc_dir_entry_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE WinPE_RsrcDirEntryRec + + FT_FRAME_START( 8 ), + FT_FRAME_ULONG_LE( name ), + FT_FRAME_ULONG_LE( offset ), + FT_FRAME_END + }; + + static const FT_Frame_Field winpe_rsrc_data_entry_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE WinPE_RsrcDataEntryRec + + FT_FRAME_START( 16 ), + FT_FRAME_ULONG_LE( offset_to_data ), + FT_FRAME_ULONG_LE( size ), + FT_FRAME_ULONG_LE( code_page ), + FT_FRAME_ULONG_LE( reserved ), + FT_FRAME_END + }; + + static const FT_Frame_Field winfnt_header_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE FT_WinFNT_HeaderRec + + FT_FRAME_START( 148 ), + FT_FRAME_USHORT_LE( version ), + FT_FRAME_ULONG_LE ( file_size ), + FT_FRAME_BYTES ( copyright, 60 ), + FT_FRAME_USHORT_LE( file_type ), + FT_FRAME_USHORT_LE( nominal_point_size ), + FT_FRAME_USHORT_LE( vertical_resolution ), + FT_FRAME_USHORT_LE( horizontal_resolution ), + FT_FRAME_USHORT_LE( ascent ), + FT_FRAME_USHORT_LE( internal_leading ), + FT_FRAME_USHORT_LE( external_leading ), + FT_FRAME_BYTE ( italic ), + FT_FRAME_BYTE ( underline ), + FT_FRAME_BYTE ( strike_out ), + FT_FRAME_USHORT_LE( weight ), + FT_FRAME_BYTE ( charset ), + FT_FRAME_USHORT_LE( pixel_width ), + FT_FRAME_USHORT_LE( pixel_height ), + FT_FRAME_BYTE ( pitch_and_family ), + FT_FRAME_USHORT_LE( avg_width ), + FT_FRAME_USHORT_LE( max_width ), + FT_FRAME_BYTE ( first_char ), + FT_FRAME_BYTE ( last_char ), + FT_FRAME_BYTE ( default_char ), + FT_FRAME_BYTE ( break_char ), + FT_FRAME_USHORT_LE( bytes_per_row ), + FT_FRAME_ULONG_LE ( device_offset ), + FT_FRAME_ULONG_LE ( face_name_offset ), + FT_FRAME_ULONG_LE ( bits_pointer ), + FT_FRAME_ULONG_LE ( bits_offset ), + FT_FRAME_BYTE ( reserved ), + FT_FRAME_ULONG_LE ( flags ), + FT_FRAME_USHORT_LE( A_space ), + FT_FRAME_USHORT_LE( B_space ), + FT_FRAME_USHORT_LE( C_space ), + FT_FRAME_ULONG_LE ( color_table_offset ), + FT_FRAME_BYTES ( reserved1, 16 ), + FT_FRAME_END + }; + + + static void + fnt_font_done( FNT_Face face ) + { + FT_Memory memory = FT_FACE( face )->memory; + FT_Stream stream = FT_FACE( face )->stream; + FNT_Font font = face->font; + + + if ( !font ) + return; + + if ( font->fnt_frame ) + FT_FRAME_RELEASE( font->fnt_frame ); + FT_FREE( font->family_name ); + + FT_FREE( font ); + face->font = 0; + } + + + static FT_Error + fnt_font_load( FNT_Font font, + FT_Stream stream ) + { + FT_Error error; + FT_WinFNT_Header header = &font->header; + FT_Bool new_format; + FT_UInt size; + + + /* first of all, read the FNT header */ + if ( FT_STREAM_SEEK( font->offset ) || + FT_STREAM_READ_FIELDS( winfnt_header_fields, header ) ) + goto Exit; + + /* check header */ + if ( header->version != 0x200 && + header->version != 0x300 ) + { + FT_TRACE2(( "[not a valid FNT file]\n" )); + error = FNT_Err_Unknown_File_Format; + goto Exit; + } + + new_format = FT_BOOL( font->header.version == 0x300 ); + size = new_format ? 148 : 118; + + if ( header->file_size < size ) + { + FT_TRACE2(( "[not a valid FNT file]\n" )); + error = FNT_Err_Unknown_File_Format; + goto Exit; + } + + /* Version 2 doesn't have these fields */ + if ( header->version == 0x200 ) + { + header->flags = 0; + header->A_space = 0; + header->B_space = 0; + header->C_space = 0; + + header->color_table_offset = 0; + } + + if ( header->file_type & 1 ) + { + FT_TRACE2(( "[can't handle vector FNT fonts]\n" )); + error = FNT_Err_Unknown_File_Format; + goto Exit; + } + + /* this is a FNT file/table; extract its frame */ + if ( FT_STREAM_SEEK( font->offset ) || + FT_FRAME_EXTRACT( header->file_size, font->fnt_frame ) ) + goto Exit; + + Exit: + return error; + } + + + static FT_Error + fnt_face_get_dll_font( FNT_Face face, + FT_Int face_index ) + { + FT_Error error; + FT_Stream stream = FT_FACE( face )->stream; + FT_Memory memory = FT_FACE( face )->memory; + WinMZ_HeaderRec mz_header; + + + face->font = 0; + + /* does it begin with an MZ header? */ + if ( FT_STREAM_SEEK( 0 ) || + FT_STREAM_READ_FIELDS( winmz_header_fields, &mz_header ) ) + goto Exit; + + error = FNT_Err_Unknown_File_Format; + if ( mz_header.magic == WINFNT_MZ_MAGIC ) + { + /* yes, now look for an NE header in the file */ + WinNE_HeaderRec ne_header; + + + FT_TRACE2(( "MZ signature found\n" )); + + if ( FT_STREAM_SEEK( mz_header.lfanew ) || + FT_STREAM_READ_FIELDS( winne_header_fields, &ne_header ) ) + goto Exit; + + error = FNT_Err_Unknown_File_Format; + if ( ne_header.magic == WINFNT_NE_MAGIC ) + { + /* good, now look into the resource table for each FNT resource */ + FT_ULong res_offset = mz_header.lfanew + + ne_header.resource_tab_offset; + FT_UShort size_shift; + FT_UShort font_count = 0; + FT_ULong font_offset = 0; + + + FT_TRACE2(( "NE signature found\n" )); + + if ( FT_STREAM_SEEK( res_offset ) || + FT_FRAME_ENTER( ne_header.rname_tab_offset - + ne_header.resource_tab_offset ) ) + goto Exit; + + size_shift = FT_GET_USHORT_LE(); + + for (;;) + { + FT_UShort type_id, count; + + + type_id = FT_GET_USHORT_LE(); + if ( !type_id ) + break; + + count = FT_GET_USHORT_LE(); + + if ( type_id == 0x8008U ) + { + font_count = count; + font_offset = (FT_ULong)( FT_STREAM_POS() + 4 + + ( stream->cursor - stream->limit ) ); + break; + } + + stream->cursor += 4 + count * 12; + } + + FT_FRAME_EXIT(); + + if ( !font_count || !font_offset ) + { + FT_TRACE2(( "this file doesn't contain any FNT resources\n" )); + error = FNT_Err_Invalid_File_Format; + goto Exit; + } + + /* loading `winfnt_header_fields' needs at least 118 bytes; */ + /* use this as a rough measure to check the expected font size */ + if ( font_count * 118UL > stream->size ) + { + FT_TRACE2(( "invalid number of faces\n" )); + error = FNT_Err_Invalid_File_Format; + goto Exit; + } + + face->root.num_faces = font_count; + + if ( face_index >= font_count ) + { + error = FNT_Err_Invalid_Argument; + goto Exit; + } + else if ( face_index < 0 ) + goto Exit; + + if ( FT_NEW( face->font ) ) + goto Exit; + + if ( FT_STREAM_SEEK( font_offset + face_index * 12 ) || + FT_FRAME_ENTER( 12 ) ) + goto Fail; + + face->font->offset = (FT_ULong)FT_GET_USHORT_LE() << size_shift; + face->font->fnt_size = (FT_ULong)FT_GET_USHORT_LE() << size_shift; + + stream->cursor += 8; + + FT_FRAME_EXIT(); + + error = fnt_font_load( face->font, stream ); + } + else if ( ne_header.magic == WINFNT_PE_MAGIC ) + { + WinPE32_HeaderRec pe32_header; + WinPE32_SectionRec pe32_section; + WinPE_RsrcDirRec root_dir, name_dir, lang_dir; + WinPE_RsrcDirEntryRec dir_entry1, dir_entry2, dir_entry3; + WinPE_RsrcDataEntryRec data_entry; + + FT_Long root_dir_offset, name_dir_offset, lang_dir_offset; + FT_UShort i, j, k; + + + FT_TRACE2(( "PE signature found\n" )); + + if ( FT_STREAM_SEEK( mz_header.lfanew ) || + FT_STREAM_READ_FIELDS( winpe32_header_fields, &pe32_header ) ) + goto Exit; + + FT_TRACE2(( "magic %04lx, machine %02x, number_of_sections %u, " + "size_of_optional_header %02x\n" + "magic32 %02x, rsrc_virtual_address %04lx, " + "rsrc_size %04lx\n", + pe32_header.magic, pe32_header.machine, + pe32_header.number_of_sections, + pe32_header.size_of_optional_header, + pe32_header.magic32, pe32_header.rsrc_virtual_address, + pe32_header.rsrc_size )); + + if ( pe32_header.magic != WINFNT_PE_MAGIC /* check full signature */ || + pe32_header.machine != 0x014c /* i386 */ || + pe32_header.size_of_optional_header != 0xe0 /* FIXME */ || + pe32_header.magic32 != 0x10b ) + { + FT_TRACE2(( "this file has an invalid PE header\n" )); + error = FNT_Err_Invalid_File_Format; + goto Exit; + } + + face->root.num_faces = 0; + + for ( i = 0; i < pe32_header.number_of_sections; i++ ) + { + if ( FT_STREAM_READ_FIELDS( winpe32_section_fields, + &pe32_section ) ) + goto Exit; + + FT_TRACE2(( "name %.8s, va %04lx, size %04lx, offset %04lx\n", + pe32_section.name, pe32_section.virtual_address, + pe32_section.size_of_raw_data, + pe32_section.pointer_to_raw_data )); + + if ( pe32_header.rsrc_virtual_address == + pe32_section.virtual_address ) + goto Found_rsrc_section; + } + + FT_TRACE2(( "this file doesn't contain any resources\n" )); + error = FNT_Err_Invalid_File_Format; + goto Exit; + + Found_rsrc_section: + FT_TRACE2(( "found resources section %.8s\n", pe32_section.name )); + + if ( FT_STREAM_SEEK( pe32_section.pointer_to_raw_data ) || + FT_STREAM_READ_FIELDS( winpe_rsrc_dir_fields, &root_dir ) ) + goto Exit; + + root_dir_offset = pe32_section.pointer_to_raw_data; + + for ( i = 0; i < root_dir.number_of_named_entries + + root_dir.number_of_id_entries; i++ ) + { + if ( FT_STREAM_SEEK( root_dir_offset + 16 + i * 8 ) || + FT_STREAM_READ_FIELDS( winpe_rsrc_dir_entry_fields, + &dir_entry1 ) ) + goto Exit; + + if ( !(dir_entry1.offset & 0x80000000UL ) /* DataIsDirectory */ ) + { + error = FNT_Err_Invalid_File_Format; + goto Exit; + } + + dir_entry1.offset &= ~0x80000000UL; + + name_dir_offset = pe32_section.pointer_to_raw_data + + dir_entry1.offset; + + if ( FT_STREAM_SEEK( pe32_section.pointer_to_raw_data + + dir_entry1.offset ) || + FT_STREAM_READ_FIELDS( winpe_rsrc_dir_fields, &name_dir ) ) + goto Exit; + + for ( j = 0; j < name_dir.number_of_named_entries + + name_dir.number_of_id_entries; j++ ) + { + if ( FT_STREAM_SEEK( name_dir_offset + 16 + j * 8 ) || + FT_STREAM_READ_FIELDS( winpe_rsrc_dir_entry_fields, + &dir_entry2 ) ) + goto Exit; + + if ( !(dir_entry2.offset & 0x80000000UL ) /* DataIsDirectory */ ) + { + error = FNT_Err_Invalid_File_Format; + goto Exit; + } + + dir_entry2.offset &= ~0x80000000UL; + + lang_dir_offset = pe32_section.pointer_to_raw_data + + dir_entry2.offset; + + if ( FT_STREAM_SEEK( pe32_section.pointer_to_raw_data + + dir_entry2.offset ) || + FT_STREAM_READ_FIELDS( winpe_rsrc_dir_fields, &lang_dir ) ) + goto Exit; + + for ( k = 0; k < lang_dir.number_of_named_entries + + lang_dir.number_of_id_entries; k++ ) + { + if ( FT_STREAM_SEEK( lang_dir_offset + 16 + k * 8 ) || + FT_STREAM_READ_FIELDS( winpe_rsrc_dir_entry_fields, + &dir_entry3 ) ) + goto Exit; + + if ( dir_entry2.offset & 0x80000000UL /* DataIsDirectory */ ) + { + error = FNT_Err_Invalid_File_Format; + goto Exit; + } + + if ( dir_entry1.name == 8 /* RT_FONT */ ) + { + if ( FT_STREAM_SEEK( root_dir_offset + dir_entry3.offset ) || + FT_STREAM_READ_FIELDS( winpe_rsrc_data_entry_fields, + &data_entry ) ) + goto Exit; + + FT_TRACE2(( "found font #%lu, offset %04lx, " + "size %04lx, cp %lu\n", + dir_entry2.name, + pe32_section.pointer_to_raw_data + + data_entry.offset_to_data - + pe32_section.virtual_address, + data_entry.size, data_entry.code_page )); + + if ( face_index == face->root.num_faces ) + { + if ( FT_NEW( face->font ) ) + goto Exit; + + face->font->offset = pe32_section.pointer_to_raw_data + + data_entry.offset_to_data - + pe32_section.virtual_address; + face->font->fnt_size = data_entry.size; + + error = fnt_font_load( face->font, stream ); + if ( error ) + { + FT_TRACE2(( "font #%lu load error %d\n", + dir_entry2.name, error )); + goto Fail; + } + else + FT_TRACE2(( "font #%lu successfully loaded\n", + dir_entry2.name )); + } + + face->root.num_faces++; + } + } + } + } + } + + if ( !face->root.num_faces ) + { + FT_TRACE2(( "this file doesn't contain any RT_FONT resources\n" )); + error = FNT_Err_Invalid_File_Format; + goto Exit; + } + + if ( face_index >= face->root.num_faces ) + { + error = FNT_Err_Invalid_Argument; + goto Exit; + } + } + + Fail: + if ( error ) + fnt_font_done( face ); + + Exit: + return error; + } + + + typedef struct FNT_CMapRec_ + { + FT_CMapRec cmap; + FT_UInt32 first; + FT_UInt32 count; + + } FNT_CMapRec, *FNT_CMap; + + + static FT_Error + fnt_cmap_init( FNT_CMap cmap ) + { + FNT_Face face = (FNT_Face)FT_CMAP_FACE( cmap ); + FNT_Font font = face->font; + + + cmap->first = (FT_UInt32) font->header.first_char; + cmap->count = (FT_UInt32)( font->header.last_char - cmap->first + 1 ); + + return 0; + } + + + static FT_UInt + fnt_cmap_char_index( FNT_CMap cmap, + FT_UInt32 char_code ) + { + FT_UInt gindex = 0; + + + char_code -= cmap->first; + if ( char_code < cmap->count ) + /* we artificially increase the glyph index; */ + /* FNT_Load_Glyph reverts to the right one */ + gindex = (FT_UInt)( char_code + 1 ); + return gindex; + } + + + static FT_UInt32 + fnt_cmap_char_next( FNT_CMap cmap, + FT_UInt32 *pchar_code ) + { + FT_UInt gindex = 0; + FT_UInt32 result = 0; + FT_UInt32 char_code = *pchar_code + 1; + + + if ( char_code <= cmap->first ) + { + result = cmap->first; + gindex = 1; + } + else + { + char_code -= cmap->first; + if ( char_code < cmap->count ) + { + result = cmap->first + char_code; + gindex = (FT_UInt)( char_code + 1 ); + } + } + + *pchar_code = result; + return gindex; + } + + + static const FT_CMap_ClassRec fnt_cmap_class_rec = + { + sizeof ( FNT_CMapRec ), + + (FT_CMap_InitFunc) fnt_cmap_init, + (FT_CMap_DoneFunc) NULL, + (FT_CMap_CharIndexFunc)fnt_cmap_char_index, + (FT_CMap_CharNextFunc) fnt_cmap_char_next, + + NULL, NULL, NULL, NULL, NULL + }; + + static FT_CMap_Class const fnt_cmap_class = &fnt_cmap_class_rec; + + + static void + FNT_Face_Done( FNT_Face face ) + { + FT_Memory memory; + + + if ( !face ) + return; + + memory = FT_FACE_MEMORY( face ); + + fnt_font_done( face ); + + FT_FREE( face->root.available_sizes ); + face->root.num_fixed_sizes = 0; + } + + + static FT_Error + FNT_Face_Init( FT_Stream stream, + FNT_Face face, + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ) + { + FT_Error error; + FT_Memory memory = FT_FACE_MEMORY( face ); + + FT_UNUSED( num_params ); + FT_UNUSED( params ); + + + /* try to load font from a DLL */ + error = fnt_face_get_dll_font( face, face_index ); + if ( !error && face_index < 0 ) + goto Exit; + + if ( error == FNT_Err_Unknown_File_Format ) + { + /* this didn't work; try to load a single FNT font */ + FNT_Font font; + + if ( FT_NEW( face->font ) ) + goto Exit; + + face->root.num_faces = 1; + + font = face->font; + font->offset = 0; + font->fnt_size = stream->size; + + error = fnt_font_load( font, stream ); + + if ( !error ) + { + if ( face_index > 0 ) + error = FNT_Err_Invalid_Argument; + else if ( face_index < 0 ) + goto Exit; + } + } + + if ( error ) + goto Fail; + + /* we now need to fill the root FT_Face fields */ + /* with relevant information */ + { + FT_Face root = FT_FACE( face ); + FNT_Font font = face->font; + FT_PtrDist family_size; + + + root->face_index = face_index; + + root->face_flags = FT_FACE_FLAG_FIXED_SIZES | + FT_FACE_FLAG_HORIZONTAL; + + if ( font->header.avg_width == font->header.max_width ) + root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; + + if ( font->header.italic ) + root->style_flags |= FT_STYLE_FLAG_ITALIC; + + if ( font->header.weight >= 800 ) + root->style_flags |= FT_STYLE_FLAG_BOLD; + + /* set up the `fixed_sizes' array */ + if ( FT_NEW_ARRAY( root->available_sizes, 1 ) ) + goto Fail; + + root->num_fixed_sizes = 1; + + { + FT_Bitmap_Size* bsize = root->available_sizes; + FT_UShort x_res, y_res; + + + bsize->width = font->header.avg_width; + bsize->height = (FT_Short)( + font->header.pixel_height + font->header.external_leading ); + bsize->size = font->header.nominal_point_size << 6; + + x_res = font->header.horizontal_resolution; + if ( !x_res ) + x_res = 72; + + y_res = font->header.vertical_resolution; + if ( !y_res ) + y_res = 72; + + bsize->y_ppem = FT_MulDiv( bsize->size, y_res, 72 ); + bsize->y_ppem = FT_PIX_ROUND( bsize->y_ppem ); + + /* + * this reads: + * + * the nominal height is larger than the bbox's height + * + * => nominal_point_size contains incorrect value; + * use pixel_height as the nominal height + */ + if ( bsize->y_ppem > ( font->header.pixel_height << 6 ) ) + { + FT_TRACE2(( "use pixel_height as the nominal height\n" )); + + bsize->y_ppem = font->header.pixel_height << 6; + bsize->size = FT_MulDiv( bsize->y_ppem, 72, y_res ); + } + + bsize->x_ppem = FT_MulDiv( bsize->size, x_res, 72 ); + bsize->x_ppem = FT_PIX_ROUND( bsize->x_ppem ); + } + + { + FT_CharMapRec charmap; + + + charmap.encoding = FT_ENCODING_NONE; + charmap.platform_id = 0; + charmap.encoding_id = 0; + charmap.face = root; + + if ( font->header.charset == FT_WinFNT_ID_MAC ) + { + charmap.encoding = FT_ENCODING_APPLE_ROMAN; + charmap.platform_id = 1; +/* charmap.encoding_id = 0; */ + } + + error = FT_CMap_New( fnt_cmap_class, + NULL, + &charmap, + NULL ); + if ( error ) + goto Fail; + + /* Select default charmap */ + if ( root->num_charmaps ) + root->charmap = root->charmaps[0]; + } + + /* setup remaining flags */ + + /* reserve one slot for the .notdef glyph at index 0 */ + root->num_glyphs = font->header.last_char - + font->header.first_char + 1 + 1; + + if ( font->header.face_name_offset >= font->header.file_size ) + { + FT_TRACE2(( "invalid family name offset\n" )); + error = FNT_Err_Invalid_File_Format; + goto Fail; + } + family_size = font->header.file_size - font->header.face_name_offset; + /* Some broken fonts don't delimit the face name with a final */ + /* NULL byte -- the frame is erroneously one byte too small. */ + /* We thus allocate one more byte, setting it explicitly to */ + /* zero. */ + if ( FT_ALLOC( font->family_name, family_size + 1 ) ) + goto Fail; + + FT_MEM_COPY( font->family_name, + font->fnt_frame + font->header.face_name_offset, + family_size ); + + font->family_name[family_size] = '\0'; + + if ( FT_REALLOC( font->family_name, + family_size, + ft_strlen( font->family_name ) + 1 ) ) + goto Fail; + + root->family_name = font->family_name; + root->style_name = (char *)"Regular"; + + if ( root->style_flags & FT_STYLE_FLAG_BOLD ) + { + if ( root->style_flags & FT_STYLE_FLAG_ITALIC ) + root->style_name = (char *)"Bold Italic"; + else + root->style_name = (char *)"Bold"; + } + else if ( root->style_flags & FT_STYLE_FLAG_ITALIC ) + root->style_name = (char *)"Italic"; + } + goto Exit; + + Fail: + FNT_Face_Done( face ); + + Exit: + return error; + } + + + static FT_Error + FNT_Size_Select( FT_Size size ) + { + FNT_Face face = (FNT_Face)size->face; + FT_WinFNT_Header header = &face->font->header; + + + FT_Select_Metrics( size->face, 0 ); + + size->metrics.ascender = header->ascent * 64; + size->metrics.descender = -( header->pixel_height - + header->ascent ) * 64; + size->metrics.max_advance = header->max_width * 64; + + return FNT_Err_Ok; + } + + + static FT_Error + FNT_Size_Request( FT_Size size, + FT_Size_Request req ) + { + FNT_Face face = (FNT_Face)size->face; + FT_WinFNT_Header header = &face->font->header; + FT_Bitmap_Size* bsize = size->face->available_sizes; + FT_Error error = FNT_Err_Invalid_Pixel_Size; + FT_Long height; + + + height = FT_REQUEST_HEIGHT( req ); + height = ( height + 32 ) >> 6; + + switch ( req->type ) + { + case FT_SIZE_REQUEST_TYPE_NOMINAL: + if ( height == ( ( bsize->y_ppem + 32 ) >> 6 ) ) + error = FNT_Err_Ok; + break; + + case FT_SIZE_REQUEST_TYPE_REAL_DIM: + if ( height == header->pixel_height ) + error = FNT_Err_Ok; + break; + + default: + error = FNT_Err_Unimplemented_Feature; + break; + } + + if ( error ) + return error; + else + return FNT_Size_Select( size ); + } + + + static FT_Error + FNT_Load_Glyph( FT_GlyphSlot slot, + FT_Size size, + FT_UInt glyph_index, + FT_Int32 load_flags ) + { + FNT_Face face = (FNT_Face)FT_SIZE_FACE( size ); + FNT_Font font = face->font; + FT_Error error = FNT_Err_Ok; + FT_Byte* p; + FT_Int len; + FT_Bitmap* bitmap = &slot->bitmap; + FT_ULong offset; + FT_Bool new_format; + + FT_UNUSED( load_flags ); + + + if ( !face || !font || + glyph_index >= (FT_UInt)( FT_FACE( face )->num_glyphs ) ) + { + error = FNT_Err_Invalid_Argument; + goto Exit; + } + + if ( glyph_index > 0 ) + glyph_index--; /* revert to real index */ + else + glyph_index = font->header.default_char; /* the .notdef glyph */ + + new_format = FT_BOOL( font->header.version == 0x300 ); + len = new_format ? 6 : 4; + + /* jump to glyph entry */ + p = font->fnt_frame + ( new_format ? 148 : 118 ) + len * glyph_index; + + bitmap->width = FT_NEXT_SHORT_LE( p ); + + if ( new_format ) + offset = FT_NEXT_ULONG_LE( p ); + else + offset = FT_NEXT_USHORT_LE( p ); + + if ( offset >= font->header.file_size ) + { + FT_TRACE2(( "invalid FNT offset\n" )); + error = FNT_Err_Invalid_File_Format; + goto Exit; + } + + /* jump to glyph data */ + p = font->fnt_frame + /* font->header.bits_offset */ + offset; + + /* allocate and build bitmap */ + { + FT_Memory memory = FT_FACE_MEMORY( slot->face ); + FT_Int pitch = ( bitmap->width + 7 ) >> 3; + FT_Byte* column; + FT_Byte* write; + + + bitmap->pitch = pitch; + bitmap->rows = font->header.pixel_height; + bitmap->pixel_mode = FT_PIXEL_MODE_MONO; + + if ( offset + pitch * bitmap->rows >= font->header.file_size ) + { + FT_TRACE2(( "invalid bitmap width\n" )); + error = FNT_Err_Invalid_File_Format; + goto Exit; + } + + /* note: since glyphs are stored in columns and not in rows we */ + /* can't use ft_glyphslot_set_bitmap */ + if ( FT_ALLOC_MULT( bitmap->buffer, pitch, bitmap->rows ) ) + goto Exit; + + column = (FT_Byte*)bitmap->buffer; + + for ( ; pitch > 0; pitch--, column++ ) + { + FT_Byte* limit = p + bitmap->rows; + + + for ( write = column; p < limit; p++, write += bitmap->pitch ) + *write = *p; + } + } + + slot->internal->flags = FT_GLYPH_OWN_BITMAP; + slot->bitmap_left = 0; + slot->bitmap_top = font->header.ascent; + slot->format = FT_GLYPH_FORMAT_BITMAP; + + /* now set up metrics */ + slot->metrics.width = bitmap->width << 6; + slot->metrics.height = bitmap->rows << 6; + slot->metrics.horiAdvance = bitmap->width << 6; + slot->metrics.horiBearingX = 0; + slot->metrics.horiBearingY = slot->bitmap_top << 6; + + ft_synthesize_vertical_metrics( &slot->metrics, + bitmap->rows << 6 ); + + Exit: + return error; + } + + + static FT_Error + winfnt_get_header( FT_Face face, + FT_WinFNT_HeaderRec *aheader ) + { + FNT_Font font = ((FNT_Face)face)->font; + + + *aheader = font->header; + + return 0; + } + + + static const FT_Service_WinFntRec winfnt_service_rec = + { + winfnt_get_header + }; + + /* + * SERVICE LIST + * + */ + + static const FT_ServiceDescRec winfnt_services[] = + { + { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_WINFNT }, + { FT_SERVICE_ID_WINFNT, &winfnt_service_rec }, + { NULL, NULL } + }; + + + static FT_Module_Interface + winfnt_get_service( FT_Driver driver, + const FT_String* service_id ) + { + FT_UNUSED( driver ); + + return ft_service_list_lookup( winfnt_services, service_id ); + } + + + + + FT_CALLBACK_TABLE_DEF + const FT_Driver_ClassRec winfnt_driver_class = + { + { + FT_MODULE_FONT_DRIVER | + FT_MODULE_DRIVER_NO_OUTLINES, + sizeof ( FT_DriverRec ), + + "winfonts", + 0x10000L, + 0x20000L, + + 0, + + (FT_Module_Constructor)0, + (FT_Module_Destructor) 0, + (FT_Module_Requester) winfnt_get_service + }, + + sizeof( FNT_FaceRec ), + sizeof( FT_SizeRec ), + sizeof( FT_GlyphSlotRec ), + + (FT_Face_InitFunc) FNT_Face_Init, + (FT_Face_DoneFunc) FNT_Face_Done, + (FT_Size_InitFunc) 0, + (FT_Size_DoneFunc) 0, + (FT_Slot_InitFunc) 0, + (FT_Slot_DoneFunc) 0, + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + ft_stub_set_char_sizes, + ft_stub_set_pixel_sizes, +#endif + (FT_Slot_LoadFunc) FNT_Load_Glyph, + + (FT_Face_GetKerningFunc) 0, + (FT_Face_AttachFunc) 0, + (FT_Face_GetAdvancesFunc) 0, + + (FT_Size_RequestFunc) FNT_Size_Request, + (FT_Size_SelectFunc) FNT_Size_Select + }; + + +/* END */ diff --git a/mod/pub.mod/freetype.mod/src/winfonts/winfnt.h b/mod/pub.mod/freetype.mod/src/winfonts/winfnt.h new file mode 100644 index 0000000..70a9086 --- /dev/null +++ b/mod/pub.mod/freetype.mod/src/winfonts/winfnt.h @@ -0,0 +1,171 @@ +/***************************************************************************/ +/* */ +/* winfnt.h */ +/* */ +/* FreeType font driver for Windows FNT/FON files */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* Copyright 2007 Dmitry Timoshkov for Codeweavers */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __WINFNT_H__ +#define __WINFNT_H__ + + +#include <ft2build.h> +#include FT_WINFONTS_H +#include FT_INTERNAL_DRIVER_H + + +FT_BEGIN_HEADER + +#ifdef FT_CONFIG_OPTION_PIC +#error "this module does not support PIC yet" +#endif + + typedef struct WinMZ_HeaderRec_ + { + FT_UShort magic; + /* skipped content */ + FT_UShort lfanew; + + } WinMZ_HeaderRec; + + + typedef struct WinNE_HeaderRec_ + { + FT_UShort magic; + /* skipped content */ + FT_UShort resource_tab_offset; + FT_UShort rname_tab_offset; + + } WinNE_HeaderRec; + + + typedef struct WinPE32_HeaderRec_ + { + FT_ULong magic; + FT_UShort machine; + FT_UShort number_of_sections; + /* skipped content */ + FT_UShort size_of_optional_header; + /* skipped content */ + FT_UShort magic32; + /* skipped content */ + FT_ULong rsrc_virtual_address; + FT_ULong rsrc_size; + /* skipped content */ + + } WinPE32_HeaderRec; + + + typedef struct WinPE32_SectionRec_ + { + FT_Byte name[8]; + /* skipped content */ + FT_ULong virtual_address; + FT_ULong size_of_raw_data; + FT_ULong pointer_to_raw_data; + /* skipped content */ + + } WinPE32_SectionRec; + + + typedef struct WinPE_RsrcDirRec_ + { + FT_ULong characteristics; + FT_ULong time_date_stamp; + FT_UShort major_version; + FT_UShort minor_version; + FT_UShort number_of_named_entries; + FT_UShort number_of_id_entries; + + } WinPE_RsrcDirRec; + + + typedef struct WinPE_RsrcDirEntryRec_ + { + FT_ULong name; + FT_ULong offset; + + } WinPE_RsrcDirEntryRec; + + + typedef struct WinPE_RsrcDataEntryRec_ + { + FT_ULong offset_to_data; + FT_ULong size; + FT_ULong code_page; + FT_ULong reserved; + + } WinPE_RsrcDataEntryRec; + + + typedef struct WinNameInfoRec_ + { + FT_UShort offset; + FT_UShort length; + FT_UShort flags; + FT_UShort id; + FT_UShort handle; + FT_UShort usage; + + } WinNameInfoRec; + + + typedef struct WinResourceInfoRec_ + { + FT_UShort type_id; + FT_UShort count; + + } WinResourceInfoRec; + + +#define WINFNT_MZ_MAGIC 0x5A4D +#define WINFNT_NE_MAGIC 0x454E +#define WINFNT_PE_MAGIC 0x4550 + + + typedef struct FNT_FontRec_ + { + FT_ULong offset; + + FT_WinFNT_HeaderRec header; + + FT_Byte* fnt_frame; + FT_ULong fnt_size; + FT_String* family_name; + + } FNT_FontRec, *FNT_Font; + + + typedef struct FNT_FaceRec_ + { + FT_FaceRec root; + FNT_Font font; + + FT_CharMap charmap_handle; + FT_CharMapRec charmap; /* a single charmap per face */ + + } FNT_FaceRec, *FNT_Face; + + + FT_EXPORT_VAR( const FT_Driver_ClassRec ) winfnt_driver_class; + + +FT_END_HEADER + + +#endif /* __WINFNT_H__ */ + + +/* END */ diff --git a/mod/pub.mod/glew.mod/GL/glew.h b/mod/pub.mod/glew.mod/GL/glew.h new file mode 100644 index 0000000..2014092 --- /dev/null +++ b/mod/pub.mod/glew.mod/GL/glew.h @@ -0,0 +1,12262 @@ +/* +** The OpenGL Extension Wrangler Library +** Copyright (C) 2002-2008, Milan Ikits <milan ikits[]ieee org> +** Copyright (C) 2002-2008, Marcelo E. Magallon <mmagallo[]debian org> +** Copyright (C) 2002, Lev Povalahev +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are met: +** +** * Redistributions of source code must retain the above copyright notice, +** this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright notice, +** this list of conditions and the following disclaimer in the documentation +** and/or other materials provided with the distribution. +** * The name of the author may be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +** THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/* + * Mesa 3-D graphics library + * Version: 7.0 + * + * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* +** Copyright (c) 2007 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +#ifndef __glew_h__ +#define __glew_h__ +#define __GLEW_H__ + +#if defined(__gl_h_) || defined(__GL_H__) +#error gl.h included before glew.h +#endif +#if defined(__glext_h_) || defined(__GLEXT_H_) +#error glext.h included before glew.h +#endif +#if defined(__gl_ATI_h_) +#error glATI.h included before glew.h +#endif + +#define __gl_h_ +#define __GL_H__ +#define __glext_h_ +#define __GLEXT_H_ +#define __gl_ATI_h_ + +#if defined(_WIN32) + +/* + * GLEW does not include <windows.h> to avoid name space pollution. + * GL needs GLAPI and GLAPIENTRY, GLU needs APIENTRY, CALLBACK, and wchar_t + * defined properly. + */ +/* <windef.h> */ +#ifndef APIENTRY +#define GLEW_APIENTRY_DEFINED +# if defined(__MINGW32__) +# define APIENTRY __stdcall +# elif (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED) || defined(__BORLANDC__) +# define APIENTRY __stdcall +# else +# define APIENTRY +# endif +#endif +#ifndef GLAPI +# if defined(__MINGW32__) +# define GLAPI extern +# endif +#endif +/* <winnt.h> */ +#ifndef CALLBACK +#define GLEW_CALLBACK_DEFINED +# if defined(__MINGW32__) +# define CALLBACK __attribute__ ((__stdcall__)) +# elif (defined(_M_MRX000) || defined(_M_IX86) || defined(_M_ALPHA) || defined(_M_PPC)) && !defined(MIDL_PASS) +# define CALLBACK __stdcall +# else +# define CALLBACK +# endif +#endif +/* <wingdi.h> and <winnt.h> */ +#ifndef WINGDIAPI +#define GLEW_WINGDIAPI_DEFINED +#define WINGDIAPI __declspec(dllimport) +#endif +/* <ctype.h> */ +#if (defined(_MSC_VER) || defined(__BORLANDC__)) && !defined(_WCHAR_T_DEFINED) +typedef unsigned short wchar_t; +# define _WCHAR_T_DEFINED +#endif +/* <stddef.h> */ +#if !defined(_W64) +# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && defined(_MSC_VER) && _MSC_VER >= 1300 +# define _W64 __w64 +# else +# define _W64 +# endif +#endif +#if !defined(_PTRDIFF_T_DEFINED) && !defined(_PTRDIFF_T_) +# ifdef _WIN64 +typedef __int64 ptrdiff_t; +# else +typedef _W64 int ptrdiff_t; +# endif +# define _PTRDIFF_T_DEFINED +# define _PTRDIFF_T_ +#endif + +#ifndef GLAPI +# if defined(__MINGW32__) +# define GLAPI extern +# else +# define GLAPI WINGDIAPI +# endif +#endif + +#ifndef GLAPIENTRY +#define GLAPIENTRY APIENTRY +#endif + +/* + * GLEW_STATIC needs to be set when using the static version. + * GLEW_BUILD is set when building the DLL version. + */ +#ifdef GLEW_STATIC +# define GLEWAPI extern +#else +# ifdef GLEW_BUILD +# define GLEWAPI extern __declspec(dllexport) +# else +# define GLEWAPI extern __declspec(dllimport) +# endif +#endif + +#else /* _UNIX */ + +/* + * Needed for ptrdiff_t in turn needed by VBO. This is defined by ISO + * C. On my system, this amounts to _3 lines_ of included code, all of + * them pretty much harmless. If you know of a way of detecting 32 vs + * 64 _targets_ at compile time you are free to replace this with + * something that's portable. For now, _this_ is the portable solution. + * (mem, 2004-01-04) + */ + +#include <stddef.h> +#include <stdint.h> + +#define GLEW_APIENTRY_DEFINED +#define APIENTRY +#define GLEWAPI extern + +/* <glu.h> */ +#ifndef GLAPI +#define GLAPI extern +#endif +#ifndef GLAPIENTRY +#define GLAPIENTRY +#endif + +#endif /* _WIN32 */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* ----------------------------- GL_VERSION_1_1 ---------------------------- */ + +#ifndef GL_VERSION_1_1 +#define GL_VERSION_1_1 1 + +typedef unsigned int GLenum; +typedef unsigned int GLbitfield; +typedef unsigned int GLuint; +typedef int GLint; +typedef int GLsizei; +typedef unsigned char GLboolean; +typedef signed char GLbyte; +typedef short GLshort; +typedef unsigned char GLubyte; +typedef unsigned short GLushort; +typedef unsigned long GLulong; +typedef float GLfloat; +typedef float GLclampf; +typedef double GLdouble; +typedef double GLclampd; +typedef void GLvoid; +#if defined(_MSC_VER) +# if _MSC_VER < 1400 +typedef __int64 GLint64EXT; +typedef unsigned __int64 GLuint64EXT; +# else +typedef signed long long GLint64EXT; +typedef unsigned long long GLuint64EXT; +# endif +#else +# if defined(__MINGW32__) +#include <inttypes.h> +# endif +typedef int64_t GLint64EXT; +typedef uint64_t GLuint64EXT; +#endif + +#define GL_ACCUM 0x0100 +#define GL_LOAD 0x0101 +#define GL_RETURN 0x0102 +#define GL_MULT 0x0103 +#define GL_ADD 0x0104 +#define GL_NEVER 0x0200 +#define GL_LESS 0x0201 +#define GL_EQUAL 0x0202 +#define GL_LEQUAL 0x0203 +#define GL_GREATER 0x0204 +#define GL_NOTEQUAL 0x0205 +#define GL_GEQUAL 0x0206 +#define GL_ALWAYS 0x0207 +#define GL_CURRENT_BIT 0x00000001 +#define GL_POINT_BIT 0x00000002 +#define GL_LINE_BIT 0x00000004 +#define GL_POLYGON_BIT 0x00000008 +#define GL_POLYGON_STIPPLE_BIT 0x00000010 +#define GL_PIXEL_MODE_BIT 0x00000020 +#define GL_LIGHTING_BIT 0x00000040 +#define GL_FOG_BIT 0x00000080 +#define GL_DEPTH_BUFFER_BIT 0x00000100 +#define GL_ACCUM_BUFFER_BIT 0x00000200 +#define GL_STENCIL_BUFFER_BIT 0x00000400 +#define GL_VIEWPORT_BIT 0x00000800 +#define GL_TRANSFORM_BIT 0x00001000 +#define GL_ENABLE_BIT 0x00002000 +#define GL_COLOR_BUFFER_BIT 0x00004000 +#define GL_HINT_BIT 0x00008000 +#define GL_EVAL_BIT 0x00010000 +#define GL_LIST_BIT 0x00020000 +#define GL_TEXTURE_BIT 0x00040000 +#define GL_SCISSOR_BIT 0x00080000 +#define GL_ALL_ATTRIB_BITS 0x000fffff +#define GL_POINTS 0x0000 +#define GL_LINES 0x0001 +#define GL_LINE_LOOP 0x0002 +#define GL_LINE_STRIP 0x0003 +#define GL_TRIANGLES 0x0004 +#define GL_TRIANGLE_STRIP 0x0005 +#define GL_TRIANGLE_FAN 0x0006 +#define GL_QUADS 0x0007 +#define GL_QUAD_STRIP 0x0008 +#define GL_POLYGON 0x0009 +#define GL_ZERO 0 +#define GL_ONE 1 +#define GL_SRC_COLOR 0x0300 +#define GL_ONE_MINUS_SRC_COLOR 0x0301 +#define GL_SRC_ALPHA 0x0302 +#define GL_ONE_MINUS_SRC_ALPHA 0x0303 +#define GL_DST_ALPHA 0x0304 +#define GL_ONE_MINUS_DST_ALPHA 0x0305 +#define GL_DST_COLOR 0x0306 +#define GL_ONE_MINUS_DST_COLOR 0x0307 +#define GL_SRC_ALPHA_SATURATE 0x0308 +#define GL_TRUE 1 +#define GL_FALSE 0 +#define GL_CLIP_PLANE0 0x3000 +#define GL_CLIP_PLANE1 0x3001 +#define GL_CLIP_PLANE2 0x3002 +#define GL_CLIP_PLANE3 0x3003 +#define GL_CLIP_PLANE4 0x3004 +#define GL_CLIP_PLANE5 0x3005 +#define GL_BYTE 0x1400 +#define GL_UNSIGNED_BYTE 0x1401 +#define GL_SHORT 0x1402 +#define GL_UNSIGNED_SHORT 0x1403 +#define GL_INT 0x1404 +#define GL_UNSIGNED_INT 0x1405 +#define GL_FLOAT 0x1406 +#define GL_2_BYTES 0x1407 +#define GL_3_BYTES 0x1408 +#define GL_4_BYTES 0x1409 +#define GL_DOUBLE 0x140A +#define GL_NONE 0 +#define GL_FRONT_LEFT 0x0400 +#define GL_FRONT_RIGHT 0x0401 +#define GL_BACK_LEFT 0x0402 +#define GL_BACK_RIGHT 0x0403 +#define GL_FRONT 0x0404 +#define GL_BACK 0x0405 +#define GL_LEFT 0x0406 +#define GL_RIGHT 0x0407 +#define GL_FRONT_AND_BACK 0x0408 +#define GL_AUX0 0x0409 +#define GL_AUX1 0x040A +#define GL_AUX2 0x040B +#define GL_AUX3 0x040C +#define GL_NO_ERROR 0 +#define GL_INVALID_ENUM 0x0500 +#define GL_INVALID_VALUE 0x0501 +#define GL_INVALID_OPERATION 0x0502 +#define GL_STACK_OVERFLOW 0x0503 +#define GL_STACK_UNDERFLOW 0x0504 +#define GL_OUT_OF_MEMORY 0x0505 +#define GL_2D 0x0600 +#define GL_3D 0x0601 +#define GL_3D_COLOR 0x0602 +#define GL_3D_COLOR_TEXTURE 0x0603 +#define GL_4D_COLOR_TEXTURE 0x0604 +#define GL_PASS_THROUGH_TOKEN 0x0700 +#define GL_POINT_TOKEN 0x0701 +#define GL_LINE_TOKEN 0x0702 +#define GL_POLYGON_TOKEN 0x0703 +#define GL_BITMAP_TOKEN 0x0704 +#define GL_DRAW_PIXEL_TOKEN 0x0705 +#define GL_COPY_PIXEL_TOKEN 0x0706 +#define GL_LINE_RESET_TOKEN 0x0707 +#define GL_EXP 0x0800 +#define GL_EXP2 0x0801 +#define GL_CW 0x0900 +#define GL_CCW 0x0901 +#define GL_COEFF 0x0A00 +#define GL_ORDER 0x0A01 +#define GL_DOMAIN 0x0A02 +#define GL_CURRENT_COLOR 0x0B00 +#define GL_CURRENT_INDEX 0x0B01 +#define GL_CURRENT_NORMAL 0x0B02 +#define GL_CURRENT_TEXTURE_COORDS 0x0B03 +#define GL_CURRENT_RASTER_COLOR 0x0B04 +#define GL_CURRENT_RASTER_INDEX 0x0B05 +#define GL_CURRENT_RASTER_TEXTURE_COORDS 0x0B06 +#define GL_CURRENT_RASTER_POSITION 0x0B07 +#define GL_CURRENT_RASTER_POSITION_VALID 0x0B08 +#define GL_CURRENT_RASTER_DISTANCE 0x0B09 +#define GL_POINT_SMOOTH 0x0B10 +#define GL_POINT_SIZE 0x0B11 +#define GL_POINT_SIZE_RANGE 0x0B12 +#define GL_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_LINE_SMOOTH 0x0B20 +#define GL_LINE_WIDTH 0x0B21 +#define GL_LINE_WIDTH_RANGE 0x0B22 +#define GL_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_LINE_STIPPLE 0x0B24 +#define GL_LINE_STIPPLE_PATTERN 0x0B25 +#define GL_LINE_STIPPLE_REPEAT 0x0B26 +#define GL_LIST_MODE 0x0B30 +#define GL_MAX_LIST_NESTING 0x0B31 +#define GL_LIST_BASE 0x0B32 +#define GL_LIST_INDEX 0x0B33 +#define GL_POLYGON_MODE 0x0B40 +#define GL_POLYGON_SMOOTH 0x0B41 +#define GL_POLYGON_STIPPLE 0x0B42 +#define GL_EDGE_FLAG 0x0B43 +#define GL_CULL_FACE 0x0B44 +#define GL_CULL_FACE_MODE 0x0B45 +#define GL_FRONT_FACE 0x0B46 +#define GL_LIGHTING 0x0B50 +#define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51 +#define GL_LIGHT_MODEL_TWO_SIDE 0x0B52 +#define GL_LIGHT_MODEL_AMBIENT 0x0B53 +#define GL_SHADE_MODEL 0x0B54 +#define GL_COLOR_MATERIAL_FACE 0x0B55 +#define GL_COLOR_MATERIAL_PARAMETER 0x0B56 +#define GL_COLOR_MATERIAL 0x0B57 +#define GL_FOG 0x0B60 +#define GL_FOG_INDEX 0x0B61 +#define GL_FOG_DENSITY 0x0B62 +#define GL_FOG_START 0x0B63 +#define GL_FOG_END 0x0B64 +#define GL_FOG_MODE 0x0B65 +#define GL_FOG_COLOR 0x0B66 +#define GL_DEPTH_RANGE 0x0B70 +#define GL_DEPTH_TEST 0x0B71 +#define GL_DEPTH_WRITEMASK 0x0B72 +#define GL_DEPTH_CLEAR_VALUE 0x0B73 +#define GL_DEPTH_FUNC 0x0B74 +#define GL_ACCUM_CLEAR_VALUE 0x0B80 +#define GL_STENCIL_TEST 0x0B90 +#define GL_STENCIL_CLEAR_VALUE 0x0B91 +#define GL_STENCIL_FUNC 0x0B92 +#define GL_STENCIL_VALUE_MASK 0x0B93 +#define GL_STENCIL_FAIL 0x0B94 +#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 +#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 +#define GL_STENCIL_REF 0x0B97 +#define GL_STENCIL_WRITEMASK 0x0B98 +#define GL_MATRIX_MODE 0x0BA0 +#define GL_NORMALIZE 0x0BA1 +#define GL_VIEWPORT 0x0BA2 +#define GL_MODELVIEW_STACK_DEPTH 0x0BA3 +#define GL_PROJECTION_STACK_DEPTH 0x0BA4 +#define GL_TEXTURE_STACK_DEPTH 0x0BA5 +#define GL_MODELVIEW_MATRIX 0x0BA6 +#define GL_PROJECTION_MATRIX 0x0BA7 +#define GL_TEXTURE_MATRIX 0x0BA8 +#define GL_ATTRIB_STACK_DEPTH 0x0BB0 +#define GL_CLIENT_ATTRIB_STACK_DEPTH 0x0BB1 +#define GL_ALPHA_TEST 0x0BC0 +#define GL_ALPHA_TEST_FUNC 0x0BC1 +#define GL_ALPHA_TEST_REF 0x0BC2 +#define GL_DITHER 0x0BD0 +#define GL_BLEND_DST 0x0BE0 +#define GL_BLEND_SRC 0x0BE1 +#define GL_BLEND 0x0BE2 +#define GL_LOGIC_OP_MODE 0x0BF0 +#define GL_INDEX_LOGIC_OP 0x0BF1 +#define GL_COLOR_LOGIC_OP 0x0BF2 +#define GL_AUX_BUFFERS 0x0C00 +#define GL_DRAW_BUFFER 0x0C01 +#define GL_READ_BUFFER 0x0C02 +#define GL_SCISSOR_BOX 0x0C10 +#define GL_SCISSOR_TEST 0x0C11 +#define GL_INDEX_CLEAR_VALUE 0x0C20 +#define GL_INDEX_WRITEMASK 0x0C21 +#define GL_COLOR_CLEAR_VALUE 0x0C22 +#define GL_COLOR_WRITEMASK 0x0C23 +#define GL_INDEX_MODE 0x0C30 +#define GL_RGBA_MODE 0x0C31 +#define GL_DOUBLEBUFFER 0x0C32 +#define GL_STEREO 0x0C33 +#define GL_RENDER_MODE 0x0C40 +#define GL_PERSPECTIVE_CORRECTION_HINT 0x0C50 +#define GL_POINT_SMOOTH_HINT 0x0C51 +#define GL_LINE_SMOOTH_HINT 0x0C52 +#define GL_POLYGON_SMOOTH_HINT 0x0C53 +#define GL_FOG_HINT 0x0C54 +#define GL_TEXTURE_GEN_S 0x0C60 +#define GL_TEXTURE_GEN_T 0x0C61 +#define GL_TEXTURE_GEN_R 0x0C62 +#define GL_TEXTURE_GEN_Q 0x0C63 +#define GL_PIXEL_MAP_I_TO_I 0x0C70 +#define GL_PIXEL_MAP_S_TO_S 0x0C71 +#define GL_PIXEL_MAP_I_TO_R 0x0C72 +#define GL_PIXEL_MAP_I_TO_G 0x0C73 +#define GL_PIXEL_MAP_I_TO_B 0x0C74 +#define GL_PIXEL_MAP_I_TO_A 0x0C75 +#define GL_PIXEL_MAP_R_TO_R 0x0C76 +#define GL_PIXEL_MAP_G_TO_G 0x0C77 +#define GL_PIXEL_MAP_B_TO_B 0x0C78 +#define GL_PIXEL_MAP_A_TO_A 0x0C79 +#define GL_PIXEL_MAP_I_TO_I_SIZE 0x0CB0 +#define GL_PIXEL_MAP_S_TO_S_SIZE 0x0CB1 +#define GL_PIXEL_MAP_I_TO_R_SIZE 0x0CB2 +#define GL_PIXEL_MAP_I_TO_G_SIZE 0x0CB3 +#define GL_PIXEL_MAP_I_TO_B_SIZE 0x0CB4 +#define GL_PIXEL_MAP_I_TO_A_SIZE 0x0CB5 +#define GL_PIXEL_MAP_R_TO_R_SIZE 0x0CB6 +#define GL_PIXEL_MAP_G_TO_G_SIZE 0x0CB7 +#define GL_PIXEL_MAP_B_TO_B_SIZE 0x0CB8 +#define GL_PIXEL_MAP_A_TO_A_SIZE 0x0CB9 +#define GL_UNPACK_SWAP_BYTES 0x0CF0 +#define GL_UNPACK_LSB_FIRST 0x0CF1 +#define GL_UNPACK_ROW_LENGTH 0x0CF2 +#define GL_UNPACK_SKIP_ROWS 0x0CF3 +#define GL_UNPACK_SKIP_PIXELS 0x0CF4 +#define GL_UNPACK_ALIGNMENT 0x0CF5 +#define GL_PACK_SWAP_BYTES 0x0D00 +#define GL_PACK_LSB_FIRST 0x0D01 +#define GL_PACK_ROW_LENGTH 0x0D02 +#define GL_PACK_SKIP_ROWS 0x0D03 +#define GL_PACK_SKIP_PIXELS 0x0D04 +#define GL_PACK_ALIGNMENT 0x0D05 +#define GL_MAP_COLOR 0x0D10 +#define GL_MAP_STENCIL 0x0D11 +#define GL_INDEX_SHIFT 0x0D12 +#define GL_INDEX_OFFSET 0x0D13 +#define GL_RED_SCALE 0x0D14 +#define GL_RED_BIAS 0x0D15 +#define GL_ZOOM_X 0x0D16 +#define GL_ZOOM_Y 0x0D17 +#define GL_GREEN_SCALE 0x0D18 +#define GL_GREEN_BIAS 0x0D19 +#define GL_BLUE_SCALE 0x0D1A +#define GL_BLUE_BIAS 0x0D1B +#define GL_ALPHA_SCALE 0x0D1C +#define GL_ALPHA_BIAS 0x0D1D +#define GL_DEPTH_SCALE 0x0D1E +#define GL_DEPTH_BIAS 0x0D1F +#define GL_MAX_EVAL_ORDER 0x0D30 +#define GL_MAX_LIGHTS 0x0D31 +#define GL_MAX_CLIP_PLANES 0x0D32 +#define GL_MAX_TEXTURE_SIZE 0x0D33 +#define GL_MAX_PIXEL_MAP_TABLE 0x0D34 +#define GL_MAX_ATTRIB_STACK_DEPTH 0x0D35 +#define GL_MAX_MODELVIEW_STACK_DEPTH 0x0D36 +#define GL_MAX_NAME_STACK_DEPTH 0x0D37 +#define GL_MAX_PROJECTION_STACK_DEPTH 0x0D38 +#define GL_MAX_TEXTURE_STACK_DEPTH 0x0D39 +#define GL_MAX_VIEWPORT_DIMS 0x0D3A +#define GL_MAX_CLIENT_ATTRIB_STACK_DEPTH 0x0D3B +#define GL_SUBPIXEL_BITS 0x0D50 +#define GL_INDEX_BITS 0x0D51 +#define GL_RED_BITS 0x0D52 +#define GL_GREEN_BITS 0x0D53 +#define GL_BLUE_BITS 0x0D54 +#define GL_ALPHA_BITS 0x0D55 +#define GL_DEPTH_BITS 0x0D56 +#define GL_STENCIL_BITS 0x0D57 +#define GL_ACCUM_RED_BITS 0x0D58 +#define GL_ACCUM_GREEN_BITS 0x0D59 +#define GL_ACCUM_BLUE_BITS 0x0D5A +#define GL_ACCUM_ALPHA_BITS 0x0D5B +#define GL_NAME_STACK_DEPTH 0x0D70 +#define GL_AUTO_NORMAL 0x0D80 +#define GL_MAP1_COLOR_4 0x0D90 +#define GL_MAP1_INDEX 0x0D91 +#define GL_MAP1_NORMAL 0x0D92 +#define GL_MAP1_TEXTURE_COORD_1 0x0D93 +#define GL_MAP1_TEXTURE_COORD_2 0x0D94 +#define GL_MAP1_TEXTURE_COORD_3 0x0D95 +#define GL_MAP1_TEXTURE_COORD_4 0x0D96 +#define GL_MAP1_VERTEX_3 0x0D97 +#define GL_MAP1_VERTEX_4 0x0D98 +#define GL_MAP2_COLOR_4 0x0DB0 +#define GL_MAP2_INDEX 0x0DB1 +#define GL_MAP2_NORMAL 0x0DB2 +#define GL_MAP2_TEXTURE_COORD_1 0x0DB3 +#define GL_MAP2_TEXTURE_COORD_2 0x0DB4 +#define GL_MAP2_TEXTURE_COORD_3 0x0DB5 +#define GL_MAP2_TEXTURE_COORD_4 0x0DB6 +#define GL_MAP2_VERTEX_3 0x0DB7 +#define GL_MAP2_VERTEX_4 0x0DB8 +#define GL_MAP1_GRID_DOMAIN 0x0DD0 +#define GL_MAP1_GRID_SEGMENTS 0x0DD1 +#define GL_MAP2_GRID_DOMAIN 0x0DD2 +#define GL_MAP2_GRID_SEGMENTS 0x0DD3 +#define GL_TEXTURE_1D 0x0DE0 +#define GL_TEXTURE_2D 0x0DE1 +#define GL_FEEDBACK_BUFFER_POINTER 0x0DF0 +#define GL_FEEDBACK_BUFFER_SIZE 0x0DF1 +#define GL_FEEDBACK_BUFFER_TYPE 0x0DF2 +#define GL_SELECTION_BUFFER_POINTER 0x0DF3 +#define GL_SELECTION_BUFFER_SIZE 0x0DF4 +#define GL_TEXTURE_WIDTH 0x1000 +#define GL_TEXTURE_HEIGHT 0x1001 +#define GL_TEXTURE_INTERNAL_FORMAT 0x1003 +#define GL_TEXTURE_BORDER_COLOR 0x1004 +#define GL_TEXTURE_BORDER 0x1005 +#define GL_DONT_CARE 0x1100 +#define GL_FASTEST 0x1101 +#define GL_NICEST 0x1102 +#define GL_LIGHT0 0x4000 +#define GL_LIGHT1 0x4001 +#define GL_LIGHT2 0x4002 +#define GL_LIGHT3 0x4003 +#define GL_LIGHT4 0x4004 +#define GL_LIGHT5 0x4005 +#define GL_LIGHT6 0x4006 +#define GL_LIGHT7 0x4007 +#define GL_AMBIENT 0x1200 +#define GL_DIFFUSE 0x1201 +#define GL_SPECULAR 0x1202 +#define GL_POSITION 0x1203 +#define GL_SPOT_DIRECTION 0x1204 +#define GL_SPOT_EXPONENT 0x1205 +#define GL_SPOT_CUTOFF 0x1206 +#define GL_CONSTANT_ATTENUATION 0x1207 +#define GL_LINEAR_ATTENUATION 0x1208 +#define GL_QUADRATIC_ATTENUATION 0x1209 +#define GL_COMPILE 0x1300 +#define GL_COMPILE_AND_EXECUTE 0x1301 +#define GL_CLEAR 0x1500 +#define GL_AND 0x1501 +#define GL_AND_REVERSE 0x1502 +#define GL_COPY 0x1503 +#define GL_AND_INVERTED 0x1504 +#define GL_NOOP 0x1505 +#define GL_XOR 0x1506 +#define GL_OR 0x1507 +#define GL_NOR 0x1508 +#define GL_EQUIV 0x1509 +#define GL_INVERT 0x150A +#define GL_OR_REVERSE 0x150B +#define GL_COPY_INVERTED 0x150C +#define GL_OR_INVERTED 0x150D +#define GL_NAND 0x150E +#define GL_SET 0x150F +#define GL_EMISSION 0x1600 +#define GL_SHININESS 0x1601 +#define GL_AMBIENT_AND_DIFFUSE 0x1602 +#define GL_COLOR_INDEXES 0x1603 +#define GL_MODELVIEW 0x1700 +#define GL_PROJECTION 0x1701 +#define GL_TEXTURE 0x1702 +#define GL_COLOR 0x1800 +#define GL_DEPTH 0x1801 +#define GL_STENCIL 0x1802 +#define GL_COLOR_INDEX 0x1900 +#define GL_STENCIL_INDEX 0x1901 +#define GL_DEPTH_COMPONENT 0x1902 +#define GL_RED 0x1903 +#define GL_GREEN 0x1904 +#define GL_BLUE 0x1905 +#define GL_ALPHA 0x1906 +#define GL_RGB 0x1907 +#define GL_RGBA 0x1908 +#define GL_LUMINANCE 0x1909 +#define GL_LUMINANCE_ALPHA 0x190A +#define GL_BITMAP 0x1A00 +#define GL_POINT 0x1B00 +#define GL_LINE 0x1B01 +#define GL_FILL 0x1B02 +#define GL_RENDER 0x1C00 +#define GL_FEEDBACK 0x1C01 +#define GL_SELECT 0x1C02 +#define GL_FLAT 0x1D00 +#define GL_SMOOTH 0x1D01 +#define GL_KEEP 0x1E00 +#define GL_REPLACE 0x1E01 +#define GL_INCR 0x1E02 +#define GL_DECR 0x1E03 +#define GL_VENDOR 0x1F00 +#define GL_RENDERER 0x1F01 +#define GL_VERSION 0x1F02 +#define GL_EXTENSIONS 0x1F03 +#define GL_S 0x2000 +#define GL_T 0x2001 +#define GL_R 0x2002 +#define GL_Q 0x2003 +#define GL_MODULATE 0x2100 +#define GL_DECAL 0x2101 +#define GL_TEXTURE_ENV_MODE 0x2200 +#define GL_TEXTURE_ENV_COLOR 0x2201 +#define GL_TEXTURE_ENV 0x2300 +#define GL_EYE_LINEAR 0x2400 +#define GL_OBJECT_LINEAR 0x2401 +#define GL_SPHERE_MAP 0x2402 +#define GL_TEXTURE_GEN_MODE 0x2500 +#define GL_OBJECT_PLANE 0x2501 +#define GL_EYE_PLANE 0x2502 +#define GL_NEAREST 0x2600 +#define GL_LINEAR 0x2601 +#define GL_NEAREST_MIPMAP_NEAREST 0x2700 +#define GL_LINEAR_MIPMAP_NEAREST 0x2701 +#define GL_NEAREST_MIPMAP_LINEAR 0x2702 +#define GL_LINEAR_MIPMAP_LINEAR 0x2703 +#define GL_TEXTURE_MAG_FILTER 0x2800 +#define GL_TEXTURE_MIN_FILTER 0x2801 +#define GL_TEXTURE_WRAP_S 0x2802 +#define GL_TEXTURE_WRAP_T 0x2803 +#define GL_CLAMP 0x2900 +#define GL_REPEAT 0x2901 +#define GL_CLIENT_PIXEL_STORE_BIT 0x00000001 +#define GL_CLIENT_VERTEX_ARRAY_BIT 0x00000002 +#define GL_CLIENT_ALL_ATTRIB_BITS 0xffffffff +#define GL_POLYGON_OFFSET_FACTOR 0x8038 +#define GL_POLYGON_OFFSET_UNITS 0x2A00 +#define GL_POLYGON_OFFSET_POINT 0x2A01 +#define GL_POLYGON_OFFSET_LINE 0x2A02 +#define GL_POLYGON_OFFSET_FILL 0x8037 +#define GL_ALPHA4 0x803B +#define GL_ALPHA8 0x803C +#define GL_ALPHA12 0x803D +#define GL_ALPHA16 0x803E +#define GL_LUMINANCE4 0x803F +#define GL_LUMINANCE8 0x8040 +#define GL_LUMINANCE12 0x8041 +#define GL_LUMINANCE16 0x8042 +#define GL_LUMINANCE4_ALPHA4 0x8043 +#define GL_LUMINANCE6_ALPHA2 0x8044 +#define GL_LUMINANCE8_ALPHA8 0x8045 +#define GL_LUMINANCE12_ALPHA4 0x8046 +#define GL_LUMINANCE12_ALPHA12 0x8047 +#define GL_LUMINANCE16_ALPHA16 0x8048 +#define GL_INTENSITY 0x8049 +#define GL_INTENSITY4 0x804A +#define GL_INTENSITY8 0x804B +#define GL_INTENSITY12 0x804C +#define GL_INTENSITY16 0x804D +#define GL_R3_G3_B2 0x2A10 +#define GL_RGB4 0x804F +#define GL_RGB5 0x8050 +#define GL_RGB8 0x8051 +#define GL_RGB10 0x8052 +#define GL_RGB12 0x8053 +#define GL_RGB16 0x8054 +#define GL_RGBA2 0x8055 +#define GL_RGBA4 0x8056 +#define GL_RGB5_A1 0x8057 +#define GL_RGBA8 0x8058 +#define GL_RGB10_A2 0x8059 +#define GL_RGBA12 0x805A +#define GL_RGBA16 0x805B +#define GL_TEXTURE_RED_SIZE 0x805C +#define GL_TEXTURE_GREEN_SIZE 0x805D +#define GL_TEXTURE_BLUE_SIZE 0x805E +#define GL_TEXTURE_ALPHA_SIZE 0x805F +#define GL_TEXTURE_LUMINANCE_SIZE 0x8060 +#define GL_TEXTURE_INTENSITY_SIZE 0x8061 +#define GL_PROXY_TEXTURE_1D 0x8063 +#define GL_PROXY_TEXTURE_2D 0x8064 +#define GL_TEXTURE_PRIORITY 0x8066 +#define GL_TEXTURE_RESIDENT 0x8067 +#define GL_TEXTURE_BINDING_1D 0x8068 +#define GL_TEXTURE_BINDING_2D 0x8069 +#define GL_VERTEX_ARRAY 0x8074 +#define GL_NORMAL_ARRAY 0x8075 +#define GL_COLOR_ARRAY 0x8076 +#define GL_INDEX_ARRAY 0x8077 +#define GL_TEXTURE_COORD_ARRAY 0x8078 +#define GL_EDGE_FLAG_ARRAY 0x8079 +#define GL_VERTEX_ARRAY_SIZE 0x807A +#define GL_VERTEX_ARRAY_TYPE 0x807B +#define GL_VERTEX_ARRAY_STRIDE 0x807C +#define GL_NORMAL_ARRAY_TYPE 0x807E +#define GL_NORMAL_ARRAY_STRIDE 0x807F +#define GL_COLOR_ARRAY_SIZE 0x8081 +#define GL_COLOR_ARRAY_TYPE 0x8082 +#define GL_COLOR_ARRAY_STRIDE 0x8083 +#define GL_INDEX_ARRAY_TYPE 0x8085 +#define GL_INDEX_ARRAY_STRIDE 0x8086 +#define GL_TEXTURE_COORD_ARRAY_SIZE 0x8088 +#define GL_TEXTURE_COORD_ARRAY_TYPE 0x8089 +#define GL_TEXTURE_COORD_ARRAY_STRIDE 0x808A +#define GL_EDGE_FLAG_ARRAY_STRIDE 0x808C +#define GL_VERTEX_ARRAY_POINTER 0x808E +#define GL_NORMAL_ARRAY_POINTER 0x808F +#define GL_COLOR_ARRAY_POINTER 0x8090 +#define GL_INDEX_ARRAY_POINTER 0x8091 +#define GL_TEXTURE_COORD_ARRAY_POINTER 0x8092 +#define GL_EDGE_FLAG_ARRAY_POINTER 0x8093 +#define GL_V2F 0x2A20 +#define GL_V3F 0x2A21 +#define GL_C4UB_V2F 0x2A22 +#define GL_C4UB_V3F 0x2A23 +#define GL_C3F_V3F 0x2A24 +#define GL_N3F_V3F 0x2A25 +#define GL_C4F_N3F_V3F 0x2A26 +#define GL_T2F_V3F 0x2A27 +#define GL_T4F_V4F 0x2A28 +#define GL_T2F_C4UB_V3F 0x2A29 +#define GL_T2F_C3F_V3F 0x2A2A +#define GL_T2F_N3F_V3F 0x2A2B +#define GL_T2F_C4F_N3F_V3F 0x2A2C +#define GL_T4F_C4F_N3F_V4F 0x2A2D +#define GL_LOGIC_OP GL_INDEX_LOGIC_OP +#define GL_TEXTURE_COMPONENTS GL_TEXTURE_INTERNAL_FORMAT +#define GL_COLOR_INDEX1_EXT 0x80E2 +#define GL_COLOR_INDEX2_EXT 0x80E3 +#define GL_COLOR_INDEX4_EXT 0x80E4 +#define GL_COLOR_INDEX8_EXT 0x80E5 +#define GL_COLOR_INDEX12_EXT 0x80E6 +#define GL_COLOR_INDEX16_EXT 0x80E7 + +GLAPI void GLAPIENTRY glAccum (GLenum op, GLfloat value); +GLAPI void GLAPIENTRY glAlphaFunc (GLenum func, GLclampf ref); +GLAPI GLboolean GLAPIENTRY glAreTexturesResident (GLsizei n, const GLuint *textures, GLboolean *residences); +GLAPI void GLAPIENTRY glArrayElement (GLint i); +GLAPI void GLAPIENTRY glBegin (GLenum mode); +GLAPI void GLAPIENTRY glBindTexture (GLenum target, GLuint texture); +GLAPI void GLAPIENTRY glBitmap (GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap); +GLAPI void GLAPIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor); +GLAPI void GLAPIENTRY glCallList (GLuint list); +GLAPI void GLAPIENTRY glCallLists (GLsizei n, GLenum type, const GLvoid *lists); +GLAPI void GLAPIENTRY glClear (GLbitfield mask); +GLAPI void GLAPIENTRY glClearAccum (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +GLAPI void GLAPIENTRY glClearColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +GLAPI void GLAPIENTRY glClearDepth (GLclampd depth); +GLAPI void GLAPIENTRY glClearIndex (GLfloat c); +GLAPI void GLAPIENTRY glClearStencil (GLint s); +GLAPI void GLAPIENTRY glClipPlane (GLenum plane, const GLdouble *equation); +GLAPI void GLAPIENTRY glColor3b (GLbyte red, GLbyte green, GLbyte blue); +GLAPI void GLAPIENTRY glColor3bv (const GLbyte *v); +GLAPI void GLAPIENTRY glColor3d (GLdouble red, GLdouble green, GLdouble blue); +GLAPI void GLAPIENTRY glColor3dv (const GLdouble *v); +GLAPI void GLAPIENTRY glColor3f (GLfloat red, GLfloat green, GLfloat blue); +GLAPI void GLAPIENTRY glColor3fv (const GLfloat *v); +GLAPI void GLAPIENTRY glColor3i (GLint red, GLint green, GLint blue); +GLAPI void GLAPIENTRY glColor3iv (const GLint *v); +GLAPI void GLAPIENTRY glColor3s (GLshort red, GLshort green, GLshort blue); +GLAPI void GLAPIENTRY glColor3sv (const GLshort *v); +GLAPI void GLAPIENTRY glColor3ub (GLubyte red, GLubyte green, GLubyte blue); +GLAPI void GLAPIENTRY glColor3ubv (const GLubyte *v); +GLAPI void GLAPIENTRY glColor3ui (GLuint red, GLuint green, GLuint blue); +GLAPI void GLAPIENTRY glColor3uiv (const GLuint *v); +GLAPI void GLAPIENTRY glColor3us (GLushort red, GLushort green, GLushort blue); +GLAPI void GLAPIENTRY glColor3usv (const GLushort *v); +GLAPI void GLAPIENTRY glColor4b (GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha); +GLAPI void GLAPIENTRY glColor4bv (const GLbyte *v); +GLAPI void GLAPIENTRY glColor4d (GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha); +GLAPI void GLAPIENTRY glColor4dv (const GLdouble *v); +GLAPI void GLAPIENTRY glColor4f (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +GLAPI void GLAPIENTRY glColor4fv (const GLfloat *v); +GLAPI void GLAPIENTRY glColor4i (GLint red, GLint green, GLint blue, GLint alpha); +GLAPI void GLAPIENTRY glColor4iv (const GLint *v); +GLAPI void GLAPIENTRY glColor4s (GLshort red, GLshort green, GLshort blue, GLshort alpha); +GLAPI void GLAPIENTRY glColor4sv (const GLshort *v); +GLAPI void GLAPIENTRY glColor4ub (GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha); +GLAPI void GLAPIENTRY glColor4ubv (const GLubyte *v); +GLAPI void GLAPIENTRY glColor4ui (GLuint red, GLuint green, GLuint blue, GLuint alpha); +GLAPI void GLAPIENTRY glColor4uiv (const GLuint *v); +GLAPI void GLAPIENTRY glColor4us (GLushort red, GLushort green, GLushort blue, GLushort alpha); +GLAPI void GLAPIENTRY glColor4usv (const GLushort *v); +GLAPI void GLAPIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +GLAPI void GLAPIENTRY glColorMaterial (GLenum face, GLenum mode); +GLAPI void GLAPIENTRY glColorPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +GLAPI void GLAPIENTRY glCopyPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum type); +GLAPI void GLAPIENTRY glCopyTexImage1D (GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border); +GLAPI void GLAPIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +GLAPI void GLAPIENTRY glCopyTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +GLAPI void GLAPIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI void GLAPIENTRY glCullFace (GLenum mode); +GLAPI void GLAPIENTRY glDeleteLists (GLuint list, GLsizei range); +GLAPI void GLAPIENTRY glDeleteTextures (GLsizei n, const GLuint *textures); +GLAPI void GLAPIENTRY glDepthFunc (GLenum func); +GLAPI void GLAPIENTRY glDepthMask (GLboolean flag); +GLAPI void GLAPIENTRY glDepthRange (GLclampd zNear, GLclampd zFar); +GLAPI void GLAPIENTRY glDisable (GLenum cap); +GLAPI void GLAPIENTRY glDisableClientState (GLenum array); +GLAPI void GLAPIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count); +GLAPI void GLAPIENTRY glDrawBuffer (GLenum mode); +GLAPI void GLAPIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices); +GLAPI void GLAPIENTRY glDrawPixels (GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); +GLAPI void GLAPIENTRY glEdgeFlag (GLboolean flag); +GLAPI void GLAPIENTRY glEdgeFlagPointer (GLsizei stride, const GLvoid *pointer); +GLAPI void GLAPIENTRY glEdgeFlagv (const GLboolean *flag); +GLAPI void GLAPIENTRY glEnable (GLenum cap); +GLAPI void GLAPIENTRY glEnableClientState (GLenum array); +GLAPI void GLAPIENTRY glEnd (void); +GLAPI void GLAPIENTRY glEndList (void); +GLAPI void GLAPIENTRY glEvalCoord1d (GLdouble u); +GLAPI void GLAPIENTRY glEvalCoord1dv (const GLdouble *u); +GLAPI void GLAPIENTRY glEvalCoord1f (GLfloat u); +GLAPI void GLAPIENTRY glEvalCoord1fv (const GLfloat *u); +GLAPI void GLAPIENTRY glEvalCoord2d (GLdouble u, GLdouble v); +GLAPI void GLAPIENTRY glEvalCoord2dv (const GLdouble *u); +GLAPI void GLAPIENTRY glEvalCoord2f (GLfloat u, GLfloat v); +GLAPI void GLAPIENTRY glEvalCoord2fv (const GLfloat *u); +GLAPI void GLAPIENTRY glEvalMesh1 (GLenum mode, GLint i1, GLint i2); +GLAPI void GLAPIENTRY glEvalMesh2 (GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2); +GLAPI void GLAPIENTRY glEvalPoint1 (GLint i); +GLAPI void GLAPIENTRY glEvalPoint2 (GLint i, GLint j); +GLAPI void GLAPIENTRY glFeedbackBuffer (GLsizei size, GLenum type, GLfloat *buffer); +GLAPI void GLAPIENTRY glFinish (void); +GLAPI void GLAPIENTRY glFlush (void); +GLAPI void GLAPIENTRY glFogf (GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glFogfv (GLenum pname, const GLfloat *params); +GLAPI void GLAPIENTRY glFogi (GLenum pname, GLint param); +GLAPI void GLAPIENTRY glFogiv (GLenum pname, const GLint *params); +GLAPI void GLAPIENTRY glFrontFace (GLenum mode); +GLAPI void GLAPIENTRY glFrustum (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +GLAPI GLuint GLAPIENTRY glGenLists (GLsizei range); +GLAPI void GLAPIENTRY glGenTextures (GLsizei n, GLuint *textures); +GLAPI void GLAPIENTRY glGetBooleanv (GLenum pname, GLboolean *params); +GLAPI void GLAPIENTRY glGetClipPlane (GLenum plane, GLdouble *equation); +GLAPI void GLAPIENTRY glGetDoublev (GLenum pname, GLdouble *params); +GLAPI GLenum GLAPIENTRY glGetError (void); +GLAPI void GLAPIENTRY glGetFloatv (GLenum pname, GLfloat *params); +GLAPI void GLAPIENTRY glGetIntegerv (GLenum pname, GLint *params); +GLAPI void GLAPIENTRY glGetLightfv (GLenum light, GLenum pname, GLfloat *params); +GLAPI void GLAPIENTRY glGetLightiv (GLenum light, GLenum pname, GLint *params); +GLAPI void GLAPIENTRY glGetMapdv (GLenum target, GLenum query, GLdouble *v); +GLAPI void GLAPIENTRY glGetMapfv (GLenum target, GLenum query, GLfloat *v); +GLAPI void GLAPIENTRY glGetMapiv (GLenum target, GLenum query, GLint *v); +GLAPI void GLAPIENTRY glGetMaterialfv (GLenum face, GLenum pname, GLfloat *params); +GLAPI void GLAPIENTRY glGetMaterialiv (GLenum face, GLenum pname, GLint *params); +GLAPI void GLAPIENTRY glGetPixelMapfv (GLenum map, GLfloat *values); +GLAPI void GLAPIENTRY glGetPixelMapuiv (GLenum map, GLuint *values); +GLAPI void GLAPIENTRY glGetPixelMapusv (GLenum map, GLushort *values); +GLAPI void GLAPIENTRY glGetPointerv (GLenum pname, GLvoid* *params); +GLAPI void GLAPIENTRY glGetPolygonStipple (GLubyte *mask); +GLAPI const GLubyte * GLAPIENTRY glGetString (GLenum name); +GLAPI void GLAPIENTRY glGetTexEnvfv (GLenum target, GLenum pname, GLfloat *params); +GLAPI void GLAPIENTRY glGetTexEnviv (GLenum target, GLenum pname, GLint *params); +GLAPI void GLAPIENTRY glGetTexGendv (GLenum coord, GLenum pname, GLdouble *params); +GLAPI void GLAPIENTRY glGetTexGenfv (GLenum coord, GLenum pname, GLfloat *params); +GLAPI void GLAPIENTRY glGetTexGeniv (GLenum coord, GLenum pname, GLint *params); +GLAPI void GLAPIENTRY glGetTexImage (GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels); +GLAPI void GLAPIENTRY glGetTexLevelParameterfv (GLenum target, GLint level, GLenum pname, GLfloat *params); +GLAPI void GLAPIENTRY glGetTexLevelParameteriv (GLenum target, GLint level, GLenum pname, GLint *params); +GLAPI void GLAPIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat *params); +GLAPI void GLAPIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint *params); +GLAPI void GLAPIENTRY glHint (GLenum target, GLenum mode); +GLAPI void GLAPIENTRY glIndexMask (GLuint mask); +GLAPI void GLAPIENTRY glIndexPointer (GLenum type, GLsizei stride, const GLvoid *pointer); +GLAPI void GLAPIENTRY glIndexd (GLdouble c); +GLAPI void GLAPIENTRY glIndexdv (const GLdouble *c); +GLAPI void GLAPIENTRY glIndexf (GLfloat c); +GLAPI void GLAPIENTRY glIndexfv (const GLfloat *c); +GLAPI void GLAPIENTRY glIndexi (GLint c); +GLAPI void GLAPIENTRY glIndexiv (const GLint *c); +GLAPI void GLAPIENTRY glIndexs (GLshort c); +GLAPI void GLAPIENTRY glIndexsv (const GLshort *c); +GLAPI void GLAPIENTRY glIndexub (GLubyte c); +GLAPI void GLAPIENTRY glIndexubv (const GLubyte *c); +GLAPI void GLAPIENTRY glInitNames (void); +GLAPI void GLAPIENTRY glInterleavedArrays (GLenum format, GLsizei stride, const GLvoid *pointer); +GLAPI GLboolean GLAPIENTRY glIsEnabled (GLenum cap); +GLAPI GLboolean GLAPIENTRY glIsList (GLuint list); +GLAPI GLboolean GLAPIENTRY glIsTexture (GLuint texture); +GLAPI void GLAPIENTRY glLightModelf (GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glLightModelfv (GLenum pname, const GLfloat *params); +GLAPI void GLAPIENTRY glLightModeli (GLenum pname, GLint param); +GLAPI void GLAPIENTRY glLightModeliv (GLenum pname, const GLint *params); +GLAPI void GLAPIENTRY glLightf (GLenum light, GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glLightfv (GLenum light, GLenum pname, const GLfloat *params); +GLAPI void GLAPIENTRY glLighti (GLenum light, GLenum pname, GLint param); +GLAPI void GLAPIENTRY glLightiv (GLenum light, GLenum pname, const GLint *params); +GLAPI void GLAPIENTRY glLineStipple (GLint factor, GLushort pattern); +GLAPI void GLAPIENTRY glLineWidth (GLfloat width); +GLAPI void GLAPIENTRY glListBase (GLuint base); +GLAPI void GLAPIENTRY glLoadIdentity (void); +GLAPI void GLAPIENTRY glLoadMatrixd (const GLdouble *m); +GLAPI void GLAPIENTRY glLoadMatrixf (const GLfloat *m); +GLAPI void GLAPIENTRY glLoadName (GLuint name); +GLAPI void GLAPIENTRY glLogicOp (GLenum opcode); +GLAPI void GLAPIENTRY glMap1d (GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points); +GLAPI void GLAPIENTRY glMap1f (GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points); +GLAPI void GLAPIENTRY glMap2d (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points); +GLAPI void GLAPIENTRY glMap2f (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points); +GLAPI void GLAPIENTRY glMapGrid1d (GLint un, GLdouble u1, GLdouble u2); +GLAPI void GLAPIENTRY glMapGrid1f (GLint un, GLfloat u1, GLfloat u2); +GLAPI void GLAPIENTRY glMapGrid2d (GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2); +GLAPI void GLAPIENTRY glMapGrid2f (GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2); +GLAPI void GLAPIENTRY glMaterialf (GLenum face, GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glMaterialfv (GLenum face, GLenum pname, const GLfloat *params); +GLAPI void GLAPIENTRY glMateriali (GLenum face, GLenum pname, GLint param); +GLAPI void GLAPIENTRY glMaterialiv (GLenum face, GLenum pname, const GLint *params); +GLAPI void GLAPIENTRY glMatrixMode (GLenum mode); +GLAPI void GLAPIENTRY glMultMatrixd (const GLdouble *m); +GLAPI void GLAPIENTRY glMultMatrixf (const GLfloat *m); +GLAPI void GLAPIENTRY glNewList (GLuint list, GLenum mode); +GLAPI void GLAPIENTRY glNormal3b (GLbyte nx, GLbyte ny, GLbyte nz); +GLAPI void GLAPIENTRY glNormal3bv (const GLbyte *v); +GLAPI void GLAPIENTRY glNormal3d (GLdouble nx, GLdouble ny, GLdouble nz); +GLAPI void GLAPIENTRY glNormal3dv (const GLdouble *v); +GLAPI void GLAPIENTRY glNormal3f (GLfloat nx, GLfloat ny, GLfloat nz); +GLAPI void GLAPIENTRY glNormal3fv (const GLfloat *v); +GLAPI void GLAPIENTRY glNormal3i (GLint nx, GLint ny, GLint nz); +GLAPI void GLAPIENTRY glNormal3iv (const GLint *v); +GLAPI void GLAPIENTRY glNormal3s (GLshort nx, GLshort ny, GLshort nz); +GLAPI void GLAPIENTRY glNormal3sv (const GLshort *v); +GLAPI void GLAPIENTRY glNormalPointer (GLenum type, GLsizei stride, const GLvoid *pointer); +GLAPI void GLAPIENTRY glOrtho (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +GLAPI void GLAPIENTRY glPassThrough (GLfloat token); +GLAPI void GLAPIENTRY glPixelMapfv (GLenum map, GLsizei mapsize, const GLfloat *values); +GLAPI void GLAPIENTRY glPixelMapuiv (GLenum map, GLsizei mapsize, const GLuint *values); +GLAPI void GLAPIENTRY glPixelMapusv (GLenum map, GLsizei mapsize, const GLushort *values); +GLAPI void GLAPIENTRY glPixelStoref (GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glPixelStorei (GLenum pname, GLint param); +GLAPI void GLAPIENTRY glPixelTransferf (GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glPixelTransferi (GLenum pname, GLint param); +GLAPI void GLAPIENTRY glPixelZoom (GLfloat xfactor, GLfloat yfactor); +GLAPI void GLAPIENTRY glPointSize (GLfloat size); +GLAPI void GLAPIENTRY glPolygonMode (GLenum face, GLenum mode); +GLAPI void GLAPIENTRY glPolygonOffset (GLfloat factor, GLfloat units); +GLAPI void GLAPIENTRY glPolygonStipple (const GLubyte *mask); +GLAPI void GLAPIENTRY glPopAttrib (void); +GLAPI void GLAPIENTRY glPopClientAttrib (void); +GLAPI void GLAPIENTRY glPopMatrix (void); +GLAPI void GLAPIENTRY glPopName (void); +GLAPI void GLAPIENTRY glPrioritizeTextures (GLsizei n, const GLuint *textures, const GLclampf *priorities); +GLAPI void GLAPIENTRY glPushAttrib (GLbitfield mask); +GLAPI void GLAPIENTRY glPushClientAttrib (GLbitfield mask); +GLAPI void GLAPIENTRY glPushMatrix (void); +GLAPI void GLAPIENTRY glPushName (GLuint name); +GLAPI void GLAPIENTRY glRasterPos2d (GLdouble x, GLdouble y); +GLAPI void GLAPIENTRY glRasterPos2dv (const GLdouble *v); +GLAPI void GLAPIENTRY glRasterPos2f (GLfloat x, GLfloat y); +GLAPI void GLAPIENTRY glRasterPos2fv (const GLfloat *v); +GLAPI void GLAPIENTRY glRasterPos2i (GLint x, GLint y); +GLAPI void GLAPIENTRY glRasterPos2iv (const GLint *v); +GLAPI void GLAPIENTRY glRasterPos2s (GLshort x, GLshort y); +GLAPI void GLAPIENTRY glRasterPos2sv (const GLshort *v); +GLAPI void GLAPIENTRY glRasterPos3d (GLdouble x, GLdouble y, GLdouble z); +GLAPI void GLAPIENTRY glRasterPos3dv (const GLdouble *v); +GLAPI void GLAPIENTRY glRasterPos3f (GLfloat x, GLfloat y, GLfloat z); +GLAPI void GLAPIENTRY glRasterPos3fv (const GLfloat *v); +GLAPI void GLAPIENTRY glRasterPos3i (GLint x, GLint y, GLint z); +GLAPI void GLAPIENTRY glRasterPos3iv (const GLint *v); +GLAPI void GLAPIENTRY glRasterPos3s (GLshort x, GLshort y, GLshort z); +GLAPI void GLAPIENTRY glRasterPos3sv (const GLshort *v); +GLAPI void GLAPIENTRY glRasterPos4d (GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void GLAPIENTRY glRasterPos4dv (const GLdouble *v); +GLAPI void GLAPIENTRY glRasterPos4f (GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI void GLAPIENTRY glRasterPos4fv (const GLfloat *v); +GLAPI void GLAPIENTRY glRasterPos4i (GLint x, GLint y, GLint z, GLint w); +GLAPI void GLAPIENTRY glRasterPos4iv (const GLint *v); +GLAPI void GLAPIENTRY glRasterPos4s (GLshort x, GLshort y, GLshort z, GLshort w); +GLAPI void GLAPIENTRY glRasterPos4sv (const GLshort *v); +GLAPI void GLAPIENTRY glReadBuffer (GLenum mode); +GLAPI void GLAPIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels); +GLAPI void GLAPIENTRY glRectd (GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2); +GLAPI void GLAPIENTRY glRectdv (const GLdouble *v1, const GLdouble *v2); +GLAPI void GLAPIENTRY glRectf (GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2); +GLAPI void GLAPIENTRY glRectfv (const GLfloat *v1, const GLfloat *v2); +GLAPI void GLAPIENTRY glRecti (GLint x1, GLint y1, GLint x2, GLint y2); +GLAPI void GLAPIENTRY glRectiv (const GLint *v1, const GLint *v2); +GLAPI void GLAPIENTRY glRects (GLshort x1, GLshort y1, GLshort x2, GLshort y2); +GLAPI void GLAPIENTRY glRectsv (const GLshort *v1, const GLshort *v2); +GLAPI GLint GLAPIENTRY glRenderMode (GLenum mode); +GLAPI void GLAPIENTRY glRotated (GLdouble angle, GLdouble x, GLdouble y, GLdouble z); +GLAPI void GLAPIENTRY glRotatef (GLfloat angle, GLfloat x, GLfloat y, GLfloat z); +GLAPI void GLAPIENTRY glScaled (GLdouble x, GLdouble y, GLdouble z); +GLAPI void GLAPIENTRY glScalef (GLfloat x, GLfloat y, GLfloat z); +GLAPI void GLAPIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI void GLAPIENTRY glSelectBuffer (GLsizei size, GLuint *buffer); +GLAPI void GLAPIENTRY glShadeModel (GLenum mode); +GLAPI void GLAPIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask); +GLAPI void GLAPIENTRY glStencilMask (GLuint mask); +GLAPI void GLAPIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass); +GLAPI void GLAPIENTRY glTexCoord1d (GLdouble s); +GLAPI void GLAPIENTRY glTexCoord1dv (const GLdouble *v); +GLAPI void GLAPIENTRY glTexCoord1f (GLfloat s); +GLAPI void GLAPIENTRY glTexCoord1fv (const GLfloat *v); +GLAPI void GLAPIENTRY glTexCoord1i (GLint s); +GLAPI void GLAPIENTRY glTexCoord1iv (const GLint *v); +GLAPI void GLAPIENTRY glTexCoord1s (GLshort s); +GLAPI void GLAPIENTRY glTexCoord1sv (const GLshort *v); +GLAPI void GLAPIENTRY glTexCoord2d (GLdouble s, GLdouble t); +GLAPI void GLAPIENTRY glTexCoord2dv (const GLdouble *v); +GLAPI void GLAPIENTRY glTexCoord2f (GLfloat s, GLfloat t); +GLAPI void GLAPIENTRY glTexCoord2fv (const GLfloat *v); +GLAPI void GLAPIENTRY glTexCoord2i (GLint s, GLint t); +GLAPI void GLAPIENTRY glTexCoord2iv (const GLint *v); +GLAPI void GLAPIENTRY glTexCoord2s (GLshort s, GLshort t); +GLAPI void GLAPIENTRY glTexCoord2sv (const GLshort *v); +GLAPI void GLAPIENTRY glTexCoord3d (GLdouble s, GLdouble t, GLdouble r); +GLAPI void GLAPIENTRY glTexCoord3dv (const GLdouble *v); +GLAPI void GLAPIENTRY glTexCoord3f (GLfloat s, GLfloat t, GLfloat r); +GLAPI void GLAPIENTRY glTexCoord3fv (const GLfloat *v); +GLAPI void GLAPIENTRY glTexCoord3i (GLint s, GLint t, GLint r); +GLAPI void GLAPIENTRY glTexCoord3iv (const GLint *v); +GLAPI void GLAPIENTRY glTexCoord3s (GLshort s, GLshort t, GLshort r); +GLAPI void GLAPIENTRY glTexCoord3sv (const GLshort *v); +GLAPI void GLAPIENTRY glTexCoord4d (GLdouble s, GLdouble t, GLdouble r, GLdouble q); +GLAPI void GLAPIENTRY glTexCoord4dv (const GLdouble *v); +GLAPI void GLAPIENTRY glTexCoord4f (GLfloat s, GLfloat t, GLfloat r, GLfloat q); +GLAPI void GLAPIENTRY glTexCoord4fv (const GLfloat *v); +GLAPI void GLAPIENTRY glTexCoord4i (GLint s, GLint t, GLint r, GLint q); +GLAPI void GLAPIENTRY glTexCoord4iv (const GLint *v); +GLAPI void GLAPIENTRY glTexCoord4s (GLshort s, GLshort t, GLshort r, GLshort q); +GLAPI void GLAPIENTRY glTexCoord4sv (const GLshort *v); +GLAPI void GLAPIENTRY glTexCoordPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +GLAPI void GLAPIENTRY glTexEnvf (GLenum target, GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glTexEnvfv (GLenum target, GLenum pname, const GLfloat *params); +GLAPI void GLAPIENTRY glTexEnvi (GLenum target, GLenum pname, GLint param); +GLAPI void GLAPIENTRY glTexEnviv (GLenum target, GLenum pname, const GLint *params); +GLAPI void GLAPIENTRY glTexGend (GLenum coord, GLenum pname, GLdouble param); +GLAPI void GLAPIENTRY glTexGendv (GLenum coord, GLenum pname, const GLdouble *params); +GLAPI void GLAPIENTRY glTexGenf (GLenum coord, GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glTexGenfv (GLenum coord, GLenum pname, const GLfloat *params); +GLAPI void GLAPIENTRY glTexGeni (GLenum coord, GLenum pname, GLint param); +GLAPI void GLAPIENTRY glTexGeniv (GLenum coord, GLenum pname, const GLint *params); +GLAPI void GLAPIENTRY glTexImage1D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +GLAPI void GLAPIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +GLAPI void GLAPIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat *params); +GLAPI void GLAPIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param); +GLAPI void GLAPIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint *params); +GLAPI void GLAPIENTRY glTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels); +GLAPI void GLAPIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); +GLAPI void GLAPIENTRY glTranslated (GLdouble x, GLdouble y, GLdouble z); +GLAPI void GLAPIENTRY glTranslatef (GLfloat x, GLfloat y, GLfloat z); +GLAPI void GLAPIENTRY glVertex2d (GLdouble x, GLdouble y); +GLAPI void GLAPIENTRY glVertex2dv (const GLdouble *v); +GLAPI void GLAPIENTRY glVertex2f (GLfloat x, GLfloat y); +GLAPI void GLAPIENTRY glVertex2fv (const GLfloat *v); +GLAPI void GLAPIENTRY glVertex2i (GLint x, GLint y); +GLAPI void GLAPIENTRY glVertex2iv (const GLint *v); +GLAPI void GLAPIENTRY glVertex2s (GLshort x, GLshort y); +GLAPI void GLAPIENTRY glVertex2sv (const GLshort *v); +GLAPI void GLAPIENTRY glVertex3d (GLdouble x, GLdouble y, GLdouble z); +GLAPI void GLAPIENTRY glVertex3dv (const GLdouble *v); +GLAPI void GLAPIENTRY glVertex3f (GLfloat x, GLfloat y, GLfloat z); +GLAPI void GLAPIENTRY glVertex3fv (const GLfloat *v); +GLAPI void GLAPIENTRY glVertex3i (GLint x, GLint y, GLint z); +GLAPI void GLAPIENTRY glVertex3iv (const GLint *v); +GLAPI void GLAPIENTRY glVertex3s (GLshort x, GLshort y, GLshort z); +GLAPI void GLAPIENTRY glVertex3sv (const GLshort *v); +GLAPI void GLAPIENTRY glVertex4d (GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void GLAPIENTRY glVertex4dv (const GLdouble *v); +GLAPI void GLAPIENTRY glVertex4f (GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI void GLAPIENTRY glVertex4fv (const GLfloat *v); +GLAPI void GLAPIENTRY glVertex4i (GLint x, GLint y, GLint z, GLint w); +GLAPI void GLAPIENTRY glVertex4iv (const GLint *v); +GLAPI void GLAPIENTRY glVertex4s (GLshort x, GLshort y, GLshort z, GLshort w); +GLAPI void GLAPIENTRY glVertex4sv (const GLshort *v); +GLAPI void GLAPIENTRY glVertexPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +GLAPI void GLAPIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height); + +#define GLEW_VERSION_1_1 GLEW_GET_VAR(__GLEW_VERSION_1_1) + +#endif /* GL_VERSION_1_1 */ + +/* ---------------------------------- GLU ---------------------------------- */ + +/* this is where we can safely include GLU */ +#if defined(__APPLE__) && defined(__MACH__) +#include <OpenGL/glu.h> +#else +#include <GL/glu.h> +#endif + +/* ----------------------------- GL_VERSION_1_2 ---------------------------- */ + +#ifndef GL_VERSION_1_2 +#define GL_VERSION_1_2 1 + +#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 +#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 +#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_UNSIGNED_BYTE_3_3_2 0x8032 +#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#define GL_UNSIGNED_INT_8_8_8_8 0x8035 +#define GL_UNSIGNED_INT_10_10_10_2 0x8036 +#define GL_RESCALE_NORMAL 0x803A +#define GL_TEXTURE_BINDING_3D 0x806A +#define GL_PACK_SKIP_IMAGES 0x806B +#define GL_PACK_IMAGE_HEIGHT 0x806C +#define GL_UNPACK_SKIP_IMAGES 0x806D +#define GL_UNPACK_IMAGE_HEIGHT 0x806E +#define GL_TEXTURE_3D 0x806F +#define GL_PROXY_TEXTURE_3D 0x8070 +#define GL_TEXTURE_DEPTH 0x8071 +#define GL_TEXTURE_WRAP_R 0x8072 +#define GL_MAX_3D_TEXTURE_SIZE 0x8073 +#define GL_BGR 0x80E0 +#define GL_BGRA 0x80E1 +#define GL_MAX_ELEMENTS_VERTICES 0x80E8 +#define GL_MAX_ELEMENTS_INDICES 0x80E9 +#define GL_CLAMP_TO_EDGE 0x812F +#define GL_TEXTURE_MIN_LOD 0x813A +#define GL_TEXTURE_MAX_LOD 0x813B +#define GL_TEXTURE_BASE_LEVEL 0x813C +#define GL_TEXTURE_MAX_LEVEL 0x813D +#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8 +#define GL_SINGLE_COLOR 0x81F9 +#define GL_SEPARATE_SPECULAR_COLOR 0x81FA +#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 +#define GL_UNSIGNED_SHORT_5_6_5 0x8363 +#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 +#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 +#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 +#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 +#define GL_ALIASED_POINT_SIZE_RANGE 0x846D +#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E + +typedef void (GLAPIENTRY * PFNGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); +typedef void (GLAPIENTRY * PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); + +#define glCopyTexSubImage3D GLEW_GET_FUN(__glewCopyTexSubImage3D) +#define glDrawRangeElements GLEW_GET_FUN(__glewDrawRangeElements) +#define glTexImage3D GLEW_GET_FUN(__glewTexImage3D) +#define glTexSubImage3D GLEW_GET_FUN(__glewTexSubImage3D) + +#define GLEW_VERSION_1_2 GLEW_GET_VAR(__GLEW_VERSION_1_2) + +#endif /* GL_VERSION_1_2 */ + +/* ----------------------------- GL_VERSION_1_3 ---------------------------- */ + +#ifndef GL_VERSION_1_3 +#define GL_VERSION_1_3 1 + +#define GL_MULTISAMPLE 0x809D +#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE 0x809F +#define GL_SAMPLE_COVERAGE 0x80A0 +#define GL_SAMPLE_BUFFERS 0x80A8 +#define GL_SAMPLES 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT 0x80AB +#define GL_CLAMP_TO_BORDER 0x812D +#define GL_TEXTURE0 0x84C0 +#define GL_TEXTURE1 0x84C1 +#define GL_TEXTURE2 0x84C2 +#define GL_TEXTURE3 0x84C3 +#define GL_TEXTURE4 0x84C4 +#define GL_TEXTURE5 0x84C5 +#define GL_TEXTURE6 0x84C6 +#define GL_TEXTURE7 0x84C7 +#define GL_TEXTURE8 0x84C8 +#define GL_TEXTURE9 0x84C9 +#define GL_TEXTURE10 0x84CA +#define GL_TEXTURE11 0x84CB +#define GL_TEXTURE12 0x84CC +#define GL_TEXTURE13 0x84CD +#define GL_TEXTURE14 0x84CE +#define GL_TEXTURE15 0x84CF +#define GL_TEXTURE16 0x84D0 +#define GL_TEXTURE17 0x84D1 +#define GL_TEXTURE18 0x84D2 +#define GL_TEXTURE19 0x84D3 +#define GL_TEXTURE20 0x84D4 +#define GL_TEXTURE21 0x84D5 +#define GL_TEXTURE22 0x84D6 +#define GL_TEXTURE23 0x84D7 +#define GL_TEXTURE24 0x84D8 +#define GL_TEXTURE25 0x84D9 +#define GL_TEXTURE26 0x84DA +#define GL_TEXTURE27 0x84DB +#define GL_TEXTURE28 0x84DC +#define GL_TEXTURE29 0x84DD +#define GL_TEXTURE30 0x84DE +#define GL_TEXTURE31 0x84DF +#define GL_ACTIVE_TEXTURE 0x84E0 +#define GL_CLIENT_ACTIVE_TEXTURE 0x84E1 +#define GL_MAX_TEXTURE_UNITS 0x84E2 +#define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3 +#define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4 +#define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5 +#define GL_TRANSPOSE_COLOR_MATRIX 0x84E6 +#define GL_SUBTRACT 0x84E7 +#define GL_COMPRESSED_ALPHA 0x84E9 +#define GL_COMPRESSED_LUMINANCE 0x84EA +#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB +#define GL_COMPRESSED_INTENSITY 0x84EC +#define GL_COMPRESSED_RGB 0x84ED +#define GL_COMPRESSED_RGBA 0x84EE +#define GL_TEXTURE_COMPRESSION_HINT 0x84EF +#define GL_NORMAL_MAP 0x8511 +#define GL_REFLECTION_MAP 0x8512 +#define GL_TEXTURE_CUBE_MAP 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C +#define GL_COMBINE 0x8570 +#define GL_COMBINE_RGB 0x8571 +#define GL_COMBINE_ALPHA 0x8572 +#define GL_RGB_SCALE 0x8573 +#define GL_ADD_SIGNED 0x8574 +#define GL_INTERPOLATE 0x8575 +#define GL_CONSTANT 0x8576 +#define GL_PRIMARY_COLOR 0x8577 +#define GL_PREVIOUS 0x8578 +#define GL_SOURCE0_RGB 0x8580 +#define GL_SOURCE1_RGB 0x8581 +#define GL_SOURCE2_RGB 0x8582 +#define GL_SOURCE0_ALPHA 0x8588 +#define GL_SOURCE1_ALPHA 0x8589 +#define GL_SOURCE2_ALPHA 0x858A +#define GL_OPERAND0_RGB 0x8590 +#define GL_OPERAND1_RGB 0x8591 +#define GL_OPERAND2_RGB 0x8592 +#define GL_OPERAND0_ALPHA 0x8598 +#define GL_OPERAND1_ALPHA 0x8599 +#define GL_OPERAND2_ALPHA 0x859A +#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0 +#define GL_TEXTURE_COMPRESSED 0x86A1 +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 +#define GL_DOT3_RGB 0x86AE +#define GL_DOT3_RGBA 0x86AF +#define GL_MULTISAMPLE_BIT 0x20000000 + +typedef void (GLAPIENTRY * PFNGLACTIVETEXTUREPROC) (GLenum texture); +typedef void (GLAPIENTRY * PFNGLCLIENTACTIVETEXTUREPROC) (GLenum texture); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (GLAPIENTRY * PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint lod, GLvoid *img); +typedef void (GLAPIENTRY * PFNGLLOADTRANSPOSEMATRIXDPROC) (const GLdouble m[16]); +typedef void (GLAPIENTRY * PFNGLLOADTRANSPOSEMATRIXFPROC) (const GLfloat m[16]); +typedef void (GLAPIENTRY * PFNGLMULTTRANSPOSEMATRIXDPROC) (const GLdouble m[16]); +typedef void (GLAPIENTRY * PFNGLMULTTRANSPOSEMATRIXFPROC) (const GLfloat m[16]); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1DPROC) (GLenum target, GLdouble s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1DVPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1FPROC) (GLenum target, GLfloat s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1FVPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1IPROC) (GLenum target, GLint s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1IVPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1SPROC) (GLenum target, GLshort s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1SVPROC) (GLenum target, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2DPROC) (GLenum target, GLdouble s, GLdouble t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2DVPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2FPROC) (GLenum target, GLfloat s, GLfloat t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2FVPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2IPROC) (GLenum target, GLint s, GLint t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2IVPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2SPROC) (GLenum target, GLshort s, GLshort t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2SVPROC) (GLenum target, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3DVPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3FVPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3IPROC) (GLenum target, GLint s, GLint t, GLint r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3IVPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3SPROC) (GLenum target, GLshort s, GLshort t, GLshort r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3SVPROC) (GLenum target, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4DVPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4FVPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4IPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4IVPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4SPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4SVPROC) (GLenum target, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLSAMPLECOVERAGEPROC) (GLclampf value, GLboolean invert); + +#define glActiveTexture GLEW_GET_FUN(__glewActiveTexture) +#define glClientActiveTexture GLEW_GET_FUN(__glewClientActiveTexture) +#define glCompressedTexImage1D GLEW_GET_FUN(__glewCompressedTexImage1D) +#define glCompressedTexImage2D GLEW_GET_FUN(__glewCompressedTexImage2D) +#define glCompressedTexImage3D GLEW_GET_FUN(__glewCompressedTexImage3D) +#define glCompressedTexSubImage1D GLEW_GET_FUN(__glewCompressedTexSubImage1D) +#define glCompressedTexSubImage2D GLEW_GET_FUN(__glewCompressedTexSubImage2D) +#define glCompressedTexSubImage3D GLEW_GET_FUN(__glewCompressedTexSubImage3D) +#define glGetCompressedTexImage GLEW_GET_FUN(__glewGetCompressedTexImage) +#define glLoadTransposeMatrixd GLEW_GET_FUN(__glewLoadTransposeMatrixd) +#define glLoadTransposeMatrixf GLEW_GET_FUN(__glewLoadTransposeMatrixf) +#define glMultTransposeMatrixd GLEW_GET_FUN(__glewMultTransposeMatrixd) +#define glMultTransposeMatrixf GLEW_GET_FUN(__glewMultTransposeMatrixf) +#define glMultiTexCoord1d GLEW_GET_FUN(__glewMultiTexCoord1d) +#define glMultiTexCoord1dv GLEW_GET_FUN(__glewMultiTexCoord1dv) +#define glMultiTexCoord1f GLEW_GET_FUN(__glewMultiTexCoord1f) +#define glMultiTexCoord1fv GLEW_GET_FUN(__glewMultiTexCoord1fv) +#define glMultiTexCoord1i GLEW_GET_FUN(__glewMultiTexCoord1i) +#define glMultiTexCoord1iv GLEW_GET_FUN(__glewMultiTexCoord1iv) +#define glMultiTexCoord1s GLEW_GET_FUN(__glewMultiTexCoord1s) +#define glMultiTexCoord1sv GLEW_GET_FUN(__glewMultiTexCoord1sv) +#define glMultiTexCoord2d GLEW_GET_FUN(__glewMultiTexCoord2d) +#define glMultiTexCoord2dv GLEW_GET_FUN(__glewMultiTexCoord2dv) +#define glMultiTexCoord2f GLEW_GET_FUN(__glewMultiTexCoord2f) +#define glMultiTexCoord2fv GLEW_GET_FUN(__glewMultiTexCoord2fv) +#define glMultiTexCoord2i GLEW_GET_FUN(__glewMultiTexCoord2i) +#define glMultiTexCoord2iv GLEW_GET_FUN(__glewMultiTexCoord2iv) +#define glMultiTexCoord2s GLEW_GET_FUN(__glewMultiTexCoord2s) +#define glMultiTexCoord2sv GLEW_GET_FUN(__glewMultiTexCoord2sv) +#define glMultiTexCoord3d GLEW_GET_FUN(__glewMultiTexCoord3d) +#define glMultiTexCoord3dv GLEW_GET_FUN(__glewMultiTexCoord3dv) +#define glMultiTexCoord3f GLEW_GET_FUN(__glewMultiTexCoord3f) +#define glMultiTexCoord3fv GLEW_GET_FUN(__glewMultiTexCoord3fv) +#define glMultiTexCoord3i GLEW_GET_FUN(__glewMultiTexCoord3i) +#define glMultiTexCoord3iv GLEW_GET_FUN(__glewMultiTexCoord3iv) +#define glMultiTexCoord3s GLEW_GET_FUN(__glewMultiTexCoord3s) +#define glMultiTexCoord3sv GLEW_GET_FUN(__glewMultiTexCoord3sv) +#define glMultiTexCoord4d GLEW_GET_FUN(__glewMultiTexCoord4d) +#define glMultiTexCoord4dv GLEW_GET_FUN(__glewMultiTexCoord4dv) +#define glMultiTexCoord4f GLEW_GET_FUN(__glewMultiTexCoord4f) +#define glMultiTexCoord4fv GLEW_GET_FUN(__glewMultiTexCoord4fv) +#define glMultiTexCoord4i GLEW_GET_FUN(__glewMultiTexCoord4i) +#define glMultiTexCoord4iv GLEW_GET_FUN(__glewMultiTexCoord4iv) +#define glMultiTexCoord4s GLEW_GET_FUN(__glewMultiTexCoord4s) +#define glMultiTexCoord4sv GLEW_GET_FUN(__glewMultiTexCoord4sv) +#define glSampleCoverage GLEW_GET_FUN(__glewSampleCoverage) + +#define GLEW_VERSION_1_3 GLEW_GET_VAR(__GLEW_VERSION_1_3) + +#endif /* GL_VERSION_1_3 */ + +/* ----------------------------- GL_VERSION_1_4 ---------------------------- */ + +#ifndef GL_VERSION_1_4 +#define GL_VERSION_1_4 1 + +#define GL_BLEND_DST_RGB 0x80C8 +#define GL_BLEND_SRC_RGB 0x80C9 +#define GL_BLEND_DST_ALPHA 0x80CA +#define GL_BLEND_SRC_ALPHA 0x80CB +#define GL_POINT_SIZE_MIN 0x8126 +#define GL_POINT_SIZE_MAX 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128 +#define GL_POINT_DISTANCE_ATTENUATION 0x8129 +#define GL_GENERATE_MIPMAP 0x8191 +#define GL_GENERATE_MIPMAP_HINT 0x8192 +#define GL_DEPTH_COMPONENT16 0x81A5 +#define GL_DEPTH_COMPONENT24 0x81A6 +#define GL_DEPTH_COMPONENT32 0x81A7 +#define GL_MIRRORED_REPEAT 0x8370 +#define GL_FOG_COORDINATE_SOURCE 0x8450 +#define GL_FOG_COORDINATE 0x8451 +#define GL_FRAGMENT_DEPTH 0x8452 +#define GL_CURRENT_FOG_COORDINATE 0x8453 +#define GL_FOG_COORDINATE_ARRAY_TYPE 0x8454 +#define GL_FOG_COORDINATE_ARRAY_STRIDE 0x8455 +#define GL_FOG_COORDINATE_ARRAY_POINTER 0x8456 +#define GL_FOG_COORDINATE_ARRAY 0x8457 +#define GL_COLOR_SUM 0x8458 +#define GL_CURRENT_SECONDARY_COLOR 0x8459 +#define GL_SECONDARY_COLOR_ARRAY_SIZE 0x845A +#define GL_SECONDARY_COLOR_ARRAY_TYPE 0x845B +#define GL_SECONDARY_COLOR_ARRAY_STRIDE 0x845C +#define GL_SECONDARY_COLOR_ARRAY_POINTER 0x845D +#define GL_SECONDARY_COLOR_ARRAY 0x845E +#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD +#define GL_TEXTURE_FILTER_CONTROL 0x8500 +#define GL_TEXTURE_LOD_BIAS 0x8501 +#define GL_INCR_WRAP 0x8507 +#define GL_DECR_WRAP 0x8508 +#define GL_TEXTURE_DEPTH_SIZE 0x884A +#define GL_DEPTH_TEXTURE_MODE 0x884B +#define GL_TEXTURE_COMPARE_MODE 0x884C +#define GL_TEXTURE_COMPARE_FUNC 0x884D +#define GL_COMPARE_R_TO_TEXTURE 0x884E + +typedef void (GLAPIENTRY * PFNGLBLENDCOLORPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONPROC) (GLenum mode); +typedef void (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +typedef void (GLAPIENTRY * PFNGLFOGCOORDPOINTERPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); +typedef void (GLAPIENTRY * PFNGLFOGCOORDDPROC) (GLdouble coord); +typedef void (GLAPIENTRY * PFNGLFOGCOORDDVPROC) (const GLdouble *coord); +typedef void (GLAPIENTRY * PFNGLFOGCOORDFPROC) (GLfloat coord); +typedef void (GLAPIENTRY * PFNGLFOGCOORDFVPROC) (const GLfloat *coord); +typedef void (GLAPIENTRY * PFNGLMULTIDRAWARRAYSPROC) (GLenum mode, GLint *first, GLsizei *count, GLsizei primcount); +typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSPROC) (GLenum mode, GLsizei *count, GLenum type, const GLvoid **indices, GLsizei primcount); +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFVPROC) (GLenum pname, GLfloat *params); +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERIPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERIVPROC) (GLenum pname, GLint *params); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3BPROC) (GLbyte red, GLbyte green, GLbyte blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3BVPROC) (const GLbyte *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3DPROC) (GLdouble red, GLdouble green, GLdouble blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3DVPROC) (const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3FPROC) (GLfloat red, GLfloat green, GLfloat blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3FVPROC) (const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3IPROC) (GLint red, GLint green, GLint blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3IVPROC) (const GLint *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3SPROC) (GLshort red, GLshort green, GLshort blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3SVPROC) (const GLshort *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UBPROC) (GLubyte red, GLubyte green, GLubyte blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UBVPROC) (const GLubyte *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UIPROC) (GLuint red, GLuint green, GLuint blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UIVPROC) (const GLuint *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3USPROC) (GLushort red, GLushort green, GLushort blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3USVPROC) (const GLushort *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORPOINTERPROC) (GLint size, GLenum type, GLsizei stride, GLvoid *pointer); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DPROC) (GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DVPROC) (const GLdouble *p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FPROC) (GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FVPROC) (const GLfloat *p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IPROC) (GLint x, GLint y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IVPROC) (const GLint *p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SPROC) (GLshort x, GLshort y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SVPROC) (const GLshort *p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DPROC) (GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DVPROC) (const GLdouble *p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FPROC) (GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FVPROC) (const GLfloat *p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IPROC) (GLint x, GLint y, GLint z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IVPROC) (const GLint *p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SPROC) (GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SVPROC) (const GLshort *p); + +#define glBlendColor GLEW_GET_FUN(__glewBlendColor) +#define glBlendEquation GLEW_GET_FUN(__glewBlendEquation) +#define glBlendFuncSeparate GLEW_GET_FUN(__glewBlendFuncSeparate) +#define glFogCoordPointer GLEW_GET_FUN(__glewFogCoordPointer) +#define glFogCoordd GLEW_GET_FUN(__glewFogCoordd) +#define glFogCoorddv GLEW_GET_FUN(__glewFogCoorddv) +#define glFogCoordf GLEW_GET_FUN(__glewFogCoordf) +#define glFogCoordfv GLEW_GET_FUN(__glewFogCoordfv) +#define glMultiDrawArrays GLEW_GET_FUN(__glewMultiDrawArrays) +#define glMultiDrawElements GLEW_GET_FUN(__glewMultiDrawElements) +#define glPointParameterf GLEW_GET_FUN(__glewPointParameterf) +#define glPointParameterfv GLEW_GET_FUN(__glewPointParameterfv) +#define glPointParameteri GLEW_GET_FUN(__glewPointParameteri) +#define glPointParameteriv GLEW_GET_FUN(__glewPointParameteriv) +#define glSecondaryColor3b GLEW_GET_FUN(__glewSecondaryColor3b) +#define glSecondaryColor3bv GLEW_GET_FUN(__glewSecondaryColor3bv) +#define glSecondaryColor3d GLEW_GET_FUN(__glewSecondaryColor3d) +#define glSecondaryColor3dv GLEW_GET_FUN(__glewSecondaryColor3dv) +#define glSecondaryColor3f GLEW_GET_FUN(__glewSecondaryColor3f) +#define glSecondaryColor3fv GLEW_GET_FUN(__glewSecondaryColor3fv) +#define glSecondaryColor3i GLEW_GET_FUN(__glewSecondaryColor3i) +#define glSecondaryColor3iv GLEW_GET_FUN(__glewSecondaryColor3iv) +#define glSecondaryColor3s GLEW_GET_FUN(__glewSecondaryColor3s) +#define glSecondaryColor3sv GLEW_GET_FUN(__glewSecondaryColor3sv) +#define glSecondaryColor3ub GLEW_GET_FUN(__glewSecondaryColor3ub) +#define glSecondaryColor3ubv GLEW_GET_FUN(__glewSecondaryColor3ubv) +#define glSecondaryColor3ui GLEW_GET_FUN(__glewSecondaryColor3ui) +#define glSecondaryColor3uiv GLEW_GET_FUN(__glewSecondaryColor3uiv) +#define glSecondaryColor3us GLEW_GET_FUN(__glewSecondaryColor3us) +#define glSecondaryColor3usv GLEW_GET_FUN(__glewSecondaryColor3usv) +#define glSecondaryColorPointer GLEW_GET_FUN(__glewSecondaryColorPointer) +#define glWindowPos2d GLEW_GET_FUN(__glewWindowPos2d) +#define glWindowPos2dv GLEW_GET_FUN(__glewWindowPos2dv) +#define glWindowPos2f GLEW_GET_FUN(__glewWindowPos2f) +#define glWindowPos2fv GLEW_GET_FUN(__glewWindowPos2fv) +#define glWindowPos2i GLEW_GET_FUN(__glewWindowPos2i) +#define glWindowPos2iv GLEW_GET_FUN(__glewWindowPos2iv) +#define glWindowPos2s GLEW_GET_FUN(__glewWindowPos2s) +#define glWindowPos2sv GLEW_GET_FUN(__glewWindowPos2sv) +#define glWindowPos3d GLEW_GET_FUN(__glewWindowPos3d) +#define glWindowPos3dv GLEW_GET_FUN(__glewWindowPos3dv) +#define glWindowPos3f GLEW_GET_FUN(__glewWindowPos3f) +#define glWindowPos3fv GLEW_GET_FUN(__glewWindowPos3fv) +#define glWindowPos3i GLEW_GET_FUN(__glewWindowPos3i) +#define glWindowPos3iv GLEW_GET_FUN(__glewWindowPos3iv) +#define glWindowPos3s GLEW_GET_FUN(__glewWindowPos3s) +#define glWindowPos3sv GLEW_GET_FUN(__glewWindowPos3sv) + +#define GLEW_VERSION_1_4 GLEW_GET_VAR(__GLEW_VERSION_1_4) + +#endif /* GL_VERSION_1_4 */ + +/* ----------------------------- GL_VERSION_1_5 ---------------------------- */ + +#ifndef GL_VERSION_1_5 +#define GL_VERSION_1_5 1 + +#define GL_FOG_COORD_SRC GL_FOG_COORDINATE_SOURCE +#define GL_FOG_COORD GL_FOG_COORDINATE +#define GL_FOG_COORD_ARRAY GL_FOG_COORDINATE_ARRAY +#define GL_SRC0_RGB GL_SOURCE0_RGB +#define GL_FOG_COORD_ARRAY_POINTER GL_FOG_COORDINATE_ARRAY_POINTER +#define GL_FOG_COORD_ARRAY_TYPE GL_FOG_COORDINATE_ARRAY_TYPE +#define GL_SRC1_ALPHA GL_SOURCE1_ALPHA +#define GL_CURRENT_FOG_COORD GL_CURRENT_FOG_COORDINATE +#define GL_FOG_COORD_ARRAY_STRIDE GL_FOG_COORDINATE_ARRAY_STRIDE +#define GL_SRC0_ALPHA GL_SOURCE0_ALPHA +#define GL_SRC1_RGB GL_SOURCE1_RGB +#define GL_FOG_COORD_ARRAY_BUFFER_BINDING GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING +#define GL_SRC2_ALPHA GL_SOURCE2_ALPHA +#define GL_SRC2_RGB GL_SOURCE2_RGB +#define GL_BUFFER_SIZE 0x8764 +#define GL_BUFFER_USAGE 0x8765 +#define GL_QUERY_COUNTER_BITS 0x8864 +#define GL_CURRENT_QUERY 0x8865 +#define GL_QUERY_RESULT 0x8866 +#define GL_QUERY_RESULT_AVAILABLE 0x8867 +#define GL_ARRAY_BUFFER 0x8892 +#define GL_ELEMENT_ARRAY_BUFFER 0x8893 +#define GL_ARRAY_BUFFER_BINDING 0x8894 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 +#define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896 +#define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897 +#define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898 +#define GL_INDEX_ARRAY_BUFFER_BINDING 0x8899 +#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A +#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING 0x889B +#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C +#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0x889D +#define GL_WEIGHT_ARRAY_BUFFER_BINDING 0x889E +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F +#define GL_READ_ONLY 0x88B8 +#define GL_WRITE_ONLY 0x88B9 +#define GL_READ_WRITE 0x88BA +#define GL_BUFFER_ACCESS 0x88BB +#define GL_BUFFER_MAPPED 0x88BC +#define GL_BUFFER_MAP_POINTER 0x88BD +#define GL_STREAM_DRAW 0x88E0 +#define GL_STREAM_READ 0x88E1 +#define GL_STREAM_COPY 0x88E2 +#define GL_STATIC_DRAW 0x88E4 +#define GL_STATIC_READ 0x88E5 +#define GL_STATIC_COPY 0x88E6 +#define GL_DYNAMIC_DRAW 0x88E8 +#define GL_DYNAMIC_READ 0x88E9 +#define GL_DYNAMIC_COPY 0x88EA +#define GL_SAMPLES_PASSED 0x8914 + +typedef ptrdiff_t GLsizeiptr; +typedef ptrdiff_t GLintptr; + +typedef void (GLAPIENTRY * PFNGLBEGINQUERYPROC) (GLenum target, GLuint id); +typedef void (GLAPIENTRY * PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer); +typedef void (GLAPIENTRY * PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage); +typedef void (GLAPIENTRY * PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data); +typedef void (GLAPIENTRY * PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint* buffers); +typedef void (GLAPIENTRY * PFNGLDELETEQUERIESPROC) (GLsizei n, const GLuint* ids); +typedef void (GLAPIENTRY * PFNGLENDQUERYPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLGENBUFFERSPROC) (GLsizei n, GLuint* buffers); +typedef void (GLAPIENTRY * PFNGLGENQUERIESPROC) (GLsizei n, GLuint* ids); +typedef void (GLAPIENTRY * PFNGLGETBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETBUFFERPOINTERVPROC) (GLenum target, GLenum pname, GLvoid** params); +typedef void (GLAPIENTRY * PFNGLGETBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, GLvoid* data); +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTIVPROC) (GLuint id, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUIVPROC) (GLuint id, GLenum pname, GLuint* params); +typedef void (GLAPIENTRY * PFNGLGETQUERYIVPROC) (GLenum target, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISBUFFERPROC) (GLuint buffer); +typedef GLboolean (GLAPIENTRY * PFNGLISQUERYPROC) (GLuint id); +typedef GLvoid* (GLAPIENTRY * PFNGLMAPBUFFERPROC) (GLenum target, GLenum access); +typedef GLboolean (GLAPIENTRY * PFNGLUNMAPBUFFERPROC) (GLenum target); + +#define glBeginQuery GLEW_GET_FUN(__glewBeginQuery) +#define glBindBuffer GLEW_GET_FUN(__glewBindBuffer) +#define glBufferData GLEW_GET_FUN(__glewBufferData) +#define glBufferSubData GLEW_GET_FUN(__glewBufferSubData) +#define glDeleteBuffers GLEW_GET_FUN(__glewDeleteBuffers) +#define glDeleteQueries GLEW_GET_FUN(__glewDeleteQueries) +#define glEndQuery GLEW_GET_FUN(__glewEndQuery) +#define glGenBuffers GLEW_GET_FUN(__glewGenBuffers) +#define glGenQueries GLEW_GET_FUN(__glewGenQueries) +#define glGetBufferParameteriv GLEW_GET_FUN(__glewGetBufferParameteriv) +#define glGetBufferPointerv GLEW_GET_FUN(__glewGetBufferPointerv) +#define glGetBufferSubData GLEW_GET_FUN(__glewGetBufferSubData) +#define glGetQueryObjectiv GLEW_GET_FUN(__glewGetQueryObjectiv) +#define glGetQueryObjectuiv GLEW_GET_FUN(__glewGetQueryObjectuiv) +#define glGetQueryiv GLEW_GET_FUN(__glewGetQueryiv) +#define glIsBuffer GLEW_GET_FUN(__glewIsBuffer) +#define glIsQuery GLEW_GET_FUN(__glewIsQuery) +#define glMapBuffer GLEW_GET_FUN(__glewMapBuffer) +#define glUnmapBuffer GLEW_GET_FUN(__glewUnmapBuffer) + +#define GLEW_VERSION_1_5 GLEW_GET_VAR(__GLEW_VERSION_1_5) + +#endif /* GL_VERSION_1_5 */ + +/* ----------------------------- GL_VERSION_2_0 ---------------------------- */ + +#ifndef GL_VERSION_2_0 +#define GL_VERSION_2_0 1 + +#define GL_BLEND_EQUATION_RGB GL_BLEND_EQUATION +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 +#define GL_CURRENT_VERTEX_ATTRIB 0x8626 +#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642 +#define GL_VERTEX_PROGRAM_TWO_SIDE 0x8643 +#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 +#define GL_STENCIL_BACK_FUNC 0x8800 +#define GL_STENCIL_BACK_FAIL 0x8801 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 +#define GL_MAX_DRAW_BUFFERS 0x8824 +#define GL_DRAW_BUFFER0 0x8825 +#define GL_DRAW_BUFFER1 0x8826 +#define GL_DRAW_BUFFER2 0x8827 +#define GL_DRAW_BUFFER3 0x8828 +#define GL_DRAW_BUFFER4 0x8829 +#define GL_DRAW_BUFFER5 0x882A +#define GL_DRAW_BUFFER6 0x882B +#define GL_DRAW_BUFFER7 0x882C +#define GL_DRAW_BUFFER8 0x882D +#define GL_DRAW_BUFFER9 0x882E +#define GL_DRAW_BUFFER10 0x882F +#define GL_DRAW_BUFFER11 0x8830 +#define GL_DRAW_BUFFER12 0x8831 +#define GL_DRAW_BUFFER13 0x8832 +#define GL_DRAW_BUFFER14 0x8833 +#define GL_DRAW_BUFFER15 0x8834 +#define GL_BLEND_EQUATION_ALPHA 0x883D +#define GL_POINT_SPRITE 0x8861 +#define GL_COORD_REPLACE 0x8862 +#define GL_MAX_VERTEX_ATTRIBS 0x8869 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A +#define GL_MAX_TEXTURE_COORDS 0x8871 +#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 +#define GL_FRAGMENT_SHADER 0x8B30 +#define GL_VERTEX_SHADER 0x8B31 +#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A +#define GL_MAX_VARYING_FLOATS 0x8B4B +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D +#define GL_SHADER_TYPE 0x8B4F +#define GL_FLOAT_VEC2 0x8B50 +#define GL_FLOAT_VEC3 0x8B51 +#define GL_FLOAT_VEC4 0x8B52 +#define GL_INT_VEC2 0x8B53 +#define GL_INT_VEC3 0x8B54 +#define GL_INT_VEC4 0x8B55 +#define GL_BOOL 0x8B56 +#define GL_BOOL_VEC2 0x8B57 +#define GL_BOOL_VEC3 0x8B58 +#define GL_BOOL_VEC4 0x8B59 +#define GL_FLOAT_MAT2 0x8B5A +#define GL_FLOAT_MAT3 0x8B5B +#define GL_FLOAT_MAT4 0x8B5C +#define GL_SAMPLER_1D 0x8B5D +#define GL_SAMPLER_2D 0x8B5E +#define GL_SAMPLER_3D 0x8B5F +#define GL_SAMPLER_CUBE 0x8B60 +#define GL_SAMPLER_1D_SHADOW 0x8B61 +#define GL_SAMPLER_2D_SHADOW 0x8B62 +#define GL_DELETE_STATUS 0x8B80 +#define GL_COMPILE_STATUS 0x8B81 +#define GL_LINK_STATUS 0x8B82 +#define GL_VALIDATE_STATUS 0x8B83 +#define GL_INFO_LOG_LENGTH 0x8B84 +#define GL_ATTACHED_SHADERS 0x8B85 +#define GL_ACTIVE_UNIFORMS 0x8B86 +#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 +#define GL_SHADER_SOURCE_LENGTH 0x8B88 +#define GL_ACTIVE_ATTRIBUTES 0x8B89 +#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B +#define GL_SHADING_LANGUAGE_VERSION 0x8B8C +#define GL_CURRENT_PROGRAM 0x8B8D +#define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0 +#define GL_LOWER_LEFT 0x8CA1 +#define GL_UPPER_LEFT 0x8CA2 +#define GL_STENCIL_BACK_REF 0x8CA3 +#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 +#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 + +typedef char GLchar; + +typedef void (GLAPIENTRY * PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader); +typedef void (GLAPIENTRY * PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar* name); +typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum, GLenum); +typedef void (GLAPIENTRY * PFNGLCOMPILESHADERPROC) (GLuint shader); +typedef GLuint (GLAPIENTRY * PFNGLCREATEPROGRAMPROC) (void); +typedef GLuint (GLAPIENTRY * PFNGLCREATESHADERPROC) (GLenum type); +typedef void (GLAPIENTRY * PFNGLDELETEPROGRAMPROC) (GLuint program); +typedef void (GLAPIENTRY * PFNGLDELETESHADERPROC) (GLuint shader); +typedef void (GLAPIENTRY * PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader); +typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint); +typedef void (GLAPIENTRY * PFNGLDRAWBUFFERSPROC) (GLsizei n, const GLenum* bufs); +typedef void (GLAPIENTRY * PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint); +typedef void (GLAPIENTRY * PFNGLGETACTIVEATTRIBPROC) (GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLchar* name); +typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMPROC) (GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLchar* name); +typedef void (GLAPIENTRY * PFNGLGETATTACHEDSHADERSPROC) (GLuint program, GLsizei maxCount, GLsizei* count, GLuint* shaders); +typedef GLint (GLAPIENTRY * PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar* name); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei* length, GLchar* infoLog); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint* param); +typedef void (GLAPIENTRY * PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* infoLog); +typedef void (GLAPIENTRY * PFNGLGETSHADERSOURCEPROC) (GLint obj, GLsizei maxLength, GLsizei* length, GLchar* source); +typedef void (GLAPIENTRY * PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint* param); +typedef GLint (GLAPIENTRY * PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar* name); +typedef void (GLAPIENTRY * PFNGLGETUNIFORMFVPROC) (GLuint program, GLint location, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETUNIFORMIVPROC) (GLuint program, GLint location, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint, GLenum, GLvoid*); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBDVPROC) (GLuint, GLenum, GLdouble*); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBFVPROC) (GLuint, GLenum, GLfloat*); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIVPROC) (GLuint, GLenum, GLint*); +typedef GLboolean (GLAPIENTRY * PFNGLISPROGRAMPROC) (GLuint program); +typedef GLboolean (GLAPIENTRY * PFNGLISSHADERPROC) (GLuint shader); +typedef void (GLAPIENTRY * PFNGLLINKPROGRAMPROC) (GLuint program); +typedef void (GLAPIENTRY * PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar** strings, const GLint* lengths); +typedef void (GLAPIENTRY * PFNGLSTENCILFUNCSEPARATEPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); +typedef void (GLAPIENTRY * PFNGLSTENCILMASKSEPARATEPROC) (GLenum, GLuint); +typedef void (GLAPIENTRY * PFNGLSTENCILOPSEPARATEPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); +typedef void (GLAPIENTRY * PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0); +typedef void (GLAPIENTRY * PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM1IPROC) (GLint location, GLint v0); +typedef void (GLAPIENTRY * PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1); +typedef void (GLAPIENTRY * PFNGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM2IPROC) (GLint location, GLint v0, GLint v1); +typedef void (GLAPIENTRY * PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM3FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (GLAPIENTRY * PFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM3IPROC) (GLint location, GLint v0, GLint v1, GLint v2); +typedef void (GLAPIENTRY * PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (GLAPIENTRY * PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM4IPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (GLAPIENTRY * PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUSEPROGRAMPROC) (GLuint program); +typedef void (GLAPIENTRY * PFNGLVALIDATEPROGRAMPROC) (GLuint program); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DPROC) (GLuint index, GLdouble x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FPROC) (GLuint index, GLfloat x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FVPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SPROC) (GLuint index, GLshort x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SVPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FPROC) (GLuint index, GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FVPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SPROC) (GLuint index, GLshort x, GLshort y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SVPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FVPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SPROC) (GLuint index, GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SVPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NBVPROC) (GLuint index, const GLbyte* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NIVPROC) (GLuint index, const GLint* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NSVPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUBVPROC) (GLuint index, const GLubyte* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUIVPROC) (GLuint index, const GLuint* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUSVPROC) (GLuint index, const GLushort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4BVPROC) (GLuint index, const GLbyte* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4IVPROC) (GLuint index, const GLint* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SVPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UBVPROC) (GLuint index, const GLubyte* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UIVPROC) (GLuint index, const GLuint* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4USVPROC) (GLuint index, const GLushort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* pointer); + +#define glAttachShader GLEW_GET_FUN(__glewAttachShader) +#define glBindAttribLocation GLEW_GET_FUN(__glewBindAttribLocation) +#define glBlendEquationSeparate GLEW_GET_FUN(__glewBlendEquationSeparate) +#define glCompileShader GLEW_GET_FUN(__glewCompileShader) +#define glCreateProgram GLEW_GET_FUN(__glewCreateProgram) +#define glCreateShader GLEW_GET_FUN(__glewCreateShader) +#define glDeleteProgram GLEW_GET_FUN(__glewDeleteProgram) +#define glDeleteShader GLEW_GET_FUN(__glewDeleteShader) +#define glDetachShader GLEW_GET_FUN(__glewDetachShader) +#define glDisableVertexAttribArray GLEW_GET_FUN(__glewDisableVertexAttribArray) +#define glDrawBuffers GLEW_GET_FUN(__glewDrawBuffers) +#define glEnableVertexAttribArray GLEW_GET_FUN(__glewEnableVertexAttribArray) +#define glGetActiveAttrib GLEW_GET_FUN(__glewGetActiveAttrib) +#define glGetActiveUniform GLEW_GET_FUN(__glewGetActiveUniform) +#define glGetAttachedShaders GLEW_GET_FUN(__glewGetAttachedShaders) +#define glGetAttribLocation GLEW_GET_FUN(__glewGetAttribLocation) +#define glGetProgramInfoLog GLEW_GET_FUN(__glewGetProgramInfoLog) +#define glGetProgramiv GLEW_GET_FUN(__glewGetProgramiv) +#define glGetShaderInfoLog GLEW_GET_FUN(__glewGetShaderInfoLog) +#define glGetShaderSource GLEW_GET_FUN(__glewGetShaderSource) +#define glGetShaderiv GLEW_GET_FUN(__glewGetShaderiv) +#define glGetUniformLocation GLEW_GET_FUN(__glewGetUniformLocation) +#define glGetUniformfv GLEW_GET_FUN(__glewGetUniformfv) +#define glGetUniformiv GLEW_GET_FUN(__glewGetUniformiv) +#define glGetVertexAttribPointerv GLEW_GET_FUN(__glewGetVertexAttribPointerv) +#define glGetVertexAttribdv GLEW_GET_FUN(__glewGetVertexAttribdv) +#define glGetVertexAttribfv GLEW_GET_FUN(__glewGetVertexAttribfv) +#define glGetVertexAttribiv GLEW_GET_FUN(__glewGetVertexAttribiv) +#define glIsProgram GLEW_GET_FUN(__glewIsProgram) +#define glIsShader GLEW_GET_FUN(__glewIsShader) +#define glLinkProgram GLEW_GET_FUN(__glewLinkProgram) +#define glShaderSource GLEW_GET_FUN(__glewShaderSource) +#define glStencilFuncSeparate GLEW_GET_FUN(__glewStencilFuncSeparate) +#define glStencilMaskSeparate GLEW_GET_FUN(__glewStencilMaskSeparate) +#define glStencilOpSeparate GLEW_GET_FUN(__glewStencilOpSeparate) +#define glUniform1f GLEW_GET_FUN(__glewUniform1f) +#define glUniform1fv GLEW_GET_FUN(__glewUniform1fv) +#define glUniform1i GLEW_GET_FUN(__glewUniform1i) +#define glUniform1iv GLEW_GET_FUN(__glewUniform1iv) +#define glUniform2f GLEW_GET_FUN(__glewUniform2f) +#define glUniform2fv GLEW_GET_FUN(__glewUniform2fv) +#define glUniform2i GLEW_GET_FUN(__glewUniform2i) +#define glUniform2iv GLEW_GET_FUN(__glewUniform2iv) +#define glUniform3f GLEW_GET_FUN(__glewUniform3f) +#define glUniform3fv GLEW_GET_FUN(__glewUniform3fv) +#define glUniform3i GLEW_GET_FUN(__glewUniform3i) +#define glUniform3iv GLEW_GET_FUN(__glewUniform3iv) +#define glUniform4f GLEW_GET_FUN(__glewUniform4f) +#define glUniform4fv GLEW_GET_FUN(__glewUniform4fv) +#define glUniform4i GLEW_GET_FUN(__glewUniform4i) +#define glUniform4iv GLEW_GET_FUN(__glewUniform4iv) +#define glUniformMatrix2fv GLEW_GET_FUN(__glewUniformMatrix2fv) +#define glUniformMatrix3fv GLEW_GET_FUN(__glewUniformMatrix3fv) +#define glUniformMatrix4fv GLEW_GET_FUN(__glewUniformMatrix4fv) +#define glUseProgram GLEW_GET_FUN(__glewUseProgram) +#define glValidateProgram GLEW_GET_FUN(__glewValidateProgram) +#define glVertexAttrib1d GLEW_GET_FUN(__glewVertexAttrib1d) +#define glVertexAttrib1dv GLEW_GET_FUN(__glewVertexAttrib1dv) +#define glVertexAttrib1f GLEW_GET_FUN(__glewVertexAttrib1f) +#define glVertexAttrib1fv GLEW_GET_FUN(__glewVertexAttrib1fv) +#define glVertexAttrib1s GLEW_GET_FUN(__glewVertexAttrib1s) +#define glVertexAttrib1sv GLEW_GET_FUN(__glewVertexAttrib1sv) +#define glVertexAttrib2d GLEW_GET_FUN(__glewVertexAttrib2d) +#define glVertexAttrib2dv GLEW_GET_FUN(__glewVertexAttrib2dv) +#define glVertexAttrib2f GLEW_GET_FUN(__glewVertexAttrib2f) +#define glVertexAttrib2fv GLEW_GET_FUN(__glewVertexAttrib2fv) +#define glVertexAttrib2s GLEW_GET_FUN(__glewVertexAttrib2s) +#define glVertexAttrib2sv GLEW_GET_FUN(__glewVertexAttrib2sv) +#define glVertexAttrib3d GLEW_GET_FUN(__glewVertexAttrib3d) +#define glVertexAttrib3dv GLEW_GET_FUN(__glewVertexAttrib3dv) +#define glVertexAttrib3f GLEW_GET_FUN(__glewVertexAttrib3f) +#define glVertexAttrib3fv GLEW_GET_FUN(__glewVertexAttrib3fv) +#define glVertexAttrib3s GLEW_GET_FUN(__glewVertexAttrib3s) +#define glVertexAttrib3sv GLEW_GET_FUN(__glewVertexAttrib3sv) +#define glVertexAttrib4Nbv GLEW_GET_FUN(__glewVertexAttrib4Nbv) +#define glVertexAttrib4Niv GLEW_GET_FUN(__glewVertexAttrib4Niv) +#define glVertexAttrib4Nsv GLEW_GET_FUN(__glewVertexAttrib4Nsv) +#define glVertexAttrib4Nub GLEW_GET_FUN(__glewVertexAttrib4Nub) +#define glVertexAttrib4Nubv GLEW_GET_FUN(__glewVertexAttrib4Nubv) +#define glVertexAttrib4Nuiv GLEW_GET_FUN(__glewVertexAttrib4Nuiv) +#define glVertexAttrib4Nusv GLEW_GET_FUN(__glewVertexAttrib4Nusv) +#define glVertexAttrib4bv GLEW_GET_FUN(__glewVertexAttrib4bv) +#define glVertexAttrib4d GLEW_GET_FUN(__glewVertexAttrib4d) +#define glVertexAttrib4dv GLEW_GET_FUN(__glewVertexAttrib4dv) +#define glVertexAttrib4f GLEW_GET_FUN(__glewVertexAttrib4f) +#define glVertexAttrib4fv GLEW_GET_FUN(__glewVertexAttrib4fv) +#define glVertexAttrib4iv GLEW_GET_FUN(__glewVertexAttrib4iv) +#define glVertexAttrib4s GLEW_GET_FUN(__glewVertexAttrib4s) +#define glVertexAttrib4sv GLEW_GET_FUN(__glewVertexAttrib4sv) +#define glVertexAttrib4ubv GLEW_GET_FUN(__glewVertexAttrib4ubv) +#define glVertexAttrib4uiv GLEW_GET_FUN(__glewVertexAttrib4uiv) +#define glVertexAttrib4usv GLEW_GET_FUN(__glewVertexAttrib4usv) +#define glVertexAttribPointer GLEW_GET_FUN(__glewVertexAttribPointer) + +#define GLEW_VERSION_2_0 GLEW_GET_VAR(__GLEW_VERSION_2_0) + +#endif /* GL_VERSION_2_0 */ + +/* ----------------------------- GL_VERSION_2_1 ---------------------------- */ + +#ifndef GL_VERSION_2_1 +#define GL_VERSION_2_1 1 + +#define GL_CURRENT_RASTER_SECONDARY_COLOR 0x845F +#define GL_PIXEL_PACK_BUFFER 0x88EB +#define GL_PIXEL_UNPACK_BUFFER 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF +#define GL_FLOAT_MAT2x3 0x8B65 +#define GL_FLOAT_MAT2x4 0x8B66 +#define GL_FLOAT_MAT3x2 0x8B67 +#define GL_FLOAT_MAT3x4 0x8B68 +#define GL_FLOAT_MAT4x2 0x8B69 +#define GL_FLOAT_MAT4x3 0x8B6A +#define GL_SRGB 0x8C40 +#define GL_SRGB8 0x8C41 +#define GL_SRGB_ALPHA 0x8C42 +#define GL_SRGB8_ALPHA8 0x8C43 +#define GL_SLUMINANCE_ALPHA 0x8C44 +#define GL_SLUMINANCE8_ALPHA8 0x8C45 +#define GL_SLUMINANCE 0x8C46 +#define GL_SLUMINANCE8 0x8C47 +#define GL_COMPRESSED_SRGB 0x8C48 +#define GL_COMPRESSED_SRGB_ALPHA 0x8C49 +#define GL_COMPRESSED_SLUMINANCE 0x8C4A +#define GL_COMPRESSED_SLUMINANCE_ALPHA 0x8C4B + +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + +#define glUniformMatrix2x3fv GLEW_GET_FUN(__glewUniformMatrix2x3fv) +#define glUniformMatrix2x4fv GLEW_GET_FUN(__glewUniformMatrix2x4fv) +#define glUniformMatrix3x2fv GLEW_GET_FUN(__glewUniformMatrix3x2fv) +#define glUniformMatrix3x4fv GLEW_GET_FUN(__glewUniformMatrix3x4fv) +#define glUniformMatrix4x2fv GLEW_GET_FUN(__glewUniformMatrix4x2fv) +#define glUniformMatrix4x3fv GLEW_GET_FUN(__glewUniformMatrix4x3fv) + +#define GLEW_VERSION_2_1 GLEW_GET_VAR(__GLEW_VERSION_2_1) + +#endif /* GL_VERSION_2_1 */ + +/* ----------------------------- GL_VERSION_3_0 ---------------------------- */ + +#ifndef GL_VERSION_3_0 +#define GL_VERSION_3_0 1 + +#define GL_MAX_CLIP_DISTANCES GL_MAX_CLIP_PLANES +#define GL_CLIP_DISTANCE5 GL_CLIP_PLANE5 +#define GL_CLIP_DISTANCE1 GL_CLIP_PLANE1 +#define GL_CLIP_DISTANCE3 GL_CLIP_PLANE3 +#define GL_COMPARE_REF_TO_TEXTURE GL_COMPARE_R_TO_TEXTURE_ARB +#define GL_CLIP_DISTANCE0 GL_CLIP_PLANE0 +#define GL_CLIP_DISTANCE4 GL_CLIP_PLANE4 +#define GL_CLIP_DISTANCE2 GL_CLIP_PLANE2 +#define GL_MAX_VARYING_COMPONENTS GL_MAX_VARYING_FLOATS +#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x0001 +#define GL_MAJOR_VERSION 0x821B +#define GL_MINOR_VERSION 0x821C +#define GL_NUM_EXTENSIONS 0x821D +#define GL_CONTEXT_FLAGS 0x821E +#define GL_DEPTH_BUFFER 0x8223 +#define GL_STENCIL_BUFFER 0x8224 +#define GL_COMPRESSED_RED 0x8225 +#define GL_COMPRESSED_RG 0x8226 +#define GL_RGBA32F 0x8814 +#define GL_RGB32F 0x8815 +#define GL_RGBA16F 0x881A +#define GL_RGB16F 0x881B +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD +#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF +#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904 +#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905 +#define GL_CLAMP_VERTEX_COLOR 0x891A +#define GL_CLAMP_FRAGMENT_COLOR 0x891B +#define GL_CLAMP_READ_COLOR 0x891C +#define GL_FIXED_ONLY 0x891D +#define GL_TEXTURE_RED_TYPE 0x8C10 +#define GL_TEXTURE_GREEN_TYPE 0x8C11 +#define GL_TEXTURE_BLUE_TYPE 0x8C12 +#define GL_TEXTURE_ALPHA_TYPE 0x8C13 +#define GL_TEXTURE_LUMINANCE_TYPE 0x8C14 +#define GL_TEXTURE_INTENSITY_TYPE 0x8C15 +#define GL_TEXTURE_DEPTH_TYPE 0x8C16 +#define GL_UNSIGNED_NORMALIZED 0x8C17 +#define GL_TEXTURE_1D_ARRAY 0x8C18 +#define GL_PROXY_TEXTURE_1D_ARRAY 0x8C19 +#define GL_TEXTURE_2D_ARRAY 0x8C1A +#define GL_PROXY_TEXTURE_2D_ARRAY 0x8C1B +#define GL_TEXTURE_BINDING_1D_ARRAY 0x8C1C +#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D +#define GL_R11F_G11F_B10F 0x8C3A +#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B +#define GL_RGB9_E5 0x8C3D +#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E +#define GL_TEXTURE_SHARED_SIZE 0x8C3F +#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76 +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80 +#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83 +#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85 +#define GL_PRIMITIVES_GENERATED 0x8C87 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88 +#define GL_RASTERIZER_DISCARD 0x8C89 +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B +#define GL_INTERLEAVED_ATTRIBS 0x8C8C +#define GL_SEPARATE_ATTRIBS 0x8C8D +#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F +#define GL_RGBA32UI 0x8D70 +#define GL_RGB32UI 0x8D71 +#define GL_RGBA16UI 0x8D76 +#define GL_RGB16UI 0x8D77 +#define GL_RGBA8UI 0x8D7C +#define GL_RGB8UI 0x8D7D +#define GL_RGBA32I 0x8D82 +#define GL_RGB32I 0x8D83 +#define GL_RGBA16I 0x8D88 +#define GL_RGB16I 0x8D89 +#define GL_RGBA8I 0x8D8E +#define GL_RGB8I 0x8D8F +#define GL_RED_INTEGER 0x8D94 +#define GL_GREEN_INTEGER 0x8D95 +#define GL_BLUE_INTEGER 0x8D96 +#define GL_ALPHA_INTEGER 0x8D97 +#define GL_RGB_INTEGER 0x8D98 +#define GL_RGBA_INTEGER 0x8D99 +#define GL_BGR_INTEGER 0x8D9A +#define GL_BGRA_INTEGER 0x8D9B +#define GL_SAMPLER_1D_ARRAY 0x8DC0 +#define GL_SAMPLER_2D_ARRAY 0x8DC1 +#define GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3 +#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4 +#define GL_SAMPLER_CUBE_SHADOW 0x8DC5 +#define GL_UNSIGNED_INT_VEC2 0x8DC6 +#define GL_UNSIGNED_INT_VEC3 0x8DC7 +#define GL_UNSIGNED_INT_VEC4 0x8DC8 +#define GL_INT_SAMPLER_1D 0x8DC9 +#define GL_INT_SAMPLER_2D 0x8DCA +#define GL_INT_SAMPLER_3D 0x8DCB +#define GL_INT_SAMPLER_CUBE 0x8DCC +#define GL_INT_SAMPLER_1D_ARRAY 0x8DCE +#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF +#define GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1 +#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2 +#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3 +#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4 +#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6 +#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7 +#define GL_QUERY_WAIT 0x8E13 +#define GL_QUERY_NO_WAIT 0x8E14 +#define GL_QUERY_BY_REGION_WAIT 0x8E15 +#define GL_QUERY_BY_REGION_NO_WAIT 0x8E16 + +typedef void (GLAPIENTRY * PFNGLBEGINCONDITIONALRENDERPROC) (GLuint, GLenum); +typedef void (GLAPIENTRY * PFNGLBEGINTRANSFORMFEEDBACKPROC) (GLenum); +typedef void (GLAPIENTRY * PFNGLBINDBUFFERBASEPROC) (GLenum, GLuint, GLuint); +typedef void (GLAPIENTRY * PFNGLBINDBUFFERRANGEPROC) (GLenum, GLuint, GLuint, GLintptr, GLsizeiptr); +typedef void (GLAPIENTRY * PFNGLBINDFRAGDATALOCATIONPROC) (GLuint, GLuint, const GLchar*); +typedef void (GLAPIENTRY * PFNGLCLAMPCOLORPROC) (GLenum, GLenum); +typedef void (GLAPIENTRY * PFNGLCLEARBUFFERFIPROC) (GLenum, GLint, GLfloat, GLint); +typedef void (GLAPIENTRY * PFNGLCLEARBUFFERFVPROC) (GLenum, GLint, const GLfloat*); +typedef void (GLAPIENTRY * PFNGLCLEARBUFFERIVPROC) (GLenum, GLint, const GLint*); +typedef void (GLAPIENTRY * PFNGLCLEARBUFFERUIVPROC) (GLenum, GLint, const GLuint*); +typedef void (GLAPIENTRY * PFNGLCOLORMASKIPROC) (GLuint, GLboolean, GLboolean, GLboolean, GLboolean); +typedef void (GLAPIENTRY * PFNGLDISABLEIPROC) (GLenum, GLuint); +typedef void (GLAPIENTRY * PFNGLENABLEIPROC) (GLenum, GLuint); +typedef void (GLAPIENTRY * PFNGLENDCONDITIONALRENDERPROC) (void); +typedef void (GLAPIENTRY * PFNGLENDTRANSFORMFEEDBACKPROC) (void); +typedef void (GLAPIENTRY * PFNGLGETBOOLEANI_VPROC) (GLenum, GLuint, GLboolean*); +typedef GLint (GLAPIENTRY * PFNGLGETFRAGDATALOCATIONPROC) (GLuint, const GLchar*); +typedef void (GLAPIENTRY * PFNGLGETINTEGERI_VPROC) (GLenum, GLuint, GLint*); +typedef const GLubyte* (GLAPIENTRY * PFNGLGETSTRINGIPROC) (GLenum, GLuint); +typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERIIVPROC) (GLenum, GLenum, GLint*); +typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERIUIVPROC) (GLenum, GLenum, GLuint*); +typedef void (GLAPIENTRY * PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) (GLuint, GLuint, GLint*); +typedef void (GLAPIENTRY * PFNGLGETUNIFORMUIVPROC) (GLuint, GLint, GLuint*); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIIVPROC) (GLuint, GLenum, GLint*); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIUIVPROC) (GLuint, GLenum, GLuint*); +typedef GLboolean (GLAPIENTRY * PFNGLISENABLEDIPROC) (GLenum, GLuint); +typedef void (GLAPIENTRY * PFNGLTEXPARAMETERIIVPROC) (GLenum, GLenum, const GLint*); +typedef void (GLAPIENTRY * PFNGLTEXPARAMETERIUIVPROC) (GLenum, GLenum, const GLuint*); +typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKVARYINGSPROC) (GLuint, GLsizei, const GLint*, GLenum); +typedef void (GLAPIENTRY * PFNGLUNIFORM1UIPROC) (GLint, GLuint); +typedef void (GLAPIENTRY * PFNGLUNIFORM1UIVPROC) (GLint, GLsizei, const GLuint*); +typedef void (GLAPIENTRY * PFNGLUNIFORM2UIPROC) (GLint, GLuint, GLuint); +typedef void (GLAPIENTRY * PFNGLUNIFORM2UIVPROC) (GLint, GLsizei, const GLuint*); +typedef void (GLAPIENTRY * PFNGLUNIFORM3UIPROC) (GLint, GLuint, GLuint, GLuint); +typedef void (GLAPIENTRY * PFNGLUNIFORM3UIVPROC) (GLint, GLsizei, const GLuint*); +typedef void (GLAPIENTRY * PFNGLUNIFORM4UIPROC) (GLint, GLuint, GLuint, GLuint, GLuint); +typedef void (GLAPIENTRY * PFNGLUNIFORM4UIVPROC) (GLint, GLsizei, const GLuint*); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1IPROC) (GLuint, GLint); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1IVPROC) (GLuint, const GLint*); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1UIPROC) (GLuint, GLuint); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1UIVPROC) (GLuint, const GLuint*); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2IPROC) (GLuint, GLint, GLint); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2IVPROC) (GLuint, const GLint*); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2UIPROC) (GLuint, GLuint, GLuint); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2UIVPROC) (GLuint, const GLuint*); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3IPROC) (GLuint, GLint, GLint, GLint); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3IVPROC) (GLuint, const GLint*); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3UIPROC) (GLuint, GLuint, GLuint, GLuint); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3UIVPROC) (GLuint, const GLuint*); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4BVPROC) (GLuint, const GLbyte*); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4IPROC) (GLuint, GLint, GLint, GLint, GLint); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4IVPROC) (GLuint, const GLint*); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4SVPROC) (GLuint, const GLshort*); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UBVPROC) (GLuint, const GLubyte*); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UIPROC) (GLuint, GLuint, GLuint, GLuint, GLuint); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UIVPROC) (GLuint, const GLuint*); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4USVPROC) (GLuint, const GLushort*); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBIPOINTERPROC) (GLuint, GLint, GLenum, GLsizei, const GLvoid*); + +#define glBeginConditionalRender GLEW_GET_FUN(__glewBeginConditionalRender) +#define glBeginTransformFeedback GLEW_GET_FUN(__glewBeginTransformFeedback) +#define glBindBufferBase GLEW_GET_FUN(__glewBindBufferBase) +#define glBindBufferRange GLEW_GET_FUN(__glewBindBufferRange) +#define glBindFragDataLocation GLEW_GET_FUN(__glewBindFragDataLocation) +#define glClampColor GLEW_GET_FUN(__glewClampColor) +#define glClearBufferfi GLEW_GET_FUN(__glewClearBufferfi) +#define glClearBufferfv GLEW_GET_FUN(__glewClearBufferfv) +#define glClearBufferiv GLEW_GET_FUN(__glewClearBufferiv) +#define glClearBufferuiv GLEW_GET_FUN(__glewClearBufferuiv) +#define glColorMaski GLEW_GET_FUN(__glewColorMaski) +#define glDisablei GLEW_GET_FUN(__glewDisablei) +#define glEnablei GLEW_GET_FUN(__glewEnablei) +#define glEndConditionalRender GLEW_GET_FUN(__glewEndConditionalRender) +#define glEndTransformFeedback GLEW_GET_FUN(__glewEndTransformFeedback) +#define glGetBooleani_v GLEW_GET_FUN(__glewGetBooleani_v) +#define glGetFragDataLocation GLEW_GET_FUN(__glewGetFragDataLocation) +#define glGetIntegeri_v GLEW_GET_FUN(__glewGetIntegeri_v) +#define glGetStringi GLEW_GET_FUN(__glewGetStringi) +#define glGetTexParameterIiv GLEW_GET_FUN(__glewGetTexParameterIiv) +#define glGetTexParameterIuiv GLEW_GET_FUN(__glewGetTexParameterIuiv) +#define glGetTransformFeedbackVarying GLEW_GET_FUN(__glewGetTransformFeedbackVarying) +#define glGetUniformuiv GLEW_GET_FUN(__glewGetUniformuiv) +#define glGetVertexAttribIiv GLEW_GET_FUN(__glewGetVertexAttribIiv) +#define glGetVertexAttribIuiv GLEW_GET_FUN(__glewGetVertexAttribIuiv) +#define glIsEnabledi GLEW_GET_FUN(__glewIsEnabledi) +#define glTexParameterIiv GLEW_GET_FUN(__glewTexParameterIiv) +#define glTexParameterIuiv GLEW_GET_FUN(__glewTexParameterIuiv) +#define glTransformFeedbackVaryings GLEW_GET_FUN(__glewTransformFeedbackVaryings) +#define glUniform1ui GLEW_GET_FUN(__glewUniform1ui) +#define glUniform1uiv GLEW_GET_FUN(__glewUniform1uiv) +#define glUniform2ui GLEW_GET_FUN(__glewUniform2ui) +#define glUniform2uiv GLEW_GET_FUN(__glewUniform2uiv) +#define glUniform3ui GLEW_GET_FUN(__glewUniform3ui) +#define glUniform3uiv GLEW_GET_FUN(__glewUniform3uiv) +#define glUniform4ui GLEW_GET_FUN(__glewUniform4ui) +#define glUniform4uiv GLEW_GET_FUN(__glewUniform4uiv) +#define glVertexAttribI1i GLEW_GET_FUN(__glewVertexAttribI1i) +#define glVertexAttribI1iv GLEW_GET_FUN(__glewVertexAttribI1iv) +#define glVertexAttribI1ui GLEW_GET_FUN(__glewVertexAttribI1ui) +#define glVertexAttribI1uiv GLEW_GET_FUN(__glewVertexAttribI1uiv) +#define glVertexAttribI2i GLEW_GET_FUN(__glewVertexAttribI2i) +#define glVertexAttribI2iv GLEW_GET_FUN(__glewVertexAttribI2iv) +#define glVertexAttribI2ui GLEW_GET_FUN(__glewVertexAttribI2ui) +#define glVertexAttribI2uiv GLEW_GET_FUN(__glewVertexAttribI2uiv) +#define glVertexAttribI3i GLEW_GET_FUN(__glewVertexAttribI3i) +#define glVertexAttribI3iv GLEW_GET_FUN(__glewVertexAttribI3iv) +#define glVertexAttribI3ui GLEW_GET_FUN(__glewVertexAttribI3ui) +#define glVertexAttribI3uiv GLEW_GET_FUN(__glewVertexAttribI3uiv) +#define glVertexAttribI4bv GLEW_GET_FUN(__glewVertexAttribI4bv) +#define glVertexAttribI4i GLEW_GET_FUN(__glewVertexAttribI4i) +#define glVertexAttribI4iv GLEW_GET_FUN(__glewVertexAttribI4iv) +#define glVertexAttribI4sv GLEW_GET_FUN(__glewVertexAttribI4sv) +#define glVertexAttribI4ubv GLEW_GET_FUN(__glewVertexAttribI4ubv) +#define glVertexAttribI4ui GLEW_GET_FUN(__glewVertexAttribI4ui) +#define glVertexAttribI4uiv GLEW_GET_FUN(__glewVertexAttribI4uiv) +#define glVertexAttribI4usv GLEW_GET_FUN(__glewVertexAttribI4usv) +#define glVertexAttribIPointer GLEW_GET_FUN(__glewVertexAttribIPointer) + +#define GLEW_VERSION_3_0 GLEW_GET_VAR(__GLEW_VERSION_3_0) + +#endif /* GL_VERSION_3_0 */ + +/* -------------------------- GL_3DFX_multisample -------------------------- */ + +#ifndef GL_3DFX_multisample +#define GL_3DFX_multisample 1 + +#define GL_MULTISAMPLE_3DFX 0x86B2 +#define GL_SAMPLE_BUFFERS_3DFX 0x86B3 +#define GL_SAMPLES_3DFX 0x86B4 +#define GL_MULTISAMPLE_BIT_3DFX 0x20000000 + +#define GLEW_3DFX_multisample GLEW_GET_VAR(__GLEW_3DFX_multisample) + +#endif /* GL_3DFX_multisample */ + +/* ---------------------------- GL_3DFX_tbuffer ---------------------------- */ + +#ifndef GL_3DFX_tbuffer +#define GL_3DFX_tbuffer 1 + +typedef void (GLAPIENTRY * PFNGLTBUFFERMASK3DFXPROC) (GLuint mask); + +#define glTbufferMask3DFX GLEW_GET_FUN(__glewTbufferMask3DFX) + +#define GLEW_3DFX_tbuffer GLEW_GET_VAR(__GLEW_3DFX_tbuffer) + +#endif /* GL_3DFX_tbuffer */ + +/* -------------------- GL_3DFX_texture_compression_FXT1 ------------------- */ + +#ifndef GL_3DFX_texture_compression_FXT1 +#define GL_3DFX_texture_compression_FXT1 1 + +#define GL_COMPRESSED_RGB_FXT1_3DFX 0x86B0 +#define GL_COMPRESSED_RGBA_FXT1_3DFX 0x86B1 + +#define GLEW_3DFX_texture_compression_FXT1 GLEW_GET_VAR(__GLEW_3DFX_texture_compression_FXT1) + +#endif /* GL_3DFX_texture_compression_FXT1 */ + +/* ------------------------ GL_APPLE_client_storage ------------------------ */ + +#ifndef GL_APPLE_client_storage +#define GL_APPLE_client_storage 1 + +#define GL_UNPACK_CLIENT_STORAGE_APPLE 0x85B2 + +#define GLEW_APPLE_client_storage GLEW_GET_VAR(__GLEW_APPLE_client_storage) + +#endif /* GL_APPLE_client_storage */ + +/* ------------------------- GL_APPLE_element_array ------------------------ */ + +#ifndef GL_APPLE_element_array +#define GL_APPLE_element_array 1 + +#define GL_ELEMENT_ARRAY_APPLE 0x8768 +#define GL_ELEMENT_ARRAY_TYPE_APPLE 0x8769 +#define GL_ELEMENT_ARRAY_POINTER_APPLE 0x876A + +typedef void (GLAPIENTRY * PFNGLDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, GLint first, GLsizei count); +typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, GLint first, GLsizei count); +typedef void (GLAPIENTRY * PFNGLELEMENTPOINTERAPPLEPROC) (GLenum type, const void* pointer); +typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, const GLint* first, const GLsizei *count, GLsizei primcount); +typedef void (GLAPIENTRY * PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, const GLint* first, const GLsizei *count, GLsizei primcount); + +#define glDrawElementArrayAPPLE GLEW_GET_FUN(__glewDrawElementArrayAPPLE) +#define glDrawRangeElementArrayAPPLE GLEW_GET_FUN(__glewDrawRangeElementArrayAPPLE) +#define glElementPointerAPPLE GLEW_GET_FUN(__glewElementPointerAPPLE) +#define glMultiDrawElementArrayAPPLE GLEW_GET_FUN(__glewMultiDrawElementArrayAPPLE) +#define glMultiDrawRangeElementArrayAPPLE GLEW_GET_FUN(__glewMultiDrawRangeElementArrayAPPLE) + +#define GLEW_APPLE_element_array GLEW_GET_VAR(__GLEW_APPLE_element_array) + +#endif /* GL_APPLE_element_array */ + +/* ----------------------------- GL_APPLE_fence ---------------------------- */ + +#ifndef GL_APPLE_fence +#define GL_APPLE_fence 1 + +#define GL_DRAW_PIXELS_APPLE 0x8A0A +#define GL_FENCE_APPLE 0x8A0B + +typedef void (GLAPIENTRY * PFNGLDELETEFENCESAPPLEPROC) (GLsizei n, const GLuint* fences); +typedef void (GLAPIENTRY * PFNGLFINISHFENCEAPPLEPROC) (GLuint fence); +typedef void (GLAPIENTRY * PFNGLFINISHOBJECTAPPLEPROC) (GLenum object, GLint name); +typedef void (GLAPIENTRY * PFNGLGENFENCESAPPLEPROC) (GLsizei n, GLuint* fences); +typedef GLboolean (GLAPIENTRY * PFNGLISFENCEAPPLEPROC) (GLuint fence); +typedef void (GLAPIENTRY * PFNGLSETFENCEAPPLEPROC) (GLuint fence); +typedef GLboolean (GLAPIENTRY * PFNGLTESTFENCEAPPLEPROC) (GLuint fence); +typedef GLboolean (GLAPIENTRY * PFNGLTESTOBJECTAPPLEPROC) (GLenum object, GLuint name); + +#define glDeleteFencesAPPLE GLEW_GET_FUN(__glewDeleteFencesAPPLE) +#define glFinishFenceAPPLE GLEW_GET_FUN(__glewFinishFenceAPPLE) +#define glFinishObjectAPPLE GLEW_GET_FUN(__glewFinishObjectAPPLE) +#define glGenFencesAPPLE GLEW_GET_FUN(__glewGenFencesAPPLE) +#define glIsFenceAPPLE GLEW_GET_FUN(__glewIsFenceAPPLE) +#define glSetFenceAPPLE GLEW_GET_FUN(__glewSetFenceAPPLE) +#define glTestFenceAPPLE GLEW_GET_FUN(__glewTestFenceAPPLE) +#define glTestObjectAPPLE GLEW_GET_FUN(__glewTestObjectAPPLE) + +#define GLEW_APPLE_fence GLEW_GET_VAR(__GLEW_APPLE_fence) + +#endif /* GL_APPLE_fence */ + +/* ------------------------- GL_APPLE_float_pixels ------------------------- */ + +#ifndef GL_APPLE_float_pixels +#define GL_APPLE_float_pixels 1 + +#define GL_HALF_APPLE 0x140B +#define GL_RGBA_FLOAT32_APPLE 0x8814 +#define GL_RGB_FLOAT32_APPLE 0x8815 +#define GL_ALPHA_FLOAT32_APPLE 0x8816 +#define GL_INTENSITY_FLOAT32_APPLE 0x8817 +#define GL_LUMINANCE_FLOAT32_APPLE 0x8818 +#define GL_LUMINANCE_ALPHA_FLOAT32_APPLE 0x8819 +#define GL_RGBA_FLOAT16_APPLE 0x881A +#define GL_RGB_FLOAT16_APPLE 0x881B +#define GL_ALPHA_FLOAT16_APPLE 0x881C +#define GL_INTENSITY_FLOAT16_APPLE 0x881D +#define GL_LUMINANCE_FLOAT16_APPLE 0x881E +#define GL_LUMINANCE_ALPHA_FLOAT16_APPLE 0x881F +#define GL_COLOR_FLOAT_APPLE 0x8A0F + +#define GLEW_APPLE_float_pixels GLEW_GET_VAR(__GLEW_APPLE_float_pixels) + +#endif /* GL_APPLE_float_pixels */ + +/* ---------------------- GL_APPLE_flush_buffer_range ---------------------- */ + +#ifndef GL_APPLE_flush_buffer_range +#define GL_APPLE_flush_buffer_range 1 + +#define GL_BUFFER_SERIALIZED_MODIFY_APPLE 0x8A12 +#define GL_BUFFER_FLUSHING_UNMAP_APPLE 0x8A13 + +typedef void (GLAPIENTRY * PFNGLBUFFERPARAMETERIAPPLEPROC) (GLenum target, GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC) (GLenum target, GLintptr offset, GLsizeiptr size); + +#define glBufferParameteriAPPLE GLEW_GET_FUN(__glewBufferParameteriAPPLE) +#define glFlushMappedBufferRangeAPPLE GLEW_GET_FUN(__glewFlushMappedBufferRangeAPPLE) + +#define GLEW_APPLE_flush_buffer_range GLEW_GET_VAR(__GLEW_APPLE_flush_buffer_range) + +#endif /* GL_APPLE_flush_buffer_range */ + +/* ------------------------- GL_APPLE_pixel_buffer ------------------------- */ + +#ifndef GL_APPLE_pixel_buffer +#define GL_APPLE_pixel_buffer 1 + +#define GL_MIN_PBUFFER_VIEWPORT_DIMS_APPLE 0x8A10 + +#define GLEW_APPLE_pixel_buffer GLEW_GET_VAR(__GLEW_APPLE_pixel_buffer) + +#endif /* GL_APPLE_pixel_buffer */ + +/* ------------------------ GL_APPLE_specular_vector ----------------------- */ + +#ifndef GL_APPLE_specular_vector +#define GL_APPLE_specular_vector 1 + +#define GL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE 0x85B0 + +#define GLEW_APPLE_specular_vector GLEW_GET_VAR(__GLEW_APPLE_specular_vector) + +#endif /* GL_APPLE_specular_vector */ + +/* ------------------------- GL_APPLE_texture_range ------------------------ */ + +#ifndef GL_APPLE_texture_range +#define GL_APPLE_texture_range 1 + +#define GL_TEXTURE_RANGE_LENGTH_APPLE 0x85B7 +#define GL_TEXTURE_RANGE_POINTER_APPLE 0x85B8 +#define GL_TEXTURE_STORAGE_HINT_APPLE 0x85BC +#define GL_STORAGE_PRIVATE_APPLE 0x85BD +#define GL_STORAGE_CACHED_APPLE 0x85BE +#define GL_STORAGE_SHARED_APPLE 0x85BF + +typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC) (GLenum target, GLenum pname, GLvoid **params); +typedef void (GLAPIENTRY * PFNGLTEXTURERANGEAPPLEPROC) (GLenum target, GLsizei length, GLvoid *pointer); + +#define glGetTexParameterPointervAPPLE GLEW_GET_FUN(__glewGetTexParameterPointervAPPLE) +#define glTextureRangeAPPLE GLEW_GET_FUN(__glewTextureRangeAPPLE) + +#define GLEW_APPLE_texture_range GLEW_GET_VAR(__GLEW_APPLE_texture_range) + +#endif /* GL_APPLE_texture_range */ + +/* ------------------------ GL_APPLE_transform_hint ------------------------ */ + +#ifndef GL_APPLE_transform_hint +#define GL_APPLE_transform_hint 1 + +#define GL_TRANSFORM_HINT_APPLE 0x85B1 + +#define GLEW_APPLE_transform_hint GLEW_GET_VAR(__GLEW_APPLE_transform_hint) + +#endif /* GL_APPLE_transform_hint */ + +/* ---------------------- GL_APPLE_vertex_array_object --------------------- */ + +#ifndef GL_APPLE_vertex_array_object +#define GL_APPLE_vertex_array_object 1 + +#define GL_VERTEX_ARRAY_BINDING_APPLE 0x85B5 + +typedef void (GLAPIENTRY * PFNGLBINDVERTEXARRAYAPPLEPROC) (GLuint array); +typedef void (GLAPIENTRY * PFNGLDELETEVERTEXARRAYSAPPLEPROC) (GLsizei n, const GLuint* arrays); +typedef void (GLAPIENTRY * PFNGLGENVERTEXARRAYSAPPLEPROC) (GLsizei n, const GLuint* arrays); +typedef GLboolean (GLAPIENTRY * PFNGLISVERTEXARRAYAPPLEPROC) (GLuint array); + +#define glBindVertexArrayAPPLE GLEW_GET_FUN(__glewBindVertexArrayAPPLE) +#define glDeleteVertexArraysAPPLE GLEW_GET_FUN(__glewDeleteVertexArraysAPPLE) +#define glGenVertexArraysAPPLE GLEW_GET_FUN(__glewGenVertexArraysAPPLE) +#define glIsVertexArrayAPPLE GLEW_GET_FUN(__glewIsVertexArrayAPPLE) + +#define GLEW_APPLE_vertex_array_object GLEW_GET_VAR(__GLEW_APPLE_vertex_array_object) + +#endif /* GL_APPLE_vertex_array_object */ + +/* ---------------------- GL_APPLE_vertex_array_range ---------------------- */ + +#ifndef GL_APPLE_vertex_array_range +#define GL_APPLE_vertex_array_range 1 + +#define GL_VERTEX_ARRAY_RANGE_APPLE 0x851D +#define GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE 0x851E +#define GL_VERTEX_ARRAY_STORAGE_HINT_APPLE 0x851F +#define GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_APPLE 0x8520 +#define GL_VERTEX_ARRAY_RANGE_POINTER_APPLE 0x8521 +#define GL_STORAGE_CACHED_APPLE 0x85BE +#define GL_STORAGE_SHARED_APPLE 0x85BF + +typedef void (GLAPIENTRY * PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, void* pointer); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYPARAMETERIAPPLEPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, void* pointer); + +#define glFlushVertexArrayRangeAPPLE GLEW_GET_FUN(__glewFlushVertexArrayRangeAPPLE) +#define glVertexArrayParameteriAPPLE GLEW_GET_FUN(__glewVertexArrayParameteriAPPLE) +#define glVertexArrayRangeAPPLE GLEW_GET_FUN(__glewVertexArrayRangeAPPLE) + +#define GLEW_APPLE_vertex_array_range GLEW_GET_VAR(__GLEW_APPLE_vertex_array_range) + +#endif /* GL_APPLE_vertex_array_range */ + +/* --------------------------- GL_APPLE_ycbcr_422 -------------------------- */ + +#ifndef GL_APPLE_ycbcr_422 +#define GL_APPLE_ycbcr_422 1 + +#define GL_YCBCR_422_APPLE 0x85B9 +#define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA +#define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB + +#define GLEW_APPLE_ycbcr_422 GLEW_GET_VAR(__GLEW_APPLE_ycbcr_422) + +#endif /* GL_APPLE_ycbcr_422 */ + +/* ----------------------- GL_ARB_color_buffer_float ----------------------- */ + +#ifndef GL_ARB_color_buffer_float +#define GL_ARB_color_buffer_float 1 + +#define GL_RGBA_FLOAT_MODE_ARB 0x8820 +#define GL_CLAMP_VERTEX_COLOR_ARB 0x891A +#define GL_CLAMP_FRAGMENT_COLOR_ARB 0x891B +#define GL_CLAMP_READ_COLOR_ARB 0x891C +#define GL_FIXED_ONLY_ARB 0x891D + +typedef void (GLAPIENTRY * PFNGLCLAMPCOLORARBPROC) (GLenum target, GLenum clamp); + +#define glClampColorARB GLEW_GET_FUN(__glewClampColorARB) + +#define GLEW_ARB_color_buffer_float GLEW_GET_VAR(__GLEW_ARB_color_buffer_float) + +#endif /* GL_ARB_color_buffer_float */ + +/* ----------------------- GL_ARB_depth_buffer_float ----------------------- */ + +#ifndef GL_ARB_depth_buffer_float +#define GL_ARB_depth_buffer_float 1 + +#define GL_DEPTH_COMPONENT32F 0x8CAC +#define GL_DEPTH32F_STENCIL8 0x8CAD +#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD + +#define GLEW_ARB_depth_buffer_float GLEW_GET_VAR(__GLEW_ARB_depth_buffer_float) + +#endif /* GL_ARB_depth_buffer_float */ + +/* -------------------------- GL_ARB_depth_texture ------------------------- */ + +#ifndef GL_ARB_depth_texture +#define GL_ARB_depth_texture 1 + +#define GL_DEPTH_COMPONENT16_ARB 0x81A5 +#define GL_DEPTH_COMPONENT24_ARB 0x81A6 +#define GL_DEPTH_COMPONENT32_ARB 0x81A7 +#define GL_TEXTURE_DEPTH_SIZE_ARB 0x884A +#define GL_DEPTH_TEXTURE_MODE_ARB 0x884B + +#define GLEW_ARB_depth_texture GLEW_GET_VAR(__GLEW_ARB_depth_texture) + +#endif /* GL_ARB_depth_texture */ + +/* -------------------------- GL_ARB_draw_buffers -------------------------- */ + +#ifndef GL_ARB_draw_buffers +#define GL_ARB_draw_buffers 1 + +#define GL_MAX_DRAW_BUFFERS_ARB 0x8824 +#define GL_DRAW_BUFFER0_ARB 0x8825 +#define GL_DRAW_BUFFER1_ARB 0x8826 +#define GL_DRAW_BUFFER2_ARB 0x8827 +#define GL_DRAW_BUFFER3_ARB 0x8828 +#define GL_DRAW_BUFFER4_ARB 0x8829 +#define GL_DRAW_BUFFER5_ARB 0x882A +#define GL_DRAW_BUFFER6_ARB 0x882B +#define GL_DRAW_BUFFER7_ARB 0x882C +#define GL_DRAW_BUFFER8_ARB 0x882D +#define GL_DRAW_BUFFER9_ARB 0x882E +#define GL_DRAW_BUFFER10_ARB 0x882F +#define GL_DRAW_BUFFER11_ARB 0x8830 +#define GL_DRAW_BUFFER12_ARB 0x8831 +#define GL_DRAW_BUFFER13_ARB 0x8832 +#define GL_DRAW_BUFFER14_ARB 0x8833 +#define GL_DRAW_BUFFER15_ARB 0x8834 + +typedef void (GLAPIENTRY * PFNGLDRAWBUFFERSARBPROC) (GLsizei n, const GLenum* bufs); + +#define glDrawBuffersARB GLEW_GET_FUN(__glewDrawBuffersARB) + +#define GLEW_ARB_draw_buffers GLEW_GET_VAR(__GLEW_ARB_draw_buffers) + +#endif /* GL_ARB_draw_buffers */ + +/* ------------------------- GL_ARB_draw_instanced ------------------------- */ + +#ifndef GL_ARB_draw_instanced +#define GL_ARB_draw_instanced 1 + +typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINSTANCEDARBPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount); +typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDARBPROC) (GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei primcount); + +#define glDrawArraysInstancedARB GLEW_GET_FUN(__glewDrawArraysInstancedARB) +#define glDrawElementsInstancedARB GLEW_GET_FUN(__glewDrawElementsInstancedARB) + +#define GLEW_ARB_draw_instanced GLEW_GET_VAR(__GLEW_ARB_draw_instanced) + +#endif /* GL_ARB_draw_instanced */ + +/* ------------------------ GL_ARB_fragment_program ------------------------ */ + +#ifndef GL_ARB_fragment_program +#define GL_ARB_fragment_program 1 + +#define GL_FRAGMENT_PROGRAM_ARB 0x8804 +#define GL_PROGRAM_ALU_INSTRUCTIONS_ARB 0x8805 +#define GL_PROGRAM_TEX_INSTRUCTIONS_ARB 0x8806 +#define GL_PROGRAM_TEX_INDIRECTIONS_ARB 0x8807 +#define GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x8808 +#define GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x8809 +#define GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x880A +#define GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB 0x880B +#define GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB 0x880C +#define GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB 0x880D +#define GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x880E +#define GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x880F +#define GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x8810 +#define GL_MAX_TEXTURE_COORDS_ARB 0x8871 +#define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872 + +#define GLEW_ARB_fragment_program GLEW_GET_VAR(__GLEW_ARB_fragment_program) + +#endif /* GL_ARB_fragment_program */ + +/* --------------------- GL_ARB_fragment_program_shadow -------------------- */ + +#ifndef GL_ARB_fragment_program_shadow +#define GL_ARB_fragment_program_shadow 1 + +#define GLEW_ARB_fragment_program_shadow GLEW_GET_VAR(__GLEW_ARB_fragment_program_shadow) + +#endif /* GL_ARB_fragment_program_shadow */ + +/* ------------------------- GL_ARB_fragment_shader ------------------------ */ + +#ifndef GL_ARB_fragment_shader +#define GL_ARB_fragment_shader 1 + +#define GL_FRAGMENT_SHADER_ARB 0x8B30 +#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB 0x8B49 +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB 0x8B8B + +#define GLEW_ARB_fragment_shader GLEW_GET_VAR(__GLEW_ARB_fragment_shader) + +#endif /* GL_ARB_fragment_shader */ + +/* ----------------------- GL_ARB_framebuffer_object ----------------------- */ + +#ifndef GL_ARB_framebuffer_object +#define GL_ARB_framebuffer_object 1 + +#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 +#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210 +#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211 +#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212 +#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213 +#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214 +#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215 +#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216 +#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217 +#define GL_FRAMEBUFFER_DEFAULT 0x8218 +#define GL_FRAMEBUFFER_UNDEFINED 0x8219 +#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A +#define GL_INDEX 0x8222 +#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 +#define GL_DEPTH_STENCIL 0x84F9 +#define GL_UNSIGNED_INT_24_8 0x84FA +#define GL_DEPTH24_STENCIL8 0x88F0 +#define GL_TEXTURE_STENCIL_SIZE 0x88F1 +#define GL_UNSIGNED_NORMALIZED 0x8C17 +#define GL_SRGB 0x8C40 +#define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_RENDERBUFFER_BINDING 0x8CA7 +#define GL_READ_FRAMEBUFFER 0x8CA8 +#define GL_DRAW_FRAMEBUFFER 0x8CA9 +#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA +#define GL_RENDERBUFFER_SAMPLES 0x8CAB +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 +#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB +#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC +#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD +#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF +#define GL_COLOR_ATTACHMENT0 0x8CE0 +#define GL_COLOR_ATTACHMENT1 0x8CE1 +#define GL_COLOR_ATTACHMENT2 0x8CE2 +#define GL_COLOR_ATTACHMENT3 0x8CE3 +#define GL_COLOR_ATTACHMENT4 0x8CE4 +#define GL_COLOR_ATTACHMENT5 0x8CE5 +#define GL_COLOR_ATTACHMENT6 0x8CE6 +#define GL_COLOR_ATTACHMENT7 0x8CE7 +#define GL_COLOR_ATTACHMENT8 0x8CE8 +#define GL_COLOR_ATTACHMENT9 0x8CE9 +#define GL_COLOR_ATTACHMENT10 0x8CEA +#define GL_COLOR_ATTACHMENT11 0x8CEB +#define GL_COLOR_ATTACHMENT12 0x8CEC +#define GL_COLOR_ATTACHMENT13 0x8CED +#define GL_COLOR_ATTACHMENT14 0x8CEE +#define GL_COLOR_ATTACHMENT15 0x8CEF +#define GL_DEPTH_ATTACHMENT 0x8D00 +#define GL_STENCIL_ATTACHMENT 0x8D20 +#define GL_FRAMEBUFFER 0x8D40 +#define GL_RENDERBUFFER 0x8D41 +#define GL_RENDERBUFFER_WIDTH 0x8D42 +#define GL_RENDERBUFFER_HEIGHT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 +#define GL_STENCIL_INDEX1 0x8D46 +#define GL_STENCIL_INDEX4 0x8D47 +#define GL_STENCIL_INDEX8 0x8D48 +#define GL_STENCIL_INDEX16 0x8D49 +#define GL_RENDERBUFFER_RED_SIZE 0x8D50 +#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 +#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 +#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 +#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 +#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 +#define GL_MAX_SAMPLES 0x8D57 + +typedef void (GLAPIENTRY * PFNGLBINDFRAMEBUFFERPROC) (GLenum target, GLuint framebuffer); +typedef void (GLAPIENTRY * PFNGLBINDRENDERBUFFERPROC) (GLenum target, GLuint renderbuffer); +typedef void (GLAPIENTRY * PFNGLBLITFRAMEBUFFERPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +typedef GLenum (GLAPIENTRY * PFNGLCHECKFRAMEBUFFERSTATUSPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLDELETEFRAMEBUFFERSPROC) (GLsizei n, const GLuint* framebuffers); +typedef void (GLAPIENTRY * PFNGLDELETERENDERBUFFERSPROC) (GLsizei n, const GLuint* renderbuffers); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERRENDERBUFFERPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURLAYERPROC) (GLenum target,GLenum attachment, GLuint texture,GLint level,GLint layer); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE1DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE2DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE3DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint layer); +typedef void (GLAPIENTRY * PFNGLGENFRAMEBUFFERSPROC) (GLsizei n, GLuint* framebuffers); +typedef void (GLAPIENTRY * PFNGLGENRENDERBUFFERSPROC) (GLsizei n, GLuint* renderbuffers); +typedef void (GLAPIENTRY * PFNGLGENERATEMIPMAPPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLenum target, GLenum attachment, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETRENDERBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISFRAMEBUFFERPROC) (GLuint framebuffer); +typedef GLboolean (GLAPIENTRY * PFNGLISRENDERBUFFERPROC) (GLuint renderbuffer); +typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); + +#define glBindFramebuffer GLEW_GET_FUN(__glewBindFramebuffer) +#define glBindRenderbuffer GLEW_GET_FUN(__glewBindRenderbuffer) +#define glBlitFramebuffer GLEW_GET_FUN(__glewBlitFramebuffer) +#define glCheckFramebufferStatus GLEW_GET_FUN(__glewCheckFramebufferStatus) +#define glDeleteFramebuffers GLEW_GET_FUN(__glewDeleteFramebuffers) +#define glDeleteRenderbuffers GLEW_GET_FUN(__glewDeleteRenderbuffers) +#define glFramebufferRenderbuffer GLEW_GET_FUN(__glewFramebufferRenderbuffer) +#define glFramebufferTexturLayer GLEW_GET_FUN(__glewFramebufferTexturLayer) +#define glFramebufferTexture1D GLEW_GET_FUN(__glewFramebufferTexture1D) +#define glFramebufferTexture2D GLEW_GET_FUN(__glewFramebufferTexture2D) +#define glFramebufferTexture3D GLEW_GET_FUN(__glewFramebufferTexture3D) +#define glGenFramebuffers GLEW_GET_FUN(__glewGenFramebuffers) +#define glGenRenderbuffers GLEW_GET_FUN(__glewGenRenderbuffers) +#define glGenerateMipmap GLEW_GET_FUN(__glewGenerateMipmap) +#define glGetFramebufferAttachmentParameteriv GLEW_GET_FUN(__glewGetFramebufferAttachmentParameteriv) +#define glGetRenderbufferParameteriv GLEW_GET_FUN(__glewGetRenderbufferParameteriv) +#define glIsFramebuffer GLEW_GET_FUN(__glewIsFramebuffer) +#define glIsRenderbuffer GLEW_GET_FUN(__glewIsRenderbuffer) +#define glRenderbufferStorage GLEW_GET_FUN(__glewRenderbufferStorage) +#define glRenderbufferStorageMultisample GLEW_GET_FUN(__glewRenderbufferStorageMultisample) + +#define GLEW_ARB_framebuffer_object GLEW_GET_VAR(__GLEW_ARB_framebuffer_object) + +#endif /* GL_ARB_framebuffer_object */ + +/* ------------------------ GL_ARB_framebuffer_sRGB ------------------------ */ + +#ifndef GL_ARB_framebuffer_sRGB +#define GL_ARB_framebuffer_sRGB 1 + +#define GL_FRAMEBUFFER_SRGB 0x8DB9 + +#define GLEW_ARB_framebuffer_sRGB GLEW_GET_VAR(__GLEW_ARB_framebuffer_sRGB) + +#endif /* GL_ARB_framebuffer_sRGB */ + +/* ------------------------ GL_ARB_geometry_shader4 ------------------------ */ + +#ifndef GL_ARB_geometry_shader4 +#define GL_ARB_geometry_shader4 1 + +#define GL_LINES_ADJACENCY_ARB 0xA +#define GL_LINE_STRIP_ADJACENCY_ARB 0xB +#define GL_TRIANGLES_ADJACENCY_ARB 0xC +#define GL_TRIANGLE_STRIP_ADJACENCY_ARB 0xD +#define GL_PROGRAM_POINT_SIZE_ARB 0x8642 +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB 0x8C29 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_ARB 0x8DA7 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB 0x8DA8 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB 0x8DA9 +#define GL_GEOMETRY_SHADER_ARB 0x8DD9 +#define GL_GEOMETRY_VERTICES_OUT_ARB 0x8DDA +#define GL_GEOMETRY_INPUT_TYPE_ARB 0x8DDB +#define GL_GEOMETRY_OUTPUT_TYPE_ARB 0x8DDC +#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_ARB 0x8DDD +#define GL_MAX_VERTEX_VARYING_COMPONENTS_ARB 0x8DDE +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB 0x8DDF +#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_ARB 0x8DE0 +#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB 0x8DE1 + +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREFACEARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURELAYERARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETERIARBPROC) (GLuint program, GLenum pname, GLint value); + +#define glFramebufferTextureARB GLEW_GET_FUN(__glewFramebufferTextureARB) +#define glFramebufferTextureFaceARB GLEW_GET_FUN(__glewFramebufferTextureFaceARB) +#define glFramebufferTextureLayerARB GLEW_GET_FUN(__glewFramebufferTextureLayerARB) +#define glProgramParameteriARB GLEW_GET_FUN(__glewProgramParameteriARB) + +#define GLEW_ARB_geometry_shader4 GLEW_GET_VAR(__GLEW_ARB_geometry_shader4) + +#endif /* GL_ARB_geometry_shader4 */ + +/* ------------------------ GL_ARB_half_float_pixel ------------------------ */ + +#ifndef GL_ARB_half_float_pixel +#define GL_ARB_half_float_pixel 1 + +#define GL_HALF_FLOAT_ARB 0x140B + +#define GLEW_ARB_half_float_pixel GLEW_GET_VAR(__GLEW_ARB_half_float_pixel) + +#endif /* GL_ARB_half_float_pixel */ + +/* ------------------------ GL_ARB_half_float_vertex ----------------------- */ + +#ifndef GL_ARB_half_float_vertex +#define GL_ARB_half_float_vertex 1 + +#define GL_HALF_FLOAT 0x140B + +#define GLEW_ARB_half_float_vertex GLEW_GET_VAR(__GLEW_ARB_half_float_vertex) + +#endif /* GL_ARB_half_float_vertex */ + +/* ----------------------------- GL_ARB_imaging ---------------------------- */ + +#ifndef GL_ARB_imaging +#define GL_ARB_imaging 1 + +#define GL_CONSTANT_COLOR 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 +#define GL_CONSTANT_ALPHA 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 +#define GL_BLEND_COLOR 0x8005 +#define GL_FUNC_ADD 0x8006 +#define GL_MIN 0x8007 +#define GL_MAX 0x8008 +#define GL_BLEND_EQUATION 0x8009 +#define GL_FUNC_SUBTRACT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT 0x800B +#define GL_CONVOLUTION_1D 0x8010 +#define GL_CONVOLUTION_2D 0x8011 +#define GL_SEPARABLE_2D 0x8012 +#define GL_CONVOLUTION_BORDER_MODE 0x8013 +#define GL_CONVOLUTION_FILTER_SCALE 0x8014 +#define GL_CONVOLUTION_FILTER_BIAS 0x8015 +#define GL_REDUCE 0x8016 +#define GL_CONVOLUTION_FORMAT 0x8017 +#define GL_CONVOLUTION_WIDTH 0x8018 +#define GL_CONVOLUTION_HEIGHT 0x8019 +#define GL_MAX_CONVOLUTION_WIDTH 0x801A +#define GL_MAX_CONVOLUTION_HEIGHT 0x801B +#define GL_POST_CONVOLUTION_RED_SCALE 0x801C +#define GL_POST_CONVOLUTION_GREEN_SCALE 0x801D +#define GL_POST_CONVOLUTION_BLUE_SCALE 0x801E +#define GL_POST_CONVOLUTION_ALPHA_SCALE 0x801F +#define GL_POST_CONVOLUTION_RED_BIAS 0x8020 +#define GL_POST_CONVOLUTION_GREEN_BIAS 0x8021 +#define GL_POST_CONVOLUTION_BLUE_BIAS 0x8022 +#define GL_POST_CONVOLUTION_ALPHA_BIAS 0x8023 +#define GL_HISTOGRAM 0x8024 +#define GL_PROXY_HISTOGRAM 0x8025 +#define GL_HISTOGRAM_WIDTH 0x8026 +#define GL_HISTOGRAM_FORMAT 0x8027 +#define GL_HISTOGRAM_RED_SIZE 0x8028 +#define GL_HISTOGRAM_GREEN_SIZE 0x8029 +#define GL_HISTOGRAM_BLUE_SIZE 0x802A +#define GL_HISTOGRAM_ALPHA_SIZE 0x802B +#define GL_HISTOGRAM_LUMINANCE_SIZE 0x802C +#define GL_HISTOGRAM_SINK 0x802D +#define GL_MINMAX 0x802E +#define GL_MINMAX_FORMAT 0x802F +#define GL_MINMAX_SINK 0x8030 +#define GL_TABLE_TOO_LARGE 0x8031 +#define GL_COLOR_MATRIX 0x80B1 +#define GL_COLOR_MATRIX_STACK_DEPTH 0x80B2 +#define GL_MAX_COLOR_MATRIX_STACK_DEPTH 0x80B3 +#define GL_POST_COLOR_MATRIX_RED_SCALE 0x80B4 +#define GL_POST_COLOR_MATRIX_GREEN_SCALE 0x80B5 +#define GL_POST_COLOR_MATRIX_BLUE_SCALE 0x80B6 +#define GL_POST_COLOR_MATRIX_ALPHA_SCALE 0x80B7 +#define GL_POST_COLOR_MATRIX_RED_BIAS 0x80B8 +#define GL_POST_COLOR_MATRIX_GREEN_BIAS 0x80B9 +#define GL_POST_COLOR_MATRIX_BLUE_BIAS 0x80BA +#define GL_POST_COLOR_MATRIX_ALPHA_BIAS 0x80BB +#define GL_COLOR_TABLE 0x80D0 +#define GL_POST_CONVOLUTION_COLOR_TABLE 0x80D1 +#define GL_POST_COLOR_MATRIX_COLOR_TABLE 0x80D2 +#define GL_PROXY_COLOR_TABLE 0x80D3 +#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE 0x80D4 +#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE 0x80D5 +#define GL_COLOR_TABLE_SCALE 0x80D6 +#define GL_COLOR_TABLE_BIAS 0x80D7 +#define GL_COLOR_TABLE_FORMAT 0x80D8 +#define GL_COLOR_TABLE_WIDTH 0x80D9 +#define GL_COLOR_TABLE_RED_SIZE 0x80DA +#define GL_COLOR_TABLE_GREEN_SIZE 0x80DB +#define GL_COLOR_TABLE_BLUE_SIZE 0x80DC +#define GL_COLOR_TABLE_ALPHA_SIZE 0x80DD +#define GL_COLOR_TABLE_LUMINANCE_SIZE 0x80DE +#define GL_COLOR_TABLE_INTENSITY_SIZE 0x80DF +#define GL_IGNORE_BORDER 0x8150 +#define GL_CONSTANT_BORDER 0x8151 +#define GL_WRAP_BORDER 0x8152 +#define GL_REPLICATE_BORDER 0x8153 +#define GL_CONVOLUTION_BORDER_COLOR 0x8154 + +typedef void (GLAPIENTRY * PFNGLCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data); +typedef void (GLAPIENTRY * PFNGLCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); +typedef void (GLAPIENTRY * PFNGLCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (GLAPIENTRY * PFNGLCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat params); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERIPROC) (GLenum target, GLenum pname, GLint params); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (GLAPIENTRY * PFNGLCOPYCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRY * PFNGLCOPYCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRY * PFNGLCOPYCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRY * PFNGLCOPYCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPROC) (GLenum target, GLenum format, GLenum type, GLvoid *table); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *image); +typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); +typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GLAPIENTRY * PFNGLGETMINMAXPROC) (GLenum target, GLboolean reset, GLenum format, GLenum types, GLvoid *values); +typedef void (GLAPIENTRY * PFNGLGETMINMAXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (GLAPIENTRY * PFNGLGETMINMAXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GLAPIENTRY * PFNGLGETSEPARABLEFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span); +typedef void (GLAPIENTRY * PFNGLHISTOGRAMPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); +typedef void (GLAPIENTRY * PFNGLMINMAXPROC) (GLenum target, GLenum internalformat, GLboolean sink); +typedef void (GLAPIENTRY * PFNGLRESETHISTOGRAMPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLRESETMINMAXPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLSEPARABLEFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column); + +#define glColorSubTable GLEW_GET_FUN(__glewColorSubTable) +#define glColorTable GLEW_GET_FUN(__glewColorTable) +#define glColorTableParameterfv GLEW_GET_FUN(__glewColorTableParameterfv) +#define glColorTableParameteriv GLEW_GET_FUN(__glewColorTableParameteriv) +#define glConvolutionFilter1D GLEW_GET_FUN(__glewConvolutionFilter1D) +#define glConvolutionFilter2D GLEW_GET_FUN(__glewConvolutionFilter2D) +#define glConvolutionParameterf GLEW_GET_FUN(__glewConvolutionParameterf) +#define glConvolutionParameterfv GLEW_GET_FUN(__glewConvolutionParameterfv) +#define glConvolutionParameteri GLEW_GET_FUN(__glewConvolutionParameteri) +#define glConvolutionParameteriv GLEW_GET_FUN(__glewConvolutionParameteriv) +#define glCopyColorSubTable GLEW_GET_FUN(__glewCopyColorSubTable) +#define glCopyColorTable GLEW_GET_FUN(__glewCopyColorTable) +#define glCopyConvolutionFilter1D GLEW_GET_FUN(__glewCopyConvolutionFilter1D) +#define glCopyConvolutionFilter2D GLEW_GET_FUN(__glewCopyConvolutionFilter2D) +#define glGetColorTable GLEW_GET_FUN(__glewGetColorTable) +#define glGetColorTableParameterfv GLEW_GET_FUN(__glewGetColorTableParameterfv) +#define glGetColorTableParameteriv GLEW_GET_FUN(__glewGetColorTableParameteriv) +#define glGetConvolutionFilter GLEW_GET_FUN(__glewGetConvolutionFilter) +#define glGetConvolutionParameterfv GLEW_GET_FUN(__glewGetConvolutionParameterfv) +#define glGetConvolutionParameteriv GLEW_GET_FUN(__glewGetConvolutionParameteriv) +#define glGetHistogram GLEW_GET_FUN(__glewGetHistogram) +#define glGetHistogramParameterfv GLEW_GET_FUN(__glewGetHistogramParameterfv) +#define glGetHistogramParameteriv GLEW_GET_FUN(__glewGetHistogramParameteriv) +#define glGetMinmax GLEW_GET_FUN(__glewGetMinmax) +#define glGetMinmaxParameterfv GLEW_GET_FUN(__glewGetMinmaxParameterfv) +#define glGetMinmaxParameteriv GLEW_GET_FUN(__glewGetMinmaxParameteriv) +#define glGetSeparableFilter GLEW_GET_FUN(__glewGetSeparableFilter) +#define glHistogram GLEW_GET_FUN(__glewHistogram) +#define glMinmax GLEW_GET_FUN(__glewMinmax) +#define glResetHistogram GLEW_GET_FUN(__glewResetHistogram) +#define glResetMinmax GLEW_GET_FUN(__glewResetMinmax) +#define glSeparableFilter2D GLEW_GET_FUN(__glewSeparableFilter2D) + +#define GLEW_ARB_imaging GLEW_GET_VAR(__GLEW_ARB_imaging) + +#endif /* GL_ARB_imaging */ + +/* ------------------------ GL_ARB_instanced_arrays ------------------------ */ + +#ifndef GL_ARB_instanced_arrays +#define GL_ARB_instanced_arrays 1 + +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB 0x88FE + +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBDIVISORARBPROC) (GLuint index, GLuint divisor); + +#define glVertexAttribDivisorARB GLEW_GET_FUN(__glewVertexAttribDivisorARB) + +#define GLEW_ARB_instanced_arrays GLEW_GET_VAR(__GLEW_ARB_instanced_arrays) + +#endif /* GL_ARB_instanced_arrays */ + +/* ------------------------ GL_ARB_map_buffer_range ------------------------ */ + +#ifndef GL_ARB_map_buffer_range +#define GL_ARB_map_buffer_range 1 + +#define GL_MAP_READ_BIT 0x0001 +#define GL_MAP_WRITE_BIT 0x0002 +#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004 +#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008 +#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010 +#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020 + +typedef void (GLAPIENTRY * PFNGLFLUSHMAPPEDBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length); +typedef GLvoid * (GLAPIENTRY * PFNGLMAPBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); + +#define glFlushMappedBufferRange GLEW_GET_FUN(__glewFlushMappedBufferRange) +#define glMapBufferRange GLEW_GET_FUN(__glewMapBufferRange) + +#define GLEW_ARB_map_buffer_range GLEW_GET_VAR(__GLEW_ARB_map_buffer_range) + +#endif /* GL_ARB_map_buffer_range */ + +/* ------------------------- GL_ARB_matrix_palette ------------------------- */ + +#ifndef GL_ARB_matrix_palette +#define GL_ARB_matrix_palette 1 + +#define GL_MATRIX_PALETTE_ARB 0x8840 +#define GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB 0x8841 +#define GL_MAX_PALETTE_MATRICES_ARB 0x8842 +#define GL_CURRENT_PALETTE_MATRIX_ARB 0x8843 +#define GL_MATRIX_INDEX_ARRAY_ARB 0x8844 +#define GL_CURRENT_MATRIX_INDEX_ARB 0x8845 +#define GL_MATRIX_INDEX_ARRAY_SIZE_ARB 0x8846 +#define GL_MATRIX_INDEX_ARRAY_TYPE_ARB 0x8847 +#define GL_MATRIX_INDEX_ARRAY_STRIDE_ARB 0x8848 +#define GL_MATRIX_INDEX_ARRAY_POINTER_ARB 0x8849 + +typedef void (GLAPIENTRY * PFNGLCURRENTPALETTEMATRIXARBPROC) (GLint index); +typedef void (GLAPIENTRY * PFNGLMATRIXINDEXPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, GLvoid *pointer); +typedef void (GLAPIENTRY * PFNGLMATRIXINDEXUBVARBPROC) (GLint size, GLubyte *indices); +typedef void (GLAPIENTRY * PFNGLMATRIXINDEXUIVARBPROC) (GLint size, GLuint *indices); +typedef void (GLAPIENTRY * PFNGLMATRIXINDEXUSVARBPROC) (GLint size, GLushort *indices); + +#define glCurrentPaletteMatrixARB GLEW_GET_FUN(__glewCurrentPaletteMatrixARB) +#define glMatrixIndexPointerARB GLEW_GET_FUN(__glewMatrixIndexPointerARB) +#define glMatrixIndexubvARB GLEW_GET_FUN(__glewMatrixIndexubvARB) +#define glMatrixIndexuivARB GLEW_GET_FUN(__glewMatrixIndexuivARB) +#define glMatrixIndexusvARB GLEW_GET_FUN(__glewMatrixIndexusvARB) + +#define GLEW_ARB_matrix_palette GLEW_GET_VAR(__GLEW_ARB_matrix_palette) + +#endif /* GL_ARB_matrix_palette */ + +/* --------------------------- GL_ARB_multisample -------------------------- */ + +#ifndef GL_ARB_multisample +#define GL_ARB_multisample 1 + +#define GL_MULTISAMPLE_ARB 0x809D +#define GL_SAMPLE_ALPHA_TO_COVERAGE_ARB 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_ARB 0x809F +#define GL_SAMPLE_COVERAGE_ARB 0x80A0 +#define GL_SAMPLE_BUFFERS_ARB 0x80A8 +#define GL_SAMPLES_ARB 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE_ARB 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT_ARB 0x80AB +#define GL_MULTISAMPLE_BIT_ARB 0x20000000 + +typedef void (GLAPIENTRY * PFNGLSAMPLECOVERAGEARBPROC) (GLclampf value, GLboolean invert); + +#define glSampleCoverageARB GLEW_GET_FUN(__glewSampleCoverageARB) + +#define GLEW_ARB_multisample GLEW_GET_VAR(__GLEW_ARB_multisample) + +#endif /* GL_ARB_multisample */ + +/* -------------------------- GL_ARB_multitexture -------------------------- */ + +#ifndef GL_ARB_multitexture +#define GL_ARB_multitexture 1 + +#define GL_TEXTURE0_ARB 0x84C0 +#define GL_TEXTURE1_ARB 0x84C1 +#define GL_TEXTURE2_ARB 0x84C2 +#define GL_TEXTURE3_ARB 0x84C3 +#define GL_TEXTURE4_ARB 0x84C4 +#define GL_TEXTURE5_ARB 0x84C5 +#define GL_TEXTURE6_ARB 0x84C6 +#define GL_TEXTURE7_ARB 0x84C7 +#define GL_TEXTURE8_ARB 0x84C8 +#define GL_TEXTURE9_ARB 0x84C9 +#define GL_TEXTURE10_ARB 0x84CA +#define GL_TEXTURE11_ARB 0x84CB +#define GL_TEXTURE12_ARB 0x84CC +#define GL_TEXTURE13_ARB 0x84CD +#define GL_TEXTURE14_ARB 0x84CE +#define GL_TEXTURE15_ARB 0x84CF +#define GL_TEXTURE16_ARB 0x84D0 +#define GL_TEXTURE17_ARB 0x84D1 +#define GL_TEXTURE18_ARB 0x84D2 +#define GL_TEXTURE19_ARB 0x84D3 +#define GL_TEXTURE20_ARB 0x84D4 +#define GL_TEXTURE21_ARB 0x84D5 +#define GL_TEXTURE22_ARB 0x84D6 +#define GL_TEXTURE23_ARB 0x84D7 +#define GL_TEXTURE24_ARB 0x84D8 +#define GL_TEXTURE25_ARB 0x84D9 +#define GL_TEXTURE26_ARB 0x84DA +#define GL_TEXTURE27_ARB 0x84DB +#define GL_TEXTURE28_ARB 0x84DC +#define GL_TEXTURE29_ARB 0x84DD +#define GL_TEXTURE30_ARB 0x84DE +#define GL_TEXTURE31_ARB 0x84DF +#define GL_ACTIVE_TEXTURE_ARB 0x84E0 +#define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1 +#define GL_MAX_TEXTURE_UNITS_ARB 0x84E2 + +typedef void (GLAPIENTRY * PFNGLACTIVETEXTUREARBPROC) (GLenum texture); +typedef void (GLAPIENTRY * PFNGLCLIENTACTIVETEXTUREARBPROC) (GLenum texture); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1DARBPROC) (GLenum target, GLdouble s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1FARBPROC) (GLenum target, GLfloat s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1IARBPROC) (GLenum target, GLint s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1IVARBPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1SARBPROC) (GLenum target, GLshort s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1SVARBPROC) (GLenum target, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2DARBPROC) (GLenum target, GLdouble s, GLdouble t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2FARBPROC) (GLenum target, GLfloat s, GLfloat t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2IARBPROC) (GLenum target, GLint s, GLint t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2IVARBPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2SARBPROC) (GLenum target, GLshort s, GLshort t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2SVARBPROC) (GLenum target, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3IARBPROC) (GLenum target, GLint s, GLint t, GLint r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3IVARBPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3SVARBPROC) (GLenum target, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4IARBPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4IVARBPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4SVARBPROC) (GLenum target, const GLshort *v); + +#define glActiveTextureARB GLEW_GET_FUN(__glewActiveTextureARB) +#define glClientActiveTextureARB GLEW_GET_FUN(__glewClientActiveTextureARB) +#define glMultiTexCoord1dARB GLEW_GET_FUN(__glewMultiTexCoord1dARB) +#define glMultiTexCoord1dvARB GLEW_GET_FUN(__glewMultiTexCoord1dvARB) +#define glMultiTexCoord1fARB GLEW_GET_FUN(__glewMultiTexCoord1fARB) +#define glMultiTexCoord1fvARB GLEW_GET_FUN(__glewMultiTexCoord1fvARB) +#define glMultiTexCoord1iARB GLEW_GET_FUN(__glewMultiTexCoord1iARB) +#define glMultiTexCoord1ivARB GLEW_GET_FUN(__glewMultiTexCoord1ivARB) +#define glMultiTexCoord1sARB GLEW_GET_FUN(__glewMultiTexCoord1sARB) +#define glMultiTexCoord1svARB GLEW_GET_FUN(__glewMultiTexCoord1svARB) +#define glMultiTexCoord2dARB GLEW_GET_FUN(__glewMultiTexCoord2dARB) +#define glMultiTexCoord2dvARB GLEW_GET_FUN(__glewMultiTexCoord2dvARB) +#define glMultiTexCoord2fARB GLEW_GET_FUN(__glewMultiTexCoord2fARB) +#define glMultiTexCoord2fvARB GLEW_GET_FUN(__glewMultiTexCoord2fvARB) +#define glMultiTexCoord2iARB GLEW_GET_FUN(__glewMultiTexCoord2iARB) +#define glMultiTexCoord2ivARB GLEW_GET_FUN(__glewMultiTexCoord2ivARB) +#define glMultiTexCoord2sARB GLEW_GET_FUN(__glewMultiTexCoord2sARB) +#define glMultiTexCoord2svARB GLEW_GET_FUN(__glewMultiTexCoord2svARB) +#define glMultiTexCoord3dARB GLEW_GET_FUN(__glewMultiTexCoord3dARB) +#define glMultiTexCoord3dvARB GLEW_GET_FUN(__glewMultiTexCoord3dvARB) +#define glMultiTexCoord3fARB GLEW_GET_FUN(__glewMultiTexCoord3fARB) +#define glMultiTexCoord3fvARB GLEW_GET_FUN(__glewMultiTexCoord3fvARB) +#define glMultiTexCoord3iARB GLEW_GET_FUN(__glewMultiTexCoord3iARB) +#define glMultiTexCoord3ivARB GLEW_GET_FUN(__glewMultiTexCoord3ivARB) +#define glMultiTexCoord3sARB GLEW_GET_FUN(__glewMultiTexCoord3sARB) +#define glMultiTexCoord3svARB GLEW_GET_FUN(__glewMultiTexCoord3svARB) +#define glMultiTexCoord4dARB GLEW_GET_FUN(__glewMultiTexCoord4dARB) +#define glMultiTexCoord4dvARB GLEW_GET_FUN(__glewMultiTexCoord4dvARB) +#define glMultiTexCoord4fARB GLEW_GET_FUN(__glewMultiTexCoord4fARB) +#define glMultiTexCoord4fvARB GLEW_GET_FUN(__glewMultiTexCoord4fvARB) +#define glMultiTexCoord4iARB GLEW_GET_FUN(__glewMultiTexCoord4iARB) +#define glMultiTexCoord4ivARB GLEW_GET_FUN(__glewMultiTexCoord4ivARB) +#define glMultiTexCoord4sARB GLEW_GET_FUN(__glewMultiTexCoord4sARB) +#define glMultiTexCoord4svARB GLEW_GET_FUN(__glewMultiTexCoord4svARB) + +#define GLEW_ARB_multitexture GLEW_GET_VAR(__GLEW_ARB_multitexture) + +#endif /* GL_ARB_multitexture */ + +/* ------------------------- GL_ARB_occlusion_query ------------------------ */ + +#ifndef GL_ARB_occlusion_query +#define GL_ARB_occlusion_query 1 + +#define GL_QUERY_COUNTER_BITS_ARB 0x8864 +#define GL_CURRENT_QUERY_ARB 0x8865 +#define GL_QUERY_RESULT_ARB 0x8866 +#define GL_QUERY_RESULT_AVAILABLE_ARB 0x8867 +#define GL_SAMPLES_PASSED_ARB 0x8914 + +typedef void (GLAPIENTRY * PFNGLBEGINQUERYARBPROC) (GLenum target, GLuint id); +typedef void (GLAPIENTRY * PFNGLDELETEQUERIESARBPROC) (GLsizei n, const GLuint* ids); +typedef void (GLAPIENTRY * PFNGLENDQUERYARBPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLGENQUERIESARBPROC) (GLsizei n, GLuint* ids); +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTIVARBPROC) (GLuint id, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUIVARBPROC) (GLuint id, GLenum pname, GLuint* params); +typedef void (GLAPIENTRY * PFNGLGETQUERYIVARBPROC) (GLenum target, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISQUERYARBPROC) (GLuint id); + +#define glBeginQueryARB GLEW_GET_FUN(__glewBeginQueryARB) +#define glDeleteQueriesARB GLEW_GET_FUN(__glewDeleteQueriesARB) +#define glEndQueryARB GLEW_GET_FUN(__glewEndQueryARB) +#define glGenQueriesARB GLEW_GET_FUN(__glewGenQueriesARB) +#define glGetQueryObjectivARB GLEW_GET_FUN(__glewGetQueryObjectivARB) +#define glGetQueryObjectuivARB GLEW_GET_FUN(__glewGetQueryObjectuivARB) +#define glGetQueryivARB GLEW_GET_FUN(__glewGetQueryivARB) +#define glIsQueryARB GLEW_GET_FUN(__glewIsQueryARB) + +#define GLEW_ARB_occlusion_query GLEW_GET_VAR(__GLEW_ARB_occlusion_query) + +#endif /* GL_ARB_occlusion_query */ + +/* ----------------------- GL_ARB_pixel_buffer_object ---------------------- */ + +#ifndef GL_ARB_pixel_buffer_object +#define GL_ARB_pixel_buffer_object 1 + +#define GL_PIXEL_PACK_BUFFER_ARB 0x88EB +#define GL_PIXEL_UNPACK_BUFFER_ARB 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING_ARB 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING_ARB 0x88EF + +#define GLEW_ARB_pixel_buffer_object GLEW_GET_VAR(__GLEW_ARB_pixel_buffer_object) + +#endif /* GL_ARB_pixel_buffer_object */ + +/* ------------------------ GL_ARB_point_parameters ------------------------ */ + +#ifndef GL_ARB_point_parameters +#define GL_ARB_point_parameters 1 + +#define GL_POINT_SIZE_MIN_ARB 0x8126 +#define GL_POINT_SIZE_MAX_ARB 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE_ARB 0x8128 +#define GL_POINT_DISTANCE_ATTENUATION_ARB 0x8129 + +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFARBPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFVARBPROC) (GLenum pname, GLfloat* params); + +#define glPointParameterfARB GLEW_GET_FUN(__glewPointParameterfARB) +#define glPointParameterfvARB GLEW_GET_FUN(__glewPointParameterfvARB) + +#define GLEW_ARB_point_parameters GLEW_GET_VAR(__GLEW_ARB_point_parameters) + +#endif /* GL_ARB_point_parameters */ + +/* -------------------------- GL_ARB_point_sprite -------------------------- */ + +#ifndef GL_ARB_point_sprite +#define GL_ARB_point_sprite 1 + +#define GL_POINT_SPRITE_ARB 0x8861 +#define GL_COORD_REPLACE_ARB 0x8862 + +#define GLEW_ARB_point_sprite GLEW_GET_VAR(__GLEW_ARB_point_sprite) + +#endif /* GL_ARB_point_sprite */ + +/* ------------------------- GL_ARB_shader_objects ------------------------- */ + +#ifndef GL_ARB_shader_objects +#define GL_ARB_shader_objects 1 + +#define GL_PROGRAM_OBJECT_ARB 0x8B40 +#define GL_SHADER_OBJECT_ARB 0x8B48 +#define GL_OBJECT_TYPE_ARB 0x8B4E +#define GL_OBJECT_SUBTYPE_ARB 0x8B4F +#define GL_FLOAT_VEC2_ARB 0x8B50 +#define GL_FLOAT_VEC3_ARB 0x8B51 +#define GL_FLOAT_VEC4_ARB 0x8B52 +#define GL_INT_VEC2_ARB 0x8B53 +#define GL_INT_VEC3_ARB 0x8B54 +#define GL_INT_VEC4_ARB 0x8B55 +#define GL_BOOL_ARB 0x8B56 +#define GL_BOOL_VEC2_ARB 0x8B57 +#define GL_BOOL_VEC3_ARB 0x8B58 +#define GL_BOOL_VEC4_ARB 0x8B59 +#define GL_FLOAT_MAT2_ARB 0x8B5A +#define GL_FLOAT_MAT3_ARB 0x8B5B +#define GL_FLOAT_MAT4_ARB 0x8B5C +#define GL_SAMPLER_1D_ARB 0x8B5D +#define GL_SAMPLER_2D_ARB 0x8B5E +#define GL_SAMPLER_3D_ARB 0x8B5F +#define GL_SAMPLER_CUBE_ARB 0x8B60 +#define GL_SAMPLER_1D_SHADOW_ARB 0x8B61 +#define GL_SAMPLER_2D_SHADOW_ARB 0x8B62 +#define GL_SAMPLER_2D_RECT_ARB 0x8B63 +#define GL_SAMPLER_2D_RECT_SHADOW_ARB 0x8B64 +#define GL_OBJECT_DELETE_STATUS_ARB 0x8B80 +#define GL_OBJECT_COMPILE_STATUS_ARB 0x8B81 +#define GL_OBJECT_LINK_STATUS_ARB 0x8B82 +#define GL_OBJECT_VALIDATE_STATUS_ARB 0x8B83 +#define GL_OBJECT_INFO_LOG_LENGTH_ARB 0x8B84 +#define GL_OBJECT_ATTACHED_OBJECTS_ARB 0x8B85 +#define GL_OBJECT_ACTIVE_UNIFORMS_ARB 0x8B86 +#define GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB 0x8B87 +#define GL_OBJECT_SHADER_SOURCE_LENGTH_ARB 0x8B88 + +typedef char GLcharARB; +typedef unsigned int GLhandleARB; + +typedef void (GLAPIENTRY * PFNGLATTACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB obj); +typedef void (GLAPIENTRY * PFNGLCOMPILESHADERARBPROC) (GLhandleARB shaderObj); +typedef GLhandleARB (GLAPIENTRY * PFNGLCREATEPROGRAMOBJECTARBPROC) (void); +typedef GLhandleARB (GLAPIENTRY * PFNGLCREATESHADEROBJECTARBPROC) (GLenum shaderType); +typedef void (GLAPIENTRY * PFNGLDELETEOBJECTARBPROC) (GLhandleARB obj); +typedef void (GLAPIENTRY * PFNGLDETACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB attachedObj); +typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei* length, GLint *size, GLenum *type, GLcharARB *name); +typedef void (GLAPIENTRY * PFNGLGETATTACHEDOBJECTSARBPROC) (GLhandleARB containerObj, GLsizei maxCount, GLsizei* count, GLhandleARB *obj); +typedef GLhandleARB (GLAPIENTRY * PFNGLGETHANDLEARBPROC) (GLenum pname); +typedef void (GLAPIENTRY * PFNGLGETINFOLOGARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei* length, GLcharARB *infoLog); +typedef void (GLAPIENTRY * PFNGLGETOBJECTPARAMETERFVARBPROC) (GLhandleARB obj, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETOBJECTPARAMETERIVARBPROC) (GLhandleARB obj, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETSHADERSOURCEARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei* length, GLcharARB *source); +typedef GLint (GLAPIENTRY * PFNGLGETUNIFORMLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB* name); +typedef void (GLAPIENTRY * PFNGLGETUNIFORMFVARBPROC) (GLhandleARB programObj, GLint location, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETUNIFORMIVARBPROC) (GLhandleARB programObj, GLint location, GLint* params); +typedef void (GLAPIENTRY * PFNGLLINKPROGRAMARBPROC) (GLhandleARB programObj); +typedef void (GLAPIENTRY * PFNGLSHADERSOURCEARBPROC) (GLhandleARB shaderObj, GLsizei count, const GLcharARB ** string, const GLint *length); +typedef void (GLAPIENTRY * PFNGLUNIFORM1FARBPROC) (GLint location, GLfloat v0); +typedef void (GLAPIENTRY * PFNGLUNIFORM1FVARBPROC) (GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM1IARBPROC) (GLint location, GLint v0); +typedef void (GLAPIENTRY * PFNGLUNIFORM1IVARBPROC) (GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM2FARBPROC) (GLint location, GLfloat v0, GLfloat v1); +typedef void (GLAPIENTRY * PFNGLUNIFORM2FVARBPROC) (GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM2IARBPROC) (GLint location, GLint v0, GLint v1); +typedef void (GLAPIENTRY * PFNGLUNIFORM2IVARBPROC) (GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM3FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (GLAPIENTRY * PFNGLUNIFORM3FVARBPROC) (GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM3IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2); +typedef void (GLAPIENTRY * PFNGLUNIFORM3IVARBPROC) (GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM4FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (GLAPIENTRY * PFNGLUNIFORM4FVARBPROC) (GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM4IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (GLAPIENTRY * PFNGLUNIFORM4IVARBPROC) (GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUSEPROGRAMOBJECTARBPROC) (GLhandleARB programObj); +typedef void (GLAPIENTRY * PFNGLVALIDATEPROGRAMARBPROC) (GLhandleARB programObj); + +#define glAttachObjectARB GLEW_GET_FUN(__glewAttachObjectARB) +#define glCompileShaderARB GLEW_GET_FUN(__glewCompileShaderARB) +#define glCreateProgramObjectARB GLEW_GET_FUN(__glewCreateProgramObjectARB) +#define glCreateShaderObjectARB GLEW_GET_FUN(__glewCreateShaderObjectARB) +#define glDeleteObjectARB GLEW_GET_FUN(__glewDeleteObjectARB) +#define glDetachObjectARB GLEW_GET_FUN(__glewDetachObjectARB) +#define glGetActiveUniformARB GLEW_GET_FUN(__glewGetActiveUniformARB) +#define glGetAttachedObjectsARB GLEW_GET_FUN(__glewGetAttachedObjectsARB) +#define glGetHandleARB GLEW_GET_FUN(__glewGetHandleARB) +#define glGetInfoLogARB GLEW_GET_FUN(__glewGetInfoLogARB) +#define glGetObjectParameterfvARB GLEW_GET_FUN(__glewGetObjectParameterfvARB) +#define glGetObjectParameterivARB GLEW_GET_FUN(__glewGetObjectParameterivARB) +#define glGetShaderSourceARB GLEW_GET_FUN(__glewGetShaderSourceARB) +#define glGetUniformLocationARB GLEW_GET_FUN(__glewGetUniformLocationARB) +#define glGetUniformfvARB GLEW_GET_FUN(__glewGetUniformfvARB) +#define glGetUniformivARB GLEW_GET_FUN(__glewGetUniformivARB) +#define glLinkProgramARB GLEW_GET_FUN(__glewLinkProgramARB) +#define glShaderSourceARB GLEW_GET_FUN(__glewShaderSourceARB) +#define glUniform1fARB GLEW_GET_FUN(__glewUniform1fARB) +#define glUniform1fvARB GLEW_GET_FUN(__glewUniform1fvARB) +#define glUniform1iARB GLEW_GET_FUN(__glewUniform1iARB) +#define glUniform1ivARB GLEW_GET_FUN(__glewUniform1ivARB) +#define glUniform2fARB GLEW_GET_FUN(__glewUniform2fARB) +#define glUniform2fvARB GLEW_GET_FUN(__glewUniform2fvARB) +#define glUniform2iARB GLEW_GET_FUN(__glewUniform2iARB) +#define glUniform2ivARB GLEW_GET_FUN(__glewUniform2ivARB) +#define glUniform3fARB GLEW_GET_FUN(__glewUniform3fARB) +#define glUniform3fvARB GLEW_GET_FUN(__glewUniform3fvARB) +#define glUniform3iARB GLEW_GET_FUN(__glewUniform3iARB) +#define glUniform3ivARB GLEW_GET_FUN(__glewUniform3ivARB) +#define glUniform4fARB GLEW_GET_FUN(__glewUniform4fARB) +#define glUniform4fvARB GLEW_GET_FUN(__glewUniform4fvARB) +#define glUniform4iARB GLEW_GET_FUN(__glewUniform4iARB) +#define glUniform4ivARB GLEW_GET_FUN(__glewUniform4ivARB) +#define glUniformMatrix2fvARB GLEW_GET_FUN(__glewUniformMatrix2fvARB) +#define glUniformMatrix3fvARB GLEW_GET_FUN(__glewUniformMatrix3fvARB) +#define glUniformMatrix4fvARB GLEW_GET_FUN(__glewUniformMatrix4fvARB) +#define glUseProgramObjectARB GLEW_GET_FUN(__glewUseProgramObjectARB) +#define glValidateProgramARB GLEW_GET_FUN(__glewValidateProgramARB) + +#define GLEW_ARB_shader_objects GLEW_GET_VAR(__GLEW_ARB_shader_objects) + +#endif /* GL_ARB_shader_objects */ + +/* ---------------------- GL_ARB_shading_language_100 ---------------------- */ + +#ifndef GL_ARB_shading_language_100 +#define GL_ARB_shading_language_100 1 + +#define GL_SHADING_LANGUAGE_VERSION_ARB 0x8B8C + +#define GLEW_ARB_shading_language_100 GLEW_GET_VAR(__GLEW_ARB_shading_language_100) + +#endif /* GL_ARB_shading_language_100 */ + +/* ----------------------------- GL_ARB_shadow ----------------------------- */ + +#ifndef GL_ARB_shadow +#define GL_ARB_shadow 1 + +#define GL_TEXTURE_COMPARE_MODE_ARB 0x884C +#define GL_TEXTURE_COMPARE_FUNC_ARB 0x884D +#define GL_COMPARE_R_TO_TEXTURE_ARB 0x884E + +#define GLEW_ARB_shadow GLEW_GET_VAR(__GLEW_ARB_shadow) + +#endif /* GL_ARB_shadow */ + +/* ------------------------- GL_ARB_shadow_ambient ------------------------- */ + +#ifndef GL_ARB_shadow_ambient +#define GL_ARB_shadow_ambient 1 + +#define GL_TEXTURE_COMPARE_FAIL_VALUE_ARB 0x80BF + +#define GLEW_ARB_shadow_ambient GLEW_GET_VAR(__GLEW_ARB_shadow_ambient) + +#endif /* GL_ARB_shadow_ambient */ + +/* ---------------------- GL_ARB_texture_border_clamp ---------------------- */ + +#ifndef GL_ARB_texture_border_clamp +#define GL_ARB_texture_border_clamp 1 + +#define GL_CLAMP_TO_BORDER_ARB 0x812D + +#define GLEW_ARB_texture_border_clamp GLEW_GET_VAR(__GLEW_ARB_texture_border_clamp) + +#endif /* GL_ARB_texture_border_clamp */ + +/* ---------------------- GL_ARB_texture_buffer_object --------------------- */ + +#ifndef GL_ARB_texture_buffer_object +#define GL_ARB_texture_buffer_object 1 + +#define GL_TEXTURE_BUFFER_ARB 0x8C2A +#define GL_MAX_TEXTURE_BUFFER_SIZE_ARB 0x8C2B +#define GL_TEXTURE_BINDING_BUFFER_ARB 0x8C2C +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_ARB 0x8C2D +#define GL_TEXTURE_BUFFER_FORMAT_ARB 0x8C2E + +typedef void (GLAPIENTRY * PFNGLTEXBUFFERARBPROC) (GLenum target, GLenum internalformat, GLuint buffer); + +#define glTexBufferARB GLEW_GET_FUN(__glewTexBufferARB) + +#define GLEW_ARB_texture_buffer_object GLEW_GET_VAR(__GLEW_ARB_texture_buffer_object) + +#endif /* GL_ARB_texture_buffer_object */ + +/* ----------------------- GL_ARB_texture_compression ---------------------- */ + +#ifndef GL_ARB_texture_compression +#define GL_ARB_texture_compression 1 + +#define GL_COMPRESSED_ALPHA_ARB 0x84E9 +#define GL_COMPRESSED_LUMINANCE_ARB 0x84EA +#define GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB +#define GL_COMPRESSED_INTENSITY_ARB 0x84EC +#define GL_COMPRESSED_RGB_ARB 0x84ED +#define GL_COMPRESSED_RGBA_ARB 0x84EE +#define GL_TEXTURE_COMPRESSION_HINT_ARB 0x84EF +#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB 0x86A0 +#define GL_TEXTURE_COMPRESSED_ARB 0x86A1 +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3 + +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE1DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE2DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE3DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLGETCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint lod, void* img); + +#define glCompressedTexImage1DARB GLEW_GET_FUN(__glewCompressedTexImage1DARB) +#define glCompressedTexImage2DARB GLEW_GET_FUN(__glewCompressedTexImage2DARB) +#define glCompressedTexImage3DARB GLEW_GET_FUN(__glewCompressedTexImage3DARB) +#define glCompressedTexSubImage1DARB GLEW_GET_FUN(__glewCompressedTexSubImage1DARB) +#define glCompressedTexSubImage2DARB GLEW_GET_FUN(__glewCompressedTexSubImage2DARB) +#define glCompressedTexSubImage3DARB GLEW_GET_FUN(__glewCompressedTexSubImage3DARB) +#define glGetCompressedTexImageARB GLEW_GET_FUN(__glewGetCompressedTexImageARB) + +#define GLEW_ARB_texture_compression GLEW_GET_VAR(__GLEW_ARB_texture_compression) + +#endif /* GL_ARB_texture_compression */ + +/* -------------------- GL_ARB_texture_compression_rgtc -------------------- */ + +#ifndef GL_ARB_texture_compression_rgtc +#define GL_ARB_texture_compression_rgtc 1 + +#define GL_COMPRESSED_RED_RGTC1 0x8DBB +#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC +#define GL_COMPRESSED_RG_RGTC2 0x8DBD +#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE + +#define GLEW_ARB_texture_compression_rgtc GLEW_GET_VAR(__GLEW_ARB_texture_compression_rgtc) + +#endif /* GL_ARB_texture_compression_rgtc */ + +/* ------------------------ GL_ARB_texture_cube_map ------------------------ */ + +#ifndef GL_ARB_texture_cube_map +#define GL_ARB_texture_cube_map 1 + +#define GL_NORMAL_MAP_ARB 0x8511 +#define GL_REFLECTION_MAP_ARB 0x8512 +#define GL_TEXTURE_CUBE_MAP_ARB 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP_ARB 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB 0x851C + +#define GLEW_ARB_texture_cube_map GLEW_GET_VAR(__GLEW_ARB_texture_cube_map) + +#endif /* GL_ARB_texture_cube_map */ + +/* ------------------------- GL_ARB_texture_env_add ------------------------ */ + +#ifndef GL_ARB_texture_env_add +#define GL_ARB_texture_env_add 1 + +#define GLEW_ARB_texture_env_add GLEW_GET_VAR(__GLEW_ARB_texture_env_add) + +#endif /* GL_ARB_texture_env_add */ + +/* ----------------------- GL_ARB_texture_env_combine ---------------------- */ + +#ifndef GL_ARB_texture_env_combine +#define GL_ARB_texture_env_combine 1 + +#define GL_SUBTRACT_ARB 0x84E7 +#define GL_COMBINE_ARB 0x8570 +#define GL_COMBINE_RGB_ARB 0x8571 +#define GL_COMBINE_ALPHA_ARB 0x8572 +#define GL_RGB_SCALE_ARB 0x8573 +#define GL_ADD_SIGNED_ARB 0x8574 +#define GL_INTERPOLATE_ARB 0x8575 +#define GL_CONSTANT_ARB 0x8576 +#define GL_PRIMARY_COLOR_ARB 0x8577 +#define GL_PREVIOUS_ARB 0x8578 +#define GL_SOURCE0_RGB_ARB 0x8580 +#define GL_SOURCE1_RGB_ARB 0x8581 +#define GL_SOURCE2_RGB_ARB 0x8582 +#define GL_SOURCE0_ALPHA_ARB 0x8588 +#define GL_SOURCE1_ALPHA_ARB 0x8589 +#define GL_SOURCE2_ALPHA_ARB 0x858A +#define GL_OPERAND0_RGB_ARB 0x8590 +#define GL_OPERAND1_RGB_ARB 0x8591 +#define GL_OPERAND2_RGB_ARB 0x8592 +#define GL_OPERAND0_ALPHA_ARB 0x8598 +#define GL_OPERAND1_ALPHA_ARB 0x8599 +#define GL_OPERAND2_ALPHA_ARB 0x859A + +#define GLEW_ARB_texture_env_combine GLEW_GET_VAR(__GLEW_ARB_texture_env_combine) + +#endif /* GL_ARB_texture_env_combine */ + +/* ---------------------- GL_ARB_texture_env_crossbar ---------------------- */ + +#ifndef GL_ARB_texture_env_crossbar +#define GL_ARB_texture_env_crossbar 1 + +#define GLEW_ARB_texture_env_crossbar GLEW_GET_VAR(__GLEW_ARB_texture_env_crossbar) + +#endif /* GL_ARB_texture_env_crossbar */ + +/* ------------------------ GL_ARB_texture_env_dot3 ------------------------ */ + +#ifndef GL_ARB_texture_env_dot3 +#define GL_ARB_texture_env_dot3 1 + +#define GL_DOT3_RGB_ARB 0x86AE +#define GL_DOT3_RGBA_ARB 0x86AF + +#define GLEW_ARB_texture_env_dot3 GLEW_GET_VAR(__GLEW_ARB_texture_env_dot3) + +#endif /* GL_ARB_texture_env_dot3 */ + +/* -------------------------- GL_ARB_texture_float ------------------------- */ + +#ifndef GL_ARB_texture_float +#define GL_ARB_texture_float 1 + +#define GL_RGBA32F_ARB 0x8814 +#define GL_RGB32F_ARB 0x8815 +#define GL_ALPHA32F_ARB 0x8816 +#define GL_INTENSITY32F_ARB 0x8817 +#define GL_LUMINANCE32F_ARB 0x8818 +#define GL_LUMINANCE_ALPHA32F_ARB 0x8819 +#define GL_RGBA16F_ARB 0x881A +#define GL_RGB16F_ARB 0x881B +#define GL_ALPHA16F_ARB 0x881C +#define GL_INTENSITY16F_ARB 0x881D +#define GL_LUMINANCE16F_ARB 0x881E +#define GL_LUMINANCE_ALPHA16F_ARB 0x881F +#define GL_TEXTURE_RED_TYPE_ARB 0x8C10 +#define GL_TEXTURE_GREEN_TYPE_ARB 0x8C11 +#define GL_TEXTURE_BLUE_TYPE_ARB 0x8C12 +#define GL_TEXTURE_ALPHA_TYPE_ARB 0x8C13 +#define GL_TEXTURE_LUMINANCE_TYPE_ARB 0x8C14 +#define GL_TEXTURE_INTENSITY_TYPE_ARB 0x8C15 +#define GL_TEXTURE_DEPTH_TYPE_ARB 0x8C16 +#define GL_UNSIGNED_NORMALIZED_ARB 0x8C17 + +#define GLEW_ARB_texture_float GLEW_GET_VAR(__GLEW_ARB_texture_float) + +#endif /* GL_ARB_texture_float */ + +/* --------------------- GL_ARB_texture_mirrored_repeat -------------------- */ + +#ifndef GL_ARB_texture_mirrored_repeat +#define GL_ARB_texture_mirrored_repeat 1 + +#define GL_MIRRORED_REPEAT_ARB 0x8370 + +#define GLEW_ARB_texture_mirrored_repeat GLEW_GET_VAR(__GLEW_ARB_texture_mirrored_repeat) + +#endif /* GL_ARB_texture_mirrored_repeat */ + +/* -------------------- GL_ARB_texture_non_power_of_two -------------------- */ + +#ifndef GL_ARB_texture_non_power_of_two +#define GL_ARB_texture_non_power_of_two 1 + +#define GLEW_ARB_texture_non_power_of_two GLEW_GET_VAR(__GLEW_ARB_texture_non_power_of_two) + +#endif /* GL_ARB_texture_non_power_of_two */ + +/* ------------------------ GL_ARB_texture_rectangle ----------------------- */ + +#ifndef GL_ARB_texture_rectangle +#define GL_ARB_texture_rectangle 1 + +#define GL_TEXTURE_RECTANGLE_ARB 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE_ARB 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE_ARB 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB 0x84F8 +#define GL_SAMPLER_2D_RECT_ARB 0x8B63 +#define GL_SAMPLER_2D_RECT_SHADOW_ARB 0x8B64 + +#define GLEW_ARB_texture_rectangle GLEW_GET_VAR(__GLEW_ARB_texture_rectangle) + +#endif /* GL_ARB_texture_rectangle */ + +/* --------------------------- GL_ARB_texture_rg --------------------------- */ + +#ifndef GL_ARB_texture_rg +#define GL_ARB_texture_rg 1 + +#define GL_RED 0x1903 +#define GL_RG 0x8227 +#define GL_RG_INTEGER 0x8228 +#define GL_R8 0x8229 +#define GL_R16 0x822A +#define GL_RG8 0x822B +#define GL_RG16 0x822C +#define GL_R16F 0x822D +#define GL_R32F 0x822E +#define GL_RG16F 0x822F +#define GL_RG32F 0x8230 +#define GL_R8I 0x8231 +#define GL_R8UI 0x8232 +#define GL_R16I 0x8233 +#define GL_R16UI 0x8234 +#define GL_R32I 0x8235 +#define GL_R32UI 0x8236 +#define GL_RG8I 0x8237 +#define GL_RG8UI 0x8238 +#define GL_RG16I 0x8239 +#define GL_RG16UI 0x823A +#define GL_RG32I 0x823B +#define GL_RG32UI 0x823C + +#define GLEW_ARB_texture_rg GLEW_GET_VAR(__GLEW_ARB_texture_rg) + +#endif /* GL_ARB_texture_rg */ + +/* ------------------------ GL_ARB_transpose_matrix ------------------------ */ + +#ifndef GL_ARB_transpose_matrix +#define GL_ARB_transpose_matrix 1 + +#define GL_TRANSPOSE_MODELVIEW_MATRIX_ARB 0x84E3 +#define GL_TRANSPOSE_PROJECTION_MATRIX_ARB 0x84E4 +#define GL_TRANSPOSE_TEXTURE_MATRIX_ARB 0x84E5 +#define GL_TRANSPOSE_COLOR_MATRIX_ARB 0x84E6 + +typedef void (GLAPIENTRY * PFNGLLOADTRANSPOSEMATRIXDARBPROC) (GLdouble m[16]); +typedef void (GLAPIENTRY * PFNGLLOADTRANSPOSEMATRIXFARBPROC) (GLfloat m[16]); +typedef void (GLAPIENTRY * PFNGLMULTTRANSPOSEMATRIXDARBPROC) (GLdouble m[16]); +typedef void (GLAPIENTRY * PFNGLMULTTRANSPOSEMATRIXFARBPROC) (GLfloat m[16]); + +#define glLoadTransposeMatrixdARB GLEW_GET_FUN(__glewLoadTransposeMatrixdARB) +#define glLoadTransposeMatrixfARB GLEW_GET_FUN(__glewLoadTransposeMatrixfARB) +#define glMultTransposeMatrixdARB GLEW_GET_FUN(__glewMultTransposeMatrixdARB) +#define glMultTransposeMatrixfARB GLEW_GET_FUN(__glewMultTransposeMatrixfARB) + +#define GLEW_ARB_transpose_matrix GLEW_GET_VAR(__GLEW_ARB_transpose_matrix) + +#endif /* GL_ARB_transpose_matrix */ + +/* ----------------------- GL_ARB_vertex_array_object ---------------------- */ + +#ifndef GL_ARB_vertex_array_object +#define GL_ARB_vertex_array_object 1 + +#define GL_VERTEX_ARRAY_BINDING 0x85B5 + +typedef void (GLAPIENTRY * PFNGLBINDVERTEXARRAYPROC) (GLuint array); +typedef void (GLAPIENTRY * PFNGLDELETEVERTEXARRAYSPROC) (GLsizei n, const GLuint* arrays); +typedef void (GLAPIENTRY * PFNGLGENVERTEXARRAYSPROC) (GLsizei n, GLuint* arrays); +typedef GLboolean (GLAPIENTRY * PFNGLISVERTEXARRAYPROC) (GLuint array); + +#define glBindVertexArray GLEW_GET_FUN(__glewBindVertexArray) +#define glDeleteVertexArrays GLEW_GET_FUN(__glewDeleteVertexArrays) +#define glGenVertexArrays GLEW_GET_FUN(__glewGenVertexArrays) +#define glIsVertexArray GLEW_GET_FUN(__glewIsVertexArray) + +#define GLEW_ARB_vertex_array_object GLEW_GET_VAR(__GLEW_ARB_vertex_array_object) + +#endif /* GL_ARB_vertex_array_object */ + +/* -------------------------- GL_ARB_vertex_blend -------------------------- */ + +#ifndef GL_ARB_vertex_blend +#define GL_ARB_vertex_blend 1 + +#define GL_MODELVIEW0_ARB 0x1700 +#define GL_MODELVIEW1_ARB 0x850A +#define GL_MAX_VERTEX_UNITS_ARB 0x86A4 +#define GL_ACTIVE_VERTEX_UNITS_ARB 0x86A5 +#define GL_WEIGHT_SUM_UNITY_ARB 0x86A6 +#define GL_VERTEX_BLEND_ARB 0x86A7 +#define GL_CURRENT_WEIGHT_ARB 0x86A8 +#define GL_WEIGHT_ARRAY_TYPE_ARB 0x86A9 +#define GL_WEIGHT_ARRAY_STRIDE_ARB 0x86AA +#define GL_WEIGHT_ARRAY_SIZE_ARB 0x86AB +#define GL_WEIGHT_ARRAY_POINTER_ARB 0x86AC +#define GL_WEIGHT_ARRAY_ARB 0x86AD +#define GL_MODELVIEW2_ARB 0x8722 +#define GL_MODELVIEW3_ARB 0x8723 +#define GL_MODELVIEW4_ARB 0x8724 +#define GL_MODELVIEW5_ARB 0x8725 +#define GL_MODELVIEW6_ARB 0x8726 +#define GL_MODELVIEW7_ARB 0x8727 +#define GL_MODELVIEW8_ARB 0x8728 +#define GL_MODELVIEW9_ARB 0x8729 +#define GL_MODELVIEW10_ARB 0x872A +#define GL_MODELVIEW11_ARB 0x872B +#define GL_MODELVIEW12_ARB 0x872C +#define GL_MODELVIEW13_ARB 0x872D +#define GL_MODELVIEW14_ARB 0x872E +#define GL_MODELVIEW15_ARB 0x872F +#define GL_MODELVIEW16_ARB 0x8730 +#define GL_MODELVIEW17_ARB 0x8731 +#define GL_MODELVIEW18_ARB 0x8732 +#define GL_MODELVIEW19_ARB 0x8733 +#define GL_MODELVIEW20_ARB 0x8734 +#define GL_MODELVIEW21_ARB 0x8735 +#define GL_MODELVIEW22_ARB 0x8736 +#define GL_MODELVIEW23_ARB 0x8737 +#define GL_MODELVIEW24_ARB 0x8738 +#define GL_MODELVIEW25_ARB 0x8739 +#define GL_MODELVIEW26_ARB 0x873A +#define GL_MODELVIEW27_ARB 0x873B +#define GL_MODELVIEW28_ARB 0x873C +#define GL_MODELVIEW29_ARB 0x873D +#define GL_MODELVIEW30_ARB 0x873E +#define GL_MODELVIEW31_ARB 0x873F + +typedef void (GLAPIENTRY * PFNGLVERTEXBLENDARBPROC) (GLint count); +typedef void (GLAPIENTRY * PFNGLWEIGHTPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, GLvoid *pointer); +typedef void (GLAPIENTRY * PFNGLWEIGHTBVARBPROC) (GLint size, GLbyte *weights); +typedef void (GLAPIENTRY * PFNGLWEIGHTDVARBPROC) (GLint size, GLdouble *weights); +typedef void (GLAPIENTRY * PFNGLWEIGHTFVARBPROC) (GLint size, GLfloat *weights); +typedef void (GLAPIENTRY * PFNGLWEIGHTIVARBPROC) (GLint size, GLint *weights); +typedef void (GLAPIENTRY * PFNGLWEIGHTSVARBPROC) (GLint size, GLshort *weights); +typedef void (GLAPIENTRY * PFNGLWEIGHTUBVARBPROC) (GLint size, GLubyte *weights); +typedef void (GLAPIENTRY * PFNGLWEIGHTUIVARBPROC) (GLint size, GLuint *weights); +typedef void (GLAPIENTRY * PFNGLWEIGHTUSVARBPROC) (GLint size, GLushort *weights); + +#define glVertexBlendARB GLEW_GET_FUN(__glewVertexBlendARB) +#define glWeightPointerARB GLEW_GET_FUN(__glewWeightPointerARB) +#define glWeightbvARB GLEW_GET_FUN(__glewWeightbvARB) +#define glWeightdvARB GLEW_GET_FUN(__glewWeightdvARB) +#define glWeightfvARB GLEW_GET_FUN(__glewWeightfvARB) +#define glWeightivARB GLEW_GET_FUN(__glewWeightivARB) +#define glWeightsvARB GLEW_GET_FUN(__glewWeightsvARB) +#define glWeightubvARB GLEW_GET_FUN(__glewWeightubvARB) +#define glWeightuivARB GLEW_GET_FUN(__glewWeightuivARB) +#define glWeightusvARB GLEW_GET_FUN(__glewWeightusvARB) + +#define GLEW_ARB_vertex_blend GLEW_GET_VAR(__GLEW_ARB_vertex_blend) + +#endif /* GL_ARB_vertex_blend */ + +/* ---------------------- GL_ARB_vertex_buffer_object ---------------------- */ + +#ifndef GL_ARB_vertex_buffer_object +#define GL_ARB_vertex_buffer_object 1 + +#define GL_BUFFER_SIZE_ARB 0x8764 +#define GL_BUFFER_USAGE_ARB 0x8765 +#define GL_ARRAY_BUFFER_ARB 0x8892 +#define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893 +#define GL_ARRAY_BUFFER_BINDING_ARB 0x8894 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895 +#define GL_VERTEX_ARRAY_BUFFER_BINDING_ARB 0x8896 +#define GL_NORMAL_ARRAY_BUFFER_BINDING_ARB 0x8897 +#define GL_COLOR_ARRAY_BUFFER_BINDING_ARB 0x8898 +#define GL_INDEX_ARRAY_BUFFER_BINDING_ARB 0x8899 +#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB 0x889A +#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB 0x889B +#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB 0x889C +#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB 0x889D +#define GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB 0x889E +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB 0x889F +#define GL_READ_ONLY_ARB 0x88B8 +#define GL_WRITE_ONLY_ARB 0x88B9 +#define GL_READ_WRITE_ARB 0x88BA +#define GL_BUFFER_ACCESS_ARB 0x88BB +#define GL_BUFFER_MAPPED_ARB 0x88BC +#define GL_BUFFER_MAP_POINTER_ARB 0x88BD +#define GL_STREAM_DRAW_ARB 0x88E0 +#define GL_STREAM_READ_ARB 0x88E1 +#define GL_STREAM_COPY_ARB 0x88E2 +#define GL_STATIC_DRAW_ARB 0x88E4 +#define GL_STATIC_READ_ARB 0x88E5 +#define GL_STATIC_COPY_ARB 0x88E6 +#define GL_DYNAMIC_DRAW_ARB 0x88E8 +#define GL_DYNAMIC_READ_ARB 0x88E9 +#define GL_DYNAMIC_COPY_ARB 0x88EA + +typedef ptrdiff_t GLsizeiptrARB; +typedef ptrdiff_t GLintptrARB; + +typedef void (GLAPIENTRY * PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer); +typedef void (GLAPIENTRY * PFNGLBUFFERDATAARBPROC) (GLenum target, GLsizeiptrARB size, const GLvoid* data, GLenum usage); +typedef void (GLAPIENTRY * PFNGLBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid* data); +typedef void (GLAPIENTRY * PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint* buffers); +typedef void (GLAPIENTRY * PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint* buffers); +typedef void (GLAPIENTRY * PFNGLGETBUFFERPARAMETERIVARBPROC) (GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETBUFFERPOINTERVARBPROC) (GLenum target, GLenum pname, GLvoid** params); +typedef void (GLAPIENTRY * PFNGLGETBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid* data); +typedef GLboolean (GLAPIENTRY * PFNGLISBUFFERARBPROC) (GLuint buffer); +typedef GLvoid * (GLAPIENTRY * PFNGLMAPBUFFERARBPROC) (GLenum target, GLenum access); +typedef GLboolean (GLAPIENTRY * PFNGLUNMAPBUFFERARBPROC) (GLenum target); + +#define glBindBufferARB GLEW_GET_FUN(__glewBindBufferARB) +#define glBufferDataARB GLEW_GET_FUN(__glewBufferDataARB) +#define glBufferSubDataARB GLEW_GET_FUN(__glewBufferSubDataARB) +#define glDeleteBuffersARB GLEW_GET_FUN(__glewDeleteBuffersARB) +#define glGenBuffersARB GLEW_GET_FUN(__glewGenBuffersARB) +#define glGetBufferParameterivARB GLEW_GET_FUN(__glewGetBufferParameterivARB) +#define glGetBufferPointervARB GLEW_GET_FUN(__glewGetBufferPointervARB) +#define glGetBufferSubDataARB GLEW_GET_FUN(__glewGetBufferSubDataARB) +#define glIsBufferARB GLEW_GET_FUN(__glewIsBufferARB) +#define glMapBufferARB GLEW_GET_FUN(__glewMapBufferARB) +#define glUnmapBufferARB GLEW_GET_FUN(__glewUnmapBufferARB) + +#define GLEW_ARB_vertex_buffer_object GLEW_GET_VAR(__GLEW_ARB_vertex_buffer_object) + +#endif /* GL_ARB_vertex_buffer_object */ + +/* ------------------------- GL_ARB_vertex_program ------------------------- */ + +#ifndef GL_ARB_vertex_program +#define GL_ARB_vertex_program 1 + +#define GL_COLOR_SUM_ARB 0x8458 +#define GL_VERTEX_PROGRAM_ARB 0x8620 +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB 0x8625 +#define GL_CURRENT_VERTEX_ATTRIB_ARB 0x8626 +#define GL_PROGRAM_LENGTH_ARB 0x8627 +#define GL_PROGRAM_STRING_ARB 0x8628 +#define GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB 0x862E +#define GL_MAX_PROGRAM_MATRICES_ARB 0x862F +#define GL_CURRENT_MATRIX_STACK_DEPTH_ARB 0x8640 +#define GL_CURRENT_MATRIX_ARB 0x8641 +#define GL_VERTEX_PROGRAM_POINT_SIZE_ARB 0x8642 +#define GL_VERTEX_PROGRAM_TWO_SIDE_ARB 0x8643 +#define GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB 0x8645 +#define GL_PROGRAM_ERROR_POSITION_ARB 0x864B +#define GL_PROGRAM_BINDING_ARB 0x8677 +#define GL_MAX_VERTEX_ATTRIBS_ARB 0x8869 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB 0x886A +#define GL_PROGRAM_ERROR_STRING_ARB 0x8874 +#define GL_PROGRAM_FORMAT_ASCII_ARB 0x8875 +#define GL_PROGRAM_FORMAT_ARB 0x8876 +#define GL_PROGRAM_INSTRUCTIONS_ARB 0x88A0 +#define GL_MAX_PROGRAM_INSTRUCTIONS_ARB 0x88A1 +#define GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A2 +#define GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A3 +#define GL_PROGRAM_TEMPORARIES_ARB 0x88A4 +#define GL_MAX_PROGRAM_TEMPORARIES_ARB 0x88A5 +#define GL_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A6 +#define GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A7 +#define GL_PROGRAM_PARAMETERS_ARB 0x88A8 +#define GL_MAX_PROGRAM_PARAMETERS_ARB 0x88A9 +#define GL_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AA +#define GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AB +#define GL_PROGRAM_ATTRIBS_ARB 0x88AC +#define GL_MAX_PROGRAM_ATTRIBS_ARB 0x88AD +#define GL_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AE +#define GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AF +#define GL_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B0 +#define GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B1 +#define GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B2 +#define GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B3 +#define GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB 0x88B4 +#define GL_MAX_PROGRAM_ENV_PARAMETERS_ARB 0x88B5 +#define GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB 0x88B6 +#define GL_TRANSPOSE_CURRENT_MATRIX_ARB 0x88B7 +#define GL_MATRIX0_ARB 0x88C0 +#define GL_MATRIX1_ARB 0x88C1 +#define GL_MATRIX2_ARB 0x88C2 +#define GL_MATRIX3_ARB 0x88C3 +#define GL_MATRIX4_ARB 0x88C4 +#define GL_MATRIX5_ARB 0x88C5 +#define GL_MATRIX6_ARB 0x88C6 +#define GL_MATRIX7_ARB 0x88C7 +#define GL_MATRIX8_ARB 0x88C8 +#define GL_MATRIX9_ARB 0x88C9 +#define GL_MATRIX10_ARB 0x88CA +#define GL_MATRIX11_ARB 0x88CB +#define GL_MATRIX12_ARB 0x88CC +#define GL_MATRIX13_ARB 0x88CD +#define GL_MATRIX14_ARB 0x88CE +#define GL_MATRIX15_ARB 0x88CF +#define GL_MATRIX16_ARB 0x88D0 +#define GL_MATRIX17_ARB 0x88D1 +#define GL_MATRIX18_ARB 0x88D2 +#define GL_MATRIX19_ARB 0x88D3 +#define GL_MATRIX20_ARB 0x88D4 +#define GL_MATRIX21_ARB 0x88D5 +#define GL_MATRIX22_ARB 0x88D6 +#define GL_MATRIX23_ARB 0x88D7 +#define GL_MATRIX24_ARB 0x88D8 +#define GL_MATRIX25_ARB 0x88D9 +#define GL_MATRIX26_ARB 0x88DA +#define GL_MATRIX27_ARB 0x88DB +#define GL_MATRIX28_ARB 0x88DC +#define GL_MATRIX29_ARB 0x88DD +#define GL_MATRIX30_ARB 0x88DE +#define GL_MATRIX31_ARB 0x88DF + +typedef void (GLAPIENTRY * PFNGLBINDPROGRAMARBPROC) (GLenum target, GLuint program); +typedef void (GLAPIENTRY * PFNGLDELETEPROGRAMSARBPROC) (GLsizei n, const GLuint* programs); +typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) (GLuint index); +typedef void (GLAPIENTRY * PFNGLENABLEVERTEXATTRIBARRAYARBPROC) (GLuint index); +typedef void (GLAPIENTRY * PFNGLGENPROGRAMSARBPROC) (GLsizei n, GLuint* programs); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMENVPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMENVPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMSTRINGARBPROC) (GLenum target, GLenum pname, void* string); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMIVARBPROC) (GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBPOINTERVARBPROC) (GLuint index, GLenum pname, GLvoid** pointer); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBDVARBPROC) (GLuint index, GLenum pname, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBFVARBPROC) (GLuint index, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIVARBPROC) (GLuint index, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISPROGRAMARBPROC) (GLuint program); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble* params); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble* params); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLPROGRAMSTRINGARBPROC) (GLenum target, GLenum format, GLsizei len, const void* string); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DARBPROC) (GLuint index, GLdouble x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DVARBPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FARBPROC) (GLuint index, GLfloat x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FVARBPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SARBPROC) (GLuint index, GLshort x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SVARBPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DARBPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DVARBPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FARBPROC) (GLuint index, GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FVARBPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SARBPROC) (GLuint index, GLshort x, GLshort y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SVARBPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DVARBPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FVARBPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SVARBPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NBVARBPROC) (GLuint index, const GLbyte* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NIVARBPROC) (GLuint index, const GLint* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NSVARBPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUBARBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUBVARBPROC) (GLuint index, const GLubyte* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUIVARBPROC) (GLuint index, const GLuint* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUSVARBPROC) (GLuint index, const GLushort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4BVARBPROC) (GLuint index, const GLbyte* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DVARBPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FVARBPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4IVARBPROC) (GLuint index, const GLint* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SVARBPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UBVARBPROC) (GLuint index, const GLubyte* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UIVARBPROC) (GLuint index, const GLuint* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4USVARBPROC) (GLuint index, const GLushort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBPOINTERARBPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* pointer); + +#define glBindProgramARB GLEW_GET_FUN(__glewBindProgramARB) +#define glDeleteProgramsARB GLEW_GET_FUN(__glewDeleteProgramsARB) +#define glDisableVertexAttribArrayARB GLEW_GET_FUN(__glewDisableVertexAttribArrayARB) +#define glEnableVertexAttribArrayARB GLEW_GET_FUN(__glewEnableVertexAttribArrayARB) +#define glGenProgramsARB GLEW_GET_FUN(__glewGenProgramsARB) +#define glGetProgramEnvParameterdvARB GLEW_GET_FUN(__glewGetProgramEnvParameterdvARB) +#define glGetProgramEnvParameterfvARB GLEW_GET_FUN(__glewGetProgramEnvParameterfvARB) +#define glGetProgramLocalParameterdvARB GLEW_GET_FUN(__glewGetProgramLocalParameterdvARB) +#define glGetProgramLocalParameterfvARB GLEW_GET_FUN(__glewGetProgramLocalParameterfvARB) +#define glGetProgramStringARB GLEW_GET_FUN(__glewGetProgramStringARB) +#define glGetProgramivARB GLEW_GET_FUN(__glewGetProgramivARB) +#define glGetVertexAttribPointervARB GLEW_GET_FUN(__glewGetVertexAttribPointervARB) +#define glGetVertexAttribdvARB GLEW_GET_FUN(__glewGetVertexAttribdvARB) +#define glGetVertexAttribfvARB GLEW_GET_FUN(__glewGetVertexAttribfvARB) +#define glGetVertexAttribivARB GLEW_GET_FUN(__glewGetVertexAttribivARB) +#define glIsProgramARB GLEW_GET_FUN(__glewIsProgramARB) +#define glProgramEnvParameter4dARB GLEW_GET_FUN(__glewProgramEnvParameter4dARB) +#define glProgramEnvParameter4dvARB GLEW_GET_FUN(__glewProgramEnvParameter4dvARB) +#define glProgramEnvParameter4fARB GLEW_GET_FUN(__glewProgramEnvParameter4fARB) +#define glProgramEnvParameter4fvARB GLEW_GET_FUN(__glewProgramEnvParameter4fvARB) +#define glProgramLocalParameter4dARB GLEW_GET_FUN(__glewProgramLocalParameter4dARB) +#define glProgramLocalParameter4dvARB GLEW_GET_FUN(__glewProgramLocalParameter4dvARB) +#define glProgramLocalParameter4fARB GLEW_GET_FUN(__glewProgramLocalParameter4fARB) +#define glProgramLocalParameter4fvARB GLEW_GET_FUN(__glewProgramLocalParameter4fvARB) +#define glProgramStringARB GLEW_GET_FUN(__glewProgramStringARB) +#define glVertexAttrib1dARB GLEW_GET_FUN(__glewVertexAttrib1dARB) +#define glVertexAttrib1dvARB GLEW_GET_FUN(__glewVertexAttrib1dvARB) +#define glVertexAttrib1fARB GLEW_GET_FUN(__glewVertexAttrib1fARB) +#define glVertexAttrib1fvARB GLEW_GET_FUN(__glewVertexAttrib1fvARB) +#define glVertexAttrib1sARB GLEW_GET_FUN(__glewVertexAttrib1sARB) +#define glVertexAttrib1svARB GLEW_GET_FUN(__glewVertexAttrib1svARB) +#define glVertexAttrib2dARB GLEW_GET_FUN(__glewVertexAttrib2dARB) +#define glVertexAttrib2dvARB GLEW_GET_FUN(__glewVertexAttrib2dvARB) +#define glVertexAttrib2fARB GLEW_GET_FUN(__glewVertexAttrib2fARB) +#define glVertexAttrib2fvARB GLEW_GET_FUN(__glewVertexAttrib2fvARB) +#define glVertexAttrib2sARB GLEW_GET_FUN(__glewVertexAttrib2sARB) +#define glVertexAttrib2svARB GLEW_GET_FUN(__glewVertexAttrib2svARB) +#define glVertexAttrib3dARB GLEW_GET_FUN(__glewVertexAttrib3dARB) +#define glVertexAttrib3dvARB GLEW_GET_FUN(__glewVertexAttrib3dvARB) +#define glVertexAttrib3fARB GLEW_GET_FUN(__glewVertexAttrib3fARB) +#define glVertexAttrib3fvARB GLEW_GET_FUN(__glewVertexAttrib3fvARB) +#define glVertexAttrib3sARB GLEW_GET_FUN(__glewVertexAttrib3sARB) +#define glVertexAttrib3svARB GLEW_GET_FUN(__glewVertexAttrib3svARB) +#define glVertexAttrib4NbvARB GLEW_GET_FUN(__glewVertexAttrib4NbvARB) +#define glVertexAttrib4NivARB GLEW_GET_FUN(__glewVertexAttrib4NivARB) +#define glVertexAttrib4NsvARB GLEW_GET_FUN(__glewVertexAttrib4NsvARB) +#define glVertexAttrib4NubARB GLEW_GET_FUN(__glewVertexAttrib4NubARB) +#define glVertexAttrib4NubvARB GLEW_GET_FUN(__glewVertexAttrib4NubvARB) +#define glVertexAttrib4NuivARB GLEW_GET_FUN(__glewVertexAttrib4NuivARB) +#define glVertexAttrib4NusvARB GLEW_GET_FUN(__glewVertexAttrib4NusvARB) +#define glVertexAttrib4bvARB GLEW_GET_FUN(__glewVertexAttrib4bvARB) +#define glVertexAttrib4dARB GLEW_GET_FUN(__glewVertexAttrib4dARB) +#define glVertexAttrib4dvARB GLEW_GET_FUN(__glewVertexAttrib4dvARB) +#define glVertexAttrib4fARB GLEW_GET_FUN(__glewVertexAttrib4fARB) +#define glVertexAttrib4fvARB GLEW_GET_FUN(__glewVertexAttrib4fvARB) +#define glVertexAttrib4ivARB GLEW_GET_FUN(__glewVertexAttrib4ivARB) +#define glVertexAttrib4sARB GLEW_GET_FUN(__glewVertexAttrib4sARB) +#define glVertexAttrib4svARB GLEW_GET_FUN(__glewVertexAttrib4svARB) +#define glVertexAttrib4ubvARB GLEW_GET_FUN(__glewVertexAttrib4ubvARB) +#define glVertexAttrib4uivARB GLEW_GET_FUN(__glewVertexAttrib4uivARB) +#define glVertexAttrib4usvARB GLEW_GET_FUN(__glewVertexAttrib4usvARB) +#define glVertexAttribPointerARB GLEW_GET_FUN(__glewVertexAttribPointerARB) + +#define GLEW_ARB_vertex_program GLEW_GET_VAR(__GLEW_ARB_vertex_program) + +#endif /* GL_ARB_vertex_program */ + +/* -------------------------- GL_ARB_vertex_shader ------------------------- */ + +#ifndef GL_ARB_vertex_shader +#define GL_ARB_vertex_shader 1 + +#define GL_VERTEX_SHADER_ARB 0x8B31 +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB 0x8B4A +#define GL_MAX_VARYING_FLOATS_ARB 0x8B4B +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB 0x8B4C +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB 0x8B4D +#define GL_OBJECT_ACTIVE_ATTRIBUTES_ARB 0x8B89 +#define GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB 0x8B8A + +typedef void (GLAPIENTRY * PFNGLBINDATTRIBLOCATIONARBPROC) (GLhandleARB programObj, GLuint index, const GLcharARB* name); +typedef void (GLAPIENTRY * PFNGLGETACTIVEATTRIBARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei* length, GLint *size, GLenum *type, GLcharARB *name); +typedef GLint (GLAPIENTRY * PFNGLGETATTRIBLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB* name); + +#define glBindAttribLocationARB GLEW_GET_FUN(__glewBindAttribLocationARB) +#define glGetActiveAttribARB GLEW_GET_FUN(__glewGetActiveAttribARB) +#define glGetAttribLocationARB GLEW_GET_FUN(__glewGetAttribLocationARB) + +#define GLEW_ARB_vertex_shader GLEW_GET_VAR(__GLEW_ARB_vertex_shader) + +#endif /* GL_ARB_vertex_shader */ + +/* --------------------------- GL_ARB_window_pos --------------------------- */ + +#ifndef GL_ARB_window_pos +#define GL_ARB_window_pos 1 + +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DARBPROC) (GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DVARBPROC) (const GLdouble* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FARBPROC) (GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FVARBPROC) (const GLfloat* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IARBPROC) (GLint x, GLint y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IVARBPROC) (const GLint* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SARBPROC) (GLshort x, GLshort y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SVARBPROC) (const GLshort* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DARBPROC) (GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DVARBPROC) (const GLdouble* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FARBPROC) (GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FVARBPROC) (const GLfloat* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IARBPROC) (GLint x, GLint y, GLint z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IVARBPROC) (const GLint* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SARBPROC) (GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SVARBPROC) (const GLshort* p); + +#define glWindowPos2dARB GLEW_GET_FUN(__glewWindowPos2dARB) +#define glWindowPos2dvARB GLEW_GET_FUN(__glewWindowPos2dvARB) +#define glWindowPos2fARB GLEW_GET_FUN(__glewWindowPos2fARB) +#define glWindowPos2fvARB GLEW_GET_FUN(__glewWindowPos2fvARB) +#define glWindowPos2iARB GLEW_GET_FUN(__glewWindowPos2iARB) +#define glWindowPos2ivARB GLEW_GET_FUN(__glewWindowPos2ivARB) +#define glWindowPos2sARB GLEW_GET_FUN(__glewWindowPos2sARB) +#define glWindowPos2svARB GLEW_GET_FUN(__glewWindowPos2svARB) +#define glWindowPos3dARB GLEW_GET_FUN(__glewWindowPos3dARB) +#define glWindowPos3dvARB GLEW_GET_FUN(__glewWindowPos3dvARB) +#define glWindowPos3fARB GLEW_GET_FUN(__glewWindowPos3fARB) +#define glWindowPos3fvARB GLEW_GET_FUN(__glewWindowPos3fvARB) +#define glWindowPos3iARB GLEW_GET_FUN(__glewWindowPos3iARB) +#define glWindowPos3ivARB GLEW_GET_FUN(__glewWindowPos3ivARB) +#define glWindowPos3sARB GLEW_GET_FUN(__glewWindowPos3sARB) +#define glWindowPos3svARB GLEW_GET_FUN(__glewWindowPos3svARB) + +#define GLEW_ARB_window_pos GLEW_GET_VAR(__GLEW_ARB_window_pos) + +#endif /* GL_ARB_window_pos */ + +/* ------------------------- GL_ATIX_point_sprites ------------------------- */ + +#ifndef GL_ATIX_point_sprites +#define GL_ATIX_point_sprites 1 + +#define GL_TEXTURE_POINT_MODE_ATIX 0x60B0 +#define GL_TEXTURE_POINT_ONE_COORD_ATIX 0x60B1 +#define GL_TEXTURE_POINT_SPRITE_ATIX 0x60B2 +#define GL_POINT_SPRITE_CULL_MODE_ATIX 0x60B3 +#define GL_POINT_SPRITE_CULL_CENTER_ATIX 0x60B4 +#define GL_POINT_SPRITE_CULL_CLIP_ATIX 0x60B5 + +#define GLEW_ATIX_point_sprites GLEW_GET_VAR(__GLEW_ATIX_point_sprites) + +#endif /* GL_ATIX_point_sprites */ + +/* ---------------------- GL_ATIX_texture_env_combine3 --------------------- */ + +#ifndef GL_ATIX_texture_env_combine3 +#define GL_ATIX_texture_env_combine3 1 + +#define GL_MODULATE_ADD_ATIX 0x8744 +#define GL_MODULATE_SIGNED_ADD_ATIX 0x8745 +#define GL_MODULATE_SUBTRACT_ATIX 0x8746 + +#define GLEW_ATIX_texture_env_combine3 GLEW_GET_VAR(__GLEW_ATIX_texture_env_combine3) + +#endif /* GL_ATIX_texture_env_combine3 */ + +/* ----------------------- GL_ATIX_texture_env_route ----------------------- */ + +#ifndef GL_ATIX_texture_env_route +#define GL_ATIX_texture_env_route 1 + +#define GL_SECONDARY_COLOR_ATIX 0x8747 +#define GL_TEXTURE_OUTPUT_RGB_ATIX 0x8748 +#define GL_TEXTURE_OUTPUT_ALPHA_ATIX 0x8749 + +#define GLEW_ATIX_texture_env_route GLEW_GET_VAR(__GLEW_ATIX_texture_env_route) + +#endif /* GL_ATIX_texture_env_route */ + +/* ---------------- GL_ATIX_vertex_shader_output_point_size ---------------- */ + +#ifndef GL_ATIX_vertex_shader_output_point_size +#define GL_ATIX_vertex_shader_output_point_size 1 + +#define GL_OUTPUT_POINT_SIZE_ATIX 0x610E + +#define GLEW_ATIX_vertex_shader_output_point_size GLEW_GET_VAR(__GLEW_ATIX_vertex_shader_output_point_size) + +#endif /* GL_ATIX_vertex_shader_output_point_size */ + +/* -------------------------- GL_ATI_draw_buffers -------------------------- */ + +#ifndef GL_ATI_draw_buffers +#define GL_ATI_draw_buffers 1 + +#define GL_MAX_DRAW_BUFFERS_ATI 0x8824 +#define GL_DRAW_BUFFER0_ATI 0x8825 +#define GL_DRAW_BUFFER1_ATI 0x8826 +#define GL_DRAW_BUFFER2_ATI 0x8827 +#define GL_DRAW_BUFFER3_ATI 0x8828 +#define GL_DRAW_BUFFER4_ATI 0x8829 +#define GL_DRAW_BUFFER5_ATI 0x882A +#define GL_DRAW_BUFFER6_ATI 0x882B +#define GL_DRAW_BUFFER7_ATI 0x882C +#define GL_DRAW_BUFFER8_ATI 0x882D +#define GL_DRAW_BUFFER9_ATI 0x882E +#define GL_DRAW_BUFFER10_ATI 0x882F +#define GL_DRAW_BUFFER11_ATI 0x8830 +#define GL_DRAW_BUFFER12_ATI 0x8831 +#define GL_DRAW_BUFFER13_ATI 0x8832 +#define GL_DRAW_BUFFER14_ATI 0x8833 +#define GL_DRAW_BUFFER15_ATI 0x8834 + +typedef void (GLAPIENTRY * PFNGLDRAWBUFFERSATIPROC) (GLsizei n, const GLenum* bufs); + +#define glDrawBuffersATI GLEW_GET_FUN(__glewDrawBuffersATI) + +#define GLEW_ATI_draw_buffers GLEW_GET_VAR(__GLEW_ATI_draw_buffers) + +#endif /* GL_ATI_draw_buffers */ + +/* -------------------------- GL_ATI_element_array ------------------------- */ + +#ifndef GL_ATI_element_array +#define GL_ATI_element_array 1 + +#define GL_ELEMENT_ARRAY_ATI 0x8768 +#define GL_ELEMENT_ARRAY_TYPE_ATI 0x8769 +#define GL_ELEMENT_ARRAY_POINTER_ATI 0x876A + +typedef void (GLAPIENTRY * PFNGLDRAWELEMENTARRAYATIPROC) (GLenum mode, GLsizei count); +typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTARRAYATIPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count); +typedef void (GLAPIENTRY * PFNGLELEMENTPOINTERATIPROC) (GLenum type, const void* pointer); + +#define glDrawElementArrayATI GLEW_GET_FUN(__glewDrawElementArrayATI) +#define glDrawRangeElementArrayATI GLEW_GET_FUN(__glewDrawRangeElementArrayATI) +#define glElementPointerATI GLEW_GET_FUN(__glewElementPointerATI) + +#define GLEW_ATI_element_array GLEW_GET_VAR(__GLEW_ATI_element_array) + +#endif /* GL_ATI_element_array */ + +/* ------------------------- GL_ATI_envmap_bumpmap ------------------------- */ + +#ifndef GL_ATI_envmap_bumpmap +#define GL_ATI_envmap_bumpmap 1 + +#define GL_BUMP_ROT_MATRIX_ATI 0x8775 +#define GL_BUMP_ROT_MATRIX_SIZE_ATI 0x8776 +#define GL_BUMP_NUM_TEX_UNITS_ATI 0x8777 +#define GL_BUMP_TEX_UNITS_ATI 0x8778 +#define GL_DUDV_ATI 0x8779 +#define GL_DU8DV8_ATI 0x877A +#define GL_BUMP_ENVMAP_ATI 0x877B +#define GL_BUMP_TARGET_ATI 0x877C + +typedef void (GLAPIENTRY * PFNGLGETTEXBUMPPARAMETERFVATIPROC) (GLenum pname, GLfloat *param); +typedef void (GLAPIENTRY * PFNGLGETTEXBUMPPARAMETERIVATIPROC) (GLenum pname, GLint *param); +typedef void (GLAPIENTRY * PFNGLTEXBUMPPARAMETERFVATIPROC) (GLenum pname, GLfloat *param); +typedef void (GLAPIENTRY * PFNGLTEXBUMPPARAMETERIVATIPROC) (GLenum pname, GLint *param); + +#define glGetTexBumpParameterfvATI GLEW_GET_FUN(__glewGetTexBumpParameterfvATI) +#define glGetTexBumpParameterivATI GLEW_GET_FUN(__glewGetTexBumpParameterivATI) +#define glTexBumpParameterfvATI GLEW_GET_FUN(__glewTexBumpParameterfvATI) +#define glTexBumpParameterivATI GLEW_GET_FUN(__glewTexBumpParameterivATI) + +#define GLEW_ATI_envmap_bumpmap GLEW_GET_VAR(__GLEW_ATI_envmap_bumpmap) + +#endif /* GL_ATI_envmap_bumpmap */ + +/* ------------------------- GL_ATI_fragment_shader ------------------------ */ + +#ifndef GL_ATI_fragment_shader +#define GL_ATI_fragment_shader 1 + +#define GL_RED_BIT_ATI 0x00000001 +#define GL_2X_BIT_ATI 0x00000001 +#define GL_4X_BIT_ATI 0x00000002 +#define GL_GREEN_BIT_ATI 0x00000002 +#define GL_COMP_BIT_ATI 0x00000002 +#define GL_BLUE_BIT_ATI 0x00000004 +#define GL_8X_BIT_ATI 0x00000004 +#define GL_NEGATE_BIT_ATI 0x00000004 +#define GL_BIAS_BIT_ATI 0x00000008 +#define GL_HALF_BIT_ATI 0x00000008 +#define GL_QUARTER_BIT_ATI 0x00000010 +#define GL_EIGHTH_BIT_ATI 0x00000020 +#define GL_SATURATE_BIT_ATI 0x00000040 +#define GL_FRAGMENT_SHADER_ATI 0x8920 +#define GL_REG_0_ATI 0x8921 +#define GL_REG_1_ATI 0x8922 +#define GL_REG_2_ATI 0x8923 +#define GL_REG_3_ATI 0x8924 +#define GL_REG_4_ATI 0x8925 +#define GL_REG_5_ATI 0x8926 +#define GL_CON_0_ATI 0x8941 +#define GL_CON_1_ATI 0x8942 +#define GL_CON_2_ATI 0x8943 +#define GL_CON_3_ATI 0x8944 +#define GL_CON_4_ATI 0x8945 +#define GL_CON_5_ATI 0x8946 +#define GL_CON_6_ATI 0x8947 +#define GL_CON_7_ATI 0x8948 +#define GL_MOV_ATI 0x8961 +#define GL_ADD_ATI 0x8963 +#define GL_MUL_ATI 0x8964 +#define GL_SUB_ATI 0x8965 +#define GL_DOT3_ATI 0x8966 +#define GL_DOT4_ATI 0x8967 +#define GL_MAD_ATI 0x8968 +#define GL_LERP_ATI 0x8969 +#define GL_CND_ATI 0x896A +#define GL_CND0_ATI 0x896B +#define GL_DOT2_ADD_ATI 0x896C +#define GL_SECONDARY_INTERPOLATOR_ATI 0x896D +#define GL_NUM_FRAGMENT_REGISTERS_ATI 0x896E +#define GL_NUM_FRAGMENT_CONSTANTS_ATI 0x896F +#define GL_NUM_PASSES_ATI 0x8970 +#define GL_NUM_INSTRUCTIONS_PER_PASS_ATI 0x8971 +#define GL_NUM_INSTRUCTIONS_TOTAL_ATI 0x8972 +#define GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI 0x8973 +#define GL_NUM_LOOPBACK_COMPONENTS_ATI 0x8974 +#define GL_COLOR_ALPHA_PAIRING_ATI 0x8975 +#define GL_SWIZZLE_STR_ATI 0x8976 +#define GL_SWIZZLE_STQ_ATI 0x8977 +#define GL_SWIZZLE_STR_DR_ATI 0x8978 +#define GL_SWIZZLE_STQ_DQ_ATI 0x8979 +#define GL_SWIZZLE_STRQ_ATI 0x897A +#define GL_SWIZZLE_STRQ_DQ_ATI 0x897B + +typedef void (GLAPIENTRY * PFNGLALPHAFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); +typedef void (GLAPIENTRY * PFNGLALPHAFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); +typedef void (GLAPIENTRY * PFNGLALPHAFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); +typedef void (GLAPIENTRY * PFNGLBEGINFRAGMENTSHADERATIPROC) (void); +typedef void (GLAPIENTRY * PFNGLBINDFRAGMENTSHADERATIPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLCOLORFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); +typedef void (GLAPIENTRY * PFNGLCOLORFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); +typedef void (GLAPIENTRY * PFNGLCOLORFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); +typedef void (GLAPIENTRY * PFNGLDELETEFRAGMENTSHADERATIPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLENDFRAGMENTSHADERATIPROC) (void); +typedef GLuint (GLAPIENTRY * PFNGLGENFRAGMENTSHADERSATIPROC) (GLuint range); +typedef void (GLAPIENTRY * PFNGLPASSTEXCOORDATIPROC) (GLuint dst, GLuint coord, GLenum swizzle); +typedef void (GLAPIENTRY * PFNGLSAMPLEMAPATIPROC) (GLuint dst, GLuint interp, GLenum swizzle); +typedef void (GLAPIENTRY * PFNGLSETFRAGMENTSHADERCONSTANTATIPROC) (GLuint dst, const GLfloat* value); + +#define glAlphaFragmentOp1ATI GLEW_GET_FUN(__glewAlphaFragmentOp1ATI) +#define glAlphaFragmentOp2ATI GLEW_GET_FUN(__glewAlphaFragmentOp2ATI) +#define glAlphaFragmentOp3ATI GLEW_GET_FUN(__glewAlphaFragmentOp3ATI) +#define glBeginFragmentShaderATI GLEW_GET_FUN(__glewBeginFragmentShaderATI) +#define glBindFragmentShaderATI GLEW_GET_FUN(__glewBindFragmentShaderATI) +#define glColorFragmentOp1ATI GLEW_GET_FUN(__glewColorFragmentOp1ATI) +#define glColorFragmentOp2ATI GLEW_GET_FUN(__glewColorFragmentOp2ATI) +#define glColorFragmentOp3ATI GLEW_GET_FUN(__glewColorFragmentOp3ATI) +#define glDeleteFragmentShaderATI GLEW_GET_FUN(__glewDeleteFragmentShaderATI) +#define glEndFragmentShaderATI GLEW_GET_FUN(__glewEndFragmentShaderATI) +#define glGenFragmentShadersATI GLEW_GET_FUN(__glewGenFragmentShadersATI) +#define glPassTexCoordATI GLEW_GET_FUN(__glewPassTexCoordATI) +#define glSampleMapATI GLEW_GET_FUN(__glewSampleMapATI) +#define glSetFragmentShaderConstantATI GLEW_GET_FUN(__glewSetFragmentShaderConstantATI) + +#define GLEW_ATI_fragment_shader GLEW_GET_VAR(__GLEW_ATI_fragment_shader) + +#endif /* GL_ATI_fragment_shader */ + +/* ------------------------ GL_ATI_map_object_buffer ----------------------- */ + +#ifndef GL_ATI_map_object_buffer +#define GL_ATI_map_object_buffer 1 + +typedef void* (GLAPIENTRY * PFNGLMAPOBJECTBUFFERATIPROC) (GLuint buffer); +typedef void (GLAPIENTRY * PFNGLUNMAPOBJECTBUFFERATIPROC) (GLuint buffer); + +#define glMapObjectBufferATI GLEW_GET_FUN(__glewMapObjectBufferATI) +#define glUnmapObjectBufferATI GLEW_GET_FUN(__glewUnmapObjectBufferATI) + +#define GLEW_ATI_map_object_buffer GLEW_GET_VAR(__GLEW_ATI_map_object_buffer) + +#endif /* GL_ATI_map_object_buffer */ + +/* -------------------------- GL_ATI_pn_triangles -------------------------- */ + +#ifndef GL_ATI_pn_triangles +#define GL_ATI_pn_triangles 1 + +#define GL_PN_TRIANGLES_ATI 0x87F0 +#define GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F1 +#define GL_PN_TRIANGLES_POINT_MODE_ATI 0x87F2 +#define GL_PN_TRIANGLES_NORMAL_MODE_ATI 0x87F3 +#define GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F4 +#define GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI 0x87F5 +#define GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI 0x87F6 +#define GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI 0x87F7 +#define GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI 0x87F8 + +typedef void (GLAPIENTRY * PFNGLPNTRIANGLESFATIPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLPNTRIANGLESIATIPROC) (GLenum pname, GLint param); + +#define glPNTrianglesfATI GLEW_GET_FUN(__glPNTrianglewesfATI) +#define glPNTrianglesiATI GLEW_GET_FUN(__glPNTrianglewesiATI) + +#define GLEW_ATI_pn_triangles GLEW_GET_VAR(__GLEW_ATI_pn_triangles) + +#endif /* GL_ATI_pn_triangles */ + +/* ------------------------ GL_ATI_separate_stencil ------------------------ */ + +#ifndef GL_ATI_separate_stencil +#define GL_ATI_separate_stencil 1 + +#define GL_STENCIL_BACK_FUNC_ATI 0x8800 +#define GL_STENCIL_BACK_FAIL_ATI 0x8801 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI 0x8803 + +typedef void (GLAPIENTRY * PFNGLSTENCILFUNCSEPARATEATIPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); +typedef void (GLAPIENTRY * PFNGLSTENCILOPSEPARATEATIPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); + +#define glStencilFuncSeparateATI GLEW_GET_FUN(__glewStencilFuncSeparateATI) +#define glStencilOpSeparateATI GLEW_GET_FUN(__glewStencilOpSeparateATI) + +#define GLEW_ATI_separate_stencil GLEW_GET_VAR(__GLEW_ATI_separate_stencil) + +#endif /* GL_ATI_separate_stencil */ + +/* ----------------------- GL_ATI_shader_texture_lod ----------------------- */ + +#ifndef GL_ATI_shader_texture_lod +#define GL_ATI_shader_texture_lod 1 + +#define GLEW_ATI_shader_texture_lod GLEW_GET_VAR(__GLEW_ATI_shader_texture_lod) + +#endif /* GL_ATI_shader_texture_lod */ + +/* ---------------------- GL_ATI_text_fragment_shader ---------------------- */ + +#ifndef GL_ATI_text_fragment_shader +#define GL_ATI_text_fragment_shader 1 + +#define GL_TEXT_FRAGMENT_SHADER_ATI 0x8200 + +#define GLEW_ATI_text_fragment_shader GLEW_GET_VAR(__GLEW_ATI_text_fragment_shader) + +#endif /* GL_ATI_text_fragment_shader */ + +/* --------------------- GL_ATI_texture_compression_3dc -------------------- */ + +#ifndef GL_ATI_texture_compression_3dc +#define GL_ATI_texture_compression_3dc 1 + +#define GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI 0x8837 + +#define GLEW_ATI_texture_compression_3dc GLEW_GET_VAR(__GLEW_ATI_texture_compression_3dc) + +#endif /* GL_ATI_texture_compression_3dc */ + +/* ---------------------- GL_ATI_texture_env_combine3 ---------------------- */ + +#ifndef GL_ATI_texture_env_combine3 +#define GL_ATI_texture_env_combine3 1 + +#define GL_MODULATE_ADD_ATI 0x8744 +#define GL_MODULATE_SIGNED_ADD_ATI 0x8745 +#define GL_MODULATE_SUBTRACT_ATI 0x8746 + +#define GLEW_ATI_texture_env_combine3 GLEW_GET_VAR(__GLEW_ATI_texture_env_combine3) + +#endif /* GL_ATI_texture_env_combine3 */ + +/* -------------------------- GL_ATI_texture_float ------------------------- */ + +#ifndef GL_ATI_texture_float +#define GL_ATI_texture_float 1 + +#define GL_RGBA_FLOAT32_ATI 0x8814 +#define GL_RGB_FLOAT32_ATI 0x8815 +#define GL_ALPHA_FLOAT32_ATI 0x8816 +#define GL_INTENSITY_FLOAT32_ATI 0x8817 +#define GL_LUMINANCE_FLOAT32_ATI 0x8818 +#define GL_LUMINANCE_ALPHA_FLOAT32_ATI 0x8819 +#define GL_RGBA_FLOAT16_ATI 0x881A +#define GL_RGB_FLOAT16_ATI 0x881B +#define GL_ALPHA_FLOAT16_ATI 0x881C +#define GL_INTENSITY_FLOAT16_ATI 0x881D +#define GL_LUMINANCE_FLOAT16_ATI 0x881E +#define GL_LUMINANCE_ALPHA_FLOAT16_ATI 0x881F + +#define GLEW_ATI_texture_float GLEW_GET_VAR(__GLEW_ATI_texture_float) + +#endif /* GL_ATI_texture_float */ + +/* ----------------------- GL_ATI_texture_mirror_once ---------------------- */ + +#ifndef GL_ATI_texture_mirror_once +#define GL_ATI_texture_mirror_once 1 + +#define GL_MIRROR_CLAMP_ATI 0x8742 +#define GL_MIRROR_CLAMP_TO_EDGE_ATI 0x8743 + +#define GLEW_ATI_texture_mirror_once GLEW_GET_VAR(__GLEW_ATI_texture_mirror_once) + +#endif /* GL_ATI_texture_mirror_once */ + +/* ----------------------- GL_ATI_vertex_array_object ---------------------- */ + +#ifndef GL_ATI_vertex_array_object +#define GL_ATI_vertex_array_object 1 + +#define GL_STATIC_ATI 0x8760 +#define GL_DYNAMIC_ATI 0x8761 +#define GL_PRESERVE_ATI 0x8762 +#define GL_DISCARD_ATI 0x8763 +#define GL_OBJECT_BUFFER_SIZE_ATI 0x8764 +#define GL_OBJECT_BUFFER_USAGE_ATI 0x8765 +#define GL_ARRAY_OBJECT_BUFFER_ATI 0x8766 +#define GL_ARRAY_OBJECT_OFFSET_ATI 0x8767 + +typedef void (GLAPIENTRY * PFNGLARRAYOBJECTATIPROC) (GLenum array, GLint size, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); +typedef void (GLAPIENTRY * PFNGLFREEOBJECTBUFFERATIPROC) (GLuint buffer); +typedef void (GLAPIENTRY * PFNGLGETARRAYOBJECTFVATIPROC) (GLenum array, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETARRAYOBJECTIVATIPROC) (GLenum array, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETOBJECTBUFFERFVATIPROC) (GLuint buffer, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETOBJECTBUFFERIVATIPROC) (GLuint buffer, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETVARIANTARRAYOBJECTFVATIPROC) (GLuint id, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETVARIANTARRAYOBJECTIVATIPROC) (GLuint id, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISOBJECTBUFFERATIPROC) (GLuint buffer); +typedef GLuint (GLAPIENTRY * PFNGLNEWOBJECTBUFFERATIPROC) (GLsizei size, const void* pointer, GLenum usage); +typedef void (GLAPIENTRY * PFNGLUPDATEOBJECTBUFFERATIPROC) (GLuint buffer, GLuint offset, GLsizei size, const void* pointer, GLenum preserve); +typedef void (GLAPIENTRY * PFNGLVARIANTARRAYOBJECTATIPROC) (GLuint id, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); + +#define glArrayObjectATI GLEW_GET_FUN(__glewArrayObjectATI) +#define glFreeObjectBufferATI GLEW_GET_FUN(__glewFreeObjectBufferATI) +#define glGetArrayObjectfvATI GLEW_GET_FUN(__glewGetArrayObjectfvATI) +#define glGetArrayObjectivATI GLEW_GET_FUN(__glewGetArrayObjectivATI) +#define glGetObjectBufferfvATI GLEW_GET_FUN(__glewGetObjectBufferfvATI) +#define glGetObjectBufferivATI GLEW_GET_FUN(__glewGetObjectBufferivATI) +#define glGetVariantArrayObjectfvATI GLEW_GET_FUN(__glewGetVariantArrayObjectfvATI) +#define glGetVariantArrayObjectivATI GLEW_GET_FUN(__glewGetVariantArrayObjectivATI) +#define glIsObjectBufferATI GLEW_GET_FUN(__glewIsObjectBufferATI) +#define glNewObjectBufferATI GLEW_GET_FUN(__glewNewObjectBufferATI) +#define glUpdateObjectBufferATI GLEW_GET_FUN(__glewUpdateObjectBufferATI) +#define glVariantArrayObjectATI GLEW_GET_FUN(__glewVariantArrayObjectATI) + +#define GLEW_ATI_vertex_array_object GLEW_GET_VAR(__GLEW_ATI_vertex_array_object) + +#endif /* GL_ATI_vertex_array_object */ + +/* ------------------- GL_ATI_vertex_attrib_array_object ------------------- */ + +#ifndef GL_ATI_vertex_attrib_array_object +#define GL_ATI_vertex_attrib_array_object 1 + +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC) (GLuint index, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC) (GLuint index, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBARRAYOBJECTATIPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLuint buffer, GLuint offset); + +#define glGetVertexAttribArrayObjectfvATI GLEW_GET_FUN(__glewGetVertexAttribArrayObjectfvATI) +#define glGetVertexAttribArrayObjectivATI GLEW_GET_FUN(__glewGetVertexAttribArrayObjectivATI) +#define glVertexAttribArrayObjectATI GLEW_GET_FUN(__glewVertexAttribArrayObjectATI) + +#define GLEW_ATI_vertex_attrib_array_object GLEW_GET_VAR(__GLEW_ATI_vertex_attrib_array_object) + +#endif /* GL_ATI_vertex_attrib_array_object */ + +/* ------------------------- GL_ATI_vertex_streams ------------------------- */ + +#ifndef GL_ATI_vertex_streams +#define GL_ATI_vertex_streams 1 + +#define GL_MAX_VERTEX_STREAMS_ATI 0x876B +#define GL_VERTEX_SOURCE_ATI 0x876C +#define GL_VERTEX_STREAM0_ATI 0x876D +#define GL_VERTEX_STREAM1_ATI 0x876E +#define GL_VERTEX_STREAM2_ATI 0x876F +#define GL_VERTEX_STREAM3_ATI 0x8770 +#define GL_VERTEX_STREAM4_ATI 0x8771 +#define GL_VERTEX_STREAM5_ATI 0x8772 +#define GL_VERTEX_STREAM6_ATI 0x8773 +#define GL_VERTEX_STREAM7_ATI 0x8774 + +typedef void (GLAPIENTRY * PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC) (GLenum stream); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3BATIPROC) (GLenum stream, GLbyte x, GLbyte y, GLbyte z); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3BVATIPROC) (GLenum stream, const GLbyte *v); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3DVATIPROC) (GLenum stream, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3FVATIPROC) (GLenum stream, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3IATIPROC) (GLenum stream, GLint x, GLint y, GLint z); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3IVATIPROC) (GLenum stream, const GLint *v); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3SVATIPROC) (GLenum stream, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLVERTEXBLENDENVFATIPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLVERTEXBLENDENVIATIPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2DATIPROC) (GLenum stream, GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2DVATIPROC) (GLenum stream, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2FATIPROC) (GLenum stream, GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2FVATIPROC) (GLenum stream, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2IATIPROC) (GLenum stream, GLint x, GLint y); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2IVATIPROC) (GLenum stream, const GLint *v); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2SATIPROC) (GLenum stream, GLshort x, GLshort y); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2SVATIPROC) (GLenum stream, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3DVATIPROC) (GLenum stream, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3FVATIPROC) (GLenum stream, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3IATIPROC) (GLenum stream, GLint x, GLint y, GLint z); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3IVATIPROC) (GLenum stream, const GLint *v); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3SVATIPROC) (GLenum stream, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4DVATIPROC) (GLenum stream, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4FVATIPROC) (GLenum stream, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4IATIPROC) (GLenum stream, GLint x, GLint y, GLint z, GLint w); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4IVATIPROC) (GLenum stream, const GLint *v); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4SVATIPROC) (GLenum stream, const GLshort *v); + +#define glClientActiveVertexStreamATI GLEW_GET_FUN(__glewClientActiveVertexStreamATI) +#define glNormalStream3bATI GLEW_GET_FUN(__glewNormalStream3bATI) +#define glNormalStream3bvATI GLEW_GET_FUN(__glewNormalStream3bvATI) +#define glNormalStream3dATI GLEW_GET_FUN(__glewNormalStream3dATI) +#define glNormalStream3dvATI GLEW_GET_FUN(__glewNormalStream3dvATI) +#define glNormalStream3fATI GLEW_GET_FUN(__glewNormalStream3fATI) +#define glNormalStream3fvATI GLEW_GET_FUN(__glewNormalStream3fvATI) +#define glNormalStream3iATI GLEW_GET_FUN(__glewNormalStream3iATI) +#define glNormalStream3ivATI GLEW_GET_FUN(__glewNormalStream3ivATI) +#define glNormalStream3sATI GLEW_GET_FUN(__glewNormalStream3sATI) +#define glNormalStream3svATI GLEW_GET_FUN(__glewNormalStream3svATI) +#define glVertexBlendEnvfATI GLEW_GET_FUN(__glewVertexBlendEnvfATI) +#define glVertexBlendEnviATI GLEW_GET_FUN(__glewVertexBlendEnviATI) +#define glVertexStream2dATI GLEW_GET_FUN(__glewVertexStream2dATI) +#define glVertexStream2dvATI GLEW_GET_FUN(__glewVertexStream2dvATI) +#define glVertexStream2fATI GLEW_GET_FUN(__glewVertexStream2fATI) +#define glVertexStream2fvATI GLEW_GET_FUN(__glewVertexStream2fvATI) +#define glVertexStream2iATI GLEW_GET_FUN(__glewVertexStream2iATI) +#define glVertexStream2ivATI GLEW_GET_FUN(__glewVertexStream2ivATI) +#define glVertexStream2sATI GLEW_GET_FUN(__glewVertexStream2sATI) +#define glVertexStream2svATI GLEW_GET_FUN(__glewVertexStream2svATI) +#define glVertexStream3dATI GLEW_GET_FUN(__glewVertexStream3dATI) +#define glVertexStream3dvATI GLEW_GET_FUN(__glewVertexStream3dvATI) +#define glVertexStream3fATI GLEW_GET_FUN(__glewVertexStream3fATI) +#define glVertexStream3fvATI GLEW_GET_FUN(__glewVertexStream3fvATI) +#define glVertexStream3iATI GLEW_GET_FUN(__glewVertexStream3iATI) +#define glVertexStream3ivATI GLEW_GET_FUN(__glewVertexStream3ivATI) +#define glVertexStream3sATI GLEW_GET_FUN(__glewVertexStream3sATI) +#define glVertexStream3svATI GLEW_GET_FUN(__glewVertexStream3svATI) +#define glVertexStream4dATI GLEW_GET_FUN(__glewVertexStream4dATI) +#define glVertexStream4dvATI GLEW_GET_FUN(__glewVertexStream4dvATI) +#define glVertexStream4fATI GLEW_GET_FUN(__glewVertexStream4fATI) +#define glVertexStream4fvATI GLEW_GET_FUN(__glewVertexStream4fvATI) +#define glVertexStream4iATI GLEW_GET_FUN(__glewVertexStream4iATI) +#define glVertexStream4ivATI GLEW_GET_FUN(__glewVertexStream4ivATI) +#define glVertexStream4sATI GLEW_GET_FUN(__glewVertexStream4sATI) +#define glVertexStream4svATI GLEW_GET_FUN(__glewVertexStream4svATI) + +#define GLEW_ATI_vertex_streams GLEW_GET_VAR(__GLEW_ATI_vertex_streams) + +#endif /* GL_ATI_vertex_streams */ + +/* --------------------------- GL_EXT_422_pixels --------------------------- */ + +#ifndef GL_EXT_422_pixels +#define GL_EXT_422_pixels 1 + +#define GL_422_EXT 0x80CC +#define GL_422_REV_EXT 0x80CD +#define GL_422_AVERAGE_EXT 0x80CE +#define GL_422_REV_AVERAGE_EXT 0x80CF + +#define GLEW_EXT_422_pixels GLEW_GET_VAR(__GLEW_EXT_422_pixels) + +#endif /* GL_EXT_422_pixels */ + +/* ---------------------------- GL_EXT_Cg_shader --------------------------- */ + +#ifndef GL_EXT_Cg_shader +#define GL_EXT_Cg_shader 1 + +#define GL_CG_VERTEX_SHADER_EXT 0x890E +#define GL_CG_FRAGMENT_SHADER_EXT 0x890F + +#define GLEW_EXT_Cg_shader GLEW_GET_VAR(__GLEW_EXT_Cg_shader) + +#endif /* GL_EXT_Cg_shader */ + +/* ------------------------------ GL_EXT_abgr ------------------------------ */ + +#ifndef GL_EXT_abgr +#define GL_EXT_abgr 1 + +#define GL_ABGR_EXT 0x8000 + +#define GLEW_EXT_abgr GLEW_GET_VAR(__GLEW_EXT_abgr) + +#endif /* GL_EXT_abgr */ + +/* ------------------------------ GL_EXT_bgra ------------------------------ */ + +#ifndef GL_EXT_bgra +#define GL_EXT_bgra 1 + +#define GL_BGR_EXT 0x80E0 +#define GL_BGRA_EXT 0x80E1 + +#define GLEW_EXT_bgra GLEW_GET_VAR(__GLEW_EXT_bgra) + +#endif /* GL_EXT_bgra */ + +/* ------------------------ GL_EXT_bindable_uniform ------------------------ */ + +#ifndef GL_EXT_bindable_uniform +#define GL_EXT_bindable_uniform 1 + +#define GL_MAX_VERTEX_BINDABLE_UNIFORMS_EXT 0x8DE2 +#define GL_MAX_FRAGMENT_BINDABLE_UNIFORMS_EXT 0x8DE3 +#define GL_MAX_GEOMETRY_BINDABLE_UNIFORMS_EXT 0x8DE4 +#define GL_MAX_BINDABLE_UNIFORM_SIZE_EXT 0x8DED +#define GL_UNIFORM_BUFFER_EXT 0x8DEE +#define GL_UNIFORM_BUFFER_BINDING_EXT 0x8DEF + +typedef GLint (GLAPIENTRY * PFNGLGETUNIFORMBUFFERSIZEEXTPROC) (GLuint program, GLint location); +typedef GLintptr (GLAPIENTRY * PFNGLGETUNIFORMOFFSETEXTPROC) (GLuint program, GLint location); +typedef void (GLAPIENTRY * PFNGLUNIFORMBUFFEREXTPROC) (GLuint program, GLint location, GLuint buffer); + +#define glGetUniformBufferSizeEXT GLEW_GET_FUN(__glewGetUniformBufferSizeEXT) +#define glGetUniformOffsetEXT GLEW_GET_FUN(__glewGetUniformOffsetEXT) +#define glUniformBufferEXT GLEW_GET_FUN(__glewUniformBufferEXT) + +#define GLEW_EXT_bindable_uniform GLEW_GET_VAR(__GLEW_EXT_bindable_uniform) + +#endif /* GL_EXT_bindable_uniform */ + +/* --------------------------- GL_EXT_blend_color -------------------------- */ + +#ifndef GL_EXT_blend_color +#define GL_EXT_blend_color 1 + +#define GL_CONSTANT_COLOR_EXT 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR_EXT 0x8002 +#define GL_CONSTANT_ALPHA_EXT 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA_EXT 0x8004 +#define GL_BLEND_COLOR_EXT 0x8005 + +typedef void (GLAPIENTRY * PFNGLBLENDCOLOREXTPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); + +#define glBlendColorEXT GLEW_GET_FUN(__glewBlendColorEXT) + +#define GLEW_EXT_blend_color GLEW_GET_VAR(__GLEW_EXT_blend_color) + +#endif /* GL_EXT_blend_color */ + +/* --------------------- GL_EXT_blend_equation_separate -------------------- */ + +#ifndef GL_EXT_blend_equation_separate +#define GL_EXT_blend_equation_separate 1 + +#define GL_BLEND_EQUATION_RGB_EXT 0x8009 +#define GL_BLEND_EQUATION_ALPHA_EXT 0x883D + +typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEEXTPROC) (GLenum modeRGB, GLenum modeAlpha); + +#define glBlendEquationSeparateEXT GLEW_GET_FUN(__glewBlendEquationSeparateEXT) + +#define GLEW_EXT_blend_equation_separate GLEW_GET_VAR(__GLEW_EXT_blend_equation_separate) + +#endif /* GL_EXT_blend_equation_separate */ + +/* ----------------------- GL_EXT_blend_func_separate ---------------------- */ + +#ifndef GL_EXT_blend_func_separate +#define GL_EXT_blend_func_separate 1 + +#define GL_BLEND_DST_RGB_EXT 0x80C8 +#define GL_BLEND_SRC_RGB_EXT 0x80C9 +#define GL_BLEND_DST_ALPHA_EXT 0x80CA +#define GL_BLEND_SRC_ALPHA_EXT 0x80CB + +typedef void (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEEXTPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); + +#define glBlendFuncSeparateEXT GLEW_GET_FUN(__glewBlendFuncSeparateEXT) + +#define GLEW_EXT_blend_func_separate GLEW_GET_VAR(__GLEW_EXT_blend_func_separate) + +#endif /* GL_EXT_blend_func_separate */ + +/* ------------------------- GL_EXT_blend_logic_op ------------------------- */ + +#ifndef GL_EXT_blend_logic_op +#define GL_EXT_blend_logic_op 1 + +#define GLEW_EXT_blend_logic_op GLEW_GET_VAR(__GLEW_EXT_blend_logic_op) + +#endif /* GL_EXT_blend_logic_op */ + +/* -------------------------- GL_EXT_blend_minmax -------------------------- */ + +#ifndef GL_EXT_blend_minmax +#define GL_EXT_blend_minmax 1 + +#define GL_FUNC_ADD_EXT 0x8006 +#define GL_MIN_EXT 0x8007 +#define GL_MAX_EXT 0x8008 +#define GL_BLEND_EQUATION_EXT 0x8009 + +typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONEXTPROC) (GLenum mode); + +#define glBlendEquationEXT GLEW_GET_FUN(__glewBlendEquationEXT) + +#define GLEW_EXT_blend_minmax GLEW_GET_VAR(__GLEW_EXT_blend_minmax) + +#endif /* GL_EXT_blend_minmax */ + +/* ------------------------- GL_EXT_blend_subtract ------------------------- */ + +#ifndef GL_EXT_blend_subtract +#define GL_EXT_blend_subtract 1 + +#define GL_FUNC_SUBTRACT_EXT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT_EXT 0x800B + +#define GLEW_EXT_blend_subtract GLEW_GET_VAR(__GLEW_EXT_blend_subtract) + +#endif /* GL_EXT_blend_subtract */ + +/* ------------------------ GL_EXT_clip_volume_hint ------------------------ */ + +#ifndef GL_EXT_clip_volume_hint +#define GL_EXT_clip_volume_hint 1 + +#define GL_CLIP_VOLUME_CLIPPING_HINT_EXT 0x80F0 + +#define GLEW_EXT_clip_volume_hint GLEW_GET_VAR(__GLEW_EXT_clip_volume_hint) + +#endif /* GL_EXT_clip_volume_hint */ + +/* ------------------------------ GL_EXT_cmyka ----------------------------- */ + +#ifndef GL_EXT_cmyka +#define GL_EXT_cmyka 1 + +#define GL_CMYK_EXT 0x800C +#define GL_CMYKA_EXT 0x800D +#define GL_PACK_CMYK_HINT_EXT 0x800E +#define GL_UNPACK_CMYK_HINT_EXT 0x800F + +#define GLEW_EXT_cmyka GLEW_GET_VAR(__GLEW_EXT_cmyka) + +#endif /* GL_EXT_cmyka */ + +/* ------------------------- GL_EXT_color_subtable ------------------------- */ + +#ifndef GL_EXT_color_subtable +#define GL_EXT_color_subtable 1 + +typedef void (GLAPIENTRY * PFNGLCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const void* data); +typedef void (GLAPIENTRY * PFNGLCOPYCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); + +#define glColorSubTableEXT GLEW_GET_FUN(__glewColorSubTableEXT) +#define glCopyColorSubTableEXT GLEW_GET_FUN(__glewCopyColorSubTableEXT) + +#define GLEW_EXT_color_subtable GLEW_GET_VAR(__GLEW_EXT_color_subtable) + +#endif /* GL_EXT_color_subtable */ + +/* ---------------------- GL_EXT_compiled_vertex_array --------------------- */ + +#ifndef GL_EXT_compiled_vertex_array +#define GL_EXT_compiled_vertex_array 1 + +#define GL_ARRAY_ELEMENT_LOCK_FIRST_EXT 0x81A8 +#define GL_ARRAY_ELEMENT_LOCK_COUNT_EXT 0x81A9 + +typedef void (GLAPIENTRY * PFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count); +typedef void (GLAPIENTRY * PFNGLUNLOCKARRAYSEXTPROC) (void); + +#define glLockArraysEXT GLEW_GET_FUN(__glewLockArraysEXT) +#define glUnlockArraysEXT GLEW_GET_FUN(__glewUnlockArraysEXT) + +#define GLEW_EXT_compiled_vertex_array GLEW_GET_VAR(__GLEW_EXT_compiled_vertex_array) + +#endif /* GL_EXT_compiled_vertex_array */ + +/* --------------------------- GL_EXT_convolution -------------------------- */ + +#ifndef GL_EXT_convolution +#define GL_EXT_convolution 1 + +#define GL_CONVOLUTION_1D_EXT 0x8010 +#define GL_CONVOLUTION_2D_EXT 0x8011 +#define GL_SEPARABLE_2D_EXT 0x8012 +#define GL_CONVOLUTION_BORDER_MODE_EXT 0x8013 +#define GL_CONVOLUTION_FILTER_SCALE_EXT 0x8014 +#define GL_CONVOLUTION_FILTER_BIAS_EXT 0x8015 +#define GL_REDUCE_EXT 0x8016 +#define GL_CONVOLUTION_FORMAT_EXT 0x8017 +#define GL_CONVOLUTION_WIDTH_EXT 0x8018 +#define GL_CONVOLUTION_HEIGHT_EXT 0x8019 +#define GL_MAX_CONVOLUTION_WIDTH_EXT 0x801A +#define GL_MAX_CONVOLUTION_HEIGHT_EXT 0x801B +#define GL_POST_CONVOLUTION_RED_SCALE_EXT 0x801C +#define GL_POST_CONVOLUTION_GREEN_SCALE_EXT 0x801D +#define GL_POST_CONVOLUTION_BLUE_SCALE_EXT 0x801E +#define GL_POST_CONVOLUTION_ALPHA_SCALE_EXT 0x801F +#define GL_POST_CONVOLUTION_RED_BIAS_EXT 0x8020 +#define GL_POST_CONVOLUTION_GREEN_BIAS_EXT 0x8021 +#define GL_POST_CONVOLUTION_BLUE_BIAS_EXT 0x8022 +#define GL_POST_CONVOLUTION_ALPHA_BIAS_EXT 0x8023 + +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void* image); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* image); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRY * PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, void* image); +typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETSEPARABLEFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, void* row, void* column, void* span); +typedef void (GLAPIENTRY * PFNGLSEPARABLEFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* row, const void* column); + +#define glConvolutionFilter1DEXT GLEW_GET_FUN(__glewConvolutionFilter1DEXT) +#define glConvolutionFilter2DEXT GLEW_GET_FUN(__glewConvolutionFilter2DEXT) +#define glConvolutionParameterfEXT GLEW_GET_FUN(__glewConvolutionParameterfEXT) +#define glConvolutionParameterfvEXT GLEW_GET_FUN(__glewConvolutionParameterfvEXT) +#define glConvolutionParameteriEXT GLEW_GET_FUN(__glewConvolutionParameteriEXT) +#define glConvolutionParameterivEXT GLEW_GET_FUN(__glewConvolutionParameterivEXT) +#define glCopyConvolutionFilter1DEXT GLEW_GET_FUN(__glewCopyConvolutionFilter1DEXT) +#define glCopyConvolutionFilter2DEXT GLEW_GET_FUN(__glewCopyConvolutionFilter2DEXT) +#define glGetConvolutionFilterEXT GLEW_GET_FUN(__glewGetConvolutionFilterEXT) +#define glGetConvolutionParameterfvEXT GLEW_GET_FUN(__glewGetConvolutionParameterfvEXT) +#define glGetConvolutionParameterivEXT GLEW_GET_FUN(__glewGetConvolutionParameterivEXT) +#define glGetSeparableFilterEXT GLEW_GET_FUN(__glewGetSeparableFilterEXT) +#define glSeparableFilter2DEXT GLEW_GET_FUN(__glewSeparableFilter2DEXT) + +#define GLEW_EXT_convolution GLEW_GET_VAR(__GLEW_EXT_convolution) + +#endif /* GL_EXT_convolution */ + +/* ------------------------ GL_EXT_coordinate_frame ------------------------ */ + +#ifndef GL_EXT_coordinate_frame +#define GL_EXT_coordinate_frame 1 + +#define GL_TANGENT_ARRAY_EXT 0x8439 +#define GL_BINORMAL_ARRAY_EXT 0x843A +#define GL_CURRENT_TANGENT_EXT 0x843B +#define GL_CURRENT_BINORMAL_EXT 0x843C +#define GL_TANGENT_ARRAY_TYPE_EXT 0x843E +#define GL_TANGENT_ARRAY_STRIDE_EXT 0x843F +#define GL_BINORMAL_ARRAY_TYPE_EXT 0x8440 +#define GL_BINORMAL_ARRAY_STRIDE_EXT 0x8441 +#define GL_TANGENT_ARRAY_POINTER_EXT 0x8442 +#define GL_BINORMAL_ARRAY_POINTER_EXT 0x8443 +#define GL_MAP1_TANGENT_EXT 0x8444 +#define GL_MAP2_TANGENT_EXT 0x8445 +#define GL_MAP1_BINORMAL_EXT 0x8446 +#define GL_MAP2_BINORMAL_EXT 0x8447 + +typedef void (GLAPIENTRY * PFNGLBINORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, void* pointer); +typedef void (GLAPIENTRY * PFNGLTANGENTPOINTEREXTPROC) (GLenum type, GLsizei stride, void* pointer); + +#define glBinormalPointerEXT GLEW_GET_FUN(__glewBinormalPointerEXT) +#define glTangentPointerEXT GLEW_GET_FUN(__glewTangentPointerEXT) + +#define GLEW_EXT_coordinate_frame GLEW_GET_VAR(__GLEW_EXT_coordinate_frame) + +#endif /* GL_EXT_coordinate_frame */ + +/* -------------------------- GL_EXT_copy_texture -------------------------- */ + +#ifndef GL_EXT_copy_texture +#define GL_EXT_copy_texture 1 + +typedef void (GLAPIENTRY * PFNGLCOPYTEXIMAGE1DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); +typedef void (GLAPIENTRY * PFNGLCOPYTEXIMAGE2DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +typedef void (GLAPIENTRY * PFNGLCOPYTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRY * PFNGLCOPYTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLCOPYTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); + +#define glCopyTexImage1DEXT GLEW_GET_FUN(__glewCopyTexImage1DEXT) +#define glCopyTexImage2DEXT GLEW_GET_FUN(__glewCopyTexImage2DEXT) +#define glCopyTexSubImage1DEXT GLEW_GET_FUN(__glewCopyTexSubImage1DEXT) +#define glCopyTexSubImage2DEXT GLEW_GET_FUN(__glewCopyTexSubImage2DEXT) +#define glCopyTexSubImage3DEXT GLEW_GET_FUN(__glewCopyTexSubImage3DEXT) + +#define GLEW_EXT_copy_texture GLEW_GET_VAR(__GLEW_EXT_copy_texture) + +#endif /* GL_EXT_copy_texture */ + +/* --------------------------- GL_EXT_cull_vertex -------------------------- */ + +#ifndef GL_EXT_cull_vertex +#define GL_EXT_cull_vertex 1 + +typedef void (GLAPIENTRY * PFNGLCULLPARAMETERDVEXTPROC) (GLenum pname, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLCULLPARAMETERFVEXTPROC) (GLenum pname, GLfloat* params); + +#define glCullParameterdvEXT GLEW_GET_FUN(__glewCullParameterdvEXT) +#define glCullParameterfvEXT GLEW_GET_FUN(__glewCullParameterfvEXT) + +#define GLEW_EXT_cull_vertex GLEW_GET_VAR(__GLEW_EXT_cull_vertex) + +#endif /* GL_EXT_cull_vertex */ + +/* ------------------------ GL_EXT_depth_bounds_test ----------------------- */ + +#ifndef GL_EXT_depth_bounds_test +#define GL_EXT_depth_bounds_test 1 + +#define GL_DEPTH_BOUNDS_TEST_EXT 0x8890 +#define GL_DEPTH_BOUNDS_EXT 0x8891 + +typedef void (GLAPIENTRY * PFNGLDEPTHBOUNDSEXTPROC) (GLclampd zmin, GLclampd zmax); + +#define glDepthBoundsEXT GLEW_GET_FUN(__glewDepthBoundsEXT) + +#define GLEW_EXT_depth_bounds_test GLEW_GET_VAR(__GLEW_EXT_depth_bounds_test) + +#endif /* GL_EXT_depth_bounds_test */ + +/* ----------------------- GL_EXT_direct_state_access ---------------------- */ + +#ifndef GL_EXT_direct_state_access +#define GL_EXT_direct_state_access 1 + +#define GL_PROGRAM_MATRIX_EXT 0x8E2D +#define GL_TRANSPOSE_PROGRAM_MATRIX_EXT 0x8E2E +#define GL_PROGRAM_MATRIX_STACK_DEPTH_EXT 0x8E2F + +typedef void (GLAPIENTRY * PFNGLBINDMULTITEXTUREEXTPROC) (GLenum texunit, GLenum target, GLuint texture); +typedef GLenum (GLAPIENTRY * PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC) (GLuint framebuffer, GLenum target); +typedef void (GLAPIENTRY * PFNGLCLIENTATTRIBDEFAULTEXTPROC) (GLbitfield mask); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOPYMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); +typedef void (GLAPIENTRY * PFNGLCOPYMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +typedef void (GLAPIENTRY * PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRY * PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLCOPYTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); +typedef void (GLAPIENTRY * PFNGLCOPYTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +typedef void (GLAPIENTRY * PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRY * PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC) (GLenum array, GLuint index); +typedef void (GLAPIENTRY * PFNGLENABLECLIENTSTATEINDEXEDEXTPROC) (GLenum array, GLuint index); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC) (GLuint framebuffer, GLenum mode); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC) (GLuint framebuffer, GLsizei n, const GLenum* bufs); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERREADBUFFEREXTPROC) (GLuint framebuffer, GLenum mode); +typedef void (GLAPIENTRY * PFNGLGENERATEMULTITEXMIPMAPEXTPROC) (GLenum texunit, GLenum target); +typedef void (GLAPIENTRY * PFNGLGENERATETEXTUREMIPMAPEXTPROC) (GLuint texture, GLenum target); +typedef void (GLAPIENTRY * PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC) (GLenum texunit, GLenum target, GLint level, void* img); +typedef void (GLAPIENTRY * PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC) (GLuint texture, GLenum target, GLint level, void* img); +typedef void (GLAPIENTRY * PFNGLGETDOUBLEINDEXEDVEXTPROC) (GLenum pname, GLuint index, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETFLOATINDEXEDVEXTPROC) (GLenum pname, GLuint index, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum pname, GLint* param); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXENVFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXENVIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXGENDVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXGENFVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXGENIVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXIMAGEEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum format, GLenum type, void* pixels); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXPARAMETERIIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXPARAMETERIUIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLuint* params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC) (GLuint buffer, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERPOINTERVEXTPROC) (GLuint buffer, GLenum pname, void** params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, void* data); +typedef void (GLAPIENTRY * PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLuint* params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC) (GLuint program, GLenum target, GLuint index, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC) (GLuint program, GLenum target, GLuint index, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMSTRINGEXTPROC) (GLuint program, GLenum target, GLenum pname, void* string); +typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMIVEXTPROC) (GLuint program, GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC) (GLuint renderbuffer, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETPOINTERINDEXEDVEXTPROC) (GLenum pname, GLuint index, GLvoid** params); +typedef void (GLAPIENTRY * PFNGLGETTEXTUREIMAGEEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum format, GLenum type, void* pixels); +typedef void (GLAPIENTRY * PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERIIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERIUIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLuint* params); +typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint* params); +typedef GLvoid * (GLAPIENTRY * PFNGLMAPNAMEDBUFFEREXTPROC) (GLuint buffer, GLenum access); +typedef void (GLAPIENTRY * PFNGLMATRIXFRUSTUMEXTPROC) (GLenum matrixMode, GLdouble l, GLdouble r, GLdouble b, GLdouble t, GLdouble n, GLdouble f); +typedef void (GLAPIENTRY * PFNGLMATRIXLOADIDENTITYEXTPROC) (GLenum matrixMode); +typedef void (GLAPIENTRY * PFNGLMATRIXLOADTRANSPOSEDEXTPROC) (GLenum matrixMode, const GLdouble* m); +typedef void (GLAPIENTRY * PFNGLMATRIXLOADTRANSPOSEFEXTPROC) (GLenum matrixMode, const GLfloat* m); +typedef void (GLAPIENTRY * PFNGLMATRIXLOADDEXTPROC) (GLenum matrixMode, const GLdouble* m); +typedef void (GLAPIENTRY * PFNGLMATRIXLOADFEXTPROC) (GLenum matrixMode, const GLfloat* m); +typedef void (GLAPIENTRY * PFNGLMATRIXMULTTRANSPOSEDEXTPROC) (GLenum matrixMode, const GLdouble* m); +typedef void (GLAPIENTRY * PFNGLMATRIXMULTTRANSPOSEFEXTPROC) (GLenum matrixMode, const GLfloat* m); +typedef void (GLAPIENTRY * PFNGLMATRIXMULTDEXTPROC) (GLenum matrixMode, const GLdouble* m); +typedef void (GLAPIENTRY * PFNGLMATRIXMULTFEXTPROC) (GLenum matrixMode, const GLfloat* m); +typedef void (GLAPIENTRY * PFNGLMATRIXORTHOEXTPROC) (GLenum matrixMode, GLdouble l, GLdouble r, GLdouble b, GLdouble t, GLdouble n, GLdouble f); +typedef void (GLAPIENTRY * PFNGLMATRIXPOPEXTPROC) (GLenum matrixMode); +typedef void (GLAPIENTRY * PFNGLMATRIXPUSHEXTPROC) (GLenum matrixMode); +typedef void (GLAPIENTRY * PFNGLMATRIXROTATEDEXTPROC) (GLenum matrixMode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLMATRIXROTATEFEXTPROC) (GLenum matrixMode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLMATRIXSCALEDEXTPROC) (GLenum matrixMode, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLMATRIXSCALEFEXTPROC) (GLenum matrixMode, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLMATRIXTRANSLATEDEXTPROC) (GLenum matrixMode, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLMATRIXTRANSLATEFEXTPROC) (GLenum matrixMode, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLMULTITEXBUFFEREXTPROC) (GLenum texunit, GLenum target, GLenum internalformat, GLuint buffer); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDPOINTEREXTPROC) (GLenum texunit, GLint size, GLenum type, GLsizei stride, const void* pointer); +typedef void (GLAPIENTRY * PFNGLMULTITEXENVFEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLMULTITEXENVFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLMULTITEXENVIEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLMULTITEXENVIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLMULTITEXGENDEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLdouble param); +typedef void (GLAPIENTRY * PFNGLMULTITEXGENDVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLdouble* params); +typedef void (GLAPIENTRY * PFNGLMULTITEXGENFEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLMULTITEXGENFVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLMULTITEXGENIEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLMULTITEXGENIVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLMULTITEXIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERIIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERIUIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLuint* params); +typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERFEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLfloat* param); +typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERIEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint* param); +typedef void (GLAPIENTRY * PFNGLMULTITEXRENDERBUFFEREXTPROC) (GLenum texunit, GLenum target, GLuint renderbuffer); +typedef void (GLAPIENTRY * PFNGLMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLNAMEDBUFFERDATAEXTPROC) (GLuint buffer, GLsizeiptr size, const void* data, GLenum usage); +typedef void (GLAPIENTRY * PFNGLNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, const void* data); +typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC) (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLenum face); +typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC) (GLuint program, GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLdouble* params); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC) (GLuint program, GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC) (GLuint program, GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLint* params); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC) (GLuint program, GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLuint* params); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLint* params); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLuint* params); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMSTRINGEXTPROC) (GLuint program, GLenum target, GLenum format, GLsizei len, const void* string); +typedef void (GLAPIENTRY * PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC) (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC) (GLuint renderbuffer, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1FEXTPROC) (GLuint program, GLint location, GLfloat v0); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1IEXTPROC) (GLuint program, GLint location, GLint v0); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1UIEXTPROC) (GLuint program, GLint location, GLuint v0); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC) (GLbitfield mask); +typedef void (GLAPIENTRY * PFNGLTEXTUREBUFFEREXTPROC) (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer); +typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIUIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLuint* params); +typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERFEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLfloat* param); +typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLint* param); +typedef void (GLAPIENTRY * PFNGLTEXTURERENDERBUFFEREXTPROC) (GLuint texture, GLenum target, GLuint renderbuffer); +typedef void (GLAPIENTRY * PFNGLTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels); +typedef GLboolean (GLAPIENTRY * PFNGLUNMAPNAMEDBUFFEREXTPROC) (GLuint buffer); + +#define glBindMultiTextureEXT GLEW_GET_FUN(__glewBindMultiTextureEXT) +#define glCheckNamedFramebufferStatusEXT GLEW_GET_FUN(__glewCheckNamedFramebufferStatusEXT) +#define glClientAttribDefaultEXT GLEW_GET_FUN(__glewClientAttribDefaultEXT) +#define glCompressedMultiTexImage1DEXT GLEW_GET_FUN(__glewCompressedMultiTexImage1DEXT) +#define glCompressedMultiTexImage2DEXT GLEW_GET_FUN(__glewCompressedMultiTexImage2DEXT) +#define glCompressedMultiTexImage3DEXT GLEW_GET_FUN(__glewCompressedMultiTexImage3DEXT) +#define glCompressedMultiTexSubImage1DEXT GLEW_GET_FUN(__glewCompressedMultiTexSubImage1DEXT) +#define glCompressedMultiTexSubImage2DEXT GLEW_GET_FUN(__glewCompressedMultiTexSubImage2DEXT) +#define glCompressedMultiTexSubImage3DEXT GLEW_GET_FUN(__glewCompressedMultiTexSubImage3DEXT) +#define glCompressedTextureImage1DEXT GLEW_GET_FUN(__glewCompressedTextureImage1DEXT) +#define glCompressedTextureImage2DEXT GLEW_GET_FUN(__glewCompressedTextureImage2DEXT) +#define glCompressedTextureImage3DEXT GLEW_GET_FUN(__glewCompressedTextureImage3DEXT) +#define glCompressedTextureSubImage1DEXT GLEW_GET_FUN(__glewCompressedTextureSubImage1DEXT) +#define glCompressedTextureSubImage2DEXT GLEW_GET_FUN(__glewCompressedTextureSubImage2DEXT) +#define glCompressedTextureSubImage3DEXT GLEW_GET_FUN(__glewCompressedTextureSubImage3DEXT) +#define glCopyMultiTexImage1DEXT GLEW_GET_FUN(__glewCopyMultiTexImage1DEXT) +#define glCopyMultiTexImage2DEXT GLEW_GET_FUN(__glewCopyMultiTexImage2DEXT) +#define glCopyMultiTexSubImage1DEXT GLEW_GET_FUN(__glewCopyMultiTexSubImage1DEXT) +#define glCopyMultiTexSubImage2DEXT GLEW_GET_FUN(__glewCopyMultiTexSubImage2DEXT) +#define glCopyMultiTexSubImage3DEXT GLEW_GET_FUN(__glewCopyMultiTexSubImage3DEXT) +#define glCopyTextureImage1DEXT GLEW_GET_FUN(__glewCopyTextureImage1DEXT) +#define glCopyTextureImage2DEXT GLEW_GET_FUN(__glewCopyTextureImage2DEXT) +#define glCopyTextureSubImage1DEXT GLEW_GET_FUN(__glewCopyTextureSubImage1DEXT) +#define glCopyTextureSubImage2DEXT GLEW_GET_FUN(__glewCopyTextureSubImage2DEXT) +#define glCopyTextureSubImage3DEXT GLEW_GET_FUN(__glewCopyTextureSubImage3DEXT) +#define glDisableClientStateIndexedEXT GLEW_GET_FUN(__glewDisableClientStateIndexedEXT) +#define glEnableClientStateIndexedEXT GLEW_GET_FUN(__glewEnableClientStateIndexedEXT) +#define glFramebufferDrawBufferEXT GLEW_GET_FUN(__glewFramebufferDrawBufferEXT) +#define glFramebufferDrawBuffersEXT GLEW_GET_FUN(__glewFramebufferDrawBuffersEXT) +#define glFramebufferReadBufferEXT GLEW_GET_FUN(__glewFramebufferReadBufferEXT) +#define glGenerateMultiTexMipmapEXT GLEW_GET_FUN(__glewGenerateMultiTexMipmapEXT) +#define glGenerateTextureMipmapEXT GLEW_GET_FUN(__glewGenerateTextureMipmapEXT) +#define glGetCompressedMultiTexImageEXT GLEW_GET_FUN(__glewGetCompressedMultiTexImageEXT) +#define glGetCompressedTextureImageEXT GLEW_GET_FUN(__glewGetCompressedTextureImageEXT) +#define glGetDoubleIndexedvEXT GLEW_GET_FUN(__glewGetDoubleIndexedvEXT) +#define glGetFloatIndexedvEXT GLEW_GET_FUN(__glewGetFloatIndexedvEXT) +#define glGetFramebufferParameterivEXT GLEW_GET_FUN(__glewGetFramebufferParameterivEXT) +#define glGetMultiTexEnvfvEXT GLEW_GET_FUN(__glewGetMultiTexEnvfvEXT) +#define glGetMultiTexEnvivEXT GLEW_GET_FUN(__glewGetMultiTexEnvivEXT) +#define glGetMultiTexGendvEXT GLEW_GET_FUN(__glewGetMultiTexGendvEXT) +#define glGetMultiTexGenfvEXT GLEW_GET_FUN(__glewGetMultiTexGenfvEXT) +#define glGetMultiTexGenivEXT GLEW_GET_FUN(__glewGetMultiTexGenivEXT) +#define glGetMultiTexImageEXT GLEW_GET_FUN(__glewGetMultiTexImageEXT) +#define glGetMultiTexLevelParameterfvEXT GLEW_GET_FUN(__glewGetMultiTexLevelParameterfvEXT) +#define glGetMultiTexLevelParameterivEXT GLEW_GET_FUN(__glewGetMultiTexLevelParameterivEXT) +#define glGetMultiTexParameterIivEXT GLEW_GET_FUN(__glewGetMultiTexParameterIivEXT) +#define glGetMultiTexParameterIuivEXT GLEW_GET_FUN(__glewGetMultiTexParameterIuivEXT) +#define glGetMultiTexParameterfvEXT GLEW_GET_FUN(__glewGetMultiTexParameterfvEXT) +#define glGetMultiTexParameterivEXT GLEW_GET_FUN(__glewGetMultiTexParameterivEXT) +#define glGetNamedBufferParameterivEXT GLEW_GET_FUN(__glewGetNamedBufferParameterivEXT) +#define glGetNamedBufferPointervEXT GLEW_GET_FUN(__glewGetNamedBufferPointervEXT) +#define glGetNamedBufferSubDataEXT GLEW_GET_FUN(__glewGetNamedBufferSubDataEXT) +#define glGetNamedFramebufferAttachmentParameterivEXT GLEW_GET_FUN(__glewGetNamedFramebufferAttachmentParameterivEXT) +#define glGetNamedProgramLocalParameterIivEXT GLEW_GET_FUN(__glewGetNamedProgramLocalParameterIivEXT) +#define glGetNamedProgramLocalParameterIuivEXT GLEW_GET_FUN(__glewGetNamedProgramLocalParameterIuivEXT) +#define glGetNamedProgramLocalParameterdvEXT GLEW_GET_FUN(__glewGetNamedProgramLocalParameterdvEXT) +#define glGetNamedProgramLocalParameterfvEXT GLEW_GET_FUN(__glewGetNamedProgramLocalParameterfvEXT) +#define glGetNamedProgramStringEXT GLEW_GET_FUN(__glewGetNamedProgramStringEXT) +#define glGetNamedProgramivEXT GLEW_GET_FUN(__glewGetNamedProgramivEXT) +#define glGetNamedRenderbufferParameterivEXT GLEW_GET_FUN(__glewGetNamedRenderbufferParameterivEXT) +#define glGetPointerIndexedvEXT GLEW_GET_FUN(__glewGetPointerIndexedvEXT) +#define glGetTextureImageEXT GLEW_GET_FUN(__glewGetTextureImageEXT) +#define glGetTextureLevelParameterfvEXT GLEW_GET_FUN(__glewGetTextureLevelParameterfvEXT) +#define glGetTextureLevelParameterivEXT GLEW_GET_FUN(__glewGetTextureLevelParameterivEXT) +#define glGetTextureParameterIivEXT GLEW_GET_FUN(__glewGetTextureParameterIivEXT) +#define glGetTextureParameterIuivEXT GLEW_GET_FUN(__glewGetTextureParameterIuivEXT) +#define glGetTextureParameterfvEXT GLEW_GET_FUN(__glewGetTextureParameterfvEXT) +#define glGetTextureParameterivEXT GLEW_GET_FUN(__glewGetTextureParameterivEXT) +#define glMapNamedBufferEXT GLEW_GET_FUN(__glewMapNamedBufferEXT) +#define glMatrixFrustumEXT GLEW_GET_FUN(__glewMatrixFrustumEXT) +#define glMatrixLoadIdentityEXT GLEW_GET_FUN(__glewMatrixLoadIdentityEXT) +#define glMatrixLoadTransposedEXT GLEW_GET_FUN(__glewMatrixLoadTransposedEXT) +#define glMatrixLoadTransposefEXT GLEW_GET_FUN(__glewMatrixLoadTransposefEXT) +#define glMatrixLoaddEXT GLEW_GET_FUN(__glewMatrixLoaddEXT) +#define glMatrixLoadfEXT GLEW_GET_FUN(__glewMatrixLoadfEXT) +#define glMatrixMultTransposedEXT GLEW_GET_FUN(__glewMatrixMultTransposedEXT) +#define glMatrixMultTransposefEXT GLEW_GET_FUN(__glewMatrixMultTransposefEXT) +#define glMatrixMultdEXT GLEW_GET_FUN(__glewMatrixMultdEXT) +#define glMatrixMultfEXT GLEW_GET_FUN(__glewMatrixMultfEXT) +#define glMatrixOrthoEXT GLEW_GET_FUN(__glewMatrixOrthoEXT) +#define glMatrixPopEXT GLEW_GET_FUN(__glewMatrixPopEXT) +#define glMatrixPushEXT GLEW_GET_FUN(__glewMatrixPushEXT) +#define glMatrixRotatedEXT GLEW_GET_FUN(__glewMatrixRotatedEXT) +#define glMatrixRotatefEXT GLEW_GET_FUN(__glewMatrixRotatefEXT) +#define glMatrixScaledEXT GLEW_GET_FUN(__glewMatrixScaledEXT) +#define glMatrixScalefEXT GLEW_GET_FUN(__glewMatrixScalefEXT) +#define glMatrixTranslatedEXT GLEW_GET_FUN(__glewMatrixTranslatedEXT) +#define glMatrixTranslatefEXT GLEW_GET_FUN(__glewMatrixTranslatefEXT) +#define glMultiTexBufferEXT GLEW_GET_FUN(__glewMultiTexBufferEXT) +#define glMultiTexCoordPointerEXT GLEW_GET_FUN(__glewMultiTexCoordPointerEXT) +#define glMultiTexEnvfEXT GLEW_GET_FUN(__glewMultiTexEnvfEXT) +#define glMultiTexEnvfvEXT GLEW_GET_FUN(__glewMultiTexEnvfvEXT) +#define glMultiTexEnviEXT GLEW_GET_FUN(__glewMultiTexEnviEXT) +#define glMultiTexEnvivEXT GLEW_GET_FUN(__glewMultiTexEnvivEXT) +#define glMultiTexGendEXT GLEW_GET_FUN(__glewMultiTexGendEXT) +#define glMultiTexGendvEXT GLEW_GET_FUN(__glewMultiTexGendvEXT) +#define glMultiTexGenfEXT GLEW_GET_FUN(__glewMultiTexGenfEXT) +#define glMultiTexGenfvEXT GLEW_GET_FUN(__glewMultiTexGenfvEXT) +#define glMultiTexGeniEXT GLEW_GET_FUN(__glewMultiTexGeniEXT) +#define glMultiTexGenivEXT GLEW_GET_FUN(__glewMultiTexGenivEXT) +#define glMultiTexImage1DEXT GLEW_GET_FUN(__glewMultiTexImage1DEXT) +#define glMultiTexImage2DEXT GLEW_GET_FUN(__glewMultiTexImage2DEXT) +#define glMultiTexImage3DEXT GLEW_GET_FUN(__glewMultiTexImage3DEXT) +#define glMultiTexParameterIivEXT GLEW_GET_FUN(__glewMultiTexParameterIivEXT) +#define glMultiTexParameterIuivEXT GLEW_GET_FUN(__glewMultiTexParameterIuivEXT) +#define glMultiTexParameterfEXT GLEW_GET_FUN(__glewMultiTexParameterfEXT) +#define glMultiTexParameterfvEXT GLEW_GET_FUN(__glewMultiTexParameterfvEXT) +#define glMultiTexParameteriEXT GLEW_GET_FUN(__glewMultiTexParameteriEXT) +#define glMultiTexParameterivEXT GLEW_GET_FUN(__glewMultiTexParameterivEXT) +#define glMultiTexRenderbufferEXT GLEW_GET_FUN(__glewMultiTexRenderbufferEXT) +#define glMultiTexSubImage1DEXT GLEW_GET_FUN(__glewMultiTexSubImage1DEXT) +#define glMultiTexSubImage2DEXT GLEW_GET_FUN(__glewMultiTexSubImage2DEXT) +#define glMultiTexSubImage3DEXT GLEW_GET_FUN(__glewMultiTexSubImage3DEXT) +#define glNamedBufferDataEXT GLEW_GET_FUN(__glewNamedBufferDataEXT) +#define glNamedBufferSubDataEXT GLEW_GET_FUN(__glewNamedBufferSubDataEXT) +#define glNamedFramebufferRenderbufferEXT GLEW_GET_FUN(__glewNamedFramebufferRenderbufferEXT) +#define glNamedFramebufferTexture1DEXT GLEW_GET_FUN(__glewNamedFramebufferTexture1DEXT) +#define glNamedFramebufferTexture2DEXT GLEW_GET_FUN(__glewNamedFramebufferTexture2DEXT) +#define glNamedFramebufferTexture3DEXT GLEW_GET_FUN(__glewNamedFramebufferTexture3DEXT) +#define glNamedFramebufferTextureEXT GLEW_GET_FUN(__glewNamedFramebufferTextureEXT) +#define glNamedFramebufferTextureFaceEXT GLEW_GET_FUN(__glewNamedFramebufferTextureFaceEXT) +#define glNamedFramebufferTextureLayerEXT GLEW_GET_FUN(__glewNamedFramebufferTextureLayerEXT) +#define glNamedProgramLocalParameter4dEXT GLEW_GET_FUN(__glewNamedProgramLocalParameter4dEXT) +#define glNamedProgramLocalParameter4dvEXT GLEW_GET_FUN(__glewNamedProgramLocalParameter4dvEXT) +#define glNamedProgramLocalParameter4fEXT GLEW_GET_FUN(__glewNamedProgramLocalParameter4fEXT) +#define glNamedProgramLocalParameter4fvEXT GLEW_GET_FUN(__glewNamedProgramLocalParameter4fvEXT) +#define glNamedProgramLocalParameterI4iEXT GLEW_GET_FUN(__glewNamedProgramLocalParameterI4iEXT) +#define glNamedProgramLocalParameterI4ivEXT GLEW_GET_FUN(__glewNamedProgramLocalParameterI4ivEXT) +#define glNamedProgramLocalParameterI4uiEXT GLEW_GET_FUN(__glewNamedProgramLocalParameterI4uiEXT) +#define glNamedProgramLocalParameterI4uivEXT GLEW_GET_FUN(__glewNamedProgramLocalParameterI4uivEXT) +#define glNamedProgramLocalParameters4fvEXT GLEW_GET_FUN(__glewNamedProgramLocalParameters4fvEXT) +#define glNamedProgramLocalParametersI4ivEXT GLEW_GET_FUN(__glewNamedProgramLocalParametersI4ivEXT) +#define glNamedProgramLocalParametersI4uivEXT GLEW_GET_FUN(__glewNamedProgramLocalParametersI4uivEXT) +#define glNamedProgramStringEXT GLEW_GET_FUN(__glewNamedProgramStringEXT) +#define glNamedRenderbufferStorageEXT GLEW_GET_FUN(__glewNamedRenderbufferStorageEXT) +#define glNamedRenderbufferStorageMultisampleCoverageEXT GLEW_GET_FUN(__glewNamedRenderbufferStorageMultisampleCoverageEXT) +#define glNamedRenderbufferStorageMultisampleEXT GLEW_GET_FUN(__glewNamedRenderbufferStorageMultisampleEXT) +#define glProgramUniform1fEXT GLEW_GET_FUN(__glewProgramUniform1fEXT) +#define glProgramUniform1fvEXT GLEW_GET_FUN(__glewProgramUniform1fvEXT) +#define glProgramUniform1iEXT GLEW_GET_FUN(__glewProgramUniform1iEXT) +#define glProgramUniform1ivEXT GLEW_GET_FUN(__glewProgramUniform1ivEXT) +#define glProgramUniform1uiEXT GLEW_GET_FUN(__glewProgramUniform1uiEXT) +#define glProgramUniform1uivEXT GLEW_GET_FUN(__glewProgramUniform1uivEXT) +#define glProgramUniform2fEXT GLEW_GET_FUN(__glewProgramUniform2fEXT) +#define glProgramUniform2fvEXT GLEW_GET_FUN(__glewProgramUniform2fvEXT) +#define glProgramUniform2iEXT GLEW_GET_FUN(__glewProgramUniform2iEXT) +#define glProgramUniform2ivEXT GLEW_GET_FUN(__glewProgramUniform2ivEXT) +#define glProgramUniform2uiEXT GLEW_GET_FUN(__glewProgramUniform2uiEXT) +#define glProgramUniform2uivEXT GLEW_GET_FUN(__glewProgramUniform2uivEXT) +#define glProgramUniform3fEXT GLEW_GET_FUN(__glewProgramUniform3fEXT) +#define glProgramUniform3fvEXT GLEW_GET_FUN(__glewProgramUniform3fvEXT) +#define glProgramUniform3iEXT GLEW_GET_FUN(__glewProgramUniform3iEXT) +#define glProgramUniform3ivEXT GLEW_GET_FUN(__glewProgramUniform3ivEXT) +#define glProgramUniform3uiEXT GLEW_GET_FUN(__glewProgramUniform3uiEXT) +#define glProgramUniform3uivEXT GLEW_GET_FUN(__glewProgramUniform3uivEXT) +#define glProgramUniform4fEXT GLEW_GET_FUN(__glewProgramUniform4fEXT) +#define glProgramUniform4fvEXT GLEW_GET_FUN(__glewProgramUniform4fvEXT) +#define glProgramUniform4iEXT GLEW_GET_FUN(__glewProgramUniform4iEXT) +#define glProgramUniform4ivEXT GLEW_GET_FUN(__glewProgramUniform4ivEXT) +#define glProgramUniform4uiEXT GLEW_GET_FUN(__glewProgramUniform4uiEXT) +#define glProgramUniform4uivEXT GLEW_GET_FUN(__glewProgramUniform4uivEXT) +#define glProgramUniformMatrix2fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix2fvEXT) +#define glProgramUniformMatrix2x3fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix2x3fvEXT) +#define glProgramUniformMatrix2x4fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix2x4fvEXT) +#define glProgramUniformMatrix3fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix3fvEXT) +#define glProgramUniformMatrix3x2fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix3x2fvEXT) +#define glProgramUniformMatrix3x4fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix3x4fvEXT) +#define glProgramUniformMatrix4fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix4fvEXT) +#define glProgramUniformMatrix4x2fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix4x2fvEXT) +#define glProgramUniformMatrix4x3fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix4x3fvEXT) +#define glPushClientAttribDefaultEXT GLEW_GET_FUN(__glewPushClientAttribDefaultEXT) +#define glTextureBufferEXT GLEW_GET_FUN(__glewTextureBufferEXT) +#define glTextureImage1DEXT GLEW_GET_FUN(__glewTextureImage1DEXT) +#define glTextureImage2DEXT GLEW_GET_FUN(__glewTextureImage2DEXT) +#define glTextureImage3DEXT GLEW_GET_FUN(__glewTextureImage3DEXT) +#define glTextureParameterIivEXT GLEW_GET_FUN(__glewTextureParameterIivEXT) +#define glTextureParameterIuivEXT GLEW_GET_FUN(__glewTextureParameterIuivEXT) +#define glTextureParameterfEXT GLEW_GET_FUN(__glewTextureParameterfEXT) +#define glTextureParameterfvEXT GLEW_GET_FUN(__glewTextureParameterfvEXT) +#define glTextureParameteriEXT GLEW_GET_FUN(__glewTextureParameteriEXT) +#define glTextureParameterivEXT GLEW_GET_FUN(__glewTextureParameterivEXT) +#define glTextureRenderbufferEXT GLEW_GET_FUN(__glewTextureRenderbufferEXT) +#define glTextureSubImage1DEXT GLEW_GET_FUN(__glewTextureSubImage1DEXT) +#define glTextureSubImage2DEXT GLEW_GET_FUN(__glewTextureSubImage2DEXT) +#define glTextureSubImage3DEXT GLEW_GET_FUN(__glewTextureSubImage3DEXT) +#define glUnmapNamedBufferEXT GLEW_GET_FUN(__glewUnmapNamedBufferEXT) + +#define GLEW_EXT_direct_state_access GLEW_GET_VAR(__GLEW_EXT_direct_state_access) + +#endif /* GL_EXT_direct_state_access */ + +/* -------------------------- GL_EXT_draw_buffers2 ------------------------- */ + +#ifndef GL_EXT_draw_buffers2 +#define GL_EXT_draw_buffers2 1 + +typedef void (GLAPIENTRY * PFNGLCOLORMASKINDEXEDEXTPROC) (GLuint buf, GLboolean r, GLboolean g, GLboolean b, GLboolean a); +typedef void (GLAPIENTRY * PFNGLDISABLEINDEXEDEXTPROC) (GLenum target, GLuint index); +typedef void (GLAPIENTRY * PFNGLENABLEINDEXEDEXTPROC) (GLenum target, GLuint index); +typedef void (GLAPIENTRY * PFNGLGETBOOLEANINDEXEDVEXTPROC) (GLenum value, GLuint index, GLboolean* data); +typedef void (GLAPIENTRY * PFNGLGETINTEGERINDEXEDVEXTPROC) (GLenum value, GLuint index, GLint* data); +typedef GLboolean (GLAPIENTRY * PFNGLISENABLEDINDEXEDEXTPROC) (GLenum target, GLuint index); + +#define glColorMaskIndexedEXT GLEW_GET_FUN(__glewColorMaskIndexedEXT) +#define glDisableIndexedEXT GLEW_GET_FUN(__glewDisableIndexedEXT) +#define glEnableIndexedEXT GLEW_GET_FUN(__glewEnableIndexedEXT) +#define glGetBooleanIndexedvEXT GLEW_GET_FUN(__glewGetBooleanIndexedvEXT) +#define glGetIntegerIndexedvEXT GLEW_GET_FUN(__glewGetIntegerIndexedvEXT) +#define glIsEnabledIndexedEXT GLEW_GET_FUN(__glewIsEnabledIndexedEXT) + +#define GLEW_EXT_draw_buffers2 GLEW_GET_VAR(__GLEW_EXT_draw_buffers2) + +#endif /* GL_EXT_draw_buffers2 */ + +/* ------------------------- GL_EXT_draw_instanced ------------------------- */ + +#ifndef GL_EXT_draw_instanced +#define GL_EXT_draw_instanced 1 + +typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINSTANCEDEXTPROC) (GLenum mode, GLint start, GLsizei count, GLsizei primcount); +typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDEXTPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount); + +#define glDrawArraysInstancedEXT GLEW_GET_FUN(__glewDrawArraysInstancedEXT) +#define glDrawElementsInstancedEXT GLEW_GET_FUN(__glewDrawElementsInstancedEXT) + +#define GLEW_EXT_draw_instanced GLEW_GET_VAR(__GLEW_EXT_draw_instanced) + +#endif /* GL_EXT_draw_instanced */ + +/* ----------------------- GL_EXT_draw_range_elements ---------------------- */ + +#ifndef GL_EXT_draw_range_elements +#define GL_EXT_draw_range_elements 1 + +#define GL_MAX_ELEMENTS_VERTICES 0x80E8 +#define GL_MAX_ELEMENTS_INDICES 0x80E9 + +typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTSEXTPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); + +#define glDrawRangeElementsEXT GLEW_GET_FUN(__glewDrawRangeElementsEXT) + +#define GLEW_EXT_draw_range_elements GLEW_GET_VAR(__GLEW_EXT_draw_range_elements) + +#endif /* GL_EXT_draw_range_elements */ + +/* ---------------------------- GL_EXT_fog_coord --------------------------- */ + +#ifndef GL_EXT_fog_coord +#define GL_EXT_fog_coord 1 + +#define GL_FOG_COORDINATE_SOURCE_EXT 0x8450 +#define GL_FOG_COORDINATE_EXT 0x8451 +#define GL_FRAGMENT_DEPTH_EXT 0x8452 +#define GL_CURRENT_FOG_COORDINATE_EXT 0x8453 +#define GL_FOG_COORDINATE_ARRAY_TYPE_EXT 0x8454 +#define GL_FOG_COORDINATE_ARRAY_STRIDE_EXT 0x8455 +#define GL_FOG_COORDINATE_ARRAY_POINTER_EXT 0x8456 +#define GL_FOG_COORDINATE_ARRAY_EXT 0x8457 + +typedef void (GLAPIENTRY * PFNGLFOGCOORDPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); +typedef void (GLAPIENTRY * PFNGLFOGCOORDDEXTPROC) (GLdouble coord); +typedef void (GLAPIENTRY * PFNGLFOGCOORDDVEXTPROC) (const GLdouble *coord); +typedef void (GLAPIENTRY * PFNGLFOGCOORDFEXTPROC) (GLfloat coord); +typedef void (GLAPIENTRY * PFNGLFOGCOORDFVEXTPROC) (const GLfloat *coord); + +#define glFogCoordPointerEXT GLEW_GET_FUN(__glewFogCoordPointerEXT) +#define glFogCoorddEXT GLEW_GET_FUN(__glewFogCoorddEXT) +#define glFogCoorddvEXT GLEW_GET_FUN(__glewFogCoorddvEXT) +#define glFogCoordfEXT GLEW_GET_FUN(__glewFogCoordfEXT) +#define glFogCoordfvEXT GLEW_GET_FUN(__glewFogCoordfvEXT) + +#define GLEW_EXT_fog_coord GLEW_GET_VAR(__GLEW_EXT_fog_coord) + +#endif /* GL_EXT_fog_coord */ + +/* ------------------------ GL_EXT_fragment_lighting ----------------------- */ + +#ifndef GL_EXT_fragment_lighting +#define GL_EXT_fragment_lighting 1 + +#define GL_FRAGMENT_LIGHTING_EXT 0x8400 +#define GL_FRAGMENT_COLOR_MATERIAL_EXT 0x8401 +#define GL_FRAGMENT_COLOR_MATERIAL_FACE_EXT 0x8402 +#define GL_FRAGMENT_COLOR_MATERIAL_PARAMETER_EXT 0x8403 +#define GL_MAX_FRAGMENT_LIGHTS_EXT 0x8404 +#define GL_MAX_ACTIVE_LIGHTS_EXT 0x8405 +#define GL_CURRENT_RASTER_NORMAL_EXT 0x8406 +#define GL_LIGHT_ENV_MODE_EXT 0x8407 +#define GL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_EXT 0x8408 +#define GL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_EXT 0x8409 +#define GL_FRAGMENT_LIGHT_MODEL_AMBIENT_EXT 0x840A +#define GL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_EXT 0x840B +#define GL_FRAGMENT_LIGHT0_EXT 0x840C +#define GL_FRAGMENT_LIGHT7_EXT 0x8413 + +typedef void (GLAPIENTRY * PFNGLFRAGMENTCOLORMATERIALEXTPROC) (GLenum face, GLenum mode); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELFEXTPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELFVEXTPROC) (GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELIEXTPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELIVEXTPROC) (GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTFEXTPROC) (GLenum light, GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTFVEXTPROC) (GLenum light, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTIEXTPROC) (GLenum light, GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTIVEXTPROC) (GLenum light, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALFEXTPROC) (GLenum face, GLenum pname, const GLfloat param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALFVEXTPROC) (GLenum face, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALIEXTPROC) (GLenum face, GLenum pname, const GLint param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALIVEXTPROC) (GLenum face, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLGETFRAGMENTLIGHTFVEXTPROC) (GLenum light, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETFRAGMENTLIGHTIVEXTPROC) (GLenum light, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETFRAGMENTMATERIALFVEXTPROC) (GLenum face, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETFRAGMENTMATERIALIVEXTPROC) (GLenum face, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLLIGHTENVIEXTPROC) (GLenum pname, GLint param); + +#define glFragmentColorMaterialEXT GLEW_GET_FUN(__glewFragmentColorMaterialEXT) +#define glFragmentLightModelfEXT GLEW_GET_FUN(__glewFragmentLightModelfEXT) +#define glFragmentLightModelfvEXT GLEW_GET_FUN(__glewFragmentLightModelfvEXT) +#define glFragmentLightModeliEXT GLEW_GET_FUN(__glewFragmentLightModeliEXT) +#define glFragmentLightModelivEXT GLEW_GET_FUN(__glewFragmentLightModelivEXT) +#define glFragmentLightfEXT GLEW_GET_FUN(__glewFragmentLightfEXT) +#define glFragmentLightfvEXT GLEW_GET_FUN(__glewFragmentLightfvEXT) +#define glFragmentLightiEXT GLEW_GET_FUN(__glewFragmentLightiEXT) +#define glFragmentLightivEXT GLEW_GET_FUN(__glewFragmentLightivEXT) +#define glFragmentMaterialfEXT GLEW_GET_FUN(__glewFragmentMaterialfEXT) +#define glFragmentMaterialfvEXT GLEW_GET_FUN(__glewFragmentMaterialfvEXT) +#define glFragmentMaterialiEXT GLEW_GET_FUN(__glewFragmentMaterialiEXT) +#define glFragmentMaterialivEXT GLEW_GET_FUN(__glewFragmentMaterialivEXT) +#define glGetFragmentLightfvEXT GLEW_GET_FUN(__glewGetFragmentLightfvEXT) +#define glGetFragmentLightivEXT GLEW_GET_FUN(__glewGetFragmentLightivEXT) +#define glGetFragmentMaterialfvEXT GLEW_GET_FUN(__glewGetFragmentMaterialfvEXT) +#define glGetFragmentMaterialivEXT GLEW_GET_FUN(__glewGetFragmentMaterialivEXT) +#define glLightEnviEXT GLEW_GET_FUN(__glewLightEnviEXT) + +#define GLEW_EXT_fragment_lighting GLEW_GET_VAR(__GLEW_EXT_fragment_lighting) + +#endif /* GL_EXT_fragment_lighting */ + +/* ------------------------ GL_EXT_framebuffer_blit ------------------------ */ + +#ifndef GL_EXT_framebuffer_blit +#define GL_EXT_framebuffer_blit 1 + +#define GL_DRAW_FRAMEBUFFER_BINDING_EXT 0x8CA6 +#define GL_READ_FRAMEBUFFER_EXT 0x8CA8 +#define GL_DRAW_FRAMEBUFFER_EXT 0x8CA9 +#define GL_READ_FRAMEBUFFER_BINDING_EXT 0x8CAA + +typedef void (GLAPIENTRY * PFNGLBLITFRAMEBUFFEREXTPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); + +#define glBlitFramebufferEXT GLEW_GET_FUN(__glewBlitFramebufferEXT) + +#define GLEW_EXT_framebuffer_blit GLEW_GET_VAR(__GLEW_EXT_framebuffer_blit) + +#endif /* GL_EXT_framebuffer_blit */ + +/* --------------------- GL_EXT_framebuffer_multisample -------------------- */ + +#ifndef GL_EXT_framebuffer_multisample +#define GL_EXT_framebuffer_multisample 1 + +#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56 +#define GL_MAX_SAMPLES_EXT 0x8D57 + +typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); + +#define glRenderbufferStorageMultisampleEXT GLEW_GET_FUN(__glewRenderbufferStorageMultisampleEXT) + +#define GLEW_EXT_framebuffer_multisample GLEW_GET_VAR(__GLEW_EXT_framebuffer_multisample) + +#endif /* GL_EXT_framebuffer_multisample */ + +/* ----------------------- GL_EXT_framebuffer_object ----------------------- */ + +#ifndef GL_EXT_framebuffer_object +#define GL_EXT_framebuffer_object 1 + +#define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506 +#define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8 +#define GL_FRAMEBUFFER_BINDING_EXT 0x8CA6 +#define GL_RENDERBUFFER_BINDING_EXT 0x8CA7 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4 +#define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9 +#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA +#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB +#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC +#define GL_FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD +#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF +#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0 +#define GL_COLOR_ATTACHMENT1_EXT 0x8CE1 +#define GL_COLOR_ATTACHMENT2_EXT 0x8CE2 +#define GL_COLOR_ATTACHMENT3_EXT 0x8CE3 +#define GL_COLOR_ATTACHMENT4_EXT 0x8CE4 +#define GL_COLOR_ATTACHMENT5_EXT 0x8CE5 +#define GL_COLOR_ATTACHMENT6_EXT 0x8CE6 +#define GL_COLOR_ATTACHMENT7_EXT 0x8CE7 +#define GL_COLOR_ATTACHMENT8_EXT 0x8CE8 +#define GL_COLOR_ATTACHMENT9_EXT 0x8CE9 +#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA +#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB +#define GL_COLOR_ATTACHMENT12_EXT 0x8CEC +#define GL_COLOR_ATTACHMENT13_EXT 0x8CED +#define GL_COLOR_ATTACHMENT14_EXT 0x8CEE +#define GL_COLOR_ATTACHMENT15_EXT 0x8CEF +#define GL_DEPTH_ATTACHMENT_EXT 0x8D00 +#define GL_STENCIL_ATTACHMENT_EXT 0x8D20 +#define GL_FRAMEBUFFER_EXT 0x8D40 +#define GL_RENDERBUFFER_EXT 0x8D41 +#define GL_RENDERBUFFER_WIDTH_EXT 0x8D42 +#define GL_RENDERBUFFER_HEIGHT_EXT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44 +#define GL_STENCIL_INDEX1_EXT 0x8D46 +#define GL_STENCIL_INDEX4_EXT 0x8D47 +#define GL_STENCIL_INDEX8_EXT 0x8D48 +#define GL_STENCIL_INDEX16_EXT 0x8D49 +#define GL_RENDERBUFFER_RED_SIZE_EXT 0x8D50 +#define GL_RENDERBUFFER_GREEN_SIZE_EXT 0x8D51 +#define GL_RENDERBUFFER_BLUE_SIZE_EXT 0x8D52 +#define GL_RENDERBUFFER_ALPHA_SIZE_EXT 0x8D53 +#define GL_RENDERBUFFER_DEPTH_SIZE_EXT 0x8D54 +#define GL_RENDERBUFFER_STENCIL_SIZE_EXT 0x8D55 + +typedef void (GLAPIENTRY * PFNGLBINDFRAMEBUFFEREXTPROC) (GLenum target, GLuint framebuffer); +typedef void (GLAPIENTRY * PFNGLBINDRENDERBUFFEREXTPROC) (GLenum target, GLuint renderbuffer); +typedef GLenum (GLAPIENTRY * PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLDELETEFRAMEBUFFERSEXTPROC) (GLsizei n, const GLuint* framebuffers); +typedef void (GLAPIENTRY * PFNGLDELETERENDERBUFFERSEXTPROC) (GLsizei n, const GLuint* renderbuffers); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE1DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE3DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +typedef void (GLAPIENTRY * PFNGLGENFRAMEBUFFERSEXTPROC) (GLsizei n, GLuint* framebuffers); +typedef void (GLAPIENTRY * PFNGLGENRENDERBUFFERSEXTPROC) (GLsizei n, GLuint* renderbuffers); +typedef void (GLAPIENTRY * PFNGLGENERATEMIPMAPEXTPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLenum target, GLenum attachment, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISFRAMEBUFFEREXTPROC) (GLuint framebuffer); +typedef GLboolean (GLAPIENTRY * PFNGLISRENDERBUFFEREXTPROC) (GLuint renderbuffer); +typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); + +#define glBindFramebufferEXT GLEW_GET_FUN(__glewBindFramebufferEXT) +#define glBindRenderbufferEXT GLEW_GET_FUN(__glewBindRenderbufferEXT) +#define glCheckFramebufferStatusEXT GLEW_GET_FUN(__glewCheckFramebufferStatusEXT) +#define glDeleteFramebuffersEXT GLEW_GET_FUN(__glewDeleteFramebuffersEXT) +#define glDeleteRenderbuffersEXT GLEW_GET_FUN(__glewDeleteRenderbuffersEXT) +#define glFramebufferRenderbufferEXT GLEW_GET_FUN(__glewFramebufferRenderbufferEXT) +#define glFramebufferTexture1DEXT GLEW_GET_FUN(__glewFramebufferTexture1DEXT) +#define glFramebufferTexture2DEXT GLEW_GET_FUN(__glewFramebufferTexture2DEXT) +#define glFramebufferTexture3DEXT GLEW_GET_FUN(__glewFramebufferTexture3DEXT) +#define glGenFramebuffersEXT GLEW_GET_FUN(__glewGenFramebuffersEXT) +#define glGenRenderbuffersEXT GLEW_GET_FUN(__glewGenRenderbuffersEXT) +#define glGenerateMipmapEXT GLEW_GET_FUN(__glewGenerateMipmapEXT) +#define glGetFramebufferAttachmentParameterivEXT GLEW_GET_FUN(__glewGetFramebufferAttachmentParameterivEXT) +#define glGetRenderbufferParameterivEXT GLEW_GET_FUN(__glewGetRenderbufferParameterivEXT) +#define glIsFramebufferEXT GLEW_GET_FUN(__glewIsFramebufferEXT) +#define glIsRenderbufferEXT GLEW_GET_FUN(__glewIsRenderbufferEXT) +#define glRenderbufferStorageEXT GLEW_GET_FUN(__glewRenderbufferStorageEXT) + +#define GLEW_EXT_framebuffer_object GLEW_GET_VAR(__GLEW_EXT_framebuffer_object) + +#endif /* GL_EXT_framebuffer_object */ + +/* ------------------------ GL_EXT_framebuffer_sRGB ------------------------ */ + +#ifndef GL_EXT_framebuffer_sRGB +#define GL_EXT_framebuffer_sRGB 1 + +#define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9 +#define GL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x8DBA + +#define GLEW_EXT_framebuffer_sRGB GLEW_GET_VAR(__GLEW_EXT_framebuffer_sRGB) + +#endif /* GL_EXT_framebuffer_sRGB */ + +/* ------------------------ GL_EXT_geometry_shader4 ------------------------ */ + +#ifndef GL_EXT_geometry_shader4 +#define GL_EXT_geometry_shader4 1 + +#define GL_LINES_ADJACENCY_EXT 0xA +#define GL_LINE_STRIP_ADJACENCY_EXT 0xB +#define GL_TRIANGLES_ADJACENCY_EXT 0xC +#define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0xD +#define GL_PROGRAM_POINT_SIZE_EXT 0x8642 +#define GL_MAX_VARYING_COMPONENTS_EXT 0x8B4B +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT 0x8DA9 +#define GL_GEOMETRY_SHADER_EXT 0x8DD9 +#define GL_GEOMETRY_VERTICES_OUT_EXT 0x8DDA +#define GL_GEOMETRY_INPUT_TYPE_EXT 0x8DDB +#define GL_GEOMETRY_OUTPUT_TYPE_EXT 0x8DDC +#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_EXT 0x8DDD +#define GL_MAX_VERTEX_VARYING_COMPONENTS_EXT 0x8DDE +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8DDF +#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT 0x8DE0 +#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT 0x8DE1 + +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETERIEXTPROC) (GLuint program, GLenum pname, GLint value); + +#define glFramebufferTextureEXT GLEW_GET_FUN(__glewFramebufferTextureEXT) +#define glFramebufferTextureFaceEXT GLEW_GET_FUN(__glewFramebufferTextureFaceEXT) +#define glFramebufferTextureLayerEXT GLEW_GET_FUN(__glewFramebufferTextureLayerEXT) +#define glProgramParameteriEXT GLEW_GET_FUN(__glewProgramParameteriEXT) + +#define GLEW_EXT_geometry_shader4 GLEW_GET_VAR(__GLEW_EXT_geometry_shader4) + +#endif /* GL_EXT_geometry_shader4 */ + +/* --------------------- GL_EXT_gpu_program_parameters --------------------- */ + +#ifndef GL_EXT_gpu_program_parameters +#define GL_EXT_gpu_program_parameters 1 + +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERS4FVEXTPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat* params); + +#define glProgramEnvParameters4fvEXT GLEW_GET_FUN(__glewProgramEnvParameters4fvEXT) +#define glProgramLocalParameters4fvEXT GLEW_GET_FUN(__glewProgramLocalParameters4fvEXT) + +#define GLEW_EXT_gpu_program_parameters GLEW_GET_VAR(__GLEW_EXT_gpu_program_parameters) + +#endif /* GL_EXT_gpu_program_parameters */ + +/* --------------------------- GL_EXT_gpu_shader4 -------------------------- */ + +#ifndef GL_EXT_gpu_shader4 +#define GL_EXT_gpu_shader4 1 + +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER_EXT 0x88FD +#define GL_SAMPLER_1D_ARRAY_EXT 0x8DC0 +#define GL_SAMPLER_2D_ARRAY_EXT 0x8DC1 +#define GL_SAMPLER_BUFFER_EXT 0x8DC2 +#define GL_SAMPLER_1D_ARRAY_SHADOW_EXT 0x8DC3 +#define GL_SAMPLER_2D_ARRAY_SHADOW_EXT 0x8DC4 +#define GL_SAMPLER_CUBE_SHADOW_EXT 0x8DC5 +#define GL_UNSIGNED_INT_VEC2_EXT 0x8DC6 +#define GL_UNSIGNED_INT_VEC3_EXT 0x8DC7 +#define GL_UNSIGNED_INT_VEC4_EXT 0x8DC8 +#define GL_INT_SAMPLER_1D_EXT 0x8DC9 +#define GL_INT_SAMPLER_2D_EXT 0x8DCA +#define GL_INT_SAMPLER_3D_EXT 0x8DCB +#define GL_INT_SAMPLER_CUBE_EXT 0x8DCC +#define GL_INT_SAMPLER_2D_RECT_EXT 0x8DCD +#define GL_INT_SAMPLER_1D_ARRAY_EXT 0x8DCE +#define GL_INT_SAMPLER_2D_ARRAY_EXT 0x8DCF +#define GL_INT_SAMPLER_BUFFER_EXT 0x8DD0 +#define GL_UNSIGNED_INT_SAMPLER_1D_EXT 0x8DD1 +#define GL_UNSIGNED_INT_SAMPLER_2D_EXT 0x8DD2 +#define GL_UNSIGNED_INT_SAMPLER_3D_EXT 0x8DD3 +#define GL_UNSIGNED_INT_SAMPLER_CUBE_EXT 0x8DD4 +#define GL_UNSIGNED_INT_SAMPLER_2D_RECT_EXT 0x8DD5 +#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY_EXT 0x8DD6 +#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY_EXT 0x8DD7 +#define GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT 0x8DD8 + +typedef void (GLAPIENTRY * PFNGLBINDFRAGDATALOCATIONEXTPROC) (GLuint program, GLuint color, const GLchar *name); +typedef GLint (GLAPIENTRY * PFNGLGETFRAGDATALOCATIONEXTPROC) (GLuint program, const GLchar *name); +typedef void (GLAPIENTRY * PFNGLGETUNIFORMUIVEXTPROC) (GLuint program, GLint location, GLuint *params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIIVEXTPROC) (GLuint index, GLenum pname, GLint *params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIUIVEXTPROC) (GLuint index, GLenum pname, GLuint *params); +typedef void (GLAPIENTRY * PFNGLUNIFORM1UIEXTPROC) (GLint location, GLuint v0); +typedef void (GLAPIENTRY * PFNGLUNIFORM1UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (GLAPIENTRY * PFNGLUNIFORM2UIEXTPROC) (GLint location, GLuint v0, GLuint v1); +typedef void (GLAPIENTRY * PFNGLUNIFORM2UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (GLAPIENTRY * PFNGLUNIFORM3UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2); +typedef void (GLAPIENTRY * PFNGLUNIFORM3UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (GLAPIENTRY * PFNGLUNIFORM4UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +typedef void (GLAPIENTRY * PFNGLUNIFORM4UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1IEXTPROC) (GLuint index, GLint x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1IVEXTPROC) (GLuint index, const GLint *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1UIEXTPROC) (GLuint index, GLuint x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1UIVEXTPROC) (GLuint index, const GLuint *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2IEXTPROC) (GLuint index, GLint x, GLint y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2IVEXTPROC) (GLuint index, const GLint *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2UIEXTPROC) (GLuint index, GLuint x, GLuint y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2UIVEXTPROC) (GLuint index, const GLuint *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3IEXTPROC) (GLuint index, GLint x, GLint y, GLint z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3IVEXTPROC) (GLuint index, const GLint *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3UIVEXTPROC) (GLuint index, const GLuint *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4BVEXTPROC) (GLuint index, const GLbyte *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4IEXTPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4IVEXTPROC) (GLuint index, const GLint *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4SVEXTPROC) (GLuint index, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UBVEXTPROC) (GLuint index, const GLubyte *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UIVEXTPROC) (GLuint index, const GLuint *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4USVEXTPROC) (GLuint index, const GLushort *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBIPOINTEREXTPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); + +#define glBindFragDataLocationEXT GLEW_GET_FUN(__glewBindFragDataLocationEXT) +#define glGetFragDataLocationEXT GLEW_GET_FUN(__glewGetFragDataLocationEXT) +#define glGetUniformuivEXT GLEW_GET_FUN(__glewGetUniformuivEXT) +#define glGetVertexAttribIivEXT GLEW_GET_FUN(__glewGetVertexAttribIivEXT) +#define glGetVertexAttribIuivEXT GLEW_GET_FUN(__glewGetVertexAttribIuivEXT) +#define glUniform1uiEXT GLEW_GET_FUN(__glewUniform1uiEXT) +#define glUniform1uivEXT GLEW_GET_FUN(__glewUniform1uivEXT) +#define glUniform2uiEXT GLEW_GET_FUN(__glewUniform2uiEXT) +#define glUniform2uivEXT GLEW_GET_FUN(__glewUniform2uivEXT) +#define glUniform3uiEXT GLEW_GET_FUN(__glewUniform3uiEXT) +#define glUniform3uivEXT GLEW_GET_FUN(__glewUniform3uivEXT) +#define glUniform4uiEXT GLEW_GET_FUN(__glewUniform4uiEXT) +#define glUniform4uivEXT GLEW_GET_FUN(__glewUniform4uivEXT) +#define glVertexAttribI1iEXT GLEW_GET_FUN(__glewVertexAttribI1iEXT) +#define glVertexAttribI1ivEXT GLEW_GET_FUN(__glewVertexAttribI1ivEXT) +#define glVertexAttribI1uiEXT GLEW_GET_FUN(__glewVertexAttribI1uiEXT) +#define glVertexAttribI1uivEXT GLEW_GET_FUN(__glewVertexAttribI1uivEXT) +#define glVertexAttribI2iEXT GLEW_GET_FUN(__glewVertexAttribI2iEXT) +#define glVertexAttribI2ivEXT GLEW_GET_FUN(__glewVertexAttribI2ivEXT) +#define glVertexAttribI2uiEXT GLEW_GET_FUN(__glewVertexAttribI2uiEXT) +#define glVertexAttribI2uivEXT GLEW_GET_FUN(__glewVertexAttribI2uivEXT) +#define glVertexAttribI3iEXT GLEW_GET_FUN(__glewVertexAttribI3iEXT) +#define glVertexAttribI3ivEXT GLEW_GET_FUN(__glewVertexAttribI3ivEXT) +#define glVertexAttribI3uiEXT GLEW_GET_FUN(__glewVertexAttribI3uiEXT) +#define glVertexAttribI3uivEXT GLEW_GET_FUN(__glewVertexAttribI3uivEXT) +#define glVertexAttribI4bvEXT GLEW_GET_FUN(__glewVertexAttribI4bvEXT) +#define glVertexAttribI4iEXT GLEW_GET_FUN(__glewVertexAttribI4iEXT) +#define glVertexAttribI4ivEXT GLEW_GET_FUN(__glewVertexAttribI4ivEXT) +#define glVertexAttribI4svEXT GLEW_GET_FUN(__glewVertexAttribI4svEXT) +#define glVertexAttribI4ubvEXT GLEW_GET_FUN(__glewVertexAttribI4ubvEXT) +#define glVertexAttribI4uiEXT GLEW_GET_FUN(__glewVertexAttribI4uiEXT) +#define glVertexAttribI4uivEXT GLEW_GET_FUN(__glewVertexAttribI4uivEXT) +#define glVertexAttribI4usvEXT GLEW_GET_FUN(__glewVertexAttribI4usvEXT) +#define glVertexAttribIPointerEXT GLEW_GET_FUN(__glewVertexAttribIPointerEXT) + +#define GLEW_EXT_gpu_shader4 GLEW_GET_VAR(__GLEW_EXT_gpu_shader4) + +#endif /* GL_EXT_gpu_shader4 */ + +/* ---------------------------- GL_EXT_histogram --------------------------- */ + +#ifndef GL_EXT_histogram +#define GL_EXT_histogram 1 + +#define GL_HISTOGRAM_EXT 0x8024 +#define GL_PROXY_HISTOGRAM_EXT 0x8025 +#define GL_HISTOGRAM_WIDTH_EXT 0x8026 +#define GL_HISTOGRAM_FORMAT_EXT 0x8027 +#define GL_HISTOGRAM_RED_SIZE_EXT 0x8028 +#define GL_HISTOGRAM_GREEN_SIZE_EXT 0x8029 +#define GL_HISTOGRAM_BLUE_SIZE_EXT 0x802A +#define GL_HISTOGRAM_ALPHA_SIZE_EXT 0x802B +#define GL_HISTOGRAM_LUMINANCE_SIZE_EXT 0x802C +#define GL_HISTOGRAM_SINK_EXT 0x802D +#define GL_MINMAX_EXT 0x802E +#define GL_MINMAX_FORMAT_EXT 0x802F +#define GL_MINMAX_SINK_EXT 0x8030 + +typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, void* values); +typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETMINMAXEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, void* values); +typedef void (GLAPIENTRY * PFNGLGETMINMAXPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETMINMAXPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLHISTOGRAMEXTPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); +typedef void (GLAPIENTRY * PFNGLMINMAXEXTPROC) (GLenum target, GLenum internalformat, GLboolean sink); +typedef void (GLAPIENTRY * PFNGLRESETHISTOGRAMEXTPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLRESETMINMAXEXTPROC) (GLenum target); + +#define glGetHistogramEXT GLEW_GET_FUN(__glewGetHistogramEXT) +#define glGetHistogramParameterfvEXT GLEW_GET_FUN(__glewGetHistogramParameterfvEXT) +#define glGetHistogramParameterivEXT GLEW_GET_FUN(__glewGetHistogramParameterivEXT) +#define glGetMinmaxEXT GLEW_GET_FUN(__glewGetMinmaxEXT) +#define glGetMinmaxParameterfvEXT GLEW_GET_FUN(__glewGetMinmaxParameterfvEXT) +#define glGetMinmaxParameterivEXT GLEW_GET_FUN(__glewGetMinmaxParameterivEXT) +#define glHistogramEXT GLEW_GET_FUN(__glewHistogramEXT) +#define glMinmaxEXT GLEW_GET_FUN(__glewMinmaxEXT) +#define glResetHistogramEXT GLEW_GET_FUN(__glewResetHistogramEXT) +#define glResetMinmaxEXT GLEW_GET_FUN(__glewResetMinmaxEXT) + +#define GLEW_EXT_histogram GLEW_GET_VAR(__GLEW_EXT_histogram) + +#endif /* GL_EXT_histogram */ + +/* ----------------------- GL_EXT_index_array_formats ---------------------- */ + +#ifndef GL_EXT_index_array_formats +#define GL_EXT_index_array_formats 1 + +#define GLEW_EXT_index_array_formats GLEW_GET_VAR(__GLEW_EXT_index_array_formats) + +#endif /* GL_EXT_index_array_formats */ + +/* --------------------------- GL_EXT_index_func --------------------------- */ + +#ifndef GL_EXT_index_func +#define GL_EXT_index_func 1 + +typedef void (GLAPIENTRY * PFNGLINDEXFUNCEXTPROC) (GLenum func, GLfloat ref); + +#define glIndexFuncEXT GLEW_GET_FUN(__glewIndexFuncEXT) + +#define GLEW_EXT_index_func GLEW_GET_VAR(__GLEW_EXT_index_func) + +#endif /* GL_EXT_index_func */ + +/* ------------------------- GL_EXT_index_material ------------------------- */ + +#ifndef GL_EXT_index_material +#define GL_EXT_index_material 1 + +typedef void (GLAPIENTRY * PFNGLINDEXMATERIALEXTPROC) (GLenum face, GLenum mode); + +#define glIndexMaterialEXT GLEW_GET_FUN(__glewIndexMaterialEXT) + +#define GLEW_EXT_index_material GLEW_GET_VAR(__GLEW_EXT_index_material) + +#endif /* GL_EXT_index_material */ + +/* -------------------------- GL_EXT_index_texture ------------------------- */ + +#ifndef GL_EXT_index_texture +#define GL_EXT_index_texture 1 + +#define GLEW_EXT_index_texture GLEW_GET_VAR(__GLEW_EXT_index_texture) + +#endif /* GL_EXT_index_texture */ + +/* -------------------------- GL_EXT_light_texture ------------------------- */ + +#ifndef GL_EXT_light_texture +#define GL_EXT_light_texture 1 + +#define GL_FRAGMENT_MATERIAL_EXT 0x8349 +#define GL_FRAGMENT_NORMAL_EXT 0x834A +#define GL_FRAGMENT_COLOR_EXT 0x834C +#define GL_ATTENUATION_EXT 0x834D +#define GL_SHADOW_ATTENUATION_EXT 0x834E +#define GL_TEXTURE_APPLICATION_MODE_EXT 0x834F +#define GL_TEXTURE_LIGHT_EXT 0x8350 +#define GL_TEXTURE_MATERIAL_FACE_EXT 0x8351 +#define GL_TEXTURE_MATERIAL_PARAMETER_EXT 0x8352 +#define GL_FRAGMENT_DEPTH_EXT 0x8452 + +typedef void (GLAPIENTRY * PFNGLAPPLYTEXTUREEXTPROC) (GLenum mode); +typedef void (GLAPIENTRY * PFNGLTEXTURELIGHTEXTPROC) (GLenum pname); +typedef void (GLAPIENTRY * PFNGLTEXTUREMATERIALEXTPROC) (GLenum face, GLenum mode); + +#define glApplyTextureEXT GLEW_GET_FUN(__glewApplyTextureEXT) +#define glTextureLightEXT GLEW_GET_FUN(__glewTextureLightEXT) +#define glTextureMaterialEXT GLEW_GET_FUN(__glewTextureMaterialEXT) + +#define GLEW_EXT_light_texture GLEW_GET_VAR(__GLEW_EXT_light_texture) + +#endif /* GL_EXT_light_texture */ + +/* ------------------------- GL_EXT_misc_attribute ------------------------- */ + +#ifndef GL_EXT_misc_attribute +#define GL_EXT_misc_attribute 1 + +#define GLEW_EXT_misc_attribute GLEW_GET_VAR(__GLEW_EXT_misc_attribute) + +#endif /* GL_EXT_misc_attribute */ + +/* ------------------------ GL_EXT_multi_draw_arrays ----------------------- */ + +#ifndef GL_EXT_multi_draw_arrays +#define GL_EXT_multi_draw_arrays 1 + +typedef void (GLAPIENTRY * PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, GLint* first, GLsizei *count, GLsizei primcount); +typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, GLsizei* count, GLenum type, const GLvoid **indices, GLsizei primcount); + +#define glMultiDrawArraysEXT GLEW_GET_FUN(__glewMultiDrawArraysEXT) +#define glMultiDrawElementsEXT GLEW_GET_FUN(__glewMultiDrawElementsEXT) + +#define GLEW_EXT_multi_draw_arrays GLEW_GET_VAR(__GLEW_EXT_multi_draw_arrays) + +#endif /* GL_EXT_multi_draw_arrays */ + +/* --------------------------- GL_EXT_multisample -------------------------- */ + +#ifndef GL_EXT_multisample +#define GL_EXT_multisample 1 + +#define GL_MULTISAMPLE_EXT 0x809D +#define GL_SAMPLE_ALPHA_TO_MASK_EXT 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_EXT 0x809F +#define GL_SAMPLE_MASK_EXT 0x80A0 +#define GL_1PASS_EXT 0x80A1 +#define GL_2PASS_0_EXT 0x80A2 +#define GL_2PASS_1_EXT 0x80A3 +#define GL_4PASS_0_EXT 0x80A4 +#define GL_4PASS_1_EXT 0x80A5 +#define GL_4PASS_2_EXT 0x80A6 +#define GL_4PASS_3_EXT 0x80A7 +#define GL_SAMPLE_BUFFERS_EXT 0x80A8 +#define GL_SAMPLES_EXT 0x80A9 +#define GL_SAMPLE_MASK_VALUE_EXT 0x80AA +#define GL_SAMPLE_MASK_INVERT_EXT 0x80AB +#define GL_SAMPLE_PATTERN_EXT 0x80AC +#define GL_MULTISAMPLE_BIT_EXT 0x20000000 + +typedef void (GLAPIENTRY * PFNGLSAMPLEMASKEXTPROC) (GLclampf value, GLboolean invert); +typedef void (GLAPIENTRY * PFNGLSAMPLEPATTERNEXTPROC) (GLenum pattern); + +#define glSampleMaskEXT GLEW_GET_FUN(__glewSampleMaskEXT) +#define glSamplePatternEXT GLEW_GET_FUN(__glewSamplePatternEXT) + +#define GLEW_EXT_multisample GLEW_GET_VAR(__GLEW_EXT_multisample) + +#endif /* GL_EXT_multisample */ + +/* ---------------------- GL_EXT_packed_depth_stencil ---------------------- */ + +#ifndef GL_EXT_packed_depth_stencil +#define GL_EXT_packed_depth_stencil 1 + +#define GL_DEPTH_STENCIL_EXT 0x84F9 +#define GL_UNSIGNED_INT_24_8_EXT 0x84FA +#define GL_DEPTH24_STENCIL8_EXT 0x88F0 +#define GL_TEXTURE_STENCIL_SIZE_EXT 0x88F1 + +#define GLEW_EXT_packed_depth_stencil GLEW_GET_VAR(__GLEW_EXT_packed_depth_stencil) + +#endif /* GL_EXT_packed_depth_stencil */ + +/* -------------------------- GL_EXT_packed_float -------------------------- */ + +#ifndef GL_EXT_packed_float +#define GL_EXT_packed_float 1 + +#define GL_R11F_G11F_B10F_EXT 0x8C3A +#define GL_UNSIGNED_INT_10F_11F_11F_REV_EXT 0x8C3B +#define GL_RGBA_SIGNED_COMPONENTS_EXT 0x8C3C + +#define GLEW_EXT_packed_float GLEW_GET_VAR(__GLEW_EXT_packed_float) + +#endif /* GL_EXT_packed_float */ + +/* -------------------------- GL_EXT_packed_pixels ------------------------- */ + +#ifndef GL_EXT_packed_pixels +#define GL_EXT_packed_pixels 1 + +#define GL_UNSIGNED_BYTE_3_3_2_EXT 0x8032 +#define GL_UNSIGNED_SHORT_4_4_4_4_EXT 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1_EXT 0x8034 +#define GL_UNSIGNED_INT_8_8_8_8_EXT 0x8035 +#define GL_UNSIGNED_INT_10_10_10_2_EXT 0x8036 + +#define GLEW_EXT_packed_pixels GLEW_GET_VAR(__GLEW_EXT_packed_pixels) + +#endif /* GL_EXT_packed_pixels */ + +/* ------------------------ GL_EXT_paletted_texture ------------------------ */ + +#ifndef GL_EXT_paletted_texture +#define GL_EXT_paletted_texture 1 + +#define GL_TEXTURE_1D 0x0DE0 +#define GL_TEXTURE_2D 0x0DE1 +#define GL_PROXY_TEXTURE_1D 0x8063 +#define GL_PROXY_TEXTURE_2D 0x8064 +#define GL_TEXTURE_3D_EXT 0x806F +#define GL_PROXY_TEXTURE_3D_EXT 0x8070 +#define GL_COLOR_TABLE_FORMAT_EXT 0x80D8 +#define GL_COLOR_TABLE_WIDTH_EXT 0x80D9 +#define GL_COLOR_TABLE_RED_SIZE_EXT 0x80DA +#define GL_COLOR_TABLE_GREEN_SIZE_EXT 0x80DB +#define GL_COLOR_TABLE_BLUE_SIZE_EXT 0x80DC +#define GL_COLOR_TABLE_ALPHA_SIZE_EXT 0x80DD +#define GL_COLOR_TABLE_LUMINANCE_SIZE_EXT 0x80DE +#define GL_COLOR_TABLE_INTENSITY_SIZE_EXT 0x80DF +#define GL_COLOR_INDEX1_EXT 0x80E2 +#define GL_COLOR_INDEX2_EXT 0x80E3 +#define GL_COLOR_INDEX4_EXT 0x80E4 +#define GL_COLOR_INDEX8_EXT 0x80E5 +#define GL_COLOR_INDEX12_EXT 0x80E6 +#define GL_COLOR_INDEX16_EXT 0x80E7 +#define GL_TEXTURE_INDEX_SIZE_EXT 0x80ED +#define GL_TEXTURE_CUBE_MAP_ARB 0x8513 +#define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B + +typedef void (GLAPIENTRY * PFNGLCOLORTABLEEXTPROC) (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const void* data); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEEXTPROC) (GLenum target, GLenum format, GLenum type, void* data); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint* params); + +#define glColorTableEXT GLEW_GET_FUN(__glewColorTableEXT) +#define glGetColorTableEXT GLEW_GET_FUN(__glewGetColorTableEXT) +#define glGetColorTableParameterfvEXT GLEW_GET_FUN(__glewGetColorTableParameterfvEXT) +#define glGetColorTableParameterivEXT GLEW_GET_FUN(__glewGetColorTableParameterivEXT) + +#define GLEW_EXT_paletted_texture GLEW_GET_VAR(__GLEW_EXT_paletted_texture) + +#endif /* GL_EXT_paletted_texture */ + +/* ----------------------- GL_EXT_pixel_buffer_object ---------------------- */ + +#ifndef GL_EXT_pixel_buffer_object +#define GL_EXT_pixel_buffer_object 1 + +#define GL_PIXEL_PACK_BUFFER_EXT 0x88EB +#define GL_PIXEL_UNPACK_BUFFER_EXT 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING_EXT 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING_EXT 0x88EF + +#define GLEW_EXT_pixel_buffer_object GLEW_GET_VAR(__GLEW_EXT_pixel_buffer_object) + +#endif /* GL_EXT_pixel_buffer_object */ + +/* ------------------------- GL_EXT_pixel_transform ------------------------ */ + +#ifndef GL_EXT_pixel_transform +#define GL_EXT_pixel_transform 1 + +#define GL_PIXEL_TRANSFORM_2D_EXT 0x8330 +#define GL_PIXEL_MAG_FILTER_EXT 0x8331 +#define GL_PIXEL_MIN_FILTER_EXT 0x8332 +#define GL_PIXEL_CUBIC_WEIGHT_EXT 0x8333 +#define GL_CUBIC_EXT 0x8334 +#define GL_AVERAGE_EXT 0x8335 +#define GL_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8336 +#define GL_MAX_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8337 +#define GL_PIXEL_TRANSFORM_2D_MATRIX_EXT 0x8338 + +typedef void (GLAPIENTRY * PFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLPIXELTRANSFORMPARAMETERFEXTPROC) (GLenum target, GLenum pname, const GLfloat param); +typedef void (GLAPIENTRY * PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLPIXELTRANSFORMPARAMETERIEXTPROC) (GLenum target, GLenum pname, const GLint param); +typedef void (GLAPIENTRY * PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint* params); + +#define glGetPixelTransformParameterfvEXT GLEW_GET_FUN(__glewGetPixelTransformParameterfvEXT) +#define glGetPixelTransformParameterivEXT GLEW_GET_FUN(__glewGetPixelTransformParameterivEXT) +#define glPixelTransformParameterfEXT GLEW_GET_FUN(__glewPixelTransformParameterfEXT) +#define glPixelTransformParameterfvEXT GLEW_GET_FUN(__glewPixelTransformParameterfvEXT) +#define glPixelTransformParameteriEXT GLEW_GET_FUN(__glewPixelTransformParameteriEXT) +#define glPixelTransformParameterivEXT GLEW_GET_FUN(__glewPixelTransformParameterivEXT) + +#define GLEW_EXT_pixel_transform GLEW_GET_VAR(__GLEW_EXT_pixel_transform) + +#endif /* GL_EXT_pixel_transform */ + +/* ------------------- GL_EXT_pixel_transform_color_table ------------------ */ + +#ifndef GL_EXT_pixel_transform_color_table +#define GL_EXT_pixel_transform_color_table 1 + +#define GLEW_EXT_pixel_transform_color_table GLEW_GET_VAR(__GLEW_EXT_pixel_transform_color_table) + +#endif /* GL_EXT_pixel_transform_color_table */ + +/* ------------------------ GL_EXT_point_parameters ------------------------ */ + +#ifndef GL_EXT_point_parameters +#define GL_EXT_point_parameters 1 + +#define GL_POINT_SIZE_MIN_EXT 0x8126 +#define GL_POINT_SIZE_MAX_EXT 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE_EXT 0x8128 +#define GL_DISTANCE_ATTENUATION_EXT 0x8129 + +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFEXTPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFVEXTPROC) (GLenum pname, GLfloat* params); + +#define glPointParameterfEXT GLEW_GET_FUN(__glewPointParameterfEXT) +#define glPointParameterfvEXT GLEW_GET_FUN(__glewPointParameterfvEXT) + +#define GLEW_EXT_point_parameters GLEW_GET_VAR(__GLEW_EXT_point_parameters) + +#endif /* GL_EXT_point_parameters */ + +/* ------------------------- GL_EXT_polygon_offset ------------------------- */ + +#ifndef GL_EXT_polygon_offset +#define GL_EXT_polygon_offset 1 + +#define GL_POLYGON_OFFSET_EXT 0x8037 +#define GL_POLYGON_OFFSET_FACTOR_EXT 0x8038 +#define GL_POLYGON_OFFSET_BIAS_EXT 0x8039 + +typedef void (GLAPIENTRY * PFNGLPOLYGONOFFSETEXTPROC) (GLfloat factor, GLfloat bias); + +#define glPolygonOffsetEXT GLEW_GET_FUN(__glewPolygonOffsetEXT) + +#define GLEW_EXT_polygon_offset GLEW_GET_VAR(__GLEW_EXT_polygon_offset) + +#endif /* GL_EXT_polygon_offset */ + +/* ------------------------- GL_EXT_rescale_normal ------------------------- */ + +#ifndef GL_EXT_rescale_normal +#define GL_EXT_rescale_normal 1 + +#define GL_RESCALE_NORMAL_EXT 0x803A + +#define GLEW_EXT_rescale_normal GLEW_GET_VAR(__GLEW_EXT_rescale_normal) + +#endif /* GL_EXT_rescale_normal */ + +/* -------------------------- GL_EXT_scene_marker -------------------------- */ + +#ifndef GL_EXT_scene_marker +#define GL_EXT_scene_marker 1 + +typedef void (GLAPIENTRY * PFNGLBEGINSCENEEXTPROC) (void); +typedef void (GLAPIENTRY * PFNGLENDSCENEEXTPROC) (void); + +#define glBeginSceneEXT GLEW_GET_FUN(__glewBeginSceneEXT) +#define glEndSceneEXT GLEW_GET_FUN(__glewEndSceneEXT) + +#define GLEW_EXT_scene_marker GLEW_GET_VAR(__GLEW_EXT_scene_marker) + +#endif /* GL_EXT_scene_marker */ + +/* ------------------------- GL_EXT_secondary_color ------------------------ */ + +#ifndef GL_EXT_secondary_color +#define GL_EXT_secondary_color 1 + +#define GL_COLOR_SUM_EXT 0x8458 +#define GL_CURRENT_SECONDARY_COLOR_EXT 0x8459 +#define GL_SECONDARY_COLOR_ARRAY_SIZE_EXT 0x845A +#define GL_SECONDARY_COLOR_ARRAY_TYPE_EXT 0x845B +#define GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT 0x845C +#define GL_SECONDARY_COLOR_ARRAY_POINTER_EXT 0x845D +#define GL_SECONDARY_COLOR_ARRAY_EXT 0x845E + +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3BEXTPROC) (GLbyte red, GLbyte green, GLbyte blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3BVEXTPROC) (const GLbyte *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3DEXTPROC) (GLdouble red, GLdouble green, GLdouble blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3DVEXTPROC) (const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3FEXTPROC) (GLfloat red, GLfloat green, GLfloat blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3FVEXTPROC) (const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3IEXTPROC) (GLint red, GLint green, GLint blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3IVEXTPROC) (const GLint *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3SEXTPROC) (GLshort red, GLshort green, GLshort blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3SVEXTPROC) (const GLshort *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UBEXTPROC) (GLubyte red, GLubyte green, GLubyte blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UBVEXTPROC) (const GLubyte *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UIEXTPROC) (GLuint red, GLuint green, GLuint blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UIVEXTPROC) (const GLuint *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3USEXTPROC) (GLushort red, GLushort green, GLushort blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3USVEXTPROC) (const GLushort *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLvoid *pointer); + +#define glSecondaryColor3bEXT GLEW_GET_FUN(__glewSecondaryColor3bEXT) +#define glSecondaryColor3bvEXT GLEW_GET_FUN(__glewSecondaryColor3bvEXT) +#define glSecondaryColor3dEXT GLEW_GET_FUN(__glewSecondaryColor3dEXT) +#define glSecondaryColor3dvEXT GLEW_GET_FUN(__glewSecondaryColor3dvEXT) +#define glSecondaryColor3fEXT GLEW_GET_FUN(__glewSecondaryColor3fEXT) +#define glSecondaryColor3fvEXT GLEW_GET_FUN(__glewSecondaryColor3fvEXT) +#define glSecondaryColor3iEXT GLEW_GET_FUN(__glewSecondaryColor3iEXT) +#define glSecondaryColor3ivEXT GLEW_GET_FUN(__glewSecondaryColor3ivEXT) +#define glSecondaryColor3sEXT GLEW_GET_FUN(__glewSecondaryColor3sEXT) +#define glSecondaryColor3svEXT GLEW_GET_FUN(__glewSecondaryColor3svEXT) +#define glSecondaryColor3ubEXT GLEW_GET_FUN(__glewSecondaryColor3ubEXT) +#define glSecondaryColor3ubvEXT GLEW_GET_FUN(__glewSecondaryColor3ubvEXT) +#define glSecondaryColor3uiEXT GLEW_GET_FUN(__glewSecondaryColor3uiEXT) +#define glSecondaryColor3uivEXT GLEW_GET_FUN(__glewSecondaryColor3uivEXT) +#define glSecondaryColor3usEXT GLEW_GET_FUN(__glewSecondaryColor3usEXT) +#define glSecondaryColor3usvEXT GLEW_GET_FUN(__glewSecondaryColor3usvEXT) +#define glSecondaryColorPointerEXT GLEW_GET_FUN(__glewSecondaryColorPointerEXT) + +#define GLEW_EXT_secondary_color GLEW_GET_VAR(__GLEW_EXT_secondary_color) + +#endif /* GL_EXT_secondary_color */ + +/* --------------------- GL_EXT_separate_specular_color -------------------- */ + +#ifndef GL_EXT_separate_specular_color +#define GL_EXT_separate_specular_color 1 + +#define GL_LIGHT_MODEL_COLOR_CONTROL_EXT 0x81F8 +#define GL_SINGLE_COLOR_EXT 0x81F9 +#define GL_SEPARATE_SPECULAR_COLOR_EXT 0x81FA + +#define GLEW_EXT_separate_specular_color GLEW_GET_VAR(__GLEW_EXT_separate_specular_color) + +#endif /* GL_EXT_separate_specular_color */ + +/* -------------------------- GL_EXT_shadow_funcs -------------------------- */ + +#ifndef GL_EXT_shadow_funcs +#define GL_EXT_shadow_funcs 1 + +#define GLEW_EXT_shadow_funcs GLEW_GET_VAR(__GLEW_EXT_shadow_funcs) + +#endif /* GL_EXT_shadow_funcs */ + +/* --------------------- GL_EXT_shared_texture_palette --------------------- */ + +#ifndef GL_EXT_shared_texture_palette +#define GL_EXT_shared_texture_palette 1 + +#define GL_SHARED_TEXTURE_PALETTE_EXT 0x81FB + +#define GLEW_EXT_shared_texture_palette GLEW_GET_VAR(__GLEW_EXT_shared_texture_palette) + +#endif /* GL_EXT_shared_texture_palette */ + +/* ------------------------ GL_EXT_stencil_clear_tag ----------------------- */ + +#ifndef GL_EXT_stencil_clear_tag +#define GL_EXT_stencil_clear_tag 1 + +#define GL_STENCIL_TAG_BITS_EXT 0x88F2 +#define GL_STENCIL_CLEAR_TAG_VALUE_EXT 0x88F3 + +#define GLEW_EXT_stencil_clear_tag GLEW_GET_VAR(__GLEW_EXT_stencil_clear_tag) + +#endif /* GL_EXT_stencil_clear_tag */ + +/* ------------------------ GL_EXT_stencil_two_side ------------------------ */ + +#ifndef GL_EXT_stencil_two_side +#define GL_EXT_stencil_two_side 1 + +#define GL_STENCIL_TEST_TWO_SIDE_EXT 0x8910 +#define GL_ACTIVE_STENCIL_FACE_EXT 0x8911 + +typedef void (GLAPIENTRY * PFNGLACTIVESTENCILFACEEXTPROC) (GLenum face); + +#define glActiveStencilFaceEXT GLEW_GET_FUN(__glewActiveStencilFaceEXT) + +#define GLEW_EXT_stencil_two_side GLEW_GET_VAR(__GLEW_EXT_stencil_two_side) + +#endif /* GL_EXT_stencil_two_side */ + +/* -------------------------- GL_EXT_stencil_wrap -------------------------- */ + +#ifndef GL_EXT_stencil_wrap +#define GL_EXT_stencil_wrap 1 + +#define GL_INCR_WRAP_EXT 0x8507 +#define GL_DECR_WRAP_EXT 0x8508 + +#define GLEW_EXT_stencil_wrap GLEW_GET_VAR(__GLEW_EXT_stencil_wrap) + +#endif /* GL_EXT_stencil_wrap */ + +/* --------------------------- GL_EXT_subtexture --------------------------- */ + +#ifndef GL_EXT_subtexture +#define GL_EXT_subtexture 1 + +typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels); + +#define glTexSubImage1DEXT GLEW_GET_FUN(__glewTexSubImage1DEXT) +#define glTexSubImage2DEXT GLEW_GET_FUN(__glewTexSubImage2DEXT) +#define glTexSubImage3DEXT GLEW_GET_FUN(__glewTexSubImage3DEXT) + +#define GLEW_EXT_subtexture GLEW_GET_VAR(__GLEW_EXT_subtexture) + +#endif /* GL_EXT_subtexture */ + +/* ----------------------------- GL_EXT_texture ---------------------------- */ + +#ifndef GL_EXT_texture +#define GL_EXT_texture 1 + +#define GL_ALPHA4_EXT 0x803B +#define GL_ALPHA8_EXT 0x803C +#define GL_ALPHA12_EXT 0x803D +#define GL_ALPHA16_EXT 0x803E +#define GL_LUMINANCE4_EXT 0x803F +#define GL_LUMINANCE8_EXT 0x8040 +#define GL_LUMINANCE12_EXT 0x8041 +#define GL_LUMINANCE16_EXT 0x8042 +#define GL_LUMINANCE4_ALPHA4_EXT 0x8043 +#define GL_LUMINANCE6_ALPHA2_EXT 0x8044 +#define GL_LUMINANCE8_ALPHA8_EXT 0x8045 +#define GL_LUMINANCE12_ALPHA4_EXT 0x8046 +#define GL_LUMINANCE12_ALPHA12_EXT 0x8047 +#define GL_LUMINANCE16_ALPHA16_EXT 0x8048 +#define GL_INTENSITY_EXT 0x8049 +#define GL_INTENSITY4_EXT 0x804A +#define GL_INTENSITY8_EXT 0x804B +#define GL_INTENSITY12_EXT 0x804C +#define GL_INTENSITY16_EXT 0x804D +#define GL_RGB2_EXT 0x804E +#define GL_RGB4_EXT 0x804F +#define GL_RGB5_EXT 0x8050 +#define GL_RGB8_EXT 0x8051 +#define GL_RGB10_EXT 0x8052 +#define GL_RGB12_EXT 0x8053 +#define GL_RGB16_EXT 0x8054 +#define GL_RGBA2_EXT 0x8055 +#define GL_RGBA4_EXT 0x8056 +#define GL_RGB5_A1_EXT 0x8057 +#define GL_RGBA8_EXT 0x8058 +#define GL_RGB10_A2_EXT 0x8059 +#define GL_RGBA12_EXT 0x805A +#define GL_RGBA16_EXT 0x805B +#define GL_TEXTURE_RED_SIZE_EXT 0x805C +#define GL_TEXTURE_GREEN_SIZE_EXT 0x805D +#define GL_TEXTURE_BLUE_SIZE_EXT 0x805E +#define GL_TEXTURE_ALPHA_SIZE_EXT 0x805F +#define GL_TEXTURE_LUMINANCE_SIZE_EXT 0x8060 +#define GL_TEXTURE_INTENSITY_SIZE_EXT 0x8061 +#define GL_REPLACE_EXT 0x8062 +#define GL_PROXY_TEXTURE_1D_EXT 0x8063 +#define GL_PROXY_TEXTURE_2D_EXT 0x8064 + +#define GLEW_EXT_texture GLEW_GET_VAR(__GLEW_EXT_texture) + +#endif /* GL_EXT_texture */ + +/* ---------------------------- GL_EXT_texture3D --------------------------- */ + +#ifndef GL_EXT_texture3D +#define GL_EXT_texture3D 1 + +#define GL_PACK_SKIP_IMAGES_EXT 0x806B +#define GL_PACK_IMAGE_HEIGHT_EXT 0x806C +#define GL_UNPACK_SKIP_IMAGES_EXT 0x806D +#define GL_UNPACK_IMAGE_HEIGHT_EXT 0x806E +#define GL_TEXTURE_3D_EXT 0x806F +#define GL_PROXY_TEXTURE_3D_EXT 0x8070 +#define GL_TEXTURE_DEPTH_EXT 0x8071 +#define GL_TEXTURE_WRAP_R_EXT 0x8072 +#define GL_MAX_3D_TEXTURE_SIZE_EXT 0x8073 + +typedef void (GLAPIENTRY * PFNGLTEXIMAGE3DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void* pixels); + +#define glTexImage3DEXT GLEW_GET_FUN(__glewTexImage3DEXT) + +#define GLEW_EXT_texture3D GLEW_GET_VAR(__GLEW_EXT_texture3D) + +#endif /* GL_EXT_texture3D */ + +/* -------------------------- GL_EXT_texture_array ------------------------- */ + +#ifndef GL_EXT_texture_array +#define GL_EXT_texture_array 1 + +#define GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT 0x884E +#define GL_MAX_ARRAY_TEXTURE_LAYERS_EXT 0x88FF +#define GL_TEXTURE_1D_ARRAY_EXT 0x8C18 +#define GL_PROXY_TEXTURE_1D_ARRAY_EXT 0x8C19 +#define GL_TEXTURE_2D_ARRAY_EXT 0x8C1A +#define GL_PROXY_TEXTURE_2D_ARRAY_EXT 0x8C1B +#define GL_TEXTURE_BINDING_1D_ARRAY_EXT 0x8C1C +#define GL_TEXTURE_BINDING_2D_ARRAY_EXT 0x8C1D + +#define GLEW_EXT_texture_array GLEW_GET_VAR(__GLEW_EXT_texture_array) + +#endif /* GL_EXT_texture_array */ + +/* ---------------------- GL_EXT_texture_buffer_object --------------------- */ + +#ifndef GL_EXT_texture_buffer_object +#define GL_EXT_texture_buffer_object 1 + +#define GL_TEXTURE_BUFFER_EXT 0x8C2A +#define GL_MAX_TEXTURE_BUFFER_SIZE_EXT 0x8C2B +#define GL_TEXTURE_BINDING_BUFFER_EXT 0x8C2C +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT 0x8C2D +#define GL_TEXTURE_BUFFER_FORMAT_EXT 0x8C2E + +typedef void (GLAPIENTRY * PFNGLTEXBUFFEREXTPROC) (GLenum target, GLenum internalformat, GLuint buffer); + +#define glTexBufferEXT GLEW_GET_FUN(__glewTexBufferEXT) + +#define GLEW_EXT_texture_buffer_object GLEW_GET_VAR(__GLEW_EXT_texture_buffer_object) + +#endif /* GL_EXT_texture_buffer_object */ + +/* -------------------- GL_EXT_texture_compression_dxt1 -------------------- */ + +#ifndef GL_EXT_texture_compression_dxt1 +#define GL_EXT_texture_compression_dxt1 1 + +#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 +#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 + +#define GLEW_EXT_texture_compression_dxt1 GLEW_GET_VAR(__GLEW_EXT_texture_compression_dxt1) + +#endif /* GL_EXT_texture_compression_dxt1 */ + +/* -------------------- GL_EXT_texture_compression_latc -------------------- */ + +#ifndef GL_EXT_texture_compression_latc +#define GL_EXT_texture_compression_latc 1 + +#define GL_COMPRESSED_LUMINANCE_LATC1_EXT 0x8C70 +#define GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT 0x8C71 +#define GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT 0x8C72 +#define GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT 0x8C73 + +#define GLEW_EXT_texture_compression_latc GLEW_GET_VAR(__GLEW_EXT_texture_compression_latc) + +#endif /* GL_EXT_texture_compression_latc */ + +/* -------------------- GL_EXT_texture_compression_rgtc -------------------- */ + +#ifndef GL_EXT_texture_compression_rgtc +#define GL_EXT_texture_compression_rgtc 1 + +#define GL_COMPRESSED_RED_RGTC1_EXT 0x8DBB +#define GL_COMPRESSED_SIGNED_RED_RGTC1_EXT 0x8DBC +#define GL_COMPRESSED_RED_GREEN_RGTC2_EXT 0x8DBD +#define GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8DBE + +#define GLEW_EXT_texture_compression_rgtc GLEW_GET_VAR(__GLEW_EXT_texture_compression_rgtc) + +#endif /* GL_EXT_texture_compression_rgtc */ + +/* -------------------- GL_EXT_texture_compression_s3tc -------------------- */ + +#ifndef GL_EXT_texture_compression_s3tc +#define GL_EXT_texture_compression_s3tc 1 + +#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 +#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 +#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 +#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 + +#define GLEW_EXT_texture_compression_s3tc GLEW_GET_VAR(__GLEW_EXT_texture_compression_s3tc) + +#endif /* GL_EXT_texture_compression_s3tc */ + +/* ------------------------ GL_EXT_texture_cube_map ------------------------ */ + +#ifndef GL_EXT_texture_cube_map +#define GL_EXT_texture_cube_map 1 + +#define GL_NORMAL_MAP_EXT 0x8511 +#define GL_REFLECTION_MAP_EXT 0x8512 +#define GL_TEXTURE_CUBE_MAP_EXT 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP_EXT 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP_EXT 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_EXT 0x851C + +#define GLEW_EXT_texture_cube_map GLEW_GET_VAR(__GLEW_EXT_texture_cube_map) + +#endif /* GL_EXT_texture_cube_map */ + +/* ----------------------- GL_EXT_texture_edge_clamp ----------------------- */ + +#ifndef GL_EXT_texture_edge_clamp +#define GL_EXT_texture_edge_clamp 1 + +#define GL_CLAMP_TO_EDGE_EXT 0x812F + +#define GLEW_EXT_texture_edge_clamp GLEW_GET_VAR(__GLEW_EXT_texture_edge_clamp) + +#endif /* GL_EXT_texture_edge_clamp */ + +/* --------------------------- GL_EXT_texture_env -------------------------- */ + +#ifndef GL_EXT_texture_env +#define GL_EXT_texture_env 1 + +#define GL_TEXTURE_ENV0_EXT 0 +#define GL_ENV_BLEND_EXT 0 +#define GL_TEXTURE_ENV_SHIFT_EXT 0 +#define GL_ENV_REPLACE_EXT 0 +#define GL_ENV_ADD_EXT 0 +#define GL_ENV_SUBTRACT_EXT 0 +#define GL_TEXTURE_ENV_MODE_ALPHA_EXT 0 +#define GL_ENV_REVERSE_SUBTRACT_EXT 0 +#define GL_ENV_REVERSE_BLEND_EXT 0 +#define GL_ENV_COPY_EXT 0 +#define GL_ENV_MODULATE_EXT 0 + +#define GLEW_EXT_texture_env GLEW_GET_VAR(__GLEW_EXT_texture_env) + +#endif /* GL_EXT_texture_env */ + +/* ------------------------- GL_EXT_texture_env_add ------------------------ */ + +#ifndef GL_EXT_texture_env_add +#define GL_EXT_texture_env_add 1 + +#define GLEW_EXT_texture_env_add GLEW_GET_VAR(__GLEW_EXT_texture_env_add) + +#endif /* GL_EXT_texture_env_add */ + +/* ----------------------- GL_EXT_texture_env_combine ---------------------- */ + +#ifndef GL_EXT_texture_env_combine +#define GL_EXT_texture_env_combine 1 + +#define GL_COMBINE_EXT 0x8570 +#define GL_COMBINE_RGB_EXT 0x8571 +#define GL_COMBINE_ALPHA_EXT 0x8572 +#define GL_RGB_SCALE_EXT 0x8573 +#define GL_ADD_SIGNED_EXT 0x8574 +#define GL_INTERPOLATE_EXT 0x8575 +#define GL_CONSTANT_EXT 0x8576 +#define GL_PRIMARY_COLOR_EXT 0x8577 +#define GL_PREVIOUS_EXT 0x8578 +#define GL_SOURCE0_RGB_EXT 0x8580 +#define GL_SOURCE1_RGB_EXT 0x8581 +#define GL_SOURCE2_RGB_EXT 0x8582 +#define GL_SOURCE0_ALPHA_EXT 0x8588 +#define GL_SOURCE1_ALPHA_EXT 0x8589 +#define GL_SOURCE2_ALPHA_EXT 0x858A +#define GL_OPERAND0_RGB_EXT 0x8590 +#define GL_OPERAND1_RGB_EXT 0x8591 +#define GL_OPERAND2_RGB_EXT 0x8592 +#define GL_OPERAND0_ALPHA_EXT 0x8598 +#define GL_OPERAND1_ALPHA_EXT 0x8599 +#define GL_OPERAND2_ALPHA_EXT 0x859A + +#define GLEW_EXT_texture_env_combine GLEW_GET_VAR(__GLEW_EXT_texture_env_combine) + +#endif /* GL_EXT_texture_env_combine */ + +/* ------------------------ GL_EXT_texture_env_dot3 ------------------------ */ + +#ifndef GL_EXT_texture_env_dot3 +#define GL_EXT_texture_env_dot3 1 + +#define GL_DOT3_RGB_EXT 0x8740 +#define GL_DOT3_RGBA_EXT 0x8741 + +#define GLEW_EXT_texture_env_dot3 GLEW_GET_VAR(__GLEW_EXT_texture_env_dot3) + +#endif /* GL_EXT_texture_env_dot3 */ + +/* ------------------- GL_EXT_texture_filter_anisotropic ------------------- */ + +#ifndef GL_EXT_texture_filter_anisotropic +#define GL_EXT_texture_filter_anisotropic 1 + +#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE +#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF + +#define GLEW_EXT_texture_filter_anisotropic GLEW_GET_VAR(__GLEW_EXT_texture_filter_anisotropic) + +#endif /* GL_EXT_texture_filter_anisotropic */ + +/* ------------------------- GL_EXT_texture_integer ------------------------ */ + +#ifndef GL_EXT_texture_integer +#define GL_EXT_texture_integer 1 + +#define GL_RGBA32UI_EXT 0x8D70 +#define GL_RGB32UI_EXT 0x8D71 +#define GL_ALPHA32UI_EXT 0x8D72 +#define GL_INTENSITY32UI_EXT 0x8D73 +#define GL_LUMINANCE32UI_EXT 0x8D74 +#define GL_LUMINANCE_ALPHA32UI_EXT 0x8D75 +#define GL_RGBA16UI_EXT 0x8D76 +#define GL_RGB16UI_EXT 0x8D77 +#define GL_ALPHA16UI_EXT 0x8D78 +#define GL_INTENSITY16UI_EXT 0x8D79 +#define GL_LUMINANCE16UI_EXT 0x8D7A +#define GL_LUMINANCE_ALPHA16UI_EXT 0x8D7B +#define GL_RGBA8UI_EXT 0x8D7C +#define GL_RGB8UI_EXT 0x8D7D +#define GL_ALPHA8UI_EXT 0x8D7E +#define GL_INTENSITY8UI_EXT 0x8D7F +#define GL_LUMINANCE8UI_EXT 0x8D80 +#define GL_LUMINANCE_ALPHA8UI_EXT 0x8D81 +#define GL_RGBA32I_EXT 0x8D82 +#define GL_RGB32I_EXT 0x8D83 +#define GL_ALPHA32I_EXT 0x8D84 +#define GL_INTENSITY32I_EXT 0x8D85 +#define GL_LUMINANCE32I_EXT 0x8D86 +#define GL_LUMINANCE_ALPHA32I_EXT 0x8D87 +#define GL_RGBA16I_EXT 0x8D88 +#define GL_RGB16I_EXT 0x8D89 +#define GL_ALPHA16I_EXT 0x8D8A +#define GL_INTENSITY16I_EXT 0x8D8B +#define GL_LUMINANCE16I_EXT 0x8D8C +#define GL_LUMINANCE_ALPHA16I_EXT 0x8D8D +#define GL_RGBA8I_EXT 0x8D8E +#define GL_RGB8I_EXT 0x8D8F +#define GL_ALPHA8I_EXT 0x8D90 +#define GL_INTENSITY8I_EXT 0x8D91 +#define GL_LUMINANCE8I_EXT 0x8D92 +#define GL_LUMINANCE_ALPHA8I_EXT 0x8D93 +#define GL_RED_INTEGER_EXT 0x8D94 +#define GL_GREEN_INTEGER_EXT 0x8D95 +#define GL_BLUE_INTEGER_EXT 0x8D96 +#define GL_ALPHA_INTEGER_EXT 0x8D97 +#define GL_RGB_INTEGER_EXT 0x8D98 +#define GL_RGBA_INTEGER_EXT 0x8D99 +#define GL_BGR_INTEGER_EXT 0x8D9A +#define GL_BGRA_INTEGER_EXT 0x8D9B +#define GL_LUMINANCE_INTEGER_EXT 0x8D9C +#define GL_LUMINANCE_ALPHA_INTEGER_EXT 0x8D9D +#define GL_RGBA_INTEGER_MODE_EXT 0x8D9E + +typedef void (GLAPIENTRY * PFNGLCLEARCOLORIIEXTPROC) (GLint red, GLint green, GLint blue, GLint alpha); +typedef void (GLAPIENTRY * PFNGLCLEARCOLORIUIEXTPROC) (GLuint red, GLuint green, GLuint blue, GLuint alpha); +typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, GLuint *params); +typedef void (GLAPIENTRY * PFNGLTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (GLAPIENTRY * PFNGLTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, const GLuint *params); + +#define glClearColorIiEXT GLEW_GET_FUN(__glewClearColorIiEXT) +#define glClearColorIuiEXT GLEW_GET_FUN(__glewClearColorIuiEXT) +#define glGetTexParameterIivEXT GLEW_GET_FUN(__glewGetTexParameterIivEXT) +#define glGetTexParameterIuivEXT GLEW_GET_FUN(__glewGetTexParameterIuivEXT) +#define glTexParameterIivEXT GLEW_GET_FUN(__glewTexParameterIivEXT) +#define glTexParameterIuivEXT GLEW_GET_FUN(__glewTexParameterIuivEXT) + +#define GLEW_EXT_texture_integer GLEW_GET_VAR(__GLEW_EXT_texture_integer) + +#endif /* GL_EXT_texture_integer */ + +/* ------------------------ GL_EXT_texture_lod_bias ------------------------ */ + +#ifndef GL_EXT_texture_lod_bias +#define GL_EXT_texture_lod_bias 1 + +#define GL_MAX_TEXTURE_LOD_BIAS_EXT 0x84FD +#define GL_TEXTURE_FILTER_CONTROL_EXT 0x8500 +#define GL_TEXTURE_LOD_BIAS_EXT 0x8501 + +#define GLEW_EXT_texture_lod_bias GLEW_GET_VAR(__GLEW_EXT_texture_lod_bias) + +#endif /* GL_EXT_texture_lod_bias */ + +/* ---------------------- GL_EXT_texture_mirror_clamp ---------------------- */ + +#ifndef GL_EXT_texture_mirror_clamp +#define GL_EXT_texture_mirror_clamp 1 + +#define GL_MIRROR_CLAMP_EXT 0x8742 +#define GL_MIRROR_CLAMP_TO_EDGE_EXT 0x8743 +#define GL_MIRROR_CLAMP_TO_BORDER_EXT 0x8912 + +#define GLEW_EXT_texture_mirror_clamp GLEW_GET_VAR(__GLEW_EXT_texture_mirror_clamp) + +#endif /* GL_EXT_texture_mirror_clamp */ + +/* ------------------------- GL_EXT_texture_object ------------------------- */ + +#ifndef GL_EXT_texture_object +#define GL_EXT_texture_object 1 + +#define GL_TEXTURE_PRIORITY_EXT 0x8066 +#define GL_TEXTURE_RESIDENT_EXT 0x8067 +#define GL_TEXTURE_1D_BINDING_EXT 0x8068 +#define GL_TEXTURE_2D_BINDING_EXT 0x8069 +#define GL_TEXTURE_3D_BINDING_EXT 0x806A + +typedef GLboolean (GLAPIENTRY * PFNGLARETEXTURESRESIDENTEXTPROC) (GLsizei n, const GLuint* textures, GLboolean* residences); +typedef void (GLAPIENTRY * PFNGLBINDTEXTUREEXTPROC) (GLenum target, GLuint texture); +typedef void (GLAPIENTRY * PFNGLDELETETEXTURESEXTPROC) (GLsizei n, const GLuint* textures); +typedef void (GLAPIENTRY * PFNGLGENTEXTURESEXTPROC) (GLsizei n, GLuint* textures); +typedef GLboolean (GLAPIENTRY * PFNGLISTEXTUREEXTPROC) (GLuint texture); +typedef void (GLAPIENTRY * PFNGLPRIORITIZETEXTURESEXTPROC) (GLsizei n, const GLuint* textures, const GLclampf* priorities); + +#define glAreTexturesResidentEXT GLEW_GET_FUN(__glewAreTexturesResidentEXT) +#define glBindTextureEXT GLEW_GET_FUN(__glewBindTextureEXT) +#define glDeleteTexturesEXT GLEW_GET_FUN(__glewDeleteTexturesEXT) +#define glGenTexturesEXT GLEW_GET_FUN(__glewGenTexturesEXT) +#define glIsTextureEXT GLEW_GET_FUN(__glewIsTextureEXT) +#define glPrioritizeTexturesEXT GLEW_GET_FUN(__glewPrioritizeTexturesEXT) + +#define GLEW_EXT_texture_object GLEW_GET_VAR(__GLEW_EXT_texture_object) + +#endif /* GL_EXT_texture_object */ + +/* --------------------- GL_EXT_texture_perturb_normal --------------------- */ + +#ifndef GL_EXT_texture_perturb_normal +#define GL_EXT_texture_perturb_normal 1 + +#define GL_PERTURB_EXT 0x85AE +#define GL_TEXTURE_NORMAL_EXT 0x85AF + +typedef void (GLAPIENTRY * PFNGLTEXTURENORMALEXTPROC) (GLenum mode); + +#define glTextureNormalEXT GLEW_GET_FUN(__glewTextureNormalEXT) + +#define GLEW_EXT_texture_perturb_normal GLEW_GET_VAR(__GLEW_EXT_texture_perturb_normal) + +#endif /* GL_EXT_texture_perturb_normal */ + +/* ------------------------ GL_EXT_texture_rectangle ----------------------- */ + +#ifndef GL_EXT_texture_rectangle +#define GL_EXT_texture_rectangle 1 + +#define GL_TEXTURE_RECTANGLE_EXT 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE_EXT 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE_EXT 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE_EXT 0x84F8 + +#define GLEW_EXT_texture_rectangle GLEW_GET_VAR(__GLEW_EXT_texture_rectangle) + +#endif /* GL_EXT_texture_rectangle */ + +/* -------------------------- GL_EXT_texture_sRGB -------------------------- */ + +#ifndef GL_EXT_texture_sRGB +#define GL_EXT_texture_sRGB 1 + +#define GL_SRGB_EXT 0x8C40 +#define GL_SRGB8_EXT 0x8C41 +#define GL_SRGB_ALPHA_EXT 0x8C42 +#define GL_SRGB8_ALPHA8_EXT 0x8C43 +#define GL_SLUMINANCE_ALPHA_EXT 0x8C44 +#define GL_SLUMINANCE8_ALPHA8_EXT 0x8C45 +#define GL_SLUMINANCE_EXT 0x8C46 +#define GL_SLUMINANCE8_EXT 0x8C47 +#define GL_COMPRESSED_SRGB_EXT 0x8C48 +#define GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49 +#define GL_COMPRESSED_SLUMINANCE_EXT 0x8C4A +#define GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B +#define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F + +#define GLEW_EXT_texture_sRGB GLEW_GET_VAR(__GLEW_EXT_texture_sRGB) + +#endif /* GL_EXT_texture_sRGB */ + +/* --------------------- GL_EXT_texture_shared_exponent -------------------- */ + +#ifndef GL_EXT_texture_shared_exponent +#define GL_EXT_texture_shared_exponent 1 + +#define GL_RGB9_E5_EXT 0x8C3D +#define GL_UNSIGNED_INT_5_9_9_9_REV_EXT 0x8C3E +#define GL_TEXTURE_SHARED_SIZE_EXT 0x8C3F + +#define GLEW_EXT_texture_shared_exponent GLEW_GET_VAR(__GLEW_EXT_texture_shared_exponent) + +#endif /* GL_EXT_texture_shared_exponent */ + +/* ------------------------- GL_EXT_texture_swizzle ------------------------ */ + +#ifndef GL_EXT_texture_swizzle +#define GL_EXT_texture_swizzle 1 + +#define GL_TEXTURE_SWIZZLE_R_EXT 0x8E42 +#define GL_TEXTURE_SWIZZLE_G_EXT 0x8E43 +#define GL_TEXTURE_SWIZZLE_B_EXT 0x8E44 +#define GL_TEXTURE_SWIZZLE_A_EXT 0x8E45 +#define GL_TEXTURE_SWIZZLE_RGBA_EXT 0x8E46 + +#define GLEW_EXT_texture_swizzle GLEW_GET_VAR(__GLEW_EXT_texture_swizzle) + +#endif /* GL_EXT_texture_swizzle */ + +/* --------------------------- GL_EXT_timer_query -------------------------- */ + +#ifndef GL_EXT_timer_query +#define GL_EXT_timer_query 1 + +#define GL_TIME_ELAPSED_EXT 0x88BF + +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTI64VEXTPROC) (GLuint id, GLenum pname, GLint64EXT *params); +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUI64VEXTPROC) (GLuint id, GLenum pname, GLuint64EXT *params); + +#define glGetQueryObjecti64vEXT GLEW_GET_FUN(__glewGetQueryObjecti64vEXT) +#define glGetQueryObjectui64vEXT GLEW_GET_FUN(__glewGetQueryObjectui64vEXT) + +#define GLEW_EXT_timer_query GLEW_GET_VAR(__GLEW_EXT_timer_query) + +#endif /* GL_EXT_timer_query */ + +/* ----------------------- GL_EXT_transform_feedback ----------------------- */ + +#ifndef GL_EXT_transform_feedback +#define GL_EXT_transform_feedback 1 + +#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH_EXT 0x8C76 +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_EXT 0x8C7F +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_EXT 0x8C80 +#define GL_TRANSFORM_FEEDBACK_VARYINGS_EXT 0x8C83 +#define GL_TRANSFORM_FEEDBACK_BUFFER_START_EXT 0x8C84 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_EXT 0x8C85 +#define GL_PRIMITIVES_GENERATED_EXT 0x8C87 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_EXT 0x8C88 +#define GL_RASTERIZER_DISCARD_EXT 0x8C89 +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_EXT 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_EXT 0x8C8B +#define GL_INTERLEAVED_ATTRIBS_EXT 0x8C8C +#define GL_SEPARATE_ATTRIBS_EXT 0x8C8D +#define GL_TRANSFORM_FEEDBACK_BUFFER_EXT 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_EXT 0x8C8F + +typedef void (GLAPIENTRY * PFNGLBEGINTRANSFORMFEEDBACKEXTPROC) (GLenum primitiveMode); +typedef void (GLAPIENTRY * PFNGLBINDBUFFERBASEEXTPROC) (GLenum target, GLuint index, GLuint buffer); +typedef void (GLAPIENTRY * PFNGLBINDBUFFEROFFSETEXTPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLBINDBUFFERRANGEEXTPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (GLAPIENTRY * PFNGLENDTRANSFORMFEEDBACKEXTPROC) (void); +typedef void (GLAPIENTRY * PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei *size, GLenum *type, char *name); +typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC) (GLuint program, GLsizei count, const char ** varyings, GLenum bufferMode); + +#define glBeginTransformFeedbackEXT GLEW_GET_FUN(__glewBeginTransformFeedbackEXT) +#define glBindBufferBaseEXT GLEW_GET_FUN(__glewBindBufferBaseEXT) +#define glBindBufferOffsetEXT GLEW_GET_FUN(__glewBindBufferOffsetEXT) +#define glBindBufferRangeEXT GLEW_GET_FUN(__glewBindBufferRangeEXT) +#define glEndTransformFeedbackEXT GLEW_GET_FUN(__glewEndTransformFeedbackEXT) +#define glGetTransformFeedbackVaryingEXT GLEW_GET_FUN(__glewGetTransformFeedbackVaryingEXT) +#define glTransformFeedbackVaryingsEXT GLEW_GET_FUN(__glewTransformFeedbackVaryingsEXT) + +#define GLEW_EXT_transform_feedback GLEW_GET_VAR(__GLEW_EXT_transform_feedback) + +#endif /* GL_EXT_transform_feedback */ + +/* -------------------------- GL_EXT_vertex_array -------------------------- */ + +#ifndef GL_EXT_vertex_array +#define GL_EXT_vertex_array 1 + +#define GL_DOUBLE_EXT 0x140A +#define GL_VERTEX_ARRAY_EXT 0x8074 +#define GL_NORMAL_ARRAY_EXT 0x8075 +#define GL_COLOR_ARRAY_EXT 0x8076 +#define GL_INDEX_ARRAY_EXT 0x8077 +#define GL_TEXTURE_COORD_ARRAY_EXT 0x8078 +#define GL_EDGE_FLAG_ARRAY_EXT 0x8079 +#define GL_VERTEX_ARRAY_SIZE_EXT 0x807A +#define GL_VERTEX_ARRAY_TYPE_EXT 0x807B +#define GL_VERTEX_ARRAY_STRIDE_EXT 0x807C +#define GL_VERTEX_ARRAY_COUNT_EXT 0x807D +#define GL_NORMAL_ARRAY_TYPE_EXT 0x807E +#define GL_NORMAL_ARRAY_STRIDE_EXT 0x807F +#define GL_NORMAL_ARRAY_COUNT_EXT 0x8080 +#define GL_COLOR_ARRAY_SIZE_EXT 0x8081 +#define GL_COLOR_ARRAY_TYPE_EXT 0x8082 +#define GL_COLOR_ARRAY_STRIDE_EXT 0x8083 +#define GL_COLOR_ARRAY_COUNT_EXT 0x8084 +#define GL_INDEX_ARRAY_TYPE_EXT 0x8085 +#define GL_INDEX_ARRAY_STRIDE_EXT 0x8086 +#define GL_INDEX_ARRAY_COUNT_EXT 0x8087 +#define GL_TEXTURE_COORD_ARRAY_SIZE_EXT 0x8088 +#define GL_TEXTURE_COORD_ARRAY_TYPE_EXT 0x8089 +#define GL_TEXTURE_COORD_ARRAY_STRIDE_EXT 0x808A +#define GL_TEXTURE_COORD_ARRAY_COUNT_EXT 0x808B +#define GL_EDGE_FLAG_ARRAY_STRIDE_EXT 0x808C +#define GL_EDGE_FLAG_ARRAY_COUNT_EXT 0x808D +#define GL_VERTEX_ARRAY_POINTER_EXT 0x808E +#define GL_NORMAL_ARRAY_POINTER_EXT 0x808F +#define GL_COLOR_ARRAY_POINTER_EXT 0x8090 +#define GL_INDEX_ARRAY_POINTER_EXT 0x8091 +#define GL_TEXTURE_COORD_ARRAY_POINTER_EXT 0x8092 +#define GL_EDGE_FLAG_ARRAY_POINTER_EXT 0x8093 + +typedef void (GLAPIENTRY * PFNGLARRAYELEMENTEXTPROC) (GLint i); +typedef void (GLAPIENTRY * PFNGLCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const void* pointer); +typedef void (GLAPIENTRY * PFNGLDRAWARRAYSEXTPROC) (GLenum mode, GLint first, GLsizei count); +typedef void (GLAPIENTRY * PFNGLEDGEFLAGPOINTEREXTPROC) (GLsizei stride, GLsizei count, const GLboolean* pointer); +typedef void (GLAPIENTRY * PFNGLGETPOINTERVEXTPROC) (GLenum pname, void** params); +typedef void (GLAPIENTRY * PFNGLINDEXPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const void* pointer); +typedef void (GLAPIENTRY * PFNGLNORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const void* pointer); +typedef void (GLAPIENTRY * PFNGLTEXCOORDPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const void* pointer); +typedef void (GLAPIENTRY * PFNGLVERTEXPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const void* pointer); + +#define glArrayElementEXT GLEW_GET_FUN(__glewArrayElementEXT) +#define glColorPointerEXT GLEW_GET_FUN(__glewColorPointerEXT) +#define glDrawArraysEXT GLEW_GET_FUN(__glewDrawArraysEXT) +#define glEdgeFlagPointerEXT GLEW_GET_FUN(__glewEdgeFlagPointerEXT) +#define glGetPointervEXT GLEW_GET_FUN(__glewGetPointervEXT) +#define glIndexPointerEXT GLEW_GET_FUN(__glewIndexPointerEXT) +#define glNormalPointerEXT GLEW_GET_FUN(__glewNormalPointerEXT) +#define glTexCoordPointerEXT GLEW_GET_FUN(__glewTexCoordPointerEXT) +#define glVertexPointerEXT GLEW_GET_FUN(__glewVertexPointerEXT) + +#define GLEW_EXT_vertex_array GLEW_GET_VAR(__GLEW_EXT_vertex_array) + +#endif /* GL_EXT_vertex_array */ + +/* ------------------------ GL_EXT_vertex_array_bgra ----------------------- */ + +#ifndef GL_EXT_vertex_array_bgra +#define GL_EXT_vertex_array_bgra 1 + +#define GL_BGRA 0x80E1 + +#define GLEW_EXT_vertex_array_bgra GLEW_GET_VAR(__GLEW_EXT_vertex_array_bgra) + +#endif /* GL_EXT_vertex_array_bgra */ + +/* -------------------------- GL_EXT_vertex_shader ------------------------- */ + +#ifndef GL_EXT_vertex_shader +#define GL_EXT_vertex_shader 1 + +#define GL_VERTEX_SHADER_EXT 0x8780 +#define GL_VERTEX_SHADER_BINDING_EXT 0x8781 +#define GL_OP_INDEX_EXT 0x8782 +#define GL_OP_NEGATE_EXT 0x8783 +#define GL_OP_DOT3_EXT 0x8784 +#define GL_OP_DOT4_EXT 0x8785 +#define GL_OP_MUL_EXT 0x8786 +#define GL_OP_ADD_EXT 0x8787 +#define GL_OP_MADD_EXT 0x8788 +#define GL_OP_FRAC_EXT 0x8789 +#define GL_OP_MAX_EXT 0x878A +#define GL_OP_MIN_EXT 0x878B +#define GL_OP_SET_GE_EXT 0x878C +#define GL_OP_SET_LT_EXT 0x878D +#define GL_OP_CLAMP_EXT 0x878E +#define GL_OP_FLOOR_EXT 0x878F +#define GL_OP_ROUND_EXT 0x8790 +#define GL_OP_EXP_BASE_2_EXT 0x8791 +#define GL_OP_LOG_BASE_2_EXT 0x8792 +#define GL_OP_POWER_EXT 0x8793 +#define GL_OP_RECIP_EXT 0x8794 +#define GL_OP_RECIP_SQRT_EXT 0x8795 +#define GL_OP_SUB_EXT 0x8796 +#define GL_OP_CROSS_PRODUCT_EXT 0x8797 +#define GL_OP_MULTIPLY_MATRIX_EXT 0x8798 +#define GL_OP_MOV_EXT 0x8799 +#define GL_OUTPUT_VERTEX_EXT 0x879A +#define GL_OUTPUT_COLOR0_EXT 0x879B +#define GL_OUTPUT_COLOR1_EXT 0x879C +#define GL_OUTPUT_TEXTURE_COORD0_EXT 0x879D +#define GL_OUTPUT_TEXTURE_COORD1_EXT 0x879E +#define GL_OUTPUT_TEXTURE_COORD2_EXT 0x879F +#define GL_OUTPUT_TEXTURE_COORD3_EXT 0x87A0 +#define GL_OUTPUT_TEXTURE_COORD4_EXT 0x87A1 +#define GL_OUTPUT_TEXTURE_COORD5_EXT 0x87A2 +#define GL_OUTPUT_TEXTURE_COORD6_EXT 0x87A3 +#define GL_OUTPUT_TEXTURE_COORD7_EXT 0x87A4 +#define GL_OUTPUT_TEXTURE_COORD8_EXT 0x87A5 +#define GL_OUTPUT_TEXTURE_COORD9_EXT 0x87A6 +#define GL_OUTPUT_TEXTURE_COORD10_EXT 0x87A7 +#define GL_OUTPUT_TEXTURE_COORD11_EXT 0x87A8 +#define GL_OUTPUT_TEXTURE_COORD12_EXT 0x87A9 +#define GL_OUTPUT_TEXTURE_COORD13_EXT 0x87AA +#define GL_OUTPUT_TEXTURE_COORD14_EXT 0x87AB +#define GL_OUTPUT_TEXTURE_COORD15_EXT 0x87AC +#define GL_OUTPUT_TEXTURE_COORD16_EXT 0x87AD +#define GL_OUTPUT_TEXTURE_COORD17_EXT 0x87AE +#define GL_OUTPUT_TEXTURE_COORD18_EXT 0x87AF +#define GL_OUTPUT_TEXTURE_COORD19_EXT 0x87B0 +#define GL_OUTPUT_TEXTURE_COORD20_EXT 0x87B1 +#define GL_OUTPUT_TEXTURE_COORD21_EXT 0x87B2 +#define GL_OUTPUT_TEXTURE_COORD22_EXT 0x87B3 +#define GL_OUTPUT_TEXTURE_COORD23_EXT 0x87B4 +#define GL_OUTPUT_TEXTURE_COORD24_EXT 0x87B5 +#define GL_OUTPUT_TEXTURE_COORD25_EXT 0x87B6 +#define GL_OUTPUT_TEXTURE_COORD26_EXT 0x87B7 +#define GL_OUTPUT_TEXTURE_COORD27_EXT 0x87B8 +#define GL_OUTPUT_TEXTURE_COORD28_EXT 0x87B9 +#define GL_OUTPUT_TEXTURE_COORD29_EXT 0x87BA +#define GL_OUTPUT_TEXTURE_COORD30_EXT 0x87BB +#define GL_OUTPUT_TEXTURE_COORD31_EXT 0x87BC +#define GL_OUTPUT_FOG_EXT 0x87BD +#define GL_SCALAR_EXT 0x87BE +#define GL_VECTOR_EXT 0x87BF +#define GL_MATRIX_EXT 0x87C0 +#define GL_VARIANT_EXT 0x87C1 +#define GL_INVARIANT_EXT 0x87C2 +#define GL_LOCAL_CONSTANT_EXT 0x87C3 +#define GL_LOCAL_EXT 0x87C4 +#define GL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87C5 +#define GL_MAX_VERTEX_SHADER_VARIANTS_EXT 0x87C6 +#define GL_MAX_VERTEX_SHADER_INVARIANTS_EXT 0x87C7 +#define GL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87C8 +#define GL_MAX_VERTEX_SHADER_LOCALS_EXT 0x87C9 +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CA +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT 0x87CB +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT 0x87CC +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87CD +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT 0x87CE +#define GL_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CF +#define GL_VERTEX_SHADER_VARIANTS_EXT 0x87D0 +#define GL_VERTEX_SHADER_INVARIANTS_EXT 0x87D1 +#define GL_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87D2 +#define GL_VERTEX_SHADER_LOCALS_EXT 0x87D3 +#define GL_VERTEX_SHADER_OPTIMIZED_EXT 0x87D4 +#define GL_X_EXT 0x87D5 +#define GL_Y_EXT 0x87D6 +#define GL_Z_EXT 0x87D7 +#define GL_W_EXT 0x87D8 +#define GL_NEGATIVE_X_EXT 0x87D9 +#define GL_NEGATIVE_Y_EXT 0x87DA +#define GL_NEGATIVE_Z_EXT 0x87DB +#define GL_NEGATIVE_W_EXT 0x87DC +#define GL_ZERO_EXT 0x87DD +#define GL_ONE_EXT 0x87DE +#define GL_NEGATIVE_ONE_EXT 0x87DF +#define GL_NORMALIZED_RANGE_EXT 0x87E0 +#define GL_FULL_RANGE_EXT 0x87E1 +#define GL_CURRENT_VERTEX_EXT 0x87E2 +#define GL_MVP_MATRIX_EXT 0x87E3 +#define GL_VARIANT_VALUE_EXT 0x87E4 +#define GL_VARIANT_DATATYPE_EXT 0x87E5 +#define GL_VARIANT_ARRAY_STRIDE_EXT 0x87E6 +#define GL_VARIANT_ARRAY_TYPE_EXT 0x87E7 +#define GL_VARIANT_ARRAY_EXT 0x87E8 +#define GL_VARIANT_ARRAY_POINTER_EXT 0x87E9 +#define GL_INVARIANT_VALUE_EXT 0x87EA +#define GL_INVARIANT_DATATYPE_EXT 0x87EB +#define GL_LOCAL_CONSTANT_VALUE_EXT 0x87EC +#define GL_LOCAL_CONSTANT_DATATYPE_EXT 0x87ED + +typedef void (GLAPIENTRY * PFNGLBEGINVERTEXSHADEREXTPROC) (void); +typedef GLuint (GLAPIENTRY * PFNGLBINDLIGHTPARAMETEREXTPROC) (GLenum light, GLenum value); +typedef GLuint (GLAPIENTRY * PFNGLBINDMATERIALPARAMETEREXTPROC) (GLenum face, GLenum value); +typedef GLuint (GLAPIENTRY * PFNGLBINDPARAMETEREXTPROC) (GLenum value); +typedef GLuint (GLAPIENTRY * PFNGLBINDTEXGENPARAMETEREXTPROC) (GLenum unit, GLenum coord, GLenum value); +typedef GLuint (GLAPIENTRY * PFNGLBINDTEXTUREUNITPARAMETEREXTPROC) (GLenum unit, GLenum value); +typedef void (GLAPIENTRY * PFNGLBINDVERTEXSHADEREXTPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLDELETEVERTEXSHADEREXTPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLENABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLENDVERTEXSHADEREXTPROC) (void); +typedef void (GLAPIENTRY * PFNGLEXTRACTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num); +typedef GLuint (GLAPIENTRY * PFNGLGENSYMBOLSEXTPROC) (GLenum dataType, GLenum storageType, GLenum range, GLuint components); +typedef GLuint (GLAPIENTRY * PFNGLGENVERTEXSHADERSEXTPROC) (GLuint range); +typedef void (GLAPIENTRY * PFNGLGETINVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); +typedef void (GLAPIENTRY * PFNGLGETINVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); +typedef void (GLAPIENTRY * PFNGLGETINVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); +typedef void (GLAPIENTRY * PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); +typedef void (GLAPIENTRY * PFNGLGETLOCALCONSTANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); +typedef void (GLAPIENTRY * PFNGLGETLOCALCONSTANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); +typedef void (GLAPIENTRY * PFNGLGETVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); +typedef void (GLAPIENTRY * PFNGLGETVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); +typedef void (GLAPIENTRY * PFNGLGETVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); +typedef void (GLAPIENTRY * PFNGLGETVARIANTPOINTERVEXTPROC) (GLuint id, GLenum value, GLvoid **data); +typedef void (GLAPIENTRY * PFNGLINSERTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num); +typedef GLboolean (GLAPIENTRY * PFNGLISVARIANTENABLEDEXTPROC) (GLuint id, GLenum cap); +typedef void (GLAPIENTRY * PFNGLSETINVARIANTEXTPROC) (GLuint id, GLenum type, GLvoid *addr); +typedef void (GLAPIENTRY * PFNGLSETLOCALCONSTANTEXTPROC) (GLuint id, GLenum type, GLvoid *addr); +typedef void (GLAPIENTRY * PFNGLSHADEROP1EXTPROC) (GLenum op, GLuint res, GLuint arg1); +typedef void (GLAPIENTRY * PFNGLSHADEROP2EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2); +typedef void (GLAPIENTRY * PFNGLSHADEROP3EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2, GLuint arg3); +typedef void (GLAPIENTRY * PFNGLSWIZZLEEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); +typedef void (GLAPIENTRY * PFNGLVARIANTPOINTEREXTPROC) (GLuint id, GLenum type, GLuint stride, GLvoid *addr); +typedef void (GLAPIENTRY * PFNGLVARIANTBVEXTPROC) (GLuint id, GLbyte *addr); +typedef void (GLAPIENTRY * PFNGLVARIANTDVEXTPROC) (GLuint id, GLdouble *addr); +typedef void (GLAPIENTRY * PFNGLVARIANTFVEXTPROC) (GLuint id, GLfloat *addr); +typedef void (GLAPIENTRY * PFNGLVARIANTIVEXTPROC) (GLuint id, GLint *addr); +typedef void (GLAPIENTRY * PFNGLVARIANTSVEXTPROC) (GLuint id, GLshort *addr); +typedef void (GLAPIENTRY * PFNGLVARIANTUBVEXTPROC) (GLuint id, GLubyte *addr); +typedef void (GLAPIENTRY * PFNGLVARIANTUIVEXTPROC) (GLuint id, GLuint *addr); +typedef void (GLAPIENTRY * PFNGLVARIANTUSVEXTPROC) (GLuint id, GLushort *addr); +typedef void (GLAPIENTRY * PFNGLWRITEMASKEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); + +#define glBeginVertexShaderEXT GLEW_GET_FUN(__glewBeginVertexShaderEXT) +#define glBindLightParameterEXT GLEW_GET_FUN(__glewBindLightParameterEXT) +#define glBindMaterialParameterEXT GLEW_GET_FUN(__glewBindMaterialParameterEXT) +#define glBindParameterEXT GLEW_GET_FUN(__glewBindParameterEXT) +#define glBindTexGenParameterEXT GLEW_GET_FUN(__glewBindTexGenParameterEXT) +#define glBindTextureUnitParameterEXT GLEW_GET_FUN(__glewBindTextureUnitParameterEXT) +#define glBindVertexShaderEXT GLEW_GET_FUN(__glewBindVertexShaderEXT) +#define glDeleteVertexShaderEXT GLEW_GET_FUN(__glewDeleteVertexShaderEXT) +#define glDisableVariantClientStateEXT GLEW_GET_FUN(__glewDisableVariantClientStateEXT) +#define glEnableVariantClientStateEXT GLEW_GET_FUN(__glewEnableVariantClientStateEXT) +#define glEndVertexShaderEXT GLEW_GET_FUN(__glewEndVertexShaderEXT) +#define glExtractComponentEXT GLEW_GET_FUN(__glewExtractComponentEXT) +#define glGenSymbolsEXT GLEW_GET_FUN(__glewGenSymbolsEXT) +#define glGenVertexShadersEXT GLEW_GET_FUN(__glewGenVertexShadersEXT) +#define glGetInvariantBooleanvEXT GLEW_GET_FUN(__glewGetInvariantBooleanvEXT) +#define glGetInvariantFloatvEXT GLEW_GET_FUN(__glewGetInvariantFloatvEXT) +#define glGetInvariantIntegervEXT GLEW_GET_FUN(__glewGetInvariantIntegervEXT) +#define glGetLocalConstantBooleanvEXT GLEW_GET_FUN(__glewGetLocalConstantBooleanvEXT) +#define glGetLocalConstantFloatvEXT GLEW_GET_FUN(__glewGetLocalConstantFloatvEXT) +#define glGetLocalConstantIntegervEXT GLEW_GET_FUN(__glewGetLocalConstantIntegervEXT) +#define glGetVariantBooleanvEXT GLEW_GET_FUN(__glewGetVariantBooleanvEXT) +#define glGetVariantFloatvEXT GLEW_GET_FUN(__glewGetVariantFloatvEXT) +#define glGetVariantIntegervEXT GLEW_GET_FUN(__glewGetVariantIntegervEXT) +#define glGetVariantPointervEXT GLEW_GET_FUN(__glewGetVariantPointervEXT) +#define glInsertComponentEXT GLEW_GET_FUN(__glewInsertComponentEXT) +#define glIsVariantEnabledEXT GLEW_GET_FUN(__glewIsVariantEnabledEXT) +#define glSetInvariantEXT GLEW_GET_FUN(__glewSetInvariantEXT) +#define glSetLocalConstantEXT GLEW_GET_FUN(__glewSetLocalConstantEXT) +#define glShaderOp1EXT GLEW_GET_FUN(__glewShaderOp1EXT) +#define glShaderOp2EXT GLEW_GET_FUN(__glewShaderOp2EXT) +#define glShaderOp3EXT GLEW_GET_FUN(__glewShaderOp3EXT) +#define glSwizzleEXT GLEW_GET_FUN(__glewSwizzleEXT) +#define glVariantPointerEXT GLEW_GET_FUN(__glewVariantPointerEXT) +#define glVariantbvEXT GLEW_GET_FUN(__glewVariantbvEXT) +#define glVariantdvEXT GLEW_GET_FUN(__glewVariantdvEXT) +#define glVariantfvEXT GLEW_GET_FUN(__glewVariantfvEXT) +#define glVariantivEXT GLEW_GET_FUN(__glewVariantivEXT) +#define glVariantsvEXT GLEW_GET_FUN(__glewVariantsvEXT) +#define glVariantubvEXT GLEW_GET_FUN(__glewVariantubvEXT) +#define glVariantuivEXT GLEW_GET_FUN(__glewVariantuivEXT) +#define glVariantusvEXT GLEW_GET_FUN(__glewVariantusvEXT) +#define glWriteMaskEXT GLEW_GET_FUN(__glewWriteMaskEXT) + +#define GLEW_EXT_vertex_shader GLEW_GET_VAR(__GLEW_EXT_vertex_shader) + +#endif /* GL_EXT_vertex_shader */ + +/* ------------------------ GL_EXT_vertex_weighting ------------------------ */ + +#ifndef GL_EXT_vertex_weighting +#define GL_EXT_vertex_weighting 1 + +#define GL_MODELVIEW0_STACK_DEPTH_EXT 0x0BA3 +#define GL_MODELVIEW0_MATRIX_EXT 0x0BA6 +#define GL_MODELVIEW0_EXT 0x1700 +#define GL_MODELVIEW1_STACK_DEPTH_EXT 0x8502 +#define GL_MODELVIEW1_MATRIX_EXT 0x8506 +#define GL_VERTEX_WEIGHTING_EXT 0x8509 +#define GL_MODELVIEW1_EXT 0x850A +#define GL_CURRENT_VERTEX_WEIGHT_EXT 0x850B +#define GL_VERTEX_WEIGHT_ARRAY_EXT 0x850C +#define GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT 0x850D +#define GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT 0x850E +#define GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT 0x850F +#define GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT 0x8510 + +typedef void (GLAPIENTRY * PFNGLVERTEXWEIGHTPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, void* pointer); +typedef void (GLAPIENTRY * PFNGLVERTEXWEIGHTFEXTPROC) (GLfloat weight); +typedef void (GLAPIENTRY * PFNGLVERTEXWEIGHTFVEXTPROC) (GLfloat* weight); + +#define glVertexWeightPointerEXT GLEW_GET_FUN(__glewVertexWeightPointerEXT) +#define glVertexWeightfEXT GLEW_GET_FUN(__glewVertexWeightfEXT) +#define glVertexWeightfvEXT GLEW_GET_FUN(__glewVertexWeightfvEXT) + +#define GLEW_EXT_vertex_weighting GLEW_GET_VAR(__GLEW_EXT_vertex_weighting) + +#endif /* GL_EXT_vertex_weighting */ + +/* ---------------------- GL_GREMEDY_frame_terminator ---------------------- */ + +#ifndef GL_GREMEDY_frame_terminator +#define GL_GREMEDY_frame_terminator 1 + +typedef void (GLAPIENTRY * PFNGLFRAMETERMINATORGREMEDYPROC) (void); + +#define glFrameTerminatorGREMEDY GLEW_GET_FUN(__glewFrameTerminatorGREMEDY) + +#define GLEW_GREMEDY_frame_terminator GLEW_GET_VAR(__GLEW_GREMEDY_frame_terminator) + +#endif /* GL_GREMEDY_frame_terminator */ + +/* ------------------------ GL_GREMEDY_string_marker ----------------------- */ + +#ifndef GL_GREMEDY_string_marker +#define GL_GREMEDY_string_marker 1 + +typedef void (GLAPIENTRY * PFNGLSTRINGMARKERGREMEDYPROC) (GLsizei len, const void* string); + +#define glStringMarkerGREMEDY GLEW_GET_FUN(__glewStringMarkerGREMEDY) + +#define GLEW_GREMEDY_string_marker GLEW_GET_VAR(__GLEW_GREMEDY_string_marker) + +#endif /* GL_GREMEDY_string_marker */ + +/* --------------------- GL_HP_convolution_border_modes -------------------- */ + +#ifndef GL_HP_convolution_border_modes +#define GL_HP_convolution_border_modes 1 + +#define GLEW_HP_convolution_border_modes GLEW_GET_VAR(__GLEW_HP_convolution_border_modes) + +#endif /* GL_HP_convolution_border_modes */ + +/* ------------------------- GL_HP_image_transform ------------------------- */ + +#ifndef GL_HP_image_transform +#define GL_HP_image_transform 1 + +typedef void (GLAPIENTRY * PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLIMAGETRANSFORMPARAMETERFHPPROC) (GLenum target, GLenum pname, const GLfloat param); +typedef void (GLAPIENTRY * PFNGLIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLIMAGETRANSFORMPARAMETERIHPPROC) (GLenum target, GLenum pname, const GLint param); +typedef void (GLAPIENTRY * PFNGLIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, const GLint* params); + +#define glGetImageTransformParameterfvHP GLEW_GET_FUN(__glewGetImageTransformParameterfvHP) +#define glGetImageTransformParameterivHP GLEW_GET_FUN(__glewGetImageTransformParameterivHP) +#define glImageTransformParameterfHP GLEW_GET_FUN(__glewImageTransformParameterfHP) +#define glImageTransformParameterfvHP GLEW_GET_FUN(__glewImageTransformParameterfvHP) +#define glImageTransformParameteriHP GLEW_GET_FUN(__glewImageTransformParameteriHP) +#define glImageTransformParameterivHP GLEW_GET_FUN(__glewImageTransformParameterivHP) + +#define GLEW_HP_image_transform GLEW_GET_VAR(__GLEW_HP_image_transform) + +#endif /* GL_HP_image_transform */ + +/* -------------------------- GL_HP_occlusion_test ------------------------- */ + +#ifndef GL_HP_occlusion_test +#define GL_HP_occlusion_test 1 + +#define GL_OCCLUSION_TEST_HP 0x8165 +#define GL_OCCLUSION_TEST_RESULT_HP 0x8166 + +#define GLEW_HP_occlusion_test GLEW_GET_VAR(__GLEW_HP_occlusion_test) + +#endif /* GL_HP_occlusion_test */ + +/* ------------------------- GL_HP_texture_lighting ------------------------ */ + +#ifndef GL_HP_texture_lighting +#define GL_HP_texture_lighting 1 + +#define GLEW_HP_texture_lighting GLEW_GET_VAR(__GLEW_HP_texture_lighting) + +#endif /* GL_HP_texture_lighting */ + +/* --------------------------- GL_IBM_cull_vertex -------------------------- */ + +#ifndef GL_IBM_cull_vertex +#define GL_IBM_cull_vertex 1 + +#define GL_CULL_VERTEX_IBM 103050 + +#define GLEW_IBM_cull_vertex GLEW_GET_VAR(__GLEW_IBM_cull_vertex) + +#endif /* GL_IBM_cull_vertex */ + +/* ---------------------- GL_IBM_multimode_draw_arrays --------------------- */ + +#ifndef GL_IBM_multimode_draw_arrays +#define GL_IBM_multimode_draw_arrays 1 + +typedef void (GLAPIENTRY * PFNGLMULTIMODEDRAWARRAYSIBMPROC) (const GLenum* mode, const GLint *first, const GLsizei *count, GLsizei primcount, GLint modestride); +typedef void (GLAPIENTRY * PFNGLMULTIMODEDRAWELEMENTSIBMPROC) (const GLenum* mode, const GLsizei *count, GLenum type, const GLvoid * const *indices, GLsizei primcount, GLint modestride); + +#define glMultiModeDrawArraysIBM GLEW_GET_FUN(__glewMultiModeDrawArraysIBM) +#define glMultiModeDrawElementsIBM GLEW_GET_FUN(__glewMultiModeDrawElementsIBM) + +#define GLEW_IBM_multimode_draw_arrays GLEW_GET_VAR(__GLEW_IBM_multimode_draw_arrays) + +#endif /* GL_IBM_multimode_draw_arrays */ + +/* ------------------------- GL_IBM_rasterpos_clip ------------------------- */ + +#ifndef GL_IBM_rasterpos_clip +#define GL_IBM_rasterpos_clip 1 + +#define GL_RASTER_POSITION_UNCLIPPED_IBM 103010 + +#define GLEW_IBM_rasterpos_clip GLEW_GET_VAR(__GLEW_IBM_rasterpos_clip) + +#endif /* GL_IBM_rasterpos_clip */ + +/* --------------------------- GL_IBM_static_data -------------------------- */ + +#ifndef GL_IBM_static_data +#define GL_IBM_static_data 1 + +#define GL_ALL_STATIC_DATA_IBM 103060 +#define GL_STATIC_VERTEX_ARRAY_IBM 103061 + +#define GLEW_IBM_static_data GLEW_GET_VAR(__GLEW_IBM_static_data) + +#endif /* GL_IBM_static_data */ + +/* --------------------- GL_IBM_texture_mirrored_repeat -------------------- */ + +#ifndef GL_IBM_texture_mirrored_repeat +#define GL_IBM_texture_mirrored_repeat 1 + +#define GL_MIRRORED_REPEAT_IBM 0x8370 + +#define GLEW_IBM_texture_mirrored_repeat GLEW_GET_VAR(__GLEW_IBM_texture_mirrored_repeat) + +#endif /* GL_IBM_texture_mirrored_repeat */ + +/* ----------------------- GL_IBM_vertex_array_lists ----------------------- */ + +#ifndef GL_IBM_vertex_array_lists +#define GL_IBM_vertex_array_lists 1 + +#define GL_VERTEX_ARRAY_LIST_IBM 103070 +#define GL_NORMAL_ARRAY_LIST_IBM 103071 +#define GL_COLOR_ARRAY_LIST_IBM 103072 +#define GL_INDEX_ARRAY_LIST_IBM 103073 +#define GL_TEXTURE_COORD_ARRAY_LIST_IBM 103074 +#define GL_EDGE_FLAG_ARRAY_LIST_IBM 103075 +#define GL_FOG_COORDINATE_ARRAY_LIST_IBM 103076 +#define GL_SECONDARY_COLOR_ARRAY_LIST_IBM 103077 +#define GL_VERTEX_ARRAY_LIST_STRIDE_IBM 103080 +#define GL_NORMAL_ARRAY_LIST_STRIDE_IBM 103081 +#define GL_COLOR_ARRAY_LIST_STRIDE_IBM 103082 +#define GL_INDEX_ARRAY_LIST_STRIDE_IBM 103083 +#define GL_TEXTURE_COORD_ARRAY_LIST_STRIDE_IBM 103084 +#define GL_EDGE_FLAG_ARRAY_LIST_STRIDE_IBM 103085 +#define GL_FOG_COORDINATE_ARRAY_LIST_STRIDE_IBM 103086 +#define GL_SECONDARY_COLOR_ARRAY_LIST_STRIDE_IBM 103087 + +typedef void (GLAPIENTRY * PFNGLCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid ** pointer, GLint ptrstride); +typedef void (GLAPIENTRY * PFNGLEDGEFLAGPOINTERLISTIBMPROC) (GLint stride, const GLboolean ** pointer, GLint ptrstride); +typedef void (GLAPIENTRY * PFNGLFOGCOORDPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid ** pointer, GLint ptrstride); +typedef void (GLAPIENTRY * PFNGLINDEXPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid ** pointer, GLint ptrstride); +typedef void (GLAPIENTRY * PFNGLNORMALPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid ** pointer, GLint ptrstride); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid ** pointer, GLint ptrstride); +typedef void (GLAPIENTRY * PFNGLTEXCOORDPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid ** pointer, GLint ptrstride); +typedef void (GLAPIENTRY * PFNGLVERTEXPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid ** pointer, GLint ptrstride); + +#define glColorPointerListIBM GLEW_GET_FUN(__glewColorPointerListIBM) +#define glEdgeFlagPointerListIBM GLEW_GET_FUN(__glewEdgeFlagPointerListIBM) +#define glFogCoordPointerListIBM GLEW_GET_FUN(__glewFogCoordPointerListIBM) +#define glIndexPointerListIBM GLEW_GET_FUN(__glewIndexPointerListIBM) +#define glNormalPointerListIBM GLEW_GET_FUN(__glewNormalPointerListIBM) +#define glSecondaryColorPointerListIBM GLEW_GET_FUN(__glewSecondaryColorPointerListIBM) +#define glTexCoordPointerListIBM GLEW_GET_FUN(__glewTexCoordPointerListIBM) +#define glVertexPointerListIBM GLEW_GET_FUN(__glewVertexPointerListIBM) + +#define GLEW_IBM_vertex_array_lists GLEW_GET_VAR(__GLEW_IBM_vertex_array_lists) + +#endif /* GL_IBM_vertex_array_lists */ + +/* -------------------------- GL_INGR_color_clamp -------------------------- */ + +#ifndef GL_INGR_color_clamp +#define GL_INGR_color_clamp 1 + +#define GL_RED_MIN_CLAMP_INGR 0x8560 +#define GL_GREEN_MIN_CLAMP_INGR 0x8561 +#define GL_BLUE_MIN_CLAMP_INGR 0x8562 +#define GL_ALPHA_MIN_CLAMP_INGR 0x8563 +#define GL_RED_MAX_CLAMP_INGR 0x8564 +#define GL_GREEN_MAX_CLAMP_INGR 0x8565 +#define GL_BLUE_MAX_CLAMP_INGR 0x8566 +#define GL_ALPHA_MAX_CLAMP_INGR 0x8567 + +#define GLEW_INGR_color_clamp GLEW_GET_VAR(__GLEW_INGR_color_clamp) + +#endif /* GL_INGR_color_clamp */ + +/* ------------------------- GL_INGR_interlace_read ------------------------ */ + +#ifndef GL_INGR_interlace_read +#define GL_INGR_interlace_read 1 + +#define GL_INTERLACE_READ_INGR 0x8568 + +#define GLEW_INGR_interlace_read GLEW_GET_VAR(__GLEW_INGR_interlace_read) + +#endif /* GL_INGR_interlace_read */ + +/* ------------------------ GL_INTEL_parallel_arrays ----------------------- */ + +#ifndef GL_INTEL_parallel_arrays +#define GL_INTEL_parallel_arrays 1 + +#define GL_PARALLEL_ARRAYS_INTEL 0x83F4 +#define GL_VERTEX_ARRAY_PARALLEL_POINTERS_INTEL 0x83F5 +#define GL_NORMAL_ARRAY_PARALLEL_POINTERS_INTEL 0x83F6 +#define GL_COLOR_ARRAY_PARALLEL_POINTERS_INTEL 0x83F7 +#define GL_TEXTURE_COORD_ARRAY_PARALLEL_POINTERS_INTEL 0x83F8 + +typedef void (GLAPIENTRY * PFNGLCOLORPOINTERVINTELPROC) (GLint size, GLenum type, const void** pointer); +typedef void (GLAPIENTRY * PFNGLNORMALPOINTERVINTELPROC) (GLenum type, const void** pointer); +typedef void (GLAPIENTRY * PFNGLTEXCOORDPOINTERVINTELPROC) (GLint size, GLenum type, const void** pointer); +typedef void (GLAPIENTRY * PFNGLVERTEXPOINTERVINTELPROC) (GLint size, GLenum type, const void** pointer); + +#define glColorPointervINTEL GLEW_GET_FUN(__glewColorPointervINTEL) +#define glNormalPointervINTEL GLEW_GET_FUN(__glewNormalPointervINTEL) +#define glTexCoordPointervINTEL GLEW_GET_FUN(__glewTexCoordPointervINTEL) +#define glVertexPointervINTEL GLEW_GET_FUN(__glewVertexPointervINTEL) + +#define GLEW_INTEL_parallel_arrays GLEW_GET_VAR(__GLEW_INTEL_parallel_arrays) + +#endif /* GL_INTEL_parallel_arrays */ + +/* ------------------------ GL_INTEL_texture_scissor ----------------------- */ + +#ifndef GL_INTEL_texture_scissor +#define GL_INTEL_texture_scissor 1 + +typedef void (GLAPIENTRY * PFNGLTEXSCISSORFUNCINTELPROC) (GLenum target, GLenum lfunc, GLenum hfunc); +typedef void (GLAPIENTRY * PFNGLTEXSCISSORINTELPROC) (GLenum target, GLclampf tlow, GLclampf thigh); + +#define glTexScissorFuncINTEL GLEW_GET_FUN(__glewTexScissorFuncINTEL) +#define glTexScissorINTEL GLEW_GET_FUN(__glewTexScissorINTEL) + +#define GLEW_INTEL_texture_scissor GLEW_GET_VAR(__GLEW_INTEL_texture_scissor) + +#endif /* GL_INTEL_texture_scissor */ + +/* -------------------------- GL_KTX_buffer_region ------------------------- */ + +#ifndef GL_KTX_buffer_region +#define GL_KTX_buffer_region 1 + +#define GL_KTX_FRONT_REGION 0x0 +#define GL_KTX_BACK_REGION 0x1 +#define GL_KTX_Z_REGION 0x2 +#define GL_KTX_STENCIL_REGION 0x3 + +typedef GLuint (GLAPIENTRY * PFNGLBUFFERREGIONENABLEDEXTPROC) (void); +typedef void (GLAPIENTRY * PFNGLDELETEBUFFERREGIONEXTPROC) (GLenum region); +typedef void (GLAPIENTRY * PFNGLDRAWBUFFERREGIONEXTPROC) (GLuint region, GLint x, GLint y, GLsizei width, GLsizei height, GLint xDest, GLint yDest); +typedef GLuint (GLAPIENTRY * PFNGLNEWBUFFERREGIONEXTPROC) (GLenum region); +typedef void (GLAPIENTRY * PFNGLREADBUFFERREGIONEXTPROC) (GLuint region, GLint x, GLint y, GLsizei width, GLsizei height); + +#define glBufferRegionEnabledEXT GLEW_GET_FUN(__glewBufferRegionEnabledEXT) +#define glDeleteBufferRegionEXT GLEW_GET_FUN(__glewDeleteBufferRegionEXT) +#define glDrawBufferRegionEXT GLEW_GET_FUN(__glewDrawBufferRegionEXT) +#define glNewBufferRegionEXT GLEW_GET_FUN(__glewNewBufferRegionEXT) +#define glReadBufferRegionEXT GLEW_GET_FUN(__glewReadBufferRegionEXT) + +#define GLEW_KTX_buffer_region GLEW_GET_VAR(__GLEW_KTX_buffer_region) + +#endif /* GL_KTX_buffer_region */ + +/* ------------------------- GL_MESAX_texture_stack ------------------------ */ + +#ifndef GL_MESAX_texture_stack +#define GL_MESAX_texture_stack 1 + +#define GL_TEXTURE_1D_STACK_MESAX 0x8759 +#define GL_TEXTURE_2D_STACK_MESAX 0x875A +#define GL_PROXY_TEXTURE_1D_STACK_MESAX 0x875B +#define GL_PROXY_TEXTURE_2D_STACK_MESAX 0x875C +#define GL_TEXTURE_1D_STACK_BINDING_MESAX 0x875D +#define GL_TEXTURE_2D_STACK_BINDING_MESAX 0x875E + +#define GLEW_MESAX_texture_stack GLEW_GET_VAR(__GLEW_MESAX_texture_stack) + +#endif /* GL_MESAX_texture_stack */ + +/* -------------------------- GL_MESA_pack_invert -------------------------- */ + +#ifndef GL_MESA_pack_invert +#define GL_MESA_pack_invert 1 + +#define GL_PACK_INVERT_MESA 0x8758 + +#define GLEW_MESA_pack_invert GLEW_GET_VAR(__GLEW_MESA_pack_invert) + +#endif /* GL_MESA_pack_invert */ + +/* ------------------------- GL_MESA_resize_buffers ------------------------ */ + +#ifndef GL_MESA_resize_buffers +#define GL_MESA_resize_buffers 1 + +typedef void (GLAPIENTRY * PFNGLRESIZEBUFFERSMESAPROC) (void); + +#define glResizeBuffersMESA GLEW_GET_FUN(__glewResizeBuffersMESA) + +#define GLEW_MESA_resize_buffers GLEW_GET_VAR(__GLEW_MESA_resize_buffers) + +#endif /* GL_MESA_resize_buffers */ + +/* --------------------------- GL_MESA_window_pos -------------------------- */ + +#ifndef GL_MESA_window_pos +#define GL_MESA_window_pos 1 + +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DMESAPROC) (GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DVMESAPROC) (const GLdouble* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FMESAPROC) (GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FVMESAPROC) (const GLfloat* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IMESAPROC) (GLint x, GLint y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IVMESAPROC) (const GLint* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SMESAPROC) (GLshort x, GLshort y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SVMESAPROC) (const GLshort* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DMESAPROC) (GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DVMESAPROC) (const GLdouble* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FMESAPROC) (GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FVMESAPROC) (const GLfloat* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IMESAPROC) (GLint x, GLint y, GLint z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IVMESAPROC) (const GLint* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SMESAPROC) (GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SVMESAPROC) (const GLshort* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS4DMESAPROC) (GLdouble x, GLdouble y, GLdouble z, GLdouble); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS4DVMESAPROC) (const GLdouble* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS4FMESAPROC) (GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS4FVMESAPROC) (const GLfloat* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS4IMESAPROC) (GLint x, GLint y, GLint z, GLint w); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS4IVMESAPROC) (const GLint* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS4SMESAPROC) (GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS4SVMESAPROC) (const GLshort* p); + +#define glWindowPos2dMESA GLEW_GET_FUN(__glewWindowPos2dMESA) +#define glWindowPos2dvMESA GLEW_GET_FUN(__glewWindowPos2dvMESA) +#define glWindowPos2fMESA GLEW_GET_FUN(__glewWindowPos2fMESA) +#define glWindowPos2fvMESA GLEW_GET_FUN(__glewWindowPos2fvMESA) +#define glWindowPos2iMESA GLEW_GET_FUN(__glewWindowPos2iMESA) +#define glWindowPos2ivMESA GLEW_GET_FUN(__glewWindowPos2ivMESA) +#define glWindowPos2sMESA GLEW_GET_FUN(__glewWindowPos2sMESA) +#define glWindowPos2svMESA GLEW_GET_FUN(__glewWindowPos2svMESA) +#define glWindowPos3dMESA GLEW_GET_FUN(__glewWindowPos3dMESA) +#define glWindowPos3dvMESA GLEW_GET_FUN(__glewWindowPos3dvMESA) +#define glWindowPos3fMESA GLEW_GET_FUN(__glewWindowPos3fMESA) +#define glWindowPos3fvMESA GLEW_GET_FUN(__glewWindowPos3fvMESA) +#define glWindowPos3iMESA GLEW_GET_FUN(__glewWindowPos3iMESA) +#define glWindowPos3ivMESA GLEW_GET_FUN(__glewWindowPos3ivMESA) +#define glWindowPos3sMESA GLEW_GET_FUN(__glewWindowPos3sMESA) +#define glWindowPos3svMESA GLEW_GET_FUN(__glewWindowPos3svMESA) +#define glWindowPos4dMESA GLEW_GET_FUN(__glewWindowPos4dMESA) +#define glWindowPos4dvMESA GLEW_GET_FUN(__glewWindowPos4dvMESA) +#define glWindowPos4fMESA GLEW_GET_FUN(__glewWindowPos4fMESA) +#define glWindowPos4fvMESA GLEW_GET_FUN(__glewWindowPos4fvMESA) +#define glWindowPos4iMESA GLEW_GET_FUN(__glewWindowPos4iMESA) +#define glWindowPos4ivMESA GLEW_GET_FUN(__glewWindowPos4ivMESA) +#define glWindowPos4sMESA GLEW_GET_FUN(__glewWindowPos4sMESA) +#define glWindowPos4svMESA GLEW_GET_FUN(__glewWindowPos4svMESA) + +#define GLEW_MESA_window_pos GLEW_GET_VAR(__GLEW_MESA_window_pos) + +#endif /* GL_MESA_window_pos */ + +/* ------------------------- GL_MESA_ycbcr_texture ------------------------- */ + +#ifndef GL_MESA_ycbcr_texture +#define GL_MESA_ycbcr_texture 1 + +#define GL_UNSIGNED_SHORT_8_8_MESA 0x85BA +#define GL_UNSIGNED_SHORT_8_8_REV_MESA 0x85BB +#define GL_YCBCR_MESA 0x8757 + +#define GLEW_MESA_ycbcr_texture GLEW_GET_VAR(__GLEW_MESA_ycbcr_texture) + +#endif /* GL_MESA_ycbcr_texture */ + +/* --------------------------- GL_NV_blend_square -------------------------- */ + +#ifndef GL_NV_blend_square +#define GL_NV_blend_square 1 + +#define GLEW_NV_blend_square GLEW_GET_VAR(__GLEW_NV_blend_square) + +#endif /* GL_NV_blend_square */ + +/* ------------------------ GL_NV_conditional_render ----------------------- */ + +#ifndef GL_NV_conditional_render +#define GL_NV_conditional_render 1 + +#define GL_QUERY_WAIT_NV 0x8E13 +#define GL_QUERY_NO_WAIT_NV 0x8E14 +#define GL_QUERY_BY_REGION_WAIT_NV 0x8E15 +#define GL_QUERY_BY_REGION_NO_WAIT_NV 0x8E16 + +typedef void (GLAPIENTRY * PFNGLBEGINCONDITIONALRENDERNVPROC) (GLuint id, GLenum mode); +typedef void (GLAPIENTRY * PFNGLENDCONDITIONALRENDERNVPROC) (void); + +#define glBeginConditionalRenderNV GLEW_GET_FUN(__glewBeginConditionalRenderNV) +#define glEndConditionalRenderNV GLEW_GET_FUN(__glewEndConditionalRenderNV) + +#define GLEW_NV_conditional_render GLEW_GET_VAR(__GLEW_NV_conditional_render) + +#endif /* GL_NV_conditional_render */ + +/* ----------------------- GL_NV_copy_depth_to_color ----------------------- */ + +#ifndef GL_NV_copy_depth_to_color +#define GL_NV_copy_depth_to_color 1 + +#define GL_DEPTH_STENCIL_TO_RGBA_NV 0x886E +#define GL_DEPTH_STENCIL_TO_BGRA_NV 0x886F + +#define GLEW_NV_copy_depth_to_color GLEW_GET_VAR(__GLEW_NV_copy_depth_to_color) + +#endif /* GL_NV_copy_depth_to_color */ + +/* ------------------------ GL_NV_depth_buffer_float ----------------------- */ + +#ifndef GL_NV_depth_buffer_float +#define GL_NV_depth_buffer_float 1 + +#define GL_DEPTH_COMPONENT32F_NV 0x8DAB +#define GL_DEPTH32F_STENCIL8_NV 0x8DAC +#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV_NV 0x8DAD +#define GL_DEPTH_BUFFER_FLOAT_MODE_NV 0x8DAF + +typedef void (GLAPIENTRY * PFNGLCLEARDEPTHDNVPROC) (GLdouble depth); +typedef void (GLAPIENTRY * PFNGLDEPTHBOUNDSDNVPROC) (GLdouble zmin, GLdouble zmax); +typedef void (GLAPIENTRY * PFNGLDEPTHRANGEDNVPROC) (GLdouble zNear, GLdouble zFar); + +#define glClearDepthdNV GLEW_GET_FUN(__glewClearDepthdNV) +#define glDepthBoundsdNV GLEW_GET_FUN(__glewDepthBoundsdNV) +#define glDepthRangedNV GLEW_GET_FUN(__glewDepthRangedNV) + +#define GLEW_NV_depth_buffer_float GLEW_GET_VAR(__GLEW_NV_depth_buffer_float) + +#endif /* GL_NV_depth_buffer_float */ + +/* --------------------------- GL_NV_depth_clamp --------------------------- */ + +#ifndef GL_NV_depth_clamp +#define GL_NV_depth_clamp 1 + +#define GL_DEPTH_CLAMP_NV 0x864F + +#define GLEW_NV_depth_clamp GLEW_GET_VAR(__GLEW_NV_depth_clamp) + +#endif /* GL_NV_depth_clamp */ + +/* ---------------------- GL_NV_depth_range_unclamped ---------------------- */ + +#ifndef GL_NV_depth_range_unclamped +#define GL_NV_depth_range_unclamped 1 + +#define GL_SAMPLE_COUNT_BITS_NV 0x8864 +#define GL_CURRENT_SAMPLE_COUNT_QUERY_NV 0x8865 +#define GL_QUERY_RESULT_NV 0x8866 +#define GL_QUERY_RESULT_AVAILABLE_NV 0x8867 +#define GL_SAMPLE_COUNT_NV 0x8914 + +#define GLEW_NV_depth_range_unclamped GLEW_GET_VAR(__GLEW_NV_depth_range_unclamped) + +#endif /* GL_NV_depth_range_unclamped */ + +/* ---------------------------- GL_NV_evaluators --------------------------- */ + +#ifndef GL_NV_evaluators +#define GL_NV_evaluators 1 + +#define GL_EVAL_2D_NV 0x86C0 +#define GL_EVAL_TRIANGULAR_2D_NV 0x86C1 +#define GL_MAP_TESSELLATION_NV 0x86C2 +#define GL_MAP_ATTRIB_U_ORDER_NV 0x86C3 +#define GL_MAP_ATTRIB_V_ORDER_NV 0x86C4 +#define GL_EVAL_FRACTIONAL_TESSELLATION_NV 0x86C5 +#define GL_EVAL_VERTEX_ATTRIB0_NV 0x86C6 +#define GL_EVAL_VERTEX_ATTRIB1_NV 0x86C7 +#define GL_EVAL_VERTEX_ATTRIB2_NV 0x86C8 +#define GL_EVAL_VERTEX_ATTRIB3_NV 0x86C9 +#define GL_EVAL_VERTEX_ATTRIB4_NV 0x86CA +#define GL_EVAL_VERTEX_ATTRIB5_NV 0x86CB +#define GL_EVAL_VERTEX_ATTRIB6_NV 0x86CC +#define GL_EVAL_VERTEX_ATTRIB7_NV 0x86CD +#define GL_EVAL_VERTEX_ATTRIB8_NV 0x86CE +#define GL_EVAL_VERTEX_ATTRIB9_NV 0x86CF +#define GL_EVAL_VERTEX_ATTRIB10_NV 0x86D0 +#define GL_EVAL_VERTEX_ATTRIB11_NV 0x86D1 +#define GL_EVAL_VERTEX_ATTRIB12_NV 0x86D2 +#define GL_EVAL_VERTEX_ATTRIB13_NV 0x86D3 +#define GL_EVAL_VERTEX_ATTRIB14_NV 0x86D4 +#define GL_EVAL_VERTEX_ATTRIB15_NV 0x86D5 +#define GL_MAX_MAP_TESSELLATION_NV 0x86D6 +#define GL_MAX_RATIONAL_EVAL_ORDER_NV 0x86D7 + +typedef void (GLAPIENTRY * PFNGLEVALMAPSNVPROC) (GLenum target, GLenum mode); +typedef void (GLAPIENTRY * PFNGLGETMAPATTRIBPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETMAPATTRIBPARAMETERIVNVPROC) (GLenum target, GLuint index, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLboolean packed, void* points); +typedef void (GLAPIENTRY * PFNGLGETMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLint uorder, GLint vorder, GLboolean packed, const void* points); +typedef void (GLAPIENTRY * PFNGLMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, const GLint* params); + +#define glEvalMapsNV GLEW_GET_FUN(__glewEvalMapsNV) +#define glGetMapAttribParameterfvNV GLEW_GET_FUN(__glewGetMapAttribParameterfvNV) +#define glGetMapAttribParameterivNV GLEW_GET_FUN(__glewGetMapAttribParameterivNV) +#define glGetMapControlPointsNV GLEW_GET_FUN(__glewGetMapControlPointsNV) +#define glGetMapParameterfvNV GLEW_GET_FUN(__glewGetMapParameterfvNV) +#define glGetMapParameterivNV GLEW_GET_FUN(__glewGetMapParameterivNV) +#define glMapControlPointsNV GLEW_GET_FUN(__glewMapControlPointsNV) +#define glMapParameterfvNV GLEW_GET_FUN(__glewMapParameterfvNV) +#define glMapParameterivNV GLEW_GET_FUN(__glewMapParameterivNV) + +#define GLEW_NV_evaluators GLEW_GET_VAR(__GLEW_NV_evaluators) + +#endif /* GL_NV_evaluators */ + +/* ----------------------- GL_NV_explicit_multisample ---------------------- */ + +#ifndef GL_NV_explicit_multisample +#define GL_NV_explicit_multisample 1 + +#define GL_SAMPLE_POSITION_NV 0x8E50 +#define GL_SAMPLE_MASK_NV 0x8E51 +#define GL_SAMPLE_MASK_VALUE_NV 0x8E52 +#define GL_TEXTURE_BINDING_RENDERBUFFER_NV 0x8E53 +#define GL_TEXTURE_RENDERBUFFER_DATA_STORE_BINDING_NV 0x8E54 +#define GL_TEXTURE_RENDERBUFFER_NV 0x8E55 +#define GL_SAMPLER_RENDERBUFFER_NV 0x8E56 +#define GL_INT_SAMPLER_RENDERBUFFER_NV 0x8E57 +#define GL_UNSIGNED_INT_SAMPLER_RENDERBUFFER_NV 0x8E58 +#define GL_MAX_SAMPLE_MASK_WORDS_NV 0x8E59 + +typedef void (GLAPIENTRY * PFNGLGETMULTISAMPLEFVNVPROC) (GLenum pname, GLuint index, GLfloat* val); +typedef void (GLAPIENTRY * PFNGLSAMPLEMASKINDEXEDNVPROC) (GLuint index, GLbitfield mask); +typedef void (GLAPIENTRY * PFNGLTEXRENDERBUFFERNVPROC) (GLenum target, GLuint renderbuffer); + +#define glGetMultisamplefvNV GLEW_GET_FUN(__glewGetMultisamplefvNV) +#define glSampleMaskIndexedNV GLEW_GET_FUN(__glewSampleMaskIndexedNV) +#define glTexRenderbufferNV GLEW_GET_FUN(__glewTexRenderbufferNV) + +#define GLEW_NV_explicit_multisample GLEW_GET_VAR(__GLEW_NV_explicit_multisample) + +#endif /* GL_NV_explicit_multisample */ + +/* ------------------------------ GL_NV_fence ------------------------------ */ + +#ifndef GL_NV_fence +#define GL_NV_fence 1 + +#define GL_ALL_COMPLETED_NV 0x84F2 +#define GL_FENCE_STATUS_NV 0x84F3 +#define GL_FENCE_CONDITION_NV 0x84F4 + +typedef void (GLAPIENTRY * PFNGLDELETEFENCESNVPROC) (GLsizei n, const GLuint* fences); +typedef void (GLAPIENTRY * PFNGLFINISHFENCENVPROC) (GLuint fence); +typedef void (GLAPIENTRY * PFNGLGENFENCESNVPROC) (GLsizei n, GLuint* fences); +typedef void (GLAPIENTRY * PFNGLGETFENCEIVNVPROC) (GLuint fence, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISFENCENVPROC) (GLuint fence); +typedef void (GLAPIENTRY * PFNGLSETFENCENVPROC) (GLuint fence, GLenum condition); +typedef GLboolean (GLAPIENTRY * PFNGLTESTFENCENVPROC) (GLuint fence); + +#define glDeleteFencesNV GLEW_GET_FUN(__glewDeleteFencesNV) +#define glFinishFenceNV GLEW_GET_FUN(__glewFinishFenceNV) +#define glGenFencesNV GLEW_GET_FUN(__glewGenFencesNV) +#define glGetFenceivNV GLEW_GET_FUN(__glewGetFenceivNV) +#define glIsFenceNV GLEW_GET_FUN(__glewIsFenceNV) +#define glSetFenceNV GLEW_GET_FUN(__glewSetFenceNV) +#define glTestFenceNV GLEW_GET_FUN(__glewTestFenceNV) + +#define GLEW_NV_fence GLEW_GET_VAR(__GLEW_NV_fence) + +#endif /* GL_NV_fence */ + +/* --------------------------- GL_NV_float_buffer -------------------------- */ + +#ifndef GL_NV_float_buffer +#define GL_NV_float_buffer 1 + +#define GL_FLOAT_R_NV 0x8880 +#define GL_FLOAT_RG_NV 0x8881 +#define GL_FLOAT_RGB_NV 0x8882 +#define GL_FLOAT_RGBA_NV 0x8883 +#define GL_FLOAT_R16_NV 0x8884 +#define GL_FLOAT_R32_NV 0x8885 +#define GL_FLOAT_RG16_NV 0x8886 +#define GL_FLOAT_RG32_NV 0x8887 +#define GL_FLOAT_RGB16_NV 0x8888 +#define GL_FLOAT_RGB32_NV 0x8889 +#define GL_FLOAT_RGBA16_NV 0x888A +#define GL_FLOAT_RGBA32_NV 0x888B +#define GL_TEXTURE_FLOAT_COMPONENTS_NV 0x888C +#define GL_FLOAT_CLEAR_COLOR_VALUE_NV 0x888D +#define GL_FLOAT_RGBA_MODE_NV 0x888E + +#define GLEW_NV_float_buffer GLEW_GET_VAR(__GLEW_NV_float_buffer) + +#endif /* GL_NV_float_buffer */ + +/* --------------------------- GL_NV_fog_distance -------------------------- */ + +#ifndef GL_NV_fog_distance +#define GL_NV_fog_distance 1 + +#define GL_FOG_DISTANCE_MODE_NV 0x855A +#define GL_EYE_RADIAL_NV 0x855B +#define GL_EYE_PLANE_ABSOLUTE_NV 0x855C + +#define GLEW_NV_fog_distance GLEW_GET_VAR(__GLEW_NV_fog_distance) + +#endif /* GL_NV_fog_distance */ + +/* ------------------------- GL_NV_fragment_program ------------------------ */ + +#ifndef GL_NV_fragment_program +#define GL_NV_fragment_program 1 + +#define GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV 0x8868 +#define GL_FRAGMENT_PROGRAM_NV 0x8870 +#define GL_MAX_TEXTURE_COORDS_NV 0x8871 +#define GL_MAX_TEXTURE_IMAGE_UNITS_NV 0x8872 +#define GL_FRAGMENT_PROGRAM_BINDING_NV 0x8873 +#define GL_PROGRAM_ERROR_STRING_NV 0x8874 + +typedef void (GLAPIENTRY * PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC) (GLuint id, GLsizei len, const GLubyte* name, GLdouble *params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC) (GLuint id, GLsizei len, const GLubyte* name, GLfloat *params); +typedef void (GLAPIENTRY * PFNGLPROGRAMNAMEDPARAMETER4DNVPROC) (GLuint id, GLsizei len, const GLubyte* name, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC) (GLuint id, GLsizei len, const GLubyte* name, const GLdouble v[]); +typedef void (GLAPIENTRY * PFNGLPROGRAMNAMEDPARAMETER4FNVPROC) (GLuint id, GLsizei len, const GLubyte* name, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC) (GLuint id, GLsizei len, const GLubyte* name, const GLfloat v[]); + +#define glGetProgramNamedParameterdvNV GLEW_GET_FUN(__glewGetProgramNamedParameterdvNV) +#define glGetProgramNamedParameterfvNV GLEW_GET_FUN(__glewGetProgramNamedParameterfvNV) +#define glProgramNamedParameter4dNV GLEW_GET_FUN(__glewProgramNamedParameter4dNV) +#define glProgramNamedParameter4dvNV GLEW_GET_FUN(__glewProgramNamedParameter4dvNV) +#define glProgramNamedParameter4fNV GLEW_GET_FUN(__glewProgramNamedParameter4fNV) +#define glProgramNamedParameter4fvNV GLEW_GET_FUN(__glewProgramNamedParameter4fvNV) + +#define GLEW_NV_fragment_program GLEW_GET_VAR(__GLEW_NV_fragment_program) + +#endif /* GL_NV_fragment_program */ + +/* ------------------------ GL_NV_fragment_program2 ------------------------ */ + +#ifndef GL_NV_fragment_program2 +#define GL_NV_fragment_program2 1 + +#define GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV 0x88F4 +#define GL_MAX_PROGRAM_CALL_DEPTH_NV 0x88F5 +#define GL_MAX_PROGRAM_IF_DEPTH_NV 0x88F6 +#define GL_MAX_PROGRAM_LOOP_DEPTH_NV 0x88F7 +#define GL_MAX_PROGRAM_LOOP_COUNT_NV 0x88F8 + +#define GLEW_NV_fragment_program2 GLEW_GET_VAR(__GLEW_NV_fragment_program2) + +#endif /* GL_NV_fragment_program2 */ + +/* ------------------------ GL_NV_fragment_program4 ------------------------ */ + +#ifndef GL_NV_fragment_program4 +#define GL_NV_fragment_program4 1 + +#define GLEW_NV_fragment_program4 GLEW_GET_VAR(__GLEW_NV_fragment_program4) + +#endif /* GL_NV_fragment_program4 */ + +/* --------------------- GL_NV_fragment_program_option --------------------- */ + +#ifndef GL_NV_fragment_program_option +#define GL_NV_fragment_program_option 1 + +#define GLEW_NV_fragment_program_option GLEW_GET_VAR(__GLEW_NV_fragment_program_option) + +#endif /* GL_NV_fragment_program_option */ + +/* ----------------- GL_NV_framebuffer_multisample_coverage ---------------- */ + +#ifndef GL_NV_framebuffer_multisample_coverage +#define GL_NV_framebuffer_multisample_coverage 1 + +#define GL_RENDERBUFFER_COVERAGE_SAMPLES_NV 0x8CAB +#define GL_RENDERBUFFER_COLOR_SAMPLES_NV 0x8E10 +#define GL_MAX_MULTISAMPLE_COVERAGE_MODES_NV 0x8E11 +#define GL_MULTISAMPLE_COVERAGE_MODES_NV 0x8E12 + +typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); + +#define glRenderbufferStorageMultisampleCoverageNV GLEW_GET_FUN(__glewRenderbufferStorageMultisampleCoverageNV) + +#define GLEW_NV_framebuffer_multisample_coverage GLEW_GET_VAR(__GLEW_NV_framebuffer_multisample_coverage) + +#endif /* GL_NV_framebuffer_multisample_coverage */ + +/* ------------------------ GL_NV_geometry_program4 ------------------------ */ + +#ifndef GL_NV_geometry_program4 +#define GL_NV_geometry_program4 1 + +#define GL_GEOMETRY_PROGRAM_NV 0x8C26 +#define GL_MAX_PROGRAM_OUTPUT_VERTICES_NV 0x8C27 +#define GL_MAX_PROGRAM_TOTAL_OUTPUT_COMPONENTS_NV 0x8C28 + +typedef void (GLAPIENTRY * PFNGLPROGRAMVERTEXLIMITNVPROC) (GLenum target, GLint limit); + +#define glProgramVertexLimitNV GLEW_GET_FUN(__glewProgramVertexLimitNV) + +#define GLEW_NV_geometry_program4 GLEW_GET_VAR(__GLEW_NV_geometry_program4) + +#endif /* GL_NV_geometry_program4 */ + +/* ------------------------- GL_NV_geometry_shader4 ------------------------ */ + +#ifndef GL_NV_geometry_shader4 +#define GL_NV_geometry_shader4 1 + +#define GLEW_NV_geometry_shader4 GLEW_GET_VAR(__GLEW_NV_geometry_shader4) + +#endif /* GL_NV_geometry_shader4 */ + +/* --------------------------- GL_NV_gpu_program4 -------------------------- */ + +#ifndef GL_NV_gpu_program4 +#define GL_NV_gpu_program4 1 + +#define GL_MIN_PROGRAM_TEXEL_OFFSET_NV 0x8904 +#define GL_MAX_PROGRAM_TEXEL_OFFSET_NV 0x8905 +#define GL_PROGRAM_ATTRIB_COMPONENTS_NV 0x8906 +#define GL_PROGRAM_RESULT_COMPONENTS_NV 0x8907 +#define GL_MAX_PROGRAM_ATTRIB_COMPONENTS_NV 0x8908 +#define GL_MAX_PROGRAM_RESULT_COMPONENTS_NV 0x8909 +#define GL_MAX_PROGRAM_GENERIC_ATTRIBS_NV 0x8DA5 +#define GL_MAX_PROGRAM_GENERIC_RESULTS_NV 0x8DA6 + +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params); + +#define glProgramEnvParameterI4iNV GLEW_GET_FUN(__glewProgramEnvParameterI4iNV) +#define glProgramEnvParameterI4ivNV GLEW_GET_FUN(__glewProgramEnvParameterI4ivNV) +#define glProgramEnvParameterI4uiNV GLEW_GET_FUN(__glewProgramEnvParameterI4uiNV) +#define glProgramEnvParameterI4uivNV GLEW_GET_FUN(__glewProgramEnvParameterI4uivNV) +#define glProgramEnvParametersI4ivNV GLEW_GET_FUN(__glewProgramEnvParametersI4ivNV) +#define glProgramEnvParametersI4uivNV GLEW_GET_FUN(__glewProgramEnvParametersI4uivNV) +#define glProgramLocalParameterI4iNV GLEW_GET_FUN(__glewProgramLocalParameterI4iNV) +#define glProgramLocalParameterI4ivNV GLEW_GET_FUN(__glewProgramLocalParameterI4ivNV) +#define glProgramLocalParameterI4uiNV GLEW_GET_FUN(__glewProgramLocalParameterI4uiNV) +#define glProgramLocalParameterI4uivNV GLEW_GET_FUN(__glewProgramLocalParameterI4uivNV) +#define glProgramLocalParametersI4ivNV GLEW_GET_FUN(__glewProgramLocalParametersI4ivNV) +#define glProgramLocalParametersI4uivNV GLEW_GET_FUN(__glewProgramLocalParametersI4uivNV) + +#define GLEW_NV_gpu_program4 GLEW_GET_VAR(__GLEW_NV_gpu_program4) + +#endif /* GL_NV_gpu_program4 */ + +/* ---------------------------- GL_NV_half_float --------------------------- */ + +#ifndef GL_NV_half_float +#define GL_NV_half_float 1 + +#define GL_HALF_FLOAT_NV 0x140B + +typedef unsigned short GLhalf; + +typedef void (GLAPIENTRY * PFNGLCOLOR3HNVPROC) (GLhalf red, GLhalf green, GLhalf blue); +typedef void (GLAPIENTRY * PFNGLCOLOR3HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLCOLOR4HNVPROC) (GLhalf red, GLhalf green, GLhalf blue, GLhalf alpha); +typedef void (GLAPIENTRY * PFNGLCOLOR4HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLFOGCOORDHNVPROC) (GLhalf fog); +typedef void (GLAPIENTRY * PFNGLFOGCOORDHVNVPROC) (const GLhalf* fog); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1HNVPROC) (GLenum target, GLhalf s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1HVNVPROC) (GLenum target, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2HNVPROC) (GLenum target, GLhalf s, GLhalf t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2HVNVPROC) (GLenum target, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3HNVPROC) (GLenum target, GLhalf s, GLhalf t, GLhalf r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3HVNVPROC) (GLenum target, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4HNVPROC) (GLenum target, GLhalf s, GLhalf t, GLhalf r, GLhalf q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4HVNVPROC) (GLenum target, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLNORMAL3HNVPROC) (GLhalf nx, GLhalf ny, GLhalf nz); +typedef void (GLAPIENTRY * PFNGLNORMAL3HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3HNVPROC) (GLhalf red, GLhalf green, GLhalf blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD1HNVPROC) (GLhalf s); +typedef void (GLAPIENTRY * PFNGLTEXCOORD1HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2HNVPROC) (GLhalf s, GLhalf t); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD3HNVPROC) (GLhalf s, GLhalf t, GLhalf r); +typedef void (GLAPIENTRY * PFNGLTEXCOORD3HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD4HNVPROC) (GLhalf s, GLhalf t, GLhalf r, GLhalf q); +typedef void (GLAPIENTRY * PFNGLTEXCOORD4HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEX2HNVPROC) (GLhalf x, GLhalf y); +typedef void (GLAPIENTRY * PFNGLVERTEX2HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEX3HNVPROC) (GLhalf x, GLhalf y, GLhalf z); +typedef void (GLAPIENTRY * PFNGLVERTEX3HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEX4HNVPROC) (GLhalf x, GLhalf y, GLhalf z, GLhalf w); +typedef void (GLAPIENTRY * PFNGLVERTEX4HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1HNVPROC) (GLuint index, GLhalf x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1HVNVPROC) (GLuint index, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2HNVPROC) (GLuint index, GLhalf x, GLhalf y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2HVNVPROC) (GLuint index, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3HNVPROC) (GLuint index, GLhalf x, GLhalf y, GLhalf z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3HVNVPROC) (GLuint index, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4HNVPROC) (GLuint index, GLhalf x, GLhalf y, GLhalf z, GLhalf w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4HVNVPROC) (GLuint index, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS1HVNVPROC) (GLuint index, GLsizei n, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS2HVNVPROC) (GLuint index, GLsizei n, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS3HVNVPROC) (GLuint index, GLsizei n, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS4HVNVPROC) (GLuint index, GLsizei n, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEXWEIGHTHNVPROC) (GLhalf weight); +typedef void (GLAPIENTRY * PFNGLVERTEXWEIGHTHVNVPROC) (const GLhalf* weight); + +#define glColor3hNV GLEW_GET_FUN(__glewColor3hNV) +#define glColor3hvNV GLEW_GET_FUN(__glewColor3hvNV) +#define glColor4hNV GLEW_GET_FUN(__glewColor4hNV) +#define glColor4hvNV GLEW_GET_FUN(__glewColor4hvNV) +#define glFogCoordhNV GLEW_GET_FUN(__glewFogCoordhNV) +#define glFogCoordhvNV GLEW_GET_FUN(__glewFogCoordhvNV) +#define glMultiTexCoord1hNV GLEW_GET_FUN(__glewMultiTexCoord1hNV) +#define glMultiTexCoord1hvNV GLEW_GET_FUN(__glewMultiTexCoord1hvNV) +#define glMultiTexCoord2hNV GLEW_GET_FUN(__glewMultiTexCoord2hNV) +#define glMultiTexCoord2hvNV GLEW_GET_FUN(__glewMultiTexCoord2hvNV) +#define glMultiTexCoord3hNV GLEW_GET_FUN(__glewMultiTexCoord3hNV) +#define glMultiTexCoord3hvNV GLEW_GET_FUN(__glewMultiTexCoord3hvNV) +#define glMultiTexCoord4hNV GLEW_GET_FUN(__glewMultiTexCoord4hNV) +#define glMultiTexCoord4hvNV GLEW_GET_FUN(__glewMultiTexCoord4hvNV) +#define glNormal3hNV GLEW_GET_FUN(__glewNormal3hNV) +#define glNormal3hvNV GLEW_GET_FUN(__glewNormal3hvNV) +#define glSecondaryColor3hNV GLEW_GET_FUN(__glewSecondaryColor3hNV) +#define glSecondaryColor3hvNV GLEW_GET_FUN(__glewSecondaryColor3hvNV) +#define glTexCoord1hNV GLEW_GET_FUN(__glewTexCoord1hNV) +#define glTexCoord1hvNV GLEW_GET_FUN(__glewTexCoord1hvNV) +#define glTexCoord2hNV GLEW_GET_FUN(__glewTexCoord2hNV) +#define glTexCoord2hvNV GLEW_GET_FUN(__glewTexCoord2hvNV) +#define glTexCoord3hNV GLEW_GET_FUN(__glewTexCoord3hNV) +#define glTexCoord3hvNV GLEW_GET_FUN(__glewTexCoord3hvNV) +#define glTexCoord4hNV GLEW_GET_FUN(__glewTexCoord4hNV) +#define glTexCoord4hvNV GLEW_GET_FUN(__glewTexCoord4hvNV) +#define glVertex2hNV GLEW_GET_FUN(__glewVertex2hNV) +#define glVertex2hvNV GLEW_GET_FUN(__glewVertex2hvNV) +#define glVertex3hNV GLEW_GET_FUN(__glewVertex3hNV) +#define glVertex3hvNV GLEW_GET_FUN(__glewVertex3hvNV) +#define glVertex4hNV GLEW_GET_FUN(__glewVertex4hNV) +#define glVertex4hvNV GLEW_GET_FUN(__glewVertex4hvNV) +#define glVertexAttrib1hNV GLEW_GET_FUN(__glewVertexAttrib1hNV) +#define glVertexAttrib1hvNV GLEW_GET_FUN(__glewVertexAttrib1hvNV) +#define glVertexAttrib2hNV GLEW_GET_FUN(__glewVertexAttrib2hNV) +#define glVertexAttrib2hvNV GLEW_GET_FUN(__glewVertexAttrib2hvNV) +#define glVertexAttrib3hNV GLEW_GET_FUN(__glewVertexAttrib3hNV) +#define glVertexAttrib3hvNV GLEW_GET_FUN(__glewVertexAttrib3hvNV) +#define glVertexAttrib4hNV GLEW_GET_FUN(__glewVertexAttrib4hNV) +#define glVertexAttrib4hvNV GLEW_GET_FUN(__glewVertexAttrib4hvNV) +#define glVertexAttribs1hvNV GLEW_GET_FUN(__glewVertexAttribs1hvNV) +#define glVertexAttribs2hvNV GLEW_GET_FUN(__glewVertexAttribs2hvNV) +#define glVertexAttribs3hvNV GLEW_GET_FUN(__glewVertexAttribs3hvNV) +#define glVertexAttribs4hvNV GLEW_GET_FUN(__glewVertexAttribs4hvNV) +#define glVertexWeighthNV GLEW_GET_FUN(__glewVertexWeighthNV) +#define glVertexWeighthvNV GLEW_GET_FUN(__glewVertexWeighthvNV) + +#define GLEW_NV_half_float GLEW_GET_VAR(__GLEW_NV_half_float) + +#endif /* GL_NV_half_float */ + +/* ------------------------ GL_NV_light_max_exponent ----------------------- */ + +#ifndef GL_NV_light_max_exponent +#define GL_NV_light_max_exponent 1 + +#define GL_MAX_SHININESS_NV 0x8504 +#define GL_MAX_SPOT_EXPONENT_NV 0x8505 + +#define GLEW_NV_light_max_exponent GLEW_GET_VAR(__GLEW_NV_light_max_exponent) + +#endif /* GL_NV_light_max_exponent */ + +/* --------------------- GL_NV_multisample_filter_hint --------------------- */ + +#ifndef GL_NV_multisample_filter_hint +#define GL_NV_multisample_filter_hint 1 + +#define GL_MULTISAMPLE_FILTER_HINT_NV 0x8534 + +#define GLEW_NV_multisample_filter_hint GLEW_GET_VAR(__GLEW_NV_multisample_filter_hint) + +#endif /* GL_NV_multisample_filter_hint */ + +/* ------------------------- GL_NV_occlusion_query ------------------------- */ + +#ifndef GL_NV_occlusion_query +#define GL_NV_occlusion_query 1 + +#define GL_PIXEL_COUNTER_BITS_NV 0x8864 +#define GL_CURRENT_OCCLUSION_QUERY_ID_NV 0x8865 +#define GL_PIXEL_COUNT_NV 0x8866 +#define GL_PIXEL_COUNT_AVAILABLE_NV 0x8867 + +typedef void (GLAPIENTRY * PFNGLBEGINOCCLUSIONQUERYNVPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLDELETEOCCLUSIONQUERIESNVPROC) (GLsizei n, const GLuint* ids); +typedef void (GLAPIENTRY * PFNGLENDOCCLUSIONQUERYNVPROC) (void); +typedef void (GLAPIENTRY * PFNGLGENOCCLUSIONQUERIESNVPROC) (GLsizei n, GLuint* ids); +typedef void (GLAPIENTRY * PFNGLGETOCCLUSIONQUERYIVNVPROC) (GLuint id, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETOCCLUSIONQUERYUIVNVPROC) (GLuint id, GLenum pname, GLuint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISOCCLUSIONQUERYNVPROC) (GLuint id); + +#define glBeginOcclusionQueryNV GLEW_GET_FUN(__glewBeginOcclusionQueryNV) +#define glDeleteOcclusionQueriesNV GLEW_GET_FUN(__glewDeleteOcclusionQueriesNV) +#define glEndOcclusionQueryNV GLEW_GET_FUN(__glewEndOcclusionQueryNV) +#define glGenOcclusionQueriesNV GLEW_GET_FUN(__glewGenOcclusionQueriesNV) +#define glGetOcclusionQueryivNV GLEW_GET_FUN(__glewGetOcclusionQueryivNV) +#define glGetOcclusionQueryuivNV GLEW_GET_FUN(__glewGetOcclusionQueryuivNV) +#define glIsOcclusionQueryNV GLEW_GET_FUN(__glewIsOcclusionQueryNV) + +#define GLEW_NV_occlusion_query GLEW_GET_VAR(__GLEW_NV_occlusion_query) + +#endif /* GL_NV_occlusion_query */ + +/* ----------------------- GL_NV_packed_depth_stencil ---------------------- */ + +#ifndef GL_NV_packed_depth_stencil +#define GL_NV_packed_depth_stencil 1 + +#define GL_DEPTH_STENCIL_NV 0x84F9 +#define GL_UNSIGNED_INT_24_8_NV 0x84FA + +#define GLEW_NV_packed_depth_stencil GLEW_GET_VAR(__GLEW_NV_packed_depth_stencil) + +#endif /* GL_NV_packed_depth_stencil */ + +/* --------------------- GL_NV_parameter_buffer_object --------------------- */ + +#ifndef GL_NV_parameter_buffer_object +#define GL_NV_parameter_buffer_object 1 + +#define GL_MAX_PROGRAM_PARAMETER_BUFFER_BINDINGS_NV 0x8DA0 +#define GL_MAX_PROGRAM_PARAMETER_BUFFER_SIZE_NV 0x8DA1 +#define GL_VERTEX_PROGRAM_PARAMETER_BUFFER_NV 0x8DA2 +#define GL_GEOMETRY_PROGRAM_PARAMETER_BUFFER_NV 0x8DA3 +#define GL_FRAGMENT_PROGRAM_PARAMETER_BUFFER_NV 0x8DA4 + +typedef void (GLAPIENTRY * PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLint *params); +typedef void (GLAPIENTRY * PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLuint *params); +typedef void (GLAPIENTRY * PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLfloat *params); + +#define glProgramBufferParametersIivNV GLEW_GET_FUN(__glewProgramBufferParametersIivNV) +#define glProgramBufferParametersIuivNV GLEW_GET_FUN(__glewProgramBufferParametersIuivNV) +#define glProgramBufferParametersfvNV GLEW_GET_FUN(__glewProgramBufferParametersfvNV) + +#define GLEW_NV_parameter_buffer_object GLEW_GET_VAR(__GLEW_NV_parameter_buffer_object) + +#endif /* GL_NV_parameter_buffer_object */ + +/* ------------------------- GL_NV_pixel_data_range ------------------------ */ + +#ifndef GL_NV_pixel_data_range +#define GL_NV_pixel_data_range 1 + +#define GL_WRITE_PIXEL_DATA_RANGE_NV 0x8878 +#define GL_READ_PIXEL_DATA_RANGE_NV 0x8879 +#define GL_WRITE_PIXEL_DATA_RANGE_LENGTH_NV 0x887A +#define GL_READ_PIXEL_DATA_RANGE_LENGTH_NV 0x887B +#define GL_WRITE_PIXEL_DATA_RANGE_POINTER_NV 0x887C +#define GL_READ_PIXEL_DATA_RANGE_POINTER_NV 0x887D + +typedef void (GLAPIENTRY * PFNGLFLUSHPIXELDATARANGENVPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLPIXELDATARANGENVPROC) (GLenum target, GLsizei length, void* pointer); + +#define glFlushPixelDataRangeNV GLEW_GET_FUN(__glewFlushPixelDataRangeNV) +#define glPixelDataRangeNV GLEW_GET_FUN(__glewPixelDataRangeNV) + +#define GLEW_NV_pixel_data_range GLEW_GET_VAR(__GLEW_NV_pixel_data_range) + +#endif /* GL_NV_pixel_data_range */ + +/* --------------------------- GL_NV_point_sprite -------------------------- */ + +#ifndef GL_NV_point_sprite +#define GL_NV_point_sprite 1 + +#define GL_POINT_SPRITE_NV 0x8861 +#define GL_COORD_REPLACE_NV 0x8862 +#define GL_POINT_SPRITE_R_MODE_NV 0x8863 + +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERINVPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERIVNVPROC) (GLenum pname, const GLint* params); + +#define glPointParameteriNV GLEW_GET_FUN(__glewPointParameteriNV) +#define glPointParameterivNV GLEW_GET_FUN(__glewPointParameterivNV) + +#define GLEW_NV_point_sprite GLEW_GET_VAR(__GLEW_NV_point_sprite) + +#endif /* GL_NV_point_sprite */ + +/* -------------------------- GL_NV_present_video -------------------------- */ + +#ifndef GL_NV_present_video +#define GL_NV_present_video 1 + +#define GL_FRAME_NV 0x8E26 +#define GL_FIELDS_NV 0x8E27 +#define GL_CURRENT_TIME_NV 0x8E28 +#define GL_NUM_FILL_STREAMS_NV 0x8E29 +#define GL_PRESENT_TIME_NV 0x8E2A +#define GL_PRESENT_DURATION_NV 0x8E2B + +typedef void (GLAPIENTRY * PFNGLGETVIDEOI64VNVPROC) (GLuint video_slot, GLenum pname, GLint64EXT* params); +typedef void (GLAPIENTRY * PFNGLGETVIDEOIVNVPROC) (GLuint video_slot, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETVIDEOUI64VNVPROC) (GLuint video_slot, GLenum pname, GLuint64EXT* params); +typedef void (GLAPIENTRY * PFNGLGETVIDEOUIVNVPROC) (GLuint video_slot, GLenum pname, GLuint* params); +typedef void (GLAPIENTRY * PFNGLPRESENTFRAMEDUALFILLNVPROC) (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLenum target1, GLuint fill1, GLenum target2, GLuint fill2, GLenum target3, GLuint fill3); +typedef void (GLAPIENTRY * PFNGLPRESENTFRAMEKEYEDNVPROC) (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLuint key0, GLenum target1, GLuint fill1, GLuint key1); +typedef void (GLAPIENTRY * PFNGLVIDEOPARAMETERIVNVPROC) (GLuint video_slot, GLenum pname, const GLint* params); + +#define glGetVideoi64vNV GLEW_GET_FUN(__glewGetVideoi64vNV) +#define glGetVideoivNV GLEW_GET_FUN(__glewGetVideoivNV) +#define glGetVideoui64vNV GLEW_GET_FUN(__glewGetVideoui64vNV) +#define glGetVideouivNV GLEW_GET_FUN(__glewGetVideouivNV) +#define glPresentFrameDualFillNV GLEW_GET_FUN(__glewPresentFrameDualFillNV) +#define glPresentFrameKeyedNV GLEW_GET_FUN(__glewPresentFrameKeyedNV) +#define glVideoParameterivNV GLEW_GET_FUN(__glewVideoParameterivNV) + +#define GLEW_NV_present_video GLEW_GET_VAR(__GLEW_NV_present_video) + +#endif /* GL_NV_present_video */ + +/* ------------------------ GL_NV_primitive_restart ------------------------ */ + +#ifndef GL_NV_primitive_restart +#define GL_NV_primitive_restart 1 + +#define GL_PRIMITIVE_RESTART_NV 0x8558 +#define GL_PRIMITIVE_RESTART_INDEX_NV 0x8559 + +typedef void (GLAPIENTRY * PFNGLPRIMITIVERESTARTINDEXNVPROC) (GLuint index); +typedef void (GLAPIENTRY * PFNGLPRIMITIVERESTARTNVPROC) (void); + +#define glPrimitiveRestartIndexNV GLEW_GET_FUN(__glewPrimitiveRestartIndexNV) +#define glPrimitiveRestartNV GLEW_GET_FUN(__glewPrimitiveRestartNV) + +#define GLEW_NV_primitive_restart GLEW_GET_VAR(__GLEW_NV_primitive_restart) + +#endif /* GL_NV_primitive_restart */ + +/* ------------------------ GL_NV_register_combiners ----------------------- */ + +#ifndef GL_NV_register_combiners +#define GL_NV_register_combiners 1 + +#define GL_REGISTER_COMBINERS_NV 0x8522 +#define GL_VARIABLE_A_NV 0x8523 +#define GL_VARIABLE_B_NV 0x8524 +#define GL_VARIABLE_C_NV 0x8525 +#define GL_VARIABLE_D_NV 0x8526 +#define GL_VARIABLE_E_NV 0x8527 +#define GL_VARIABLE_F_NV 0x8528 +#define GL_VARIABLE_G_NV 0x8529 +#define GL_CONSTANT_COLOR0_NV 0x852A +#define GL_CONSTANT_COLOR1_NV 0x852B +#define GL_PRIMARY_COLOR_NV 0x852C +#define GL_SECONDARY_COLOR_NV 0x852D +#define GL_SPARE0_NV 0x852E +#define GL_SPARE1_NV 0x852F +#define GL_DISCARD_NV 0x8530 +#define GL_E_TIMES_F_NV 0x8531 +#define GL_SPARE0_PLUS_SECONDARY_COLOR_NV 0x8532 +#define GL_UNSIGNED_IDENTITY_NV 0x8536 +#define GL_UNSIGNED_INVERT_NV 0x8537 +#define GL_EXPAND_NORMAL_NV 0x8538 +#define GL_EXPAND_NEGATE_NV 0x8539 +#define GL_HALF_BIAS_NORMAL_NV 0x853A +#define GL_HALF_BIAS_NEGATE_NV 0x853B +#define GL_SIGNED_IDENTITY_NV 0x853C +#define GL_SIGNED_NEGATE_NV 0x853D +#define GL_SCALE_BY_TWO_NV 0x853E +#define GL_SCALE_BY_FOUR_NV 0x853F +#define GL_SCALE_BY_ONE_HALF_NV 0x8540 +#define GL_BIAS_BY_NEGATIVE_ONE_HALF_NV 0x8541 +#define GL_COMBINER_INPUT_NV 0x8542 +#define GL_COMBINER_MAPPING_NV 0x8543 +#define GL_COMBINER_COMPONENT_USAGE_NV 0x8544 +#define GL_COMBINER_AB_DOT_PRODUCT_NV 0x8545 +#define GL_COMBINER_CD_DOT_PRODUCT_NV 0x8546 +#define GL_COMBINER_MUX_SUM_NV 0x8547 +#define GL_COMBINER_SCALE_NV 0x8548 +#define GL_COMBINER_BIAS_NV 0x8549 +#define GL_COMBINER_AB_OUTPUT_NV 0x854A +#define GL_COMBINER_CD_OUTPUT_NV 0x854B +#define GL_COMBINER_SUM_OUTPUT_NV 0x854C +#define GL_MAX_GENERAL_COMBINERS_NV 0x854D +#define GL_NUM_GENERAL_COMBINERS_NV 0x854E +#define GL_COLOR_SUM_CLAMP_NV 0x854F +#define GL_COMBINER0_NV 0x8550 +#define GL_COMBINER1_NV 0x8551 +#define GL_COMBINER2_NV 0x8552 +#define GL_COMBINER3_NV 0x8553 +#define GL_COMBINER4_NV 0x8554 +#define GL_COMBINER5_NV 0x8555 +#define GL_COMBINER6_NV 0x8556 +#define GL_COMBINER7_NV 0x8557 + +typedef void (GLAPIENTRY * PFNGLCOMBINERINPUTNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); +typedef void (GLAPIENTRY * PFNGLCOMBINEROUTPUTNVPROC) (GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum); +typedef void (GLAPIENTRY * PFNGLCOMBINERPARAMETERFNVPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLCOMBINERPARAMETERFVNVPROC) (GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLCOMBINERPARAMETERINVPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLCOMBINERPARAMETERIVNVPROC) (GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLFINALCOMBINERINPUTNVPROC) (GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); +typedef void (GLAPIENTRY * PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC) (GLenum variable, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC) (GLenum variable, GLenum pname, GLint* params); + +#define glCombinerInputNV GLEW_GET_FUN(__glewCombinerInputNV) +#define glCombinerOutputNV GLEW_GET_FUN(__glewCombinerOutputNV) +#define glCombinerParameterfNV GLEW_GET_FUN(__glewCombinerParameterfNV) +#define glCombinerParameterfvNV GLEW_GET_FUN(__glewCombinerParameterfvNV) +#define glCombinerParameteriNV GLEW_GET_FUN(__glewCombinerParameteriNV) +#define glCombinerParameterivNV GLEW_GET_FUN(__glewCombinerParameterivNV) +#define glFinalCombinerInputNV GLEW_GET_FUN(__glewFinalCombinerInputNV) +#define glGetCombinerInputParameterfvNV GLEW_GET_FUN(__glewGetCombinerInputParameterfvNV) +#define glGetCombinerInputParameterivNV GLEW_GET_FUN(__glewGetCombinerInputParameterivNV) +#define glGetCombinerOutputParameterfvNV GLEW_GET_FUN(__glewGetCombinerOutputParameterfvNV) +#define glGetCombinerOutputParameterivNV GLEW_GET_FUN(__glewGetCombinerOutputParameterivNV) +#define glGetFinalCombinerInputParameterfvNV GLEW_GET_FUN(__glewGetFinalCombinerInputParameterfvNV) +#define glGetFinalCombinerInputParameterivNV GLEW_GET_FUN(__glewGetFinalCombinerInputParameterivNV) + +#define GLEW_NV_register_combiners GLEW_GET_VAR(__GLEW_NV_register_combiners) + +#endif /* GL_NV_register_combiners */ + +/* ----------------------- GL_NV_register_combiners2 ----------------------- */ + +#ifndef GL_NV_register_combiners2 +#define GL_NV_register_combiners2 1 + +#define GL_PER_STAGE_CONSTANTS_NV 0x8535 + +typedef void (GLAPIENTRY * PFNGLCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, GLfloat* params); + +#define glCombinerStageParameterfvNV GLEW_GET_FUN(__glewCombinerStageParameterfvNV) +#define glGetCombinerStageParameterfvNV GLEW_GET_FUN(__glewGetCombinerStageParameterfvNV) + +#define GLEW_NV_register_combiners2 GLEW_GET_VAR(__GLEW_NV_register_combiners2) + +#endif /* GL_NV_register_combiners2 */ + +/* -------------------------- GL_NV_texgen_emboss -------------------------- */ + +#ifndef GL_NV_texgen_emboss +#define GL_NV_texgen_emboss 1 + +#define GL_EMBOSS_LIGHT_NV 0x855D +#define GL_EMBOSS_CONSTANT_NV 0x855E +#define GL_EMBOSS_MAP_NV 0x855F + +#define GLEW_NV_texgen_emboss GLEW_GET_VAR(__GLEW_NV_texgen_emboss) + +#endif /* GL_NV_texgen_emboss */ + +/* ------------------------ GL_NV_texgen_reflection ------------------------ */ + +#ifndef GL_NV_texgen_reflection +#define GL_NV_texgen_reflection 1 + +#define GL_NORMAL_MAP_NV 0x8511 +#define GL_REFLECTION_MAP_NV 0x8512 + +#define GLEW_NV_texgen_reflection GLEW_GET_VAR(__GLEW_NV_texgen_reflection) + +#endif /* GL_NV_texgen_reflection */ + +/* --------------------- GL_NV_texture_compression_vtc --------------------- */ + +#ifndef GL_NV_texture_compression_vtc +#define GL_NV_texture_compression_vtc 1 + +#define GLEW_NV_texture_compression_vtc GLEW_GET_VAR(__GLEW_NV_texture_compression_vtc) + +#endif /* GL_NV_texture_compression_vtc */ + +/* ----------------------- GL_NV_texture_env_combine4 ---------------------- */ + +#ifndef GL_NV_texture_env_combine4 +#define GL_NV_texture_env_combine4 1 + +#define GL_COMBINE4_NV 0x8503 +#define GL_SOURCE3_RGB_NV 0x8583 +#define GL_SOURCE3_ALPHA_NV 0x858B +#define GL_OPERAND3_RGB_NV 0x8593 +#define GL_OPERAND3_ALPHA_NV 0x859B + +#define GLEW_NV_texture_env_combine4 GLEW_GET_VAR(__GLEW_NV_texture_env_combine4) + +#endif /* GL_NV_texture_env_combine4 */ + +/* ---------------------- GL_NV_texture_expand_normal ---------------------- */ + +#ifndef GL_NV_texture_expand_normal +#define GL_NV_texture_expand_normal 1 + +#define GL_TEXTURE_UNSIGNED_REMAP_MODE_NV 0x888F + +#define GLEW_NV_texture_expand_normal GLEW_GET_VAR(__GLEW_NV_texture_expand_normal) + +#endif /* GL_NV_texture_expand_normal */ + +/* ------------------------ GL_NV_texture_rectangle ------------------------ */ + +#ifndef GL_NV_texture_rectangle +#define GL_NV_texture_rectangle 1 + +#define GL_TEXTURE_RECTANGLE_NV 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE_NV 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE_NV 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE_NV 0x84F8 + +#define GLEW_NV_texture_rectangle GLEW_GET_VAR(__GLEW_NV_texture_rectangle) + +#endif /* GL_NV_texture_rectangle */ + +/* -------------------------- GL_NV_texture_shader ------------------------- */ + +#ifndef GL_NV_texture_shader +#define GL_NV_texture_shader 1 + +#define GL_OFFSET_TEXTURE_RECTANGLE_NV 0x864C +#define GL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV 0x864D +#define GL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV 0x864E +#define GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV 0x86D9 +#define GL_UNSIGNED_INT_S8_S8_8_8_NV 0x86DA +#define GL_UNSIGNED_INT_8_8_S8_S8_REV_NV 0x86DB +#define GL_DSDT_MAG_INTENSITY_NV 0x86DC +#define GL_SHADER_CONSISTENT_NV 0x86DD +#define GL_TEXTURE_SHADER_NV 0x86DE +#define GL_SHADER_OPERATION_NV 0x86DF +#define GL_CULL_MODES_NV 0x86E0 +#define GL_OFFSET_TEXTURE_2D_MATRIX_NV 0x86E1 +#define GL_OFFSET_TEXTURE_MATRIX_NV 0x86E1 +#define GL_OFFSET_TEXTURE_2D_SCALE_NV 0x86E2 +#define GL_OFFSET_TEXTURE_SCALE_NV 0x86E2 +#define GL_OFFSET_TEXTURE_BIAS_NV 0x86E3 +#define GL_OFFSET_TEXTURE_2D_BIAS_NV 0x86E3 +#define GL_PREVIOUS_TEXTURE_INPUT_NV 0x86E4 +#define GL_CONST_EYE_NV 0x86E5 +#define GL_PASS_THROUGH_NV 0x86E6 +#define GL_CULL_FRAGMENT_NV 0x86E7 +#define GL_OFFSET_TEXTURE_2D_NV 0x86E8 +#define GL_DEPENDENT_AR_TEXTURE_2D_NV 0x86E9 +#define GL_DEPENDENT_GB_TEXTURE_2D_NV 0x86EA +#define GL_DOT_PRODUCT_NV 0x86EC +#define GL_DOT_PRODUCT_DEPTH_REPLACE_NV 0x86ED +#define GL_DOT_PRODUCT_TEXTURE_2D_NV 0x86EE +#define GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV 0x86F0 +#define GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV 0x86F1 +#define GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV 0x86F2 +#define GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV 0x86F3 +#define GL_HILO_NV 0x86F4 +#define GL_DSDT_NV 0x86F5 +#define GL_DSDT_MAG_NV 0x86F6 +#define GL_DSDT_MAG_VIB_NV 0x86F7 +#define GL_HILO16_NV 0x86F8 +#define GL_SIGNED_HILO_NV 0x86F9 +#define GL_SIGNED_HILO16_NV 0x86FA +#define GL_SIGNED_RGBA_NV 0x86FB +#define GL_SIGNED_RGBA8_NV 0x86FC +#define GL_SIGNED_RGB_NV 0x86FE +#define GL_SIGNED_RGB8_NV 0x86FF +#define GL_SIGNED_LUMINANCE_NV 0x8701 +#define GL_SIGNED_LUMINANCE8_NV 0x8702 +#define GL_SIGNED_LUMINANCE_ALPHA_NV 0x8703 +#define GL_SIGNED_LUMINANCE8_ALPHA8_NV 0x8704 +#define GL_SIGNED_ALPHA_NV 0x8705 +#define GL_SIGNED_ALPHA8_NV 0x8706 +#define GL_SIGNED_INTENSITY_NV 0x8707 +#define GL_SIGNED_INTENSITY8_NV 0x8708 +#define GL_DSDT8_NV 0x8709 +#define GL_DSDT8_MAG8_NV 0x870A +#define GL_DSDT8_MAG8_INTENSITY8_NV 0x870B +#define GL_SIGNED_RGB_UNSIGNED_ALPHA_NV 0x870C +#define GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV 0x870D +#define GL_HI_SCALE_NV 0x870E +#define GL_LO_SCALE_NV 0x870F +#define GL_DS_SCALE_NV 0x8710 +#define GL_DT_SCALE_NV 0x8711 +#define GL_MAGNITUDE_SCALE_NV 0x8712 +#define GL_VIBRANCE_SCALE_NV 0x8713 +#define GL_HI_BIAS_NV 0x8714 +#define GL_LO_BIAS_NV 0x8715 +#define GL_DS_BIAS_NV 0x8716 +#define GL_DT_BIAS_NV 0x8717 +#define GL_MAGNITUDE_BIAS_NV 0x8718 +#define GL_VIBRANCE_BIAS_NV 0x8719 +#define GL_TEXTURE_BORDER_VALUES_NV 0x871A +#define GL_TEXTURE_HI_SIZE_NV 0x871B +#define GL_TEXTURE_LO_SIZE_NV 0x871C +#define GL_TEXTURE_DS_SIZE_NV 0x871D +#define GL_TEXTURE_DT_SIZE_NV 0x871E +#define GL_TEXTURE_MAG_SIZE_NV 0x871F + +#define GLEW_NV_texture_shader GLEW_GET_VAR(__GLEW_NV_texture_shader) + +#endif /* GL_NV_texture_shader */ + +/* ------------------------- GL_NV_texture_shader2 ------------------------- */ + +#ifndef GL_NV_texture_shader2 +#define GL_NV_texture_shader2 1 + +#define GL_UNSIGNED_INT_S8_S8_8_8_NV 0x86DA +#define GL_UNSIGNED_INT_8_8_S8_S8_REV_NV 0x86DB +#define GL_DSDT_MAG_INTENSITY_NV 0x86DC +#define GL_DOT_PRODUCT_TEXTURE_3D_NV 0x86EF +#define GL_HILO_NV 0x86F4 +#define GL_DSDT_NV 0x86F5 +#define GL_DSDT_MAG_NV 0x86F6 +#define GL_DSDT_MAG_VIB_NV 0x86F7 +#define GL_HILO16_NV 0x86F8 +#define GL_SIGNED_HILO_NV 0x86F9 +#define GL_SIGNED_HILO16_NV 0x86FA +#define GL_SIGNED_RGBA_NV 0x86FB +#define GL_SIGNED_RGBA8_NV 0x86FC +#define GL_SIGNED_RGB_NV 0x86FE +#define GL_SIGNED_RGB8_NV 0x86FF +#define GL_SIGNED_LUMINANCE_NV 0x8701 +#define GL_SIGNED_LUMINANCE8_NV 0x8702 +#define GL_SIGNED_LUMINANCE_ALPHA_NV 0x8703 +#define GL_SIGNED_LUMINANCE8_ALPHA8_NV 0x8704 +#define GL_SIGNED_ALPHA_NV 0x8705 +#define GL_SIGNED_ALPHA8_NV 0x8706 +#define GL_SIGNED_INTENSITY_NV 0x8707 +#define GL_SIGNED_INTENSITY8_NV 0x8708 +#define GL_DSDT8_NV 0x8709 +#define GL_DSDT8_MAG8_NV 0x870A +#define GL_DSDT8_MAG8_INTENSITY8_NV 0x870B +#define GL_SIGNED_RGB_UNSIGNED_ALPHA_NV 0x870C +#define GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV 0x870D + +#define GLEW_NV_texture_shader2 GLEW_GET_VAR(__GLEW_NV_texture_shader2) + +#endif /* GL_NV_texture_shader2 */ + +/* ------------------------- GL_NV_texture_shader3 ------------------------- */ + +#ifndef GL_NV_texture_shader3 +#define GL_NV_texture_shader3 1 + +#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_NV 0x8850 +#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV 0x8851 +#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8852 +#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV 0x8853 +#define GL_OFFSET_HILO_TEXTURE_2D_NV 0x8854 +#define GL_OFFSET_HILO_TEXTURE_RECTANGLE_NV 0x8855 +#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_2D_NV 0x8856 +#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8857 +#define GL_DEPENDENT_HILO_TEXTURE_2D_NV 0x8858 +#define GL_DEPENDENT_RGB_TEXTURE_3D_NV 0x8859 +#define GL_DEPENDENT_RGB_TEXTURE_CUBE_MAP_NV 0x885A +#define GL_DOT_PRODUCT_PASS_THROUGH_NV 0x885B +#define GL_DOT_PRODUCT_TEXTURE_1D_NV 0x885C +#define GL_DOT_PRODUCT_AFFINE_DEPTH_REPLACE_NV 0x885D +#define GL_HILO8_NV 0x885E +#define GL_SIGNED_HILO8_NV 0x885F +#define GL_FORCE_BLUE_TO_ONE_NV 0x8860 + +#define GLEW_NV_texture_shader3 GLEW_GET_VAR(__GLEW_NV_texture_shader3) + +#endif /* GL_NV_texture_shader3 */ + +/* ------------------------ GL_NV_transform_feedback ----------------------- */ + +#ifndef GL_NV_transform_feedback +#define GL_NV_transform_feedback 1 + +#define GL_BACK_PRIMARY_COLOR_NV 0x8C77 +#define GL_BACK_SECONDARY_COLOR_NV 0x8C78 +#define GL_TEXTURE_COORD_NV 0x8C79 +#define GL_CLIP_DISTANCE_NV 0x8C7A +#define GL_VERTEX_ID_NV 0x8C7B +#define GL_PRIMITIVE_ID_NV 0x8C7C +#define GL_GENERIC_ATTRIB_NV 0x8C7D +#define GL_TRANSFORM_FEEDBACK_ATTRIBS_NV 0x8C7E +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_NV 0x8C7F +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_NV 0x8C80 +#define GL_ACTIVE_VARYINGS_NV 0x8C81 +#define GL_ACTIVE_VARYING_MAX_LENGTH_NV 0x8C82 +#define GL_TRANSFORM_FEEDBACK_VARYINGS_NV 0x8C83 +#define GL_TRANSFORM_FEEDBACK_BUFFER_START_NV 0x8C84 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_NV 0x8C85 +#define GL_TRANSFORM_FEEDBACK_RECORD_NV 0x8C86 +#define GL_PRIMITIVES_GENERATED_NV 0x8C87 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV 0x8C88 +#define GL_RASTERIZER_DISCARD_NV 0x8C89 +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_NV 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_NV 0x8C8B +#define GL_INTERLEAVED_ATTRIBS_NV 0x8C8C +#define GL_SEPARATE_ATTRIBS_NV 0x8C8D +#define GL_TRANSFORM_FEEDBACK_BUFFER_NV 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_NV 0x8C8F + +typedef void (GLAPIENTRY * PFNGLACTIVEVARYINGNVPROC) (GLuint program, const GLchar *name); +typedef void (GLAPIENTRY * PFNGLBEGINTRANSFORMFEEDBACKNVPROC) (GLenum primitiveMode); +typedef void (GLAPIENTRY * PFNGLBINDBUFFERBASENVPROC) (GLenum target, GLuint index, GLuint buffer); +typedef void (GLAPIENTRY * PFNGLBINDBUFFEROFFSETNVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLBINDBUFFERRANGENVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (GLAPIENTRY * PFNGLENDTRANSFORMFEEDBACKNVPROC) (void); +typedef void (GLAPIENTRY * PFNGLGETACTIVEVARYINGNVPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); +typedef void (GLAPIENTRY * PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC) (GLuint program, GLuint index, GLint *location); +typedef GLint (GLAPIENTRY * PFNGLGETVARYINGLOCATIONNVPROC) (GLuint program, const GLchar *name); +typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC) (GLuint count, const GLint *attribs, GLenum bufferMode); +typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC) (GLuint program, GLsizei count, const GLint *locations, GLenum bufferMode); + +#define glActiveVaryingNV GLEW_GET_FUN(__glewActiveVaryingNV) +#define glBeginTransformFeedbackNV GLEW_GET_FUN(__glewBeginTransformFeedbackNV) +#define glBindBufferBaseNV GLEW_GET_FUN(__glewBindBufferBaseNV) +#define glBindBufferOffsetNV GLEW_GET_FUN(__glewBindBufferOffsetNV) +#define glBindBufferRangeNV GLEW_GET_FUN(__glewBindBufferRangeNV) +#define glEndTransformFeedbackNV GLEW_GET_FUN(__glewEndTransformFeedbackNV) +#define glGetActiveVaryingNV GLEW_GET_FUN(__glewGetActiveVaryingNV) +#define glGetTransformFeedbackVaryingNV GLEW_GET_FUN(__glewGetTransformFeedbackVaryingNV) +#define glGetVaryingLocationNV GLEW_GET_FUN(__glewGetVaryingLocationNV) +#define glTransformFeedbackAttribsNV GLEW_GET_FUN(__glewTransformFeedbackAttribsNV) +#define glTransformFeedbackVaryingsNV GLEW_GET_FUN(__glewTransformFeedbackVaryingsNV) + +#define GLEW_NV_transform_feedback GLEW_GET_VAR(__GLEW_NV_transform_feedback) + +#endif /* GL_NV_transform_feedback */ + +/* ------------------------ GL_NV_vertex_array_range ----------------------- */ + +#ifndef GL_NV_vertex_array_range +#define GL_NV_vertex_array_range 1 + +#define GL_VERTEX_ARRAY_RANGE_NV 0x851D +#define GL_VERTEX_ARRAY_RANGE_LENGTH_NV 0x851E +#define GL_VERTEX_ARRAY_RANGE_VALID_NV 0x851F +#define GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV 0x8520 +#define GL_VERTEX_ARRAY_RANGE_POINTER_NV 0x8521 + +typedef void (GLAPIENTRY * PFNGLFLUSHVERTEXARRAYRANGENVPROC) (void); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYRANGENVPROC) (GLsizei length, void* pointer); + +#define glFlushVertexArrayRangeNV GLEW_GET_FUN(__glewFlushVertexArrayRangeNV) +#define glVertexArrayRangeNV GLEW_GET_FUN(__glewVertexArrayRangeNV) + +#define GLEW_NV_vertex_array_range GLEW_GET_VAR(__GLEW_NV_vertex_array_range) + +#endif /* GL_NV_vertex_array_range */ + +/* ----------------------- GL_NV_vertex_array_range2 ----------------------- */ + +#ifndef GL_NV_vertex_array_range2 +#define GL_NV_vertex_array_range2 1 + +#define GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV 0x8533 + +#define GLEW_NV_vertex_array_range2 GLEW_GET_VAR(__GLEW_NV_vertex_array_range2) + +#endif /* GL_NV_vertex_array_range2 */ + +/* -------------------------- GL_NV_vertex_program ------------------------- */ + +#ifndef GL_NV_vertex_program +#define GL_NV_vertex_program 1 + +#define GL_VERTEX_PROGRAM_NV 0x8620 +#define GL_VERTEX_STATE_PROGRAM_NV 0x8621 +#define GL_ATTRIB_ARRAY_SIZE_NV 0x8623 +#define GL_ATTRIB_ARRAY_STRIDE_NV 0x8624 +#define GL_ATTRIB_ARRAY_TYPE_NV 0x8625 +#define GL_CURRENT_ATTRIB_NV 0x8626 +#define GL_PROGRAM_LENGTH_NV 0x8627 +#define GL_PROGRAM_STRING_NV 0x8628 +#define GL_MODELVIEW_PROJECTION_NV 0x8629 +#define GL_IDENTITY_NV 0x862A +#define GL_INVERSE_NV 0x862B +#define GL_TRANSPOSE_NV 0x862C +#define GL_INVERSE_TRANSPOSE_NV 0x862D +#define GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV 0x862E +#define GL_MAX_TRACK_MATRICES_NV 0x862F +#define GL_MATRIX0_NV 0x8630 +#define GL_MATRIX1_NV 0x8631 +#define GL_MATRIX2_NV 0x8632 +#define GL_MATRIX3_NV 0x8633 +#define GL_MATRIX4_NV 0x8634 +#define GL_MATRIX5_NV 0x8635 +#define GL_MATRIX6_NV 0x8636 +#define GL_MATRIX7_NV 0x8637 +#define GL_CURRENT_MATRIX_STACK_DEPTH_NV 0x8640 +#define GL_CURRENT_MATRIX_NV 0x8641 +#define GL_VERTEX_PROGRAM_POINT_SIZE_NV 0x8642 +#define GL_VERTEX_PROGRAM_TWO_SIDE_NV 0x8643 +#define GL_PROGRAM_PARAMETER_NV 0x8644 +#define GL_ATTRIB_ARRAY_POINTER_NV 0x8645 +#define GL_PROGRAM_TARGET_NV 0x8646 +#define GL_PROGRAM_RESIDENT_NV 0x8647 +#define GL_TRACK_MATRIX_NV 0x8648 +#define GL_TRACK_MATRIX_TRANSFORM_NV 0x8649 +#define GL_VERTEX_PROGRAM_BINDING_NV 0x864A +#define GL_PROGRAM_ERROR_POSITION_NV 0x864B +#define GL_VERTEX_ATTRIB_ARRAY0_NV 0x8650 +#define GL_VERTEX_ATTRIB_ARRAY1_NV 0x8651 +#define GL_VERTEX_ATTRIB_ARRAY2_NV 0x8652 +#define GL_VERTEX_ATTRIB_ARRAY3_NV 0x8653 +#define GL_VERTEX_ATTRIB_ARRAY4_NV 0x8654 +#define GL_VERTEX_ATTRIB_ARRAY5_NV 0x8655 +#define GL_VERTEX_ATTRIB_ARRAY6_NV 0x8656 +#define GL_VERTEX_ATTRIB_ARRAY7_NV 0x8657 +#define GL_VERTEX_ATTRIB_ARRAY8_NV 0x8658 +#define GL_VERTEX_ATTRIB_ARRAY9_NV 0x8659 +#define GL_VERTEX_ATTRIB_ARRAY10_NV 0x865A +#define GL_VERTEX_ATTRIB_ARRAY11_NV 0x865B +#define GL_VERTEX_ATTRIB_ARRAY12_NV 0x865C +#define GL_VERTEX_ATTRIB_ARRAY13_NV 0x865D +#define GL_VERTEX_ATTRIB_ARRAY14_NV 0x865E +#define GL_VERTEX_ATTRIB_ARRAY15_NV 0x865F +#define GL_MAP1_VERTEX_ATTRIB0_4_NV 0x8660 +#define GL_MAP1_VERTEX_ATTRIB1_4_NV 0x8661 +#define GL_MAP1_VERTEX_ATTRIB2_4_NV 0x8662 +#define GL_MAP1_VERTEX_ATTRIB3_4_NV 0x8663 +#define GL_MAP1_VERTEX_ATTRIB4_4_NV 0x8664 +#define GL_MAP1_VERTEX_ATTRIB5_4_NV 0x8665 +#define GL_MAP1_VERTEX_ATTRIB6_4_NV 0x8666 +#define GL_MAP1_VERTEX_ATTRIB7_4_NV 0x8667 +#define GL_MAP1_VERTEX_ATTRIB8_4_NV 0x8668 +#define GL_MAP1_VERTEX_ATTRIB9_4_NV 0x8669 +#define GL_MAP1_VERTEX_ATTRIB10_4_NV 0x866A +#define GL_MAP1_VERTEX_ATTRIB11_4_NV 0x866B +#define GL_MAP1_VERTEX_ATTRIB12_4_NV 0x866C +#define GL_MAP1_VERTEX_ATTRIB13_4_NV 0x866D +#define GL_MAP1_VERTEX_ATTRIB14_4_NV 0x866E +#define GL_MAP1_VERTEX_ATTRIB15_4_NV 0x866F +#define GL_MAP2_VERTEX_ATTRIB0_4_NV 0x8670 +#define GL_MAP2_VERTEX_ATTRIB1_4_NV 0x8671 +#define GL_MAP2_VERTEX_ATTRIB2_4_NV 0x8672 +#define GL_MAP2_VERTEX_ATTRIB3_4_NV 0x8673 +#define GL_MAP2_VERTEX_ATTRIB4_4_NV 0x8674 +#define GL_MAP2_VERTEX_ATTRIB5_4_NV 0x8675 +#define GL_MAP2_VERTEX_ATTRIB6_4_NV 0x8676 +#define GL_MAP2_VERTEX_ATTRIB7_4_NV 0x8677 +#define GL_MAP2_VERTEX_ATTRIB8_4_NV 0x8678 +#define GL_MAP2_VERTEX_ATTRIB9_4_NV 0x8679 +#define GL_MAP2_VERTEX_ATTRIB10_4_NV 0x867A +#define GL_MAP2_VERTEX_ATTRIB11_4_NV 0x867B +#define GL_MAP2_VERTEX_ATTRIB12_4_NV 0x867C +#define GL_MAP2_VERTEX_ATTRIB13_4_NV 0x867D +#define GL_MAP2_VERTEX_ATTRIB14_4_NV 0x867E +#define GL_MAP2_VERTEX_ATTRIB15_4_NV 0x867F + +typedef GLboolean (GLAPIENTRY * PFNGLAREPROGRAMSRESIDENTNVPROC) (GLsizei n, const GLuint* ids, GLboolean *residences); +typedef void (GLAPIENTRY * PFNGLBINDPROGRAMNVPROC) (GLenum target, GLuint id); +typedef void (GLAPIENTRY * PFNGLDELETEPROGRAMSNVPROC) (GLsizei n, const GLuint* ids); +typedef void (GLAPIENTRY * PFNGLEXECUTEPROGRAMNVPROC) (GLenum target, GLuint id, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGENPROGRAMSNVPROC) (GLsizei n, GLuint* ids); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMPARAMETERDVNVPROC) (GLenum target, GLuint index, GLenum pname, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMSTRINGNVPROC) (GLuint id, GLenum pname, GLubyte* program); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMIVNVPROC) (GLuint id, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETTRACKMATRIXIVNVPROC) (GLenum target, GLuint address, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBPOINTERVNVPROC) (GLuint index, GLenum pname, GLvoid** pointer); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBDVNVPROC) (GLuint index, GLenum pname, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBFVNVPROC) (GLuint index, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIVNVPROC) (GLuint index, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISPROGRAMNVPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLLOADPROGRAMNVPROC) (GLenum target, GLuint id, GLsizei len, const GLubyte* program); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETER4DNVPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETER4DVNVPROC) (GLenum target, GLuint index, const GLdouble* params); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETER4FNVPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETER4FVNVPROC) (GLenum target, GLuint index, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETERS4DVNVPROC) (GLenum target, GLuint index, GLuint num, const GLdouble* params); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETERS4FVNVPROC) (GLenum target, GLuint index, GLuint num, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLREQUESTRESIDENTPROGRAMSNVPROC) (GLsizei n, GLuint* ids); +typedef void (GLAPIENTRY * PFNGLTRACKMATRIXNVPROC) (GLenum target, GLuint address, GLenum matrix, GLenum transform); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DNVPROC) (GLuint index, GLdouble x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DVNVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FNVPROC) (GLuint index, GLfloat x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FVNVPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SNVPROC) (GLuint index, GLshort x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SVNVPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DNVPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DVNVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FNVPROC) (GLuint index, GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FVNVPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SNVPROC) (GLuint index, GLshort x, GLshort y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SVNVPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DVNVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FVNVPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SVNVPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DVNVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FVNVPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SVNVPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UBNVPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UBVNVPROC) (GLuint index, const GLubyte* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBPOINTERNVPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void* pointer); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS1DVNVPROC) (GLuint index, GLsizei n, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS1FVNVPROC) (GLuint index, GLsizei n, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS1SVNVPROC) (GLuint index, GLsizei n, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS2DVNVPROC) (GLuint index, GLsizei n, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS2FVNVPROC) (GLuint index, GLsizei n, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS2SVNVPROC) (GLuint index, GLsizei n, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS3DVNVPROC) (GLuint index, GLsizei n, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS3FVNVPROC) (GLuint index, GLsizei n, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS3SVNVPROC) (GLuint index, GLsizei n, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS4DVNVPROC) (GLuint index, GLsizei n, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS4FVNVPROC) (GLuint index, GLsizei n, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS4SVNVPROC) (GLuint index, GLsizei n, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS4UBVNVPROC) (GLuint index, GLsizei n, const GLubyte* v); + +#define glAreProgramsResidentNV GLEW_GET_FUN(__glewAreProgramsResidentNV) +#define glBindProgramNV GLEW_GET_FUN(__glewBindProgramNV) +#define glDeleteProgramsNV GLEW_GET_FUN(__glewDeleteProgramsNV) +#define glExecuteProgramNV GLEW_GET_FUN(__glewExecuteProgramNV) +#define glGenProgramsNV GLEW_GET_FUN(__glewGenProgramsNV) +#define glGetProgramParameterdvNV GLEW_GET_FUN(__glewGetProgramParameterdvNV) +#define glGetProgramParameterfvNV GLEW_GET_FUN(__glewGetProgramParameterfvNV) +#define glGetProgramStringNV GLEW_GET_FUN(__glewGetProgramStringNV) +#define glGetProgramivNV GLEW_GET_FUN(__glewGetProgramivNV) +#define glGetTrackMatrixivNV GLEW_GET_FUN(__glewGetTrackMatrixivNV) +#define glGetVertexAttribPointervNV GLEW_GET_FUN(__glewGetVertexAttribPointervNV) +#define glGetVertexAttribdvNV GLEW_GET_FUN(__glewGetVertexAttribdvNV) +#define glGetVertexAttribfvNV GLEW_GET_FUN(__glewGetVertexAttribfvNV) +#define glGetVertexAttribivNV GLEW_GET_FUN(__glewGetVertexAttribivNV) +#define glIsProgramNV GLEW_GET_FUN(__glewIsProgramNV) +#define glLoadProgramNV GLEW_GET_FUN(__glewLoadProgramNV) +#define glProgramParameter4dNV GLEW_GET_FUN(__glewProgramParameter4dNV) +#define glProgramParameter4dvNV GLEW_GET_FUN(__glewProgramParameter4dvNV) +#define glProgramParameter4fNV GLEW_GET_FUN(__glewProgramParameter4fNV) +#define glProgramParameter4fvNV GLEW_GET_FUN(__glewProgramParameter4fvNV) +#define glProgramParameters4dvNV GLEW_GET_FUN(__glewProgramParameters4dvNV) +#define glProgramParameters4fvNV GLEW_GET_FUN(__glewProgramParameters4fvNV) +#define glRequestResidentProgramsNV GLEW_GET_FUN(__glewRequestResidentProgramsNV) +#define glTrackMatrixNV GLEW_GET_FUN(__glewTrackMatrixNV) +#define glVertexAttrib1dNV GLEW_GET_FUN(__glewVertexAttrib1dNV) +#define glVertexAttrib1dvNV GLEW_GET_FUN(__glewVertexAttrib1dvNV) +#define glVertexAttrib1fNV GLEW_GET_FUN(__glewVertexAttrib1fNV) +#define glVertexAttrib1fvNV GLEW_GET_FUN(__glewVertexAttrib1fvNV) +#define glVertexAttrib1sNV GLEW_GET_FUN(__glewVertexAttrib1sNV) +#define glVertexAttrib1svNV GLEW_GET_FUN(__glewVertexAttrib1svNV) +#define glVertexAttrib2dNV GLEW_GET_FUN(__glewVertexAttrib2dNV) +#define glVertexAttrib2dvNV GLEW_GET_FUN(__glewVertexAttrib2dvNV) +#define glVertexAttrib2fNV GLEW_GET_FUN(__glewVertexAttrib2fNV) +#define glVertexAttrib2fvNV GLEW_GET_FUN(__glewVertexAttrib2fvNV) +#define glVertexAttrib2sNV GLEW_GET_FUN(__glewVertexAttrib2sNV) +#define glVertexAttrib2svNV GLEW_GET_FUN(__glewVertexAttrib2svNV) +#define glVertexAttrib3dNV GLEW_GET_FUN(__glewVertexAttrib3dNV) +#define glVertexAttrib3dvNV GLEW_GET_FUN(__glewVertexAttrib3dvNV) +#define glVertexAttrib3fNV GLEW_GET_FUN(__glewVertexAttrib3fNV) +#define glVertexAttrib3fvNV GLEW_GET_FUN(__glewVertexAttrib3fvNV) +#define glVertexAttrib3sNV GLEW_GET_FUN(__glewVertexAttrib3sNV) +#define glVertexAttrib3svNV GLEW_GET_FUN(__glewVertexAttrib3svNV) +#define glVertexAttrib4dNV GLEW_GET_FUN(__glewVertexAttrib4dNV) +#define glVertexAttrib4dvNV GLEW_GET_FUN(__glewVertexAttrib4dvNV) +#define glVertexAttrib4fNV GLEW_GET_FUN(__glewVertexAttrib4fNV) +#define glVertexAttrib4fvNV GLEW_GET_FUN(__glewVertexAttrib4fvNV) +#define glVertexAttrib4sNV GLEW_GET_FUN(__glewVertexAttrib4sNV) +#define glVertexAttrib4svNV GLEW_GET_FUN(__glewVertexAttrib4svNV) +#define glVertexAttrib4ubNV GLEW_GET_FUN(__glewVertexAttrib4ubNV) +#define glVertexAttrib4ubvNV GLEW_GET_FUN(__glewVertexAttrib4ubvNV) +#define glVertexAttribPointerNV GLEW_GET_FUN(__glewVertexAttribPointerNV) +#define glVertexAttribs1dvNV GLEW_GET_FUN(__glewVertexAttribs1dvNV) +#define glVertexAttribs1fvNV GLEW_GET_FUN(__glewVertexAttribs1fvNV) +#define glVertexAttribs1svNV GLEW_GET_FUN(__glewVertexAttribs1svNV) +#define glVertexAttribs2dvNV GLEW_GET_FUN(__glewVertexAttribs2dvNV) +#define glVertexAttribs2fvNV GLEW_GET_FUN(__glewVertexAttribs2fvNV) +#define glVertexAttribs2svNV GLEW_GET_FUN(__glewVertexAttribs2svNV) +#define glVertexAttribs3dvNV GLEW_GET_FUN(__glewVertexAttribs3dvNV) +#define glVertexAttribs3fvNV GLEW_GET_FUN(__glewVertexAttribs3fvNV) +#define glVertexAttribs3svNV GLEW_GET_FUN(__glewVertexAttribs3svNV) +#define glVertexAttribs4dvNV GLEW_GET_FUN(__glewVertexAttribs4dvNV) +#define glVertexAttribs4fvNV GLEW_GET_FUN(__glewVertexAttribs4fvNV) +#define glVertexAttribs4svNV GLEW_GET_FUN(__glewVertexAttribs4svNV) +#define glVertexAttribs4ubvNV GLEW_GET_FUN(__glewVertexAttribs4ubvNV) + +#define GLEW_NV_vertex_program GLEW_GET_VAR(__GLEW_NV_vertex_program) + +#endif /* GL_NV_vertex_program */ + +/* ------------------------ GL_NV_vertex_program1_1 ------------------------ */ + +#ifndef GL_NV_vertex_program1_1 +#define GL_NV_vertex_program1_1 1 + +#define GLEW_NV_vertex_program1_1 GLEW_GET_VAR(__GLEW_NV_vertex_program1_1) + +#endif /* GL_NV_vertex_program1_1 */ + +/* ------------------------- GL_NV_vertex_program2 ------------------------- */ + +#ifndef GL_NV_vertex_program2 +#define GL_NV_vertex_program2 1 + +#define GLEW_NV_vertex_program2 GLEW_GET_VAR(__GLEW_NV_vertex_program2) + +#endif /* GL_NV_vertex_program2 */ + +/* ---------------------- GL_NV_vertex_program2_option --------------------- */ + +#ifndef GL_NV_vertex_program2_option +#define GL_NV_vertex_program2_option 1 + +#define GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV 0x88F4 +#define GL_MAX_PROGRAM_CALL_DEPTH_NV 0x88F5 + +#define GLEW_NV_vertex_program2_option GLEW_GET_VAR(__GLEW_NV_vertex_program2_option) + +#endif /* GL_NV_vertex_program2_option */ + +/* ------------------------- GL_NV_vertex_program3 ------------------------- */ + +#ifndef GL_NV_vertex_program3 +#define GL_NV_vertex_program3 1 + +#define MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB 0x8B4C + +#define GLEW_NV_vertex_program3 GLEW_GET_VAR(__GLEW_NV_vertex_program3) + +#endif /* GL_NV_vertex_program3 */ + +/* ------------------------- GL_NV_vertex_program4 ------------------------- */ + +#ifndef GL_NV_vertex_program4 +#define GL_NV_vertex_program4 1 + +#define GLEW_NV_vertex_program4 GLEW_GET_VAR(__GLEW_NV_vertex_program4) + +#endif /* GL_NV_vertex_program4 */ + +/* ------------------------ GL_OES_byte_coordinates ------------------------ */ + +#ifndef GL_OES_byte_coordinates +#define GL_OES_byte_coordinates 1 + +#define GL_BYTE 0x1400 + +#define GLEW_OES_byte_coordinates GLEW_GET_VAR(__GLEW_OES_byte_coordinates) + +#endif /* GL_OES_byte_coordinates */ + +/* ------------------- GL_OES_compressed_paletted_texture ------------------ */ + +#ifndef GL_OES_compressed_paletted_texture +#define GL_OES_compressed_paletted_texture 1 + +#define GL_PALETTE4_RGB8_OES 0x8B90 +#define GL_PALETTE4_RGBA8_OES 0x8B91 +#define GL_PALETTE4_R5_G6_B5_OES 0x8B92 +#define GL_PALETTE4_RGBA4_OES 0x8B93 +#define GL_PALETTE4_RGB5_A1_OES 0x8B94 +#define GL_PALETTE8_RGB8_OES 0x8B95 +#define GL_PALETTE8_RGBA8_OES 0x8B96 +#define GL_PALETTE8_R5_G6_B5_OES 0x8B97 +#define GL_PALETTE8_RGBA4_OES 0x8B98 +#define GL_PALETTE8_RGB5_A1_OES 0x8B99 + +#define GLEW_OES_compressed_paletted_texture GLEW_GET_VAR(__GLEW_OES_compressed_paletted_texture) + +#endif /* GL_OES_compressed_paletted_texture */ + +/* --------------------------- GL_OES_read_format -------------------------- */ + +#ifndef GL_OES_read_format +#define GL_OES_read_format 1 + +#define GL_IMPLEMENTATION_COLOR_READ_TYPE_OES 0x8B9A +#define GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES 0x8B9B + +#define GLEW_OES_read_format GLEW_GET_VAR(__GLEW_OES_read_format) + +#endif /* GL_OES_read_format */ + +/* ------------------------ GL_OES_single_precision ------------------------ */ + +#ifndef GL_OES_single_precision +#define GL_OES_single_precision 1 + +typedef void (GLAPIENTRY * PFNGLCLEARDEPTHFOESPROC) (GLclampd depth); +typedef void (GLAPIENTRY * PFNGLCLIPPLANEFOESPROC) (GLenum plane, const GLfloat* equation); +typedef void (GLAPIENTRY * PFNGLDEPTHRANGEFOESPROC) (GLclampf n, GLclampf f); +typedef void (GLAPIENTRY * PFNGLFRUSTUMFOESPROC) (GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f); +typedef void (GLAPIENTRY * PFNGLGETCLIPPLANEFOESPROC) (GLenum plane, GLfloat* equation); +typedef void (GLAPIENTRY * PFNGLORTHOFOESPROC) (GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f); + +#define glClearDepthfOES GLEW_GET_FUN(__glewClearDepthfOES) +#define glClipPlanefOES GLEW_GET_FUN(__glewClipPlanefOES) +#define glDepthRangefOES GLEW_GET_FUN(__glewDepthRangefOES) +#define glFrustumfOES GLEW_GET_FUN(__glewFrustumfOES) +#define glGetClipPlanefOES GLEW_GET_FUN(__glewGetClipPlanefOES) +#define glOrthofOES GLEW_GET_FUN(__glewOrthofOES) + +#define GLEW_OES_single_precision GLEW_GET_VAR(__GLEW_OES_single_precision) + +#endif /* GL_OES_single_precision */ + +/* ---------------------------- GL_OML_interlace --------------------------- */ + +#ifndef GL_OML_interlace +#define GL_OML_interlace 1 + +#define GL_INTERLACE_OML 0x8980 +#define GL_INTERLACE_READ_OML 0x8981 + +#define GLEW_OML_interlace GLEW_GET_VAR(__GLEW_OML_interlace) + +#endif /* GL_OML_interlace */ + +/* ---------------------------- GL_OML_resample ---------------------------- */ + +#ifndef GL_OML_resample +#define GL_OML_resample 1 + +#define GL_PACK_RESAMPLE_OML 0x8984 +#define GL_UNPACK_RESAMPLE_OML 0x8985 +#define GL_RESAMPLE_REPLICATE_OML 0x8986 +#define GL_RESAMPLE_ZERO_FILL_OML 0x8987 +#define GL_RESAMPLE_AVERAGE_OML 0x8988 +#define GL_RESAMPLE_DECIMATE_OML 0x8989 + +#define GLEW_OML_resample GLEW_GET_VAR(__GLEW_OML_resample) + +#endif /* GL_OML_resample */ + +/* ---------------------------- GL_OML_subsample --------------------------- */ + +#ifndef GL_OML_subsample +#define GL_OML_subsample 1 + +#define GL_FORMAT_SUBSAMPLE_24_24_OML 0x8982 +#define GL_FORMAT_SUBSAMPLE_244_244_OML 0x8983 + +#define GLEW_OML_subsample GLEW_GET_VAR(__GLEW_OML_subsample) + +#endif /* GL_OML_subsample */ + +/* --------------------------- GL_PGI_misc_hints --------------------------- */ + +#ifndef GL_PGI_misc_hints +#define GL_PGI_misc_hints 1 + +#define GL_PREFER_DOUBLEBUFFER_HINT_PGI 107000 +#define GL_CONSERVE_MEMORY_HINT_PGI 107005 +#define GL_RECLAIM_MEMORY_HINT_PGI 107006 +#define GL_NATIVE_GRAPHICS_HANDLE_PGI 107010 +#define GL_NATIVE_GRAPHICS_BEGIN_HINT_PGI 107011 +#define GL_NATIVE_GRAPHICS_END_HINT_PGI 107012 +#define GL_ALWAYS_FAST_HINT_PGI 107020 +#define GL_ALWAYS_SOFT_HINT_PGI 107021 +#define GL_ALLOW_DRAW_OBJ_HINT_PGI 107022 +#define GL_ALLOW_DRAW_WIN_HINT_PGI 107023 +#define GL_ALLOW_DRAW_FRG_HINT_PGI 107024 +#define GL_ALLOW_DRAW_MEM_HINT_PGI 107025 +#define GL_STRICT_DEPTHFUNC_HINT_PGI 107030 +#define GL_STRICT_LIGHTING_HINT_PGI 107031 +#define GL_STRICT_SCISSOR_HINT_PGI 107032 +#define GL_FULL_STIPPLE_HINT_PGI 107033 +#define GL_CLIP_NEAR_HINT_PGI 107040 +#define GL_CLIP_FAR_HINT_PGI 107041 +#define GL_WIDE_LINE_HINT_PGI 107042 +#define GL_BACK_NORMALS_HINT_PGI 107043 + +#define GLEW_PGI_misc_hints GLEW_GET_VAR(__GLEW_PGI_misc_hints) + +#endif /* GL_PGI_misc_hints */ + +/* -------------------------- GL_PGI_vertex_hints -------------------------- */ + +#ifndef GL_PGI_vertex_hints +#define GL_PGI_vertex_hints 1 + +#define GL_VERTEX23_BIT_PGI 0x00000004 +#define GL_VERTEX4_BIT_PGI 0x00000008 +#define GL_COLOR3_BIT_PGI 0x00010000 +#define GL_COLOR4_BIT_PGI 0x00020000 +#define GL_EDGEFLAG_BIT_PGI 0x00040000 +#define GL_INDEX_BIT_PGI 0x00080000 +#define GL_MAT_AMBIENT_BIT_PGI 0x00100000 +#define GL_VERTEX_DATA_HINT_PGI 107050 +#define GL_VERTEX_CONSISTENT_HINT_PGI 107051 +#define GL_MATERIAL_SIDE_HINT_PGI 107052 +#define GL_MAX_VERTEX_HINT_PGI 107053 +#define GL_MAT_AMBIENT_AND_DIFFUSE_BIT_PGI 0x00200000 +#define GL_MAT_DIFFUSE_BIT_PGI 0x00400000 +#define GL_MAT_EMISSION_BIT_PGI 0x00800000 +#define GL_MAT_COLOR_INDEXES_BIT_PGI 0x01000000 +#define GL_MAT_SHININESS_BIT_PGI 0x02000000 +#define GL_MAT_SPECULAR_BIT_PGI 0x04000000 +#define GL_NORMAL_BIT_PGI 0x08000000 +#define GL_TEXCOORD1_BIT_PGI 0x10000000 +#define GL_TEXCOORD2_BIT_PGI 0x20000000 +#define GL_TEXCOORD3_BIT_PGI 0x40000000 +#define GL_TEXCOORD4_BIT_PGI 0x80000000 + +#define GLEW_PGI_vertex_hints GLEW_GET_VAR(__GLEW_PGI_vertex_hints) + +#endif /* GL_PGI_vertex_hints */ + +/* ----------------------- GL_REND_screen_coordinates ---------------------- */ + +#ifndef GL_REND_screen_coordinates +#define GL_REND_screen_coordinates 1 + +#define GL_SCREEN_COORDINATES_REND 0x8490 +#define GL_INVERTED_SCREEN_W_REND 0x8491 + +#define GLEW_REND_screen_coordinates GLEW_GET_VAR(__GLEW_REND_screen_coordinates) + +#endif /* GL_REND_screen_coordinates */ + +/* ------------------------------- GL_S3_s3tc ------------------------------ */ + +#ifndef GL_S3_s3tc +#define GL_S3_s3tc 1 + +#define GL_RGB_S3TC 0x83A0 +#define GL_RGB4_S3TC 0x83A1 +#define GL_RGBA_S3TC 0x83A2 +#define GL_RGBA4_S3TC 0x83A3 +#define GL_RGBA_DXT5_S3TC 0x83A4 +#define GL_RGBA4_DXT5_S3TC 0x83A5 + +#define GLEW_S3_s3tc GLEW_GET_VAR(__GLEW_S3_s3tc) + +#endif /* GL_S3_s3tc */ + +/* -------------------------- GL_SGIS_color_range -------------------------- */ + +#ifndef GL_SGIS_color_range +#define GL_SGIS_color_range 1 + +#define GL_EXTENDED_RANGE_SGIS 0x85A5 +#define GL_MIN_RED_SGIS 0x85A6 +#define GL_MAX_RED_SGIS 0x85A7 +#define GL_MIN_GREEN_SGIS 0x85A8 +#define GL_MAX_GREEN_SGIS 0x85A9 +#define GL_MIN_BLUE_SGIS 0x85AA +#define GL_MAX_BLUE_SGIS 0x85AB +#define GL_MIN_ALPHA_SGIS 0x85AC +#define GL_MAX_ALPHA_SGIS 0x85AD + +#define GLEW_SGIS_color_range GLEW_GET_VAR(__GLEW_SGIS_color_range) + +#endif /* GL_SGIS_color_range */ + +/* ------------------------- GL_SGIS_detail_texture ------------------------ */ + +#ifndef GL_SGIS_detail_texture +#define GL_SGIS_detail_texture 1 + +typedef void (GLAPIENTRY * PFNGLDETAILTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat* points); +typedef void (GLAPIENTRY * PFNGLGETDETAILTEXFUNCSGISPROC) (GLenum target, GLfloat* points); + +#define glDetailTexFuncSGIS GLEW_GET_FUN(__glewDetailTexFuncSGIS) +#define glGetDetailTexFuncSGIS GLEW_GET_FUN(__glewGetDetailTexFuncSGIS) + +#define GLEW_SGIS_detail_texture GLEW_GET_VAR(__GLEW_SGIS_detail_texture) + +#endif /* GL_SGIS_detail_texture */ + +/* -------------------------- GL_SGIS_fog_function ------------------------- */ + +#ifndef GL_SGIS_fog_function +#define GL_SGIS_fog_function 1 + +typedef void (GLAPIENTRY * PFNGLFOGFUNCSGISPROC) (GLsizei n, const GLfloat* points); +typedef void (GLAPIENTRY * PFNGLGETFOGFUNCSGISPROC) (GLfloat* points); + +#define glFogFuncSGIS GLEW_GET_FUN(__glewFogFuncSGIS) +#define glGetFogFuncSGIS GLEW_GET_FUN(__glewGetFogFuncSGIS) + +#define GLEW_SGIS_fog_function GLEW_GET_VAR(__GLEW_SGIS_fog_function) + +#endif /* GL_SGIS_fog_function */ + +/* ------------------------ GL_SGIS_generate_mipmap ------------------------ */ + +#ifndef GL_SGIS_generate_mipmap +#define GL_SGIS_generate_mipmap 1 + +#define GL_GENERATE_MIPMAP_SGIS 0x8191 +#define GL_GENERATE_MIPMAP_HINT_SGIS 0x8192 + +#define GLEW_SGIS_generate_mipmap GLEW_GET_VAR(__GLEW_SGIS_generate_mipmap) + +#endif /* GL_SGIS_generate_mipmap */ + +/* -------------------------- GL_SGIS_multisample -------------------------- */ + +#ifndef GL_SGIS_multisample +#define GL_SGIS_multisample 1 + +#define GL_MULTISAMPLE_SGIS 0x809D +#define GL_SAMPLE_ALPHA_TO_MASK_SGIS 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_SGIS 0x809F +#define GL_SAMPLE_MASK_SGIS 0x80A0 +#define GL_1PASS_SGIS 0x80A1 +#define GL_2PASS_0_SGIS 0x80A2 +#define GL_2PASS_1_SGIS 0x80A3 +#define GL_4PASS_0_SGIS 0x80A4 +#define GL_4PASS_1_SGIS 0x80A5 +#define GL_4PASS_2_SGIS 0x80A6 +#define GL_4PASS_3_SGIS 0x80A7 +#define GL_SAMPLE_BUFFERS_SGIS 0x80A8 +#define GL_SAMPLES_SGIS 0x80A9 +#define GL_SAMPLE_MASK_VALUE_SGIS 0x80AA +#define GL_SAMPLE_MASK_INVERT_SGIS 0x80AB +#define GL_SAMPLE_PATTERN_SGIS 0x80AC +#define GL_MULTISAMPLE_BIT_EXT 0x20000000 + +typedef void (GLAPIENTRY * PFNGLSAMPLEMASKSGISPROC) (GLclampf value, GLboolean invert); +typedef void (GLAPIENTRY * PFNGLSAMPLEPATTERNSGISPROC) (GLenum pattern); + +#define glSampleMaskSGIS GLEW_GET_FUN(__glewSampleMaskSGIS) +#define glSamplePatternSGIS GLEW_GET_FUN(__glewSamplePatternSGIS) + +#define GLEW_SGIS_multisample GLEW_GET_VAR(__GLEW_SGIS_multisample) + +#endif /* GL_SGIS_multisample */ + +/* ------------------------- GL_SGIS_pixel_texture ------------------------- */ + +#ifndef GL_SGIS_pixel_texture +#define GL_SGIS_pixel_texture 1 + +#define GLEW_SGIS_pixel_texture GLEW_GET_VAR(__GLEW_SGIS_pixel_texture) + +#endif /* GL_SGIS_pixel_texture */ + +/* ----------------------- GL_SGIS_point_line_texgen ----------------------- */ + +#ifndef GL_SGIS_point_line_texgen +#define GL_SGIS_point_line_texgen 1 + +#define GL_EYE_DISTANCE_TO_POINT_SGIS 0x81F0 +#define GL_OBJECT_DISTANCE_TO_POINT_SGIS 0x81F1 +#define GL_EYE_DISTANCE_TO_LINE_SGIS 0x81F2 +#define GL_OBJECT_DISTANCE_TO_LINE_SGIS 0x81F3 +#define GL_EYE_POINT_SGIS 0x81F4 +#define GL_OBJECT_POINT_SGIS 0x81F5 +#define GL_EYE_LINE_SGIS 0x81F6 +#define GL_OBJECT_LINE_SGIS 0x81F7 + +#define GLEW_SGIS_point_line_texgen GLEW_GET_VAR(__GLEW_SGIS_point_line_texgen) + +#endif /* GL_SGIS_point_line_texgen */ + +/* ------------------------ GL_SGIS_sharpen_texture ------------------------ */ + +#ifndef GL_SGIS_sharpen_texture +#define GL_SGIS_sharpen_texture 1 + +typedef void (GLAPIENTRY * PFNGLGETSHARPENTEXFUNCSGISPROC) (GLenum target, GLfloat* points); +typedef void (GLAPIENTRY * PFNGLSHARPENTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat* points); + +#define glGetSharpenTexFuncSGIS GLEW_GET_FUN(__glewGetSharpenTexFuncSGIS) +#define glSharpenTexFuncSGIS GLEW_GET_FUN(__glewSharpenTexFuncSGIS) + +#define GLEW_SGIS_sharpen_texture GLEW_GET_VAR(__GLEW_SGIS_sharpen_texture) + +#endif /* GL_SGIS_sharpen_texture */ + +/* --------------------------- GL_SGIS_texture4D --------------------------- */ + +#ifndef GL_SGIS_texture4D +#define GL_SGIS_texture4D 1 + +typedef void (GLAPIENTRY * PFNGLTEXIMAGE4DSGISPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLsizei extent, GLint border, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE4DSGISPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint woffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei extent, GLenum format, GLenum type, const void* pixels); + +#define glTexImage4DSGIS GLEW_GET_FUN(__glewTexImage4DSGIS) +#define glTexSubImage4DSGIS GLEW_GET_FUN(__glewTexSubImage4DSGIS) + +#define GLEW_SGIS_texture4D GLEW_GET_VAR(__GLEW_SGIS_texture4D) + +#endif /* GL_SGIS_texture4D */ + +/* ---------------------- GL_SGIS_texture_border_clamp --------------------- */ + +#ifndef GL_SGIS_texture_border_clamp +#define GL_SGIS_texture_border_clamp 1 + +#define GL_CLAMP_TO_BORDER_SGIS 0x812D + +#define GLEW_SGIS_texture_border_clamp GLEW_GET_VAR(__GLEW_SGIS_texture_border_clamp) + +#endif /* GL_SGIS_texture_border_clamp */ + +/* ----------------------- GL_SGIS_texture_edge_clamp ---------------------- */ + +#ifndef GL_SGIS_texture_edge_clamp +#define GL_SGIS_texture_edge_clamp 1 + +#define GL_CLAMP_TO_EDGE_SGIS 0x812F + +#define GLEW_SGIS_texture_edge_clamp GLEW_GET_VAR(__GLEW_SGIS_texture_edge_clamp) + +#endif /* GL_SGIS_texture_edge_clamp */ + +/* ------------------------ GL_SGIS_texture_filter4 ------------------------ */ + +#ifndef GL_SGIS_texture_filter4 +#define GL_SGIS_texture_filter4 1 + +typedef void (GLAPIENTRY * PFNGLGETTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLfloat* weights); +typedef void (GLAPIENTRY * PFNGLTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLsizei n, const GLfloat* weights); + +#define glGetTexFilterFuncSGIS GLEW_GET_FUN(__glewGetTexFilterFuncSGIS) +#define glTexFilterFuncSGIS GLEW_GET_FUN(__glewTexFilterFuncSGIS) + +#define GLEW_SGIS_texture_filter4 GLEW_GET_VAR(__GLEW_SGIS_texture_filter4) + +#endif /* GL_SGIS_texture_filter4 */ + +/* -------------------------- GL_SGIS_texture_lod -------------------------- */ + +#ifndef GL_SGIS_texture_lod +#define GL_SGIS_texture_lod 1 + +#define GL_TEXTURE_MIN_LOD_SGIS 0x813A +#define GL_TEXTURE_MAX_LOD_SGIS 0x813B +#define GL_TEXTURE_BASE_LEVEL_SGIS 0x813C +#define GL_TEXTURE_MAX_LEVEL_SGIS 0x813D + +#define GLEW_SGIS_texture_lod GLEW_GET_VAR(__GLEW_SGIS_texture_lod) + +#endif /* GL_SGIS_texture_lod */ + +/* ------------------------- GL_SGIS_texture_select ------------------------ */ + +#ifndef GL_SGIS_texture_select +#define GL_SGIS_texture_select 1 + +#define GLEW_SGIS_texture_select GLEW_GET_VAR(__GLEW_SGIS_texture_select) + +#endif /* GL_SGIS_texture_select */ + +/* ----------------------------- GL_SGIX_async ----------------------------- */ + +#ifndef GL_SGIX_async +#define GL_SGIX_async 1 + +#define GL_ASYNC_MARKER_SGIX 0x8329 + +typedef void (GLAPIENTRY * PFNGLASYNCMARKERSGIXPROC) (GLuint marker); +typedef void (GLAPIENTRY * PFNGLDELETEASYNCMARKERSSGIXPROC) (GLuint marker, GLsizei range); +typedef GLint (GLAPIENTRY * PFNGLFINISHASYNCSGIXPROC) (GLuint* markerp); +typedef GLuint (GLAPIENTRY * PFNGLGENASYNCMARKERSSGIXPROC) (GLsizei range); +typedef GLboolean (GLAPIENTRY * PFNGLISASYNCMARKERSGIXPROC) (GLuint marker); +typedef GLint (GLAPIENTRY * PFNGLPOLLASYNCSGIXPROC) (GLuint* markerp); + +#define glAsyncMarkerSGIX GLEW_GET_FUN(__glewAsyncMarkerSGIX) +#define glDeleteAsyncMarkersSGIX GLEW_GET_FUN(__glewDeleteAsyncMarkersSGIX) +#define glFinishAsyncSGIX GLEW_GET_FUN(__glewFinishAsyncSGIX) +#define glGenAsyncMarkersSGIX GLEW_GET_FUN(__glewGenAsyncMarkersSGIX) +#define glIsAsyncMarkerSGIX GLEW_GET_FUN(__glewIsAsyncMarkerSGIX) +#define glPollAsyncSGIX GLEW_GET_FUN(__glewPollAsyncSGIX) + +#define GLEW_SGIX_async GLEW_GET_VAR(__GLEW_SGIX_async) + +#endif /* GL_SGIX_async */ + +/* ------------------------ GL_SGIX_async_histogram ------------------------ */ + +#ifndef GL_SGIX_async_histogram +#define GL_SGIX_async_histogram 1 + +#define GL_ASYNC_HISTOGRAM_SGIX 0x832C +#define GL_MAX_ASYNC_HISTOGRAM_SGIX 0x832D + +#define GLEW_SGIX_async_histogram GLEW_GET_VAR(__GLEW_SGIX_async_histogram) + +#endif /* GL_SGIX_async_histogram */ + +/* -------------------------- GL_SGIX_async_pixel -------------------------- */ + +#ifndef GL_SGIX_async_pixel +#define GL_SGIX_async_pixel 1 + +#define GL_ASYNC_TEX_IMAGE_SGIX 0x835C +#define GL_ASYNC_DRAW_PIXELS_SGIX 0x835D +#define GL_ASYNC_READ_PIXELS_SGIX 0x835E +#define GL_MAX_ASYNC_TEX_IMAGE_SGIX 0x835F +#define GL_MAX_ASYNC_DRAW_PIXELS_SGIX 0x8360 +#define GL_MAX_ASYNC_READ_PIXELS_SGIX 0x8361 + +#define GLEW_SGIX_async_pixel GLEW_GET_VAR(__GLEW_SGIX_async_pixel) + +#endif /* GL_SGIX_async_pixel */ + +/* ----------------------- GL_SGIX_blend_alpha_minmax ---------------------- */ + +#ifndef GL_SGIX_blend_alpha_minmax +#define GL_SGIX_blend_alpha_minmax 1 + +#define GL_ALPHA_MIN_SGIX 0x8320 +#define GL_ALPHA_MAX_SGIX 0x8321 + +#define GLEW_SGIX_blend_alpha_minmax GLEW_GET_VAR(__GLEW_SGIX_blend_alpha_minmax) + +#endif /* GL_SGIX_blend_alpha_minmax */ + +/* ---------------------------- GL_SGIX_clipmap ---------------------------- */ + +#ifndef GL_SGIX_clipmap +#define GL_SGIX_clipmap 1 + +#define GLEW_SGIX_clipmap GLEW_GET_VAR(__GLEW_SGIX_clipmap) + +#endif /* GL_SGIX_clipmap */ + +/* ---------------------- GL_SGIX_convolution_accuracy --------------------- */ + +#ifndef GL_SGIX_convolution_accuracy +#define GL_SGIX_convolution_accuracy 1 + +#define GL_CONVOLUTION_HINT_SGIX 0x8316 + +#define GLEW_SGIX_convolution_accuracy GLEW_GET_VAR(__GLEW_SGIX_convolution_accuracy) + +#endif /* GL_SGIX_convolution_accuracy */ + +/* ------------------------- GL_SGIX_depth_texture ------------------------- */ + +#ifndef GL_SGIX_depth_texture +#define GL_SGIX_depth_texture 1 + +#define GL_DEPTH_COMPONENT16_SGIX 0x81A5 +#define GL_DEPTH_COMPONENT24_SGIX 0x81A6 +#define GL_DEPTH_COMPONENT32_SGIX 0x81A7 + +#define GLEW_SGIX_depth_texture GLEW_GET_VAR(__GLEW_SGIX_depth_texture) + +#endif /* GL_SGIX_depth_texture */ + +/* -------------------------- GL_SGIX_flush_raster ------------------------- */ + +#ifndef GL_SGIX_flush_raster +#define GL_SGIX_flush_raster 1 + +typedef void (GLAPIENTRY * PFNGLFLUSHRASTERSGIXPROC) (void); + +#define glFlushRasterSGIX GLEW_GET_FUN(__glewFlushRasterSGIX) + +#define GLEW_SGIX_flush_raster GLEW_GET_VAR(__GLEW_SGIX_flush_raster) + +#endif /* GL_SGIX_flush_raster */ + +/* --------------------------- GL_SGIX_fog_offset -------------------------- */ + +#ifndef GL_SGIX_fog_offset +#define GL_SGIX_fog_offset 1 + +#define GL_FOG_OFFSET_SGIX 0x8198 +#define GL_FOG_OFFSET_VALUE_SGIX 0x8199 + +#define GLEW_SGIX_fog_offset GLEW_GET_VAR(__GLEW_SGIX_fog_offset) + +#endif /* GL_SGIX_fog_offset */ + +/* -------------------------- GL_SGIX_fog_texture -------------------------- */ + +#ifndef GL_SGIX_fog_texture +#define GL_SGIX_fog_texture 1 + +#define GL_TEXTURE_FOG_SGIX 0 +#define GL_FOG_PATCHY_FACTOR_SGIX 0 +#define GL_FRAGMENT_FOG_SGIX 0 + +typedef void (GLAPIENTRY * PFNGLTEXTUREFOGSGIXPROC) (GLenum pname); + +#define glTextureFogSGIX GLEW_GET_FUN(__glewTextureFogSGIX) + +#define GLEW_SGIX_fog_texture GLEW_GET_VAR(__GLEW_SGIX_fog_texture) + +#endif /* GL_SGIX_fog_texture */ + +/* ------------------- GL_SGIX_fragment_specular_lighting ------------------ */ + +#ifndef GL_SGIX_fragment_specular_lighting +#define GL_SGIX_fragment_specular_lighting 1 + +typedef void (GLAPIENTRY * PFNGLFRAGMENTCOLORMATERIALSGIXPROC) (GLenum face, GLenum mode); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELFSGIXPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELFVSGIXPROC) (GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELISGIXPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELIVSGIXPROC) (GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTFSGIXPROC) (GLenum light, GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTISGIXPROC) (GLenum light, GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALFSGIXPROC) (GLenum face, GLenum pname, const GLfloat param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALISGIXPROC) (GLenum face, GLenum pname, const GLint param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLGETFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum value, GLfloat* data); +typedef void (GLAPIENTRY * PFNGLGETFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum value, GLint* data); +typedef void (GLAPIENTRY * PFNGLGETFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, const GLfloat* data); +typedef void (GLAPIENTRY * PFNGLGETFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, const GLint* data); + +#define glFragmentColorMaterialSGIX GLEW_GET_FUN(__glewFragmentColorMaterialSGIX) +#define glFragmentLightModelfSGIX GLEW_GET_FUN(__glewFragmentLightModelfSGIX) +#define glFragmentLightModelfvSGIX GLEW_GET_FUN(__glewFragmentLightModelfvSGIX) +#define glFragmentLightModeliSGIX GLEW_GET_FUN(__glewFragmentLightModeliSGIX) +#define glFragmentLightModelivSGIX GLEW_GET_FUN(__glewFragmentLightModelivSGIX) +#define glFragmentLightfSGIX GLEW_GET_FUN(__glewFragmentLightfSGIX) +#define glFragmentLightfvSGIX GLEW_GET_FUN(__glewFragmentLightfvSGIX) +#define glFragmentLightiSGIX GLEW_GET_FUN(__glewFragmentLightiSGIX) +#define glFragmentLightivSGIX GLEW_GET_FUN(__glewFragmentLightivSGIX) +#define glFragmentMaterialfSGIX GLEW_GET_FUN(__glewFragmentMaterialfSGIX) +#define glFragmentMaterialfvSGIX GLEW_GET_FUN(__glewFragmentMaterialfvSGIX) +#define glFragmentMaterialiSGIX GLEW_GET_FUN(__glewFragmentMaterialiSGIX) +#define glFragmentMaterialivSGIX GLEW_GET_FUN(__glewFragmentMaterialivSGIX) +#define glGetFragmentLightfvSGIX GLEW_GET_FUN(__glewGetFragmentLightfvSGIX) +#define glGetFragmentLightivSGIX GLEW_GET_FUN(__glewGetFragmentLightivSGIX) +#define glGetFragmentMaterialfvSGIX GLEW_GET_FUN(__glewGetFragmentMaterialfvSGIX) +#define glGetFragmentMaterialivSGIX GLEW_GET_FUN(__glewGetFragmentMaterialivSGIX) + +#define GLEW_SGIX_fragment_specular_lighting GLEW_GET_VAR(__GLEW_SGIX_fragment_specular_lighting) + +#endif /* GL_SGIX_fragment_specular_lighting */ + +/* --------------------------- GL_SGIX_framezoom --------------------------- */ + +#ifndef GL_SGIX_framezoom +#define GL_SGIX_framezoom 1 + +typedef void (GLAPIENTRY * PFNGLFRAMEZOOMSGIXPROC) (GLint factor); + +#define glFrameZoomSGIX GLEW_GET_FUN(__glewFrameZoomSGIX) + +#define GLEW_SGIX_framezoom GLEW_GET_VAR(__GLEW_SGIX_framezoom) + +#endif /* GL_SGIX_framezoom */ + +/* --------------------------- GL_SGIX_interlace --------------------------- */ + +#ifndef GL_SGIX_interlace +#define GL_SGIX_interlace 1 + +#define GL_INTERLACE_SGIX 0x8094 + +#define GLEW_SGIX_interlace GLEW_GET_VAR(__GLEW_SGIX_interlace) + +#endif /* GL_SGIX_interlace */ + +/* ------------------------- GL_SGIX_ir_instrument1 ------------------------ */ + +#ifndef GL_SGIX_ir_instrument1 +#define GL_SGIX_ir_instrument1 1 + +#define GLEW_SGIX_ir_instrument1 GLEW_GET_VAR(__GLEW_SGIX_ir_instrument1) + +#endif /* GL_SGIX_ir_instrument1 */ + +/* ------------------------- GL_SGIX_list_priority ------------------------- */ + +#ifndef GL_SGIX_list_priority +#define GL_SGIX_list_priority 1 + +#define GLEW_SGIX_list_priority GLEW_GET_VAR(__GLEW_SGIX_list_priority) + +#endif /* GL_SGIX_list_priority */ + +/* ------------------------- GL_SGIX_pixel_texture ------------------------- */ + +#ifndef GL_SGIX_pixel_texture +#define GL_SGIX_pixel_texture 1 + +typedef void (GLAPIENTRY * PFNGLPIXELTEXGENSGIXPROC) (GLenum mode); + +#define glPixelTexGenSGIX GLEW_GET_FUN(__glewPixelTexGenSGIX) + +#define GLEW_SGIX_pixel_texture GLEW_GET_VAR(__GLEW_SGIX_pixel_texture) + +#endif /* GL_SGIX_pixel_texture */ + +/* ----------------------- GL_SGIX_pixel_texture_bits ---------------------- */ + +#ifndef GL_SGIX_pixel_texture_bits +#define GL_SGIX_pixel_texture_bits 1 + +#define GLEW_SGIX_pixel_texture_bits GLEW_GET_VAR(__GLEW_SGIX_pixel_texture_bits) + +#endif /* GL_SGIX_pixel_texture_bits */ + +/* ------------------------ GL_SGIX_reference_plane ------------------------ */ + +#ifndef GL_SGIX_reference_plane +#define GL_SGIX_reference_plane 1 + +typedef void (GLAPIENTRY * PFNGLREFERENCEPLANESGIXPROC) (const GLdouble* equation); + +#define glReferencePlaneSGIX GLEW_GET_FUN(__glewReferencePlaneSGIX) + +#define GLEW_SGIX_reference_plane GLEW_GET_VAR(__GLEW_SGIX_reference_plane) + +#endif /* GL_SGIX_reference_plane */ + +/* ---------------------------- GL_SGIX_resample --------------------------- */ + +#ifndef GL_SGIX_resample +#define GL_SGIX_resample 1 + +#define GL_PACK_RESAMPLE_SGIX 0x842E +#define GL_UNPACK_RESAMPLE_SGIX 0x842F +#define GL_RESAMPLE_DECIMATE_SGIX 0x8430 +#define GL_RESAMPLE_REPLICATE_SGIX 0x8433 +#define GL_RESAMPLE_ZERO_FILL_SGIX 0x8434 + +#define GLEW_SGIX_resample GLEW_GET_VAR(__GLEW_SGIX_resample) + +#endif /* GL_SGIX_resample */ + +/* ----------------------------- GL_SGIX_shadow ---------------------------- */ + +#ifndef GL_SGIX_shadow +#define GL_SGIX_shadow 1 + +#define GL_TEXTURE_COMPARE_SGIX 0x819A +#define GL_TEXTURE_COMPARE_OPERATOR_SGIX 0x819B +#define GL_TEXTURE_LEQUAL_R_SGIX 0x819C +#define GL_TEXTURE_GEQUAL_R_SGIX 0x819D + +#define GLEW_SGIX_shadow GLEW_GET_VAR(__GLEW_SGIX_shadow) + +#endif /* GL_SGIX_shadow */ + +/* ------------------------- GL_SGIX_shadow_ambient ------------------------ */ + +#ifndef GL_SGIX_shadow_ambient +#define GL_SGIX_shadow_ambient 1 + +#define GL_SHADOW_AMBIENT_SGIX 0x80BF + +#define GLEW_SGIX_shadow_ambient GLEW_GET_VAR(__GLEW_SGIX_shadow_ambient) + +#endif /* GL_SGIX_shadow_ambient */ + +/* ----------------------------- GL_SGIX_sprite ---------------------------- */ + +#ifndef GL_SGIX_sprite +#define GL_SGIX_sprite 1 + +typedef void (GLAPIENTRY * PFNGLSPRITEPARAMETERFSGIXPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLSPRITEPARAMETERFVSGIXPROC) (GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLSPRITEPARAMETERISGIXPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLSPRITEPARAMETERIVSGIXPROC) (GLenum pname, GLint* params); + +#define glSpriteParameterfSGIX GLEW_GET_FUN(__glewSpriteParameterfSGIX) +#define glSpriteParameterfvSGIX GLEW_GET_FUN(__glewSpriteParameterfvSGIX) +#define glSpriteParameteriSGIX GLEW_GET_FUN(__glewSpriteParameteriSGIX) +#define glSpriteParameterivSGIX GLEW_GET_FUN(__glewSpriteParameterivSGIX) + +#define GLEW_SGIX_sprite GLEW_GET_VAR(__GLEW_SGIX_sprite) + +#endif /* GL_SGIX_sprite */ + +/* ----------------------- GL_SGIX_tag_sample_buffer ----------------------- */ + +#ifndef GL_SGIX_tag_sample_buffer +#define GL_SGIX_tag_sample_buffer 1 + +typedef void (GLAPIENTRY * PFNGLTAGSAMPLEBUFFERSGIXPROC) (void); + +#define glTagSampleBufferSGIX GLEW_GET_FUN(__glewTagSampleBufferSGIX) + +#define GLEW_SGIX_tag_sample_buffer GLEW_GET_VAR(__GLEW_SGIX_tag_sample_buffer) + +#endif /* GL_SGIX_tag_sample_buffer */ + +/* ------------------------ GL_SGIX_texture_add_env ------------------------ */ + +#ifndef GL_SGIX_texture_add_env +#define GL_SGIX_texture_add_env 1 + +#define GLEW_SGIX_texture_add_env GLEW_GET_VAR(__GLEW_SGIX_texture_add_env) + +#endif /* GL_SGIX_texture_add_env */ + +/* -------------------- GL_SGIX_texture_coordinate_clamp ------------------- */ + +#ifndef GL_SGIX_texture_coordinate_clamp +#define GL_SGIX_texture_coordinate_clamp 1 + +#define GL_TEXTURE_MAX_CLAMP_S_SGIX 0x8369 +#define GL_TEXTURE_MAX_CLAMP_T_SGIX 0x836A +#define GL_TEXTURE_MAX_CLAMP_R_SGIX 0x836B + +#define GLEW_SGIX_texture_coordinate_clamp GLEW_GET_VAR(__GLEW_SGIX_texture_coordinate_clamp) + +#endif /* GL_SGIX_texture_coordinate_clamp */ + +/* ------------------------ GL_SGIX_texture_lod_bias ----------------------- */ + +#ifndef GL_SGIX_texture_lod_bias +#define GL_SGIX_texture_lod_bias 1 + +#define GLEW_SGIX_texture_lod_bias GLEW_GET_VAR(__GLEW_SGIX_texture_lod_bias) + +#endif /* GL_SGIX_texture_lod_bias */ + +/* ---------------------- GL_SGIX_texture_multi_buffer --------------------- */ + +#ifndef GL_SGIX_texture_multi_buffer +#define GL_SGIX_texture_multi_buffer 1 + +#define GL_TEXTURE_MULTI_BUFFER_HINT_SGIX 0x812E + +#define GLEW_SGIX_texture_multi_buffer GLEW_GET_VAR(__GLEW_SGIX_texture_multi_buffer) + +#endif /* GL_SGIX_texture_multi_buffer */ + +/* ------------------------- GL_SGIX_texture_range ------------------------- */ + +#ifndef GL_SGIX_texture_range +#define GL_SGIX_texture_range 1 + +#define GL_RGB_SIGNED_SGIX 0x85E0 +#define GL_RGBA_SIGNED_SGIX 0x85E1 +#define GL_ALPHA_SIGNED_SGIX 0x85E2 +#define GL_LUMINANCE_SIGNED_SGIX 0x85E3 +#define GL_INTENSITY_SIGNED_SGIX 0x85E4 +#define GL_LUMINANCE_ALPHA_SIGNED_SGIX 0x85E5 +#define GL_RGB16_SIGNED_SGIX 0x85E6 +#define GL_RGBA16_SIGNED_SGIX 0x85E7 +#define GL_ALPHA16_SIGNED_SGIX 0x85E8 +#define GL_LUMINANCE16_SIGNED_SGIX 0x85E9 +#define GL_INTENSITY16_SIGNED_SGIX 0x85EA +#define GL_LUMINANCE16_ALPHA16_SIGNED_SGIX 0x85EB +#define GL_RGB_EXTENDED_RANGE_SGIX 0x85EC +#define GL_RGBA_EXTENDED_RANGE_SGIX 0x85ED +#define GL_ALPHA_EXTENDED_RANGE_SGIX 0x85EE +#define GL_LUMINANCE_EXTENDED_RANGE_SGIX 0x85EF +#define GL_INTENSITY_EXTENDED_RANGE_SGIX 0x85F0 +#define GL_LUMINANCE_ALPHA_EXTENDED_RANGE_SGIX 0x85F1 +#define GL_RGB16_EXTENDED_RANGE_SGIX 0x85F2 +#define GL_RGBA16_EXTENDED_RANGE_SGIX 0x85F3 +#define GL_ALPHA16_EXTENDED_RANGE_SGIX 0x85F4 +#define GL_LUMINANCE16_EXTENDED_RANGE_SGIX 0x85F5 +#define GL_INTENSITY16_EXTENDED_RANGE_SGIX 0x85F6 +#define GL_LUMINANCE16_ALPHA16_EXTENDED_RANGE_SGIX 0x85F7 +#define GL_MIN_LUMINANCE_SGIS 0x85F8 +#define GL_MAX_LUMINANCE_SGIS 0x85F9 +#define GL_MIN_INTENSITY_SGIS 0x85FA +#define GL_MAX_INTENSITY_SGIS 0x85FB + +#define GLEW_SGIX_texture_range GLEW_GET_VAR(__GLEW_SGIX_texture_range) + +#endif /* GL_SGIX_texture_range */ + +/* ----------------------- GL_SGIX_texture_scale_bias ---------------------- */ + +#ifndef GL_SGIX_texture_scale_bias +#define GL_SGIX_texture_scale_bias 1 + +#define GL_POST_TEXTURE_FILTER_BIAS_SGIX 0x8179 +#define GL_POST_TEXTURE_FILTER_SCALE_SGIX 0x817A +#define GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX 0x817B +#define GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX 0x817C + +#define GLEW_SGIX_texture_scale_bias GLEW_GET_VAR(__GLEW_SGIX_texture_scale_bias) + +#endif /* GL_SGIX_texture_scale_bias */ + +/* ------------------------- GL_SGIX_vertex_preclip ------------------------ */ + +#ifndef GL_SGIX_vertex_preclip +#define GL_SGIX_vertex_preclip 1 + +#define GL_VERTEX_PRECLIP_SGIX 0x83EE +#define GL_VERTEX_PRECLIP_HINT_SGIX 0x83EF + +#define GLEW_SGIX_vertex_preclip GLEW_GET_VAR(__GLEW_SGIX_vertex_preclip) + +#endif /* GL_SGIX_vertex_preclip */ + +/* ---------------------- GL_SGIX_vertex_preclip_hint ---------------------- */ + +#ifndef GL_SGIX_vertex_preclip_hint +#define GL_SGIX_vertex_preclip_hint 1 + +#define GL_VERTEX_PRECLIP_SGIX 0x83EE +#define GL_VERTEX_PRECLIP_HINT_SGIX 0x83EF + +#define GLEW_SGIX_vertex_preclip_hint GLEW_GET_VAR(__GLEW_SGIX_vertex_preclip_hint) + +#endif /* GL_SGIX_vertex_preclip_hint */ + +/* ----------------------------- GL_SGIX_ycrcb ----------------------------- */ + +#ifndef GL_SGIX_ycrcb +#define GL_SGIX_ycrcb 1 + +#define GLEW_SGIX_ycrcb GLEW_GET_VAR(__GLEW_SGIX_ycrcb) + +#endif /* GL_SGIX_ycrcb */ + +/* -------------------------- GL_SGI_color_matrix -------------------------- */ + +#ifndef GL_SGI_color_matrix +#define GL_SGI_color_matrix 1 + +#define GL_COLOR_MATRIX_SGI 0x80B1 +#define GL_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B2 +#define GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B3 +#define GL_POST_COLOR_MATRIX_RED_SCALE_SGI 0x80B4 +#define GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI 0x80B5 +#define GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI 0x80B6 +#define GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI 0x80B7 +#define GL_POST_COLOR_MATRIX_RED_BIAS_SGI 0x80B8 +#define GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI 0x80B9 +#define GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI 0x80BA +#define GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI 0x80BB + +#define GLEW_SGI_color_matrix GLEW_GET_VAR(__GLEW_SGI_color_matrix) + +#endif /* GL_SGI_color_matrix */ + +/* --------------------------- GL_SGI_color_table -------------------------- */ + +#ifndef GL_SGI_color_table +#define GL_SGI_color_table 1 + +#define GL_COLOR_TABLE_SGI 0x80D0 +#define GL_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D1 +#define GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D2 +#define GL_PROXY_COLOR_TABLE_SGI 0x80D3 +#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D4 +#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D5 +#define GL_COLOR_TABLE_SCALE_SGI 0x80D6 +#define GL_COLOR_TABLE_BIAS_SGI 0x80D7 +#define GL_COLOR_TABLE_FORMAT_SGI 0x80D8 +#define GL_COLOR_TABLE_WIDTH_SGI 0x80D9 +#define GL_COLOR_TABLE_RED_SIZE_SGI 0x80DA +#define GL_COLOR_TABLE_GREEN_SIZE_SGI 0x80DB +#define GL_COLOR_TABLE_BLUE_SIZE_SGI 0x80DC +#define GL_COLOR_TABLE_ALPHA_SIZE_SGI 0x80DD +#define GL_COLOR_TABLE_LUMINANCE_SIZE_SGI 0x80DE +#define GL_COLOR_TABLE_INTENSITY_SIZE_SGI 0x80DF + +typedef void (GLAPIENTRY * PFNGLCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void* table); +typedef void (GLAPIENTRY * PFNGLCOPYCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLESGIPROC) (GLenum target, GLenum format, GLenum type, void* table); + +#define glColorTableParameterfvSGI GLEW_GET_FUN(__glewColorTableParameterfvSGI) +#define glColorTableParameterivSGI GLEW_GET_FUN(__glewColorTableParameterivSGI) +#define glColorTableSGI GLEW_GET_FUN(__glewColorTableSGI) +#define glCopyColorTableSGI GLEW_GET_FUN(__glewCopyColorTableSGI) +#define glGetColorTableParameterfvSGI GLEW_GET_FUN(__glewGetColorTableParameterfvSGI) +#define glGetColorTableParameterivSGI GLEW_GET_FUN(__glewGetColorTableParameterivSGI) +#define glGetColorTableSGI GLEW_GET_FUN(__glewGetColorTableSGI) + +#define GLEW_SGI_color_table GLEW_GET_VAR(__GLEW_SGI_color_table) + +#endif /* GL_SGI_color_table */ + +/* ----------------------- GL_SGI_texture_color_table ---------------------- */ + +#ifndef GL_SGI_texture_color_table +#define GL_SGI_texture_color_table 1 + +#define GL_TEXTURE_COLOR_TABLE_SGI 0x80BC +#define GL_PROXY_TEXTURE_COLOR_TABLE_SGI 0x80BD + +#define GLEW_SGI_texture_color_table GLEW_GET_VAR(__GLEW_SGI_texture_color_table) + +#endif /* GL_SGI_texture_color_table */ + +/* ------------------------- GL_SUNX_constant_data ------------------------- */ + +#ifndef GL_SUNX_constant_data +#define GL_SUNX_constant_data 1 + +#define GL_UNPACK_CONSTANT_DATA_SUNX 0x81D5 +#define GL_TEXTURE_CONSTANT_DATA_SUNX 0x81D6 + +typedef void (GLAPIENTRY * PFNGLFINISHTEXTURESUNXPROC) (void); + +#define glFinishTextureSUNX GLEW_GET_FUN(__glewFinishTextureSUNX) + +#define GLEW_SUNX_constant_data GLEW_GET_VAR(__GLEW_SUNX_constant_data) + +#endif /* GL_SUNX_constant_data */ + +/* -------------------- GL_SUN_convolution_border_modes -------------------- */ + +#ifndef GL_SUN_convolution_border_modes +#define GL_SUN_convolution_border_modes 1 + +#define GL_WRAP_BORDER_SUN 0x81D4 + +#define GLEW_SUN_convolution_border_modes GLEW_GET_VAR(__GLEW_SUN_convolution_border_modes) + +#endif /* GL_SUN_convolution_border_modes */ + +/* -------------------------- GL_SUN_global_alpha -------------------------- */ + +#ifndef GL_SUN_global_alpha +#define GL_SUN_global_alpha 1 + +#define GL_GLOBAL_ALPHA_SUN 0x81D9 +#define GL_GLOBAL_ALPHA_FACTOR_SUN 0x81DA + +typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORBSUNPROC) (GLbyte factor); +typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORDSUNPROC) (GLdouble factor); +typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORFSUNPROC) (GLfloat factor); +typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORISUNPROC) (GLint factor); +typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORSSUNPROC) (GLshort factor); +typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORUBSUNPROC) (GLubyte factor); +typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORUISUNPROC) (GLuint factor); +typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORUSSUNPROC) (GLushort factor); + +#define glGlobalAlphaFactorbSUN GLEW_GET_FUN(__glewGlobalAlphaFactorbSUN) +#define glGlobalAlphaFactordSUN GLEW_GET_FUN(__glewGlobalAlphaFactordSUN) +#define glGlobalAlphaFactorfSUN GLEW_GET_FUN(__glewGlobalAlphaFactorfSUN) +#define glGlobalAlphaFactoriSUN GLEW_GET_FUN(__glewGlobalAlphaFactoriSUN) +#define glGlobalAlphaFactorsSUN GLEW_GET_FUN(__glewGlobalAlphaFactorsSUN) +#define glGlobalAlphaFactorubSUN GLEW_GET_FUN(__glewGlobalAlphaFactorubSUN) +#define glGlobalAlphaFactoruiSUN GLEW_GET_FUN(__glewGlobalAlphaFactoruiSUN) +#define glGlobalAlphaFactorusSUN GLEW_GET_FUN(__glewGlobalAlphaFactorusSUN) + +#define GLEW_SUN_global_alpha GLEW_GET_VAR(__GLEW_SUN_global_alpha) + +#endif /* GL_SUN_global_alpha */ + +/* --------------------------- GL_SUN_mesh_array --------------------------- */ + +#ifndef GL_SUN_mesh_array +#define GL_SUN_mesh_array 1 + +#define GL_QUAD_MESH_SUN 0x8614 +#define GL_TRIANGLE_MESH_SUN 0x8615 + +#define GLEW_SUN_mesh_array GLEW_GET_VAR(__GLEW_SUN_mesh_array) + +#endif /* GL_SUN_mesh_array */ + +/* ------------------------ GL_SUN_read_video_pixels ----------------------- */ + +#ifndef GL_SUN_read_video_pixels +#define GL_SUN_read_video_pixels 1 + +typedef void (GLAPIENTRY * PFNGLREADVIDEOPIXELSSUNPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels); + +#define glReadVideoPixelsSUN GLEW_GET_FUN(__glewReadVideoPixelsSUN) + +#define GLEW_SUN_read_video_pixels GLEW_GET_VAR(__GLEW_SUN_read_video_pixels) + +#endif /* GL_SUN_read_video_pixels */ + +/* --------------------------- GL_SUN_slice_accum -------------------------- */ + +#ifndef GL_SUN_slice_accum +#define GL_SUN_slice_accum 1 + +#define GL_SLICE_ACCUM_SUN 0x85CC + +#define GLEW_SUN_slice_accum GLEW_GET_VAR(__GLEW_SUN_slice_accum) + +#endif /* GL_SUN_slice_accum */ + +/* -------------------------- GL_SUN_triangle_list ------------------------- */ + +#ifndef GL_SUN_triangle_list +#define GL_SUN_triangle_list 1 + +#define GL_RESTART_SUN 0x01 +#define GL_REPLACE_MIDDLE_SUN 0x02 +#define GL_REPLACE_OLDEST_SUN 0x03 +#define GL_TRIANGLE_LIST_SUN 0x81D7 +#define GL_REPLACEMENT_CODE_SUN 0x81D8 +#define GL_REPLACEMENT_CODE_ARRAY_SUN 0x85C0 +#define GL_REPLACEMENT_CODE_ARRAY_TYPE_SUN 0x85C1 +#define GL_REPLACEMENT_CODE_ARRAY_STRIDE_SUN 0x85C2 +#define GL_REPLACEMENT_CODE_ARRAY_POINTER_SUN 0x85C3 +#define GL_R1UI_V3F_SUN 0x85C4 +#define GL_R1UI_C4UB_V3F_SUN 0x85C5 +#define GL_R1UI_C3F_V3F_SUN 0x85C6 +#define GL_R1UI_N3F_V3F_SUN 0x85C7 +#define GL_R1UI_C4F_N3F_V3F_SUN 0x85C8 +#define GL_R1UI_T2F_V3F_SUN 0x85C9 +#define GL_R1UI_T2F_N3F_V3F_SUN 0x85CA +#define GL_R1UI_T2F_C4F_N3F_V3F_SUN 0x85CB + +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEPOINTERSUNPROC) (GLenum type, GLsizei stride, const void* pointer); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUBSUNPROC) (GLubyte code); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUBVSUNPROC) (const GLubyte* code); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUISUNPROC) (GLuint code); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUIVSUNPROC) (const GLuint* code); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUSSUNPROC) (GLushort code); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUSVSUNPROC) (const GLushort* code); + +#define glReplacementCodePointerSUN GLEW_GET_FUN(__glewReplacementCodePointerSUN) +#define glReplacementCodeubSUN GLEW_GET_FUN(__glewReplacementCodeubSUN) +#define glReplacementCodeubvSUN GLEW_GET_FUN(__glewReplacementCodeubvSUN) +#define glReplacementCodeuiSUN GLEW_GET_FUN(__glewReplacementCodeuiSUN) +#define glReplacementCodeuivSUN GLEW_GET_FUN(__glewReplacementCodeuivSUN) +#define glReplacementCodeusSUN GLEW_GET_FUN(__glewReplacementCodeusSUN) +#define glReplacementCodeusvSUN GLEW_GET_FUN(__glewReplacementCodeusvSUN) + +#define GLEW_SUN_triangle_list GLEW_GET_VAR(__GLEW_SUN_triangle_list) + +#endif /* GL_SUN_triangle_list */ + +/* ----------------------------- GL_SUN_vertex ----------------------------- */ + +#ifndef GL_SUN_vertex +#define GL_SUN_vertex 1 + +typedef void (GLAPIENTRY * PFNGLCOLOR3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLCOLOR3FVERTEX3FVSUNPROC) (const GLfloat* c, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat* c, const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLCOLOR4UBVERTEX2FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLCOLOR4UBVERTEX2FVSUNPROC) (const GLubyte* c, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLCOLOR4UBVERTEX3FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLCOLOR4UBVERTEX3FVSUNPROC) (const GLubyte* c, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLNORMAL3FVERTEX3FSUNPROC) (GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLNORMAL3FVERTEX3FVSUNPROC) (const GLfloat* n, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *c, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC) (GLuint rc, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC) (const GLuint* rc, const GLubyte *c, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *tc, const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *tc, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC) (GLuint rc, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC) (const GLfloat* tc, const GLfloat *c, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat* tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC) (const GLfloat* tc, const GLubyte *c, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat* tc, const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FVERTEX3FVSUNPROC) (const GLfloat* tc, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC) (const GLfloat* tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD4FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLTEXCOORD4FVERTEX4FVSUNPROC) (const GLfloat* tc, const GLfloat *v); + +#define glColor3fVertex3fSUN GLEW_GET_FUN(__glewColor3fVertex3fSUN) +#define glColor3fVertex3fvSUN GLEW_GET_FUN(__glewColor3fVertex3fvSUN) +#define glColor4fNormal3fVertex3fSUN GLEW_GET_FUN(__glewColor4fNormal3fVertex3fSUN) +#define glColor4fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewColor4fNormal3fVertex3fvSUN) +#define glColor4ubVertex2fSUN GLEW_GET_FUN(__glewColor4ubVertex2fSUN) +#define glColor4ubVertex2fvSUN GLEW_GET_FUN(__glewColor4ubVertex2fvSUN) +#define glColor4ubVertex3fSUN GLEW_GET_FUN(__glewColor4ubVertex3fSUN) +#define glColor4ubVertex3fvSUN GLEW_GET_FUN(__glewColor4ubVertex3fvSUN) +#define glNormal3fVertex3fSUN GLEW_GET_FUN(__glewNormal3fVertex3fSUN) +#define glNormal3fVertex3fvSUN GLEW_GET_FUN(__glewNormal3fVertex3fvSUN) +#define glReplacementCodeuiColor3fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiColor3fVertex3fSUN) +#define glReplacementCodeuiColor3fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiColor3fVertex3fvSUN) +#define glReplacementCodeuiColor4fNormal3fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiColor4fNormal3fVertex3fSUN) +#define glReplacementCodeuiColor4fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiColor4fNormal3fVertex3fvSUN) +#define glReplacementCodeuiColor4ubVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiColor4ubVertex3fSUN) +#define glReplacementCodeuiColor4ubVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiColor4ubVertex3fvSUN) +#define glReplacementCodeuiNormal3fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiNormal3fVertex3fSUN) +#define glReplacementCodeuiNormal3fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiNormal3fVertex3fvSUN) +#define glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN) +#define glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN) +#define glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fNormal3fVertex3fSUN) +#define glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN) +#define glReplacementCodeuiTexCoord2fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fVertex3fSUN) +#define glReplacementCodeuiTexCoord2fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fVertex3fvSUN) +#define glReplacementCodeuiVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiVertex3fSUN) +#define glReplacementCodeuiVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiVertex3fvSUN) +#define glTexCoord2fColor3fVertex3fSUN GLEW_GET_FUN(__glewTexCoord2fColor3fVertex3fSUN) +#define glTexCoord2fColor3fVertex3fvSUN GLEW_GET_FUN(__glewTexCoord2fColor3fVertex3fvSUN) +#define glTexCoord2fColor4fNormal3fVertex3fSUN GLEW_GET_FUN(__glewTexCoord2fColor4fNormal3fVertex3fSUN) +#define glTexCoord2fColor4fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewTexCoord2fColor4fNormal3fVertex3fvSUN) +#define glTexCoord2fColor4ubVertex3fSUN GLEW_GET_FUN(__glewTexCoord2fColor4ubVertex3fSUN) +#define glTexCoord2fColor4ubVertex3fvSUN GLEW_GET_FUN(__glewTexCoord2fColor4ubVertex3fvSUN) +#define glTexCoord2fNormal3fVertex3fSUN GLEW_GET_FUN(__glewTexCoord2fNormal3fVertex3fSUN) +#define glTexCoord2fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewTexCoord2fNormal3fVertex3fvSUN) +#define glTexCoord2fVertex3fSUN GLEW_GET_FUN(__glewTexCoord2fVertex3fSUN) +#define glTexCoord2fVertex3fvSUN GLEW_GET_FUN(__glewTexCoord2fVertex3fvSUN) +#define glTexCoord4fColor4fNormal3fVertex4fSUN GLEW_GET_FUN(__glewTexCoord4fColor4fNormal3fVertex4fSUN) +#define glTexCoord4fColor4fNormal3fVertex4fvSUN GLEW_GET_FUN(__glewTexCoord4fColor4fNormal3fVertex4fvSUN) +#define glTexCoord4fVertex4fSUN GLEW_GET_FUN(__glewTexCoord4fVertex4fSUN) +#define glTexCoord4fVertex4fvSUN GLEW_GET_FUN(__glewTexCoord4fVertex4fvSUN) + +#define GLEW_SUN_vertex GLEW_GET_VAR(__GLEW_SUN_vertex) + +#endif /* GL_SUN_vertex */ + +/* -------------------------- GL_WIN_phong_shading ------------------------- */ + +#ifndef GL_WIN_phong_shading +#define GL_WIN_phong_shading 1 + +#define GL_PHONG_WIN 0x80EA +#define GL_PHONG_HINT_WIN 0x80EB + +#define GLEW_WIN_phong_shading GLEW_GET_VAR(__GLEW_WIN_phong_shading) + +#endif /* GL_WIN_phong_shading */ + +/* -------------------------- GL_WIN_specular_fog -------------------------- */ + +#ifndef GL_WIN_specular_fog +#define GL_WIN_specular_fog 1 + +#define GL_FOG_SPECULAR_TEXTURE_WIN 0x80EC + +#define GLEW_WIN_specular_fog GLEW_GET_VAR(__GLEW_WIN_specular_fog) + +#endif /* GL_WIN_specular_fog */ + +/* ---------------------------- GL_WIN_swap_hint --------------------------- */ + +#ifndef GL_WIN_swap_hint +#define GL_WIN_swap_hint 1 + +typedef void (GLAPIENTRY * PFNGLADDSWAPHINTRECTWINPROC) (GLint x, GLint y, GLsizei width, GLsizei height); + +#define glAddSwapHintRectWIN GLEW_GET_FUN(__glewAddSwapHintRectWIN) + +#define GLEW_WIN_swap_hint GLEW_GET_VAR(__GLEW_WIN_swap_hint) + +#endif /* GL_WIN_swap_hint */ + +/* ------------------------------------------------------------------------- */ + +#if defined(GLEW_MX) && defined(_WIN32) +#define GLEW_FUN_EXPORT +#else +#define GLEW_FUN_EXPORT GLEWAPI +#endif /* GLEW_MX */ + +#if defined(GLEW_MX) +#define GLEW_VAR_EXPORT +#else +#define GLEW_VAR_EXPORT GLEWAPI +#endif /* GLEW_MX */ + +#if defined(GLEW_MX) && defined(_WIN32) +struct GLEWContextStruct +{ +#endif /* GLEW_MX */ + +GLEW_FUN_EXPORT PFNGLCOPYTEXSUBIMAGE3DPROC __glewCopyTexSubImage3D; +GLEW_FUN_EXPORT PFNGLDRAWRANGEELEMENTSPROC __glewDrawRangeElements; +GLEW_FUN_EXPORT PFNGLTEXIMAGE3DPROC __glewTexImage3D; +GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE3DPROC __glewTexSubImage3D; + +GLEW_FUN_EXPORT PFNGLACTIVETEXTUREPROC __glewActiveTexture; +GLEW_FUN_EXPORT PFNGLCLIENTACTIVETEXTUREPROC __glewClientActiveTexture; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE1DPROC __glewCompressedTexImage1D; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE2DPROC __glewCompressedTexImage2D; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE3DPROC __glewCompressedTexImage3D; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC __glewCompressedTexSubImage1D; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC __glewCompressedTexSubImage2D; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC __glewCompressedTexSubImage3D; +GLEW_FUN_EXPORT PFNGLGETCOMPRESSEDTEXIMAGEPROC __glewGetCompressedTexImage; +GLEW_FUN_EXPORT PFNGLLOADTRANSPOSEMATRIXDPROC __glewLoadTransposeMatrixd; +GLEW_FUN_EXPORT PFNGLLOADTRANSPOSEMATRIXFPROC __glewLoadTransposeMatrixf; +GLEW_FUN_EXPORT PFNGLMULTTRANSPOSEMATRIXDPROC __glewMultTransposeMatrixd; +GLEW_FUN_EXPORT PFNGLMULTTRANSPOSEMATRIXFPROC __glewMultTransposeMatrixf; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1DPROC __glewMultiTexCoord1d; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1DVPROC __glewMultiTexCoord1dv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1FPROC __glewMultiTexCoord1f; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1FVPROC __glewMultiTexCoord1fv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1IPROC __glewMultiTexCoord1i; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1IVPROC __glewMultiTexCoord1iv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1SPROC __glewMultiTexCoord1s; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1SVPROC __glewMultiTexCoord1sv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2DPROC __glewMultiTexCoord2d; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2DVPROC __glewMultiTexCoord2dv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2FPROC __glewMultiTexCoord2f; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2FVPROC __glewMultiTexCoord2fv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2IPROC __glewMultiTexCoord2i; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2IVPROC __glewMultiTexCoord2iv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2SPROC __glewMultiTexCoord2s; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2SVPROC __glewMultiTexCoord2sv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3DPROC __glewMultiTexCoord3d; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3DVPROC __glewMultiTexCoord3dv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3FPROC __glewMultiTexCoord3f; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3FVPROC __glewMultiTexCoord3fv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3IPROC __glewMultiTexCoord3i; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3IVPROC __glewMultiTexCoord3iv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3SPROC __glewMultiTexCoord3s; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3SVPROC __glewMultiTexCoord3sv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4DPROC __glewMultiTexCoord4d; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4DVPROC __glewMultiTexCoord4dv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4FPROC __glewMultiTexCoord4f; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4FVPROC __glewMultiTexCoord4fv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4IPROC __glewMultiTexCoord4i; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4IVPROC __glewMultiTexCoord4iv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4SPROC __glewMultiTexCoord4s; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4SVPROC __glewMultiTexCoord4sv; +GLEW_FUN_EXPORT PFNGLSAMPLECOVERAGEPROC __glewSampleCoverage; + +GLEW_FUN_EXPORT PFNGLBLENDCOLORPROC __glewBlendColor; +GLEW_FUN_EXPORT PFNGLBLENDEQUATIONPROC __glewBlendEquation; +GLEW_FUN_EXPORT PFNGLBLENDFUNCSEPARATEPROC __glewBlendFuncSeparate; +GLEW_FUN_EXPORT PFNGLFOGCOORDPOINTERPROC __glewFogCoordPointer; +GLEW_FUN_EXPORT PFNGLFOGCOORDDPROC __glewFogCoordd; +GLEW_FUN_EXPORT PFNGLFOGCOORDDVPROC __glewFogCoorddv; +GLEW_FUN_EXPORT PFNGLFOGCOORDFPROC __glewFogCoordf; +GLEW_FUN_EXPORT PFNGLFOGCOORDFVPROC __glewFogCoordfv; +GLEW_FUN_EXPORT PFNGLMULTIDRAWARRAYSPROC __glewMultiDrawArrays; +GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSPROC __glewMultiDrawElements; +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFPROC __glewPointParameterf; +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFVPROC __glewPointParameterfv; +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERIPROC __glewPointParameteri; +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERIVPROC __glewPointParameteriv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3BPROC __glewSecondaryColor3b; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3BVPROC __glewSecondaryColor3bv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3DPROC __glewSecondaryColor3d; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3DVPROC __glewSecondaryColor3dv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3FPROC __glewSecondaryColor3f; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3FVPROC __glewSecondaryColor3fv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3IPROC __glewSecondaryColor3i; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3IVPROC __glewSecondaryColor3iv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3SPROC __glewSecondaryColor3s; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3SVPROC __glewSecondaryColor3sv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UBPROC __glewSecondaryColor3ub; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UBVPROC __glewSecondaryColor3ubv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UIPROC __glewSecondaryColor3ui; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UIVPROC __glewSecondaryColor3uiv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3USPROC __glewSecondaryColor3us; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3USVPROC __glewSecondaryColor3usv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLORPOINTERPROC __glewSecondaryColorPointer; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2DPROC __glewWindowPos2d; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2DVPROC __glewWindowPos2dv; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2FPROC __glewWindowPos2f; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2FVPROC __glewWindowPos2fv; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2IPROC __glewWindowPos2i; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2IVPROC __glewWindowPos2iv; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2SPROC __glewWindowPos2s; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2SVPROC __glewWindowPos2sv; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3DPROC __glewWindowPos3d; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3DVPROC __glewWindowPos3dv; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3FPROC __glewWindowPos3f; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3FVPROC __glewWindowPos3fv; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3IPROC __glewWindowPos3i; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3IVPROC __glewWindowPos3iv; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3SPROC __glewWindowPos3s; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3SVPROC __glewWindowPos3sv; + +GLEW_FUN_EXPORT PFNGLBEGINQUERYPROC __glewBeginQuery; +GLEW_FUN_EXPORT PFNGLBINDBUFFERPROC __glewBindBuffer; +GLEW_FUN_EXPORT PFNGLBUFFERDATAPROC __glewBufferData; +GLEW_FUN_EXPORT PFNGLBUFFERSUBDATAPROC __glewBufferSubData; +GLEW_FUN_EXPORT PFNGLDELETEBUFFERSPROC __glewDeleteBuffers; +GLEW_FUN_EXPORT PFNGLDELETEQUERIESPROC __glewDeleteQueries; +GLEW_FUN_EXPORT PFNGLENDQUERYPROC __glewEndQuery; +GLEW_FUN_EXPORT PFNGLGENBUFFERSPROC __glewGenBuffers; +GLEW_FUN_EXPORT PFNGLGENQUERIESPROC __glewGenQueries; +GLEW_FUN_EXPORT PFNGLGETBUFFERPARAMETERIVPROC __glewGetBufferParameteriv; +GLEW_FUN_EXPORT PFNGLGETBUFFERPOINTERVPROC __glewGetBufferPointerv; +GLEW_FUN_EXPORT PFNGLGETBUFFERSUBDATAPROC __glewGetBufferSubData; +GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTIVPROC __glewGetQueryObjectiv; +GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTUIVPROC __glewGetQueryObjectuiv; +GLEW_FUN_EXPORT PFNGLGETQUERYIVPROC __glewGetQueryiv; +GLEW_FUN_EXPORT PFNGLISBUFFERPROC __glewIsBuffer; +GLEW_FUN_EXPORT PFNGLISQUERYPROC __glewIsQuery; +GLEW_FUN_EXPORT PFNGLMAPBUFFERPROC __glewMapBuffer; +GLEW_FUN_EXPORT PFNGLUNMAPBUFFERPROC __glewUnmapBuffer; + +GLEW_FUN_EXPORT PFNGLATTACHSHADERPROC __glewAttachShader; +GLEW_FUN_EXPORT PFNGLBINDATTRIBLOCATIONPROC __glewBindAttribLocation; +GLEW_FUN_EXPORT PFNGLBLENDEQUATIONSEPARATEPROC __glewBlendEquationSeparate; +GLEW_FUN_EXPORT PFNGLCOMPILESHADERPROC __glewCompileShader; +GLEW_FUN_EXPORT PFNGLCREATEPROGRAMPROC __glewCreateProgram; +GLEW_FUN_EXPORT PFNGLCREATESHADERPROC __glewCreateShader; +GLEW_FUN_EXPORT PFNGLDELETEPROGRAMPROC __glewDeleteProgram; +GLEW_FUN_EXPORT PFNGLDELETESHADERPROC __glewDeleteShader; +GLEW_FUN_EXPORT PFNGLDETACHSHADERPROC __glewDetachShader; +GLEW_FUN_EXPORT PFNGLDISABLEVERTEXATTRIBARRAYPROC __glewDisableVertexAttribArray; +GLEW_FUN_EXPORT PFNGLDRAWBUFFERSPROC __glewDrawBuffers; +GLEW_FUN_EXPORT PFNGLENABLEVERTEXATTRIBARRAYPROC __glewEnableVertexAttribArray; +GLEW_FUN_EXPORT PFNGLGETACTIVEATTRIBPROC __glewGetActiveAttrib; +GLEW_FUN_EXPORT PFNGLGETACTIVEUNIFORMPROC __glewGetActiveUniform; +GLEW_FUN_EXPORT PFNGLGETATTACHEDSHADERSPROC __glewGetAttachedShaders; +GLEW_FUN_EXPORT PFNGLGETATTRIBLOCATIONPROC __glewGetAttribLocation; +GLEW_FUN_EXPORT PFNGLGETPROGRAMINFOLOGPROC __glewGetProgramInfoLog; +GLEW_FUN_EXPORT PFNGLGETPROGRAMIVPROC __glewGetProgramiv; +GLEW_FUN_EXPORT PFNGLGETSHADERINFOLOGPROC __glewGetShaderInfoLog; +GLEW_FUN_EXPORT PFNGLGETSHADERSOURCEPROC __glewGetShaderSource; +GLEW_FUN_EXPORT PFNGLGETSHADERIVPROC __glewGetShaderiv; +GLEW_FUN_EXPORT PFNGLGETUNIFORMLOCATIONPROC __glewGetUniformLocation; +GLEW_FUN_EXPORT PFNGLGETUNIFORMFVPROC __glewGetUniformfv; +GLEW_FUN_EXPORT PFNGLGETUNIFORMIVPROC __glewGetUniformiv; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBPOINTERVPROC __glewGetVertexAttribPointerv; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBDVPROC __glewGetVertexAttribdv; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBFVPROC __glewGetVertexAttribfv; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIVPROC __glewGetVertexAttribiv; +GLEW_FUN_EXPORT PFNGLISPROGRAMPROC __glewIsProgram; +GLEW_FUN_EXPORT PFNGLISSHADERPROC __glewIsShader; +GLEW_FUN_EXPORT PFNGLLINKPROGRAMPROC __glewLinkProgram; +GLEW_FUN_EXPORT PFNGLSHADERSOURCEPROC __glewShaderSource; +GLEW_FUN_EXPORT PFNGLSTENCILFUNCSEPARATEPROC __glewStencilFuncSeparate; +GLEW_FUN_EXPORT PFNGLSTENCILMASKSEPARATEPROC __glewStencilMaskSeparate; +GLEW_FUN_EXPORT PFNGLSTENCILOPSEPARATEPROC __glewStencilOpSeparate; +GLEW_FUN_EXPORT PFNGLUNIFORM1FPROC __glewUniform1f; +GLEW_FUN_EXPORT PFNGLUNIFORM1FVPROC __glewUniform1fv; +GLEW_FUN_EXPORT PFNGLUNIFORM1IPROC __glewUniform1i; +GLEW_FUN_EXPORT PFNGLUNIFORM1IVPROC __glewUniform1iv; +GLEW_FUN_EXPORT PFNGLUNIFORM2FPROC __glewUniform2f; +GLEW_FUN_EXPORT PFNGLUNIFORM2FVPROC __glewUniform2fv; +GLEW_FUN_EXPORT PFNGLUNIFORM2IPROC __glewUniform2i; +GLEW_FUN_EXPORT PFNGLUNIFORM2IVPROC __glewUniform2iv; +GLEW_FUN_EXPORT PFNGLUNIFORM3FPROC __glewUniform3f; +GLEW_FUN_EXPORT PFNGLUNIFORM3FVPROC __glewUniform3fv; +GLEW_FUN_EXPORT PFNGLUNIFORM3IPROC __glewUniform3i; +GLEW_FUN_EXPORT PFNGLUNIFORM3IVPROC __glewUniform3iv; +GLEW_FUN_EXPORT PFNGLUNIFORM4FPROC __glewUniform4f; +GLEW_FUN_EXPORT PFNGLUNIFORM4FVPROC __glewUniform4fv; +GLEW_FUN_EXPORT PFNGLUNIFORM4IPROC __glewUniform4i; +GLEW_FUN_EXPORT PFNGLUNIFORM4IVPROC __glewUniform4iv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2FVPROC __glewUniformMatrix2fv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3FVPROC __glewUniformMatrix3fv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4FVPROC __glewUniformMatrix4fv; +GLEW_FUN_EXPORT PFNGLUSEPROGRAMPROC __glewUseProgram; +GLEW_FUN_EXPORT PFNGLVALIDATEPROGRAMPROC __glewValidateProgram; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DPROC __glewVertexAttrib1d; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DVPROC __glewVertexAttrib1dv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FPROC __glewVertexAttrib1f; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FVPROC __glewVertexAttrib1fv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SPROC __glewVertexAttrib1s; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SVPROC __glewVertexAttrib1sv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DPROC __glewVertexAttrib2d; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DVPROC __glewVertexAttrib2dv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FPROC __glewVertexAttrib2f; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FVPROC __glewVertexAttrib2fv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SPROC __glewVertexAttrib2s; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SVPROC __glewVertexAttrib2sv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DPROC __glewVertexAttrib3d; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DVPROC __glewVertexAttrib3dv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FPROC __glewVertexAttrib3f; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FVPROC __glewVertexAttrib3fv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SPROC __glewVertexAttrib3s; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SVPROC __glewVertexAttrib3sv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NBVPROC __glewVertexAttrib4Nbv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NIVPROC __glewVertexAttrib4Niv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NSVPROC __glewVertexAttrib4Nsv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUBPROC __glewVertexAttrib4Nub; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUBVPROC __glewVertexAttrib4Nubv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUIVPROC __glewVertexAttrib4Nuiv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUSVPROC __glewVertexAttrib4Nusv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4BVPROC __glewVertexAttrib4bv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DPROC __glewVertexAttrib4d; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DVPROC __glewVertexAttrib4dv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FPROC __glewVertexAttrib4f; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FVPROC __glewVertexAttrib4fv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4IVPROC __glewVertexAttrib4iv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SPROC __glewVertexAttrib4s; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SVPROC __glewVertexAttrib4sv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UBVPROC __glewVertexAttrib4ubv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UIVPROC __glewVertexAttrib4uiv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4USVPROC __glewVertexAttrib4usv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBPOINTERPROC __glewVertexAttribPointer; + +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2X3FVPROC __glewUniformMatrix2x3fv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2X4FVPROC __glewUniformMatrix2x4fv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3X2FVPROC __glewUniformMatrix3x2fv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3X4FVPROC __glewUniformMatrix3x4fv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4X2FVPROC __glewUniformMatrix4x2fv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4X3FVPROC __glewUniformMatrix4x3fv; + +GLEW_FUN_EXPORT PFNGLBEGINCONDITIONALRENDERPROC __glewBeginConditionalRender; +GLEW_FUN_EXPORT PFNGLBEGINTRANSFORMFEEDBACKPROC __glewBeginTransformFeedback; +GLEW_FUN_EXPORT PFNGLBINDBUFFERBASEPROC __glewBindBufferBase; +GLEW_FUN_EXPORT PFNGLBINDBUFFERRANGEPROC __glewBindBufferRange; +GLEW_FUN_EXPORT PFNGLBINDFRAGDATALOCATIONPROC __glewBindFragDataLocation; +GLEW_FUN_EXPORT PFNGLCLAMPCOLORPROC __glewClampColor; +GLEW_FUN_EXPORT PFNGLCLEARBUFFERFIPROC __glewClearBufferfi; +GLEW_FUN_EXPORT PFNGLCLEARBUFFERFVPROC __glewClearBufferfv; +GLEW_FUN_EXPORT PFNGLCLEARBUFFERIVPROC __glewClearBufferiv; +GLEW_FUN_EXPORT PFNGLCLEARBUFFERUIVPROC __glewClearBufferuiv; +GLEW_FUN_EXPORT PFNGLCOLORMASKIPROC __glewColorMaski; +GLEW_FUN_EXPORT PFNGLDISABLEIPROC __glewDisablei; +GLEW_FUN_EXPORT PFNGLENABLEIPROC __glewEnablei; +GLEW_FUN_EXPORT PFNGLENDCONDITIONALRENDERPROC __glewEndConditionalRender; +GLEW_FUN_EXPORT PFNGLENDTRANSFORMFEEDBACKPROC __glewEndTransformFeedback; +GLEW_FUN_EXPORT PFNGLGETBOOLEANI_VPROC __glewGetBooleani_v; +GLEW_FUN_EXPORT PFNGLGETFRAGDATALOCATIONPROC __glewGetFragDataLocation; +GLEW_FUN_EXPORT PFNGLGETINTEGERI_VPROC __glewGetIntegeri_v; +GLEW_FUN_EXPORT PFNGLGETSTRINGIPROC __glewGetStringi; +GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERIIVPROC __glewGetTexParameterIiv; +GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERIUIVPROC __glewGetTexParameterIuiv; +GLEW_FUN_EXPORT PFNGLGETTRANSFORMFEEDBACKVARYINGPROC __glewGetTransformFeedbackVarying; +GLEW_FUN_EXPORT PFNGLGETUNIFORMUIVPROC __glewGetUniformuiv; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIIVPROC __glewGetVertexAttribIiv; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIUIVPROC __glewGetVertexAttribIuiv; +GLEW_FUN_EXPORT PFNGLISENABLEDIPROC __glewIsEnabledi; +GLEW_FUN_EXPORT PFNGLTEXPARAMETERIIVPROC __glewTexParameterIiv; +GLEW_FUN_EXPORT PFNGLTEXPARAMETERIUIVPROC __glewTexParameterIuiv; +GLEW_FUN_EXPORT PFNGLTRANSFORMFEEDBACKVARYINGSPROC __glewTransformFeedbackVaryings; +GLEW_FUN_EXPORT PFNGLUNIFORM1UIPROC __glewUniform1ui; +GLEW_FUN_EXPORT PFNGLUNIFORM1UIVPROC __glewUniform1uiv; +GLEW_FUN_EXPORT PFNGLUNIFORM2UIPROC __glewUniform2ui; +GLEW_FUN_EXPORT PFNGLUNIFORM2UIVPROC __glewUniform2uiv; +GLEW_FUN_EXPORT PFNGLUNIFORM3UIPROC __glewUniform3ui; +GLEW_FUN_EXPORT PFNGLUNIFORM3UIVPROC __glewUniform3uiv; +GLEW_FUN_EXPORT PFNGLUNIFORM4UIPROC __glewUniform4ui; +GLEW_FUN_EXPORT PFNGLUNIFORM4UIVPROC __glewUniform4uiv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1IPROC __glewVertexAttribI1i; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1IVPROC __glewVertexAttribI1iv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1UIPROC __glewVertexAttribI1ui; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1UIVPROC __glewVertexAttribI1uiv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2IPROC __glewVertexAttribI2i; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2IVPROC __glewVertexAttribI2iv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2UIPROC __glewVertexAttribI2ui; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2UIVPROC __glewVertexAttribI2uiv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3IPROC __glewVertexAttribI3i; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3IVPROC __glewVertexAttribI3iv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3UIPROC __glewVertexAttribI3ui; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3UIVPROC __glewVertexAttribI3uiv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4BVPROC __glewVertexAttribI4bv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4IPROC __glewVertexAttribI4i; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4IVPROC __glewVertexAttribI4iv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4SVPROC __glewVertexAttribI4sv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4UBVPROC __glewVertexAttribI4ubv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4UIPROC __glewVertexAttribI4ui; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4UIVPROC __glewVertexAttribI4uiv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4USVPROC __glewVertexAttribI4usv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBIPOINTERPROC __glewVertexAttribIPointer; + +GLEW_FUN_EXPORT PFNGLTBUFFERMASK3DFXPROC __glewTbufferMask3DFX; + +GLEW_FUN_EXPORT PFNGLDRAWELEMENTARRAYAPPLEPROC __glewDrawElementArrayAPPLE; +GLEW_FUN_EXPORT PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC __glewDrawRangeElementArrayAPPLE; +GLEW_FUN_EXPORT PFNGLELEMENTPOINTERAPPLEPROC __glewElementPointerAPPLE; +GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC __glewMultiDrawElementArrayAPPLE; +GLEW_FUN_EXPORT PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC __glewMultiDrawRangeElementArrayAPPLE; + +GLEW_FUN_EXPORT PFNGLDELETEFENCESAPPLEPROC __glewDeleteFencesAPPLE; +GLEW_FUN_EXPORT PFNGLFINISHFENCEAPPLEPROC __glewFinishFenceAPPLE; +GLEW_FUN_EXPORT PFNGLFINISHOBJECTAPPLEPROC __glewFinishObjectAPPLE; +GLEW_FUN_EXPORT PFNGLGENFENCESAPPLEPROC __glewGenFencesAPPLE; +GLEW_FUN_EXPORT PFNGLISFENCEAPPLEPROC __glewIsFenceAPPLE; +GLEW_FUN_EXPORT PFNGLSETFENCEAPPLEPROC __glewSetFenceAPPLE; +GLEW_FUN_EXPORT PFNGLTESTFENCEAPPLEPROC __glewTestFenceAPPLE; +GLEW_FUN_EXPORT PFNGLTESTOBJECTAPPLEPROC __glewTestObjectAPPLE; + +GLEW_FUN_EXPORT PFNGLBUFFERPARAMETERIAPPLEPROC __glewBufferParameteriAPPLE; +GLEW_FUN_EXPORT PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC __glewFlushMappedBufferRangeAPPLE; + +GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC __glewGetTexParameterPointervAPPLE; +GLEW_FUN_EXPORT PFNGLTEXTURERANGEAPPLEPROC __glewTextureRangeAPPLE; + +GLEW_FUN_EXPORT PFNGLBINDVERTEXARRAYAPPLEPROC __glewBindVertexArrayAPPLE; +GLEW_FUN_EXPORT PFNGLDELETEVERTEXARRAYSAPPLEPROC __glewDeleteVertexArraysAPPLE; +GLEW_FUN_EXPORT PFNGLGENVERTEXARRAYSAPPLEPROC __glewGenVertexArraysAPPLE; +GLEW_FUN_EXPORT PFNGLISVERTEXARRAYAPPLEPROC __glewIsVertexArrayAPPLE; + +GLEW_FUN_EXPORT PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC __glewFlushVertexArrayRangeAPPLE; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYPARAMETERIAPPLEPROC __glewVertexArrayParameteriAPPLE; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYRANGEAPPLEPROC __glewVertexArrayRangeAPPLE; + +GLEW_FUN_EXPORT PFNGLCLAMPCOLORARBPROC __glewClampColorARB; + +GLEW_FUN_EXPORT PFNGLDRAWBUFFERSARBPROC __glewDrawBuffersARB; + +GLEW_FUN_EXPORT PFNGLDRAWARRAYSINSTANCEDARBPROC __glewDrawArraysInstancedARB; +GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDARBPROC __glewDrawElementsInstancedARB; + +GLEW_FUN_EXPORT PFNGLBINDFRAMEBUFFERPROC __glewBindFramebuffer; +GLEW_FUN_EXPORT PFNGLBINDRENDERBUFFERPROC __glewBindRenderbuffer; +GLEW_FUN_EXPORT PFNGLBLITFRAMEBUFFERPROC __glewBlitFramebuffer; +GLEW_FUN_EXPORT PFNGLCHECKFRAMEBUFFERSTATUSPROC __glewCheckFramebufferStatus; +GLEW_FUN_EXPORT PFNGLDELETEFRAMEBUFFERSPROC __glewDeleteFramebuffers; +GLEW_FUN_EXPORT PFNGLDELETERENDERBUFFERSPROC __glewDeleteRenderbuffers; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERRENDERBUFFERPROC __glewFramebufferRenderbuffer; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURLAYERPROC __glewFramebufferTexturLayer; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE1DPROC __glewFramebufferTexture1D; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE2DPROC __glewFramebufferTexture2D; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE3DPROC __glewFramebufferTexture3D; +GLEW_FUN_EXPORT PFNGLGENFRAMEBUFFERSPROC __glewGenFramebuffers; +GLEW_FUN_EXPORT PFNGLGENRENDERBUFFERSPROC __glewGenRenderbuffers; +GLEW_FUN_EXPORT PFNGLGENERATEMIPMAPPROC __glewGenerateMipmap; +GLEW_FUN_EXPORT PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC __glewGetFramebufferAttachmentParameteriv; +GLEW_FUN_EXPORT PFNGLGETRENDERBUFFERPARAMETERIVPROC __glewGetRenderbufferParameteriv; +GLEW_FUN_EXPORT PFNGLISFRAMEBUFFERPROC __glewIsFramebuffer; +GLEW_FUN_EXPORT PFNGLISRENDERBUFFERPROC __glewIsRenderbuffer; +GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEPROC __glewRenderbufferStorage; +GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC __glewRenderbufferStorageMultisample; + +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTUREARBPROC __glewFramebufferTextureARB; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTUREFACEARBPROC __glewFramebufferTextureFaceARB; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURELAYERARBPROC __glewFramebufferTextureLayerARB; +GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETERIARBPROC __glewProgramParameteriARB; + +GLEW_FUN_EXPORT PFNGLCOLORSUBTABLEPROC __glewColorSubTable; +GLEW_FUN_EXPORT PFNGLCOLORTABLEPROC __glewColorTable; +GLEW_FUN_EXPORT PFNGLCOLORTABLEPARAMETERFVPROC __glewColorTableParameterfv; +GLEW_FUN_EXPORT PFNGLCOLORTABLEPARAMETERIVPROC __glewColorTableParameteriv; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONFILTER1DPROC __glewConvolutionFilter1D; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONFILTER2DPROC __glewConvolutionFilter2D; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERFPROC __glewConvolutionParameterf; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERFVPROC __glewConvolutionParameterfv; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERIPROC __glewConvolutionParameteri; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERIVPROC __glewConvolutionParameteriv; +GLEW_FUN_EXPORT PFNGLCOPYCOLORSUBTABLEPROC __glewCopyColorSubTable; +GLEW_FUN_EXPORT PFNGLCOPYCOLORTABLEPROC __glewCopyColorTable; +GLEW_FUN_EXPORT PFNGLCOPYCONVOLUTIONFILTER1DPROC __glewCopyConvolutionFilter1D; +GLEW_FUN_EXPORT PFNGLCOPYCONVOLUTIONFILTER2DPROC __glewCopyConvolutionFilter2D; +GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPROC __glewGetColorTable; +GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERFVPROC __glewGetColorTableParameterfv; +GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERIVPROC __glewGetColorTableParameteriv; +GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONFILTERPROC __glewGetConvolutionFilter; +GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONPARAMETERFVPROC __glewGetConvolutionParameterfv; +GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONPARAMETERIVPROC __glewGetConvolutionParameteriv; +GLEW_FUN_EXPORT PFNGLGETHISTOGRAMPROC __glewGetHistogram; +GLEW_FUN_EXPORT PFNGLGETHISTOGRAMPARAMETERFVPROC __glewGetHistogramParameterfv; +GLEW_FUN_EXPORT PFNGLGETHISTOGRAMPARAMETERIVPROC __glewGetHistogramParameteriv; +GLEW_FUN_EXPORT PFNGLGETMINMAXPROC __glewGetMinmax; +GLEW_FUN_EXPORT PFNGLGETMINMAXPARAMETERFVPROC __glewGetMinmaxParameterfv; +GLEW_FUN_EXPORT PFNGLGETMINMAXPARAMETERIVPROC __glewGetMinmaxParameteriv; +GLEW_FUN_EXPORT PFNGLGETSEPARABLEFILTERPROC __glewGetSeparableFilter; +GLEW_FUN_EXPORT PFNGLHISTOGRAMPROC __glewHistogram; +GLEW_FUN_EXPORT PFNGLMINMAXPROC __glewMinmax; +GLEW_FUN_EXPORT PFNGLRESETHISTOGRAMPROC __glewResetHistogram; +GLEW_FUN_EXPORT PFNGLRESETMINMAXPROC __glewResetMinmax; +GLEW_FUN_EXPORT PFNGLSEPARABLEFILTER2DPROC __glewSeparableFilter2D; + +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBDIVISORARBPROC __glewVertexAttribDivisorARB; + +GLEW_FUN_EXPORT PFNGLFLUSHMAPPEDBUFFERRANGEPROC __glewFlushMappedBufferRange; +GLEW_FUN_EXPORT PFNGLMAPBUFFERRANGEPROC __glewMapBufferRange; + +GLEW_FUN_EXPORT PFNGLCURRENTPALETTEMATRIXARBPROC __glewCurrentPaletteMatrixARB; +GLEW_FUN_EXPORT PFNGLMATRIXINDEXPOINTERARBPROC __glewMatrixIndexPointerARB; +GLEW_FUN_EXPORT PFNGLMATRIXINDEXUBVARBPROC __glewMatrixIndexubvARB; +GLEW_FUN_EXPORT PFNGLMATRIXINDEXUIVARBPROC __glewMatrixIndexuivARB; +GLEW_FUN_EXPORT PFNGLMATRIXINDEXUSVARBPROC __glewMatrixIndexusvARB; + +GLEW_FUN_EXPORT PFNGLSAMPLECOVERAGEARBPROC __glewSampleCoverageARB; + +GLEW_FUN_EXPORT PFNGLACTIVETEXTUREARBPROC __glewActiveTextureARB; +GLEW_FUN_EXPORT PFNGLCLIENTACTIVETEXTUREARBPROC __glewClientActiveTextureARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1DARBPROC __glewMultiTexCoord1dARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1DVARBPROC __glewMultiTexCoord1dvARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1FARBPROC __glewMultiTexCoord1fARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1FVARBPROC __glewMultiTexCoord1fvARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1IARBPROC __glewMultiTexCoord1iARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1IVARBPROC __glewMultiTexCoord1ivARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1SARBPROC __glewMultiTexCoord1sARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1SVARBPROC __glewMultiTexCoord1svARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2DARBPROC __glewMultiTexCoord2dARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2DVARBPROC __glewMultiTexCoord2dvARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2FARBPROC __glewMultiTexCoord2fARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2FVARBPROC __glewMultiTexCoord2fvARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2IARBPROC __glewMultiTexCoord2iARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2IVARBPROC __glewMultiTexCoord2ivARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2SARBPROC __glewMultiTexCoord2sARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2SVARBPROC __glewMultiTexCoord2svARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3DARBPROC __glewMultiTexCoord3dARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3DVARBPROC __glewMultiTexCoord3dvARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3FARBPROC __glewMultiTexCoord3fARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3FVARBPROC __glewMultiTexCoord3fvARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3IARBPROC __glewMultiTexCoord3iARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3IVARBPROC __glewMultiTexCoord3ivARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3SARBPROC __glewMultiTexCoord3sARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3SVARBPROC __glewMultiTexCoord3svARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4DARBPROC __glewMultiTexCoord4dARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4DVARBPROC __glewMultiTexCoord4dvARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4FARBPROC __glewMultiTexCoord4fARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4FVARBPROC __glewMultiTexCoord4fvARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4IARBPROC __glewMultiTexCoord4iARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4IVARBPROC __glewMultiTexCoord4ivARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4SARBPROC __glewMultiTexCoord4sARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4SVARBPROC __glewMultiTexCoord4svARB; + +GLEW_FUN_EXPORT PFNGLBEGINQUERYARBPROC __glewBeginQueryARB; +GLEW_FUN_EXPORT PFNGLDELETEQUERIESARBPROC __glewDeleteQueriesARB; +GLEW_FUN_EXPORT PFNGLENDQUERYARBPROC __glewEndQueryARB; +GLEW_FUN_EXPORT PFNGLGENQUERIESARBPROC __glewGenQueriesARB; +GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTIVARBPROC __glewGetQueryObjectivARB; +GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTUIVARBPROC __glewGetQueryObjectuivARB; +GLEW_FUN_EXPORT PFNGLGETQUERYIVARBPROC __glewGetQueryivARB; +GLEW_FUN_EXPORT PFNGLISQUERYARBPROC __glewIsQueryARB; + +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFARBPROC __glewPointParameterfARB; +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFVARBPROC __glewPointParameterfvARB; + +GLEW_FUN_EXPORT PFNGLATTACHOBJECTARBPROC __glewAttachObjectARB; +GLEW_FUN_EXPORT PFNGLCOMPILESHADERARBPROC __glewCompileShaderARB; +GLEW_FUN_EXPORT PFNGLCREATEPROGRAMOBJECTARBPROC __glewCreateProgramObjectARB; +GLEW_FUN_EXPORT PFNGLCREATESHADEROBJECTARBPROC __glewCreateShaderObjectARB; +GLEW_FUN_EXPORT PFNGLDELETEOBJECTARBPROC __glewDeleteObjectARB; +GLEW_FUN_EXPORT PFNGLDETACHOBJECTARBPROC __glewDetachObjectARB; +GLEW_FUN_EXPORT PFNGLGETACTIVEUNIFORMARBPROC __glewGetActiveUniformARB; +GLEW_FUN_EXPORT PFNGLGETATTACHEDOBJECTSARBPROC __glewGetAttachedObjectsARB; +GLEW_FUN_EXPORT PFNGLGETHANDLEARBPROC __glewGetHandleARB; +GLEW_FUN_EXPORT PFNGLGETINFOLOGARBPROC __glewGetInfoLogARB; +GLEW_FUN_EXPORT PFNGLGETOBJECTPARAMETERFVARBPROC __glewGetObjectParameterfvARB; +GLEW_FUN_EXPORT PFNGLGETOBJECTPARAMETERIVARBPROC __glewGetObjectParameterivARB; +GLEW_FUN_EXPORT PFNGLGETSHADERSOURCEARBPROC __glewGetShaderSourceARB; +GLEW_FUN_EXPORT PFNGLGETUNIFORMLOCATIONARBPROC __glewGetUniformLocationARB; +GLEW_FUN_EXPORT PFNGLGETUNIFORMFVARBPROC __glewGetUniformfvARB; +GLEW_FUN_EXPORT PFNGLGETUNIFORMIVARBPROC __glewGetUniformivARB; +GLEW_FUN_EXPORT PFNGLLINKPROGRAMARBPROC __glewLinkProgramARB; +GLEW_FUN_EXPORT PFNGLSHADERSOURCEARBPROC __glewShaderSourceARB; +GLEW_FUN_EXPORT PFNGLUNIFORM1FARBPROC __glewUniform1fARB; +GLEW_FUN_EXPORT PFNGLUNIFORM1FVARBPROC __glewUniform1fvARB; +GLEW_FUN_EXPORT PFNGLUNIFORM1IARBPROC __glewUniform1iARB; +GLEW_FUN_EXPORT PFNGLUNIFORM1IVARBPROC __glewUniform1ivARB; +GLEW_FUN_EXPORT PFNGLUNIFORM2FARBPROC __glewUniform2fARB; +GLEW_FUN_EXPORT PFNGLUNIFORM2FVARBPROC __glewUniform2fvARB; +GLEW_FUN_EXPORT PFNGLUNIFORM2IARBPROC __glewUniform2iARB; +GLEW_FUN_EXPORT PFNGLUNIFORM2IVARBPROC __glewUniform2ivARB; +GLEW_FUN_EXPORT PFNGLUNIFORM3FARBPROC __glewUniform3fARB; +GLEW_FUN_EXPORT PFNGLUNIFORM3FVARBPROC __glewUniform3fvARB; +GLEW_FUN_EXPORT PFNGLUNIFORM3IARBPROC __glewUniform3iARB; +GLEW_FUN_EXPORT PFNGLUNIFORM3IVARBPROC __glewUniform3ivARB; +GLEW_FUN_EXPORT PFNGLUNIFORM4FARBPROC __glewUniform4fARB; +GLEW_FUN_EXPORT PFNGLUNIFORM4FVARBPROC __glewUniform4fvARB; +GLEW_FUN_EXPORT PFNGLUNIFORM4IARBPROC __glewUniform4iARB; +GLEW_FUN_EXPORT PFNGLUNIFORM4IVARBPROC __glewUniform4ivARB; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2FVARBPROC __glewUniformMatrix2fvARB; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3FVARBPROC __glewUniformMatrix3fvARB; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4FVARBPROC __glewUniformMatrix4fvARB; +GLEW_FUN_EXPORT PFNGLUSEPROGRAMOBJECTARBPROC __glewUseProgramObjectARB; +GLEW_FUN_EXPORT PFNGLVALIDATEPROGRAMARBPROC __glewValidateProgramARB; + +GLEW_FUN_EXPORT PFNGLTEXBUFFERARBPROC __glewTexBufferARB; + +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE1DARBPROC __glewCompressedTexImage1DARB; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE2DARBPROC __glewCompressedTexImage2DARB; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE3DARBPROC __glewCompressedTexImage3DARB; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC __glewCompressedTexSubImage1DARB; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC __glewCompressedTexSubImage2DARB; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC __glewCompressedTexSubImage3DARB; +GLEW_FUN_EXPORT PFNGLGETCOMPRESSEDTEXIMAGEARBPROC __glewGetCompressedTexImageARB; + +GLEW_FUN_EXPORT PFNGLLOADTRANSPOSEMATRIXDARBPROC __glewLoadTransposeMatrixdARB; +GLEW_FUN_EXPORT PFNGLLOADTRANSPOSEMATRIXFARBPROC __glewLoadTransposeMatrixfARB; +GLEW_FUN_EXPORT PFNGLMULTTRANSPOSEMATRIXDARBPROC __glewMultTransposeMatrixdARB; +GLEW_FUN_EXPORT PFNGLMULTTRANSPOSEMATRIXFARBPROC __glewMultTransposeMatrixfARB; + +GLEW_FUN_EXPORT PFNGLBINDVERTEXARRAYPROC __glewBindVertexArray; +GLEW_FUN_EXPORT PFNGLDELETEVERTEXARRAYSPROC __glewDeleteVertexArrays; +GLEW_FUN_EXPORT PFNGLGENVERTEXARRAYSPROC __glewGenVertexArrays; +GLEW_FUN_EXPORT PFNGLISVERTEXARRAYPROC __glewIsVertexArray; + +GLEW_FUN_EXPORT PFNGLVERTEXBLENDARBPROC __glewVertexBlendARB; +GLEW_FUN_EXPORT PFNGLWEIGHTPOINTERARBPROC __glewWeightPointerARB; +GLEW_FUN_EXPORT PFNGLWEIGHTBVARBPROC __glewWeightbvARB; +GLEW_FUN_EXPORT PFNGLWEIGHTDVARBPROC __glewWeightdvARB; +GLEW_FUN_EXPORT PFNGLWEIGHTFVARBPROC __glewWeightfvARB; +GLEW_FUN_EXPORT PFNGLWEIGHTIVARBPROC __glewWeightivARB; +GLEW_FUN_EXPORT PFNGLWEIGHTSVARBPROC __glewWeightsvARB; +GLEW_FUN_EXPORT PFNGLWEIGHTUBVARBPROC __glewWeightubvARB; +GLEW_FUN_EXPORT PFNGLWEIGHTUIVARBPROC __glewWeightuivARB; +GLEW_FUN_EXPORT PFNGLWEIGHTUSVARBPROC __glewWeightusvARB; + +GLEW_FUN_EXPORT PFNGLBINDBUFFERARBPROC __glewBindBufferARB; +GLEW_FUN_EXPORT PFNGLBUFFERDATAARBPROC __glewBufferDataARB; +GLEW_FUN_EXPORT PFNGLBUFFERSUBDATAARBPROC __glewBufferSubDataARB; +GLEW_FUN_EXPORT PFNGLDELETEBUFFERSARBPROC __glewDeleteBuffersARB; +GLEW_FUN_EXPORT PFNGLGENBUFFERSARBPROC __glewGenBuffersARB; +GLEW_FUN_EXPORT PFNGLGETBUFFERPARAMETERIVARBPROC __glewGetBufferParameterivARB; +GLEW_FUN_EXPORT PFNGLGETBUFFERPOINTERVARBPROC __glewGetBufferPointervARB; +GLEW_FUN_EXPORT PFNGLGETBUFFERSUBDATAARBPROC __glewGetBufferSubDataARB; +GLEW_FUN_EXPORT PFNGLISBUFFERARBPROC __glewIsBufferARB; +GLEW_FUN_EXPORT PFNGLMAPBUFFERARBPROC __glewMapBufferARB; +GLEW_FUN_EXPORT PFNGLUNMAPBUFFERARBPROC __glewUnmapBufferARB; + +GLEW_FUN_EXPORT PFNGLBINDPROGRAMARBPROC __glewBindProgramARB; +GLEW_FUN_EXPORT PFNGLDELETEPROGRAMSARBPROC __glewDeleteProgramsARB; +GLEW_FUN_EXPORT PFNGLDISABLEVERTEXATTRIBARRAYARBPROC __glewDisableVertexAttribArrayARB; +GLEW_FUN_EXPORT PFNGLENABLEVERTEXATTRIBARRAYARBPROC __glewEnableVertexAttribArrayARB; +GLEW_FUN_EXPORT PFNGLGENPROGRAMSARBPROC __glewGenProgramsARB; +GLEW_FUN_EXPORT PFNGLGETPROGRAMENVPARAMETERDVARBPROC __glewGetProgramEnvParameterdvARB; +GLEW_FUN_EXPORT PFNGLGETPROGRAMENVPARAMETERFVARBPROC __glewGetProgramEnvParameterfvARB; +GLEW_FUN_EXPORT PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC __glewGetProgramLocalParameterdvARB; +GLEW_FUN_EXPORT PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC __glewGetProgramLocalParameterfvARB; +GLEW_FUN_EXPORT PFNGLGETPROGRAMSTRINGARBPROC __glewGetProgramStringARB; +GLEW_FUN_EXPORT PFNGLGETPROGRAMIVARBPROC __glewGetProgramivARB; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBPOINTERVARBPROC __glewGetVertexAttribPointervARB; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBDVARBPROC __glewGetVertexAttribdvARB; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBFVARBPROC __glewGetVertexAttribfvARB; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIVARBPROC __glewGetVertexAttribivARB; +GLEW_FUN_EXPORT PFNGLISPROGRAMARBPROC __glewIsProgramARB; +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETER4DARBPROC __glewProgramEnvParameter4dARB; +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETER4DVARBPROC __glewProgramEnvParameter4dvARB; +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETER4FARBPROC __glewProgramEnvParameter4fARB; +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETER4FVARBPROC __glewProgramEnvParameter4fvARB; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETER4DARBPROC __glewProgramLocalParameter4dARB; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETER4DVARBPROC __glewProgramLocalParameter4dvARB; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETER4FARBPROC __glewProgramLocalParameter4fARB; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETER4FVARBPROC __glewProgramLocalParameter4fvARB; +GLEW_FUN_EXPORT PFNGLPROGRAMSTRINGARBPROC __glewProgramStringARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DARBPROC __glewVertexAttrib1dARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DVARBPROC __glewVertexAttrib1dvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FARBPROC __glewVertexAttrib1fARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FVARBPROC __glewVertexAttrib1fvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SARBPROC __glewVertexAttrib1sARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SVARBPROC __glewVertexAttrib1svARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DARBPROC __glewVertexAttrib2dARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DVARBPROC __glewVertexAttrib2dvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FARBPROC __glewVertexAttrib2fARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FVARBPROC __glewVertexAttrib2fvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SARBPROC __glewVertexAttrib2sARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SVARBPROC __glewVertexAttrib2svARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DARBPROC __glewVertexAttrib3dARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DVARBPROC __glewVertexAttrib3dvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FARBPROC __glewVertexAttrib3fARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FVARBPROC __glewVertexAttrib3fvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SARBPROC __glewVertexAttrib3sARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SVARBPROC __glewVertexAttrib3svARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NBVARBPROC __glewVertexAttrib4NbvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NIVARBPROC __glewVertexAttrib4NivARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NSVARBPROC __glewVertexAttrib4NsvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUBARBPROC __glewVertexAttrib4NubARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUBVARBPROC __glewVertexAttrib4NubvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUIVARBPROC __glewVertexAttrib4NuivARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUSVARBPROC __glewVertexAttrib4NusvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4BVARBPROC __glewVertexAttrib4bvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DARBPROC __glewVertexAttrib4dARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DVARBPROC __glewVertexAttrib4dvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FARBPROC __glewVertexAttrib4fARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FVARBPROC __glewVertexAttrib4fvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4IVARBPROC __glewVertexAttrib4ivARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SARBPROC __glewVertexAttrib4sARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SVARBPROC __glewVertexAttrib4svARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UBVARBPROC __glewVertexAttrib4ubvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UIVARBPROC __glewVertexAttrib4uivARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4USVARBPROC __glewVertexAttrib4usvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBPOINTERARBPROC __glewVertexAttribPointerARB; + +GLEW_FUN_EXPORT PFNGLBINDATTRIBLOCATIONARBPROC __glewBindAttribLocationARB; +GLEW_FUN_EXPORT PFNGLGETACTIVEATTRIBARBPROC __glewGetActiveAttribARB; +GLEW_FUN_EXPORT PFNGLGETATTRIBLOCATIONARBPROC __glewGetAttribLocationARB; + +GLEW_FUN_EXPORT PFNGLWINDOWPOS2DARBPROC __glewWindowPos2dARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2DVARBPROC __glewWindowPos2dvARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2FARBPROC __glewWindowPos2fARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2FVARBPROC __glewWindowPos2fvARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2IARBPROC __glewWindowPos2iARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2IVARBPROC __glewWindowPos2ivARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2SARBPROC __glewWindowPos2sARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2SVARBPROC __glewWindowPos2svARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3DARBPROC __glewWindowPos3dARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3DVARBPROC __glewWindowPos3dvARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3FARBPROC __glewWindowPos3fARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3FVARBPROC __glewWindowPos3fvARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3IARBPROC __glewWindowPos3iARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3IVARBPROC __glewWindowPos3ivARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3SARBPROC __glewWindowPos3sARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3SVARBPROC __glewWindowPos3svARB; + +GLEW_FUN_EXPORT PFNGLDRAWBUFFERSATIPROC __glewDrawBuffersATI; + +GLEW_FUN_EXPORT PFNGLDRAWELEMENTARRAYATIPROC __glewDrawElementArrayATI; +GLEW_FUN_EXPORT PFNGLDRAWRANGEELEMENTARRAYATIPROC __glewDrawRangeElementArrayATI; +GLEW_FUN_EXPORT PFNGLELEMENTPOINTERATIPROC __glewElementPointerATI; + +GLEW_FUN_EXPORT PFNGLGETTEXBUMPPARAMETERFVATIPROC __glewGetTexBumpParameterfvATI; +GLEW_FUN_EXPORT PFNGLGETTEXBUMPPARAMETERIVATIPROC __glewGetTexBumpParameterivATI; +GLEW_FUN_EXPORT PFNGLTEXBUMPPARAMETERFVATIPROC __glewTexBumpParameterfvATI; +GLEW_FUN_EXPORT PFNGLTEXBUMPPARAMETERIVATIPROC __glewTexBumpParameterivATI; + +GLEW_FUN_EXPORT PFNGLALPHAFRAGMENTOP1ATIPROC __glewAlphaFragmentOp1ATI; +GLEW_FUN_EXPORT PFNGLALPHAFRAGMENTOP2ATIPROC __glewAlphaFragmentOp2ATI; +GLEW_FUN_EXPORT PFNGLALPHAFRAGMENTOP3ATIPROC __glewAlphaFragmentOp3ATI; +GLEW_FUN_EXPORT PFNGLBEGINFRAGMENTSHADERATIPROC __glewBeginFragmentShaderATI; +GLEW_FUN_EXPORT PFNGLBINDFRAGMENTSHADERATIPROC __glewBindFragmentShaderATI; +GLEW_FUN_EXPORT PFNGLCOLORFRAGMENTOP1ATIPROC __glewColorFragmentOp1ATI; +GLEW_FUN_EXPORT PFNGLCOLORFRAGMENTOP2ATIPROC __glewColorFragmentOp2ATI; +GLEW_FUN_EXPORT PFNGLCOLORFRAGMENTOP3ATIPROC __glewColorFragmentOp3ATI; +GLEW_FUN_EXPORT PFNGLDELETEFRAGMENTSHADERATIPROC __glewDeleteFragmentShaderATI; +GLEW_FUN_EXPORT PFNGLENDFRAGMENTSHADERATIPROC __glewEndFragmentShaderATI; +GLEW_FUN_EXPORT PFNGLGENFRAGMENTSHADERSATIPROC __glewGenFragmentShadersATI; +GLEW_FUN_EXPORT PFNGLPASSTEXCOORDATIPROC __glewPassTexCoordATI; +GLEW_FUN_EXPORT PFNGLSAMPLEMAPATIPROC __glewSampleMapATI; +GLEW_FUN_EXPORT PFNGLSETFRAGMENTSHADERCONSTANTATIPROC __glewSetFragmentShaderConstantATI; + +GLEW_FUN_EXPORT PFNGLMAPOBJECTBUFFERATIPROC __glewMapObjectBufferATI; +GLEW_FUN_EXPORT PFNGLUNMAPOBJECTBUFFERATIPROC __glewUnmapObjectBufferATI; + +GLEW_FUN_EXPORT PFNGLPNTRIANGLESFATIPROC __glPNTrianglewesfATI; +GLEW_FUN_EXPORT PFNGLPNTRIANGLESIATIPROC __glPNTrianglewesiATI; + +GLEW_FUN_EXPORT PFNGLSTENCILFUNCSEPARATEATIPROC __glewStencilFuncSeparateATI; +GLEW_FUN_EXPORT PFNGLSTENCILOPSEPARATEATIPROC __glewStencilOpSeparateATI; + +GLEW_FUN_EXPORT PFNGLARRAYOBJECTATIPROC __glewArrayObjectATI; +GLEW_FUN_EXPORT PFNGLFREEOBJECTBUFFERATIPROC __glewFreeObjectBufferATI; +GLEW_FUN_EXPORT PFNGLGETARRAYOBJECTFVATIPROC __glewGetArrayObjectfvATI; +GLEW_FUN_EXPORT PFNGLGETARRAYOBJECTIVATIPROC __glewGetArrayObjectivATI; +GLEW_FUN_EXPORT PFNGLGETOBJECTBUFFERFVATIPROC __glewGetObjectBufferfvATI; +GLEW_FUN_EXPORT PFNGLGETOBJECTBUFFERIVATIPROC __glewGetObjectBufferivATI; +GLEW_FUN_EXPORT PFNGLGETVARIANTARRAYOBJECTFVATIPROC __glewGetVariantArrayObjectfvATI; +GLEW_FUN_EXPORT PFNGLGETVARIANTARRAYOBJECTIVATIPROC __glewGetVariantArrayObjectivATI; +GLEW_FUN_EXPORT PFNGLISOBJECTBUFFERATIPROC __glewIsObjectBufferATI; +GLEW_FUN_EXPORT PFNGLNEWOBJECTBUFFERATIPROC __glewNewObjectBufferATI; +GLEW_FUN_EXPORT PFNGLUPDATEOBJECTBUFFERATIPROC __glewUpdateObjectBufferATI; +GLEW_FUN_EXPORT PFNGLVARIANTARRAYOBJECTATIPROC __glewVariantArrayObjectATI; + +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC __glewGetVertexAttribArrayObjectfvATI; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC __glewGetVertexAttribArrayObjectivATI; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBARRAYOBJECTATIPROC __glewVertexAttribArrayObjectATI; + +GLEW_FUN_EXPORT PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC __glewClientActiveVertexStreamATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3BATIPROC __glewNormalStream3bATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3BVATIPROC __glewNormalStream3bvATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3DATIPROC __glewNormalStream3dATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3DVATIPROC __glewNormalStream3dvATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3FATIPROC __glewNormalStream3fATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3FVATIPROC __glewNormalStream3fvATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3IATIPROC __glewNormalStream3iATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3IVATIPROC __glewNormalStream3ivATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3SATIPROC __glewNormalStream3sATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3SVATIPROC __glewNormalStream3svATI; +GLEW_FUN_EXPORT PFNGLVERTEXBLENDENVFATIPROC __glewVertexBlendEnvfATI; +GLEW_FUN_EXPORT PFNGLVERTEXBLENDENVIATIPROC __glewVertexBlendEnviATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2DATIPROC __glewVertexStream2dATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2DVATIPROC __glewVertexStream2dvATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2FATIPROC __glewVertexStream2fATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2FVATIPROC __glewVertexStream2fvATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2IATIPROC __glewVertexStream2iATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2IVATIPROC __glewVertexStream2ivATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2SATIPROC __glewVertexStream2sATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2SVATIPROC __glewVertexStream2svATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3DATIPROC __glewVertexStream3dATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3DVATIPROC __glewVertexStream3dvATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3FATIPROC __glewVertexStream3fATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3FVATIPROC __glewVertexStream3fvATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3IATIPROC __glewVertexStream3iATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3IVATIPROC __glewVertexStream3ivATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3SATIPROC __glewVertexStream3sATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3SVATIPROC __glewVertexStream3svATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4DATIPROC __glewVertexStream4dATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4DVATIPROC __glewVertexStream4dvATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4FATIPROC __glewVertexStream4fATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4FVATIPROC __glewVertexStream4fvATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4IATIPROC __glewVertexStream4iATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4IVATIPROC __glewVertexStream4ivATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4SATIPROC __glewVertexStream4sATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4SVATIPROC __glewVertexStream4svATI; + +GLEW_FUN_EXPORT PFNGLGETUNIFORMBUFFERSIZEEXTPROC __glewGetUniformBufferSizeEXT; +GLEW_FUN_EXPORT PFNGLGETUNIFORMOFFSETEXTPROC __glewGetUniformOffsetEXT; +GLEW_FUN_EXPORT PFNGLUNIFORMBUFFEREXTPROC __glewUniformBufferEXT; + +GLEW_FUN_EXPORT PFNGLBLENDCOLOREXTPROC __glewBlendColorEXT; + +GLEW_FUN_EXPORT PFNGLBLENDEQUATIONSEPARATEEXTPROC __glewBlendEquationSeparateEXT; + +GLEW_FUN_EXPORT PFNGLBLENDFUNCSEPARATEEXTPROC __glewBlendFuncSeparateEXT; + +GLEW_FUN_EXPORT PFNGLBLENDEQUATIONEXTPROC __glewBlendEquationEXT; + +GLEW_FUN_EXPORT PFNGLCOLORSUBTABLEEXTPROC __glewColorSubTableEXT; +GLEW_FUN_EXPORT PFNGLCOPYCOLORSUBTABLEEXTPROC __glewCopyColorSubTableEXT; + +GLEW_FUN_EXPORT PFNGLLOCKARRAYSEXTPROC __glewLockArraysEXT; +GLEW_FUN_EXPORT PFNGLUNLOCKARRAYSEXTPROC __glewUnlockArraysEXT; + +GLEW_FUN_EXPORT PFNGLCONVOLUTIONFILTER1DEXTPROC __glewConvolutionFilter1DEXT; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONFILTER2DEXTPROC __glewConvolutionFilter2DEXT; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERFEXTPROC __glewConvolutionParameterfEXT; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERFVEXTPROC __glewConvolutionParameterfvEXT; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERIEXTPROC __glewConvolutionParameteriEXT; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERIVEXTPROC __glewConvolutionParameterivEXT; +GLEW_FUN_EXPORT PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC __glewCopyConvolutionFilter1DEXT; +GLEW_FUN_EXPORT PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC __glewCopyConvolutionFilter2DEXT; +GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONFILTEREXTPROC __glewGetConvolutionFilterEXT; +GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC __glewGetConvolutionParameterfvEXT; +GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC __glewGetConvolutionParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETSEPARABLEFILTEREXTPROC __glewGetSeparableFilterEXT; +GLEW_FUN_EXPORT PFNGLSEPARABLEFILTER2DEXTPROC __glewSeparableFilter2DEXT; + +GLEW_FUN_EXPORT PFNGLBINORMALPOINTEREXTPROC __glewBinormalPointerEXT; +GLEW_FUN_EXPORT PFNGLTANGENTPOINTEREXTPROC __glewTangentPointerEXT; + +GLEW_FUN_EXPORT PFNGLCOPYTEXIMAGE1DEXTPROC __glewCopyTexImage1DEXT; +GLEW_FUN_EXPORT PFNGLCOPYTEXIMAGE2DEXTPROC __glewCopyTexImage2DEXT; +GLEW_FUN_EXPORT PFNGLCOPYTEXSUBIMAGE1DEXTPROC __glewCopyTexSubImage1DEXT; +GLEW_FUN_EXPORT PFNGLCOPYTEXSUBIMAGE2DEXTPROC __glewCopyTexSubImage2DEXT; +GLEW_FUN_EXPORT PFNGLCOPYTEXSUBIMAGE3DEXTPROC __glewCopyTexSubImage3DEXT; + +GLEW_FUN_EXPORT PFNGLCULLPARAMETERDVEXTPROC __glewCullParameterdvEXT; +GLEW_FUN_EXPORT PFNGLCULLPARAMETERFVEXTPROC __glewCullParameterfvEXT; + +GLEW_FUN_EXPORT PFNGLDEPTHBOUNDSEXTPROC __glewDepthBoundsEXT; + +GLEW_FUN_EXPORT PFNGLBINDMULTITEXTUREEXTPROC __glewBindMultiTextureEXT; +GLEW_FUN_EXPORT PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC __glewCheckNamedFramebufferStatusEXT; +GLEW_FUN_EXPORT PFNGLCLIENTATTRIBDEFAULTEXTPROC __glewClientAttribDefaultEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC __glewCompressedMultiTexImage1DEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC __glewCompressedMultiTexImage2DEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC __glewCompressedMultiTexImage3DEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC __glewCompressedMultiTexSubImage1DEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC __glewCompressedMultiTexSubImage2DEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC __glewCompressedMultiTexSubImage3DEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC __glewCompressedTextureImage1DEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC __glewCompressedTextureImage2DEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC __glewCompressedTextureImage3DEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC __glewCompressedTextureSubImage1DEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC __glewCompressedTextureSubImage2DEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC __glewCompressedTextureSubImage3DEXT; +GLEW_FUN_EXPORT PFNGLCOPYMULTITEXIMAGE1DEXTPROC __glewCopyMultiTexImage1DEXT; +GLEW_FUN_EXPORT PFNGLCOPYMULTITEXIMAGE2DEXTPROC __glewCopyMultiTexImage2DEXT; +GLEW_FUN_EXPORT PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC __glewCopyMultiTexSubImage1DEXT; +GLEW_FUN_EXPORT PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC __glewCopyMultiTexSubImage2DEXT; +GLEW_FUN_EXPORT PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC __glewCopyMultiTexSubImage3DEXT; +GLEW_FUN_EXPORT PFNGLCOPYTEXTUREIMAGE1DEXTPROC __glewCopyTextureImage1DEXT; +GLEW_FUN_EXPORT PFNGLCOPYTEXTUREIMAGE2DEXTPROC __glewCopyTextureImage2DEXT; +GLEW_FUN_EXPORT PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC __glewCopyTextureSubImage1DEXT; +GLEW_FUN_EXPORT PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC __glewCopyTextureSubImage2DEXT; +GLEW_FUN_EXPORT PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC __glewCopyTextureSubImage3DEXT; +GLEW_FUN_EXPORT PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC __glewDisableClientStateIndexedEXT; +GLEW_FUN_EXPORT PFNGLENABLECLIENTSTATEINDEXEDEXTPROC __glewEnableClientStateIndexedEXT; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC __glewFramebufferDrawBufferEXT; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC __glewFramebufferDrawBuffersEXT; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERREADBUFFEREXTPROC __glewFramebufferReadBufferEXT; +GLEW_FUN_EXPORT PFNGLGENERATEMULTITEXMIPMAPEXTPROC __glewGenerateMultiTexMipmapEXT; +GLEW_FUN_EXPORT PFNGLGENERATETEXTUREMIPMAPEXTPROC __glewGenerateTextureMipmapEXT; +GLEW_FUN_EXPORT PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC __glewGetCompressedMultiTexImageEXT; +GLEW_FUN_EXPORT PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC __glewGetCompressedTextureImageEXT; +GLEW_FUN_EXPORT PFNGLGETDOUBLEINDEXEDVEXTPROC __glewGetDoubleIndexedvEXT; +GLEW_FUN_EXPORT PFNGLGETFLOATINDEXEDVEXTPROC __glewGetFloatIndexedvEXT; +GLEW_FUN_EXPORT PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC __glewGetFramebufferParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXENVFVEXTPROC __glewGetMultiTexEnvfvEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXENVIVEXTPROC __glewGetMultiTexEnvivEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXGENDVEXTPROC __glewGetMultiTexGendvEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXGENFVEXTPROC __glewGetMultiTexGenfvEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXGENIVEXTPROC __glewGetMultiTexGenivEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXIMAGEEXTPROC __glewGetMultiTexImageEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC __glewGetMultiTexLevelParameterfvEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC __glewGetMultiTexLevelParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXPARAMETERIIVEXTPROC __glewGetMultiTexParameterIivEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXPARAMETERIUIVEXTPROC __glewGetMultiTexParameterIuivEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXPARAMETERFVEXTPROC __glewGetMultiTexParameterfvEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXPARAMETERIVEXTPROC __glewGetMultiTexParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC __glewGetNamedBufferParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETNAMEDBUFFERPOINTERVEXTPROC __glewGetNamedBufferPointervEXT; +GLEW_FUN_EXPORT PFNGLGETNAMEDBUFFERSUBDATAEXTPROC __glewGetNamedBufferSubDataEXT; +GLEW_FUN_EXPORT PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC __glewGetNamedFramebufferAttachmentParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC __glewGetNamedProgramLocalParameterIivEXT; +GLEW_FUN_EXPORT PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC __glewGetNamedProgramLocalParameterIuivEXT; +GLEW_FUN_EXPORT PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC __glewGetNamedProgramLocalParameterdvEXT; +GLEW_FUN_EXPORT PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC __glewGetNamedProgramLocalParameterfvEXT; +GLEW_FUN_EXPORT PFNGLGETNAMEDPROGRAMSTRINGEXTPROC __glewGetNamedProgramStringEXT; +GLEW_FUN_EXPORT PFNGLGETNAMEDPROGRAMIVEXTPROC __glewGetNamedProgramivEXT; +GLEW_FUN_EXPORT PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC __glewGetNamedRenderbufferParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETPOINTERINDEXEDVEXTPROC __glewGetPointerIndexedvEXT; +GLEW_FUN_EXPORT PFNGLGETTEXTUREIMAGEEXTPROC __glewGetTextureImageEXT; +GLEW_FUN_EXPORT PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC __glewGetTextureLevelParameterfvEXT; +GLEW_FUN_EXPORT PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC __glewGetTextureLevelParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETTEXTUREPARAMETERIIVEXTPROC __glewGetTextureParameterIivEXT; +GLEW_FUN_EXPORT PFNGLGETTEXTUREPARAMETERIUIVEXTPROC __glewGetTextureParameterIuivEXT; +GLEW_FUN_EXPORT PFNGLGETTEXTUREPARAMETERFVEXTPROC __glewGetTextureParameterfvEXT; +GLEW_FUN_EXPORT PFNGLGETTEXTUREPARAMETERIVEXTPROC __glewGetTextureParameterivEXT; +GLEW_FUN_EXPORT PFNGLMAPNAMEDBUFFEREXTPROC __glewMapNamedBufferEXT; +GLEW_FUN_EXPORT PFNGLMATRIXFRUSTUMEXTPROC __glewMatrixFrustumEXT; +GLEW_FUN_EXPORT PFNGLMATRIXLOADIDENTITYEXTPROC __glewMatrixLoadIdentityEXT; +GLEW_FUN_EXPORT PFNGLMATRIXLOADTRANSPOSEDEXTPROC __glewMatrixLoadTransposedEXT; +GLEW_FUN_EXPORT PFNGLMATRIXLOADTRANSPOSEFEXTPROC __glewMatrixLoadTransposefEXT; +GLEW_FUN_EXPORT PFNGLMATRIXLOADDEXTPROC __glewMatrixLoaddEXT; +GLEW_FUN_EXPORT PFNGLMATRIXLOADFEXTPROC __glewMatrixLoadfEXT; +GLEW_FUN_EXPORT PFNGLMATRIXMULTTRANSPOSEDEXTPROC __glewMatrixMultTransposedEXT; +GLEW_FUN_EXPORT PFNGLMATRIXMULTTRANSPOSEFEXTPROC __glewMatrixMultTransposefEXT; +GLEW_FUN_EXPORT PFNGLMATRIXMULTDEXTPROC __glewMatrixMultdEXT; +GLEW_FUN_EXPORT PFNGLMATRIXMULTFEXTPROC __glewMatrixMultfEXT; +GLEW_FUN_EXPORT PFNGLMATRIXORTHOEXTPROC __glewMatrixOrthoEXT; +GLEW_FUN_EXPORT PFNGLMATRIXPOPEXTPROC __glewMatrixPopEXT; +GLEW_FUN_EXPORT PFNGLMATRIXPUSHEXTPROC __glewMatrixPushEXT; +GLEW_FUN_EXPORT PFNGLMATRIXROTATEDEXTPROC __glewMatrixRotatedEXT; +GLEW_FUN_EXPORT PFNGLMATRIXROTATEFEXTPROC __glewMatrixRotatefEXT; +GLEW_FUN_EXPORT PFNGLMATRIXSCALEDEXTPROC __glewMatrixScaledEXT; +GLEW_FUN_EXPORT PFNGLMATRIXSCALEFEXTPROC __glewMatrixScalefEXT; +GLEW_FUN_EXPORT PFNGLMATRIXTRANSLATEDEXTPROC __glewMatrixTranslatedEXT; +GLEW_FUN_EXPORT PFNGLMATRIXTRANSLATEFEXTPROC __glewMatrixTranslatefEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXBUFFEREXTPROC __glewMultiTexBufferEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORDPOINTEREXTPROC __glewMultiTexCoordPointerEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXENVFEXTPROC __glewMultiTexEnvfEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXENVFVEXTPROC __glewMultiTexEnvfvEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXENVIEXTPROC __glewMultiTexEnviEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXENVIVEXTPROC __glewMultiTexEnvivEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXGENDEXTPROC __glewMultiTexGendEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXGENDVEXTPROC __glewMultiTexGendvEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXGENFEXTPROC __glewMultiTexGenfEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXGENFVEXTPROC __glewMultiTexGenfvEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXGENIEXTPROC __glewMultiTexGeniEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXGENIVEXTPROC __glewMultiTexGenivEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXIMAGE1DEXTPROC __glewMultiTexImage1DEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXIMAGE2DEXTPROC __glewMultiTexImage2DEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXIMAGE3DEXTPROC __glewMultiTexImage3DEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXPARAMETERIIVEXTPROC __glewMultiTexParameterIivEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXPARAMETERIUIVEXTPROC __glewMultiTexParameterIuivEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXPARAMETERFEXTPROC __glewMultiTexParameterfEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXPARAMETERFVEXTPROC __glewMultiTexParameterfvEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXPARAMETERIEXTPROC __glewMultiTexParameteriEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXPARAMETERIVEXTPROC __glewMultiTexParameterivEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXRENDERBUFFEREXTPROC __glewMultiTexRenderbufferEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXSUBIMAGE1DEXTPROC __glewMultiTexSubImage1DEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXSUBIMAGE2DEXTPROC __glewMultiTexSubImage2DEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXSUBIMAGE3DEXTPROC __glewMultiTexSubImage3DEXT; +GLEW_FUN_EXPORT PFNGLNAMEDBUFFERDATAEXTPROC __glewNamedBufferDataEXT; +GLEW_FUN_EXPORT PFNGLNAMEDBUFFERSUBDATAEXTPROC __glewNamedBufferSubDataEXT; +GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC __glewNamedFramebufferRenderbufferEXT; +GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC __glewNamedFramebufferTexture1DEXT; +GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC __glewNamedFramebufferTexture2DEXT; +GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC __glewNamedFramebufferTexture3DEXT; +GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC __glewNamedFramebufferTextureEXT; +GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC __glewNamedFramebufferTextureFaceEXT; +GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC __glewNamedFramebufferTextureLayerEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC __glewNamedProgramLocalParameter4dEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC __glewNamedProgramLocalParameter4dvEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC __glewNamedProgramLocalParameter4fEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC __glewNamedProgramLocalParameter4fvEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC __glewNamedProgramLocalParameterI4iEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC __glewNamedProgramLocalParameterI4ivEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC __glewNamedProgramLocalParameterI4uiEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC __glewNamedProgramLocalParameterI4uivEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC __glewNamedProgramLocalParameters4fvEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC __glewNamedProgramLocalParametersI4ivEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC __glewNamedProgramLocalParametersI4uivEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMSTRINGEXTPROC __glewNamedProgramStringEXT; +GLEW_FUN_EXPORT PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC __glewNamedRenderbufferStorageEXT; +GLEW_FUN_EXPORT PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC __glewNamedRenderbufferStorageMultisampleCoverageEXT; +GLEW_FUN_EXPORT PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC __glewNamedRenderbufferStorageMultisampleEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1FEXTPROC __glewProgramUniform1fEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1FVEXTPROC __glewProgramUniform1fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1IEXTPROC __glewProgramUniform1iEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1IVEXTPROC __glewProgramUniform1ivEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1UIEXTPROC __glewProgramUniform1uiEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1UIVEXTPROC __glewProgramUniform1uivEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2FEXTPROC __glewProgramUniform2fEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2FVEXTPROC __glewProgramUniform2fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2IEXTPROC __glewProgramUniform2iEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2IVEXTPROC __glewProgramUniform2ivEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2UIEXTPROC __glewProgramUniform2uiEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2UIVEXTPROC __glewProgramUniform2uivEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3FEXTPROC __glewProgramUniform3fEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3FVEXTPROC __glewProgramUniform3fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3IEXTPROC __glewProgramUniform3iEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3IVEXTPROC __glewProgramUniform3ivEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3UIEXTPROC __glewProgramUniform3uiEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3UIVEXTPROC __glewProgramUniform3uivEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4FEXTPROC __glewProgramUniform4fEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4FVEXTPROC __glewProgramUniform4fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4IEXTPROC __glewProgramUniform4iEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4IVEXTPROC __glewProgramUniform4ivEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4UIEXTPROC __glewProgramUniform4uiEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4UIVEXTPROC __glewProgramUniform4uivEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC __glewProgramUniformMatrix2fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC __glewProgramUniformMatrix2x3fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC __glewProgramUniformMatrix2x4fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC __glewProgramUniformMatrix3fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC __glewProgramUniformMatrix3x2fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC __glewProgramUniformMatrix3x4fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC __glewProgramUniformMatrix4fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC __glewProgramUniformMatrix4x2fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC __glewProgramUniformMatrix4x3fvEXT; +GLEW_FUN_EXPORT PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC __glewPushClientAttribDefaultEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREBUFFEREXTPROC __glewTextureBufferEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREIMAGE1DEXTPROC __glewTextureImage1DEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREIMAGE2DEXTPROC __glewTextureImage2DEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREIMAGE3DEXTPROC __glewTextureImage3DEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERIIVEXTPROC __glewTextureParameterIivEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERIUIVEXTPROC __glewTextureParameterIuivEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERFEXTPROC __glewTextureParameterfEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERFVEXTPROC __glewTextureParameterfvEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERIEXTPROC __glewTextureParameteriEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERIVEXTPROC __glewTextureParameterivEXT; +GLEW_FUN_EXPORT PFNGLTEXTURERENDERBUFFEREXTPROC __glewTextureRenderbufferEXT; +GLEW_FUN_EXPORT PFNGLTEXTURESUBIMAGE1DEXTPROC __glewTextureSubImage1DEXT; +GLEW_FUN_EXPORT PFNGLTEXTURESUBIMAGE2DEXTPROC __glewTextureSubImage2DEXT; +GLEW_FUN_EXPORT PFNGLTEXTURESUBIMAGE3DEXTPROC __glewTextureSubImage3DEXT; +GLEW_FUN_EXPORT PFNGLUNMAPNAMEDBUFFEREXTPROC __glewUnmapNamedBufferEXT; + +GLEW_FUN_EXPORT PFNGLCOLORMASKINDEXEDEXTPROC __glewColorMaskIndexedEXT; +GLEW_FUN_EXPORT PFNGLDISABLEINDEXEDEXTPROC __glewDisableIndexedEXT; +GLEW_FUN_EXPORT PFNGLENABLEINDEXEDEXTPROC __glewEnableIndexedEXT; +GLEW_FUN_EXPORT PFNGLGETBOOLEANINDEXEDVEXTPROC __glewGetBooleanIndexedvEXT; +GLEW_FUN_EXPORT PFNGLGETINTEGERINDEXEDVEXTPROC __glewGetIntegerIndexedvEXT; +GLEW_FUN_EXPORT PFNGLISENABLEDINDEXEDEXTPROC __glewIsEnabledIndexedEXT; + +GLEW_FUN_EXPORT PFNGLDRAWARRAYSINSTANCEDEXTPROC __glewDrawArraysInstancedEXT; +GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDEXTPROC __glewDrawElementsInstancedEXT; + +GLEW_FUN_EXPORT PFNGLDRAWRANGEELEMENTSEXTPROC __glewDrawRangeElementsEXT; + +GLEW_FUN_EXPORT PFNGLFOGCOORDPOINTEREXTPROC __glewFogCoordPointerEXT; +GLEW_FUN_EXPORT PFNGLFOGCOORDDEXTPROC __glewFogCoorddEXT; +GLEW_FUN_EXPORT PFNGLFOGCOORDDVEXTPROC __glewFogCoorddvEXT; +GLEW_FUN_EXPORT PFNGLFOGCOORDFEXTPROC __glewFogCoordfEXT; +GLEW_FUN_EXPORT PFNGLFOGCOORDFVEXTPROC __glewFogCoordfvEXT; + +GLEW_FUN_EXPORT PFNGLFRAGMENTCOLORMATERIALEXTPROC __glewFragmentColorMaterialEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELFEXTPROC __glewFragmentLightModelfEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELFVEXTPROC __glewFragmentLightModelfvEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELIEXTPROC __glewFragmentLightModeliEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELIVEXTPROC __glewFragmentLightModelivEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTFEXTPROC __glewFragmentLightfEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTFVEXTPROC __glewFragmentLightfvEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTIEXTPROC __glewFragmentLightiEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTIVEXTPROC __glewFragmentLightivEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALFEXTPROC __glewFragmentMaterialfEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALFVEXTPROC __glewFragmentMaterialfvEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALIEXTPROC __glewFragmentMaterialiEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALIVEXTPROC __glewFragmentMaterialivEXT; +GLEW_FUN_EXPORT PFNGLGETFRAGMENTLIGHTFVEXTPROC __glewGetFragmentLightfvEXT; +GLEW_FUN_EXPORT PFNGLGETFRAGMENTLIGHTIVEXTPROC __glewGetFragmentLightivEXT; +GLEW_FUN_EXPORT PFNGLGETFRAGMENTMATERIALFVEXTPROC __glewGetFragmentMaterialfvEXT; +GLEW_FUN_EXPORT PFNGLGETFRAGMENTMATERIALIVEXTPROC __glewGetFragmentMaterialivEXT; +GLEW_FUN_EXPORT PFNGLLIGHTENVIEXTPROC __glewLightEnviEXT; + +GLEW_FUN_EXPORT PFNGLBLITFRAMEBUFFEREXTPROC __glewBlitFramebufferEXT; + +GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC __glewRenderbufferStorageMultisampleEXT; + +GLEW_FUN_EXPORT PFNGLBINDFRAMEBUFFEREXTPROC __glewBindFramebufferEXT; +GLEW_FUN_EXPORT PFNGLBINDRENDERBUFFEREXTPROC __glewBindRenderbufferEXT; +GLEW_FUN_EXPORT PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC __glewCheckFramebufferStatusEXT; +GLEW_FUN_EXPORT PFNGLDELETEFRAMEBUFFERSEXTPROC __glewDeleteFramebuffersEXT; +GLEW_FUN_EXPORT PFNGLDELETERENDERBUFFERSEXTPROC __glewDeleteRenderbuffersEXT; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC __glewFramebufferRenderbufferEXT; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE1DEXTPROC __glewFramebufferTexture1DEXT; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE2DEXTPROC __glewFramebufferTexture2DEXT; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE3DEXTPROC __glewFramebufferTexture3DEXT; +GLEW_FUN_EXPORT PFNGLGENFRAMEBUFFERSEXTPROC __glewGenFramebuffersEXT; +GLEW_FUN_EXPORT PFNGLGENRENDERBUFFERSEXTPROC __glewGenRenderbuffersEXT; +GLEW_FUN_EXPORT PFNGLGENERATEMIPMAPEXTPROC __glewGenerateMipmapEXT; +GLEW_FUN_EXPORT PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC __glewGetFramebufferAttachmentParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC __glewGetRenderbufferParameterivEXT; +GLEW_FUN_EXPORT PFNGLISFRAMEBUFFEREXTPROC __glewIsFramebufferEXT; +GLEW_FUN_EXPORT PFNGLISRENDERBUFFEREXTPROC __glewIsRenderbufferEXT; +GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEEXTPROC __glewRenderbufferStorageEXT; + +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTUREEXTPROC __glewFramebufferTextureEXT; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC __glewFramebufferTextureFaceEXT; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC __glewFramebufferTextureLayerEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETERIEXTPROC __glewProgramParameteriEXT; + +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERS4FVEXTPROC __glewProgramEnvParameters4fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC __glewProgramLocalParameters4fvEXT; + +GLEW_FUN_EXPORT PFNGLBINDFRAGDATALOCATIONEXTPROC __glewBindFragDataLocationEXT; +GLEW_FUN_EXPORT PFNGLGETFRAGDATALOCATIONEXTPROC __glewGetFragDataLocationEXT; +GLEW_FUN_EXPORT PFNGLGETUNIFORMUIVEXTPROC __glewGetUniformuivEXT; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIIVEXTPROC __glewGetVertexAttribIivEXT; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIUIVEXTPROC __glewGetVertexAttribIuivEXT; +GLEW_FUN_EXPORT PFNGLUNIFORM1UIEXTPROC __glewUniform1uiEXT; +GLEW_FUN_EXPORT PFNGLUNIFORM1UIVEXTPROC __glewUniform1uivEXT; +GLEW_FUN_EXPORT PFNGLUNIFORM2UIEXTPROC __glewUniform2uiEXT; +GLEW_FUN_EXPORT PFNGLUNIFORM2UIVEXTPROC __glewUniform2uivEXT; +GLEW_FUN_EXPORT PFNGLUNIFORM3UIEXTPROC __glewUniform3uiEXT; +GLEW_FUN_EXPORT PFNGLUNIFORM3UIVEXTPROC __glewUniform3uivEXT; +GLEW_FUN_EXPORT PFNGLUNIFORM4UIEXTPROC __glewUniform4uiEXT; +GLEW_FUN_EXPORT PFNGLUNIFORM4UIVEXTPROC __glewUniform4uivEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1IEXTPROC __glewVertexAttribI1iEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1IVEXTPROC __glewVertexAttribI1ivEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1UIEXTPROC __glewVertexAttribI1uiEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1UIVEXTPROC __glewVertexAttribI1uivEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2IEXTPROC __glewVertexAttribI2iEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2IVEXTPROC __glewVertexAttribI2ivEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2UIEXTPROC __glewVertexAttribI2uiEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2UIVEXTPROC __glewVertexAttribI2uivEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3IEXTPROC __glewVertexAttribI3iEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3IVEXTPROC __glewVertexAttribI3ivEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3UIEXTPROC __glewVertexAttribI3uiEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3UIVEXTPROC __glewVertexAttribI3uivEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4BVEXTPROC __glewVertexAttribI4bvEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4IEXTPROC __glewVertexAttribI4iEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4IVEXTPROC __glewVertexAttribI4ivEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4SVEXTPROC __glewVertexAttribI4svEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4UBVEXTPROC __glewVertexAttribI4ubvEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4UIEXTPROC __glewVertexAttribI4uiEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4UIVEXTPROC __glewVertexAttribI4uivEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4USVEXTPROC __glewVertexAttribI4usvEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBIPOINTEREXTPROC __glewVertexAttribIPointerEXT; + +GLEW_FUN_EXPORT PFNGLGETHISTOGRAMEXTPROC __glewGetHistogramEXT; +GLEW_FUN_EXPORT PFNGLGETHISTOGRAMPARAMETERFVEXTPROC __glewGetHistogramParameterfvEXT; +GLEW_FUN_EXPORT PFNGLGETHISTOGRAMPARAMETERIVEXTPROC __glewGetHistogramParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETMINMAXEXTPROC __glewGetMinmaxEXT; +GLEW_FUN_EXPORT PFNGLGETMINMAXPARAMETERFVEXTPROC __glewGetMinmaxParameterfvEXT; +GLEW_FUN_EXPORT PFNGLGETMINMAXPARAMETERIVEXTPROC __glewGetMinmaxParameterivEXT; +GLEW_FUN_EXPORT PFNGLHISTOGRAMEXTPROC __glewHistogramEXT; +GLEW_FUN_EXPORT PFNGLMINMAXEXTPROC __glewMinmaxEXT; +GLEW_FUN_EXPORT PFNGLRESETHISTOGRAMEXTPROC __glewResetHistogramEXT; +GLEW_FUN_EXPORT PFNGLRESETMINMAXEXTPROC __glewResetMinmaxEXT; + +GLEW_FUN_EXPORT PFNGLINDEXFUNCEXTPROC __glewIndexFuncEXT; + +GLEW_FUN_EXPORT PFNGLINDEXMATERIALEXTPROC __glewIndexMaterialEXT; + +GLEW_FUN_EXPORT PFNGLAPPLYTEXTUREEXTPROC __glewApplyTextureEXT; +GLEW_FUN_EXPORT PFNGLTEXTURELIGHTEXTPROC __glewTextureLightEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREMATERIALEXTPROC __glewTextureMaterialEXT; + +GLEW_FUN_EXPORT PFNGLMULTIDRAWARRAYSEXTPROC __glewMultiDrawArraysEXT; +GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSEXTPROC __glewMultiDrawElementsEXT; + +GLEW_FUN_EXPORT PFNGLSAMPLEMASKEXTPROC __glewSampleMaskEXT; +GLEW_FUN_EXPORT PFNGLSAMPLEPATTERNEXTPROC __glewSamplePatternEXT; + +GLEW_FUN_EXPORT PFNGLCOLORTABLEEXTPROC __glewColorTableEXT; +GLEW_FUN_EXPORT PFNGLGETCOLORTABLEEXTPROC __glewGetColorTableEXT; +GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERFVEXTPROC __glewGetColorTableParameterfvEXT; +GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERIVEXTPROC __glewGetColorTableParameterivEXT; + +GLEW_FUN_EXPORT PFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC __glewGetPixelTransformParameterfvEXT; +GLEW_FUN_EXPORT PFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC __glewGetPixelTransformParameterivEXT; +GLEW_FUN_EXPORT PFNGLPIXELTRANSFORMPARAMETERFEXTPROC __glewPixelTransformParameterfEXT; +GLEW_FUN_EXPORT PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC __glewPixelTransformParameterfvEXT; +GLEW_FUN_EXPORT PFNGLPIXELTRANSFORMPARAMETERIEXTPROC __glewPixelTransformParameteriEXT; +GLEW_FUN_EXPORT PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC __glewPixelTransformParameterivEXT; + +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFEXTPROC __glewPointParameterfEXT; +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFVEXTPROC __glewPointParameterfvEXT; + +GLEW_FUN_EXPORT PFNGLPOLYGONOFFSETEXTPROC __glewPolygonOffsetEXT; + +GLEW_FUN_EXPORT PFNGLBEGINSCENEEXTPROC __glewBeginSceneEXT; +GLEW_FUN_EXPORT PFNGLENDSCENEEXTPROC __glewEndSceneEXT; + +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3BEXTPROC __glewSecondaryColor3bEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3BVEXTPROC __glewSecondaryColor3bvEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3DEXTPROC __glewSecondaryColor3dEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3DVEXTPROC __glewSecondaryColor3dvEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3FEXTPROC __glewSecondaryColor3fEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3FVEXTPROC __glewSecondaryColor3fvEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3IEXTPROC __glewSecondaryColor3iEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3IVEXTPROC __glewSecondaryColor3ivEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3SEXTPROC __glewSecondaryColor3sEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3SVEXTPROC __glewSecondaryColor3svEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UBEXTPROC __glewSecondaryColor3ubEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UBVEXTPROC __glewSecondaryColor3ubvEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UIEXTPROC __glewSecondaryColor3uiEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UIVEXTPROC __glewSecondaryColor3uivEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3USEXTPROC __glewSecondaryColor3usEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3USVEXTPROC __glewSecondaryColor3usvEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLORPOINTEREXTPROC __glewSecondaryColorPointerEXT; + +GLEW_FUN_EXPORT PFNGLACTIVESTENCILFACEEXTPROC __glewActiveStencilFaceEXT; + +GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE1DEXTPROC __glewTexSubImage1DEXT; +GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE2DEXTPROC __glewTexSubImage2DEXT; +GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE3DEXTPROC __glewTexSubImage3DEXT; + +GLEW_FUN_EXPORT PFNGLTEXIMAGE3DEXTPROC __glewTexImage3DEXT; + +GLEW_FUN_EXPORT PFNGLTEXBUFFEREXTPROC __glewTexBufferEXT; + +GLEW_FUN_EXPORT PFNGLCLEARCOLORIIEXTPROC __glewClearColorIiEXT; +GLEW_FUN_EXPORT PFNGLCLEARCOLORIUIEXTPROC __glewClearColorIuiEXT; +GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERIIVEXTPROC __glewGetTexParameterIivEXT; +GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERIUIVEXTPROC __glewGetTexParameterIuivEXT; +GLEW_FUN_EXPORT PFNGLTEXPARAMETERIIVEXTPROC __glewTexParameterIivEXT; +GLEW_FUN_EXPORT PFNGLTEXPARAMETERIUIVEXTPROC __glewTexParameterIuivEXT; + +GLEW_FUN_EXPORT PFNGLARETEXTURESRESIDENTEXTPROC __glewAreTexturesResidentEXT; +GLEW_FUN_EXPORT PFNGLBINDTEXTUREEXTPROC __glewBindTextureEXT; +GLEW_FUN_EXPORT PFNGLDELETETEXTURESEXTPROC __glewDeleteTexturesEXT; +GLEW_FUN_EXPORT PFNGLGENTEXTURESEXTPROC __glewGenTexturesEXT; +GLEW_FUN_EXPORT PFNGLISTEXTUREEXTPROC __glewIsTextureEXT; +GLEW_FUN_EXPORT PFNGLPRIORITIZETEXTURESEXTPROC __glewPrioritizeTexturesEXT; + +GLEW_FUN_EXPORT PFNGLTEXTURENORMALEXTPROC __glewTextureNormalEXT; + +GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTI64VEXTPROC __glewGetQueryObjecti64vEXT; +GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTUI64VEXTPROC __glewGetQueryObjectui64vEXT; + +GLEW_FUN_EXPORT PFNGLBEGINTRANSFORMFEEDBACKEXTPROC __glewBeginTransformFeedbackEXT; +GLEW_FUN_EXPORT PFNGLBINDBUFFERBASEEXTPROC __glewBindBufferBaseEXT; +GLEW_FUN_EXPORT PFNGLBINDBUFFEROFFSETEXTPROC __glewBindBufferOffsetEXT; +GLEW_FUN_EXPORT PFNGLBINDBUFFERRANGEEXTPROC __glewBindBufferRangeEXT; +GLEW_FUN_EXPORT PFNGLENDTRANSFORMFEEDBACKEXTPROC __glewEndTransformFeedbackEXT; +GLEW_FUN_EXPORT PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC __glewGetTransformFeedbackVaryingEXT; +GLEW_FUN_EXPORT PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC __glewTransformFeedbackVaryingsEXT; + +GLEW_FUN_EXPORT PFNGLARRAYELEMENTEXTPROC __glewArrayElementEXT; +GLEW_FUN_EXPORT PFNGLCOLORPOINTEREXTPROC __glewColorPointerEXT; +GLEW_FUN_EXPORT PFNGLDRAWARRAYSEXTPROC __glewDrawArraysEXT; +GLEW_FUN_EXPORT PFNGLEDGEFLAGPOINTEREXTPROC __glewEdgeFlagPointerEXT; +GLEW_FUN_EXPORT PFNGLGETPOINTERVEXTPROC __glewGetPointervEXT; +GLEW_FUN_EXPORT PFNGLINDEXPOINTEREXTPROC __glewIndexPointerEXT; +GLEW_FUN_EXPORT PFNGLNORMALPOINTEREXTPROC __glewNormalPointerEXT; +GLEW_FUN_EXPORT PFNGLTEXCOORDPOINTEREXTPROC __glewTexCoordPointerEXT; +GLEW_FUN_EXPORT PFNGLVERTEXPOINTEREXTPROC __glewVertexPointerEXT; + +GLEW_FUN_EXPORT PFNGLBEGINVERTEXSHADEREXTPROC __glewBeginVertexShaderEXT; +GLEW_FUN_EXPORT PFNGLBINDLIGHTPARAMETEREXTPROC __glewBindLightParameterEXT; +GLEW_FUN_EXPORT PFNGLBINDMATERIALPARAMETEREXTPROC __glewBindMaterialParameterEXT; +GLEW_FUN_EXPORT PFNGLBINDPARAMETEREXTPROC __glewBindParameterEXT; +GLEW_FUN_EXPORT PFNGLBINDTEXGENPARAMETEREXTPROC __glewBindTexGenParameterEXT; +GLEW_FUN_EXPORT PFNGLBINDTEXTUREUNITPARAMETEREXTPROC __glewBindTextureUnitParameterEXT; +GLEW_FUN_EXPORT PFNGLBINDVERTEXSHADEREXTPROC __glewBindVertexShaderEXT; +GLEW_FUN_EXPORT PFNGLDELETEVERTEXSHADEREXTPROC __glewDeleteVertexShaderEXT; +GLEW_FUN_EXPORT PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC __glewDisableVariantClientStateEXT; +GLEW_FUN_EXPORT PFNGLENABLEVARIANTCLIENTSTATEEXTPROC __glewEnableVariantClientStateEXT; +GLEW_FUN_EXPORT PFNGLENDVERTEXSHADEREXTPROC __glewEndVertexShaderEXT; +GLEW_FUN_EXPORT PFNGLEXTRACTCOMPONENTEXTPROC __glewExtractComponentEXT; +GLEW_FUN_EXPORT PFNGLGENSYMBOLSEXTPROC __glewGenSymbolsEXT; +GLEW_FUN_EXPORT PFNGLGENVERTEXSHADERSEXTPROC __glewGenVertexShadersEXT; +GLEW_FUN_EXPORT PFNGLGETINVARIANTBOOLEANVEXTPROC __glewGetInvariantBooleanvEXT; +GLEW_FUN_EXPORT PFNGLGETINVARIANTFLOATVEXTPROC __glewGetInvariantFloatvEXT; +GLEW_FUN_EXPORT PFNGLGETINVARIANTINTEGERVEXTPROC __glewGetInvariantIntegervEXT; +GLEW_FUN_EXPORT PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC __glewGetLocalConstantBooleanvEXT; +GLEW_FUN_EXPORT PFNGLGETLOCALCONSTANTFLOATVEXTPROC __glewGetLocalConstantFloatvEXT; +GLEW_FUN_EXPORT PFNGLGETLOCALCONSTANTINTEGERVEXTPROC __glewGetLocalConstantIntegervEXT; +GLEW_FUN_EXPORT PFNGLGETVARIANTBOOLEANVEXTPROC __glewGetVariantBooleanvEXT; +GLEW_FUN_EXPORT PFNGLGETVARIANTFLOATVEXTPROC __glewGetVariantFloatvEXT; +GLEW_FUN_EXPORT PFNGLGETVARIANTINTEGERVEXTPROC __glewGetVariantIntegervEXT; +GLEW_FUN_EXPORT PFNGLGETVARIANTPOINTERVEXTPROC __glewGetVariantPointervEXT; +GLEW_FUN_EXPORT PFNGLINSERTCOMPONENTEXTPROC __glewInsertComponentEXT; +GLEW_FUN_EXPORT PFNGLISVARIANTENABLEDEXTPROC __glewIsVariantEnabledEXT; +GLEW_FUN_EXPORT PFNGLSETINVARIANTEXTPROC __glewSetInvariantEXT; +GLEW_FUN_EXPORT PFNGLSETLOCALCONSTANTEXTPROC __glewSetLocalConstantEXT; +GLEW_FUN_EXPORT PFNGLSHADEROP1EXTPROC __glewShaderOp1EXT; +GLEW_FUN_EXPORT PFNGLSHADEROP2EXTPROC __glewShaderOp2EXT; +GLEW_FUN_EXPORT PFNGLSHADEROP3EXTPROC __glewShaderOp3EXT; +GLEW_FUN_EXPORT PFNGLSWIZZLEEXTPROC __glewSwizzleEXT; +GLEW_FUN_EXPORT PFNGLVARIANTPOINTEREXTPROC __glewVariantPointerEXT; +GLEW_FUN_EXPORT PFNGLVARIANTBVEXTPROC __glewVariantbvEXT; +GLEW_FUN_EXPORT PFNGLVARIANTDVEXTPROC __glewVariantdvEXT; +GLEW_FUN_EXPORT PFNGLVARIANTFVEXTPROC __glewVariantfvEXT; +GLEW_FUN_EXPORT PFNGLVARIANTIVEXTPROC __glewVariantivEXT; +GLEW_FUN_EXPORT PFNGLVARIANTSVEXTPROC __glewVariantsvEXT; +GLEW_FUN_EXPORT PFNGLVARIANTUBVEXTPROC __glewVariantubvEXT; +GLEW_FUN_EXPORT PFNGLVARIANTUIVEXTPROC __glewVariantuivEXT; +GLEW_FUN_EXPORT PFNGLVARIANTUSVEXTPROC __glewVariantusvEXT; +GLEW_FUN_EXPORT PFNGLWRITEMASKEXTPROC __glewWriteMaskEXT; + +GLEW_FUN_EXPORT PFNGLVERTEXWEIGHTPOINTEREXTPROC __glewVertexWeightPointerEXT; +GLEW_FUN_EXPORT PFNGLVERTEXWEIGHTFEXTPROC __glewVertexWeightfEXT; +GLEW_FUN_EXPORT PFNGLVERTEXWEIGHTFVEXTPROC __glewVertexWeightfvEXT; + +GLEW_FUN_EXPORT PFNGLFRAMETERMINATORGREMEDYPROC __glewFrameTerminatorGREMEDY; + +GLEW_FUN_EXPORT PFNGLSTRINGMARKERGREMEDYPROC __glewStringMarkerGREMEDY; + +GLEW_FUN_EXPORT PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC __glewGetImageTransformParameterfvHP; +GLEW_FUN_EXPORT PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC __glewGetImageTransformParameterivHP; +GLEW_FUN_EXPORT PFNGLIMAGETRANSFORMPARAMETERFHPPROC __glewImageTransformParameterfHP; +GLEW_FUN_EXPORT PFNGLIMAGETRANSFORMPARAMETERFVHPPROC __glewImageTransformParameterfvHP; +GLEW_FUN_EXPORT PFNGLIMAGETRANSFORMPARAMETERIHPPROC __glewImageTransformParameteriHP; +GLEW_FUN_EXPORT PFNGLIMAGETRANSFORMPARAMETERIVHPPROC __glewImageTransformParameterivHP; + +GLEW_FUN_EXPORT PFNGLMULTIMODEDRAWARRAYSIBMPROC __glewMultiModeDrawArraysIBM; +GLEW_FUN_EXPORT PFNGLMULTIMODEDRAWELEMENTSIBMPROC __glewMultiModeDrawElementsIBM; + +GLEW_FUN_EXPORT PFNGLCOLORPOINTERLISTIBMPROC __glewColorPointerListIBM; +GLEW_FUN_EXPORT PFNGLEDGEFLAGPOINTERLISTIBMPROC __glewEdgeFlagPointerListIBM; +GLEW_FUN_EXPORT PFNGLFOGCOORDPOINTERLISTIBMPROC __glewFogCoordPointerListIBM; +GLEW_FUN_EXPORT PFNGLINDEXPOINTERLISTIBMPROC __glewIndexPointerListIBM; +GLEW_FUN_EXPORT PFNGLNORMALPOINTERLISTIBMPROC __glewNormalPointerListIBM; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLORPOINTERLISTIBMPROC __glewSecondaryColorPointerListIBM; +GLEW_FUN_EXPORT PFNGLTEXCOORDPOINTERLISTIBMPROC __glewTexCoordPointerListIBM; +GLEW_FUN_EXPORT PFNGLVERTEXPOINTERLISTIBMPROC __glewVertexPointerListIBM; + +GLEW_FUN_EXPORT PFNGLCOLORPOINTERVINTELPROC __glewColorPointervINTEL; +GLEW_FUN_EXPORT PFNGLNORMALPOINTERVINTELPROC __glewNormalPointervINTEL; +GLEW_FUN_EXPORT PFNGLTEXCOORDPOINTERVINTELPROC __glewTexCoordPointervINTEL; +GLEW_FUN_EXPORT PFNGLVERTEXPOINTERVINTELPROC __glewVertexPointervINTEL; + +GLEW_FUN_EXPORT PFNGLTEXSCISSORFUNCINTELPROC __glewTexScissorFuncINTEL; +GLEW_FUN_EXPORT PFNGLTEXSCISSORINTELPROC __glewTexScissorINTEL; + +GLEW_FUN_EXPORT PFNGLBUFFERREGIONENABLEDEXTPROC __glewBufferRegionEnabledEXT; +GLEW_FUN_EXPORT PFNGLDELETEBUFFERREGIONEXTPROC __glewDeleteBufferRegionEXT; +GLEW_FUN_EXPORT PFNGLDRAWBUFFERREGIONEXTPROC __glewDrawBufferRegionEXT; +GLEW_FUN_EXPORT PFNGLNEWBUFFERREGIONEXTPROC __glewNewBufferRegionEXT; +GLEW_FUN_EXPORT PFNGLREADBUFFERREGIONEXTPROC __glewReadBufferRegionEXT; + +GLEW_FUN_EXPORT PFNGLRESIZEBUFFERSMESAPROC __glewResizeBuffersMESA; + +GLEW_FUN_EXPORT PFNGLWINDOWPOS2DMESAPROC __glewWindowPos2dMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2DVMESAPROC __glewWindowPos2dvMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2FMESAPROC __glewWindowPos2fMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2FVMESAPROC __glewWindowPos2fvMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2IMESAPROC __glewWindowPos2iMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2IVMESAPROC __glewWindowPos2ivMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2SMESAPROC __glewWindowPos2sMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2SVMESAPROC __glewWindowPos2svMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3DMESAPROC __glewWindowPos3dMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3DVMESAPROC __glewWindowPos3dvMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3FMESAPROC __glewWindowPos3fMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3FVMESAPROC __glewWindowPos3fvMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3IMESAPROC __glewWindowPos3iMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3IVMESAPROC __glewWindowPos3ivMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3SMESAPROC __glewWindowPos3sMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3SVMESAPROC __glewWindowPos3svMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS4DMESAPROC __glewWindowPos4dMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS4DVMESAPROC __glewWindowPos4dvMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS4FMESAPROC __glewWindowPos4fMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS4FVMESAPROC __glewWindowPos4fvMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS4IMESAPROC __glewWindowPos4iMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS4IVMESAPROC __glewWindowPos4ivMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS4SMESAPROC __glewWindowPos4sMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS4SVMESAPROC __glewWindowPos4svMESA; + +GLEW_FUN_EXPORT PFNGLBEGINCONDITIONALRENDERNVPROC __glewBeginConditionalRenderNV; +GLEW_FUN_EXPORT PFNGLENDCONDITIONALRENDERNVPROC __glewEndConditionalRenderNV; + +GLEW_FUN_EXPORT PFNGLCLEARDEPTHDNVPROC __glewClearDepthdNV; +GLEW_FUN_EXPORT PFNGLDEPTHBOUNDSDNVPROC __glewDepthBoundsdNV; +GLEW_FUN_EXPORT PFNGLDEPTHRANGEDNVPROC __glewDepthRangedNV; + +GLEW_FUN_EXPORT PFNGLEVALMAPSNVPROC __glewEvalMapsNV; +GLEW_FUN_EXPORT PFNGLGETMAPATTRIBPARAMETERFVNVPROC __glewGetMapAttribParameterfvNV; +GLEW_FUN_EXPORT PFNGLGETMAPATTRIBPARAMETERIVNVPROC __glewGetMapAttribParameterivNV; +GLEW_FUN_EXPORT PFNGLGETMAPCONTROLPOINTSNVPROC __glewGetMapControlPointsNV; +GLEW_FUN_EXPORT PFNGLGETMAPPARAMETERFVNVPROC __glewGetMapParameterfvNV; +GLEW_FUN_EXPORT PFNGLGETMAPPARAMETERIVNVPROC __glewGetMapParameterivNV; +GLEW_FUN_EXPORT PFNGLMAPCONTROLPOINTSNVPROC __glewMapControlPointsNV; +GLEW_FUN_EXPORT PFNGLMAPPARAMETERFVNVPROC __glewMapParameterfvNV; +GLEW_FUN_EXPORT PFNGLMAPPARAMETERIVNVPROC __glewMapParameterivNV; + +GLEW_FUN_EXPORT PFNGLGETMULTISAMPLEFVNVPROC __glewGetMultisamplefvNV; +GLEW_FUN_EXPORT PFNGLSAMPLEMASKINDEXEDNVPROC __glewSampleMaskIndexedNV; +GLEW_FUN_EXPORT PFNGLTEXRENDERBUFFERNVPROC __glewTexRenderbufferNV; + +GLEW_FUN_EXPORT PFNGLDELETEFENCESNVPROC __glewDeleteFencesNV; +GLEW_FUN_EXPORT PFNGLFINISHFENCENVPROC __glewFinishFenceNV; +GLEW_FUN_EXPORT PFNGLGENFENCESNVPROC __glewGenFencesNV; +GLEW_FUN_EXPORT PFNGLGETFENCEIVNVPROC __glewGetFenceivNV; +GLEW_FUN_EXPORT PFNGLISFENCENVPROC __glewIsFenceNV; +GLEW_FUN_EXPORT PFNGLSETFENCENVPROC __glewSetFenceNV; +GLEW_FUN_EXPORT PFNGLTESTFENCENVPROC __glewTestFenceNV; + +GLEW_FUN_EXPORT PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC __glewGetProgramNamedParameterdvNV; +GLEW_FUN_EXPORT PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC __glewGetProgramNamedParameterfvNV; +GLEW_FUN_EXPORT PFNGLPROGRAMNAMEDPARAMETER4DNVPROC __glewProgramNamedParameter4dNV; +GLEW_FUN_EXPORT PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC __glewProgramNamedParameter4dvNV; +GLEW_FUN_EXPORT PFNGLPROGRAMNAMEDPARAMETER4FNVPROC __glewProgramNamedParameter4fNV; +GLEW_FUN_EXPORT PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC __glewProgramNamedParameter4fvNV; + +GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC __glewRenderbufferStorageMultisampleCoverageNV; + +GLEW_FUN_EXPORT PFNGLPROGRAMVERTEXLIMITNVPROC __glewProgramVertexLimitNV; + +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERI4INVPROC __glewProgramEnvParameterI4iNV; +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERI4IVNVPROC __glewProgramEnvParameterI4ivNV; +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERI4UINVPROC __glewProgramEnvParameterI4uiNV; +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERI4UIVNVPROC __glewProgramEnvParameterI4uivNV; +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERSI4IVNVPROC __glewProgramEnvParametersI4ivNV; +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC __glewProgramEnvParametersI4uivNV; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERI4INVPROC __glewProgramLocalParameterI4iNV; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC __glewProgramLocalParameterI4ivNV; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERI4UINVPROC __glewProgramLocalParameterI4uiNV; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC __glewProgramLocalParameterI4uivNV; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC __glewProgramLocalParametersI4ivNV; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC __glewProgramLocalParametersI4uivNV; + +GLEW_FUN_EXPORT PFNGLCOLOR3HNVPROC __glewColor3hNV; +GLEW_FUN_EXPORT PFNGLCOLOR3HVNVPROC __glewColor3hvNV; +GLEW_FUN_EXPORT PFNGLCOLOR4HNVPROC __glewColor4hNV; +GLEW_FUN_EXPORT PFNGLCOLOR4HVNVPROC __glewColor4hvNV; +GLEW_FUN_EXPORT PFNGLFOGCOORDHNVPROC __glewFogCoordhNV; +GLEW_FUN_EXPORT PFNGLFOGCOORDHVNVPROC __glewFogCoordhvNV; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1HNVPROC __glewMultiTexCoord1hNV; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1HVNVPROC __glewMultiTexCoord1hvNV; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2HNVPROC __glewMultiTexCoord2hNV; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2HVNVPROC __glewMultiTexCoord2hvNV; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3HNVPROC __glewMultiTexCoord3hNV; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3HVNVPROC __glewMultiTexCoord3hvNV; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4HNVPROC __glewMultiTexCoord4hNV; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4HVNVPROC __glewMultiTexCoord4hvNV; +GLEW_FUN_EXPORT PFNGLNORMAL3HNVPROC __glewNormal3hNV; +GLEW_FUN_EXPORT PFNGLNORMAL3HVNVPROC __glewNormal3hvNV; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3HNVPROC __glewSecondaryColor3hNV; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3HVNVPROC __glewSecondaryColor3hvNV; +GLEW_FUN_EXPORT PFNGLTEXCOORD1HNVPROC __glewTexCoord1hNV; +GLEW_FUN_EXPORT PFNGLTEXCOORD1HVNVPROC __glewTexCoord1hvNV; +GLEW_FUN_EXPORT PFNGLTEXCOORD2HNVPROC __glewTexCoord2hNV; +GLEW_FUN_EXPORT PFNGLTEXCOORD2HVNVPROC __glewTexCoord2hvNV; +GLEW_FUN_EXPORT PFNGLTEXCOORD3HNVPROC __glewTexCoord3hNV; +GLEW_FUN_EXPORT PFNGLTEXCOORD3HVNVPROC __glewTexCoord3hvNV; +GLEW_FUN_EXPORT PFNGLTEXCOORD4HNVPROC __glewTexCoord4hNV; +GLEW_FUN_EXPORT PFNGLTEXCOORD4HVNVPROC __glewTexCoord4hvNV; +GLEW_FUN_EXPORT PFNGLVERTEX2HNVPROC __glewVertex2hNV; +GLEW_FUN_EXPORT PFNGLVERTEX2HVNVPROC __glewVertex2hvNV; +GLEW_FUN_EXPORT PFNGLVERTEX3HNVPROC __glewVertex3hNV; +GLEW_FUN_EXPORT PFNGLVERTEX3HVNVPROC __glewVertex3hvNV; +GLEW_FUN_EXPORT PFNGLVERTEX4HNVPROC __glewVertex4hNV; +GLEW_FUN_EXPORT PFNGLVERTEX4HVNVPROC __glewVertex4hvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1HNVPROC __glewVertexAttrib1hNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1HVNVPROC __glewVertexAttrib1hvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2HNVPROC __glewVertexAttrib2hNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2HVNVPROC __glewVertexAttrib2hvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3HNVPROC __glewVertexAttrib3hNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3HVNVPROC __glewVertexAttrib3hvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4HNVPROC __glewVertexAttrib4hNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4HVNVPROC __glewVertexAttrib4hvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS1HVNVPROC __glewVertexAttribs1hvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS2HVNVPROC __glewVertexAttribs2hvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS3HVNVPROC __glewVertexAttribs3hvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS4HVNVPROC __glewVertexAttribs4hvNV; +GLEW_FUN_EXPORT PFNGLVERTEXWEIGHTHNVPROC __glewVertexWeighthNV; +GLEW_FUN_EXPORT PFNGLVERTEXWEIGHTHVNVPROC __glewVertexWeighthvNV; + +GLEW_FUN_EXPORT PFNGLBEGINOCCLUSIONQUERYNVPROC __glewBeginOcclusionQueryNV; +GLEW_FUN_EXPORT PFNGLDELETEOCCLUSIONQUERIESNVPROC __glewDeleteOcclusionQueriesNV; +GLEW_FUN_EXPORT PFNGLENDOCCLUSIONQUERYNVPROC __glewEndOcclusionQueryNV; +GLEW_FUN_EXPORT PFNGLGENOCCLUSIONQUERIESNVPROC __glewGenOcclusionQueriesNV; +GLEW_FUN_EXPORT PFNGLGETOCCLUSIONQUERYIVNVPROC __glewGetOcclusionQueryivNV; +GLEW_FUN_EXPORT PFNGLGETOCCLUSIONQUERYUIVNVPROC __glewGetOcclusionQueryuivNV; +GLEW_FUN_EXPORT PFNGLISOCCLUSIONQUERYNVPROC __glewIsOcclusionQueryNV; + +GLEW_FUN_EXPORT PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC __glewProgramBufferParametersIivNV; +GLEW_FUN_EXPORT PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC __glewProgramBufferParametersIuivNV; +GLEW_FUN_EXPORT PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC __glewProgramBufferParametersfvNV; + +GLEW_FUN_EXPORT PFNGLFLUSHPIXELDATARANGENVPROC __glewFlushPixelDataRangeNV; +GLEW_FUN_EXPORT PFNGLPIXELDATARANGENVPROC __glewPixelDataRangeNV; + +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERINVPROC __glewPointParameteriNV; +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERIVNVPROC __glewPointParameterivNV; + +GLEW_FUN_EXPORT PFNGLGETVIDEOI64VNVPROC __glewGetVideoi64vNV; +GLEW_FUN_EXPORT PFNGLGETVIDEOIVNVPROC __glewGetVideoivNV; +GLEW_FUN_EXPORT PFNGLGETVIDEOUI64VNVPROC __glewGetVideoui64vNV; +GLEW_FUN_EXPORT PFNGLGETVIDEOUIVNVPROC __glewGetVideouivNV; +GLEW_FUN_EXPORT PFNGLPRESENTFRAMEDUALFILLNVPROC __glewPresentFrameDualFillNV; +GLEW_FUN_EXPORT PFNGLPRESENTFRAMEKEYEDNVPROC __glewPresentFrameKeyedNV; +GLEW_FUN_EXPORT PFNGLVIDEOPARAMETERIVNVPROC __glewVideoParameterivNV; + +GLEW_FUN_EXPORT PFNGLPRIMITIVERESTARTINDEXNVPROC __glewPrimitiveRestartIndexNV; +GLEW_FUN_EXPORT PFNGLPRIMITIVERESTARTNVPROC __glewPrimitiveRestartNV; + +GLEW_FUN_EXPORT PFNGLCOMBINERINPUTNVPROC __glewCombinerInputNV; +GLEW_FUN_EXPORT PFNGLCOMBINEROUTPUTNVPROC __glewCombinerOutputNV; +GLEW_FUN_EXPORT PFNGLCOMBINERPARAMETERFNVPROC __glewCombinerParameterfNV; +GLEW_FUN_EXPORT PFNGLCOMBINERPARAMETERFVNVPROC __glewCombinerParameterfvNV; +GLEW_FUN_EXPORT PFNGLCOMBINERPARAMETERINVPROC __glewCombinerParameteriNV; +GLEW_FUN_EXPORT PFNGLCOMBINERPARAMETERIVNVPROC __glewCombinerParameterivNV; +GLEW_FUN_EXPORT PFNGLFINALCOMBINERINPUTNVPROC __glewFinalCombinerInputNV; +GLEW_FUN_EXPORT PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC __glewGetCombinerInputParameterfvNV; +GLEW_FUN_EXPORT PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC __glewGetCombinerInputParameterivNV; +GLEW_FUN_EXPORT PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC __glewGetCombinerOutputParameterfvNV; +GLEW_FUN_EXPORT PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC __glewGetCombinerOutputParameterivNV; +GLEW_FUN_EXPORT PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC __glewGetFinalCombinerInputParameterfvNV; +GLEW_FUN_EXPORT PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC __glewGetFinalCombinerInputParameterivNV; + +GLEW_FUN_EXPORT PFNGLCOMBINERSTAGEPARAMETERFVNVPROC __glewCombinerStageParameterfvNV; +GLEW_FUN_EXPORT PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC __glewGetCombinerStageParameterfvNV; + +GLEW_FUN_EXPORT PFNGLACTIVEVARYINGNVPROC __glewActiveVaryingNV; +GLEW_FUN_EXPORT PFNGLBEGINTRANSFORMFEEDBACKNVPROC __glewBeginTransformFeedbackNV; +GLEW_FUN_EXPORT PFNGLBINDBUFFERBASENVPROC __glewBindBufferBaseNV; +GLEW_FUN_EXPORT PFNGLBINDBUFFEROFFSETNVPROC __glewBindBufferOffsetNV; +GLEW_FUN_EXPORT PFNGLBINDBUFFERRANGENVPROC __glewBindBufferRangeNV; +GLEW_FUN_EXPORT PFNGLENDTRANSFORMFEEDBACKNVPROC __glewEndTransformFeedbackNV; +GLEW_FUN_EXPORT PFNGLGETACTIVEVARYINGNVPROC __glewGetActiveVaryingNV; +GLEW_FUN_EXPORT PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC __glewGetTransformFeedbackVaryingNV; +GLEW_FUN_EXPORT PFNGLGETVARYINGLOCATIONNVPROC __glewGetVaryingLocationNV; +GLEW_FUN_EXPORT PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC __glewTransformFeedbackAttribsNV; +GLEW_FUN_EXPORT PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC __glewTransformFeedbackVaryingsNV; + +GLEW_FUN_EXPORT PFNGLFLUSHVERTEXARRAYRANGENVPROC __glewFlushVertexArrayRangeNV; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYRANGENVPROC __glewVertexArrayRangeNV; + +GLEW_FUN_EXPORT PFNGLAREPROGRAMSRESIDENTNVPROC __glewAreProgramsResidentNV; +GLEW_FUN_EXPORT PFNGLBINDPROGRAMNVPROC __glewBindProgramNV; +GLEW_FUN_EXPORT PFNGLDELETEPROGRAMSNVPROC __glewDeleteProgramsNV; +GLEW_FUN_EXPORT PFNGLEXECUTEPROGRAMNVPROC __glewExecuteProgramNV; +GLEW_FUN_EXPORT PFNGLGENPROGRAMSNVPROC __glewGenProgramsNV; +GLEW_FUN_EXPORT PFNGLGETPROGRAMPARAMETERDVNVPROC __glewGetProgramParameterdvNV; +GLEW_FUN_EXPORT PFNGLGETPROGRAMPARAMETERFVNVPROC __glewGetProgramParameterfvNV; +GLEW_FUN_EXPORT PFNGLGETPROGRAMSTRINGNVPROC __glewGetProgramStringNV; +GLEW_FUN_EXPORT PFNGLGETPROGRAMIVNVPROC __glewGetProgramivNV; +GLEW_FUN_EXPORT PFNGLGETTRACKMATRIXIVNVPROC __glewGetTrackMatrixivNV; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBPOINTERVNVPROC __glewGetVertexAttribPointervNV; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBDVNVPROC __glewGetVertexAttribdvNV; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBFVNVPROC __glewGetVertexAttribfvNV; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIVNVPROC __glewGetVertexAttribivNV; +GLEW_FUN_EXPORT PFNGLISPROGRAMNVPROC __glewIsProgramNV; +GLEW_FUN_EXPORT PFNGLLOADPROGRAMNVPROC __glewLoadProgramNV; +GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETER4DNVPROC __glewProgramParameter4dNV; +GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETER4DVNVPROC __glewProgramParameter4dvNV; +GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETER4FNVPROC __glewProgramParameter4fNV; +GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETER4FVNVPROC __glewProgramParameter4fvNV; +GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETERS4DVNVPROC __glewProgramParameters4dvNV; +GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETERS4FVNVPROC __glewProgramParameters4fvNV; +GLEW_FUN_EXPORT PFNGLREQUESTRESIDENTPROGRAMSNVPROC __glewRequestResidentProgramsNV; +GLEW_FUN_EXPORT PFNGLTRACKMATRIXNVPROC __glewTrackMatrixNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DNVPROC __glewVertexAttrib1dNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DVNVPROC __glewVertexAttrib1dvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FNVPROC __glewVertexAttrib1fNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FVNVPROC __glewVertexAttrib1fvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SNVPROC __glewVertexAttrib1sNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SVNVPROC __glewVertexAttrib1svNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DNVPROC __glewVertexAttrib2dNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DVNVPROC __glewVertexAttrib2dvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FNVPROC __glewVertexAttrib2fNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FVNVPROC __glewVertexAttrib2fvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SNVPROC __glewVertexAttrib2sNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SVNVPROC __glewVertexAttrib2svNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DNVPROC __glewVertexAttrib3dNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DVNVPROC __glewVertexAttrib3dvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FNVPROC __glewVertexAttrib3fNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FVNVPROC __glewVertexAttrib3fvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SNVPROC __glewVertexAttrib3sNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SVNVPROC __glewVertexAttrib3svNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DNVPROC __glewVertexAttrib4dNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DVNVPROC __glewVertexAttrib4dvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FNVPROC __glewVertexAttrib4fNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FVNVPROC __glewVertexAttrib4fvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SNVPROC __glewVertexAttrib4sNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SVNVPROC __glewVertexAttrib4svNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UBNVPROC __glewVertexAttrib4ubNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UBVNVPROC __glewVertexAttrib4ubvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBPOINTERNVPROC __glewVertexAttribPointerNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS1DVNVPROC __glewVertexAttribs1dvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS1FVNVPROC __glewVertexAttribs1fvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS1SVNVPROC __glewVertexAttribs1svNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS2DVNVPROC __glewVertexAttribs2dvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS2FVNVPROC __glewVertexAttribs2fvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS2SVNVPROC __glewVertexAttribs2svNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS3DVNVPROC __glewVertexAttribs3dvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS3FVNVPROC __glewVertexAttribs3fvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS3SVNVPROC __glewVertexAttribs3svNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS4DVNVPROC __glewVertexAttribs4dvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS4FVNVPROC __glewVertexAttribs4fvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS4SVNVPROC __glewVertexAttribs4svNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS4UBVNVPROC __glewVertexAttribs4ubvNV; + +GLEW_FUN_EXPORT PFNGLCLEARDEPTHFOESPROC __glewClearDepthfOES; +GLEW_FUN_EXPORT PFNGLCLIPPLANEFOESPROC __glewClipPlanefOES; +GLEW_FUN_EXPORT PFNGLDEPTHRANGEFOESPROC __glewDepthRangefOES; +GLEW_FUN_EXPORT PFNGLFRUSTUMFOESPROC __glewFrustumfOES; +GLEW_FUN_EXPORT PFNGLGETCLIPPLANEFOESPROC __glewGetClipPlanefOES; +GLEW_FUN_EXPORT PFNGLORTHOFOESPROC __glewOrthofOES; + +GLEW_FUN_EXPORT PFNGLDETAILTEXFUNCSGISPROC __glewDetailTexFuncSGIS; +GLEW_FUN_EXPORT PFNGLGETDETAILTEXFUNCSGISPROC __glewGetDetailTexFuncSGIS; + +GLEW_FUN_EXPORT PFNGLFOGFUNCSGISPROC __glewFogFuncSGIS; +GLEW_FUN_EXPORT PFNGLGETFOGFUNCSGISPROC __glewGetFogFuncSGIS; + +GLEW_FUN_EXPORT PFNGLSAMPLEMASKSGISPROC __glewSampleMaskSGIS; +GLEW_FUN_EXPORT PFNGLSAMPLEPATTERNSGISPROC __glewSamplePatternSGIS; + +GLEW_FUN_EXPORT PFNGLGETSHARPENTEXFUNCSGISPROC __glewGetSharpenTexFuncSGIS; +GLEW_FUN_EXPORT PFNGLSHARPENTEXFUNCSGISPROC __glewSharpenTexFuncSGIS; + +GLEW_FUN_EXPORT PFNGLTEXIMAGE4DSGISPROC __glewTexImage4DSGIS; +GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE4DSGISPROC __glewTexSubImage4DSGIS; + +GLEW_FUN_EXPORT PFNGLGETTEXFILTERFUNCSGISPROC __glewGetTexFilterFuncSGIS; +GLEW_FUN_EXPORT PFNGLTEXFILTERFUNCSGISPROC __glewTexFilterFuncSGIS; + +GLEW_FUN_EXPORT PFNGLASYNCMARKERSGIXPROC __glewAsyncMarkerSGIX; +GLEW_FUN_EXPORT PFNGLDELETEASYNCMARKERSSGIXPROC __glewDeleteAsyncMarkersSGIX; +GLEW_FUN_EXPORT PFNGLFINISHASYNCSGIXPROC __glewFinishAsyncSGIX; +GLEW_FUN_EXPORT PFNGLGENASYNCMARKERSSGIXPROC __glewGenAsyncMarkersSGIX; +GLEW_FUN_EXPORT PFNGLISASYNCMARKERSGIXPROC __glewIsAsyncMarkerSGIX; +GLEW_FUN_EXPORT PFNGLPOLLASYNCSGIXPROC __glewPollAsyncSGIX; + +GLEW_FUN_EXPORT PFNGLFLUSHRASTERSGIXPROC __glewFlushRasterSGIX; + +GLEW_FUN_EXPORT PFNGLTEXTUREFOGSGIXPROC __glewTextureFogSGIX; + +GLEW_FUN_EXPORT PFNGLFRAGMENTCOLORMATERIALSGIXPROC __glewFragmentColorMaterialSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELFSGIXPROC __glewFragmentLightModelfSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELFVSGIXPROC __glewFragmentLightModelfvSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELISGIXPROC __glewFragmentLightModeliSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELIVSGIXPROC __glewFragmentLightModelivSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTFSGIXPROC __glewFragmentLightfSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTFVSGIXPROC __glewFragmentLightfvSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTISGIXPROC __glewFragmentLightiSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTIVSGIXPROC __glewFragmentLightivSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALFSGIXPROC __glewFragmentMaterialfSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALFVSGIXPROC __glewFragmentMaterialfvSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALISGIXPROC __glewFragmentMaterialiSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALIVSGIXPROC __glewFragmentMaterialivSGIX; +GLEW_FUN_EXPORT PFNGLGETFRAGMENTLIGHTFVSGIXPROC __glewGetFragmentLightfvSGIX; +GLEW_FUN_EXPORT PFNGLGETFRAGMENTLIGHTIVSGIXPROC __glewGetFragmentLightivSGIX; +GLEW_FUN_EXPORT PFNGLGETFRAGMENTMATERIALFVSGIXPROC __glewGetFragmentMaterialfvSGIX; +GLEW_FUN_EXPORT PFNGLGETFRAGMENTMATERIALIVSGIXPROC __glewGetFragmentMaterialivSGIX; + +GLEW_FUN_EXPORT PFNGLFRAMEZOOMSGIXPROC __glewFrameZoomSGIX; + +GLEW_FUN_EXPORT PFNGLPIXELTEXGENSGIXPROC __glewPixelTexGenSGIX; + +GLEW_FUN_EXPORT PFNGLREFERENCEPLANESGIXPROC __glewReferencePlaneSGIX; + +GLEW_FUN_EXPORT PFNGLSPRITEPARAMETERFSGIXPROC __glewSpriteParameterfSGIX; +GLEW_FUN_EXPORT PFNGLSPRITEPARAMETERFVSGIXPROC __glewSpriteParameterfvSGIX; +GLEW_FUN_EXPORT PFNGLSPRITEPARAMETERISGIXPROC __glewSpriteParameteriSGIX; +GLEW_FUN_EXPORT PFNGLSPRITEPARAMETERIVSGIXPROC __glewSpriteParameterivSGIX; + +GLEW_FUN_EXPORT PFNGLTAGSAMPLEBUFFERSGIXPROC __glewTagSampleBufferSGIX; + +GLEW_FUN_EXPORT PFNGLCOLORTABLEPARAMETERFVSGIPROC __glewColorTableParameterfvSGI; +GLEW_FUN_EXPORT PFNGLCOLORTABLEPARAMETERIVSGIPROC __glewColorTableParameterivSGI; +GLEW_FUN_EXPORT PFNGLCOLORTABLESGIPROC __glewColorTableSGI; +GLEW_FUN_EXPORT PFNGLCOPYCOLORTABLESGIPROC __glewCopyColorTableSGI; +GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERFVSGIPROC __glewGetColorTableParameterfvSGI; +GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERIVSGIPROC __glewGetColorTableParameterivSGI; +GLEW_FUN_EXPORT PFNGLGETCOLORTABLESGIPROC __glewGetColorTableSGI; + +GLEW_FUN_EXPORT PFNGLFINISHTEXTURESUNXPROC __glewFinishTextureSUNX; + +GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORBSUNPROC __glewGlobalAlphaFactorbSUN; +GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORDSUNPROC __glewGlobalAlphaFactordSUN; +GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORFSUNPROC __glewGlobalAlphaFactorfSUN; +GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORISUNPROC __glewGlobalAlphaFactoriSUN; +GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORSSUNPROC __glewGlobalAlphaFactorsSUN; +GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORUBSUNPROC __glewGlobalAlphaFactorubSUN; +GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORUISUNPROC __glewGlobalAlphaFactoruiSUN; +GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORUSSUNPROC __glewGlobalAlphaFactorusSUN; + +GLEW_FUN_EXPORT PFNGLREADVIDEOPIXELSSUNPROC __glewReadVideoPixelsSUN; + +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEPOINTERSUNPROC __glewReplacementCodePointerSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUBSUNPROC __glewReplacementCodeubSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUBVSUNPROC __glewReplacementCodeubvSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUISUNPROC __glewReplacementCodeuiSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUIVSUNPROC __glewReplacementCodeuivSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUSSUNPROC __glewReplacementCodeusSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUSVSUNPROC __glewReplacementCodeusvSUN; + +GLEW_FUN_EXPORT PFNGLCOLOR3FVERTEX3FSUNPROC __glewColor3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLCOLOR3FVERTEX3FVSUNPROC __glewColor3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC __glewColor4fNormal3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewColor4fNormal3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLCOLOR4UBVERTEX2FSUNPROC __glewColor4ubVertex2fSUN; +GLEW_FUN_EXPORT PFNGLCOLOR4UBVERTEX2FVSUNPROC __glewColor4ubVertex2fvSUN; +GLEW_FUN_EXPORT PFNGLCOLOR4UBVERTEX3FSUNPROC __glewColor4ubVertex3fSUN; +GLEW_FUN_EXPORT PFNGLCOLOR4UBVERTEX3FVSUNPROC __glewColor4ubVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLNORMAL3FVERTEX3FSUNPROC __glewNormal3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLNORMAL3FVERTEX3FVSUNPROC __glewNormal3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC __glewReplacementCodeuiColor3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC __glewReplacementCodeuiColor3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiColor4fNormal3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiColor4fNormal3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC __glewReplacementCodeuiColor4ubVertex3fSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC __glewReplacementCodeuiColor4ubVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiNormal3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiNormal3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiTexCoord2fNormal3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC __glewReplacementCodeuiTexCoord2fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC __glewReplacementCodeuiTexCoord2fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC __glewReplacementCodeuiVertex3fSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC __glewReplacementCodeuiVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC __glewTexCoord2fColor3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC __glewTexCoord2fColor3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC __glewTexCoord2fColor4fNormal3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewTexCoord2fColor4fNormal3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC __glewTexCoord2fColor4ubVertex3fSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC __glewTexCoord2fColor4ubVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC __glewTexCoord2fNormal3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC __glewTexCoord2fNormal3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FVERTEX3FSUNPROC __glewTexCoord2fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FVERTEX3FVSUNPROC __glewTexCoord2fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC __glewTexCoord4fColor4fNormal3fVertex4fSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC __glewTexCoord4fColor4fNormal3fVertex4fvSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD4FVERTEX4FSUNPROC __glewTexCoord4fVertex4fSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD4FVERTEX4FVSUNPROC __glewTexCoord4fVertex4fvSUN; + +GLEW_FUN_EXPORT PFNGLADDSWAPHINTRECTWINPROC __glewAddSwapHintRectWIN; + +#if defined(GLEW_MX) && !defined(_WIN32) +struct GLEWContextStruct +{ +#endif /* GLEW_MX */ + +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_1; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_2; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_3; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_4; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_5; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_2_0; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_2_1; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_3_0; +GLEW_VAR_EXPORT GLboolean __GLEW_3DFX_multisample; +GLEW_VAR_EXPORT GLboolean __GLEW_3DFX_tbuffer; +GLEW_VAR_EXPORT GLboolean __GLEW_3DFX_texture_compression_FXT1; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_client_storage; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_element_array; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_fence; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_float_pixels; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_flush_buffer_range; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_pixel_buffer; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_specular_vector; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_texture_range; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_transform_hint; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_vertex_array_object; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_vertex_array_range; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_ycbcr_422; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_color_buffer_float; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_depth_buffer_float; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_depth_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_draw_buffers; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_draw_instanced; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_fragment_program; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_fragment_program_shadow; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_fragment_shader; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_framebuffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_framebuffer_sRGB; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_geometry_shader4; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_half_float_pixel; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_half_float_vertex; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_imaging; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_instanced_arrays; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_map_buffer_range; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_matrix_palette; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_multisample; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_multitexture; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_occlusion_query; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_pixel_buffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_point_parameters; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_point_sprite; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_objects; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shading_language_100; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shadow; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shadow_ambient; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_border_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_buffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_compression; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_compression_rgtc; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_cube_map; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_env_add; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_env_combine; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_env_crossbar; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_env_dot3; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_float; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_mirrored_repeat; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_non_power_of_two; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_rectangle; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_rg; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_transpose_matrix; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_array_object; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_blend; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_buffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_program; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_shader; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_window_pos; +GLEW_VAR_EXPORT GLboolean __GLEW_ATIX_point_sprites; +GLEW_VAR_EXPORT GLboolean __GLEW_ATIX_texture_env_combine3; +GLEW_VAR_EXPORT GLboolean __GLEW_ATIX_texture_env_route; +GLEW_VAR_EXPORT GLboolean __GLEW_ATIX_vertex_shader_output_point_size; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_draw_buffers; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_element_array; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_envmap_bumpmap; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_fragment_shader; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_map_object_buffer; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_pn_triangles; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_separate_stencil; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_shader_texture_lod; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_text_fragment_shader; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_texture_compression_3dc; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_texture_env_combine3; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_texture_float; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_texture_mirror_once; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_vertex_array_object; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_vertex_attrib_array_object; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_vertex_streams; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_422_pixels; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_Cg_shader; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_abgr; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_bgra; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_bindable_uniform; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_color; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_equation_separate; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_func_separate; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_logic_op; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_minmax; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_subtract; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_clip_volume_hint; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_cmyka; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_color_subtable; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_compiled_vertex_array; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_convolution; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_coordinate_frame; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_copy_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_cull_vertex; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_depth_bounds_test; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_direct_state_access; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_draw_buffers2; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_draw_instanced; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_draw_range_elements; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_fog_coord; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_fragment_lighting; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_framebuffer_blit; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_framebuffer_multisample; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_framebuffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_framebuffer_sRGB; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_geometry_shader4; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_gpu_program_parameters; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_gpu_shader4; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_histogram; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_index_array_formats; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_index_func; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_index_material; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_index_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_light_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_misc_attribute; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_multi_draw_arrays; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_multisample; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_packed_depth_stencil; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_packed_float; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_packed_pixels; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_paletted_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_pixel_buffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_pixel_transform; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_pixel_transform_color_table; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_point_parameters; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_polygon_offset; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_rescale_normal; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_scene_marker; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_secondary_color; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_separate_specular_color; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shadow_funcs; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shared_texture_palette; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_stencil_clear_tag; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_stencil_two_side; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_stencil_wrap; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_subtexture; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture3D; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_array; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_buffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_compression_dxt1; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_compression_latc; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_compression_rgtc; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_compression_s3tc; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_cube_map; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_edge_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_env; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_env_add; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_env_combine; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_env_dot3; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_filter_anisotropic; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_integer; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_lod_bias; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_mirror_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_object; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_perturb_normal; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_rectangle; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_sRGB; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_shared_exponent; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_swizzle; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_timer_query; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_transform_feedback; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_vertex_array; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_vertex_array_bgra; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_vertex_shader; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_vertex_weighting; +GLEW_VAR_EXPORT GLboolean __GLEW_GREMEDY_frame_terminator; +GLEW_VAR_EXPORT GLboolean __GLEW_GREMEDY_string_marker; +GLEW_VAR_EXPORT GLboolean __GLEW_HP_convolution_border_modes; +GLEW_VAR_EXPORT GLboolean __GLEW_HP_image_transform; +GLEW_VAR_EXPORT GLboolean __GLEW_HP_occlusion_test; +GLEW_VAR_EXPORT GLboolean __GLEW_HP_texture_lighting; +GLEW_VAR_EXPORT GLboolean __GLEW_IBM_cull_vertex; +GLEW_VAR_EXPORT GLboolean __GLEW_IBM_multimode_draw_arrays; +GLEW_VAR_EXPORT GLboolean __GLEW_IBM_rasterpos_clip; +GLEW_VAR_EXPORT GLboolean __GLEW_IBM_static_data; +GLEW_VAR_EXPORT GLboolean __GLEW_IBM_texture_mirrored_repeat; +GLEW_VAR_EXPORT GLboolean __GLEW_IBM_vertex_array_lists; +GLEW_VAR_EXPORT GLboolean __GLEW_INGR_color_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_INGR_interlace_read; +GLEW_VAR_EXPORT GLboolean __GLEW_INTEL_parallel_arrays; +GLEW_VAR_EXPORT GLboolean __GLEW_INTEL_texture_scissor; +GLEW_VAR_EXPORT GLboolean __GLEW_KTX_buffer_region; +GLEW_VAR_EXPORT GLboolean __GLEW_MESAX_texture_stack; +GLEW_VAR_EXPORT GLboolean __GLEW_MESA_pack_invert; +GLEW_VAR_EXPORT GLboolean __GLEW_MESA_resize_buffers; +GLEW_VAR_EXPORT GLboolean __GLEW_MESA_window_pos; +GLEW_VAR_EXPORT GLboolean __GLEW_MESA_ycbcr_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_blend_square; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_conditional_render; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_copy_depth_to_color; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_depth_buffer_float; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_depth_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_depth_range_unclamped; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_evaluators; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_explicit_multisample; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_fence; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_float_buffer; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_fog_distance; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_fragment_program; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_fragment_program2; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_fragment_program4; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_fragment_program_option; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_framebuffer_multisample_coverage; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_geometry_program4; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_geometry_shader4; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_gpu_program4; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_half_float; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_light_max_exponent; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_multisample_filter_hint; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_occlusion_query; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_packed_depth_stencil; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_parameter_buffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_pixel_data_range; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_point_sprite; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_present_video; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_primitive_restart; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_register_combiners; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_register_combiners2; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texgen_emboss; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texgen_reflection; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_compression_vtc; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_env_combine4; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_expand_normal; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_rectangle; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_shader; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_shader2; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_shader3; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_transform_feedback; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_array_range; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_array_range2; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program1_1; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program2; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program2_option; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program3; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program4; +GLEW_VAR_EXPORT GLboolean __GLEW_OES_byte_coordinates; +GLEW_VAR_EXPORT GLboolean __GLEW_OES_compressed_paletted_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_OES_read_format; +GLEW_VAR_EXPORT GLboolean __GLEW_OES_single_precision; +GLEW_VAR_EXPORT GLboolean __GLEW_OML_interlace; +GLEW_VAR_EXPORT GLboolean __GLEW_OML_resample; +GLEW_VAR_EXPORT GLboolean __GLEW_OML_subsample; +GLEW_VAR_EXPORT GLboolean __GLEW_PGI_misc_hints; +GLEW_VAR_EXPORT GLboolean __GLEW_PGI_vertex_hints; +GLEW_VAR_EXPORT GLboolean __GLEW_REND_screen_coordinates; +GLEW_VAR_EXPORT GLboolean __GLEW_S3_s3tc; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_color_range; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_detail_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_fog_function; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_generate_mipmap; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_multisample; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_pixel_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_point_line_texgen; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_sharpen_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture4D; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture_border_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture_edge_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture_filter4; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture_lod; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture_select; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_async; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_async_histogram; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_async_pixel; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_blend_alpha_minmax; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_clipmap; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_convolution_accuracy; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_depth_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_flush_raster; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_fog_offset; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_fog_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_fragment_specular_lighting; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_framezoom; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_interlace; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_ir_instrument1; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_list_priority; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_pixel_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_pixel_texture_bits; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_reference_plane; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_resample; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_shadow; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_shadow_ambient; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_sprite; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_tag_sample_buffer; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_add_env; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_coordinate_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_lod_bias; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_multi_buffer; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_range; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_scale_bias; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_vertex_preclip; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_vertex_preclip_hint; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_ycrcb; +GLEW_VAR_EXPORT GLboolean __GLEW_SGI_color_matrix; +GLEW_VAR_EXPORT GLboolean __GLEW_SGI_color_table; +GLEW_VAR_EXPORT GLboolean __GLEW_SGI_texture_color_table; +GLEW_VAR_EXPORT GLboolean __GLEW_SUNX_constant_data; +GLEW_VAR_EXPORT GLboolean __GLEW_SUN_convolution_border_modes; +GLEW_VAR_EXPORT GLboolean __GLEW_SUN_global_alpha; +GLEW_VAR_EXPORT GLboolean __GLEW_SUN_mesh_array; +GLEW_VAR_EXPORT GLboolean __GLEW_SUN_read_video_pixels; +GLEW_VAR_EXPORT GLboolean __GLEW_SUN_slice_accum; +GLEW_VAR_EXPORT GLboolean __GLEW_SUN_triangle_list; +GLEW_VAR_EXPORT GLboolean __GLEW_SUN_vertex; +GLEW_VAR_EXPORT GLboolean __GLEW_WIN_phong_shading; +GLEW_VAR_EXPORT GLboolean __GLEW_WIN_specular_fog; +GLEW_VAR_EXPORT GLboolean __GLEW_WIN_swap_hint; + +#ifdef GLEW_MX +}; /* GLEWContextStruct */ +#endif /* GLEW_MX */ + +/* ------------------------------------------------------------------------- */ + +/* error codes */ +#define GLEW_OK 0 +#define GLEW_NO_ERROR 0 +#define GLEW_ERROR_NO_GL_VERSION 1 /* missing GL version */ +#define GLEW_ERROR_GL_VERSION_10_ONLY 2 /* GL 1.1 and up are not supported */ +#define GLEW_ERROR_GLX_VERSION_11_ONLY 3 /* GLX 1.2 and up are not supported */ + +/* string codes */ +#define GLEW_VERSION 1 +#define GLEW_VERSION_MAJOR 2 +#define GLEW_VERSION_MINOR 3 +#define GLEW_VERSION_MICRO 4 + +/* API */ +#ifdef GLEW_MX + +typedef struct GLEWContextStruct GLEWContext; +GLEWAPI GLenum glewContextInit (GLEWContext* ctx); +GLEWAPI GLboolean glewContextIsSupported (GLEWContext* ctx, const char* name); + +#define glewInit() glewContextInit(glewGetContext()) +#define glewIsSupported(x) glewContextIsSupported(glewGetContext(), x) +#define glewIsExtensionSupported(x) glewIsSupported(x) + +#define GLEW_GET_VAR(x) (*(const GLboolean*)&(glewGetContext()->x)) +#ifdef _WIN32 +# define GLEW_GET_FUN(x) glewGetContext()->x +#else +# define GLEW_GET_FUN(x) x +#endif + +#else /* GLEW_MX */ + +GLEWAPI GLenum glewInit (); +GLEWAPI GLboolean glewIsSupported (const char* name); +#define glewIsExtensionSupported(x) glewIsSupported(x) + +#define GLEW_GET_VAR(x) (*(const GLboolean*)&x) +#define GLEW_GET_FUN(x) x + +#endif /* GLEW_MX */ + +GLEWAPI GLboolean glewExperimental; +GLEWAPI GLboolean glewGetExtension (const char* name); +GLEWAPI const GLubyte* glewGetErrorString (GLenum error); +GLEWAPI const GLubyte* glewGetString (GLenum name); + +#ifdef __cplusplus +} +#endif + +#ifdef GLEW_APIENTRY_DEFINED +#undef GLEW_APIENTRY_DEFINED +#undef APIENTRY +#undef GLAPIENTRY +#endif + +#ifdef GLEW_CALLBACK_DEFINED +#undef GLEW_CALLBACK_DEFINED +#undef CALLBACK +#endif + +#ifdef GLEW_WINGDIAPI_DEFINED +#undef GLEW_WINGDIAPI_DEFINED +#undef WINGDIAPI +#endif + +#undef GLAPI +/* #undef GLEWAPI */ + +#endif /* __glew_h__ */ diff --git a/mod/pub.mod/glew.mod/GL/glxew.h b/mod/pub.mod/glew.mod/GL/glxew.h new file mode 100644 index 0000000..a29030d --- /dev/null +++ b/mod/pub.mod/glew.mod/GL/glxew.h @@ -0,0 +1,1397 @@ +/* +** The OpenGL Extension Wrangler Library +** Copyright (C) 2002-2008, Milan Ikits <milan ikits[]ieee org> +** Copyright (C) 2002-2008, Marcelo E. Magallon <mmagallo[]debian org> +** Copyright (C) 2002, Lev Povalahev +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are met: +** +** * Redistributions of source code must retain the above copyright notice, +** this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright notice, +** this list of conditions and the following disclaimer in the documentation +** and/or other materials provided with the distribution. +** * The name of the author may be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +** THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/* + * Mesa 3-D graphics library + * Version: 7.0 + * + * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* +** Copyright (c) 2007 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +#ifndef __glxew_h__ +#define __glxew_h__ +#define __GLXEW_H__ + +#ifdef __glxext_h_ +#error glxext.h included before glxew.h +#endif +#ifdef GLX_H +#error glx.h included before glxew.h +#endif + +#define __glxext_h_ +#define __GLX_glx_h__ +#define GLX_H + +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <X11/Xmd.h> +#include <GL/glew.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* ---------------------------- GLX_VERSION_1_0 --------------------------- */ + +#ifndef GLX_VERSION_1_0 +#define GLX_VERSION_1_0 1 + +#define GLX_USE_GL 1 +#define GLX_BUFFER_SIZE 2 +#define GLX_LEVEL 3 +#define GLX_RGBA 4 +#define GLX_DOUBLEBUFFER 5 +#define GLX_STEREO 6 +#define GLX_AUX_BUFFERS 7 +#define GLX_RED_SIZE 8 +#define GLX_GREEN_SIZE 9 +#define GLX_BLUE_SIZE 10 +#define GLX_ALPHA_SIZE 11 +#define GLX_DEPTH_SIZE 12 +#define GLX_STENCIL_SIZE 13 +#define GLX_ACCUM_RED_SIZE 14 +#define GLX_ACCUM_GREEN_SIZE 15 +#define GLX_ACCUM_BLUE_SIZE 16 +#define GLX_ACCUM_ALPHA_SIZE 17 +#define GLX_BAD_SCREEN 1 +#define GLX_BAD_ATTRIBUTE 2 +#define GLX_NO_EXTENSION 3 +#define GLX_BAD_VISUAL 4 +#define GLX_BAD_CONTEXT 5 +#define GLX_BAD_VALUE 6 +#define GLX_BAD_ENUM 7 + +typedef XID GLXDrawable; +typedef XID GLXPixmap; +#ifdef __sun +typedef struct __glXContextRec *GLXContext; +#else +typedef struct __GLXcontextRec *GLXContext; +#endif + +typedef unsigned int GLXVideoDeviceNV; + +extern Bool glXQueryExtension (Display *dpy, int *errorBase, int *eventBase); +extern Bool glXQueryVersion (Display *dpy, int *major, int *minor); +extern int glXGetConfig (Display *dpy, XVisualInfo *vis, int attrib, int *value); +extern XVisualInfo* glXChooseVisual (Display *dpy, int screen, int *attribList); +extern GLXPixmap glXCreateGLXPixmap (Display *dpy, XVisualInfo *vis, Pixmap pixmap); +extern void glXDestroyGLXPixmap (Display *dpy, GLXPixmap pix); +extern GLXContext glXCreateContext (Display *dpy, XVisualInfo *vis, GLXContext shareList, Bool direct); +extern void glXDestroyContext (Display *dpy, GLXContext ctx); +extern Bool glXIsDirect (Display *dpy, GLXContext ctx); +extern void glXCopyContext (Display *dpy, GLXContext src, GLXContext dst, GLulong mask); +extern Bool glXMakeCurrent (Display *dpy, GLXDrawable drawable, GLXContext ctx); +extern GLXContext glXGetCurrentContext (void); +extern GLXDrawable glXGetCurrentDrawable (void); +extern void glXWaitGL (void); +extern void glXWaitX (void); +extern void glXSwapBuffers (Display *dpy, GLXDrawable drawable); +extern void glXUseXFont (Font font, int first, int count, int listBase); + +#define GLXEW_VERSION_1_0 GLXEW_GET_VAR(__GLXEW_VERSION_1_0) + +#endif /* GLX_VERSION_1_0 */ + +/* ---------------------------- GLX_VERSION_1_1 --------------------------- */ + +#ifndef GLX_VERSION_1_1 +#define GLX_VERSION_1_1 + +#define GLX_VENDOR 0x1 +#define GLX_VERSION 0x2 +#define GLX_EXTENSIONS 0x3 + +extern const char* glXQueryExtensionsString (Display *dpy, int screen); +extern const char* glXGetClientString (Display *dpy, int name); +extern const char* glXQueryServerString (Display *dpy, int screen, int name); + +#define GLXEW_VERSION_1_1 GLXEW_GET_VAR(__GLXEW_VERSION_1_1) + +#endif /* GLX_VERSION_1_1 */ + +/* ---------------------------- GLX_VERSION_1_2 ---------------------------- */ + +#ifndef GLX_VERSION_1_2 +#define GLX_VERSION_1_2 1 + +typedef Display* ( * PFNGLXGETCURRENTDISPLAYPROC) (void); + +#define glXGetCurrentDisplay GLXEW_GET_FUN(__glewXGetCurrentDisplay) + +#define GLXEW_VERSION_1_2 GLXEW_GET_VAR(__GLXEW_VERSION_1_2) + +#endif /* GLX_VERSION_1_2 */ + +/* ---------------------------- GLX_VERSION_1_3 ---------------------------- */ + +#ifndef GLX_VERSION_1_3 +#define GLX_VERSION_1_3 1 + +#define GLX_RGBA_BIT 0x00000001 +#define GLX_FRONT_LEFT_BUFFER_BIT 0x00000001 +#define GLX_WINDOW_BIT 0x00000001 +#define GLX_COLOR_INDEX_BIT 0x00000002 +#define GLX_PIXMAP_BIT 0x00000002 +#define GLX_FRONT_RIGHT_BUFFER_BIT 0x00000002 +#define GLX_BACK_LEFT_BUFFER_BIT 0x00000004 +#define GLX_PBUFFER_BIT 0x00000004 +#define GLX_BACK_RIGHT_BUFFER_BIT 0x00000008 +#define GLX_AUX_BUFFERS_BIT 0x00000010 +#define GLX_CONFIG_CAVEAT 0x20 +#define GLX_DEPTH_BUFFER_BIT 0x00000020 +#define GLX_X_VISUAL_TYPE 0x22 +#define GLX_TRANSPARENT_TYPE 0x23 +#define GLX_TRANSPARENT_INDEX_VALUE 0x24 +#define GLX_TRANSPARENT_RED_VALUE 0x25 +#define GLX_TRANSPARENT_GREEN_VALUE 0x26 +#define GLX_TRANSPARENT_BLUE_VALUE 0x27 +#define GLX_TRANSPARENT_ALPHA_VALUE 0x28 +#define GLX_STENCIL_BUFFER_BIT 0x00000040 +#define GLX_ACCUM_BUFFER_BIT 0x00000080 +#define GLX_NONE 0x8000 +#define GLX_SLOW_CONFIG 0x8001 +#define GLX_TRUE_COLOR 0x8002 +#define GLX_DIRECT_COLOR 0x8003 +#define GLX_PSEUDO_COLOR 0x8004 +#define GLX_STATIC_COLOR 0x8005 +#define GLX_GRAY_SCALE 0x8006 +#define GLX_STATIC_GRAY 0x8007 +#define GLX_TRANSPARENT_RGB 0x8008 +#define GLX_TRANSPARENT_INDEX 0x8009 +#define GLX_VISUAL_ID 0x800B +#define GLX_SCREEN 0x800C +#define GLX_NON_CONFORMANT_CONFIG 0x800D +#define GLX_DRAWABLE_TYPE 0x8010 +#define GLX_RENDER_TYPE 0x8011 +#define GLX_X_RENDERABLE 0x8012 +#define GLX_FBCONFIG_ID 0x8013 +#define GLX_RGBA_TYPE 0x8014 +#define GLX_COLOR_INDEX_TYPE 0x8015 +#define GLX_MAX_PBUFFER_WIDTH 0x8016 +#define GLX_MAX_PBUFFER_HEIGHT 0x8017 +#define GLX_MAX_PBUFFER_PIXELS 0x8018 +#define GLX_PRESERVED_CONTENTS 0x801B +#define GLX_LARGEST_PBUFFER 0x801C +#define GLX_WIDTH 0x801D +#define GLX_HEIGHT 0x801E +#define GLX_EVENT_MASK 0x801F +#define GLX_DAMAGED 0x8020 +#define GLX_SAVED 0x8021 +#define GLX_WINDOW 0x8022 +#define GLX_PBUFFER 0x8023 +#define GLX_PBUFFER_HEIGHT 0x8040 +#define GLX_PBUFFER_WIDTH 0x8041 +#define GLX_PBUFFER_CLOBBER_MASK 0x08000000 +#define GLX_DONT_CARE 0xFFFFFFFF + +typedef XID GLXFBConfigID; +typedef XID GLXWindow; +typedef XID GLXPbuffer; +typedef struct __GLXFBConfigRec *GLXFBConfig; + +typedef struct { + int event_type; + int draw_type; + unsigned long serial; + Bool send_event; + Display *display; + GLXDrawable drawable; + unsigned int buffer_mask; + unsigned int aux_buffer; + int x, y; + int width, height; + int count; +} GLXPbufferClobberEvent; +typedef union __GLXEvent { + GLXPbufferClobberEvent glxpbufferclobber; + long pad[24]; +} GLXEvent; + +typedef GLXFBConfig* ( * PFNGLXCHOOSEFBCONFIGPROC) (Display *dpy, int screen, const int *attrib_list, int *nelements); +typedef GLXContext ( * PFNGLXCREATENEWCONTEXTPROC) (Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct); +typedef GLXPbuffer ( * PFNGLXCREATEPBUFFERPROC) (Display *dpy, GLXFBConfig config, const int *attrib_list); +typedef GLXPixmap ( * PFNGLXCREATEPIXMAPPROC) (Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attrib_list); +typedef GLXWindow ( * PFNGLXCREATEWINDOWPROC) (Display *dpy, GLXFBConfig config, Window win, const int *attrib_list); +typedef void ( * PFNGLXDESTROYPBUFFERPROC) (Display *dpy, GLXPbuffer pbuf); +typedef void ( * PFNGLXDESTROYPIXMAPPROC) (Display *dpy, GLXPixmap pixmap); +typedef void ( * PFNGLXDESTROYWINDOWPROC) (Display *dpy, GLXWindow win); +typedef GLXDrawable ( * PFNGLXGETCURRENTREADDRAWABLEPROC) (void); +typedef int ( * PFNGLXGETFBCONFIGATTRIBPROC) (Display *dpy, GLXFBConfig config, int attribute, int *value); +typedef GLXFBConfig* ( * PFNGLXGETFBCONFIGSPROC) (Display *dpy, int screen, int *nelements); +typedef void ( * PFNGLXGETSELECTEDEVENTPROC) (Display *dpy, GLXDrawable draw, unsigned long *event_mask); +typedef XVisualInfo* ( * PFNGLXGETVISUALFROMFBCONFIGPROC) (Display *dpy, GLXFBConfig config); +typedef Bool ( * PFNGLXMAKECONTEXTCURRENTPROC) (Display *display, GLXDrawable draw, GLXDrawable read, GLXContext ctx); +typedef int ( * PFNGLXQUERYCONTEXTPROC) (Display *dpy, GLXContext ctx, int attribute, int *value); +typedef void ( * PFNGLXQUERYDRAWABLEPROC) (Display *dpy, GLXDrawable draw, int attribute, unsigned int *value); +typedef void ( * PFNGLXSELECTEVENTPROC) (Display *dpy, GLXDrawable draw, unsigned long event_mask); + +#define glXChooseFBConfig GLXEW_GET_FUN(__glewXChooseFBConfig) +#define glXCreateNewContext GLXEW_GET_FUN(__glewXCreateNewContext) +#define glXCreatePbuffer GLXEW_GET_FUN(__glewXCreatePbuffer) +#define glXCreatePixmap GLXEW_GET_FUN(__glewXCreatePixmap) +#define glXCreateWindow GLXEW_GET_FUN(__glewXCreateWindow) +#define glXDestroyPbuffer GLXEW_GET_FUN(__glewXDestroyPbuffer) +#define glXDestroyPixmap GLXEW_GET_FUN(__glewXDestroyPixmap) +#define glXDestroyWindow GLXEW_GET_FUN(__glewXDestroyWindow) +#define glXGetCurrentReadDrawable GLXEW_GET_FUN(__glewXGetCurrentReadDrawable) +#define glXGetFBConfigAttrib GLXEW_GET_FUN(__glewXGetFBConfigAttrib) +#define glXGetFBConfigs GLXEW_GET_FUN(__glewXGetFBConfigs) +#define glXGetSelectedEvent GLXEW_GET_FUN(__glewXGetSelectedEvent) +#define glXGetVisualFromFBConfig GLXEW_GET_FUN(__glewXGetVisualFromFBConfig) +#define glXMakeContextCurrent GLXEW_GET_FUN(__glewXMakeContextCurrent) +#define glXQueryContext GLXEW_GET_FUN(__glewXQueryContext) +#define glXQueryDrawable GLXEW_GET_FUN(__glewXQueryDrawable) +#define glXSelectEvent GLXEW_GET_FUN(__glewXSelectEvent) + +#define GLXEW_VERSION_1_3 GLXEW_GET_VAR(__GLXEW_VERSION_1_3) + +#endif /* GLX_VERSION_1_3 */ + +/* ---------------------------- GLX_VERSION_1_4 ---------------------------- */ + +#ifndef GLX_VERSION_1_4 +#define GLX_VERSION_1_4 1 + +#define GLX_SAMPLE_BUFFERS 100000 +#define GLX_SAMPLES 100001 + +extern void ( * glXGetProcAddress (const GLubyte *procName)) (void); + +#define GLXEW_VERSION_1_4 GLXEW_GET_VAR(__GLXEW_VERSION_1_4) + +#endif /* GLX_VERSION_1_4 */ + +/* -------------------------- GLX_3DFX_multisample ------------------------- */ + +#ifndef GLX_3DFX_multisample +#define GLX_3DFX_multisample 1 + +#define GLX_SAMPLE_BUFFERS_3DFX 0x8050 +#define GLX_SAMPLES_3DFX 0x8051 + +#define GLXEW_3DFX_multisample GLXEW_GET_VAR(__GLXEW_3DFX_multisample) + +#endif /* GLX_3DFX_multisample */ + +/* ------------------------- GLX_ARB_create_context ------------------------ */ + +#ifndef GLX_ARB_create_context +#define GLX_ARB_create_context 1 + +#define GLX_CONTEXT_DEBUG_BIT_ARB 0x0001 +#define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002 +#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091 +#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092 +#define GLX_CONTEXT_FLAGS_ARB 0x2094 + +typedef GLXContext ( * PFNGLXCREATECONTEXTATTRIBSARBPROC) (Display* dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list); + +#define glXCreateContextAttribsARB GLXEW_GET_FUN(__glewXCreateContextAttribsARB) + +#define GLXEW_ARB_create_context GLXEW_GET_VAR(__GLXEW_ARB_create_context) + +#endif /* GLX_ARB_create_context */ + +/* ------------------------- GLX_ARB_fbconfig_float ------------------------ */ + +#ifndef GLX_ARB_fbconfig_float +#define GLX_ARB_fbconfig_float 1 + +#define GLX_RGBA_FLOAT_BIT 0x00000004 +#define GLX_RGBA_FLOAT_TYPE 0x20B9 + +#define GLXEW_ARB_fbconfig_float GLXEW_GET_VAR(__GLXEW_ARB_fbconfig_float) + +#endif /* GLX_ARB_fbconfig_float */ + +/* ------------------------ GLX_ARB_framebuffer_sRGB ----------------------- */ + +#ifndef GLX_ARB_framebuffer_sRGB +#define GLX_ARB_framebuffer_sRGB 1 + +#define GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20B2 + +#define GLXEW_ARB_framebuffer_sRGB GLXEW_GET_VAR(__GLXEW_ARB_framebuffer_sRGB) + +#endif /* GLX_ARB_framebuffer_sRGB */ + +/* ------------------------ GLX_ARB_get_proc_address ----------------------- */ + +#ifndef GLX_ARB_get_proc_address +#define GLX_ARB_get_proc_address 1 + +extern void ( * glXGetProcAddressARB (const GLubyte *procName)) (void); + +#define GLXEW_ARB_get_proc_address GLXEW_GET_VAR(__GLXEW_ARB_get_proc_address) + +#endif /* GLX_ARB_get_proc_address */ + +/* -------------------------- GLX_ARB_multisample -------------------------- */ + +#ifndef GLX_ARB_multisample +#define GLX_ARB_multisample 1 + +#define GLX_SAMPLE_BUFFERS_ARB 100000 +#define GLX_SAMPLES_ARB 100001 + +#define GLXEW_ARB_multisample GLXEW_GET_VAR(__GLXEW_ARB_multisample) + +#endif /* GLX_ARB_multisample */ + +/* ----------------------- GLX_ATI_pixel_format_float ---------------------- */ + +#ifndef GLX_ATI_pixel_format_float +#define GLX_ATI_pixel_format_float 1 + +#define GLX_RGBA_FLOAT_ATI_BIT 0x00000100 + +#define GLXEW_ATI_pixel_format_float GLXEW_GET_VAR(__GLXEW_ATI_pixel_format_float) + +#endif /* GLX_ATI_pixel_format_float */ + +/* ------------------------- GLX_ATI_render_texture ------------------------ */ + +#ifndef GLX_ATI_render_texture +#define GLX_ATI_render_texture 1 + +#define GLX_BIND_TO_TEXTURE_RGB_ATI 0x9800 +#define GLX_BIND_TO_TEXTURE_RGBA_ATI 0x9801 +#define GLX_TEXTURE_FORMAT_ATI 0x9802 +#define GLX_TEXTURE_TARGET_ATI 0x9803 +#define GLX_MIPMAP_TEXTURE_ATI 0x9804 +#define GLX_TEXTURE_RGB_ATI 0x9805 +#define GLX_TEXTURE_RGBA_ATI 0x9806 +#define GLX_NO_TEXTURE_ATI 0x9807 +#define GLX_TEXTURE_CUBE_MAP_ATI 0x9808 +#define GLX_TEXTURE_1D_ATI 0x9809 +#define GLX_TEXTURE_2D_ATI 0x980A +#define GLX_MIPMAP_LEVEL_ATI 0x980B +#define GLX_CUBE_MAP_FACE_ATI 0x980C +#define GLX_TEXTURE_CUBE_MAP_POSITIVE_X_ATI 0x980D +#define GLX_TEXTURE_CUBE_MAP_NEGATIVE_X_ATI 0x980E +#define GLX_TEXTURE_CUBE_MAP_POSITIVE_Y_ATI 0x980F +#define GLX_TEXTURE_CUBE_MAP_NEGATIVE_Y_ATI 0x9810 +#define GLX_TEXTURE_CUBE_MAP_POSITIVE_Z_ATI 0x9811 +#define GLX_TEXTURE_CUBE_MAP_NEGATIVE_Z_ATI 0x9812 +#define GLX_FRONT_LEFT_ATI 0x9813 +#define GLX_FRONT_RIGHT_ATI 0x9814 +#define GLX_BACK_LEFT_ATI 0x9815 +#define GLX_BACK_RIGHT_ATI 0x9816 +#define GLX_AUX0_ATI 0x9817 +#define GLX_AUX1_ATI 0x9818 +#define GLX_AUX2_ATI 0x9819 +#define GLX_AUX3_ATI 0x981A +#define GLX_AUX4_ATI 0x981B +#define GLX_AUX5_ATI 0x981C +#define GLX_AUX6_ATI 0x981D +#define GLX_AUX7_ATI 0x981E +#define GLX_AUX8_ATI 0x981F +#define GLX_AUX9_ATI 0x9820 +#define GLX_BIND_TO_TEXTURE_LUMINANCE_ATI 0x9821 +#define GLX_BIND_TO_TEXTURE_INTENSITY_ATI 0x9822 + +typedef void ( * PFNGLXBINDTEXIMAGEATIPROC) (Display *dpy, GLXPbuffer pbuf, int buffer); +typedef void ( * PFNGLXDRAWABLEATTRIBATIPROC) (Display *dpy, GLXDrawable draw, const int *attrib_list); +typedef void ( * PFNGLXRELEASETEXIMAGEATIPROC) (Display *dpy, GLXPbuffer pbuf, int buffer); + +#define glXBindTexImageATI GLXEW_GET_FUN(__glewXBindTexImageATI) +#define glXDrawableAttribATI GLXEW_GET_FUN(__glewXDrawableAttribATI) +#define glXReleaseTexImageATI GLXEW_GET_FUN(__glewXReleaseTexImageATI) + +#define GLXEW_ATI_render_texture GLXEW_GET_VAR(__GLXEW_ATI_render_texture) + +#endif /* GLX_ATI_render_texture */ + +/* --------------------- GLX_EXT_fbconfig_packed_float --------------------- */ + +#ifndef GLX_EXT_fbconfig_packed_float +#define GLX_EXT_fbconfig_packed_float 1 + +#define GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT 0x00000008 +#define GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT 0x20B1 + +#define GLXEW_EXT_fbconfig_packed_float GLXEW_GET_VAR(__GLXEW_EXT_fbconfig_packed_float) + +#endif /* GLX_EXT_fbconfig_packed_float */ + +/* ------------------------ GLX_EXT_framebuffer_sRGB ----------------------- */ + +#ifndef GLX_EXT_framebuffer_sRGB +#define GLX_EXT_framebuffer_sRGB 1 + +#define GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20B2 + +#define GLXEW_EXT_framebuffer_sRGB GLXEW_GET_VAR(__GLXEW_EXT_framebuffer_sRGB) + +#endif /* GLX_EXT_framebuffer_sRGB */ + +/* ------------------------- GLX_EXT_import_context ------------------------ */ + +#ifndef GLX_EXT_import_context +#define GLX_EXT_import_context 1 + +#define GLX_SHARE_CONTEXT_EXT 0x800A +#define GLX_VISUAL_ID_EXT 0x800B +#define GLX_SCREEN_EXT 0x800C + +typedef XID GLXContextID; + +typedef void ( * PFNGLXFREECONTEXTEXTPROC) (Display* dpy, GLXContext context); +typedef GLXContextID ( * PFNGLXGETCONTEXTIDEXTPROC) (const GLXContext context); +typedef GLXContext ( * PFNGLXIMPORTCONTEXTEXTPROC) (Display* dpy, GLXContextID contextID); +typedef int ( * PFNGLXQUERYCONTEXTINFOEXTPROC) (Display* dpy, GLXContext context, int attribute,int *value); + +#define glXFreeContextEXT GLXEW_GET_FUN(__glewXFreeContextEXT) +#define glXGetContextIDEXT GLXEW_GET_FUN(__glewXGetContextIDEXT) +#define glXImportContextEXT GLXEW_GET_FUN(__glewXImportContextEXT) +#define glXQueryContextInfoEXT GLXEW_GET_FUN(__glewXQueryContextInfoEXT) + +#define GLXEW_EXT_import_context GLXEW_GET_VAR(__GLXEW_EXT_import_context) + +#endif /* GLX_EXT_import_context */ + +/* -------------------------- GLX_EXT_scene_marker ------------------------- */ + +#ifndef GLX_EXT_scene_marker +#define GLX_EXT_scene_marker 1 + +#define GLXEW_EXT_scene_marker GLXEW_GET_VAR(__GLXEW_EXT_scene_marker) + +#endif /* GLX_EXT_scene_marker */ + +/* ---------------------- GLX_EXT_texture_from_pixmap ---------------------- */ + +#ifndef GLX_EXT_texture_from_pixmap +#define GLX_EXT_texture_from_pixmap 1 + +#define GLX_TEXTURE_1D_BIT_EXT 0x00000001 +#define GLX_TEXTURE_2D_BIT_EXT 0x00000002 +#define GLX_TEXTURE_RECTANGLE_BIT_EXT 0x00000004 +#define GLX_BIND_TO_TEXTURE_RGB_EXT 0x20D0 +#define GLX_BIND_TO_TEXTURE_RGBA_EXT 0x20D1 +#define GLX_BIND_TO_MIPMAP_TEXTURE_EXT 0x20D2 +#define GLX_BIND_TO_TEXTURE_TARGETS_EXT 0x20D3 +#define GLX_Y_INVERTED_EXT 0x20D4 +#define GLX_TEXTURE_FORMAT_EXT 0x20D5 +#define GLX_TEXTURE_TARGET_EXT 0x20D6 +#define GLX_MIPMAP_TEXTURE_EXT 0x20D7 +#define GLX_TEXTURE_FORMAT_NONE_EXT 0x20D8 +#define GLX_TEXTURE_FORMAT_RGB_EXT 0x20D9 +#define GLX_TEXTURE_FORMAT_RGBA_EXT 0x20DA +#define GLX_TEXTURE_1D_EXT 0x20DB +#define GLX_TEXTURE_2D_EXT 0x20DC +#define GLX_TEXTURE_RECTANGLE_EXT 0x20DD +#define GLX_FRONT_LEFT_EXT 0x20DE +#define GLX_FRONT_RIGHT_EXT 0x20DF +#define GLX_BACK_LEFT_EXT 0x20E0 +#define GLX_BACK_RIGHT_EXT 0x20E1 +#define GLX_AUX0_EXT 0x20E2 +#define GLX_AUX1_EXT 0x20E3 +#define GLX_AUX2_EXT 0x20E4 +#define GLX_AUX3_EXT 0x20E5 +#define GLX_AUX4_EXT 0x20E6 +#define GLX_AUX5_EXT 0x20E7 +#define GLX_AUX6_EXT 0x20E8 +#define GLX_AUX7_EXT 0x20E9 +#define GLX_AUX8_EXT 0x20EA +#define GLX_AUX9_EXT 0x20EB + +typedef void ( * PFNGLXBINDTEXIMAGEEXTPROC) (Display* display, GLXDrawable drawable, int buffer, const int *attrib_list); +typedef void ( * PFNGLXRELEASETEXIMAGEEXTPROC) (Display* display, GLXDrawable drawable, int buffer); + +#define glXBindTexImageEXT GLXEW_GET_FUN(__glewXBindTexImageEXT) +#define glXReleaseTexImageEXT GLXEW_GET_FUN(__glewXReleaseTexImageEXT) + +#define GLXEW_EXT_texture_from_pixmap GLXEW_GET_VAR(__GLXEW_EXT_texture_from_pixmap) + +#endif /* GLX_EXT_texture_from_pixmap */ + +/* -------------------------- GLX_EXT_visual_info -------------------------- */ + +#ifndef GLX_EXT_visual_info +#define GLX_EXT_visual_info 1 + +#define GLX_X_VISUAL_TYPE_EXT 0x22 +#define GLX_TRANSPARENT_TYPE_EXT 0x23 +#define GLX_TRANSPARENT_INDEX_VALUE_EXT 0x24 +#define GLX_TRANSPARENT_RED_VALUE_EXT 0x25 +#define GLX_TRANSPARENT_GREEN_VALUE_EXT 0x26 +#define GLX_TRANSPARENT_BLUE_VALUE_EXT 0x27 +#define GLX_TRANSPARENT_ALPHA_VALUE_EXT 0x28 +#define GLX_NONE_EXT 0x8000 +#define GLX_TRUE_COLOR_EXT 0x8002 +#define GLX_DIRECT_COLOR_EXT 0x8003 +#define GLX_PSEUDO_COLOR_EXT 0x8004 +#define GLX_STATIC_COLOR_EXT 0x8005 +#define GLX_GRAY_SCALE_EXT 0x8006 +#define GLX_STATIC_GRAY_EXT 0x8007 +#define GLX_TRANSPARENT_RGB_EXT 0x8008 +#define GLX_TRANSPARENT_INDEX_EXT 0x8009 + +#define GLXEW_EXT_visual_info GLXEW_GET_VAR(__GLXEW_EXT_visual_info) + +#endif /* GLX_EXT_visual_info */ + +/* ------------------------- GLX_EXT_visual_rating ------------------------- */ + +#ifndef GLX_EXT_visual_rating +#define GLX_EXT_visual_rating 1 + +#define GLX_VISUAL_CAVEAT_EXT 0x20 +#define GLX_SLOW_VISUAL_EXT 0x8001 +#define GLX_NON_CONFORMANT_VISUAL_EXT 0x800D + +#define GLXEW_EXT_visual_rating GLXEW_GET_VAR(__GLXEW_EXT_visual_rating) + +#endif /* GLX_EXT_visual_rating */ + +/* -------------------------- GLX_MESA_agp_offset -------------------------- */ + +#ifndef GLX_MESA_agp_offset +#define GLX_MESA_agp_offset 1 + +typedef unsigned int ( * PFNGLXGETAGPOFFSETMESAPROC) (const void* pointer); + +#define glXGetAGPOffsetMESA GLXEW_GET_FUN(__glewXGetAGPOffsetMESA) + +#define GLXEW_MESA_agp_offset GLXEW_GET_VAR(__GLXEW_MESA_agp_offset) + +#endif /* GLX_MESA_agp_offset */ + +/* ------------------------ GLX_MESA_copy_sub_buffer ----------------------- */ + +#ifndef GLX_MESA_copy_sub_buffer +#define GLX_MESA_copy_sub_buffer 1 + +typedef void ( * PFNGLXCOPYSUBBUFFERMESAPROC) (Display* dpy, GLXDrawable drawable, int x, int y, int width, int height); + +#define glXCopySubBufferMESA GLXEW_GET_FUN(__glewXCopySubBufferMESA) + +#define GLXEW_MESA_copy_sub_buffer GLXEW_GET_VAR(__GLXEW_MESA_copy_sub_buffer) + +#endif /* GLX_MESA_copy_sub_buffer */ + +/* ------------------------ GLX_MESA_pixmap_colormap ----------------------- */ + +#ifndef GLX_MESA_pixmap_colormap +#define GLX_MESA_pixmap_colormap 1 + +typedef GLXPixmap ( * PFNGLXCREATEGLXPIXMAPMESAPROC) (Display* dpy, XVisualInfo *visual, Pixmap pixmap, Colormap cmap); + +#define glXCreateGLXPixmapMESA GLXEW_GET_FUN(__glewXCreateGLXPixmapMESA) + +#define GLXEW_MESA_pixmap_colormap GLXEW_GET_VAR(__GLXEW_MESA_pixmap_colormap) + +#endif /* GLX_MESA_pixmap_colormap */ + +/* ------------------------ GLX_MESA_release_buffers ----------------------- */ + +#ifndef GLX_MESA_release_buffers +#define GLX_MESA_release_buffers 1 + +typedef Bool ( * PFNGLXRELEASEBUFFERSMESAPROC) (Display* dpy, GLXDrawable d); + +#define glXReleaseBuffersMESA GLXEW_GET_FUN(__glewXReleaseBuffersMESA) + +#define GLXEW_MESA_release_buffers GLXEW_GET_VAR(__GLXEW_MESA_release_buffers) + +#endif /* GLX_MESA_release_buffers */ + +/* ------------------------- GLX_MESA_set_3dfx_mode ------------------------ */ + +#ifndef GLX_MESA_set_3dfx_mode +#define GLX_MESA_set_3dfx_mode 1 + +#define GLX_3DFX_WINDOW_MODE_MESA 0x1 +#define GLX_3DFX_FULLSCREEN_MODE_MESA 0x2 + +typedef GLboolean ( * PFNGLXSET3DFXMODEMESAPROC) (GLint mode); + +#define glXSet3DfxModeMESA GLXEW_GET_FUN(__glewXSet3DfxModeMESA) + +#define GLXEW_MESA_set_3dfx_mode GLXEW_GET_VAR(__GLXEW_MESA_set_3dfx_mode) + +#endif /* GLX_MESA_set_3dfx_mode */ + +/* -------------------------- GLX_NV_float_buffer -------------------------- */ + +#ifndef GLX_NV_float_buffer +#define GLX_NV_float_buffer 1 + +#define GLX_FLOAT_COMPONENTS_NV 0x20B0 + +#define GLXEW_NV_float_buffer GLXEW_GET_VAR(__GLXEW_NV_float_buffer) + +#endif /* GLX_NV_float_buffer */ + +/* -------------------------- GLX_NV_present_video ------------------------- */ + +#ifndef GLX_NV_present_video +#define GLX_NV_present_video 1 + +#define GLX_NUM_VIDEO_SLOTS_NV 0x20F0 + +typedef int ( * PFNGLXBINDVIDEODEVICENVPROC) (Display* dpy, unsigned int video_slot, unsigned int video_device, const int *attrib_list); +typedef unsigned int* ( * PFNGLXENUMERATEVIDEODEVICESNVPROC) (Display *dpy, int screen, int *nelements); + +#define glXBindVideoDeviceNV GLXEW_GET_FUN(__glewXBindVideoDeviceNV) +#define glXEnumerateVideoDevicesNV GLXEW_GET_FUN(__glewXEnumerateVideoDevicesNV) + +#define GLXEW_NV_present_video GLXEW_GET_VAR(__GLXEW_NV_present_video) + +#endif /* GLX_NV_present_video */ + +/* --------------------------- GLX_NV_swap_group --------------------------- */ + +#ifndef GLX_NV_swap_group +#define GLX_NV_swap_group 1 + +typedef Bool ( * PFNGLXBINDSWAPBARRIERNVPROC) (Display* dpy, GLuint group, GLuint barrier); +typedef Bool ( * PFNGLXJOINSWAPGROUPNVPROC) (Display* dpy, GLXDrawable drawable, GLuint group); +typedef Bool ( * PFNGLXQUERYFRAMECOUNTNVPROC) (Display* dpy, int screen, GLuint *count); +typedef Bool ( * PFNGLXQUERYMAXSWAPGROUPSNVPROC) (Display* dpy, int screen, GLuint *maxGroups, GLuint *maxBarriers); +typedef Bool ( * PFNGLXQUERYSWAPGROUPNVPROC) (Display* dpy, GLXDrawable drawable, GLuint *group, GLuint *barrier); +typedef Bool ( * PFNGLXRESETFRAMECOUNTNVPROC) (Display* dpy, int screen); + +#define glXBindSwapBarrierNV GLXEW_GET_FUN(__glewXBindSwapBarrierNV) +#define glXJoinSwapGroupNV GLXEW_GET_FUN(__glewXJoinSwapGroupNV) +#define glXQueryFrameCountNV GLXEW_GET_FUN(__glewXQueryFrameCountNV) +#define glXQueryMaxSwapGroupsNV GLXEW_GET_FUN(__glewXQueryMaxSwapGroupsNV) +#define glXQuerySwapGroupNV GLXEW_GET_FUN(__glewXQuerySwapGroupNV) +#define glXResetFrameCountNV GLXEW_GET_FUN(__glewXResetFrameCountNV) + +#define GLXEW_NV_swap_group GLXEW_GET_VAR(__GLXEW_NV_swap_group) + +#endif /* GLX_NV_swap_group */ + +/* ----------------------- GLX_NV_vertex_array_range ----------------------- */ + +#ifndef GLX_NV_vertex_array_range +#define GLX_NV_vertex_array_range 1 + +typedef void * ( * PFNGLXALLOCATEMEMORYNVPROC) (GLsizei size, GLfloat readFrequency, GLfloat writeFrequency, GLfloat priority); +typedef void ( * PFNGLXFREEMEMORYNVPROC) (void *pointer); + +#define glXAllocateMemoryNV GLXEW_GET_FUN(__glewXAllocateMemoryNV) +#define glXFreeMemoryNV GLXEW_GET_FUN(__glewXFreeMemoryNV) + +#define GLXEW_NV_vertex_array_range GLXEW_GET_VAR(__GLXEW_NV_vertex_array_range) + +#endif /* GLX_NV_vertex_array_range */ + +/* -------------------------- GLX_NV_video_output -------------------------- */ + +#ifndef GLX_NV_video_output +#define GLX_NV_video_output 1 + +#define GLX_VIDEO_OUT_COLOR_NV 0x20C3 +#define GLX_VIDEO_OUT_ALPHA_NV 0x20C4 +#define GLX_VIDEO_OUT_DEPTH_NV 0x20C5 +#define GLX_VIDEO_OUT_COLOR_AND_ALPHA_NV 0x20C6 +#define GLX_VIDEO_OUT_COLOR_AND_DEPTH_NV 0x20C7 +#define GLX_VIDEO_OUT_FRAME_NV 0x20C8 +#define GLX_VIDEO_OUT_FIELD_1_NV 0x20C9 +#define GLX_VIDEO_OUT_FIELD_2_NV 0x20CA +#define GLX_VIDEO_OUT_STACKED_FIELDS_1_2_NV 0x20CB +#define GLX_VIDEO_OUT_STACKED_FIELDS_2_1_NV 0x20CC + +typedef int ( * PFNGLXBINDVIDEOIMAGENVPROC) (Display* dpy, GLXVideoDeviceNV VideoDevice, GLXPbuffer pbuf, int iVideoBuffer); +typedef int ( * PFNGLXGETVIDEODEVICENVPROC) (Display* dpy, int screen, int numVideoDevices, GLXVideoDeviceNV *pVideoDevice); +typedef int ( * PFNGLXGETVIDEOINFONVPROC) (Display* dpy, int screen, GLXVideoDeviceNV VideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo); +typedef int ( * PFNGLXRELEASEVIDEODEVICENVPROC) (Display* dpy, int screen, GLXVideoDeviceNV VideoDevice); +typedef int ( * PFNGLXRELEASEVIDEOIMAGENVPROC) (Display* dpy, GLXPbuffer pbuf); +typedef int ( * PFNGLXSENDPBUFFERTOVIDEONVPROC) (Display* dpy, GLXPbuffer pbuf, int iBufferType, unsigned long *pulCounterPbuffer, GLboolean bBlock); + +#define glXBindVideoImageNV GLXEW_GET_FUN(__glewXBindVideoImageNV) +#define glXGetVideoDeviceNV GLXEW_GET_FUN(__glewXGetVideoDeviceNV) +#define glXGetVideoInfoNV GLXEW_GET_FUN(__glewXGetVideoInfoNV) +#define glXReleaseVideoDeviceNV GLXEW_GET_FUN(__glewXReleaseVideoDeviceNV) +#define glXReleaseVideoImageNV GLXEW_GET_FUN(__glewXReleaseVideoImageNV) +#define glXSendPbufferToVideoNV GLXEW_GET_FUN(__glewXSendPbufferToVideoNV) + +#define GLXEW_NV_video_output GLXEW_GET_VAR(__GLXEW_NV_video_output) + +#endif /* GLX_NV_video_output */ + +/* -------------------------- GLX_OML_swap_method -------------------------- */ + +#ifndef GLX_OML_swap_method +#define GLX_OML_swap_method 1 + +#define GLX_SWAP_METHOD_OML 0x8060 +#define GLX_SWAP_EXCHANGE_OML 0x8061 +#define GLX_SWAP_COPY_OML 0x8062 +#define GLX_SWAP_UNDEFINED_OML 0x8063 + +#define GLXEW_OML_swap_method GLXEW_GET_VAR(__GLXEW_OML_swap_method) + +#endif /* GLX_OML_swap_method */ + +/* -------------------------- GLX_OML_sync_control ------------------------- */ + +#if !defined(GLX_OML_sync_control) && defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +#include <inttypes.h> +#define GLX_OML_sync_control 1 + +typedef Bool ( * PFNGLXGETMSCRATEOMLPROC) (Display* dpy, GLXDrawable drawable, int32_t* numerator, int32_t* denominator); +typedef Bool ( * PFNGLXGETSYNCVALUESOMLPROC) (Display* dpy, GLXDrawable drawable, int64_t* ust, int64_t* msc, int64_t* sbc); +typedef int64_t ( * PFNGLXSWAPBUFFERSMSCOMLPROC) (Display* dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder); +typedef Bool ( * PFNGLXWAITFORMSCOMLPROC) (Display* dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder, int64_t* ust, int64_t* msc, int64_t* sbc); +typedef Bool ( * PFNGLXWAITFORSBCOMLPROC) (Display* dpy, GLXDrawable drawable, int64_t target_sbc, int64_t* ust, int64_t* msc, int64_t* sbc); + +#define glXGetMscRateOML GLXEW_GET_FUN(__glewXGetMscRateOML) +#define glXGetSyncValuesOML GLXEW_GET_FUN(__glewXGetSyncValuesOML) +#define glXSwapBuffersMscOML GLXEW_GET_FUN(__glewXSwapBuffersMscOML) +#define glXWaitForMscOML GLXEW_GET_FUN(__glewXWaitForMscOML) +#define glXWaitForSbcOML GLXEW_GET_FUN(__glewXWaitForSbcOML) + +#define GLXEW_OML_sync_control GLXEW_GET_VAR(__GLXEW_OML_sync_control) + +#endif /* GLX_OML_sync_control */ + +/* ------------------------ GLX_SGIS_blended_overlay ----------------------- */ + +#ifndef GLX_SGIS_blended_overlay +#define GLX_SGIS_blended_overlay 1 + +#define GLX_BLENDED_RGBA_SGIS 0x8025 + +#define GLXEW_SGIS_blended_overlay GLXEW_GET_VAR(__GLXEW_SGIS_blended_overlay) + +#endif /* GLX_SGIS_blended_overlay */ + +/* -------------------------- GLX_SGIS_color_range ------------------------- */ + +#ifndef GLX_SGIS_color_range +#define GLX_SGIS_color_range 1 + +#define GLX_MIN_RED_SGIS 0 +#define GLX_MAX_GREEN_SGIS 0 +#define GLX_MIN_BLUE_SGIS 0 +#define GLX_MAX_ALPHA_SGIS 0 +#define GLX_MIN_GREEN_SGIS 0 +#define GLX_MIN_ALPHA_SGIS 0 +#define GLX_MAX_RED_SGIS 0 +#define GLX_EXTENDED_RANGE_SGIS 0 +#define GLX_MAX_BLUE_SGIS 0 + +#define GLXEW_SGIS_color_range GLXEW_GET_VAR(__GLXEW_SGIS_color_range) + +#endif /* GLX_SGIS_color_range */ + +/* -------------------------- GLX_SGIS_multisample ------------------------- */ + +#ifndef GLX_SGIS_multisample +#define GLX_SGIS_multisample 1 + +#define GLX_SAMPLE_BUFFERS_SGIS 100000 +#define GLX_SAMPLES_SGIS 100001 + +#define GLXEW_SGIS_multisample GLXEW_GET_VAR(__GLXEW_SGIS_multisample) + +#endif /* GLX_SGIS_multisample */ + +/* ---------------------- GLX_SGIS_shared_multisample ---------------------- */ + +#ifndef GLX_SGIS_shared_multisample +#define GLX_SGIS_shared_multisample 1 + +#define GLX_MULTISAMPLE_SUB_RECT_WIDTH_SGIS 0x8026 +#define GLX_MULTISAMPLE_SUB_RECT_HEIGHT_SGIS 0x8027 + +#define GLXEW_SGIS_shared_multisample GLXEW_GET_VAR(__GLXEW_SGIS_shared_multisample) + +#endif /* GLX_SGIS_shared_multisample */ + +/* --------------------------- GLX_SGIX_fbconfig --------------------------- */ + +#ifndef GLX_SGIX_fbconfig +#define GLX_SGIX_fbconfig 1 + +#define GLX_WINDOW_BIT_SGIX 0x00000001 +#define GLX_RGBA_BIT_SGIX 0x00000001 +#define GLX_PIXMAP_BIT_SGIX 0x00000002 +#define GLX_COLOR_INDEX_BIT_SGIX 0x00000002 +#define GLX_SCREEN_EXT 0x800C +#define GLX_DRAWABLE_TYPE_SGIX 0x8010 +#define GLX_RENDER_TYPE_SGIX 0x8011 +#define GLX_X_RENDERABLE_SGIX 0x8012 +#define GLX_FBCONFIG_ID_SGIX 0x8013 +#define GLX_RGBA_TYPE_SGIX 0x8014 +#define GLX_COLOR_INDEX_TYPE_SGIX 0x8015 + +typedef XID GLXFBConfigIDSGIX; +typedef struct __GLXFBConfigRec *GLXFBConfigSGIX; + +typedef GLXFBConfigSGIX* ( * PFNGLXCHOOSEFBCONFIGSGIXPROC) (Display *dpy, int screen, const int *attrib_list, int *nelements); +typedef GLXContext ( * PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC) (Display* dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct); +typedef GLXPixmap ( * PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC) (Display* dpy, GLXFBConfig config, Pixmap pixmap); +typedef int ( * PFNGLXGETFBCONFIGATTRIBSGIXPROC) (Display* dpy, GLXFBConfigSGIX config, int attribute, int *value); +typedef GLXFBConfigSGIX ( * PFNGLXGETFBCONFIGFROMVISUALSGIXPROC) (Display* dpy, XVisualInfo *vis); +typedef XVisualInfo* ( * PFNGLXGETVISUALFROMFBCONFIGSGIXPROC) (Display *dpy, GLXFBConfig config); + +#define glXChooseFBConfigSGIX GLXEW_GET_FUN(__glewXChooseFBConfigSGIX) +#define glXCreateContextWithConfigSGIX GLXEW_GET_FUN(__glewXCreateContextWithConfigSGIX) +#define glXCreateGLXPixmapWithConfigSGIX GLXEW_GET_FUN(__glewXCreateGLXPixmapWithConfigSGIX) +#define glXGetFBConfigAttribSGIX GLXEW_GET_FUN(__glewXGetFBConfigAttribSGIX) +#define glXGetFBConfigFromVisualSGIX GLXEW_GET_FUN(__glewXGetFBConfigFromVisualSGIX) +#define glXGetVisualFromFBConfigSGIX GLXEW_GET_FUN(__glewXGetVisualFromFBConfigSGIX) + +#define GLXEW_SGIX_fbconfig GLXEW_GET_VAR(__GLXEW_SGIX_fbconfig) + +#endif /* GLX_SGIX_fbconfig */ + +/* --------------------------- GLX_SGIX_hyperpipe -------------------------- */ + +#ifndef GLX_SGIX_hyperpipe +#define GLX_SGIX_hyperpipe 1 + +#define GLX_HYPERPIPE_DISPLAY_PIPE_SGIX 0x00000001 +#define GLX_PIPE_RECT_SGIX 0x00000001 +#define GLX_PIPE_RECT_LIMITS_SGIX 0x00000002 +#define GLX_HYPERPIPE_RENDER_PIPE_SGIX 0x00000002 +#define GLX_HYPERPIPE_STEREO_SGIX 0x00000003 +#define GLX_HYPERPIPE_PIXEL_AVERAGE_SGIX 0x00000004 +#define GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX 80 +#define GLX_BAD_HYPERPIPE_CONFIG_SGIX 91 +#define GLX_BAD_HYPERPIPE_SGIX 92 +#define GLX_HYPERPIPE_ID_SGIX 0x8030 + +typedef struct { + char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]; + int networkId; +} GLXHyperpipeNetworkSGIX; +typedef struct { + char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]; + int XOrigin; + int YOrigin; + int maxHeight; + int maxWidth; +} GLXPipeRectLimits; +typedef struct { + char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]; + int channel; + unsigned int participationType; + int timeSlice; +} GLXHyperpipeConfigSGIX; +typedef struct { + char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]; + int srcXOrigin; + int srcYOrigin; + int srcWidth; + int srcHeight; + int destXOrigin; + int destYOrigin; + int destWidth; + int destHeight; +} GLXPipeRect; + +typedef int ( * PFNGLXBINDHYPERPIPESGIXPROC) (Display *dpy, int hpId); +typedef int ( * PFNGLXDESTROYHYPERPIPECONFIGSGIXPROC) (Display *dpy, int hpId); +typedef int ( * PFNGLXHYPERPIPEATTRIBSGIXPROC) (Display *dpy, int timeSlice, int attrib, int size, void *attribList); +typedef int ( * PFNGLXHYPERPIPECONFIGSGIXPROC) (Display *dpy, int networkId, int npipes, GLXHyperpipeConfigSGIX *cfg, int *hpId); +typedef int ( * PFNGLXQUERYHYPERPIPEATTRIBSGIXPROC) (Display *dpy, int timeSlice, int attrib, int size, void *returnAttribList); +typedef int ( * PFNGLXQUERYHYPERPIPEBESTATTRIBSGIXPROC) (Display *dpy, int timeSlice, int attrib, int size, void *attribList, void *returnAttribList); +typedef GLXHyperpipeConfigSGIX * ( * PFNGLXQUERYHYPERPIPECONFIGSGIXPROC) (Display *dpy, int hpId, int *npipes); +typedef GLXHyperpipeNetworkSGIX * ( * PFNGLXQUERYHYPERPIPENETWORKSGIXPROC) (Display *dpy, int *npipes); + +#define glXBindHyperpipeSGIX GLXEW_GET_FUN(__glewXBindHyperpipeSGIX) +#define glXDestroyHyperpipeConfigSGIX GLXEW_GET_FUN(__glewXDestroyHyperpipeConfigSGIX) +#define glXHyperpipeAttribSGIX GLXEW_GET_FUN(__glewXHyperpipeAttribSGIX) +#define glXHyperpipeConfigSGIX GLXEW_GET_FUN(__glewXHyperpipeConfigSGIX) +#define glXQueryHyperpipeAttribSGIX GLXEW_GET_FUN(__glewXQueryHyperpipeAttribSGIX) +#define glXQueryHyperpipeBestAttribSGIX GLXEW_GET_FUN(__glewXQueryHyperpipeBestAttribSGIX) +#define glXQueryHyperpipeConfigSGIX GLXEW_GET_FUN(__glewXQueryHyperpipeConfigSGIX) +#define glXQueryHyperpipeNetworkSGIX GLXEW_GET_FUN(__glewXQueryHyperpipeNetworkSGIX) + +#define GLXEW_SGIX_hyperpipe GLXEW_GET_VAR(__GLXEW_SGIX_hyperpipe) + +#endif /* GLX_SGIX_hyperpipe */ + +/* ---------------------------- GLX_SGIX_pbuffer --------------------------- */ + +#ifndef GLX_SGIX_pbuffer +#define GLX_SGIX_pbuffer 1 + +#define GLX_FRONT_LEFT_BUFFER_BIT_SGIX 0x00000001 +#define GLX_FRONT_RIGHT_BUFFER_BIT_SGIX 0x00000002 +#define GLX_PBUFFER_BIT_SGIX 0x00000004 +#define GLX_BACK_LEFT_BUFFER_BIT_SGIX 0x00000004 +#define GLX_BACK_RIGHT_BUFFER_BIT_SGIX 0x00000008 +#define GLX_AUX_BUFFERS_BIT_SGIX 0x00000010 +#define GLX_DEPTH_BUFFER_BIT_SGIX 0x00000020 +#define GLX_STENCIL_BUFFER_BIT_SGIX 0x00000040 +#define GLX_ACCUM_BUFFER_BIT_SGIX 0x00000080 +#define GLX_SAMPLE_BUFFERS_BIT_SGIX 0x00000100 +#define GLX_MAX_PBUFFER_WIDTH_SGIX 0x8016 +#define GLX_MAX_PBUFFER_HEIGHT_SGIX 0x8017 +#define GLX_MAX_PBUFFER_PIXELS_SGIX 0x8018 +#define GLX_OPTIMAL_PBUFFER_WIDTH_SGIX 0x8019 +#define GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX 0x801A +#define GLX_PRESERVED_CONTENTS_SGIX 0x801B +#define GLX_LARGEST_PBUFFER_SGIX 0x801C +#define GLX_WIDTH_SGIX 0x801D +#define GLX_HEIGHT_SGIX 0x801E +#define GLX_EVENT_MASK_SGIX 0x801F +#define GLX_DAMAGED_SGIX 0x8020 +#define GLX_SAVED_SGIX 0x8021 +#define GLX_WINDOW_SGIX 0x8022 +#define GLX_PBUFFER_SGIX 0x8023 +#define GLX_BUFFER_CLOBBER_MASK_SGIX 0x08000000 + +typedef XID GLXPbufferSGIX; +typedef struct { int type; unsigned long serial; Bool send_event; Display *display; GLXDrawable drawable; int event_type; int draw_type; unsigned int mask; int x, y; int width, height; int count; } GLXBufferClobberEventSGIX; + +typedef GLXPbuffer ( * PFNGLXCREATEGLXPBUFFERSGIXPROC) (Display* dpy, GLXFBConfig config, unsigned int width, unsigned int height, int *attrib_list); +typedef void ( * PFNGLXDESTROYGLXPBUFFERSGIXPROC) (Display* dpy, GLXPbuffer pbuf); +typedef void ( * PFNGLXGETSELECTEDEVENTSGIXPROC) (Display* dpy, GLXDrawable drawable, unsigned long *mask); +typedef void ( * PFNGLXQUERYGLXPBUFFERSGIXPROC) (Display* dpy, GLXPbuffer pbuf, int attribute, unsigned int *value); +typedef void ( * PFNGLXSELECTEVENTSGIXPROC) (Display* dpy, GLXDrawable drawable, unsigned long mask); + +#define glXCreateGLXPbufferSGIX GLXEW_GET_FUN(__glewXCreateGLXPbufferSGIX) +#define glXDestroyGLXPbufferSGIX GLXEW_GET_FUN(__glewXDestroyGLXPbufferSGIX) +#define glXGetSelectedEventSGIX GLXEW_GET_FUN(__glewXGetSelectedEventSGIX) +#define glXQueryGLXPbufferSGIX GLXEW_GET_FUN(__glewXQueryGLXPbufferSGIX) +#define glXSelectEventSGIX GLXEW_GET_FUN(__glewXSelectEventSGIX) + +#define GLXEW_SGIX_pbuffer GLXEW_GET_VAR(__GLXEW_SGIX_pbuffer) + +#endif /* GLX_SGIX_pbuffer */ + +/* ------------------------- GLX_SGIX_swap_barrier ------------------------- */ + +#ifndef GLX_SGIX_swap_barrier +#define GLX_SGIX_swap_barrier 1 + +typedef void ( * PFNGLXBINDSWAPBARRIERSGIXPROC) (Display *dpy, GLXDrawable drawable, int barrier); +typedef Bool ( * PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC) (Display *dpy, int screen, int *max); + +#define glXBindSwapBarrierSGIX GLXEW_GET_FUN(__glewXBindSwapBarrierSGIX) +#define glXQueryMaxSwapBarriersSGIX GLXEW_GET_FUN(__glewXQueryMaxSwapBarriersSGIX) + +#define GLXEW_SGIX_swap_barrier GLXEW_GET_VAR(__GLXEW_SGIX_swap_barrier) + +#endif /* GLX_SGIX_swap_barrier */ + +/* -------------------------- GLX_SGIX_swap_group -------------------------- */ + +#ifndef GLX_SGIX_swap_group +#define GLX_SGIX_swap_group 1 + +typedef void ( * PFNGLXJOINSWAPGROUPSGIXPROC) (Display *dpy, GLXDrawable drawable, GLXDrawable member); + +#define glXJoinSwapGroupSGIX GLXEW_GET_FUN(__glewXJoinSwapGroupSGIX) + +#define GLXEW_SGIX_swap_group GLXEW_GET_VAR(__GLXEW_SGIX_swap_group) + +#endif /* GLX_SGIX_swap_group */ + +/* ------------------------- GLX_SGIX_video_resize ------------------------- */ + +#ifndef GLX_SGIX_video_resize +#define GLX_SGIX_video_resize 1 + +#define GLX_SYNC_FRAME_SGIX 0x00000000 +#define GLX_SYNC_SWAP_SGIX 0x00000001 + +typedef int ( * PFNGLXBINDCHANNELTOWINDOWSGIXPROC) (Display* display, int screen, int channel, Window window); +typedef int ( * PFNGLXCHANNELRECTSGIXPROC) (Display* display, int screen, int channel, int x, int y, int w, int h); +typedef int ( * PFNGLXCHANNELRECTSYNCSGIXPROC) (Display* display, int screen, int channel, GLenum synctype); +typedef int ( * PFNGLXQUERYCHANNELDELTASSGIXPROC) (Display* display, int screen, int channel, int *x, int *y, int *w, int *h); +typedef int ( * PFNGLXQUERYCHANNELRECTSGIXPROC) (Display* display, int screen, int channel, int *dx, int *dy, int *dw, int *dh); + +#define glXBindChannelToWindowSGIX GLXEW_GET_FUN(__glewXBindChannelToWindowSGIX) +#define glXChannelRectSGIX GLXEW_GET_FUN(__glewXChannelRectSGIX) +#define glXChannelRectSyncSGIX GLXEW_GET_FUN(__glewXChannelRectSyncSGIX) +#define glXQueryChannelDeltasSGIX GLXEW_GET_FUN(__glewXQueryChannelDeltasSGIX) +#define glXQueryChannelRectSGIX GLXEW_GET_FUN(__glewXQueryChannelRectSGIX) + +#define GLXEW_SGIX_video_resize GLXEW_GET_VAR(__GLXEW_SGIX_video_resize) + +#endif /* GLX_SGIX_video_resize */ + +/* ---------------------- GLX_SGIX_visual_select_group --------------------- */ + +#ifndef GLX_SGIX_visual_select_group +#define GLX_SGIX_visual_select_group 1 + +#define GLX_VISUAL_SELECT_GROUP_SGIX 0x8028 + +#define GLXEW_SGIX_visual_select_group GLXEW_GET_VAR(__GLXEW_SGIX_visual_select_group) + +#endif /* GLX_SGIX_visual_select_group */ + +/* ---------------------------- GLX_SGI_cushion ---------------------------- */ + +#ifndef GLX_SGI_cushion +#define GLX_SGI_cushion 1 + +typedef void ( * PFNGLXCUSHIONSGIPROC) (Display* dpy, Window window, float cushion); + +#define glXCushionSGI GLXEW_GET_FUN(__glewXCushionSGI) + +#define GLXEW_SGI_cushion GLXEW_GET_VAR(__GLXEW_SGI_cushion) + +#endif /* GLX_SGI_cushion */ + +/* ----------------------- GLX_SGI_make_current_read ----------------------- */ + +#ifndef GLX_SGI_make_current_read +#define GLX_SGI_make_current_read 1 + +typedef GLXDrawable ( * PFNGLXGETCURRENTREADDRAWABLESGIPROC) (void); +typedef Bool ( * PFNGLXMAKECURRENTREADSGIPROC) (Display* dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx); + +#define glXGetCurrentReadDrawableSGI GLXEW_GET_FUN(__glewXGetCurrentReadDrawableSGI) +#define glXMakeCurrentReadSGI GLXEW_GET_FUN(__glewXMakeCurrentReadSGI) + +#define GLXEW_SGI_make_current_read GLXEW_GET_VAR(__GLXEW_SGI_make_current_read) + +#endif /* GLX_SGI_make_current_read */ + +/* -------------------------- GLX_SGI_swap_control ------------------------- */ + +#ifndef GLX_SGI_swap_control +#define GLX_SGI_swap_control 1 + +typedef int ( * PFNGLXSWAPINTERVALSGIPROC) (int interval); + +#define glXSwapIntervalSGI GLXEW_GET_FUN(__glewXSwapIntervalSGI) + +#define GLXEW_SGI_swap_control GLXEW_GET_VAR(__GLXEW_SGI_swap_control) + +#endif /* GLX_SGI_swap_control */ + +/* --------------------------- GLX_SGI_video_sync -------------------------- */ + +#ifndef GLX_SGI_video_sync +#define GLX_SGI_video_sync 1 + +typedef int ( * PFNGLXGETVIDEOSYNCSGIPROC) (uint* count); +typedef int ( * PFNGLXWAITVIDEOSYNCSGIPROC) (int divisor, int remainder, unsigned int* count); + +#define glXGetVideoSyncSGI GLXEW_GET_FUN(__glewXGetVideoSyncSGI) +#define glXWaitVideoSyncSGI GLXEW_GET_FUN(__glewXWaitVideoSyncSGI) + +#define GLXEW_SGI_video_sync GLXEW_GET_VAR(__GLXEW_SGI_video_sync) + +#endif /* GLX_SGI_video_sync */ + +/* --------------------- GLX_SUN_get_transparent_index --------------------- */ + +#ifndef GLX_SUN_get_transparent_index +#define GLX_SUN_get_transparent_index 1 + +typedef Status ( * PFNGLXGETTRANSPARENTINDEXSUNPROC) (Display* dpy, Window overlay, Window underlay, unsigned long *pTransparentIndex); + +#define glXGetTransparentIndexSUN GLXEW_GET_FUN(__glewXGetTransparentIndexSUN) + +#define GLXEW_SUN_get_transparent_index GLXEW_GET_VAR(__GLXEW_SUN_get_transparent_index) + +#endif /* GLX_SUN_get_transparent_index */ + +/* -------------------------- GLX_SUN_video_resize ------------------------- */ + +#ifndef GLX_SUN_video_resize +#define GLX_SUN_video_resize 1 + +#define GLX_VIDEO_RESIZE_SUN 0x8171 +#define GL_VIDEO_RESIZE_COMPENSATION_SUN 0x85CD + +typedef int ( * PFNGLXGETVIDEORESIZESUNPROC) (Display* display, GLXDrawable window, float* factor); +typedef int ( * PFNGLXVIDEORESIZESUNPROC) (Display* display, GLXDrawable window, float factor); + +#define glXGetVideoResizeSUN GLXEW_GET_FUN(__glewXGetVideoResizeSUN) +#define glXVideoResizeSUN GLXEW_GET_FUN(__glewXVideoResizeSUN) + +#define GLXEW_SUN_video_resize GLXEW_GET_VAR(__GLXEW_SUN_video_resize) + +#endif /* GLX_SUN_video_resize */ + +/* ------------------------------------------------------------------------- */ + +#ifdef GLEW_MX +#define GLXEW_EXPORT +#else +#define GLXEW_EXPORT extern +#endif /* GLEW_MX */ + +extern PFNGLXGETCURRENTDISPLAYPROC __glewXGetCurrentDisplay; + +extern PFNGLXCHOOSEFBCONFIGPROC __glewXChooseFBConfig; +extern PFNGLXCREATENEWCONTEXTPROC __glewXCreateNewContext; +extern PFNGLXCREATEPBUFFERPROC __glewXCreatePbuffer; +extern PFNGLXCREATEPIXMAPPROC __glewXCreatePixmap; +extern PFNGLXCREATEWINDOWPROC __glewXCreateWindow; +extern PFNGLXDESTROYPBUFFERPROC __glewXDestroyPbuffer; +extern PFNGLXDESTROYPIXMAPPROC __glewXDestroyPixmap; +extern PFNGLXDESTROYWINDOWPROC __glewXDestroyWindow; +extern PFNGLXGETCURRENTREADDRAWABLEPROC __glewXGetCurrentReadDrawable; +extern PFNGLXGETFBCONFIGATTRIBPROC __glewXGetFBConfigAttrib; +extern PFNGLXGETFBCONFIGSPROC __glewXGetFBConfigs; +extern PFNGLXGETSELECTEDEVENTPROC __glewXGetSelectedEvent; +extern PFNGLXGETVISUALFROMFBCONFIGPROC __glewXGetVisualFromFBConfig; +extern PFNGLXMAKECONTEXTCURRENTPROC __glewXMakeContextCurrent; +extern PFNGLXQUERYCONTEXTPROC __glewXQueryContext; +extern PFNGLXQUERYDRAWABLEPROC __glewXQueryDrawable; +extern PFNGLXSELECTEVENTPROC __glewXSelectEvent; + +extern PFNGLXCREATECONTEXTATTRIBSARBPROC __glewXCreateContextAttribsARB; + +extern PFNGLXBINDTEXIMAGEATIPROC __glewXBindTexImageATI; +extern PFNGLXDRAWABLEATTRIBATIPROC __glewXDrawableAttribATI; +extern PFNGLXRELEASETEXIMAGEATIPROC __glewXReleaseTexImageATI; + +extern PFNGLXFREECONTEXTEXTPROC __glewXFreeContextEXT; +extern PFNGLXGETCONTEXTIDEXTPROC __glewXGetContextIDEXT; +extern PFNGLXIMPORTCONTEXTEXTPROC __glewXImportContextEXT; +extern PFNGLXQUERYCONTEXTINFOEXTPROC __glewXQueryContextInfoEXT; + +extern PFNGLXBINDTEXIMAGEEXTPROC __glewXBindTexImageEXT; +extern PFNGLXRELEASETEXIMAGEEXTPROC __glewXReleaseTexImageEXT; + +extern PFNGLXGETAGPOFFSETMESAPROC __glewXGetAGPOffsetMESA; + +extern PFNGLXCOPYSUBBUFFERMESAPROC __glewXCopySubBufferMESA; + +extern PFNGLXCREATEGLXPIXMAPMESAPROC __glewXCreateGLXPixmapMESA; + +extern PFNGLXRELEASEBUFFERSMESAPROC __glewXReleaseBuffersMESA; + +extern PFNGLXSET3DFXMODEMESAPROC __glewXSet3DfxModeMESA; + +extern PFNGLXBINDVIDEODEVICENVPROC __glewXBindVideoDeviceNV; +extern PFNGLXENUMERATEVIDEODEVICESNVPROC __glewXEnumerateVideoDevicesNV; + +extern PFNGLXBINDSWAPBARRIERNVPROC __glewXBindSwapBarrierNV; +extern PFNGLXJOINSWAPGROUPNVPROC __glewXJoinSwapGroupNV; +extern PFNGLXQUERYFRAMECOUNTNVPROC __glewXQueryFrameCountNV; +extern PFNGLXQUERYMAXSWAPGROUPSNVPROC __glewXQueryMaxSwapGroupsNV; +extern PFNGLXQUERYSWAPGROUPNVPROC __glewXQuerySwapGroupNV; +extern PFNGLXRESETFRAMECOUNTNVPROC __glewXResetFrameCountNV; + +extern PFNGLXALLOCATEMEMORYNVPROC __glewXAllocateMemoryNV; +extern PFNGLXFREEMEMORYNVPROC __glewXFreeMemoryNV; + +extern PFNGLXBINDVIDEOIMAGENVPROC __glewXBindVideoImageNV; +extern PFNGLXGETVIDEODEVICENVPROC __glewXGetVideoDeviceNV; +extern PFNGLXGETVIDEOINFONVPROC __glewXGetVideoInfoNV; +extern PFNGLXRELEASEVIDEODEVICENVPROC __glewXReleaseVideoDeviceNV; +extern PFNGLXRELEASEVIDEOIMAGENVPROC __glewXReleaseVideoImageNV; +extern PFNGLXSENDPBUFFERTOVIDEONVPROC __glewXSendPbufferToVideoNV; + +#ifdef GLX_OML_sync_control +extern PFNGLXGETMSCRATEOMLPROC __glewXGetMscRateOML; +extern PFNGLXGETSYNCVALUESOMLPROC __glewXGetSyncValuesOML; +extern PFNGLXSWAPBUFFERSMSCOMLPROC __glewXSwapBuffersMscOML; +extern PFNGLXWAITFORMSCOMLPROC __glewXWaitForMscOML; +extern PFNGLXWAITFORSBCOMLPROC __glewXWaitForSbcOML; +#endif + +extern PFNGLXCHOOSEFBCONFIGSGIXPROC __glewXChooseFBConfigSGIX; +extern PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC __glewXCreateContextWithConfigSGIX; +extern PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC __glewXCreateGLXPixmapWithConfigSGIX; +extern PFNGLXGETFBCONFIGATTRIBSGIXPROC __glewXGetFBConfigAttribSGIX; +extern PFNGLXGETFBCONFIGFROMVISUALSGIXPROC __glewXGetFBConfigFromVisualSGIX; +extern PFNGLXGETVISUALFROMFBCONFIGSGIXPROC __glewXGetVisualFromFBConfigSGIX; + +extern PFNGLXBINDHYPERPIPESGIXPROC __glewXBindHyperpipeSGIX; +extern PFNGLXDESTROYHYPERPIPECONFIGSGIXPROC __glewXDestroyHyperpipeConfigSGIX; +extern PFNGLXHYPERPIPEATTRIBSGIXPROC __glewXHyperpipeAttribSGIX; +extern PFNGLXHYPERPIPECONFIGSGIXPROC __glewXHyperpipeConfigSGIX; +extern PFNGLXQUERYHYPERPIPEATTRIBSGIXPROC __glewXQueryHyperpipeAttribSGIX; +extern PFNGLXQUERYHYPERPIPEBESTATTRIBSGIXPROC __glewXQueryHyperpipeBestAttribSGIX; +extern PFNGLXQUERYHYPERPIPECONFIGSGIXPROC __glewXQueryHyperpipeConfigSGIX; +extern PFNGLXQUERYHYPERPIPENETWORKSGIXPROC __glewXQueryHyperpipeNetworkSGIX; + +extern PFNGLXCREATEGLXPBUFFERSGIXPROC __glewXCreateGLXPbufferSGIX; +extern PFNGLXDESTROYGLXPBUFFERSGIXPROC __glewXDestroyGLXPbufferSGIX; +extern PFNGLXGETSELECTEDEVENTSGIXPROC __glewXGetSelectedEventSGIX; +extern PFNGLXQUERYGLXPBUFFERSGIXPROC __glewXQueryGLXPbufferSGIX; +extern PFNGLXSELECTEVENTSGIXPROC __glewXSelectEventSGIX; + +extern PFNGLXBINDSWAPBARRIERSGIXPROC __glewXBindSwapBarrierSGIX; +extern PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC __glewXQueryMaxSwapBarriersSGIX; + +extern PFNGLXJOINSWAPGROUPSGIXPROC __glewXJoinSwapGroupSGIX; + +extern PFNGLXBINDCHANNELTOWINDOWSGIXPROC __glewXBindChannelToWindowSGIX; +extern PFNGLXCHANNELRECTSGIXPROC __glewXChannelRectSGIX; +extern PFNGLXCHANNELRECTSYNCSGIXPROC __glewXChannelRectSyncSGIX; +extern PFNGLXQUERYCHANNELDELTASSGIXPROC __glewXQueryChannelDeltasSGIX; +extern PFNGLXQUERYCHANNELRECTSGIXPROC __glewXQueryChannelRectSGIX; + +extern PFNGLXCUSHIONSGIPROC __glewXCushionSGI; + +extern PFNGLXGETCURRENTREADDRAWABLESGIPROC __glewXGetCurrentReadDrawableSGI; +extern PFNGLXMAKECURRENTREADSGIPROC __glewXMakeCurrentReadSGI; + +extern PFNGLXSWAPINTERVALSGIPROC __glewXSwapIntervalSGI; + +extern PFNGLXGETVIDEOSYNCSGIPROC __glewXGetVideoSyncSGI; +extern PFNGLXWAITVIDEOSYNCSGIPROC __glewXWaitVideoSyncSGI; + +extern PFNGLXGETTRANSPARENTINDEXSUNPROC __glewXGetTransparentIndexSUN; + +extern PFNGLXGETVIDEORESIZESUNPROC __glewXGetVideoResizeSUN; +extern PFNGLXVIDEORESIZESUNPROC __glewXVideoResizeSUN; + +#if defined(GLEW_MX) +struct GLXEWContextStruct +{ +#endif /* GLEW_MX */ + +GLXEW_EXPORT GLboolean __GLXEW_VERSION_1_0; +GLXEW_EXPORT GLboolean __GLXEW_VERSION_1_1; +GLXEW_EXPORT GLboolean __GLXEW_VERSION_1_2; +GLXEW_EXPORT GLboolean __GLXEW_VERSION_1_3; +GLXEW_EXPORT GLboolean __GLXEW_VERSION_1_4; +GLXEW_EXPORT GLboolean __GLXEW_3DFX_multisample; +GLXEW_EXPORT GLboolean __GLXEW_ARB_create_context; +GLXEW_EXPORT GLboolean __GLXEW_ARB_fbconfig_float; +GLXEW_EXPORT GLboolean __GLXEW_ARB_framebuffer_sRGB; +GLXEW_EXPORT GLboolean __GLXEW_ARB_get_proc_address; +GLXEW_EXPORT GLboolean __GLXEW_ARB_multisample; +GLXEW_EXPORT GLboolean __GLXEW_ATI_pixel_format_float; +GLXEW_EXPORT GLboolean __GLXEW_ATI_render_texture; +GLXEW_EXPORT GLboolean __GLXEW_EXT_fbconfig_packed_float; +GLXEW_EXPORT GLboolean __GLXEW_EXT_framebuffer_sRGB; +GLXEW_EXPORT GLboolean __GLXEW_EXT_import_context; +GLXEW_EXPORT GLboolean __GLXEW_EXT_scene_marker; +GLXEW_EXPORT GLboolean __GLXEW_EXT_texture_from_pixmap; +GLXEW_EXPORT GLboolean __GLXEW_EXT_visual_info; +GLXEW_EXPORT GLboolean __GLXEW_EXT_visual_rating; +GLXEW_EXPORT GLboolean __GLXEW_MESA_agp_offset; +GLXEW_EXPORT GLboolean __GLXEW_MESA_copy_sub_buffer; +GLXEW_EXPORT GLboolean __GLXEW_MESA_pixmap_colormap; +GLXEW_EXPORT GLboolean __GLXEW_MESA_release_buffers; +GLXEW_EXPORT GLboolean __GLXEW_MESA_set_3dfx_mode; +GLXEW_EXPORT GLboolean __GLXEW_NV_float_buffer; +GLXEW_EXPORT GLboolean __GLXEW_NV_present_video; +GLXEW_EXPORT GLboolean __GLXEW_NV_swap_group; +GLXEW_EXPORT GLboolean __GLXEW_NV_vertex_array_range; +GLXEW_EXPORT GLboolean __GLXEW_NV_video_output; +GLXEW_EXPORT GLboolean __GLXEW_OML_swap_method; +GLXEW_EXPORT GLboolean __GLXEW_OML_sync_control; +GLXEW_EXPORT GLboolean __GLXEW_SGIS_blended_overlay; +GLXEW_EXPORT GLboolean __GLXEW_SGIS_color_range; +GLXEW_EXPORT GLboolean __GLXEW_SGIS_multisample; +GLXEW_EXPORT GLboolean __GLXEW_SGIS_shared_multisample; +GLXEW_EXPORT GLboolean __GLXEW_SGIX_fbconfig; +GLXEW_EXPORT GLboolean __GLXEW_SGIX_hyperpipe; +GLXEW_EXPORT GLboolean __GLXEW_SGIX_pbuffer; +GLXEW_EXPORT GLboolean __GLXEW_SGIX_swap_barrier; +GLXEW_EXPORT GLboolean __GLXEW_SGIX_swap_group; +GLXEW_EXPORT GLboolean __GLXEW_SGIX_video_resize; +GLXEW_EXPORT GLboolean __GLXEW_SGIX_visual_select_group; +GLXEW_EXPORT GLboolean __GLXEW_SGI_cushion; +GLXEW_EXPORT GLboolean __GLXEW_SGI_make_current_read; +GLXEW_EXPORT GLboolean __GLXEW_SGI_swap_control; +GLXEW_EXPORT GLboolean __GLXEW_SGI_video_sync; +GLXEW_EXPORT GLboolean __GLXEW_SUN_get_transparent_index; +GLXEW_EXPORT GLboolean __GLXEW_SUN_video_resize; + +#ifdef GLEW_MX +}; /* GLXEWContextStruct */ +#endif /* GLEW_MX */ + +/* ------------------------------------------------------------------------ */ + +#ifdef GLEW_MX + +typedef struct GLXEWContextStruct GLXEWContext; +extern GLenum glxewContextInit (GLXEWContext* ctx); +extern GLboolean glxewContextIsSupported (GLXEWContext* ctx, const char* name); + +#define glxewInit() glxewContextInit(glxewGetContext()) +#define glxewIsSupported(x) glxewContextIsSupported(glxewGetContext(), x) + +#define GLXEW_GET_VAR(x) (*(const GLboolean*)&(glxewGetContext()->x)) +#define GLXEW_GET_FUN(x) x + +#else /* GLEW_MX */ + +#define GLXEW_GET_VAR(x) (*(const GLboolean*)&x) +#define GLXEW_GET_FUN(x) x + +extern GLboolean glxewIsSupported (const char* name); + +#endif /* GLEW_MX */ + +extern GLboolean glxewGetExtension (const char* name); + +#ifdef __cplusplus +} +#endif + +#endif /* __glxew_h__ */ diff --git a/mod/pub.mod/glew.mod/GL/wglew.h b/mod/pub.mod/glew.mod/GL/wglew.h new file mode 100644 index 0000000..2eaad36 --- /dev/null +++ b/mod/pub.mod/glew.mod/GL/wglew.h @@ -0,0 +1,1165 @@ +/* +** The OpenGL Extension Wrangler Library +** Copyright (C) 2002-2008, Milan Ikits <milan ikits[]ieee org> +** Copyright (C) 2002-2008, Marcelo E. Magallon <mmagallo[]debian org> +** Copyright (C) 2002, Lev Povalahev +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are met: +** +** * Redistributions of source code must retain the above copyright notice, +** this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright notice, +** this list of conditions and the following disclaimer in the documentation +** and/or other materials provided with the distribution. +** * The name of the author may be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +** THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/* +** Copyright (c) 2007 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +#ifndef __wglew_h__ +#define __wglew_h__ +#define __WGLEW_H__ + +#ifdef __wglext_h_ +#error wglext.h included before wglew.h +#endif + +#define __wglext_h_ + +#if !defined(APIENTRY) && !defined(__CYGWIN__) +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN 1 +# endif +#include <windows.h> +#endif + +/* + * GLEW_STATIC needs to be set when using the static version. + * GLEW_BUILD is set when building the DLL version. + */ +#ifdef GLEW_STATIC +# define GLEWAPI extern +#else +# ifdef GLEW_BUILD +# define GLEWAPI extern __declspec(dllexport) +# else +# define GLEWAPI extern __declspec(dllimport) +# endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* -------------------------- WGL_3DFX_multisample ------------------------- */ + +#ifndef WGL_3DFX_multisample +#define WGL_3DFX_multisample 1 + +#define WGL_SAMPLE_BUFFERS_3DFX 0x2060 +#define WGL_SAMPLES_3DFX 0x2061 + +#define WGLEW_3DFX_multisample WGLEW_GET_VAR(__WGLEW_3DFX_multisample) + +#endif /* WGL_3DFX_multisample */ + +/* ------------------------- WGL_3DL_stereo_control ------------------------ */ + +#ifndef WGL_3DL_stereo_control +#define WGL_3DL_stereo_control 1 + +#define WGL_STEREO_EMITTER_ENABLE_3DL 0x2055 +#define WGL_STEREO_EMITTER_DISABLE_3DL 0x2056 +#define WGL_STEREO_POLARITY_NORMAL_3DL 0x2057 +#define WGL_STEREO_POLARITY_INVERT_3DL 0x2058 + +typedef BOOL (WINAPI * PFNWGLSETSTEREOEMITTERSTATE3DLPROC) (HDC hDC, UINT uState); + +#define wglSetStereoEmitterState3DL WGLEW_GET_FUN(__wglewSetStereoEmitterState3DL) + +#define WGLEW_3DL_stereo_control WGLEW_GET_VAR(__WGLEW_3DL_stereo_control) + +#endif /* WGL_3DL_stereo_control */ + +/* ------------------------- WGL_ARB_buffer_region ------------------------- */ + +#ifndef WGL_ARB_buffer_region +#define WGL_ARB_buffer_region 1 + +#define WGL_FRONT_COLOR_BUFFER_BIT_ARB 0x00000001 +#define WGL_BACK_COLOR_BUFFER_BIT_ARB 0x00000002 +#define WGL_DEPTH_BUFFER_BIT_ARB 0x00000004 +#define WGL_STENCIL_BUFFER_BIT_ARB 0x00000008 + +typedef HANDLE (WINAPI * PFNWGLCREATEBUFFERREGIONARBPROC) (HDC hDC, int iLayerPlane, UINT uType); +typedef VOID (WINAPI * PFNWGLDELETEBUFFERREGIONARBPROC) (HANDLE hRegion); +typedef BOOL (WINAPI * PFNWGLRESTOREBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc); +typedef BOOL (WINAPI * PFNWGLSAVEBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height); + +#define wglCreateBufferRegionARB WGLEW_GET_FUN(__wglewCreateBufferRegionARB) +#define wglDeleteBufferRegionARB WGLEW_GET_FUN(__wglewDeleteBufferRegionARB) +#define wglRestoreBufferRegionARB WGLEW_GET_FUN(__wglewRestoreBufferRegionARB) +#define wglSaveBufferRegionARB WGLEW_GET_FUN(__wglewSaveBufferRegionARB) + +#define WGLEW_ARB_buffer_region WGLEW_GET_VAR(__WGLEW_ARB_buffer_region) + +#endif /* WGL_ARB_buffer_region */ + +/* ------------------------- WGL_ARB_create_context ------------------------ */ + +#ifndef WGL_ARB_create_context +#define WGL_ARB_create_context 1 + +#define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001 +#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002 +#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 +#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 +#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093 +#define WGL_CONTEXT_FLAGS_ARB 0x2094 + +typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC, HGLRC hShareContext, const int* attribList); + +#define wglCreateContextAttribsARB WGLEW_GET_FUN(__wglewCreateContextAttribsARB) + +#define WGLEW_ARB_create_context WGLEW_GET_VAR(__WGLEW_ARB_create_context) + +#endif /* WGL_ARB_create_context */ + +/* ----------------------- WGL_ARB_extensions_string ----------------------- */ + +#ifndef WGL_ARB_extensions_string +#define WGL_ARB_extensions_string 1 + +typedef const char* (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc); + +#define wglGetExtensionsStringARB WGLEW_GET_FUN(__wglewGetExtensionsStringARB) + +#define WGLEW_ARB_extensions_string WGLEW_GET_VAR(__WGLEW_ARB_extensions_string) + +#endif /* WGL_ARB_extensions_string */ + +/* ------------------------ WGL_ARB_framebuffer_sRGB ----------------------- */ + +#ifndef WGL_ARB_framebuffer_sRGB +#define WGL_ARB_framebuffer_sRGB 1 + +#define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20A9 + +#define WGLEW_ARB_framebuffer_sRGB WGLEW_GET_VAR(__WGLEW_ARB_framebuffer_sRGB) + +#endif /* WGL_ARB_framebuffer_sRGB */ + +/* ----------------------- WGL_ARB_make_current_read ----------------------- */ + +#ifndef WGL_ARB_make_current_read +#define WGL_ARB_make_current_read 1 + +#define ERROR_INVALID_PIXEL_TYPE_ARB 0x2043 +#define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054 + +typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCARBPROC) (VOID); +typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTARBPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); + +#define wglGetCurrentReadDCARB WGLEW_GET_FUN(__wglewGetCurrentReadDCARB) +#define wglMakeContextCurrentARB WGLEW_GET_FUN(__wglewMakeContextCurrentARB) + +#define WGLEW_ARB_make_current_read WGLEW_GET_VAR(__WGLEW_ARB_make_current_read) + +#endif /* WGL_ARB_make_current_read */ + +/* -------------------------- WGL_ARB_multisample -------------------------- */ + +#ifndef WGL_ARB_multisample +#define WGL_ARB_multisample 1 + +#define WGL_SAMPLE_BUFFERS_ARB 0x2041 +#define WGL_SAMPLES_ARB 0x2042 + +#define WGLEW_ARB_multisample WGLEW_GET_VAR(__WGLEW_ARB_multisample) + +#endif /* WGL_ARB_multisample */ + +/* ---------------------------- WGL_ARB_pbuffer ---------------------------- */ + +#ifndef WGL_ARB_pbuffer +#define WGL_ARB_pbuffer 1 + +#define WGL_DRAW_TO_PBUFFER_ARB 0x202D +#define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E +#define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F +#define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030 +#define WGL_PBUFFER_LARGEST_ARB 0x2033 +#define WGL_PBUFFER_WIDTH_ARB 0x2034 +#define WGL_PBUFFER_HEIGHT_ARB 0x2035 +#define WGL_PBUFFER_LOST_ARB 0x2036 + +DECLARE_HANDLE(HPBUFFERARB); + +typedef HPBUFFERARB (WINAPI * PFNWGLCREATEPBUFFERARBPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int* piAttribList); +typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFERARBPROC) (HPBUFFERARB hPbuffer); +typedef HDC (WINAPI * PFNWGLGETPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer); +typedef BOOL (WINAPI * PFNWGLQUERYPBUFFERARBPROC) (HPBUFFERARB hPbuffer, int iAttribute, int* piValue); +typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer, HDC hDC); + +#define wglCreatePbufferARB WGLEW_GET_FUN(__wglewCreatePbufferARB) +#define wglDestroyPbufferARB WGLEW_GET_FUN(__wglewDestroyPbufferARB) +#define wglGetPbufferDCARB WGLEW_GET_FUN(__wglewGetPbufferDCARB) +#define wglQueryPbufferARB WGLEW_GET_FUN(__wglewQueryPbufferARB) +#define wglReleasePbufferDCARB WGLEW_GET_FUN(__wglewReleasePbufferDCARB) + +#define WGLEW_ARB_pbuffer WGLEW_GET_VAR(__WGLEW_ARB_pbuffer) + +#endif /* WGL_ARB_pbuffer */ + +/* -------------------------- WGL_ARB_pixel_format ------------------------- */ + +#ifndef WGL_ARB_pixel_format +#define WGL_ARB_pixel_format 1 + +#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000 +#define WGL_DRAW_TO_WINDOW_ARB 0x2001 +#define WGL_DRAW_TO_BITMAP_ARB 0x2002 +#define WGL_ACCELERATION_ARB 0x2003 +#define WGL_NEED_PALETTE_ARB 0x2004 +#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005 +#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006 +#define WGL_SWAP_METHOD_ARB 0x2007 +#define WGL_NUMBER_OVERLAYS_ARB 0x2008 +#define WGL_NUMBER_UNDERLAYS_ARB 0x2009 +#define WGL_TRANSPARENT_ARB 0x200A +#define WGL_SHARE_DEPTH_ARB 0x200C +#define WGL_SHARE_STENCIL_ARB 0x200D +#define WGL_SHARE_ACCUM_ARB 0x200E +#define WGL_SUPPORT_GDI_ARB 0x200F +#define WGL_SUPPORT_OPENGL_ARB 0x2010 +#define WGL_DOUBLE_BUFFER_ARB 0x2011 +#define WGL_STEREO_ARB 0x2012 +#define WGL_PIXEL_TYPE_ARB 0x2013 +#define WGL_COLOR_BITS_ARB 0x2014 +#define WGL_RED_BITS_ARB 0x2015 +#define WGL_RED_SHIFT_ARB 0x2016 +#define WGL_GREEN_BITS_ARB 0x2017 +#define WGL_GREEN_SHIFT_ARB 0x2018 +#define WGL_BLUE_BITS_ARB 0x2019 +#define WGL_BLUE_SHIFT_ARB 0x201A +#define WGL_ALPHA_BITS_ARB 0x201B +#define WGL_ALPHA_SHIFT_ARB 0x201C +#define WGL_ACCUM_BITS_ARB 0x201D +#define WGL_ACCUM_RED_BITS_ARB 0x201E +#define WGL_ACCUM_GREEN_BITS_ARB 0x201F +#define WGL_ACCUM_BLUE_BITS_ARB 0x2020 +#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021 +#define WGL_DEPTH_BITS_ARB 0x2022 +#define WGL_STENCIL_BITS_ARB 0x2023 +#define WGL_AUX_BUFFERS_ARB 0x2024 +#define WGL_NO_ACCELERATION_ARB 0x2025 +#define WGL_GENERIC_ACCELERATION_ARB 0x2026 +#define WGL_FULL_ACCELERATION_ARB 0x2027 +#define WGL_SWAP_EXCHANGE_ARB 0x2028 +#define WGL_SWAP_COPY_ARB 0x2029 +#define WGL_SWAP_UNDEFINED_ARB 0x202A +#define WGL_TYPE_RGBA_ARB 0x202B +#define WGL_TYPE_COLORINDEX_ARB 0x202C +#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037 +#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038 +#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039 +#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A +#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B + +typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int* piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int* piAttributes, FLOAT *pfValues); +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int* piAttributes, int *piValues); + +#define wglChoosePixelFormatARB WGLEW_GET_FUN(__wglewChoosePixelFormatARB) +#define wglGetPixelFormatAttribfvARB WGLEW_GET_FUN(__wglewGetPixelFormatAttribfvARB) +#define wglGetPixelFormatAttribivARB WGLEW_GET_FUN(__wglewGetPixelFormatAttribivARB) + +#define WGLEW_ARB_pixel_format WGLEW_GET_VAR(__WGLEW_ARB_pixel_format) + +#endif /* WGL_ARB_pixel_format */ + +/* ----------------------- WGL_ARB_pixel_format_float ---------------------- */ + +#ifndef WGL_ARB_pixel_format_float +#define WGL_ARB_pixel_format_float 1 + +#define WGL_TYPE_RGBA_FLOAT_ARB 0x21A0 + +#define WGLEW_ARB_pixel_format_float WGLEW_GET_VAR(__WGLEW_ARB_pixel_format_float) + +#endif /* WGL_ARB_pixel_format_float */ + +/* ------------------------- WGL_ARB_render_texture ------------------------ */ + +#ifndef WGL_ARB_render_texture +#define WGL_ARB_render_texture 1 + +#define WGL_BIND_TO_TEXTURE_RGB_ARB 0x2070 +#define WGL_BIND_TO_TEXTURE_RGBA_ARB 0x2071 +#define WGL_TEXTURE_FORMAT_ARB 0x2072 +#define WGL_TEXTURE_TARGET_ARB 0x2073 +#define WGL_MIPMAP_TEXTURE_ARB 0x2074 +#define WGL_TEXTURE_RGB_ARB 0x2075 +#define WGL_TEXTURE_RGBA_ARB 0x2076 +#define WGL_NO_TEXTURE_ARB 0x2077 +#define WGL_TEXTURE_CUBE_MAP_ARB 0x2078 +#define WGL_TEXTURE_1D_ARB 0x2079 +#define WGL_TEXTURE_2D_ARB 0x207A +#define WGL_MIPMAP_LEVEL_ARB 0x207B +#define WGL_CUBE_MAP_FACE_ARB 0x207C +#define WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x207D +#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x207E +#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x207F +#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x2080 +#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x2081 +#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x2082 +#define WGL_FRONT_LEFT_ARB 0x2083 +#define WGL_FRONT_RIGHT_ARB 0x2084 +#define WGL_BACK_LEFT_ARB 0x2085 +#define WGL_BACK_RIGHT_ARB 0x2086 +#define WGL_AUX0_ARB 0x2087 +#define WGL_AUX1_ARB 0x2088 +#define WGL_AUX2_ARB 0x2089 +#define WGL_AUX3_ARB 0x208A +#define WGL_AUX4_ARB 0x208B +#define WGL_AUX5_ARB 0x208C +#define WGL_AUX6_ARB 0x208D +#define WGL_AUX7_ARB 0x208E +#define WGL_AUX8_ARB 0x208F +#define WGL_AUX9_ARB 0x2090 + +typedef BOOL (WINAPI * PFNWGLBINDTEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer); +typedef BOOL (WINAPI * PFNWGLRELEASETEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer); +typedef BOOL (WINAPI * PFNWGLSETPBUFFERATTRIBARBPROC) (HPBUFFERARB hPbuffer, const int* piAttribList); + +#define wglBindTexImageARB WGLEW_GET_FUN(__wglewBindTexImageARB) +#define wglReleaseTexImageARB WGLEW_GET_FUN(__wglewReleaseTexImageARB) +#define wglSetPbufferAttribARB WGLEW_GET_FUN(__wglewSetPbufferAttribARB) + +#define WGLEW_ARB_render_texture WGLEW_GET_VAR(__WGLEW_ARB_render_texture) + +#endif /* WGL_ARB_render_texture */ + +/* ----------------------- WGL_ATI_pixel_format_float ---------------------- */ + +#ifndef WGL_ATI_pixel_format_float +#define WGL_ATI_pixel_format_float 1 + +#define WGL_TYPE_RGBA_FLOAT_ATI 0x21A0 +#define GL_RGBA_FLOAT_MODE_ATI 0x8820 +#define GL_COLOR_CLEAR_UNCLAMPED_VALUE_ATI 0x8835 + +#define WGLEW_ATI_pixel_format_float WGLEW_GET_VAR(__WGLEW_ATI_pixel_format_float) + +#endif /* WGL_ATI_pixel_format_float */ + +/* -------------------- WGL_ATI_render_texture_rectangle ------------------- */ + +#ifndef WGL_ATI_render_texture_rectangle +#define WGL_ATI_render_texture_rectangle 1 + +#define WGL_TEXTURE_RECTANGLE_ATI 0x21A5 + +#define WGLEW_ATI_render_texture_rectangle WGLEW_GET_VAR(__WGLEW_ATI_render_texture_rectangle) + +#endif /* WGL_ATI_render_texture_rectangle */ + +/* -------------------------- WGL_EXT_depth_float -------------------------- */ + +#ifndef WGL_EXT_depth_float +#define WGL_EXT_depth_float 1 + +#define WGL_DEPTH_FLOAT_EXT 0x2040 + +#define WGLEW_EXT_depth_float WGLEW_GET_VAR(__WGLEW_EXT_depth_float) + +#endif /* WGL_EXT_depth_float */ + +/* ---------------------- WGL_EXT_display_color_table ---------------------- */ + +#ifndef WGL_EXT_display_color_table +#define WGL_EXT_display_color_table 1 + +typedef GLboolean (WINAPI * PFNWGLBINDDISPLAYCOLORTABLEEXTPROC) (GLushort id); +typedef GLboolean (WINAPI * PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC) (GLushort id); +typedef void (WINAPI * PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC) (GLushort id); +typedef GLboolean (WINAPI * PFNWGLLOADDISPLAYCOLORTABLEEXTPROC) (GLushort* table, GLuint length); + +#define wglBindDisplayColorTableEXT WGLEW_GET_FUN(__wglewBindDisplayColorTableEXT) +#define wglCreateDisplayColorTableEXT WGLEW_GET_FUN(__wglewCreateDisplayColorTableEXT) +#define wglDestroyDisplayColorTableEXT WGLEW_GET_FUN(__wglewDestroyDisplayColorTableEXT) +#define wglLoadDisplayColorTableEXT WGLEW_GET_FUN(__wglewLoadDisplayColorTableEXT) + +#define WGLEW_EXT_display_color_table WGLEW_GET_VAR(__WGLEW_EXT_display_color_table) + +#endif /* WGL_EXT_display_color_table */ + +/* ----------------------- WGL_EXT_extensions_string ----------------------- */ + +#ifndef WGL_EXT_extensions_string +#define WGL_EXT_extensions_string 1 + +typedef const char* (WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC) (void); + +#define wglGetExtensionsStringEXT WGLEW_GET_FUN(__wglewGetExtensionsStringEXT) + +#define WGLEW_EXT_extensions_string WGLEW_GET_VAR(__WGLEW_EXT_extensions_string) + +#endif /* WGL_EXT_extensions_string */ + +/* ------------------------ WGL_EXT_framebuffer_sRGB ----------------------- */ + +#ifndef WGL_EXT_framebuffer_sRGB +#define WGL_EXT_framebuffer_sRGB 1 + +#define WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20A9 + +#define WGLEW_EXT_framebuffer_sRGB WGLEW_GET_VAR(__WGLEW_EXT_framebuffer_sRGB) + +#endif /* WGL_EXT_framebuffer_sRGB */ + +/* ----------------------- WGL_EXT_make_current_read ----------------------- */ + +#ifndef WGL_EXT_make_current_read +#define WGL_EXT_make_current_read 1 + +#define ERROR_INVALID_PIXEL_TYPE_EXT 0x2043 + +typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCEXTPROC) (VOID); +typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTEXTPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); + +#define wglGetCurrentReadDCEXT WGLEW_GET_FUN(__wglewGetCurrentReadDCEXT) +#define wglMakeContextCurrentEXT WGLEW_GET_FUN(__wglewMakeContextCurrentEXT) + +#define WGLEW_EXT_make_current_read WGLEW_GET_VAR(__WGLEW_EXT_make_current_read) + +#endif /* WGL_EXT_make_current_read */ + +/* -------------------------- WGL_EXT_multisample -------------------------- */ + +#ifndef WGL_EXT_multisample +#define WGL_EXT_multisample 1 + +#define WGL_SAMPLE_BUFFERS_EXT 0x2041 +#define WGL_SAMPLES_EXT 0x2042 + +#define WGLEW_EXT_multisample WGLEW_GET_VAR(__WGLEW_EXT_multisample) + +#endif /* WGL_EXT_multisample */ + +/* ---------------------------- WGL_EXT_pbuffer ---------------------------- */ + +#ifndef WGL_EXT_pbuffer +#define WGL_EXT_pbuffer 1 + +#define WGL_DRAW_TO_PBUFFER_EXT 0x202D +#define WGL_MAX_PBUFFER_PIXELS_EXT 0x202E +#define WGL_MAX_PBUFFER_WIDTH_EXT 0x202F +#define WGL_MAX_PBUFFER_HEIGHT_EXT 0x2030 +#define WGL_OPTIMAL_PBUFFER_WIDTH_EXT 0x2031 +#define WGL_OPTIMAL_PBUFFER_HEIGHT_EXT 0x2032 +#define WGL_PBUFFER_LARGEST_EXT 0x2033 +#define WGL_PBUFFER_WIDTH_EXT 0x2034 +#define WGL_PBUFFER_HEIGHT_EXT 0x2035 + +DECLARE_HANDLE(HPBUFFEREXT); + +typedef HPBUFFEREXT (WINAPI * PFNWGLCREATEPBUFFEREXTPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int* piAttribList); +typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer); +typedef HDC (WINAPI * PFNWGLGETPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer); +typedef BOOL (WINAPI * PFNWGLQUERYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer, int iAttribute, int* piValue); +typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer, HDC hDC); + +#define wglCreatePbufferEXT WGLEW_GET_FUN(__wglewCreatePbufferEXT) +#define wglDestroyPbufferEXT WGLEW_GET_FUN(__wglewDestroyPbufferEXT) +#define wglGetPbufferDCEXT WGLEW_GET_FUN(__wglewGetPbufferDCEXT) +#define wglQueryPbufferEXT WGLEW_GET_FUN(__wglewQueryPbufferEXT) +#define wglReleasePbufferDCEXT WGLEW_GET_FUN(__wglewReleasePbufferDCEXT) + +#define WGLEW_EXT_pbuffer WGLEW_GET_VAR(__WGLEW_EXT_pbuffer) + +#endif /* WGL_EXT_pbuffer */ + +/* -------------------------- WGL_EXT_pixel_format ------------------------- */ + +#ifndef WGL_EXT_pixel_format +#define WGL_EXT_pixel_format 1 + +#define WGL_NUMBER_PIXEL_FORMATS_EXT 0x2000 +#define WGL_DRAW_TO_WINDOW_EXT 0x2001 +#define WGL_DRAW_TO_BITMAP_EXT 0x2002 +#define WGL_ACCELERATION_EXT 0x2003 +#define WGL_NEED_PALETTE_EXT 0x2004 +#define WGL_NEED_SYSTEM_PALETTE_EXT 0x2005 +#define WGL_SWAP_LAYER_BUFFERS_EXT 0x2006 +#define WGL_SWAP_METHOD_EXT 0x2007 +#define WGL_NUMBER_OVERLAYS_EXT 0x2008 +#define WGL_NUMBER_UNDERLAYS_EXT 0x2009 +#define WGL_TRANSPARENT_EXT 0x200A +#define WGL_TRANSPARENT_VALUE_EXT 0x200B +#define WGL_SHARE_DEPTH_EXT 0x200C +#define WGL_SHARE_STENCIL_EXT 0x200D +#define WGL_SHARE_ACCUM_EXT 0x200E +#define WGL_SUPPORT_GDI_EXT 0x200F +#define WGL_SUPPORT_OPENGL_EXT 0x2010 +#define WGL_DOUBLE_BUFFER_EXT 0x2011 +#define WGL_STEREO_EXT 0x2012 +#define WGL_PIXEL_TYPE_EXT 0x2013 +#define WGL_COLOR_BITS_EXT 0x2014 +#define WGL_RED_BITS_EXT 0x2015 +#define WGL_RED_SHIFT_EXT 0x2016 +#define WGL_GREEN_BITS_EXT 0x2017 +#define WGL_GREEN_SHIFT_EXT 0x2018 +#define WGL_BLUE_BITS_EXT 0x2019 +#define WGL_BLUE_SHIFT_EXT 0x201A +#define WGL_ALPHA_BITS_EXT 0x201B +#define WGL_ALPHA_SHIFT_EXT 0x201C +#define WGL_ACCUM_BITS_EXT 0x201D +#define WGL_ACCUM_RED_BITS_EXT 0x201E +#define WGL_ACCUM_GREEN_BITS_EXT 0x201F +#define WGL_ACCUM_BLUE_BITS_EXT 0x2020 +#define WGL_ACCUM_ALPHA_BITS_EXT 0x2021 +#define WGL_DEPTH_BITS_EXT 0x2022 +#define WGL_STENCIL_BITS_EXT 0x2023 +#define WGL_AUX_BUFFERS_EXT 0x2024 +#define WGL_NO_ACCELERATION_EXT 0x2025 +#define WGL_GENERIC_ACCELERATION_EXT 0x2026 +#define WGL_FULL_ACCELERATION_EXT 0x2027 +#define WGL_SWAP_EXCHANGE_EXT 0x2028 +#define WGL_SWAP_COPY_EXT 0x2029 +#define WGL_SWAP_UNDEFINED_EXT 0x202A +#define WGL_TYPE_RGBA_EXT 0x202B +#define WGL_TYPE_COLORINDEX_EXT 0x202C + +typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATEXTPROC) (HDC hdc, const int* piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int* piAttributes, FLOAT *pfValues); +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int* piAttributes, int *piValues); + +#define wglChoosePixelFormatEXT WGLEW_GET_FUN(__wglewChoosePixelFormatEXT) +#define wglGetPixelFormatAttribfvEXT WGLEW_GET_FUN(__wglewGetPixelFormatAttribfvEXT) +#define wglGetPixelFormatAttribivEXT WGLEW_GET_FUN(__wglewGetPixelFormatAttribivEXT) + +#define WGLEW_EXT_pixel_format WGLEW_GET_VAR(__WGLEW_EXT_pixel_format) + +#endif /* WGL_EXT_pixel_format */ + +/* ------------------- WGL_EXT_pixel_format_packed_float ------------------- */ + +#ifndef WGL_EXT_pixel_format_packed_float +#define WGL_EXT_pixel_format_packed_float 1 + +#define WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT 0x20A8 + +#define WGLEW_EXT_pixel_format_packed_float WGLEW_GET_VAR(__WGLEW_EXT_pixel_format_packed_float) + +#endif /* WGL_EXT_pixel_format_packed_float */ + +/* -------------------------- WGL_EXT_swap_control ------------------------- */ + +#ifndef WGL_EXT_swap_control +#define WGL_EXT_swap_control 1 + +typedef int (WINAPI * PFNWGLGETSWAPINTERVALEXTPROC) (void); +typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval); + +#define wglGetSwapIntervalEXT WGLEW_GET_FUN(__wglewGetSwapIntervalEXT) +#define wglSwapIntervalEXT WGLEW_GET_FUN(__wglewSwapIntervalEXT) + +#define WGLEW_EXT_swap_control WGLEW_GET_VAR(__WGLEW_EXT_swap_control) + +#endif /* WGL_EXT_swap_control */ + +/* --------------------- WGL_I3D_digital_video_control --------------------- */ + +#ifndef WGL_I3D_digital_video_control +#define WGL_I3D_digital_video_control 1 + +#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D 0x2050 +#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D 0x2051 +#define WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D 0x2052 +#define WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D 0x2053 + +typedef BOOL (WINAPI * PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int* piValue); +typedef BOOL (WINAPI * PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int* piValue); + +#define wglGetDigitalVideoParametersI3D WGLEW_GET_FUN(__wglewGetDigitalVideoParametersI3D) +#define wglSetDigitalVideoParametersI3D WGLEW_GET_FUN(__wglewSetDigitalVideoParametersI3D) + +#define WGLEW_I3D_digital_video_control WGLEW_GET_VAR(__WGLEW_I3D_digital_video_control) + +#endif /* WGL_I3D_digital_video_control */ + +/* ----------------------------- WGL_I3D_gamma ----------------------------- */ + +#ifndef WGL_I3D_gamma +#define WGL_I3D_gamma 1 + +#define WGL_GAMMA_TABLE_SIZE_I3D 0x204E +#define WGL_GAMMA_EXCLUDE_DESKTOP_I3D 0x204F + +typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, USHORT* puRed, USHORT *puGreen, USHORT *puBlue); +typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int* piValue); +typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, const USHORT* puRed, const USHORT *puGreen, const USHORT *puBlue); +typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int* piValue); + +#define wglGetGammaTableI3D WGLEW_GET_FUN(__wglewGetGammaTableI3D) +#define wglGetGammaTableParametersI3D WGLEW_GET_FUN(__wglewGetGammaTableParametersI3D) +#define wglSetGammaTableI3D WGLEW_GET_FUN(__wglewSetGammaTableI3D) +#define wglSetGammaTableParametersI3D WGLEW_GET_FUN(__wglewSetGammaTableParametersI3D) + +#define WGLEW_I3D_gamma WGLEW_GET_VAR(__WGLEW_I3D_gamma) + +#endif /* WGL_I3D_gamma */ + +/* ---------------------------- WGL_I3D_genlock ---------------------------- */ + +#ifndef WGL_I3D_genlock +#define WGL_I3D_genlock 1 + +#define WGL_GENLOCK_SOURCE_MULTIVIEW_I3D 0x2044 +#define WGL_GENLOCK_SOURCE_EXTERNAL_SYNC_I3D 0x2045 +#define WGL_GENLOCK_SOURCE_EXTERNAL_FIELD_I3D 0x2046 +#define WGL_GENLOCK_SOURCE_EXTERNAL_TTL_I3D 0x2047 +#define WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D 0x2048 +#define WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D 0x2049 +#define WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D 0x204A +#define WGL_GENLOCK_SOURCE_EDGE_RISING_I3D 0x204B +#define WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D 0x204C + +typedef BOOL (WINAPI * PFNWGLDISABLEGENLOCKI3DPROC) (HDC hDC); +typedef BOOL (WINAPI * PFNWGLENABLEGENLOCKI3DPROC) (HDC hDC); +typedef BOOL (WINAPI * PFNWGLGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT uRate); +typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT uDelay); +typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT uEdge); +typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEI3DPROC) (HDC hDC, UINT uSource); +typedef BOOL (WINAPI * PFNWGLGETGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT* uRate); +typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT* uDelay); +typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT* uEdge); +typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEI3DPROC) (HDC hDC, UINT* uSource); +typedef BOOL (WINAPI * PFNWGLISENABLEDGENLOCKI3DPROC) (HDC hDC, BOOL* pFlag); +typedef BOOL (WINAPI * PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC) (HDC hDC, UINT* uMaxLineDelay, UINT *uMaxPixelDelay); + +#define wglDisableGenlockI3D WGLEW_GET_FUN(__wglewDisableGenlockI3D) +#define wglEnableGenlockI3D WGLEW_GET_FUN(__wglewEnableGenlockI3D) +#define wglGenlockSampleRateI3D WGLEW_GET_FUN(__wglewGenlockSampleRateI3D) +#define wglGenlockSourceDelayI3D WGLEW_GET_FUN(__wglewGenlockSourceDelayI3D) +#define wglGenlockSourceEdgeI3D WGLEW_GET_FUN(__wglewGenlockSourceEdgeI3D) +#define wglGenlockSourceI3D WGLEW_GET_FUN(__wglewGenlockSourceI3D) +#define wglGetGenlockSampleRateI3D WGLEW_GET_FUN(__wglewGetGenlockSampleRateI3D) +#define wglGetGenlockSourceDelayI3D WGLEW_GET_FUN(__wglewGetGenlockSourceDelayI3D) +#define wglGetGenlockSourceEdgeI3D WGLEW_GET_FUN(__wglewGetGenlockSourceEdgeI3D) +#define wglGetGenlockSourceI3D WGLEW_GET_FUN(__wglewGetGenlockSourceI3D) +#define wglIsEnabledGenlockI3D WGLEW_GET_FUN(__wglewIsEnabledGenlockI3D) +#define wglQueryGenlockMaxSourceDelayI3D WGLEW_GET_FUN(__wglewQueryGenlockMaxSourceDelayI3D) + +#define WGLEW_I3D_genlock WGLEW_GET_VAR(__WGLEW_I3D_genlock) + +#endif /* WGL_I3D_genlock */ + +/* -------------------------- WGL_I3D_image_buffer ------------------------- */ + +#ifndef WGL_I3D_image_buffer +#define WGL_I3D_image_buffer 1 + +#define WGL_IMAGE_BUFFER_MIN_ACCESS_I3D 0x00000001 +#define WGL_IMAGE_BUFFER_LOCK_I3D 0x00000002 + +typedef BOOL (WINAPI * PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC) (HDC hdc, HANDLE* pEvent, LPVOID *pAddress, DWORD *pSize, UINT count); +typedef LPVOID (WINAPI * PFNWGLCREATEIMAGEBUFFERI3DPROC) (HDC hDC, DWORD dwSize, UINT uFlags); +typedef BOOL (WINAPI * PFNWGLDESTROYIMAGEBUFFERI3DPROC) (HDC hDC, LPVOID pAddress); +typedef BOOL (WINAPI * PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC) (HDC hdc, LPVOID* pAddress, UINT count); + +#define wglAssociateImageBufferEventsI3D WGLEW_GET_FUN(__wglewAssociateImageBufferEventsI3D) +#define wglCreateImageBufferI3D WGLEW_GET_FUN(__wglewCreateImageBufferI3D) +#define wglDestroyImageBufferI3D WGLEW_GET_FUN(__wglewDestroyImageBufferI3D) +#define wglReleaseImageBufferEventsI3D WGLEW_GET_FUN(__wglewReleaseImageBufferEventsI3D) + +#define WGLEW_I3D_image_buffer WGLEW_GET_VAR(__WGLEW_I3D_image_buffer) + +#endif /* WGL_I3D_image_buffer */ + +/* ------------------------ WGL_I3D_swap_frame_lock ------------------------ */ + +#ifndef WGL_I3D_swap_frame_lock +#define WGL_I3D_swap_frame_lock 1 + +typedef BOOL (WINAPI * PFNWGLDISABLEFRAMELOCKI3DPROC) (VOID); +typedef BOOL (WINAPI * PFNWGLENABLEFRAMELOCKI3DPROC) (VOID); +typedef BOOL (WINAPI * PFNWGLISENABLEDFRAMELOCKI3DPROC) (BOOL* pFlag); +typedef BOOL (WINAPI * PFNWGLQUERYFRAMELOCKMASTERI3DPROC) (BOOL* pFlag); + +#define wglDisableFrameLockI3D WGLEW_GET_FUN(__wglewDisableFrameLockI3D) +#define wglEnableFrameLockI3D WGLEW_GET_FUN(__wglewEnableFrameLockI3D) +#define wglIsEnabledFrameLockI3D WGLEW_GET_FUN(__wglewIsEnabledFrameLockI3D) +#define wglQueryFrameLockMasterI3D WGLEW_GET_FUN(__wglewQueryFrameLockMasterI3D) + +#define WGLEW_I3D_swap_frame_lock WGLEW_GET_VAR(__WGLEW_I3D_swap_frame_lock) + +#endif /* WGL_I3D_swap_frame_lock */ + +/* ------------------------ WGL_I3D_swap_frame_usage ----------------------- */ + +#ifndef WGL_I3D_swap_frame_usage +#define WGL_I3D_swap_frame_usage 1 + +typedef BOOL (WINAPI * PFNWGLBEGINFRAMETRACKINGI3DPROC) (void); +typedef BOOL (WINAPI * PFNWGLENDFRAMETRACKINGI3DPROC) (void); +typedef BOOL (WINAPI * PFNWGLGETFRAMEUSAGEI3DPROC) (float* pUsage); +typedef BOOL (WINAPI * PFNWGLQUERYFRAMETRACKINGI3DPROC) (DWORD* pFrameCount, DWORD *pMissedFrames, float *pLastMissedUsage); + +#define wglBeginFrameTrackingI3D WGLEW_GET_FUN(__wglewBeginFrameTrackingI3D) +#define wglEndFrameTrackingI3D WGLEW_GET_FUN(__wglewEndFrameTrackingI3D) +#define wglGetFrameUsageI3D WGLEW_GET_FUN(__wglewGetFrameUsageI3D) +#define wglQueryFrameTrackingI3D WGLEW_GET_FUN(__wglewQueryFrameTrackingI3D) + +#define WGLEW_I3D_swap_frame_usage WGLEW_GET_VAR(__WGLEW_I3D_swap_frame_usage) + +#endif /* WGL_I3D_swap_frame_usage */ + +/* -------------------------- WGL_NV_float_buffer -------------------------- */ + +#ifndef WGL_NV_float_buffer +#define WGL_NV_float_buffer 1 + +#define WGL_FLOAT_COMPONENTS_NV 0x20B0 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV 0x20B1 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV 0x20B2 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV 0x20B3 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV 0x20B4 +#define WGL_TEXTURE_FLOAT_R_NV 0x20B5 +#define WGL_TEXTURE_FLOAT_RG_NV 0x20B6 +#define WGL_TEXTURE_FLOAT_RGB_NV 0x20B7 +#define WGL_TEXTURE_FLOAT_RGBA_NV 0x20B8 + +#define WGLEW_NV_float_buffer WGLEW_GET_VAR(__WGLEW_NV_float_buffer) + +#endif /* WGL_NV_float_buffer */ + +/* -------------------------- WGL_NV_gpu_affinity -------------------------- */ + +#ifndef WGL_NV_gpu_affinity +#define WGL_NV_gpu_affinity 1 + +#define WGL_ERROR_INCOMPATIBLE_AFFINITY_MASKS_NV 0x20D0 +#define WGL_ERROR_MISSING_AFFINITY_MASK_NV 0x20D1 + +DECLARE_HANDLE(HGPUNV); +typedef struct _GPU_DEVICE { + DWORD cb; + CHAR DeviceName[32]; + CHAR DeviceString[128]; + DWORD Flags; + RECT rcVirtualScreen; +} GPU_DEVICE, *PGPU_DEVICE; + +typedef HDC (WINAPI * PFNWGLCREATEAFFINITYDCNVPROC) (const HGPUNV *phGpuList); +typedef BOOL (WINAPI * PFNWGLDELETEDCNVPROC) (HDC hdc); +typedef BOOL (WINAPI * PFNWGLENUMGPUDEVICESNVPROC) (HGPUNV hGpu, UINT iDeviceIndex, PGPU_DEVICE lpGpuDevice); +typedef BOOL (WINAPI * PFNWGLENUMGPUSFROMAFFINITYDCNVPROC) (HDC hAffinityDC, UINT iGpuIndex, HGPUNV *hGpu); +typedef BOOL (WINAPI * PFNWGLENUMGPUSNVPROC) (UINT iGpuIndex, HGPUNV *phGpu); + +#define wglCreateAffinityDCNV WGLEW_GET_FUN(__wglewCreateAffinityDCNV) +#define wglDeleteDCNV WGLEW_GET_FUN(__wglewDeleteDCNV) +#define wglEnumGpuDevicesNV WGLEW_GET_FUN(__wglewEnumGpuDevicesNV) +#define wglEnumGpusFromAffinityDCNV WGLEW_GET_FUN(__wglewEnumGpusFromAffinityDCNV) +#define wglEnumGpusNV WGLEW_GET_FUN(__wglewEnumGpusNV) + +#define WGLEW_NV_gpu_affinity WGLEW_GET_VAR(__WGLEW_NV_gpu_affinity) + +#endif /* WGL_NV_gpu_affinity */ + +/* -------------------------- WGL_NV_present_video ------------------------- */ + +#ifndef WGL_NV_present_video +#define WGL_NV_present_video 1 + +#define WGL_NUM_VIDEO_SLOTS_NV 0x20F0 + +DECLARE_HANDLE(HVIDEOOUTPUTDEVICENV); + +typedef BOOL (WINAPI * PFNWGLBINDVIDEODEVICENVPROC) (HDC hDc, unsigned int uVideoSlot, HVIDEOOUTPUTDEVICENV hVideoDevice, const int* piAttribList); +typedef int (WINAPI * PFNWGLENUMERATEVIDEODEVICESNVPROC) (HDC hDc, HVIDEOOUTPUTDEVICENV* phDeviceList); +typedef BOOL (WINAPI * PFNWGLQUERYCURRENTCONTEXTNVPROC) (int iAttribute, int* piValue); + +#define wglBindVideoDeviceNV WGLEW_GET_FUN(__wglewBindVideoDeviceNV) +#define wglEnumerateVideoDevicesNV WGLEW_GET_FUN(__wglewEnumerateVideoDevicesNV) +#define wglQueryCurrentContextNV WGLEW_GET_FUN(__wglewQueryCurrentContextNV) + +#define WGLEW_NV_present_video WGLEW_GET_VAR(__WGLEW_NV_present_video) + +#endif /* WGL_NV_present_video */ + +/* ---------------------- WGL_NV_render_depth_texture ---------------------- */ + +#ifndef WGL_NV_render_depth_texture +#define WGL_NV_render_depth_texture 1 + +#define WGL_NO_TEXTURE_ARB 0x2077 +#define WGL_BIND_TO_TEXTURE_DEPTH_NV 0x20A3 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV 0x20A4 +#define WGL_DEPTH_TEXTURE_FORMAT_NV 0x20A5 +#define WGL_TEXTURE_DEPTH_COMPONENT_NV 0x20A6 +#define WGL_DEPTH_COMPONENT_NV 0x20A7 + +#define WGLEW_NV_render_depth_texture WGLEW_GET_VAR(__WGLEW_NV_render_depth_texture) + +#endif /* WGL_NV_render_depth_texture */ + +/* -------------------- WGL_NV_render_texture_rectangle -------------------- */ + +#ifndef WGL_NV_render_texture_rectangle +#define WGL_NV_render_texture_rectangle 1 + +#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV 0x20A0 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV 0x20A1 +#define WGL_TEXTURE_RECTANGLE_NV 0x20A2 + +#define WGLEW_NV_render_texture_rectangle WGLEW_GET_VAR(__WGLEW_NV_render_texture_rectangle) + +#endif /* WGL_NV_render_texture_rectangle */ + +/* --------------------------- WGL_NV_swap_group --------------------------- */ + +#ifndef WGL_NV_swap_group +#define WGL_NV_swap_group 1 + +typedef BOOL (WINAPI * PFNWGLBINDSWAPBARRIERNVPROC) (GLuint group, GLuint barrier); +typedef BOOL (WINAPI * PFNWGLJOINSWAPGROUPNVPROC) (HDC hDC, GLuint group); +typedef BOOL (WINAPI * PFNWGLQUERYFRAMECOUNTNVPROC) (HDC hDC, GLuint* count); +typedef BOOL (WINAPI * PFNWGLQUERYMAXSWAPGROUPSNVPROC) (HDC hDC, GLuint* maxGroups, GLuint *maxBarriers); +typedef BOOL (WINAPI * PFNWGLQUERYSWAPGROUPNVPROC) (HDC hDC, GLuint* group); +typedef BOOL (WINAPI * PFNWGLRESETFRAMECOUNTNVPROC) (HDC hDC); + +#define wglBindSwapBarrierNV WGLEW_GET_FUN(__wglewBindSwapBarrierNV) +#define wglJoinSwapGroupNV WGLEW_GET_FUN(__wglewJoinSwapGroupNV) +#define wglQueryFrameCountNV WGLEW_GET_FUN(__wglewQueryFrameCountNV) +#define wglQueryMaxSwapGroupsNV WGLEW_GET_FUN(__wglewQueryMaxSwapGroupsNV) +#define wglQuerySwapGroupNV WGLEW_GET_FUN(__wglewQuerySwapGroupNV) +#define wglResetFrameCountNV WGLEW_GET_FUN(__wglewResetFrameCountNV) + +#define WGLEW_NV_swap_group WGLEW_GET_VAR(__WGLEW_NV_swap_group) + +#endif /* WGL_NV_swap_group */ + +/* ----------------------- WGL_NV_vertex_array_range ----------------------- */ + +#ifndef WGL_NV_vertex_array_range +#define WGL_NV_vertex_array_range 1 + +typedef void * (WINAPI * PFNWGLALLOCATEMEMORYNVPROC) (GLsizei size, GLfloat readFrequency, GLfloat writeFrequency, GLfloat priority); +typedef void (WINAPI * PFNWGLFREEMEMORYNVPROC) (void *pointer); + +#define wglAllocateMemoryNV WGLEW_GET_FUN(__wglewAllocateMemoryNV) +#define wglFreeMemoryNV WGLEW_GET_FUN(__wglewFreeMemoryNV) + +#define WGLEW_NV_vertex_array_range WGLEW_GET_VAR(__WGLEW_NV_vertex_array_range) + +#endif /* WGL_NV_vertex_array_range */ + +/* -------------------------- WGL_NV_video_output -------------------------- */ + +#ifndef WGL_NV_video_output +#define WGL_NV_video_output 1 + +#define WGL_BIND_TO_VIDEO_RGB_NV 0x20C0 +#define WGL_BIND_TO_VIDEO_RGBA_NV 0x20C1 +#define WGL_BIND_TO_VIDEO_RGB_AND_DEPTH_NV 0x20C2 +#define WGL_VIDEO_OUT_COLOR_NV 0x20C3 +#define WGL_VIDEO_OUT_ALPHA_NV 0x20C4 +#define WGL_VIDEO_OUT_DEPTH_NV 0x20C5 +#define WGL_VIDEO_OUT_COLOR_AND_ALPHA_NV 0x20C6 +#define WGL_VIDEO_OUT_COLOR_AND_DEPTH_NV 0x20C7 +#define WGL_VIDEO_OUT_FRAME 0x20C8 +#define WGL_VIDEO_OUT_FIELD_1 0x20C9 +#define WGL_VIDEO_OUT_FIELD_2 0x20CA +#define WGL_VIDEO_OUT_STACKED_FIELDS_1_2 0x20CB +#define WGL_VIDEO_OUT_STACKED_FIELDS_2_1 0x20CC + +DECLARE_HANDLE(HPVIDEODEV); + +typedef BOOL (WINAPI * PFNWGLBINDVIDEOIMAGENVPROC) (HPVIDEODEV hVideoDevice, HPBUFFERARB hPbuffer, int iVideoBuffer); +typedef BOOL (WINAPI * PFNWGLGETVIDEODEVICENVPROC) (HDC hDC, int numDevices, HPVIDEODEV* hVideoDevice); +typedef BOOL (WINAPI * PFNWGLGETVIDEOINFONVPROC) (HPVIDEODEV hpVideoDevice, unsigned long* pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo); +typedef BOOL (WINAPI * PFNWGLRELEASEVIDEODEVICENVPROC) (HPVIDEODEV hVideoDevice); +typedef BOOL (WINAPI * PFNWGLRELEASEVIDEOIMAGENVPROC) (HPBUFFERARB hPbuffer, int iVideoBuffer); +typedef BOOL (WINAPI * PFNWGLSENDPBUFFERTOVIDEONVPROC) (HPBUFFERARB hPbuffer, int iBufferType, unsigned long* pulCounterPbuffer, BOOL bBlock); + +#define wglBindVideoImageNV WGLEW_GET_FUN(__wglewBindVideoImageNV) +#define wglGetVideoDeviceNV WGLEW_GET_FUN(__wglewGetVideoDeviceNV) +#define wglGetVideoInfoNV WGLEW_GET_FUN(__wglewGetVideoInfoNV) +#define wglReleaseVideoDeviceNV WGLEW_GET_FUN(__wglewReleaseVideoDeviceNV) +#define wglReleaseVideoImageNV WGLEW_GET_FUN(__wglewReleaseVideoImageNV) +#define wglSendPbufferToVideoNV WGLEW_GET_FUN(__wglewSendPbufferToVideoNV) + +#define WGLEW_NV_video_output WGLEW_GET_VAR(__WGLEW_NV_video_output) + +#endif /* WGL_NV_video_output */ + +/* -------------------------- WGL_OML_sync_control ------------------------- */ + +#ifndef WGL_OML_sync_control +#define WGL_OML_sync_control 1 + +typedef BOOL (WINAPI * PFNWGLGETMSCRATEOMLPROC) (HDC hdc, INT32* numerator, INT32 *denominator); +typedef BOOL (WINAPI * PFNWGLGETSYNCVALUESOMLPROC) (HDC hdc, INT64* ust, INT64 *msc, INT64 *sbc); +typedef INT64 (WINAPI * PFNWGLSWAPBUFFERSMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder); +typedef INT64 (WINAPI * PFNWGLSWAPLAYERBUFFERSMSCOMLPROC) (HDC hdc, INT fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder); +typedef BOOL (WINAPI * PFNWGLWAITFORMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64* ust, INT64 *msc, INT64 *sbc); +typedef BOOL (WINAPI * PFNWGLWAITFORSBCOMLPROC) (HDC hdc, INT64 target_sbc, INT64* ust, INT64 *msc, INT64 *sbc); + +#define wglGetMscRateOML WGLEW_GET_FUN(__wglewGetMscRateOML) +#define wglGetSyncValuesOML WGLEW_GET_FUN(__wglewGetSyncValuesOML) +#define wglSwapBuffersMscOML WGLEW_GET_FUN(__wglewSwapBuffersMscOML) +#define wglSwapLayerBuffersMscOML WGLEW_GET_FUN(__wglewSwapLayerBuffersMscOML) +#define wglWaitForMscOML WGLEW_GET_FUN(__wglewWaitForMscOML) +#define wglWaitForSbcOML WGLEW_GET_FUN(__wglewWaitForSbcOML) + +#define WGLEW_OML_sync_control WGLEW_GET_VAR(__WGLEW_OML_sync_control) + +#endif /* WGL_OML_sync_control */ + +/* ------------------------------------------------------------------------- */ + +#ifdef GLEW_MX +#define WGLEW_EXPORT +#else +#define WGLEW_EXPORT GLEWAPI +#endif /* GLEW_MX */ + +#ifdef GLEW_MX +struct WGLEWContextStruct +{ +#endif /* GLEW_MX */ + +WGLEW_EXPORT PFNWGLSETSTEREOEMITTERSTATE3DLPROC __wglewSetStereoEmitterState3DL; + +WGLEW_EXPORT PFNWGLCREATEBUFFERREGIONARBPROC __wglewCreateBufferRegionARB; +WGLEW_EXPORT PFNWGLDELETEBUFFERREGIONARBPROC __wglewDeleteBufferRegionARB; +WGLEW_EXPORT PFNWGLRESTOREBUFFERREGIONARBPROC __wglewRestoreBufferRegionARB; +WGLEW_EXPORT PFNWGLSAVEBUFFERREGIONARBPROC __wglewSaveBufferRegionARB; + +WGLEW_EXPORT PFNWGLCREATECONTEXTATTRIBSARBPROC __wglewCreateContextAttribsARB; + +WGLEW_EXPORT PFNWGLGETEXTENSIONSSTRINGARBPROC __wglewGetExtensionsStringARB; + +WGLEW_EXPORT PFNWGLGETCURRENTREADDCARBPROC __wglewGetCurrentReadDCARB; +WGLEW_EXPORT PFNWGLMAKECONTEXTCURRENTARBPROC __wglewMakeContextCurrentARB; + +WGLEW_EXPORT PFNWGLCREATEPBUFFERARBPROC __wglewCreatePbufferARB; +WGLEW_EXPORT PFNWGLDESTROYPBUFFERARBPROC __wglewDestroyPbufferARB; +WGLEW_EXPORT PFNWGLGETPBUFFERDCARBPROC __wglewGetPbufferDCARB; +WGLEW_EXPORT PFNWGLQUERYPBUFFERARBPROC __wglewQueryPbufferARB; +WGLEW_EXPORT PFNWGLRELEASEPBUFFERDCARBPROC __wglewReleasePbufferDCARB; + +WGLEW_EXPORT PFNWGLCHOOSEPIXELFORMATARBPROC __wglewChoosePixelFormatARB; +WGLEW_EXPORT PFNWGLGETPIXELFORMATATTRIBFVARBPROC __wglewGetPixelFormatAttribfvARB; +WGLEW_EXPORT PFNWGLGETPIXELFORMATATTRIBIVARBPROC __wglewGetPixelFormatAttribivARB; + +WGLEW_EXPORT PFNWGLBINDTEXIMAGEARBPROC __wglewBindTexImageARB; +WGLEW_EXPORT PFNWGLRELEASETEXIMAGEARBPROC __wglewReleaseTexImageARB; +WGLEW_EXPORT PFNWGLSETPBUFFERATTRIBARBPROC __wglewSetPbufferAttribARB; + +WGLEW_EXPORT PFNWGLBINDDISPLAYCOLORTABLEEXTPROC __wglewBindDisplayColorTableEXT; +WGLEW_EXPORT PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC __wglewCreateDisplayColorTableEXT; +WGLEW_EXPORT PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC __wglewDestroyDisplayColorTableEXT; +WGLEW_EXPORT PFNWGLLOADDISPLAYCOLORTABLEEXTPROC __wglewLoadDisplayColorTableEXT; + +WGLEW_EXPORT PFNWGLGETEXTENSIONSSTRINGEXTPROC __wglewGetExtensionsStringEXT; + +WGLEW_EXPORT PFNWGLGETCURRENTREADDCEXTPROC __wglewGetCurrentReadDCEXT; +WGLEW_EXPORT PFNWGLMAKECONTEXTCURRENTEXTPROC __wglewMakeContextCurrentEXT; + +WGLEW_EXPORT PFNWGLCREATEPBUFFEREXTPROC __wglewCreatePbufferEXT; +WGLEW_EXPORT PFNWGLDESTROYPBUFFEREXTPROC __wglewDestroyPbufferEXT; +WGLEW_EXPORT PFNWGLGETPBUFFERDCEXTPROC __wglewGetPbufferDCEXT; +WGLEW_EXPORT PFNWGLQUERYPBUFFEREXTPROC __wglewQueryPbufferEXT; +WGLEW_EXPORT PFNWGLRELEASEPBUFFERDCEXTPROC __wglewReleasePbufferDCEXT; + +WGLEW_EXPORT PFNWGLCHOOSEPIXELFORMATEXTPROC __wglewChoosePixelFormatEXT; +WGLEW_EXPORT PFNWGLGETPIXELFORMATATTRIBFVEXTPROC __wglewGetPixelFormatAttribfvEXT; +WGLEW_EXPORT PFNWGLGETPIXELFORMATATTRIBIVEXTPROC __wglewGetPixelFormatAttribivEXT; + +WGLEW_EXPORT PFNWGLGETSWAPINTERVALEXTPROC __wglewGetSwapIntervalEXT; +WGLEW_EXPORT PFNWGLSWAPINTERVALEXTPROC __wglewSwapIntervalEXT; + +WGLEW_EXPORT PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC __wglewGetDigitalVideoParametersI3D; +WGLEW_EXPORT PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC __wglewSetDigitalVideoParametersI3D; + +WGLEW_EXPORT PFNWGLGETGAMMATABLEI3DPROC __wglewGetGammaTableI3D; +WGLEW_EXPORT PFNWGLGETGAMMATABLEPARAMETERSI3DPROC __wglewGetGammaTableParametersI3D; +WGLEW_EXPORT PFNWGLSETGAMMATABLEI3DPROC __wglewSetGammaTableI3D; +WGLEW_EXPORT PFNWGLSETGAMMATABLEPARAMETERSI3DPROC __wglewSetGammaTableParametersI3D; + +WGLEW_EXPORT PFNWGLDISABLEGENLOCKI3DPROC __wglewDisableGenlockI3D; +WGLEW_EXPORT PFNWGLENABLEGENLOCKI3DPROC __wglewEnableGenlockI3D; +WGLEW_EXPORT PFNWGLGENLOCKSAMPLERATEI3DPROC __wglewGenlockSampleRateI3D; +WGLEW_EXPORT PFNWGLGENLOCKSOURCEDELAYI3DPROC __wglewGenlockSourceDelayI3D; +WGLEW_EXPORT PFNWGLGENLOCKSOURCEEDGEI3DPROC __wglewGenlockSourceEdgeI3D; +WGLEW_EXPORT PFNWGLGENLOCKSOURCEI3DPROC __wglewGenlockSourceI3D; +WGLEW_EXPORT PFNWGLGETGENLOCKSAMPLERATEI3DPROC __wglewGetGenlockSampleRateI3D; +WGLEW_EXPORT PFNWGLGETGENLOCKSOURCEDELAYI3DPROC __wglewGetGenlockSourceDelayI3D; +WGLEW_EXPORT PFNWGLGETGENLOCKSOURCEEDGEI3DPROC __wglewGetGenlockSourceEdgeI3D; +WGLEW_EXPORT PFNWGLGETGENLOCKSOURCEI3DPROC __wglewGetGenlockSourceI3D; +WGLEW_EXPORT PFNWGLISENABLEDGENLOCKI3DPROC __wglewIsEnabledGenlockI3D; +WGLEW_EXPORT PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC __wglewQueryGenlockMaxSourceDelayI3D; + +WGLEW_EXPORT PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC __wglewAssociateImageBufferEventsI3D; +WGLEW_EXPORT PFNWGLCREATEIMAGEBUFFERI3DPROC __wglewCreateImageBufferI3D; +WGLEW_EXPORT PFNWGLDESTROYIMAGEBUFFERI3DPROC __wglewDestroyImageBufferI3D; +WGLEW_EXPORT PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC __wglewReleaseImageBufferEventsI3D; + +WGLEW_EXPORT PFNWGLDISABLEFRAMELOCKI3DPROC __wglewDisableFrameLockI3D; +WGLEW_EXPORT PFNWGLENABLEFRAMELOCKI3DPROC __wglewEnableFrameLockI3D; +WGLEW_EXPORT PFNWGLISENABLEDFRAMELOCKI3DPROC __wglewIsEnabledFrameLockI3D; +WGLEW_EXPORT PFNWGLQUERYFRAMELOCKMASTERI3DPROC __wglewQueryFrameLockMasterI3D; + +WGLEW_EXPORT PFNWGLBEGINFRAMETRACKINGI3DPROC __wglewBeginFrameTrackingI3D; +WGLEW_EXPORT PFNWGLENDFRAMETRACKINGI3DPROC __wglewEndFrameTrackingI3D; +WGLEW_EXPORT PFNWGLGETFRAMEUSAGEI3DPROC __wglewGetFrameUsageI3D; +WGLEW_EXPORT PFNWGLQUERYFRAMETRACKINGI3DPROC __wglewQueryFrameTrackingI3D; + +WGLEW_EXPORT PFNWGLCREATEAFFINITYDCNVPROC __wglewCreateAffinityDCNV; +WGLEW_EXPORT PFNWGLDELETEDCNVPROC __wglewDeleteDCNV; +WGLEW_EXPORT PFNWGLENUMGPUDEVICESNVPROC __wglewEnumGpuDevicesNV; +WGLEW_EXPORT PFNWGLENUMGPUSFROMAFFINITYDCNVPROC __wglewEnumGpusFromAffinityDCNV; +WGLEW_EXPORT PFNWGLENUMGPUSNVPROC __wglewEnumGpusNV; + +WGLEW_EXPORT PFNWGLBINDVIDEODEVICENVPROC __wglewBindVideoDeviceNV; +WGLEW_EXPORT PFNWGLENUMERATEVIDEODEVICESNVPROC __wglewEnumerateVideoDevicesNV; +WGLEW_EXPORT PFNWGLQUERYCURRENTCONTEXTNVPROC __wglewQueryCurrentContextNV; + +WGLEW_EXPORT PFNWGLBINDSWAPBARRIERNVPROC __wglewBindSwapBarrierNV; +WGLEW_EXPORT PFNWGLJOINSWAPGROUPNVPROC __wglewJoinSwapGroupNV; +WGLEW_EXPORT PFNWGLQUERYFRAMECOUNTNVPROC __wglewQueryFrameCountNV; +WGLEW_EXPORT PFNWGLQUERYMAXSWAPGROUPSNVPROC __wglewQueryMaxSwapGroupsNV; +WGLEW_EXPORT PFNWGLQUERYSWAPGROUPNVPROC __wglewQuerySwapGroupNV; +WGLEW_EXPORT PFNWGLRESETFRAMECOUNTNVPROC __wglewResetFrameCountNV; + +WGLEW_EXPORT PFNWGLALLOCATEMEMORYNVPROC __wglewAllocateMemoryNV; +WGLEW_EXPORT PFNWGLFREEMEMORYNVPROC __wglewFreeMemoryNV; + +WGLEW_EXPORT PFNWGLBINDVIDEOIMAGENVPROC __wglewBindVideoImageNV; +WGLEW_EXPORT PFNWGLGETVIDEODEVICENVPROC __wglewGetVideoDeviceNV; +WGLEW_EXPORT PFNWGLGETVIDEOINFONVPROC __wglewGetVideoInfoNV; +WGLEW_EXPORT PFNWGLRELEASEVIDEODEVICENVPROC __wglewReleaseVideoDeviceNV; +WGLEW_EXPORT PFNWGLRELEASEVIDEOIMAGENVPROC __wglewReleaseVideoImageNV; +WGLEW_EXPORT PFNWGLSENDPBUFFERTOVIDEONVPROC __wglewSendPbufferToVideoNV; + +WGLEW_EXPORT PFNWGLGETMSCRATEOMLPROC __wglewGetMscRateOML; +WGLEW_EXPORT PFNWGLGETSYNCVALUESOMLPROC __wglewGetSyncValuesOML; +WGLEW_EXPORT PFNWGLSWAPBUFFERSMSCOMLPROC __wglewSwapBuffersMscOML; +WGLEW_EXPORT PFNWGLSWAPLAYERBUFFERSMSCOMLPROC __wglewSwapLayerBuffersMscOML; +WGLEW_EXPORT PFNWGLWAITFORMSCOMLPROC __wglewWaitForMscOML; +WGLEW_EXPORT PFNWGLWAITFORSBCOMLPROC __wglewWaitForSbcOML; +WGLEW_EXPORT GLboolean __WGLEW_3DFX_multisample; +WGLEW_EXPORT GLboolean __WGLEW_3DL_stereo_control; +WGLEW_EXPORT GLboolean __WGLEW_ARB_buffer_region; +WGLEW_EXPORT GLboolean __WGLEW_ARB_create_context; +WGLEW_EXPORT GLboolean __WGLEW_ARB_extensions_string; +WGLEW_EXPORT GLboolean __WGLEW_ARB_framebuffer_sRGB; +WGLEW_EXPORT GLboolean __WGLEW_ARB_make_current_read; +WGLEW_EXPORT GLboolean __WGLEW_ARB_multisample; +WGLEW_EXPORT GLboolean __WGLEW_ARB_pbuffer; +WGLEW_EXPORT GLboolean __WGLEW_ARB_pixel_format; +WGLEW_EXPORT GLboolean __WGLEW_ARB_pixel_format_float; +WGLEW_EXPORT GLboolean __WGLEW_ARB_render_texture; +WGLEW_EXPORT GLboolean __WGLEW_ATI_pixel_format_float; +WGLEW_EXPORT GLboolean __WGLEW_ATI_render_texture_rectangle; +WGLEW_EXPORT GLboolean __WGLEW_EXT_depth_float; +WGLEW_EXPORT GLboolean __WGLEW_EXT_display_color_table; +WGLEW_EXPORT GLboolean __WGLEW_EXT_extensions_string; +WGLEW_EXPORT GLboolean __WGLEW_EXT_framebuffer_sRGB; +WGLEW_EXPORT GLboolean __WGLEW_EXT_make_current_read; +WGLEW_EXPORT GLboolean __WGLEW_EXT_multisample; +WGLEW_EXPORT GLboolean __WGLEW_EXT_pbuffer; +WGLEW_EXPORT GLboolean __WGLEW_EXT_pixel_format; +WGLEW_EXPORT GLboolean __WGLEW_EXT_pixel_format_packed_float; +WGLEW_EXPORT GLboolean __WGLEW_EXT_swap_control; +WGLEW_EXPORT GLboolean __WGLEW_I3D_digital_video_control; +WGLEW_EXPORT GLboolean __WGLEW_I3D_gamma; +WGLEW_EXPORT GLboolean __WGLEW_I3D_genlock; +WGLEW_EXPORT GLboolean __WGLEW_I3D_image_buffer; +WGLEW_EXPORT GLboolean __WGLEW_I3D_swap_frame_lock; +WGLEW_EXPORT GLboolean __WGLEW_I3D_swap_frame_usage; +WGLEW_EXPORT GLboolean __WGLEW_NV_float_buffer; +WGLEW_EXPORT GLboolean __WGLEW_NV_gpu_affinity; +WGLEW_EXPORT GLboolean __WGLEW_NV_present_video; +WGLEW_EXPORT GLboolean __WGLEW_NV_render_depth_texture; +WGLEW_EXPORT GLboolean __WGLEW_NV_render_texture_rectangle; +WGLEW_EXPORT GLboolean __WGLEW_NV_swap_group; +WGLEW_EXPORT GLboolean __WGLEW_NV_vertex_array_range; +WGLEW_EXPORT GLboolean __WGLEW_NV_video_output; +WGLEW_EXPORT GLboolean __WGLEW_OML_sync_control; + +#ifdef GLEW_MX +}; /* WGLEWContextStruct */ +#endif /* GLEW_MX */ + +/* ------------------------------------------------------------------------- */ + +#ifdef GLEW_MX + +typedef struct WGLEWContextStruct WGLEWContext; +GLEWAPI GLenum wglewContextInit (WGLEWContext* ctx); +GLEWAPI GLboolean wglewContextIsSupported (WGLEWContext* ctx, const char* name); + +#define wglewInit() wglewContextInit(wglewGetContext()) +#define wglewIsSupported(x) wglewContextIsSupported(wglewGetContext(), x) + +#define WGLEW_GET_VAR(x) (*(const GLboolean*)&(wglewGetContext()->x)) +#define WGLEW_GET_FUN(x) wglewGetContext()->x + +#else /* GLEW_MX */ + +#define WGLEW_GET_VAR(x) (*(const GLboolean*)&x) +#define WGLEW_GET_FUN(x) x + +GLEWAPI GLboolean wglewIsSupported (const char* name); + +#endif /* GLEW_MX */ + +GLEWAPI GLboolean wglewGetExtension (const char* name); + +#ifdef __cplusplus +} +#endif + +#undef GLEWAPI + +#endif /* __wglew_h__ */ diff --git a/mod/pub.mod/glew.mod/glew.bmx b/mod/pub.mod/glew.mod/glew.bmx new file mode 100644 index 0000000..3a8c02b --- /dev/null +++ b/mod/pub.mod/glew.mod/glew.bmx @@ -0,0 +1,4415 @@ + +Strict + +Module Pub.Glew + +ModuleInfo "Version: 1.07" +ModuleInfo "Author: Milan Ikits, Marcelo Magallon" +ModuleInfo "License: SGI Free Software License B" +ModuleInfo "Copyright: Milan Ikits, Marcelo Magallon" +ModuleInfo "Modserver: BRL" + +ModuleInfo "History: 1.07 Release" +ModuleInfo "History: Updated to glew 1.5.1" +ModuleInfo "History: Modified glew2bmx to handle a GLint64EXT, GLuint64EXT and char - UNTESTED!" +ModuleInfo "History: 1.06 Release" +ModuleInfo "History: Rebuilt to fix MacOS ld errors" +ModuleInfo "History: 1.05 Release" +ModuleInfo "History: Removed glew2bmx.exe!" +ModuleInfo "History: 1.04 Release" +ModuleInfo "History: Updated to glew 1.3.4" +ModuleInfo "History: 1.03 Release" +ModuleInfo "History: Updated to GL2.0 compatible version 1.3.3" + +Import Pub.OpenGL + +Import "glew_static.c" + +Extern "Os" + +Global GL_VERSION_1_1:Byte="__GLEW_VERSION_1_1" +Const GL_SMOOTH_POINT_SIZE_RANGE=$0B12 +Const GL_SMOOTH_POINT_SIZE_GRANULARITY=$0B13 +Const GL_SMOOTH_LINE_WIDTH_RANGE=$0B22 +Const GL_SMOOTH_LINE_WIDTH_GRANULARITY=$0B23 +Const GL_UNSIGNED_BYTE_3_3_2=$8032 +Const GL_UNSIGNED_SHORT_4_4_4_4=$8033 +Const GL_UNSIGNED_SHORT_5_5_5_1=$8034 +Const GL_UNSIGNED_INT_8_8_8_8=$8035 +Const GL_UNSIGNED_INT_10_10_10_2=$8036 +Const GL_RESCALE_NORMAL=$803A +Const GL_TEXTURE_BINDING_3D=$806A +Const GL_PACK_SKIP_IMAGES=$806B +Const GL_PACK_IMAGE_HEIGHT=$806C +Const GL_UNPACK_SKIP_IMAGES=$806D +Const GL_UNPACK_IMAGE_HEIGHT=$806E +Const GL_TEXTURE_3D=$806F +Const GL_PROXY_TEXTURE_3D=$8070 +Const GL_TEXTURE_DEPTH=$8071 +Const GL_TEXTURE_WRAP_R=$8072 +Const GL_MAX_3D_TEXTURE_SIZE=$8073 +Const GL_BGR=$80E0 +Const GL_BGRA=$80E1 +Const GL_MAX_ELEMENTS_VERTICES=$80E8 +Const GL_MAX_ELEMENTS_INDICES=$80E9 +Const GL_CLAMP_TO_EDGE=$812F +Const GL_TEXTURE_MIN_LOD=$813A +Const GL_TEXTURE_MAX_LOD=$813B +Const GL_TEXTURE_BASE_LEVEL=$813C +Const GL_TEXTURE_MAX_LEVEL=$813D +Const GL_LIGHT_MODEL_COLOR_CONTROL=$81F8 +Const GL_SINGLE_COLOR=$81F9 +Const GL_SEPARATE_SPECULAR_COLOR=$81FA +Const GL_UNSIGNED_BYTE_2_3_3_REV=$8362 +Const GL_UNSIGNED_SHORT_5_6_5=$8363 +Const GL_UNSIGNED_SHORT_5_6_5_REV=$8364 +Const GL_UNSIGNED_SHORT_4_4_4_4_REV=$8365 +Const GL_UNSIGNED_SHORT_1_5_5_5_REV=$8366 +Const GL_UNSIGNED_INT_8_8_8_8_REV=$8367 +Const GL_UNSIGNED_INT_2_10_10_10_REV=$8368 +Const GL_ALIASED_POINT_SIZE_RANGE=$846D +Const GL_ALIASED_LINE_WIDTH_RANGE=$846E +Global glCopyTexSubImage3D(target_:Int,level_:Int,xoffset_:Int,yoffset_:Int,zoffset_:Int,x_:Int,y_:Int,width_:Int,height_:Int)="__glewCopyTexSubImage3D" +Global glDrawRangeElements(mode_:Int,start_:Int,end_:Int,count_:Int,type_:Int,indices_:Byte Ptr)="__glewDrawRangeElements" +Global glTexImage3D(target_:Int,level_:Int,internalFormat_:Int,width_:Int,height_:Int,depth_:Int,border_:Int,format_:Int,type_:Int,pixels_:Byte Ptr)="__glewTexImage3D" +Global glTexSubImage3D(target_:Int,level_:Int,xoffset_:Int,yoffset_:Int,zoffset_:Int,width_:Int,height_:Int,depth_:Int,format_:Int,type_:Int,pixels_:Byte Ptr)="__glewTexSubImage3D" +Global GL_VERSION_1_2:Byte="__GLEW_VERSION_1_2" +Const GL_MULTISAMPLE=$809D +Const GL_SAMPLE_ALPHA_TO_COVERAGE=$809E +Const GL_SAMPLE_ALPHA_TO_ONE=$809F +Const GL_SAMPLE_COVERAGE=$80A0 +Const GL_SAMPLE_BUFFERS=$80A8 +Const GL_SAMPLES=$80A9 +Const GL_SAMPLE_COVERAGE_VALUE=$80AA +Const GL_SAMPLE_COVERAGE_INVERT=$80AB +Const GL_CLAMP_TO_BORDER=$812D +Const GL_TEXTURE0=$84C0 +Const GL_TEXTURE1=$84C1 +Const GL_TEXTURE2=$84C2 +Const GL_TEXTURE3=$84C3 +Const GL_TEXTURE4=$84C4 +Const GL_TEXTURE5=$84C5 +Const GL_TEXTURE6=$84C6 +Const GL_TEXTURE7=$84C7 +Const GL_TEXTURE8=$84C8 +Const GL_TEXTURE9=$84C9 +Const GL_TEXTURE10=$84CA +Const GL_TEXTURE11=$84CB +Const GL_TEXTURE12=$84CC +Const GL_TEXTURE13=$84CD +Const GL_TEXTURE14=$84CE +Const GL_TEXTURE15=$84CF +Const GL_TEXTURE16=$84D0 +Const GL_TEXTURE17=$84D1 +Const GL_TEXTURE18=$84D2 +Const GL_TEXTURE19=$84D3 +Const GL_TEXTURE20=$84D4 +Const GL_TEXTURE21=$84D5 +Const GL_TEXTURE22=$84D6 +Const GL_TEXTURE23=$84D7 +Const GL_TEXTURE24=$84D8 +Const GL_TEXTURE25=$84D9 +Const GL_TEXTURE26=$84DA +Const GL_TEXTURE27=$84DB +Const GL_TEXTURE28=$84DC +Const GL_TEXTURE29=$84DD +Const GL_TEXTURE30=$84DE +Const GL_TEXTURE31=$84DF +Const GL_ACTIVE_TEXTURE=$84E0 +Const GL_CLIENT_ACTIVE_TEXTURE=$84E1 +Const GL_MAX_TEXTURE_UNITS=$84E2 +Const GL_TRANSPOSE_MODELVIEW_MATRIX=$84E3 +Const GL_TRANSPOSE_PROJECTION_MATRIX=$84E4 +Const GL_TRANSPOSE_TEXTURE_MATRIX=$84E5 +Const GL_TRANSPOSE_COLOR_MATRIX=$84E6 +Const GL_SUBTRACT=$84E7 +Const GL_COMPRESSED_ALPHA=$84E9 +Const GL_COMPRESSED_LUMINANCE=$84EA +Const GL_COMPRESSED_LUMINANCE_ALPHA=$84EB +Const GL_COMPRESSED_INTENSITY=$84EC +Const GL_COMPRESSED_RGB=$84ED +Const GL_COMPRESSED_RGBA=$84EE +Const GL_TEXTURE_COMPRESSION_HINT=$84EF +Const GL_NORMAL_MAP=$8511 +Const GL_REFLECTION_MAP=$8512 +Const GL_TEXTURE_CUBE_MAP=$8513 +Const GL_TEXTURE_BINDING_CUBE_MAP=$8514 +Const GL_TEXTURE_CUBE_MAP_POSITIVE_X=$8515 +Const GL_TEXTURE_CUBE_MAP_NEGATIVE_X=$8516 +Const GL_TEXTURE_CUBE_MAP_POSITIVE_Y=$8517 +Const GL_TEXTURE_CUBE_MAP_NEGATIVE_Y=$8518 +Const GL_TEXTURE_CUBE_MAP_POSITIVE_Z=$8519 +Const GL_TEXTURE_CUBE_MAP_NEGATIVE_Z=$851A +Const GL_PROXY_TEXTURE_CUBE_MAP=$851B +Const GL_MAX_CUBE_MAP_TEXTURE_SIZE=$851C +Const GL_COMBINE=$8570 +Const GL_COMBINE_RGB=$8571 +Const GL_COMBINE_ALPHA=$8572 +Const GL_RGB_SCALE=$8573 +Const GL_ADD_SIGNED=$8574 +Const GL_INTERPOLATE=$8575 +Const GL_CONSTANT=$8576 +Const GL_PRIMARY_COLOR=$8577 +Const GL_PREVIOUS=$8578 +Const GL_SOURCE0_RGB=$8580 +Const GL_SOURCE1_RGB=$8581 +Const GL_SOURCE2_RGB=$8582 +Const GL_SOURCE0_ALPHA=$8588 +Const GL_SOURCE1_ALPHA=$8589 +Const GL_SOURCE2_ALPHA=$858A +Const GL_OPERAND0_RGB=$8590 +Const GL_OPERAND1_RGB=$8591 +Const GL_OPERAND2_RGB=$8592 +Const GL_OPERAND0_ALPHA=$8598 +Const GL_OPERAND1_ALPHA=$8599 +Const GL_OPERAND2_ALPHA=$859A +Const GL_TEXTURE_COMPRESSED_IMAGE_SIZE=$86A0 +Const GL_TEXTURE_COMPRESSED=$86A1 +Const GL_NUM_COMPRESSED_TEXTURE_FORMATS=$86A2 +Const GL_COMPRESSED_TEXTURE_FORMATS=$86A3 +Const GL_DOT3_RGB=$86AE +Const GL_DOT3_RGBA=$86AF +Const GL_MULTISAMPLE_BIT=$20000000 +Global glActiveTexture(texture_:Int)="__glewActiveTexture" +Global glClientActiveTexture(texture_:Int)="__glewClientActiveTexture" +Global glCompressedTexImage1D(target_:Int,level_:Int,internalformat_:Int,width_:Int,border_:Int,imageSize_:Int,data_:Byte Ptr)="__glewCompressedTexImage1D" +Global glCompressedTexImage2D(target_:Int,level_:Int,internalformat_:Int,width_:Int,height_:Int,border_:Int,imageSize_:Int,data_:Byte Ptr)="__glewCompressedTexImage2D" +Global glCompressedTexImage3D(target_:Int,level_:Int,internalformat_:Int,width_:Int,height_:Int,depth_:Int,border_:Int,imageSize_:Int,data_:Byte Ptr)="__glewCompressedTexImage3D" +Global glCompressedTexSubImage1D(target_:Int,level_:Int,xoffset_:Int,width_:Int,format_:Int,imageSize_:Int,data_:Byte Ptr)="__glewCompressedTexSubImage1D" +Global glCompressedTexSubImage2D(target_:Int,level_:Int,xoffset_:Int,yoffset_:Int,width_:Int,height_:Int,format_:Int,imageSize_:Int,data_:Byte Ptr)="__glewCompressedTexSubImage2D" +Global glCompressedTexSubImage3D(target_:Int,level_:Int,xoffset_:Int,yoffset_:Int,zoffset_:Int,width_:Int,height_:Int,depth_:Int,format_:Int,imageSize_:Int,data_:Byte Ptr)="__glewCompressedTexSubImage3D" +Global glGetCompressedTexImage(target_:Int,lod_:Int,img_:Byte Ptr)="__glewGetCompressedTexImage" +Global glLoadTransposeMatrixd(m_:Double Ptr)="__glewLoadTransposeMatrixd" +Global glLoadTransposeMatrixf(m_:Float Ptr)="__glewLoadTransposeMatrixf" +Global glMultTransposeMatrixd(m_:Double Ptr)="__glewMultTransposeMatrixd" +Global glMultTransposeMatrixf(m_:Float Ptr)="__glewMultTransposeMatrixf" +Global glMultiTexCoord1d(target_:Int,s_:Double)="__glewMultiTexCoord1d" +Global glMultiTexCoord1dv(target_:Int,v_:Double Ptr)="__glewMultiTexCoord1dv" +Global glMultiTexCoord1f(target_:Int,s_:Float)="__glewMultiTexCoord1f" +Global glMultiTexCoord1fv(target_:Int,v_:Float Ptr)="__glewMultiTexCoord1fv" +Global glMultiTexCoord1i(target_:Int,s_:Int)="__glewMultiTexCoord1i" +Global glMultiTexCoord1iv(target_:Int,v_:Int Ptr)="__glewMultiTexCoord1iv" +Global glMultiTexCoord1s(target_:Int,s_:Short)="__glewMultiTexCoord1s" +Global glMultiTexCoord1sv(target_:Int,v_:Short Ptr)="__glewMultiTexCoord1sv" +Global glMultiTexCoord2d(target_:Int,s_:Double,t_:Double)="__glewMultiTexCoord2d" +Global glMultiTexCoord2dv(target_:Int,v_:Double Ptr)="__glewMultiTexCoord2dv" +Global glMultiTexCoord2f(target_:Int,s_:Float,t_:Float)="__glewMultiTexCoord2f" +Global glMultiTexCoord2fv(target_:Int,v_:Float Ptr)="__glewMultiTexCoord2fv" +Global glMultiTexCoord2i(target_:Int,s_:Int,t_:Int)="__glewMultiTexCoord2i" +Global glMultiTexCoord2iv(target_:Int,v_:Int Ptr)="__glewMultiTexCoord2iv" +Global glMultiTexCoord2s(target_:Int,s_:Short,t_:Short)="__glewMultiTexCoord2s" +Global glMultiTexCoord2sv(target_:Int,v_:Short Ptr)="__glewMultiTexCoord2sv" +Global glMultiTexCoord3d(target_:Int,s_:Double,t_:Double,r_:Double)="__glewMultiTexCoord3d" +Global glMultiTexCoord3dv(target_:Int,v_:Double Ptr)="__glewMultiTexCoord3dv" +Global glMultiTexCoord3f(target_:Int,s_:Float,t_:Float,r_:Float)="__glewMultiTexCoord3f" +Global glMultiTexCoord3fv(target_:Int,v_:Float Ptr)="__glewMultiTexCoord3fv" +Global glMultiTexCoord3i(target_:Int,s_:Int,t_:Int,r_:Int)="__glewMultiTexCoord3i" +Global glMultiTexCoord3iv(target_:Int,v_:Int Ptr)="__glewMultiTexCoord3iv" +Global glMultiTexCoord3s(target_:Int,s_:Short,t_:Short,r_:Short)="__glewMultiTexCoord3s" +Global glMultiTexCoord3sv(target_:Int,v_:Short Ptr)="__glewMultiTexCoord3sv" +Global glMultiTexCoord4d(target_:Int,s_:Double,t_:Double,r_:Double,q_:Double)="__glewMultiTexCoord4d" +Global glMultiTexCoord4dv(target_:Int,v_:Double Ptr)="__glewMultiTexCoord4dv" +Global glMultiTexCoord4f(target_:Int,s_:Float,t_:Float,r_:Float,q_:Float)="__glewMultiTexCoord4f" +Global glMultiTexCoord4fv(target_:Int,v_:Float Ptr)="__glewMultiTexCoord4fv" +Global glMultiTexCoord4i(target_:Int,s_:Int,t_:Int,r_:Int,q_:Int)="__glewMultiTexCoord4i" +Global glMultiTexCoord4iv(target_:Int,v_:Int Ptr)="__glewMultiTexCoord4iv" +Global glMultiTexCoord4s(target_:Int,s_:Short,t_:Short,r_:Short,q_:Short)="__glewMultiTexCoord4s" +Global glMultiTexCoord4sv(target_:Int,v_:Short Ptr)="__glewMultiTexCoord4sv" +Global glSampleCoverage(value_:Float,invert_:Byte)="__glewSampleCoverage" +Global GL_VERSION_1_3:Byte="__GLEW_VERSION_1_3" +Const GL_BLEND_DST_RGB=$80C8 +Const GL_BLEND_SRC_RGB=$80C9 +Const GL_BLEND_DST_ALPHA=$80CA +Const GL_BLEND_SRC_ALPHA=$80CB +Const GL_POINT_SIZE_MIN=$8126 +Const GL_POINT_SIZE_MAX=$8127 +Const GL_POINT_FADE_THRESHOLD_SIZE=$8128 +Const GL_POINT_DISTANCE_ATTENUATION=$8129 +Const GL_GENERATE_MIPMAP=$8191 +Const GL_GENERATE_MIPMAP_HINT=$8192 +Const GL_DEPTH_COMPONENT16=$81A5 +Const GL_DEPTH_COMPONENT24=$81A6 +Const GL_DEPTH_COMPONENT32=$81A7 +Const GL_MIRRORED_REPEAT=$8370 +Const GL_FOG_COORDINATE_SOURCE=$8450 +Const GL_FOG_COORDINATE=$8451 +Const GL_FRAGMENT_DEPTH=$8452 +Const GL_CURRENT_FOG_COORDINATE=$8453 +Const GL_FOG_COORDINATE_ARRAY_TYPE=$8454 +Const GL_FOG_COORDINATE_ARRAY_STRIDE=$8455 +Const GL_FOG_COORDINATE_ARRAY_POINTER=$8456 +Const GL_FOG_COORDINATE_ARRAY=$8457 +Const GL_COLOR_SUM=$8458 +Const GL_CURRENT_SECONDARY_COLOR=$8459 +Const GL_SECONDARY_COLOR_ARRAY_SIZE=$845A +Const GL_SECONDARY_COLOR_ARRAY_TYPE=$845B +Const GL_SECONDARY_COLOR_ARRAY_STRIDE=$845C +Const GL_SECONDARY_COLOR_ARRAY_POINTER=$845D +Const GL_SECONDARY_COLOR_ARRAY=$845E +Const GL_MAX_TEXTURE_LOD_BIAS=$84FD +Const GL_TEXTURE_FILTER_CONTROL=$8500 +Const GL_TEXTURE_LOD_BIAS=$8501 +Const GL_INCR_WRAP=$8507 +Const GL_DECR_WRAP=$8508 +Const GL_TEXTURE_DEPTH_SIZE=$884A +Const GL_DEPTH_TEXTURE_MODE=$884B +Const GL_TEXTURE_COMPARE_MODE=$884C +Const GL_TEXTURE_COMPARE_FUNC=$884D +Const GL_COMPARE_R_TO_TEXTURE=$884E +Global glBlendColor(red_:Float,green_:Float,blue_:Float,alpha_:Float)="__glewBlendColor" +Global glBlendEquation(mode_:Int)="__glewBlendEquation" +Global glBlendFuncSeparate(sfactorRGB_:Int,dfactorRGB_:Int,sfactorAlpha_:Int,dfactorAlpha_:Int)="__glewBlendFuncSeparate" +Global glFogCoordPointer(type_:Int,stride_:Int,pointer_:Byte Ptr)="__glewFogCoordPointer" +Global glFogCoordd(coord_:Double)="__glewFogCoordd" +Global glFogCoorddv(coord_:Double Ptr)="__glewFogCoorddv" +Global glFogCoordf(coord_:Float)="__glewFogCoordf" +Global glFogCoordfv(coord_:Float Ptr)="__glewFogCoordfv" +Global glMultiDrawArrays(mode_:Int,first_:Int Ptr,count_:Int Ptr,primcount_:Int)="__glewMultiDrawArrays" +Global glMultiDrawElements(mode_:Int,count_:Int Ptr,type_:Int,indices_:Byte Ptr Ptr,primcount_:Int)="__glewMultiDrawElements" +Global glPointParameterf(pname_:Int,param_:Float)="__glewPointParameterf" +Global glPointParameterfv(pname_:Int,params_:Float Ptr)="__glewPointParameterfv" +Global glPointParameteri(pname_:Int,param_:Int)="__glewPointParameteri" +Global glPointParameteriv(pname_:Int,params_:Int Ptr)="__glewPointParameteriv" +Global glSecondaryColor3b(red_:Byte,green_:Byte,blue_:Byte)="__glewSecondaryColor3b" +Global glSecondaryColor3bv(v_:Byte Ptr)="__glewSecondaryColor3bv" +Global glSecondaryColor3d(red_:Double,green_:Double,blue_:Double)="__glewSecondaryColor3d" +Global glSecondaryColor3dv(v_:Double Ptr)="__glewSecondaryColor3dv" +Global glSecondaryColor3f(red_:Float,green_:Float,blue_:Float)="__glewSecondaryColor3f" +Global glSecondaryColor3fv(v_:Float Ptr)="__glewSecondaryColor3fv" +Global glSecondaryColor3i(red_:Int,green_:Int,blue_:Int)="__glewSecondaryColor3i" +Global glSecondaryColor3iv(v_:Int Ptr)="__glewSecondaryColor3iv" +Global glSecondaryColor3s(red_:Short,green_:Short,blue_:Short)="__glewSecondaryColor3s" +Global glSecondaryColor3sv(v_:Short Ptr)="__glewSecondaryColor3sv" +Global glSecondaryColor3ub(red_:Byte,green_:Byte,blue_:Byte)="__glewSecondaryColor3ub" +Global glSecondaryColor3ubv(v_:Byte Ptr)="__glewSecondaryColor3ubv" +Global glSecondaryColor3ui(red_:Int,green_:Int,blue_:Int)="__glewSecondaryColor3ui" +Global glSecondaryColor3uiv(v_:Int Ptr)="__glewSecondaryColor3uiv" +Global glSecondaryColor3us(red_:Short,green_:Short,blue_:Short)="__glewSecondaryColor3us" +Global glSecondaryColor3usv(v_:Short Ptr)="__glewSecondaryColor3usv" +Global glSecondaryColorPointer(size_:Int,type_:Int,stride_:Int,pointer_:Byte Ptr)="__glewSecondaryColorPointer" +Global glWindowPos2d(x_:Double,y_:Double)="__glewWindowPos2d" +Global glWindowPos2dv(p_:Double Ptr)="__glewWindowPos2dv" +Global glWindowPos2f(x_:Float,y_:Float)="__glewWindowPos2f" +Global glWindowPos2fv(p_:Float Ptr)="__glewWindowPos2fv" +Global glWindowPos2i(x_:Int,y_:Int)="__glewWindowPos2i" +Global glWindowPos2iv(p_:Int Ptr)="__glewWindowPos2iv" +Global glWindowPos2s(x_:Short,y_:Short)="__glewWindowPos2s" +Global glWindowPos2sv(p_:Short Ptr)="__glewWindowPos2sv" +Global glWindowPos3d(x_:Double,y_:Double,z_:Double)="__glewWindowPos3d" +Global glWindowPos3dv(p_:Double Ptr)="__glewWindowPos3dv" +Global glWindowPos3f(x_:Float,y_:Float,z_:Float)="__glewWindowPos3f" +Global glWindowPos3fv(p_:Float Ptr)="__glewWindowPos3fv" +Global glWindowPos3i(x_:Int,y_:Int,z_:Int)="__glewWindowPos3i" +Global glWindowPos3iv(p_:Int Ptr)="__glewWindowPos3iv" +Global glWindowPos3s(x_:Short,y_:Short,z_:Short)="__glewWindowPos3s" +Global glWindowPos3sv(p_:Short Ptr)="__glewWindowPos3sv" +Global GL_VERSION_1_4:Byte="__GLEW_VERSION_1_4" +Const GL_BUFFER_SIZE=$8764 +Const GL_BUFFER_USAGE=$8765 +Const GL_QUERY_COUNTER_BITS=$8864 +Const GL_CURRENT_QUERY=$8865 +Const GL_QUERY_RESULT=$8866 +Const GL_QUERY_RESULT_AVAILABLE=$8867 +Const GL_ARRAY_BUFFER=$8892 +Const GL_ELEMENT_ARRAY_BUFFER=$8893 +Const GL_ARRAY_BUFFER_BINDING=$8894 +Const GL_ELEMENT_ARRAY_BUFFER_BINDING=$8895 +Const GL_VERTEX_ARRAY_BUFFER_BINDING=$8896 +Const GL_NORMAL_ARRAY_BUFFER_BINDING=$8897 +Const GL_COLOR_ARRAY_BUFFER_BINDING=$8898 +Const GL_INDEX_ARRAY_BUFFER_BINDING=$8899 +Const GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING=$889A +Const GL_EDGE_FLAG_ARRAY_BUFFER_BINDING=$889B +Const GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING=$889C +Const GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING=$889D +Const GL_WEIGHT_ARRAY_BUFFER_BINDING=$889E +Const GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING=$889F +Const GL_READ_ONLY=$88B8 +Const GL_WRITE_ONLY=$88B9 +Const GL_READ_WRITE=$88BA +Const GL_BUFFER_ACCESS=$88BB +Const GL_BUFFER_MAPPED=$88BC +Const GL_BUFFER_MAP_POINTER=$88BD +Const GL_STREAM_DRAW=$88E0 +Const GL_STREAM_READ=$88E1 +Const GL_STREAM_COPY=$88E2 +Const GL_STATIC_DRAW=$88E4 +Const GL_STATIC_READ=$88E5 +Const GL_STATIC_COPY=$88E6 +Const GL_DYNAMIC_DRAW=$88E8 +Const GL_DYNAMIC_READ=$88E9 +Const GL_DYNAMIC_COPY=$88EA +Const GL_SAMPLES_PASSED=$8914 +Global glBeginQuery(target_:Int,id_:Int)="__glewBeginQuery" +Global glBindBuffer(target_:Int,buffer_:Int)="__glewBindBuffer" +Global glBufferData(target_:Int,size_:Int,data_:Byte Ptr,usage_:Int)="__glewBufferData" +Global glBufferSubData(target_:Int,offset_:Int,size_:Int,data_:Byte Ptr)="__glewBufferSubData" +Global glDeleteBuffers(n_:Int,buffers_:Int Ptr)="__glewDeleteBuffers" +Global glDeleteQueries(n_:Int,ids_:Int Ptr)="__glewDeleteQueries" +Global glEndQuery(target_:Int)="__glewEndQuery" +Global glGenBuffers(n_:Int,buffers_:Int Ptr)="__glewGenBuffers" +Global glGenQueries(n_:Int,ids_:Int Ptr)="__glewGenQueries" +Global glGetBufferParameteriv(target_:Int,pname_:Int,params_:Int Ptr)="__glewGetBufferParameteriv" +Global glGetBufferPointerv(target_:Int,pname_:Int,params_:Byte Ptr Ptr)="__glewGetBufferPointerv" +Global glGetBufferSubData(target_:Int,offset_:Int,size_:Int,data_:Byte Ptr)="__glewGetBufferSubData" +Global glGetQueryObjectiv(id_:Int,pname_:Int,params_:Int Ptr)="__glewGetQueryObjectiv" +Global glGetQueryObjectuiv(id_:Int,pname_:Int,params_:Int Ptr)="__glewGetQueryObjectuiv" +Global glGetQueryiv(target_:Int,pname_:Int,params_:Int Ptr)="__glewGetQueryiv" +Global glIsBuffer:Byte(buffer_:Int)="__glewIsBuffer" +Global glIsQuery:Byte(id_:Int)="__glewIsQuery" +Global glMapBuffer:Byte Ptr(target_:Int,access_:Int)="__glewMapBuffer" +Global glUnmapBuffer:Byte(target_:Int)="__glewUnmapBuffer" +Global GL_VERSION_1_5:Byte="__GLEW_VERSION_1_5" +Const GL_VERTEX_ATTRIB_ARRAY_ENABLED=$8622 +Const GL_VERTEX_ATTRIB_ARRAY_SIZE=$8623 +Const GL_VERTEX_ATTRIB_ARRAY_STRIDE=$8624 +Const GL_VERTEX_ATTRIB_ARRAY_TYPE=$8625 +Const GL_CURRENT_VERTEX_ATTRIB=$8626 +Const GL_VERTEX_PROGRAM_POINT_SIZE=$8642 +Const GL_VERTEX_PROGRAM_TWO_SIDE=$8643 +Const GL_VERTEX_ATTRIB_ARRAY_POINTER=$8645 +Const GL_STENCIL_BACK_FUNC=$8800 +Const GL_STENCIL_BACK_FAIL=$8801 +Const GL_STENCIL_BACK_PASS_DEPTH_FAIL=$8802 +Const GL_STENCIL_BACK_PASS_DEPTH_PASS=$8803 +Const GL_MAX_DRAW_BUFFERS=$8824 +Const GL_DRAW_BUFFER0=$8825 +Const GL_DRAW_BUFFER1=$8826 +Const GL_DRAW_BUFFER2=$8827 +Const GL_DRAW_BUFFER3=$8828 +Const GL_DRAW_BUFFER4=$8829 +Const GL_DRAW_BUFFER5=$882A +Const GL_DRAW_BUFFER6=$882B +Const GL_DRAW_BUFFER7=$882C +Const GL_DRAW_BUFFER8=$882D +Const GL_DRAW_BUFFER9=$882E +Const GL_DRAW_BUFFER10=$882F +Const GL_DRAW_BUFFER11=$8830 +Const GL_DRAW_BUFFER12=$8831 +Const GL_DRAW_BUFFER13=$8832 +Const GL_DRAW_BUFFER14=$8833 +Const GL_DRAW_BUFFER15=$8834 +Const GL_BLEND_EQUATION_ALPHA=$883D +Const GL_POINT_SPRITE=$8861 +Const GL_COORD_REPLACE=$8862 +Const GL_MAX_VERTEX_ATTRIBS=$8869 +Const GL_VERTEX_ATTRIB_ARRAY_NORMALIZED=$886A +Const GL_MAX_TEXTURE_COORDS=$8871 +Const GL_MAX_TEXTURE_IMAGE_UNITS=$8872 +Const GL_FRAGMENT_SHADER=$8B30 +Const GL_VERTEX_SHADER=$8B31 +Const GL_MAX_FRAGMENT_UNIFORM_COMPONENTS=$8B49 +Const GL_MAX_VERTEX_UNIFORM_COMPONENTS=$8B4A +Const GL_MAX_VARYING_FLOATS=$8B4B +Const GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS=$8B4C +Const GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS=$8B4D +Const GL_SHADER_TYPE=$8B4F +Const GL_FLOAT_VEC2=$8B50 +Const GL_FLOAT_VEC3=$8B51 +Const GL_FLOAT_VEC4=$8B52 +Const GL_INT_VEC2=$8B53 +Const GL_INT_VEC3=$8B54 +Const GL_INT_VEC4=$8B55 +Const GL_BOOL=$8B56 +Const GL_BOOL_VEC2=$8B57 +Const GL_BOOL_VEC3=$8B58 +Const GL_BOOL_VEC4=$8B59 +Const GL_FLOAT_MAT2=$8B5A +Const GL_FLOAT_MAT3=$8B5B +Const GL_FLOAT_MAT4=$8B5C +Const GL_SAMPLER_1D=$8B5D +Const GL_SAMPLER_2D=$8B5E +Const GL_SAMPLER_3D=$8B5F +Const GL_SAMPLER_CUBE=$8B60 +Const GL_SAMPLER_1D_SHADOW=$8B61 +Const GL_SAMPLER_2D_SHADOW=$8B62 +Const GL_DELETE_STATUS=$8B80 +Const GL_COMPILE_STATUS=$8B81 +Const GL_LINK_STATUS=$8B82 +Const GL_VALIDATE_STATUS=$8B83 +Const GL_INFO_LOG_LENGTH=$8B84 +Const GL_ATTACHED_SHADERS=$8B85 +Const GL_ACTIVE_UNIFORMS=$8B86 +Const GL_ACTIVE_UNIFORM_MAX_LENGTH=$8B87 +Const GL_SHADER_SOURCE_LENGTH=$8B88 +Const GL_ACTIVE_ATTRIBUTES=$8B89 +Const GL_ACTIVE_ATTRIBUTE_MAX_LENGTH=$8B8A +Const GL_FRAGMENT_SHADER_DERIVATIVE_HINT=$8B8B +Const GL_SHADING_LANGUAGE_VERSION=$8B8C +Const GL_CURRENT_PROGRAM=$8B8D +Const GL_POINT_SPRITE_COORD_ORIGIN=$8CA0 +Const GL_LOWER_LEFT=$8CA1 +Const GL_UPPER_LEFT=$8CA2 +Const GL_STENCIL_BACK_REF=$8CA3 +Const GL_STENCIL_BACK_VALUE_MASK=$8CA4 +Const GL_STENCIL_BACK_WRITEMASK=$8CA5 +Global glAttachShader(program_:Int,shader_:Int)="__glewAttachShader" +Global glBindAttribLocation(program_:Int,index_:Int,name_:Byte Ptr)="__glewBindAttribLocation" +Global glBlendEquationSeparate(arg0_:Int,arg1_:Int)="__glewBlendEquationSeparate" +Global glCompileShader(shader_:Int)="__glewCompileShader" +Global glCreateProgram:Int()="__glewCreateProgram" +Global glCreateShader:Int(type_:Int)="__glewCreateShader" +Global glDeleteProgram(program_:Int)="__glewDeleteProgram" +Global glDeleteShader(shader_:Int)="__glewDeleteShader" +Global glDetachShader(program_:Int,shader_:Int)="__glewDetachShader" +Global glDisableVertexAttribArray(arg0_:Int)="__glewDisableVertexAttribArray" +Global glDrawBuffers(n_:Int,bufs_:Int Ptr)="__glewDrawBuffers" +Global glEnableVertexAttribArray(arg0_:Int)="__glewEnableVertexAttribArray" +Global glGetActiveAttrib(program_:Int,index_:Int,maxLength_:Int,length_:Int Ptr,size_:Int Ptr,type_:Int Ptr,name_:Byte Ptr)="__glewGetActiveAttrib" +Global glGetActiveUniform(program_:Int,index_:Int,maxLength_:Int,length_:Int Ptr,size_:Int Ptr,type_:Int Ptr,name_:Byte Ptr)="__glewGetActiveUniform" +Global glGetAttachedShaders(program_:Int,maxCount_:Int,count_:Int Ptr,shaders_:Int Ptr)="__glewGetAttachedShaders" +Global glGetAttribLocation:Int(program_:Int,name_:Byte Ptr)="__glewGetAttribLocation" +Global glGetProgramInfoLog(program_:Int,bufSize_:Int,length_:Int Ptr,infoLog_:Byte Ptr)="__glewGetProgramInfoLog" +Global glGetProgramiv(program_:Int,pname_:Int,param_:Int Ptr)="__glewGetProgramiv" +Global glGetShaderInfoLog(shader_:Int,bufSize_:Int,length_:Int Ptr,infoLog_:Byte Ptr)="__glewGetShaderInfoLog" +Global glGetShaderSource(obj_:Int,maxLength_:Int,length_:Int Ptr,source_:Byte Ptr)="__glewGetShaderSource" +Global glGetShaderiv(shader_:Int,pname_:Int,param_:Int Ptr)="__glewGetShaderiv" +Global glGetUniformLocation:Int(program_:Int,name_:Byte Ptr)="__glewGetUniformLocation" +Global glGetUniformfv(program_:Int,location_:Int,params_:Float Ptr)="__glewGetUniformfv" +Global glGetUniformiv(program_:Int,location_:Int,params_:Int Ptr)="__glewGetUniformiv" +Global glGetVertexAttribPointerv(arg0_:Int,arg1_:Int,arg2_:Byte Ptr)="__glewGetVertexAttribPointerv" +Global glGetVertexAttribdv(arg0_:Int,arg1_:Int,arg2_:Double Ptr)="__glewGetVertexAttribdv" +Global glGetVertexAttribfv(arg0_:Int,arg1_:Int,arg2_:Float Ptr)="__glewGetVertexAttribfv" +Global glGetVertexAttribiv(arg0_:Int,arg1_:Int,arg2_:Int Ptr)="__glewGetVertexAttribiv" +Global glIsProgram:Byte(program_:Int)="__glewIsProgram" +Global glIsShader:Byte(shader_:Int)="__glewIsShader" +Global glLinkProgram(program_:Int)="__glewLinkProgram" +Global glShaderSource(shader_:Int,count_:Int,strings_:Byte Ptr Ptr,lengths_:Int Ptr)="__glewShaderSource" +Global glStencilFuncSeparate(frontfunc_:Int,backfunc_:Int,ref_:Int,mask_:Int)="__glewStencilFuncSeparate" +Global glStencilMaskSeparate(arg0_:Int,arg1_:Int)="__glewStencilMaskSeparate" +Global glStencilOpSeparate(face_:Int,sfail_:Int,dpfail_:Int,dppass_:Int)="__glewStencilOpSeparate" +Global glUniform1f(location_:Int,v0_:Float)="__glewUniform1f" +Global glUniform1fv(location_:Int,count_:Int,value_:Float Ptr)="__glewUniform1fv" +Global glUniform1i(location_:Int,v0_:Int)="__glewUniform1i" +Global glUniform1iv(location_:Int,count_:Int,value_:Int Ptr)="__glewUniform1iv" +Global glUniform2f(location_:Int,v0_:Float,v1_:Float)="__glewUniform2f" +Global glUniform2fv(location_:Int,count_:Int,value_:Float Ptr)="__glewUniform2fv" +Global glUniform2i(location_:Int,v0_:Int,v1_:Int)="__glewUniform2i" +Global glUniform2iv(location_:Int,count_:Int,value_:Int Ptr)="__glewUniform2iv" +Global glUniform3f(location_:Int,v0_:Float,v1_:Float,v2_:Float)="__glewUniform3f" +Global glUniform3fv(location_:Int,count_:Int,value_:Float Ptr)="__glewUniform3fv" +Global glUniform3i(location_:Int,v0_:Int,v1_:Int,v2_:Int)="__glewUniform3i" +Global glUniform3iv(location_:Int,count_:Int,value_:Int Ptr)="__glewUniform3iv" +Global glUniform4f(location_:Int,v0_:Float,v1_:Float,v2_:Float,v3_:Float)="__glewUniform4f" +Global glUniform4fv(location_:Int,count_:Int,value_:Float Ptr)="__glewUniform4fv" +Global glUniform4i(location_:Int,v0_:Int,v1_:Int,v2_:Int,v3_:Int)="__glewUniform4i" +Global glUniform4iv(location_:Int,count_:Int,value_:Int Ptr)="__glewUniform4iv" +Global glUniformMatrix2fv(location_:Int,count_:Int,transpose_:Byte,value_:Float Ptr)="__glewUniformMatrix2fv" +Global glUniformMatrix3fv(location_:Int,count_:Int,transpose_:Byte,value_:Float Ptr)="__glewUniformMatrix3fv" +Global glUniformMatrix4fv(location_:Int,count_:Int,transpose_:Byte,value_:Float Ptr)="__glewUniformMatrix4fv" +Global glUseProgram(program_:Int)="__glewUseProgram" +Global glValidateProgram(program_:Int)="__glewValidateProgram" +Global glVertexAttrib1d(index_:Int,x_:Double)="__glewVertexAttrib1d" +Global glVertexAttrib1dv(index_:Int,v_:Double Ptr)="__glewVertexAttrib1dv" +Global glVertexAttrib1f(index_:Int,x_:Float)="__glewVertexAttrib1f" +Global glVertexAttrib1fv(index_:Int,v_:Float Ptr)="__glewVertexAttrib1fv" +Global glVertexAttrib1s(index_:Int,x_:Short)="__glewVertexAttrib1s" +Global glVertexAttrib1sv(index_:Int,v_:Short Ptr)="__glewVertexAttrib1sv" +Global glVertexAttrib2d(index_:Int,x_:Double,y_:Double)="__glewVertexAttrib2d" +Global glVertexAttrib2dv(index_:Int,v_:Double Ptr)="__glewVertexAttrib2dv" +Global glVertexAttrib2f(index_:Int,x_:Float,y_:Float)="__glewVertexAttrib2f" +Global glVertexAttrib2fv(index_:Int,v_:Float Ptr)="__glewVertexAttrib2fv" +Global glVertexAttrib2s(index_:Int,x_:Short,y_:Short)="__glewVertexAttrib2s" +Global glVertexAttrib2sv(index_:Int,v_:Short Ptr)="__glewVertexAttrib2sv" +Global glVertexAttrib3d(index_:Int,x_:Double,y_:Double,z_:Double)="__glewVertexAttrib3d" +Global glVertexAttrib3dv(index_:Int,v_:Double Ptr)="__glewVertexAttrib3dv" +Global glVertexAttrib3f(index_:Int,x_:Float,y_:Float,z_:Float)="__glewVertexAttrib3f" +Global glVertexAttrib3fv(index_:Int,v_:Float Ptr)="__glewVertexAttrib3fv" +Global glVertexAttrib3s(index_:Int,x_:Short,y_:Short,z_:Short)="__glewVertexAttrib3s" +Global glVertexAttrib3sv(index_:Int,v_:Short Ptr)="__glewVertexAttrib3sv" +Global glVertexAttrib4Nbv(index_:Int,v_:Byte Ptr)="__glewVertexAttrib4Nbv" +Global glVertexAttrib4Niv(index_:Int,v_:Int Ptr)="__glewVertexAttrib4Niv" +Global glVertexAttrib4Nsv(index_:Int,v_:Short Ptr)="__glewVertexAttrib4Nsv" +Global glVertexAttrib4Nub(index_:Int,x_:Byte,y_:Byte,z_:Byte,w_:Byte)="__glewVertexAttrib4Nub" +Global glVertexAttrib4Nubv(index_:Int,v_:Byte Ptr)="__glewVertexAttrib4Nubv" +Global glVertexAttrib4Nuiv(index_:Int,v_:Int Ptr)="__glewVertexAttrib4Nuiv" +Global glVertexAttrib4Nusv(index_:Int,v_:Short Ptr)="__glewVertexAttrib4Nusv" +Global glVertexAttrib4bv(index_:Int,v_:Byte Ptr)="__glewVertexAttrib4bv" +Global glVertexAttrib4d(index_:Int,x_:Double,y_:Double,z_:Double,w_:Double)="__glewVertexAttrib4d" +Global glVertexAttrib4dv(index_:Int,v_:Double Ptr)="__glewVertexAttrib4dv" +Global glVertexAttrib4f(index_:Int,x_:Float,y_:Float,z_:Float,w_:Float)="__glewVertexAttrib4f" +Global glVertexAttrib4fv(index_:Int,v_:Float Ptr)="__glewVertexAttrib4fv" +Global glVertexAttrib4iv(index_:Int,v_:Int Ptr)="__glewVertexAttrib4iv" +Global glVertexAttrib4s(index_:Int,x_:Short,y_:Short,z_:Short,w_:Short)="__glewVertexAttrib4s" +Global glVertexAttrib4sv(index_:Int,v_:Short Ptr)="__glewVertexAttrib4sv" +Global glVertexAttrib4ubv(index_:Int,v_:Byte Ptr)="__glewVertexAttrib4ubv" +Global glVertexAttrib4uiv(index_:Int,v_:Int Ptr)="__glewVertexAttrib4uiv" +Global glVertexAttrib4usv(index_:Int,v_:Short Ptr)="__glewVertexAttrib4usv" +Global glVertexAttribPointer(index_:Int,size_:Int,type_:Int,normalized_:Byte,stride_:Int,pointer_:Byte Ptr)="__glewVertexAttribPointer" +Global GL_VERSION_2_0:Byte="__GLEW_VERSION_2_0" +Const GL_CURRENT_RASTER_SECONDARY_COLOR=$845F +Const GL_PIXEL_PACK_BUFFER=$88EB +Const GL_PIXEL_UNPACK_BUFFER=$88EC +Const GL_PIXEL_PACK_BUFFER_BINDING=$88ED +Const GL_PIXEL_UNPACK_BUFFER_BINDING=$88EF +Const GL_FLOAT_MAT2x3=$8B65 +Const GL_FLOAT_MAT2x4=$8B66 +Const GL_FLOAT_MAT3x2=$8B67 +Const GL_FLOAT_MAT3x4=$8B68 +Const GL_FLOAT_MAT4x2=$8B69 +Const GL_FLOAT_MAT4x3=$8B6A +Const GL_SRGB=$8C40 +Const GL_SRGB8=$8C41 +Const GL_SRGB_ALPHA=$8C42 +Const GL_SRGB8_ALPHA8=$8C43 +Const GL_SLUMINANCE_ALPHA=$8C44 +Const GL_SLUMINANCE8_ALPHA8=$8C45 +Const GL_SLUMINANCE=$8C46 +Const GL_SLUMINANCE8=$8C47 +Const GL_COMPRESSED_SRGB=$8C48 +Const GL_COMPRESSED_SRGB_ALPHA=$8C49 +Const GL_COMPRESSED_SLUMINANCE=$8C4A +Const GL_COMPRESSED_SLUMINANCE_ALPHA=$8C4B +Global glUniformMatrix2x3fv(location_:Int,count_:Int,transpose_:Byte,value_:Float Ptr)="__glewUniformMatrix2x3fv" +Global glUniformMatrix2x4fv(location_:Int,count_:Int,transpose_:Byte,value_:Float Ptr)="__glewUniformMatrix2x4fv" +Global glUniformMatrix3x2fv(location_:Int,count_:Int,transpose_:Byte,value_:Float Ptr)="__glewUniformMatrix3x2fv" +Global glUniformMatrix3x4fv(location_:Int,count_:Int,transpose_:Byte,value_:Float Ptr)="__glewUniformMatrix3x4fv" +Global glUniformMatrix4x2fv(location_:Int,count_:Int,transpose_:Byte,value_:Float Ptr)="__glewUniformMatrix4x2fv" +Global glUniformMatrix4x3fv(location_:Int,count_:Int,transpose_:Byte,value_:Float Ptr)="__glewUniformMatrix4x3fv" +Global GL_VERSION_2_1:Byte="__GLEW_VERSION_2_1" +Const GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT=$0001 +Const GL_MAJOR_VERSION=$821B +Const GL_MINOR_VERSION=$821C +Const GL_NUM_EXTENSIONS=$821D +Const GL_CONTEXT_FLAGS=$821E +Const GL_DEPTH_BUFFER=$8223 +Const GL_STENCIL_BUFFER=$8224 +Const GL_COMPRESSED_RED=$8225 +Const GL_COMPRESSED_RG=$8226 +Const GL_RGBA32F=$8814 +Const GL_RGB32F=$8815 +Const GL_RGBA16F=$881A +Const GL_RGB16F=$881B +Const GL_VERTEX_ATTRIB_ARRAY_INTEGER=$88FD +Const GL_MAX_ARRAY_TEXTURE_LAYERS=$88FF +Const GL_MIN_PROGRAM_TEXEL_OFFSET=$8904 +Const GL_MAX_PROGRAM_TEXEL_OFFSET=$8905 +Const GL_CLAMP_VERTEX_COLOR=$891A +Const GL_CLAMP_FRAGMENT_COLOR=$891B +Const GL_CLAMP_READ_COLOR=$891C +Const GL_FIXED_ONLY=$891D +Const GL_TEXTURE_RED_TYPE=$8C10 +Const GL_TEXTURE_GREEN_TYPE=$8C11 +Const GL_TEXTURE_BLUE_TYPE=$8C12 +Const GL_TEXTURE_ALPHA_TYPE=$8C13 +Const GL_TEXTURE_LUMINANCE_TYPE=$8C14 +Const GL_TEXTURE_INTENSITY_TYPE=$8C15 +Const GL_TEXTURE_DEPTH_TYPE=$8C16 +Const GL_UNSIGNED_NORMALIZED=$8C17 +Const GL_TEXTURE_1D_ARRAY=$8C18 +Const GL_PROXY_TEXTURE_1D_ARRAY=$8C19 +Const GL_TEXTURE_2D_ARRAY=$8C1A +Const GL_PROXY_TEXTURE_2D_ARRAY=$8C1B +Const GL_TEXTURE_BINDING_1D_ARRAY=$8C1C +Const GL_TEXTURE_BINDING_2D_ARRAY=$8C1D +Const GL_R11F_G11F_B10F=$8C3A +Const GL_UNSIGNED_INT_10F_11F_11F_REV=$8C3B +Const GL_RGB9_E5=$8C3D +Const GL_UNSIGNED_INT_5_9_9_9_REV=$8C3E +Const GL_TEXTURE_SHARED_SIZE=$8C3F +Const GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH=$8C76 +Const GL_TRANSFORM_FEEDBACK_BUFFER_MODE=$8C7F +Const GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS=$8C80 +Const GL_TRANSFORM_FEEDBACK_VARYINGS=$8C83 +Const GL_TRANSFORM_FEEDBACK_BUFFER_START=$8C84 +Const GL_TRANSFORM_FEEDBACK_BUFFER_SIZE=$8C85 +Const GL_PRIMITIVES_GENERATED=$8C87 +Const GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN=$8C88 +Const GL_RASTERIZER_DISCARD=$8C89 +Const GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS=$8C8A +Const GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS=$8C8B +Const GL_INTERLEAVED_ATTRIBS=$8C8C +Const GL_SEPARATE_ATTRIBS=$8C8D +Const GL_TRANSFORM_FEEDBACK_BUFFER=$8C8E +Const GL_TRANSFORM_FEEDBACK_BUFFER_BINDING=$8C8F +Const GL_RGBA32UI=$8D70 +Const GL_RGB32UI=$8D71 +Const GL_RGBA16UI=$8D76 +Const GL_RGB16UI=$8D77 +Const GL_RGBA8UI=$8D7C +Const GL_RGB8UI=$8D7D +Const GL_RGBA32I=$8D82 +Const GL_RGB32I=$8D83 +Const GL_RGBA16I=$8D88 +Const GL_RGB16I=$8D89 +Const GL_RGBA8I=$8D8E +Const GL_RGB8I=$8D8F +Const GL_RED_INTEGER=$8D94 +Const GL_GREEN_INTEGER=$8D95 +Const GL_BLUE_INTEGER=$8D96 +Const GL_ALPHA_INTEGER=$8D97 +Const GL_RGB_INTEGER=$8D98 +Const GL_RGBA_INTEGER=$8D99 +Const GL_BGR_INTEGER=$8D9A +Const GL_BGRA_INTEGER=$8D9B +Const GL_SAMPLER_1D_ARRAY=$8DC0 +Const GL_SAMPLER_2D_ARRAY=$8DC1 +Const GL_SAMPLER_1D_ARRAY_SHADOW=$8DC3 +Const GL_SAMPLER_2D_ARRAY_SHADOW=$8DC4 +Const GL_SAMPLER_CUBE_SHADOW=$8DC5 +Const GL_UNSIGNED_INT_VEC2=$8DC6 +Const GL_UNSIGNED_INT_VEC3=$8DC7 +Const GL_UNSIGNED_INT_VEC4=$8DC8 +Const GL_INT_SAMPLER_1D=$8DC9 +Const GL_INT_SAMPLER_2D=$8DCA +Const GL_INT_SAMPLER_3D=$8DCB +Const GL_INT_SAMPLER_CUBE=$8DCC +Const GL_INT_SAMPLER_1D_ARRAY=$8DCE +Const GL_INT_SAMPLER_2D_ARRAY=$8DCF +Const GL_UNSIGNED_INT_SAMPLER_1D=$8DD1 +Const GL_UNSIGNED_INT_SAMPLER_2D=$8DD2 +Const GL_UNSIGNED_INT_SAMPLER_3D=$8DD3 +Const GL_UNSIGNED_INT_SAMPLER_CUBE=$8DD4 +Const GL_UNSIGNED_INT_SAMPLER_1D_ARRAY=$8DD6 +Const GL_UNSIGNED_INT_SAMPLER_2D_ARRAY=$8DD7 +Const GL_QUERY_WAIT=$8E13 +Const GL_QUERY_NO_WAIT=$8E14 +Const GL_QUERY_BY_REGION_WAIT=$8E15 +Const GL_QUERY_BY_REGION_NO_WAIT=$8E16 +Global glBeginConditionalRender(arg0_:Int,arg1_:Int)="__glewBeginConditionalRender" +Global glBeginTransformFeedback(arg0_:Int)="__glewBeginTransformFeedback" +Global glBindBufferBase(arg0_:Int,arg1_:Int,arg2_:Int)="__glewBindBufferBase" +Global glBindBufferRange(arg0_:Int,arg1_:Int,arg2_:Int,arg3_:Int,arg4_:Int)="__glewBindBufferRange" +Global glBindFragDataLocation(arg0_:Int,arg1_:Int,arg2_:Byte Ptr)="__glewBindFragDataLocation" +Global glClampColor(arg0_:Int,arg1_:Int)="__glewClampColor" +Global glClearBufferfi(arg0_:Int,arg1_:Int,arg2_:Float,arg3_:Int)="__glewClearBufferfi" +Global glClearBufferfv(arg0_:Int,arg1_:Int,arg2_:Float Ptr)="__glewClearBufferfv" +Global glClearBufferiv(arg0_:Int,arg1_:Int,arg2_:Int Ptr)="__glewClearBufferiv" +Global glClearBufferuiv(arg0_:Int,arg1_:Int,arg2_:Int Ptr)="__glewClearBufferuiv" +Global glColorMaski(arg0_:Int,arg1_:Byte,arg2_:Byte,arg3_:Byte,arg4_:Byte)="__glewColorMaski" +Global glDisablei(arg0_:Int,arg1_:Int)="__glewDisablei" +Global glEnablei(arg0_:Int,arg1_:Int)="__glewEnablei" +Global glEndConditionalRender()="__glewEndConditionalRender" +Global glEndTransformFeedback()="__glewEndTransformFeedback" +Global glGetBooleani_v(arg0_:Int,arg1_:Int,arg2_:Byte Ptr)="__glewGetBooleani_v" +Global glGetFragDataLocation:Int(arg0_:Int,arg1_:Byte Ptr)="__glewGetFragDataLocation" +Global glGetIntegeri_v(arg0_:Int,arg1_:Int,arg2_:Int Ptr)="__glewGetIntegeri_v" +Global glGetStringi:Byte Ptr(arg0_:Int,arg1_:Int)="__glewGetStringi" +Global glGetTexParameterIiv(arg0_:Int,arg1_:Int,arg2_:Int Ptr)="__glewGetTexParameterIiv" +Global glGetTexParameterIuiv(arg0_:Int,arg1_:Int,arg2_:Int Ptr)="__glewGetTexParameterIuiv" +Global glGetTransformFeedbackVarying(arg0_:Int,arg1_:Int,arg2_:Int Ptr)="__glewGetTransformFeedbackVarying" +Global glGetUniformuiv(arg0_:Int,arg1_:Int,arg2_:Int Ptr)="__glewGetUniformuiv" +Global glGetVertexAttribIiv(arg0_:Int,arg1_:Int,arg2_:Int Ptr)="__glewGetVertexAttribIiv" +Global glGetVertexAttribIuiv(arg0_:Int,arg1_:Int,arg2_:Int Ptr)="__glewGetVertexAttribIuiv" +Global glIsEnabledi:Byte(arg0_:Int,arg1_:Int)="__glewIsEnabledi" +Global glTexParameterIiv(arg0_:Int,arg1_:Int,arg2_:Int Ptr)="__glewTexParameterIiv" +Global glTexParameterIuiv(arg0_:Int,arg1_:Int,arg2_:Int Ptr)="__glewTexParameterIuiv" +Global glTransformFeedbackVaryings(arg0_:Int,arg1_:Int,arg2_:Int Ptr,arg3_:Int)="__glewTransformFeedbackVaryings" +Global glUniform1ui(arg0_:Int,arg1_:Int)="__glewUniform1ui" +Global glUniform1uiv(arg0_:Int,arg1_:Int,arg2_:Int Ptr)="__glewUniform1uiv" +Global glUniform2ui(arg0_:Int,arg1_:Int,arg2_:Int)="__glewUniform2ui" +Global glUniform2uiv(arg0_:Int,arg1_:Int,arg2_:Int Ptr)="__glewUniform2uiv" +Global glUniform3ui(arg0_:Int,arg1_:Int,arg2_:Int,arg3_:Int)="__glewUniform3ui" +Global glUniform3uiv(arg0_:Int,arg1_:Int,arg2_:Int Ptr)="__glewUniform3uiv" +Global glUniform4ui(arg0_:Int,arg1_:Int,arg2_:Int,arg3_:Int,arg4_:Int)="__glewUniform4ui" +Global glUniform4uiv(arg0_:Int,arg1_:Int,arg2_:Int Ptr)="__glewUniform4uiv" +Global glVertexAttribI1i(arg0_:Int,arg1_:Int)="__glewVertexAttribI1i" +Global glVertexAttribI1iv(arg0_:Int,arg1_:Int Ptr)="__glewVertexAttribI1iv" +Global glVertexAttribI1ui(arg0_:Int,arg1_:Int)="__glewVertexAttribI1ui" +Global glVertexAttribI1uiv(arg0_:Int,arg1_:Int Ptr)="__glewVertexAttribI1uiv" +Global glVertexAttribI2i(arg0_:Int,arg1_:Int,arg2_:Int)="__glewVertexAttribI2i" +Global glVertexAttribI2iv(arg0_:Int,arg1_:Int Ptr)="__glewVertexAttribI2iv" +Global glVertexAttribI2ui(arg0_:Int,arg1_:Int,arg2_:Int)="__glewVertexAttribI2ui" +Global glVertexAttribI2uiv(arg0_:Int,arg1_:Int Ptr)="__glewVertexAttribI2uiv" +Global glVertexAttribI3i(arg0_:Int,arg1_:Int,arg2_:Int,arg3_:Int)="__glewVertexAttribI3i" +Global glVertexAttribI3iv(arg0_:Int,arg1_:Int Ptr)="__glewVertexAttribI3iv" +Global glVertexAttribI3ui(arg0_:Int,arg1_:Int,arg2_:Int,arg3_:Int)="__glewVertexAttribI3ui" +Global glVertexAttribI3uiv(arg0_:Int,arg1_:Int Ptr)="__glewVertexAttribI3uiv" +Global glVertexAttribI4bv(arg0_:Int,arg1_:Byte Ptr)="__glewVertexAttribI4bv" +Global glVertexAttribI4i(arg0_:Int,arg1_:Int,arg2_:Int,arg3_:Int,arg4_:Int)="__glewVertexAttribI4i" +Global glVertexAttribI4iv(arg0_:Int,arg1_:Int Ptr)="__glewVertexAttribI4iv" +Global glVertexAttribI4sv(arg0_:Int,arg1_:Short Ptr)="__glewVertexAttribI4sv" +Global glVertexAttribI4ubv(arg0_:Int,arg1_:Byte Ptr)="__glewVertexAttribI4ubv" +Global glVertexAttribI4ui(arg0_:Int,arg1_:Int,arg2_:Int,arg3_:Int,arg4_:Int)="__glewVertexAttribI4ui" +Global glVertexAttribI4uiv(arg0_:Int,arg1_:Int Ptr)="__glewVertexAttribI4uiv" +Global glVertexAttribI4usv(arg0_:Int,arg1_:Short Ptr)="__glewVertexAttribI4usv" +Global glVertexAttribIPointer(arg0_:Int,arg1_:Int,arg2_:Int,arg3_:Int,arg4_:Byte Ptr)="__glewVertexAttribIPointer" +Global GL_VERSION_3_0:Byte="__GLEW_VERSION_3_0" +Const GL_MULTISAMPLE_3DFX=$86B2 +Const GL_SAMPLE_BUFFERS_3DFX=$86B3 +Const GL_SAMPLES_3DFX=$86B4 +Const GL_MULTISAMPLE_BIT_3DFX=$20000000 +Global GL_3DFX_multisample:Byte="__GLEW_3DFX_multisample" +Global glTbufferMask3DFX(mask_:Int)="__glewTbufferMask3DFX" +Global GL_3DFX_tbuffer:Byte="__GLEW_3DFX_tbuffer" +Const GL_COMPRESSED_RGB_FXT1_3DFX=$86B0 +Const GL_COMPRESSED_RGBA_FXT1_3DFX=$86B1 +Global GL_3DFX_texture_compression_FXT1:Byte="__GLEW_3DFX_texture_compression_FXT1" +Const GL_UNPACK_CLIENT_STORAGE_APPLE=$85B2 +Global GL_APPLE_client_storage:Byte="__GLEW_APPLE_client_storage" +Const GL_ELEMENT_ARRAY_APPLE=$8768 +Const GL_ELEMENT_ARRAY_TYPE_APPLE=$8769 +Const GL_ELEMENT_ARRAY_POINTER_APPLE=$876A +Global glDrawElementArrayAPPLE(mode_:Int,first_:Int,count_:Int)="__glewDrawElementArrayAPPLE" +Global glDrawRangeElementArrayAPPLE(mode_:Int,start_:Int,end_:Int,first_:Int,count_:Int)="__glewDrawRangeElementArrayAPPLE" +Global glElementPointerAPPLE(type_:Int,pointer_:Byte Ptr)="__glewElementPointerAPPLE" +Global glMultiDrawElementArrayAPPLE(mode_:Int,first_:Int Ptr,count_:Int Ptr,primcount_:Int)="__glewMultiDrawElementArrayAPPLE" +Global glMultiDrawRangeElementArrayAPPLE(mode_:Int,start_:Int,end_:Int,first_:Int Ptr,count_:Int Ptr,primcount_:Int)="__glewMultiDrawRangeElementArrayAPPLE" +Global GL_APPLE_element_array:Byte="__GLEW_APPLE_element_array" +Const GL_DRAW_PIXELS_APPLE=$8A0A +Const GL_FENCE_APPLE=$8A0B +Global glDeleteFencesAPPLE(n_:Int,fences_:Int Ptr)="__glewDeleteFencesAPPLE" +Global glFinishFenceAPPLE(fence_:Int)="__glewFinishFenceAPPLE" +Global glFinishObjectAPPLE(object_:Int,name_:Int)="__glewFinishObjectAPPLE" +Global glGenFencesAPPLE(n_:Int,fences_:Int Ptr)="__glewGenFencesAPPLE" +Global glIsFenceAPPLE:Byte(fence_:Int)="__glewIsFenceAPPLE" +Global glSetFenceAPPLE(fence_:Int)="__glewSetFenceAPPLE" +Global glTestFenceAPPLE:Byte(fence_:Int)="__glewTestFenceAPPLE" +Global glTestObjectAPPLE:Byte(object_:Int,name_:Int)="__glewTestObjectAPPLE" +Global GL_APPLE_fence:Byte="__GLEW_APPLE_fence" +Const GL_HALF_APPLE=$140B +Const GL_RGBA_FLOAT32_APPLE=$8814 +Const GL_RGB_FLOAT32_APPLE=$8815 +Const GL_ALPHA_FLOAT32_APPLE=$8816 +Const GL_INTENSITY_FLOAT32_APPLE=$8817 +Const GL_LUMINANCE_FLOAT32_APPLE=$8818 +Const GL_LUMINANCE_ALPHA_FLOAT32_APPLE=$8819 +Const GL_RGBA_FLOAT16_APPLE=$881A +Const GL_RGB_FLOAT16_APPLE=$881B +Const GL_ALPHA_FLOAT16_APPLE=$881C +Const GL_INTENSITY_FLOAT16_APPLE=$881D +Const GL_LUMINANCE_FLOAT16_APPLE=$881E +Const GL_LUMINANCE_ALPHA_FLOAT16_APPLE=$881F +Const GL_COLOR_FLOAT_APPLE=$8A0F +Global GL_APPLE_float_pixels:Byte="__GLEW_APPLE_float_pixels" +Const GL_BUFFER_SERIALIZED_MODIFY_APPLE=$8A12 +Const GL_BUFFER_FLUSHING_UNMAP_APPLE=$8A13 +Global glBufferParameteriAPPLE(target_:Int,pname_:Int,param_:Int)="__glewBufferParameteriAPPLE" +Global glFlushMappedBufferRangeAPPLE(target_:Int,offset_:Int,size_:Int)="__glewFlushMappedBufferRangeAPPLE" +Global GL_APPLE_flush_buffer_range:Byte="__GLEW_APPLE_flush_buffer_range" +Const GL_MIN_PBUFFER_VIEWPORT_DIMS_APPLE=$8A10 +Global GL_APPLE_pixel_buffer:Byte="__GLEW_APPLE_pixel_buffer" +Const GL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE=$85B0 +Global GL_APPLE_specular_vector:Byte="__GLEW_APPLE_specular_vector" +Const GL_TEXTURE_RANGE_LENGTH_APPLE=$85B7 +Const GL_TEXTURE_RANGE_POINTER_APPLE=$85B8 +Const GL_TEXTURE_STORAGE_HINT_APPLE=$85BC +Const GL_STORAGE_PRIVATE_APPLE=$85BD +Const GL_STORAGE_CACHED_APPLE=$85BE +Const GL_STORAGE_SHARED_APPLE=$85BF +Global glGetTexParameterPointervAPPLE(target_:Int,pname_:Int,params_:Byte Ptr Ptr)="__glewGetTexParameterPointervAPPLE" +Global glTextureRangeAPPLE(target_:Int,length_:Int,pointer_:Byte Ptr)="__glewTextureRangeAPPLE" +Global GL_APPLE_texture_range:Byte="__GLEW_APPLE_texture_range" +Const GL_TRANSFORM_HINT_APPLE=$85B1 +Global GL_APPLE_transform_hint:Byte="__GLEW_APPLE_transform_hint" +Const GL_VERTEX_ARRAY_BINDING_APPLE=$85B5 +Global glBindVertexArrayAPPLE(array_:Int)="__glewBindVertexArrayAPPLE" +Global glDeleteVertexArraysAPPLE(n_:Int,arrays_:Int Ptr)="__glewDeleteVertexArraysAPPLE" +Global glGenVertexArraysAPPLE(n_:Int,arrays_:Int Ptr)="__glewGenVertexArraysAPPLE" +Global glIsVertexArrayAPPLE:Byte(array_:Int)="__glewIsVertexArrayAPPLE" +Global GL_APPLE_vertex_array_object:Byte="__GLEW_APPLE_vertex_array_object" +Const GL_VERTEX_ARRAY_RANGE_APPLE=$851D +Const GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE=$851E +Const GL_VERTEX_ARRAY_STORAGE_HINT_APPLE=$851F +Const GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_APPLE=$8520 +Const GL_VERTEX_ARRAY_RANGE_POINTER_APPLE=$8521 +Global glFlushVertexArrayRangeAPPLE(length_:Int,pointer_:Byte Ptr)="__glewFlushVertexArrayRangeAPPLE" +Global glVertexArrayParameteriAPPLE(pname_:Int,param_:Int)="__glewVertexArrayParameteriAPPLE" +Global glVertexArrayRangeAPPLE(length_:Int,pointer_:Byte Ptr)="__glewVertexArrayRangeAPPLE" +Global GL_APPLE_vertex_array_range:Byte="__GLEW_APPLE_vertex_array_range" +Const GL_YCBCR_422_APPLE=$85B9 +Const GL_UNSIGNED_SHORT_8_8_APPLE=$85BA +Const GL_UNSIGNED_SHORT_8_8_REV_APPLE=$85BB +Global GL_APPLE_ycbcr_422:Byte="__GLEW_APPLE_ycbcr_422" +Const GL_RGBA_FLOAT_MODE_ARB=$8820 +Const GL_CLAMP_VERTEX_COLOR_ARB=$891A +Const GL_CLAMP_FRAGMENT_COLOR_ARB=$891B +Const GL_CLAMP_READ_COLOR_ARB=$891C +Const GL_FIXED_ONLY_ARB=$891D +Global glClampColorARB(target_:Int,clamp_:Int)="__glewClampColorARB" +Global GL_ARB_color_buffer_float:Byte="__GLEW_ARB_color_buffer_float" +Const GL_DEPTH_COMPONENT32F=$8CAC +Const GL_DEPTH32F_STENCIL8=$8CAD +Const GL_FLOAT_32_UNSIGNED_INT_24_8_REV=$8DAD +Global GL_ARB_depth_buffer_float:Byte="__GLEW_ARB_depth_buffer_float" +Const GL_DEPTH_COMPONENT16_ARB=$81A5 +Const GL_DEPTH_COMPONENT24_ARB=$81A6 +Const GL_DEPTH_COMPONENT32_ARB=$81A7 +Const GL_TEXTURE_DEPTH_SIZE_ARB=$884A +Const GL_DEPTH_TEXTURE_MODE_ARB=$884B +Global GL_ARB_depth_texture:Byte="__GLEW_ARB_depth_texture" +Const GL_MAX_DRAW_BUFFERS_ARB=$8824 +Const GL_DRAW_BUFFER0_ARB=$8825 +Const GL_DRAW_BUFFER1_ARB=$8826 +Const GL_DRAW_BUFFER2_ARB=$8827 +Const GL_DRAW_BUFFER3_ARB=$8828 +Const GL_DRAW_BUFFER4_ARB=$8829 +Const GL_DRAW_BUFFER5_ARB=$882A +Const GL_DRAW_BUFFER6_ARB=$882B +Const GL_DRAW_BUFFER7_ARB=$882C +Const GL_DRAW_BUFFER8_ARB=$882D +Const GL_DRAW_BUFFER9_ARB=$882E +Const GL_DRAW_BUFFER10_ARB=$882F +Const GL_DRAW_BUFFER11_ARB=$8830 +Const GL_DRAW_BUFFER12_ARB=$8831 +Const GL_DRAW_BUFFER13_ARB=$8832 +Const GL_DRAW_BUFFER14_ARB=$8833 +Const GL_DRAW_BUFFER15_ARB=$8834 +Global glDrawBuffersARB(n_:Int,bufs_:Int Ptr)="__glewDrawBuffersARB" +Global GL_ARB_draw_buffers:Byte="__GLEW_ARB_draw_buffers" +Global glDrawArraysInstancedARB(mode_:Int,first_:Int,count_:Int,primcount_:Int)="__glewDrawArraysInstancedARB" +Global glDrawElementsInstancedARB(mode_:Int,count_:Int,type_:Int,indices_:Byte Ptr,primcount_:Int)="__glewDrawElementsInstancedARB" +Global GL_ARB_draw_instanced:Byte="__GLEW_ARB_draw_instanced" +Const GL_FRAGMENT_PROGRAM_ARB=$8804 +Const GL_PROGRAM_ALU_INSTRUCTIONS_ARB=$8805 +Const GL_PROGRAM_TEX_INSTRUCTIONS_ARB=$8806 +Const GL_PROGRAM_TEX_INDIRECTIONS_ARB=$8807 +Const GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB=$8808 +Const GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB=$8809 +Const GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB=$880A +Const GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB=$880B +Const GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB=$880C +Const GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB=$880D +Const GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB=$880E +Const GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB=$880F +Const GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB=$8810 +Const GL_MAX_TEXTURE_COORDS_ARB=$8871 +Const GL_MAX_TEXTURE_IMAGE_UNITS_ARB=$8872 +Global GL_ARB_fragment_program:Byte="__GLEW_ARB_fragment_program" +Global GL_ARB_fragment_program_shadow:Byte="__GLEW_ARB_fragment_program_shadow" +Const GL_FRAGMENT_SHADER_ARB=$8B30 +Const GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB=$8B49 +Const GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB=$8B8B +Global GL_ARB_fragment_shader:Byte="__GLEW_ARB_fragment_shader" +Const GL_INVALID_FRAMEBUFFER_OPERATION=$0506 +Const GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING=$8210 +Const GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE=$8211 +Const GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE=$8212 +Const GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE=$8213 +Const GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE=$8214 +Const GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE=$8215 +Const GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE=$8216 +Const GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE=$8217 +Const GL_FRAMEBUFFER_DEFAULT=$8218 +Const GL_FRAMEBUFFER_UNDEFINED=$8219 +Const GL_DEPTH_STENCIL_ATTACHMENT=$821A +Const GL_INDEX=$8222 +Const GL_MAX_RENDERBUFFER_SIZE=$84E8 +Const GL_DEPTH_STENCIL=$84F9 +Const GL_UNSIGNED_INT_24_8=$84FA +Const GL_DEPTH24_STENCIL8=$88F0 +Const GL_TEXTURE_STENCIL_SIZE=$88F1 +Const GL_DRAW_FRAMEBUFFER_BINDING=$8CA6 +Const GL_FRAMEBUFFER_BINDING=$8CA6 +Const GL_RENDERBUFFER_BINDING=$8CA7 +Const GL_READ_FRAMEBUFFER=$8CA8 +Const GL_DRAW_FRAMEBUFFER=$8CA9 +Const GL_READ_FRAMEBUFFER_BINDING=$8CAA +Const GL_RENDERBUFFER_SAMPLES=$8CAB +Const GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE=$8CD0 +Const GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME=$8CD1 +Const GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL=$8CD2 +Const GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE=$8CD3 +Const GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER=$8CD4 +Const GL_FRAMEBUFFER_COMPLETE=$8CD5 +Const GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT=$8CD6 +Const GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT=$8CD7 +Const GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER=$8CDB +Const GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER=$8CDC +Const GL_FRAMEBUFFER_UNSUPPORTED=$8CDD +Const GL_MAX_COLOR_ATTACHMENTS=$8CDF +Const GL_COLOR_ATTACHMENT0=$8CE0 +Const GL_COLOR_ATTACHMENT1=$8CE1 +Const GL_COLOR_ATTACHMENT2=$8CE2 +Const GL_COLOR_ATTACHMENT3=$8CE3 +Const GL_COLOR_ATTACHMENT4=$8CE4 +Const GL_COLOR_ATTACHMENT5=$8CE5 +Const GL_COLOR_ATTACHMENT6=$8CE6 +Const GL_COLOR_ATTACHMENT7=$8CE7 +Const GL_COLOR_ATTACHMENT8=$8CE8 +Const GL_COLOR_ATTACHMENT9=$8CE9 +Const GL_COLOR_ATTACHMENT10=$8CEA +Const GL_COLOR_ATTACHMENT11=$8CEB +Const GL_COLOR_ATTACHMENT12=$8CEC +Const GL_COLOR_ATTACHMENT13=$8CED +Const GL_COLOR_ATTACHMENT14=$8CEE +Const GL_COLOR_ATTACHMENT15=$8CEF +Const GL_DEPTH_ATTACHMENT=$8D00 +Const GL_STENCIL_ATTACHMENT=$8D20 +Const GL_FRAMEBUFFER=$8D40 +Const GL_RENDERBUFFER=$8D41 +Const GL_RENDERBUFFER_WIDTH=$8D42 +Const GL_RENDERBUFFER_HEIGHT=$8D43 +Const GL_RENDERBUFFER_INTERNAL_FORMAT=$8D44 +Const GL_STENCIL_INDEX1=$8D46 +Const GL_STENCIL_INDEX4=$8D47 +Const GL_STENCIL_INDEX8=$8D48 +Const GL_STENCIL_INDEX16=$8D49 +Const GL_RENDERBUFFER_RED_SIZE=$8D50 +Const GL_RENDERBUFFER_GREEN_SIZE=$8D51 +Const GL_RENDERBUFFER_BLUE_SIZE=$8D52 +Const GL_RENDERBUFFER_ALPHA_SIZE=$8D53 +Const GL_RENDERBUFFER_DEPTH_SIZE=$8D54 +Const GL_RENDERBUFFER_STENCIL_SIZE=$8D55 +Const GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE=$8D56 +Const GL_MAX_SAMPLES=$8D57 +Global glBindFramebuffer(target_:Int,framebuffer_:Int)="__glewBindFramebuffer" +Global glBindRenderbuffer(target_:Int,renderbuffer_:Int)="__glewBindRenderbuffer" +Global glBlitFramebuffer(srcX0_:Int,srcY0_:Int,srcX1_:Int,srcY1_:Int,dstX0_:Int,dstY0_:Int,dstX1_:Int,dstY1_:Int,mask_:Int,filter_:Int)="__glewBlitFramebuffer" +Global glCheckFramebufferStatus:Int(target_:Int)="__glewCheckFramebufferStatus" +Global glDeleteFramebuffers(n_:Int,framebuffers_:Int Ptr)="__glewDeleteFramebuffers" +Global glDeleteRenderbuffers(n_:Int,renderbuffers_:Int Ptr)="__glewDeleteRenderbuffers" +Global glFramebufferRenderbuffer(target_:Int,attachment_:Int,renderbuffertarget_:Int,renderbuffer_:Int)="__glewFramebufferRenderbuffer" +Global glFramebufferTexturLayer(target_:Int,attachment_:Int,texture_:Int,level_:Int,layer_:Int)="__glewFramebufferTexturLayer" +Global glFramebufferTexture1D(target_:Int,attachment_:Int,textarget_:Int,texture_:Int,level_:Int)="__glewFramebufferTexture1D" +Global glFramebufferTexture2D(target_:Int,attachment_:Int,textarget_:Int,texture_:Int,level_:Int)="__glewFramebufferTexture2D" +Global glFramebufferTexture3D(target_:Int,attachment_:Int,textarget_:Int,texture_:Int,level_:Int,layer_:Int)="__glewFramebufferTexture3D" +Global glGenFramebuffers(n_:Int,framebuffers_:Int Ptr)="__glewGenFramebuffers" +Global glGenRenderbuffers(n_:Int,renderbuffers_:Int Ptr)="__glewGenRenderbuffers" +Global glGenerateMipmap(target_:Int)="__glewGenerateMipmap" +Global glGetFramebufferAttachmentParameteriv(target_:Int,attachment_:Int,pname_:Int,params_:Int Ptr)="__glewGetFramebufferAttachmentParameteriv" +Global glGetRenderbufferParameteriv(target_:Int,pname_:Int,params_:Int Ptr)="__glewGetRenderbufferParameteriv" +Global glIsFramebuffer:Byte(framebuffer_:Int)="__glewIsFramebuffer" +Global glIsRenderbuffer:Byte(renderbuffer_:Int)="__glewIsRenderbuffer" +Global glRenderbufferStorage(target_:Int,internalformat_:Int,width_:Int,height_:Int)="__glewRenderbufferStorage" +Global glRenderbufferStorageMultisample(target_:Int,samples_:Int,internalformat_:Int,width_:Int,height_:Int)="__glewRenderbufferStorageMultisample" +Global GL_ARB_framebuffer_object:Byte="__GLEW_ARB_framebuffer_object" +Const GL_FRAMEBUFFER_SRGB=$8DB9 +Global GL_ARB_framebuffer_sRGB:Byte="__GLEW_ARB_framebuffer_sRGB" +Const GL_LINES_ADJACENCY_ARB=$A +Const GL_LINE_STRIP_ADJACENCY_ARB=$B +Const GL_TRIANGLES_ADJACENCY_ARB=$C +Const GL_TRIANGLE_STRIP_ADJACENCY_ARB=$D +Const GL_PROGRAM_POINT_SIZE_ARB=$8642 +Const GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB=$8C29 +Const GL_FRAMEBUFFER_ATTACHMENT_LAYERED_ARB=$8DA7 +Const GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB=$8DA8 +Const GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB=$8DA9 +Const GL_GEOMETRY_SHADER_ARB=$8DD9 +Const GL_GEOMETRY_VERTICES_OUT_ARB=$8DDA +Const GL_GEOMETRY_INPUT_TYPE_ARB=$8DDB +Const GL_GEOMETRY_OUTPUT_TYPE_ARB=$8DDC +Const GL_MAX_GEOMETRY_VARYING_COMPONENTS_ARB=$8DDD +Const GL_MAX_VERTEX_VARYING_COMPONENTS_ARB=$8DDE +Const GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB=$8DDF +Const GL_MAX_GEOMETRY_OUTPUT_VERTICES_ARB=$8DE0 +Const GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB=$8DE1 +Global glFramebufferTextureARB(target_:Int,attachment_:Int,texture_:Int,level_:Int)="__glewFramebufferTextureARB" +Global glFramebufferTextureFaceARB(target_:Int,attachment_:Int,texture_:Int,level_:Int,face_:Int)="__glewFramebufferTextureFaceARB" +Global glFramebufferTextureLayerARB(target_:Int,attachment_:Int,texture_:Int,level_:Int,layer_:Int)="__glewFramebufferTextureLayerARB" +Global glProgramParameteriARB(program_:Int,pname_:Int,value_:Int)="__glewProgramParameteriARB" +Global GL_ARB_geometry_shader4:Byte="__GLEW_ARB_geometry_shader4" +Const GL_HALF_FLOAT_ARB=$140B +Global GL_ARB_half_float_pixel:Byte="__GLEW_ARB_half_float_pixel" +Const GL_HALF_FLOAT=$140B +Global GL_ARB_half_float_vertex:Byte="__GLEW_ARB_half_float_vertex" +Const GL_CONSTANT_COLOR=$8001 +Const GL_ONE_MINUS_CONSTANT_COLOR=$8002 +Const GL_CONSTANT_ALPHA=$8003 +Const GL_ONE_MINUS_CONSTANT_ALPHA=$8004 +Const GL_BLEND_COLOR=$8005 +Const GL_FUNC_ADD=$8006 +Const GL_MIN=$8007 +Const GL_MAX=$8008 +Const GL_BLEND_EQUATION=$8009 +Const GL_FUNC_SUBTRACT=$800A +Const GL_FUNC_REVERSE_SUBTRACT=$800B +Const GL_CONVOLUTION_1D=$8010 +Const GL_CONVOLUTION_2D=$8011 +Const GL_SEPARABLE_2D=$8012 +Const GL_CONVOLUTION_BORDER_MODE=$8013 +Const GL_CONVOLUTION_FILTER_SCALE=$8014 +Const GL_CONVOLUTION_FILTER_BIAS=$8015 +Const GL_REDUCE=$8016 +Const GL_CONVOLUTION_FORMAT=$8017 +Const GL_CONVOLUTION_WIDTH=$8018 +Const GL_CONVOLUTION_HEIGHT=$8019 +Const GL_MAX_CONVOLUTION_WIDTH=$801A +Const GL_MAX_CONVOLUTION_HEIGHT=$801B +Const GL_POST_CONVOLUTION_RED_SCALE=$801C +Const GL_POST_CONVOLUTION_GREEN_SCALE=$801D +Const GL_POST_CONVOLUTION_BLUE_SCALE=$801E +Const GL_POST_CONVOLUTION_ALPHA_SCALE=$801F +Const GL_POST_CONVOLUTION_RED_BIAS=$8020 +Const GL_POST_CONVOLUTION_GREEN_BIAS=$8021 +Const GL_POST_CONVOLUTION_BLUE_BIAS=$8022 +Const GL_POST_CONVOLUTION_ALPHA_BIAS=$8023 +Const GL_HISTOGRAM=$8024 +Const GL_PROXY_HISTOGRAM=$8025 +Const GL_HISTOGRAM_WIDTH=$8026 +Const GL_HISTOGRAM_FORMAT=$8027 +Const GL_HISTOGRAM_RED_SIZE=$8028 +Const GL_HISTOGRAM_GREEN_SIZE=$8029 +Const GL_HISTOGRAM_BLUE_SIZE=$802A +Const GL_HISTOGRAM_ALPHA_SIZE=$802B +Const GL_HISTOGRAM_LUMINANCE_SIZE=$802C +Const GL_HISTOGRAM_SINK=$802D +Const GL_MINMAX=$802E +Const GL_MINMAX_FORMAT=$802F +Const GL_MINMAX_SINK=$8030 +Const GL_TABLE_TOO_LARGE=$8031 +Const GL_COLOR_MATRIX=$80B1 +Const GL_COLOR_MATRIX_STACK_DEPTH=$80B2 +Const GL_MAX_COLOR_MATRIX_STACK_DEPTH=$80B3 +Const GL_POST_COLOR_MATRIX_RED_SCALE=$80B4 +Const GL_POST_COLOR_MATRIX_GREEN_SCALE=$80B5 +Const GL_POST_COLOR_MATRIX_BLUE_SCALE=$80B6 +Const GL_POST_COLOR_MATRIX_ALPHA_SCALE=$80B7 +Const GL_POST_COLOR_MATRIX_RED_BIAS=$80B8 +Const GL_POST_COLOR_MATRIX_GREEN_BIAS=$80B9 +Const GL_POST_COLOR_MATRIX_BLUE_BIAS=$80BA +Const GL_POST_COLOR_MATRIX_ALPHA_BIAS=$80BB +Const GL_COLOR_TABLE=$80D0 +Const GL_POST_CONVOLUTION_COLOR_TABLE=$80D1 +Const GL_POST_COLOR_MATRIX_COLOR_TABLE=$80D2 +Const GL_PROXY_COLOR_TABLE=$80D3 +Const GL_PROXY_POST_CONVOLUTION_COLOR_TABLE=$80D4 +Const GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE=$80D5 +Const GL_COLOR_TABLE_SCALE=$80D6 +Const GL_COLOR_TABLE_BIAS=$80D7 +Const GL_COLOR_TABLE_FORMAT=$80D8 +Const GL_COLOR_TABLE_WIDTH=$80D9 +Const GL_COLOR_TABLE_RED_SIZE=$80DA +Const GL_COLOR_TABLE_GREEN_SIZE=$80DB +Const GL_COLOR_TABLE_BLUE_SIZE=$80DC +Const GL_COLOR_TABLE_ALPHA_SIZE=$80DD +Const GL_COLOR_TABLE_LUMINANCE_SIZE=$80DE +Const GL_COLOR_TABLE_INTENSITY_SIZE=$80DF +Const GL_IGNORE_BORDER=$8150 +Const GL_CONSTANT_BORDER=$8151 +Const GL_WRAP_BORDER=$8152 +Const GL_REPLICATE_BORDER=$8153 +Const GL_CONVOLUTION_BORDER_COLOR=$8154 +Global glColorSubTable(target_:Int,start_:Int,count_:Int,format_:Int,type_:Int,data_:Byte Ptr)="__glewColorSubTable" +Global glColorTable(target_:Int,internalformat_:Int,width_:Int,format_:Int,type_:Int,table_:Byte Ptr)="__glewColorTable" +Global glColorTableParameterfv(target_:Int,pname_:Int,params_:Float Ptr)="__glewColorTableParameterfv" +Global glColorTableParameteriv(target_:Int,pname_:Int,params_:Int Ptr)="__glewColorTableParameteriv" +Global glConvolutionFilter1D(target_:Int,internalformat_:Int,width_:Int,format_:Int,type_:Int,image_:Byte Ptr)="__glewConvolutionFilter1D" +Global glConvolutionFilter2D(target_:Int,internalformat_:Int,width_:Int,height_:Int,format_:Int,type_:Int,image_:Byte Ptr)="__glewConvolutionFilter2D" +Global glConvolutionParameterf(target_:Int,pname_:Int,params_:Float)="__glewConvolutionParameterf" +Global glConvolutionParameterfv(target_:Int,pname_:Int,params_:Float Ptr)="__glewConvolutionParameterfv" +Global glConvolutionParameteri(target_:Int,pname_:Int,params_:Int)="__glewConvolutionParameteri" +Global glConvolutionParameteriv(target_:Int,pname_:Int,params_:Int Ptr)="__glewConvolutionParameteriv" +Global glCopyColorSubTable(target_:Int,start_:Int,x_:Int,y_:Int,width_:Int)="__glewCopyColorSubTable" +Global glCopyColorTable(target_:Int,internalformat_:Int,x_:Int,y_:Int,width_:Int)="__glewCopyColorTable" +Global glCopyConvolutionFilter1D(target_:Int,internalformat_:Int,x_:Int,y_:Int,width_:Int)="__glewCopyConvolutionFilter1D" +Global glCopyConvolutionFilter2D(target_:Int,internalformat_:Int,x_:Int,y_:Int,width_:Int,height_:Int)="__glewCopyConvolutionFilter2D" +Global glGetColorTable(target_:Int,format_:Int,type_:Int,table_:Byte Ptr)="__glewGetColorTable" +Global glGetColorTableParameterfv(target_:Int,pname_:Int,params_:Float Ptr)="__glewGetColorTableParameterfv" +Global glGetColorTableParameteriv(target_:Int,pname_:Int,params_:Int Ptr)="__glewGetColorTableParameteriv" +Global glGetConvolutionFilter(target_:Int,format_:Int,type_:Int,image_:Byte Ptr)="__glewGetConvolutionFilter" +Global glGetConvolutionParameterfv(target_:Int,pname_:Int,params_:Float Ptr)="__glewGetConvolutionParameterfv" +Global glGetConvolutionParameteriv(target_:Int,pname_:Int,params_:Int Ptr)="__glewGetConvolutionParameteriv" +Global glGetHistogram(target_:Int,reset_:Byte,format_:Int,type_:Int,values_:Byte Ptr)="__glewGetHistogram" +Global glGetHistogramParameterfv(target_:Int,pname_:Int,params_:Float Ptr)="__glewGetHistogramParameterfv" +Global glGetHistogramParameteriv(target_:Int,pname_:Int,params_:Int Ptr)="__glewGetHistogramParameteriv" +Global glGetMinmax(target_:Int,reset_:Byte,format_:Int,types_:Int,values_:Byte Ptr)="__glewGetMinmax" +Global glGetMinmaxParameterfv(target_:Int,pname_:Int,params_:Float Ptr)="__glewGetMinmaxParameterfv" +Global glGetMinmaxParameteriv(target_:Int,pname_:Int,params_:Int Ptr)="__glewGetMinmaxParameteriv" +Global glGetSeparableFilter(target_:Int,format_:Int,type_:Int,row_:Byte Ptr,column_:Byte Ptr,span_:Byte Ptr)="__glewGetSeparableFilter" +Global glHistogram(target_:Int,width_:Int,internalformat_:Int,sink_:Byte)="__glewHistogram" +Global glMinmax(target_:Int,internalformat_:Int,sink_:Byte)="__glewMinmax" +Global glResetHistogram(target_:Int)="__glewResetHistogram" +Global glResetMinmax(target_:Int)="__glewResetMinmax" +Global glSeparableFilter2D(target_:Int,internalformat_:Int,width_:Int,height_:Int,format_:Int,type_:Int,row_:Byte Ptr,column_:Byte Ptr)="__glewSeparableFilter2D" +Global GL_ARB_imaging:Byte="__GLEW_ARB_imaging" +Const GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB=$88FE +Global glVertexAttribDivisorARB(index_:Int,divisor_:Int)="__glewVertexAttribDivisorARB" +Global GL_ARB_instanced_arrays:Byte="__GLEW_ARB_instanced_arrays" +Const GL_MAP_READ_BIT=$0001 +Const GL_MAP_WRITE_BIT=$0002 +Const GL_MAP_INVALIDATE_RANGE_BIT=$0004 +Const GL_MAP_INVALIDATE_BUFFER_BIT=$0008 +Const GL_MAP_FLUSH_EXPLICIT_BIT=$0010 +Const GL_MAP_UNSYNCHRONIZED_BIT=$0020 +Global glFlushMappedBufferRange(target_:Int,offset_:Int,length_:Int)="__glewFlushMappedBufferRange" +Global glMapBufferRange:Byte Ptr(target_:Int,offset_:Int,length_:Int,access_:Int)="__glewMapBufferRange" +Global GL_ARB_map_buffer_range:Byte="__GLEW_ARB_map_buffer_range" +Const GL_MATRIX_PALETTE_ARB=$8840 +Const GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB=$8841 +Const GL_MAX_PALETTE_MATRICES_ARB=$8842 +Const GL_CURRENT_PALETTE_MATRIX_ARB=$8843 +Const GL_MATRIX_INDEX_ARRAY_ARB=$8844 +Const GL_CURRENT_MATRIX_INDEX_ARB=$8845 +Const GL_MATRIX_INDEX_ARRAY_SIZE_ARB=$8846 +Const GL_MATRIX_INDEX_ARRAY_TYPE_ARB=$8847 +Const GL_MATRIX_INDEX_ARRAY_STRIDE_ARB=$8848 +Const GL_MATRIX_INDEX_ARRAY_POINTER_ARB=$8849 +Global glCurrentPaletteMatrixARB(index_:Int)="__glewCurrentPaletteMatrixARB" +Global glMatrixIndexPointerARB(size_:Int,type_:Int,stride_:Int,pointer_:Byte Ptr)="__glewMatrixIndexPointerARB" +Global glMatrixIndexubvARB(size_:Int,indices_:Byte Ptr)="__glewMatrixIndexubvARB" +Global glMatrixIndexuivARB(size_:Int,indices_:Int Ptr)="__glewMatrixIndexuivARB" +Global glMatrixIndexusvARB(size_:Int,indices_:Short Ptr)="__glewMatrixIndexusvARB" +Global GL_ARB_matrix_palette:Byte="__GLEW_ARB_matrix_palette" +Const GL_MULTISAMPLE_ARB=$809D +Const GL_SAMPLE_ALPHA_TO_COVERAGE_ARB=$809E +Const GL_SAMPLE_ALPHA_TO_ONE_ARB=$809F +Const GL_SAMPLE_COVERAGE_ARB=$80A0 +Const GL_SAMPLE_BUFFERS_ARB=$80A8 +Const GL_SAMPLES_ARB=$80A9 +Const GL_SAMPLE_COVERAGE_VALUE_ARB=$80AA +Const GL_SAMPLE_COVERAGE_INVERT_ARB=$80AB +Const GL_MULTISAMPLE_BIT_ARB=$20000000 +Global glSampleCoverageARB(value_:Float,invert_:Byte)="__glewSampleCoverageARB" +Global GL_ARB_multisample:Byte="__GLEW_ARB_multisample" +Const GL_TEXTURE0_ARB=$84C0 +Const GL_TEXTURE1_ARB=$84C1 +Const GL_TEXTURE2_ARB=$84C2 +Const GL_TEXTURE3_ARB=$84C3 +Const GL_TEXTURE4_ARB=$84C4 +Const GL_TEXTURE5_ARB=$84C5 +Const GL_TEXTURE6_ARB=$84C6 +Const GL_TEXTURE7_ARB=$84C7 +Const GL_TEXTURE8_ARB=$84C8 +Const GL_TEXTURE9_ARB=$84C9 +Const GL_TEXTURE10_ARB=$84CA +Const GL_TEXTURE11_ARB=$84CB +Const GL_TEXTURE12_ARB=$84CC +Const GL_TEXTURE13_ARB=$84CD +Const GL_TEXTURE14_ARB=$84CE +Const GL_TEXTURE15_ARB=$84CF +Const GL_TEXTURE16_ARB=$84D0 +Const GL_TEXTURE17_ARB=$84D1 +Const GL_TEXTURE18_ARB=$84D2 +Const GL_TEXTURE19_ARB=$84D3 +Const GL_TEXTURE20_ARB=$84D4 +Const GL_TEXTURE21_ARB=$84D5 +Const GL_TEXTURE22_ARB=$84D6 +Const GL_TEXTURE23_ARB=$84D7 +Const GL_TEXTURE24_ARB=$84D8 +Const GL_TEXTURE25_ARB=$84D9 +Const GL_TEXTURE26_ARB=$84DA +Const GL_TEXTURE27_ARB=$84DB +Const GL_TEXTURE28_ARB=$84DC +Const GL_TEXTURE29_ARB=$84DD +Const GL_TEXTURE30_ARB=$84DE +Const GL_TEXTURE31_ARB=$84DF +Const GL_ACTIVE_TEXTURE_ARB=$84E0 +Const GL_CLIENT_ACTIVE_TEXTURE_ARB=$84E1 +Const GL_MAX_TEXTURE_UNITS_ARB=$84E2 +Global glActiveTextureARB(texture_:Int)="__glewActiveTextureARB" +Global glClientActiveTextureARB(texture_:Int)="__glewClientActiveTextureARB" +Global glMultiTexCoord1dARB(target_:Int,s_:Double)="__glewMultiTexCoord1dARB" +Global glMultiTexCoord1dvARB(target_:Int,v_:Double Ptr)="__glewMultiTexCoord1dvARB" +Global glMultiTexCoord1fARB(target_:Int,s_:Float)="__glewMultiTexCoord1fARB" +Global glMultiTexCoord1fvARB(target_:Int,v_:Float Ptr)="__glewMultiTexCoord1fvARB" +Global glMultiTexCoord1iARB(target_:Int,s_:Int)="__glewMultiTexCoord1iARB" +Global glMultiTexCoord1ivARB(target_:Int,v_:Int Ptr)="__glewMultiTexCoord1ivARB" +Global glMultiTexCoord1sARB(target_:Int,s_:Short)="__glewMultiTexCoord1sARB" +Global glMultiTexCoord1svARB(target_:Int,v_:Short Ptr)="__glewMultiTexCoord1svARB" +Global glMultiTexCoord2dARB(target_:Int,s_:Double,t_:Double)="__glewMultiTexCoord2dARB" +Global glMultiTexCoord2dvARB(target_:Int,v_:Double Ptr)="__glewMultiTexCoord2dvARB" +Global glMultiTexCoord2fARB(target_:Int,s_:Float,t_:Float)="__glewMultiTexCoord2fARB" +Global glMultiTexCoord2fvARB(target_:Int,v_:Float Ptr)="__glewMultiTexCoord2fvARB" +Global glMultiTexCoord2iARB(target_:Int,s_:Int,t_:Int)="__glewMultiTexCoord2iARB" +Global glMultiTexCoord2ivARB(target_:Int,v_:Int Ptr)="__glewMultiTexCoord2ivARB" +Global glMultiTexCoord2sARB(target_:Int,s_:Short,t_:Short)="__glewMultiTexCoord2sARB" +Global glMultiTexCoord2svARB(target_:Int,v_:Short Ptr)="__glewMultiTexCoord2svARB" +Global glMultiTexCoord3dARB(target_:Int,s_:Double,t_:Double,r_:Double)="__glewMultiTexCoord3dARB" +Global glMultiTexCoord3dvARB(target_:Int,v_:Double Ptr)="__glewMultiTexCoord3dvARB" +Global glMultiTexCoord3fARB(target_:Int,s_:Float,t_:Float,r_:Float)="__glewMultiTexCoord3fARB" +Global glMultiTexCoord3fvARB(target_:Int,v_:Float Ptr)="__glewMultiTexCoord3fvARB" +Global glMultiTexCoord3iARB(target_:Int,s_:Int,t_:Int,r_:Int)="__glewMultiTexCoord3iARB" +Global glMultiTexCoord3ivARB(target_:Int,v_:Int Ptr)="__glewMultiTexCoord3ivARB" +Global glMultiTexCoord3sARB(target_:Int,s_:Short,t_:Short,r_:Short)="__glewMultiTexCoord3sARB" +Global glMultiTexCoord3svARB(target_:Int,v_:Short Ptr)="__glewMultiTexCoord3svARB" +Global glMultiTexCoord4dARB(target_:Int,s_:Double,t_:Double,r_:Double,q_:Double)="__glewMultiTexCoord4dARB" +Global glMultiTexCoord4dvARB(target_:Int,v_:Double Ptr)="__glewMultiTexCoord4dvARB" +Global glMultiTexCoord4fARB(target_:Int,s_:Float,t_:Float,r_:Float,q_:Float)="__glewMultiTexCoord4fARB" +Global glMultiTexCoord4fvARB(target_:Int,v_:Float Ptr)="__glewMultiTexCoord4fvARB" +Global glMultiTexCoord4iARB(target_:Int,s_:Int,t_:Int,r_:Int,q_:Int)="__glewMultiTexCoord4iARB" +Global glMultiTexCoord4ivARB(target_:Int,v_:Int Ptr)="__glewMultiTexCoord4ivARB" +Global glMultiTexCoord4sARB(target_:Int,s_:Short,t_:Short,r_:Short,q_:Short)="__glewMultiTexCoord4sARB" +Global glMultiTexCoord4svARB(target_:Int,v_:Short Ptr)="__glewMultiTexCoord4svARB" +Global GL_ARB_multitexture:Byte="__GLEW_ARB_multitexture" +Const GL_QUERY_COUNTER_BITS_ARB=$8864 +Const GL_CURRENT_QUERY_ARB=$8865 +Const GL_QUERY_RESULT_ARB=$8866 +Const GL_QUERY_RESULT_AVAILABLE_ARB=$8867 +Const GL_SAMPLES_PASSED_ARB=$8914 +Global glBeginQueryARB(target_:Int,id_:Int)="__glewBeginQueryARB" +Global glDeleteQueriesARB(n_:Int,ids_:Int Ptr)="__glewDeleteQueriesARB" +Global glEndQueryARB(target_:Int)="__glewEndQueryARB" +Global glGenQueriesARB(n_:Int,ids_:Int Ptr)="__glewGenQueriesARB" +Global glGetQueryObjectivARB(id_:Int,pname_:Int,params_:Int Ptr)="__glewGetQueryObjectivARB" +Global glGetQueryObjectuivARB(id_:Int,pname_:Int,params_:Int Ptr)="__glewGetQueryObjectuivARB" +Global glGetQueryivARB(target_:Int,pname_:Int,params_:Int Ptr)="__glewGetQueryivARB" +Global glIsQueryARB:Byte(id_:Int)="__glewIsQueryARB" +Global GL_ARB_occlusion_query:Byte="__GLEW_ARB_occlusion_query" +Const GL_PIXEL_PACK_BUFFER_ARB=$88EB +Const GL_PIXEL_UNPACK_BUFFER_ARB=$88EC +Const GL_PIXEL_PACK_BUFFER_BINDING_ARB=$88ED +Const GL_PIXEL_UNPACK_BUFFER_BINDING_ARB=$88EF +Global GL_ARB_pixel_buffer_object:Byte="__GLEW_ARB_pixel_buffer_object" +Const GL_POINT_SIZE_MIN_ARB=$8126 +Const GL_POINT_SIZE_MAX_ARB=$8127 +Const GL_POINT_FADE_THRESHOLD_SIZE_ARB=$8128 +Const GL_POINT_DISTANCE_ATTENUATION_ARB=$8129 +Global glPointParameterfARB(pname_:Int,param_:Float)="__glewPointParameterfARB" +Global glPointParameterfvARB(pname_:Int,params_:Float Ptr)="__glewPointParameterfvARB" +Global GL_ARB_point_parameters:Byte="__GLEW_ARB_point_parameters" +Const GL_POINT_SPRITE_ARB=$8861 +Const GL_COORD_REPLACE_ARB=$8862 +Global GL_ARB_point_sprite:Byte="__GLEW_ARB_point_sprite" +Const GL_PROGRAM_OBJECT_ARB=$8B40 +Const GL_SHADER_OBJECT_ARB=$8B48 +Const GL_OBJECT_TYPE_ARB=$8B4E +Const GL_OBJECT_SUBTYPE_ARB=$8B4F +Const GL_FLOAT_VEC2_ARB=$8B50 +Const GL_FLOAT_VEC3_ARB=$8B51 +Const GL_FLOAT_VEC4_ARB=$8B52 +Const GL_INT_VEC2_ARB=$8B53 +Const GL_INT_VEC3_ARB=$8B54 +Const GL_INT_VEC4_ARB=$8B55 +Const GL_BOOL_ARB=$8B56 +Const GL_BOOL_VEC2_ARB=$8B57 +Const GL_BOOL_VEC3_ARB=$8B58 +Const GL_BOOL_VEC4_ARB=$8B59 +Const GL_FLOAT_MAT2_ARB=$8B5A +Const GL_FLOAT_MAT3_ARB=$8B5B +Const GL_FLOAT_MAT4_ARB=$8B5C +Const GL_SAMPLER_1D_ARB=$8B5D +Const GL_SAMPLER_2D_ARB=$8B5E +Const GL_SAMPLER_3D_ARB=$8B5F +Const GL_SAMPLER_CUBE_ARB=$8B60 +Const GL_SAMPLER_1D_SHADOW_ARB=$8B61 +Const GL_SAMPLER_2D_SHADOW_ARB=$8B62 +Const GL_SAMPLER_2D_RECT_ARB=$8B63 +Const GL_SAMPLER_2D_RECT_SHADOW_ARB=$8B64 +Const GL_OBJECT_DELETE_STATUS_ARB=$8B80 +Const GL_OBJECT_COMPILE_STATUS_ARB=$8B81 +Const GL_OBJECT_LINK_STATUS_ARB=$8B82 +Const GL_OBJECT_VALIDATE_STATUS_ARB=$8B83 +Const GL_OBJECT_INFO_LOG_LENGTH_ARB=$8B84 +Const GL_OBJECT_ATTACHED_OBJECTS_ARB=$8B85 +Const GL_OBJECT_ACTIVE_UNIFORMS_ARB=$8B86 +Const GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB=$8B87 +Const GL_OBJECT_SHADER_SOURCE_LENGTH_ARB=$8B88 +Global glAttachObjectARB(containerObj_:Int,obj_:Int)="__glewAttachObjectARB" +Global glCompileShaderARB(shaderObj_:Int)="__glewCompileShaderARB" +Global glCreateProgramObjectARB:Int()="__glewCreateProgramObjectARB" +Global glCreateShaderObjectARB:Int(shaderType_:Int)="__glewCreateShaderObjectARB" +Global glDeleteObjectARB(obj_:Int)="__glewDeleteObjectARB" +Global glDetachObjectARB(containerObj_:Int,attachedObj_:Int)="__glewDetachObjectARB" +Global glGetActiveUniformARB(programObj_:Int,index_:Int,maxLength_:Int,length_:Int Ptr,size_:Int Ptr,type_:Int Ptr,name_:Byte Ptr)="__glewGetActiveUniformARB" +Global glGetAttachedObjectsARB(containerObj_:Int,maxCount_:Int,count_:Int Ptr,obj_:Int Ptr)="__glewGetAttachedObjectsARB" +Global glGetHandleARB:Int(pname_:Int)="__glewGetHandleARB" +Global glGetInfoLogARB(obj_:Int,maxLength_:Int,length_:Int Ptr,infoLog_:Byte Ptr)="__glewGetInfoLogARB" +Global glGetObjectParameterfvARB(obj_:Int,pname_:Int,params_:Float Ptr)="__glewGetObjectParameterfvARB" +Global glGetObjectParameterivARB(obj_:Int,pname_:Int,params_:Int Ptr)="__glewGetObjectParameterivARB" +Global glGetShaderSourceARB(obj_:Int,maxLength_:Int,length_:Int Ptr,source_:Byte Ptr)="__glewGetShaderSourceARB" +Global glGetUniformLocationARB:Int(programObj_:Int,name_:Byte Ptr)="__glewGetUniformLocationARB" +Global glGetUniformfvARB(programObj_:Int,location_:Int,params_:Float Ptr)="__glewGetUniformfvARB" +Global glGetUniformivARB(programObj_:Int,location_:Int,params_:Int Ptr)="__glewGetUniformivARB" +Global glLinkProgramARB(programObj_:Int)="__glewLinkProgramARB" +Global glShaderSourceARB(shaderObj_:Int,count_:Int,string_:Byte Ptr Ptr,length_:Int Ptr)="__glewShaderSourceARB" +Global glUniform1fARB(location_:Int,v0_:Float)="__glewUniform1fARB" +Global glUniform1fvARB(location_:Int,count_:Int,value_:Float Ptr)="__glewUniform1fvARB" +Global glUniform1iARB(location_:Int,v0_:Int)="__glewUniform1iARB" +Global glUniform1ivARB(location_:Int,count_:Int,value_:Int Ptr)="__glewUniform1ivARB" +Global glUniform2fARB(location_:Int,v0_:Float,v1_:Float)="__glewUniform2fARB" +Global glUniform2fvARB(location_:Int,count_:Int,value_:Float Ptr)="__glewUniform2fvARB" +Global glUniform2iARB(location_:Int,v0_:Int,v1_:Int)="__glewUniform2iARB" +Global glUniform2ivARB(location_:Int,count_:Int,value_:Int Ptr)="__glewUniform2ivARB" +Global glUniform3fARB(location_:Int,v0_:Float,v1_:Float,v2_:Float)="__glewUniform3fARB" +Global glUniform3fvARB(location_:Int,count_:Int,value_:Float Ptr)="__glewUniform3fvARB" +Global glUniform3iARB(location_:Int,v0_:Int,v1_:Int,v2_:Int)="__glewUniform3iARB" +Global glUniform3ivARB(location_:Int,count_:Int,value_:Int Ptr)="__glewUniform3ivARB" +Global glUniform4fARB(location_:Int,v0_:Float,v1_:Float,v2_:Float,v3_:Float)="__glewUniform4fARB" +Global glUniform4fvARB(location_:Int,count_:Int,value_:Float Ptr)="__glewUniform4fvARB" +Global glUniform4iARB(location_:Int,v0_:Int,v1_:Int,v2_:Int,v3_:Int)="__glewUniform4iARB" +Global glUniform4ivARB(location_:Int,count_:Int,value_:Int Ptr)="__glewUniform4ivARB" +Global glUniformMatrix2fvARB(location_:Int,count_:Int,transpose_:Byte,value_:Float Ptr)="__glewUniformMatrix2fvARB" +Global glUniformMatrix3fvARB(location_:Int,count_:Int,transpose_:Byte,value_:Float Ptr)="__glewUniformMatrix3fvARB" +Global glUniformMatrix4fvARB(location_:Int,count_:Int,transpose_:Byte,value_:Float Ptr)="__glewUniformMatrix4fvARB" +Global glUseProgramObjectARB(programObj_:Int)="__glewUseProgramObjectARB" +Global glValidateProgramARB(programObj_:Int)="__glewValidateProgramARB" +Global GL_ARB_shader_objects:Byte="__GLEW_ARB_shader_objects" +Const GL_SHADING_LANGUAGE_VERSION_ARB=$8B8C +Global GL_ARB_shading_language_100:Byte="__GLEW_ARB_shading_language_100" +Const GL_TEXTURE_COMPARE_MODE_ARB=$884C +Const GL_TEXTURE_COMPARE_FUNC_ARB=$884D +Const GL_COMPARE_R_TO_TEXTURE_ARB=$884E +Global GL_ARB_shadow:Byte="__GLEW_ARB_shadow" +Const GL_TEXTURE_COMPARE_FAIL_VALUE_ARB=$80BF +Global GL_ARB_shadow_ambient:Byte="__GLEW_ARB_shadow_ambient" +Const GL_CLAMP_TO_BORDER_ARB=$812D +Global GL_ARB_texture_border_clamp:Byte="__GLEW_ARB_texture_border_clamp" +Const GL_TEXTURE_BUFFER_ARB=$8C2A +Const GL_MAX_TEXTURE_BUFFER_SIZE_ARB=$8C2B +Const GL_TEXTURE_BINDING_BUFFER_ARB=$8C2C +Const GL_TEXTURE_BUFFER_DATA_STORE_BINDING_ARB=$8C2D +Const GL_TEXTURE_BUFFER_FORMAT_ARB=$8C2E +Global glTexBufferARB(target_:Int,internalformat_:Int,buffer_:Int)="__glewTexBufferARB" +Global GL_ARB_texture_buffer_object:Byte="__GLEW_ARB_texture_buffer_object" +Const GL_COMPRESSED_ALPHA_ARB=$84E9 +Const GL_COMPRESSED_LUMINANCE_ARB=$84EA +Const GL_COMPRESSED_LUMINANCE_ALPHA_ARB=$84EB +Const GL_COMPRESSED_INTENSITY_ARB=$84EC +Const GL_COMPRESSED_RGB_ARB=$84ED +Const GL_COMPRESSED_RGBA_ARB=$84EE +Const GL_TEXTURE_COMPRESSION_HINT_ARB=$84EF +Const GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB=$86A0 +Const GL_TEXTURE_COMPRESSED_ARB=$86A1 +Const GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB=$86A2 +Const GL_COMPRESSED_TEXTURE_FORMATS_ARB=$86A3 +Global glCompressedTexImage1DARB(target_:Int,level_:Int,internalformat_:Int,width_:Int,border_:Int,imageSize_:Int,data_:Byte Ptr)="__glewCompressedTexImage1DARB" +Global glCompressedTexImage2DARB(target_:Int,level_:Int,internalformat_:Int,width_:Int,height_:Int,border_:Int,imageSize_:Int,data_:Byte Ptr)="__glewCompressedTexImage2DARB" +Global glCompressedTexImage3DARB(target_:Int,level_:Int,internalformat_:Int,width_:Int,height_:Int,depth_:Int,border_:Int,imageSize_:Int,data_:Byte Ptr)="__glewCompressedTexImage3DARB" +Global glCompressedTexSubImage1DARB(target_:Int,level_:Int,xoffset_:Int,width_:Int,format_:Int,imageSize_:Int,data_:Byte Ptr)="__glewCompressedTexSubImage1DARB" +Global glCompressedTexSubImage2DARB(target_:Int,level_:Int,xoffset_:Int,yoffset_:Int,width_:Int,height_:Int,format_:Int,imageSize_:Int,data_:Byte Ptr)="__glewCompressedTexSubImage2DARB" +Global glCompressedTexSubImage3DARB(target_:Int,level_:Int,xoffset_:Int,yoffset_:Int,zoffset_:Int,width_:Int,height_:Int,depth_:Int,format_:Int,imageSize_:Int,data_:Byte Ptr)="__glewCompressedTexSubImage3DARB" +Global glGetCompressedTexImageARB(target_:Int,lod_:Int,img_:Byte Ptr)="__glewGetCompressedTexImageARB" +Global GL_ARB_texture_compression:Byte="__GLEW_ARB_texture_compression" +Const GL_COMPRESSED_RED_RGTC1=$8DBB +Const GL_COMPRESSED_SIGNED_RED_RGTC1=$8DBC +Const GL_COMPRESSED_RG_RGTC2=$8DBD +Const GL_COMPRESSED_SIGNED_RG_RGTC2=$8DBE +Global GL_ARB_texture_compression_rgtc:Byte="__GLEW_ARB_texture_compression_rgtc" +Const GL_NORMAL_MAP_ARB=$8511 +Const GL_REFLECTION_MAP_ARB=$8512 +Const GL_TEXTURE_CUBE_MAP_ARB=$8513 +Const GL_TEXTURE_BINDING_CUBE_MAP_ARB=$8514 +Const GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB=$8515 +Const GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB=$8516 +Const GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB=$8517 +Const GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB=$8518 +Const GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB=$8519 +Const GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB=$851A +Const GL_PROXY_TEXTURE_CUBE_MAP_ARB=$851B +Const GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB=$851C +Global GL_ARB_texture_cube_map:Byte="__GLEW_ARB_texture_cube_map" +Global GL_ARB_texture_env_add:Byte="__GLEW_ARB_texture_env_add" +Const GL_SUBTRACT_ARB=$84E7 +Const GL_COMBINE_ARB=$8570 +Const GL_COMBINE_RGB_ARB=$8571 +Const GL_COMBINE_ALPHA_ARB=$8572 +Const GL_RGB_SCALE_ARB=$8573 +Const GL_ADD_SIGNED_ARB=$8574 +Const GL_INTERPOLATE_ARB=$8575 +Const GL_CONSTANT_ARB=$8576 +Const GL_PRIMARY_COLOR_ARB=$8577 +Const GL_PREVIOUS_ARB=$8578 +Const GL_SOURCE0_RGB_ARB=$8580 +Const GL_SOURCE1_RGB_ARB=$8581 +Const GL_SOURCE2_RGB_ARB=$8582 +Const GL_SOURCE0_ALPHA_ARB=$8588 +Const GL_SOURCE1_ALPHA_ARB=$8589 +Const GL_SOURCE2_ALPHA_ARB=$858A +Const GL_OPERAND0_RGB_ARB=$8590 +Const GL_OPERAND1_RGB_ARB=$8591 +Const GL_OPERAND2_RGB_ARB=$8592 +Const GL_OPERAND0_ALPHA_ARB=$8598 +Const GL_OPERAND1_ALPHA_ARB=$8599 +Const GL_OPERAND2_ALPHA_ARB=$859A +Global GL_ARB_texture_env_combine:Byte="__GLEW_ARB_texture_env_combine" +Global GL_ARB_texture_env_crossbar:Byte="__GLEW_ARB_texture_env_crossbar" +Const GL_DOT3_RGB_ARB=$86AE +Const GL_DOT3_RGBA_ARB=$86AF +Global GL_ARB_texture_env_dot3:Byte="__GLEW_ARB_texture_env_dot3" +Const GL_RGBA32F_ARB=$8814 +Const GL_RGB32F_ARB=$8815 +Const GL_ALPHA32F_ARB=$8816 +Const GL_INTENSITY32F_ARB=$8817 +Const GL_LUMINANCE32F_ARB=$8818 +Const GL_LUMINANCE_ALPHA32F_ARB=$8819 +Const GL_RGBA16F_ARB=$881A +Const GL_RGB16F_ARB=$881B +Const GL_ALPHA16F_ARB=$881C +Const GL_INTENSITY16F_ARB=$881D +Const GL_LUMINANCE16F_ARB=$881E +Const GL_LUMINANCE_ALPHA16F_ARB=$881F +Const GL_TEXTURE_RED_TYPE_ARB=$8C10 +Const GL_TEXTURE_GREEN_TYPE_ARB=$8C11 +Const GL_TEXTURE_BLUE_TYPE_ARB=$8C12 +Const GL_TEXTURE_ALPHA_TYPE_ARB=$8C13 +Const GL_TEXTURE_LUMINANCE_TYPE_ARB=$8C14 +Const GL_TEXTURE_INTENSITY_TYPE_ARB=$8C15 +Const GL_TEXTURE_DEPTH_TYPE_ARB=$8C16 +Const GL_UNSIGNED_NORMALIZED_ARB=$8C17 +Global GL_ARB_texture_float:Byte="__GLEW_ARB_texture_float" +Const GL_MIRRORED_REPEAT_ARB=$8370 +Global GL_ARB_texture_mirrored_repeat:Byte="__GLEW_ARB_texture_mirrored_repeat" +Global GL_ARB_texture_non_power_of_two:Byte="__GLEW_ARB_texture_non_power_of_two" +Const GL_TEXTURE_RECTANGLE_ARB=$84F5 +Const GL_TEXTURE_BINDING_RECTANGLE_ARB=$84F6 +Const GL_PROXY_TEXTURE_RECTANGLE_ARB=$84F7 +Const GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB=$84F8 +Global GL_ARB_texture_rectangle:Byte="__GLEW_ARB_texture_rectangle" +Const GL_RG=$8227 +Const GL_RG_INTEGER=$8228 +Const GL_R8=$8229 +Const GL_R16=$822A +Const GL_RG8=$822B +Const GL_RG16=$822C +Const GL_R16F=$822D +Const GL_R32F=$822E +Const GL_RG16F=$822F +Const GL_RG32F=$8230 +Const GL_R8I=$8231 +Const GL_R8UI=$8232 +Const GL_R16I=$8233 +Const GL_R16UI=$8234 +Const GL_R32I=$8235 +Const GL_R32UI=$8236 +Const GL_RG8I=$8237 +Const GL_RG8UI=$8238 +Const GL_RG16I=$8239 +Const GL_RG16UI=$823A +Const GL_RG32I=$823B +Const GL_RG32UI=$823C +Global GL_ARB_texture_rg:Byte="__GLEW_ARB_texture_rg" +Const GL_TRANSPOSE_MODELVIEW_MATRIX_ARB=$84E3 +Const GL_TRANSPOSE_PROJECTION_MATRIX_ARB=$84E4 +Const GL_TRANSPOSE_TEXTURE_MATRIX_ARB=$84E5 +Const GL_TRANSPOSE_COLOR_MATRIX_ARB=$84E6 +Global glLoadTransposeMatrixdARB(m_:Double Ptr)="__glewLoadTransposeMatrixdARB" +Global glLoadTransposeMatrixfARB(m_:Float Ptr)="__glewLoadTransposeMatrixfARB" +Global glMultTransposeMatrixdARB(m_:Double Ptr)="__glewMultTransposeMatrixdARB" +Global glMultTransposeMatrixfARB(m_:Float Ptr)="__glewMultTransposeMatrixfARB" +Global GL_ARB_transpose_matrix:Byte="__GLEW_ARB_transpose_matrix" +Const GL_VERTEX_ARRAY_BINDING=$85B5 +Global glBindVertexArray(array_:Int)="__glewBindVertexArray" +Global glDeleteVertexArrays(n_:Int,arrays_:Int Ptr)="__glewDeleteVertexArrays" +Global glGenVertexArrays(n_:Int,arrays_:Int Ptr)="__glewGenVertexArrays" +Global glIsVertexArray:Byte(array_:Int)="__glewIsVertexArray" +Global GL_ARB_vertex_array_object:Byte="__GLEW_ARB_vertex_array_object" +Const GL_MODELVIEW0_ARB=$1700 +Const GL_MODELVIEW1_ARB=$850A +Const GL_MAX_VERTEX_UNITS_ARB=$86A4 +Const GL_ACTIVE_VERTEX_UNITS_ARB=$86A5 +Const GL_WEIGHT_SUM_UNITY_ARB=$86A6 +Const GL_VERTEX_BLEND_ARB=$86A7 +Const GL_CURRENT_WEIGHT_ARB=$86A8 +Const GL_WEIGHT_ARRAY_TYPE_ARB=$86A9 +Const GL_WEIGHT_ARRAY_STRIDE_ARB=$86AA +Const GL_WEIGHT_ARRAY_SIZE_ARB=$86AB +Const GL_WEIGHT_ARRAY_POINTER_ARB=$86AC +Const GL_WEIGHT_ARRAY_ARB=$86AD +Const GL_MODELVIEW2_ARB=$8722 +Const GL_MODELVIEW3_ARB=$8723 +Const GL_MODELVIEW4_ARB=$8724 +Const GL_MODELVIEW5_ARB=$8725 +Const GL_MODELVIEW6_ARB=$8726 +Const GL_MODELVIEW7_ARB=$8727 +Const GL_MODELVIEW8_ARB=$8728 +Const GL_MODELVIEW9_ARB=$8729 +Const GL_MODELVIEW10_ARB=$872A +Const GL_MODELVIEW11_ARB=$872B +Const GL_MODELVIEW12_ARB=$872C +Const GL_MODELVIEW13_ARB=$872D +Const GL_MODELVIEW14_ARB=$872E +Const GL_MODELVIEW15_ARB=$872F +Const GL_MODELVIEW16_ARB=$8730 +Const GL_MODELVIEW17_ARB=$8731 +Const GL_MODELVIEW18_ARB=$8732 +Const GL_MODELVIEW19_ARB=$8733 +Const GL_MODELVIEW20_ARB=$8734 +Const GL_MODELVIEW21_ARB=$8735 +Const GL_MODELVIEW22_ARB=$8736 +Const GL_MODELVIEW23_ARB=$8737 +Const GL_MODELVIEW24_ARB=$8738 +Const GL_MODELVIEW25_ARB=$8739 +Const GL_MODELVIEW26_ARB=$873A +Const GL_MODELVIEW27_ARB=$873B +Const GL_MODELVIEW28_ARB=$873C +Const GL_MODELVIEW29_ARB=$873D +Const GL_MODELVIEW30_ARB=$873E +Const GL_MODELVIEW31_ARB=$873F +Global glVertexBlendARB(count_:Int)="__glewVertexBlendARB" +Global glWeightPointerARB(size_:Int,type_:Int,stride_:Int,pointer_:Byte Ptr)="__glewWeightPointerARB" +Global glWeightbvARB(size_:Int,weights_:Byte Ptr)="__glewWeightbvARB" +Global glWeightdvARB(size_:Int,weights_:Double Ptr)="__glewWeightdvARB" +Global glWeightfvARB(size_:Int,weights_:Float Ptr)="__glewWeightfvARB" +Global glWeightivARB(size_:Int,weights_:Int Ptr)="__glewWeightivARB" +Global glWeightsvARB(size_:Int,weights_:Short Ptr)="__glewWeightsvARB" +Global glWeightubvARB(size_:Int,weights_:Byte Ptr)="__glewWeightubvARB" +Global glWeightuivARB(size_:Int,weights_:Int Ptr)="__glewWeightuivARB" +Global glWeightusvARB(size_:Int,weights_:Short Ptr)="__glewWeightusvARB" +Global GL_ARB_vertex_blend:Byte="__GLEW_ARB_vertex_blend" +Const GL_BUFFER_SIZE_ARB=$8764 +Const GL_BUFFER_USAGE_ARB=$8765 +Const GL_ARRAY_BUFFER_ARB=$8892 +Const GL_ELEMENT_ARRAY_BUFFER_ARB=$8893 +Const GL_ARRAY_BUFFER_BINDING_ARB=$8894 +Const GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB=$8895 +Const GL_VERTEX_ARRAY_BUFFER_BINDING_ARB=$8896 +Const GL_NORMAL_ARRAY_BUFFER_BINDING_ARB=$8897 +Const GL_COLOR_ARRAY_BUFFER_BINDING_ARB=$8898 +Const GL_INDEX_ARRAY_BUFFER_BINDING_ARB=$8899 +Const GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB=$889A +Const GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB=$889B +Const GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB=$889C +Const GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB=$889D +Const GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB=$889E +Const GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB=$889F +Const GL_READ_ONLY_ARB=$88B8 +Const GL_WRITE_ONLY_ARB=$88B9 +Const GL_READ_WRITE_ARB=$88BA +Const GL_BUFFER_ACCESS_ARB=$88BB +Const GL_BUFFER_MAPPED_ARB=$88BC +Const GL_BUFFER_MAP_POINTER_ARB=$88BD +Const GL_STREAM_DRAW_ARB=$88E0 +Const GL_STREAM_READ_ARB=$88E1 +Const GL_STREAM_COPY_ARB=$88E2 +Const GL_STATIC_DRAW_ARB=$88E4 +Const GL_STATIC_READ_ARB=$88E5 +Const GL_STATIC_COPY_ARB=$88E6 +Const GL_DYNAMIC_DRAW_ARB=$88E8 +Const GL_DYNAMIC_READ_ARB=$88E9 +Const GL_DYNAMIC_COPY_ARB=$88EA +Global glBindBufferARB(target_:Int,buffer_:Int)="__glewBindBufferARB" +Global glBufferDataARB(target_:Int,size_:Int,data_:Byte Ptr,usage_:Int)="__glewBufferDataARB" +Global glBufferSubDataARB(target_:Int,offset_:Int,size_:Int,data_:Byte Ptr)="__glewBufferSubDataARB" +Global glDeleteBuffersARB(n_:Int,buffers_:Int Ptr)="__glewDeleteBuffersARB" +Global glGenBuffersARB(n_:Int,buffers_:Int Ptr)="__glewGenBuffersARB" +Global glGetBufferParameterivARB(target_:Int,pname_:Int,params_:Int Ptr)="__glewGetBufferParameterivARB" +Global glGetBufferPointervARB(target_:Int,pname_:Int,params_:Byte Ptr Ptr)="__glewGetBufferPointervARB" +Global glGetBufferSubDataARB(target_:Int,offset_:Int,size_:Int,data_:Byte Ptr)="__glewGetBufferSubDataARB" +Global glIsBufferARB:Byte(buffer_:Int)="__glewIsBufferARB" +Global glMapBufferARB:Byte Ptr(target_:Int,access_:Int)="__glewMapBufferARB" +Global glUnmapBufferARB:Byte(target_:Int)="__glewUnmapBufferARB" +Global GL_ARB_vertex_buffer_object:Byte="__GLEW_ARB_vertex_buffer_object" +Const GL_COLOR_SUM_ARB=$8458 +Const GL_VERTEX_PROGRAM_ARB=$8620 +Const GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB=$8622 +Const GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB=$8623 +Const GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB=$8624 +Const GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB=$8625 +Const GL_CURRENT_VERTEX_ATTRIB_ARB=$8626 +Const GL_PROGRAM_LENGTH_ARB=$8627 +Const GL_PROGRAM_STRING_ARB=$8628 +Const GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB=$862E +Const GL_MAX_PROGRAM_MATRICES_ARB=$862F +Const GL_CURRENT_MATRIX_STACK_DEPTH_ARB=$8640 +Const GL_CURRENT_MATRIX_ARB=$8641 +Const GL_VERTEX_PROGRAM_POINT_SIZE_ARB=$8642 +Const GL_VERTEX_PROGRAM_TWO_SIDE_ARB=$8643 +Const GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB=$8645 +Const GL_PROGRAM_ERROR_POSITION_ARB=$864B +Const GL_PROGRAM_BINDING_ARB=$8677 +Const GL_MAX_VERTEX_ATTRIBS_ARB=$8869 +Const GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB=$886A +Const GL_PROGRAM_ERROR_STRING_ARB=$8874 +Const GL_PROGRAM_FORMAT_ASCII_ARB=$8875 +Const GL_PROGRAM_FORMAT_ARB=$8876 +Const GL_PROGRAM_INSTRUCTIONS_ARB=$88A0 +Const GL_MAX_PROGRAM_INSTRUCTIONS_ARB=$88A1 +Const GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB=$88A2 +Const GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB=$88A3 +Const GL_PROGRAM_TEMPORARIES_ARB=$88A4 +Const GL_MAX_PROGRAM_TEMPORARIES_ARB=$88A5 +Const GL_PROGRAM_NATIVE_TEMPORARIES_ARB=$88A6 +Const GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB=$88A7 +Const GL_PROGRAM_PARAMETERS_ARB=$88A8 +Const GL_MAX_PROGRAM_PARAMETERS_ARB=$88A9 +Const GL_PROGRAM_NATIVE_PARAMETERS_ARB=$88AA +Const GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB=$88AB +Const GL_PROGRAM_ATTRIBS_ARB=$88AC +Const GL_MAX_PROGRAM_ATTRIBS_ARB=$88AD +Const GL_PROGRAM_NATIVE_ATTRIBS_ARB=$88AE +Const GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB=$88AF +Const GL_PROGRAM_ADDRESS_REGISTERS_ARB=$88B0 +Const GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB=$88B1 +Const GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB=$88B2 +Const GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB=$88B3 +Const GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB=$88B4 +Const GL_MAX_PROGRAM_ENV_PARAMETERS_ARB=$88B5 +Const GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB=$88B6 +Const GL_TRANSPOSE_CURRENT_MATRIX_ARB=$88B7 +Const GL_MATRIX0_ARB=$88C0 +Const GL_MATRIX1_ARB=$88C1 +Const GL_MATRIX2_ARB=$88C2 +Const GL_MATRIX3_ARB=$88C3 +Const GL_MATRIX4_ARB=$88C4 +Const GL_MATRIX5_ARB=$88C5 +Const GL_MATRIX6_ARB=$88C6 +Const GL_MATRIX7_ARB=$88C7 +Const GL_MATRIX8_ARB=$88C8 +Const GL_MATRIX9_ARB=$88C9 +Const GL_MATRIX10_ARB=$88CA +Const GL_MATRIX11_ARB=$88CB +Const GL_MATRIX12_ARB=$88CC +Const GL_MATRIX13_ARB=$88CD +Const GL_MATRIX14_ARB=$88CE +Const GL_MATRIX15_ARB=$88CF +Const GL_MATRIX16_ARB=$88D0 +Const GL_MATRIX17_ARB=$88D1 +Const GL_MATRIX18_ARB=$88D2 +Const GL_MATRIX19_ARB=$88D3 +Const GL_MATRIX20_ARB=$88D4 +Const GL_MATRIX21_ARB=$88D5 +Const GL_MATRIX22_ARB=$88D6 +Const GL_MATRIX23_ARB=$88D7 +Const GL_MATRIX24_ARB=$88D8 +Const GL_MATRIX25_ARB=$88D9 +Const GL_MATRIX26_ARB=$88DA +Const GL_MATRIX27_ARB=$88DB +Const GL_MATRIX28_ARB=$88DC +Const GL_MATRIX29_ARB=$88DD +Const GL_MATRIX30_ARB=$88DE +Const GL_MATRIX31_ARB=$88DF +Global glBindProgramARB(target_:Int,program_:Int)="__glewBindProgramARB" +Global glDeleteProgramsARB(n_:Int,programs_:Int Ptr)="__glewDeleteProgramsARB" +Global glDisableVertexAttribArrayARB(index_:Int)="__glewDisableVertexAttribArrayARB" +Global glEnableVertexAttribArrayARB(index_:Int)="__glewEnableVertexAttribArrayARB" +Global glGenProgramsARB(n_:Int,programs_:Int Ptr)="__glewGenProgramsARB" +Global glGetProgramEnvParameterdvARB(target_:Int,index_:Int,params_:Double Ptr)="__glewGetProgramEnvParameterdvARB" +Global glGetProgramEnvParameterfvARB(target_:Int,index_:Int,params_:Float Ptr)="__glewGetProgramEnvParameterfvARB" +Global glGetProgramLocalParameterdvARB(target_:Int,index_:Int,params_:Double Ptr)="__glewGetProgramLocalParameterdvARB" +Global glGetProgramLocalParameterfvARB(target_:Int,index_:Int,params_:Float Ptr)="__glewGetProgramLocalParameterfvARB" +Global glGetProgramStringARB(target_:Int,pname_:Int,string_:Byte Ptr)="__glewGetProgramStringARB" +Global glGetProgramivARB(target_:Int,pname_:Int,params_:Int Ptr)="__glewGetProgramivARB" +Global glGetVertexAttribPointervARB(index_:Int,pname_:Int,pointer_:Byte Ptr Ptr)="__glewGetVertexAttribPointervARB" +Global glGetVertexAttribdvARB(index_:Int,pname_:Int,params_:Double Ptr)="__glewGetVertexAttribdvARB" +Global glGetVertexAttribfvARB(index_:Int,pname_:Int,params_:Float Ptr)="__glewGetVertexAttribfvARB" +Global glGetVertexAttribivARB(index_:Int,pname_:Int,params_:Int Ptr)="__glewGetVertexAttribivARB" +Global glIsProgramARB:Byte(program_:Int)="__glewIsProgramARB" +Global glProgramEnvParameter4dARB(target_:Int,index_:Int,x_:Double,y_:Double,z_:Double,w_:Double)="__glewProgramEnvParameter4dARB" +Global glProgramEnvParameter4dvARB(target_:Int,index_:Int,params_:Double Ptr)="__glewProgramEnvParameter4dvARB" +Global glProgramEnvParameter4fARB(target_:Int,index_:Int,x_:Float,y_:Float,z_:Float,w_:Float)="__glewProgramEnvParameter4fARB" +Global glProgramEnvParameter4fvARB(target_:Int,index_:Int,params_:Float Ptr)="__glewProgramEnvParameter4fvARB" +Global glProgramLocalParameter4dARB(target_:Int,index_:Int,x_:Double,y_:Double,z_:Double,w_:Double)="__glewProgramLocalParameter4dARB" +Global glProgramLocalParameter4dvARB(target_:Int,index_:Int,params_:Double Ptr)="__glewProgramLocalParameter4dvARB" +Global glProgramLocalParameter4fARB(target_:Int,index_:Int,x_:Float,y_:Float,z_:Float,w_:Float)="__glewProgramLocalParameter4fARB" +Global glProgramLocalParameter4fvARB(target_:Int,index_:Int,params_:Float Ptr)="__glewProgramLocalParameter4fvARB" +Global glProgramStringARB(target_:Int,format_:Int,len_:Int,string_:Byte Ptr)="__glewProgramStringARB" +Global glVertexAttrib1dARB(index_:Int,x_:Double)="__glewVertexAttrib1dARB" +Global glVertexAttrib1dvARB(index_:Int,v_:Double Ptr)="__glewVertexAttrib1dvARB" +Global glVertexAttrib1fARB(index_:Int,x_:Float)="__glewVertexAttrib1fARB" +Global glVertexAttrib1fvARB(index_:Int,v_:Float Ptr)="__glewVertexAttrib1fvARB" +Global glVertexAttrib1sARB(index_:Int,x_:Short)="__glewVertexAttrib1sARB" +Global glVertexAttrib1svARB(index_:Int,v_:Short Ptr)="__glewVertexAttrib1svARB" +Global glVertexAttrib2dARB(index_:Int,x_:Double,y_:Double)="__glewVertexAttrib2dARB" +Global glVertexAttrib2dvARB(index_:Int,v_:Double Ptr)="__glewVertexAttrib2dvARB" +Global glVertexAttrib2fARB(index_:Int,x_:Float,y_:Float)="__glewVertexAttrib2fARB" +Global glVertexAttrib2fvARB(index_:Int,v_:Float Ptr)="__glewVertexAttrib2fvARB" +Global glVertexAttrib2sARB(index_:Int,x_:Short,y_:Short)="__glewVertexAttrib2sARB" +Global glVertexAttrib2svARB(index_:Int,v_:Short Ptr)="__glewVertexAttrib2svARB" +Global glVertexAttrib3dARB(index_:Int,x_:Double,y_:Double,z_:Double)="__glewVertexAttrib3dARB" +Global glVertexAttrib3dvARB(index_:Int,v_:Double Ptr)="__glewVertexAttrib3dvARB" +Global glVertexAttrib3fARB(index_:Int,x_:Float,y_:Float,z_:Float)="__glewVertexAttrib3fARB" +Global glVertexAttrib3fvARB(index_:Int,v_:Float Ptr)="__glewVertexAttrib3fvARB" +Global glVertexAttrib3sARB(index_:Int,x_:Short,y_:Short,z_:Short)="__glewVertexAttrib3sARB" +Global glVertexAttrib3svARB(index_:Int,v_:Short Ptr)="__glewVertexAttrib3svARB" +Global glVertexAttrib4NbvARB(index_:Int,v_:Byte Ptr)="__glewVertexAttrib4NbvARB" +Global glVertexAttrib4NivARB(index_:Int,v_:Int Ptr)="__glewVertexAttrib4NivARB" +Global glVertexAttrib4NsvARB(index_:Int,v_:Short Ptr)="__glewVertexAttrib4NsvARB" +Global glVertexAttrib4NubARB(index_:Int,x_:Byte,y_:Byte,z_:Byte,w_:Byte)="__glewVertexAttrib4NubARB" +Global glVertexAttrib4NubvARB(index_:Int,v_:Byte Ptr)="__glewVertexAttrib4NubvARB" +Global glVertexAttrib4NuivARB(index_:Int,v_:Int Ptr)="__glewVertexAttrib4NuivARB" +Global glVertexAttrib4NusvARB(index_:Int,v_:Short Ptr)="__glewVertexAttrib4NusvARB" +Global glVertexAttrib4bvARB(index_:Int,v_:Byte Ptr)="__glewVertexAttrib4bvARB" +Global glVertexAttrib4dARB(index_:Int,x_:Double,y_:Double,z_:Double,w_:Double)="__glewVertexAttrib4dARB" +Global glVertexAttrib4dvARB(index_:Int,v_:Double Ptr)="__glewVertexAttrib4dvARB" +Global glVertexAttrib4fARB(index_:Int,x_:Float,y_:Float,z_:Float,w_:Float)="__glewVertexAttrib4fARB" +Global glVertexAttrib4fvARB(index_:Int,v_:Float Ptr)="__glewVertexAttrib4fvARB" +Global glVertexAttrib4ivARB(index_:Int,v_:Int Ptr)="__glewVertexAttrib4ivARB" +Global glVertexAttrib4sARB(index_:Int,x_:Short,y_:Short,z_:Short,w_:Short)="__glewVertexAttrib4sARB" +Global glVertexAttrib4svARB(index_:Int,v_:Short Ptr)="__glewVertexAttrib4svARB" +Global glVertexAttrib4ubvARB(index_:Int,v_:Byte Ptr)="__glewVertexAttrib4ubvARB" +Global glVertexAttrib4uivARB(index_:Int,v_:Int Ptr)="__glewVertexAttrib4uivARB" +Global glVertexAttrib4usvARB(index_:Int,v_:Short Ptr)="__glewVertexAttrib4usvARB" +Global glVertexAttribPointerARB(index_:Int,size_:Int,type_:Int,normalized_:Byte,stride_:Int,pointer_:Byte Ptr)="__glewVertexAttribPointerARB" +Global GL_ARB_vertex_program:Byte="__GLEW_ARB_vertex_program" +Const GL_VERTEX_SHADER_ARB=$8B31 +Const GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB=$8B4A +Const GL_MAX_VARYING_FLOATS_ARB=$8B4B +Const GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB=$8B4C +Const GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB=$8B4D +Const GL_OBJECT_ACTIVE_ATTRIBUTES_ARB=$8B89 +Const GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB=$8B8A +Global glBindAttribLocationARB(programObj_:Int,index_:Int,name_:Byte Ptr)="__glewBindAttribLocationARB" +Global glGetActiveAttribARB(programObj_:Int,index_:Int,maxLength_:Int,length_:Int Ptr,size_:Int Ptr,type_:Int Ptr,name_:Byte Ptr)="__glewGetActiveAttribARB" +Global glGetAttribLocationARB:Int(programObj_:Int,name_:Byte Ptr)="__glewGetAttribLocationARB" +Global GL_ARB_vertex_shader:Byte="__GLEW_ARB_vertex_shader" +Global glWindowPos2dARB(x_:Double,y_:Double)="__glewWindowPos2dARB" +Global glWindowPos2dvARB(p_:Double Ptr)="__glewWindowPos2dvARB" +Global glWindowPos2fARB(x_:Float,y_:Float)="__glewWindowPos2fARB" +Global glWindowPos2fvARB(p_:Float Ptr)="__glewWindowPos2fvARB" +Global glWindowPos2iARB(x_:Int,y_:Int)="__glewWindowPos2iARB" +Global glWindowPos2ivARB(p_:Int Ptr)="__glewWindowPos2ivARB" +Global glWindowPos2sARB(x_:Short,y_:Short)="__glewWindowPos2sARB" +Global glWindowPos2svARB(p_:Short Ptr)="__glewWindowPos2svARB" +Global glWindowPos3dARB(x_:Double,y_:Double,z_:Double)="__glewWindowPos3dARB" +Global glWindowPos3dvARB(p_:Double Ptr)="__glewWindowPos3dvARB" +Global glWindowPos3fARB(x_:Float,y_:Float,z_:Float)="__glewWindowPos3fARB" +Global glWindowPos3fvARB(p_:Float Ptr)="__glewWindowPos3fvARB" +Global glWindowPos3iARB(x_:Int,y_:Int,z_:Int)="__glewWindowPos3iARB" +Global glWindowPos3ivARB(p_:Int Ptr)="__glewWindowPos3ivARB" +Global glWindowPos3sARB(x_:Short,y_:Short,z_:Short)="__glewWindowPos3sARB" +Global glWindowPos3svARB(p_:Short Ptr)="__glewWindowPos3svARB" +Global GL_ARB_window_pos:Byte="__GLEW_ARB_window_pos" +Const GL_TEXTURE_POINT_MODE_ATIX=$60B0 +Const GL_TEXTURE_POINT_ONE_COORD_ATIX=$60B1 +Const GL_TEXTURE_POINT_SPRITE_ATIX=$60B2 +Const GL_POINT_SPRITE_CULL_MODE_ATIX=$60B3 +Const GL_POINT_SPRITE_CULL_CENTER_ATIX=$60B4 +Const GL_POINT_SPRITE_CULL_CLIP_ATIX=$60B5 +Global GL_ATIX_point_sprites:Byte="__GLEW_ATIX_point_sprites" +Const GL_MODULATE_ADD_ATIX=$8744 +Const GL_MODULATE_SIGNED_ADD_ATIX=$8745 +Const GL_MODULATE_SUBTRACT_ATIX=$8746 +Global GL_ATIX_texture_env_combine3:Byte="__GLEW_ATIX_texture_env_combine3" +Const GL_SECONDARY_COLOR_ATIX=$8747 +Const GL_TEXTURE_OUTPUT_RGB_ATIX=$8748 +Const GL_TEXTURE_OUTPUT_ALPHA_ATIX=$8749 +Global GL_ATIX_texture_env_route:Byte="__GLEW_ATIX_texture_env_route" +Const GL_OUTPUT_POINT_SIZE_ATIX=$610E +Global GL_ATIX_vertex_shader_output_point_size:Byte="__GLEW_ATIX_vertex_shader_output_point_size" +Const GL_MAX_DRAW_BUFFERS_ATI=$8824 +Const GL_DRAW_BUFFER0_ATI=$8825 +Const GL_DRAW_BUFFER1_ATI=$8826 +Const GL_DRAW_BUFFER2_ATI=$8827 +Const GL_DRAW_BUFFER3_ATI=$8828 +Const GL_DRAW_BUFFER4_ATI=$8829 +Const GL_DRAW_BUFFER5_ATI=$882A +Const GL_DRAW_BUFFER6_ATI=$882B +Const GL_DRAW_BUFFER7_ATI=$882C +Const GL_DRAW_BUFFER8_ATI=$882D +Const GL_DRAW_BUFFER9_ATI=$882E +Const GL_DRAW_BUFFER10_ATI=$882F +Const GL_DRAW_BUFFER11_ATI=$8830 +Const GL_DRAW_BUFFER12_ATI=$8831 +Const GL_DRAW_BUFFER13_ATI=$8832 +Const GL_DRAW_BUFFER14_ATI=$8833 +Const GL_DRAW_BUFFER15_ATI=$8834 +Global glDrawBuffersATI(n_:Int,bufs_:Int Ptr)="__glewDrawBuffersATI" +Global GL_ATI_draw_buffers:Byte="__GLEW_ATI_draw_buffers" +Const GL_ELEMENT_ARRAY_ATI=$8768 +Const GL_ELEMENT_ARRAY_TYPE_ATI=$8769 +Const GL_ELEMENT_ARRAY_POINTER_ATI=$876A +Global glDrawElementArrayATI(mode_:Int,count_:Int)="__glewDrawElementArrayATI" +Global glDrawRangeElementArrayATI(mode_:Int,start_:Int,end_:Int,count_:Int)="__glewDrawRangeElementArrayATI" +Global glElementPointerATI(type_:Int,pointer_:Byte Ptr)="__glewElementPointerATI" +Global GL_ATI_element_array:Byte="__GLEW_ATI_element_array" +Const GL_BUMP_ROT_MATRIX_ATI=$8775 +Const GL_BUMP_ROT_MATRIX_SIZE_ATI=$8776 +Const GL_BUMP_NUM_TEX_UNITS_ATI=$8777 +Const GL_BUMP_TEX_UNITS_ATI=$8778 +Const GL_DUDV_ATI=$8779 +Const GL_DU8DV8_ATI=$877A +Const GL_BUMP_ENVMAP_ATI=$877B +Const GL_BUMP_TARGET_ATI=$877C +Global glGetTexBumpParameterfvATI(pname_:Int,param_:Float Ptr)="__glewGetTexBumpParameterfvATI" +Global glGetTexBumpParameterivATI(pname_:Int,param_:Int Ptr)="__glewGetTexBumpParameterivATI" +Global glTexBumpParameterfvATI(pname_:Int,param_:Float Ptr)="__glewTexBumpParameterfvATI" +Global glTexBumpParameterivATI(pname_:Int,param_:Int Ptr)="__glewTexBumpParameterivATI" +Global GL_ATI_envmap_bumpmap:Byte="__GLEW_ATI_envmap_bumpmap" +Const GL_RED_BIT_ATI=$00000001 +Const GL_2X_BIT_ATI=$00000001 +Const GL_4X_BIT_ATI=$00000002 +Const GL_GREEN_BIT_ATI=$00000002 +Const GL_COMP_BIT_ATI=$00000002 +Const GL_BLUE_BIT_ATI=$00000004 +Const GL_8X_BIT_ATI=$00000004 +Const GL_NEGATE_BIT_ATI=$00000004 +Const GL_BIAS_BIT_ATI=$00000008 +Const GL_HALF_BIT_ATI=$00000008 +Const GL_QUARTER_BIT_ATI=$00000010 +Const GL_EIGHTH_BIT_ATI=$00000020 +Const GL_SATURATE_BIT_ATI=$00000040 +Const GL_FRAGMENT_SHADER_ATI=$8920 +Const GL_REG_0_ATI=$8921 +Const GL_REG_1_ATI=$8922 +Const GL_REG_2_ATI=$8923 +Const GL_REG_3_ATI=$8924 +Const GL_REG_4_ATI=$8925 +Const GL_REG_5_ATI=$8926 +Const GL_CON_0_ATI=$8941 +Const GL_CON_1_ATI=$8942 +Const GL_CON_2_ATI=$8943 +Const GL_CON_3_ATI=$8944 +Const GL_CON_4_ATI=$8945 +Const GL_CON_5_ATI=$8946 +Const GL_CON_6_ATI=$8947 +Const GL_CON_7_ATI=$8948 +Const GL_MOV_ATI=$8961 +Const GL_ADD_ATI=$8963 +Const GL_MUL_ATI=$8964 +Const GL_SUB_ATI=$8965 +Const GL_DOT3_ATI=$8966 +Const GL_DOT4_ATI=$8967 +Const GL_MAD_ATI=$8968 +Const GL_LERP_ATI=$8969 +Const GL_CND_ATI=$896A +Const GL_CND0_ATI=$896B +Const GL_DOT2_ADD_ATI=$896C +Const GL_SECONDARY_INTERPOLATOR_ATI=$896D +Const GL_NUM_FRAGMENT_REGISTERS_ATI=$896E +Const GL_NUM_FRAGMENT_CONSTANTS_ATI=$896F +Const GL_NUM_PASSES_ATI=$8970 +Const GL_NUM_INSTRUCTIONS_PER_PASS_ATI=$8971 +Const GL_NUM_INSTRUCTIONS_TOTAL_ATI=$8972 +Const GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI=$8973 +Const GL_NUM_LOOPBACK_COMPONENTS_ATI=$8974 +Const GL_COLOR_ALPHA_PAIRING_ATI=$8975 +Const GL_SWIZZLE_STR_ATI=$8976 +Const GL_SWIZZLE_STQ_ATI=$8977 +Const GL_SWIZZLE_STR_DR_ATI=$8978 +Const GL_SWIZZLE_STQ_DQ_ATI=$8979 +Const GL_SWIZZLE_STRQ_ATI=$897A +Const GL_SWIZZLE_STRQ_DQ_ATI=$897B +Global glAlphaFragmentOp1ATI(op_:Int,dst_:Int,dstMod_:Int,arg1_:Int,arg1Rep_:Int,arg1Mod_:Int)="__glewAlphaFragmentOp1ATI" +Global glAlphaFragmentOp2ATI(op_:Int,dst_:Int,dstMod_:Int,arg1_:Int,arg1Rep_:Int,arg1Mod_:Int,arg2_:Int,arg2Rep_:Int,arg2Mod_:Int)="__glewAlphaFragmentOp2ATI" +Global glAlphaFragmentOp3ATI(op_:Int,dst_:Int,dstMod_:Int,arg1_:Int,arg1Rep_:Int,arg1Mod_:Int,arg2_:Int,arg2Rep_:Int,arg2Mod_:Int,arg3_:Int,arg3Rep_:Int,arg3Mod_:Int)="__glewAlphaFragmentOp3ATI" +Global glBeginFragmentShaderATI()="__glewBeginFragmentShaderATI" +Global glBindFragmentShaderATI(id_:Int)="__glewBindFragmentShaderATI" +Global glColorFragmentOp1ATI(op_:Int,dst_:Int,dstMask_:Int,dstMod_:Int,arg1_:Int,arg1Rep_:Int,arg1Mod_:Int)="__glewColorFragmentOp1ATI" +Global glColorFragmentOp2ATI(op_:Int,dst_:Int,dstMask_:Int,dstMod_:Int,arg1_:Int,arg1Rep_:Int,arg1Mod_:Int,arg2_:Int,arg2Rep_:Int,arg2Mod_:Int)="__glewColorFragmentOp2ATI" +Global glColorFragmentOp3ATI(op_:Int,dst_:Int,dstMask_:Int,dstMod_:Int,arg1_:Int,arg1Rep_:Int,arg1Mod_:Int,arg2_:Int,arg2Rep_:Int,arg2Mod_:Int,arg3_:Int,arg3Rep_:Int,arg3Mod_:Int)="__glewColorFragmentOp3ATI" +Global glDeleteFragmentShaderATI(id_:Int)="__glewDeleteFragmentShaderATI" +Global glEndFragmentShaderATI()="__glewEndFragmentShaderATI" +Global glGenFragmentShadersATI:Int(range_:Int)="__glewGenFragmentShadersATI" +Global glPassTexCoordATI(dst_:Int,coord_:Int,swizzle_:Int)="__glewPassTexCoordATI" +Global glSampleMapATI(dst_:Int,interp_:Int,swizzle_:Int)="__glewSampleMapATI" +Global glSetFragmentShaderConstantATI(dst_:Int,value_:Float Ptr)="__glewSetFragmentShaderConstantATI" +Global GL_ATI_fragment_shader:Byte="__GLEW_ATI_fragment_shader" +Global glMapObjectBufferATI:Byte Ptr(buffer_:Int)="__glewMapObjectBufferATI" +Global glUnmapObjectBufferATI(buffer_:Int)="__glewUnmapObjectBufferATI" +Global GL_ATI_map_object_buffer:Byte="__GLEW_ATI_map_object_buffer" +Const GL_PN_TRIANGLES_ATI=$87F0 +Const GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI=$87F1 +Const GL_PN_TRIANGLES_POINT_MODE_ATI=$87F2 +Const GL_PN_TRIANGLES_NORMAL_MODE_ATI=$87F3 +Const GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI=$87F4 +Const GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI=$87F5 +Const GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI=$87F6 +Const GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI=$87F7 +Const GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI=$87F8 +Global GL_ATI_pn_triangles:Byte="__GLEW_ATI_pn_triangles" +Const GL_STENCIL_BACK_FUNC_ATI=$8800 +Const GL_STENCIL_BACK_FAIL_ATI=$8801 +Const GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI=$8802 +Const GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI=$8803 +Global glStencilFuncSeparateATI(frontfunc_:Int,backfunc_:Int,ref_:Int,mask_:Int)="__glewStencilFuncSeparateATI" +Global glStencilOpSeparateATI(face_:Int,sfail_:Int,dpfail_:Int,dppass_:Int)="__glewStencilOpSeparateATI" +Global GL_ATI_separate_stencil:Byte="__GLEW_ATI_separate_stencil" +Global GL_ATI_shader_texture_lod:Byte="__GLEW_ATI_shader_texture_lod" +Const GL_TEXT_FRAGMENT_SHADER_ATI=$8200 +Global GL_ATI_text_fragment_shader:Byte="__GLEW_ATI_text_fragment_shader" +Const GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI=$8837 +Global GL_ATI_texture_compression_3dc:Byte="__GLEW_ATI_texture_compression_3dc" +Const GL_MODULATE_ADD_ATI=$8744 +Const GL_MODULATE_SIGNED_ADD_ATI=$8745 +Const GL_MODULATE_SUBTRACT_ATI=$8746 +Global GL_ATI_texture_env_combine3:Byte="__GLEW_ATI_texture_env_combine3" +Const GL_RGBA_FLOAT32_ATI=$8814 +Const GL_RGB_FLOAT32_ATI=$8815 +Const GL_ALPHA_FLOAT32_ATI=$8816 +Const GL_INTENSITY_FLOAT32_ATI=$8817 +Const GL_LUMINANCE_FLOAT32_ATI=$8818 +Const GL_LUMINANCE_ALPHA_FLOAT32_ATI=$8819 +Const GL_RGBA_FLOAT16_ATI=$881A +Const GL_RGB_FLOAT16_ATI=$881B +Const GL_ALPHA_FLOAT16_ATI=$881C +Const GL_INTENSITY_FLOAT16_ATI=$881D +Const GL_LUMINANCE_FLOAT16_ATI=$881E +Const GL_LUMINANCE_ALPHA_FLOAT16_ATI=$881F +Global GL_ATI_texture_float:Byte="__GLEW_ATI_texture_float" +Const GL_MIRROR_CLAMP_ATI=$8742 +Const GL_MIRROR_CLAMP_TO_EDGE_ATI=$8743 +Global GL_ATI_texture_mirror_once:Byte="__GLEW_ATI_texture_mirror_once" +Const GL_STATIC_ATI=$8760 +Const GL_DYNAMIC_ATI=$8761 +Const GL_PRESERVE_ATI=$8762 +Const GL_DISCARD_ATI=$8763 +Const GL_OBJECT_BUFFER_SIZE_ATI=$8764 +Const GL_OBJECT_BUFFER_USAGE_ATI=$8765 +Const GL_ARRAY_OBJECT_BUFFER_ATI=$8766 +Const GL_ARRAY_OBJECT_OFFSET_ATI=$8767 +Global glArrayObjectATI(array_:Int,size_:Int,type_:Int,stride_:Int,buffer_:Int,offset_:Int)="__glewArrayObjectATI" +Global glFreeObjectBufferATI(buffer_:Int)="__glewFreeObjectBufferATI" +Global glGetArrayObjectfvATI(array_:Int,pname_:Int,params_:Float Ptr)="__glewGetArrayObjectfvATI" +Global glGetArrayObjectivATI(array_:Int,pname_:Int,params_:Int Ptr)="__glewGetArrayObjectivATI" +Global glGetObjectBufferfvATI(buffer_:Int,pname_:Int,params_:Float Ptr)="__glewGetObjectBufferfvATI" +Global glGetObjectBufferivATI(buffer_:Int,pname_:Int,params_:Int Ptr)="__glewGetObjectBufferivATI" +Global glGetVariantArrayObjectfvATI(id_:Int,pname_:Int,params_:Float Ptr)="__glewGetVariantArrayObjectfvATI" +Global glGetVariantArrayObjectivATI(id_:Int,pname_:Int,params_:Int Ptr)="__glewGetVariantArrayObjectivATI" +Global glIsObjectBufferATI:Byte(buffer_:Int)="__glewIsObjectBufferATI" +Global glNewObjectBufferATI:Int(size_:Int,pointer_:Byte Ptr,usage_:Int)="__glewNewObjectBufferATI" +Global glUpdateObjectBufferATI(buffer_:Int,offset_:Int,size_:Int,pointer_:Byte Ptr,preserve_:Int)="__glewUpdateObjectBufferATI" +Global glVariantArrayObjectATI(id_:Int,type_:Int,stride_:Int,buffer_:Int,offset_:Int)="__glewVariantArrayObjectATI" +Global GL_ATI_vertex_array_object:Byte="__GLEW_ATI_vertex_array_object" +Global glGetVertexAttribArrayObjectfvATI(index_:Int,pname_:Int,params_:Float Ptr)="__glewGetVertexAttribArrayObjectfvATI" +Global glGetVertexAttribArrayObjectivATI(index_:Int,pname_:Int,params_:Int Ptr)="__glewGetVertexAttribArrayObjectivATI" +Global glVertexAttribArrayObjectATI(index_:Int,size_:Int,type_:Int,normalized_:Byte,stride_:Int,buffer_:Int,offset_:Int)="__glewVertexAttribArrayObjectATI" +Global GL_ATI_vertex_attrib_array_object:Byte="__GLEW_ATI_vertex_attrib_array_object" +Const GL_MAX_VERTEX_STREAMS_ATI=$876B +Const GL_VERTEX_SOURCE_ATI=$876C +Const GL_VERTEX_STREAM0_ATI=$876D +Const GL_VERTEX_STREAM1_ATI=$876E +Const GL_VERTEX_STREAM2_ATI=$876F +Const GL_VERTEX_STREAM3_ATI=$8770 +Const GL_VERTEX_STREAM4_ATI=$8771 +Const GL_VERTEX_STREAM5_ATI=$8772 +Const GL_VERTEX_STREAM6_ATI=$8773 +Const GL_VERTEX_STREAM7_ATI=$8774 +Global glClientActiveVertexStreamATI(stream_:Int)="__glewClientActiveVertexStreamATI" +Global glNormalStream3bATI(stream_:Int,x_:Byte,y_:Byte,z_:Byte)="__glewNormalStream3bATI" +Global glNormalStream3bvATI(stream_:Int,v_:Byte Ptr)="__glewNormalStream3bvATI" +Global glNormalStream3dATI(stream_:Int,x_:Double,y_:Double,z_:Double)="__glewNormalStream3dATI" +Global glNormalStream3dvATI(stream_:Int,v_:Double Ptr)="__glewNormalStream3dvATI" +Global glNormalStream3fATI(stream_:Int,x_:Float,y_:Float,z_:Float)="__glewNormalStream3fATI" +Global glNormalStream3fvATI(stream_:Int,v_:Float Ptr)="__glewNormalStream3fvATI" +Global glNormalStream3iATI(stream_:Int,x_:Int,y_:Int,z_:Int)="__glewNormalStream3iATI" +Global glNormalStream3ivATI(stream_:Int,v_:Int Ptr)="__glewNormalStream3ivATI" +Global glNormalStream3sATI(stream_:Int,x_:Short,y_:Short,z_:Short)="__glewNormalStream3sATI" +Global glNormalStream3svATI(stream_:Int,v_:Short Ptr)="__glewNormalStream3svATI" +Global glVertexBlendEnvfATI(pname_:Int,param_:Float)="__glewVertexBlendEnvfATI" +Global glVertexBlendEnviATI(pname_:Int,param_:Int)="__glewVertexBlendEnviATI" +Global glVertexStream2dATI(stream_:Int,x_:Double,y_:Double)="__glewVertexStream2dATI" +Global glVertexStream2dvATI(stream_:Int,v_:Double Ptr)="__glewVertexStream2dvATI" +Global glVertexStream2fATI(stream_:Int,x_:Float,y_:Float)="__glewVertexStream2fATI" +Global glVertexStream2fvATI(stream_:Int,v_:Float Ptr)="__glewVertexStream2fvATI" +Global glVertexStream2iATI(stream_:Int,x_:Int,y_:Int)="__glewVertexStream2iATI" +Global glVertexStream2ivATI(stream_:Int,v_:Int Ptr)="__glewVertexStream2ivATI" +Global glVertexStream2sATI(stream_:Int,x_:Short,y_:Short)="__glewVertexStream2sATI" +Global glVertexStream2svATI(stream_:Int,v_:Short Ptr)="__glewVertexStream2svATI" +Global glVertexStream3dATI(stream_:Int,x_:Double,y_:Double,z_:Double)="__glewVertexStream3dATI" +Global glVertexStream3dvATI(stream_:Int,v_:Double Ptr)="__glewVertexStream3dvATI" +Global glVertexStream3fATI(stream_:Int,x_:Float,y_:Float,z_:Float)="__glewVertexStream3fATI" +Global glVertexStream3fvATI(stream_:Int,v_:Float Ptr)="__glewVertexStream3fvATI" +Global glVertexStream3iATI(stream_:Int,x_:Int,y_:Int,z_:Int)="__glewVertexStream3iATI" +Global glVertexStream3ivATI(stream_:Int,v_:Int Ptr)="__glewVertexStream3ivATI" +Global glVertexStream3sATI(stream_:Int,x_:Short,y_:Short,z_:Short)="__glewVertexStream3sATI" +Global glVertexStream3svATI(stream_:Int,v_:Short Ptr)="__glewVertexStream3svATI" +Global glVertexStream4dATI(stream_:Int,x_:Double,y_:Double,z_:Double,w_:Double)="__glewVertexStream4dATI" +Global glVertexStream4dvATI(stream_:Int,v_:Double Ptr)="__glewVertexStream4dvATI" +Global glVertexStream4fATI(stream_:Int,x_:Float,y_:Float,z_:Float,w_:Float)="__glewVertexStream4fATI" +Global glVertexStream4fvATI(stream_:Int,v_:Float Ptr)="__glewVertexStream4fvATI" +Global glVertexStream4iATI(stream_:Int,x_:Int,y_:Int,z_:Int,w_:Int)="__glewVertexStream4iATI" +Global glVertexStream4ivATI(stream_:Int,v_:Int Ptr)="__glewVertexStream4ivATI" +Global glVertexStream4sATI(stream_:Int,x_:Short,y_:Short,z_:Short,w_:Short)="__glewVertexStream4sATI" +Global glVertexStream4svATI(stream_:Int,v_:Short Ptr)="__glewVertexStream4svATI" +Global GL_ATI_vertex_streams:Byte="__GLEW_ATI_vertex_streams" +Const GL_422_EXT=$80CC +Const GL_422_REV_EXT=$80CD +Const GL_422_AVERAGE_EXT=$80CE +Const GL_422_REV_AVERAGE_EXT=$80CF +Global GL_EXT_422_pixels:Byte="__GLEW_EXT_422_pixels" +Const GL_CG_VERTEX_SHADER_EXT=$890E +Const GL_CG_FRAGMENT_SHADER_EXT=$890F +Global GL_EXT_Cg_shader:Byte="__GLEW_EXT_Cg_shader" +Const GL_ABGR_EXT=$8000 +Global GL_EXT_abgr:Byte="__GLEW_EXT_abgr" +Const GL_BGR_EXT=$80E0 +Const GL_BGRA_EXT=$80E1 +Global GL_EXT_bgra:Byte="__GLEW_EXT_bgra" +Const GL_MAX_VERTEX_BINDABLE_UNIFORMS_EXT=$8DE2 +Const GL_MAX_FRAGMENT_BINDABLE_UNIFORMS_EXT=$8DE3 +Const GL_MAX_GEOMETRY_BINDABLE_UNIFORMS_EXT=$8DE4 +Const GL_MAX_BINDABLE_UNIFORM_SIZE_EXT=$8DED +Const GL_UNIFORM_BUFFER_EXT=$8DEE +Const GL_UNIFORM_BUFFER_BINDING_EXT=$8DEF +Global glGetUniformBufferSizeEXT:Int(program_:Int,location_:Int)="__glewGetUniformBufferSizeEXT" +Global glGetUniformOffsetEXT:Int(program_:Int,location_:Int)="__glewGetUniformOffsetEXT" +Global glUniformBufferEXT(program_:Int,location_:Int,buffer_:Int)="__glewUniformBufferEXT" +Global GL_EXT_bindable_uniform:Byte="__GLEW_EXT_bindable_uniform" +Const GL_CONSTANT_COLOR_EXT=$8001 +Const GL_ONE_MINUS_CONSTANT_COLOR_EXT=$8002 +Const GL_CONSTANT_ALPHA_EXT=$8003 +Const GL_ONE_MINUS_CONSTANT_ALPHA_EXT=$8004 +Const GL_BLEND_COLOR_EXT=$8005 +Global glBlendColorEXT(red_:Float,green_:Float,blue_:Float,alpha_:Float)="__glewBlendColorEXT" +Global GL_EXT_blend_color:Byte="__GLEW_EXT_blend_color" +Const GL_BLEND_EQUATION_RGB_EXT=$8009 +Const GL_BLEND_EQUATION_ALPHA_EXT=$883D +Global glBlendEquationSeparateEXT(modeRGB_:Int,modeAlpha_:Int)="__glewBlendEquationSeparateEXT" +Global GL_EXT_blend_equation_separate:Byte="__GLEW_EXT_blend_equation_separate" +Const GL_BLEND_DST_RGB_EXT=$80C8 +Const GL_BLEND_SRC_RGB_EXT=$80C9 +Const GL_BLEND_DST_ALPHA_EXT=$80CA +Const GL_BLEND_SRC_ALPHA_EXT=$80CB +Global glBlendFuncSeparateEXT(sfactorRGB_:Int,dfactorRGB_:Int,sfactorAlpha_:Int,dfactorAlpha_:Int)="__glewBlendFuncSeparateEXT" +Global GL_EXT_blend_func_separate:Byte="__GLEW_EXT_blend_func_separate" +Global GL_EXT_blend_logic_op:Byte="__GLEW_EXT_blend_logic_op" +Const GL_FUNC_ADD_EXT=$8006 +Const GL_MIN_EXT=$8007 +Const GL_MAX_EXT=$8008 +Const GL_BLEND_EQUATION_EXT=$8009 +Global glBlendEquationEXT(mode_:Int)="__glewBlendEquationEXT" +Global GL_EXT_blend_minmax:Byte="__GLEW_EXT_blend_minmax" +Const GL_FUNC_SUBTRACT_EXT=$800A +Const GL_FUNC_REVERSE_SUBTRACT_EXT=$800B +Global GL_EXT_blend_subtract:Byte="__GLEW_EXT_blend_subtract" +Const GL_CLIP_VOLUME_CLIPPING_HINT_EXT=$80F0 +Global GL_EXT_clip_volume_hint:Byte="__GLEW_EXT_clip_volume_hint" +Const GL_CMYK_EXT=$800C +Const GL_CMYKA_EXT=$800D +Const GL_PACK_CMYK_HINT_EXT=$800E +Const GL_UNPACK_CMYK_HINT_EXT=$800F +Global GL_EXT_cmyka:Byte="__GLEW_EXT_cmyka" +Global glColorSubTableEXT(target_:Int,start_:Int,count_:Int,format_:Int,type_:Int,data_:Byte Ptr)="__glewColorSubTableEXT" +Global glCopyColorSubTableEXT(target_:Int,start_:Int,x_:Int,y_:Int,width_:Int)="__glewCopyColorSubTableEXT" +Global GL_EXT_color_subtable:Byte="__GLEW_EXT_color_subtable" +Const GL_ARRAY_ELEMENT_LOCK_FIRST_EXT=$81A8 +Const GL_ARRAY_ELEMENT_LOCK_COUNT_EXT=$81A9 +Global glLockArraysEXT(first_:Int,count_:Int)="__glewLockArraysEXT" +Global glUnlockArraysEXT()="__glewUnlockArraysEXT" +Global GL_EXT_compiled_vertex_array:Byte="__GLEW_EXT_compiled_vertex_array" +Const GL_CONVOLUTION_1D_EXT=$8010 +Const GL_CONVOLUTION_2D_EXT=$8011 +Const GL_SEPARABLE_2D_EXT=$8012 +Const GL_CONVOLUTION_BORDER_MODE_EXT=$8013 +Const GL_CONVOLUTION_FILTER_SCALE_EXT=$8014 +Const GL_CONVOLUTION_FILTER_BIAS_EXT=$8015 +Const GL_REDUCE_EXT=$8016 +Const GL_CONVOLUTION_FORMAT_EXT=$8017 +Const GL_CONVOLUTION_WIDTH_EXT=$8018 +Const GL_CONVOLUTION_HEIGHT_EXT=$8019 +Const GL_MAX_CONVOLUTION_WIDTH_EXT=$801A +Const GL_MAX_CONVOLUTION_HEIGHT_EXT=$801B +Const GL_POST_CONVOLUTION_RED_SCALE_EXT=$801C +Const GL_POST_CONVOLUTION_GREEN_SCALE_EXT=$801D +Const GL_POST_CONVOLUTION_BLUE_SCALE_EXT=$801E +Const GL_POST_CONVOLUTION_ALPHA_SCALE_EXT=$801F +Const GL_POST_CONVOLUTION_RED_BIAS_EXT=$8020 +Const GL_POST_CONVOLUTION_GREEN_BIAS_EXT=$8021 +Const GL_POST_CONVOLUTION_BLUE_BIAS_EXT=$8022 +Const GL_POST_CONVOLUTION_ALPHA_BIAS_EXT=$8023 +Global glConvolutionFilter1DEXT(target_:Int,internalformat_:Int,width_:Int,format_:Int,type_:Int,image_:Byte Ptr)="__glewConvolutionFilter1DEXT" +Global glConvolutionFilter2DEXT(target_:Int,internalformat_:Int,width_:Int,height_:Int,format_:Int,type_:Int,image_:Byte Ptr)="__glewConvolutionFilter2DEXT" +Global glConvolutionParameterfEXT(target_:Int,pname_:Int,param_:Float)="__glewConvolutionParameterfEXT" +Global glConvolutionParameterfvEXT(target_:Int,pname_:Int,params_:Float Ptr)="__glewConvolutionParameterfvEXT" +Global glConvolutionParameteriEXT(target_:Int,pname_:Int,param_:Int)="__glewConvolutionParameteriEXT" +Global glConvolutionParameterivEXT(target_:Int,pname_:Int,params_:Int Ptr)="__glewConvolutionParameterivEXT" +Global glCopyConvolutionFilter1DEXT(target_:Int,internalformat_:Int,x_:Int,y_:Int,width_:Int)="__glewCopyConvolutionFilter1DEXT" +Global glCopyConvolutionFilter2DEXT(target_:Int,internalformat_:Int,x_:Int,y_:Int,width_:Int,height_:Int)="__glewCopyConvolutionFilter2DEXT" +Global glGetConvolutionFilterEXT(target_:Int,format_:Int,type_:Int,image_:Byte Ptr)="__glewGetConvolutionFilterEXT" +Global glGetConvolutionParameterfvEXT(target_:Int,pname_:Int,params_:Float Ptr)="__glewGetConvolutionParameterfvEXT" +Global glGetConvolutionParameterivEXT(target_:Int,pname_:Int,params_:Int Ptr)="__glewGetConvolutionParameterivEXT" +Global glGetSeparableFilterEXT(target_:Int,format_:Int,type_:Int,row_:Byte Ptr,column_:Byte Ptr,span_:Byte Ptr)="__glewGetSeparableFilterEXT" +Global glSeparableFilter2DEXT(target_:Int,internalformat_:Int,width_:Int,height_:Int,format_:Int,type_:Int,row_:Byte Ptr,column_:Byte Ptr)="__glewSeparableFilter2DEXT" +Global GL_EXT_convolution:Byte="__GLEW_EXT_convolution" +Const GL_TANGENT_ARRAY_EXT=$8439 +Const GL_BINORMAL_ARRAY_EXT=$843A +Const GL_CURRENT_TANGENT_EXT=$843B +Const GL_CURRENT_BINORMAL_EXT=$843C +Const GL_TANGENT_ARRAY_TYPE_EXT=$843E +Const GL_TANGENT_ARRAY_STRIDE_EXT=$843F +Const GL_BINORMAL_ARRAY_TYPE_EXT=$8440 +Const GL_BINORMAL_ARRAY_STRIDE_EXT=$8441 +Const GL_TANGENT_ARRAY_POINTER_EXT=$8442 +Const GL_BINORMAL_ARRAY_POINTER_EXT=$8443 +Const GL_MAP1_TANGENT_EXT=$8444 +Const GL_MAP2_TANGENT_EXT=$8445 +Const GL_MAP1_BINORMAL_EXT=$8446 +Const GL_MAP2_BINORMAL_EXT=$8447 +Global glBinormalPointerEXT(type_:Int,stride_:Int,pointer_:Byte Ptr)="__glewBinormalPointerEXT" +Global glTangentPointerEXT(type_:Int,stride_:Int,pointer_:Byte Ptr)="__glewTangentPointerEXT" +Global GL_EXT_coordinate_frame:Byte="__GLEW_EXT_coordinate_frame" +Global glCopyTexImage1DEXT(target_:Int,level_:Int,internalformat_:Int,x_:Int,y_:Int,width_:Int,border_:Int)="__glewCopyTexImage1DEXT" +Global glCopyTexImage2DEXT(target_:Int,level_:Int,internalformat_:Int,x_:Int,y_:Int,width_:Int,height_:Int,border_:Int)="__glewCopyTexImage2DEXT" +Global glCopyTexSubImage1DEXT(target_:Int,level_:Int,xoffset_:Int,x_:Int,y_:Int,width_:Int)="__glewCopyTexSubImage1DEXT" +Global glCopyTexSubImage2DEXT(target_:Int,level_:Int,xoffset_:Int,yoffset_:Int,x_:Int,y_:Int,width_:Int,height_:Int)="__glewCopyTexSubImage2DEXT" +Global glCopyTexSubImage3DEXT(target_:Int,level_:Int,xoffset_:Int,yoffset_:Int,zoffset_:Int,x_:Int,y_:Int,width_:Int,height_:Int)="__glewCopyTexSubImage3DEXT" +Global GL_EXT_copy_texture:Byte="__GLEW_EXT_copy_texture" +Global glCullParameterdvEXT(pname_:Int,params_:Double Ptr)="__glewCullParameterdvEXT" +Global glCullParameterfvEXT(pname_:Int,params_:Float Ptr)="__glewCullParameterfvEXT" +Global GL_EXT_cull_vertex:Byte="__GLEW_EXT_cull_vertex" +Const GL_DEPTH_BOUNDS_TEST_EXT=$8890 +Const GL_DEPTH_BOUNDS_EXT=$8891 +Global glDepthBoundsEXT(zmin_:Double,zmax_:Double)="__glewDepthBoundsEXT" +Global GL_EXT_depth_bounds_test:Byte="__GLEW_EXT_depth_bounds_test" +Const GL_PROGRAM_MATRIX_EXT=$8E2D +Const GL_TRANSPOSE_PROGRAM_MATRIX_EXT=$8E2E +Const GL_PROGRAM_MATRIX_STACK_DEPTH_EXT=$8E2F +Global glBindMultiTextureEXT(texunit_:Int,target_:Int,texture_:Int)="__glewBindMultiTextureEXT" +Global glCheckNamedFramebufferStatusEXT:Int(framebuffer_:Int,target_:Int)="__glewCheckNamedFramebufferStatusEXT" +Global glClientAttribDefaultEXT(mask_:Int)="__glewClientAttribDefaultEXT" +Global glCompressedMultiTexImage1DEXT(texunit_:Int,target_:Int,level_:Int,internalformat_:Int,width_:Int,border_:Int,imageSize_:Int,data_:Byte Ptr)="__glewCompressedMultiTexImage1DEXT" +Global glCompressedMultiTexImage2DEXT(texunit_:Int,target_:Int,level_:Int,internalformat_:Int,width_:Int,height_:Int,border_:Int,imageSize_:Int,data_:Byte Ptr)="__glewCompressedMultiTexImage2DEXT" +Global glCompressedMultiTexImage3DEXT(texunit_:Int,target_:Int,level_:Int,internalformat_:Int,width_:Int,height_:Int,depth_:Int,border_:Int,imageSize_:Int,data_:Byte Ptr)="__glewCompressedMultiTexImage3DEXT" +Global glCompressedMultiTexSubImage1DEXT(texunit_:Int,target_:Int,level_:Int,xoffset_:Int,width_:Int,format_:Int,imageSize_:Int,data_:Byte Ptr)="__glewCompressedMultiTexSubImage1DEXT" +Global glCompressedMultiTexSubImage2DEXT(texunit_:Int,target_:Int,level_:Int,xoffset_:Int,yoffset_:Int,width_:Int,height_:Int,format_:Int,imageSize_:Int,data_:Byte Ptr)="__glewCompressedMultiTexSubImage2DEXT" +Global glCompressedMultiTexSubImage3DEXT(texunit_:Int,target_:Int,level_:Int,xoffset_:Int,yoffset_:Int,zoffset_:Int,width_:Int,height_:Int,depth_:Int,format_:Int,imageSize_:Int,data_:Byte Ptr)="__glewCompressedMultiTexSubImage3DEXT" +Global glCompressedTextureImage1DEXT(texture_:Int,target_:Int,level_:Int,internalformat_:Int,width_:Int,border_:Int,imageSize_:Int,data_:Byte Ptr)="__glewCompressedTextureImage1DEXT" +Global glCompressedTextureImage2DEXT(texture_:Int,target_:Int,level_:Int,internalformat_:Int,width_:Int,height_:Int,border_:Int,imageSize_:Int,data_:Byte Ptr)="__glewCompressedTextureImage2DEXT" +Global glCompressedTextureImage3DEXT(texture_:Int,target_:Int,level_:Int,internalformat_:Int,width_:Int,height_:Int,depth_:Int,border_:Int,imageSize_:Int,data_:Byte Ptr)="__glewCompressedTextureImage3DEXT" +Global glCompressedTextureSubImage1DEXT(texture_:Int,target_:Int,level_:Int,xoffset_:Int,width_:Int,format_:Int,imageSize_:Int,data_:Byte Ptr)="__glewCompressedTextureSubImage1DEXT" +Global glCompressedTextureSubImage2DEXT(texture_:Int,target_:Int,level_:Int,xoffset_:Int,yoffset_:Int,width_:Int,height_:Int,format_:Int,imageSize_:Int,data_:Byte Ptr)="__glewCompressedTextureSubImage2DEXT" +Global glCompressedTextureSubImage3DEXT(texture_:Int,target_:Int,level_:Int,xoffset_:Int,yoffset_:Int,zoffset_:Int,width_:Int,height_:Int,depth_:Int,format_:Int,imageSize_:Int,data_:Byte Ptr)="__glewCompressedTextureSubImage3DEXT" +Global glCopyMultiTexImage1DEXT(texunit_:Int,target_:Int,level_:Int,internalformat_:Int,x_:Int,y_:Int,width_:Int,border_:Int)="__glewCopyMultiTexImage1DEXT" +Global glCopyMultiTexImage2DEXT(texunit_:Int,target_:Int,level_:Int,internalformat_:Int,x_:Int,y_:Int,width_:Int,height_:Int,border_:Int)="__glewCopyMultiTexImage2DEXT" +Global glCopyMultiTexSubImage1DEXT(texunit_:Int,target_:Int,level_:Int,xoffset_:Int,x_:Int,y_:Int,width_:Int)="__glewCopyMultiTexSubImage1DEXT" +Global glCopyMultiTexSubImage2DEXT(texunit_:Int,target_:Int,level_:Int,xoffset_:Int,yoffset_:Int,x_:Int,y_:Int,width_:Int,height_:Int)="__glewCopyMultiTexSubImage2DEXT" +Global glCopyMultiTexSubImage3DEXT(texunit_:Int,target_:Int,level_:Int,xoffset_:Int,yoffset_:Int,zoffset_:Int,x_:Int,y_:Int,width_:Int,height_:Int)="__glewCopyMultiTexSubImage3DEXT" +Global glCopyTextureImage1DEXT(texture_:Int,target_:Int,level_:Int,internalformat_:Int,x_:Int,y_:Int,width_:Int,border_:Int)="__glewCopyTextureImage1DEXT" +Global glCopyTextureImage2DEXT(texture_:Int,target_:Int,level_:Int,internalformat_:Int,x_:Int,y_:Int,width_:Int,height_:Int,border_:Int)="__glewCopyTextureImage2DEXT" +Global glCopyTextureSubImage1DEXT(texture_:Int,target_:Int,level_:Int,xoffset_:Int,x_:Int,y_:Int,width_:Int)="__glewCopyTextureSubImage1DEXT" +Global glCopyTextureSubImage2DEXT(texture_:Int,target_:Int,level_:Int,xoffset_:Int,yoffset_:Int,x_:Int,y_:Int,width_:Int,height_:Int)="__glewCopyTextureSubImage2DEXT" +Global glCopyTextureSubImage3DEXT(texture_:Int,target_:Int,level_:Int,xoffset_:Int,yoffset_:Int,zoffset_:Int,x_:Int,y_:Int,width_:Int,height_:Int)="__glewCopyTextureSubImage3DEXT" +Global glDisableClientStateIndexedEXT(array_:Int,index_:Int)="__glewDisableClientStateIndexedEXT" +Global glEnableClientStateIndexedEXT(array_:Int,index_:Int)="__glewEnableClientStateIndexedEXT" +Global glFramebufferDrawBufferEXT(framebuffer_:Int,mode_:Int)="__glewFramebufferDrawBufferEXT" +Global glFramebufferDrawBuffersEXT(framebuffer_:Int,n_:Int,bufs_:Int Ptr)="__glewFramebufferDrawBuffersEXT" +Global glFramebufferReadBufferEXT(framebuffer_:Int,mode_:Int)="__glewFramebufferReadBufferEXT" +Global glGenerateMultiTexMipmapEXT(texunit_:Int,target_:Int)="__glewGenerateMultiTexMipmapEXT" +Global glGenerateTextureMipmapEXT(texture_:Int,target_:Int)="__glewGenerateTextureMipmapEXT" +Global glGetCompressedMultiTexImageEXT(texunit_:Int,target_:Int,level_:Int,img_:Byte Ptr)="__glewGetCompressedMultiTexImageEXT" +Global glGetCompressedTextureImageEXT(texture_:Int,target_:Int,level_:Int,img_:Byte Ptr)="__glewGetCompressedTextureImageEXT" +Global glGetDoubleIndexedvEXT(pname_:Int,index_:Int,params_:Double Ptr)="__glewGetDoubleIndexedvEXT" +Global glGetFloatIndexedvEXT(pname_:Int,index_:Int,params_:Float Ptr)="__glewGetFloatIndexedvEXT" +Global glGetFramebufferParameterivEXT(framebuffer_:Int,pname_:Int,param_:Int Ptr)="__glewGetFramebufferParameterivEXT" +Global glGetMultiTexEnvfvEXT(texunit_:Int,target_:Int,pname_:Int,params_:Float Ptr)="__glewGetMultiTexEnvfvEXT" +Global glGetMultiTexEnvivEXT(texunit_:Int,target_:Int,pname_:Int,params_:Int Ptr)="__glewGetMultiTexEnvivEXT" +Global glGetMultiTexGendvEXT(texunit_:Int,coord_:Int,pname_:Int,params_:Double Ptr)="__glewGetMultiTexGendvEXT" +Global glGetMultiTexGenfvEXT(texunit_:Int,coord_:Int,pname_:Int,params_:Float Ptr)="__glewGetMultiTexGenfvEXT" +Global glGetMultiTexGenivEXT(texunit_:Int,coord_:Int,pname_:Int,params_:Int Ptr)="__glewGetMultiTexGenivEXT" +Global glGetMultiTexImageEXT(texunit_:Int,target_:Int,level_:Int,format_:Int,type_:Int,pixels_:Byte Ptr)="__glewGetMultiTexImageEXT" +Global glGetMultiTexLevelParameterfvEXT(texunit_:Int,target_:Int,level_:Int,pname_:Int,params_:Float Ptr)="__glewGetMultiTexLevelParameterfvEXT" +Global glGetMultiTexLevelParameterivEXT(texunit_:Int,target_:Int,level_:Int,pname_:Int,params_:Int Ptr)="__glewGetMultiTexLevelParameterivEXT" +Global glGetMultiTexParameterIivEXT(texunit_:Int,target_:Int,pname_:Int,params_:Int Ptr)="__glewGetMultiTexParameterIivEXT" +Global glGetMultiTexParameterIuivEXT(texunit_:Int,target_:Int,pname_:Int,params_:Int Ptr)="__glewGetMultiTexParameterIuivEXT" +Global glGetMultiTexParameterfvEXT(texunit_:Int,target_:Int,pname_:Int,params_:Float Ptr)="__glewGetMultiTexParameterfvEXT" +Global glGetMultiTexParameterivEXT(texunit_:Int,target_:Int,pname_:Int,params_:Int Ptr)="__glewGetMultiTexParameterivEXT" +Global glGetNamedBufferParameterivEXT(buffer_:Int,pname_:Int,params_:Int Ptr)="__glewGetNamedBufferParameterivEXT" +Global glGetNamedBufferPointervEXT(buffer_:Int,pname_:Int,params_:Byte Ptr Ptr)="__glewGetNamedBufferPointervEXT" +Global glGetNamedBufferSubDataEXT(buffer_:Int,offset_:Int,size_:Int,data_:Byte Ptr)="__glewGetNamedBufferSubDataEXT" +Global glGetNamedFramebufferAttachmentParameterivEXT(framebuffer_:Int,attachment_:Int,pname_:Int,params_:Int Ptr)="__glewGetNamedFramebufferAttachmentParameterivEXT" +Global glGetNamedProgramLocalParameterIivEXT(program_:Int,target_:Int,index_:Int,params_:Int Ptr)="__glewGetNamedProgramLocalParameterIivEXT" +Global glGetNamedProgramLocalParameterIuivEXT(program_:Int,target_:Int,index_:Int,params_:Int Ptr)="__glewGetNamedProgramLocalParameterIuivEXT" +Global glGetNamedProgramLocalParameterdvEXT(program_:Int,target_:Int,index_:Int,params_:Double Ptr)="__glewGetNamedProgramLocalParameterdvEXT" +Global glGetNamedProgramLocalParameterfvEXT(program_:Int,target_:Int,index_:Int,params_:Float Ptr)="__glewGetNamedProgramLocalParameterfvEXT" +Global glGetNamedProgramStringEXT(program_:Int,target_:Int,pname_:Int,string_:Byte Ptr)="__glewGetNamedProgramStringEXT" +Global glGetNamedProgramivEXT(program_:Int,target_:Int,pname_:Int,params_:Int Ptr)="__glewGetNamedProgramivEXT" +Global glGetNamedRenderbufferParameterivEXT(renderbuffer_:Int,pname_:Int,params_:Int Ptr)="__glewGetNamedRenderbufferParameterivEXT" +Global glGetPointerIndexedvEXT(pname_:Int,index_:Int,params_:Byte Ptr Ptr)="__glewGetPointerIndexedvEXT" +Global glGetTextureImageEXT(texture_:Int,target_:Int,level_:Int,format_:Int,type_:Int,pixels_:Byte Ptr)="__glewGetTextureImageEXT" +Global glGetTextureLevelParameterfvEXT(texture_:Int,target_:Int,level_:Int,pname_:Int,params_:Float Ptr)="__glewGetTextureLevelParameterfvEXT" +Global glGetTextureLevelParameterivEXT(texture_:Int,target_:Int,level_:Int,pname_:Int,params_:Int Ptr)="__glewGetTextureLevelParameterivEXT" +Global glGetTextureParameterIivEXT(texture_:Int,target_:Int,pname_:Int,params_:Int Ptr)="__glewGetTextureParameterIivEXT" +Global glGetTextureParameterIuivEXT(texture_:Int,target_:Int,pname_:Int,params_:Int Ptr)="__glewGetTextureParameterIuivEXT" +Global glGetTextureParameterfvEXT(texture_:Int,target_:Int,pname_:Int,params_:Float Ptr)="__glewGetTextureParameterfvEXT" +Global glGetTextureParameterivEXT(texture_:Int,target_:Int,pname_:Int,params_:Int Ptr)="__glewGetTextureParameterivEXT" +Global glMapNamedBufferEXT:Byte Ptr(buffer_:Int,access_:Int)="__glewMapNamedBufferEXT" +Global glMatrixFrustumEXT(matrixMode_:Int,l_:Double,r_:Double,b_:Double,t_:Double,n_:Double,f_:Double)="__glewMatrixFrustumEXT" +Global glMatrixLoadIdentityEXT(matrixMode_:Int)="__glewMatrixLoadIdentityEXT" +Global glMatrixLoadTransposedEXT(matrixMode_:Int,m_:Double Ptr)="__glewMatrixLoadTransposedEXT" +Global glMatrixLoadTransposefEXT(matrixMode_:Int,m_:Float Ptr)="__glewMatrixLoadTransposefEXT" +Global glMatrixLoaddEXT(matrixMode_:Int,m_:Double Ptr)="__glewMatrixLoaddEXT" +Global glMatrixLoadfEXT(matrixMode_:Int,m_:Float Ptr)="__glewMatrixLoadfEXT" +Global glMatrixMultTransposedEXT(matrixMode_:Int,m_:Double Ptr)="__glewMatrixMultTransposedEXT" +Global glMatrixMultTransposefEXT(matrixMode_:Int,m_:Float Ptr)="__glewMatrixMultTransposefEXT" +Global glMatrixMultdEXT(matrixMode_:Int,m_:Double Ptr)="__glewMatrixMultdEXT" +Global glMatrixMultfEXT(matrixMode_:Int,m_:Float Ptr)="__glewMatrixMultfEXT" +Global glMatrixOrthoEXT(matrixMode_:Int,l_:Double,r_:Double,b_:Double,t_:Double,n_:Double,f_:Double)="__glewMatrixOrthoEXT" +Global glMatrixPopEXT(matrixMode_:Int)="__glewMatrixPopEXT" +Global glMatrixPushEXT(matrixMode_:Int)="__glewMatrixPushEXT" +Global glMatrixRotatedEXT(matrixMode_:Int,angle_:Double,x_:Double,y_:Double,z_:Double)="__glewMatrixRotatedEXT" +Global glMatrixRotatefEXT(matrixMode_:Int,angle_:Float,x_:Float,y_:Float,z_:Float)="__glewMatrixRotatefEXT" +Global glMatrixScaledEXT(matrixMode_:Int,x_:Double,y_:Double,z_:Double)="__glewMatrixScaledEXT" +Global glMatrixScalefEXT(matrixMode_:Int,x_:Float,y_:Float,z_:Float)="__glewMatrixScalefEXT" +Global glMatrixTranslatedEXT(matrixMode_:Int,x_:Double,y_:Double,z_:Double)="__glewMatrixTranslatedEXT" +Global glMatrixTranslatefEXT(matrixMode_:Int,x_:Float,y_:Float,z_:Float)="__glewMatrixTranslatefEXT" +Global glMultiTexBufferEXT(texunit_:Int,target_:Int,internalformat_:Int,buffer_:Int)="__glewMultiTexBufferEXT" +Global glMultiTexCoordPointerEXT(texunit_:Int,size_:Int,type_:Int,stride_:Int,pointer_:Byte Ptr)="__glewMultiTexCoordPointerEXT" +Global glMultiTexEnvfEXT(texunit_:Int,target_:Int,pname_:Int,param_:Float)="__glewMultiTexEnvfEXT" +Global glMultiTexEnvfvEXT(texunit_:Int,target_:Int,pname_:Int,params_:Float Ptr)="__glewMultiTexEnvfvEXT" +Global glMultiTexEnviEXT(texunit_:Int,target_:Int,pname_:Int,param_:Int)="__glewMultiTexEnviEXT" +Global glMultiTexEnvivEXT(texunit_:Int,target_:Int,pname_:Int,params_:Int Ptr)="__glewMultiTexEnvivEXT" +Global glMultiTexGendEXT(texunit_:Int,coord_:Int,pname_:Int,param_:Double)="__glewMultiTexGendEXT" +Global glMultiTexGendvEXT(texunit_:Int,coord_:Int,pname_:Int,params_:Double Ptr)="__glewMultiTexGendvEXT" +Global glMultiTexGenfEXT(texunit_:Int,coord_:Int,pname_:Int,param_:Float)="__glewMultiTexGenfEXT" +Global glMultiTexGenfvEXT(texunit_:Int,coord_:Int,pname_:Int,params_:Float Ptr)="__glewMultiTexGenfvEXT" +Global glMultiTexGeniEXT(texunit_:Int,coord_:Int,pname_:Int,param_:Int)="__glewMultiTexGeniEXT" +Global glMultiTexGenivEXT(texunit_:Int,coord_:Int,pname_:Int,params_:Int Ptr)="__glewMultiTexGenivEXT" +Global glMultiTexImage1DEXT(texunit_:Int,target_:Int,level_:Int,internalformat_:Int,width_:Int,border_:Int,format_:Int,type_:Int,pixels_:Byte Ptr)="__glewMultiTexImage1DEXT" +Global glMultiTexImage2DEXT(texunit_:Int,target_:Int,level_:Int,internalformat_:Int,width_:Int,height_:Int,border_:Int,format_:Int,type_:Int,pixels_:Byte Ptr)="__glewMultiTexImage2DEXT" +Global glMultiTexImage3DEXT(texunit_:Int,target_:Int,level_:Int,internalformat_:Int,width_:Int,height_:Int,depth_:Int,border_:Int,format_:Int,type_:Int,pixels_:Byte Ptr)="__glewMultiTexImage3DEXT" +Global glMultiTexParameterIivEXT(texunit_:Int,target_:Int,pname_:Int,params_:Int Ptr)="__glewMultiTexParameterIivEXT" +Global glMultiTexParameterIuivEXT(texunit_:Int,target_:Int,pname_:Int,params_:Int Ptr)="__glewMultiTexParameterIuivEXT" +Global glMultiTexParameterfEXT(texunit_:Int,target_:Int,pname_:Int,param_:Float)="__glewMultiTexParameterfEXT" +Global glMultiTexParameterfvEXT(texunit_:Int,target_:Int,pname_:Int,param_:Float Ptr)="__glewMultiTexParameterfvEXT" +Global glMultiTexParameteriEXT(texunit_:Int,target_:Int,pname_:Int,param_:Int)="__glewMultiTexParameteriEXT" +Global glMultiTexParameterivEXT(texunit_:Int,target_:Int,pname_:Int,param_:Int Ptr)="__glewMultiTexParameterivEXT" +Global glMultiTexRenderbufferEXT(texunit_:Int,target_:Int,renderbuffer_:Int)="__glewMultiTexRenderbufferEXT" +Global glMultiTexSubImage1DEXT(texunit_:Int,target_:Int,level_:Int,xoffset_:Int,width_:Int,format_:Int,type_:Int,pixels_:Byte Ptr)="__glewMultiTexSubImage1DEXT" +Global glMultiTexSubImage2DEXT(texunit_:Int,target_:Int,level_:Int,xoffset_:Int,yoffset_:Int,width_:Int,height_:Int,format_:Int,type_:Int,pixels_:Byte Ptr)="__glewMultiTexSubImage2DEXT" +Global glMultiTexSubImage3DEXT(texunit_:Int,target_:Int,level_:Int,xoffset_:Int,yoffset_:Int,zoffset_:Int,width_:Int,height_:Int,depth_:Int,format_:Int,type_:Int,pixels_:Byte Ptr)="__glewMultiTexSubImage3DEXT" +Global glNamedBufferDataEXT(buffer_:Int,size_:Int,data_:Byte Ptr,usage_:Int)="__glewNamedBufferDataEXT" +Global glNamedBufferSubDataEXT(buffer_:Int,offset_:Int,size_:Int,data_:Byte Ptr)="__glewNamedBufferSubDataEXT" +Global glNamedFramebufferRenderbufferEXT(framebuffer_:Int,attachment_:Int,renderbuffertarget_:Int,renderbuffer_:Int)="__glewNamedFramebufferRenderbufferEXT" +Global glNamedFramebufferTexture1DEXT(framebuffer_:Int,attachment_:Int,textarget_:Int,texture_:Int,level_:Int)="__glewNamedFramebufferTexture1DEXT" +Global glNamedFramebufferTexture2DEXT(framebuffer_:Int,attachment_:Int,textarget_:Int,texture_:Int,level_:Int)="__glewNamedFramebufferTexture2DEXT" +Global glNamedFramebufferTexture3DEXT(framebuffer_:Int,attachment_:Int,textarget_:Int,texture_:Int,level_:Int,zoffset_:Int)="__glewNamedFramebufferTexture3DEXT" +Global glNamedFramebufferTextureEXT(framebuffer_:Int,attachment_:Int,texture_:Int,level_:Int)="__glewNamedFramebufferTextureEXT" +Global glNamedFramebufferTextureFaceEXT(framebuffer_:Int,attachment_:Int,texture_:Int,level_:Int,face_:Int)="__glewNamedFramebufferTextureFaceEXT" +Global glNamedFramebufferTextureLayerEXT(framebuffer_:Int,attachment_:Int,texture_:Int,level_:Int,layer_:Int)="__glewNamedFramebufferTextureLayerEXT" +Global glNamedProgramLocalParameter4dEXT(program_:Int,target_:Int,index_:Int,x_:Double,y_:Double,z_:Double,w_:Double)="__glewNamedProgramLocalParameter4dEXT" +Global glNamedProgramLocalParameter4dvEXT(program_:Int,target_:Int,index_:Int,params_:Double Ptr)="__glewNamedProgramLocalParameter4dvEXT" +Global glNamedProgramLocalParameter4fEXT(program_:Int,target_:Int,index_:Int,x_:Float,y_:Float,z_:Float,w_:Float)="__glewNamedProgramLocalParameter4fEXT" +Global glNamedProgramLocalParameter4fvEXT(program_:Int,target_:Int,index_:Int,params_:Float Ptr)="__glewNamedProgramLocalParameter4fvEXT" +Global glNamedProgramLocalParameterI4iEXT(program_:Int,target_:Int,index_:Int,x_:Int,y_:Int,z_:Int,w_:Int)="__glewNamedProgramLocalParameterI4iEXT" +Global glNamedProgramLocalParameterI4ivEXT(program_:Int,target_:Int,index_:Int,params_:Int Ptr)="__glewNamedProgramLocalParameterI4ivEXT" +Global glNamedProgramLocalParameterI4uiEXT(program_:Int,target_:Int,index_:Int,x_:Int,y_:Int,z_:Int,w_:Int)="__glewNamedProgramLocalParameterI4uiEXT" +Global glNamedProgramLocalParameterI4uivEXT(program_:Int,target_:Int,index_:Int,params_:Int Ptr)="__glewNamedProgramLocalParameterI4uivEXT" +Global glNamedProgramLocalParameters4fvEXT(program_:Int,target_:Int,index_:Int,count_:Int,params_:Float Ptr)="__glewNamedProgramLocalParameters4fvEXT" +Global glNamedProgramLocalParametersI4ivEXT(program_:Int,target_:Int,index_:Int,count_:Int,params_:Int Ptr)="__glewNamedProgramLocalParametersI4ivEXT" +Global glNamedProgramLocalParametersI4uivEXT(program_:Int,target_:Int,index_:Int,count_:Int,params_:Int Ptr)="__glewNamedProgramLocalParametersI4uivEXT" +Global glNamedProgramStringEXT(program_:Int,target_:Int,format_:Int,len_:Int,string_:Byte Ptr)="__glewNamedProgramStringEXT" +Global glNamedRenderbufferStorageEXT(renderbuffer_:Int,internalformat_:Int,width_:Int,height_:Int)="__glewNamedRenderbufferStorageEXT" +Global glNamedRenderbufferStorageMultisampleCoverageEXT(renderbuffer_:Int,coverageSamples_:Int,colorSamples_:Int,internalformat_:Int,width_:Int,height_:Int)="__glewNamedRenderbufferStorageMultisampleCoverageEXT" +Global glNamedRenderbufferStorageMultisampleEXT(renderbuffer_:Int,samples_:Int,internalformat_:Int,width_:Int,height_:Int)="__glewNamedRenderbufferStorageMultisampleEXT" +Global glProgramUniform1fEXT(program_:Int,location_:Int,v0_:Float)="__glewProgramUniform1fEXT" +Global glProgramUniform1fvEXT(program_:Int,location_:Int,count_:Int,value_:Float Ptr)="__glewProgramUniform1fvEXT" +Global glProgramUniform1iEXT(program_:Int,location_:Int,v0_:Int)="__glewProgramUniform1iEXT" +Global glProgramUniform1ivEXT(program_:Int,location_:Int,count_:Int,value_:Int Ptr)="__glewProgramUniform1ivEXT" +Global glProgramUniform1uiEXT(program_:Int,location_:Int,v0_:Int)="__glewProgramUniform1uiEXT" +Global glProgramUniform1uivEXT(program_:Int,location_:Int,count_:Int,value_:Int Ptr)="__glewProgramUniform1uivEXT" +Global glProgramUniform2fEXT(program_:Int,location_:Int,v0_:Float,v1_:Float)="__glewProgramUniform2fEXT" +Global glProgramUniform2fvEXT(program_:Int,location_:Int,count_:Int,value_:Float Ptr)="__glewProgramUniform2fvEXT" +Global glProgramUniform2iEXT(program_:Int,location_:Int,v0_:Int,v1_:Int)="__glewProgramUniform2iEXT" +Global glProgramUniform2ivEXT(program_:Int,location_:Int,count_:Int,value_:Int Ptr)="__glewProgramUniform2ivEXT" +Global glProgramUniform2uiEXT(program_:Int,location_:Int,v0_:Int,v1_:Int)="__glewProgramUniform2uiEXT" +Global glProgramUniform2uivEXT(program_:Int,location_:Int,count_:Int,value_:Int Ptr)="__glewProgramUniform2uivEXT" +Global glProgramUniform3fEXT(program_:Int,location_:Int,v0_:Float,v1_:Float,v2_:Float)="__glewProgramUniform3fEXT" +Global glProgramUniform3fvEXT(program_:Int,location_:Int,count_:Int,value_:Float Ptr)="__glewProgramUniform3fvEXT" +Global glProgramUniform3iEXT(program_:Int,location_:Int,v0_:Int,v1_:Int,v2_:Int)="__glewProgramUniform3iEXT" +Global glProgramUniform3ivEXT(program_:Int,location_:Int,count_:Int,value_:Int Ptr)="__glewProgramUniform3ivEXT" +Global glProgramUniform3uiEXT(program_:Int,location_:Int,v0_:Int,v1_:Int,v2_:Int)="__glewProgramUniform3uiEXT" +Global glProgramUniform3uivEXT(program_:Int,location_:Int,count_:Int,value_:Int Ptr)="__glewProgramUniform3uivEXT" +Global glProgramUniform4fEXT(program_:Int,location_:Int,v0_:Float,v1_:Float,v2_:Float,v3_:Float)="__glewProgramUniform4fEXT" +Global glProgramUniform4fvEXT(program_:Int,location_:Int,count_:Int,value_:Float Ptr)="__glewProgramUniform4fvEXT" +Global glProgramUniform4iEXT(program_:Int,location_:Int,v0_:Int,v1_:Int,v2_:Int,v3_:Int)="__glewProgramUniform4iEXT" +Global glProgramUniform4ivEXT(program_:Int,location_:Int,count_:Int,value_:Int Ptr)="__glewProgramUniform4ivEXT" +Global glProgramUniform4uiEXT(program_:Int,location_:Int,v0_:Int,v1_:Int,v2_:Int,v3_:Int)="__glewProgramUniform4uiEXT" +Global glProgramUniform4uivEXT(program_:Int,location_:Int,count_:Int,value_:Int Ptr)="__glewProgramUniform4uivEXT" +Global glProgramUniformMatrix2fvEXT(program_:Int,location_:Int,count_:Int,transpose_:Byte,value_:Float Ptr)="__glewProgramUniformMatrix2fvEXT" +Global glProgramUniformMatrix2x3fvEXT(program_:Int,location_:Int,count_:Int,transpose_:Byte,value_:Float Ptr)="__glewProgramUniformMatrix2x3fvEXT" +Global glProgramUniformMatrix2x4fvEXT(program_:Int,location_:Int,count_:Int,transpose_:Byte,value_:Float Ptr)="__glewProgramUniformMatrix2x4fvEXT" +Global glProgramUniformMatrix3fvEXT(program_:Int,location_:Int,count_:Int,transpose_:Byte,value_:Float Ptr)="__glewProgramUniformMatrix3fvEXT" +Global glProgramUniformMatrix3x2fvEXT(program_:Int,location_:Int,count_:Int,transpose_:Byte,value_:Float Ptr)="__glewProgramUniformMatrix3x2fvEXT" +Global glProgramUniformMatrix3x4fvEXT(program_:Int,location_:Int,count_:Int,transpose_:Byte,value_:Float Ptr)="__glewProgramUniformMatrix3x4fvEXT" +Global glProgramUniformMatrix4fvEXT(program_:Int,location_:Int,count_:Int,transpose_:Byte,value_:Float Ptr)="__glewProgramUniformMatrix4fvEXT" +Global glProgramUniformMatrix4x2fvEXT(program_:Int,location_:Int,count_:Int,transpose_:Byte,value_:Float Ptr)="__glewProgramUniformMatrix4x2fvEXT" +Global glProgramUniformMatrix4x3fvEXT(program_:Int,location_:Int,count_:Int,transpose_:Byte,value_:Float Ptr)="__glewProgramUniformMatrix4x3fvEXT" +Global glPushClientAttribDefaultEXT(mask_:Int)="__glewPushClientAttribDefaultEXT" +Global glTextureBufferEXT(texture_:Int,target_:Int,internalformat_:Int,buffer_:Int)="__glewTextureBufferEXT" +Global glTextureImage1DEXT(texture_:Int,target_:Int,level_:Int,internalformat_:Int,width_:Int,border_:Int,format_:Int,type_:Int,pixels_:Byte Ptr)="__glewTextureImage1DEXT" +Global glTextureImage2DEXT(texture_:Int,target_:Int,level_:Int,internalformat_:Int,width_:Int,height_:Int,border_:Int,format_:Int,type_:Int,pixels_:Byte Ptr)="__glewTextureImage2DEXT" +Global glTextureImage3DEXT(texture_:Int,target_:Int,level_:Int,internalformat_:Int,width_:Int,height_:Int,depth_:Int,border_:Int,format_:Int,type_:Int,pixels_:Byte Ptr)="__glewTextureImage3DEXT" +Global glTextureParameterIivEXT(texture_:Int,target_:Int,pname_:Int,params_:Int Ptr)="__glewTextureParameterIivEXT" +Global glTextureParameterIuivEXT(texture_:Int,target_:Int,pname_:Int,params_:Int Ptr)="__glewTextureParameterIuivEXT" +Global glTextureParameterfEXT(texture_:Int,target_:Int,pname_:Int,param_:Float)="__glewTextureParameterfEXT" +Global glTextureParameterfvEXT(texture_:Int,target_:Int,pname_:Int,param_:Float Ptr)="__glewTextureParameterfvEXT" +Global glTextureParameteriEXT(texture_:Int,target_:Int,pname_:Int,param_:Int)="__glewTextureParameteriEXT" +Global glTextureParameterivEXT(texture_:Int,target_:Int,pname_:Int,param_:Int Ptr)="__glewTextureParameterivEXT" +Global glTextureRenderbufferEXT(texture_:Int,target_:Int,renderbuffer_:Int)="__glewTextureRenderbufferEXT" +Global glTextureSubImage1DEXT(texture_:Int,target_:Int,level_:Int,xoffset_:Int,width_:Int,format_:Int,type_:Int,pixels_:Byte Ptr)="__glewTextureSubImage1DEXT" +Global glTextureSubImage2DEXT(texture_:Int,target_:Int,level_:Int,xoffset_:Int,yoffset_:Int,width_:Int,height_:Int,format_:Int,type_:Int,pixels_:Byte Ptr)="__glewTextureSubImage2DEXT" +Global glTextureSubImage3DEXT(texture_:Int,target_:Int,level_:Int,xoffset_:Int,yoffset_:Int,zoffset_:Int,width_:Int,height_:Int,depth_:Int,format_:Int,type_:Int,pixels_:Byte Ptr)="__glewTextureSubImage3DEXT" +Global glUnmapNamedBufferEXT:Byte(buffer_:Int)="__glewUnmapNamedBufferEXT" +Global GL_EXT_direct_state_access:Byte="__GLEW_EXT_direct_state_access" +Global glColorMaskIndexedEXT(buf_:Int,r_:Byte,g_:Byte,b_:Byte,a_:Byte)="__glewColorMaskIndexedEXT" +Global glDisableIndexedEXT(target_:Int,index_:Int)="__glewDisableIndexedEXT" +Global glEnableIndexedEXT(target_:Int,index_:Int)="__glewEnableIndexedEXT" +Global glGetBooleanIndexedvEXT(value_:Int,index_:Int,data_:Byte Ptr)="__glewGetBooleanIndexedvEXT" +Global glGetIntegerIndexedvEXT(value_:Int,index_:Int,data_:Int Ptr)="__glewGetIntegerIndexedvEXT" +Global glIsEnabledIndexedEXT:Byte(target_:Int,index_:Int)="__glewIsEnabledIndexedEXT" +Global GL_EXT_draw_buffers2:Byte="__GLEW_EXT_draw_buffers2" +Global glDrawArraysInstancedEXT(mode_:Int,start_:Int,count_:Int,primcount_:Int)="__glewDrawArraysInstancedEXT" +Global glDrawElementsInstancedEXT(mode_:Int,count_:Int,type_:Int,indices_:Byte Ptr,primcount_:Int)="__glewDrawElementsInstancedEXT" +Global GL_EXT_draw_instanced:Byte="__GLEW_EXT_draw_instanced" +Global glDrawRangeElementsEXT(mode_:Int,start_:Int,end_:Int,count_:Int,type_:Int,indices_:Byte Ptr)="__glewDrawRangeElementsEXT" +Global GL_EXT_draw_range_elements:Byte="__GLEW_EXT_draw_range_elements" +Const GL_FOG_COORDINATE_SOURCE_EXT=$8450 +Const GL_FOG_COORDINATE_EXT=$8451 +Const GL_FRAGMENT_DEPTH_EXT=$8452 +Const GL_CURRENT_FOG_COORDINATE_EXT=$8453 +Const GL_FOG_COORDINATE_ARRAY_TYPE_EXT=$8454 +Const GL_FOG_COORDINATE_ARRAY_STRIDE_EXT=$8455 +Const GL_FOG_COORDINATE_ARRAY_POINTER_EXT=$8456 +Const GL_FOG_COORDINATE_ARRAY_EXT=$8457 +Global glFogCoordPointerEXT(type_:Int,stride_:Int,pointer_:Byte Ptr)="__glewFogCoordPointerEXT" +Global glFogCoorddEXT(coord_:Double)="__glewFogCoorddEXT" +Global glFogCoorddvEXT(coord_:Double Ptr)="__glewFogCoorddvEXT" +Global glFogCoordfEXT(coord_:Float)="__glewFogCoordfEXT" +Global glFogCoordfvEXT(coord_:Float Ptr)="__glewFogCoordfvEXT" +Global GL_EXT_fog_coord:Byte="__GLEW_EXT_fog_coord" +Const GL_FRAGMENT_LIGHTING_EXT=$8400 +Const GL_FRAGMENT_COLOR_MATERIAL_EXT=$8401 +Const GL_FRAGMENT_COLOR_MATERIAL_FACE_EXT=$8402 +Const GL_FRAGMENT_COLOR_MATERIAL_PARAMETER_EXT=$8403 +Const GL_MAX_FRAGMENT_LIGHTS_EXT=$8404 +Const GL_MAX_ACTIVE_LIGHTS_EXT=$8405 +Const GL_CURRENT_RASTER_NORMAL_EXT=$8406 +Const GL_LIGHT_ENV_MODE_EXT=$8407 +Const GL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_EXT=$8408 +Const GL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_EXT=$8409 +Const GL_FRAGMENT_LIGHT_MODEL_AMBIENT_EXT=$840A +Const GL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_EXT=$840B +Const GL_FRAGMENT_LIGHT0_EXT=$840C +Const GL_FRAGMENT_LIGHT7_EXT=$8413 +Global glFragmentColorMaterialEXT(face_:Int,mode_:Int)="__glewFragmentColorMaterialEXT" +Global glFragmentLightModelfEXT(pname_:Int,param_:Float)="__glewFragmentLightModelfEXT" +Global glFragmentLightModelfvEXT(pname_:Int,params_:Float Ptr)="__glewFragmentLightModelfvEXT" +Global glFragmentLightModeliEXT(pname_:Int,param_:Int)="__glewFragmentLightModeliEXT" +Global glFragmentLightModelivEXT(pname_:Int,params_:Int Ptr)="__glewFragmentLightModelivEXT" +Global glFragmentLightfEXT(light_:Int,pname_:Int,param_:Float)="__glewFragmentLightfEXT" +Global glFragmentLightfvEXT(light_:Int,pname_:Int,params_:Float Ptr)="__glewFragmentLightfvEXT" +Global glFragmentLightiEXT(light_:Int,pname_:Int,param_:Int)="__glewFragmentLightiEXT" +Global glFragmentLightivEXT(light_:Int,pname_:Int,params_:Int Ptr)="__glewFragmentLightivEXT" +Global glFragmentMaterialfEXT(face_:Int,pname_:Int,param_:Float)="__glewFragmentMaterialfEXT" +Global glFragmentMaterialfvEXT(face_:Int,pname_:Int,params_:Float Ptr)="__glewFragmentMaterialfvEXT" +Global glFragmentMaterialiEXT(face_:Int,pname_:Int,param_:Int)="__glewFragmentMaterialiEXT" +Global glFragmentMaterialivEXT(face_:Int,pname_:Int,params_:Int Ptr)="__glewFragmentMaterialivEXT" +Global glGetFragmentLightfvEXT(light_:Int,pname_:Int,params_:Float Ptr)="__glewGetFragmentLightfvEXT" +Global glGetFragmentLightivEXT(light_:Int,pname_:Int,params_:Int Ptr)="__glewGetFragmentLightivEXT" +Global glGetFragmentMaterialfvEXT(face_:Int,pname_:Int,params_:Float Ptr)="__glewGetFragmentMaterialfvEXT" +Global glGetFragmentMaterialivEXT(face_:Int,pname_:Int,params_:Int Ptr)="__glewGetFragmentMaterialivEXT" +Global glLightEnviEXT(pname_:Int,param_:Int)="__glewLightEnviEXT" +Global GL_EXT_fragment_lighting:Byte="__GLEW_EXT_fragment_lighting" +Const GL_DRAW_FRAMEBUFFER_BINDING_EXT=$8CA6 +Const GL_READ_FRAMEBUFFER_EXT=$8CA8 +Const GL_DRAW_FRAMEBUFFER_EXT=$8CA9 +Const GL_READ_FRAMEBUFFER_BINDING_EXT=$8CAA +Global glBlitFramebufferEXT(srcX0_:Int,srcY0_:Int,srcX1_:Int,srcY1_:Int,dstX0_:Int,dstY0_:Int,dstX1_:Int,dstY1_:Int,mask_:Int,filter_:Int)="__glewBlitFramebufferEXT" +Global GL_EXT_framebuffer_blit:Byte="__GLEW_EXT_framebuffer_blit" +Const GL_RENDERBUFFER_SAMPLES_EXT=$8CAB +Const GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT=$8D56 +Const GL_MAX_SAMPLES_EXT=$8D57 +Global glRenderbufferStorageMultisampleEXT(target_:Int,samples_:Int,internalformat_:Int,width_:Int,height_:Int)="__glewRenderbufferStorageMultisampleEXT" +Global GL_EXT_framebuffer_multisample:Byte="__GLEW_EXT_framebuffer_multisample" +Const GL_INVALID_FRAMEBUFFER_OPERATION_EXT=$0506 +Const GL_MAX_RENDERBUFFER_SIZE_EXT=$84E8 +Const GL_FRAMEBUFFER_BINDING_EXT=$8CA6 +Const GL_RENDERBUFFER_BINDING_EXT=$8CA7 +Const GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT=$8CD0 +Const GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT=$8CD1 +Const GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT=$8CD2 +Const GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT=$8CD3 +Const GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT=$8CD4 +Const GL_FRAMEBUFFER_COMPLETE_EXT=$8CD5 +Const GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT=$8CD6 +Const GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT=$8CD7 +Const GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT=$8CD9 +Const GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT=$8CDA +Const GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT=$8CDB +Const GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT=$8CDC +Const GL_FRAMEBUFFER_UNSUPPORTED_EXT=$8CDD +Const GL_MAX_COLOR_ATTACHMENTS_EXT=$8CDF +Const GL_COLOR_ATTACHMENT0_EXT=$8CE0 +Const GL_COLOR_ATTACHMENT1_EXT=$8CE1 +Const GL_COLOR_ATTACHMENT2_EXT=$8CE2 +Const GL_COLOR_ATTACHMENT3_EXT=$8CE3 +Const GL_COLOR_ATTACHMENT4_EXT=$8CE4 +Const GL_COLOR_ATTACHMENT5_EXT=$8CE5 +Const GL_COLOR_ATTACHMENT6_EXT=$8CE6 +Const GL_COLOR_ATTACHMENT7_EXT=$8CE7 +Const GL_COLOR_ATTACHMENT8_EXT=$8CE8 +Const GL_COLOR_ATTACHMENT9_EXT=$8CE9 +Const GL_COLOR_ATTACHMENT10_EXT=$8CEA +Const GL_COLOR_ATTACHMENT11_EXT=$8CEB +Const GL_COLOR_ATTACHMENT12_EXT=$8CEC +Const GL_COLOR_ATTACHMENT13_EXT=$8CED +Const GL_COLOR_ATTACHMENT14_EXT=$8CEE +Const GL_COLOR_ATTACHMENT15_EXT=$8CEF +Const GL_DEPTH_ATTACHMENT_EXT=$8D00 +Const GL_STENCIL_ATTACHMENT_EXT=$8D20 +Const GL_FRAMEBUFFER_EXT=$8D40 +Const GL_RENDERBUFFER_EXT=$8D41 +Const GL_RENDERBUFFER_WIDTH_EXT=$8D42 +Const GL_RENDERBUFFER_HEIGHT_EXT=$8D43 +Const GL_RENDERBUFFER_INTERNAL_FORMAT_EXT=$8D44 +Const GL_STENCIL_INDEX1_EXT=$8D46 +Const GL_STENCIL_INDEX4_EXT=$8D47 +Const GL_STENCIL_INDEX8_EXT=$8D48 +Const GL_STENCIL_INDEX16_EXT=$8D49 +Const GL_RENDERBUFFER_RED_SIZE_EXT=$8D50 +Const GL_RENDERBUFFER_GREEN_SIZE_EXT=$8D51 +Const GL_RENDERBUFFER_BLUE_SIZE_EXT=$8D52 +Const GL_RENDERBUFFER_ALPHA_SIZE_EXT=$8D53 +Const GL_RENDERBUFFER_DEPTH_SIZE_EXT=$8D54 +Const GL_RENDERBUFFER_STENCIL_SIZE_EXT=$8D55 +Global glBindFramebufferEXT(target_:Int,framebuffer_:Int)="__glewBindFramebufferEXT" +Global glBindRenderbufferEXT(target_:Int,renderbuffer_:Int)="__glewBindRenderbufferEXT" +Global glCheckFramebufferStatusEXT:Int(target_:Int)="__glewCheckFramebufferStatusEXT" +Global glDeleteFramebuffersEXT(n_:Int,framebuffers_:Int Ptr)="__glewDeleteFramebuffersEXT" +Global glDeleteRenderbuffersEXT(n_:Int,renderbuffers_:Int Ptr)="__glewDeleteRenderbuffersEXT" +Global glFramebufferRenderbufferEXT(target_:Int,attachment_:Int,renderbuffertarget_:Int,renderbuffer_:Int)="__glewFramebufferRenderbufferEXT" +Global glFramebufferTexture1DEXT(target_:Int,attachment_:Int,textarget_:Int,texture_:Int,level_:Int)="__glewFramebufferTexture1DEXT" +Global glFramebufferTexture2DEXT(target_:Int,attachment_:Int,textarget_:Int,texture_:Int,level_:Int)="__glewFramebufferTexture2DEXT" +Global glFramebufferTexture3DEXT(target_:Int,attachment_:Int,textarget_:Int,texture_:Int,level_:Int,zoffset_:Int)="__glewFramebufferTexture3DEXT" +Global glGenFramebuffersEXT(n_:Int,framebuffers_:Int Ptr)="__glewGenFramebuffersEXT" +Global glGenRenderbuffersEXT(n_:Int,renderbuffers_:Int Ptr)="__glewGenRenderbuffersEXT" +Global glGenerateMipmapEXT(target_:Int)="__glewGenerateMipmapEXT" +Global glGetFramebufferAttachmentParameterivEXT(target_:Int,attachment_:Int,pname_:Int,params_:Int Ptr)="__glewGetFramebufferAttachmentParameterivEXT" +Global glGetRenderbufferParameterivEXT(target_:Int,pname_:Int,params_:Int Ptr)="__glewGetRenderbufferParameterivEXT" +Global glIsFramebufferEXT:Byte(framebuffer_:Int)="__glewIsFramebufferEXT" +Global glIsRenderbufferEXT:Byte(renderbuffer_:Int)="__glewIsRenderbufferEXT" +Global glRenderbufferStorageEXT(target_:Int,internalformat_:Int,width_:Int,height_:Int)="__glewRenderbufferStorageEXT" +Global GL_EXT_framebuffer_object:Byte="__GLEW_EXT_framebuffer_object" +Const GL_FRAMEBUFFER_SRGB_EXT=$8DB9 +Const GL_FRAMEBUFFER_SRGB_CAPABLE_EXT=$8DBA +Global GL_EXT_framebuffer_sRGB:Byte="__GLEW_EXT_framebuffer_sRGB" +Const GL_LINES_ADJACENCY_EXT=$A +Const GL_LINE_STRIP_ADJACENCY_EXT=$B +Const GL_TRIANGLES_ADJACENCY_EXT=$C +Const GL_TRIANGLE_STRIP_ADJACENCY_EXT=$D +Const GL_PROGRAM_POINT_SIZE_EXT=$8642 +Const GL_MAX_VARYING_COMPONENTS_EXT=$8B4B +Const GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT=$8C29 +Const GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT=$8CD4 +Const GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT=$8DA7 +Const GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT=$8DA8 +Const GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT=$8DA9 +Const GL_GEOMETRY_SHADER_EXT=$8DD9 +Const GL_GEOMETRY_VERTICES_OUT_EXT=$8DDA +Const GL_GEOMETRY_INPUT_TYPE_EXT=$8DDB +Const GL_GEOMETRY_OUTPUT_TYPE_EXT=$8DDC +Const GL_MAX_GEOMETRY_VARYING_COMPONENTS_EXT=$8DDD +Const GL_MAX_VERTEX_VARYING_COMPONENTS_EXT=$8DDE +Const GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT=$8DDF +Const GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT=$8DE0 +Const GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT=$8DE1 +Global glFramebufferTextureEXT(target_:Int,attachment_:Int,texture_:Int,level_:Int)="__glewFramebufferTextureEXT" +Global glFramebufferTextureFaceEXT(target_:Int,attachment_:Int,texture_:Int,level_:Int,face_:Int)="__glewFramebufferTextureFaceEXT" +Global glFramebufferTextureLayerEXT(target_:Int,attachment_:Int,texture_:Int,level_:Int,layer_:Int)="__glewFramebufferTextureLayerEXT" +Global glProgramParameteriEXT(program_:Int,pname_:Int,value_:Int)="__glewProgramParameteriEXT" +Global GL_EXT_geometry_shader4:Byte="__GLEW_EXT_geometry_shader4" +Global glProgramEnvParameters4fvEXT(target_:Int,index_:Int,count_:Int,params_:Float Ptr)="__glewProgramEnvParameters4fvEXT" +Global glProgramLocalParameters4fvEXT(target_:Int,index_:Int,count_:Int,params_:Float Ptr)="__glewProgramLocalParameters4fvEXT" +Global GL_EXT_gpu_program_parameters:Byte="__GLEW_EXT_gpu_program_parameters" +Const GL_VERTEX_ATTRIB_ARRAY_INTEGER_EXT=$88FD +Const GL_SAMPLER_1D_ARRAY_EXT=$8DC0 +Const GL_SAMPLER_2D_ARRAY_EXT=$8DC1 +Const GL_SAMPLER_BUFFER_EXT=$8DC2 +Const GL_SAMPLER_1D_ARRAY_SHADOW_EXT=$8DC3 +Const GL_SAMPLER_2D_ARRAY_SHADOW_EXT=$8DC4 +Const GL_SAMPLER_CUBE_SHADOW_EXT=$8DC5 +Const GL_UNSIGNED_INT_VEC2_EXT=$8DC6 +Const GL_UNSIGNED_INT_VEC3_EXT=$8DC7 +Const GL_UNSIGNED_INT_VEC4_EXT=$8DC8 +Const GL_INT_SAMPLER_1D_EXT=$8DC9 +Const GL_INT_SAMPLER_2D_EXT=$8DCA +Const GL_INT_SAMPLER_3D_EXT=$8DCB +Const GL_INT_SAMPLER_CUBE_EXT=$8DCC +Const GL_INT_SAMPLER_2D_RECT_EXT=$8DCD +Const GL_INT_SAMPLER_1D_ARRAY_EXT=$8DCE +Const GL_INT_SAMPLER_2D_ARRAY_EXT=$8DCF +Const GL_INT_SAMPLER_BUFFER_EXT=$8DD0 +Const GL_UNSIGNED_INT_SAMPLER_1D_EXT=$8DD1 +Const GL_UNSIGNED_INT_SAMPLER_2D_EXT=$8DD2 +Const GL_UNSIGNED_INT_SAMPLER_3D_EXT=$8DD3 +Const GL_UNSIGNED_INT_SAMPLER_CUBE_EXT=$8DD4 +Const GL_UNSIGNED_INT_SAMPLER_2D_RECT_EXT=$8DD5 +Const GL_UNSIGNED_INT_SAMPLER_1D_ARRAY_EXT=$8DD6 +Const GL_UNSIGNED_INT_SAMPLER_2D_ARRAY_EXT=$8DD7 +Const GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT=$8DD8 +Global glBindFragDataLocationEXT(program_:Int,color_:Int,name_:Byte Ptr)="__glewBindFragDataLocationEXT" +Global glGetFragDataLocationEXT:Int(program_:Int,name_:Byte Ptr)="__glewGetFragDataLocationEXT" +Global glGetUniformuivEXT(program_:Int,location_:Int,params_:Int Ptr)="__glewGetUniformuivEXT" +Global glGetVertexAttribIivEXT(index_:Int,pname_:Int,params_:Int Ptr)="__glewGetVertexAttribIivEXT" +Global glGetVertexAttribIuivEXT(index_:Int,pname_:Int,params_:Int Ptr)="__glewGetVertexAttribIuivEXT" +Global glUniform1uiEXT(location_:Int,v0_:Int)="__glewUniform1uiEXT" +Global glUniform1uivEXT(location_:Int,count_:Int,value_:Int Ptr)="__glewUniform1uivEXT" +Global glUniform2uiEXT(location_:Int,v0_:Int,v1_:Int)="__glewUniform2uiEXT" +Global glUniform2uivEXT(location_:Int,count_:Int,value_:Int Ptr)="__glewUniform2uivEXT" +Global glUniform3uiEXT(location_:Int,v0_:Int,v1_:Int,v2_:Int)="__glewUniform3uiEXT" +Global glUniform3uivEXT(location_:Int,count_:Int,value_:Int Ptr)="__glewUniform3uivEXT" +Global glUniform4uiEXT(location_:Int,v0_:Int,v1_:Int,v2_:Int,v3_:Int)="__glewUniform4uiEXT" +Global glUniform4uivEXT(location_:Int,count_:Int,value_:Int Ptr)="__glewUniform4uivEXT" +Global glVertexAttribI1iEXT(index_:Int,x_:Int)="__glewVertexAttribI1iEXT" +Global glVertexAttribI1ivEXT(index_:Int,v_:Int Ptr)="__glewVertexAttribI1ivEXT" +Global glVertexAttribI1uiEXT(index_:Int,x_:Int)="__glewVertexAttribI1uiEXT" +Global glVertexAttribI1uivEXT(index_:Int,v_:Int Ptr)="__glewVertexAttribI1uivEXT" +Global glVertexAttribI2iEXT(index_:Int,x_:Int,y_:Int)="__glewVertexAttribI2iEXT" +Global glVertexAttribI2ivEXT(index_:Int,v_:Int Ptr)="__glewVertexAttribI2ivEXT" +Global glVertexAttribI2uiEXT(index_:Int,x_:Int,y_:Int)="__glewVertexAttribI2uiEXT" +Global glVertexAttribI2uivEXT(index_:Int,v_:Int Ptr)="__glewVertexAttribI2uivEXT" +Global glVertexAttribI3iEXT(index_:Int,x_:Int,y_:Int,z_:Int)="__glewVertexAttribI3iEXT" +Global glVertexAttribI3ivEXT(index_:Int,v_:Int Ptr)="__glewVertexAttribI3ivEXT" +Global glVertexAttribI3uiEXT(index_:Int,x_:Int,y_:Int,z_:Int)="__glewVertexAttribI3uiEXT" +Global glVertexAttribI3uivEXT(index_:Int,v_:Int Ptr)="__glewVertexAttribI3uivEXT" +Global glVertexAttribI4bvEXT(index_:Int,v_:Byte Ptr)="__glewVertexAttribI4bvEXT" +Global glVertexAttribI4iEXT(index_:Int,x_:Int,y_:Int,z_:Int,w_:Int)="__glewVertexAttribI4iEXT" +Global glVertexAttribI4ivEXT(index_:Int,v_:Int Ptr)="__glewVertexAttribI4ivEXT" +Global glVertexAttribI4svEXT(index_:Int,v_:Short Ptr)="__glewVertexAttribI4svEXT" +Global glVertexAttribI4ubvEXT(index_:Int,v_:Byte Ptr)="__glewVertexAttribI4ubvEXT" +Global glVertexAttribI4uiEXT(index_:Int,x_:Int,y_:Int,z_:Int,w_:Int)="__glewVertexAttribI4uiEXT" +Global glVertexAttribI4uivEXT(index_:Int,v_:Int Ptr)="__glewVertexAttribI4uivEXT" +Global glVertexAttribI4usvEXT(index_:Int,v_:Short Ptr)="__glewVertexAttribI4usvEXT" +Global glVertexAttribIPointerEXT(index_:Int,size_:Int,type_:Int,stride_:Int,pointer_:Byte Ptr)="__glewVertexAttribIPointerEXT" +Global GL_EXT_gpu_shader4:Byte="__GLEW_EXT_gpu_shader4" +Const GL_HISTOGRAM_EXT=$8024 +Const GL_PROXY_HISTOGRAM_EXT=$8025 +Const GL_HISTOGRAM_WIDTH_EXT=$8026 +Const GL_HISTOGRAM_FORMAT_EXT=$8027 +Const GL_HISTOGRAM_RED_SIZE_EXT=$8028 +Const GL_HISTOGRAM_GREEN_SIZE_EXT=$8029 +Const GL_HISTOGRAM_BLUE_SIZE_EXT=$802A +Const GL_HISTOGRAM_ALPHA_SIZE_EXT=$802B +Const GL_HISTOGRAM_LUMINANCE_SIZE_EXT=$802C +Const GL_HISTOGRAM_SINK_EXT=$802D +Const GL_MINMAX_EXT=$802E +Const GL_MINMAX_FORMAT_EXT=$802F +Const GL_MINMAX_SINK_EXT=$8030 +Global glGetHistogramEXT(target_:Int,reset_:Byte,format_:Int,type_:Int,values_:Byte Ptr)="__glewGetHistogramEXT" +Global glGetHistogramParameterfvEXT(target_:Int,pname_:Int,params_:Float Ptr)="__glewGetHistogramParameterfvEXT" +Global glGetHistogramParameterivEXT(target_:Int,pname_:Int,params_:Int Ptr)="__glewGetHistogramParameterivEXT" +Global glGetMinmaxEXT(target_:Int,reset_:Byte,format_:Int,type_:Int,values_:Byte Ptr)="__glewGetMinmaxEXT" +Global glGetMinmaxParameterfvEXT(target_:Int,pname_:Int,params_:Float Ptr)="__glewGetMinmaxParameterfvEXT" +Global glGetMinmaxParameterivEXT(target_:Int,pname_:Int,params_:Int Ptr)="__glewGetMinmaxParameterivEXT" +Global glHistogramEXT(target_:Int,width_:Int,internalformat_:Int,sink_:Byte)="__glewHistogramEXT" +Global glMinmaxEXT(target_:Int,internalformat_:Int,sink_:Byte)="__glewMinmaxEXT" +Global glResetHistogramEXT(target_:Int)="__glewResetHistogramEXT" +Global glResetMinmaxEXT(target_:Int)="__glewResetMinmaxEXT" +Global GL_EXT_histogram:Byte="__GLEW_EXT_histogram" +Global GL_EXT_index_array_formats:Byte="__GLEW_EXT_index_array_formats" +Global glIndexFuncEXT(func_:Int,ref_:Float)="__glewIndexFuncEXT" +Global GL_EXT_index_func:Byte="__GLEW_EXT_index_func" +Global glIndexMaterialEXT(face_:Int,mode_:Int)="__glewIndexMaterialEXT" +Global GL_EXT_index_material:Byte="__GLEW_EXT_index_material" +Global GL_EXT_index_texture:Byte="__GLEW_EXT_index_texture" +Const GL_FRAGMENT_MATERIAL_EXT=$8349 +Const GL_FRAGMENT_NORMAL_EXT=$834A +Const GL_FRAGMENT_COLOR_EXT=$834C +Const GL_ATTENUATION_EXT=$834D +Const GL_SHADOW_ATTENUATION_EXT=$834E +Const GL_TEXTURE_APPLICATION_MODE_EXT=$834F +Const GL_TEXTURE_LIGHT_EXT=$8350 +Const GL_TEXTURE_MATERIAL_FACE_EXT=$8351 +Const GL_TEXTURE_MATERIAL_PARAMETER_EXT=$8352 +Global glApplyTextureEXT(mode_:Int)="__glewApplyTextureEXT" +Global glTextureLightEXT(pname_:Int)="__glewTextureLightEXT" +Global glTextureMaterialEXT(face_:Int,mode_:Int)="__glewTextureMaterialEXT" +Global GL_EXT_light_texture:Byte="__GLEW_EXT_light_texture" +Global GL_EXT_misc_attribute:Byte="__GLEW_EXT_misc_attribute" +Global glMultiDrawArraysEXT(mode_:Int,first_:Int Ptr,count_:Int Ptr,primcount_:Int)="__glewMultiDrawArraysEXT" +Global glMultiDrawElementsEXT(mode_:Int,count_:Int Ptr,type_:Int,indices_:Byte Ptr Ptr,primcount_:Int)="__glewMultiDrawElementsEXT" +Global GL_EXT_multi_draw_arrays:Byte="__GLEW_EXT_multi_draw_arrays" +Const GL_MULTISAMPLE_EXT=$809D +Const GL_SAMPLE_ALPHA_TO_MASK_EXT=$809E +Const GL_SAMPLE_ALPHA_TO_ONE_EXT=$809F +Const GL_SAMPLE_MASK_EXT=$80A0 +Const GL_1PASS_EXT=$80A1 +Const GL_2PASS_0_EXT=$80A2 +Const GL_2PASS_1_EXT=$80A3 +Const GL_4PASS_0_EXT=$80A4 +Const GL_4PASS_1_EXT=$80A5 +Const GL_4PASS_2_EXT=$80A6 +Const GL_4PASS_3_EXT=$80A7 +Const GL_SAMPLE_BUFFERS_EXT=$80A8 +Const GL_SAMPLES_EXT=$80A9 +Const GL_SAMPLE_MASK_VALUE_EXT=$80AA +Const GL_SAMPLE_MASK_INVERT_EXT=$80AB +Const GL_SAMPLE_PATTERN_EXT=$80AC +Const GL_MULTISAMPLE_BIT_EXT=$20000000 +Global glSampleMaskEXT(value_:Float,invert_:Byte)="__glewSampleMaskEXT" +Global glSamplePatternEXT(pattern_:Int)="__glewSamplePatternEXT" +Global GL_EXT_multisample:Byte="__GLEW_EXT_multisample" +Const GL_DEPTH_STENCIL_EXT=$84F9 +Const GL_UNSIGNED_INT_24_8_EXT=$84FA +Const GL_DEPTH24_STENCIL8_EXT=$88F0 +Const GL_TEXTURE_STENCIL_SIZE_EXT=$88F1 +Global GL_EXT_packed_depth_stencil:Byte="__GLEW_EXT_packed_depth_stencil" +Const GL_R11F_G11F_B10F_EXT=$8C3A +Const GL_UNSIGNED_INT_10F_11F_11F_REV_EXT=$8C3B +Const GL_RGBA_SIGNED_COMPONENTS_EXT=$8C3C +Global GL_EXT_packed_float:Byte="__GLEW_EXT_packed_float" +Const GL_UNSIGNED_BYTE_3_3_2_EXT=$8032 +Const GL_UNSIGNED_SHORT_4_4_4_4_EXT=$8033 +Const GL_UNSIGNED_SHORT_5_5_5_1_EXT=$8034 +Const GL_UNSIGNED_INT_8_8_8_8_EXT=$8035 +Const GL_UNSIGNED_INT_10_10_10_2_EXT=$8036 +Global GL_EXT_packed_pixels:Byte="__GLEW_EXT_packed_pixels" +Const GL_TEXTURE_3D_EXT=$806F +Const GL_PROXY_TEXTURE_3D_EXT=$8070 +Const GL_COLOR_TABLE_FORMAT_EXT=$80D8 +Const GL_COLOR_TABLE_WIDTH_EXT=$80D9 +Const GL_COLOR_TABLE_RED_SIZE_EXT=$80DA +Const GL_COLOR_TABLE_GREEN_SIZE_EXT=$80DB +Const GL_COLOR_TABLE_BLUE_SIZE_EXT=$80DC +Const GL_COLOR_TABLE_ALPHA_SIZE_EXT=$80DD +Const GL_COLOR_TABLE_LUMINANCE_SIZE_EXT=$80DE +Const GL_COLOR_TABLE_INTENSITY_SIZE_EXT=$80DF +Const GL_TEXTURE_INDEX_SIZE_EXT=$80ED +Global glColorTableEXT(target_:Int,internalFormat_:Int,width_:Int,format_:Int,type_:Int,data_:Byte Ptr)="__glewColorTableEXT" +Global glGetColorTableEXT(target_:Int,format_:Int,type_:Int,data_:Byte Ptr)="__glewGetColorTableEXT" +Global glGetColorTableParameterfvEXT(target_:Int,pname_:Int,params_:Float Ptr)="__glewGetColorTableParameterfvEXT" +Global glGetColorTableParameterivEXT(target_:Int,pname_:Int,params_:Int Ptr)="__glewGetColorTableParameterivEXT" +Global GL_EXT_paletted_texture:Byte="__GLEW_EXT_paletted_texture" +Const GL_PIXEL_PACK_BUFFER_EXT=$88EB +Const GL_PIXEL_UNPACK_BUFFER_EXT=$88EC +Const GL_PIXEL_PACK_BUFFER_BINDING_EXT=$88ED +Const GL_PIXEL_UNPACK_BUFFER_BINDING_EXT=$88EF +Global GL_EXT_pixel_buffer_object:Byte="__GLEW_EXT_pixel_buffer_object" +Const GL_PIXEL_TRANSFORM_2D_EXT=$8330 +Const GL_PIXEL_MAG_FILTER_EXT=$8331 +Const GL_PIXEL_MIN_FILTER_EXT=$8332 +Const GL_PIXEL_CUBIC_WEIGHT_EXT=$8333 +Const GL_CUBIC_EXT=$8334 +Const GL_AVERAGE_EXT=$8335 +Const GL_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT=$8336 +Const GL_MAX_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT=$8337 +Const GL_PIXEL_TRANSFORM_2D_MATRIX_EXT=$8338 +Global glGetPixelTransformParameterfvEXT(target_:Int,pname_:Int,params_:Float Ptr)="__glewGetPixelTransformParameterfvEXT" +Global glGetPixelTransformParameterivEXT(target_:Int,pname_:Int,params_:Int Ptr)="__glewGetPixelTransformParameterivEXT" +Global glPixelTransformParameterfEXT(target_:Int,pname_:Int,param_:Float)="__glewPixelTransformParameterfEXT" +Global glPixelTransformParameterfvEXT(target_:Int,pname_:Int,params_:Float Ptr)="__glewPixelTransformParameterfvEXT" +Global glPixelTransformParameteriEXT(target_:Int,pname_:Int,param_:Int)="__glewPixelTransformParameteriEXT" +Global glPixelTransformParameterivEXT(target_:Int,pname_:Int,params_:Int Ptr)="__glewPixelTransformParameterivEXT" +Global GL_EXT_pixel_transform:Byte="__GLEW_EXT_pixel_transform" +Global GL_EXT_pixel_transform_color_table:Byte="__GLEW_EXT_pixel_transform_color_table" +Const GL_POINT_SIZE_MIN_EXT=$8126 +Const GL_POINT_SIZE_MAX_EXT=$8127 +Const GL_POINT_FADE_THRESHOLD_SIZE_EXT=$8128 +Const GL_DISTANCE_ATTENUATION_EXT=$8129 +Global glPointParameterfEXT(pname_:Int,param_:Float)="__glewPointParameterfEXT" +Global glPointParameterfvEXT(pname_:Int,params_:Float Ptr)="__glewPointParameterfvEXT" +Global GL_EXT_point_parameters:Byte="__GLEW_EXT_point_parameters" +Const GL_POLYGON_OFFSET_EXT=$8037 +Const GL_POLYGON_OFFSET_FACTOR_EXT=$8038 +Const GL_POLYGON_OFFSET_BIAS_EXT=$8039 +Global glPolygonOffsetEXT(factor_:Float,bias_:Float)="__glewPolygonOffsetEXT" +Global GL_EXT_polygon_offset:Byte="__GLEW_EXT_polygon_offset" +Const GL_RESCALE_NORMAL_EXT=$803A +Global GL_EXT_rescale_normal:Byte="__GLEW_EXT_rescale_normal" +Global glBeginSceneEXT()="__glewBeginSceneEXT" +Global glEndSceneEXT()="__glewEndSceneEXT" +Global GL_EXT_scene_marker:Byte="__GLEW_EXT_scene_marker" +Const GL_COLOR_SUM_EXT=$8458 +Const GL_CURRENT_SECONDARY_COLOR_EXT=$8459 +Const GL_SECONDARY_COLOR_ARRAY_SIZE_EXT=$845A +Const GL_SECONDARY_COLOR_ARRAY_TYPE_EXT=$845B +Const GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT=$845C +Const GL_SECONDARY_COLOR_ARRAY_POINTER_EXT=$845D +Const GL_SECONDARY_COLOR_ARRAY_EXT=$845E +Global glSecondaryColor3bEXT(red_:Byte,green_:Byte,blue_:Byte)="__glewSecondaryColor3bEXT" +Global glSecondaryColor3bvEXT(v_:Byte Ptr)="__glewSecondaryColor3bvEXT" +Global glSecondaryColor3dEXT(red_:Double,green_:Double,blue_:Double)="__glewSecondaryColor3dEXT" +Global glSecondaryColor3dvEXT(v_:Double Ptr)="__glewSecondaryColor3dvEXT" +Global glSecondaryColor3fEXT(red_:Float,green_:Float,blue_:Float)="__glewSecondaryColor3fEXT" +Global glSecondaryColor3fvEXT(v_:Float Ptr)="__glewSecondaryColor3fvEXT" +Global glSecondaryColor3iEXT(red_:Int,green_:Int,blue_:Int)="__glewSecondaryColor3iEXT" +Global glSecondaryColor3ivEXT(v_:Int Ptr)="__glewSecondaryColor3ivEXT" +Global glSecondaryColor3sEXT(red_:Short,green_:Short,blue_:Short)="__glewSecondaryColor3sEXT" +Global glSecondaryColor3svEXT(v_:Short Ptr)="__glewSecondaryColor3svEXT" +Global glSecondaryColor3ubEXT(red_:Byte,green_:Byte,blue_:Byte)="__glewSecondaryColor3ubEXT" +Global glSecondaryColor3ubvEXT(v_:Byte Ptr)="__glewSecondaryColor3ubvEXT" +Global glSecondaryColor3uiEXT(red_:Int,green_:Int,blue_:Int)="__glewSecondaryColor3uiEXT" +Global glSecondaryColor3uivEXT(v_:Int Ptr)="__glewSecondaryColor3uivEXT" +Global glSecondaryColor3usEXT(red_:Short,green_:Short,blue_:Short)="__glewSecondaryColor3usEXT" +Global glSecondaryColor3usvEXT(v_:Short Ptr)="__glewSecondaryColor3usvEXT" +Global glSecondaryColorPointerEXT(size_:Int,type_:Int,stride_:Int,pointer_:Byte Ptr)="__glewSecondaryColorPointerEXT" +Global GL_EXT_secondary_color:Byte="__GLEW_EXT_secondary_color" +Const GL_LIGHT_MODEL_COLOR_CONTROL_EXT=$81F8 +Const GL_SINGLE_COLOR_EXT=$81F9 +Const GL_SEPARATE_SPECULAR_COLOR_EXT=$81FA +Global GL_EXT_separate_specular_color:Byte="__GLEW_EXT_separate_specular_color" +Global GL_EXT_shadow_funcs:Byte="__GLEW_EXT_shadow_funcs" +Const GL_SHARED_TEXTURE_PALETTE_EXT=$81FB +Global GL_EXT_shared_texture_palette:Byte="__GLEW_EXT_shared_texture_palette" +Const GL_STENCIL_TAG_BITS_EXT=$88F2 +Const GL_STENCIL_CLEAR_TAG_VALUE_EXT=$88F3 +Global GL_EXT_stencil_clear_tag:Byte="__GLEW_EXT_stencil_clear_tag" +Const GL_STENCIL_TEST_TWO_SIDE_EXT=$8910 +Const GL_ACTIVE_STENCIL_FACE_EXT=$8911 +Global glActiveStencilFaceEXT(face_:Int)="__glewActiveStencilFaceEXT" +Global GL_EXT_stencil_two_side:Byte="__GLEW_EXT_stencil_two_side" +Const GL_INCR_WRAP_EXT=$8507 +Const GL_DECR_WRAP_EXT=$8508 +Global GL_EXT_stencil_wrap:Byte="__GLEW_EXT_stencil_wrap" +Global glTexSubImage1DEXT(target_:Int,level_:Int,xoffset_:Int,width_:Int,format_:Int,type_:Int,pixels_:Byte Ptr)="__glewTexSubImage1DEXT" +Global glTexSubImage2DEXT(target_:Int,level_:Int,xoffset_:Int,yoffset_:Int,width_:Int,height_:Int,format_:Int,type_:Int,pixels_:Byte Ptr)="__glewTexSubImage2DEXT" +Global glTexSubImage3DEXT(target_:Int,level_:Int,xoffset_:Int,yoffset_:Int,zoffset_:Int,width_:Int,height_:Int,depth_:Int,format_:Int,type_:Int,pixels_:Byte Ptr)="__glewTexSubImage3DEXT" +Global GL_EXT_subtexture:Byte="__GLEW_EXT_subtexture" +Const GL_ALPHA4_EXT=$803B +Const GL_ALPHA8_EXT=$803C +Const GL_ALPHA12_EXT=$803D +Const GL_ALPHA16_EXT=$803E +Const GL_LUMINANCE4_EXT=$803F +Const GL_LUMINANCE8_EXT=$8040 +Const GL_LUMINANCE12_EXT=$8041 +Const GL_LUMINANCE16_EXT=$8042 +Const GL_LUMINANCE4_ALPHA4_EXT=$8043 +Const GL_LUMINANCE6_ALPHA2_EXT=$8044 +Const GL_LUMINANCE8_ALPHA8_EXT=$8045 +Const GL_LUMINANCE12_ALPHA4_EXT=$8046 +Const GL_LUMINANCE12_ALPHA12_EXT=$8047 +Const GL_LUMINANCE16_ALPHA16_EXT=$8048 +Const GL_INTENSITY_EXT=$8049 +Const GL_INTENSITY4_EXT=$804A +Const GL_INTENSITY8_EXT=$804B +Const GL_INTENSITY12_EXT=$804C +Const GL_INTENSITY16_EXT=$804D +Const GL_RGB2_EXT=$804E +Const GL_RGB4_EXT=$804F +Const GL_RGB5_EXT=$8050 +Const GL_RGB8_EXT=$8051 +Const GL_RGB10_EXT=$8052 +Const GL_RGB12_EXT=$8053 +Const GL_RGB16_EXT=$8054 +Const GL_RGBA2_EXT=$8055 +Const GL_RGBA4_EXT=$8056 +Const GL_RGB5_A1_EXT=$8057 +Const GL_RGBA8_EXT=$8058 +Const GL_RGB10_A2_EXT=$8059 +Const GL_RGBA12_EXT=$805A +Const GL_RGBA16_EXT=$805B +Const GL_TEXTURE_RED_SIZE_EXT=$805C +Const GL_TEXTURE_GREEN_SIZE_EXT=$805D +Const GL_TEXTURE_BLUE_SIZE_EXT=$805E +Const GL_TEXTURE_ALPHA_SIZE_EXT=$805F +Const GL_TEXTURE_LUMINANCE_SIZE_EXT=$8060 +Const GL_TEXTURE_INTENSITY_SIZE_EXT=$8061 +Const GL_REPLACE_EXT=$8062 +Const GL_PROXY_TEXTURE_1D_EXT=$8063 +Const GL_PROXY_TEXTURE_2D_EXT=$8064 +Global GL_EXT_texture:Byte="__GLEW_EXT_texture" +Const GL_PACK_SKIP_IMAGES_EXT=$806B +Const GL_PACK_IMAGE_HEIGHT_EXT=$806C +Const GL_UNPACK_SKIP_IMAGES_EXT=$806D +Const GL_UNPACK_IMAGE_HEIGHT_EXT=$806E +Const GL_TEXTURE_DEPTH_EXT=$8071 +Const GL_TEXTURE_WRAP_R_EXT=$8072 +Const GL_MAX_3D_TEXTURE_SIZE_EXT=$8073 +Global glTexImage3DEXT(target_:Int,level_:Int,internalformat_:Int,width_:Int,height_:Int,depth_:Int,border_:Int,format_:Int,type_:Int,pixels_:Byte Ptr)="__glewTexImage3DEXT" +Global GL_EXT_texture3D:Byte="__GLEW_EXT_texture3D" +Const GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT=$884E +Const GL_MAX_ARRAY_TEXTURE_LAYERS_EXT=$88FF +Const GL_TEXTURE_1D_ARRAY_EXT=$8C18 +Const GL_PROXY_TEXTURE_1D_ARRAY_EXT=$8C19 +Const GL_TEXTURE_2D_ARRAY_EXT=$8C1A +Const GL_PROXY_TEXTURE_2D_ARRAY_EXT=$8C1B +Const GL_TEXTURE_BINDING_1D_ARRAY_EXT=$8C1C +Const GL_TEXTURE_BINDING_2D_ARRAY_EXT=$8C1D +Global GL_EXT_texture_array:Byte="__GLEW_EXT_texture_array" +Const GL_TEXTURE_BUFFER_EXT=$8C2A +Const GL_MAX_TEXTURE_BUFFER_SIZE_EXT=$8C2B +Const GL_TEXTURE_BINDING_BUFFER_EXT=$8C2C +Const GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT=$8C2D +Const GL_TEXTURE_BUFFER_FORMAT_EXT=$8C2E +Global glTexBufferEXT(target_:Int,internalformat_:Int,buffer_:Int)="__glewTexBufferEXT" +Global GL_EXT_texture_buffer_object:Byte="__GLEW_EXT_texture_buffer_object" +Const GL_COMPRESSED_RGB_S3TC_DXT1_EXT=$83F0 +Const GL_COMPRESSED_RGBA_S3TC_DXT1_EXT=$83F1 +Global GL_EXT_texture_compression_dxt1:Byte="__GLEW_EXT_texture_compression_dxt1" +Const GL_COMPRESSED_LUMINANCE_LATC1_EXT=$8C70 +Const GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT=$8C71 +Const GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT=$8C72 +Const GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT=$8C73 +Global GL_EXT_texture_compression_latc:Byte="__GLEW_EXT_texture_compression_latc" +Const GL_COMPRESSED_RED_RGTC1_EXT=$8DBB +Const GL_COMPRESSED_SIGNED_RED_RGTC1_EXT=$8DBC +Const GL_COMPRESSED_RED_GREEN_RGTC2_EXT=$8DBD +Const GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT=$8DBE +Global GL_EXT_texture_compression_rgtc:Byte="__GLEW_EXT_texture_compression_rgtc" +Const GL_COMPRESSED_RGBA_S3TC_DXT3_EXT=$83F2 +Const GL_COMPRESSED_RGBA_S3TC_DXT5_EXT=$83F3 +Global GL_EXT_texture_compression_s3tc:Byte="__GLEW_EXT_texture_compression_s3tc" +Const GL_NORMAL_MAP_EXT=$8511 +Const GL_REFLECTION_MAP_EXT=$8512 +Const GL_TEXTURE_CUBE_MAP_EXT=$8513 +Const GL_TEXTURE_BINDING_CUBE_MAP_EXT=$8514 +Const GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT=$8515 +Const GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT=$8516 +Const GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT=$8517 +Const GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT=$8518 +Const GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT=$8519 +Const GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT=$851A +Const GL_PROXY_TEXTURE_CUBE_MAP_EXT=$851B +Const GL_MAX_CUBE_MAP_TEXTURE_SIZE_EXT=$851C +Global GL_EXT_texture_cube_map:Byte="__GLEW_EXT_texture_cube_map" +Const GL_CLAMP_TO_EDGE_EXT=$812F +Global GL_EXT_texture_edge_clamp:Byte="__GLEW_EXT_texture_edge_clamp" +Const GL_TEXTURE_ENV0_EXT=0 +Const GL_ENV_BLEND_EXT=0 +Const GL_TEXTURE_ENV_SHIFT_EXT=0 +Const GL_ENV_REPLACE_EXT=0 +Const GL_ENV_ADD_EXT=0 +Const GL_ENV_SUBTRACT_EXT=0 +Const GL_TEXTURE_ENV_MODE_ALPHA_EXT=0 +Const GL_ENV_REVERSE_SUBTRACT_EXT=0 +Const GL_ENV_REVERSE_BLEND_EXT=0 +Const GL_ENV_COPY_EXT=0 +Const GL_ENV_MODULATE_EXT=0 +Global GL_EXT_texture_env:Byte="__GLEW_EXT_texture_env" +Global GL_EXT_texture_env_add:Byte="__GLEW_EXT_texture_env_add" +Const GL_COMBINE_EXT=$8570 +Const GL_COMBINE_RGB_EXT=$8571 +Const GL_COMBINE_ALPHA_EXT=$8572 +Const GL_RGB_SCALE_EXT=$8573 +Const GL_ADD_SIGNED_EXT=$8574 +Const GL_INTERPOLATE_EXT=$8575 +Const GL_CONSTANT_EXT=$8576 +Const GL_PRIMARY_COLOR_EXT=$8577 +Const GL_PREVIOUS_EXT=$8578 +Const GL_SOURCE0_RGB_EXT=$8580 +Const GL_SOURCE1_RGB_EXT=$8581 +Const GL_SOURCE2_RGB_EXT=$8582 +Const GL_SOURCE0_ALPHA_EXT=$8588 +Const GL_SOURCE1_ALPHA_EXT=$8589 +Const GL_SOURCE2_ALPHA_EXT=$858A +Const GL_OPERAND0_RGB_EXT=$8590 +Const GL_OPERAND1_RGB_EXT=$8591 +Const GL_OPERAND2_RGB_EXT=$8592 +Const GL_OPERAND0_ALPHA_EXT=$8598 +Const GL_OPERAND1_ALPHA_EXT=$8599 +Const GL_OPERAND2_ALPHA_EXT=$859A +Global GL_EXT_texture_env_combine:Byte="__GLEW_EXT_texture_env_combine" +Const GL_DOT3_RGB_EXT=$8740 +Const GL_DOT3_RGBA_EXT=$8741 +Global GL_EXT_texture_env_dot3:Byte="__GLEW_EXT_texture_env_dot3" +Const GL_TEXTURE_MAX_ANISOTROPY_EXT=$84FE +Const GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT=$84FF +Global GL_EXT_texture_filter_anisotropic:Byte="__GLEW_EXT_texture_filter_anisotropic" +Const GL_RGBA32UI_EXT=$8D70 +Const GL_RGB32UI_EXT=$8D71 +Const GL_ALPHA32UI_EXT=$8D72 +Const GL_INTENSITY32UI_EXT=$8D73 +Const GL_LUMINANCE32UI_EXT=$8D74 +Const GL_LUMINANCE_ALPHA32UI_EXT=$8D75 +Const GL_RGBA16UI_EXT=$8D76 +Const GL_RGB16UI_EXT=$8D77 +Const GL_ALPHA16UI_EXT=$8D78 +Const GL_INTENSITY16UI_EXT=$8D79 +Const GL_LUMINANCE16UI_EXT=$8D7A +Const GL_LUMINANCE_ALPHA16UI_EXT=$8D7B +Const GL_RGBA8UI_EXT=$8D7C +Const GL_RGB8UI_EXT=$8D7D +Const GL_ALPHA8UI_EXT=$8D7E +Const GL_INTENSITY8UI_EXT=$8D7F +Const GL_LUMINANCE8UI_EXT=$8D80 +Const GL_LUMINANCE_ALPHA8UI_EXT=$8D81 +Const GL_RGBA32I_EXT=$8D82 +Const GL_RGB32I_EXT=$8D83 +Const GL_ALPHA32I_EXT=$8D84 +Const GL_INTENSITY32I_EXT=$8D85 +Const GL_LUMINANCE32I_EXT=$8D86 +Const GL_LUMINANCE_ALPHA32I_EXT=$8D87 +Const GL_RGBA16I_EXT=$8D88 +Const GL_RGB16I_EXT=$8D89 +Const GL_ALPHA16I_EXT=$8D8A +Const GL_INTENSITY16I_EXT=$8D8B +Const GL_LUMINANCE16I_EXT=$8D8C +Const GL_LUMINANCE_ALPHA16I_EXT=$8D8D +Const GL_RGBA8I_EXT=$8D8E +Const GL_RGB8I_EXT=$8D8F +Const GL_ALPHA8I_EXT=$8D90 +Const GL_INTENSITY8I_EXT=$8D91 +Const GL_LUMINANCE8I_EXT=$8D92 +Const GL_LUMINANCE_ALPHA8I_EXT=$8D93 +Const GL_RED_INTEGER_EXT=$8D94 +Const GL_GREEN_INTEGER_EXT=$8D95 +Const GL_BLUE_INTEGER_EXT=$8D96 +Const GL_ALPHA_INTEGER_EXT=$8D97 +Const GL_RGB_INTEGER_EXT=$8D98 +Const GL_RGBA_INTEGER_EXT=$8D99 +Const GL_BGR_INTEGER_EXT=$8D9A +Const GL_BGRA_INTEGER_EXT=$8D9B +Const GL_LUMINANCE_INTEGER_EXT=$8D9C +Const GL_LUMINANCE_ALPHA_INTEGER_EXT=$8D9D +Const GL_RGBA_INTEGER_MODE_EXT=$8D9E +Global glClearColorIiEXT(red_:Int,green_:Int,blue_:Int,alpha_:Int)="__glewClearColorIiEXT" +Global glClearColorIuiEXT(red_:Int,green_:Int,blue_:Int,alpha_:Int)="__glewClearColorIuiEXT" +Global glGetTexParameterIivEXT(target_:Int,pname_:Int,params_:Int Ptr)="__glewGetTexParameterIivEXT" +Global glGetTexParameterIuivEXT(target_:Int,pname_:Int,params_:Int Ptr)="__glewGetTexParameterIuivEXT" +Global glTexParameterIivEXT(target_:Int,pname_:Int,params_:Int Ptr)="__glewTexParameterIivEXT" +Global glTexParameterIuivEXT(target_:Int,pname_:Int,params_:Int Ptr)="__glewTexParameterIuivEXT" +Global GL_EXT_texture_integer:Byte="__GLEW_EXT_texture_integer" +Const GL_MAX_TEXTURE_LOD_BIAS_EXT=$84FD +Const GL_TEXTURE_FILTER_CONTROL_EXT=$8500 +Const GL_TEXTURE_LOD_BIAS_EXT=$8501 +Global GL_EXT_texture_lod_bias:Byte="__GLEW_EXT_texture_lod_bias" +Const GL_MIRROR_CLAMP_EXT=$8742 +Const GL_MIRROR_CLAMP_TO_EDGE_EXT=$8743 +Const GL_MIRROR_CLAMP_TO_BORDER_EXT=$8912 +Global GL_EXT_texture_mirror_clamp:Byte="__GLEW_EXT_texture_mirror_clamp" +Const GL_TEXTURE_PRIORITY_EXT=$8066 +Const GL_TEXTURE_RESIDENT_EXT=$8067 +Const GL_TEXTURE_1D_BINDING_EXT=$8068 +Const GL_TEXTURE_2D_BINDING_EXT=$8069 +Const GL_TEXTURE_3D_BINDING_EXT=$806A +Global glAreTexturesResidentEXT:Byte(n_:Int,textures_:Int Ptr,residences_:Byte Ptr)="__glewAreTexturesResidentEXT" +Global glBindTextureEXT(target_:Int,texture_:Int)="__glewBindTextureEXT" +Global glDeleteTexturesEXT(n_:Int,textures_:Int Ptr)="__glewDeleteTexturesEXT" +Global glGenTexturesEXT(n_:Int,textures_:Int Ptr)="__glewGenTexturesEXT" +Global glIsTextureEXT:Byte(texture_:Int)="__glewIsTextureEXT" +Global glPrioritizeTexturesEXT(n_:Int,textures_:Int Ptr,priorities_:Float Ptr)="__glewPrioritizeTexturesEXT" +Global GL_EXT_texture_object:Byte="__GLEW_EXT_texture_object" +Const GL_PERTURB_EXT=$85AE +Const GL_TEXTURE_NORMAL_EXT=$85AF +Global glTextureNormalEXT(mode_:Int)="__glewTextureNormalEXT" +Global GL_EXT_texture_perturb_normal:Byte="__GLEW_EXT_texture_perturb_normal" +Const GL_TEXTURE_RECTANGLE_EXT=$84F5 +Const GL_TEXTURE_BINDING_RECTANGLE_EXT=$84F6 +Const GL_PROXY_TEXTURE_RECTANGLE_EXT=$84F7 +Const GL_MAX_RECTANGLE_TEXTURE_SIZE_EXT=$84F8 +Global GL_EXT_texture_rectangle:Byte="__GLEW_EXT_texture_rectangle" +Const GL_SRGB_EXT=$8C40 +Const GL_SRGB8_EXT=$8C41 +Const GL_SRGB_ALPHA_EXT=$8C42 +Const GL_SRGB8_ALPHA8_EXT=$8C43 +Const GL_SLUMINANCE_ALPHA_EXT=$8C44 +Const GL_SLUMINANCE8_ALPHA8_EXT=$8C45 +Const GL_SLUMINANCE_EXT=$8C46 +Const GL_SLUMINANCE8_EXT=$8C47 +Const GL_COMPRESSED_SRGB_EXT=$8C48 +Const GL_COMPRESSED_SRGB_ALPHA_EXT=$8C49 +Const GL_COMPRESSED_SLUMINANCE_EXT=$8C4A +Const GL_COMPRESSED_SLUMINANCE_ALPHA_EXT=$8C4B +Const GL_COMPRESSED_SRGB_S3TC_DXT1_EXT=$8C4C +Const GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT=$8C4D +Const GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT=$8C4E +Const GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT=$8C4F +Global GL_EXT_texture_sRGB:Byte="__GLEW_EXT_texture_sRGB" +Const GL_RGB9_E5_EXT=$8C3D +Const GL_UNSIGNED_INT_5_9_9_9_REV_EXT=$8C3E +Const GL_TEXTURE_SHARED_SIZE_EXT=$8C3F +Global GL_EXT_texture_shared_exponent:Byte="__GLEW_EXT_texture_shared_exponent" +Const GL_TEXTURE_SWIZZLE_R_EXT=$8E42 +Const GL_TEXTURE_SWIZZLE_G_EXT=$8E43 +Const GL_TEXTURE_SWIZZLE_B_EXT=$8E44 +Const GL_TEXTURE_SWIZZLE_A_EXT=$8E45 +Const GL_TEXTURE_SWIZZLE_RGBA_EXT=$8E46 +Global GL_EXT_texture_swizzle:Byte="__GLEW_EXT_texture_swizzle" +Const GL_TIME_ELAPSED_EXT=$88BF +Global glGetQueryObjecti64vEXT(id_:Int,pname_:Int,params_:Long Ptr)="__glewGetQueryObjecti64vEXT" +Global glGetQueryObjectui64vEXT(id_:Int,pname_:Int,params_:Long Ptr)="__glewGetQueryObjectui64vEXT" +Global GL_EXT_timer_query:Byte="__GLEW_EXT_timer_query" +Const GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH_EXT=$8C76 +Const GL_TRANSFORM_FEEDBACK_BUFFER_MODE_EXT=$8C7F +Const GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_EXT=$8C80 +Const GL_TRANSFORM_FEEDBACK_VARYINGS_EXT=$8C83 +Const GL_TRANSFORM_FEEDBACK_BUFFER_START_EXT=$8C84 +Const GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_EXT=$8C85 +Const GL_PRIMITIVES_GENERATED_EXT=$8C87 +Const GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_EXT=$8C88 +Const GL_RASTERIZER_DISCARD_EXT=$8C89 +Const GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_EXT=$8C8A +Const GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_EXT=$8C8B +Const GL_INTERLEAVED_ATTRIBS_EXT=$8C8C +Const GL_SEPARATE_ATTRIBS_EXT=$8C8D +Const GL_TRANSFORM_FEEDBACK_BUFFER_EXT=$8C8E +Const GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_EXT=$8C8F +Global glBeginTransformFeedbackEXT(primitiveMode_:Int)="__glewBeginTransformFeedbackEXT" +Global glBindBufferBaseEXT(target_:Int,index_:Int,buffer_:Int)="__glewBindBufferBaseEXT" +Global glBindBufferOffsetEXT(target_:Int,index_:Int,buffer_:Int,offset_:Int)="__glewBindBufferOffsetEXT" +Global glBindBufferRangeEXT(target_:Int,index_:Int,buffer_:Int,offset_:Int,size_:Int)="__glewBindBufferRangeEXT" +Global glEndTransformFeedbackEXT()="__glewEndTransformFeedbackEXT" +Global glGetTransformFeedbackVaryingEXT(program_:Int,index_:Int,bufSize_:Int,length_:Int Ptr,size_:Int Ptr,type_:Int Ptr,name_:Byte Ptr)="__glewGetTransformFeedbackVaryingEXT" +Global glTransformFeedbackVaryingsEXT(program_:Int,count_:Int,varyings_:Byte Ptr Ptr,bufferMode_:Int)="__glewTransformFeedbackVaryingsEXT" +Global GL_EXT_transform_feedback:Byte="__GLEW_EXT_transform_feedback" +Const GL_DOUBLE_EXT=$140A +Const GL_VERTEX_ARRAY_EXT=$8074 +Const GL_NORMAL_ARRAY_EXT=$8075 +Const GL_COLOR_ARRAY_EXT=$8076 +Const GL_INDEX_ARRAY_EXT=$8077 +Const GL_TEXTURE_COORD_ARRAY_EXT=$8078 +Const GL_EDGE_FLAG_ARRAY_EXT=$8079 +Const GL_VERTEX_ARRAY_SIZE_EXT=$807A +Const GL_VERTEX_ARRAY_TYPE_EXT=$807B +Const GL_VERTEX_ARRAY_STRIDE_EXT=$807C +Const GL_VERTEX_ARRAY_COUNT_EXT=$807D +Const GL_NORMAL_ARRAY_TYPE_EXT=$807E +Const GL_NORMAL_ARRAY_STRIDE_EXT=$807F +Const GL_NORMAL_ARRAY_COUNT_EXT=$8080 +Const GL_COLOR_ARRAY_SIZE_EXT=$8081 +Const GL_COLOR_ARRAY_TYPE_EXT=$8082 +Const GL_COLOR_ARRAY_STRIDE_EXT=$8083 +Const GL_COLOR_ARRAY_COUNT_EXT=$8084 +Const GL_INDEX_ARRAY_TYPE_EXT=$8085 +Const GL_INDEX_ARRAY_STRIDE_EXT=$8086 +Const GL_INDEX_ARRAY_COUNT_EXT=$8087 +Const GL_TEXTURE_COORD_ARRAY_SIZE_EXT=$8088 +Const GL_TEXTURE_COORD_ARRAY_TYPE_EXT=$8089 +Const GL_TEXTURE_COORD_ARRAY_STRIDE_EXT=$808A +Const GL_TEXTURE_COORD_ARRAY_COUNT_EXT=$808B +Const GL_EDGE_FLAG_ARRAY_STRIDE_EXT=$808C +Const GL_EDGE_FLAG_ARRAY_COUNT_EXT=$808D +Const GL_VERTEX_ARRAY_POINTER_EXT=$808E +Const GL_NORMAL_ARRAY_POINTER_EXT=$808F +Const GL_COLOR_ARRAY_POINTER_EXT=$8090 +Const GL_INDEX_ARRAY_POINTER_EXT=$8091 +Const GL_TEXTURE_COORD_ARRAY_POINTER_EXT=$8092 +Const GL_EDGE_FLAG_ARRAY_POINTER_EXT=$8093 +Global glArrayElementEXT(i_:Int)="__glewArrayElementEXT" +Global glColorPointerEXT(size_:Int,type_:Int,stride_:Int,count_:Int,pointer_:Byte Ptr)="__glewColorPointerEXT" +Global glDrawArraysEXT(mode_:Int,first_:Int,count_:Int)="__glewDrawArraysEXT" +Global glEdgeFlagPointerEXT(stride_:Int,count_:Int,pointer_:Byte Ptr)="__glewEdgeFlagPointerEXT" +Global glGetPointervEXT(pname_:Int,params_:Byte Ptr Ptr)="__glewGetPointervEXT" +Global glIndexPointerEXT(type_:Int,stride_:Int,count_:Int,pointer_:Byte Ptr)="__glewIndexPointerEXT" +Global glNormalPointerEXT(type_:Int,stride_:Int,count_:Int,pointer_:Byte Ptr)="__glewNormalPointerEXT" +Global glTexCoordPointerEXT(size_:Int,type_:Int,stride_:Int,count_:Int,pointer_:Byte Ptr)="__glewTexCoordPointerEXT" +Global glVertexPointerEXT(size_:Int,type_:Int,stride_:Int,count_:Int,pointer_:Byte Ptr)="__glewVertexPointerEXT" +Global GL_EXT_vertex_array:Byte="__GLEW_EXT_vertex_array" +Global GL_EXT_vertex_array_bgra:Byte="__GLEW_EXT_vertex_array_bgra" +Const GL_VERTEX_SHADER_EXT=$8780 +Const GL_VERTEX_SHADER_BINDING_EXT=$8781 +Const GL_OP_INDEX_EXT=$8782 +Const GL_OP_NEGATE_EXT=$8783 +Const GL_OP_DOT3_EXT=$8784 +Const GL_OP_DOT4_EXT=$8785 +Const GL_OP_MUL_EXT=$8786 +Const GL_OP_ADD_EXT=$8787 +Const GL_OP_MADD_EXT=$8788 +Const GL_OP_FRAC_EXT=$8789 +Const GL_OP_MAX_EXT=$878A +Const GL_OP_MIN_EXT=$878B +Const GL_OP_SET_GE_EXT=$878C +Const GL_OP_SET_LT_EXT=$878D +Const GL_OP_CLAMP_EXT=$878E +Const GL_OP_FLOOR_EXT=$878F +Const GL_OP_ROUND_EXT=$8790 +Const GL_OP_EXP_BASE_2_EXT=$8791 +Const GL_OP_LOG_BASE_2_EXT=$8792 +Const GL_OP_POWER_EXT=$8793 +Const GL_OP_RECIP_EXT=$8794 +Const GL_OP_RECIP_SQRT_EXT=$8795 +Const GL_OP_SUB_EXT=$8796 +Const GL_OP_CROSS_PRODUCT_EXT=$8797 +Const GL_OP_MULTIPLY_MATRIX_EXT=$8798 +Const GL_OP_MOV_EXT=$8799 +Const GL_OUTPUT_VERTEX_EXT=$879A +Const GL_OUTPUT_COLOR0_EXT=$879B +Const GL_OUTPUT_COLOR1_EXT=$879C +Const GL_OUTPUT_TEXTURE_COORD0_EXT=$879D +Const GL_OUTPUT_TEXTURE_COORD1_EXT=$879E +Const GL_OUTPUT_TEXTURE_COORD2_EXT=$879F +Const GL_OUTPUT_TEXTURE_COORD3_EXT=$87A0 +Const GL_OUTPUT_TEXTURE_COORD4_EXT=$87A1 +Const GL_OUTPUT_TEXTURE_COORD5_EXT=$87A2 +Const GL_OUTPUT_TEXTURE_COORD6_EXT=$87A3 +Const GL_OUTPUT_TEXTURE_COORD7_EXT=$87A4 +Const GL_OUTPUT_TEXTURE_COORD8_EXT=$87A5 +Const GL_OUTPUT_TEXTURE_COORD9_EXT=$87A6 +Const GL_OUTPUT_TEXTURE_COORD10_EXT=$87A7 +Const GL_OUTPUT_TEXTURE_COORD11_EXT=$87A8 +Const GL_OUTPUT_TEXTURE_COORD12_EXT=$87A9 +Const GL_OUTPUT_TEXTURE_COORD13_EXT=$87AA +Const GL_OUTPUT_TEXTURE_COORD14_EXT=$87AB +Const GL_OUTPUT_TEXTURE_COORD15_EXT=$87AC +Const GL_OUTPUT_TEXTURE_COORD16_EXT=$87AD +Const GL_OUTPUT_TEXTURE_COORD17_EXT=$87AE +Const GL_OUTPUT_TEXTURE_COORD18_EXT=$87AF +Const GL_OUTPUT_TEXTURE_COORD19_EXT=$87B0 +Const GL_OUTPUT_TEXTURE_COORD20_EXT=$87B1 +Const GL_OUTPUT_TEXTURE_COORD21_EXT=$87B2 +Const GL_OUTPUT_TEXTURE_COORD22_EXT=$87B3 +Const GL_OUTPUT_TEXTURE_COORD23_EXT=$87B4 +Const GL_OUTPUT_TEXTURE_COORD24_EXT=$87B5 +Const GL_OUTPUT_TEXTURE_COORD25_EXT=$87B6 +Const GL_OUTPUT_TEXTURE_COORD26_EXT=$87B7 +Const GL_OUTPUT_TEXTURE_COORD27_EXT=$87B8 +Const GL_OUTPUT_TEXTURE_COORD28_EXT=$87B9 +Const GL_OUTPUT_TEXTURE_COORD29_EXT=$87BA +Const GL_OUTPUT_TEXTURE_COORD30_EXT=$87BB +Const GL_OUTPUT_TEXTURE_COORD31_EXT=$87BC +Const GL_OUTPUT_FOG_EXT=$87BD +Const GL_SCALAR_EXT=$87BE +Const GL_VECTOR_EXT=$87BF +Const GL_MATRIX_EXT=$87C0 +Const GL_VARIANT_EXT=$87C1 +Const GL_INVARIANT_EXT=$87C2 +Const GL_LOCAL_CONSTANT_EXT=$87C3 +Const GL_LOCAL_EXT=$87C4 +Const GL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT=$87C5 +Const GL_MAX_VERTEX_SHADER_VARIANTS_EXT=$87C6 +Const GL_MAX_VERTEX_SHADER_INVARIANTS_EXT=$87C7 +Const GL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT=$87C8 +Const GL_MAX_VERTEX_SHADER_LOCALS_EXT=$87C9 +Const GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT=$87CA +Const GL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT=$87CB +Const GL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT=$87CC +Const GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT=$87CD +Const GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT=$87CE +Const GL_VERTEX_SHADER_INSTRUCTIONS_EXT=$87CF +Const GL_VERTEX_SHADER_VARIANTS_EXT=$87D0 +Const GL_VERTEX_SHADER_INVARIANTS_EXT=$87D1 +Const GL_VERTEX_SHADER_LOCAL_CONSTANTS_EXT=$87D2 +Const GL_VERTEX_SHADER_LOCALS_EXT=$87D3 +Const GL_VERTEX_SHADER_OPTIMIZED_EXT=$87D4 +Const GL_X_EXT=$87D5 +Const GL_Y_EXT=$87D6 +Const GL_Z_EXT=$87D7 +Const GL_W_EXT=$87D8 +Const GL_NEGATIVE_X_EXT=$87D9 +Const GL_NEGATIVE_Y_EXT=$87DA +Const GL_NEGATIVE_Z_EXT=$87DB +Const GL_NEGATIVE_W_EXT=$87DC +Const GL_ZERO_EXT=$87DD +Const GL_ONE_EXT=$87DE +Const GL_NEGATIVE_ONE_EXT=$87DF +Const GL_NORMALIZED_RANGE_EXT=$87E0 +Const GL_FULL_RANGE_EXT=$87E1 +Const GL_CURRENT_VERTEX_EXT=$87E2 +Const GL_MVP_MATRIX_EXT=$87E3 +Const GL_VARIANT_VALUE_EXT=$87E4 +Const GL_VARIANT_DATATYPE_EXT=$87E5 +Const GL_VARIANT_ARRAY_STRIDE_EXT=$87E6 +Const GL_VARIANT_ARRAY_TYPE_EXT=$87E7 +Const GL_VARIANT_ARRAY_EXT=$87E8 +Const GL_VARIANT_ARRAY_POINTER_EXT=$87E9 +Const GL_INVARIANT_VALUE_EXT=$87EA +Const GL_INVARIANT_DATATYPE_EXT=$87EB +Const GL_LOCAL_CONSTANT_VALUE_EXT=$87EC +Const GL_LOCAL_CONSTANT_DATATYPE_EXT=$87ED +Global glBeginVertexShaderEXT()="__glewBeginVertexShaderEXT" +Global glBindLightParameterEXT:Int(light_:Int,value_:Int)="__glewBindLightParameterEXT" +Global glBindMaterialParameterEXT:Int(face_:Int,value_:Int)="__glewBindMaterialParameterEXT" +Global glBindParameterEXT:Int(value_:Int)="__glewBindParameterEXT" +Global glBindTexGenParameterEXT:Int(unit_:Int,coord_:Int,value_:Int)="__glewBindTexGenParameterEXT" +Global glBindTextureUnitParameterEXT:Int(unit_:Int,value_:Int)="__glewBindTextureUnitParameterEXT" +Global glBindVertexShaderEXT(id_:Int)="__glewBindVertexShaderEXT" +Global glDeleteVertexShaderEXT(id_:Int)="__glewDeleteVertexShaderEXT" +Global glDisableVariantClientStateEXT(id_:Int)="__glewDisableVariantClientStateEXT" +Global glEnableVariantClientStateEXT(id_:Int)="__glewEnableVariantClientStateEXT" +Global glEndVertexShaderEXT()="__glewEndVertexShaderEXT" +Global glExtractComponentEXT(res_:Int,src_:Int,num_:Int)="__glewExtractComponentEXT" +Global glGenSymbolsEXT:Int(dataType_:Int,storageType_:Int,range_:Int,components_:Int)="__glewGenSymbolsEXT" +Global glGenVertexShadersEXT:Int(range_:Int)="__glewGenVertexShadersEXT" +Global glGetInvariantBooleanvEXT(id_:Int,value_:Int,data_:Byte Ptr)="__glewGetInvariantBooleanvEXT" +Global glGetInvariantFloatvEXT(id_:Int,value_:Int,data_:Float Ptr)="__glewGetInvariantFloatvEXT" +Global glGetInvariantIntegervEXT(id_:Int,value_:Int,data_:Int Ptr)="__glewGetInvariantIntegervEXT" +Global glGetLocalConstantBooleanvEXT(id_:Int,value_:Int,data_:Byte Ptr)="__glewGetLocalConstantBooleanvEXT" +Global glGetLocalConstantFloatvEXT(id_:Int,value_:Int,data_:Float Ptr)="__glewGetLocalConstantFloatvEXT" +Global glGetLocalConstantIntegervEXT(id_:Int,value_:Int,data_:Int Ptr)="__glewGetLocalConstantIntegervEXT" +Global glGetVariantBooleanvEXT(id_:Int,value_:Int,data_:Byte Ptr)="__glewGetVariantBooleanvEXT" +Global glGetVariantFloatvEXT(id_:Int,value_:Int,data_:Float Ptr)="__glewGetVariantFloatvEXT" +Global glGetVariantIntegervEXT(id_:Int,value_:Int,data_:Int Ptr)="__glewGetVariantIntegervEXT" +Global glGetVariantPointervEXT(id_:Int,value_:Int,data_:Byte Ptr Ptr)="__glewGetVariantPointervEXT" +Global glInsertComponentEXT(res_:Int,src_:Int,num_:Int)="__glewInsertComponentEXT" +Global glIsVariantEnabledEXT:Byte(id_:Int,cap_:Int)="__glewIsVariantEnabledEXT" +Global glSetInvariantEXT(id_:Int,type_:Int,addr_:Byte Ptr)="__glewSetInvariantEXT" +Global glSetLocalConstantEXT(id_:Int,type_:Int,addr_:Byte Ptr)="__glewSetLocalConstantEXT" +Global glShaderOp1EXT(op_:Int,res_:Int,arg1_:Int)="__glewShaderOp1EXT" +Global glShaderOp2EXT(op_:Int,res_:Int,arg1_:Int,arg2_:Int)="__glewShaderOp2EXT" +Global glShaderOp3EXT(op_:Int,res_:Int,arg1_:Int,arg2_:Int,arg3_:Int)="__glewShaderOp3EXT" +Global glSwizzleEXT(res_:Int,in_:Int,outX_:Int,outY_:Int,outZ_:Int,outW_:Int)="__glewSwizzleEXT" +Global glVariantPointerEXT(id_:Int,type_:Int,stride_:Int,addr_:Byte Ptr)="__glewVariantPointerEXT" +Global glVariantbvEXT(id_:Int,addr_:Byte Ptr)="__glewVariantbvEXT" +Global glVariantdvEXT(id_:Int,addr_:Double Ptr)="__glewVariantdvEXT" +Global glVariantfvEXT(id_:Int,addr_:Float Ptr)="__glewVariantfvEXT" +Global glVariantivEXT(id_:Int,addr_:Int Ptr)="__glewVariantivEXT" +Global glVariantsvEXT(id_:Int,addr_:Short Ptr)="__glewVariantsvEXT" +Global glVariantubvEXT(id_:Int,addr_:Byte Ptr)="__glewVariantubvEXT" +Global glVariantuivEXT(id_:Int,addr_:Int Ptr)="__glewVariantuivEXT" +Global glVariantusvEXT(id_:Int,addr_:Short Ptr)="__glewVariantusvEXT" +Global glWriteMaskEXT(res_:Int,in_:Int,outX_:Int,outY_:Int,outZ_:Int,outW_:Int)="__glewWriteMaskEXT" +Global GL_EXT_vertex_shader:Byte="__GLEW_EXT_vertex_shader" +Const GL_MODELVIEW0_STACK_DEPTH_EXT=$0BA3 +Const GL_MODELVIEW0_MATRIX_EXT=$0BA6 +Const GL_MODELVIEW0_EXT=$1700 +Const GL_MODELVIEW1_STACK_DEPTH_EXT=$8502 +Const GL_MODELVIEW1_MATRIX_EXT=$8506 +Const GL_VERTEX_WEIGHTING_EXT=$8509 +Const GL_MODELVIEW1_EXT=$850A +Const GL_CURRENT_VERTEX_WEIGHT_EXT=$850B +Const GL_VERTEX_WEIGHT_ARRAY_EXT=$850C +Const GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT=$850D +Const GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT=$850E +Const GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT=$850F +Const GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT=$8510 +Global glVertexWeightPointerEXT(size_:Int,type_:Int,stride_:Int,pointer_:Byte Ptr)="__glewVertexWeightPointerEXT" +Global glVertexWeightfEXT(weight_:Float)="__glewVertexWeightfEXT" +Global glVertexWeightfvEXT(weight_:Float Ptr)="__glewVertexWeightfvEXT" +Global GL_EXT_vertex_weighting:Byte="__GLEW_EXT_vertex_weighting" +Global glFrameTerminatorGREMEDY()="__glewFrameTerminatorGREMEDY" +Global GL_GREMEDY_frame_terminator:Byte="__GLEW_GREMEDY_frame_terminator" +Global glStringMarkerGREMEDY(len_:Int,string_:Byte Ptr)="__glewStringMarkerGREMEDY" +Global GL_GREMEDY_string_marker:Byte="__GLEW_GREMEDY_string_marker" +Global GL_HP_convolution_border_modes:Byte="__GLEW_HP_convolution_border_modes" +Global glGetImageTransformParameterfvHP(target_:Int,pname_:Int,params_:Float Ptr)="__glewGetImageTransformParameterfvHP" +Global glGetImageTransformParameterivHP(target_:Int,pname_:Int,params_:Int Ptr)="__glewGetImageTransformParameterivHP" +Global glImageTransformParameterfHP(target_:Int,pname_:Int,param_:Float)="__glewImageTransformParameterfHP" +Global glImageTransformParameterfvHP(target_:Int,pname_:Int,params_:Float Ptr)="__glewImageTransformParameterfvHP" +Global glImageTransformParameteriHP(target_:Int,pname_:Int,param_:Int)="__glewImageTransformParameteriHP" +Global glImageTransformParameterivHP(target_:Int,pname_:Int,params_:Int Ptr)="__glewImageTransformParameterivHP" +Global GL_HP_image_transform:Byte="__GLEW_HP_image_transform" +Const GL_OCCLUSION_TEST_HP=$8165 +Const GL_OCCLUSION_TEST_RESULT_HP=$8166 +Global GL_HP_occlusion_test:Byte="__GLEW_HP_occlusion_test" +Global GL_HP_texture_lighting:Byte="__GLEW_HP_texture_lighting" +Const GL_CULL_VERTEX_IBM=103050 +Global GL_IBM_cull_vertex:Byte="__GLEW_IBM_cull_vertex" +Global glMultiModeDrawArraysIBM(mode_:Int Ptr,first_:Int Ptr,count_:Int Ptr,primcount_:Int,modestride_:Int)="__glewMultiModeDrawArraysIBM" +Global glMultiModeDrawElementsIBM(mode_:Int Ptr,count_:Int Ptr,type_:Int,indices_:Byte Ptr Ptr,primcount_:Int,modestride_:Int)="__glewMultiModeDrawElementsIBM" +Global GL_IBM_multimode_draw_arrays:Byte="__GLEW_IBM_multimode_draw_arrays" +Const GL_RASTER_POSITION_UNCLIPPED_IBM=103010 +Global GL_IBM_rasterpos_clip:Byte="__GLEW_IBM_rasterpos_clip" +Const GL_ALL_STATIC_DATA_IBM=103060 +Const GL_STATIC_VERTEX_ARRAY_IBM=103061 +Global GL_IBM_static_data:Byte="__GLEW_IBM_static_data" +Const GL_MIRRORED_REPEAT_IBM=$8370 +Global GL_IBM_texture_mirrored_repeat:Byte="__GLEW_IBM_texture_mirrored_repeat" +Const GL_VERTEX_ARRAY_LIST_IBM=103070 +Const GL_NORMAL_ARRAY_LIST_IBM=103071 +Const GL_COLOR_ARRAY_LIST_IBM=103072 +Const GL_INDEX_ARRAY_LIST_IBM=103073 +Const GL_TEXTURE_COORD_ARRAY_LIST_IBM=103074 +Const GL_EDGE_FLAG_ARRAY_LIST_IBM=103075 +Const GL_FOG_COORDINATE_ARRAY_LIST_IBM=103076 +Const GL_SECONDARY_COLOR_ARRAY_LIST_IBM=103077 +Const GL_VERTEX_ARRAY_LIST_STRIDE_IBM=103080 +Const GL_NORMAL_ARRAY_LIST_STRIDE_IBM=103081 +Const GL_COLOR_ARRAY_LIST_STRIDE_IBM=103082 +Const GL_INDEX_ARRAY_LIST_STRIDE_IBM=103083 +Const GL_TEXTURE_COORD_ARRAY_LIST_STRIDE_IBM=103084 +Const GL_EDGE_FLAG_ARRAY_LIST_STRIDE_IBM=103085 +Const GL_FOG_COORDINATE_ARRAY_LIST_STRIDE_IBM=103086 +Const GL_SECONDARY_COLOR_ARRAY_LIST_STRIDE_IBM=103087 +Global glColorPointerListIBM(size_:Int,type_:Int,stride_:Int,pointer_:Byte Ptr Ptr,ptrstride_:Int)="__glewColorPointerListIBM" +Global glEdgeFlagPointerListIBM(stride_:Int,pointer_:Byte Ptr Ptr,ptrstride_:Int)="__glewEdgeFlagPointerListIBM" +Global glFogCoordPointerListIBM(type_:Int,stride_:Int,pointer_:Byte Ptr Ptr,ptrstride_:Int)="__glewFogCoordPointerListIBM" +Global glIndexPointerListIBM(type_:Int,stride_:Int,pointer_:Byte Ptr Ptr,ptrstride_:Int)="__glewIndexPointerListIBM" +Global glNormalPointerListIBM(type_:Int,stride_:Int,pointer_:Byte Ptr Ptr,ptrstride_:Int)="__glewNormalPointerListIBM" +Global glSecondaryColorPointerListIBM(size_:Int,type_:Int,stride_:Int,pointer_:Byte Ptr Ptr,ptrstride_:Int)="__glewSecondaryColorPointerListIBM" +Global glTexCoordPointerListIBM(size_:Int,type_:Int,stride_:Int,pointer_:Byte Ptr Ptr,ptrstride_:Int)="__glewTexCoordPointerListIBM" +Global glVertexPointerListIBM(size_:Int,type_:Int,stride_:Int,pointer_:Byte Ptr Ptr,ptrstride_:Int)="__glewVertexPointerListIBM" +Global GL_IBM_vertex_array_lists:Byte="__GLEW_IBM_vertex_array_lists" +Const GL_RED_MIN_CLAMP_INGR=$8560 +Const GL_GREEN_MIN_CLAMP_INGR=$8561 +Const GL_BLUE_MIN_CLAMP_INGR=$8562 +Const GL_ALPHA_MIN_CLAMP_INGR=$8563 +Const GL_RED_MAX_CLAMP_INGR=$8564 +Const GL_GREEN_MAX_CLAMP_INGR=$8565 +Const GL_BLUE_MAX_CLAMP_INGR=$8566 +Const GL_ALPHA_MAX_CLAMP_INGR=$8567 +Global GL_INGR_color_clamp:Byte="__GLEW_INGR_color_clamp" +Const GL_INTERLACE_READ_INGR=$8568 +Global GL_INGR_interlace_read:Byte="__GLEW_INGR_interlace_read" +Const GL_PARALLEL_ARRAYS_INTEL=$83F4 +Const GL_VERTEX_ARRAY_PARALLEL_POINTERS_INTEL=$83F5 +Const GL_NORMAL_ARRAY_PARALLEL_POINTERS_INTEL=$83F6 +Const GL_COLOR_ARRAY_PARALLEL_POINTERS_INTEL=$83F7 +Const GL_TEXTURE_COORD_ARRAY_PARALLEL_POINTERS_INTEL=$83F8 +Global glColorPointervINTEL(size_:Int,type_:Int,pointer_:Byte Ptr Ptr)="__glewColorPointervINTEL" +Global glNormalPointervINTEL(type_:Int,pointer_:Byte Ptr Ptr)="__glewNormalPointervINTEL" +Global glTexCoordPointervINTEL(size_:Int,type_:Int,pointer_:Byte Ptr Ptr)="__glewTexCoordPointervINTEL" +Global glVertexPointervINTEL(size_:Int,type_:Int,pointer_:Byte Ptr Ptr)="__glewVertexPointervINTEL" +Global GL_INTEL_parallel_arrays:Byte="__GLEW_INTEL_parallel_arrays" +Global glTexScissorFuncINTEL(target_:Int,lfunc_:Int,hfunc_:Int)="__glewTexScissorFuncINTEL" +Global glTexScissorINTEL(target_:Int,tlow_:Float,thigh_:Float)="__glewTexScissorINTEL" +Global GL_INTEL_texture_scissor:Byte="__GLEW_INTEL_texture_scissor" +Const GL_KTX_FRONT_REGION=$0 +Const GL_KTX_BACK_REGION=$1 +Const GL_KTX_Z_REGION=$2 +Const GL_KTX_STENCIL_REGION=$3 +Global glBufferRegionEnabledEXT:Int()="__glewBufferRegionEnabledEXT" +Global glDeleteBufferRegionEXT(region_:Int)="__glewDeleteBufferRegionEXT" +Global glDrawBufferRegionEXT(region_:Int,x_:Int,y_:Int,width_:Int,height_:Int,xDest_:Int,yDest_:Int)="__glewDrawBufferRegionEXT" +Global glNewBufferRegionEXT:Int(region_:Int)="__glewNewBufferRegionEXT" +Global glReadBufferRegionEXT(region_:Int,x_:Int,y_:Int,width_:Int,height_:Int)="__glewReadBufferRegionEXT" +Global GL_KTX_buffer_region:Byte="__GLEW_KTX_buffer_region" +Const GL_TEXTURE_1D_STACK_MESAX=$8759 +Const GL_TEXTURE_2D_STACK_MESAX=$875A +Const GL_PROXY_TEXTURE_1D_STACK_MESAX=$875B +Const GL_PROXY_TEXTURE_2D_STACK_MESAX=$875C +Const GL_TEXTURE_1D_STACK_BINDING_MESAX=$875D +Const GL_TEXTURE_2D_STACK_BINDING_MESAX=$875E +Global GL_MESAX_texture_stack:Byte="__GLEW_MESAX_texture_stack" +Const GL_PACK_INVERT_MESA=$8758 +Global GL_MESA_pack_invert:Byte="__GLEW_MESA_pack_invert" +Global glResizeBuffersMESA()="__glewResizeBuffersMESA" +Global GL_MESA_resize_buffers:Byte="__GLEW_MESA_resize_buffers" +Global glWindowPos2dMESA(x_:Double,y_:Double)="__glewWindowPos2dMESA" +Global glWindowPos2dvMESA(p_:Double Ptr)="__glewWindowPos2dvMESA" +Global glWindowPos2fMESA(x_:Float,y_:Float)="__glewWindowPos2fMESA" +Global glWindowPos2fvMESA(p_:Float Ptr)="__glewWindowPos2fvMESA" +Global glWindowPos2iMESA(x_:Int,y_:Int)="__glewWindowPos2iMESA" +Global glWindowPos2ivMESA(p_:Int Ptr)="__glewWindowPos2ivMESA" +Global glWindowPos2sMESA(x_:Short,y_:Short)="__glewWindowPos2sMESA" +Global glWindowPos2svMESA(p_:Short Ptr)="__glewWindowPos2svMESA" +Global glWindowPos3dMESA(x_:Double,y_:Double,z_:Double)="__glewWindowPos3dMESA" +Global glWindowPos3dvMESA(p_:Double Ptr)="__glewWindowPos3dvMESA" +Global glWindowPos3fMESA(x_:Float,y_:Float,z_:Float)="__glewWindowPos3fMESA" +Global glWindowPos3fvMESA(p_:Float Ptr)="__glewWindowPos3fvMESA" +Global glWindowPos3iMESA(x_:Int,y_:Int,z_:Int)="__glewWindowPos3iMESA" +Global glWindowPos3ivMESA(p_:Int Ptr)="__glewWindowPos3ivMESA" +Global glWindowPos3sMESA(x_:Short,y_:Short,z_:Short)="__glewWindowPos3sMESA" +Global glWindowPos3svMESA(p_:Short Ptr)="__glewWindowPos3svMESA" +Global glWindowPos4dMESA(x_:Double,y_:Double,z_:Double,arg3_:Double)="__glewWindowPos4dMESA" +Global glWindowPos4dvMESA(p_:Double Ptr)="__glewWindowPos4dvMESA" +Global glWindowPos4fMESA(x_:Float,y_:Float,z_:Float,w_:Float)="__glewWindowPos4fMESA" +Global glWindowPos4fvMESA(p_:Float Ptr)="__glewWindowPos4fvMESA" +Global glWindowPos4iMESA(x_:Int,y_:Int,z_:Int,w_:Int)="__glewWindowPos4iMESA" +Global glWindowPos4ivMESA(p_:Int Ptr)="__glewWindowPos4ivMESA" +Global glWindowPos4sMESA(x_:Short,y_:Short,z_:Short,w_:Short)="__glewWindowPos4sMESA" +Global glWindowPos4svMESA(p_:Short Ptr)="__glewWindowPos4svMESA" +Global GL_MESA_window_pos:Byte="__GLEW_MESA_window_pos" +Const GL_UNSIGNED_SHORT_8_8_MESA=$85BA +Const GL_UNSIGNED_SHORT_8_8_REV_MESA=$85BB +Const GL_YCBCR_MESA=$8757 +Global GL_MESA_ycbcr_texture:Byte="__GLEW_MESA_ycbcr_texture" +Global GL_NV_blend_square:Byte="__GLEW_NV_blend_square" +Const GL_QUERY_WAIT_NV=$8E13 +Const GL_QUERY_NO_WAIT_NV=$8E14 +Const GL_QUERY_BY_REGION_WAIT_NV=$8E15 +Const GL_QUERY_BY_REGION_NO_WAIT_NV=$8E16 +Global glBeginConditionalRenderNV(id_:Int,mode_:Int)="__glewBeginConditionalRenderNV" +Global glEndConditionalRenderNV()="__glewEndConditionalRenderNV" +Global GL_NV_conditional_render:Byte="__GLEW_NV_conditional_render" +Const GL_DEPTH_STENCIL_TO_RGBA_NV=$886E +Const GL_DEPTH_STENCIL_TO_BGRA_NV=$886F +Global GL_NV_copy_depth_to_color:Byte="__GLEW_NV_copy_depth_to_color" +Const GL_DEPTH_COMPONENT32F_NV=$8DAB +Const GL_DEPTH32F_STENCIL8_NV=$8DAC +Const GL_FLOAT_32_UNSIGNED_INT_24_8_REV_NV=$8DAD +Const GL_DEPTH_BUFFER_FLOAT_MODE_NV=$8DAF +Global glClearDepthdNV(depth_:Double)="__glewClearDepthdNV" +Global glDepthBoundsdNV(zmin_:Double,zmax_:Double)="__glewDepthBoundsdNV" +Global glDepthRangedNV(zNear_:Double,zFar_:Double)="__glewDepthRangedNV" +Global GL_NV_depth_buffer_float:Byte="__GLEW_NV_depth_buffer_float" +Const GL_DEPTH_CLAMP_NV=$864F +Global GL_NV_depth_clamp:Byte="__GLEW_NV_depth_clamp" +Const GL_SAMPLE_COUNT_BITS_NV=$8864 +Const GL_CURRENT_SAMPLE_COUNT_QUERY_NV=$8865 +Const GL_QUERY_RESULT_NV=$8866 +Const GL_QUERY_RESULT_AVAILABLE_NV=$8867 +Const GL_SAMPLE_COUNT_NV=$8914 +Global GL_NV_depth_range_unclamped:Byte="__GLEW_NV_depth_range_unclamped" +Const GL_EVAL_2D_NV=$86C0 +Const GL_EVAL_TRIANGULAR_2D_NV=$86C1 +Const GL_MAP_TESSELLATION_NV=$86C2 +Const GL_MAP_ATTRIB_U_ORDER_NV=$86C3 +Const GL_MAP_ATTRIB_V_ORDER_NV=$86C4 +Const GL_EVAL_FRACTIONAL_TESSELLATION_NV=$86C5 +Const GL_EVAL_VERTEX_ATTRIB0_NV=$86C6 +Const GL_EVAL_VERTEX_ATTRIB1_NV=$86C7 +Const GL_EVAL_VERTEX_ATTRIB2_NV=$86C8 +Const GL_EVAL_VERTEX_ATTRIB3_NV=$86C9 +Const GL_EVAL_VERTEX_ATTRIB4_NV=$86CA +Const GL_EVAL_VERTEX_ATTRIB5_NV=$86CB +Const GL_EVAL_VERTEX_ATTRIB6_NV=$86CC +Const GL_EVAL_VERTEX_ATTRIB7_NV=$86CD +Const GL_EVAL_VERTEX_ATTRIB8_NV=$86CE +Const GL_EVAL_VERTEX_ATTRIB9_NV=$86CF +Const GL_EVAL_VERTEX_ATTRIB10_NV=$86D0 +Const GL_EVAL_VERTEX_ATTRIB11_NV=$86D1 +Const GL_EVAL_VERTEX_ATTRIB12_NV=$86D2 +Const GL_EVAL_VERTEX_ATTRIB13_NV=$86D3 +Const GL_EVAL_VERTEX_ATTRIB14_NV=$86D4 +Const GL_EVAL_VERTEX_ATTRIB15_NV=$86D5 +Const GL_MAX_MAP_TESSELLATION_NV=$86D6 +Const GL_MAX_RATIONAL_EVAL_ORDER_NV=$86D7 +Global glEvalMapsNV(target_:Int,mode_:Int)="__glewEvalMapsNV" +Global glGetMapAttribParameterfvNV(target_:Int,index_:Int,pname_:Int,params_:Float Ptr)="__glewGetMapAttribParameterfvNV" +Global glGetMapAttribParameterivNV(target_:Int,index_:Int,pname_:Int,params_:Int Ptr)="__glewGetMapAttribParameterivNV" +Global glGetMapControlPointsNV(target_:Int,index_:Int,type_:Int,ustride_:Int,vstride_:Int,packed_:Byte,points_:Byte Ptr)="__glewGetMapControlPointsNV" +Global glGetMapParameterfvNV(target_:Int,pname_:Int,params_:Float Ptr)="__glewGetMapParameterfvNV" +Global glGetMapParameterivNV(target_:Int,pname_:Int,params_:Int Ptr)="__glewGetMapParameterivNV" +Global glMapControlPointsNV(target_:Int,index_:Int,type_:Int,ustride_:Int,vstride_:Int,uorder_:Int,vorder_:Int,packed_:Byte,points_:Byte Ptr)="__glewMapControlPointsNV" +Global glMapParameterfvNV(target_:Int,pname_:Int,params_:Float Ptr)="__glewMapParameterfvNV" +Global glMapParameterivNV(target_:Int,pname_:Int,params_:Int Ptr)="__glewMapParameterivNV" +Global GL_NV_evaluators:Byte="__GLEW_NV_evaluators" +Const GL_SAMPLE_POSITION_NV=$8E50 +Const GL_SAMPLE_MASK_NV=$8E51 +Const GL_SAMPLE_MASK_VALUE_NV=$8E52 +Const GL_TEXTURE_BINDING_RENDERBUFFER_NV=$8E53 +Const GL_TEXTURE_RENDERBUFFER_DATA_STORE_BINDING_NV=$8E54 +Const GL_TEXTURE_RENDERBUFFER_NV=$8E55 +Const GL_SAMPLER_RENDERBUFFER_NV=$8E56 +Const GL_INT_SAMPLER_RENDERBUFFER_NV=$8E57 +Const GL_UNSIGNED_INT_SAMPLER_RENDERBUFFER_NV=$8E58 +Const GL_MAX_SAMPLE_MASK_WORDS_NV=$8E59 +Global glGetMultisamplefvNV(pname_:Int,index_:Int,val_:Float Ptr)="__glewGetMultisamplefvNV" +Global glSampleMaskIndexedNV(index_:Int,mask_:Int)="__glewSampleMaskIndexedNV" +Global glTexRenderbufferNV(target_:Int,renderbuffer_:Int)="__glewTexRenderbufferNV" +Global GL_NV_explicit_multisample:Byte="__GLEW_NV_explicit_multisample" +Const GL_ALL_COMPLETED_NV=$84F2 +Const GL_FENCE_STATUS_NV=$84F3 +Const GL_FENCE_CONDITION_NV=$84F4 +Global glDeleteFencesNV(n_:Int,fences_:Int Ptr)="__glewDeleteFencesNV" +Global glFinishFenceNV(fence_:Int)="__glewFinishFenceNV" +Global glGenFencesNV(n_:Int,fences_:Int Ptr)="__glewGenFencesNV" +Global glGetFenceivNV(fence_:Int,pname_:Int,params_:Int Ptr)="__glewGetFenceivNV" +Global glIsFenceNV:Byte(fence_:Int)="__glewIsFenceNV" +Global glSetFenceNV(fence_:Int,condition_:Int)="__glewSetFenceNV" +Global glTestFenceNV:Byte(fence_:Int)="__glewTestFenceNV" +Global GL_NV_fence:Byte="__GLEW_NV_fence" +Const GL_FLOAT_R_NV=$8880 +Const GL_FLOAT_RG_NV=$8881 +Const GL_FLOAT_RGB_NV=$8882 +Const GL_FLOAT_RGBA_NV=$8883 +Const GL_FLOAT_R16_NV=$8884 +Const GL_FLOAT_R32_NV=$8885 +Const GL_FLOAT_RG16_NV=$8886 +Const GL_FLOAT_RG32_NV=$8887 +Const GL_FLOAT_RGB16_NV=$8888 +Const GL_FLOAT_RGB32_NV=$8889 +Const GL_FLOAT_RGBA16_NV=$888A +Const GL_FLOAT_RGBA32_NV=$888B +Const GL_TEXTURE_FLOAT_COMPONENTS_NV=$888C +Const GL_FLOAT_CLEAR_COLOR_VALUE_NV=$888D +Const GL_FLOAT_RGBA_MODE_NV=$888E +Global GL_NV_float_buffer:Byte="__GLEW_NV_float_buffer" +Const GL_FOG_DISTANCE_MODE_NV=$855A +Const GL_EYE_RADIAL_NV=$855B +Const GL_EYE_PLANE_ABSOLUTE_NV=$855C +Global GL_NV_fog_distance:Byte="__GLEW_NV_fog_distance" +Const GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV=$8868 +Const GL_FRAGMENT_PROGRAM_NV=$8870 +Const GL_MAX_TEXTURE_COORDS_NV=$8871 +Const GL_MAX_TEXTURE_IMAGE_UNITS_NV=$8872 +Const GL_FRAGMENT_PROGRAM_BINDING_NV=$8873 +Const GL_PROGRAM_ERROR_STRING_NV=$8874 +Global glGetProgramNamedParameterdvNV(id_:Int,len_:Int,name_:Byte Ptr,params_:Double Ptr)="__glewGetProgramNamedParameterdvNV" +Global glGetProgramNamedParameterfvNV(id_:Int,len_:Int,name_:Byte Ptr,params_:Float Ptr)="__glewGetProgramNamedParameterfvNV" +Global glProgramNamedParameter4dNV(id_:Int,len_:Int,name_:Byte Ptr,x_:Double,y_:Double,z_:Double,w_:Double)="__glewProgramNamedParameter4dNV" +Global glProgramNamedParameter4dvNV(id_:Int,len_:Int,name_:Byte Ptr,v_:Double Ptr)="__glewProgramNamedParameter4dvNV" +Global glProgramNamedParameter4fNV(id_:Int,len_:Int,name_:Byte Ptr,x_:Float,y_:Float,z_:Float,w_:Float)="__glewProgramNamedParameter4fNV" +Global glProgramNamedParameter4fvNV(id_:Int,len_:Int,name_:Byte Ptr,v_:Float Ptr)="__glewProgramNamedParameter4fvNV" +Global GL_NV_fragment_program:Byte="__GLEW_NV_fragment_program" +Const GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV=$88F4 +Const GL_MAX_PROGRAM_CALL_DEPTH_NV=$88F5 +Const GL_MAX_PROGRAM_IF_DEPTH_NV=$88F6 +Const GL_MAX_PROGRAM_LOOP_DEPTH_NV=$88F7 +Const GL_MAX_PROGRAM_LOOP_COUNT_NV=$88F8 +Global GL_NV_fragment_program2:Byte="__GLEW_NV_fragment_program2" +Global GL_NV_fragment_program4:Byte="__GLEW_NV_fragment_program4" +Global GL_NV_fragment_program_option:Byte="__GLEW_NV_fragment_program_option" +Const GL_RENDERBUFFER_COVERAGE_SAMPLES_NV=$8CAB +Const GL_RENDERBUFFER_COLOR_SAMPLES_NV=$8E10 +Const GL_MAX_MULTISAMPLE_COVERAGE_MODES_NV=$8E11 +Const GL_MULTISAMPLE_COVERAGE_MODES_NV=$8E12 +Global glRenderbufferStorageMultisampleCoverageNV(target_:Int,coverageSamples_:Int,colorSamples_:Int,internalformat_:Int,width_:Int,height_:Int)="__glewRenderbufferStorageMultisampleCoverageNV" +Global GL_NV_framebuffer_multisample_coverage:Byte="__GLEW_NV_framebuffer_multisample_coverage" +Const GL_GEOMETRY_PROGRAM_NV=$8C26 +Const GL_MAX_PROGRAM_OUTPUT_VERTICES_NV=$8C27 +Const GL_MAX_PROGRAM_TOTAL_OUTPUT_COMPONENTS_NV=$8C28 +Global glProgramVertexLimitNV(target_:Int,limit_:Int)="__glewProgramVertexLimitNV" +Global GL_NV_geometry_program4:Byte="__GLEW_NV_geometry_program4" +Global GL_NV_geometry_shader4:Byte="__GLEW_NV_geometry_shader4" +Const GL_MIN_PROGRAM_TEXEL_OFFSET_NV=$8904 +Const GL_MAX_PROGRAM_TEXEL_OFFSET_NV=$8905 +Const GL_PROGRAM_ATTRIB_COMPONENTS_NV=$8906 +Const GL_PROGRAM_RESULT_COMPONENTS_NV=$8907 +Const GL_MAX_PROGRAM_ATTRIB_COMPONENTS_NV=$8908 +Const GL_MAX_PROGRAM_RESULT_COMPONENTS_NV=$8909 +Const GL_MAX_PROGRAM_GENERIC_ATTRIBS_NV=$8DA5 +Const GL_MAX_PROGRAM_GENERIC_RESULTS_NV=$8DA6 +Global glProgramEnvParameterI4iNV(target_:Int,index_:Int,x_:Int,y_:Int,z_:Int,w_:Int)="__glewProgramEnvParameterI4iNV" +Global glProgramEnvParameterI4ivNV(target_:Int,index_:Int,params_:Int Ptr)="__glewProgramEnvParameterI4ivNV" +Global glProgramEnvParameterI4uiNV(target_:Int,index_:Int,x_:Int,y_:Int,z_:Int,w_:Int)="__glewProgramEnvParameterI4uiNV" +Global glProgramEnvParameterI4uivNV(target_:Int,index_:Int,params_:Int Ptr)="__glewProgramEnvParameterI4uivNV" +Global glProgramEnvParametersI4ivNV(target_:Int,index_:Int,count_:Int,params_:Int Ptr)="__glewProgramEnvParametersI4ivNV" +Global glProgramEnvParametersI4uivNV(target_:Int,index_:Int,count_:Int,params_:Int Ptr)="__glewProgramEnvParametersI4uivNV" +Global glProgramLocalParameterI4iNV(target_:Int,index_:Int,x_:Int,y_:Int,z_:Int,w_:Int)="__glewProgramLocalParameterI4iNV" +Global glProgramLocalParameterI4ivNV(target_:Int,index_:Int,params_:Int Ptr)="__glewProgramLocalParameterI4ivNV" +Global glProgramLocalParameterI4uiNV(target_:Int,index_:Int,x_:Int,y_:Int,z_:Int,w_:Int)="__glewProgramLocalParameterI4uiNV" +Global glProgramLocalParameterI4uivNV(target_:Int,index_:Int,params_:Int Ptr)="__glewProgramLocalParameterI4uivNV" +Global glProgramLocalParametersI4ivNV(target_:Int,index_:Int,count_:Int,params_:Int Ptr)="__glewProgramLocalParametersI4ivNV" +Global glProgramLocalParametersI4uivNV(target_:Int,index_:Int,count_:Int,params_:Int Ptr)="__glewProgramLocalParametersI4uivNV" +Global GL_NV_gpu_program4:Byte="__GLEW_NV_gpu_program4" +Const GL_HALF_FLOAT_NV=$140B +Global glColor3hNV(red_:Short,green_:Short,blue_:Short)="__glewColor3hNV" +Global glColor3hvNV(v_:Short Ptr)="__glewColor3hvNV" +Global glColor4hNV(red_:Short,green_:Short,blue_:Short,alpha_:Short)="__glewColor4hNV" +Global glColor4hvNV(v_:Short Ptr)="__glewColor4hvNV" +Global glFogCoordhNV(fog_:Short)="__glewFogCoordhNV" +Global glFogCoordhvNV(fog_:Short Ptr)="__glewFogCoordhvNV" +Global glMultiTexCoord1hNV(target_:Int,s_:Short)="__glewMultiTexCoord1hNV" +Global glMultiTexCoord1hvNV(target_:Int,v_:Short Ptr)="__glewMultiTexCoord1hvNV" +Global glMultiTexCoord2hNV(target_:Int,s_:Short,t_:Short)="__glewMultiTexCoord2hNV" +Global glMultiTexCoord2hvNV(target_:Int,v_:Short Ptr)="__glewMultiTexCoord2hvNV" +Global glMultiTexCoord3hNV(target_:Int,s_:Short,t_:Short,r_:Short)="__glewMultiTexCoord3hNV" +Global glMultiTexCoord3hvNV(target_:Int,v_:Short Ptr)="__glewMultiTexCoord3hvNV" +Global glMultiTexCoord4hNV(target_:Int,s_:Short,t_:Short,r_:Short,q_:Short)="__glewMultiTexCoord4hNV" +Global glMultiTexCoord4hvNV(target_:Int,v_:Short Ptr)="__glewMultiTexCoord4hvNV" +Global glNormal3hNV(nx_:Short,ny_:Short,nz_:Short)="__glewNormal3hNV" +Global glNormal3hvNV(v_:Short Ptr)="__glewNormal3hvNV" +Global glSecondaryColor3hNV(red_:Short,green_:Short,blue_:Short)="__glewSecondaryColor3hNV" +Global glSecondaryColor3hvNV(v_:Short Ptr)="__glewSecondaryColor3hvNV" +Global glTexCoord1hNV(s_:Short)="__glewTexCoord1hNV" +Global glTexCoord1hvNV(v_:Short Ptr)="__glewTexCoord1hvNV" +Global glTexCoord2hNV(s_:Short,t_:Short)="__glewTexCoord2hNV" +Global glTexCoord2hvNV(v_:Short Ptr)="__glewTexCoord2hvNV" +Global glTexCoord3hNV(s_:Short,t_:Short,r_:Short)="__glewTexCoord3hNV" +Global glTexCoord3hvNV(v_:Short Ptr)="__glewTexCoord3hvNV" +Global glTexCoord4hNV(s_:Short,t_:Short,r_:Short,q_:Short)="__glewTexCoord4hNV" +Global glTexCoord4hvNV(v_:Short Ptr)="__glewTexCoord4hvNV" +Global glVertex2hNV(x_:Short,y_:Short)="__glewVertex2hNV" +Global glVertex2hvNV(v_:Short Ptr)="__glewVertex2hvNV" +Global glVertex3hNV(x_:Short,y_:Short,z_:Short)="__glewVertex3hNV" +Global glVertex3hvNV(v_:Short Ptr)="__glewVertex3hvNV" +Global glVertex4hNV(x_:Short,y_:Short,z_:Short,w_:Short)="__glewVertex4hNV" +Global glVertex4hvNV(v_:Short Ptr)="__glewVertex4hvNV" +Global glVertexAttrib1hNV(index_:Int,x_:Short)="__glewVertexAttrib1hNV" +Global glVertexAttrib1hvNV(index_:Int,v_:Short Ptr)="__glewVertexAttrib1hvNV" +Global glVertexAttrib2hNV(index_:Int,x_:Short,y_:Short)="__glewVertexAttrib2hNV" +Global glVertexAttrib2hvNV(index_:Int,v_:Short Ptr)="__glewVertexAttrib2hvNV" +Global glVertexAttrib3hNV(index_:Int,x_:Short,y_:Short,z_:Short)="__glewVertexAttrib3hNV" +Global glVertexAttrib3hvNV(index_:Int,v_:Short Ptr)="__glewVertexAttrib3hvNV" +Global glVertexAttrib4hNV(index_:Int,x_:Short,y_:Short,z_:Short,w_:Short)="__glewVertexAttrib4hNV" +Global glVertexAttrib4hvNV(index_:Int,v_:Short Ptr)="__glewVertexAttrib4hvNV" +Global glVertexAttribs1hvNV(index_:Int,n_:Int,v_:Short Ptr)="__glewVertexAttribs1hvNV" +Global glVertexAttribs2hvNV(index_:Int,n_:Int,v_:Short Ptr)="__glewVertexAttribs2hvNV" +Global glVertexAttribs3hvNV(index_:Int,n_:Int,v_:Short Ptr)="__glewVertexAttribs3hvNV" +Global glVertexAttribs4hvNV(index_:Int,n_:Int,v_:Short Ptr)="__glewVertexAttribs4hvNV" +Global glVertexWeighthNV(weight_:Short)="__glewVertexWeighthNV" +Global glVertexWeighthvNV(weight_:Short Ptr)="__glewVertexWeighthvNV" +Global GL_NV_half_float:Byte="__GLEW_NV_half_float" +Const GL_MAX_SHININESS_NV=$8504 +Const GL_MAX_SPOT_EXPONENT_NV=$8505 +Global GL_NV_light_max_exponent:Byte="__GLEW_NV_light_max_exponent" +Const GL_MULTISAMPLE_FILTER_HINT_NV=$8534 +Global GL_NV_multisample_filter_hint:Byte="__GLEW_NV_multisample_filter_hint" +Const GL_PIXEL_COUNTER_BITS_NV=$8864 +Const GL_CURRENT_OCCLUSION_QUERY_ID_NV=$8865 +Const GL_PIXEL_COUNT_NV=$8866 +Const GL_PIXEL_COUNT_AVAILABLE_NV=$8867 +Global glBeginOcclusionQueryNV(id_:Int)="__glewBeginOcclusionQueryNV" +Global glDeleteOcclusionQueriesNV(n_:Int,ids_:Int Ptr)="__glewDeleteOcclusionQueriesNV" +Global glEndOcclusionQueryNV()="__glewEndOcclusionQueryNV" +Global glGenOcclusionQueriesNV(n_:Int,ids_:Int Ptr)="__glewGenOcclusionQueriesNV" +Global glGetOcclusionQueryivNV(id_:Int,pname_:Int,params_:Int Ptr)="__glewGetOcclusionQueryivNV" +Global glGetOcclusionQueryuivNV(id_:Int,pname_:Int,params_:Int Ptr)="__glewGetOcclusionQueryuivNV" +Global glIsOcclusionQueryNV:Byte(id_:Int)="__glewIsOcclusionQueryNV" +Global GL_NV_occlusion_query:Byte="__GLEW_NV_occlusion_query" +Const GL_DEPTH_STENCIL_NV=$84F9 +Const GL_UNSIGNED_INT_24_8_NV=$84FA +Global GL_NV_packed_depth_stencil:Byte="__GLEW_NV_packed_depth_stencil" +Const GL_MAX_PROGRAM_PARAMETER_BUFFER_BINDINGS_NV=$8DA0 +Const GL_MAX_PROGRAM_PARAMETER_BUFFER_SIZE_NV=$8DA1 +Const GL_VERTEX_PROGRAM_PARAMETER_BUFFER_NV=$8DA2 +Const GL_GEOMETRY_PROGRAM_PARAMETER_BUFFER_NV=$8DA3 +Const GL_FRAGMENT_PROGRAM_PARAMETER_BUFFER_NV=$8DA4 +Global glProgramBufferParametersIivNV(target_:Int,buffer_:Int,index_:Int,count_:Int,params_:Int Ptr)="__glewProgramBufferParametersIivNV" +Global glProgramBufferParametersIuivNV(target_:Int,buffer_:Int,index_:Int,count_:Int,params_:Int Ptr)="__glewProgramBufferParametersIuivNV" +Global glProgramBufferParametersfvNV(target_:Int,buffer_:Int,index_:Int,count_:Int,params_:Float Ptr)="__glewProgramBufferParametersfvNV" +Global GL_NV_parameter_buffer_object:Byte="__GLEW_NV_parameter_buffer_object" +Const GL_WRITE_PIXEL_DATA_RANGE_NV=$8878 +Const GL_READ_PIXEL_DATA_RANGE_NV=$8879 +Const GL_WRITE_PIXEL_DATA_RANGE_LENGTH_NV=$887A +Const GL_READ_PIXEL_DATA_RANGE_LENGTH_NV=$887B +Const GL_WRITE_PIXEL_DATA_RANGE_POINTER_NV=$887C +Const GL_READ_PIXEL_DATA_RANGE_POINTER_NV=$887D +Global glFlushPixelDataRangeNV(target_:Int)="__glewFlushPixelDataRangeNV" +Global glPixelDataRangeNV(target_:Int,length_:Int,pointer_:Byte Ptr)="__glewPixelDataRangeNV" +Global GL_NV_pixel_data_range:Byte="__GLEW_NV_pixel_data_range" +Const GL_POINT_SPRITE_NV=$8861 +Const GL_COORD_REPLACE_NV=$8862 +Const GL_POINT_SPRITE_R_MODE_NV=$8863 +Global glPointParameteriNV(pname_:Int,param_:Int)="__glewPointParameteriNV" +Global glPointParameterivNV(pname_:Int,params_:Int Ptr)="__glewPointParameterivNV" +Global GL_NV_point_sprite:Byte="__GLEW_NV_point_sprite" +Const GL_FRAME_NV=$8E26 +Const GL_FIELDS_NV=$8E27 +Const GL_CURRENT_TIME_NV=$8E28 +Const GL_NUM_FILL_STREAMS_NV=$8E29 +Const GL_PRESENT_TIME_NV=$8E2A +Const GL_PRESENT_DURATION_NV=$8E2B +Global glGetVideoi64vNV(video_slot_:Int,pname_:Int,params_:Long Ptr)="__glewGetVideoi64vNV" +Global glGetVideoivNV(video_slot_:Int,pname_:Int,params_:Int Ptr)="__glewGetVideoivNV" +Global glGetVideoui64vNV(video_slot_:Int,pname_:Int,params_:Long Ptr)="__glewGetVideoui64vNV" +Global glGetVideouivNV(video_slot_:Int,pname_:Int,params_:Int Ptr)="__glewGetVideouivNV" +Global glPresentFrameDualFillNV(video_slot_:Int,minPresentTime_:Long,beginPresentTimeId_:Int,presentDurationId_:Int,type_:Int,target0_:Int,fill0_:Int,target1_:Int,fill1_:Int,target2_:Int,fill2_:Int,target3_:Int,fill3_:Int)="__glewPresentFrameDualFillNV" +Global glPresentFrameKeyedNV(video_slot_:Int,minPresentTime_:Long,beginPresentTimeId_:Int,presentDurationId_:Int,type_:Int,target0_:Int,fill0_:Int,key0_:Int,target1_:Int,fill1_:Int,key1_:Int)="__glewPresentFrameKeyedNV" +Global glVideoParameterivNV(video_slot_:Int,pname_:Int,params_:Int Ptr)="__glewVideoParameterivNV" +Global GL_NV_present_video:Byte="__GLEW_NV_present_video" +Const GL_PRIMITIVE_RESTART_NV=$8558 +Const GL_PRIMITIVE_RESTART_INDEX_NV=$8559 +Global glPrimitiveRestartIndexNV(index_:Int)="__glewPrimitiveRestartIndexNV" +Global glPrimitiveRestartNV()="__glewPrimitiveRestartNV" +Global GL_NV_primitive_restart:Byte="__GLEW_NV_primitive_restart" +Const GL_REGISTER_COMBINERS_NV=$8522 +Const GL_VARIABLE_A_NV=$8523 +Const GL_VARIABLE_B_NV=$8524 +Const GL_VARIABLE_C_NV=$8525 +Const GL_VARIABLE_D_NV=$8526 +Const GL_VARIABLE_E_NV=$8527 +Const GL_VARIABLE_F_NV=$8528 +Const GL_VARIABLE_G_NV=$8529 +Const GL_CONSTANT_COLOR0_NV=$852A +Const GL_CONSTANT_COLOR1_NV=$852B +Const GL_PRIMARY_COLOR_NV=$852C +Const GL_SECONDARY_COLOR_NV=$852D +Const GL_SPARE0_NV=$852E +Const GL_SPARE1_NV=$852F +Const GL_DISCARD_NV=$8530 +Const GL_E_TIMES_F_NV=$8531 +Const GL_SPARE0_PLUS_SECONDARY_COLOR_NV=$8532 +Const GL_UNSIGNED_IDENTITY_NV=$8536 +Const GL_UNSIGNED_INVERT_NV=$8537 +Const GL_EXPAND_NORMAL_NV=$8538 +Const GL_EXPAND_NEGATE_NV=$8539 +Const GL_HALF_BIAS_NORMAL_NV=$853A +Const GL_HALF_BIAS_NEGATE_NV=$853B +Const GL_SIGNED_IDENTITY_NV=$853C +Const GL_SIGNED_NEGATE_NV=$853D +Const GL_SCALE_BY_TWO_NV=$853E +Const GL_SCALE_BY_FOUR_NV=$853F +Const GL_SCALE_BY_ONE_HALF_NV=$8540 +Const GL_BIAS_BY_NEGATIVE_ONE_HALF_NV=$8541 +Const GL_COMBINER_INPUT_NV=$8542 +Const GL_COMBINER_MAPPING_NV=$8543 +Const GL_COMBINER_COMPONENT_USAGE_NV=$8544 +Const GL_COMBINER_AB_DOT_PRODUCT_NV=$8545 +Const GL_COMBINER_CD_DOT_PRODUCT_NV=$8546 +Const GL_COMBINER_MUX_SUM_NV=$8547 +Const GL_COMBINER_SCALE_NV=$8548 +Const GL_COMBINER_BIAS_NV=$8549 +Const GL_COMBINER_AB_OUTPUT_NV=$854A +Const GL_COMBINER_CD_OUTPUT_NV=$854B +Const GL_COMBINER_SUM_OUTPUT_NV=$854C +Const GL_MAX_GENERAL_COMBINERS_NV=$854D +Const GL_NUM_GENERAL_COMBINERS_NV=$854E +Const GL_COLOR_SUM_CLAMP_NV=$854F +Const GL_COMBINER0_NV=$8550 +Const GL_COMBINER1_NV=$8551 +Const GL_COMBINER2_NV=$8552 +Const GL_COMBINER3_NV=$8553 +Const GL_COMBINER4_NV=$8554 +Const GL_COMBINER5_NV=$8555 +Const GL_COMBINER6_NV=$8556 +Const GL_COMBINER7_NV=$8557 +Global glCombinerInputNV(stage_:Int,portion_:Int,variable_:Int,input_:Int,mapping_:Int,componentUsage_:Int)="__glewCombinerInputNV" +Global glCombinerOutputNV(stage_:Int,portion_:Int,abOutput_:Int,cdOutput_:Int,sumOutput_:Int,scale_:Int,bias_:Int,abDotProduct_:Byte,cdDotProduct_:Byte,muxSum_:Byte)="__glewCombinerOutputNV" +Global glCombinerParameterfNV(pname_:Int,param_:Float)="__glewCombinerParameterfNV" +Global glCombinerParameterfvNV(pname_:Int,params_:Float Ptr)="__glewCombinerParameterfvNV" +Global glCombinerParameteriNV(pname_:Int,param_:Int)="__glewCombinerParameteriNV" +Global glCombinerParameterivNV(pname_:Int,params_:Int Ptr)="__glewCombinerParameterivNV" +Global glFinalCombinerInputNV(variable_:Int,input_:Int,mapping_:Int,componentUsage_:Int)="__glewFinalCombinerInputNV" +Global glGetCombinerInputParameterfvNV(stage_:Int,portion_:Int,variable_:Int,pname_:Int,params_:Float Ptr)="__glewGetCombinerInputParameterfvNV" +Global glGetCombinerInputParameterivNV(stage_:Int,portion_:Int,variable_:Int,pname_:Int,params_:Int Ptr)="__glewGetCombinerInputParameterivNV" +Global glGetCombinerOutputParameterfvNV(stage_:Int,portion_:Int,pname_:Int,params_:Float Ptr)="__glewGetCombinerOutputParameterfvNV" +Global glGetCombinerOutputParameterivNV(stage_:Int,portion_:Int,pname_:Int,params_:Int Ptr)="__glewGetCombinerOutputParameterivNV" +Global glGetFinalCombinerInputParameterfvNV(variable_:Int,pname_:Int,params_:Float Ptr)="__glewGetFinalCombinerInputParameterfvNV" +Global glGetFinalCombinerInputParameterivNV(variable_:Int,pname_:Int,params_:Int Ptr)="__glewGetFinalCombinerInputParameterivNV" +Global GL_NV_register_combiners:Byte="__GLEW_NV_register_combiners" +Const GL_PER_STAGE_CONSTANTS_NV=$8535 +Global glCombinerStageParameterfvNV(stage_:Int,pname_:Int,params_:Float Ptr)="__glewCombinerStageParameterfvNV" +Global glGetCombinerStageParameterfvNV(stage_:Int,pname_:Int,params_:Float Ptr)="__glewGetCombinerStageParameterfvNV" +Global GL_NV_register_combiners2:Byte="__GLEW_NV_register_combiners2" +Const GL_EMBOSS_LIGHT_NV=$855D +Const GL_EMBOSS_CONSTANT_NV=$855E +Const GL_EMBOSS_MAP_NV=$855F +Global GL_NV_texgen_emboss:Byte="__GLEW_NV_texgen_emboss" +Const GL_NORMAL_MAP_NV=$8511 +Const GL_REFLECTION_MAP_NV=$8512 +Global GL_NV_texgen_reflection:Byte="__GLEW_NV_texgen_reflection" +Global GL_NV_texture_compression_vtc:Byte="__GLEW_NV_texture_compression_vtc" +Const GL_COMBINE4_NV=$8503 +Const GL_SOURCE3_RGB_NV=$8583 +Const GL_SOURCE3_ALPHA_NV=$858B +Const GL_OPERAND3_RGB_NV=$8593 +Const GL_OPERAND3_ALPHA_NV=$859B +Global GL_NV_texture_env_combine4:Byte="__GLEW_NV_texture_env_combine4" +Const GL_TEXTURE_UNSIGNED_REMAP_MODE_NV=$888F +Global GL_NV_texture_expand_normal:Byte="__GLEW_NV_texture_expand_normal" +Const GL_TEXTURE_RECTANGLE_NV=$84F5 +Const GL_TEXTURE_BINDING_RECTANGLE_NV=$84F6 +Const GL_PROXY_TEXTURE_RECTANGLE_NV=$84F7 +Const GL_MAX_RECTANGLE_TEXTURE_SIZE_NV=$84F8 +Global GL_NV_texture_rectangle:Byte="__GLEW_NV_texture_rectangle" +Const GL_OFFSET_TEXTURE_RECTANGLE_NV=$864C +Const GL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV=$864D +Const GL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV=$864E +Const GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV=$86D9 +Const GL_UNSIGNED_INT_S8_S8_8_8_NV=$86DA +Const GL_UNSIGNED_INT_8_8_S8_S8_REV_NV=$86DB +Const GL_DSDT_MAG_INTENSITY_NV=$86DC +Const GL_SHADER_CONSISTENT_NV=$86DD +Const GL_TEXTURE_SHADER_NV=$86DE +Const GL_SHADER_OPERATION_NV=$86DF +Const GL_CULL_MODES_NV=$86E0 +Const GL_OFFSET_TEXTURE_2D_MATRIX_NV=$86E1 +Const GL_OFFSET_TEXTURE_MATRIX_NV=$86E1 +Const GL_OFFSET_TEXTURE_2D_SCALE_NV=$86E2 +Const GL_OFFSET_TEXTURE_SCALE_NV=$86E2 +Const GL_OFFSET_TEXTURE_BIAS_NV=$86E3 +Const GL_OFFSET_TEXTURE_2D_BIAS_NV=$86E3 +Const GL_PREVIOUS_TEXTURE_INPUT_NV=$86E4 +Const GL_CONST_EYE_NV=$86E5 +Const GL_PASS_THROUGH_NV=$86E6 +Const GL_CULL_FRAGMENT_NV=$86E7 +Const GL_OFFSET_TEXTURE_2D_NV=$86E8 +Const GL_DEPENDENT_AR_TEXTURE_2D_NV=$86E9 +Const GL_DEPENDENT_GB_TEXTURE_2D_NV=$86EA +Const GL_DOT_PRODUCT_NV=$86EC +Const GL_DOT_PRODUCT_DEPTH_REPLACE_NV=$86ED +Const GL_DOT_PRODUCT_TEXTURE_2D_NV=$86EE +Const GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV=$86F0 +Const GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV=$86F1 +Const GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV=$86F2 +Const GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV=$86F3 +Const GL_HILO_NV=$86F4 +Const GL_DSDT_NV=$86F5 +Const GL_DSDT_MAG_NV=$86F6 +Const GL_DSDT_MAG_VIB_NV=$86F7 +Const GL_HILO16_NV=$86F8 +Const GL_SIGNED_HILO_NV=$86F9 +Const GL_SIGNED_HILO16_NV=$86FA +Const GL_SIGNED_RGBA_NV=$86FB +Const GL_SIGNED_RGBA8_NV=$86FC +Const GL_SIGNED_RGB_NV=$86FE +Const GL_SIGNED_RGB8_NV=$86FF +Const GL_SIGNED_LUMINANCE_NV=$8701 +Const GL_SIGNED_LUMINANCE8_NV=$8702 +Const GL_SIGNED_LUMINANCE_ALPHA_NV=$8703 +Const GL_SIGNED_LUMINANCE8_ALPHA8_NV=$8704 +Const GL_SIGNED_ALPHA_NV=$8705 +Const GL_SIGNED_ALPHA8_NV=$8706 +Const GL_SIGNED_INTENSITY_NV=$8707 +Const GL_SIGNED_INTENSITY8_NV=$8708 +Const GL_DSDT8_NV=$8709 +Const GL_DSDT8_MAG8_NV=$870A +Const GL_DSDT8_MAG8_INTENSITY8_NV=$870B +Const GL_SIGNED_RGB_UNSIGNED_ALPHA_NV=$870C +Const GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV=$870D +Const GL_HI_SCALE_NV=$870E +Const GL_LO_SCALE_NV=$870F +Const GL_DS_SCALE_NV=$8710 +Const GL_DT_SCALE_NV=$8711 +Const GL_MAGNITUDE_SCALE_NV=$8712 +Const GL_VIBRANCE_SCALE_NV=$8713 +Const GL_HI_BIAS_NV=$8714 +Const GL_LO_BIAS_NV=$8715 +Const GL_DS_BIAS_NV=$8716 +Const GL_DT_BIAS_NV=$8717 +Const GL_MAGNITUDE_BIAS_NV=$8718 +Const GL_VIBRANCE_BIAS_NV=$8719 +Const GL_TEXTURE_BORDER_VALUES_NV=$871A +Const GL_TEXTURE_HI_SIZE_NV=$871B +Const GL_TEXTURE_LO_SIZE_NV=$871C +Const GL_TEXTURE_DS_SIZE_NV=$871D +Const GL_TEXTURE_DT_SIZE_NV=$871E +Const GL_TEXTURE_MAG_SIZE_NV=$871F +Global GL_NV_texture_shader:Byte="__GLEW_NV_texture_shader" +Const GL_DOT_PRODUCT_TEXTURE_3D_NV=$86EF +Global GL_NV_texture_shader2:Byte="__GLEW_NV_texture_shader2" +Const GL_OFFSET_PROJECTIVE_TEXTURE_2D_NV=$8850 +Const GL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV=$8851 +Const GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV=$8852 +Const GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV=$8853 +Const GL_OFFSET_HILO_TEXTURE_2D_NV=$8854 +Const GL_OFFSET_HILO_TEXTURE_RECTANGLE_NV=$8855 +Const GL_OFFSET_HILO_PROJECTIVE_TEXTURE_2D_NV=$8856 +Const GL_OFFSET_HILO_PROJECTIVE_TEXTURE_RECTANGLE_NV=$8857 +Const GL_DEPENDENT_HILO_TEXTURE_2D_NV=$8858 +Const GL_DEPENDENT_RGB_TEXTURE_3D_NV=$8859 +Const GL_DEPENDENT_RGB_TEXTURE_CUBE_MAP_NV=$885A +Const GL_DOT_PRODUCT_PASS_THROUGH_NV=$885B +Const GL_DOT_PRODUCT_TEXTURE_1D_NV=$885C +Const GL_DOT_PRODUCT_AFFINE_DEPTH_REPLACE_NV=$885D +Const GL_HILO8_NV=$885E +Const GL_SIGNED_HILO8_NV=$885F +Const GL_FORCE_BLUE_TO_ONE_NV=$8860 +Global GL_NV_texture_shader3:Byte="__GLEW_NV_texture_shader3" +Const GL_BACK_PRIMARY_COLOR_NV=$8C77 +Const GL_BACK_SECONDARY_COLOR_NV=$8C78 +Const GL_TEXTURE_COORD_NV=$8C79 +Const GL_CLIP_DISTANCE_NV=$8C7A +Const GL_VERTEX_ID_NV=$8C7B +Const GL_PRIMITIVE_ID_NV=$8C7C +Const GL_GENERIC_ATTRIB_NV=$8C7D +Const GL_TRANSFORM_FEEDBACK_ATTRIBS_NV=$8C7E +Const GL_TRANSFORM_FEEDBACK_BUFFER_MODE_NV=$8C7F +Const GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_NV=$8C80 +Const GL_ACTIVE_VARYINGS_NV=$8C81 +Const GL_ACTIVE_VARYING_MAX_LENGTH_NV=$8C82 +Const GL_TRANSFORM_FEEDBACK_VARYINGS_NV=$8C83 +Const GL_TRANSFORM_FEEDBACK_BUFFER_START_NV=$8C84 +Const GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_NV=$8C85 +Const GL_TRANSFORM_FEEDBACK_RECORD_NV=$8C86 +Const GL_PRIMITIVES_GENERATED_NV=$8C87 +Const GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV=$8C88 +Const GL_RASTERIZER_DISCARD_NV=$8C89 +Const GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_NV=$8C8A +Const GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_NV=$8C8B +Const GL_INTERLEAVED_ATTRIBS_NV=$8C8C +Const GL_SEPARATE_ATTRIBS_NV=$8C8D +Const GL_TRANSFORM_FEEDBACK_BUFFER_NV=$8C8E +Const GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_NV=$8C8F +Global glActiveVaryingNV(program_:Int,name_:Byte Ptr)="__glewActiveVaryingNV" +Global glBeginTransformFeedbackNV(primitiveMode_:Int)="__glewBeginTransformFeedbackNV" +Global glBindBufferBaseNV(target_:Int,index_:Int,buffer_:Int)="__glewBindBufferBaseNV" +Global glBindBufferOffsetNV(target_:Int,index_:Int,buffer_:Int,offset_:Int)="__glewBindBufferOffsetNV" +Global glBindBufferRangeNV(target_:Int,index_:Int,buffer_:Int,offset_:Int,size_:Int)="__glewBindBufferRangeNV" +Global glEndTransformFeedbackNV()="__glewEndTransformFeedbackNV" +Global glGetActiveVaryingNV(program_:Int,index_:Int,bufSize_:Int,length_:Int Ptr,size_:Int Ptr,type_:Int Ptr,name_:Byte Ptr)="__glewGetActiveVaryingNV" +Global glGetTransformFeedbackVaryingNV(program_:Int,index_:Int,location_:Int Ptr)="__glewGetTransformFeedbackVaryingNV" +Global glGetVaryingLocationNV:Int(program_:Int,name_:Byte Ptr)="__glewGetVaryingLocationNV" +Global glTransformFeedbackAttribsNV(count_:Int,attribs_:Int Ptr,bufferMode_:Int)="__glewTransformFeedbackAttribsNV" +Global glTransformFeedbackVaryingsNV(program_:Int,count_:Int,locations_:Int Ptr,bufferMode_:Int)="__glewTransformFeedbackVaryingsNV" +Global GL_NV_transform_feedback:Byte="__GLEW_NV_transform_feedback" +Const GL_VERTEX_ARRAY_RANGE_NV=$851D +Const GL_VERTEX_ARRAY_RANGE_LENGTH_NV=$851E +Const GL_VERTEX_ARRAY_RANGE_VALID_NV=$851F +Const GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV=$8520 +Const GL_VERTEX_ARRAY_RANGE_POINTER_NV=$8521 +Global glFlushVertexArrayRangeNV()="__glewFlushVertexArrayRangeNV" +Global glVertexArrayRangeNV(length_:Int,pointer_:Byte Ptr)="__glewVertexArrayRangeNV" +Global GL_NV_vertex_array_range:Byte="__GLEW_NV_vertex_array_range" +Const GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV=$8533 +Global GL_NV_vertex_array_range2:Byte="__GLEW_NV_vertex_array_range2" +Const GL_VERTEX_PROGRAM_NV=$8620 +Const GL_VERTEX_STATE_PROGRAM_NV=$8621 +Const GL_ATTRIB_ARRAY_SIZE_NV=$8623 +Const GL_ATTRIB_ARRAY_STRIDE_NV=$8624 +Const GL_ATTRIB_ARRAY_TYPE_NV=$8625 +Const GL_CURRENT_ATTRIB_NV=$8626 +Const GL_PROGRAM_LENGTH_NV=$8627 +Const GL_PROGRAM_STRING_NV=$8628 +Const GL_MODELVIEW_PROJECTION_NV=$8629 +Const GL_IDENTITY_NV=$862A +Const GL_INVERSE_NV=$862B +Const GL_TRANSPOSE_NV=$862C +Const GL_INVERSE_TRANSPOSE_NV=$862D +Const GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV=$862E +Const GL_MAX_TRACK_MATRICES_NV=$862F +Const GL_MATRIX0_NV=$8630 +Const GL_MATRIX1_NV=$8631 +Const GL_MATRIX2_NV=$8632 +Const GL_MATRIX3_NV=$8633 +Const GL_MATRIX4_NV=$8634 +Const GL_MATRIX5_NV=$8635 +Const GL_MATRIX6_NV=$8636 +Const GL_MATRIX7_NV=$8637 +Const GL_CURRENT_MATRIX_STACK_DEPTH_NV=$8640 +Const GL_CURRENT_MATRIX_NV=$8641 +Const GL_VERTEX_PROGRAM_POINT_SIZE_NV=$8642 +Const GL_VERTEX_PROGRAM_TWO_SIDE_NV=$8643 +Const GL_PROGRAM_PARAMETER_NV=$8644 +Const GL_ATTRIB_ARRAY_POINTER_NV=$8645 +Const GL_PROGRAM_TARGET_NV=$8646 +Const GL_PROGRAM_RESIDENT_NV=$8647 +Const GL_TRACK_MATRIX_NV=$8648 +Const GL_TRACK_MATRIX_TRANSFORM_NV=$8649 +Const GL_VERTEX_PROGRAM_BINDING_NV=$864A +Const GL_PROGRAM_ERROR_POSITION_NV=$864B +Const GL_VERTEX_ATTRIB_ARRAY0_NV=$8650 +Const GL_VERTEX_ATTRIB_ARRAY1_NV=$8651 +Const GL_VERTEX_ATTRIB_ARRAY2_NV=$8652 +Const GL_VERTEX_ATTRIB_ARRAY3_NV=$8653 +Const GL_VERTEX_ATTRIB_ARRAY4_NV=$8654 +Const GL_VERTEX_ATTRIB_ARRAY5_NV=$8655 +Const GL_VERTEX_ATTRIB_ARRAY6_NV=$8656 +Const GL_VERTEX_ATTRIB_ARRAY7_NV=$8657 +Const GL_VERTEX_ATTRIB_ARRAY8_NV=$8658 +Const GL_VERTEX_ATTRIB_ARRAY9_NV=$8659 +Const GL_VERTEX_ATTRIB_ARRAY10_NV=$865A +Const GL_VERTEX_ATTRIB_ARRAY11_NV=$865B +Const GL_VERTEX_ATTRIB_ARRAY12_NV=$865C +Const GL_VERTEX_ATTRIB_ARRAY13_NV=$865D +Const GL_VERTEX_ATTRIB_ARRAY14_NV=$865E +Const GL_VERTEX_ATTRIB_ARRAY15_NV=$865F +Const GL_MAP1_VERTEX_ATTRIB0_4_NV=$8660 +Const GL_MAP1_VERTEX_ATTRIB1_4_NV=$8661 +Const GL_MAP1_VERTEX_ATTRIB2_4_NV=$8662 +Const GL_MAP1_VERTEX_ATTRIB3_4_NV=$8663 +Const GL_MAP1_VERTEX_ATTRIB4_4_NV=$8664 +Const GL_MAP1_VERTEX_ATTRIB5_4_NV=$8665 +Const GL_MAP1_VERTEX_ATTRIB6_4_NV=$8666 +Const GL_MAP1_VERTEX_ATTRIB7_4_NV=$8667 +Const GL_MAP1_VERTEX_ATTRIB8_4_NV=$8668 +Const GL_MAP1_VERTEX_ATTRIB9_4_NV=$8669 +Const GL_MAP1_VERTEX_ATTRIB10_4_NV=$866A +Const GL_MAP1_VERTEX_ATTRIB11_4_NV=$866B +Const GL_MAP1_VERTEX_ATTRIB12_4_NV=$866C +Const GL_MAP1_VERTEX_ATTRIB13_4_NV=$866D +Const GL_MAP1_VERTEX_ATTRIB14_4_NV=$866E +Const GL_MAP1_VERTEX_ATTRIB15_4_NV=$866F +Const GL_MAP2_VERTEX_ATTRIB0_4_NV=$8670 +Const GL_MAP2_VERTEX_ATTRIB1_4_NV=$8671 +Const GL_MAP2_VERTEX_ATTRIB2_4_NV=$8672 +Const GL_MAP2_VERTEX_ATTRIB3_4_NV=$8673 +Const GL_MAP2_VERTEX_ATTRIB4_4_NV=$8674 +Const GL_MAP2_VERTEX_ATTRIB5_4_NV=$8675 +Const GL_MAP2_VERTEX_ATTRIB6_4_NV=$8676 +Const GL_MAP2_VERTEX_ATTRIB7_4_NV=$8677 +Const GL_MAP2_VERTEX_ATTRIB8_4_NV=$8678 +Const GL_MAP2_VERTEX_ATTRIB9_4_NV=$8679 +Const GL_MAP2_VERTEX_ATTRIB10_4_NV=$867A +Const GL_MAP2_VERTEX_ATTRIB11_4_NV=$867B +Const GL_MAP2_VERTEX_ATTRIB12_4_NV=$867C +Const GL_MAP2_VERTEX_ATTRIB13_4_NV=$867D +Const GL_MAP2_VERTEX_ATTRIB14_4_NV=$867E +Const GL_MAP2_VERTEX_ATTRIB15_4_NV=$867F +Global glAreProgramsResidentNV:Byte(n_:Int,ids_:Int Ptr,residences_:Byte Ptr)="__glewAreProgramsResidentNV" +Global glBindProgramNV(target_:Int,id_:Int)="__glewBindProgramNV" +Global glDeleteProgramsNV(n_:Int,ids_:Int Ptr)="__glewDeleteProgramsNV" +Global glExecuteProgramNV(target_:Int,id_:Int,params_:Float Ptr)="__glewExecuteProgramNV" +Global glGenProgramsNV(n_:Int,ids_:Int Ptr)="__glewGenProgramsNV" +Global glGetProgramParameterdvNV(target_:Int,index_:Int,pname_:Int,params_:Double Ptr)="__glewGetProgramParameterdvNV" +Global glGetProgramParameterfvNV(target_:Int,index_:Int,pname_:Int,params_:Float Ptr)="__glewGetProgramParameterfvNV" +Global glGetProgramStringNV(id_:Int,pname_:Int,program_:Byte Ptr)="__glewGetProgramStringNV" +Global glGetProgramivNV(id_:Int,pname_:Int,params_:Int Ptr)="__glewGetProgramivNV" +Global glGetTrackMatrixivNV(target_:Int,address_:Int,pname_:Int,params_:Int Ptr)="__glewGetTrackMatrixivNV" +Global glGetVertexAttribPointervNV(index_:Int,pname_:Int,pointer_:Byte Ptr Ptr)="__glewGetVertexAttribPointervNV" +Global glGetVertexAttribdvNV(index_:Int,pname_:Int,params_:Double Ptr)="__glewGetVertexAttribdvNV" +Global glGetVertexAttribfvNV(index_:Int,pname_:Int,params_:Float Ptr)="__glewGetVertexAttribfvNV" +Global glGetVertexAttribivNV(index_:Int,pname_:Int,params_:Int Ptr)="__glewGetVertexAttribivNV" +Global glIsProgramNV:Byte(id_:Int)="__glewIsProgramNV" +Global glLoadProgramNV(target_:Int,id_:Int,len_:Int,program_:Byte Ptr)="__glewLoadProgramNV" +Global glProgramParameter4dNV(target_:Int,index_:Int,x_:Double,y_:Double,z_:Double,w_:Double)="__glewProgramParameter4dNV" +Global glProgramParameter4dvNV(target_:Int,index_:Int,params_:Double Ptr)="__glewProgramParameter4dvNV" +Global glProgramParameter4fNV(target_:Int,index_:Int,x_:Float,y_:Float,z_:Float,w_:Float)="__glewProgramParameter4fNV" +Global glProgramParameter4fvNV(target_:Int,index_:Int,params_:Float Ptr)="__glewProgramParameter4fvNV" +Global glProgramParameters4dvNV(target_:Int,index_:Int,num_:Int,params_:Double Ptr)="__glewProgramParameters4dvNV" +Global glProgramParameters4fvNV(target_:Int,index_:Int,num_:Int,params_:Float Ptr)="__glewProgramParameters4fvNV" +Global glRequestResidentProgramsNV(n_:Int,ids_:Int Ptr)="__glewRequestResidentProgramsNV" +Global glTrackMatrixNV(target_:Int,address_:Int,matrix_:Int,transform_:Int)="__glewTrackMatrixNV" +Global glVertexAttrib1dNV(index_:Int,x_:Double)="__glewVertexAttrib1dNV" +Global glVertexAttrib1dvNV(index_:Int,v_:Double Ptr)="__glewVertexAttrib1dvNV" +Global glVertexAttrib1fNV(index_:Int,x_:Float)="__glewVertexAttrib1fNV" +Global glVertexAttrib1fvNV(index_:Int,v_:Float Ptr)="__glewVertexAttrib1fvNV" +Global glVertexAttrib1sNV(index_:Int,x_:Short)="__glewVertexAttrib1sNV" +Global glVertexAttrib1svNV(index_:Int,v_:Short Ptr)="__glewVertexAttrib1svNV" +Global glVertexAttrib2dNV(index_:Int,x_:Double,y_:Double)="__glewVertexAttrib2dNV" +Global glVertexAttrib2dvNV(index_:Int,v_:Double Ptr)="__glewVertexAttrib2dvNV" +Global glVertexAttrib2fNV(index_:Int,x_:Float,y_:Float)="__glewVertexAttrib2fNV" +Global glVertexAttrib2fvNV(index_:Int,v_:Float Ptr)="__glewVertexAttrib2fvNV" +Global glVertexAttrib2sNV(index_:Int,x_:Short,y_:Short)="__glewVertexAttrib2sNV" +Global glVertexAttrib2svNV(index_:Int,v_:Short Ptr)="__glewVertexAttrib2svNV" +Global glVertexAttrib3dNV(index_:Int,x_:Double,y_:Double,z_:Double)="__glewVertexAttrib3dNV" +Global glVertexAttrib3dvNV(index_:Int,v_:Double Ptr)="__glewVertexAttrib3dvNV" +Global glVertexAttrib3fNV(index_:Int,x_:Float,y_:Float,z_:Float)="__glewVertexAttrib3fNV" +Global glVertexAttrib3fvNV(index_:Int,v_:Float Ptr)="__glewVertexAttrib3fvNV" +Global glVertexAttrib3sNV(index_:Int,x_:Short,y_:Short,z_:Short)="__glewVertexAttrib3sNV" +Global glVertexAttrib3svNV(index_:Int,v_:Short Ptr)="__glewVertexAttrib3svNV" +Global glVertexAttrib4dNV(index_:Int,x_:Double,y_:Double,z_:Double,w_:Double)="__glewVertexAttrib4dNV" +Global glVertexAttrib4dvNV(index_:Int,v_:Double Ptr)="__glewVertexAttrib4dvNV" +Global glVertexAttrib4fNV(index_:Int,x_:Float,y_:Float,z_:Float,w_:Float)="__glewVertexAttrib4fNV" +Global glVertexAttrib4fvNV(index_:Int,v_:Float Ptr)="__glewVertexAttrib4fvNV" +Global glVertexAttrib4sNV(index_:Int,x_:Short,y_:Short,z_:Short,w_:Short)="__glewVertexAttrib4sNV" +Global glVertexAttrib4svNV(index_:Int,v_:Short Ptr)="__glewVertexAttrib4svNV" +Global glVertexAttrib4ubNV(index_:Int,x_:Byte,y_:Byte,z_:Byte,w_:Byte)="__glewVertexAttrib4ubNV" +Global glVertexAttrib4ubvNV(index_:Int,v_:Byte Ptr)="__glewVertexAttrib4ubvNV" +Global glVertexAttribPointerNV(index_:Int,size_:Int,type_:Int,stride_:Int,pointer_:Byte Ptr)="__glewVertexAttribPointerNV" +Global glVertexAttribs1dvNV(index_:Int,n_:Int,v_:Double Ptr)="__glewVertexAttribs1dvNV" +Global glVertexAttribs1fvNV(index_:Int,n_:Int,v_:Float Ptr)="__glewVertexAttribs1fvNV" +Global glVertexAttribs1svNV(index_:Int,n_:Int,v_:Short Ptr)="__glewVertexAttribs1svNV" +Global glVertexAttribs2dvNV(index_:Int,n_:Int,v_:Double Ptr)="__glewVertexAttribs2dvNV" +Global glVertexAttribs2fvNV(index_:Int,n_:Int,v_:Float Ptr)="__glewVertexAttribs2fvNV" +Global glVertexAttribs2svNV(index_:Int,n_:Int,v_:Short Ptr)="__glewVertexAttribs2svNV" +Global glVertexAttribs3dvNV(index_:Int,n_:Int,v_:Double Ptr)="__glewVertexAttribs3dvNV" +Global glVertexAttribs3fvNV(index_:Int,n_:Int,v_:Float Ptr)="__glewVertexAttribs3fvNV" +Global glVertexAttribs3svNV(index_:Int,n_:Int,v_:Short Ptr)="__glewVertexAttribs3svNV" +Global glVertexAttribs4dvNV(index_:Int,n_:Int,v_:Double Ptr)="__glewVertexAttribs4dvNV" +Global glVertexAttribs4fvNV(index_:Int,n_:Int,v_:Float Ptr)="__glewVertexAttribs4fvNV" +Global glVertexAttribs4svNV(index_:Int,n_:Int,v_:Short Ptr)="__glewVertexAttribs4svNV" +Global glVertexAttribs4ubvNV(index_:Int,n_:Int,v_:Byte Ptr)="__glewVertexAttribs4ubvNV" +Global GL_NV_vertex_program:Byte="__GLEW_NV_vertex_program" +Global GL_NV_vertex_program1_1:Byte="__GLEW_NV_vertex_program1_1" +Global GL_NV_vertex_program2:Byte="__GLEW_NV_vertex_program2" +Global GL_NV_vertex_program2_option:Byte="__GLEW_NV_vertex_program2_option" +Global GL_NV_vertex_program3:Byte="__GLEW_NV_vertex_program3" +Global GL_NV_vertex_program4:Byte="__GLEW_NV_vertex_program4" +Global GL_OES_byte_coordinates:Byte="__GLEW_OES_byte_coordinates" +Const GL_PALETTE4_RGB8_OES=$8B90 +Const GL_PALETTE4_RGBA8_OES=$8B91 +Const GL_PALETTE4_R5_G6_B5_OES=$8B92 +Const GL_PALETTE4_RGBA4_OES=$8B93 +Const GL_PALETTE4_RGB5_A1_OES=$8B94 +Const GL_PALETTE8_RGB8_OES=$8B95 +Const GL_PALETTE8_RGBA8_OES=$8B96 +Const GL_PALETTE8_R5_G6_B5_OES=$8B97 +Const GL_PALETTE8_RGBA4_OES=$8B98 +Const GL_PALETTE8_RGB5_A1_OES=$8B99 +Global GL_OES_compressed_paletted_texture:Byte="__GLEW_OES_compressed_paletted_texture" +Const GL_IMPLEMENTATION_COLOR_READ_TYPE_OES=$8B9A +Const GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES=$8B9B +Global GL_OES_read_format:Byte="__GLEW_OES_read_format" +Global glClearDepthfOES(depth_:Double)="__glewClearDepthfOES" +Global glClipPlanefOES(plane_:Int,equation_:Float Ptr)="__glewClipPlanefOES" +Global glDepthRangefOES(n_:Float,f_:Float)="__glewDepthRangefOES" +Global glFrustumfOES(l_:Float,r_:Float,b_:Float,t_:Float,n_:Float,f_:Float)="__glewFrustumfOES" +Global glGetClipPlanefOES(plane_:Int,equation_:Float Ptr)="__glewGetClipPlanefOES" +Global glOrthofOES(l_:Float,r_:Float,b_:Float,t_:Float,n_:Float,f_:Float)="__glewOrthofOES" +Global GL_OES_single_precision:Byte="__GLEW_OES_single_precision" +Const GL_INTERLACE_OML=$8980 +Const GL_INTERLACE_READ_OML=$8981 +Global GL_OML_interlace:Byte="__GLEW_OML_interlace" +Const GL_PACK_RESAMPLE_OML=$8984 +Const GL_UNPACK_RESAMPLE_OML=$8985 +Const GL_RESAMPLE_REPLICATE_OML=$8986 +Const GL_RESAMPLE_ZERO_FILL_OML=$8987 +Const GL_RESAMPLE_AVERAGE_OML=$8988 +Const GL_RESAMPLE_DECIMATE_OML=$8989 +Global GL_OML_resample:Byte="__GLEW_OML_resample" +Const GL_FORMAT_SUBSAMPLE_24_24_OML=$8982 +Const GL_FORMAT_SUBSAMPLE_244_244_OML=$8983 +Global GL_OML_subsample:Byte="__GLEW_OML_subsample" +Const GL_PREFER_DOUBLEBUFFER_HINT_PGI=107000 +Const GL_CONSERVE_MEMORY_HINT_PGI=107005 +Const GL_RECLAIM_MEMORY_HINT_PGI=107006 +Const GL_NATIVE_GRAPHICS_HANDLE_PGI=107010 +Const GL_NATIVE_GRAPHICS_BEGIN_HINT_PGI=107011 +Const GL_NATIVE_GRAPHICS_END_HINT_PGI=107012 +Const GL_ALWAYS_FAST_HINT_PGI=107020 +Const GL_ALWAYS_SOFT_HINT_PGI=107021 +Const GL_ALLOW_DRAW_OBJ_HINT_PGI=107022 +Const GL_ALLOW_DRAW_WIN_HINT_PGI=107023 +Const GL_ALLOW_DRAW_FRG_HINT_PGI=107024 +Const GL_ALLOW_DRAW_MEM_HINT_PGI=107025 +Const GL_STRICT_DEPTHFUNC_HINT_PGI=107030 +Const GL_STRICT_LIGHTING_HINT_PGI=107031 +Const GL_STRICT_SCISSOR_HINT_PGI=107032 +Const GL_FULL_STIPPLE_HINT_PGI=107033 +Const GL_CLIP_NEAR_HINT_PGI=107040 +Const GL_CLIP_FAR_HINT_PGI=107041 +Const GL_WIDE_LINE_HINT_PGI=107042 +Const GL_BACK_NORMALS_HINT_PGI=107043 +Global GL_PGI_misc_hints:Byte="__GLEW_PGI_misc_hints" +Const GL_VERTEX23_BIT_PGI=$00000004 +Const GL_VERTEX4_BIT_PGI=$00000008 +Const GL_COLOR3_BIT_PGI=$00010000 +Const GL_COLOR4_BIT_PGI=$00020000 +Const GL_EDGEFLAG_BIT_PGI=$00040000 +Const GL_INDEX_BIT_PGI=$00080000 +Const GL_MAT_AMBIENT_BIT_PGI=$00100000 +Const GL_VERTEX_DATA_HINT_PGI=107050 +Const GL_VERTEX_CONSISTENT_HINT_PGI=107051 +Const GL_MATERIAL_SIDE_HINT_PGI=107052 +Const GL_MAX_VERTEX_HINT_PGI=107053 +Const GL_MAT_AMBIENT_AND_DIFFUSE_BIT_PGI=$00200000 +Const GL_MAT_DIFFUSE_BIT_PGI=$00400000 +Const GL_MAT_EMISSION_BIT_PGI=$00800000 +Const GL_MAT_COLOR_INDEXES_BIT_PGI=$01000000 +Const GL_MAT_SHININESS_BIT_PGI=$02000000 +Const GL_MAT_SPECULAR_BIT_PGI=$04000000 +Const GL_NORMAL_BIT_PGI=$08000000 +Const GL_TEXCOORD1_BIT_PGI=$10000000 +Const GL_TEXCOORD2_BIT_PGI=$20000000 +Const GL_TEXCOORD3_BIT_PGI=$40000000 +Const GL_TEXCOORD4_BIT_PGI=$80000000 +Global GL_PGI_vertex_hints:Byte="__GLEW_PGI_vertex_hints" +Const GL_SCREEN_COORDINATES_REND=$8490 +Const GL_INVERTED_SCREEN_W_REND=$8491 +Global GL_REND_screen_coordinates:Byte="__GLEW_REND_screen_coordinates" +Const GL_RGB_S3TC=$83A0 +Const GL_RGB4_S3TC=$83A1 +Const GL_RGBA_S3TC=$83A2 +Const GL_RGBA4_S3TC=$83A3 +Const GL_RGBA_DXT5_S3TC=$83A4 +Const GL_RGBA4_DXT5_S3TC=$83A5 +Global GL_S3_s3tc:Byte="__GLEW_S3_s3tc" +Const GL_EXTENDED_RANGE_SGIS=$85A5 +Const GL_MIN_RED_SGIS=$85A6 +Const GL_MAX_RED_SGIS=$85A7 +Const GL_MIN_GREEN_SGIS=$85A8 +Const GL_MAX_GREEN_SGIS=$85A9 +Const GL_MIN_BLUE_SGIS=$85AA +Const GL_MAX_BLUE_SGIS=$85AB +Const GL_MIN_ALPHA_SGIS=$85AC +Const GL_MAX_ALPHA_SGIS=$85AD +Global GL_SGIS_color_range:Byte="__GLEW_SGIS_color_range" +Global glDetailTexFuncSGIS(target_:Int,n_:Int,points_:Float Ptr)="__glewDetailTexFuncSGIS" +Global glGetDetailTexFuncSGIS(target_:Int,points_:Float Ptr)="__glewGetDetailTexFuncSGIS" +Global GL_SGIS_detail_texture:Byte="__GLEW_SGIS_detail_texture" +Global glFogFuncSGIS(n_:Int,points_:Float Ptr)="__glewFogFuncSGIS" +Global glGetFogFuncSGIS(points_:Float Ptr)="__glewGetFogFuncSGIS" +Global GL_SGIS_fog_function:Byte="__GLEW_SGIS_fog_function" +Const GL_GENERATE_MIPMAP_SGIS=$8191 +Const GL_GENERATE_MIPMAP_HINT_SGIS=$8192 +Global GL_SGIS_generate_mipmap:Byte="__GLEW_SGIS_generate_mipmap" +Const GL_MULTISAMPLE_SGIS=$809D +Const GL_SAMPLE_ALPHA_TO_MASK_SGIS=$809E +Const GL_SAMPLE_ALPHA_TO_ONE_SGIS=$809F +Const GL_SAMPLE_MASK_SGIS=$80A0 +Const GL_1PASS_SGIS=$80A1 +Const GL_2PASS_0_SGIS=$80A2 +Const GL_2PASS_1_SGIS=$80A3 +Const GL_4PASS_0_SGIS=$80A4 +Const GL_4PASS_1_SGIS=$80A5 +Const GL_4PASS_2_SGIS=$80A6 +Const GL_4PASS_3_SGIS=$80A7 +Const GL_SAMPLE_BUFFERS_SGIS=$80A8 +Const GL_SAMPLES_SGIS=$80A9 +Const GL_SAMPLE_MASK_VALUE_SGIS=$80AA +Const GL_SAMPLE_MASK_INVERT_SGIS=$80AB +Const GL_SAMPLE_PATTERN_SGIS=$80AC +Global glSampleMaskSGIS(value_:Float,invert_:Byte)="__glewSampleMaskSGIS" +Global glSamplePatternSGIS(pattern_:Int)="__glewSamplePatternSGIS" +Global GL_SGIS_multisample:Byte="__GLEW_SGIS_multisample" +Global GL_SGIS_pixel_texture:Byte="__GLEW_SGIS_pixel_texture" +Const GL_EYE_DISTANCE_TO_POINT_SGIS=$81F0 +Const GL_OBJECT_DISTANCE_TO_POINT_SGIS=$81F1 +Const GL_EYE_DISTANCE_TO_LINE_SGIS=$81F2 +Const GL_OBJECT_DISTANCE_TO_LINE_SGIS=$81F3 +Const GL_EYE_POINT_SGIS=$81F4 +Const GL_OBJECT_POINT_SGIS=$81F5 +Const GL_EYE_LINE_SGIS=$81F6 +Const GL_OBJECT_LINE_SGIS=$81F7 +Global GL_SGIS_point_line_texgen:Byte="__GLEW_SGIS_point_line_texgen" +Global glGetSharpenTexFuncSGIS(target_:Int,points_:Float Ptr)="__glewGetSharpenTexFuncSGIS" +Global glSharpenTexFuncSGIS(target_:Int,n_:Int,points_:Float Ptr)="__glewSharpenTexFuncSGIS" +Global GL_SGIS_sharpen_texture:Byte="__GLEW_SGIS_sharpen_texture" +Global glTexImage4DSGIS(target_:Int,level_:Int,internalformat_:Int,width_:Int,height_:Int,depth_:Int,extent_:Int,border_:Int,format_:Int,type_:Int,pixels_:Byte Ptr)="__glewTexImage4DSGIS" +Global glTexSubImage4DSGIS(target_:Int,level_:Int,xoffset_:Int,yoffset_:Int,zoffset_:Int,woffset_:Int,width_:Int,height_:Int,depth_:Int,extent_:Int,format_:Int,type_:Int,pixels_:Byte Ptr)="__glewTexSubImage4DSGIS" +Global GL_SGIS_texture4D:Byte="__GLEW_SGIS_texture4D" +Const GL_CLAMP_TO_BORDER_SGIS=$812D +Global GL_SGIS_texture_border_clamp:Byte="__GLEW_SGIS_texture_border_clamp" +Const GL_CLAMP_TO_EDGE_SGIS=$812F +Global GL_SGIS_texture_edge_clamp:Byte="__GLEW_SGIS_texture_edge_clamp" +Global glGetTexFilterFuncSGIS(target_:Int,filter_:Int,weights_:Float Ptr)="__glewGetTexFilterFuncSGIS" +Global glTexFilterFuncSGIS(target_:Int,filter_:Int,n_:Int,weights_:Float Ptr)="__glewTexFilterFuncSGIS" +Global GL_SGIS_texture_filter4:Byte="__GLEW_SGIS_texture_filter4" +Const GL_TEXTURE_MIN_LOD_SGIS=$813A +Const GL_TEXTURE_MAX_LOD_SGIS=$813B +Const GL_TEXTURE_BASE_LEVEL_SGIS=$813C +Const GL_TEXTURE_MAX_LEVEL_SGIS=$813D +Global GL_SGIS_texture_lod:Byte="__GLEW_SGIS_texture_lod" +Global GL_SGIS_texture_select:Byte="__GLEW_SGIS_texture_select" +Const GL_ASYNC_MARKER_SGIX=$8329 +Global glAsyncMarkerSGIX(marker_:Int)="__glewAsyncMarkerSGIX" +Global glDeleteAsyncMarkersSGIX(marker_:Int,range_:Int)="__glewDeleteAsyncMarkersSGIX" +Global glFinishAsyncSGIX:Int(markerp_:Int Ptr)="__glewFinishAsyncSGIX" +Global glGenAsyncMarkersSGIX:Int(range_:Int)="__glewGenAsyncMarkersSGIX" +Global glIsAsyncMarkerSGIX:Byte(marker_:Int)="__glewIsAsyncMarkerSGIX" +Global glPollAsyncSGIX:Int(markerp_:Int Ptr)="__glewPollAsyncSGIX" +Global GL_SGIX_async:Byte="__GLEW_SGIX_async" +Const GL_ASYNC_HISTOGRAM_SGIX=$832C +Const GL_MAX_ASYNC_HISTOGRAM_SGIX=$832D +Global GL_SGIX_async_histogram:Byte="__GLEW_SGIX_async_histogram" +Const GL_ASYNC_TEX_IMAGE_SGIX=$835C +Const GL_ASYNC_DRAW_PIXELS_SGIX=$835D +Const GL_ASYNC_READ_PIXELS_SGIX=$835E +Const GL_MAX_ASYNC_TEX_IMAGE_SGIX=$835F +Const GL_MAX_ASYNC_DRAW_PIXELS_SGIX=$8360 +Const GL_MAX_ASYNC_READ_PIXELS_SGIX=$8361 +Global GL_SGIX_async_pixel:Byte="__GLEW_SGIX_async_pixel" +Const GL_ALPHA_MIN_SGIX=$8320 +Const GL_ALPHA_MAX_SGIX=$8321 +Global GL_SGIX_blend_alpha_minmax:Byte="__GLEW_SGIX_blend_alpha_minmax" +Global GL_SGIX_clipmap:Byte="__GLEW_SGIX_clipmap" +Const GL_CONVOLUTION_HINT_SGIX=$8316 +Global GL_SGIX_convolution_accuracy:Byte="__GLEW_SGIX_convolution_accuracy" +Const GL_DEPTH_COMPONENT16_SGIX=$81A5 +Const GL_DEPTH_COMPONENT24_SGIX=$81A6 +Const GL_DEPTH_COMPONENT32_SGIX=$81A7 +Global GL_SGIX_depth_texture:Byte="__GLEW_SGIX_depth_texture" +Global glFlushRasterSGIX()="__glewFlushRasterSGIX" +Global GL_SGIX_flush_raster:Byte="__GLEW_SGIX_flush_raster" +Const GL_FOG_OFFSET_SGIX=$8198 +Const GL_FOG_OFFSET_VALUE_SGIX=$8199 +Global GL_SGIX_fog_offset:Byte="__GLEW_SGIX_fog_offset" +Const GL_TEXTURE_FOG_SGIX=0 +Const GL_FOG_PATCHY_FACTOR_SGIX=0 +Const GL_FRAGMENT_FOG_SGIX=0 +Global glTextureFogSGIX(pname_:Int)="__glewTextureFogSGIX" +Global GL_SGIX_fog_texture:Byte="__GLEW_SGIX_fog_texture" +Global glFragmentColorMaterialSGIX(face_:Int,mode_:Int)="__glewFragmentColorMaterialSGIX" +Global glFragmentLightModelfSGIX(pname_:Int,param_:Float)="__glewFragmentLightModelfSGIX" +Global glFragmentLightModelfvSGIX(pname_:Int,params_:Float Ptr)="__glewFragmentLightModelfvSGIX" +Global glFragmentLightModeliSGIX(pname_:Int,param_:Int)="__glewFragmentLightModeliSGIX" +Global glFragmentLightModelivSGIX(pname_:Int,params_:Int Ptr)="__glewFragmentLightModelivSGIX" +Global glFragmentLightfSGIX(light_:Int,pname_:Int,param_:Float)="__glewFragmentLightfSGIX" +Global glFragmentLightfvSGIX(light_:Int,pname_:Int,params_:Float Ptr)="__glewFragmentLightfvSGIX" +Global glFragmentLightiSGIX(light_:Int,pname_:Int,param_:Int)="__glewFragmentLightiSGIX" +Global glFragmentLightivSGIX(light_:Int,pname_:Int,params_:Int Ptr)="__glewFragmentLightivSGIX" +Global glFragmentMaterialfSGIX(face_:Int,pname_:Int,param_:Float)="__glewFragmentMaterialfSGIX" +Global glFragmentMaterialfvSGIX(face_:Int,pname_:Int,params_:Float Ptr)="__glewFragmentMaterialfvSGIX" +Global glFragmentMaterialiSGIX(face_:Int,pname_:Int,param_:Int)="__glewFragmentMaterialiSGIX" +Global glFragmentMaterialivSGIX(face_:Int,pname_:Int,params_:Int Ptr)="__glewFragmentMaterialivSGIX" +Global glGetFragmentLightfvSGIX(light_:Int,value_:Int,data_:Float Ptr)="__glewGetFragmentLightfvSGIX" +Global glGetFragmentLightivSGIX(light_:Int,value_:Int,data_:Int Ptr)="__glewGetFragmentLightivSGIX" +Global glGetFragmentMaterialfvSGIX(face_:Int,pname_:Int,data_:Float Ptr)="__glewGetFragmentMaterialfvSGIX" +Global glGetFragmentMaterialivSGIX(face_:Int,pname_:Int,data_:Int Ptr)="__glewGetFragmentMaterialivSGIX" +Global GL_SGIX_fragment_specular_lighting:Byte="__GLEW_SGIX_fragment_specular_lighting" +Global glFrameZoomSGIX(factor_:Int)="__glewFrameZoomSGIX" +Global GL_SGIX_framezoom:Byte="__GLEW_SGIX_framezoom" +Const GL_INTERLACE_SGIX=$8094 +Global GL_SGIX_interlace:Byte="__GLEW_SGIX_interlace" +Global GL_SGIX_ir_instrument1:Byte="__GLEW_SGIX_ir_instrument1" +Global GL_SGIX_list_priority:Byte="__GLEW_SGIX_list_priority" +Global glPixelTexGenSGIX(mode_:Int)="__glewPixelTexGenSGIX" +Global GL_SGIX_pixel_texture:Byte="__GLEW_SGIX_pixel_texture" +Global GL_SGIX_pixel_texture_bits:Byte="__GLEW_SGIX_pixel_texture_bits" +Global glReferencePlaneSGIX(equation_:Double Ptr)="__glewReferencePlaneSGIX" +Global GL_SGIX_reference_plane:Byte="__GLEW_SGIX_reference_plane" +Const GL_PACK_RESAMPLE_SGIX=$842E +Const GL_UNPACK_RESAMPLE_SGIX=$842F +Const GL_RESAMPLE_DECIMATE_SGIX=$8430 +Const GL_RESAMPLE_REPLICATE_SGIX=$8433 +Const GL_RESAMPLE_ZERO_FILL_SGIX=$8434 +Global GL_SGIX_resample:Byte="__GLEW_SGIX_resample" +Const GL_TEXTURE_COMPARE_SGIX=$819A +Const GL_TEXTURE_COMPARE_OPERATOR_SGIX=$819B +Const GL_TEXTURE_LEQUAL_R_SGIX=$819C +Const GL_TEXTURE_GEQUAL_R_SGIX=$819D +Global GL_SGIX_shadow:Byte="__GLEW_SGIX_shadow" +Const GL_SHADOW_AMBIENT_SGIX=$80BF +Global GL_SGIX_shadow_ambient:Byte="__GLEW_SGIX_shadow_ambient" +Global glSpriteParameterfSGIX(pname_:Int,param_:Float)="__glewSpriteParameterfSGIX" +Global glSpriteParameterfvSGIX(pname_:Int,params_:Float Ptr)="__glewSpriteParameterfvSGIX" +Global glSpriteParameteriSGIX(pname_:Int,param_:Int)="__glewSpriteParameteriSGIX" +Global glSpriteParameterivSGIX(pname_:Int,params_:Int Ptr)="__glewSpriteParameterivSGIX" +Global GL_SGIX_sprite:Byte="__GLEW_SGIX_sprite" +Global glTagSampleBufferSGIX()="__glewTagSampleBufferSGIX" +Global GL_SGIX_tag_sample_buffer:Byte="__GLEW_SGIX_tag_sample_buffer" +Global GL_SGIX_texture_add_env:Byte="__GLEW_SGIX_texture_add_env" +Const GL_TEXTURE_MAX_CLAMP_S_SGIX=$8369 +Const GL_TEXTURE_MAX_CLAMP_T_SGIX=$836A +Const GL_TEXTURE_MAX_CLAMP_R_SGIX=$836B +Global GL_SGIX_texture_coordinate_clamp:Byte="__GLEW_SGIX_texture_coordinate_clamp" +Global GL_SGIX_texture_lod_bias:Byte="__GLEW_SGIX_texture_lod_bias" +Const GL_TEXTURE_MULTI_BUFFER_HINT_SGIX=$812E +Global GL_SGIX_texture_multi_buffer:Byte="__GLEW_SGIX_texture_multi_buffer" +Const GL_RGB_SIGNED_SGIX=$85E0 +Const GL_RGBA_SIGNED_SGIX=$85E1 +Const GL_ALPHA_SIGNED_SGIX=$85E2 +Const GL_LUMINANCE_SIGNED_SGIX=$85E3 +Const GL_INTENSITY_SIGNED_SGIX=$85E4 +Const GL_LUMINANCE_ALPHA_SIGNED_SGIX=$85E5 +Const GL_RGB16_SIGNED_SGIX=$85E6 +Const GL_RGBA16_SIGNED_SGIX=$85E7 +Const GL_ALPHA16_SIGNED_SGIX=$85E8 +Const GL_LUMINANCE16_SIGNED_SGIX=$85E9 +Const GL_INTENSITY16_SIGNED_SGIX=$85EA +Const GL_LUMINANCE16_ALPHA16_SIGNED_SGIX=$85EB +Const GL_RGB_EXTENDED_RANGE_SGIX=$85EC +Const GL_RGBA_EXTENDED_RANGE_SGIX=$85ED +Const GL_ALPHA_EXTENDED_RANGE_SGIX=$85EE +Const GL_LUMINANCE_EXTENDED_RANGE_SGIX=$85EF +Const GL_INTENSITY_EXTENDED_RANGE_SGIX=$85F0 +Const GL_LUMINANCE_ALPHA_EXTENDED_RANGE_SGIX=$85F1 +Const GL_RGB16_EXTENDED_RANGE_SGIX=$85F2 +Const GL_RGBA16_EXTENDED_RANGE_SGIX=$85F3 +Const GL_ALPHA16_EXTENDED_RANGE_SGIX=$85F4 +Const GL_LUMINANCE16_EXTENDED_RANGE_SGIX=$85F5 +Const GL_INTENSITY16_EXTENDED_RANGE_SGIX=$85F6 +Const GL_LUMINANCE16_ALPHA16_EXTENDED_RANGE_SGIX=$85F7 +Const GL_MIN_LUMINANCE_SGIS=$85F8 +Const GL_MAX_LUMINANCE_SGIS=$85F9 +Const GL_MIN_INTENSITY_SGIS=$85FA +Const GL_MAX_INTENSITY_SGIS=$85FB +Global GL_SGIX_texture_range:Byte="__GLEW_SGIX_texture_range" +Const GL_POST_TEXTURE_FILTER_BIAS_SGIX=$8179 +Const GL_POST_TEXTURE_FILTER_SCALE_SGIX=$817A +Const GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX=$817B +Const GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX=$817C +Global GL_SGIX_texture_scale_bias:Byte="__GLEW_SGIX_texture_scale_bias" +Const GL_VERTEX_PRECLIP_SGIX=$83EE +Const GL_VERTEX_PRECLIP_HINT_SGIX=$83EF +Global GL_SGIX_vertex_preclip:Byte="__GLEW_SGIX_vertex_preclip" +Global GL_SGIX_vertex_preclip_hint:Byte="__GLEW_SGIX_vertex_preclip_hint" +Global GL_SGIX_ycrcb:Byte="__GLEW_SGIX_ycrcb" +Const GL_COLOR_MATRIX_SGI=$80B1 +Const GL_COLOR_MATRIX_STACK_DEPTH_SGI=$80B2 +Const GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI=$80B3 +Const GL_POST_COLOR_MATRIX_RED_SCALE_SGI=$80B4 +Const GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI=$80B5 +Const GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI=$80B6 +Const GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI=$80B7 +Const GL_POST_COLOR_MATRIX_RED_BIAS_SGI=$80B8 +Const GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI=$80B9 +Const GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI=$80BA +Const GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI=$80BB +Global GL_SGI_color_matrix:Byte="__GLEW_SGI_color_matrix" +Const GL_COLOR_TABLE_SGI=$80D0 +Const GL_POST_CONVOLUTION_COLOR_TABLE_SGI=$80D1 +Const GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI=$80D2 +Const GL_PROXY_COLOR_TABLE_SGI=$80D3 +Const GL_PROXY_POST_CONVOLUTION_COLOR_TABLE_SGI=$80D4 +Const GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_SGI=$80D5 +Const GL_COLOR_TABLE_SCALE_SGI=$80D6 +Const GL_COLOR_TABLE_BIAS_SGI=$80D7 +Const GL_COLOR_TABLE_FORMAT_SGI=$80D8 +Const GL_COLOR_TABLE_WIDTH_SGI=$80D9 +Const GL_COLOR_TABLE_RED_SIZE_SGI=$80DA +Const GL_COLOR_TABLE_GREEN_SIZE_SGI=$80DB +Const GL_COLOR_TABLE_BLUE_SIZE_SGI=$80DC +Const GL_COLOR_TABLE_ALPHA_SIZE_SGI=$80DD +Const GL_COLOR_TABLE_LUMINANCE_SIZE_SGI=$80DE +Const GL_COLOR_TABLE_INTENSITY_SIZE_SGI=$80DF +Global glColorTableParameterfvSGI(target_:Int,pname_:Int,params_:Float Ptr)="__glewColorTableParameterfvSGI" +Global glColorTableParameterivSGI(target_:Int,pname_:Int,params_:Int Ptr)="__glewColorTableParameterivSGI" +Global glColorTableSGI(target_:Int,internalformat_:Int,width_:Int,format_:Int,type_:Int,table_:Byte Ptr)="__glewColorTableSGI" +Global glCopyColorTableSGI(target_:Int,internalformat_:Int,x_:Int,y_:Int,width_:Int)="__glewCopyColorTableSGI" +Global glGetColorTableParameterfvSGI(target_:Int,pname_:Int,params_:Float Ptr)="__glewGetColorTableParameterfvSGI" +Global glGetColorTableParameterivSGI(target_:Int,pname_:Int,params_:Int Ptr)="__glewGetColorTableParameterivSGI" +Global glGetColorTableSGI(target_:Int,format_:Int,type_:Int,table_:Byte Ptr)="__glewGetColorTableSGI" +Global GL_SGI_color_table:Byte="__GLEW_SGI_color_table" +Const GL_TEXTURE_COLOR_TABLE_SGI=$80BC +Const GL_PROXY_TEXTURE_COLOR_TABLE_SGI=$80BD +Global GL_SGI_texture_color_table:Byte="__GLEW_SGI_texture_color_table" +Const GL_UNPACK_CONSTANT_DATA_SUNX=$81D5 +Const GL_TEXTURE_CONSTANT_DATA_SUNX=$81D6 +Global glFinishTextureSUNX()="__glewFinishTextureSUNX" +Global GL_SUNX_constant_data:Byte="__GLEW_SUNX_constant_data" +Const GL_WRAP_BORDER_SUN=$81D4 +Global GL_SUN_convolution_border_modes:Byte="__GLEW_SUN_convolution_border_modes" +Const GL_GLOBAL_ALPHA_SUN=$81D9 +Const GL_GLOBAL_ALPHA_FACTOR_SUN=$81DA +Global glGlobalAlphaFactorbSUN(factor_:Byte)="__glewGlobalAlphaFactorbSUN" +Global glGlobalAlphaFactordSUN(factor_:Double)="__glewGlobalAlphaFactordSUN" +Global glGlobalAlphaFactorfSUN(factor_:Float)="__glewGlobalAlphaFactorfSUN" +Global glGlobalAlphaFactoriSUN(factor_:Int)="__glewGlobalAlphaFactoriSUN" +Global glGlobalAlphaFactorsSUN(factor_:Short)="__glewGlobalAlphaFactorsSUN" +Global glGlobalAlphaFactorubSUN(factor_:Byte)="__glewGlobalAlphaFactorubSUN" +Global glGlobalAlphaFactoruiSUN(factor_:Int)="__glewGlobalAlphaFactoruiSUN" +Global glGlobalAlphaFactorusSUN(factor_:Short)="__glewGlobalAlphaFactorusSUN" +Global GL_SUN_global_alpha:Byte="__GLEW_SUN_global_alpha" +Const GL_QUAD_MESH_SUN=$8614 +Const GL_TRIANGLE_MESH_SUN=$8615 +Global GL_SUN_mesh_array:Byte="__GLEW_SUN_mesh_array" +Global glReadVideoPixelsSUN(x_:Int,y_:Int,width_:Int,height_:Int,format_:Int,type_:Int,pixels_:Byte Ptr)="__glewReadVideoPixelsSUN" +Global GL_SUN_read_video_pixels:Byte="__GLEW_SUN_read_video_pixels" +Const GL_SLICE_ACCUM_SUN=$85CC +Global GL_SUN_slice_accum:Byte="__GLEW_SUN_slice_accum" +Const GL_RESTART_SUN=$01 +Const GL_REPLACE_MIDDLE_SUN=$02 +Const GL_REPLACE_OLDEST_SUN=$03 +Const GL_TRIANGLE_LIST_SUN=$81D7 +Const GL_REPLACEMENT_CODE_SUN=$81D8 +Const GL_REPLACEMENT_CODE_ARRAY_SUN=$85C0 +Const GL_REPLACEMENT_CODE_ARRAY_TYPE_SUN=$85C1 +Const GL_REPLACEMENT_CODE_ARRAY_STRIDE_SUN=$85C2 +Const GL_REPLACEMENT_CODE_ARRAY_POINTER_SUN=$85C3 +Const GL_R1UI_V3F_SUN=$85C4 +Const GL_R1UI_C4UB_V3F_SUN=$85C5 +Const GL_R1UI_C3F_V3F_SUN=$85C6 +Const GL_R1UI_N3F_V3F_SUN=$85C7 +Const GL_R1UI_C4F_N3F_V3F_SUN=$85C8 +Const GL_R1UI_T2F_V3F_SUN=$85C9 +Const GL_R1UI_T2F_N3F_V3F_SUN=$85CA +Const GL_R1UI_T2F_C4F_N3F_V3F_SUN=$85CB +Global glReplacementCodePointerSUN(type_:Int,stride_:Int,pointer_:Byte Ptr)="__glewReplacementCodePointerSUN" +Global glReplacementCodeubSUN(code_:Byte)="__glewReplacementCodeubSUN" +Global glReplacementCodeubvSUN(code_:Byte Ptr)="__glewReplacementCodeubvSUN" +Global glReplacementCodeuiSUN(code_:Int)="__glewReplacementCodeuiSUN" +Global glReplacementCodeuivSUN(code_:Int Ptr)="__glewReplacementCodeuivSUN" +Global glReplacementCodeusSUN(code_:Short)="__glewReplacementCodeusSUN" +Global glReplacementCodeusvSUN(code_:Short Ptr)="__glewReplacementCodeusvSUN" +Global GL_SUN_triangle_list:Byte="__GLEW_SUN_triangle_list" +Global glColor3fVertex3fSUN(r_:Float,g_:Float,b_:Float,x_:Float,y_:Float,z_:Float)="__glewColor3fVertex3fSUN" +Global glColor3fVertex3fvSUN(c_:Float Ptr,v_:Float Ptr)="__glewColor3fVertex3fvSUN" +Global glColor4fNormal3fVertex3fSUN(r_:Float,g_:Float,b_:Float,a_:Float,nx_:Float,ny_:Float,nz_:Float,x_:Float,y_:Float,z_:Float)="__glewColor4fNormal3fVertex3fSUN" +Global glColor4fNormal3fVertex3fvSUN(c_:Float Ptr,n_:Float Ptr,v_:Float Ptr)="__glewColor4fNormal3fVertex3fvSUN" +Global glColor4ubVertex2fSUN(r_:Byte,g_:Byte,b_:Byte,a_:Byte,x_:Float,y_:Float)="__glewColor4ubVertex2fSUN" +Global glColor4ubVertex2fvSUN(c_:Byte Ptr,v_:Float Ptr)="__glewColor4ubVertex2fvSUN" +Global glColor4ubVertex3fSUN(r_:Byte,g_:Byte,b_:Byte,a_:Byte,x_:Float,y_:Float,z_:Float)="__glewColor4ubVertex3fSUN" +Global glColor4ubVertex3fvSUN(c_:Byte Ptr,v_:Float Ptr)="__glewColor4ubVertex3fvSUN" +Global glNormal3fVertex3fSUN(nx_:Float,ny_:Float,nz_:Float,x_:Float,y_:Float,z_:Float)="__glewNormal3fVertex3fSUN" +Global glNormal3fVertex3fvSUN(n_:Float Ptr,v_:Float Ptr)="__glewNormal3fVertex3fvSUN" +Global glReplacementCodeuiColor3fVertex3fSUN(rc_:Int,r_:Float,g_:Float,b_:Float,x_:Float,y_:Float,z_:Float)="__glewReplacementCodeuiColor3fVertex3fSUN" +Global glReplacementCodeuiColor3fVertex3fvSUN(rc_:Int Ptr,c_:Float Ptr,v_:Float Ptr)="__glewReplacementCodeuiColor3fVertex3fvSUN" +Global glReplacementCodeuiColor4fNormal3fVertex3fSUN(rc_:Int,r_:Float,g_:Float,b_:Float,a_:Float,nx_:Float,ny_:Float,nz_:Float,x_:Float,y_:Float,z_:Float)="__glewReplacementCodeuiColor4fNormal3fVertex3fSUN" +Global glReplacementCodeuiColor4fNormal3fVertex3fvSUN(rc_:Int Ptr,c_:Float Ptr,n_:Float Ptr,v_:Float Ptr)="__glewReplacementCodeuiColor4fNormal3fVertex3fvSUN" +Global glReplacementCodeuiColor4ubVertex3fSUN(rc_:Int,r_:Byte,g_:Byte,b_:Byte,a_:Byte,x_:Float,y_:Float,z_:Float)="__glewReplacementCodeuiColor4ubVertex3fSUN" +Global glReplacementCodeuiColor4ubVertex3fvSUN(rc_:Int Ptr,c_:Byte Ptr,v_:Float Ptr)="__glewReplacementCodeuiColor4ubVertex3fvSUN" +Global glReplacementCodeuiNormal3fVertex3fSUN(rc_:Int,nx_:Float,ny_:Float,nz_:Float,x_:Float,y_:Float,z_:Float)="__glewReplacementCodeuiNormal3fVertex3fSUN" +Global glReplacementCodeuiNormal3fVertex3fvSUN(rc_:Int Ptr,n_:Float Ptr,v_:Float Ptr)="__glewReplacementCodeuiNormal3fVertex3fvSUN" +Global glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN(rc_:Int,s_:Float,t_:Float,r_:Float,g_:Float,b_:Float,a_:Float,nx_:Float,ny_:Float,nz_:Float,x_:Float,y_:Float,z_:Float)="__glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN" +Global glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN(rc_:Int Ptr,tc_:Float Ptr,c_:Float Ptr,n_:Float Ptr,v_:Float Ptr)="__glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN" +Global glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN(rc_:Int,s_:Float,t_:Float,nx_:Float,ny_:Float,nz_:Float,x_:Float,y_:Float,z_:Float)="__glewReplacementCodeuiTexCoord2fNormal3fVertex3fSUN" +Global glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN(rc_:Int Ptr,tc_:Float Ptr,n_:Float Ptr,v_:Float Ptr)="__glewReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN" +Global glReplacementCodeuiTexCoord2fVertex3fSUN(rc_:Int,s_:Float,t_:Float,x_:Float,y_:Float,z_:Float)="__glewReplacementCodeuiTexCoord2fVertex3fSUN" +Global glReplacementCodeuiTexCoord2fVertex3fvSUN(rc_:Int Ptr,tc_:Float Ptr,v_:Float Ptr)="__glewReplacementCodeuiTexCoord2fVertex3fvSUN" +Global glReplacementCodeuiVertex3fSUN(rc_:Int,x_:Float,y_:Float,z_:Float)="__glewReplacementCodeuiVertex3fSUN" +Global glReplacementCodeuiVertex3fvSUN(rc_:Int Ptr,v_:Float Ptr)="__glewReplacementCodeuiVertex3fvSUN" +Global glTexCoord2fColor3fVertex3fSUN(s_:Float,t_:Float,r_:Float,g_:Float,b_:Float,x_:Float,y_:Float,z_:Float)="__glewTexCoord2fColor3fVertex3fSUN" +Global glTexCoord2fColor3fVertex3fvSUN(tc_:Float Ptr,c_:Float Ptr,v_:Float Ptr)="__glewTexCoord2fColor3fVertex3fvSUN" +Global glTexCoord2fColor4fNormal3fVertex3fSUN(s_:Float,t_:Float,r_:Float,g_:Float,b_:Float,a_:Float,nx_:Float,ny_:Float,nz_:Float,x_:Float,y_:Float,z_:Float)="__glewTexCoord2fColor4fNormal3fVertex3fSUN" +Global glTexCoord2fColor4fNormal3fVertex3fvSUN(tc_:Float Ptr,c_:Float Ptr,n_:Float Ptr,v_:Float Ptr)="__glewTexCoord2fColor4fNormal3fVertex3fvSUN" +Global glTexCoord2fColor4ubVertex3fSUN(s_:Float,t_:Float,r_:Byte,g_:Byte,b_:Byte,a_:Byte,x_:Float,y_:Float,z_:Float)="__glewTexCoord2fColor4ubVertex3fSUN" +Global glTexCoord2fColor4ubVertex3fvSUN(tc_:Float Ptr,c_:Byte Ptr,v_:Float Ptr)="__glewTexCoord2fColor4ubVertex3fvSUN" +Global glTexCoord2fNormal3fVertex3fSUN(s_:Float,t_:Float,nx_:Float,ny_:Float,nz_:Float,x_:Float,y_:Float,z_:Float)="__glewTexCoord2fNormal3fVertex3fSUN" +Global glTexCoord2fNormal3fVertex3fvSUN(tc_:Float Ptr,n_:Float Ptr,v_:Float Ptr)="__glewTexCoord2fNormal3fVertex3fvSUN" +Global glTexCoord2fVertex3fSUN(s_:Float,t_:Float,x_:Float,y_:Float,z_:Float)="__glewTexCoord2fVertex3fSUN" +Global glTexCoord2fVertex3fvSUN(tc_:Float Ptr,v_:Float Ptr)="__glewTexCoord2fVertex3fvSUN" +Global glTexCoord4fColor4fNormal3fVertex4fSUN(s_:Float,t_:Float,p_:Float,q_:Float,r_:Float,g_:Float,b_:Float,a_:Float,nx_:Float,ny_:Float,nz_:Float,x_:Float,y_:Float,z_:Float,w_:Float)="__glewTexCoord4fColor4fNormal3fVertex4fSUN" +Global glTexCoord4fColor4fNormal3fVertex4fvSUN(tc_:Float Ptr,c_:Float Ptr,n_:Float Ptr,v_:Float Ptr)="__glewTexCoord4fColor4fNormal3fVertex4fvSUN" +Global glTexCoord4fVertex4fSUN(s_:Float,t_:Float,p_:Float,q_:Float,x_:Float,y_:Float,z_:Float,w_:Float)="__glewTexCoord4fVertex4fSUN" +Global glTexCoord4fVertex4fvSUN(tc_:Float Ptr,v_:Float Ptr)="__glewTexCoord4fVertex4fvSUN" +Global GL_SUN_vertex:Byte="__GLEW_SUN_vertex" +Const GL_PHONG_WIN=$80EA +Const GL_PHONG_HINT_WIN=$80EB +Global GL_WIN_phong_shading:Byte="__GLEW_WIN_phong_shading" +Const GL_FOG_SPECULAR_TEXTURE_WIN=$80EC +Global GL_WIN_specular_fog:Byte="__GLEW_WIN_specular_fog" +Global glAddSwapHintRectWIN(x_:Int,y_:Int,width_:Int,height_:Int)="__glewAddSwapHintRectWIN" +Global GL_WIN_swap_hint:Byte="__GLEW_WIN_swap_hint" + +End Extern + +Extern "C" + +Function glewInit() + +End Extern diff --git a/mod/pub.mod/glew.mod/glew.c b/mod/pub.mod/glew.mod/glew.c new file mode 100644 index 0000000..24c6a72 --- /dev/null +++ b/mod/pub.mod/glew.mod/glew.c @@ -0,0 +1,12180 @@ +/* +** The OpenGL Extension Wrangler Library +** Copyright (C) 2002-2008, Milan Ikits <milan ikits[]ieee org> +** Copyright (C) 2002-2008, Marcelo E. Magallon <mmagallo[]debian org> +** Copyright (C) 2002, Lev Povalahev +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are met: +** +** * Redistributions of source code must retain the above copyright notice, +** this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright notice, +** this list of conditions and the following disclaimer in the documentation +** and/or other materials provided with the distribution. +** * The name of the author may be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +** THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include <GL/glew.h> +#if defined(_WIN32) +# include <GL/wglew.h> +#elif !defined(__APPLE__) || defined(GLEW_APPLE_GLX) +# include <GL/glxew.h> +#endif + +/* + * Define glewGetContext and related helper macros. + */ +#ifdef GLEW_MX +# define glewGetContext() ctx +# ifdef _WIN32 +# define GLEW_CONTEXT_ARG_DEF_INIT GLEWContext* ctx +# define GLEW_CONTEXT_ARG_VAR_INIT ctx +# define wglewGetContext() ctx +# define WGLEW_CONTEXT_ARG_DEF_INIT WGLEWContext* ctx +# define WGLEW_CONTEXT_ARG_DEF_LIST WGLEWContext* ctx +# else /* _WIN32 */ +# define GLEW_CONTEXT_ARG_DEF_INIT void +# define GLEW_CONTEXT_ARG_VAR_INIT +# define glxewGetContext() ctx +# define GLXEW_CONTEXT_ARG_DEF_INIT void +# define GLXEW_CONTEXT_ARG_DEF_LIST GLXEWContext* ctx +# endif /* _WIN32 */ +# define GLEW_CONTEXT_ARG_DEF_LIST GLEWContext* ctx +#else /* GLEW_MX */ +# define GLEW_CONTEXT_ARG_DEF_INIT void +# define GLEW_CONTEXT_ARG_VAR_INIT +# define GLEW_CONTEXT_ARG_DEF_LIST void +# define WGLEW_CONTEXT_ARG_DEF_INIT void +# define WGLEW_CONTEXT_ARG_DEF_LIST void +# define GLXEW_CONTEXT_ARG_DEF_INIT void +# define GLXEW_CONTEXT_ARG_DEF_LIST void +#endif /* GLEW_MX */ + +#if defined(__APPLE__) +#include <mach-o/dyld.h> +#include <stdlib.h> +#include <string.h> + +void* NSGLGetProcAddress (const GLubyte *name) +{ + static const struct mach_header* image = NULL; + NSSymbol symbol; + char* symbolName; + if (NULL == image) + { + image = NSAddImage("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", NSADDIMAGE_OPTION_RETURN_ON_ERROR); + } + /* prepend a '_' for the Unix C symbol mangling convention */ + symbolName = malloc(strlen((const char*)name) + 2); + strcpy(symbolName+1, (const char*)name); + symbolName[0] = '_'; + symbol = NULL; + /* if (NSIsSymbolNameDefined(symbolName)) + symbol = NSLookupAndBindSymbol(symbolName); */ + symbol = image ? NSLookupSymbolInImage(image, symbolName, NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR) : NULL; + free(symbolName); + return symbol ? NSAddressOfSymbol(symbol) : NULL; +} +#endif /* __APPLE__ */ + +#if defined(__sgi) || defined (__sun) +#include <dlfcn.h> +#include <stdio.h> +#include <stdlib.h> + +void* dlGetProcAddress (const GLubyte* name) +{ + static void* h = NULL; + static void* gpa; + + if (h == NULL) + { + if ((h = dlopen(NULL, RTLD_LAZY | RTLD_LOCAL)) == NULL) return NULL; + gpa = dlsym(h, "glXGetProcAddress"); + } + + if (gpa != NULL) + return ((void*(*)(const GLubyte*))gpa)(name); + else + return dlsym(h, (const char*)name); +} +#endif /* __sgi || __sun */ + +/* + * Define glewGetProcAddress. + */ +#if defined(_WIN32) +# define glewGetProcAddress(name) wglGetProcAddress((LPCSTR)name) +#else +# if defined(__APPLE__) +# define glewGetProcAddress(name) NSGLGetProcAddress(name) +# else +# if defined(__sgi) || defined(__sun) +# define glewGetProcAddress(name) dlGetProcAddress(name) +# else /* __linux */ +# define glewGetProcAddress(name) (*glXGetProcAddressARB)(name) +# endif +# endif +#endif + +/* + * Define GLboolean const cast. + */ +#define CONST_CAST(x) (*(GLboolean*)&x) + +/* + * GLEW, just like OpenGL or GLU, does not rely on the standard C library. + * These functions implement the functionality required in this file. + */ +static GLuint _glewStrLen (const GLubyte* s) +{ + GLuint i=0; + if (s == NULL) return 0; + while (s[i] != '\0') i++; + return i; +} + +static GLuint _glewStrCLen (const GLubyte* s, GLubyte c) +{ + GLuint i=0; + if (s == NULL) return 0; + while (s[i] != '\0' && s[i] != c) i++; + return (s[i] == '\0' || s[i] == c) ? i : 0; +} + +static GLboolean _glewStrSame (const GLubyte* a, const GLubyte* b, GLuint n) +{ + GLuint i=0; + if(a == NULL || b == NULL) + return (a == NULL && b == NULL && n == 0) ? GL_TRUE : GL_FALSE; + while (i < n && a[i] != '\0' && b[i] != '\0' && a[i] == b[i]) i++; + return i == n ? GL_TRUE : GL_FALSE; +} + +static GLboolean _glewStrSame1 (GLubyte** a, GLuint* na, const GLubyte* b, GLuint nb) +{ + while (*na > 0 && (**a == ' ' || **a == '\n' || **a == '\r' || **a == '\t')) + { + (*a)++; + (*na)--; + } + if(*na >= nb) + { + GLuint i=0; + while (i < nb && (*a)+i != NULL && b+i != NULL && (*a)[i] == b[i]) i++; + if(i == nb) + { + *a = *a + nb; + *na = *na - nb; + return GL_TRUE; + } + } + return GL_FALSE; +} + +static GLboolean _glewStrSame2 (GLubyte** a, GLuint* na, const GLubyte* b, GLuint nb) +{ + if(*na >= nb) + { + GLuint i=0; + while (i < nb && (*a)+i != NULL && b+i != NULL && (*a)[i] == b[i]) i++; + if(i == nb) + { + *a = *a + nb; + *na = *na - nb; + return GL_TRUE; + } + } + return GL_FALSE; +} + +static GLboolean _glewStrSame3 (GLubyte** a, GLuint* na, const GLubyte* b, GLuint nb) +{ + if(*na >= nb) + { + GLuint i=0; + while (i < nb && (*a)+i != NULL && b+i != NULL && (*a)[i] == b[i]) i++; + if (i == nb && (*na == nb || (*a)[i] == ' ' || (*a)[i] == '\n' || (*a)[i] == '\r' || (*a)[i] == '\t')) + { + *a = *a + nb; + *na = *na - nb; + return GL_TRUE; + } + } + return GL_FALSE; +} + +#if !defined(_WIN32) || !defined(GLEW_MX) + +PFNGLCOPYTEXSUBIMAGE3DPROC __glewCopyTexSubImage3D = NULL; +PFNGLDRAWRANGEELEMENTSPROC __glewDrawRangeElements = NULL; +PFNGLTEXIMAGE3DPROC __glewTexImage3D = NULL; +PFNGLTEXSUBIMAGE3DPROC __glewTexSubImage3D = NULL; + +PFNGLACTIVETEXTUREPROC __glewActiveTexture = NULL; +PFNGLCLIENTACTIVETEXTUREPROC __glewClientActiveTexture = NULL; +PFNGLCOMPRESSEDTEXIMAGE1DPROC __glewCompressedTexImage1D = NULL; +PFNGLCOMPRESSEDTEXIMAGE2DPROC __glewCompressedTexImage2D = NULL; +PFNGLCOMPRESSEDTEXIMAGE3DPROC __glewCompressedTexImage3D = NULL; +PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC __glewCompressedTexSubImage1D = NULL; +PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC __glewCompressedTexSubImage2D = NULL; +PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC __glewCompressedTexSubImage3D = NULL; +PFNGLGETCOMPRESSEDTEXIMAGEPROC __glewGetCompressedTexImage = NULL; +PFNGLLOADTRANSPOSEMATRIXDPROC __glewLoadTransposeMatrixd = NULL; +PFNGLLOADTRANSPOSEMATRIXFPROC __glewLoadTransposeMatrixf = NULL; +PFNGLMULTTRANSPOSEMATRIXDPROC __glewMultTransposeMatrixd = NULL; +PFNGLMULTTRANSPOSEMATRIXFPROC __glewMultTransposeMatrixf = NULL; +PFNGLMULTITEXCOORD1DPROC __glewMultiTexCoord1d = NULL; +PFNGLMULTITEXCOORD1DVPROC __glewMultiTexCoord1dv = NULL; +PFNGLMULTITEXCOORD1FPROC __glewMultiTexCoord1f = NULL; +PFNGLMULTITEXCOORD1FVPROC __glewMultiTexCoord1fv = NULL; +PFNGLMULTITEXCOORD1IPROC __glewMultiTexCoord1i = NULL; +PFNGLMULTITEXCOORD1IVPROC __glewMultiTexCoord1iv = NULL; +PFNGLMULTITEXCOORD1SPROC __glewMultiTexCoord1s = NULL; +PFNGLMULTITEXCOORD1SVPROC __glewMultiTexCoord1sv = NULL; +PFNGLMULTITEXCOORD2DPROC __glewMultiTexCoord2d = NULL; +PFNGLMULTITEXCOORD2DVPROC __glewMultiTexCoord2dv = NULL; +PFNGLMULTITEXCOORD2FPROC __glewMultiTexCoord2f = NULL; +PFNGLMULTITEXCOORD2FVPROC __glewMultiTexCoord2fv = NULL; +PFNGLMULTITEXCOORD2IPROC __glewMultiTexCoord2i = NULL; +PFNGLMULTITEXCOORD2IVPROC __glewMultiTexCoord2iv = NULL; +PFNGLMULTITEXCOORD2SPROC __glewMultiTexCoord2s = NULL; +PFNGLMULTITEXCOORD2SVPROC __glewMultiTexCoord2sv = NULL; +PFNGLMULTITEXCOORD3DPROC __glewMultiTexCoord3d = NULL; +PFNGLMULTITEXCOORD3DVPROC __glewMultiTexCoord3dv = NULL; +PFNGLMULTITEXCOORD3FPROC __glewMultiTexCoord3f = NULL; +PFNGLMULTITEXCOORD3FVPROC __glewMultiTexCoord3fv = NULL; +PFNGLMULTITEXCOORD3IPROC __glewMultiTexCoord3i = NULL; +PFNGLMULTITEXCOORD3IVPROC __glewMultiTexCoord3iv = NULL; +PFNGLMULTITEXCOORD3SPROC __glewMultiTexCoord3s = NULL; +PFNGLMULTITEXCOORD3SVPROC __glewMultiTexCoord3sv = NULL; +PFNGLMULTITEXCOORD4DPROC __glewMultiTexCoord4d = NULL; +PFNGLMULTITEXCOORD4DVPROC __glewMultiTexCoord4dv = NULL; +PFNGLMULTITEXCOORD4FPROC __glewMultiTexCoord4f = NULL; +PFNGLMULTITEXCOORD4FVPROC __glewMultiTexCoord4fv = NULL; +PFNGLMULTITEXCOORD4IPROC __glewMultiTexCoord4i = NULL; +PFNGLMULTITEXCOORD4IVPROC __glewMultiTexCoord4iv = NULL; +PFNGLMULTITEXCOORD4SPROC __glewMultiTexCoord4s = NULL; +PFNGLMULTITEXCOORD4SVPROC __glewMultiTexCoord4sv = NULL; +PFNGLSAMPLECOVERAGEPROC __glewSampleCoverage = NULL; + +PFNGLBLENDCOLORPROC __glewBlendColor = NULL; +PFNGLBLENDEQUATIONPROC __glewBlendEquation = NULL; +PFNGLBLENDFUNCSEPARATEPROC __glewBlendFuncSeparate = NULL; +PFNGLFOGCOORDPOINTERPROC __glewFogCoordPointer = NULL; +PFNGLFOGCOORDDPROC __glewFogCoordd = NULL; +PFNGLFOGCOORDDVPROC __glewFogCoorddv = NULL; +PFNGLFOGCOORDFPROC __glewFogCoordf = NULL; +PFNGLFOGCOORDFVPROC __glewFogCoordfv = NULL; +PFNGLMULTIDRAWARRAYSPROC __glewMultiDrawArrays = NULL; +PFNGLMULTIDRAWELEMENTSPROC __glewMultiDrawElements = NULL; +PFNGLPOINTPARAMETERFPROC __glewPointParameterf = NULL; +PFNGLPOINTPARAMETERFVPROC __glewPointParameterfv = NULL; +PFNGLPOINTPARAMETERIPROC __glewPointParameteri = NULL; +PFNGLPOINTPARAMETERIVPROC __glewPointParameteriv = NULL; +PFNGLSECONDARYCOLOR3BPROC __glewSecondaryColor3b = NULL; +PFNGLSECONDARYCOLOR3BVPROC __glewSecondaryColor3bv = NULL; +PFNGLSECONDARYCOLOR3DPROC __glewSecondaryColor3d = NULL; +PFNGLSECONDARYCOLOR3DVPROC __glewSecondaryColor3dv = NULL; +PFNGLSECONDARYCOLOR3FPROC __glewSecondaryColor3f = NULL; +PFNGLSECONDARYCOLOR3FVPROC __glewSecondaryColor3fv = NULL; +PFNGLSECONDARYCOLOR3IPROC __glewSecondaryColor3i = NULL; +PFNGLSECONDARYCOLOR3IVPROC __glewSecondaryColor3iv = NULL; +PFNGLSECONDARYCOLOR3SPROC __glewSecondaryColor3s = NULL; +PFNGLSECONDARYCOLOR3SVPROC __glewSecondaryColor3sv = NULL; +PFNGLSECONDARYCOLOR3UBPROC __glewSecondaryColor3ub = NULL; +PFNGLSECONDARYCOLOR3UBVPROC __glewSecondaryColor3ubv = NULL; +PFNGLSECONDARYCOLOR3UIPROC __glewSecondaryColor3ui = NULL; +PFNGLSECONDARYCOLOR3UIVPROC __glewSecondaryColor3uiv = NULL; +PFNGLSECONDARYCOLOR3USPROC __glewSecondaryColor3us = NULL; +PFNGLSECONDARYCOLOR3USVPROC __glewSecondaryColor3usv = NULL; +PFNGLSECONDARYCOLORPOINTERPROC __glewSecondaryColorPointer = NULL; +PFNGLWINDOWPOS2DPROC __glewWindowPos2d = NULL; +PFNGLWINDOWPOS2DVPROC __glewWindowPos2dv = NULL; +PFNGLWINDOWPOS2FPROC __glewWindowPos2f = NULL; +PFNGLWINDOWPOS2FVPROC __glewWindowPos2fv = NULL; +PFNGLWINDOWPOS2IPROC __glewWindowPos2i = NULL; +PFNGLWINDOWPOS2IVPROC __glewWindowPos2iv = NULL; +PFNGLWINDOWPOS2SPROC __glewWindowPos2s = NULL; +PFNGLWINDOWPOS2SVPROC __glewWindowPos2sv = NULL; +PFNGLWINDOWPOS3DPROC __glewWindowPos3d = NULL; +PFNGLWINDOWPOS3DVPROC __glewWindowPos3dv = NULL; +PFNGLWINDOWPOS3FPROC __glewWindowPos3f = NULL; +PFNGLWINDOWPOS3FVPROC __glewWindowPos3fv = NULL; +PFNGLWINDOWPOS3IPROC __glewWindowPos3i = NULL; +PFNGLWINDOWPOS3IVPROC __glewWindowPos3iv = NULL; +PFNGLWINDOWPOS3SPROC __glewWindowPos3s = NULL; +PFNGLWINDOWPOS3SVPROC __glewWindowPos3sv = NULL; + +PFNGLBEGINQUERYPROC __glewBeginQuery = NULL; +PFNGLBINDBUFFERPROC __glewBindBuffer = NULL; +PFNGLBUFFERDATAPROC __glewBufferData = NULL; +PFNGLBUFFERSUBDATAPROC __glewBufferSubData = NULL; +PFNGLDELETEBUFFERSPROC __glewDeleteBuffers = NULL; +PFNGLDELETEQUERIESPROC __glewDeleteQueries = NULL; +PFNGLENDQUERYPROC __glewEndQuery = NULL; +PFNGLGENBUFFERSPROC __glewGenBuffers = NULL; +PFNGLGENQUERIESPROC __glewGenQueries = NULL; +PFNGLGETBUFFERPARAMETERIVPROC __glewGetBufferParameteriv = NULL; +PFNGLGETBUFFERPOINTERVPROC __glewGetBufferPointerv = NULL; +PFNGLGETBUFFERSUBDATAPROC __glewGetBufferSubData = NULL; +PFNGLGETQUERYOBJECTIVPROC __glewGetQueryObjectiv = NULL; +PFNGLGETQUERYOBJECTUIVPROC __glewGetQueryObjectuiv = NULL; +PFNGLGETQUERYIVPROC __glewGetQueryiv = NULL; +PFNGLISBUFFERPROC __glewIsBuffer = NULL; +PFNGLISQUERYPROC __glewIsQuery = NULL; +PFNGLMAPBUFFERPROC __glewMapBuffer = NULL; +PFNGLUNMAPBUFFERPROC __glewUnmapBuffer = NULL; + +PFNGLATTACHSHADERPROC __glewAttachShader = NULL; +PFNGLBINDATTRIBLOCATIONPROC __glewBindAttribLocation = NULL; +PFNGLBLENDEQUATIONSEPARATEPROC __glewBlendEquationSeparate = NULL; +PFNGLCOMPILESHADERPROC __glewCompileShader = NULL; +PFNGLCREATEPROGRAMPROC __glewCreateProgram = NULL; +PFNGLCREATESHADERPROC __glewCreateShader = NULL; +PFNGLDELETEPROGRAMPROC __glewDeleteProgram = NULL; +PFNGLDELETESHADERPROC __glewDeleteShader = NULL; +PFNGLDETACHSHADERPROC __glewDetachShader = NULL; +PFNGLDISABLEVERTEXATTRIBARRAYPROC __glewDisableVertexAttribArray = NULL; +PFNGLDRAWBUFFERSPROC __glewDrawBuffers = NULL; +PFNGLENABLEVERTEXATTRIBARRAYPROC __glewEnableVertexAttribArray = NULL; +PFNGLGETACTIVEATTRIBPROC __glewGetActiveAttrib = NULL; +PFNGLGETACTIVEUNIFORMPROC __glewGetActiveUniform = NULL; +PFNGLGETATTACHEDSHADERSPROC __glewGetAttachedShaders = NULL; +PFNGLGETATTRIBLOCATIONPROC __glewGetAttribLocation = NULL; +PFNGLGETPROGRAMINFOLOGPROC __glewGetProgramInfoLog = NULL; +PFNGLGETPROGRAMIVPROC __glewGetProgramiv = NULL; +PFNGLGETSHADERINFOLOGPROC __glewGetShaderInfoLog = NULL; +PFNGLGETSHADERSOURCEPROC __glewGetShaderSource = NULL; +PFNGLGETSHADERIVPROC __glewGetShaderiv = NULL; +PFNGLGETUNIFORMLOCATIONPROC __glewGetUniformLocation = NULL; +PFNGLGETUNIFORMFVPROC __glewGetUniformfv = NULL; +PFNGLGETUNIFORMIVPROC __glewGetUniformiv = NULL; +PFNGLGETVERTEXATTRIBPOINTERVPROC __glewGetVertexAttribPointerv = NULL; +PFNGLGETVERTEXATTRIBDVPROC __glewGetVertexAttribdv = NULL; +PFNGLGETVERTEXATTRIBFVPROC __glewGetVertexAttribfv = NULL; +PFNGLGETVERTEXATTRIBIVPROC __glewGetVertexAttribiv = NULL; +PFNGLISPROGRAMPROC __glewIsProgram = NULL; +PFNGLISSHADERPROC __glewIsShader = NULL; +PFNGLLINKPROGRAMPROC __glewLinkProgram = NULL; +PFNGLSHADERSOURCEPROC __glewShaderSource = NULL; +PFNGLSTENCILFUNCSEPARATEPROC __glewStencilFuncSeparate = NULL; +PFNGLSTENCILMASKSEPARATEPROC __glewStencilMaskSeparate = NULL; +PFNGLSTENCILOPSEPARATEPROC __glewStencilOpSeparate = NULL; +PFNGLUNIFORM1FPROC __glewUniform1f = NULL; +PFNGLUNIFORM1FVPROC __glewUniform1fv = NULL; +PFNGLUNIFORM1IPROC __glewUniform1i = NULL; +PFNGLUNIFORM1IVPROC __glewUniform1iv = NULL; +PFNGLUNIFORM2FPROC __glewUniform2f = NULL; +PFNGLUNIFORM2FVPROC __glewUniform2fv = NULL; +PFNGLUNIFORM2IPROC __glewUniform2i = NULL; +PFNGLUNIFORM2IVPROC __glewUniform2iv = NULL; +PFNGLUNIFORM3FPROC __glewUniform3f = NULL; +PFNGLUNIFORM3FVPROC __glewUniform3fv = NULL; +PFNGLUNIFORM3IPROC __glewUniform3i = NULL; +PFNGLUNIFORM3IVPROC __glewUniform3iv = NULL; +PFNGLUNIFORM4FPROC __glewUniform4f = NULL; +PFNGLUNIFORM4FVPROC __glewUniform4fv = NULL; +PFNGLUNIFORM4IPROC __glewUniform4i = NULL; +PFNGLUNIFORM4IVPROC __glewUniform4iv = NULL; +PFNGLUNIFORMMATRIX2FVPROC __glewUniformMatrix2fv = NULL; +PFNGLUNIFORMMATRIX3FVPROC __glewUniformMatrix3fv = NULL; +PFNGLUNIFORMMATRIX4FVPROC __glewUniformMatrix4fv = NULL; +PFNGLUSEPROGRAMPROC __glewUseProgram = NULL; +PFNGLVALIDATEPROGRAMPROC __glewValidateProgram = NULL; +PFNGLVERTEXATTRIB1DPROC __glewVertexAttrib1d = NULL; +PFNGLVERTEXATTRIB1DVPROC __glewVertexAttrib1dv = NULL; +PFNGLVERTEXATTRIB1FPROC __glewVertexAttrib1f = NULL; +PFNGLVERTEXATTRIB1FVPROC __glewVertexAttrib1fv = NULL; +PFNGLVERTEXATTRIB1SPROC __glewVertexAttrib1s = NULL; +PFNGLVERTEXATTRIB1SVPROC __glewVertexAttrib1sv = NULL; +PFNGLVERTEXATTRIB2DPROC __glewVertexAttrib2d = NULL; +PFNGLVERTEXATTRIB2DVPROC __glewVertexAttrib2dv = NULL; +PFNGLVERTEXATTRIB2FPROC __glewVertexAttrib2f = NULL; +PFNGLVERTEXATTRIB2FVPROC __glewVertexAttrib2fv = NULL; +PFNGLVERTEXATTRIB2SPROC __glewVertexAttrib2s = NULL; +PFNGLVERTEXATTRIB2SVPROC __glewVertexAttrib2sv = NULL; +PFNGLVERTEXATTRIB3DPROC __glewVertexAttrib3d = NULL; +PFNGLVERTEXATTRIB3DVPROC __glewVertexAttrib3dv = NULL; +PFNGLVERTEXATTRIB3FPROC __glewVertexAttrib3f = NULL; +PFNGLVERTEXATTRIB3FVPROC __glewVertexAttrib3fv = NULL; +PFNGLVERTEXATTRIB3SPROC __glewVertexAttrib3s = NULL; +PFNGLVERTEXATTRIB3SVPROC __glewVertexAttrib3sv = NULL; +PFNGLVERTEXATTRIB4NBVPROC __glewVertexAttrib4Nbv = NULL; +PFNGLVERTEXATTRIB4NIVPROC __glewVertexAttrib4Niv = NULL; +PFNGLVERTEXATTRIB4NSVPROC __glewVertexAttrib4Nsv = NULL; +PFNGLVERTEXATTRIB4NUBPROC __glewVertexAttrib4Nub = NULL; +PFNGLVERTEXATTRIB4NUBVPROC __glewVertexAttrib4Nubv = NULL; +PFNGLVERTEXATTRIB4NUIVPROC __glewVertexAttrib4Nuiv = NULL; +PFNGLVERTEXATTRIB4NUSVPROC __glewVertexAttrib4Nusv = NULL; +PFNGLVERTEXATTRIB4BVPROC __glewVertexAttrib4bv = NULL; +PFNGLVERTEXATTRIB4DPROC __glewVertexAttrib4d = NULL; +PFNGLVERTEXATTRIB4DVPROC __glewVertexAttrib4dv = NULL; +PFNGLVERTEXATTRIB4FPROC __glewVertexAttrib4f = NULL; +PFNGLVERTEXATTRIB4FVPROC __glewVertexAttrib4fv = NULL; +PFNGLVERTEXATTRIB4IVPROC __glewVertexAttrib4iv = NULL; +PFNGLVERTEXATTRIB4SPROC __glewVertexAttrib4s = NULL; +PFNGLVERTEXATTRIB4SVPROC __glewVertexAttrib4sv = NULL; +PFNGLVERTEXATTRIB4UBVPROC __glewVertexAttrib4ubv = NULL; +PFNGLVERTEXATTRIB4UIVPROC __glewVertexAttrib4uiv = NULL; +PFNGLVERTEXATTRIB4USVPROC __glewVertexAttrib4usv = NULL; +PFNGLVERTEXATTRIBPOINTERPROC __glewVertexAttribPointer = NULL; + +PFNGLUNIFORMMATRIX2X3FVPROC __glewUniformMatrix2x3fv = NULL; +PFNGLUNIFORMMATRIX2X4FVPROC __glewUniformMatrix2x4fv = NULL; +PFNGLUNIFORMMATRIX3X2FVPROC __glewUniformMatrix3x2fv = NULL; +PFNGLUNIFORMMATRIX3X4FVPROC __glewUniformMatrix3x4fv = NULL; +PFNGLUNIFORMMATRIX4X2FVPROC __glewUniformMatrix4x2fv = NULL; +PFNGLUNIFORMMATRIX4X3FVPROC __glewUniformMatrix4x3fv = NULL; + +PFNGLBEGINCONDITIONALRENDERPROC __glewBeginConditionalRender = NULL; +PFNGLBEGINTRANSFORMFEEDBACKPROC __glewBeginTransformFeedback = NULL; +PFNGLBINDBUFFERBASEPROC __glewBindBufferBase = NULL; +PFNGLBINDBUFFERRANGEPROC __glewBindBufferRange = NULL; +PFNGLBINDFRAGDATALOCATIONPROC __glewBindFragDataLocation = NULL; +PFNGLCLAMPCOLORPROC __glewClampColor = NULL; +PFNGLCLEARBUFFERFIPROC __glewClearBufferfi = NULL; +PFNGLCLEARBUFFERFVPROC __glewClearBufferfv = NULL; +PFNGLCLEARBUFFERIVPROC __glewClearBufferiv = NULL; +PFNGLCLEARBUFFERUIVPROC __glewClearBufferuiv = NULL; +PFNGLCOLORMASKIPROC __glewColorMaski = NULL; +PFNGLDISABLEIPROC __glewDisablei = NULL; +PFNGLENABLEIPROC __glewEnablei = NULL; +PFNGLENDCONDITIONALRENDERPROC __glewEndConditionalRender = NULL; +PFNGLENDTRANSFORMFEEDBACKPROC __glewEndTransformFeedback = NULL; +PFNGLGETBOOLEANI_VPROC __glewGetBooleani_v = NULL; +PFNGLGETFRAGDATALOCATIONPROC __glewGetFragDataLocation = NULL; +PFNGLGETINTEGERI_VPROC __glewGetIntegeri_v = NULL; +PFNGLGETSTRINGIPROC __glewGetStringi = NULL; +PFNGLGETTEXPARAMETERIIVPROC __glewGetTexParameterIiv = NULL; +PFNGLGETTEXPARAMETERIUIVPROC __glewGetTexParameterIuiv = NULL; +PFNGLGETTRANSFORMFEEDBACKVARYINGPROC __glewGetTransformFeedbackVarying = NULL; +PFNGLGETUNIFORMUIVPROC __glewGetUniformuiv = NULL; +PFNGLGETVERTEXATTRIBIIVPROC __glewGetVertexAttribIiv = NULL; +PFNGLGETVERTEXATTRIBIUIVPROC __glewGetVertexAttribIuiv = NULL; +PFNGLISENABLEDIPROC __glewIsEnabledi = NULL; +PFNGLTEXPARAMETERIIVPROC __glewTexParameterIiv = NULL; +PFNGLTEXPARAMETERIUIVPROC __glewTexParameterIuiv = NULL; +PFNGLTRANSFORMFEEDBACKVARYINGSPROC __glewTransformFeedbackVaryings = NULL; +PFNGLUNIFORM1UIPROC __glewUniform1ui = NULL; +PFNGLUNIFORM1UIVPROC __glewUniform1uiv = NULL; +PFNGLUNIFORM2UIPROC __glewUniform2ui = NULL; +PFNGLUNIFORM2UIVPROC __glewUniform2uiv = NULL; +PFNGLUNIFORM3UIPROC __glewUniform3ui = NULL; +PFNGLUNIFORM3UIVPROC __glewUniform3uiv = NULL; +PFNGLUNIFORM4UIPROC __glewUniform4ui = NULL; +PFNGLUNIFORM4UIVPROC __glewUniform4uiv = NULL; +PFNGLVERTEXATTRIBI1IPROC __glewVertexAttribI1i = NULL; +PFNGLVERTEXATTRIBI1IVPROC __glewVertexAttribI1iv = NULL; +PFNGLVERTEXATTRIBI1UIPROC __glewVertexAttribI1ui = NULL; +PFNGLVERTEXATTRIBI1UIVPROC __glewVertexAttribI1uiv = NULL; +PFNGLVERTEXATTRIBI2IPROC __glewVertexAttribI2i = NULL; +PFNGLVERTEXATTRIBI2IVPROC __glewVertexAttribI2iv = NULL; +PFNGLVERTEXATTRIBI2UIPROC __glewVertexAttribI2ui = NULL; +PFNGLVERTEXATTRIBI2UIVPROC __glewVertexAttribI2uiv = NULL; +PFNGLVERTEXATTRIBI3IPROC __glewVertexAttribI3i = NULL; +PFNGLVERTEXATTRIBI3IVPROC __glewVertexAttribI3iv = NULL; +PFNGLVERTEXATTRIBI3UIPROC __glewVertexAttribI3ui = NULL; +PFNGLVERTEXATTRIBI3UIVPROC __glewVertexAttribI3uiv = NULL; +PFNGLVERTEXATTRIBI4BVPROC __glewVertexAttribI4bv = NULL; +PFNGLVERTEXATTRIBI4IPROC __glewVertexAttribI4i = NULL; +PFNGLVERTEXATTRIBI4IVPROC __glewVertexAttribI4iv = NULL; +PFNGLVERTEXATTRIBI4SVPROC __glewVertexAttribI4sv = NULL; +PFNGLVERTEXATTRIBI4UBVPROC __glewVertexAttribI4ubv = NULL; +PFNGLVERTEXATTRIBI4UIPROC __glewVertexAttribI4ui = NULL; +PFNGLVERTEXATTRIBI4UIVPROC __glewVertexAttribI4uiv = NULL; +PFNGLVERTEXATTRIBI4USVPROC __glewVertexAttribI4usv = NULL; +PFNGLVERTEXATTRIBIPOINTERPROC __glewVertexAttribIPointer = NULL; + +PFNGLTBUFFERMASK3DFXPROC __glewTbufferMask3DFX = NULL; + +PFNGLDRAWELEMENTARRAYAPPLEPROC __glewDrawElementArrayAPPLE = NULL; +PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC __glewDrawRangeElementArrayAPPLE = NULL; +PFNGLELEMENTPOINTERAPPLEPROC __glewElementPointerAPPLE = NULL; +PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC __glewMultiDrawElementArrayAPPLE = NULL; +PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC __glewMultiDrawRangeElementArrayAPPLE = NULL; + +PFNGLDELETEFENCESAPPLEPROC __glewDeleteFencesAPPLE = NULL; +PFNGLFINISHFENCEAPPLEPROC __glewFinishFenceAPPLE = NULL; +PFNGLFINISHOBJECTAPPLEPROC __glewFinishObjectAPPLE = NULL; +PFNGLGENFENCESAPPLEPROC __glewGenFencesAPPLE = NULL; +PFNGLISFENCEAPPLEPROC __glewIsFenceAPPLE = NULL; +PFNGLSETFENCEAPPLEPROC __glewSetFenceAPPLE = NULL; +PFNGLTESTFENCEAPPLEPROC __glewTestFenceAPPLE = NULL; +PFNGLTESTOBJECTAPPLEPROC __glewTestObjectAPPLE = NULL; + +PFNGLBUFFERPARAMETERIAPPLEPROC __glewBufferParameteriAPPLE = NULL; +PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC __glewFlushMappedBufferRangeAPPLE = NULL; + +PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC __glewGetTexParameterPointervAPPLE = NULL; +PFNGLTEXTURERANGEAPPLEPROC __glewTextureRangeAPPLE = NULL; + +PFNGLBINDVERTEXARRAYAPPLEPROC __glewBindVertexArrayAPPLE = NULL; +PFNGLDELETEVERTEXARRAYSAPPLEPROC __glewDeleteVertexArraysAPPLE = NULL; +PFNGLGENVERTEXARRAYSAPPLEPROC __glewGenVertexArraysAPPLE = NULL; +PFNGLISVERTEXARRAYAPPLEPROC __glewIsVertexArrayAPPLE = NULL; + +PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC __glewFlushVertexArrayRangeAPPLE = NULL; +PFNGLVERTEXARRAYPARAMETERIAPPLEPROC __glewVertexArrayParameteriAPPLE = NULL; +PFNGLVERTEXARRAYRANGEAPPLEPROC __glewVertexArrayRangeAPPLE = NULL; + +PFNGLCLAMPCOLORARBPROC __glewClampColorARB = NULL; + +PFNGLDRAWBUFFERSARBPROC __glewDrawBuffersARB = NULL; + +PFNGLDRAWARRAYSINSTANCEDARBPROC __glewDrawArraysInstancedARB = NULL; +PFNGLDRAWELEMENTSINSTANCEDARBPROC __glewDrawElementsInstancedARB = NULL; + +PFNGLBINDFRAMEBUFFERPROC __glewBindFramebuffer = NULL; +PFNGLBINDRENDERBUFFERPROC __glewBindRenderbuffer = NULL; +PFNGLBLITFRAMEBUFFERPROC __glewBlitFramebuffer = NULL; +PFNGLCHECKFRAMEBUFFERSTATUSPROC __glewCheckFramebufferStatus = NULL; +PFNGLDELETEFRAMEBUFFERSPROC __glewDeleteFramebuffers = NULL; +PFNGLDELETERENDERBUFFERSPROC __glewDeleteRenderbuffers = NULL; +PFNGLFRAMEBUFFERRENDERBUFFERPROC __glewFramebufferRenderbuffer = NULL; +PFNGLFRAMEBUFFERTEXTURLAYERPROC __glewFramebufferTexturLayer = NULL; +PFNGLFRAMEBUFFERTEXTURE1DPROC __glewFramebufferTexture1D = NULL; +PFNGLFRAMEBUFFERTEXTURE2DPROC __glewFramebufferTexture2D = NULL; +PFNGLFRAMEBUFFERTEXTURE3DPROC __glewFramebufferTexture3D = NULL; +PFNGLGENFRAMEBUFFERSPROC __glewGenFramebuffers = NULL; +PFNGLGENRENDERBUFFERSPROC __glewGenRenderbuffers = NULL; +PFNGLGENERATEMIPMAPPROC __glewGenerateMipmap = NULL; +PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC __glewGetFramebufferAttachmentParameteriv = NULL; +PFNGLGETRENDERBUFFERPARAMETERIVPROC __glewGetRenderbufferParameteriv = NULL; +PFNGLISFRAMEBUFFERPROC __glewIsFramebuffer = NULL; +PFNGLISRENDERBUFFERPROC __glewIsRenderbuffer = NULL; +PFNGLRENDERBUFFERSTORAGEPROC __glewRenderbufferStorage = NULL; +PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC __glewRenderbufferStorageMultisample = NULL; + +PFNGLFRAMEBUFFERTEXTUREARBPROC __glewFramebufferTextureARB = NULL; +PFNGLFRAMEBUFFERTEXTUREFACEARBPROC __glewFramebufferTextureFaceARB = NULL; +PFNGLFRAMEBUFFERTEXTURELAYERARBPROC __glewFramebufferTextureLayerARB = NULL; +PFNGLPROGRAMPARAMETERIARBPROC __glewProgramParameteriARB = NULL; + +PFNGLCOLORSUBTABLEPROC __glewColorSubTable = NULL; +PFNGLCOLORTABLEPROC __glewColorTable = NULL; +PFNGLCOLORTABLEPARAMETERFVPROC __glewColorTableParameterfv = NULL; +PFNGLCOLORTABLEPARAMETERIVPROC __glewColorTableParameteriv = NULL; +PFNGLCONVOLUTIONFILTER1DPROC __glewConvolutionFilter1D = NULL; +PFNGLCONVOLUTIONFILTER2DPROC __glewConvolutionFilter2D = NULL; +PFNGLCONVOLUTIONPARAMETERFPROC __glewConvolutionParameterf = NULL; +PFNGLCONVOLUTIONPARAMETERFVPROC __glewConvolutionParameterfv = NULL; +PFNGLCONVOLUTIONPARAMETERIPROC __glewConvolutionParameteri = NULL; +PFNGLCONVOLUTIONPARAMETERIVPROC __glewConvolutionParameteriv = NULL; +PFNGLCOPYCOLORSUBTABLEPROC __glewCopyColorSubTable = NULL; +PFNGLCOPYCOLORTABLEPROC __glewCopyColorTable = NULL; +PFNGLCOPYCONVOLUTIONFILTER1DPROC __glewCopyConvolutionFilter1D = NULL; +PFNGLCOPYCONVOLUTIONFILTER2DPROC __glewCopyConvolutionFilter2D = NULL; +PFNGLGETCOLORTABLEPROC __glewGetColorTable = NULL; +PFNGLGETCOLORTABLEPARAMETERFVPROC __glewGetColorTableParameterfv = NULL; +PFNGLGETCOLORTABLEPARAMETERIVPROC __glewGetColorTableParameteriv = NULL; +PFNGLGETCONVOLUTIONFILTERPROC __glewGetConvolutionFilter = NULL; +PFNGLGETCONVOLUTIONPARAMETERFVPROC __glewGetConvolutionParameterfv = NULL; +PFNGLGETCONVOLUTIONPARAMETERIVPROC __glewGetConvolutionParameteriv = NULL; +PFNGLGETHISTOGRAMPROC __glewGetHistogram = NULL; +PFNGLGETHISTOGRAMPARAMETERFVPROC __glewGetHistogramParameterfv = NULL; +PFNGLGETHISTOGRAMPARAMETERIVPROC __glewGetHistogramParameteriv = NULL; +PFNGLGETMINMAXPROC __glewGetMinmax = NULL; +PFNGLGETMINMAXPARAMETERFVPROC __glewGetMinmaxParameterfv = NULL; +PFNGLGETMINMAXPARAMETERIVPROC __glewGetMinmaxParameteriv = NULL; +PFNGLGETSEPARABLEFILTERPROC __glewGetSeparableFilter = NULL; +PFNGLHISTOGRAMPROC __glewHistogram = NULL; +PFNGLMINMAXPROC __glewMinmax = NULL; +PFNGLRESETHISTOGRAMPROC __glewResetHistogram = NULL; +PFNGLRESETMINMAXPROC __glewResetMinmax = NULL; +PFNGLSEPARABLEFILTER2DPROC __glewSeparableFilter2D = NULL; + +PFNGLVERTEXATTRIBDIVISORARBPROC __glewVertexAttribDivisorARB = NULL; + +PFNGLFLUSHMAPPEDBUFFERRANGEPROC __glewFlushMappedBufferRange = NULL; +PFNGLMAPBUFFERRANGEPROC __glewMapBufferRange = NULL; + +PFNGLCURRENTPALETTEMATRIXARBPROC __glewCurrentPaletteMatrixARB = NULL; +PFNGLMATRIXINDEXPOINTERARBPROC __glewMatrixIndexPointerARB = NULL; +PFNGLMATRIXINDEXUBVARBPROC __glewMatrixIndexubvARB = NULL; +PFNGLMATRIXINDEXUIVARBPROC __glewMatrixIndexuivARB = NULL; +PFNGLMATRIXINDEXUSVARBPROC __glewMatrixIndexusvARB = NULL; + +PFNGLSAMPLECOVERAGEARBPROC __glewSampleCoverageARB = NULL; + +PFNGLACTIVETEXTUREARBPROC __glewActiveTextureARB = NULL; +PFNGLCLIENTACTIVETEXTUREARBPROC __glewClientActiveTextureARB = NULL; +PFNGLMULTITEXCOORD1DARBPROC __glewMultiTexCoord1dARB = NULL; +PFNGLMULTITEXCOORD1DVARBPROC __glewMultiTexCoord1dvARB = NULL; +PFNGLMULTITEXCOORD1FARBPROC __glewMultiTexCoord1fARB = NULL; +PFNGLMULTITEXCOORD1FVARBPROC __glewMultiTexCoord1fvARB = NULL; +PFNGLMULTITEXCOORD1IARBPROC __glewMultiTexCoord1iARB = NULL; +PFNGLMULTITEXCOORD1IVARBPROC __glewMultiTexCoord1ivARB = NULL; +PFNGLMULTITEXCOORD1SARBPROC __glewMultiTexCoord1sARB = NULL; +PFNGLMULTITEXCOORD1SVARBPROC __glewMultiTexCoord1svARB = NULL; +PFNGLMULTITEXCOORD2DARBPROC __glewMultiTexCoord2dARB = NULL; +PFNGLMULTITEXCOORD2DVARBPROC __glewMultiTexCoord2dvARB = NULL; +PFNGLMULTITEXCOORD2FARBPROC __glewMultiTexCoord2fARB = NULL; +PFNGLMULTITEXCOORD2FVARBPROC __glewMultiTexCoord2fvARB = NULL; +PFNGLMULTITEXCOORD2IARBPROC __glewMultiTexCoord2iARB = NULL; +PFNGLMULTITEXCOORD2IVARBPROC __glewMultiTexCoord2ivARB = NULL; +PFNGLMULTITEXCOORD2SARBPROC __glewMultiTexCoord2sARB = NULL; +PFNGLMULTITEXCOORD2SVARBPROC __glewMultiTexCoord2svARB = NULL; +PFNGLMULTITEXCOORD3DARBPROC __glewMultiTexCoord3dARB = NULL; +PFNGLMULTITEXCOORD3DVARBPROC __glewMultiTexCoord3dvARB = NULL; +PFNGLMULTITEXCOORD3FARBPROC __glewMultiTexCoord3fARB = NULL; +PFNGLMULTITEXCOORD3FVARBPROC __glewMultiTexCoord3fvARB = NULL; +PFNGLMULTITEXCOORD3IARBPROC __glewMultiTexCoord3iARB = NULL; +PFNGLMULTITEXCOORD3IVARBPROC __glewMultiTexCoord3ivARB = NULL; +PFNGLMULTITEXCOORD3SARBPROC __glewMultiTexCoord3sARB = NULL; +PFNGLMULTITEXCOORD3SVARBPROC __glewMultiTexCoord3svARB = NULL; +PFNGLMULTITEXCOORD4DARBPROC __glewMultiTexCoord4dARB = NULL; +PFNGLMULTITEXCOORD4DVARBPROC __glewMultiTexCoord4dvARB = NULL; +PFNGLMULTITEXCOORD4FARBPROC __glewMultiTexCoord4fARB = NULL; +PFNGLMULTITEXCOORD4FVARBPROC __glewMultiTexCoord4fvARB = NULL; +PFNGLMULTITEXCOORD4IARBPROC __glewMultiTexCoord4iARB = NULL; +PFNGLMULTITEXCOORD4IVARBPROC __glewMultiTexCoord4ivARB = NULL; +PFNGLMULTITEXCOORD4SARBPROC __glewMultiTexCoord4sARB = NULL; +PFNGLMULTITEXCOORD4SVARBPROC __glewMultiTexCoord4svARB = NULL; + +PFNGLBEGINQUERYARBPROC __glewBeginQueryARB = NULL; +PFNGLDELETEQUERIESARBPROC __glewDeleteQueriesARB = NULL; +PFNGLENDQUERYARBPROC __glewEndQueryARB = NULL; +PFNGLGENQUERIESARBPROC __glewGenQueriesARB = NULL; +PFNGLGETQUERYOBJECTIVARBPROC __glewGetQueryObjectivARB = NULL; +PFNGLGETQUERYOBJECTUIVARBPROC __glewGetQueryObjectuivARB = NULL; +PFNGLGETQUERYIVARBPROC __glewGetQueryivARB = NULL; +PFNGLISQUERYARBPROC __glewIsQueryARB = NULL; + +PFNGLPOINTPARAMETERFARBPROC __glewPointParameterfARB = NULL; +PFNGLPOINTPARAMETERFVARBPROC __glewPointParameterfvARB = NULL; + +PFNGLATTACHOBJECTARBPROC __glewAttachObjectARB = NULL; +PFNGLCOMPILESHADERARBPROC __glewCompileShaderARB = NULL; +PFNGLCREATEPROGRAMOBJECTARBPROC __glewCreateProgramObjectARB = NULL; +PFNGLCREATESHADEROBJECTARBPROC __glewCreateShaderObjectARB = NULL; +PFNGLDELETEOBJECTARBPROC __glewDeleteObjectARB = NULL; +PFNGLDETACHOBJECTARBPROC __glewDetachObjectARB = NULL; +PFNGLGETACTIVEUNIFORMARBPROC __glewGetActiveUniformARB = NULL; +PFNGLGETATTACHEDOBJECTSARBPROC __glewGetAttachedObjectsARB = NULL; +PFNGLGETHANDLEARBPROC __glewGetHandleARB = NULL; +PFNGLGETINFOLOGARBPROC __glewGetInfoLogARB = NULL; +PFNGLGETOBJECTPARAMETERFVARBPROC __glewGetObjectParameterfvARB = NULL; +PFNGLGETOBJECTPARAMETERIVARBPROC __glewGetObjectParameterivARB = NULL; +PFNGLGETSHADERSOURCEARBPROC __glewGetShaderSourceARB = NULL; +PFNGLGETUNIFORMLOCATIONARBPROC __glewGetUniformLocationARB = NULL; +PFNGLGETUNIFORMFVARBPROC __glewGetUniformfvARB = NULL; +PFNGLGETUNIFORMIVARBPROC __glewGetUniformivARB = NULL; +PFNGLLINKPROGRAMARBPROC __glewLinkProgramARB = NULL; +PFNGLSHADERSOURCEARBPROC __glewShaderSourceARB = NULL; +PFNGLUNIFORM1FARBPROC __glewUniform1fARB = NULL; +PFNGLUNIFORM1FVARBPROC __glewUniform1fvARB = NULL; +PFNGLUNIFORM1IARBPROC __glewUniform1iARB = NULL; +PFNGLUNIFORM1IVARBPROC __glewUniform1ivARB = NULL; +PFNGLUNIFORM2FARBPROC __glewUniform2fARB = NULL; +PFNGLUNIFORM2FVARBPROC __glewUniform2fvARB = NULL; +PFNGLUNIFORM2IARBPROC __glewUniform2iARB = NULL; +PFNGLUNIFORM2IVARBPROC __glewUniform2ivARB = NULL; +PFNGLUNIFORM3FARBPROC __glewUniform3fARB = NULL; +PFNGLUNIFORM3FVARBPROC __glewUniform3fvARB = NULL; +PFNGLUNIFORM3IARBPROC __glewUniform3iARB = NULL; +PFNGLUNIFORM3IVARBPROC __glewUniform3ivARB = NULL; +PFNGLUNIFORM4FARBPROC __glewUniform4fARB = NULL; +PFNGLUNIFORM4FVARBPROC __glewUniform4fvARB = NULL; +PFNGLUNIFORM4IARBPROC __glewUniform4iARB = NULL; +PFNGLUNIFORM4IVARBPROC __glewUniform4ivARB = NULL; +PFNGLUNIFORMMATRIX2FVARBPROC __glewUniformMatrix2fvARB = NULL; +PFNGLUNIFORMMATRIX3FVARBPROC __glewUniformMatrix3fvARB = NULL; +PFNGLUNIFORMMATRIX4FVARBPROC __glewUniformMatrix4fvARB = NULL; +PFNGLUSEPROGRAMOBJECTARBPROC __glewUseProgramObjectARB = NULL; +PFNGLVALIDATEPROGRAMARBPROC __glewValidateProgramARB = NULL; + +PFNGLTEXBUFFERARBPROC __glewTexBufferARB = NULL; + +PFNGLCOMPRESSEDTEXIMAGE1DARBPROC __glewCompressedTexImage1DARB = NULL; +PFNGLCOMPRESSEDTEXIMAGE2DARBPROC __glewCompressedTexImage2DARB = NULL; +PFNGLCOMPRESSEDTEXIMAGE3DARBPROC __glewCompressedTexImage3DARB = NULL; +PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC __glewCompressedTexSubImage1DARB = NULL; +PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC __glewCompressedTexSubImage2DARB = NULL; +PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC __glewCompressedTexSubImage3DARB = NULL; +PFNGLGETCOMPRESSEDTEXIMAGEARBPROC __glewGetCompressedTexImageARB = NULL; + +PFNGLLOADTRANSPOSEMATRIXDARBPROC __glewLoadTransposeMatrixdARB = NULL; +PFNGLLOADTRANSPOSEMATRIXFARBPROC __glewLoadTransposeMatrixfARB = NULL; +PFNGLMULTTRANSPOSEMATRIXDARBPROC __glewMultTransposeMatrixdARB = NULL; +PFNGLMULTTRANSPOSEMATRIXFARBPROC __glewMultTransposeMatrixfARB = NULL; + +PFNGLBINDVERTEXARRAYPROC __glewBindVertexArray = NULL; +PFNGLDELETEVERTEXARRAYSPROC __glewDeleteVertexArrays = NULL; +PFNGLGENVERTEXARRAYSPROC __glewGenVertexArrays = NULL; +PFNGLISVERTEXARRAYPROC __glewIsVertexArray = NULL; + +PFNGLVERTEXBLENDARBPROC __glewVertexBlendARB = NULL; +PFNGLWEIGHTPOINTERARBPROC __glewWeightPointerARB = NULL; +PFNGLWEIGHTBVARBPROC __glewWeightbvARB = NULL; +PFNGLWEIGHTDVARBPROC __glewWeightdvARB = NULL; +PFNGLWEIGHTFVARBPROC __glewWeightfvARB = NULL; +PFNGLWEIGHTIVARBPROC __glewWeightivARB = NULL; +PFNGLWEIGHTSVARBPROC __glewWeightsvARB = NULL; +PFNGLWEIGHTUBVARBPROC __glewWeightubvARB = NULL; +PFNGLWEIGHTUIVARBPROC __glewWeightuivARB = NULL; +PFNGLWEIGHTUSVARBPROC __glewWeightusvARB = NULL; + +PFNGLBINDBUFFERARBPROC __glewBindBufferARB = NULL; +PFNGLBUFFERDATAARBPROC __glewBufferDataARB = NULL; +PFNGLBUFFERSUBDATAARBPROC __glewBufferSubDataARB = NULL; +PFNGLDELETEBUFFERSARBPROC __glewDeleteBuffersARB = NULL; +PFNGLGENBUFFERSARBPROC __glewGenBuffersARB = NULL; +PFNGLGETBUFFERPARAMETERIVARBPROC __glewGetBufferParameterivARB = NULL; +PFNGLGETBUFFERPOINTERVARBPROC __glewGetBufferPointervARB = NULL; +PFNGLGETBUFFERSUBDATAARBPROC __glewGetBufferSubDataARB = NULL; +PFNGLISBUFFERARBPROC __glewIsBufferARB = NULL; +PFNGLMAPBUFFERARBPROC __glewMapBufferARB = NULL; +PFNGLUNMAPBUFFERARBPROC __glewUnmapBufferARB = NULL; + +PFNGLBINDPROGRAMARBPROC __glewBindProgramARB = NULL; +PFNGLDELETEPROGRAMSARBPROC __glewDeleteProgramsARB = NULL; +PFNGLDISABLEVERTEXATTRIBARRAYARBPROC __glewDisableVertexAttribArrayARB = NULL; +PFNGLENABLEVERTEXATTRIBARRAYARBPROC __glewEnableVertexAttribArrayARB = NULL; +PFNGLGENPROGRAMSARBPROC __glewGenProgramsARB = NULL; +PFNGLGETPROGRAMENVPARAMETERDVARBPROC __glewGetProgramEnvParameterdvARB = NULL; +PFNGLGETPROGRAMENVPARAMETERFVARBPROC __glewGetProgramEnvParameterfvARB = NULL; +PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC __glewGetProgramLocalParameterdvARB = NULL; +PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC __glewGetProgramLocalParameterfvARB = NULL; +PFNGLGETPROGRAMSTRINGARBPROC __glewGetProgramStringARB = NULL; +PFNGLGETPROGRAMIVARBPROC __glewGetProgramivARB = NULL; +PFNGLGETVERTEXATTRIBPOINTERVARBPROC __glewGetVertexAttribPointervARB = NULL; +PFNGLGETVERTEXATTRIBDVARBPROC __glewGetVertexAttribdvARB = NULL; +PFNGLGETVERTEXATTRIBFVARBPROC __glewGetVertexAttribfvARB = NULL; +PFNGLGETVERTEXATTRIBIVARBPROC __glewGetVertexAttribivARB = NULL; +PFNGLISPROGRAMARBPROC __glewIsProgramARB = NULL; +PFNGLPROGRAMENVPARAMETER4DARBPROC __glewProgramEnvParameter4dARB = NULL; +PFNGLPROGRAMENVPARAMETER4DVARBPROC __glewProgramEnvParameter4dvARB = NULL; +PFNGLPROGRAMENVPARAMETER4FARBPROC __glewProgramEnvParameter4fARB = NULL; +PFNGLPROGRAMENVPARAMETER4FVARBPROC __glewProgramEnvParameter4fvARB = NULL; +PFNGLPROGRAMLOCALPARAMETER4DARBPROC __glewProgramLocalParameter4dARB = NULL; +PFNGLPROGRAMLOCALPARAMETER4DVARBPROC __glewProgramLocalParameter4dvARB = NULL; +PFNGLPROGRAMLOCALPARAMETER4FARBPROC __glewProgramLocalParameter4fARB = NULL; +PFNGLPROGRAMLOCALPARAMETER4FVARBPROC __glewProgramLocalParameter4fvARB = NULL; +PFNGLPROGRAMSTRINGARBPROC __glewProgramStringARB = NULL; +PFNGLVERTEXATTRIB1DARBPROC __glewVertexAttrib1dARB = NULL; +PFNGLVERTEXATTRIB1DVARBPROC __glewVertexAttrib1dvARB = NULL; +PFNGLVERTEXATTRIB1FARBPROC __glewVertexAttrib1fARB = NULL; +PFNGLVERTEXATTRIB1FVARBPROC __glewVertexAttrib1fvARB = NULL; +PFNGLVERTEXATTRIB1SARBPROC __glewVertexAttrib1sARB = NULL; +PFNGLVERTEXATTRIB1SVARBPROC __glewVertexAttrib1svARB = NULL; +PFNGLVERTEXATTRIB2DARBPROC __glewVertexAttrib2dARB = NULL; +PFNGLVERTEXATTRIB2DVARBPROC __glewVertexAttrib2dvARB = NULL; +PFNGLVERTEXATTRIB2FARBPROC __glewVertexAttrib2fARB = NULL; +PFNGLVERTEXATTRIB2FVARBPROC __glewVertexAttrib2fvARB = NULL; +PFNGLVERTEXATTRIB2SARBPROC __glewVertexAttrib2sARB = NULL; +PFNGLVERTEXATTRIB2SVARBPROC __glewVertexAttrib2svARB = NULL; +PFNGLVERTEXATTRIB3DARBPROC __glewVertexAttrib3dARB = NULL; +PFNGLVERTEXATTRIB3DVARBPROC __glewVertexAttrib3dvARB = NULL; +PFNGLVERTEXATTRIB3FARBPROC __glewVertexAttrib3fARB = NULL; +PFNGLVERTEXATTRIB3FVARBPROC __glewVertexAttrib3fvARB = NULL; +PFNGLVERTEXATTRIB3SARBPROC __glewVertexAttrib3sARB = NULL; +PFNGLVERTEXATTRIB3SVARBPROC __glewVertexAttrib3svARB = NULL; +PFNGLVERTEXATTRIB4NBVARBPROC __glewVertexAttrib4NbvARB = NULL; +PFNGLVERTEXATTRIB4NIVARBPROC __glewVertexAttrib4NivARB = NULL; +PFNGLVERTEXATTRIB4NSVARBPROC __glewVertexAttrib4NsvARB = NULL; +PFNGLVERTEXATTRIB4NUBARBPROC __glewVertexAttrib4NubARB = NULL; +PFNGLVERTEXATTRIB4NUBVARBPROC __glewVertexAttrib4NubvARB = NULL; +PFNGLVERTEXATTRIB4NUIVARBPROC __glewVertexAttrib4NuivARB = NULL; +PFNGLVERTEXATTRIB4NUSVARBPROC __glewVertexAttrib4NusvARB = NULL; +PFNGLVERTEXATTRIB4BVARBPROC __glewVertexAttrib4bvARB = NULL; +PFNGLVERTEXATTRIB4DARBPROC __glewVertexAttrib4dARB = NULL; +PFNGLVERTEXATTRIB4DVARBPROC __glewVertexAttrib4dvARB = NULL; +PFNGLVERTEXATTRIB4FARBPROC __glewVertexAttrib4fARB = NULL; +PFNGLVERTEXATTRIB4FVARBPROC __glewVertexAttrib4fvARB = NULL; +PFNGLVERTEXATTRIB4IVARBPROC __glewVertexAttrib4ivARB = NULL; +PFNGLVERTEXATTRIB4SARBPROC __glewVertexAttrib4sARB = NULL; +PFNGLVERTEXATTRIB4SVARBPROC __glewVertexAttrib4svARB = NULL; +PFNGLVERTEXATTRIB4UBVARBPROC __glewVertexAttrib4ubvARB = NULL; +PFNGLVERTEXATTRIB4UIVARBPROC __glewVertexAttrib4uivARB = NULL; +PFNGLVERTEXATTRIB4USVARBPROC __glewVertexAttrib4usvARB = NULL; +PFNGLVERTEXATTRIBPOINTERARBPROC __glewVertexAttribPointerARB = NULL; + +PFNGLBINDATTRIBLOCATIONARBPROC __glewBindAttribLocationARB = NULL; +PFNGLGETACTIVEATTRIBARBPROC __glewGetActiveAttribARB = NULL; +PFNGLGETATTRIBLOCATIONARBPROC __glewGetAttribLocationARB = NULL; + +PFNGLWINDOWPOS2DARBPROC __glewWindowPos2dARB = NULL; +PFNGLWINDOWPOS2DVARBPROC __glewWindowPos2dvARB = NULL; +PFNGLWINDOWPOS2FARBPROC __glewWindowPos2fARB = NULL; +PFNGLWINDOWPOS2FVARBPROC __glewWindowPos2fvARB = NULL; +PFNGLWINDOWPOS2IARBPROC __glewWindowPos2iARB = NULL; +PFNGLWINDOWPOS2IVARBPROC __glewWindowPos2ivARB = NULL; +PFNGLWINDOWPOS2SARBPROC __glewWindowPos2sARB = NULL; +PFNGLWINDOWPOS2SVARBPROC __glewWindowPos2svARB = NULL; +PFNGLWINDOWPOS3DARBPROC __glewWindowPos3dARB = NULL; +PFNGLWINDOWPOS3DVARBPROC __glewWindowPos3dvARB = NULL; +PFNGLWINDOWPOS3FARBPROC __glewWindowPos3fARB = NULL; +PFNGLWINDOWPOS3FVARBPROC __glewWindowPos3fvARB = NULL; +PFNGLWINDOWPOS3IARBPROC __glewWindowPos3iARB = NULL; +PFNGLWINDOWPOS3IVARBPROC __glewWindowPos3ivARB = NULL; +PFNGLWINDOWPOS3SARBPROC __glewWindowPos3sARB = NULL; +PFNGLWINDOWPOS3SVARBPROC __glewWindowPos3svARB = NULL; + +PFNGLDRAWBUFFERSATIPROC __glewDrawBuffersATI = NULL; + +PFNGLDRAWELEMENTARRAYATIPROC __glewDrawElementArrayATI = NULL; +PFNGLDRAWRANGEELEMENTARRAYATIPROC __glewDrawRangeElementArrayATI = NULL; +PFNGLELEMENTPOINTERATIPROC __glewElementPointerATI = NULL; + +PFNGLGETTEXBUMPPARAMETERFVATIPROC __glewGetTexBumpParameterfvATI = NULL; +PFNGLGETTEXBUMPPARAMETERIVATIPROC __glewGetTexBumpParameterivATI = NULL; +PFNGLTEXBUMPPARAMETERFVATIPROC __glewTexBumpParameterfvATI = NULL; +PFNGLTEXBUMPPARAMETERIVATIPROC __glewTexBumpParameterivATI = NULL; + +PFNGLALPHAFRAGMENTOP1ATIPROC __glewAlphaFragmentOp1ATI = NULL; +PFNGLALPHAFRAGMENTOP2ATIPROC __glewAlphaFragmentOp2ATI = NULL; +PFNGLALPHAFRAGMENTOP3ATIPROC __glewAlphaFragmentOp3ATI = NULL; +PFNGLBEGINFRAGMENTSHADERATIPROC __glewBeginFragmentShaderATI = NULL; +PFNGLBINDFRAGMENTSHADERATIPROC __glewBindFragmentShaderATI = NULL; +PFNGLCOLORFRAGMENTOP1ATIPROC __glewColorFragmentOp1ATI = NULL; +PFNGLCOLORFRAGMENTOP2ATIPROC __glewColorFragmentOp2ATI = NULL; +PFNGLCOLORFRAGMENTOP3ATIPROC __glewColorFragmentOp3ATI = NULL; +PFNGLDELETEFRAGMENTSHADERATIPROC __glewDeleteFragmentShaderATI = NULL; +PFNGLENDFRAGMENTSHADERATIPROC __glewEndFragmentShaderATI = NULL; +PFNGLGENFRAGMENTSHADERSATIPROC __glewGenFragmentShadersATI = NULL; +PFNGLPASSTEXCOORDATIPROC __glewPassTexCoordATI = NULL; +PFNGLSAMPLEMAPATIPROC __glewSampleMapATI = NULL; +PFNGLSETFRAGMENTSHADERCONSTANTATIPROC __glewSetFragmentShaderConstantATI = NULL; + +PFNGLMAPOBJECTBUFFERATIPROC __glewMapObjectBufferATI = NULL; +PFNGLUNMAPOBJECTBUFFERATIPROC __glewUnmapObjectBufferATI = NULL; + +PFNGLPNTRIANGLESFATIPROC __glPNTrianglewesfATI = NULL; +PFNGLPNTRIANGLESIATIPROC __glPNTrianglewesiATI = NULL; + +PFNGLSTENCILFUNCSEPARATEATIPROC __glewStencilFuncSeparateATI = NULL; +PFNGLSTENCILOPSEPARATEATIPROC __glewStencilOpSeparateATI = NULL; + +PFNGLARRAYOBJECTATIPROC __glewArrayObjectATI = NULL; +PFNGLFREEOBJECTBUFFERATIPROC __glewFreeObjectBufferATI = NULL; +PFNGLGETARRAYOBJECTFVATIPROC __glewGetArrayObjectfvATI = NULL; +PFNGLGETARRAYOBJECTIVATIPROC __glewGetArrayObjectivATI = NULL; +PFNGLGETOBJECTBUFFERFVATIPROC __glewGetObjectBufferfvATI = NULL; +PFNGLGETOBJECTBUFFERIVATIPROC __glewGetObjectBufferivATI = NULL; +PFNGLGETVARIANTARRAYOBJECTFVATIPROC __glewGetVariantArrayObjectfvATI = NULL; +PFNGLGETVARIANTARRAYOBJECTIVATIPROC __glewGetVariantArrayObjectivATI = NULL; +PFNGLISOBJECTBUFFERATIPROC __glewIsObjectBufferATI = NULL; +PFNGLNEWOBJECTBUFFERATIPROC __glewNewObjectBufferATI = NULL; +PFNGLUPDATEOBJECTBUFFERATIPROC __glewUpdateObjectBufferATI = NULL; +PFNGLVARIANTARRAYOBJECTATIPROC __glewVariantArrayObjectATI = NULL; + +PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC __glewGetVertexAttribArrayObjectfvATI = NULL; +PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC __glewGetVertexAttribArrayObjectivATI = NULL; +PFNGLVERTEXATTRIBARRAYOBJECTATIPROC __glewVertexAttribArrayObjectATI = NULL; + +PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC __glewClientActiveVertexStreamATI = NULL; +PFNGLNORMALSTREAM3BATIPROC __glewNormalStream3bATI = NULL; +PFNGLNORMALSTREAM3BVATIPROC __glewNormalStream3bvATI = NULL; +PFNGLNORMALSTREAM3DATIPROC __glewNormalStream3dATI = NULL; +PFNGLNORMALSTREAM3DVATIPROC __glewNormalStream3dvATI = NULL; +PFNGLNORMALSTREAM3FATIPROC __glewNormalStream3fATI = NULL; +PFNGLNORMALSTREAM3FVATIPROC __glewNormalStream3fvATI = NULL; +PFNGLNORMALSTREAM3IATIPROC __glewNormalStream3iATI = NULL; +PFNGLNORMALSTREAM3IVATIPROC __glewNormalStream3ivATI = NULL; +PFNGLNORMALSTREAM3SATIPROC __glewNormalStream3sATI = NULL; +PFNGLNORMALSTREAM3SVATIPROC __glewNormalStream3svATI = NULL; +PFNGLVERTEXBLENDENVFATIPROC __glewVertexBlendEnvfATI = NULL; +PFNGLVERTEXBLENDENVIATIPROC __glewVertexBlendEnviATI = NULL; +PFNGLVERTEXSTREAM2DATIPROC __glewVertexStream2dATI = NULL; +PFNGLVERTEXSTREAM2DVATIPROC __glewVertexStream2dvATI = NULL; +PFNGLVERTEXSTREAM2FATIPROC __glewVertexStream2fATI = NULL; +PFNGLVERTEXSTREAM2FVATIPROC __glewVertexStream2fvATI = NULL; +PFNGLVERTEXSTREAM2IATIPROC __glewVertexStream2iATI = NULL; +PFNGLVERTEXSTREAM2IVATIPROC __glewVertexStream2ivATI = NULL; +PFNGLVERTEXSTREAM2SATIPROC __glewVertexStream2sATI = NULL; +PFNGLVERTEXSTREAM2SVATIPROC __glewVertexStream2svATI = NULL; +PFNGLVERTEXSTREAM3DATIPROC __glewVertexStream3dATI = NULL; +PFNGLVERTEXSTREAM3DVATIPROC __glewVertexStream3dvATI = NULL; +PFNGLVERTEXSTREAM3FATIPROC __glewVertexStream3fATI = NULL; +PFNGLVERTEXSTREAM3FVATIPROC __glewVertexStream3fvATI = NULL; +PFNGLVERTEXSTREAM3IATIPROC __glewVertexStream3iATI = NULL; +PFNGLVERTEXSTREAM3IVATIPROC __glewVertexStream3ivATI = NULL; +PFNGLVERTEXSTREAM3SATIPROC __glewVertexStream3sATI = NULL; +PFNGLVERTEXSTREAM3SVATIPROC __glewVertexStream3svATI = NULL; +PFNGLVERTEXSTREAM4DATIPROC __glewVertexStream4dATI = NULL; +PFNGLVERTEXSTREAM4DVATIPROC __glewVertexStream4dvATI = NULL; +PFNGLVERTEXSTREAM4FATIPROC __glewVertexStream4fATI = NULL; +PFNGLVERTEXSTREAM4FVATIPROC __glewVertexStream4fvATI = NULL; +PFNGLVERTEXSTREAM4IATIPROC __glewVertexStream4iATI = NULL; +PFNGLVERTEXSTREAM4IVATIPROC __glewVertexStream4ivATI = NULL; +PFNGLVERTEXSTREAM4SATIPROC __glewVertexStream4sATI = NULL; +PFNGLVERTEXSTREAM4SVATIPROC __glewVertexStream4svATI = NULL; + +PFNGLGETUNIFORMBUFFERSIZEEXTPROC __glewGetUniformBufferSizeEXT = NULL; +PFNGLGETUNIFORMOFFSETEXTPROC __glewGetUniformOffsetEXT = NULL; +PFNGLUNIFORMBUFFEREXTPROC __glewUniformBufferEXT = NULL; + +PFNGLBLENDCOLOREXTPROC __glewBlendColorEXT = NULL; + +PFNGLBLENDEQUATIONSEPARATEEXTPROC __glewBlendEquationSeparateEXT = NULL; + +PFNGLBLENDFUNCSEPARATEEXTPROC __glewBlendFuncSeparateEXT = NULL; + +PFNGLBLENDEQUATIONEXTPROC __glewBlendEquationEXT = NULL; + +PFNGLCOLORSUBTABLEEXTPROC __glewColorSubTableEXT = NULL; +PFNGLCOPYCOLORSUBTABLEEXTPROC __glewCopyColorSubTableEXT = NULL; + +PFNGLLOCKARRAYSEXTPROC __glewLockArraysEXT = NULL; +PFNGLUNLOCKARRAYSEXTPROC __glewUnlockArraysEXT = NULL; + +PFNGLCONVOLUTIONFILTER1DEXTPROC __glewConvolutionFilter1DEXT = NULL; +PFNGLCONVOLUTIONFILTER2DEXTPROC __glewConvolutionFilter2DEXT = NULL; +PFNGLCONVOLUTIONPARAMETERFEXTPROC __glewConvolutionParameterfEXT = NULL; +PFNGLCONVOLUTIONPARAMETERFVEXTPROC __glewConvolutionParameterfvEXT = NULL; +PFNGLCONVOLUTIONPARAMETERIEXTPROC __glewConvolutionParameteriEXT = NULL; +PFNGLCONVOLUTIONPARAMETERIVEXTPROC __glewConvolutionParameterivEXT = NULL; +PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC __glewCopyConvolutionFilter1DEXT = NULL; +PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC __glewCopyConvolutionFilter2DEXT = NULL; +PFNGLGETCONVOLUTIONFILTEREXTPROC __glewGetConvolutionFilterEXT = NULL; +PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC __glewGetConvolutionParameterfvEXT = NULL; +PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC __glewGetConvolutionParameterivEXT = NULL; +PFNGLGETSEPARABLEFILTEREXTPROC __glewGetSeparableFilterEXT = NULL; +PFNGLSEPARABLEFILTER2DEXTPROC __glewSeparableFilter2DEXT = NULL; + +PFNGLBINORMALPOINTEREXTPROC __glewBinormalPointerEXT = NULL; +PFNGLTANGENTPOINTEREXTPROC __glewTangentPointerEXT = NULL; + +PFNGLCOPYTEXIMAGE1DEXTPROC __glewCopyTexImage1DEXT = NULL; +PFNGLCOPYTEXIMAGE2DEXTPROC __glewCopyTexImage2DEXT = NULL; +PFNGLCOPYTEXSUBIMAGE1DEXTPROC __glewCopyTexSubImage1DEXT = NULL; +PFNGLCOPYTEXSUBIMAGE2DEXTPROC __glewCopyTexSubImage2DEXT = NULL; +PFNGLCOPYTEXSUBIMAGE3DEXTPROC __glewCopyTexSubImage3DEXT = NULL; + +PFNGLCULLPARAMETERDVEXTPROC __glewCullParameterdvEXT = NULL; +PFNGLCULLPARAMETERFVEXTPROC __glewCullParameterfvEXT = NULL; + +PFNGLDEPTHBOUNDSEXTPROC __glewDepthBoundsEXT = NULL; + +PFNGLBINDMULTITEXTUREEXTPROC __glewBindMultiTextureEXT = NULL; +PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC __glewCheckNamedFramebufferStatusEXT = NULL; +PFNGLCLIENTATTRIBDEFAULTEXTPROC __glewClientAttribDefaultEXT = NULL; +PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC __glewCompressedMultiTexImage1DEXT = NULL; +PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC __glewCompressedMultiTexImage2DEXT = NULL; +PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC __glewCompressedMultiTexImage3DEXT = NULL; +PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC __glewCompressedMultiTexSubImage1DEXT = NULL; +PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC __glewCompressedMultiTexSubImage2DEXT = NULL; +PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC __glewCompressedMultiTexSubImage3DEXT = NULL; +PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC __glewCompressedTextureImage1DEXT = NULL; +PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC __glewCompressedTextureImage2DEXT = NULL; +PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC __glewCompressedTextureImage3DEXT = NULL; +PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC __glewCompressedTextureSubImage1DEXT = NULL; +PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC __glewCompressedTextureSubImage2DEXT = NULL; +PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC __glewCompressedTextureSubImage3DEXT = NULL; +PFNGLCOPYMULTITEXIMAGE1DEXTPROC __glewCopyMultiTexImage1DEXT = NULL; +PFNGLCOPYMULTITEXIMAGE2DEXTPROC __glewCopyMultiTexImage2DEXT = NULL; +PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC __glewCopyMultiTexSubImage1DEXT = NULL; +PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC __glewCopyMultiTexSubImage2DEXT = NULL; +PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC __glewCopyMultiTexSubImage3DEXT = NULL; +PFNGLCOPYTEXTUREIMAGE1DEXTPROC __glewCopyTextureImage1DEXT = NULL; +PFNGLCOPYTEXTUREIMAGE2DEXTPROC __glewCopyTextureImage2DEXT = NULL; +PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC __glewCopyTextureSubImage1DEXT = NULL; +PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC __glewCopyTextureSubImage2DEXT = NULL; +PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC __glewCopyTextureSubImage3DEXT = NULL; +PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC __glewDisableClientStateIndexedEXT = NULL; +PFNGLENABLECLIENTSTATEINDEXEDEXTPROC __glewEnableClientStateIndexedEXT = NULL; +PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC __glewFramebufferDrawBufferEXT = NULL; +PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC __glewFramebufferDrawBuffersEXT = NULL; +PFNGLFRAMEBUFFERREADBUFFEREXTPROC __glewFramebufferReadBufferEXT = NULL; +PFNGLGENERATEMULTITEXMIPMAPEXTPROC __glewGenerateMultiTexMipmapEXT = NULL; +PFNGLGENERATETEXTUREMIPMAPEXTPROC __glewGenerateTextureMipmapEXT = NULL; +PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC __glewGetCompressedMultiTexImageEXT = NULL; +PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC __glewGetCompressedTextureImageEXT = NULL; +PFNGLGETDOUBLEINDEXEDVEXTPROC __glewGetDoubleIndexedvEXT = NULL; +PFNGLGETFLOATINDEXEDVEXTPROC __glewGetFloatIndexedvEXT = NULL; +PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC __glewGetFramebufferParameterivEXT = NULL; +PFNGLGETMULTITEXENVFVEXTPROC __glewGetMultiTexEnvfvEXT = NULL; +PFNGLGETMULTITEXENVIVEXTPROC __glewGetMultiTexEnvivEXT = NULL; +PFNGLGETMULTITEXGENDVEXTPROC __glewGetMultiTexGendvEXT = NULL; +PFNGLGETMULTITEXGENFVEXTPROC __glewGetMultiTexGenfvEXT = NULL; +PFNGLGETMULTITEXGENIVEXTPROC __glewGetMultiTexGenivEXT = NULL; +PFNGLGETMULTITEXIMAGEEXTPROC __glewGetMultiTexImageEXT = NULL; +PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC __glewGetMultiTexLevelParameterfvEXT = NULL; +PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC __glewGetMultiTexLevelParameterivEXT = NULL; +PFNGLGETMULTITEXPARAMETERIIVEXTPROC __glewGetMultiTexParameterIivEXT = NULL; +PFNGLGETMULTITEXPARAMETERIUIVEXTPROC __glewGetMultiTexParameterIuivEXT = NULL; +PFNGLGETMULTITEXPARAMETERFVEXTPROC __glewGetMultiTexParameterfvEXT = NULL; +PFNGLGETMULTITEXPARAMETERIVEXTPROC __glewGetMultiTexParameterivEXT = NULL; +PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC __glewGetNamedBufferParameterivEXT = NULL; +PFNGLGETNAMEDBUFFERPOINTERVEXTPROC __glewGetNamedBufferPointervEXT = NULL; +PFNGLGETNAMEDBUFFERSUBDATAEXTPROC __glewGetNamedBufferSubDataEXT = NULL; +PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC __glewGetNamedFramebufferAttachmentParameterivEXT = NULL; +PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC __glewGetNamedProgramLocalParameterIivEXT = NULL; +PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC __glewGetNamedProgramLocalParameterIuivEXT = NULL; +PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC __glewGetNamedProgramLocalParameterdvEXT = NULL; +PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC __glewGetNamedProgramLocalParameterfvEXT = NULL; +PFNGLGETNAMEDPROGRAMSTRINGEXTPROC __glewGetNamedProgramStringEXT = NULL; +PFNGLGETNAMEDPROGRAMIVEXTPROC __glewGetNamedProgramivEXT = NULL; +PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC __glewGetNamedRenderbufferParameterivEXT = NULL; +PFNGLGETPOINTERINDEXEDVEXTPROC __glewGetPointerIndexedvEXT = NULL; +PFNGLGETTEXTUREIMAGEEXTPROC __glewGetTextureImageEXT = NULL; +PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC __glewGetTextureLevelParameterfvEXT = NULL; +PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC __glewGetTextureLevelParameterivEXT = NULL; +PFNGLGETTEXTUREPARAMETERIIVEXTPROC __glewGetTextureParameterIivEXT = NULL; +PFNGLGETTEXTUREPARAMETERIUIVEXTPROC __glewGetTextureParameterIuivEXT = NULL; +PFNGLGETTEXTUREPARAMETERFVEXTPROC __glewGetTextureParameterfvEXT = NULL; +PFNGLGETTEXTUREPARAMETERIVEXTPROC __glewGetTextureParameterivEXT = NULL; +PFNGLMAPNAMEDBUFFEREXTPROC __glewMapNamedBufferEXT = NULL; +PFNGLMATRIXFRUSTUMEXTPROC __glewMatrixFrustumEXT = NULL; +PFNGLMATRIXLOADIDENTITYEXTPROC __glewMatrixLoadIdentityEXT = NULL; +PFNGLMATRIXLOADTRANSPOSEDEXTPROC __glewMatrixLoadTransposedEXT = NULL; +PFNGLMATRIXLOADTRANSPOSEFEXTPROC __glewMatrixLoadTransposefEXT = NULL; +PFNGLMATRIXLOADDEXTPROC __glewMatrixLoaddEXT = NULL; +PFNGLMATRIXLOADFEXTPROC __glewMatrixLoadfEXT = NULL; +PFNGLMATRIXMULTTRANSPOSEDEXTPROC __glewMatrixMultTransposedEXT = NULL; +PFNGLMATRIXMULTTRANSPOSEFEXTPROC __glewMatrixMultTransposefEXT = NULL; +PFNGLMATRIXMULTDEXTPROC __glewMatrixMultdEXT = NULL; +PFNGLMATRIXMULTFEXTPROC __glewMatrixMultfEXT = NULL; +PFNGLMATRIXORTHOEXTPROC __glewMatrixOrthoEXT = NULL; +PFNGLMATRIXPOPEXTPROC __glewMatrixPopEXT = NULL; +PFNGLMATRIXPUSHEXTPROC __glewMatrixPushEXT = NULL; +PFNGLMATRIXROTATEDEXTPROC __glewMatrixRotatedEXT = NULL; +PFNGLMATRIXROTATEFEXTPROC __glewMatrixRotatefEXT = NULL; +PFNGLMATRIXSCALEDEXTPROC __glewMatrixScaledEXT = NULL; +PFNGLMATRIXSCALEFEXTPROC __glewMatrixScalefEXT = NULL; +PFNGLMATRIXTRANSLATEDEXTPROC __glewMatrixTranslatedEXT = NULL; +PFNGLMATRIXTRANSLATEFEXTPROC __glewMatrixTranslatefEXT = NULL; +PFNGLMULTITEXBUFFEREXTPROC __glewMultiTexBufferEXT = NULL; +PFNGLMULTITEXCOORDPOINTEREXTPROC __glewMultiTexCoordPointerEXT = NULL; +PFNGLMULTITEXENVFEXTPROC __glewMultiTexEnvfEXT = NULL; +PFNGLMULTITEXENVFVEXTPROC __glewMultiTexEnvfvEXT = NULL; +PFNGLMULTITEXENVIEXTPROC __glewMultiTexEnviEXT = NULL; +PFNGLMULTITEXENVIVEXTPROC __glewMultiTexEnvivEXT = NULL; +PFNGLMULTITEXGENDEXTPROC __glewMultiTexGendEXT = NULL; +PFNGLMULTITEXGENDVEXTPROC __glewMultiTexGendvEXT = NULL; +PFNGLMULTITEXGENFEXTPROC __glewMultiTexGenfEXT = NULL; +PFNGLMULTITEXGENFVEXTPROC __glewMultiTexGenfvEXT = NULL; +PFNGLMULTITEXGENIEXTPROC __glewMultiTexGeniEXT = NULL; +PFNGLMULTITEXGENIVEXTPROC __glewMultiTexGenivEXT = NULL; +PFNGLMULTITEXIMAGE1DEXTPROC __glewMultiTexImage1DEXT = NULL; +PFNGLMULTITEXIMAGE2DEXTPROC __glewMultiTexImage2DEXT = NULL; +PFNGLMULTITEXIMAGE3DEXTPROC __glewMultiTexImage3DEXT = NULL; +PFNGLMULTITEXPARAMETERIIVEXTPROC __glewMultiTexParameterIivEXT = NULL; +PFNGLMULTITEXPARAMETERIUIVEXTPROC __glewMultiTexParameterIuivEXT = NULL; +PFNGLMULTITEXPARAMETERFEXTPROC __glewMultiTexParameterfEXT = NULL; +PFNGLMULTITEXPARAMETERFVEXTPROC __glewMultiTexParameterfvEXT = NULL; +PFNGLMULTITEXPARAMETERIEXTPROC __glewMultiTexParameteriEXT = NULL; +PFNGLMULTITEXPARAMETERIVEXTPROC __glewMultiTexParameterivEXT = NULL; +PFNGLMULTITEXRENDERBUFFEREXTPROC __glewMultiTexRenderbufferEXT = NULL; +PFNGLMULTITEXSUBIMAGE1DEXTPROC __glewMultiTexSubImage1DEXT = NULL; +PFNGLMULTITEXSUBIMAGE2DEXTPROC __glewMultiTexSubImage2DEXT = NULL; +PFNGLMULTITEXSUBIMAGE3DEXTPROC __glewMultiTexSubImage3DEXT = NULL; +PFNGLNAMEDBUFFERDATAEXTPROC __glewNamedBufferDataEXT = NULL; +PFNGLNAMEDBUFFERSUBDATAEXTPROC __glewNamedBufferSubDataEXT = NULL; +PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC __glewNamedFramebufferRenderbufferEXT = NULL; +PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC __glewNamedFramebufferTexture1DEXT = NULL; +PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC __glewNamedFramebufferTexture2DEXT = NULL; +PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC __glewNamedFramebufferTexture3DEXT = NULL; +PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC __glewNamedFramebufferTextureEXT = NULL; +PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC __glewNamedFramebufferTextureFaceEXT = NULL; +PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC __glewNamedFramebufferTextureLayerEXT = NULL; +PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC __glewNamedProgramLocalParameter4dEXT = NULL; +PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC __glewNamedProgramLocalParameter4dvEXT = NULL; +PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC __glewNamedProgramLocalParameter4fEXT = NULL; +PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC __glewNamedProgramLocalParameter4fvEXT = NULL; +PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC __glewNamedProgramLocalParameterI4iEXT = NULL; +PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC __glewNamedProgramLocalParameterI4ivEXT = NULL; +PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC __glewNamedProgramLocalParameterI4uiEXT = NULL; +PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC __glewNamedProgramLocalParameterI4uivEXT = NULL; +PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC __glewNamedProgramLocalParameters4fvEXT = NULL; +PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC __glewNamedProgramLocalParametersI4ivEXT = NULL; +PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC __glewNamedProgramLocalParametersI4uivEXT = NULL; +PFNGLNAMEDPROGRAMSTRINGEXTPROC __glewNamedProgramStringEXT = NULL; +PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC __glewNamedRenderbufferStorageEXT = NULL; +PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC __glewNamedRenderbufferStorageMultisampleCoverageEXT = NULL; +PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC __glewNamedRenderbufferStorageMultisampleEXT = NULL; +PFNGLPROGRAMUNIFORM1FEXTPROC __glewProgramUniform1fEXT = NULL; +PFNGLPROGRAMUNIFORM1FVEXTPROC __glewProgramUniform1fvEXT = NULL; +PFNGLPROGRAMUNIFORM1IEXTPROC __glewProgramUniform1iEXT = NULL; +PFNGLPROGRAMUNIFORM1IVEXTPROC __glewProgramUniform1ivEXT = NULL; +PFNGLPROGRAMUNIFORM1UIEXTPROC __glewProgramUniform1uiEXT = NULL; +PFNGLPROGRAMUNIFORM1UIVEXTPROC __glewProgramUniform1uivEXT = NULL; +PFNGLPROGRAMUNIFORM2FEXTPROC __glewProgramUniform2fEXT = NULL; +PFNGLPROGRAMUNIFORM2FVEXTPROC __glewProgramUniform2fvEXT = NULL; +PFNGLPROGRAMUNIFORM2IEXTPROC __glewProgramUniform2iEXT = NULL; +PFNGLPROGRAMUNIFORM2IVEXTPROC __glewProgramUniform2ivEXT = NULL; +PFNGLPROGRAMUNIFORM2UIEXTPROC __glewProgramUniform2uiEXT = NULL; +PFNGLPROGRAMUNIFORM2UIVEXTPROC __glewProgramUniform2uivEXT = NULL; +PFNGLPROGRAMUNIFORM3FEXTPROC __glewProgramUniform3fEXT = NULL; +PFNGLPROGRAMUNIFORM3FVEXTPROC __glewProgramUniform3fvEXT = NULL; +PFNGLPROGRAMUNIFORM3IEXTPROC __glewProgramUniform3iEXT = NULL; +PFNGLPROGRAMUNIFORM3IVEXTPROC __glewProgramUniform3ivEXT = NULL; +PFNGLPROGRAMUNIFORM3UIEXTPROC __glewProgramUniform3uiEXT = NULL; +PFNGLPROGRAMUNIFORM3UIVEXTPROC __glewProgramUniform3uivEXT = NULL; +PFNGLPROGRAMUNIFORM4FEXTPROC __glewProgramUniform4fEXT = NULL; +PFNGLPROGRAMUNIFORM4FVEXTPROC __glewProgramUniform4fvEXT = NULL; +PFNGLPROGRAMUNIFORM4IEXTPROC __glewProgramUniform4iEXT = NULL; +PFNGLPROGRAMUNIFORM4IVEXTPROC __glewProgramUniform4ivEXT = NULL; +PFNGLPROGRAMUNIFORM4UIEXTPROC __glewProgramUniform4uiEXT = NULL; +PFNGLPROGRAMUNIFORM4UIVEXTPROC __glewProgramUniform4uivEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC __glewProgramUniformMatrix2fvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC __glewProgramUniformMatrix2x3fvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC __glewProgramUniformMatrix2x4fvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC __glewProgramUniformMatrix3fvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC __glewProgramUniformMatrix3x2fvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC __glewProgramUniformMatrix3x4fvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC __glewProgramUniformMatrix4fvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC __glewProgramUniformMatrix4x2fvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC __glewProgramUniformMatrix4x3fvEXT = NULL; +PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC __glewPushClientAttribDefaultEXT = NULL; +PFNGLTEXTUREBUFFEREXTPROC __glewTextureBufferEXT = NULL; +PFNGLTEXTUREIMAGE1DEXTPROC __glewTextureImage1DEXT = NULL; +PFNGLTEXTUREIMAGE2DEXTPROC __glewTextureImage2DEXT = NULL; +PFNGLTEXTUREIMAGE3DEXTPROC __glewTextureImage3DEXT = NULL; +PFNGLTEXTUREPARAMETERIIVEXTPROC __glewTextureParameterIivEXT = NULL; +PFNGLTEXTUREPARAMETERIUIVEXTPROC __glewTextureParameterIuivEXT = NULL; +PFNGLTEXTUREPARAMETERFEXTPROC __glewTextureParameterfEXT = NULL; +PFNGLTEXTUREPARAMETERFVEXTPROC __glewTextureParameterfvEXT = NULL; +PFNGLTEXTUREPARAMETERIEXTPROC __glewTextureParameteriEXT = NULL; +PFNGLTEXTUREPARAMETERIVEXTPROC __glewTextureParameterivEXT = NULL; +PFNGLTEXTURERENDERBUFFEREXTPROC __glewTextureRenderbufferEXT = NULL; +PFNGLTEXTURESUBIMAGE1DEXTPROC __glewTextureSubImage1DEXT = NULL; +PFNGLTEXTURESUBIMAGE2DEXTPROC __glewTextureSubImage2DEXT = NULL; +PFNGLTEXTURESUBIMAGE3DEXTPROC __glewTextureSubImage3DEXT = NULL; +PFNGLUNMAPNAMEDBUFFEREXTPROC __glewUnmapNamedBufferEXT = NULL; + +PFNGLCOLORMASKINDEXEDEXTPROC __glewColorMaskIndexedEXT = NULL; +PFNGLDISABLEINDEXEDEXTPROC __glewDisableIndexedEXT = NULL; +PFNGLENABLEINDEXEDEXTPROC __glewEnableIndexedEXT = NULL; +PFNGLGETBOOLEANINDEXEDVEXTPROC __glewGetBooleanIndexedvEXT = NULL; +PFNGLGETINTEGERINDEXEDVEXTPROC __glewGetIntegerIndexedvEXT = NULL; +PFNGLISENABLEDINDEXEDEXTPROC __glewIsEnabledIndexedEXT = NULL; + +PFNGLDRAWARRAYSINSTANCEDEXTPROC __glewDrawArraysInstancedEXT = NULL; +PFNGLDRAWELEMENTSINSTANCEDEXTPROC __glewDrawElementsInstancedEXT = NULL; + +PFNGLDRAWRANGEELEMENTSEXTPROC __glewDrawRangeElementsEXT = NULL; + +PFNGLFOGCOORDPOINTEREXTPROC __glewFogCoordPointerEXT = NULL; +PFNGLFOGCOORDDEXTPROC __glewFogCoorddEXT = NULL; +PFNGLFOGCOORDDVEXTPROC __glewFogCoorddvEXT = NULL; +PFNGLFOGCOORDFEXTPROC __glewFogCoordfEXT = NULL; +PFNGLFOGCOORDFVEXTPROC __glewFogCoordfvEXT = NULL; + +PFNGLFRAGMENTCOLORMATERIALEXTPROC __glewFragmentColorMaterialEXT = NULL; +PFNGLFRAGMENTLIGHTMODELFEXTPROC __glewFragmentLightModelfEXT = NULL; +PFNGLFRAGMENTLIGHTMODELFVEXTPROC __glewFragmentLightModelfvEXT = NULL; +PFNGLFRAGMENTLIGHTMODELIEXTPROC __glewFragmentLightModeliEXT = NULL; +PFNGLFRAGMENTLIGHTMODELIVEXTPROC __glewFragmentLightModelivEXT = NULL; +PFNGLFRAGMENTLIGHTFEXTPROC __glewFragmentLightfEXT = NULL; +PFNGLFRAGMENTLIGHTFVEXTPROC __glewFragmentLightfvEXT = NULL; +PFNGLFRAGMENTLIGHTIEXTPROC __glewFragmentLightiEXT = NULL; +PFNGLFRAGMENTLIGHTIVEXTPROC __glewFragmentLightivEXT = NULL; +PFNGLFRAGMENTMATERIALFEXTPROC __glewFragmentMaterialfEXT = NULL; +PFNGLFRAGMENTMATERIALFVEXTPROC __glewFragmentMaterialfvEXT = NULL; +PFNGLFRAGMENTMATERIALIEXTPROC __glewFragmentMaterialiEXT = NULL; +PFNGLFRAGMENTMATERIALIVEXTPROC __glewFragmentMaterialivEXT = NULL; +PFNGLGETFRAGMENTLIGHTFVEXTPROC __glewGetFragmentLightfvEXT = NULL; +PFNGLGETFRAGMENTLIGHTIVEXTPROC __glewGetFragmentLightivEXT = NULL; +PFNGLGETFRAGMENTMATERIALFVEXTPROC __glewGetFragmentMaterialfvEXT = NULL; +PFNGLGETFRAGMENTMATERIALIVEXTPROC __glewGetFragmentMaterialivEXT = NULL; +PFNGLLIGHTENVIEXTPROC __glewLightEnviEXT = NULL; + +PFNGLBLITFRAMEBUFFEREXTPROC __glewBlitFramebufferEXT = NULL; + +PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC __glewRenderbufferStorageMultisampleEXT = NULL; + +PFNGLBINDFRAMEBUFFEREXTPROC __glewBindFramebufferEXT = NULL; +PFNGLBINDRENDERBUFFEREXTPROC __glewBindRenderbufferEXT = NULL; +PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC __glewCheckFramebufferStatusEXT = NULL; +PFNGLDELETEFRAMEBUFFERSEXTPROC __glewDeleteFramebuffersEXT = NULL; +PFNGLDELETERENDERBUFFERSEXTPROC __glewDeleteRenderbuffersEXT = NULL; +PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC __glewFramebufferRenderbufferEXT = NULL; +PFNGLFRAMEBUFFERTEXTURE1DEXTPROC __glewFramebufferTexture1DEXT = NULL; +PFNGLFRAMEBUFFERTEXTURE2DEXTPROC __glewFramebufferTexture2DEXT = NULL; +PFNGLFRAMEBUFFERTEXTURE3DEXTPROC __glewFramebufferTexture3DEXT = NULL; +PFNGLGENFRAMEBUFFERSEXTPROC __glewGenFramebuffersEXT = NULL; +PFNGLGENRENDERBUFFERSEXTPROC __glewGenRenderbuffersEXT = NULL; +PFNGLGENERATEMIPMAPEXTPROC __glewGenerateMipmapEXT = NULL; +PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC __glewGetFramebufferAttachmentParameterivEXT = NULL; +PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC __glewGetRenderbufferParameterivEXT = NULL; +PFNGLISFRAMEBUFFEREXTPROC __glewIsFramebufferEXT = NULL; +PFNGLISRENDERBUFFEREXTPROC __glewIsRenderbufferEXT = NULL; +PFNGLRENDERBUFFERSTORAGEEXTPROC __glewRenderbufferStorageEXT = NULL; + +PFNGLFRAMEBUFFERTEXTUREEXTPROC __glewFramebufferTextureEXT = NULL; +PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC __glewFramebufferTextureFaceEXT = NULL; +PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC __glewFramebufferTextureLayerEXT = NULL; +PFNGLPROGRAMPARAMETERIEXTPROC __glewProgramParameteriEXT = NULL; + +PFNGLPROGRAMENVPARAMETERS4FVEXTPROC __glewProgramEnvParameters4fvEXT = NULL; +PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC __glewProgramLocalParameters4fvEXT = NULL; + +PFNGLBINDFRAGDATALOCATIONEXTPROC __glewBindFragDataLocationEXT = NULL; +PFNGLGETFRAGDATALOCATIONEXTPROC __glewGetFragDataLocationEXT = NULL; +PFNGLGETUNIFORMUIVEXTPROC __glewGetUniformuivEXT = NULL; +PFNGLGETVERTEXATTRIBIIVEXTPROC __glewGetVertexAttribIivEXT = NULL; +PFNGLGETVERTEXATTRIBIUIVEXTPROC __glewGetVertexAttribIuivEXT = NULL; +PFNGLUNIFORM1UIEXTPROC __glewUniform1uiEXT = NULL; +PFNGLUNIFORM1UIVEXTPROC __glewUniform1uivEXT = NULL; +PFNGLUNIFORM2UIEXTPROC __glewUniform2uiEXT = NULL; +PFNGLUNIFORM2UIVEXTPROC __glewUniform2uivEXT = NULL; +PFNGLUNIFORM3UIEXTPROC __glewUniform3uiEXT = NULL; +PFNGLUNIFORM3UIVEXTPROC __glewUniform3uivEXT = NULL; +PFNGLUNIFORM4UIEXTPROC __glewUniform4uiEXT = NULL; +PFNGLUNIFORM4UIVEXTPROC __glewUniform4uivEXT = NULL; +PFNGLVERTEXATTRIBI1IEXTPROC __glewVertexAttribI1iEXT = NULL; +PFNGLVERTEXATTRIBI1IVEXTPROC __glewVertexAttribI1ivEXT = NULL; +PFNGLVERTEXATTRIBI1UIEXTPROC __glewVertexAttribI1uiEXT = NULL; +PFNGLVERTEXATTRIBI1UIVEXTPROC __glewVertexAttribI1uivEXT = NULL; +PFNGLVERTEXATTRIBI2IEXTPROC __glewVertexAttribI2iEXT = NULL; +PFNGLVERTEXATTRIBI2IVEXTPROC __glewVertexAttribI2ivEXT = NULL; +PFNGLVERTEXATTRIBI2UIEXTPROC __glewVertexAttribI2uiEXT = NULL; +PFNGLVERTEXATTRIBI2UIVEXTPROC __glewVertexAttribI2uivEXT = NULL; +PFNGLVERTEXATTRIBI3IEXTPROC __glewVertexAttribI3iEXT = NULL; +PFNGLVERTEXATTRIBI3IVEXTPROC __glewVertexAttribI3ivEXT = NULL; +PFNGLVERTEXATTRIBI3UIEXTPROC __glewVertexAttribI3uiEXT = NULL; +PFNGLVERTEXATTRIBI3UIVEXTPROC __glewVertexAttribI3uivEXT = NULL; +PFNGLVERTEXATTRIBI4BVEXTPROC __glewVertexAttribI4bvEXT = NULL; +PFNGLVERTEXATTRIBI4IEXTPROC __glewVertexAttribI4iEXT = NULL; +PFNGLVERTEXATTRIBI4IVEXTPROC __glewVertexAttribI4ivEXT = NULL; +PFNGLVERTEXATTRIBI4SVEXTPROC __glewVertexAttribI4svEXT = NULL; +PFNGLVERTEXATTRIBI4UBVEXTPROC __glewVertexAttribI4ubvEXT = NULL; +PFNGLVERTEXATTRIBI4UIEXTPROC __glewVertexAttribI4uiEXT = NULL; +PFNGLVERTEXATTRIBI4UIVEXTPROC __glewVertexAttribI4uivEXT = NULL; +PFNGLVERTEXATTRIBI4USVEXTPROC __glewVertexAttribI4usvEXT = NULL; +PFNGLVERTEXATTRIBIPOINTEREXTPROC __glewVertexAttribIPointerEXT = NULL; + +PFNGLGETHISTOGRAMEXTPROC __glewGetHistogramEXT = NULL; +PFNGLGETHISTOGRAMPARAMETERFVEXTPROC __glewGetHistogramParameterfvEXT = NULL; +PFNGLGETHISTOGRAMPARAMETERIVEXTPROC __glewGetHistogramParameterivEXT = NULL; +PFNGLGETMINMAXEXTPROC __glewGetMinmaxEXT = NULL; +PFNGLGETMINMAXPARAMETERFVEXTPROC __glewGetMinmaxParameterfvEXT = NULL; +PFNGLGETMINMAXPARAMETERIVEXTPROC __glewGetMinmaxParameterivEXT = NULL; +PFNGLHISTOGRAMEXTPROC __glewHistogramEXT = NULL; +PFNGLMINMAXEXTPROC __glewMinmaxEXT = NULL; +PFNGLRESETHISTOGRAMEXTPROC __glewResetHistogramEXT = NULL; +PFNGLRESETMINMAXEXTPROC __glewResetMinmaxEXT = NULL; + +PFNGLINDEXFUNCEXTPROC __glewIndexFuncEXT = NULL; + +PFNGLINDEXMATERIALEXTPROC __glewIndexMaterialEXT = NULL; + +PFNGLAPPLYTEXTUREEXTPROC __glewApplyTextureEXT = NULL; +PFNGLTEXTURELIGHTEXTPROC __glewTextureLightEXT = NULL; +PFNGLTEXTUREMATERIALEXTPROC __glewTextureMaterialEXT = NULL; + +PFNGLMULTIDRAWARRAYSEXTPROC __glewMultiDrawArraysEXT = NULL; +PFNGLMULTIDRAWELEMENTSEXTPROC __glewMultiDrawElementsEXT = NULL; + +PFNGLSAMPLEMASKEXTPROC __glewSampleMaskEXT = NULL; +PFNGLSAMPLEPATTERNEXTPROC __glewSamplePatternEXT = NULL; + +PFNGLCOLORTABLEEXTPROC __glewColorTableEXT = NULL; +PFNGLGETCOLORTABLEEXTPROC __glewGetColorTableEXT = NULL; +PFNGLGETCOLORTABLEPARAMETERFVEXTPROC __glewGetColorTableParameterfvEXT = NULL; +PFNGLGETCOLORTABLEPARAMETERIVEXTPROC __glewGetColorTableParameterivEXT = NULL; + +PFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC __glewGetPixelTransformParameterfvEXT = NULL; +PFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC __glewGetPixelTransformParameterivEXT = NULL; +PFNGLPIXELTRANSFORMPARAMETERFEXTPROC __glewPixelTransformParameterfEXT = NULL; +PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC __glewPixelTransformParameterfvEXT = NULL; +PFNGLPIXELTRANSFORMPARAMETERIEXTPROC __glewPixelTransformParameteriEXT = NULL; +PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC __glewPixelTransformParameterivEXT = NULL; + +PFNGLPOINTPARAMETERFEXTPROC __glewPointParameterfEXT = NULL; +PFNGLPOINTPARAMETERFVEXTPROC __glewPointParameterfvEXT = NULL; + +PFNGLPOLYGONOFFSETEXTPROC __glewPolygonOffsetEXT = NULL; + +PFNGLBEGINSCENEEXTPROC __glewBeginSceneEXT = NULL; +PFNGLENDSCENEEXTPROC __glewEndSceneEXT = NULL; + +PFNGLSECONDARYCOLOR3BEXTPROC __glewSecondaryColor3bEXT = NULL; +PFNGLSECONDARYCOLOR3BVEXTPROC __glewSecondaryColor3bvEXT = NULL; +PFNGLSECONDARYCOLOR3DEXTPROC __glewSecondaryColor3dEXT = NULL; +PFNGLSECONDARYCOLOR3DVEXTPROC __glewSecondaryColor3dvEXT = NULL; +PFNGLSECONDARYCOLOR3FEXTPROC __glewSecondaryColor3fEXT = NULL; +PFNGLSECONDARYCOLOR3FVEXTPROC __glewSecondaryColor3fvEXT = NULL; +PFNGLSECONDARYCOLOR3IEXTPROC __glewSecondaryColor3iEXT = NULL; +PFNGLSECONDARYCOLOR3IVEXTPROC __glewSecondaryColor3ivEXT = NULL; +PFNGLSECONDARYCOLOR3SEXTPROC __glewSecondaryColor3sEXT = NULL; +PFNGLSECONDARYCOLOR3SVEXTPROC __glewSecondaryColor3svEXT = NULL; +PFNGLSECONDARYCOLOR3UBEXTPROC __glewSecondaryColor3ubEXT = NULL; +PFNGLSECONDARYCOLOR3UBVEXTPROC __glewSecondaryColor3ubvEXT = NULL; +PFNGLSECONDARYCOLOR3UIEXTPROC __glewSecondaryColor3uiEXT = NULL; +PFNGLSECONDARYCOLOR3UIVEXTPROC __glewSecondaryColor3uivEXT = NULL; +PFNGLSECONDARYCOLOR3USEXTPROC __glewSecondaryColor3usEXT = NULL; +PFNGLSECONDARYCOLOR3USVEXTPROC __glewSecondaryColor3usvEXT = NULL; +PFNGLSECONDARYCOLORPOINTEREXTPROC __glewSecondaryColorPointerEXT = NULL; + +PFNGLACTIVESTENCILFACEEXTPROC __glewActiveStencilFaceEXT = NULL; + +PFNGLTEXSUBIMAGE1DEXTPROC __glewTexSubImage1DEXT = NULL; +PFNGLTEXSUBIMAGE2DEXTPROC __glewTexSubImage2DEXT = NULL; +PFNGLTEXSUBIMAGE3DEXTPROC __glewTexSubImage3DEXT = NULL; + +PFNGLTEXIMAGE3DEXTPROC __glewTexImage3DEXT = NULL; + +PFNGLTEXBUFFEREXTPROC __glewTexBufferEXT = NULL; + +PFNGLCLEARCOLORIIEXTPROC __glewClearColorIiEXT = NULL; +PFNGLCLEARCOLORIUIEXTPROC __glewClearColorIuiEXT = NULL; +PFNGLGETTEXPARAMETERIIVEXTPROC __glewGetTexParameterIivEXT = NULL; +PFNGLGETTEXPARAMETERIUIVEXTPROC __glewGetTexParameterIuivEXT = NULL; +PFNGLTEXPARAMETERIIVEXTPROC __glewTexParameterIivEXT = NULL; +PFNGLTEXPARAMETERIUIVEXTPROC __glewTexParameterIuivEXT = NULL; + +PFNGLARETEXTURESRESIDENTEXTPROC __glewAreTexturesResidentEXT = NULL; +PFNGLBINDTEXTUREEXTPROC __glewBindTextureEXT = NULL; +PFNGLDELETETEXTURESEXTPROC __glewDeleteTexturesEXT = NULL; +PFNGLGENTEXTURESEXTPROC __glewGenTexturesEXT = NULL; +PFNGLISTEXTUREEXTPROC __glewIsTextureEXT = NULL; +PFNGLPRIORITIZETEXTURESEXTPROC __glewPrioritizeTexturesEXT = NULL; + +PFNGLTEXTURENORMALEXTPROC __glewTextureNormalEXT = NULL; + +PFNGLGETQUERYOBJECTI64VEXTPROC __glewGetQueryObjecti64vEXT = NULL; +PFNGLGETQUERYOBJECTUI64VEXTPROC __glewGetQueryObjectui64vEXT = NULL; + +PFNGLBEGINTRANSFORMFEEDBACKEXTPROC __glewBeginTransformFeedbackEXT = NULL; +PFNGLBINDBUFFERBASEEXTPROC __glewBindBufferBaseEXT = NULL; +PFNGLBINDBUFFEROFFSETEXTPROC __glewBindBufferOffsetEXT = NULL; +PFNGLBINDBUFFERRANGEEXTPROC __glewBindBufferRangeEXT = NULL; +PFNGLENDTRANSFORMFEEDBACKEXTPROC __glewEndTransformFeedbackEXT = NULL; +PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC __glewGetTransformFeedbackVaryingEXT = NULL; +PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC __glewTransformFeedbackVaryingsEXT = NULL; + +PFNGLARRAYELEMENTEXTPROC __glewArrayElementEXT = NULL; +PFNGLCOLORPOINTEREXTPROC __glewColorPointerEXT = NULL; +PFNGLDRAWARRAYSEXTPROC __glewDrawArraysEXT = NULL; +PFNGLEDGEFLAGPOINTEREXTPROC __glewEdgeFlagPointerEXT = NULL; +PFNGLGETPOINTERVEXTPROC __glewGetPointervEXT = NULL; +PFNGLINDEXPOINTEREXTPROC __glewIndexPointerEXT = NULL; +PFNGLNORMALPOINTEREXTPROC __glewNormalPointerEXT = NULL; +PFNGLTEXCOORDPOINTEREXTPROC __glewTexCoordPointerEXT = NULL; +PFNGLVERTEXPOINTEREXTPROC __glewVertexPointerEXT = NULL; + +PFNGLBEGINVERTEXSHADEREXTPROC __glewBeginVertexShaderEXT = NULL; +PFNGLBINDLIGHTPARAMETEREXTPROC __glewBindLightParameterEXT = NULL; +PFNGLBINDMATERIALPARAMETEREXTPROC __glewBindMaterialParameterEXT = NULL; +PFNGLBINDPARAMETEREXTPROC __glewBindParameterEXT = NULL; +PFNGLBINDTEXGENPARAMETEREXTPROC __glewBindTexGenParameterEXT = NULL; +PFNGLBINDTEXTUREUNITPARAMETEREXTPROC __glewBindTextureUnitParameterEXT = NULL; +PFNGLBINDVERTEXSHADEREXTPROC __glewBindVertexShaderEXT = NULL; +PFNGLDELETEVERTEXSHADEREXTPROC __glewDeleteVertexShaderEXT = NULL; +PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC __glewDisableVariantClientStateEXT = NULL; +PFNGLENABLEVARIANTCLIENTSTATEEXTPROC __glewEnableVariantClientStateEXT = NULL; +PFNGLENDVERTEXSHADEREXTPROC __glewEndVertexShaderEXT = NULL; +PFNGLEXTRACTCOMPONENTEXTPROC __glewExtractComponentEXT = NULL; +PFNGLGENSYMBOLSEXTPROC __glewGenSymbolsEXT = NULL; +PFNGLGENVERTEXSHADERSEXTPROC __glewGenVertexShadersEXT = NULL; +PFNGLGETINVARIANTBOOLEANVEXTPROC __glewGetInvariantBooleanvEXT = NULL; +PFNGLGETINVARIANTFLOATVEXTPROC __glewGetInvariantFloatvEXT = NULL; +PFNGLGETINVARIANTINTEGERVEXTPROC __glewGetInvariantIntegervEXT = NULL; +PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC __glewGetLocalConstantBooleanvEXT = NULL; +PFNGLGETLOCALCONSTANTFLOATVEXTPROC __glewGetLocalConstantFloatvEXT = NULL; +PFNGLGETLOCALCONSTANTINTEGERVEXTPROC __glewGetLocalConstantIntegervEXT = NULL; +PFNGLGETVARIANTBOOLEANVEXTPROC __glewGetVariantBooleanvEXT = NULL; +PFNGLGETVARIANTFLOATVEXTPROC __glewGetVariantFloatvEXT = NULL; +PFNGLGETVARIANTINTEGERVEXTPROC __glewGetVariantIntegervEXT = NULL; +PFNGLGETVARIANTPOINTERVEXTPROC __glewGetVariantPointervEXT = NULL; +PFNGLINSERTCOMPONENTEXTPROC __glewInsertComponentEXT = NULL; +PFNGLISVARIANTENABLEDEXTPROC __glewIsVariantEnabledEXT = NULL; +PFNGLSETINVARIANTEXTPROC __glewSetInvariantEXT = NULL; +PFNGLSETLOCALCONSTANTEXTPROC __glewSetLocalConstantEXT = NULL; +PFNGLSHADEROP1EXTPROC __glewShaderOp1EXT = NULL; +PFNGLSHADEROP2EXTPROC __glewShaderOp2EXT = NULL; +PFNGLSHADEROP3EXTPROC __glewShaderOp3EXT = NULL; +PFNGLSWIZZLEEXTPROC __glewSwizzleEXT = NULL; +PFNGLVARIANTPOINTEREXTPROC __glewVariantPointerEXT = NULL; +PFNGLVARIANTBVEXTPROC __glewVariantbvEXT = NULL; +PFNGLVARIANTDVEXTPROC __glewVariantdvEXT = NULL; +PFNGLVARIANTFVEXTPROC __glewVariantfvEXT = NULL; +PFNGLVARIANTIVEXTPROC __glewVariantivEXT = NULL; +PFNGLVARIANTSVEXTPROC __glewVariantsvEXT = NULL; +PFNGLVARIANTUBVEXTPROC __glewVariantubvEXT = NULL; +PFNGLVARIANTUIVEXTPROC __glewVariantuivEXT = NULL; +PFNGLVARIANTUSVEXTPROC __glewVariantusvEXT = NULL; +PFNGLWRITEMASKEXTPROC __glewWriteMaskEXT = NULL; + +PFNGLVERTEXWEIGHTPOINTEREXTPROC __glewVertexWeightPointerEXT = NULL; +PFNGLVERTEXWEIGHTFEXTPROC __glewVertexWeightfEXT = NULL; +PFNGLVERTEXWEIGHTFVEXTPROC __glewVertexWeightfvEXT = NULL; + +PFNGLFRAMETERMINATORGREMEDYPROC __glewFrameTerminatorGREMEDY = NULL; + +PFNGLSTRINGMARKERGREMEDYPROC __glewStringMarkerGREMEDY = NULL; + +PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC __glewGetImageTransformParameterfvHP = NULL; +PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC __glewGetImageTransformParameterivHP = NULL; +PFNGLIMAGETRANSFORMPARAMETERFHPPROC __glewImageTransformParameterfHP = NULL; +PFNGLIMAGETRANSFORMPARAMETERFVHPPROC __glewImageTransformParameterfvHP = NULL; +PFNGLIMAGETRANSFORMPARAMETERIHPPROC __glewImageTransformParameteriHP = NULL; +PFNGLIMAGETRANSFORMPARAMETERIVHPPROC __glewImageTransformParameterivHP = NULL; + +PFNGLMULTIMODEDRAWARRAYSIBMPROC __glewMultiModeDrawArraysIBM = NULL; +PFNGLMULTIMODEDRAWELEMENTSIBMPROC __glewMultiModeDrawElementsIBM = NULL; + +PFNGLCOLORPOINTERLISTIBMPROC __glewColorPointerListIBM = NULL; +PFNGLEDGEFLAGPOINTERLISTIBMPROC __glewEdgeFlagPointerListIBM = NULL; +PFNGLFOGCOORDPOINTERLISTIBMPROC __glewFogCoordPointerListIBM = NULL; +PFNGLINDEXPOINTERLISTIBMPROC __glewIndexPointerListIBM = NULL; +PFNGLNORMALPOINTERLISTIBMPROC __glewNormalPointerListIBM = NULL; +PFNGLSECONDARYCOLORPOINTERLISTIBMPROC __glewSecondaryColorPointerListIBM = NULL; +PFNGLTEXCOORDPOINTERLISTIBMPROC __glewTexCoordPointerListIBM = NULL; +PFNGLVERTEXPOINTERLISTIBMPROC __glewVertexPointerListIBM = NULL; + +PFNGLCOLORPOINTERVINTELPROC __glewColorPointervINTEL = NULL; +PFNGLNORMALPOINTERVINTELPROC __glewNormalPointervINTEL = NULL; +PFNGLTEXCOORDPOINTERVINTELPROC __glewTexCoordPointervINTEL = NULL; +PFNGLVERTEXPOINTERVINTELPROC __glewVertexPointervINTEL = NULL; + +PFNGLTEXSCISSORFUNCINTELPROC __glewTexScissorFuncINTEL = NULL; +PFNGLTEXSCISSORINTELPROC __glewTexScissorINTEL = NULL; + +PFNGLBUFFERREGIONENABLEDEXTPROC __glewBufferRegionEnabledEXT = NULL; +PFNGLDELETEBUFFERREGIONEXTPROC __glewDeleteBufferRegionEXT = NULL; +PFNGLDRAWBUFFERREGIONEXTPROC __glewDrawBufferRegionEXT = NULL; +PFNGLNEWBUFFERREGIONEXTPROC __glewNewBufferRegionEXT = NULL; +PFNGLREADBUFFERREGIONEXTPROC __glewReadBufferRegionEXT = NULL; + +PFNGLRESIZEBUFFERSMESAPROC __glewResizeBuffersMESA = NULL; + +PFNGLWINDOWPOS2DMESAPROC __glewWindowPos2dMESA = NULL; +PFNGLWINDOWPOS2DVMESAPROC __glewWindowPos2dvMESA = NULL; +PFNGLWINDOWPOS2FMESAPROC __glewWindowPos2fMESA = NULL; +PFNGLWINDOWPOS2FVMESAPROC __glewWindowPos2fvMESA = NULL; +PFNGLWINDOWPOS2IMESAPROC __glewWindowPos2iMESA = NULL; +PFNGLWINDOWPOS2IVMESAPROC __glewWindowPos2ivMESA = NULL; +PFNGLWINDOWPOS2SMESAPROC __glewWindowPos2sMESA = NULL; +PFNGLWINDOWPOS2SVMESAPROC __glewWindowPos2svMESA = NULL; +PFNGLWINDOWPOS3DMESAPROC __glewWindowPos3dMESA = NULL; +PFNGLWINDOWPOS3DVMESAPROC __glewWindowPos3dvMESA = NULL; +PFNGLWINDOWPOS3FMESAPROC __glewWindowPos3fMESA = NULL; +PFNGLWINDOWPOS3FVMESAPROC __glewWindowPos3fvMESA = NULL; +PFNGLWINDOWPOS3IMESAPROC __glewWindowPos3iMESA = NULL; +PFNGLWINDOWPOS3IVMESAPROC __glewWindowPos3ivMESA = NULL; +PFNGLWINDOWPOS3SMESAPROC __glewWindowPos3sMESA = NULL; +PFNGLWINDOWPOS3SVMESAPROC __glewWindowPos3svMESA = NULL; +PFNGLWINDOWPOS4DMESAPROC __glewWindowPos4dMESA = NULL; +PFNGLWINDOWPOS4DVMESAPROC __glewWindowPos4dvMESA = NULL; +PFNGLWINDOWPOS4FMESAPROC __glewWindowPos4fMESA = NULL; +PFNGLWINDOWPOS4FVMESAPROC __glewWindowPos4fvMESA = NULL; +PFNGLWINDOWPOS4IMESAPROC __glewWindowPos4iMESA = NULL; +PFNGLWINDOWPOS4IVMESAPROC __glewWindowPos4ivMESA = NULL; +PFNGLWINDOWPOS4SMESAPROC __glewWindowPos4sMESA = NULL; +PFNGLWINDOWPOS4SVMESAPROC __glewWindowPos4svMESA = NULL; + +PFNGLBEGINCONDITIONALRENDERNVPROC __glewBeginConditionalRenderNV = NULL; +PFNGLENDCONDITIONALRENDERNVPROC __glewEndConditionalRenderNV = NULL; + +PFNGLCLEARDEPTHDNVPROC __glewClearDepthdNV = NULL; +PFNGLDEPTHBOUNDSDNVPROC __glewDepthBoundsdNV = NULL; +PFNGLDEPTHRANGEDNVPROC __glewDepthRangedNV = NULL; + +PFNGLEVALMAPSNVPROC __glewEvalMapsNV = NULL; +PFNGLGETMAPATTRIBPARAMETERFVNVPROC __glewGetMapAttribParameterfvNV = NULL; +PFNGLGETMAPATTRIBPARAMETERIVNVPROC __glewGetMapAttribParameterivNV = NULL; +PFNGLGETMAPCONTROLPOINTSNVPROC __glewGetMapControlPointsNV = NULL; +PFNGLGETMAPPARAMETERFVNVPROC __glewGetMapParameterfvNV = NULL; +PFNGLGETMAPPARAMETERIVNVPROC __glewGetMapParameterivNV = NULL; +PFNGLMAPCONTROLPOINTSNVPROC __glewMapControlPointsNV = NULL; +PFNGLMAPPARAMETERFVNVPROC __glewMapParameterfvNV = NULL; +PFNGLMAPPARAMETERIVNVPROC __glewMapParameterivNV = NULL; + +PFNGLGETMULTISAMPLEFVNVPROC __glewGetMultisamplefvNV = NULL; +PFNGLSAMPLEMASKINDEXEDNVPROC __glewSampleMaskIndexedNV = NULL; +PFNGLTEXRENDERBUFFERNVPROC __glewTexRenderbufferNV = NULL; + +PFNGLDELETEFENCESNVPROC __glewDeleteFencesNV = NULL; +PFNGLFINISHFENCENVPROC __glewFinishFenceNV = NULL; +PFNGLGENFENCESNVPROC __glewGenFencesNV = NULL; +PFNGLGETFENCEIVNVPROC __glewGetFenceivNV = NULL; +PFNGLISFENCENVPROC __glewIsFenceNV = NULL; +PFNGLSETFENCENVPROC __glewSetFenceNV = NULL; +PFNGLTESTFENCENVPROC __glewTestFenceNV = NULL; + +PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC __glewGetProgramNamedParameterdvNV = NULL; +PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC __glewGetProgramNamedParameterfvNV = NULL; +PFNGLPROGRAMNAMEDPARAMETER4DNVPROC __glewProgramNamedParameter4dNV = NULL; +PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC __glewProgramNamedParameter4dvNV = NULL; +PFNGLPROGRAMNAMEDPARAMETER4FNVPROC __glewProgramNamedParameter4fNV = NULL; +PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC __glewProgramNamedParameter4fvNV = NULL; + +PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC __glewRenderbufferStorageMultisampleCoverageNV = NULL; + +PFNGLPROGRAMVERTEXLIMITNVPROC __glewProgramVertexLimitNV = NULL; + +PFNGLPROGRAMENVPARAMETERI4INVPROC __glewProgramEnvParameterI4iNV = NULL; +PFNGLPROGRAMENVPARAMETERI4IVNVPROC __glewProgramEnvParameterI4ivNV = NULL; +PFNGLPROGRAMENVPARAMETERI4UINVPROC __glewProgramEnvParameterI4uiNV = NULL; +PFNGLPROGRAMENVPARAMETERI4UIVNVPROC __glewProgramEnvParameterI4uivNV = NULL; +PFNGLPROGRAMENVPARAMETERSI4IVNVPROC __glewProgramEnvParametersI4ivNV = NULL; +PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC __glewProgramEnvParametersI4uivNV = NULL; +PFNGLPROGRAMLOCALPARAMETERI4INVPROC __glewProgramLocalParameterI4iNV = NULL; +PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC __glewProgramLocalParameterI4ivNV = NULL; +PFNGLPROGRAMLOCALPARAMETERI4UINVPROC __glewProgramLocalParameterI4uiNV = NULL; +PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC __glewProgramLocalParameterI4uivNV = NULL; +PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC __glewProgramLocalParametersI4ivNV = NULL; +PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC __glewProgramLocalParametersI4uivNV = NULL; + +PFNGLCOLOR3HNVPROC __glewColor3hNV = NULL; +PFNGLCOLOR3HVNVPROC __glewColor3hvNV = NULL; +PFNGLCOLOR4HNVPROC __glewColor4hNV = NULL; +PFNGLCOLOR4HVNVPROC __glewColor4hvNV = NULL; +PFNGLFOGCOORDHNVPROC __glewFogCoordhNV = NULL; +PFNGLFOGCOORDHVNVPROC __glewFogCoordhvNV = NULL; +PFNGLMULTITEXCOORD1HNVPROC __glewMultiTexCoord1hNV = NULL; +PFNGLMULTITEXCOORD1HVNVPROC __glewMultiTexCoord1hvNV = NULL; +PFNGLMULTITEXCOORD2HNVPROC __glewMultiTexCoord2hNV = NULL; +PFNGLMULTITEXCOORD2HVNVPROC __glewMultiTexCoord2hvNV = NULL; +PFNGLMULTITEXCOORD3HNVPROC __glewMultiTexCoord3hNV = NULL; +PFNGLMULTITEXCOORD3HVNVPROC __glewMultiTexCoord3hvNV = NULL; +PFNGLMULTITEXCOORD4HNVPROC __glewMultiTexCoord4hNV = NULL; +PFNGLMULTITEXCOORD4HVNVPROC __glewMultiTexCoord4hvNV = NULL; +PFNGLNORMAL3HNVPROC __glewNormal3hNV = NULL; +PFNGLNORMAL3HVNVPROC __glewNormal3hvNV = NULL; +PFNGLSECONDARYCOLOR3HNVPROC __glewSecondaryColor3hNV = NULL; +PFNGLSECONDARYCOLOR3HVNVPROC __glewSecondaryColor3hvNV = NULL; +PFNGLTEXCOORD1HNVPROC __glewTexCoord1hNV = NULL; +PFNGLTEXCOORD1HVNVPROC __glewTexCoord1hvNV = NULL; +PFNGLTEXCOORD2HNVPROC __glewTexCoord2hNV = NULL; +PFNGLTEXCOORD2HVNVPROC __glewTexCoord2hvNV = NULL; +PFNGLTEXCOORD3HNVPROC __glewTexCoord3hNV = NULL; +PFNGLTEXCOORD3HVNVPROC __glewTexCoord3hvNV = NULL; +PFNGLTEXCOORD4HNVPROC __glewTexCoord4hNV = NULL; +PFNGLTEXCOORD4HVNVPROC __glewTexCoord4hvNV = NULL; +PFNGLVERTEX2HNVPROC __glewVertex2hNV = NULL; +PFNGLVERTEX2HVNVPROC __glewVertex2hvNV = NULL; +PFNGLVERTEX3HNVPROC __glewVertex3hNV = NULL; +PFNGLVERTEX3HVNVPROC __glewVertex3hvNV = NULL; +PFNGLVERTEX4HNVPROC __glewVertex4hNV = NULL; +PFNGLVERTEX4HVNVPROC __glewVertex4hvNV = NULL; +PFNGLVERTEXATTRIB1HNVPROC __glewVertexAttrib1hNV = NULL; +PFNGLVERTEXATTRIB1HVNVPROC __glewVertexAttrib1hvNV = NULL; +PFNGLVERTEXATTRIB2HNVPROC __glewVertexAttrib2hNV = NULL; +PFNGLVERTEXATTRIB2HVNVPROC __glewVertexAttrib2hvNV = NULL; +PFNGLVERTEXATTRIB3HNVPROC __glewVertexAttrib3hNV = NULL; +PFNGLVERTEXATTRIB3HVNVPROC __glewVertexAttrib3hvNV = NULL; +PFNGLVERTEXATTRIB4HNVPROC __glewVertexAttrib4hNV = NULL; +PFNGLVERTEXATTRIB4HVNVPROC __glewVertexAttrib4hvNV = NULL; +PFNGLVERTEXATTRIBS1HVNVPROC __glewVertexAttribs1hvNV = NULL; +PFNGLVERTEXATTRIBS2HVNVPROC __glewVertexAttribs2hvNV = NULL; +PFNGLVERTEXATTRIBS3HVNVPROC __glewVertexAttribs3hvNV = NULL; +PFNGLVERTEXATTRIBS4HVNVPROC __glewVertexAttribs4hvNV = NULL; +PFNGLVERTEXWEIGHTHNVPROC __glewVertexWeighthNV = NULL; +PFNGLVERTEXWEIGHTHVNVPROC __glewVertexWeighthvNV = NULL; + +PFNGLBEGINOCCLUSIONQUERYNVPROC __glewBeginOcclusionQueryNV = NULL; +PFNGLDELETEOCCLUSIONQUERIESNVPROC __glewDeleteOcclusionQueriesNV = NULL; +PFNGLENDOCCLUSIONQUERYNVPROC __glewEndOcclusionQueryNV = NULL; +PFNGLGENOCCLUSIONQUERIESNVPROC __glewGenOcclusionQueriesNV = NULL; +PFNGLGETOCCLUSIONQUERYIVNVPROC __glewGetOcclusionQueryivNV = NULL; +PFNGLGETOCCLUSIONQUERYUIVNVPROC __glewGetOcclusionQueryuivNV = NULL; +PFNGLISOCCLUSIONQUERYNVPROC __glewIsOcclusionQueryNV = NULL; + +PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC __glewProgramBufferParametersIivNV = NULL; +PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC __glewProgramBufferParametersIuivNV = NULL; +PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC __glewProgramBufferParametersfvNV = NULL; + +PFNGLFLUSHPIXELDATARANGENVPROC __glewFlushPixelDataRangeNV = NULL; +PFNGLPIXELDATARANGENVPROC __glewPixelDataRangeNV = NULL; + +PFNGLPOINTPARAMETERINVPROC __glewPointParameteriNV = NULL; +PFNGLPOINTPARAMETERIVNVPROC __glewPointParameterivNV = NULL; + +PFNGLGETVIDEOI64VNVPROC __glewGetVideoi64vNV = NULL; +PFNGLGETVIDEOIVNVPROC __glewGetVideoivNV = NULL; +PFNGLGETVIDEOUI64VNVPROC __glewGetVideoui64vNV = NULL; +PFNGLGETVIDEOUIVNVPROC __glewGetVideouivNV = NULL; +PFNGLPRESENTFRAMEDUALFILLNVPROC __glewPresentFrameDualFillNV = NULL; +PFNGLPRESENTFRAMEKEYEDNVPROC __glewPresentFrameKeyedNV = NULL; +PFNGLVIDEOPARAMETERIVNVPROC __glewVideoParameterivNV = NULL; + +PFNGLPRIMITIVERESTARTINDEXNVPROC __glewPrimitiveRestartIndexNV = NULL; +PFNGLPRIMITIVERESTARTNVPROC __glewPrimitiveRestartNV = NULL; + +PFNGLCOMBINERINPUTNVPROC __glewCombinerInputNV = NULL; +PFNGLCOMBINEROUTPUTNVPROC __glewCombinerOutputNV = NULL; +PFNGLCOMBINERPARAMETERFNVPROC __glewCombinerParameterfNV = NULL; +PFNGLCOMBINERPARAMETERFVNVPROC __glewCombinerParameterfvNV = NULL; +PFNGLCOMBINERPARAMETERINVPROC __glewCombinerParameteriNV = NULL; +PFNGLCOMBINERPARAMETERIVNVPROC __glewCombinerParameterivNV = NULL; +PFNGLFINALCOMBINERINPUTNVPROC __glewFinalCombinerInputNV = NULL; +PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC __glewGetCombinerInputParameterfvNV = NULL; +PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC __glewGetCombinerInputParameterivNV = NULL; +PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC __glewGetCombinerOutputParameterfvNV = NULL; +PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC __glewGetCombinerOutputParameterivNV = NULL; +PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC __glewGetFinalCombinerInputParameterfvNV = NULL; +PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC __glewGetFinalCombinerInputParameterivNV = NULL; + +PFNGLCOMBINERSTAGEPARAMETERFVNVPROC __glewCombinerStageParameterfvNV = NULL; +PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC __glewGetCombinerStageParameterfvNV = NULL; + +PFNGLACTIVEVARYINGNVPROC __glewActiveVaryingNV = NULL; +PFNGLBEGINTRANSFORMFEEDBACKNVPROC __glewBeginTransformFeedbackNV = NULL; +PFNGLBINDBUFFERBASENVPROC __glewBindBufferBaseNV = NULL; +PFNGLBINDBUFFEROFFSETNVPROC __glewBindBufferOffsetNV = NULL; +PFNGLBINDBUFFERRANGENVPROC __glewBindBufferRangeNV = NULL; +PFNGLENDTRANSFORMFEEDBACKNVPROC __glewEndTransformFeedbackNV = NULL; +PFNGLGETACTIVEVARYINGNVPROC __glewGetActiveVaryingNV = NULL; +PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC __glewGetTransformFeedbackVaryingNV = NULL; +PFNGLGETVARYINGLOCATIONNVPROC __glewGetVaryingLocationNV = NULL; +PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC __glewTransformFeedbackAttribsNV = NULL; +PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC __glewTransformFeedbackVaryingsNV = NULL; + +PFNGLFLUSHVERTEXARRAYRANGENVPROC __glewFlushVertexArrayRangeNV = NULL; +PFNGLVERTEXARRAYRANGENVPROC __glewVertexArrayRangeNV = NULL; + +PFNGLAREPROGRAMSRESIDENTNVPROC __glewAreProgramsResidentNV = NULL; +PFNGLBINDPROGRAMNVPROC __glewBindProgramNV = NULL; +PFNGLDELETEPROGRAMSNVPROC __glewDeleteProgramsNV = NULL; +PFNGLEXECUTEPROGRAMNVPROC __glewExecuteProgramNV = NULL; +PFNGLGENPROGRAMSNVPROC __glewGenProgramsNV = NULL; +PFNGLGETPROGRAMPARAMETERDVNVPROC __glewGetProgramParameterdvNV = NULL; +PFNGLGETPROGRAMPARAMETERFVNVPROC __glewGetProgramParameterfvNV = NULL; +PFNGLGETPROGRAMSTRINGNVPROC __glewGetProgramStringNV = NULL; +PFNGLGETPROGRAMIVNVPROC __glewGetProgramivNV = NULL; +PFNGLGETTRACKMATRIXIVNVPROC __glewGetTrackMatrixivNV = NULL; +PFNGLGETVERTEXATTRIBPOINTERVNVPROC __glewGetVertexAttribPointervNV = NULL; +PFNGLGETVERTEXATTRIBDVNVPROC __glewGetVertexAttribdvNV = NULL; +PFNGLGETVERTEXATTRIBFVNVPROC __glewGetVertexAttribfvNV = NULL; +PFNGLGETVERTEXATTRIBIVNVPROC __glewGetVertexAttribivNV = NULL; +PFNGLISPROGRAMNVPROC __glewIsProgramNV = NULL; +PFNGLLOADPROGRAMNVPROC __glewLoadProgramNV = NULL; +PFNGLPROGRAMPARAMETER4DNVPROC __glewProgramParameter4dNV = NULL; +PFNGLPROGRAMPARAMETER4DVNVPROC __glewProgramParameter4dvNV = NULL; +PFNGLPROGRAMPARAMETER4FNVPROC __glewProgramParameter4fNV = NULL; +PFNGLPROGRAMPARAMETER4FVNVPROC __glewProgramParameter4fvNV = NULL; +PFNGLPROGRAMPARAMETERS4DVNVPROC __glewProgramParameters4dvNV = NULL; +PFNGLPROGRAMPARAMETERS4FVNVPROC __glewProgramParameters4fvNV = NULL; +PFNGLREQUESTRESIDENTPROGRAMSNVPROC __glewRequestResidentProgramsNV = NULL; +PFNGLTRACKMATRIXNVPROC __glewTrackMatrixNV = NULL; +PFNGLVERTEXATTRIB1DNVPROC __glewVertexAttrib1dNV = NULL; +PFNGLVERTEXATTRIB1DVNVPROC __glewVertexAttrib1dvNV = NULL; +PFNGLVERTEXATTRIB1FNVPROC __glewVertexAttrib1fNV = NULL; +PFNGLVERTEXATTRIB1FVNVPROC __glewVertexAttrib1fvNV = NULL; +PFNGLVERTEXATTRIB1SNVPROC __glewVertexAttrib1sNV = NULL; +PFNGLVERTEXATTRIB1SVNVPROC __glewVertexAttrib1svNV = NULL; +PFNGLVERTEXATTRIB2DNVPROC __glewVertexAttrib2dNV = NULL; +PFNGLVERTEXATTRIB2DVNVPROC __glewVertexAttrib2dvNV = NULL; +PFNGLVERTEXATTRIB2FNVPROC __glewVertexAttrib2fNV = NULL; +PFNGLVERTEXATTRIB2FVNVPROC __glewVertexAttrib2fvNV = NULL; +PFNGLVERTEXATTRIB2SNVPROC __glewVertexAttrib2sNV = NULL; +PFNGLVERTEXATTRIB2SVNVPROC __glewVertexAttrib2svNV = NULL; +PFNGLVERTEXATTRIB3DNVPROC __glewVertexAttrib3dNV = NULL; +PFNGLVERTEXATTRIB3DVNVPROC __glewVertexAttrib3dvNV = NULL; +PFNGLVERTEXATTRIB3FNVPROC __glewVertexAttrib3fNV = NULL; +PFNGLVERTEXATTRIB3FVNVPROC __glewVertexAttrib3fvNV = NULL; +PFNGLVERTEXATTRIB3SNVPROC __glewVertexAttrib3sNV = NULL; +PFNGLVERTEXATTRIB3SVNVPROC __glewVertexAttrib3svNV = NULL; +PFNGLVERTEXATTRIB4DNVPROC __glewVertexAttrib4dNV = NULL; +PFNGLVERTEXATTRIB4DVNVPROC __glewVertexAttrib4dvNV = NULL; +PFNGLVERTEXATTRIB4FNVPROC __glewVertexAttrib4fNV = NULL; +PFNGLVERTEXATTRIB4FVNVPROC __glewVertexAttrib4fvNV = NULL; +PFNGLVERTEXATTRIB4SNVPROC __glewVertexAttrib4sNV = NULL; +PFNGLVERTEXATTRIB4SVNVPROC __glewVertexAttrib4svNV = NULL; +PFNGLVERTEXATTRIB4UBNVPROC __glewVertexAttrib4ubNV = NULL; +PFNGLVERTEXATTRIB4UBVNVPROC __glewVertexAttrib4ubvNV = NULL; +PFNGLVERTEXATTRIBPOINTERNVPROC __glewVertexAttribPointerNV = NULL; +PFNGLVERTEXATTRIBS1DVNVPROC __glewVertexAttribs1dvNV = NULL; +PFNGLVERTEXATTRIBS1FVNVPROC __glewVertexAttribs1fvNV = NULL; +PFNGLVERTEXATTRIBS1SVNVPROC __glewVertexAttribs1svNV = NULL; +PFNGLVERTEXATTRIBS2DVNVPROC __glewVertexAttribs2dvNV = NULL; +PFNGLVERTEXATTRIBS2FVNVPROC __glewVertexAttribs2fvNV = NULL; +PFNGLVERTEXATTRIBS2SVNVPROC __glewVertexAttribs2svNV = NULL; +PFNGLVERTEXATTRIBS3DVNVPROC __glewVertexAttribs3dvNV = NULL; +PFNGLVERTEXATTRIBS3FVNVPROC __glewVertexAttribs3fvNV = NULL; +PFNGLVERTEXATTRIBS3SVNVPROC __glewVertexAttribs3svNV = NULL; +PFNGLVERTEXATTRIBS4DVNVPROC __glewVertexAttribs4dvNV = NULL; +PFNGLVERTEXATTRIBS4FVNVPROC __glewVertexAttribs4fvNV = NULL; +PFNGLVERTEXATTRIBS4SVNVPROC __glewVertexAttribs4svNV = NULL; +PFNGLVERTEXATTRIBS4UBVNVPROC __glewVertexAttribs4ubvNV = NULL; + +PFNGLCLEARDEPTHFOESPROC __glewClearDepthfOES = NULL; +PFNGLCLIPPLANEFOESPROC __glewClipPlanefOES = NULL; +PFNGLDEPTHRANGEFOESPROC __glewDepthRangefOES = NULL; +PFNGLFRUSTUMFOESPROC __glewFrustumfOES = NULL; +PFNGLGETCLIPPLANEFOESPROC __glewGetClipPlanefOES = NULL; +PFNGLORTHOFOESPROC __glewOrthofOES = NULL; + +PFNGLDETAILTEXFUNCSGISPROC __glewDetailTexFuncSGIS = NULL; +PFNGLGETDETAILTEXFUNCSGISPROC __glewGetDetailTexFuncSGIS = NULL; + +PFNGLFOGFUNCSGISPROC __glewFogFuncSGIS = NULL; +PFNGLGETFOGFUNCSGISPROC __glewGetFogFuncSGIS = NULL; + +PFNGLSAMPLEMASKSGISPROC __glewSampleMaskSGIS = NULL; +PFNGLSAMPLEPATTERNSGISPROC __glewSamplePatternSGIS = NULL; + +PFNGLGETSHARPENTEXFUNCSGISPROC __glewGetSharpenTexFuncSGIS = NULL; +PFNGLSHARPENTEXFUNCSGISPROC __glewSharpenTexFuncSGIS = NULL; + +PFNGLTEXIMAGE4DSGISPROC __glewTexImage4DSGIS = NULL; +PFNGLTEXSUBIMAGE4DSGISPROC __glewTexSubImage4DSGIS = NULL; + +PFNGLGETTEXFILTERFUNCSGISPROC __glewGetTexFilterFuncSGIS = NULL; +PFNGLTEXFILTERFUNCSGISPROC __glewTexFilterFuncSGIS = NULL; + +PFNGLASYNCMARKERSGIXPROC __glewAsyncMarkerSGIX = NULL; +PFNGLDELETEASYNCMARKERSSGIXPROC __glewDeleteAsyncMarkersSGIX = NULL; +PFNGLFINISHASYNCSGIXPROC __glewFinishAsyncSGIX = NULL; +PFNGLGENASYNCMARKERSSGIXPROC __glewGenAsyncMarkersSGIX = NULL; +PFNGLISASYNCMARKERSGIXPROC __glewIsAsyncMarkerSGIX = NULL; +PFNGLPOLLASYNCSGIXPROC __glewPollAsyncSGIX = NULL; + +PFNGLFLUSHRASTERSGIXPROC __glewFlushRasterSGIX = NULL; + +PFNGLTEXTUREFOGSGIXPROC __glewTextureFogSGIX = NULL; + +PFNGLFRAGMENTCOLORMATERIALSGIXPROC __glewFragmentColorMaterialSGIX = NULL; +PFNGLFRAGMENTLIGHTMODELFSGIXPROC __glewFragmentLightModelfSGIX = NULL; +PFNGLFRAGMENTLIGHTMODELFVSGIXPROC __glewFragmentLightModelfvSGIX = NULL; +PFNGLFRAGMENTLIGHTMODELISGIXPROC __glewFragmentLightModeliSGIX = NULL; +PFNGLFRAGMENTLIGHTMODELIVSGIXPROC __glewFragmentLightModelivSGIX = NULL; +PFNGLFRAGMENTLIGHTFSGIXPROC __glewFragmentLightfSGIX = NULL; +PFNGLFRAGMENTLIGHTFVSGIXPROC __glewFragmentLightfvSGIX = NULL; +PFNGLFRAGMENTLIGHTISGIXPROC __glewFragmentLightiSGIX = NULL; +PFNGLFRAGMENTLIGHTIVSGIXPROC __glewFragmentLightivSGIX = NULL; +PFNGLFRAGMENTMATERIALFSGIXPROC __glewFragmentMaterialfSGIX = NULL; +PFNGLFRAGMENTMATERIALFVSGIXPROC __glewFragmentMaterialfvSGIX = NULL; +PFNGLFRAGMENTMATERIALISGIXPROC __glewFragmentMaterialiSGIX = NULL; +PFNGLFRAGMENTMATERIALIVSGIXPROC __glewFragmentMaterialivSGIX = NULL; +PFNGLGETFRAGMENTLIGHTFVSGIXPROC __glewGetFragmentLightfvSGIX = NULL; +PFNGLGETFRAGMENTLIGHTIVSGIXPROC __glewGetFragmentLightivSGIX = NULL; +PFNGLGETFRAGMENTMATERIALFVSGIXPROC __glewGetFragmentMaterialfvSGIX = NULL; +PFNGLGETFRAGMENTMATERIALIVSGIXPROC __glewGetFragmentMaterialivSGIX = NULL; + +PFNGLFRAMEZOOMSGIXPROC __glewFrameZoomSGIX = NULL; + +PFNGLPIXELTEXGENSGIXPROC __glewPixelTexGenSGIX = NULL; + +PFNGLREFERENCEPLANESGIXPROC __glewReferencePlaneSGIX = NULL; + +PFNGLSPRITEPARAMETERFSGIXPROC __glewSpriteParameterfSGIX = NULL; +PFNGLSPRITEPARAMETERFVSGIXPROC __glewSpriteParameterfvSGIX = NULL; +PFNGLSPRITEPARAMETERISGIXPROC __glewSpriteParameteriSGIX = NULL; +PFNGLSPRITEPARAMETERIVSGIXPROC __glewSpriteParameterivSGIX = NULL; + +PFNGLTAGSAMPLEBUFFERSGIXPROC __glewTagSampleBufferSGIX = NULL; + +PFNGLCOLORTABLEPARAMETERFVSGIPROC __glewColorTableParameterfvSGI = NULL; +PFNGLCOLORTABLEPARAMETERIVSGIPROC __glewColorTableParameterivSGI = NULL; +PFNGLCOLORTABLESGIPROC __glewColorTableSGI = NULL; +PFNGLCOPYCOLORTABLESGIPROC __glewCopyColorTableSGI = NULL; +PFNGLGETCOLORTABLEPARAMETERFVSGIPROC __glewGetColorTableParameterfvSGI = NULL; +PFNGLGETCOLORTABLEPARAMETERIVSGIPROC __glewGetColorTableParameterivSGI = NULL; +PFNGLGETCOLORTABLESGIPROC __glewGetColorTableSGI = NULL; + +PFNGLFINISHTEXTURESUNXPROC __glewFinishTextureSUNX = NULL; + +PFNGLGLOBALALPHAFACTORBSUNPROC __glewGlobalAlphaFactorbSUN = NULL; +PFNGLGLOBALALPHAFACTORDSUNPROC __glewGlobalAlphaFactordSUN = NULL; +PFNGLGLOBALALPHAFACTORFSUNPROC __glewGlobalAlphaFactorfSUN = NULL; +PFNGLGLOBALALPHAFACTORISUNPROC __glewGlobalAlphaFactoriSUN = NULL; +PFNGLGLOBALALPHAFACTORSSUNPROC __glewGlobalAlphaFactorsSUN = NULL; +PFNGLGLOBALALPHAFACTORUBSUNPROC __glewGlobalAlphaFactorubSUN = NULL; +PFNGLGLOBALALPHAFACTORUISUNPROC __glewGlobalAlphaFactoruiSUN = NULL; +PFNGLGLOBALALPHAFACTORUSSUNPROC __glewGlobalAlphaFactorusSUN = NULL; + +PFNGLREADVIDEOPIXELSSUNPROC __glewReadVideoPixelsSUN = NULL; + +PFNGLREPLACEMENTCODEPOINTERSUNPROC __glewReplacementCodePointerSUN = NULL; +PFNGLREPLACEMENTCODEUBSUNPROC __glewReplacementCodeubSUN = NULL; +PFNGLREPLACEMENTCODEUBVSUNPROC __glewReplacementCodeubvSUN = NULL; +PFNGLREPLACEMENTCODEUISUNPROC __glewReplacementCodeuiSUN = NULL; +PFNGLREPLACEMENTCODEUIVSUNPROC __glewReplacementCodeuivSUN = NULL; +PFNGLREPLACEMENTCODEUSSUNPROC __glewReplacementCodeusSUN = NULL; +PFNGLREPLACEMENTCODEUSVSUNPROC __glewReplacementCodeusvSUN = NULL; + +PFNGLCOLOR3FVERTEX3FSUNPROC __glewColor3fVertex3fSUN = NULL; +PFNGLCOLOR3FVERTEX3FVSUNPROC __glewColor3fVertex3fvSUN = NULL; +PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC __glewColor4fNormal3fVertex3fSUN = NULL; +PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewColor4fNormal3fVertex3fvSUN = NULL; +PFNGLCOLOR4UBVERTEX2FSUNPROC __glewColor4ubVertex2fSUN = NULL; +PFNGLCOLOR4UBVERTEX2FVSUNPROC __glewColor4ubVertex2fvSUN = NULL; +PFNGLCOLOR4UBVERTEX3FSUNPROC __glewColor4ubVertex3fSUN = NULL; +PFNGLCOLOR4UBVERTEX3FVSUNPROC __glewColor4ubVertex3fvSUN = NULL; +PFNGLNORMAL3FVERTEX3FSUNPROC __glewNormal3fVertex3fSUN = NULL; +PFNGLNORMAL3FVERTEX3FVSUNPROC __glewNormal3fVertex3fvSUN = NULL; +PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC __glewReplacementCodeuiColor3fVertex3fSUN = NULL; +PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC __glewReplacementCodeuiColor3fVertex3fvSUN = NULL; +PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiColor4fNormal3fVertex3fSUN = NULL; +PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiColor4fNormal3fVertex3fvSUN = NULL; +PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC __glewReplacementCodeuiColor4ubVertex3fSUN = NULL; +PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC __glewReplacementCodeuiColor4ubVertex3fvSUN = NULL; +PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiNormal3fVertex3fSUN = NULL; +PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiNormal3fVertex3fvSUN = NULL; +PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN = NULL; +PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN = NULL; +PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiTexCoord2fNormal3fVertex3fSUN = NULL; +PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN = NULL; +PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC __glewReplacementCodeuiTexCoord2fVertex3fSUN = NULL; +PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC __glewReplacementCodeuiTexCoord2fVertex3fvSUN = NULL; +PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC __glewReplacementCodeuiVertex3fSUN = NULL; +PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC __glewReplacementCodeuiVertex3fvSUN = NULL; +PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC __glewTexCoord2fColor3fVertex3fSUN = NULL; +PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC __glewTexCoord2fColor3fVertex3fvSUN = NULL; +PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC __glewTexCoord2fColor4fNormal3fVertex3fSUN = NULL; +PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewTexCoord2fColor4fNormal3fVertex3fvSUN = NULL; +PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC __glewTexCoord2fColor4ubVertex3fSUN = NULL; +PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC __glewTexCoord2fColor4ubVertex3fvSUN = NULL; +PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC __glewTexCoord2fNormal3fVertex3fSUN = NULL; +PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC __glewTexCoord2fNormal3fVertex3fvSUN = NULL; +PFNGLTEXCOORD2FVERTEX3FSUNPROC __glewTexCoord2fVertex3fSUN = NULL; +PFNGLTEXCOORD2FVERTEX3FVSUNPROC __glewTexCoord2fVertex3fvSUN = NULL; +PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC __glewTexCoord4fColor4fNormal3fVertex4fSUN = NULL; +PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC __glewTexCoord4fColor4fNormal3fVertex4fvSUN = NULL; +PFNGLTEXCOORD4FVERTEX4FSUNPROC __glewTexCoord4fVertex4fSUN = NULL; +PFNGLTEXCOORD4FVERTEX4FVSUNPROC __glewTexCoord4fVertex4fvSUN = NULL; + +PFNGLADDSWAPHINTRECTWINPROC __glewAddSwapHintRectWIN = NULL; + +#endif /* !WIN32 || !GLEW_MX */ + +#if !defined(GLEW_MX) + +GLboolean __GLEW_VERSION_1_1 = GL_FALSE; +GLboolean __GLEW_VERSION_1_2 = GL_FALSE; +GLboolean __GLEW_VERSION_1_3 = GL_FALSE; +GLboolean __GLEW_VERSION_1_4 = GL_FALSE; +GLboolean __GLEW_VERSION_1_5 = GL_FALSE; +GLboolean __GLEW_VERSION_2_0 = GL_FALSE; +GLboolean __GLEW_VERSION_2_1 = GL_FALSE; +GLboolean __GLEW_VERSION_3_0 = GL_FALSE; +GLboolean __GLEW_3DFX_multisample = GL_FALSE; +GLboolean __GLEW_3DFX_tbuffer = GL_FALSE; +GLboolean __GLEW_3DFX_texture_compression_FXT1 = GL_FALSE; +GLboolean __GLEW_APPLE_client_storage = GL_FALSE; +GLboolean __GLEW_APPLE_element_array = GL_FALSE; +GLboolean __GLEW_APPLE_fence = GL_FALSE; +GLboolean __GLEW_APPLE_float_pixels = GL_FALSE; +GLboolean __GLEW_APPLE_flush_buffer_range = GL_FALSE; +GLboolean __GLEW_APPLE_pixel_buffer = GL_FALSE; +GLboolean __GLEW_APPLE_specular_vector = GL_FALSE; +GLboolean __GLEW_APPLE_texture_range = GL_FALSE; +GLboolean __GLEW_APPLE_transform_hint = GL_FALSE; +GLboolean __GLEW_APPLE_vertex_array_object = GL_FALSE; +GLboolean __GLEW_APPLE_vertex_array_range = GL_FALSE; +GLboolean __GLEW_APPLE_ycbcr_422 = GL_FALSE; +GLboolean __GLEW_ARB_color_buffer_float = GL_FALSE; +GLboolean __GLEW_ARB_depth_buffer_float = GL_FALSE; +GLboolean __GLEW_ARB_depth_texture = GL_FALSE; +GLboolean __GLEW_ARB_draw_buffers = GL_FALSE; +GLboolean __GLEW_ARB_draw_instanced = GL_FALSE; +GLboolean __GLEW_ARB_fragment_program = GL_FALSE; +GLboolean __GLEW_ARB_fragment_program_shadow = GL_FALSE; +GLboolean __GLEW_ARB_fragment_shader = GL_FALSE; +GLboolean __GLEW_ARB_framebuffer_object = GL_FALSE; +GLboolean __GLEW_ARB_framebuffer_sRGB = GL_FALSE; +GLboolean __GLEW_ARB_geometry_shader4 = GL_FALSE; +GLboolean __GLEW_ARB_half_float_pixel = GL_FALSE; +GLboolean __GLEW_ARB_half_float_vertex = GL_FALSE; +GLboolean __GLEW_ARB_imaging = GL_FALSE; +GLboolean __GLEW_ARB_instanced_arrays = GL_FALSE; +GLboolean __GLEW_ARB_map_buffer_range = GL_FALSE; +GLboolean __GLEW_ARB_matrix_palette = GL_FALSE; +GLboolean __GLEW_ARB_multisample = GL_FALSE; +GLboolean __GLEW_ARB_multitexture = GL_FALSE; +GLboolean __GLEW_ARB_occlusion_query = GL_FALSE; +GLboolean __GLEW_ARB_pixel_buffer_object = GL_FALSE; +GLboolean __GLEW_ARB_point_parameters = GL_FALSE; +GLboolean __GLEW_ARB_point_sprite = GL_FALSE; +GLboolean __GLEW_ARB_shader_objects = GL_FALSE; +GLboolean __GLEW_ARB_shading_language_100 = GL_FALSE; +GLboolean __GLEW_ARB_shadow = GL_FALSE; +GLboolean __GLEW_ARB_shadow_ambient = GL_FALSE; +GLboolean __GLEW_ARB_texture_border_clamp = GL_FALSE; +GLboolean __GLEW_ARB_texture_buffer_object = GL_FALSE; +GLboolean __GLEW_ARB_texture_compression = GL_FALSE; +GLboolean __GLEW_ARB_texture_compression_rgtc = GL_FALSE; +GLboolean __GLEW_ARB_texture_cube_map = GL_FALSE; +GLboolean __GLEW_ARB_texture_env_add = GL_FALSE; +GLboolean __GLEW_ARB_texture_env_combine = GL_FALSE; +GLboolean __GLEW_ARB_texture_env_crossbar = GL_FALSE; +GLboolean __GLEW_ARB_texture_env_dot3 = GL_FALSE; +GLboolean __GLEW_ARB_texture_float = GL_FALSE; +GLboolean __GLEW_ARB_texture_mirrored_repeat = GL_FALSE; +GLboolean __GLEW_ARB_texture_non_power_of_two = GL_FALSE; +GLboolean __GLEW_ARB_texture_rectangle = GL_FALSE; +GLboolean __GLEW_ARB_texture_rg = GL_FALSE; +GLboolean __GLEW_ARB_transpose_matrix = GL_FALSE; +GLboolean __GLEW_ARB_vertex_array_object = GL_FALSE; +GLboolean __GLEW_ARB_vertex_blend = GL_FALSE; +GLboolean __GLEW_ARB_vertex_buffer_object = GL_FALSE; +GLboolean __GLEW_ARB_vertex_program = GL_FALSE; +GLboolean __GLEW_ARB_vertex_shader = GL_FALSE; +GLboolean __GLEW_ARB_window_pos = GL_FALSE; +GLboolean __GLEW_ATIX_point_sprites = GL_FALSE; +GLboolean __GLEW_ATIX_texture_env_combine3 = GL_FALSE; +GLboolean __GLEW_ATIX_texture_env_route = GL_FALSE; +GLboolean __GLEW_ATIX_vertex_shader_output_point_size = GL_FALSE; +GLboolean __GLEW_ATI_draw_buffers = GL_FALSE; +GLboolean __GLEW_ATI_element_array = GL_FALSE; +GLboolean __GLEW_ATI_envmap_bumpmap = GL_FALSE; +GLboolean __GLEW_ATI_fragment_shader = GL_FALSE; +GLboolean __GLEW_ATI_map_object_buffer = GL_FALSE; +GLboolean __GLEW_ATI_pn_triangles = GL_FALSE; +GLboolean __GLEW_ATI_separate_stencil = GL_FALSE; +GLboolean __GLEW_ATI_shader_texture_lod = GL_FALSE; +GLboolean __GLEW_ATI_text_fragment_shader = GL_FALSE; +GLboolean __GLEW_ATI_texture_compression_3dc = GL_FALSE; +GLboolean __GLEW_ATI_texture_env_combine3 = GL_FALSE; +GLboolean __GLEW_ATI_texture_float = GL_FALSE; +GLboolean __GLEW_ATI_texture_mirror_once = GL_FALSE; +GLboolean __GLEW_ATI_vertex_array_object = GL_FALSE; +GLboolean __GLEW_ATI_vertex_attrib_array_object = GL_FALSE; +GLboolean __GLEW_ATI_vertex_streams = GL_FALSE; +GLboolean __GLEW_EXT_422_pixels = GL_FALSE; +GLboolean __GLEW_EXT_Cg_shader = GL_FALSE; +GLboolean __GLEW_EXT_abgr = GL_FALSE; +GLboolean __GLEW_EXT_bgra = GL_FALSE; +GLboolean __GLEW_EXT_bindable_uniform = GL_FALSE; +GLboolean __GLEW_EXT_blend_color = GL_FALSE; +GLboolean __GLEW_EXT_blend_equation_separate = GL_FALSE; +GLboolean __GLEW_EXT_blend_func_separate = GL_FALSE; +GLboolean __GLEW_EXT_blend_logic_op = GL_FALSE; +GLboolean __GLEW_EXT_blend_minmax = GL_FALSE; +GLboolean __GLEW_EXT_blend_subtract = GL_FALSE; +GLboolean __GLEW_EXT_clip_volume_hint = GL_FALSE; +GLboolean __GLEW_EXT_cmyka = GL_FALSE; +GLboolean __GLEW_EXT_color_subtable = GL_FALSE; +GLboolean __GLEW_EXT_compiled_vertex_array = GL_FALSE; +GLboolean __GLEW_EXT_convolution = GL_FALSE; +GLboolean __GLEW_EXT_coordinate_frame = GL_FALSE; +GLboolean __GLEW_EXT_copy_texture = GL_FALSE; +GLboolean __GLEW_EXT_cull_vertex = GL_FALSE; +GLboolean __GLEW_EXT_depth_bounds_test = GL_FALSE; +GLboolean __GLEW_EXT_direct_state_access = GL_FALSE; +GLboolean __GLEW_EXT_draw_buffers2 = GL_FALSE; +GLboolean __GLEW_EXT_draw_instanced = GL_FALSE; +GLboolean __GLEW_EXT_draw_range_elements = GL_FALSE; +GLboolean __GLEW_EXT_fog_coord = GL_FALSE; +GLboolean __GLEW_EXT_fragment_lighting = GL_FALSE; +GLboolean __GLEW_EXT_framebuffer_blit = GL_FALSE; +GLboolean __GLEW_EXT_framebuffer_multisample = GL_FALSE; +GLboolean __GLEW_EXT_framebuffer_object = GL_FALSE; +GLboolean __GLEW_EXT_framebuffer_sRGB = GL_FALSE; +GLboolean __GLEW_EXT_geometry_shader4 = GL_FALSE; +GLboolean __GLEW_EXT_gpu_program_parameters = GL_FALSE; +GLboolean __GLEW_EXT_gpu_shader4 = GL_FALSE; +GLboolean __GLEW_EXT_histogram = GL_FALSE; +GLboolean __GLEW_EXT_index_array_formats = GL_FALSE; +GLboolean __GLEW_EXT_index_func = GL_FALSE; +GLboolean __GLEW_EXT_index_material = GL_FALSE; +GLboolean __GLEW_EXT_index_texture = GL_FALSE; +GLboolean __GLEW_EXT_light_texture = GL_FALSE; +GLboolean __GLEW_EXT_misc_attribute = GL_FALSE; +GLboolean __GLEW_EXT_multi_draw_arrays = GL_FALSE; +GLboolean __GLEW_EXT_multisample = GL_FALSE; +GLboolean __GLEW_EXT_packed_depth_stencil = GL_FALSE; +GLboolean __GLEW_EXT_packed_float = GL_FALSE; +GLboolean __GLEW_EXT_packed_pixels = GL_FALSE; +GLboolean __GLEW_EXT_paletted_texture = GL_FALSE; +GLboolean __GLEW_EXT_pixel_buffer_object = GL_FALSE; +GLboolean __GLEW_EXT_pixel_transform = GL_FALSE; +GLboolean __GLEW_EXT_pixel_transform_color_table = GL_FALSE; +GLboolean __GLEW_EXT_point_parameters = GL_FALSE; +GLboolean __GLEW_EXT_polygon_offset = GL_FALSE; +GLboolean __GLEW_EXT_rescale_normal = GL_FALSE; +GLboolean __GLEW_EXT_scene_marker = GL_FALSE; +GLboolean __GLEW_EXT_secondary_color = GL_FALSE; +GLboolean __GLEW_EXT_separate_specular_color = GL_FALSE; +GLboolean __GLEW_EXT_shadow_funcs = GL_FALSE; +GLboolean __GLEW_EXT_shared_texture_palette = GL_FALSE; +GLboolean __GLEW_EXT_stencil_clear_tag = GL_FALSE; +GLboolean __GLEW_EXT_stencil_two_side = GL_FALSE; +GLboolean __GLEW_EXT_stencil_wrap = GL_FALSE; +GLboolean __GLEW_EXT_subtexture = GL_FALSE; +GLboolean __GLEW_EXT_texture = GL_FALSE; +GLboolean __GLEW_EXT_texture3D = GL_FALSE; +GLboolean __GLEW_EXT_texture_array = GL_FALSE; +GLboolean __GLEW_EXT_texture_buffer_object = GL_FALSE; +GLboolean __GLEW_EXT_texture_compression_dxt1 = GL_FALSE; +GLboolean __GLEW_EXT_texture_compression_latc = GL_FALSE; +GLboolean __GLEW_EXT_texture_compression_rgtc = GL_FALSE; +GLboolean __GLEW_EXT_texture_compression_s3tc = GL_FALSE; +GLboolean __GLEW_EXT_texture_cube_map = GL_FALSE; +GLboolean __GLEW_EXT_texture_edge_clamp = GL_FALSE; +GLboolean __GLEW_EXT_texture_env = GL_FALSE; +GLboolean __GLEW_EXT_texture_env_add = GL_FALSE; +GLboolean __GLEW_EXT_texture_env_combine = GL_FALSE; +GLboolean __GLEW_EXT_texture_env_dot3 = GL_FALSE; +GLboolean __GLEW_EXT_texture_filter_anisotropic = GL_FALSE; +GLboolean __GLEW_EXT_texture_integer = GL_FALSE; +GLboolean __GLEW_EXT_texture_lod_bias = GL_FALSE; +GLboolean __GLEW_EXT_texture_mirror_clamp = GL_FALSE; +GLboolean __GLEW_EXT_texture_object = GL_FALSE; +GLboolean __GLEW_EXT_texture_perturb_normal = GL_FALSE; +GLboolean __GLEW_EXT_texture_rectangle = GL_FALSE; +GLboolean __GLEW_EXT_texture_sRGB = GL_FALSE; +GLboolean __GLEW_EXT_texture_shared_exponent = GL_FALSE; +GLboolean __GLEW_EXT_texture_swizzle = GL_FALSE; +GLboolean __GLEW_EXT_timer_query = GL_FALSE; +GLboolean __GLEW_EXT_transform_feedback = GL_FALSE; +GLboolean __GLEW_EXT_vertex_array = GL_FALSE; +GLboolean __GLEW_EXT_vertex_array_bgra = GL_FALSE; +GLboolean __GLEW_EXT_vertex_shader = GL_FALSE; +GLboolean __GLEW_EXT_vertex_weighting = GL_FALSE; +GLboolean __GLEW_GREMEDY_frame_terminator = GL_FALSE; +GLboolean __GLEW_GREMEDY_string_marker = GL_FALSE; +GLboolean __GLEW_HP_convolution_border_modes = GL_FALSE; +GLboolean __GLEW_HP_image_transform = GL_FALSE; +GLboolean __GLEW_HP_occlusion_test = GL_FALSE; +GLboolean __GLEW_HP_texture_lighting = GL_FALSE; +GLboolean __GLEW_IBM_cull_vertex = GL_FALSE; +GLboolean __GLEW_IBM_multimode_draw_arrays = GL_FALSE; +GLboolean __GLEW_IBM_rasterpos_clip = GL_FALSE; +GLboolean __GLEW_IBM_static_data = GL_FALSE; +GLboolean __GLEW_IBM_texture_mirrored_repeat = GL_FALSE; +GLboolean __GLEW_IBM_vertex_array_lists = GL_FALSE; +GLboolean __GLEW_INGR_color_clamp = GL_FALSE; +GLboolean __GLEW_INGR_interlace_read = GL_FALSE; +GLboolean __GLEW_INTEL_parallel_arrays = GL_FALSE; +GLboolean __GLEW_INTEL_texture_scissor = GL_FALSE; +GLboolean __GLEW_KTX_buffer_region = GL_FALSE; +GLboolean __GLEW_MESAX_texture_stack = GL_FALSE; +GLboolean __GLEW_MESA_pack_invert = GL_FALSE; +GLboolean __GLEW_MESA_resize_buffers = GL_FALSE; +GLboolean __GLEW_MESA_window_pos = GL_FALSE; +GLboolean __GLEW_MESA_ycbcr_texture = GL_FALSE; +GLboolean __GLEW_NV_blend_square = GL_FALSE; +GLboolean __GLEW_NV_conditional_render = GL_FALSE; +GLboolean __GLEW_NV_copy_depth_to_color = GL_FALSE; +GLboolean __GLEW_NV_depth_buffer_float = GL_FALSE; +GLboolean __GLEW_NV_depth_clamp = GL_FALSE; +GLboolean __GLEW_NV_depth_range_unclamped = GL_FALSE; +GLboolean __GLEW_NV_evaluators = GL_FALSE; +GLboolean __GLEW_NV_explicit_multisample = GL_FALSE; +GLboolean __GLEW_NV_fence = GL_FALSE; +GLboolean __GLEW_NV_float_buffer = GL_FALSE; +GLboolean __GLEW_NV_fog_distance = GL_FALSE; +GLboolean __GLEW_NV_fragment_program = GL_FALSE; +GLboolean __GLEW_NV_fragment_program2 = GL_FALSE; +GLboolean __GLEW_NV_fragment_program4 = GL_FALSE; +GLboolean __GLEW_NV_fragment_program_option = GL_FALSE; +GLboolean __GLEW_NV_framebuffer_multisample_coverage = GL_FALSE; +GLboolean __GLEW_NV_geometry_program4 = GL_FALSE; +GLboolean __GLEW_NV_geometry_shader4 = GL_FALSE; +GLboolean __GLEW_NV_gpu_program4 = GL_FALSE; +GLboolean __GLEW_NV_half_float = GL_FALSE; +GLboolean __GLEW_NV_light_max_exponent = GL_FALSE; +GLboolean __GLEW_NV_multisample_filter_hint = GL_FALSE; +GLboolean __GLEW_NV_occlusion_query = GL_FALSE; +GLboolean __GLEW_NV_packed_depth_stencil = GL_FALSE; +GLboolean __GLEW_NV_parameter_buffer_object = GL_FALSE; +GLboolean __GLEW_NV_pixel_data_range = GL_FALSE; +GLboolean __GLEW_NV_point_sprite = GL_FALSE; +GLboolean __GLEW_NV_present_video = GL_FALSE; +GLboolean __GLEW_NV_primitive_restart = GL_FALSE; +GLboolean __GLEW_NV_register_combiners = GL_FALSE; +GLboolean __GLEW_NV_register_combiners2 = GL_FALSE; +GLboolean __GLEW_NV_texgen_emboss = GL_FALSE; +GLboolean __GLEW_NV_texgen_reflection = GL_FALSE; +GLboolean __GLEW_NV_texture_compression_vtc = GL_FALSE; +GLboolean __GLEW_NV_texture_env_combine4 = GL_FALSE; +GLboolean __GLEW_NV_texture_expand_normal = GL_FALSE; +GLboolean __GLEW_NV_texture_rectangle = GL_FALSE; +GLboolean __GLEW_NV_texture_shader = GL_FALSE; +GLboolean __GLEW_NV_texture_shader2 = GL_FALSE; +GLboolean __GLEW_NV_texture_shader3 = GL_FALSE; +GLboolean __GLEW_NV_transform_feedback = GL_FALSE; +GLboolean __GLEW_NV_vertex_array_range = GL_FALSE; +GLboolean __GLEW_NV_vertex_array_range2 = GL_FALSE; +GLboolean __GLEW_NV_vertex_program = GL_FALSE; +GLboolean __GLEW_NV_vertex_program1_1 = GL_FALSE; +GLboolean __GLEW_NV_vertex_program2 = GL_FALSE; +GLboolean __GLEW_NV_vertex_program2_option = GL_FALSE; +GLboolean __GLEW_NV_vertex_program3 = GL_FALSE; +GLboolean __GLEW_NV_vertex_program4 = GL_FALSE; +GLboolean __GLEW_OES_byte_coordinates = GL_FALSE; +GLboolean __GLEW_OES_compressed_paletted_texture = GL_FALSE; +GLboolean __GLEW_OES_read_format = GL_FALSE; +GLboolean __GLEW_OES_single_precision = GL_FALSE; +GLboolean __GLEW_OML_interlace = GL_FALSE; +GLboolean __GLEW_OML_resample = GL_FALSE; +GLboolean __GLEW_OML_subsample = GL_FALSE; +GLboolean __GLEW_PGI_misc_hints = GL_FALSE; +GLboolean __GLEW_PGI_vertex_hints = GL_FALSE; +GLboolean __GLEW_REND_screen_coordinates = GL_FALSE; +GLboolean __GLEW_S3_s3tc = GL_FALSE; +GLboolean __GLEW_SGIS_color_range = GL_FALSE; +GLboolean __GLEW_SGIS_detail_texture = GL_FALSE; +GLboolean __GLEW_SGIS_fog_function = GL_FALSE; +GLboolean __GLEW_SGIS_generate_mipmap = GL_FALSE; +GLboolean __GLEW_SGIS_multisample = GL_FALSE; +GLboolean __GLEW_SGIS_pixel_texture = GL_FALSE; +GLboolean __GLEW_SGIS_point_line_texgen = GL_FALSE; +GLboolean __GLEW_SGIS_sharpen_texture = GL_FALSE; +GLboolean __GLEW_SGIS_texture4D = GL_FALSE; +GLboolean __GLEW_SGIS_texture_border_clamp = GL_FALSE; +GLboolean __GLEW_SGIS_texture_edge_clamp = GL_FALSE; +GLboolean __GLEW_SGIS_texture_filter4 = GL_FALSE; +GLboolean __GLEW_SGIS_texture_lod = GL_FALSE; +GLboolean __GLEW_SGIS_texture_select = GL_FALSE; +GLboolean __GLEW_SGIX_async = GL_FALSE; +GLboolean __GLEW_SGIX_async_histogram = GL_FALSE; +GLboolean __GLEW_SGIX_async_pixel = GL_FALSE; +GLboolean __GLEW_SGIX_blend_alpha_minmax = GL_FALSE; +GLboolean __GLEW_SGIX_clipmap = GL_FALSE; +GLboolean __GLEW_SGIX_convolution_accuracy = GL_FALSE; +GLboolean __GLEW_SGIX_depth_texture = GL_FALSE; +GLboolean __GLEW_SGIX_flush_raster = GL_FALSE; +GLboolean __GLEW_SGIX_fog_offset = GL_FALSE; +GLboolean __GLEW_SGIX_fog_texture = GL_FALSE; +GLboolean __GLEW_SGIX_fragment_specular_lighting = GL_FALSE; +GLboolean __GLEW_SGIX_framezoom = GL_FALSE; +GLboolean __GLEW_SGIX_interlace = GL_FALSE; +GLboolean __GLEW_SGIX_ir_instrument1 = GL_FALSE; +GLboolean __GLEW_SGIX_list_priority = GL_FALSE; +GLboolean __GLEW_SGIX_pixel_texture = GL_FALSE; +GLboolean __GLEW_SGIX_pixel_texture_bits = GL_FALSE; +GLboolean __GLEW_SGIX_reference_plane = GL_FALSE; +GLboolean __GLEW_SGIX_resample = GL_FALSE; +GLboolean __GLEW_SGIX_shadow = GL_FALSE; +GLboolean __GLEW_SGIX_shadow_ambient = GL_FALSE; +GLboolean __GLEW_SGIX_sprite = GL_FALSE; +GLboolean __GLEW_SGIX_tag_sample_buffer = GL_FALSE; +GLboolean __GLEW_SGIX_texture_add_env = GL_FALSE; +GLboolean __GLEW_SGIX_texture_coordinate_clamp = GL_FALSE; +GLboolean __GLEW_SGIX_texture_lod_bias = GL_FALSE; +GLboolean __GLEW_SGIX_texture_multi_buffer = GL_FALSE; +GLboolean __GLEW_SGIX_texture_range = GL_FALSE; +GLboolean __GLEW_SGIX_texture_scale_bias = GL_FALSE; +GLboolean __GLEW_SGIX_vertex_preclip = GL_FALSE; +GLboolean __GLEW_SGIX_vertex_preclip_hint = GL_FALSE; +GLboolean __GLEW_SGIX_ycrcb = GL_FALSE; +GLboolean __GLEW_SGI_color_matrix = GL_FALSE; +GLboolean __GLEW_SGI_color_table = GL_FALSE; +GLboolean __GLEW_SGI_texture_color_table = GL_FALSE; +GLboolean __GLEW_SUNX_constant_data = GL_FALSE; +GLboolean __GLEW_SUN_convolution_border_modes = GL_FALSE; +GLboolean __GLEW_SUN_global_alpha = GL_FALSE; +GLboolean __GLEW_SUN_mesh_array = GL_FALSE; +GLboolean __GLEW_SUN_read_video_pixels = GL_FALSE; +GLboolean __GLEW_SUN_slice_accum = GL_FALSE; +GLboolean __GLEW_SUN_triangle_list = GL_FALSE; +GLboolean __GLEW_SUN_vertex = GL_FALSE; +GLboolean __GLEW_WIN_phong_shading = GL_FALSE; +GLboolean __GLEW_WIN_specular_fog = GL_FALSE; +GLboolean __GLEW_WIN_swap_hint = GL_FALSE; + +#endif /* !GLEW_MX */ + +#ifdef GL_VERSION_1_2 + +static GLboolean _glewInit_GL_VERSION_1_2 (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glCopyTexSubImage3D = (PFNGLCOPYTEXSUBIMAGE3DPROC)glewGetProcAddress((const GLubyte*)"glCopyTexSubImage3D")) == NULL) || r; + r = ((glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)glewGetProcAddress((const GLubyte*)"glDrawRangeElements")) == NULL) || r; + r = ((glTexImage3D = (PFNGLTEXIMAGE3DPROC)glewGetProcAddress((const GLubyte*)"glTexImage3D")) == NULL) || r; + r = ((glTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC)glewGetProcAddress((const GLubyte*)"glTexSubImage3D")) == NULL) || r; + + return r; +} + +#endif /* GL_VERSION_1_2 */ + +#ifdef GL_VERSION_1_3 + +static GLboolean _glewInit_GL_VERSION_1_3 (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glActiveTexture = (PFNGLACTIVETEXTUREPROC)glewGetProcAddress((const GLubyte*)"glActiveTexture")) == NULL) || r; + r = ((glClientActiveTexture = (PFNGLCLIENTACTIVETEXTUREPROC)glewGetProcAddress((const GLubyte*)"glClientActiveTexture")) == NULL) || r; + r = ((glCompressedTexImage1D = (PFNGLCOMPRESSEDTEXIMAGE1DPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexImage1D")) == NULL) || r; + r = ((glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexImage2D")) == NULL) || r; + r = ((glCompressedTexImage3D = (PFNGLCOMPRESSEDTEXIMAGE3DPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexImage3D")) == NULL) || r; + r = ((glCompressedTexSubImage1D = (PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexSubImage1D")) == NULL) || r; + r = ((glCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexSubImage2D")) == NULL) || r; + r = ((glCompressedTexSubImage3D = (PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexSubImage3D")) == NULL) || r; + r = ((glGetCompressedTexImage = (PFNGLGETCOMPRESSEDTEXIMAGEPROC)glewGetProcAddress((const GLubyte*)"glGetCompressedTexImage")) == NULL) || r; + r = ((glLoadTransposeMatrixd = (PFNGLLOADTRANSPOSEMATRIXDPROC)glewGetProcAddress((const GLubyte*)"glLoadTransposeMatrixd")) == NULL) || r; + r = ((glLoadTransposeMatrixf = (PFNGLLOADTRANSPOSEMATRIXFPROC)glewGetProcAddress((const GLubyte*)"glLoadTransposeMatrixf")) == NULL) || r; + r = ((glMultTransposeMatrixd = (PFNGLMULTTRANSPOSEMATRIXDPROC)glewGetProcAddress((const GLubyte*)"glMultTransposeMatrixd")) == NULL) || r; + r = ((glMultTransposeMatrixf = (PFNGLMULTTRANSPOSEMATRIXFPROC)glewGetProcAddress((const GLubyte*)"glMultTransposeMatrixf")) == NULL) || r; + r = ((glMultiTexCoord1d = (PFNGLMULTITEXCOORD1DPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1d")) == NULL) || r; + r = ((glMultiTexCoord1dv = (PFNGLMULTITEXCOORD1DVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1dv")) == NULL) || r; + r = ((glMultiTexCoord1f = (PFNGLMULTITEXCOORD1FPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1f")) == NULL) || r; + r = ((glMultiTexCoord1fv = (PFNGLMULTITEXCOORD1FVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1fv")) == NULL) || r; + r = ((glMultiTexCoord1i = (PFNGLMULTITEXCOORD1IPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1i")) == NULL) || r; + r = ((glMultiTexCoord1iv = (PFNGLMULTITEXCOORD1IVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1iv")) == NULL) || r; + r = ((glMultiTexCoord1s = (PFNGLMULTITEXCOORD1SPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1s")) == NULL) || r; + r = ((glMultiTexCoord1sv = (PFNGLMULTITEXCOORD1SVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1sv")) == NULL) || r; + r = ((glMultiTexCoord2d = (PFNGLMULTITEXCOORD2DPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2d")) == NULL) || r; + r = ((glMultiTexCoord2dv = (PFNGLMULTITEXCOORD2DVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2dv")) == NULL) || r; + r = ((glMultiTexCoord2f = (PFNGLMULTITEXCOORD2FPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2f")) == NULL) || r; + r = ((glMultiTexCoord2fv = (PFNGLMULTITEXCOORD2FVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2fv")) == NULL) || r; + r = ((glMultiTexCoord2i = (PFNGLMULTITEXCOORD2IPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2i")) == NULL) || r; + r = ((glMultiTexCoord2iv = (PFNGLMULTITEXCOORD2IVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2iv")) == NULL) || r; + r = ((glMultiTexCoord2s = (PFNGLMULTITEXCOORD2SPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2s")) == NULL) || r; + r = ((glMultiTexCoord2sv = (PFNGLMULTITEXCOORD2SVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2sv")) == NULL) || r; + r = ((glMultiTexCoord3d = (PFNGLMULTITEXCOORD3DPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3d")) == NULL) || r; + r = ((glMultiTexCoord3dv = (PFNGLMULTITEXCOORD3DVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3dv")) == NULL) || r; + r = ((glMultiTexCoord3f = (PFNGLMULTITEXCOORD3FPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3f")) == NULL) || r; + r = ((glMultiTexCoord3fv = (PFNGLMULTITEXCOORD3FVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3fv")) == NULL) || r; + r = ((glMultiTexCoord3i = (PFNGLMULTITEXCOORD3IPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3i")) == NULL) || r; + r = ((glMultiTexCoord3iv = (PFNGLMULTITEXCOORD3IVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3iv")) == NULL) || r; + r = ((glMultiTexCoord3s = (PFNGLMULTITEXCOORD3SPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3s")) == NULL) || r; + r = ((glMultiTexCoord3sv = (PFNGLMULTITEXCOORD3SVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3sv")) == NULL) || r; + r = ((glMultiTexCoord4d = (PFNGLMULTITEXCOORD4DPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4d")) == NULL) || r; + r = ((glMultiTexCoord4dv = (PFNGLMULTITEXCOORD4DVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4dv")) == NULL) || r; + r = ((glMultiTexCoord4f = (PFNGLMULTITEXCOORD4FPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4f")) == NULL) || r; + r = ((glMultiTexCoord4fv = (PFNGLMULTITEXCOORD4FVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4fv")) == NULL) || r; + r = ((glMultiTexCoord4i = (PFNGLMULTITEXCOORD4IPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4i")) == NULL) || r; + r = ((glMultiTexCoord4iv = (PFNGLMULTITEXCOORD4IVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4iv")) == NULL) || r; + r = ((glMultiTexCoord4s = (PFNGLMULTITEXCOORD4SPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4s")) == NULL) || r; + r = ((glMultiTexCoord4sv = (PFNGLMULTITEXCOORD4SVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4sv")) == NULL) || r; + r = ((glSampleCoverage = (PFNGLSAMPLECOVERAGEPROC)glewGetProcAddress((const GLubyte*)"glSampleCoverage")) == NULL) || r; + + return r; +} + +#endif /* GL_VERSION_1_3 */ + +#ifdef GL_VERSION_1_4 + +static GLboolean _glewInit_GL_VERSION_1_4 (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBlendColor = (PFNGLBLENDCOLORPROC)glewGetProcAddress((const GLubyte*)"glBlendColor")) == NULL) || r; + r = ((glBlendEquation = (PFNGLBLENDEQUATIONPROC)glewGetProcAddress((const GLubyte*)"glBlendEquation")) == NULL) || r; + r = ((glBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC)glewGetProcAddress((const GLubyte*)"glBlendFuncSeparate")) == NULL) || r; + r = ((glFogCoordPointer = (PFNGLFOGCOORDPOINTERPROC)glewGetProcAddress((const GLubyte*)"glFogCoordPointer")) == NULL) || r; + r = ((glFogCoordd = (PFNGLFOGCOORDDPROC)glewGetProcAddress((const GLubyte*)"glFogCoordd")) == NULL) || r; + r = ((glFogCoorddv = (PFNGLFOGCOORDDVPROC)glewGetProcAddress((const GLubyte*)"glFogCoorddv")) == NULL) || r; + r = ((glFogCoordf = (PFNGLFOGCOORDFPROC)glewGetProcAddress((const GLubyte*)"glFogCoordf")) == NULL) || r; + r = ((glFogCoordfv = (PFNGLFOGCOORDFVPROC)glewGetProcAddress((const GLubyte*)"glFogCoordfv")) == NULL) || r; + r = ((glMultiDrawArrays = (PFNGLMULTIDRAWARRAYSPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawArrays")) == NULL) || r; + r = ((glMultiDrawElements = (PFNGLMULTIDRAWELEMENTSPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawElements")) == NULL) || r; + r = ((glPointParameterf = (PFNGLPOINTPARAMETERFPROC)glewGetProcAddress((const GLubyte*)"glPointParameterf")) == NULL) || r; + r = ((glPointParameterfv = (PFNGLPOINTPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glPointParameterfv")) == NULL) || r; + r = ((glPointParameteri = (PFNGLPOINTPARAMETERIPROC)glewGetProcAddress((const GLubyte*)"glPointParameteri")) == NULL) || r; + r = ((glPointParameteriv = (PFNGLPOINTPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glPointParameteriv")) == NULL) || r; + r = ((glSecondaryColor3b = (PFNGLSECONDARYCOLOR3BPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3b")) == NULL) || r; + r = ((glSecondaryColor3bv = (PFNGLSECONDARYCOLOR3BVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3bv")) == NULL) || r; + r = ((glSecondaryColor3d = (PFNGLSECONDARYCOLOR3DPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3d")) == NULL) || r; + r = ((glSecondaryColor3dv = (PFNGLSECONDARYCOLOR3DVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3dv")) == NULL) || r; + r = ((glSecondaryColor3f = (PFNGLSECONDARYCOLOR3FPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3f")) == NULL) || r; + r = ((glSecondaryColor3fv = (PFNGLSECONDARYCOLOR3FVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3fv")) == NULL) || r; + r = ((glSecondaryColor3i = (PFNGLSECONDARYCOLOR3IPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3i")) == NULL) || r; + r = ((glSecondaryColor3iv = (PFNGLSECONDARYCOLOR3IVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3iv")) == NULL) || r; + r = ((glSecondaryColor3s = (PFNGLSECONDARYCOLOR3SPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3s")) == NULL) || r; + r = ((glSecondaryColor3sv = (PFNGLSECONDARYCOLOR3SVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3sv")) == NULL) || r; + r = ((glSecondaryColor3ub = (PFNGLSECONDARYCOLOR3UBPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3ub")) == NULL) || r; + r = ((glSecondaryColor3ubv = (PFNGLSECONDARYCOLOR3UBVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3ubv")) == NULL) || r; + r = ((glSecondaryColor3ui = (PFNGLSECONDARYCOLOR3UIPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3ui")) == NULL) || r; + r = ((glSecondaryColor3uiv = (PFNGLSECONDARYCOLOR3UIVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3uiv")) == NULL) || r; + r = ((glSecondaryColor3us = (PFNGLSECONDARYCOLOR3USPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3us")) == NULL) || r; + r = ((glSecondaryColor3usv = (PFNGLSECONDARYCOLOR3USVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3usv")) == NULL) || r; + r = ((glSecondaryColorPointer = (PFNGLSECONDARYCOLORPOINTERPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColorPointer")) == NULL) || r; + r = ((glWindowPos2d = (PFNGLWINDOWPOS2DPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2d")) == NULL) || r; + r = ((glWindowPos2dv = (PFNGLWINDOWPOS2DVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2dv")) == NULL) || r; + r = ((glWindowPos2f = (PFNGLWINDOWPOS2FPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2f")) == NULL) || r; + r = ((glWindowPos2fv = (PFNGLWINDOWPOS2FVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2fv")) == NULL) || r; + r = ((glWindowPos2i = (PFNGLWINDOWPOS2IPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2i")) == NULL) || r; + r = ((glWindowPos2iv = (PFNGLWINDOWPOS2IVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2iv")) == NULL) || r; + r = ((glWindowPos2s = (PFNGLWINDOWPOS2SPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2s")) == NULL) || r; + r = ((glWindowPos2sv = (PFNGLWINDOWPOS2SVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2sv")) == NULL) || r; + r = ((glWindowPos3d = (PFNGLWINDOWPOS3DPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3d")) == NULL) || r; + r = ((glWindowPos3dv = (PFNGLWINDOWPOS3DVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3dv")) == NULL) || r; + r = ((glWindowPos3f = (PFNGLWINDOWPOS3FPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3f")) == NULL) || r; + r = ((glWindowPos3fv = (PFNGLWINDOWPOS3FVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3fv")) == NULL) || r; + r = ((glWindowPos3i = (PFNGLWINDOWPOS3IPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3i")) == NULL) || r; + r = ((glWindowPos3iv = (PFNGLWINDOWPOS3IVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3iv")) == NULL) || r; + r = ((glWindowPos3s = (PFNGLWINDOWPOS3SPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3s")) == NULL) || r; + r = ((glWindowPos3sv = (PFNGLWINDOWPOS3SVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3sv")) == NULL) || r; + + return r; +} + +#endif /* GL_VERSION_1_4 */ + +#ifdef GL_VERSION_1_5 + +static GLboolean _glewInit_GL_VERSION_1_5 (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBeginQuery = (PFNGLBEGINQUERYPROC)glewGetProcAddress((const GLubyte*)"glBeginQuery")) == NULL) || r; + r = ((glBindBuffer = (PFNGLBINDBUFFERPROC)glewGetProcAddress((const GLubyte*)"glBindBuffer")) == NULL) || r; + r = ((glBufferData = (PFNGLBUFFERDATAPROC)glewGetProcAddress((const GLubyte*)"glBufferData")) == NULL) || r; + r = ((glBufferSubData = (PFNGLBUFFERSUBDATAPROC)glewGetProcAddress((const GLubyte*)"glBufferSubData")) == NULL) || r; + r = ((glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glDeleteBuffers")) == NULL) || r; + r = ((glDeleteQueries = (PFNGLDELETEQUERIESPROC)glewGetProcAddress((const GLubyte*)"glDeleteQueries")) == NULL) || r; + r = ((glEndQuery = (PFNGLENDQUERYPROC)glewGetProcAddress((const GLubyte*)"glEndQuery")) == NULL) || r; + r = ((glGenBuffers = (PFNGLGENBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glGenBuffers")) == NULL) || r; + r = ((glGenQueries = (PFNGLGENQUERIESPROC)glewGetProcAddress((const GLubyte*)"glGenQueries")) == NULL) || r; + r = ((glGetBufferParameteriv = (PFNGLGETBUFFERPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetBufferParameteriv")) == NULL) || r; + r = ((glGetBufferPointerv = (PFNGLGETBUFFERPOINTERVPROC)glewGetProcAddress((const GLubyte*)"glGetBufferPointerv")) == NULL) || r; + r = ((glGetBufferSubData = (PFNGLGETBUFFERSUBDATAPROC)glewGetProcAddress((const GLubyte*)"glGetBufferSubData")) == NULL) || r; + r = ((glGetQueryObjectiv = (PFNGLGETQUERYOBJECTIVPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjectiv")) == NULL) || r; + r = ((glGetQueryObjectuiv = (PFNGLGETQUERYOBJECTUIVPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjectuiv")) == NULL) || r; + r = ((glGetQueryiv = (PFNGLGETQUERYIVPROC)glewGetProcAddress((const GLubyte*)"glGetQueryiv")) == NULL) || r; + r = ((glIsBuffer = (PFNGLISBUFFERPROC)glewGetProcAddress((const GLubyte*)"glIsBuffer")) == NULL) || r; + r = ((glIsQuery = (PFNGLISQUERYPROC)glewGetProcAddress((const GLubyte*)"glIsQuery")) == NULL) || r; + r = ((glMapBuffer = (PFNGLMAPBUFFERPROC)glewGetProcAddress((const GLubyte*)"glMapBuffer")) == NULL) || r; + r = ((glUnmapBuffer = (PFNGLUNMAPBUFFERPROC)glewGetProcAddress((const GLubyte*)"glUnmapBuffer")) == NULL) || r; + + return r; +} + +#endif /* GL_VERSION_1_5 */ + +#ifdef GL_VERSION_2_0 + +static GLboolean _glewInit_GL_VERSION_2_0 (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glAttachShader = (PFNGLATTACHSHADERPROC)glewGetProcAddress((const GLubyte*)"glAttachShader")) == NULL) || r; + r = ((glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC)glewGetProcAddress((const GLubyte*)"glBindAttribLocation")) == NULL) || r; + r = ((glBlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEPROC)glewGetProcAddress((const GLubyte*)"glBlendEquationSeparate")) == NULL) || r; + r = ((glCompileShader = (PFNGLCOMPILESHADERPROC)glewGetProcAddress((const GLubyte*)"glCompileShader")) == NULL) || r; + r = ((glCreateProgram = (PFNGLCREATEPROGRAMPROC)glewGetProcAddress((const GLubyte*)"glCreateProgram")) == NULL) || r; + r = ((glCreateShader = (PFNGLCREATESHADERPROC)glewGetProcAddress((const GLubyte*)"glCreateShader")) == NULL) || r; + r = ((glDeleteProgram = (PFNGLDELETEPROGRAMPROC)glewGetProcAddress((const GLubyte*)"glDeleteProgram")) == NULL) || r; + r = ((glDeleteShader = (PFNGLDELETESHADERPROC)glewGetProcAddress((const GLubyte*)"glDeleteShader")) == NULL) || r; + r = ((glDetachShader = (PFNGLDETACHSHADERPROC)glewGetProcAddress((const GLubyte*)"glDetachShader")) == NULL) || r; + r = ((glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC)glewGetProcAddress((const GLubyte*)"glDisableVertexAttribArray")) == NULL) || r; + r = ((glDrawBuffers = (PFNGLDRAWBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glDrawBuffers")) == NULL) || r; + r = ((glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)glewGetProcAddress((const GLubyte*)"glEnableVertexAttribArray")) == NULL) || r; + r = ((glGetActiveAttrib = (PFNGLGETACTIVEATTRIBPROC)glewGetProcAddress((const GLubyte*)"glGetActiveAttrib")) == NULL) || r; + r = ((glGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC)glewGetProcAddress((const GLubyte*)"glGetActiveUniform")) == NULL) || r; + r = ((glGetAttachedShaders = (PFNGLGETATTACHEDSHADERSPROC)glewGetProcAddress((const GLubyte*)"glGetAttachedShaders")) == NULL) || r; + r = ((glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC)glewGetProcAddress((const GLubyte*)"glGetAttribLocation")) == NULL) || r; + r = ((glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)glewGetProcAddress((const GLubyte*)"glGetProgramInfoLog")) == NULL) || r; + r = ((glGetProgramiv = (PFNGLGETPROGRAMIVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramiv")) == NULL) || r; + r = ((glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)glewGetProcAddress((const GLubyte*)"glGetShaderInfoLog")) == NULL) || r; + r = ((glGetShaderSource = (PFNGLGETSHADERSOURCEPROC)glewGetProcAddress((const GLubyte*)"glGetShaderSource")) == NULL) || r; + r = ((glGetShaderiv = (PFNGLGETSHADERIVPROC)glewGetProcAddress((const GLubyte*)"glGetShaderiv")) == NULL) || r; + r = ((glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)glewGetProcAddress((const GLubyte*)"glGetUniformLocation")) == NULL) || r; + r = ((glGetUniformfv = (PFNGLGETUNIFORMFVPROC)glewGetProcAddress((const GLubyte*)"glGetUniformfv")) == NULL) || r; + r = ((glGetUniformiv = (PFNGLGETUNIFORMIVPROC)glewGetProcAddress((const GLubyte*)"glGetUniformiv")) == NULL) || r; + r = ((glGetVertexAttribPointerv = (PFNGLGETVERTEXATTRIBPOINTERVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribPointerv")) == NULL) || r; + r = ((glGetVertexAttribdv = (PFNGLGETVERTEXATTRIBDVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribdv")) == NULL) || r; + r = ((glGetVertexAttribfv = (PFNGLGETVERTEXATTRIBFVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribfv")) == NULL) || r; + r = ((glGetVertexAttribiv = (PFNGLGETVERTEXATTRIBIVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribiv")) == NULL) || r; + r = ((glIsProgram = (PFNGLISPROGRAMPROC)glewGetProcAddress((const GLubyte*)"glIsProgram")) == NULL) || r; + r = ((glIsShader = (PFNGLISSHADERPROC)glewGetProcAddress((const GLubyte*)"glIsShader")) == NULL) || r; + r = ((glLinkProgram = (PFNGLLINKPROGRAMPROC)glewGetProcAddress((const GLubyte*)"glLinkProgram")) == NULL) || r; + r = ((glShaderSource = (PFNGLSHADERSOURCEPROC)glewGetProcAddress((const GLubyte*)"glShaderSource")) == NULL) || r; + r = ((glStencilFuncSeparate = (PFNGLSTENCILFUNCSEPARATEPROC)glewGetProcAddress((const GLubyte*)"glStencilFuncSeparate")) == NULL) || r; + r = ((glStencilMaskSeparate = (PFNGLSTENCILMASKSEPARATEPROC)glewGetProcAddress((const GLubyte*)"glStencilMaskSeparate")) == NULL) || r; + r = ((glStencilOpSeparate = (PFNGLSTENCILOPSEPARATEPROC)glewGetProcAddress((const GLubyte*)"glStencilOpSeparate")) == NULL) || r; + r = ((glUniform1f = (PFNGLUNIFORM1FPROC)glewGetProcAddress((const GLubyte*)"glUniform1f")) == NULL) || r; + r = ((glUniform1fv = (PFNGLUNIFORM1FVPROC)glewGetProcAddress((const GLubyte*)"glUniform1fv")) == NULL) || r; + r = ((glUniform1i = (PFNGLUNIFORM1IPROC)glewGetProcAddress((const GLubyte*)"glUniform1i")) == NULL) || r; + r = ((glUniform1iv = (PFNGLUNIFORM1IVPROC)glewGetProcAddress((const GLubyte*)"glUniform1iv")) == NULL) || r; + r = ((glUniform2f = (PFNGLUNIFORM2FPROC)glewGetProcAddress((const GLubyte*)"glUniform2f")) == NULL) || r; + r = ((glUniform2fv = (PFNGLUNIFORM2FVPROC)glewGetProcAddress((const GLubyte*)"glUniform2fv")) == NULL) || r; + r = ((glUniform2i = (PFNGLUNIFORM2IPROC)glewGetProcAddress((const GLubyte*)"glUniform2i")) == NULL) || r; + r = ((glUniform2iv = (PFNGLUNIFORM2IVPROC)glewGetProcAddress((const GLubyte*)"glUniform2iv")) == NULL) || r; + r = ((glUniform3f = (PFNGLUNIFORM3FPROC)glewGetProcAddress((const GLubyte*)"glUniform3f")) == NULL) || r; + r = ((glUniform3fv = (PFNGLUNIFORM3FVPROC)glewGetProcAddress((const GLubyte*)"glUniform3fv")) == NULL) || r; + r = ((glUniform3i = (PFNGLUNIFORM3IPROC)glewGetProcAddress((const GLubyte*)"glUniform3i")) == NULL) || r; + r = ((glUniform3iv = (PFNGLUNIFORM3IVPROC)glewGetProcAddress((const GLubyte*)"glUniform3iv")) == NULL) || r; + r = ((glUniform4f = (PFNGLUNIFORM4FPROC)glewGetProcAddress((const GLubyte*)"glUniform4f")) == NULL) || r; + r = ((glUniform4fv = (PFNGLUNIFORM4FVPROC)glewGetProcAddress((const GLubyte*)"glUniform4fv")) == NULL) || r; + r = ((glUniform4i = (PFNGLUNIFORM4IPROC)glewGetProcAddress((const GLubyte*)"glUniform4i")) == NULL) || r; + r = ((glUniform4iv = (PFNGLUNIFORM4IVPROC)glewGetProcAddress((const GLubyte*)"glUniform4iv")) == NULL) || r; + r = ((glUniformMatrix2fv = (PFNGLUNIFORMMATRIX2FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix2fv")) == NULL) || r; + r = ((glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix3fv")) == NULL) || r; + r = ((glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix4fv")) == NULL) || r; + r = ((glUseProgram = (PFNGLUSEPROGRAMPROC)glewGetProcAddress((const GLubyte*)"glUseProgram")) == NULL) || r; + r = ((glValidateProgram = (PFNGLVALIDATEPROGRAMPROC)glewGetProcAddress((const GLubyte*)"glValidateProgram")) == NULL) || r; + r = ((glVertexAttrib1d = (PFNGLVERTEXATTRIB1DPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1d")) == NULL) || r; + r = ((glVertexAttrib1dv = (PFNGLVERTEXATTRIB1DVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1dv")) == NULL) || r; + r = ((glVertexAttrib1f = (PFNGLVERTEXATTRIB1FPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1f")) == NULL) || r; + r = ((glVertexAttrib1fv = (PFNGLVERTEXATTRIB1FVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1fv")) == NULL) || r; + r = ((glVertexAttrib1s = (PFNGLVERTEXATTRIB1SPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1s")) == NULL) || r; + r = ((glVertexAttrib1sv = (PFNGLVERTEXATTRIB1SVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1sv")) == NULL) || r; + r = ((glVertexAttrib2d = (PFNGLVERTEXATTRIB2DPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2d")) == NULL) || r; + r = ((glVertexAttrib2dv = (PFNGLVERTEXATTRIB2DVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2dv")) == NULL) || r; + r = ((glVertexAttrib2f = (PFNGLVERTEXATTRIB2FPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2f")) == NULL) || r; + r = ((glVertexAttrib2fv = (PFNGLVERTEXATTRIB2FVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2fv")) == NULL) || r; + r = ((glVertexAttrib2s = (PFNGLVERTEXATTRIB2SPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2s")) == NULL) || r; + r = ((glVertexAttrib2sv = (PFNGLVERTEXATTRIB2SVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2sv")) == NULL) || r; + r = ((glVertexAttrib3d = (PFNGLVERTEXATTRIB3DPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3d")) == NULL) || r; + r = ((glVertexAttrib3dv = (PFNGLVERTEXATTRIB3DVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3dv")) == NULL) || r; + r = ((glVertexAttrib3f = (PFNGLVERTEXATTRIB3FPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3f")) == NULL) || r; + r = ((glVertexAttrib3fv = (PFNGLVERTEXATTRIB3FVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3fv")) == NULL) || r; + r = ((glVertexAttrib3s = (PFNGLVERTEXATTRIB3SPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3s")) == NULL) || r; + r = ((glVertexAttrib3sv = (PFNGLVERTEXATTRIB3SVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3sv")) == NULL) || r; + r = ((glVertexAttrib4Nbv = (PFNGLVERTEXATTRIB4NBVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4Nbv")) == NULL) || r; + r = ((glVertexAttrib4Niv = (PFNGLVERTEXATTRIB4NIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4Niv")) == NULL) || r; + r = ((glVertexAttrib4Nsv = (PFNGLVERTEXATTRIB4NSVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4Nsv")) == NULL) || r; + r = ((glVertexAttrib4Nub = (PFNGLVERTEXATTRIB4NUBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4Nub")) == NULL) || r; + r = ((glVertexAttrib4Nubv = (PFNGLVERTEXATTRIB4NUBVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4Nubv")) == NULL) || r; + r = ((glVertexAttrib4Nuiv = (PFNGLVERTEXATTRIB4NUIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4Nuiv")) == NULL) || r; + r = ((glVertexAttrib4Nusv = (PFNGLVERTEXATTRIB4NUSVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4Nusv")) == NULL) || r; + r = ((glVertexAttrib4bv = (PFNGLVERTEXATTRIB4BVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4bv")) == NULL) || r; + r = ((glVertexAttrib4d = (PFNGLVERTEXATTRIB4DPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4d")) == NULL) || r; + r = ((glVertexAttrib4dv = (PFNGLVERTEXATTRIB4DVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4dv")) == NULL) || r; + r = ((glVertexAttrib4f = (PFNGLVERTEXATTRIB4FPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4f")) == NULL) || r; + r = ((glVertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4fv")) == NULL) || r; + r = ((glVertexAttrib4iv = (PFNGLVERTEXATTRIB4IVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4iv")) == NULL) || r; + r = ((glVertexAttrib4s = (PFNGLVERTEXATTRIB4SPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4s")) == NULL) || r; + r = ((glVertexAttrib4sv = (PFNGLVERTEXATTRIB4SVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4sv")) == NULL) || r; + r = ((glVertexAttrib4ubv = (PFNGLVERTEXATTRIB4UBVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4ubv")) == NULL) || r; + r = ((glVertexAttrib4uiv = (PFNGLVERTEXATTRIB4UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4uiv")) == NULL) || r; + r = ((glVertexAttrib4usv = (PFNGLVERTEXATTRIB4USVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4usv")) == NULL) || r; + r = ((glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribPointer")) == NULL) || r; + + return r; +} + +#endif /* GL_VERSION_2_0 */ + +#ifdef GL_VERSION_2_1 + +static GLboolean _glewInit_GL_VERSION_2_1 (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glUniformMatrix2x3fv = (PFNGLUNIFORMMATRIX2X3FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix2x3fv")) == NULL) || r; + r = ((glUniformMatrix2x4fv = (PFNGLUNIFORMMATRIX2X4FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix2x4fv")) == NULL) || r; + r = ((glUniformMatrix3x2fv = (PFNGLUNIFORMMATRIX3X2FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix3x2fv")) == NULL) || r; + r = ((glUniformMatrix3x4fv = (PFNGLUNIFORMMATRIX3X4FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix3x4fv")) == NULL) || r; + r = ((glUniformMatrix4x2fv = (PFNGLUNIFORMMATRIX4X2FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix4x2fv")) == NULL) || r; + r = ((glUniformMatrix4x3fv = (PFNGLUNIFORMMATRIX4X3FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix4x3fv")) == NULL) || r; + + return r; +} + +#endif /* GL_VERSION_2_1 */ + +#ifdef GL_VERSION_3_0 + +static GLboolean _glewInit_GL_VERSION_3_0 (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBeginConditionalRender = (PFNGLBEGINCONDITIONALRENDERPROC)glewGetProcAddress((const GLubyte*)"glBeginConditionalRender")) == NULL) || r; + r = ((glBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC)glewGetProcAddress((const GLubyte*)"glBeginTransformFeedback")) == NULL) || r; + r = ((glBindBufferBase = (PFNGLBINDBUFFERBASEPROC)glewGetProcAddress((const GLubyte*)"glBindBufferBase")) == NULL) || r; + r = ((glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC)glewGetProcAddress((const GLubyte*)"glBindBufferRange")) == NULL) || r; + r = ((glBindFragDataLocation = (PFNGLBINDFRAGDATALOCATIONPROC)glewGetProcAddress((const GLubyte*)"glBindFragDataLocation")) == NULL) || r; + r = ((glClampColor = (PFNGLCLAMPCOLORPROC)glewGetProcAddress((const GLubyte*)"glClampColor")) == NULL) || r; + r = ((glClearBufferfi = (PFNGLCLEARBUFFERFIPROC)glewGetProcAddress((const GLubyte*)"glClearBufferfi")) == NULL) || r; + r = ((glClearBufferfv = (PFNGLCLEARBUFFERFVPROC)glewGetProcAddress((const GLubyte*)"glClearBufferfv")) == NULL) || r; + r = ((glClearBufferiv = (PFNGLCLEARBUFFERIVPROC)glewGetProcAddress((const GLubyte*)"glClearBufferiv")) == NULL) || r; + r = ((glClearBufferuiv = (PFNGLCLEARBUFFERUIVPROC)glewGetProcAddress((const GLubyte*)"glClearBufferuiv")) == NULL) || r; + r = ((glColorMaski = (PFNGLCOLORMASKIPROC)glewGetProcAddress((const GLubyte*)"glColorMaski")) == NULL) || r; + r = ((glDisablei = (PFNGLDISABLEIPROC)glewGetProcAddress((const GLubyte*)"glDisablei")) == NULL) || r; + r = ((glEnablei = (PFNGLENABLEIPROC)glewGetProcAddress((const GLubyte*)"glEnablei")) == NULL) || r; + r = ((glEndConditionalRender = (PFNGLENDCONDITIONALRENDERPROC)glewGetProcAddress((const GLubyte*)"glEndConditionalRender")) == NULL) || r; + r = ((glEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC)glewGetProcAddress((const GLubyte*)"glEndTransformFeedback")) == NULL) || r; + r = ((glGetBooleani_v = (PFNGLGETBOOLEANI_VPROC)glewGetProcAddress((const GLubyte*)"glGetBooleani_v")) == NULL) || r; + r = ((glGetFragDataLocation = (PFNGLGETFRAGDATALOCATIONPROC)glewGetProcAddress((const GLubyte*)"glGetFragDataLocation")) == NULL) || r; + r = ((glGetIntegeri_v = (PFNGLGETINTEGERI_VPROC)glewGetProcAddress((const GLubyte*)"glGetIntegeri_v")) == NULL) || r; + r = ((glGetStringi = (PFNGLGETSTRINGIPROC)glewGetProcAddress((const GLubyte*)"glGetStringi")) == NULL) || r; + r = ((glGetTexParameterIiv = (PFNGLGETTEXPARAMETERIIVPROC)glewGetProcAddress((const GLubyte*)"glGetTexParameterIiv")) == NULL) || r; + r = ((glGetTexParameterIuiv = (PFNGLGETTEXPARAMETERIUIVPROC)glewGetProcAddress((const GLubyte*)"glGetTexParameterIuiv")) == NULL) || r; + r = ((glGetTransformFeedbackVarying = (PFNGLGETTRANSFORMFEEDBACKVARYINGPROC)glewGetProcAddress((const GLubyte*)"glGetTransformFeedbackVarying")) == NULL) || r; + r = ((glGetUniformuiv = (PFNGLGETUNIFORMUIVPROC)glewGetProcAddress((const GLubyte*)"glGetUniformuiv")) == NULL) || r; + r = ((glGetVertexAttribIiv = (PFNGLGETVERTEXATTRIBIIVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribIiv")) == NULL) || r; + r = ((glGetVertexAttribIuiv = (PFNGLGETVERTEXATTRIBIUIVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribIuiv")) == NULL) || r; + r = ((glIsEnabledi = (PFNGLISENABLEDIPROC)glewGetProcAddress((const GLubyte*)"glIsEnabledi")) == NULL) || r; + r = ((glTexParameterIiv = (PFNGLTEXPARAMETERIIVPROC)glewGetProcAddress((const GLubyte*)"glTexParameterIiv")) == NULL) || r; + r = ((glTexParameterIuiv = (PFNGLTEXPARAMETERIUIVPROC)glewGetProcAddress((const GLubyte*)"glTexParameterIuiv")) == NULL) || r; + r = ((glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC)glewGetProcAddress((const GLubyte*)"glTransformFeedbackVaryings")) == NULL) || r; + r = ((glUniform1ui = (PFNGLUNIFORM1UIPROC)glewGetProcAddress((const GLubyte*)"glUniform1ui")) == NULL) || r; + r = ((glUniform1uiv = (PFNGLUNIFORM1UIVPROC)glewGetProcAddress((const GLubyte*)"glUniform1uiv")) == NULL) || r; + r = ((glUniform2ui = (PFNGLUNIFORM2UIPROC)glewGetProcAddress((const GLubyte*)"glUniform2ui")) == NULL) || r; + r = ((glUniform2uiv = (PFNGLUNIFORM2UIVPROC)glewGetProcAddress((const GLubyte*)"glUniform2uiv")) == NULL) || r; + r = ((glUniform3ui = (PFNGLUNIFORM3UIPROC)glewGetProcAddress((const GLubyte*)"glUniform3ui")) == NULL) || r; + r = ((glUniform3uiv = (PFNGLUNIFORM3UIVPROC)glewGetProcAddress((const GLubyte*)"glUniform3uiv")) == NULL) || r; + r = ((glUniform4ui = (PFNGLUNIFORM4UIPROC)glewGetProcAddress((const GLubyte*)"glUniform4ui")) == NULL) || r; + r = ((glUniform4uiv = (PFNGLUNIFORM4UIVPROC)glewGetProcAddress((const GLubyte*)"glUniform4uiv")) == NULL) || r; + r = ((glVertexAttribI1i = (PFNGLVERTEXATTRIBI1IPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI1i")) == NULL) || r; + r = ((glVertexAttribI1iv = (PFNGLVERTEXATTRIBI1IVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI1iv")) == NULL) || r; + r = ((glVertexAttribI1ui = (PFNGLVERTEXATTRIBI1UIPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI1ui")) == NULL) || r; + r = ((glVertexAttribI1uiv = (PFNGLVERTEXATTRIBI1UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI1uiv")) == NULL) || r; + r = ((glVertexAttribI2i = (PFNGLVERTEXATTRIBI2IPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI2i")) == NULL) || r; + r = ((glVertexAttribI2iv = (PFNGLVERTEXATTRIBI2IVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI2iv")) == NULL) || r; + r = ((glVertexAttribI2ui = (PFNGLVERTEXATTRIBI2UIPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI2ui")) == NULL) || r; + r = ((glVertexAttribI2uiv = (PFNGLVERTEXATTRIBI2UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI2uiv")) == NULL) || r; + r = ((glVertexAttribI3i = (PFNGLVERTEXATTRIBI3IPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI3i")) == NULL) || r; + r = ((glVertexAttribI3iv = (PFNGLVERTEXATTRIBI3IVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI3iv")) == NULL) || r; + r = ((glVertexAttribI3ui = (PFNGLVERTEXATTRIBI3UIPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI3ui")) == NULL) || r; + r = ((glVertexAttribI3uiv = (PFNGLVERTEXATTRIBI3UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI3uiv")) == NULL) || r; + r = ((glVertexAttribI4bv = (PFNGLVERTEXATTRIBI4BVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4bv")) == NULL) || r; + r = ((glVertexAttribI4i = (PFNGLVERTEXATTRIBI4IPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4i")) == NULL) || r; + r = ((glVertexAttribI4iv = (PFNGLVERTEXATTRIBI4IVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4iv")) == NULL) || r; + r = ((glVertexAttribI4sv = (PFNGLVERTEXATTRIBI4SVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4sv")) == NULL) || r; + r = ((glVertexAttribI4ubv = (PFNGLVERTEXATTRIBI4UBVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4ubv")) == NULL) || r; + r = ((glVertexAttribI4ui = (PFNGLVERTEXATTRIBI4UIPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4ui")) == NULL) || r; + r = ((glVertexAttribI4uiv = (PFNGLVERTEXATTRIBI4UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4uiv")) == NULL) || r; + r = ((glVertexAttribI4usv = (PFNGLVERTEXATTRIBI4USVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4usv")) == NULL) || r; + r = ((glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribIPointer")) == NULL) || r; + + return r; +} + +#endif /* GL_VERSION_3_0 */ + +#ifdef GL_3DFX_multisample + +#endif /* GL_3DFX_multisample */ + +#ifdef GL_3DFX_tbuffer + +static GLboolean _glewInit_GL_3DFX_tbuffer (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glTbufferMask3DFX = (PFNGLTBUFFERMASK3DFXPROC)glewGetProcAddress((const GLubyte*)"glTbufferMask3DFX")) == NULL) || r; + + return r; +} + +#endif /* GL_3DFX_tbuffer */ + +#ifdef GL_3DFX_texture_compression_FXT1 + +#endif /* GL_3DFX_texture_compression_FXT1 */ + +#ifdef GL_APPLE_client_storage + +#endif /* GL_APPLE_client_storage */ + +#ifdef GL_APPLE_element_array + +static GLboolean _glewInit_GL_APPLE_element_array (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glDrawElementArrayAPPLE = (PFNGLDRAWELEMENTARRAYAPPLEPROC)glewGetProcAddress((const GLubyte*)"glDrawElementArrayAPPLE")) == NULL) || r; + r = ((glDrawRangeElementArrayAPPLE = (PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC)glewGetProcAddress((const GLubyte*)"glDrawRangeElementArrayAPPLE")) == NULL) || r; + r = ((glElementPointerAPPLE = (PFNGLELEMENTPOINTERAPPLEPROC)glewGetProcAddress((const GLubyte*)"glElementPointerAPPLE")) == NULL) || r; + r = ((glMultiDrawElementArrayAPPLE = (PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawElementArrayAPPLE")) == NULL) || r; + r = ((glMultiDrawRangeElementArrayAPPLE = (PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawRangeElementArrayAPPLE")) == NULL) || r; + + return r; +} + +#endif /* GL_APPLE_element_array */ + +#ifdef GL_APPLE_fence + +static GLboolean _glewInit_GL_APPLE_fence (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glDeleteFencesAPPLE = (PFNGLDELETEFENCESAPPLEPROC)glewGetProcAddress((const GLubyte*)"glDeleteFencesAPPLE")) == NULL) || r; + r = ((glFinishFenceAPPLE = (PFNGLFINISHFENCEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glFinishFenceAPPLE")) == NULL) || r; + r = ((glFinishObjectAPPLE = (PFNGLFINISHOBJECTAPPLEPROC)glewGetProcAddress((const GLubyte*)"glFinishObjectAPPLE")) == NULL) || r; + r = ((glGenFencesAPPLE = (PFNGLGENFENCESAPPLEPROC)glewGetProcAddress((const GLubyte*)"glGenFencesAPPLE")) == NULL) || r; + r = ((glIsFenceAPPLE = (PFNGLISFENCEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glIsFenceAPPLE")) == NULL) || r; + r = ((glSetFenceAPPLE = (PFNGLSETFENCEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glSetFenceAPPLE")) == NULL) || r; + r = ((glTestFenceAPPLE = (PFNGLTESTFENCEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glTestFenceAPPLE")) == NULL) || r; + r = ((glTestObjectAPPLE = (PFNGLTESTOBJECTAPPLEPROC)glewGetProcAddress((const GLubyte*)"glTestObjectAPPLE")) == NULL) || r; + + return r; +} + +#endif /* GL_APPLE_fence */ + +#ifdef GL_APPLE_float_pixels + +#endif /* GL_APPLE_float_pixels */ + +#ifdef GL_APPLE_flush_buffer_range + +static GLboolean _glewInit_GL_APPLE_flush_buffer_range (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBufferParameteriAPPLE = (PFNGLBUFFERPARAMETERIAPPLEPROC)glewGetProcAddress((const GLubyte*)"glBufferParameteriAPPLE")) == NULL) || r; + r = ((glFlushMappedBufferRangeAPPLE = (PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glFlushMappedBufferRangeAPPLE")) == NULL) || r; + + return r; +} + +#endif /* GL_APPLE_flush_buffer_range */ + +#ifdef GL_APPLE_pixel_buffer + +#endif /* GL_APPLE_pixel_buffer */ + +#ifdef GL_APPLE_specular_vector + +#endif /* GL_APPLE_specular_vector */ + +#ifdef GL_APPLE_texture_range + +static GLboolean _glewInit_GL_APPLE_texture_range (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetTexParameterPointervAPPLE = (PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC)glewGetProcAddress((const GLubyte*)"glGetTexParameterPointervAPPLE")) == NULL) || r; + r = ((glTextureRangeAPPLE = (PFNGLTEXTURERANGEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glTextureRangeAPPLE")) == NULL) || r; + + return r; +} + +#endif /* GL_APPLE_texture_range */ + +#ifdef GL_APPLE_transform_hint + +#endif /* GL_APPLE_transform_hint */ + +#ifdef GL_APPLE_vertex_array_object + +static GLboolean _glewInit_GL_APPLE_vertex_array_object (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBindVertexArrayAPPLE = (PFNGLBINDVERTEXARRAYAPPLEPROC)glewGetProcAddress((const GLubyte*)"glBindVertexArrayAPPLE")) == NULL) || r; + r = ((glDeleteVertexArraysAPPLE = (PFNGLDELETEVERTEXARRAYSAPPLEPROC)glewGetProcAddress((const GLubyte*)"glDeleteVertexArraysAPPLE")) == NULL) || r; + r = ((glGenVertexArraysAPPLE = (PFNGLGENVERTEXARRAYSAPPLEPROC)glewGetProcAddress((const GLubyte*)"glGenVertexArraysAPPLE")) == NULL) || r; + r = ((glIsVertexArrayAPPLE = (PFNGLISVERTEXARRAYAPPLEPROC)glewGetProcAddress((const GLubyte*)"glIsVertexArrayAPPLE")) == NULL) || r; + + return r; +} + +#endif /* GL_APPLE_vertex_array_object */ + +#ifdef GL_APPLE_vertex_array_range + +static GLboolean _glewInit_GL_APPLE_vertex_array_range (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glFlushVertexArrayRangeAPPLE = (PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glFlushVertexArrayRangeAPPLE")) == NULL) || r; + r = ((glVertexArrayParameteriAPPLE = (PFNGLVERTEXARRAYPARAMETERIAPPLEPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayParameteriAPPLE")) == NULL) || r; + r = ((glVertexArrayRangeAPPLE = (PFNGLVERTEXARRAYRANGEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayRangeAPPLE")) == NULL) || r; + + return r; +} + +#endif /* GL_APPLE_vertex_array_range */ + +#ifdef GL_APPLE_ycbcr_422 + +#endif /* GL_APPLE_ycbcr_422 */ + +#ifdef GL_ARB_color_buffer_float + +static GLboolean _glewInit_GL_ARB_color_buffer_float (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glClampColorARB = (PFNGLCLAMPCOLORARBPROC)glewGetProcAddress((const GLubyte*)"glClampColorARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_color_buffer_float */ + +#ifdef GL_ARB_depth_buffer_float + +#endif /* GL_ARB_depth_buffer_float */ + +#ifdef GL_ARB_depth_texture + +#endif /* GL_ARB_depth_texture */ + +#ifdef GL_ARB_draw_buffers + +static GLboolean _glewInit_GL_ARB_draw_buffers (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glDrawBuffersARB = (PFNGLDRAWBUFFERSARBPROC)glewGetProcAddress((const GLubyte*)"glDrawBuffersARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_draw_buffers */ + +#ifdef GL_ARB_draw_instanced + +static GLboolean _glewInit_GL_ARB_draw_instanced (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glDrawArraysInstancedARB = (PFNGLDRAWARRAYSINSTANCEDARBPROC)glewGetProcAddress((const GLubyte*)"glDrawArraysInstancedARB")) == NULL) || r; + r = ((glDrawElementsInstancedARB = (PFNGLDRAWELEMENTSINSTANCEDARBPROC)glewGetProcAddress((const GLubyte*)"glDrawElementsInstancedARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_draw_instanced */ + +#ifdef GL_ARB_fragment_program + +#endif /* GL_ARB_fragment_program */ + +#ifdef GL_ARB_fragment_program_shadow + +#endif /* GL_ARB_fragment_program_shadow */ + +#ifdef GL_ARB_fragment_shader + +#endif /* GL_ARB_fragment_shader */ + +#ifdef GL_ARB_framebuffer_object + +static GLboolean _glewInit_GL_ARB_framebuffer_object (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)glewGetProcAddress((const GLubyte*)"glBindFramebuffer")) == NULL) || r; + r = ((glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC)glewGetProcAddress((const GLubyte*)"glBindRenderbuffer")) == NULL) || r; + r = ((glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC)glewGetProcAddress((const GLubyte*)"glBlitFramebuffer")) == NULL) || r; + r = ((glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)glewGetProcAddress((const GLubyte*)"glCheckFramebufferStatus")) == NULL) || r; + r = ((glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glDeleteFramebuffers")) == NULL) || r; + r = ((glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glDeleteRenderbuffers")) == NULL) || r; + r = ((glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)glewGetProcAddress((const GLubyte*)"glFramebufferRenderbuffer")) == NULL) || r; + r = ((glFramebufferTexturLayer = (PFNGLFRAMEBUFFERTEXTURLAYERPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexturLayer")) == NULL) || r; + r = ((glFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexture1D")) == NULL) || r; + r = ((glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexture2D")) == NULL) || r; + r = ((glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexture3D")) == NULL) || r; + r = ((glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glGenFramebuffers")) == NULL) || r; + r = ((glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glGenRenderbuffers")) == NULL) || r; + r = ((glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC)glewGetProcAddress((const GLubyte*)"glGenerateMipmap")) == NULL) || r; + r = ((glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetFramebufferAttachmentParameteriv")) == NULL) || r; + r = ((glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetRenderbufferParameteriv")) == NULL) || r; + r = ((glIsFramebuffer = (PFNGLISFRAMEBUFFERPROC)glewGetProcAddress((const GLubyte*)"glIsFramebuffer")) == NULL) || r; + r = ((glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC)glewGetProcAddress((const GLubyte*)"glIsRenderbuffer")) == NULL) || r; + r = ((glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC)glewGetProcAddress((const GLubyte*)"glRenderbufferStorage")) == NULL) || r; + r = ((glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)glewGetProcAddress((const GLubyte*)"glRenderbufferStorageMultisample")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_framebuffer_object */ + +#ifdef GL_ARB_framebuffer_sRGB + +#endif /* GL_ARB_framebuffer_sRGB */ + +#ifdef GL_ARB_geometry_shader4 + +static GLboolean _glewInit_GL_ARB_geometry_shader4 (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glFramebufferTextureARB = (PFNGLFRAMEBUFFERTEXTUREARBPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTextureARB")) == NULL) || r; + r = ((glFramebufferTextureFaceARB = (PFNGLFRAMEBUFFERTEXTUREFACEARBPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTextureFaceARB")) == NULL) || r; + r = ((glFramebufferTextureLayerARB = (PFNGLFRAMEBUFFERTEXTURELAYERARBPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTextureLayerARB")) == NULL) || r; + r = ((glProgramParameteriARB = (PFNGLPROGRAMPARAMETERIARBPROC)glewGetProcAddress((const GLubyte*)"glProgramParameteriARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_geometry_shader4 */ + +#ifdef GL_ARB_half_float_pixel + +#endif /* GL_ARB_half_float_pixel */ + +#ifdef GL_ARB_half_float_vertex + +#endif /* GL_ARB_half_float_vertex */ + +#ifdef GL_ARB_imaging + +static GLboolean _glewInit_GL_ARB_imaging (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBlendEquation = (PFNGLBLENDEQUATIONPROC)glewGetProcAddress((const GLubyte*)"glBlendEquation")) == NULL) || r; + r = ((glColorSubTable = (PFNGLCOLORSUBTABLEPROC)glewGetProcAddress((const GLubyte*)"glColorSubTable")) == NULL) || r; + r = ((glColorTable = (PFNGLCOLORTABLEPROC)glewGetProcAddress((const GLubyte*)"glColorTable")) == NULL) || r; + r = ((glColorTableParameterfv = (PFNGLCOLORTABLEPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glColorTableParameterfv")) == NULL) || r; + r = ((glColorTableParameteriv = (PFNGLCOLORTABLEPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glColorTableParameteriv")) == NULL) || r; + r = ((glConvolutionFilter1D = (PFNGLCONVOLUTIONFILTER1DPROC)glewGetProcAddress((const GLubyte*)"glConvolutionFilter1D")) == NULL) || r; + r = ((glConvolutionFilter2D = (PFNGLCONVOLUTIONFILTER2DPROC)glewGetProcAddress((const GLubyte*)"glConvolutionFilter2D")) == NULL) || r; + r = ((glConvolutionParameterf = (PFNGLCONVOLUTIONPARAMETERFPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameterf")) == NULL) || r; + r = ((glConvolutionParameterfv = (PFNGLCONVOLUTIONPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameterfv")) == NULL) || r; + r = ((glConvolutionParameteri = (PFNGLCONVOLUTIONPARAMETERIPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameteri")) == NULL) || r; + r = ((glConvolutionParameteriv = (PFNGLCONVOLUTIONPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameteriv")) == NULL) || r; + r = ((glCopyColorSubTable = (PFNGLCOPYCOLORSUBTABLEPROC)glewGetProcAddress((const GLubyte*)"glCopyColorSubTable")) == NULL) || r; + r = ((glCopyColorTable = (PFNGLCOPYCOLORTABLEPROC)glewGetProcAddress((const GLubyte*)"glCopyColorTable")) == NULL) || r; + r = ((glCopyConvolutionFilter1D = (PFNGLCOPYCONVOLUTIONFILTER1DPROC)glewGetProcAddress((const GLubyte*)"glCopyConvolutionFilter1D")) == NULL) || r; + r = ((glCopyConvolutionFilter2D = (PFNGLCOPYCONVOLUTIONFILTER2DPROC)glewGetProcAddress((const GLubyte*)"glCopyConvolutionFilter2D")) == NULL) || r; + r = ((glGetColorTable = (PFNGLGETCOLORTABLEPROC)glewGetProcAddress((const GLubyte*)"glGetColorTable")) == NULL) || r; + r = ((glGetColorTableParameterfv = (PFNGLGETCOLORTABLEPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableParameterfv")) == NULL) || r; + r = ((glGetColorTableParameteriv = (PFNGLGETCOLORTABLEPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableParameteriv")) == NULL) || r; + r = ((glGetConvolutionFilter = (PFNGLGETCONVOLUTIONFILTERPROC)glewGetProcAddress((const GLubyte*)"glGetConvolutionFilter")) == NULL) || r; + r = ((glGetConvolutionParameterfv = (PFNGLGETCONVOLUTIONPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glGetConvolutionParameterfv")) == NULL) || r; + r = ((glGetConvolutionParameteriv = (PFNGLGETCONVOLUTIONPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetConvolutionParameteriv")) == NULL) || r; + r = ((glGetHistogram = (PFNGLGETHISTOGRAMPROC)glewGetProcAddress((const GLubyte*)"glGetHistogram")) == NULL) || r; + r = ((glGetHistogramParameterfv = (PFNGLGETHISTOGRAMPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glGetHistogramParameterfv")) == NULL) || r; + r = ((glGetHistogramParameteriv = (PFNGLGETHISTOGRAMPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetHistogramParameteriv")) == NULL) || r; + r = ((glGetMinmax = (PFNGLGETMINMAXPROC)glewGetProcAddress((const GLubyte*)"glGetMinmax")) == NULL) || r; + r = ((glGetMinmaxParameterfv = (PFNGLGETMINMAXPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glGetMinmaxParameterfv")) == NULL) || r; + r = ((glGetMinmaxParameteriv = (PFNGLGETMINMAXPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetMinmaxParameteriv")) == NULL) || r; + r = ((glGetSeparableFilter = (PFNGLGETSEPARABLEFILTERPROC)glewGetProcAddress((const GLubyte*)"glGetSeparableFilter")) == NULL) || r; + r = ((glHistogram = (PFNGLHISTOGRAMPROC)glewGetProcAddress((const GLubyte*)"glHistogram")) == NULL) || r; + r = ((glMinmax = (PFNGLMINMAXPROC)glewGetProcAddress((const GLubyte*)"glMinmax")) == NULL) || r; + r = ((glResetHistogram = (PFNGLRESETHISTOGRAMPROC)glewGetProcAddress((const GLubyte*)"glResetHistogram")) == NULL) || r; + r = ((glResetMinmax = (PFNGLRESETMINMAXPROC)glewGetProcAddress((const GLubyte*)"glResetMinmax")) == NULL) || r; + r = ((glSeparableFilter2D = (PFNGLSEPARABLEFILTER2DPROC)glewGetProcAddress((const GLubyte*)"glSeparableFilter2D")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_imaging */ + +#ifdef GL_ARB_instanced_arrays + +static GLboolean _glewInit_GL_ARB_instanced_arrays (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glVertexAttribDivisorARB = (PFNGLVERTEXATTRIBDIVISORARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribDivisorARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_instanced_arrays */ + +#ifdef GL_ARB_map_buffer_range + +static GLboolean _glewInit_GL_ARB_map_buffer_range (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glFlushMappedBufferRange = (PFNGLFLUSHMAPPEDBUFFERRANGEPROC)glewGetProcAddress((const GLubyte*)"glFlushMappedBufferRange")) == NULL) || r; + r = ((glMapBufferRange = (PFNGLMAPBUFFERRANGEPROC)glewGetProcAddress((const GLubyte*)"glMapBufferRange")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_map_buffer_range */ + +#ifdef GL_ARB_matrix_palette + +static GLboolean _glewInit_GL_ARB_matrix_palette (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glCurrentPaletteMatrixARB = (PFNGLCURRENTPALETTEMATRIXARBPROC)glewGetProcAddress((const GLubyte*)"glCurrentPaletteMatrixARB")) == NULL) || r; + r = ((glMatrixIndexPointerARB = (PFNGLMATRIXINDEXPOINTERARBPROC)glewGetProcAddress((const GLubyte*)"glMatrixIndexPointerARB")) == NULL) || r; + r = ((glMatrixIndexubvARB = (PFNGLMATRIXINDEXUBVARBPROC)glewGetProcAddress((const GLubyte*)"glMatrixIndexubvARB")) == NULL) || r; + r = ((glMatrixIndexuivARB = (PFNGLMATRIXINDEXUIVARBPROC)glewGetProcAddress((const GLubyte*)"glMatrixIndexuivARB")) == NULL) || r; + r = ((glMatrixIndexusvARB = (PFNGLMATRIXINDEXUSVARBPROC)glewGetProcAddress((const GLubyte*)"glMatrixIndexusvARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_matrix_palette */ + +#ifdef GL_ARB_multisample + +static GLboolean _glewInit_GL_ARB_multisample (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glSampleCoverageARB = (PFNGLSAMPLECOVERAGEARBPROC)glewGetProcAddress((const GLubyte*)"glSampleCoverageARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_multisample */ + +#ifdef GL_ARB_multitexture + +static GLboolean _glewInit_GL_ARB_multitexture (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC)glewGetProcAddress((const GLubyte*)"glActiveTextureARB")) == NULL) || r; + r = ((glClientActiveTextureARB = (PFNGLCLIENTACTIVETEXTUREARBPROC)glewGetProcAddress((const GLubyte*)"glClientActiveTextureARB")) == NULL) || r; + r = ((glMultiTexCoord1dARB = (PFNGLMULTITEXCOORD1DARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1dARB")) == NULL) || r; + r = ((glMultiTexCoord1dvARB = (PFNGLMULTITEXCOORD1DVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1dvARB")) == NULL) || r; + r = ((glMultiTexCoord1fARB = (PFNGLMULTITEXCOORD1FARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1fARB")) == NULL) || r; + r = ((glMultiTexCoord1fvARB = (PFNGLMULTITEXCOORD1FVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1fvARB")) == NULL) || r; + r = ((glMultiTexCoord1iARB = (PFNGLMULTITEXCOORD1IARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1iARB")) == NULL) || r; + r = ((glMultiTexCoord1ivARB = (PFNGLMULTITEXCOORD1IVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1ivARB")) == NULL) || r; + r = ((glMultiTexCoord1sARB = (PFNGLMULTITEXCOORD1SARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1sARB")) == NULL) || r; + r = ((glMultiTexCoord1svARB = (PFNGLMULTITEXCOORD1SVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1svARB")) == NULL) || r; + r = ((glMultiTexCoord2dARB = (PFNGLMULTITEXCOORD2DARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2dARB")) == NULL) || r; + r = ((glMultiTexCoord2dvARB = (PFNGLMULTITEXCOORD2DVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2dvARB")) == NULL) || r; + r = ((glMultiTexCoord2fARB = (PFNGLMULTITEXCOORD2FARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2fARB")) == NULL) || r; + r = ((glMultiTexCoord2fvARB = (PFNGLMULTITEXCOORD2FVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2fvARB")) == NULL) || r; + r = ((glMultiTexCoord2iARB = (PFNGLMULTITEXCOORD2IARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2iARB")) == NULL) || r; + r = ((glMultiTexCoord2ivARB = (PFNGLMULTITEXCOORD2IVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2ivARB")) == NULL) || r; + r = ((glMultiTexCoord2sARB = (PFNGLMULTITEXCOORD2SARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2sARB")) == NULL) || r; + r = ((glMultiTexCoord2svARB = (PFNGLMULTITEXCOORD2SVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2svARB")) == NULL) || r; + r = ((glMultiTexCoord3dARB = (PFNGLMULTITEXCOORD3DARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3dARB")) == NULL) || r; + r = ((glMultiTexCoord3dvARB = (PFNGLMULTITEXCOORD3DVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3dvARB")) == NULL) || r; + r = ((glMultiTexCoord3fARB = (PFNGLMULTITEXCOORD3FARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3fARB")) == NULL) || r; + r = ((glMultiTexCoord3fvARB = (PFNGLMULTITEXCOORD3FVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3fvARB")) == NULL) || r; + r = ((glMultiTexCoord3iARB = (PFNGLMULTITEXCOORD3IARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3iARB")) == NULL) || r; + r = ((glMultiTexCoord3ivARB = (PFNGLMULTITEXCOORD3IVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3ivARB")) == NULL) || r; + r = ((glMultiTexCoord3sARB = (PFNGLMULTITEXCOORD3SARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3sARB")) == NULL) || r; + r = ((glMultiTexCoord3svARB = (PFNGLMULTITEXCOORD3SVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3svARB")) == NULL) || r; + r = ((glMultiTexCoord4dARB = (PFNGLMULTITEXCOORD4DARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4dARB")) == NULL) || r; + r = ((glMultiTexCoord4dvARB = (PFNGLMULTITEXCOORD4DVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4dvARB")) == NULL) || r; + r = ((glMultiTexCoord4fARB = (PFNGLMULTITEXCOORD4FARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4fARB")) == NULL) || r; + r = ((glMultiTexCoord4fvARB = (PFNGLMULTITEXCOORD4FVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4fvARB")) == NULL) || r; + r = ((glMultiTexCoord4iARB = (PFNGLMULTITEXCOORD4IARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4iARB")) == NULL) || r; + r = ((glMultiTexCoord4ivARB = (PFNGLMULTITEXCOORD4IVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4ivARB")) == NULL) || r; + r = ((glMultiTexCoord4sARB = (PFNGLMULTITEXCOORD4SARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4sARB")) == NULL) || r; + r = ((glMultiTexCoord4svARB = (PFNGLMULTITEXCOORD4SVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4svARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_multitexture */ + +#ifdef GL_ARB_occlusion_query + +static GLboolean _glewInit_GL_ARB_occlusion_query (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBeginQueryARB = (PFNGLBEGINQUERYARBPROC)glewGetProcAddress((const GLubyte*)"glBeginQueryARB")) == NULL) || r; + r = ((glDeleteQueriesARB = (PFNGLDELETEQUERIESARBPROC)glewGetProcAddress((const GLubyte*)"glDeleteQueriesARB")) == NULL) || r; + r = ((glEndQueryARB = (PFNGLENDQUERYARBPROC)glewGetProcAddress((const GLubyte*)"glEndQueryARB")) == NULL) || r; + r = ((glGenQueriesARB = (PFNGLGENQUERIESARBPROC)glewGetProcAddress((const GLubyte*)"glGenQueriesARB")) == NULL) || r; + r = ((glGetQueryObjectivARB = (PFNGLGETQUERYOBJECTIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjectivARB")) == NULL) || r; + r = ((glGetQueryObjectuivARB = (PFNGLGETQUERYOBJECTUIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjectuivARB")) == NULL) || r; + r = ((glGetQueryivARB = (PFNGLGETQUERYIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetQueryivARB")) == NULL) || r; + r = ((glIsQueryARB = (PFNGLISQUERYARBPROC)glewGetProcAddress((const GLubyte*)"glIsQueryARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_occlusion_query */ + +#ifdef GL_ARB_pixel_buffer_object + +#endif /* GL_ARB_pixel_buffer_object */ + +#ifdef GL_ARB_point_parameters + +static GLboolean _glewInit_GL_ARB_point_parameters (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glPointParameterfARB = (PFNGLPOINTPARAMETERFARBPROC)glewGetProcAddress((const GLubyte*)"glPointParameterfARB")) == NULL) || r; + r = ((glPointParameterfvARB = (PFNGLPOINTPARAMETERFVARBPROC)glewGetProcAddress((const GLubyte*)"glPointParameterfvARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_point_parameters */ + +#ifdef GL_ARB_point_sprite + +#endif /* GL_ARB_point_sprite */ + +#ifdef GL_ARB_shader_objects + +static GLboolean _glewInit_GL_ARB_shader_objects (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glAttachObjectARB = (PFNGLATTACHOBJECTARBPROC)glewGetProcAddress((const GLubyte*)"glAttachObjectARB")) == NULL) || r; + r = ((glCompileShaderARB = (PFNGLCOMPILESHADERARBPROC)glewGetProcAddress((const GLubyte*)"glCompileShaderARB")) == NULL) || r; + r = ((glCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC)glewGetProcAddress((const GLubyte*)"glCreateProgramObjectARB")) == NULL) || r; + r = ((glCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC)glewGetProcAddress((const GLubyte*)"glCreateShaderObjectARB")) == NULL) || r; + r = ((glDeleteObjectARB = (PFNGLDELETEOBJECTARBPROC)glewGetProcAddress((const GLubyte*)"glDeleteObjectARB")) == NULL) || r; + r = ((glDetachObjectARB = (PFNGLDETACHOBJECTARBPROC)glewGetProcAddress((const GLubyte*)"glDetachObjectARB")) == NULL) || r; + r = ((glGetActiveUniformARB = (PFNGLGETACTIVEUNIFORMARBPROC)glewGetProcAddress((const GLubyte*)"glGetActiveUniformARB")) == NULL) || r; + r = ((glGetAttachedObjectsARB = (PFNGLGETATTACHEDOBJECTSARBPROC)glewGetProcAddress((const GLubyte*)"glGetAttachedObjectsARB")) == NULL) || r; + r = ((glGetHandleARB = (PFNGLGETHANDLEARBPROC)glewGetProcAddress((const GLubyte*)"glGetHandleARB")) == NULL) || r; + r = ((glGetInfoLogARB = (PFNGLGETINFOLOGARBPROC)glewGetProcAddress((const GLubyte*)"glGetInfoLogARB")) == NULL) || r; + r = ((glGetObjectParameterfvARB = (PFNGLGETOBJECTPARAMETERFVARBPROC)glewGetProcAddress((const GLubyte*)"glGetObjectParameterfvARB")) == NULL) || r; + r = ((glGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetObjectParameterivARB")) == NULL) || r; + r = ((glGetShaderSourceARB = (PFNGLGETSHADERSOURCEARBPROC)glewGetProcAddress((const GLubyte*)"glGetShaderSourceARB")) == NULL) || r; + r = ((glGetUniformLocationARB = (PFNGLGETUNIFORMLOCATIONARBPROC)glewGetProcAddress((const GLubyte*)"glGetUniformLocationARB")) == NULL) || r; + r = ((glGetUniformfvARB = (PFNGLGETUNIFORMFVARBPROC)glewGetProcAddress((const GLubyte*)"glGetUniformfvARB")) == NULL) || r; + r = ((glGetUniformivARB = (PFNGLGETUNIFORMIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetUniformivARB")) == NULL) || r; + r = ((glLinkProgramARB = (PFNGLLINKPROGRAMARBPROC)glewGetProcAddress((const GLubyte*)"glLinkProgramARB")) == NULL) || r; + r = ((glShaderSourceARB = (PFNGLSHADERSOURCEARBPROC)glewGetProcAddress((const GLubyte*)"glShaderSourceARB")) == NULL) || r; + r = ((glUniform1fARB = (PFNGLUNIFORM1FARBPROC)glewGetProcAddress((const GLubyte*)"glUniform1fARB")) == NULL) || r; + r = ((glUniform1fvARB = (PFNGLUNIFORM1FVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform1fvARB")) == NULL) || r; + r = ((glUniform1iARB = (PFNGLUNIFORM1IARBPROC)glewGetProcAddress((const GLubyte*)"glUniform1iARB")) == NULL) || r; + r = ((glUniform1ivARB = (PFNGLUNIFORM1IVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform1ivARB")) == NULL) || r; + r = ((glUniform2fARB = (PFNGLUNIFORM2FARBPROC)glewGetProcAddress((const GLubyte*)"glUniform2fARB")) == NULL) || r; + r = ((glUniform2fvARB = (PFNGLUNIFORM2FVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform2fvARB")) == NULL) || r; + r = ((glUniform2iARB = (PFNGLUNIFORM2IARBPROC)glewGetProcAddress((const GLubyte*)"glUniform2iARB")) == NULL) || r; + r = ((glUniform2ivARB = (PFNGLUNIFORM2IVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform2ivARB")) == NULL) || r; + r = ((glUniform3fARB = (PFNGLUNIFORM3FARBPROC)glewGetProcAddress((const GLubyte*)"glUniform3fARB")) == NULL) || r; + r = ((glUniform3fvARB = (PFNGLUNIFORM3FVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform3fvARB")) == NULL) || r; + r = ((glUniform3iARB = (PFNGLUNIFORM3IARBPROC)glewGetProcAddress((const GLubyte*)"glUniform3iARB")) == NULL) || r; + r = ((glUniform3ivARB = (PFNGLUNIFORM3IVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform3ivARB")) == NULL) || r; + r = ((glUniform4fARB = (PFNGLUNIFORM4FARBPROC)glewGetProcAddress((const GLubyte*)"glUniform4fARB")) == NULL) || r; + r = ((glUniform4fvARB = (PFNGLUNIFORM4FVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform4fvARB")) == NULL) || r; + r = ((glUniform4iARB = (PFNGLUNIFORM4IARBPROC)glewGetProcAddress((const GLubyte*)"glUniform4iARB")) == NULL) || r; + r = ((glUniform4ivARB = (PFNGLUNIFORM4IVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform4ivARB")) == NULL) || r; + r = ((glUniformMatrix2fvARB = (PFNGLUNIFORMMATRIX2FVARBPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix2fvARB")) == NULL) || r; + r = ((glUniformMatrix3fvARB = (PFNGLUNIFORMMATRIX3FVARBPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix3fvARB")) == NULL) || r; + r = ((glUniformMatrix4fvARB = (PFNGLUNIFORMMATRIX4FVARBPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix4fvARB")) == NULL) || r; + r = ((glUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC)glewGetProcAddress((const GLubyte*)"glUseProgramObjectARB")) == NULL) || r; + r = ((glValidateProgramARB = (PFNGLVALIDATEPROGRAMARBPROC)glewGetProcAddress((const GLubyte*)"glValidateProgramARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_shader_objects */ + +#ifdef GL_ARB_shading_language_100 + +#endif /* GL_ARB_shading_language_100 */ + +#ifdef GL_ARB_shadow + +#endif /* GL_ARB_shadow */ + +#ifdef GL_ARB_shadow_ambient + +#endif /* GL_ARB_shadow_ambient */ + +#ifdef GL_ARB_texture_border_clamp + +#endif /* GL_ARB_texture_border_clamp */ + +#ifdef GL_ARB_texture_buffer_object + +static GLboolean _glewInit_GL_ARB_texture_buffer_object (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glTexBufferARB = (PFNGLTEXBUFFERARBPROC)glewGetProcAddress((const GLubyte*)"glTexBufferARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_texture_buffer_object */ + +#ifdef GL_ARB_texture_compression + +static GLboolean _glewInit_GL_ARB_texture_compression (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glCompressedTexImage1DARB = (PFNGLCOMPRESSEDTEXIMAGE1DARBPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexImage1DARB")) == NULL) || r; + r = ((glCompressedTexImage2DARB = (PFNGLCOMPRESSEDTEXIMAGE2DARBPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexImage2DARB")) == NULL) || r; + r = ((glCompressedTexImage3DARB = (PFNGLCOMPRESSEDTEXIMAGE3DARBPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexImage3DARB")) == NULL) || r; + r = ((glCompressedTexSubImage1DARB = (PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexSubImage1DARB")) == NULL) || r; + r = ((glCompressedTexSubImage2DARB = (PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexSubImage2DARB")) == NULL) || r; + r = ((glCompressedTexSubImage3DARB = (PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexSubImage3DARB")) == NULL) || r; + r = ((glGetCompressedTexImageARB = (PFNGLGETCOMPRESSEDTEXIMAGEARBPROC)glewGetProcAddress((const GLubyte*)"glGetCompressedTexImageARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_texture_compression */ + +#ifdef GL_ARB_texture_compression_rgtc + +#endif /* GL_ARB_texture_compression_rgtc */ + +#ifdef GL_ARB_texture_cube_map + +#endif /* GL_ARB_texture_cube_map */ + +#ifdef GL_ARB_texture_env_add + +#endif /* GL_ARB_texture_env_add */ + +#ifdef GL_ARB_texture_env_combine + +#endif /* GL_ARB_texture_env_combine */ + +#ifdef GL_ARB_texture_env_crossbar + +#endif /* GL_ARB_texture_env_crossbar */ + +#ifdef GL_ARB_texture_env_dot3 + +#endif /* GL_ARB_texture_env_dot3 */ + +#ifdef GL_ARB_texture_float + +#endif /* GL_ARB_texture_float */ + +#ifdef GL_ARB_texture_mirrored_repeat + +#endif /* GL_ARB_texture_mirrored_repeat */ + +#ifdef GL_ARB_texture_non_power_of_two + +#endif /* GL_ARB_texture_non_power_of_two */ + +#ifdef GL_ARB_texture_rectangle + +#endif /* GL_ARB_texture_rectangle */ + +#ifdef GL_ARB_texture_rg + +#endif /* GL_ARB_texture_rg */ + +#ifdef GL_ARB_transpose_matrix + +static GLboolean _glewInit_GL_ARB_transpose_matrix (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glLoadTransposeMatrixdARB = (PFNGLLOADTRANSPOSEMATRIXDARBPROC)glewGetProcAddress((const GLubyte*)"glLoadTransposeMatrixdARB")) == NULL) || r; + r = ((glLoadTransposeMatrixfARB = (PFNGLLOADTRANSPOSEMATRIXFARBPROC)glewGetProcAddress((const GLubyte*)"glLoadTransposeMatrixfARB")) == NULL) || r; + r = ((glMultTransposeMatrixdARB = (PFNGLMULTTRANSPOSEMATRIXDARBPROC)glewGetProcAddress((const GLubyte*)"glMultTransposeMatrixdARB")) == NULL) || r; + r = ((glMultTransposeMatrixfARB = (PFNGLMULTTRANSPOSEMATRIXFARBPROC)glewGetProcAddress((const GLubyte*)"glMultTransposeMatrixfARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_transpose_matrix */ + +#ifdef GL_ARB_vertex_array_object + +static GLboolean _glewInit_GL_ARB_vertex_array_object (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC)glewGetProcAddress((const GLubyte*)"glBindVertexArray")) == NULL) || r; + r = ((glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC)glewGetProcAddress((const GLubyte*)"glDeleteVertexArrays")) == NULL) || r; + r = ((glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)glewGetProcAddress((const GLubyte*)"glGenVertexArrays")) == NULL) || r; + r = ((glIsVertexArray = (PFNGLISVERTEXARRAYPROC)glewGetProcAddress((const GLubyte*)"glIsVertexArray")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_vertex_array_object */ + +#ifdef GL_ARB_vertex_blend + +static GLboolean _glewInit_GL_ARB_vertex_blend (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glVertexBlendARB = (PFNGLVERTEXBLENDARBPROC)glewGetProcAddress((const GLubyte*)"glVertexBlendARB")) == NULL) || r; + r = ((glWeightPointerARB = (PFNGLWEIGHTPOINTERARBPROC)glewGetProcAddress((const GLubyte*)"glWeightPointerARB")) == NULL) || r; + r = ((glWeightbvARB = (PFNGLWEIGHTBVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightbvARB")) == NULL) || r; + r = ((glWeightdvARB = (PFNGLWEIGHTDVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightdvARB")) == NULL) || r; + r = ((glWeightfvARB = (PFNGLWEIGHTFVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightfvARB")) == NULL) || r; + r = ((glWeightivARB = (PFNGLWEIGHTIVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightivARB")) == NULL) || r; + r = ((glWeightsvARB = (PFNGLWEIGHTSVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightsvARB")) == NULL) || r; + r = ((glWeightubvARB = (PFNGLWEIGHTUBVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightubvARB")) == NULL) || r; + r = ((glWeightuivARB = (PFNGLWEIGHTUIVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightuivARB")) == NULL) || r; + r = ((glWeightusvARB = (PFNGLWEIGHTUSVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightusvARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_vertex_blend */ + +#ifdef GL_ARB_vertex_buffer_object + +static GLboolean _glewInit_GL_ARB_vertex_buffer_object (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBindBufferARB = (PFNGLBINDBUFFERARBPROC)glewGetProcAddress((const GLubyte*)"glBindBufferARB")) == NULL) || r; + r = ((glBufferDataARB = (PFNGLBUFFERDATAARBPROC)glewGetProcAddress((const GLubyte*)"glBufferDataARB")) == NULL) || r; + r = ((glBufferSubDataARB = (PFNGLBUFFERSUBDATAARBPROC)glewGetProcAddress((const GLubyte*)"glBufferSubDataARB")) == NULL) || r; + r = ((glDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC)glewGetProcAddress((const GLubyte*)"glDeleteBuffersARB")) == NULL) || r; + r = ((glGenBuffersARB = (PFNGLGENBUFFERSARBPROC)glewGetProcAddress((const GLubyte*)"glGenBuffersARB")) == NULL) || r; + r = ((glGetBufferParameterivARB = (PFNGLGETBUFFERPARAMETERIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetBufferParameterivARB")) == NULL) || r; + r = ((glGetBufferPointervARB = (PFNGLGETBUFFERPOINTERVARBPROC)glewGetProcAddress((const GLubyte*)"glGetBufferPointervARB")) == NULL) || r; + r = ((glGetBufferSubDataARB = (PFNGLGETBUFFERSUBDATAARBPROC)glewGetProcAddress((const GLubyte*)"glGetBufferSubDataARB")) == NULL) || r; + r = ((glIsBufferARB = (PFNGLISBUFFERARBPROC)glewGetProcAddress((const GLubyte*)"glIsBufferARB")) == NULL) || r; + r = ((glMapBufferARB = (PFNGLMAPBUFFERARBPROC)glewGetProcAddress((const GLubyte*)"glMapBufferARB")) == NULL) || r; + r = ((glUnmapBufferARB = (PFNGLUNMAPBUFFERARBPROC)glewGetProcAddress((const GLubyte*)"glUnmapBufferARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_vertex_buffer_object */ + +#ifdef GL_ARB_vertex_program + +static GLboolean _glewInit_GL_ARB_vertex_program (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBindProgramARB = (PFNGLBINDPROGRAMARBPROC)glewGetProcAddress((const GLubyte*)"glBindProgramARB")) == NULL) || r; + r = ((glDeleteProgramsARB = (PFNGLDELETEPROGRAMSARBPROC)glewGetProcAddress((const GLubyte*)"glDeleteProgramsARB")) == NULL) || r; + r = ((glDisableVertexAttribArrayARB = (PFNGLDISABLEVERTEXATTRIBARRAYARBPROC)glewGetProcAddress((const GLubyte*)"glDisableVertexAttribArrayARB")) == NULL) || r; + r = ((glEnableVertexAttribArrayARB = (PFNGLENABLEVERTEXATTRIBARRAYARBPROC)glewGetProcAddress((const GLubyte*)"glEnableVertexAttribArrayARB")) == NULL) || r; + r = ((glGenProgramsARB = (PFNGLGENPROGRAMSARBPROC)glewGetProcAddress((const GLubyte*)"glGenProgramsARB")) == NULL) || r; + r = ((glGetProgramEnvParameterdvARB = (PFNGLGETPROGRAMENVPARAMETERDVARBPROC)glewGetProcAddress((const GLubyte*)"glGetProgramEnvParameterdvARB")) == NULL) || r; + r = ((glGetProgramEnvParameterfvARB = (PFNGLGETPROGRAMENVPARAMETERFVARBPROC)glewGetProcAddress((const GLubyte*)"glGetProgramEnvParameterfvARB")) == NULL) || r; + r = ((glGetProgramLocalParameterdvARB = (PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC)glewGetProcAddress((const GLubyte*)"glGetProgramLocalParameterdvARB")) == NULL) || r; + r = ((glGetProgramLocalParameterfvARB = (PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC)glewGetProcAddress((const GLubyte*)"glGetProgramLocalParameterfvARB")) == NULL) || r; + r = ((glGetProgramStringARB = (PFNGLGETPROGRAMSTRINGARBPROC)glewGetProcAddress((const GLubyte*)"glGetProgramStringARB")) == NULL) || r; + r = ((glGetProgramivARB = (PFNGLGETPROGRAMIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetProgramivARB")) == NULL) || r; + r = ((glGetVertexAttribPointervARB = (PFNGLGETVERTEXATTRIBPOINTERVARBPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribPointervARB")) == NULL) || r; + r = ((glGetVertexAttribdvARB = (PFNGLGETVERTEXATTRIBDVARBPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribdvARB")) == NULL) || r; + r = ((glGetVertexAttribfvARB = (PFNGLGETVERTEXATTRIBFVARBPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribfvARB")) == NULL) || r; + r = ((glGetVertexAttribivARB = (PFNGLGETVERTEXATTRIBIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribivARB")) == NULL) || r; + r = ((glIsProgramARB = (PFNGLISPROGRAMARBPROC)glewGetProcAddress((const GLubyte*)"glIsProgramARB")) == NULL) || r; + r = ((glProgramEnvParameter4dARB = (PFNGLPROGRAMENVPARAMETER4DARBPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameter4dARB")) == NULL) || r; + r = ((glProgramEnvParameter4dvARB = (PFNGLPROGRAMENVPARAMETER4DVARBPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameter4dvARB")) == NULL) || r; + r = ((glProgramEnvParameter4fARB = (PFNGLPROGRAMENVPARAMETER4FARBPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameter4fARB")) == NULL) || r; + r = ((glProgramEnvParameter4fvARB = (PFNGLPROGRAMENVPARAMETER4FVARBPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameter4fvARB")) == NULL) || r; + r = ((glProgramLocalParameter4dARB = (PFNGLPROGRAMLOCALPARAMETER4DARBPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameter4dARB")) == NULL) || r; + r = ((glProgramLocalParameter4dvARB = (PFNGLPROGRAMLOCALPARAMETER4DVARBPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameter4dvARB")) == NULL) || r; + r = ((glProgramLocalParameter4fARB = (PFNGLPROGRAMLOCALPARAMETER4FARBPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameter4fARB")) == NULL) || r; + r = ((glProgramLocalParameter4fvARB = (PFNGLPROGRAMLOCALPARAMETER4FVARBPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameter4fvARB")) == NULL) || r; + r = ((glProgramStringARB = (PFNGLPROGRAMSTRINGARBPROC)glewGetProcAddress((const GLubyte*)"glProgramStringARB")) == NULL) || r; + r = ((glVertexAttrib1dARB = (PFNGLVERTEXATTRIB1DARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1dARB")) == NULL) || r; + r = ((glVertexAttrib1dvARB = (PFNGLVERTEXATTRIB1DVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1dvARB")) == NULL) || r; + r = ((glVertexAttrib1fARB = (PFNGLVERTEXATTRIB1FARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1fARB")) == NULL) || r; + r = ((glVertexAttrib1fvARB = (PFNGLVERTEXATTRIB1FVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1fvARB")) == NULL) || r; + r = ((glVertexAttrib1sARB = (PFNGLVERTEXATTRIB1SARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1sARB")) == NULL) || r; + r = ((glVertexAttrib1svARB = (PFNGLVERTEXATTRIB1SVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1svARB")) == NULL) || r; + r = ((glVertexAttrib2dARB = (PFNGLVERTEXATTRIB2DARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2dARB")) == NULL) || r; + r = ((glVertexAttrib2dvARB = (PFNGLVERTEXATTRIB2DVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2dvARB")) == NULL) || r; + r = ((glVertexAttrib2fARB = (PFNGLVERTEXATTRIB2FARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2fARB")) == NULL) || r; + r = ((glVertexAttrib2fvARB = (PFNGLVERTEXATTRIB2FVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2fvARB")) == NULL) || r; + r = ((glVertexAttrib2sARB = (PFNGLVERTEXATTRIB2SARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2sARB")) == NULL) || r; + r = ((glVertexAttrib2svARB = (PFNGLVERTEXATTRIB2SVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2svARB")) == NULL) || r; + r = ((glVertexAttrib3dARB = (PFNGLVERTEXATTRIB3DARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3dARB")) == NULL) || r; + r = ((glVertexAttrib3dvARB = (PFNGLVERTEXATTRIB3DVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3dvARB")) == NULL) || r; + r = ((glVertexAttrib3fARB = (PFNGLVERTEXATTRIB3FARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3fARB")) == NULL) || r; + r = ((glVertexAttrib3fvARB = (PFNGLVERTEXATTRIB3FVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3fvARB")) == NULL) || r; + r = ((glVertexAttrib3sARB = (PFNGLVERTEXATTRIB3SARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3sARB")) == NULL) || r; + r = ((glVertexAttrib3svARB = (PFNGLVERTEXATTRIB3SVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3svARB")) == NULL) || r; + r = ((glVertexAttrib4NbvARB = (PFNGLVERTEXATTRIB4NBVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4NbvARB")) == NULL) || r; + r = ((glVertexAttrib4NivARB = (PFNGLVERTEXATTRIB4NIVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4NivARB")) == NULL) || r; + r = ((glVertexAttrib4NsvARB = (PFNGLVERTEXATTRIB4NSVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4NsvARB")) == NULL) || r; + r = ((glVertexAttrib4NubARB = (PFNGLVERTEXATTRIB4NUBARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4NubARB")) == NULL) || r; + r = ((glVertexAttrib4NubvARB = (PFNGLVERTEXATTRIB4NUBVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4NubvARB")) == NULL) || r; + r = ((glVertexAttrib4NuivARB = (PFNGLVERTEXATTRIB4NUIVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4NuivARB")) == NULL) || r; + r = ((glVertexAttrib4NusvARB = (PFNGLVERTEXATTRIB4NUSVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4NusvARB")) == NULL) || r; + r = ((glVertexAttrib4bvARB = (PFNGLVERTEXATTRIB4BVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4bvARB")) == NULL) || r; + r = ((glVertexAttrib4dARB = (PFNGLVERTEXATTRIB4DARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4dARB")) == NULL) || r; + r = ((glVertexAttrib4dvARB = (PFNGLVERTEXATTRIB4DVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4dvARB")) == NULL) || r; + r = ((glVertexAttrib4fARB = (PFNGLVERTEXATTRIB4FARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4fARB")) == NULL) || r; + r = ((glVertexAttrib4fvARB = (PFNGLVERTEXATTRIB4FVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4fvARB")) == NULL) || r; + r = ((glVertexAttrib4ivARB = (PFNGLVERTEXATTRIB4IVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4ivARB")) == NULL) || r; + r = ((glVertexAttrib4sARB = (PFNGLVERTEXATTRIB4SARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4sARB")) == NULL) || r; + r = ((glVertexAttrib4svARB = (PFNGLVERTEXATTRIB4SVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4svARB")) == NULL) || r; + r = ((glVertexAttrib4ubvARB = (PFNGLVERTEXATTRIB4UBVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4ubvARB")) == NULL) || r; + r = ((glVertexAttrib4uivARB = (PFNGLVERTEXATTRIB4UIVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4uivARB")) == NULL) || r; + r = ((glVertexAttrib4usvARB = (PFNGLVERTEXATTRIB4USVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4usvARB")) == NULL) || r; + r = ((glVertexAttribPointerARB = (PFNGLVERTEXATTRIBPOINTERARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribPointerARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_vertex_program */ + +#ifdef GL_ARB_vertex_shader + +static GLboolean _glewInit_GL_ARB_vertex_shader (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBindAttribLocationARB = (PFNGLBINDATTRIBLOCATIONARBPROC)glewGetProcAddress((const GLubyte*)"glBindAttribLocationARB")) == NULL) || r; + r = ((glGetActiveAttribARB = (PFNGLGETACTIVEATTRIBARBPROC)glewGetProcAddress((const GLubyte*)"glGetActiveAttribARB")) == NULL) || r; + r = ((glGetAttribLocationARB = (PFNGLGETATTRIBLOCATIONARBPROC)glewGetProcAddress((const GLubyte*)"glGetAttribLocationARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_vertex_shader */ + +#ifdef GL_ARB_window_pos + +static GLboolean _glewInit_GL_ARB_window_pos (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glWindowPos2dARB = (PFNGLWINDOWPOS2DARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2dARB")) == NULL) || r; + r = ((glWindowPos2dvARB = (PFNGLWINDOWPOS2DVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2dvARB")) == NULL) || r; + r = ((glWindowPos2fARB = (PFNGLWINDOWPOS2FARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2fARB")) == NULL) || r; + r = ((glWindowPos2fvARB = (PFNGLWINDOWPOS2FVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2fvARB")) == NULL) || r; + r = ((glWindowPos2iARB = (PFNGLWINDOWPOS2IARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2iARB")) == NULL) || r; + r = ((glWindowPos2ivARB = (PFNGLWINDOWPOS2IVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2ivARB")) == NULL) || r; + r = ((glWindowPos2sARB = (PFNGLWINDOWPOS2SARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2sARB")) == NULL) || r; + r = ((glWindowPos2svARB = (PFNGLWINDOWPOS2SVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2svARB")) == NULL) || r; + r = ((glWindowPos3dARB = (PFNGLWINDOWPOS3DARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3dARB")) == NULL) || r; + r = ((glWindowPos3dvARB = (PFNGLWINDOWPOS3DVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3dvARB")) == NULL) || r; + r = ((glWindowPos3fARB = (PFNGLWINDOWPOS3FARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3fARB")) == NULL) || r; + r = ((glWindowPos3fvARB = (PFNGLWINDOWPOS3FVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3fvARB")) == NULL) || r; + r = ((glWindowPos3iARB = (PFNGLWINDOWPOS3IARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3iARB")) == NULL) || r; + r = ((glWindowPos3ivARB = (PFNGLWINDOWPOS3IVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3ivARB")) == NULL) || r; + r = ((glWindowPos3sARB = (PFNGLWINDOWPOS3SARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3sARB")) == NULL) || r; + r = ((glWindowPos3svARB = (PFNGLWINDOWPOS3SVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3svARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_window_pos */ + +#ifdef GL_ATIX_point_sprites + +#endif /* GL_ATIX_point_sprites */ + +#ifdef GL_ATIX_texture_env_combine3 + +#endif /* GL_ATIX_texture_env_combine3 */ + +#ifdef GL_ATIX_texture_env_route + +#endif /* GL_ATIX_texture_env_route */ + +#ifdef GL_ATIX_vertex_shader_output_point_size + +#endif /* GL_ATIX_vertex_shader_output_point_size */ + +#ifdef GL_ATI_draw_buffers + +static GLboolean _glewInit_GL_ATI_draw_buffers (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glDrawBuffersATI = (PFNGLDRAWBUFFERSATIPROC)glewGetProcAddress((const GLubyte*)"glDrawBuffersATI")) == NULL) || r; + + return r; +} + +#endif /* GL_ATI_draw_buffers */ + +#ifdef GL_ATI_element_array + +static GLboolean _glewInit_GL_ATI_element_array (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glDrawElementArrayATI = (PFNGLDRAWELEMENTARRAYATIPROC)glewGetProcAddress((const GLubyte*)"glDrawElementArrayATI")) == NULL) || r; + r = ((glDrawRangeElementArrayATI = (PFNGLDRAWRANGEELEMENTARRAYATIPROC)glewGetProcAddress((const GLubyte*)"glDrawRangeElementArrayATI")) == NULL) || r; + r = ((glElementPointerATI = (PFNGLELEMENTPOINTERATIPROC)glewGetProcAddress((const GLubyte*)"glElementPointerATI")) == NULL) || r; + + return r; +} + +#endif /* GL_ATI_element_array */ + +#ifdef GL_ATI_envmap_bumpmap + +static GLboolean _glewInit_GL_ATI_envmap_bumpmap (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetTexBumpParameterfvATI = (PFNGLGETTEXBUMPPARAMETERFVATIPROC)glewGetProcAddress((const GLubyte*)"glGetTexBumpParameterfvATI")) == NULL) || r; + r = ((glGetTexBumpParameterivATI = (PFNGLGETTEXBUMPPARAMETERIVATIPROC)glewGetProcAddress((const GLubyte*)"glGetTexBumpParameterivATI")) == NULL) || r; + r = ((glTexBumpParameterfvATI = (PFNGLTEXBUMPPARAMETERFVATIPROC)glewGetProcAddress((const GLubyte*)"glTexBumpParameterfvATI")) == NULL) || r; + r = ((glTexBumpParameterivATI = (PFNGLTEXBUMPPARAMETERIVATIPROC)glewGetProcAddress((const GLubyte*)"glTexBumpParameterivATI")) == NULL) || r; + + return r; +} + +#endif /* GL_ATI_envmap_bumpmap */ + +#ifdef GL_ATI_fragment_shader + +static GLboolean _glewInit_GL_ATI_fragment_shader (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glAlphaFragmentOp1ATI = (PFNGLALPHAFRAGMENTOP1ATIPROC)glewGetProcAddress((const GLubyte*)"glAlphaFragmentOp1ATI")) == NULL) || r; + r = ((glAlphaFragmentOp2ATI = (PFNGLALPHAFRAGMENTOP2ATIPROC)glewGetProcAddress((const GLubyte*)"glAlphaFragmentOp2ATI")) == NULL) || r; + r = ((glAlphaFragmentOp3ATI = (PFNGLALPHAFRAGMENTOP3ATIPROC)glewGetProcAddress((const GLubyte*)"glAlphaFragmentOp3ATI")) == NULL) || r; + r = ((glBeginFragmentShaderATI = (PFNGLBEGINFRAGMENTSHADERATIPROC)glewGetProcAddress((const GLubyte*)"glBeginFragmentShaderATI")) == NULL) || r; + r = ((glBindFragmentShaderATI = (PFNGLBINDFRAGMENTSHADERATIPROC)glewGetProcAddress((const GLubyte*)"glBindFragmentShaderATI")) == NULL) || r; + r = ((glColorFragmentOp1ATI = (PFNGLCOLORFRAGMENTOP1ATIPROC)glewGetProcAddress((const GLubyte*)"glColorFragmentOp1ATI")) == NULL) || r; + r = ((glColorFragmentOp2ATI = (PFNGLCOLORFRAGMENTOP2ATIPROC)glewGetProcAddress((const GLubyte*)"glColorFragmentOp2ATI")) == NULL) || r; + r = ((glColorFragmentOp3ATI = (PFNGLCOLORFRAGMENTOP3ATIPROC)glewGetProcAddress((const GLubyte*)"glColorFragmentOp3ATI")) == NULL) || r; + r = ((glDeleteFragmentShaderATI = (PFNGLDELETEFRAGMENTSHADERATIPROC)glewGetProcAddress((const GLubyte*)"glDeleteFragmentShaderATI")) == NULL) || r; + r = ((glEndFragmentShaderATI = (PFNGLENDFRAGMENTSHADERATIPROC)glewGetProcAddress((const GLubyte*)"glEndFragmentShaderATI")) == NULL) || r; + r = ((glGenFragmentShadersATI = (PFNGLGENFRAGMENTSHADERSATIPROC)glewGetProcAddress((const GLubyte*)"glGenFragmentShadersATI")) == NULL) || r; + r = ((glPassTexCoordATI = (PFNGLPASSTEXCOORDATIPROC)glewGetProcAddress((const GLubyte*)"glPassTexCoordATI")) == NULL) || r; + r = ((glSampleMapATI = (PFNGLSAMPLEMAPATIPROC)glewGetProcAddress((const GLubyte*)"glSampleMapATI")) == NULL) || r; + r = ((glSetFragmentShaderConstantATI = (PFNGLSETFRAGMENTSHADERCONSTANTATIPROC)glewGetProcAddress((const GLubyte*)"glSetFragmentShaderConstantATI")) == NULL) || r; + + return r; +} + +#endif /* GL_ATI_fragment_shader */ + +#ifdef GL_ATI_map_object_buffer + +static GLboolean _glewInit_GL_ATI_map_object_buffer (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glMapObjectBufferATI = (PFNGLMAPOBJECTBUFFERATIPROC)glewGetProcAddress((const GLubyte*)"glMapObjectBufferATI")) == NULL) || r; + r = ((glUnmapObjectBufferATI = (PFNGLUNMAPOBJECTBUFFERATIPROC)glewGetProcAddress((const GLubyte*)"glUnmapObjectBufferATI")) == NULL) || r; + + return r; +} + +#endif /* GL_ATI_map_object_buffer */ + +#ifdef GL_ATI_pn_triangles + +static GLboolean _glewInit_GL_ATI_pn_triangles (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glPNTrianglesfATI = (PFNGLPNTRIANGLESFATIPROC)glewGetProcAddress((const GLubyte*)"glPNTrianglesfATI")) == NULL) || r; + r = ((glPNTrianglesiATI = (PFNGLPNTRIANGLESIATIPROC)glewGetProcAddress((const GLubyte*)"glPNTrianglesiATI")) == NULL) || r; + + return r; +} + +#endif /* GL_ATI_pn_triangles */ + +#ifdef GL_ATI_separate_stencil + +static GLboolean _glewInit_GL_ATI_separate_stencil (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glStencilFuncSeparateATI = (PFNGLSTENCILFUNCSEPARATEATIPROC)glewGetProcAddress((const GLubyte*)"glStencilFuncSeparateATI")) == NULL) || r; + r = ((glStencilOpSeparateATI = (PFNGLSTENCILOPSEPARATEATIPROC)glewGetProcAddress((const GLubyte*)"glStencilOpSeparateATI")) == NULL) || r; + + return r; +} + +#endif /* GL_ATI_separate_stencil */ + +#ifdef GL_ATI_shader_texture_lod + +#endif /* GL_ATI_shader_texture_lod */ + +#ifdef GL_ATI_text_fragment_shader + +#endif /* GL_ATI_text_fragment_shader */ + +#ifdef GL_ATI_texture_compression_3dc + +#endif /* GL_ATI_texture_compression_3dc */ + +#ifdef GL_ATI_texture_env_combine3 + +#endif /* GL_ATI_texture_env_combine3 */ + +#ifdef GL_ATI_texture_float + +#endif /* GL_ATI_texture_float */ + +#ifdef GL_ATI_texture_mirror_once + +#endif /* GL_ATI_texture_mirror_once */ + +#ifdef GL_ATI_vertex_array_object + +static GLboolean _glewInit_GL_ATI_vertex_array_object (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glArrayObjectATI = (PFNGLARRAYOBJECTATIPROC)glewGetProcAddress((const GLubyte*)"glArrayObjectATI")) == NULL) || r; + r = ((glFreeObjectBufferATI = (PFNGLFREEOBJECTBUFFERATIPROC)glewGetProcAddress((const GLubyte*)"glFreeObjectBufferATI")) == NULL) || r; + r = ((glGetArrayObjectfvATI = (PFNGLGETARRAYOBJECTFVATIPROC)glewGetProcAddress((const GLubyte*)"glGetArrayObjectfvATI")) == NULL) || r; + r = ((glGetArrayObjectivATI = (PFNGLGETARRAYOBJECTIVATIPROC)glewGetProcAddress((const GLubyte*)"glGetArrayObjectivATI")) == NULL) || r; + r = ((glGetObjectBufferfvATI = (PFNGLGETOBJECTBUFFERFVATIPROC)glewGetProcAddress((const GLubyte*)"glGetObjectBufferfvATI")) == NULL) || r; + r = ((glGetObjectBufferivATI = (PFNGLGETOBJECTBUFFERIVATIPROC)glewGetProcAddress((const GLubyte*)"glGetObjectBufferivATI")) == NULL) || r; + r = ((glGetVariantArrayObjectfvATI = (PFNGLGETVARIANTARRAYOBJECTFVATIPROC)glewGetProcAddress((const GLubyte*)"glGetVariantArrayObjectfvATI")) == NULL) || r; + r = ((glGetVariantArrayObjectivATI = (PFNGLGETVARIANTARRAYOBJECTIVATIPROC)glewGetProcAddress((const GLubyte*)"glGetVariantArrayObjectivATI")) == NULL) || r; + r = ((glIsObjectBufferATI = (PFNGLISOBJECTBUFFERATIPROC)glewGetProcAddress((const GLubyte*)"glIsObjectBufferATI")) == NULL) || r; + r = ((glNewObjectBufferATI = (PFNGLNEWOBJECTBUFFERATIPROC)glewGetProcAddress((const GLubyte*)"glNewObjectBufferATI")) == NULL) || r; + r = ((glUpdateObjectBufferATI = (PFNGLUPDATEOBJECTBUFFERATIPROC)glewGetProcAddress((const GLubyte*)"glUpdateObjectBufferATI")) == NULL) || r; + r = ((glVariantArrayObjectATI = (PFNGLVARIANTARRAYOBJECTATIPROC)glewGetProcAddress((const GLubyte*)"glVariantArrayObjectATI")) == NULL) || r; + + return r; +} + +#endif /* GL_ATI_vertex_array_object */ + +#ifdef GL_ATI_vertex_attrib_array_object + +static GLboolean _glewInit_GL_ATI_vertex_attrib_array_object (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetVertexAttribArrayObjectfvATI = (PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribArrayObjectfvATI")) == NULL) || r; + r = ((glGetVertexAttribArrayObjectivATI = (PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribArrayObjectivATI")) == NULL) || r; + r = ((glVertexAttribArrayObjectATI = (PFNGLVERTEXATTRIBARRAYOBJECTATIPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribArrayObjectATI")) == NULL) || r; + + return r; +} + +#endif /* GL_ATI_vertex_attrib_array_object */ + +#ifdef GL_ATI_vertex_streams + +static GLboolean _glewInit_GL_ATI_vertex_streams (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glClientActiveVertexStreamATI = (PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC)glewGetProcAddress((const GLubyte*)"glClientActiveVertexStreamATI")) == NULL) || r; + r = ((glNormalStream3bATI = (PFNGLNORMALSTREAM3BATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3bATI")) == NULL) || r; + r = ((glNormalStream3bvATI = (PFNGLNORMALSTREAM3BVATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3bvATI")) == NULL) || r; + r = ((glNormalStream3dATI = (PFNGLNORMALSTREAM3DATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3dATI")) == NULL) || r; + r = ((glNormalStream3dvATI = (PFNGLNORMALSTREAM3DVATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3dvATI")) == NULL) || r; + r = ((glNormalStream3fATI = (PFNGLNORMALSTREAM3FATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3fATI")) == NULL) || r; + r = ((glNormalStream3fvATI = (PFNGLNORMALSTREAM3FVATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3fvATI")) == NULL) || r; + r = ((glNormalStream3iATI = (PFNGLNORMALSTREAM3IATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3iATI")) == NULL) || r; + r = ((glNormalStream3ivATI = (PFNGLNORMALSTREAM3IVATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3ivATI")) == NULL) || r; + r = ((glNormalStream3sATI = (PFNGLNORMALSTREAM3SATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3sATI")) == NULL) || r; + r = ((glNormalStream3svATI = (PFNGLNORMALSTREAM3SVATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3svATI")) == NULL) || r; + r = ((glVertexBlendEnvfATI = (PFNGLVERTEXBLENDENVFATIPROC)glewGetProcAddress((const GLubyte*)"glVertexBlendEnvfATI")) == NULL) || r; + r = ((glVertexBlendEnviATI = (PFNGLVERTEXBLENDENVIATIPROC)glewGetProcAddress((const GLubyte*)"glVertexBlendEnviATI")) == NULL) || r; + r = ((glVertexStream2dATI = (PFNGLVERTEXSTREAM2DATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2dATI")) == NULL) || r; + r = ((glVertexStream2dvATI = (PFNGLVERTEXSTREAM2DVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2dvATI")) == NULL) || r; + r = ((glVertexStream2fATI = (PFNGLVERTEXSTREAM2FATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2fATI")) == NULL) || r; + r = ((glVertexStream2fvATI = (PFNGLVERTEXSTREAM2FVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2fvATI")) == NULL) || r; + r = ((glVertexStream2iATI = (PFNGLVERTEXSTREAM2IATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2iATI")) == NULL) || r; + r = ((glVertexStream2ivATI = (PFNGLVERTEXSTREAM2IVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2ivATI")) == NULL) || r; + r = ((glVertexStream2sATI = (PFNGLVERTEXSTREAM2SATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2sATI")) == NULL) || r; + r = ((glVertexStream2svATI = (PFNGLVERTEXSTREAM2SVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2svATI")) == NULL) || r; + r = ((glVertexStream3dATI = (PFNGLVERTEXSTREAM3DATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3dATI")) == NULL) || r; + r = ((glVertexStream3dvATI = (PFNGLVERTEXSTREAM3DVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3dvATI")) == NULL) || r; + r = ((glVertexStream3fATI = (PFNGLVERTEXSTREAM3FATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3fATI")) == NULL) || r; + r = ((glVertexStream3fvATI = (PFNGLVERTEXSTREAM3FVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3fvATI")) == NULL) || r; + r = ((glVertexStream3iATI = (PFNGLVERTEXSTREAM3IATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3iATI")) == NULL) || r; + r = ((glVertexStream3ivATI = (PFNGLVERTEXSTREAM3IVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3ivATI")) == NULL) || r; + r = ((glVertexStream3sATI = (PFNGLVERTEXSTREAM3SATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3sATI")) == NULL) || r; + r = ((glVertexStream3svATI = (PFNGLVERTEXSTREAM3SVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3svATI")) == NULL) || r; + r = ((glVertexStream4dATI = (PFNGLVERTEXSTREAM4DATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4dATI")) == NULL) || r; + r = ((glVertexStream4dvATI = (PFNGLVERTEXSTREAM4DVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4dvATI")) == NULL) || r; + r = ((glVertexStream4fATI = (PFNGLVERTEXSTREAM4FATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4fATI")) == NULL) || r; + r = ((glVertexStream4fvATI = (PFNGLVERTEXSTREAM4FVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4fvATI")) == NULL) || r; + r = ((glVertexStream4iATI = (PFNGLVERTEXSTREAM4IATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4iATI")) == NULL) || r; + r = ((glVertexStream4ivATI = (PFNGLVERTEXSTREAM4IVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4ivATI")) == NULL) || r; + r = ((glVertexStream4sATI = (PFNGLVERTEXSTREAM4SATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4sATI")) == NULL) || r; + r = ((glVertexStream4svATI = (PFNGLVERTEXSTREAM4SVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4svATI")) == NULL) || r; + + return r; +} + +#endif /* GL_ATI_vertex_streams */ + +#ifdef GL_EXT_422_pixels + +#endif /* GL_EXT_422_pixels */ + +#ifdef GL_EXT_Cg_shader + +#endif /* GL_EXT_Cg_shader */ + +#ifdef GL_EXT_abgr + +#endif /* GL_EXT_abgr */ + +#ifdef GL_EXT_bgra + +#endif /* GL_EXT_bgra */ + +#ifdef GL_EXT_bindable_uniform + +static GLboolean _glewInit_GL_EXT_bindable_uniform (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetUniformBufferSizeEXT = (PFNGLGETUNIFORMBUFFERSIZEEXTPROC)glewGetProcAddress((const GLubyte*)"glGetUniformBufferSizeEXT")) == NULL) || r; + r = ((glGetUniformOffsetEXT = (PFNGLGETUNIFORMOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glGetUniformOffsetEXT")) == NULL) || r; + r = ((glUniformBufferEXT = (PFNGLUNIFORMBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glUniformBufferEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_bindable_uniform */ + +#ifdef GL_EXT_blend_color + +static GLboolean _glewInit_GL_EXT_blend_color (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBlendColorEXT = (PFNGLBLENDCOLOREXTPROC)glewGetProcAddress((const GLubyte*)"glBlendColorEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_blend_color */ + +#ifdef GL_EXT_blend_equation_separate + +static GLboolean _glewInit_GL_EXT_blend_equation_separate (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBlendEquationSeparateEXT = (PFNGLBLENDEQUATIONSEPARATEEXTPROC)glewGetProcAddress((const GLubyte*)"glBlendEquationSeparateEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_blend_equation_separate */ + +#ifdef GL_EXT_blend_func_separate + +static GLboolean _glewInit_GL_EXT_blend_func_separate (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBlendFuncSeparateEXT = (PFNGLBLENDFUNCSEPARATEEXTPROC)glewGetProcAddress((const GLubyte*)"glBlendFuncSeparateEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_blend_func_separate */ + +#ifdef GL_EXT_blend_logic_op + +#endif /* GL_EXT_blend_logic_op */ + +#ifdef GL_EXT_blend_minmax + +static GLboolean _glewInit_GL_EXT_blend_minmax (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBlendEquationEXT = (PFNGLBLENDEQUATIONEXTPROC)glewGetProcAddress((const GLubyte*)"glBlendEquationEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_blend_minmax */ + +#ifdef GL_EXT_blend_subtract + +#endif /* GL_EXT_blend_subtract */ + +#ifdef GL_EXT_clip_volume_hint + +#endif /* GL_EXT_clip_volume_hint */ + +#ifdef GL_EXT_cmyka + +#endif /* GL_EXT_cmyka */ + +#ifdef GL_EXT_color_subtable + +static GLboolean _glewInit_GL_EXT_color_subtable (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glColorSubTableEXT = (PFNGLCOLORSUBTABLEEXTPROC)glewGetProcAddress((const GLubyte*)"glColorSubTableEXT")) == NULL) || r; + r = ((glCopyColorSubTableEXT = (PFNGLCOPYCOLORSUBTABLEEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyColorSubTableEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_color_subtable */ + +#ifdef GL_EXT_compiled_vertex_array + +static GLboolean _glewInit_GL_EXT_compiled_vertex_array (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glLockArraysEXT = (PFNGLLOCKARRAYSEXTPROC)glewGetProcAddress((const GLubyte*)"glLockArraysEXT")) == NULL) || r; + r = ((glUnlockArraysEXT = (PFNGLUNLOCKARRAYSEXTPROC)glewGetProcAddress((const GLubyte*)"glUnlockArraysEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_compiled_vertex_array */ + +#ifdef GL_EXT_convolution + +static GLboolean _glewInit_GL_EXT_convolution (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glConvolutionFilter1DEXT = (PFNGLCONVOLUTIONFILTER1DEXTPROC)glewGetProcAddress((const GLubyte*)"glConvolutionFilter1DEXT")) == NULL) || r; + r = ((glConvolutionFilter2DEXT = (PFNGLCONVOLUTIONFILTER2DEXTPROC)glewGetProcAddress((const GLubyte*)"glConvolutionFilter2DEXT")) == NULL) || r; + r = ((glConvolutionParameterfEXT = (PFNGLCONVOLUTIONPARAMETERFEXTPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameterfEXT")) == NULL) || r; + r = ((glConvolutionParameterfvEXT = (PFNGLCONVOLUTIONPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameterfvEXT")) == NULL) || r; + r = ((glConvolutionParameteriEXT = (PFNGLCONVOLUTIONPARAMETERIEXTPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameteriEXT")) == NULL) || r; + r = ((glConvolutionParameterivEXT = (PFNGLCONVOLUTIONPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameterivEXT")) == NULL) || r; + r = ((glCopyConvolutionFilter1DEXT = (PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyConvolutionFilter1DEXT")) == NULL) || r; + r = ((glCopyConvolutionFilter2DEXT = (PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyConvolutionFilter2DEXT")) == NULL) || r; + r = ((glGetConvolutionFilterEXT = (PFNGLGETCONVOLUTIONFILTEREXTPROC)glewGetProcAddress((const GLubyte*)"glGetConvolutionFilterEXT")) == NULL) || r; + r = ((glGetConvolutionParameterfvEXT = (PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetConvolutionParameterfvEXT")) == NULL) || r; + r = ((glGetConvolutionParameterivEXT = (PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetConvolutionParameterivEXT")) == NULL) || r; + r = ((glGetSeparableFilterEXT = (PFNGLGETSEPARABLEFILTEREXTPROC)glewGetProcAddress((const GLubyte*)"glGetSeparableFilterEXT")) == NULL) || r; + r = ((glSeparableFilter2DEXT = (PFNGLSEPARABLEFILTER2DEXTPROC)glewGetProcAddress((const GLubyte*)"glSeparableFilter2DEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_convolution */ + +#ifdef GL_EXT_coordinate_frame + +static GLboolean _glewInit_GL_EXT_coordinate_frame (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBinormalPointerEXT = (PFNGLBINORMALPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glBinormalPointerEXT")) == NULL) || r; + r = ((glTangentPointerEXT = (PFNGLTANGENTPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glTangentPointerEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_coordinate_frame */ + +#ifdef GL_EXT_copy_texture + +static GLboolean _glewInit_GL_EXT_copy_texture (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glCopyTexImage1DEXT = (PFNGLCOPYTEXIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTexImage1DEXT")) == NULL) || r; + r = ((glCopyTexImage2DEXT = (PFNGLCOPYTEXIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTexImage2DEXT")) == NULL) || r; + r = ((glCopyTexSubImage1DEXT = (PFNGLCOPYTEXSUBIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTexSubImage1DEXT")) == NULL) || r; + r = ((glCopyTexSubImage2DEXT = (PFNGLCOPYTEXSUBIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTexSubImage2DEXT")) == NULL) || r; + r = ((glCopyTexSubImage3DEXT = (PFNGLCOPYTEXSUBIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTexSubImage3DEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_copy_texture */ + +#ifdef GL_EXT_cull_vertex + +static GLboolean _glewInit_GL_EXT_cull_vertex (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glCullParameterdvEXT = (PFNGLCULLPARAMETERDVEXTPROC)glewGetProcAddress((const GLubyte*)"glCullParameterdvEXT")) == NULL) || r; + r = ((glCullParameterfvEXT = (PFNGLCULLPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glCullParameterfvEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_cull_vertex */ + +#ifdef GL_EXT_depth_bounds_test + +static GLboolean _glewInit_GL_EXT_depth_bounds_test (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glDepthBoundsEXT = (PFNGLDEPTHBOUNDSEXTPROC)glewGetProcAddress((const GLubyte*)"glDepthBoundsEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_depth_bounds_test */ + +#ifdef GL_EXT_direct_state_access + +static GLboolean _glewInit_GL_EXT_direct_state_access (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBindMultiTextureEXT = (PFNGLBINDMULTITEXTUREEXTPROC)glewGetProcAddress((const GLubyte*)"glBindMultiTextureEXT")) == NULL) || r; + r = ((glCheckNamedFramebufferStatusEXT = (PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC)glewGetProcAddress((const GLubyte*)"glCheckNamedFramebufferStatusEXT")) == NULL) || r; + r = ((glClientAttribDefaultEXT = (PFNGLCLIENTATTRIBDEFAULTEXTPROC)glewGetProcAddress((const GLubyte*)"glClientAttribDefaultEXT")) == NULL) || r; + r = ((glCompressedMultiTexImage1DEXT = (PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedMultiTexImage1DEXT")) == NULL) || r; + r = ((glCompressedMultiTexImage2DEXT = (PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedMultiTexImage2DEXT")) == NULL) || r; + r = ((glCompressedMultiTexImage3DEXT = (PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedMultiTexImage3DEXT")) == NULL) || r; + r = ((glCompressedMultiTexSubImage1DEXT = (PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedMultiTexSubImage1DEXT")) == NULL) || r; + r = ((glCompressedMultiTexSubImage2DEXT = (PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedMultiTexSubImage2DEXT")) == NULL) || r; + r = ((glCompressedMultiTexSubImage3DEXT = (PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedMultiTexSubImage3DEXT")) == NULL) || r; + r = ((glCompressedTextureImage1DEXT = (PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedTextureImage1DEXT")) == NULL) || r; + r = ((glCompressedTextureImage2DEXT = (PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedTextureImage2DEXT")) == NULL) || r; + r = ((glCompressedTextureImage3DEXT = (PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedTextureImage3DEXT")) == NULL) || r; + r = ((glCompressedTextureSubImage1DEXT = (PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedTextureSubImage1DEXT")) == NULL) || r; + r = ((glCompressedTextureSubImage2DEXT = (PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedTextureSubImage2DEXT")) == NULL) || r; + r = ((glCompressedTextureSubImage3DEXT = (PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedTextureSubImage3DEXT")) == NULL) || r; + r = ((glCopyMultiTexImage1DEXT = (PFNGLCOPYMULTITEXIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyMultiTexImage1DEXT")) == NULL) || r; + r = ((glCopyMultiTexImage2DEXT = (PFNGLCOPYMULTITEXIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyMultiTexImage2DEXT")) == NULL) || r; + r = ((glCopyMultiTexSubImage1DEXT = (PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyMultiTexSubImage1DEXT")) == NULL) || r; + r = ((glCopyMultiTexSubImage2DEXT = (PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyMultiTexSubImage2DEXT")) == NULL) || r; + r = ((glCopyMultiTexSubImage3DEXT = (PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyMultiTexSubImage3DEXT")) == NULL) || r; + r = ((glCopyTextureImage1DEXT = (PFNGLCOPYTEXTUREIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTextureImage1DEXT")) == NULL) || r; + r = ((glCopyTextureImage2DEXT = (PFNGLCOPYTEXTUREIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTextureImage2DEXT")) == NULL) || r; + r = ((glCopyTextureSubImage1DEXT = (PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTextureSubImage1DEXT")) == NULL) || r; + r = ((glCopyTextureSubImage2DEXT = (PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTextureSubImage2DEXT")) == NULL) || r; + r = ((glCopyTextureSubImage3DEXT = (PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTextureSubImage3DEXT")) == NULL) || r; + r = ((glDisableClientStateIndexedEXT = (PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC)glewGetProcAddress((const GLubyte*)"glDisableClientStateIndexedEXT")) == NULL) || r; + r = ((glEnableClientStateIndexedEXT = (PFNGLENABLECLIENTSTATEINDEXEDEXTPROC)glewGetProcAddress((const GLubyte*)"glEnableClientStateIndexedEXT")) == NULL) || r; + r = ((glFramebufferDrawBufferEXT = (PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferDrawBufferEXT")) == NULL) || r; + r = ((glFramebufferDrawBuffersEXT = (PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferDrawBuffersEXT")) == NULL) || r; + r = ((glFramebufferReadBufferEXT = (PFNGLFRAMEBUFFERREADBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferReadBufferEXT")) == NULL) || r; + r = ((glGenerateMultiTexMipmapEXT = (PFNGLGENERATEMULTITEXMIPMAPEXTPROC)glewGetProcAddress((const GLubyte*)"glGenerateMultiTexMipmapEXT")) == NULL) || r; + r = ((glGenerateTextureMipmapEXT = (PFNGLGENERATETEXTUREMIPMAPEXTPROC)glewGetProcAddress((const GLubyte*)"glGenerateTextureMipmapEXT")) == NULL) || r; + r = ((glGetCompressedMultiTexImageEXT = (PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glGetCompressedMultiTexImageEXT")) == NULL) || r; + r = ((glGetCompressedTextureImageEXT = (PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glGetCompressedTextureImageEXT")) == NULL) || r; + r = ((glGetDoubleIndexedvEXT = (PFNGLGETDOUBLEINDEXEDVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetDoubleIndexedvEXT")) == NULL) || r; + r = ((glGetFloatIndexedvEXT = (PFNGLGETFLOATINDEXEDVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFloatIndexedvEXT")) == NULL) || r; + r = ((glGetFramebufferParameterivEXT = (PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFramebufferParameterivEXT")) == NULL) || r; + r = ((glGetMultiTexEnvfvEXT = (PFNGLGETMULTITEXENVFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexEnvfvEXT")) == NULL) || r; + r = ((glGetMultiTexEnvivEXT = (PFNGLGETMULTITEXENVIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexEnvivEXT")) == NULL) || r; + r = ((glGetMultiTexGendvEXT = (PFNGLGETMULTITEXGENDVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexGendvEXT")) == NULL) || r; + r = ((glGetMultiTexGenfvEXT = (PFNGLGETMULTITEXGENFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexGenfvEXT")) == NULL) || r; + r = ((glGetMultiTexGenivEXT = (PFNGLGETMULTITEXGENIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexGenivEXT")) == NULL) || r; + r = ((glGetMultiTexImageEXT = (PFNGLGETMULTITEXIMAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexImageEXT")) == NULL) || r; + r = ((glGetMultiTexLevelParameterfvEXT = (PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexLevelParameterfvEXT")) == NULL) || r; + r = ((glGetMultiTexLevelParameterivEXT = (PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexLevelParameterivEXT")) == NULL) || r; + r = ((glGetMultiTexParameterIivEXT = (PFNGLGETMULTITEXPARAMETERIIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexParameterIivEXT")) == NULL) || r; + r = ((glGetMultiTexParameterIuivEXT = (PFNGLGETMULTITEXPARAMETERIUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexParameterIuivEXT")) == NULL) || r; + r = ((glGetMultiTexParameterfvEXT = (PFNGLGETMULTITEXPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexParameterfvEXT")) == NULL) || r; + r = ((glGetMultiTexParameterivEXT = (PFNGLGETMULTITEXPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexParameterivEXT")) == NULL) || r; + r = ((glGetNamedBufferParameterivEXT = (PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedBufferParameterivEXT")) == NULL) || r; + r = ((glGetNamedBufferPointervEXT = (PFNGLGETNAMEDBUFFERPOINTERVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedBufferPointervEXT")) == NULL) || r; + r = ((glGetNamedBufferSubDataEXT = (PFNGLGETNAMEDBUFFERSUBDATAEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedBufferSubDataEXT")) == NULL) || r; + r = ((glGetNamedFramebufferAttachmentParameterivEXT = (PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedFramebufferAttachmentParameterivEXT")) == NULL) || r; + r = ((glGetNamedProgramLocalParameterIivEXT = (PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedProgramLocalParameterIivEXT")) == NULL) || r; + r = ((glGetNamedProgramLocalParameterIuivEXT = (PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedProgramLocalParameterIuivEXT")) == NULL) || r; + r = ((glGetNamedProgramLocalParameterdvEXT = (PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedProgramLocalParameterdvEXT")) == NULL) || r; + r = ((glGetNamedProgramLocalParameterfvEXT = (PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedProgramLocalParameterfvEXT")) == NULL) || r; + r = ((glGetNamedProgramStringEXT = (PFNGLGETNAMEDPROGRAMSTRINGEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedProgramStringEXT")) == NULL) || r; + r = ((glGetNamedProgramivEXT = (PFNGLGETNAMEDPROGRAMIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedProgramivEXT")) == NULL) || r; + r = ((glGetNamedRenderbufferParameterivEXT = (PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedRenderbufferParameterivEXT")) == NULL) || r; + r = ((glGetPointerIndexedvEXT = (PFNGLGETPOINTERINDEXEDVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetPointerIndexedvEXT")) == NULL) || r; + r = ((glGetTextureImageEXT = (PFNGLGETTEXTUREIMAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTextureImageEXT")) == NULL) || r; + r = ((glGetTextureLevelParameterfvEXT = (PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTextureLevelParameterfvEXT")) == NULL) || r; + r = ((glGetTextureLevelParameterivEXT = (PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTextureLevelParameterivEXT")) == NULL) || r; + r = ((glGetTextureParameterIivEXT = (PFNGLGETTEXTUREPARAMETERIIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTextureParameterIivEXT")) == NULL) || r; + r = ((glGetTextureParameterIuivEXT = (PFNGLGETTEXTUREPARAMETERIUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTextureParameterIuivEXT")) == NULL) || r; + r = ((glGetTextureParameterfvEXT = (PFNGLGETTEXTUREPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTextureParameterfvEXT")) == NULL) || r; + r = ((glGetTextureParameterivEXT = (PFNGLGETTEXTUREPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTextureParameterivEXT")) == NULL) || r; + r = ((glMapNamedBufferEXT = (PFNGLMAPNAMEDBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glMapNamedBufferEXT")) == NULL) || r; + r = ((glMatrixFrustumEXT = (PFNGLMATRIXFRUSTUMEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixFrustumEXT")) == NULL) || r; + r = ((glMatrixLoadIdentityEXT = (PFNGLMATRIXLOADIDENTITYEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixLoadIdentityEXT")) == NULL) || r; + r = ((glMatrixLoadTransposedEXT = (PFNGLMATRIXLOADTRANSPOSEDEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixLoadTransposedEXT")) == NULL) || r; + r = ((glMatrixLoadTransposefEXT = (PFNGLMATRIXLOADTRANSPOSEFEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixLoadTransposefEXT")) == NULL) || r; + r = ((glMatrixLoaddEXT = (PFNGLMATRIXLOADDEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixLoaddEXT")) == NULL) || r; + r = ((glMatrixLoadfEXT = (PFNGLMATRIXLOADFEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixLoadfEXT")) == NULL) || r; + r = ((glMatrixMultTransposedEXT = (PFNGLMATRIXMULTTRANSPOSEDEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixMultTransposedEXT")) == NULL) || r; + r = ((glMatrixMultTransposefEXT = (PFNGLMATRIXMULTTRANSPOSEFEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixMultTransposefEXT")) == NULL) || r; + r = ((glMatrixMultdEXT = (PFNGLMATRIXMULTDEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixMultdEXT")) == NULL) || r; + r = ((glMatrixMultfEXT = (PFNGLMATRIXMULTFEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixMultfEXT")) == NULL) || r; + r = ((glMatrixOrthoEXT = (PFNGLMATRIXORTHOEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixOrthoEXT")) == NULL) || r; + r = ((glMatrixPopEXT = (PFNGLMATRIXPOPEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixPopEXT")) == NULL) || r; + r = ((glMatrixPushEXT = (PFNGLMATRIXPUSHEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixPushEXT")) == NULL) || r; + r = ((glMatrixRotatedEXT = (PFNGLMATRIXROTATEDEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixRotatedEXT")) == NULL) || r; + r = ((glMatrixRotatefEXT = (PFNGLMATRIXROTATEFEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixRotatefEXT")) == NULL) || r; + r = ((glMatrixScaledEXT = (PFNGLMATRIXSCALEDEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixScaledEXT")) == NULL) || r; + r = ((glMatrixScalefEXT = (PFNGLMATRIXSCALEFEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixScalefEXT")) == NULL) || r; + r = ((glMatrixTranslatedEXT = (PFNGLMATRIXTRANSLATEDEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixTranslatedEXT")) == NULL) || r; + r = ((glMatrixTranslatefEXT = (PFNGLMATRIXTRANSLATEFEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixTranslatefEXT")) == NULL) || r; + r = ((glMultiTexBufferEXT = (PFNGLMULTITEXBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexBufferEXT")) == NULL) || r; + r = ((glMultiTexCoordPointerEXT = (PFNGLMULTITEXCOORDPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoordPointerEXT")) == NULL) || r; + r = ((glMultiTexEnvfEXT = (PFNGLMULTITEXENVFEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexEnvfEXT")) == NULL) || r; + r = ((glMultiTexEnvfvEXT = (PFNGLMULTITEXENVFVEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexEnvfvEXT")) == NULL) || r; + r = ((glMultiTexEnviEXT = (PFNGLMULTITEXENVIEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexEnviEXT")) == NULL) || r; + r = ((glMultiTexEnvivEXT = (PFNGLMULTITEXENVIVEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexEnvivEXT")) == NULL) || r; + r = ((glMultiTexGendEXT = (PFNGLMULTITEXGENDEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexGendEXT")) == NULL) || r; + r = ((glMultiTexGendvEXT = (PFNGLMULTITEXGENDVEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexGendvEXT")) == NULL) || r; + r = ((glMultiTexGenfEXT = (PFNGLMULTITEXGENFEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexGenfEXT")) == NULL) || r; + r = ((glMultiTexGenfvEXT = (PFNGLMULTITEXGENFVEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexGenfvEXT")) == NULL) || r; + r = ((glMultiTexGeniEXT = (PFNGLMULTITEXGENIEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexGeniEXT")) == NULL) || r; + r = ((glMultiTexGenivEXT = (PFNGLMULTITEXGENIVEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexGenivEXT")) == NULL) || r; + r = ((glMultiTexImage1DEXT = (PFNGLMULTITEXIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexImage1DEXT")) == NULL) || r; + r = ((glMultiTexImage2DEXT = (PFNGLMULTITEXIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexImage2DEXT")) == NULL) || r; + r = ((glMultiTexImage3DEXT = (PFNGLMULTITEXIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexImage3DEXT")) == NULL) || r; + r = ((glMultiTexParameterIivEXT = (PFNGLMULTITEXPARAMETERIIVEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexParameterIivEXT")) == NULL) || r; + r = ((glMultiTexParameterIuivEXT = (PFNGLMULTITEXPARAMETERIUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexParameterIuivEXT")) == NULL) || r; + r = ((glMultiTexParameterfEXT = (PFNGLMULTITEXPARAMETERFEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexParameterfEXT")) == NULL) || r; + r = ((glMultiTexParameterfvEXT = (PFNGLMULTITEXPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexParameterfvEXT")) == NULL) || r; + r = ((glMultiTexParameteriEXT = (PFNGLMULTITEXPARAMETERIEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexParameteriEXT")) == NULL) || r; + r = ((glMultiTexParameterivEXT = (PFNGLMULTITEXPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexParameterivEXT")) == NULL) || r; + r = ((glMultiTexRenderbufferEXT = (PFNGLMULTITEXRENDERBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexRenderbufferEXT")) == NULL) || r; + r = ((glMultiTexSubImage1DEXT = (PFNGLMULTITEXSUBIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexSubImage1DEXT")) == NULL) || r; + r = ((glMultiTexSubImage2DEXT = (PFNGLMULTITEXSUBIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexSubImage2DEXT")) == NULL) || r; + r = ((glMultiTexSubImage3DEXT = (PFNGLMULTITEXSUBIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexSubImage3DEXT")) == NULL) || r; + r = ((glNamedBufferDataEXT = (PFNGLNAMEDBUFFERDATAEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedBufferDataEXT")) == NULL) || r; + r = ((glNamedBufferSubDataEXT = (PFNGLNAMEDBUFFERSUBDATAEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedBufferSubDataEXT")) == NULL) || r; + r = ((glNamedFramebufferRenderbufferEXT = (PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferRenderbufferEXT")) == NULL) || r; + r = ((glNamedFramebufferTexture1DEXT = (PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferTexture1DEXT")) == NULL) || r; + r = ((glNamedFramebufferTexture2DEXT = (PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferTexture2DEXT")) == NULL) || r; + r = ((glNamedFramebufferTexture3DEXT = (PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferTexture3DEXT")) == NULL) || r; + r = ((glNamedFramebufferTextureEXT = (PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferTextureEXT")) == NULL) || r; + r = ((glNamedFramebufferTextureFaceEXT = (PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferTextureFaceEXT")) == NULL) || r; + r = ((glNamedFramebufferTextureLayerEXT = (PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferTextureLayerEXT")) == NULL) || r; + r = ((glNamedProgramLocalParameter4dEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParameter4dEXT")) == NULL) || r; + r = ((glNamedProgramLocalParameter4dvEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParameter4dvEXT")) == NULL) || r; + r = ((glNamedProgramLocalParameter4fEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParameter4fEXT")) == NULL) || r; + r = ((glNamedProgramLocalParameter4fvEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParameter4fvEXT")) == NULL) || r; + r = ((glNamedProgramLocalParameterI4iEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParameterI4iEXT")) == NULL) || r; + r = ((glNamedProgramLocalParameterI4ivEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParameterI4ivEXT")) == NULL) || r; + r = ((glNamedProgramLocalParameterI4uiEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParameterI4uiEXT")) == NULL) || r; + r = ((glNamedProgramLocalParameterI4uivEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParameterI4uivEXT")) == NULL) || r; + r = ((glNamedProgramLocalParameters4fvEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParameters4fvEXT")) == NULL) || r; + r = ((glNamedProgramLocalParametersI4ivEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParametersI4ivEXT")) == NULL) || r; + r = ((glNamedProgramLocalParametersI4uivEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParametersI4uivEXT")) == NULL) || r; + r = ((glNamedProgramStringEXT = (PFNGLNAMEDPROGRAMSTRINGEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramStringEXT")) == NULL) || r; + r = ((glNamedRenderbufferStorageEXT = (PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedRenderbufferStorageEXT")) == NULL) || r; + r = ((glNamedRenderbufferStorageMultisampleCoverageEXT = (PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedRenderbufferStorageMultisampleCoverageEXT")) == NULL) || r; + r = ((glNamedRenderbufferStorageMultisampleEXT = (PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedRenderbufferStorageMultisampleEXT")) == NULL) || r; + r = ((glProgramUniform1fEXT = (PFNGLPROGRAMUNIFORM1FEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1fEXT")) == NULL) || r; + r = ((glProgramUniform1fvEXT = (PFNGLPROGRAMUNIFORM1FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1fvEXT")) == NULL) || r; + r = ((glProgramUniform1iEXT = (PFNGLPROGRAMUNIFORM1IEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1iEXT")) == NULL) || r; + r = ((glProgramUniform1ivEXT = (PFNGLPROGRAMUNIFORM1IVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1ivEXT")) == NULL) || r; + r = ((glProgramUniform1uiEXT = (PFNGLPROGRAMUNIFORM1UIEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1uiEXT")) == NULL) || r; + r = ((glProgramUniform1uivEXT = (PFNGLPROGRAMUNIFORM1UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1uivEXT")) == NULL) || r; + r = ((glProgramUniform2fEXT = (PFNGLPROGRAMUNIFORM2FEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2fEXT")) == NULL) || r; + r = ((glProgramUniform2fvEXT = (PFNGLPROGRAMUNIFORM2FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2fvEXT")) == NULL) || r; + r = ((glProgramUniform2iEXT = (PFNGLPROGRAMUNIFORM2IEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2iEXT")) == NULL) || r; + r = ((glProgramUniform2ivEXT = (PFNGLPROGRAMUNIFORM2IVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2ivEXT")) == NULL) || r; + r = ((glProgramUniform2uiEXT = (PFNGLPROGRAMUNIFORM2UIEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2uiEXT")) == NULL) || r; + r = ((glProgramUniform2uivEXT = (PFNGLPROGRAMUNIFORM2UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2uivEXT")) == NULL) || r; + r = ((glProgramUniform3fEXT = (PFNGLPROGRAMUNIFORM3FEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3fEXT")) == NULL) || r; + r = ((glProgramUniform3fvEXT = (PFNGLPROGRAMUNIFORM3FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3fvEXT")) == NULL) || r; + r = ((glProgramUniform3iEXT = (PFNGLPROGRAMUNIFORM3IEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3iEXT")) == NULL) || r; + r = ((glProgramUniform3ivEXT = (PFNGLPROGRAMUNIFORM3IVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3ivEXT")) == NULL) || r; + r = ((glProgramUniform3uiEXT = (PFNGLPROGRAMUNIFORM3UIEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3uiEXT")) == NULL) || r; + r = ((glProgramUniform3uivEXT = (PFNGLPROGRAMUNIFORM3UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3uivEXT")) == NULL) || r; + r = ((glProgramUniform4fEXT = (PFNGLPROGRAMUNIFORM4FEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4fEXT")) == NULL) || r; + r = ((glProgramUniform4fvEXT = (PFNGLPROGRAMUNIFORM4FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4fvEXT")) == NULL) || r; + r = ((glProgramUniform4iEXT = (PFNGLPROGRAMUNIFORM4IEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4iEXT")) == NULL) || r; + r = ((glProgramUniform4ivEXT = (PFNGLPROGRAMUNIFORM4IVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4ivEXT")) == NULL) || r; + r = ((glProgramUniform4uiEXT = (PFNGLPROGRAMUNIFORM4UIEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4uiEXT")) == NULL) || r; + r = ((glProgramUniform4uivEXT = (PFNGLPROGRAMUNIFORM4UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4uivEXT")) == NULL) || r; + r = ((glProgramUniformMatrix2fvEXT = (PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix2fvEXT")) == NULL) || r; + r = ((glProgramUniformMatrix2x3fvEXT = (PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix2x3fvEXT")) == NULL) || r; + r = ((glProgramUniformMatrix2x4fvEXT = (PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix2x4fvEXT")) == NULL) || r; + r = ((glProgramUniformMatrix3fvEXT = (PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix3fvEXT")) == NULL) || r; + r = ((glProgramUniformMatrix3x2fvEXT = (PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix3x2fvEXT")) == NULL) || r; + r = ((glProgramUniformMatrix3x4fvEXT = (PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix3x4fvEXT")) == NULL) || r; + r = ((glProgramUniformMatrix4fvEXT = (PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix4fvEXT")) == NULL) || r; + r = ((glProgramUniformMatrix4x2fvEXT = (PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix4x2fvEXT")) == NULL) || r; + r = ((glProgramUniformMatrix4x3fvEXT = (PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix4x3fvEXT")) == NULL) || r; + r = ((glPushClientAttribDefaultEXT = (PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC)glewGetProcAddress((const GLubyte*)"glPushClientAttribDefaultEXT")) == NULL) || r; + r = ((glTextureBufferEXT = (PFNGLTEXTUREBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glTextureBufferEXT")) == NULL) || r; + r = ((glTextureImage1DEXT = (PFNGLTEXTUREIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureImage1DEXT")) == NULL) || r; + r = ((glTextureImage2DEXT = (PFNGLTEXTUREIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureImage2DEXT")) == NULL) || r; + r = ((glTextureImage3DEXT = (PFNGLTEXTUREIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureImage3DEXT")) == NULL) || r; + r = ((glTextureParameterIivEXT = (PFNGLTEXTUREPARAMETERIIVEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureParameterIivEXT")) == NULL) || r; + r = ((glTextureParameterIuivEXT = (PFNGLTEXTUREPARAMETERIUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureParameterIuivEXT")) == NULL) || r; + r = ((glTextureParameterfEXT = (PFNGLTEXTUREPARAMETERFEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureParameterfEXT")) == NULL) || r; + r = ((glTextureParameterfvEXT = (PFNGLTEXTUREPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureParameterfvEXT")) == NULL) || r; + r = ((glTextureParameteriEXT = (PFNGLTEXTUREPARAMETERIEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureParameteriEXT")) == NULL) || r; + r = ((glTextureParameterivEXT = (PFNGLTEXTUREPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureParameterivEXT")) == NULL) || r; + r = ((glTextureRenderbufferEXT = (PFNGLTEXTURERENDERBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glTextureRenderbufferEXT")) == NULL) || r; + r = ((glTextureSubImage1DEXT = (PFNGLTEXTURESUBIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureSubImage1DEXT")) == NULL) || r; + r = ((glTextureSubImage2DEXT = (PFNGLTEXTURESUBIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureSubImage2DEXT")) == NULL) || r; + r = ((glTextureSubImage3DEXT = (PFNGLTEXTURESUBIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureSubImage3DEXT")) == NULL) || r; + r = ((glUnmapNamedBufferEXT = (PFNGLUNMAPNAMEDBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glUnmapNamedBufferEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_direct_state_access */ + +#ifdef GL_EXT_draw_buffers2 + +static GLboolean _glewInit_GL_EXT_draw_buffers2 (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glColorMaskIndexedEXT = (PFNGLCOLORMASKINDEXEDEXTPROC)glewGetProcAddress((const GLubyte*)"glColorMaskIndexedEXT")) == NULL) || r; + r = ((glDisableIndexedEXT = (PFNGLDISABLEINDEXEDEXTPROC)glewGetProcAddress((const GLubyte*)"glDisableIndexedEXT")) == NULL) || r; + r = ((glEnableIndexedEXT = (PFNGLENABLEINDEXEDEXTPROC)glewGetProcAddress((const GLubyte*)"glEnableIndexedEXT")) == NULL) || r; + r = ((glGetBooleanIndexedvEXT = (PFNGLGETBOOLEANINDEXEDVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetBooleanIndexedvEXT")) == NULL) || r; + r = ((glGetIntegerIndexedvEXT = (PFNGLGETINTEGERINDEXEDVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetIntegerIndexedvEXT")) == NULL) || r; + r = ((glIsEnabledIndexedEXT = (PFNGLISENABLEDINDEXEDEXTPROC)glewGetProcAddress((const GLubyte*)"glIsEnabledIndexedEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_draw_buffers2 */ + +#ifdef GL_EXT_draw_instanced + +static GLboolean _glewInit_GL_EXT_draw_instanced (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glDrawArraysInstancedEXT = (PFNGLDRAWARRAYSINSTANCEDEXTPROC)glewGetProcAddress((const GLubyte*)"glDrawArraysInstancedEXT")) == NULL) || r; + r = ((glDrawElementsInstancedEXT = (PFNGLDRAWELEMENTSINSTANCEDEXTPROC)glewGetProcAddress((const GLubyte*)"glDrawElementsInstancedEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_draw_instanced */ + +#ifdef GL_EXT_draw_range_elements + +static GLboolean _glewInit_GL_EXT_draw_range_elements (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glDrawRangeElementsEXT = (PFNGLDRAWRANGEELEMENTSEXTPROC)glewGetProcAddress((const GLubyte*)"glDrawRangeElementsEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_draw_range_elements */ + +#ifdef GL_EXT_fog_coord + +static GLboolean _glewInit_GL_EXT_fog_coord (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glFogCoordPointerEXT = (PFNGLFOGCOORDPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glFogCoordPointerEXT")) == NULL) || r; + r = ((glFogCoorddEXT = (PFNGLFOGCOORDDEXTPROC)glewGetProcAddress((const GLubyte*)"glFogCoorddEXT")) == NULL) || r; + r = ((glFogCoorddvEXT = (PFNGLFOGCOORDDVEXTPROC)glewGetProcAddress((const GLubyte*)"glFogCoorddvEXT")) == NULL) || r; + r = ((glFogCoordfEXT = (PFNGLFOGCOORDFEXTPROC)glewGetProcAddress((const GLubyte*)"glFogCoordfEXT")) == NULL) || r; + r = ((glFogCoordfvEXT = (PFNGLFOGCOORDFVEXTPROC)glewGetProcAddress((const GLubyte*)"glFogCoordfvEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_fog_coord */ + +#ifdef GL_EXT_fragment_lighting + +static GLboolean _glewInit_GL_EXT_fragment_lighting (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glFragmentColorMaterialEXT = (PFNGLFRAGMENTCOLORMATERIALEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentColorMaterialEXT")) == NULL) || r; + r = ((glFragmentLightModelfEXT = (PFNGLFRAGMENTLIGHTMODELFEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModelfEXT")) == NULL) || r; + r = ((glFragmentLightModelfvEXT = (PFNGLFRAGMENTLIGHTMODELFVEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModelfvEXT")) == NULL) || r; + r = ((glFragmentLightModeliEXT = (PFNGLFRAGMENTLIGHTMODELIEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModeliEXT")) == NULL) || r; + r = ((glFragmentLightModelivEXT = (PFNGLFRAGMENTLIGHTMODELIVEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModelivEXT")) == NULL) || r; + r = ((glFragmentLightfEXT = (PFNGLFRAGMENTLIGHTFEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightfEXT")) == NULL) || r; + r = ((glFragmentLightfvEXT = (PFNGLFRAGMENTLIGHTFVEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightfvEXT")) == NULL) || r; + r = ((glFragmentLightiEXT = (PFNGLFRAGMENTLIGHTIEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightiEXT")) == NULL) || r; + r = ((glFragmentLightivEXT = (PFNGLFRAGMENTLIGHTIVEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightivEXT")) == NULL) || r; + r = ((glFragmentMaterialfEXT = (PFNGLFRAGMENTMATERIALFEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialfEXT")) == NULL) || r; + r = ((glFragmentMaterialfvEXT = (PFNGLFRAGMENTMATERIALFVEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialfvEXT")) == NULL) || r; + r = ((glFragmentMaterialiEXT = (PFNGLFRAGMENTMATERIALIEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialiEXT")) == NULL) || r; + r = ((glFragmentMaterialivEXT = (PFNGLFRAGMENTMATERIALIVEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialivEXT")) == NULL) || r; + r = ((glGetFragmentLightfvEXT = (PFNGLGETFRAGMENTLIGHTFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentLightfvEXT")) == NULL) || r; + r = ((glGetFragmentLightivEXT = (PFNGLGETFRAGMENTLIGHTIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentLightivEXT")) == NULL) || r; + r = ((glGetFragmentMaterialfvEXT = (PFNGLGETFRAGMENTMATERIALFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentMaterialfvEXT")) == NULL) || r; + r = ((glGetFragmentMaterialivEXT = (PFNGLGETFRAGMENTMATERIALIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentMaterialivEXT")) == NULL) || r; + r = ((glLightEnviEXT = (PFNGLLIGHTENVIEXTPROC)glewGetProcAddress((const GLubyte*)"glLightEnviEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_fragment_lighting */ + +#ifdef GL_EXT_framebuffer_blit + +static GLboolean _glewInit_GL_EXT_framebuffer_blit (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBlitFramebufferEXT = (PFNGLBLITFRAMEBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glBlitFramebufferEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_framebuffer_blit */ + +#ifdef GL_EXT_framebuffer_multisample + +static GLboolean _glewInit_GL_EXT_framebuffer_multisample (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glRenderbufferStorageMultisampleEXT = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)glewGetProcAddress((const GLubyte*)"glRenderbufferStorageMultisampleEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_framebuffer_multisample */ + +#ifdef GL_EXT_framebuffer_object + +static GLboolean _glewInit_GL_EXT_framebuffer_object (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindFramebufferEXT")) == NULL) || r; + r = ((glBindRenderbufferEXT = (PFNGLBINDRENDERBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindRenderbufferEXT")) == NULL) || r; + r = ((glCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)glewGetProcAddress((const GLubyte*)"glCheckFramebufferStatusEXT")) == NULL) || r; + r = ((glDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC)glewGetProcAddress((const GLubyte*)"glDeleteFramebuffersEXT")) == NULL) || r; + r = ((glDeleteRenderbuffersEXT = (PFNGLDELETERENDERBUFFERSEXTPROC)glewGetProcAddress((const GLubyte*)"glDeleteRenderbuffersEXT")) == NULL) || r; + r = ((glFramebufferRenderbufferEXT = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferRenderbufferEXT")) == NULL) || r; + r = ((glFramebufferTexture1DEXT = (PFNGLFRAMEBUFFERTEXTURE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexture1DEXT")) == NULL) || r; + r = ((glFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexture2DEXT")) == NULL) || r; + r = ((glFramebufferTexture3DEXT = (PFNGLFRAMEBUFFERTEXTURE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexture3DEXT")) == NULL) || r; + r = ((glGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC)glewGetProcAddress((const GLubyte*)"glGenFramebuffersEXT")) == NULL) || r; + r = ((glGenRenderbuffersEXT = (PFNGLGENRENDERBUFFERSEXTPROC)glewGetProcAddress((const GLubyte*)"glGenRenderbuffersEXT")) == NULL) || r; + r = ((glGenerateMipmapEXT = (PFNGLGENERATEMIPMAPEXTPROC)glewGetProcAddress((const GLubyte*)"glGenerateMipmapEXT")) == NULL) || r; + r = ((glGetFramebufferAttachmentParameterivEXT = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFramebufferAttachmentParameterivEXT")) == NULL) || r; + r = ((glGetRenderbufferParameterivEXT = (PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetRenderbufferParameterivEXT")) == NULL) || r; + r = ((glIsFramebufferEXT = (PFNGLISFRAMEBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glIsFramebufferEXT")) == NULL) || r; + r = ((glIsRenderbufferEXT = (PFNGLISRENDERBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glIsRenderbufferEXT")) == NULL) || r; + r = ((glRenderbufferStorageEXT = (PFNGLRENDERBUFFERSTORAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glRenderbufferStorageEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_framebuffer_object */ + +#ifdef GL_EXT_framebuffer_sRGB + +#endif /* GL_EXT_framebuffer_sRGB */ + +#ifdef GL_EXT_geometry_shader4 + +static GLboolean _glewInit_GL_EXT_geometry_shader4 (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glFramebufferTextureEXT = (PFNGLFRAMEBUFFERTEXTUREEXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTextureEXT")) == NULL) || r; + r = ((glFramebufferTextureFaceEXT = (PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTextureFaceEXT")) == NULL) || r; + r = ((glFramebufferTextureLayerEXT = (PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTextureLayerEXT")) == NULL) || r; + r = ((glProgramParameteriEXT = (PFNGLPROGRAMPARAMETERIEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramParameteriEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_geometry_shader4 */ + +#ifdef GL_EXT_gpu_program_parameters + +static GLboolean _glewInit_GL_EXT_gpu_program_parameters (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glProgramEnvParameters4fvEXT = (PFNGLPROGRAMENVPARAMETERS4FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameters4fvEXT")) == NULL) || r; + r = ((glProgramLocalParameters4fvEXT = (PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameters4fvEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_gpu_program_parameters */ + +#ifdef GL_EXT_gpu_shader4 + +static GLboolean _glewInit_GL_EXT_gpu_shader4 (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBindFragDataLocationEXT = (PFNGLBINDFRAGDATALOCATIONEXTPROC)glewGetProcAddress((const GLubyte*)"glBindFragDataLocationEXT")) == NULL) || r; + r = ((glGetFragDataLocationEXT = (PFNGLGETFRAGDATALOCATIONEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFragDataLocationEXT")) == NULL) || r; + r = ((glGetUniformuivEXT = (PFNGLGETUNIFORMUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetUniformuivEXT")) == NULL) || r; + r = ((glGetVertexAttribIivEXT = (PFNGLGETVERTEXATTRIBIIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribIivEXT")) == NULL) || r; + r = ((glGetVertexAttribIuivEXT = (PFNGLGETVERTEXATTRIBIUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribIuivEXT")) == NULL) || r; + r = ((glUniform1uiEXT = (PFNGLUNIFORM1UIEXTPROC)glewGetProcAddress((const GLubyte*)"glUniform1uiEXT")) == NULL) || r; + r = ((glUniform1uivEXT = (PFNGLUNIFORM1UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glUniform1uivEXT")) == NULL) || r; + r = ((glUniform2uiEXT = (PFNGLUNIFORM2UIEXTPROC)glewGetProcAddress((const GLubyte*)"glUniform2uiEXT")) == NULL) || r; + r = ((glUniform2uivEXT = (PFNGLUNIFORM2UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glUniform2uivEXT")) == NULL) || r; + r = ((glUniform3uiEXT = (PFNGLUNIFORM3UIEXTPROC)glewGetProcAddress((const GLubyte*)"glUniform3uiEXT")) == NULL) || r; + r = ((glUniform3uivEXT = (PFNGLUNIFORM3UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glUniform3uivEXT")) == NULL) || r; + r = ((glUniform4uiEXT = (PFNGLUNIFORM4UIEXTPROC)glewGetProcAddress((const GLubyte*)"glUniform4uiEXT")) == NULL) || r; + r = ((glUniform4uivEXT = (PFNGLUNIFORM4UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glUniform4uivEXT")) == NULL) || r; + r = ((glVertexAttribI1iEXT = (PFNGLVERTEXATTRIBI1IEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI1iEXT")) == NULL) || r; + r = ((glVertexAttribI1ivEXT = (PFNGLVERTEXATTRIBI1IVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI1ivEXT")) == NULL) || r; + r = ((glVertexAttribI1uiEXT = (PFNGLVERTEXATTRIBI1UIEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI1uiEXT")) == NULL) || r; + r = ((glVertexAttribI1uivEXT = (PFNGLVERTEXATTRIBI1UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI1uivEXT")) == NULL) || r; + r = ((glVertexAttribI2iEXT = (PFNGLVERTEXATTRIBI2IEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI2iEXT")) == NULL) || r; + r = ((glVertexAttribI2ivEXT = (PFNGLVERTEXATTRIBI2IVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI2ivEXT")) == NULL) || r; + r = ((glVertexAttribI2uiEXT = (PFNGLVERTEXATTRIBI2UIEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI2uiEXT")) == NULL) || r; + r = ((glVertexAttribI2uivEXT = (PFNGLVERTEXATTRIBI2UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI2uivEXT")) == NULL) || r; + r = ((glVertexAttribI3iEXT = (PFNGLVERTEXATTRIBI3IEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI3iEXT")) == NULL) || r; + r = ((glVertexAttribI3ivEXT = (PFNGLVERTEXATTRIBI3IVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI3ivEXT")) == NULL) || r; + r = ((glVertexAttribI3uiEXT = (PFNGLVERTEXATTRIBI3UIEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI3uiEXT")) == NULL) || r; + r = ((glVertexAttribI3uivEXT = (PFNGLVERTEXATTRIBI3UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI3uivEXT")) == NULL) || r; + r = ((glVertexAttribI4bvEXT = (PFNGLVERTEXATTRIBI4BVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4bvEXT")) == NULL) || r; + r = ((glVertexAttribI4iEXT = (PFNGLVERTEXATTRIBI4IEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4iEXT")) == NULL) || r; + r = ((glVertexAttribI4ivEXT = (PFNGLVERTEXATTRIBI4IVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4ivEXT")) == NULL) || r; + r = ((glVertexAttribI4svEXT = (PFNGLVERTEXATTRIBI4SVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4svEXT")) == NULL) || r; + r = ((glVertexAttribI4ubvEXT = (PFNGLVERTEXATTRIBI4UBVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4ubvEXT")) == NULL) || r; + r = ((glVertexAttribI4uiEXT = (PFNGLVERTEXATTRIBI4UIEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4uiEXT")) == NULL) || r; + r = ((glVertexAttribI4uivEXT = (PFNGLVERTEXATTRIBI4UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4uivEXT")) == NULL) || r; + r = ((glVertexAttribI4usvEXT = (PFNGLVERTEXATTRIBI4USVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4usvEXT")) == NULL) || r; + r = ((glVertexAttribIPointerEXT = (PFNGLVERTEXATTRIBIPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribIPointerEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_gpu_shader4 */ + +#ifdef GL_EXT_histogram + +static GLboolean _glewInit_GL_EXT_histogram (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetHistogramEXT = (PFNGLGETHISTOGRAMEXTPROC)glewGetProcAddress((const GLubyte*)"glGetHistogramEXT")) == NULL) || r; + r = ((glGetHistogramParameterfvEXT = (PFNGLGETHISTOGRAMPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetHistogramParameterfvEXT")) == NULL) || r; + r = ((glGetHistogramParameterivEXT = (PFNGLGETHISTOGRAMPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetHistogramParameterivEXT")) == NULL) || r; + r = ((glGetMinmaxEXT = (PFNGLGETMINMAXEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMinmaxEXT")) == NULL) || r; + r = ((glGetMinmaxParameterfvEXT = (PFNGLGETMINMAXPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMinmaxParameterfvEXT")) == NULL) || r; + r = ((glGetMinmaxParameterivEXT = (PFNGLGETMINMAXPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMinmaxParameterivEXT")) == NULL) || r; + r = ((glHistogramEXT = (PFNGLHISTOGRAMEXTPROC)glewGetProcAddress((const GLubyte*)"glHistogramEXT")) == NULL) || r; + r = ((glMinmaxEXT = (PFNGLMINMAXEXTPROC)glewGetProcAddress((const GLubyte*)"glMinmaxEXT")) == NULL) || r; + r = ((glResetHistogramEXT = (PFNGLRESETHISTOGRAMEXTPROC)glewGetProcAddress((const GLubyte*)"glResetHistogramEXT")) == NULL) || r; + r = ((glResetMinmaxEXT = (PFNGLRESETMINMAXEXTPROC)glewGetProcAddress((const GLubyte*)"glResetMinmaxEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_histogram */ + +#ifdef GL_EXT_index_array_formats + +#endif /* GL_EXT_index_array_formats */ + +#ifdef GL_EXT_index_func + +static GLboolean _glewInit_GL_EXT_index_func (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glIndexFuncEXT = (PFNGLINDEXFUNCEXTPROC)glewGetProcAddress((const GLubyte*)"glIndexFuncEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_index_func */ + +#ifdef GL_EXT_index_material + +static GLboolean _glewInit_GL_EXT_index_material (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glIndexMaterialEXT = (PFNGLINDEXMATERIALEXTPROC)glewGetProcAddress((const GLubyte*)"glIndexMaterialEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_index_material */ + +#ifdef GL_EXT_index_texture + +#endif /* GL_EXT_index_texture */ + +#ifdef GL_EXT_light_texture + +static GLboolean _glewInit_GL_EXT_light_texture (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glApplyTextureEXT = (PFNGLAPPLYTEXTUREEXTPROC)glewGetProcAddress((const GLubyte*)"glApplyTextureEXT")) == NULL) || r; + r = ((glTextureLightEXT = (PFNGLTEXTURELIGHTEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureLightEXT")) == NULL) || r; + r = ((glTextureMaterialEXT = (PFNGLTEXTUREMATERIALEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureMaterialEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_light_texture */ + +#ifdef GL_EXT_misc_attribute + +#endif /* GL_EXT_misc_attribute */ + +#ifdef GL_EXT_multi_draw_arrays + +static GLboolean _glewInit_GL_EXT_multi_draw_arrays (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glMultiDrawArraysEXT = (PFNGLMULTIDRAWARRAYSEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawArraysEXT")) == NULL) || r; + r = ((glMultiDrawElementsEXT = (PFNGLMULTIDRAWELEMENTSEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawElementsEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_multi_draw_arrays */ + +#ifdef GL_EXT_multisample + +static GLboolean _glewInit_GL_EXT_multisample (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glSampleMaskEXT = (PFNGLSAMPLEMASKEXTPROC)glewGetProcAddress((const GLubyte*)"glSampleMaskEXT")) == NULL) || r; + r = ((glSamplePatternEXT = (PFNGLSAMPLEPATTERNEXTPROC)glewGetProcAddress((const GLubyte*)"glSamplePatternEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_multisample */ + +#ifdef GL_EXT_packed_depth_stencil + +#endif /* GL_EXT_packed_depth_stencil */ + +#ifdef GL_EXT_packed_float + +#endif /* GL_EXT_packed_float */ + +#ifdef GL_EXT_packed_pixels + +#endif /* GL_EXT_packed_pixels */ + +#ifdef GL_EXT_paletted_texture + +static GLboolean _glewInit_GL_EXT_paletted_texture (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glColorTableEXT = (PFNGLCOLORTABLEEXTPROC)glewGetProcAddress((const GLubyte*)"glColorTableEXT")) == NULL) || r; + r = ((glGetColorTableEXT = (PFNGLGETCOLORTABLEEXTPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableEXT")) == NULL) || r; + r = ((glGetColorTableParameterfvEXT = (PFNGLGETCOLORTABLEPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableParameterfvEXT")) == NULL) || r; + r = ((glGetColorTableParameterivEXT = (PFNGLGETCOLORTABLEPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableParameterivEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_paletted_texture */ + +#ifdef GL_EXT_pixel_buffer_object + +#endif /* GL_EXT_pixel_buffer_object */ + +#ifdef GL_EXT_pixel_transform + +static GLboolean _glewInit_GL_EXT_pixel_transform (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetPixelTransformParameterfvEXT = (PFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetPixelTransformParameterfvEXT")) == NULL) || r; + r = ((glGetPixelTransformParameterivEXT = (PFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetPixelTransformParameterivEXT")) == NULL) || r; + r = ((glPixelTransformParameterfEXT = (PFNGLPIXELTRANSFORMPARAMETERFEXTPROC)glewGetProcAddress((const GLubyte*)"glPixelTransformParameterfEXT")) == NULL) || r; + r = ((glPixelTransformParameterfvEXT = (PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glPixelTransformParameterfvEXT")) == NULL) || r; + r = ((glPixelTransformParameteriEXT = (PFNGLPIXELTRANSFORMPARAMETERIEXTPROC)glewGetProcAddress((const GLubyte*)"glPixelTransformParameteriEXT")) == NULL) || r; + r = ((glPixelTransformParameterivEXT = (PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glPixelTransformParameterivEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_pixel_transform */ + +#ifdef GL_EXT_pixel_transform_color_table + +#endif /* GL_EXT_pixel_transform_color_table */ + +#ifdef GL_EXT_point_parameters + +static GLboolean _glewInit_GL_EXT_point_parameters (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glPointParameterfEXT = (PFNGLPOINTPARAMETERFEXTPROC)glewGetProcAddress((const GLubyte*)"glPointParameterfEXT")) == NULL) || r; + r = ((glPointParameterfvEXT = (PFNGLPOINTPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glPointParameterfvEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_point_parameters */ + +#ifdef GL_EXT_polygon_offset + +static GLboolean _glewInit_GL_EXT_polygon_offset (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glPolygonOffsetEXT = (PFNGLPOLYGONOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glPolygonOffsetEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_polygon_offset */ + +#ifdef GL_EXT_rescale_normal + +#endif /* GL_EXT_rescale_normal */ + +#ifdef GL_EXT_scene_marker + +static GLboolean _glewInit_GL_EXT_scene_marker (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBeginSceneEXT = (PFNGLBEGINSCENEEXTPROC)glewGetProcAddress((const GLubyte*)"glBeginSceneEXT")) == NULL) || r; + r = ((glEndSceneEXT = (PFNGLENDSCENEEXTPROC)glewGetProcAddress((const GLubyte*)"glEndSceneEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_scene_marker */ + +#ifdef GL_EXT_secondary_color + +static GLboolean _glewInit_GL_EXT_secondary_color (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glSecondaryColor3bEXT = (PFNGLSECONDARYCOLOR3BEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3bEXT")) == NULL) || r; + r = ((glSecondaryColor3bvEXT = (PFNGLSECONDARYCOLOR3BVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3bvEXT")) == NULL) || r; + r = ((glSecondaryColor3dEXT = (PFNGLSECONDARYCOLOR3DEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3dEXT")) == NULL) || r; + r = ((glSecondaryColor3dvEXT = (PFNGLSECONDARYCOLOR3DVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3dvEXT")) == NULL) || r; + r = ((glSecondaryColor3fEXT = (PFNGLSECONDARYCOLOR3FEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3fEXT")) == NULL) || r; + r = ((glSecondaryColor3fvEXT = (PFNGLSECONDARYCOLOR3FVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3fvEXT")) == NULL) || r; + r = ((glSecondaryColor3iEXT = (PFNGLSECONDARYCOLOR3IEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3iEXT")) == NULL) || r; + r = ((glSecondaryColor3ivEXT = (PFNGLSECONDARYCOLOR3IVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3ivEXT")) == NULL) || r; + r = ((glSecondaryColor3sEXT = (PFNGLSECONDARYCOLOR3SEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3sEXT")) == NULL) || r; + r = ((glSecondaryColor3svEXT = (PFNGLSECONDARYCOLOR3SVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3svEXT")) == NULL) || r; + r = ((glSecondaryColor3ubEXT = (PFNGLSECONDARYCOLOR3UBEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3ubEXT")) == NULL) || r; + r = ((glSecondaryColor3ubvEXT = (PFNGLSECONDARYCOLOR3UBVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3ubvEXT")) == NULL) || r; + r = ((glSecondaryColor3uiEXT = (PFNGLSECONDARYCOLOR3UIEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3uiEXT")) == NULL) || r; + r = ((glSecondaryColor3uivEXT = (PFNGLSECONDARYCOLOR3UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3uivEXT")) == NULL) || r; + r = ((glSecondaryColor3usEXT = (PFNGLSECONDARYCOLOR3USEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3usEXT")) == NULL) || r; + r = ((glSecondaryColor3usvEXT = (PFNGLSECONDARYCOLOR3USVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3usvEXT")) == NULL) || r; + r = ((glSecondaryColorPointerEXT = (PFNGLSECONDARYCOLORPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColorPointerEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_secondary_color */ + +#ifdef GL_EXT_separate_specular_color + +#endif /* GL_EXT_separate_specular_color */ + +#ifdef GL_EXT_shadow_funcs + +#endif /* GL_EXT_shadow_funcs */ + +#ifdef GL_EXT_shared_texture_palette + +#endif /* GL_EXT_shared_texture_palette */ + +#ifdef GL_EXT_stencil_clear_tag + +#endif /* GL_EXT_stencil_clear_tag */ + +#ifdef GL_EXT_stencil_two_side + +static GLboolean _glewInit_GL_EXT_stencil_two_side (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glActiveStencilFaceEXT = (PFNGLACTIVESTENCILFACEEXTPROC)glewGetProcAddress((const GLubyte*)"glActiveStencilFaceEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_stencil_two_side */ + +#ifdef GL_EXT_stencil_wrap + +#endif /* GL_EXT_stencil_wrap */ + +#ifdef GL_EXT_subtexture + +static GLboolean _glewInit_GL_EXT_subtexture (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glTexSubImage1DEXT = (PFNGLTEXSUBIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glTexSubImage1DEXT")) == NULL) || r; + r = ((glTexSubImage2DEXT = (PFNGLTEXSUBIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glTexSubImage2DEXT")) == NULL) || r; + r = ((glTexSubImage3DEXT = (PFNGLTEXSUBIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glTexSubImage3DEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_subtexture */ + +#ifdef GL_EXT_texture + +#endif /* GL_EXT_texture */ + +#ifdef GL_EXT_texture3D + +static GLboolean _glewInit_GL_EXT_texture3D (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glTexImage3DEXT = (PFNGLTEXIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glTexImage3DEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_texture3D */ + +#ifdef GL_EXT_texture_array + +#endif /* GL_EXT_texture_array */ + +#ifdef GL_EXT_texture_buffer_object + +static GLboolean _glewInit_GL_EXT_texture_buffer_object (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glTexBufferEXT = (PFNGLTEXBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glTexBufferEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_texture_buffer_object */ + +#ifdef GL_EXT_texture_compression_dxt1 + +#endif /* GL_EXT_texture_compression_dxt1 */ + +#ifdef GL_EXT_texture_compression_latc + +#endif /* GL_EXT_texture_compression_latc */ + +#ifdef GL_EXT_texture_compression_rgtc + +#endif /* GL_EXT_texture_compression_rgtc */ + +#ifdef GL_EXT_texture_compression_s3tc + +#endif /* GL_EXT_texture_compression_s3tc */ + +#ifdef GL_EXT_texture_cube_map + +#endif /* GL_EXT_texture_cube_map */ + +#ifdef GL_EXT_texture_edge_clamp + +#endif /* GL_EXT_texture_edge_clamp */ + +#ifdef GL_EXT_texture_env + +#endif /* GL_EXT_texture_env */ + +#ifdef GL_EXT_texture_env_add + +#endif /* GL_EXT_texture_env_add */ + +#ifdef GL_EXT_texture_env_combine + +#endif /* GL_EXT_texture_env_combine */ + +#ifdef GL_EXT_texture_env_dot3 + +#endif /* GL_EXT_texture_env_dot3 */ + +#ifdef GL_EXT_texture_filter_anisotropic + +#endif /* GL_EXT_texture_filter_anisotropic */ + +#ifdef GL_EXT_texture_integer + +static GLboolean _glewInit_GL_EXT_texture_integer (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glClearColorIiEXT = (PFNGLCLEARCOLORIIEXTPROC)glewGetProcAddress((const GLubyte*)"glClearColorIiEXT")) == NULL) || r; + r = ((glClearColorIuiEXT = (PFNGLCLEARCOLORIUIEXTPROC)glewGetProcAddress((const GLubyte*)"glClearColorIuiEXT")) == NULL) || r; + r = ((glGetTexParameterIivEXT = (PFNGLGETTEXPARAMETERIIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTexParameterIivEXT")) == NULL) || r; + r = ((glGetTexParameterIuivEXT = (PFNGLGETTEXPARAMETERIUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTexParameterIuivEXT")) == NULL) || r; + r = ((glTexParameterIivEXT = (PFNGLTEXPARAMETERIIVEXTPROC)glewGetProcAddress((const GLubyte*)"glTexParameterIivEXT")) == NULL) || r; + r = ((glTexParameterIuivEXT = (PFNGLTEXPARAMETERIUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glTexParameterIuivEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_texture_integer */ + +#ifdef GL_EXT_texture_lod_bias + +#endif /* GL_EXT_texture_lod_bias */ + +#ifdef GL_EXT_texture_mirror_clamp + +#endif /* GL_EXT_texture_mirror_clamp */ + +#ifdef GL_EXT_texture_object + +static GLboolean _glewInit_GL_EXT_texture_object (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glAreTexturesResidentEXT = (PFNGLARETEXTURESRESIDENTEXTPROC)glewGetProcAddress((const GLubyte*)"glAreTexturesResidentEXT")) == NULL) || r; + r = ((glBindTextureEXT = (PFNGLBINDTEXTUREEXTPROC)glewGetProcAddress((const GLubyte*)"glBindTextureEXT")) == NULL) || r; + r = ((glDeleteTexturesEXT = (PFNGLDELETETEXTURESEXTPROC)glewGetProcAddress((const GLubyte*)"glDeleteTexturesEXT")) == NULL) || r; + r = ((glGenTexturesEXT = (PFNGLGENTEXTURESEXTPROC)glewGetProcAddress((const GLubyte*)"glGenTexturesEXT")) == NULL) || r; + r = ((glIsTextureEXT = (PFNGLISTEXTUREEXTPROC)glewGetProcAddress((const GLubyte*)"glIsTextureEXT")) == NULL) || r; + r = ((glPrioritizeTexturesEXT = (PFNGLPRIORITIZETEXTURESEXTPROC)glewGetProcAddress((const GLubyte*)"glPrioritizeTexturesEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_texture_object */ + +#ifdef GL_EXT_texture_perturb_normal + +static GLboolean _glewInit_GL_EXT_texture_perturb_normal (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glTextureNormalEXT = (PFNGLTEXTURENORMALEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureNormalEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_texture_perturb_normal */ + +#ifdef GL_EXT_texture_rectangle + +#endif /* GL_EXT_texture_rectangle */ + +#ifdef GL_EXT_texture_sRGB + +#endif /* GL_EXT_texture_sRGB */ + +#ifdef GL_EXT_texture_shared_exponent + +#endif /* GL_EXT_texture_shared_exponent */ + +#ifdef GL_EXT_texture_swizzle + +#endif /* GL_EXT_texture_swizzle */ + +#ifdef GL_EXT_timer_query + +static GLboolean _glewInit_GL_EXT_timer_query (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetQueryObjecti64vEXT = (PFNGLGETQUERYOBJECTI64VEXTPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjecti64vEXT")) == NULL) || r; + r = ((glGetQueryObjectui64vEXT = (PFNGLGETQUERYOBJECTUI64VEXTPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjectui64vEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_timer_query */ + +#ifdef GL_EXT_transform_feedback + +static GLboolean _glewInit_GL_EXT_transform_feedback (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBeginTransformFeedbackEXT = (PFNGLBEGINTRANSFORMFEEDBACKEXTPROC)glewGetProcAddress((const GLubyte*)"glBeginTransformFeedbackEXT")) == NULL) || r; + r = ((glBindBufferBaseEXT = (PFNGLBINDBUFFERBASEEXTPROC)glewGetProcAddress((const GLubyte*)"glBindBufferBaseEXT")) == NULL) || r; + r = ((glBindBufferOffsetEXT = (PFNGLBINDBUFFEROFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glBindBufferOffsetEXT")) == NULL) || r; + r = ((glBindBufferRangeEXT = (PFNGLBINDBUFFERRANGEEXTPROC)glewGetProcAddress((const GLubyte*)"glBindBufferRangeEXT")) == NULL) || r; + r = ((glEndTransformFeedbackEXT = (PFNGLENDTRANSFORMFEEDBACKEXTPROC)glewGetProcAddress((const GLubyte*)"glEndTransformFeedbackEXT")) == NULL) || r; + r = ((glGetTransformFeedbackVaryingEXT = (PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTransformFeedbackVaryingEXT")) == NULL) || r; + r = ((glTransformFeedbackVaryingsEXT = (PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC)glewGetProcAddress((const GLubyte*)"glTransformFeedbackVaryingsEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_transform_feedback */ + +#ifdef GL_EXT_vertex_array + +static GLboolean _glewInit_GL_EXT_vertex_array (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glArrayElementEXT = (PFNGLARRAYELEMENTEXTPROC)glewGetProcAddress((const GLubyte*)"glArrayElementEXT")) == NULL) || r; + r = ((glColorPointerEXT = (PFNGLCOLORPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glColorPointerEXT")) == NULL) || r; + r = ((glDrawArraysEXT = (PFNGLDRAWARRAYSEXTPROC)glewGetProcAddress((const GLubyte*)"glDrawArraysEXT")) == NULL) || r; + r = ((glEdgeFlagPointerEXT = (PFNGLEDGEFLAGPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glEdgeFlagPointerEXT")) == NULL) || r; + r = ((glGetPointervEXT = (PFNGLGETPOINTERVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetPointervEXT")) == NULL) || r; + r = ((glIndexPointerEXT = (PFNGLINDEXPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glIndexPointerEXT")) == NULL) || r; + r = ((glNormalPointerEXT = (PFNGLNORMALPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glNormalPointerEXT")) == NULL) || r; + r = ((glTexCoordPointerEXT = (PFNGLTEXCOORDPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glTexCoordPointerEXT")) == NULL) || r; + r = ((glVertexPointerEXT = (PFNGLVERTEXPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glVertexPointerEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_vertex_array */ + +#ifdef GL_EXT_vertex_array_bgra + +#endif /* GL_EXT_vertex_array_bgra */ + +#ifdef GL_EXT_vertex_shader + +static GLboolean _glewInit_GL_EXT_vertex_shader (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBeginVertexShaderEXT = (PFNGLBEGINVERTEXSHADEREXTPROC)glewGetProcAddress((const GLubyte*)"glBeginVertexShaderEXT")) == NULL) || r; + r = ((glBindLightParameterEXT = (PFNGLBINDLIGHTPARAMETEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindLightParameterEXT")) == NULL) || r; + r = ((glBindMaterialParameterEXT = (PFNGLBINDMATERIALPARAMETEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindMaterialParameterEXT")) == NULL) || r; + r = ((glBindParameterEXT = (PFNGLBINDPARAMETEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindParameterEXT")) == NULL) || r; + r = ((glBindTexGenParameterEXT = (PFNGLBINDTEXGENPARAMETEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindTexGenParameterEXT")) == NULL) || r; + r = ((glBindTextureUnitParameterEXT = (PFNGLBINDTEXTUREUNITPARAMETEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindTextureUnitParameterEXT")) == NULL) || r; + r = ((glBindVertexShaderEXT = (PFNGLBINDVERTEXSHADEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindVertexShaderEXT")) == NULL) || r; + r = ((glDeleteVertexShaderEXT = (PFNGLDELETEVERTEXSHADEREXTPROC)glewGetProcAddress((const GLubyte*)"glDeleteVertexShaderEXT")) == NULL) || r; + r = ((glDisableVariantClientStateEXT = (PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC)glewGetProcAddress((const GLubyte*)"glDisableVariantClientStateEXT")) == NULL) || r; + r = ((glEnableVariantClientStateEXT = (PFNGLENABLEVARIANTCLIENTSTATEEXTPROC)glewGetProcAddress((const GLubyte*)"glEnableVariantClientStateEXT")) == NULL) || r; + r = ((glEndVertexShaderEXT = (PFNGLENDVERTEXSHADEREXTPROC)glewGetProcAddress((const GLubyte*)"glEndVertexShaderEXT")) == NULL) || r; + r = ((glExtractComponentEXT = (PFNGLEXTRACTCOMPONENTEXTPROC)glewGetProcAddress((const GLubyte*)"glExtractComponentEXT")) == NULL) || r; + r = ((glGenSymbolsEXT = (PFNGLGENSYMBOLSEXTPROC)glewGetProcAddress((const GLubyte*)"glGenSymbolsEXT")) == NULL) || r; + r = ((glGenVertexShadersEXT = (PFNGLGENVERTEXSHADERSEXTPROC)glewGetProcAddress((const GLubyte*)"glGenVertexShadersEXT")) == NULL) || r; + r = ((glGetInvariantBooleanvEXT = (PFNGLGETINVARIANTBOOLEANVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetInvariantBooleanvEXT")) == NULL) || r; + r = ((glGetInvariantFloatvEXT = (PFNGLGETINVARIANTFLOATVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetInvariantFloatvEXT")) == NULL) || r; + r = ((glGetInvariantIntegervEXT = (PFNGLGETINVARIANTINTEGERVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetInvariantIntegervEXT")) == NULL) || r; + r = ((glGetLocalConstantBooleanvEXT = (PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetLocalConstantBooleanvEXT")) == NULL) || r; + r = ((glGetLocalConstantFloatvEXT = (PFNGLGETLOCALCONSTANTFLOATVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetLocalConstantFloatvEXT")) == NULL) || r; + r = ((glGetLocalConstantIntegervEXT = (PFNGLGETLOCALCONSTANTINTEGERVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetLocalConstantIntegervEXT")) == NULL) || r; + r = ((glGetVariantBooleanvEXT = (PFNGLGETVARIANTBOOLEANVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVariantBooleanvEXT")) == NULL) || r; + r = ((glGetVariantFloatvEXT = (PFNGLGETVARIANTFLOATVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVariantFloatvEXT")) == NULL) || r; + r = ((glGetVariantIntegervEXT = (PFNGLGETVARIANTINTEGERVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVariantIntegervEXT")) == NULL) || r; + r = ((glGetVariantPointervEXT = (PFNGLGETVARIANTPOINTERVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVariantPointervEXT")) == NULL) || r; + r = ((glInsertComponentEXT = (PFNGLINSERTCOMPONENTEXTPROC)glewGetProcAddress((const GLubyte*)"glInsertComponentEXT")) == NULL) || r; + r = ((glIsVariantEnabledEXT = (PFNGLISVARIANTENABLEDEXTPROC)glewGetProcAddress((const GLubyte*)"glIsVariantEnabledEXT")) == NULL) || r; + r = ((glSetInvariantEXT = (PFNGLSETINVARIANTEXTPROC)glewGetProcAddress((const GLubyte*)"glSetInvariantEXT")) == NULL) || r; + r = ((glSetLocalConstantEXT = (PFNGLSETLOCALCONSTANTEXTPROC)glewGetProcAddress((const GLubyte*)"glSetLocalConstantEXT")) == NULL) || r; + r = ((glShaderOp1EXT = (PFNGLSHADEROP1EXTPROC)glewGetProcAddress((const GLubyte*)"glShaderOp1EXT")) == NULL) || r; + r = ((glShaderOp2EXT = (PFNGLSHADEROP2EXTPROC)glewGetProcAddress((const GLubyte*)"glShaderOp2EXT")) == NULL) || r; + r = ((glShaderOp3EXT = (PFNGLSHADEROP3EXTPROC)glewGetProcAddress((const GLubyte*)"glShaderOp3EXT")) == NULL) || r; + r = ((glSwizzleEXT = (PFNGLSWIZZLEEXTPROC)glewGetProcAddress((const GLubyte*)"glSwizzleEXT")) == NULL) || r; + r = ((glVariantPointerEXT = (PFNGLVARIANTPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glVariantPointerEXT")) == NULL) || r; + r = ((glVariantbvEXT = (PFNGLVARIANTBVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantbvEXT")) == NULL) || r; + r = ((glVariantdvEXT = (PFNGLVARIANTDVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantdvEXT")) == NULL) || r; + r = ((glVariantfvEXT = (PFNGLVARIANTFVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantfvEXT")) == NULL) || r; + r = ((glVariantivEXT = (PFNGLVARIANTIVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantivEXT")) == NULL) || r; + r = ((glVariantsvEXT = (PFNGLVARIANTSVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantsvEXT")) == NULL) || r; + r = ((glVariantubvEXT = (PFNGLVARIANTUBVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantubvEXT")) == NULL) || r; + r = ((glVariantuivEXT = (PFNGLVARIANTUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantuivEXT")) == NULL) || r; + r = ((glVariantusvEXT = (PFNGLVARIANTUSVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantusvEXT")) == NULL) || r; + r = ((glWriteMaskEXT = (PFNGLWRITEMASKEXTPROC)glewGetProcAddress((const GLubyte*)"glWriteMaskEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_vertex_shader */ + +#ifdef GL_EXT_vertex_weighting + +static GLboolean _glewInit_GL_EXT_vertex_weighting (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glVertexWeightPointerEXT = (PFNGLVERTEXWEIGHTPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glVertexWeightPointerEXT")) == NULL) || r; + r = ((glVertexWeightfEXT = (PFNGLVERTEXWEIGHTFEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexWeightfEXT")) == NULL) || r; + r = ((glVertexWeightfvEXT = (PFNGLVERTEXWEIGHTFVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexWeightfvEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_vertex_weighting */ + +#ifdef GL_GREMEDY_frame_terminator + +static GLboolean _glewInit_GL_GREMEDY_frame_terminator (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glFrameTerminatorGREMEDY = (PFNGLFRAMETERMINATORGREMEDYPROC)glewGetProcAddress((const GLubyte*)"glFrameTerminatorGREMEDY")) == NULL) || r; + + return r; +} + +#endif /* GL_GREMEDY_frame_terminator */ + +#ifdef GL_GREMEDY_string_marker + +static GLboolean _glewInit_GL_GREMEDY_string_marker (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glStringMarkerGREMEDY = (PFNGLSTRINGMARKERGREMEDYPROC)glewGetProcAddress((const GLubyte*)"glStringMarkerGREMEDY")) == NULL) || r; + + return r; +} + +#endif /* GL_GREMEDY_string_marker */ + +#ifdef GL_HP_convolution_border_modes + +#endif /* GL_HP_convolution_border_modes */ + +#ifdef GL_HP_image_transform + +static GLboolean _glewInit_GL_HP_image_transform (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetImageTransformParameterfvHP = (PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC)glewGetProcAddress((const GLubyte*)"glGetImageTransformParameterfvHP")) == NULL) || r; + r = ((glGetImageTransformParameterivHP = (PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC)glewGetProcAddress((const GLubyte*)"glGetImageTransformParameterivHP")) == NULL) || r; + r = ((glImageTransformParameterfHP = (PFNGLIMAGETRANSFORMPARAMETERFHPPROC)glewGetProcAddress((const GLubyte*)"glImageTransformParameterfHP")) == NULL) || r; + r = ((glImageTransformParameterfvHP = (PFNGLIMAGETRANSFORMPARAMETERFVHPPROC)glewGetProcAddress((const GLubyte*)"glImageTransformParameterfvHP")) == NULL) || r; + r = ((glImageTransformParameteriHP = (PFNGLIMAGETRANSFORMPARAMETERIHPPROC)glewGetProcAddress((const GLubyte*)"glImageTransformParameteriHP")) == NULL) || r; + r = ((glImageTransformParameterivHP = (PFNGLIMAGETRANSFORMPARAMETERIVHPPROC)glewGetProcAddress((const GLubyte*)"glImageTransformParameterivHP")) == NULL) || r; + + return r; +} + +#endif /* GL_HP_image_transform */ + +#ifdef GL_HP_occlusion_test + +#endif /* GL_HP_occlusion_test */ + +#ifdef GL_HP_texture_lighting + +#endif /* GL_HP_texture_lighting */ + +#ifdef GL_IBM_cull_vertex + +#endif /* GL_IBM_cull_vertex */ + +#ifdef GL_IBM_multimode_draw_arrays + +static GLboolean _glewInit_GL_IBM_multimode_draw_arrays (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glMultiModeDrawArraysIBM = (PFNGLMULTIMODEDRAWARRAYSIBMPROC)glewGetProcAddress((const GLubyte*)"glMultiModeDrawArraysIBM")) == NULL) || r; + r = ((glMultiModeDrawElementsIBM = (PFNGLMULTIMODEDRAWELEMENTSIBMPROC)glewGetProcAddress((const GLubyte*)"glMultiModeDrawElementsIBM")) == NULL) || r; + + return r; +} + +#endif /* GL_IBM_multimode_draw_arrays */ + +#ifdef GL_IBM_rasterpos_clip + +#endif /* GL_IBM_rasterpos_clip */ + +#ifdef GL_IBM_static_data + +#endif /* GL_IBM_static_data */ + +#ifdef GL_IBM_texture_mirrored_repeat + +#endif /* GL_IBM_texture_mirrored_repeat */ + +#ifdef GL_IBM_vertex_array_lists + +static GLboolean _glewInit_GL_IBM_vertex_array_lists (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glColorPointerListIBM = (PFNGLCOLORPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glColorPointerListIBM")) == NULL) || r; + r = ((glEdgeFlagPointerListIBM = (PFNGLEDGEFLAGPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glEdgeFlagPointerListIBM")) == NULL) || r; + r = ((glFogCoordPointerListIBM = (PFNGLFOGCOORDPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glFogCoordPointerListIBM")) == NULL) || r; + r = ((glIndexPointerListIBM = (PFNGLINDEXPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glIndexPointerListIBM")) == NULL) || r; + r = ((glNormalPointerListIBM = (PFNGLNORMALPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glNormalPointerListIBM")) == NULL) || r; + r = ((glSecondaryColorPointerListIBM = (PFNGLSECONDARYCOLORPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColorPointerListIBM")) == NULL) || r; + r = ((glTexCoordPointerListIBM = (PFNGLTEXCOORDPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glTexCoordPointerListIBM")) == NULL) || r; + r = ((glVertexPointerListIBM = (PFNGLVERTEXPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glVertexPointerListIBM")) == NULL) || r; + + return r; +} + +#endif /* GL_IBM_vertex_array_lists */ + +#ifdef GL_INGR_color_clamp + +#endif /* GL_INGR_color_clamp */ + +#ifdef GL_INGR_interlace_read + +#endif /* GL_INGR_interlace_read */ + +#ifdef GL_INTEL_parallel_arrays + +static GLboolean _glewInit_GL_INTEL_parallel_arrays (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glColorPointervINTEL = (PFNGLCOLORPOINTERVINTELPROC)glewGetProcAddress((const GLubyte*)"glColorPointervINTEL")) == NULL) || r; + r = ((glNormalPointervINTEL = (PFNGLNORMALPOINTERVINTELPROC)glewGetProcAddress((const GLubyte*)"glNormalPointervINTEL")) == NULL) || r; + r = ((glTexCoordPointervINTEL = (PFNGLTEXCOORDPOINTERVINTELPROC)glewGetProcAddress((const GLubyte*)"glTexCoordPointervINTEL")) == NULL) || r; + r = ((glVertexPointervINTEL = (PFNGLVERTEXPOINTERVINTELPROC)glewGetProcAddress((const GLubyte*)"glVertexPointervINTEL")) == NULL) || r; + + return r; +} + +#endif /* GL_INTEL_parallel_arrays */ + +#ifdef GL_INTEL_texture_scissor + +static GLboolean _glewInit_GL_INTEL_texture_scissor (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glTexScissorFuncINTEL = (PFNGLTEXSCISSORFUNCINTELPROC)glewGetProcAddress((const GLubyte*)"glTexScissorFuncINTEL")) == NULL) || r; + r = ((glTexScissorINTEL = (PFNGLTEXSCISSORINTELPROC)glewGetProcAddress((const GLubyte*)"glTexScissorINTEL")) == NULL) || r; + + return r; +} + +#endif /* GL_INTEL_texture_scissor */ + +#ifdef GL_KTX_buffer_region + +static GLboolean _glewInit_GL_KTX_buffer_region (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBufferRegionEnabledEXT = (PFNGLBUFFERREGIONENABLEDEXTPROC)glewGetProcAddress((const GLubyte*)"glBufferRegionEnabledEXT")) == NULL) || r; + r = ((glDeleteBufferRegionEXT = (PFNGLDELETEBUFFERREGIONEXTPROC)glewGetProcAddress((const GLubyte*)"glDeleteBufferRegionEXT")) == NULL) || r; + r = ((glDrawBufferRegionEXT = (PFNGLDRAWBUFFERREGIONEXTPROC)glewGetProcAddress((const GLubyte*)"glDrawBufferRegionEXT")) == NULL) || r; + r = ((glNewBufferRegionEXT = (PFNGLNEWBUFFERREGIONEXTPROC)glewGetProcAddress((const GLubyte*)"glNewBufferRegionEXT")) == NULL) || r; + r = ((glReadBufferRegionEXT = (PFNGLREADBUFFERREGIONEXTPROC)glewGetProcAddress((const GLubyte*)"glReadBufferRegionEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_KTX_buffer_region */ + +#ifdef GL_MESAX_texture_stack + +#endif /* GL_MESAX_texture_stack */ + +#ifdef GL_MESA_pack_invert + +#endif /* GL_MESA_pack_invert */ + +#ifdef GL_MESA_resize_buffers + +static GLboolean _glewInit_GL_MESA_resize_buffers (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glResizeBuffersMESA = (PFNGLRESIZEBUFFERSMESAPROC)glewGetProcAddress((const GLubyte*)"glResizeBuffersMESA")) == NULL) || r; + + return r; +} + +#endif /* GL_MESA_resize_buffers */ + +#ifdef GL_MESA_window_pos + +static GLboolean _glewInit_GL_MESA_window_pos (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glWindowPos2dMESA = (PFNGLWINDOWPOS2DMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2dMESA")) == NULL) || r; + r = ((glWindowPos2dvMESA = (PFNGLWINDOWPOS2DVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2dvMESA")) == NULL) || r; + r = ((glWindowPos2fMESA = (PFNGLWINDOWPOS2FMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2fMESA")) == NULL) || r; + r = ((glWindowPos2fvMESA = (PFNGLWINDOWPOS2FVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2fvMESA")) == NULL) || r; + r = ((glWindowPos2iMESA = (PFNGLWINDOWPOS2IMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2iMESA")) == NULL) || r; + r = ((glWindowPos2ivMESA = (PFNGLWINDOWPOS2IVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2ivMESA")) == NULL) || r; + r = ((glWindowPos2sMESA = (PFNGLWINDOWPOS2SMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2sMESA")) == NULL) || r; + r = ((glWindowPos2svMESA = (PFNGLWINDOWPOS2SVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2svMESA")) == NULL) || r; + r = ((glWindowPos3dMESA = (PFNGLWINDOWPOS3DMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3dMESA")) == NULL) || r; + r = ((glWindowPos3dvMESA = (PFNGLWINDOWPOS3DVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3dvMESA")) == NULL) || r; + r = ((glWindowPos3fMESA = (PFNGLWINDOWPOS3FMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3fMESA")) == NULL) || r; + r = ((glWindowPos3fvMESA = (PFNGLWINDOWPOS3FVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3fvMESA")) == NULL) || r; + r = ((glWindowPos3iMESA = (PFNGLWINDOWPOS3IMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3iMESA")) == NULL) || r; + r = ((glWindowPos3ivMESA = (PFNGLWINDOWPOS3IVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3ivMESA")) == NULL) || r; + r = ((glWindowPos3sMESA = (PFNGLWINDOWPOS3SMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3sMESA")) == NULL) || r; + r = ((glWindowPos3svMESA = (PFNGLWINDOWPOS3SVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3svMESA")) == NULL) || r; + r = ((glWindowPos4dMESA = (PFNGLWINDOWPOS4DMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4dMESA")) == NULL) || r; + r = ((glWindowPos4dvMESA = (PFNGLWINDOWPOS4DVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4dvMESA")) == NULL) || r; + r = ((glWindowPos4fMESA = (PFNGLWINDOWPOS4FMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4fMESA")) == NULL) || r; + r = ((glWindowPos4fvMESA = (PFNGLWINDOWPOS4FVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4fvMESA")) == NULL) || r; + r = ((glWindowPos4iMESA = (PFNGLWINDOWPOS4IMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4iMESA")) == NULL) || r; + r = ((glWindowPos4ivMESA = (PFNGLWINDOWPOS4IVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4ivMESA")) == NULL) || r; + r = ((glWindowPos4sMESA = (PFNGLWINDOWPOS4SMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4sMESA")) == NULL) || r; + r = ((glWindowPos4svMESA = (PFNGLWINDOWPOS4SVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4svMESA")) == NULL) || r; + + return r; +} + +#endif /* GL_MESA_window_pos */ + +#ifdef GL_MESA_ycbcr_texture + +#endif /* GL_MESA_ycbcr_texture */ + +#ifdef GL_NV_blend_square + +#endif /* GL_NV_blend_square */ + +#ifdef GL_NV_conditional_render + +static GLboolean _glewInit_GL_NV_conditional_render (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBeginConditionalRenderNV = (PFNGLBEGINCONDITIONALRENDERNVPROC)glewGetProcAddress((const GLubyte*)"glBeginConditionalRenderNV")) == NULL) || r; + r = ((glEndConditionalRenderNV = (PFNGLENDCONDITIONALRENDERNVPROC)glewGetProcAddress((const GLubyte*)"glEndConditionalRenderNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_conditional_render */ + +#ifdef GL_NV_copy_depth_to_color + +#endif /* GL_NV_copy_depth_to_color */ + +#ifdef GL_NV_depth_buffer_float + +static GLboolean _glewInit_GL_NV_depth_buffer_float (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glClearDepthdNV = (PFNGLCLEARDEPTHDNVPROC)glewGetProcAddress((const GLubyte*)"glClearDepthdNV")) == NULL) || r; + r = ((glDepthBoundsdNV = (PFNGLDEPTHBOUNDSDNVPROC)glewGetProcAddress((const GLubyte*)"glDepthBoundsdNV")) == NULL) || r; + r = ((glDepthRangedNV = (PFNGLDEPTHRANGEDNVPROC)glewGetProcAddress((const GLubyte*)"glDepthRangedNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_depth_buffer_float */ + +#ifdef GL_NV_depth_clamp + +#endif /* GL_NV_depth_clamp */ + +#ifdef GL_NV_depth_range_unclamped + +#endif /* GL_NV_depth_range_unclamped */ + +#ifdef GL_NV_evaluators + +static GLboolean _glewInit_GL_NV_evaluators (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glEvalMapsNV = (PFNGLEVALMAPSNVPROC)glewGetProcAddress((const GLubyte*)"glEvalMapsNV")) == NULL) || r; + r = ((glGetMapAttribParameterfvNV = (PFNGLGETMAPATTRIBPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetMapAttribParameterfvNV")) == NULL) || r; + r = ((glGetMapAttribParameterivNV = (PFNGLGETMAPATTRIBPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetMapAttribParameterivNV")) == NULL) || r; + r = ((glGetMapControlPointsNV = (PFNGLGETMAPCONTROLPOINTSNVPROC)glewGetProcAddress((const GLubyte*)"glGetMapControlPointsNV")) == NULL) || r; + r = ((glGetMapParameterfvNV = (PFNGLGETMAPPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetMapParameterfvNV")) == NULL) || r; + r = ((glGetMapParameterivNV = (PFNGLGETMAPPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetMapParameterivNV")) == NULL) || r; + r = ((glMapControlPointsNV = (PFNGLMAPCONTROLPOINTSNVPROC)glewGetProcAddress((const GLubyte*)"glMapControlPointsNV")) == NULL) || r; + r = ((glMapParameterfvNV = (PFNGLMAPPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glMapParameterfvNV")) == NULL) || r; + r = ((glMapParameterivNV = (PFNGLMAPPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glMapParameterivNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_evaluators */ + +#ifdef GL_NV_explicit_multisample + +static GLboolean _glewInit_GL_NV_explicit_multisample (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetMultisamplefvNV = (PFNGLGETMULTISAMPLEFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetMultisamplefvNV")) == NULL) || r; + r = ((glSampleMaskIndexedNV = (PFNGLSAMPLEMASKINDEXEDNVPROC)glewGetProcAddress((const GLubyte*)"glSampleMaskIndexedNV")) == NULL) || r; + r = ((glTexRenderbufferNV = (PFNGLTEXRENDERBUFFERNVPROC)glewGetProcAddress((const GLubyte*)"glTexRenderbufferNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_explicit_multisample */ + +#ifdef GL_NV_fence + +static GLboolean _glewInit_GL_NV_fence (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glDeleteFencesNV = (PFNGLDELETEFENCESNVPROC)glewGetProcAddress((const GLubyte*)"glDeleteFencesNV")) == NULL) || r; + r = ((glFinishFenceNV = (PFNGLFINISHFENCENVPROC)glewGetProcAddress((const GLubyte*)"glFinishFenceNV")) == NULL) || r; + r = ((glGenFencesNV = (PFNGLGENFENCESNVPROC)glewGetProcAddress((const GLubyte*)"glGenFencesNV")) == NULL) || r; + r = ((glGetFenceivNV = (PFNGLGETFENCEIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetFenceivNV")) == NULL) || r; + r = ((glIsFenceNV = (PFNGLISFENCENVPROC)glewGetProcAddress((const GLubyte*)"glIsFenceNV")) == NULL) || r; + r = ((glSetFenceNV = (PFNGLSETFENCENVPROC)glewGetProcAddress((const GLubyte*)"glSetFenceNV")) == NULL) || r; + r = ((glTestFenceNV = (PFNGLTESTFENCENVPROC)glewGetProcAddress((const GLubyte*)"glTestFenceNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_fence */ + +#ifdef GL_NV_float_buffer + +#endif /* GL_NV_float_buffer */ + +#ifdef GL_NV_fog_distance + +#endif /* GL_NV_fog_distance */ + +#ifdef GL_NV_fragment_program + +static GLboolean _glewInit_GL_NV_fragment_program (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetProgramNamedParameterdvNV = (PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramNamedParameterdvNV")) == NULL) || r; + r = ((glGetProgramNamedParameterfvNV = (PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramNamedParameterfvNV")) == NULL) || r; + r = ((glProgramNamedParameter4dNV = (PFNGLPROGRAMNAMEDPARAMETER4DNVPROC)glewGetProcAddress((const GLubyte*)"glProgramNamedParameter4dNV")) == NULL) || r; + r = ((glProgramNamedParameter4dvNV = (PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramNamedParameter4dvNV")) == NULL) || r; + r = ((glProgramNamedParameter4fNV = (PFNGLPROGRAMNAMEDPARAMETER4FNVPROC)glewGetProcAddress((const GLubyte*)"glProgramNamedParameter4fNV")) == NULL) || r; + r = ((glProgramNamedParameter4fvNV = (PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramNamedParameter4fvNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_fragment_program */ + +#ifdef GL_NV_fragment_program2 + +#endif /* GL_NV_fragment_program2 */ + +#ifdef GL_NV_fragment_program4 + +#endif /* GL_NV_fragment_program4 */ + +#ifdef GL_NV_fragment_program_option + +#endif /* GL_NV_fragment_program_option */ + +#ifdef GL_NV_framebuffer_multisample_coverage + +static GLboolean _glewInit_GL_NV_framebuffer_multisample_coverage (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glRenderbufferStorageMultisampleCoverageNV = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC)glewGetProcAddress((const GLubyte*)"glRenderbufferStorageMultisampleCoverageNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_framebuffer_multisample_coverage */ + +#ifdef GL_NV_geometry_program4 + +static GLboolean _glewInit_GL_NV_geometry_program4 (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glProgramVertexLimitNV = (PFNGLPROGRAMVERTEXLIMITNVPROC)glewGetProcAddress((const GLubyte*)"glProgramVertexLimitNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_geometry_program4 */ + +#ifdef GL_NV_geometry_shader4 + +#endif /* GL_NV_geometry_shader4 */ + +#ifdef GL_NV_gpu_program4 + +static GLboolean _glewInit_GL_NV_gpu_program4 (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glProgramEnvParameterI4iNV = (PFNGLPROGRAMENVPARAMETERI4INVPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameterI4iNV")) == NULL) || r; + r = ((glProgramEnvParameterI4ivNV = (PFNGLPROGRAMENVPARAMETERI4IVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameterI4ivNV")) == NULL) || r; + r = ((glProgramEnvParameterI4uiNV = (PFNGLPROGRAMENVPARAMETERI4UINVPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameterI4uiNV")) == NULL) || r; + r = ((glProgramEnvParameterI4uivNV = (PFNGLPROGRAMENVPARAMETERI4UIVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameterI4uivNV")) == NULL) || r; + r = ((glProgramEnvParametersI4ivNV = (PFNGLPROGRAMENVPARAMETERSI4IVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParametersI4ivNV")) == NULL) || r; + r = ((glProgramEnvParametersI4uivNV = (PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParametersI4uivNV")) == NULL) || r; + r = ((glProgramLocalParameterI4iNV = (PFNGLPROGRAMLOCALPARAMETERI4INVPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameterI4iNV")) == NULL) || r; + r = ((glProgramLocalParameterI4ivNV = (PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameterI4ivNV")) == NULL) || r; + r = ((glProgramLocalParameterI4uiNV = (PFNGLPROGRAMLOCALPARAMETERI4UINVPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameterI4uiNV")) == NULL) || r; + r = ((glProgramLocalParameterI4uivNV = (PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameterI4uivNV")) == NULL) || r; + r = ((glProgramLocalParametersI4ivNV = (PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParametersI4ivNV")) == NULL) || r; + r = ((glProgramLocalParametersI4uivNV = (PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParametersI4uivNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_gpu_program4 */ + +#ifdef GL_NV_half_float + +static GLboolean _glewInit_GL_NV_half_float (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glColor3hNV = (PFNGLCOLOR3HNVPROC)glewGetProcAddress((const GLubyte*)"glColor3hNV")) == NULL) || r; + r = ((glColor3hvNV = (PFNGLCOLOR3HVNVPROC)glewGetProcAddress((const GLubyte*)"glColor3hvNV")) == NULL) || r; + r = ((glColor4hNV = (PFNGLCOLOR4HNVPROC)glewGetProcAddress((const GLubyte*)"glColor4hNV")) == NULL) || r; + r = ((glColor4hvNV = (PFNGLCOLOR4HVNVPROC)glewGetProcAddress((const GLubyte*)"glColor4hvNV")) == NULL) || r; + r = ((glFogCoordhNV = (PFNGLFOGCOORDHNVPROC)glewGetProcAddress((const GLubyte*)"glFogCoordhNV")) == NULL) || r; + r = ((glFogCoordhvNV = (PFNGLFOGCOORDHVNVPROC)glewGetProcAddress((const GLubyte*)"glFogCoordhvNV")) == NULL) || r; + r = ((glMultiTexCoord1hNV = (PFNGLMULTITEXCOORD1HNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1hNV")) == NULL) || r; + r = ((glMultiTexCoord1hvNV = (PFNGLMULTITEXCOORD1HVNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1hvNV")) == NULL) || r; + r = ((glMultiTexCoord2hNV = (PFNGLMULTITEXCOORD2HNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2hNV")) == NULL) || r; + r = ((glMultiTexCoord2hvNV = (PFNGLMULTITEXCOORD2HVNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2hvNV")) == NULL) || r; + r = ((glMultiTexCoord3hNV = (PFNGLMULTITEXCOORD3HNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3hNV")) == NULL) || r; + r = ((glMultiTexCoord3hvNV = (PFNGLMULTITEXCOORD3HVNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3hvNV")) == NULL) || r; + r = ((glMultiTexCoord4hNV = (PFNGLMULTITEXCOORD4HNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4hNV")) == NULL) || r; + r = ((glMultiTexCoord4hvNV = (PFNGLMULTITEXCOORD4HVNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4hvNV")) == NULL) || r; + r = ((glNormal3hNV = (PFNGLNORMAL3HNVPROC)glewGetProcAddress((const GLubyte*)"glNormal3hNV")) == NULL) || r; + r = ((glNormal3hvNV = (PFNGLNORMAL3HVNVPROC)glewGetProcAddress((const GLubyte*)"glNormal3hvNV")) == NULL) || r; + r = ((glSecondaryColor3hNV = (PFNGLSECONDARYCOLOR3HNVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3hNV")) == NULL) || r; + r = ((glSecondaryColor3hvNV = (PFNGLSECONDARYCOLOR3HVNVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3hvNV")) == NULL) || r; + r = ((glTexCoord1hNV = (PFNGLTEXCOORD1HNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord1hNV")) == NULL) || r; + r = ((glTexCoord1hvNV = (PFNGLTEXCOORD1HVNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord1hvNV")) == NULL) || r; + r = ((glTexCoord2hNV = (PFNGLTEXCOORD2HNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2hNV")) == NULL) || r; + r = ((glTexCoord2hvNV = (PFNGLTEXCOORD2HVNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2hvNV")) == NULL) || r; + r = ((glTexCoord3hNV = (PFNGLTEXCOORD3HNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord3hNV")) == NULL) || r; + r = ((glTexCoord3hvNV = (PFNGLTEXCOORD3HVNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord3hvNV")) == NULL) || r; + r = ((glTexCoord4hNV = (PFNGLTEXCOORD4HNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord4hNV")) == NULL) || r; + r = ((glTexCoord4hvNV = (PFNGLTEXCOORD4HVNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord4hvNV")) == NULL) || r; + r = ((glVertex2hNV = (PFNGLVERTEX2HNVPROC)glewGetProcAddress((const GLubyte*)"glVertex2hNV")) == NULL) || r; + r = ((glVertex2hvNV = (PFNGLVERTEX2HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertex2hvNV")) == NULL) || r; + r = ((glVertex3hNV = (PFNGLVERTEX3HNVPROC)glewGetProcAddress((const GLubyte*)"glVertex3hNV")) == NULL) || r; + r = ((glVertex3hvNV = (PFNGLVERTEX3HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertex3hvNV")) == NULL) || r; + r = ((glVertex4hNV = (PFNGLVERTEX4HNVPROC)glewGetProcAddress((const GLubyte*)"glVertex4hNV")) == NULL) || r; + r = ((glVertex4hvNV = (PFNGLVERTEX4HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertex4hvNV")) == NULL) || r; + r = ((glVertexAttrib1hNV = (PFNGLVERTEXATTRIB1HNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1hNV")) == NULL) || r; + r = ((glVertexAttrib1hvNV = (PFNGLVERTEXATTRIB1HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1hvNV")) == NULL) || r; + r = ((glVertexAttrib2hNV = (PFNGLVERTEXATTRIB2HNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2hNV")) == NULL) || r; + r = ((glVertexAttrib2hvNV = (PFNGLVERTEXATTRIB2HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2hvNV")) == NULL) || r; + r = ((glVertexAttrib3hNV = (PFNGLVERTEXATTRIB3HNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3hNV")) == NULL) || r; + r = ((glVertexAttrib3hvNV = (PFNGLVERTEXATTRIB3HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3hvNV")) == NULL) || r; + r = ((glVertexAttrib4hNV = (PFNGLVERTEXATTRIB4HNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4hNV")) == NULL) || r; + r = ((glVertexAttrib4hvNV = (PFNGLVERTEXATTRIB4HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4hvNV")) == NULL) || r; + r = ((glVertexAttribs1hvNV = (PFNGLVERTEXATTRIBS1HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs1hvNV")) == NULL) || r; + r = ((glVertexAttribs2hvNV = (PFNGLVERTEXATTRIBS2HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs2hvNV")) == NULL) || r; + r = ((glVertexAttribs3hvNV = (PFNGLVERTEXATTRIBS3HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs3hvNV")) == NULL) || r; + r = ((glVertexAttribs4hvNV = (PFNGLVERTEXATTRIBS4HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs4hvNV")) == NULL) || r; + r = ((glVertexWeighthNV = (PFNGLVERTEXWEIGHTHNVPROC)glewGetProcAddress((const GLubyte*)"glVertexWeighthNV")) == NULL) || r; + r = ((glVertexWeighthvNV = (PFNGLVERTEXWEIGHTHVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexWeighthvNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_half_float */ + +#ifdef GL_NV_light_max_exponent + +#endif /* GL_NV_light_max_exponent */ + +#ifdef GL_NV_multisample_filter_hint + +#endif /* GL_NV_multisample_filter_hint */ + +#ifdef GL_NV_occlusion_query + +static GLboolean _glewInit_GL_NV_occlusion_query (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBeginOcclusionQueryNV = (PFNGLBEGINOCCLUSIONQUERYNVPROC)glewGetProcAddress((const GLubyte*)"glBeginOcclusionQueryNV")) == NULL) || r; + r = ((glDeleteOcclusionQueriesNV = (PFNGLDELETEOCCLUSIONQUERIESNVPROC)glewGetProcAddress((const GLubyte*)"glDeleteOcclusionQueriesNV")) == NULL) || r; + r = ((glEndOcclusionQueryNV = (PFNGLENDOCCLUSIONQUERYNVPROC)glewGetProcAddress((const GLubyte*)"glEndOcclusionQueryNV")) == NULL) || r; + r = ((glGenOcclusionQueriesNV = (PFNGLGENOCCLUSIONQUERIESNVPROC)glewGetProcAddress((const GLubyte*)"glGenOcclusionQueriesNV")) == NULL) || r; + r = ((glGetOcclusionQueryivNV = (PFNGLGETOCCLUSIONQUERYIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetOcclusionQueryivNV")) == NULL) || r; + r = ((glGetOcclusionQueryuivNV = (PFNGLGETOCCLUSIONQUERYUIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetOcclusionQueryuivNV")) == NULL) || r; + r = ((glIsOcclusionQueryNV = (PFNGLISOCCLUSIONQUERYNVPROC)glewGetProcAddress((const GLubyte*)"glIsOcclusionQueryNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_occlusion_query */ + +#ifdef GL_NV_packed_depth_stencil + +#endif /* GL_NV_packed_depth_stencil */ + +#ifdef GL_NV_parameter_buffer_object + +static GLboolean _glewInit_GL_NV_parameter_buffer_object (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glProgramBufferParametersIivNV = (PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramBufferParametersIivNV")) == NULL) || r; + r = ((glProgramBufferParametersIuivNV = (PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramBufferParametersIuivNV")) == NULL) || r; + r = ((glProgramBufferParametersfvNV = (PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramBufferParametersfvNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_parameter_buffer_object */ + +#ifdef GL_NV_pixel_data_range + +static GLboolean _glewInit_GL_NV_pixel_data_range (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glFlushPixelDataRangeNV = (PFNGLFLUSHPIXELDATARANGENVPROC)glewGetProcAddress((const GLubyte*)"glFlushPixelDataRangeNV")) == NULL) || r; + r = ((glPixelDataRangeNV = (PFNGLPIXELDATARANGENVPROC)glewGetProcAddress((const GLubyte*)"glPixelDataRangeNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_pixel_data_range */ + +#ifdef GL_NV_point_sprite + +static GLboolean _glewInit_GL_NV_point_sprite (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glPointParameteriNV = (PFNGLPOINTPARAMETERINVPROC)glewGetProcAddress((const GLubyte*)"glPointParameteriNV")) == NULL) || r; + r = ((glPointParameterivNV = (PFNGLPOINTPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glPointParameterivNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_point_sprite */ + +#ifdef GL_NV_present_video + +static GLboolean _glewInit_GL_NV_present_video (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetVideoi64vNV = (PFNGLGETVIDEOI64VNVPROC)glewGetProcAddress((const GLubyte*)"glGetVideoi64vNV")) == NULL) || r; + r = ((glGetVideoivNV = (PFNGLGETVIDEOIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVideoivNV")) == NULL) || r; + r = ((glGetVideoui64vNV = (PFNGLGETVIDEOUI64VNVPROC)glewGetProcAddress((const GLubyte*)"glGetVideoui64vNV")) == NULL) || r; + r = ((glGetVideouivNV = (PFNGLGETVIDEOUIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVideouivNV")) == NULL) || r; + r = ((glPresentFrameDualFillNV = (PFNGLPRESENTFRAMEDUALFILLNVPROC)glewGetProcAddress((const GLubyte*)"glPresentFrameDualFillNV")) == NULL) || r; + r = ((glPresentFrameKeyedNV = (PFNGLPRESENTFRAMEKEYEDNVPROC)glewGetProcAddress((const GLubyte*)"glPresentFrameKeyedNV")) == NULL) || r; + r = ((glVideoParameterivNV = (PFNGLVIDEOPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glVideoParameterivNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_present_video */ + +#ifdef GL_NV_primitive_restart + +static GLboolean _glewInit_GL_NV_primitive_restart (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glPrimitiveRestartIndexNV = (PFNGLPRIMITIVERESTARTINDEXNVPROC)glewGetProcAddress((const GLubyte*)"glPrimitiveRestartIndexNV")) == NULL) || r; + r = ((glPrimitiveRestartNV = (PFNGLPRIMITIVERESTARTNVPROC)glewGetProcAddress((const GLubyte*)"glPrimitiveRestartNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_primitive_restart */ + +#ifdef GL_NV_register_combiners + +static GLboolean _glewInit_GL_NV_register_combiners (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glCombinerInputNV = (PFNGLCOMBINERINPUTNVPROC)glewGetProcAddress((const GLubyte*)"glCombinerInputNV")) == NULL) || r; + r = ((glCombinerOutputNV = (PFNGLCOMBINEROUTPUTNVPROC)glewGetProcAddress((const GLubyte*)"glCombinerOutputNV")) == NULL) || r; + r = ((glCombinerParameterfNV = (PFNGLCOMBINERPARAMETERFNVPROC)glewGetProcAddress((const GLubyte*)"glCombinerParameterfNV")) == NULL) || r; + r = ((glCombinerParameterfvNV = (PFNGLCOMBINERPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glCombinerParameterfvNV")) == NULL) || r; + r = ((glCombinerParameteriNV = (PFNGLCOMBINERPARAMETERINVPROC)glewGetProcAddress((const GLubyte*)"glCombinerParameteriNV")) == NULL) || r; + r = ((glCombinerParameterivNV = (PFNGLCOMBINERPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glCombinerParameterivNV")) == NULL) || r; + r = ((glFinalCombinerInputNV = (PFNGLFINALCOMBINERINPUTNVPROC)glewGetProcAddress((const GLubyte*)"glFinalCombinerInputNV")) == NULL) || r; + r = ((glGetCombinerInputParameterfvNV = (PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetCombinerInputParameterfvNV")) == NULL) || r; + r = ((glGetCombinerInputParameterivNV = (PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetCombinerInputParameterivNV")) == NULL) || r; + r = ((glGetCombinerOutputParameterfvNV = (PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetCombinerOutputParameterfvNV")) == NULL) || r; + r = ((glGetCombinerOutputParameterivNV = (PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetCombinerOutputParameterivNV")) == NULL) || r; + r = ((glGetFinalCombinerInputParameterfvNV = (PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetFinalCombinerInputParameterfvNV")) == NULL) || r; + r = ((glGetFinalCombinerInputParameterivNV = (PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetFinalCombinerInputParameterivNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_register_combiners */ + +#ifdef GL_NV_register_combiners2 + +static GLboolean _glewInit_GL_NV_register_combiners2 (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glCombinerStageParameterfvNV = (PFNGLCOMBINERSTAGEPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glCombinerStageParameterfvNV")) == NULL) || r; + r = ((glGetCombinerStageParameterfvNV = (PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetCombinerStageParameterfvNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_register_combiners2 */ + +#ifdef GL_NV_texgen_emboss + +#endif /* GL_NV_texgen_emboss */ + +#ifdef GL_NV_texgen_reflection + +#endif /* GL_NV_texgen_reflection */ + +#ifdef GL_NV_texture_compression_vtc + +#endif /* GL_NV_texture_compression_vtc */ + +#ifdef GL_NV_texture_env_combine4 + +#endif /* GL_NV_texture_env_combine4 */ + +#ifdef GL_NV_texture_expand_normal + +#endif /* GL_NV_texture_expand_normal */ + +#ifdef GL_NV_texture_rectangle + +#endif /* GL_NV_texture_rectangle */ + +#ifdef GL_NV_texture_shader + +#endif /* GL_NV_texture_shader */ + +#ifdef GL_NV_texture_shader2 + +#endif /* GL_NV_texture_shader2 */ + +#ifdef GL_NV_texture_shader3 + +#endif /* GL_NV_texture_shader3 */ + +#ifdef GL_NV_transform_feedback + +static GLboolean _glewInit_GL_NV_transform_feedback (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glActiveVaryingNV = (PFNGLACTIVEVARYINGNVPROC)glewGetProcAddress((const GLubyte*)"glActiveVaryingNV")) == NULL) || r; + r = ((glBeginTransformFeedbackNV = (PFNGLBEGINTRANSFORMFEEDBACKNVPROC)glewGetProcAddress((const GLubyte*)"glBeginTransformFeedbackNV")) == NULL) || r; + r = ((glBindBufferBaseNV = (PFNGLBINDBUFFERBASENVPROC)glewGetProcAddress((const GLubyte*)"glBindBufferBaseNV")) == NULL) || r; + r = ((glBindBufferOffsetNV = (PFNGLBINDBUFFEROFFSETNVPROC)glewGetProcAddress((const GLubyte*)"glBindBufferOffsetNV")) == NULL) || r; + r = ((glBindBufferRangeNV = (PFNGLBINDBUFFERRANGENVPROC)glewGetProcAddress((const GLubyte*)"glBindBufferRangeNV")) == NULL) || r; + r = ((glEndTransformFeedbackNV = (PFNGLENDTRANSFORMFEEDBACKNVPROC)glewGetProcAddress((const GLubyte*)"glEndTransformFeedbackNV")) == NULL) || r; + r = ((glGetActiveVaryingNV = (PFNGLGETACTIVEVARYINGNVPROC)glewGetProcAddress((const GLubyte*)"glGetActiveVaryingNV")) == NULL) || r; + r = ((glGetTransformFeedbackVaryingNV = (PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC)glewGetProcAddress((const GLubyte*)"glGetTransformFeedbackVaryingNV")) == NULL) || r; + r = ((glGetVaryingLocationNV = (PFNGLGETVARYINGLOCATIONNVPROC)glewGetProcAddress((const GLubyte*)"glGetVaryingLocationNV")) == NULL) || r; + r = ((glTransformFeedbackAttribsNV = (PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC)glewGetProcAddress((const GLubyte*)"glTransformFeedbackAttribsNV")) == NULL) || r; + r = ((glTransformFeedbackVaryingsNV = (PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC)glewGetProcAddress((const GLubyte*)"glTransformFeedbackVaryingsNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_transform_feedback */ + +#ifdef GL_NV_vertex_array_range + +static GLboolean _glewInit_GL_NV_vertex_array_range (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glFlushVertexArrayRangeNV = (PFNGLFLUSHVERTEXARRAYRANGENVPROC)glewGetProcAddress((const GLubyte*)"glFlushVertexArrayRangeNV")) == NULL) || r; + r = ((glVertexArrayRangeNV = (PFNGLVERTEXARRAYRANGENVPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayRangeNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_vertex_array_range */ + +#ifdef GL_NV_vertex_array_range2 + +#endif /* GL_NV_vertex_array_range2 */ + +#ifdef GL_NV_vertex_program + +static GLboolean _glewInit_GL_NV_vertex_program (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glAreProgramsResidentNV = (PFNGLAREPROGRAMSRESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glAreProgramsResidentNV")) == NULL) || r; + r = ((glBindProgramNV = (PFNGLBINDPROGRAMNVPROC)glewGetProcAddress((const GLubyte*)"glBindProgramNV")) == NULL) || r; + r = ((glDeleteProgramsNV = (PFNGLDELETEPROGRAMSNVPROC)glewGetProcAddress((const GLubyte*)"glDeleteProgramsNV")) == NULL) || r; + r = ((glExecuteProgramNV = (PFNGLEXECUTEPROGRAMNVPROC)glewGetProcAddress((const GLubyte*)"glExecuteProgramNV")) == NULL) || r; + r = ((glGenProgramsNV = (PFNGLGENPROGRAMSNVPROC)glewGetProcAddress((const GLubyte*)"glGenProgramsNV")) == NULL) || r; + r = ((glGetProgramParameterdvNV = (PFNGLGETPROGRAMPARAMETERDVNVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramParameterdvNV")) == NULL) || r; + r = ((glGetProgramParameterfvNV = (PFNGLGETPROGRAMPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramParameterfvNV")) == NULL) || r; + r = ((glGetProgramStringNV = (PFNGLGETPROGRAMSTRINGNVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramStringNV")) == NULL) || r; + r = ((glGetProgramivNV = (PFNGLGETPROGRAMIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramivNV")) == NULL) || r; + r = ((glGetTrackMatrixivNV = (PFNGLGETTRACKMATRIXIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetTrackMatrixivNV")) == NULL) || r; + r = ((glGetVertexAttribPointervNV = (PFNGLGETVERTEXATTRIBPOINTERVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribPointervNV")) == NULL) || r; + r = ((glGetVertexAttribdvNV = (PFNGLGETVERTEXATTRIBDVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribdvNV")) == NULL) || r; + r = ((glGetVertexAttribfvNV = (PFNGLGETVERTEXATTRIBFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribfvNV")) == NULL) || r; + r = ((glGetVertexAttribivNV = (PFNGLGETVERTEXATTRIBIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribivNV")) == NULL) || r; + r = ((glIsProgramNV = (PFNGLISPROGRAMNVPROC)glewGetProcAddress((const GLubyte*)"glIsProgramNV")) == NULL) || r; + r = ((glLoadProgramNV = (PFNGLLOADPROGRAMNVPROC)glewGetProcAddress((const GLubyte*)"glLoadProgramNV")) == NULL) || r; + r = ((glProgramParameter4dNV = (PFNGLPROGRAMPARAMETER4DNVPROC)glewGetProcAddress((const GLubyte*)"glProgramParameter4dNV")) == NULL) || r; + r = ((glProgramParameter4dvNV = (PFNGLPROGRAMPARAMETER4DVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramParameter4dvNV")) == NULL) || r; + r = ((glProgramParameter4fNV = (PFNGLPROGRAMPARAMETER4FNVPROC)glewGetProcAddress((const GLubyte*)"glProgramParameter4fNV")) == NULL) || r; + r = ((glProgramParameter4fvNV = (PFNGLPROGRAMPARAMETER4FVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramParameter4fvNV")) == NULL) || r; + r = ((glProgramParameters4dvNV = (PFNGLPROGRAMPARAMETERS4DVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramParameters4dvNV")) == NULL) || r; + r = ((glProgramParameters4fvNV = (PFNGLPROGRAMPARAMETERS4FVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramParameters4fvNV")) == NULL) || r; + r = ((glRequestResidentProgramsNV = (PFNGLREQUESTRESIDENTPROGRAMSNVPROC)glewGetProcAddress((const GLubyte*)"glRequestResidentProgramsNV")) == NULL) || r; + r = ((glTrackMatrixNV = (PFNGLTRACKMATRIXNVPROC)glewGetProcAddress((const GLubyte*)"glTrackMatrixNV")) == NULL) || r; + r = ((glVertexAttrib1dNV = (PFNGLVERTEXATTRIB1DNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1dNV")) == NULL) || r; + r = ((glVertexAttrib1dvNV = (PFNGLVERTEXATTRIB1DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1dvNV")) == NULL) || r; + r = ((glVertexAttrib1fNV = (PFNGLVERTEXATTRIB1FNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1fNV")) == NULL) || r; + r = ((glVertexAttrib1fvNV = (PFNGLVERTEXATTRIB1FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1fvNV")) == NULL) || r; + r = ((glVertexAttrib1sNV = (PFNGLVERTEXATTRIB1SNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1sNV")) == NULL) || r; + r = ((glVertexAttrib1svNV = (PFNGLVERTEXATTRIB1SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1svNV")) == NULL) || r; + r = ((glVertexAttrib2dNV = (PFNGLVERTEXATTRIB2DNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2dNV")) == NULL) || r; + r = ((glVertexAttrib2dvNV = (PFNGLVERTEXATTRIB2DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2dvNV")) == NULL) || r; + r = ((glVertexAttrib2fNV = (PFNGLVERTEXATTRIB2FNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2fNV")) == NULL) || r; + r = ((glVertexAttrib2fvNV = (PFNGLVERTEXATTRIB2FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2fvNV")) == NULL) || r; + r = ((glVertexAttrib2sNV = (PFNGLVERTEXATTRIB2SNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2sNV")) == NULL) || r; + r = ((glVertexAttrib2svNV = (PFNGLVERTEXATTRIB2SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2svNV")) == NULL) || r; + r = ((glVertexAttrib3dNV = (PFNGLVERTEXATTRIB3DNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3dNV")) == NULL) || r; + r = ((glVertexAttrib3dvNV = (PFNGLVERTEXATTRIB3DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3dvNV")) == NULL) || r; + r = ((glVertexAttrib3fNV = (PFNGLVERTEXATTRIB3FNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3fNV")) == NULL) || r; + r = ((glVertexAttrib3fvNV = (PFNGLVERTEXATTRIB3FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3fvNV")) == NULL) || r; + r = ((glVertexAttrib3sNV = (PFNGLVERTEXATTRIB3SNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3sNV")) == NULL) || r; + r = ((glVertexAttrib3svNV = (PFNGLVERTEXATTRIB3SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3svNV")) == NULL) || r; + r = ((glVertexAttrib4dNV = (PFNGLVERTEXATTRIB4DNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4dNV")) == NULL) || r; + r = ((glVertexAttrib4dvNV = (PFNGLVERTEXATTRIB4DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4dvNV")) == NULL) || r; + r = ((glVertexAttrib4fNV = (PFNGLVERTEXATTRIB4FNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4fNV")) == NULL) || r; + r = ((glVertexAttrib4fvNV = (PFNGLVERTEXATTRIB4FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4fvNV")) == NULL) || r; + r = ((glVertexAttrib4sNV = (PFNGLVERTEXATTRIB4SNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4sNV")) == NULL) || r; + r = ((glVertexAttrib4svNV = (PFNGLVERTEXATTRIB4SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4svNV")) == NULL) || r; + r = ((glVertexAttrib4ubNV = (PFNGLVERTEXATTRIB4UBNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4ubNV")) == NULL) || r; + r = ((glVertexAttrib4ubvNV = (PFNGLVERTEXATTRIB4UBVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4ubvNV")) == NULL) || r; + r = ((glVertexAttribPointerNV = (PFNGLVERTEXATTRIBPOINTERNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribPointerNV")) == NULL) || r; + r = ((glVertexAttribs1dvNV = (PFNGLVERTEXATTRIBS1DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs1dvNV")) == NULL) || r; + r = ((glVertexAttribs1fvNV = (PFNGLVERTEXATTRIBS1FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs1fvNV")) == NULL) || r; + r = ((glVertexAttribs1svNV = (PFNGLVERTEXATTRIBS1SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs1svNV")) == NULL) || r; + r = ((glVertexAttribs2dvNV = (PFNGLVERTEXATTRIBS2DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs2dvNV")) == NULL) || r; + r = ((glVertexAttribs2fvNV = (PFNGLVERTEXATTRIBS2FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs2fvNV")) == NULL) || r; + r = ((glVertexAttribs2svNV = (PFNGLVERTEXATTRIBS2SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs2svNV")) == NULL) || r; + r = ((glVertexAttribs3dvNV = (PFNGLVERTEXATTRIBS3DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs3dvNV")) == NULL) || r; + r = ((glVertexAttribs3fvNV = (PFNGLVERTEXATTRIBS3FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs3fvNV")) == NULL) || r; + r = ((glVertexAttribs3svNV = (PFNGLVERTEXATTRIBS3SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs3svNV")) == NULL) || r; + r = ((glVertexAttribs4dvNV = (PFNGLVERTEXATTRIBS4DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs4dvNV")) == NULL) || r; + r = ((glVertexAttribs4fvNV = (PFNGLVERTEXATTRIBS4FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs4fvNV")) == NULL) || r; + r = ((glVertexAttribs4svNV = (PFNGLVERTEXATTRIBS4SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs4svNV")) == NULL) || r; + r = ((glVertexAttribs4ubvNV = (PFNGLVERTEXATTRIBS4UBVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs4ubvNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_vertex_program */ + +#ifdef GL_NV_vertex_program1_1 + +#endif /* GL_NV_vertex_program1_1 */ + +#ifdef GL_NV_vertex_program2 + +#endif /* GL_NV_vertex_program2 */ + +#ifdef GL_NV_vertex_program2_option + +#endif /* GL_NV_vertex_program2_option */ + +#ifdef GL_NV_vertex_program3 + +#endif /* GL_NV_vertex_program3 */ + +#ifdef GL_NV_vertex_program4 + +#endif /* GL_NV_vertex_program4 */ + +#ifdef GL_OES_byte_coordinates + +#endif /* GL_OES_byte_coordinates */ + +#ifdef GL_OES_compressed_paletted_texture + +#endif /* GL_OES_compressed_paletted_texture */ + +#ifdef GL_OES_read_format + +#endif /* GL_OES_read_format */ + +#ifdef GL_OES_single_precision + +static GLboolean _glewInit_GL_OES_single_precision (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glClearDepthfOES = (PFNGLCLEARDEPTHFOESPROC)glewGetProcAddress((const GLubyte*)"glClearDepthfOES")) == NULL) || r; + r = ((glClipPlanefOES = (PFNGLCLIPPLANEFOESPROC)glewGetProcAddress((const GLubyte*)"glClipPlanefOES")) == NULL) || r; + r = ((glDepthRangefOES = (PFNGLDEPTHRANGEFOESPROC)glewGetProcAddress((const GLubyte*)"glDepthRangefOES")) == NULL) || r; + r = ((glFrustumfOES = (PFNGLFRUSTUMFOESPROC)glewGetProcAddress((const GLubyte*)"glFrustumfOES")) == NULL) || r; + r = ((glGetClipPlanefOES = (PFNGLGETCLIPPLANEFOESPROC)glewGetProcAddress((const GLubyte*)"glGetClipPlanefOES")) == NULL) || r; + r = ((glOrthofOES = (PFNGLORTHOFOESPROC)glewGetProcAddress((const GLubyte*)"glOrthofOES")) == NULL) || r; + + return r; +} + +#endif /* GL_OES_single_precision */ + +#ifdef GL_OML_interlace + +#endif /* GL_OML_interlace */ + +#ifdef GL_OML_resample + +#endif /* GL_OML_resample */ + +#ifdef GL_OML_subsample + +#endif /* GL_OML_subsample */ + +#ifdef GL_PGI_misc_hints + +#endif /* GL_PGI_misc_hints */ + +#ifdef GL_PGI_vertex_hints + +#endif /* GL_PGI_vertex_hints */ + +#ifdef GL_REND_screen_coordinates + +#endif /* GL_REND_screen_coordinates */ + +#ifdef GL_S3_s3tc + +#endif /* GL_S3_s3tc */ + +#ifdef GL_SGIS_color_range + +#endif /* GL_SGIS_color_range */ + +#ifdef GL_SGIS_detail_texture + +static GLboolean _glewInit_GL_SGIS_detail_texture (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glDetailTexFuncSGIS = (PFNGLDETAILTEXFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glDetailTexFuncSGIS")) == NULL) || r; + r = ((glGetDetailTexFuncSGIS = (PFNGLGETDETAILTEXFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glGetDetailTexFuncSGIS")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIS_detail_texture */ + +#ifdef GL_SGIS_fog_function + +static GLboolean _glewInit_GL_SGIS_fog_function (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glFogFuncSGIS = (PFNGLFOGFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glFogFuncSGIS")) == NULL) || r; + r = ((glGetFogFuncSGIS = (PFNGLGETFOGFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glGetFogFuncSGIS")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIS_fog_function */ + +#ifdef GL_SGIS_generate_mipmap + +#endif /* GL_SGIS_generate_mipmap */ + +#ifdef GL_SGIS_multisample + +static GLboolean _glewInit_GL_SGIS_multisample (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glSampleMaskSGIS = (PFNGLSAMPLEMASKSGISPROC)glewGetProcAddress((const GLubyte*)"glSampleMaskSGIS")) == NULL) || r; + r = ((glSamplePatternSGIS = (PFNGLSAMPLEPATTERNSGISPROC)glewGetProcAddress((const GLubyte*)"glSamplePatternSGIS")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIS_multisample */ + +#ifdef GL_SGIS_pixel_texture + +#endif /* GL_SGIS_pixel_texture */ + +#ifdef GL_SGIS_point_line_texgen + +#endif /* GL_SGIS_point_line_texgen */ + +#ifdef GL_SGIS_sharpen_texture + +static GLboolean _glewInit_GL_SGIS_sharpen_texture (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetSharpenTexFuncSGIS = (PFNGLGETSHARPENTEXFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glGetSharpenTexFuncSGIS")) == NULL) || r; + r = ((glSharpenTexFuncSGIS = (PFNGLSHARPENTEXFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glSharpenTexFuncSGIS")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIS_sharpen_texture */ + +#ifdef GL_SGIS_texture4D + +static GLboolean _glewInit_GL_SGIS_texture4D (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glTexImage4DSGIS = (PFNGLTEXIMAGE4DSGISPROC)glewGetProcAddress((const GLubyte*)"glTexImage4DSGIS")) == NULL) || r; + r = ((glTexSubImage4DSGIS = (PFNGLTEXSUBIMAGE4DSGISPROC)glewGetProcAddress((const GLubyte*)"glTexSubImage4DSGIS")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIS_texture4D */ + +#ifdef GL_SGIS_texture_border_clamp + +#endif /* GL_SGIS_texture_border_clamp */ + +#ifdef GL_SGIS_texture_edge_clamp + +#endif /* GL_SGIS_texture_edge_clamp */ + +#ifdef GL_SGIS_texture_filter4 + +static GLboolean _glewInit_GL_SGIS_texture_filter4 (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetTexFilterFuncSGIS = (PFNGLGETTEXFILTERFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glGetTexFilterFuncSGIS")) == NULL) || r; + r = ((glTexFilterFuncSGIS = (PFNGLTEXFILTERFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glTexFilterFuncSGIS")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIS_texture_filter4 */ + +#ifdef GL_SGIS_texture_lod + +#endif /* GL_SGIS_texture_lod */ + +#ifdef GL_SGIS_texture_select + +#endif /* GL_SGIS_texture_select */ + +#ifdef GL_SGIX_async + +static GLboolean _glewInit_GL_SGIX_async (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glAsyncMarkerSGIX = (PFNGLASYNCMARKERSGIXPROC)glewGetProcAddress((const GLubyte*)"glAsyncMarkerSGIX")) == NULL) || r; + r = ((glDeleteAsyncMarkersSGIX = (PFNGLDELETEASYNCMARKERSSGIXPROC)glewGetProcAddress((const GLubyte*)"glDeleteAsyncMarkersSGIX")) == NULL) || r; + r = ((glFinishAsyncSGIX = (PFNGLFINISHASYNCSGIXPROC)glewGetProcAddress((const GLubyte*)"glFinishAsyncSGIX")) == NULL) || r; + r = ((glGenAsyncMarkersSGIX = (PFNGLGENASYNCMARKERSSGIXPROC)glewGetProcAddress((const GLubyte*)"glGenAsyncMarkersSGIX")) == NULL) || r; + r = ((glIsAsyncMarkerSGIX = (PFNGLISASYNCMARKERSGIXPROC)glewGetProcAddress((const GLubyte*)"glIsAsyncMarkerSGIX")) == NULL) || r; + r = ((glPollAsyncSGIX = (PFNGLPOLLASYNCSGIXPROC)glewGetProcAddress((const GLubyte*)"glPollAsyncSGIX")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIX_async */ + +#ifdef GL_SGIX_async_histogram + +#endif /* GL_SGIX_async_histogram */ + +#ifdef GL_SGIX_async_pixel + +#endif /* GL_SGIX_async_pixel */ + +#ifdef GL_SGIX_blend_alpha_minmax + +#endif /* GL_SGIX_blend_alpha_minmax */ + +#ifdef GL_SGIX_clipmap + +#endif /* GL_SGIX_clipmap */ + +#ifdef GL_SGIX_convolution_accuracy + +#endif /* GL_SGIX_convolution_accuracy */ + +#ifdef GL_SGIX_depth_texture + +#endif /* GL_SGIX_depth_texture */ + +#ifdef GL_SGIX_flush_raster + +static GLboolean _glewInit_GL_SGIX_flush_raster (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glFlushRasterSGIX = (PFNGLFLUSHRASTERSGIXPROC)glewGetProcAddress((const GLubyte*)"glFlushRasterSGIX")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIX_flush_raster */ + +#ifdef GL_SGIX_fog_offset + +#endif /* GL_SGIX_fog_offset */ + +#ifdef GL_SGIX_fog_texture + +static GLboolean _glewInit_GL_SGIX_fog_texture (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glTextureFogSGIX = (PFNGLTEXTUREFOGSGIXPROC)glewGetProcAddress((const GLubyte*)"glTextureFogSGIX")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIX_fog_texture */ + +#ifdef GL_SGIX_fragment_specular_lighting + +static GLboolean _glewInit_GL_SGIX_fragment_specular_lighting (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glFragmentColorMaterialSGIX = (PFNGLFRAGMENTCOLORMATERIALSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentColorMaterialSGIX")) == NULL) || r; + r = ((glFragmentLightModelfSGIX = (PFNGLFRAGMENTLIGHTMODELFSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModelfSGIX")) == NULL) || r; + r = ((glFragmentLightModelfvSGIX = (PFNGLFRAGMENTLIGHTMODELFVSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModelfvSGIX")) == NULL) || r; + r = ((glFragmentLightModeliSGIX = (PFNGLFRAGMENTLIGHTMODELISGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModeliSGIX")) == NULL) || r; + r = ((glFragmentLightModelivSGIX = (PFNGLFRAGMENTLIGHTMODELIVSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModelivSGIX")) == NULL) || r; + r = ((glFragmentLightfSGIX = (PFNGLFRAGMENTLIGHTFSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightfSGIX")) == NULL) || r; + r = ((glFragmentLightfvSGIX = (PFNGLFRAGMENTLIGHTFVSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightfvSGIX")) == NULL) || r; + r = ((glFragmentLightiSGIX = (PFNGLFRAGMENTLIGHTISGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightiSGIX")) == NULL) || r; + r = ((glFragmentLightivSGIX = (PFNGLFRAGMENTLIGHTIVSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightivSGIX")) == NULL) || r; + r = ((glFragmentMaterialfSGIX = (PFNGLFRAGMENTMATERIALFSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialfSGIX")) == NULL) || r; + r = ((glFragmentMaterialfvSGIX = (PFNGLFRAGMENTMATERIALFVSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialfvSGIX")) == NULL) || r; + r = ((glFragmentMaterialiSGIX = (PFNGLFRAGMENTMATERIALISGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialiSGIX")) == NULL) || r; + r = ((glFragmentMaterialivSGIX = (PFNGLFRAGMENTMATERIALIVSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialivSGIX")) == NULL) || r; + r = ((glGetFragmentLightfvSGIX = (PFNGLGETFRAGMENTLIGHTFVSGIXPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentLightfvSGIX")) == NULL) || r; + r = ((glGetFragmentLightivSGIX = (PFNGLGETFRAGMENTLIGHTIVSGIXPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentLightivSGIX")) == NULL) || r; + r = ((glGetFragmentMaterialfvSGIX = (PFNGLGETFRAGMENTMATERIALFVSGIXPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentMaterialfvSGIX")) == NULL) || r; + r = ((glGetFragmentMaterialivSGIX = (PFNGLGETFRAGMENTMATERIALIVSGIXPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentMaterialivSGIX")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIX_fragment_specular_lighting */ + +#ifdef GL_SGIX_framezoom + +static GLboolean _glewInit_GL_SGIX_framezoom (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glFrameZoomSGIX = (PFNGLFRAMEZOOMSGIXPROC)glewGetProcAddress((const GLubyte*)"glFrameZoomSGIX")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIX_framezoom */ + +#ifdef GL_SGIX_interlace + +#endif /* GL_SGIX_interlace */ + +#ifdef GL_SGIX_ir_instrument1 + +#endif /* GL_SGIX_ir_instrument1 */ + +#ifdef GL_SGIX_list_priority + +#endif /* GL_SGIX_list_priority */ + +#ifdef GL_SGIX_pixel_texture + +static GLboolean _glewInit_GL_SGIX_pixel_texture (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glPixelTexGenSGIX = (PFNGLPIXELTEXGENSGIXPROC)glewGetProcAddress((const GLubyte*)"glPixelTexGenSGIX")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIX_pixel_texture */ + +#ifdef GL_SGIX_pixel_texture_bits + +#endif /* GL_SGIX_pixel_texture_bits */ + +#ifdef GL_SGIX_reference_plane + +static GLboolean _glewInit_GL_SGIX_reference_plane (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glReferencePlaneSGIX = (PFNGLREFERENCEPLANESGIXPROC)glewGetProcAddress((const GLubyte*)"glReferencePlaneSGIX")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIX_reference_plane */ + +#ifdef GL_SGIX_resample + +#endif /* GL_SGIX_resample */ + +#ifdef GL_SGIX_shadow + +#endif /* GL_SGIX_shadow */ + +#ifdef GL_SGIX_shadow_ambient + +#endif /* GL_SGIX_shadow_ambient */ + +#ifdef GL_SGIX_sprite + +static GLboolean _glewInit_GL_SGIX_sprite (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glSpriteParameterfSGIX = (PFNGLSPRITEPARAMETERFSGIXPROC)glewGetProcAddress((const GLubyte*)"glSpriteParameterfSGIX")) == NULL) || r; + r = ((glSpriteParameterfvSGIX = (PFNGLSPRITEPARAMETERFVSGIXPROC)glewGetProcAddress((const GLubyte*)"glSpriteParameterfvSGIX")) == NULL) || r; + r = ((glSpriteParameteriSGIX = (PFNGLSPRITEPARAMETERISGIXPROC)glewGetProcAddress((const GLubyte*)"glSpriteParameteriSGIX")) == NULL) || r; + r = ((glSpriteParameterivSGIX = (PFNGLSPRITEPARAMETERIVSGIXPROC)glewGetProcAddress((const GLubyte*)"glSpriteParameterivSGIX")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIX_sprite */ + +#ifdef GL_SGIX_tag_sample_buffer + +static GLboolean _glewInit_GL_SGIX_tag_sample_buffer (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glTagSampleBufferSGIX = (PFNGLTAGSAMPLEBUFFERSGIXPROC)glewGetProcAddress((const GLubyte*)"glTagSampleBufferSGIX")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIX_tag_sample_buffer */ + +#ifdef GL_SGIX_texture_add_env + +#endif /* GL_SGIX_texture_add_env */ + +#ifdef GL_SGIX_texture_coordinate_clamp + +#endif /* GL_SGIX_texture_coordinate_clamp */ + +#ifdef GL_SGIX_texture_lod_bias + +#endif /* GL_SGIX_texture_lod_bias */ + +#ifdef GL_SGIX_texture_multi_buffer + +#endif /* GL_SGIX_texture_multi_buffer */ + +#ifdef GL_SGIX_texture_range + +#endif /* GL_SGIX_texture_range */ + +#ifdef GL_SGIX_texture_scale_bias + +#endif /* GL_SGIX_texture_scale_bias */ + +#ifdef GL_SGIX_vertex_preclip + +#endif /* GL_SGIX_vertex_preclip */ + +#ifdef GL_SGIX_vertex_preclip_hint + +#endif /* GL_SGIX_vertex_preclip_hint */ + +#ifdef GL_SGIX_ycrcb + +#endif /* GL_SGIX_ycrcb */ + +#ifdef GL_SGI_color_matrix + +#endif /* GL_SGI_color_matrix */ + +#ifdef GL_SGI_color_table + +static GLboolean _glewInit_GL_SGI_color_table (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glColorTableParameterfvSGI = (PFNGLCOLORTABLEPARAMETERFVSGIPROC)glewGetProcAddress((const GLubyte*)"glColorTableParameterfvSGI")) == NULL) || r; + r = ((glColorTableParameterivSGI = (PFNGLCOLORTABLEPARAMETERIVSGIPROC)glewGetProcAddress((const GLubyte*)"glColorTableParameterivSGI")) == NULL) || r; + r = ((glColorTableSGI = (PFNGLCOLORTABLESGIPROC)glewGetProcAddress((const GLubyte*)"glColorTableSGI")) == NULL) || r; + r = ((glCopyColorTableSGI = (PFNGLCOPYCOLORTABLESGIPROC)glewGetProcAddress((const GLubyte*)"glCopyColorTableSGI")) == NULL) || r; + r = ((glGetColorTableParameterfvSGI = (PFNGLGETCOLORTABLEPARAMETERFVSGIPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableParameterfvSGI")) == NULL) || r; + r = ((glGetColorTableParameterivSGI = (PFNGLGETCOLORTABLEPARAMETERIVSGIPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableParameterivSGI")) == NULL) || r; + r = ((glGetColorTableSGI = (PFNGLGETCOLORTABLESGIPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableSGI")) == NULL) || r; + + return r; +} + +#endif /* GL_SGI_color_table */ + +#ifdef GL_SGI_texture_color_table + +#endif /* GL_SGI_texture_color_table */ + +#ifdef GL_SUNX_constant_data + +static GLboolean _glewInit_GL_SUNX_constant_data (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glFinishTextureSUNX = (PFNGLFINISHTEXTURESUNXPROC)glewGetProcAddress((const GLubyte*)"glFinishTextureSUNX")) == NULL) || r; + + return r; +} + +#endif /* GL_SUNX_constant_data */ + +#ifdef GL_SUN_convolution_border_modes + +#endif /* GL_SUN_convolution_border_modes */ + +#ifdef GL_SUN_global_alpha + +static GLboolean _glewInit_GL_SUN_global_alpha (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGlobalAlphaFactorbSUN = (PFNGLGLOBALALPHAFACTORBSUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactorbSUN")) == NULL) || r; + r = ((glGlobalAlphaFactordSUN = (PFNGLGLOBALALPHAFACTORDSUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactordSUN")) == NULL) || r; + r = ((glGlobalAlphaFactorfSUN = (PFNGLGLOBALALPHAFACTORFSUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactorfSUN")) == NULL) || r; + r = ((glGlobalAlphaFactoriSUN = (PFNGLGLOBALALPHAFACTORISUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactoriSUN")) == NULL) || r; + r = ((glGlobalAlphaFactorsSUN = (PFNGLGLOBALALPHAFACTORSSUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactorsSUN")) == NULL) || r; + r = ((glGlobalAlphaFactorubSUN = (PFNGLGLOBALALPHAFACTORUBSUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactorubSUN")) == NULL) || r; + r = ((glGlobalAlphaFactoruiSUN = (PFNGLGLOBALALPHAFACTORUISUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactoruiSUN")) == NULL) || r; + r = ((glGlobalAlphaFactorusSUN = (PFNGLGLOBALALPHAFACTORUSSUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactorusSUN")) == NULL) || r; + + return r; +} + +#endif /* GL_SUN_global_alpha */ + +#ifdef GL_SUN_mesh_array + +#endif /* GL_SUN_mesh_array */ + +#ifdef GL_SUN_read_video_pixels + +static GLboolean _glewInit_GL_SUN_read_video_pixels (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glReadVideoPixelsSUN = (PFNGLREADVIDEOPIXELSSUNPROC)glewGetProcAddress((const GLubyte*)"glReadVideoPixelsSUN")) == NULL) || r; + + return r; +} + +#endif /* GL_SUN_read_video_pixels */ + +#ifdef GL_SUN_slice_accum + +#endif /* GL_SUN_slice_accum */ + +#ifdef GL_SUN_triangle_list + +static GLboolean _glewInit_GL_SUN_triangle_list (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glReplacementCodePointerSUN = (PFNGLREPLACEMENTCODEPOINTERSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodePointerSUN")) == NULL) || r; + r = ((glReplacementCodeubSUN = (PFNGLREPLACEMENTCODEUBSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeubSUN")) == NULL) || r; + r = ((glReplacementCodeubvSUN = (PFNGLREPLACEMENTCODEUBVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeubvSUN")) == NULL) || r; + r = ((glReplacementCodeuiSUN = (PFNGLREPLACEMENTCODEUISUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiSUN")) == NULL) || r; + r = ((glReplacementCodeuivSUN = (PFNGLREPLACEMENTCODEUIVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuivSUN")) == NULL) || r; + r = ((glReplacementCodeusSUN = (PFNGLREPLACEMENTCODEUSSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeusSUN")) == NULL) || r; + r = ((glReplacementCodeusvSUN = (PFNGLREPLACEMENTCODEUSVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeusvSUN")) == NULL) || r; + + return r; +} + +#endif /* GL_SUN_triangle_list */ + +#ifdef GL_SUN_vertex + +static GLboolean _glewInit_GL_SUN_vertex (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glColor3fVertex3fSUN = (PFNGLCOLOR3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glColor3fVertex3fSUN")) == NULL) || r; + r = ((glColor3fVertex3fvSUN = (PFNGLCOLOR3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glColor3fVertex3fvSUN")) == NULL) || r; + r = ((glColor4fNormal3fVertex3fSUN = (PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glColor4fNormal3fVertex3fSUN")) == NULL) || r; + r = ((glColor4fNormal3fVertex3fvSUN = (PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glColor4fNormal3fVertex3fvSUN")) == NULL) || r; + r = ((glColor4ubVertex2fSUN = (PFNGLCOLOR4UBVERTEX2FSUNPROC)glewGetProcAddress((const GLubyte*)"glColor4ubVertex2fSUN")) == NULL) || r; + r = ((glColor4ubVertex2fvSUN = (PFNGLCOLOR4UBVERTEX2FVSUNPROC)glewGetProcAddress((const GLubyte*)"glColor4ubVertex2fvSUN")) == NULL) || r; + r = ((glColor4ubVertex3fSUN = (PFNGLCOLOR4UBVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glColor4ubVertex3fSUN")) == NULL) || r; + r = ((glColor4ubVertex3fvSUN = (PFNGLCOLOR4UBVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glColor4ubVertex3fvSUN")) == NULL) || r; + r = ((glNormal3fVertex3fSUN = (PFNGLNORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glNormal3fVertex3fSUN")) == NULL) || r; + r = ((glNormal3fVertex3fvSUN = (PFNGLNORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glNormal3fVertex3fvSUN")) == NULL) || r; + r = ((glReplacementCodeuiColor3fVertex3fSUN = (PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiColor3fVertex3fSUN")) == NULL) || r; + r = ((glReplacementCodeuiColor3fVertex3fvSUN = (PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiColor3fVertex3fvSUN")) == NULL) || r; + r = ((glReplacementCodeuiColor4fNormal3fVertex3fSUN = (PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiColor4fNormal3fVertex3fSUN")) == NULL) || r; + r = ((glReplacementCodeuiColor4fNormal3fVertex3fvSUN = (PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiColor4fNormal3fVertex3fvSUN")) == NULL) || r; + r = ((glReplacementCodeuiColor4ubVertex3fSUN = (PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiColor4ubVertex3fSUN")) == NULL) || r; + r = ((glReplacementCodeuiColor4ubVertex3fvSUN = (PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiColor4ubVertex3fvSUN")) == NULL) || r; + r = ((glReplacementCodeuiNormal3fVertex3fSUN = (PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiNormal3fVertex3fSUN")) == NULL) || r; + r = ((glReplacementCodeuiNormal3fVertex3fvSUN = (PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiNormal3fVertex3fvSUN")) == NULL) || r; + r = ((glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN = (PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN")) == NULL) || r; + r = ((glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN = (PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN")) == NULL) || r; + r = ((glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN = (PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN")) == NULL) || r; + r = ((glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN = (PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN")) == NULL) || r; + r = ((glReplacementCodeuiTexCoord2fVertex3fSUN = (PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiTexCoord2fVertex3fSUN")) == NULL) || r; + r = ((glReplacementCodeuiTexCoord2fVertex3fvSUN = (PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiTexCoord2fVertex3fvSUN")) == NULL) || r; + r = ((glReplacementCodeuiVertex3fSUN = (PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiVertex3fSUN")) == NULL) || r; + r = ((glReplacementCodeuiVertex3fvSUN = (PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiVertex3fvSUN")) == NULL) || r; + r = ((glTexCoord2fColor3fVertex3fSUN = (PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fColor3fVertex3fSUN")) == NULL) || r; + r = ((glTexCoord2fColor3fVertex3fvSUN = (PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fColor3fVertex3fvSUN")) == NULL) || r; + r = ((glTexCoord2fColor4fNormal3fVertex3fSUN = (PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fColor4fNormal3fVertex3fSUN")) == NULL) || r; + r = ((glTexCoord2fColor4fNormal3fVertex3fvSUN = (PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fColor4fNormal3fVertex3fvSUN")) == NULL) || r; + r = ((glTexCoord2fColor4ubVertex3fSUN = (PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fColor4ubVertex3fSUN")) == NULL) || r; + r = ((glTexCoord2fColor4ubVertex3fvSUN = (PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fColor4ubVertex3fvSUN")) == NULL) || r; + r = ((glTexCoord2fNormal3fVertex3fSUN = (PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fNormal3fVertex3fSUN")) == NULL) || r; + r = ((glTexCoord2fNormal3fVertex3fvSUN = (PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fNormal3fVertex3fvSUN")) == NULL) || r; + r = ((glTexCoord2fVertex3fSUN = (PFNGLTEXCOORD2FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fVertex3fSUN")) == NULL) || r; + r = ((glTexCoord2fVertex3fvSUN = (PFNGLTEXCOORD2FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fVertex3fvSUN")) == NULL) || r; + r = ((glTexCoord4fColor4fNormal3fVertex4fSUN = (PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord4fColor4fNormal3fVertex4fSUN")) == NULL) || r; + r = ((glTexCoord4fColor4fNormal3fVertex4fvSUN = (PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord4fColor4fNormal3fVertex4fvSUN")) == NULL) || r; + r = ((glTexCoord4fVertex4fSUN = (PFNGLTEXCOORD4FVERTEX4FSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord4fVertex4fSUN")) == NULL) || r; + r = ((glTexCoord4fVertex4fvSUN = (PFNGLTEXCOORD4FVERTEX4FVSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord4fVertex4fvSUN")) == NULL) || r; + + return r; +} + +#endif /* GL_SUN_vertex */ + +#ifdef GL_WIN_phong_shading + +#endif /* GL_WIN_phong_shading */ + +#ifdef GL_WIN_specular_fog + +#endif /* GL_WIN_specular_fog */ + +#ifdef GL_WIN_swap_hint + +static GLboolean _glewInit_GL_WIN_swap_hint (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glAddSwapHintRectWIN = (PFNGLADDSWAPHINTRECTWINPROC)glewGetProcAddress((const GLubyte*)"glAddSwapHintRectWIN")) == NULL) || r; + + return r; +} + +#endif /* GL_WIN_swap_hint */ + +/* ------------------------------------------------------------------------- */ + +/* + * Search for name in the extensions string. Use of strstr() + * is not sufficient because extension names can be prefixes of + * other extension names. Could use strtok() but the constant + * string returned by glGetString might be in read-only memory. + */ +GLboolean glewGetExtension (const char* name) +{ + GLubyte* p; + GLubyte* end; + GLuint len = _glewStrLen((const GLubyte*)name); + p = (GLubyte*)glGetString(GL_EXTENSIONS); + if (0 == p) return GL_FALSE; + end = p + _glewStrLen(p); + while (p < end) + { + GLuint n = _glewStrCLen(p, ' '); + if (len == n && _glewStrSame((const GLubyte*)name, p, n)) return GL_TRUE; + p += n+1; + } + return GL_FALSE; +} + +/* ------------------------------------------------------------------------- */ + +#ifndef GLEW_MX +static +#endif +GLenum glewContextInit (GLEW_CONTEXT_ARG_DEF_LIST) +{ + const GLubyte* s; + GLuint dot, major, minor; + /* query opengl version */ + s = glGetString(GL_VERSION); + dot = _glewStrCLen(s, '.'); + major = dot-1; + minor = dot+1; + if (dot == 0 || s[minor] == '\0') + return GLEW_ERROR_NO_GL_VERSION; + if (s[major] == '1' && s[minor] == '0') + { + return GLEW_ERROR_GL_VERSION_10_ONLY; + } + else + { + CONST_CAST(GLEW_VERSION_1_1) = GL_TRUE; + if (s[major] >= '2') + { + CONST_CAST(GLEW_VERSION_1_2) = GL_TRUE; + CONST_CAST(GLEW_VERSION_1_3) = GL_TRUE; + CONST_CAST(GLEW_VERSION_1_4) = GL_TRUE; + CONST_CAST(GLEW_VERSION_1_5) = GL_TRUE; + CONST_CAST(GLEW_VERSION_2_0) = GL_TRUE; + if (s[minor] >= '1') + { + CONST_CAST(GLEW_VERSION_2_1) = GL_TRUE; + } + } + else + { + if (s[minor] >= '5') + { + CONST_CAST(GLEW_VERSION_1_2) = GL_TRUE; + CONST_CAST(GLEW_VERSION_1_3) = GL_TRUE; + CONST_CAST(GLEW_VERSION_1_4) = GL_TRUE; + CONST_CAST(GLEW_VERSION_1_5) = GL_TRUE; + CONST_CAST(GLEW_VERSION_2_0) = GL_FALSE; + CONST_CAST(GLEW_VERSION_2_1) = GL_FALSE; + } + if (s[minor] == '4') + { + CONST_CAST(GLEW_VERSION_1_2) = GL_TRUE; + CONST_CAST(GLEW_VERSION_1_3) = GL_TRUE; + CONST_CAST(GLEW_VERSION_1_4) = GL_TRUE; + CONST_CAST(GLEW_VERSION_1_5) = GL_FALSE; + CONST_CAST(GLEW_VERSION_2_0) = GL_FALSE; + CONST_CAST(GLEW_VERSION_2_1) = GL_FALSE; + } + if (s[minor] == '3') + { + CONST_CAST(GLEW_VERSION_1_2) = GL_TRUE; + CONST_CAST(GLEW_VERSION_1_3) = GL_TRUE; + CONST_CAST(GLEW_VERSION_1_4) = GL_FALSE; + CONST_CAST(GLEW_VERSION_1_5) = GL_FALSE; + CONST_CAST(GLEW_VERSION_2_0) = GL_FALSE; + CONST_CAST(GLEW_VERSION_2_1) = GL_FALSE; + } + if (s[minor] == '2') + { + CONST_CAST(GLEW_VERSION_1_2) = GL_TRUE; + CONST_CAST(GLEW_VERSION_1_3) = GL_FALSE; + CONST_CAST(GLEW_VERSION_1_4) = GL_FALSE; + CONST_CAST(GLEW_VERSION_1_5) = GL_FALSE; + CONST_CAST(GLEW_VERSION_2_0) = GL_FALSE; + CONST_CAST(GLEW_VERSION_2_1) = GL_FALSE; + } + if (s[minor] < '2') + { + CONST_CAST(GLEW_VERSION_1_2) = GL_FALSE; + CONST_CAST(GLEW_VERSION_1_3) = GL_FALSE; + CONST_CAST(GLEW_VERSION_1_4) = GL_FALSE; + CONST_CAST(GLEW_VERSION_1_5) = GL_FALSE; + CONST_CAST(GLEW_VERSION_2_0) = GL_FALSE; + CONST_CAST(GLEW_VERSION_2_1) = GL_FALSE; + } + } + } + /* initialize extensions */ +#ifdef GL_VERSION_1_2 + if (glewExperimental || GLEW_VERSION_1_2) CONST_CAST(GLEW_VERSION_1_2) = !_glewInit_GL_VERSION_1_2(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_VERSION_1_2 */ +#ifdef GL_VERSION_1_3 + if (glewExperimental || GLEW_VERSION_1_3) CONST_CAST(GLEW_VERSION_1_3) = !_glewInit_GL_VERSION_1_3(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_VERSION_1_3 */ +#ifdef GL_VERSION_1_4 + if (glewExperimental || GLEW_VERSION_1_4) CONST_CAST(GLEW_VERSION_1_4) = !_glewInit_GL_VERSION_1_4(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_VERSION_1_4 */ +#ifdef GL_VERSION_1_5 + if (glewExperimental || GLEW_VERSION_1_5) CONST_CAST(GLEW_VERSION_1_5) = !_glewInit_GL_VERSION_1_5(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_VERSION_1_5 */ +#ifdef GL_VERSION_2_0 + if (glewExperimental || GLEW_VERSION_2_0) CONST_CAST(GLEW_VERSION_2_0) = !_glewInit_GL_VERSION_2_0(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_VERSION_2_0 */ +#ifdef GL_VERSION_2_1 + if (glewExperimental || GLEW_VERSION_2_1) CONST_CAST(GLEW_VERSION_2_1) = !_glewInit_GL_VERSION_2_1(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_VERSION_2_1 */ +#ifdef GL_VERSION_3_0 + if (glewExperimental || GLEW_VERSION_3_0) CONST_CAST(GLEW_VERSION_3_0) = !_glewInit_GL_VERSION_3_0(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_VERSION_3_0 */ +#ifdef GL_3DFX_multisample + CONST_CAST(GLEW_3DFX_multisample) = glewGetExtension("GL_3DFX_multisample"); +#endif /* GL_3DFX_multisample */ +#ifdef GL_3DFX_tbuffer + CONST_CAST(GLEW_3DFX_tbuffer) = glewGetExtension("GL_3DFX_tbuffer"); + if (glewExperimental || GLEW_3DFX_tbuffer) CONST_CAST(GLEW_3DFX_tbuffer) = !_glewInit_GL_3DFX_tbuffer(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_3DFX_tbuffer */ +#ifdef GL_3DFX_texture_compression_FXT1 + CONST_CAST(GLEW_3DFX_texture_compression_FXT1) = glewGetExtension("GL_3DFX_texture_compression_FXT1"); +#endif /* GL_3DFX_texture_compression_FXT1 */ +#ifdef GL_APPLE_client_storage + CONST_CAST(GLEW_APPLE_client_storage) = glewGetExtension("GL_APPLE_client_storage"); +#endif /* GL_APPLE_client_storage */ +#ifdef GL_APPLE_element_array + CONST_CAST(GLEW_APPLE_element_array) = glewGetExtension("GL_APPLE_element_array"); + if (glewExperimental || GLEW_APPLE_element_array) CONST_CAST(GLEW_APPLE_element_array) = !_glewInit_GL_APPLE_element_array(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_APPLE_element_array */ +#ifdef GL_APPLE_fence + CONST_CAST(GLEW_APPLE_fence) = glewGetExtension("GL_APPLE_fence"); + if (glewExperimental || GLEW_APPLE_fence) CONST_CAST(GLEW_APPLE_fence) = !_glewInit_GL_APPLE_fence(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_APPLE_fence */ +#ifdef GL_APPLE_float_pixels + CONST_CAST(GLEW_APPLE_float_pixels) = glewGetExtension("GL_APPLE_float_pixels"); +#endif /* GL_APPLE_float_pixels */ +#ifdef GL_APPLE_flush_buffer_range + CONST_CAST(GLEW_APPLE_flush_buffer_range) = glewGetExtension("GL_APPLE_flush_buffer_range"); + if (glewExperimental || GLEW_APPLE_flush_buffer_range) CONST_CAST(GLEW_APPLE_flush_buffer_range) = !_glewInit_GL_APPLE_flush_buffer_range(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_APPLE_flush_buffer_range */ +#ifdef GL_APPLE_pixel_buffer + CONST_CAST(GLEW_APPLE_pixel_buffer) = glewGetExtension("GL_APPLE_pixel_buffer"); +#endif /* GL_APPLE_pixel_buffer */ +#ifdef GL_APPLE_specular_vector + CONST_CAST(GLEW_APPLE_specular_vector) = glewGetExtension("GL_APPLE_specular_vector"); +#endif /* GL_APPLE_specular_vector */ +#ifdef GL_APPLE_texture_range + CONST_CAST(GLEW_APPLE_texture_range) = glewGetExtension("GL_APPLE_texture_range"); + if (glewExperimental || GLEW_APPLE_texture_range) CONST_CAST(GLEW_APPLE_texture_range) = !_glewInit_GL_APPLE_texture_range(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_APPLE_texture_range */ +#ifdef GL_APPLE_transform_hint + CONST_CAST(GLEW_APPLE_transform_hint) = glewGetExtension("GL_APPLE_transform_hint"); +#endif /* GL_APPLE_transform_hint */ +#ifdef GL_APPLE_vertex_array_object + CONST_CAST(GLEW_APPLE_vertex_array_object) = glewGetExtension("GL_APPLE_vertex_array_object"); + if (glewExperimental || GLEW_APPLE_vertex_array_object) CONST_CAST(GLEW_APPLE_vertex_array_object) = !_glewInit_GL_APPLE_vertex_array_object(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_APPLE_vertex_array_object */ +#ifdef GL_APPLE_vertex_array_range + CONST_CAST(GLEW_APPLE_vertex_array_range) = glewGetExtension("GL_APPLE_vertex_array_range"); + if (glewExperimental || GLEW_APPLE_vertex_array_range) CONST_CAST(GLEW_APPLE_vertex_array_range) = !_glewInit_GL_APPLE_vertex_array_range(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_APPLE_vertex_array_range */ +#ifdef GL_APPLE_ycbcr_422 + CONST_CAST(GLEW_APPLE_ycbcr_422) = glewGetExtension("GL_APPLE_ycbcr_422"); +#endif /* GL_APPLE_ycbcr_422 */ +#ifdef GL_ARB_color_buffer_float + CONST_CAST(GLEW_ARB_color_buffer_float) = glewGetExtension("GL_ARB_color_buffer_float"); + if (glewExperimental || GLEW_ARB_color_buffer_float) CONST_CAST(GLEW_ARB_color_buffer_float) = !_glewInit_GL_ARB_color_buffer_float(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_color_buffer_float */ +#ifdef GL_ARB_depth_buffer_float + CONST_CAST(GLEW_ARB_depth_buffer_float) = glewGetExtension("GL_ARB_depth_buffer_float"); +#endif /* GL_ARB_depth_buffer_float */ +#ifdef GL_ARB_depth_texture + CONST_CAST(GLEW_ARB_depth_texture) = glewGetExtension("GL_ARB_depth_texture"); +#endif /* GL_ARB_depth_texture */ +#ifdef GL_ARB_draw_buffers + CONST_CAST(GLEW_ARB_draw_buffers) = glewGetExtension("GL_ARB_draw_buffers"); + if (glewExperimental || GLEW_ARB_draw_buffers) CONST_CAST(GLEW_ARB_draw_buffers) = !_glewInit_GL_ARB_draw_buffers(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_draw_buffers */ +#ifdef GL_ARB_draw_instanced + CONST_CAST(GLEW_ARB_draw_instanced) = glewGetExtension("GL_ARB_draw_instanced"); + if (glewExperimental || GLEW_ARB_draw_instanced) CONST_CAST(GLEW_ARB_draw_instanced) = !_glewInit_GL_ARB_draw_instanced(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_draw_instanced */ +#ifdef GL_ARB_fragment_program + CONST_CAST(GLEW_ARB_fragment_program) = glewGetExtension("GL_ARB_fragment_program"); +#endif /* GL_ARB_fragment_program */ +#ifdef GL_ARB_fragment_program_shadow + CONST_CAST(GLEW_ARB_fragment_program_shadow) = glewGetExtension("GL_ARB_fragment_program_shadow"); +#endif /* GL_ARB_fragment_program_shadow */ +#ifdef GL_ARB_fragment_shader + CONST_CAST(GLEW_ARB_fragment_shader) = glewGetExtension("GL_ARB_fragment_shader"); +#endif /* GL_ARB_fragment_shader */ +#ifdef GL_ARB_framebuffer_object + CONST_CAST(GLEW_ARB_framebuffer_object) = glewGetExtension("GL_ARB_framebuffer_object"); + if (glewExperimental || GLEW_ARB_framebuffer_object) CONST_CAST(GLEW_ARB_framebuffer_object) = !_glewInit_GL_ARB_framebuffer_object(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_framebuffer_object */ +#ifdef GL_ARB_framebuffer_sRGB + CONST_CAST(GLEW_ARB_framebuffer_sRGB) = glewGetExtension("GL_ARB_framebuffer_sRGB"); +#endif /* GL_ARB_framebuffer_sRGB */ +#ifdef GL_ARB_geometry_shader4 + CONST_CAST(GLEW_ARB_geometry_shader4) = glewGetExtension("GL_ARB_geometry_shader4"); + if (glewExperimental || GLEW_ARB_geometry_shader4) CONST_CAST(GLEW_ARB_geometry_shader4) = !_glewInit_GL_ARB_geometry_shader4(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_geometry_shader4 */ +#ifdef GL_ARB_half_float_pixel + CONST_CAST(GLEW_ARB_half_float_pixel) = glewGetExtension("GL_ARB_half_float_pixel"); +#endif /* GL_ARB_half_float_pixel */ +#ifdef GL_ARB_half_float_vertex + CONST_CAST(GLEW_ARB_half_float_vertex) = glewGetExtension("GL_ARB_half_float_vertex"); +#endif /* GL_ARB_half_float_vertex */ +#ifdef GL_ARB_imaging + CONST_CAST(GLEW_ARB_imaging) = glewGetExtension("GL_ARB_imaging"); + if (glewExperimental || GLEW_ARB_imaging) CONST_CAST(GLEW_ARB_imaging) = !_glewInit_GL_ARB_imaging(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_imaging */ +#ifdef GL_ARB_instanced_arrays + CONST_CAST(GLEW_ARB_instanced_arrays) = glewGetExtension("GL_ARB_instanced_arrays"); + if (glewExperimental || GLEW_ARB_instanced_arrays) CONST_CAST(GLEW_ARB_instanced_arrays) = !_glewInit_GL_ARB_instanced_arrays(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_instanced_arrays */ +#ifdef GL_ARB_map_buffer_range + CONST_CAST(GLEW_ARB_map_buffer_range) = glewGetExtension("GL_ARB_map_buffer_range"); + if (glewExperimental || GLEW_ARB_map_buffer_range) CONST_CAST(GLEW_ARB_map_buffer_range) = !_glewInit_GL_ARB_map_buffer_range(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_map_buffer_range */ +#ifdef GL_ARB_matrix_palette + CONST_CAST(GLEW_ARB_matrix_palette) = glewGetExtension("GL_ARB_matrix_palette"); + if (glewExperimental || GLEW_ARB_matrix_palette) CONST_CAST(GLEW_ARB_matrix_palette) = !_glewInit_GL_ARB_matrix_palette(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_matrix_palette */ +#ifdef GL_ARB_multisample + CONST_CAST(GLEW_ARB_multisample) = glewGetExtension("GL_ARB_multisample"); + if (glewExperimental || GLEW_ARB_multisample) CONST_CAST(GLEW_ARB_multisample) = !_glewInit_GL_ARB_multisample(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_multisample */ +#ifdef GL_ARB_multitexture + CONST_CAST(GLEW_ARB_multitexture) = glewGetExtension("GL_ARB_multitexture"); + if (glewExperimental || GLEW_ARB_multitexture) CONST_CAST(GLEW_ARB_multitexture) = !_glewInit_GL_ARB_multitexture(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_multitexture */ +#ifdef GL_ARB_occlusion_query + CONST_CAST(GLEW_ARB_occlusion_query) = glewGetExtension("GL_ARB_occlusion_query"); + if (glewExperimental || GLEW_ARB_occlusion_query) CONST_CAST(GLEW_ARB_occlusion_query) = !_glewInit_GL_ARB_occlusion_query(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_occlusion_query */ +#ifdef GL_ARB_pixel_buffer_object + CONST_CAST(GLEW_ARB_pixel_buffer_object) = glewGetExtension("GL_ARB_pixel_buffer_object"); +#endif /* GL_ARB_pixel_buffer_object */ +#ifdef GL_ARB_point_parameters + CONST_CAST(GLEW_ARB_point_parameters) = glewGetExtension("GL_ARB_point_parameters"); + if (glewExperimental || GLEW_ARB_point_parameters) CONST_CAST(GLEW_ARB_point_parameters) = !_glewInit_GL_ARB_point_parameters(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_point_parameters */ +#ifdef GL_ARB_point_sprite + CONST_CAST(GLEW_ARB_point_sprite) = glewGetExtension("GL_ARB_point_sprite"); +#endif /* GL_ARB_point_sprite */ +#ifdef GL_ARB_shader_objects + CONST_CAST(GLEW_ARB_shader_objects) = glewGetExtension("GL_ARB_shader_objects"); + if (glewExperimental || GLEW_ARB_shader_objects) CONST_CAST(GLEW_ARB_shader_objects) = !_glewInit_GL_ARB_shader_objects(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_shader_objects */ +#ifdef GL_ARB_shading_language_100 + CONST_CAST(GLEW_ARB_shading_language_100) = glewGetExtension("GL_ARB_shading_language_100"); +#endif /* GL_ARB_shading_language_100 */ +#ifdef GL_ARB_shadow + CONST_CAST(GLEW_ARB_shadow) = glewGetExtension("GL_ARB_shadow"); +#endif /* GL_ARB_shadow */ +#ifdef GL_ARB_shadow_ambient + CONST_CAST(GLEW_ARB_shadow_ambient) = glewGetExtension("GL_ARB_shadow_ambient"); +#endif /* GL_ARB_shadow_ambient */ +#ifdef GL_ARB_texture_border_clamp + CONST_CAST(GLEW_ARB_texture_border_clamp) = glewGetExtension("GL_ARB_texture_border_clamp"); +#endif /* GL_ARB_texture_border_clamp */ +#ifdef GL_ARB_texture_buffer_object + CONST_CAST(GLEW_ARB_texture_buffer_object) = glewGetExtension("GL_ARB_texture_buffer_object"); + if (glewExperimental || GLEW_ARB_texture_buffer_object) CONST_CAST(GLEW_ARB_texture_buffer_object) = !_glewInit_GL_ARB_texture_buffer_object(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_texture_buffer_object */ +#ifdef GL_ARB_texture_compression + CONST_CAST(GLEW_ARB_texture_compression) = glewGetExtension("GL_ARB_texture_compression"); + if (glewExperimental || GLEW_ARB_texture_compression) CONST_CAST(GLEW_ARB_texture_compression) = !_glewInit_GL_ARB_texture_compression(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_texture_compression */ +#ifdef GL_ARB_texture_compression_rgtc + CONST_CAST(GLEW_ARB_texture_compression_rgtc) = glewGetExtension("GL_ARB_texture_compression_rgtc"); +#endif /* GL_ARB_texture_compression_rgtc */ +#ifdef GL_ARB_texture_cube_map + CONST_CAST(GLEW_ARB_texture_cube_map) = glewGetExtension("GL_ARB_texture_cube_map"); +#endif /* GL_ARB_texture_cube_map */ +#ifdef GL_ARB_texture_env_add + CONST_CAST(GLEW_ARB_texture_env_add) = glewGetExtension("GL_ARB_texture_env_add"); +#endif /* GL_ARB_texture_env_add */ +#ifdef GL_ARB_texture_env_combine + CONST_CAST(GLEW_ARB_texture_env_combine) = glewGetExtension("GL_ARB_texture_env_combine"); +#endif /* GL_ARB_texture_env_combine */ +#ifdef GL_ARB_texture_env_crossbar + CONST_CAST(GLEW_ARB_texture_env_crossbar) = glewGetExtension("GL_ARB_texture_env_crossbar"); +#endif /* GL_ARB_texture_env_crossbar */ +#ifdef GL_ARB_texture_env_dot3 + CONST_CAST(GLEW_ARB_texture_env_dot3) = glewGetExtension("GL_ARB_texture_env_dot3"); +#endif /* GL_ARB_texture_env_dot3 */ +#ifdef GL_ARB_texture_float + CONST_CAST(GLEW_ARB_texture_float) = glewGetExtension("GL_ARB_texture_float"); +#endif /* GL_ARB_texture_float */ +#ifdef GL_ARB_texture_mirrored_repeat + CONST_CAST(GLEW_ARB_texture_mirrored_repeat) = glewGetExtension("GL_ARB_texture_mirrored_repeat"); +#endif /* GL_ARB_texture_mirrored_repeat */ +#ifdef GL_ARB_texture_non_power_of_two + CONST_CAST(GLEW_ARB_texture_non_power_of_two) = glewGetExtension("GL_ARB_texture_non_power_of_two"); +#endif /* GL_ARB_texture_non_power_of_two */ +#ifdef GL_ARB_texture_rectangle + CONST_CAST(GLEW_ARB_texture_rectangle) = glewGetExtension("GL_ARB_texture_rectangle"); +#endif /* GL_ARB_texture_rectangle */ +#ifdef GL_ARB_texture_rg + CONST_CAST(GLEW_ARB_texture_rg) = glewGetExtension("GL_ARB_texture_rg"); +#endif /* GL_ARB_texture_rg */ +#ifdef GL_ARB_transpose_matrix + CONST_CAST(GLEW_ARB_transpose_matrix) = glewGetExtension("GL_ARB_transpose_matrix"); + if (glewExperimental || GLEW_ARB_transpose_matrix) CONST_CAST(GLEW_ARB_transpose_matrix) = !_glewInit_GL_ARB_transpose_matrix(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_transpose_matrix */ +#ifdef GL_ARB_vertex_array_object + CONST_CAST(GLEW_ARB_vertex_array_object) = glewGetExtension("GL_ARB_vertex_array_object"); + if (glewExperimental || GLEW_ARB_vertex_array_object) CONST_CAST(GLEW_ARB_vertex_array_object) = !_glewInit_GL_ARB_vertex_array_object(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_vertex_array_object */ +#ifdef GL_ARB_vertex_blend + CONST_CAST(GLEW_ARB_vertex_blend) = glewGetExtension("GL_ARB_vertex_blend"); + if (glewExperimental || GLEW_ARB_vertex_blend) CONST_CAST(GLEW_ARB_vertex_blend) = !_glewInit_GL_ARB_vertex_blend(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_vertex_blend */ +#ifdef GL_ARB_vertex_buffer_object + CONST_CAST(GLEW_ARB_vertex_buffer_object) = glewGetExtension("GL_ARB_vertex_buffer_object"); + if (glewExperimental || GLEW_ARB_vertex_buffer_object) CONST_CAST(GLEW_ARB_vertex_buffer_object) = !_glewInit_GL_ARB_vertex_buffer_object(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_vertex_buffer_object */ +#ifdef GL_ARB_vertex_program + CONST_CAST(GLEW_ARB_vertex_program) = glewGetExtension("GL_ARB_vertex_program"); + if (glewExperimental || GLEW_ARB_vertex_program) CONST_CAST(GLEW_ARB_vertex_program) = !_glewInit_GL_ARB_vertex_program(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_vertex_program */ +#ifdef GL_ARB_vertex_shader + CONST_CAST(GLEW_ARB_vertex_shader) = glewGetExtension("GL_ARB_vertex_shader"); + if (glewExperimental || GLEW_ARB_vertex_shader) CONST_CAST(GLEW_ARB_vertex_shader) = !_glewInit_GL_ARB_vertex_shader(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_vertex_shader */ +#ifdef GL_ARB_window_pos + CONST_CAST(GLEW_ARB_window_pos) = glewGetExtension("GL_ARB_window_pos"); + if (glewExperimental || GLEW_ARB_window_pos) CONST_CAST(GLEW_ARB_window_pos) = !_glewInit_GL_ARB_window_pos(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_window_pos */ +#ifdef GL_ATIX_point_sprites + CONST_CAST(GLEW_ATIX_point_sprites) = glewGetExtension("GL_ATIX_point_sprites"); +#endif /* GL_ATIX_point_sprites */ +#ifdef GL_ATIX_texture_env_combine3 + CONST_CAST(GLEW_ATIX_texture_env_combine3) = glewGetExtension("GL_ATIX_texture_env_combine3"); +#endif /* GL_ATIX_texture_env_combine3 */ +#ifdef GL_ATIX_texture_env_route + CONST_CAST(GLEW_ATIX_texture_env_route) = glewGetExtension("GL_ATIX_texture_env_route"); +#endif /* GL_ATIX_texture_env_route */ +#ifdef GL_ATIX_vertex_shader_output_point_size + CONST_CAST(GLEW_ATIX_vertex_shader_output_point_size) = glewGetExtension("GL_ATIX_vertex_shader_output_point_size"); +#endif /* GL_ATIX_vertex_shader_output_point_size */ +#ifdef GL_ATI_draw_buffers + CONST_CAST(GLEW_ATI_draw_buffers) = glewGetExtension("GL_ATI_draw_buffers"); + if (glewExperimental || GLEW_ATI_draw_buffers) CONST_CAST(GLEW_ATI_draw_buffers) = !_glewInit_GL_ATI_draw_buffers(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ATI_draw_buffers */ +#ifdef GL_ATI_element_array + CONST_CAST(GLEW_ATI_element_array) = glewGetExtension("GL_ATI_element_array"); + if (glewExperimental || GLEW_ATI_element_array) CONST_CAST(GLEW_ATI_element_array) = !_glewInit_GL_ATI_element_array(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ATI_element_array */ +#ifdef GL_ATI_envmap_bumpmap + CONST_CAST(GLEW_ATI_envmap_bumpmap) = glewGetExtension("GL_ATI_envmap_bumpmap"); + if (glewExperimental || GLEW_ATI_envmap_bumpmap) CONST_CAST(GLEW_ATI_envmap_bumpmap) = !_glewInit_GL_ATI_envmap_bumpmap(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ATI_envmap_bumpmap */ +#ifdef GL_ATI_fragment_shader + CONST_CAST(GLEW_ATI_fragment_shader) = glewGetExtension("GL_ATI_fragment_shader"); + if (glewExperimental || GLEW_ATI_fragment_shader) CONST_CAST(GLEW_ATI_fragment_shader) = !_glewInit_GL_ATI_fragment_shader(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ATI_fragment_shader */ +#ifdef GL_ATI_map_object_buffer + CONST_CAST(GLEW_ATI_map_object_buffer) = glewGetExtension("GL_ATI_map_object_buffer"); + if (glewExperimental || GLEW_ATI_map_object_buffer) CONST_CAST(GLEW_ATI_map_object_buffer) = !_glewInit_GL_ATI_map_object_buffer(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ATI_map_object_buffer */ +#ifdef GL_ATI_pn_triangles + CONST_CAST(GLEW_ATI_pn_triangles) = glewGetExtension("GL_ATI_pn_triangles"); + if (glewExperimental || GLEW_ATI_pn_triangles) CONST_CAST(GLEW_ATI_pn_triangles) = !_glewInit_GL_ATI_pn_triangles(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ATI_pn_triangles */ +#ifdef GL_ATI_separate_stencil + CONST_CAST(GLEW_ATI_separate_stencil) = glewGetExtension("GL_ATI_separate_stencil"); + if (glewExperimental || GLEW_ATI_separate_stencil) CONST_CAST(GLEW_ATI_separate_stencil) = !_glewInit_GL_ATI_separate_stencil(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ATI_separate_stencil */ +#ifdef GL_ATI_shader_texture_lod + CONST_CAST(GLEW_ATI_shader_texture_lod) = glewGetExtension("GL_ATI_shader_texture_lod"); +#endif /* GL_ATI_shader_texture_lod */ +#ifdef GL_ATI_text_fragment_shader + CONST_CAST(GLEW_ATI_text_fragment_shader) = glewGetExtension("GL_ATI_text_fragment_shader"); +#endif /* GL_ATI_text_fragment_shader */ +#ifdef GL_ATI_texture_compression_3dc + CONST_CAST(GLEW_ATI_texture_compression_3dc) = glewGetExtension("GL_ATI_texture_compression_3dc"); +#endif /* GL_ATI_texture_compression_3dc */ +#ifdef GL_ATI_texture_env_combine3 + CONST_CAST(GLEW_ATI_texture_env_combine3) = glewGetExtension("GL_ATI_texture_env_combine3"); +#endif /* GL_ATI_texture_env_combine3 */ +#ifdef GL_ATI_texture_float + CONST_CAST(GLEW_ATI_texture_float) = glewGetExtension("GL_ATI_texture_float"); +#endif /* GL_ATI_texture_float */ +#ifdef GL_ATI_texture_mirror_once + CONST_CAST(GLEW_ATI_texture_mirror_once) = glewGetExtension("GL_ATI_texture_mirror_once"); +#endif /* GL_ATI_texture_mirror_once */ +#ifdef GL_ATI_vertex_array_object + CONST_CAST(GLEW_ATI_vertex_array_object) = glewGetExtension("GL_ATI_vertex_array_object"); + if (glewExperimental || GLEW_ATI_vertex_array_object) CONST_CAST(GLEW_ATI_vertex_array_object) = !_glewInit_GL_ATI_vertex_array_object(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ATI_vertex_array_object */ +#ifdef GL_ATI_vertex_attrib_array_object + CONST_CAST(GLEW_ATI_vertex_attrib_array_object) = glewGetExtension("GL_ATI_vertex_attrib_array_object"); + if (glewExperimental || GLEW_ATI_vertex_attrib_array_object) CONST_CAST(GLEW_ATI_vertex_attrib_array_object) = !_glewInit_GL_ATI_vertex_attrib_array_object(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ATI_vertex_attrib_array_object */ +#ifdef GL_ATI_vertex_streams + CONST_CAST(GLEW_ATI_vertex_streams) = glewGetExtension("GL_ATI_vertex_streams"); + if (glewExperimental || GLEW_ATI_vertex_streams) CONST_CAST(GLEW_ATI_vertex_streams) = !_glewInit_GL_ATI_vertex_streams(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ATI_vertex_streams */ +#ifdef GL_EXT_422_pixels + CONST_CAST(GLEW_EXT_422_pixels) = glewGetExtension("GL_EXT_422_pixels"); +#endif /* GL_EXT_422_pixels */ +#ifdef GL_EXT_Cg_shader + CONST_CAST(GLEW_EXT_Cg_shader) = glewGetExtension("GL_EXT_Cg_shader"); +#endif /* GL_EXT_Cg_shader */ +#ifdef GL_EXT_abgr + CONST_CAST(GLEW_EXT_abgr) = glewGetExtension("GL_EXT_abgr"); +#endif /* GL_EXT_abgr */ +#ifdef GL_EXT_bgra + CONST_CAST(GLEW_EXT_bgra) = glewGetExtension("GL_EXT_bgra"); +#endif /* GL_EXT_bgra */ +#ifdef GL_EXT_bindable_uniform + CONST_CAST(GLEW_EXT_bindable_uniform) = glewGetExtension("GL_EXT_bindable_uniform"); + if (glewExperimental || GLEW_EXT_bindable_uniform) CONST_CAST(GLEW_EXT_bindable_uniform) = !_glewInit_GL_EXT_bindable_uniform(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_bindable_uniform */ +#ifdef GL_EXT_blend_color + CONST_CAST(GLEW_EXT_blend_color) = glewGetExtension("GL_EXT_blend_color"); + if (glewExperimental || GLEW_EXT_blend_color) CONST_CAST(GLEW_EXT_blend_color) = !_glewInit_GL_EXT_blend_color(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_blend_color */ +#ifdef GL_EXT_blend_equation_separate + CONST_CAST(GLEW_EXT_blend_equation_separate) = glewGetExtension("GL_EXT_blend_equation_separate"); + if (glewExperimental || GLEW_EXT_blend_equation_separate) CONST_CAST(GLEW_EXT_blend_equation_separate) = !_glewInit_GL_EXT_blend_equation_separate(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_blend_equation_separate */ +#ifdef GL_EXT_blend_func_separate + CONST_CAST(GLEW_EXT_blend_func_separate) = glewGetExtension("GL_EXT_blend_func_separate"); + if (glewExperimental || GLEW_EXT_blend_func_separate) CONST_CAST(GLEW_EXT_blend_func_separate) = !_glewInit_GL_EXT_blend_func_separate(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_blend_func_separate */ +#ifdef GL_EXT_blend_logic_op + CONST_CAST(GLEW_EXT_blend_logic_op) = glewGetExtension("GL_EXT_blend_logic_op"); +#endif /* GL_EXT_blend_logic_op */ +#ifdef GL_EXT_blend_minmax + CONST_CAST(GLEW_EXT_blend_minmax) = glewGetExtension("GL_EXT_blend_minmax"); + if (glewExperimental || GLEW_EXT_blend_minmax) CONST_CAST(GLEW_EXT_blend_minmax) = !_glewInit_GL_EXT_blend_minmax(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_blend_minmax */ +#ifdef GL_EXT_blend_subtract + CONST_CAST(GLEW_EXT_blend_subtract) = glewGetExtension("GL_EXT_blend_subtract"); +#endif /* GL_EXT_blend_subtract */ +#ifdef GL_EXT_clip_volume_hint + CONST_CAST(GLEW_EXT_clip_volume_hint) = glewGetExtension("GL_EXT_clip_volume_hint"); +#endif /* GL_EXT_clip_volume_hint */ +#ifdef GL_EXT_cmyka + CONST_CAST(GLEW_EXT_cmyka) = glewGetExtension("GL_EXT_cmyka"); +#endif /* GL_EXT_cmyka */ +#ifdef GL_EXT_color_subtable + CONST_CAST(GLEW_EXT_color_subtable) = glewGetExtension("GL_EXT_color_subtable"); + if (glewExperimental || GLEW_EXT_color_subtable) CONST_CAST(GLEW_EXT_color_subtable) = !_glewInit_GL_EXT_color_subtable(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_color_subtable */ +#ifdef GL_EXT_compiled_vertex_array + CONST_CAST(GLEW_EXT_compiled_vertex_array) = glewGetExtension("GL_EXT_compiled_vertex_array"); + if (glewExperimental || GLEW_EXT_compiled_vertex_array) CONST_CAST(GLEW_EXT_compiled_vertex_array) = !_glewInit_GL_EXT_compiled_vertex_array(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_compiled_vertex_array */ +#ifdef GL_EXT_convolution + CONST_CAST(GLEW_EXT_convolution) = glewGetExtension("GL_EXT_convolution"); + if (glewExperimental || GLEW_EXT_convolution) CONST_CAST(GLEW_EXT_convolution) = !_glewInit_GL_EXT_convolution(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_convolution */ +#ifdef GL_EXT_coordinate_frame + CONST_CAST(GLEW_EXT_coordinate_frame) = glewGetExtension("GL_EXT_coordinate_frame"); + if (glewExperimental || GLEW_EXT_coordinate_frame) CONST_CAST(GLEW_EXT_coordinate_frame) = !_glewInit_GL_EXT_coordinate_frame(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_coordinate_frame */ +#ifdef GL_EXT_copy_texture + CONST_CAST(GLEW_EXT_copy_texture) = glewGetExtension("GL_EXT_copy_texture"); + if (glewExperimental || GLEW_EXT_copy_texture) CONST_CAST(GLEW_EXT_copy_texture) = !_glewInit_GL_EXT_copy_texture(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_copy_texture */ +#ifdef GL_EXT_cull_vertex + CONST_CAST(GLEW_EXT_cull_vertex) = glewGetExtension("GL_EXT_cull_vertex"); + if (glewExperimental || GLEW_EXT_cull_vertex) CONST_CAST(GLEW_EXT_cull_vertex) = !_glewInit_GL_EXT_cull_vertex(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_cull_vertex */ +#ifdef GL_EXT_depth_bounds_test + CONST_CAST(GLEW_EXT_depth_bounds_test) = glewGetExtension("GL_EXT_depth_bounds_test"); + if (glewExperimental || GLEW_EXT_depth_bounds_test) CONST_CAST(GLEW_EXT_depth_bounds_test) = !_glewInit_GL_EXT_depth_bounds_test(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_depth_bounds_test */ +#ifdef GL_EXT_direct_state_access + CONST_CAST(GLEW_EXT_direct_state_access) = glewGetExtension("GL_EXT_direct_state_access"); + if (glewExperimental || GLEW_EXT_direct_state_access) CONST_CAST(GLEW_EXT_direct_state_access) = !_glewInit_GL_EXT_direct_state_access(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_direct_state_access */ +#ifdef GL_EXT_draw_buffers2 + CONST_CAST(GLEW_EXT_draw_buffers2) = glewGetExtension("GL_EXT_draw_buffers2"); + if (glewExperimental || GLEW_EXT_draw_buffers2) CONST_CAST(GLEW_EXT_draw_buffers2) = !_glewInit_GL_EXT_draw_buffers2(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_draw_buffers2 */ +#ifdef GL_EXT_draw_instanced + CONST_CAST(GLEW_EXT_draw_instanced) = glewGetExtension("GL_EXT_draw_instanced"); + if (glewExperimental || GLEW_EXT_draw_instanced) CONST_CAST(GLEW_EXT_draw_instanced) = !_glewInit_GL_EXT_draw_instanced(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_draw_instanced */ +#ifdef GL_EXT_draw_range_elements + CONST_CAST(GLEW_EXT_draw_range_elements) = glewGetExtension("GL_EXT_draw_range_elements"); + if (glewExperimental || GLEW_EXT_draw_range_elements) CONST_CAST(GLEW_EXT_draw_range_elements) = !_glewInit_GL_EXT_draw_range_elements(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_draw_range_elements */ +#ifdef GL_EXT_fog_coord + CONST_CAST(GLEW_EXT_fog_coord) = glewGetExtension("GL_EXT_fog_coord"); + if (glewExperimental || GLEW_EXT_fog_coord) CONST_CAST(GLEW_EXT_fog_coord) = !_glewInit_GL_EXT_fog_coord(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_fog_coord */ +#ifdef GL_EXT_fragment_lighting + CONST_CAST(GLEW_EXT_fragment_lighting) = glewGetExtension("GL_EXT_fragment_lighting"); + if (glewExperimental || GLEW_EXT_fragment_lighting) CONST_CAST(GLEW_EXT_fragment_lighting) = !_glewInit_GL_EXT_fragment_lighting(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_fragment_lighting */ +#ifdef GL_EXT_framebuffer_blit + CONST_CAST(GLEW_EXT_framebuffer_blit) = glewGetExtension("GL_EXT_framebuffer_blit"); + if (glewExperimental || GLEW_EXT_framebuffer_blit) CONST_CAST(GLEW_EXT_framebuffer_blit) = !_glewInit_GL_EXT_framebuffer_blit(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_framebuffer_blit */ +#ifdef GL_EXT_framebuffer_multisample + CONST_CAST(GLEW_EXT_framebuffer_multisample) = glewGetExtension("GL_EXT_framebuffer_multisample"); + if (glewExperimental || GLEW_EXT_framebuffer_multisample) CONST_CAST(GLEW_EXT_framebuffer_multisample) = !_glewInit_GL_EXT_framebuffer_multisample(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_framebuffer_multisample */ +#ifdef GL_EXT_framebuffer_object + CONST_CAST(GLEW_EXT_framebuffer_object) = glewGetExtension("GL_EXT_framebuffer_object"); + if (glewExperimental || GLEW_EXT_framebuffer_object) CONST_CAST(GLEW_EXT_framebuffer_object) = !_glewInit_GL_EXT_framebuffer_object(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_framebuffer_object */ +#ifdef GL_EXT_framebuffer_sRGB + CONST_CAST(GLEW_EXT_framebuffer_sRGB) = glewGetExtension("GL_EXT_framebuffer_sRGB"); +#endif /* GL_EXT_framebuffer_sRGB */ +#ifdef GL_EXT_geometry_shader4 + CONST_CAST(GLEW_EXT_geometry_shader4) = glewGetExtension("GL_EXT_geometry_shader4"); + if (glewExperimental || GLEW_EXT_geometry_shader4) CONST_CAST(GLEW_EXT_geometry_shader4) = !_glewInit_GL_EXT_geometry_shader4(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_geometry_shader4 */ +#ifdef GL_EXT_gpu_program_parameters + CONST_CAST(GLEW_EXT_gpu_program_parameters) = glewGetExtension("GL_EXT_gpu_program_parameters"); + if (glewExperimental || GLEW_EXT_gpu_program_parameters) CONST_CAST(GLEW_EXT_gpu_program_parameters) = !_glewInit_GL_EXT_gpu_program_parameters(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_gpu_program_parameters */ +#ifdef GL_EXT_gpu_shader4 + CONST_CAST(GLEW_EXT_gpu_shader4) = glewGetExtension("GL_EXT_gpu_shader4"); + if (glewExperimental || GLEW_EXT_gpu_shader4) CONST_CAST(GLEW_EXT_gpu_shader4) = !_glewInit_GL_EXT_gpu_shader4(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_gpu_shader4 */ +#ifdef GL_EXT_histogram + CONST_CAST(GLEW_EXT_histogram) = glewGetExtension("GL_EXT_histogram"); + if (glewExperimental || GLEW_EXT_histogram) CONST_CAST(GLEW_EXT_histogram) = !_glewInit_GL_EXT_histogram(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_histogram */ +#ifdef GL_EXT_index_array_formats + CONST_CAST(GLEW_EXT_index_array_formats) = glewGetExtension("GL_EXT_index_array_formats"); +#endif /* GL_EXT_index_array_formats */ +#ifdef GL_EXT_index_func + CONST_CAST(GLEW_EXT_index_func) = glewGetExtension("GL_EXT_index_func"); + if (glewExperimental || GLEW_EXT_index_func) CONST_CAST(GLEW_EXT_index_func) = !_glewInit_GL_EXT_index_func(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_index_func */ +#ifdef GL_EXT_index_material + CONST_CAST(GLEW_EXT_index_material) = glewGetExtension("GL_EXT_index_material"); + if (glewExperimental || GLEW_EXT_index_material) CONST_CAST(GLEW_EXT_index_material) = !_glewInit_GL_EXT_index_material(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_index_material */ +#ifdef GL_EXT_index_texture + CONST_CAST(GLEW_EXT_index_texture) = glewGetExtension("GL_EXT_index_texture"); +#endif /* GL_EXT_index_texture */ +#ifdef GL_EXT_light_texture + CONST_CAST(GLEW_EXT_light_texture) = glewGetExtension("GL_EXT_light_texture"); + if (glewExperimental || GLEW_EXT_light_texture) CONST_CAST(GLEW_EXT_light_texture) = !_glewInit_GL_EXT_light_texture(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_light_texture */ +#ifdef GL_EXT_misc_attribute + CONST_CAST(GLEW_EXT_misc_attribute) = glewGetExtension("GL_EXT_misc_attribute"); +#endif /* GL_EXT_misc_attribute */ +#ifdef GL_EXT_multi_draw_arrays + CONST_CAST(GLEW_EXT_multi_draw_arrays) = glewGetExtension("GL_EXT_multi_draw_arrays"); + if (glewExperimental || GLEW_EXT_multi_draw_arrays) CONST_CAST(GLEW_EXT_multi_draw_arrays) = !_glewInit_GL_EXT_multi_draw_arrays(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_multi_draw_arrays */ +#ifdef GL_EXT_multisample + CONST_CAST(GLEW_EXT_multisample) = glewGetExtension("GL_EXT_multisample"); + if (glewExperimental || GLEW_EXT_multisample) CONST_CAST(GLEW_EXT_multisample) = !_glewInit_GL_EXT_multisample(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_multisample */ +#ifdef GL_EXT_packed_depth_stencil + CONST_CAST(GLEW_EXT_packed_depth_stencil) = glewGetExtension("GL_EXT_packed_depth_stencil"); +#endif /* GL_EXT_packed_depth_stencil */ +#ifdef GL_EXT_packed_float + CONST_CAST(GLEW_EXT_packed_float) = glewGetExtension("GL_EXT_packed_float"); +#endif /* GL_EXT_packed_float */ +#ifdef GL_EXT_packed_pixels + CONST_CAST(GLEW_EXT_packed_pixels) = glewGetExtension("GL_EXT_packed_pixels"); +#endif /* GL_EXT_packed_pixels */ +#ifdef GL_EXT_paletted_texture + CONST_CAST(GLEW_EXT_paletted_texture) = glewGetExtension("GL_EXT_paletted_texture"); + if (glewExperimental || GLEW_EXT_paletted_texture) CONST_CAST(GLEW_EXT_paletted_texture) = !_glewInit_GL_EXT_paletted_texture(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_paletted_texture */ +#ifdef GL_EXT_pixel_buffer_object + CONST_CAST(GLEW_EXT_pixel_buffer_object) = glewGetExtension("GL_EXT_pixel_buffer_object"); +#endif /* GL_EXT_pixel_buffer_object */ +#ifdef GL_EXT_pixel_transform + CONST_CAST(GLEW_EXT_pixel_transform) = glewGetExtension("GL_EXT_pixel_transform"); + if (glewExperimental || GLEW_EXT_pixel_transform) CONST_CAST(GLEW_EXT_pixel_transform) = !_glewInit_GL_EXT_pixel_transform(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_pixel_transform */ +#ifdef GL_EXT_pixel_transform_color_table + CONST_CAST(GLEW_EXT_pixel_transform_color_table) = glewGetExtension("GL_EXT_pixel_transform_color_table"); +#endif /* GL_EXT_pixel_transform_color_table */ +#ifdef GL_EXT_point_parameters + CONST_CAST(GLEW_EXT_point_parameters) = glewGetExtension("GL_EXT_point_parameters"); + if (glewExperimental || GLEW_EXT_point_parameters) CONST_CAST(GLEW_EXT_point_parameters) = !_glewInit_GL_EXT_point_parameters(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_point_parameters */ +#ifdef GL_EXT_polygon_offset + CONST_CAST(GLEW_EXT_polygon_offset) = glewGetExtension("GL_EXT_polygon_offset"); + if (glewExperimental || GLEW_EXT_polygon_offset) CONST_CAST(GLEW_EXT_polygon_offset) = !_glewInit_GL_EXT_polygon_offset(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_polygon_offset */ +#ifdef GL_EXT_rescale_normal + CONST_CAST(GLEW_EXT_rescale_normal) = glewGetExtension("GL_EXT_rescale_normal"); +#endif /* GL_EXT_rescale_normal */ +#ifdef GL_EXT_scene_marker + CONST_CAST(GLEW_EXT_scene_marker) = glewGetExtension("GL_EXT_scene_marker"); + if (glewExperimental || GLEW_EXT_scene_marker) CONST_CAST(GLEW_EXT_scene_marker) = !_glewInit_GL_EXT_scene_marker(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_scene_marker */ +#ifdef GL_EXT_secondary_color + CONST_CAST(GLEW_EXT_secondary_color) = glewGetExtension("GL_EXT_secondary_color"); + if (glewExperimental || GLEW_EXT_secondary_color) CONST_CAST(GLEW_EXT_secondary_color) = !_glewInit_GL_EXT_secondary_color(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_secondary_color */ +#ifdef GL_EXT_separate_specular_color + CONST_CAST(GLEW_EXT_separate_specular_color) = glewGetExtension("GL_EXT_separate_specular_color"); +#endif /* GL_EXT_separate_specular_color */ +#ifdef GL_EXT_shadow_funcs + CONST_CAST(GLEW_EXT_shadow_funcs) = glewGetExtension("GL_EXT_shadow_funcs"); +#endif /* GL_EXT_shadow_funcs */ +#ifdef GL_EXT_shared_texture_palette + CONST_CAST(GLEW_EXT_shared_texture_palette) = glewGetExtension("GL_EXT_shared_texture_palette"); +#endif /* GL_EXT_shared_texture_palette */ +#ifdef GL_EXT_stencil_clear_tag + CONST_CAST(GLEW_EXT_stencil_clear_tag) = glewGetExtension("GL_EXT_stencil_clear_tag"); +#endif /* GL_EXT_stencil_clear_tag */ +#ifdef GL_EXT_stencil_two_side + CONST_CAST(GLEW_EXT_stencil_two_side) = glewGetExtension("GL_EXT_stencil_two_side"); + if (glewExperimental || GLEW_EXT_stencil_two_side) CONST_CAST(GLEW_EXT_stencil_two_side) = !_glewInit_GL_EXT_stencil_two_side(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_stencil_two_side */ +#ifdef GL_EXT_stencil_wrap + CONST_CAST(GLEW_EXT_stencil_wrap) = glewGetExtension("GL_EXT_stencil_wrap"); +#endif /* GL_EXT_stencil_wrap */ +#ifdef GL_EXT_subtexture + CONST_CAST(GLEW_EXT_subtexture) = glewGetExtension("GL_EXT_subtexture"); + if (glewExperimental || GLEW_EXT_subtexture) CONST_CAST(GLEW_EXT_subtexture) = !_glewInit_GL_EXT_subtexture(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_subtexture */ +#ifdef GL_EXT_texture + CONST_CAST(GLEW_EXT_texture) = glewGetExtension("GL_EXT_texture"); +#endif /* GL_EXT_texture */ +#ifdef GL_EXT_texture3D + CONST_CAST(GLEW_EXT_texture3D) = glewGetExtension("GL_EXT_texture3D"); + if (glewExperimental || GLEW_EXT_texture3D) CONST_CAST(GLEW_EXT_texture3D) = !_glewInit_GL_EXT_texture3D(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_texture3D */ +#ifdef GL_EXT_texture_array + CONST_CAST(GLEW_EXT_texture_array) = glewGetExtension("GL_EXT_texture_array"); +#endif /* GL_EXT_texture_array */ +#ifdef GL_EXT_texture_buffer_object + CONST_CAST(GLEW_EXT_texture_buffer_object) = glewGetExtension("GL_EXT_texture_buffer_object"); + if (glewExperimental || GLEW_EXT_texture_buffer_object) CONST_CAST(GLEW_EXT_texture_buffer_object) = !_glewInit_GL_EXT_texture_buffer_object(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_texture_buffer_object */ +#ifdef GL_EXT_texture_compression_dxt1 + CONST_CAST(GLEW_EXT_texture_compression_dxt1) = glewGetExtension("GL_EXT_texture_compression_dxt1"); +#endif /* GL_EXT_texture_compression_dxt1 */ +#ifdef GL_EXT_texture_compression_latc + CONST_CAST(GLEW_EXT_texture_compression_latc) = glewGetExtension("GL_EXT_texture_compression_latc"); +#endif /* GL_EXT_texture_compression_latc */ +#ifdef GL_EXT_texture_compression_rgtc + CONST_CAST(GLEW_EXT_texture_compression_rgtc) = glewGetExtension("GL_EXT_texture_compression_rgtc"); +#endif /* GL_EXT_texture_compression_rgtc */ +#ifdef GL_EXT_texture_compression_s3tc + CONST_CAST(GLEW_EXT_texture_compression_s3tc) = glewGetExtension("GL_EXT_texture_compression_s3tc"); +#endif /* GL_EXT_texture_compression_s3tc */ +#ifdef GL_EXT_texture_cube_map + CONST_CAST(GLEW_EXT_texture_cube_map) = glewGetExtension("GL_EXT_texture_cube_map"); +#endif /* GL_EXT_texture_cube_map */ +#ifdef GL_EXT_texture_edge_clamp + CONST_CAST(GLEW_EXT_texture_edge_clamp) = glewGetExtension("GL_EXT_texture_edge_clamp"); +#endif /* GL_EXT_texture_edge_clamp */ +#ifdef GL_EXT_texture_env + CONST_CAST(GLEW_EXT_texture_env) = glewGetExtension("GL_EXT_texture_env"); +#endif /* GL_EXT_texture_env */ +#ifdef GL_EXT_texture_env_add + CONST_CAST(GLEW_EXT_texture_env_add) = glewGetExtension("GL_EXT_texture_env_add"); +#endif /* GL_EXT_texture_env_add */ +#ifdef GL_EXT_texture_env_combine + CONST_CAST(GLEW_EXT_texture_env_combine) = glewGetExtension("GL_EXT_texture_env_combine"); +#endif /* GL_EXT_texture_env_combine */ +#ifdef GL_EXT_texture_env_dot3 + CONST_CAST(GLEW_EXT_texture_env_dot3) = glewGetExtension("GL_EXT_texture_env_dot3"); +#endif /* GL_EXT_texture_env_dot3 */ +#ifdef GL_EXT_texture_filter_anisotropic + CONST_CAST(GLEW_EXT_texture_filter_anisotropic) = glewGetExtension("GL_EXT_texture_filter_anisotropic"); +#endif /* GL_EXT_texture_filter_anisotropic */ +#ifdef GL_EXT_texture_integer + CONST_CAST(GLEW_EXT_texture_integer) = glewGetExtension("GL_EXT_texture_integer"); + if (glewExperimental || GLEW_EXT_texture_integer) CONST_CAST(GLEW_EXT_texture_integer) = !_glewInit_GL_EXT_texture_integer(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_texture_integer */ +#ifdef GL_EXT_texture_lod_bias + CONST_CAST(GLEW_EXT_texture_lod_bias) = glewGetExtension("GL_EXT_texture_lod_bias"); +#endif /* GL_EXT_texture_lod_bias */ +#ifdef GL_EXT_texture_mirror_clamp + CONST_CAST(GLEW_EXT_texture_mirror_clamp) = glewGetExtension("GL_EXT_texture_mirror_clamp"); +#endif /* GL_EXT_texture_mirror_clamp */ +#ifdef GL_EXT_texture_object + CONST_CAST(GLEW_EXT_texture_object) = glewGetExtension("GL_EXT_texture_object"); + if (glewExperimental || GLEW_EXT_texture_object) CONST_CAST(GLEW_EXT_texture_object) = !_glewInit_GL_EXT_texture_object(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_texture_object */ +#ifdef GL_EXT_texture_perturb_normal + CONST_CAST(GLEW_EXT_texture_perturb_normal) = glewGetExtension("GL_EXT_texture_perturb_normal"); + if (glewExperimental || GLEW_EXT_texture_perturb_normal) CONST_CAST(GLEW_EXT_texture_perturb_normal) = !_glewInit_GL_EXT_texture_perturb_normal(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_texture_perturb_normal */ +#ifdef GL_EXT_texture_rectangle + CONST_CAST(GLEW_EXT_texture_rectangle) = glewGetExtension("GL_EXT_texture_rectangle"); +#endif /* GL_EXT_texture_rectangle */ +#ifdef GL_EXT_texture_sRGB + CONST_CAST(GLEW_EXT_texture_sRGB) = glewGetExtension("GL_EXT_texture_sRGB"); +#endif /* GL_EXT_texture_sRGB */ +#ifdef GL_EXT_texture_shared_exponent + CONST_CAST(GLEW_EXT_texture_shared_exponent) = glewGetExtension("GL_EXT_texture_shared_exponent"); +#endif /* GL_EXT_texture_shared_exponent */ +#ifdef GL_EXT_texture_swizzle + CONST_CAST(GLEW_EXT_texture_swizzle) = glewGetExtension("GL_EXT_texture_swizzle"); +#endif /* GL_EXT_texture_swizzle */ +#ifdef GL_EXT_timer_query + CONST_CAST(GLEW_EXT_timer_query) = glewGetExtension("GL_EXT_timer_query"); + if (glewExperimental || GLEW_EXT_timer_query) CONST_CAST(GLEW_EXT_timer_query) = !_glewInit_GL_EXT_timer_query(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_timer_query */ +#ifdef GL_EXT_transform_feedback + CONST_CAST(GLEW_EXT_transform_feedback) = glewGetExtension("GL_EXT_transform_feedback"); + if (glewExperimental || GLEW_EXT_transform_feedback) CONST_CAST(GLEW_EXT_transform_feedback) = !_glewInit_GL_EXT_transform_feedback(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_transform_feedback */ +#ifdef GL_EXT_vertex_array + CONST_CAST(GLEW_EXT_vertex_array) = glewGetExtension("GL_EXT_vertex_array"); + if (glewExperimental || GLEW_EXT_vertex_array) CONST_CAST(GLEW_EXT_vertex_array) = !_glewInit_GL_EXT_vertex_array(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_vertex_array */ +#ifdef GL_EXT_vertex_array_bgra + CONST_CAST(GLEW_EXT_vertex_array_bgra) = glewGetExtension("GL_EXT_vertex_array_bgra"); +#endif /* GL_EXT_vertex_array_bgra */ +#ifdef GL_EXT_vertex_shader + CONST_CAST(GLEW_EXT_vertex_shader) = glewGetExtension("GL_EXT_vertex_shader"); + if (glewExperimental || GLEW_EXT_vertex_shader) CONST_CAST(GLEW_EXT_vertex_shader) = !_glewInit_GL_EXT_vertex_shader(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_vertex_shader */ +#ifdef GL_EXT_vertex_weighting + CONST_CAST(GLEW_EXT_vertex_weighting) = glewGetExtension("GL_EXT_vertex_weighting"); + if (glewExperimental || GLEW_EXT_vertex_weighting) CONST_CAST(GLEW_EXT_vertex_weighting) = !_glewInit_GL_EXT_vertex_weighting(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_vertex_weighting */ +#ifdef GL_GREMEDY_frame_terminator + CONST_CAST(GLEW_GREMEDY_frame_terminator) = glewGetExtension("GL_GREMEDY_frame_terminator"); + if (glewExperimental || GLEW_GREMEDY_frame_terminator) CONST_CAST(GLEW_GREMEDY_frame_terminator) = !_glewInit_GL_GREMEDY_frame_terminator(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_GREMEDY_frame_terminator */ +#ifdef GL_GREMEDY_string_marker + CONST_CAST(GLEW_GREMEDY_string_marker) = glewGetExtension("GL_GREMEDY_string_marker"); + if (glewExperimental || GLEW_GREMEDY_string_marker) CONST_CAST(GLEW_GREMEDY_string_marker) = !_glewInit_GL_GREMEDY_string_marker(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_GREMEDY_string_marker */ +#ifdef GL_HP_convolution_border_modes + CONST_CAST(GLEW_HP_convolution_border_modes) = glewGetExtension("GL_HP_convolution_border_modes"); +#endif /* GL_HP_convolution_border_modes */ +#ifdef GL_HP_image_transform + CONST_CAST(GLEW_HP_image_transform) = glewGetExtension("GL_HP_image_transform"); + if (glewExperimental || GLEW_HP_image_transform) CONST_CAST(GLEW_HP_image_transform) = !_glewInit_GL_HP_image_transform(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_HP_image_transform */ +#ifdef GL_HP_occlusion_test + CONST_CAST(GLEW_HP_occlusion_test) = glewGetExtension("GL_HP_occlusion_test"); +#endif /* GL_HP_occlusion_test */ +#ifdef GL_HP_texture_lighting + CONST_CAST(GLEW_HP_texture_lighting) = glewGetExtension("GL_HP_texture_lighting"); +#endif /* GL_HP_texture_lighting */ +#ifdef GL_IBM_cull_vertex + CONST_CAST(GLEW_IBM_cull_vertex) = glewGetExtension("GL_IBM_cull_vertex"); +#endif /* GL_IBM_cull_vertex */ +#ifdef GL_IBM_multimode_draw_arrays + CONST_CAST(GLEW_IBM_multimode_draw_arrays) = glewGetExtension("GL_IBM_multimode_draw_arrays"); + if (glewExperimental || GLEW_IBM_multimode_draw_arrays) CONST_CAST(GLEW_IBM_multimode_draw_arrays) = !_glewInit_GL_IBM_multimode_draw_arrays(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_IBM_multimode_draw_arrays */ +#ifdef GL_IBM_rasterpos_clip + CONST_CAST(GLEW_IBM_rasterpos_clip) = glewGetExtension("GL_IBM_rasterpos_clip"); +#endif /* GL_IBM_rasterpos_clip */ +#ifdef GL_IBM_static_data + CONST_CAST(GLEW_IBM_static_data) = glewGetExtension("GL_IBM_static_data"); +#endif /* GL_IBM_static_data */ +#ifdef GL_IBM_texture_mirrored_repeat + CONST_CAST(GLEW_IBM_texture_mirrored_repeat) = glewGetExtension("GL_IBM_texture_mirrored_repeat"); +#endif /* GL_IBM_texture_mirrored_repeat */ +#ifdef GL_IBM_vertex_array_lists + CONST_CAST(GLEW_IBM_vertex_array_lists) = glewGetExtension("GL_IBM_vertex_array_lists"); + if (glewExperimental || GLEW_IBM_vertex_array_lists) CONST_CAST(GLEW_IBM_vertex_array_lists) = !_glewInit_GL_IBM_vertex_array_lists(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_IBM_vertex_array_lists */ +#ifdef GL_INGR_color_clamp + CONST_CAST(GLEW_INGR_color_clamp) = glewGetExtension("GL_INGR_color_clamp"); +#endif /* GL_INGR_color_clamp */ +#ifdef GL_INGR_interlace_read + CONST_CAST(GLEW_INGR_interlace_read) = glewGetExtension("GL_INGR_interlace_read"); +#endif /* GL_INGR_interlace_read */ +#ifdef GL_INTEL_parallel_arrays + CONST_CAST(GLEW_INTEL_parallel_arrays) = glewGetExtension("GL_INTEL_parallel_arrays"); + if (glewExperimental || GLEW_INTEL_parallel_arrays) CONST_CAST(GLEW_INTEL_parallel_arrays) = !_glewInit_GL_INTEL_parallel_arrays(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_INTEL_parallel_arrays */ +#ifdef GL_INTEL_texture_scissor + CONST_CAST(GLEW_INTEL_texture_scissor) = glewGetExtension("GL_INTEL_texture_scissor"); + if (glewExperimental || GLEW_INTEL_texture_scissor) CONST_CAST(GLEW_INTEL_texture_scissor) = !_glewInit_GL_INTEL_texture_scissor(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_INTEL_texture_scissor */ +#ifdef GL_KTX_buffer_region + CONST_CAST(GLEW_KTX_buffer_region) = glewGetExtension("GL_KTX_buffer_region"); + if (glewExperimental || GLEW_KTX_buffer_region) CONST_CAST(GLEW_KTX_buffer_region) = !_glewInit_GL_KTX_buffer_region(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_KTX_buffer_region */ +#ifdef GL_MESAX_texture_stack + CONST_CAST(GLEW_MESAX_texture_stack) = glewGetExtension("GL_MESAX_texture_stack"); +#endif /* GL_MESAX_texture_stack */ +#ifdef GL_MESA_pack_invert + CONST_CAST(GLEW_MESA_pack_invert) = glewGetExtension("GL_MESA_pack_invert"); +#endif /* GL_MESA_pack_invert */ +#ifdef GL_MESA_resize_buffers + CONST_CAST(GLEW_MESA_resize_buffers) = glewGetExtension("GL_MESA_resize_buffers"); + if (glewExperimental || GLEW_MESA_resize_buffers) CONST_CAST(GLEW_MESA_resize_buffers) = !_glewInit_GL_MESA_resize_buffers(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_MESA_resize_buffers */ +#ifdef GL_MESA_window_pos + CONST_CAST(GLEW_MESA_window_pos) = glewGetExtension("GL_MESA_window_pos"); + if (glewExperimental || GLEW_MESA_window_pos) CONST_CAST(GLEW_MESA_window_pos) = !_glewInit_GL_MESA_window_pos(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_MESA_window_pos */ +#ifdef GL_MESA_ycbcr_texture + CONST_CAST(GLEW_MESA_ycbcr_texture) = glewGetExtension("GL_MESA_ycbcr_texture"); +#endif /* GL_MESA_ycbcr_texture */ +#ifdef GL_NV_blend_square + CONST_CAST(GLEW_NV_blend_square) = glewGetExtension("GL_NV_blend_square"); +#endif /* GL_NV_blend_square */ +#ifdef GL_NV_conditional_render + CONST_CAST(GLEW_NV_conditional_render) = glewGetExtension("GL_NV_conditional_render"); + if (glewExperimental || GLEW_NV_conditional_render) CONST_CAST(GLEW_NV_conditional_render) = !_glewInit_GL_NV_conditional_render(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_conditional_render */ +#ifdef GL_NV_copy_depth_to_color + CONST_CAST(GLEW_NV_copy_depth_to_color) = glewGetExtension("GL_NV_copy_depth_to_color"); +#endif /* GL_NV_copy_depth_to_color */ +#ifdef GL_NV_depth_buffer_float + CONST_CAST(GLEW_NV_depth_buffer_float) = glewGetExtension("GL_NV_depth_buffer_float"); + if (glewExperimental || GLEW_NV_depth_buffer_float) CONST_CAST(GLEW_NV_depth_buffer_float) = !_glewInit_GL_NV_depth_buffer_float(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_depth_buffer_float */ +#ifdef GL_NV_depth_clamp + CONST_CAST(GLEW_NV_depth_clamp) = glewGetExtension("GL_NV_depth_clamp"); +#endif /* GL_NV_depth_clamp */ +#ifdef GL_NV_depth_range_unclamped + CONST_CAST(GLEW_NV_depth_range_unclamped) = glewGetExtension("GL_NV_depth_range_unclamped"); +#endif /* GL_NV_depth_range_unclamped */ +#ifdef GL_NV_evaluators + CONST_CAST(GLEW_NV_evaluators) = glewGetExtension("GL_NV_evaluators"); + if (glewExperimental || GLEW_NV_evaluators) CONST_CAST(GLEW_NV_evaluators) = !_glewInit_GL_NV_evaluators(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_evaluators */ +#ifdef GL_NV_explicit_multisample + CONST_CAST(GLEW_NV_explicit_multisample) = glewGetExtension("GL_NV_explicit_multisample"); + if (glewExperimental || GLEW_NV_explicit_multisample) CONST_CAST(GLEW_NV_explicit_multisample) = !_glewInit_GL_NV_explicit_multisample(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_explicit_multisample */ +#ifdef GL_NV_fence + CONST_CAST(GLEW_NV_fence) = glewGetExtension("GL_NV_fence"); + if (glewExperimental || GLEW_NV_fence) CONST_CAST(GLEW_NV_fence) = !_glewInit_GL_NV_fence(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_fence */ +#ifdef GL_NV_float_buffer + CONST_CAST(GLEW_NV_float_buffer) = glewGetExtension("GL_NV_float_buffer"); +#endif /* GL_NV_float_buffer */ +#ifdef GL_NV_fog_distance + CONST_CAST(GLEW_NV_fog_distance) = glewGetExtension("GL_NV_fog_distance"); +#endif /* GL_NV_fog_distance */ +#ifdef GL_NV_fragment_program + CONST_CAST(GLEW_NV_fragment_program) = glewGetExtension("GL_NV_fragment_program"); + if (glewExperimental || GLEW_NV_fragment_program) CONST_CAST(GLEW_NV_fragment_program) = !_glewInit_GL_NV_fragment_program(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_fragment_program */ +#ifdef GL_NV_fragment_program2 + CONST_CAST(GLEW_NV_fragment_program2) = glewGetExtension("GL_NV_fragment_program2"); +#endif /* GL_NV_fragment_program2 */ +#ifdef GL_NV_fragment_program4 + CONST_CAST(GLEW_NV_fragment_program4) = glewGetExtension("GL_NV_fragment_program4"); +#endif /* GL_NV_fragment_program4 */ +#ifdef GL_NV_fragment_program_option + CONST_CAST(GLEW_NV_fragment_program_option) = glewGetExtension("GL_NV_fragment_program_option"); +#endif /* GL_NV_fragment_program_option */ +#ifdef GL_NV_framebuffer_multisample_coverage + CONST_CAST(GLEW_NV_framebuffer_multisample_coverage) = glewGetExtension("GL_NV_framebuffer_multisample_coverage"); + if (glewExperimental || GLEW_NV_framebuffer_multisample_coverage) CONST_CAST(GLEW_NV_framebuffer_multisample_coverage) = !_glewInit_GL_NV_framebuffer_multisample_coverage(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_framebuffer_multisample_coverage */ +#ifdef GL_NV_geometry_program4 + CONST_CAST(GLEW_NV_geometry_program4) = glewGetExtension("GL_NV_geometry_program4"); + if (glewExperimental || GLEW_NV_geometry_program4) CONST_CAST(GLEW_NV_geometry_program4) = !_glewInit_GL_NV_geometry_program4(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_geometry_program4 */ +#ifdef GL_NV_geometry_shader4 + CONST_CAST(GLEW_NV_geometry_shader4) = glewGetExtension("GL_NV_geometry_shader4"); +#endif /* GL_NV_geometry_shader4 */ +#ifdef GL_NV_gpu_program4 + CONST_CAST(GLEW_NV_gpu_program4) = glewGetExtension("GL_NV_gpu_program4"); + if (glewExperimental || GLEW_NV_gpu_program4) CONST_CAST(GLEW_NV_gpu_program4) = !_glewInit_GL_NV_gpu_program4(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_gpu_program4 */ +#ifdef GL_NV_half_float + CONST_CAST(GLEW_NV_half_float) = glewGetExtension("GL_NV_half_float"); + if (glewExperimental || GLEW_NV_half_float) CONST_CAST(GLEW_NV_half_float) = !_glewInit_GL_NV_half_float(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_half_float */ +#ifdef GL_NV_light_max_exponent + CONST_CAST(GLEW_NV_light_max_exponent) = glewGetExtension("GL_NV_light_max_exponent"); +#endif /* GL_NV_light_max_exponent */ +#ifdef GL_NV_multisample_filter_hint + CONST_CAST(GLEW_NV_multisample_filter_hint) = glewGetExtension("GL_NV_multisample_filter_hint"); +#endif /* GL_NV_multisample_filter_hint */ +#ifdef GL_NV_occlusion_query + CONST_CAST(GLEW_NV_occlusion_query) = glewGetExtension("GL_NV_occlusion_query"); + if (glewExperimental || GLEW_NV_occlusion_query) CONST_CAST(GLEW_NV_occlusion_query) = !_glewInit_GL_NV_occlusion_query(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_occlusion_query */ +#ifdef GL_NV_packed_depth_stencil + CONST_CAST(GLEW_NV_packed_depth_stencil) = glewGetExtension("GL_NV_packed_depth_stencil"); +#endif /* GL_NV_packed_depth_stencil */ +#ifdef GL_NV_parameter_buffer_object + CONST_CAST(GLEW_NV_parameter_buffer_object) = glewGetExtension("GL_NV_parameter_buffer_object"); + if (glewExperimental || GLEW_NV_parameter_buffer_object) CONST_CAST(GLEW_NV_parameter_buffer_object) = !_glewInit_GL_NV_parameter_buffer_object(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_parameter_buffer_object */ +#ifdef GL_NV_pixel_data_range + CONST_CAST(GLEW_NV_pixel_data_range) = glewGetExtension("GL_NV_pixel_data_range"); + if (glewExperimental || GLEW_NV_pixel_data_range) CONST_CAST(GLEW_NV_pixel_data_range) = !_glewInit_GL_NV_pixel_data_range(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_pixel_data_range */ +#ifdef GL_NV_point_sprite + CONST_CAST(GLEW_NV_point_sprite) = glewGetExtension("GL_NV_point_sprite"); + if (glewExperimental || GLEW_NV_point_sprite) CONST_CAST(GLEW_NV_point_sprite) = !_glewInit_GL_NV_point_sprite(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_point_sprite */ +#ifdef GL_NV_present_video + CONST_CAST(GLEW_NV_present_video) = glewGetExtension("GL_NV_present_video"); + if (glewExperimental || GLEW_NV_present_video) CONST_CAST(GLEW_NV_present_video) = !_glewInit_GL_NV_present_video(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_present_video */ +#ifdef GL_NV_primitive_restart + CONST_CAST(GLEW_NV_primitive_restart) = glewGetExtension("GL_NV_primitive_restart"); + if (glewExperimental || GLEW_NV_primitive_restart) CONST_CAST(GLEW_NV_primitive_restart) = !_glewInit_GL_NV_primitive_restart(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_primitive_restart */ +#ifdef GL_NV_register_combiners + CONST_CAST(GLEW_NV_register_combiners) = glewGetExtension("GL_NV_register_combiners"); + if (glewExperimental || GLEW_NV_register_combiners) CONST_CAST(GLEW_NV_register_combiners) = !_glewInit_GL_NV_register_combiners(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_register_combiners */ +#ifdef GL_NV_register_combiners2 + CONST_CAST(GLEW_NV_register_combiners2) = glewGetExtension("GL_NV_register_combiners2"); + if (glewExperimental || GLEW_NV_register_combiners2) CONST_CAST(GLEW_NV_register_combiners2) = !_glewInit_GL_NV_register_combiners2(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_register_combiners2 */ +#ifdef GL_NV_texgen_emboss + CONST_CAST(GLEW_NV_texgen_emboss) = glewGetExtension("GL_NV_texgen_emboss"); +#endif /* GL_NV_texgen_emboss */ +#ifdef GL_NV_texgen_reflection + CONST_CAST(GLEW_NV_texgen_reflection) = glewGetExtension("GL_NV_texgen_reflection"); +#endif /* GL_NV_texgen_reflection */ +#ifdef GL_NV_texture_compression_vtc + CONST_CAST(GLEW_NV_texture_compression_vtc) = glewGetExtension("GL_NV_texture_compression_vtc"); +#endif /* GL_NV_texture_compression_vtc */ +#ifdef GL_NV_texture_env_combine4 + CONST_CAST(GLEW_NV_texture_env_combine4) = glewGetExtension("GL_NV_texture_env_combine4"); +#endif /* GL_NV_texture_env_combine4 */ +#ifdef GL_NV_texture_expand_normal + CONST_CAST(GLEW_NV_texture_expand_normal) = glewGetExtension("GL_NV_texture_expand_normal"); +#endif /* GL_NV_texture_expand_normal */ +#ifdef GL_NV_texture_rectangle + CONST_CAST(GLEW_NV_texture_rectangle) = glewGetExtension("GL_NV_texture_rectangle"); +#endif /* GL_NV_texture_rectangle */ +#ifdef GL_NV_texture_shader + CONST_CAST(GLEW_NV_texture_shader) = glewGetExtension("GL_NV_texture_shader"); +#endif /* GL_NV_texture_shader */ +#ifdef GL_NV_texture_shader2 + CONST_CAST(GLEW_NV_texture_shader2) = glewGetExtension("GL_NV_texture_shader2"); +#endif /* GL_NV_texture_shader2 */ +#ifdef GL_NV_texture_shader3 + CONST_CAST(GLEW_NV_texture_shader3) = glewGetExtension("GL_NV_texture_shader3"); +#endif /* GL_NV_texture_shader3 */ +#ifdef GL_NV_transform_feedback + CONST_CAST(GLEW_NV_transform_feedback) = glewGetExtension("GL_NV_transform_feedback"); + if (glewExperimental || GLEW_NV_transform_feedback) CONST_CAST(GLEW_NV_transform_feedback) = !_glewInit_GL_NV_transform_feedback(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_transform_feedback */ +#ifdef GL_NV_vertex_array_range + CONST_CAST(GLEW_NV_vertex_array_range) = glewGetExtension("GL_NV_vertex_array_range"); + if (glewExperimental || GLEW_NV_vertex_array_range) CONST_CAST(GLEW_NV_vertex_array_range) = !_glewInit_GL_NV_vertex_array_range(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_vertex_array_range */ +#ifdef GL_NV_vertex_array_range2 + CONST_CAST(GLEW_NV_vertex_array_range2) = glewGetExtension("GL_NV_vertex_array_range2"); +#endif /* GL_NV_vertex_array_range2 */ +#ifdef GL_NV_vertex_program + CONST_CAST(GLEW_NV_vertex_program) = glewGetExtension("GL_NV_vertex_program"); + if (glewExperimental || GLEW_NV_vertex_program) CONST_CAST(GLEW_NV_vertex_program) = !_glewInit_GL_NV_vertex_program(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_vertex_program */ +#ifdef GL_NV_vertex_program1_1 + CONST_CAST(GLEW_NV_vertex_program1_1) = glewGetExtension("GL_NV_vertex_program1_1"); +#endif /* GL_NV_vertex_program1_1 */ +#ifdef GL_NV_vertex_program2 + CONST_CAST(GLEW_NV_vertex_program2) = glewGetExtension("GL_NV_vertex_program2"); +#endif /* GL_NV_vertex_program2 */ +#ifdef GL_NV_vertex_program2_option + CONST_CAST(GLEW_NV_vertex_program2_option) = glewGetExtension("GL_NV_vertex_program2_option"); +#endif /* GL_NV_vertex_program2_option */ +#ifdef GL_NV_vertex_program3 + CONST_CAST(GLEW_NV_vertex_program3) = glewGetExtension("GL_NV_vertex_program3"); +#endif /* GL_NV_vertex_program3 */ +#ifdef GL_NV_vertex_program4 + CONST_CAST(GLEW_NV_vertex_program4) = glewGetExtension("GL_NV_vertex_program4"); +#endif /* GL_NV_vertex_program4 */ +#ifdef GL_OES_byte_coordinates + CONST_CAST(GLEW_OES_byte_coordinates) = glewGetExtension("GL_OES_byte_coordinates"); +#endif /* GL_OES_byte_coordinates */ +#ifdef GL_OES_compressed_paletted_texture + CONST_CAST(GLEW_OES_compressed_paletted_texture) = glewGetExtension("GL_OES_compressed_paletted_texture"); +#endif /* GL_OES_compressed_paletted_texture */ +#ifdef GL_OES_read_format + CONST_CAST(GLEW_OES_read_format) = glewGetExtension("GL_OES_read_format"); +#endif /* GL_OES_read_format */ +#ifdef GL_OES_single_precision + CONST_CAST(GLEW_OES_single_precision) = glewGetExtension("GL_OES_single_precision"); + if (glewExperimental || GLEW_OES_single_precision) CONST_CAST(GLEW_OES_single_precision) = !_glewInit_GL_OES_single_precision(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_OES_single_precision */ +#ifdef GL_OML_interlace + CONST_CAST(GLEW_OML_interlace) = glewGetExtension("GL_OML_interlace"); +#endif /* GL_OML_interlace */ +#ifdef GL_OML_resample + CONST_CAST(GLEW_OML_resample) = glewGetExtension("GL_OML_resample"); +#endif /* GL_OML_resample */ +#ifdef GL_OML_subsample + CONST_CAST(GLEW_OML_subsample) = glewGetExtension("GL_OML_subsample"); +#endif /* GL_OML_subsample */ +#ifdef GL_PGI_misc_hints + CONST_CAST(GLEW_PGI_misc_hints) = glewGetExtension("GL_PGI_misc_hints"); +#endif /* GL_PGI_misc_hints */ +#ifdef GL_PGI_vertex_hints + CONST_CAST(GLEW_PGI_vertex_hints) = glewGetExtension("GL_PGI_vertex_hints"); +#endif /* GL_PGI_vertex_hints */ +#ifdef GL_REND_screen_coordinates + CONST_CAST(GLEW_REND_screen_coordinates) = glewGetExtension("GL_REND_screen_coordinates"); +#endif /* GL_REND_screen_coordinates */ +#ifdef GL_S3_s3tc + CONST_CAST(GLEW_S3_s3tc) = glewGetExtension("GL_S3_s3tc"); +#endif /* GL_S3_s3tc */ +#ifdef GL_SGIS_color_range + CONST_CAST(GLEW_SGIS_color_range) = glewGetExtension("GL_SGIS_color_range"); +#endif /* GL_SGIS_color_range */ +#ifdef GL_SGIS_detail_texture + CONST_CAST(GLEW_SGIS_detail_texture) = glewGetExtension("GL_SGIS_detail_texture"); + if (glewExperimental || GLEW_SGIS_detail_texture) CONST_CAST(GLEW_SGIS_detail_texture) = !_glewInit_GL_SGIS_detail_texture(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIS_detail_texture */ +#ifdef GL_SGIS_fog_function + CONST_CAST(GLEW_SGIS_fog_function) = glewGetExtension("GL_SGIS_fog_function"); + if (glewExperimental || GLEW_SGIS_fog_function) CONST_CAST(GLEW_SGIS_fog_function) = !_glewInit_GL_SGIS_fog_function(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIS_fog_function */ +#ifdef GL_SGIS_generate_mipmap + CONST_CAST(GLEW_SGIS_generate_mipmap) = glewGetExtension("GL_SGIS_generate_mipmap"); +#endif /* GL_SGIS_generate_mipmap */ +#ifdef GL_SGIS_multisample + CONST_CAST(GLEW_SGIS_multisample) = glewGetExtension("GL_SGIS_multisample"); + if (glewExperimental || GLEW_SGIS_multisample) CONST_CAST(GLEW_SGIS_multisample) = !_glewInit_GL_SGIS_multisample(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIS_multisample */ +#ifdef GL_SGIS_pixel_texture + CONST_CAST(GLEW_SGIS_pixel_texture) = glewGetExtension("GL_SGIS_pixel_texture"); +#endif /* GL_SGIS_pixel_texture */ +#ifdef GL_SGIS_point_line_texgen + CONST_CAST(GLEW_SGIS_point_line_texgen) = glewGetExtension("GL_SGIS_point_line_texgen"); +#endif /* GL_SGIS_point_line_texgen */ +#ifdef GL_SGIS_sharpen_texture + CONST_CAST(GLEW_SGIS_sharpen_texture) = glewGetExtension("GL_SGIS_sharpen_texture"); + if (glewExperimental || GLEW_SGIS_sharpen_texture) CONST_CAST(GLEW_SGIS_sharpen_texture) = !_glewInit_GL_SGIS_sharpen_texture(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIS_sharpen_texture */ +#ifdef GL_SGIS_texture4D + CONST_CAST(GLEW_SGIS_texture4D) = glewGetExtension("GL_SGIS_texture4D"); + if (glewExperimental || GLEW_SGIS_texture4D) CONST_CAST(GLEW_SGIS_texture4D) = !_glewInit_GL_SGIS_texture4D(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIS_texture4D */ +#ifdef GL_SGIS_texture_border_clamp + CONST_CAST(GLEW_SGIS_texture_border_clamp) = glewGetExtension("GL_SGIS_texture_border_clamp"); +#endif /* GL_SGIS_texture_border_clamp */ +#ifdef GL_SGIS_texture_edge_clamp + CONST_CAST(GLEW_SGIS_texture_edge_clamp) = glewGetExtension("GL_SGIS_texture_edge_clamp"); +#endif /* GL_SGIS_texture_edge_clamp */ +#ifdef GL_SGIS_texture_filter4 + CONST_CAST(GLEW_SGIS_texture_filter4) = glewGetExtension("GL_SGIS_texture_filter4"); + if (glewExperimental || GLEW_SGIS_texture_filter4) CONST_CAST(GLEW_SGIS_texture_filter4) = !_glewInit_GL_SGIS_texture_filter4(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIS_texture_filter4 */ +#ifdef GL_SGIS_texture_lod + CONST_CAST(GLEW_SGIS_texture_lod) = glewGetExtension("GL_SGIS_texture_lod"); +#endif /* GL_SGIS_texture_lod */ +#ifdef GL_SGIS_texture_select + CONST_CAST(GLEW_SGIS_texture_select) = glewGetExtension("GL_SGIS_texture_select"); +#endif /* GL_SGIS_texture_select */ +#ifdef GL_SGIX_async + CONST_CAST(GLEW_SGIX_async) = glewGetExtension("GL_SGIX_async"); + if (glewExperimental || GLEW_SGIX_async) CONST_CAST(GLEW_SGIX_async) = !_glewInit_GL_SGIX_async(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIX_async */ +#ifdef GL_SGIX_async_histogram + CONST_CAST(GLEW_SGIX_async_histogram) = glewGetExtension("GL_SGIX_async_histogram"); +#endif /* GL_SGIX_async_histogram */ +#ifdef GL_SGIX_async_pixel + CONST_CAST(GLEW_SGIX_async_pixel) = glewGetExtension("GL_SGIX_async_pixel"); +#endif /* GL_SGIX_async_pixel */ +#ifdef GL_SGIX_blend_alpha_minmax + CONST_CAST(GLEW_SGIX_blend_alpha_minmax) = glewGetExtension("GL_SGIX_blend_alpha_minmax"); +#endif /* GL_SGIX_blend_alpha_minmax */ +#ifdef GL_SGIX_clipmap + CONST_CAST(GLEW_SGIX_clipmap) = glewGetExtension("GL_SGIX_clipmap"); +#endif /* GL_SGIX_clipmap */ +#ifdef GL_SGIX_convolution_accuracy + CONST_CAST(GLEW_SGIX_convolution_accuracy) = glewGetExtension("GL_SGIX_convolution_accuracy"); +#endif /* GL_SGIX_convolution_accuracy */ +#ifdef GL_SGIX_depth_texture + CONST_CAST(GLEW_SGIX_depth_texture) = glewGetExtension("GL_SGIX_depth_texture"); +#endif /* GL_SGIX_depth_texture */ +#ifdef GL_SGIX_flush_raster + CONST_CAST(GLEW_SGIX_flush_raster) = glewGetExtension("GL_SGIX_flush_raster"); + if (glewExperimental || GLEW_SGIX_flush_raster) CONST_CAST(GLEW_SGIX_flush_raster) = !_glewInit_GL_SGIX_flush_raster(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIX_flush_raster */ +#ifdef GL_SGIX_fog_offset + CONST_CAST(GLEW_SGIX_fog_offset) = glewGetExtension("GL_SGIX_fog_offset"); +#endif /* GL_SGIX_fog_offset */ +#ifdef GL_SGIX_fog_texture + CONST_CAST(GLEW_SGIX_fog_texture) = glewGetExtension("GL_SGIX_fog_texture"); + if (glewExperimental || GLEW_SGIX_fog_texture) CONST_CAST(GLEW_SGIX_fog_texture) = !_glewInit_GL_SGIX_fog_texture(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIX_fog_texture */ +#ifdef GL_SGIX_fragment_specular_lighting + CONST_CAST(GLEW_SGIX_fragment_specular_lighting) = glewGetExtension("GL_SGIX_fragment_specular_lighting"); + if (glewExperimental || GLEW_SGIX_fragment_specular_lighting) CONST_CAST(GLEW_SGIX_fragment_specular_lighting) = !_glewInit_GL_SGIX_fragment_specular_lighting(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIX_fragment_specular_lighting */ +#ifdef GL_SGIX_framezoom + CONST_CAST(GLEW_SGIX_framezoom) = glewGetExtension("GL_SGIX_framezoom"); + if (glewExperimental || GLEW_SGIX_framezoom) CONST_CAST(GLEW_SGIX_framezoom) = !_glewInit_GL_SGIX_framezoom(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIX_framezoom */ +#ifdef GL_SGIX_interlace + CONST_CAST(GLEW_SGIX_interlace) = glewGetExtension("GL_SGIX_interlace"); +#endif /* GL_SGIX_interlace */ +#ifdef GL_SGIX_ir_instrument1 + CONST_CAST(GLEW_SGIX_ir_instrument1) = glewGetExtension("GL_SGIX_ir_instrument1"); +#endif /* GL_SGIX_ir_instrument1 */ +#ifdef GL_SGIX_list_priority + CONST_CAST(GLEW_SGIX_list_priority) = glewGetExtension("GL_SGIX_list_priority"); +#endif /* GL_SGIX_list_priority */ +#ifdef GL_SGIX_pixel_texture + CONST_CAST(GLEW_SGIX_pixel_texture) = glewGetExtension("GL_SGIX_pixel_texture"); + if (glewExperimental || GLEW_SGIX_pixel_texture) CONST_CAST(GLEW_SGIX_pixel_texture) = !_glewInit_GL_SGIX_pixel_texture(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIX_pixel_texture */ +#ifdef GL_SGIX_pixel_texture_bits + CONST_CAST(GLEW_SGIX_pixel_texture_bits) = glewGetExtension("GL_SGIX_pixel_texture_bits"); +#endif /* GL_SGIX_pixel_texture_bits */ +#ifdef GL_SGIX_reference_plane + CONST_CAST(GLEW_SGIX_reference_plane) = glewGetExtension("GL_SGIX_reference_plane"); + if (glewExperimental || GLEW_SGIX_reference_plane) CONST_CAST(GLEW_SGIX_reference_plane) = !_glewInit_GL_SGIX_reference_plane(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIX_reference_plane */ +#ifdef GL_SGIX_resample + CONST_CAST(GLEW_SGIX_resample) = glewGetExtension("GL_SGIX_resample"); +#endif /* GL_SGIX_resample */ +#ifdef GL_SGIX_shadow + CONST_CAST(GLEW_SGIX_shadow) = glewGetExtension("GL_SGIX_shadow"); +#endif /* GL_SGIX_shadow */ +#ifdef GL_SGIX_shadow_ambient + CONST_CAST(GLEW_SGIX_shadow_ambient) = glewGetExtension("GL_SGIX_shadow_ambient"); +#endif /* GL_SGIX_shadow_ambient */ +#ifdef GL_SGIX_sprite + CONST_CAST(GLEW_SGIX_sprite) = glewGetExtension("GL_SGIX_sprite"); + if (glewExperimental || GLEW_SGIX_sprite) CONST_CAST(GLEW_SGIX_sprite) = !_glewInit_GL_SGIX_sprite(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIX_sprite */ +#ifdef GL_SGIX_tag_sample_buffer + CONST_CAST(GLEW_SGIX_tag_sample_buffer) = glewGetExtension("GL_SGIX_tag_sample_buffer"); + if (glewExperimental || GLEW_SGIX_tag_sample_buffer) CONST_CAST(GLEW_SGIX_tag_sample_buffer) = !_glewInit_GL_SGIX_tag_sample_buffer(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIX_tag_sample_buffer */ +#ifdef GL_SGIX_texture_add_env + CONST_CAST(GLEW_SGIX_texture_add_env) = glewGetExtension("GL_SGIX_texture_add_env"); +#endif /* GL_SGIX_texture_add_env */ +#ifdef GL_SGIX_texture_coordinate_clamp + CONST_CAST(GLEW_SGIX_texture_coordinate_clamp) = glewGetExtension("GL_SGIX_texture_coordinate_clamp"); +#endif /* GL_SGIX_texture_coordinate_clamp */ +#ifdef GL_SGIX_texture_lod_bias + CONST_CAST(GLEW_SGIX_texture_lod_bias) = glewGetExtension("GL_SGIX_texture_lod_bias"); +#endif /* GL_SGIX_texture_lod_bias */ +#ifdef GL_SGIX_texture_multi_buffer + CONST_CAST(GLEW_SGIX_texture_multi_buffer) = glewGetExtension("GL_SGIX_texture_multi_buffer"); +#endif /* GL_SGIX_texture_multi_buffer */ +#ifdef GL_SGIX_texture_range + CONST_CAST(GLEW_SGIX_texture_range) = glewGetExtension("GL_SGIX_texture_range"); +#endif /* GL_SGIX_texture_range */ +#ifdef GL_SGIX_texture_scale_bias + CONST_CAST(GLEW_SGIX_texture_scale_bias) = glewGetExtension("GL_SGIX_texture_scale_bias"); +#endif /* GL_SGIX_texture_scale_bias */ +#ifdef GL_SGIX_vertex_preclip + CONST_CAST(GLEW_SGIX_vertex_preclip) = glewGetExtension("GL_SGIX_vertex_preclip"); +#endif /* GL_SGIX_vertex_preclip */ +#ifdef GL_SGIX_vertex_preclip_hint + CONST_CAST(GLEW_SGIX_vertex_preclip_hint) = glewGetExtension("GL_SGIX_vertex_preclip_hint"); +#endif /* GL_SGIX_vertex_preclip_hint */ +#ifdef GL_SGIX_ycrcb + CONST_CAST(GLEW_SGIX_ycrcb) = glewGetExtension("GL_SGIX_ycrcb"); +#endif /* GL_SGIX_ycrcb */ +#ifdef GL_SGI_color_matrix + CONST_CAST(GLEW_SGI_color_matrix) = glewGetExtension("GL_SGI_color_matrix"); +#endif /* GL_SGI_color_matrix */ +#ifdef GL_SGI_color_table + CONST_CAST(GLEW_SGI_color_table) = glewGetExtension("GL_SGI_color_table"); + if (glewExperimental || GLEW_SGI_color_table) CONST_CAST(GLEW_SGI_color_table) = !_glewInit_GL_SGI_color_table(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGI_color_table */ +#ifdef GL_SGI_texture_color_table + CONST_CAST(GLEW_SGI_texture_color_table) = glewGetExtension("GL_SGI_texture_color_table"); +#endif /* GL_SGI_texture_color_table */ +#ifdef GL_SUNX_constant_data + CONST_CAST(GLEW_SUNX_constant_data) = glewGetExtension("GL_SUNX_constant_data"); + if (glewExperimental || GLEW_SUNX_constant_data) CONST_CAST(GLEW_SUNX_constant_data) = !_glewInit_GL_SUNX_constant_data(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SUNX_constant_data */ +#ifdef GL_SUN_convolution_border_modes + CONST_CAST(GLEW_SUN_convolution_border_modes) = glewGetExtension("GL_SUN_convolution_border_modes"); +#endif /* GL_SUN_convolution_border_modes */ +#ifdef GL_SUN_global_alpha + CONST_CAST(GLEW_SUN_global_alpha) = glewGetExtension("GL_SUN_global_alpha"); + if (glewExperimental || GLEW_SUN_global_alpha) CONST_CAST(GLEW_SUN_global_alpha) = !_glewInit_GL_SUN_global_alpha(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SUN_global_alpha */ +#ifdef GL_SUN_mesh_array + CONST_CAST(GLEW_SUN_mesh_array) = glewGetExtension("GL_SUN_mesh_array"); +#endif /* GL_SUN_mesh_array */ +#ifdef GL_SUN_read_video_pixels + CONST_CAST(GLEW_SUN_read_video_pixels) = glewGetExtension("GL_SUN_read_video_pixels"); + if (glewExperimental || GLEW_SUN_read_video_pixels) CONST_CAST(GLEW_SUN_read_video_pixels) = !_glewInit_GL_SUN_read_video_pixels(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SUN_read_video_pixels */ +#ifdef GL_SUN_slice_accum + CONST_CAST(GLEW_SUN_slice_accum) = glewGetExtension("GL_SUN_slice_accum"); +#endif /* GL_SUN_slice_accum */ +#ifdef GL_SUN_triangle_list + CONST_CAST(GLEW_SUN_triangle_list) = glewGetExtension("GL_SUN_triangle_list"); + if (glewExperimental || GLEW_SUN_triangle_list) CONST_CAST(GLEW_SUN_triangle_list) = !_glewInit_GL_SUN_triangle_list(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SUN_triangle_list */ +#ifdef GL_SUN_vertex + CONST_CAST(GLEW_SUN_vertex) = glewGetExtension("GL_SUN_vertex"); + if (glewExperimental || GLEW_SUN_vertex) CONST_CAST(GLEW_SUN_vertex) = !_glewInit_GL_SUN_vertex(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SUN_vertex */ +#ifdef GL_WIN_phong_shading + CONST_CAST(GLEW_WIN_phong_shading) = glewGetExtension("GL_WIN_phong_shading"); +#endif /* GL_WIN_phong_shading */ +#ifdef GL_WIN_specular_fog + CONST_CAST(GLEW_WIN_specular_fog) = glewGetExtension("GL_WIN_specular_fog"); +#endif /* GL_WIN_specular_fog */ +#ifdef GL_WIN_swap_hint + CONST_CAST(GLEW_WIN_swap_hint) = glewGetExtension("GL_WIN_swap_hint"); + if (glewExperimental || GLEW_WIN_swap_hint) CONST_CAST(GLEW_WIN_swap_hint) = !_glewInit_GL_WIN_swap_hint(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_WIN_swap_hint */ + + return GLEW_OK; +} + + +#if defined(_WIN32) + +#if !defined(GLEW_MX) + +PFNWGLSETSTEREOEMITTERSTATE3DLPROC __wglewSetStereoEmitterState3DL = NULL; + +PFNWGLCREATEBUFFERREGIONARBPROC __wglewCreateBufferRegionARB = NULL; +PFNWGLDELETEBUFFERREGIONARBPROC __wglewDeleteBufferRegionARB = NULL; +PFNWGLRESTOREBUFFERREGIONARBPROC __wglewRestoreBufferRegionARB = NULL; +PFNWGLSAVEBUFFERREGIONARBPROC __wglewSaveBufferRegionARB = NULL; + +PFNWGLCREATECONTEXTATTRIBSARBPROC __wglewCreateContextAttribsARB = NULL; + +PFNWGLGETEXTENSIONSSTRINGARBPROC __wglewGetExtensionsStringARB = NULL; + +PFNWGLGETCURRENTREADDCARBPROC __wglewGetCurrentReadDCARB = NULL; +PFNWGLMAKECONTEXTCURRENTARBPROC __wglewMakeContextCurrentARB = NULL; + +PFNWGLCREATEPBUFFERARBPROC __wglewCreatePbufferARB = NULL; +PFNWGLDESTROYPBUFFERARBPROC __wglewDestroyPbufferARB = NULL; +PFNWGLGETPBUFFERDCARBPROC __wglewGetPbufferDCARB = NULL; +PFNWGLQUERYPBUFFERARBPROC __wglewQueryPbufferARB = NULL; +PFNWGLRELEASEPBUFFERDCARBPROC __wglewReleasePbufferDCARB = NULL; + +PFNWGLCHOOSEPIXELFORMATARBPROC __wglewChoosePixelFormatARB = NULL; +PFNWGLGETPIXELFORMATATTRIBFVARBPROC __wglewGetPixelFormatAttribfvARB = NULL; +PFNWGLGETPIXELFORMATATTRIBIVARBPROC __wglewGetPixelFormatAttribivARB = NULL; + +PFNWGLBINDTEXIMAGEARBPROC __wglewBindTexImageARB = NULL; +PFNWGLRELEASETEXIMAGEARBPROC __wglewReleaseTexImageARB = NULL; +PFNWGLSETPBUFFERATTRIBARBPROC __wglewSetPbufferAttribARB = NULL; + +PFNWGLBINDDISPLAYCOLORTABLEEXTPROC __wglewBindDisplayColorTableEXT = NULL; +PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC __wglewCreateDisplayColorTableEXT = NULL; +PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC __wglewDestroyDisplayColorTableEXT = NULL; +PFNWGLLOADDISPLAYCOLORTABLEEXTPROC __wglewLoadDisplayColorTableEXT = NULL; + +PFNWGLGETEXTENSIONSSTRINGEXTPROC __wglewGetExtensionsStringEXT = NULL; + +PFNWGLGETCURRENTREADDCEXTPROC __wglewGetCurrentReadDCEXT = NULL; +PFNWGLMAKECONTEXTCURRENTEXTPROC __wglewMakeContextCurrentEXT = NULL; + +PFNWGLCREATEPBUFFEREXTPROC __wglewCreatePbufferEXT = NULL; +PFNWGLDESTROYPBUFFEREXTPROC __wglewDestroyPbufferEXT = NULL; +PFNWGLGETPBUFFERDCEXTPROC __wglewGetPbufferDCEXT = NULL; +PFNWGLQUERYPBUFFEREXTPROC __wglewQueryPbufferEXT = NULL; +PFNWGLRELEASEPBUFFERDCEXTPROC __wglewReleasePbufferDCEXT = NULL; + +PFNWGLCHOOSEPIXELFORMATEXTPROC __wglewChoosePixelFormatEXT = NULL; +PFNWGLGETPIXELFORMATATTRIBFVEXTPROC __wglewGetPixelFormatAttribfvEXT = NULL; +PFNWGLGETPIXELFORMATATTRIBIVEXTPROC __wglewGetPixelFormatAttribivEXT = NULL; + +PFNWGLGETSWAPINTERVALEXTPROC __wglewGetSwapIntervalEXT = NULL; +PFNWGLSWAPINTERVALEXTPROC __wglewSwapIntervalEXT = NULL; + +PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC __wglewGetDigitalVideoParametersI3D = NULL; +PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC __wglewSetDigitalVideoParametersI3D = NULL; + +PFNWGLGETGAMMATABLEI3DPROC __wglewGetGammaTableI3D = NULL; +PFNWGLGETGAMMATABLEPARAMETERSI3DPROC __wglewGetGammaTableParametersI3D = NULL; +PFNWGLSETGAMMATABLEI3DPROC __wglewSetGammaTableI3D = NULL; +PFNWGLSETGAMMATABLEPARAMETERSI3DPROC __wglewSetGammaTableParametersI3D = NULL; + +PFNWGLDISABLEGENLOCKI3DPROC __wglewDisableGenlockI3D = NULL; +PFNWGLENABLEGENLOCKI3DPROC __wglewEnableGenlockI3D = NULL; +PFNWGLGENLOCKSAMPLERATEI3DPROC __wglewGenlockSampleRateI3D = NULL; +PFNWGLGENLOCKSOURCEDELAYI3DPROC __wglewGenlockSourceDelayI3D = NULL; +PFNWGLGENLOCKSOURCEEDGEI3DPROC __wglewGenlockSourceEdgeI3D = NULL; +PFNWGLGENLOCKSOURCEI3DPROC __wglewGenlockSourceI3D = NULL; +PFNWGLGETGENLOCKSAMPLERATEI3DPROC __wglewGetGenlockSampleRateI3D = NULL; +PFNWGLGETGENLOCKSOURCEDELAYI3DPROC __wglewGetGenlockSourceDelayI3D = NULL; +PFNWGLGETGENLOCKSOURCEEDGEI3DPROC __wglewGetGenlockSourceEdgeI3D = NULL; +PFNWGLGETGENLOCKSOURCEI3DPROC __wglewGetGenlockSourceI3D = NULL; +PFNWGLISENABLEDGENLOCKI3DPROC __wglewIsEnabledGenlockI3D = NULL; +PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC __wglewQueryGenlockMaxSourceDelayI3D = NULL; + +PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC __wglewAssociateImageBufferEventsI3D = NULL; +PFNWGLCREATEIMAGEBUFFERI3DPROC __wglewCreateImageBufferI3D = NULL; +PFNWGLDESTROYIMAGEBUFFERI3DPROC __wglewDestroyImageBufferI3D = NULL; +PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC __wglewReleaseImageBufferEventsI3D = NULL; + +PFNWGLDISABLEFRAMELOCKI3DPROC __wglewDisableFrameLockI3D = NULL; +PFNWGLENABLEFRAMELOCKI3DPROC __wglewEnableFrameLockI3D = NULL; +PFNWGLISENABLEDFRAMELOCKI3DPROC __wglewIsEnabledFrameLockI3D = NULL; +PFNWGLQUERYFRAMELOCKMASTERI3DPROC __wglewQueryFrameLockMasterI3D = NULL; + +PFNWGLBEGINFRAMETRACKINGI3DPROC __wglewBeginFrameTrackingI3D = NULL; +PFNWGLENDFRAMETRACKINGI3DPROC __wglewEndFrameTrackingI3D = NULL; +PFNWGLGETFRAMEUSAGEI3DPROC __wglewGetFrameUsageI3D = NULL; +PFNWGLQUERYFRAMETRACKINGI3DPROC __wglewQueryFrameTrackingI3D = NULL; + +PFNWGLCREATEAFFINITYDCNVPROC __wglewCreateAffinityDCNV = NULL; +PFNWGLDELETEDCNVPROC __wglewDeleteDCNV = NULL; +PFNWGLENUMGPUDEVICESNVPROC __wglewEnumGpuDevicesNV = NULL; +PFNWGLENUMGPUSFROMAFFINITYDCNVPROC __wglewEnumGpusFromAffinityDCNV = NULL; +PFNWGLENUMGPUSNVPROC __wglewEnumGpusNV = NULL; + +PFNWGLBINDVIDEODEVICENVPROC __wglewBindVideoDeviceNV = NULL; +PFNWGLENUMERATEVIDEODEVICESNVPROC __wglewEnumerateVideoDevicesNV = NULL; +PFNWGLQUERYCURRENTCONTEXTNVPROC __wglewQueryCurrentContextNV = NULL; + +PFNWGLBINDSWAPBARRIERNVPROC __wglewBindSwapBarrierNV = NULL; +PFNWGLJOINSWAPGROUPNVPROC __wglewJoinSwapGroupNV = NULL; +PFNWGLQUERYFRAMECOUNTNVPROC __wglewQueryFrameCountNV = NULL; +PFNWGLQUERYMAXSWAPGROUPSNVPROC __wglewQueryMaxSwapGroupsNV = NULL; +PFNWGLQUERYSWAPGROUPNVPROC __wglewQuerySwapGroupNV = NULL; +PFNWGLRESETFRAMECOUNTNVPROC __wglewResetFrameCountNV = NULL; + +PFNWGLALLOCATEMEMORYNVPROC __wglewAllocateMemoryNV = NULL; +PFNWGLFREEMEMORYNVPROC __wglewFreeMemoryNV = NULL; + +PFNWGLBINDVIDEOIMAGENVPROC __wglewBindVideoImageNV = NULL; +PFNWGLGETVIDEODEVICENVPROC __wglewGetVideoDeviceNV = NULL; +PFNWGLGETVIDEOINFONVPROC __wglewGetVideoInfoNV = NULL; +PFNWGLRELEASEVIDEODEVICENVPROC __wglewReleaseVideoDeviceNV = NULL; +PFNWGLRELEASEVIDEOIMAGENVPROC __wglewReleaseVideoImageNV = NULL; +PFNWGLSENDPBUFFERTOVIDEONVPROC __wglewSendPbufferToVideoNV = NULL; + +PFNWGLGETMSCRATEOMLPROC __wglewGetMscRateOML = NULL; +PFNWGLGETSYNCVALUESOMLPROC __wglewGetSyncValuesOML = NULL; +PFNWGLSWAPBUFFERSMSCOMLPROC __wglewSwapBuffersMscOML = NULL; +PFNWGLSWAPLAYERBUFFERSMSCOMLPROC __wglewSwapLayerBuffersMscOML = NULL; +PFNWGLWAITFORMSCOMLPROC __wglewWaitForMscOML = NULL; +PFNWGLWAITFORSBCOMLPROC __wglewWaitForSbcOML = NULL; +GLboolean __WGLEW_3DFX_multisample = GL_FALSE; +GLboolean __WGLEW_3DL_stereo_control = GL_FALSE; +GLboolean __WGLEW_ARB_buffer_region = GL_FALSE; +GLboolean __WGLEW_ARB_create_context = GL_FALSE; +GLboolean __WGLEW_ARB_extensions_string = GL_FALSE; +GLboolean __WGLEW_ARB_framebuffer_sRGB = GL_FALSE; +GLboolean __WGLEW_ARB_make_current_read = GL_FALSE; +GLboolean __WGLEW_ARB_multisample = GL_FALSE; +GLboolean __WGLEW_ARB_pbuffer = GL_FALSE; +GLboolean __WGLEW_ARB_pixel_format = GL_FALSE; +GLboolean __WGLEW_ARB_pixel_format_float = GL_FALSE; +GLboolean __WGLEW_ARB_render_texture = GL_FALSE; +GLboolean __WGLEW_ATI_pixel_format_float = GL_FALSE; +GLboolean __WGLEW_ATI_render_texture_rectangle = GL_FALSE; +GLboolean __WGLEW_EXT_depth_float = GL_FALSE; +GLboolean __WGLEW_EXT_display_color_table = GL_FALSE; +GLboolean __WGLEW_EXT_extensions_string = GL_FALSE; +GLboolean __WGLEW_EXT_framebuffer_sRGB = GL_FALSE; +GLboolean __WGLEW_EXT_make_current_read = GL_FALSE; +GLboolean __WGLEW_EXT_multisample = GL_FALSE; +GLboolean __WGLEW_EXT_pbuffer = GL_FALSE; +GLboolean __WGLEW_EXT_pixel_format = GL_FALSE; +GLboolean __WGLEW_EXT_pixel_format_packed_float = GL_FALSE; +GLboolean __WGLEW_EXT_swap_control = GL_FALSE; +GLboolean __WGLEW_I3D_digital_video_control = GL_FALSE; +GLboolean __WGLEW_I3D_gamma = GL_FALSE; +GLboolean __WGLEW_I3D_genlock = GL_FALSE; +GLboolean __WGLEW_I3D_image_buffer = GL_FALSE; +GLboolean __WGLEW_I3D_swap_frame_lock = GL_FALSE; +GLboolean __WGLEW_I3D_swap_frame_usage = GL_FALSE; +GLboolean __WGLEW_NV_float_buffer = GL_FALSE; +GLboolean __WGLEW_NV_gpu_affinity = GL_FALSE; +GLboolean __WGLEW_NV_present_video = GL_FALSE; +GLboolean __WGLEW_NV_render_depth_texture = GL_FALSE; +GLboolean __WGLEW_NV_render_texture_rectangle = GL_FALSE; +GLboolean __WGLEW_NV_swap_group = GL_FALSE; +GLboolean __WGLEW_NV_vertex_array_range = GL_FALSE; +GLboolean __WGLEW_NV_video_output = GL_FALSE; +GLboolean __WGLEW_OML_sync_control = GL_FALSE; + +#endif /* !GLEW_MX */ + +#ifdef WGL_3DFX_multisample + +#endif /* WGL_3DFX_multisample */ + +#ifdef WGL_3DL_stereo_control + +static GLboolean _glewInit_WGL_3DL_stereo_control (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglSetStereoEmitterState3DL = (PFNWGLSETSTEREOEMITTERSTATE3DLPROC)glewGetProcAddress((const GLubyte*)"wglSetStereoEmitterState3DL")) == NULL) || r; + + return r; +} + +#endif /* WGL_3DL_stereo_control */ + +#ifdef WGL_ARB_buffer_region + +static GLboolean _glewInit_WGL_ARB_buffer_region (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglCreateBufferRegionARB = (PFNWGLCREATEBUFFERREGIONARBPROC)glewGetProcAddress((const GLubyte*)"wglCreateBufferRegionARB")) == NULL) || r; + r = ((wglDeleteBufferRegionARB = (PFNWGLDELETEBUFFERREGIONARBPROC)glewGetProcAddress((const GLubyte*)"wglDeleteBufferRegionARB")) == NULL) || r; + r = ((wglRestoreBufferRegionARB = (PFNWGLRESTOREBUFFERREGIONARBPROC)glewGetProcAddress((const GLubyte*)"wglRestoreBufferRegionARB")) == NULL) || r; + r = ((wglSaveBufferRegionARB = (PFNWGLSAVEBUFFERREGIONARBPROC)glewGetProcAddress((const GLubyte*)"wglSaveBufferRegionARB")) == NULL) || r; + + return r; +} + +#endif /* WGL_ARB_buffer_region */ + +#ifdef WGL_ARB_create_context + +static GLboolean _glewInit_WGL_ARB_create_context (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)glewGetProcAddress((const GLubyte*)"wglCreateContextAttribsARB")) == NULL) || r; + + return r; +} + +#endif /* WGL_ARB_create_context */ + +#ifdef WGL_ARB_extensions_string + +static GLboolean _glewInit_WGL_ARB_extensions_string (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)glewGetProcAddress((const GLubyte*)"wglGetExtensionsStringARB")) == NULL) || r; + + return r; +} + +#endif /* WGL_ARB_extensions_string */ + +#ifdef WGL_ARB_framebuffer_sRGB + +#endif /* WGL_ARB_framebuffer_sRGB */ + +#ifdef WGL_ARB_make_current_read + +static GLboolean _glewInit_WGL_ARB_make_current_read (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglGetCurrentReadDCARB = (PFNWGLGETCURRENTREADDCARBPROC)glewGetProcAddress((const GLubyte*)"wglGetCurrentReadDCARB")) == NULL) || r; + r = ((wglMakeContextCurrentARB = (PFNWGLMAKECONTEXTCURRENTARBPROC)glewGetProcAddress((const GLubyte*)"wglMakeContextCurrentARB")) == NULL) || r; + + return r; +} + +#endif /* WGL_ARB_make_current_read */ + +#ifdef WGL_ARB_multisample + +#endif /* WGL_ARB_multisample */ + +#ifdef WGL_ARB_pbuffer + +static GLboolean _glewInit_WGL_ARB_pbuffer (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglCreatePbufferARB = (PFNWGLCREATEPBUFFERARBPROC)glewGetProcAddress((const GLubyte*)"wglCreatePbufferARB")) == NULL) || r; + r = ((wglDestroyPbufferARB = (PFNWGLDESTROYPBUFFERARBPROC)glewGetProcAddress((const GLubyte*)"wglDestroyPbufferARB")) == NULL) || r; + r = ((wglGetPbufferDCARB = (PFNWGLGETPBUFFERDCARBPROC)glewGetProcAddress((const GLubyte*)"wglGetPbufferDCARB")) == NULL) || r; + r = ((wglQueryPbufferARB = (PFNWGLQUERYPBUFFERARBPROC)glewGetProcAddress((const GLubyte*)"wglQueryPbufferARB")) == NULL) || r; + r = ((wglReleasePbufferDCARB = (PFNWGLRELEASEPBUFFERDCARBPROC)glewGetProcAddress((const GLubyte*)"wglReleasePbufferDCARB")) == NULL) || r; + + return r; +} + +#endif /* WGL_ARB_pbuffer */ + +#ifdef WGL_ARB_pixel_format + +static GLboolean _glewInit_WGL_ARB_pixel_format (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)glewGetProcAddress((const GLubyte*)"wglChoosePixelFormatARB")) == NULL) || r; + r = ((wglGetPixelFormatAttribfvARB = (PFNWGLGETPIXELFORMATATTRIBFVARBPROC)glewGetProcAddress((const GLubyte*)"wglGetPixelFormatAttribfvARB")) == NULL) || r; + r = ((wglGetPixelFormatAttribivARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC)glewGetProcAddress((const GLubyte*)"wglGetPixelFormatAttribivARB")) == NULL) || r; + + return r; +} + +#endif /* WGL_ARB_pixel_format */ + +#ifdef WGL_ARB_pixel_format_float + +#endif /* WGL_ARB_pixel_format_float */ + +#ifdef WGL_ARB_render_texture + +static GLboolean _glewInit_WGL_ARB_render_texture (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglBindTexImageARB = (PFNWGLBINDTEXIMAGEARBPROC)glewGetProcAddress((const GLubyte*)"wglBindTexImageARB")) == NULL) || r; + r = ((wglReleaseTexImageARB = (PFNWGLRELEASETEXIMAGEARBPROC)glewGetProcAddress((const GLubyte*)"wglReleaseTexImageARB")) == NULL) || r; + r = ((wglSetPbufferAttribARB = (PFNWGLSETPBUFFERATTRIBARBPROC)glewGetProcAddress((const GLubyte*)"wglSetPbufferAttribARB")) == NULL) || r; + + return r; +} + +#endif /* WGL_ARB_render_texture */ + +#ifdef WGL_ATI_pixel_format_float + +#endif /* WGL_ATI_pixel_format_float */ + +#ifdef WGL_ATI_render_texture_rectangle + +#endif /* WGL_ATI_render_texture_rectangle */ + +#ifdef WGL_EXT_depth_float + +#endif /* WGL_EXT_depth_float */ + +#ifdef WGL_EXT_display_color_table + +static GLboolean _glewInit_WGL_EXT_display_color_table (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglBindDisplayColorTableEXT = (PFNWGLBINDDISPLAYCOLORTABLEEXTPROC)glewGetProcAddress((const GLubyte*)"wglBindDisplayColorTableEXT")) == NULL) || r; + r = ((wglCreateDisplayColorTableEXT = (PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC)glewGetProcAddress((const GLubyte*)"wglCreateDisplayColorTableEXT")) == NULL) || r; + r = ((wglDestroyDisplayColorTableEXT = (PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC)glewGetProcAddress((const GLubyte*)"wglDestroyDisplayColorTableEXT")) == NULL) || r; + r = ((wglLoadDisplayColorTableEXT = (PFNWGLLOADDISPLAYCOLORTABLEEXTPROC)glewGetProcAddress((const GLubyte*)"wglLoadDisplayColorTableEXT")) == NULL) || r; + + return r; +} + +#endif /* WGL_EXT_display_color_table */ + +#ifdef WGL_EXT_extensions_string + +static GLboolean _glewInit_WGL_EXT_extensions_string (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglGetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC)glewGetProcAddress((const GLubyte*)"wglGetExtensionsStringEXT")) == NULL) || r; + + return r; +} + +#endif /* WGL_EXT_extensions_string */ + +#ifdef WGL_EXT_framebuffer_sRGB + +#endif /* WGL_EXT_framebuffer_sRGB */ + +#ifdef WGL_EXT_make_current_read + +static GLboolean _glewInit_WGL_EXT_make_current_read (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglGetCurrentReadDCEXT = (PFNWGLGETCURRENTREADDCEXTPROC)glewGetProcAddress((const GLubyte*)"wglGetCurrentReadDCEXT")) == NULL) || r; + r = ((wglMakeContextCurrentEXT = (PFNWGLMAKECONTEXTCURRENTEXTPROC)glewGetProcAddress((const GLubyte*)"wglMakeContextCurrentEXT")) == NULL) || r; + + return r; +} + +#endif /* WGL_EXT_make_current_read */ + +#ifdef WGL_EXT_multisample + +#endif /* WGL_EXT_multisample */ + +#ifdef WGL_EXT_pbuffer + +static GLboolean _glewInit_WGL_EXT_pbuffer (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglCreatePbufferEXT = (PFNWGLCREATEPBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"wglCreatePbufferEXT")) == NULL) || r; + r = ((wglDestroyPbufferEXT = (PFNWGLDESTROYPBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"wglDestroyPbufferEXT")) == NULL) || r; + r = ((wglGetPbufferDCEXT = (PFNWGLGETPBUFFERDCEXTPROC)glewGetProcAddress((const GLubyte*)"wglGetPbufferDCEXT")) == NULL) || r; + r = ((wglQueryPbufferEXT = (PFNWGLQUERYPBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"wglQueryPbufferEXT")) == NULL) || r; + r = ((wglReleasePbufferDCEXT = (PFNWGLRELEASEPBUFFERDCEXTPROC)glewGetProcAddress((const GLubyte*)"wglReleasePbufferDCEXT")) == NULL) || r; + + return r; +} + +#endif /* WGL_EXT_pbuffer */ + +#ifdef WGL_EXT_pixel_format + +static GLboolean _glewInit_WGL_EXT_pixel_format (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglChoosePixelFormatEXT = (PFNWGLCHOOSEPIXELFORMATEXTPROC)glewGetProcAddress((const GLubyte*)"wglChoosePixelFormatEXT")) == NULL) || r; + r = ((wglGetPixelFormatAttribfvEXT = (PFNWGLGETPIXELFORMATATTRIBFVEXTPROC)glewGetProcAddress((const GLubyte*)"wglGetPixelFormatAttribfvEXT")) == NULL) || r; + r = ((wglGetPixelFormatAttribivEXT = (PFNWGLGETPIXELFORMATATTRIBIVEXTPROC)glewGetProcAddress((const GLubyte*)"wglGetPixelFormatAttribivEXT")) == NULL) || r; + + return r; +} + +#endif /* WGL_EXT_pixel_format */ + +#ifdef WGL_EXT_pixel_format_packed_float + +#endif /* WGL_EXT_pixel_format_packed_float */ + +#ifdef WGL_EXT_swap_control + +static GLboolean _glewInit_WGL_EXT_swap_control (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglGetSwapIntervalEXT = (PFNWGLGETSWAPINTERVALEXTPROC)glewGetProcAddress((const GLubyte*)"wglGetSwapIntervalEXT")) == NULL) || r; + r = ((wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)glewGetProcAddress((const GLubyte*)"wglSwapIntervalEXT")) == NULL) || r; + + return r; +} + +#endif /* WGL_EXT_swap_control */ + +#ifdef WGL_I3D_digital_video_control + +static GLboolean _glewInit_WGL_I3D_digital_video_control (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglGetDigitalVideoParametersI3D = (PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC)glewGetProcAddress((const GLubyte*)"wglGetDigitalVideoParametersI3D")) == NULL) || r; + r = ((wglSetDigitalVideoParametersI3D = (PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC)glewGetProcAddress((const GLubyte*)"wglSetDigitalVideoParametersI3D")) == NULL) || r; + + return r; +} + +#endif /* WGL_I3D_digital_video_control */ + +#ifdef WGL_I3D_gamma + +static GLboolean _glewInit_WGL_I3D_gamma (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglGetGammaTableI3D = (PFNWGLGETGAMMATABLEI3DPROC)glewGetProcAddress((const GLubyte*)"wglGetGammaTableI3D")) == NULL) || r; + r = ((wglGetGammaTableParametersI3D = (PFNWGLGETGAMMATABLEPARAMETERSI3DPROC)glewGetProcAddress((const GLubyte*)"wglGetGammaTableParametersI3D")) == NULL) || r; + r = ((wglSetGammaTableI3D = (PFNWGLSETGAMMATABLEI3DPROC)glewGetProcAddress((const GLubyte*)"wglSetGammaTableI3D")) == NULL) || r; + r = ((wglSetGammaTableParametersI3D = (PFNWGLSETGAMMATABLEPARAMETERSI3DPROC)glewGetProcAddress((const GLubyte*)"wglSetGammaTableParametersI3D")) == NULL) || r; + + return r; +} + +#endif /* WGL_I3D_gamma */ + +#ifdef WGL_I3D_genlock + +static GLboolean _glewInit_WGL_I3D_genlock (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglDisableGenlockI3D = (PFNWGLDISABLEGENLOCKI3DPROC)glewGetProcAddress((const GLubyte*)"wglDisableGenlockI3D")) == NULL) || r; + r = ((wglEnableGenlockI3D = (PFNWGLENABLEGENLOCKI3DPROC)glewGetProcAddress((const GLubyte*)"wglEnableGenlockI3D")) == NULL) || r; + r = ((wglGenlockSampleRateI3D = (PFNWGLGENLOCKSAMPLERATEI3DPROC)glewGetProcAddress((const GLubyte*)"wglGenlockSampleRateI3D")) == NULL) || r; + r = ((wglGenlockSourceDelayI3D = (PFNWGLGENLOCKSOURCEDELAYI3DPROC)glewGetProcAddress((const GLubyte*)"wglGenlockSourceDelayI3D")) == NULL) || r; + r = ((wglGenlockSourceEdgeI3D = (PFNWGLGENLOCKSOURCEEDGEI3DPROC)glewGetProcAddress((const GLubyte*)"wglGenlockSourceEdgeI3D")) == NULL) || r; + r = ((wglGenlockSourceI3D = (PFNWGLGENLOCKSOURCEI3DPROC)glewGetProcAddress((const GLubyte*)"wglGenlockSourceI3D")) == NULL) || r; + r = ((wglGetGenlockSampleRateI3D = (PFNWGLGETGENLOCKSAMPLERATEI3DPROC)glewGetProcAddress((const GLubyte*)"wglGetGenlockSampleRateI3D")) == NULL) || r; + r = ((wglGetGenlockSourceDelayI3D = (PFNWGLGETGENLOCKSOURCEDELAYI3DPROC)glewGetProcAddress((const GLubyte*)"wglGetGenlockSourceDelayI3D")) == NULL) || r; + r = ((wglGetGenlockSourceEdgeI3D = (PFNWGLGETGENLOCKSOURCEEDGEI3DPROC)glewGetProcAddress((const GLubyte*)"wglGetGenlockSourceEdgeI3D")) == NULL) || r; + r = ((wglGetGenlockSourceI3D = (PFNWGLGETGENLOCKSOURCEI3DPROC)glewGetProcAddress((const GLubyte*)"wglGetGenlockSourceI3D")) == NULL) || r; + r = ((wglIsEnabledGenlockI3D = (PFNWGLISENABLEDGENLOCKI3DPROC)glewGetProcAddress((const GLubyte*)"wglIsEnabledGenlockI3D")) == NULL) || r; + r = ((wglQueryGenlockMaxSourceDelayI3D = (PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC)glewGetProcAddress((const GLubyte*)"wglQueryGenlockMaxSourceDelayI3D")) == NULL) || r; + + return r; +} + +#endif /* WGL_I3D_genlock */ + +#ifdef WGL_I3D_image_buffer + +static GLboolean _glewInit_WGL_I3D_image_buffer (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglAssociateImageBufferEventsI3D = (PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC)glewGetProcAddress((const GLubyte*)"wglAssociateImageBufferEventsI3D")) == NULL) || r; + r = ((wglCreateImageBufferI3D = (PFNWGLCREATEIMAGEBUFFERI3DPROC)glewGetProcAddress((const GLubyte*)"wglCreateImageBufferI3D")) == NULL) || r; + r = ((wglDestroyImageBufferI3D = (PFNWGLDESTROYIMAGEBUFFERI3DPROC)glewGetProcAddress((const GLubyte*)"wglDestroyImageBufferI3D")) == NULL) || r; + r = ((wglReleaseImageBufferEventsI3D = (PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC)glewGetProcAddress((const GLubyte*)"wglReleaseImageBufferEventsI3D")) == NULL) || r; + + return r; +} + +#endif /* WGL_I3D_image_buffer */ + +#ifdef WGL_I3D_swap_frame_lock + +static GLboolean _glewInit_WGL_I3D_swap_frame_lock (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglDisableFrameLockI3D = (PFNWGLDISABLEFRAMELOCKI3DPROC)glewGetProcAddress((const GLubyte*)"wglDisableFrameLockI3D")) == NULL) || r; + r = ((wglEnableFrameLockI3D = (PFNWGLENABLEFRAMELOCKI3DPROC)glewGetProcAddress((const GLubyte*)"wglEnableFrameLockI3D")) == NULL) || r; + r = ((wglIsEnabledFrameLockI3D = (PFNWGLISENABLEDFRAMELOCKI3DPROC)glewGetProcAddress((const GLubyte*)"wglIsEnabledFrameLockI3D")) == NULL) || r; + r = ((wglQueryFrameLockMasterI3D = (PFNWGLQUERYFRAMELOCKMASTERI3DPROC)glewGetProcAddress((const GLubyte*)"wglQueryFrameLockMasterI3D")) == NULL) || r; + + return r; +} + +#endif /* WGL_I3D_swap_frame_lock */ + +#ifdef WGL_I3D_swap_frame_usage + +static GLboolean _glewInit_WGL_I3D_swap_frame_usage (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglBeginFrameTrackingI3D = (PFNWGLBEGINFRAMETRACKINGI3DPROC)glewGetProcAddress((const GLubyte*)"wglBeginFrameTrackingI3D")) == NULL) || r; + r = ((wglEndFrameTrackingI3D = (PFNWGLENDFRAMETRACKINGI3DPROC)glewGetProcAddress((const GLubyte*)"wglEndFrameTrackingI3D")) == NULL) || r; + r = ((wglGetFrameUsageI3D = (PFNWGLGETFRAMEUSAGEI3DPROC)glewGetProcAddress((const GLubyte*)"wglGetFrameUsageI3D")) == NULL) || r; + r = ((wglQueryFrameTrackingI3D = (PFNWGLQUERYFRAMETRACKINGI3DPROC)glewGetProcAddress((const GLubyte*)"wglQueryFrameTrackingI3D")) == NULL) || r; + + return r; +} + +#endif /* WGL_I3D_swap_frame_usage */ + +#ifdef WGL_NV_float_buffer + +#endif /* WGL_NV_float_buffer */ + +#ifdef WGL_NV_gpu_affinity + +static GLboolean _glewInit_WGL_NV_gpu_affinity (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglCreateAffinityDCNV = (PFNWGLCREATEAFFINITYDCNVPROC)glewGetProcAddress((const GLubyte*)"wglCreateAffinityDCNV")) == NULL) || r; + r = ((wglDeleteDCNV = (PFNWGLDELETEDCNVPROC)glewGetProcAddress((const GLubyte*)"wglDeleteDCNV")) == NULL) || r; + r = ((wglEnumGpuDevicesNV = (PFNWGLENUMGPUDEVICESNVPROC)glewGetProcAddress((const GLubyte*)"wglEnumGpuDevicesNV")) == NULL) || r; + r = ((wglEnumGpusFromAffinityDCNV = (PFNWGLENUMGPUSFROMAFFINITYDCNVPROC)glewGetProcAddress((const GLubyte*)"wglEnumGpusFromAffinityDCNV")) == NULL) || r; + r = ((wglEnumGpusNV = (PFNWGLENUMGPUSNVPROC)glewGetProcAddress((const GLubyte*)"wglEnumGpusNV")) == NULL) || r; + + return r; +} + +#endif /* WGL_NV_gpu_affinity */ + +#ifdef WGL_NV_present_video + +static GLboolean _glewInit_WGL_NV_present_video (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglBindVideoDeviceNV = (PFNWGLBINDVIDEODEVICENVPROC)glewGetProcAddress((const GLubyte*)"wglBindVideoDeviceNV")) == NULL) || r; + r = ((wglEnumerateVideoDevicesNV = (PFNWGLENUMERATEVIDEODEVICESNVPROC)glewGetProcAddress((const GLubyte*)"wglEnumerateVideoDevicesNV")) == NULL) || r; + r = ((wglQueryCurrentContextNV = (PFNWGLQUERYCURRENTCONTEXTNVPROC)glewGetProcAddress((const GLubyte*)"wglQueryCurrentContextNV")) == NULL) || r; + + return r; +} + +#endif /* WGL_NV_present_video */ + +#ifdef WGL_NV_render_depth_texture + +#endif /* WGL_NV_render_depth_texture */ + +#ifdef WGL_NV_render_texture_rectangle + +#endif /* WGL_NV_render_texture_rectangle */ + +#ifdef WGL_NV_swap_group + +static GLboolean _glewInit_WGL_NV_swap_group (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglBindSwapBarrierNV = (PFNWGLBINDSWAPBARRIERNVPROC)glewGetProcAddress((const GLubyte*)"wglBindSwapBarrierNV")) == NULL) || r; + r = ((wglJoinSwapGroupNV = (PFNWGLJOINSWAPGROUPNVPROC)glewGetProcAddress((const GLubyte*)"wglJoinSwapGroupNV")) == NULL) || r; + r = ((wglQueryFrameCountNV = (PFNWGLQUERYFRAMECOUNTNVPROC)glewGetProcAddress((const GLubyte*)"wglQueryFrameCountNV")) == NULL) || r; + r = ((wglQueryMaxSwapGroupsNV = (PFNWGLQUERYMAXSWAPGROUPSNVPROC)glewGetProcAddress((const GLubyte*)"wglQueryMaxSwapGroupsNV")) == NULL) || r; + r = ((wglQuerySwapGroupNV = (PFNWGLQUERYSWAPGROUPNVPROC)glewGetProcAddress((const GLubyte*)"wglQuerySwapGroupNV")) == NULL) || r; + r = ((wglResetFrameCountNV = (PFNWGLRESETFRAMECOUNTNVPROC)glewGetProcAddress((const GLubyte*)"wglResetFrameCountNV")) == NULL) || r; + + return r; +} + +#endif /* WGL_NV_swap_group */ + +#ifdef WGL_NV_vertex_array_range + +static GLboolean _glewInit_WGL_NV_vertex_array_range (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglAllocateMemoryNV = (PFNWGLALLOCATEMEMORYNVPROC)glewGetProcAddress((const GLubyte*)"wglAllocateMemoryNV")) == NULL) || r; + r = ((wglFreeMemoryNV = (PFNWGLFREEMEMORYNVPROC)glewGetProcAddress((const GLubyte*)"wglFreeMemoryNV")) == NULL) || r; + + return r; +} + +#endif /* WGL_NV_vertex_array_range */ + +#ifdef WGL_NV_video_output + +static GLboolean _glewInit_WGL_NV_video_output (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglBindVideoImageNV = (PFNWGLBINDVIDEOIMAGENVPROC)glewGetProcAddress((const GLubyte*)"wglBindVideoImageNV")) == NULL) || r; + r = ((wglGetVideoDeviceNV = (PFNWGLGETVIDEODEVICENVPROC)glewGetProcAddress((const GLubyte*)"wglGetVideoDeviceNV")) == NULL) || r; + r = ((wglGetVideoInfoNV = (PFNWGLGETVIDEOINFONVPROC)glewGetProcAddress((const GLubyte*)"wglGetVideoInfoNV")) == NULL) || r; + r = ((wglReleaseVideoDeviceNV = (PFNWGLRELEASEVIDEODEVICENVPROC)glewGetProcAddress((const GLubyte*)"wglReleaseVideoDeviceNV")) == NULL) || r; + r = ((wglReleaseVideoImageNV = (PFNWGLRELEASEVIDEOIMAGENVPROC)glewGetProcAddress((const GLubyte*)"wglReleaseVideoImageNV")) == NULL) || r; + r = ((wglSendPbufferToVideoNV = (PFNWGLSENDPBUFFERTOVIDEONVPROC)glewGetProcAddress((const GLubyte*)"wglSendPbufferToVideoNV")) == NULL) || r; + + return r; +} + +#endif /* WGL_NV_video_output */ + +#ifdef WGL_OML_sync_control + +static GLboolean _glewInit_WGL_OML_sync_control (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglGetMscRateOML = (PFNWGLGETMSCRATEOMLPROC)glewGetProcAddress((const GLubyte*)"wglGetMscRateOML")) == NULL) || r; + r = ((wglGetSyncValuesOML = (PFNWGLGETSYNCVALUESOMLPROC)glewGetProcAddress((const GLubyte*)"wglGetSyncValuesOML")) == NULL) || r; + r = ((wglSwapBuffersMscOML = (PFNWGLSWAPBUFFERSMSCOMLPROC)glewGetProcAddress((const GLubyte*)"wglSwapBuffersMscOML")) == NULL) || r; + r = ((wglSwapLayerBuffersMscOML = (PFNWGLSWAPLAYERBUFFERSMSCOMLPROC)glewGetProcAddress((const GLubyte*)"wglSwapLayerBuffersMscOML")) == NULL) || r; + r = ((wglWaitForMscOML = (PFNWGLWAITFORMSCOMLPROC)glewGetProcAddress((const GLubyte*)"wglWaitForMscOML")) == NULL) || r; + r = ((wglWaitForSbcOML = (PFNWGLWAITFORSBCOMLPROC)glewGetProcAddress((const GLubyte*)"wglWaitForSbcOML")) == NULL) || r; + + return r; +} + +#endif /* WGL_OML_sync_control */ + +/* ------------------------------------------------------------------------- */ + +static PFNWGLGETEXTENSIONSSTRINGARBPROC _wglewGetExtensionsStringARB = NULL; +static PFNWGLGETEXTENSIONSSTRINGEXTPROC _wglewGetExtensionsStringEXT = NULL; + +GLboolean wglewGetExtension (const char* name) +{ + GLubyte* p; + GLubyte* end; + GLuint len = _glewStrLen((const GLubyte*)name); + if (_wglewGetExtensionsStringARB == NULL) + if (_wglewGetExtensionsStringEXT == NULL) + return GL_FALSE; + else + p = (GLubyte*)_wglewGetExtensionsStringEXT(); + else + p = (GLubyte*)_wglewGetExtensionsStringARB(wglGetCurrentDC()); + if (0 == p) return GL_FALSE; + end = p + _glewStrLen(p); + while (p < end) + { + GLuint n = _glewStrCLen(p, ' '); + if (len == n && _glewStrSame((const GLubyte*)name, p, n)) return GL_TRUE; + p += n+1; + } + return GL_FALSE; +} + +GLenum wglewContextInit (WGLEW_CONTEXT_ARG_DEF_LIST) +{ + GLboolean crippled; + /* find wgl extension string query functions */ + _wglewGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)glewGetProcAddress((const GLubyte*)"wglGetExtensionsStringARB"); + _wglewGetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC)glewGetProcAddress((const GLubyte*)"wglGetExtensionsStringEXT"); + /* initialize extensions */ + crippled = _wglewGetExtensionsStringARB == NULL && _wglewGetExtensionsStringEXT == NULL; +#ifdef WGL_3DFX_multisample + CONST_CAST(WGLEW_3DFX_multisample) = wglewGetExtension("WGL_3DFX_multisample"); +#endif /* WGL_3DFX_multisample */ +#ifdef WGL_3DL_stereo_control + CONST_CAST(WGLEW_3DL_stereo_control) = wglewGetExtension("WGL_3DL_stereo_control"); + if (glewExperimental || WGLEW_3DL_stereo_control|| crippled) CONST_CAST(WGLEW_3DL_stereo_control)= !_glewInit_WGL_3DL_stereo_control(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_3DL_stereo_control */ +#ifdef WGL_ARB_buffer_region + CONST_CAST(WGLEW_ARB_buffer_region) = wglewGetExtension("WGL_ARB_buffer_region"); + if (glewExperimental || WGLEW_ARB_buffer_region|| crippled) CONST_CAST(WGLEW_ARB_buffer_region)= !_glewInit_WGL_ARB_buffer_region(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_ARB_buffer_region */ +#ifdef WGL_ARB_create_context + CONST_CAST(WGLEW_ARB_create_context) = wglewGetExtension("WGL_ARB_create_context"); + if (glewExperimental || WGLEW_ARB_create_context|| crippled) CONST_CAST(WGLEW_ARB_create_context)= !_glewInit_WGL_ARB_create_context(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_ARB_create_context */ +#ifdef WGL_ARB_extensions_string + CONST_CAST(WGLEW_ARB_extensions_string) = wglewGetExtension("WGL_ARB_extensions_string"); + if (glewExperimental || WGLEW_ARB_extensions_string|| crippled) CONST_CAST(WGLEW_ARB_extensions_string)= !_glewInit_WGL_ARB_extensions_string(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_ARB_extensions_string */ +#ifdef WGL_ARB_framebuffer_sRGB + CONST_CAST(WGLEW_ARB_framebuffer_sRGB) = wglewGetExtension("WGL_ARB_framebuffer_sRGB"); +#endif /* WGL_ARB_framebuffer_sRGB */ +#ifdef WGL_ARB_make_current_read + CONST_CAST(WGLEW_ARB_make_current_read) = wglewGetExtension("WGL_ARB_make_current_read"); + if (glewExperimental || WGLEW_ARB_make_current_read|| crippled) CONST_CAST(WGLEW_ARB_make_current_read)= !_glewInit_WGL_ARB_make_current_read(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_ARB_make_current_read */ +#ifdef WGL_ARB_multisample + CONST_CAST(WGLEW_ARB_multisample) = wglewGetExtension("WGL_ARB_multisample"); +#endif /* WGL_ARB_multisample */ +#ifdef WGL_ARB_pbuffer + CONST_CAST(WGLEW_ARB_pbuffer) = wglewGetExtension("WGL_ARB_pbuffer"); + if (glewExperimental || WGLEW_ARB_pbuffer|| crippled) CONST_CAST(WGLEW_ARB_pbuffer)= !_glewInit_WGL_ARB_pbuffer(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_ARB_pbuffer */ +#ifdef WGL_ARB_pixel_format + CONST_CAST(WGLEW_ARB_pixel_format) = wglewGetExtension("WGL_ARB_pixel_format"); + if (glewExperimental || WGLEW_ARB_pixel_format|| crippled) CONST_CAST(WGLEW_ARB_pixel_format)= !_glewInit_WGL_ARB_pixel_format(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_ARB_pixel_format */ +#ifdef WGL_ARB_pixel_format_float + CONST_CAST(WGLEW_ARB_pixel_format_float) = wglewGetExtension("WGL_ARB_pixel_format_float"); +#endif /* WGL_ARB_pixel_format_float */ +#ifdef WGL_ARB_render_texture + CONST_CAST(WGLEW_ARB_render_texture) = wglewGetExtension("WGL_ARB_render_texture"); + if (glewExperimental || WGLEW_ARB_render_texture|| crippled) CONST_CAST(WGLEW_ARB_render_texture)= !_glewInit_WGL_ARB_render_texture(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_ARB_render_texture */ +#ifdef WGL_ATI_pixel_format_float + CONST_CAST(WGLEW_ATI_pixel_format_float) = wglewGetExtension("WGL_ATI_pixel_format_float"); +#endif /* WGL_ATI_pixel_format_float */ +#ifdef WGL_ATI_render_texture_rectangle + CONST_CAST(WGLEW_ATI_render_texture_rectangle) = wglewGetExtension("WGL_ATI_render_texture_rectangle"); +#endif /* WGL_ATI_render_texture_rectangle */ +#ifdef WGL_EXT_depth_float + CONST_CAST(WGLEW_EXT_depth_float) = wglewGetExtension("WGL_EXT_depth_float"); +#endif /* WGL_EXT_depth_float */ +#ifdef WGL_EXT_display_color_table + CONST_CAST(WGLEW_EXT_display_color_table) = wglewGetExtension("WGL_EXT_display_color_table"); + if (glewExperimental || WGLEW_EXT_display_color_table|| crippled) CONST_CAST(WGLEW_EXT_display_color_table)= !_glewInit_WGL_EXT_display_color_table(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_EXT_display_color_table */ +#ifdef WGL_EXT_extensions_string + CONST_CAST(WGLEW_EXT_extensions_string) = wglewGetExtension("WGL_EXT_extensions_string"); + if (glewExperimental || WGLEW_EXT_extensions_string|| crippled) CONST_CAST(WGLEW_EXT_extensions_string)= !_glewInit_WGL_EXT_extensions_string(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_EXT_extensions_string */ +#ifdef WGL_EXT_framebuffer_sRGB + CONST_CAST(WGLEW_EXT_framebuffer_sRGB) = wglewGetExtension("WGL_EXT_framebuffer_sRGB"); +#endif /* WGL_EXT_framebuffer_sRGB */ +#ifdef WGL_EXT_make_current_read + CONST_CAST(WGLEW_EXT_make_current_read) = wglewGetExtension("WGL_EXT_make_current_read"); + if (glewExperimental || WGLEW_EXT_make_current_read|| crippled) CONST_CAST(WGLEW_EXT_make_current_read)= !_glewInit_WGL_EXT_make_current_read(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_EXT_make_current_read */ +#ifdef WGL_EXT_multisample + CONST_CAST(WGLEW_EXT_multisample) = wglewGetExtension("WGL_EXT_multisample"); +#endif /* WGL_EXT_multisample */ +#ifdef WGL_EXT_pbuffer + CONST_CAST(WGLEW_EXT_pbuffer) = wglewGetExtension("WGL_EXT_pbuffer"); + if (glewExperimental || WGLEW_EXT_pbuffer|| crippled) CONST_CAST(WGLEW_EXT_pbuffer)= !_glewInit_WGL_EXT_pbuffer(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_EXT_pbuffer */ +#ifdef WGL_EXT_pixel_format + CONST_CAST(WGLEW_EXT_pixel_format) = wglewGetExtension("WGL_EXT_pixel_format"); + if (glewExperimental || WGLEW_EXT_pixel_format|| crippled) CONST_CAST(WGLEW_EXT_pixel_format)= !_glewInit_WGL_EXT_pixel_format(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_EXT_pixel_format */ +#ifdef WGL_EXT_pixel_format_packed_float + CONST_CAST(WGLEW_EXT_pixel_format_packed_float) = wglewGetExtension("WGL_EXT_pixel_format_packed_float"); +#endif /* WGL_EXT_pixel_format_packed_float */ +#ifdef WGL_EXT_swap_control + CONST_CAST(WGLEW_EXT_swap_control) = wglewGetExtension("WGL_EXT_swap_control"); + if (glewExperimental || WGLEW_EXT_swap_control|| crippled) CONST_CAST(WGLEW_EXT_swap_control)= !_glewInit_WGL_EXT_swap_control(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_EXT_swap_control */ +#ifdef WGL_I3D_digital_video_control + CONST_CAST(WGLEW_I3D_digital_video_control) = wglewGetExtension("WGL_I3D_digital_video_control"); + if (glewExperimental || WGLEW_I3D_digital_video_control|| crippled) CONST_CAST(WGLEW_I3D_digital_video_control)= !_glewInit_WGL_I3D_digital_video_control(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_I3D_digital_video_control */ +#ifdef WGL_I3D_gamma + CONST_CAST(WGLEW_I3D_gamma) = wglewGetExtension("WGL_I3D_gamma"); + if (glewExperimental || WGLEW_I3D_gamma|| crippled) CONST_CAST(WGLEW_I3D_gamma)= !_glewInit_WGL_I3D_gamma(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_I3D_gamma */ +#ifdef WGL_I3D_genlock + CONST_CAST(WGLEW_I3D_genlock) = wglewGetExtension("WGL_I3D_genlock"); + if (glewExperimental || WGLEW_I3D_genlock|| crippled) CONST_CAST(WGLEW_I3D_genlock)= !_glewInit_WGL_I3D_genlock(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_I3D_genlock */ +#ifdef WGL_I3D_image_buffer + CONST_CAST(WGLEW_I3D_image_buffer) = wglewGetExtension("WGL_I3D_image_buffer"); + if (glewExperimental || WGLEW_I3D_image_buffer|| crippled) CONST_CAST(WGLEW_I3D_image_buffer)= !_glewInit_WGL_I3D_image_buffer(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_I3D_image_buffer */ +#ifdef WGL_I3D_swap_frame_lock + CONST_CAST(WGLEW_I3D_swap_frame_lock) = wglewGetExtension("WGL_I3D_swap_frame_lock"); + if (glewExperimental || WGLEW_I3D_swap_frame_lock|| crippled) CONST_CAST(WGLEW_I3D_swap_frame_lock)= !_glewInit_WGL_I3D_swap_frame_lock(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_I3D_swap_frame_lock */ +#ifdef WGL_I3D_swap_frame_usage + CONST_CAST(WGLEW_I3D_swap_frame_usage) = wglewGetExtension("WGL_I3D_swap_frame_usage"); + if (glewExperimental || WGLEW_I3D_swap_frame_usage|| crippled) CONST_CAST(WGLEW_I3D_swap_frame_usage)= !_glewInit_WGL_I3D_swap_frame_usage(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_I3D_swap_frame_usage */ +#ifdef WGL_NV_float_buffer + CONST_CAST(WGLEW_NV_float_buffer) = wglewGetExtension("WGL_NV_float_buffer"); +#endif /* WGL_NV_float_buffer */ +#ifdef WGL_NV_gpu_affinity + CONST_CAST(WGLEW_NV_gpu_affinity) = wglewGetExtension("WGL_NV_gpu_affinity"); + if (glewExperimental || WGLEW_NV_gpu_affinity|| crippled) CONST_CAST(WGLEW_NV_gpu_affinity)= !_glewInit_WGL_NV_gpu_affinity(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_NV_gpu_affinity */ +#ifdef WGL_NV_present_video + CONST_CAST(WGLEW_NV_present_video) = wglewGetExtension("WGL_NV_present_video"); + if (glewExperimental || WGLEW_NV_present_video|| crippled) CONST_CAST(WGLEW_NV_present_video)= !_glewInit_WGL_NV_present_video(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_NV_present_video */ +#ifdef WGL_NV_render_depth_texture + CONST_CAST(WGLEW_NV_render_depth_texture) = wglewGetExtension("WGL_NV_render_depth_texture"); +#endif /* WGL_NV_render_depth_texture */ +#ifdef WGL_NV_render_texture_rectangle + CONST_CAST(WGLEW_NV_render_texture_rectangle) = wglewGetExtension("WGL_NV_render_texture_rectangle"); +#endif /* WGL_NV_render_texture_rectangle */ +#ifdef WGL_NV_swap_group + CONST_CAST(WGLEW_NV_swap_group) = wglewGetExtension("WGL_NV_swap_group"); + if (glewExperimental || WGLEW_NV_swap_group|| crippled) CONST_CAST(WGLEW_NV_swap_group)= !_glewInit_WGL_NV_swap_group(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_NV_swap_group */ +#ifdef WGL_NV_vertex_array_range + CONST_CAST(WGLEW_NV_vertex_array_range) = wglewGetExtension("WGL_NV_vertex_array_range"); + if (glewExperimental || WGLEW_NV_vertex_array_range|| crippled) CONST_CAST(WGLEW_NV_vertex_array_range)= !_glewInit_WGL_NV_vertex_array_range(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_NV_vertex_array_range */ +#ifdef WGL_NV_video_output + CONST_CAST(WGLEW_NV_video_output) = wglewGetExtension("WGL_NV_video_output"); + if (glewExperimental || WGLEW_NV_video_output|| crippled) CONST_CAST(WGLEW_NV_video_output)= !_glewInit_WGL_NV_video_output(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_NV_video_output */ +#ifdef WGL_OML_sync_control + CONST_CAST(WGLEW_OML_sync_control) = wglewGetExtension("WGL_OML_sync_control"); + if (glewExperimental || WGLEW_OML_sync_control|| crippled) CONST_CAST(WGLEW_OML_sync_control)= !_glewInit_WGL_OML_sync_control(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_OML_sync_control */ + + return GLEW_OK; +} + +#elif !defined(__APPLE__) || defined(GLEW_APPLE_GLX) + +PFNGLXGETCURRENTDISPLAYPROC __glewXGetCurrentDisplay = NULL; + +PFNGLXCHOOSEFBCONFIGPROC __glewXChooseFBConfig = NULL; +PFNGLXCREATENEWCONTEXTPROC __glewXCreateNewContext = NULL; +PFNGLXCREATEPBUFFERPROC __glewXCreatePbuffer = NULL; +PFNGLXCREATEPIXMAPPROC __glewXCreatePixmap = NULL; +PFNGLXCREATEWINDOWPROC __glewXCreateWindow = NULL; +PFNGLXDESTROYPBUFFERPROC __glewXDestroyPbuffer = NULL; +PFNGLXDESTROYPIXMAPPROC __glewXDestroyPixmap = NULL; +PFNGLXDESTROYWINDOWPROC __glewXDestroyWindow = NULL; +PFNGLXGETCURRENTREADDRAWABLEPROC __glewXGetCurrentReadDrawable = NULL; +PFNGLXGETFBCONFIGATTRIBPROC __glewXGetFBConfigAttrib = NULL; +PFNGLXGETFBCONFIGSPROC __glewXGetFBConfigs = NULL; +PFNGLXGETSELECTEDEVENTPROC __glewXGetSelectedEvent = NULL; +PFNGLXGETVISUALFROMFBCONFIGPROC __glewXGetVisualFromFBConfig = NULL; +PFNGLXMAKECONTEXTCURRENTPROC __glewXMakeContextCurrent = NULL; +PFNGLXQUERYCONTEXTPROC __glewXQueryContext = NULL; +PFNGLXQUERYDRAWABLEPROC __glewXQueryDrawable = NULL; +PFNGLXSELECTEVENTPROC __glewXSelectEvent = NULL; + +PFNGLXCREATECONTEXTATTRIBSARBPROC __glewXCreateContextAttribsARB = NULL; + +PFNGLXBINDTEXIMAGEATIPROC __glewXBindTexImageATI = NULL; +PFNGLXDRAWABLEATTRIBATIPROC __glewXDrawableAttribATI = NULL; +PFNGLXRELEASETEXIMAGEATIPROC __glewXReleaseTexImageATI = NULL; + +PFNGLXFREECONTEXTEXTPROC __glewXFreeContextEXT = NULL; +PFNGLXGETCONTEXTIDEXTPROC __glewXGetContextIDEXT = NULL; +PFNGLXIMPORTCONTEXTEXTPROC __glewXImportContextEXT = NULL; +PFNGLXQUERYCONTEXTINFOEXTPROC __glewXQueryContextInfoEXT = NULL; + +PFNGLXBINDTEXIMAGEEXTPROC __glewXBindTexImageEXT = NULL; +PFNGLXRELEASETEXIMAGEEXTPROC __glewXReleaseTexImageEXT = NULL; + +PFNGLXGETAGPOFFSETMESAPROC __glewXGetAGPOffsetMESA = NULL; + +PFNGLXCOPYSUBBUFFERMESAPROC __glewXCopySubBufferMESA = NULL; + +PFNGLXCREATEGLXPIXMAPMESAPROC __glewXCreateGLXPixmapMESA = NULL; + +PFNGLXRELEASEBUFFERSMESAPROC __glewXReleaseBuffersMESA = NULL; + +PFNGLXSET3DFXMODEMESAPROC __glewXSet3DfxModeMESA = NULL; + +PFNGLXBINDVIDEODEVICENVPROC __glewXBindVideoDeviceNV = NULL; +PFNGLXENUMERATEVIDEODEVICESNVPROC __glewXEnumerateVideoDevicesNV = NULL; + +PFNGLXBINDSWAPBARRIERNVPROC __glewXBindSwapBarrierNV = NULL; +PFNGLXJOINSWAPGROUPNVPROC __glewXJoinSwapGroupNV = NULL; +PFNGLXQUERYFRAMECOUNTNVPROC __glewXQueryFrameCountNV = NULL; +PFNGLXQUERYMAXSWAPGROUPSNVPROC __glewXQueryMaxSwapGroupsNV = NULL; +PFNGLXQUERYSWAPGROUPNVPROC __glewXQuerySwapGroupNV = NULL; +PFNGLXRESETFRAMECOUNTNVPROC __glewXResetFrameCountNV = NULL; + +PFNGLXALLOCATEMEMORYNVPROC __glewXAllocateMemoryNV = NULL; +PFNGLXFREEMEMORYNVPROC __glewXFreeMemoryNV = NULL; + +PFNGLXBINDVIDEOIMAGENVPROC __glewXBindVideoImageNV = NULL; +PFNGLXGETVIDEODEVICENVPROC __glewXGetVideoDeviceNV = NULL; +PFNGLXGETVIDEOINFONVPROC __glewXGetVideoInfoNV = NULL; +PFNGLXRELEASEVIDEODEVICENVPROC __glewXReleaseVideoDeviceNV = NULL; +PFNGLXRELEASEVIDEOIMAGENVPROC __glewXReleaseVideoImageNV = NULL; +PFNGLXSENDPBUFFERTOVIDEONVPROC __glewXSendPbufferToVideoNV = NULL; + +#ifdef GLX_OML_sync_control +PFNGLXGETMSCRATEOMLPROC __glewXGetMscRateOML = NULL; +PFNGLXGETSYNCVALUESOMLPROC __glewXGetSyncValuesOML = NULL; +PFNGLXSWAPBUFFERSMSCOMLPROC __glewXSwapBuffersMscOML = NULL; +PFNGLXWAITFORMSCOMLPROC __glewXWaitForMscOML = NULL; +PFNGLXWAITFORSBCOMLPROC __glewXWaitForSbcOML = NULL; +#endif + +PFNGLXCHOOSEFBCONFIGSGIXPROC __glewXChooseFBConfigSGIX = NULL; +PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC __glewXCreateContextWithConfigSGIX = NULL; +PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC __glewXCreateGLXPixmapWithConfigSGIX = NULL; +PFNGLXGETFBCONFIGATTRIBSGIXPROC __glewXGetFBConfigAttribSGIX = NULL; +PFNGLXGETFBCONFIGFROMVISUALSGIXPROC __glewXGetFBConfigFromVisualSGIX = NULL; +PFNGLXGETVISUALFROMFBCONFIGSGIXPROC __glewXGetVisualFromFBConfigSGIX = NULL; + +PFNGLXBINDHYPERPIPESGIXPROC __glewXBindHyperpipeSGIX = NULL; +PFNGLXDESTROYHYPERPIPECONFIGSGIXPROC __glewXDestroyHyperpipeConfigSGIX = NULL; +PFNGLXHYPERPIPEATTRIBSGIXPROC __glewXHyperpipeAttribSGIX = NULL; +PFNGLXHYPERPIPECONFIGSGIXPROC __glewXHyperpipeConfigSGIX = NULL; +PFNGLXQUERYHYPERPIPEATTRIBSGIXPROC __glewXQueryHyperpipeAttribSGIX = NULL; +PFNGLXQUERYHYPERPIPEBESTATTRIBSGIXPROC __glewXQueryHyperpipeBestAttribSGIX = NULL; +PFNGLXQUERYHYPERPIPECONFIGSGIXPROC __glewXQueryHyperpipeConfigSGIX = NULL; +PFNGLXQUERYHYPERPIPENETWORKSGIXPROC __glewXQueryHyperpipeNetworkSGIX = NULL; + +PFNGLXCREATEGLXPBUFFERSGIXPROC __glewXCreateGLXPbufferSGIX = NULL; +PFNGLXDESTROYGLXPBUFFERSGIXPROC __glewXDestroyGLXPbufferSGIX = NULL; +PFNGLXGETSELECTEDEVENTSGIXPROC __glewXGetSelectedEventSGIX = NULL; +PFNGLXQUERYGLXPBUFFERSGIXPROC __glewXQueryGLXPbufferSGIX = NULL; +PFNGLXSELECTEVENTSGIXPROC __glewXSelectEventSGIX = NULL; + +PFNGLXBINDSWAPBARRIERSGIXPROC __glewXBindSwapBarrierSGIX = NULL; +PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC __glewXQueryMaxSwapBarriersSGIX = NULL; + +PFNGLXJOINSWAPGROUPSGIXPROC __glewXJoinSwapGroupSGIX = NULL; + +PFNGLXBINDCHANNELTOWINDOWSGIXPROC __glewXBindChannelToWindowSGIX = NULL; +PFNGLXCHANNELRECTSGIXPROC __glewXChannelRectSGIX = NULL; +PFNGLXCHANNELRECTSYNCSGIXPROC __glewXChannelRectSyncSGIX = NULL; +PFNGLXQUERYCHANNELDELTASSGIXPROC __glewXQueryChannelDeltasSGIX = NULL; +PFNGLXQUERYCHANNELRECTSGIXPROC __glewXQueryChannelRectSGIX = NULL; + +PFNGLXCUSHIONSGIPROC __glewXCushionSGI = NULL; + +PFNGLXGETCURRENTREADDRAWABLESGIPROC __glewXGetCurrentReadDrawableSGI = NULL; +PFNGLXMAKECURRENTREADSGIPROC __glewXMakeCurrentReadSGI = NULL; + +PFNGLXSWAPINTERVALSGIPROC __glewXSwapIntervalSGI = NULL; + +PFNGLXGETVIDEOSYNCSGIPROC __glewXGetVideoSyncSGI = NULL; +PFNGLXWAITVIDEOSYNCSGIPROC __glewXWaitVideoSyncSGI = NULL; + +PFNGLXGETTRANSPARENTINDEXSUNPROC __glewXGetTransparentIndexSUN = NULL; + +PFNGLXGETVIDEORESIZESUNPROC __glewXGetVideoResizeSUN = NULL; +PFNGLXVIDEORESIZESUNPROC __glewXVideoResizeSUN = NULL; + +#if !defined(GLEW_MX) + +GLboolean __GLXEW_VERSION_1_0 = GL_FALSE; +GLboolean __GLXEW_VERSION_1_1 = GL_FALSE; +GLboolean __GLXEW_VERSION_1_2 = GL_FALSE; +GLboolean __GLXEW_VERSION_1_3 = GL_FALSE; +GLboolean __GLXEW_VERSION_1_4 = GL_FALSE; +GLboolean __GLXEW_3DFX_multisample = GL_FALSE; +GLboolean __GLXEW_ARB_create_context = GL_FALSE; +GLboolean __GLXEW_ARB_fbconfig_float = GL_FALSE; +GLboolean __GLXEW_ARB_framebuffer_sRGB = GL_FALSE; +GLboolean __GLXEW_ARB_get_proc_address = GL_FALSE; +GLboolean __GLXEW_ARB_multisample = GL_FALSE; +GLboolean __GLXEW_ATI_pixel_format_float = GL_FALSE; +GLboolean __GLXEW_ATI_render_texture = GL_FALSE; +GLboolean __GLXEW_EXT_fbconfig_packed_float = GL_FALSE; +GLboolean __GLXEW_EXT_framebuffer_sRGB = GL_FALSE; +GLboolean __GLXEW_EXT_import_context = GL_FALSE; +GLboolean __GLXEW_EXT_scene_marker = GL_FALSE; +GLboolean __GLXEW_EXT_texture_from_pixmap = GL_FALSE; +GLboolean __GLXEW_EXT_visual_info = GL_FALSE; +GLboolean __GLXEW_EXT_visual_rating = GL_FALSE; +GLboolean __GLXEW_MESA_agp_offset = GL_FALSE; +GLboolean __GLXEW_MESA_copy_sub_buffer = GL_FALSE; +GLboolean __GLXEW_MESA_pixmap_colormap = GL_FALSE; +GLboolean __GLXEW_MESA_release_buffers = GL_FALSE; +GLboolean __GLXEW_MESA_set_3dfx_mode = GL_FALSE; +GLboolean __GLXEW_NV_float_buffer = GL_FALSE; +GLboolean __GLXEW_NV_present_video = GL_FALSE; +GLboolean __GLXEW_NV_swap_group = GL_FALSE; +GLboolean __GLXEW_NV_vertex_array_range = GL_FALSE; +GLboolean __GLXEW_NV_video_output = GL_FALSE; +GLboolean __GLXEW_OML_swap_method = GL_FALSE; +#ifdef GLX_OML_sync_control +GLboolean __GLXEW_OML_sync_control = GL_FALSE; +#endif +GLboolean __GLXEW_SGIS_blended_overlay = GL_FALSE; +GLboolean __GLXEW_SGIS_color_range = GL_FALSE; +GLboolean __GLXEW_SGIS_multisample = GL_FALSE; +GLboolean __GLXEW_SGIS_shared_multisample = GL_FALSE; +GLboolean __GLXEW_SGIX_fbconfig = GL_FALSE; +GLboolean __GLXEW_SGIX_hyperpipe = GL_FALSE; +GLboolean __GLXEW_SGIX_pbuffer = GL_FALSE; +GLboolean __GLXEW_SGIX_swap_barrier = GL_FALSE; +GLboolean __GLXEW_SGIX_swap_group = GL_FALSE; +GLboolean __GLXEW_SGIX_video_resize = GL_FALSE; +GLboolean __GLXEW_SGIX_visual_select_group = GL_FALSE; +GLboolean __GLXEW_SGI_cushion = GL_FALSE; +GLboolean __GLXEW_SGI_make_current_read = GL_FALSE; +GLboolean __GLXEW_SGI_swap_control = GL_FALSE; +GLboolean __GLXEW_SGI_video_sync = GL_FALSE; +GLboolean __GLXEW_SUN_get_transparent_index = GL_FALSE; +GLboolean __GLXEW_SUN_video_resize = GL_FALSE; + +#endif /* !GLEW_MX */ + +#ifdef GLX_VERSION_1_2 + +static GLboolean _glewInit_GLX_VERSION_1_2 (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXGetCurrentDisplay = (PFNGLXGETCURRENTDISPLAYPROC)glewGetProcAddress((const GLubyte*)"glXGetCurrentDisplay")) == NULL) || r; + + return r; +} + +#endif /* GLX_VERSION_1_2 */ + +#ifdef GLX_VERSION_1_3 + +static GLboolean _glewInit_GLX_VERSION_1_3 (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC)glewGetProcAddress((const GLubyte*)"glXChooseFBConfig")) == NULL) || r; + r = ((glXCreateNewContext = (PFNGLXCREATENEWCONTEXTPROC)glewGetProcAddress((const GLubyte*)"glXCreateNewContext")) == NULL) || r; + r = ((glXCreatePbuffer = (PFNGLXCREATEPBUFFERPROC)glewGetProcAddress((const GLubyte*)"glXCreatePbuffer")) == NULL) || r; + r = ((glXCreatePixmap = (PFNGLXCREATEPIXMAPPROC)glewGetProcAddress((const GLubyte*)"glXCreatePixmap")) == NULL) || r; + r = ((glXCreateWindow = (PFNGLXCREATEWINDOWPROC)glewGetProcAddress((const GLubyte*)"glXCreateWindow")) == NULL) || r; + r = ((glXDestroyPbuffer = (PFNGLXDESTROYPBUFFERPROC)glewGetProcAddress((const GLubyte*)"glXDestroyPbuffer")) == NULL) || r; + r = ((glXDestroyPixmap = (PFNGLXDESTROYPIXMAPPROC)glewGetProcAddress((const GLubyte*)"glXDestroyPixmap")) == NULL) || r; + r = ((glXDestroyWindow = (PFNGLXDESTROYWINDOWPROC)glewGetProcAddress((const GLubyte*)"glXDestroyWindow")) == NULL) || r; + r = ((glXGetCurrentReadDrawable = (PFNGLXGETCURRENTREADDRAWABLEPROC)glewGetProcAddress((const GLubyte*)"glXGetCurrentReadDrawable")) == NULL) || r; + r = ((glXGetFBConfigAttrib = (PFNGLXGETFBCONFIGATTRIBPROC)glewGetProcAddress((const GLubyte*)"glXGetFBConfigAttrib")) == NULL) || r; + r = ((glXGetFBConfigs = (PFNGLXGETFBCONFIGSPROC)glewGetProcAddress((const GLubyte*)"glXGetFBConfigs")) == NULL) || r; + r = ((glXGetSelectedEvent = (PFNGLXGETSELECTEDEVENTPROC)glewGetProcAddress((const GLubyte*)"glXGetSelectedEvent")) == NULL) || r; + r = ((glXGetVisualFromFBConfig = (PFNGLXGETVISUALFROMFBCONFIGPROC)glewGetProcAddress((const GLubyte*)"glXGetVisualFromFBConfig")) == NULL) || r; + r = ((glXMakeContextCurrent = (PFNGLXMAKECONTEXTCURRENTPROC)glewGetProcAddress((const GLubyte*)"glXMakeContextCurrent")) == NULL) || r; + r = ((glXQueryContext = (PFNGLXQUERYCONTEXTPROC)glewGetProcAddress((const GLubyte*)"glXQueryContext")) == NULL) || r; + r = ((glXQueryDrawable = (PFNGLXQUERYDRAWABLEPROC)glewGetProcAddress((const GLubyte*)"glXQueryDrawable")) == NULL) || r; + r = ((glXSelectEvent = (PFNGLXSELECTEVENTPROC)glewGetProcAddress((const GLubyte*)"glXSelectEvent")) == NULL) || r; + + return r; +} + +#endif /* GLX_VERSION_1_3 */ + +#ifdef GLX_VERSION_1_4 + +#endif /* GLX_VERSION_1_4 */ + +#ifdef GLX_3DFX_multisample + +#endif /* GLX_3DFX_multisample */ + +#ifdef GLX_ARB_create_context + +static GLboolean _glewInit_GLX_ARB_create_context (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)glewGetProcAddress((const GLubyte*)"glXCreateContextAttribsARB")) == NULL) || r; + + return r; +} + +#endif /* GLX_ARB_create_context */ + +#ifdef GLX_ARB_fbconfig_float + +#endif /* GLX_ARB_fbconfig_float */ + +#ifdef GLX_ARB_framebuffer_sRGB + +#endif /* GLX_ARB_framebuffer_sRGB */ + +#ifdef GLX_ARB_get_proc_address + +#endif /* GLX_ARB_get_proc_address */ + +#ifdef GLX_ARB_multisample + +#endif /* GLX_ARB_multisample */ + +#ifdef GLX_ATI_pixel_format_float + +#endif /* GLX_ATI_pixel_format_float */ + +#ifdef GLX_ATI_render_texture + +static GLboolean _glewInit_GLX_ATI_render_texture (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXBindTexImageATI = (PFNGLXBINDTEXIMAGEATIPROC)glewGetProcAddress((const GLubyte*)"glXBindTexImageATI")) == NULL) || r; + r = ((glXDrawableAttribATI = (PFNGLXDRAWABLEATTRIBATIPROC)glewGetProcAddress((const GLubyte*)"glXDrawableAttribATI")) == NULL) || r; + r = ((glXReleaseTexImageATI = (PFNGLXRELEASETEXIMAGEATIPROC)glewGetProcAddress((const GLubyte*)"glXReleaseTexImageATI")) == NULL) || r; + + return r; +} + +#endif /* GLX_ATI_render_texture */ + +#ifdef GLX_EXT_fbconfig_packed_float + +#endif /* GLX_EXT_fbconfig_packed_float */ + +#ifdef GLX_EXT_framebuffer_sRGB + +#endif /* GLX_EXT_framebuffer_sRGB */ + +#ifdef GLX_EXT_import_context + +static GLboolean _glewInit_GLX_EXT_import_context (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXFreeContextEXT = (PFNGLXFREECONTEXTEXTPROC)glewGetProcAddress((const GLubyte*)"glXFreeContextEXT")) == NULL) || r; + r = ((glXGetContextIDEXT = (PFNGLXGETCONTEXTIDEXTPROC)glewGetProcAddress((const GLubyte*)"glXGetContextIDEXT")) == NULL) || r; + r = ((glXImportContextEXT = (PFNGLXIMPORTCONTEXTEXTPROC)glewGetProcAddress((const GLubyte*)"glXImportContextEXT")) == NULL) || r; + r = ((glXQueryContextInfoEXT = (PFNGLXQUERYCONTEXTINFOEXTPROC)glewGetProcAddress((const GLubyte*)"glXQueryContextInfoEXT")) == NULL) || r; + + return r; +} + +#endif /* GLX_EXT_import_context */ + +#ifdef GLX_EXT_scene_marker + +#endif /* GLX_EXT_scene_marker */ + +#ifdef GLX_EXT_texture_from_pixmap + +static GLboolean _glewInit_GLX_EXT_texture_from_pixmap (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXBindTexImageEXT = (PFNGLXBINDTEXIMAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glXBindTexImageEXT")) == NULL) || r; + r = ((glXReleaseTexImageEXT = (PFNGLXRELEASETEXIMAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glXReleaseTexImageEXT")) == NULL) || r; + + return r; +} + +#endif /* GLX_EXT_texture_from_pixmap */ + +#ifdef GLX_EXT_visual_info + +#endif /* GLX_EXT_visual_info */ + +#ifdef GLX_EXT_visual_rating + +#endif /* GLX_EXT_visual_rating */ + +#ifdef GLX_MESA_agp_offset + +static GLboolean _glewInit_GLX_MESA_agp_offset (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXGetAGPOffsetMESA = (PFNGLXGETAGPOFFSETMESAPROC)glewGetProcAddress((const GLubyte*)"glXGetAGPOffsetMESA")) == NULL) || r; + + return r; +} + +#endif /* GLX_MESA_agp_offset */ + +#ifdef GLX_MESA_copy_sub_buffer + +static GLboolean _glewInit_GLX_MESA_copy_sub_buffer (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXCopySubBufferMESA = (PFNGLXCOPYSUBBUFFERMESAPROC)glewGetProcAddress((const GLubyte*)"glXCopySubBufferMESA")) == NULL) || r; + + return r; +} + +#endif /* GLX_MESA_copy_sub_buffer */ + +#ifdef GLX_MESA_pixmap_colormap + +static GLboolean _glewInit_GLX_MESA_pixmap_colormap (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXCreateGLXPixmapMESA = (PFNGLXCREATEGLXPIXMAPMESAPROC)glewGetProcAddress((const GLubyte*)"glXCreateGLXPixmapMESA")) == NULL) || r; + + return r; +} + +#endif /* GLX_MESA_pixmap_colormap */ + +#ifdef GLX_MESA_release_buffers + +static GLboolean _glewInit_GLX_MESA_release_buffers (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXReleaseBuffersMESA = (PFNGLXRELEASEBUFFERSMESAPROC)glewGetProcAddress((const GLubyte*)"glXReleaseBuffersMESA")) == NULL) || r; + + return r; +} + +#endif /* GLX_MESA_release_buffers */ + +#ifdef GLX_MESA_set_3dfx_mode + +static GLboolean _glewInit_GLX_MESA_set_3dfx_mode (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXSet3DfxModeMESA = (PFNGLXSET3DFXMODEMESAPROC)glewGetProcAddress((const GLubyte*)"glXSet3DfxModeMESA")) == NULL) || r; + + return r; +} + +#endif /* GLX_MESA_set_3dfx_mode */ + +#ifdef GLX_NV_float_buffer + +#endif /* GLX_NV_float_buffer */ + +#ifdef GLX_NV_present_video + +static GLboolean _glewInit_GLX_NV_present_video (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXBindVideoDeviceNV = (PFNGLXBINDVIDEODEVICENVPROC)glewGetProcAddress((const GLubyte*)"glXBindVideoDeviceNV")) == NULL) || r; + r = ((glXEnumerateVideoDevicesNV = (PFNGLXENUMERATEVIDEODEVICESNVPROC)glewGetProcAddress((const GLubyte*)"glXEnumerateVideoDevicesNV")) == NULL) || r; + + return r; +} + +#endif /* GLX_NV_present_video */ + +#ifdef GLX_NV_swap_group + +static GLboolean _glewInit_GLX_NV_swap_group (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXBindSwapBarrierNV = (PFNGLXBINDSWAPBARRIERNVPROC)glewGetProcAddress((const GLubyte*)"glXBindSwapBarrierNV")) == NULL) || r; + r = ((glXJoinSwapGroupNV = (PFNGLXJOINSWAPGROUPNVPROC)glewGetProcAddress((const GLubyte*)"glXJoinSwapGroupNV")) == NULL) || r; + r = ((glXQueryFrameCountNV = (PFNGLXQUERYFRAMECOUNTNVPROC)glewGetProcAddress((const GLubyte*)"glXQueryFrameCountNV")) == NULL) || r; + r = ((glXQueryMaxSwapGroupsNV = (PFNGLXQUERYMAXSWAPGROUPSNVPROC)glewGetProcAddress((const GLubyte*)"glXQueryMaxSwapGroupsNV")) == NULL) || r; + r = ((glXQuerySwapGroupNV = (PFNGLXQUERYSWAPGROUPNVPROC)glewGetProcAddress((const GLubyte*)"glXQuerySwapGroupNV")) == NULL) || r; + r = ((glXResetFrameCountNV = (PFNGLXRESETFRAMECOUNTNVPROC)glewGetProcAddress((const GLubyte*)"glXResetFrameCountNV")) == NULL) || r; + + return r; +} + +#endif /* GLX_NV_swap_group */ + +#ifdef GLX_NV_vertex_array_range + +static GLboolean _glewInit_GLX_NV_vertex_array_range (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXAllocateMemoryNV = (PFNGLXALLOCATEMEMORYNVPROC)glewGetProcAddress((const GLubyte*)"glXAllocateMemoryNV")) == NULL) || r; + r = ((glXFreeMemoryNV = (PFNGLXFREEMEMORYNVPROC)glewGetProcAddress((const GLubyte*)"glXFreeMemoryNV")) == NULL) || r; + + return r; +} + +#endif /* GLX_NV_vertex_array_range */ + +#ifdef GLX_NV_video_output + +static GLboolean _glewInit_GLX_NV_video_output (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXBindVideoImageNV = (PFNGLXBINDVIDEOIMAGENVPROC)glewGetProcAddress((const GLubyte*)"glXBindVideoImageNV")) == NULL) || r; + r = ((glXGetVideoDeviceNV = (PFNGLXGETVIDEODEVICENVPROC)glewGetProcAddress((const GLubyte*)"glXGetVideoDeviceNV")) == NULL) || r; + r = ((glXGetVideoInfoNV = (PFNGLXGETVIDEOINFONVPROC)glewGetProcAddress((const GLubyte*)"glXGetVideoInfoNV")) == NULL) || r; + r = ((glXReleaseVideoDeviceNV = (PFNGLXRELEASEVIDEODEVICENVPROC)glewGetProcAddress((const GLubyte*)"glXReleaseVideoDeviceNV")) == NULL) || r; + r = ((glXReleaseVideoImageNV = (PFNGLXRELEASEVIDEOIMAGENVPROC)glewGetProcAddress((const GLubyte*)"glXReleaseVideoImageNV")) == NULL) || r; + r = ((glXSendPbufferToVideoNV = (PFNGLXSENDPBUFFERTOVIDEONVPROC)glewGetProcAddress((const GLubyte*)"glXSendPbufferToVideoNV")) == NULL) || r; + + return r; +} + +#endif /* GLX_NV_video_output */ + +#ifdef GLX_OML_swap_method + +#endif /* GLX_OML_swap_method */ + +#if defined(GLX_OML_sync_control) && defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +#include <inttypes.h> + +static GLboolean _glewInit_GLX_OML_sync_control (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXGetMscRateOML = (PFNGLXGETMSCRATEOMLPROC)glewGetProcAddress((const GLubyte*)"glXGetMscRateOML")) == NULL) || r; + r = ((glXGetSyncValuesOML = (PFNGLXGETSYNCVALUESOMLPROC)glewGetProcAddress((const GLubyte*)"glXGetSyncValuesOML")) == NULL) || r; + r = ((glXSwapBuffersMscOML = (PFNGLXSWAPBUFFERSMSCOMLPROC)glewGetProcAddress((const GLubyte*)"glXSwapBuffersMscOML")) == NULL) || r; + r = ((glXWaitForMscOML = (PFNGLXWAITFORMSCOMLPROC)glewGetProcAddress((const GLubyte*)"glXWaitForMscOML")) == NULL) || r; + r = ((glXWaitForSbcOML = (PFNGLXWAITFORSBCOMLPROC)glewGetProcAddress((const GLubyte*)"glXWaitForSbcOML")) == NULL) || r; + + return r; +} + +#endif /* GLX_OML_sync_control */ + +#ifdef GLX_SGIS_blended_overlay + +#endif /* GLX_SGIS_blended_overlay */ + +#ifdef GLX_SGIS_color_range + +#endif /* GLX_SGIS_color_range */ + +#ifdef GLX_SGIS_multisample + +#endif /* GLX_SGIS_multisample */ + +#ifdef GLX_SGIS_shared_multisample + +#endif /* GLX_SGIS_shared_multisample */ + +#ifdef GLX_SGIX_fbconfig + +static GLboolean _glewInit_GLX_SGIX_fbconfig (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXChooseFBConfigSGIX = (PFNGLXCHOOSEFBCONFIGSGIXPROC)glewGetProcAddress((const GLubyte*)"glXChooseFBConfigSGIX")) == NULL) || r; + r = ((glXCreateContextWithConfigSGIX = (PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC)glewGetProcAddress((const GLubyte*)"glXCreateContextWithConfigSGIX")) == NULL) || r; + r = ((glXCreateGLXPixmapWithConfigSGIX = (PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC)glewGetProcAddress((const GLubyte*)"glXCreateGLXPixmapWithConfigSGIX")) == NULL) || r; + r = ((glXGetFBConfigAttribSGIX = (PFNGLXGETFBCONFIGATTRIBSGIXPROC)glewGetProcAddress((const GLubyte*)"glXGetFBConfigAttribSGIX")) == NULL) || r; + r = ((glXGetFBConfigFromVisualSGIX = (PFNGLXGETFBCONFIGFROMVISUALSGIXPROC)glewGetProcAddress((const GLubyte*)"glXGetFBConfigFromVisualSGIX")) == NULL) || r; + r = ((glXGetVisualFromFBConfigSGIX = (PFNGLXGETVISUALFROMFBCONFIGSGIXPROC)glewGetProcAddress((const GLubyte*)"glXGetVisualFromFBConfigSGIX")) == NULL) || r; + + return r; +} + +#endif /* GLX_SGIX_fbconfig */ + +#ifdef GLX_SGIX_hyperpipe + +static GLboolean _glewInit_GLX_SGIX_hyperpipe (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXBindHyperpipeSGIX = (PFNGLXBINDHYPERPIPESGIXPROC)glewGetProcAddress((const GLubyte*)"glXBindHyperpipeSGIX")) == NULL) || r; + r = ((glXDestroyHyperpipeConfigSGIX = (PFNGLXDESTROYHYPERPIPECONFIGSGIXPROC)glewGetProcAddress((const GLubyte*)"glXDestroyHyperpipeConfigSGIX")) == NULL) || r; + r = ((glXHyperpipeAttribSGIX = (PFNGLXHYPERPIPEATTRIBSGIXPROC)glewGetProcAddress((const GLubyte*)"glXHyperpipeAttribSGIX")) == NULL) || r; + r = ((glXHyperpipeConfigSGIX = (PFNGLXHYPERPIPECONFIGSGIXPROC)glewGetProcAddress((const GLubyte*)"glXHyperpipeConfigSGIX")) == NULL) || r; + r = ((glXQueryHyperpipeAttribSGIX = (PFNGLXQUERYHYPERPIPEATTRIBSGIXPROC)glewGetProcAddress((const GLubyte*)"glXQueryHyperpipeAttribSGIX")) == NULL) || r; + r = ((glXQueryHyperpipeBestAttribSGIX = (PFNGLXQUERYHYPERPIPEBESTATTRIBSGIXPROC)glewGetProcAddress((const GLubyte*)"glXQueryHyperpipeBestAttribSGIX")) == NULL) || r; + r = ((glXQueryHyperpipeConfigSGIX = (PFNGLXQUERYHYPERPIPECONFIGSGIXPROC)glewGetProcAddress((const GLubyte*)"glXQueryHyperpipeConfigSGIX")) == NULL) || r; + r = ((glXQueryHyperpipeNetworkSGIX = (PFNGLXQUERYHYPERPIPENETWORKSGIXPROC)glewGetProcAddress((const GLubyte*)"glXQueryHyperpipeNetworkSGIX")) == NULL) || r; + + return r; +} + +#endif /* GLX_SGIX_hyperpipe */ + +#ifdef GLX_SGIX_pbuffer + +static GLboolean _glewInit_GLX_SGIX_pbuffer (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXCreateGLXPbufferSGIX = (PFNGLXCREATEGLXPBUFFERSGIXPROC)glewGetProcAddress((const GLubyte*)"glXCreateGLXPbufferSGIX")) == NULL) || r; + r = ((glXDestroyGLXPbufferSGIX = (PFNGLXDESTROYGLXPBUFFERSGIXPROC)glewGetProcAddress((const GLubyte*)"glXDestroyGLXPbufferSGIX")) == NULL) || r; + r = ((glXGetSelectedEventSGIX = (PFNGLXGETSELECTEDEVENTSGIXPROC)glewGetProcAddress((const GLubyte*)"glXGetSelectedEventSGIX")) == NULL) || r; + r = ((glXQueryGLXPbufferSGIX = (PFNGLXQUERYGLXPBUFFERSGIXPROC)glewGetProcAddress((const GLubyte*)"glXQueryGLXPbufferSGIX")) == NULL) || r; + r = ((glXSelectEventSGIX = (PFNGLXSELECTEVENTSGIXPROC)glewGetProcAddress((const GLubyte*)"glXSelectEventSGIX")) == NULL) || r; + + return r; +} + +#endif /* GLX_SGIX_pbuffer */ + +#ifdef GLX_SGIX_swap_barrier + +static GLboolean _glewInit_GLX_SGIX_swap_barrier (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXBindSwapBarrierSGIX = (PFNGLXBINDSWAPBARRIERSGIXPROC)glewGetProcAddress((const GLubyte*)"glXBindSwapBarrierSGIX")) == NULL) || r; + r = ((glXQueryMaxSwapBarriersSGIX = (PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC)glewGetProcAddress((const GLubyte*)"glXQueryMaxSwapBarriersSGIX")) == NULL) || r; + + return r; +} + +#endif /* GLX_SGIX_swap_barrier */ + +#ifdef GLX_SGIX_swap_group + +static GLboolean _glewInit_GLX_SGIX_swap_group (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXJoinSwapGroupSGIX = (PFNGLXJOINSWAPGROUPSGIXPROC)glewGetProcAddress((const GLubyte*)"glXJoinSwapGroupSGIX")) == NULL) || r; + + return r; +} + +#endif /* GLX_SGIX_swap_group */ + +#ifdef GLX_SGIX_video_resize + +static GLboolean _glewInit_GLX_SGIX_video_resize (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXBindChannelToWindowSGIX = (PFNGLXBINDCHANNELTOWINDOWSGIXPROC)glewGetProcAddress((const GLubyte*)"glXBindChannelToWindowSGIX")) == NULL) || r; + r = ((glXChannelRectSGIX = (PFNGLXCHANNELRECTSGIXPROC)glewGetProcAddress((const GLubyte*)"glXChannelRectSGIX")) == NULL) || r; + r = ((glXChannelRectSyncSGIX = (PFNGLXCHANNELRECTSYNCSGIXPROC)glewGetProcAddress((const GLubyte*)"glXChannelRectSyncSGIX")) == NULL) || r; + r = ((glXQueryChannelDeltasSGIX = (PFNGLXQUERYCHANNELDELTASSGIXPROC)glewGetProcAddress((const GLubyte*)"glXQueryChannelDeltasSGIX")) == NULL) || r; + r = ((glXQueryChannelRectSGIX = (PFNGLXQUERYCHANNELRECTSGIXPROC)glewGetProcAddress((const GLubyte*)"glXQueryChannelRectSGIX")) == NULL) || r; + + return r; +} + +#endif /* GLX_SGIX_video_resize */ + +#ifdef GLX_SGIX_visual_select_group + +#endif /* GLX_SGIX_visual_select_group */ + +#ifdef GLX_SGI_cushion + +static GLboolean _glewInit_GLX_SGI_cushion (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXCushionSGI = (PFNGLXCUSHIONSGIPROC)glewGetProcAddress((const GLubyte*)"glXCushionSGI")) == NULL) || r; + + return r; +} + +#endif /* GLX_SGI_cushion */ + +#ifdef GLX_SGI_make_current_read + +static GLboolean _glewInit_GLX_SGI_make_current_read (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXGetCurrentReadDrawableSGI = (PFNGLXGETCURRENTREADDRAWABLESGIPROC)glewGetProcAddress((const GLubyte*)"glXGetCurrentReadDrawableSGI")) == NULL) || r; + r = ((glXMakeCurrentReadSGI = (PFNGLXMAKECURRENTREADSGIPROC)glewGetProcAddress((const GLubyte*)"glXMakeCurrentReadSGI")) == NULL) || r; + + return r; +} + +#endif /* GLX_SGI_make_current_read */ + +#ifdef GLX_SGI_swap_control + +static GLboolean _glewInit_GLX_SGI_swap_control (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXSwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC)glewGetProcAddress((const GLubyte*)"glXSwapIntervalSGI")) == NULL) || r; + + return r; +} + +#endif /* GLX_SGI_swap_control */ + +#ifdef GLX_SGI_video_sync + +static GLboolean _glewInit_GLX_SGI_video_sync (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXGetVideoSyncSGI = (PFNGLXGETVIDEOSYNCSGIPROC)glewGetProcAddress((const GLubyte*)"glXGetVideoSyncSGI")) == NULL) || r; + r = ((glXWaitVideoSyncSGI = (PFNGLXWAITVIDEOSYNCSGIPROC)glewGetProcAddress((const GLubyte*)"glXWaitVideoSyncSGI")) == NULL) || r; + + return r; +} + +#endif /* GLX_SGI_video_sync */ + +#ifdef GLX_SUN_get_transparent_index + +static GLboolean _glewInit_GLX_SUN_get_transparent_index (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXGetTransparentIndexSUN = (PFNGLXGETTRANSPARENTINDEXSUNPROC)glewGetProcAddress((const GLubyte*)"glXGetTransparentIndexSUN")) == NULL) || r; + + return r; +} + +#endif /* GLX_SUN_get_transparent_index */ + +#ifdef GLX_SUN_video_resize + +static GLboolean _glewInit_GLX_SUN_video_resize (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXGetVideoResizeSUN = (PFNGLXGETVIDEORESIZESUNPROC)glewGetProcAddress((const GLubyte*)"glXGetVideoResizeSUN")) == NULL) || r; + r = ((glXVideoResizeSUN = (PFNGLXVIDEORESIZESUNPROC)glewGetProcAddress((const GLubyte*)"glXVideoResizeSUN")) == NULL) || r; + + return r; +} + +#endif /* GLX_SUN_video_resize */ + +/* ------------------------------------------------------------------------ */ + +GLboolean glxewGetExtension (const char* name) +{ + GLubyte* p; + GLubyte* end; + GLuint len = _glewStrLen((const GLubyte*)name); +/* if (glXQueryExtensionsString == NULL || glXGetCurrentDisplay == NULL) return GL_FALSE; */ +/* p = (GLubyte*)glXQueryExtensionsString(glXGetCurrentDisplay(), DefaultScreen(glXGetCurrentDisplay())); */ + if (glXGetClientString == NULL || glXGetCurrentDisplay == NULL) return GL_FALSE; + p = (GLubyte*)glXGetClientString(glXGetCurrentDisplay(), GLX_EXTENSIONS); + if (0 == p) return GL_FALSE; + end = p + _glewStrLen(p); + while (p < end) + { + GLuint n = _glewStrCLen(p, ' '); + if (len == n && _glewStrSame((const GLubyte*)name, p, n)) return GL_TRUE; + p += n+1; + } + return GL_FALSE; +} + +GLenum glxewContextInit (GLXEW_CONTEXT_ARG_DEF_LIST) +{ + int major, minor; + /* initialize core GLX 1.2 */ + if (_glewInit_GLX_VERSION_1_2(GLEW_CONTEXT_ARG_VAR_INIT)) return GLEW_ERROR_GLX_VERSION_11_ONLY; + /* initialize flags */ + CONST_CAST(GLXEW_VERSION_1_0) = GL_TRUE; + CONST_CAST(GLXEW_VERSION_1_1) = GL_TRUE; + CONST_CAST(GLXEW_VERSION_1_2) = GL_TRUE; + CONST_CAST(GLXEW_VERSION_1_3) = GL_TRUE; + CONST_CAST(GLXEW_VERSION_1_4) = GL_TRUE; + /* query GLX version */ + glXQueryVersion(glXGetCurrentDisplay(), &major, &minor); + if (major == 1 && minor <= 3) + { + switch (minor) + { + case 3: + CONST_CAST(GLXEW_VERSION_1_4) = GL_FALSE; + break; + case 2: + CONST_CAST(GLXEW_VERSION_1_4) = GL_FALSE; + CONST_CAST(GLXEW_VERSION_1_3) = GL_FALSE; + break; + default: + return GLEW_ERROR_GLX_VERSION_11_ONLY; + break; + } + } + /* initialize extensions */ +#ifdef GLX_VERSION_1_3 + if (glewExperimental || GLXEW_VERSION_1_3) CONST_CAST(GLXEW_VERSION_1_3) = !_glewInit_GLX_VERSION_1_3(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_VERSION_1_3 */ +#ifdef GLX_3DFX_multisample + CONST_CAST(GLXEW_3DFX_multisample) = glxewGetExtension("GLX_3DFX_multisample"); +#endif /* GLX_3DFX_multisample */ +#ifdef GLX_ARB_create_context + CONST_CAST(GLXEW_ARB_create_context) = glxewGetExtension("GLX_ARB_create_context"); + if (glewExperimental || GLXEW_ARB_create_context) CONST_CAST(GLXEW_ARB_create_context) = !_glewInit_GLX_ARB_create_context(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_ARB_create_context */ +#ifdef GLX_ARB_fbconfig_float + CONST_CAST(GLXEW_ARB_fbconfig_float) = glxewGetExtension("GLX_ARB_fbconfig_float"); +#endif /* GLX_ARB_fbconfig_float */ +#ifdef GLX_ARB_framebuffer_sRGB + CONST_CAST(GLXEW_ARB_framebuffer_sRGB) = glxewGetExtension("GLX_ARB_framebuffer_sRGB"); +#endif /* GLX_ARB_framebuffer_sRGB */ +#ifdef GLX_ARB_get_proc_address + CONST_CAST(GLXEW_ARB_get_proc_address) = glxewGetExtension("GLX_ARB_get_proc_address"); +#endif /* GLX_ARB_get_proc_address */ +#ifdef GLX_ARB_multisample + CONST_CAST(GLXEW_ARB_multisample) = glxewGetExtension("GLX_ARB_multisample"); +#endif /* GLX_ARB_multisample */ +#ifdef GLX_ATI_pixel_format_float + CONST_CAST(GLXEW_ATI_pixel_format_float) = glxewGetExtension("GLX_ATI_pixel_format_float"); +#endif /* GLX_ATI_pixel_format_float */ +#ifdef GLX_ATI_render_texture + CONST_CAST(GLXEW_ATI_render_texture) = glxewGetExtension("GLX_ATI_render_texture"); + if (glewExperimental || GLXEW_ATI_render_texture) CONST_CAST(GLXEW_ATI_render_texture) = !_glewInit_GLX_ATI_render_texture(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_ATI_render_texture */ +#ifdef GLX_EXT_fbconfig_packed_float + CONST_CAST(GLXEW_EXT_fbconfig_packed_float) = glxewGetExtension("GLX_EXT_fbconfig_packed_float"); +#endif /* GLX_EXT_fbconfig_packed_float */ +#ifdef GLX_EXT_framebuffer_sRGB + CONST_CAST(GLXEW_EXT_framebuffer_sRGB) = glxewGetExtension("GLX_EXT_framebuffer_sRGB"); +#endif /* GLX_EXT_framebuffer_sRGB */ +#ifdef GLX_EXT_import_context + CONST_CAST(GLXEW_EXT_import_context) = glxewGetExtension("GLX_EXT_import_context"); + if (glewExperimental || GLXEW_EXT_import_context) CONST_CAST(GLXEW_EXT_import_context) = !_glewInit_GLX_EXT_import_context(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_EXT_import_context */ +#ifdef GLX_EXT_scene_marker + CONST_CAST(GLXEW_EXT_scene_marker) = glxewGetExtension("GLX_EXT_scene_marker"); +#endif /* GLX_EXT_scene_marker */ +#ifdef GLX_EXT_texture_from_pixmap + CONST_CAST(GLXEW_EXT_texture_from_pixmap) = glxewGetExtension("GLX_EXT_texture_from_pixmap"); + if (glewExperimental || GLXEW_EXT_texture_from_pixmap) CONST_CAST(GLXEW_EXT_texture_from_pixmap) = !_glewInit_GLX_EXT_texture_from_pixmap(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_EXT_texture_from_pixmap */ +#ifdef GLX_EXT_visual_info + CONST_CAST(GLXEW_EXT_visual_info) = glxewGetExtension("GLX_EXT_visual_info"); +#endif /* GLX_EXT_visual_info */ +#ifdef GLX_EXT_visual_rating + CONST_CAST(GLXEW_EXT_visual_rating) = glxewGetExtension("GLX_EXT_visual_rating"); +#endif /* GLX_EXT_visual_rating */ +#ifdef GLX_MESA_agp_offset + CONST_CAST(GLXEW_MESA_agp_offset) = glxewGetExtension("GLX_MESA_agp_offset"); + if (glewExperimental || GLXEW_MESA_agp_offset) CONST_CAST(GLXEW_MESA_agp_offset) = !_glewInit_GLX_MESA_agp_offset(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_MESA_agp_offset */ +#ifdef GLX_MESA_copy_sub_buffer + CONST_CAST(GLXEW_MESA_copy_sub_buffer) = glxewGetExtension("GLX_MESA_copy_sub_buffer"); + if (glewExperimental || GLXEW_MESA_copy_sub_buffer) CONST_CAST(GLXEW_MESA_copy_sub_buffer) = !_glewInit_GLX_MESA_copy_sub_buffer(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_MESA_copy_sub_buffer */ +#ifdef GLX_MESA_pixmap_colormap + CONST_CAST(GLXEW_MESA_pixmap_colormap) = glxewGetExtension("GLX_MESA_pixmap_colormap"); + if (glewExperimental || GLXEW_MESA_pixmap_colormap) CONST_CAST(GLXEW_MESA_pixmap_colormap) = !_glewInit_GLX_MESA_pixmap_colormap(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_MESA_pixmap_colormap */ +#ifdef GLX_MESA_release_buffers + CONST_CAST(GLXEW_MESA_release_buffers) = glxewGetExtension("GLX_MESA_release_buffers"); + if (glewExperimental || GLXEW_MESA_release_buffers) CONST_CAST(GLXEW_MESA_release_buffers) = !_glewInit_GLX_MESA_release_buffers(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_MESA_release_buffers */ +#ifdef GLX_MESA_set_3dfx_mode + CONST_CAST(GLXEW_MESA_set_3dfx_mode) = glxewGetExtension("GLX_MESA_set_3dfx_mode"); + if (glewExperimental || GLXEW_MESA_set_3dfx_mode) CONST_CAST(GLXEW_MESA_set_3dfx_mode) = !_glewInit_GLX_MESA_set_3dfx_mode(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_MESA_set_3dfx_mode */ +#ifdef GLX_NV_float_buffer + CONST_CAST(GLXEW_NV_float_buffer) = glxewGetExtension("GLX_NV_float_buffer"); +#endif /* GLX_NV_float_buffer */ +#ifdef GLX_NV_present_video + CONST_CAST(GLXEW_NV_present_video) = glxewGetExtension("GLX_NV_present_video"); + if (glewExperimental || GLXEW_NV_present_video) CONST_CAST(GLXEW_NV_present_video) = !_glewInit_GLX_NV_present_video(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_NV_present_video */ +#ifdef GLX_NV_swap_group + CONST_CAST(GLXEW_NV_swap_group) = glxewGetExtension("GLX_NV_swap_group"); + if (glewExperimental || GLXEW_NV_swap_group) CONST_CAST(GLXEW_NV_swap_group) = !_glewInit_GLX_NV_swap_group(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_NV_swap_group */ +#ifdef GLX_NV_vertex_array_range + CONST_CAST(GLXEW_NV_vertex_array_range) = glxewGetExtension("GLX_NV_vertex_array_range"); + if (glewExperimental || GLXEW_NV_vertex_array_range) CONST_CAST(GLXEW_NV_vertex_array_range) = !_glewInit_GLX_NV_vertex_array_range(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_NV_vertex_array_range */ +#ifdef GLX_NV_video_output + CONST_CAST(GLXEW_NV_video_output) = glxewGetExtension("GLX_NV_video_output"); + if (glewExperimental || GLXEW_NV_video_output) CONST_CAST(GLXEW_NV_video_output) = !_glewInit_GLX_NV_video_output(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_NV_video_output */ +#ifdef GLX_OML_swap_method + CONST_CAST(GLXEW_OML_swap_method) = glxewGetExtension("GLX_OML_swap_method"); +#endif /* GLX_OML_swap_method */ +#if defined(GLX_OML_sync_control) && defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +#include <inttypes.h> + CONST_CAST(GLXEW_OML_sync_control) = glxewGetExtension("GLX_OML_sync_control"); + if (glewExperimental || GLXEW_OML_sync_control) CONST_CAST(GLXEW_OML_sync_control) = !_glewInit_GLX_OML_sync_control(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_OML_sync_control */ +#ifdef GLX_SGIS_blended_overlay + CONST_CAST(GLXEW_SGIS_blended_overlay) = glxewGetExtension("GLX_SGIS_blended_overlay"); +#endif /* GLX_SGIS_blended_overlay */ +#ifdef GLX_SGIS_color_range + CONST_CAST(GLXEW_SGIS_color_range) = glxewGetExtension("GLX_SGIS_color_range"); +#endif /* GLX_SGIS_color_range */ +#ifdef GLX_SGIS_multisample + CONST_CAST(GLXEW_SGIS_multisample) = glxewGetExtension("GLX_SGIS_multisample"); +#endif /* GLX_SGIS_multisample */ +#ifdef GLX_SGIS_shared_multisample + CONST_CAST(GLXEW_SGIS_shared_multisample) = glxewGetExtension("GLX_SGIS_shared_multisample"); +#endif /* GLX_SGIS_shared_multisample */ +#ifdef GLX_SGIX_fbconfig + CONST_CAST(GLXEW_SGIX_fbconfig) = glxewGetExtension("GLX_SGIX_fbconfig"); + if (glewExperimental || GLXEW_SGIX_fbconfig) CONST_CAST(GLXEW_SGIX_fbconfig) = !_glewInit_GLX_SGIX_fbconfig(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_SGIX_fbconfig */ +#ifdef GLX_SGIX_hyperpipe + CONST_CAST(GLXEW_SGIX_hyperpipe) = glxewGetExtension("GLX_SGIX_hyperpipe"); + if (glewExperimental || GLXEW_SGIX_hyperpipe) CONST_CAST(GLXEW_SGIX_hyperpipe) = !_glewInit_GLX_SGIX_hyperpipe(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_SGIX_hyperpipe */ +#ifdef GLX_SGIX_pbuffer + CONST_CAST(GLXEW_SGIX_pbuffer) = glxewGetExtension("GLX_SGIX_pbuffer"); + if (glewExperimental || GLXEW_SGIX_pbuffer) CONST_CAST(GLXEW_SGIX_pbuffer) = !_glewInit_GLX_SGIX_pbuffer(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_SGIX_pbuffer */ +#ifdef GLX_SGIX_swap_barrier + CONST_CAST(GLXEW_SGIX_swap_barrier) = glxewGetExtension("GLX_SGIX_swap_barrier"); + if (glewExperimental || GLXEW_SGIX_swap_barrier) CONST_CAST(GLXEW_SGIX_swap_barrier) = !_glewInit_GLX_SGIX_swap_barrier(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_SGIX_swap_barrier */ +#ifdef GLX_SGIX_swap_group + CONST_CAST(GLXEW_SGIX_swap_group) = glxewGetExtension("GLX_SGIX_swap_group"); + if (glewExperimental || GLXEW_SGIX_swap_group) CONST_CAST(GLXEW_SGIX_swap_group) = !_glewInit_GLX_SGIX_swap_group(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_SGIX_swap_group */ +#ifdef GLX_SGIX_video_resize + CONST_CAST(GLXEW_SGIX_video_resize) = glxewGetExtension("GLX_SGIX_video_resize"); + if (glewExperimental || GLXEW_SGIX_video_resize) CONST_CAST(GLXEW_SGIX_video_resize) = !_glewInit_GLX_SGIX_video_resize(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_SGIX_video_resize */ +#ifdef GLX_SGIX_visual_select_group + CONST_CAST(GLXEW_SGIX_visual_select_group) = glxewGetExtension("GLX_SGIX_visual_select_group"); +#endif /* GLX_SGIX_visual_select_group */ +#ifdef GLX_SGI_cushion + CONST_CAST(GLXEW_SGI_cushion) = glxewGetExtension("GLX_SGI_cushion"); + if (glewExperimental || GLXEW_SGI_cushion) CONST_CAST(GLXEW_SGI_cushion) = !_glewInit_GLX_SGI_cushion(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_SGI_cushion */ +#ifdef GLX_SGI_make_current_read + CONST_CAST(GLXEW_SGI_make_current_read) = glxewGetExtension("GLX_SGI_make_current_read"); + if (glewExperimental || GLXEW_SGI_make_current_read) CONST_CAST(GLXEW_SGI_make_current_read) = !_glewInit_GLX_SGI_make_current_read(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_SGI_make_current_read */ +#ifdef GLX_SGI_swap_control + CONST_CAST(GLXEW_SGI_swap_control) = glxewGetExtension("GLX_SGI_swap_control"); + if (glewExperimental || GLXEW_SGI_swap_control) CONST_CAST(GLXEW_SGI_swap_control) = !_glewInit_GLX_SGI_swap_control(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_SGI_swap_control */ +#ifdef GLX_SGI_video_sync + CONST_CAST(GLXEW_SGI_video_sync) = glxewGetExtension("GLX_SGI_video_sync"); + if (glewExperimental || GLXEW_SGI_video_sync) CONST_CAST(GLXEW_SGI_video_sync) = !_glewInit_GLX_SGI_video_sync(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_SGI_video_sync */ +#ifdef GLX_SUN_get_transparent_index + CONST_CAST(GLXEW_SUN_get_transparent_index) = glxewGetExtension("GLX_SUN_get_transparent_index"); + if (glewExperimental || GLXEW_SUN_get_transparent_index) CONST_CAST(GLXEW_SUN_get_transparent_index) = !_glewInit_GLX_SUN_get_transparent_index(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_SUN_get_transparent_index */ +#ifdef GLX_SUN_video_resize + CONST_CAST(GLXEW_SUN_video_resize) = glxewGetExtension("GLX_SUN_video_resize"); + if (glewExperimental || GLXEW_SUN_video_resize) CONST_CAST(GLXEW_SUN_video_resize) = !_glewInit_GLX_SUN_video_resize(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_SUN_video_resize */ + + return GLEW_OK; +} + +#endif /* !__APPLE__ || GLEW_APPLE_GLX */ + +/* ------------------------------------------------------------------------ */ + +const GLubyte* glewGetErrorString (GLenum error) +{ + static const GLubyte* _glewErrorString[] = + { + (const GLubyte*)"No error", + (const GLubyte*)"Missing GL version", + (const GLubyte*)"GL 1.1 and up are not supported", + (const GLubyte*)"GLX 1.2 and up are not supported", + (const GLubyte*)"Unknown error" + }; + const int max_error = sizeof(_glewErrorString)/sizeof(*_glewErrorString) - 1; + return _glewErrorString[(int)error > max_error ? max_error : (int)error]; +} + +const GLubyte* glewGetString (GLenum name) +{ + static const GLubyte* _glewString[] = + { + (const GLubyte*)NULL, + (const GLubyte*)"1.5.1", + (const GLubyte*)"1", + (const GLubyte*)"5", + (const GLubyte*)"1" + }; + const int max_string = sizeof(_glewString)/sizeof(*_glewString) - 1; + return _glewString[(int)name > max_string ? 0 : (int)name]; +} + +/* ------------------------------------------------------------------------ */ + +GLboolean glewExperimental = GL_FALSE; + +#if !defined(GLEW_MX) + +#if defined(_WIN32) +extern GLenum wglewContextInit (void); +#elif !defined(__APPLE__) || defined(GLEW_APPLE_GLX) /* _UNIX */ +extern GLenum glxewContextInit (void); +#endif /* _WIN32 */ + +GLenum glewInit () +{ + GLenum r; + if ( (r = glewContextInit()) ) return r; +#if defined(_WIN32) + return wglewContextInit(); +#elif !defined(__APPLE__) || defined(GLEW_APPLE_GLX) /* _UNIX */ + return glxewContextInit(); +#else + return r; +#endif /* _WIN32 */ +} + +#endif /* !GLEW_MX */ +#ifdef GLEW_MX +GLboolean glewContextIsSupported (GLEWContext* ctx, const char* name) +#else +GLboolean glewIsSupported (const char* name) +#endif +{ + GLubyte* pos = (GLubyte*)name; + GLuint len = _glewStrLen(pos); + GLboolean ret = GL_TRUE; + while (ret && len > 0) + { + if (_glewStrSame1(&pos, &len, (const GLubyte*)"GL_", 3)) + { + if (_glewStrSame2(&pos, &len, (const GLubyte*)"VERSION_", 8)) + { +#ifdef GL_VERSION_1_2 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_2", 3)) + { + ret = GLEW_VERSION_1_2; + continue; + } +#endif +#ifdef GL_VERSION_1_3 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_3", 3)) + { + ret = GLEW_VERSION_1_3; + continue; + } +#endif +#ifdef GL_VERSION_1_4 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_4", 3)) + { + ret = GLEW_VERSION_1_4; + continue; + } +#endif +#ifdef GL_VERSION_1_5 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_5", 3)) + { + ret = GLEW_VERSION_1_5; + continue; + } +#endif +#ifdef GL_VERSION_2_0 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"2_0", 3)) + { + ret = GLEW_VERSION_2_0; + continue; + } +#endif +#ifdef GL_VERSION_2_1 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"2_1", 3)) + { + ret = GLEW_VERSION_2_1; + continue; + } +#endif +#ifdef GL_VERSION_3_0 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"3_0", 3)) + { + ret = GLEW_VERSION_3_0; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"3DFX_", 5)) + { +#ifdef GL_3DFX_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11)) + { + ret = GLEW_3DFX_multisample; + continue; + } +#endif +#ifdef GL_3DFX_tbuffer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"tbuffer", 7)) + { + ret = GLEW_3DFX_tbuffer; + continue; + } +#endif +#ifdef GL_3DFX_texture_compression_FXT1 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_FXT1", 24)) + { + ret = GLEW_3DFX_texture_compression_FXT1; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"APPLE_", 6)) + { +#ifdef GL_APPLE_client_storage + if (_glewStrSame3(&pos, &len, (const GLubyte*)"client_storage", 14)) + { + ret = GLEW_APPLE_client_storage; + continue; + } +#endif +#ifdef GL_APPLE_element_array + if (_glewStrSame3(&pos, &len, (const GLubyte*)"element_array", 13)) + { + ret = GLEW_APPLE_element_array; + continue; + } +#endif +#ifdef GL_APPLE_fence + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fence", 5)) + { + ret = GLEW_APPLE_fence; + continue; + } +#endif +#ifdef GL_APPLE_float_pixels + if (_glewStrSame3(&pos, &len, (const GLubyte*)"float_pixels", 12)) + { + ret = GLEW_APPLE_float_pixels; + continue; + } +#endif +#ifdef GL_APPLE_flush_buffer_range + if (_glewStrSame3(&pos, &len, (const GLubyte*)"flush_buffer_range", 18)) + { + ret = GLEW_APPLE_flush_buffer_range; + continue; + } +#endif +#ifdef GL_APPLE_pixel_buffer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_buffer", 12)) + { + ret = GLEW_APPLE_pixel_buffer; + continue; + } +#endif +#ifdef GL_APPLE_specular_vector + if (_glewStrSame3(&pos, &len, (const GLubyte*)"specular_vector", 15)) + { + ret = GLEW_APPLE_specular_vector; + continue; + } +#endif +#ifdef GL_APPLE_texture_range + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_range", 13)) + { + ret = GLEW_APPLE_texture_range; + continue; + } +#endif +#ifdef GL_APPLE_transform_hint + if (_glewStrSame3(&pos, &len, (const GLubyte*)"transform_hint", 14)) + { + ret = GLEW_APPLE_transform_hint; + continue; + } +#endif +#ifdef GL_APPLE_vertex_array_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_object", 19)) + { + ret = GLEW_APPLE_vertex_array_object; + continue; + } +#endif +#ifdef GL_APPLE_vertex_array_range + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_range", 18)) + { + ret = GLEW_APPLE_vertex_array_range; + continue; + } +#endif +#ifdef GL_APPLE_ycbcr_422 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"ycbcr_422", 9)) + { + ret = GLEW_APPLE_ycbcr_422; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"ARB_", 4)) + { +#ifdef GL_ARB_color_buffer_float + if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_buffer_float", 18)) + { + ret = GLEW_ARB_color_buffer_float; + continue; + } +#endif +#ifdef GL_ARB_depth_buffer_float + if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_buffer_float", 18)) + { + ret = GLEW_ARB_depth_buffer_float; + continue; + } +#endif +#ifdef GL_ARB_depth_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_texture", 13)) + { + ret = GLEW_ARB_depth_texture; + continue; + } +#endif +#ifdef GL_ARB_draw_buffers + if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_buffers", 12)) + { + ret = GLEW_ARB_draw_buffers; + continue; + } +#endif +#ifdef GL_ARB_draw_instanced + if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_instanced", 14)) + { + ret = GLEW_ARB_draw_instanced; + continue; + } +#endif +#ifdef GL_ARB_fragment_program + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_program", 16)) + { + ret = GLEW_ARB_fragment_program; + continue; + } +#endif +#ifdef GL_ARB_fragment_program_shadow + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_program_shadow", 23)) + { + ret = GLEW_ARB_fragment_program_shadow; + continue; + } +#endif +#ifdef GL_ARB_fragment_shader + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_shader", 15)) + { + ret = GLEW_ARB_fragment_shader; + continue; + } +#endif +#ifdef GL_ARB_framebuffer_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_object", 18)) + { + ret = GLEW_ARB_framebuffer_object; + continue; + } +#endif +#ifdef GL_ARB_framebuffer_sRGB + if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_sRGB", 16)) + { + ret = GLEW_ARB_framebuffer_sRGB; + continue; + } +#endif +#ifdef GL_ARB_geometry_shader4 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"geometry_shader4", 16)) + { + ret = GLEW_ARB_geometry_shader4; + continue; + } +#endif +#ifdef GL_ARB_half_float_pixel + if (_glewStrSame3(&pos, &len, (const GLubyte*)"half_float_pixel", 16)) + { + ret = GLEW_ARB_half_float_pixel; + continue; + } +#endif +#ifdef GL_ARB_half_float_vertex + if (_glewStrSame3(&pos, &len, (const GLubyte*)"half_float_vertex", 17)) + { + ret = GLEW_ARB_half_float_vertex; + continue; + } +#endif +#ifdef GL_ARB_imaging + if (_glewStrSame3(&pos, &len, (const GLubyte*)"imaging", 7)) + { + ret = GLEW_ARB_imaging; + continue; + } +#endif +#ifdef GL_ARB_instanced_arrays + if (_glewStrSame3(&pos, &len, (const GLubyte*)"instanced_arrays", 16)) + { + ret = GLEW_ARB_instanced_arrays; + continue; + } +#endif +#ifdef GL_ARB_map_buffer_range + if (_glewStrSame3(&pos, &len, (const GLubyte*)"map_buffer_range", 16)) + { + ret = GLEW_ARB_map_buffer_range; + continue; + } +#endif +#ifdef GL_ARB_matrix_palette + if (_glewStrSame3(&pos, &len, (const GLubyte*)"matrix_palette", 14)) + { + ret = GLEW_ARB_matrix_palette; + continue; + } +#endif +#ifdef GL_ARB_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11)) + { + ret = GLEW_ARB_multisample; + continue; + } +#endif +#ifdef GL_ARB_multitexture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multitexture", 12)) + { + ret = GLEW_ARB_multitexture; + continue; + } +#endif +#ifdef GL_ARB_occlusion_query + if (_glewStrSame3(&pos, &len, (const GLubyte*)"occlusion_query", 15)) + { + ret = GLEW_ARB_occlusion_query; + continue; + } +#endif +#ifdef GL_ARB_pixel_buffer_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_buffer_object", 19)) + { + ret = GLEW_ARB_pixel_buffer_object; + continue; + } +#endif +#ifdef GL_ARB_point_parameters + if (_glewStrSame3(&pos, &len, (const GLubyte*)"point_parameters", 16)) + { + ret = GLEW_ARB_point_parameters; + continue; + } +#endif +#ifdef GL_ARB_point_sprite + if (_glewStrSame3(&pos, &len, (const GLubyte*)"point_sprite", 12)) + { + ret = GLEW_ARB_point_sprite; + continue; + } +#endif +#ifdef GL_ARB_shader_objects + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_objects", 14)) + { + ret = GLEW_ARB_shader_objects; + continue; + } +#endif +#ifdef GL_ARB_shading_language_100 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shading_language_100", 20)) + { + ret = GLEW_ARB_shading_language_100; + continue; + } +#endif +#ifdef GL_ARB_shadow + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shadow", 6)) + { + ret = GLEW_ARB_shadow; + continue; + } +#endif +#ifdef GL_ARB_shadow_ambient + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shadow_ambient", 14)) + { + ret = GLEW_ARB_shadow_ambient; + continue; + } +#endif +#ifdef GL_ARB_texture_border_clamp + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_border_clamp", 20)) + { + ret = GLEW_ARB_texture_border_clamp; + continue; + } +#endif +#ifdef GL_ARB_texture_buffer_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_buffer_object", 21)) + { + ret = GLEW_ARB_texture_buffer_object; + continue; + } +#endif +#ifdef GL_ARB_texture_compression + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression", 19)) + { + ret = GLEW_ARB_texture_compression; + continue; + } +#endif +#ifdef GL_ARB_texture_compression_rgtc + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_rgtc", 24)) + { + ret = GLEW_ARB_texture_compression_rgtc; + continue; + } +#endif +#ifdef GL_ARB_texture_cube_map + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_cube_map", 16)) + { + ret = GLEW_ARB_texture_cube_map; + continue; + } +#endif +#ifdef GL_ARB_texture_env_add + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_add", 15)) + { + ret = GLEW_ARB_texture_env_add; + continue; + } +#endif +#ifdef GL_ARB_texture_env_combine + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_combine", 19)) + { + ret = GLEW_ARB_texture_env_combine; + continue; + } +#endif +#ifdef GL_ARB_texture_env_crossbar + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_crossbar", 20)) + { + ret = GLEW_ARB_texture_env_crossbar; + continue; + } +#endif +#ifdef GL_ARB_texture_env_dot3 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_dot3", 16)) + { + ret = GLEW_ARB_texture_env_dot3; + continue; + } +#endif +#ifdef GL_ARB_texture_float + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_float", 13)) + { + ret = GLEW_ARB_texture_float; + continue; + } +#endif +#ifdef GL_ARB_texture_mirrored_repeat + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_mirrored_repeat", 23)) + { + ret = GLEW_ARB_texture_mirrored_repeat; + continue; + } +#endif +#ifdef GL_ARB_texture_non_power_of_two + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_non_power_of_two", 24)) + { + ret = GLEW_ARB_texture_non_power_of_two; + continue; + } +#endif +#ifdef GL_ARB_texture_rectangle + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_rectangle", 17)) + { + ret = GLEW_ARB_texture_rectangle; + continue; + } +#endif +#ifdef GL_ARB_texture_rg + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_rg", 10)) + { + ret = GLEW_ARB_texture_rg; + continue; + } +#endif +#ifdef GL_ARB_transpose_matrix + if (_glewStrSame3(&pos, &len, (const GLubyte*)"transpose_matrix", 16)) + { + ret = GLEW_ARB_transpose_matrix; + continue; + } +#endif +#ifdef GL_ARB_vertex_array_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_object", 19)) + { + ret = GLEW_ARB_vertex_array_object; + continue; + } +#endif +#ifdef GL_ARB_vertex_blend + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_blend", 12)) + { + ret = GLEW_ARB_vertex_blend; + continue; + } +#endif +#ifdef GL_ARB_vertex_buffer_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_buffer_object", 20)) + { + ret = GLEW_ARB_vertex_buffer_object; + continue; + } +#endif +#ifdef GL_ARB_vertex_program + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_program", 14)) + { + ret = GLEW_ARB_vertex_program; + continue; + } +#endif +#ifdef GL_ARB_vertex_shader + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_shader", 13)) + { + ret = GLEW_ARB_vertex_shader; + continue; + } +#endif +#ifdef GL_ARB_window_pos + if (_glewStrSame3(&pos, &len, (const GLubyte*)"window_pos", 10)) + { + ret = GLEW_ARB_window_pos; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"ATIX_", 5)) + { +#ifdef GL_ATIX_point_sprites + if (_glewStrSame3(&pos, &len, (const GLubyte*)"point_sprites", 13)) + { + ret = GLEW_ATIX_point_sprites; + continue; + } +#endif +#ifdef GL_ATIX_texture_env_combine3 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_combine3", 20)) + { + ret = GLEW_ATIX_texture_env_combine3; + continue; + } +#endif +#ifdef GL_ATIX_texture_env_route + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_route", 17)) + { + ret = GLEW_ATIX_texture_env_route; + continue; + } +#endif +#ifdef GL_ATIX_vertex_shader_output_point_size + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_shader_output_point_size", 31)) + { + ret = GLEW_ATIX_vertex_shader_output_point_size; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"ATI_", 4)) + { +#ifdef GL_ATI_draw_buffers + if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_buffers", 12)) + { + ret = GLEW_ATI_draw_buffers; + continue; + } +#endif +#ifdef GL_ATI_element_array + if (_glewStrSame3(&pos, &len, (const GLubyte*)"element_array", 13)) + { + ret = GLEW_ATI_element_array; + continue; + } +#endif +#ifdef GL_ATI_envmap_bumpmap + if (_glewStrSame3(&pos, &len, (const GLubyte*)"envmap_bumpmap", 14)) + { + ret = GLEW_ATI_envmap_bumpmap; + continue; + } +#endif +#ifdef GL_ATI_fragment_shader + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_shader", 15)) + { + ret = GLEW_ATI_fragment_shader; + continue; + } +#endif +#ifdef GL_ATI_map_object_buffer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"map_object_buffer", 17)) + { + ret = GLEW_ATI_map_object_buffer; + continue; + } +#endif +#ifdef GL_ATI_pn_triangles + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pn_triangles", 12)) + { + ret = GLEW_ATI_pn_triangles; + continue; + } +#endif +#ifdef GL_ATI_separate_stencil + if (_glewStrSame3(&pos, &len, (const GLubyte*)"separate_stencil", 16)) + { + ret = GLEW_ATI_separate_stencil; + continue; + } +#endif +#ifdef GL_ATI_shader_texture_lod + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_texture_lod", 18)) + { + ret = GLEW_ATI_shader_texture_lod; + continue; + } +#endif +#ifdef GL_ATI_text_fragment_shader + if (_glewStrSame3(&pos, &len, (const GLubyte*)"text_fragment_shader", 20)) + { + ret = GLEW_ATI_text_fragment_shader; + continue; + } +#endif +#ifdef GL_ATI_texture_compression_3dc + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_3dc", 23)) + { + ret = GLEW_ATI_texture_compression_3dc; + continue; + } +#endif +#ifdef GL_ATI_texture_env_combine3 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_combine3", 20)) + { + ret = GLEW_ATI_texture_env_combine3; + continue; + } +#endif +#ifdef GL_ATI_texture_float + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_float", 13)) + { + ret = GLEW_ATI_texture_float; + continue; + } +#endif +#ifdef GL_ATI_texture_mirror_once + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_mirror_once", 19)) + { + ret = GLEW_ATI_texture_mirror_once; + continue; + } +#endif +#ifdef GL_ATI_vertex_array_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_object", 19)) + { + ret = GLEW_ATI_vertex_array_object; + continue; + } +#endif +#ifdef GL_ATI_vertex_attrib_array_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_attrib_array_object", 26)) + { + ret = GLEW_ATI_vertex_attrib_array_object; + continue; + } +#endif +#ifdef GL_ATI_vertex_streams + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_streams", 14)) + { + ret = GLEW_ATI_vertex_streams; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"EXT_", 4)) + { +#ifdef GL_EXT_422_pixels + if (_glewStrSame3(&pos, &len, (const GLubyte*)"422_pixels", 10)) + { + ret = GLEW_EXT_422_pixels; + continue; + } +#endif +#ifdef GL_EXT_Cg_shader + if (_glewStrSame3(&pos, &len, (const GLubyte*)"Cg_shader", 9)) + { + ret = GLEW_EXT_Cg_shader; + continue; + } +#endif +#ifdef GL_EXT_abgr + if (_glewStrSame3(&pos, &len, (const GLubyte*)"abgr", 4)) + { + ret = GLEW_EXT_abgr; + continue; + } +#endif +#ifdef GL_EXT_bgra + if (_glewStrSame3(&pos, &len, (const GLubyte*)"bgra", 4)) + { + ret = GLEW_EXT_bgra; + continue; + } +#endif +#ifdef GL_EXT_bindable_uniform + if (_glewStrSame3(&pos, &len, (const GLubyte*)"bindable_uniform", 16)) + { + ret = GLEW_EXT_bindable_uniform; + continue; + } +#endif +#ifdef GL_EXT_blend_color + if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_color", 11)) + { + ret = GLEW_EXT_blend_color; + continue; + } +#endif +#ifdef GL_EXT_blend_equation_separate + if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_equation_separate", 23)) + { + ret = GLEW_EXT_blend_equation_separate; + continue; + } +#endif +#ifdef GL_EXT_blend_func_separate + if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_func_separate", 19)) + { + ret = GLEW_EXT_blend_func_separate; + continue; + } +#endif +#ifdef GL_EXT_blend_logic_op + if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_logic_op", 14)) + { + ret = GLEW_EXT_blend_logic_op; + continue; + } +#endif +#ifdef GL_EXT_blend_minmax + if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_minmax", 12)) + { + ret = GLEW_EXT_blend_minmax; + continue; + } +#endif +#ifdef GL_EXT_blend_subtract + if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_subtract", 14)) + { + ret = GLEW_EXT_blend_subtract; + continue; + } +#endif +#ifdef GL_EXT_clip_volume_hint + if (_glewStrSame3(&pos, &len, (const GLubyte*)"clip_volume_hint", 16)) + { + ret = GLEW_EXT_clip_volume_hint; + continue; + } +#endif +#ifdef GL_EXT_cmyka + if (_glewStrSame3(&pos, &len, (const GLubyte*)"cmyka", 5)) + { + ret = GLEW_EXT_cmyka; + continue; + } +#endif +#ifdef GL_EXT_color_subtable + if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_subtable", 14)) + { + ret = GLEW_EXT_color_subtable; + continue; + } +#endif +#ifdef GL_EXT_compiled_vertex_array + if (_glewStrSame3(&pos, &len, (const GLubyte*)"compiled_vertex_array", 21)) + { + ret = GLEW_EXT_compiled_vertex_array; + continue; + } +#endif +#ifdef GL_EXT_convolution + if (_glewStrSame3(&pos, &len, (const GLubyte*)"convolution", 11)) + { + ret = GLEW_EXT_convolution; + continue; + } +#endif +#ifdef GL_EXT_coordinate_frame + if (_glewStrSame3(&pos, &len, (const GLubyte*)"coordinate_frame", 16)) + { + ret = GLEW_EXT_coordinate_frame; + continue; + } +#endif +#ifdef GL_EXT_copy_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"copy_texture", 12)) + { + ret = GLEW_EXT_copy_texture; + continue; + } +#endif +#ifdef GL_EXT_cull_vertex + if (_glewStrSame3(&pos, &len, (const GLubyte*)"cull_vertex", 11)) + { + ret = GLEW_EXT_cull_vertex; + continue; + } +#endif +#ifdef GL_EXT_depth_bounds_test + if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_bounds_test", 17)) + { + ret = GLEW_EXT_depth_bounds_test; + continue; + } +#endif +#ifdef GL_EXT_direct_state_access + if (_glewStrSame3(&pos, &len, (const GLubyte*)"direct_state_access", 19)) + { + ret = GLEW_EXT_direct_state_access; + continue; + } +#endif +#ifdef GL_EXT_draw_buffers2 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_buffers2", 13)) + { + ret = GLEW_EXT_draw_buffers2; + continue; + } +#endif +#ifdef GL_EXT_draw_instanced + if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_instanced", 14)) + { + ret = GLEW_EXT_draw_instanced; + continue; + } +#endif +#ifdef GL_EXT_draw_range_elements + if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_range_elements", 19)) + { + ret = GLEW_EXT_draw_range_elements; + continue; + } +#endif +#ifdef GL_EXT_fog_coord + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fog_coord", 9)) + { + ret = GLEW_EXT_fog_coord; + continue; + } +#endif +#ifdef GL_EXT_fragment_lighting + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_lighting", 17)) + { + ret = GLEW_EXT_fragment_lighting; + continue; + } +#endif +#ifdef GL_EXT_framebuffer_blit + if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_blit", 16)) + { + ret = GLEW_EXT_framebuffer_blit; + continue; + } +#endif +#ifdef GL_EXT_framebuffer_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_multisample", 23)) + { + ret = GLEW_EXT_framebuffer_multisample; + continue; + } +#endif +#ifdef GL_EXT_framebuffer_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_object", 18)) + { + ret = GLEW_EXT_framebuffer_object; + continue; + } +#endif +#ifdef GL_EXT_framebuffer_sRGB + if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_sRGB", 16)) + { + ret = GLEW_EXT_framebuffer_sRGB; + continue; + } +#endif +#ifdef GL_EXT_geometry_shader4 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"geometry_shader4", 16)) + { + ret = GLEW_EXT_geometry_shader4; + continue; + } +#endif +#ifdef GL_EXT_gpu_program_parameters + if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_program_parameters", 22)) + { + ret = GLEW_EXT_gpu_program_parameters; + continue; + } +#endif +#ifdef GL_EXT_gpu_shader4 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_shader4", 11)) + { + ret = GLEW_EXT_gpu_shader4; + continue; + } +#endif +#ifdef GL_EXT_histogram + if (_glewStrSame3(&pos, &len, (const GLubyte*)"histogram", 9)) + { + ret = GLEW_EXT_histogram; + continue; + } +#endif +#ifdef GL_EXT_index_array_formats + if (_glewStrSame3(&pos, &len, (const GLubyte*)"index_array_formats", 19)) + { + ret = GLEW_EXT_index_array_formats; + continue; + } +#endif +#ifdef GL_EXT_index_func + if (_glewStrSame3(&pos, &len, (const GLubyte*)"index_func", 10)) + { + ret = GLEW_EXT_index_func; + continue; + } +#endif +#ifdef GL_EXT_index_material + if (_glewStrSame3(&pos, &len, (const GLubyte*)"index_material", 14)) + { + ret = GLEW_EXT_index_material; + continue; + } +#endif +#ifdef GL_EXT_index_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"index_texture", 13)) + { + ret = GLEW_EXT_index_texture; + continue; + } +#endif +#ifdef GL_EXT_light_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"light_texture", 13)) + { + ret = GLEW_EXT_light_texture; + continue; + } +#endif +#ifdef GL_EXT_misc_attribute + if (_glewStrSame3(&pos, &len, (const GLubyte*)"misc_attribute", 14)) + { + ret = GLEW_EXT_misc_attribute; + continue; + } +#endif +#ifdef GL_EXT_multi_draw_arrays + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multi_draw_arrays", 17)) + { + ret = GLEW_EXT_multi_draw_arrays; + continue; + } +#endif +#ifdef GL_EXT_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11)) + { + ret = GLEW_EXT_multisample; + continue; + } +#endif +#ifdef GL_EXT_packed_depth_stencil + if (_glewStrSame3(&pos, &len, (const GLubyte*)"packed_depth_stencil", 20)) + { + ret = GLEW_EXT_packed_depth_stencil; + continue; + } +#endif +#ifdef GL_EXT_packed_float + if (_glewStrSame3(&pos, &len, (const GLubyte*)"packed_float", 12)) + { + ret = GLEW_EXT_packed_float; + continue; + } +#endif +#ifdef GL_EXT_packed_pixels + if (_glewStrSame3(&pos, &len, (const GLubyte*)"packed_pixels", 13)) + { + ret = GLEW_EXT_packed_pixels; + continue; + } +#endif +#ifdef GL_EXT_paletted_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"paletted_texture", 16)) + { + ret = GLEW_EXT_paletted_texture; + continue; + } +#endif +#ifdef GL_EXT_pixel_buffer_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_buffer_object", 19)) + { + ret = GLEW_EXT_pixel_buffer_object; + continue; + } +#endif +#ifdef GL_EXT_pixel_transform + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_transform", 15)) + { + ret = GLEW_EXT_pixel_transform; + continue; + } +#endif +#ifdef GL_EXT_pixel_transform_color_table + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_transform_color_table", 27)) + { + ret = GLEW_EXT_pixel_transform_color_table; + continue; + } +#endif +#ifdef GL_EXT_point_parameters + if (_glewStrSame3(&pos, &len, (const GLubyte*)"point_parameters", 16)) + { + ret = GLEW_EXT_point_parameters; + continue; + } +#endif +#ifdef GL_EXT_polygon_offset + if (_glewStrSame3(&pos, &len, (const GLubyte*)"polygon_offset", 14)) + { + ret = GLEW_EXT_polygon_offset; + continue; + } +#endif +#ifdef GL_EXT_rescale_normal + if (_glewStrSame3(&pos, &len, (const GLubyte*)"rescale_normal", 14)) + { + ret = GLEW_EXT_rescale_normal; + continue; + } +#endif +#ifdef GL_EXT_scene_marker + if (_glewStrSame3(&pos, &len, (const GLubyte*)"scene_marker", 12)) + { + ret = GLEW_EXT_scene_marker; + continue; + } +#endif +#ifdef GL_EXT_secondary_color + if (_glewStrSame3(&pos, &len, (const GLubyte*)"secondary_color", 15)) + { + ret = GLEW_EXT_secondary_color; + continue; + } +#endif +#ifdef GL_EXT_separate_specular_color + if (_glewStrSame3(&pos, &len, (const GLubyte*)"separate_specular_color", 23)) + { + ret = GLEW_EXT_separate_specular_color; + continue; + } +#endif +#ifdef GL_EXT_shadow_funcs + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shadow_funcs", 12)) + { + ret = GLEW_EXT_shadow_funcs; + continue; + } +#endif +#ifdef GL_EXT_shared_texture_palette + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shared_texture_palette", 22)) + { + ret = GLEW_EXT_shared_texture_palette; + continue; + } +#endif +#ifdef GL_EXT_stencil_clear_tag + if (_glewStrSame3(&pos, &len, (const GLubyte*)"stencil_clear_tag", 17)) + { + ret = GLEW_EXT_stencil_clear_tag; + continue; + } +#endif +#ifdef GL_EXT_stencil_two_side + if (_glewStrSame3(&pos, &len, (const GLubyte*)"stencil_two_side", 16)) + { + ret = GLEW_EXT_stencil_two_side; + continue; + } +#endif +#ifdef GL_EXT_stencil_wrap + if (_glewStrSame3(&pos, &len, (const GLubyte*)"stencil_wrap", 12)) + { + ret = GLEW_EXT_stencil_wrap; + continue; + } +#endif +#ifdef GL_EXT_subtexture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"subtexture", 10)) + { + ret = GLEW_EXT_subtexture; + continue; + } +#endif +#ifdef GL_EXT_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture", 7)) + { + ret = GLEW_EXT_texture; + continue; + } +#endif +#ifdef GL_EXT_texture3D + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture3D", 9)) + { + ret = GLEW_EXT_texture3D; + continue; + } +#endif +#ifdef GL_EXT_texture_array + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_array", 13)) + { + ret = GLEW_EXT_texture_array; + continue; + } +#endif +#ifdef GL_EXT_texture_buffer_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_buffer_object", 21)) + { + ret = GLEW_EXT_texture_buffer_object; + continue; + } +#endif +#ifdef GL_EXT_texture_compression_dxt1 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_dxt1", 24)) + { + ret = GLEW_EXT_texture_compression_dxt1; + continue; + } +#endif +#ifdef GL_EXT_texture_compression_latc + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_latc", 24)) + { + ret = GLEW_EXT_texture_compression_latc; + continue; + } +#endif +#ifdef GL_EXT_texture_compression_rgtc + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_rgtc", 24)) + { + ret = GLEW_EXT_texture_compression_rgtc; + continue; + } +#endif +#ifdef GL_EXT_texture_compression_s3tc + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_s3tc", 24)) + { + ret = GLEW_EXT_texture_compression_s3tc; + continue; + } +#endif +#ifdef GL_EXT_texture_cube_map + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_cube_map", 16)) + { + ret = GLEW_EXT_texture_cube_map; + continue; + } +#endif +#ifdef GL_EXT_texture_edge_clamp + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_edge_clamp", 18)) + { + ret = GLEW_EXT_texture_edge_clamp; + continue; + } +#endif +#ifdef GL_EXT_texture_env + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env", 11)) + { + ret = GLEW_EXT_texture_env; + continue; + } +#endif +#ifdef GL_EXT_texture_env_add + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_add", 15)) + { + ret = GLEW_EXT_texture_env_add; + continue; + } +#endif +#ifdef GL_EXT_texture_env_combine + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_combine", 19)) + { + ret = GLEW_EXT_texture_env_combine; + continue; + } +#endif +#ifdef GL_EXT_texture_env_dot3 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_dot3", 16)) + { + ret = GLEW_EXT_texture_env_dot3; + continue; + } +#endif +#ifdef GL_EXT_texture_filter_anisotropic + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_filter_anisotropic", 26)) + { + ret = GLEW_EXT_texture_filter_anisotropic; + continue; + } +#endif +#ifdef GL_EXT_texture_integer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_integer", 15)) + { + ret = GLEW_EXT_texture_integer; + continue; + } +#endif +#ifdef GL_EXT_texture_lod_bias + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_lod_bias", 16)) + { + ret = GLEW_EXT_texture_lod_bias; + continue; + } +#endif +#ifdef GL_EXT_texture_mirror_clamp + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_mirror_clamp", 20)) + { + ret = GLEW_EXT_texture_mirror_clamp; + continue; + } +#endif +#ifdef GL_EXT_texture_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_object", 14)) + { + ret = GLEW_EXT_texture_object; + continue; + } +#endif +#ifdef GL_EXT_texture_perturb_normal + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_perturb_normal", 22)) + { + ret = GLEW_EXT_texture_perturb_normal; + continue; + } +#endif +#ifdef GL_EXT_texture_rectangle + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_rectangle", 17)) + { + ret = GLEW_EXT_texture_rectangle; + continue; + } +#endif +#ifdef GL_EXT_texture_sRGB + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_sRGB", 12)) + { + ret = GLEW_EXT_texture_sRGB; + continue; + } +#endif +#ifdef GL_EXT_texture_shared_exponent + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_shared_exponent", 23)) + { + ret = GLEW_EXT_texture_shared_exponent; + continue; + } +#endif +#ifdef GL_EXT_texture_swizzle + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_swizzle", 15)) + { + ret = GLEW_EXT_texture_swizzle; + continue; + } +#endif +#ifdef GL_EXT_timer_query + if (_glewStrSame3(&pos, &len, (const GLubyte*)"timer_query", 11)) + { + ret = GLEW_EXT_timer_query; + continue; + } +#endif +#ifdef GL_EXT_transform_feedback + if (_glewStrSame3(&pos, &len, (const GLubyte*)"transform_feedback", 18)) + { + ret = GLEW_EXT_transform_feedback; + continue; + } +#endif +#ifdef GL_EXT_vertex_array + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array", 12)) + { + ret = GLEW_EXT_vertex_array; + continue; + } +#endif +#ifdef GL_EXT_vertex_array_bgra + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_bgra", 17)) + { + ret = GLEW_EXT_vertex_array_bgra; + continue; + } +#endif +#ifdef GL_EXT_vertex_shader + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_shader", 13)) + { + ret = GLEW_EXT_vertex_shader; + continue; + } +#endif +#ifdef GL_EXT_vertex_weighting + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_weighting", 16)) + { + ret = GLEW_EXT_vertex_weighting; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"GREMEDY_", 8)) + { +#ifdef GL_GREMEDY_frame_terminator + if (_glewStrSame3(&pos, &len, (const GLubyte*)"frame_terminator", 16)) + { + ret = GLEW_GREMEDY_frame_terminator; + continue; + } +#endif +#ifdef GL_GREMEDY_string_marker + if (_glewStrSame3(&pos, &len, (const GLubyte*)"string_marker", 13)) + { + ret = GLEW_GREMEDY_string_marker; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"HP_", 3)) + { +#ifdef GL_HP_convolution_border_modes + if (_glewStrSame3(&pos, &len, (const GLubyte*)"convolution_border_modes", 24)) + { + ret = GLEW_HP_convolution_border_modes; + continue; + } +#endif +#ifdef GL_HP_image_transform + if (_glewStrSame3(&pos, &len, (const GLubyte*)"image_transform", 15)) + { + ret = GLEW_HP_image_transform; + continue; + } +#endif +#ifdef GL_HP_occlusion_test + if (_glewStrSame3(&pos, &len, (const GLubyte*)"occlusion_test", 14)) + { + ret = GLEW_HP_occlusion_test; + continue; + } +#endif +#ifdef GL_HP_texture_lighting + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_lighting", 16)) + { + ret = GLEW_HP_texture_lighting; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"IBM_", 4)) + { +#ifdef GL_IBM_cull_vertex + if (_glewStrSame3(&pos, &len, (const GLubyte*)"cull_vertex", 11)) + { + ret = GLEW_IBM_cull_vertex; + continue; + } +#endif +#ifdef GL_IBM_multimode_draw_arrays + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multimode_draw_arrays", 21)) + { + ret = GLEW_IBM_multimode_draw_arrays; + continue; + } +#endif +#ifdef GL_IBM_rasterpos_clip + if (_glewStrSame3(&pos, &len, (const GLubyte*)"rasterpos_clip", 14)) + { + ret = GLEW_IBM_rasterpos_clip; + continue; + } +#endif +#ifdef GL_IBM_static_data + if (_glewStrSame3(&pos, &len, (const GLubyte*)"static_data", 11)) + { + ret = GLEW_IBM_static_data; + continue; + } +#endif +#ifdef GL_IBM_texture_mirrored_repeat + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_mirrored_repeat", 23)) + { + ret = GLEW_IBM_texture_mirrored_repeat; + continue; + } +#endif +#ifdef GL_IBM_vertex_array_lists + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_lists", 18)) + { + ret = GLEW_IBM_vertex_array_lists; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"INGR_", 5)) + { +#ifdef GL_INGR_color_clamp + if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_clamp", 11)) + { + ret = GLEW_INGR_color_clamp; + continue; + } +#endif +#ifdef GL_INGR_interlace_read + if (_glewStrSame3(&pos, &len, (const GLubyte*)"interlace_read", 14)) + { + ret = GLEW_INGR_interlace_read; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"INTEL_", 6)) + { +#ifdef GL_INTEL_parallel_arrays + if (_glewStrSame3(&pos, &len, (const GLubyte*)"parallel_arrays", 15)) + { + ret = GLEW_INTEL_parallel_arrays; + continue; + } +#endif +#ifdef GL_INTEL_texture_scissor + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_scissor", 15)) + { + ret = GLEW_INTEL_texture_scissor; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"KTX_", 4)) + { +#ifdef GL_KTX_buffer_region + if (_glewStrSame3(&pos, &len, (const GLubyte*)"buffer_region", 13)) + { + ret = GLEW_KTX_buffer_region; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"MESAX_", 6)) + { +#ifdef GL_MESAX_texture_stack + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_stack", 13)) + { + ret = GLEW_MESAX_texture_stack; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"MESA_", 5)) + { +#ifdef GL_MESA_pack_invert + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pack_invert", 11)) + { + ret = GLEW_MESA_pack_invert; + continue; + } +#endif +#ifdef GL_MESA_resize_buffers + if (_glewStrSame3(&pos, &len, (const GLubyte*)"resize_buffers", 14)) + { + ret = GLEW_MESA_resize_buffers; + continue; + } +#endif +#ifdef GL_MESA_window_pos + if (_glewStrSame3(&pos, &len, (const GLubyte*)"window_pos", 10)) + { + ret = GLEW_MESA_window_pos; + continue; + } +#endif +#ifdef GL_MESA_ycbcr_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"ycbcr_texture", 13)) + { + ret = GLEW_MESA_ycbcr_texture; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"NV_", 3)) + { +#ifdef GL_NV_blend_square + if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_square", 12)) + { + ret = GLEW_NV_blend_square; + continue; + } +#endif +#ifdef GL_NV_conditional_render + if (_glewStrSame3(&pos, &len, (const GLubyte*)"conditional_render", 18)) + { + ret = GLEW_NV_conditional_render; + continue; + } +#endif +#ifdef GL_NV_copy_depth_to_color + if (_glewStrSame3(&pos, &len, (const GLubyte*)"copy_depth_to_color", 19)) + { + ret = GLEW_NV_copy_depth_to_color; + continue; + } +#endif +#ifdef GL_NV_depth_buffer_float + if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_buffer_float", 18)) + { + ret = GLEW_NV_depth_buffer_float; + continue; + } +#endif +#ifdef GL_NV_depth_clamp + if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_clamp", 11)) + { + ret = GLEW_NV_depth_clamp; + continue; + } +#endif +#ifdef GL_NV_depth_range_unclamped + if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_range_unclamped", 21)) + { + ret = GLEW_NV_depth_range_unclamped; + continue; + } +#endif +#ifdef GL_NV_evaluators + if (_glewStrSame3(&pos, &len, (const GLubyte*)"evaluators", 10)) + { + ret = GLEW_NV_evaluators; + continue; + } +#endif +#ifdef GL_NV_explicit_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"explicit_multisample", 20)) + { + ret = GLEW_NV_explicit_multisample; + continue; + } +#endif +#ifdef GL_NV_fence + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fence", 5)) + { + ret = GLEW_NV_fence; + continue; + } +#endif +#ifdef GL_NV_float_buffer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"float_buffer", 12)) + { + ret = GLEW_NV_float_buffer; + continue; + } +#endif +#ifdef GL_NV_fog_distance + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fog_distance", 12)) + { + ret = GLEW_NV_fog_distance; + continue; + } +#endif +#ifdef GL_NV_fragment_program + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_program", 16)) + { + ret = GLEW_NV_fragment_program; + continue; + } +#endif +#ifdef GL_NV_fragment_program2 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_program2", 17)) + { + ret = GLEW_NV_fragment_program2; + continue; + } +#endif +#ifdef GL_NV_fragment_program4 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_program4", 17)) + { + ret = GLEW_NV_fragment_program4; + continue; + } +#endif +#ifdef GL_NV_fragment_program_option + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_program_option", 23)) + { + ret = GLEW_NV_fragment_program_option; + continue; + } +#endif +#ifdef GL_NV_framebuffer_multisample_coverage + if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_multisample_coverage", 32)) + { + ret = GLEW_NV_framebuffer_multisample_coverage; + continue; + } +#endif +#ifdef GL_NV_geometry_program4 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"geometry_program4", 17)) + { + ret = GLEW_NV_geometry_program4; + continue; + } +#endif +#ifdef GL_NV_geometry_shader4 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"geometry_shader4", 16)) + { + ret = GLEW_NV_geometry_shader4; + continue; + } +#endif +#ifdef GL_NV_gpu_program4 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_program4", 12)) + { + ret = GLEW_NV_gpu_program4; + continue; + } +#endif +#ifdef GL_NV_half_float + if (_glewStrSame3(&pos, &len, (const GLubyte*)"half_float", 10)) + { + ret = GLEW_NV_half_float; + continue; + } +#endif +#ifdef GL_NV_light_max_exponent + if (_glewStrSame3(&pos, &len, (const GLubyte*)"light_max_exponent", 18)) + { + ret = GLEW_NV_light_max_exponent; + continue; + } +#endif +#ifdef GL_NV_multisample_filter_hint + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample_filter_hint", 23)) + { + ret = GLEW_NV_multisample_filter_hint; + continue; + } +#endif +#ifdef GL_NV_occlusion_query + if (_glewStrSame3(&pos, &len, (const GLubyte*)"occlusion_query", 15)) + { + ret = GLEW_NV_occlusion_query; + continue; + } +#endif +#ifdef GL_NV_packed_depth_stencil + if (_glewStrSame3(&pos, &len, (const GLubyte*)"packed_depth_stencil", 20)) + { + ret = GLEW_NV_packed_depth_stencil; + continue; + } +#endif +#ifdef GL_NV_parameter_buffer_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"parameter_buffer_object", 23)) + { + ret = GLEW_NV_parameter_buffer_object; + continue; + } +#endif +#ifdef GL_NV_pixel_data_range + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_data_range", 16)) + { + ret = GLEW_NV_pixel_data_range; + continue; + } +#endif +#ifdef GL_NV_point_sprite + if (_glewStrSame3(&pos, &len, (const GLubyte*)"point_sprite", 12)) + { + ret = GLEW_NV_point_sprite; + continue; + } +#endif +#ifdef GL_NV_present_video + if (_glewStrSame3(&pos, &len, (const GLubyte*)"present_video", 13)) + { + ret = GLEW_NV_present_video; + continue; + } +#endif +#ifdef GL_NV_primitive_restart + if (_glewStrSame3(&pos, &len, (const GLubyte*)"primitive_restart", 17)) + { + ret = GLEW_NV_primitive_restart; + continue; + } +#endif +#ifdef GL_NV_register_combiners + if (_glewStrSame3(&pos, &len, (const GLubyte*)"register_combiners", 18)) + { + ret = GLEW_NV_register_combiners; + continue; + } +#endif +#ifdef GL_NV_register_combiners2 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"register_combiners2", 19)) + { + ret = GLEW_NV_register_combiners2; + continue; + } +#endif +#ifdef GL_NV_texgen_emboss + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texgen_emboss", 13)) + { + ret = GLEW_NV_texgen_emboss; + continue; + } +#endif +#ifdef GL_NV_texgen_reflection + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texgen_reflection", 17)) + { + ret = GLEW_NV_texgen_reflection; + continue; + } +#endif +#ifdef GL_NV_texture_compression_vtc + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_vtc", 23)) + { + ret = GLEW_NV_texture_compression_vtc; + continue; + } +#endif +#ifdef GL_NV_texture_env_combine4 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_combine4", 20)) + { + ret = GLEW_NV_texture_env_combine4; + continue; + } +#endif +#ifdef GL_NV_texture_expand_normal + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_expand_normal", 21)) + { + ret = GLEW_NV_texture_expand_normal; + continue; + } +#endif +#ifdef GL_NV_texture_rectangle + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_rectangle", 17)) + { + ret = GLEW_NV_texture_rectangle; + continue; + } +#endif +#ifdef GL_NV_texture_shader + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_shader", 14)) + { + ret = GLEW_NV_texture_shader; + continue; + } +#endif +#ifdef GL_NV_texture_shader2 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_shader2", 15)) + { + ret = GLEW_NV_texture_shader2; + continue; + } +#endif +#ifdef GL_NV_texture_shader3 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_shader3", 15)) + { + ret = GLEW_NV_texture_shader3; + continue; + } +#endif +#ifdef GL_NV_transform_feedback + if (_glewStrSame3(&pos, &len, (const GLubyte*)"transform_feedback", 18)) + { + ret = GLEW_NV_transform_feedback; + continue; + } +#endif +#ifdef GL_NV_vertex_array_range + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_range", 18)) + { + ret = GLEW_NV_vertex_array_range; + continue; + } +#endif +#ifdef GL_NV_vertex_array_range2 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_range2", 19)) + { + ret = GLEW_NV_vertex_array_range2; + continue; + } +#endif +#ifdef GL_NV_vertex_program + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_program", 14)) + { + ret = GLEW_NV_vertex_program; + continue; + } +#endif +#ifdef GL_NV_vertex_program1_1 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_program1_1", 17)) + { + ret = GLEW_NV_vertex_program1_1; + continue; + } +#endif +#ifdef GL_NV_vertex_program2 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_program2", 15)) + { + ret = GLEW_NV_vertex_program2; + continue; + } +#endif +#ifdef GL_NV_vertex_program2_option + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_program2_option", 22)) + { + ret = GLEW_NV_vertex_program2_option; + continue; + } +#endif +#ifdef GL_NV_vertex_program3 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_program3", 15)) + { + ret = GLEW_NV_vertex_program3; + continue; + } +#endif +#ifdef GL_NV_vertex_program4 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_program4", 15)) + { + ret = GLEW_NV_vertex_program4; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"OES_", 4)) + { +#ifdef GL_OES_byte_coordinates + if (_glewStrSame3(&pos, &len, (const GLubyte*)"byte_coordinates", 16)) + { + ret = GLEW_OES_byte_coordinates; + continue; + } +#endif +#ifdef GL_OES_compressed_paletted_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"compressed_paletted_texture", 27)) + { + ret = GLEW_OES_compressed_paletted_texture; + continue; + } +#endif +#ifdef GL_OES_read_format + if (_glewStrSame3(&pos, &len, (const GLubyte*)"read_format", 11)) + { + ret = GLEW_OES_read_format; + continue; + } +#endif +#ifdef GL_OES_single_precision + if (_glewStrSame3(&pos, &len, (const GLubyte*)"single_precision", 16)) + { + ret = GLEW_OES_single_precision; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"OML_", 4)) + { +#ifdef GL_OML_interlace + if (_glewStrSame3(&pos, &len, (const GLubyte*)"interlace", 9)) + { + ret = GLEW_OML_interlace; + continue; + } +#endif +#ifdef GL_OML_resample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"resample", 8)) + { + ret = GLEW_OML_resample; + continue; + } +#endif +#ifdef GL_OML_subsample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"subsample", 9)) + { + ret = GLEW_OML_subsample; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"PGI_", 4)) + { +#ifdef GL_PGI_misc_hints + if (_glewStrSame3(&pos, &len, (const GLubyte*)"misc_hints", 10)) + { + ret = GLEW_PGI_misc_hints; + continue; + } +#endif +#ifdef GL_PGI_vertex_hints + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_hints", 12)) + { + ret = GLEW_PGI_vertex_hints; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"REND_", 5)) + { +#ifdef GL_REND_screen_coordinates + if (_glewStrSame3(&pos, &len, (const GLubyte*)"screen_coordinates", 18)) + { + ret = GLEW_REND_screen_coordinates; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"S3_", 3)) + { +#ifdef GL_S3_s3tc + if (_glewStrSame3(&pos, &len, (const GLubyte*)"s3tc", 4)) + { + ret = GLEW_S3_s3tc; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"SGIS_", 5)) + { +#ifdef GL_SGIS_color_range + if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_range", 11)) + { + ret = GLEW_SGIS_color_range; + continue; + } +#endif +#ifdef GL_SGIS_detail_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"detail_texture", 14)) + { + ret = GLEW_SGIS_detail_texture; + continue; + } +#endif +#ifdef GL_SGIS_fog_function + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fog_function", 12)) + { + ret = GLEW_SGIS_fog_function; + continue; + } +#endif +#ifdef GL_SGIS_generate_mipmap + if (_glewStrSame3(&pos, &len, (const GLubyte*)"generate_mipmap", 15)) + { + ret = GLEW_SGIS_generate_mipmap; + continue; + } +#endif +#ifdef GL_SGIS_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11)) + { + ret = GLEW_SGIS_multisample; + continue; + } +#endif +#ifdef GL_SGIS_pixel_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_texture", 13)) + { + ret = GLEW_SGIS_pixel_texture; + continue; + } +#endif +#ifdef GL_SGIS_point_line_texgen + if (_glewStrSame3(&pos, &len, (const GLubyte*)"point_line_texgen", 17)) + { + ret = GLEW_SGIS_point_line_texgen; + continue; + } +#endif +#ifdef GL_SGIS_sharpen_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"sharpen_texture", 15)) + { + ret = GLEW_SGIS_sharpen_texture; + continue; + } +#endif +#ifdef GL_SGIS_texture4D + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture4D", 9)) + { + ret = GLEW_SGIS_texture4D; + continue; + } +#endif +#ifdef GL_SGIS_texture_border_clamp + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_border_clamp", 20)) + { + ret = GLEW_SGIS_texture_border_clamp; + continue; + } +#endif +#ifdef GL_SGIS_texture_edge_clamp + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_edge_clamp", 18)) + { + ret = GLEW_SGIS_texture_edge_clamp; + continue; + } +#endif +#ifdef GL_SGIS_texture_filter4 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_filter4", 15)) + { + ret = GLEW_SGIS_texture_filter4; + continue; + } +#endif +#ifdef GL_SGIS_texture_lod + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_lod", 11)) + { + ret = GLEW_SGIS_texture_lod; + continue; + } +#endif +#ifdef GL_SGIS_texture_select + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_select", 14)) + { + ret = GLEW_SGIS_texture_select; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"SGIX_", 5)) + { +#ifdef GL_SGIX_async + if (_glewStrSame3(&pos, &len, (const GLubyte*)"async", 5)) + { + ret = GLEW_SGIX_async; + continue; + } +#endif +#ifdef GL_SGIX_async_histogram + if (_glewStrSame3(&pos, &len, (const GLubyte*)"async_histogram", 15)) + { + ret = GLEW_SGIX_async_histogram; + continue; + } +#endif +#ifdef GL_SGIX_async_pixel + if (_glewStrSame3(&pos, &len, (const GLubyte*)"async_pixel", 11)) + { + ret = GLEW_SGIX_async_pixel; + continue; + } +#endif +#ifdef GL_SGIX_blend_alpha_minmax + if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_alpha_minmax", 18)) + { + ret = GLEW_SGIX_blend_alpha_minmax; + continue; + } +#endif +#ifdef GL_SGIX_clipmap + if (_glewStrSame3(&pos, &len, (const GLubyte*)"clipmap", 7)) + { + ret = GLEW_SGIX_clipmap; + continue; + } +#endif +#ifdef GL_SGIX_convolution_accuracy + if (_glewStrSame3(&pos, &len, (const GLubyte*)"convolution_accuracy", 20)) + { + ret = GLEW_SGIX_convolution_accuracy; + continue; + } +#endif +#ifdef GL_SGIX_depth_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_texture", 13)) + { + ret = GLEW_SGIX_depth_texture; + continue; + } +#endif +#ifdef GL_SGIX_flush_raster + if (_glewStrSame3(&pos, &len, (const GLubyte*)"flush_raster", 12)) + { + ret = GLEW_SGIX_flush_raster; + continue; + } +#endif +#ifdef GL_SGIX_fog_offset + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fog_offset", 10)) + { + ret = GLEW_SGIX_fog_offset; + continue; + } +#endif +#ifdef GL_SGIX_fog_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fog_texture", 11)) + { + ret = GLEW_SGIX_fog_texture; + continue; + } +#endif +#ifdef GL_SGIX_fragment_specular_lighting + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_specular_lighting", 26)) + { + ret = GLEW_SGIX_fragment_specular_lighting; + continue; + } +#endif +#ifdef GL_SGIX_framezoom + if (_glewStrSame3(&pos, &len, (const GLubyte*)"framezoom", 9)) + { + ret = GLEW_SGIX_framezoom; + continue; + } +#endif +#ifdef GL_SGIX_interlace + if (_glewStrSame3(&pos, &len, (const GLubyte*)"interlace", 9)) + { + ret = GLEW_SGIX_interlace; + continue; + } +#endif +#ifdef GL_SGIX_ir_instrument1 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"ir_instrument1", 14)) + { + ret = GLEW_SGIX_ir_instrument1; + continue; + } +#endif +#ifdef GL_SGIX_list_priority + if (_glewStrSame3(&pos, &len, (const GLubyte*)"list_priority", 13)) + { + ret = GLEW_SGIX_list_priority; + continue; + } +#endif +#ifdef GL_SGIX_pixel_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_texture", 13)) + { + ret = GLEW_SGIX_pixel_texture; + continue; + } +#endif +#ifdef GL_SGIX_pixel_texture_bits + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_texture_bits", 18)) + { + ret = GLEW_SGIX_pixel_texture_bits; + continue; + } +#endif +#ifdef GL_SGIX_reference_plane + if (_glewStrSame3(&pos, &len, (const GLubyte*)"reference_plane", 15)) + { + ret = GLEW_SGIX_reference_plane; + continue; + } +#endif +#ifdef GL_SGIX_resample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"resample", 8)) + { + ret = GLEW_SGIX_resample; + continue; + } +#endif +#ifdef GL_SGIX_shadow + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shadow", 6)) + { + ret = GLEW_SGIX_shadow; + continue; + } +#endif +#ifdef GL_SGIX_shadow_ambient + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shadow_ambient", 14)) + { + ret = GLEW_SGIX_shadow_ambient; + continue; + } +#endif +#ifdef GL_SGIX_sprite + if (_glewStrSame3(&pos, &len, (const GLubyte*)"sprite", 6)) + { + ret = GLEW_SGIX_sprite; + continue; + } +#endif +#ifdef GL_SGIX_tag_sample_buffer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"tag_sample_buffer", 17)) + { + ret = GLEW_SGIX_tag_sample_buffer; + continue; + } +#endif +#ifdef GL_SGIX_texture_add_env + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_add_env", 15)) + { + ret = GLEW_SGIX_texture_add_env; + continue; + } +#endif +#ifdef GL_SGIX_texture_coordinate_clamp + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_coordinate_clamp", 24)) + { + ret = GLEW_SGIX_texture_coordinate_clamp; + continue; + } +#endif +#ifdef GL_SGIX_texture_lod_bias + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_lod_bias", 16)) + { + ret = GLEW_SGIX_texture_lod_bias; + continue; + } +#endif +#ifdef GL_SGIX_texture_multi_buffer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_multi_buffer", 20)) + { + ret = GLEW_SGIX_texture_multi_buffer; + continue; + } +#endif +#ifdef GL_SGIX_texture_range + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_range", 13)) + { + ret = GLEW_SGIX_texture_range; + continue; + } +#endif +#ifdef GL_SGIX_texture_scale_bias + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_scale_bias", 18)) + { + ret = GLEW_SGIX_texture_scale_bias; + continue; + } +#endif +#ifdef GL_SGIX_vertex_preclip + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_preclip", 14)) + { + ret = GLEW_SGIX_vertex_preclip; + continue; + } +#endif +#ifdef GL_SGIX_vertex_preclip_hint + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_preclip_hint", 19)) + { + ret = GLEW_SGIX_vertex_preclip_hint; + continue; + } +#endif +#ifdef GL_SGIX_ycrcb + if (_glewStrSame3(&pos, &len, (const GLubyte*)"ycrcb", 5)) + { + ret = GLEW_SGIX_ycrcb; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"SGI_", 4)) + { +#ifdef GL_SGI_color_matrix + if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_matrix", 12)) + { + ret = GLEW_SGI_color_matrix; + continue; + } +#endif +#ifdef GL_SGI_color_table + if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_table", 11)) + { + ret = GLEW_SGI_color_table; + continue; + } +#endif +#ifdef GL_SGI_texture_color_table + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_color_table", 19)) + { + ret = GLEW_SGI_texture_color_table; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"SUNX_", 5)) + { +#ifdef GL_SUNX_constant_data + if (_glewStrSame3(&pos, &len, (const GLubyte*)"constant_data", 13)) + { + ret = GLEW_SUNX_constant_data; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"SUN_", 4)) + { +#ifdef GL_SUN_convolution_border_modes + if (_glewStrSame3(&pos, &len, (const GLubyte*)"convolution_border_modes", 24)) + { + ret = GLEW_SUN_convolution_border_modes; + continue; + } +#endif +#ifdef GL_SUN_global_alpha + if (_glewStrSame3(&pos, &len, (const GLubyte*)"global_alpha", 12)) + { + ret = GLEW_SUN_global_alpha; + continue; + } +#endif +#ifdef GL_SUN_mesh_array + if (_glewStrSame3(&pos, &len, (const GLubyte*)"mesh_array", 10)) + { + ret = GLEW_SUN_mesh_array; + continue; + } +#endif +#ifdef GL_SUN_read_video_pixels + if (_glewStrSame3(&pos, &len, (const GLubyte*)"read_video_pixels", 17)) + { + ret = GLEW_SUN_read_video_pixels; + continue; + } +#endif +#ifdef GL_SUN_slice_accum + if (_glewStrSame3(&pos, &len, (const GLubyte*)"slice_accum", 11)) + { + ret = GLEW_SUN_slice_accum; + continue; + } +#endif +#ifdef GL_SUN_triangle_list + if (_glewStrSame3(&pos, &len, (const GLubyte*)"triangle_list", 13)) + { + ret = GLEW_SUN_triangle_list; + continue; + } +#endif +#ifdef GL_SUN_vertex + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex", 6)) + { + ret = GLEW_SUN_vertex; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"WIN_", 4)) + { +#ifdef GL_WIN_phong_shading + if (_glewStrSame3(&pos, &len, (const GLubyte*)"phong_shading", 13)) + { + ret = GLEW_WIN_phong_shading; + continue; + } +#endif +#ifdef GL_WIN_specular_fog + if (_glewStrSame3(&pos, &len, (const GLubyte*)"specular_fog", 12)) + { + ret = GLEW_WIN_specular_fog; + continue; + } +#endif +#ifdef GL_WIN_swap_hint + if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_hint", 9)) + { + ret = GLEW_WIN_swap_hint; + continue; + } +#endif + } + } + ret = (len == 0); + } + return ret; +} + +#if defined(_WIN32) + +#if defined(GLEW_MX) +GLboolean wglewContextIsSupported (WGLEWContext* ctx, const char* name) +#else +GLboolean wglewIsSupported (const char* name) +#endif +{ + GLubyte* pos = (GLubyte*)name; + GLuint len = _glewStrLen(pos); + GLboolean ret = GL_TRUE; + while (ret && len > 0) + { + if (_glewStrSame1(&pos, &len, (const GLubyte*)"WGL_", 4)) + { + if (_glewStrSame2(&pos, &len, (const GLubyte*)"3DFX_", 5)) + { +#ifdef WGL_3DFX_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11)) + { + ret = WGLEW_3DFX_multisample; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"3DL_", 4)) + { +#ifdef WGL_3DL_stereo_control + if (_glewStrSame3(&pos, &len, (const GLubyte*)"stereo_control", 14)) + { + ret = WGLEW_3DL_stereo_control; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"ARB_", 4)) + { +#ifdef WGL_ARB_buffer_region + if (_glewStrSame3(&pos, &len, (const GLubyte*)"buffer_region", 13)) + { + ret = WGLEW_ARB_buffer_region; + continue; + } +#endif +#ifdef WGL_ARB_create_context + if (_glewStrSame3(&pos, &len, (const GLubyte*)"create_context", 14)) + { + ret = WGLEW_ARB_create_context; + continue; + } +#endif +#ifdef WGL_ARB_extensions_string + if (_glewStrSame3(&pos, &len, (const GLubyte*)"extensions_string", 17)) + { + ret = WGLEW_ARB_extensions_string; + continue; + } +#endif +#ifdef WGL_ARB_framebuffer_sRGB + if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_sRGB", 16)) + { + ret = WGLEW_ARB_framebuffer_sRGB; + continue; + } +#endif +#ifdef WGL_ARB_make_current_read + if (_glewStrSame3(&pos, &len, (const GLubyte*)"make_current_read", 17)) + { + ret = WGLEW_ARB_make_current_read; + continue; + } +#endif +#ifdef WGL_ARB_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11)) + { + ret = WGLEW_ARB_multisample; + continue; + } +#endif +#ifdef WGL_ARB_pbuffer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pbuffer", 7)) + { + ret = WGLEW_ARB_pbuffer; + continue; + } +#endif +#ifdef WGL_ARB_pixel_format + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_format", 12)) + { + ret = WGLEW_ARB_pixel_format; + continue; + } +#endif +#ifdef WGL_ARB_pixel_format_float + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_format_float", 18)) + { + ret = WGLEW_ARB_pixel_format_float; + continue; + } +#endif +#ifdef WGL_ARB_render_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"render_texture", 14)) + { + ret = WGLEW_ARB_render_texture; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"ATI_", 4)) + { +#ifdef WGL_ATI_pixel_format_float + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_format_float", 18)) + { + ret = WGLEW_ATI_pixel_format_float; + continue; + } +#endif +#ifdef WGL_ATI_render_texture_rectangle + if (_glewStrSame3(&pos, &len, (const GLubyte*)"render_texture_rectangle", 24)) + { + ret = WGLEW_ATI_render_texture_rectangle; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"EXT_", 4)) + { +#ifdef WGL_EXT_depth_float + if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_float", 11)) + { + ret = WGLEW_EXT_depth_float; + continue; + } +#endif +#ifdef WGL_EXT_display_color_table + if (_glewStrSame3(&pos, &len, (const GLubyte*)"display_color_table", 19)) + { + ret = WGLEW_EXT_display_color_table; + continue; + } +#endif +#ifdef WGL_EXT_extensions_string + if (_glewStrSame3(&pos, &len, (const GLubyte*)"extensions_string", 17)) + { + ret = WGLEW_EXT_extensions_string; + continue; + } +#endif +#ifdef WGL_EXT_framebuffer_sRGB + if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_sRGB", 16)) + { + ret = WGLEW_EXT_framebuffer_sRGB; + continue; + } +#endif +#ifdef WGL_EXT_make_current_read + if (_glewStrSame3(&pos, &len, (const GLubyte*)"make_current_read", 17)) + { + ret = WGLEW_EXT_make_current_read; + continue; + } +#endif +#ifdef WGL_EXT_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11)) + { + ret = WGLEW_EXT_multisample; + continue; + } +#endif +#ifdef WGL_EXT_pbuffer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pbuffer", 7)) + { + ret = WGLEW_EXT_pbuffer; + continue; + } +#endif +#ifdef WGL_EXT_pixel_format + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_format", 12)) + { + ret = WGLEW_EXT_pixel_format; + continue; + } +#endif +#ifdef WGL_EXT_pixel_format_packed_float + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_format_packed_float", 25)) + { + ret = WGLEW_EXT_pixel_format_packed_float; + continue; + } +#endif +#ifdef WGL_EXT_swap_control + if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_control", 12)) + { + ret = WGLEW_EXT_swap_control; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"I3D_", 4)) + { +#ifdef WGL_I3D_digital_video_control + if (_glewStrSame3(&pos, &len, (const GLubyte*)"digital_video_control", 21)) + { + ret = WGLEW_I3D_digital_video_control; + continue; + } +#endif +#ifdef WGL_I3D_gamma + if (_glewStrSame3(&pos, &len, (const GLubyte*)"gamma", 5)) + { + ret = WGLEW_I3D_gamma; + continue; + } +#endif +#ifdef WGL_I3D_genlock + if (_glewStrSame3(&pos, &len, (const GLubyte*)"genlock", 7)) + { + ret = WGLEW_I3D_genlock; + continue; + } +#endif +#ifdef WGL_I3D_image_buffer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"image_buffer", 12)) + { + ret = WGLEW_I3D_image_buffer; + continue; + } +#endif +#ifdef WGL_I3D_swap_frame_lock + if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_frame_lock", 15)) + { + ret = WGLEW_I3D_swap_frame_lock; + continue; + } +#endif +#ifdef WGL_I3D_swap_frame_usage + if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_frame_usage", 16)) + { + ret = WGLEW_I3D_swap_frame_usage; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"NV_", 3)) + { +#ifdef WGL_NV_float_buffer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"float_buffer", 12)) + { + ret = WGLEW_NV_float_buffer; + continue; + } +#endif +#ifdef WGL_NV_gpu_affinity + if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_affinity", 12)) + { + ret = WGLEW_NV_gpu_affinity; + continue; + } +#endif +#ifdef WGL_NV_present_video + if (_glewStrSame3(&pos, &len, (const GLubyte*)"present_video", 13)) + { + ret = WGLEW_NV_present_video; + continue; + } +#endif +#ifdef WGL_NV_render_depth_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"render_depth_texture", 20)) + { + ret = WGLEW_NV_render_depth_texture; + continue; + } +#endif +#ifdef WGL_NV_render_texture_rectangle + if (_glewStrSame3(&pos, &len, (const GLubyte*)"render_texture_rectangle", 24)) + { + ret = WGLEW_NV_render_texture_rectangle; + continue; + } +#endif +#ifdef WGL_NV_swap_group + if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_group", 10)) + { + ret = WGLEW_NV_swap_group; + continue; + } +#endif +#ifdef WGL_NV_vertex_array_range + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_range", 18)) + { + ret = WGLEW_NV_vertex_array_range; + continue; + } +#endif +#ifdef WGL_NV_video_output + if (_glewStrSame3(&pos, &len, (const GLubyte*)"video_output", 12)) + { + ret = WGLEW_NV_video_output; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"OML_", 4)) + { +#ifdef WGL_OML_sync_control + if (_glewStrSame3(&pos, &len, (const GLubyte*)"sync_control", 12)) + { + ret = WGLEW_OML_sync_control; + continue; + } +#endif + } + } + ret = (len == 0); + } + return ret; +} + +#elif !defined(__APPLE__) || defined(GLEW_APPLE_GLX) + +#if defined(GLEW_MX) +GLboolean glxewContextIsSupported (GLXEWContext* ctx, const char* name) +#else +GLboolean glxewIsSupported (const char* name) +#endif +{ + GLubyte* pos = (GLubyte*)name; + GLuint len = _glewStrLen(pos); + GLboolean ret = GL_TRUE; + while (ret && len > 0) + { + if(_glewStrSame1(&pos, &len, (const GLubyte*)"GLX_", 4)) + { + if (_glewStrSame2(&pos, &len, (const GLubyte*)"VERSION_", 8)) + { +#ifdef GLX_VERSION_1_2 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_2", 3)) + { + ret = GLXEW_VERSION_1_2; + continue; + } +#endif +#ifdef GLX_VERSION_1_3 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_3", 3)) + { + ret = GLXEW_VERSION_1_3; + continue; + } +#endif +#ifdef GLX_VERSION_1_4 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_4", 3)) + { + ret = GLXEW_VERSION_1_4; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"3DFX_", 5)) + { +#ifdef GLX_3DFX_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11)) + { + ret = GLXEW_3DFX_multisample; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"ARB_", 4)) + { +#ifdef GLX_ARB_create_context + if (_glewStrSame3(&pos, &len, (const GLubyte*)"create_context", 14)) + { + ret = GLXEW_ARB_create_context; + continue; + } +#endif +#ifdef GLX_ARB_fbconfig_float + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fbconfig_float", 14)) + { + ret = GLXEW_ARB_fbconfig_float; + continue; + } +#endif +#ifdef GLX_ARB_framebuffer_sRGB + if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_sRGB", 16)) + { + ret = GLXEW_ARB_framebuffer_sRGB; + continue; + } +#endif +#ifdef GLX_ARB_get_proc_address + if (_glewStrSame3(&pos, &len, (const GLubyte*)"get_proc_address", 16)) + { + ret = GLXEW_ARB_get_proc_address; + continue; + } +#endif +#ifdef GLX_ARB_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11)) + { + ret = GLXEW_ARB_multisample; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"ATI_", 4)) + { +#ifdef GLX_ATI_pixel_format_float + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_format_float", 18)) + { + ret = GLXEW_ATI_pixel_format_float; + continue; + } +#endif +#ifdef GLX_ATI_render_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"render_texture", 14)) + { + ret = GLXEW_ATI_render_texture; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"EXT_", 4)) + { +#ifdef GLX_EXT_fbconfig_packed_float + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fbconfig_packed_float", 21)) + { + ret = GLXEW_EXT_fbconfig_packed_float; + continue; + } +#endif +#ifdef GLX_EXT_framebuffer_sRGB + if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_sRGB", 16)) + { + ret = GLXEW_EXT_framebuffer_sRGB; + continue; + } +#endif +#ifdef GLX_EXT_import_context + if (_glewStrSame3(&pos, &len, (const GLubyte*)"import_context", 14)) + { + ret = GLXEW_EXT_import_context; + continue; + } +#endif +#ifdef GLX_EXT_scene_marker + if (_glewStrSame3(&pos, &len, (const GLubyte*)"scene_marker", 12)) + { + ret = GLXEW_EXT_scene_marker; + continue; + } +#endif +#ifdef GLX_EXT_texture_from_pixmap + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_from_pixmap", 19)) + { + ret = GLXEW_EXT_texture_from_pixmap; + continue; + } +#endif +#ifdef GLX_EXT_visual_info + if (_glewStrSame3(&pos, &len, (const GLubyte*)"visual_info", 11)) + { + ret = GLXEW_EXT_visual_info; + continue; + } +#endif +#ifdef GLX_EXT_visual_rating + if (_glewStrSame3(&pos, &len, (const GLubyte*)"visual_rating", 13)) + { + ret = GLXEW_EXT_visual_rating; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"MESA_", 5)) + { +#ifdef GLX_MESA_agp_offset + if (_glewStrSame3(&pos, &len, (const GLubyte*)"agp_offset", 10)) + { + ret = GLXEW_MESA_agp_offset; + continue; + } +#endif +#ifdef GLX_MESA_copy_sub_buffer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"copy_sub_buffer", 15)) + { + ret = GLXEW_MESA_copy_sub_buffer; + continue; + } +#endif +#ifdef GLX_MESA_pixmap_colormap + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixmap_colormap", 15)) + { + ret = GLXEW_MESA_pixmap_colormap; + continue; + } +#endif +#ifdef GLX_MESA_release_buffers + if (_glewStrSame3(&pos, &len, (const GLubyte*)"release_buffers", 15)) + { + ret = GLXEW_MESA_release_buffers; + continue; + } +#endif +#ifdef GLX_MESA_set_3dfx_mode + if (_glewStrSame3(&pos, &len, (const GLubyte*)"set_3dfx_mode", 13)) + { + ret = GLXEW_MESA_set_3dfx_mode; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"NV_", 3)) + { +#ifdef GLX_NV_float_buffer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"float_buffer", 12)) + { + ret = GLXEW_NV_float_buffer; + continue; + } +#endif +#ifdef GLX_NV_present_video + if (_glewStrSame3(&pos, &len, (const GLubyte*)"present_video", 13)) + { + ret = GLXEW_NV_present_video; + continue; + } +#endif +#ifdef GLX_NV_swap_group + if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_group", 10)) + { + ret = GLXEW_NV_swap_group; + continue; + } +#endif +#ifdef GLX_NV_vertex_array_range + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_range", 18)) + { + ret = GLXEW_NV_vertex_array_range; + continue; + } +#endif +#ifdef GLX_NV_video_output + if (_glewStrSame3(&pos, &len, (const GLubyte*)"video_output", 12)) + { + ret = GLXEW_NV_video_output; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"OML_", 4)) + { +#ifdef GLX_OML_swap_method + if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_method", 11)) + { + ret = GLXEW_OML_swap_method; + continue; + } +#endif +#if defined(GLX_OML_sync_control) && defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +#include <inttypes.h> + if (_glewStrSame3(&pos, &len, (const GLubyte*)"sync_control", 12)) + { + ret = GLXEW_OML_sync_control; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"SGIS_", 5)) + { +#ifdef GLX_SGIS_blended_overlay + if (_glewStrSame3(&pos, &len, (const GLubyte*)"blended_overlay", 15)) + { + ret = GLXEW_SGIS_blended_overlay; + continue; + } +#endif +#ifdef GLX_SGIS_color_range + if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_range", 11)) + { + ret = GLXEW_SGIS_color_range; + continue; + } +#endif +#ifdef GLX_SGIS_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11)) + { + ret = GLXEW_SGIS_multisample; + continue; + } +#endif +#ifdef GLX_SGIS_shared_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shared_multisample", 18)) + { + ret = GLXEW_SGIS_shared_multisample; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"SGIX_", 5)) + { +#ifdef GLX_SGIX_fbconfig + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fbconfig", 8)) + { + ret = GLXEW_SGIX_fbconfig; + continue; + } +#endif +#ifdef GLX_SGIX_hyperpipe + if (_glewStrSame3(&pos, &len, (const GLubyte*)"hyperpipe", 9)) + { + ret = GLXEW_SGIX_hyperpipe; + continue; + } +#endif +#ifdef GLX_SGIX_pbuffer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pbuffer", 7)) + { + ret = GLXEW_SGIX_pbuffer; + continue; + } +#endif +#ifdef GLX_SGIX_swap_barrier + if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_barrier", 12)) + { + ret = GLXEW_SGIX_swap_barrier; + continue; + } +#endif +#ifdef GLX_SGIX_swap_group + if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_group", 10)) + { + ret = GLXEW_SGIX_swap_group; + continue; + } +#endif +#ifdef GLX_SGIX_video_resize + if (_glewStrSame3(&pos, &len, (const GLubyte*)"video_resize", 12)) + { + ret = GLXEW_SGIX_video_resize; + continue; + } +#endif +#ifdef GLX_SGIX_visual_select_group + if (_glewStrSame3(&pos, &len, (const GLubyte*)"visual_select_group", 19)) + { + ret = GLXEW_SGIX_visual_select_group; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"SGI_", 4)) + { +#ifdef GLX_SGI_cushion + if (_glewStrSame3(&pos, &len, (const GLubyte*)"cushion", 7)) + { + ret = GLXEW_SGI_cushion; + continue; + } +#endif +#ifdef GLX_SGI_make_current_read + if (_glewStrSame3(&pos, &len, (const GLubyte*)"make_current_read", 17)) + { + ret = GLXEW_SGI_make_current_read; + continue; + } +#endif +#ifdef GLX_SGI_swap_control + if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_control", 12)) + { + ret = GLXEW_SGI_swap_control; + continue; + } +#endif +#ifdef GLX_SGI_video_sync + if (_glewStrSame3(&pos, &len, (const GLubyte*)"video_sync", 10)) + { + ret = GLXEW_SGI_video_sync; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"SUN_", 4)) + { +#ifdef GLX_SUN_get_transparent_index + if (_glewStrSame3(&pos, &len, (const GLubyte*)"get_transparent_index", 21)) + { + ret = GLXEW_SUN_get_transparent_index; + continue; + } +#endif +#ifdef GLX_SUN_video_resize + if (_glewStrSame3(&pos, &len, (const GLubyte*)"video_resize", 12)) + { + ret = GLXEW_SUN_video_resize; + continue; + } +#endif + } + } + ret = (len == 0); + } + return ret; +} + +#endif /* _WIN32 */ diff --git a/mod/pub.mod/glew.mod/glew2bmx.bmx b/mod/pub.mod/glew.mod/glew2bmx.bmx new file mode 100644 index 0000000..1855f5c --- /dev/null +++ b/mod/pub.mod/glew.mod/glew2bmx.bmx @@ -0,0 +1,211 @@ + +Strict + +Framework brl.basic + +Import brl.map + +Rem + +Cheezy little app to convert glew.h to bmx source. + +Run this, then copy 'n' paste the output into opengl.bmx +(everything <=glViewport) and glew.bmx (the rest!) + +End Rem + +Global in:TStream=ReadStream( "GL/glew.h" ) + +Global curr$,text$ + +Local funMap:TMap=New TMap +Local constMap:TMap=New TMap + +While Not Eof(in) + text=in.ReadLine() + bump + If curr="GLAPI" + bump + Local funty$=gltype() + If funty<>"x" And curr="GLAPIENTRY" + Local id$=bump() + If id[..2]="gl" And bump()="(" + Local proto$=glproto() + If proto<>"x" + Print "Function "+id+funty+"("+proto+")" + EndIf + EndIf + EndIf + Else If curr="#" + If bump()="define" + Local id$=bump() + If id[..11]="GL_VERSION_" + + Else If id[..3]="GL_" + If Not constMap.ValueForKey(id) + Local n$=bump() + If n[..2]="0x" + Print "Const "+id+"=$"+n[2..] + Else If n.length And isdigit(n[0]) And n<>"1" + Print "Const "+id+"="+n + EndIf + constMap.Insert id,n + EndIf + Else If id[..5]="GLEW_" + If bump()="GLEW_GET_VAR" And bump()="(" + Local sym$=bump() + If sym[..7]="__GLEW_" And bump()=")" + Print "Global GL_"+id[5..]+":Byte=~q"+sym+"~q" + EndIf + EndIf + Else If id[..2]="gl" + If bump()="GLEW_GET_FUN" And bump()="(" + Local sym$=bump() + If sym[..6]="__glew" And bump()=")" + Local key$="PFNGL"+sym[6..].ToUpper()+"PROC" + Local val$=String( funMap.ValueForKey( key ) ) + If val + Print "Global "+id+val+"=~q"+sym+"~q" + Else + Print "***** "+sym+" *****" + EndIf + EndIf + EndIf + EndIf + EndIf + Else If curr="typedef" + bump + Local funty$=gltype() + If funty<>"x" And curr="(" And bump()="GLAPIENTRY" And bump()="*" + Local id$=bump() + If id[..5]="PFNGL" And bump()=")" And bump()="(" + Local proto$=glproto() + If proto<>"x" + funMap.Insert id,funty+"("+proto+")" + EndIf + EndIf + EndIf + EndIf +Wend + +in.Close + +Function glproto$() + If bump()=")" Return "" + Local proto$,err,argid + Repeat + Local argty$=gltype() + If argty="x" Return argty + Local id$ + If curr<>"," And curr<>")" And curr.length And (isalpha(curr[0]) Or curr[0]=Asc("_")) + id$=curr + If bump()="[" + While bump()<>"]" + Wend + bump + If Not argty argty="Byte" + argty:+" Ptr" + EndIf + Else + id="arg"+argid + EndIf + argid:+1 + If proto proto:+"," + proto:+id+"_"+argty + If curr=")" + bump + If proto="arg0_" proto="" + Return proto + EndIf + If curr<>"," Return "x" + bump + Forever +End Function + +Function gltype$() + Local ty$ + If curr="const" + bump + EndIf + Select curr + Case "void","GLvoid" + ty="" + Case "char","GLbyte","GLubyte","GLchar","GLboolean","GLcharARB" + ty="Byte" + Case "GLshort","GLushort","GLhalf" + ty="Short" + Case "GLint","GLuint","GLenum","GLsizei","GLbitfield" + ty="Int" + Case "GLintptr","GLsizeiptr","GLintptrARB","GLsizeiptrARB" + ty="Int" + Case "GLhandleARB" + ty="Int" + Case "GLint64EXT","GLuint64EXT" + ty="Long" + Case "GLfloat","GLclampf" + ty="Float" + Case "GLdouble","GLclampd" + ty="Double" + Default + Return "x" + End Select + Repeat + bump + If curr="const" bump + If curr<>"*" Exit + If Not ty ty="Byte" + ty:+" Ptr" + Forever + If ty ty=":"+ty + Return ty +End Function + +Function isalpha( c ) + Return (c>=Asc("A") And c<=Asc("Z")) Or (c>=Asc("a") And c<=Asc("z")) +End Function + +Function isdigit( c ) + Return c>=Asc("0") And c<=Asc("9") +End Function + +Function isalnum( c ) + Return isalpha(c) Or isdigit(c) +End Function + +Function isxdigit( c ) + Return (c>=Asc("A") And c<=Asc("F")) Or (c>=Asc("a") And c<=Asc("f")) Or isdigit(c) +End Function + +Function bump$() + Local i=0 + While i<text.length And text[i]<=Asc(" ") + i:+1 + Wend + If i=text.length + curr="" + text="" + Return curr + EndIf + text=text[i..] + Local c=text[0] + i=1 + If isalpha(c) Or c=Asc("_") + While i<text.length And (isalnum( text[i] ) Or text[i]=Asc("_")) + i:+1 + Wend + Else If c>=Asc("0") And c<=Asc("9") + If i<text.length And c=Asc("0") And text[i]=Asc("x") + i:+1 + While i<text.length And isxdigit(text[i]) + i:+1 + Wend + Else + While i<text.length And isdigit(text[i]) + i:+1 + Wend + EndIf + EndIf + curr=text[..i] + text=text[i..] + Return curr +End Function diff --git a/mod/pub.mod/glew.mod/glew_static.c b/mod/pub.mod/glew.mod/glew_static.c new file mode 100644 index 0000000..c67530c --- /dev/null +++ b/mod/pub.mod/glew.mod/glew_static.c @@ -0,0 +1,3 @@ + +#define GLEW_STATIC 1 +#include "glew.c" diff --git a/mod/pub.mod/libjpeg.mod/jcapimin.c b/mod/pub.mod/libjpeg.mod/jcapimin.c new file mode 100644 index 0000000..54fb8c5 --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jcapimin.c @@ -0,0 +1,280 @@ +/* + * jcapimin.c + * + * Copyright (C) 1994-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains application interface code for the compression half + * of the JPEG library. These are the "minimum" API routines that may be + * needed in either the normal full-compression case or the transcoding-only + * case. + * + * Most of the routines intended to be called directly by an application + * are in this file or in jcapistd.c. But also see jcparam.c for + * parameter-setup helper routines, jcomapi.c for routines shared by + * compression and decompression, and jctrans.c for the transcoding case. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* + * Initialization of a JPEG compression object. + * The error manager must already be set up (in case memory manager fails). + */ + +GLOBAL(void) +jpeg_CreateCompress (j_compress_ptr cinfo, int version, size_t structsize) +{ + int i; + + /* Guard against version mismatches between library and caller. */ + cinfo->mem = NULL; /* so jpeg_destroy knows mem mgr not called */ + if (version != JPEG_LIB_VERSION) + ERREXIT2(cinfo, JERR_BAD_LIB_VERSION, JPEG_LIB_VERSION, version); + if (structsize != SIZEOF(struct jpeg_compress_struct)) + ERREXIT2(cinfo, JERR_BAD_STRUCT_SIZE, + (int) SIZEOF(struct jpeg_compress_struct), (int) structsize); + + /* For debugging purposes, we zero the whole master structure. + * But the application has already set the err pointer, and may have set + * client_data, so we have to save and restore those fields. + * Note: if application hasn't set client_data, tools like Purify may + * complain here. + */ + { + struct jpeg_error_mgr * err = cinfo->err; + void * client_data = cinfo->client_data; /* ignore Purify complaint here */ + MEMZERO(cinfo, SIZEOF(struct jpeg_compress_struct)); + cinfo->err = err; + cinfo->client_data = client_data; + } + cinfo->is_decompressor = FALSE; + + /* Initialize a memory manager instance for this object */ + jinit_memory_mgr((j_common_ptr) cinfo); + + /* Zero out pointers to permanent structures. */ + cinfo->progress = NULL; + cinfo->dest = NULL; + + cinfo->comp_info = NULL; + + for (i = 0; i < NUM_QUANT_TBLS; i++) + cinfo->quant_tbl_ptrs[i] = NULL; + + for (i = 0; i < NUM_HUFF_TBLS; i++) { + cinfo->dc_huff_tbl_ptrs[i] = NULL; + cinfo->ac_huff_tbl_ptrs[i] = NULL; + } + + cinfo->script_space = NULL; + + cinfo->input_gamma = 1.0; /* in case application forgets */ + + /* OK, I'm ready */ + cinfo->global_state = CSTATE_START; +} + + +/* + * Destruction of a JPEG compression object + */ + +GLOBAL(void) +jpeg_destroy_compress (j_compress_ptr cinfo) +{ + jpeg_destroy((j_common_ptr) cinfo); /* use common routine */ +} + + +/* + * Abort processing of a JPEG compression operation, + * but don't destroy the object itself. + */ + +GLOBAL(void) +jpeg_abort_compress (j_compress_ptr cinfo) +{ + jpeg_abort((j_common_ptr) cinfo); /* use common routine */ +} + + +/* + * Forcibly suppress or un-suppress all quantization and Huffman tables. + * Marks all currently defined tables as already written (if suppress) + * or not written (if !suppress). This will control whether they get emitted + * by a subsequent jpeg_start_compress call. + * + * This routine is exported for use by applications that want to produce + * abbreviated JPEG datastreams. It logically belongs in jcparam.c, but + * since it is called by jpeg_start_compress, we put it here --- otherwise + * jcparam.o would be linked whether the application used it or not. + */ + +GLOBAL(void) +jpeg_suppress_tables (j_compress_ptr cinfo, boolean suppress) +{ + int i; + JQUANT_TBL * qtbl; + JHUFF_TBL * htbl; + + for (i = 0; i < NUM_QUANT_TBLS; i++) { + if ((qtbl = cinfo->quant_tbl_ptrs[i]) != NULL) + qtbl->sent_table = suppress; + } + + for (i = 0; i < NUM_HUFF_TBLS; i++) { + if ((htbl = cinfo->dc_huff_tbl_ptrs[i]) != NULL) + htbl->sent_table = suppress; + if ((htbl = cinfo->ac_huff_tbl_ptrs[i]) != NULL) + htbl->sent_table = suppress; + } +} + + +/* + * Finish JPEG compression. + * + * If a multipass operating mode was selected, this may do a great deal of + * work including most of the actual output. + */ + +GLOBAL(void) +jpeg_finish_compress (j_compress_ptr cinfo) +{ + JDIMENSION iMCU_row; + + if (cinfo->global_state == CSTATE_SCANNING || + cinfo->global_state == CSTATE_RAW_OK) { + /* Terminate first pass */ + if (cinfo->next_scanline < cinfo->image_height) + ERREXIT(cinfo, JERR_TOO_LITTLE_DATA); + (*cinfo->master->finish_pass) (cinfo); + } else if (cinfo->global_state != CSTATE_WRCOEFS) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + /* Perform any remaining passes */ + while (! cinfo->master->is_last_pass) { + (*cinfo->master->prepare_for_pass) (cinfo); + for (iMCU_row = 0; iMCU_row < cinfo->total_iMCU_rows; iMCU_row++) { + if (cinfo->progress != NULL) { + cinfo->progress->pass_counter = (long) iMCU_row; + cinfo->progress->pass_limit = (long) cinfo->total_iMCU_rows; + (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); + } + /* We bypass the main controller and invoke coef controller directly; + * all work is being done from the coefficient buffer. + */ + if (! (*cinfo->coef->compress_data) (cinfo, (JSAMPIMAGE) NULL)) + ERREXIT(cinfo, JERR_CANT_SUSPEND); + } + (*cinfo->master->finish_pass) (cinfo); + } + /* Write EOI, do final cleanup */ + (*cinfo->marker->write_file_trailer) (cinfo); + (*cinfo->dest->term_destination) (cinfo); + /* We can use jpeg_abort to release memory and reset global_state */ + jpeg_abort((j_common_ptr) cinfo); +} + + +/* + * Write a special marker. + * This is only recommended for writing COM or APPn markers. + * Must be called after jpeg_start_compress() and before + * first call to jpeg_write_scanlines() or jpeg_write_raw_data(). + */ + +GLOBAL(void) +jpeg_write_marker (j_compress_ptr cinfo, int marker, + const JOCTET *dataptr, unsigned int datalen) +{ + JMETHOD(void, write_marker_byte, (j_compress_ptr info, int val)); + + if (cinfo->next_scanline != 0 || + (cinfo->global_state != CSTATE_SCANNING && + cinfo->global_state != CSTATE_RAW_OK && + cinfo->global_state != CSTATE_WRCOEFS)) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + + (*cinfo->marker->write_marker_header) (cinfo, marker, datalen); + write_marker_byte = cinfo->marker->write_marker_byte; /* copy for speed */ + while (datalen--) { + (*write_marker_byte) (cinfo, *dataptr); + dataptr++; + } +} + +/* Same, but piecemeal. */ + +GLOBAL(void) +jpeg_write_m_header (j_compress_ptr cinfo, int marker, unsigned int datalen) +{ + if (cinfo->next_scanline != 0 || + (cinfo->global_state != CSTATE_SCANNING && + cinfo->global_state != CSTATE_RAW_OK && + cinfo->global_state != CSTATE_WRCOEFS)) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + + (*cinfo->marker->write_marker_header) (cinfo, marker, datalen); +} + +GLOBAL(void) +jpeg_write_m_byte (j_compress_ptr cinfo, int val) +{ + (*cinfo->marker->write_marker_byte) (cinfo, val); +} + + +/* + * Alternate compression function: just write an abbreviated table file. + * Before calling this, all parameters and a data destination must be set up. + * + * To produce a pair of files containing abbreviated tables and abbreviated + * image data, one would proceed as follows: + * + * initialize JPEG object + * set JPEG parameters + * set destination to table file + * jpeg_write_tables(cinfo); + * set destination to image file + * jpeg_start_compress(cinfo, FALSE); + * write data... + * jpeg_finish_compress(cinfo); + * + * jpeg_write_tables has the side effect of marking all tables written + * (same as jpeg_suppress_tables(..., TRUE)). Thus a subsequent start_compress + * will not re-emit the tables unless it is passed write_all_tables=TRUE. + */ + +GLOBAL(void) +jpeg_write_tables (j_compress_ptr cinfo) +{ + if (cinfo->global_state != CSTATE_START) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + + /* (Re)initialize error mgr and destination modules */ + (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo); + (*cinfo->dest->init_destination) (cinfo); + /* Initialize the marker writer ... bit of a crock to do it here. */ + jinit_marker_writer(cinfo); + /* Write them tables! */ + (*cinfo->marker->write_tables_only) (cinfo); + /* And clean up. */ + (*cinfo->dest->term_destination) (cinfo); + /* + * In library releases up through v6a, we called jpeg_abort() here to free + * any working memory allocated by the destination manager and marker + * writer. Some applications had a problem with that: they allocated space + * of their own from the library memory manager, and didn't want it to go + * away during write_tables. So now we do nothing. This will cause a + * memory leak if an app calls write_tables repeatedly without doing a full + * compression cycle or otherwise resetting the JPEG object. However, that + * seems less bad than unexpectedly freeing memory in the normal case. + * An app that prefers the old behavior can call jpeg_abort for itself after + * each call to jpeg_write_tables(). + */ +} diff --git a/mod/pub.mod/libjpeg.mod/jcapistd.c b/mod/pub.mod/libjpeg.mod/jcapistd.c new file mode 100644 index 0000000..c0320b1 --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jcapistd.c @@ -0,0 +1,161 @@ +/* + * jcapistd.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains application interface code for the compression half + * of the JPEG library. These are the "standard" API routines that are + * used in the normal full-compression case. They are not used by a + * transcoding-only application. Note that if an application links in + * jpeg_start_compress, it will end up linking in the entire compressor. + * We thus must separate this file from jcapimin.c to avoid linking the + * whole compression library into a transcoder. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* + * Compression initialization. + * Before calling this, all parameters and a data destination must be set up. + * + * We require a write_all_tables parameter as a failsafe check when writing + * multiple datastreams from the same compression object. Since prior runs + * will have left all the tables marked sent_table=TRUE, a subsequent run + * would emit an abbreviated stream (no tables) by default. This may be what + * is wanted, but for safety's sake it should not be the default behavior: + * programmers should have to make a deliberate choice to emit abbreviated + * images. Therefore the documentation and examples should encourage people + * to pass write_all_tables=TRUE; then it will take active thought to do the + * wrong thing. + */ + +GLOBAL(void) +jpeg_start_compress (j_compress_ptr cinfo, boolean write_all_tables) +{ + if (cinfo->global_state != CSTATE_START) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + + if (write_all_tables) + jpeg_suppress_tables(cinfo, FALSE); /* mark all tables to be written */ + + /* (Re)initialize error mgr and destination modules */ + (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo); + (*cinfo->dest->init_destination) (cinfo); + /* Perform master selection of active modules */ + jinit_compress_master(cinfo); + /* Set up for the first pass */ + (*cinfo->master->prepare_for_pass) (cinfo); + /* Ready for application to drive first pass through jpeg_write_scanlines + * or jpeg_write_raw_data. + */ + cinfo->next_scanline = 0; + cinfo->global_state = (cinfo->raw_data_in ? CSTATE_RAW_OK : CSTATE_SCANNING); +} + + +/* + * Write some scanlines of data to the JPEG compressor. + * + * The return value will be the number of lines actually written. + * This should be less than the supplied num_lines only in case that + * the data destination module has requested suspension of the compressor, + * or if more than image_height scanlines are passed in. + * + * Note: we warn about excess calls to jpeg_write_scanlines() since + * this likely signals an application programmer error. However, + * excess scanlines passed in the last valid call are *silently* ignored, + * so that the application need not adjust num_lines for end-of-image + * when using a multiple-scanline buffer. + */ + +GLOBAL(JDIMENSION) +jpeg_write_scanlines (j_compress_ptr cinfo, JSAMPARRAY scanlines, + JDIMENSION num_lines) +{ + JDIMENSION row_ctr, rows_left; + + if (cinfo->global_state != CSTATE_SCANNING) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + if (cinfo->next_scanline >= cinfo->image_height) + WARNMS(cinfo, JWRN_TOO_MUCH_DATA); + + /* Call progress monitor hook if present */ + if (cinfo->progress != NULL) { + cinfo->progress->pass_counter = (long) cinfo->next_scanline; + cinfo->progress->pass_limit = (long) cinfo->image_height; + (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); + } + + /* Give master control module another chance if this is first call to + * jpeg_write_scanlines. This lets output of the frame/scan headers be + * delayed so that application can write COM, etc, markers between + * jpeg_start_compress and jpeg_write_scanlines. + */ + if (cinfo->master->call_pass_startup) + (*cinfo->master->pass_startup) (cinfo); + + /* Ignore any extra scanlines at bottom of image. */ + rows_left = cinfo->image_height - cinfo->next_scanline; + if (num_lines > rows_left) + num_lines = rows_left; + + row_ctr = 0; + (*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, num_lines); + cinfo->next_scanline += row_ctr; + return row_ctr; +} + + +/* + * Alternate entry point to write raw data. + * Processes exactly one iMCU row per call, unless suspended. + */ + +GLOBAL(JDIMENSION) +jpeg_write_raw_data (j_compress_ptr cinfo, JSAMPIMAGE data, + JDIMENSION num_lines) +{ + JDIMENSION lines_per_iMCU_row; + + if (cinfo->global_state != CSTATE_RAW_OK) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + if (cinfo->next_scanline >= cinfo->image_height) { + WARNMS(cinfo, JWRN_TOO_MUCH_DATA); + return 0; + } + + /* Call progress monitor hook if present */ + if (cinfo->progress != NULL) { + cinfo->progress->pass_counter = (long) cinfo->next_scanline; + cinfo->progress->pass_limit = (long) cinfo->image_height; + (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); + } + + /* Give master control module another chance if this is first call to + * jpeg_write_raw_data. This lets output of the frame/scan headers be + * delayed so that application can write COM, etc, markers between + * jpeg_start_compress and jpeg_write_raw_data. + */ + if (cinfo->master->call_pass_startup) + (*cinfo->master->pass_startup) (cinfo); + + /* Verify that at least one iMCU row has been passed. */ + lines_per_iMCU_row = cinfo->max_v_samp_factor * DCTSIZE; + if (num_lines < lines_per_iMCU_row) + ERREXIT(cinfo, JERR_BUFFER_SIZE); + + /* Directly compress the row. */ + if (! (*cinfo->coef->compress_data) (cinfo, data)) { + /* If compressor did not consume the whole row, suspend processing. */ + return 0; + } + + /* OK, we processed one iMCU row. */ + cinfo->next_scanline += lines_per_iMCU_row; + return lines_per_iMCU_row; +} diff --git a/mod/pub.mod/libjpeg.mod/jccoefct.c b/mod/pub.mod/libjpeg.mod/jccoefct.c new file mode 100644 index 0000000..1963ddb --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jccoefct.c @@ -0,0 +1,449 @@ +/* + * jccoefct.c + * + * Copyright (C) 1994-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains the coefficient buffer controller for compression. + * This controller is the top level of the JPEG compressor proper. + * The coefficient buffer lies between forward-DCT and entropy encoding steps. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* We use a full-image coefficient buffer when doing Huffman optimization, + * and also for writing multiple-scan JPEG files. In all cases, the DCT + * step is run during the first pass, and subsequent passes need only read + * the buffered coefficients. + */ +#ifdef ENTROPY_OPT_SUPPORTED +#define FULL_COEF_BUFFER_SUPPORTED +#else +#ifdef C_MULTISCAN_FILES_SUPPORTED +#define FULL_COEF_BUFFER_SUPPORTED +#endif +#endif + + +/* Private buffer controller object */ + +typedef struct { + struct jpeg_c_coef_controller pub; /* public fields */ + + JDIMENSION iMCU_row_num; /* iMCU row # within image */ + JDIMENSION mcu_ctr; /* counts MCUs processed in current row */ + int MCU_vert_offset; /* counts MCU rows within iMCU row */ + int MCU_rows_per_iMCU_row; /* number of such rows needed */ + + /* For single-pass compression, it's sufficient to buffer just one MCU + * (although this may prove a bit slow in practice). We allocate a + * workspace of C_MAX_BLOCKS_IN_MCU coefficient blocks, and reuse it for each + * MCU constructed and sent. (On 80x86, the workspace is FAR even though + * it's not really very big; this is to keep the module interfaces unchanged + * when a large coefficient buffer is necessary.) + * In multi-pass modes, this array points to the current MCU's blocks + * within the virtual arrays. + */ + JBLOCKROW MCU_buffer[C_MAX_BLOCKS_IN_MCU]; + + /* In multi-pass modes, we need a virtual block array for each component. */ + jvirt_barray_ptr whole_image[MAX_COMPONENTS]; +} my_coef_controller; + +typedef my_coef_controller * my_coef_ptr; + + +/* Forward declarations */ +METHODDEF(boolean) compress_data + JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf)); +#ifdef FULL_COEF_BUFFER_SUPPORTED +METHODDEF(boolean) compress_first_pass + JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf)); +METHODDEF(boolean) compress_output + JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf)); +#endif + + +LOCAL(void) +start_iMCU_row (j_compress_ptr cinfo) +/* Reset within-iMCU-row counters for a new row */ +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + + /* In an interleaved scan, an MCU row is the same as an iMCU row. + * In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows. + * But at the bottom of the image, process only what's left. + */ + if (cinfo->comps_in_scan > 1) { + coef->MCU_rows_per_iMCU_row = 1; + } else { + if (coef->iMCU_row_num < (cinfo->total_iMCU_rows-1)) + coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor; + else + coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height; + } + + coef->mcu_ctr = 0; + coef->MCU_vert_offset = 0; +} + + +/* + * Initialize for a processing pass. + */ + +METHODDEF(void) +start_pass_coef (j_compress_ptr cinfo, J_BUF_MODE pass_mode) +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + + coef->iMCU_row_num = 0; + start_iMCU_row(cinfo); + + switch (pass_mode) { + case JBUF_PASS_THRU: + if (coef->whole_image[0] != NULL) + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + coef->pub.compress_data = compress_data; + break; +#ifdef FULL_COEF_BUFFER_SUPPORTED + case JBUF_SAVE_AND_PASS: + if (coef->whole_image[0] == NULL) + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + coef->pub.compress_data = compress_first_pass; + break; + case JBUF_CRANK_DEST: + if (coef->whole_image[0] == NULL) + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + coef->pub.compress_data = compress_output; + break; +#endif + default: + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + break; + } +} + + +/* + * Process some data in the single-pass case. + * We process the equivalent of one fully interleaved MCU row ("iMCU" row) + * per call, ie, v_samp_factor block rows for each component in the image. + * Returns TRUE if the iMCU row is completed, FALSE if suspended. + * + * NB: input_buf contains a plane for each component in image, + * which we index according to the component's SOF position. + */ + +METHODDEF(boolean) +compress_data (j_compress_ptr cinfo, JSAMPIMAGE input_buf) +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + JDIMENSION MCU_col_num; /* index of current MCU within row */ + JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1; + JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1; + int blkn, bi, ci, yindex, yoffset, blockcnt; + JDIMENSION ypos, xpos; + jpeg_component_info *compptr; + + /* Loop to write as much as one whole iMCU row */ + for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row; + yoffset++) { + for (MCU_col_num = coef->mcu_ctr; MCU_col_num <= last_MCU_col; + MCU_col_num++) { + /* Determine where data comes from in input_buf and do the DCT thing. + * Each call on forward_DCT processes a horizontal row of DCT blocks + * as wide as an MCU; we rely on having allocated the MCU_buffer[] blocks + * sequentially. Dummy blocks at the right or bottom edge are filled in + * specially. The data in them does not matter for image reconstruction, + * so we fill them with values that will encode to the smallest amount of + * data, viz: all zeroes in the AC entries, DC entries equal to previous + * block's DC value. (Thanks to Thomas Kinsman for this idea.) + */ + blkn = 0; + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + blockcnt = (MCU_col_num < last_MCU_col) ? compptr->MCU_width + : compptr->last_col_width; + xpos = MCU_col_num * compptr->MCU_sample_width; + ypos = yoffset * DCTSIZE; /* ypos == (yoffset+yindex) * DCTSIZE */ + for (yindex = 0; yindex < compptr->MCU_height; yindex++) { + if (coef->iMCU_row_num < last_iMCU_row || + yoffset+yindex < compptr->last_row_height) { + (*cinfo->fdct->forward_DCT) (cinfo, compptr, + input_buf[compptr->component_index], + coef->MCU_buffer[blkn], + ypos, xpos, (JDIMENSION) blockcnt); + if (blockcnt < compptr->MCU_width) { + /* Create some dummy blocks at the right edge of the image. */ + jzero_far((void FAR *) coef->MCU_buffer[blkn + blockcnt], + (compptr->MCU_width - blockcnt) * SIZEOF(JBLOCK)); + for (bi = blockcnt; bi < compptr->MCU_width; bi++) { + coef->MCU_buffer[blkn+bi][0][0] = coef->MCU_buffer[blkn+bi-1][0][0]; + } + } + } else { + /* Create a row of dummy blocks at the bottom of the image. */ + jzero_far((void FAR *) coef->MCU_buffer[blkn], + compptr->MCU_width * SIZEOF(JBLOCK)); + for (bi = 0; bi < compptr->MCU_width; bi++) { + coef->MCU_buffer[blkn+bi][0][0] = coef->MCU_buffer[blkn-1][0][0]; + } + } + blkn += compptr->MCU_width; + ypos += DCTSIZE; + } + } + /* Try to write the MCU. In event of a suspension failure, we will + * re-DCT the MCU on restart (a bit inefficient, could be fixed...) + */ + if (! (*cinfo->entropy->encode_mcu) (cinfo, coef->MCU_buffer)) { + /* Suspension forced; update state counters and exit */ + coef->MCU_vert_offset = yoffset; + coef->mcu_ctr = MCU_col_num; + return FALSE; + } + } + /* Completed an MCU row, but perhaps not an iMCU row */ + coef->mcu_ctr = 0; + } + /* Completed the iMCU row, advance counters for next one */ + coef->iMCU_row_num++; + start_iMCU_row(cinfo); + return TRUE; +} + + +#ifdef FULL_COEF_BUFFER_SUPPORTED + +/* + * Process some data in the first pass of a multi-pass case. + * We process the equivalent of one fully interleaved MCU row ("iMCU" row) + * per call, ie, v_samp_factor block rows for each component in the image. + * This amount of data is read from the source buffer, DCT'd and quantized, + * and saved into the virtual arrays. We also generate suitable dummy blocks + * as needed at the right and lower edges. (The dummy blocks are constructed + * in the virtual arrays, which have been padded appropriately.) This makes + * it possible for subsequent passes not to worry about real vs. dummy blocks. + * + * We must also emit the data to the entropy encoder. This is conveniently + * done by calling compress_output() after we've loaded the current strip + * of the virtual arrays. + * + * NB: input_buf contains a plane for each component in image. All + * components are DCT'd and loaded into the virtual arrays in this pass. + * However, it may be that only a subset of the components are emitted to + * the entropy encoder during this first pass; be careful about looking + * at the scan-dependent variables (MCU dimensions, etc). + */ + +METHODDEF(boolean) +compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf) +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1; + JDIMENSION blocks_across, MCUs_across, MCUindex; + int bi, ci, h_samp_factor, block_row, block_rows, ndummy; + JCOEF lastDC; + jpeg_component_info *compptr; + JBLOCKARRAY buffer; + JBLOCKROW thisblockrow, lastblockrow; + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + /* Align the virtual buffer for this component. */ + buffer = (*cinfo->mem->access_virt_barray) + ((j_common_ptr) cinfo, coef->whole_image[ci], + coef->iMCU_row_num * compptr->v_samp_factor, + (JDIMENSION) compptr->v_samp_factor, TRUE); + /* Count non-dummy DCT block rows in this iMCU row. */ + if (coef->iMCU_row_num < last_iMCU_row) + block_rows = compptr->v_samp_factor; + else { + /* NB: can't use last_row_height here, since may not be set! */ + block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor); + if (block_rows == 0) block_rows = compptr->v_samp_factor; + } + blocks_across = compptr->width_in_blocks; + h_samp_factor = compptr->h_samp_factor; + /* Count number of dummy blocks to be added at the right margin. */ + ndummy = (int) (blocks_across % h_samp_factor); + if (ndummy > 0) + ndummy = h_samp_factor - ndummy; + /* Perform DCT for all non-dummy blocks in this iMCU row. Each call + * on forward_DCT processes a complete horizontal row of DCT blocks. + */ + for (block_row = 0; block_row < block_rows; block_row++) { + thisblockrow = buffer[block_row]; + (*cinfo->fdct->forward_DCT) (cinfo, compptr, + input_buf[ci], thisblockrow, + (JDIMENSION) (block_row * DCTSIZE), + (JDIMENSION) 0, blocks_across); + if (ndummy > 0) { + /* Create dummy blocks at the right edge of the image. */ + thisblockrow += blocks_across; /* => first dummy block */ + jzero_far((void FAR *) thisblockrow, ndummy * SIZEOF(JBLOCK)); + lastDC = thisblockrow[-1][0]; + for (bi = 0; bi < ndummy; bi++) { + thisblockrow[bi][0] = lastDC; + } + } + } + /* If at end of image, create dummy block rows as needed. + * The tricky part here is that within each MCU, we want the DC values + * of the dummy blocks to match the last real block's DC value. + * This squeezes a few more bytes out of the resulting file... + */ + if (coef->iMCU_row_num == last_iMCU_row) { + blocks_across += ndummy; /* include lower right corner */ + MCUs_across = blocks_across / h_samp_factor; + for (block_row = block_rows; block_row < compptr->v_samp_factor; + block_row++) { + thisblockrow = buffer[block_row]; + lastblockrow = buffer[block_row-1]; + jzero_far((void FAR *) thisblockrow, + (size_t) (blocks_across * SIZEOF(JBLOCK))); + for (MCUindex = 0; MCUindex < MCUs_across; MCUindex++) { + lastDC = lastblockrow[h_samp_factor-1][0]; + for (bi = 0; bi < h_samp_factor; bi++) { + thisblockrow[bi][0] = lastDC; + } + thisblockrow += h_samp_factor; /* advance to next MCU in row */ + lastblockrow += h_samp_factor; + } + } + } + } + /* NB: compress_output will increment iMCU_row_num if successful. + * A suspension return will result in redoing all the work above next time. + */ + + /* Emit data to the entropy encoder, sharing code with subsequent passes */ + return compress_output(cinfo, input_buf); +} + + +/* + * Process some data in subsequent passes of a multi-pass case. + * We process the equivalent of one fully interleaved MCU row ("iMCU" row) + * per call, ie, v_samp_factor block rows for each component in the scan. + * The data is obtained from the virtual arrays and fed to the entropy coder. + * Returns TRUE if the iMCU row is completed, FALSE if suspended. + * + * NB: input_buf is ignored; it is likely to be a NULL pointer. + */ + +METHODDEF(boolean) +compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf) +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + JDIMENSION MCU_col_num; /* index of current MCU within row */ + int blkn, ci, xindex, yindex, yoffset; + JDIMENSION start_col; + JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN]; + JBLOCKROW buffer_ptr; + jpeg_component_info *compptr; + + /* Align the virtual buffers for the components used in this scan. + * NB: during first pass, this is safe only because the buffers will + * already be aligned properly, so jmemmgr.c won't need to do any I/O. + */ + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + buffer[ci] = (*cinfo->mem->access_virt_barray) + ((j_common_ptr) cinfo, coef->whole_image[compptr->component_index], + coef->iMCU_row_num * compptr->v_samp_factor, + (JDIMENSION) compptr->v_samp_factor, FALSE); + } + + /* Loop to process one whole iMCU row */ + for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row; + yoffset++) { + for (MCU_col_num = coef->mcu_ctr; MCU_col_num < cinfo->MCUs_per_row; + MCU_col_num++) { + /* Construct list of pointers to DCT blocks belonging to this MCU */ + blkn = 0; /* index of current DCT block within MCU */ + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + start_col = MCU_col_num * compptr->MCU_width; + for (yindex = 0; yindex < compptr->MCU_height; yindex++) { + buffer_ptr = buffer[ci][yindex+yoffset] + start_col; + for (xindex = 0; xindex < compptr->MCU_width; xindex++) { + coef->MCU_buffer[blkn++] = buffer_ptr++; + } + } + } + /* Try to write the MCU. */ + if (! (*cinfo->entropy->encode_mcu) (cinfo, coef->MCU_buffer)) { + /* Suspension forced; update state counters and exit */ + coef->MCU_vert_offset = yoffset; + coef->mcu_ctr = MCU_col_num; + return FALSE; + } + } + /* Completed an MCU row, but perhaps not an iMCU row */ + coef->mcu_ctr = 0; + } + /* Completed the iMCU row, advance counters for next one */ + coef->iMCU_row_num++; + start_iMCU_row(cinfo); + return TRUE; +} + +#endif /* FULL_COEF_BUFFER_SUPPORTED */ + + +/* + * Initialize coefficient buffer controller. + */ + +GLOBAL(void) +jinit_c_coef_controller (j_compress_ptr cinfo, boolean need_full_buffer) +{ + my_coef_ptr coef; + + coef = (my_coef_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_coef_controller)); + cinfo->coef = (struct jpeg_c_coef_controller *) coef; + coef->pub.start_pass = start_pass_coef; + + /* Create the coefficient buffer. */ + if (need_full_buffer) { +#ifdef FULL_COEF_BUFFER_SUPPORTED + /* Allocate a full-image virtual array for each component, */ + /* padded to a multiple of samp_factor DCT blocks in each direction. */ + int ci; + jpeg_component_info *compptr; + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + coef->whole_image[ci] = (*cinfo->mem->request_virt_barray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE, + (JDIMENSION) jround_up((long) compptr->width_in_blocks, + (long) compptr->h_samp_factor), + (JDIMENSION) jround_up((long) compptr->height_in_blocks, + (long) compptr->v_samp_factor), + (JDIMENSION) compptr->v_samp_factor); + } +#else + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); +#endif + } else { + /* We only need a single-MCU buffer. */ + JBLOCKROW buffer; + int i; + + buffer = (JBLOCKROW) + (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE, + C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK)); + for (i = 0; i < C_MAX_BLOCKS_IN_MCU; i++) { + coef->MCU_buffer[i] = buffer + i; + } + coef->whole_image[0] = NULL; /* flag for no virtual arrays */ + } +} diff --git a/mod/pub.mod/libjpeg.mod/jccolor.c b/mod/pub.mod/libjpeg.mod/jccolor.c new file mode 100644 index 0000000..0a8a4b5 --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jccolor.c @@ -0,0 +1,459 @@ +/* + * jccolor.c + * + * Copyright (C) 1991-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains input colorspace conversion routines. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* Private subobject */ + +typedef struct { + struct jpeg_color_converter pub; /* public fields */ + + /* Private state for RGB->YCC conversion */ + INT32 * rgb_ycc_tab; /* => table for RGB to YCbCr conversion */ +} my_color_converter; + +typedef my_color_converter * my_cconvert_ptr; + + +/**************** RGB -> YCbCr conversion: most common case **************/ + +/* + * YCbCr is defined per CCIR 601-1, except that Cb and Cr are + * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5. + * The conversion equations to be implemented are therefore + * Y = 0.29900 * R + 0.58700 * G + 0.11400 * B + * Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B + CENTERJSAMPLE + * Cr = 0.50000 * R - 0.41869 * G - 0.08131 * B + CENTERJSAMPLE + * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.) + * Note: older versions of the IJG code used a zero offset of MAXJSAMPLE/2, + * rather than CENTERJSAMPLE, for Cb and Cr. This gave equal positive and + * negative swings for Cb/Cr, but meant that grayscale values (Cb=Cr=0) + * were not represented exactly. Now we sacrifice exact representation of + * maximum red and maximum blue in order to get exact grayscales. + * + * To avoid floating-point arithmetic, we represent the fractional constants + * as integers scaled up by 2^16 (about 4 digits precision); we have to divide + * the products by 2^16, with appropriate rounding, to get the correct answer. + * + * For even more speed, we avoid doing any multiplications in the inner loop + * by precalculating the constants times R,G,B for all possible values. + * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table); + * for 12-bit samples it is still acceptable. It's not very reasonable for + * 16-bit samples, but if you want lossless storage you shouldn't be changing + * colorspace anyway. + * The CENTERJSAMPLE offsets and the rounding fudge-factor of 0.5 are included + * in the tables to save adding them separately in the inner loop. + */ + +#define SCALEBITS 16 /* speediest right-shift on some machines */ +#define CBCR_OFFSET ((INT32) CENTERJSAMPLE << SCALEBITS) +#define ONE_HALF ((INT32) 1 << (SCALEBITS-1)) +#define FIX(x) ((INT32) ((x) * (1L<<SCALEBITS) + 0.5)) + +/* We allocate one big table and divide it up into eight parts, instead of + * doing eight alloc_small requests. This lets us use a single table base + * address, which can be held in a register in the inner loops on many + * machines (more than can hold all eight addresses, anyway). + */ + +#define R_Y_OFF 0 /* offset to R => Y section */ +#define G_Y_OFF (1*(MAXJSAMPLE+1)) /* offset to G => Y section */ +#define B_Y_OFF (2*(MAXJSAMPLE+1)) /* etc. */ +#define R_CB_OFF (3*(MAXJSAMPLE+1)) +#define G_CB_OFF (4*(MAXJSAMPLE+1)) +#define B_CB_OFF (5*(MAXJSAMPLE+1)) +#define R_CR_OFF B_CB_OFF /* B=>Cb, R=>Cr are the same */ +#define G_CR_OFF (6*(MAXJSAMPLE+1)) +#define B_CR_OFF (7*(MAXJSAMPLE+1)) +#define TABLE_SIZE (8*(MAXJSAMPLE+1)) + + +/* + * Initialize for RGB->YCC colorspace conversion. + */ + +METHODDEF(void) +rgb_ycc_start (j_compress_ptr cinfo) +{ + my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; + INT32 * rgb_ycc_tab; + INT32 i; + + /* Allocate and fill in the conversion tables. */ + cconvert->rgb_ycc_tab = rgb_ycc_tab = (INT32 *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (TABLE_SIZE * SIZEOF(INT32))); + + for (i = 0; i <= MAXJSAMPLE; i++) { + rgb_ycc_tab[i+R_Y_OFF] = FIX(0.29900) * i; + rgb_ycc_tab[i+G_Y_OFF] = FIX(0.58700) * i; + rgb_ycc_tab[i+B_Y_OFF] = FIX(0.11400) * i + ONE_HALF; + rgb_ycc_tab[i+R_CB_OFF] = (-FIX(0.16874)) * i; + rgb_ycc_tab[i+G_CB_OFF] = (-FIX(0.33126)) * i; + /* We use a rounding fudge-factor of 0.5-epsilon for Cb and Cr. + * This ensures that the maximum output will round to MAXJSAMPLE + * not MAXJSAMPLE+1, and thus that we don't have to range-limit. + */ + rgb_ycc_tab[i+B_CB_OFF] = FIX(0.50000) * i + CBCR_OFFSET + ONE_HALF-1; +/* B=>Cb and R=>Cr tables are the same + rgb_ycc_tab[i+R_CR_OFF] = FIX(0.50000) * i + CBCR_OFFSET + ONE_HALF-1; +*/ + rgb_ycc_tab[i+G_CR_OFF] = (-FIX(0.41869)) * i; + rgb_ycc_tab[i+B_CR_OFF] = (-FIX(0.08131)) * i; + } +} + + +/* + * Convert some rows of samples to the JPEG colorspace. + * + * Note that we change from the application's interleaved-pixel format + * to our internal noninterleaved, one-plane-per-component format. + * The input buffer is therefore three times as wide as the output buffer. + * + * A starting row offset is provided only for the output buffer. The caller + * can easily adjust the passed input_buf value to accommodate any row + * offset required on that side. + */ + +METHODDEF(void) +rgb_ycc_convert (j_compress_ptr cinfo, + JSAMPARRAY input_buf, JSAMPIMAGE output_buf, + JDIMENSION output_row, int num_rows) +{ + my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; + register int r, g, b; + register INT32 * ctab = cconvert->rgb_ycc_tab; + register JSAMPROW inptr; + register JSAMPROW outptr0, outptr1, outptr2; + register JDIMENSION col; + JDIMENSION num_cols = cinfo->image_width; + + while (--num_rows >= 0) { + inptr = *input_buf++; + outptr0 = output_buf[0][output_row]; + outptr1 = output_buf[1][output_row]; + outptr2 = output_buf[2][output_row]; + output_row++; + for (col = 0; col < num_cols; col++) { + r = GETJSAMPLE(inptr[RGB_RED]); + g = GETJSAMPLE(inptr[RGB_GREEN]); + b = GETJSAMPLE(inptr[RGB_BLUE]); + inptr += RGB_PIXELSIZE; + /* If the inputs are 0..MAXJSAMPLE, the outputs of these equations + * must be too; we do not need an explicit range-limiting operation. + * Hence the value being shifted is never negative, and we don't + * need the general RIGHT_SHIFT macro. + */ + /* Y */ + outptr0[col] = (JSAMPLE) + ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF]) + >> SCALEBITS); + /* Cb */ + outptr1[col] = (JSAMPLE) + ((ctab[r+R_CB_OFF] + ctab[g+G_CB_OFF] + ctab[b+B_CB_OFF]) + >> SCALEBITS); + /* Cr */ + outptr2[col] = (JSAMPLE) + ((ctab[r+R_CR_OFF] + ctab[g+G_CR_OFF] + ctab[b+B_CR_OFF]) + >> SCALEBITS); + } + } +} + + +/**************** Cases other than RGB -> YCbCr **************/ + + +/* + * Convert some rows of samples to the JPEG colorspace. + * This version handles RGB->grayscale conversion, which is the same + * as the RGB->Y portion of RGB->YCbCr. + * We assume rgb_ycc_start has been called (we only use the Y tables). + */ + +METHODDEF(void) +rgb_gray_convert (j_compress_ptr cinfo, + JSAMPARRAY input_buf, JSAMPIMAGE output_buf, + JDIMENSION output_row, int num_rows) +{ + my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; + register int r, g, b; + register INT32 * ctab = cconvert->rgb_ycc_tab; + register JSAMPROW inptr; + register JSAMPROW outptr; + register JDIMENSION col; + JDIMENSION num_cols = cinfo->image_width; + + while (--num_rows >= 0) { + inptr = *input_buf++; + outptr = output_buf[0][output_row]; + output_row++; + for (col = 0; col < num_cols; col++) { + r = GETJSAMPLE(inptr[RGB_RED]); + g = GETJSAMPLE(inptr[RGB_GREEN]); + b = GETJSAMPLE(inptr[RGB_BLUE]); + inptr += RGB_PIXELSIZE; + /* Y */ + outptr[col] = (JSAMPLE) + ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF]) + >> SCALEBITS); + } + } +} + + +/* + * Convert some rows of samples to the JPEG colorspace. + * This version handles Adobe-style CMYK->YCCK conversion, + * where we convert R=1-C, G=1-M, and B=1-Y to YCbCr using the same + * conversion as above, while passing K (black) unchanged. + * We assume rgb_ycc_start has been called. + */ + +METHODDEF(void) +cmyk_ycck_convert (j_compress_ptr cinfo, + JSAMPARRAY input_buf, JSAMPIMAGE output_buf, + JDIMENSION output_row, int num_rows) +{ + my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; + register int r, g, b; + register INT32 * ctab = cconvert->rgb_ycc_tab; + register JSAMPROW inptr; + register JSAMPROW outptr0, outptr1, outptr2, outptr3; + register JDIMENSION col; + JDIMENSION num_cols = cinfo->image_width; + + while (--num_rows >= 0) { + inptr = *input_buf++; + outptr0 = output_buf[0][output_row]; + outptr1 = output_buf[1][output_row]; + outptr2 = output_buf[2][output_row]; + outptr3 = output_buf[3][output_row]; + output_row++; + for (col = 0; col < num_cols; col++) { + r = MAXJSAMPLE - GETJSAMPLE(inptr[0]); + g = MAXJSAMPLE - GETJSAMPLE(inptr[1]); + b = MAXJSAMPLE - GETJSAMPLE(inptr[2]); + /* K passes through as-is */ + outptr3[col] = inptr[3]; /* don't need GETJSAMPLE here */ + inptr += 4; + /* If the inputs are 0..MAXJSAMPLE, the outputs of these equations + * must be too; we do not need an explicit range-limiting operation. + * Hence the value being shifted is never negative, and we don't + * need the general RIGHT_SHIFT macro. + */ + /* Y */ + outptr0[col] = (JSAMPLE) + ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF]) + >> SCALEBITS); + /* Cb */ + outptr1[col] = (JSAMPLE) + ((ctab[r+R_CB_OFF] + ctab[g+G_CB_OFF] + ctab[b+B_CB_OFF]) + >> SCALEBITS); + /* Cr */ + outptr2[col] = (JSAMPLE) + ((ctab[r+R_CR_OFF] + ctab[g+G_CR_OFF] + ctab[b+B_CR_OFF]) + >> SCALEBITS); + } + } +} + + +/* + * Convert some rows of samples to the JPEG colorspace. + * This version handles grayscale output with no conversion. + * The source can be either plain grayscale or YCbCr (since Y == gray). + */ + +METHODDEF(void) +grayscale_convert (j_compress_ptr cinfo, + JSAMPARRAY input_buf, JSAMPIMAGE output_buf, + JDIMENSION output_row, int num_rows) +{ + register JSAMPROW inptr; + register JSAMPROW outptr; + register JDIMENSION col; + JDIMENSION num_cols = cinfo->image_width; + int instride = cinfo->input_components; + + while (--num_rows >= 0) { + inptr = *input_buf++; + outptr = output_buf[0][output_row]; + output_row++; + for (col = 0; col < num_cols; col++) { + outptr[col] = inptr[0]; /* don't need GETJSAMPLE() here */ + inptr += instride; + } + } +} + + +/* + * Convert some rows of samples to the JPEG colorspace. + * This version handles multi-component colorspaces without conversion. + * We assume input_components == num_components. + */ + +METHODDEF(void) +null_convert (j_compress_ptr cinfo, + JSAMPARRAY input_buf, JSAMPIMAGE output_buf, + JDIMENSION output_row, int num_rows) +{ + register JSAMPROW inptr; + register JSAMPROW outptr; + register JDIMENSION col; + register int ci; + int nc = cinfo->num_components; + JDIMENSION num_cols = cinfo->image_width; + + while (--num_rows >= 0) { + /* It seems fastest to make a separate pass for each component. */ + for (ci = 0; ci < nc; ci++) { + inptr = *input_buf; + outptr = output_buf[ci][output_row]; + for (col = 0; col < num_cols; col++) { + outptr[col] = inptr[ci]; /* don't need GETJSAMPLE() here */ + inptr += nc; + } + } + input_buf++; + output_row++; + } +} + + +/* + * Empty method for start_pass. + */ + +METHODDEF(void) +null_method (j_compress_ptr cinfo) +{ + /* no work needed */ +} + + +/* + * Module initialization routine for input colorspace conversion. + */ + +GLOBAL(void) +jinit_color_converter (j_compress_ptr cinfo) +{ + my_cconvert_ptr cconvert; + + cconvert = (my_cconvert_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_color_converter)); + cinfo->cconvert = (struct jpeg_color_converter *) cconvert; + /* set start_pass to null method until we find out differently */ + cconvert->pub.start_pass = null_method; + + /* Make sure input_components agrees with in_color_space */ + switch (cinfo->in_color_space) { + case JCS_GRAYSCALE: + if (cinfo->input_components != 1) + ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE); + break; + + case JCS_RGB: +#if RGB_PIXELSIZE != 3 + if (cinfo->input_components != RGB_PIXELSIZE) + ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE); + break; +#endif /* else share code with YCbCr */ + + case JCS_YCbCr: + if (cinfo->input_components != 3) + ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE); + break; + + case JCS_CMYK: + case JCS_YCCK: + if (cinfo->input_components != 4) + ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE); + break; + + default: /* JCS_UNKNOWN can be anything */ + if (cinfo->input_components < 1) + ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE); + break; + } + + /* Check num_components, set conversion method based on requested space */ + switch (cinfo->jpeg_color_space) { + case JCS_GRAYSCALE: + if (cinfo->num_components != 1) + ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); + if (cinfo->in_color_space == JCS_GRAYSCALE) + cconvert->pub.color_convert = grayscale_convert; + else if (cinfo->in_color_space == JCS_RGB) { + cconvert->pub.start_pass = rgb_ycc_start; + cconvert->pub.color_convert = rgb_gray_convert; + } else if (cinfo->in_color_space == JCS_YCbCr) + cconvert->pub.color_convert = grayscale_convert; + else + ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); + break; + + case JCS_RGB: + if (cinfo->num_components != 3) + ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); + if (cinfo->in_color_space == JCS_RGB && RGB_PIXELSIZE == 3) + cconvert->pub.color_convert = null_convert; + else + ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); + break; + + case JCS_YCbCr: + if (cinfo->num_components != 3) + ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); + if (cinfo->in_color_space == JCS_RGB) { + cconvert->pub.start_pass = rgb_ycc_start; + cconvert->pub.color_convert = rgb_ycc_convert; + } else if (cinfo->in_color_space == JCS_YCbCr) + cconvert->pub.color_convert = null_convert; + else + ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); + break; + + case JCS_CMYK: + if (cinfo->num_components != 4) + ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); + if (cinfo->in_color_space == JCS_CMYK) + cconvert->pub.color_convert = null_convert; + else + ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); + break; + + case JCS_YCCK: + if (cinfo->num_components != 4) + ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); + if (cinfo->in_color_space == JCS_CMYK) { + cconvert->pub.start_pass = rgb_ycc_start; + cconvert->pub.color_convert = cmyk_ycck_convert; + } else if (cinfo->in_color_space == JCS_YCCK) + cconvert->pub.color_convert = null_convert; + else + ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); + break; + + default: /* allow null conversion of JCS_UNKNOWN */ + if (cinfo->jpeg_color_space != cinfo->in_color_space || + cinfo->num_components != cinfo->input_components) + ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); + cconvert->pub.color_convert = null_convert; + break; + } +} diff --git a/mod/pub.mod/libjpeg.mod/jcdctmgr.c b/mod/pub.mod/libjpeg.mod/jcdctmgr.c new file mode 100644 index 0000000..61fa79b --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jcdctmgr.c @@ -0,0 +1,387 @@ +/* + * jcdctmgr.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains the forward-DCT management logic. + * This code selects a particular DCT implementation to be used, + * and it performs related housekeeping chores including coefficient + * quantization. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdct.h" /* Private declarations for DCT subsystem */ + + +/* Private subobject for this module */ + +typedef struct { + struct jpeg_forward_dct pub; /* public fields */ + + /* Pointer to the DCT routine actually in use */ + forward_DCT_method_ptr do_dct; + + /* The actual post-DCT divisors --- not identical to the quant table + * entries, because of scaling (especially for an unnormalized DCT). + * Each table is given in normal array order. + */ + DCTELEM * divisors[NUM_QUANT_TBLS]; + +#ifdef DCT_FLOAT_SUPPORTED + /* Same as above for the floating-point case. */ + float_DCT_method_ptr do_float_dct; + FAST_FLOAT * float_divisors[NUM_QUANT_TBLS]; +#endif +} my_fdct_controller; + +typedef my_fdct_controller * my_fdct_ptr; + + +/* + * Initialize for a processing pass. + * Verify that all referenced Q-tables are present, and set up + * the divisor table for each one. + * In the current implementation, DCT of all components is done during + * the first pass, even if only some components will be output in the + * first scan. Hence all components should be examined here. + */ + +METHODDEF(void) +start_pass_fdctmgr (j_compress_ptr cinfo) +{ + my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct; + int ci, qtblno, i; + jpeg_component_info *compptr; + JQUANT_TBL * qtbl; + DCTELEM * dtbl; + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + qtblno = compptr->quant_tbl_no; + /* Make sure specified quantization table is present */ + if (qtblno < 0 || qtblno >= NUM_QUANT_TBLS || + cinfo->quant_tbl_ptrs[qtblno] == NULL) + ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, qtblno); + qtbl = cinfo->quant_tbl_ptrs[qtblno]; + /* Compute divisors for this quant table */ + /* We may do this more than once for same table, but it's not a big deal */ + switch (cinfo->dct_method) { +#ifdef DCT_ISLOW_SUPPORTED + case JDCT_ISLOW: + /* For LL&M IDCT method, divisors are equal to raw quantization + * coefficients multiplied by 8 (to counteract scaling). + */ + if (fdct->divisors[qtblno] == NULL) { + fdct->divisors[qtblno] = (DCTELEM *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + DCTSIZE2 * SIZEOF(DCTELEM)); + } + dtbl = fdct->divisors[qtblno]; + for (i = 0; i < DCTSIZE2; i++) { + dtbl[i] = ((DCTELEM) qtbl->quantval[i]) << 3; + } + break; +#endif +#ifdef DCT_IFAST_SUPPORTED + case JDCT_IFAST: + { + /* For AA&N IDCT method, divisors are equal to quantization + * coefficients scaled by scalefactor[row]*scalefactor[col], where + * scalefactor[0] = 1 + * scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7 + * We apply a further scale factor of 8. + */ +#define CONST_BITS 14 + static const INT16 aanscales[DCTSIZE2] = { + /* precomputed values scaled up by 14 bits */ + 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520, + 22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270, + 21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906, + 19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315, + 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520, + 12873, 17855, 16819, 15137, 12873, 10114, 6967, 3552, + 8867, 12299, 11585, 10426, 8867, 6967, 4799, 2446, + 4520, 6270, 5906, 5315, 4520, 3552, 2446, 1247 + }; + SHIFT_TEMPS + + if (fdct->divisors[qtblno] == NULL) { + fdct->divisors[qtblno] = (DCTELEM *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + DCTSIZE2 * SIZEOF(DCTELEM)); + } + dtbl = fdct->divisors[qtblno]; + for (i = 0; i < DCTSIZE2; i++) { + dtbl[i] = (DCTELEM) + DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[i], + (INT32) aanscales[i]), + CONST_BITS-3); + } + } + break; +#endif +#ifdef DCT_FLOAT_SUPPORTED + case JDCT_FLOAT: + { + /* For float AA&N IDCT method, divisors are equal to quantization + * coefficients scaled by scalefactor[row]*scalefactor[col], where + * scalefactor[0] = 1 + * scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7 + * We apply a further scale factor of 8. + * What's actually stored is 1/divisor so that the inner loop can + * use a multiplication rather than a division. + */ + FAST_FLOAT * fdtbl; + int row, col; + static const double aanscalefactor[DCTSIZE] = { + 1.0, 1.387039845, 1.306562965, 1.175875602, + 1.0, 0.785694958, 0.541196100, 0.275899379 + }; + + if (fdct->float_divisors[qtblno] == NULL) { + fdct->float_divisors[qtblno] = (FAST_FLOAT *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + DCTSIZE2 * SIZEOF(FAST_FLOAT)); + } + fdtbl = fdct->float_divisors[qtblno]; + i = 0; + for (row = 0; row < DCTSIZE; row++) { + for (col = 0; col < DCTSIZE; col++) { + fdtbl[i] = (FAST_FLOAT) + (1.0 / (((double) qtbl->quantval[i] * + aanscalefactor[row] * aanscalefactor[col] * 8.0))); + i++; + } + } + } + break; +#endif + default: + ERREXIT(cinfo, JERR_NOT_COMPILED); + break; + } + } +} + + +/* + * Perform forward DCT on one or more blocks of a component. + * + * The input samples are taken from the sample_data[] array starting at + * position start_row/start_col, and moving to the right for any additional + * blocks. The quantized coefficients are returned in coef_blocks[]. + */ + +METHODDEF(void) +forward_DCT (j_compress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY sample_data, JBLOCKROW coef_blocks, + JDIMENSION start_row, JDIMENSION start_col, + JDIMENSION num_blocks) +/* This version is used for integer DCT implementations. */ +{ + /* This routine is heavily used, so it's worth coding it tightly. */ + my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct; + forward_DCT_method_ptr do_dct = fdct->do_dct; + DCTELEM * divisors = fdct->divisors[compptr->quant_tbl_no]; + DCTELEM workspace[DCTSIZE2]; /* work area for FDCT subroutine */ + JDIMENSION bi; + + sample_data += start_row; /* fold in the vertical offset once */ + + for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) { + /* Load data into workspace, applying unsigned->signed conversion */ + { register DCTELEM *workspaceptr; + register JSAMPROW elemptr; + register int elemr; + + workspaceptr = workspace; + for (elemr = 0; elemr < DCTSIZE; elemr++) { + elemptr = sample_data[elemr] + start_col; +#if DCTSIZE == 8 /* unroll the inner loop */ + *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; + *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; + *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; + *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; + *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; + *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; + *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; + *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; +#else + { register int elemc; + for (elemc = DCTSIZE; elemc > 0; elemc--) { + *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; + } + } +#endif + } + } + + /* Perform the DCT */ + (*do_dct) (workspace); + + /* Quantize/descale the coefficients, and store into coef_blocks[] */ + { register DCTELEM temp, qval; + register int i; + register JCOEFPTR output_ptr = coef_blocks[bi]; + + for (i = 0; i < DCTSIZE2; i++) { + qval = divisors[i]; + temp = workspace[i]; + /* Divide the coefficient value by qval, ensuring proper rounding. + * Since C does not specify the direction of rounding for negative + * quotients, we have to force the dividend positive for portability. + * + * In most files, at least half of the output values will be zero + * (at default quantization settings, more like three-quarters...) + * so we should ensure that this case is fast. On many machines, + * a comparison is enough cheaper than a divide to make a special test + * a win. Since both inputs will be nonnegative, we need only test + * for a < b to discover whether a/b is 0. + * If your machine's division is fast enough, define FAST_DIVIDE. + */ +#ifdef FAST_DIVIDE +#define DIVIDE_BY(a,b) a /= b +#else +#define DIVIDE_BY(a,b) if (a >= b) a /= b; else a = 0 +#endif + if (temp < 0) { + temp = -temp; + temp += qval>>1; /* for rounding */ + DIVIDE_BY(temp, qval); + temp = -temp; + } else { + temp += qval>>1; /* for rounding */ + DIVIDE_BY(temp, qval); + } + output_ptr[i] = (JCOEF) temp; + } + } + } +} + + +#ifdef DCT_FLOAT_SUPPORTED + +METHODDEF(void) +forward_DCT_float (j_compress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY sample_data, JBLOCKROW coef_blocks, + JDIMENSION start_row, JDIMENSION start_col, + JDIMENSION num_blocks) +/* This version is used for floating-point DCT implementations. */ +{ + /* This routine is heavily used, so it's worth coding it tightly. */ + my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct; + float_DCT_method_ptr do_dct = fdct->do_float_dct; + FAST_FLOAT * divisors = fdct->float_divisors[compptr->quant_tbl_no]; + FAST_FLOAT workspace[DCTSIZE2]; /* work area for FDCT subroutine */ + JDIMENSION bi; + + sample_data += start_row; /* fold in the vertical offset once */ + + for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) { + /* Load data into workspace, applying unsigned->signed conversion */ + { register FAST_FLOAT *workspaceptr; + register JSAMPROW elemptr; + register int elemr; + + workspaceptr = workspace; + for (elemr = 0; elemr < DCTSIZE; elemr++) { + elemptr = sample_data[elemr] + start_col; +#if DCTSIZE == 8 /* unroll the inner loop */ + *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); + *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); + *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); + *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); + *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); + *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); + *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); + *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); +#else + { register int elemc; + for (elemc = DCTSIZE; elemc > 0; elemc--) { + *workspaceptr++ = (FAST_FLOAT) + (GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); + } + } +#endif + } + } + + /* Perform the DCT */ + (*do_dct) (workspace); + + /* Quantize/descale the coefficients, and store into coef_blocks[] */ + { register FAST_FLOAT temp; + register int i; + register JCOEFPTR output_ptr = coef_blocks[bi]; + + for (i = 0; i < DCTSIZE2; i++) { + /* Apply the quantization and scaling factor */ + temp = workspace[i] * divisors[i]; + /* Round to nearest integer. + * Since C does not specify the direction of rounding for negative + * quotients, we have to force the dividend positive for portability. + * The maximum coefficient size is +-16K (for 12-bit data), so this + * code should work for either 16-bit or 32-bit ints. + */ + output_ptr[i] = (JCOEF) ((int) (temp + (FAST_FLOAT) 16384.5) - 16384); + } + } + } +} + +#endif /* DCT_FLOAT_SUPPORTED */ + + +/* + * Initialize FDCT manager. + */ + +GLOBAL(void) +jinit_forward_dct (j_compress_ptr cinfo) +{ + my_fdct_ptr fdct; + int i; + + fdct = (my_fdct_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_fdct_controller)); + cinfo->fdct = (struct jpeg_forward_dct *) fdct; + fdct->pub.start_pass = start_pass_fdctmgr; + + switch (cinfo->dct_method) { +#ifdef DCT_ISLOW_SUPPORTED + case JDCT_ISLOW: + fdct->pub.forward_DCT = forward_DCT; + fdct->do_dct = jpeg_fdct_islow; + break; +#endif +#ifdef DCT_IFAST_SUPPORTED + case JDCT_IFAST: + fdct->pub.forward_DCT = forward_DCT; + fdct->do_dct = jpeg_fdct_ifast; + break; +#endif +#ifdef DCT_FLOAT_SUPPORTED + case JDCT_FLOAT: + fdct->pub.forward_DCT = forward_DCT_float; + fdct->do_float_dct = jpeg_fdct_float; + break; +#endif + default: + ERREXIT(cinfo, JERR_NOT_COMPILED); + break; + } + + /* Mark divisor tables unallocated */ + for (i = 0; i < NUM_QUANT_TBLS; i++) { + fdct->divisors[i] = NULL; +#ifdef DCT_FLOAT_SUPPORTED + fdct->float_divisors[i] = NULL; +#endif + } +} diff --git a/mod/pub.mod/libjpeg.mod/jchuff.c b/mod/pub.mod/libjpeg.mod/jchuff.c new file mode 100644 index 0000000..f235250 --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jchuff.c @@ -0,0 +1,909 @@ +/* + * jchuff.c + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains Huffman entropy encoding routines. + * + * Much of the complexity here has to do with supporting output suspension. + * If the data destination module demands suspension, we want to be able to + * back up to the start of the current MCU. To do this, we copy state + * variables into local working storage, and update them back to the + * permanent JPEG objects only upon successful completion of an MCU. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jchuff.h" /* Declarations shared with jcphuff.c */ + + +/* Expanded entropy encoder object for Huffman encoding. + * + * The savable_state subrecord contains fields that change within an MCU, + * but must not be updated permanently until we complete the MCU. + */ + +typedef struct { + INT32 put_buffer; /* current bit-accumulation buffer */ + int put_bits; /* # of bits now in it */ + int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */ +} savable_state; + +/* This macro is to work around compilers with missing or broken + * structure assignment. You'll need to fix this code if you have + * such a compiler and you change MAX_COMPS_IN_SCAN. + */ + +#ifndef NO_STRUCT_ASSIGN +#define ASSIGN_STATE(dest,src) ((dest) = (src)) +#else +#if MAX_COMPS_IN_SCAN == 4 +#define ASSIGN_STATE(dest,src) \ + ((dest).put_buffer = (src).put_buffer, \ + (dest).put_bits = (src).put_bits, \ + (dest).last_dc_val[0] = (src).last_dc_val[0], \ + (dest).last_dc_val[1] = (src).last_dc_val[1], \ + (dest).last_dc_val[2] = (src).last_dc_val[2], \ + (dest).last_dc_val[3] = (src).last_dc_val[3]) +#endif +#endif + + +typedef struct { + struct jpeg_entropy_encoder pub; /* public fields */ + + savable_state saved; /* Bit buffer & DC state at start of MCU */ + + /* These fields are NOT loaded into local working state. */ + unsigned int restarts_to_go; /* MCUs left in this restart interval */ + int next_restart_num; /* next restart number to write (0-7) */ + + /* Pointers to derived tables (these workspaces have image lifespan) */ + c_derived_tbl * dc_derived_tbls[NUM_HUFF_TBLS]; + c_derived_tbl * ac_derived_tbls[NUM_HUFF_TBLS]; + +#ifdef ENTROPY_OPT_SUPPORTED /* Statistics tables for optimization */ + long * dc_count_ptrs[NUM_HUFF_TBLS]; + long * ac_count_ptrs[NUM_HUFF_TBLS]; +#endif +} huff_entropy_encoder; + +typedef huff_entropy_encoder * huff_entropy_ptr; + +/* Working state while writing an MCU. + * This struct contains all the fields that are needed by subroutines. + */ + +typedef struct { + JOCTET * next_output_byte; /* => next byte to write in buffer */ + size_t free_in_buffer; /* # of byte spaces remaining in buffer */ + savable_state cur; /* Current bit buffer & DC state */ + j_compress_ptr cinfo; /* dump_buffer needs access to this */ +} working_state; + + +/* Forward declarations */ +METHODDEF(boolean) encode_mcu_huff JPP((j_compress_ptr cinfo, + JBLOCKROW *MCU_data)); +METHODDEF(void) finish_pass_huff JPP((j_compress_ptr cinfo)); +#ifdef ENTROPY_OPT_SUPPORTED +METHODDEF(boolean) encode_mcu_gather JPP((j_compress_ptr cinfo, + JBLOCKROW *MCU_data)); +METHODDEF(void) finish_pass_gather JPP((j_compress_ptr cinfo)); +#endif + + +/* + * Initialize for a Huffman-compressed scan. + * If gather_statistics is TRUE, we do not output anything during the scan, + * just count the Huffman symbols used and generate Huffman code tables. + */ + +METHODDEF(void) +start_pass_huff (j_compress_ptr cinfo, boolean gather_statistics) +{ + huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; + int ci, dctbl, actbl; + jpeg_component_info * compptr; + + if (gather_statistics) { +#ifdef ENTROPY_OPT_SUPPORTED + entropy->pub.encode_mcu = encode_mcu_gather; + entropy->pub.finish_pass = finish_pass_gather; +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } else { + entropy->pub.encode_mcu = encode_mcu_huff; + entropy->pub.finish_pass = finish_pass_huff; + } + + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + dctbl = compptr->dc_tbl_no; + actbl = compptr->ac_tbl_no; + if (gather_statistics) { +#ifdef ENTROPY_OPT_SUPPORTED + /* Check for invalid table indexes */ + /* (make_c_derived_tbl does this in the other path) */ + if (dctbl < 0 || dctbl >= NUM_HUFF_TBLS) + ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, dctbl); + if (actbl < 0 || actbl >= NUM_HUFF_TBLS) + ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, actbl); + /* Allocate and zero the statistics tables */ + /* Note that jpeg_gen_optimal_table expects 257 entries in each table! */ + if (entropy->dc_count_ptrs[dctbl] == NULL) + entropy->dc_count_ptrs[dctbl] = (long *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + 257 * SIZEOF(long)); + MEMZERO(entropy->dc_count_ptrs[dctbl], 257 * SIZEOF(long)); + if (entropy->ac_count_ptrs[actbl] == NULL) + entropy->ac_count_ptrs[actbl] = (long *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + 257 * SIZEOF(long)); + MEMZERO(entropy->ac_count_ptrs[actbl], 257 * SIZEOF(long)); +#endif + } else { + /* Compute derived values for Huffman tables */ + /* We may do this more than once for a table, but it's not expensive */ + jpeg_make_c_derived_tbl(cinfo, TRUE, dctbl, + & entropy->dc_derived_tbls[dctbl]); + jpeg_make_c_derived_tbl(cinfo, FALSE, actbl, + & entropy->ac_derived_tbls[actbl]); + } + /* Initialize DC predictions to 0 */ + entropy->saved.last_dc_val[ci] = 0; + } + + /* Initialize bit buffer to empty */ + entropy->saved.put_buffer = 0; + entropy->saved.put_bits = 0; + + /* Initialize restart stuff */ + entropy->restarts_to_go = cinfo->restart_interval; + entropy->next_restart_num = 0; +} + + +/* + * Compute the derived values for a Huffman table. + * This routine also performs some validation checks on the table. + * + * Note this is also used by jcphuff.c. + */ + +GLOBAL(void) +jpeg_make_c_derived_tbl (j_compress_ptr cinfo, boolean isDC, int tblno, + c_derived_tbl ** pdtbl) +{ + JHUFF_TBL *htbl; + c_derived_tbl *dtbl; + int p, i, l, lastp, si, maxsymbol; + char huffsize[257]; + unsigned int huffcode[257]; + unsigned int code; + + /* Note that huffsize[] and huffcode[] are filled in code-length order, + * paralleling the order of the symbols themselves in htbl->huffval[]. + */ + + /* Find the input Huffman table */ + if (tblno < 0 || tblno >= NUM_HUFF_TBLS) + ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno); + htbl = + isDC ? cinfo->dc_huff_tbl_ptrs[tblno] : cinfo->ac_huff_tbl_ptrs[tblno]; + if (htbl == NULL) + ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno); + + /* Allocate a workspace if we haven't already done so. */ + if (*pdtbl == NULL) + *pdtbl = (c_derived_tbl *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(c_derived_tbl)); + dtbl = *pdtbl; + + /* Figure C.1: make table of Huffman code length for each symbol */ + + p = 0; + for (l = 1; l <= 16; l++) { + i = (int) htbl->bits[l]; + if (i < 0 || p + i > 256) /* protect against table overrun */ + ERREXIT(cinfo, JERR_BAD_HUFF_TABLE); + while (i--) + huffsize[p++] = (char) l; + } + huffsize[p] = 0; + lastp = p; + + /* Figure C.2: generate the codes themselves */ + /* We also validate that the counts represent a legal Huffman code tree. */ + + code = 0; + si = huffsize[0]; + p = 0; + while (huffsize[p]) { + while (((int) huffsize[p]) == si) { + huffcode[p++] = code; + code++; + } + /* code is now 1 more than the last code used for codelength si; but + * it must still fit in si bits, since no code is allowed to be all ones. + */ + if (((INT32) code) >= (((INT32) 1) << si)) + ERREXIT(cinfo, JERR_BAD_HUFF_TABLE); + code <<= 1; + si++; + } + + /* Figure C.3: generate encoding tables */ + /* These are code and size indexed by symbol value */ + + /* Set all codeless symbols to have code length 0; + * this lets us detect duplicate VAL entries here, and later + * allows emit_bits to detect any attempt to emit such symbols. + */ + MEMZERO(dtbl->ehufsi, SIZEOF(dtbl->ehufsi)); + + /* This is also a convenient place to check for out-of-range + * and duplicated VAL entries. We allow 0..255 for AC symbols + * but only 0..15 for DC. (We could constrain them further + * based on data depth and mode, but this seems enough.) + */ + maxsymbol = isDC ? 15 : 255; + + for (p = 0; p < lastp; p++) { + i = htbl->huffval[p]; + if (i < 0 || i > maxsymbol || dtbl->ehufsi[i]) + ERREXIT(cinfo, JERR_BAD_HUFF_TABLE); + dtbl->ehufco[i] = huffcode[p]; + dtbl->ehufsi[i] = huffsize[p]; + } +} + + +/* Outputting bytes to the file */ + +/* Emit a byte, taking 'action' if must suspend. */ +#define emit_byte(state,val,action) \ + { *(state)->next_output_byte++ = (JOCTET) (val); \ + if (--(state)->free_in_buffer == 0) \ + if (! dump_buffer(state)) \ + { action; } } + + +LOCAL(boolean) +dump_buffer (working_state * state) +/* Empty the output buffer; return TRUE if successful, FALSE if must suspend */ +{ + struct jpeg_destination_mgr * dest = state->cinfo->dest; + + if (! (*dest->empty_output_buffer) (state->cinfo)) + return FALSE; + /* After a successful buffer dump, must reset buffer pointers */ + state->next_output_byte = dest->next_output_byte; + state->free_in_buffer = dest->free_in_buffer; + return TRUE; +} + + +/* Outputting bits to the file */ + +/* Only the right 24 bits of put_buffer are used; the valid bits are + * left-justified in this part. At most 16 bits can be passed to emit_bits + * in one call, and we never retain more than 7 bits in put_buffer + * between calls, so 24 bits are sufficient. + */ + +INLINE +LOCAL(boolean) +emit_bits (working_state * state, unsigned int code, int size) +/* Emit some bits; return TRUE if successful, FALSE if must suspend */ +{ + /* This routine is heavily used, so it's worth coding tightly. */ + register INT32 put_buffer = (INT32) code; + register int put_bits = state->cur.put_bits; + + /* if size is 0, caller used an invalid Huffman table entry */ + if (size == 0) + ERREXIT(state->cinfo, JERR_HUFF_MISSING_CODE); + + put_buffer &= (((INT32) 1)<<size) - 1; /* mask off any extra bits in code */ + + put_bits += size; /* new number of bits in buffer */ + + put_buffer <<= 24 - put_bits; /* align incoming bits */ + + put_buffer |= state->cur.put_buffer; /* and merge with old buffer contents */ + + while (put_bits >= 8) { + int c = (int) ((put_buffer >> 16) & 0xFF); + + emit_byte(state, c, return FALSE); + if (c == 0xFF) { /* need to stuff a zero byte? */ + emit_byte(state, 0, return FALSE); + } + put_buffer <<= 8; + put_bits -= 8; + } + + state->cur.put_buffer = put_buffer; /* update state variables */ + state->cur.put_bits = put_bits; + + return TRUE; +} + + +LOCAL(boolean) +flush_bits (working_state * state) +{ + if (! emit_bits(state, 0x7F, 7)) /* fill any partial byte with ones */ + return FALSE; + state->cur.put_buffer = 0; /* and reset bit-buffer to empty */ + state->cur.put_bits = 0; + return TRUE; +} + + +/* Encode a single block's worth of coefficients */ + +LOCAL(boolean) +encode_one_block (working_state * state, JCOEFPTR block, int last_dc_val, + c_derived_tbl *dctbl, c_derived_tbl *actbl) +{ + register int temp, temp2; + register int nbits; + register int k, r, i; + + /* Encode the DC coefficient difference per section F.1.2.1 */ + + temp = temp2 = block[0] - last_dc_val; + + if (temp < 0) { + temp = -temp; /* temp is abs value of input */ + /* For a negative input, want temp2 = bitwise complement of abs(input) */ + /* This code assumes we are on a two's complement machine */ + temp2--; + } + + /* Find the number of bits needed for the magnitude of the coefficient */ + nbits = 0; + while (temp) { + nbits++; + temp >>= 1; + } + /* Check for out-of-range coefficient values. + * Since we're encoding a difference, the range limit is twice as much. + */ + if (nbits > MAX_COEF_BITS+1) + ERREXIT(state->cinfo, JERR_BAD_DCT_COEF); + + /* Emit the Huffman-coded symbol for the number of bits */ + if (! emit_bits(state, dctbl->ehufco[nbits], dctbl->ehufsi[nbits])) + return FALSE; + + /* Emit that number of bits of the value, if positive, */ + /* or the complement of its magnitude, if negative. */ + if (nbits) /* emit_bits rejects calls with size 0 */ + if (! emit_bits(state, (unsigned int) temp2, nbits)) + return FALSE; + + /* Encode the AC coefficients per section F.1.2.2 */ + + r = 0; /* r = run length of zeros */ + + for (k = 1; k < DCTSIZE2; k++) { + if ((temp = block[jpeg_natural_order[k]]) == 0) { + r++; + } else { + /* if run length > 15, must emit special run-length-16 codes (0xF0) */ + while (r > 15) { + if (! emit_bits(state, actbl->ehufco[0xF0], actbl->ehufsi[0xF0])) + return FALSE; + r -= 16; + } + + temp2 = temp; + if (temp < 0) { + temp = -temp; /* temp is abs value of input */ + /* This code assumes we are on a two's complement machine */ + temp2--; + } + + /* Find the number of bits needed for the magnitude of the coefficient */ + nbits = 1; /* there must be at least one 1 bit */ + while ((temp >>= 1)) + nbits++; + /* Check for out-of-range coefficient values */ + if (nbits > MAX_COEF_BITS) + ERREXIT(state->cinfo, JERR_BAD_DCT_COEF); + + /* Emit Huffman symbol for run length / number of bits */ + i = (r << 4) + nbits; + if (! emit_bits(state, actbl->ehufco[i], actbl->ehufsi[i])) + return FALSE; + + /* Emit that number of bits of the value, if positive, */ + /* or the complement of its magnitude, if negative. */ + if (! emit_bits(state, (unsigned int) temp2, nbits)) + return FALSE; + + r = 0; + } + } + + /* If the last coef(s) were zero, emit an end-of-block code */ + if (r > 0) + if (! emit_bits(state, actbl->ehufco[0], actbl->ehufsi[0])) + return FALSE; + + return TRUE; +} + + +/* + * Emit a restart marker & resynchronize predictions. + */ + +LOCAL(boolean) +emit_restart (working_state * state, int restart_num) +{ + int ci; + + if (! flush_bits(state)) + return FALSE; + + emit_byte(state, 0xFF, return FALSE); + emit_byte(state, JPEG_RST0 + restart_num, return FALSE); + + /* Re-initialize DC predictions to 0 */ + for (ci = 0; ci < state->cinfo->comps_in_scan; ci++) + state->cur.last_dc_val[ci] = 0; + + /* The restart counter is not updated until we successfully write the MCU. */ + + return TRUE; +} + + +/* + * Encode and output one MCU's worth of Huffman-compressed coefficients. + */ + +METHODDEF(boolean) +encode_mcu_huff (j_compress_ptr cinfo, JBLOCKROW *MCU_data) +{ + huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; + working_state state; + int blkn, ci; + jpeg_component_info * compptr; + + /* Load up working state */ + state.next_output_byte = cinfo->dest->next_output_byte; + state.free_in_buffer = cinfo->dest->free_in_buffer; + ASSIGN_STATE(state.cur, entropy->saved); + state.cinfo = cinfo; + + /* Emit restart marker if needed */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) + if (! emit_restart(&state, entropy->next_restart_num)) + return FALSE; + } + + /* Encode the MCU data blocks */ + for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { + ci = cinfo->MCU_membership[blkn]; + compptr = cinfo->cur_comp_info[ci]; + if (! encode_one_block(&state, + MCU_data[blkn][0], state.cur.last_dc_val[ci], + entropy->dc_derived_tbls[compptr->dc_tbl_no], + entropy->ac_derived_tbls[compptr->ac_tbl_no])) + return FALSE; + /* Update last_dc_val */ + state.cur.last_dc_val[ci] = MCU_data[blkn][0][0]; + } + + /* Completed MCU, so update state */ + cinfo->dest->next_output_byte = state.next_output_byte; + cinfo->dest->free_in_buffer = state.free_in_buffer; + ASSIGN_STATE(entropy->saved, state.cur); + + /* Update restart-interval state too */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) { + entropy->restarts_to_go = cinfo->restart_interval; + entropy->next_restart_num++; + entropy->next_restart_num &= 7; + } + entropy->restarts_to_go--; + } + + return TRUE; +} + + +/* + * Finish up at the end of a Huffman-compressed scan. + */ + +METHODDEF(void) +finish_pass_huff (j_compress_ptr cinfo) +{ + huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; + working_state state; + + /* Load up working state ... flush_bits needs it */ + state.next_output_byte = cinfo->dest->next_output_byte; + state.free_in_buffer = cinfo->dest->free_in_buffer; + ASSIGN_STATE(state.cur, entropy->saved); + state.cinfo = cinfo; + + /* Flush out the last data */ + if (! flush_bits(&state)) + ERREXIT(cinfo, JERR_CANT_SUSPEND); + + /* Update state */ + cinfo->dest->next_output_byte = state.next_output_byte; + cinfo->dest->free_in_buffer = state.free_in_buffer; + ASSIGN_STATE(entropy->saved, state.cur); +} + + +/* + * Huffman coding optimization. + * + * We first scan the supplied data and count the number of uses of each symbol + * that is to be Huffman-coded. (This process MUST agree with the code above.) + * Then we build a Huffman coding tree for the observed counts. + * Symbols which are not needed at all for the particular image are not + * assigned any code, which saves space in the DHT marker as well as in + * the compressed data. + */ + +#ifdef ENTROPY_OPT_SUPPORTED + + +/* Process a single block's worth of coefficients */ + +LOCAL(void) +htest_one_block (j_compress_ptr cinfo, JCOEFPTR block, int last_dc_val, + long dc_counts[], long ac_counts[]) +{ + register int temp; + register int nbits; + register int k, r; + + /* Encode the DC coefficient difference per section F.1.2.1 */ + + temp = block[0] - last_dc_val; + if (temp < 0) + temp = -temp; + + /* Find the number of bits needed for the magnitude of the coefficient */ + nbits = 0; + while (temp) { + nbits++; + temp >>= 1; + } + /* Check for out-of-range coefficient values. + * Since we're encoding a difference, the range limit is twice as much. + */ + if (nbits > MAX_COEF_BITS+1) + ERREXIT(cinfo, JERR_BAD_DCT_COEF); + + /* Count the Huffman symbol for the number of bits */ + dc_counts[nbits]++; + + /* Encode the AC coefficients per section F.1.2.2 */ + + r = 0; /* r = run length of zeros */ + + for (k = 1; k < DCTSIZE2; k++) { + if ((temp = block[jpeg_natural_order[k]]) == 0) { + r++; + } else { + /* if run length > 15, must emit special run-length-16 codes (0xF0) */ + while (r > 15) { + ac_counts[0xF0]++; + r -= 16; + } + + /* Find the number of bits needed for the magnitude of the coefficient */ + if (temp < 0) + temp = -temp; + + /* Find the number of bits needed for the magnitude of the coefficient */ + nbits = 1; /* there must be at least one 1 bit */ + while ((temp >>= 1)) + nbits++; + /* Check for out-of-range coefficient values */ + if (nbits > MAX_COEF_BITS) + ERREXIT(cinfo, JERR_BAD_DCT_COEF); + + /* Count Huffman symbol for run length / number of bits */ + ac_counts[(r << 4) + nbits]++; + + r = 0; + } + } + + /* If the last coef(s) were zero, emit an end-of-block code */ + if (r > 0) + ac_counts[0]++; +} + + +/* + * Trial-encode one MCU's worth of Huffman-compressed coefficients. + * No data is actually output, so no suspension return is possible. + */ + +METHODDEF(boolean) +encode_mcu_gather (j_compress_ptr cinfo, JBLOCKROW *MCU_data) +{ + huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; + int blkn, ci; + jpeg_component_info * compptr; + + /* Take care of restart intervals if needed */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) { + /* Re-initialize DC predictions to 0 */ + for (ci = 0; ci < cinfo->comps_in_scan; ci++) + entropy->saved.last_dc_val[ci] = 0; + /* Update restart state */ + entropy->restarts_to_go = cinfo->restart_interval; + } + entropy->restarts_to_go--; + } + + for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { + ci = cinfo->MCU_membership[blkn]; + compptr = cinfo->cur_comp_info[ci]; + htest_one_block(cinfo, MCU_data[blkn][0], entropy->saved.last_dc_val[ci], + entropy->dc_count_ptrs[compptr->dc_tbl_no], + entropy->ac_count_ptrs[compptr->ac_tbl_no]); + entropy->saved.last_dc_val[ci] = MCU_data[blkn][0][0]; + } + + return TRUE; +} + + +/* + * Generate the best Huffman code table for the given counts, fill htbl. + * Note this is also used by jcphuff.c. + * + * The JPEG standard requires that no symbol be assigned a codeword of all + * one bits (so that padding bits added at the end of a compressed segment + * can't look like a valid code). Because of the canonical ordering of + * codewords, this just means that there must be an unused slot in the + * longest codeword length category. Section K.2 of the JPEG spec suggests + * reserving such a slot by pretending that symbol 256 is a valid symbol + * with count 1. In theory that's not optimal; giving it count zero but + * including it in the symbol set anyway should give a better Huffman code. + * But the theoretically better code actually seems to come out worse in + * practice, because it produces more all-ones bytes (which incur stuffed + * zero bytes in the final file). In any case the difference is tiny. + * + * The JPEG standard requires Huffman codes to be no more than 16 bits long. + * If some symbols have a very small but nonzero probability, the Huffman tree + * must be adjusted to meet the code length restriction. We currently use + * the adjustment method suggested in JPEG section K.2. This method is *not* + * optimal; it may not choose the best possible limited-length code. But + * typically only very-low-frequency symbols will be given less-than-optimal + * lengths, so the code is almost optimal. Experimental comparisons against + * an optimal limited-length-code algorithm indicate that the difference is + * microscopic --- usually less than a hundredth of a percent of total size. + * So the extra complexity of an optimal algorithm doesn't seem worthwhile. + */ + +GLOBAL(void) +jpeg_gen_optimal_table (j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[]) +{ +#define MAX_CLEN 32 /* assumed maximum initial code length */ + UINT8 bits[MAX_CLEN+1]; /* bits[k] = # of symbols with code length k */ + int codesize[257]; /* codesize[k] = code length of symbol k */ + int others[257]; /* next symbol in current branch of tree */ + int c1, c2; + int p, i, j; + long v; + + /* This algorithm is explained in section K.2 of the JPEG standard */ + + MEMZERO(bits, SIZEOF(bits)); + MEMZERO(codesize, SIZEOF(codesize)); + for (i = 0; i < 257; i++) + others[i] = -1; /* init links to empty */ + + freq[256] = 1; /* make sure 256 has a nonzero count */ + /* Including the pseudo-symbol 256 in the Huffman procedure guarantees + * that no real symbol is given code-value of all ones, because 256 + * will be placed last in the largest codeword category. + */ + + /* Huffman's basic algorithm to assign optimal code lengths to symbols */ + + for (;;) { + /* Find the smallest nonzero frequency, set c1 = its symbol */ + /* In case of ties, take the larger symbol number */ + c1 = -1; + v = 1000000000L; + for (i = 0; i <= 256; i++) { + if (freq[i] && freq[i] <= v) { + v = freq[i]; + c1 = i; + } + } + + /* Find the next smallest nonzero frequency, set c2 = its symbol */ + /* In case of ties, take the larger symbol number */ + c2 = -1; + v = 1000000000L; + for (i = 0; i <= 256; i++) { + if (freq[i] && freq[i] <= v && i != c1) { + v = freq[i]; + c2 = i; + } + } + + /* Done if we've merged everything into one frequency */ + if (c2 < 0) + break; + + /* Else merge the two counts/trees */ + freq[c1] += freq[c2]; + freq[c2] = 0; + + /* Increment the codesize of everything in c1's tree branch */ + codesize[c1]++; + while (others[c1] >= 0) { + c1 = others[c1]; + codesize[c1]++; + } + + others[c1] = c2; /* chain c2 onto c1's tree branch */ + + /* Increment the codesize of everything in c2's tree branch */ + codesize[c2]++; + while (others[c2] >= 0) { + c2 = others[c2]; + codesize[c2]++; + } + } + + /* Now count the number of symbols of each code length */ + for (i = 0; i <= 256; i++) { + if (codesize[i]) { + /* The JPEG standard seems to think that this can't happen, */ + /* but I'm paranoid... */ + if (codesize[i] > MAX_CLEN) + ERREXIT(cinfo, JERR_HUFF_CLEN_OVERFLOW); + + bits[codesize[i]]++; + } + } + + /* JPEG doesn't allow symbols with code lengths over 16 bits, so if the pure + * Huffman procedure assigned any such lengths, we must adjust the coding. + * Here is what the JPEG spec says about how this next bit works: + * Since symbols are paired for the longest Huffman code, the symbols are + * removed from this length category two at a time. The prefix for the pair + * (which is one bit shorter) is allocated to one of the pair; then, + * skipping the BITS entry for that prefix length, a code word from the next + * shortest nonzero BITS entry is converted into a prefix for two code words + * one bit longer. + */ + + for (i = MAX_CLEN; i > 16; i--) { + while (bits[i] > 0) { + j = i - 2; /* find length of new prefix to be used */ + while (bits[j] == 0) + j--; + + bits[i] -= 2; /* remove two symbols */ + bits[i-1]++; /* one goes in this length */ + bits[j+1] += 2; /* two new symbols in this length */ + bits[j]--; /* symbol of this length is now a prefix */ + } + } + + /* Remove the count for the pseudo-symbol 256 from the largest codelength */ + while (bits[i] == 0) /* find largest codelength still in use */ + i--; + bits[i]--; + + /* Return final symbol counts (only for lengths 0..16) */ + MEMCOPY(htbl->bits, bits, SIZEOF(htbl->bits)); + + /* Return a list of the symbols sorted by code length */ + /* It's not real clear to me why we don't need to consider the codelength + * changes made above, but the JPEG spec seems to think this works. + */ + p = 0; + for (i = 1; i <= MAX_CLEN; i++) { + for (j = 0; j <= 255; j++) { + if (codesize[j] == i) { + htbl->huffval[p] = (UINT8) j; + p++; + } + } + } + + /* Set sent_table FALSE so updated table will be written to JPEG file. */ + htbl->sent_table = FALSE; +} + + +/* + * Finish up a statistics-gathering pass and create the new Huffman tables. + */ + +METHODDEF(void) +finish_pass_gather (j_compress_ptr cinfo) +{ + huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; + int ci, dctbl, actbl; + jpeg_component_info * compptr; + JHUFF_TBL **htblptr; + boolean did_dc[NUM_HUFF_TBLS]; + boolean did_ac[NUM_HUFF_TBLS]; + + /* It's important not to apply jpeg_gen_optimal_table more than once + * per table, because it clobbers the input frequency counts! + */ + MEMZERO(did_dc, SIZEOF(did_dc)); + MEMZERO(did_ac, SIZEOF(did_ac)); + + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + dctbl = compptr->dc_tbl_no; + actbl = compptr->ac_tbl_no; + if (! did_dc[dctbl]) { + htblptr = & cinfo->dc_huff_tbl_ptrs[dctbl]; + if (*htblptr == NULL) + *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo); + jpeg_gen_optimal_table(cinfo, *htblptr, entropy->dc_count_ptrs[dctbl]); + did_dc[dctbl] = TRUE; + } + if (! did_ac[actbl]) { + htblptr = & cinfo->ac_huff_tbl_ptrs[actbl]; + if (*htblptr == NULL) + *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo); + jpeg_gen_optimal_table(cinfo, *htblptr, entropy->ac_count_ptrs[actbl]); + did_ac[actbl] = TRUE; + } + } +} + + +#endif /* ENTROPY_OPT_SUPPORTED */ + + +/* + * Module initialization routine for Huffman entropy encoding. + */ + +GLOBAL(void) +jinit_huff_encoder (j_compress_ptr cinfo) +{ + huff_entropy_ptr entropy; + int i; + + entropy = (huff_entropy_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(huff_entropy_encoder)); + cinfo->entropy = (struct jpeg_entropy_encoder *) entropy; + entropy->pub.start_pass = start_pass_huff; + + /* Mark tables unallocated */ + for (i = 0; i < NUM_HUFF_TBLS; i++) { + entropy->dc_derived_tbls[i] = entropy->ac_derived_tbls[i] = NULL; +#ifdef ENTROPY_OPT_SUPPORTED + entropy->dc_count_ptrs[i] = entropy->ac_count_ptrs[i] = NULL; +#endif + } +} diff --git a/mod/pub.mod/libjpeg.mod/jchuff.h b/mod/pub.mod/libjpeg.mod/jchuff.h new file mode 100644 index 0000000..a9599fc --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jchuff.h @@ -0,0 +1,47 @@ +/* + * jchuff.h + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains declarations for Huffman entropy encoding routines + * that are shared between the sequential encoder (jchuff.c) and the + * progressive encoder (jcphuff.c). No other modules need to see these. + */ + +/* The legal range of a DCT coefficient is + * -1024 .. +1023 for 8-bit data; + * -16384 .. +16383 for 12-bit data. + * Hence the magnitude should always fit in 10 or 14 bits respectively. + */ + +#if BITS_IN_JSAMPLE == 8 +#define MAX_COEF_BITS 10 +#else +#define MAX_COEF_BITS 14 +#endif + +/* Derived data constructed for each Huffman table */ + +typedef struct { + unsigned int ehufco[256]; /* code for each symbol */ + char ehufsi[256]; /* length of code for each symbol */ + /* If no code has been allocated for a symbol S, ehufsi[S] contains 0 */ +} c_derived_tbl; + +/* Short forms of external names for systems with brain-damaged linkers. */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jpeg_make_c_derived_tbl jMkCDerived +#define jpeg_gen_optimal_table jGenOptTbl +#endif /* NEED_SHORT_EXTERNAL_NAMES */ + +/* Expand a Huffman table definition into the derived format */ +EXTERN(void) jpeg_make_c_derived_tbl + JPP((j_compress_ptr cinfo, boolean isDC, int tblno, + c_derived_tbl ** pdtbl)); + +/* Generate an optimal table definition given the specified counts */ +EXTERN(void) jpeg_gen_optimal_table + JPP((j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[])); diff --git a/mod/pub.mod/libjpeg.mod/jcinit.c b/mod/pub.mod/libjpeg.mod/jcinit.c new file mode 100644 index 0000000..5efffe3 --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jcinit.c @@ -0,0 +1,72 @@ +/* + * jcinit.c + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains initialization logic for the JPEG compressor. + * This routine is in charge of selecting the modules to be executed and + * making an initialization call to each one. + * + * Logically, this code belongs in jcmaster.c. It's split out because + * linking this routine implies linking the entire compression library. + * For a transcoding-only application, we want to be able to use jcmaster.c + * without linking in the whole library. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* + * Master selection of compression modules. + * This is done once at the start of processing an image. We determine + * which modules will be used and give them appropriate initialization calls. + */ + +GLOBAL(void) +jinit_compress_master (j_compress_ptr cinfo) +{ + /* Initialize master control (includes parameter checking/processing) */ + jinit_c_master_control(cinfo, FALSE /* full compression */); + + /* Preprocessing */ + if (! cinfo->raw_data_in) { + jinit_color_converter(cinfo); + jinit_downsampler(cinfo); + jinit_c_prep_controller(cinfo, FALSE /* never need full buffer here */); + } + /* Forward DCT */ + jinit_forward_dct(cinfo); + /* Entropy encoding: either Huffman or arithmetic coding. */ + if (cinfo->arith_code) { + ERREXIT(cinfo, JERR_ARITH_NOTIMPL); + } else { + if (cinfo->progressive_mode) { +#ifdef C_PROGRESSIVE_SUPPORTED + jinit_phuff_encoder(cinfo); +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } else + jinit_huff_encoder(cinfo); + } + + /* Need a full-image coefficient buffer in any multi-pass mode. */ + jinit_c_coef_controller(cinfo, + (boolean) (cinfo->num_scans > 1 || cinfo->optimize_coding)); + jinit_c_main_controller(cinfo, FALSE /* never need full buffer here */); + + jinit_marker_writer(cinfo); + + /* We can now tell the memory manager to allocate virtual arrays. */ + (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo); + + /* Write the datastream header (SOI) immediately. + * Frame and scan headers are postponed till later. + * This lets application insert special markers after the SOI. + */ + (*cinfo->marker->write_file_header) (cinfo); +} diff --git a/mod/pub.mod/libjpeg.mod/jcmainct.c b/mod/pub.mod/libjpeg.mod/jcmainct.c new file mode 100644 index 0000000..e0279a7 --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jcmainct.c @@ -0,0 +1,293 @@ +/* + * jcmainct.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains the main buffer controller for compression. + * The main buffer lies between the pre-processor and the JPEG + * compressor proper; it holds downsampled data in the JPEG colorspace. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* Note: currently, there is no operating mode in which a full-image buffer + * is needed at this step. If there were, that mode could not be used with + * "raw data" input, since this module is bypassed in that case. However, + * we've left the code here for possible use in special applications. + */ +#undef FULL_MAIN_BUFFER_SUPPORTED + + +/* Private buffer controller object */ + +typedef struct { + struct jpeg_c_main_controller pub; /* public fields */ + + JDIMENSION cur_iMCU_row; /* number of current iMCU row */ + JDIMENSION rowgroup_ctr; /* counts row groups received in iMCU row */ + boolean suspended; /* remember if we suspended output */ + J_BUF_MODE pass_mode; /* current operating mode */ + + /* If using just a strip buffer, this points to the entire set of buffers + * (we allocate one for each component). In the full-image case, this + * points to the currently accessible strips of the virtual arrays. + */ + JSAMPARRAY buffer[MAX_COMPONENTS]; + +#ifdef FULL_MAIN_BUFFER_SUPPORTED + /* If using full-image storage, this array holds pointers to virtual-array + * control blocks for each component. Unused if not full-image storage. + */ + jvirt_sarray_ptr whole_image[MAX_COMPONENTS]; +#endif +} my_main_controller; + +typedef my_main_controller * my_main_ptr; + + +/* Forward declarations */ +METHODDEF(void) process_data_simple_main + JPP((j_compress_ptr cinfo, JSAMPARRAY input_buf, + JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail)); +#ifdef FULL_MAIN_BUFFER_SUPPORTED +METHODDEF(void) process_data_buffer_main + JPP((j_compress_ptr cinfo, JSAMPARRAY input_buf, + JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail)); +#endif + + +/* + * Initialize for a processing pass. + */ + +METHODDEF(void) +start_pass_main (j_compress_ptr cinfo, J_BUF_MODE pass_mode) +{ + my_main_ptr main = (my_main_ptr) cinfo->main; + + /* Do nothing in raw-data mode. */ + if (cinfo->raw_data_in) + return; + + main->cur_iMCU_row = 0; /* initialize counters */ + main->rowgroup_ctr = 0; + main->suspended = FALSE; + main->pass_mode = pass_mode; /* save mode for use by process_data */ + + switch (pass_mode) { + case JBUF_PASS_THRU: +#ifdef FULL_MAIN_BUFFER_SUPPORTED + if (main->whole_image[0] != NULL) + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); +#endif + main->pub.process_data = process_data_simple_main; + break; +#ifdef FULL_MAIN_BUFFER_SUPPORTED + case JBUF_SAVE_SOURCE: + case JBUF_CRANK_DEST: + case JBUF_SAVE_AND_PASS: + if (main->whole_image[0] == NULL) + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + main->pub.process_data = process_data_buffer_main; + break; +#endif + default: + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + break; + } +} + + +/* + * Process some data. + * This routine handles the simple pass-through mode, + * where we have only a strip buffer. + */ + +METHODDEF(void) +process_data_simple_main (j_compress_ptr cinfo, + JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, + JDIMENSION in_rows_avail) +{ + my_main_ptr main = (my_main_ptr) cinfo->main; + + while (main->cur_iMCU_row < cinfo->total_iMCU_rows) { + /* Read input data if we haven't filled the main buffer yet */ + if (main->rowgroup_ctr < DCTSIZE) + (*cinfo->prep->pre_process_data) (cinfo, + input_buf, in_row_ctr, in_rows_avail, + main->buffer, &main->rowgroup_ctr, + (JDIMENSION) DCTSIZE); + + /* If we don't have a full iMCU row buffered, return to application for + * more data. Note that preprocessor will always pad to fill the iMCU row + * at the bottom of the image. + */ + if (main->rowgroup_ctr != DCTSIZE) + return; + + /* Send the completed row to the compressor */ + if (! (*cinfo->coef->compress_data) (cinfo, main->buffer)) { + /* If compressor did not consume the whole row, then we must need to + * suspend processing and return to the application. In this situation + * we pretend we didn't yet consume the last input row; otherwise, if + * it happened to be the last row of the image, the application would + * think we were done. + */ + if (! main->suspended) { + (*in_row_ctr)--; + main->suspended = TRUE; + } + return; + } + /* We did finish the row. Undo our little suspension hack if a previous + * call suspended; then mark the main buffer empty. + */ + if (main->suspended) { + (*in_row_ctr)++; + main->suspended = FALSE; + } + main->rowgroup_ctr = 0; + main->cur_iMCU_row++; + } +} + + +#ifdef FULL_MAIN_BUFFER_SUPPORTED + +/* + * Process some data. + * This routine handles all of the modes that use a full-size buffer. + */ + +METHODDEF(void) +process_data_buffer_main (j_compress_ptr cinfo, + JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, + JDIMENSION in_rows_avail) +{ + my_main_ptr main = (my_main_ptr) cinfo->main; + int ci; + jpeg_component_info *compptr; + boolean writing = (main->pass_mode != JBUF_CRANK_DEST); + + while (main->cur_iMCU_row < cinfo->total_iMCU_rows) { + /* Realign the virtual buffers if at the start of an iMCU row. */ + if (main->rowgroup_ctr == 0) { + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + main->buffer[ci] = (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, main->whole_image[ci], + main->cur_iMCU_row * (compptr->v_samp_factor * DCTSIZE), + (JDIMENSION) (compptr->v_samp_factor * DCTSIZE), writing); + } + /* In a read pass, pretend we just read some source data. */ + if (! writing) { + *in_row_ctr += cinfo->max_v_samp_factor * DCTSIZE; + main->rowgroup_ctr = DCTSIZE; + } + } + + /* If a write pass, read input data until the current iMCU row is full. */ + /* Note: preprocessor will pad if necessary to fill the last iMCU row. */ + if (writing) { + (*cinfo->prep->pre_process_data) (cinfo, + input_buf, in_row_ctr, in_rows_avail, + main->buffer, &main->rowgroup_ctr, + (JDIMENSION) DCTSIZE); + /* Return to application if we need more data to fill the iMCU row. */ + if (main->rowgroup_ctr < DCTSIZE) + return; + } + + /* Emit data, unless this is a sink-only pass. */ + if (main->pass_mode != JBUF_SAVE_SOURCE) { + if (! (*cinfo->coef->compress_data) (cinfo, main->buffer)) { + /* If compressor did not consume the whole row, then we must need to + * suspend processing and return to the application. In this situation + * we pretend we didn't yet consume the last input row; otherwise, if + * it happened to be the last row of the image, the application would + * think we were done. + */ + if (! main->suspended) { + (*in_row_ctr)--; + main->suspended = TRUE; + } + return; + } + /* We did finish the row. Undo our little suspension hack if a previous + * call suspended; then mark the main buffer empty. + */ + if (main->suspended) { + (*in_row_ctr)++; + main->suspended = FALSE; + } + } + + /* If get here, we are done with this iMCU row. Mark buffer empty. */ + main->rowgroup_ctr = 0; + main->cur_iMCU_row++; + } +} + +#endif /* FULL_MAIN_BUFFER_SUPPORTED */ + + +/* + * Initialize main buffer controller. + */ + +GLOBAL(void) +jinit_c_main_controller (j_compress_ptr cinfo, boolean need_full_buffer) +{ + my_main_ptr main; + int ci; + jpeg_component_info *compptr; + + main = (my_main_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_main_controller)); + cinfo->main = (struct jpeg_c_main_controller *) main; + main->pub.start_pass = start_pass_main; + + /* We don't need to create a buffer in raw-data mode. */ + if (cinfo->raw_data_in) + return; + + /* Create the buffer. It holds downsampled data, so each component + * may be of a different size. + */ + if (need_full_buffer) { +#ifdef FULL_MAIN_BUFFER_SUPPORTED + /* Allocate a full-image virtual array for each component */ + /* Note we pad the bottom to a multiple of the iMCU height */ + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + main->whole_image[ci] = (*cinfo->mem->request_virt_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE, + compptr->width_in_blocks * DCTSIZE, + (JDIMENSION) jround_up((long) compptr->height_in_blocks, + (long) compptr->v_samp_factor) * DCTSIZE, + (JDIMENSION) (compptr->v_samp_factor * DCTSIZE)); + } +#else + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); +#endif + } else { +#ifdef FULL_MAIN_BUFFER_SUPPORTED + main->whole_image[0] = NULL; /* flag for no virtual arrays */ +#endif + /* Allocate a strip buffer for each component */ + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + main->buffer[ci] = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + compptr->width_in_blocks * DCTSIZE, + (JDIMENSION) (compptr->v_samp_factor * DCTSIZE)); + } + } +} diff --git a/mod/pub.mod/libjpeg.mod/jcmarker.c b/mod/pub.mod/libjpeg.mod/jcmarker.c new file mode 100644 index 0000000..3d1e6c6 --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jcmarker.c @@ -0,0 +1,664 @@ +/* + * jcmarker.c + * + * Copyright (C) 1991-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains routines to write JPEG datastream markers. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +typedef enum { /* JPEG marker codes */ + M_SOF0 = 0xc0, + M_SOF1 = 0xc1, + M_SOF2 = 0xc2, + M_SOF3 = 0xc3, + + M_SOF5 = 0xc5, + M_SOF6 = 0xc6, + M_SOF7 = 0xc7, + + M_JPG = 0xc8, + M_SOF9 = 0xc9, + M_SOF10 = 0xca, + M_SOF11 = 0xcb, + + M_SOF13 = 0xcd, + M_SOF14 = 0xce, + M_SOF15 = 0xcf, + + M_DHT = 0xc4, + + M_DAC = 0xcc, + + M_RST0 = 0xd0, + M_RST1 = 0xd1, + M_RST2 = 0xd2, + M_RST3 = 0xd3, + M_RST4 = 0xd4, + M_RST5 = 0xd5, + M_RST6 = 0xd6, + M_RST7 = 0xd7, + + M_SOI = 0xd8, + M_EOI = 0xd9, + M_SOS = 0xda, + M_DQT = 0xdb, + M_DNL = 0xdc, + M_DRI = 0xdd, + M_DHP = 0xde, + M_EXP = 0xdf, + + M_APP0 = 0xe0, + M_APP1 = 0xe1, + M_APP2 = 0xe2, + M_APP3 = 0xe3, + M_APP4 = 0xe4, + M_APP5 = 0xe5, + M_APP6 = 0xe6, + M_APP7 = 0xe7, + M_APP8 = 0xe8, + M_APP9 = 0xe9, + M_APP10 = 0xea, + M_APP11 = 0xeb, + M_APP12 = 0xec, + M_APP13 = 0xed, + M_APP14 = 0xee, + M_APP15 = 0xef, + + M_JPG0 = 0xf0, + M_JPG13 = 0xfd, + M_COM = 0xfe, + + M_TEM = 0x01, + + M_ERROR = 0x100 +} JPEG_MARKER; + + +/* Private state */ + +typedef struct { + struct jpeg_marker_writer pub; /* public fields */ + + unsigned int last_restart_interval; /* last DRI value emitted; 0 after SOI */ +} my_marker_writer; + +typedef my_marker_writer * my_marker_ptr; + + +/* + * Basic output routines. + * + * Note that we do not support suspension while writing a marker. + * Therefore, an application using suspension must ensure that there is + * enough buffer space for the initial markers (typ. 600-700 bytes) before + * calling jpeg_start_compress, and enough space to write the trailing EOI + * (a few bytes) before calling jpeg_finish_compress. Multipass compression + * modes are not supported at all with suspension, so those two are the only + * points where markers will be written. + */ + +LOCAL(void) +emit_byte (j_compress_ptr cinfo, int val) +/* Emit a byte */ +{ + struct jpeg_destination_mgr * dest = cinfo->dest; + + *(dest->next_output_byte)++ = (JOCTET) val; + if (--dest->free_in_buffer == 0) { + if (! (*dest->empty_output_buffer) (cinfo)) + ERREXIT(cinfo, JERR_CANT_SUSPEND); + } +} + + +LOCAL(void) +emit_marker (j_compress_ptr cinfo, JPEG_MARKER mark) +/* Emit a marker code */ +{ + emit_byte(cinfo, 0xFF); + emit_byte(cinfo, (int) mark); +} + + +LOCAL(void) +emit_2bytes (j_compress_ptr cinfo, int value) +/* Emit a 2-byte integer; these are always MSB first in JPEG files */ +{ + emit_byte(cinfo, (value >> 8) & 0xFF); + emit_byte(cinfo, value & 0xFF); +} + + +/* + * Routines to write specific marker types. + */ + +LOCAL(int) +emit_dqt (j_compress_ptr cinfo, int index) +/* Emit a DQT marker */ +/* Returns the precision used (0 = 8bits, 1 = 16bits) for baseline checking */ +{ + JQUANT_TBL * qtbl = cinfo->quant_tbl_ptrs[index]; + int prec; + int i; + + if (qtbl == NULL) + ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, index); + + prec = 0; + for (i = 0; i < DCTSIZE2; i++) { + if (qtbl->quantval[i] > 255) + prec = 1; + } + + if (! qtbl->sent_table) { + emit_marker(cinfo, M_DQT); + + emit_2bytes(cinfo, prec ? DCTSIZE2*2 + 1 + 2 : DCTSIZE2 + 1 + 2); + + emit_byte(cinfo, index + (prec<<4)); + + for (i = 0; i < DCTSIZE2; i++) { + /* The table entries must be emitted in zigzag order. */ + unsigned int qval = qtbl->quantval[jpeg_natural_order[i]]; + if (prec) + emit_byte(cinfo, (int) (qval >> 8)); + emit_byte(cinfo, (int) (qval & 0xFF)); + } + + qtbl->sent_table = TRUE; + } + + return prec; +} + + +LOCAL(void) +emit_dht (j_compress_ptr cinfo, int index, boolean is_ac) +/* Emit a DHT marker */ +{ + JHUFF_TBL * htbl; + int length, i; + + if (is_ac) { + htbl = cinfo->ac_huff_tbl_ptrs[index]; + index += 0x10; /* output index has AC bit set */ + } else { + htbl = cinfo->dc_huff_tbl_ptrs[index]; + } + + if (htbl == NULL) + ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, index); + + if (! htbl->sent_table) { + emit_marker(cinfo, M_DHT); + + length = 0; + for (i = 1; i <= 16; i++) + length += htbl->bits[i]; + + emit_2bytes(cinfo, length + 2 + 1 + 16); + emit_byte(cinfo, index); + + for (i = 1; i <= 16; i++) + emit_byte(cinfo, htbl->bits[i]); + + for (i = 0; i < length; i++) + emit_byte(cinfo, htbl->huffval[i]); + + htbl->sent_table = TRUE; + } +} + + +LOCAL(void) +emit_dac (j_compress_ptr cinfo) +/* Emit a DAC marker */ +/* Since the useful info is so small, we want to emit all the tables in */ +/* one DAC marker. Therefore this routine does its own scan of the table. */ +{ +#ifdef C_ARITH_CODING_SUPPORTED + char dc_in_use[NUM_ARITH_TBLS]; + char ac_in_use[NUM_ARITH_TBLS]; + int length, i; + jpeg_component_info *compptr; + + for (i = 0; i < NUM_ARITH_TBLS; i++) + dc_in_use[i] = ac_in_use[i] = 0; + + for (i = 0; i < cinfo->comps_in_scan; i++) { + compptr = cinfo->cur_comp_info[i]; + dc_in_use[compptr->dc_tbl_no] = 1; + ac_in_use[compptr->ac_tbl_no] = 1; + } + + length = 0; + for (i = 0; i < NUM_ARITH_TBLS; i++) + length += dc_in_use[i] + ac_in_use[i]; + + emit_marker(cinfo, M_DAC); + + emit_2bytes(cinfo, length*2 + 2); + + for (i = 0; i < NUM_ARITH_TBLS; i++) { + if (dc_in_use[i]) { + emit_byte(cinfo, i); + emit_byte(cinfo, cinfo->arith_dc_L[i] + (cinfo->arith_dc_U[i]<<4)); + } + if (ac_in_use[i]) { + emit_byte(cinfo, i + 0x10); + emit_byte(cinfo, cinfo->arith_ac_K[i]); + } + } +#endif /* C_ARITH_CODING_SUPPORTED */ +} + + +LOCAL(void) +emit_dri (j_compress_ptr cinfo) +/* Emit a DRI marker */ +{ + emit_marker(cinfo, M_DRI); + + emit_2bytes(cinfo, 4); /* fixed length */ + + emit_2bytes(cinfo, (int) cinfo->restart_interval); +} + + +LOCAL(void) +emit_sof (j_compress_ptr cinfo, JPEG_MARKER code) +/* Emit a SOF marker */ +{ + int ci; + jpeg_component_info *compptr; + + emit_marker(cinfo, code); + + emit_2bytes(cinfo, 3 * cinfo->num_components + 2 + 5 + 1); /* length */ + + /* Make sure image isn't bigger than SOF field can handle */ + if ((long) cinfo->image_height > 65535L || + (long) cinfo->image_width > 65535L) + ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) 65535); + + emit_byte(cinfo, cinfo->data_precision); + emit_2bytes(cinfo, (int) cinfo->image_height); + emit_2bytes(cinfo, (int) cinfo->image_width); + + emit_byte(cinfo, cinfo->num_components); + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + emit_byte(cinfo, compptr->component_id); + emit_byte(cinfo, (compptr->h_samp_factor << 4) + compptr->v_samp_factor); + emit_byte(cinfo, compptr->quant_tbl_no); + } +} + + +LOCAL(void) +emit_sos (j_compress_ptr cinfo) +/* Emit a SOS marker */ +{ + int i, td, ta; + jpeg_component_info *compptr; + + emit_marker(cinfo, M_SOS); + + emit_2bytes(cinfo, 2 * cinfo->comps_in_scan + 2 + 1 + 3); /* length */ + + emit_byte(cinfo, cinfo->comps_in_scan); + + for (i = 0; i < cinfo->comps_in_scan; i++) { + compptr = cinfo->cur_comp_info[i]; + emit_byte(cinfo, compptr->component_id); + td = compptr->dc_tbl_no; + ta = compptr->ac_tbl_no; + if (cinfo->progressive_mode) { + /* Progressive mode: only DC or only AC tables are used in one scan; + * furthermore, Huffman coding of DC refinement uses no table at all. + * We emit 0 for unused field(s); this is recommended by the P&M text + * but does not seem to be specified in the standard. + */ + if (cinfo->Ss == 0) { + ta = 0; /* DC scan */ + if (cinfo->Ah != 0 && !cinfo->arith_code) + td = 0; /* no DC table either */ + } else { + td = 0; /* AC scan */ + } + } + emit_byte(cinfo, (td << 4) + ta); + } + + emit_byte(cinfo, cinfo->Ss); + emit_byte(cinfo, cinfo->Se); + emit_byte(cinfo, (cinfo->Ah << 4) + cinfo->Al); +} + + +LOCAL(void) +emit_jfif_app0 (j_compress_ptr cinfo) +/* Emit a JFIF-compliant APP0 marker */ +{ + /* + * Length of APP0 block (2 bytes) + * Block ID (4 bytes - ASCII "JFIF") + * Zero byte (1 byte to terminate the ID string) + * Version Major, Minor (2 bytes - major first) + * Units (1 byte - 0x00 = none, 0x01 = inch, 0x02 = cm) + * Xdpu (2 bytes - dots per unit horizontal) + * Ydpu (2 bytes - dots per unit vertical) + * Thumbnail X size (1 byte) + * Thumbnail Y size (1 byte) + */ + + emit_marker(cinfo, M_APP0); + + emit_2bytes(cinfo, 2 + 4 + 1 + 2 + 1 + 2 + 2 + 1 + 1); /* length */ + + emit_byte(cinfo, 0x4A); /* Identifier: ASCII "JFIF" */ + emit_byte(cinfo, 0x46); + emit_byte(cinfo, 0x49); + emit_byte(cinfo, 0x46); + emit_byte(cinfo, 0); + emit_byte(cinfo, cinfo->JFIF_major_version); /* Version fields */ + emit_byte(cinfo, cinfo->JFIF_minor_version); + emit_byte(cinfo, cinfo->density_unit); /* Pixel size information */ + emit_2bytes(cinfo, (int) cinfo->X_density); + emit_2bytes(cinfo, (int) cinfo->Y_density); + emit_byte(cinfo, 0); /* No thumbnail image */ + emit_byte(cinfo, 0); +} + + +LOCAL(void) +emit_adobe_app14 (j_compress_ptr cinfo) +/* Emit an Adobe APP14 marker */ +{ + /* + * Length of APP14 block (2 bytes) + * Block ID (5 bytes - ASCII "Adobe") + * Version Number (2 bytes - currently 100) + * Flags0 (2 bytes - currently 0) + * Flags1 (2 bytes - currently 0) + * Color transform (1 byte) + * + * Although Adobe TN 5116 mentions Version = 101, all the Adobe files + * now in circulation seem to use Version = 100, so that's what we write. + * + * We write the color transform byte as 1 if the JPEG color space is + * YCbCr, 2 if it's YCCK, 0 otherwise. Adobe's definition has to do with + * whether the encoder performed a transformation, which is pretty useless. + */ + + emit_marker(cinfo, M_APP14); + + emit_2bytes(cinfo, 2 + 5 + 2 + 2 + 2 + 1); /* length */ + + emit_byte(cinfo, 0x41); /* Identifier: ASCII "Adobe" */ + emit_byte(cinfo, 0x64); + emit_byte(cinfo, 0x6F); + emit_byte(cinfo, 0x62); + emit_byte(cinfo, 0x65); + emit_2bytes(cinfo, 100); /* Version */ + emit_2bytes(cinfo, 0); /* Flags0 */ + emit_2bytes(cinfo, 0); /* Flags1 */ + switch (cinfo->jpeg_color_space) { + case JCS_YCbCr: + emit_byte(cinfo, 1); /* Color transform = 1 */ + break; + case JCS_YCCK: + emit_byte(cinfo, 2); /* Color transform = 2 */ + break; + default: + emit_byte(cinfo, 0); /* Color transform = 0 */ + break; + } +} + + +/* + * These routines allow writing an arbitrary marker with parameters. + * The only intended use is to emit COM or APPn markers after calling + * write_file_header and before calling write_frame_header. + * Other uses are not guaranteed to produce desirable results. + * Counting the parameter bytes properly is the caller's responsibility. + */ + +METHODDEF(void) +write_marker_header (j_compress_ptr cinfo, int marker, unsigned int datalen) +/* Emit an arbitrary marker header */ +{ + if (datalen > (unsigned int) 65533) /* safety check */ + ERREXIT(cinfo, JERR_BAD_LENGTH); + + emit_marker(cinfo, (JPEG_MARKER) marker); + + emit_2bytes(cinfo, (int) (datalen + 2)); /* total length */ +} + +METHODDEF(void) +write_marker_byte (j_compress_ptr cinfo, int val) +/* Emit one byte of marker parameters following write_marker_header */ +{ + emit_byte(cinfo, val); +} + + +/* + * Write datastream header. + * This consists of an SOI and optional APPn markers. + * We recommend use of the JFIF marker, but not the Adobe marker, + * when using YCbCr or grayscale data. The JFIF marker should NOT + * be used for any other JPEG colorspace. The Adobe marker is helpful + * to distinguish RGB, CMYK, and YCCK colorspaces. + * Note that an application can write additional header markers after + * jpeg_start_compress returns. + */ + +METHODDEF(void) +write_file_header (j_compress_ptr cinfo) +{ + my_marker_ptr marker = (my_marker_ptr) cinfo->marker; + + emit_marker(cinfo, M_SOI); /* first the SOI */ + + /* SOI is defined to reset restart interval to 0 */ + marker->last_restart_interval = 0; + + if (cinfo->write_JFIF_header) /* next an optional JFIF APP0 */ + emit_jfif_app0(cinfo); + if (cinfo->write_Adobe_marker) /* next an optional Adobe APP14 */ + emit_adobe_app14(cinfo); +} + + +/* + * Write frame header. + * This consists of DQT and SOFn markers. + * Note that we do not emit the SOF until we have emitted the DQT(s). + * This avoids compatibility problems with incorrect implementations that + * try to error-check the quant table numbers as soon as they see the SOF. + */ + +METHODDEF(void) +write_frame_header (j_compress_ptr cinfo) +{ + int ci, prec; + boolean is_baseline; + jpeg_component_info *compptr; + + /* Emit DQT for each quantization table. + * Note that emit_dqt() suppresses any duplicate tables. + */ + prec = 0; + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + prec += emit_dqt(cinfo, compptr->quant_tbl_no); + } + /* now prec is nonzero iff there are any 16-bit quant tables. */ + + /* Check for a non-baseline specification. + * Note we assume that Huffman table numbers won't be changed later. + */ + if (cinfo->arith_code || cinfo->progressive_mode || + cinfo->data_precision != 8) { + is_baseline = FALSE; + } else { + is_baseline = TRUE; + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + if (compptr->dc_tbl_no > 1 || compptr->ac_tbl_no > 1) + is_baseline = FALSE; + } + if (prec && is_baseline) { + is_baseline = FALSE; + /* If it's baseline except for quantizer size, warn the user */ + TRACEMS(cinfo, 0, JTRC_16BIT_TABLES); + } + } + + /* Emit the proper SOF marker */ + if (cinfo->arith_code) { + emit_sof(cinfo, M_SOF9); /* SOF code for arithmetic coding */ + } else { + if (cinfo->progressive_mode) + emit_sof(cinfo, M_SOF2); /* SOF code for progressive Huffman */ + else if (is_baseline) + emit_sof(cinfo, M_SOF0); /* SOF code for baseline implementation */ + else + emit_sof(cinfo, M_SOF1); /* SOF code for non-baseline Huffman file */ + } +} + + +/* + * Write scan header. + * This consists of DHT or DAC markers, optional DRI, and SOS. + * Compressed data will be written following the SOS. + */ + +METHODDEF(void) +write_scan_header (j_compress_ptr cinfo) +{ + my_marker_ptr marker = (my_marker_ptr) cinfo->marker; + int i; + jpeg_component_info *compptr; + + if (cinfo->arith_code) { + /* Emit arith conditioning info. We may have some duplication + * if the file has multiple scans, but it's so small it's hardly + * worth worrying about. + */ + emit_dac(cinfo); + } else { + /* Emit Huffman tables. + * Note that emit_dht() suppresses any duplicate tables. + */ + for (i = 0; i < cinfo->comps_in_scan; i++) { + compptr = cinfo->cur_comp_info[i]; + if (cinfo->progressive_mode) { + /* Progressive mode: only DC or only AC tables are used in one scan */ + if (cinfo->Ss == 0) { + if (cinfo->Ah == 0) /* DC needs no table for refinement scan */ + emit_dht(cinfo, compptr->dc_tbl_no, FALSE); + } else { + emit_dht(cinfo, compptr->ac_tbl_no, TRUE); + } + } else { + /* Sequential mode: need both DC and AC tables */ + emit_dht(cinfo, compptr->dc_tbl_no, FALSE); + emit_dht(cinfo, compptr->ac_tbl_no, TRUE); + } + } + } + + /* Emit DRI if required --- note that DRI value could change for each scan. + * We avoid wasting space with unnecessary DRIs, however. + */ + if (cinfo->restart_interval != marker->last_restart_interval) { + emit_dri(cinfo); + marker->last_restart_interval = cinfo->restart_interval; + } + + emit_sos(cinfo); +} + + +/* + * Write datastream trailer. + */ + +METHODDEF(void) +write_file_trailer (j_compress_ptr cinfo) +{ + emit_marker(cinfo, M_EOI); +} + + +/* + * Write an abbreviated table-specification datastream. + * This consists of SOI, DQT and DHT tables, and EOI. + * Any table that is defined and not marked sent_table = TRUE will be + * emitted. Note that all tables will be marked sent_table = TRUE at exit. + */ + +METHODDEF(void) +write_tables_only (j_compress_ptr cinfo) +{ + int i; + + emit_marker(cinfo, M_SOI); + + for (i = 0; i < NUM_QUANT_TBLS; i++) { + if (cinfo->quant_tbl_ptrs[i] != NULL) + (void) emit_dqt(cinfo, i); + } + + if (! cinfo->arith_code) { + for (i = 0; i < NUM_HUFF_TBLS; i++) { + if (cinfo->dc_huff_tbl_ptrs[i] != NULL) + emit_dht(cinfo, i, FALSE); + if (cinfo->ac_huff_tbl_ptrs[i] != NULL) + emit_dht(cinfo, i, TRUE); + } + } + + emit_marker(cinfo, M_EOI); +} + + +/* + * Initialize the marker writer module. + */ + +GLOBAL(void) +jinit_marker_writer (j_compress_ptr cinfo) +{ + my_marker_ptr marker; + + /* Create the subobject */ + marker = (my_marker_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_marker_writer)); + cinfo->marker = (struct jpeg_marker_writer *) marker; + /* Initialize method pointers */ + marker->pub.write_file_header = write_file_header; + marker->pub.write_frame_header = write_frame_header; + marker->pub.write_scan_header = write_scan_header; + marker->pub.write_file_trailer = write_file_trailer; + marker->pub.write_tables_only = write_tables_only; + marker->pub.write_marker_header = write_marker_header; + marker->pub.write_marker_byte = write_marker_byte; + /* Initialize private state */ + marker->last_restart_interval = 0; +} diff --git a/mod/pub.mod/libjpeg.mod/jcmaster.c b/mod/pub.mod/libjpeg.mod/jcmaster.c new file mode 100644 index 0000000..aab4020 --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jcmaster.c @@ -0,0 +1,590 @@ +/* + * jcmaster.c + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains master control logic for the JPEG compressor. + * These routines are concerned with parameter validation, initial setup, + * and inter-pass control (determining the number of passes and the work + * to be done in each pass). + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* Private state */ + +typedef enum { + main_pass, /* input data, also do first output step */ + huff_opt_pass, /* Huffman code optimization pass */ + output_pass /* data output pass */ +} c_pass_type; + +typedef struct { + struct jpeg_comp_master pub; /* public fields */ + + c_pass_type pass_type; /* the type of the current pass */ + + int pass_number; /* # of passes completed */ + int total_passes; /* total # of passes needed */ + + int scan_number; /* current index in scan_info[] */ +} my_comp_master; + +typedef my_comp_master * my_master_ptr; + + +/* + * Support routines that do various essential calculations. + */ + +LOCAL(void) +initial_setup (j_compress_ptr cinfo) +/* Do computations that are needed before master selection phase */ +{ + int ci; + jpeg_component_info *compptr; + long samplesperrow; + JDIMENSION jd_samplesperrow; + + /* Sanity check on image dimensions */ + if (cinfo->image_height <= 0 || cinfo->image_width <= 0 + || cinfo->num_components <= 0 || cinfo->input_components <= 0) + ERREXIT(cinfo, JERR_EMPTY_IMAGE); + + /* Make sure image isn't bigger than I can handle */ + if ((long) cinfo->image_height > (long) JPEG_MAX_DIMENSION || + (long) cinfo->image_width > (long) JPEG_MAX_DIMENSION) + ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) JPEG_MAX_DIMENSION); + + /* Width of an input scanline must be representable as JDIMENSION. */ + samplesperrow = (long) cinfo->image_width * (long) cinfo->input_components; + jd_samplesperrow = (JDIMENSION) samplesperrow; + if ((long) jd_samplesperrow != samplesperrow) + ERREXIT(cinfo, JERR_WIDTH_OVERFLOW); + + /* For now, precision must match compiled-in value... */ + if (cinfo->data_precision != BITS_IN_JSAMPLE) + ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision); + + /* Check that number of components won't exceed internal array sizes */ + if (cinfo->num_components > MAX_COMPONENTS) + ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components, + MAX_COMPONENTS); + + /* Compute maximum sampling factors; check factor validity */ + cinfo->max_h_samp_factor = 1; + cinfo->max_v_samp_factor = 1; + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + if (compptr->h_samp_factor<=0 || compptr->h_samp_factor>MAX_SAMP_FACTOR || + compptr->v_samp_factor<=0 || compptr->v_samp_factor>MAX_SAMP_FACTOR) + ERREXIT(cinfo, JERR_BAD_SAMPLING); + cinfo->max_h_samp_factor = MAX(cinfo->max_h_samp_factor, + compptr->h_samp_factor); + cinfo->max_v_samp_factor = MAX(cinfo->max_v_samp_factor, + compptr->v_samp_factor); + } + + /* Compute dimensions of components */ + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + /* Fill in the correct component_index value; don't rely on application */ + compptr->component_index = ci; + /* For compression, we never do DCT scaling. */ + compptr->DCT_scaled_size = DCTSIZE; + /* Size in DCT blocks */ + compptr->width_in_blocks = (JDIMENSION) + jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor, + (long) (cinfo->max_h_samp_factor * DCTSIZE)); + compptr->height_in_blocks = (JDIMENSION) + jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor, + (long) (cinfo->max_v_samp_factor * DCTSIZE)); + /* Size in samples */ + compptr->downsampled_width = (JDIMENSION) + jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor, + (long) cinfo->max_h_samp_factor); + compptr->downsampled_height = (JDIMENSION) + jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor, + (long) cinfo->max_v_samp_factor); + /* Mark component needed (this flag isn't actually used for compression) */ + compptr->component_needed = TRUE; + } + + /* Compute number of fully interleaved MCU rows (number of times that + * main controller will call coefficient controller). + */ + cinfo->total_iMCU_rows = (JDIMENSION) + jdiv_round_up((long) cinfo->image_height, + (long) (cinfo->max_v_samp_factor*DCTSIZE)); +} + + +#ifdef C_MULTISCAN_FILES_SUPPORTED + +LOCAL(void) +validate_script (j_compress_ptr cinfo) +/* Verify that the scan script in cinfo->scan_info[] is valid; also + * determine whether it uses progressive JPEG, and set cinfo->progressive_mode. + */ +{ + const jpeg_scan_info * scanptr; + int scanno, ncomps, ci, coefi, thisi; + int Ss, Se, Ah, Al; + boolean component_sent[MAX_COMPONENTS]; +#ifdef C_PROGRESSIVE_SUPPORTED + int * last_bitpos_ptr; + int last_bitpos[MAX_COMPONENTS][DCTSIZE2]; + /* -1 until that coefficient has been seen; then last Al for it */ +#endif + + if (cinfo->num_scans <= 0) + ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, 0); + + /* For sequential JPEG, all scans must have Ss=0, Se=DCTSIZE2-1; + * for progressive JPEG, no scan can have this. + */ + scanptr = cinfo->scan_info; + if (scanptr->Ss != 0 || scanptr->Se != DCTSIZE2-1) { +#ifdef C_PROGRESSIVE_SUPPORTED + cinfo->progressive_mode = TRUE; + last_bitpos_ptr = & last_bitpos[0][0]; + for (ci = 0; ci < cinfo->num_components; ci++) + for (coefi = 0; coefi < DCTSIZE2; coefi++) + *last_bitpos_ptr++ = -1; +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } else { + cinfo->progressive_mode = FALSE; + for (ci = 0; ci < cinfo->num_components; ci++) + component_sent[ci] = FALSE; + } + + for (scanno = 1; scanno <= cinfo->num_scans; scanptr++, scanno++) { + /* Validate component indexes */ + ncomps = scanptr->comps_in_scan; + if (ncomps <= 0 || ncomps > MAX_COMPS_IN_SCAN) + ERREXIT2(cinfo, JERR_COMPONENT_COUNT, ncomps, MAX_COMPS_IN_SCAN); + for (ci = 0; ci < ncomps; ci++) { + thisi = scanptr->component_index[ci]; + if (thisi < 0 || thisi >= cinfo->num_components) + ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, scanno); + /* Components must appear in SOF order within each scan */ + if (ci > 0 && thisi <= scanptr->component_index[ci-1]) + ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, scanno); + } + /* Validate progression parameters */ + Ss = scanptr->Ss; + Se = scanptr->Se; + Ah = scanptr->Ah; + Al = scanptr->Al; + if (cinfo->progressive_mode) { +#ifdef C_PROGRESSIVE_SUPPORTED + /* The JPEG spec simply gives the ranges 0..13 for Ah and Al, but that + * seems wrong: the upper bound ought to depend on data precision. + * Perhaps they really meant 0..N+1 for N-bit precision. + * Here we allow 0..10 for 8-bit data; Al larger than 10 results in + * out-of-range reconstructed DC values during the first DC scan, + * which might cause problems for some decoders. + */ +#if BITS_IN_JSAMPLE == 8 +#define MAX_AH_AL 10 +#else +#define MAX_AH_AL 13 +#endif + if (Ss < 0 || Ss >= DCTSIZE2 || Se < Ss || Se >= DCTSIZE2 || + Ah < 0 || Ah > MAX_AH_AL || Al < 0 || Al > MAX_AH_AL) + ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno); + if (Ss == 0) { + if (Se != 0) /* DC and AC together not OK */ + ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno); + } else { + if (ncomps != 1) /* AC scans must be for only one component */ + ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno); + } + for (ci = 0; ci < ncomps; ci++) { + last_bitpos_ptr = & last_bitpos[scanptr->component_index[ci]][0]; + if (Ss != 0 && last_bitpos_ptr[0] < 0) /* AC without prior DC scan */ + ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno); + for (coefi = Ss; coefi <= Se; coefi++) { + if (last_bitpos_ptr[coefi] < 0) { + /* first scan of this coefficient */ + if (Ah != 0) + ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno); + } else { + /* not first scan */ + if (Ah != last_bitpos_ptr[coefi] || Al != Ah-1) + ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno); + } + last_bitpos_ptr[coefi] = Al; + } + } +#endif + } else { + /* For sequential JPEG, all progression parameters must be these: */ + if (Ss != 0 || Se != DCTSIZE2-1 || Ah != 0 || Al != 0) + ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno); + /* Make sure components are not sent twice */ + for (ci = 0; ci < ncomps; ci++) { + thisi = scanptr->component_index[ci]; + if (component_sent[thisi]) + ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, scanno); + component_sent[thisi] = TRUE; + } + } + } + + /* Now verify that everything got sent. */ + if (cinfo->progressive_mode) { +#ifdef C_PROGRESSIVE_SUPPORTED + /* For progressive mode, we only check that at least some DC data + * got sent for each component; the spec does not require that all bits + * of all coefficients be transmitted. Would it be wiser to enforce + * transmission of all coefficient bits?? + */ + for (ci = 0; ci < cinfo->num_components; ci++) { + if (last_bitpos[ci][0] < 0) + ERREXIT(cinfo, JERR_MISSING_DATA); + } +#endif + } else { + for (ci = 0; ci < cinfo->num_components; ci++) { + if (! component_sent[ci]) + ERREXIT(cinfo, JERR_MISSING_DATA); + } + } +} + +#endif /* C_MULTISCAN_FILES_SUPPORTED */ + + +LOCAL(void) +select_scan_parameters (j_compress_ptr cinfo) +/* Set up the scan parameters for the current scan */ +{ + int ci; + +#ifdef C_MULTISCAN_FILES_SUPPORTED + if (cinfo->scan_info != NULL) { + /* Prepare for current scan --- the script is already validated */ + my_master_ptr master = (my_master_ptr) cinfo->master; + const jpeg_scan_info * scanptr = cinfo->scan_info + master->scan_number; + + cinfo->comps_in_scan = scanptr->comps_in_scan; + for (ci = 0; ci < scanptr->comps_in_scan; ci++) { + cinfo->cur_comp_info[ci] = + &cinfo->comp_info[scanptr->component_index[ci]]; + } + cinfo->Ss = scanptr->Ss; + cinfo->Se = scanptr->Se; + cinfo->Ah = scanptr->Ah; + cinfo->Al = scanptr->Al; + } + else +#endif + { + /* Prepare for single sequential-JPEG scan containing all components */ + if (cinfo->num_components > MAX_COMPS_IN_SCAN) + ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components, + MAX_COMPS_IN_SCAN); + cinfo->comps_in_scan = cinfo->num_components; + for (ci = 0; ci < cinfo->num_components; ci++) { + cinfo->cur_comp_info[ci] = &cinfo->comp_info[ci]; + } + cinfo->Ss = 0; + cinfo->Se = DCTSIZE2-1; + cinfo->Ah = 0; + cinfo->Al = 0; + } +} + + +LOCAL(void) +per_scan_setup (j_compress_ptr cinfo) +/* Do computations that are needed before processing a JPEG scan */ +/* cinfo->comps_in_scan and cinfo->cur_comp_info[] are already set */ +{ + int ci, mcublks, tmp; + jpeg_component_info *compptr; + + if (cinfo->comps_in_scan == 1) { + + /* Noninterleaved (single-component) scan */ + compptr = cinfo->cur_comp_info[0]; + + /* Overall image size in MCUs */ + cinfo->MCUs_per_row = compptr->width_in_blocks; + cinfo->MCU_rows_in_scan = compptr->height_in_blocks; + + /* For noninterleaved scan, always one block per MCU */ + compptr->MCU_width = 1; + compptr->MCU_height = 1; + compptr->MCU_blocks = 1; + compptr->MCU_sample_width = DCTSIZE; + compptr->last_col_width = 1; + /* For noninterleaved scans, it is convenient to define last_row_height + * as the number of block rows present in the last iMCU row. + */ + tmp = (int) (compptr->height_in_blocks % compptr->v_samp_factor); + if (tmp == 0) tmp = compptr->v_samp_factor; + compptr->last_row_height = tmp; + + /* Prepare array describing MCU composition */ + cinfo->blocks_in_MCU = 1; + cinfo->MCU_membership[0] = 0; + + } else { + + /* Interleaved (multi-component) scan */ + if (cinfo->comps_in_scan <= 0 || cinfo->comps_in_scan > MAX_COMPS_IN_SCAN) + ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->comps_in_scan, + MAX_COMPS_IN_SCAN); + + /* Overall image size in MCUs */ + cinfo->MCUs_per_row = (JDIMENSION) + jdiv_round_up((long) cinfo->image_width, + (long) (cinfo->max_h_samp_factor*DCTSIZE)); + cinfo->MCU_rows_in_scan = (JDIMENSION) + jdiv_round_up((long) cinfo->image_height, + (long) (cinfo->max_v_samp_factor*DCTSIZE)); + + cinfo->blocks_in_MCU = 0; + + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + /* Sampling factors give # of blocks of component in each MCU */ + compptr->MCU_width = compptr->h_samp_factor; + compptr->MCU_height = compptr->v_samp_factor; + compptr->MCU_blocks = compptr->MCU_width * compptr->MCU_height; + compptr->MCU_sample_width = compptr->MCU_width * DCTSIZE; + /* Figure number of non-dummy blocks in last MCU column & row */ + tmp = (int) (compptr->width_in_blocks % compptr->MCU_width); + if (tmp == 0) tmp = compptr->MCU_width; + compptr->last_col_width = tmp; + tmp = (int) (compptr->height_in_blocks % compptr->MCU_height); + if (tmp == 0) tmp = compptr->MCU_height; + compptr->last_row_height = tmp; + /* Prepare array describing MCU composition */ + mcublks = compptr->MCU_blocks; + if (cinfo->blocks_in_MCU + mcublks > C_MAX_BLOCKS_IN_MCU) + ERREXIT(cinfo, JERR_BAD_MCU_SIZE); + while (mcublks-- > 0) { + cinfo->MCU_membership[cinfo->blocks_in_MCU++] = ci; + } + } + + } + + /* Convert restart specified in rows to actual MCU count. */ + /* Note that count must fit in 16 bits, so we provide limiting. */ + if (cinfo->restart_in_rows > 0) { + long nominal = (long) cinfo->restart_in_rows * (long) cinfo->MCUs_per_row; + cinfo->restart_interval = (unsigned int) MIN(nominal, 65535L); + } +} + + +/* + * Per-pass setup. + * This is called at the beginning of each pass. We determine which modules + * will be active during this pass and give them appropriate start_pass calls. + * We also set is_last_pass to indicate whether any more passes will be + * required. + */ + +METHODDEF(void) +prepare_for_pass (j_compress_ptr cinfo) +{ + my_master_ptr master = (my_master_ptr) cinfo->master; + + switch (master->pass_type) { + case main_pass: + /* Initial pass: will collect input data, and do either Huffman + * optimization or data output for the first scan. + */ + select_scan_parameters(cinfo); + per_scan_setup(cinfo); + if (! cinfo->raw_data_in) { + (*cinfo->cconvert->start_pass) (cinfo); + (*cinfo->downsample->start_pass) (cinfo); + (*cinfo->prep->start_pass) (cinfo, JBUF_PASS_THRU); + } + (*cinfo->fdct->start_pass) (cinfo); + (*cinfo->entropy->start_pass) (cinfo, cinfo->optimize_coding); + (*cinfo->coef->start_pass) (cinfo, + (master->total_passes > 1 ? + JBUF_SAVE_AND_PASS : JBUF_PASS_THRU)); + (*cinfo->main->start_pass) (cinfo, JBUF_PASS_THRU); + if (cinfo->optimize_coding) { + /* No immediate data output; postpone writing frame/scan headers */ + master->pub.call_pass_startup = FALSE; + } else { + /* Will write frame/scan headers at first jpeg_write_scanlines call */ + master->pub.call_pass_startup = TRUE; + } + break; +#ifdef ENTROPY_OPT_SUPPORTED + case huff_opt_pass: + /* Do Huffman optimization for a scan after the first one. */ + select_scan_parameters(cinfo); + per_scan_setup(cinfo); + if (cinfo->Ss != 0 || cinfo->Ah == 0 || cinfo->arith_code) { + (*cinfo->entropy->start_pass) (cinfo, TRUE); + (*cinfo->coef->start_pass) (cinfo, JBUF_CRANK_DEST); + master->pub.call_pass_startup = FALSE; + break; + } + /* Special case: Huffman DC refinement scans need no Huffman table + * and therefore we can skip the optimization pass for them. + */ + master->pass_type = output_pass; + master->pass_number++; + /*FALLTHROUGH*/ +#endif + case output_pass: + /* Do a data-output pass. */ + /* We need not repeat per-scan setup if prior optimization pass did it. */ + if (! cinfo->optimize_coding) { + select_scan_parameters(cinfo); + per_scan_setup(cinfo); + } + (*cinfo->entropy->start_pass) (cinfo, FALSE); + (*cinfo->coef->start_pass) (cinfo, JBUF_CRANK_DEST); + /* We emit frame/scan headers now */ + if (master->scan_number == 0) + (*cinfo->marker->write_frame_header) (cinfo); + (*cinfo->marker->write_scan_header) (cinfo); + master->pub.call_pass_startup = FALSE; + break; + default: + ERREXIT(cinfo, JERR_NOT_COMPILED); + } + + master->pub.is_last_pass = (master->pass_number == master->total_passes-1); + + /* Set up progress monitor's pass info if present */ + if (cinfo->progress != NULL) { + cinfo->progress->completed_passes = master->pass_number; + cinfo->progress->total_passes = master->total_passes; + } +} + + +/* + * Special start-of-pass hook. + * This is called by jpeg_write_scanlines if call_pass_startup is TRUE. + * In single-pass processing, we need this hook because we don't want to + * write frame/scan headers during jpeg_start_compress; we want to let the + * application write COM markers etc. between jpeg_start_compress and the + * jpeg_write_scanlines loop. + * In multi-pass processing, this routine is not used. + */ + +METHODDEF(void) +pass_startup (j_compress_ptr cinfo) +{ + cinfo->master->call_pass_startup = FALSE; /* reset flag so call only once */ + + (*cinfo->marker->write_frame_header) (cinfo); + (*cinfo->marker->write_scan_header) (cinfo); +} + + +/* + * Finish up at end of pass. + */ + +METHODDEF(void) +finish_pass_master (j_compress_ptr cinfo) +{ + my_master_ptr master = (my_master_ptr) cinfo->master; + + /* The entropy coder always needs an end-of-pass call, + * either to analyze statistics or to flush its output buffer. + */ + (*cinfo->entropy->finish_pass) (cinfo); + + /* Update state for next pass */ + switch (master->pass_type) { + case main_pass: + /* next pass is either output of scan 0 (after optimization) + * or output of scan 1 (if no optimization). + */ + master->pass_type = output_pass; + if (! cinfo->optimize_coding) + master->scan_number++; + break; + case huff_opt_pass: + /* next pass is always output of current scan */ + master->pass_type = output_pass; + break; + case output_pass: + /* next pass is either optimization or output of next scan */ + if (cinfo->optimize_coding) + master->pass_type = huff_opt_pass; + master->scan_number++; + break; + } + + master->pass_number++; +} + + +/* + * Initialize master compression control. + */ + +GLOBAL(void) +jinit_c_master_control (j_compress_ptr cinfo, boolean transcode_only) +{ + my_master_ptr master; + + master = (my_master_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_comp_master)); + cinfo->master = (struct jpeg_comp_master *) master; + master->pub.prepare_for_pass = prepare_for_pass; + master->pub.pass_startup = pass_startup; + master->pub.finish_pass = finish_pass_master; + master->pub.is_last_pass = FALSE; + + /* Validate parameters, determine derived values */ + initial_setup(cinfo); + + if (cinfo->scan_info != NULL) { +#ifdef C_MULTISCAN_FILES_SUPPORTED + validate_script(cinfo); +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } else { + cinfo->progressive_mode = FALSE; + cinfo->num_scans = 1; + } + + if (cinfo->progressive_mode) /* TEMPORARY HACK ??? */ + cinfo->optimize_coding = TRUE; /* assume default tables no good for progressive mode */ + + /* Initialize my private state */ + if (transcode_only) { + /* no main pass in transcoding */ + if (cinfo->optimize_coding) + master->pass_type = huff_opt_pass; + else + master->pass_type = output_pass; + } else { + /* for normal compression, first pass is always this type: */ + master->pass_type = main_pass; + } + master->scan_number = 0; + master->pass_number = 0; + if (cinfo->optimize_coding) + master->total_passes = cinfo->num_scans * 2; + else + master->total_passes = cinfo->num_scans; +} diff --git a/mod/pub.mod/libjpeg.mod/jcomapi.c b/mod/pub.mod/libjpeg.mod/jcomapi.c new file mode 100644 index 0000000..9b1fa75 --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jcomapi.c @@ -0,0 +1,106 @@ +/* + * jcomapi.c + * + * Copyright (C) 1994-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains application interface routines that are used for both + * compression and decompression. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* + * Abort processing of a JPEG compression or decompression operation, + * but don't destroy the object itself. + * + * For this, we merely clean up all the nonpermanent memory pools. + * Note that temp files (virtual arrays) are not allowed to belong to + * the permanent pool, so we will be able to close all temp files here. + * Closing a data source or destination, if necessary, is the application's + * responsibility. + */ + +GLOBAL(void) +jpeg_abort (j_common_ptr cinfo) +{ + int pool; + + /* Do nothing if called on a not-initialized or destroyed JPEG object. */ + if (cinfo->mem == NULL) + return; + + /* Releasing pools in reverse order might help avoid fragmentation + * with some (brain-damaged) malloc libraries. + */ + for (pool = JPOOL_NUMPOOLS-1; pool > JPOOL_PERMANENT; pool--) { + (*cinfo->mem->free_pool) (cinfo, pool); + } + + /* Reset overall state for possible reuse of object */ + if (cinfo->is_decompressor) { + cinfo->global_state = DSTATE_START; + /* Try to keep application from accessing now-deleted marker list. + * A bit kludgy to do it here, but this is the most central place. + */ + ((j_decompress_ptr) cinfo)->marker_list = NULL; + } else { + cinfo->global_state = CSTATE_START; + } +} + + +/* + * Destruction of a JPEG object. + * + * Everything gets deallocated except the master jpeg_compress_struct itself + * and the error manager struct. Both of these are supplied by the application + * and must be freed, if necessary, by the application. (Often they are on + * the stack and so don't need to be freed anyway.) + * Closing a data source or destination, if necessary, is the application's + * responsibility. + */ + +GLOBAL(void) +jpeg_destroy (j_common_ptr cinfo) +{ + /* We need only tell the memory manager to release everything. */ + /* NB: mem pointer is NULL if memory mgr failed to initialize. */ + if (cinfo->mem != NULL) + (*cinfo->mem->self_destruct) (cinfo); + cinfo->mem = NULL; /* be safe if jpeg_destroy is called twice */ + cinfo->global_state = 0; /* mark it destroyed */ +} + + +/* + * Convenience routines for allocating quantization and Huffman tables. + * (Would jutils.c be a more reasonable place to put these?) + */ + +GLOBAL(JQUANT_TBL *) +jpeg_alloc_quant_table (j_common_ptr cinfo) +{ + JQUANT_TBL *tbl; + + tbl = (JQUANT_TBL *) + (*cinfo->mem->alloc_small) (cinfo, JPOOL_PERMANENT, SIZEOF(JQUANT_TBL)); + tbl->sent_table = FALSE; /* make sure this is false in any new table */ + return tbl; +} + + +GLOBAL(JHUFF_TBL *) +jpeg_alloc_huff_table (j_common_ptr cinfo) +{ + JHUFF_TBL *tbl; + + tbl = (JHUFF_TBL *) + (*cinfo->mem->alloc_small) (cinfo, JPOOL_PERMANENT, SIZEOF(JHUFF_TBL)); + tbl->sent_table = FALSE; /* make sure this is false in any new table */ + return tbl; +} diff --git a/mod/pub.mod/libjpeg.mod/jcparam.c b/mod/pub.mod/libjpeg.mod/jcparam.c new file mode 100644 index 0000000..6fc48f5 --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jcparam.c @@ -0,0 +1,610 @@ +/* + * jcparam.c + * + * Copyright (C) 1991-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains optional default-setting code for the JPEG compressor. + * Applications do not have to use this file, but those that don't use it + * must know a lot more about the innards of the JPEG code. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* + * Quantization table setup routines + */ + +GLOBAL(void) +jpeg_add_quant_table (j_compress_ptr cinfo, int which_tbl, + const unsigned int *basic_table, + int scale_factor, boolean force_baseline) +/* Define a quantization table equal to the basic_table times + * a scale factor (given as a percentage). + * If force_baseline is TRUE, the computed quantization table entries + * are limited to 1..255 for JPEG baseline compatibility. + */ +{ + JQUANT_TBL ** qtblptr; + int i; + long temp; + + /* Safety check to ensure start_compress not called yet. */ + if (cinfo->global_state != CSTATE_START) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + + if (which_tbl < 0 || which_tbl >= NUM_QUANT_TBLS) + ERREXIT1(cinfo, JERR_DQT_INDEX, which_tbl); + + qtblptr = & cinfo->quant_tbl_ptrs[which_tbl]; + + if (*qtblptr == NULL) + *qtblptr = jpeg_alloc_quant_table((j_common_ptr) cinfo); + + for (i = 0; i < DCTSIZE2; i++) { + temp = ((long) basic_table[i] * scale_factor + 50L) / 100L; + /* limit the values to the valid range */ + if (temp <= 0L) temp = 1L; + if (temp > 32767L) temp = 32767L; /* max quantizer needed for 12 bits */ + if (force_baseline && temp > 255L) + temp = 255L; /* limit to baseline range if requested */ + (*qtblptr)->quantval[i] = (UINT16) temp; + } + + /* Initialize sent_table FALSE so table will be written to JPEG file. */ + (*qtblptr)->sent_table = FALSE; +} + + +GLOBAL(void) +jpeg_set_linear_quality (j_compress_ptr cinfo, int scale_factor, + boolean force_baseline) +/* Set or change the 'quality' (quantization) setting, using default tables + * and a straight percentage-scaling quality scale. In most cases it's better + * to use jpeg_set_quality (below); this entry point is provided for + * applications that insist on a linear percentage scaling. + */ +{ + /* These are the sample quantization tables given in JPEG spec section K.1. + * The spec says that the values given produce "good" quality, and + * when divided by 2, "very good" quality. + */ + static const unsigned int std_luminance_quant_tbl[DCTSIZE2] = { + 16, 11, 10, 16, 24, 40, 51, 61, + 12, 12, 14, 19, 26, 58, 60, 55, + 14, 13, 16, 24, 40, 57, 69, 56, + 14, 17, 22, 29, 51, 87, 80, 62, + 18, 22, 37, 56, 68, 109, 103, 77, + 24, 35, 55, 64, 81, 104, 113, 92, + 49, 64, 78, 87, 103, 121, 120, 101, + 72, 92, 95, 98, 112, 100, 103, 99 + }; + static const unsigned int std_chrominance_quant_tbl[DCTSIZE2] = { + 17, 18, 24, 47, 99, 99, 99, 99, + 18, 21, 26, 66, 99, 99, 99, 99, + 24, 26, 56, 99, 99, 99, 99, 99, + 47, 66, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99 + }; + + /* Set up two quantization tables using the specified scaling */ + jpeg_add_quant_table(cinfo, 0, std_luminance_quant_tbl, + scale_factor, force_baseline); + jpeg_add_quant_table(cinfo, 1, std_chrominance_quant_tbl, + scale_factor, force_baseline); +} + + +GLOBAL(int) +jpeg_quality_scaling (int quality) +/* Convert a user-specified quality rating to a percentage scaling factor + * for an underlying quantization table, using our recommended scaling curve. + * The input 'quality' factor should be 0 (terrible) to 100 (very good). + */ +{ + /* Safety limit on quality factor. Convert 0 to 1 to avoid zero divide. */ + if (quality <= 0) quality = 1; + if (quality > 100) quality = 100; + + /* The basic table is used as-is (scaling 100) for a quality of 50. + * Qualities 50..100 are converted to scaling percentage 200 - 2*Q; + * note that at Q=100 the scaling is 0, which will cause jpeg_add_quant_table + * to make all the table entries 1 (hence, minimum quantization loss). + * Qualities 1..50 are converted to scaling percentage 5000/Q. + */ + if (quality < 50) + quality = 5000 / quality; + else + quality = 200 - quality*2; + + return quality; +} + + +GLOBAL(void) +jpeg_set_quality (j_compress_ptr cinfo, int quality, boolean force_baseline) +/* Set or change the 'quality' (quantization) setting, using default tables. + * This is the standard quality-adjusting entry point for typical user + * interfaces; only those who want detailed control over quantization tables + * would use the preceding three routines directly. + */ +{ + /* Convert user 0-100 rating to percentage scaling */ + quality = jpeg_quality_scaling(quality); + + /* Set up standard quality tables */ + jpeg_set_linear_quality(cinfo, quality, force_baseline); +} + + +/* + * Huffman table setup routines + */ + +LOCAL(void) +add_huff_table (j_compress_ptr cinfo, + JHUFF_TBL **htblptr, const UINT8 *bits, const UINT8 *val) +/* Define a Huffman table */ +{ + int nsymbols, len; + + if (*htblptr == NULL) + *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo); + + /* Copy the number-of-symbols-of-each-code-length counts */ + MEMCOPY((*htblptr)->bits, bits, SIZEOF((*htblptr)->bits)); + + /* Validate the counts. We do this here mainly so we can copy the right + * number of symbols from the val[] array, without risking marching off + * the end of memory. jchuff.c will do a more thorough test later. + */ + nsymbols = 0; + for (len = 1; len <= 16; len++) + nsymbols += bits[len]; + if (nsymbols < 1 || nsymbols > 256) + ERREXIT(cinfo, JERR_BAD_HUFF_TABLE); + + MEMCOPY((*htblptr)->huffval, val, nsymbols * SIZEOF(UINT8)); + + /* Initialize sent_table FALSE so table will be written to JPEG file. */ + (*htblptr)->sent_table = FALSE; +} + + +LOCAL(void) +std_huff_tables (j_compress_ptr cinfo) +/* Set up the standard Huffman tables (cf. JPEG standard section K.3) */ +/* IMPORTANT: these are only valid for 8-bit data precision! */ +{ + static const UINT8 bits_dc_luminance[17] = + { /* 0-base */ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 }; + static const UINT8 val_dc_luminance[] = + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; + + static const UINT8 bits_dc_chrominance[17] = + { /* 0-base */ 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 }; + static const UINT8 val_dc_chrominance[] = + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; + + static const UINT8 bits_ac_luminance[17] = + { /* 0-base */ 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d }; + static const UINT8 val_ac_luminance[] = + { 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, + 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, + 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, + 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, + 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, + 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, + 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, + 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, + 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, + 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, + 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, + 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, + 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, + 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, + 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, + 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, + 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, + 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, + 0xf9, 0xfa }; + + static const UINT8 bits_ac_chrominance[17] = + { /* 0-base */ 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 }; + static const UINT8 val_ac_chrominance[] = + { 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, + 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, + 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, + 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, + 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, + 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, + 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, + 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, + 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, + 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, + 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, + 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, + 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, + 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, + 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, + 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, + 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, + 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, + 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, + 0xf9, 0xfa }; + + add_huff_table(cinfo, &cinfo->dc_huff_tbl_ptrs[0], + bits_dc_luminance, val_dc_luminance); + add_huff_table(cinfo, &cinfo->ac_huff_tbl_ptrs[0], + bits_ac_luminance, val_ac_luminance); + add_huff_table(cinfo, &cinfo->dc_huff_tbl_ptrs[1], + bits_dc_chrominance, val_dc_chrominance); + add_huff_table(cinfo, &cinfo->ac_huff_tbl_ptrs[1], + bits_ac_chrominance, val_ac_chrominance); +} + + +/* + * Default parameter setup for compression. + * + * Applications that don't choose to use this routine must do their + * own setup of all these parameters. Alternately, you can call this + * to establish defaults and then alter parameters selectively. This + * is the recommended approach since, if we add any new parameters, + * your code will still work (they'll be set to reasonable defaults). + */ + +GLOBAL(void) +jpeg_set_defaults (j_compress_ptr cinfo) +{ + int i; + + /* Safety check to ensure start_compress not called yet. */ + if (cinfo->global_state != CSTATE_START) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + + /* Allocate comp_info array large enough for maximum component count. + * Array is made permanent in case application wants to compress + * multiple images at same param settings. + */ + if (cinfo->comp_info == NULL) + cinfo->comp_info = (jpeg_component_info *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, + MAX_COMPONENTS * SIZEOF(jpeg_component_info)); + + /* Initialize everything not dependent on the color space */ + + cinfo->data_precision = BITS_IN_JSAMPLE; + /* Set up two quantization tables using default quality of 75 */ + jpeg_set_quality(cinfo, 75, TRUE); + /* Set up two Huffman tables */ + std_huff_tables(cinfo); + + /* Initialize default arithmetic coding conditioning */ + for (i = 0; i < NUM_ARITH_TBLS; i++) { + cinfo->arith_dc_L[i] = 0; + cinfo->arith_dc_U[i] = 1; + cinfo->arith_ac_K[i] = 5; + } + + /* Default is no multiple-scan output */ + cinfo->scan_info = NULL; + cinfo->num_scans = 0; + + /* Expect normal source image, not raw downsampled data */ + cinfo->raw_data_in = FALSE; + + /* Use Huffman coding, not arithmetic coding, by default */ + cinfo->arith_code = FALSE; + + /* By default, don't do extra passes to optimize entropy coding */ + cinfo->optimize_coding = FALSE; + /* The standard Huffman tables are only valid for 8-bit data precision. + * If the precision is higher, force optimization on so that usable + * tables will be computed. This test can be removed if default tables + * are supplied that are valid for the desired precision. + */ + if (cinfo->data_precision > 8) + cinfo->optimize_coding = TRUE; + + /* By default, use the simpler non-cosited sampling alignment */ + cinfo->CCIR601_sampling = FALSE; + + /* No input smoothing */ + cinfo->smoothing_factor = 0; + + /* DCT algorithm preference */ + cinfo->dct_method = JDCT_DEFAULT; + + /* No restart markers */ + cinfo->restart_interval = 0; + cinfo->restart_in_rows = 0; + + /* Fill in default JFIF marker parameters. Note that whether the marker + * will actually be written is determined by jpeg_set_colorspace. + * + * By default, the library emits JFIF version code 1.01. + * An application that wants to emit JFIF 1.02 extension markers should set + * JFIF_minor_version to 2. We could probably get away with just defaulting + * to 1.02, but there may still be some decoders in use that will complain + * about that; saying 1.01 should minimize compatibility problems. + */ + cinfo->JFIF_major_version = 1; /* Default JFIF version = 1.01 */ + cinfo->JFIF_minor_version = 1; + cinfo->density_unit = 0; /* Pixel size is unknown by default */ + cinfo->X_density = 1; /* Pixel aspect ratio is square by default */ + cinfo->Y_density = 1; + + /* Choose JPEG colorspace based on input space, set defaults accordingly */ + + jpeg_default_colorspace(cinfo); +} + + +/* + * Select an appropriate JPEG colorspace for in_color_space. + */ + +GLOBAL(void) +jpeg_default_colorspace (j_compress_ptr cinfo) +{ + switch (cinfo->in_color_space) { + case JCS_GRAYSCALE: + jpeg_set_colorspace(cinfo, JCS_GRAYSCALE); + break; + case JCS_RGB: + jpeg_set_colorspace(cinfo, JCS_YCbCr); + break; + case JCS_YCbCr: + jpeg_set_colorspace(cinfo, JCS_YCbCr); + break; + case JCS_CMYK: + jpeg_set_colorspace(cinfo, JCS_CMYK); /* By default, no translation */ + break; + case JCS_YCCK: + jpeg_set_colorspace(cinfo, JCS_YCCK); + break; + case JCS_UNKNOWN: + jpeg_set_colorspace(cinfo, JCS_UNKNOWN); + break; + default: + ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE); + } +} + + +/* + * Set the JPEG colorspace, and choose colorspace-dependent default values. + */ + +GLOBAL(void) +jpeg_set_colorspace (j_compress_ptr cinfo, J_COLOR_SPACE colorspace) +{ + jpeg_component_info * compptr; + int ci; + +#define SET_COMP(index,id,hsamp,vsamp,quant,dctbl,actbl) \ + (compptr = &cinfo->comp_info[index], \ + compptr->component_id = (id), \ + compptr->h_samp_factor = (hsamp), \ + compptr->v_samp_factor = (vsamp), \ + compptr->quant_tbl_no = (quant), \ + compptr->dc_tbl_no = (dctbl), \ + compptr->ac_tbl_no = (actbl) ) + + /* Safety check to ensure start_compress not called yet. */ + if (cinfo->global_state != CSTATE_START) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + + /* For all colorspaces, we use Q and Huff tables 0 for luminance components, + * tables 1 for chrominance components. + */ + + cinfo->jpeg_color_space = colorspace; + + cinfo->write_JFIF_header = FALSE; /* No marker for non-JFIF colorspaces */ + cinfo->write_Adobe_marker = FALSE; /* write no Adobe marker by default */ + + switch (colorspace) { + case JCS_GRAYSCALE: + cinfo->write_JFIF_header = TRUE; /* Write a JFIF marker */ + cinfo->num_components = 1; + /* JFIF specifies component ID 1 */ + SET_COMP(0, 1, 1,1, 0, 0,0); + break; + case JCS_RGB: + cinfo->write_Adobe_marker = TRUE; /* write Adobe marker to flag RGB */ + cinfo->num_components = 3; + SET_COMP(0, 0x52 /* 'R' */, 1,1, 0, 0,0); + SET_COMP(1, 0x47 /* 'G' */, 1,1, 0, 0,0); + SET_COMP(2, 0x42 /* 'B' */, 1,1, 0, 0,0); + break; + case JCS_YCbCr: + cinfo->write_JFIF_header = TRUE; /* Write a JFIF marker */ + cinfo->num_components = 3; + /* JFIF specifies component IDs 1,2,3 */ + /* We default to 2x2 subsamples of chrominance */ + SET_COMP(0, 1, 2,2, 0, 0,0); + SET_COMP(1, 2, 1,1, 1, 1,1); + SET_COMP(2, 3, 1,1, 1, 1,1); + break; + case JCS_CMYK: + cinfo->write_Adobe_marker = TRUE; /* write Adobe marker to flag CMYK */ + cinfo->num_components = 4; + SET_COMP(0, 0x43 /* 'C' */, 1,1, 0, 0,0); + SET_COMP(1, 0x4D /* 'M' */, 1,1, 0, 0,0); + SET_COMP(2, 0x59 /* 'Y' */, 1,1, 0, 0,0); + SET_COMP(3, 0x4B /* 'K' */, 1,1, 0, 0,0); + break; + case JCS_YCCK: + cinfo->write_Adobe_marker = TRUE; /* write Adobe marker to flag YCCK */ + cinfo->num_components = 4; + SET_COMP(0, 1, 2,2, 0, 0,0); + SET_COMP(1, 2, 1,1, 1, 1,1); + SET_COMP(2, 3, 1,1, 1, 1,1); + SET_COMP(3, 4, 2,2, 0, 0,0); + break; + case JCS_UNKNOWN: + cinfo->num_components = cinfo->input_components; + if (cinfo->num_components < 1 || cinfo->num_components > MAX_COMPONENTS) + ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components, + MAX_COMPONENTS); + for (ci = 0; ci < cinfo->num_components; ci++) { + SET_COMP(ci, ci, 1,1, 0, 0,0); + } + break; + default: + ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); + } +} + + +#ifdef C_PROGRESSIVE_SUPPORTED + +LOCAL(jpeg_scan_info *) +fill_a_scan (jpeg_scan_info * scanptr, int ci, + int Ss, int Se, int Ah, int Al) +/* Support routine: generate one scan for specified component */ +{ + scanptr->comps_in_scan = 1; + scanptr->component_index[0] = ci; + scanptr->Ss = Ss; + scanptr->Se = Se; + scanptr->Ah = Ah; + scanptr->Al = Al; + scanptr++; + return scanptr; +} + +LOCAL(jpeg_scan_info *) +fill_scans (jpeg_scan_info * scanptr, int ncomps, + int Ss, int Se, int Ah, int Al) +/* Support routine: generate one scan for each component */ +{ + int ci; + + for (ci = 0; ci < ncomps; ci++) { + scanptr->comps_in_scan = 1; + scanptr->component_index[0] = ci; + scanptr->Ss = Ss; + scanptr->Se = Se; + scanptr->Ah = Ah; + scanptr->Al = Al; + scanptr++; + } + return scanptr; +} + +LOCAL(jpeg_scan_info *) +fill_dc_scans (jpeg_scan_info * scanptr, int ncomps, int Ah, int Al) +/* Support routine: generate interleaved DC scan if possible, else N scans */ +{ + int ci; + + if (ncomps <= MAX_COMPS_IN_SCAN) { + /* Single interleaved DC scan */ + scanptr->comps_in_scan = ncomps; + for (ci = 0; ci < ncomps; ci++) + scanptr->component_index[ci] = ci; + scanptr->Ss = scanptr->Se = 0; + scanptr->Ah = Ah; + scanptr->Al = Al; + scanptr++; + } else { + /* Noninterleaved DC scan for each component */ + scanptr = fill_scans(scanptr, ncomps, 0, 0, Ah, Al); + } + return scanptr; +} + + +/* + * Create a recommended progressive-JPEG script. + * cinfo->num_components and cinfo->jpeg_color_space must be correct. + */ + +GLOBAL(void) +jpeg_simple_progression (j_compress_ptr cinfo) +{ + int ncomps = cinfo->num_components; + int nscans; + jpeg_scan_info * scanptr; + + /* Safety check to ensure start_compress not called yet. */ + if (cinfo->global_state != CSTATE_START) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + + /* Figure space needed for script. Calculation must match code below! */ + if (ncomps == 3 && cinfo->jpeg_color_space == JCS_YCbCr) { + /* Custom script for YCbCr color images. */ + nscans = 10; + } else { + /* All-purpose script for other color spaces. */ + if (ncomps > MAX_COMPS_IN_SCAN) + nscans = 6 * ncomps; /* 2 DC + 4 AC scans per component */ + else + nscans = 2 + 4 * ncomps; /* 2 DC scans; 4 AC scans per component */ + } + + /* Allocate space for script. + * We need to put it in the permanent pool in case the application performs + * multiple compressions without changing the settings. To avoid a memory + * leak if jpeg_simple_progression is called repeatedly for the same JPEG + * object, we try to re-use previously allocated space, and we allocate + * enough space to handle YCbCr even if initially asked for grayscale. + */ + if (cinfo->script_space == NULL || cinfo->script_space_size < nscans) { + cinfo->script_space_size = MAX(nscans, 10); + cinfo->script_space = (jpeg_scan_info *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, + cinfo->script_space_size * SIZEOF(jpeg_scan_info)); + } + scanptr = cinfo->script_space; + cinfo->scan_info = scanptr; + cinfo->num_scans = nscans; + + if (ncomps == 3 && cinfo->jpeg_color_space == JCS_YCbCr) { + /* Custom script for YCbCr color images. */ + /* Initial DC scan */ + scanptr = fill_dc_scans(scanptr, ncomps, 0, 1); + /* Initial AC scan: get some luma data out in a hurry */ + scanptr = fill_a_scan(scanptr, 0, 1, 5, 0, 2); + /* Chroma data is too small to be worth expending many scans on */ + scanptr = fill_a_scan(scanptr, 2, 1, 63, 0, 1); + scanptr = fill_a_scan(scanptr, 1, 1, 63, 0, 1); + /* Complete spectral selection for luma AC */ + scanptr = fill_a_scan(scanptr, 0, 6, 63, 0, 2); + /* Refine next bit of luma AC */ + scanptr = fill_a_scan(scanptr, 0, 1, 63, 2, 1); + /* Finish DC successive approximation */ + scanptr = fill_dc_scans(scanptr, ncomps, 1, 0); + /* Finish AC successive approximation */ + scanptr = fill_a_scan(scanptr, 2, 1, 63, 1, 0); + scanptr = fill_a_scan(scanptr, 1, 1, 63, 1, 0); + /* Luma bottom bit comes last since it's usually largest scan */ + scanptr = fill_a_scan(scanptr, 0, 1, 63, 1, 0); + } else { + /* All-purpose script for other color spaces. */ + /* Successive approximation first pass */ + scanptr = fill_dc_scans(scanptr, ncomps, 0, 1); + scanptr = fill_scans(scanptr, ncomps, 1, 5, 0, 2); + scanptr = fill_scans(scanptr, ncomps, 6, 63, 0, 2); + /* Successive approximation second pass */ + scanptr = fill_scans(scanptr, ncomps, 1, 63, 2, 1); + /* Successive approximation final pass */ + scanptr = fill_dc_scans(scanptr, ncomps, 1, 0); + scanptr = fill_scans(scanptr, ncomps, 1, 63, 1, 0); + } +} + +#endif /* C_PROGRESSIVE_SUPPORTED */ diff --git a/mod/pub.mod/libjpeg.mod/jcphuff.c b/mod/pub.mod/libjpeg.mod/jcphuff.c new file mode 100644 index 0000000..07f9178 --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jcphuff.c @@ -0,0 +1,833 @@ +/* + * jcphuff.c + * + * Copyright (C) 1995-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains Huffman entropy encoding routines for progressive JPEG. + * + * We do not support output suspension in this module, since the library + * currently does not allow multiple-scan files to be written with output + * suspension. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jchuff.h" /* Declarations shared with jchuff.c */ + +#ifdef C_PROGRESSIVE_SUPPORTED + +/* Expanded entropy encoder object for progressive Huffman encoding. */ + +typedef struct { + struct jpeg_entropy_encoder pub; /* public fields */ + + /* Mode flag: TRUE for optimization, FALSE for actual data output */ + boolean gather_statistics; + + /* Bit-level coding status. + * next_output_byte/free_in_buffer are local copies of cinfo->dest fields. + */ + JOCTET * next_output_byte; /* => next byte to write in buffer */ + size_t free_in_buffer; /* # of byte spaces remaining in buffer */ + INT32 put_buffer; /* current bit-accumulation buffer */ + int put_bits; /* # of bits now in it */ + j_compress_ptr cinfo; /* link to cinfo (needed for dump_buffer) */ + + /* Coding status for DC components */ + int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */ + + /* Coding status for AC components */ + int ac_tbl_no; /* the table number of the single component */ + unsigned int EOBRUN; /* run length of EOBs */ + unsigned int BE; /* # of buffered correction bits before MCU */ + char * bit_buffer; /* buffer for correction bits (1 per char) */ + /* packing correction bits tightly would save some space but cost time... */ + + unsigned int restarts_to_go; /* MCUs left in this restart interval */ + int next_restart_num; /* next restart number to write (0-7) */ + + /* Pointers to derived tables (these workspaces have image lifespan). + * Since any one scan codes only DC or only AC, we only need one set + * of tables, not one for DC and one for AC. + */ + c_derived_tbl * derived_tbls[NUM_HUFF_TBLS]; + + /* Statistics tables for optimization; again, one set is enough */ + long * count_ptrs[NUM_HUFF_TBLS]; +} phuff_entropy_encoder; + +typedef phuff_entropy_encoder * phuff_entropy_ptr; + +/* MAX_CORR_BITS is the number of bits the AC refinement correction-bit + * buffer can hold. Larger sizes may slightly improve compression, but + * 1000 is already well into the realm of overkill. + * The minimum safe size is 64 bits. + */ + +#define MAX_CORR_BITS 1000 /* Max # of correction bits I can buffer */ + +/* IRIGHT_SHIFT is like RIGHT_SHIFT, but works on int rather than INT32. + * We assume that int right shift is unsigned if INT32 right shift is, + * which should be safe. + */ + +#ifdef RIGHT_SHIFT_IS_UNSIGNED +#define ISHIFT_TEMPS int ishift_temp; +#define IRIGHT_SHIFT(x,shft) \ + ((ishift_temp = (x)) < 0 ? \ + (ishift_temp >> (shft)) | ((~0) << (16-(shft))) : \ + (ishift_temp >> (shft))) +#else +#define ISHIFT_TEMPS +#define IRIGHT_SHIFT(x,shft) ((x) >> (shft)) +#endif + +/* Forward declarations */ +METHODDEF(boolean) encode_mcu_DC_first JPP((j_compress_ptr cinfo, + JBLOCKROW *MCU_data)); +METHODDEF(boolean) encode_mcu_AC_first JPP((j_compress_ptr cinfo, + JBLOCKROW *MCU_data)); +METHODDEF(boolean) encode_mcu_DC_refine JPP((j_compress_ptr cinfo, + JBLOCKROW *MCU_data)); +METHODDEF(boolean) encode_mcu_AC_refine JPP((j_compress_ptr cinfo, + JBLOCKROW *MCU_data)); +METHODDEF(void) finish_pass_phuff JPP((j_compress_ptr cinfo)); +METHODDEF(void) finish_pass_gather_phuff JPP((j_compress_ptr cinfo)); + + +/* + * Initialize for a Huffman-compressed scan using progressive JPEG. + */ + +METHODDEF(void) +start_pass_phuff (j_compress_ptr cinfo, boolean gather_statistics) +{ + phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + boolean is_DC_band; + int ci, tbl; + jpeg_component_info * compptr; + + entropy->cinfo = cinfo; + entropy->gather_statistics = gather_statistics; + + is_DC_band = (cinfo->Ss == 0); + + /* We assume jcmaster.c already validated the scan parameters. */ + + /* Select execution routines */ + if (cinfo->Ah == 0) { + if (is_DC_band) + entropy->pub.encode_mcu = encode_mcu_DC_first; + else + entropy->pub.encode_mcu = encode_mcu_AC_first; + } else { + if (is_DC_band) + entropy->pub.encode_mcu = encode_mcu_DC_refine; + else { + entropy->pub.encode_mcu = encode_mcu_AC_refine; + /* AC refinement needs a correction bit buffer */ + if (entropy->bit_buffer == NULL) + entropy->bit_buffer = (char *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + MAX_CORR_BITS * SIZEOF(char)); + } + } + if (gather_statistics) + entropy->pub.finish_pass = finish_pass_gather_phuff; + else + entropy->pub.finish_pass = finish_pass_phuff; + + /* Only DC coefficients may be interleaved, so cinfo->comps_in_scan = 1 + * for AC coefficients. + */ + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + /* Initialize DC predictions to 0 */ + entropy->last_dc_val[ci] = 0; + /* Get table index */ + if (is_DC_band) { + if (cinfo->Ah != 0) /* DC refinement needs no table */ + continue; + tbl = compptr->dc_tbl_no; + } else { + entropy->ac_tbl_no = tbl = compptr->ac_tbl_no; + } + if (gather_statistics) { + /* Check for invalid table index */ + /* (make_c_derived_tbl does this in the other path) */ + if (tbl < 0 || tbl >= NUM_HUFF_TBLS) + ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tbl); + /* Allocate and zero the statistics tables */ + /* Note that jpeg_gen_optimal_table expects 257 entries in each table! */ + if (entropy->count_ptrs[tbl] == NULL) + entropy->count_ptrs[tbl] = (long *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + 257 * SIZEOF(long)); + MEMZERO(entropy->count_ptrs[tbl], 257 * SIZEOF(long)); + } else { + /* Compute derived values for Huffman table */ + /* We may do this more than once for a table, but it's not expensive */ + jpeg_make_c_derived_tbl(cinfo, is_DC_band, tbl, + & entropy->derived_tbls[tbl]); + } + } + + /* Initialize AC stuff */ + entropy->EOBRUN = 0; + entropy->BE = 0; + + /* Initialize bit buffer to empty */ + entropy->put_buffer = 0; + entropy->put_bits = 0; + + /* Initialize restart stuff */ + entropy->restarts_to_go = cinfo->restart_interval; + entropy->next_restart_num = 0; +} + + +/* Outputting bytes to the file. + * NB: these must be called only when actually outputting, + * that is, entropy->gather_statistics == FALSE. + */ + +/* Emit a byte */ +#define emit_byte(entropy,val) \ + { *(entropy)->next_output_byte++ = (JOCTET) (val); \ + if (--(entropy)->free_in_buffer == 0) \ + dump_buffer(entropy); } + + +LOCAL(void) +dump_buffer (phuff_entropy_ptr entropy) +/* Empty the output buffer; we do not support suspension in this module. */ +{ + struct jpeg_destination_mgr * dest = entropy->cinfo->dest; + + if (! (*dest->empty_output_buffer) (entropy->cinfo)) + ERREXIT(entropy->cinfo, JERR_CANT_SUSPEND); + /* After a successful buffer dump, must reset buffer pointers */ + entropy->next_output_byte = dest->next_output_byte; + entropy->free_in_buffer = dest->free_in_buffer; +} + + +/* Outputting bits to the file */ + +/* Only the right 24 bits of put_buffer are used; the valid bits are + * left-justified in this part. At most 16 bits can be passed to emit_bits + * in one call, and we never retain more than 7 bits in put_buffer + * between calls, so 24 bits are sufficient. + */ + +INLINE +LOCAL(void) +emit_bits (phuff_entropy_ptr entropy, unsigned int code, int size) +/* Emit some bits, unless we are in gather mode */ +{ + /* This routine is heavily used, so it's worth coding tightly. */ + register INT32 put_buffer = (INT32) code; + register int put_bits = entropy->put_bits; + + /* if size is 0, caller used an invalid Huffman table entry */ + if (size == 0) + ERREXIT(entropy->cinfo, JERR_HUFF_MISSING_CODE); + + if (entropy->gather_statistics) + return; /* do nothing if we're only getting stats */ + + put_buffer &= (((INT32) 1)<<size) - 1; /* mask off any extra bits in code */ + + put_bits += size; /* new number of bits in buffer */ + + put_buffer <<= 24 - put_bits; /* align incoming bits */ + + put_buffer |= entropy->put_buffer; /* and merge with old buffer contents */ + + while (put_bits >= 8) { + int c = (int) ((put_buffer >> 16) & 0xFF); + + emit_byte(entropy, c); + if (c == 0xFF) { /* need to stuff a zero byte? */ + emit_byte(entropy, 0); + } + put_buffer <<= 8; + put_bits -= 8; + } + + entropy->put_buffer = put_buffer; /* update variables */ + entropy->put_bits = put_bits; +} + + +LOCAL(void) +flush_bits (phuff_entropy_ptr entropy) +{ + emit_bits(entropy, 0x7F, 7); /* fill any partial byte with ones */ + entropy->put_buffer = 0; /* and reset bit-buffer to empty */ + entropy->put_bits = 0; +} + + +/* + * Emit (or just count) a Huffman symbol. + */ + +INLINE +LOCAL(void) +emit_symbol (phuff_entropy_ptr entropy, int tbl_no, int symbol) +{ + if (entropy->gather_statistics) + entropy->count_ptrs[tbl_no][symbol]++; + else { + c_derived_tbl * tbl = entropy->derived_tbls[tbl_no]; + emit_bits(entropy, tbl->ehufco[symbol], tbl->ehufsi[symbol]); + } +} + + +/* + * Emit bits from a correction bit buffer. + */ + +LOCAL(void) +emit_buffered_bits (phuff_entropy_ptr entropy, char * bufstart, + unsigned int nbits) +{ + if (entropy->gather_statistics) + return; /* no real work */ + + while (nbits > 0) { + emit_bits(entropy, (unsigned int) (*bufstart), 1); + bufstart++; + nbits--; + } +} + + +/* + * Emit any pending EOBRUN symbol. + */ + +LOCAL(void) +emit_eobrun (phuff_entropy_ptr entropy) +{ + register int temp, nbits; + + if (entropy->EOBRUN > 0) { /* if there is any pending EOBRUN */ + temp = entropy->EOBRUN; + nbits = 0; + while ((temp >>= 1)) + nbits++; + /* safety check: shouldn't happen given limited correction-bit buffer */ + if (nbits > 14) + ERREXIT(entropy->cinfo, JERR_HUFF_MISSING_CODE); + + emit_symbol(entropy, entropy->ac_tbl_no, nbits << 4); + if (nbits) + emit_bits(entropy, entropy->EOBRUN, nbits); + + entropy->EOBRUN = 0; + + /* Emit any buffered correction bits */ + emit_buffered_bits(entropy, entropy->bit_buffer, entropy->BE); + entropy->BE = 0; + } +} + + +/* + * Emit a restart marker & resynchronize predictions. + */ + +LOCAL(void) +emit_restart (phuff_entropy_ptr entropy, int restart_num) +{ + int ci; + + emit_eobrun(entropy); + + if (! entropy->gather_statistics) { + flush_bits(entropy); + emit_byte(entropy, 0xFF); + emit_byte(entropy, JPEG_RST0 + restart_num); + } + + if (entropy->cinfo->Ss == 0) { + /* Re-initialize DC predictions to 0 */ + for (ci = 0; ci < entropy->cinfo->comps_in_scan; ci++) + entropy->last_dc_val[ci] = 0; + } else { + /* Re-initialize all AC-related fields to 0 */ + entropy->EOBRUN = 0; + entropy->BE = 0; + } +} + + +/* + * MCU encoding for DC initial scan (either spectral selection, + * or first pass of successive approximation). + */ + +METHODDEF(boolean) +encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data) +{ + phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + register int temp, temp2; + register int nbits; + int blkn, ci; + int Al = cinfo->Al; + JBLOCKROW block; + jpeg_component_info * compptr; + ISHIFT_TEMPS + + entropy->next_output_byte = cinfo->dest->next_output_byte; + entropy->free_in_buffer = cinfo->dest->free_in_buffer; + + /* Emit restart marker if needed */ + if (cinfo->restart_interval) + if (entropy->restarts_to_go == 0) + emit_restart(entropy, entropy->next_restart_num); + + /* Encode the MCU data blocks */ + for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { + block = MCU_data[blkn]; + ci = cinfo->MCU_membership[blkn]; + compptr = cinfo->cur_comp_info[ci]; + + /* Compute the DC value after the required point transform by Al. + * This is simply an arithmetic right shift. + */ + temp2 = IRIGHT_SHIFT((int) ((*block)[0]), Al); + + /* DC differences are figured on the point-transformed values. */ + temp = temp2 - entropy->last_dc_val[ci]; + entropy->last_dc_val[ci] = temp2; + + /* Encode the DC coefficient difference per section G.1.2.1 */ + temp2 = temp; + if (temp < 0) { + temp = -temp; /* temp is abs value of input */ + /* For a negative input, want temp2 = bitwise complement of abs(input) */ + /* This code assumes we are on a two's complement machine */ + temp2--; + } + + /* Find the number of bits needed for the magnitude of the coefficient */ + nbits = 0; + while (temp) { + nbits++; + temp >>= 1; + } + /* Check for out-of-range coefficient values. + * Since we're encoding a difference, the range limit is twice as much. + */ + if (nbits > MAX_COEF_BITS+1) + ERREXIT(cinfo, JERR_BAD_DCT_COEF); + + /* Count/emit the Huffman-coded symbol for the number of bits */ + emit_symbol(entropy, compptr->dc_tbl_no, nbits); + + /* Emit that number of bits of the value, if positive, */ + /* or the complement of its magnitude, if negative. */ + if (nbits) /* emit_bits rejects calls with size 0 */ + emit_bits(entropy, (unsigned int) temp2, nbits); + } + + cinfo->dest->next_output_byte = entropy->next_output_byte; + cinfo->dest->free_in_buffer = entropy->free_in_buffer; + + /* Update restart-interval state too */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) { + entropy->restarts_to_go = cinfo->restart_interval; + entropy->next_restart_num++; + entropy->next_restart_num &= 7; + } + entropy->restarts_to_go--; + } + + return TRUE; +} + + +/* + * MCU encoding for AC initial scan (either spectral selection, + * or first pass of successive approximation). + */ + +METHODDEF(boolean) +encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data) +{ + phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + register int temp, temp2; + register int nbits; + register int r, k; + int Se = cinfo->Se; + int Al = cinfo->Al; + JBLOCKROW block; + + entropy->next_output_byte = cinfo->dest->next_output_byte; + entropy->free_in_buffer = cinfo->dest->free_in_buffer; + + /* Emit restart marker if needed */ + if (cinfo->restart_interval) + if (entropy->restarts_to_go == 0) + emit_restart(entropy, entropy->next_restart_num); + + /* Encode the MCU data block */ + block = MCU_data[0]; + + /* Encode the AC coefficients per section G.1.2.2, fig. G.3 */ + + r = 0; /* r = run length of zeros */ + + for (k = cinfo->Ss; k <= Se; k++) { + if ((temp = (*block)[jpeg_natural_order[k]]) == 0) { + r++; + continue; + } + /* We must apply the point transform by Al. For AC coefficients this + * is an integer division with rounding towards 0. To do this portably + * in C, we shift after obtaining the absolute value; so the code is + * interwoven with finding the abs value (temp) and output bits (temp2). + */ + if (temp < 0) { + temp = -temp; /* temp is abs value of input */ + temp >>= Al; /* apply the point transform */ + /* For a negative coef, want temp2 = bitwise complement of abs(coef) */ + temp2 = ~temp; + } else { + temp >>= Al; /* apply the point transform */ + temp2 = temp; + } + /* Watch out for case that nonzero coef is zero after point transform */ + if (temp == 0) { + r++; + continue; + } + + /* Emit any pending EOBRUN */ + if (entropy->EOBRUN > 0) + emit_eobrun(entropy); + /* if run length > 15, must emit special run-length-16 codes (0xF0) */ + while (r > 15) { + emit_symbol(entropy, entropy->ac_tbl_no, 0xF0); + r -= 16; + } + + /* Find the number of bits needed for the magnitude of the coefficient */ + nbits = 1; /* there must be at least one 1 bit */ + while ((temp >>= 1)) + nbits++; + /* Check for out-of-range coefficient values */ + if (nbits > MAX_COEF_BITS) + ERREXIT(cinfo, JERR_BAD_DCT_COEF); + + /* Count/emit Huffman symbol for run length / number of bits */ + emit_symbol(entropy, entropy->ac_tbl_no, (r << 4) + nbits); + + /* Emit that number of bits of the value, if positive, */ + /* or the complement of its magnitude, if negative. */ + emit_bits(entropy, (unsigned int) temp2, nbits); + + r = 0; /* reset zero run length */ + } + + if (r > 0) { /* If there are trailing zeroes, */ + entropy->EOBRUN++; /* count an EOB */ + if (entropy->EOBRUN == 0x7FFF) + emit_eobrun(entropy); /* force it out to avoid overflow */ + } + + cinfo->dest->next_output_byte = entropy->next_output_byte; + cinfo->dest->free_in_buffer = entropy->free_in_buffer; + + /* Update restart-interval state too */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) { + entropy->restarts_to_go = cinfo->restart_interval; + entropy->next_restart_num++; + entropy->next_restart_num &= 7; + } + entropy->restarts_to_go--; + } + + return TRUE; +} + + +/* + * MCU encoding for DC successive approximation refinement scan. + * Note: we assume such scans can be multi-component, although the spec + * is not very clear on the point. + */ + +METHODDEF(boolean) +encode_mcu_DC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data) +{ + phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + register int temp; + int blkn; + int Al = cinfo->Al; + JBLOCKROW block; + + entropy->next_output_byte = cinfo->dest->next_output_byte; + entropy->free_in_buffer = cinfo->dest->free_in_buffer; + + /* Emit restart marker if needed */ + if (cinfo->restart_interval) + if (entropy->restarts_to_go == 0) + emit_restart(entropy, entropy->next_restart_num); + + /* Encode the MCU data blocks */ + for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { + block = MCU_data[blkn]; + + /* We simply emit the Al'th bit of the DC coefficient value. */ + temp = (*block)[0]; + emit_bits(entropy, (unsigned int) (temp >> Al), 1); + } + + cinfo->dest->next_output_byte = entropy->next_output_byte; + cinfo->dest->free_in_buffer = entropy->free_in_buffer; + + /* Update restart-interval state too */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) { + entropy->restarts_to_go = cinfo->restart_interval; + entropy->next_restart_num++; + entropy->next_restart_num &= 7; + } + entropy->restarts_to_go--; + } + + return TRUE; +} + + +/* + * MCU encoding for AC successive approximation refinement scan. + */ + +METHODDEF(boolean) +encode_mcu_AC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data) +{ + phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + register int temp; + register int r, k; + int EOB; + char *BR_buffer; + unsigned int BR; + int Se = cinfo->Se; + int Al = cinfo->Al; + JBLOCKROW block; + int absvalues[DCTSIZE2]; + + entropy->next_output_byte = cinfo->dest->next_output_byte; + entropy->free_in_buffer = cinfo->dest->free_in_buffer; + + /* Emit restart marker if needed */ + if (cinfo->restart_interval) + if (entropy->restarts_to_go == 0) + emit_restart(entropy, entropy->next_restart_num); + + /* Encode the MCU data block */ + block = MCU_data[0]; + + /* It is convenient to make a pre-pass to determine the transformed + * coefficients' absolute values and the EOB position. + */ + EOB = 0; + for (k = cinfo->Ss; k <= Se; k++) { + temp = (*block)[jpeg_natural_order[k]]; + /* We must apply the point transform by Al. For AC coefficients this + * is an integer division with rounding towards 0. To do this portably + * in C, we shift after obtaining the absolute value. + */ + if (temp < 0) + temp = -temp; /* temp is abs value of input */ + temp >>= Al; /* apply the point transform */ + absvalues[k] = temp; /* save abs value for main pass */ + if (temp == 1) + EOB = k; /* EOB = index of last newly-nonzero coef */ + } + + /* Encode the AC coefficients per section G.1.2.3, fig. G.7 */ + + r = 0; /* r = run length of zeros */ + BR = 0; /* BR = count of buffered bits added now */ + BR_buffer = entropy->bit_buffer + entropy->BE; /* Append bits to buffer */ + + for (k = cinfo->Ss; k <= Se; k++) { + if ((temp = absvalues[k]) == 0) { + r++; + continue; + } + + /* Emit any required ZRLs, but not if they can be folded into EOB */ + while (r > 15 && k <= EOB) { + /* emit any pending EOBRUN and the BE correction bits */ + emit_eobrun(entropy); + /* Emit ZRL */ + emit_symbol(entropy, entropy->ac_tbl_no, 0xF0); + r -= 16; + /* Emit buffered correction bits that must be associated with ZRL */ + emit_buffered_bits(entropy, BR_buffer, BR); + BR_buffer = entropy->bit_buffer; /* BE bits are gone now */ + BR = 0; + } + + /* If the coef was previously nonzero, it only needs a correction bit. + * NOTE: a straight translation of the spec's figure G.7 would suggest + * that we also need to test r > 15. But if r > 15, we can only get here + * if k > EOB, which implies that this coefficient is not 1. + */ + if (temp > 1) { + /* The correction bit is the next bit of the absolute value. */ + BR_buffer[BR++] = (char) (temp & 1); + continue; + } + + /* Emit any pending EOBRUN and the BE correction bits */ + emit_eobrun(entropy); + + /* Count/emit Huffman symbol for run length / number of bits */ + emit_symbol(entropy, entropy->ac_tbl_no, (r << 4) + 1); + + /* Emit output bit for newly-nonzero coef */ + temp = ((*block)[jpeg_natural_order[k]] < 0) ? 0 : 1; + emit_bits(entropy, (unsigned int) temp, 1); + + /* Emit buffered correction bits that must be associated with this code */ + emit_buffered_bits(entropy, BR_buffer, BR); + BR_buffer = entropy->bit_buffer; /* BE bits are gone now */ + BR = 0; + r = 0; /* reset zero run length */ + } + + if (r > 0 || BR > 0) { /* If there are trailing zeroes, */ + entropy->EOBRUN++; /* count an EOB */ + entropy->BE += BR; /* concat my correction bits to older ones */ + /* We force out the EOB if we risk either: + * 1. overflow of the EOB counter; + * 2. overflow of the correction bit buffer during the next MCU. + */ + if (entropy->EOBRUN == 0x7FFF || entropy->BE > (MAX_CORR_BITS-DCTSIZE2+1)) + emit_eobrun(entropy); + } + + cinfo->dest->next_output_byte = entropy->next_output_byte; + cinfo->dest->free_in_buffer = entropy->free_in_buffer; + + /* Update restart-interval state too */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) { + entropy->restarts_to_go = cinfo->restart_interval; + entropy->next_restart_num++; + entropy->next_restart_num &= 7; + } + entropy->restarts_to_go--; + } + + return TRUE; +} + + +/* + * Finish up at the end of a Huffman-compressed progressive scan. + */ + +METHODDEF(void) +finish_pass_phuff (j_compress_ptr cinfo) +{ + phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + + entropy->next_output_byte = cinfo->dest->next_output_byte; + entropy->free_in_buffer = cinfo->dest->free_in_buffer; + + /* Flush out any buffered data */ + emit_eobrun(entropy); + flush_bits(entropy); + + cinfo->dest->next_output_byte = entropy->next_output_byte; + cinfo->dest->free_in_buffer = entropy->free_in_buffer; +} + + +/* + * Finish up a statistics-gathering pass and create the new Huffman tables. + */ + +METHODDEF(void) +finish_pass_gather_phuff (j_compress_ptr cinfo) +{ + phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + boolean is_DC_band; + int ci, tbl; + jpeg_component_info * compptr; + JHUFF_TBL **htblptr; + boolean did[NUM_HUFF_TBLS]; + + /* Flush out buffered data (all we care about is counting the EOB symbol) */ + emit_eobrun(entropy); + + is_DC_band = (cinfo->Ss == 0); + + /* It's important not to apply jpeg_gen_optimal_table more than once + * per table, because it clobbers the input frequency counts! + */ + MEMZERO(did, SIZEOF(did)); + + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + if (is_DC_band) { + if (cinfo->Ah != 0) /* DC refinement needs no table */ + continue; + tbl = compptr->dc_tbl_no; + } else { + tbl = compptr->ac_tbl_no; + } + if (! did[tbl]) { + if (is_DC_band) + htblptr = & cinfo->dc_huff_tbl_ptrs[tbl]; + else + htblptr = & cinfo->ac_huff_tbl_ptrs[tbl]; + if (*htblptr == NULL) + *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo); + jpeg_gen_optimal_table(cinfo, *htblptr, entropy->count_ptrs[tbl]); + did[tbl] = TRUE; + } + } +} + + +/* + * Module initialization routine for progressive Huffman entropy encoding. + */ + +GLOBAL(void) +jinit_phuff_encoder (j_compress_ptr cinfo) +{ + phuff_entropy_ptr entropy; + int i; + + entropy = (phuff_entropy_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(phuff_entropy_encoder)); + cinfo->entropy = (struct jpeg_entropy_encoder *) entropy; + entropy->pub.start_pass = start_pass_phuff; + + /* Mark tables unallocated */ + for (i = 0; i < NUM_HUFF_TBLS; i++) { + entropy->derived_tbls[i] = NULL; + entropy->count_ptrs[i] = NULL; + } + entropy->bit_buffer = NULL; /* needed only in AC refinement scan */ +} + +#endif /* C_PROGRESSIVE_SUPPORTED */ diff --git a/mod/pub.mod/libjpeg.mod/jcprepct.c b/mod/pub.mod/libjpeg.mod/jcprepct.c new file mode 100644 index 0000000..fa93333 --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jcprepct.c @@ -0,0 +1,354 @@ +/* + * jcprepct.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains the compression preprocessing controller. + * This controller manages the color conversion, downsampling, + * and edge expansion steps. + * + * Most of the complexity here is associated with buffering input rows + * as required by the downsampler. See the comments at the head of + * jcsample.c for the downsampler's needs. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* At present, jcsample.c can request context rows only for smoothing. + * In the future, we might also need context rows for CCIR601 sampling + * or other more-complex downsampling procedures. The code to support + * context rows should be compiled only if needed. + */ +#ifdef INPUT_SMOOTHING_SUPPORTED +#define CONTEXT_ROWS_SUPPORTED +#endif + + +/* + * For the simple (no-context-row) case, we just need to buffer one + * row group's worth of pixels for the downsampling step. At the bottom of + * the image, we pad to a full row group by replicating the last pixel row. + * The downsampler's last output row is then replicated if needed to pad + * out to a full iMCU row. + * + * When providing context rows, we must buffer three row groups' worth of + * pixels. Three row groups are physically allocated, but the row pointer + * arrays are made five row groups high, with the extra pointers above and + * below "wrapping around" to point to the last and first real row groups. + * This allows the downsampler to access the proper context rows. + * At the top and bottom of the image, we create dummy context rows by + * copying the first or last real pixel row. This copying could be avoided + * by pointer hacking as is done in jdmainct.c, but it doesn't seem worth the + * trouble on the compression side. + */ + + +/* Private buffer controller object */ + +typedef struct { + struct jpeg_c_prep_controller pub; /* public fields */ + + /* Downsampling input buffer. This buffer holds color-converted data + * until we have enough to do a downsample step. + */ + JSAMPARRAY color_buf[MAX_COMPONENTS]; + + JDIMENSION rows_to_go; /* counts rows remaining in source image */ + int next_buf_row; /* index of next row to store in color_buf */ + +#ifdef CONTEXT_ROWS_SUPPORTED /* only needed for context case */ + int this_row_group; /* starting row index of group to process */ + int next_buf_stop; /* downsample when we reach this index */ +#endif +} my_prep_controller; + +typedef my_prep_controller * my_prep_ptr; + + +/* + * Initialize for a processing pass. + */ + +METHODDEF(void) +start_pass_prep (j_compress_ptr cinfo, J_BUF_MODE pass_mode) +{ + my_prep_ptr prep = (my_prep_ptr) cinfo->prep; + + if (pass_mode != JBUF_PASS_THRU) + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + + /* Initialize total-height counter for detecting bottom of image */ + prep->rows_to_go = cinfo->image_height; + /* Mark the conversion buffer empty */ + prep->next_buf_row = 0; +#ifdef CONTEXT_ROWS_SUPPORTED + /* Preset additional state variables for context mode. + * These aren't used in non-context mode, so we needn't test which mode. + */ + prep->this_row_group = 0; + /* Set next_buf_stop to stop after two row groups have been read in. */ + prep->next_buf_stop = 2 * cinfo->max_v_samp_factor; +#endif +} + + +/* + * Expand an image vertically from height input_rows to height output_rows, + * by duplicating the bottom row. + */ + +LOCAL(void) +expand_bottom_edge (JSAMPARRAY image_data, JDIMENSION num_cols, + int input_rows, int output_rows) +{ + register int row; + + for (row = input_rows; row < output_rows; row++) { + jcopy_sample_rows(image_data, input_rows-1, image_data, row, + 1, num_cols); + } +} + + +/* + * Process some data in the simple no-context case. + * + * Preprocessor output data is counted in "row groups". A row group + * is defined to be v_samp_factor sample rows of each component. + * Downsampling will produce this much data from each max_v_samp_factor + * input rows. + */ + +METHODDEF(void) +pre_process_data (j_compress_ptr cinfo, + JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, + JDIMENSION in_rows_avail, + JSAMPIMAGE output_buf, JDIMENSION *out_row_group_ctr, + JDIMENSION out_row_groups_avail) +{ + my_prep_ptr prep = (my_prep_ptr) cinfo->prep; + int numrows, ci; + JDIMENSION inrows; + jpeg_component_info * compptr; + + while (*in_row_ctr < in_rows_avail && + *out_row_group_ctr < out_row_groups_avail) { + /* Do color conversion to fill the conversion buffer. */ + inrows = in_rows_avail - *in_row_ctr; + numrows = cinfo->max_v_samp_factor - prep->next_buf_row; + numrows = (int) MIN((JDIMENSION) numrows, inrows); + (*cinfo->cconvert->color_convert) (cinfo, input_buf + *in_row_ctr, + prep->color_buf, + (JDIMENSION) prep->next_buf_row, + numrows); + *in_row_ctr += numrows; + prep->next_buf_row += numrows; + prep->rows_to_go -= numrows; + /* If at bottom of image, pad to fill the conversion buffer. */ + if (prep->rows_to_go == 0 && + prep->next_buf_row < cinfo->max_v_samp_factor) { + for (ci = 0; ci < cinfo->num_components; ci++) { + expand_bottom_edge(prep->color_buf[ci], cinfo->image_width, + prep->next_buf_row, cinfo->max_v_samp_factor); + } + prep->next_buf_row = cinfo->max_v_samp_factor; + } + /* If we've filled the conversion buffer, empty it. */ + if (prep->next_buf_row == cinfo->max_v_samp_factor) { + (*cinfo->downsample->downsample) (cinfo, + prep->color_buf, (JDIMENSION) 0, + output_buf, *out_row_group_ctr); + prep->next_buf_row = 0; + (*out_row_group_ctr)++; + } + /* If at bottom of image, pad the output to a full iMCU height. + * Note we assume the caller is providing a one-iMCU-height output buffer! + */ + if (prep->rows_to_go == 0 && + *out_row_group_ctr < out_row_groups_avail) { + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + expand_bottom_edge(output_buf[ci], + compptr->width_in_blocks * DCTSIZE, + (int) (*out_row_group_ctr * compptr->v_samp_factor), + (int) (out_row_groups_avail * compptr->v_samp_factor)); + } + *out_row_group_ctr = out_row_groups_avail; + break; /* can exit outer loop without test */ + } + } +} + + +#ifdef CONTEXT_ROWS_SUPPORTED + +/* + * Process some data in the context case. + */ + +METHODDEF(void) +pre_process_context (j_compress_ptr cinfo, + JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, + JDIMENSION in_rows_avail, + JSAMPIMAGE output_buf, JDIMENSION *out_row_group_ctr, + JDIMENSION out_row_groups_avail) +{ + my_prep_ptr prep = (my_prep_ptr) cinfo->prep; + int numrows, ci; + int buf_height = cinfo->max_v_samp_factor * 3; + JDIMENSION inrows; + + while (*out_row_group_ctr < out_row_groups_avail) { + if (*in_row_ctr < in_rows_avail) { + /* Do color conversion to fill the conversion buffer. */ + inrows = in_rows_avail - *in_row_ctr; + numrows = prep->next_buf_stop - prep->next_buf_row; + numrows = (int) MIN((JDIMENSION) numrows, inrows); + (*cinfo->cconvert->color_convert) (cinfo, input_buf + *in_row_ctr, + prep->color_buf, + (JDIMENSION) prep->next_buf_row, + numrows); + /* Pad at top of image, if first time through */ + if (prep->rows_to_go == cinfo->image_height) { + for (ci = 0; ci < cinfo->num_components; ci++) { + int row; + for (row = 1; row <= cinfo->max_v_samp_factor; row++) { + jcopy_sample_rows(prep->color_buf[ci], 0, + prep->color_buf[ci], -row, + 1, cinfo->image_width); + } + } + } + *in_row_ctr += numrows; + prep->next_buf_row += numrows; + prep->rows_to_go -= numrows; + } else { + /* Return for more data, unless we are at the bottom of the image. */ + if (prep->rows_to_go != 0) + break; + /* When at bottom of image, pad to fill the conversion buffer. */ + if (prep->next_buf_row < prep->next_buf_stop) { + for (ci = 0; ci < cinfo->num_components; ci++) { + expand_bottom_edge(prep->color_buf[ci], cinfo->image_width, + prep->next_buf_row, prep->next_buf_stop); + } + prep->next_buf_row = prep->next_buf_stop; + } + } + /* If we've gotten enough data, downsample a row group. */ + if (prep->next_buf_row == prep->next_buf_stop) { + (*cinfo->downsample->downsample) (cinfo, + prep->color_buf, + (JDIMENSION) prep->this_row_group, + output_buf, *out_row_group_ctr); + (*out_row_group_ctr)++; + /* Advance pointers with wraparound as necessary. */ + prep->this_row_group += cinfo->max_v_samp_factor; + if (prep->this_row_group >= buf_height) + prep->this_row_group = 0; + if (prep->next_buf_row >= buf_height) + prep->next_buf_row = 0; + prep->next_buf_stop = prep->next_buf_row + cinfo->max_v_samp_factor; + } + } +} + + +/* + * Create the wrapped-around downsampling input buffer needed for context mode. + */ + +LOCAL(void) +create_context_buffer (j_compress_ptr cinfo) +{ + my_prep_ptr prep = (my_prep_ptr) cinfo->prep; + int rgroup_height = cinfo->max_v_samp_factor; + int ci, i; + jpeg_component_info * compptr; + JSAMPARRAY true_buffer, fake_buffer; + + /* Grab enough space for fake row pointers for all the components; + * we need five row groups' worth of pointers for each component. + */ + fake_buffer = (JSAMPARRAY) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (cinfo->num_components * 5 * rgroup_height) * + SIZEOF(JSAMPROW)); + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + /* Allocate the actual buffer space (3 row groups) for this component. + * We make the buffer wide enough to allow the downsampler to edge-expand + * horizontally within the buffer, if it so chooses. + */ + true_buffer = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + (JDIMENSION) (((long) compptr->width_in_blocks * DCTSIZE * + cinfo->max_h_samp_factor) / compptr->h_samp_factor), + (JDIMENSION) (3 * rgroup_height)); + /* Copy true buffer row pointers into the middle of the fake row array */ + MEMCOPY(fake_buffer + rgroup_height, true_buffer, + 3 * rgroup_height * SIZEOF(JSAMPROW)); + /* Fill in the above and below wraparound pointers */ + for (i = 0; i < rgroup_height; i++) { + fake_buffer[i] = true_buffer[2 * rgroup_height + i]; + fake_buffer[4 * rgroup_height + i] = true_buffer[i]; + } + prep->color_buf[ci] = fake_buffer + rgroup_height; + fake_buffer += 5 * rgroup_height; /* point to space for next component */ + } +} + +#endif /* CONTEXT_ROWS_SUPPORTED */ + + +/* + * Initialize preprocessing controller. + */ + +GLOBAL(void) +jinit_c_prep_controller (j_compress_ptr cinfo, boolean need_full_buffer) +{ + my_prep_ptr prep; + int ci; + jpeg_component_info * compptr; + + if (need_full_buffer) /* safety check */ + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + + prep = (my_prep_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_prep_controller)); + cinfo->prep = (struct jpeg_c_prep_controller *) prep; + prep->pub.start_pass = start_pass_prep; + + /* Allocate the color conversion buffer. + * We make the buffer wide enough to allow the downsampler to edge-expand + * horizontally within the buffer, if it so chooses. + */ + if (cinfo->downsample->need_context_rows) { + /* Set up to provide context rows */ +#ifdef CONTEXT_ROWS_SUPPORTED + prep->pub.pre_process_data = pre_process_context; + create_context_buffer(cinfo); +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } else { + /* No context, just make it tall enough for one row group */ + prep->pub.pre_process_data = pre_process_data; + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + prep->color_buf[ci] = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + (JDIMENSION) (((long) compptr->width_in_blocks * DCTSIZE * + cinfo->max_h_samp_factor) / compptr->h_samp_factor), + (JDIMENSION) cinfo->max_v_samp_factor); + } + } +} diff --git a/mod/pub.mod/libjpeg.mod/jcsample.c b/mod/pub.mod/libjpeg.mod/jcsample.c new file mode 100644 index 0000000..212ec87 --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jcsample.c @@ -0,0 +1,519 @@ +/* + * jcsample.c + * + * Copyright (C) 1991-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains downsampling routines. + * + * Downsampling input data is counted in "row groups". A row group + * is defined to be max_v_samp_factor pixel rows of each component, + * from which the downsampler produces v_samp_factor sample rows. + * A single row group is processed in each call to the downsampler module. + * + * The downsampler is responsible for edge-expansion of its output data + * to fill an integral number of DCT blocks horizontally. The source buffer + * may be modified if it is helpful for this purpose (the source buffer is + * allocated wide enough to correspond to the desired output width). + * The caller (the prep controller) is responsible for vertical padding. + * + * The downsampler may request "context rows" by setting need_context_rows + * during startup. In this case, the input arrays will contain at least + * one row group's worth of pixels above and below the passed-in data; + * the caller will create dummy rows at image top and bottom by replicating + * the first or last real pixel row. + * + * An excellent reference for image resampling is + * Digital Image Warping, George Wolberg, 1990. + * Pub. by IEEE Computer Society Press, Los Alamitos, CA. ISBN 0-8186-8944-7. + * + * The downsampling algorithm used here is a simple average of the source + * pixels covered by the output pixel. The hi-falutin sampling literature + * refers to this as a "box filter". In general the characteristics of a box + * filter are not very good, but for the specific cases we normally use (1:1 + * and 2:1 ratios) the box is equivalent to a "triangle filter" which is not + * nearly so bad. If you intend to use other sampling ratios, you'd be well + * advised to improve this code. + * + * A simple input-smoothing capability is provided. This is mainly intended + * for cleaning up color-dithered GIF input files (if you find it inadequate, + * we suggest using an external filtering program such as pnmconvol). When + * enabled, each input pixel P is replaced by a weighted sum of itself and its + * eight neighbors. P's weight is 1-8*SF and each neighbor's weight is SF, + * where SF = (smoothing_factor / 1024). + * Currently, smoothing is only supported for 2h2v sampling factors. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* Pointer to routine to downsample a single component */ +typedef JMETHOD(void, downsample1_ptr, + (j_compress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY output_data)); + +/* Private subobject */ + +typedef struct { + struct jpeg_downsampler pub; /* public fields */ + + /* Downsampling method pointers, one per component */ + downsample1_ptr methods[MAX_COMPONENTS]; +} my_downsampler; + +typedef my_downsampler * my_downsample_ptr; + + +/* + * Initialize for a downsampling pass. + */ + +METHODDEF(void) +start_pass_downsample (j_compress_ptr cinfo) +{ + /* no work for now */ +} + + +/* + * Expand a component horizontally from width input_cols to width output_cols, + * by duplicating the rightmost samples. + */ + +LOCAL(void) +expand_right_edge (JSAMPARRAY image_data, int num_rows, + JDIMENSION input_cols, JDIMENSION output_cols) +{ + register JSAMPROW ptr; + register JSAMPLE pixval; + register int count; + int row; + int numcols = (int) (output_cols - input_cols); + + if (numcols > 0) { + for (row = 0; row < num_rows; row++) { + ptr = image_data[row] + input_cols; + pixval = ptr[-1]; /* don't need GETJSAMPLE() here */ + for (count = numcols; count > 0; count--) + *ptr++ = pixval; + } + } +} + + +/* + * Do downsampling for a whole row group (all components). + * + * In this version we simply downsample each component independently. + */ + +METHODDEF(void) +sep_downsample (j_compress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION in_row_index, + JSAMPIMAGE output_buf, JDIMENSION out_row_group_index) +{ + my_downsample_ptr downsample = (my_downsample_ptr) cinfo->downsample; + int ci; + jpeg_component_info * compptr; + JSAMPARRAY in_ptr, out_ptr; + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + in_ptr = input_buf[ci] + in_row_index; + out_ptr = output_buf[ci] + (out_row_group_index * compptr->v_samp_factor); + (*downsample->methods[ci]) (cinfo, compptr, in_ptr, out_ptr); + } +} + + +/* + * Downsample pixel values of a single component. + * One row group is processed per call. + * This version handles arbitrary integral sampling ratios, without smoothing. + * Note that this version is not actually used for customary sampling ratios. + */ + +METHODDEF(void) +int_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY output_data) +{ + int inrow, outrow, h_expand, v_expand, numpix, numpix2, h, v; + JDIMENSION outcol, outcol_h; /* outcol_h == outcol*h_expand */ + JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE; + JSAMPROW inptr, outptr; + INT32 outvalue; + + h_expand = cinfo->max_h_samp_factor / compptr->h_samp_factor; + v_expand = cinfo->max_v_samp_factor / compptr->v_samp_factor; + numpix = h_expand * v_expand; + numpix2 = numpix/2; + + /* Expand input data enough to let all the output samples be generated + * by the standard loop. Special-casing padded output would be more + * efficient. + */ + expand_right_edge(input_data, cinfo->max_v_samp_factor, + cinfo->image_width, output_cols * h_expand); + + inrow = 0; + for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) { + outptr = output_data[outrow]; + for (outcol = 0, outcol_h = 0; outcol < output_cols; + outcol++, outcol_h += h_expand) { + outvalue = 0; + for (v = 0; v < v_expand; v++) { + inptr = input_data[inrow+v] + outcol_h; + for (h = 0; h < h_expand; h++) { + outvalue += (INT32) GETJSAMPLE(*inptr++); + } + } + *outptr++ = (JSAMPLE) ((outvalue + numpix2) / numpix); + } + inrow += v_expand; + } +} + + +/* + * Downsample pixel values of a single component. + * This version handles the special case of a full-size component, + * without smoothing. + */ + +METHODDEF(void) +fullsize_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY output_data) +{ + /* Copy the data */ + jcopy_sample_rows(input_data, 0, output_data, 0, + cinfo->max_v_samp_factor, cinfo->image_width); + /* Edge-expand */ + expand_right_edge(output_data, cinfo->max_v_samp_factor, + cinfo->image_width, compptr->width_in_blocks * DCTSIZE); +} + + +/* + * Downsample pixel values of a single component. + * This version handles the common case of 2:1 horizontal and 1:1 vertical, + * without smoothing. + * + * A note about the "bias" calculations: when rounding fractional values to + * integer, we do not want to always round 0.5 up to the next integer. + * If we did that, we'd introduce a noticeable bias towards larger values. + * Instead, this code is arranged so that 0.5 will be rounded up or down at + * alternate pixel locations (a simple ordered dither pattern). + */ + +METHODDEF(void) +h2v1_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY output_data) +{ + int outrow; + JDIMENSION outcol; + JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE; + register JSAMPROW inptr, outptr; + register int bias; + + /* Expand input data enough to let all the output samples be generated + * by the standard loop. Special-casing padded output would be more + * efficient. + */ + expand_right_edge(input_data, cinfo->max_v_samp_factor, + cinfo->image_width, output_cols * 2); + + for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) { + outptr = output_data[outrow]; + inptr = input_data[outrow]; + bias = 0; /* bias = 0,1,0,1,... for successive samples */ + for (outcol = 0; outcol < output_cols; outcol++) { + *outptr++ = (JSAMPLE) ((GETJSAMPLE(*inptr) + GETJSAMPLE(inptr[1]) + + bias) >> 1); + bias ^= 1; /* 0=>1, 1=>0 */ + inptr += 2; + } + } +} + + +/* + * Downsample pixel values of a single component. + * This version handles the standard case of 2:1 horizontal and 2:1 vertical, + * without smoothing. + */ + +METHODDEF(void) +h2v2_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY output_data) +{ + int inrow, outrow; + JDIMENSION outcol; + JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE; + register JSAMPROW inptr0, inptr1, outptr; + register int bias; + + /* Expand input data enough to let all the output samples be generated + * by the standard loop. Special-casing padded output would be more + * efficient. + */ + expand_right_edge(input_data, cinfo->max_v_samp_factor, + cinfo->image_width, output_cols * 2); + + inrow = 0; + for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) { + outptr = output_data[outrow]; + inptr0 = input_data[inrow]; + inptr1 = input_data[inrow+1]; + bias = 1; /* bias = 1,2,1,2,... for successive samples */ + for (outcol = 0; outcol < output_cols; outcol++) { + *outptr++ = (JSAMPLE) ((GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) + + GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]) + + bias) >> 2); + bias ^= 3; /* 1=>2, 2=>1 */ + inptr0 += 2; inptr1 += 2; + } + inrow += 2; + } +} + + +#ifdef INPUT_SMOOTHING_SUPPORTED + +/* + * Downsample pixel values of a single component. + * This version handles the standard case of 2:1 horizontal and 2:1 vertical, + * with smoothing. One row of context is required. + */ + +METHODDEF(void) +h2v2_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY output_data) +{ + int inrow, outrow; + JDIMENSION colctr; + JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE; + register JSAMPROW inptr0, inptr1, above_ptr, below_ptr, outptr; + INT32 membersum, neighsum, memberscale, neighscale; + + /* Expand input data enough to let all the output samples be generated + * by the standard loop. Special-casing padded output would be more + * efficient. + */ + expand_right_edge(input_data - 1, cinfo->max_v_samp_factor + 2, + cinfo->image_width, output_cols * 2); + + /* We don't bother to form the individual "smoothed" input pixel values; + * we can directly compute the output which is the average of the four + * smoothed values. Each of the four member pixels contributes a fraction + * (1-8*SF) to its own smoothed image and a fraction SF to each of the three + * other smoothed pixels, therefore a total fraction (1-5*SF)/4 to the final + * output. The four corner-adjacent neighbor pixels contribute a fraction + * SF to just one smoothed pixel, or SF/4 to the final output; while the + * eight edge-adjacent neighbors contribute SF to each of two smoothed + * pixels, or SF/2 overall. In order to use integer arithmetic, these + * factors are scaled by 2^16 = 65536. + * Also recall that SF = smoothing_factor / 1024. + */ + + memberscale = 16384 - cinfo->smoothing_factor * 80; /* scaled (1-5*SF)/4 */ + neighscale = cinfo->smoothing_factor * 16; /* scaled SF/4 */ + + inrow = 0; + for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) { + outptr = output_data[outrow]; + inptr0 = input_data[inrow]; + inptr1 = input_data[inrow+1]; + above_ptr = input_data[inrow-1]; + below_ptr = input_data[inrow+2]; + + /* Special case for first column: pretend column -1 is same as column 0 */ + membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) + + GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]); + neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) + + GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) + + GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[2]) + + GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[2]); + neighsum += neighsum; + neighsum += GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[2]) + + GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[2]); + membersum = membersum * memberscale + neighsum * neighscale; + *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16); + inptr0 += 2; inptr1 += 2; above_ptr += 2; below_ptr += 2; + + for (colctr = output_cols - 2; colctr > 0; colctr--) { + /* sum of pixels directly mapped to this output element */ + membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) + + GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]); + /* sum of edge-neighbor pixels */ + neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) + + GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) + + GETJSAMPLE(inptr0[-1]) + GETJSAMPLE(inptr0[2]) + + GETJSAMPLE(inptr1[-1]) + GETJSAMPLE(inptr1[2]); + /* The edge-neighbors count twice as much as corner-neighbors */ + neighsum += neighsum; + /* Add in the corner-neighbors */ + neighsum += GETJSAMPLE(above_ptr[-1]) + GETJSAMPLE(above_ptr[2]) + + GETJSAMPLE(below_ptr[-1]) + GETJSAMPLE(below_ptr[2]); + /* form final output scaled up by 2^16 */ + membersum = membersum * memberscale + neighsum * neighscale; + /* round, descale and output it */ + *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16); + inptr0 += 2; inptr1 += 2; above_ptr += 2; below_ptr += 2; + } + + /* Special case for last column */ + membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) + + GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]); + neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) + + GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) + + GETJSAMPLE(inptr0[-1]) + GETJSAMPLE(inptr0[1]) + + GETJSAMPLE(inptr1[-1]) + GETJSAMPLE(inptr1[1]); + neighsum += neighsum; + neighsum += GETJSAMPLE(above_ptr[-1]) + GETJSAMPLE(above_ptr[1]) + + GETJSAMPLE(below_ptr[-1]) + GETJSAMPLE(below_ptr[1]); + membersum = membersum * memberscale + neighsum * neighscale; + *outptr = (JSAMPLE) ((membersum + 32768) >> 16); + + inrow += 2; + } +} + + +/* + * Downsample pixel values of a single component. + * This version handles the special case of a full-size component, + * with smoothing. One row of context is required. + */ + +METHODDEF(void) +fullsize_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info *compptr, + JSAMPARRAY input_data, JSAMPARRAY output_data) +{ + int outrow; + JDIMENSION colctr; + JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE; + register JSAMPROW inptr, above_ptr, below_ptr, outptr; + INT32 membersum, neighsum, memberscale, neighscale; + int colsum, lastcolsum, nextcolsum; + + /* Expand input data enough to let all the output samples be generated + * by the standard loop. Special-casing padded output would be more + * efficient. + */ + expand_right_edge(input_data - 1, cinfo->max_v_samp_factor + 2, + cinfo->image_width, output_cols); + + /* Each of the eight neighbor pixels contributes a fraction SF to the + * smoothed pixel, while the main pixel contributes (1-8*SF). In order + * to use integer arithmetic, these factors are multiplied by 2^16 = 65536. + * Also recall that SF = smoothing_factor / 1024. + */ + + memberscale = 65536L - cinfo->smoothing_factor * 512L; /* scaled 1-8*SF */ + neighscale = cinfo->smoothing_factor * 64; /* scaled SF */ + + for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) { + outptr = output_data[outrow]; + inptr = input_data[outrow]; + above_ptr = input_data[outrow-1]; + below_ptr = input_data[outrow+1]; + + /* Special case for first column */ + colsum = GETJSAMPLE(*above_ptr++) + GETJSAMPLE(*below_ptr++) + + GETJSAMPLE(*inptr); + membersum = GETJSAMPLE(*inptr++); + nextcolsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(*below_ptr) + + GETJSAMPLE(*inptr); + neighsum = colsum + (colsum - membersum) + nextcolsum; + membersum = membersum * memberscale + neighsum * neighscale; + *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16); + lastcolsum = colsum; colsum = nextcolsum; + + for (colctr = output_cols - 2; colctr > 0; colctr--) { + membersum = GETJSAMPLE(*inptr++); + above_ptr++; below_ptr++; + nextcolsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(*below_ptr) + + GETJSAMPLE(*inptr); + neighsum = lastcolsum + (colsum - membersum) + nextcolsum; + membersum = membersum * memberscale + neighsum * neighscale; + *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16); + lastcolsum = colsum; colsum = nextcolsum; + } + + /* Special case for last column */ + membersum = GETJSAMPLE(*inptr); + neighsum = lastcolsum + (colsum - membersum) + colsum; + membersum = membersum * memberscale + neighsum * neighscale; + *outptr = (JSAMPLE) ((membersum + 32768) >> 16); + + } +} + +#endif /* INPUT_SMOOTHING_SUPPORTED */ + + +/* + * Module initialization routine for downsampling. + * Note that we must select a routine for each component. + */ + +GLOBAL(void) +jinit_downsampler (j_compress_ptr cinfo) +{ + my_downsample_ptr downsample; + int ci; + jpeg_component_info * compptr; + boolean smoothok = TRUE; + + downsample = (my_downsample_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_downsampler)); + cinfo->downsample = (struct jpeg_downsampler *) downsample; + downsample->pub.start_pass = start_pass_downsample; + downsample->pub.downsample = sep_downsample; + downsample->pub.need_context_rows = FALSE; + + if (cinfo->CCIR601_sampling) + ERREXIT(cinfo, JERR_CCIR601_NOTIMPL); + + /* Verify we can handle the sampling factors, and set up method pointers */ + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + if (compptr->h_samp_factor == cinfo->max_h_samp_factor && + compptr->v_samp_factor == cinfo->max_v_samp_factor) { +#ifdef INPUT_SMOOTHING_SUPPORTED + if (cinfo->smoothing_factor) { + downsample->methods[ci] = fullsize_smooth_downsample; + downsample->pub.need_context_rows = TRUE; + } else +#endif + downsample->methods[ci] = fullsize_downsample; + } else if (compptr->h_samp_factor * 2 == cinfo->max_h_samp_factor && + compptr->v_samp_factor == cinfo->max_v_samp_factor) { + smoothok = FALSE; + downsample->methods[ci] = h2v1_downsample; + } else if (compptr->h_samp_factor * 2 == cinfo->max_h_samp_factor && + compptr->v_samp_factor * 2 == cinfo->max_v_samp_factor) { +#ifdef INPUT_SMOOTHING_SUPPORTED + if (cinfo->smoothing_factor) { + downsample->methods[ci] = h2v2_smooth_downsample; + downsample->pub.need_context_rows = TRUE; + } else +#endif + downsample->methods[ci] = h2v2_downsample; + } else if ((cinfo->max_h_samp_factor % compptr->h_samp_factor) == 0 && + (cinfo->max_v_samp_factor % compptr->v_samp_factor) == 0) { + smoothok = FALSE; + downsample->methods[ci] = int_downsample; + } else + ERREXIT(cinfo, JERR_FRACT_SAMPLE_NOTIMPL); + } + +#ifdef INPUT_SMOOTHING_SUPPORTED + if (cinfo->smoothing_factor && !smoothok) + TRACEMS(cinfo, 0, JTRC_SMOOTH_NOTIMPL); +#endif +} diff --git a/mod/pub.mod/libjpeg.mod/jctrans.c b/mod/pub.mod/libjpeg.mod/jctrans.c new file mode 100644 index 0000000..0e6d707 --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jctrans.c @@ -0,0 +1,388 @@ +/* + * jctrans.c + * + * Copyright (C) 1995-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains library routines for transcoding compression, + * that is, writing raw DCT coefficient arrays to an output JPEG file. + * The routines in jcapimin.c will also be needed by a transcoder. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* Forward declarations */ +LOCAL(void) transencode_master_selection + JPP((j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays)); +LOCAL(void) transencode_coef_controller + JPP((j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays)); + + +/* + * Compression initialization for writing raw-coefficient data. + * Before calling this, all parameters and a data destination must be set up. + * Call jpeg_finish_compress() to actually write the data. + * + * The number of passed virtual arrays must match cinfo->num_components. + * Note that the virtual arrays need not be filled or even realized at + * the time write_coefficients is called; indeed, if the virtual arrays + * were requested from this compression object's memory manager, they + * typically will be realized during this routine and filled afterwards. + */ + +GLOBAL(void) +jpeg_write_coefficients (j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays) +{ + if (cinfo->global_state != CSTATE_START) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + /* Mark all tables to be written */ + jpeg_suppress_tables(cinfo, FALSE); + /* (Re)initialize error mgr and destination modules */ + (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo); + (*cinfo->dest->init_destination) (cinfo); + /* Perform master selection of active modules */ + transencode_master_selection(cinfo, coef_arrays); + /* Wait for jpeg_finish_compress() call */ + cinfo->next_scanline = 0; /* so jpeg_write_marker works */ + cinfo->global_state = CSTATE_WRCOEFS; +} + + +/* + * Initialize the compression object with default parameters, + * then copy from the source object all parameters needed for lossless + * transcoding. Parameters that can be varied without loss (such as + * scan script and Huffman optimization) are left in their default states. + */ + +GLOBAL(void) +jpeg_copy_critical_parameters (j_decompress_ptr srcinfo, + j_compress_ptr dstinfo) +{ + JQUANT_TBL ** qtblptr; + jpeg_component_info *incomp, *outcomp; + JQUANT_TBL *c_quant, *slot_quant; + int tblno, ci, coefi; + + /* Safety check to ensure start_compress not called yet. */ + if (dstinfo->global_state != CSTATE_START) + ERREXIT1(dstinfo, JERR_BAD_STATE, dstinfo->global_state); + /* Copy fundamental image dimensions */ + dstinfo->image_width = srcinfo->image_width; + dstinfo->image_height = srcinfo->image_height; + dstinfo->input_components = srcinfo->num_components; + dstinfo->in_color_space = srcinfo->jpeg_color_space; + /* Initialize all parameters to default values */ + jpeg_set_defaults(dstinfo); + /* jpeg_set_defaults may choose wrong colorspace, eg YCbCr if input is RGB. + * Fix it to get the right header markers for the image colorspace. + */ + jpeg_set_colorspace(dstinfo, srcinfo->jpeg_color_space); + dstinfo->data_precision = srcinfo->data_precision; + dstinfo->CCIR601_sampling = srcinfo->CCIR601_sampling; + /* Copy the source's quantization tables. */ + for (tblno = 0; tblno < NUM_QUANT_TBLS; tblno++) { + if (srcinfo->quant_tbl_ptrs[tblno] != NULL) { + qtblptr = & dstinfo->quant_tbl_ptrs[tblno]; + if (*qtblptr == NULL) + *qtblptr = jpeg_alloc_quant_table((j_common_ptr) dstinfo); + MEMCOPY((*qtblptr)->quantval, + srcinfo->quant_tbl_ptrs[tblno]->quantval, + SIZEOF((*qtblptr)->quantval)); + (*qtblptr)->sent_table = FALSE; + } + } + /* Copy the source's per-component info. + * Note we assume jpeg_set_defaults has allocated the dest comp_info array. + */ + dstinfo->num_components = srcinfo->num_components; + if (dstinfo->num_components < 1 || dstinfo->num_components > MAX_COMPONENTS) + ERREXIT2(dstinfo, JERR_COMPONENT_COUNT, dstinfo->num_components, + MAX_COMPONENTS); + for (ci = 0, incomp = srcinfo->comp_info, outcomp = dstinfo->comp_info; + ci < dstinfo->num_components; ci++, incomp++, outcomp++) { + outcomp->component_id = incomp->component_id; + outcomp->h_samp_factor = incomp->h_samp_factor; + outcomp->v_samp_factor = incomp->v_samp_factor; + outcomp->quant_tbl_no = incomp->quant_tbl_no; + /* Make sure saved quantization table for component matches the qtable + * slot. If not, the input file re-used this qtable slot. + * IJG encoder currently cannot duplicate this. + */ + tblno = outcomp->quant_tbl_no; + if (tblno < 0 || tblno >= NUM_QUANT_TBLS || + srcinfo->quant_tbl_ptrs[tblno] == NULL) + ERREXIT1(dstinfo, JERR_NO_QUANT_TABLE, tblno); + slot_quant = srcinfo->quant_tbl_ptrs[tblno]; + c_quant = incomp->quant_table; + if (c_quant != NULL) { + for (coefi = 0; coefi < DCTSIZE2; coefi++) { + if (c_quant->quantval[coefi] != slot_quant->quantval[coefi]) + ERREXIT1(dstinfo, JERR_MISMATCHED_QUANT_TABLE, tblno); + } + } + /* Note: we do not copy the source's Huffman table assignments; + * instead we rely on jpeg_set_colorspace to have made a suitable choice. + */ + } + /* Also copy JFIF version and resolution information, if available. + * Strictly speaking this isn't "critical" info, but it's nearly + * always appropriate to copy it if available. In particular, + * if the application chooses to copy JFIF 1.02 extension markers from + * the source file, we need to copy the version to make sure we don't + * emit a file that has 1.02 extensions but a claimed version of 1.01. + * We will *not*, however, copy version info from mislabeled "2.01" files. + */ + if (srcinfo->saw_JFIF_marker) { + if (srcinfo->JFIF_major_version == 1) { + dstinfo->JFIF_major_version = srcinfo->JFIF_major_version; + dstinfo->JFIF_minor_version = srcinfo->JFIF_minor_version; + } + dstinfo->density_unit = srcinfo->density_unit; + dstinfo->X_density = srcinfo->X_density; + dstinfo->Y_density = srcinfo->Y_density; + } +} + + +/* + * Master selection of compression modules for transcoding. + * This substitutes for jcinit.c's initialization of the full compressor. + */ + +LOCAL(void) +transencode_master_selection (j_compress_ptr cinfo, + jvirt_barray_ptr * coef_arrays) +{ + /* Although we don't actually use input_components for transcoding, + * jcmaster.c's initial_setup will complain if input_components is 0. + */ + cinfo->input_components = 1; + /* Initialize master control (includes parameter checking/processing) */ + jinit_c_master_control(cinfo, TRUE /* transcode only */); + + /* Entropy encoding: either Huffman or arithmetic coding. */ + if (cinfo->arith_code) { + ERREXIT(cinfo, JERR_ARITH_NOTIMPL); + } else { + if (cinfo->progressive_mode) { +#ifdef C_PROGRESSIVE_SUPPORTED + jinit_phuff_encoder(cinfo); +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } else + jinit_huff_encoder(cinfo); + } + + /* We need a special coefficient buffer controller. */ + transencode_coef_controller(cinfo, coef_arrays); + + jinit_marker_writer(cinfo); + + /* We can now tell the memory manager to allocate virtual arrays. */ + (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo); + + /* Write the datastream header (SOI, JFIF) immediately. + * Frame and scan headers are postponed till later. + * This lets application insert special markers after the SOI. + */ + (*cinfo->marker->write_file_header) (cinfo); +} + + +/* + * The rest of this file is a special implementation of the coefficient + * buffer controller. This is similar to jccoefct.c, but it handles only + * output from presupplied virtual arrays. Furthermore, we generate any + * dummy padding blocks on-the-fly rather than expecting them to be present + * in the arrays. + */ + +/* Private buffer controller object */ + +typedef struct { + struct jpeg_c_coef_controller pub; /* public fields */ + + JDIMENSION iMCU_row_num; /* iMCU row # within image */ + JDIMENSION mcu_ctr; /* counts MCUs processed in current row */ + int MCU_vert_offset; /* counts MCU rows within iMCU row */ + int MCU_rows_per_iMCU_row; /* number of such rows needed */ + + /* Virtual block array for each component. */ + jvirt_barray_ptr * whole_image; + + /* Workspace for constructing dummy blocks at right/bottom edges. */ + JBLOCKROW dummy_buffer[C_MAX_BLOCKS_IN_MCU]; +} my_coef_controller; + +typedef my_coef_controller * my_coef_ptr; + + +LOCAL(void) +start_iMCU_row (j_compress_ptr cinfo) +/* Reset within-iMCU-row counters for a new row */ +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + + /* In an interleaved scan, an MCU row is the same as an iMCU row. + * In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows. + * But at the bottom of the image, process only what's left. + */ + if (cinfo->comps_in_scan > 1) { + coef->MCU_rows_per_iMCU_row = 1; + } else { + if (coef->iMCU_row_num < (cinfo->total_iMCU_rows-1)) + coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor; + else + coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height; + } + + coef->mcu_ctr = 0; + coef->MCU_vert_offset = 0; +} + + +/* + * Initialize for a processing pass. + */ + +METHODDEF(void) +start_pass_coef (j_compress_ptr cinfo, J_BUF_MODE pass_mode) +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + + if (pass_mode != JBUF_CRANK_DEST) + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + + coef->iMCU_row_num = 0; + start_iMCU_row(cinfo); +} + + +/* + * Process some data. + * We process the equivalent of one fully interleaved MCU row ("iMCU" row) + * per call, ie, v_samp_factor block rows for each component in the scan. + * The data is obtained from the virtual arrays and fed to the entropy coder. + * Returns TRUE if the iMCU row is completed, FALSE if suspended. + * + * NB: input_buf is ignored; it is likely to be a NULL pointer. + */ + +METHODDEF(boolean) +compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf) +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + JDIMENSION MCU_col_num; /* index of current MCU within row */ + JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1; + JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1; + int blkn, ci, xindex, yindex, yoffset, blockcnt; + JDIMENSION start_col; + JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN]; + JBLOCKROW MCU_buffer[C_MAX_BLOCKS_IN_MCU]; + JBLOCKROW buffer_ptr; + jpeg_component_info *compptr; + + /* Align the virtual buffers for the components used in this scan. */ + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + buffer[ci] = (*cinfo->mem->access_virt_barray) + ((j_common_ptr) cinfo, coef->whole_image[compptr->component_index], + coef->iMCU_row_num * compptr->v_samp_factor, + (JDIMENSION) compptr->v_samp_factor, FALSE); + } + + /* Loop to process one whole iMCU row */ + for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row; + yoffset++) { + for (MCU_col_num = coef->mcu_ctr; MCU_col_num < cinfo->MCUs_per_row; + MCU_col_num++) { + /* Construct list of pointers to DCT blocks belonging to this MCU */ + blkn = 0; /* index of current DCT block within MCU */ + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + start_col = MCU_col_num * compptr->MCU_width; + blockcnt = (MCU_col_num < last_MCU_col) ? compptr->MCU_width + : compptr->last_col_width; + for (yindex = 0; yindex < compptr->MCU_height; yindex++) { + if (coef->iMCU_row_num < last_iMCU_row || + yindex+yoffset < compptr->last_row_height) { + /* Fill in pointers to real blocks in this row */ + buffer_ptr = buffer[ci][yindex+yoffset] + start_col; + for (xindex = 0; xindex < blockcnt; xindex++) + MCU_buffer[blkn++] = buffer_ptr++; + } else { + /* At bottom of image, need a whole row of dummy blocks */ + xindex = 0; + } + /* Fill in any dummy blocks needed in this row. + * Dummy blocks are filled in the same way as in jccoefct.c: + * all zeroes in the AC entries, DC entries equal to previous + * block's DC value. The init routine has already zeroed the + * AC entries, so we need only set the DC entries correctly. + */ + for (; xindex < compptr->MCU_width; xindex++) { + MCU_buffer[blkn] = coef->dummy_buffer[blkn]; + MCU_buffer[blkn][0][0] = MCU_buffer[blkn-1][0][0]; + blkn++; + } + } + } + /* Try to write the MCU. */ + if (! (*cinfo->entropy->encode_mcu) (cinfo, MCU_buffer)) { + /* Suspension forced; update state counters and exit */ + coef->MCU_vert_offset = yoffset; + coef->mcu_ctr = MCU_col_num; + return FALSE; + } + } + /* Completed an MCU row, but perhaps not an iMCU row */ + coef->mcu_ctr = 0; + } + /* Completed the iMCU row, advance counters for next one */ + coef->iMCU_row_num++; + start_iMCU_row(cinfo); + return TRUE; +} + + +/* + * Initialize coefficient buffer controller. + * + * Each passed coefficient array must be the right size for that + * coefficient: width_in_blocks wide and height_in_blocks high, + * with unitheight at least v_samp_factor. + */ + +LOCAL(void) +transencode_coef_controller (j_compress_ptr cinfo, + jvirt_barray_ptr * coef_arrays) +{ + my_coef_ptr coef; + JBLOCKROW buffer; + int i; + + coef = (my_coef_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_coef_controller)); + cinfo->coef = (struct jpeg_c_coef_controller *) coef; + coef->pub.start_pass = start_pass_coef; + coef->pub.compress_data = compress_output; + + /* Save pointer to virtual arrays */ + coef->whole_image = coef_arrays; + + /* Allocate and pre-zero space for dummy DCT blocks. */ + buffer = (JBLOCKROW) + (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE, + C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK)); + jzero_far((void FAR *) buffer, C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK)); + for (i = 0; i < C_MAX_BLOCKS_IN_MCU; i++) { + coef->dummy_buffer[i] = buffer + i; + } +} diff --git a/mod/pub.mod/libjpeg.mod/jdapimin.c b/mod/pub.mod/libjpeg.mod/jdapimin.c new file mode 100644 index 0000000..cadb59f --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jdapimin.c @@ -0,0 +1,395 @@ +/* + * jdapimin.c + * + * Copyright (C) 1994-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains application interface code for the decompression half + * of the JPEG library. These are the "minimum" API routines that may be + * needed in either the normal full-decompression case or the + * transcoding-only case. + * + * Most of the routines intended to be called directly by an application + * are in this file or in jdapistd.c. But also see jcomapi.c for routines + * shared by compression and decompression, and jdtrans.c for the transcoding + * case. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* + * Initialization of a JPEG decompression object. + * The error manager must already be set up (in case memory manager fails). + */ + +GLOBAL(void) +jpeg_CreateDecompress (j_decompress_ptr cinfo, int version, size_t structsize) +{ + int i; + + /* Guard against version mismatches between library and caller. */ + cinfo->mem = NULL; /* so jpeg_destroy knows mem mgr not called */ + if (version != JPEG_LIB_VERSION) + ERREXIT2(cinfo, JERR_BAD_LIB_VERSION, JPEG_LIB_VERSION, version); + if (structsize != SIZEOF(struct jpeg_decompress_struct)) + ERREXIT2(cinfo, JERR_BAD_STRUCT_SIZE, + (int) SIZEOF(struct jpeg_decompress_struct), (int) structsize); + + /* For debugging purposes, we zero the whole master structure. + * But the application has already set the err pointer, and may have set + * client_data, so we have to save and restore those fields. + * Note: if application hasn't set client_data, tools like Purify may + * complain here. + */ + { + struct jpeg_error_mgr * err = cinfo->err; + void * client_data = cinfo->client_data; /* ignore Purify complaint here */ + MEMZERO(cinfo, SIZEOF(struct jpeg_decompress_struct)); + cinfo->err = err; + cinfo->client_data = client_data; + } + cinfo->is_decompressor = TRUE; + + /* Initialize a memory manager instance for this object */ + jinit_memory_mgr((j_common_ptr) cinfo); + + /* Zero out pointers to permanent structures. */ + cinfo->progress = NULL; + cinfo->src = NULL; + + for (i = 0; i < NUM_QUANT_TBLS; i++) + cinfo->quant_tbl_ptrs[i] = NULL; + + for (i = 0; i < NUM_HUFF_TBLS; i++) { + cinfo->dc_huff_tbl_ptrs[i] = NULL; + cinfo->ac_huff_tbl_ptrs[i] = NULL; + } + + /* Initialize marker processor so application can override methods + * for COM, APPn markers before calling jpeg_read_header. + */ + cinfo->marker_list = NULL; + jinit_marker_reader(cinfo); + + /* And initialize the overall input controller. */ + jinit_input_controller(cinfo); + + /* OK, I'm ready */ + cinfo->global_state = DSTATE_START; +} + + +/* + * Destruction of a JPEG decompression object + */ + +GLOBAL(void) +jpeg_destroy_decompress (j_decompress_ptr cinfo) +{ + jpeg_destroy((j_common_ptr) cinfo); /* use common routine */ +} + + +/* + * Abort processing of a JPEG decompression operation, + * but don't destroy the object itself. + */ + +GLOBAL(void) +jpeg_abort_decompress (j_decompress_ptr cinfo) +{ + jpeg_abort((j_common_ptr) cinfo); /* use common routine */ +} + + +/* + * Set default decompression parameters. + */ + +LOCAL(void) +default_decompress_parms (j_decompress_ptr cinfo) +{ + /* Guess the input colorspace, and set output colorspace accordingly. */ + /* (Wish JPEG committee had provided a real way to specify this...) */ + /* Note application may override our guesses. */ + switch (cinfo->num_components) { + case 1: + cinfo->jpeg_color_space = JCS_GRAYSCALE; + cinfo->out_color_space = JCS_GRAYSCALE; + break; + + case 3: + if (cinfo->saw_JFIF_marker) { + cinfo->jpeg_color_space = JCS_YCbCr; /* JFIF implies YCbCr */ + } else if (cinfo->saw_Adobe_marker) { + switch (cinfo->Adobe_transform) { + case 0: + cinfo->jpeg_color_space = JCS_RGB; + break; + case 1: + cinfo->jpeg_color_space = JCS_YCbCr; + break; + default: + WARNMS1(cinfo, JWRN_ADOBE_XFORM, cinfo->Adobe_transform); + cinfo->jpeg_color_space = JCS_YCbCr; /* assume it's YCbCr */ + break; + } + } else { + /* Saw no special markers, try to guess from the component IDs */ + int cid0 = cinfo->comp_info[0].component_id; + int cid1 = cinfo->comp_info[1].component_id; + int cid2 = cinfo->comp_info[2].component_id; + + if (cid0 == 1 && cid1 == 2 && cid2 == 3) + cinfo->jpeg_color_space = JCS_YCbCr; /* assume JFIF w/out marker */ + else if (cid0 == 82 && cid1 == 71 && cid2 == 66) + cinfo->jpeg_color_space = JCS_RGB; /* ASCII 'R', 'G', 'B' */ + else { + TRACEMS3(cinfo, 1, JTRC_UNKNOWN_IDS, cid0, cid1, cid2); + cinfo->jpeg_color_space = JCS_YCbCr; /* assume it's YCbCr */ + } + } + /* Always guess RGB is proper output colorspace. */ + cinfo->out_color_space = JCS_RGB; + break; + + case 4: + if (cinfo->saw_Adobe_marker) { + switch (cinfo->Adobe_transform) { + case 0: + cinfo->jpeg_color_space = JCS_CMYK; + break; + case 2: + cinfo->jpeg_color_space = JCS_YCCK; + break; + default: + WARNMS1(cinfo, JWRN_ADOBE_XFORM, cinfo->Adobe_transform); + cinfo->jpeg_color_space = JCS_YCCK; /* assume it's YCCK */ + break; + } + } else { + /* No special markers, assume straight CMYK. */ + cinfo->jpeg_color_space = JCS_CMYK; + } + cinfo->out_color_space = JCS_CMYK; + break; + + default: + cinfo->jpeg_color_space = JCS_UNKNOWN; + cinfo->out_color_space = JCS_UNKNOWN; + break; + } + + /* Set defaults for other decompression parameters. */ + cinfo->scale_num = 1; /* 1:1 scaling */ + cinfo->scale_denom = 1; + cinfo->output_gamma = 1.0; + cinfo->buffered_image = FALSE; + cinfo->raw_data_out = FALSE; + cinfo->dct_method = JDCT_DEFAULT; + cinfo->do_fancy_upsampling = TRUE; + cinfo->do_block_smoothing = TRUE; + cinfo->quantize_colors = FALSE; + /* We set these in case application only sets quantize_colors. */ + cinfo->dither_mode = JDITHER_FS; +#ifdef QUANT_2PASS_SUPPORTED + cinfo->two_pass_quantize = TRUE; +#else + cinfo->two_pass_quantize = FALSE; +#endif + cinfo->desired_number_of_colors = 256; + cinfo->colormap = NULL; + /* Initialize for no mode change in buffered-image mode. */ + cinfo->enable_1pass_quant = FALSE; + cinfo->enable_external_quant = FALSE; + cinfo->enable_2pass_quant = FALSE; +} + + +/* + * Decompression startup: read start of JPEG datastream to see what's there. + * Need only initialize JPEG object and supply a data source before calling. + * + * This routine will read as far as the first SOS marker (ie, actual start of + * compressed data), and will save all tables and parameters in the JPEG + * object. It will also initialize the decompression parameters to default + * values, and finally return JPEG_HEADER_OK. On return, the application may + * adjust the decompression parameters and then call jpeg_start_decompress. + * (Or, if the application only wanted to determine the image parameters, + * the data need not be decompressed. In that case, call jpeg_abort or + * jpeg_destroy to release any temporary space.) + * If an abbreviated (tables only) datastream is presented, the routine will + * return JPEG_HEADER_TABLES_ONLY upon reaching EOI. The application may then + * re-use the JPEG object to read the abbreviated image datastream(s). + * It is unnecessary (but OK) to call jpeg_abort in this case. + * The JPEG_SUSPENDED return code only occurs if the data source module + * requests suspension of the decompressor. In this case the application + * should load more source data and then re-call jpeg_read_header to resume + * processing. + * If a non-suspending data source is used and require_image is TRUE, then the + * return code need not be inspected since only JPEG_HEADER_OK is possible. + * + * This routine is now just a front end to jpeg_consume_input, with some + * extra error checking. + */ + +GLOBAL(int) +jpeg_read_header (j_decompress_ptr cinfo, boolean require_image) +{ + int retcode; + + if (cinfo->global_state != DSTATE_START && + cinfo->global_state != DSTATE_INHEADER) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + + retcode = jpeg_consume_input(cinfo); + + switch (retcode) { + case JPEG_REACHED_SOS: + retcode = JPEG_HEADER_OK; + break; + case JPEG_REACHED_EOI: + if (require_image) /* Complain if application wanted an image */ + ERREXIT(cinfo, JERR_NO_IMAGE); + /* Reset to start state; it would be safer to require the application to + * call jpeg_abort, but we can't change it now for compatibility reasons. + * A side effect is to free any temporary memory (there shouldn't be any). + */ + jpeg_abort((j_common_ptr) cinfo); /* sets state = DSTATE_START */ + retcode = JPEG_HEADER_TABLES_ONLY; + break; + case JPEG_SUSPENDED: + /* no work */ + break; + } + + return retcode; +} + + +/* + * Consume data in advance of what the decompressor requires. + * This can be called at any time once the decompressor object has + * been created and a data source has been set up. + * + * This routine is essentially a state machine that handles a couple + * of critical state-transition actions, namely initial setup and + * transition from header scanning to ready-for-start_decompress. + * All the actual input is done via the input controller's consume_input + * method. + */ + +GLOBAL(int) +jpeg_consume_input (j_decompress_ptr cinfo) +{ + int retcode = JPEG_SUSPENDED; + + /* NB: every possible DSTATE value should be listed in this switch */ + switch (cinfo->global_state) { + case DSTATE_START: + /* Start-of-datastream actions: reset appropriate modules */ + (*cinfo->inputctl->reset_input_controller) (cinfo); + /* Initialize application's data source module */ + (*cinfo->src->init_source) (cinfo); + cinfo->global_state = DSTATE_INHEADER; + /*FALLTHROUGH*/ + case DSTATE_INHEADER: + retcode = (*cinfo->inputctl->consume_input) (cinfo); + if (retcode == JPEG_REACHED_SOS) { /* Found SOS, prepare to decompress */ + /* Set up default parameters based on header data */ + default_decompress_parms(cinfo); + /* Set global state: ready for start_decompress */ + cinfo->global_state = DSTATE_READY; + } + break; + case DSTATE_READY: + /* Can't advance past first SOS until start_decompress is called */ + retcode = JPEG_REACHED_SOS; + break; + case DSTATE_PRELOAD: + case DSTATE_PRESCAN: + case DSTATE_SCANNING: + case DSTATE_RAW_OK: + case DSTATE_BUFIMAGE: + case DSTATE_BUFPOST: + case DSTATE_STOPPING: + retcode = (*cinfo->inputctl->consume_input) (cinfo); + break; + default: + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + } + return retcode; +} + + +/* + * Have we finished reading the input file? + */ + +GLOBAL(boolean) +jpeg_input_complete (j_decompress_ptr cinfo) +{ + /* Check for valid jpeg object */ + if (cinfo->global_state < DSTATE_START || + cinfo->global_state > DSTATE_STOPPING) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + return cinfo->inputctl->eoi_reached; +} + + +/* + * Is there more than one scan? + */ + +GLOBAL(boolean) +jpeg_has_multiple_scans (j_decompress_ptr cinfo) +{ + /* Only valid after jpeg_read_header completes */ + if (cinfo->global_state < DSTATE_READY || + cinfo->global_state > DSTATE_STOPPING) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + return cinfo->inputctl->has_multiple_scans; +} + + +/* + * Finish JPEG decompression. + * + * This will normally just verify the file trailer and release temp storage. + * + * Returns FALSE if suspended. The return value need be inspected only if + * a suspending data source is used. + */ + +GLOBAL(boolean) +jpeg_finish_decompress (j_decompress_ptr cinfo) +{ + if ((cinfo->global_state == DSTATE_SCANNING || + cinfo->global_state == DSTATE_RAW_OK) && ! cinfo->buffered_image) { + /* Terminate final pass of non-buffered mode */ + if (cinfo->output_scanline < cinfo->output_height) + ERREXIT(cinfo, JERR_TOO_LITTLE_DATA); + (*cinfo->master->finish_output_pass) (cinfo); + cinfo->global_state = DSTATE_STOPPING; + } else if (cinfo->global_state == DSTATE_BUFIMAGE) { + /* Finishing after a buffered-image operation */ + cinfo->global_state = DSTATE_STOPPING; + } else if (cinfo->global_state != DSTATE_STOPPING) { + /* STOPPING = repeat call after a suspension, anything else is error */ + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + } + /* Read until EOI */ + while (! cinfo->inputctl->eoi_reached) { + if ((*cinfo->inputctl->consume_input) (cinfo) == JPEG_SUSPENDED) + return FALSE; /* Suspend, come back later */ + } + /* Do final cleanup */ + (*cinfo->src->term_source) (cinfo); + /* We can use jpeg_abort to release memory and reset global_state */ + jpeg_abort((j_common_ptr) cinfo); + return TRUE; +} diff --git a/mod/pub.mod/libjpeg.mod/jdapistd.c b/mod/pub.mod/libjpeg.mod/jdapistd.c new file mode 100644 index 0000000..c8e3fa0 --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jdapistd.c @@ -0,0 +1,275 @@ +/* + * jdapistd.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains application interface code for the decompression half + * of the JPEG library. These are the "standard" API routines that are + * used in the normal full-decompression case. They are not used by a + * transcoding-only application. Note that if an application links in + * jpeg_start_decompress, it will end up linking in the entire decompressor. + * We thus must separate this file from jdapimin.c to avoid linking the + * whole decompression library into a transcoder. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* Forward declarations */ +LOCAL(boolean) output_pass_setup JPP((j_decompress_ptr cinfo)); + + +/* + * Decompression initialization. + * jpeg_read_header must be completed before calling this. + * + * If a multipass operating mode was selected, this will do all but the + * last pass, and thus may take a great deal of time. + * + * Returns FALSE if suspended. The return value need be inspected only if + * a suspending data source is used. + */ + +GLOBAL(boolean) +jpeg_start_decompress (j_decompress_ptr cinfo) +{ + if (cinfo->global_state == DSTATE_READY) { + /* First call: initialize master control, select active modules */ + jinit_master_decompress(cinfo); + if (cinfo->buffered_image) { + /* No more work here; expecting jpeg_start_output next */ + cinfo->global_state = DSTATE_BUFIMAGE; + return TRUE; + } + cinfo->global_state = DSTATE_PRELOAD; + } + if (cinfo->global_state == DSTATE_PRELOAD) { + /* If file has multiple scans, absorb them all into the coef buffer */ + if (cinfo->inputctl->has_multiple_scans) { +#ifdef D_MULTISCAN_FILES_SUPPORTED + for (;;) { + int retcode; + /* Call progress monitor hook if present */ + if (cinfo->progress != NULL) + (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); + /* Absorb some more input */ + retcode = (*cinfo->inputctl->consume_input) (cinfo); + if (retcode == JPEG_SUSPENDED) + return FALSE; + if (retcode == JPEG_REACHED_EOI) + break; + /* Advance progress counter if appropriate */ + if (cinfo->progress != NULL && + (retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) { + if (++cinfo->progress->pass_counter >= cinfo->progress->pass_limit) { + /* jdmaster underestimated number of scans; ratchet up one scan */ + cinfo->progress->pass_limit += (long) cinfo->total_iMCU_rows; + } + } + } +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif /* D_MULTISCAN_FILES_SUPPORTED */ + } + cinfo->output_scan_number = cinfo->input_scan_number; + } else if (cinfo->global_state != DSTATE_PRESCAN) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + /* Perform any dummy output passes, and set up for the final pass */ + return output_pass_setup(cinfo); +} + + +/* + * Set up for an output pass, and perform any dummy pass(es) needed. + * Common subroutine for jpeg_start_decompress and jpeg_start_output. + * Entry: global_state = DSTATE_PRESCAN only if previously suspended. + * Exit: If done, returns TRUE and sets global_state for proper output mode. + * If suspended, returns FALSE and sets global_state = DSTATE_PRESCAN. + */ + +LOCAL(boolean) +output_pass_setup (j_decompress_ptr cinfo) +{ + if (cinfo->global_state != DSTATE_PRESCAN) { + /* First call: do pass setup */ + (*cinfo->master->prepare_for_output_pass) (cinfo); + cinfo->output_scanline = 0; + cinfo->global_state = DSTATE_PRESCAN; + } + /* Loop over any required dummy passes */ + while (cinfo->master->is_dummy_pass) { +#ifdef QUANT_2PASS_SUPPORTED + /* Crank through the dummy pass */ + while (cinfo->output_scanline < cinfo->output_height) { + JDIMENSION last_scanline; + /* Call progress monitor hook if present */ + if (cinfo->progress != NULL) { + cinfo->progress->pass_counter = (long) cinfo->output_scanline; + cinfo->progress->pass_limit = (long) cinfo->output_height; + (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); + } + /* Process some data */ + last_scanline = cinfo->output_scanline; + (*cinfo->main->process_data) (cinfo, (JSAMPARRAY) NULL, + &cinfo->output_scanline, (JDIMENSION) 0); + if (cinfo->output_scanline == last_scanline) + return FALSE; /* No progress made, must suspend */ + } + /* Finish up dummy pass, and set up for another one */ + (*cinfo->master->finish_output_pass) (cinfo); + (*cinfo->master->prepare_for_output_pass) (cinfo); + cinfo->output_scanline = 0; +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif /* QUANT_2PASS_SUPPORTED */ + } + /* Ready for application to drive output pass through + * jpeg_read_scanlines or jpeg_read_raw_data. + */ + cinfo->global_state = cinfo->raw_data_out ? DSTATE_RAW_OK : DSTATE_SCANNING; + return TRUE; +} + + +/* + * Read some scanlines of data from the JPEG decompressor. + * + * The return value will be the number of lines actually read. + * This may be less than the number requested in several cases, + * including bottom of image, data source suspension, and operating + * modes that emit multiple scanlines at a time. + * + * Note: we warn about excess calls to jpeg_read_scanlines() since + * this likely signals an application programmer error. However, + * an oversize buffer (max_lines > scanlines remaining) is not an error. + */ + +GLOBAL(JDIMENSION) +jpeg_read_scanlines (j_decompress_ptr cinfo, JSAMPARRAY scanlines, + JDIMENSION max_lines) +{ + JDIMENSION row_ctr; + + if (cinfo->global_state != DSTATE_SCANNING) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + if (cinfo->output_scanline >= cinfo->output_height) { + WARNMS(cinfo, JWRN_TOO_MUCH_DATA); + return 0; + } + + /* Call progress monitor hook if present */ + if (cinfo->progress != NULL) { + cinfo->progress->pass_counter = (long) cinfo->output_scanline; + cinfo->progress->pass_limit = (long) cinfo->output_height; + (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); + } + + /* Process some data */ + row_ctr = 0; + (*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, max_lines); + cinfo->output_scanline += row_ctr; + return row_ctr; +} + + +/* + * Alternate entry point to read raw data. + * Processes exactly one iMCU row per call, unless suspended. + */ + +GLOBAL(JDIMENSION) +jpeg_read_raw_data (j_decompress_ptr cinfo, JSAMPIMAGE data, + JDIMENSION max_lines) +{ + JDIMENSION lines_per_iMCU_row; + + if (cinfo->global_state != DSTATE_RAW_OK) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + if (cinfo->output_scanline >= cinfo->output_height) { + WARNMS(cinfo, JWRN_TOO_MUCH_DATA); + return 0; + } + + /* Call progress monitor hook if present */ + if (cinfo->progress != NULL) { + cinfo->progress->pass_counter = (long) cinfo->output_scanline; + cinfo->progress->pass_limit = (long) cinfo->output_height; + (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); + } + + /* Verify that at least one iMCU row can be returned. */ + lines_per_iMCU_row = cinfo->max_v_samp_factor * cinfo->min_DCT_scaled_size; + if (max_lines < lines_per_iMCU_row) + ERREXIT(cinfo, JERR_BUFFER_SIZE); + + /* Decompress directly into user's buffer. */ + if (! (*cinfo->coef->decompress_data) (cinfo, data)) + return 0; /* suspension forced, can do nothing more */ + + /* OK, we processed one iMCU row. */ + cinfo->output_scanline += lines_per_iMCU_row; + return lines_per_iMCU_row; +} + + +/* Additional entry points for buffered-image mode. */ + +#ifdef D_MULTISCAN_FILES_SUPPORTED + +/* + * Initialize for an output pass in buffered-image mode. + */ + +GLOBAL(boolean) +jpeg_start_output (j_decompress_ptr cinfo, int scan_number) +{ + if (cinfo->global_state != DSTATE_BUFIMAGE && + cinfo->global_state != DSTATE_PRESCAN) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + /* Limit scan number to valid range */ + if (scan_number <= 0) + scan_number = 1; + if (cinfo->inputctl->eoi_reached && + scan_number > cinfo->input_scan_number) + scan_number = cinfo->input_scan_number; + cinfo->output_scan_number = scan_number; + /* Perform any dummy output passes, and set up for the real pass */ + return output_pass_setup(cinfo); +} + + +/* + * Finish up after an output pass in buffered-image mode. + * + * Returns FALSE if suspended. The return value need be inspected only if + * a suspending data source is used. + */ + +GLOBAL(boolean) +jpeg_finish_output (j_decompress_ptr cinfo) +{ + if ((cinfo->global_state == DSTATE_SCANNING || + cinfo->global_state == DSTATE_RAW_OK) && cinfo->buffered_image) { + /* Terminate this pass. */ + /* We do not require the whole pass to have been completed. */ + (*cinfo->master->finish_output_pass) (cinfo); + cinfo->global_state = DSTATE_BUFPOST; + } else if (cinfo->global_state != DSTATE_BUFPOST) { + /* BUFPOST = repeat call after a suspension, anything else is error */ + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + } + /* Read markers looking for SOS or EOI */ + while (cinfo->input_scan_number <= cinfo->output_scan_number && + ! cinfo->inputctl->eoi_reached) { + if ((*cinfo->inputctl->consume_input) (cinfo) == JPEG_SUSPENDED) + return FALSE; /* Suspend, come back later */ + } + cinfo->global_state = DSTATE_BUFIMAGE; + return TRUE; +} + +#endif /* D_MULTISCAN_FILES_SUPPORTED */ diff --git a/mod/pub.mod/libjpeg.mod/jdatadst.c b/mod/pub.mod/libjpeg.mod/jdatadst.c new file mode 100644 index 0000000..ea0a830 --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jdatadst.c @@ -0,0 +1,152 @@ +/* + * jdatadst.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains compression data destination routines for the case of + * emitting JPEG data to a file (or any stdio stream). While these routines + * are sufficient for most applications, some will want to use a different + * destination manager. + * IMPORTANT: we assume that fwrite() will correctly transcribe an array of + * JOCTETs into 8-bit-wide elements on external storage. If char is wider + * than 8 bits on your machine, you may need to do some tweaking. + */ + +/* this is not a core library module, so it doesn't define JPEG_INTERNALS */ +#include "jinclude.h" +#include "jpeglib.h" +#include "jerror.h" + + +/* Expanded data destination object for stdio output */ + +typedef struct { + struct jpeg_destination_mgr pub; /* public fields */ + + FILE * outfile; /* target stream */ + JOCTET * buffer; /* start of buffer */ +} my_destination_mgr; + +typedef my_destination_mgr * my_dest_ptr; + +#define OUTPUT_BUF_SIZE 4096 /* choose an efficiently fwrite'able size */ + + +/* + * Initialize destination --- called by jpeg_start_compress + * before any data is actually written. + */ + +METHODDEF(void) +init_destination (j_compress_ptr cinfo) +{ + my_dest_ptr dest = (my_dest_ptr) cinfo->dest; + + /* Allocate the output buffer --- it will be released when done with image */ + dest->buffer = (JOCTET *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + OUTPUT_BUF_SIZE * SIZEOF(JOCTET)); + + dest->pub.next_output_byte = dest->buffer; + dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; +} + + +/* + * Empty the output buffer --- called whenever buffer fills up. + * + * In typical applications, this should write the entire output buffer + * (ignoring the current state of next_output_byte & free_in_buffer), + * reset the pointer & count to the start of the buffer, and return TRUE + * indicating that the buffer has been dumped. + * + * In applications that need to be able to suspend compression due to output + * overrun, a FALSE return indicates that the buffer cannot be emptied now. + * In this situation, the compressor will return to its caller (possibly with + * an indication that it has not accepted all the supplied scanlines). The + * application should resume compression after it has made more room in the + * output buffer. Note that there are substantial restrictions on the use of + * suspension --- see the documentation. + * + * When suspending, the compressor will back up to a convenient restart point + * (typically the start of the current MCU). next_output_byte & free_in_buffer + * indicate where the restart point will be if the current call returns FALSE. + * Data beyond this point will be regenerated after resumption, so do not + * write it out when emptying the buffer externally. + */ + +METHODDEF(boolean) +empty_output_buffer (j_compress_ptr cinfo) +{ + my_dest_ptr dest = (my_dest_ptr) cinfo->dest; + + if (JFWRITE(dest->outfile, dest->buffer, OUTPUT_BUF_SIZE) != + (size_t) OUTPUT_BUF_SIZE) + ERREXIT(cinfo, JERR_FILE_WRITE); + + dest->pub.next_output_byte = dest->buffer; + dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; + + return TRUE; +} + + +/* + * Terminate destination --- called by jpeg_finish_compress + * after all data has been written. Usually needs to flush buffer. + * + * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding + * application must deal with any cleanup that should happen even + * for error exit. + */ + +METHODDEF(void) +term_destination (j_compress_ptr cinfo) +{ + my_dest_ptr dest = (my_dest_ptr) cinfo->dest; + size_t datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer; + + /* Write any data remaining in the buffer */ + if (datacount > 0) { + if (JFWRITE(dest->outfile, dest->buffer, datacount) != datacount) + ERREXIT(cinfo, JERR_FILE_WRITE); + } +// simon was here, oh for f's sake... +// fflush(dest->outfile); +/* Make sure we wrote the output file OK */ +// if (ferror(dest->outfile)) +// ERREXIT(cinfo, JERR_FILE_WRITE); +} + + +/* + * Prepare for output to a stdio stream. + * The caller must have already opened the stream, and is responsible + * for closing it after finishing compression. + */ + +GLOBAL(void) +jpeg_stdio_dest (j_compress_ptr cinfo, FILE * outfile) +{ + my_dest_ptr dest; + + /* The destination object is made permanent so that multiple JPEG images + * can be written to the same file without re-executing jpeg_stdio_dest. + * This makes it dangerous to use this manager and a different destination + * manager serially with the same JPEG object, because their private object + * sizes may be different. Caveat programmer. + */ + if (cinfo->dest == NULL) { /* first time for this JPEG object? */ + cinfo->dest = (struct jpeg_destination_mgr *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, + SIZEOF(my_destination_mgr)); + } + + dest = (my_dest_ptr) cinfo->dest; + dest->pub.init_destination = init_destination; + dest->pub.empty_output_buffer = empty_output_buffer; + dest->pub.term_destination = term_destination; + dest->outfile = outfile; +} diff --git a/mod/pub.mod/libjpeg.mod/jdatasrc.c b/mod/pub.mod/libjpeg.mod/jdatasrc.c new file mode 100644 index 0000000..edc752b --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jdatasrc.c @@ -0,0 +1,212 @@ +/* + * jdatasrc.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains decompression data source routines for the case of + * reading JPEG data from a file (or any stdio stream). While these routines + * are sufficient for most applications, some will want to use a different + * source manager. + * IMPORTANT: we assume that fread() will correctly transcribe an array of + * JOCTETs from 8-bit-wide elements on external storage. If char is wider + * than 8 bits on your machine, you may need to do some tweaking. + */ + +/* this is not a core library module, so it doesn't define JPEG_INTERNALS */ +#include "jinclude.h" +#include "jpeglib.h" +#include "jerror.h" + + +/* Expanded data source object for stdio input */ + +typedef struct { + struct jpeg_source_mgr pub; /* public fields */ + + FILE * infile; /* source stream */ + JOCTET * buffer; /* start of buffer */ + boolean start_of_file; /* have we gotten any data yet? */ +} my_source_mgr; + +typedef my_source_mgr * my_src_ptr; + +#define INPUT_BUF_SIZE 4096 /* choose an efficiently fread'able size */ + + +/* + * Initialize source --- called by jpeg_read_header + * before any data is actually read. + */ + +METHODDEF(void) +init_source (j_decompress_ptr cinfo) +{ + my_src_ptr src = (my_src_ptr) cinfo->src; + + /* We reset the empty-input-file flag for each image, + * but we don't clear the input buffer. + * This is correct behavior for reading a series of images from one source. + */ + src->start_of_file = TRUE; +} + + +/* + * Fill the input buffer --- called whenever buffer is emptied. + * + * In typical applications, this should read fresh data into the buffer + * (ignoring the current state of next_input_byte & bytes_in_buffer), + * reset the pointer & count to the start of the buffer, and return TRUE + * indicating that the buffer has been reloaded. It is not necessary to + * fill the buffer entirely, only to obtain at least one more byte. + * + * There is no such thing as an EOF return. If the end of the file has been + * reached, the routine has a choice of ERREXIT() or inserting fake data into + * the buffer. In most cases, generating a warning message and inserting a + * fake EOI marker is the best course of action --- this will allow the + * decompressor to output however much of the image is there. However, + * the resulting error message is misleading if the real problem is an empty + * input file, so we handle that case specially. + * + * In applications that need to be able to suspend compression due to input + * not being available yet, a FALSE return indicates that no more data can be + * obtained right now, but more may be forthcoming later. In this situation, + * the decompressor will return to its caller (with an indication of the + * number of scanlines it has read, if any). The application should resume + * decompression after it has loaded more data into the input buffer. Note + * that there are substantial restrictions on the use of suspension --- see + * the documentation. + * + * When suspending, the decompressor will back up to a convenient restart point + * (typically the start of the current MCU). next_input_byte & bytes_in_buffer + * indicate where the restart point will be if the current call returns FALSE. + * Data beyond this point must be rescanned after resumption, so move it to + * the front of the buffer rather than discarding it. + */ + +METHODDEF(boolean) +fill_input_buffer (j_decompress_ptr cinfo) +{ + my_src_ptr src = (my_src_ptr) cinfo->src; + size_t nbytes; + + nbytes = JFREAD(src->infile, src->buffer, INPUT_BUF_SIZE); + + if (nbytes <= 0) { + if (src->start_of_file) /* Treat empty input file as fatal error */ + ERREXIT(cinfo, JERR_INPUT_EMPTY); + WARNMS(cinfo, JWRN_JPEG_EOF); + /* Insert a fake EOI marker */ + src->buffer[0] = (JOCTET) 0xFF; + src->buffer[1] = (JOCTET) JPEG_EOI; + nbytes = 2; + } + + src->pub.next_input_byte = src->buffer; + src->pub.bytes_in_buffer = nbytes; + src->start_of_file = FALSE; + + return TRUE; +} + + +/* + * Skip data --- used to skip over a potentially large amount of + * uninteresting data (such as an APPn marker). + * + * Writers of suspendable-input applications must note that skip_input_data + * is not granted the right to give a suspension return. If the skip extends + * beyond the data currently in the buffer, the buffer can be marked empty so + * that the next read will cause a fill_input_buffer call that can suspend. + * Arranging for additional bytes to be discarded before reloading the input + * buffer is the application writer's problem. + */ + +METHODDEF(void) +skip_input_data (j_decompress_ptr cinfo, long num_bytes) +{ + my_src_ptr src = (my_src_ptr) cinfo->src; + + /* Just a dumb implementation for now. Could use fseek() except + * it doesn't work on pipes. Not clear that being smart is worth + * any trouble anyway --- large skips are infrequent. + */ + if (num_bytes > 0) { + while (num_bytes > (long) src->pub.bytes_in_buffer) { + num_bytes -= (long) src->pub.bytes_in_buffer; + (void) fill_input_buffer(cinfo); + /* note we assume that fill_input_buffer will never return FALSE, + * so suspension need not be handled. + */ + } + src->pub.next_input_byte += (size_t) num_bytes; + src->pub.bytes_in_buffer -= (size_t) num_bytes; + } +} + + +/* + * An additional method that can be provided by data source modules is the + * resync_to_restart method for error recovery in the presence of RST markers. + * For the moment, this source module just uses the default resync method + * provided by the JPEG library. That method assumes that no backtracking + * is possible. + */ + + +/* + * Terminate source --- called by jpeg_finish_decompress + * after all data has been read. Often a no-op. + * + * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding + * application must deal with any cleanup that should happen even + * for error exit. + */ + +METHODDEF(void) +term_source (j_decompress_ptr cinfo) +{ + /* no work necessary here */ +} + + +/* + * Prepare for input from a stdio stream. + * The caller must have already opened the stream, and is responsible + * for closing it after finishing decompression. + */ + +GLOBAL(void) +jpeg_stdio_src (j_decompress_ptr cinfo, FILE * infile) +{ + my_src_ptr src; + + /* The source object and input buffer are made permanent so that a series + * of JPEG images can be read from the same file by calling jpeg_stdio_src + * only before the first one. (If we discarded the buffer at the end of + * one image, we'd likely lose the start of the next one.) + * This makes it unsafe to use this manager and a different source + * manager serially with the same JPEG object. Caveat programmer. + */ + if (cinfo->src == NULL) { /* first time for this JPEG object? */ + cinfo->src = (struct jpeg_source_mgr *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, + SIZEOF(my_source_mgr)); + src = (my_src_ptr) cinfo->src; + src->buffer = (JOCTET *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, + INPUT_BUF_SIZE * SIZEOF(JOCTET)); + } + + src = (my_src_ptr) cinfo->src; + src->pub.init_source = init_source; + src->pub.fill_input_buffer = fill_input_buffer; + src->pub.skip_input_data = skip_input_data; + src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */ + src->pub.term_source = term_source; + src->infile = infile; + src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */ + src->pub.next_input_byte = NULL; /* until buffer loaded */ +} diff --git a/mod/pub.mod/libjpeg.mod/jdcoefct.c b/mod/pub.mod/libjpeg.mod/jdcoefct.c new file mode 100644 index 0000000..4938d20 --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jdcoefct.c @@ -0,0 +1,736 @@ +/* + * jdcoefct.c + * + * Copyright (C) 1994-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains the coefficient buffer controller for decompression. + * This controller is the top level of the JPEG decompressor proper. + * The coefficient buffer lies between entropy decoding and inverse-DCT steps. + * + * In buffered-image mode, this controller is the interface between + * input-oriented processing and output-oriented processing. + * Also, the input side (only) is used when reading a file for transcoding. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + +/* Block smoothing is only applicable for progressive JPEG, so: */ +#ifndef D_PROGRESSIVE_SUPPORTED +#undef BLOCK_SMOOTHING_SUPPORTED +#endif + +/* Private buffer controller object */ + +typedef struct { + struct jpeg_d_coef_controller pub; /* public fields */ + + /* These variables keep track of the current location of the input side. */ + /* cinfo->input_iMCU_row is also used for this. */ + JDIMENSION MCU_ctr; /* counts MCUs processed in current row */ + int MCU_vert_offset; /* counts MCU rows within iMCU row */ + int MCU_rows_per_iMCU_row; /* number of such rows needed */ + + /* The output side's location is represented by cinfo->output_iMCU_row. */ + + /* In single-pass modes, it's sufficient to buffer just one MCU. + * We allocate a workspace of D_MAX_BLOCKS_IN_MCU coefficient blocks, + * and let the entropy decoder write into that workspace each time. + * (On 80x86, the workspace is FAR even though it's not really very big; + * this is to keep the module interfaces unchanged when a large coefficient + * buffer is necessary.) + * In multi-pass modes, this array points to the current MCU's blocks + * within the virtual arrays; it is used only by the input side. + */ + JBLOCKROW MCU_buffer[D_MAX_BLOCKS_IN_MCU]; + +#ifdef D_MULTISCAN_FILES_SUPPORTED + /* In multi-pass modes, we need a virtual block array for each component. */ + jvirt_barray_ptr whole_image[MAX_COMPONENTS]; +#endif + +#ifdef BLOCK_SMOOTHING_SUPPORTED + /* When doing block smoothing, we latch coefficient Al values here */ + int * coef_bits_latch; +#define SAVED_COEFS 6 /* we save coef_bits[0..5] */ +#endif +} my_coef_controller; + +typedef my_coef_controller * my_coef_ptr; + +/* Forward declarations */ +METHODDEF(int) decompress_onepass + JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf)); +#ifdef D_MULTISCAN_FILES_SUPPORTED +METHODDEF(int) decompress_data + JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf)); +#endif +#ifdef BLOCK_SMOOTHING_SUPPORTED +LOCAL(boolean) smoothing_ok JPP((j_decompress_ptr cinfo)); +METHODDEF(int) decompress_smooth_data + JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf)); +#endif + + +LOCAL(void) +start_iMCU_row (j_decompress_ptr cinfo) +/* Reset within-iMCU-row counters for a new row (input side) */ +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + + /* In an interleaved scan, an MCU row is the same as an iMCU row. + * In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows. + * But at the bottom of the image, process only what's left. + */ + if (cinfo->comps_in_scan > 1) { + coef->MCU_rows_per_iMCU_row = 1; + } else { + if (cinfo->input_iMCU_row < (cinfo->total_iMCU_rows-1)) + coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor; + else + coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height; + } + + coef->MCU_ctr = 0; + coef->MCU_vert_offset = 0; +} + + +/* + * Initialize for an input processing pass. + */ + +METHODDEF(void) +start_input_pass (j_decompress_ptr cinfo) +{ + cinfo->input_iMCU_row = 0; + start_iMCU_row(cinfo); +} + + +/* + * Initialize for an output processing pass. + */ + +METHODDEF(void) +start_output_pass (j_decompress_ptr cinfo) +{ +#ifdef BLOCK_SMOOTHING_SUPPORTED + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + + /* If multipass, check to see whether to use block smoothing on this pass */ + if (coef->pub.coef_arrays != NULL) { + if (cinfo->do_block_smoothing && smoothing_ok(cinfo)) + coef->pub.decompress_data = decompress_smooth_data; + else + coef->pub.decompress_data = decompress_data; + } +#endif + cinfo->output_iMCU_row = 0; +} + + +/* + * Decompress and return some data in the single-pass case. + * Always attempts to emit one fully interleaved MCU row ("iMCU" row). + * Input and output must run in lockstep since we have only a one-MCU buffer. + * Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED. + * + * NB: output_buf contains a plane for each component in image, + * which we index according to the component's SOF position. + */ + +METHODDEF(int) +decompress_onepass (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + JDIMENSION MCU_col_num; /* index of current MCU within row */ + JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1; + JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1; + int blkn, ci, xindex, yindex, yoffset, useful_width; + JSAMPARRAY output_ptr; + JDIMENSION start_col, output_col; + jpeg_component_info *compptr; + inverse_DCT_method_ptr inverse_DCT; + + /* Loop to process as much as one whole iMCU row */ + for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row; + yoffset++) { + for (MCU_col_num = coef->MCU_ctr; MCU_col_num <= last_MCU_col; + MCU_col_num++) { + /* Try to fetch an MCU. Entropy decoder expects buffer to be zeroed. */ + jzero_far((void FAR *) coef->MCU_buffer[0], + (size_t) (cinfo->blocks_in_MCU * SIZEOF(JBLOCK))); + if (! (*cinfo->entropy->decode_mcu) (cinfo, coef->MCU_buffer)) { + /* Suspension forced; update state counters and exit */ + coef->MCU_vert_offset = yoffset; + coef->MCU_ctr = MCU_col_num; + return JPEG_SUSPENDED; + } + /* Determine where data should go in output_buf and do the IDCT thing. + * We skip dummy blocks at the right and bottom edges (but blkn gets + * incremented past them!). Note the inner loop relies on having + * allocated the MCU_buffer[] blocks sequentially. + */ + blkn = 0; /* index of current DCT block within MCU */ + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + /* Don't bother to IDCT an uninteresting component. */ + if (! compptr->component_needed) { + blkn += compptr->MCU_blocks; + continue; + } + inverse_DCT = cinfo->idct->inverse_DCT[compptr->component_index]; + useful_width = (MCU_col_num < last_MCU_col) ? compptr->MCU_width + : compptr->last_col_width; + output_ptr = output_buf[compptr->component_index] + + yoffset * compptr->DCT_scaled_size; + start_col = MCU_col_num * compptr->MCU_sample_width; + for (yindex = 0; yindex < compptr->MCU_height; yindex++) { + if (cinfo->input_iMCU_row < last_iMCU_row || + yoffset+yindex < compptr->last_row_height) { + output_col = start_col; + for (xindex = 0; xindex < useful_width; xindex++) { + (*inverse_DCT) (cinfo, compptr, + (JCOEFPTR) coef->MCU_buffer[blkn+xindex], + output_ptr, output_col); + output_col += compptr->DCT_scaled_size; + } + } + blkn += compptr->MCU_width; + output_ptr += compptr->DCT_scaled_size; + } + } + } + /* Completed an MCU row, but perhaps not an iMCU row */ + coef->MCU_ctr = 0; + } + /* Completed the iMCU row, advance counters for next one */ + cinfo->output_iMCU_row++; + if (++(cinfo->input_iMCU_row) < cinfo->total_iMCU_rows) { + start_iMCU_row(cinfo); + return JPEG_ROW_COMPLETED; + } + /* Completed the scan */ + (*cinfo->inputctl->finish_input_pass) (cinfo); + return JPEG_SCAN_COMPLETED; +} + + +/* + * Dummy consume-input routine for single-pass operation. + */ + +METHODDEF(int) +dummy_consume_data (j_decompress_ptr cinfo) +{ + return JPEG_SUSPENDED; /* Always indicate nothing was done */ +} + + +#ifdef D_MULTISCAN_FILES_SUPPORTED + +/* + * Consume input data and store it in the full-image coefficient buffer. + * We read as much as one fully interleaved MCU row ("iMCU" row) per call, + * ie, v_samp_factor block rows for each component in the scan. + * Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED. + */ + +METHODDEF(int) +consume_data (j_decompress_ptr cinfo) +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + JDIMENSION MCU_col_num; /* index of current MCU within row */ + int blkn, ci, xindex, yindex, yoffset; + JDIMENSION start_col; + JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN]; + JBLOCKROW buffer_ptr; + jpeg_component_info *compptr; + + /* Align the virtual buffers for the components used in this scan. */ + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + buffer[ci] = (*cinfo->mem->access_virt_barray) + ((j_common_ptr) cinfo, coef->whole_image[compptr->component_index], + cinfo->input_iMCU_row * compptr->v_samp_factor, + (JDIMENSION) compptr->v_samp_factor, TRUE); + /* Note: entropy decoder expects buffer to be zeroed, + * but this is handled automatically by the memory manager + * because we requested a pre-zeroed array. + */ + } + + /* Loop to process one whole iMCU row */ + for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row; + yoffset++) { + for (MCU_col_num = coef->MCU_ctr; MCU_col_num < cinfo->MCUs_per_row; + MCU_col_num++) { + /* Construct list of pointers to DCT blocks belonging to this MCU */ + blkn = 0; /* index of current DCT block within MCU */ + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + start_col = MCU_col_num * compptr->MCU_width; + for (yindex = 0; yindex < compptr->MCU_height; yindex++) { + buffer_ptr = buffer[ci][yindex+yoffset] + start_col; + for (xindex = 0; xindex < compptr->MCU_width; xindex++) { + coef->MCU_buffer[blkn++] = buffer_ptr++; + } + } + } + /* Try to fetch the MCU. */ + if (! (*cinfo->entropy->decode_mcu) (cinfo, coef->MCU_buffer)) { + /* Suspension forced; update state counters and exit */ + coef->MCU_vert_offset = yoffset; + coef->MCU_ctr = MCU_col_num; + return JPEG_SUSPENDED; + } + } + /* Completed an MCU row, but perhaps not an iMCU row */ + coef->MCU_ctr = 0; + } + /* Completed the iMCU row, advance counters for next one */ + if (++(cinfo->input_iMCU_row) < cinfo->total_iMCU_rows) { + start_iMCU_row(cinfo); + return JPEG_ROW_COMPLETED; + } + /* Completed the scan */ + (*cinfo->inputctl->finish_input_pass) (cinfo); + return JPEG_SCAN_COMPLETED; +} + + +/* + * Decompress and return some data in the multi-pass case. + * Always attempts to emit one fully interleaved MCU row ("iMCU" row). + * Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED. + * + * NB: output_buf contains a plane for each component in image. + */ + +METHODDEF(int) +decompress_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1; + JDIMENSION block_num; + int ci, block_row, block_rows; + JBLOCKARRAY buffer; + JBLOCKROW buffer_ptr; + JSAMPARRAY output_ptr; + JDIMENSION output_col; + jpeg_component_info *compptr; + inverse_DCT_method_ptr inverse_DCT; + + /* Force some input to be done if we are getting ahead of the input. */ + while (cinfo->input_scan_number < cinfo->output_scan_number || + (cinfo->input_scan_number == cinfo->output_scan_number && + cinfo->input_iMCU_row <= cinfo->output_iMCU_row)) { + if ((*cinfo->inputctl->consume_input)(cinfo) == JPEG_SUSPENDED) + return JPEG_SUSPENDED; + } + + /* OK, output from the virtual arrays. */ + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + /* Don't bother to IDCT an uninteresting component. */ + if (! compptr->component_needed) + continue; + /* Align the virtual buffer for this component. */ + buffer = (*cinfo->mem->access_virt_barray) + ((j_common_ptr) cinfo, coef->whole_image[ci], + cinfo->output_iMCU_row * compptr->v_samp_factor, + (JDIMENSION) compptr->v_samp_factor, FALSE); + /* Count non-dummy DCT block rows in this iMCU row. */ + if (cinfo->output_iMCU_row < last_iMCU_row) + block_rows = compptr->v_samp_factor; + else { + /* NB: can't use last_row_height here; it is input-side-dependent! */ + block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor); + if (block_rows == 0) block_rows = compptr->v_samp_factor; + } + inverse_DCT = cinfo->idct->inverse_DCT[ci]; + output_ptr = output_buf[ci]; + /* Loop over all DCT blocks to be processed. */ + for (block_row = 0; block_row < block_rows; block_row++) { + buffer_ptr = buffer[block_row]; + output_col = 0; + for (block_num = 0; block_num < compptr->width_in_blocks; block_num++) { + (*inverse_DCT) (cinfo, compptr, (JCOEFPTR) buffer_ptr, + output_ptr, output_col); + buffer_ptr++; + output_col += compptr->DCT_scaled_size; + } + output_ptr += compptr->DCT_scaled_size; + } + } + + if (++(cinfo->output_iMCU_row) < cinfo->total_iMCU_rows) + return JPEG_ROW_COMPLETED; + return JPEG_SCAN_COMPLETED; +} + +#endif /* D_MULTISCAN_FILES_SUPPORTED */ + + +#ifdef BLOCK_SMOOTHING_SUPPORTED + +/* + * This code applies interblock smoothing as described by section K.8 + * of the JPEG standard: the first 5 AC coefficients are estimated from + * the DC values of a DCT block and its 8 neighboring blocks. + * We apply smoothing only for progressive JPEG decoding, and only if + * the coefficients it can estimate are not yet known to full precision. + */ + +/* Natural-order array positions of the first 5 zigzag-order coefficients */ +#define Q01_POS 1 +#define Q10_POS 8 +#define Q20_POS 16 +#define Q11_POS 9 +#define Q02_POS 2 + +/* + * Determine whether block smoothing is applicable and safe. + * We also latch the current states of the coef_bits[] entries for the + * AC coefficients; otherwise, if the input side of the decompressor + * advances into a new scan, we might think the coefficients are known + * more accurately than they really are. + */ + +LOCAL(boolean) +smoothing_ok (j_decompress_ptr cinfo) +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + boolean smoothing_useful = FALSE; + int ci, coefi; + jpeg_component_info *compptr; + JQUANT_TBL * qtable; + int * coef_bits; + int * coef_bits_latch; + + if (! cinfo->progressive_mode || cinfo->coef_bits == NULL) + return FALSE; + + /* Allocate latch area if not already done */ + if (coef->coef_bits_latch == NULL) + coef->coef_bits_latch = (int *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + cinfo->num_components * + (SAVED_COEFS * SIZEOF(int))); + coef_bits_latch = coef->coef_bits_latch; + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + /* All components' quantization values must already be latched. */ + if ((qtable = compptr->quant_table) == NULL) + return FALSE; + /* Verify DC & first 5 AC quantizers are nonzero to avoid zero-divide. */ + if (qtable->quantval[0] == 0 || + qtable->quantval[Q01_POS] == 0 || + qtable->quantval[Q10_POS] == 0 || + qtable->quantval[Q20_POS] == 0 || + qtable->quantval[Q11_POS] == 0 || + qtable->quantval[Q02_POS] == 0) + return FALSE; + /* DC values must be at least partly known for all components. */ + coef_bits = cinfo->coef_bits[ci]; + if (coef_bits[0] < 0) + return FALSE; + /* Block smoothing is helpful if some AC coefficients remain inaccurate. */ + for (coefi = 1; coefi <= 5; coefi++) { + coef_bits_latch[coefi] = coef_bits[coefi]; + if (coef_bits[coefi] != 0) + smoothing_useful = TRUE; + } + coef_bits_latch += SAVED_COEFS; + } + + return smoothing_useful; +} + + +/* + * Variant of decompress_data for use when doing block smoothing. + */ + +METHODDEF(int) +decompress_smooth_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1; + JDIMENSION block_num, last_block_column; + int ci, block_row, block_rows, access_rows; + JBLOCKARRAY buffer; + JBLOCKROW buffer_ptr, prev_block_row, next_block_row; + JSAMPARRAY output_ptr; + JDIMENSION output_col; + jpeg_component_info *compptr; + inverse_DCT_method_ptr inverse_DCT; + boolean first_row, last_row; + JBLOCK workspace; + int *coef_bits; + JQUANT_TBL *quanttbl; + INT32 Q00,Q01,Q02,Q10,Q11,Q20, num; + int DC1,DC2,DC3,DC4,DC5,DC6,DC7,DC8,DC9; + int Al, pred; + + /* Force some input to be done if we are getting ahead of the input. */ + while (cinfo->input_scan_number <= cinfo->output_scan_number && + ! cinfo->inputctl->eoi_reached) { + if (cinfo->input_scan_number == cinfo->output_scan_number) { + /* If input is working on current scan, we ordinarily want it to + * have completed the current row. But if input scan is DC, + * we want it to keep one row ahead so that next block row's DC + * values are up to date. + */ + JDIMENSION delta = (cinfo->Ss == 0) ? 1 : 0; + if (cinfo->input_iMCU_row > cinfo->output_iMCU_row+delta) + break; + } + if ((*cinfo->inputctl->consume_input)(cinfo) == JPEG_SUSPENDED) + return JPEG_SUSPENDED; + } + + /* OK, output from the virtual arrays. */ + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + /* Don't bother to IDCT an uninteresting component. */ + if (! compptr->component_needed) + continue; + /* Count non-dummy DCT block rows in this iMCU row. */ + if (cinfo->output_iMCU_row < last_iMCU_row) { + block_rows = compptr->v_samp_factor; + access_rows = block_rows * 2; /* this and next iMCU row */ + last_row = FALSE; + } else { + /* NB: can't use last_row_height here; it is input-side-dependent! */ + block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor); + if (block_rows == 0) block_rows = compptr->v_samp_factor; + access_rows = block_rows; /* this iMCU row only */ + last_row = TRUE; + } + /* Align the virtual buffer for this component. */ + if (cinfo->output_iMCU_row > 0) { + access_rows += compptr->v_samp_factor; /* prior iMCU row too */ + buffer = (*cinfo->mem->access_virt_barray) + ((j_common_ptr) cinfo, coef->whole_image[ci], + (cinfo->output_iMCU_row - 1) * compptr->v_samp_factor, + (JDIMENSION) access_rows, FALSE); + buffer += compptr->v_samp_factor; /* point to current iMCU row */ + first_row = FALSE; + } else { + buffer = (*cinfo->mem->access_virt_barray) + ((j_common_ptr) cinfo, coef->whole_image[ci], + (JDIMENSION) 0, (JDIMENSION) access_rows, FALSE); + first_row = TRUE; + } + /* Fetch component-dependent info */ + coef_bits = coef->coef_bits_latch + (ci * SAVED_COEFS); + quanttbl = compptr->quant_table; + Q00 = quanttbl->quantval[0]; + Q01 = quanttbl->quantval[Q01_POS]; + Q10 = quanttbl->quantval[Q10_POS]; + Q20 = quanttbl->quantval[Q20_POS]; + Q11 = quanttbl->quantval[Q11_POS]; + Q02 = quanttbl->quantval[Q02_POS]; + inverse_DCT = cinfo->idct->inverse_DCT[ci]; + output_ptr = output_buf[ci]; + /* Loop over all DCT blocks to be processed. */ + for (block_row = 0; block_row < block_rows; block_row++) { + buffer_ptr = buffer[block_row]; + if (first_row && block_row == 0) + prev_block_row = buffer_ptr; + else + prev_block_row = buffer[block_row-1]; + if (last_row && block_row == block_rows-1) + next_block_row = buffer_ptr; + else + next_block_row = buffer[block_row+1]; + /* We fetch the surrounding DC values using a sliding-register approach. + * Initialize all nine here so as to do the right thing on narrow pics. + */ + DC1 = DC2 = DC3 = (int) prev_block_row[0][0]; + DC4 = DC5 = DC6 = (int) buffer_ptr[0][0]; + DC7 = DC8 = DC9 = (int) next_block_row[0][0]; + output_col = 0; + last_block_column = compptr->width_in_blocks - 1; + for (block_num = 0; block_num <= last_block_column; block_num++) { + /* Fetch current DCT block into workspace so we can modify it. */ + jcopy_block_row(buffer_ptr, (JBLOCKROW) workspace, (JDIMENSION) 1); + /* Update DC values */ + if (block_num < last_block_column) { + DC3 = (int) prev_block_row[1][0]; + DC6 = (int) buffer_ptr[1][0]; + DC9 = (int) next_block_row[1][0]; + } + /* Compute coefficient estimates per K.8. + * An estimate is applied only if coefficient is still zero, + * and is not known to be fully accurate. + */ + /* AC01 */ + if ((Al=coef_bits[1]) != 0 && workspace[1] == 0) { + num = 36 * Q00 * (DC4 - DC6); + if (num >= 0) { + pred = (int) (((Q01<<7) + num) / (Q01<<8)); + if (Al > 0 && pred >= (1<<Al)) + pred = (1<<Al)-1; + } else { + pred = (int) (((Q01<<7) - num) / (Q01<<8)); + if (Al > 0 && pred >= (1<<Al)) + pred = (1<<Al)-1; + pred = -pred; + } + workspace[1] = (JCOEF) pred; + } + /* AC10 */ + if ((Al=coef_bits[2]) != 0 && workspace[8] == 0) { + num = 36 * Q00 * (DC2 - DC8); + if (num >= 0) { + pred = (int) (((Q10<<7) + num) / (Q10<<8)); + if (Al > 0 && pred >= (1<<Al)) + pred = (1<<Al)-1; + } else { + pred = (int) (((Q10<<7) - num) / (Q10<<8)); + if (Al > 0 && pred >= (1<<Al)) + pred = (1<<Al)-1; + pred = -pred; + } + workspace[8] = (JCOEF) pred; + } + /* AC20 */ + if ((Al=coef_bits[3]) != 0 && workspace[16] == 0) { + num = 9 * Q00 * (DC2 + DC8 - 2*DC5); + if (num >= 0) { + pred = (int) (((Q20<<7) + num) / (Q20<<8)); + if (Al > 0 && pred >= (1<<Al)) + pred = (1<<Al)-1; + } else { + pred = (int) (((Q20<<7) - num) / (Q20<<8)); + if (Al > 0 && pred >= (1<<Al)) + pred = (1<<Al)-1; + pred = -pred; + } + workspace[16] = (JCOEF) pred; + } + /* AC11 */ + if ((Al=coef_bits[4]) != 0 && workspace[9] == 0) { + num = 5 * Q00 * (DC1 - DC3 - DC7 + DC9); + if (num >= 0) { + pred = (int) (((Q11<<7) + num) / (Q11<<8)); + if (Al > 0 && pred >= (1<<Al)) + pred = (1<<Al)-1; + } else { + pred = (int) (((Q11<<7) - num) / (Q11<<8)); + if (Al > 0 && pred >= (1<<Al)) + pred = (1<<Al)-1; + pred = -pred; + } + workspace[9] = (JCOEF) pred; + } + /* AC02 */ + if ((Al=coef_bits[5]) != 0 && workspace[2] == 0) { + num = 9 * Q00 * (DC4 + DC6 - 2*DC5); + if (num >= 0) { + pred = (int) (((Q02<<7) + num) / (Q02<<8)); + if (Al > 0 && pred >= (1<<Al)) + pred = (1<<Al)-1; + } else { + pred = (int) (((Q02<<7) - num) / (Q02<<8)); + if (Al > 0 && pred >= (1<<Al)) + pred = (1<<Al)-1; + pred = -pred; + } + workspace[2] = (JCOEF) pred; + } + /* OK, do the IDCT */ + (*inverse_DCT) (cinfo, compptr, (JCOEFPTR) workspace, + output_ptr, output_col); + /* Advance for next column */ + DC1 = DC2; DC2 = DC3; + DC4 = DC5; DC5 = DC6; + DC7 = DC8; DC8 = DC9; + buffer_ptr++, prev_block_row++, next_block_row++; + output_col += compptr->DCT_scaled_size; + } + output_ptr += compptr->DCT_scaled_size; + } + } + + if (++(cinfo->output_iMCU_row) < cinfo->total_iMCU_rows) + return JPEG_ROW_COMPLETED; + return JPEG_SCAN_COMPLETED; +} + +#endif /* BLOCK_SMOOTHING_SUPPORTED */ + + +/* + * Initialize coefficient buffer controller. + */ + +GLOBAL(void) +jinit_d_coef_controller (j_decompress_ptr cinfo, boolean need_full_buffer) +{ + my_coef_ptr coef; + + coef = (my_coef_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_coef_controller)); + cinfo->coef = (struct jpeg_d_coef_controller *) coef; + coef->pub.start_input_pass = start_input_pass; + coef->pub.start_output_pass = start_output_pass; +#ifdef BLOCK_SMOOTHING_SUPPORTED + coef->coef_bits_latch = NULL; +#endif + + /* Create the coefficient buffer. */ + if (need_full_buffer) { +#ifdef D_MULTISCAN_FILES_SUPPORTED + /* Allocate a full-image virtual array for each component, */ + /* padded to a multiple of samp_factor DCT blocks in each direction. */ + /* Note we ask for a pre-zeroed array. */ + int ci, access_rows; + jpeg_component_info *compptr; + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + access_rows = compptr->v_samp_factor; +#ifdef BLOCK_SMOOTHING_SUPPORTED + /* If block smoothing could be used, need a bigger window */ + if (cinfo->progressive_mode) + access_rows *= 3; +#endif + coef->whole_image[ci] = (*cinfo->mem->request_virt_barray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, TRUE, + (JDIMENSION) jround_up((long) compptr->width_in_blocks, + (long) compptr->h_samp_factor), + (JDIMENSION) jround_up((long) compptr->height_in_blocks, + (long) compptr->v_samp_factor), + (JDIMENSION) access_rows); + } + coef->pub.consume_data = consume_data; + coef->pub.decompress_data = decompress_data; + coef->pub.coef_arrays = coef->whole_image; /* link to virtual arrays */ +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } else { + /* We only need a single-MCU buffer. */ + JBLOCKROW buffer; + int i; + + buffer = (JBLOCKROW) + (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE, + D_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK)); + for (i = 0; i < D_MAX_BLOCKS_IN_MCU; i++) { + coef->MCU_buffer[i] = buffer + i; + } + coef->pub.consume_data = dummy_consume_data; + coef->pub.decompress_data = decompress_onepass; + coef->pub.coef_arrays = NULL; /* flag for no virtual arrays */ + } +} diff --git a/mod/pub.mod/libjpeg.mod/jdcolor.c b/mod/pub.mod/libjpeg.mod/jdcolor.c new file mode 100644 index 0000000..6c04dfe --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jdcolor.c @@ -0,0 +1,396 @@ +/* + * jdcolor.c + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains output colorspace conversion routines. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* Private subobject */ + +typedef struct { + struct jpeg_color_deconverter pub; /* public fields */ + + /* Private state for YCC->RGB conversion */ + int * Cr_r_tab; /* => table for Cr to R conversion */ + int * Cb_b_tab; /* => table for Cb to B conversion */ + INT32 * Cr_g_tab; /* => table for Cr to G conversion */ + INT32 * Cb_g_tab; /* => table for Cb to G conversion */ +} my_color_deconverter; + +typedef my_color_deconverter * my_cconvert_ptr; + + +/**************** YCbCr -> RGB conversion: most common case **************/ + +/* + * YCbCr is defined per CCIR 601-1, except that Cb and Cr are + * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5. + * The conversion equations to be implemented are therefore + * R = Y + 1.40200 * Cr + * G = Y - 0.34414 * Cb - 0.71414 * Cr + * B = Y + 1.77200 * Cb + * where Cb and Cr represent the incoming values less CENTERJSAMPLE. + * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.) + * + * To avoid floating-point arithmetic, we represent the fractional constants + * as integers scaled up by 2^16 (about 4 digits precision); we have to divide + * the products by 2^16, with appropriate rounding, to get the correct answer. + * Notice that Y, being an integral input, does not contribute any fraction + * so it need not participate in the rounding. + * + * For even more speed, we avoid doing any multiplications in the inner loop + * by precalculating the constants times Cb and Cr for all possible values. + * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table); + * for 12-bit samples it is still acceptable. It's not very reasonable for + * 16-bit samples, but if you want lossless storage you shouldn't be changing + * colorspace anyway. + * The Cr=>R and Cb=>B values can be rounded to integers in advance; the + * values for the G calculation are left scaled up, since we must add them + * together before rounding. + */ + +#define SCALEBITS 16 /* speediest right-shift on some machines */ +#define ONE_HALF ((INT32) 1 << (SCALEBITS-1)) +#define FIX(x) ((INT32) ((x) * (1L<<SCALEBITS) + 0.5)) + + +/* + * Initialize tables for YCC->RGB colorspace conversion. + */ + +LOCAL(void) +build_ycc_rgb_table (j_decompress_ptr cinfo) +{ + my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; + int i; + INT32 x; + SHIFT_TEMPS + + cconvert->Cr_r_tab = (int *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (MAXJSAMPLE+1) * SIZEOF(int)); + cconvert->Cb_b_tab = (int *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (MAXJSAMPLE+1) * SIZEOF(int)); + cconvert->Cr_g_tab = (INT32 *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (MAXJSAMPLE+1) * SIZEOF(INT32)); + cconvert->Cb_g_tab = (INT32 *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (MAXJSAMPLE+1) * SIZEOF(INT32)); + + for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) { + /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */ + /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */ + /* Cr=>R value is nearest int to 1.40200 * x */ + cconvert->Cr_r_tab[i] = (int) + RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS); + /* Cb=>B value is nearest int to 1.77200 * x */ + cconvert->Cb_b_tab[i] = (int) + RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS); + /* Cr=>G value is scaled-up -0.71414 * x */ + cconvert->Cr_g_tab[i] = (- FIX(0.71414)) * x; + /* Cb=>G value is scaled-up -0.34414 * x */ + /* We also add in ONE_HALF so that need not do it in inner loop */ + cconvert->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF; + } +} + + +/* + * Convert some rows of samples to the output colorspace. + * + * Note that we change from noninterleaved, one-plane-per-component format + * to interleaved-pixel format. The output buffer is therefore three times + * as wide as the input buffer. + * A starting row offset is provided only for the input buffer. The caller + * can easily adjust the passed output_buf value to accommodate any row + * offset required on that side. + */ + +METHODDEF(void) +ycc_rgb_convert (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION input_row, + JSAMPARRAY output_buf, int num_rows) +{ + my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; + register int y, cb, cr; + register JSAMPROW outptr; + register JSAMPROW inptr0, inptr1, inptr2; + register JDIMENSION col; + JDIMENSION num_cols = cinfo->output_width; + /* copy these pointers into registers if possible */ + register JSAMPLE * range_limit = cinfo->sample_range_limit; + register int * Crrtab = cconvert->Cr_r_tab; + register int * Cbbtab = cconvert->Cb_b_tab; + register INT32 * Crgtab = cconvert->Cr_g_tab; + register INT32 * Cbgtab = cconvert->Cb_g_tab; + SHIFT_TEMPS + + while (--num_rows >= 0) { + inptr0 = input_buf[0][input_row]; + inptr1 = input_buf[1][input_row]; + inptr2 = input_buf[2][input_row]; + input_row++; + outptr = *output_buf++; + for (col = 0; col < num_cols; col++) { + y = GETJSAMPLE(inptr0[col]); + cb = GETJSAMPLE(inptr1[col]); + cr = GETJSAMPLE(inptr2[col]); + /* Range-limiting is essential due to noise introduced by DCT losses. */ + outptr[RGB_RED] = range_limit[y + Crrtab[cr]]; + outptr[RGB_GREEN] = range_limit[y + + ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], + SCALEBITS))]; + outptr[RGB_BLUE] = range_limit[y + Cbbtab[cb]]; + outptr += RGB_PIXELSIZE; + } + } +} + + +/**************** Cases other than YCbCr -> RGB **************/ + + +/* + * Color conversion for no colorspace change: just copy the data, + * converting from separate-planes to interleaved representation. + */ + +METHODDEF(void) +null_convert (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION input_row, + JSAMPARRAY output_buf, int num_rows) +{ + register JSAMPROW inptr, outptr; + register JDIMENSION count; + register int num_components = cinfo->num_components; + JDIMENSION num_cols = cinfo->output_width; + int ci; + + while (--num_rows >= 0) { + for (ci = 0; ci < num_components; ci++) { + inptr = input_buf[ci][input_row]; + outptr = output_buf[0] + ci; + for (count = num_cols; count > 0; count--) { + *outptr = *inptr++; /* needn't bother with GETJSAMPLE() here */ + outptr += num_components; + } + } + input_row++; + output_buf++; + } +} + + +/* + * Color conversion for grayscale: just copy the data. + * This also works for YCbCr -> grayscale conversion, in which + * we just copy the Y (luminance) component and ignore chrominance. + */ + +METHODDEF(void) +grayscale_convert (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION input_row, + JSAMPARRAY output_buf, int num_rows) +{ + jcopy_sample_rows(input_buf[0], (int) input_row, output_buf, 0, + num_rows, cinfo->output_width); +} + + +/* + * Convert grayscale to RGB: just duplicate the graylevel three times. + * This is provided to support applications that don't want to cope + * with grayscale as a separate case. + */ + +METHODDEF(void) +gray_rgb_convert (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION input_row, + JSAMPARRAY output_buf, int num_rows) +{ + register JSAMPROW inptr, outptr; + register JDIMENSION col; + JDIMENSION num_cols = cinfo->output_width; + + while (--num_rows >= 0) { + inptr = input_buf[0][input_row++]; + outptr = *output_buf++; + for (col = 0; col < num_cols; col++) { + /* We can dispense with GETJSAMPLE() here */ + outptr[RGB_RED] = outptr[RGB_GREEN] = outptr[RGB_BLUE] = inptr[col]; + outptr += RGB_PIXELSIZE; + } + } +} + + +/* + * Adobe-style YCCK->CMYK conversion. + * We convert YCbCr to R=1-C, G=1-M, and B=1-Y using the same + * conversion as above, while passing K (black) unchanged. + * We assume build_ycc_rgb_table has been called. + */ + +METHODDEF(void) +ycck_cmyk_convert (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION input_row, + JSAMPARRAY output_buf, int num_rows) +{ + my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; + register int y, cb, cr; + register JSAMPROW outptr; + register JSAMPROW inptr0, inptr1, inptr2, inptr3; + register JDIMENSION col; + JDIMENSION num_cols = cinfo->output_width; + /* copy these pointers into registers if possible */ + register JSAMPLE * range_limit = cinfo->sample_range_limit; + register int * Crrtab = cconvert->Cr_r_tab; + register int * Cbbtab = cconvert->Cb_b_tab; + register INT32 * Crgtab = cconvert->Cr_g_tab; + register INT32 * Cbgtab = cconvert->Cb_g_tab; + SHIFT_TEMPS + + while (--num_rows >= 0) { + inptr0 = input_buf[0][input_row]; + inptr1 = input_buf[1][input_row]; + inptr2 = input_buf[2][input_row]; + inptr3 = input_buf[3][input_row]; + input_row++; + outptr = *output_buf++; + for (col = 0; col < num_cols; col++) { + y = GETJSAMPLE(inptr0[col]); + cb = GETJSAMPLE(inptr1[col]); + cr = GETJSAMPLE(inptr2[col]); + /* Range-limiting is essential due to noise introduced by DCT losses. */ + outptr[0] = range_limit[MAXJSAMPLE - (y + Crrtab[cr])]; /* red */ + outptr[1] = range_limit[MAXJSAMPLE - (y + /* green */ + ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], + SCALEBITS)))]; + outptr[2] = range_limit[MAXJSAMPLE - (y + Cbbtab[cb])]; /* blue */ + /* K passes through unchanged */ + outptr[3] = inptr3[col]; /* don't need GETJSAMPLE here */ + outptr += 4; + } + } +} + + +/* + * Empty method for start_pass. + */ + +METHODDEF(void) +start_pass_dcolor (j_decompress_ptr cinfo) +{ + /* no work needed */ +} + + +/* + * Module initialization routine for output colorspace conversion. + */ + +GLOBAL(void) +jinit_color_deconverter (j_decompress_ptr cinfo) +{ + my_cconvert_ptr cconvert; + int ci; + + cconvert = (my_cconvert_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_color_deconverter)); + cinfo->cconvert = (struct jpeg_color_deconverter *) cconvert; + cconvert->pub.start_pass = start_pass_dcolor; + + /* Make sure num_components agrees with jpeg_color_space */ + switch (cinfo->jpeg_color_space) { + case JCS_GRAYSCALE: + if (cinfo->num_components != 1) + ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); + break; + + case JCS_RGB: + case JCS_YCbCr: + if (cinfo->num_components != 3) + ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); + break; + + case JCS_CMYK: + case JCS_YCCK: + if (cinfo->num_components != 4) + ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); + break; + + default: /* JCS_UNKNOWN can be anything */ + if (cinfo->num_components < 1) + ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); + break; + } + + /* Set out_color_components and conversion method based on requested space. + * Also clear the component_needed flags for any unused components, + * so that earlier pipeline stages can avoid useless computation. + */ + + switch (cinfo->out_color_space) { + case JCS_GRAYSCALE: + cinfo->out_color_components = 1; + if (cinfo->jpeg_color_space == JCS_GRAYSCALE || + cinfo->jpeg_color_space == JCS_YCbCr) { + cconvert->pub.color_convert = grayscale_convert; + /* For color->grayscale conversion, only the Y (0) component is needed */ + for (ci = 1; ci < cinfo->num_components; ci++) + cinfo->comp_info[ci].component_needed = FALSE; + } else + ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); + break; + + case JCS_RGB: + cinfo->out_color_components = RGB_PIXELSIZE; + if (cinfo->jpeg_color_space == JCS_YCbCr) { + cconvert->pub.color_convert = ycc_rgb_convert; + build_ycc_rgb_table(cinfo); + } else if (cinfo->jpeg_color_space == JCS_GRAYSCALE) { + cconvert->pub.color_convert = gray_rgb_convert; + } else if (cinfo->jpeg_color_space == JCS_RGB && RGB_PIXELSIZE == 3) { + cconvert->pub.color_convert = null_convert; + } else + ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); + break; + + case JCS_CMYK: + cinfo->out_color_components = 4; + if (cinfo->jpeg_color_space == JCS_YCCK) { + cconvert->pub.color_convert = ycck_cmyk_convert; + build_ycc_rgb_table(cinfo); + } else if (cinfo->jpeg_color_space == JCS_CMYK) { + cconvert->pub.color_convert = null_convert; + } else + ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); + break; + + default: + /* Permit null conversion to same output space */ + if (cinfo->out_color_space == cinfo->jpeg_color_space) { + cinfo->out_color_components = cinfo->num_components; + cconvert->pub.color_convert = null_convert; + } else /* unsupported non-null conversion */ + ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); + break; + } + + if (cinfo->quantize_colors) + cinfo->output_components = 1; /* single colormapped output component */ + else + cinfo->output_components = cinfo->out_color_components; +} diff --git a/mod/pub.mod/libjpeg.mod/jdct.h b/mod/pub.mod/libjpeg.mod/jdct.h new file mode 100644 index 0000000..04192a2 --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jdct.h @@ -0,0 +1,176 @@ +/* + * jdct.h + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This include file contains common declarations for the forward and + * inverse DCT modules. These declarations are private to the DCT managers + * (jcdctmgr.c, jddctmgr.c) and the individual DCT algorithms. + * The individual DCT algorithms are kept in separate files to ease + * machine-dependent tuning (e.g., assembly coding). + */ + + +/* + * A forward DCT routine is given a pointer to a work area of type DCTELEM[]; + * the DCT is to be performed in-place in that buffer. Type DCTELEM is int + * for 8-bit samples, INT32 for 12-bit samples. (NOTE: Floating-point DCT + * implementations use an array of type FAST_FLOAT, instead.) + * The DCT inputs are expected to be signed (range +-CENTERJSAMPLE). + * The DCT outputs are returned scaled up by a factor of 8; they therefore + * have a range of +-8K for 8-bit data, +-128K for 12-bit data. This + * convention improves accuracy in integer implementations and saves some + * work in floating-point ones. + * Quantization of the output coefficients is done by jcdctmgr.c. + */ + +#if BITS_IN_JSAMPLE == 8 +typedef int DCTELEM; /* 16 or 32 bits is fine */ +#else +typedef INT32 DCTELEM; /* must have 32 bits */ +#endif + +typedef JMETHOD(void, forward_DCT_method_ptr, (DCTELEM * data)); +typedef JMETHOD(void, float_DCT_method_ptr, (FAST_FLOAT * data)); + + +/* + * An inverse DCT routine is given a pointer to the input JBLOCK and a pointer + * to an output sample array. The routine must dequantize the input data as + * well as perform the IDCT; for dequantization, it uses the multiplier table + * pointed to by compptr->dct_table. The output data is to be placed into the + * sample array starting at a specified column. (Any row offset needed will + * be applied to the array pointer before it is passed to the IDCT code.) + * Note that the number of samples emitted by the IDCT routine is + * DCT_scaled_size * DCT_scaled_size. + */ + +/* typedef inverse_DCT_method_ptr is declared in jpegint.h */ + +/* + * Each IDCT routine has its own ideas about the best dct_table element type. + */ + +typedef MULTIPLIER ISLOW_MULT_TYPE; /* short or int, whichever is faster */ +#if BITS_IN_JSAMPLE == 8 +typedef MULTIPLIER IFAST_MULT_TYPE; /* 16 bits is OK, use short if faster */ +#define IFAST_SCALE_BITS 2 /* fractional bits in scale factors */ +#else +typedef INT32 IFAST_MULT_TYPE; /* need 32 bits for scaled quantizers */ +#define IFAST_SCALE_BITS 13 /* fractional bits in scale factors */ +#endif +typedef FAST_FLOAT FLOAT_MULT_TYPE; /* preferred floating type */ + + +/* + * Each IDCT routine is responsible for range-limiting its results and + * converting them to unsigned form (0..MAXJSAMPLE). The raw outputs could + * be quite far out of range if the input data is corrupt, so a bulletproof + * range-limiting step is required. We use a mask-and-table-lookup method + * to do the combined operations quickly. See the comments with + * prepare_range_limit_table (in jdmaster.c) for more info. + */ + +#define IDCT_range_limit(cinfo) ((cinfo)->sample_range_limit + CENTERJSAMPLE) + +#define RANGE_MASK (MAXJSAMPLE * 4 + 3) /* 2 bits wider than legal samples */ + + +/* Short forms of external names for systems with brain-damaged linkers. */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jpeg_fdct_islow jFDislow +#define jpeg_fdct_ifast jFDifast +#define jpeg_fdct_float jFDfloat +#define jpeg_idct_islow jRDislow +#define jpeg_idct_ifast jRDifast +#define jpeg_idct_float jRDfloat +#define jpeg_idct_4x4 jRD4x4 +#define jpeg_idct_2x2 jRD2x2 +#define jpeg_idct_1x1 jRD1x1 +#endif /* NEED_SHORT_EXTERNAL_NAMES */ + +/* Extern declarations for the forward and inverse DCT routines. */ + +EXTERN(void) jpeg_fdct_islow JPP((DCTELEM * data)); +EXTERN(void) jpeg_fdct_ifast JPP((DCTELEM * data)); +EXTERN(void) jpeg_fdct_float JPP((FAST_FLOAT * data)); + +EXTERN(void) jpeg_idct_islow + JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); +EXTERN(void) jpeg_idct_ifast + JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); +EXTERN(void) jpeg_idct_float + JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); +EXTERN(void) jpeg_idct_4x4 + JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); +EXTERN(void) jpeg_idct_2x2 + JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); +EXTERN(void) jpeg_idct_1x1 + JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); + + +/* + * Macros for handling fixed-point arithmetic; these are used by many + * but not all of the DCT/IDCT modules. + * + * All values are expected to be of type INT32. + * Fractional constants are scaled left by CONST_BITS bits. + * CONST_BITS is defined within each module using these macros, + * and may differ from one module to the next. + */ + +#define ONE ((INT32) 1) +#define CONST_SCALE (ONE << CONST_BITS) + +/* Convert a positive real constant to an integer scaled by CONST_SCALE. + * Caution: some C compilers fail to reduce "FIX(constant)" at compile time, + * thus causing a lot of useless floating-point operations at run time. + */ + +#define FIX(x) ((INT32) ((x) * CONST_SCALE + 0.5)) + +/* Descale and correctly round an INT32 value that's scaled by N bits. + * We assume RIGHT_SHIFT rounds towards minus infinity, so adding + * the fudge factor is correct for either sign of X. + */ + +#define DESCALE(x,n) RIGHT_SHIFT((x) + (ONE << ((n)-1)), n) + +/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result. + * This macro is used only when the two inputs will actually be no more than + * 16 bits wide, so that a 16x16->32 bit multiply can be used instead of a + * full 32x32 multiply. This provides a useful speedup on many machines. + * Unfortunately there is no way to specify a 16x16->32 multiply portably + * in C, but some C compilers will do the right thing if you provide the + * correct combination of casts. + */ + +#ifdef SHORTxSHORT_32 /* may work if 'int' is 32 bits */ +#define MULTIPLY16C16(var,const) (((INT16) (var)) * ((INT16) (const))) +#endif +#ifdef SHORTxLCONST_32 /* known to work with Microsoft C 6.0 */ +#define MULTIPLY16C16(var,const) (((INT16) (var)) * ((INT32) (const))) +#endif + +#ifndef MULTIPLY16C16 /* default definition */ +#define MULTIPLY16C16(var,const) ((var) * (const)) +#endif + +/* Same except both inputs are variables. */ + +#ifdef SHORTxSHORT_32 /* may work if 'int' is 32 bits */ +#define MULTIPLY16V16(var1,var2) (((INT16) (var1)) * ((INT16) (var2))) +#endif + +#ifndef MULTIPLY16V16 /* default definition */ +#define MULTIPLY16V16(var1,var2) ((var1) * (var2)) +#endif diff --git a/mod/pub.mod/libjpeg.mod/jddctmgr.c b/mod/pub.mod/libjpeg.mod/jddctmgr.c new file mode 100644 index 0000000..bbf8d0e --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jddctmgr.c @@ -0,0 +1,269 @@ +/* + * jddctmgr.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains the inverse-DCT management logic. + * This code selects a particular IDCT implementation to be used, + * and it performs related housekeeping chores. No code in this file + * is executed per IDCT step, only during output pass setup. + * + * Note that the IDCT routines are responsible for performing coefficient + * dequantization as well as the IDCT proper. This module sets up the + * dequantization multiplier table needed by the IDCT routine. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdct.h" /* Private declarations for DCT subsystem */ + + +/* + * The decompressor input side (jdinput.c) saves away the appropriate + * quantization table for each component at the start of the first scan + * involving that component. (This is necessary in order to correctly + * decode files that reuse Q-table slots.) + * When we are ready to make an output pass, the saved Q-table is converted + * to a multiplier table that will actually be used by the IDCT routine. + * The multiplier table contents are IDCT-method-dependent. To support + * application changes in IDCT method between scans, we can remake the + * multiplier tables if necessary. + * In buffered-image mode, the first output pass may occur before any data + * has been seen for some components, and thus before their Q-tables have + * been saved away. To handle this case, multiplier tables are preset + * to zeroes; the result of the IDCT will be a neutral gray level. + */ + + +/* Private subobject for this module */ + +typedef struct { + struct jpeg_inverse_dct pub; /* public fields */ + + /* This array contains the IDCT method code that each multiplier table + * is currently set up for, or -1 if it's not yet set up. + * The actual multiplier tables are pointed to by dct_table in the + * per-component comp_info structures. + */ + int cur_method[MAX_COMPONENTS]; +} my_idct_controller; + +typedef my_idct_controller * my_idct_ptr; + + +/* Allocated multiplier tables: big enough for any supported variant */ + +typedef union { + ISLOW_MULT_TYPE islow_array[DCTSIZE2]; +#ifdef DCT_IFAST_SUPPORTED + IFAST_MULT_TYPE ifast_array[DCTSIZE2]; +#endif +#ifdef DCT_FLOAT_SUPPORTED + FLOAT_MULT_TYPE float_array[DCTSIZE2]; +#endif +} multiplier_table; + + +/* The current scaled-IDCT routines require ISLOW-style multiplier tables, + * so be sure to compile that code if either ISLOW or SCALING is requested. + */ +#ifdef DCT_ISLOW_SUPPORTED +#define PROVIDE_ISLOW_TABLES +#else +#ifdef IDCT_SCALING_SUPPORTED +#define PROVIDE_ISLOW_TABLES +#endif +#endif + + +/* + * Prepare for an output pass. + * Here we select the proper IDCT routine for each component and build + * a matching multiplier table. + */ + +METHODDEF(void) +start_pass (j_decompress_ptr cinfo) +{ + my_idct_ptr idct = (my_idct_ptr) cinfo->idct; + int ci, i; + jpeg_component_info *compptr; + int method = 0; + inverse_DCT_method_ptr method_ptr = NULL; + JQUANT_TBL * qtbl; + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + /* Select the proper IDCT routine for this component's scaling */ + switch (compptr->DCT_scaled_size) { +#ifdef IDCT_SCALING_SUPPORTED + case 1: + method_ptr = jpeg_idct_1x1; + method = JDCT_ISLOW; /* jidctred uses islow-style table */ + break; + case 2: + method_ptr = jpeg_idct_2x2; + method = JDCT_ISLOW; /* jidctred uses islow-style table */ + break; + case 4: + method_ptr = jpeg_idct_4x4; + method = JDCT_ISLOW; /* jidctred uses islow-style table */ + break; +#endif + case DCTSIZE: + switch (cinfo->dct_method) { +#ifdef DCT_ISLOW_SUPPORTED + case JDCT_ISLOW: + method_ptr = jpeg_idct_islow; + method = JDCT_ISLOW; + break; +#endif +#ifdef DCT_IFAST_SUPPORTED + case JDCT_IFAST: + method_ptr = jpeg_idct_ifast; + method = JDCT_IFAST; + break; +#endif +#ifdef DCT_FLOAT_SUPPORTED + case JDCT_FLOAT: + method_ptr = jpeg_idct_float; + method = JDCT_FLOAT; + break; +#endif + default: + ERREXIT(cinfo, JERR_NOT_COMPILED); + break; + } + break; + default: + ERREXIT1(cinfo, JERR_BAD_DCTSIZE, compptr->DCT_scaled_size); + break; + } + idct->pub.inverse_DCT[ci] = method_ptr; + /* Create multiplier table from quant table. + * However, we can skip this if the component is uninteresting + * or if we already built the table. Also, if no quant table + * has yet been saved for the component, we leave the + * multiplier table all-zero; we'll be reading zeroes from the + * coefficient controller's buffer anyway. + */ + if (! compptr->component_needed || idct->cur_method[ci] == method) + continue; + qtbl = compptr->quant_table; + if (qtbl == NULL) /* happens if no data yet for component */ + continue; + idct->cur_method[ci] = method; + switch (method) { +#ifdef PROVIDE_ISLOW_TABLES + case JDCT_ISLOW: + { + /* For LL&M IDCT method, multipliers are equal to raw quantization + * coefficients, but are stored as ints to ensure access efficiency. + */ + ISLOW_MULT_TYPE * ismtbl = (ISLOW_MULT_TYPE *) compptr->dct_table; + for (i = 0; i < DCTSIZE2; i++) { + ismtbl[i] = (ISLOW_MULT_TYPE) qtbl->quantval[i]; + } + } + break; +#endif +#ifdef DCT_IFAST_SUPPORTED + case JDCT_IFAST: + { + /* For AA&N IDCT method, multipliers are equal to quantization + * coefficients scaled by scalefactor[row]*scalefactor[col], where + * scalefactor[0] = 1 + * scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7 + * For integer operation, the multiplier table is to be scaled by + * IFAST_SCALE_BITS. + */ + IFAST_MULT_TYPE * ifmtbl = (IFAST_MULT_TYPE *) compptr->dct_table; +#define CONST_BITS 14 + static const INT16 aanscales[DCTSIZE2] = { + /* precomputed values scaled up by 14 bits */ + 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520, + 22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270, + 21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906, + 19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315, + 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520, + 12873, 17855, 16819, 15137, 12873, 10114, 6967, 3552, + 8867, 12299, 11585, 10426, 8867, 6967, 4799, 2446, + 4520, 6270, 5906, 5315, 4520, 3552, 2446, 1247 + }; + SHIFT_TEMPS + + for (i = 0; i < DCTSIZE2; i++) { + ifmtbl[i] = (IFAST_MULT_TYPE) + DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[i], + (INT32) aanscales[i]), + CONST_BITS-IFAST_SCALE_BITS); + } + } + break; +#endif +#ifdef DCT_FLOAT_SUPPORTED + case JDCT_FLOAT: + { + /* For float AA&N IDCT method, multipliers are equal to quantization + * coefficients scaled by scalefactor[row]*scalefactor[col], where + * scalefactor[0] = 1 + * scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7 + */ + FLOAT_MULT_TYPE * fmtbl = (FLOAT_MULT_TYPE *) compptr->dct_table; + int row, col; + static const double aanscalefactor[DCTSIZE] = { + 1.0, 1.387039845, 1.306562965, 1.175875602, + 1.0, 0.785694958, 0.541196100, 0.275899379 + }; + + i = 0; + for (row = 0; row < DCTSIZE; row++) { + for (col = 0; col < DCTSIZE; col++) { + fmtbl[i] = (FLOAT_MULT_TYPE) + ((double) qtbl->quantval[i] * + aanscalefactor[row] * aanscalefactor[col]); + i++; + } + } + } + break; +#endif + default: + ERREXIT(cinfo, JERR_NOT_COMPILED); + break; + } + } +} + + +/* + * Initialize IDCT manager. + */ + +GLOBAL(void) +jinit_inverse_dct (j_decompress_ptr cinfo) +{ + my_idct_ptr idct; + int ci; + jpeg_component_info *compptr; + + idct = (my_idct_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_idct_controller)); + cinfo->idct = (struct jpeg_inverse_dct *) idct; + idct->pub.start_pass = start_pass; + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + /* Allocate and pre-zero a multiplier table for each component */ + compptr->dct_table = + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(multiplier_table)); + MEMZERO(compptr->dct_table, SIZEOF(multiplier_table)); + /* Mark multiplier table not yet set up for any method */ + idct->cur_method[ci] = -1; + } +} diff --git a/mod/pub.mod/libjpeg.mod/jdhuff.c b/mod/pub.mod/libjpeg.mod/jdhuff.c new file mode 100644 index 0000000..b5ba39f --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jdhuff.c @@ -0,0 +1,651 @@ +/* + * jdhuff.c + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains Huffman entropy decoding routines. + * + * Much of the complexity here has to do with supporting input suspension. + * If the data source module demands suspension, we want to be able to back + * up to the start of the current MCU. To do this, we copy state variables + * into local working storage, and update them back to the permanent + * storage only upon successful completion of an MCU. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdhuff.h" /* Declarations shared with jdphuff.c */ + + +/* + * Expanded entropy decoder object for Huffman decoding. + * + * The savable_state subrecord contains fields that change within an MCU, + * but must not be updated permanently until we complete the MCU. + */ + +typedef struct { + int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */ +} savable_state; + +/* This macro is to work around compilers with missing or broken + * structure assignment. You'll need to fix this code if you have + * such a compiler and you change MAX_COMPS_IN_SCAN. + */ + +#ifndef NO_STRUCT_ASSIGN +#define ASSIGN_STATE(dest,src) ((dest) = (src)) +#else +#if MAX_COMPS_IN_SCAN == 4 +#define ASSIGN_STATE(dest,src) \ + ((dest).last_dc_val[0] = (src).last_dc_val[0], \ + (dest).last_dc_val[1] = (src).last_dc_val[1], \ + (dest).last_dc_val[2] = (src).last_dc_val[2], \ + (dest).last_dc_val[3] = (src).last_dc_val[3]) +#endif +#endif + + +typedef struct { + struct jpeg_entropy_decoder pub; /* public fields */ + + /* These fields are loaded into local variables at start of each MCU. + * In case of suspension, we exit WITHOUT updating them. + */ + bitread_perm_state bitstate; /* Bit buffer at start of MCU */ + savable_state saved; /* Other state at start of MCU */ + + /* These fields are NOT loaded into local working state. */ + unsigned int restarts_to_go; /* MCUs left in this restart interval */ + + /* Pointers to derived tables (these workspaces have image lifespan) */ + d_derived_tbl * dc_derived_tbls[NUM_HUFF_TBLS]; + d_derived_tbl * ac_derived_tbls[NUM_HUFF_TBLS]; + + /* Precalculated info set up by start_pass for use in decode_mcu: */ + + /* Pointers to derived tables to be used for each block within an MCU */ + d_derived_tbl * dc_cur_tbls[D_MAX_BLOCKS_IN_MCU]; + d_derived_tbl * ac_cur_tbls[D_MAX_BLOCKS_IN_MCU]; + /* Whether we care about the DC and AC coefficient values for each block */ + boolean dc_needed[D_MAX_BLOCKS_IN_MCU]; + boolean ac_needed[D_MAX_BLOCKS_IN_MCU]; +} huff_entropy_decoder; + +typedef huff_entropy_decoder * huff_entropy_ptr; + + +/* + * Initialize for a Huffman-compressed scan. + */ + +METHODDEF(void) +start_pass_huff_decoder (j_decompress_ptr cinfo) +{ + huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; + int ci, blkn, dctbl, actbl; + jpeg_component_info * compptr; + + /* Check that the scan parameters Ss, Se, Ah/Al are OK for sequential JPEG. + * This ought to be an error condition, but we make it a warning because + * there are some baseline files out there with all zeroes in these bytes. + */ + if (cinfo->Ss != 0 || cinfo->Se != DCTSIZE2-1 || + cinfo->Ah != 0 || cinfo->Al != 0) + WARNMS(cinfo, JWRN_NOT_SEQUENTIAL); + + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + dctbl = compptr->dc_tbl_no; + actbl = compptr->ac_tbl_no; + /* Compute derived values for Huffman tables */ + /* We may do this more than once for a table, but it's not expensive */ + jpeg_make_d_derived_tbl(cinfo, TRUE, dctbl, + & entropy->dc_derived_tbls[dctbl]); + jpeg_make_d_derived_tbl(cinfo, FALSE, actbl, + & entropy->ac_derived_tbls[actbl]); + /* Initialize DC predictions to 0 */ + entropy->saved.last_dc_val[ci] = 0; + } + + /* Precalculate decoding info for each block in an MCU of this scan */ + for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { + ci = cinfo->MCU_membership[blkn]; + compptr = cinfo->cur_comp_info[ci]; + /* Precalculate which table to use for each block */ + entropy->dc_cur_tbls[blkn] = entropy->dc_derived_tbls[compptr->dc_tbl_no]; + entropy->ac_cur_tbls[blkn] = entropy->ac_derived_tbls[compptr->ac_tbl_no]; + /* Decide whether we really care about the coefficient values */ + if (compptr->component_needed) { + entropy->dc_needed[blkn] = TRUE; + /* we don't need the ACs if producing a 1/8th-size image */ + entropy->ac_needed[blkn] = (compptr->DCT_scaled_size > 1); + } else { + entropy->dc_needed[blkn] = entropy->ac_needed[blkn] = FALSE; + } + } + + /* Initialize bitread state variables */ + entropy->bitstate.bits_left = 0; + entropy->bitstate.get_buffer = 0; /* unnecessary, but keeps Purify quiet */ + entropy->pub.insufficient_data = FALSE; + + /* Initialize restart counter */ + entropy->restarts_to_go = cinfo->restart_interval; +} + + +/* + * Compute the derived values for a Huffman table. + * This routine also performs some validation checks on the table. + * + * Note this is also used by jdphuff.c. + */ + +GLOBAL(void) +jpeg_make_d_derived_tbl (j_decompress_ptr cinfo, boolean isDC, int tblno, + d_derived_tbl ** pdtbl) +{ + JHUFF_TBL *htbl; + d_derived_tbl *dtbl; + int p, i, l, si, numsymbols; + int lookbits, ctr; + char huffsize[257]; + unsigned int huffcode[257]; + unsigned int code; + + /* Note that huffsize[] and huffcode[] are filled in code-length order, + * paralleling the order of the symbols themselves in htbl->huffval[]. + */ + + /* Find the input Huffman table */ + if (tblno < 0 || tblno >= NUM_HUFF_TBLS) + ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno); + htbl = + isDC ? cinfo->dc_huff_tbl_ptrs[tblno] : cinfo->ac_huff_tbl_ptrs[tblno]; + if (htbl == NULL) + ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno); + + /* Allocate a workspace if we haven't already done so. */ + if (*pdtbl == NULL) + *pdtbl = (d_derived_tbl *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(d_derived_tbl)); + dtbl = *pdtbl; + dtbl->pub = htbl; /* fill in back link */ + + /* Figure C.1: make table of Huffman code length for each symbol */ + + p = 0; + for (l = 1; l <= 16; l++) { + i = (int) htbl->bits[l]; + if (i < 0 || p + i > 256) /* protect against table overrun */ + ERREXIT(cinfo, JERR_BAD_HUFF_TABLE); + while (i--) + huffsize[p++] = (char) l; + } + huffsize[p] = 0; + numsymbols = p; + + /* Figure C.2: generate the codes themselves */ + /* We also validate that the counts represent a legal Huffman code tree. */ + + code = 0; + si = huffsize[0]; + p = 0; + while (huffsize[p]) { + while (((int) huffsize[p]) == si) { + huffcode[p++] = code; + code++; + } + /* code is now 1 more than the last code used for codelength si; but + * it must still fit in si bits, since no code is allowed to be all ones. + */ + if (((INT32) code) >= (((INT32) 1) << si)) + ERREXIT(cinfo, JERR_BAD_HUFF_TABLE); + code <<= 1; + si++; + } + + /* Figure F.15: generate decoding tables for bit-sequential decoding */ + + p = 0; + for (l = 1; l <= 16; l++) { + if (htbl->bits[l]) { + /* valoffset[l] = huffval[] index of 1st symbol of code length l, + * minus the minimum code of length l + */ + dtbl->valoffset[l] = (INT32) p - (INT32) huffcode[p]; + p += htbl->bits[l]; + dtbl->maxcode[l] = huffcode[p-1]; /* maximum code of length l */ + } else { + dtbl->maxcode[l] = -1; /* -1 if no codes of this length */ + } + } + dtbl->maxcode[17] = 0xFFFFFL; /* ensures jpeg_huff_decode terminates */ + + /* Compute lookahead tables to speed up decoding. + * First we set all the table entries to 0, indicating "too long"; + * then we iterate through the Huffman codes that are short enough and + * fill in all the entries that correspond to bit sequences starting + * with that code. + */ + + MEMZERO(dtbl->look_nbits, SIZEOF(dtbl->look_nbits)); + + p = 0; + for (l = 1; l <= HUFF_LOOKAHEAD; l++) { + for (i = 1; i <= (int) htbl->bits[l]; i++, p++) { + /* l = current code's length, p = its index in huffcode[] & huffval[]. */ + /* Generate left-justified code followed by all possible bit sequences */ + lookbits = huffcode[p] << (HUFF_LOOKAHEAD-l); + for (ctr = 1 << (HUFF_LOOKAHEAD-l); ctr > 0; ctr--) { + dtbl->look_nbits[lookbits] = l; + dtbl->look_sym[lookbits] = htbl->huffval[p]; + lookbits++; + } + } + } + + /* Validate symbols as being reasonable. + * For AC tables, we make no check, but accept all byte values 0..255. + * For DC tables, we require the symbols to be in range 0..15. + * (Tighter bounds could be applied depending on the data depth and mode, + * but this is sufficient to ensure safe decoding.) + */ + if (isDC) { + for (i = 0; i < numsymbols; i++) { + int sym = htbl->huffval[i]; + if (sym < 0 || sym > 15) + ERREXIT(cinfo, JERR_BAD_HUFF_TABLE); + } + } +} + + +/* + * Out-of-line code for bit fetching (shared with jdphuff.c). + * See jdhuff.h for info about usage. + * Note: current values of get_buffer and bits_left are passed as parameters, + * but are returned in the corresponding fields of the state struct. + * + * On most machines MIN_GET_BITS should be 25 to allow the full 32-bit width + * of get_buffer to be used. (On machines with wider words, an even larger + * buffer could be used.) However, on some machines 32-bit shifts are + * quite slow and take time proportional to the number of places shifted. + * (This is true with most PC compilers, for instance.) In this case it may + * be a win to set MIN_GET_BITS to the minimum value of 15. This reduces the + * average shift distance at the cost of more calls to jpeg_fill_bit_buffer. + */ + +#ifdef SLOW_SHIFT_32 +#define MIN_GET_BITS 15 /* minimum allowable value */ +#else +#define MIN_GET_BITS (BIT_BUF_SIZE-7) +#endif + + +GLOBAL(boolean) +jpeg_fill_bit_buffer (bitread_working_state * state, + register bit_buf_type get_buffer, register int bits_left, + int nbits) +/* Load up the bit buffer to a depth of at least nbits */ +{ + /* Copy heavily used state fields into locals (hopefully registers) */ + register const JOCTET * next_input_byte = state->next_input_byte; + register size_t bytes_in_buffer = state->bytes_in_buffer; + j_decompress_ptr cinfo = state->cinfo; + + /* Attempt to load at least MIN_GET_BITS bits into get_buffer. */ + /* (It is assumed that no request will be for more than that many bits.) */ + /* We fail to do so only if we hit a marker or are forced to suspend. */ + + if (cinfo->unread_marker == 0) { /* cannot advance past a marker */ + while (bits_left < MIN_GET_BITS) { + register int c; + + /* Attempt to read a byte */ + if (bytes_in_buffer == 0) { + if (! (*cinfo->src->fill_input_buffer) (cinfo)) + return FALSE; + next_input_byte = cinfo->src->next_input_byte; + bytes_in_buffer = cinfo->src->bytes_in_buffer; + } + bytes_in_buffer--; + c = GETJOCTET(*next_input_byte++); + + /* If it's 0xFF, check and discard stuffed zero byte */ + if (c == 0xFF) { + /* Loop here to discard any padding FF's on terminating marker, + * so that we can save a valid unread_marker value. NOTE: we will + * accept multiple FF's followed by a 0 as meaning a single FF data + * byte. This data pattern is not valid according to the standard. + */ + do { + if (bytes_in_buffer == 0) { + if (! (*cinfo->src->fill_input_buffer) (cinfo)) + return FALSE; + next_input_byte = cinfo->src->next_input_byte; + bytes_in_buffer = cinfo->src->bytes_in_buffer; + } + bytes_in_buffer--; + c = GETJOCTET(*next_input_byte++); + } while (c == 0xFF); + + if (c == 0) { + /* Found FF/00, which represents an FF data byte */ + c = 0xFF; + } else { + /* Oops, it's actually a marker indicating end of compressed data. + * Save the marker code for later use. + * Fine point: it might appear that we should save the marker into + * bitread working state, not straight into permanent state. But + * once we have hit a marker, we cannot need to suspend within the + * current MCU, because we will read no more bytes from the data + * source. So it is OK to update permanent state right away. + */ + cinfo->unread_marker = c; + /* See if we need to insert some fake zero bits. */ + goto no_more_bytes; + } + } + + /* OK, load c into get_buffer */ + get_buffer = (get_buffer << 8) | c; + bits_left += 8; + } /* end while */ + } else { + no_more_bytes: + /* We get here if we've read the marker that terminates the compressed + * data segment. There should be enough bits in the buffer register + * to satisfy the request; if so, no problem. + */ + if (nbits > bits_left) { + /* Uh-oh. Report corrupted data to user and stuff zeroes into + * the data stream, so that we can produce some kind of image. + * We use a nonvolatile flag to ensure that only one warning message + * appears per data segment. + */ + if (! cinfo->entropy->insufficient_data) { + WARNMS(cinfo, JWRN_HIT_MARKER); + cinfo->entropy->insufficient_data = TRUE; + } + /* Fill the buffer with zero bits */ + get_buffer <<= MIN_GET_BITS - bits_left; + bits_left = MIN_GET_BITS; + } + } + + /* Unload the local registers */ + state->next_input_byte = next_input_byte; + state->bytes_in_buffer = bytes_in_buffer; + state->get_buffer = get_buffer; + state->bits_left = bits_left; + + return TRUE; +} + + +/* + * Out-of-line code for Huffman code decoding. + * See jdhuff.h for info about usage. + */ + +GLOBAL(int) +jpeg_huff_decode (bitread_working_state * state, + register bit_buf_type get_buffer, register int bits_left, + d_derived_tbl * htbl, int min_bits) +{ + register int l = min_bits; + register INT32 code; + + /* HUFF_DECODE has determined that the code is at least min_bits */ + /* bits long, so fetch that many bits in one swoop. */ + + CHECK_BIT_BUFFER(*state, l, return -1); + code = GET_BITS(l); + + /* Collect the rest of the Huffman code one bit at a time. */ + /* This is per Figure F.16 in the JPEG spec. */ + + while (code > htbl->maxcode[l]) { + code <<= 1; + CHECK_BIT_BUFFER(*state, 1, return -1); + code |= GET_BITS(1); + l++; + } + + /* Unload the local registers */ + state->get_buffer = get_buffer; + state->bits_left = bits_left; + + /* With garbage input we may reach the sentinel value l = 17. */ + + if (l > 16) { + WARNMS(state->cinfo, JWRN_HUFF_BAD_CODE); + return 0; /* fake a zero as the safest result */ + } + + return htbl->pub->huffval[ (int) (code + htbl->valoffset[l]) ]; +} + + +/* + * Figure F.12: extend sign bit. + * On some machines, a shift and add will be faster than a table lookup. + */ + +#ifdef AVOID_TABLES + +#define HUFF_EXTEND(x,s) ((x) < (1<<((s)-1)) ? (x) + (((-1)<<(s)) + 1) : (x)) + +#else + +#define HUFF_EXTEND(x,s) ((x) < extend_test[s] ? (x) + extend_offset[s] : (x)) + +static const int extend_test[16] = /* entry n is 2**(n-1) */ + { 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, + 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 }; + +static const int extend_offset[16] = /* entry n is (-1 << n) + 1 */ + { 0, ((-1)<<1) + 1, ((-1)<<2) + 1, ((-1)<<3) + 1, ((-1)<<4) + 1, + ((-1)<<5) + 1, ((-1)<<6) + 1, ((-1)<<7) + 1, ((-1)<<8) + 1, + ((-1)<<9) + 1, ((-1)<<10) + 1, ((-1)<<11) + 1, ((-1)<<12) + 1, + ((-1)<<13) + 1, ((-1)<<14) + 1, ((-1)<<15) + 1 }; + +#endif /* AVOID_TABLES */ + + +/* + * Check for a restart marker & resynchronize decoder. + * Returns FALSE if must suspend. + */ + +LOCAL(boolean) +process_restart (j_decompress_ptr cinfo) +{ + huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; + int ci; + + /* Throw away any unused bits remaining in bit buffer; */ + /* include any full bytes in next_marker's count of discarded bytes */ + cinfo->marker->discarded_bytes += entropy->bitstate.bits_left / 8; + entropy->bitstate.bits_left = 0; + + /* Advance past the RSTn marker */ + if (! (*cinfo->marker->read_restart_marker) (cinfo)) + return FALSE; + + /* Re-initialize DC predictions to 0 */ + for (ci = 0; ci < cinfo->comps_in_scan; ci++) + entropy->saved.last_dc_val[ci] = 0; + + /* Reset restart counter */ + entropy->restarts_to_go = cinfo->restart_interval; + + /* Reset out-of-data flag, unless read_restart_marker left us smack up + * against a marker. In that case we will end up treating the next data + * segment as empty, and we can avoid producing bogus output pixels by + * leaving the flag set. + */ + if (cinfo->unread_marker == 0) + entropy->pub.insufficient_data = FALSE; + + return TRUE; +} + + +/* + * Decode and return one MCU's worth of Huffman-compressed coefficients. + * The coefficients are reordered from zigzag order into natural array order, + * but are not dequantized. + * + * The i'th block of the MCU is stored into the block pointed to by + * MCU_data[i]. WE ASSUME THIS AREA HAS BEEN ZEROED BY THE CALLER. + * (Wholesale zeroing is usually a little faster than retail...) + * + * Returns FALSE if data source requested suspension. In that case no + * changes have been made to permanent state. (Exception: some output + * coefficients may already have been assigned. This is harmless for + * this module, since we'll just re-assign them on the next call.) + */ + +METHODDEF(boolean) +decode_mcu (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) +{ + huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; + int blkn; + BITREAD_STATE_VARS; + savable_state state; + + /* Process restart marker if needed; may have to suspend */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) + if (! process_restart(cinfo)) + return FALSE; + } + + /* If we've run out of data, just leave the MCU set to zeroes. + * This way, we return uniform gray for the remainder of the segment. + */ + if (! entropy->pub.insufficient_data) { + + /* Load up working state */ + BITREAD_LOAD_STATE(cinfo,entropy->bitstate); + ASSIGN_STATE(state, entropy->saved); + + /* Outer loop handles each block in the MCU */ + + for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { + JBLOCKROW block = MCU_data[blkn]; + d_derived_tbl * dctbl = entropy->dc_cur_tbls[blkn]; + d_derived_tbl * actbl = entropy->ac_cur_tbls[blkn]; + register int s, k, r; + + /* Decode a single block's worth of coefficients */ + + /* Section F.2.2.1: decode the DC coefficient difference */ + HUFF_DECODE(s, br_state, dctbl, return FALSE, label1); + if (s) { + CHECK_BIT_BUFFER(br_state, s, return FALSE); + r = GET_BITS(s); + s = HUFF_EXTEND(r, s); + } + + if (entropy->dc_needed[blkn]) { + /* Convert DC difference to actual value, update last_dc_val */ + int ci = cinfo->MCU_membership[blkn]; + s += state.last_dc_val[ci]; + state.last_dc_val[ci] = s; + /* Output the DC coefficient (assumes jpeg_natural_order[0] = 0) */ + (*block)[0] = (JCOEF) s; + } + + if (entropy->ac_needed[blkn]) { + + /* Section F.2.2.2: decode the AC coefficients */ + /* Since zeroes are skipped, output area must be cleared beforehand */ + for (k = 1; k < DCTSIZE2; k++) { + HUFF_DECODE(s, br_state, actbl, return FALSE, label2); + + r = s >> 4; + s &= 15; + + if (s) { + k += r; + CHECK_BIT_BUFFER(br_state, s, return FALSE); + r = GET_BITS(s); + s = HUFF_EXTEND(r, s); + /* Output coefficient in natural (dezigzagged) order. + * Note: the extra entries in jpeg_natural_order[] will save us + * if k >= DCTSIZE2, which could happen if the data is corrupted. + */ + (*block)[jpeg_natural_order[k]] = (JCOEF) s; + } else { + if (r != 15) + break; + k += 15; + } + } + + } else { + + /* Section F.2.2.2: decode the AC coefficients */ + /* In this path we just discard the values */ + for (k = 1; k < DCTSIZE2; k++) { + HUFF_DECODE(s, br_state, actbl, return FALSE, label3); + + r = s >> 4; + s &= 15; + + if (s) { + k += r; + CHECK_BIT_BUFFER(br_state, s, return FALSE); + DROP_BITS(s); + } else { + if (r != 15) + break; + k += 15; + } + } + + } + } + + /* Completed MCU, so update state */ + BITREAD_SAVE_STATE(cinfo,entropy->bitstate); + ASSIGN_STATE(entropy->saved, state); + } + + /* Account for restart interval (no-op if not using restarts) */ + entropy->restarts_to_go--; + + return TRUE; +} + + +/* + * Module initialization routine for Huffman entropy decoding. + */ + +GLOBAL(void) +jinit_huff_decoder (j_decompress_ptr cinfo) +{ + huff_entropy_ptr entropy; + int i; + + entropy = (huff_entropy_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(huff_entropy_decoder)); + cinfo->entropy = (struct jpeg_entropy_decoder *) entropy; + entropy->pub.start_pass = start_pass_huff_decoder; + entropy->pub.decode_mcu = decode_mcu; + + /* Mark tables unallocated */ + for (i = 0; i < NUM_HUFF_TBLS; i++) { + entropy->dc_derived_tbls[i] = entropy->ac_derived_tbls[i] = NULL; + } +} diff --git a/mod/pub.mod/libjpeg.mod/jdhuff.h b/mod/pub.mod/libjpeg.mod/jdhuff.h new file mode 100644 index 0000000..ae19b6c --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jdhuff.h @@ -0,0 +1,201 @@ +/* + * jdhuff.h + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains declarations for Huffman entropy decoding routines + * that are shared between the sequential decoder (jdhuff.c) and the + * progressive decoder (jdphuff.c). No other modules need to see these. + */ + +/* Short forms of external names for systems with brain-damaged linkers. */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jpeg_make_d_derived_tbl jMkDDerived +#define jpeg_fill_bit_buffer jFilBitBuf +#define jpeg_huff_decode jHufDecode +#endif /* NEED_SHORT_EXTERNAL_NAMES */ + + +/* Derived data constructed for each Huffman table */ + +#define HUFF_LOOKAHEAD 8 /* # of bits of lookahead */ + +typedef struct { + /* Basic tables: (element [0] of each array is unused) */ + INT32 maxcode[18]; /* largest code of length k (-1 if none) */ + /* (maxcode[17] is a sentinel to ensure jpeg_huff_decode terminates) */ + INT32 valoffset[17]; /* huffval[] offset for codes of length k */ + /* valoffset[k] = huffval[] index of 1st symbol of code length k, less + * the smallest code of length k; so given a code of length k, the + * corresponding symbol is huffval[code + valoffset[k]] + */ + + /* Link to public Huffman table (needed only in jpeg_huff_decode) */ + JHUFF_TBL *pub; + + /* Lookahead tables: indexed by the next HUFF_LOOKAHEAD bits of + * the input data stream. If the next Huffman code is no more + * than HUFF_LOOKAHEAD bits long, we can obtain its length and + * the corresponding symbol directly from these tables. + */ + int look_nbits[1<<HUFF_LOOKAHEAD]; /* # bits, or 0 if too long */ + UINT8 look_sym[1<<HUFF_LOOKAHEAD]; /* symbol, or unused */ +} d_derived_tbl; + +/* Expand a Huffman table definition into the derived format */ +EXTERN(void) jpeg_make_d_derived_tbl + JPP((j_decompress_ptr cinfo, boolean isDC, int tblno, + d_derived_tbl ** pdtbl)); + + +/* + * Fetching the next N bits from the input stream is a time-critical operation + * for the Huffman decoders. We implement it with a combination of inline + * macros and out-of-line subroutines. Note that N (the number of bits + * demanded at one time) never exceeds 15 for JPEG use. + * + * We read source bytes into get_buffer and dole out bits as needed. + * If get_buffer already contains enough bits, they are fetched in-line + * by the macros CHECK_BIT_BUFFER and GET_BITS. When there aren't enough + * bits, jpeg_fill_bit_buffer is called; it will attempt to fill get_buffer + * as full as possible (not just to the number of bits needed; this + * prefetching reduces the overhead cost of calling jpeg_fill_bit_buffer). + * Note that jpeg_fill_bit_buffer may return FALSE to indicate suspension. + * On TRUE return, jpeg_fill_bit_buffer guarantees that get_buffer contains + * at least the requested number of bits --- dummy zeroes are inserted if + * necessary. + */ + +typedef INT32 bit_buf_type; /* type of bit-extraction buffer */ +#define BIT_BUF_SIZE 32 /* size of buffer in bits */ + +/* If long is > 32 bits on your machine, and shifting/masking longs is + * reasonably fast, making bit_buf_type be long and setting BIT_BUF_SIZE + * appropriately should be a win. Unfortunately we can't define the size + * with something like #define BIT_BUF_SIZE (sizeof(bit_buf_type)*8) + * because not all machines measure sizeof in 8-bit bytes. + */ + +typedef struct { /* Bitreading state saved across MCUs */ + bit_buf_type get_buffer; /* current bit-extraction buffer */ + int bits_left; /* # of unused bits in it */ +} bitread_perm_state; + +typedef struct { /* Bitreading working state within an MCU */ + /* Current data source location */ + /* We need a copy, rather than munging the original, in case of suspension */ + const JOCTET * next_input_byte; /* => next byte to read from source */ + size_t bytes_in_buffer; /* # of bytes remaining in source buffer */ + /* Bit input buffer --- note these values are kept in register variables, + * not in this struct, inside the inner loops. + */ + bit_buf_type get_buffer; /* current bit-extraction buffer */ + int bits_left; /* # of unused bits in it */ + /* Pointer needed by jpeg_fill_bit_buffer. */ + j_decompress_ptr cinfo; /* back link to decompress master record */ +} bitread_working_state; + +/* Macros to declare and load/save bitread local variables. */ +#define BITREAD_STATE_VARS \ + register bit_buf_type get_buffer; \ + register int bits_left; \ + bitread_working_state br_state + +#define BITREAD_LOAD_STATE(cinfop,permstate) \ + br_state.cinfo = cinfop; \ + br_state.next_input_byte = cinfop->src->next_input_byte; \ + br_state.bytes_in_buffer = cinfop->src->bytes_in_buffer; \ + get_buffer = permstate.get_buffer; \ + bits_left = permstate.bits_left; + +#define BITREAD_SAVE_STATE(cinfop,permstate) \ + cinfop->src->next_input_byte = br_state.next_input_byte; \ + cinfop->src->bytes_in_buffer = br_state.bytes_in_buffer; \ + permstate.get_buffer = get_buffer; \ + permstate.bits_left = bits_left + +/* + * These macros provide the in-line portion of bit fetching. + * Use CHECK_BIT_BUFFER to ensure there are N bits in get_buffer + * before using GET_BITS, PEEK_BITS, or DROP_BITS. + * The variables get_buffer and bits_left are assumed to be locals, + * but the state struct might not be (jpeg_huff_decode needs this). + * CHECK_BIT_BUFFER(state,n,action); + * Ensure there are N bits in get_buffer; if suspend, take action. + * val = GET_BITS(n); + * Fetch next N bits. + * val = PEEK_BITS(n); + * Fetch next N bits without removing them from the buffer. + * DROP_BITS(n); + * Discard next N bits. + * The value N should be a simple variable, not an expression, because it + * is evaluated multiple times. + */ + +#define CHECK_BIT_BUFFER(state,nbits,action) \ + { if (bits_left < (nbits)) { \ + if (! jpeg_fill_bit_buffer(&(state),get_buffer,bits_left,nbits)) \ + { action; } \ + get_buffer = (state).get_buffer; bits_left = (state).bits_left; } } + +#define GET_BITS(nbits) \ + (((int) (get_buffer >> (bits_left -= (nbits)))) & ((1<<(nbits))-1)) + +#define PEEK_BITS(nbits) \ + (((int) (get_buffer >> (bits_left - (nbits)))) & ((1<<(nbits))-1)) + +#define DROP_BITS(nbits) \ + (bits_left -= (nbits)) + +/* Load up the bit buffer to a depth of at least nbits */ +EXTERN(boolean) jpeg_fill_bit_buffer + JPP((bitread_working_state * state, register bit_buf_type get_buffer, + register int bits_left, int nbits)); + + +/* + * Code for extracting next Huffman-coded symbol from input bit stream. + * Again, this is time-critical and we make the main paths be macros. + * + * We use a lookahead table to process codes of up to HUFF_LOOKAHEAD bits + * without looping. Usually, more than 95% of the Huffman codes will be 8 + * or fewer bits long. The few overlength codes are handled with a loop, + * which need not be inline code. + * + * Notes about the HUFF_DECODE macro: + * 1. Near the end of the data segment, we may fail to get enough bits + * for a lookahead. In that case, we do it the hard way. + * 2. If the lookahead table contains no entry, the next code must be + * more than HUFF_LOOKAHEAD bits long. + * 3. jpeg_huff_decode returns -1 if forced to suspend. + */ + +#define HUFF_DECODE(result,state,htbl,failaction,slowlabel) \ +{ register int nb, look; \ + if (bits_left < HUFF_LOOKAHEAD) { \ + if (! jpeg_fill_bit_buffer(&state,get_buffer,bits_left, 0)) {failaction;} \ + get_buffer = state.get_buffer; bits_left = state.bits_left; \ + if (bits_left < HUFF_LOOKAHEAD) { \ + nb = 1; goto slowlabel; \ + } \ + } \ + look = PEEK_BITS(HUFF_LOOKAHEAD); \ + if ((nb = htbl->look_nbits[look]) != 0) { \ + DROP_BITS(nb); \ + result = htbl->look_sym[look]; \ + } else { \ + nb = HUFF_LOOKAHEAD+1; \ +slowlabel: \ + if ((result=jpeg_huff_decode(&state,get_buffer,bits_left,htbl,nb)) < 0) \ + { failaction; } \ + get_buffer = state.get_buffer; bits_left = state.bits_left; \ + } \ +} + +/* Out-of-line case for Huffman code fetching */ +EXTERN(int) jpeg_huff_decode + JPP((bitread_working_state * state, register bit_buf_type get_buffer, + register int bits_left, d_derived_tbl * htbl, int min_bits)); diff --git a/mod/pub.mod/libjpeg.mod/jdinput.c b/mod/pub.mod/libjpeg.mod/jdinput.c new file mode 100644 index 0000000..0c2ac8f --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jdinput.c @@ -0,0 +1,381 @@ +/* + * jdinput.c + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains input control logic for the JPEG decompressor. + * These routines are concerned with controlling the decompressor's input + * processing (marker reading and coefficient decoding). The actual input + * reading is done in jdmarker.c, jdhuff.c, and jdphuff.c. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* Private state */ + +typedef struct { + struct jpeg_input_controller pub; /* public fields */ + + boolean inheaders; /* TRUE until first SOS is reached */ +} my_input_controller; + +typedef my_input_controller * my_inputctl_ptr; + + +/* Forward declarations */ +METHODDEF(int) consume_markers JPP((j_decompress_ptr cinfo)); + + +/* + * Routines to calculate various quantities related to the size of the image. + */ + +LOCAL(void) +initial_setup (j_decompress_ptr cinfo) +/* Called once, when first SOS marker is reached */ +{ + int ci; + jpeg_component_info *compptr; + + /* Make sure image isn't bigger than I can handle */ + if ((long) cinfo->image_height > (long) JPEG_MAX_DIMENSION || + (long) cinfo->image_width > (long) JPEG_MAX_DIMENSION) + ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) JPEG_MAX_DIMENSION); + + /* For now, precision must match compiled-in value... */ + if (cinfo->data_precision != BITS_IN_JSAMPLE) + ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision); + + /* Check that number of components won't exceed internal array sizes */ + if (cinfo->num_components > MAX_COMPONENTS) + ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components, + MAX_COMPONENTS); + + /* Compute maximum sampling factors; check factor validity */ + cinfo->max_h_samp_factor = 1; + cinfo->max_v_samp_factor = 1; + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + if (compptr->h_samp_factor<=0 || compptr->h_samp_factor>MAX_SAMP_FACTOR || + compptr->v_samp_factor<=0 || compptr->v_samp_factor>MAX_SAMP_FACTOR) + ERREXIT(cinfo, JERR_BAD_SAMPLING); + cinfo->max_h_samp_factor = MAX(cinfo->max_h_samp_factor, + compptr->h_samp_factor); + cinfo->max_v_samp_factor = MAX(cinfo->max_v_samp_factor, + compptr->v_samp_factor); + } + + /* We initialize DCT_scaled_size and min_DCT_scaled_size to DCTSIZE. + * In the full decompressor, this will be overridden by jdmaster.c; + * but in the transcoder, jdmaster.c is not used, so we must do it here. + */ + cinfo->min_DCT_scaled_size = DCTSIZE; + + /* Compute dimensions of components */ + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + compptr->DCT_scaled_size = DCTSIZE; + /* Size in DCT blocks */ + compptr->width_in_blocks = (JDIMENSION) + jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor, + (long) (cinfo->max_h_samp_factor * DCTSIZE)); + compptr->height_in_blocks = (JDIMENSION) + jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor, + (long) (cinfo->max_v_samp_factor * DCTSIZE)); + /* downsampled_width and downsampled_height will also be overridden by + * jdmaster.c if we are doing full decompression. The transcoder library + * doesn't use these values, but the calling application might. + */ + /* Size in samples */ + compptr->downsampled_width = (JDIMENSION) + jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor, + (long) cinfo->max_h_samp_factor); + compptr->downsampled_height = (JDIMENSION) + jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor, + (long) cinfo->max_v_samp_factor); + /* Mark component needed, until color conversion says otherwise */ + compptr->component_needed = TRUE; + /* Mark no quantization table yet saved for component */ + compptr->quant_table = NULL; + } + + /* Compute number of fully interleaved MCU rows. */ + cinfo->total_iMCU_rows = (JDIMENSION) + jdiv_round_up((long) cinfo->image_height, + (long) (cinfo->max_v_samp_factor*DCTSIZE)); + + /* Decide whether file contains multiple scans */ + if (cinfo->comps_in_scan < cinfo->num_components || cinfo->progressive_mode) + cinfo->inputctl->has_multiple_scans = TRUE; + else + cinfo->inputctl->has_multiple_scans = FALSE; +} + + +LOCAL(void) +per_scan_setup (j_decompress_ptr cinfo) +/* Do computations that are needed before processing a JPEG scan */ +/* cinfo->comps_in_scan and cinfo->cur_comp_info[] were set from SOS marker */ +{ + int ci, mcublks, tmp; + jpeg_component_info *compptr; + + if (cinfo->comps_in_scan == 1) { + + /* Noninterleaved (single-component) scan */ + compptr = cinfo->cur_comp_info[0]; + + /* Overall image size in MCUs */ + cinfo->MCUs_per_row = compptr->width_in_blocks; + cinfo->MCU_rows_in_scan = compptr->height_in_blocks; + + /* For noninterleaved scan, always one block per MCU */ + compptr->MCU_width = 1; + compptr->MCU_height = 1; + compptr->MCU_blocks = 1; + compptr->MCU_sample_width = compptr->DCT_scaled_size; + compptr->last_col_width = 1; + /* For noninterleaved scans, it is convenient to define last_row_height + * as the number of block rows present in the last iMCU row. + */ + tmp = (int) (compptr->height_in_blocks % compptr->v_samp_factor); + if (tmp == 0) tmp = compptr->v_samp_factor; + compptr->last_row_height = tmp; + + /* Prepare array describing MCU composition */ + cinfo->blocks_in_MCU = 1; + cinfo->MCU_membership[0] = 0; + + } else { + + /* Interleaved (multi-component) scan */ + if (cinfo->comps_in_scan <= 0 || cinfo->comps_in_scan > MAX_COMPS_IN_SCAN) + ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->comps_in_scan, + MAX_COMPS_IN_SCAN); + + /* Overall image size in MCUs */ + cinfo->MCUs_per_row = (JDIMENSION) + jdiv_round_up((long) cinfo->image_width, + (long) (cinfo->max_h_samp_factor*DCTSIZE)); + cinfo->MCU_rows_in_scan = (JDIMENSION) + jdiv_round_up((long) cinfo->image_height, + (long) (cinfo->max_v_samp_factor*DCTSIZE)); + + cinfo->blocks_in_MCU = 0; + + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + /* Sampling factors give # of blocks of component in each MCU */ + compptr->MCU_width = compptr->h_samp_factor; + compptr->MCU_height = compptr->v_samp_factor; + compptr->MCU_blocks = compptr->MCU_width * compptr->MCU_height; + compptr->MCU_sample_width = compptr->MCU_width * compptr->DCT_scaled_size; + /* Figure number of non-dummy blocks in last MCU column & row */ + tmp = (int) (compptr->width_in_blocks % compptr->MCU_width); + if (tmp == 0) tmp = compptr->MCU_width; + compptr->last_col_width = tmp; + tmp = (int) (compptr->height_in_blocks % compptr->MCU_height); + if (tmp == 0) tmp = compptr->MCU_height; + compptr->last_row_height = tmp; + /* Prepare array describing MCU composition */ + mcublks = compptr->MCU_blocks; + if (cinfo->blocks_in_MCU + mcublks > D_MAX_BLOCKS_IN_MCU) + ERREXIT(cinfo, JERR_BAD_MCU_SIZE); + while (mcublks-- > 0) { + cinfo->MCU_membership[cinfo->blocks_in_MCU++] = ci; + } + } + + } +} + + +/* + * Save away a copy of the Q-table referenced by each component present + * in the current scan, unless already saved during a prior scan. + * + * In a multiple-scan JPEG file, the encoder could assign different components + * the same Q-table slot number, but change table definitions between scans + * so that each component uses a different Q-table. (The IJG encoder is not + * currently capable of doing this, but other encoders might.) Since we want + * to be able to dequantize all the components at the end of the file, this + * means that we have to save away the table actually used for each component. + * We do this by copying the table at the start of the first scan containing + * the component. + * The JPEG spec prohibits the encoder from changing the contents of a Q-table + * slot between scans of a component using that slot. If the encoder does so + * anyway, this decoder will simply use the Q-table values that were current + * at the start of the first scan for the component. + * + * The decompressor output side looks only at the saved quant tables, + * not at the current Q-table slots. + */ + +LOCAL(void) +latch_quant_tables (j_decompress_ptr cinfo) +{ + int ci, qtblno; + jpeg_component_info *compptr; + JQUANT_TBL * qtbl; + + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + /* No work if we already saved Q-table for this component */ + if (compptr->quant_table != NULL) + continue; + /* Make sure specified quantization table is present */ + qtblno = compptr->quant_tbl_no; + if (qtblno < 0 || qtblno >= NUM_QUANT_TBLS || + cinfo->quant_tbl_ptrs[qtblno] == NULL) + ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, qtblno); + /* OK, save away the quantization table */ + qtbl = (JQUANT_TBL *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(JQUANT_TBL)); + MEMCOPY(qtbl, cinfo->quant_tbl_ptrs[qtblno], SIZEOF(JQUANT_TBL)); + compptr->quant_table = qtbl; + } +} + + +/* + * Initialize the input modules to read a scan of compressed data. + * The first call to this is done by jdmaster.c after initializing + * the entire decompressor (during jpeg_start_decompress). + * Subsequent calls come from consume_markers, below. + */ + +METHODDEF(void) +start_input_pass (j_decompress_ptr cinfo) +{ + per_scan_setup(cinfo); + latch_quant_tables(cinfo); + (*cinfo->entropy->start_pass) (cinfo); + (*cinfo->coef->start_input_pass) (cinfo); + cinfo->inputctl->consume_input = cinfo->coef->consume_data; +} + + +/* + * Finish up after inputting a compressed-data scan. + * This is called by the coefficient controller after it's read all + * the expected data of the scan. + */ + +METHODDEF(void) +finish_input_pass (j_decompress_ptr cinfo) +{ + cinfo->inputctl->consume_input = consume_markers; +} + + +/* + * Read JPEG markers before, between, or after compressed-data scans. + * Change state as necessary when a new scan is reached. + * Return value is JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI. + * + * The consume_input method pointer points either here or to the + * coefficient controller's consume_data routine, depending on whether + * we are reading a compressed data segment or inter-segment markers. + */ + +METHODDEF(int) +consume_markers (j_decompress_ptr cinfo) +{ + my_inputctl_ptr inputctl = (my_inputctl_ptr) cinfo->inputctl; + int val; + + if (inputctl->pub.eoi_reached) /* After hitting EOI, read no further */ + return JPEG_REACHED_EOI; + + val = (*cinfo->marker->read_markers) (cinfo); + + switch (val) { + case JPEG_REACHED_SOS: /* Found SOS */ + if (inputctl->inheaders) { /* 1st SOS */ + initial_setup(cinfo); + inputctl->inheaders = FALSE; + /* Note: start_input_pass must be called by jdmaster.c + * before any more input can be consumed. jdapimin.c is + * responsible for enforcing this sequencing. + */ + } else { /* 2nd or later SOS marker */ + if (! inputctl->pub.has_multiple_scans) + ERREXIT(cinfo, JERR_EOI_EXPECTED); /* Oops, I wasn't expecting this! */ + start_input_pass(cinfo); + } + break; + case JPEG_REACHED_EOI: /* Found EOI */ + inputctl->pub.eoi_reached = TRUE; + if (inputctl->inheaders) { /* Tables-only datastream, apparently */ + if (cinfo->marker->saw_SOF) + ERREXIT(cinfo, JERR_SOF_NO_SOS); + } else { + /* Prevent infinite loop in coef ctlr's decompress_data routine + * if user set output_scan_number larger than number of scans. + */ + if (cinfo->output_scan_number > cinfo->input_scan_number) + cinfo->output_scan_number = cinfo->input_scan_number; + } + break; + case JPEG_SUSPENDED: + break; + } + + return val; +} + + +/* + * Reset state to begin a fresh datastream. + */ + +METHODDEF(void) +reset_input_controller (j_decompress_ptr cinfo) +{ + my_inputctl_ptr inputctl = (my_inputctl_ptr) cinfo->inputctl; + + inputctl->pub.consume_input = consume_markers; + inputctl->pub.has_multiple_scans = FALSE; /* "unknown" would be better */ + inputctl->pub.eoi_reached = FALSE; + inputctl->inheaders = TRUE; + /* Reset other modules */ + (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo); + (*cinfo->marker->reset_marker_reader) (cinfo); + /* Reset progression state -- would be cleaner if entropy decoder did this */ + cinfo->coef_bits = NULL; +} + + +/* + * Initialize the input controller module. + * This is called only once, when the decompression object is created. + */ + +GLOBAL(void) +jinit_input_controller (j_decompress_ptr cinfo) +{ + my_inputctl_ptr inputctl; + + /* Create subobject in permanent pool */ + inputctl = (my_inputctl_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, + SIZEOF(my_input_controller)); + cinfo->inputctl = (struct jpeg_input_controller *) inputctl; + /* Initialize method pointers */ + inputctl->pub.consume_input = consume_markers; + inputctl->pub.reset_input_controller = reset_input_controller; + inputctl->pub.start_input_pass = start_input_pass; + inputctl->pub.finish_input_pass = finish_input_pass; + /* Initialize state: can't use reset_input_controller since we don't + * want to try to reset other modules yet. + */ + inputctl->pub.has_multiple_scans = FALSE; /* "unknown" would be better */ + inputctl->pub.eoi_reached = FALSE; + inputctl->inheaders = TRUE; +} diff --git a/mod/pub.mod/libjpeg.mod/jdmainct.c b/mod/pub.mod/libjpeg.mod/jdmainct.c new file mode 100644 index 0000000..13c956f --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jdmainct.c @@ -0,0 +1,512 @@ +/* + * jdmainct.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains the main buffer controller for decompression. + * The main buffer lies between the JPEG decompressor proper and the + * post-processor; it holds downsampled data in the JPEG colorspace. + * + * Note that this code is bypassed in raw-data mode, since the application + * supplies the equivalent of the main buffer in that case. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* + * In the current system design, the main buffer need never be a full-image + * buffer; any full-height buffers will be found inside the coefficient or + * postprocessing controllers. Nonetheless, the main controller is not + * trivial. Its responsibility is to provide context rows for upsampling/ + * rescaling, and doing this in an efficient fashion is a bit tricky. + * + * Postprocessor input data is counted in "row groups". A row group + * is defined to be (v_samp_factor * DCT_scaled_size / min_DCT_scaled_size) + * sample rows of each component. (We require DCT_scaled_size values to be + * chosen such that these numbers are integers. In practice DCT_scaled_size + * values will likely be powers of two, so we actually have the stronger + * condition that DCT_scaled_size / min_DCT_scaled_size is an integer.) + * Upsampling will typically produce max_v_samp_factor pixel rows from each + * row group (times any additional scale factor that the upsampler is + * applying). + * + * The coefficient controller will deliver data to us one iMCU row at a time; + * each iMCU row contains v_samp_factor * DCT_scaled_size sample rows, or + * exactly min_DCT_scaled_size row groups. (This amount of data corresponds + * to one row of MCUs when the image is fully interleaved.) Note that the + * number of sample rows varies across components, but the number of row + * groups does not. Some garbage sample rows may be included in the last iMCU + * row at the bottom of the image. + * + * Depending on the vertical scaling algorithm used, the upsampler may need + * access to the sample row(s) above and below its current input row group. + * The upsampler is required to set need_context_rows TRUE at global selection + * time if so. When need_context_rows is FALSE, this controller can simply + * obtain one iMCU row at a time from the coefficient controller and dole it + * out as row groups to the postprocessor. + * + * When need_context_rows is TRUE, this controller guarantees that the buffer + * passed to postprocessing contains at least one row group's worth of samples + * above and below the row group(s) being processed. Note that the context + * rows "above" the first passed row group appear at negative row offsets in + * the passed buffer. At the top and bottom of the image, the required + * context rows are manufactured by duplicating the first or last real sample + * row; this avoids having special cases in the upsampling inner loops. + * + * The amount of context is fixed at one row group just because that's a + * convenient number for this controller to work with. The existing + * upsamplers really only need one sample row of context. An upsampler + * supporting arbitrary output rescaling might wish for more than one row + * group of context when shrinking the image; tough, we don't handle that. + * (This is justified by the assumption that downsizing will be handled mostly + * by adjusting the DCT_scaled_size values, so that the actual scale factor at + * the upsample step needn't be much less than one.) + * + * To provide the desired context, we have to retain the last two row groups + * of one iMCU row while reading in the next iMCU row. (The last row group + * can't be processed until we have another row group for its below-context, + * and so we have to save the next-to-last group too for its above-context.) + * We could do this most simply by copying data around in our buffer, but + * that'd be very slow. We can avoid copying any data by creating a rather + * strange pointer structure. Here's how it works. We allocate a workspace + * consisting of M+2 row groups (where M = min_DCT_scaled_size is the number + * of row groups per iMCU row). We create two sets of redundant pointers to + * the workspace. Labeling the physical row groups 0 to M+1, the synthesized + * pointer lists look like this: + * M+1 M-1 + * master pointer --> 0 master pointer --> 0 + * 1 1 + * ... ... + * M-3 M-3 + * M-2 M + * M-1 M+1 + * M M-2 + * M+1 M-1 + * 0 0 + * We read alternate iMCU rows using each master pointer; thus the last two + * row groups of the previous iMCU row remain un-overwritten in the workspace. + * The pointer lists are set up so that the required context rows appear to + * be adjacent to the proper places when we pass the pointer lists to the + * upsampler. + * + * The above pictures describe the normal state of the pointer lists. + * At top and bottom of the image, we diddle the pointer lists to duplicate + * the first or last sample row as necessary (this is cheaper than copying + * sample rows around). + * + * This scheme breaks down if M < 2, ie, min_DCT_scaled_size is 1. In that + * situation each iMCU row provides only one row group so the buffering logic + * must be different (eg, we must read two iMCU rows before we can emit the + * first row group). For now, we simply do not support providing context + * rows when min_DCT_scaled_size is 1. That combination seems unlikely to + * be worth providing --- if someone wants a 1/8th-size preview, they probably + * want it quick and dirty, so a context-free upsampler is sufficient. + */ + + +/* Private buffer controller object */ + +typedef struct { + struct jpeg_d_main_controller pub; /* public fields */ + + /* Pointer to allocated workspace (M or M+2 row groups). */ + JSAMPARRAY buffer[MAX_COMPONENTS]; + + boolean buffer_full; /* Have we gotten an iMCU row from decoder? */ + JDIMENSION rowgroup_ctr; /* counts row groups output to postprocessor */ + + /* Remaining fields are only used in the context case. */ + + /* These are the master pointers to the funny-order pointer lists. */ + JSAMPIMAGE xbuffer[2]; /* pointers to weird pointer lists */ + + int whichptr; /* indicates which pointer set is now in use */ + int context_state; /* process_data state machine status */ + JDIMENSION rowgroups_avail; /* row groups available to postprocessor */ + JDIMENSION iMCU_row_ctr; /* counts iMCU rows to detect image top/bot */ +} my_main_controller; + +typedef my_main_controller * my_main_ptr; + +/* context_state values: */ +#define CTX_PREPARE_FOR_IMCU 0 /* need to prepare for MCU row */ +#define CTX_PROCESS_IMCU 1 /* feeding iMCU to postprocessor */ +#define CTX_POSTPONED_ROW 2 /* feeding postponed row group */ + + +/* Forward declarations */ +METHODDEF(void) process_data_simple_main + JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf, + JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail)); +METHODDEF(void) process_data_context_main + JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf, + JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail)); +#ifdef QUANT_2PASS_SUPPORTED +METHODDEF(void) process_data_crank_post + JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf, + JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail)); +#endif + + +LOCAL(void) +alloc_funny_pointers (j_decompress_ptr cinfo) +/* Allocate space for the funny pointer lists. + * This is done only once, not once per pass. + */ +{ + my_main_ptr main = (my_main_ptr) cinfo->main; + int ci, rgroup; + int M = cinfo->min_DCT_scaled_size; + jpeg_component_info *compptr; + JSAMPARRAY xbuf; + + /* Get top-level space for component array pointers. + * We alloc both arrays with one call to save a few cycles. + */ + main->xbuffer[0] = (JSAMPIMAGE) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + cinfo->num_components * 2 * SIZEOF(JSAMPARRAY)); + main->xbuffer[1] = main->xbuffer[0] + cinfo->num_components; + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) / + cinfo->min_DCT_scaled_size; /* height of a row group of component */ + /* Get space for pointer lists --- M+4 row groups in each list. + * We alloc both pointer lists with one call to save a few cycles. + */ + xbuf = (JSAMPARRAY) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + 2 * (rgroup * (M + 4)) * SIZEOF(JSAMPROW)); + xbuf += rgroup; /* want one row group at negative offsets */ + main->xbuffer[0][ci] = xbuf; + xbuf += rgroup * (M + 4); + main->xbuffer[1][ci] = xbuf; + } +} + + +LOCAL(void) +make_funny_pointers (j_decompress_ptr cinfo) +/* Create the funny pointer lists discussed in the comments above. + * The actual workspace is already allocated (in main->buffer), + * and the space for the pointer lists is allocated too. + * This routine just fills in the curiously ordered lists. + * This will be repeated at the beginning of each pass. + */ +{ + my_main_ptr main = (my_main_ptr) cinfo->main; + int ci, i, rgroup; + int M = cinfo->min_DCT_scaled_size; + jpeg_component_info *compptr; + JSAMPARRAY buf, xbuf0, xbuf1; + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) / + cinfo->min_DCT_scaled_size; /* height of a row group of component */ + xbuf0 = main->xbuffer[0][ci]; + xbuf1 = main->xbuffer[1][ci]; + /* First copy the workspace pointers as-is */ + buf = main->buffer[ci]; + for (i = 0; i < rgroup * (M + 2); i++) { + xbuf0[i] = xbuf1[i] = buf[i]; + } + /* In the second list, put the last four row groups in swapped order */ + for (i = 0; i < rgroup * 2; i++) { + xbuf1[rgroup*(M-2) + i] = buf[rgroup*M + i]; + xbuf1[rgroup*M + i] = buf[rgroup*(M-2) + i]; + } + /* The wraparound pointers at top and bottom will be filled later + * (see set_wraparound_pointers, below). Initially we want the "above" + * pointers to duplicate the first actual data line. This only needs + * to happen in xbuffer[0]. + */ + for (i = 0; i < rgroup; i++) { + xbuf0[i - rgroup] = xbuf0[0]; + } + } +} + + +LOCAL(void) +set_wraparound_pointers (j_decompress_ptr cinfo) +/* Set up the "wraparound" pointers at top and bottom of the pointer lists. + * This changes the pointer list state from top-of-image to the normal state. + */ +{ + my_main_ptr main = (my_main_ptr) cinfo->main; + int ci, i, rgroup; + int M = cinfo->min_DCT_scaled_size; + jpeg_component_info *compptr; + JSAMPARRAY xbuf0, xbuf1; + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) / + cinfo->min_DCT_scaled_size; /* height of a row group of component */ + xbuf0 = main->xbuffer[0][ci]; + xbuf1 = main->xbuffer[1][ci]; + for (i = 0; i < rgroup; i++) { + xbuf0[i - rgroup] = xbuf0[rgroup*(M+1) + i]; + xbuf1[i - rgroup] = xbuf1[rgroup*(M+1) + i]; + xbuf0[rgroup*(M+2) + i] = xbuf0[i]; + xbuf1[rgroup*(M+2) + i] = xbuf1[i]; + } + } +} + + +LOCAL(void) +set_bottom_pointers (j_decompress_ptr cinfo) +/* Change the pointer lists to duplicate the last sample row at the bottom + * of the image. whichptr indicates which xbuffer holds the final iMCU row. + * Also sets rowgroups_avail to indicate number of nondummy row groups in row. + */ +{ + my_main_ptr main = (my_main_ptr) cinfo->main; + int ci, i, rgroup, iMCUheight, rows_left; + jpeg_component_info *compptr; + JSAMPARRAY xbuf; + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + /* Count sample rows in one iMCU row and in one row group */ + iMCUheight = compptr->v_samp_factor * compptr->DCT_scaled_size; + rgroup = iMCUheight / cinfo->min_DCT_scaled_size; + /* Count nondummy sample rows remaining for this component */ + rows_left = (int) (compptr->downsampled_height % (JDIMENSION) iMCUheight); + if (rows_left == 0) rows_left = iMCUheight; + /* Count nondummy row groups. Should get same answer for each component, + * so we need only do it once. + */ + if (ci == 0) { + main->rowgroups_avail = (JDIMENSION) ((rows_left-1) / rgroup + 1); + } + /* Duplicate the last real sample row rgroup*2 times; this pads out the + * last partial rowgroup and ensures at least one full rowgroup of context. + */ + xbuf = main->xbuffer[main->whichptr][ci]; + for (i = 0; i < rgroup * 2; i++) { + xbuf[rows_left + i] = xbuf[rows_left-1]; + } + } +} + + +/* + * Initialize for a processing pass. + */ + +METHODDEF(void) +start_pass_main (j_decompress_ptr cinfo, J_BUF_MODE pass_mode) +{ + my_main_ptr main = (my_main_ptr) cinfo->main; + + switch (pass_mode) { + case JBUF_PASS_THRU: + if (cinfo->upsample->need_context_rows) { + main->pub.process_data = process_data_context_main; + make_funny_pointers(cinfo); /* Create the xbuffer[] lists */ + main->whichptr = 0; /* Read first iMCU row into xbuffer[0] */ + main->context_state = CTX_PREPARE_FOR_IMCU; + main->iMCU_row_ctr = 0; + } else { + /* Simple case with no context needed */ + main->pub.process_data = process_data_simple_main; + } + main->buffer_full = FALSE; /* Mark buffer empty */ + main->rowgroup_ctr = 0; + break; +#ifdef QUANT_2PASS_SUPPORTED + case JBUF_CRANK_DEST: + /* For last pass of 2-pass quantization, just crank the postprocessor */ + main->pub.process_data = process_data_crank_post; + break; +#endif + default: + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + break; + } +} + + +/* + * Process some data. + * This handles the simple case where no context is required. + */ + +METHODDEF(void) +process_data_simple_main (j_decompress_ptr cinfo, + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail) +{ + my_main_ptr main = (my_main_ptr) cinfo->main; + JDIMENSION rowgroups_avail; + + /* Read input data if we haven't filled the main buffer yet */ + if (! main->buffer_full) { + if (! (*cinfo->coef->decompress_data) (cinfo, main->buffer)) + return; /* suspension forced, can do nothing more */ + main->buffer_full = TRUE; /* OK, we have an iMCU row to work with */ + } + + /* There are always min_DCT_scaled_size row groups in an iMCU row. */ + rowgroups_avail = (JDIMENSION) cinfo->min_DCT_scaled_size; + /* Note: at the bottom of the image, we may pass extra garbage row groups + * to the postprocessor. The postprocessor has to check for bottom + * of image anyway (at row resolution), so no point in us doing it too. + */ + + /* Feed the postprocessor */ + (*cinfo->post->post_process_data) (cinfo, main->buffer, + &main->rowgroup_ctr, rowgroups_avail, + output_buf, out_row_ctr, out_rows_avail); + + /* Has postprocessor consumed all the data yet? If so, mark buffer empty */ + if (main->rowgroup_ctr >= rowgroups_avail) { + main->buffer_full = FALSE; + main->rowgroup_ctr = 0; + } +} + + +/* + * Process some data. + * This handles the case where context rows must be provided. + */ + +METHODDEF(void) +process_data_context_main (j_decompress_ptr cinfo, + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail) +{ + my_main_ptr main = (my_main_ptr) cinfo->main; + + /* Read input data if we haven't filled the main buffer yet */ + if (! main->buffer_full) { + if (! (*cinfo->coef->decompress_data) (cinfo, + main->xbuffer[main->whichptr])) + return; /* suspension forced, can do nothing more */ + main->buffer_full = TRUE; /* OK, we have an iMCU row to work with */ + main->iMCU_row_ctr++; /* count rows received */ + } + + /* Postprocessor typically will not swallow all the input data it is handed + * in one call (due to filling the output buffer first). Must be prepared + * to exit and restart. This switch lets us keep track of how far we got. + * Note that each case falls through to the next on successful completion. + */ + switch (main->context_state) { + case CTX_POSTPONED_ROW: + /* Call postprocessor using previously set pointers for postponed row */ + (*cinfo->post->post_process_data) (cinfo, main->xbuffer[main->whichptr], + &main->rowgroup_ctr, main->rowgroups_avail, + output_buf, out_row_ctr, out_rows_avail); + if (main->rowgroup_ctr < main->rowgroups_avail) + return; /* Need to suspend */ + main->context_state = CTX_PREPARE_FOR_IMCU; + if (*out_row_ctr >= out_rows_avail) + return; /* Postprocessor exactly filled output buf */ + /*FALLTHROUGH*/ + case CTX_PREPARE_FOR_IMCU: + /* Prepare to process first M-1 row groups of this iMCU row */ + main->rowgroup_ctr = 0; + main->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_scaled_size - 1); + /* Check for bottom of image: if so, tweak pointers to "duplicate" + * the last sample row, and adjust rowgroups_avail to ignore padding rows. + */ + if (main->iMCU_row_ctr == cinfo->total_iMCU_rows) + set_bottom_pointers(cinfo); + main->context_state = CTX_PROCESS_IMCU; + /*FALLTHROUGH*/ + case CTX_PROCESS_IMCU: + /* Call postprocessor using previously set pointers */ + (*cinfo->post->post_process_data) (cinfo, main->xbuffer[main->whichptr], + &main->rowgroup_ctr, main->rowgroups_avail, + output_buf, out_row_ctr, out_rows_avail); + if (main->rowgroup_ctr < main->rowgroups_avail) + return; /* Need to suspend */ + /* After the first iMCU, change wraparound pointers to normal state */ + if (main->iMCU_row_ctr == 1) + set_wraparound_pointers(cinfo); + /* Prepare to load new iMCU row using other xbuffer list */ + main->whichptr ^= 1; /* 0=>1 or 1=>0 */ + main->buffer_full = FALSE; + /* Still need to process last row group of this iMCU row, */ + /* which is saved at index M+1 of the other xbuffer */ + main->rowgroup_ctr = (JDIMENSION) (cinfo->min_DCT_scaled_size + 1); + main->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_scaled_size + 2); + main->context_state = CTX_POSTPONED_ROW; + } +} + + +/* + * Process some data. + * Final pass of two-pass quantization: just call the postprocessor. + * Source data will be the postprocessor controller's internal buffer. + */ + +#ifdef QUANT_2PASS_SUPPORTED + +METHODDEF(void) +process_data_crank_post (j_decompress_ptr cinfo, + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail) +{ + (*cinfo->post->post_process_data) (cinfo, (JSAMPIMAGE) NULL, + (JDIMENSION *) NULL, (JDIMENSION) 0, + output_buf, out_row_ctr, out_rows_avail); +} + +#endif /* QUANT_2PASS_SUPPORTED */ + + +/* + * Initialize main buffer controller. + */ + +GLOBAL(void) +jinit_d_main_controller (j_decompress_ptr cinfo, boolean need_full_buffer) +{ + my_main_ptr main; + int ci, rgroup, ngroups; + jpeg_component_info *compptr; + + main = (my_main_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_main_controller)); + cinfo->main = (struct jpeg_d_main_controller *) main; + main->pub.start_pass = start_pass_main; + + if (need_full_buffer) /* shouldn't happen */ + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + + /* Allocate the workspace. + * ngroups is the number of row groups we need. + */ + if (cinfo->upsample->need_context_rows) { + if (cinfo->min_DCT_scaled_size < 2) /* unsupported, see comments above */ + ERREXIT(cinfo, JERR_NOTIMPL); + alloc_funny_pointers(cinfo); /* Alloc space for xbuffer[] lists */ + ngroups = cinfo->min_DCT_scaled_size + 2; + } else { + ngroups = cinfo->min_DCT_scaled_size; + } + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) / + cinfo->min_DCT_scaled_size; /* height of a row group of component */ + main->buffer[ci] = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + compptr->width_in_blocks * compptr->DCT_scaled_size, + (JDIMENSION) (rgroup * ngroups)); + } +} diff --git a/mod/pub.mod/libjpeg.mod/jdmarker.c b/mod/pub.mod/libjpeg.mod/jdmarker.c new file mode 100644 index 0000000..f4cca8c --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jdmarker.c @@ -0,0 +1,1360 @@ +/* + * jdmarker.c + * + * Copyright (C) 1991-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains routines to decode JPEG datastream markers. + * Most of the complexity arises from our desire to support input + * suspension: if not all of the data for a marker is available, + * we must exit back to the application. On resumption, we reprocess + * the marker. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +typedef enum { /* JPEG marker codes */ + M_SOF0 = 0xc0, + M_SOF1 = 0xc1, + M_SOF2 = 0xc2, + M_SOF3 = 0xc3, + + M_SOF5 = 0xc5, + M_SOF6 = 0xc6, + M_SOF7 = 0xc7, + + M_JPG = 0xc8, + M_SOF9 = 0xc9, + M_SOF10 = 0xca, + M_SOF11 = 0xcb, + + M_SOF13 = 0xcd, + M_SOF14 = 0xce, + M_SOF15 = 0xcf, + + M_DHT = 0xc4, + + M_DAC = 0xcc, + + M_RST0 = 0xd0, + M_RST1 = 0xd1, + M_RST2 = 0xd2, + M_RST3 = 0xd3, + M_RST4 = 0xd4, + M_RST5 = 0xd5, + M_RST6 = 0xd6, + M_RST7 = 0xd7, + + M_SOI = 0xd8, + M_EOI = 0xd9, + M_SOS = 0xda, + M_DQT = 0xdb, + M_DNL = 0xdc, + M_DRI = 0xdd, + M_DHP = 0xde, + M_EXP = 0xdf, + + M_APP0 = 0xe0, + M_APP1 = 0xe1, + M_APP2 = 0xe2, + M_APP3 = 0xe3, + M_APP4 = 0xe4, + M_APP5 = 0xe5, + M_APP6 = 0xe6, + M_APP7 = 0xe7, + M_APP8 = 0xe8, + M_APP9 = 0xe9, + M_APP10 = 0xea, + M_APP11 = 0xeb, + M_APP12 = 0xec, + M_APP13 = 0xed, + M_APP14 = 0xee, + M_APP15 = 0xef, + + M_JPG0 = 0xf0, + M_JPG13 = 0xfd, + M_COM = 0xfe, + + M_TEM = 0x01, + + M_ERROR = 0x100 +} JPEG_MARKER; + + +/* Private state */ + +typedef struct { + struct jpeg_marker_reader pub; /* public fields */ + + /* Application-overridable marker processing methods */ + jpeg_marker_parser_method process_COM; + jpeg_marker_parser_method process_APPn[16]; + + /* Limit on marker data length to save for each marker type */ + unsigned int length_limit_COM; + unsigned int length_limit_APPn[16]; + + /* Status of COM/APPn marker saving */ + jpeg_saved_marker_ptr cur_marker; /* NULL if not processing a marker */ + unsigned int bytes_read; /* data bytes read so far in marker */ + /* Note: cur_marker is not linked into marker_list until it's all read. */ +} my_marker_reader; + +typedef my_marker_reader * my_marker_ptr; + + +/* + * Macros for fetching data from the data source module. + * + * At all times, cinfo->src->next_input_byte and ->bytes_in_buffer reflect + * the current restart point; we update them only when we have reached a + * suitable place to restart if a suspension occurs. + */ + +/* Declare and initialize local copies of input pointer/count */ +#define INPUT_VARS(cinfo) \ + struct jpeg_source_mgr * datasrc = (cinfo)->src; \ + const JOCTET * next_input_byte = datasrc->next_input_byte; \ + size_t bytes_in_buffer = datasrc->bytes_in_buffer + +/* Unload the local copies --- do this only at a restart boundary */ +#define INPUT_SYNC(cinfo) \ + ( datasrc->next_input_byte = next_input_byte, \ + datasrc->bytes_in_buffer = bytes_in_buffer ) + +/* Reload the local copies --- used only in MAKE_BYTE_AVAIL */ +#define INPUT_RELOAD(cinfo) \ + ( next_input_byte = datasrc->next_input_byte, \ + bytes_in_buffer = datasrc->bytes_in_buffer ) + +/* Internal macro for INPUT_BYTE and INPUT_2BYTES: make a byte available. + * Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + * but we must reload the local copies after a successful fill. + */ +#define MAKE_BYTE_AVAIL(cinfo,action) \ + if (bytes_in_buffer == 0) { \ + if (! (*datasrc->fill_input_buffer) (cinfo)) \ + { action; } \ + INPUT_RELOAD(cinfo); \ + } + +/* Read a byte into variable V. + * If must suspend, take the specified action (typically "return FALSE"). + */ +#define INPUT_BYTE(cinfo,V,action) \ + MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \ + bytes_in_buffer--; \ + V = GETJOCTET(*next_input_byte++); ) + +/* As above, but read two bytes interpreted as an unsigned 16-bit integer. + * V should be declared unsigned int or perhaps INT32. + */ +#define INPUT_2BYTES(cinfo,V,action) \ + MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \ + bytes_in_buffer--; \ + V = ((unsigned int) GETJOCTET(*next_input_byte++)) << 8; \ + MAKE_BYTE_AVAIL(cinfo,action); \ + bytes_in_buffer--; \ + V += GETJOCTET(*next_input_byte++); ) + + +/* + * Routines to process JPEG markers. + * + * Entry condition: JPEG marker itself has been read and its code saved + * in cinfo->unread_marker; input restart point is just after the marker. + * + * Exit: if return TRUE, have read and processed any parameters, and have + * updated the restart point to point after the parameters. + * If return FALSE, was forced to suspend before reaching end of + * marker parameters; restart point has not been moved. Same routine + * will be called again after application supplies more input data. + * + * This approach to suspension assumes that all of a marker's parameters + * can fit into a single input bufferload. This should hold for "normal" + * markers. Some COM/APPn markers might have large parameter segments + * that might not fit. If we are simply dropping such a marker, we use + * skip_input_data to get past it, and thereby put the problem on the + * source manager's shoulders. If we are saving the marker's contents + * into memory, we use a slightly different convention: when forced to + * suspend, the marker processor updates the restart point to the end of + * what it's consumed (ie, the end of the buffer) before returning FALSE. + * On resumption, cinfo->unread_marker still contains the marker code, + * but the data source will point to the next chunk of marker data. + * The marker processor must retain internal state to deal with this. + * + * Note that we don't bother to avoid duplicate trace messages if a + * suspension occurs within marker parameters. Other side effects + * require more care. + */ + + +LOCAL(boolean) +get_soi (j_decompress_ptr cinfo) +/* Process an SOI marker */ +{ + int i; + + TRACEMS(cinfo, 1, JTRC_SOI); + + if (cinfo->marker->saw_SOI) + ERREXIT(cinfo, JERR_SOI_DUPLICATE); + + /* Reset all parameters that are defined to be reset by SOI */ + + for (i = 0; i < NUM_ARITH_TBLS; i++) { + cinfo->arith_dc_L[i] = 0; + cinfo->arith_dc_U[i] = 1; + cinfo->arith_ac_K[i] = 5; + } + cinfo->restart_interval = 0; + + /* Set initial assumptions for colorspace etc */ + + cinfo->jpeg_color_space = JCS_UNKNOWN; + cinfo->CCIR601_sampling = FALSE; /* Assume non-CCIR sampling??? */ + + cinfo->saw_JFIF_marker = FALSE; + cinfo->JFIF_major_version = 1; /* set default JFIF APP0 values */ + cinfo->JFIF_minor_version = 1; + cinfo->density_unit = 0; + cinfo->X_density = 1; + cinfo->Y_density = 1; + cinfo->saw_Adobe_marker = FALSE; + cinfo->Adobe_transform = 0; + + cinfo->marker->saw_SOI = TRUE; + + return TRUE; +} + + +LOCAL(boolean) +get_sof (j_decompress_ptr cinfo, boolean is_prog, boolean is_arith) +/* Process a SOFn marker */ +{ + INT32 length; + int c, ci; + jpeg_component_info * compptr; + INPUT_VARS(cinfo); + + cinfo->progressive_mode = is_prog; + cinfo->arith_code = is_arith; + + INPUT_2BYTES(cinfo, length, return FALSE); + + INPUT_BYTE(cinfo, cinfo->data_precision, return FALSE); + INPUT_2BYTES(cinfo, cinfo->image_height, return FALSE); + INPUT_2BYTES(cinfo, cinfo->image_width, return FALSE); + INPUT_BYTE(cinfo, cinfo->num_components, return FALSE); + + length -= 8; + + TRACEMS4(cinfo, 1, JTRC_SOF, cinfo->unread_marker, + (int) cinfo->image_width, (int) cinfo->image_height, + cinfo->num_components); + + if (cinfo->marker->saw_SOF) + ERREXIT(cinfo, JERR_SOF_DUPLICATE); + + /* We don't support files in which the image height is initially specified */ + /* as 0 and is later redefined by DNL. As long as we have to check that, */ + /* might as well have a general sanity check. */ + if (cinfo->image_height <= 0 || cinfo->image_width <= 0 + || cinfo->num_components <= 0) + ERREXIT(cinfo, JERR_EMPTY_IMAGE); + + if (length != (cinfo->num_components * 3)) + ERREXIT(cinfo, JERR_BAD_LENGTH); + + if (cinfo->comp_info == NULL) /* do only once, even if suspend */ + cinfo->comp_info = (jpeg_component_info *) (*cinfo->mem->alloc_small) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + cinfo->num_components * SIZEOF(jpeg_component_info)); + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + compptr->component_index = ci; + INPUT_BYTE(cinfo, compptr->component_id, return FALSE); + INPUT_BYTE(cinfo, c, return FALSE); + compptr->h_samp_factor = (c >> 4) & 15; + compptr->v_samp_factor = (c ) & 15; + INPUT_BYTE(cinfo, compptr->quant_tbl_no, return FALSE); + + TRACEMS4(cinfo, 1, JTRC_SOF_COMPONENT, + compptr->component_id, compptr->h_samp_factor, + compptr->v_samp_factor, compptr->quant_tbl_no); + } + + cinfo->marker->saw_SOF = TRUE; + + INPUT_SYNC(cinfo); + return TRUE; +} + + +LOCAL(boolean) +get_sos (j_decompress_ptr cinfo) +/* Process a SOS marker */ +{ + INT32 length; + int i, ci, n, c, cc; + jpeg_component_info * compptr; + INPUT_VARS(cinfo); + + if (! cinfo->marker->saw_SOF) + ERREXIT(cinfo, JERR_SOS_NO_SOF); + + INPUT_2BYTES(cinfo, length, return FALSE); + + INPUT_BYTE(cinfo, n, return FALSE); /* Number of components */ + + TRACEMS1(cinfo, 1, JTRC_SOS, n); + + if (length != (n * 2 + 6) || n < 1 || n > MAX_COMPS_IN_SCAN) + ERREXIT(cinfo, JERR_BAD_LENGTH); + + cinfo->comps_in_scan = n; + + /* Collect the component-spec parameters */ + + for (i = 0; i < n; i++) { + INPUT_BYTE(cinfo, cc, return FALSE); + INPUT_BYTE(cinfo, c, return FALSE); + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + if (cc == compptr->component_id) + goto id_found; + } + + ERREXIT1(cinfo, JERR_BAD_COMPONENT_ID, cc); + + id_found: + + cinfo->cur_comp_info[i] = compptr; + compptr->dc_tbl_no = (c >> 4) & 15; + compptr->ac_tbl_no = (c ) & 15; + + TRACEMS3(cinfo, 1, JTRC_SOS_COMPONENT, cc, + compptr->dc_tbl_no, compptr->ac_tbl_no); + } + + /* Collect the additional scan parameters Ss, Se, Ah/Al. */ + INPUT_BYTE(cinfo, c, return FALSE); + cinfo->Ss = c; + INPUT_BYTE(cinfo, c, return FALSE); + cinfo->Se = c; + INPUT_BYTE(cinfo, c, return FALSE); + cinfo->Ah = (c >> 4) & 15; + cinfo->Al = (c ) & 15; + + TRACEMS4(cinfo, 1, JTRC_SOS_PARAMS, cinfo->Ss, cinfo->Se, + cinfo->Ah, cinfo->Al); + + /* Prepare to scan data & restart markers */ + cinfo->marker->next_restart_num = 0; + + /* Count another SOS marker */ + cinfo->input_scan_number++; + + INPUT_SYNC(cinfo); + return TRUE; +} + + +#ifdef D_ARITH_CODING_SUPPORTED + +LOCAL(boolean) +get_dac (j_decompress_ptr cinfo) +/* Process a DAC marker */ +{ + INT32 length; + int index, val; + INPUT_VARS(cinfo); + + INPUT_2BYTES(cinfo, length, return FALSE); + length -= 2; + + while (length > 0) { + INPUT_BYTE(cinfo, index, return FALSE); + INPUT_BYTE(cinfo, val, return FALSE); + + length -= 2; + + TRACEMS2(cinfo, 1, JTRC_DAC, index, val); + + if (index < 0 || index >= (2*NUM_ARITH_TBLS)) + ERREXIT1(cinfo, JERR_DAC_INDEX, index); + + if (index >= NUM_ARITH_TBLS) { /* define AC table */ + cinfo->arith_ac_K[index-NUM_ARITH_TBLS] = (UINT8) val; + } else { /* define DC table */ + cinfo->arith_dc_L[index] = (UINT8) (val & 0x0F); + cinfo->arith_dc_U[index] = (UINT8) (val >> 4); + if (cinfo->arith_dc_L[index] > cinfo->arith_dc_U[index]) + ERREXIT1(cinfo, JERR_DAC_VALUE, val); + } + } + + if (length != 0) + ERREXIT(cinfo, JERR_BAD_LENGTH); + + INPUT_SYNC(cinfo); + return TRUE; +} + +#else /* ! D_ARITH_CODING_SUPPORTED */ + +#define get_dac(cinfo) skip_variable(cinfo) + +#endif /* D_ARITH_CODING_SUPPORTED */ + + +LOCAL(boolean) +get_dht (j_decompress_ptr cinfo) +/* Process a DHT marker */ +{ + INT32 length; + UINT8 bits[17]; + UINT8 huffval[256]; + int i, index, count; + JHUFF_TBL **htblptr; + INPUT_VARS(cinfo); + + INPUT_2BYTES(cinfo, length, return FALSE); + length -= 2; + + while (length > 16) { + INPUT_BYTE(cinfo, index, return FALSE); + + TRACEMS1(cinfo, 1, JTRC_DHT, index); + + bits[0] = 0; + count = 0; + for (i = 1; i <= 16; i++) { + INPUT_BYTE(cinfo, bits[i], return FALSE); + count += bits[i]; + } + + length -= 1 + 16; + + TRACEMS8(cinfo, 2, JTRC_HUFFBITS, + bits[1], bits[2], bits[3], bits[4], + bits[5], bits[6], bits[7], bits[8]); + TRACEMS8(cinfo, 2, JTRC_HUFFBITS, + bits[9], bits[10], bits[11], bits[12], + bits[13], bits[14], bits[15], bits[16]); + + /* Here we just do minimal validation of the counts to avoid walking + * off the end of our table space. jdhuff.c will check more carefully. + */ + if (count > 256 || ((INT32) count) > length) + ERREXIT(cinfo, JERR_BAD_HUFF_TABLE); + + for (i = 0; i < count; i++) + INPUT_BYTE(cinfo, huffval[i], return FALSE); + + length -= count; + + if (index & 0x10) { /* AC table definition */ + index -= 0x10; + htblptr = &cinfo->ac_huff_tbl_ptrs[index]; + } else { /* DC table definition */ + htblptr = &cinfo->dc_huff_tbl_ptrs[index]; + } + + if (index < 0 || index >= NUM_HUFF_TBLS) + ERREXIT1(cinfo, JERR_DHT_INDEX, index); + + if (*htblptr == NULL) + *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo); + + MEMCOPY((*htblptr)->bits, bits, SIZEOF((*htblptr)->bits)); + MEMCOPY((*htblptr)->huffval, huffval, SIZEOF((*htblptr)->huffval)); + } + + if (length != 0) + ERREXIT(cinfo, JERR_BAD_LENGTH); + + INPUT_SYNC(cinfo); + return TRUE; +} + + +LOCAL(boolean) +get_dqt (j_decompress_ptr cinfo) +/* Process a DQT marker */ +{ + INT32 length; + int n, i, prec; + unsigned int tmp; + JQUANT_TBL *quant_ptr; + INPUT_VARS(cinfo); + + INPUT_2BYTES(cinfo, length, return FALSE); + length -= 2; + + while (length > 0) { + INPUT_BYTE(cinfo, n, return FALSE); + prec = n >> 4; + n &= 0x0F; + + TRACEMS2(cinfo, 1, JTRC_DQT, n, prec); + + if (n >= NUM_QUANT_TBLS) + ERREXIT1(cinfo, JERR_DQT_INDEX, n); + + if (cinfo->quant_tbl_ptrs[n] == NULL) + cinfo->quant_tbl_ptrs[n] = jpeg_alloc_quant_table((j_common_ptr) cinfo); + quant_ptr = cinfo->quant_tbl_ptrs[n]; + + for (i = 0; i < DCTSIZE2; i++) { + if (prec) + INPUT_2BYTES(cinfo, tmp, return FALSE); + else + INPUT_BYTE(cinfo, tmp, return FALSE); + /* We convert the zigzag-order table to natural array order. */ + quant_ptr->quantval[jpeg_natural_order[i]] = (UINT16) tmp; + } + + if (cinfo->err->trace_level >= 2) { + for (i = 0; i < DCTSIZE2; i += 8) { + TRACEMS8(cinfo, 2, JTRC_QUANTVALS, + quant_ptr->quantval[i], quant_ptr->quantval[i+1], + quant_ptr->quantval[i+2], quant_ptr->quantval[i+3], + quant_ptr->quantval[i+4], quant_ptr->quantval[i+5], + quant_ptr->quantval[i+6], quant_ptr->quantval[i+7]); + } + } + + length -= DCTSIZE2+1; + if (prec) length -= DCTSIZE2; + } + + if (length != 0) + ERREXIT(cinfo, JERR_BAD_LENGTH); + + INPUT_SYNC(cinfo); + return TRUE; +} + + +LOCAL(boolean) +get_dri (j_decompress_ptr cinfo) +/* Process a DRI marker */ +{ + INT32 length; + unsigned int tmp; + INPUT_VARS(cinfo); + + INPUT_2BYTES(cinfo, length, return FALSE); + + if (length != 4) + ERREXIT(cinfo, JERR_BAD_LENGTH); + + INPUT_2BYTES(cinfo, tmp, return FALSE); + + TRACEMS1(cinfo, 1, JTRC_DRI, tmp); + + cinfo->restart_interval = tmp; + + INPUT_SYNC(cinfo); + return TRUE; +} + + +/* + * Routines for processing APPn and COM markers. + * These are either saved in memory or discarded, per application request. + * APP0 and APP14 are specially checked to see if they are + * JFIF and Adobe markers, respectively. + */ + +#define APP0_DATA_LEN 14 /* Length of interesting data in APP0 */ +#define APP14_DATA_LEN 12 /* Length of interesting data in APP14 */ +#define APPN_DATA_LEN 14 /* Must be the largest of the above!! */ + + +LOCAL(void) +examine_app0 (j_decompress_ptr cinfo, JOCTET FAR * data, + unsigned int datalen, INT32 remaining) +/* Examine first few bytes from an APP0. + * Take appropriate action if it is a JFIF marker. + * datalen is # of bytes at data[], remaining is length of rest of marker data. + */ +{ + INT32 totallen = (INT32) datalen + remaining; + + if (datalen >= APP0_DATA_LEN && + GETJOCTET(data[0]) == 0x4A && + GETJOCTET(data[1]) == 0x46 && + GETJOCTET(data[2]) == 0x49 && + GETJOCTET(data[3]) == 0x46 && + GETJOCTET(data[4]) == 0) { + /* Found JFIF APP0 marker: save info */ + cinfo->saw_JFIF_marker = TRUE; + cinfo->JFIF_major_version = GETJOCTET(data[5]); + cinfo->JFIF_minor_version = GETJOCTET(data[6]); + cinfo->density_unit = GETJOCTET(data[7]); + cinfo->X_density = (GETJOCTET(data[8]) << 8) + GETJOCTET(data[9]); + cinfo->Y_density = (GETJOCTET(data[10]) << 8) + GETJOCTET(data[11]); + /* Check version. + * Major version must be 1, anything else signals an incompatible change. + * (We used to treat this as an error, but now it's a nonfatal warning, + * because some bozo at Hijaak couldn't read the spec.) + * Minor version should be 0..2, but process anyway if newer. + */ + if (cinfo->JFIF_major_version != 1) + WARNMS2(cinfo, JWRN_JFIF_MAJOR, + cinfo->JFIF_major_version, cinfo->JFIF_minor_version); + /* Generate trace messages */ + TRACEMS5(cinfo, 1, JTRC_JFIF, + cinfo->JFIF_major_version, cinfo->JFIF_minor_version, + cinfo->X_density, cinfo->Y_density, cinfo->density_unit); + /* Validate thumbnail dimensions and issue appropriate messages */ + if (GETJOCTET(data[12]) | GETJOCTET(data[13])) + TRACEMS2(cinfo, 1, JTRC_JFIF_THUMBNAIL, + GETJOCTET(data[12]), GETJOCTET(data[13])); + totallen -= APP0_DATA_LEN; + if (totallen != + ((INT32)GETJOCTET(data[12]) * (INT32)GETJOCTET(data[13]) * (INT32) 3)) + TRACEMS1(cinfo, 1, JTRC_JFIF_BADTHUMBNAILSIZE, (int) totallen); + } else if (datalen >= 6 && + GETJOCTET(data[0]) == 0x4A && + GETJOCTET(data[1]) == 0x46 && + GETJOCTET(data[2]) == 0x58 && + GETJOCTET(data[3]) == 0x58 && + GETJOCTET(data[4]) == 0) { + /* Found JFIF "JFXX" extension APP0 marker */ + /* The library doesn't actually do anything with these, + * but we try to produce a helpful trace message. + */ + switch (GETJOCTET(data[5])) { + case 0x10: + TRACEMS1(cinfo, 1, JTRC_THUMB_JPEG, (int) totallen); + break; + case 0x11: + TRACEMS1(cinfo, 1, JTRC_THUMB_PALETTE, (int) totallen); + break; + case 0x13: + TRACEMS1(cinfo, 1, JTRC_THUMB_RGB, (int) totallen); + break; + default: + TRACEMS2(cinfo, 1, JTRC_JFIF_EXTENSION, + GETJOCTET(data[5]), (int) totallen); + break; + } + } else { + /* Start of APP0 does not match "JFIF" or "JFXX", or too short */ + TRACEMS1(cinfo, 1, JTRC_APP0, (int) totallen); + } +} + + +LOCAL(void) +examine_app14 (j_decompress_ptr cinfo, JOCTET FAR * data, + unsigned int datalen, INT32 remaining) +/* Examine first few bytes from an APP14. + * Take appropriate action if it is an Adobe marker. + * datalen is # of bytes at data[], remaining is length of rest of marker data. + */ +{ + unsigned int version, flags0, flags1, transform; + + if (datalen >= APP14_DATA_LEN && + GETJOCTET(data[0]) == 0x41 && + GETJOCTET(data[1]) == 0x64 && + GETJOCTET(data[2]) == 0x6F && + GETJOCTET(data[3]) == 0x62 && + GETJOCTET(data[4]) == 0x65) { + /* Found Adobe APP14 marker */ + version = (GETJOCTET(data[5]) << 8) + GETJOCTET(data[6]); + flags0 = (GETJOCTET(data[7]) << 8) + GETJOCTET(data[8]); + flags1 = (GETJOCTET(data[9]) << 8) + GETJOCTET(data[10]); + transform = GETJOCTET(data[11]); + TRACEMS4(cinfo, 1, JTRC_ADOBE, version, flags0, flags1, transform); + cinfo->saw_Adobe_marker = TRUE; + cinfo->Adobe_transform = (UINT8) transform; + } else { + /* Start of APP14 does not match "Adobe", or too short */ + TRACEMS1(cinfo, 1, JTRC_APP14, (int) (datalen + remaining)); + } +} + + +METHODDEF(boolean) +get_interesting_appn (j_decompress_ptr cinfo) +/* Process an APP0 or APP14 marker without saving it */ +{ + INT32 length; + JOCTET b[APPN_DATA_LEN]; + unsigned int i, numtoread; + INPUT_VARS(cinfo); + + INPUT_2BYTES(cinfo, length, return FALSE); + length -= 2; + + /* get the interesting part of the marker data */ + if (length >= APPN_DATA_LEN) + numtoread = APPN_DATA_LEN; + else if (length > 0) + numtoread = (unsigned int) length; + else + numtoread = 0; + for (i = 0; i < numtoread; i++) + INPUT_BYTE(cinfo, b[i], return FALSE); + length -= numtoread; + + /* process it */ + switch (cinfo->unread_marker) { + case M_APP0: + examine_app0(cinfo, (JOCTET FAR *) b, numtoread, length); + break; + case M_APP14: + examine_app14(cinfo, (JOCTET FAR *) b, numtoread, length); + break; + default: + /* can't get here unless jpeg_save_markers chooses wrong processor */ + ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, cinfo->unread_marker); + break; + } + + /* skip any remaining data -- could be lots */ + INPUT_SYNC(cinfo); + if (length > 0) + (*cinfo->src->skip_input_data) (cinfo, (long) length); + + return TRUE; +} + + +#ifdef SAVE_MARKERS_SUPPORTED + +METHODDEF(boolean) +save_marker (j_decompress_ptr cinfo) +/* Save an APPn or COM marker into the marker list */ +{ + my_marker_ptr marker = (my_marker_ptr) cinfo->marker; + jpeg_saved_marker_ptr cur_marker = marker->cur_marker; + unsigned int bytes_read, data_length; + JOCTET FAR * data; + INT32 length = 0; + INPUT_VARS(cinfo); + + if (cur_marker == NULL) { + /* begin reading a marker */ + INPUT_2BYTES(cinfo, length, return FALSE); + length -= 2; + if (length >= 0) { /* watch out for bogus length word */ + /* figure out how much we want to save */ + unsigned int limit; + if (cinfo->unread_marker == (int) M_COM) + limit = marker->length_limit_COM; + else + limit = marker->length_limit_APPn[cinfo->unread_marker - (int) M_APP0]; + if ((unsigned int) length < limit) + limit = (unsigned int) length; + /* allocate and initialize the marker item */ + cur_marker = (jpeg_saved_marker_ptr) + (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(struct jpeg_marker_struct) + limit); + cur_marker->next = NULL; + cur_marker->marker = (UINT8) cinfo->unread_marker; + cur_marker->original_length = (unsigned int) length; + cur_marker->data_length = limit; + /* data area is just beyond the jpeg_marker_struct */ + data = cur_marker->data = (JOCTET FAR *) (cur_marker + 1); + marker->cur_marker = cur_marker; + marker->bytes_read = 0; + bytes_read = 0; + data_length = limit; + } else { + /* deal with bogus length word */ + bytes_read = data_length = 0; + data = NULL; + } + } else { + /* resume reading a marker */ + bytes_read = marker->bytes_read; + data_length = cur_marker->data_length; + data = cur_marker->data + bytes_read; + } + + while (bytes_read < data_length) { + INPUT_SYNC(cinfo); /* move the restart point to here */ + marker->bytes_read = bytes_read; + /* If there's not at least one byte in buffer, suspend */ + MAKE_BYTE_AVAIL(cinfo, return FALSE); + /* Copy bytes with reasonable rapidity */ + while (bytes_read < data_length && bytes_in_buffer > 0) { + *data++ = *next_input_byte++; + bytes_in_buffer--; + bytes_read++; + } + } + + /* Done reading what we want to read */ + if (cur_marker != NULL) { /* will be NULL if bogus length word */ + /* Add new marker to end of list */ + if (cinfo->marker_list == NULL) { + cinfo->marker_list = cur_marker; + } else { + jpeg_saved_marker_ptr prev = cinfo->marker_list; + while (prev->next != NULL) + prev = prev->next; + prev->next = cur_marker; + } + /* Reset pointer & calc remaining data length */ + data = cur_marker->data; + length = cur_marker->original_length - data_length; + } + /* Reset to initial state for next marker */ + marker->cur_marker = NULL; + + /* Process the marker if interesting; else just make a generic trace msg */ + switch (cinfo->unread_marker) { + case M_APP0: + examine_app0(cinfo, data, data_length, length); + break; + case M_APP14: + examine_app14(cinfo, data, data_length, length); + break; + default: + TRACEMS2(cinfo, 1, JTRC_MISC_MARKER, cinfo->unread_marker, + (int) (data_length + length)); + break; + } + + /* skip any remaining data -- could be lots */ + INPUT_SYNC(cinfo); /* do before skip_input_data */ + if (length > 0) + (*cinfo->src->skip_input_data) (cinfo, (long) length); + + return TRUE; +} + +#endif /* SAVE_MARKERS_SUPPORTED */ + + +METHODDEF(boolean) +skip_variable (j_decompress_ptr cinfo) +/* Skip over an unknown or uninteresting variable-length marker */ +{ + INT32 length; + INPUT_VARS(cinfo); + + INPUT_2BYTES(cinfo, length, return FALSE); + length -= 2; + + TRACEMS2(cinfo, 1, JTRC_MISC_MARKER, cinfo->unread_marker, (int) length); + + INPUT_SYNC(cinfo); /* do before skip_input_data */ + if (length > 0) + (*cinfo->src->skip_input_data) (cinfo, (long) length); + + return TRUE; +} + + +/* + * Find the next JPEG marker, save it in cinfo->unread_marker. + * Returns FALSE if had to suspend before reaching a marker; + * in that case cinfo->unread_marker is unchanged. + * + * Note that the result might not be a valid marker code, + * but it will never be 0 or FF. + */ + +LOCAL(boolean) +next_marker (j_decompress_ptr cinfo) +{ + int c; + INPUT_VARS(cinfo); + + for (;;) { + INPUT_BYTE(cinfo, c, return FALSE); + /* Skip any non-FF bytes. + * This may look a bit inefficient, but it will not occur in a valid file. + * We sync after each discarded byte so that a suspending data source + * can discard the byte from its buffer. + */ + while (c != 0xFF) { + cinfo->marker->discarded_bytes++; + INPUT_SYNC(cinfo); + INPUT_BYTE(cinfo, c, return FALSE); + } + /* This loop swallows any duplicate FF bytes. Extra FFs are legal as + * pad bytes, so don't count them in discarded_bytes. We assume there + * will not be so many consecutive FF bytes as to overflow a suspending + * data source's input buffer. + */ + do { + INPUT_BYTE(cinfo, c, return FALSE); + } while (c == 0xFF); + if (c != 0) + break; /* found a valid marker, exit loop */ + /* Reach here if we found a stuffed-zero data sequence (FF/00). + * Discard it and loop back to try again. + */ + cinfo->marker->discarded_bytes += 2; + INPUT_SYNC(cinfo); + } + + if (cinfo->marker->discarded_bytes != 0) { + WARNMS2(cinfo, JWRN_EXTRANEOUS_DATA, cinfo->marker->discarded_bytes, c); + cinfo->marker->discarded_bytes = 0; + } + + cinfo->unread_marker = c; + + INPUT_SYNC(cinfo); + return TRUE; +} + + +LOCAL(boolean) +first_marker (j_decompress_ptr cinfo) +/* Like next_marker, but used to obtain the initial SOI marker. */ +/* For this marker, we do not allow preceding garbage or fill; otherwise, + * we might well scan an entire input file before realizing it ain't JPEG. + * If an application wants to process non-JFIF files, it must seek to the + * SOI before calling the JPEG library. + */ +{ + int c, c2; + INPUT_VARS(cinfo); + + INPUT_BYTE(cinfo, c, return FALSE); + INPUT_BYTE(cinfo, c2, return FALSE); + if (c != 0xFF || c2 != (int) M_SOI) + ERREXIT2(cinfo, JERR_NO_SOI, c, c2); + + cinfo->unread_marker = c2; + + INPUT_SYNC(cinfo); + return TRUE; +} + + +/* + * Read markers until SOS or EOI. + * + * Returns same codes as are defined for jpeg_consume_input: + * JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI. + */ + +METHODDEF(int) +read_markers (j_decompress_ptr cinfo) +{ + /* Outer loop repeats once for each marker. */ + for (;;) { + /* Collect the marker proper, unless we already did. */ + /* NB: first_marker() enforces the requirement that SOI appear first. */ + if (cinfo->unread_marker == 0) { + if (! cinfo->marker->saw_SOI) { + if (! first_marker(cinfo)) + return JPEG_SUSPENDED; + } else { + if (! next_marker(cinfo)) + return JPEG_SUSPENDED; + } + } + /* At this point cinfo->unread_marker contains the marker code and the + * input point is just past the marker proper, but before any parameters. + * A suspension will cause us to return with this state still true. + */ + switch (cinfo->unread_marker) { + case M_SOI: + if (! get_soi(cinfo)) + return JPEG_SUSPENDED; + break; + + case M_SOF0: /* Baseline */ + case M_SOF1: /* Extended sequential, Huffman */ + if (! get_sof(cinfo, FALSE, FALSE)) + return JPEG_SUSPENDED; + break; + + case M_SOF2: /* Progressive, Huffman */ + if (! get_sof(cinfo, TRUE, FALSE)) + return JPEG_SUSPENDED; + break; + + case M_SOF9: /* Extended sequential, arithmetic */ + if (! get_sof(cinfo, FALSE, TRUE)) + return JPEG_SUSPENDED; + break; + + case M_SOF10: /* Progressive, arithmetic */ + if (! get_sof(cinfo, TRUE, TRUE)) + return JPEG_SUSPENDED; + break; + + /* Currently unsupported SOFn types */ + case M_SOF3: /* Lossless, Huffman */ + case M_SOF5: /* Differential sequential, Huffman */ + case M_SOF6: /* Differential progressive, Huffman */ + case M_SOF7: /* Differential lossless, Huffman */ + case M_JPG: /* Reserved for JPEG extensions */ + case M_SOF11: /* Lossless, arithmetic */ + case M_SOF13: /* Differential sequential, arithmetic */ + case M_SOF14: /* Differential progressive, arithmetic */ + case M_SOF15: /* Differential lossless, arithmetic */ + ERREXIT1(cinfo, JERR_SOF_UNSUPPORTED, cinfo->unread_marker); + break; + + case M_SOS: + if (! get_sos(cinfo)) + return JPEG_SUSPENDED; + cinfo->unread_marker = 0; /* processed the marker */ + return JPEG_REACHED_SOS; + + case M_EOI: + TRACEMS(cinfo, 1, JTRC_EOI); + cinfo->unread_marker = 0; /* processed the marker */ + return JPEG_REACHED_EOI; + + case M_DAC: + if (! get_dac(cinfo)) + return JPEG_SUSPENDED; + break; + + case M_DHT: + if (! get_dht(cinfo)) + return JPEG_SUSPENDED; + break; + + case M_DQT: + if (! get_dqt(cinfo)) + return JPEG_SUSPENDED; + break; + + case M_DRI: + if (! get_dri(cinfo)) + return JPEG_SUSPENDED; + break; + + case M_APP0: + case M_APP1: + case M_APP2: + case M_APP3: + case M_APP4: + case M_APP5: + case M_APP6: + case M_APP7: + case M_APP8: + case M_APP9: + case M_APP10: + case M_APP11: + case M_APP12: + case M_APP13: + case M_APP14: + case M_APP15: + if (! (*((my_marker_ptr) cinfo->marker)->process_APPn[ + cinfo->unread_marker - (int) M_APP0]) (cinfo)) + return JPEG_SUSPENDED; + break; + + case M_COM: + if (! (*((my_marker_ptr) cinfo->marker)->process_COM) (cinfo)) + return JPEG_SUSPENDED; + break; + + case M_RST0: /* these are all parameterless */ + case M_RST1: + case M_RST2: + case M_RST3: + case M_RST4: + case M_RST5: + case M_RST6: + case M_RST7: + case M_TEM: + TRACEMS1(cinfo, 1, JTRC_PARMLESS_MARKER, cinfo->unread_marker); + break; + + case M_DNL: /* Ignore DNL ... perhaps the wrong thing */ + if (! skip_variable(cinfo)) + return JPEG_SUSPENDED; + break; + + default: /* must be DHP, EXP, JPGn, or RESn */ + /* For now, we treat the reserved markers as fatal errors since they are + * likely to be used to signal incompatible JPEG Part 3 extensions. + * Once the JPEG 3 version-number marker is well defined, this code + * ought to change! + */ + ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, cinfo->unread_marker); + break; + } + /* Successfully processed marker, so reset state variable */ + cinfo->unread_marker = 0; + } /* end loop */ +} + + +/* + * Read a restart marker, which is expected to appear next in the datastream; + * if the marker is not there, take appropriate recovery action. + * Returns FALSE if suspension is required. + * + * This is called by the entropy decoder after it has read an appropriate + * number of MCUs. cinfo->unread_marker may be nonzero if the entropy decoder + * has already read a marker from the data source. Under normal conditions + * cinfo->unread_marker will be reset to 0 before returning; if not reset, + * it holds a marker which the decoder will be unable to read past. + */ + +METHODDEF(boolean) +read_restart_marker (j_decompress_ptr cinfo) +{ + /* Obtain a marker unless we already did. */ + /* Note that next_marker will complain if it skips any data. */ + if (cinfo->unread_marker == 0) { + if (! next_marker(cinfo)) + return FALSE; + } + + if (cinfo->unread_marker == + ((int) M_RST0 + cinfo->marker->next_restart_num)) { + /* Normal case --- swallow the marker and let entropy decoder continue */ + TRACEMS1(cinfo, 3, JTRC_RST, cinfo->marker->next_restart_num); + cinfo->unread_marker = 0; + } else { + /* Uh-oh, the restart markers have been messed up. */ + /* Let the data source manager determine how to resync. */ + if (! (*cinfo->src->resync_to_restart) (cinfo, + cinfo->marker->next_restart_num)) + return FALSE; + } + + /* Update next-restart state */ + cinfo->marker->next_restart_num = (cinfo->marker->next_restart_num + 1) & 7; + + return TRUE; +} + + +/* + * This is the default resync_to_restart method for data source managers + * to use if they don't have any better approach. Some data source managers + * may be able to back up, or may have additional knowledge about the data + * which permits a more intelligent recovery strategy; such managers would + * presumably supply their own resync method. + * + * read_restart_marker calls resync_to_restart if it finds a marker other than + * the restart marker it was expecting. (This code is *not* used unless + * a nonzero restart interval has been declared.) cinfo->unread_marker is + * the marker code actually found (might be anything, except 0 or FF). + * The desired restart marker number (0..7) is passed as a parameter. + * This routine is supposed to apply whatever error recovery strategy seems + * appropriate in order to position the input stream to the next data segment. + * Note that cinfo->unread_marker is treated as a marker appearing before + * the current data-source input point; usually it should be reset to zero + * before returning. + * Returns FALSE if suspension is required. + * + * This implementation is substantially constrained by wanting to treat the + * input as a data stream; this means we can't back up. Therefore, we have + * only the following actions to work with: + * 1. Simply discard the marker and let the entropy decoder resume at next + * byte of file. + * 2. Read forward until we find another marker, discarding intervening + * data. (In theory we could look ahead within the current bufferload, + * without having to discard data if we don't find the desired marker. + * This idea is not implemented here, in part because it makes behavior + * dependent on buffer size and chance buffer-boundary positions.) + * 3. Leave the marker unread (by failing to zero cinfo->unread_marker). + * This will cause the entropy decoder to process an empty data segment, + * inserting dummy zeroes, and then we will reprocess the marker. + * + * #2 is appropriate if we think the desired marker lies ahead, while #3 is + * appropriate if the found marker is a future restart marker (indicating + * that we have missed the desired restart marker, probably because it got + * corrupted). + * We apply #2 or #3 if the found marker is a restart marker no more than + * two counts behind or ahead of the expected one. We also apply #2 if the + * found marker is not a legal JPEG marker code (it's certainly bogus data). + * If the found marker is a restart marker more than 2 counts away, we do #1 + * (too much risk that the marker is erroneous; with luck we will be able to + * resync at some future point). + * For any valid non-restart JPEG marker, we apply #3. This keeps us from + * overrunning the end of a scan. An implementation limited to single-scan + * files might find it better to apply #2 for markers other than EOI, since + * any other marker would have to be bogus data in that case. + */ + +GLOBAL(boolean) +jpeg_resync_to_restart (j_decompress_ptr cinfo, int desired) +{ + int marker = cinfo->unread_marker; + int action = 1; + + /* Always put up a warning. */ + WARNMS2(cinfo, JWRN_MUST_RESYNC, marker, desired); + + /* Outer loop handles repeated decision after scanning forward. */ + for (;;) { + if (marker < (int) M_SOF0) + action = 2; /* invalid marker */ + else if (marker < (int) M_RST0 || marker > (int) M_RST7) + action = 3; /* valid non-restart marker */ + else { + if (marker == ((int) M_RST0 + ((desired+1) & 7)) || + marker == ((int) M_RST0 + ((desired+2) & 7))) + action = 3; /* one of the next two expected restarts */ + else if (marker == ((int) M_RST0 + ((desired-1) & 7)) || + marker == ((int) M_RST0 + ((desired-2) & 7))) + action = 2; /* a prior restart, so advance */ + else + action = 1; /* desired restart or too far away */ + } + TRACEMS2(cinfo, 4, JTRC_RECOVERY_ACTION, marker, action); + switch (action) { + case 1: + /* Discard marker and let entropy decoder resume processing. */ + cinfo->unread_marker = 0; + return TRUE; + case 2: + /* Scan to the next marker, and repeat the decision loop. */ + if (! next_marker(cinfo)) + return FALSE; + marker = cinfo->unread_marker; + break; + case 3: + /* Return without advancing past this marker. */ + /* Entropy decoder will be forced to process an empty segment. */ + return TRUE; + } + } /* end loop */ +} + + +/* + * Reset marker processing state to begin a fresh datastream. + */ + +METHODDEF(void) +reset_marker_reader (j_decompress_ptr cinfo) +{ + my_marker_ptr marker = (my_marker_ptr) cinfo->marker; + + cinfo->comp_info = NULL; /* until allocated by get_sof */ + cinfo->input_scan_number = 0; /* no SOS seen yet */ + cinfo->unread_marker = 0; /* no pending marker */ + marker->pub.saw_SOI = FALSE; /* set internal state too */ + marker->pub.saw_SOF = FALSE; + marker->pub.discarded_bytes = 0; + marker->cur_marker = NULL; +} + + +/* + * Initialize the marker reader module. + * This is called only once, when the decompression object is created. + */ + +GLOBAL(void) +jinit_marker_reader (j_decompress_ptr cinfo) +{ + my_marker_ptr marker; + int i; + + /* Create subobject in permanent pool */ + marker = (my_marker_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, + SIZEOF(my_marker_reader)); + cinfo->marker = (struct jpeg_marker_reader *) marker; + /* Initialize public method pointers */ + marker->pub.reset_marker_reader = reset_marker_reader; + marker->pub.read_markers = read_markers; + marker->pub.read_restart_marker = read_restart_marker; + /* Initialize COM/APPn processing. + * By default, we examine and then discard APP0 and APP14, + * but simply discard COM and all other APPn. + */ + marker->process_COM = skip_variable; + marker->length_limit_COM = 0; + for (i = 0; i < 16; i++) { + marker->process_APPn[i] = skip_variable; + marker->length_limit_APPn[i] = 0; + } + marker->process_APPn[0] = get_interesting_appn; + marker->process_APPn[14] = get_interesting_appn; + /* Reset marker processing state */ + reset_marker_reader(cinfo); +} + + +/* + * Control saving of COM and APPn markers into marker_list. + */ + +#ifdef SAVE_MARKERS_SUPPORTED + +GLOBAL(void) +jpeg_save_markers (j_decompress_ptr cinfo, int marker_code, + unsigned int length_limit) +{ + my_marker_ptr marker = (my_marker_ptr) cinfo->marker; + long maxlength; + jpeg_marker_parser_method processor; + + /* Length limit mustn't be larger than what we can allocate + * (should only be a concern in a 16-bit environment). + */ + maxlength = cinfo->mem->max_alloc_chunk - SIZEOF(struct jpeg_marker_struct); + if (((long) length_limit) > maxlength) + length_limit = (unsigned int) maxlength; + + /* Choose processor routine to use. + * APP0/APP14 have special requirements. + */ + if (length_limit) { + processor = save_marker; + /* If saving APP0/APP14, save at least enough for our internal use. */ + if (marker_code == (int) M_APP0 && length_limit < APP0_DATA_LEN) + length_limit = APP0_DATA_LEN; + else if (marker_code == (int) M_APP14 && length_limit < APP14_DATA_LEN) + length_limit = APP14_DATA_LEN; + } else { + processor = skip_variable; + /* If discarding APP0/APP14, use our regular on-the-fly processor. */ + if (marker_code == (int) M_APP0 || marker_code == (int) M_APP14) + processor = get_interesting_appn; + } + + if (marker_code == (int) M_COM) { + marker->process_COM = processor; + marker->length_limit_COM = length_limit; + } else if (marker_code >= (int) M_APP0 && marker_code <= (int) M_APP15) { + marker->process_APPn[marker_code - (int) M_APP0] = processor; + marker->length_limit_APPn[marker_code - (int) M_APP0] = length_limit; + } else + ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, marker_code); +} + +#endif /* SAVE_MARKERS_SUPPORTED */ + + +/* + * Install a special processing method for COM or APPn markers. + */ + +GLOBAL(void) +jpeg_set_marker_processor (j_decompress_ptr cinfo, int marker_code, + jpeg_marker_parser_method routine) +{ + my_marker_ptr marker = (my_marker_ptr) cinfo->marker; + + if (marker_code == (int) M_COM) + marker->process_COM = routine; + else if (marker_code >= (int) M_APP0 && marker_code <= (int) M_APP15) + marker->process_APPn[marker_code - (int) M_APP0] = routine; + else + ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, marker_code); +} diff --git a/mod/pub.mod/libjpeg.mod/jdmaster.c b/mod/pub.mod/libjpeg.mod/jdmaster.c new file mode 100644 index 0000000..2802c5b --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jdmaster.c @@ -0,0 +1,557 @@ +/* + * jdmaster.c + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains master control logic for the JPEG decompressor. + * These routines are concerned with selecting the modules to be executed + * and with determining the number of passes and the work to be done in each + * pass. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* Private state */ + +typedef struct { + struct jpeg_decomp_master pub; /* public fields */ + + int pass_number; /* # of passes completed */ + + boolean using_merged_upsample; /* TRUE if using merged upsample/cconvert */ + + /* Saved references to initialized quantizer modules, + * in case we need to switch modes. + */ + struct jpeg_color_quantizer * quantizer_1pass; + struct jpeg_color_quantizer * quantizer_2pass; +} my_decomp_master; + +typedef my_decomp_master * my_master_ptr; + + +/* + * Determine whether merged upsample/color conversion should be used. + * CRUCIAL: this must match the actual capabilities of jdmerge.c! + */ + +LOCAL(boolean) +use_merged_upsample (j_decompress_ptr cinfo) +{ +#ifdef UPSAMPLE_MERGING_SUPPORTED + /* Merging is the equivalent of plain box-filter upsampling */ + if (cinfo->do_fancy_upsampling || cinfo->CCIR601_sampling) + return FALSE; + /* jdmerge.c only supports YCC=>RGB color conversion */ + if (cinfo->jpeg_color_space != JCS_YCbCr || cinfo->num_components != 3 || + cinfo->out_color_space != JCS_RGB || + cinfo->out_color_components != RGB_PIXELSIZE) + return FALSE; + /* and it only handles 2h1v or 2h2v sampling ratios */ + if (cinfo->comp_info[0].h_samp_factor != 2 || + cinfo->comp_info[1].h_samp_factor != 1 || + cinfo->comp_info[2].h_samp_factor != 1 || + cinfo->comp_info[0].v_samp_factor > 2 || + cinfo->comp_info[1].v_samp_factor != 1 || + cinfo->comp_info[2].v_samp_factor != 1) + return FALSE; + /* furthermore, it doesn't work if we've scaled the IDCTs differently */ + if (cinfo->comp_info[0].DCT_scaled_size != cinfo->min_DCT_scaled_size || + cinfo->comp_info[1].DCT_scaled_size != cinfo->min_DCT_scaled_size || + cinfo->comp_info[2].DCT_scaled_size != cinfo->min_DCT_scaled_size) + return FALSE; + /* ??? also need to test for upsample-time rescaling, when & if supported */ + return TRUE; /* by golly, it'll work... */ +#else + return FALSE; +#endif +} + + +/* + * Compute output image dimensions and related values. + * NOTE: this is exported for possible use by application. + * Hence it mustn't do anything that can't be done twice. + * Also note that it may be called before the master module is initialized! + */ + +GLOBAL(void) +jpeg_calc_output_dimensions (j_decompress_ptr cinfo) +/* Do computations that are needed before master selection phase */ +{ +#ifdef IDCT_SCALING_SUPPORTED + int ci; + jpeg_component_info *compptr; +#endif + + /* Prevent application from calling me at wrong times */ + if (cinfo->global_state != DSTATE_READY) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + +#ifdef IDCT_SCALING_SUPPORTED + + /* Compute actual output image dimensions and DCT scaling choices. */ + if (cinfo->scale_num * 8 <= cinfo->scale_denom) { + /* Provide 1/8 scaling */ + cinfo->output_width = (JDIMENSION) + jdiv_round_up((long) cinfo->image_width, 8L); + cinfo->output_height = (JDIMENSION) + jdiv_round_up((long) cinfo->image_height, 8L); + cinfo->min_DCT_scaled_size = 1; + } else if (cinfo->scale_num * 4 <= cinfo->scale_denom) { + /* Provide 1/4 scaling */ + cinfo->output_width = (JDIMENSION) + jdiv_round_up((long) cinfo->image_width, 4L); + cinfo->output_height = (JDIMENSION) + jdiv_round_up((long) cinfo->image_height, 4L); + cinfo->min_DCT_scaled_size = 2; + } else if (cinfo->scale_num * 2 <= cinfo->scale_denom) { + /* Provide 1/2 scaling */ + cinfo->output_width = (JDIMENSION) + jdiv_round_up((long) cinfo->image_width, 2L); + cinfo->output_height = (JDIMENSION) + jdiv_round_up((long) cinfo->image_height, 2L); + cinfo->min_DCT_scaled_size = 4; + } else { + /* Provide 1/1 scaling */ + cinfo->output_width = cinfo->image_width; + cinfo->output_height = cinfo->image_height; + cinfo->min_DCT_scaled_size = DCTSIZE; + } + /* In selecting the actual DCT scaling for each component, we try to + * scale up the chroma components via IDCT scaling rather than upsampling. + * This saves time if the upsampler gets to use 1:1 scaling. + * Note this code assumes that the supported DCT scalings are powers of 2. + */ + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + int ssize = cinfo->min_DCT_scaled_size; + while (ssize < DCTSIZE && + (compptr->h_samp_factor * ssize * 2 <= + cinfo->max_h_samp_factor * cinfo->min_DCT_scaled_size) && + (compptr->v_samp_factor * ssize * 2 <= + cinfo->max_v_samp_factor * cinfo->min_DCT_scaled_size)) { + ssize = ssize * 2; + } + compptr->DCT_scaled_size = ssize; + } + + /* Recompute downsampled dimensions of components; + * application needs to know these if using raw downsampled data. + */ + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + /* Size in samples, after IDCT scaling */ + compptr->downsampled_width = (JDIMENSION) + jdiv_round_up((long) cinfo->image_width * + (long) (compptr->h_samp_factor * compptr->DCT_scaled_size), + (long) (cinfo->max_h_samp_factor * DCTSIZE)); + compptr->downsampled_height = (JDIMENSION) + jdiv_round_up((long) cinfo->image_height * + (long) (compptr->v_samp_factor * compptr->DCT_scaled_size), + (long) (cinfo->max_v_samp_factor * DCTSIZE)); + } + +#else /* !IDCT_SCALING_SUPPORTED */ + + /* Hardwire it to "no scaling" */ + cinfo->output_width = cinfo->image_width; + cinfo->output_height = cinfo->image_height; + /* jdinput.c has already initialized DCT_scaled_size to DCTSIZE, + * and has computed unscaled downsampled_width and downsampled_height. + */ + +#endif /* IDCT_SCALING_SUPPORTED */ + + /* Report number of components in selected colorspace. */ + /* Probably this should be in the color conversion module... */ + switch (cinfo->out_color_space) { + case JCS_GRAYSCALE: + cinfo->out_color_components = 1; + break; + case JCS_RGB: +#if RGB_PIXELSIZE != 3 + cinfo->out_color_components = RGB_PIXELSIZE; + break; +#endif /* else share code with YCbCr */ + case JCS_YCbCr: + cinfo->out_color_components = 3; + break; + case JCS_CMYK: + case JCS_YCCK: + cinfo->out_color_components = 4; + break; + default: /* else must be same colorspace as in file */ + cinfo->out_color_components = cinfo->num_components; + break; + } + cinfo->output_components = (cinfo->quantize_colors ? 1 : + cinfo->out_color_components); + + /* See if upsampler will want to emit more than one row at a time */ + if (use_merged_upsample(cinfo)) + cinfo->rec_outbuf_height = cinfo->max_v_samp_factor; + else + cinfo->rec_outbuf_height = 1; +} + + +/* + * Several decompression processes need to range-limit values to the range + * 0..MAXJSAMPLE; the input value may fall somewhat outside this range + * due to noise introduced by quantization, roundoff error, etc. These + * processes are inner loops and need to be as fast as possible. On most + * machines, particularly CPUs with pipelines or instruction prefetch, + * a (subscript-check-less) C table lookup + * x = sample_range_limit[x]; + * is faster than explicit tests + * if (x < 0) x = 0; + * else if (x > MAXJSAMPLE) x = MAXJSAMPLE; + * These processes all use a common table prepared by the routine below. + * + * For most steps we can mathematically guarantee that the initial value + * of x is within MAXJSAMPLE+1 of the legal range, so a table running from + * -(MAXJSAMPLE+1) to 2*MAXJSAMPLE+1 is sufficient. But for the initial + * limiting step (just after the IDCT), a wildly out-of-range value is + * possible if the input data is corrupt. To avoid any chance of indexing + * off the end of memory and getting a bad-pointer trap, we perform the + * post-IDCT limiting thus: + * x = range_limit[x & MASK]; + * where MASK is 2 bits wider than legal sample data, ie 10 bits for 8-bit + * samples. Under normal circumstances this is more than enough range and + * a correct output will be generated; with bogus input data the mask will + * cause wraparound, and we will safely generate a bogus-but-in-range output. + * For the post-IDCT step, we want to convert the data from signed to unsigned + * representation by adding CENTERJSAMPLE at the same time that we limit it. + * So the post-IDCT limiting table ends up looking like this: + * CENTERJSAMPLE,CENTERJSAMPLE+1,...,MAXJSAMPLE, + * MAXJSAMPLE (repeat 2*(MAXJSAMPLE+1)-CENTERJSAMPLE times), + * 0 (repeat 2*(MAXJSAMPLE+1)-CENTERJSAMPLE times), + * 0,1,...,CENTERJSAMPLE-1 + * Negative inputs select values from the upper half of the table after + * masking. + * + * We can save some space by overlapping the start of the post-IDCT table + * with the simpler range limiting table. The post-IDCT table begins at + * sample_range_limit + CENTERJSAMPLE. + * + * Note that the table is allocated in near data space on PCs; it's small + * enough and used often enough to justify this. + */ + +LOCAL(void) +prepare_range_limit_table (j_decompress_ptr cinfo) +/* Allocate and fill in the sample_range_limit table */ +{ + JSAMPLE * table; + int i; + + table = (JSAMPLE *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (5 * (MAXJSAMPLE+1) + CENTERJSAMPLE) * SIZEOF(JSAMPLE)); + table += (MAXJSAMPLE+1); /* allow negative subscripts of simple table */ + cinfo->sample_range_limit = table; + /* First segment of "simple" table: limit[x] = 0 for x < 0 */ + MEMZERO(table - (MAXJSAMPLE+1), (MAXJSAMPLE+1) * SIZEOF(JSAMPLE)); + /* Main part of "simple" table: limit[x] = x */ + for (i = 0; i <= MAXJSAMPLE; i++) + table[i] = (JSAMPLE) i; + table += CENTERJSAMPLE; /* Point to where post-IDCT table starts */ + /* End of simple table, rest of first half of post-IDCT table */ + for (i = CENTERJSAMPLE; i < 2*(MAXJSAMPLE+1); i++) + table[i] = MAXJSAMPLE; + /* Second half of post-IDCT table */ + MEMZERO(table + (2 * (MAXJSAMPLE+1)), + (2 * (MAXJSAMPLE+1) - CENTERJSAMPLE) * SIZEOF(JSAMPLE)); + MEMCOPY(table + (4 * (MAXJSAMPLE+1) - CENTERJSAMPLE), + cinfo->sample_range_limit, CENTERJSAMPLE * SIZEOF(JSAMPLE)); +} + + +/* + * Master selection of decompression modules. + * This is done once at jpeg_start_decompress time. We determine + * which modules will be used and give them appropriate initialization calls. + * We also initialize the decompressor input side to begin consuming data. + * + * Since jpeg_read_header has finished, we know what is in the SOF + * and (first) SOS markers. We also have all the application parameter + * settings. + */ + +LOCAL(void) +master_selection (j_decompress_ptr cinfo) +{ + my_master_ptr master = (my_master_ptr) cinfo->master; + boolean use_c_buffer; + long samplesperrow; + JDIMENSION jd_samplesperrow; + + /* Initialize dimensions and other stuff */ + jpeg_calc_output_dimensions(cinfo); + prepare_range_limit_table(cinfo); + + /* Width of an output scanline must be representable as JDIMENSION. */ + samplesperrow = (long) cinfo->output_width * (long) cinfo->out_color_components; + jd_samplesperrow = (JDIMENSION) samplesperrow; + if ((long) jd_samplesperrow != samplesperrow) + ERREXIT(cinfo, JERR_WIDTH_OVERFLOW); + + /* Initialize my private state */ + master->pass_number = 0; + master->using_merged_upsample = use_merged_upsample(cinfo); + + /* Color quantizer selection */ + master->quantizer_1pass = NULL; + master->quantizer_2pass = NULL; + /* No mode changes if not using buffered-image mode. */ + if (! cinfo->quantize_colors || ! cinfo->buffered_image) { + cinfo->enable_1pass_quant = FALSE; + cinfo->enable_external_quant = FALSE; + cinfo->enable_2pass_quant = FALSE; + } + if (cinfo->quantize_colors) { + if (cinfo->raw_data_out) + ERREXIT(cinfo, JERR_NOTIMPL); + /* 2-pass quantizer only works in 3-component color space. */ + if (cinfo->out_color_components != 3) { + cinfo->enable_1pass_quant = TRUE; + cinfo->enable_external_quant = FALSE; + cinfo->enable_2pass_quant = FALSE; + cinfo->colormap = NULL; + } else if (cinfo->colormap != NULL) { + cinfo->enable_external_quant = TRUE; + } else if (cinfo->two_pass_quantize) { + cinfo->enable_2pass_quant = TRUE; + } else { + cinfo->enable_1pass_quant = TRUE; + } + + if (cinfo->enable_1pass_quant) { +#ifdef QUANT_1PASS_SUPPORTED + jinit_1pass_quantizer(cinfo); + master->quantizer_1pass = cinfo->cquantize; +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } + + /* We use the 2-pass code to map to external colormaps. */ + if (cinfo->enable_2pass_quant || cinfo->enable_external_quant) { +#ifdef QUANT_2PASS_SUPPORTED + jinit_2pass_quantizer(cinfo); + master->quantizer_2pass = cinfo->cquantize; +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } + /* If both quantizers are initialized, the 2-pass one is left active; + * this is necessary for starting with quantization to an external map. + */ + } + + /* Post-processing: in particular, color conversion first */ + if (! cinfo->raw_data_out) { + if (master->using_merged_upsample) { +#ifdef UPSAMPLE_MERGING_SUPPORTED + jinit_merged_upsampler(cinfo); /* does color conversion too */ +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } else { + jinit_color_deconverter(cinfo); + jinit_upsampler(cinfo); + } + jinit_d_post_controller(cinfo, cinfo->enable_2pass_quant); + } + /* Inverse DCT */ + jinit_inverse_dct(cinfo); + /* Entropy decoding: either Huffman or arithmetic coding. */ + if (cinfo->arith_code) { + ERREXIT(cinfo, JERR_ARITH_NOTIMPL); + } else { + if (cinfo->progressive_mode) { +#ifdef D_PROGRESSIVE_SUPPORTED + jinit_phuff_decoder(cinfo); +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } else + jinit_huff_decoder(cinfo); + } + + /* Initialize principal buffer controllers. */ + use_c_buffer = cinfo->inputctl->has_multiple_scans || cinfo->buffered_image; + jinit_d_coef_controller(cinfo, use_c_buffer); + + if (! cinfo->raw_data_out) + jinit_d_main_controller(cinfo, FALSE /* never need full buffer here */); + + /* We can now tell the memory manager to allocate virtual arrays. */ + (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo); + + /* Initialize input side of decompressor to consume first scan. */ + (*cinfo->inputctl->start_input_pass) (cinfo); + +#ifdef D_MULTISCAN_FILES_SUPPORTED + /* If jpeg_start_decompress will read the whole file, initialize + * progress monitoring appropriately. The input step is counted + * as one pass. + */ + if (cinfo->progress != NULL && ! cinfo->buffered_image && + cinfo->inputctl->has_multiple_scans) { + int nscans; + /* Estimate number of scans to set pass_limit. */ + if (cinfo->progressive_mode) { + /* Arbitrarily estimate 2 interleaved DC scans + 3 AC scans/component. */ + nscans = 2 + 3 * cinfo->num_components; + } else { + /* For a nonprogressive multiscan file, estimate 1 scan per component. */ + nscans = cinfo->num_components; + } + cinfo->progress->pass_counter = 0L; + cinfo->progress->pass_limit = (long) cinfo->total_iMCU_rows * nscans; + cinfo->progress->completed_passes = 0; + cinfo->progress->total_passes = (cinfo->enable_2pass_quant ? 3 : 2); + /* Count the input pass as done */ + master->pass_number++; + } +#endif /* D_MULTISCAN_FILES_SUPPORTED */ +} + + +/* + * Per-pass setup. + * This is called at the beginning of each output pass. We determine which + * modules will be active during this pass and give them appropriate + * start_pass calls. We also set is_dummy_pass to indicate whether this + * is a "real" output pass or a dummy pass for color quantization. + * (In the latter case, jdapistd.c will crank the pass to completion.) + */ + +METHODDEF(void) +prepare_for_output_pass (j_decompress_ptr cinfo) +{ + my_master_ptr master = (my_master_ptr) cinfo->master; + + if (master->pub.is_dummy_pass) { +#ifdef QUANT_2PASS_SUPPORTED + /* Final pass of 2-pass quantization */ + master->pub.is_dummy_pass = FALSE; + (*cinfo->cquantize->start_pass) (cinfo, FALSE); + (*cinfo->post->start_pass) (cinfo, JBUF_CRANK_DEST); + (*cinfo->main->start_pass) (cinfo, JBUF_CRANK_DEST); +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif /* QUANT_2PASS_SUPPORTED */ + } else { + if (cinfo->quantize_colors && cinfo->colormap == NULL) { + /* Select new quantization method */ + if (cinfo->two_pass_quantize && cinfo->enable_2pass_quant) { + cinfo->cquantize = master->quantizer_2pass; + master->pub.is_dummy_pass = TRUE; + } else if (cinfo->enable_1pass_quant) { + cinfo->cquantize = master->quantizer_1pass; + } else { + ERREXIT(cinfo, JERR_MODE_CHANGE); + } + } + (*cinfo->idct->start_pass) (cinfo); + (*cinfo->coef->start_output_pass) (cinfo); + if (! cinfo->raw_data_out) { + if (! master->using_merged_upsample) + (*cinfo->cconvert->start_pass) (cinfo); + (*cinfo->upsample->start_pass) (cinfo); + if (cinfo->quantize_colors) + (*cinfo->cquantize->start_pass) (cinfo, master->pub.is_dummy_pass); + (*cinfo->post->start_pass) (cinfo, + (master->pub.is_dummy_pass ? JBUF_SAVE_AND_PASS : JBUF_PASS_THRU)); + (*cinfo->main->start_pass) (cinfo, JBUF_PASS_THRU); + } + } + + /* Set up progress monitor's pass info if present */ + if (cinfo->progress != NULL) { + cinfo->progress->completed_passes = master->pass_number; + cinfo->progress->total_passes = master->pass_number + + (master->pub.is_dummy_pass ? 2 : 1); + /* In buffered-image mode, we assume one more output pass if EOI not + * yet reached, but no more passes if EOI has been reached. + */ + if (cinfo->buffered_image && ! cinfo->inputctl->eoi_reached) { + cinfo->progress->total_passes += (cinfo->enable_2pass_quant ? 2 : 1); + } + } +} + + +/* + * Finish up at end of an output pass. + */ + +METHODDEF(void) +finish_output_pass (j_decompress_ptr cinfo) +{ + my_master_ptr master = (my_master_ptr) cinfo->master; + + if (cinfo->quantize_colors) + (*cinfo->cquantize->finish_pass) (cinfo); + master->pass_number++; +} + + +#ifdef D_MULTISCAN_FILES_SUPPORTED + +/* + * Switch to a new external colormap between output passes. + */ + +GLOBAL(void) +jpeg_new_colormap (j_decompress_ptr cinfo) +{ + my_master_ptr master = (my_master_ptr) cinfo->master; + + /* Prevent application from calling me at wrong times */ + if (cinfo->global_state != DSTATE_BUFIMAGE) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + + if (cinfo->quantize_colors && cinfo->enable_external_quant && + cinfo->colormap != NULL) { + /* Select 2-pass quantizer for external colormap use */ + cinfo->cquantize = master->quantizer_2pass; + /* Notify quantizer of colormap change */ + (*cinfo->cquantize->new_color_map) (cinfo); + master->pub.is_dummy_pass = FALSE; /* just in case */ + } else + ERREXIT(cinfo, JERR_MODE_CHANGE); +} + +#endif /* D_MULTISCAN_FILES_SUPPORTED */ + + +/* + * Initialize master decompression control and select active modules. + * This is performed at the start of jpeg_start_decompress. + */ + +GLOBAL(void) +jinit_master_decompress (j_decompress_ptr cinfo) +{ + my_master_ptr master; + + master = (my_master_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_decomp_master)); + cinfo->master = (struct jpeg_decomp_master *) master; + master->pub.prepare_for_output_pass = prepare_for_output_pass; + master->pub.finish_output_pass = finish_output_pass; + + master->pub.is_dummy_pass = FALSE; + + master_selection(cinfo); +} diff --git a/mod/pub.mod/libjpeg.mod/jdmerge.c b/mod/pub.mod/libjpeg.mod/jdmerge.c new file mode 100644 index 0000000..3744446 --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jdmerge.c @@ -0,0 +1,400 @@ +/* + * jdmerge.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains code for merged upsampling/color conversion. + * + * This file combines functions from jdsample.c and jdcolor.c; + * read those files first to understand what's going on. + * + * When the chroma components are to be upsampled by simple replication + * (ie, box filtering), we can save some work in color conversion by + * calculating all the output pixels corresponding to a pair of chroma + * samples at one time. In the conversion equations + * R = Y + K1 * Cr + * G = Y + K2 * Cb + K3 * Cr + * B = Y + K4 * Cb + * only the Y term varies among the group of pixels corresponding to a pair + * of chroma samples, so the rest of the terms can be calculated just once. + * At typical sampling ratios, this eliminates half or three-quarters of the + * multiplications needed for color conversion. + * + * This file currently provides implementations for the following cases: + * YCbCr => RGB color conversion only. + * Sampling ratios of 2h1v or 2h2v. + * No scaling needed at upsample time. + * Corner-aligned (non-CCIR601) sampling alignment. + * Other special cases could be added, but in most applications these are + * the only common cases. (For uncommon cases we fall back on the more + * general code in jdsample.c and jdcolor.c.) + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + +#ifdef UPSAMPLE_MERGING_SUPPORTED + + +/* Private subobject */ + +typedef struct { + struct jpeg_upsampler pub; /* public fields */ + + /* Pointer to routine to do actual upsampling/conversion of one row group */ + JMETHOD(void, upmethod, (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr, + JSAMPARRAY output_buf)); + + /* Private state for YCC->RGB conversion */ + int * Cr_r_tab; /* => table for Cr to R conversion */ + int * Cb_b_tab; /* => table for Cb to B conversion */ + INT32 * Cr_g_tab; /* => table for Cr to G conversion */ + INT32 * Cb_g_tab; /* => table for Cb to G conversion */ + + /* For 2:1 vertical sampling, we produce two output rows at a time. + * We need a "spare" row buffer to hold the second output row if the + * application provides just a one-row buffer; we also use the spare + * to discard the dummy last row if the image height is odd. + */ + JSAMPROW spare_row; + boolean spare_full; /* T if spare buffer is occupied */ + + JDIMENSION out_row_width; /* samples per output row */ + JDIMENSION rows_to_go; /* counts rows remaining in image */ +} my_upsampler; + +typedef my_upsampler * my_upsample_ptr; + +#define SCALEBITS 16 /* speediest right-shift on some machines */ +#define ONE_HALF ((INT32) 1 << (SCALEBITS-1)) +#define FIX(x) ((INT32) ((x) * (1L<<SCALEBITS) + 0.5)) + + +/* + * Initialize tables for YCC->RGB colorspace conversion. + * This is taken directly from jdcolor.c; see that file for more info. + */ + +LOCAL(void) +build_ycc_rgb_table (j_decompress_ptr cinfo) +{ + my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; + int i; + INT32 x; + SHIFT_TEMPS + + upsample->Cr_r_tab = (int *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (MAXJSAMPLE+1) * SIZEOF(int)); + upsample->Cb_b_tab = (int *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (MAXJSAMPLE+1) * SIZEOF(int)); + upsample->Cr_g_tab = (INT32 *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (MAXJSAMPLE+1) * SIZEOF(INT32)); + upsample->Cb_g_tab = (INT32 *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (MAXJSAMPLE+1) * SIZEOF(INT32)); + + for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) { + /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */ + /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */ + /* Cr=>R value is nearest int to 1.40200 * x */ + upsample->Cr_r_tab[i] = (int) + RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS); + /* Cb=>B value is nearest int to 1.77200 * x */ + upsample->Cb_b_tab[i] = (int) + RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS); + /* Cr=>G value is scaled-up -0.71414 * x */ + upsample->Cr_g_tab[i] = (- FIX(0.71414)) * x; + /* Cb=>G value is scaled-up -0.34414 * x */ + /* We also add in ONE_HALF so that need not do it in inner loop */ + upsample->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF; + } +} + + +/* + * Initialize for an upsampling pass. + */ + +METHODDEF(void) +start_pass_merged_upsample (j_decompress_ptr cinfo) +{ + my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; + + /* Mark the spare buffer empty */ + upsample->spare_full = FALSE; + /* Initialize total-height counter for detecting bottom of image */ + upsample->rows_to_go = cinfo->output_height; +} + + +/* + * Control routine to do upsampling (and color conversion). + * + * The control routine just handles the row buffering considerations. + */ + +METHODDEF(void) +merged_2v_upsample (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, + JDIMENSION in_row_groups_avail, + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail) +/* 2:1 vertical sampling case: may need a spare row. */ +{ + my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; + JSAMPROW work_ptrs[2]; + JDIMENSION num_rows; /* number of rows returned to caller */ + + if (upsample->spare_full) { + /* If we have a spare row saved from a previous cycle, just return it. */ + jcopy_sample_rows(& upsample->spare_row, 0, output_buf + *out_row_ctr, 0, + 1, upsample->out_row_width); + num_rows = 1; + upsample->spare_full = FALSE; + } else { + /* Figure number of rows to return to caller. */ + num_rows = 2; + /* Not more than the distance to the end of the image. */ + if (num_rows > upsample->rows_to_go) + num_rows = upsample->rows_to_go; + /* And not more than what the client can accept: */ + out_rows_avail -= *out_row_ctr; + if (num_rows > out_rows_avail) + num_rows = out_rows_avail; + /* Create output pointer array for upsampler. */ + work_ptrs[0] = output_buf[*out_row_ctr]; + if (num_rows > 1) { + work_ptrs[1] = output_buf[*out_row_ctr + 1]; + } else { + work_ptrs[1] = upsample->spare_row; + upsample->spare_full = TRUE; + } + /* Now do the upsampling. */ + (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr, work_ptrs); + } + + /* Adjust counts */ + *out_row_ctr += num_rows; + upsample->rows_to_go -= num_rows; + /* When the buffer is emptied, declare this input row group consumed */ + if (! upsample->spare_full) + (*in_row_group_ctr)++; +} + + +METHODDEF(void) +merged_1v_upsample (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, + JDIMENSION in_row_groups_avail, + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail) +/* 1:1 vertical sampling case: much easier, never need a spare row. */ +{ + my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; + + /* Just do the upsampling. */ + (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr, + output_buf + *out_row_ctr); + /* Adjust counts */ + (*out_row_ctr)++; + (*in_row_group_ctr)++; +} + + +/* + * These are the routines invoked by the control routines to do + * the actual upsampling/conversion. One row group is processed per call. + * + * Note: since we may be writing directly into application-supplied buffers, + * we have to be honest about the output width; we can't assume the buffer + * has been rounded up to an even width. + */ + + +/* + * Upsample and color convert for the case of 2:1 horizontal and 1:1 vertical. + */ + +METHODDEF(void) +h2v1_merged_upsample (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr, + JSAMPARRAY output_buf) +{ + my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; + register int y, cred, cgreen, cblue; + int cb, cr; + register JSAMPROW outptr; + JSAMPROW inptr0, inptr1, inptr2; + JDIMENSION col; + /* copy these pointers into registers if possible */ + register JSAMPLE * range_limit = cinfo->sample_range_limit; + int * Crrtab = upsample->Cr_r_tab; + int * Cbbtab = upsample->Cb_b_tab; + INT32 * Crgtab = upsample->Cr_g_tab; + INT32 * Cbgtab = upsample->Cb_g_tab; + SHIFT_TEMPS + + inptr0 = input_buf[0][in_row_group_ctr]; + inptr1 = input_buf[1][in_row_group_ctr]; + inptr2 = input_buf[2][in_row_group_ctr]; + outptr = output_buf[0]; + /* Loop for each pair of output pixels */ + for (col = cinfo->output_width >> 1; col > 0; col--) { + /* Do the chroma part of the calculation */ + cb = GETJSAMPLE(*inptr1++); + cr = GETJSAMPLE(*inptr2++); + cred = Crrtab[cr]; + cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); + cblue = Cbbtab[cb]; + /* Fetch 2 Y values and emit 2 pixels */ + y = GETJSAMPLE(*inptr0++); + outptr[RGB_RED] = range_limit[y + cred]; + outptr[RGB_GREEN] = range_limit[y + cgreen]; + outptr[RGB_BLUE] = range_limit[y + cblue]; + outptr += RGB_PIXELSIZE; + y = GETJSAMPLE(*inptr0++); + outptr[RGB_RED] = range_limit[y + cred]; + outptr[RGB_GREEN] = range_limit[y + cgreen]; + outptr[RGB_BLUE] = range_limit[y + cblue]; + outptr += RGB_PIXELSIZE; + } + /* If image width is odd, do the last output column separately */ + if (cinfo->output_width & 1) { + cb = GETJSAMPLE(*inptr1); + cr = GETJSAMPLE(*inptr2); + cred = Crrtab[cr]; + cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); + cblue = Cbbtab[cb]; + y = GETJSAMPLE(*inptr0); + outptr[RGB_RED] = range_limit[y + cred]; + outptr[RGB_GREEN] = range_limit[y + cgreen]; + outptr[RGB_BLUE] = range_limit[y + cblue]; + } +} + + +/* + * Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical. + */ + +METHODDEF(void) +h2v2_merged_upsample (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr, + JSAMPARRAY output_buf) +{ + my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; + register int y, cred, cgreen, cblue; + int cb, cr; + register JSAMPROW outptr0, outptr1; + JSAMPROW inptr00, inptr01, inptr1, inptr2; + JDIMENSION col; + /* copy these pointers into registers if possible */ + register JSAMPLE * range_limit = cinfo->sample_range_limit; + int * Crrtab = upsample->Cr_r_tab; + int * Cbbtab = upsample->Cb_b_tab; + INT32 * Crgtab = upsample->Cr_g_tab; + INT32 * Cbgtab = upsample->Cb_g_tab; + SHIFT_TEMPS + + inptr00 = input_buf[0][in_row_group_ctr*2]; + inptr01 = input_buf[0][in_row_group_ctr*2 + 1]; + inptr1 = input_buf[1][in_row_group_ctr]; + inptr2 = input_buf[2][in_row_group_ctr]; + outptr0 = output_buf[0]; + outptr1 = output_buf[1]; + /* Loop for each group of output pixels */ + for (col = cinfo->output_width >> 1; col > 0; col--) { + /* Do the chroma part of the calculation */ + cb = GETJSAMPLE(*inptr1++); + cr = GETJSAMPLE(*inptr2++); + cred = Crrtab[cr]; + cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); + cblue = Cbbtab[cb]; + /* Fetch 4 Y values and emit 4 pixels */ + y = GETJSAMPLE(*inptr00++); + outptr0[RGB_RED] = range_limit[y + cred]; + outptr0[RGB_GREEN] = range_limit[y + cgreen]; + outptr0[RGB_BLUE] = range_limit[y + cblue]; + outptr0 += RGB_PIXELSIZE; + y = GETJSAMPLE(*inptr00++); + outptr0[RGB_RED] = range_limit[y + cred]; + outptr0[RGB_GREEN] = range_limit[y + cgreen]; + outptr0[RGB_BLUE] = range_limit[y + cblue]; + outptr0 += RGB_PIXELSIZE; + y = GETJSAMPLE(*inptr01++); + outptr1[RGB_RED] = range_limit[y + cred]; + outptr1[RGB_GREEN] = range_limit[y + cgreen]; + outptr1[RGB_BLUE] = range_limit[y + cblue]; + outptr1 += RGB_PIXELSIZE; + y = GETJSAMPLE(*inptr01++); + outptr1[RGB_RED] = range_limit[y + cred]; + outptr1[RGB_GREEN] = range_limit[y + cgreen]; + outptr1[RGB_BLUE] = range_limit[y + cblue]; + outptr1 += RGB_PIXELSIZE; + } + /* If image width is odd, do the last output column separately */ + if (cinfo->output_width & 1) { + cb = GETJSAMPLE(*inptr1); + cr = GETJSAMPLE(*inptr2); + cred = Crrtab[cr]; + cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); + cblue = Cbbtab[cb]; + y = GETJSAMPLE(*inptr00); + outptr0[RGB_RED] = range_limit[y + cred]; + outptr0[RGB_GREEN] = range_limit[y + cgreen]; + outptr0[RGB_BLUE] = range_limit[y + cblue]; + y = GETJSAMPLE(*inptr01); + outptr1[RGB_RED] = range_limit[y + cred]; + outptr1[RGB_GREEN] = range_limit[y + cgreen]; + outptr1[RGB_BLUE] = range_limit[y + cblue]; + } +} + + +/* + * Module initialization routine for merged upsampling/color conversion. + * + * NB: this is called under the conditions determined by use_merged_upsample() + * in jdmaster.c. That routine MUST correspond to the actual capabilities + * of this module; no safety checks are made here. + */ + +GLOBAL(void) +jinit_merged_upsampler (j_decompress_ptr cinfo) +{ + my_upsample_ptr upsample; + + upsample = (my_upsample_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_upsampler)); + cinfo->upsample = (struct jpeg_upsampler *) upsample; + upsample->pub.start_pass = start_pass_merged_upsample; + upsample->pub.need_context_rows = FALSE; + + upsample->out_row_width = cinfo->output_width * cinfo->out_color_components; + + if (cinfo->max_v_samp_factor == 2) { + upsample->pub.upsample = merged_2v_upsample; + upsample->upmethod = h2v2_merged_upsample; + /* Allocate a spare row buffer */ + upsample->spare_row = (JSAMPROW) + (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (size_t) (upsample->out_row_width * SIZEOF(JSAMPLE))); + } else { + upsample->pub.upsample = merged_1v_upsample; + upsample->upmethod = h2v1_merged_upsample; + /* No spare row needed */ + upsample->spare_row = NULL; + } + + build_ycc_rgb_table(cinfo); +} + +#endif /* UPSAMPLE_MERGING_SUPPORTED */ diff --git a/mod/pub.mod/libjpeg.mod/jdphuff.c b/mod/pub.mod/libjpeg.mod/jdphuff.c new file mode 100644 index 0000000..2267809 --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jdphuff.c @@ -0,0 +1,668 @@ +/* + * jdphuff.c + * + * Copyright (C) 1995-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains Huffman entropy decoding routines for progressive JPEG. + * + * Much of the complexity here has to do with supporting input suspension. + * If the data source module demands suspension, we want to be able to back + * up to the start of the current MCU. To do this, we copy state variables + * into local working storage, and update them back to the permanent + * storage only upon successful completion of an MCU. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdhuff.h" /* Declarations shared with jdhuff.c */ + + +#ifdef D_PROGRESSIVE_SUPPORTED + +/* + * Expanded entropy decoder object for progressive Huffman decoding. + * + * The savable_state subrecord contains fields that change within an MCU, + * but must not be updated permanently until we complete the MCU. + */ + +typedef struct { + unsigned int EOBRUN; /* remaining EOBs in EOBRUN */ + int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */ +} savable_state; + +/* This macro is to work around compilers with missing or broken + * structure assignment. You'll need to fix this code if you have + * such a compiler and you change MAX_COMPS_IN_SCAN. + */ + +#ifndef NO_STRUCT_ASSIGN +#define ASSIGN_STATE(dest,src) ((dest) = (src)) +#else +#if MAX_COMPS_IN_SCAN == 4 +#define ASSIGN_STATE(dest,src) \ + ((dest).EOBRUN = (src).EOBRUN, \ + (dest).last_dc_val[0] = (src).last_dc_val[0], \ + (dest).last_dc_val[1] = (src).last_dc_val[1], \ + (dest).last_dc_val[2] = (src).last_dc_val[2], \ + (dest).last_dc_val[3] = (src).last_dc_val[3]) +#endif +#endif + + +typedef struct { + struct jpeg_entropy_decoder pub; /* public fields */ + + /* These fields are loaded into local variables at start of each MCU. + * In case of suspension, we exit WITHOUT updating them. + */ + bitread_perm_state bitstate; /* Bit buffer at start of MCU */ + savable_state saved; /* Other state at start of MCU */ + + /* These fields are NOT loaded into local working state. */ + unsigned int restarts_to_go; /* MCUs left in this restart interval */ + + /* Pointers to derived tables (these workspaces have image lifespan) */ + d_derived_tbl * derived_tbls[NUM_HUFF_TBLS]; + + d_derived_tbl * ac_derived_tbl; /* active table during an AC scan */ +} phuff_entropy_decoder; + +typedef phuff_entropy_decoder * phuff_entropy_ptr; + +/* Forward declarations */ +METHODDEF(boolean) decode_mcu_DC_first JPP((j_decompress_ptr cinfo, + JBLOCKROW *MCU_data)); +METHODDEF(boolean) decode_mcu_AC_first JPP((j_decompress_ptr cinfo, + JBLOCKROW *MCU_data)); +METHODDEF(boolean) decode_mcu_DC_refine JPP((j_decompress_ptr cinfo, + JBLOCKROW *MCU_data)); +METHODDEF(boolean) decode_mcu_AC_refine JPP((j_decompress_ptr cinfo, + JBLOCKROW *MCU_data)); + + +/* + * Initialize for a Huffman-compressed scan. + */ + +METHODDEF(void) +start_pass_phuff_decoder (j_decompress_ptr cinfo) +{ + phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + boolean is_DC_band, bad; + int ci, coefi, tbl; + int *coef_bit_ptr; + jpeg_component_info * compptr; + + is_DC_band = (cinfo->Ss == 0); + + /* Validate scan parameters */ + bad = FALSE; + if (is_DC_band) { + if (cinfo->Se != 0) + bad = TRUE; + } else { + /* need not check Ss/Se < 0 since they came from unsigned bytes */ + if (cinfo->Ss > cinfo->Se || cinfo->Se >= DCTSIZE2) + bad = TRUE; + /* AC scans may have only one component */ + if (cinfo->comps_in_scan != 1) + bad = TRUE; + } + if (cinfo->Ah != 0) { + /* Successive approximation refinement scan: must have Al = Ah-1. */ + if (cinfo->Al != cinfo->Ah-1) + bad = TRUE; + } + if (cinfo->Al > 13) /* need not check for < 0 */ + bad = TRUE; + /* Arguably the maximum Al value should be less than 13 for 8-bit precision, + * but the spec doesn't say so, and we try to be liberal about what we + * accept. Note: large Al values could result in out-of-range DC + * coefficients during early scans, leading to bizarre displays due to + * overflows in the IDCT math. But we won't crash. + */ + if (bad) + ERREXIT4(cinfo, JERR_BAD_PROGRESSION, + cinfo->Ss, cinfo->Se, cinfo->Ah, cinfo->Al); + /* Update progression status, and verify that scan order is legal. + * Note that inter-scan inconsistencies are treated as warnings + * not fatal errors ... not clear if this is right way to behave. + */ + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + int cindex = cinfo->cur_comp_info[ci]->component_index; + coef_bit_ptr = & cinfo->coef_bits[cindex][0]; + if (!is_DC_band && coef_bit_ptr[0] < 0) /* AC without prior DC scan */ + WARNMS2(cinfo, JWRN_BOGUS_PROGRESSION, cindex, 0); + for (coefi = cinfo->Ss; coefi <= cinfo->Se; coefi++) { + int expected = (coef_bit_ptr[coefi] < 0) ? 0 : coef_bit_ptr[coefi]; + if (cinfo->Ah != expected) + WARNMS2(cinfo, JWRN_BOGUS_PROGRESSION, cindex, coefi); + coef_bit_ptr[coefi] = cinfo->Al; + } + } + + /* Select MCU decoding routine */ + if (cinfo->Ah == 0) { + if (is_DC_band) + entropy->pub.decode_mcu = decode_mcu_DC_first; + else + entropy->pub.decode_mcu = decode_mcu_AC_first; + } else { + if (is_DC_band) + entropy->pub.decode_mcu = decode_mcu_DC_refine; + else + entropy->pub.decode_mcu = decode_mcu_AC_refine; + } + + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + /* Make sure requested tables are present, and compute derived tables. + * We may build same derived table more than once, but it's not expensive. + */ + if (is_DC_band) { + if (cinfo->Ah == 0) { /* DC refinement needs no table */ + tbl = compptr->dc_tbl_no; + jpeg_make_d_derived_tbl(cinfo, TRUE, tbl, + & entropy->derived_tbls[tbl]); + } + } else { + tbl = compptr->ac_tbl_no; + jpeg_make_d_derived_tbl(cinfo, FALSE, tbl, + & entropy->derived_tbls[tbl]); + /* remember the single active table */ + entropy->ac_derived_tbl = entropy->derived_tbls[tbl]; + } + /* Initialize DC predictions to 0 */ + entropy->saved.last_dc_val[ci] = 0; + } + + /* Initialize bitread state variables */ + entropy->bitstate.bits_left = 0; + entropy->bitstate.get_buffer = 0; /* unnecessary, but keeps Purify quiet */ + entropy->pub.insufficient_data = FALSE; + + /* Initialize private state variables */ + entropy->saved.EOBRUN = 0; + + /* Initialize restart counter */ + entropy->restarts_to_go = cinfo->restart_interval; +} + + +/* + * Figure F.12: extend sign bit. + * On some machines, a shift and add will be faster than a table lookup. + */ + +#ifdef AVOID_TABLES + +#define HUFF_EXTEND(x,s) ((x) < (1<<((s)-1)) ? (x) + (((-1)<<(s)) + 1) : (x)) + +#else + +#define HUFF_EXTEND(x,s) ((x) < extend_test[s] ? (x) + extend_offset[s] : (x)) + +static const int extend_test[16] = /* entry n is 2**(n-1) */ + { 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, + 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 }; + +static const int extend_offset[16] = /* entry n is (-1 << n) + 1 */ + { 0, ((-1)<<1) + 1, ((-1)<<2) + 1, ((-1)<<3) + 1, ((-1)<<4) + 1, + ((-1)<<5) + 1, ((-1)<<6) + 1, ((-1)<<7) + 1, ((-1)<<8) + 1, + ((-1)<<9) + 1, ((-1)<<10) + 1, ((-1)<<11) + 1, ((-1)<<12) + 1, + ((-1)<<13) + 1, ((-1)<<14) + 1, ((-1)<<15) + 1 }; + +#endif /* AVOID_TABLES */ + + +/* + * Check for a restart marker & resynchronize decoder. + * Returns FALSE if must suspend. + */ + +LOCAL(boolean) +process_restart (j_decompress_ptr cinfo) +{ + phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + int ci; + + /* Throw away any unused bits remaining in bit buffer; */ + /* include any full bytes in next_marker's count of discarded bytes */ + cinfo->marker->discarded_bytes += entropy->bitstate.bits_left / 8; + entropy->bitstate.bits_left = 0; + + /* Advance past the RSTn marker */ + if (! (*cinfo->marker->read_restart_marker) (cinfo)) + return FALSE; + + /* Re-initialize DC predictions to 0 */ + for (ci = 0; ci < cinfo->comps_in_scan; ci++) + entropy->saved.last_dc_val[ci] = 0; + /* Re-init EOB run count, too */ + entropy->saved.EOBRUN = 0; + + /* Reset restart counter */ + entropy->restarts_to_go = cinfo->restart_interval; + + /* Reset out-of-data flag, unless read_restart_marker left us smack up + * against a marker. In that case we will end up treating the next data + * segment as empty, and we can avoid producing bogus output pixels by + * leaving the flag set. + */ + if (cinfo->unread_marker == 0) + entropy->pub.insufficient_data = FALSE; + + return TRUE; +} + + +/* + * Huffman MCU decoding. + * Each of these routines decodes and returns one MCU's worth of + * Huffman-compressed coefficients. + * The coefficients are reordered from zigzag order into natural array order, + * but are not dequantized. + * + * The i'th block of the MCU is stored into the block pointed to by + * MCU_data[i]. WE ASSUME THIS AREA IS INITIALLY ZEROED BY THE CALLER. + * + * We return FALSE if data source requested suspension. In that case no + * changes have been made to permanent state. (Exception: some output + * coefficients may already have been assigned. This is harmless for + * spectral selection, since we'll just re-assign them on the next call. + * Successive approximation AC refinement has to be more careful, however.) + */ + +/* + * MCU decoding for DC initial scan (either spectral selection, + * or first pass of successive approximation). + */ + +METHODDEF(boolean) +decode_mcu_DC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) +{ + phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + int Al = cinfo->Al; + register int s, r; + int blkn, ci; + JBLOCKROW block; + BITREAD_STATE_VARS; + savable_state state; + d_derived_tbl * tbl; + jpeg_component_info * compptr; + + /* Process restart marker if needed; may have to suspend */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) + if (! process_restart(cinfo)) + return FALSE; + } + + /* If we've run out of data, just leave the MCU set to zeroes. + * This way, we return uniform gray for the remainder of the segment. + */ + if (! entropy->pub.insufficient_data) { + + /* Load up working state */ + BITREAD_LOAD_STATE(cinfo,entropy->bitstate); + ASSIGN_STATE(state, entropy->saved); + + /* Outer loop handles each block in the MCU */ + + for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { + block = MCU_data[blkn]; + ci = cinfo->MCU_membership[blkn]; + compptr = cinfo->cur_comp_info[ci]; + tbl = entropy->derived_tbls[compptr->dc_tbl_no]; + + /* Decode a single block's worth of coefficients */ + + /* Section F.2.2.1: decode the DC coefficient difference */ + HUFF_DECODE(s, br_state, tbl, return FALSE, label1); + if (s) { + CHECK_BIT_BUFFER(br_state, s, return FALSE); + r = GET_BITS(s); + s = HUFF_EXTEND(r, s); + } + + /* Convert DC difference to actual value, update last_dc_val */ + s += state.last_dc_val[ci]; + state.last_dc_val[ci] = s; + /* Scale and output the coefficient (assumes jpeg_natural_order[0]=0) */ + (*block)[0] = (JCOEF) (s << Al); + } + + /* Completed MCU, so update state */ + BITREAD_SAVE_STATE(cinfo,entropy->bitstate); + ASSIGN_STATE(entropy->saved, state); + } + + /* Account for restart interval (no-op if not using restarts) */ + entropy->restarts_to_go--; + + return TRUE; +} + + +/* + * MCU decoding for AC initial scan (either spectral selection, + * or first pass of successive approximation). + */ + +METHODDEF(boolean) +decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) +{ + phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + int Se = cinfo->Se; + int Al = cinfo->Al; + register int s, k, r; + unsigned int EOBRUN; + JBLOCKROW block; + BITREAD_STATE_VARS; + d_derived_tbl * tbl; + + /* Process restart marker if needed; may have to suspend */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) + if (! process_restart(cinfo)) + return FALSE; + } + + /* If we've run out of data, just leave the MCU set to zeroes. + * This way, we return uniform gray for the remainder of the segment. + */ + if (! entropy->pub.insufficient_data) { + + /* Load up working state. + * We can avoid loading/saving bitread state if in an EOB run. + */ + EOBRUN = entropy->saved.EOBRUN; /* only part of saved state we need */ + + /* There is always only one block per MCU */ + + if (EOBRUN > 0) /* if it's a band of zeroes... */ + EOBRUN--; /* ...process it now (we do nothing) */ + else { + BITREAD_LOAD_STATE(cinfo,entropy->bitstate); + block = MCU_data[0]; + tbl = entropy->ac_derived_tbl; + + for (k = cinfo->Ss; k <= Se; k++) { + HUFF_DECODE(s, br_state, tbl, return FALSE, label2); + r = s >> 4; + s &= 15; + if (s) { + k += r; + CHECK_BIT_BUFFER(br_state, s, return FALSE); + r = GET_BITS(s); + s = HUFF_EXTEND(r, s); + /* Scale and output coefficient in natural (dezigzagged) order */ + (*block)[jpeg_natural_order[k]] = (JCOEF) (s << Al); + } else { + if (r == 15) { /* ZRL */ + k += 15; /* skip 15 zeroes in band */ + } else { /* EOBr, run length is 2^r + appended bits */ + EOBRUN = 1 << r; + if (r) { /* EOBr, r > 0 */ + CHECK_BIT_BUFFER(br_state, r, return FALSE); + r = GET_BITS(r); + EOBRUN += r; + } + EOBRUN--; /* this band is processed at this moment */ + break; /* force end-of-band */ + } + } + } + + BITREAD_SAVE_STATE(cinfo,entropy->bitstate); + } + + /* Completed MCU, so update state */ + entropy->saved.EOBRUN = EOBRUN; /* only part of saved state we need */ + } + + /* Account for restart interval (no-op if not using restarts) */ + entropy->restarts_to_go--; + + return TRUE; +} + + +/* + * MCU decoding for DC successive approximation refinement scan. + * Note: we assume such scans can be multi-component, although the spec + * is not very clear on the point. + */ + +METHODDEF(boolean) +decode_mcu_DC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) +{ + phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + int p1 = 1 << cinfo->Al; /* 1 in the bit position being coded */ + int blkn; + JBLOCKROW block; + BITREAD_STATE_VARS; + + /* Process restart marker if needed; may have to suspend */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) + if (! process_restart(cinfo)) + return FALSE; + } + + /* Not worth the cycles to check insufficient_data here, + * since we will not change the data anyway if we read zeroes. + */ + + /* Load up working state */ + BITREAD_LOAD_STATE(cinfo,entropy->bitstate); + + /* Outer loop handles each block in the MCU */ + + for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { + block = MCU_data[blkn]; + + /* Encoded data is simply the next bit of the two's-complement DC value */ + CHECK_BIT_BUFFER(br_state, 1, return FALSE); + if (GET_BITS(1)) + (*block)[0] |= p1; + /* Note: since we use |=, repeating the assignment later is safe */ + } + + /* Completed MCU, so update state */ + BITREAD_SAVE_STATE(cinfo,entropy->bitstate); + + /* Account for restart interval (no-op if not using restarts) */ + entropy->restarts_to_go--; + + return TRUE; +} + + +/* + * MCU decoding for AC successive approximation refinement scan. + */ + +METHODDEF(boolean) +decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) +{ + phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + int Se = cinfo->Se; + int p1 = 1 << cinfo->Al; /* 1 in the bit position being coded */ + int m1 = (-1) << cinfo->Al; /* -1 in the bit position being coded */ + register int s, k, r; + unsigned int EOBRUN; + JBLOCKROW block; + JCOEFPTR thiscoef; + BITREAD_STATE_VARS; + d_derived_tbl * tbl; + int num_newnz; + int newnz_pos[DCTSIZE2]; + + /* Process restart marker if needed; may have to suspend */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) + if (! process_restart(cinfo)) + return FALSE; + } + + /* If we've run out of data, don't modify the MCU. + */ + if (! entropy->pub.insufficient_data) { + + /* Load up working state */ + BITREAD_LOAD_STATE(cinfo,entropy->bitstate); + EOBRUN = entropy->saved.EOBRUN; /* only part of saved state we need */ + + /* There is always only one block per MCU */ + block = MCU_data[0]; + tbl = entropy->ac_derived_tbl; + + /* If we are forced to suspend, we must undo the assignments to any newly + * nonzero coefficients in the block, because otherwise we'd get confused + * next time about which coefficients were already nonzero. + * But we need not undo addition of bits to already-nonzero coefficients; + * instead, we can test the current bit to see if we already did it. + */ + num_newnz = 0; + + /* initialize coefficient loop counter to start of band */ + k = cinfo->Ss; + + if (EOBRUN == 0) { + for (; k <= Se; k++) { + HUFF_DECODE(s, br_state, tbl, goto undoit, label3); + r = s >> 4; + s &= 15; + if (s) { + if (s != 1) /* size of new coef should always be 1 */ + WARNMS(cinfo, JWRN_HUFF_BAD_CODE); + CHECK_BIT_BUFFER(br_state, 1, goto undoit); + if (GET_BITS(1)) + s = p1; /* newly nonzero coef is positive */ + else + s = m1; /* newly nonzero coef is negative */ + } else { + if (r != 15) { + EOBRUN = 1 << r; /* EOBr, run length is 2^r + appended bits */ + if (r) { + CHECK_BIT_BUFFER(br_state, r, goto undoit); + r = GET_BITS(r); + EOBRUN += r; + } + break; /* rest of block is handled by EOB logic */ + } + /* note s = 0 for processing ZRL */ + } + /* Advance over already-nonzero coefs and r still-zero coefs, + * appending correction bits to the nonzeroes. A correction bit is 1 + * if the absolute value of the coefficient must be increased. + */ + do { + thiscoef = *block + jpeg_natural_order[k]; + if (*thiscoef != 0) { + CHECK_BIT_BUFFER(br_state, 1, goto undoit); + if (GET_BITS(1)) { + if ((*thiscoef & p1) == 0) { /* do nothing if already set it */ + if (*thiscoef >= 0) + *thiscoef += p1; + else + *thiscoef += m1; + } + } + } else { + if (--r < 0) + break; /* reached target zero coefficient */ + } + k++; + } while (k <= Se); + if (s) { + int pos = jpeg_natural_order[k]; + /* Output newly nonzero coefficient */ + (*block)[pos] = (JCOEF) s; + /* Remember its position in case we have to suspend */ + newnz_pos[num_newnz++] = pos; + } + } + } + + if (EOBRUN > 0) { + /* Scan any remaining coefficient positions after the end-of-band + * (the last newly nonzero coefficient, if any). Append a correction + * bit to each already-nonzero coefficient. A correction bit is 1 + * if the absolute value of the coefficient must be increased. + */ + for (; k <= Se; k++) { + thiscoef = *block + jpeg_natural_order[k]; + if (*thiscoef != 0) { + CHECK_BIT_BUFFER(br_state, 1, goto undoit); + if (GET_BITS(1)) { + if ((*thiscoef & p1) == 0) { /* do nothing if already changed it */ + if (*thiscoef >= 0) + *thiscoef += p1; + else + *thiscoef += m1; + } + } + } + } + /* Count one block completed in EOB run */ + EOBRUN--; + } + + /* Completed MCU, so update state */ + BITREAD_SAVE_STATE(cinfo,entropy->bitstate); + entropy->saved.EOBRUN = EOBRUN; /* only part of saved state we need */ + } + + /* Account for restart interval (no-op if not using restarts) */ + entropy->restarts_to_go--; + + return TRUE; + +undoit: + /* Re-zero any output coefficients that we made newly nonzero */ + while (num_newnz > 0) + (*block)[newnz_pos[--num_newnz]] = 0; + + return FALSE; +} + + +/* + * Module initialization routine for progressive Huffman entropy decoding. + */ + +GLOBAL(void) +jinit_phuff_decoder (j_decompress_ptr cinfo) +{ + phuff_entropy_ptr entropy; + int *coef_bit_ptr; + int ci, i; + + entropy = (phuff_entropy_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(phuff_entropy_decoder)); + cinfo->entropy = (struct jpeg_entropy_decoder *) entropy; + entropy->pub.start_pass = start_pass_phuff_decoder; + + /* Mark derived tables unallocated */ + for (i = 0; i < NUM_HUFF_TBLS; i++) { + entropy->derived_tbls[i] = NULL; + } + + /* Create progression status table */ + cinfo->coef_bits = (int (*)[DCTSIZE2]) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + cinfo->num_components*DCTSIZE2*SIZEOF(int)); + coef_bit_ptr = & cinfo->coef_bits[0][0]; + for (ci = 0; ci < cinfo->num_components; ci++) + for (i = 0; i < DCTSIZE2; i++) + *coef_bit_ptr++ = -1; +} + +#endif /* D_PROGRESSIVE_SUPPORTED */ diff --git a/mod/pub.mod/libjpeg.mod/jdpostct.c b/mod/pub.mod/libjpeg.mod/jdpostct.c new file mode 100644 index 0000000..571563d --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jdpostct.c @@ -0,0 +1,290 @@ +/* + * jdpostct.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains the decompression postprocessing controller. + * This controller manages the upsampling, color conversion, and color + * quantization/reduction steps; specifically, it controls the buffering + * between upsample/color conversion and color quantization/reduction. + * + * If no color quantization/reduction is required, then this module has no + * work to do, and it just hands off to the upsample/color conversion code. + * An integrated upsample/convert/quantize process would replace this module + * entirely. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* Private buffer controller object */ + +typedef struct { + struct jpeg_d_post_controller pub; /* public fields */ + + /* Color quantization source buffer: this holds output data from + * the upsample/color conversion step to be passed to the quantizer. + * For two-pass color quantization, we need a full-image buffer; + * for one-pass operation, a strip buffer is sufficient. + */ + jvirt_sarray_ptr whole_image; /* virtual array, or NULL if one-pass */ + JSAMPARRAY buffer; /* strip buffer, or current strip of virtual */ + JDIMENSION strip_height; /* buffer size in rows */ + /* for two-pass mode only: */ + JDIMENSION starting_row; /* row # of first row in current strip */ + JDIMENSION next_row; /* index of next row to fill/empty in strip */ +} my_post_controller; + +typedef my_post_controller * my_post_ptr; + + +/* Forward declarations */ +METHODDEF(void) post_process_1pass + JPP((j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, + JDIMENSION in_row_groups_avail, + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail)); +#ifdef QUANT_2PASS_SUPPORTED +METHODDEF(void) post_process_prepass + JPP((j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, + JDIMENSION in_row_groups_avail, + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail)); +METHODDEF(void) post_process_2pass + JPP((j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, + JDIMENSION in_row_groups_avail, + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail)); +#endif + + +/* + * Initialize for a processing pass. + */ + +METHODDEF(void) +start_pass_dpost (j_decompress_ptr cinfo, J_BUF_MODE pass_mode) +{ + my_post_ptr post = (my_post_ptr) cinfo->post; + + switch (pass_mode) { + case JBUF_PASS_THRU: + if (cinfo->quantize_colors) { + /* Single-pass processing with color quantization. */ + post->pub.post_process_data = post_process_1pass; + /* We could be doing buffered-image output before starting a 2-pass + * color quantization; in that case, jinit_d_post_controller did not + * allocate a strip buffer. Use the virtual-array buffer as workspace. + */ + if (post->buffer == NULL) { + post->buffer = (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, post->whole_image, + (JDIMENSION) 0, post->strip_height, TRUE); + } + } else { + /* For single-pass processing without color quantization, + * I have no work to do; just call the upsampler directly. + */ + post->pub.post_process_data = cinfo->upsample->upsample; + } + break; +#ifdef QUANT_2PASS_SUPPORTED + case JBUF_SAVE_AND_PASS: + /* First pass of 2-pass quantization */ + if (post->whole_image == NULL) + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + post->pub.post_process_data = post_process_prepass; + break; + case JBUF_CRANK_DEST: + /* Second pass of 2-pass quantization */ + if (post->whole_image == NULL) + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + post->pub.post_process_data = post_process_2pass; + break; +#endif /* QUANT_2PASS_SUPPORTED */ + default: + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + break; + } + post->starting_row = post->next_row = 0; +} + + +/* + * Process some data in the one-pass (strip buffer) case. + * This is used for color precision reduction as well as one-pass quantization. + */ + +METHODDEF(void) +post_process_1pass (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, + JDIMENSION in_row_groups_avail, + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail) +{ + my_post_ptr post = (my_post_ptr) cinfo->post; + JDIMENSION num_rows, max_rows; + + /* Fill the buffer, but not more than what we can dump out in one go. */ + /* Note we rely on the upsampler to detect bottom of image. */ + max_rows = out_rows_avail - *out_row_ctr; + if (max_rows > post->strip_height) + max_rows = post->strip_height; + num_rows = 0; + (*cinfo->upsample->upsample) (cinfo, + input_buf, in_row_group_ctr, in_row_groups_avail, + post->buffer, &num_rows, max_rows); + /* Quantize and emit data. */ + (*cinfo->cquantize->color_quantize) (cinfo, + post->buffer, output_buf + *out_row_ctr, (int) num_rows); + *out_row_ctr += num_rows; +} + + +#ifdef QUANT_2PASS_SUPPORTED + +/* + * Process some data in the first pass of 2-pass quantization. + */ + +METHODDEF(void) +post_process_prepass (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, + JDIMENSION in_row_groups_avail, + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail) +{ + my_post_ptr post = (my_post_ptr) cinfo->post; + JDIMENSION old_next_row, num_rows; + + /* Reposition virtual buffer if at start of strip. */ + if (post->next_row == 0) { + post->buffer = (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, post->whole_image, + post->starting_row, post->strip_height, TRUE); + } + + /* Upsample some data (up to a strip height's worth). */ + old_next_row = post->next_row; + (*cinfo->upsample->upsample) (cinfo, + input_buf, in_row_group_ctr, in_row_groups_avail, + post->buffer, &post->next_row, post->strip_height); + + /* Allow quantizer to scan new data. No data is emitted, */ + /* but we advance out_row_ctr so outer loop can tell when we're done. */ + if (post->next_row > old_next_row) { + num_rows = post->next_row - old_next_row; + (*cinfo->cquantize->color_quantize) (cinfo, post->buffer + old_next_row, + (JSAMPARRAY) NULL, (int) num_rows); + *out_row_ctr += num_rows; + } + + /* Advance if we filled the strip. */ + if (post->next_row >= post->strip_height) { + post->starting_row += post->strip_height; + post->next_row = 0; + } +} + + +/* + * Process some data in the second pass of 2-pass quantization. + */ + +METHODDEF(void) +post_process_2pass (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, + JDIMENSION in_row_groups_avail, + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail) +{ + my_post_ptr post = (my_post_ptr) cinfo->post; + JDIMENSION num_rows, max_rows; + + /* Reposition virtual buffer if at start of strip. */ + if (post->next_row == 0) { + post->buffer = (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, post->whole_image, + post->starting_row, post->strip_height, FALSE); + } + + /* Determine number of rows to emit. */ + num_rows = post->strip_height - post->next_row; /* available in strip */ + max_rows = out_rows_avail - *out_row_ctr; /* available in output area */ + if (num_rows > max_rows) + num_rows = max_rows; + /* We have to check bottom of image here, can't depend on upsampler. */ + max_rows = cinfo->output_height - post->starting_row; + if (num_rows > max_rows) + num_rows = max_rows; + + /* Quantize and emit data. */ + (*cinfo->cquantize->color_quantize) (cinfo, + post->buffer + post->next_row, output_buf + *out_row_ctr, + (int) num_rows); + *out_row_ctr += num_rows; + + /* Advance if we filled the strip. */ + post->next_row += num_rows; + if (post->next_row >= post->strip_height) { + post->starting_row += post->strip_height; + post->next_row = 0; + } +} + +#endif /* QUANT_2PASS_SUPPORTED */ + + +/* + * Initialize postprocessing controller. + */ + +GLOBAL(void) +jinit_d_post_controller (j_decompress_ptr cinfo, boolean need_full_buffer) +{ + my_post_ptr post; + + post = (my_post_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_post_controller)); + cinfo->post = (struct jpeg_d_post_controller *) post; + post->pub.start_pass = start_pass_dpost; + post->whole_image = NULL; /* flag for no virtual arrays */ + post->buffer = NULL; /* flag for no strip buffer */ + + /* Create the quantization buffer, if needed */ + if (cinfo->quantize_colors) { + /* The buffer strip height is max_v_samp_factor, which is typically + * an efficient number of rows for upsampling to return. + * (In the presence of output rescaling, we might want to be smarter?) + */ + post->strip_height = (JDIMENSION) cinfo->max_v_samp_factor; + if (need_full_buffer) { + /* Two-pass color quantization: need full-image storage. */ + /* We round up the number of rows to a multiple of the strip height. */ +#ifdef QUANT_2PASS_SUPPORTED + post->whole_image = (*cinfo->mem->request_virt_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE, + cinfo->output_width * cinfo->out_color_components, + (JDIMENSION) jround_up((long) cinfo->output_height, + (long) post->strip_height), + post->strip_height); +#else + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); +#endif /* QUANT_2PASS_SUPPORTED */ + } else { + /* One-pass color quantization: just make a strip buffer. */ + post->buffer = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + cinfo->output_width * cinfo->out_color_components, + post->strip_height); + } + } +} diff --git a/mod/pub.mod/libjpeg.mod/jdsample.c b/mod/pub.mod/libjpeg.mod/jdsample.c new file mode 100644 index 0000000..80ffefb --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jdsample.c @@ -0,0 +1,478 @@ +/* + * jdsample.c + * + * Copyright (C) 1991-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains upsampling routines. + * + * Upsampling input data is counted in "row groups". A row group + * is defined to be (v_samp_factor * DCT_scaled_size / min_DCT_scaled_size) + * sample rows of each component. Upsampling will normally produce + * max_v_samp_factor pixel rows from each row group (but this could vary + * if the upsampler is applying a scale factor of its own). + * + * An excellent reference for image resampling is + * Digital Image Warping, George Wolberg, 1990. + * Pub. by IEEE Computer Society Press, Los Alamitos, CA. ISBN 0-8186-8944-7. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* Pointer to routine to upsample a single component */ +typedef JMETHOD(void, upsample1_ptr, + (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)); + +/* Private subobject */ + +typedef struct { + struct jpeg_upsampler pub; /* public fields */ + + /* Color conversion buffer. When using separate upsampling and color + * conversion steps, this buffer holds one upsampled row group until it + * has been color converted and output. + * Note: we do not allocate any storage for component(s) which are full-size, + * ie do not need rescaling. The corresponding entry of color_buf[] is + * simply set to point to the input data array, thereby avoiding copying. + */ + JSAMPARRAY color_buf[MAX_COMPONENTS]; + + /* Per-component upsampling method pointers */ + upsample1_ptr methods[MAX_COMPONENTS]; + + int next_row_out; /* counts rows emitted from color_buf */ + JDIMENSION rows_to_go; /* counts rows remaining in image */ + + /* Height of an input row group for each component. */ + int rowgroup_height[MAX_COMPONENTS]; + + /* These arrays save pixel expansion factors so that int_expand need not + * recompute them each time. They are unused for other upsampling methods. + */ + UINT8 h_expand[MAX_COMPONENTS]; + UINT8 v_expand[MAX_COMPONENTS]; +} my_upsampler; + +typedef my_upsampler * my_upsample_ptr; + + +/* + * Initialize for an upsampling pass. + */ + +METHODDEF(void) +start_pass_upsample (j_decompress_ptr cinfo) +{ + my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; + + /* Mark the conversion buffer empty */ + upsample->next_row_out = cinfo->max_v_samp_factor; + /* Initialize total-height counter for detecting bottom of image */ + upsample->rows_to_go = cinfo->output_height; +} + + +/* + * Control routine to do upsampling (and color conversion). + * + * In this version we upsample each component independently. + * We upsample one row group into the conversion buffer, then apply + * color conversion a row at a time. + */ + +METHODDEF(void) +sep_upsample (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, + JDIMENSION in_row_groups_avail, + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail) +{ + my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; + int ci; + jpeg_component_info * compptr; + JDIMENSION num_rows; + + /* Fill the conversion buffer, if it's empty */ + if (upsample->next_row_out >= cinfo->max_v_samp_factor) { + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + /* Invoke per-component upsample method. Notice we pass a POINTER + * to color_buf[ci], so that fullsize_upsample can change it. + */ + (*upsample->methods[ci]) (cinfo, compptr, + input_buf[ci] + (*in_row_group_ctr * upsample->rowgroup_height[ci]), + upsample->color_buf + ci); + } + upsample->next_row_out = 0; + } + + /* Color-convert and emit rows */ + + /* How many we have in the buffer: */ + num_rows = (JDIMENSION) (cinfo->max_v_samp_factor - upsample->next_row_out); + /* Not more than the distance to the end of the image. Need this test + * in case the image height is not a multiple of max_v_samp_factor: + */ + if (num_rows > upsample->rows_to_go) + num_rows = upsample->rows_to_go; + /* And not more than what the client can accept: */ + out_rows_avail -= *out_row_ctr; + if (num_rows > out_rows_avail) + num_rows = out_rows_avail; + + (*cinfo->cconvert->color_convert) (cinfo, upsample->color_buf, + (JDIMENSION) upsample->next_row_out, + output_buf + *out_row_ctr, + (int) num_rows); + + /* Adjust counts */ + *out_row_ctr += num_rows; + upsample->rows_to_go -= num_rows; + upsample->next_row_out += num_rows; + /* When the buffer is emptied, declare this input row group consumed */ + if (upsample->next_row_out >= cinfo->max_v_samp_factor) + (*in_row_group_ctr)++; +} + + +/* + * These are the routines invoked by sep_upsample to upsample pixel values + * of a single component. One row group is processed per call. + */ + + +/* + * For full-size components, we just make color_buf[ci] point at the + * input buffer, and thus avoid copying any data. Note that this is + * safe only because sep_upsample doesn't declare the input row group + * "consumed" until we are done color converting and emitting it. + */ + +METHODDEF(void) +fullsize_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) +{ + *output_data_ptr = input_data; +} + + +/* + * This is a no-op version used for "uninteresting" components. + * These components will not be referenced by color conversion. + */ + +METHODDEF(void) +noop_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) +{ + *output_data_ptr = NULL; /* safety check */ +} + + +/* + * This version handles any integral sampling ratios. + * This is not used for typical JPEG files, so it need not be fast. + * Nor, for that matter, is it particularly accurate: the algorithm is + * simple replication of the input pixel onto the corresponding output + * pixels. The hi-falutin sampling literature refers to this as a + * "box filter". A box filter tends to introduce visible artifacts, + * so if you are actually going to use 3:1 or 4:1 sampling ratios + * you would be well advised to improve this code. + */ + +METHODDEF(void) +int_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) +{ + my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; + JSAMPARRAY output_data = *output_data_ptr; + register JSAMPROW inptr, outptr; + register JSAMPLE invalue; + register int h; + JSAMPROW outend; + int h_expand, v_expand; + int inrow, outrow; + + h_expand = upsample->h_expand[compptr->component_index]; + v_expand = upsample->v_expand[compptr->component_index]; + + inrow = outrow = 0; + while (outrow < cinfo->max_v_samp_factor) { + /* Generate one output row with proper horizontal expansion */ + inptr = input_data[inrow]; + outptr = output_data[outrow]; + outend = outptr + cinfo->output_width; + while (outptr < outend) { + invalue = *inptr++; /* don't need GETJSAMPLE() here */ + for (h = h_expand; h > 0; h--) { + *outptr++ = invalue; + } + } + /* Generate any additional output rows by duplicating the first one */ + if (v_expand > 1) { + jcopy_sample_rows(output_data, outrow, output_data, outrow+1, + v_expand-1, cinfo->output_width); + } + inrow++; + outrow += v_expand; + } +} + + +/* + * Fast processing for the common case of 2:1 horizontal and 1:1 vertical. + * It's still a box filter. + */ + +METHODDEF(void) +h2v1_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) +{ + JSAMPARRAY output_data = *output_data_ptr; + register JSAMPROW inptr, outptr; + register JSAMPLE invalue; + JSAMPROW outend; + int inrow; + + for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) { + inptr = input_data[inrow]; + outptr = output_data[inrow]; + outend = outptr + cinfo->output_width; + while (outptr < outend) { + invalue = *inptr++; /* don't need GETJSAMPLE() here */ + *outptr++ = invalue; + *outptr++ = invalue; + } + } +} + + +/* + * Fast processing for the common case of 2:1 horizontal and 2:1 vertical. + * It's still a box filter. + */ + +METHODDEF(void) +h2v2_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) +{ + JSAMPARRAY output_data = *output_data_ptr; + register JSAMPROW inptr, outptr; + register JSAMPLE invalue; + JSAMPROW outend; + int inrow, outrow; + + inrow = outrow = 0; + while (outrow < cinfo->max_v_samp_factor) { + inptr = input_data[inrow]; + outptr = output_data[outrow]; + outend = outptr + cinfo->output_width; + while (outptr < outend) { + invalue = *inptr++; /* don't need GETJSAMPLE() here */ + *outptr++ = invalue; + *outptr++ = invalue; + } + jcopy_sample_rows(output_data, outrow, output_data, outrow+1, + 1, cinfo->output_width); + inrow++; + outrow += 2; + } +} + + +/* + * Fancy processing for the common case of 2:1 horizontal and 1:1 vertical. + * + * The upsampling algorithm is linear interpolation between pixel centers, + * also known as a "triangle filter". This is a good compromise between + * speed and visual quality. The centers of the output pixels are 1/4 and 3/4 + * of the way between input pixel centers. + * + * A note about the "bias" calculations: when rounding fractional values to + * integer, we do not want to always round 0.5 up to the next integer. + * If we did that, we'd introduce a noticeable bias towards larger values. + * Instead, this code is arranged so that 0.5 will be rounded up or down at + * alternate pixel locations (a simple ordered dither pattern). + */ + +METHODDEF(void) +h2v1_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) +{ + JSAMPARRAY output_data = *output_data_ptr; + register JSAMPROW inptr, outptr; + register int invalue; + register JDIMENSION colctr; + int inrow; + + for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) { + inptr = input_data[inrow]; + outptr = output_data[inrow]; + /* Special case for first column */ + invalue = GETJSAMPLE(*inptr++); + *outptr++ = (JSAMPLE) invalue; + *outptr++ = (JSAMPLE) ((invalue * 3 + GETJSAMPLE(*inptr) + 2) >> 2); + + for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) { + /* General case: 3/4 * nearer pixel + 1/4 * further pixel */ + invalue = GETJSAMPLE(*inptr++) * 3; + *outptr++ = (JSAMPLE) ((invalue + GETJSAMPLE(inptr[-2]) + 1) >> 2); + *outptr++ = (JSAMPLE) ((invalue + GETJSAMPLE(*inptr) + 2) >> 2); + } + + /* Special case for last column */ + invalue = GETJSAMPLE(*inptr); + *outptr++ = (JSAMPLE) ((invalue * 3 + GETJSAMPLE(inptr[-1]) + 1) >> 2); + *outptr++ = (JSAMPLE) invalue; + } +} + + +/* + * Fancy processing for the common case of 2:1 horizontal and 2:1 vertical. + * Again a triangle filter; see comments for h2v1 case, above. + * + * It is OK for us to reference the adjacent input rows because we demanded + * context from the main buffer controller (see initialization code). + */ + +METHODDEF(void) +h2v2_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) +{ + JSAMPARRAY output_data = *output_data_ptr; + register JSAMPROW inptr0, inptr1, outptr; +#if BITS_IN_JSAMPLE == 8 + register int thiscolsum, lastcolsum, nextcolsum; +#else + register INT32 thiscolsum, lastcolsum, nextcolsum; +#endif + register JDIMENSION colctr; + int inrow, outrow, v; + + inrow = outrow = 0; + while (outrow < cinfo->max_v_samp_factor) { + for (v = 0; v < 2; v++) { + /* inptr0 points to nearest input row, inptr1 points to next nearest */ + inptr0 = input_data[inrow]; + if (v == 0) /* next nearest is row above */ + inptr1 = input_data[inrow-1]; + else /* next nearest is row below */ + inptr1 = input_data[inrow+1]; + outptr = output_data[outrow++]; + + /* Special case for first column */ + thiscolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++); + nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++); + *outptr++ = (JSAMPLE) ((thiscolsum * 4 + 8) >> 4); + *outptr++ = (JSAMPLE) ((thiscolsum * 3 + nextcolsum + 7) >> 4); + lastcolsum = thiscolsum; thiscolsum = nextcolsum; + + for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) { + /* General case: 3/4 * nearer pixel + 1/4 * further pixel in each */ + /* dimension, thus 9/16, 3/16, 3/16, 1/16 overall */ + nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++); + *outptr++ = (JSAMPLE) ((thiscolsum * 3 + lastcolsum + 8) >> 4); + *outptr++ = (JSAMPLE) ((thiscolsum * 3 + nextcolsum + 7) >> 4); + lastcolsum = thiscolsum; thiscolsum = nextcolsum; + } + + /* Special case for last column */ + *outptr++ = (JSAMPLE) ((thiscolsum * 3 + lastcolsum + 8) >> 4); + *outptr++ = (JSAMPLE) ((thiscolsum * 4 + 7) >> 4); + } + inrow++; + } +} + + +/* + * Module initialization routine for upsampling. + */ + +GLOBAL(void) +jinit_upsampler (j_decompress_ptr cinfo) +{ + my_upsample_ptr upsample; + int ci; + jpeg_component_info * compptr; + boolean need_buffer, do_fancy; + int h_in_group, v_in_group, h_out_group, v_out_group; + + upsample = (my_upsample_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_upsampler)); + cinfo->upsample = (struct jpeg_upsampler *) upsample; + upsample->pub.start_pass = start_pass_upsample; + upsample->pub.upsample = sep_upsample; + upsample->pub.need_context_rows = FALSE; /* until we find out differently */ + + if (cinfo->CCIR601_sampling) /* this isn't supported */ + ERREXIT(cinfo, JERR_CCIR601_NOTIMPL); + + /* jdmainct.c doesn't support context rows when min_DCT_scaled_size = 1, + * so don't ask for it. + */ + do_fancy = cinfo->do_fancy_upsampling && cinfo->min_DCT_scaled_size > 1; + + /* Verify we can handle the sampling factors, select per-component methods, + * and create storage as needed. + */ + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + /* Compute size of an "input group" after IDCT scaling. This many samples + * are to be converted to max_h_samp_factor * max_v_samp_factor pixels. + */ + h_in_group = (compptr->h_samp_factor * compptr->DCT_scaled_size) / + cinfo->min_DCT_scaled_size; + v_in_group = (compptr->v_samp_factor * compptr->DCT_scaled_size) / + cinfo->min_DCT_scaled_size; + h_out_group = cinfo->max_h_samp_factor; + v_out_group = cinfo->max_v_samp_factor; + upsample->rowgroup_height[ci] = v_in_group; /* save for use later */ + need_buffer = TRUE; + if (! compptr->component_needed) { + /* Don't bother to upsample an uninteresting component. */ + upsample->methods[ci] = noop_upsample; + need_buffer = FALSE; + } else if (h_in_group == h_out_group && v_in_group == v_out_group) { + /* Fullsize components can be processed without any work. */ + upsample->methods[ci] = fullsize_upsample; + need_buffer = FALSE; + } else if (h_in_group * 2 == h_out_group && + v_in_group == v_out_group) { + /* Special cases for 2h1v upsampling */ + if (do_fancy && compptr->downsampled_width > 2) + upsample->methods[ci] = h2v1_fancy_upsample; + else + upsample->methods[ci] = h2v1_upsample; + } else if (h_in_group * 2 == h_out_group && + v_in_group * 2 == v_out_group) { + /* Special cases for 2h2v upsampling */ + if (do_fancy && compptr->downsampled_width > 2) { + upsample->methods[ci] = h2v2_fancy_upsample; + upsample->pub.need_context_rows = TRUE; + } else + upsample->methods[ci] = h2v2_upsample; + } else if ((h_out_group % h_in_group) == 0 && + (v_out_group % v_in_group) == 0) { + /* Generic integral-factors upsampling method */ + upsample->methods[ci] = int_upsample; + upsample->h_expand[ci] = (UINT8) (h_out_group / h_in_group); + upsample->v_expand[ci] = (UINT8) (v_out_group / v_in_group); + } else + ERREXIT(cinfo, JERR_FRACT_SAMPLE_NOTIMPL); + if (need_buffer) { + upsample->color_buf[ci] = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + (JDIMENSION) jround_up((long) cinfo->output_width, + (long) cinfo->max_h_samp_factor), + (JDIMENSION) cinfo->max_v_samp_factor); + } + } +} diff --git a/mod/pub.mod/libjpeg.mod/jdtrans.c b/mod/pub.mod/libjpeg.mod/jdtrans.c new file mode 100644 index 0000000..6c0ab71 --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jdtrans.c @@ -0,0 +1,143 @@ +/* + * jdtrans.c + * + * Copyright (C) 1995-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains library routines for transcoding decompression, + * that is, reading raw DCT coefficient arrays from an input JPEG file. + * The routines in jdapimin.c will also be needed by a transcoder. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* Forward declarations */ +LOCAL(void) transdecode_master_selection JPP((j_decompress_ptr cinfo)); + + +/* + * Read the coefficient arrays from a JPEG file. + * jpeg_read_header must be completed before calling this. + * + * The entire image is read into a set of virtual coefficient-block arrays, + * one per component. The return value is a pointer to the array of + * virtual-array descriptors. These can be manipulated directly via the + * JPEG memory manager, or handed off to jpeg_write_coefficients(). + * To release the memory occupied by the virtual arrays, call + * jpeg_finish_decompress() when done with the data. + * + * An alternative usage is to simply obtain access to the coefficient arrays + * during a buffered-image-mode decompression operation. This is allowed + * after any jpeg_finish_output() call. The arrays can be accessed until + * jpeg_finish_decompress() is called. (Note that any call to the library + * may reposition the arrays, so don't rely on access_virt_barray() results + * to stay valid across library calls.) + * + * Returns NULL if suspended. This case need be checked only if + * a suspending data source is used. + */ + +GLOBAL(jvirt_barray_ptr *) +jpeg_read_coefficients (j_decompress_ptr cinfo) +{ + if (cinfo->global_state == DSTATE_READY) { + /* First call: initialize active modules */ + transdecode_master_selection(cinfo); + cinfo->global_state = DSTATE_RDCOEFS; + } + if (cinfo->global_state == DSTATE_RDCOEFS) { + /* Absorb whole file into the coef buffer */ + for (;;) { + int retcode; + /* Call progress monitor hook if present */ + if (cinfo->progress != NULL) + (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); + /* Absorb some more input */ + retcode = (*cinfo->inputctl->consume_input) (cinfo); + if (retcode == JPEG_SUSPENDED) + return NULL; + if (retcode == JPEG_REACHED_EOI) + break; + /* Advance progress counter if appropriate */ + if (cinfo->progress != NULL && + (retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) { + if (++cinfo->progress->pass_counter >= cinfo->progress->pass_limit) { + /* startup underestimated number of scans; ratchet up one scan */ + cinfo->progress->pass_limit += (long) cinfo->total_iMCU_rows; + } + } + } + /* Set state so that jpeg_finish_decompress does the right thing */ + cinfo->global_state = DSTATE_STOPPING; + } + /* At this point we should be in state DSTATE_STOPPING if being used + * standalone, or in state DSTATE_BUFIMAGE if being invoked to get access + * to the coefficients during a full buffered-image-mode decompression. + */ + if ((cinfo->global_state == DSTATE_STOPPING || + cinfo->global_state == DSTATE_BUFIMAGE) && cinfo->buffered_image) { + return cinfo->coef->coef_arrays; + } + /* Oops, improper usage */ + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + return NULL; /* keep compiler happy */ +} + + +/* + * Master selection of decompression modules for transcoding. + * This substitutes for jdmaster.c's initialization of the full decompressor. + */ + +LOCAL(void) +transdecode_master_selection (j_decompress_ptr cinfo) +{ + /* This is effectively a buffered-image operation. */ + cinfo->buffered_image = TRUE; + + /* Entropy decoding: either Huffman or arithmetic coding. */ + if (cinfo->arith_code) { + ERREXIT(cinfo, JERR_ARITH_NOTIMPL); + } else { + if (cinfo->progressive_mode) { +#ifdef D_PROGRESSIVE_SUPPORTED + jinit_phuff_decoder(cinfo); +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } else + jinit_huff_decoder(cinfo); + } + + /* Always get a full-image coefficient buffer. */ + jinit_d_coef_controller(cinfo, TRUE); + + /* We can now tell the memory manager to allocate virtual arrays. */ + (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo); + + /* Initialize input side of decompressor to consume first scan. */ + (*cinfo->inputctl->start_input_pass) (cinfo); + + /* Initialize progress monitoring. */ + if (cinfo->progress != NULL) { + int nscans; + /* Estimate number of scans to set pass_limit. */ + if (cinfo->progressive_mode) { + /* Arbitrarily estimate 2 interleaved DC scans + 3 AC scans/component. */ + nscans = 2 + 3 * cinfo->num_components; + } else if (cinfo->inputctl->has_multiple_scans) { + /* For a nonprogressive multiscan file, estimate 1 scan per component. */ + nscans = cinfo->num_components; + } else { + nscans = 1; + } + cinfo->progress->pass_counter = 0L; + cinfo->progress->pass_limit = (long) cinfo->total_iMCU_rows * nscans; + cinfo->progress->completed_passes = 0; + cinfo->progress->total_passes = 1; + } +} diff --git a/mod/pub.mod/libjpeg.mod/jerror.c b/mod/pub.mod/libjpeg.mod/jerror.c new file mode 100644 index 0000000..286f597 --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jerror.c @@ -0,0 +1,254 @@ +/* + * jerror.c + * + * Copyright (C) 1991-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains simple error-reporting and trace-message routines. + * These are suitable for Unix-like systems and others where writing to + * stderr is the right thing to do. Many applications will want to replace + * some or all of these routines. + * + * If you define USE_WINDOWS_MESSAGEBOX in jconfig.h or in the makefile, + * you get a Windows-specific hack to display error messages in a dialog box. + * It ain't much, but it beats dropping error messages into the bit bucket, + * which is what happens to output to stderr under most Windows C compilers. + * + * These routines are used by both the compression and decompression code. + */ + +/* this is not a core library module, so it doesn't define JPEG_INTERNALS */ +#include "jinclude.h" +#include "jpeglib.h" +#include "jversion.h" +#include "jerror.h" + +#include <stdlib.h> //for exit. + +#ifdef USE_WINDOWS_MESSAGEBOX +#include <windows.h> +#endif + +#ifndef EXIT_FAILURE /* define exit() codes if not provided */ +#define EXIT_FAILURE 1 +#endif + + +/* + * Create the message string table. + * We do this from the master message list in jerror.h by re-reading + * jerror.h with a suitable definition for macro JMESSAGE. + * The message table is made an external symbol just in case any applications + * want to refer to it directly. + */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jpeg_std_message_table jMsgTable +#endif + +#define JMESSAGE(code,string) string , + +const char * const jpeg_std_message_table[] = { +#include "jerror.h" + NULL +}; + + +/* + * Error exit handler: must not return to caller. + * + * Applications may override this if they want to get control back after + * an error. Typically one would longjmp somewhere instead of exiting. + * The setjmp buffer can be made a private field within an expanded error + * handler object. Note that the info needed to generate an error message + * is stored in the error object, so you can generate the message now or + * later, at your convenience. + * You should make sure that the JPEG object is cleaned up (with jpeg_abort + * or jpeg_destroy) at some point. + */ + +METHODDEF(void) +error_exit (j_common_ptr cinfo) +{ + /* Always display the message */ + (*cinfo->err->output_message) (cinfo); + + /* Let the memory manager delete any temp files before we die */ + jpeg_destroy(cinfo); + + exit(EXIT_FAILURE); +} + + +/* + * Actual output of an error or trace message. + * Applications may override this method to send JPEG messages somewhere + * other than stderr. + * + * On Windows, printing to stderr is generally completely useless, + * so we provide optional code to produce an error-dialog popup. + * Most Windows applications will still prefer to override this routine, + * but if they don't, it'll do something at least marginally useful. + * + * NOTE: to use the library in an environment that doesn't support the + * C stdio library, you may have to delete the call to fprintf() entirely, + * not just not use this routine. + */ + +METHODDEF(void) +output_message (j_common_ptr cinfo) +{ + char buffer[JMSG_LENGTH_MAX]; + + /* Create the message */ + (*cinfo->err->format_message) (cinfo, buffer); + +#ifdef USE_WINDOWS_MESSAGEBOX + /* Display it in a message dialog box */ + MessageBox(GetActiveWindow(), buffer, "JPEG Library Error", + MB_OK | MB_ICONERROR); +#else + /* Send it to stderr, adding a newline */ + fprintf(stderr, "%s\n", buffer); +#endif +} + + +/* + * Decide whether to emit a trace or warning message. + * msg_level is one of: + * -1: recoverable corrupt-data warning, may want to abort. + * 0: important advisory messages (always display to user). + * 1: first level of tracing detail. + * 2,3,...: successively more detailed tracing messages. + * An application might override this method if it wanted to abort on warnings + * or change the policy about which messages to display. + */ + +METHODDEF(void) +emit_message (j_common_ptr cinfo, int msg_level) +{ + struct jpeg_error_mgr * err = cinfo->err; + + if (msg_level < 0) { + /* It's a warning message. Since corrupt files may generate many warnings, + * the policy implemented here is to show only the first warning, + * unless trace_level >= 3. + */ + if (err->num_warnings == 0 || err->trace_level >= 3) + (*err->output_message) (cinfo); + /* Always count warnings in num_warnings. */ + err->num_warnings++; + } else { + /* It's a trace message. Show it if trace_level >= msg_level. */ + if (err->trace_level >= msg_level) + (*err->output_message) (cinfo); + } +} + + +/* + * Format a message string for the most recent JPEG error or message. + * The message is stored into buffer, which should be at least JMSG_LENGTH_MAX + * characters. Note that no '\n' character is added to the string. + * Few applications should need to override this method. + */ + +METHODDEF(void) +format_message (j_common_ptr cinfo, char * buffer) +{ + struct jpeg_error_mgr * err = cinfo->err; + int msg_code = err->msg_code; + const char * msgtext = NULL; + const char * msgptr; + char ch; + boolean isstring; + + /* Look up message string in proper table */ + if (msg_code > 0 && msg_code <= err->last_jpeg_message) { + msgtext = err->jpeg_message_table[msg_code]; + } else if (err->addon_message_table != NULL && + msg_code >= err->first_addon_message && + msg_code <= err->last_addon_message) { + msgtext = err->addon_message_table[msg_code - err->first_addon_message]; + } + + /* Defend against bogus message number */ + if (msgtext == NULL) { + err->msg_parm.i[0] = msg_code; + msgtext = err->jpeg_message_table[0]; + } + + /* Check for string parameter, as indicated by %s in the message text */ + isstring = FALSE; + msgptr = msgtext; + while ((ch = *msgptr++) != '\0') { + if (ch == '%') { + if (*msgptr == 's') isstring = TRUE; + break; + } + } + + /* Format the message into the passed buffer */ + if (isstring) + sprintf(buffer, msgtext, err->msg_parm.s); + else + sprintf(buffer, msgtext, + err->msg_parm.i[0], err->msg_parm.i[1], + err->msg_parm.i[2], err->msg_parm.i[3], + err->msg_parm.i[4], err->msg_parm.i[5], + err->msg_parm.i[6], err->msg_parm.i[7]); +} + + +/* + * Reset error state variables at start of a new image. + * This is called during compression startup to reset trace/error + * processing to default state, without losing any application-specific + * method pointers. An application might possibly want to override + * this method if it has additional error processing state. + */ + +METHODDEF(void) +reset_error_mgr (j_common_ptr cinfo) +{ + cinfo->err->num_warnings = 0; + /* trace_level is not reset since it is an application-supplied parameter */ + cinfo->err->msg_code = 0; /* may be useful as a flag for "no error" */ +} + + +/* + * Fill in the standard error-handling methods in a jpeg_error_mgr object. + * Typical call is: + * struct jpeg_compress_struct cinfo; + * struct jpeg_error_mgr err; + * + * cinfo.err = jpeg_std_error(&err); + * after which the application may override some of the methods. + */ + +GLOBAL(struct jpeg_error_mgr *) +jpeg_std_error (struct jpeg_error_mgr * err) +{ + err->error_exit = error_exit; + err->emit_message = emit_message; + err->output_message = output_message; + err->format_message = format_message; + err->reset_error_mgr = reset_error_mgr; + + err->trace_level = 0; /* default = no tracing */ + err->num_warnings = 0; /* no warnings emitted yet */ + err->msg_code = 0; /* may be useful as a flag for "no error" */ + + /* Initialize message table pointers */ + err->jpeg_message_table = jpeg_std_message_table; + err->last_jpeg_message = (int) JMSG_LASTMSGCODE - 1; + + err->addon_message_table = NULL; + err->first_addon_message = 0; /* for safety */ + err->last_addon_message = 0; + + return err; +} diff --git a/mod/pub.mod/libjpeg.mod/jerror.h b/mod/pub.mod/libjpeg.mod/jerror.h new file mode 100644 index 0000000..fc2fffe --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jerror.h @@ -0,0 +1,291 @@ +/* + * jerror.h + * + * Copyright (C) 1994-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file defines the error and message codes for the JPEG library. + * Edit this file to add new codes, or to translate the message strings to + * some other language. + * A set of error-reporting macros are defined too. Some applications using + * the JPEG library may wish to include this file to get the error codes + * and/or the macros. + */ + +/* + * To define the enum list of message codes, include this file without + * defining macro JMESSAGE. To create a message string table, include it + * again with a suitable JMESSAGE definition (see jerror.c for an example). + */ +#ifndef JMESSAGE +#ifndef JERROR_H +/* First time through, define the enum list */ +#define JMAKE_ENUM_LIST +#else +/* Repeated inclusions of this file are no-ops unless JMESSAGE is defined */ +#define JMESSAGE(code,string) +#endif /* JERROR_H */ +#endif /* JMESSAGE */ + +#ifdef JMAKE_ENUM_LIST + +typedef enum { + +#define JMESSAGE(code,string) code , + +#endif /* JMAKE_ENUM_LIST */ + +JMESSAGE(JMSG_NOMESSAGE, "Bogus message code %d") /* Must be first entry! */ + +/* For maintenance convenience, list is alphabetical by message code name */ +JMESSAGE(JERR_ARITH_NOTIMPL, + "Sorry, there are legal restrictions on arithmetic coding") +JMESSAGE(JERR_BAD_ALIGN_TYPE, "ALIGN_TYPE is wrong, please fix") +JMESSAGE(JERR_BAD_ALLOC_CHUNK, "MAX_ALLOC_CHUNK is wrong, please fix") +JMESSAGE(JERR_BAD_BUFFER_MODE, "Bogus buffer control mode") +JMESSAGE(JERR_BAD_COMPONENT_ID, "Invalid component ID %d in SOS") +JMESSAGE(JERR_BAD_DCT_COEF, "DCT coefficient out of range") +JMESSAGE(JERR_BAD_DCTSIZE, "IDCT output block size %d not supported") +JMESSAGE(JERR_BAD_HUFF_TABLE, "Bogus Huffman table definition") +JMESSAGE(JERR_BAD_IN_COLORSPACE, "Bogus input colorspace") +JMESSAGE(JERR_BAD_J_COLORSPACE, "Bogus JPEG colorspace") +JMESSAGE(JERR_BAD_LENGTH, "Bogus marker length") +JMESSAGE(JERR_BAD_LIB_VERSION, + "Wrong JPEG library version: library is %d, caller expects %d") +JMESSAGE(JERR_BAD_MCU_SIZE, "Sampling factors too large for interleaved scan") +JMESSAGE(JERR_BAD_POOL_ID, "Invalid memory pool code %d") +JMESSAGE(JERR_BAD_PRECISION, "Unsupported JPEG data precision %d") +JMESSAGE(JERR_BAD_PROGRESSION, + "Invalid progressive parameters Ss=%d Se=%d Ah=%d Al=%d") +JMESSAGE(JERR_BAD_PROG_SCRIPT, + "Invalid progressive parameters at scan script entry %d") +JMESSAGE(JERR_BAD_SAMPLING, "Bogus sampling factors") +JMESSAGE(JERR_BAD_SCAN_SCRIPT, "Invalid scan script at entry %d") +JMESSAGE(JERR_BAD_STATE, "Improper call to JPEG library in state %d") +JMESSAGE(JERR_BAD_STRUCT_SIZE, + "JPEG parameter struct mismatch: library thinks size is %u, caller expects %u") +JMESSAGE(JERR_BAD_VIRTUAL_ACCESS, "Bogus virtual array access") +JMESSAGE(JERR_BUFFER_SIZE, "Buffer passed to JPEG library is too small") +JMESSAGE(JERR_CANT_SUSPEND, "Suspension not allowed here") +JMESSAGE(JERR_CCIR601_NOTIMPL, "CCIR601 sampling not implemented yet") +JMESSAGE(JERR_COMPONENT_COUNT, "Too many color components: %d, max %d") +JMESSAGE(JERR_CONVERSION_NOTIMPL, "Unsupported color conversion request") +JMESSAGE(JERR_DAC_INDEX, "Bogus DAC index %d") +JMESSAGE(JERR_DAC_VALUE, "Bogus DAC value 0x%x") +JMESSAGE(JERR_DHT_INDEX, "Bogus DHT index %d") +JMESSAGE(JERR_DQT_INDEX, "Bogus DQT index %d") +JMESSAGE(JERR_EMPTY_IMAGE, "Empty JPEG image (DNL not supported)") +JMESSAGE(JERR_EMS_READ, "Read from EMS failed") +JMESSAGE(JERR_EMS_WRITE, "Write to EMS failed") +JMESSAGE(JERR_EOI_EXPECTED, "Didn't expect more than one scan") +JMESSAGE(JERR_FILE_READ, "Input file read error") +JMESSAGE(JERR_FILE_WRITE, "Output file write error --- out of disk space?") +JMESSAGE(JERR_FRACT_SAMPLE_NOTIMPL, "Fractional sampling not implemented yet") +JMESSAGE(JERR_HUFF_CLEN_OVERFLOW, "Huffman code size table overflow") +JMESSAGE(JERR_HUFF_MISSING_CODE, "Missing Huffman code table entry") +JMESSAGE(JERR_IMAGE_TOO_BIG, "Maximum supported image dimension is %u pixels") +JMESSAGE(JERR_INPUT_EMPTY, "Empty input file") +JMESSAGE(JERR_INPUT_EOF, "Premature end of input file") +JMESSAGE(JERR_MISMATCHED_QUANT_TABLE, + "Cannot transcode due to multiple use of quantization table %d") +JMESSAGE(JERR_MISSING_DATA, "Scan script does not transmit all data") +JMESSAGE(JERR_MODE_CHANGE, "Invalid color quantization mode change") +JMESSAGE(JERR_NOTIMPL, "Not implemented yet") +JMESSAGE(JERR_NOT_COMPILED, "Requested feature was omitted at compile time") +JMESSAGE(JERR_NO_BACKING_STORE, "Backing store not supported") +JMESSAGE(JERR_NO_HUFF_TABLE, "Huffman table 0x%02x was not defined") +JMESSAGE(JERR_NO_IMAGE, "JPEG datastream contains no image") +JMESSAGE(JERR_NO_QUANT_TABLE, "Quantization table 0x%02x was not defined") +JMESSAGE(JERR_NO_SOI, "Not a JPEG file: starts with 0x%02x 0x%02x") +JMESSAGE(JERR_OUT_OF_MEMORY, "Insufficient memory (case %d)") +JMESSAGE(JERR_QUANT_COMPONENTS, + "Cannot quantize more than %d color components") +JMESSAGE(JERR_QUANT_FEW_COLORS, "Cannot quantize to fewer than %d colors") +JMESSAGE(JERR_QUANT_MANY_COLORS, "Cannot quantize to more than %d colors") +JMESSAGE(JERR_SOF_DUPLICATE, "Invalid JPEG file structure: two SOF markers") +JMESSAGE(JERR_SOF_NO_SOS, "Invalid JPEG file structure: missing SOS marker") +JMESSAGE(JERR_SOF_UNSUPPORTED, "Unsupported JPEG process: SOF type 0x%02x") +JMESSAGE(JERR_SOI_DUPLICATE, "Invalid JPEG file structure: two SOI markers") +JMESSAGE(JERR_SOS_NO_SOF, "Invalid JPEG file structure: SOS before SOF") +JMESSAGE(JERR_TFILE_CREATE, "Failed to create temporary file %s") +JMESSAGE(JERR_TFILE_READ, "Read failed on temporary file") +JMESSAGE(JERR_TFILE_SEEK, "Seek failed on temporary file") +JMESSAGE(JERR_TFILE_WRITE, + "Write failed on temporary file --- out of disk space?") +JMESSAGE(JERR_TOO_LITTLE_DATA, "Application transferred too few scanlines") +JMESSAGE(JERR_UNKNOWN_MARKER, "Unsupported marker type 0x%02x") +JMESSAGE(JERR_VIRTUAL_BUG, "Virtual array controller messed up") +JMESSAGE(JERR_WIDTH_OVERFLOW, "Image too wide for this implementation") +JMESSAGE(JERR_XMS_READ, "Read from XMS failed") +JMESSAGE(JERR_XMS_WRITE, "Write to XMS failed") +JMESSAGE(JMSG_COPYRIGHT, JCOPYRIGHT) +JMESSAGE(JMSG_VERSION, JVERSION) +JMESSAGE(JTRC_16BIT_TABLES, + "Caution: quantization tables are too coarse for baseline JPEG") +JMESSAGE(JTRC_ADOBE, + "Adobe APP14 marker: version %d, flags 0x%04x 0x%04x, transform %d") +JMESSAGE(JTRC_APP0, "Unknown APP0 marker (not JFIF), length %u") +JMESSAGE(JTRC_APP14, "Unknown APP14 marker (not Adobe), length %u") +JMESSAGE(JTRC_DAC, "Define Arithmetic Table 0x%02x: 0x%02x") +JMESSAGE(JTRC_DHT, "Define Huffman Table 0x%02x") +JMESSAGE(JTRC_DQT, "Define Quantization Table %d precision %d") +JMESSAGE(JTRC_DRI, "Define Restart Interval %u") +JMESSAGE(JTRC_EMS_CLOSE, "Freed EMS handle %u") +JMESSAGE(JTRC_EMS_OPEN, "Obtained EMS handle %u") +JMESSAGE(JTRC_EOI, "End Of Image") +JMESSAGE(JTRC_HUFFBITS, " %3d %3d %3d %3d %3d %3d %3d %3d") +JMESSAGE(JTRC_JFIF, "JFIF APP0 marker: version %d.%02d, density %dx%d %d") +JMESSAGE(JTRC_JFIF_BADTHUMBNAILSIZE, + "Warning: thumbnail image size does not match data length %u") +JMESSAGE(JTRC_JFIF_EXTENSION, + "JFIF extension marker: type 0x%02x, length %u") +JMESSAGE(JTRC_JFIF_THUMBNAIL, " with %d x %d thumbnail image") +JMESSAGE(JTRC_MISC_MARKER, "Miscellaneous marker 0x%02x, length %u") +JMESSAGE(JTRC_PARMLESS_MARKER, "Unexpected marker 0x%02x") +JMESSAGE(JTRC_QUANTVALS, " %4u %4u %4u %4u %4u %4u %4u %4u") +JMESSAGE(JTRC_QUANT_3_NCOLORS, "Quantizing to %d = %d*%d*%d colors") +JMESSAGE(JTRC_QUANT_NCOLORS, "Quantizing to %d colors") +JMESSAGE(JTRC_QUANT_SELECTED, "Selected %d colors for quantization") +JMESSAGE(JTRC_RECOVERY_ACTION, "At marker 0x%02x, recovery action %d") +JMESSAGE(JTRC_RST, "RST%d") +JMESSAGE(JTRC_SMOOTH_NOTIMPL, + "Smoothing not supported with nonstandard sampling ratios") +JMESSAGE(JTRC_SOF, "Start Of Frame 0x%02x: width=%u, height=%u, components=%d") +JMESSAGE(JTRC_SOF_COMPONENT, " Component %d: %dhx%dv q=%d") +JMESSAGE(JTRC_SOI, "Start of Image") +JMESSAGE(JTRC_SOS, "Start Of Scan: %d components") +JMESSAGE(JTRC_SOS_COMPONENT, " Component %d: dc=%d ac=%d") +JMESSAGE(JTRC_SOS_PARAMS, " Ss=%d, Se=%d, Ah=%d, Al=%d") +JMESSAGE(JTRC_TFILE_CLOSE, "Closed temporary file %s") +JMESSAGE(JTRC_TFILE_OPEN, "Opened temporary file %s") +JMESSAGE(JTRC_THUMB_JPEG, + "JFIF extension marker: JPEG-compressed thumbnail image, length %u") +JMESSAGE(JTRC_THUMB_PALETTE, + "JFIF extension marker: palette thumbnail image, length %u") +JMESSAGE(JTRC_THUMB_RGB, + "JFIF extension marker: RGB thumbnail image, length %u") +JMESSAGE(JTRC_UNKNOWN_IDS, + "Unrecognized component IDs %d %d %d, assuming YCbCr") +JMESSAGE(JTRC_XMS_CLOSE, "Freed XMS handle %u") +JMESSAGE(JTRC_XMS_OPEN, "Obtained XMS handle %u") +JMESSAGE(JWRN_ADOBE_XFORM, "Unknown Adobe color transform code %d") +JMESSAGE(JWRN_BOGUS_PROGRESSION, + "Inconsistent progression sequence for component %d coefficient %d") +JMESSAGE(JWRN_EXTRANEOUS_DATA, + "Corrupt JPEG data: %u extraneous bytes before marker 0x%02x") +JMESSAGE(JWRN_HIT_MARKER, "Corrupt JPEG data: premature end of data segment") +JMESSAGE(JWRN_HUFF_BAD_CODE, "Corrupt JPEG data: bad Huffman code") +JMESSAGE(JWRN_JFIF_MAJOR, "Warning: unknown JFIF revision number %d.%02d") +JMESSAGE(JWRN_JPEG_EOF, "Premature end of JPEG file") +JMESSAGE(JWRN_MUST_RESYNC, + "Corrupt JPEG data: found marker 0x%02x instead of RST%d") +JMESSAGE(JWRN_NOT_SEQUENTIAL, "Invalid SOS parameters for sequential JPEG") +JMESSAGE(JWRN_TOO_MUCH_DATA, "Application transferred too many scanlines") + +#ifdef JMAKE_ENUM_LIST + + JMSG_LASTMSGCODE +} J_MESSAGE_CODE; + +#undef JMAKE_ENUM_LIST +#endif /* JMAKE_ENUM_LIST */ + +/* Zap JMESSAGE macro so that future re-inclusions do nothing by default */ +#undef JMESSAGE + + +#ifndef JERROR_H +#define JERROR_H + +/* Macros to simplify using the error and trace message stuff */ +/* The first parameter is either type of cinfo pointer */ + +/* Fatal errors (print message and exit) */ +#define ERREXIT(cinfo,code) \ + ((cinfo)->err->msg_code = (code), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXIT1(cinfo,code,p1) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXIT2(cinfo,code,p1,p2) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXIT3(cinfo,code,p1,p2,p3) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (cinfo)->err->msg_parm.i[2] = (p3), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXIT4(cinfo,code,p1,p2,p3,p4) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (cinfo)->err->msg_parm.i[2] = (p3), \ + (cinfo)->err->msg_parm.i[3] = (p4), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXITS(cinfo,code,str) \ + ((cinfo)->err->msg_code = (code), \ + strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) + +#define MAKESTMT(stuff) do { stuff } while (0) + +/* Nonfatal errors (we can keep going, but the data is probably corrupt) */ +#define WARNMS(cinfo,code) \ + ((cinfo)->err->msg_code = (code), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1)) +#define WARNMS1(cinfo,code,p1) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1)) +#define WARNMS2(cinfo,code,p1,p2) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1)) + +/* Informational/debugging messages */ +#define TRACEMS(cinfo,lvl,code) \ + ((cinfo)->err->msg_code = (code), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) +#define TRACEMS1(cinfo,lvl,code,p1) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) +#define TRACEMS2(cinfo,lvl,code,p1,p2) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) +#define TRACEMS3(cinfo,lvl,code,p1,p2,p3) \ + MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ + _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); \ + (cinfo)->err->msg_code = (code); \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) +#define TRACEMS4(cinfo,lvl,code,p1,p2,p3,p4) \ + MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ + _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \ + (cinfo)->err->msg_code = (code); \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) +#define TRACEMS5(cinfo,lvl,code,p1,p2,p3,p4,p5) \ + MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ + _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \ + _mp[4] = (p5); \ + (cinfo)->err->msg_code = (code); \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) +#define TRACEMS8(cinfo,lvl,code,p1,p2,p3,p4,p5,p6,p7,p8) \ + MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ + _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \ + _mp[4] = (p5); _mp[5] = (p6); _mp[6] = (p7); _mp[7] = (p8); \ + (cinfo)->err->msg_code = (code); \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) +#define TRACEMSS(cinfo,lvl,code,str) \ + ((cinfo)->err->msg_code = (code), \ + strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) + +#endif /* JERROR_H */ diff --git a/mod/pub.mod/libjpeg.mod/jfdctflt.c b/mod/pub.mod/libjpeg.mod/jfdctflt.c new file mode 100644 index 0000000..79d7a00 --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jfdctflt.c @@ -0,0 +1,168 @@ +/* + * jfdctflt.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains a floating-point implementation of the + * forward DCT (Discrete Cosine Transform). + * + * This implementation should be more accurate than either of the integer + * DCT implementations. However, it may not give the same results on all + * machines because of differences in roundoff behavior. Speed will depend + * on the hardware's floating point capacity. + * + * A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT + * on each column. Direct algorithms are also available, but they are + * much more complex and seem not to be any faster when reduced to code. + * + * This implementation is based on Arai, Agui, and Nakajima's algorithm for + * scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in + * Japanese, but the algorithm is described in the Pennebaker & Mitchell + * JPEG textbook (see REFERENCES section in file README). The following code + * is based directly on figure 4-8 in P&M. + * While an 8-point DCT cannot be done in less than 11 multiplies, it is + * possible to arrange the computation so that many of the multiplies are + * simple scalings of the final outputs. These multiplies can then be + * folded into the multiplications or divisions by the JPEG quantization + * table entries. The AA&N method leaves only 5 multiplies and 29 adds + * to be done in the DCT itself. + * The primary disadvantage of this method is that with a fixed-point + * implementation, accuracy is lost due to imprecise representation of the + * scaled quantization values. However, that problem does not arise if + * we use floating point arithmetic. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdct.h" /* Private declarations for DCT subsystem */ + +#ifdef DCT_FLOAT_SUPPORTED + + +/* + * This module is specialized to the case DCTSIZE = 8. + */ + +#if DCTSIZE != 8 + Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */ +#endif + + +/* + * Perform the forward DCT on one block of samples. + */ + +GLOBAL(void) +jpeg_fdct_float (FAST_FLOAT * data) +{ + FAST_FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; + FAST_FLOAT tmp10, tmp11, tmp12, tmp13; + FAST_FLOAT z1, z2, z3, z4, z5, z11, z13; + FAST_FLOAT *dataptr; + int ctr; + + /* Pass 1: process rows. */ + + dataptr = data; + for (ctr = DCTSIZE-1; ctr >= 0; ctr--) { + tmp0 = dataptr[0] + dataptr[7]; + tmp7 = dataptr[0] - dataptr[7]; + tmp1 = dataptr[1] + dataptr[6]; + tmp6 = dataptr[1] - dataptr[6]; + tmp2 = dataptr[2] + dataptr[5]; + tmp5 = dataptr[2] - dataptr[5]; + tmp3 = dataptr[3] + dataptr[4]; + tmp4 = dataptr[3] - dataptr[4]; + + /* Even part */ + + tmp10 = tmp0 + tmp3; /* phase 2 */ + tmp13 = tmp0 - tmp3; + tmp11 = tmp1 + tmp2; + tmp12 = tmp1 - tmp2; + + dataptr[0] = tmp10 + tmp11; /* phase 3 */ + dataptr[4] = tmp10 - tmp11; + + z1 = (tmp12 + tmp13) * ((FAST_FLOAT) 0.707106781); /* c4 */ + dataptr[2] = tmp13 + z1; /* phase 5 */ + dataptr[6] = tmp13 - z1; + + /* Odd part */ + + tmp10 = tmp4 + tmp5; /* phase 2 */ + tmp11 = tmp5 + tmp6; + tmp12 = tmp6 + tmp7; + + /* The rotator is modified from fig 4-8 to avoid extra negations. */ + z5 = (tmp10 - tmp12) * ((FAST_FLOAT) 0.382683433); /* c6 */ + z2 = ((FAST_FLOAT) 0.541196100) * tmp10 + z5; /* c2-c6 */ + z4 = ((FAST_FLOAT) 1.306562965) * tmp12 + z5; /* c2+c6 */ + z3 = tmp11 * ((FAST_FLOAT) 0.707106781); /* c4 */ + + z11 = tmp7 + z3; /* phase 5 */ + z13 = tmp7 - z3; + + dataptr[5] = z13 + z2; /* phase 6 */ + dataptr[3] = z13 - z2; + dataptr[1] = z11 + z4; + dataptr[7] = z11 - z4; + + dataptr += DCTSIZE; /* advance pointer to next row */ + } + + /* Pass 2: process columns. */ + + dataptr = data; + for (ctr = DCTSIZE-1; ctr >= 0; ctr--) { + tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7]; + tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7]; + tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6]; + tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6]; + tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5]; + tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5]; + tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4]; + tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4]; + + /* Even part */ + + tmp10 = tmp0 + tmp3; /* phase 2 */ + tmp13 = tmp0 - tmp3; + tmp11 = tmp1 + tmp2; + tmp12 = tmp1 - tmp2; + + dataptr[DCTSIZE*0] = tmp10 + tmp11; /* phase 3 */ + dataptr[DCTSIZE*4] = tmp10 - tmp11; + + z1 = (tmp12 + tmp13) * ((FAST_FLOAT) 0.707106781); /* c4 */ + dataptr[DCTSIZE*2] = tmp13 + z1; /* phase 5 */ + dataptr[DCTSIZE*6] = tmp13 - z1; + + /* Odd part */ + + tmp10 = tmp4 + tmp5; /* phase 2 */ + tmp11 = tmp5 + tmp6; + tmp12 = tmp6 + tmp7; + + /* The rotator is modified from fig 4-8 to avoid extra negations. */ + z5 = (tmp10 - tmp12) * ((FAST_FLOAT) 0.382683433); /* c6 */ + z2 = ((FAST_FLOAT) 0.541196100) * tmp10 + z5; /* c2-c6 */ + z4 = ((FAST_FLOAT) 1.306562965) * tmp12 + z5; /* c2+c6 */ + z3 = tmp11 * ((FAST_FLOAT) 0.707106781); /* c4 */ + + z11 = tmp7 + z3; /* phase 5 */ + z13 = tmp7 - z3; + + dataptr[DCTSIZE*5] = z13 + z2; /* phase 6 */ + dataptr[DCTSIZE*3] = z13 - z2; + dataptr[DCTSIZE*1] = z11 + z4; + dataptr[DCTSIZE*7] = z11 - z4; + + dataptr++; /* advance pointer to next column */ + } +} + +#endif /* DCT_FLOAT_SUPPORTED */ diff --git a/mod/pub.mod/libjpeg.mod/jfdctfst.c b/mod/pub.mod/libjpeg.mod/jfdctfst.c new file mode 100644 index 0000000..ccb378a --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jfdctfst.c @@ -0,0 +1,224 @@ +/* + * jfdctfst.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains a fast, not so accurate integer implementation of the + * forward DCT (Discrete Cosine Transform). + * + * A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT + * on each column. Direct algorithms are also available, but they are + * much more complex and seem not to be any faster when reduced to code. + * + * This implementation is based on Arai, Agui, and Nakajima's algorithm for + * scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in + * Japanese, but the algorithm is described in the Pennebaker & Mitchell + * JPEG textbook (see REFERENCES section in file README). The following code + * is based directly on figure 4-8 in P&M. + * While an 8-point DCT cannot be done in less than 11 multiplies, it is + * possible to arrange the computation so that many of the multiplies are + * simple scalings of the final outputs. These multiplies can then be + * folded into the multiplications or divisions by the JPEG quantization + * table entries. The AA&N method leaves only 5 multiplies and 29 adds + * to be done in the DCT itself. + * The primary disadvantage of this method is that with fixed-point math, + * accuracy is lost due to imprecise representation of the scaled + * quantization values. The smaller the quantization table entry, the less + * precise the scaled value, so this implementation does worse with high- + * quality-setting files than with low-quality ones. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdct.h" /* Private declarations for DCT subsystem */ + +#ifdef DCT_IFAST_SUPPORTED + + +/* + * This module is specialized to the case DCTSIZE = 8. + */ + +#if DCTSIZE != 8 + Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */ +#endif + + +/* Scaling decisions are generally the same as in the LL&M algorithm; + * see jfdctint.c for more details. However, we choose to descale + * (right shift) multiplication products as soon as they are formed, + * rather than carrying additional fractional bits into subsequent additions. + * This compromises accuracy slightly, but it lets us save a few shifts. + * More importantly, 16-bit arithmetic is then adequate (for 8-bit samples) + * everywhere except in the multiplications proper; this saves a good deal + * of work on 16-bit-int machines. + * + * Again to save a few shifts, the intermediate results between pass 1 and + * pass 2 are not upscaled, but are represented only to integral precision. + * + * A final compromise is to represent the multiplicative constants to only + * 8 fractional bits, rather than 13. This saves some shifting work on some + * machines, and may also reduce the cost of multiplication (since there + * are fewer one-bits in the constants). + */ + +#define CONST_BITS 8 + + +/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus + * causing a lot of useless floating-point operations at run time. + * To get around this we use the following pre-calculated constants. + * If you change CONST_BITS you may want to add appropriate values. + * (With a reasonable C compiler, you can just rely on the FIX() macro...) + */ + +#if CONST_BITS == 8 +#define FIX_0_382683433 ((INT32) 98) /* FIX(0.382683433) */ +#define FIX_0_541196100 ((INT32) 139) /* FIX(0.541196100) */ +#define FIX_0_707106781 ((INT32) 181) /* FIX(0.707106781) */ +#define FIX_1_306562965 ((INT32) 334) /* FIX(1.306562965) */ +#else +#define FIX_0_382683433 FIX(0.382683433) +#define FIX_0_541196100 FIX(0.541196100) +#define FIX_0_707106781 FIX(0.707106781) +#define FIX_1_306562965 FIX(1.306562965) +#endif + + +/* We can gain a little more speed, with a further compromise in accuracy, + * by omitting the addition in a descaling shift. This yields an incorrectly + * rounded result half the time... + */ + +#ifndef USE_ACCURATE_ROUNDING +#undef DESCALE +#define DESCALE(x,n) RIGHT_SHIFT(x, n) +#endif + + +/* Multiply a DCTELEM variable by an INT32 constant, and immediately + * descale to yield a DCTELEM result. + */ + +#define MULTIPLY(var,const) ((DCTELEM) DESCALE((var) * (const), CONST_BITS)) + + +/* + * Perform the forward DCT on one block of samples. + */ + +GLOBAL(void) +jpeg_fdct_ifast (DCTELEM * data) +{ + DCTELEM tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; + DCTELEM tmp10, tmp11, tmp12, tmp13; + DCTELEM z1, z2, z3, z4, z5, z11, z13; + DCTELEM *dataptr; + int ctr; + SHIFT_TEMPS + + /* Pass 1: process rows. */ + + dataptr = data; + for (ctr = DCTSIZE-1; ctr >= 0; ctr--) { + tmp0 = dataptr[0] + dataptr[7]; + tmp7 = dataptr[0] - dataptr[7]; + tmp1 = dataptr[1] + dataptr[6]; + tmp6 = dataptr[1] - dataptr[6]; + tmp2 = dataptr[2] + dataptr[5]; + tmp5 = dataptr[2] - dataptr[5]; + tmp3 = dataptr[3] + dataptr[4]; + tmp4 = dataptr[3] - dataptr[4]; + + /* Even part */ + + tmp10 = tmp0 + tmp3; /* phase 2 */ + tmp13 = tmp0 - tmp3; + tmp11 = tmp1 + tmp2; + tmp12 = tmp1 - tmp2; + + dataptr[0] = tmp10 + tmp11; /* phase 3 */ + dataptr[4] = tmp10 - tmp11; + + z1 = MULTIPLY(tmp12 + tmp13, FIX_0_707106781); /* c4 */ + dataptr[2] = tmp13 + z1; /* phase 5 */ + dataptr[6] = tmp13 - z1; + + /* Odd part */ + + tmp10 = tmp4 + tmp5; /* phase 2 */ + tmp11 = tmp5 + tmp6; + tmp12 = tmp6 + tmp7; + + /* The rotator is modified from fig 4-8 to avoid extra negations. */ + z5 = MULTIPLY(tmp10 - tmp12, FIX_0_382683433); /* c6 */ + z2 = MULTIPLY(tmp10, FIX_0_541196100) + z5; /* c2-c6 */ + z4 = MULTIPLY(tmp12, FIX_1_306562965) + z5; /* c2+c6 */ + z3 = MULTIPLY(tmp11, FIX_0_707106781); /* c4 */ + + z11 = tmp7 + z3; /* phase 5 */ + z13 = tmp7 - z3; + + dataptr[5] = z13 + z2; /* phase 6 */ + dataptr[3] = z13 - z2; + dataptr[1] = z11 + z4; + dataptr[7] = z11 - z4; + + dataptr += DCTSIZE; /* advance pointer to next row */ + } + + /* Pass 2: process columns. */ + + dataptr = data; + for (ctr = DCTSIZE-1; ctr >= 0; ctr--) { + tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7]; + tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7]; + tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6]; + tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6]; + tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5]; + tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5]; + tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4]; + tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4]; + + /* Even part */ + + tmp10 = tmp0 + tmp3; /* phase 2 */ + tmp13 = tmp0 - tmp3; + tmp11 = tmp1 + tmp2; + tmp12 = tmp1 - tmp2; + + dataptr[DCTSIZE*0] = tmp10 + tmp11; /* phase 3 */ + dataptr[DCTSIZE*4] = tmp10 - tmp11; + + z1 = MULTIPLY(tmp12 + tmp13, FIX_0_707106781); /* c4 */ + dataptr[DCTSIZE*2] = tmp13 + z1; /* phase 5 */ + dataptr[DCTSIZE*6] = tmp13 - z1; + + /* Odd part */ + + tmp10 = tmp4 + tmp5; /* phase 2 */ + tmp11 = tmp5 + tmp6; + tmp12 = tmp6 + tmp7; + + /* The rotator is modified from fig 4-8 to avoid extra negations. */ + z5 = MULTIPLY(tmp10 - tmp12, FIX_0_382683433); /* c6 */ + z2 = MULTIPLY(tmp10, FIX_0_541196100) + z5; /* c2-c6 */ + z4 = MULTIPLY(tmp12, FIX_1_306562965) + z5; /* c2+c6 */ + z3 = MULTIPLY(tmp11, FIX_0_707106781); /* c4 */ + + z11 = tmp7 + z3; /* phase 5 */ + z13 = tmp7 - z3; + + dataptr[DCTSIZE*5] = z13 + z2; /* phase 6 */ + dataptr[DCTSIZE*3] = z13 - z2; + dataptr[DCTSIZE*1] = z11 + z4; + dataptr[DCTSIZE*7] = z11 - z4; + + dataptr++; /* advance pointer to next column */ + } +} + +#endif /* DCT_IFAST_SUPPORTED */ diff --git a/mod/pub.mod/libjpeg.mod/jfdctint.c b/mod/pub.mod/libjpeg.mod/jfdctint.c new file mode 100644 index 0000000..0a78b64 --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jfdctint.c @@ -0,0 +1,283 @@ +/* + * jfdctint.c + * + * Copyright (C) 1991-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains a slow-but-accurate integer implementation of the + * forward DCT (Discrete Cosine Transform). + * + * A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT + * on each column. Direct algorithms are also available, but they are + * much more complex and seem not to be any faster when reduced to code. + * + * This implementation is based on an algorithm described in + * C. Loeffler, A. Ligtenberg and G. Moschytz, "Practical Fast 1-D DCT + * Algorithms with 11 Multiplications", Proc. Int'l. Conf. on Acoustics, + * Speech, and Signal Processing 1989 (ICASSP '89), pp. 988-991. + * The primary algorithm described there uses 11 multiplies and 29 adds. + * We use their alternate method with 12 multiplies and 32 adds. + * The advantage of this method is that no data path contains more than one + * multiplication; this allows a very simple and accurate implementation in + * scaled fixed-point arithmetic, with a minimal number of shifts. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdct.h" /* Private declarations for DCT subsystem */ + +#ifdef DCT_ISLOW_SUPPORTED + + +/* + * This module is specialized to the case DCTSIZE = 8. + */ + +#if DCTSIZE != 8 + Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */ +#endif + + +/* + * The poop on this scaling stuff is as follows: + * + * Each 1-D DCT step produces outputs which are a factor of sqrt(N) + * larger than the true DCT outputs. The final outputs are therefore + * a factor of N larger than desired; since N=8 this can be cured by + * a simple right shift at the end of the algorithm. The advantage of + * this arrangement is that we save two multiplications per 1-D DCT, + * because the y0 and y4 outputs need not be divided by sqrt(N). + * In the IJG code, this factor of 8 is removed by the quantization step + * (in jcdctmgr.c), NOT in this module. + * + * We have to do addition and subtraction of the integer inputs, which + * is no problem, and multiplication by fractional constants, which is + * a problem to do in integer arithmetic. We multiply all the constants + * by CONST_SCALE and convert them to integer constants (thus retaining + * CONST_BITS bits of precision in the constants). After doing a + * multiplication we have to divide the product by CONST_SCALE, with proper + * rounding, to produce the correct output. This division can be done + * cheaply as a right shift of CONST_BITS bits. We postpone shifting + * as long as possible so that partial sums can be added together with + * full fractional precision. + * + * The outputs of the first pass are scaled up by PASS1_BITS bits so that + * they are represented to better-than-integral precision. These outputs + * require BITS_IN_JSAMPLE + PASS1_BITS + 3 bits; this fits in a 16-bit word + * with the recommended scaling. (For 12-bit sample data, the intermediate + * array is INT32 anyway.) + * + * To avoid overflow of the 32-bit intermediate results in pass 2, we must + * have BITS_IN_JSAMPLE + CONST_BITS + PASS1_BITS <= 26. Error analysis + * shows that the values given below are the most effective. + */ + +#if BITS_IN_JSAMPLE == 8 +#define CONST_BITS 13 +#define PASS1_BITS 2 +#else +#define CONST_BITS 13 +#define PASS1_BITS 1 /* lose a little precision to avoid overflow */ +#endif + +/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus + * causing a lot of useless floating-point operations at run time. + * To get around this we use the following pre-calculated constants. + * If you change CONST_BITS you may want to add appropriate values. + * (With a reasonable C compiler, you can just rely on the FIX() macro...) + */ + +#if CONST_BITS == 13 +#define FIX_0_298631336 ((INT32) 2446) /* FIX(0.298631336) */ +#define FIX_0_390180644 ((INT32) 3196) /* FIX(0.390180644) */ +#define FIX_0_541196100 ((INT32) 4433) /* FIX(0.541196100) */ +#define FIX_0_765366865 ((INT32) 6270) /* FIX(0.765366865) */ +#define FIX_0_899976223 ((INT32) 7373) /* FIX(0.899976223) */ +#define FIX_1_175875602 ((INT32) 9633) /* FIX(1.175875602) */ +#define FIX_1_501321110 ((INT32) 12299) /* FIX(1.501321110) */ +#define FIX_1_847759065 ((INT32) 15137) /* FIX(1.847759065) */ +#define FIX_1_961570560 ((INT32) 16069) /* FIX(1.961570560) */ +#define FIX_2_053119869 ((INT32) 16819) /* FIX(2.053119869) */ +#define FIX_2_562915447 ((INT32) 20995) /* FIX(2.562915447) */ +#define FIX_3_072711026 ((INT32) 25172) /* FIX(3.072711026) */ +#else +#define FIX_0_298631336 FIX(0.298631336) +#define FIX_0_390180644 FIX(0.390180644) +#define FIX_0_541196100 FIX(0.541196100) +#define FIX_0_765366865 FIX(0.765366865) +#define FIX_0_899976223 FIX(0.899976223) +#define FIX_1_175875602 FIX(1.175875602) +#define FIX_1_501321110 FIX(1.501321110) +#define FIX_1_847759065 FIX(1.847759065) +#define FIX_1_961570560 FIX(1.961570560) +#define FIX_2_053119869 FIX(2.053119869) +#define FIX_2_562915447 FIX(2.562915447) +#define FIX_3_072711026 FIX(3.072711026) +#endif + + +/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result. + * For 8-bit samples with the recommended scaling, all the variable + * and constant values involved are no more than 16 bits wide, so a + * 16x16->32 bit multiply can be used instead of a full 32x32 multiply. + * For 12-bit samples, a full 32-bit multiplication will be needed. + */ + +#if BITS_IN_JSAMPLE == 8 +#define MULTIPLY(var,const) MULTIPLY16C16(var,const) +#else +#define MULTIPLY(var,const) ((var) * (const)) +#endif + + +/* + * Perform the forward DCT on one block of samples. + */ + +GLOBAL(void) +jpeg_fdct_islow (DCTELEM * data) +{ + INT32 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; + INT32 tmp10, tmp11, tmp12, tmp13; + INT32 z1, z2, z3, z4, z5; + DCTELEM *dataptr; + int ctr; + SHIFT_TEMPS + + /* Pass 1: process rows. */ + /* Note results are scaled up by sqrt(8) compared to a true DCT; */ + /* furthermore, we scale the results by 2**PASS1_BITS. */ + + dataptr = data; + for (ctr = DCTSIZE-1; ctr >= 0; ctr--) { + tmp0 = dataptr[0] + dataptr[7]; + tmp7 = dataptr[0] - dataptr[7]; + tmp1 = dataptr[1] + dataptr[6]; + tmp6 = dataptr[1] - dataptr[6]; + tmp2 = dataptr[2] + dataptr[5]; + tmp5 = dataptr[2] - dataptr[5]; + tmp3 = dataptr[3] + dataptr[4]; + tmp4 = dataptr[3] - dataptr[4]; + + /* Even part per LL&M figure 1 --- note that published figure is faulty; + * rotator "sqrt(2)*c1" should be "sqrt(2)*c6". + */ + + tmp10 = tmp0 + tmp3; + tmp13 = tmp0 - tmp3; + tmp11 = tmp1 + tmp2; + tmp12 = tmp1 - tmp2; + + dataptr[0] = (DCTELEM) ((tmp10 + tmp11) << PASS1_BITS); + dataptr[4] = (DCTELEM) ((tmp10 - tmp11) << PASS1_BITS); + + z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100); + dataptr[2] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865), + CONST_BITS-PASS1_BITS); + dataptr[6] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065), + CONST_BITS-PASS1_BITS); + + /* Odd part per figure 8 --- note paper omits factor of sqrt(2). + * cK represents cos(K*pi/16). + * i0..i3 in the paper are tmp4..tmp7 here. + */ + + z1 = tmp4 + tmp7; + z2 = tmp5 + tmp6; + z3 = tmp4 + tmp6; + z4 = tmp5 + tmp7; + z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */ + + tmp4 = MULTIPLY(tmp4, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */ + tmp5 = MULTIPLY(tmp5, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */ + tmp6 = MULTIPLY(tmp6, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */ + tmp7 = MULTIPLY(tmp7, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */ + z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */ + z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */ + z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */ + z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */ + + z3 += z5; + z4 += z5; + + dataptr[7] = (DCTELEM) DESCALE(tmp4 + z1 + z3, CONST_BITS-PASS1_BITS); + dataptr[5] = (DCTELEM) DESCALE(tmp5 + z2 + z4, CONST_BITS-PASS1_BITS); + dataptr[3] = (DCTELEM) DESCALE(tmp6 + z2 + z3, CONST_BITS-PASS1_BITS); + dataptr[1] = (DCTELEM) DESCALE(tmp7 + z1 + z4, CONST_BITS-PASS1_BITS); + + dataptr += DCTSIZE; /* advance pointer to next row */ + } + + /* Pass 2: process columns. + * We remove the PASS1_BITS scaling, but leave the results scaled up + * by an overall factor of 8. + */ + + dataptr = data; + for (ctr = DCTSIZE-1; ctr >= 0; ctr--) { + tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7]; + tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7]; + tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6]; + tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6]; + tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5]; + tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5]; + tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4]; + tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4]; + + /* Even part per LL&M figure 1 --- note that published figure is faulty; + * rotator "sqrt(2)*c1" should be "sqrt(2)*c6". + */ + + tmp10 = tmp0 + tmp3; + tmp13 = tmp0 - tmp3; + tmp11 = tmp1 + tmp2; + tmp12 = tmp1 - tmp2; + + dataptr[DCTSIZE*0] = (DCTELEM) DESCALE(tmp10 + tmp11, PASS1_BITS); + dataptr[DCTSIZE*4] = (DCTELEM) DESCALE(tmp10 - tmp11, PASS1_BITS); + + z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100); + dataptr[DCTSIZE*2] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865), + CONST_BITS+PASS1_BITS); + dataptr[DCTSIZE*6] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065), + CONST_BITS+PASS1_BITS); + + /* Odd part per figure 8 --- note paper omits factor of sqrt(2). + * cK represents cos(K*pi/16). + * i0..i3 in the paper are tmp4..tmp7 here. + */ + + z1 = tmp4 + tmp7; + z2 = tmp5 + tmp6; + z3 = tmp4 + tmp6; + z4 = tmp5 + tmp7; + z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */ + + tmp4 = MULTIPLY(tmp4, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */ + tmp5 = MULTIPLY(tmp5, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */ + tmp6 = MULTIPLY(tmp6, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */ + tmp7 = MULTIPLY(tmp7, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */ + z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */ + z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */ + z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */ + z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */ + + z3 += z5; + z4 += z5; + + dataptr[DCTSIZE*7] = (DCTELEM) DESCALE(tmp4 + z1 + z3, + CONST_BITS+PASS1_BITS); + dataptr[DCTSIZE*5] = (DCTELEM) DESCALE(tmp5 + z2 + z4, + CONST_BITS+PASS1_BITS); + dataptr[DCTSIZE*3] = (DCTELEM) DESCALE(tmp6 + z2 + z3, + CONST_BITS+PASS1_BITS); + dataptr[DCTSIZE*1] = (DCTELEM) DESCALE(tmp7 + z1 + z4, + CONST_BITS+PASS1_BITS); + + dataptr++; /* advance pointer to next column */ + } +} + +#endif /* DCT_ISLOW_SUPPORTED */ diff --git a/mod/pub.mod/libjpeg.mod/jidctflt.c b/mod/pub.mod/libjpeg.mod/jidctflt.c new file mode 100644 index 0000000..0188ce3 --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jidctflt.c @@ -0,0 +1,242 @@ +/* + * jidctflt.c + * + * Copyright (C) 1994-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains a floating-point implementation of the + * inverse DCT (Discrete Cosine Transform). In the IJG code, this routine + * must also perform dequantization of the input coefficients. + * + * This implementation should be more accurate than either of the integer + * IDCT implementations. However, it may not give the same results on all + * machines because of differences in roundoff behavior. Speed will depend + * on the hardware's floating point capacity. + * + * A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT + * on each row (or vice versa, but it's more convenient to emit a row at + * a time). Direct algorithms are also available, but they are much more + * complex and seem not to be any faster when reduced to code. + * + * This implementation is based on Arai, Agui, and Nakajima's algorithm for + * scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in + * Japanese, but the algorithm is described in the Pennebaker & Mitchell + * JPEG textbook (see REFERENCES section in file README). The following code + * is based directly on figure 4-8 in P&M. + * While an 8-point DCT cannot be done in less than 11 multiplies, it is + * possible to arrange the computation so that many of the multiplies are + * simple scalings of the final outputs. These multiplies can then be + * folded into the multiplications or divisions by the JPEG quantization + * table entries. The AA&N method leaves only 5 multiplies and 29 adds + * to be done in the DCT itself. + * The primary disadvantage of this method is that with a fixed-point + * implementation, accuracy is lost due to imprecise representation of the + * scaled quantization values. However, that problem does not arise if + * we use floating point arithmetic. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdct.h" /* Private declarations for DCT subsystem */ + +#ifdef DCT_FLOAT_SUPPORTED + + +/* + * This module is specialized to the case DCTSIZE = 8. + */ + +#if DCTSIZE != 8 + Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */ +#endif + + +/* Dequantize a coefficient by multiplying it by the multiplier-table + * entry; produce a float result. + */ + +#define DEQUANTIZE(coef,quantval) (((FAST_FLOAT) (coef)) * (quantval)) + + +/* + * Perform dequantization and inverse DCT on one block of coefficients. + */ + +GLOBAL(void) +jpeg_idct_float (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, + JSAMPARRAY output_buf, JDIMENSION output_col) +{ + FAST_FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; + FAST_FLOAT tmp10, tmp11, tmp12, tmp13; + FAST_FLOAT z5, z10, z11, z12, z13; + JCOEFPTR inptr; + FLOAT_MULT_TYPE * quantptr; + FAST_FLOAT * wsptr; + JSAMPROW outptr; + JSAMPLE *range_limit = IDCT_range_limit(cinfo); + int ctr; + FAST_FLOAT workspace[DCTSIZE2]; /* buffers data between passes */ + SHIFT_TEMPS + + /* Pass 1: process columns from input, store into work array. */ + + inptr = coef_block; + quantptr = (FLOAT_MULT_TYPE *) compptr->dct_table; + wsptr = workspace; + for (ctr = DCTSIZE; ctr > 0; ctr--) { + /* Due to quantization, we will usually find that many of the input + * coefficients are zero, especially the AC terms. We can exploit this + * by short-circuiting the IDCT calculation for any column in which all + * the AC terms are zero. In that case each output is equal to the + * DC coefficient (with scale factor as needed). + * With typical images and quantization tables, half or more of the + * column DCT calculations can be simplified this way. + */ + + if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 && + inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 && + inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 && + inptr[DCTSIZE*7] == 0) { + /* AC terms all zero */ + FAST_FLOAT dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); + + wsptr[DCTSIZE*0] = dcval; + wsptr[DCTSIZE*1] = dcval; + wsptr[DCTSIZE*2] = dcval; + wsptr[DCTSIZE*3] = dcval; + wsptr[DCTSIZE*4] = dcval; + wsptr[DCTSIZE*5] = dcval; + wsptr[DCTSIZE*6] = dcval; + wsptr[DCTSIZE*7] = dcval; + + inptr++; /* advance pointers to next column */ + quantptr++; + wsptr++; + continue; + } + + /* Even part */ + + tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); + tmp1 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); + tmp2 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]); + tmp3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]); + + tmp10 = tmp0 + tmp2; /* phase 3 */ + tmp11 = tmp0 - tmp2; + + tmp13 = tmp1 + tmp3; /* phases 5-3 */ + tmp12 = (tmp1 - tmp3) * ((FAST_FLOAT) 1.414213562) - tmp13; /* 2*c4 */ + + tmp0 = tmp10 + tmp13; /* phase 2 */ + tmp3 = tmp10 - tmp13; + tmp1 = tmp11 + tmp12; + tmp2 = tmp11 - tmp12; + + /* Odd part */ + + tmp4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); + tmp5 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); + tmp6 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); + tmp7 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]); + + z13 = tmp6 + tmp5; /* phase 6 */ + z10 = tmp6 - tmp5; + z11 = tmp4 + tmp7; + z12 = tmp4 - tmp7; + + tmp7 = z11 + z13; /* phase 5 */ + tmp11 = (z11 - z13) * ((FAST_FLOAT) 1.414213562); /* 2*c4 */ + + z5 = (z10 + z12) * ((FAST_FLOAT) 1.847759065); /* 2*c2 */ + tmp10 = ((FAST_FLOAT) 1.082392200) * z12 - z5; /* 2*(c2-c6) */ + tmp12 = ((FAST_FLOAT) -2.613125930) * z10 + z5; /* -2*(c2+c6) */ + + tmp6 = tmp12 - tmp7; /* phase 2 */ + tmp5 = tmp11 - tmp6; + tmp4 = tmp10 + tmp5; + + wsptr[DCTSIZE*0] = tmp0 + tmp7; + wsptr[DCTSIZE*7] = tmp0 - tmp7; + wsptr[DCTSIZE*1] = tmp1 + tmp6; + wsptr[DCTSIZE*6] = tmp1 - tmp6; + wsptr[DCTSIZE*2] = tmp2 + tmp5; + wsptr[DCTSIZE*5] = tmp2 - tmp5; + wsptr[DCTSIZE*4] = tmp3 + tmp4; + wsptr[DCTSIZE*3] = tmp3 - tmp4; + + inptr++; /* advance pointers to next column */ + quantptr++; + wsptr++; + } + + /* Pass 2: process rows from work array, store into output array. */ + /* Note that we must descale the results by a factor of 8 == 2**3. */ + + wsptr = workspace; + for (ctr = 0; ctr < DCTSIZE; ctr++) { + outptr = output_buf[ctr] + output_col; + /* Rows of zeroes can be exploited in the same way as we did with columns. + * However, the column calculation has created many nonzero AC terms, so + * the simplification applies less often (typically 5% to 10% of the time). + * And testing floats for zero is relatively expensive, so we don't bother. + */ + + /* Even part */ + + tmp10 = wsptr[0] + wsptr[4]; + tmp11 = wsptr[0] - wsptr[4]; + + tmp13 = wsptr[2] + wsptr[6]; + tmp12 = (wsptr[2] - wsptr[6]) * ((FAST_FLOAT) 1.414213562) - tmp13; + + tmp0 = tmp10 + tmp13; + tmp3 = tmp10 - tmp13; + tmp1 = tmp11 + tmp12; + tmp2 = tmp11 - tmp12; + + /* Odd part */ + + z13 = wsptr[5] + wsptr[3]; + z10 = wsptr[5] - wsptr[3]; + z11 = wsptr[1] + wsptr[7]; + z12 = wsptr[1] - wsptr[7]; + + tmp7 = z11 + z13; + tmp11 = (z11 - z13) * ((FAST_FLOAT) 1.414213562); + + z5 = (z10 + z12) * ((FAST_FLOAT) 1.847759065); /* 2*c2 */ + tmp10 = ((FAST_FLOAT) 1.082392200) * z12 - z5; /* 2*(c2-c6) */ + tmp12 = ((FAST_FLOAT) -2.613125930) * z10 + z5; /* -2*(c2+c6) */ + + tmp6 = tmp12 - tmp7; + tmp5 = tmp11 - tmp6; + tmp4 = tmp10 + tmp5; + + /* Final output stage: scale down by a factor of 8 and range-limit */ + + outptr[0] = range_limit[(int) DESCALE((INT32) (tmp0 + tmp7), 3) + & RANGE_MASK]; + outptr[7] = range_limit[(int) DESCALE((INT32) (tmp0 - tmp7), 3) + & RANGE_MASK]; + outptr[1] = range_limit[(int) DESCALE((INT32) (tmp1 + tmp6), 3) + & RANGE_MASK]; + outptr[6] = range_limit[(int) DESCALE((INT32) (tmp1 - tmp6), 3) + & RANGE_MASK]; + outptr[2] = range_limit[(int) DESCALE((INT32) (tmp2 + tmp5), 3) + & RANGE_MASK]; + outptr[5] = range_limit[(int) DESCALE((INT32) (tmp2 - tmp5), 3) + & RANGE_MASK]; + outptr[4] = range_limit[(int) DESCALE((INT32) (tmp3 + tmp4), 3) + & RANGE_MASK]; + outptr[3] = range_limit[(int) DESCALE((INT32) (tmp3 - tmp4), 3) + & RANGE_MASK]; + + wsptr += DCTSIZE; /* advance pointer to next row */ + } +} + +#endif /* DCT_FLOAT_SUPPORTED */ diff --git a/mod/pub.mod/libjpeg.mod/jidctfst.c b/mod/pub.mod/libjpeg.mod/jidctfst.c new file mode 100644 index 0000000..dba4216 --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jidctfst.c @@ -0,0 +1,368 @@ +/* + * jidctfst.c + * + * Copyright (C) 1994-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains a fast, not so accurate integer implementation of the + * inverse DCT (Discrete Cosine Transform). In the IJG code, this routine + * must also perform dequantization of the input coefficients. + * + * A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT + * on each row (or vice versa, but it's more convenient to emit a row at + * a time). Direct algorithms are also available, but they are much more + * complex and seem not to be any faster when reduced to code. + * + * This implementation is based on Arai, Agui, and Nakajima's algorithm for + * scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in + * Japanese, but the algorithm is described in the Pennebaker & Mitchell + * JPEG textbook (see REFERENCES section in file README). The following code + * is based directly on figure 4-8 in P&M. + * While an 8-point DCT cannot be done in less than 11 multiplies, it is + * possible to arrange the computation so that many of the multiplies are + * simple scalings of the final outputs. These multiplies can then be + * folded into the multiplications or divisions by the JPEG quantization + * table entries. The AA&N method leaves only 5 multiplies and 29 adds + * to be done in the DCT itself. + * The primary disadvantage of this method is that with fixed-point math, + * accuracy is lost due to imprecise representation of the scaled + * quantization values. The smaller the quantization table entry, the less + * precise the scaled value, so this implementation does worse with high- + * quality-setting files than with low-quality ones. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdct.h" /* Private declarations for DCT subsystem */ + +#ifdef DCT_IFAST_SUPPORTED + + +/* + * This module is specialized to the case DCTSIZE = 8. + */ + +#if DCTSIZE != 8 + Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */ +#endif + + +/* Scaling decisions are generally the same as in the LL&M algorithm; + * see jidctint.c for more details. However, we choose to descale + * (right shift) multiplication products as soon as they are formed, + * rather than carrying additional fractional bits into subsequent additions. + * This compromises accuracy slightly, but it lets us save a few shifts. + * More importantly, 16-bit arithmetic is then adequate (for 8-bit samples) + * everywhere except in the multiplications proper; this saves a good deal + * of work on 16-bit-int machines. + * + * The dequantized coefficients are not integers because the AA&N scaling + * factors have been incorporated. We represent them scaled up by PASS1_BITS, + * so that the first and second IDCT rounds have the same input scaling. + * For 8-bit JSAMPLEs, we choose IFAST_SCALE_BITS = PASS1_BITS so as to + * avoid a descaling shift; this compromises accuracy rather drastically + * for small quantization table entries, but it saves a lot of shifts. + * For 12-bit JSAMPLEs, there's no hope of using 16x16 multiplies anyway, + * so we use a much larger scaling factor to preserve accuracy. + * + * A final compromise is to represent the multiplicative constants to only + * 8 fractional bits, rather than 13. This saves some shifting work on some + * machines, and may also reduce the cost of multiplication (since there + * are fewer one-bits in the constants). + */ + +#if BITS_IN_JSAMPLE == 8 +#define CONST_BITS 8 +#define PASS1_BITS 2 +#else +#define CONST_BITS 8 +#define PASS1_BITS 1 /* lose a little precision to avoid overflow */ +#endif + +/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus + * causing a lot of useless floating-point operations at run time. + * To get around this we use the following pre-calculated constants. + * If you change CONST_BITS you may want to add appropriate values. + * (With a reasonable C compiler, you can just rely on the FIX() macro...) + */ + +#if CONST_BITS == 8 +#define FIX_1_082392200 ((INT32) 277) /* FIX(1.082392200) */ +#define FIX_1_414213562 ((INT32) 362) /* FIX(1.414213562) */ +#define FIX_1_847759065 ((INT32) 473) /* FIX(1.847759065) */ +#define FIX_2_613125930 ((INT32) 669) /* FIX(2.613125930) */ +#else +#define FIX_1_082392200 FIX(1.082392200) +#define FIX_1_414213562 FIX(1.414213562) +#define FIX_1_847759065 FIX(1.847759065) +#define FIX_2_613125930 FIX(2.613125930) +#endif + + +/* We can gain a little more speed, with a further compromise in accuracy, + * by omitting the addition in a descaling shift. This yields an incorrectly + * rounded result half the time... + */ + +#ifndef USE_ACCURATE_ROUNDING +#undef DESCALE +#define DESCALE(x,n) RIGHT_SHIFT(x, n) +#endif + + +/* Multiply a DCTELEM variable by an INT32 constant, and immediately + * descale to yield a DCTELEM result. + */ + +#define MULTIPLY(var,const) ((DCTELEM) DESCALE((var) * (const), CONST_BITS)) + + +/* Dequantize a coefficient by multiplying it by the multiplier-table + * entry; produce a DCTELEM result. For 8-bit data a 16x16->16 + * multiplication will do. For 12-bit data, the multiplier table is + * declared INT32, so a 32-bit multiply will be used. + */ + +#if BITS_IN_JSAMPLE == 8 +#define DEQUANTIZE(coef,quantval) (((IFAST_MULT_TYPE) (coef)) * (quantval)) +#else +#define DEQUANTIZE(coef,quantval) \ + DESCALE((coef)*(quantval), IFAST_SCALE_BITS-PASS1_BITS) +#endif + + +/* Like DESCALE, but applies to a DCTELEM and produces an int. + * We assume that int right shift is unsigned if INT32 right shift is. + */ + +#ifdef RIGHT_SHIFT_IS_UNSIGNED +#define ISHIFT_TEMPS DCTELEM ishift_temp; +#if BITS_IN_JSAMPLE == 8 +#define DCTELEMBITS 16 /* DCTELEM may be 16 or 32 bits */ +#else +#define DCTELEMBITS 32 /* DCTELEM must be 32 bits */ +#endif +#define IRIGHT_SHIFT(x,shft) \ + ((ishift_temp = (x)) < 0 ? \ + (ishift_temp >> (shft)) | ((~((DCTELEM) 0)) << (DCTELEMBITS-(shft))) : \ + (ishift_temp >> (shft))) +#else +#define ISHIFT_TEMPS +#define IRIGHT_SHIFT(x,shft) ((x) >> (shft)) +#endif + +#ifdef USE_ACCURATE_ROUNDING +#define IDESCALE(x,n) ((int) IRIGHT_SHIFT((x) + (1 << ((n)-1)), n)) +#else +#define IDESCALE(x,n) ((int) IRIGHT_SHIFT(x, n)) +#endif + + +/* + * Perform dequantization and inverse DCT on one block of coefficients. + */ + +GLOBAL(void) +jpeg_idct_ifast (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, + JSAMPARRAY output_buf, JDIMENSION output_col) +{ + DCTELEM tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; + DCTELEM tmp10, tmp11, tmp12, tmp13; + DCTELEM z5, z10, z11, z12, z13; + JCOEFPTR inptr; + IFAST_MULT_TYPE * quantptr; + int * wsptr; + JSAMPROW outptr; + JSAMPLE *range_limit = IDCT_range_limit(cinfo); + int ctr; + int workspace[DCTSIZE2]; /* buffers data between passes */ + SHIFT_TEMPS /* for DESCALE */ + ISHIFT_TEMPS /* for IDESCALE */ + + /* Pass 1: process columns from input, store into work array. */ + + inptr = coef_block; + quantptr = (IFAST_MULT_TYPE *) compptr->dct_table; + wsptr = workspace; + for (ctr = DCTSIZE; ctr > 0; ctr--) { + /* Due to quantization, we will usually find that many of the input + * coefficients are zero, especially the AC terms. We can exploit this + * by short-circuiting the IDCT calculation for any column in which all + * the AC terms are zero. In that case each output is equal to the + * DC coefficient (with scale factor as needed). + * With typical images and quantization tables, half or more of the + * column DCT calculations can be simplified this way. + */ + + if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 && + inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 && + inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 && + inptr[DCTSIZE*7] == 0) { + /* AC terms all zero */ + int dcval = (int) DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); + + wsptr[DCTSIZE*0] = dcval; + wsptr[DCTSIZE*1] = dcval; + wsptr[DCTSIZE*2] = dcval; + wsptr[DCTSIZE*3] = dcval; + wsptr[DCTSIZE*4] = dcval; + wsptr[DCTSIZE*5] = dcval; + wsptr[DCTSIZE*6] = dcval; + wsptr[DCTSIZE*7] = dcval; + + inptr++; /* advance pointers to next column */ + quantptr++; + wsptr++; + continue; + } + + /* Even part */ + + tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); + tmp1 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); + tmp2 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]); + tmp3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]); + + tmp10 = tmp0 + tmp2; /* phase 3 */ + tmp11 = tmp0 - tmp2; + + tmp13 = tmp1 + tmp3; /* phases 5-3 */ + tmp12 = MULTIPLY(tmp1 - tmp3, FIX_1_414213562) - tmp13; /* 2*c4 */ + + tmp0 = tmp10 + tmp13; /* phase 2 */ + tmp3 = tmp10 - tmp13; + tmp1 = tmp11 + tmp12; + tmp2 = tmp11 - tmp12; + + /* Odd part */ + + tmp4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); + tmp5 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); + tmp6 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); + tmp7 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]); + + z13 = tmp6 + tmp5; /* phase 6 */ + z10 = tmp6 - tmp5; + z11 = tmp4 + tmp7; + z12 = tmp4 - tmp7; + + tmp7 = z11 + z13; /* phase 5 */ + tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */ + + z5 = MULTIPLY(z10 + z12, FIX_1_847759065); /* 2*c2 */ + tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; /* 2*(c2-c6) */ + tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5; /* -2*(c2+c6) */ + + tmp6 = tmp12 - tmp7; /* phase 2 */ + tmp5 = tmp11 - tmp6; + tmp4 = tmp10 + tmp5; + + wsptr[DCTSIZE*0] = (int) (tmp0 + tmp7); + wsptr[DCTSIZE*7] = (int) (tmp0 - tmp7); + wsptr[DCTSIZE*1] = (int) (tmp1 + tmp6); + wsptr[DCTSIZE*6] = (int) (tmp1 - tmp6); + wsptr[DCTSIZE*2] = (int) (tmp2 + tmp5); + wsptr[DCTSIZE*5] = (int) (tmp2 - tmp5); + wsptr[DCTSIZE*4] = (int) (tmp3 + tmp4); + wsptr[DCTSIZE*3] = (int) (tmp3 - tmp4); + + inptr++; /* advance pointers to next column */ + quantptr++; + wsptr++; + } + + /* Pass 2: process rows from work array, store into output array. */ + /* Note that we must descale the results by a factor of 8 == 2**3, */ + /* and also undo the PASS1_BITS scaling. */ + + wsptr = workspace; + for (ctr = 0; ctr < DCTSIZE; ctr++) { + outptr = output_buf[ctr] + output_col; + /* Rows of zeroes can be exploited in the same way as we did with columns. + * However, the column calculation has created many nonzero AC terms, so + * the simplification applies less often (typically 5% to 10% of the time). + * On machines with very fast multiplication, it's possible that the + * test takes more time than it's worth. In that case this section + * may be commented out. + */ + +#ifndef NO_ZERO_ROW_TEST + if (wsptr[1] == 0 && wsptr[2] == 0 && wsptr[3] == 0 && wsptr[4] == 0 && + wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) { + /* AC terms all zero */ + JSAMPLE dcval = range_limit[IDESCALE(wsptr[0], PASS1_BITS+3) + & RANGE_MASK]; + + outptr[0] = dcval; + outptr[1] = dcval; + outptr[2] = dcval; + outptr[3] = dcval; + outptr[4] = dcval; + outptr[5] = dcval; + outptr[6] = dcval; + outptr[7] = dcval; + + wsptr += DCTSIZE; /* advance pointer to next row */ + continue; + } +#endif + + /* Even part */ + + tmp10 = ((DCTELEM) wsptr[0] + (DCTELEM) wsptr[4]); + tmp11 = ((DCTELEM) wsptr[0] - (DCTELEM) wsptr[4]); + + tmp13 = ((DCTELEM) wsptr[2] + (DCTELEM) wsptr[6]); + tmp12 = MULTIPLY((DCTELEM) wsptr[2] - (DCTELEM) wsptr[6], FIX_1_414213562) + - tmp13; + + tmp0 = tmp10 + tmp13; + tmp3 = tmp10 - tmp13; + tmp1 = tmp11 + tmp12; + tmp2 = tmp11 - tmp12; + + /* Odd part */ + + z13 = (DCTELEM) wsptr[5] + (DCTELEM) wsptr[3]; + z10 = (DCTELEM) wsptr[5] - (DCTELEM) wsptr[3]; + z11 = (DCTELEM) wsptr[1] + (DCTELEM) wsptr[7]; + z12 = (DCTELEM) wsptr[1] - (DCTELEM) wsptr[7]; + + tmp7 = z11 + z13; /* phase 5 */ + tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */ + + z5 = MULTIPLY(z10 + z12, FIX_1_847759065); /* 2*c2 */ + tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; /* 2*(c2-c6) */ + tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5; /* -2*(c2+c6) */ + + tmp6 = tmp12 - tmp7; /* phase 2 */ + tmp5 = tmp11 - tmp6; + tmp4 = tmp10 + tmp5; + + /* Final output stage: scale down by a factor of 8 and range-limit */ + + outptr[0] = range_limit[IDESCALE(tmp0 + tmp7, PASS1_BITS+3) + & RANGE_MASK]; + outptr[7] = range_limit[IDESCALE(tmp0 - tmp7, PASS1_BITS+3) + & RANGE_MASK]; + outptr[1] = range_limit[IDESCALE(tmp1 + tmp6, PASS1_BITS+3) + & RANGE_MASK]; + outptr[6] = range_limit[IDESCALE(tmp1 - tmp6, PASS1_BITS+3) + & RANGE_MASK]; + outptr[2] = range_limit[IDESCALE(tmp2 + tmp5, PASS1_BITS+3) + & RANGE_MASK]; + outptr[5] = range_limit[IDESCALE(tmp2 - tmp5, PASS1_BITS+3) + & RANGE_MASK]; + outptr[4] = range_limit[IDESCALE(tmp3 + tmp4, PASS1_BITS+3) + & RANGE_MASK]; + outptr[3] = range_limit[IDESCALE(tmp3 - tmp4, PASS1_BITS+3) + & RANGE_MASK]; + + wsptr += DCTSIZE; /* advance pointer to next row */ + } +} + +#endif /* DCT_IFAST_SUPPORTED */ diff --git a/mod/pub.mod/libjpeg.mod/jidctint.c b/mod/pub.mod/libjpeg.mod/jidctint.c new file mode 100644 index 0000000..a72b320 --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jidctint.c @@ -0,0 +1,389 @@ +/* + * jidctint.c + * + * Copyright (C) 1991-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains a slow-but-accurate integer implementation of the + * inverse DCT (Discrete Cosine Transform). In the IJG code, this routine + * must also perform dequantization of the input coefficients. + * + * A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT + * on each row (or vice versa, but it's more convenient to emit a row at + * a time). Direct algorithms are also available, but they are much more + * complex and seem not to be any faster when reduced to code. + * + * This implementation is based on an algorithm described in + * C. Loeffler, A. Ligtenberg and G. Moschytz, "Practical Fast 1-D DCT + * Algorithms with 11 Multiplications", Proc. Int'l. Conf. on Acoustics, + * Speech, and Signal Processing 1989 (ICASSP '89), pp. 988-991. + * The primary algorithm described there uses 11 multiplies and 29 adds. + * We use their alternate method with 12 multiplies and 32 adds. + * The advantage of this method is that no data path contains more than one + * multiplication; this allows a very simple and accurate implementation in + * scaled fixed-point arithmetic, with a minimal number of shifts. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdct.h" /* Private declarations for DCT subsystem */ + +#ifdef DCT_ISLOW_SUPPORTED + + +/* + * This module is specialized to the case DCTSIZE = 8. + */ + +#if DCTSIZE != 8 + Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */ +#endif + + +/* + * The poop on this scaling stuff is as follows: + * + * Each 1-D IDCT step produces outputs which are a factor of sqrt(N) + * larger than the true IDCT outputs. The final outputs are therefore + * a factor of N larger than desired; since N=8 this can be cured by + * a simple right shift at the end of the algorithm. The advantage of + * this arrangement is that we save two multiplications per 1-D IDCT, + * because the y0 and y4 inputs need not be divided by sqrt(N). + * + * We have to do addition and subtraction of the integer inputs, which + * is no problem, and multiplication by fractional constants, which is + * a problem to do in integer arithmetic. We multiply all the constants + * by CONST_SCALE and convert them to integer constants (thus retaining + * CONST_BITS bits of precision in the constants). After doing a + * multiplication we have to divide the product by CONST_SCALE, with proper + * rounding, to produce the correct output. This division can be done + * cheaply as a right shift of CONST_BITS bits. We postpone shifting + * as long as possible so that partial sums can be added together with + * full fractional precision. + * + * The outputs of the first pass are scaled up by PASS1_BITS bits so that + * they are represented to better-than-integral precision. These outputs + * require BITS_IN_JSAMPLE + PASS1_BITS + 3 bits; this fits in a 16-bit word + * with the recommended scaling. (To scale up 12-bit sample data further, an + * intermediate INT32 array would be needed.) + * + * To avoid overflow of the 32-bit intermediate results in pass 2, we must + * have BITS_IN_JSAMPLE + CONST_BITS + PASS1_BITS <= 26. Error analysis + * shows that the values given below are the most effective. + */ + +#if BITS_IN_JSAMPLE == 8 +#define CONST_BITS 13 +#define PASS1_BITS 2 +#else +#define CONST_BITS 13 +#define PASS1_BITS 1 /* lose a little precision to avoid overflow */ +#endif + +/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus + * causing a lot of useless floating-point operations at run time. + * To get around this we use the following pre-calculated constants. + * If you change CONST_BITS you may want to add appropriate values. + * (With a reasonable C compiler, you can just rely on the FIX() macro...) + */ + +#if CONST_BITS == 13 +#define FIX_0_298631336 ((INT32) 2446) /* FIX(0.298631336) */ +#define FIX_0_390180644 ((INT32) 3196) /* FIX(0.390180644) */ +#define FIX_0_541196100 ((INT32) 4433) /* FIX(0.541196100) */ +#define FIX_0_765366865 ((INT32) 6270) /* FIX(0.765366865) */ +#define FIX_0_899976223 ((INT32) 7373) /* FIX(0.899976223) */ +#define FIX_1_175875602 ((INT32) 9633) /* FIX(1.175875602) */ +#define FIX_1_501321110 ((INT32) 12299) /* FIX(1.501321110) */ +#define FIX_1_847759065 ((INT32) 15137) /* FIX(1.847759065) */ +#define FIX_1_961570560 ((INT32) 16069) /* FIX(1.961570560) */ +#define FIX_2_053119869 ((INT32) 16819) /* FIX(2.053119869) */ +#define FIX_2_562915447 ((INT32) 20995) /* FIX(2.562915447) */ +#define FIX_3_072711026 ((INT32) 25172) /* FIX(3.072711026) */ +#else +#define FIX_0_298631336 FIX(0.298631336) +#define FIX_0_390180644 FIX(0.390180644) +#define FIX_0_541196100 FIX(0.541196100) +#define FIX_0_765366865 FIX(0.765366865) +#define FIX_0_899976223 FIX(0.899976223) +#define FIX_1_175875602 FIX(1.175875602) +#define FIX_1_501321110 FIX(1.501321110) +#define FIX_1_847759065 FIX(1.847759065) +#define FIX_1_961570560 FIX(1.961570560) +#define FIX_2_053119869 FIX(2.053119869) +#define FIX_2_562915447 FIX(2.562915447) +#define FIX_3_072711026 FIX(3.072711026) +#endif + + +/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result. + * For 8-bit samples with the recommended scaling, all the variable + * and constant values involved are no more than 16 bits wide, so a + * 16x16->32 bit multiply can be used instead of a full 32x32 multiply. + * For 12-bit samples, a full 32-bit multiplication will be needed. + */ + +#if BITS_IN_JSAMPLE == 8 +#define MULTIPLY(var,const) MULTIPLY16C16(var,const) +#else +#define MULTIPLY(var,const) ((var) * (const)) +#endif + + +/* Dequantize a coefficient by multiplying it by the multiplier-table + * entry; produce an int result. In this module, both inputs and result + * are 16 bits or less, so either int or short multiply will work. + */ + +#define DEQUANTIZE(coef,quantval) (((ISLOW_MULT_TYPE) (coef)) * (quantval)) + + +/* + * Perform dequantization and inverse DCT on one block of coefficients. + */ + +GLOBAL(void) +jpeg_idct_islow (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, + JSAMPARRAY output_buf, JDIMENSION output_col) +{ + INT32 tmp0, tmp1, tmp2, tmp3; + INT32 tmp10, tmp11, tmp12, tmp13; + INT32 z1, z2, z3, z4, z5; + JCOEFPTR inptr; + ISLOW_MULT_TYPE * quantptr; + int * wsptr; + JSAMPROW outptr; + JSAMPLE *range_limit = IDCT_range_limit(cinfo); + int ctr; + int workspace[DCTSIZE2]; /* buffers data between passes */ + SHIFT_TEMPS + + /* Pass 1: process columns from input, store into work array. */ + /* Note results are scaled up by sqrt(8) compared to a true IDCT; */ + /* furthermore, we scale the results by 2**PASS1_BITS. */ + + inptr = coef_block; + quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table; + wsptr = workspace; + for (ctr = DCTSIZE; ctr > 0; ctr--) { + /* Due to quantization, we will usually find that many of the input + * coefficients are zero, especially the AC terms. We can exploit this + * by short-circuiting the IDCT calculation for any column in which all + * the AC terms are zero. In that case each output is equal to the + * DC coefficient (with scale factor as needed). + * With typical images and quantization tables, half or more of the + * column DCT calculations can be simplified this way. + */ + + if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 && + inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 && + inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 && + inptr[DCTSIZE*7] == 0) { + /* AC terms all zero */ + int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS; + + wsptr[DCTSIZE*0] = dcval; + wsptr[DCTSIZE*1] = dcval; + wsptr[DCTSIZE*2] = dcval; + wsptr[DCTSIZE*3] = dcval; + wsptr[DCTSIZE*4] = dcval; + wsptr[DCTSIZE*5] = dcval; + wsptr[DCTSIZE*6] = dcval; + wsptr[DCTSIZE*7] = dcval; + + inptr++; /* advance pointers to next column */ + quantptr++; + wsptr++; + continue; + } + + /* Even part: reverse the even part of the forward DCT. */ + /* The rotator is sqrt(2)*c(-6). */ + + z2 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); + z3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]); + + z1 = MULTIPLY(z2 + z3, FIX_0_541196100); + tmp2 = z1 + MULTIPLY(z3, - FIX_1_847759065); + tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865); + + z2 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); + z3 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]); + + tmp0 = (z2 + z3) << CONST_BITS; + tmp1 = (z2 - z3) << CONST_BITS; + + tmp10 = tmp0 + tmp3; + tmp13 = tmp0 - tmp3; + tmp11 = tmp1 + tmp2; + tmp12 = tmp1 - tmp2; + + /* Odd part per figure 8; the matrix is unitary and hence its + * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. + */ + + tmp0 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]); + tmp1 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); + tmp2 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); + tmp3 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); + + z1 = tmp0 + tmp3; + z2 = tmp1 + tmp2; + z3 = tmp0 + tmp2; + z4 = tmp1 + tmp3; + z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */ + + tmp0 = MULTIPLY(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */ + tmp1 = MULTIPLY(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */ + tmp2 = MULTIPLY(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */ + tmp3 = MULTIPLY(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */ + z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */ + z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */ + z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */ + z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */ + + z3 += z5; + z4 += z5; + + tmp0 += z1 + z3; + tmp1 += z2 + z4; + tmp2 += z2 + z3; + tmp3 += z1 + z4; + + /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */ + + wsptr[DCTSIZE*0] = (int) DESCALE(tmp10 + tmp3, CONST_BITS-PASS1_BITS); + wsptr[DCTSIZE*7] = (int) DESCALE(tmp10 - tmp3, CONST_BITS-PASS1_BITS); + wsptr[DCTSIZE*1] = (int) DESCALE(tmp11 + tmp2, CONST_BITS-PASS1_BITS); + wsptr[DCTSIZE*6] = (int) DESCALE(tmp11 - tmp2, CONST_BITS-PASS1_BITS); + wsptr[DCTSIZE*2] = (int) DESCALE(tmp12 + tmp1, CONST_BITS-PASS1_BITS); + wsptr[DCTSIZE*5] = (int) DESCALE(tmp12 - tmp1, CONST_BITS-PASS1_BITS); + wsptr[DCTSIZE*3] = (int) DESCALE(tmp13 + tmp0, CONST_BITS-PASS1_BITS); + wsptr[DCTSIZE*4] = (int) DESCALE(tmp13 - tmp0, CONST_BITS-PASS1_BITS); + + inptr++; /* advance pointers to next column */ + quantptr++; + wsptr++; + } + + /* Pass 2: process rows from work array, store into output array. */ + /* Note that we must descale the results by a factor of 8 == 2**3, */ + /* and also undo the PASS1_BITS scaling. */ + + wsptr = workspace; + for (ctr = 0; ctr < DCTSIZE; ctr++) { + outptr = output_buf[ctr] + output_col; + /* Rows of zeroes can be exploited in the same way as we did with columns. + * However, the column calculation has created many nonzero AC terms, so + * the simplification applies less often (typically 5% to 10% of the time). + * On machines with very fast multiplication, it's possible that the + * test takes more time than it's worth. In that case this section + * may be commented out. + */ + +#ifndef NO_ZERO_ROW_TEST + if (wsptr[1] == 0 && wsptr[2] == 0 && wsptr[3] == 0 && wsptr[4] == 0 && + wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) { + /* AC terms all zero */ + JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3) + & RANGE_MASK]; + + outptr[0] = dcval; + outptr[1] = dcval; + outptr[2] = dcval; + outptr[3] = dcval; + outptr[4] = dcval; + outptr[5] = dcval; + outptr[6] = dcval; + outptr[7] = dcval; + + wsptr += DCTSIZE; /* advance pointer to next row */ + continue; + } +#endif + + /* Even part: reverse the even part of the forward DCT. */ + /* The rotator is sqrt(2)*c(-6). */ + + z2 = (INT32) wsptr[2]; + z3 = (INT32) wsptr[6]; + + z1 = MULTIPLY(z2 + z3, FIX_0_541196100); + tmp2 = z1 + MULTIPLY(z3, - FIX_1_847759065); + tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865); + + tmp0 = ((INT32) wsptr[0] + (INT32) wsptr[4]) << CONST_BITS; + tmp1 = ((INT32) wsptr[0] - (INT32) wsptr[4]) << CONST_BITS; + + tmp10 = tmp0 + tmp3; + tmp13 = tmp0 - tmp3; + tmp11 = tmp1 + tmp2; + tmp12 = tmp1 - tmp2; + + /* Odd part per figure 8; the matrix is unitary and hence its + * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. + */ + + tmp0 = (INT32) wsptr[7]; + tmp1 = (INT32) wsptr[5]; + tmp2 = (INT32) wsptr[3]; + tmp3 = (INT32) wsptr[1]; + + z1 = tmp0 + tmp3; + z2 = tmp1 + tmp2; + z3 = tmp0 + tmp2; + z4 = tmp1 + tmp3; + z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */ + + tmp0 = MULTIPLY(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */ + tmp1 = MULTIPLY(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */ + tmp2 = MULTIPLY(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */ + tmp3 = MULTIPLY(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */ + z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */ + z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */ + z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */ + z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */ + + z3 += z5; + z4 += z5; + + tmp0 += z1 + z3; + tmp1 += z2 + z4; + tmp2 += z2 + z3; + tmp3 += z1 + z4; + + /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */ + + outptr[0] = range_limit[(int) DESCALE(tmp10 + tmp3, + CONST_BITS+PASS1_BITS+3) + & RANGE_MASK]; + outptr[7] = range_limit[(int) DESCALE(tmp10 - tmp3, + CONST_BITS+PASS1_BITS+3) + & RANGE_MASK]; + outptr[1] = range_limit[(int) DESCALE(tmp11 + tmp2, + CONST_BITS+PASS1_BITS+3) + & RANGE_MASK]; + outptr[6] = range_limit[(int) DESCALE(tmp11 - tmp2, + CONST_BITS+PASS1_BITS+3) + & RANGE_MASK]; + outptr[2] = range_limit[(int) DESCALE(tmp12 + tmp1, + CONST_BITS+PASS1_BITS+3) + & RANGE_MASK]; + outptr[5] = range_limit[(int) DESCALE(tmp12 - tmp1, + CONST_BITS+PASS1_BITS+3) + & RANGE_MASK]; + outptr[3] = range_limit[(int) DESCALE(tmp13 + tmp0, + CONST_BITS+PASS1_BITS+3) + & RANGE_MASK]; + outptr[4] = range_limit[(int) DESCALE(tmp13 - tmp0, + CONST_BITS+PASS1_BITS+3) + & RANGE_MASK]; + + wsptr += DCTSIZE; /* advance pointer to next row */ + } +} + +#endif /* DCT_ISLOW_SUPPORTED */ diff --git a/mod/pub.mod/libjpeg.mod/jidctred.c b/mod/pub.mod/libjpeg.mod/jidctred.c new file mode 100644 index 0000000..421f3c7 --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jidctred.c @@ -0,0 +1,398 @@ +/* + * jidctred.c + * + * Copyright (C) 1994-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains inverse-DCT routines that produce reduced-size output: + * either 4x4, 2x2, or 1x1 pixels from an 8x8 DCT block. + * + * The implementation is based on the Loeffler, Ligtenberg and Moschytz (LL&M) + * algorithm used in jidctint.c. We simply replace each 8-to-8 1-D IDCT step + * with an 8-to-4 step that produces the four averages of two adjacent outputs + * (or an 8-to-2 step producing two averages of four outputs, for 2x2 output). + * These steps were derived by computing the corresponding values at the end + * of the normal LL&M code, then simplifying as much as possible. + * + * 1x1 is trivial: just take the DC coefficient divided by 8. + * + * See jidctint.c for additional comments. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdct.h" /* Private declarations for DCT subsystem */ + +#ifdef IDCT_SCALING_SUPPORTED + + +/* + * This module is specialized to the case DCTSIZE = 8. + */ + +#if DCTSIZE != 8 + Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */ +#endif + + +/* Scaling is the same as in jidctint.c. */ + +#if BITS_IN_JSAMPLE == 8 +#define CONST_BITS 13 +#define PASS1_BITS 2 +#else +#define CONST_BITS 13 +#define PASS1_BITS 1 /* lose a little precision to avoid overflow */ +#endif + +/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus + * causing a lot of useless floating-point operations at run time. + * To get around this we use the following pre-calculated constants. + * If you change CONST_BITS you may want to add appropriate values. + * (With a reasonable C compiler, you can just rely on the FIX() macro...) + */ + +#if CONST_BITS == 13 +#define FIX_0_211164243 ((INT32) 1730) /* FIX(0.211164243) */ +#define FIX_0_509795579 ((INT32) 4176) /* FIX(0.509795579) */ +#define FIX_0_601344887 ((INT32) 4926) /* FIX(0.601344887) */ +#define FIX_0_720959822 ((INT32) 5906) /* FIX(0.720959822) */ +#define FIX_0_765366865 ((INT32) 6270) /* FIX(0.765366865) */ +#define FIX_0_850430095 ((INT32) 6967) /* FIX(0.850430095) */ +#define FIX_0_899976223 ((INT32) 7373) /* FIX(0.899976223) */ +#define FIX_1_061594337 ((INT32) 8697) /* FIX(1.061594337) */ +#define FIX_1_272758580 ((INT32) 10426) /* FIX(1.272758580) */ +#define FIX_1_451774981 ((INT32) 11893) /* FIX(1.451774981) */ +#define FIX_1_847759065 ((INT32) 15137) /* FIX(1.847759065) */ +#define FIX_2_172734803 ((INT32) 17799) /* FIX(2.172734803) */ +#define FIX_2_562915447 ((INT32) 20995) /* FIX(2.562915447) */ +#define FIX_3_624509785 ((INT32) 29692) /* FIX(3.624509785) */ +#else +#define FIX_0_211164243 FIX(0.211164243) +#define FIX_0_509795579 FIX(0.509795579) +#define FIX_0_601344887 FIX(0.601344887) +#define FIX_0_720959822 FIX(0.720959822) +#define FIX_0_765366865 FIX(0.765366865) +#define FIX_0_850430095 FIX(0.850430095) +#define FIX_0_899976223 FIX(0.899976223) +#define FIX_1_061594337 FIX(1.061594337) +#define FIX_1_272758580 FIX(1.272758580) +#define FIX_1_451774981 FIX(1.451774981) +#define FIX_1_847759065 FIX(1.847759065) +#define FIX_2_172734803 FIX(2.172734803) +#define FIX_2_562915447 FIX(2.562915447) +#define FIX_3_624509785 FIX(3.624509785) +#endif + + +/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result. + * For 8-bit samples with the recommended scaling, all the variable + * and constant values involved are no more than 16 bits wide, so a + * 16x16->32 bit multiply can be used instead of a full 32x32 multiply. + * For 12-bit samples, a full 32-bit multiplication will be needed. + */ + +#if BITS_IN_JSAMPLE == 8 +#define MULTIPLY(var,const) MULTIPLY16C16(var,const) +#else +#define MULTIPLY(var,const) ((var) * (const)) +#endif + + +/* Dequantize a coefficient by multiplying it by the multiplier-table + * entry; produce an int result. In this module, both inputs and result + * are 16 bits or less, so either int or short multiply will work. + */ + +#define DEQUANTIZE(coef,quantval) (((ISLOW_MULT_TYPE) (coef)) * (quantval)) + + +/* + * Perform dequantization and inverse DCT on one block of coefficients, + * producing a reduced-size 4x4 output block. + */ + +GLOBAL(void) +jpeg_idct_4x4 (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, + JSAMPARRAY output_buf, JDIMENSION output_col) +{ + INT32 tmp0, tmp2, tmp10, tmp12; + INT32 z1, z2, z3, z4; + JCOEFPTR inptr; + ISLOW_MULT_TYPE * quantptr; + int * wsptr; + JSAMPROW outptr; + JSAMPLE *range_limit = IDCT_range_limit(cinfo); + int ctr; + int workspace[DCTSIZE*4]; /* buffers data between passes */ + SHIFT_TEMPS + + /* Pass 1: process columns from input, store into work array. */ + + inptr = coef_block; + quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table; + wsptr = workspace; + for (ctr = DCTSIZE; ctr > 0; inptr++, quantptr++, wsptr++, ctr--) { + /* Don't bother to process column 4, because second pass won't use it */ + if (ctr == DCTSIZE-4) + continue; + if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 && + inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*5] == 0 && + inptr[DCTSIZE*6] == 0 && inptr[DCTSIZE*7] == 0) { + /* AC terms all zero; we need not examine term 4 for 4x4 output */ + int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS; + + wsptr[DCTSIZE*0] = dcval; + wsptr[DCTSIZE*1] = dcval; + wsptr[DCTSIZE*2] = dcval; + wsptr[DCTSIZE*3] = dcval; + + continue; + } + + /* Even part */ + + tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); + tmp0 <<= (CONST_BITS+1); + + z2 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); + z3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]); + + tmp2 = MULTIPLY(z2, FIX_1_847759065) + MULTIPLY(z3, - FIX_0_765366865); + + tmp10 = tmp0 + tmp2; + tmp12 = tmp0 - tmp2; + + /* Odd part */ + + z1 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]); + z2 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); + z3 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); + z4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); + + tmp0 = MULTIPLY(z1, - FIX_0_211164243) /* sqrt(2) * (c3-c1) */ + + MULTIPLY(z2, FIX_1_451774981) /* sqrt(2) * (c3+c7) */ + + MULTIPLY(z3, - FIX_2_172734803) /* sqrt(2) * (-c1-c5) */ + + MULTIPLY(z4, FIX_1_061594337); /* sqrt(2) * (c5+c7) */ + + tmp2 = MULTIPLY(z1, - FIX_0_509795579) /* sqrt(2) * (c7-c5) */ + + MULTIPLY(z2, - FIX_0_601344887) /* sqrt(2) * (c5-c1) */ + + MULTIPLY(z3, FIX_0_899976223) /* sqrt(2) * (c3-c7) */ + + MULTIPLY(z4, FIX_2_562915447); /* sqrt(2) * (c1+c3) */ + + /* Final output stage */ + + wsptr[DCTSIZE*0] = (int) DESCALE(tmp10 + tmp2, CONST_BITS-PASS1_BITS+1); + wsptr[DCTSIZE*3] = (int) DESCALE(tmp10 - tmp2, CONST_BITS-PASS1_BITS+1); + wsptr[DCTSIZE*1] = (int) DESCALE(tmp12 + tmp0, CONST_BITS-PASS1_BITS+1); + wsptr[DCTSIZE*2] = (int) DESCALE(tmp12 - tmp0, CONST_BITS-PASS1_BITS+1); + } + + /* Pass 2: process 4 rows from work array, store into output array. */ + + wsptr = workspace; + for (ctr = 0; ctr < 4; ctr++) { + outptr = output_buf[ctr] + output_col; + /* It's not clear whether a zero row test is worthwhile here ... */ + +#ifndef NO_ZERO_ROW_TEST + if (wsptr[1] == 0 && wsptr[2] == 0 && wsptr[3] == 0 && + wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) { + /* AC terms all zero */ + JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3) + & RANGE_MASK]; + + outptr[0] = dcval; + outptr[1] = dcval; + outptr[2] = dcval; + outptr[3] = dcval; + + wsptr += DCTSIZE; /* advance pointer to next row */ + continue; + } +#endif + + /* Even part */ + + tmp0 = ((INT32) wsptr[0]) << (CONST_BITS+1); + + tmp2 = MULTIPLY((INT32) wsptr[2], FIX_1_847759065) + + MULTIPLY((INT32) wsptr[6], - FIX_0_765366865); + + tmp10 = tmp0 + tmp2; + tmp12 = tmp0 - tmp2; + + /* Odd part */ + + z1 = (INT32) wsptr[7]; + z2 = (INT32) wsptr[5]; + z3 = (INT32) wsptr[3]; + z4 = (INT32) wsptr[1]; + + tmp0 = MULTIPLY(z1, - FIX_0_211164243) /* sqrt(2) * (c3-c1) */ + + MULTIPLY(z2, FIX_1_451774981) /* sqrt(2) * (c3+c7) */ + + MULTIPLY(z3, - FIX_2_172734803) /* sqrt(2) * (-c1-c5) */ + + MULTIPLY(z4, FIX_1_061594337); /* sqrt(2) * (c5+c7) */ + + tmp2 = MULTIPLY(z1, - FIX_0_509795579) /* sqrt(2) * (c7-c5) */ + + MULTIPLY(z2, - FIX_0_601344887) /* sqrt(2) * (c5-c1) */ + + MULTIPLY(z3, FIX_0_899976223) /* sqrt(2) * (c3-c7) */ + + MULTIPLY(z4, FIX_2_562915447); /* sqrt(2) * (c1+c3) */ + + /* Final output stage */ + + outptr[0] = range_limit[(int) DESCALE(tmp10 + tmp2, + CONST_BITS+PASS1_BITS+3+1) + & RANGE_MASK]; + outptr[3] = range_limit[(int) DESCALE(tmp10 - tmp2, + CONST_BITS+PASS1_BITS+3+1) + & RANGE_MASK]; + outptr[1] = range_limit[(int) DESCALE(tmp12 + tmp0, + CONST_BITS+PASS1_BITS+3+1) + & RANGE_MASK]; + outptr[2] = range_limit[(int) DESCALE(tmp12 - tmp0, + CONST_BITS+PASS1_BITS+3+1) + & RANGE_MASK]; + + wsptr += DCTSIZE; /* advance pointer to next row */ + } +} + + +/* + * Perform dequantization and inverse DCT on one block of coefficients, + * producing a reduced-size 2x2 output block. + */ + +GLOBAL(void) +jpeg_idct_2x2 (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, + JSAMPARRAY output_buf, JDIMENSION output_col) +{ + INT32 tmp0, tmp10, z1; + JCOEFPTR inptr; + ISLOW_MULT_TYPE * quantptr; + int * wsptr; + JSAMPROW outptr; + JSAMPLE *range_limit = IDCT_range_limit(cinfo); + int ctr; + int workspace[DCTSIZE*2]; /* buffers data between passes */ + SHIFT_TEMPS + + /* Pass 1: process columns from input, store into work array. */ + + inptr = coef_block; + quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table; + wsptr = workspace; + for (ctr = DCTSIZE; ctr > 0; inptr++, quantptr++, wsptr++, ctr--) { + /* Don't bother to process columns 2,4,6 */ + if (ctr == DCTSIZE-2 || ctr == DCTSIZE-4 || ctr == DCTSIZE-6) + continue; + if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*3] == 0 && + inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*7] == 0) { + /* AC terms all zero; we need not examine terms 2,4,6 for 2x2 output */ + int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS; + + wsptr[DCTSIZE*0] = dcval; + wsptr[DCTSIZE*1] = dcval; + + continue; + } + + /* Even part */ + + z1 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); + tmp10 = z1 << (CONST_BITS+2); + + /* Odd part */ + + z1 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]); + tmp0 = MULTIPLY(z1, - FIX_0_720959822); /* sqrt(2) * (c7-c5+c3-c1) */ + z1 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); + tmp0 += MULTIPLY(z1, FIX_0_850430095); /* sqrt(2) * (-c1+c3+c5+c7) */ + z1 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); + tmp0 += MULTIPLY(z1, - FIX_1_272758580); /* sqrt(2) * (-c1+c3-c5-c7) */ + z1 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); + tmp0 += MULTIPLY(z1, FIX_3_624509785); /* sqrt(2) * (c1+c3+c5+c7) */ + + /* Final output stage */ + + wsptr[DCTSIZE*0] = (int) DESCALE(tmp10 + tmp0, CONST_BITS-PASS1_BITS+2); + wsptr[DCTSIZE*1] = (int) DESCALE(tmp10 - tmp0, CONST_BITS-PASS1_BITS+2); + } + + /* Pass 2: process 2 rows from work array, store into output array. */ + + wsptr = workspace; + for (ctr = 0; ctr < 2; ctr++) { + outptr = output_buf[ctr] + output_col; + /* It's not clear whether a zero row test is worthwhile here ... */ + +#ifndef NO_ZERO_ROW_TEST + if (wsptr[1] == 0 && wsptr[3] == 0 && wsptr[5] == 0 && wsptr[7] == 0) { + /* AC terms all zero */ + JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3) + & RANGE_MASK]; + + outptr[0] = dcval; + outptr[1] = dcval; + + wsptr += DCTSIZE; /* advance pointer to next row */ + continue; + } +#endif + + /* Even part */ + + tmp10 = ((INT32) wsptr[0]) << (CONST_BITS+2); + + /* Odd part */ + + tmp0 = MULTIPLY((INT32) wsptr[7], - FIX_0_720959822) /* sqrt(2) * (c7-c5+c3-c1) */ + + MULTIPLY((INT32) wsptr[5], FIX_0_850430095) /* sqrt(2) * (-c1+c3+c5+c7) */ + + MULTIPLY((INT32) wsptr[3], - FIX_1_272758580) /* sqrt(2) * (-c1+c3-c5-c7) */ + + MULTIPLY((INT32) wsptr[1], FIX_3_624509785); /* sqrt(2) * (c1+c3+c5+c7) */ + + /* Final output stage */ + + outptr[0] = range_limit[(int) DESCALE(tmp10 + tmp0, + CONST_BITS+PASS1_BITS+3+2) + & RANGE_MASK]; + outptr[1] = range_limit[(int) DESCALE(tmp10 - tmp0, + CONST_BITS+PASS1_BITS+3+2) + & RANGE_MASK]; + + wsptr += DCTSIZE; /* advance pointer to next row */ + } +} + + +/* + * Perform dequantization and inverse DCT on one block of coefficients, + * producing a reduced-size 1x1 output block. + */ + +GLOBAL(void) +jpeg_idct_1x1 (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, + JSAMPARRAY output_buf, JDIMENSION output_col) +{ + int dcval; + ISLOW_MULT_TYPE * quantptr; + JSAMPLE *range_limit = IDCT_range_limit(cinfo); + SHIFT_TEMPS + + /* We hardly need an inverse DCT routine for this: just take the + * average pixel value, which is one-eighth of the DC coefficient. + */ + quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table; + dcval = DEQUANTIZE(coef_block[0], quantptr[0]); + dcval = (int) DESCALE((INT32) dcval, 3); + + output_buf[0][output_col] = range_limit[dcval & RANGE_MASK]; +} + +#endif /* IDCT_SCALING_SUPPORTED */ diff --git a/mod/pub.mod/libjpeg.mod/jinclude.h b/mod/pub.mod/libjpeg.mod/jinclude.h new file mode 100644 index 0000000..7b22283 --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jinclude.h @@ -0,0 +1,99 @@ +/* + * jinclude.h + * + * Copyright (C) 1991-1994, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file exists to provide a single place to fix any problems with + * including the wrong system include files. (Common problems are taken + * care of by the standard jconfig symbols, but on really weird systems + * you may have to edit this file.) + * + * NOTE: this file is NOT intended to be included by applications using the + * JPEG library. Most applications need only include jpeglib.h. + */ + + +/* Include auto-config file to find out which system include files we need. */ + +// #include "jconfig.h" /* auto configuration options */ +#define JCONFIG_INCLUDED /* so that jpeglib.h doesn't do it again */ + +/* + * We need the NULL macro and size_t typedef. + * On an ANSI-conforming system it is sufficient to include <stddef.h>. + * Otherwise, we get them from <stdlib.h> or <stdio.h>; we may have to + * pull in <sys/types.h> as well. + * Note that the core JPEG library does not require <stdio.h>; + * only the default error handler and data source/destination modules do. + * But we must pull it in because of the references to FILE in jpeglib.h. + * You can remove those references if you want to compile without <stdio.h>. + */ + +#ifdef HAVE_STDDEF_H +#include <stddef.h> +#endif + +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif + +#ifdef NEED_SYS_TYPES_H +#include <sys/types.h> +#endif + +#include <stdio.h> + +/* + * We need memory copying and zeroing functions, plus strncpy(). + * ANSI and System V implementations declare these in <string.h>. + * BSD doesn't have the mem() functions, but it does have bcopy()/bzero(). + * Some systems may declare memset and memcpy in <memory.h>. + * + * NOTE: we assume the size parameters to these functions are of type size_t. + * Change the casts in these macros if not! + */ + +#ifdef NEED_BSD_STRINGS + +#include <strings.h> +#define MEMZERO(target,size) bzero((void *)(target), (size_t)(size)) +#define MEMCOPY(dest,src,size) bcopy((const void *)(src), (void *)(dest), (size_t)(size)) + +#else /* not BSD, assume ANSI/SysV string lib */ + +#include <string.h> +#define MEMZERO(target,size) memset((void *)(target), 0, (size_t)(size)) +#define MEMCOPY(dest,src,size) memcpy((void *)(dest), (const void *)(src), (size_t)(size)) + +#endif + +/* + * In ANSI C, and indeed any rational implementation, size_t is also the + * type returned by sizeof(). However, it seems there are some irrational + * implementations out there, in which sizeof() returns an int even though + * size_t is defined as long or unsigned long. To ensure consistent results + * we always use this SIZEOF() macro in place of using sizeof() directly. + */ + +#define SIZEOF(object) ((size_t) sizeof(object)) + +/* + * The modules that use fread() and fwrite() always invoke them through + * these macros. On some systems you may need to twiddle the argument casts. + * CAUTION: argument order is different from underlying functions! + */ + +/* + modified fread & fwrite interfaces to use BlitzMax stream IO +*/ + +extern int(*ReadStream)(void*,int,void*); +extern int(*WriteStream)(const void*,int,void*); + + +#define JFREAD(file,buf,sizeofbuf) \ + ((size_t) (ReadStream)((void *) (buf), (size_t) (sizeofbuf), (file))) +#define JFWRITE(file,buf,sizeofbuf) \ + ((size_t) (WriteStream)((const void *) (buf), (size_t) (sizeofbuf), (file))) diff --git a/mod/pub.mod/libjpeg.mod/jmemmgr.c b/mod/pub.mod/libjpeg.mod/jmemmgr.c new file mode 100644 index 0000000..d801b32 --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jmemmgr.c @@ -0,0 +1,1118 @@ +/* + * jmemmgr.c + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains the JPEG system-independent memory management + * routines. This code is usable across a wide variety of machines; most + * of the system dependencies have been isolated in a separate file. + * The major functions provided here are: + * * pool-based allocation and freeing of memory; + * * policy decisions about how to divide available memory among the + * virtual arrays; + * * control logic for swapping virtual arrays between main memory and + * backing storage. + * The separate system-dependent file provides the actual backing-storage + * access code, and it contains the policy decision about how much total + * main memory to use. + * This file is system-dependent in the sense that some of its functions + * are unnecessary in some systems. For example, if there is enough virtual + * memory so that backing storage will never be used, much of the virtual + * array control logic could be removed. (Of course, if you have that much + * memory then you shouldn't care about a little bit of unused code...) + */ + +#define JPEG_INTERNALS +#define AM_MEMORY_MANAGER /* we define jvirt_Xarray_control structs */ +#include "jinclude.h" +#include "jpeglib.h" +#include "jmemsys.h" /* import the system-dependent declarations */ + +#ifndef NO_GETENV +#ifndef HAVE_STDLIB_H /* <stdlib.h> should declare getenv() */ +extern char * getenv JPP((const char * name)); +#endif +#endif + + +/* + * Some important notes: + * The allocation routines provided here must never return NULL. + * They should exit to error_exit if unsuccessful. + * + * It's not a good idea to try to merge the sarray and barray routines, + * even though they are textually almost the same, because samples are + * usually stored as bytes while coefficients are shorts or ints. Thus, + * in machines where byte pointers have a different representation from + * word pointers, the resulting machine code could not be the same. + */ + + +/* + * Many machines require storage alignment: longs must start on 4-byte + * boundaries, doubles on 8-byte boundaries, etc. On such machines, malloc() + * always returns pointers that are multiples of the worst-case alignment + * requirement, and we had better do so too. + * There isn't any really portable way to determine the worst-case alignment + * requirement. This module assumes that the alignment requirement is + * multiples of sizeof(ALIGN_TYPE). + * By default, we define ALIGN_TYPE as double. This is necessary on some + * workstations (where doubles really do need 8-byte alignment) and will work + * fine on nearly everything. If your machine has lesser alignment needs, + * you can save a few bytes by making ALIGN_TYPE smaller. + * The only place I know of where this will NOT work is certain Macintosh + * 680x0 compilers that define double as a 10-byte IEEE extended float. + * Doing 10-byte alignment is counterproductive because longwords won't be + * aligned well. Put "#define ALIGN_TYPE long" in jconfig.h if you have + * such a compiler. + */ + +#ifndef ALIGN_TYPE /* so can override from jconfig.h */ +#define ALIGN_TYPE double +#endif + + +/* + * We allocate objects from "pools", where each pool is gotten with a single + * request to jpeg_get_small() or jpeg_get_large(). There is no per-object + * overhead within a pool, except for alignment padding. Each pool has a + * header with a link to the next pool of the same class. + * Small and large pool headers are identical except that the latter's + * link pointer must be FAR on 80x86 machines. + * Notice that the "real" header fields are union'ed with a dummy ALIGN_TYPE + * field. This forces the compiler to make SIZEOF(small_pool_hdr) a multiple + * of the alignment requirement of ALIGN_TYPE. + */ + +typedef union small_pool_struct * small_pool_ptr; + +typedef union small_pool_struct { + struct { + small_pool_ptr next; /* next in list of pools */ + size_t bytes_used; /* how many bytes already used within pool */ + size_t bytes_left; /* bytes still available in this pool */ + } hdr; + ALIGN_TYPE dummy; /* included in union to ensure alignment */ +} small_pool_hdr; + +typedef union large_pool_struct FAR * large_pool_ptr; + +typedef union large_pool_struct { + struct { + large_pool_ptr next; /* next in list of pools */ + size_t bytes_used; /* how many bytes already used within pool */ + size_t bytes_left; /* bytes still available in this pool */ + } hdr; + ALIGN_TYPE dummy; /* included in union to ensure alignment */ +} large_pool_hdr; + + +/* + * Here is the full definition of a memory manager object. + */ + +typedef struct { + struct jpeg_memory_mgr pub; /* public fields */ + + /* Each pool identifier (lifetime class) names a linked list of pools. */ + small_pool_ptr small_list[JPOOL_NUMPOOLS]; + large_pool_ptr large_list[JPOOL_NUMPOOLS]; + + /* Since we only have one lifetime class of virtual arrays, only one + * linked list is necessary (for each datatype). Note that the virtual + * array control blocks being linked together are actually stored somewhere + * in the small-pool list. + */ + jvirt_sarray_ptr virt_sarray_list; + jvirt_barray_ptr virt_barray_list; + + /* This counts total space obtained from jpeg_get_small/large */ + long total_space_allocated; + + /* alloc_sarray and alloc_barray set this value for use by virtual + * array routines. + */ + JDIMENSION last_rowsperchunk; /* from most recent alloc_sarray/barray */ +} my_memory_mgr; + +typedef my_memory_mgr * my_mem_ptr; + + +/* + * The control blocks for virtual arrays. + * Note that these blocks are allocated in the "small" pool area. + * System-dependent info for the associated backing store (if any) is hidden + * inside the backing_store_info struct. + */ + +struct jvirt_sarray_control { + JSAMPARRAY mem_buffer; /* => the in-memory buffer */ + JDIMENSION rows_in_array; /* total virtual array height */ + JDIMENSION samplesperrow; /* width of array (and of memory buffer) */ + JDIMENSION maxaccess; /* max rows accessed by access_virt_sarray */ + JDIMENSION rows_in_mem; /* height of memory buffer */ + JDIMENSION rowsperchunk; /* allocation chunk size in mem_buffer */ + JDIMENSION cur_start_row; /* first logical row # in the buffer */ + JDIMENSION first_undef_row; /* row # of first uninitialized row */ + boolean pre_zero; /* pre-zero mode requested? */ + boolean dirty; /* do current buffer contents need written? */ + boolean b_s_open; /* is backing-store data valid? */ + jvirt_sarray_ptr next; /* link to next virtual sarray control block */ + backing_store_info b_s_info; /* System-dependent control info */ +}; + +struct jvirt_barray_control { + JBLOCKARRAY mem_buffer; /* => the in-memory buffer */ + JDIMENSION rows_in_array; /* total virtual array height */ + JDIMENSION blocksperrow; /* width of array (and of memory buffer) */ + JDIMENSION maxaccess; /* max rows accessed by access_virt_barray */ + JDIMENSION rows_in_mem; /* height of memory buffer */ + JDIMENSION rowsperchunk; /* allocation chunk size in mem_buffer */ + JDIMENSION cur_start_row; /* first logical row # in the buffer */ + JDIMENSION first_undef_row; /* row # of first uninitialized row */ + boolean pre_zero; /* pre-zero mode requested? */ + boolean dirty; /* do current buffer contents need written? */ + boolean b_s_open; /* is backing-store data valid? */ + jvirt_barray_ptr next; /* link to next virtual barray control block */ + backing_store_info b_s_info; /* System-dependent control info */ +}; + + +#ifdef MEM_STATS /* optional extra stuff for statistics */ + +LOCAL(void) +print_mem_stats (j_common_ptr cinfo, int pool_id) +{ + my_mem_ptr mem = (my_mem_ptr) cinfo->mem; + small_pool_ptr shdr_ptr; + large_pool_ptr lhdr_ptr; + + /* Since this is only a debugging stub, we can cheat a little by using + * fprintf directly rather than going through the trace message code. + * This is helpful because message parm array can't handle longs. + */ + fprintf(stderr, "Freeing pool %d, total space = %ld\n", + pool_id, mem->total_space_allocated); + + for (lhdr_ptr = mem->large_list[pool_id]; lhdr_ptr != NULL; + lhdr_ptr = lhdr_ptr->hdr.next) { + fprintf(stderr, " Large chunk used %ld\n", + (long) lhdr_ptr->hdr.bytes_used); + } + + for (shdr_ptr = mem->small_list[pool_id]; shdr_ptr != NULL; + shdr_ptr = shdr_ptr->hdr.next) { + fprintf(stderr, " Small chunk used %ld free %ld\n", + (long) shdr_ptr->hdr.bytes_used, + (long) shdr_ptr->hdr.bytes_left); + } +} + +#endif /* MEM_STATS */ + + +LOCAL(void) +out_of_memory (j_common_ptr cinfo, int which) +/* Report an out-of-memory error and stop execution */ +/* If we compiled MEM_STATS support, report alloc requests before dying */ +{ +#ifdef MEM_STATS + cinfo->err->trace_level = 2; /* force self_destruct to report stats */ +#endif + ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, which); +} + + +/* + * Allocation of "small" objects. + * + * For these, we use pooled storage. When a new pool must be created, + * we try to get enough space for the current request plus a "slop" factor, + * where the slop will be the amount of leftover space in the new pool. + * The speed vs. space tradeoff is largely determined by the slop values. + * A different slop value is provided for each pool class (lifetime), + * and we also distinguish the first pool of a class from later ones. + * NOTE: the values given work fairly well on both 16- and 32-bit-int + * machines, but may be too small if longs are 64 bits or more. + */ + +static const size_t first_pool_slop[JPOOL_NUMPOOLS] = +{ + 1600, /* first PERMANENT pool */ + 16000 /* first IMAGE pool */ +}; + +static const size_t extra_pool_slop[JPOOL_NUMPOOLS] = +{ + 0, /* additional PERMANENT pools */ + 5000 /* additional IMAGE pools */ +}; + +#define MIN_SLOP 50 /* greater than 0 to avoid futile looping */ + + +METHODDEF(void *) +alloc_small (j_common_ptr cinfo, int pool_id, size_t sizeofobject) +/* Allocate a "small" object */ +{ + my_mem_ptr mem = (my_mem_ptr) cinfo->mem; + small_pool_ptr hdr_ptr, prev_hdr_ptr; + char * data_ptr; + size_t odd_bytes, min_request, slop; + + /* Check for unsatisfiable request (do now to ensure no overflow below) */ + if (sizeofobject > (size_t) (MAX_ALLOC_CHUNK-SIZEOF(small_pool_hdr))) + out_of_memory(cinfo, 1); /* request exceeds malloc's ability */ + + /* Round up the requested size to a multiple of SIZEOF(ALIGN_TYPE) */ + odd_bytes = sizeofobject % SIZEOF(ALIGN_TYPE); + if (odd_bytes > 0) + sizeofobject += SIZEOF(ALIGN_TYPE) - odd_bytes; + + /* See if space is available in any existing pool */ + if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS) + ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */ + prev_hdr_ptr = NULL; + hdr_ptr = mem->small_list[pool_id]; + while (hdr_ptr != NULL) { + if (hdr_ptr->hdr.bytes_left >= sizeofobject) + break; /* found pool with enough space */ + prev_hdr_ptr = hdr_ptr; + hdr_ptr = hdr_ptr->hdr.next; + } + + /* Time to make a new pool? */ + if (hdr_ptr == NULL) { + /* min_request is what we need now, slop is what will be leftover */ + min_request = sizeofobject + SIZEOF(small_pool_hdr); + if (prev_hdr_ptr == NULL) /* first pool in class? */ + slop = first_pool_slop[pool_id]; + else + slop = extra_pool_slop[pool_id]; + /* Don't ask for more than MAX_ALLOC_CHUNK */ + if (slop > (size_t) (MAX_ALLOC_CHUNK-min_request)) + slop = (size_t) (MAX_ALLOC_CHUNK-min_request); + /* Try to get space, if fail reduce slop and try again */ + for (;;) { + hdr_ptr = (small_pool_ptr) jpeg_get_small(cinfo, min_request + slop); + if (hdr_ptr != NULL) + break; + slop /= 2; + if (slop < MIN_SLOP) /* give up when it gets real small */ + out_of_memory(cinfo, 2); /* jpeg_get_small failed */ + } + mem->total_space_allocated += min_request + slop; + /* Success, initialize the new pool header and add to end of list */ + hdr_ptr->hdr.next = NULL; + hdr_ptr->hdr.bytes_used = 0; + hdr_ptr->hdr.bytes_left = sizeofobject + slop; + if (prev_hdr_ptr == NULL) /* first pool in class? */ + mem->small_list[pool_id] = hdr_ptr; + else + prev_hdr_ptr->hdr.next = hdr_ptr; + } + + /* OK, allocate the object from the current pool */ + data_ptr = (char *) (hdr_ptr + 1); /* point to first data byte in pool */ + data_ptr += hdr_ptr->hdr.bytes_used; /* point to place for object */ + hdr_ptr->hdr.bytes_used += sizeofobject; + hdr_ptr->hdr.bytes_left -= sizeofobject; + + return (void *) data_ptr; +} + + +/* + * Allocation of "large" objects. + * + * The external semantics of these are the same as "small" objects, + * except that FAR pointers are used on 80x86. However the pool + * management heuristics are quite different. We assume that each + * request is large enough that it may as well be passed directly to + * jpeg_get_large; the pool management just links everything together + * so that we can free it all on demand. + * Note: the major use of "large" objects is in JSAMPARRAY and JBLOCKARRAY + * structures. The routines that create these structures (see below) + * deliberately bunch rows together to ensure a large request size. + */ + +METHODDEF(void FAR *) +alloc_large (j_common_ptr cinfo, int pool_id, size_t sizeofobject) +/* Allocate a "large" object */ +{ + my_mem_ptr mem = (my_mem_ptr) cinfo->mem; + large_pool_ptr hdr_ptr; + size_t odd_bytes; + + /* Check for unsatisfiable request (do now to ensure no overflow below) */ + if (sizeofobject > (size_t) (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr))) + out_of_memory(cinfo, 3); /* request exceeds malloc's ability */ + + /* Round up the requested size to a multiple of SIZEOF(ALIGN_TYPE) */ + odd_bytes = sizeofobject % SIZEOF(ALIGN_TYPE); + if (odd_bytes > 0) + sizeofobject += SIZEOF(ALIGN_TYPE) - odd_bytes; + + /* Always make a new pool */ + if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS) + ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */ + + hdr_ptr = (large_pool_ptr) jpeg_get_large(cinfo, sizeofobject + + SIZEOF(large_pool_hdr)); + if (hdr_ptr == NULL) + out_of_memory(cinfo, 4); /* jpeg_get_large failed */ + mem->total_space_allocated += sizeofobject + SIZEOF(large_pool_hdr); + + /* Success, initialize the new pool header and add to list */ + hdr_ptr->hdr.next = mem->large_list[pool_id]; + /* We maintain space counts in each pool header for statistical purposes, + * even though they are not needed for allocation. + */ + hdr_ptr->hdr.bytes_used = sizeofobject; + hdr_ptr->hdr.bytes_left = 0; + mem->large_list[pool_id] = hdr_ptr; + + return (void FAR *) (hdr_ptr + 1); /* point to first data byte in pool */ +} + + +/* + * Creation of 2-D sample arrays. + * The pointers are in near heap, the samples themselves in FAR heap. + * + * To minimize allocation overhead and to allow I/O of large contiguous + * blocks, we allocate the sample rows in groups of as many rows as possible + * without exceeding MAX_ALLOC_CHUNK total bytes per allocation request. + * NB: the virtual array control routines, later in this file, know about + * this chunking of rows. The rowsperchunk value is left in the mem manager + * object so that it can be saved away if this sarray is the workspace for + * a virtual array. + */ + +METHODDEF(JSAMPARRAY) +alloc_sarray (j_common_ptr cinfo, int pool_id, + JDIMENSION samplesperrow, JDIMENSION numrows) +/* Allocate a 2-D sample array */ +{ + my_mem_ptr mem = (my_mem_ptr) cinfo->mem; + JSAMPARRAY result; + JSAMPROW workspace; + JDIMENSION rowsperchunk, currow, i; + long ltemp; + + /* Calculate max # of rows allowed in one allocation chunk */ + ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) / + ((long) samplesperrow * SIZEOF(JSAMPLE)); + if (ltemp <= 0) + ERREXIT(cinfo, JERR_WIDTH_OVERFLOW); + if (ltemp < (long) numrows) + rowsperchunk = (JDIMENSION) ltemp; + else + rowsperchunk = numrows; + mem->last_rowsperchunk = rowsperchunk; + + /* Get space for row pointers (small object) */ + result = (JSAMPARRAY) alloc_small(cinfo, pool_id, + (size_t) (numrows * SIZEOF(JSAMPROW))); + + /* Get the rows themselves (large objects) */ + currow = 0; + while (currow < numrows) { + rowsperchunk = MIN(rowsperchunk, numrows - currow); + workspace = (JSAMPROW) alloc_large(cinfo, pool_id, + (size_t) ((size_t) rowsperchunk * (size_t) samplesperrow + * SIZEOF(JSAMPLE))); + for (i = rowsperchunk; i > 0; i--) { + result[currow++] = workspace; + workspace += samplesperrow; + } + } + + return result; +} + + +/* + * Creation of 2-D coefficient-block arrays. + * This is essentially the same as the code for sample arrays, above. + */ + +METHODDEF(JBLOCKARRAY) +alloc_barray (j_common_ptr cinfo, int pool_id, + JDIMENSION blocksperrow, JDIMENSION numrows) +/* Allocate a 2-D coefficient-block array */ +{ + my_mem_ptr mem = (my_mem_ptr) cinfo->mem; + JBLOCKARRAY result; + JBLOCKROW workspace; + JDIMENSION rowsperchunk, currow, i; + long ltemp; + + /* Calculate max # of rows allowed in one allocation chunk */ + ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) / + ((long) blocksperrow * SIZEOF(JBLOCK)); + if (ltemp <= 0) + ERREXIT(cinfo, JERR_WIDTH_OVERFLOW); + if (ltemp < (long) numrows) + rowsperchunk = (JDIMENSION) ltemp; + else + rowsperchunk = numrows; + mem->last_rowsperchunk = rowsperchunk; + + /* Get space for row pointers (small object) */ + result = (JBLOCKARRAY) alloc_small(cinfo, pool_id, + (size_t) (numrows * SIZEOF(JBLOCKROW))); + + /* Get the rows themselves (large objects) */ + currow = 0; + while (currow < numrows) { + rowsperchunk = MIN(rowsperchunk, numrows - currow); + workspace = (JBLOCKROW) alloc_large(cinfo, pool_id, + (size_t) ((size_t) rowsperchunk * (size_t) blocksperrow + * SIZEOF(JBLOCK))); + for (i = rowsperchunk; i > 0; i--) { + result[currow++] = workspace; + workspace += blocksperrow; + } + } + + return result; +} + + +/* + * About virtual array management: + * + * The above "normal" array routines are only used to allocate strip buffers + * (as wide as the image, but just a few rows high). Full-image-sized buffers + * are handled as "virtual" arrays. The array is still accessed a strip at a + * time, but the memory manager must save the whole array for repeated + * accesses. The intended implementation is that there is a strip buffer in + * memory (as high as is possible given the desired memory limit), plus a + * backing file that holds the rest of the array. + * + * The request_virt_array routines are told the total size of the image and + * the maximum number of rows that will be accessed at once. The in-memory + * buffer must be at least as large as the maxaccess value. + * + * The request routines create control blocks but not the in-memory buffers. + * That is postponed until realize_virt_arrays is called. At that time the + * total amount of space needed is known (approximately, anyway), so free + * memory can be divided up fairly. + * + * The access_virt_array routines are responsible for making a specific strip + * area accessible (after reading or writing the backing file, if necessary). + * Note that the access routines are told whether the caller intends to modify + * the accessed strip; during a read-only pass this saves having to rewrite + * data to disk. The access routines are also responsible for pre-zeroing + * any newly accessed rows, if pre-zeroing was requested. + * + * In current usage, the access requests are usually for nonoverlapping + * strips; that is, successive access start_row numbers differ by exactly + * num_rows = maxaccess. This means we can get good performance with simple + * buffer dump/reload logic, by making the in-memory buffer be a multiple + * of the access height; then there will never be accesses across bufferload + * boundaries. The code will still work with overlapping access requests, + * but it doesn't handle bufferload overlaps very efficiently. + */ + + +METHODDEF(jvirt_sarray_ptr) +request_virt_sarray (j_common_ptr cinfo, int pool_id, boolean pre_zero, + JDIMENSION samplesperrow, JDIMENSION numrows, + JDIMENSION maxaccess) +/* Request a virtual 2-D sample array */ +{ + my_mem_ptr mem = (my_mem_ptr) cinfo->mem; + jvirt_sarray_ptr result; + + /* Only IMAGE-lifetime virtual arrays are currently supported */ + if (pool_id != JPOOL_IMAGE) + ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */ + + /* get control block */ + result = (jvirt_sarray_ptr) alloc_small(cinfo, pool_id, + SIZEOF(struct jvirt_sarray_control)); + + result->mem_buffer = NULL; /* marks array not yet realized */ + result->rows_in_array = numrows; + result->samplesperrow = samplesperrow; + result->maxaccess = maxaccess; + result->pre_zero = pre_zero; + result->b_s_open = FALSE; /* no associated backing-store object */ + result->next = mem->virt_sarray_list; /* add to list of virtual arrays */ + mem->virt_sarray_list = result; + + return result; +} + + +METHODDEF(jvirt_barray_ptr) +request_virt_barray (j_common_ptr cinfo, int pool_id, boolean pre_zero, + JDIMENSION blocksperrow, JDIMENSION numrows, + JDIMENSION maxaccess) +/* Request a virtual 2-D coefficient-block array */ +{ + my_mem_ptr mem = (my_mem_ptr) cinfo->mem; + jvirt_barray_ptr result; + + /* Only IMAGE-lifetime virtual arrays are currently supported */ + if (pool_id != JPOOL_IMAGE) + ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */ + + /* get control block */ + result = (jvirt_barray_ptr) alloc_small(cinfo, pool_id, + SIZEOF(struct jvirt_barray_control)); + + result->mem_buffer = NULL; /* marks array not yet realized */ + result->rows_in_array = numrows; + result->blocksperrow = blocksperrow; + result->maxaccess = maxaccess; + result->pre_zero = pre_zero; + result->b_s_open = FALSE; /* no associated backing-store object */ + result->next = mem->virt_barray_list; /* add to list of virtual arrays */ + mem->virt_barray_list = result; + + return result; +} + + +METHODDEF(void) +realize_virt_arrays (j_common_ptr cinfo) +/* Allocate the in-memory buffers for any unrealized virtual arrays */ +{ + my_mem_ptr mem = (my_mem_ptr) cinfo->mem; + long space_per_minheight, maximum_space, avail_mem; + long minheights, max_minheights; + jvirt_sarray_ptr sptr; + jvirt_barray_ptr bptr; + + /* Compute the minimum space needed (maxaccess rows in each buffer) + * and the maximum space needed (full image height in each buffer). + * These may be of use to the system-dependent jpeg_mem_available routine. + */ + space_per_minheight = 0; + maximum_space = 0; + for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) { + if (sptr->mem_buffer == NULL) { /* if not realized yet */ + space_per_minheight += (long) sptr->maxaccess * + (long) sptr->samplesperrow * SIZEOF(JSAMPLE); + maximum_space += (long) sptr->rows_in_array * + (long) sptr->samplesperrow * SIZEOF(JSAMPLE); + } + } + for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) { + if (bptr->mem_buffer == NULL) { /* if not realized yet */ + space_per_minheight += (long) bptr->maxaccess * + (long) bptr->blocksperrow * SIZEOF(JBLOCK); + maximum_space += (long) bptr->rows_in_array * + (long) bptr->blocksperrow * SIZEOF(JBLOCK); + } + } + + if (space_per_minheight <= 0) + return; /* no unrealized arrays, no work */ + + /* Determine amount of memory to actually use; this is system-dependent. */ + avail_mem = jpeg_mem_available(cinfo, space_per_minheight, maximum_space, + mem->total_space_allocated); + + /* If the maximum space needed is available, make all the buffers full + * height; otherwise parcel it out with the same number of minheights + * in each buffer. + */ + if (avail_mem >= maximum_space) + max_minheights = 1000000000L; + else { + max_minheights = avail_mem / space_per_minheight; + /* If there doesn't seem to be enough space, try to get the minimum + * anyway. This allows a "stub" implementation of jpeg_mem_available(). + */ + if (max_minheights <= 0) + max_minheights = 1; + } + + /* Allocate the in-memory buffers and initialize backing store as needed. */ + + for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) { + if (sptr->mem_buffer == NULL) { /* if not realized yet */ + minheights = ((long) sptr->rows_in_array - 1L) / sptr->maxaccess + 1L; + if (minheights <= max_minheights) { + /* This buffer fits in memory */ + sptr->rows_in_mem = sptr->rows_in_array; + } else { + /* It doesn't fit in memory, create backing store. */ + sptr->rows_in_mem = (JDIMENSION) (max_minheights * sptr->maxaccess); + jpeg_open_backing_store(cinfo, & sptr->b_s_info, + (long) sptr->rows_in_array * + (long) sptr->samplesperrow * + (long) SIZEOF(JSAMPLE)); + sptr->b_s_open = TRUE; + } + sptr->mem_buffer = alloc_sarray(cinfo, JPOOL_IMAGE, + sptr->samplesperrow, sptr->rows_in_mem); + sptr->rowsperchunk = mem->last_rowsperchunk; + sptr->cur_start_row = 0; + sptr->first_undef_row = 0; + sptr->dirty = FALSE; + } + } + + for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) { + if (bptr->mem_buffer == NULL) { /* if not realized yet */ + minheights = ((long) bptr->rows_in_array - 1L) / bptr->maxaccess + 1L; + if (minheights <= max_minheights) { + /* This buffer fits in memory */ + bptr->rows_in_mem = bptr->rows_in_array; + } else { + /* It doesn't fit in memory, create backing store. */ + bptr->rows_in_mem = (JDIMENSION) (max_minheights * bptr->maxaccess); + jpeg_open_backing_store(cinfo, & bptr->b_s_info, + (long) bptr->rows_in_array * + (long) bptr->blocksperrow * + (long) SIZEOF(JBLOCK)); + bptr->b_s_open = TRUE; + } + bptr->mem_buffer = alloc_barray(cinfo, JPOOL_IMAGE, + bptr->blocksperrow, bptr->rows_in_mem); + bptr->rowsperchunk = mem->last_rowsperchunk; + bptr->cur_start_row = 0; + bptr->first_undef_row = 0; + bptr->dirty = FALSE; + } + } +} + + +LOCAL(void) +do_sarray_io (j_common_ptr cinfo, jvirt_sarray_ptr ptr, boolean writing) +/* Do backing store read or write of a virtual sample array */ +{ + long bytesperrow, file_offset, byte_count, rows, thisrow, i; + + bytesperrow = (long) ptr->samplesperrow * SIZEOF(JSAMPLE); + file_offset = ptr->cur_start_row * bytesperrow; + /* Loop to read or write each allocation chunk in mem_buffer */ + for (i = 0; i < (long) ptr->rows_in_mem; i += ptr->rowsperchunk) { + /* One chunk, but check for short chunk at end of buffer */ + rows = MIN((long) ptr->rowsperchunk, (long) ptr->rows_in_mem - i); + /* Transfer no more than is currently defined */ + thisrow = (long) ptr->cur_start_row + i; + rows = MIN(rows, (long) ptr->first_undef_row - thisrow); + /* Transfer no more than fits in file */ + rows = MIN(rows, (long) ptr->rows_in_array - thisrow); + if (rows <= 0) /* this chunk might be past end of file! */ + break; + byte_count = rows * bytesperrow; + if (writing) + (*ptr->b_s_info.write_backing_store) (cinfo, & ptr->b_s_info, + (void FAR *) ptr->mem_buffer[i], + file_offset, byte_count); + else + (*ptr->b_s_info.read_backing_store) (cinfo, & ptr->b_s_info, + (void FAR *) ptr->mem_buffer[i], + file_offset, byte_count); + file_offset += byte_count; + } +} + + +LOCAL(void) +do_barray_io (j_common_ptr cinfo, jvirt_barray_ptr ptr, boolean writing) +/* Do backing store read or write of a virtual coefficient-block array */ +{ + long bytesperrow, file_offset, byte_count, rows, thisrow, i; + + bytesperrow = (long) ptr->blocksperrow * SIZEOF(JBLOCK); + file_offset = ptr->cur_start_row * bytesperrow; + /* Loop to read or write each allocation chunk in mem_buffer */ + for (i = 0; i < (long) ptr->rows_in_mem; i += ptr->rowsperchunk) { + /* One chunk, but check for short chunk at end of buffer */ + rows = MIN((long) ptr->rowsperchunk, (long) ptr->rows_in_mem - i); + /* Transfer no more than is currently defined */ + thisrow = (long) ptr->cur_start_row + i; + rows = MIN(rows, (long) ptr->first_undef_row - thisrow); + /* Transfer no more than fits in file */ + rows = MIN(rows, (long) ptr->rows_in_array - thisrow); + if (rows <= 0) /* this chunk might be past end of file! */ + break; + byte_count = rows * bytesperrow; + if (writing) + (*ptr->b_s_info.write_backing_store) (cinfo, & ptr->b_s_info, + (void FAR *) ptr->mem_buffer[i], + file_offset, byte_count); + else + (*ptr->b_s_info.read_backing_store) (cinfo, & ptr->b_s_info, + (void FAR *) ptr->mem_buffer[i], + file_offset, byte_count); + file_offset += byte_count; + } +} + + +METHODDEF(JSAMPARRAY) +access_virt_sarray (j_common_ptr cinfo, jvirt_sarray_ptr ptr, + JDIMENSION start_row, JDIMENSION num_rows, + boolean writable) +/* Access the part of a virtual sample array starting at start_row */ +/* and extending for num_rows rows. writable is true if */ +/* caller intends to modify the accessed area. */ +{ + JDIMENSION end_row = start_row + num_rows; + JDIMENSION undef_row; + + /* debugging check */ + if (end_row > ptr->rows_in_array || num_rows > ptr->maxaccess || + ptr->mem_buffer == NULL) + ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); + + /* Make the desired part of the virtual array accessible */ + if (start_row < ptr->cur_start_row || + end_row > ptr->cur_start_row+ptr->rows_in_mem) { + if (! ptr->b_s_open) + ERREXIT(cinfo, JERR_VIRTUAL_BUG); + /* Flush old buffer contents if necessary */ + if (ptr->dirty) { + do_sarray_io(cinfo, ptr, TRUE); + ptr->dirty = FALSE; + } + /* Decide what part of virtual array to access. + * Algorithm: if target address > current window, assume forward scan, + * load starting at target address. If target address < current window, + * assume backward scan, load so that target area is top of window. + * Note that when switching from forward write to forward read, will have + * start_row = 0, so the limiting case applies and we load from 0 anyway. + */ + if (start_row > ptr->cur_start_row) { + ptr->cur_start_row = start_row; + } else { + /* use long arithmetic here to avoid overflow & unsigned problems */ + long ltemp; + + ltemp = (long) end_row - (long) ptr->rows_in_mem; + if (ltemp < 0) + ltemp = 0; /* don't fall off front end of file */ + ptr->cur_start_row = (JDIMENSION) ltemp; + } + /* Read in the selected part of the array. + * During the initial write pass, we will do no actual read + * because the selected part is all undefined. + */ + do_sarray_io(cinfo, ptr, FALSE); + } + /* Ensure the accessed part of the array is defined; prezero if needed. + * To improve locality of access, we only prezero the part of the array + * that the caller is about to access, not the entire in-memory array. + */ + if (ptr->first_undef_row < end_row) { + if (ptr->first_undef_row < start_row) { + if (writable) /* writer skipped over a section of array */ + ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); + undef_row = start_row; /* but reader is allowed to read ahead */ + } else { + undef_row = ptr->first_undef_row; + } + if (writable) + ptr->first_undef_row = end_row; + if (ptr->pre_zero) { + size_t bytesperrow = (size_t) ptr->samplesperrow * SIZEOF(JSAMPLE); + undef_row -= ptr->cur_start_row; /* make indexes relative to buffer */ + end_row -= ptr->cur_start_row; + while (undef_row < end_row) { + jzero_far((void FAR *) ptr->mem_buffer[undef_row], bytesperrow); + undef_row++; + } + } else { + if (! writable) /* reader looking at undefined data */ + ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); + } + } + /* Flag the buffer dirty if caller will write in it */ + if (writable) + ptr->dirty = TRUE; + /* Return address of proper part of the buffer */ + return ptr->mem_buffer + (start_row - ptr->cur_start_row); +} + + +METHODDEF(JBLOCKARRAY) +access_virt_barray (j_common_ptr cinfo, jvirt_barray_ptr ptr, + JDIMENSION start_row, JDIMENSION num_rows, + boolean writable) +/* Access the part of a virtual block array starting at start_row */ +/* and extending for num_rows rows. writable is true if */ +/* caller intends to modify the accessed area. */ +{ + JDIMENSION end_row = start_row + num_rows; + JDIMENSION undef_row; + + /* debugging check */ + if (end_row > ptr->rows_in_array || num_rows > ptr->maxaccess || + ptr->mem_buffer == NULL) + ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); + + /* Make the desired part of the virtual array accessible */ + if (start_row < ptr->cur_start_row || + end_row > ptr->cur_start_row+ptr->rows_in_mem) { + if (! ptr->b_s_open) + ERREXIT(cinfo, JERR_VIRTUAL_BUG); + /* Flush old buffer contents if necessary */ + if (ptr->dirty) { + do_barray_io(cinfo, ptr, TRUE); + ptr->dirty = FALSE; + } + /* Decide what part of virtual array to access. + * Algorithm: if target address > current window, assume forward scan, + * load starting at target address. If target address < current window, + * assume backward scan, load so that target area is top of window. + * Note that when switching from forward write to forward read, will have + * start_row = 0, so the limiting case applies and we load from 0 anyway. + */ + if (start_row > ptr->cur_start_row) { + ptr->cur_start_row = start_row; + } else { + /* use long arithmetic here to avoid overflow & unsigned problems */ + long ltemp; + + ltemp = (long) end_row - (long) ptr->rows_in_mem; + if (ltemp < 0) + ltemp = 0; /* don't fall off front end of file */ + ptr->cur_start_row = (JDIMENSION) ltemp; + } + /* Read in the selected part of the array. + * During the initial write pass, we will do no actual read + * because the selected part is all undefined. + */ + do_barray_io(cinfo, ptr, FALSE); + } + /* Ensure the accessed part of the array is defined; prezero if needed. + * To improve locality of access, we only prezero the part of the array + * that the caller is about to access, not the entire in-memory array. + */ + if (ptr->first_undef_row < end_row) { + if (ptr->first_undef_row < start_row) { + if (writable) /* writer skipped over a section of array */ + ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); + undef_row = start_row; /* but reader is allowed to read ahead */ + } else { + undef_row = ptr->first_undef_row; + } + if (writable) + ptr->first_undef_row = end_row; + if (ptr->pre_zero) { + size_t bytesperrow = (size_t) ptr->blocksperrow * SIZEOF(JBLOCK); + undef_row -= ptr->cur_start_row; /* make indexes relative to buffer */ + end_row -= ptr->cur_start_row; + while (undef_row < end_row) { + jzero_far((void FAR *) ptr->mem_buffer[undef_row], bytesperrow); + undef_row++; + } + } else { + if (! writable) /* reader looking at undefined data */ + ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); + } + } + /* Flag the buffer dirty if caller will write in it */ + if (writable) + ptr->dirty = TRUE; + /* Return address of proper part of the buffer */ + return ptr->mem_buffer + (start_row - ptr->cur_start_row); +} + + +/* + * Release all objects belonging to a specified pool. + */ + +METHODDEF(void) +free_pool (j_common_ptr cinfo, int pool_id) +{ + my_mem_ptr mem = (my_mem_ptr) cinfo->mem; + small_pool_ptr shdr_ptr; + large_pool_ptr lhdr_ptr; + size_t space_freed; + + if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS) + ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */ + +#ifdef MEM_STATS + if (cinfo->err->trace_level > 1) + print_mem_stats(cinfo, pool_id); /* print pool's memory usage statistics */ +#endif + + /* If freeing IMAGE pool, close any virtual arrays first */ + if (pool_id == JPOOL_IMAGE) { + jvirt_sarray_ptr sptr; + jvirt_barray_ptr bptr; + + for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) { + if (sptr->b_s_open) { /* there may be no backing store */ + sptr->b_s_open = FALSE; /* prevent recursive close if error */ + (*sptr->b_s_info.close_backing_store) (cinfo, & sptr->b_s_info); + } + } + mem->virt_sarray_list = NULL; + for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) { + if (bptr->b_s_open) { /* there may be no backing store */ + bptr->b_s_open = FALSE; /* prevent recursive close if error */ + (*bptr->b_s_info.close_backing_store) (cinfo, & bptr->b_s_info); + } + } + mem->virt_barray_list = NULL; + } + + /* Release large objects */ + lhdr_ptr = mem->large_list[pool_id]; + mem->large_list[pool_id] = NULL; + + while (lhdr_ptr != NULL) { + large_pool_ptr next_lhdr_ptr = lhdr_ptr->hdr.next; + space_freed = lhdr_ptr->hdr.bytes_used + + lhdr_ptr->hdr.bytes_left + + SIZEOF(large_pool_hdr); + jpeg_free_large(cinfo, (void FAR *) lhdr_ptr, space_freed); + mem->total_space_allocated -= space_freed; + lhdr_ptr = next_lhdr_ptr; + } + + /* Release small objects */ + shdr_ptr = mem->small_list[pool_id]; + mem->small_list[pool_id] = NULL; + + while (shdr_ptr != NULL) { + small_pool_ptr next_shdr_ptr = shdr_ptr->hdr.next; + space_freed = shdr_ptr->hdr.bytes_used + + shdr_ptr->hdr.bytes_left + + SIZEOF(small_pool_hdr); + jpeg_free_small(cinfo, (void *) shdr_ptr, space_freed); + mem->total_space_allocated -= space_freed; + shdr_ptr = next_shdr_ptr; + } +} + + +/* + * Close up shop entirely. + * Note that this cannot be called unless cinfo->mem is non-NULL. + */ + +METHODDEF(void) +self_destruct (j_common_ptr cinfo) +{ + int pool; + + /* Close all backing store, release all memory. + * Releasing pools in reverse order might help avoid fragmentation + * with some (brain-damaged) malloc libraries. + */ + for (pool = JPOOL_NUMPOOLS-1; pool >= JPOOL_PERMANENT; pool--) { + free_pool(cinfo, pool); + } + + /* Release the memory manager control block too. */ + jpeg_free_small(cinfo, (void *) cinfo->mem, SIZEOF(my_memory_mgr)); + cinfo->mem = NULL; /* ensures I will be called only once */ + + jpeg_mem_term(cinfo); /* system-dependent cleanup */ +} + + +/* + * Memory manager initialization. + * When this is called, only the error manager pointer is valid in cinfo! + */ + +GLOBAL(void) +jinit_memory_mgr (j_common_ptr cinfo) +{ + my_mem_ptr mem; + long max_to_use; + int pool; + size_t test_mac; + + cinfo->mem = NULL; /* for safety if init fails */ + + /* Check for configuration errors. + * SIZEOF(ALIGN_TYPE) should be a power of 2; otherwise, it probably + * doesn't reflect any real hardware alignment requirement. + * The test is a little tricky: for X>0, X and X-1 have no one-bits + * in common if and only if X is a power of 2, ie has only one one-bit. + * Some compilers may give an "unreachable code" warning here; ignore it. + */ + if ((SIZEOF(ALIGN_TYPE) & (SIZEOF(ALIGN_TYPE)-1)) != 0) + ERREXIT(cinfo, JERR_BAD_ALIGN_TYPE); + /* MAX_ALLOC_CHUNK must be representable as type size_t, and must be + * a multiple of SIZEOF(ALIGN_TYPE). + * Again, an "unreachable code" warning may be ignored here. + * But a "constant too large" warning means you need to fix MAX_ALLOC_CHUNK. + */ + test_mac = (size_t) MAX_ALLOC_CHUNK; + if ((long) test_mac != MAX_ALLOC_CHUNK || + (MAX_ALLOC_CHUNK % SIZEOF(ALIGN_TYPE)) != 0) + ERREXIT(cinfo, JERR_BAD_ALLOC_CHUNK); + + max_to_use = jpeg_mem_init(cinfo); /* system-dependent initialization */ + + /* Attempt to allocate memory manager's control block */ + mem = (my_mem_ptr) jpeg_get_small(cinfo, SIZEOF(my_memory_mgr)); + + if (mem == NULL) { + jpeg_mem_term(cinfo); /* system-dependent cleanup */ + ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 0); + } + + /* OK, fill in the method pointers */ + mem->pub.alloc_small = alloc_small; + mem->pub.alloc_large = alloc_large; + mem->pub.alloc_sarray = alloc_sarray; + mem->pub.alloc_barray = alloc_barray; + mem->pub.request_virt_sarray = request_virt_sarray; + mem->pub.request_virt_barray = request_virt_barray; + mem->pub.realize_virt_arrays = realize_virt_arrays; + mem->pub.access_virt_sarray = access_virt_sarray; + mem->pub.access_virt_barray = access_virt_barray; + mem->pub.free_pool = free_pool; + mem->pub.self_destruct = self_destruct; + + /* Make MAX_ALLOC_CHUNK accessible to other modules */ + mem->pub.max_alloc_chunk = MAX_ALLOC_CHUNK; + + /* Initialize working state */ + mem->pub.max_memory_to_use = max_to_use; + + for (pool = JPOOL_NUMPOOLS-1; pool >= JPOOL_PERMANENT; pool--) { + mem->small_list[pool] = NULL; + mem->large_list[pool] = NULL; + } + mem->virt_sarray_list = NULL; + mem->virt_barray_list = NULL; + + mem->total_space_allocated = SIZEOF(my_memory_mgr); + + /* Declare ourselves open for business */ + cinfo->mem = & mem->pub; + + /* Check for an environment variable JPEGMEM; if found, override the + * default max_memory setting from jpeg_mem_init. Note that the + * surrounding application may again override this value. + * If your system doesn't support getenv(), define NO_GETENV to disable + * this feature. + */ +#ifndef NO_GETENV + { char * memenv; + + if ((memenv = getenv("JPEGMEM")) != NULL) { + char ch = 'x'; + + if (sscanf(memenv, "%ld%c", &max_to_use, &ch) > 0) { + if (ch == 'm' || ch == 'M') + max_to_use *= 1000L; + mem->pub.max_memory_to_use = max_to_use * 1000L; + } + } + } +#endif + +} diff --git a/mod/pub.mod/libjpeg.mod/jmemnobs.c b/mod/pub.mod/libjpeg.mod/jmemnobs.c new file mode 100644 index 0000000..eb8c337 --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jmemnobs.c @@ -0,0 +1,109 @@ +/* + * jmemnobs.c + * + * Copyright (C) 1992-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file provides a really simple implementation of the system- + * dependent portion of the JPEG memory manager. This implementation + * assumes that no backing-store files are needed: all required space + * can be obtained from malloc(). + * This is very portable in the sense that it'll compile on almost anything, + * but you'd better have lots of main memory (or virtual memory) if you want + * to process big images. + * Note that the max_memory_to_use option is ignored by this implementation. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jmemsys.h" /* import the system-dependent declarations */ + +#ifndef HAVE_STDLIB_H /* <stdlib.h> should declare malloc(),free() */ +extern void * malloc JPP((size_t size)); +extern void free JPP((void *ptr)); +#endif + + +/* + * Memory allocation and freeing are controlled by the regular library + * routines malloc() and free(). + */ + +GLOBAL(void *) +jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject) +{ + return (void *) malloc(sizeofobject); +} + +GLOBAL(void) +jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject) +{ + free(object); +} + + +/* + * "Large" objects are treated the same as "small" ones. + * NB: although we include FAR keywords in the routine declarations, + * this file won't actually work in 80x86 small/medium model; at least, + * you probably won't be able to process useful-size images in only 64KB. + */ + +GLOBAL(void FAR *) +jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject) +{ + return (void FAR *) malloc(sizeofobject); +} + +GLOBAL(void) +jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject) +{ + free(object); +} + + +/* + * This routine computes the total memory space available for allocation. + * Here we always say, "we got all you want bud!" + */ + +GLOBAL(long) +jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed, + long max_bytes_needed, long already_allocated) +{ + return max_bytes_needed; +} + + +/* + * Backing store (temporary file) management. + * Since jpeg_mem_available always promised the moon, + * this should never be called and we can just error out. + */ + +GLOBAL(void) +jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info, + long total_bytes_needed) +{ + ERREXIT(cinfo, JERR_NO_BACKING_STORE); +} + + +/* + * These routines take care of any system-dependent initialization and + * cleanup required. Here, there isn't any. + */ + +GLOBAL(long) +jpeg_mem_init (j_common_ptr cinfo) +{ + return 0; /* just set max_memory_to_use to 0 */ +} + +GLOBAL(void) +jpeg_mem_term (j_common_ptr cinfo) +{ + /* no work */ +} diff --git a/mod/pub.mod/libjpeg.mod/jmemsys.h b/mod/pub.mod/libjpeg.mod/jmemsys.h new file mode 100644 index 0000000..6c3c6d3 --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jmemsys.h @@ -0,0 +1,198 @@ +/* + * jmemsys.h + * + * Copyright (C) 1992-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This include file defines the interface between the system-independent + * and system-dependent portions of the JPEG memory manager. No other + * modules need include it. (The system-independent portion is jmemmgr.c; + * there are several different versions of the system-dependent portion.) + * + * This file works as-is for the system-dependent memory managers supplied + * in the IJG distribution. You may need to modify it if you write a + * custom memory manager. If system-dependent changes are needed in + * this file, the best method is to #ifdef them based on a configuration + * symbol supplied in jconfig.h, as we have done with USE_MSDOS_MEMMGR + * and USE_MAC_MEMMGR. + */ + + +/* Short forms of external names for systems with brain-damaged linkers. */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jpeg_get_small jGetSmall +#define jpeg_free_small jFreeSmall +#define jpeg_get_large jGetLarge +#define jpeg_free_large jFreeLarge +#define jpeg_mem_available jMemAvail +#define jpeg_open_backing_store jOpenBackStore +#define jpeg_mem_init jMemInit +#define jpeg_mem_term jMemTerm +#endif /* NEED_SHORT_EXTERNAL_NAMES */ + + +/* + * These two functions are used to allocate and release small chunks of + * memory. (Typically the total amount requested through jpeg_get_small is + * no more than 20K or so; this will be requested in chunks of a few K each.) + * Behavior should be the same as for the standard library functions malloc + * and free; in particular, jpeg_get_small must return NULL on failure. + * On most systems, these ARE malloc and free. jpeg_free_small is passed the + * size of the object being freed, just in case it's needed. + * On an 80x86 machine using small-data memory model, these manage near heap. + */ + +EXTERN(void *) jpeg_get_small JPP((j_common_ptr cinfo, size_t sizeofobject)); +EXTERN(void) jpeg_free_small JPP((j_common_ptr cinfo, void * object, + size_t sizeofobject)); + +/* + * These two functions are used to allocate and release large chunks of + * memory (up to the total free space designated by jpeg_mem_available). + * The interface is the same as above, except that on an 80x86 machine, + * far pointers are used. On most other machines these are identical to + * the jpeg_get/free_small routines; but we keep them separate anyway, + * in case a different allocation strategy is desirable for large chunks. + */ + +EXTERN(void FAR *) jpeg_get_large JPP((j_common_ptr cinfo, + size_t sizeofobject)); +EXTERN(void) jpeg_free_large JPP((j_common_ptr cinfo, void FAR * object, + size_t sizeofobject)); + +/* + * The macro MAX_ALLOC_CHUNK designates the maximum number of bytes that may + * be requested in a single call to jpeg_get_large (and jpeg_get_small for that + * matter, but that case should never come into play). This macro is needed + * to model the 64Kb-segment-size limit of far addressing on 80x86 machines. + * On those machines, we expect that jconfig.h will provide a proper value. + * On machines with 32-bit flat address spaces, any large constant may be used. + * + * NB: jmemmgr.c expects that MAX_ALLOC_CHUNK will be representable as type + * size_t and will be a multiple of sizeof(align_type). + */ + +#ifndef MAX_ALLOC_CHUNK /* may be overridden in jconfig.h */ +#define MAX_ALLOC_CHUNK 1000000000L +#endif + +/* + * This routine computes the total space still available for allocation by + * jpeg_get_large. If more space than this is needed, backing store will be + * used. NOTE: any memory already allocated must not be counted. + * + * There is a minimum space requirement, corresponding to the minimum + * feasible buffer sizes; jmemmgr.c will request that much space even if + * jpeg_mem_available returns zero. The maximum space needed, enough to hold + * all working storage in memory, is also passed in case it is useful. + * Finally, the total space already allocated is passed. If no better + * method is available, cinfo->mem->max_memory_to_use - already_allocated + * is often a suitable calculation. + * + * It is OK for jpeg_mem_available to underestimate the space available + * (that'll just lead to more backing-store access than is really necessary). + * However, an overestimate will lead to failure. Hence it's wise to subtract + * a slop factor from the true available space. 5% should be enough. + * + * On machines with lots of virtual memory, any large constant may be returned. + * Conversely, zero may be returned to always use the minimum amount of memory. + */ + +EXTERN(long) jpeg_mem_available JPP((j_common_ptr cinfo, + long min_bytes_needed, + long max_bytes_needed, + long already_allocated)); + + +/* + * This structure holds whatever state is needed to access a single + * backing-store object. The read/write/close method pointers are called + * by jmemmgr.c to manipulate the backing-store object; all other fields + * are private to the system-dependent backing store routines. + */ + +#define TEMP_NAME_LENGTH 64 /* max length of a temporary file's name */ + + +#ifdef USE_MSDOS_MEMMGR /* DOS-specific junk */ + +typedef unsigned short XMSH; /* type of extended-memory handles */ +typedef unsigned short EMSH; /* type of expanded-memory handles */ + +typedef union { + short file_handle; /* DOS file handle if it's a temp file */ + XMSH xms_handle; /* handle if it's a chunk of XMS */ + EMSH ems_handle; /* handle if it's a chunk of EMS */ +} handle_union; + +#endif /* USE_MSDOS_MEMMGR */ + +#ifdef USE_MAC_MEMMGR /* Mac-specific junk */ +#include <Files.h> +#endif /* USE_MAC_MEMMGR */ + + +typedef struct backing_store_struct * backing_store_ptr; + +typedef struct backing_store_struct { + /* Methods for reading/writing/closing this backing-store object */ + JMETHOD(void, read_backing_store, (j_common_ptr cinfo, + backing_store_ptr info, + void FAR * buffer_address, + long file_offset, long byte_count)); + JMETHOD(void, write_backing_store, (j_common_ptr cinfo, + backing_store_ptr info, + void FAR * buffer_address, + long file_offset, long byte_count)); + JMETHOD(void, close_backing_store, (j_common_ptr cinfo, + backing_store_ptr info)); + + /* Private fields for system-dependent backing-store management */ +#ifdef USE_MSDOS_MEMMGR + /* For the MS-DOS manager (jmemdos.c), we need: */ + handle_union handle; /* reference to backing-store storage object */ + char temp_name[TEMP_NAME_LENGTH]; /* name if it's a file */ +#else +#ifdef USE_MAC_MEMMGR + /* For the Mac manager (jmemmac.c), we need: */ + short temp_file; /* file reference number to temp file */ + FSSpec tempSpec; /* the FSSpec for the temp file */ + char temp_name[TEMP_NAME_LENGTH]; /* name if it's a file */ +#else + /* For a typical implementation with temp files, we need: */ + FILE * temp_file; /* stdio reference to temp file */ + char temp_name[TEMP_NAME_LENGTH]; /* name of temp file */ +#endif +#endif +} backing_store_info; + + +/* + * Initial opening of a backing-store object. This must fill in the + * read/write/close pointers in the object. The read/write routines + * may take an error exit if the specified maximum file size is exceeded. + * (If jpeg_mem_available always returns a large value, this routine can + * just take an error exit.) + */ + +EXTERN(void) jpeg_open_backing_store JPP((j_common_ptr cinfo, + backing_store_ptr info, + long total_bytes_needed)); + + +/* + * These routines take care of any system-dependent initialization and + * cleanup required. jpeg_mem_init will be called before anything is + * allocated (and, therefore, nothing in cinfo is of use except the error + * manager pointer). It should return a suitable default value for + * max_memory_to_use; this may subsequently be overridden by the surrounding + * application. (Note that max_memory_to_use is only important if + * jpeg_mem_available chooses to consult it ... no one else will.) + * jpeg_mem_term may assume that all requested memory has been freed and that + * all opened backing-store objects have been closed. + */ + +EXTERN(long) jpeg_mem_init JPP((j_common_ptr cinfo)); +EXTERN(void) jpeg_mem_term JPP((j_common_ptr cinfo)); diff --git a/mod/pub.mod/libjpeg.mod/jmorecfg.h b/mod/pub.mod/libjpeg.mod/jmorecfg.h new file mode 100644 index 0000000..54a7d1c --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jmorecfg.h @@ -0,0 +1,363 @@ +/* + * jmorecfg.h + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains additional configuration options that customize the + * JPEG software for special applications or support machine-dependent + * optimizations. Most users will not need to touch this file. + */ + + +/* + * Define BITS_IN_JSAMPLE as either + * 8 for 8-bit sample values (the usual setting) + * 12 for 12-bit sample values + * Only 8 and 12 are legal data precisions for lossy JPEG according to the + * JPEG standard, and the IJG code does not support anything else! + * We do not support run-time selection of data precision, sorry. + */ + +#define BITS_IN_JSAMPLE 8 /* use 8 or 12 */ + + +/* + * Maximum number of components (color channels) allowed in JPEG image. + * To meet the letter of the JPEG spec, set this to 255. However, darn + * few applications need more than 4 channels (maybe 5 for CMYK + alpha + * mask). We recommend 10 as a reasonable compromise; use 4 if you are + * really short on memory. (Each allowed component costs a hundred or so + * bytes of storage, whether actually used in an image or not.) + */ + +#define MAX_COMPONENTS 10 /* maximum number of image components */ + + +/* + * Basic data types. + * You may need to change these if you have a machine with unusual data + * type sizes; for example, "char" not 8 bits, "short" not 16 bits, + * or "long" not 32 bits. We don't care whether "int" is 16 or 32 bits, + * but it had better be at least 16. + */ + +/* Representation of a single sample (pixel element value). + * We frequently allocate large arrays of these, so it's important to keep + * them small. But if you have memory to burn and access to char or short + * arrays is very slow on your hardware, you might want to change these. + */ + +#if BITS_IN_JSAMPLE == 8 +/* JSAMPLE should be the smallest type that will hold the values 0..255. + * You can use a signed char by having GETJSAMPLE mask it with 0xFF. + */ + +#ifdef HAVE_UNSIGNED_CHAR + +typedef unsigned char JSAMPLE; +#define GETJSAMPLE(value) ((int) (value)) + +#else /* not HAVE_UNSIGNED_CHAR */ + +typedef char JSAMPLE; +#ifdef CHAR_IS_UNSIGNED +#define GETJSAMPLE(value) ((int) (value)) +#else +#define GETJSAMPLE(value) ((int) (value) & 0xFF) +#endif /* CHAR_IS_UNSIGNED */ + +#endif /* HAVE_UNSIGNED_CHAR */ + +#define MAXJSAMPLE 255 +#define CENTERJSAMPLE 128 + +#endif /* BITS_IN_JSAMPLE == 8 */ + + +#if BITS_IN_JSAMPLE == 12 +/* JSAMPLE should be the smallest type that will hold the values 0..4095. + * On nearly all machines "short" will do nicely. + */ + +typedef short JSAMPLE; +#define GETJSAMPLE(value) ((int) (value)) + +#define MAXJSAMPLE 4095 +#define CENTERJSAMPLE 2048 + +#endif /* BITS_IN_JSAMPLE == 12 */ + + +/* Representation of a DCT frequency coefficient. + * This should be a signed value of at least 16 bits; "short" is usually OK. + * Again, we allocate large arrays of these, but you can change to int + * if you have memory to burn and "short" is really slow. + */ + +typedef short JCOEF; + + +/* Compressed datastreams are represented as arrays of JOCTET. + * These must be EXACTLY 8 bits wide, at least once they are written to + * external storage. Note that when using the stdio data source/destination + * managers, this is also the data type passed to fread/fwrite. + */ + +#ifdef HAVE_UNSIGNED_CHAR + +typedef unsigned char JOCTET; +#define GETJOCTET(value) (value) + +#else /* not HAVE_UNSIGNED_CHAR */ + +typedef char JOCTET; +#ifdef CHAR_IS_UNSIGNED +#define GETJOCTET(value) (value) +#else +#define GETJOCTET(value) ((value) & 0xFF) +#endif /* CHAR_IS_UNSIGNED */ + +#endif /* HAVE_UNSIGNED_CHAR */ + + +/* These typedefs are used for various table entries and so forth. + * They must be at least as wide as specified; but making them too big + * won't cost a huge amount of memory, so we don't provide special + * extraction code like we did for JSAMPLE. (In other words, these + * typedefs live at a different point on the speed/space tradeoff curve.) + */ + +/* UINT8 must hold at least the values 0..255. */ + +#ifdef HAVE_UNSIGNED_CHAR +typedef unsigned char UINT8; +#else /* not HAVE_UNSIGNED_CHAR */ +#ifdef CHAR_IS_UNSIGNED +typedef char UINT8; +#else /* not CHAR_IS_UNSIGNED */ +typedef short UINT8; +#endif /* CHAR_IS_UNSIGNED */ +#endif /* HAVE_UNSIGNED_CHAR */ + +/* UINT16 must hold at least the values 0..65535. */ + +#ifdef HAVE_UNSIGNED_SHORT +typedef unsigned short UINT16; +#else /* not HAVE_UNSIGNED_SHORT */ +typedef unsigned int UINT16; +#endif /* HAVE_UNSIGNED_SHORT */ + +/* INT16 must hold at least the values -32768..32767. */ + +#ifndef XMD_H /* X11/xmd.h correctly defines INT16 */ +typedef short INT16; +#endif + +/* INT32 must hold at least signed 32-bit values. */ + +#ifndef XMD_H /* X11/xmd.h correctly defines INT32 */ +typedef long INT32; +#endif + +/* Datatype used for image dimensions. The JPEG standard only supports + * images up to 64K*64K due to 16-bit fields in SOF markers. Therefore + * "unsigned int" is sufficient on all machines. However, if you need to + * handle larger images and you don't mind deviating from the spec, you + * can change this datatype. + */ + +typedef unsigned int JDIMENSION; + +#define JPEG_MAX_DIMENSION 65500L /* a tad under 64K to prevent overflows */ + + +/* These macros are used in all function definitions and extern declarations. + * You could modify them if you need to change function linkage conventions; + * in particular, you'll need to do that to make the library a Windows DLL. + * Another application is to make all functions global for use with debuggers + * or code profilers that require it. + */ + +/* a function called through method pointers: */ +#define METHODDEF(type) static type +/* a function used only in its module: */ +#define LOCAL(type) static type +/* a function referenced thru EXTERNs: */ +#define GLOBAL(type) type +/* a reference to a GLOBAL function: */ +#define EXTERN(type) extern type + + +/* This macro is used to declare a "method", that is, a function pointer. + * We want to supply prototype parameters if the compiler can cope. + * Note that the arglist parameter must be parenthesized! + * Again, you can customize this if you need special linkage keywords. + */ + +#ifdef HAVE_PROTOTYPES +#define JMETHOD(type,methodname,arglist) type (*methodname) arglist +#else +#define JMETHOD(type,methodname,arglist) type (*methodname) () +#endif + + +/* Here is the pseudo-keyword for declaring pointers that must be "far" + * on 80x86 machines. Most of the specialized coding for 80x86 is handled + * by just saying "FAR *" where such a pointer is needed. In a few places + * explicit coding is needed; see uses of the NEED_FAR_POINTERS symbol. + */ + +#ifdef NEED_FAR_POINTERS +#define FAR far +#else +#define FAR +#endif + + +/* + * On a few systems, type boolean and/or its values FALSE, TRUE may appear + * in standard header files. Or you may have conflicts with application- + * specific header files that you want to include together with these files. + * Defining HAVE_BOOLEAN before including jpeglib.h should make it work. + */ + +#ifndef HAVE_BOOLEAN +typedef int boolean; +#endif +#ifndef FALSE /* in case these macros already exist */ +#define FALSE 0 /* values of boolean */ +#endif +#ifndef TRUE +#define TRUE 1 +#endif + + +/* + * The remaining options affect code selection within the JPEG library, + * but they don't need to be visible to most applications using the library. + * To minimize application namespace pollution, the symbols won't be + * defined unless JPEG_INTERNALS or JPEG_INTERNAL_OPTIONS has been defined. + */ + +#ifdef JPEG_INTERNALS +#define JPEG_INTERNAL_OPTIONS +#endif + +#ifdef JPEG_INTERNAL_OPTIONS + + +/* + * These defines indicate whether to include various optional functions. + * Undefining some of these symbols will produce a smaller but less capable + * library. Note that you can leave certain source files out of the + * compilation/linking process if you've #undef'd the corresponding symbols. + * (You may HAVE to do that if your compiler doesn't like null source files.) + */ + +/* Arithmetic coding is unsupported for legal reasons. Complaints to IBM. */ + +/* Capability options common to encoder and decoder: */ + +#define DCT_ISLOW_SUPPORTED /* slow but accurate integer algorithm */ +#define DCT_IFAST_SUPPORTED /* faster, less accurate integer method */ +#define DCT_FLOAT_SUPPORTED /* floating-point: accurate, fast on fast HW */ + +/* Encoder capability options: */ + +#undef C_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */ +#define C_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */ +#define C_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/ +#define ENTROPY_OPT_SUPPORTED /* Optimization of entropy coding parms? */ +/* Note: if you selected 12-bit data precision, it is dangerous to turn off + * ENTROPY_OPT_SUPPORTED. The standard Huffman tables are only good for 8-bit + * precision, so jchuff.c normally uses entropy optimization to compute + * usable tables for higher precision. If you don't want to do optimization, + * you'll have to supply different default Huffman tables. + * The exact same statements apply for progressive JPEG: the default tables + * don't work for progressive mode. (This may get fixed, however.) + */ +#define INPUT_SMOOTHING_SUPPORTED /* Input image smoothing option? */ + +/* Decoder capability options: */ + +#undef D_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */ +#define D_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */ +#define D_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/ +#define SAVE_MARKERS_SUPPORTED /* jpeg_save_markers() needed? */ +#define BLOCK_SMOOTHING_SUPPORTED /* Block smoothing? (Progressive only) */ +#define IDCT_SCALING_SUPPORTED /* Output rescaling via IDCT? */ +#undef UPSAMPLE_SCALING_SUPPORTED /* Output rescaling at upsample stage? */ +#define UPSAMPLE_MERGING_SUPPORTED /* Fast path for sloppy upsampling? */ +#define QUANT_1PASS_SUPPORTED /* 1-pass color quantization? */ +#define QUANT_2PASS_SUPPORTED /* 2-pass color quantization? */ + +/* more capability options later, no doubt */ + + +/* + * Ordering of RGB data in scanlines passed to or from the application. + * If your application wants to deal with data in the order B,G,R, just + * change these macros. You can also deal with formats such as R,G,B,X + * (one extra byte per pixel) by changing RGB_PIXELSIZE. Note that changing + * the offsets will also change the order in which colormap data is organized. + * RESTRICTIONS: + * 1. The sample applications cjpeg,djpeg do NOT support modified RGB formats. + * 2. These macros only affect RGB<=>YCbCr color conversion, so they are not + * useful if you are using JPEG color spaces other than YCbCr or grayscale. + * 3. The color quantizer modules will not behave desirably if RGB_PIXELSIZE + * is not 3 (they don't understand about dummy color components!). So you + * can't use color quantization if you change that value. + */ + +#define RGB_RED 0 /* Offset of Red in an RGB scanline element */ +#define RGB_GREEN 1 /* Offset of Green */ +#define RGB_BLUE 2 /* Offset of Blue */ +#define RGB_PIXELSIZE 3 /* JSAMPLEs per RGB scanline element */ + + +/* Definitions for speed-related optimizations. */ + + +/* If your compiler supports inline functions, define INLINE + * as the inline keyword; otherwise define it as empty. + */ + +#ifndef INLINE +#ifdef __GNUC__ /* for instance, GNU C knows about inline */ +#define INLINE __inline__ +#endif +#ifndef INLINE +#define INLINE /* default is to define it as empty */ +#endif +#endif + + +/* On some machines (notably 68000 series) "int" is 32 bits, but multiplying + * two 16-bit shorts is faster than multiplying two ints. Define MULTIPLIER + * as short on such a machine. MULTIPLIER must be at least 16 bits wide. + */ + +#ifndef MULTIPLIER +#define MULTIPLIER int /* type for fastest integer multiply */ +#endif + + +/* FAST_FLOAT should be either float or double, whichever is done faster + * by your compiler. (Note that this type is only used in the floating point + * DCT routines, so it only matters if you've defined DCT_FLOAT_SUPPORTED.) + * Typically, float is faster in ANSI C compilers, while double is faster in + * pre-ANSI compilers (because they insist on converting to double anyway). + * The code below therefore chooses float if we have ANSI-style prototypes. + */ + +#ifndef FAST_FLOAT +#ifdef HAVE_PROTOTYPES +#define FAST_FLOAT float +#else +#define FAST_FLOAT double +#endif +#endif + +#endif /* JPEG_INTERNAL_OPTIONS */ diff --git a/mod/pub.mod/libjpeg.mod/jpegint.h b/mod/pub.mod/libjpeg.mod/jpegint.h new file mode 100644 index 0000000..95b00d4 --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jpegint.h @@ -0,0 +1,392 @@ +/* + * jpegint.h + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file provides common declarations for the various JPEG modules. + * These declarations are considered internal to the JPEG library; most + * applications using the library shouldn't need to include this file. + */ + + +/* Declarations for both compression & decompression */ + +typedef enum { /* Operating modes for buffer controllers */ + JBUF_PASS_THRU, /* Plain stripwise operation */ + /* Remaining modes require a full-image buffer to have been created */ + JBUF_SAVE_SOURCE, /* Run source subobject only, save output */ + JBUF_CRANK_DEST, /* Run dest subobject only, using saved data */ + JBUF_SAVE_AND_PASS /* Run both subobjects, save output */ +} J_BUF_MODE; + +/* Values of global_state field (jdapi.c has some dependencies on ordering!) */ +#define CSTATE_START 100 /* after create_compress */ +#define CSTATE_SCANNING 101 /* start_compress done, write_scanlines OK */ +#define CSTATE_RAW_OK 102 /* start_compress done, write_raw_data OK */ +#define CSTATE_WRCOEFS 103 /* jpeg_write_coefficients done */ +#define DSTATE_START 200 /* after create_decompress */ +#define DSTATE_INHEADER 201 /* reading header markers, no SOS yet */ +#define DSTATE_READY 202 /* found SOS, ready for start_decompress */ +#define DSTATE_PRELOAD 203 /* reading multiscan file in start_decompress*/ +#define DSTATE_PRESCAN 204 /* performing dummy pass for 2-pass quant */ +#define DSTATE_SCANNING 205 /* start_decompress done, read_scanlines OK */ +#define DSTATE_RAW_OK 206 /* start_decompress done, read_raw_data OK */ +#define DSTATE_BUFIMAGE 207 /* expecting jpeg_start_output */ +#define DSTATE_BUFPOST 208 /* looking for SOS/EOI in jpeg_finish_output */ +#define DSTATE_RDCOEFS 209 /* reading file in jpeg_read_coefficients */ +#define DSTATE_STOPPING 210 /* looking for EOI in jpeg_finish_decompress */ + + +/* Declarations for compression modules */ + +/* Master control module */ +struct jpeg_comp_master { + JMETHOD(void, prepare_for_pass, (j_compress_ptr cinfo)); + JMETHOD(void, pass_startup, (j_compress_ptr cinfo)); + JMETHOD(void, finish_pass, (j_compress_ptr cinfo)); + + /* State variables made visible to other modules */ + boolean call_pass_startup; /* True if pass_startup must be called */ + boolean is_last_pass; /* True during last pass */ +}; + +/* Main buffer control (downsampled-data buffer) */ +struct jpeg_c_main_controller { + JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode)); + JMETHOD(void, process_data, (j_compress_ptr cinfo, + JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, + JDIMENSION in_rows_avail)); +}; + +/* Compression preprocessing (downsampling input buffer control) */ +struct jpeg_c_prep_controller { + JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode)); + JMETHOD(void, pre_process_data, (j_compress_ptr cinfo, + JSAMPARRAY input_buf, + JDIMENSION *in_row_ctr, + JDIMENSION in_rows_avail, + JSAMPIMAGE output_buf, + JDIMENSION *out_row_group_ctr, + JDIMENSION out_row_groups_avail)); +}; + +/* Coefficient buffer control */ +struct jpeg_c_coef_controller { + JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode)); + JMETHOD(boolean, compress_data, (j_compress_ptr cinfo, + JSAMPIMAGE input_buf)); +}; + +/* Colorspace conversion */ +struct jpeg_color_converter { + JMETHOD(void, start_pass, (j_compress_ptr cinfo)); + JMETHOD(void, color_convert, (j_compress_ptr cinfo, + JSAMPARRAY input_buf, JSAMPIMAGE output_buf, + JDIMENSION output_row, int num_rows)); +}; + +/* Downsampling */ +struct jpeg_downsampler { + JMETHOD(void, start_pass, (j_compress_ptr cinfo)); + JMETHOD(void, downsample, (j_compress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION in_row_index, + JSAMPIMAGE output_buf, + JDIMENSION out_row_group_index)); + + boolean need_context_rows; /* TRUE if need rows above & below */ +}; + +/* Forward DCT (also controls coefficient quantization) */ +struct jpeg_forward_dct { + JMETHOD(void, start_pass, (j_compress_ptr cinfo)); + /* perhaps this should be an array??? */ + JMETHOD(void, forward_DCT, (j_compress_ptr cinfo, + jpeg_component_info * compptr, + JSAMPARRAY sample_data, JBLOCKROW coef_blocks, + JDIMENSION start_row, JDIMENSION start_col, + JDIMENSION num_blocks)); +}; + +/* Entropy encoding */ +struct jpeg_entropy_encoder { + JMETHOD(void, start_pass, (j_compress_ptr cinfo, boolean gather_statistics)); + JMETHOD(boolean, encode_mcu, (j_compress_ptr cinfo, JBLOCKROW *MCU_data)); + JMETHOD(void, finish_pass, (j_compress_ptr cinfo)); +}; + +/* Marker writing */ +struct jpeg_marker_writer { + JMETHOD(void, write_file_header, (j_compress_ptr cinfo)); + JMETHOD(void, write_frame_header, (j_compress_ptr cinfo)); + JMETHOD(void, write_scan_header, (j_compress_ptr cinfo)); + JMETHOD(void, write_file_trailer, (j_compress_ptr cinfo)); + JMETHOD(void, write_tables_only, (j_compress_ptr cinfo)); + /* These routines are exported to allow insertion of extra markers */ + /* Probably only COM and APPn markers should be written this way */ + JMETHOD(void, write_marker_header, (j_compress_ptr cinfo, int marker, + unsigned int datalen)); + JMETHOD(void, write_marker_byte, (j_compress_ptr cinfo, int val)); +}; + + +/* Declarations for decompression modules */ + +/* Master control module */ +struct jpeg_decomp_master { + JMETHOD(void, prepare_for_output_pass, (j_decompress_ptr cinfo)); + JMETHOD(void, finish_output_pass, (j_decompress_ptr cinfo)); + + /* State variables made visible to other modules */ + boolean is_dummy_pass; /* True during 1st pass for 2-pass quant */ +}; + +/* Input control module */ +struct jpeg_input_controller { + JMETHOD(int, consume_input, (j_decompress_ptr cinfo)); + JMETHOD(void, reset_input_controller, (j_decompress_ptr cinfo)); + JMETHOD(void, start_input_pass, (j_decompress_ptr cinfo)); + JMETHOD(void, finish_input_pass, (j_decompress_ptr cinfo)); + + /* State variables made visible to other modules */ + boolean has_multiple_scans; /* True if file has multiple scans */ + boolean eoi_reached; /* True when EOI has been consumed */ +}; + +/* Main buffer control (downsampled-data buffer) */ +struct jpeg_d_main_controller { + JMETHOD(void, start_pass, (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)); + JMETHOD(void, process_data, (j_decompress_ptr cinfo, + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail)); +}; + +/* Coefficient buffer control */ +struct jpeg_d_coef_controller { + JMETHOD(void, start_input_pass, (j_decompress_ptr cinfo)); + JMETHOD(int, consume_data, (j_decompress_ptr cinfo)); + JMETHOD(void, start_output_pass, (j_decompress_ptr cinfo)); + JMETHOD(int, decompress_data, (j_decompress_ptr cinfo, + JSAMPIMAGE output_buf)); + /* Pointer to array of coefficient virtual arrays, or NULL if none */ + jvirt_barray_ptr *coef_arrays; +}; + +/* Decompression postprocessing (color quantization buffer control) */ +struct jpeg_d_post_controller { + JMETHOD(void, start_pass, (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)); + JMETHOD(void, post_process_data, (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, + JDIMENSION *in_row_group_ctr, + JDIMENSION in_row_groups_avail, + JSAMPARRAY output_buf, + JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail)); +}; + +/* Marker reading & parsing */ +struct jpeg_marker_reader { + JMETHOD(void, reset_marker_reader, (j_decompress_ptr cinfo)); + /* Read markers until SOS or EOI. + * Returns same codes as are defined for jpeg_consume_input: + * JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI. + */ + JMETHOD(int, read_markers, (j_decompress_ptr cinfo)); + /* Read a restart marker --- exported for use by entropy decoder only */ + jpeg_marker_parser_method read_restart_marker; + + /* State of marker reader --- nominally internal, but applications + * supplying COM or APPn handlers might like to know the state. + */ + boolean saw_SOI; /* found SOI? */ + boolean saw_SOF; /* found SOF? */ + int next_restart_num; /* next restart number expected (0-7) */ + unsigned int discarded_bytes; /* # of bytes skipped looking for a marker */ +}; + +/* Entropy decoding */ +struct jpeg_entropy_decoder { + JMETHOD(void, start_pass, (j_decompress_ptr cinfo)); + JMETHOD(boolean, decode_mcu, (j_decompress_ptr cinfo, + JBLOCKROW *MCU_data)); + + /* This is here to share code between baseline and progressive decoders; */ + /* other modules probably should not use it */ + boolean insufficient_data; /* set TRUE after emitting warning */ +}; + +/* Inverse DCT (also performs dequantization) */ +typedef JMETHOD(void, inverse_DCT_method_ptr, + (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, + JSAMPARRAY output_buf, JDIMENSION output_col)); + +struct jpeg_inverse_dct { + JMETHOD(void, start_pass, (j_decompress_ptr cinfo)); + /* It is useful to allow each component to have a separate IDCT method. */ + inverse_DCT_method_ptr inverse_DCT[MAX_COMPONENTS]; +}; + +/* Upsampling (note that upsampler must also call color converter) */ +struct jpeg_upsampler { + JMETHOD(void, start_pass, (j_decompress_ptr cinfo)); + JMETHOD(void, upsample, (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, + JDIMENSION *in_row_group_ctr, + JDIMENSION in_row_groups_avail, + JSAMPARRAY output_buf, + JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail)); + + boolean need_context_rows; /* TRUE if need rows above & below */ +}; + +/* Colorspace conversion */ +struct jpeg_color_deconverter { + JMETHOD(void, start_pass, (j_decompress_ptr cinfo)); + JMETHOD(void, color_convert, (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION input_row, + JSAMPARRAY output_buf, int num_rows)); +}; + +/* Color quantization or color precision reduction */ +struct jpeg_color_quantizer { + JMETHOD(void, start_pass, (j_decompress_ptr cinfo, boolean is_pre_scan)); + JMETHOD(void, color_quantize, (j_decompress_ptr cinfo, + JSAMPARRAY input_buf, JSAMPARRAY output_buf, + int num_rows)); + JMETHOD(void, finish_pass, (j_decompress_ptr cinfo)); + JMETHOD(void, new_color_map, (j_decompress_ptr cinfo)); +}; + + +/* Miscellaneous useful macros */ + +#undef MAX +#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#undef MIN +#define MIN(a,b) ((a) < (b) ? (a) : (b)) + + +/* We assume that right shift corresponds to signed division by 2 with + * rounding towards minus infinity. This is correct for typical "arithmetic + * shift" instructions that shift in copies of the sign bit. But some + * C compilers implement >> with an unsigned shift. For these machines you + * must define RIGHT_SHIFT_IS_UNSIGNED. + * RIGHT_SHIFT provides a proper signed right shift of an INT32 quantity. + * It is only applied with constant shift counts. SHIFT_TEMPS must be + * included in the variables of any routine using RIGHT_SHIFT. + */ + +#ifdef RIGHT_SHIFT_IS_UNSIGNED +#define SHIFT_TEMPS INT32 shift_temp; +#define RIGHT_SHIFT(x,shft) \ + ((shift_temp = (x)) < 0 ? \ + (shift_temp >> (shft)) | ((~((INT32) 0)) << (32-(shft))) : \ + (shift_temp >> (shft))) +#else +#define SHIFT_TEMPS +#define RIGHT_SHIFT(x,shft) ((x) >> (shft)) +#endif + + +/* Short forms of external names for systems with brain-damaged linkers. */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jinit_compress_master jICompress +#define jinit_c_master_control jICMaster +#define jinit_c_main_controller jICMainC +#define jinit_c_prep_controller jICPrepC +#define jinit_c_coef_controller jICCoefC +#define jinit_color_converter jICColor +#define jinit_downsampler jIDownsampler +#define jinit_forward_dct jIFDCT +#define jinit_huff_encoder jIHEncoder +#define jinit_phuff_encoder jIPHEncoder +#define jinit_marker_writer jIMWriter +#define jinit_master_decompress jIDMaster +#define jinit_d_main_controller jIDMainC +#define jinit_d_coef_controller jIDCoefC +#define jinit_d_post_controller jIDPostC +#define jinit_input_controller jIInCtlr +#define jinit_marker_reader jIMReader +#define jinit_huff_decoder jIHDecoder +#define jinit_phuff_decoder jIPHDecoder +#define jinit_inverse_dct jIIDCT +#define jinit_upsampler jIUpsampler +#define jinit_color_deconverter jIDColor +#define jinit_1pass_quantizer jI1Quant +#define jinit_2pass_quantizer jI2Quant +#define jinit_merged_upsampler jIMUpsampler +#define jinit_memory_mgr jIMemMgr +#define jdiv_round_up jDivRound +#define jround_up jRound +#define jcopy_sample_rows jCopySamples +#define jcopy_block_row jCopyBlocks +#define jzero_far jZeroFar +#define jpeg_zigzag_order jZIGTable +#define jpeg_natural_order jZAGTable +#endif /* NEED_SHORT_EXTERNAL_NAMES */ + + +/* Compression module initialization routines */ +EXTERN(void) jinit_compress_master JPP((j_compress_ptr cinfo)); +EXTERN(void) jinit_c_master_control JPP((j_compress_ptr cinfo, + boolean transcode_only)); +EXTERN(void) jinit_c_main_controller JPP((j_compress_ptr cinfo, + boolean need_full_buffer)); +EXTERN(void) jinit_c_prep_controller JPP((j_compress_ptr cinfo, + boolean need_full_buffer)); +EXTERN(void) jinit_c_coef_controller JPP((j_compress_ptr cinfo, + boolean need_full_buffer)); +EXTERN(void) jinit_color_converter JPP((j_compress_ptr cinfo)); +EXTERN(void) jinit_downsampler JPP((j_compress_ptr cinfo)); +EXTERN(void) jinit_forward_dct JPP((j_compress_ptr cinfo)); +EXTERN(void) jinit_huff_encoder JPP((j_compress_ptr cinfo)); +EXTERN(void) jinit_phuff_encoder JPP((j_compress_ptr cinfo)); +EXTERN(void) jinit_marker_writer JPP((j_compress_ptr cinfo)); +/* Decompression module initialization routines */ +EXTERN(void) jinit_master_decompress JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_d_main_controller JPP((j_decompress_ptr cinfo, + boolean need_full_buffer)); +EXTERN(void) jinit_d_coef_controller JPP((j_decompress_ptr cinfo, + boolean need_full_buffer)); +EXTERN(void) jinit_d_post_controller JPP((j_decompress_ptr cinfo, + boolean need_full_buffer)); +EXTERN(void) jinit_input_controller JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_marker_reader JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_huff_decoder JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_phuff_decoder JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_inverse_dct JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_upsampler JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_color_deconverter JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_1pass_quantizer JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_2pass_quantizer JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_merged_upsampler JPP((j_decompress_ptr cinfo)); +/* Memory manager initialization */ +EXTERN(void) jinit_memory_mgr JPP((j_common_ptr cinfo)); + +/* Utility routines in jutils.c */ +EXTERN(long) jdiv_round_up JPP((long a, long b)); +EXTERN(long) jround_up JPP((long a, long b)); +EXTERN(void) jcopy_sample_rows JPP((JSAMPARRAY input_array, int source_row, + JSAMPARRAY output_array, int dest_row, + int num_rows, JDIMENSION num_cols)); +EXTERN(void) jcopy_block_row JPP((JBLOCKROW input_row, JBLOCKROW output_row, + JDIMENSION num_blocks)); +EXTERN(void) jzero_far JPP((void FAR * target, size_t bytestozero)); +/* Constant tables in jutils.c */ +#if 0 /* This table is not actually needed in v6a */ +extern const int jpeg_zigzag_order[]; /* natural coef order to zigzag order */ +#endif +extern const int jpeg_natural_order[]; /* zigzag coef order to natural order */ + +/* Suppress undefined-structure complaints if necessary. */ + +#ifdef INCOMPLETE_TYPES_BROKEN +#ifndef AM_MEMORY_MANAGER /* only jmemmgr.c defines these */ +struct jvirt_sarray_control { long dummy; }; +struct jvirt_barray_control { long dummy; }; +#endif +#endif /* INCOMPLETE_TYPES_BROKEN */ diff --git a/mod/pub.mod/libjpeg.mod/jpeglib.h b/mod/pub.mod/libjpeg.mod/jpeglib.h new file mode 100644 index 0000000..5b2d46b --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jpeglib.h @@ -0,0 +1,1098 @@ +/* + * jpeglib.h + * + * Copyright (C) 1991-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file defines the application interface for the JPEG library. + * Most applications using the library need only include this file, + * and perhaps jerror.h if they want to know the exact error codes. + */ + +#ifndef JPEGLIB_H +#define JPEGLIB_H + +/* + * First we include the configuration files that record how this + * installation of the JPEG library is set up. jconfig.h can be + * generated automatically for many systems. jmorecfg.h contains + * manual configuration options that most people need not worry about. + */ + +#ifndef JCONFIG_INCLUDED /* in case jinclude.h already did */ +//#include "jconfig.h" /* widely used configuration options */ +#endif +#include "jmorecfg.h" /* seldom changed options */ + + +/* Version ID for the JPEG library. + * Might be useful for tests like "#if JPEG_LIB_VERSION >= 60". + */ + +#define JPEG_LIB_VERSION 62 /* Version 6b */ + + +/* Various constants determining the sizes of things. + * All of these are specified by the JPEG standard, so don't change them + * if you want to be compatible. + */ + +#define DCTSIZE 8 /* The basic DCT block is 8x8 samples */ +#define DCTSIZE2 64 /* DCTSIZE squared; # of elements in a block */ +#define NUM_QUANT_TBLS 4 /* Quantization tables are numbered 0..3 */ +#define NUM_HUFF_TBLS 4 /* Huffman tables are numbered 0..3 */ +#define NUM_ARITH_TBLS 16 /* Arith-coding tables are numbered 0..15 */ +#define MAX_COMPS_IN_SCAN 4 /* JPEG limit on # of components in one scan */ +#define MAX_SAMP_FACTOR 4 /* JPEG limit on sampling factors */ +/* Unfortunately, some bozo at Adobe saw no reason to be bound by the standard; + * the PostScript DCT filter can emit files with many more than 10 blocks/MCU. + * If you happen to run across such a file, you can up D_MAX_BLOCKS_IN_MCU + * to handle it. We even let you do this from the jconfig.h file. However, + * we strongly discourage changing C_MAX_BLOCKS_IN_MCU; just because Adobe + * sometimes emits noncompliant files doesn't mean you should too. + */ +#define C_MAX_BLOCKS_IN_MCU 10 /* compressor's limit on blocks per MCU */ +#ifndef D_MAX_BLOCKS_IN_MCU +#define D_MAX_BLOCKS_IN_MCU 10 /* decompressor's limit on blocks per MCU */ +#endif + + +/* Data structures for images (arrays of samples and of DCT coefficients). + * On 80x86 machines, the image arrays are too big for near pointers, + * but the pointer arrays can fit in near memory. + */ + +typedef JSAMPLE FAR *JSAMPROW; /* ptr to one image row of pixel samples. */ +typedef JSAMPROW *JSAMPARRAY; /* ptr to some rows (a 2-D sample array) */ +typedef JSAMPARRAY *JSAMPIMAGE; /* a 3-D sample array: top index is color */ + +typedef JCOEF JBLOCK[DCTSIZE2]; /* one block of coefficients */ +typedef JBLOCK FAR *JBLOCKROW; /* pointer to one row of coefficient blocks */ +typedef JBLOCKROW *JBLOCKARRAY; /* a 2-D array of coefficient blocks */ +typedef JBLOCKARRAY *JBLOCKIMAGE; /* a 3-D array of coefficient blocks */ + +typedef JCOEF FAR *JCOEFPTR; /* useful in a couple of places */ + + +/* Types for JPEG compression parameters and working tables. */ + + +/* DCT coefficient quantization tables. */ + +typedef struct { + /* This array gives the coefficient quantizers in natural array order + * (not the zigzag order in which they are stored in a JPEG DQT marker). + * CAUTION: IJG versions prior to v6a kept this array in zigzag order. + */ + UINT16 quantval[DCTSIZE2]; /* quantization step for each coefficient */ + /* This field is used only during compression. It's initialized FALSE when + * the table is created, and set TRUE when it's been output to the file. + * You could suppress output of a table by setting this to TRUE. + * (See jpeg_suppress_tables for an example.) + */ + boolean sent_table; /* TRUE when table has been output */ +} JQUANT_TBL; + + +/* Huffman coding tables. */ + +typedef struct { + /* These two fields directly represent the contents of a JPEG DHT marker */ + UINT8 bits[17]; /* bits[k] = # of symbols with codes of */ + /* length k bits; bits[0] is unused */ + UINT8 huffval[256]; /* The symbols, in order of incr code length */ + /* This field is used only during compression. It's initialized FALSE when + * the table is created, and set TRUE when it's been output to the file. + * You could suppress output of a table by setting this to TRUE. + * (See jpeg_suppress_tables for an example.) + */ + boolean sent_table; /* TRUE when table has been output */ +} JHUFF_TBL; + + +/* Basic info about one component (color channel). */ + +typedef struct { + /* These values are fixed over the whole image. */ + /* For compression, they must be supplied by parameter setup; */ + /* for decompression, they are read from the SOF marker. */ + int component_id; /* identifier for this component (0..255) */ + int component_index; /* its index in SOF or cinfo->comp_info[] */ + int h_samp_factor; /* horizontal sampling factor (1..4) */ + int v_samp_factor; /* vertical sampling factor (1..4) */ + int quant_tbl_no; /* quantization table selector (0..3) */ + /* These values may vary between scans. */ + /* For compression, they must be supplied by parameter setup; */ + /* for decompression, they are read from the SOS marker. */ + /* The decompressor output side may not use these variables. */ + int dc_tbl_no; /* DC entropy table selector (0..3) */ + int ac_tbl_no; /* AC entropy table selector (0..3) */ + + /* Remaining fields should be treated as private by applications. */ + + /* These values are computed during compression or decompression startup: */ + /* Component's size in DCT blocks. + * Any dummy blocks added to complete an MCU are not counted; therefore + * these values do not depend on whether a scan is interleaved or not. + */ + JDIMENSION width_in_blocks; + JDIMENSION height_in_blocks; + /* Size of a DCT block in samples. Always DCTSIZE for compression. + * For decompression this is the size of the output from one DCT block, + * reflecting any scaling we choose to apply during the IDCT step. + * Values of 1,2,4,8 are likely to be supported. Note that different + * components may receive different IDCT scalings. + */ + int DCT_scaled_size; + /* The downsampled dimensions are the component's actual, unpadded number + * of samples at the main buffer (preprocessing/compression interface), thus + * downsampled_width = ceil(image_width * Hi/Hmax) + * and similarly for height. For decompression, IDCT scaling is included, so + * downsampled_width = ceil(image_width * Hi/Hmax * DCT_scaled_size/DCTSIZE) + */ + JDIMENSION downsampled_width; /* actual width in samples */ + JDIMENSION downsampled_height; /* actual height in samples */ + /* This flag is used only for decompression. In cases where some of the + * components will be ignored (eg grayscale output from YCbCr image), + * we can skip most computations for the unused components. + */ + boolean component_needed; /* do we need the value of this component? */ + + /* These values are computed before starting a scan of the component. */ + /* The decompressor output side may not use these variables. */ + int MCU_width; /* number of blocks per MCU, horizontally */ + int MCU_height; /* number of blocks per MCU, vertically */ + int MCU_blocks; /* MCU_width * MCU_height */ + int MCU_sample_width; /* MCU width in samples, MCU_width*DCT_scaled_size */ + int last_col_width; /* # of non-dummy blocks across in last MCU */ + int last_row_height; /* # of non-dummy blocks down in last MCU */ + + /* Saved quantization table for component; NULL if none yet saved. + * See jdinput.c comments about the need for this information. + * This field is currently used only for decompression. + */ + JQUANT_TBL * quant_table; + + /* Private per-component storage for DCT or IDCT subsystem. */ + void * dct_table; +} jpeg_component_info; + + +/* The script for encoding a multiple-scan file is an array of these: */ + +typedef struct { + int comps_in_scan; /* number of components encoded in this scan */ + int component_index[MAX_COMPS_IN_SCAN]; /* their SOF/comp_info[] indexes */ + int Ss, Se; /* progressive JPEG spectral selection parms */ + int Ah, Al; /* progressive JPEG successive approx. parms */ +} jpeg_scan_info; + +/* The decompressor can save APPn and COM markers in a list of these: */ + +typedef struct jpeg_marker_struct FAR * jpeg_saved_marker_ptr; + +struct jpeg_marker_struct { + jpeg_saved_marker_ptr next; /* next in list, or NULL */ + UINT8 marker; /* marker code: JPEG_COM, or JPEG_APP0+n */ + unsigned int original_length; /* # bytes of data in the file */ + unsigned int data_length; /* # bytes of data saved at data[] */ + JOCTET FAR * data; /* the data contained in the marker */ + /* the marker length word is not counted in data_length or original_length */ +}; + +/* Known color spaces. */ + +typedef enum { + JCS_UNKNOWN, /* error/unspecified */ + JCS_GRAYSCALE, /* monochrome */ + JCS_RGB, /* red/green/blue */ + JCS_YCbCr, /* Y/Cb/Cr (also known as YUV) */ + JCS_CMYK, /* C/M/Y/K */ + JCS_YCCK /* Y/Cb/Cr/K */ +} J_COLOR_SPACE; + +/* DCT/IDCT algorithm options. */ + +typedef enum { + JDCT_ISLOW, /* slow but accurate integer algorithm */ + JDCT_IFAST, /* faster, less accurate integer method */ + JDCT_FLOAT /* floating-point: accurate, fast on fast HW */ +} J_DCT_METHOD; + +#ifndef JDCT_DEFAULT /* may be overridden in jconfig.h */ +#define JDCT_DEFAULT JDCT_ISLOW +#endif +#ifndef JDCT_FASTEST /* may be overridden in jconfig.h */ +#define JDCT_FASTEST JDCT_IFAST +#endif + +/* Dithering options for decompression. */ + +typedef enum { + JDITHER_NONE, /* no dithering */ + JDITHER_ORDERED, /* simple ordered dither */ + JDITHER_FS /* Floyd-Steinberg error diffusion dither */ +} J_DITHER_MODE; + + +/* Common fields between JPEG compression and decompression master structs. */ + +#define jpeg_common_fields \ + struct jpeg_error_mgr * err; /* Error handler module */\ + struct jpeg_memory_mgr * mem; /* Memory manager module */\ + struct jpeg_progress_mgr * progress; /* Progress monitor, or NULL if none */\ + void * client_data; /* Available for use by application */\ + boolean is_decompressor; /* So common code can tell which is which */\ + int global_state /* For checking call sequence validity */ + +/* Routines that are to be used by both halves of the library are declared + * to receive a pointer to this structure. There are no actual instances of + * jpeg_common_struct, only of jpeg_compress_struct and jpeg_decompress_struct. + */ +struct jpeg_common_struct { + jpeg_common_fields; /* Fields common to both master struct types */ + /* Additional fields follow in an actual jpeg_compress_struct or + * jpeg_decompress_struct. All three structs must agree on these + * initial fields! (This would be a lot cleaner in C++.) + */ +}; + +typedef struct jpeg_common_struct * j_common_ptr; +typedef struct jpeg_compress_struct * j_compress_ptr; +typedef struct jpeg_decompress_struct * j_decompress_ptr; + + +/* Master record for a compression instance */ + +struct jpeg_compress_struct { + jpeg_common_fields; /* Fields shared with jpeg_decompress_struct */ + + /* Destination for compressed data */ + struct jpeg_destination_mgr * dest; + + /* Description of source image --- these fields must be filled in by + * outer application before starting compression. in_color_space must + * be correct before you can even call jpeg_set_defaults(). + */ + + JDIMENSION image_width; /* input image width */ + JDIMENSION image_height; /* input image height */ + int input_components; /* # of color components in input image */ + J_COLOR_SPACE in_color_space; /* colorspace of input image */ + + double input_gamma; /* image gamma of input image */ + + /* Compression parameters --- these fields must be set before calling + * jpeg_start_compress(). We recommend calling jpeg_set_defaults() to + * initialize everything to reasonable defaults, then changing anything + * the application specifically wants to change. That way you won't get + * burnt when new parameters are added. Also note that there are several + * helper routines to simplify changing parameters. + */ + + int data_precision; /* bits of precision in image data */ + + int num_components; /* # of color components in JPEG image */ + J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */ + + jpeg_component_info * comp_info; + /* comp_info[i] describes component that appears i'th in SOF */ + + JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS]; + /* ptrs to coefficient quantization tables, or NULL if not defined */ + + JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS]; + JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS]; + /* ptrs to Huffman coding tables, or NULL if not defined */ + + UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */ + UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */ + UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */ + + int num_scans; /* # of entries in scan_info array */ + const jpeg_scan_info * scan_info; /* script for multi-scan file, or NULL */ + /* The default value of scan_info is NULL, which causes a single-scan + * sequential JPEG file to be emitted. To create a multi-scan file, + * set num_scans and scan_info to point to an array of scan definitions. + */ + + boolean raw_data_in; /* TRUE=caller supplies downsampled data */ + boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */ + boolean optimize_coding; /* TRUE=optimize entropy encoding parms */ + boolean CCIR601_sampling; /* TRUE=first samples are cosited */ + int smoothing_factor; /* 1..100, or 0 for no input smoothing */ + J_DCT_METHOD dct_method; /* DCT algorithm selector */ + + /* The restart interval can be specified in absolute MCUs by setting + * restart_interval, or in MCU rows by setting restart_in_rows + * (in which case the correct restart_interval will be figured + * for each scan). + */ + unsigned int restart_interval; /* MCUs per restart, or 0 for no restart */ + int restart_in_rows; /* if > 0, MCU rows per restart interval */ + + /* Parameters controlling emission of special markers. */ + + boolean write_JFIF_header; /* should a JFIF marker be written? */ + UINT8 JFIF_major_version; /* What to write for the JFIF version number */ + UINT8 JFIF_minor_version; + /* These three values are not used by the JPEG code, merely copied */ + /* into the JFIF APP0 marker. density_unit can be 0 for unknown, */ + /* 1 for dots/inch, or 2 for dots/cm. Note that the pixel aspect */ + /* ratio is defined by X_density/Y_density even when density_unit=0. */ + UINT8 density_unit; /* JFIF code for pixel size units */ + UINT16 X_density; /* Horizontal pixel density */ + UINT16 Y_density; /* Vertical pixel density */ + boolean write_Adobe_marker; /* should an Adobe marker be written? */ + + /* State variable: index of next scanline to be written to + * jpeg_write_scanlines(). Application may use this to control its + * processing loop, e.g., "while (next_scanline < image_height)". + */ + + JDIMENSION next_scanline; /* 0 .. image_height-1 */ + + /* Remaining fields are known throughout compressor, but generally + * should not be touched by a surrounding application. + */ + + /* + * These fields are computed during compression startup + */ + boolean progressive_mode; /* TRUE if scan script uses progressive mode */ + int max_h_samp_factor; /* largest h_samp_factor */ + int max_v_samp_factor; /* largest v_samp_factor */ + + JDIMENSION total_iMCU_rows; /* # of iMCU rows to be input to coef ctlr */ + /* The coefficient controller receives data in units of MCU rows as defined + * for fully interleaved scans (whether the JPEG file is interleaved or not). + * There are v_samp_factor * DCTSIZE sample rows of each component in an + * "iMCU" (interleaved MCU) row. + */ + + /* + * These fields are valid during any one scan. + * They describe the components and MCUs actually appearing in the scan. + */ + int comps_in_scan; /* # of JPEG components in this scan */ + jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN]; + /* *cur_comp_info[i] describes component that appears i'th in SOS */ + + JDIMENSION MCUs_per_row; /* # of MCUs across the image */ + JDIMENSION MCU_rows_in_scan; /* # of MCU rows in the image */ + + int blocks_in_MCU; /* # of DCT blocks per MCU */ + int MCU_membership[C_MAX_BLOCKS_IN_MCU]; + /* MCU_membership[i] is index in cur_comp_info of component owning */ + /* i'th block in an MCU */ + + int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */ + + /* + * Links to compression subobjects (methods and private variables of modules) + */ + struct jpeg_comp_master * master; + struct jpeg_c_main_controller * main; + struct jpeg_c_prep_controller * prep; + struct jpeg_c_coef_controller * coef; + struct jpeg_marker_writer * marker; + struct jpeg_color_converter * cconvert; + struct jpeg_downsampler * downsample; + struct jpeg_forward_dct * fdct; + struct jpeg_entropy_encoder * entropy; + jpeg_scan_info * script_space; /* workspace for jpeg_simple_progression */ + int script_space_size; +}; + + +/* Master record for a decompression instance */ + +struct jpeg_decompress_struct { + jpeg_common_fields; /* Fields shared with jpeg_compress_struct */ + + /* Source of compressed data */ + struct jpeg_source_mgr * src; + + /* Basic description of image --- filled in by jpeg_read_header(). */ + /* Application may inspect these values to decide how to process image. */ + + JDIMENSION image_width; /* nominal image width (from SOF marker) */ + JDIMENSION image_height; /* nominal image height */ + int num_components; /* # of color components in JPEG image */ + J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */ + + /* Decompression processing parameters --- these fields must be set before + * calling jpeg_start_decompress(). Note that jpeg_read_header() initializes + * them to default values. + */ + + J_COLOR_SPACE out_color_space; /* colorspace for output */ + + unsigned int scale_num, scale_denom; /* fraction by which to scale image */ + + double output_gamma; /* image gamma wanted in output */ + + boolean buffered_image; /* TRUE=multiple output passes */ + boolean raw_data_out; /* TRUE=downsampled data wanted */ + + J_DCT_METHOD dct_method; /* IDCT algorithm selector */ + boolean do_fancy_upsampling; /* TRUE=apply fancy upsampling */ + boolean do_block_smoothing; /* TRUE=apply interblock smoothing */ + + boolean quantize_colors; /* TRUE=colormapped output wanted */ + /* the following are ignored if not quantize_colors: */ + J_DITHER_MODE dither_mode; /* type of color dithering to use */ + boolean two_pass_quantize; /* TRUE=use two-pass color quantization */ + int desired_number_of_colors; /* max # colors to use in created colormap */ + /* these are significant only in buffered-image mode: */ + boolean enable_1pass_quant; /* enable future use of 1-pass quantizer */ + boolean enable_external_quant;/* enable future use of external colormap */ + boolean enable_2pass_quant; /* enable future use of 2-pass quantizer */ + + /* Description of actual output image that will be returned to application. + * These fields are computed by jpeg_start_decompress(). + * You can also use jpeg_calc_output_dimensions() to determine these values + * in advance of calling jpeg_start_decompress(). + */ + + JDIMENSION output_width; /* scaled image width */ + JDIMENSION output_height; /* scaled image height */ + int out_color_components; /* # of color components in out_color_space */ + int output_components; /* # of color components returned */ + /* output_components is 1 (a colormap index) when quantizing colors; + * otherwise it equals out_color_components. + */ + int rec_outbuf_height; /* min recommended height of scanline buffer */ + /* If the buffer passed to jpeg_read_scanlines() is less than this many rows + * high, space and time will be wasted due to unnecessary data copying. + * Usually rec_outbuf_height will be 1 or 2, at most 4. + */ + + /* When quantizing colors, the output colormap is described by these fields. + * The application can supply a colormap by setting colormap non-NULL before + * calling jpeg_start_decompress; otherwise a colormap is created during + * jpeg_start_decompress or jpeg_start_output. + * The map has out_color_components rows and actual_number_of_colors columns. + */ + int actual_number_of_colors; /* number of entries in use */ + JSAMPARRAY colormap; /* The color map as a 2-D pixel array */ + + /* State variables: these variables indicate the progress of decompression. + * The application may examine these but must not modify them. + */ + + /* Row index of next scanline to be read from jpeg_read_scanlines(). + * Application may use this to control its processing loop, e.g., + * "while (output_scanline < output_height)". + */ + JDIMENSION output_scanline; /* 0 .. output_height-1 */ + + /* Current input scan number and number of iMCU rows completed in scan. + * These indicate the progress of the decompressor input side. + */ + int input_scan_number; /* Number of SOS markers seen so far */ + JDIMENSION input_iMCU_row; /* Number of iMCU rows completed */ + + /* The "output scan number" is the notional scan being displayed by the + * output side. The decompressor will not allow output scan/row number + * to get ahead of input scan/row, but it can fall arbitrarily far behind. + */ + int output_scan_number; /* Nominal scan number being displayed */ + JDIMENSION output_iMCU_row; /* Number of iMCU rows read */ + + /* Current progression status. coef_bits[c][i] indicates the precision + * with which component c's DCT coefficient i (in zigzag order) is known. + * It is -1 when no data has yet been received, otherwise it is the point + * transform (shift) value for the most recent scan of the coefficient + * (thus, 0 at completion of the progression). + * This pointer is NULL when reading a non-progressive file. + */ + int (*coef_bits)[DCTSIZE2]; /* -1 or current Al value for each coef */ + + /* Internal JPEG parameters --- the application usually need not look at + * these fields. Note that the decompressor output side may not use + * any parameters that can change between scans. + */ + + /* Quantization and Huffman tables are carried forward across input + * datastreams when processing abbreviated JPEG datastreams. + */ + + JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS]; + /* ptrs to coefficient quantization tables, or NULL if not defined */ + + JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS]; + JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS]; + /* ptrs to Huffman coding tables, or NULL if not defined */ + + /* These parameters are never carried across datastreams, since they + * are given in SOF/SOS markers or defined to be reset by SOI. + */ + + int data_precision; /* bits of precision in image data */ + + jpeg_component_info * comp_info; + /* comp_info[i] describes component that appears i'th in SOF */ + + boolean progressive_mode; /* TRUE if SOFn specifies progressive mode */ + boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */ + + UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */ + UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */ + UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */ + + unsigned int restart_interval; /* MCUs per restart interval, or 0 for no restart */ + + /* These fields record data obtained from optional markers recognized by + * the JPEG library. + */ + boolean saw_JFIF_marker; /* TRUE iff a JFIF APP0 marker was found */ + /* Data copied from JFIF marker; only valid if saw_JFIF_marker is TRUE: */ + UINT8 JFIF_major_version; /* JFIF version number */ + UINT8 JFIF_minor_version; + UINT8 density_unit; /* JFIF code for pixel size units */ + UINT16 X_density; /* Horizontal pixel density */ + UINT16 Y_density; /* Vertical pixel density */ + boolean saw_Adobe_marker; /* TRUE iff an Adobe APP14 marker was found */ + UINT8 Adobe_transform; /* Color transform code from Adobe marker */ + + boolean CCIR601_sampling; /* TRUE=first samples are cosited */ + + /* Aside from the specific data retained from APPn markers known to the + * library, the uninterpreted contents of any or all APPn and COM markers + * can be saved in a list for examination by the application. + */ + jpeg_saved_marker_ptr marker_list; /* Head of list of saved markers */ + + /* Remaining fields are known throughout decompressor, but generally + * should not be touched by a surrounding application. + */ + + /* + * These fields are computed during decompression startup + */ + int max_h_samp_factor; /* largest h_samp_factor */ + int max_v_samp_factor; /* largest v_samp_factor */ + + int min_DCT_scaled_size; /* smallest DCT_scaled_size of any component */ + + JDIMENSION total_iMCU_rows; /* # of iMCU rows in image */ + /* The coefficient controller's input and output progress is measured in + * units of "iMCU" (interleaved MCU) rows. These are the same as MCU rows + * in fully interleaved JPEG scans, but are used whether the scan is + * interleaved or not. We define an iMCU row as v_samp_factor DCT block + * rows of each component. Therefore, the IDCT output contains + * v_samp_factor*DCT_scaled_size sample rows of a component per iMCU row. + */ + + JSAMPLE * sample_range_limit; /* table for fast range-limiting */ + + /* + * These fields are valid during any one scan. + * They describe the components and MCUs actually appearing in the scan. + * Note that the decompressor output side must not use these fields. + */ + int comps_in_scan; /* # of JPEG components in this scan */ + jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN]; + /* *cur_comp_info[i] describes component that appears i'th in SOS */ + + JDIMENSION MCUs_per_row; /* # of MCUs across the image */ + JDIMENSION MCU_rows_in_scan; /* # of MCU rows in the image */ + + int blocks_in_MCU; /* # of DCT blocks per MCU */ + int MCU_membership[D_MAX_BLOCKS_IN_MCU]; + /* MCU_membership[i] is index in cur_comp_info of component owning */ + /* i'th block in an MCU */ + + int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */ + + /* This field is shared between entropy decoder and marker parser. + * It is either zero or the code of a JPEG marker that has been + * read from the data source, but has not yet been processed. + */ + int unread_marker; + + /* + * Links to decompression subobjects (methods, private variables of modules) + */ + struct jpeg_decomp_master * master; + struct jpeg_d_main_controller * main; + struct jpeg_d_coef_controller * coef; + struct jpeg_d_post_controller * post; + struct jpeg_input_controller * inputctl; + struct jpeg_marker_reader * marker; + struct jpeg_entropy_decoder * entropy; + struct jpeg_inverse_dct * idct; + struct jpeg_upsampler * upsample; + struct jpeg_color_deconverter * cconvert; + struct jpeg_color_quantizer * cquantize; +}; + + +/* "Object" declarations for JPEG modules that may be supplied or called + * directly by the surrounding application. + * As with all objects in the JPEG library, these structs only define the + * publicly visible methods and state variables of a module. Additional + * private fields may exist after the public ones. + */ + + +/* Error handler object */ + +struct jpeg_error_mgr { + /* Error exit handler: does not return to caller */ + JMETHOD(void, error_exit, (j_common_ptr cinfo)); + /* Conditionally emit a trace or warning message */ + JMETHOD(void, emit_message, (j_common_ptr cinfo, int msg_level)); + /* Routine that actually outputs a trace or error message */ + JMETHOD(void, output_message, (j_common_ptr cinfo)); + /* Format a message string for the most recent JPEG error or message */ + JMETHOD(void, format_message, (j_common_ptr cinfo, char * buffer)); +#define JMSG_LENGTH_MAX 200 /* recommended size of format_message buffer */ + /* Reset error state variables at start of a new image */ + JMETHOD(void, reset_error_mgr, (j_common_ptr cinfo)); + + /* The message ID code and any parameters are saved here. + * A message can have one string parameter or up to 8 int parameters. + */ + int msg_code; +#define JMSG_STR_PARM_MAX 80 + union { + int i[8]; + char s[JMSG_STR_PARM_MAX]; + } msg_parm; + + /* Standard state variables for error facility */ + + int trace_level; /* max msg_level that will be displayed */ + + /* For recoverable corrupt-data errors, we emit a warning message, + * but keep going unless emit_message chooses to abort. emit_message + * should count warnings in num_warnings. The surrounding application + * can check for bad data by seeing if num_warnings is nonzero at the + * end of processing. + */ + long num_warnings; /* number of corrupt-data warnings */ + + /* These fields point to the table(s) of error message strings. + * An application can change the table pointer to switch to a different + * message list (typically, to change the language in which errors are + * reported). Some applications may wish to add additional error codes + * that will be handled by the JPEG library error mechanism; the second + * table pointer is used for this purpose. + * + * First table includes all errors generated by JPEG library itself. + * Error code 0 is reserved for a "no such error string" message. + */ + const char * const * jpeg_message_table; /* Library errors */ + int last_jpeg_message; /* Table contains strings 0..last_jpeg_message */ + /* Second table can be added by application (see cjpeg/djpeg for example). + * It contains strings numbered first_addon_message..last_addon_message. + */ + const char * const * addon_message_table; /* Non-library errors */ + int first_addon_message; /* code for first string in addon table */ + int last_addon_message; /* code for last string in addon table */ +}; + + +/* Progress monitor object */ + +struct jpeg_progress_mgr { + JMETHOD(void, progress_monitor, (j_common_ptr cinfo)); + + long pass_counter; /* work units completed in this pass */ + long pass_limit; /* total number of work units in this pass */ + int completed_passes; /* passes completed so far */ + int total_passes; /* total number of passes expected */ +}; + + +/* Data destination object for compression */ + +struct jpeg_destination_mgr { + + JOCTET * next_output_byte; /* => next byte to write in buffer */ + + size_t free_in_buffer; /* # of byte spaces remaining in buffer */ + + JMETHOD(void, init_destination, (j_compress_ptr cinfo)); + JMETHOD(boolean, empty_output_buffer, (j_compress_ptr cinfo)); + JMETHOD(void, term_destination, (j_compress_ptr cinfo)); +}; + + +/* Data source object for decompression */ + +struct jpeg_source_mgr { + const JOCTET * next_input_byte; /* => next byte to read from buffer */ + size_t bytes_in_buffer; /* # of bytes remaining in buffer */ + + JMETHOD(void, init_source, (j_decompress_ptr cinfo)); + JMETHOD(boolean, fill_input_buffer, (j_decompress_ptr cinfo)); + JMETHOD(void, skip_input_data, (j_decompress_ptr cinfo, long num_bytes)); + JMETHOD(boolean, resync_to_restart, (j_decompress_ptr cinfo, int desired)); + JMETHOD(void, term_source, (j_decompress_ptr cinfo)); +}; + + +/* Memory manager object. + * Allocates "small" objects (a few K total), "large" objects (tens of K), + * and "really big" objects (virtual arrays with backing store if needed). + * The memory manager does not allow individual objects to be freed; rather, + * each created object is assigned to a pool, and whole pools can be freed + * at once. This is faster and more convenient than remembering exactly what + * to free, especially where malloc()/free() are not too speedy. + * NB: alloc routines never return NULL. They exit to error_exit if not + * successful. + */ + +#define JPOOL_PERMANENT 0 /* lasts until master record is destroyed */ +#define JPOOL_IMAGE 1 /* lasts until done with image/datastream */ +#define JPOOL_NUMPOOLS 2 + +typedef struct jvirt_sarray_control * jvirt_sarray_ptr; +typedef struct jvirt_barray_control * jvirt_barray_ptr; + + +struct jpeg_memory_mgr { + /* Method pointers */ + JMETHOD(void *, alloc_small, (j_common_ptr cinfo, int pool_id, + size_t sizeofobject)); + JMETHOD(void FAR *, alloc_large, (j_common_ptr cinfo, int pool_id, + size_t sizeofobject)); + JMETHOD(JSAMPARRAY, alloc_sarray, (j_common_ptr cinfo, int pool_id, + JDIMENSION samplesperrow, + JDIMENSION numrows)); + JMETHOD(JBLOCKARRAY, alloc_barray, (j_common_ptr cinfo, int pool_id, + JDIMENSION blocksperrow, + JDIMENSION numrows)); + JMETHOD(jvirt_sarray_ptr, request_virt_sarray, (j_common_ptr cinfo, + int pool_id, + boolean pre_zero, + JDIMENSION samplesperrow, + JDIMENSION numrows, + JDIMENSION maxaccess)); + JMETHOD(jvirt_barray_ptr, request_virt_barray, (j_common_ptr cinfo, + int pool_id, + boolean pre_zero, + JDIMENSION blocksperrow, + JDIMENSION numrows, + JDIMENSION maxaccess)); + JMETHOD(void, realize_virt_arrays, (j_common_ptr cinfo)); + JMETHOD(JSAMPARRAY, access_virt_sarray, (j_common_ptr cinfo, + jvirt_sarray_ptr ptr, + JDIMENSION start_row, + JDIMENSION num_rows, + boolean writable)); + JMETHOD(JBLOCKARRAY, access_virt_barray, (j_common_ptr cinfo, + jvirt_barray_ptr ptr, + JDIMENSION start_row, + JDIMENSION num_rows, + boolean writable)); + JMETHOD(void, free_pool, (j_common_ptr cinfo, int pool_id)); + JMETHOD(void, self_destruct, (j_common_ptr cinfo)); + + /* Limit on memory allocation for this JPEG object. (Note that this is + * merely advisory, not a guaranteed maximum; it only affects the space + * used for virtual-array buffers.) May be changed by outer application + * after creating the JPEG object. + */ + long max_memory_to_use; + + /* Maximum allocation request accepted by alloc_large. */ + long max_alloc_chunk; +}; + + +/* Routine signature for application-supplied marker processing methods. + * Need not pass marker code since it is stored in cinfo->unread_marker. + */ +typedef JMETHOD(boolean, jpeg_marker_parser_method, (j_decompress_ptr cinfo)); + + +/* Declarations for routines called by application. + * The JPP macro hides prototype parameters from compilers that can't cope. + * Note JPP requires double parentheses. + */ + +#ifdef HAVE_PROTOTYPES +#define JPP(arglist) arglist +#else +#define JPP(arglist) () +#endif + + +/* Short forms of external names for systems with brain-damaged linkers. + * We shorten external names to be unique in the first six letters, which + * is good enough for all known systems. + * (If your compiler itself needs names to be unique in less than 15 + * characters, you are out of luck. Get a better compiler.) + */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jpeg_std_error jStdError +#define jpeg_CreateCompress jCreaCompress +#define jpeg_CreateDecompress jCreaDecompress +#define jpeg_destroy_compress jDestCompress +#define jpeg_destroy_decompress jDestDecompress +#define jpeg_stdio_dest jStdDest +#define jpeg_stdio_src jStdSrc +#define jpeg_set_defaults jSetDefaults +#define jpeg_set_colorspace jSetColorspace +#define jpeg_default_colorspace jDefColorspace +#define jpeg_set_quality jSetQuality +#define jpeg_set_linear_quality jSetLQuality +#define jpeg_add_quant_table jAddQuantTable +#define jpeg_quality_scaling jQualityScaling +#define jpeg_simple_progression jSimProgress +#define jpeg_suppress_tables jSuppressTables +#define jpeg_alloc_quant_table jAlcQTable +#define jpeg_alloc_huff_table jAlcHTable +#define jpeg_start_compress jStrtCompress +#define jpeg_write_scanlines jWrtScanlines +#define jpeg_finish_compress jFinCompress +#define jpeg_write_raw_data jWrtRawData +#define jpeg_write_marker jWrtMarker +#define jpeg_write_m_header jWrtMHeader +#define jpeg_write_m_byte jWrtMByte +#define jpeg_write_tables jWrtTables +#define jpeg_read_header jReadHeader +#define jpeg_start_decompress jStrtDecompress +#define jpeg_read_scanlines jReadScanlines +#define jpeg_finish_decompress jFinDecompress +#define jpeg_read_raw_data jReadRawData +#define jpeg_has_multiple_scans jHasMultScn +#define jpeg_start_output jStrtOutput +#define jpeg_finish_output jFinOutput +#define jpeg_input_complete jInComplete +#define jpeg_new_colormap jNewCMap +#define jpeg_consume_input jConsumeInput +#define jpeg_calc_output_dimensions jCalcDimensions +#define jpeg_save_markers jSaveMarkers +#define jpeg_set_marker_processor jSetMarker +#define jpeg_read_coefficients jReadCoefs +#define jpeg_write_coefficients jWrtCoefs +#define jpeg_copy_critical_parameters jCopyCrit +#define jpeg_abort_compress jAbrtCompress +#define jpeg_abort_decompress jAbrtDecompress +#define jpeg_abort jAbort +#define jpeg_destroy jDestroy +#define jpeg_resync_to_restart jResyncRestart +#endif /* NEED_SHORT_EXTERNAL_NAMES */ + + +/* Default error-management setup */ +EXTERN(struct jpeg_error_mgr *) jpeg_std_error + JPP((struct jpeg_error_mgr * err)); + +/* Initialization of JPEG compression objects. + * jpeg_create_compress() and jpeg_create_decompress() are the exported + * names that applications should call. These expand to calls on + * jpeg_CreateCompress and jpeg_CreateDecompress with additional information + * passed for version mismatch checking. + * NB: you must set up the error-manager BEFORE calling jpeg_create_xxx. + */ +#define jpeg_create_compress(cinfo) \ + jpeg_CreateCompress((cinfo), JPEG_LIB_VERSION, \ + (size_t) sizeof(struct jpeg_compress_struct)) +#define jpeg_create_decompress(cinfo) \ + jpeg_CreateDecompress((cinfo), JPEG_LIB_VERSION, \ + (size_t) sizeof(struct jpeg_decompress_struct)) +EXTERN(void) jpeg_CreateCompress JPP((j_compress_ptr cinfo, + int version, size_t structsize)); +EXTERN(void) jpeg_CreateDecompress JPP((j_decompress_ptr cinfo, + int version, size_t structsize)); +/* Destruction of JPEG compression objects */ +EXTERN(void) jpeg_destroy_compress JPP((j_compress_ptr cinfo)); +EXTERN(void) jpeg_destroy_decompress JPP((j_decompress_ptr cinfo)); + +/* Standard data source and destination managers: stdio streams. */ +/* Caller is responsible for opening the file before and closing after. */ +EXTERN(void) jpeg_stdio_dest JPP((j_compress_ptr cinfo, FILE * outfile)); +EXTERN(void) jpeg_stdio_src JPP((j_decompress_ptr cinfo, FILE * infile)); + +/* Default parameter setup for compression */ +EXTERN(void) jpeg_set_defaults JPP((j_compress_ptr cinfo)); +/* Compression parameter setup aids */ +EXTERN(void) jpeg_set_colorspace JPP((j_compress_ptr cinfo, + J_COLOR_SPACE colorspace)); +EXTERN(void) jpeg_default_colorspace JPP((j_compress_ptr cinfo)); +EXTERN(void) jpeg_set_quality JPP((j_compress_ptr cinfo, int quality, + boolean force_baseline)); +EXTERN(void) jpeg_set_linear_quality JPP((j_compress_ptr cinfo, + int scale_factor, + boolean force_baseline)); +EXTERN(void) jpeg_add_quant_table JPP((j_compress_ptr cinfo, int which_tbl, + const unsigned int *basic_table, + int scale_factor, + boolean force_baseline)); +EXTERN(int) jpeg_quality_scaling JPP((int quality)); +EXTERN(void) jpeg_simple_progression JPP((j_compress_ptr cinfo)); +EXTERN(void) jpeg_suppress_tables JPP((j_compress_ptr cinfo, + boolean suppress)); +EXTERN(JQUANT_TBL *) jpeg_alloc_quant_table JPP((j_common_ptr cinfo)); +EXTERN(JHUFF_TBL *) jpeg_alloc_huff_table JPP((j_common_ptr cinfo)); + +/* Main entry points for compression */ +EXTERN(void) jpeg_start_compress JPP((j_compress_ptr cinfo, + boolean write_all_tables)); +EXTERN(JDIMENSION) jpeg_write_scanlines JPP((j_compress_ptr cinfo, + JSAMPARRAY scanlines, + JDIMENSION num_lines)); +EXTERN(void) jpeg_finish_compress JPP((j_compress_ptr cinfo)); + +/* Replaces jpeg_write_scanlines when writing raw downsampled data. */ +EXTERN(JDIMENSION) jpeg_write_raw_data JPP((j_compress_ptr cinfo, + JSAMPIMAGE data, + JDIMENSION num_lines)); + +/* Write a special marker. See libjpeg.doc concerning safe usage. */ +EXTERN(void) jpeg_write_marker + JPP((j_compress_ptr cinfo, int marker, + const JOCTET * dataptr, unsigned int datalen)); +/* Same, but piecemeal. */ +EXTERN(void) jpeg_write_m_header + JPP((j_compress_ptr cinfo, int marker, unsigned int datalen)); +EXTERN(void) jpeg_write_m_byte + JPP((j_compress_ptr cinfo, int val)); + +/* Alternate compression function: just write an abbreviated table file */ +EXTERN(void) jpeg_write_tables JPP((j_compress_ptr cinfo)); + +/* Decompression startup: read start of JPEG datastream to see what's there */ +EXTERN(int) jpeg_read_header JPP((j_decompress_ptr cinfo, + boolean require_image)); +/* Return value is one of: */ +#define JPEG_SUSPENDED 0 /* Suspended due to lack of input data */ +#define JPEG_HEADER_OK 1 /* Found valid image datastream */ +#define JPEG_HEADER_TABLES_ONLY 2 /* Found valid table-specs-only datastream */ +/* If you pass require_image = TRUE (normal case), you need not check for + * a TABLES_ONLY return code; an abbreviated file will cause an error exit. + * JPEG_SUSPENDED is only possible if you use a data source module that can + * give a suspension return (the stdio source module doesn't). + */ + +/* Main entry points for decompression */ +EXTERN(boolean) jpeg_start_decompress JPP((j_decompress_ptr cinfo)); +EXTERN(JDIMENSION) jpeg_read_scanlines JPP((j_decompress_ptr cinfo, + JSAMPARRAY scanlines, + JDIMENSION max_lines)); +EXTERN(boolean) jpeg_finish_decompress JPP((j_decompress_ptr cinfo)); + +/* Replaces jpeg_read_scanlines when reading raw downsampled data. */ +EXTERN(JDIMENSION) jpeg_read_raw_data JPP((j_decompress_ptr cinfo, + JSAMPIMAGE data, + JDIMENSION max_lines)); + +/* Additional entry points for buffered-image mode. */ +EXTERN(boolean) jpeg_has_multiple_scans JPP((j_decompress_ptr cinfo)); +EXTERN(boolean) jpeg_start_output JPP((j_decompress_ptr cinfo, + int scan_number)); +EXTERN(boolean) jpeg_finish_output JPP((j_decompress_ptr cinfo)); +EXTERN(boolean) jpeg_input_complete JPP((j_decompress_ptr cinfo)); +EXTERN(void) jpeg_new_colormap JPP((j_decompress_ptr cinfo)); +EXTERN(int) jpeg_consume_input JPP((j_decompress_ptr cinfo)); +/* Return value is one of: */ +/* #define JPEG_SUSPENDED 0 Suspended due to lack of input data */ +#define JPEG_REACHED_SOS 1 /* Reached start of new scan */ +#define JPEG_REACHED_EOI 2 /* Reached end of image */ +#define JPEG_ROW_COMPLETED 3 /* Completed one iMCU row */ +#define JPEG_SCAN_COMPLETED 4 /* Completed last iMCU row of a scan */ + +/* Precalculate output dimensions for current decompression parameters. */ +EXTERN(void) jpeg_calc_output_dimensions JPP((j_decompress_ptr cinfo)); + +/* Control saving of COM and APPn markers into marker_list. */ +EXTERN(void) jpeg_save_markers + JPP((j_decompress_ptr cinfo, int marker_code, + unsigned int length_limit)); + +/* Install a special processing method for COM or APPn markers. */ +EXTERN(void) jpeg_set_marker_processor + JPP((j_decompress_ptr cinfo, int marker_code, + jpeg_marker_parser_method routine)); + +/* Read or write raw DCT coefficients --- useful for lossless transcoding. */ +EXTERN(jvirt_barray_ptr *) jpeg_read_coefficients JPP((j_decompress_ptr cinfo)); +EXTERN(void) jpeg_write_coefficients JPP((j_compress_ptr cinfo, + jvirt_barray_ptr * coef_arrays)); +EXTERN(void) jpeg_copy_critical_parameters JPP((j_decompress_ptr srcinfo, + j_compress_ptr dstinfo)); + +/* If you choose to abort compression or decompression before completing + * jpeg_finish_(de)compress, then you need to clean up to release memory, + * temporary files, etc. You can just call jpeg_destroy_(de)compress + * if you're done with the JPEG object, but if you want to clean it up and + * reuse it, call this: + */ +EXTERN(void) jpeg_abort_compress JPP((j_compress_ptr cinfo)); +EXTERN(void) jpeg_abort_decompress JPP((j_decompress_ptr cinfo)); + +/* Generic versions of jpeg_abort and jpeg_destroy that work on either + * flavor of JPEG object. These may be more convenient in some places. + */ +EXTERN(void) jpeg_abort JPP((j_common_ptr cinfo)); +EXTERN(void) jpeg_destroy JPP((j_common_ptr cinfo)); + +/* Default restart-marker-resync procedure for use by data source modules */ +EXTERN(boolean) jpeg_resync_to_restart JPP((j_decompress_ptr cinfo, + int desired)); + + +/* These marker codes are exported since applications and data source modules + * are likely to want to use them. + */ + +#define JPEG_RST0 0xD0 /* RST0 marker code */ +#define JPEG_EOI 0xD9 /* EOI marker code */ +#define JPEG_APP0 0xE0 /* APP0 marker code */ +#define JPEG_COM 0xFE /* COM marker code */ + + +/* If we have a brain-damaged compiler that emits warnings (or worse, errors) + * for structure definitions that are never filled in, keep it quiet by + * supplying dummy definitions for the various substructures. + */ + +#ifdef INCOMPLETE_TYPES_BROKEN +#ifndef JPEG_INTERNALS /* will be defined in jpegint.h */ +struct jvirt_sarray_control { long dummy; }; +struct jvirt_barray_control { long dummy; }; +struct jpeg_comp_master { long dummy; }; +struct jpeg_c_main_controller { long dummy; }; +struct jpeg_c_prep_controller { long dummy; }; +struct jpeg_c_coef_controller { long dummy; }; +struct jpeg_marker_writer { long dummy; }; +struct jpeg_color_converter { long dummy; }; +struct jpeg_downsampler { long dummy; }; +struct jpeg_forward_dct { long dummy; }; +struct jpeg_entropy_encoder { long dummy; }; +struct jpeg_decomp_master { long dummy; }; +struct jpeg_d_main_controller { long dummy; }; +struct jpeg_d_coef_controller { long dummy; }; +struct jpeg_d_post_controller { long dummy; }; +struct jpeg_input_controller { long dummy; }; +struct jpeg_marker_reader { long dummy; }; +struct jpeg_entropy_decoder { long dummy; }; +struct jpeg_inverse_dct { long dummy; }; +struct jpeg_upsampler { long dummy; }; +struct jpeg_color_deconverter { long dummy; }; +struct jpeg_color_quantizer { long dummy; }; +#endif /* JPEG_INTERNALS */ +#endif /* INCOMPLETE_TYPES_BROKEN */ + + +/* + * The JPEG library modules define JPEG_INTERNALS before including this file. + * The internal structure declarations are read only when that is true. + * Applications using the library should not include jpegint.h, but may wish + * to include jerror.h. + */ + +#ifdef JPEG_INTERNALS +#include "jpegint.h" /* fetch private declarations */ +#include "jerror.h" /* fetch error codes too */ +#endif + +#endif /* JPEGLIB_H */ diff --git a/mod/pub.mod/libjpeg.mod/jquant1.c b/mod/pub.mod/libjpeg.mod/jquant1.c new file mode 100644 index 0000000..b2f96aa --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jquant1.c @@ -0,0 +1,856 @@ +/* + * jquant1.c + * + * Copyright (C) 1991-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains 1-pass color quantization (color mapping) routines. + * These routines provide mapping to a fixed color map using equally spaced + * color values. Optional Floyd-Steinberg or ordered dithering is available. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + +#ifdef QUANT_1PASS_SUPPORTED + + +/* + * The main purpose of 1-pass quantization is to provide a fast, if not very + * high quality, colormapped output capability. A 2-pass quantizer usually + * gives better visual quality; however, for quantized grayscale output this + * quantizer is perfectly adequate. Dithering is highly recommended with this + * quantizer, though you can turn it off if you really want to. + * + * In 1-pass quantization the colormap must be chosen in advance of seeing the + * image. We use a map consisting of all combinations of Ncolors[i] color + * values for the i'th component. The Ncolors[] values are chosen so that + * their product, the total number of colors, is no more than that requested. + * (In most cases, the product will be somewhat less.) + * + * Since the colormap is orthogonal, the representative value for each color + * component can be determined without considering the other components; + * then these indexes can be combined into a colormap index by a standard + * N-dimensional-array-subscript calculation. Most of the arithmetic involved + * can be precalculated and stored in the lookup table colorindex[]. + * colorindex[i][j] maps pixel value j in component i to the nearest + * representative value (grid plane) for that component; this index is + * multiplied by the array stride for component i, so that the + * index of the colormap entry closest to a given pixel value is just + * sum( colorindex[component-number][pixel-component-value] ) + * Aside from being fast, this scheme allows for variable spacing between + * representative values with no additional lookup cost. + * + * If gamma correction has been applied in color conversion, it might be wise + * to adjust the color grid spacing so that the representative colors are + * equidistant in linear space. At this writing, gamma correction is not + * implemented by jdcolor, so nothing is done here. + */ + + +/* Declarations for ordered dithering. + * + * We use a standard 16x16 ordered dither array. The basic concept of ordered + * dithering is described in many references, for instance Dale Schumacher's + * chapter II.2 of Graphics Gems II (James Arvo, ed. Academic Press, 1991). + * In place of Schumacher's comparisons against a "threshold" value, we add a + * "dither" value to the input pixel and then round the result to the nearest + * output value. The dither value is equivalent to (0.5 - threshold) times + * the distance between output values. For ordered dithering, we assume that + * the output colors are equally spaced; if not, results will probably be + * worse, since the dither may be too much or too little at a given point. + * + * The normal calculation would be to form pixel value + dither, range-limit + * this to 0..MAXJSAMPLE, and then index into the colorindex table as usual. + * We can skip the separate range-limiting step by extending the colorindex + * table in both directions. + */ + +#define ODITHER_SIZE 16 /* dimension of dither matrix */ +/* NB: if ODITHER_SIZE is not a power of 2, ODITHER_MASK uses will break */ +#define ODITHER_CELLS (ODITHER_SIZE*ODITHER_SIZE) /* # cells in matrix */ +#define ODITHER_MASK (ODITHER_SIZE-1) /* mask for wrapping around counters */ + +typedef int ODITHER_MATRIX[ODITHER_SIZE][ODITHER_SIZE]; +typedef int (*ODITHER_MATRIX_PTR)[ODITHER_SIZE]; + +static const UINT8 base_dither_matrix[ODITHER_SIZE][ODITHER_SIZE] = { + /* Bayer's order-4 dither array. Generated by the code given in + * Stephen Hawley's article "Ordered Dithering" in Graphics Gems I. + * The values in this array must range from 0 to ODITHER_CELLS-1. + */ + { 0,192, 48,240, 12,204, 60,252, 3,195, 51,243, 15,207, 63,255 }, + { 128, 64,176,112,140, 76,188,124,131, 67,179,115,143, 79,191,127 }, + { 32,224, 16,208, 44,236, 28,220, 35,227, 19,211, 47,239, 31,223 }, + { 160, 96,144, 80,172,108,156, 92,163, 99,147, 83,175,111,159, 95 }, + { 8,200, 56,248, 4,196, 52,244, 11,203, 59,251, 7,199, 55,247 }, + { 136, 72,184,120,132, 68,180,116,139, 75,187,123,135, 71,183,119 }, + { 40,232, 24,216, 36,228, 20,212, 43,235, 27,219, 39,231, 23,215 }, + { 168,104,152, 88,164,100,148, 84,171,107,155, 91,167,103,151, 87 }, + { 2,194, 50,242, 14,206, 62,254, 1,193, 49,241, 13,205, 61,253 }, + { 130, 66,178,114,142, 78,190,126,129, 65,177,113,141, 77,189,125 }, + { 34,226, 18,210, 46,238, 30,222, 33,225, 17,209, 45,237, 29,221 }, + { 162, 98,146, 82,174,110,158, 94,161, 97,145, 81,173,109,157, 93 }, + { 10,202, 58,250, 6,198, 54,246, 9,201, 57,249, 5,197, 53,245 }, + { 138, 74,186,122,134, 70,182,118,137, 73,185,121,133, 69,181,117 }, + { 42,234, 26,218, 38,230, 22,214, 41,233, 25,217, 37,229, 21,213 }, + { 170,106,154, 90,166,102,150, 86,169,105,153, 89,165,101,149, 85 } +}; + + +/* Declarations for Floyd-Steinberg dithering. + * + * Errors are accumulated into the array fserrors[], at a resolution of + * 1/16th of a pixel count. The error at a given pixel is propagated + * to its not-yet-processed neighbors using the standard F-S fractions, + * ... (here) 7/16 + * 3/16 5/16 1/16 + * We work left-to-right on even rows, right-to-left on odd rows. + * + * We can get away with a single array (holding one row's worth of errors) + * by using it to store the current row's errors at pixel columns not yet + * processed, but the next row's errors at columns already processed. We + * need only a few extra variables to hold the errors immediately around the + * current column. (If we are lucky, those variables are in registers, but + * even if not, they're probably cheaper to access than array elements are.) + * + * The fserrors[] array is indexed [component#][position]. + * We provide (#columns + 2) entries per component; the extra entry at each + * end saves us from special-casing the first and last pixels. + * + * Note: on a wide image, we might not have enough room in a PC's near data + * segment to hold the error array; so it is allocated with alloc_large. + */ + +#if BITS_IN_JSAMPLE == 8 +typedef INT16 FSERROR; /* 16 bits should be enough */ +typedef int LOCFSERROR; /* use 'int' for calculation temps */ +#else +typedef INT32 FSERROR; /* may need more than 16 bits */ +typedef INT32 LOCFSERROR; /* be sure calculation temps are big enough */ +#endif + +typedef FSERROR FAR *FSERRPTR; /* pointer to error array (in FAR storage!) */ + + +/* Private subobject */ + +#define MAX_Q_COMPS 4 /* max components I can handle */ + +typedef struct { + struct jpeg_color_quantizer pub; /* public fields */ + + /* Initially allocated colormap is saved here */ + JSAMPARRAY sv_colormap; /* The color map as a 2-D pixel array */ + int sv_actual; /* number of entries in use */ + + JSAMPARRAY colorindex; /* Precomputed mapping for speed */ + /* colorindex[i][j] = index of color closest to pixel value j in component i, + * premultiplied as described above. Since colormap indexes must fit into + * JSAMPLEs, the entries of this array will too. + */ + boolean is_padded; /* is the colorindex padded for odither? */ + + int Ncolors[MAX_Q_COMPS]; /* # of values alloced to each component */ + + /* Variables for ordered dithering */ + int row_index; /* cur row's vertical index in dither matrix */ + ODITHER_MATRIX_PTR odither[MAX_Q_COMPS]; /* one dither array per component */ + + /* Variables for Floyd-Steinberg dithering */ + FSERRPTR fserrors[MAX_Q_COMPS]; /* accumulated errors */ + boolean on_odd_row; /* flag to remember which row we are on */ +} my_cquantizer; + +typedef my_cquantizer * my_cquantize_ptr; + + +/* + * Policy-making subroutines for create_colormap and create_colorindex. + * These routines determine the colormap to be used. The rest of the module + * only assumes that the colormap is orthogonal. + * + * * select_ncolors decides how to divvy up the available colors + * among the components. + * * output_value defines the set of representative values for a component. + * * largest_input_value defines the mapping from input values to + * representative values for a component. + * Note that the latter two routines may impose different policies for + * different components, though this is not currently done. + */ + + +LOCAL(int) +select_ncolors (j_decompress_ptr cinfo, int Ncolors[]) +/* Determine allocation of desired colors to components, */ +/* and fill in Ncolors[] array to indicate choice. */ +/* Return value is total number of colors (product of Ncolors[] values). */ +{ + int nc = cinfo->out_color_components; /* number of color components */ + int max_colors = cinfo->desired_number_of_colors; + int total_colors, iroot, i, j; + boolean changed; + long temp; + static const int RGB_order[3] = { RGB_GREEN, RGB_RED, RGB_BLUE }; + + /* We can allocate at least the nc'th root of max_colors per component. */ + /* Compute floor(nc'th root of max_colors). */ + iroot = 1; + do { + iroot++; + temp = iroot; /* set temp = iroot ** nc */ + for (i = 1; i < nc; i++) + temp *= iroot; + } while (temp <= (long) max_colors); /* repeat till iroot exceeds root */ + iroot--; /* now iroot = floor(root) */ + + /* Must have at least 2 color values per component */ + if (iroot < 2) + ERREXIT1(cinfo, JERR_QUANT_FEW_COLORS, (int) temp); + + /* Initialize to iroot color values for each component */ + total_colors = 1; + for (i = 0; i < nc; i++) { + Ncolors[i] = iroot; + total_colors *= iroot; + } + /* We may be able to increment the count for one or more components without + * exceeding max_colors, though we know not all can be incremented. + * Sometimes, the first component can be incremented more than once! + * (Example: for 16 colors, we start at 2*2*2, go to 3*2*2, then 4*2*2.) + * In RGB colorspace, try to increment G first, then R, then B. + */ + do { + changed = FALSE; + for (i = 0; i < nc; i++) { + j = (cinfo->out_color_space == JCS_RGB ? RGB_order[i] : i); + /* calculate new total_colors if Ncolors[j] is incremented */ + temp = total_colors / Ncolors[j]; + temp *= Ncolors[j]+1; /* done in long arith to avoid oflo */ + if (temp > (long) max_colors) + break; /* won't fit, done with this pass */ + Ncolors[j]++; /* OK, apply the increment */ + total_colors = (int) temp; + changed = TRUE; + } + } while (changed); + + return total_colors; +} + + +LOCAL(int) +output_value (j_decompress_ptr cinfo, int ci, int j, int maxj) +/* Return j'th output value, where j will range from 0 to maxj */ +/* The output values must fall in 0..MAXJSAMPLE in increasing order */ +{ + /* We always provide values 0 and MAXJSAMPLE for each component; + * any additional values are equally spaced between these limits. + * (Forcing the upper and lower values to the limits ensures that + * dithering can't produce a color outside the selected gamut.) + */ + return (int) (((INT32) j * MAXJSAMPLE + maxj/2) / maxj); +} + + +LOCAL(int) +largest_input_value (j_decompress_ptr cinfo, int ci, int j, int maxj) +/* Return largest input value that should map to j'th output value */ +/* Must have largest(j=0) >= 0, and largest(j=maxj) >= MAXJSAMPLE */ +{ + /* Breakpoints are halfway between values returned by output_value */ + return (int) (((INT32) (2*j + 1) * MAXJSAMPLE + maxj) / (2*maxj)); +} + + +/* + * Create the colormap. + */ + +LOCAL(void) +create_colormap (j_decompress_ptr cinfo) +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + JSAMPARRAY colormap; /* Created colormap */ + int total_colors; /* Number of distinct output colors */ + int i,j,k, nci, blksize, blkdist, ptr, val; + + /* Select number of colors for each component */ + total_colors = select_ncolors(cinfo, cquantize->Ncolors); + + /* Report selected color counts */ + if (cinfo->out_color_components == 3) + TRACEMS4(cinfo, 1, JTRC_QUANT_3_NCOLORS, + total_colors, cquantize->Ncolors[0], + cquantize->Ncolors[1], cquantize->Ncolors[2]); + else + TRACEMS1(cinfo, 1, JTRC_QUANT_NCOLORS, total_colors); + + /* Allocate and fill in the colormap. */ + /* The colors are ordered in the map in standard row-major order, */ + /* i.e. rightmost (highest-indexed) color changes most rapidly. */ + + colormap = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + (JDIMENSION) total_colors, (JDIMENSION) cinfo->out_color_components); + + /* blksize is number of adjacent repeated entries for a component */ + /* blkdist is distance between groups of identical entries for a component */ + blkdist = total_colors; + + for (i = 0; i < cinfo->out_color_components; i++) { + /* fill in colormap entries for i'th color component */ + nci = cquantize->Ncolors[i]; /* # of distinct values for this color */ + blksize = blkdist / nci; + for (j = 0; j < nci; j++) { + /* Compute j'th output value (out of nci) for component */ + val = output_value(cinfo, i, j, nci-1); + /* Fill in all colormap entries that have this value of this component */ + for (ptr = j * blksize; ptr < total_colors; ptr += blkdist) { + /* fill in blksize entries beginning at ptr */ + for (k = 0; k < blksize; k++) + colormap[i][ptr+k] = (JSAMPLE) val; + } + } + blkdist = blksize; /* blksize of this color is blkdist of next */ + } + + /* Save the colormap in private storage, + * where it will survive color quantization mode changes. + */ + cquantize->sv_colormap = colormap; + cquantize->sv_actual = total_colors; +} + + +/* + * Create the color index table. + */ + +LOCAL(void) +create_colorindex (j_decompress_ptr cinfo) +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + JSAMPROW indexptr; + int i,j,k, nci, blksize, val, pad; + + /* For ordered dither, we pad the color index tables by MAXJSAMPLE in + * each direction (input index values can be -MAXJSAMPLE .. 2*MAXJSAMPLE). + * This is not necessary in the other dithering modes. However, we + * flag whether it was done in case user changes dithering mode. + */ + if (cinfo->dither_mode == JDITHER_ORDERED) { + pad = MAXJSAMPLE*2; + cquantize->is_padded = TRUE; + } else { + pad = 0; + cquantize->is_padded = FALSE; + } + + cquantize->colorindex = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + (JDIMENSION) (MAXJSAMPLE+1 + pad), + (JDIMENSION) cinfo->out_color_components); + + /* blksize is number of adjacent repeated entries for a component */ + blksize = cquantize->sv_actual; + + for (i = 0; i < cinfo->out_color_components; i++) { + /* fill in colorindex entries for i'th color component */ + nci = cquantize->Ncolors[i]; /* # of distinct values for this color */ + blksize = blksize / nci; + + /* adjust colorindex pointers to provide padding at negative indexes. */ + if (pad) + cquantize->colorindex[i] += MAXJSAMPLE; + + /* in loop, val = index of current output value, */ + /* and k = largest j that maps to current val */ + indexptr = cquantize->colorindex[i]; + val = 0; + k = largest_input_value(cinfo, i, 0, nci-1); + for (j = 0; j <= MAXJSAMPLE; j++) { + while (j > k) /* advance val if past boundary */ + k = largest_input_value(cinfo, i, ++val, nci-1); + /* premultiply so that no multiplication needed in main processing */ + indexptr[j] = (JSAMPLE) (val * blksize); + } + /* Pad at both ends if necessary */ + if (pad) + for (j = 1; j <= MAXJSAMPLE; j++) { + indexptr[-j] = indexptr[0]; + indexptr[MAXJSAMPLE+j] = indexptr[MAXJSAMPLE]; + } + } +} + + +/* + * Create an ordered-dither array for a component having ncolors + * distinct output values. + */ + +LOCAL(ODITHER_MATRIX_PTR) +make_odither_array (j_decompress_ptr cinfo, int ncolors) +{ + ODITHER_MATRIX_PTR odither; + int j,k; + INT32 num,den; + + odither = (ODITHER_MATRIX_PTR) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(ODITHER_MATRIX)); + /* The inter-value distance for this color is MAXJSAMPLE/(ncolors-1). + * Hence the dither value for the matrix cell with fill order f + * (f=0..N-1) should be (N-1-2*f)/(2*N) * MAXJSAMPLE/(ncolors-1). + * On 16-bit-int machine, be careful to avoid overflow. + */ + den = 2 * ODITHER_CELLS * ((INT32) (ncolors - 1)); + for (j = 0; j < ODITHER_SIZE; j++) { + for (k = 0; k < ODITHER_SIZE; k++) { + num = ((INT32) (ODITHER_CELLS-1 - 2*((int)base_dither_matrix[j][k]))) + * MAXJSAMPLE; + /* Ensure round towards zero despite C's lack of consistency + * about rounding negative values in integer division... + */ + odither[j][k] = (int) (num<0 ? -((-num)/den) : num/den); + } + } + return odither; +} + + +/* + * Create the ordered-dither tables. + * Components having the same number of representative colors may + * share a dither table. + */ + +LOCAL(void) +create_odither_tables (j_decompress_ptr cinfo) +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + ODITHER_MATRIX_PTR odither; + int i, j, nci; + + for (i = 0; i < cinfo->out_color_components; i++) { + nci = cquantize->Ncolors[i]; /* # of distinct values for this color */ + odither = NULL; /* search for matching prior component */ + for (j = 0; j < i; j++) { + if (nci == cquantize->Ncolors[j]) { + odither = cquantize->odither[j]; + break; + } + } + if (odither == NULL) /* need a new table? */ + odither = make_odither_array(cinfo, nci); + cquantize->odither[i] = odither; + } +} + + +/* + * Map some rows of pixels to the output colormapped representation. + */ + +METHODDEF(void) +color_quantize (j_decompress_ptr cinfo, JSAMPARRAY input_buf, + JSAMPARRAY output_buf, int num_rows) +/* General case, no dithering */ +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + JSAMPARRAY colorindex = cquantize->colorindex; + register int pixcode, ci; + register JSAMPROW ptrin, ptrout; + int row; + JDIMENSION col; + JDIMENSION width = cinfo->output_width; + register int nc = cinfo->out_color_components; + + for (row = 0; row < num_rows; row++) { + ptrin = input_buf[row]; + ptrout = output_buf[row]; + for (col = width; col > 0; col--) { + pixcode = 0; + for (ci = 0; ci < nc; ci++) { + pixcode += GETJSAMPLE(colorindex[ci][GETJSAMPLE(*ptrin++)]); + } + *ptrout++ = (JSAMPLE) pixcode; + } + } +} + + +METHODDEF(void) +color_quantize3 (j_decompress_ptr cinfo, JSAMPARRAY input_buf, + JSAMPARRAY output_buf, int num_rows) +/* Fast path for out_color_components==3, no dithering */ +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + register int pixcode; + register JSAMPROW ptrin, ptrout; + JSAMPROW colorindex0 = cquantize->colorindex[0]; + JSAMPROW colorindex1 = cquantize->colorindex[1]; + JSAMPROW colorindex2 = cquantize->colorindex[2]; + int row; + JDIMENSION col; + JDIMENSION width = cinfo->output_width; + + for (row = 0; row < num_rows; row++) { + ptrin = input_buf[row]; + ptrout = output_buf[row]; + for (col = width; col > 0; col--) { + pixcode = GETJSAMPLE(colorindex0[GETJSAMPLE(*ptrin++)]); + pixcode += GETJSAMPLE(colorindex1[GETJSAMPLE(*ptrin++)]); + pixcode += GETJSAMPLE(colorindex2[GETJSAMPLE(*ptrin++)]); + *ptrout++ = (JSAMPLE) pixcode; + } + } +} + + +METHODDEF(void) +quantize_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf, + JSAMPARRAY output_buf, int num_rows) +/* General case, with ordered dithering */ +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + register JSAMPROW input_ptr; + register JSAMPROW output_ptr; + JSAMPROW colorindex_ci; + int * dither; /* points to active row of dither matrix */ + int row_index, col_index; /* current indexes into dither matrix */ + int nc = cinfo->out_color_components; + int ci; + int row; + JDIMENSION col; + JDIMENSION width = cinfo->output_width; + + for (row = 0; row < num_rows; row++) { + /* Initialize output values to 0 so can process components separately */ + jzero_far((void FAR *) output_buf[row], + (size_t) (width * SIZEOF(JSAMPLE))); + row_index = cquantize->row_index; + for (ci = 0; ci < nc; ci++) { + input_ptr = input_buf[row] + ci; + output_ptr = output_buf[row]; + colorindex_ci = cquantize->colorindex[ci]; + dither = cquantize->odither[ci][row_index]; + col_index = 0; + + for (col = width; col > 0; col--) { + /* Form pixel value + dither, range-limit to 0..MAXJSAMPLE, + * select output value, accumulate into output code for this pixel. + * Range-limiting need not be done explicitly, as we have extended + * the colorindex table to produce the right answers for out-of-range + * inputs. The maximum dither is +- MAXJSAMPLE; this sets the + * required amount of padding. + */ + *output_ptr += colorindex_ci[GETJSAMPLE(*input_ptr)+dither[col_index]]; + input_ptr += nc; + output_ptr++; + col_index = (col_index + 1) & ODITHER_MASK; + } + } + /* Advance row index for next row */ + row_index = (row_index + 1) & ODITHER_MASK; + cquantize->row_index = row_index; + } +} + + +METHODDEF(void) +quantize3_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf, + JSAMPARRAY output_buf, int num_rows) +/* Fast path for out_color_components==3, with ordered dithering */ +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + register int pixcode; + register JSAMPROW input_ptr; + register JSAMPROW output_ptr; + JSAMPROW colorindex0 = cquantize->colorindex[0]; + JSAMPROW colorindex1 = cquantize->colorindex[1]; + JSAMPROW colorindex2 = cquantize->colorindex[2]; + int * dither0; /* points to active row of dither matrix */ + int * dither1; + int * dither2; + int row_index, col_index; /* current indexes into dither matrix */ + int row; + JDIMENSION col; + JDIMENSION width = cinfo->output_width; + + for (row = 0; row < num_rows; row++) { + row_index = cquantize->row_index; + input_ptr = input_buf[row]; + output_ptr = output_buf[row]; + dither0 = cquantize->odither[0][row_index]; + dither1 = cquantize->odither[1][row_index]; + dither2 = cquantize->odither[2][row_index]; + col_index = 0; + + for (col = width; col > 0; col--) { + pixcode = GETJSAMPLE(colorindex0[GETJSAMPLE(*input_ptr++) + + dither0[col_index]]); + pixcode += GETJSAMPLE(colorindex1[GETJSAMPLE(*input_ptr++) + + dither1[col_index]]); + pixcode += GETJSAMPLE(colorindex2[GETJSAMPLE(*input_ptr++) + + dither2[col_index]]); + *output_ptr++ = (JSAMPLE) pixcode; + col_index = (col_index + 1) & ODITHER_MASK; + } + row_index = (row_index + 1) & ODITHER_MASK; + cquantize->row_index = row_index; + } +} + + +METHODDEF(void) +quantize_fs_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf, + JSAMPARRAY output_buf, int num_rows) +/* General case, with Floyd-Steinberg dithering */ +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + register LOCFSERROR cur; /* current error or pixel value */ + LOCFSERROR belowerr; /* error for pixel below cur */ + LOCFSERROR bpreverr; /* error for below/prev col */ + LOCFSERROR bnexterr; /* error for below/next col */ + LOCFSERROR delta; + register FSERRPTR errorptr; /* => fserrors[] at column before current */ + register JSAMPROW input_ptr; + register JSAMPROW output_ptr; + JSAMPROW colorindex_ci; + JSAMPROW colormap_ci; + int pixcode; + int nc = cinfo->out_color_components; + int dir; /* 1 for left-to-right, -1 for right-to-left */ + int dirnc; /* dir * nc */ + int ci; + int row; + JDIMENSION col; + JDIMENSION width = cinfo->output_width; + JSAMPLE *range_limit = cinfo->sample_range_limit; + SHIFT_TEMPS + + for (row = 0; row < num_rows; row++) { + /* Initialize output values to 0 so can process components separately */ + jzero_far((void FAR *) output_buf[row], + (size_t) (width * SIZEOF(JSAMPLE))); + for (ci = 0; ci < nc; ci++) { + input_ptr = input_buf[row] + ci; + output_ptr = output_buf[row]; + if (cquantize->on_odd_row) { + /* work right to left in this row */ + input_ptr += (width-1) * nc; /* so point to rightmost pixel */ + output_ptr += width-1; + dir = -1; + dirnc = -nc; + errorptr = cquantize->fserrors[ci] + (width+1); /* => entry after last column */ + } else { + /* work left to right in this row */ + dir = 1; + dirnc = nc; + errorptr = cquantize->fserrors[ci]; /* => entry before first column */ + } + colorindex_ci = cquantize->colorindex[ci]; + colormap_ci = cquantize->sv_colormap[ci]; + /* Preset error values: no error propagated to first pixel from left */ + cur = 0; + /* and no error propagated to row below yet */ + belowerr = bpreverr = 0; + + for (col = width; col > 0; col--) { + /* cur holds the error propagated from the previous pixel on the + * current line. Add the error propagated from the previous line + * to form the complete error correction term for this pixel, and + * round the error term (which is expressed * 16) to an integer. + * RIGHT_SHIFT rounds towards minus infinity, so adding 8 is correct + * for either sign of the error value. + * Note: errorptr points to *previous* column's array entry. + */ + cur = RIGHT_SHIFT(cur + errorptr[dir] + 8, 4); + /* Form pixel value + error, and range-limit to 0..MAXJSAMPLE. + * The maximum error is +- MAXJSAMPLE; this sets the required size + * of the range_limit array. + */ + cur += GETJSAMPLE(*input_ptr); + cur = GETJSAMPLE(range_limit[cur]); + /* Select output value, accumulate into output code for this pixel */ + pixcode = GETJSAMPLE(colorindex_ci[cur]); + *output_ptr += (JSAMPLE) pixcode; + /* Compute actual representation error at this pixel */ + /* Note: we can do this even though we don't have the final */ + /* pixel code, because the colormap is orthogonal. */ + cur -= GETJSAMPLE(colormap_ci[pixcode]); + /* Compute error fractions to be propagated to adjacent pixels. + * Add these into the running sums, and simultaneously shift the + * next-line error sums left by 1 column. + */ + bnexterr = cur; + delta = cur * 2; + cur += delta; /* form error * 3 */ + errorptr[0] = (FSERROR) (bpreverr + cur); + cur += delta; /* form error * 5 */ + bpreverr = belowerr + cur; + belowerr = bnexterr; + cur += delta; /* form error * 7 */ + /* At this point cur contains the 7/16 error value to be propagated + * to the next pixel on the current line, and all the errors for the + * next line have been shifted over. We are therefore ready to move on. + */ + input_ptr += dirnc; /* advance input ptr to next column */ + output_ptr += dir; /* advance output ptr to next column */ + errorptr += dir; /* advance errorptr to current column */ + } + /* Post-loop cleanup: we must unload the final error value into the + * final fserrors[] entry. Note we need not unload belowerr because + * it is for the dummy column before or after the actual array. + */ + errorptr[0] = (FSERROR) bpreverr; /* unload prev err into array */ + } + cquantize->on_odd_row = (cquantize->on_odd_row ? FALSE : TRUE); + } +} + + +/* + * Allocate workspace for Floyd-Steinberg errors. + */ + +LOCAL(void) +alloc_fs_workspace (j_decompress_ptr cinfo) +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + size_t arraysize; + int i; + + arraysize = (size_t) ((cinfo->output_width + 2) * SIZEOF(FSERROR)); + for (i = 0; i < cinfo->out_color_components; i++) { + cquantize->fserrors[i] = (FSERRPTR) + (*cinfo->mem->alloc_large)((j_common_ptr) cinfo, JPOOL_IMAGE, arraysize); + } +} + + +/* + * Initialize for one-pass color quantization. + */ + +METHODDEF(void) +start_pass_1_quant (j_decompress_ptr cinfo, boolean is_pre_scan) +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + size_t arraysize; + int i; + + /* Install my colormap. */ + cinfo->colormap = cquantize->sv_colormap; + cinfo->actual_number_of_colors = cquantize->sv_actual; + + /* Initialize for desired dithering mode. */ + switch (cinfo->dither_mode) { + case JDITHER_NONE: + if (cinfo->out_color_components == 3) + cquantize->pub.color_quantize = color_quantize3; + else + cquantize->pub.color_quantize = color_quantize; + break; + case JDITHER_ORDERED: + if (cinfo->out_color_components == 3) + cquantize->pub.color_quantize = quantize3_ord_dither; + else + cquantize->pub.color_quantize = quantize_ord_dither; + cquantize->row_index = 0; /* initialize state for ordered dither */ + /* If user changed to ordered dither from another mode, + * we must recreate the color index table with padding. + * This will cost extra space, but probably isn't very likely. + */ + if (! cquantize->is_padded) + create_colorindex(cinfo); + /* Create ordered-dither tables if we didn't already. */ + if (cquantize->odither[0] == NULL) + create_odither_tables(cinfo); + break; + case JDITHER_FS: + cquantize->pub.color_quantize = quantize_fs_dither; + cquantize->on_odd_row = FALSE; /* initialize state for F-S dither */ + /* Allocate Floyd-Steinberg workspace if didn't already. */ + if (cquantize->fserrors[0] == NULL) + alloc_fs_workspace(cinfo); + /* Initialize the propagated errors to zero. */ + arraysize = (size_t) ((cinfo->output_width + 2) * SIZEOF(FSERROR)); + for (i = 0; i < cinfo->out_color_components; i++) + jzero_far((void FAR *) cquantize->fserrors[i], arraysize); + break; + default: + ERREXIT(cinfo, JERR_NOT_COMPILED); + break; + } +} + + +/* + * Finish up at the end of the pass. + */ + +METHODDEF(void) +finish_pass_1_quant (j_decompress_ptr cinfo) +{ + /* no work in 1-pass case */ +} + + +/* + * Switch to a new external colormap between output passes. + * Shouldn't get to this module! + */ + +METHODDEF(void) +new_color_map_1_quant (j_decompress_ptr cinfo) +{ + ERREXIT(cinfo, JERR_MODE_CHANGE); +} + + +/* + * Module initialization routine for 1-pass color quantization. + */ + +GLOBAL(void) +jinit_1pass_quantizer (j_decompress_ptr cinfo) +{ + my_cquantize_ptr cquantize; + + cquantize = (my_cquantize_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_cquantizer)); + cinfo->cquantize = (struct jpeg_color_quantizer *) cquantize; + cquantize->pub.start_pass = start_pass_1_quant; + cquantize->pub.finish_pass = finish_pass_1_quant; + cquantize->pub.new_color_map = new_color_map_1_quant; + cquantize->fserrors[0] = NULL; /* Flag FS workspace not allocated */ + cquantize->odither[0] = NULL; /* Also flag odither arrays not allocated */ + + /* Make sure my internal arrays won't overflow */ + if (cinfo->out_color_components > MAX_Q_COMPS) + ERREXIT1(cinfo, JERR_QUANT_COMPONENTS, MAX_Q_COMPS); + /* Make sure colormap indexes can be represented by JSAMPLEs */ + if (cinfo->desired_number_of_colors > (MAXJSAMPLE+1)) + ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXJSAMPLE+1); + + /* Create the colormap and color index table. */ + create_colormap(cinfo); + create_colorindex(cinfo); + + /* Allocate Floyd-Steinberg workspace now if requested. + * We do this now since it is FAR storage and may affect the memory + * manager's space calculations. If the user changes to FS dither + * mode in a later pass, we will allocate the space then, and will + * possibly overrun the max_memory_to_use setting. + */ + if (cinfo->dither_mode == JDITHER_FS) + alloc_fs_workspace(cinfo); +} + +#endif /* QUANT_1PASS_SUPPORTED */ diff --git a/mod/pub.mod/libjpeg.mod/jquant2.c b/mod/pub.mod/libjpeg.mod/jquant2.c new file mode 100644 index 0000000..af601e3 --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jquant2.c @@ -0,0 +1,1310 @@ +/* + * jquant2.c + * + * Copyright (C) 1991-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains 2-pass color quantization (color mapping) routines. + * These routines provide selection of a custom color map for an image, + * followed by mapping of the image to that color map, with optional + * Floyd-Steinberg dithering. + * It is also possible to use just the second pass to map to an arbitrary + * externally-given color map. + * + * Note: ordered dithering is not supported, since there isn't any fast + * way to compute intercolor distances; it's unclear that ordered dither's + * fundamental assumptions even hold with an irregularly spaced color map. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + +#ifdef QUANT_2PASS_SUPPORTED + + +/* + * This module implements the well-known Heckbert paradigm for color + * quantization. Most of the ideas used here can be traced back to + * Heckbert's seminal paper + * Heckbert, Paul. "Color Image Quantization for Frame Buffer Display", + * Proc. SIGGRAPH '82, Computer Graphics v.16 #3 (July 1982), pp 297-304. + * + * In the first pass over the image, we accumulate a histogram showing the + * usage count of each possible color. To keep the histogram to a reasonable + * size, we reduce the precision of the input; typical practice is to retain + * 5 or 6 bits per color, so that 8 or 4 different input values are counted + * in the same histogram cell. + * + * Next, the color-selection step begins with a box representing the whole + * color space, and repeatedly splits the "largest" remaining box until we + * have as many boxes as desired colors. Then the mean color in each + * remaining box becomes one of the possible output colors. + * + * The second pass over the image maps each input pixel to the closest output + * color (optionally after applying a Floyd-Steinberg dithering correction). + * This mapping is logically trivial, but making it go fast enough requires + * considerable care. + * + * Heckbert-style quantizers vary a good deal in their policies for choosing + * the "largest" box and deciding where to cut it. The particular policies + * used here have proved out well in experimental comparisons, but better ones + * may yet be found. + * + * In earlier versions of the IJG code, this module quantized in YCbCr color + * space, processing the raw upsampled data without a color conversion step. + * This allowed the color conversion math to be done only once per colormap + * entry, not once per pixel. However, that optimization precluded other + * useful optimizations (such as merging color conversion with upsampling) + * and it also interfered with desired capabilities such as quantizing to an + * externally-supplied colormap. We have therefore abandoned that approach. + * The present code works in the post-conversion color space, typically RGB. + * + * To improve the visual quality of the results, we actually work in scaled + * RGB space, giving G distances more weight than R, and R in turn more than + * B. To do everything in integer math, we must use integer scale factors. + * The 2/3/1 scale factors used here correspond loosely to the relative + * weights of the colors in the NTSC grayscale equation. + * If you want to use this code to quantize a non-RGB color space, you'll + * probably need to change these scale factors. + */ + +#define R_SCALE 2 /* scale R distances by this much */ +#define G_SCALE 3 /* scale G distances by this much */ +#define B_SCALE 1 /* and B by this much */ + +/* Relabel R/G/B as components 0/1/2, respecting the RGB ordering defined + * in jmorecfg.h. As the code stands, it will do the right thing for R,G,B + * and B,G,R orders. If you define some other weird order in jmorecfg.h, + * you'll get compile errors until you extend this logic. In that case + * you'll probably want to tweak the histogram sizes too. + */ + +#if RGB_RED == 0 +#define C0_SCALE R_SCALE +#endif +#if RGB_BLUE == 0 +#define C0_SCALE B_SCALE +#endif +#if RGB_GREEN == 1 +#define C1_SCALE G_SCALE +#endif +#if RGB_RED == 2 +#define C2_SCALE R_SCALE +#endif +#if RGB_BLUE == 2 +#define C2_SCALE B_SCALE +#endif + + +/* + * First we have the histogram data structure and routines for creating it. + * + * The number of bits of precision can be adjusted by changing these symbols. + * We recommend keeping 6 bits for G and 5 each for R and B. + * If you have plenty of memory and cycles, 6 bits all around gives marginally + * better results; if you are short of memory, 5 bits all around will save + * some space but degrade the results. + * To maintain a fully accurate histogram, we'd need to allocate a "long" + * (preferably unsigned long) for each cell. In practice this is overkill; + * we can get by with 16 bits per cell. Few of the cell counts will overflow, + * and clamping those that do overflow to the maximum value will give close- + * enough results. This reduces the recommended histogram size from 256Kb + * to 128Kb, which is a useful savings on PC-class machines. + * (In the second pass the histogram space is re-used for pixel mapping data; + * in that capacity, each cell must be able to store zero to the number of + * desired colors. 16 bits/cell is plenty for that too.) + * Since the JPEG code is intended to run in small memory model on 80x86 + * machines, we can't just allocate the histogram in one chunk. Instead + * of a true 3-D array, we use a row of pointers to 2-D arrays. Each + * pointer corresponds to a C0 value (typically 2^5 = 32 pointers) and + * each 2-D array has 2^6*2^5 = 2048 or 2^6*2^6 = 4096 entries. Note that + * on 80x86 machines, the pointer row is in near memory but the actual + * arrays are in far memory (same arrangement as we use for image arrays). + */ + +#define MAXNUMCOLORS (MAXJSAMPLE+1) /* maximum size of colormap */ + +/* These will do the right thing for either R,G,B or B,G,R color order, + * but you may not like the results for other color orders. + */ +#define HIST_C0_BITS 5 /* bits of precision in R/B histogram */ +#define HIST_C1_BITS 6 /* bits of precision in G histogram */ +#define HIST_C2_BITS 5 /* bits of precision in B/R histogram */ + +/* Number of elements along histogram axes. */ +#define HIST_C0_ELEMS (1<<HIST_C0_BITS) +#define HIST_C1_ELEMS (1<<HIST_C1_BITS) +#define HIST_C2_ELEMS (1<<HIST_C2_BITS) + +/* These are the amounts to shift an input value to get a histogram index. */ +#define C0_SHIFT (BITS_IN_JSAMPLE-HIST_C0_BITS) +#define C1_SHIFT (BITS_IN_JSAMPLE-HIST_C1_BITS) +#define C2_SHIFT (BITS_IN_JSAMPLE-HIST_C2_BITS) + + +typedef UINT16 histcell; /* histogram cell; prefer an unsigned type */ + +typedef histcell FAR * histptr; /* for pointers to histogram cells */ + +typedef histcell hist1d[HIST_C2_ELEMS]; /* typedefs for the array */ +typedef hist1d FAR * hist2d; /* type for the 2nd-level pointers */ +typedef hist2d * hist3d; /* type for top-level pointer */ + + +/* Declarations for Floyd-Steinberg dithering. + * + * Errors are accumulated into the array fserrors[], at a resolution of + * 1/16th of a pixel count. The error at a given pixel is propagated + * to its not-yet-processed neighbors using the standard F-S fractions, + * ... (here) 7/16 + * 3/16 5/16 1/16 + * We work left-to-right on even rows, right-to-left on odd rows. + * + * We can get away with a single array (holding one row's worth of errors) + * by using it to store the current row's errors at pixel columns not yet + * processed, but the next row's errors at columns already processed. We + * need only a few extra variables to hold the errors immediately around the + * current column. (If we are lucky, those variables are in registers, but + * even if not, they're probably cheaper to access than array elements are.) + * + * The fserrors[] array has (#columns + 2) entries; the extra entry at + * each end saves us from special-casing the first and last pixels. + * Each entry is three values long, one value for each color component. + * + * Note: on a wide image, we might not have enough room in a PC's near data + * segment to hold the error array; so it is allocated with alloc_large. + */ + +#if BITS_IN_JSAMPLE == 8 +typedef INT16 FSERROR; /* 16 bits should be enough */ +typedef int LOCFSERROR; /* use 'int' for calculation temps */ +#else +typedef INT32 FSERROR; /* may need more than 16 bits */ +typedef INT32 LOCFSERROR; /* be sure calculation temps are big enough */ +#endif + +typedef FSERROR FAR *FSERRPTR; /* pointer to error array (in FAR storage!) */ + + +/* Private subobject */ + +typedef struct { + struct jpeg_color_quantizer pub; /* public fields */ + + /* Space for the eventually created colormap is stashed here */ + JSAMPARRAY sv_colormap; /* colormap allocated at init time */ + int desired; /* desired # of colors = size of colormap */ + + /* Variables for accumulating image statistics */ + hist3d histogram; /* pointer to the histogram */ + + boolean needs_zeroed; /* TRUE if next pass must zero histogram */ + + /* Variables for Floyd-Steinberg dithering */ + FSERRPTR fserrors; /* accumulated errors */ + boolean on_odd_row; /* flag to remember which row we are on */ + int * error_limiter; /* table for clamping the applied error */ +} my_cquantizer; + +typedef my_cquantizer * my_cquantize_ptr; + + +/* + * Prescan some rows of pixels. + * In this module the prescan simply updates the histogram, which has been + * initialized to zeroes by start_pass. + * An output_buf parameter is required by the method signature, but no data + * is actually output (in fact the buffer controller is probably passing a + * NULL pointer). + */ + +METHODDEF(void) +prescan_quantize (j_decompress_ptr cinfo, JSAMPARRAY input_buf, + JSAMPARRAY output_buf, int num_rows) +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + register JSAMPROW ptr; + register histptr histp; + register hist3d histogram = cquantize->histogram; + int row; + JDIMENSION col; + JDIMENSION width = cinfo->output_width; + + for (row = 0; row < num_rows; row++) { + ptr = input_buf[row]; + for (col = width; col > 0; col--) { + /* get pixel value and index into the histogram */ + histp = & histogram[GETJSAMPLE(ptr[0]) >> C0_SHIFT] + [GETJSAMPLE(ptr[1]) >> C1_SHIFT] + [GETJSAMPLE(ptr[2]) >> C2_SHIFT]; + /* increment, check for overflow and undo increment if so. */ + if (++(*histp) <= 0) + (*histp)--; + ptr += 3; + } + } +} + + +/* + * Next we have the really interesting routines: selection of a colormap + * given the completed histogram. + * These routines work with a list of "boxes", each representing a rectangular + * subset of the input color space (to histogram precision). + */ + +typedef struct { + /* The bounds of the box (inclusive); expressed as histogram indexes */ + int c0min, c0max; + int c1min, c1max; + int c2min, c2max; + /* The volume (actually 2-norm) of the box */ + INT32 volume; + /* The number of nonzero histogram cells within this box */ + long colorcount; +} box; + +typedef box * boxptr; + + +LOCAL(boxptr) +find_biggest_color_pop (boxptr boxlist, int numboxes) +/* Find the splittable box with the largest color population */ +/* Returns NULL if no splittable boxes remain */ +{ + register boxptr boxp; + register int i; + register long maxc = 0; + boxptr which = NULL; + + for (i = 0, boxp = boxlist; i < numboxes; i++, boxp++) { + if (boxp->colorcount > maxc && boxp->volume > 0) { + which = boxp; + maxc = boxp->colorcount; + } + } + return which; +} + + +LOCAL(boxptr) +find_biggest_volume (boxptr boxlist, int numboxes) +/* Find the splittable box with the largest (scaled) volume */ +/* Returns NULL if no splittable boxes remain */ +{ + register boxptr boxp; + register int i; + register INT32 maxv = 0; + boxptr which = NULL; + + for (i = 0, boxp = boxlist; i < numboxes; i++, boxp++) { + if (boxp->volume > maxv) { + which = boxp; + maxv = boxp->volume; + } + } + return which; +} + + +LOCAL(void) +update_box (j_decompress_ptr cinfo, boxptr boxp) +/* Shrink the min/max bounds of a box to enclose only nonzero elements, */ +/* and recompute its volume and population */ +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + hist3d histogram = cquantize->histogram; + histptr histp; + int c0,c1,c2; + int c0min,c0max,c1min,c1max,c2min,c2max; + INT32 dist0,dist1,dist2; + long ccount; + + c0min = boxp->c0min; c0max = boxp->c0max; + c1min = boxp->c1min; c1max = boxp->c1max; + c2min = boxp->c2min; c2max = boxp->c2max; + + if (c0max > c0min) + for (c0 = c0min; c0 <= c0max; c0++) + for (c1 = c1min; c1 <= c1max; c1++) { + histp = & histogram[c0][c1][c2min]; + for (c2 = c2min; c2 <= c2max; c2++) + if (*histp++ != 0) { + boxp->c0min = c0min = c0; + goto have_c0min; + } + } + have_c0min: + if (c0max > c0min) + for (c0 = c0max; c0 >= c0min; c0--) + for (c1 = c1min; c1 <= c1max; c1++) { + histp = & histogram[c0][c1][c2min]; + for (c2 = c2min; c2 <= c2max; c2++) + if (*histp++ != 0) { + boxp->c0max = c0max = c0; + goto have_c0max; + } + } + have_c0max: + if (c1max > c1min) + for (c1 = c1min; c1 <= c1max; c1++) + for (c0 = c0min; c0 <= c0max; c0++) { + histp = & histogram[c0][c1][c2min]; + for (c2 = c2min; c2 <= c2max; c2++) + if (*histp++ != 0) { + boxp->c1min = c1min = c1; + goto have_c1min; + } + } + have_c1min: + if (c1max > c1min) + for (c1 = c1max; c1 >= c1min; c1--) + for (c0 = c0min; c0 <= c0max; c0++) { + histp = & histogram[c0][c1][c2min]; + for (c2 = c2min; c2 <= c2max; c2++) + if (*histp++ != 0) { + boxp->c1max = c1max = c1; + goto have_c1max; + } + } + have_c1max: + if (c2max > c2min) + for (c2 = c2min; c2 <= c2max; c2++) + for (c0 = c0min; c0 <= c0max; c0++) { + histp = & histogram[c0][c1min][c2]; + for (c1 = c1min; c1 <= c1max; c1++, histp += HIST_C2_ELEMS) + if (*histp != 0) { + boxp->c2min = c2min = c2; + goto have_c2min; + } + } + have_c2min: + if (c2max > c2min) + for (c2 = c2max; c2 >= c2min; c2--) + for (c0 = c0min; c0 <= c0max; c0++) { + histp = & histogram[c0][c1min][c2]; + for (c1 = c1min; c1 <= c1max; c1++, histp += HIST_C2_ELEMS) + if (*histp != 0) { + boxp->c2max = c2max = c2; + goto have_c2max; + } + } + have_c2max: + + /* Update box volume. + * We use 2-norm rather than real volume here; this biases the method + * against making long narrow boxes, and it has the side benefit that + * a box is splittable iff norm > 0. + * Since the differences are expressed in histogram-cell units, + * we have to shift back to JSAMPLE units to get consistent distances; + * after which, we scale according to the selected distance scale factors. + */ + dist0 = ((c0max - c0min) << C0_SHIFT) * C0_SCALE; + dist1 = ((c1max - c1min) << C1_SHIFT) * C1_SCALE; + dist2 = ((c2max - c2min) << C2_SHIFT) * C2_SCALE; + boxp->volume = dist0*dist0 + dist1*dist1 + dist2*dist2; + + /* Now scan remaining volume of box and compute population */ + ccount = 0; + for (c0 = c0min; c0 <= c0max; c0++) + for (c1 = c1min; c1 <= c1max; c1++) { + histp = & histogram[c0][c1][c2min]; + for (c2 = c2min; c2 <= c2max; c2++, histp++) + if (*histp != 0) { + ccount++; + } + } + boxp->colorcount = ccount; +} + + +LOCAL(int) +median_cut (j_decompress_ptr cinfo, boxptr boxlist, int numboxes, + int desired_colors) +/* Repeatedly select and split the largest box until we have enough boxes */ +{ + int n,lb; + int c0,c1,c2,cmax; + register boxptr b1,b2; + + while (numboxes < desired_colors) { + /* Select box to split. + * Current algorithm: by population for first half, then by volume. + */ + if (numboxes*2 <= desired_colors) { + b1 = find_biggest_color_pop(boxlist, numboxes); + } else { + b1 = find_biggest_volume(boxlist, numboxes); + } + if (b1 == NULL) /* no splittable boxes left! */ + break; + b2 = &boxlist[numboxes]; /* where new box will go */ + /* Copy the color bounds to the new box. */ + b2->c0max = b1->c0max; b2->c1max = b1->c1max; b2->c2max = b1->c2max; + b2->c0min = b1->c0min; b2->c1min = b1->c1min; b2->c2min = b1->c2min; + /* Choose which axis to split the box on. + * Current algorithm: longest scaled axis. + * See notes in update_box about scaling distances. + */ + c0 = ((b1->c0max - b1->c0min) << C0_SHIFT) * C0_SCALE; + c1 = ((b1->c1max - b1->c1min) << C1_SHIFT) * C1_SCALE; + c2 = ((b1->c2max - b1->c2min) << C2_SHIFT) * C2_SCALE; + /* We want to break any ties in favor of green, then red, blue last. + * This code does the right thing for R,G,B or B,G,R color orders only. + */ +#if RGB_RED == 0 + cmax = c1; n = 1; + if (c0 > cmax) { cmax = c0; n = 0; } + if (c2 > cmax) { n = 2; } +#else + cmax = c1; n = 1; + if (c2 > cmax) { cmax = c2; n = 2; } + if (c0 > cmax) { n = 0; } +#endif + /* Choose split point along selected axis, and update box bounds. + * Current algorithm: split at halfway point. + * (Since the box has been shrunk to minimum volume, + * any split will produce two nonempty subboxes.) + * Note that lb value is max for lower box, so must be < old max. + */ + switch (n) { + case 0: + lb = (b1->c0max + b1->c0min) / 2; + b1->c0max = lb; + b2->c0min = lb+1; + break; + case 1: + lb = (b1->c1max + b1->c1min) / 2; + b1->c1max = lb; + b2->c1min = lb+1; + break; + case 2: + lb = (b1->c2max + b1->c2min) / 2; + b1->c2max = lb; + b2->c2min = lb+1; + break; + } + /* Update stats for boxes */ + update_box(cinfo, b1); + update_box(cinfo, b2); + numboxes++; + } + return numboxes; +} + + +LOCAL(void) +compute_color (j_decompress_ptr cinfo, boxptr boxp, int icolor) +/* Compute representative color for a box, put it in colormap[icolor] */ +{ + /* Current algorithm: mean weighted by pixels (not colors) */ + /* Note it is important to get the rounding correct! */ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + hist3d histogram = cquantize->histogram; + histptr histp; + int c0,c1,c2; + int c0min,c0max,c1min,c1max,c2min,c2max; + long count; + long total = 0; + long c0total = 0; + long c1total = 0; + long c2total = 0; + + c0min = boxp->c0min; c0max = boxp->c0max; + c1min = boxp->c1min; c1max = boxp->c1max; + c2min = boxp->c2min; c2max = boxp->c2max; + + for (c0 = c0min; c0 <= c0max; c0++) + for (c1 = c1min; c1 <= c1max; c1++) { + histp = & histogram[c0][c1][c2min]; + for (c2 = c2min; c2 <= c2max; c2++) { + if ((count = *histp++) != 0) { + total += count; + c0total += ((c0 << C0_SHIFT) + ((1<<C0_SHIFT)>>1)) * count; + c1total += ((c1 << C1_SHIFT) + ((1<<C1_SHIFT)>>1)) * count; + c2total += ((c2 << C2_SHIFT) + ((1<<C2_SHIFT)>>1)) * count; + } + } + } + + cinfo->colormap[0][icolor] = (JSAMPLE) ((c0total + (total>>1)) / total); + cinfo->colormap[1][icolor] = (JSAMPLE) ((c1total + (total>>1)) / total); + cinfo->colormap[2][icolor] = (JSAMPLE) ((c2total + (total>>1)) / total); +} + + +LOCAL(void) +select_colors (j_decompress_ptr cinfo, int desired_colors) +/* Master routine for color selection */ +{ + boxptr boxlist; + int numboxes; + int i; + + /* Allocate workspace for box list */ + boxlist = (boxptr) (*cinfo->mem->alloc_small) + ((j_common_ptr) cinfo, JPOOL_IMAGE, desired_colors * SIZEOF(box)); + /* Initialize one box containing whole space */ + numboxes = 1; + boxlist[0].c0min = 0; + boxlist[0].c0max = MAXJSAMPLE >> C0_SHIFT; + boxlist[0].c1min = 0; + boxlist[0].c1max = MAXJSAMPLE >> C1_SHIFT; + boxlist[0].c2min = 0; + boxlist[0].c2max = MAXJSAMPLE >> C2_SHIFT; + /* Shrink it to actually-used volume and set its statistics */ + update_box(cinfo, & boxlist[0]); + /* Perform median-cut to produce final box list */ + numboxes = median_cut(cinfo, boxlist, numboxes, desired_colors); + /* Compute the representative color for each box, fill colormap */ + for (i = 0; i < numboxes; i++) + compute_color(cinfo, & boxlist[i], i); + cinfo->actual_number_of_colors = numboxes; + TRACEMS1(cinfo, 1, JTRC_QUANT_SELECTED, numboxes); +} + + +/* + * These routines are concerned with the time-critical task of mapping input + * colors to the nearest color in the selected colormap. + * + * We re-use the histogram space as an "inverse color map", essentially a + * cache for the results of nearest-color searches. All colors within a + * histogram cell will be mapped to the same colormap entry, namely the one + * closest to the cell's center. This may not be quite the closest entry to + * the actual input color, but it's almost as good. A zero in the cache + * indicates we haven't found the nearest color for that cell yet; the array + * is cleared to zeroes before starting the mapping pass. When we find the + * nearest color for a cell, its colormap index plus one is recorded in the + * cache for future use. The pass2 scanning routines call fill_inverse_cmap + * when they need to use an unfilled entry in the cache. + * + * Our method of efficiently finding nearest colors is based on the "locally + * sorted search" idea described by Heckbert and on the incremental distance + * calculation described by Spencer W. Thomas in chapter III.1 of Graphics + * Gems II (James Arvo, ed. Academic Press, 1991). Thomas points out that + * the distances from a given colormap entry to each cell of the histogram can + * be computed quickly using an incremental method: the differences between + * distances to adjacent cells themselves differ by a constant. This allows a + * fairly fast implementation of the "brute force" approach of computing the + * distance from every colormap entry to every histogram cell. Unfortunately, + * it needs a work array to hold the best-distance-so-far for each histogram + * cell (because the inner loop has to be over cells, not colormap entries). + * The work array elements have to be INT32s, so the work array would need + * 256Kb at our recommended precision. This is not feasible in DOS machines. + * + * To get around these problems, we apply Thomas' method to compute the + * nearest colors for only the cells within a small subbox of the histogram. + * The work array need be only as big as the subbox, so the memory usage + * problem is solved. Furthermore, we need not fill subboxes that are never + * referenced in pass2; many images use only part of the color gamut, so a + * fair amount of work is saved. An additional advantage of this + * approach is that we can apply Heckbert's locality criterion to quickly + * eliminate colormap entries that are far away from the subbox; typically + * three-fourths of the colormap entries are rejected by Heckbert's criterion, + * and we need not compute their distances to individual cells in the subbox. + * The speed of this approach is heavily influenced by the subbox size: too + * small means too much overhead, too big loses because Heckbert's criterion + * can't eliminate as many colormap entries. Empirically the best subbox + * size seems to be about 1/512th of the histogram (1/8th in each direction). + * + * Thomas' article also describes a refined method which is asymptotically + * faster than the brute-force method, but it is also far more complex and + * cannot efficiently be applied to small subboxes. It is therefore not + * useful for programs intended to be portable to DOS machines. On machines + * with plenty of memory, filling the whole histogram in one shot with Thomas' + * refined method might be faster than the present code --- but then again, + * it might not be any faster, and it's certainly more complicated. + */ + + +/* log2(histogram cells in update box) for each axis; this can be adjusted */ +#define BOX_C0_LOG (HIST_C0_BITS-3) +#define BOX_C1_LOG (HIST_C1_BITS-3) +#define BOX_C2_LOG (HIST_C2_BITS-3) + +#define BOX_C0_ELEMS (1<<BOX_C0_LOG) /* # of hist cells in update box */ +#define BOX_C1_ELEMS (1<<BOX_C1_LOG) +#define BOX_C2_ELEMS (1<<BOX_C2_LOG) + +#define BOX_C0_SHIFT (C0_SHIFT + BOX_C0_LOG) +#define BOX_C1_SHIFT (C1_SHIFT + BOX_C1_LOG) +#define BOX_C2_SHIFT (C2_SHIFT + BOX_C2_LOG) + + +/* + * The next three routines implement inverse colormap filling. They could + * all be folded into one big routine, but splitting them up this way saves + * some stack space (the mindist[] and bestdist[] arrays need not coexist) + * and may allow some compilers to produce better code by registerizing more + * inner-loop variables. + */ + +LOCAL(int) +find_nearby_colors (j_decompress_ptr cinfo, int minc0, int minc1, int minc2, + JSAMPLE colorlist[]) +/* Locate the colormap entries close enough to an update box to be candidates + * for the nearest entry to some cell(s) in the update box. The update box + * is specified by the center coordinates of its first cell. The number of + * candidate colormap entries is returned, and their colormap indexes are + * placed in colorlist[]. + * This routine uses Heckbert's "locally sorted search" criterion to select + * the colors that need further consideration. + */ +{ + int numcolors = cinfo->actual_number_of_colors; + int maxc0, maxc1, maxc2; + int centerc0, centerc1, centerc2; + int i, x, ncolors; + INT32 minmaxdist, min_dist, max_dist, tdist; + INT32 mindist[MAXNUMCOLORS]; /* min distance to colormap entry i */ + + /* Compute true coordinates of update box's upper corner and center. + * Actually we compute the coordinates of the center of the upper-corner + * histogram cell, which are the upper bounds of the volume we care about. + * Note that since ">>" rounds down, the "center" values may be closer to + * min than to max; hence comparisons to them must be "<=", not "<". + */ + maxc0 = minc0 + ((1 << BOX_C0_SHIFT) - (1 << C0_SHIFT)); + centerc0 = (minc0 + maxc0) >> 1; + maxc1 = minc1 + ((1 << BOX_C1_SHIFT) - (1 << C1_SHIFT)); + centerc1 = (minc1 + maxc1) >> 1; + maxc2 = minc2 + ((1 << BOX_C2_SHIFT) - (1 << C2_SHIFT)); + centerc2 = (minc2 + maxc2) >> 1; + + /* For each color in colormap, find: + * 1. its minimum squared-distance to any point in the update box + * (zero if color is within update box); + * 2. its maximum squared-distance to any point in the update box. + * Both of these can be found by considering only the corners of the box. + * We save the minimum distance for each color in mindist[]; + * only the smallest maximum distance is of interest. + */ + minmaxdist = 0x7FFFFFFFL; + + for (i = 0; i < numcolors; i++) { + /* We compute the squared-c0-distance term, then add in the other two. */ + x = GETJSAMPLE(cinfo->colormap[0][i]); + if (x < minc0) { + tdist = (x - minc0) * C0_SCALE; + min_dist = tdist*tdist; + tdist = (x - maxc0) * C0_SCALE; + max_dist = tdist*tdist; + } else if (x > maxc0) { + tdist = (x - maxc0) * C0_SCALE; + min_dist = tdist*tdist; + tdist = (x - minc0) * C0_SCALE; + max_dist = tdist*tdist; + } else { + /* within cell range so no contribution to min_dist */ + min_dist = 0; + if (x <= centerc0) { + tdist = (x - maxc0) * C0_SCALE; + max_dist = tdist*tdist; + } else { + tdist = (x - minc0) * C0_SCALE; + max_dist = tdist*tdist; + } + } + + x = GETJSAMPLE(cinfo->colormap[1][i]); + if (x < minc1) { + tdist = (x - minc1) * C1_SCALE; + min_dist += tdist*tdist; + tdist = (x - maxc1) * C1_SCALE; + max_dist += tdist*tdist; + } else if (x > maxc1) { + tdist = (x - maxc1) * C1_SCALE; + min_dist += tdist*tdist; + tdist = (x - minc1) * C1_SCALE; + max_dist += tdist*tdist; + } else { + /* within cell range so no contribution to min_dist */ + if (x <= centerc1) { + tdist = (x - maxc1) * C1_SCALE; + max_dist += tdist*tdist; + } else { + tdist = (x - minc1) * C1_SCALE; + max_dist += tdist*tdist; + } + } + + x = GETJSAMPLE(cinfo->colormap[2][i]); + if (x < minc2) { + tdist = (x - minc2) * C2_SCALE; + min_dist += tdist*tdist; + tdist = (x - maxc2) * C2_SCALE; + max_dist += tdist*tdist; + } else if (x > maxc2) { + tdist = (x - maxc2) * C2_SCALE; + min_dist += tdist*tdist; + tdist = (x - minc2) * C2_SCALE; + max_dist += tdist*tdist; + } else { + /* within cell range so no contribution to min_dist */ + if (x <= centerc2) { + tdist = (x - maxc2) * C2_SCALE; + max_dist += tdist*tdist; + } else { + tdist = (x - minc2) * C2_SCALE; + max_dist += tdist*tdist; + } + } + + mindist[i] = min_dist; /* save away the results */ + if (max_dist < minmaxdist) + minmaxdist = max_dist; + } + + /* Now we know that no cell in the update box is more than minmaxdist + * away from some colormap entry. Therefore, only colors that are + * within minmaxdist of some part of the box need be considered. + */ + ncolors = 0; + for (i = 0; i < numcolors; i++) { + if (mindist[i] <= minmaxdist) + colorlist[ncolors++] = (JSAMPLE) i; + } + return ncolors; +} + + +LOCAL(void) +find_best_colors (j_decompress_ptr cinfo, int minc0, int minc1, int minc2, + int numcolors, JSAMPLE colorlist[], JSAMPLE bestcolor[]) +/* Find the closest colormap entry for each cell in the update box, + * given the list of candidate colors prepared by find_nearby_colors. + * Return the indexes of the closest entries in the bestcolor[] array. + * This routine uses Thomas' incremental distance calculation method to + * find the distance from a colormap entry to successive cells in the box. + */ +{ + int ic0, ic1, ic2; + int i, icolor; + register INT32 * bptr; /* pointer into bestdist[] array */ + JSAMPLE * cptr; /* pointer into bestcolor[] array */ + INT32 dist0, dist1; /* initial distance values */ + register INT32 dist2; /* current distance in inner loop */ + INT32 xx0, xx1; /* distance increments */ + register INT32 xx2; + INT32 inc0, inc1, inc2; /* initial values for increments */ + /* This array holds the distance to the nearest-so-far color for each cell */ + INT32 bestdist[BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS]; + + /* Initialize best-distance for each cell of the update box */ + bptr = bestdist; + for (i = BOX_C0_ELEMS*BOX_C1_ELEMS*BOX_C2_ELEMS-1; i >= 0; i--) + *bptr++ = 0x7FFFFFFFL; + + /* For each color selected by find_nearby_colors, + * compute its distance to the center of each cell in the box. + * If that's less than best-so-far, update best distance and color number. + */ + + /* Nominal steps between cell centers ("x" in Thomas article) */ +#define STEP_C0 ((1 << C0_SHIFT) * C0_SCALE) +#define STEP_C1 ((1 << C1_SHIFT) * C1_SCALE) +#define STEP_C2 ((1 << C2_SHIFT) * C2_SCALE) + + for (i = 0; i < numcolors; i++) { + icolor = GETJSAMPLE(colorlist[i]); + /* Compute (square of) distance from minc0/c1/c2 to this color */ + inc0 = (minc0 - GETJSAMPLE(cinfo->colormap[0][icolor])) * C0_SCALE; + dist0 = inc0*inc0; + inc1 = (minc1 - GETJSAMPLE(cinfo->colormap[1][icolor])) * C1_SCALE; + dist0 += inc1*inc1; + inc2 = (minc2 - GETJSAMPLE(cinfo->colormap[2][icolor])) * C2_SCALE; + dist0 += inc2*inc2; + /* Form the initial difference increments */ + inc0 = inc0 * (2 * STEP_C0) + STEP_C0 * STEP_C0; + inc1 = inc1 * (2 * STEP_C1) + STEP_C1 * STEP_C1; + inc2 = inc2 * (2 * STEP_C2) + STEP_C2 * STEP_C2; + /* Now loop over all cells in box, updating distance per Thomas method */ + bptr = bestdist; + cptr = bestcolor; + xx0 = inc0; + for (ic0 = BOX_C0_ELEMS-1; ic0 >= 0; ic0--) { + dist1 = dist0; + xx1 = inc1; + for (ic1 = BOX_C1_ELEMS-1; ic1 >= 0; ic1--) { + dist2 = dist1; + xx2 = inc2; + for (ic2 = BOX_C2_ELEMS-1; ic2 >= 0; ic2--) { + if (dist2 < *bptr) { + *bptr = dist2; + *cptr = (JSAMPLE) icolor; + } + dist2 += xx2; + xx2 += 2 * STEP_C2 * STEP_C2; + bptr++; + cptr++; + } + dist1 += xx1; + xx1 += 2 * STEP_C1 * STEP_C1; + } + dist0 += xx0; + xx0 += 2 * STEP_C0 * STEP_C0; + } + } +} + + +LOCAL(void) +fill_inverse_cmap (j_decompress_ptr cinfo, int c0, int c1, int c2) +/* Fill the inverse-colormap entries in the update box that contains */ +/* histogram cell c0/c1/c2. (Only that one cell MUST be filled, but */ +/* we can fill as many others as we wish.) */ +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + hist3d histogram = cquantize->histogram; + int minc0, minc1, minc2; /* lower left corner of update box */ + int ic0, ic1, ic2; + register JSAMPLE * cptr; /* pointer into bestcolor[] array */ + register histptr cachep; /* pointer into main cache array */ + /* This array lists the candidate colormap indexes. */ + JSAMPLE colorlist[MAXNUMCOLORS]; + int numcolors; /* number of candidate colors */ + /* This array holds the actually closest colormap index for each cell. */ + JSAMPLE bestcolor[BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS]; + + /* Convert cell coordinates to update box ID */ + c0 >>= BOX_C0_LOG; + c1 >>= BOX_C1_LOG; + c2 >>= BOX_C2_LOG; + + /* Compute true coordinates of update box's origin corner. + * Actually we compute the coordinates of the center of the corner + * histogram cell, which are the lower bounds of the volume we care about. + */ + minc0 = (c0 << BOX_C0_SHIFT) + ((1 << C0_SHIFT) >> 1); + minc1 = (c1 << BOX_C1_SHIFT) + ((1 << C1_SHIFT) >> 1); + minc2 = (c2 << BOX_C2_SHIFT) + ((1 << C2_SHIFT) >> 1); + + /* Determine which colormap entries are close enough to be candidates + * for the nearest entry to some cell in the update box. + */ + numcolors = find_nearby_colors(cinfo, minc0, minc1, minc2, colorlist); + + /* Determine the actually nearest colors. */ + find_best_colors(cinfo, minc0, minc1, minc2, numcolors, colorlist, + bestcolor); + + /* Save the best color numbers (plus 1) in the main cache array */ + c0 <<= BOX_C0_LOG; /* convert ID back to base cell indexes */ + c1 <<= BOX_C1_LOG; + c2 <<= BOX_C2_LOG; + cptr = bestcolor; + for (ic0 = 0; ic0 < BOX_C0_ELEMS; ic0++) { + for (ic1 = 0; ic1 < BOX_C1_ELEMS; ic1++) { + cachep = & histogram[c0+ic0][c1+ic1][c2]; + for (ic2 = 0; ic2 < BOX_C2_ELEMS; ic2++) { + *cachep++ = (histcell) (GETJSAMPLE(*cptr++) + 1); + } + } + } +} + + +/* + * Map some rows of pixels to the output colormapped representation. + */ + +METHODDEF(void) +pass2_no_dither (j_decompress_ptr cinfo, + JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows) +/* This version performs no dithering */ +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + hist3d histogram = cquantize->histogram; + register JSAMPROW inptr, outptr; + register histptr cachep; + register int c0, c1, c2; + int row; + JDIMENSION col; + JDIMENSION width = cinfo->output_width; + + for (row = 0; row < num_rows; row++) { + inptr = input_buf[row]; + outptr = output_buf[row]; + for (col = width; col > 0; col--) { + /* get pixel value and index into the cache */ + c0 = GETJSAMPLE(*inptr++) >> C0_SHIFT; + c1 = GETJSAMPLE(*inptr++) >> C1_SHIFT; + c2 = GETJSAMPLE(*inptr++) >> C2_SHIFT; + cachep = & histogram[c0][c1][c2]; + /* If we have not seen this color before, find nearest colormap entry */ + /* and update the cache */ + if (*cachep == 0) + fill_inverse_cmap(cinfo, c0,c1,c2); + /* Now emit the colormap index for this cell */ + *outptr++ = (JSAMPLE) (*cachep - 1); + } + } +} + + +METHODDEF(void) +pass2_fs_dither (j_decompress_ptr cinfo, + JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows) +/* This version performs Floyd-Steinberg dithering */ +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + hist3d histogram = cquantize->histogram; + register LOCFSERROR cur0, cur1, cur2; /* current error or pixel value */ + LOCFSERROR belowerr0, belowerr1, belowerr2; /* error for pixel below cur */ + LOCFSERROR bpreverr0, bpreverr1, bpreverr2; /* error for below/prev col */ + register FSERRPTR errorptr; /* => fserrors[] at column before current */ + JSAMPROW inptr; /* => current input pixel */ + JSAMPROW outptr; /* => current output pixel */ + histptr cachep; + int dir; /* +1 or -1 depending on direction */ + int dir3; /* 3*dir, for advancing inptr & errorptr */ + int row; + JDIMENSION col; + JDIMENSION width = cinfo->output_width; + JSAMPLE *range_limit = cinfo->sample_range_limit; + int *error_limit = cquantize->error_limiter; + JSAMPROW colormap0 = cinfo->colormap[0]; + JSAMPROW colormap1 = cinfo->colormap[1]; + JSAMPROW colormap2 = cinfo->colormap[2]; + SHIFT_TEMPS + + for (row = 0; row < num_rows; row++) { + inptr = input_buf[row]; + outptr = output_buf[row]; + if (cquantize->on_odd_row) { + /* work right to left in this row */ + inptr += (width-1) * 3; /* so point to rightmost pixel */ + outptr += width-1; + dir = -1; + dir3 = -3; + errorptr = cquantize->fserrors + (width+1)*3; /* => entry after last column */ + cquantize->on_odd_row = FALSE; /* flip for next time */ + } else { + /* work left to right in this row */ + dir = 1; + dir3 = 3; + errorptr = cquantize->fserrors; /* => entry before first real column */ + cquantize->on_odd_row = TRUE; /* flip for next time */ + } + /* Preset error values: no error propagated to first pixel from left */ + cur0 = cur1 = cur2 = 0; + /* and no error propagated to row below yet */ + belowerr0 = belowerr1 = belowerr2 = 0; + bpreverr0 = bpreverr1 = bpreverr2 = 0; + + for (col = width; col > 0; col--) { + /* curN holds the error propagated from the previous pixel on the + * current line. Add the error propagated from the previous line + * to form the complete error correction term for this pixel, and + * round the error term (which is expressed * 16) to an integer. + * RIGHT_SHIFT rounds towards minus infinity, so adding 8 is correct + * for either sign of the error value. + * Note: errorptr points to *previous* column's array entry. + */ + cur0 = RIGHT_SHIFT(cur0 + errorptr[dir3+0] + 8, 4); + cur1 = RIGHT_SHIFT(cur1 + errorptr[dir3+1] + 8, 4); + cur2 = RIGHT_SHIFT(cur2 + errorptr[dir3+2] + 8, 4); + /* Limit the error using transfer function set by init_error_limit. + * See comments with init_error_limit for rationale. + */ + cur0 = error_limit[cur0]; + cur1 = error_limit[cur1]; + cur2 = error_limit[cur2]; + /* Form pixel value + error, and range-limit to 0..MAXJSAMPLE. + * The maximum error is +- MAXJSAMPLE (or less with error limiting); + * this sets the required size of the range_limit array. + */ + cur0 += GETJSAMPLE(inptr[0]); + cur1 += GETJSAMPLE(inptr[1]); + cur2 += GETJSAMPLE(inptr[2]); + cur0 = GETJSAMPLE(range_limit[cur0]); + cur1 = GETJSAMPLE(range_limit[cur1]); + cur2 = GETJSAMPLE(range_limit[cur2]); + /* Index into the cache with adjusted pixel value */ + cachep = & histogram[cur0>>C0_SHIFT][cur1>>C1_SHIFT][cur2>>C2_SHIFT]; + /* If we have not seen this color before, find nearest colormap */ + /* entry and update the cache */ + if (*cachep == 0) + fill_inverse_cmap(cinfo, cur0>>C0_SHIFT,cur1>>C1_SHIFT,cur2>>C2_SHIFT); + /* Now emit the colormap index for this cell */ + { register int pixcode = *cachep - 1; + *outptr = (JSAMPLE) pixcode; + /* Compute representation error for this pixel */ + cur0 -= GETJSAMPLE(colormap0[pixcode]); + cur1 -= GETJSAMPLE(colormap1[pixcode]); + cur2 -= GETJSAMPLE(colormap2[pixcode]); + } + /* Compute error fractions to be propagated to adjacent pixels. + * Add these into the running sums, and simultaneously shift the + * next-line error sums left by 1 column. + */ + { register LOCFSERROR bnexterr, delta; + + bnexterr = cur0; /* Process component 0 */ + delta = cur0 * 2; + cur0 += delta; /* form error * 3 */ + errorptr[0] = (FSERROR) (bpreverr0 + cur0); + cur0 += delta; /* form error * 5 */ + bpreverr0 = belowerr0 + cur0; + belowerr0 = bnexterr; + cur0 += delta; /* form error * 7 */ + bnexterr = cur1; /* Process component 1 */ + delta = cur1 * 2; + cur1 += delta; /* form error * 3 */ + errorptr[1] = (FSERROR) (bpreverr1 + cur1); + cur1 += delta; /* form error * 5 */ + bpreverr1 = belowerr1 + cur1; + belowerr1 = bnexterr; + cur1 += delta; /* form error * 7 */ + bnexterr = cur2; /* Process component 2 */ + delta = cur2 * 2; + cur2 += delta; /* form error * 3 */ + errorptr[2] = (FSERROR) (bpreverr2 + cur2); + cur2 += delta; /* form error * 5 */ + bpreverr2 = belowerr2 + cur2; + belowerr2 = bnexterr; + cur2 += delta; /* form error * 7 */ + } + /* At this point curN contains the 7/16 error value to be propagated + * to the next pixel on the current line, and all the errors for the + * next line have been shifted over. We are therefore ready to move on. + */ + inptr += dir3; /* Advance pixel pointers to next column */ + outptr += dir; + errorptr += dir3; /* advance errorptr to current column */ + } + /* Post-loop cleanup: we must unload the final error values into the + * final fserrors[] entry. Note we need not unload belowerrN because + * it is for the dummy column before or after the actual array. + */ + errorptr[0] = (FSERROR) bpreverr0; /* unload prev errs into array */ + errorptr[1] = (FSERROR) bpreverr1; + errorptr[2] = (FSERROR) bpreverr2; + } +} + + +/* + * Initialize the error-limiting transfer function (lookup table). + * The raw F-S error computation can potentially compute error values of up to + * +- MAXJSAMPLE. But we want the maximum correction applied to a pixel to be + * much less, otherwise obviously wrong pixels will be created. (Typical + * effects include weird fringes at color-area boundaries, isolated bright + * pixels in a dark area, etc.) The standard advice for avoiding this problem + * is to ensure that the "corners" of the color cube are allocated as output + * colors; then repeated errors in the same direction cannot cause cascading + * error buildup. However, that only prevents the error from getting + * completely out of hand; Aaron Giles reports that error limiting improves + * the results even with corner colors allocated. + * A simple clamping of the error values to about +- MAXJSAMPLE/8 works pretty + * well, but the smoother transfer function used below is even better. Thanks + * to Aaron Giles for this idea. + */ + +LOCAL(void) +init_error_limit (j_decompress_ptr cinfo) +/* Allocate and fill in the error_limiter table */ +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + int * table; + int in, out; + + table = (int *) (*cinfo->mem->alloc_small) + ((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE*2+1) * SIZEOF(int)); + table += MAXJSAMPLE; /* so can index -MAXJSAMPLE .. +MAXJSAMPLE */ + cquantize->error_limiter = table; + +#define STEPSIZE ((MAXJSAMPLE+1)/16) + /* Map errors 1:1 up to +- MAXJSAMPLE/16 */ + out = 0; + for (in = 0; in < STEPSIZE; in++, out++) { + table[in] = out; table[-in] = -out; + } + /* Map errors 1:2 up to +- 3*MAXJSAMPLE/16 */ + for (; in < STEPSIZE*3; in++, out += (in&1) ? 0 : 1) { + table[in] = out; table[-in] = -out; + } + /* Clamp the rest to final out value (which is (MAXJSAMPLE+1)/8) */ + for (; in <= MAXJSAMPLE; in++) { + table[in] = out; table[-in] = -out; + } +#undef STEPSIZE +} + + +/* + * Finish up at the end of each pass. + */ + +METHODDEF(void) +finish_pass1 (j_decompress_ptr cinfo) +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + + /* Select the representative colors and fill in cinfo->colormap */ + cinfo->colormap = cquantize->sv_colormap; + select_colors(cinfo, cquantize->desired); + /* Force next pass to zero the color index table */ + cquantize->needs_zeroed = TRUE; +} + + +METHODDEF(void) +finish_pass2 (j_decompress_ptr cinfo) +{ + /* no work */ +} + + +/* + * Initialize for each processing pass. + */ + +METHODDEF(void) +start_pass_2_quant (j_decompress_ptr cinfo, boolean is_pre_scan) +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + hist3d histogram = cquantize->histogram; + int i; + + /* Only F-S dithering or no dithering is supported. */ + /* If user asks for ordered dither, give him F-S. */ + if (cinfo->dither_mode != JDITHER_NONE) + cinfo->dither_mode = JDITHER_FS; + + if (is_pre_scan) { + /* Set up method pointers */ + cquantize->pub.color_quantize = prescan_quantize; + cquantize->pub.finish_pass = finish_pass1; + cquantize->needs_zeroed = TRUE; /* Always zero histogram */ + } else { + /* Set up method pointers */ + if (cinfo->dither_mode == JDITHER_FS) + cquantize->pub.color_quantize = pass2_fs_dither; + else + cquantize->pub.color_quantize = pass2_no_dither; + cquantize->pub.finish_pass = finish_pass2; + + /* Make sure color count is acceptable */ + i = cinfo->actual_number_of_colors; + if (i < 1) + ERREXIT1(cinfo, JERR_QUANT_FEW_COLORS, 1); + if (i > MAXNUMCOLORS) + ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXNUMCOLORS); + + if (cinfo->dither_mode == JDITHER_FS) { + size_t arraysize = (size_t) ((cinfo->output_width + 2) * + (3 * SIZEOF(FSERROR))); + /* Allocate Floyd-Steinberg workspace if we didn't already. */ + if (cquantize->fserrors == NULL) + cquantize->fserrors = (FSERRPTR) (*cinfo->mem->alloc_large) + ((j_common_ptr) cinfo, JPOOL_IMAGE, arraysize); + /* Initialize the propagated errors to zero. */ + jzero_far((void FAR *) cquantize->fserrors, arraysize); + /* Make the error-limit table if we didn't already. */ + if (cquantize->error_limiter == NULL) + init_error_limit(cinfo); + cquantize->on_odd_row = FALSE; + } + + } + /* Zero the histogram or inverse color map, if necessary */ + if (cquantize->needs_zeroed) { + for (i = 0; i < HIST_C0_ELEMS; i++) { + jzero_far((void FAR *) histogram[i], + HIST_C1_ELEMS*HIST_C2_ELEMS * SIZEOF(histcell)); + } + cquantize->needs_zeroed = FALSE; + } +} + + +/* + * Switch to a new external colormap between output passes. + */ + +METHODDEF(void) +new_color_map_2_quant (j_decompress_ptr cinfo) +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + + /* Reset the inverse color map */ + cquantize->needs_zeroed = TRUE; +} + + +/* + * Module initialization routine for 2-pass color quantization. + */ + +GLOBAL(void) +jinit_2pass_quantizer (j_decompress_ptr cinfo) +{ + my_cquantize_ptr cquantize; + int i; + + cquantize = (my_cquantize_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_cquantizer)); + cinfo->cquantize = (struct jpeg_color_quantizer *) cquantize; + cquantize->pub.start_pass = start_pass_2_quant; + cquantize->pub.new_color_map = new_color_map_2_quant; + cquantize->fserrors = NULL; /* flag optional arrays not allocated */ + cquantize->error_limiter = NULL; + + /* Make sure jdmaster didn't give me a case I can't handle */ + if (cinfo->out_color_components != 3) + ERREXIT(cinfo, JERR_NOTIMPL); + + /* Allocate the histogram/inverse colormap storage */ + cquantize->histogram = (hist3d) (*cinfo->mem->alloc_small) + ((j_common_ptr) cinfo, JPOOL_IMAGE, HIST_C0_ELEMS * SIZEOF(hist2d)); + for (i = 0; i < HIST_C0_ELEMS; i++) { + cquantize->histogram[i] = (hist2d) (*cinfo->mem->alloc_large) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + HIST_C1_ELEMS*HIST_C2_ELEMS * SIZEOF(histcell)); + } + cquantize->needs_zeroed = TRUE; /* histogram is garbage now */ + + /* Allocate storage for the completed colormap, if required. + * We do this now since it is FAR storage and may affect + * the memory manager's space calculations. + */ + if (cinfo->enable_2pass_quant) { + /* Make sure color count is acceptable */ + int desired = cinfo->desired_number_of_colors; + /* Lower bound on # of colors ... somewhat arbitrary as long as > 0 */ + if (desired < 8) + ERREXIT1(cinfo, JERR_QUANT_FEW_COLORS, 8); + /* Make sure colormap indexes can be represented by JSAMPLEs */ + if (desired > MAXNUMCOLORS) + ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXNUMCOLORS); + cquantize->sv_colormap = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo,JPOOL_IMAGE, (JDIMENSION) desired, (JDIMENSION) 3); + cquantize->desired = desired; + } else + cquantize->sv_colormap = NULL; + + /* Only F-S dithering or no dithering is supported. */ + /* If user asks for ordered dither, give him F-S. */ + if (cinfo->dither_mode != JDITHER_NONE) + cinfo->dither_mode = JDITHER_FS; + + /* Allocate Floyd-Steinberg workspace if necessary. + * This isn't really needed until pass 2, but again it is FAR storage. + * Although we will cope with a later change in dither_mode, + * we do not promise to honor max_memory_to_use if dither_mode changes. + */ + if (cinfo->dither_mode == JDITHER_FS) { + cquantize->fserrors = (FSERRPTR) (*cinfo->mem->alloc_large) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + (size_t) ((cinfo->output_width + 2) * (3 * SIZEOF(FSERROR)))); + /* Might as well create the error-limiting table too. */ + init_error_limit(cinfo); + } +} + +#endif /* QUANT_2PASS_SUPPORTED */ diff --git a/mod/pub.mod/libjpeg.mod/jutils.c b/mod/pub.mod/libjpeg.mod/jutils.c new file mode 100644 index 0000000..d18a955 --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jutils.c @@ -0,0 +1,179 @@ +/* + * jutils.c + * + * Copyright (C) 1991-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains tables and miscellaneous utility routines needed + * for both compression and decompression. + * Note we prefix all global names with "j" to minimize conflicts with + * a surrounding application. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* + * jpeg_zigzag_order[i] is the zigzag-order position of the i'th element + * of a DCT block read in natural order (left to right, top to bottom). + */ + +#if 0 /* This table is not actually needed in v6a */ + +const int jpeg_zigzag_order[DCTSIZE2] = { + 0, 1, 5, 6, 14, 15, 27, 28, + 2, 4, 7, 13, 16, 26, 29, 42, + 3, 8, 12, 17, 25, 30, 41, 43, + 9, 11, 18, 24, 31, 40, 44, 53, + 10, 19, 23, 32, 39, 45, 52, 54, + 20, 22, 33, 38, 46, 51, 55, 60, + 21, 34, 37, 47, 50, 56, 59, 61, + 35, 36, 48, 49, 57, 58, 62, 63 +}; + +#endif + +/* + * jpeg_natural_order[i] is the natural-order position of the i'th element + * of zigzag order. + * + * When reading corrupted data, the Huffman decoders could attempt + * to reference an entry beyond the end of this array (if the decoded + * zero run length reaches past the end of the block). To prevent + * wild stores without adding an inner-loop test, we put some extra + * "63"s after the real entries. This will cause the extra coefficient + * to be stored in location 63 of the block, not somewhere random. + * The worst case would be a run-length of 15, which means we need 16 + * fake entries. + */ + +const int jpeg_natural_order[DCTSIZE2+16] = { + 0, 1, 8, 16, 9, 2, 3, 10, + 17, 24, 32, 25, 18, 11, 4, 5, + 12, 19, 26, 33, 40, 48, 41, 34, + 27, 20, 13, 6, 7, 14, 21, 28, + 35, 42, 49, 56, 57, 50, 43, 36, + 29, 22, 15, 23, 30, 37, 44, 51, + 58, 59, 52, 45, 38, 31, 39, 46, + 53, 60, 61, 54, 47, 55, 62, 63, + 63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */ + 63, 63, 63, 63, 63, 63, 63, 63 +}; + + +/* + * Arithmetic utilities + */ + +GLOBAL(long) +jdiv_round_up (long a, long b) +/* Compute a/b rounded up to next integer, ie, ceil(a/b) */ +/* Assumes a >= 0, b > 0 */ +{ + return (a + b - 1L) / b; +} + + +GLOBAL(long) +jround_up (long a, long b) +/* Compute a rounded up to next multiple of b, ie, ceil(a/b)*b */ +/* Assumes a >= 0, b > 0 */ +{ + a += b - 1L; + return a - (a % b); +} + + +/* On normal machines we can apply MEMCOPY() and MEMZERO() to sample arrays + * and coefficient-block arrays. This won't work on 80x86 because the arrays + * are FAR and we're assuming a small-pointer memory model. However, some + * DOS compilers provide far-pointer versions of memcpy() and memset() even + * in the small-model libraries. These will be used if USE_FMEM is defined. + * Otherwise, the routines below do it the hard way. (The performance cost + * is not all that great, because these routines aren't very heavily used.) + */ + +#ifndef NEED_FAR_POINTERS /* normal case, same as regular macros */ +#define FMEMCOPY(dest,src,size) MEMCOPY(dest,src,size) +#define FMEMZERO(target,size) MEMZERO(target,size) +#else /* 80x86 case, define if we can */ +#ifdef USE_FMEM +#define FMEMCOPY(dest,src,size) _fmemcpy((void FAR *)(dest), (const void FAR *)(src), (size_t)(size)) +#define FMEMZERO(target,size) _fmemset((void FAR *)(target), 0, (size_t)(size)) +#endif +#endif + + +GLOBAL(void) +jcopy_sample_rows (JSAMPARRAY input_array, int source_row, + JSAMPARRAY output_array, int dest_row, + int num_rows, JDIMENSION num_cols) +/* Copy some rows of samples from one place to another. + * num_rows rows are copied from input_array[source_row++] + * to output_array[dest_row++]; these areas may overlap for duplication. + * The source and destination arrays must be at least as wide as num_cols. + */ +{ + register JSAMPROW inptr, outptr; +#ifdef FMEMCOPY + register size_t count = (size_t) (num_cols * SIZEOF(JSAMPLE)); +#else + register JDIMENSION count; +#endif + register int row; + + input_array += source_row; + output_array += dest_row; + + for (row = num_rows; row > 0; row--) { + inptr = *input_array++; + outptr = *output_array++; +#ifdef FMEMCOPY + FMEMCOPY(outptr, inptr, count); +#else + for (count = num_cols; count > 0; count--) + *outptr++ = *inptr++; /* needn't bother with GETJSAMPLE() here */ +#endif + } +} + + +GLOBAL(void) +jcopy_block_row (JBLOCKROW input_row, JBLOCKROW output_row, + JDIMENSION num_blocks) +/* Copy a row of coefficient blocks from one place to another. */ +{ +#ifdef FMEMCOPY + FMEMCOPY(output_row, input_row, num_blocks * (DCTSIZE2 * SIZEOF(JCOEF))); +#else + register JCOEFPTR inptr, outptr; + register long count; + + inptr = (JCOEFPTR) input_row; + outptr = (JCOEFPTR) output_row; + for (count = (long) num_blocks * DCTSIZE2; count > 0; count--) { + *outptr++ = *inptr++; + } +#endif +} + + +GLOBAL(void) +jzero_far (void FAR * target, size_t bytestozero) +/* Zero out a chunk of FAR memory. */ +/* This might be sample-array data, block-array data, or alloc_large data. */ +{ +#ifdef FMEMZERO + FMEMZERO(target, bytestozero); +#else + register char FAR * ptr = (char FAR *) target; + register size_t count; + + for (count = bytestozero; count > 0; count--) { + *ptr++ = 0; + } +#endif +} diff --git a/mod/pub.mod/libjpeg.mod/jversion.h b/mod/pub.mod/libjpeg.mod/jversion.h new file mode 100644 index 0000000..6472c58 --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/jversion.h @@ -0,0 +1,14 @@ +/* + * jversion.h + * + * Copyright (C) 1991-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains software version identification. + */ + + +#define JVERSION "6b 27-Mar-1998" + +#define JCOPYRIGHT "Copyright (C) 1998, Thomas G. Lane" diff --git a/mod/pub.mod/libjpeg.mod/libjpeg.bmx b/mod/pub.mod/libjpeg.mod/libjpeg.bmx new file mode 100644 index 0000000..67eb17c --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/libjpeg.bmx @@ -0,0 +1,76 @@ + +Strict + +Module Pub.LibJPEG + +ModuleInfo "Version: 1.07" +ModuleInfo "Author: Independent JPEG Group" +ModuleInfo "License: Freely distributable" +ModuleInfo "Copyright: Independent JPEG Group" +ModuleInfo "Modserver: BRL" +ModuleInfo "Credit: Adapted for BlitzMax by Simon Armstrong" + +ModuleInfo "History: 1.07 Release" +ModuleInfo "History: For the last *#!$ time - BUMP!" +ModuleInfo "History: 1.05 Release" +ModuleInfo "History: savejpg fixes" +ModuleInfo "History: 1.04 Release" +ModuleInfo "History: Removed Print statements" +ModuleInfo "History: 1.03 Release" +ModuleInfo "History: 1.02 Release" +ModuleInfo "History: Fixed C Compiler warnings" + +Import "jcapimin.c" +Import "jcapistd.c" +Import "jccoefct.c" +Import "jccolor.c" +Import "jcdctmgr.c" +Import "jchuff.c" +Import "jcinit.c" +Import "jcmainct.c" +Import "jcmarker.c" +Import "jcmaster.c" +Import "jcomapi.c" +Import "jcparam.c" +Import "jcphuff.c" +Import "jcprepct.c" +Import "jcsample.c" +Import "jctrans.c" +Import "jdapimin.c" +Import "jdapistd.c" +Import "jdatadst.c" +Import "jdatasrc.c" +Import "jdcoefct.c" +Import "jdcolor.c" +Import "jddctmgr.c" +Import "jdhuff.c" +Import "jdinput.c" +Import "jdmainct.c" +Import "jdmarker.c" +Import "jdmaster.c" +Import "jdmerge.c" +Import "jdphuff.c" +Import "jdpostct.c" +Import "jdsample.c" +Import "jdtrans.c" +Import "jerror.c" +Import "jfdctflt.c" +Import "jfdctfst.c" +Import "jfdctint.c" +Import "jidctflt.c" +Import "jidctfst.c" +Import "jidctint.c" +Import "jidctred.c" +Import "jmemmgr.c" +Import "jmemnobs.c" +Import "jquant1.c" +Import "jquant2.c" +Import "jutils.c" +Import "loadjpeg.c" + +Extern "C" + +Function loadjpg(stream:Object,readfunc:Byte Ptr,width Var,height Var,depth Var,pix:Byte Ptr Var) +Function savejpg(stream:Object,writefunc:Byte Ptr,width,height,pitch,pix:Byte Ptr,quality) + +End Extern diff --git a/mod/pub.mod/libjpeg.mod/loadjpeg.c b/mod/pub.mod/libjpeg.mod/loadjpeg.c new file mode 100644 index 0000000..968cc9e --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/loadjpeg.c @@ -0,0 +1,161 @@ +// loadjpeg.c + +// jpeg wrapper for BlitzMax libjpeg + +#include <stdio.h> +#include <stdlib.h> +#include <setjmp.h> +#include <jpeglib.h> + +static jmp_buf jmp_env; + +static void format_message (j_common_ptr cinfo, char * buffer) {} +static void output_message (j_common_ptr cinfo) {} +static void emit_message (j_common_ptr cinfo, int msg_level) {} + +static void error_exit (j_common_ptr cinfo){ +// printf("error_exit called from loadjpeg.c\n"); +// fflush(stdout); + longjmp( jmp_env,-1 ); +} +//jpeg_destroy(cinfo);} + +static void reset_error_mgr (j_common_ptr cinfo) { + cinfo->err->num_warnings=0;cinfo->err->msg_code = 0; +} + +int (*ReadStream)(void*,int,void*); +int (*WriteStream)(const void*,int,void*); + +void initjerr(struct jpeg_error_mgr *jerr) +{ + jerr->error_exit = error_exit; + jerr->emit_message = emit_message; + jerr->output_message = output_message; + jerr->format_message = format_message; + jerr->reset_error_mgr = reset_error_mgr; + jerr->trace_level = 0; // default = no tracing + jerr->num_warnings = 0; // no warnings emitted yet + jerr->msg_code = 0; // may be useful as a flag for "no error" +// Initialize message table pointers + jerr->jpeg_message_table = NULL; //jpeg_std_message_table; + jerr->last_jpeg_message = 0; //(int) JMSG_LASTMSGCODE - 1; +// jerr->jpeg_message_table = jpeg_std_message_table; +// jerr->last_jpeg_message = (int) JMSG_LASTMSGCODE - 1; + jerr->addon_message_table = NULL; + jerr->first_addon_message = 0; // for safety + jerr->last_addon_message = 0; +} + +int loadjpg(void *stream,void *readfunc,int *width,int *height,int *channels,char **pix) +{ + int size,w,h,d,span,res; + char *p; + + struct jpeg_decompress_struct cinfo; + struct jpeg_error_mgr jerr; + + ReadStream=readfunc; + + initjerr(&jerr); + cinfo.err=&jerr; + + jpeg_create_decompress(&cinfo); + jpeg_stdio_src(&cinfo,(FILE*)stream); + + if( setjmp( jmp_env ) ){ + jpeg_destroy_decompress( &cinfo ); + return -1; + } + + res=jpeg_read_header(&cinfo,TRUE); + if (res!=1){ + jpeg_destroy_decompress( &cinfo ); + return -1; + } + + jpeg_start_decompress(&cinfo); + + *width=w=cinfo.output_width; + *height=h=cinfo.output_height; + *channels=d=cinfo.output_components; + p=(char*)malloc(w*h*d); + *pix=p; + if (p) + { + span=w*d; + while (h--) + { + jpeg_read_scanlines(&cinfo,(JSAMPARRAY)&p,1); + p+=span; + } + } + jpeg_finish_decompress(&cinfo); + jpeg_destroy_decompress(&cinfo); + return 0; +} + + +struct jpeg_compress_struct ccinfo; +struct jpeg_error_mgr jerr; + +int savejpg(void *stream,void *writefunc,int width,int height,int pitch,char *pix,int qlty){ + int y; + + WriteStream=writefunc; + + initjerr(&jerr); + ccinfo.err=&jerr; + + jpeg_create_compress(&ccinfo); + jpeg_stdio_dest(&ccinfo,(FILE*)stream); //(_iobuf*)out); + + if( setjmp(jmp_env) ){return 1;} + + ccinfo.image_width=width; //* image width and height, in pixels + ccinfo.image_height=height; + ccinfo.input_components=3; // # of color components per pixel + ccinfo.in_color_space=JCS_RGB; // colorspace of input image + jpeg_set_defaults(&ccinfo); + jpeg_set_quality(&ccinfo,qlty,TRUE); + jpeg_start_compress(&ccinfo,TRUE); + + for (y=0;y<height;y++){ + jpeg_write_scanlines(&ccinfo,&pix,1); + pix+=pitch; + } + + jpeg_finish_compress(&ccinfo); + jpeg_destroy_compress(&ccinfo); + return 0; +} + + + +#ifdef simon +#include <jinclude.h> +#include <jpeglib.h> +#include <jversion.h> +#include <jerror.h> + +// from jerror.c +/* + * Create the message string table. + * We do this from the master message list in jerror.h by re-reading + * jerror.h with a suitable definition for macro JMESSAGE. + * The message table is made an external symbol just in case any applications + * want to refer to it directly. + */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jpeg_std_message_table jMsgTable +#endif + +#define JMESSAGE(code,string) string , + +const char * const jpeg_std_message_table[] = { +#include <jerror.h> + NULL +}; + +#endif diff --git a/mod/pub.mod/libjpeg.mod/transupp.h b/mod/pub.mod/libjpeg.mod/transupp.h new file mode 100644 index 0000000..5c2d32a --- /dev/null +++ b/mod/pub.mod/libjpeg.mod/transupp.h @@ -0,0 +1,135 @@ +/* + * transupp.h + * + * Copyright (C) 1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains declarations for image transformation routines and + * other utility code used by the jpegtran sample application. These are + * NOT part of the core JPEG library. But we keep these routines separate + * from jpegtran.c to ease the task of maintaining jpegtran-like programs + * that have other user interfaces. + * + * NOTE: all the routines declared here have very specific requirements + * about when they are to be executed during the reading and writing of the + * source and destination files. See the comments in transupp.c, or see + * jpegtran.c for an example of correct usage. + */ + +/* If you happen not to want the image transform support, disable it here */ +#ifndef TRANSFORMS_SUPPORTED +#define TRANSFORMS_SUPPORTED 1 /* 0 disables transform code */ +#endif + +/* Short forms of external names for systems with brain-damaged linkers. */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jtransform_request_workspace jTrRequest +#define jtransform_adjust_parameters jTrAdjust +#define jtransform_execute_transformation jTrExec +#define jcopy_markers_setup jCMrkSetup +#define jcopy_markers_execute jCMrkExec +#endif /* NEED_SHORT_EXTERNAL_NAMES */ + + +/* + * Codes for supported types of image transformations. + */ + +typedef enum { + JXFORM_NONE, /* no transformation */ + JXFORM_FLIP_H, /* horizontal flip */ + JXFORM_FLIP_V, /* vertical flip */ + JXFORM_TRANSPOSE, /* transpose across UL-to-LR axis */ + JXFORM_TRANSVERSE, /* transpose across UR-to-LL axis */ + JXFORM_ROT_90, /* 90-degree clockwise rotation */ + JXFORM_ROT_180, /* 180-degree rotation */ + JXFORM_ROT_270 /* 270-degree clockwise (or 90 ccw) */ +} JXFORM_CODE; + +/* + * Although rotating and flipping data expressed as DCT coefficients is not + * hard, there is an asymmetry in the JPEG format specification for images + * whose dimensions aren't multiples of the iMCU size. The right and bottom + * image edges are padded out to the next iMCU boundary with junk data; but + * no padding is possible at the top and left edges. If we were to flip + * the whole image including the pad data, then pad garbage would become + * visible at the top and/or left, and real pixels would disappear into the + * pad margins --- perhaps permanently, since encoders & decoders may not + * bother to preserve DCT blocks that appear to be completely outside the + * nominal image area. So, we have to exclude any partial iMCUs from the + * basic transformation. + * + * Transpose is the only transformation that can handle partial iMCUs at the + * right and bottom edges completely cleanly. flip_h can flip partial iMCUs + * at the bottom, but leaves any partial iMCUs at the right edge untouched. + * Similarly flip_v leaves any partial iMCUs at the bottom edge untouched. + * The other transforms are defined as combinations of these basic transforms + * and process edge blocks in a way that preserves the equivalence. + * + * The "trim" option causes untransformable partial iMCUs to be dropped; + * this is not strictly lossless, but it usually gives the best-looking + * result for odd-size images. Note that when this option is active, + * the expected mathematical equivalences between the transforms may not hold. + * (For example, -rot 270 -trim trims only the bottom edge, but -rot 90 -trim + * followed by -rot 180 -trim trims both edges.) + * + * We also offer a "force to grayscale" option, which simply discards the + * chrominance channels of a YCbCr image. This is lossless in the sense that + * the luminance channel is preserved exactly. It's not the same kind of + * thing as the rotate/flip transformations, but it's convenient to handle it + * as part of this package, mainly because the transformation routines have to + * be aware of the option to know how many components to work on. + */ + +typedef struct { + /* Options: set by caller */ + JXFORM_CODE transform; /* image transform operator */ + boolean trim; /* if TRUE, trim partial MCUs as needed */ + boolean force_grayscale; /* if TRUE, convert color image to grayscale */ + + /* Internal workspace: caller should not touch these */ + int num_components; /* # of components in workspace */ + jvirt_barray_ptr * workspace_coef_arrays; /* workspace for transformations */ +} jpeg_transform_info; + + +#if TRANSFORMS_SUPPORTED + +/* Request any required workspace */ +EXTERN(void) jtransform_request_workspace + JPP((j_decompress_ptr srcinfo, jpeg_transform_info *info)); +/* Adjust output image parameters */ +EXTERN(jvirt_barray_ptr *) jtransform_adjust_parameters + JPP((j_decompress_ptr srcinfo, j_compress_ptr dstinfo, + jvirt_barray_ptr *src_coef_arrays, + jpeg_transform_info *info)); +/* Execute the actual transformation, if any */ +EXTERN(void) jtransform_execute_transformation + JPP((j_decompress_ptr srcinfo, j_compress_ptr dstinfo, + jvirt_barray_ptr *src_coef_arrays, + jpeg_transform_info *info)); + +#endif /* TRANSFORMS_SUPPORTED */ + + +/* + * Support for copying optional markers from source to destination file. + */ + +typedef enum { + JCOPYOPT_NONE, /* copy no optional markers */ + JCOPYOPT_COMMENTS, /* copy only comment (COM) markers */ + JCOPYOPT_ALL /* copy all optional markers */ +} JCOPY_OPTION; + +#define JCOPYOPT_DEFAULT JCOPYOPT_COMMENTS /* recommended default */ + +/* Setup decompression object to save desired markers in memory */ +EXTERN(void) jcopy_markers_setup + JPP((j_decompress_ptr srcinfo, JCOPY_OPTION option)); +/* Copy markers saved in the given source object to the destination object */ +EXTERN(void) jcopy_markers_execute + JPP((j_decompress_ptr srcinfo, j_compress_ptr dstinfo, + JCOPY_OPTION option)); diff --git a/mod/pub.mod/libpng.mod/ANNOUNCE b/mod/pub.mod/libpng.mod/ANNOUNCE new file mode 100644 index 0000000..c861402 --- /dev/null +++ b/mod/pub.mod/libpng.mod/ANNOUNCE @@ -0,0 +1,51 @@ + +Libpng 1.2.12 - June 27, 2006 + +This is a public release of libpng, intended for use in production codes. + +Files available for download: + +Source files with LF line endings (for Unix/Linux) and with a +"configure" script + + libpng-1.2.12.tar.gz + libpng-1.2.12.tar.bz2 + +Source files with LF line endings (for Unix/Linux) without the +"configure" script + + libpng-1.2.12-no-config.tar.gz + libpng-1.2.12-no-config.tar.bz2 + +Source files with CRLF line endings (for Windows), without the +"configure" script + + lpng1212.zip + lpng1212.tar.bz2 + +Project files + + libpng-1.2.12-project-netware.zip + libpng-1.2.12-project-wince.zip + +Other information: + + libpng-1.2.12-README.txt + libpng-1.2.12-KNOWNBUGS.txt + libpng-1.2.12-LICENSE.txt + libpng-1.2.12-Y2K-compliance.txt + +Changes since the last public release (1.2.11): + +version 1.2.12 [June 27, 2006] + +version 1.0.20, 1.2.12 [June 27, 2006] + Really increased sprintf buffer from 50 to 52 chars in pngrutil.c to avoid + buffer overflow. + +Send comments/corrections/commendations to png-mng-implement at lists.sf.net +(subscription required; visit +https://lists.sourceforge.net/lists/listinfo/png-mng-implement +to subscribe) or to glennrp at users.sourceforge.net + +Glenn R-P diff --git a/mod/pub.mod/libpng.mod/CHANGES b/mod/pub.mod/libpng.mod/CHANGES new file mode 100644 index 0000000..41912db --- /dev/null +++ b/mod/pub.mod/libpng.mod/CHANGES @@ -0,0 +1,1624 @@ + +CHANGES - changes for libpng + +version 0.2 + added reader into png.h + fixed small problems in stub file + +version 0.3 + added pull reader + split up pngwrite.c to several files + added pnglib.txt + added example.c + cleaned up writer, adding a few new transformations + fixed some bugs in writer + interfaced with zlib 0.5 + added K&R support + added check for 64 KB blocks for 16 bit machines + +version 0.4 + cleaned up code and commented code + simplified time handling into png_time + created png_color_16 and png_color_8 to handle color needs + cleaned up color type defines + fixed various bugs + made various names more consistent + interfaced with zlib 0.71 + cleaned up zTXt reader and writer (using zlib's Reset functions) + split transformations into pngrtran.c and pngwtran.c + +version 0.5 + interfaced with zlib 0.8 + fixed many reading and writing bugs + saved using 3 spaces instead of tabs + +version 0.6 + added png_large_malloc() and png_large_free() + added png_size_t + cleaned up some compiler warnings + added png_start_read_image() + +version 0.7 + cleaned up lots of bugs + finished dithering and other stuff + added test program + changed name from pnglib to libpng + +version 0.71 [June, 1995] + changed pngtest.png for zlib 0.93 + fixed error in libpng.txt and example.c + +version 0.8 + cleaned up some bugs + added png_set_filler() + split up pngstub.c into pngmem.c, pngio.c, and pngerror.c + added #define's to remove unwanted code + moved png_info_init() to png.c + added old_size into png_realloc() + added functions to manually set filtering and compression info + changed compression parameters based on image type + optimized filter selection code + added version info + changed external functions passing floats to doubles (k&r problems?) + put all the configurable stuff in pngconf.h + enabled png_set_shift to work with paletted images on read + added png_read_update_info() - updates info structure with + transformations + +version 0.81 [August, 1995] + incorporated Tim Wegner's medium model code (thanks, Tim) + +version 0.82 [September, 1995] + [unspecified changes] + +version 0.85 [December, 1995] + added more medium model code (almost everything's a far) + added i/o, error, and memory callback functions + fixed some bugs (16 bit, 4 bit interlaced, etc.) + added first run progressive reader (barely tested) + +version 0.86 [January, 1996] + fixed bugs + improved documentation + +version 0.87 [January, 1996] + fixed medium model bugs + fixed other bugs introduced in 0.85 and 0.86 + added some minor documentation + +version 0.88 [January, 1996] + fixed progressive bugs + replaced tabs with spaces + cleaned up documentation + added callbacks for read/write and warning/error functions + +version 0.89 [July, 1996] + added new initialization API to make libpng work better with shared libs + we now have png_create_read_struct(), png_create_write_struct(), + png_create_info_struct(), png_destroy_read_struct(), and + png_destroy_write_struct() instead of the separate calls to + malloc and png_read_init(), png_info_init(), and png_write_init() + changed warning/error callback functions to fix bug - this means you + should use the new initialization API if you were using the old + png_set_message_fn() calls, and that the old API no longer exists + so that people are aware that they need to change their code + changed filter selection API to allow selection of multiple filters + since it didn't work in previous versions of libpng anyways + optimized filter selection code + fixed png_set_background() to allow using an arbitrary RGB color for + paletted images + fixed gamma and background correction for paletted images, so + png_correct_palette is not needed unless you are correcting an + external palette (you will need to #define PNG_CORRECT_PALETTE_SUPPORTED + in pngconf.h) - if nobody uses this, it may disappear in the future. + fixed bug with Borland 64K memory allocation (Alexander Lehmann) + fixed bug in interlace handling (Smarasderagd, I think) + added more error checking for writing and image to reduce invalid files + separated read and write functions so that they won't both be linked + into a binary when only reading or writing functionality is used + new pngtest image also has interlacing and zTXt + updated documentation to reflect new API + +version 0.90 [January, 1997] + made CRC errors/warnings on critical and ancillary chunks configurable + libpng will use the zlib CRC routines by (compile-time) default + changed DOS small/medium model memory support - needs zlib 1.04 (Tim Wegner) + added external C++ wrapper statements to png.h (Gilles Dauphin) + allow PNG file to be read when some or all of file signature has already + been read from the beginning of the stream. ****This affects the size + of info_struct and invalidates all programs that use a shared libpng**** + fixed png_filler() declarations + fixed? background color conversions + fixed order of error function pointers to match documentation + current chunk name is now available in png_struct to reduce the number + of nearly identical error messages (will simplify multi-lingual + support when available) + try to get ready for unknown-chunk callback functions: + - previously read critical chunks are flagged, so the chunk handling + routines can determine if the chunk is in the right place + - all chunk handling routines have the same prototypes, so we will + be able to handle all chunks via a callback mechanism + try to fix Linux "setjmp" buffer size problems + removed png_large_malloc, png_large_free, and png_realloc functions. + +version 0.95 [March, 1997] + fixed bug in pngwutil.c allocating "up_row" twice and "avg_row" never + fixed bug in PNG file signature compares when start != 0 + changed parameter type of png_set_filler(...filler...) from png_byte + to png_uint_32 + added test for MACOS to ensure that both math.h and fp.h are not #included + added macros for libpng to be compiled as a Windows DLL (Andreas Kupries) + added "packswap" transformation, which changes the endianness of + packed-pixel bytes (Kevin Bracey) + added "strip_alpha" transformation, which removes the alpha channel of + input images without using it (not necessarily a good idea) + added "swap_alpha" transformation, which puts the alpha channel in front + of the color bytes instead of after + removed all implicit variable tests which assume NULL == 0 (I think) + changed several variables to "png_size_t" to show 16/32-bit limitations + added new pCAL chunk read/write support + added experimental filter selection weighting (Greg Roelofs) + removed old png_set_rgbx() and png_set_xrgb() functions that have been + obsolete for about 2 years now (use png_set_filler() instead) + added macros to read 16- and 32-bit ints directly from buffer, to be + used only on those systems that support it (namely PowerPC and 680x0) + With some testing, this may become the default for MACOS/PPC systems. + only calculate CRC on data if we are going to use it + added macros for zTXt compression type PNG_zTXt_COMPRESSION_??? + added macros for simple libpng debugging output selectable at compile time + removed PNG_READ_END_MODE in progressive reader (Smarasderagd) + more description of info_struct in libpng.txt and png.h + more instructions in example.c + more chunk types tested in pngtest.c + renamed pngrcb.c to pngset.c, and all png_read_<chunk> functions to be + png_set_<chunk>. We now have corresponding png_get_<chunk> + functions in pngget.c to get information in info_ptr. This isolates + the application from the internal organization of png_info_struct + (good for shared library implementations). + +version 0.96 [May, 1997] + fixed serious bug with < 8bpp images introduced in 0.95 + fixed 256-color transparency bug (Greg Roelofs) + fixed up documentation (Greg Roelofs, Laszlo Nyul) + fixed "error" in pngconf.h for Linux setjmp() behaviour + fixed DOS medium model support (Tim Wegner) + fixed png_check_keyword() for case with error in static string text + added read of CRC after IEND chunk for embedded PNGs (Laszlo Nyul) + added typecasts to quiet compiler errors + added more debugging info + +version 0.97 [January, 1998] + removed PNG_USE_OWN_CRC capability + relocated png_set_crc_action from pngrutil.c to pngrtran.c + fixed typecasts of "new_key", etc. (Andreas Dilger) + added RFC 1152 [sic] date support + fixed bug in gamma handling of 4-bit grayscale + added 2-bit grayscale gamma handling (Glenn R-P) + added more typecasts. 65536L becomes (png_uint_32)65536L, etc. (Glenn R-P) + minor corrections in libpng.txt + added simple sRGB support (Glenn R-P) + easier conditional compiling, e.g. define PNG_READ/WRITE_NOT_FULLY_SUPPORTED; + all configurable options can be selected from command-line instead + of having to edit pngconf.h (Glenn R-P) + fixed memory leak in pngwrite.c (free info_ptr->text) (Glenn R-P) + added more conditions for png_do_background, to avoid changing + black pixels to background when a background is supplied and + no pixels are transparent + repaired PNG_NO_STDIO behaviour + tested NODIV support and made it default behaviour (Greg Roelofs) + added "-m" option and PNGTEST_DEBUG_MEMORY to pngtest (John Bowler) + regularized version numbering scheme and bumped shared-library major + version number to 2 to avoid problems with libpng 0.89 apps (Greg Roelofs) + +version 0.98 [January, 1998] + cleaned up some typos in libpng.txt and in code documentation + fixed memory leaks in pCAL chunk processing (Glenn R-P and John Bowler) + cosmetic change "display_gamma" to "screen_gamma" in pngrtran.c + changed recommendation about file_gamma for PC images to .51 from .45, + in example.c and libpng.txt, added comments to distinguish between + screen_gamma, viewing_gamma, and display_gamma. + changed all references to RFC1152 to read RFC1123 and changed the + PNG_TIME_RFC1152_SUPPORTED macro to PNG_TIME_RFC1123_SUPPORTED + added png_invert_alpha capability (Glenn R-P -- suggestion by Jon Vincent) + changed srgb_intent from png_byte to int to avoid compiler bugs + +version 0.99 [January 30, 1998] + free info_ptr->text instead of end_info_ptr->text in pngread.c (John Bowler) + fixed a longstanding "packswap" bug in pngtrans.c + fixed some inconsistencies in pngconf.h that prevented compiling with + PNG_READ_GAMMA_SUPPORTED and PNG_READ_hIST_SUPPORTED undefined + fixed some typos and made other minor rearrangement of libpng.txt (Andreas) + changed recommendation about file_gamma for PC images to .50 from .51 in + example.c and libpng.txt, and changed file_gamma for sRGB images to .45 + added a number of functions to access information from the png structure + png_get_image_height(), etc. (Glenn R-P, suggestion by Brad Pettit) + added TARGET_MACOS similar to zlib-1.0.8 + define PNG_ALWAYS_EXTERN when __MWERKS__ && WIN32 are defined + added type casting to all png_malloc() function calls +version 0.99a [January 31, 1998] + Added type casts and parentheses to all returns that return a value.(Tim W.) +version 0.99b [February 4, 1998] + Added type cast png_uint_32 on malloc function calls where needed. + Changed type of num_hist from png_uint_32 to int (same as num_palette). + Added checks for rowbytes overflow, in case png_size_t is less than 32 bits. + Renamed makefile.elf to makefile.lnx. +version 0.99c [February 7, 1998] + More type casting. Removed erroneous overflow test in pngmem.c. + Added png_buffered_memcpy() and png_buffered_memset(), apply them to rowbytes. + Added UNIX manual pages libpng.3 (incorporating libpng.txt) and png.5. +version 0.99d [February 11, 1998] + Renamed "far_to_near()" "png_far_to_near()" + Revised libpng.3 + Version 99c "buffered" operations didn't work as intended. Replaced them + with png_memcpy_check() and png_memset_check(). + Added many "if (png_ptr == NULL) return" to quell compiler warnings about + unused png_ptr, mostly in pngget.c and pngset.c. + Check for overlength tRNS chunk present when indexed-color PLTE is read. + Cleaned up spelling errors in libpng.3/libpng.txt + Corrected a problem with png_get_tRNS() which returned undefined trans array +version 0.99e [February 28, 1998] + Corrected png_get_tRNS() again. + Add parentheses for easier reading of pngget.c, fixed "||" should be "&&". + Touched up example.c to make more of it compileable, although the entire + file still can't be compiled (Willem van Schaik) + Fixed a bug in png_do_shift() (Bryan Tsai) + Added a space in png.h prototype for png_write_chunk_start() + Replaced pngtest.png with one created with zlib 1.1.1 + Changed pngtest to report PASS even when file size is different (Jean-loup G.) + Corrected some logic errors in png_do_invert_alpha() (Chris Patterson) +version 0.99f [March 5, 1998] + Corrected a bug in pngpread() introduced in version 99c (Kevin Bracey) + Moved makefiles into a "scripts" directory, and added INSTALL instruction file + Added makefile.os2 and pngos2.def (A. Zabolotny) and makefile.s2x (W. Sebok) + Added pointers to "note on libpng versions" in makefile.lnx and README + Added row callback feature when reading and writing nonprogressive rows + and added a test of this feature in pngtest.c + Added user transform callbacks, with test of the feature in pngtest.c +version 0.99g [March 6, 1998, morning] + Minor changes to pngtest.c to suppress compiler warnings. + Removed "beta" language from documentation. +version 0.99h [March 6, 1998, evening] + Minor changes to previous minor changes to pngtest.c + Changed PNG_READ_NOT_FULLY_SUPPORTED to PNG_READ_TRANSFORMS_NOT_SUPPORTED + and added PNG_PROGRESSIVE_READ_NOT_SUPPORTED macro + Added user transform capability + +version 1.00 [March 7, 1998] + Changed several typedefs in pngrutil.c + Added makefile.wat (Pawel Mrochen), updated makefile.tc3 (Willem van Schaik) + replaced "while(1)" with "for(;;)" + added PNGARG() to prototypes in pngtest.c and removed some prototypes + updated some of the makefiles (Tom Lane) + changed some typedefs (s_start, etc.) in pngrutil.c + fixed dimensions of "short_months" array in pngwrite.c + Replaced ansi2knr.c with the one from jpeg-v6 + +version 1.0.0 [March 8, 1998] + Changed name from 1.00 to 1.0.0 (Adam Costello) + Added smakefile.ppc (with SCOPTIONS.ppc) for Amiga PPC (Andreas Kleinert) +version 1.0.0a [March 9, 1998] + Fixed three bugs in pngrtran.c to make gamma+background handling consistent + (Greg Roelofs) + Changed format of the PNG_LIBPNG_VER integer to xyyzz instead of xyz + for major, minor, and bugfix releases. This is 10001. (Adam Costello, + Tom Lane) + Make months range from 1-12 in png_convert_to_rfc1123 +version 1.0.0b [March 13, 1998] + Quieted compiler complaints about two empty "for" loops in pngrutil.c + Minor changes to makefile.s2x + Removed #ifdef/#endif around a png_free() in pngread.c + +version 1.0.1 [March 14, 1998] + Changed makefile.s2x to reduce security risk of using a relative pathname + Fixed some typos in the documentation (Greg). + Fixed a problem with value of "channels" returned by png_read_update_info() +version 1.0.1a [April 21, 1998] + Optimized Paeth calculations by replacing abs() function calls with intrinsics + plus other loop optimizations. Improves avg decoding speed by about 20%. + Commented out i386istic "align" compiler flags in makefile.lnx. + Reduced the default warning level in some makefiles, to make them consistent. + Removed references to IJG and JPEG in the ansi2knr.c copyright statement. + Fixed a bug in png_do_strip_filler with XXRRGGBB => RRGGBB transformation. + Added grayscale and 16-bit capability to png_do_read_filler(). + Fixed a bug in pngset.c, introduced in version 0.99c, that sets rowbytes + too large when writing an image with bit_depth < 8 (Bob Dellaca). + Corrected some bugs in the experimental weighted filtering heuristics. + Moved a misplaced pngrutil code block that truncates tRNS if it has more + than num_palette entries -- test was done before num_palette was defined. + Fixed a png_convert_to_rfc1123() bug that converts day 31 to 0 (Steve Eddins). + Changed compiler flags in makefile.wat for better optimization (Pawel Mrochen). +version 1.0.1b [May 2, 1998] + Relocated png_do_gray_to_rgb() within png_do_read_transformations() (Greg). + Relocated the png_composite macros from pngrtran.c to png.h (Greg). + Added makefile.sco (contributed by Mike Hopkirk). + Fixed two bugs (missing definitions of "istop") introduced in libpng-1.0.1a. + Fixed a bug in pngrtran.c that would set channels=5 under some circumstances. + More work on the Paeth-filtering, achieving imperceptible speedup (A Kleinert). + More work on loop optimization which may help when compiled with C++ compilers. + Added warnings when people try to use transforms they've defined out. + Collapsed 4 "i" and "c" loops into single "i" loops in pngrtran and pngwtran. + Revised paragraph about png_set_expand() in libpng.txt and libpng.3 (Greg) +version 1.0.1c [May 11, 1998] + Fixed a bug in pngrtran.c (introduced in libpng-1.0.1a) where the masks for + filler bytes should have been 0xff instead of 0xf. + Added max_pixel_depth=32 in pngrutil.c when using FILLER with palette images. + Moved PNG_WRITE_WEIGHTED_FILTER_SUPPORTED and PNG_WRITE_FLUSH_SUPPORTED + out of the PNG_WRITE_TRANSFORMS_NOT_SUPPORTED block of pngconf.h + Added "PNG_NO_WRITE_TRANSFORMS" etc., as alternatives for *_NOT_SUPPORTED, + for consistency, in pngconf.h + Added individual "ifndef PNG_NO_[CAPABILITY]" in pngconf.h to make it easier + to remove unwanted capabilities via the compile line + Made some corrections to grammar (which, it's) in documentation (Greg). + Corrected example.c, use of row_pointers in png_write_image(). +version 1.0.1d [May 24, 1998] + Corrected several statements that used side effects illegally in pngrutil.c + and pngtrans.c, that were introduced in version 1.0.1b + Revised png_read_rows() to avoid repeated if-testing for NULL (A Kleinert) + More corrections to example.c, use of row_pointers in png_write_image() + and png_read_rows(). + Added pngdll.mak and pngdef.pas to scripts directory, contributed by + Bob Dellaca, to make a png32bd.dll with Borland C++ 4.5 + Fixed error in example.c with png_set_text: num_text is 3, not 2 (Guido V.) + Changed several loops from count-down to count-up, for consistency. +version 1.0.1e [June 6, 1998] + Revised libpng.txt and libpng.3 description of png_set_read|write_fn(), and + added warnings when people try to set png_read_fn and png_write_fn in + the same structure. + Added a test such that png_do_gamma will be done when num_trans==0 + for truecolor images that have defined a background. This corrects an + error that was introduced in libpng-0.90 that can cause gamma processing + to be skipped. + Added tests in png.h to include "trans" and "trans_values" in structures + when PNG_READ_BACKGROUND_SUPPORTED or PNG_READ_EXPAND_SUPPORTED is defined. + Add png_free(png_ptr->time_buffer) in png_destroy_read_struct() + Moved png_convert_to_rfc_1123() from pngwrite.c to png.c + Added capability for user-provided malloc_fn() and free_fn() functions, + and revised pngtest.c to demonstrate their use, replacing the + PNGTEST_DEBUG_MEM feature. + Added makefile.w32, for Microsoft C++ 4.0 and later (Tim Wegner). + +version 1.0.2 [June 14, 1998] + Fixed two bugs in makefile.bor . +version 1.0.2a [December 30, 1998] + Replaced and extended code that was removed from png_set_filler() in 1.0.1a. + Fixed a bug in png_do_filler() that made it fail to write filler bytes in + the left-most pixel of each row (Kevin Bracey). + Changed "static pngcharp tIME_string" to "static char tIME_string[30]" + in pngtest.c (Duncan Simpson). + Fixed a bug in pngtest.c that caused pngtest to try to write a tIME chunk + even when no tIME chunk was present in the source file. + Fixed a problem in pngrutil.c: gray_to_rgb didn't always work with 16-bit. + Fixed a problem in png_read_push_finish_row(), which would not skip some + passes that it should skip, for images that are less than 3 pixels high. + Interchanged the order of calls to png_do_swap() and png_do_shift() + in pngwtran.c (John Cromer). + Added #ifdef PNG_DEBUG/#endif surrounding use of PNG_DEBUG in png.h . + Changed "bad adaptive filter type" from error to warning in pngrutil.c . + Fixed a documentation error about default filtering with 8-bit indexed-color. + Separated the PNG_NO_STDIO macro into PNG_NO_STDIO and PNG_NO_CONSOLE_IO + (L. Peter Deutsch). + Added png_set_rgb_to_gray() and png_get_rgb_to_gray_status() functions. + Added png_get_copyright() and png_get_header_version() functions. + Revised comments on png_set_progressive_read_fn() in libpng.txt and example.c + Added information about debugging in libpng.txt and libpng.3 . + Changed "ln -sf" to "ln -s -f" in makefile.s2x, makefile.lnx, and makefile.sco. + Removed lines after Dynamic Dependencies" in makefile.aco . + Revised makefile.dec to make a shared library (Jeremie Petit). + Removed trailing blanks from all files. +version 1.0.2a [January 6, 1999] + Removed misplaced #endif and #ifdef PNG_NO_EXTERN near the end of png.h + Added "if" tests to silence complaints about unused png_ptr in png.h and png.c + Changed "check_if_png" function in example.c to return true (nonzero) if PNG. + Changed libpng.txt to demonstrate png_sig_cmp() instead of png_check_sig() + which is obsolete. + +version 1.0.3 [January 14, 1999] + Added makefile.hux, for Hewlett Packard HPUX 10.20 and 11.00 (Jim Rice) + Added a statement of Y2K compliance in png.h, libpng.3, and Y2KINFO. +version 1.0.3a [August 12, 1999] + Added check for PNG_READ_INTERLACE_SUPPORTED in pngread.c; issue a warning + if an attempt is made to read an interlaced image when it's not supported. + Added check if png_ptr->trans is defined before freeing it in pngread.c + Modified the Y2K statement to include versions back to version 0.71 + Fixed a bug in the check for valid IHDR bit_depth/color_types in pngrutil.c + Modified makefile.wat (added -zp8 flag, ".symbolic", changed some comments) + Replaced leading blanks with tab characters in makefile.hux + Changed "dworkin.wustl.edu" to "ccrc.wustl.edu" in various documents. + Changed (float)red and (float)green to (double)red, (double)green + in png_set_rgb_to_gray() to avoid "promotion" problems in AIX. + Fixed a bug in pngconf.h that omitted <stdio.h> when PNG_DEBUG==0 (K Bracey). + Reformatted libpng.3 and libpngpf.3 with proper fonts (script by J. vanZandt). + Updated documentation to refer to the PNG-1.2 specification. + Removed ansi2knr.c and left pointers to the latest source for ansi2knr.c + in makefile.knr, INSTALL, and README (L. Peter Deutsch) + Fixed bugs in calculation of the length of rowbytes when adding alpha + channels to 16-bit images, in pngrtran.c (Chris Nokleberg) + Added function png_set_user_transform_info() to store user_transform_ptr, + user_depth, and user_channels into the png_struct, and a function + png_get_user_transform_ptr() to retrieve the pointer (Chris Nokleberg) + Added function png_set_empty_plte_permitted() to make libpng useable + in MNG applications. + Corrected the typedef for png_free_ptr in png.h (Jesse Jones). + Correct gamma with srgb is 45455 instead of 45000 in pngrutil.c, to be + consistent with PNG-1.2, and allow variance of 500 before complaining. + Added assembler code contributed by Intel in file pngvcrd.c and modified + makefile.w32 to use it (Nirav Chhatrapati, INTEL Corporation, Gilles Vollant) + Changed "ln -s -f" to "ln -f -s" in the makefiles to make Solaris happy. + Added some aliases for png_set_expand() in pngrtran.c, namely + png_set_expand_PLTE(), png_set_expand_depth(), and png_set_expand_tRNS() + (Greg Roelofs, in "PNG: The Definitive Guide"). + Added makefile.beo for BEOS on X86, contributed by Sander Stok. +version 1.0.3b [August 26, 1999] + Replaced 2147483647L several places with PNG_MAX_UINT macro, defined in png.h + Changed leading blanks to tabs in all makefiles. + Define PNG_USE_PNGVCRD in makefile.w32, to get MMX assembler code. + Made alternate versions of png_set_expand() in pngrtran.c, namely + png_set_gray_1_2_4_to_8, png_set_palette_to_rgb, and png_set_tRNS_to_alpha + (Greg Roelofs, in "PNG: The Definitive Guide"). Deleted the 1.0.3a aliases. + Relocated start of 'extern "C"' block in png.h so it doesn't include pngconf.h + Revised calculation of num_blocks in pngmem.c to avoid a potentially + negative shift distance, whose results are undefined in the C language. + Added a check in pngset.c to prevent writing multiple tIME chunks. + Added a check in pngwrite.c to detect invalid small window_bits sizes. +version 1.0.3d [September 4, 1999] + Fixed type casting of igamma in pngrutil.c + Added new png_expand functions to scripts/pngdef.pas and pngos2.def + Added a demo read_user_transform_fn that examines the row filters in pngtest.c + +version 1.0.4 [September 24, 1999] + Define PNG_ALWAYS_EXTERN in pngconf.h if __STDC__ is defined + Delete #define PNG_INTERNAL and include "png.h" from pngasmrd.h + Made several minor corrections to pngtest.c + Renamed the makefiles with longer but more user friendly extensions. + Copied the PNG copyright and license to a separate LICENSE file. + Revised documentation, png.h, and example.c to remove reference to + "viewing_gamma" which no longer appears in the PNG specification. + Revised pngvcrd.c to use MMX code for interlacing only on the final pass. + Updated pngvcrd.c to use the faster C filter algorithms from libpng-1.0.1a + Split makefile.win32vc into two versions, makefile.vcawin32 (uses MMX + assembler code) and makefile.vcwin32 (doesn't). + Added a CPU timing report to pngtest.c (enabled by defining PNGTEST_TIMING) + Added a copy of pngnow.png to the distribution. +version 1.0.4a [September 25, 1999] + Increase max_pixel_depth in pngrutil.c if a user transform needs it. + Changed several division operations to right-shifts in pngvcrd.c +version 1.0.4b [September 30, 1999] + Added parentheses in line 3732 of pngvcrd.c + Added a comment in makefile.linux warning about buggy -O3 in pgcc 2.95.1 +version 1.0.4c [October 1, 1999] + Added a "png_check_version" function in png.c and pngtest.c that will generate + a helpful compiler error if an old png.h is found in the search path. + Changed type of png_user_transform_depth|channels from int to png_byte. +version 1.0.4d [October 6, 1999] + Changed 0.45 to 0.45455 in png_set_sRGB() + Removed unused PLTE entries from pngnow.png + Re-enabled some parts of pngvcrd.c (png_combine_row) that work properly. +version 1.0.4e [October 10, 1999] + Fixed sign error in pngvcrd.c (Greg Roelofs) + Replaced some instances of memcpy with simple assignments in pngvcrd (GR-P) +version 1.0.4f [October 15, 1999] + Surrounded example.c code with #if 0 .. #endif to prevent people from + inadvertently trying to compile it. + Changed png_get_header_version() from a function to a macro in png.h + Added type casting mostly in pngrtran.c and pngwtran.c + Removed some pointless "ptr = NULL" in pngmem.c + Added a "contrib" directory containing the source code from Greg's book. + +version 1.0.5 [October 15, 1999] + Minor editing of the INSTALL and README files. +version 1.0.5a [October 23, 1999] + Added contrib/pngsuite and contrib/pngminus (Willem van Schaik) + Fixed a typo in the png_set_sRGB() function call in example.c (Jan Nijtmans) + Further optimization and bugfix of pngvcrd.c + Revised pngset.c so that it does not allocate or free memory in the user's + text_ptr structure. Instead, it makes its own copy. + Created separate write_end_info_struct in pngtest.c for a more severe test. + Added code in pngwrite.c to free info_ptr->text[i].key to stop a memory leak. +version 1.0.5b [November 23, 1999] + Moved PNG_FLAG_HAVE_CHUNK_HEADER, PNG_FLAG_BACKGROUND_IS_GRAY and + PNG_FLAG_WROTE_tIME from flags to mode. + Added png_write_info_before_PLTE() function. + Fixed some typecasting in contrib/gregbook/*.c + Updated scripts/makevms.com and added makevms.com to contrib/gregbook + and contrib/pngminus (Martin Zinser) +version 1.0.5c [November 26, 1999] + Moved png_get_header_version from png.h to png.c, to accommodate ansi2knr. + Removed all global arrays (according to PNG_NO_GLOBAL_ARRAYS macro), to + accommodate making DLL's: Moved usr_png_ver from global variable to function + png_get_header_ver() in png.c. Moved png_sig to png_sig_bytes in png.c and + eliminated use of png_sig in pngwutil.c. Moved the various png_CHNK arrays + into pngtypes.h. Eliminated use of global png_pass arrays. Declared the + png_CHNK and png_pass arrays to be "const". Made the global arrays + available to applications (although none are used in libpng itself) when + PNG_NO_GLOBAL_ARRAYS is not defined or when PNG_GLOBAL_ARRAYS is defined. + Removed some extraneous "-I" from contrib/pngminus/makefile.std + Changed the PNG_sRGB_INTENT macros in png.h to be consistent with PNG-1.2. + Change PNG_SRGB_INTENT to PNG_sRGB_INTENT in libpng.txt and libpng.3 +version 1.0.5d [November 29, 1999] + Add type cast (png_const_charp) two places in png.c + Eliminated pngtypes.h; use macros instead to declare PNG_CHNK arrays. + Renamed "PNG_GLOBAL_ARRAYS" to "PNG_USE_GLOBAL_ARRAYS" and made available + to applications a macro "PNG_USE_LOCAL_ARRAYS". + #ifdef out all the new declarations when PNG_USE_GLOBAL_ARRAYS is defined. + Added PNG_EXPORT_VAR macro to accommodate making DLL's. +version 1.0.5e [November 30, 1999] + Added iCCP, iTXt, and sPLT support; added "lang" member to the png_text + structure; refactored the inflate/deflate support to make adding new chunks + with trailing compressed parts easier in the future, and added new functions + png_free_iCCP, png_free_pCAL, png_free_sPLT, png_free_text, png_get_iCCP, + png_get_spalettes, png_set_iCCP, png_set_spalettes (Eric S. Raymond). + NOTE: Applications that write text chunks MUST define png_text->lang + before calling png_set_text(). It must be set to NULL if you want to + write tEXt or zTXt chunks. If you want your application to be able to + run with older versions of libpng, use + + #ifdef PNG_iTXt_SUPPORTED + png_text[i].lang = NULL; + #endif + + Changed png_get_oFFs() and png_set_oFFs() to use signed rather than unsigned + offsets (Eric S. Raymond). + Combined PNG_READ_cHNK_SUPPORTED and PNG_WRITE_cHNK_SUPPORTED macros into + PNG_cHNK_SUPPORTED and combined the three types of PNG_text_SUPPORTED + macros, leaving the separate macros also available. + Removed comments on #endifs at the end of many short, non-nested #if-blocks. +version 1.0.5f [December 6, 1999] + Changed makefile.solaris to issue a warning about potential problems when + the ucb "ld" is in the path ahead of the ccs "ld". + Removed "- [date]" from the "synopsis" line in libpng.3 and libpngpf.3. + Added sCAL chunk support (Eric S. Raymond). +version 1.0.5g [December 7, 1999] + Fixed "png_free_spallettes" typo in png.h + Added code to handle new chunks in pngpread.c + Moved PNG_CHNK string macro definitions outside of PNG_NO_EXTERN block + Added "translated_key" to png_text structure and png_write_iTXt(). + Added code in pngwrite.c to work around a newly discovered zlib bug. +version 1.0.5h [December 10, 1999] + NOTE: regarding the note for version 1.0.5e, the following must also + be included in your code: + png_text[i].translated_key = NULL; + Unknown chunk handling is now supported. + Option to eliminate all floating point support was added. Some new + fixed-point functions such as png_set_gAMA_fixed() were added. + Expanded tabs and removed trailing blanks in source files. +version 1.0.5i [December 13, 1999] + Added some type casts to silence compiler warnings. + Renamed "png_free_spalette" to "png_free_spalettes" for consistency. + Removed leading blanks from a #define in pngvcrd.c + Added some parameters to the new png_set_keep_unknown_chunks() function. + Added a test for up->location != 0 in the first instance of writing + unknown chunks in pngwrite.c + Changed "num" to "i" in png_free_spalettes() and png_free_unknowns() to + prevent recursion. + Added png_free_hIST() function. + Various patches to fix bugs in the sCAL and integer cHRM processing, + and to add some convenience macros for use with sCAL. +version 1.0.5j [December 21, 1999] + Changed "unit" parameter of png_write_sCAL from png_byte to int, to work + around buggy compilers. + Added new type "png_fixed_point" for integers that hold float*100000 values + Restored backward compatibility of tEXt/zTXt chunk processing: + Restored the first four members of png_text to the same order as v.1.0.5d. + Added members "lang_key" and "itxt_length" to png_text struct. Set + text_length=0 when "text" contains iTXt data. Use the "compression" + member to distinguish among tEXt/zTXt/iTXt types. Added + PNG_ITXT_COMPRESSION_NONE (1) and PNG_ITXT_COMPRESSION_zTXt(2) macros. + The "Note" above, about backward incompatibility of libpng-1.0.5e, no + longer applies. + Fixed png_read|write_iTXt() to read|write parameters in the right order, + and to write the iTXt chunk after IDAT if it appears in the end_ptr. + Added pnggccrd.c, version of pngvcrd.c Intel assembler for gcc (Greg Roelofs) + Reversed the order of trying to write floating-point and fixed-point gAMA. +version 1.0.5k [December 27, 1999] + Added many parentheses, e.g., "if (a && b & c)" becomes "if (a && (b & c))" + Added png_handle_as_unknown() function (Glenn) + Added png_free_chunk_list() function and chunk_list and num_chunk_list members + of png_ptr. + Eliminated erroneous warnings about multiple sPLT chunks and sPLT-after-PLTE. + Fixed a libpng-1.0.5h bug in pngrutil.c that was issuing erroneous warnings + about ignoring incorrect gAMA with sRGB (gAMA was in fact not ignored) + Added png_free_tRNS(); png_set_tRNS() now malloc's its own trans array (ESR). + Define png_get_int_32 when oFFs chunk is supported as well as when pCAL is. + Changed type of proflen from png_int_32 to png_uint_32 in png_get_iCCP(). +version 1.0.5l [January 1, 2000] + Added functions png_set_read_user_chunk_fn() and png_get_user_chunk_ptr() + for setting a callback function to handle unknown chunks and for + retrieving the associated user pointer (Glenn). +version 1.0.5m [January 7, 2000] + Added high-level functions png_read_png(), png_write_png(), png_free_pixels(). +version 1.0.5n [January 9, 2000] + Added png_free_PLTE() function, and modified png_set_PLTE() to malloc its + own memory for info_ptr->palette. This makes it safe for the calling + application to free its copy of the palette any time after it calls + png_set_PLTE(). +version 1.0.5o [January 20, 2000] + Cosmetic changes only (removed some trailing blanks and TABs) +version 1.0.5p [January 31, 2000] + Renamed pngdll.mak to makefile.bd32 + Cosmetic changes in pngtest.c +version 1.0.5q [February 5, 2000] + Relocated the makefile.solaris warning about PATH problems. + Fixed pngvcrd.c bug by pushing/popping registers in mmxsupport (Bruce Oberg) + Revised makefile.gcmmx + Added PNG_SETJMP_SUPPORTED, PNG_SETJMP_NOT_SUPPORTED, and PNG_ABORT() macros +version 1.0.5r [February 7, 2000] + Removed superfluous prototype for png_get_itxt from png.h + Fixed a bug in pngrtran.c that improperly expanded the background color. + Return *num_text=0 from png_get_text() when appropriate, and fix documentation + of png_get_text() in libpng.txt/libpng.3. +version 1.0.5s [February 18, 2000] + Added "png_jmp_env()" macro to pngconf.h, to help people migrate to the + new error handler that's planned for the next libpng release, and changed + example.c, pngtest.c, and contrib programs to use this macro. + Revised some of the DLL-export macros in pngconf.h (Greg Roelofs) + Fixed a bug in png_read_png() that caused it to fail to expand some images + that it should have expanded. + Fixed some mistakes in the unused and undocumented INCH_CONVERSIONS functions + in pngget.c + Changed the allocation of palette, history, and trans arrays back to + the version 1.0.5 method (linking instead of copying) which restores + backward compatibility with version 1.0.5. Added some remarks about + that in example.c. Added "free_me" member to info_ptr and png_ptr + and added png_free_data() function. + Updated makefile.linux and makefile.gccmmx to make directories conditionally. + Made cosmetic changes to pngasmrd.h + Added png_set_rows() and png_get_rows(), for use with png_read|write_png(). + Modified png_read_png() to allocate info_ptr->row_pointers only if it + hasn't already been allocated. +version 1.0.5t [March 4, 2000] + Changed png_jmp_env() migration aiding macro to png_jmpbuf(). + Fixed "interlace" typo (should be "interlaced") in contrib/gregbook/read2-x.c + Fixed bug with use of PNG_BEFORE_IHDR bit in png_ptr->mode, introduced when + PNG_FLAG_HAVE_CHUNK_HEADER was moved into png_ptr->mode in version 1.0.5b + Files in contrib/gregbook were revised to use png_jmpbuf() and to select + a 24-bit visual if one is available, and to allow abbreviated options. + Files in contrib/pngminus were revised to use the png_jmpbuf() macro. + Removed spaces in makefile.linux and makefile.gcmmx, introduced in 1.0.5s +version 1.0.5u [March 5, 2000] + Simplified the code that detects old png.h in png.c and pngtest.c + Renamed png_spalette (_p, _pp) to png_sPLT_t (_tp, _tpp) + Increased precision of rgb_to_gray calculations from 8 to 15 bits and + added png_set_rgb_to_gray_fixed() function. + Added makefile.bc32 (32-bit Borland C++, C mode) +version 1.0.5v [March 11, 2000] + Added some parentheses to the png_jmpbuf macro definition. + Updated references to the zlib home page, which has moved to freesoftware.com. + Corrected bugs in documentation regarding png_read_row() and png_write_row(). + Updated documentation of png_rgb_to_gray calculations in libpng.3/libpng.txt. + Renamed makefile.borland,turboc3 back to makefile.bor,tc3 as in version 1.0.3, + revised borland makefiles; added makefile.ibmvac3 and makefile.gcc (Cosmin) + +version 1.0.6 [March 20, 2000] + Minor revisions of makefile.bor, libpng.txt, and gregbook/rpng2-win.c + Added makefile.sggcc (SGI IRIX with gcc) +version 1.0.6d [April 7, 2000] + Changed sprintf() to strcpy() in png_write_sCAL_s() to work without STDIO + Added data_length parameter to png_decompress_chunk() function + Revised documentation to remove reference to abandoned png_free_chnk functions + Fixed an error in png_rgb_to_gray_fixed() + Revised example.c, usage of png_destroy_write_struct(). + Renamed makefile.ibmvac3 to makefile.ibmc, added libpng.icc IBM project file + Added a check for info_ptr->free_me&PNG_FREE_TEXT when freeing text in png.c + Simplify png_sig_bytes() function to remove use of non-ISO-C strdup(). +version 1.0.6e [April 9, 2000] + Added png_data_freer() function. + In the code that checks for over-length tRNS chunks, added check of + info_ptr->num_trans as well as png_ptr->num_trans (Matthias Benckmann) + Minor revisions of libpng.txt/libpng.3. + Check for existing data and free it if the free_me flag is set, in png_set_*() + and png_handle_*(). + Only define PNG_WEIGHTED_FILTERS_SUPPORTED when PNG_FLOATING_POINT_SUPPORTED + is defined. + Changed several instances of PNG_NO_CONSOLE_ID to PNG_NO_STDIO in pngrutil.c + and mentioned the purposes of the two macros in libpng.txt/libpng.3. +version 1.0.6f [April 14, 2000] + Revised png_set_iCCP() and png_set_rows() to avoid prematurely freeing data. + Add checks in png_set_text() for NULL members of the input text structure. + Revised libpng.txt/libpng.3. + Removed superfluous prototype for png_set_itxt from png.h + Removed "else" from pngread.c, after png_error(), and changed "0" to "length". + Changed several png_errors about malformed ancillary chunks to png_warnings. +version 1.0.6g [April 24, 2000] + Added png_pass-* arrays to pnggccrd.c when PNG_USE_LOCAL_ARRAYS is defined. + Relocated paragraph about png_set_background() in libpng.3/libpng.txt + and other revisions (Matthias Benckmann) + Relocated info_ptr->free_me, png_ptr->free_me, and other info_ptr and + png_ptr members to restore binary compatibility with libpng-1.0.5 + (breaks compatibility with libpng-1.0.6). +version 1.0.6h [April 24, 2000] + Changed shared library so-number pattern from 2.x.y.z to xy.z (this builds + libpng.so.10 & libpng.so.10.6h instead of libpng.so.2 & libpng.so.2.1.0.6h) + This is a temporary change for test purposes. +version 1.0.6i [May 2, 2000] + Rearranged some members at the end of png_info and png_struct, to put + unknown_chunks_num and free_me within the original size of the png_structs + and free_me, png_read_user_fn, and png_free_fn within the original png_info, + because some old applications allocate the structs directly instead of + using png_create_*(). + Added documentation of user memory functions in libpng.txt/libpng.3 + Modified png_read_png so that it will use user_allocated row_pointers + if present, unless free_me directs that it be freed, and added description + of the use of png_set_rows() and png_get_rows() in libpng.txt/libpng.3. + Added PNG_LEGACY_SUPPORTED macro, and #ifdef out all new (since version + 1.00) members of png_struct and png_info, to regain binary compatibility + when you define this macro. Capabilities lost in this event + are user transforms (new in version 1.0.0),the user transform pointer + (new in version 1.0.2), rgb_to_gray (new in 1.0.5), iCCP, sCAL, sPLT, + the high-level interface, and unknown chunks support (all new in 1.0.6). + This was necessary because of old applications that allocate the structs + directly as authors were instructed to do in libpng-0.88 and earlier, + instead of using png_create_*(). + Added modes PNG_CREATED_READ_STRUCT and PNG_CREATED_WRITE_STRUCT which + can be used to detect codes that directly allocate the structs, and + code to check these modes in png_read_init() and png_write_init() and + generate a libpng error if the modes aren't set and PNG_LEGACY_SUPPORTED + was not defined. + Added makefile.intel and updated makefile.watcom (Pawel Mrochen) +version 1.0.6j [May 3, 2000] + Overloaded png_read_init() and png_write_init() with macros that convert + calls to png_read_init_2() or png_write_init_2() that check the version + and structure sizes. +version 1.0.7beta11 [May 7, 2000] + Removed the new PNG_CREATED_READ_STRUCT and PNG_CREATED_WRITE_STRUCT modes + which are no longer used. + Eliminated the three new members of png_text when PNG_LEGACY_SUPPORTED is + defined or when neither PNG_READ_iTXt_SUPPORTED nor PNG_WRITE_iTXT_SUPPORTED + is defined. + Made PNG_NO_READ|WRITE_iTXt the default setting, to avoid memory + overrun when old applications fill the info_ptr->text structure directly. + Added PNGAPI macro, and added it to the definitions of all exported functions. + Relocated version macro definitions ahead of the includes of zlib.h and + pngconf.h in png.h. +version 1.0.7beta12 [May 12, 2000] + Revised pngset.c to avoid a problem with expanding the png_debug macro. + Deleted some extraneous defines from pngconf.h + Made PNG_NO_CONSOLE_IO the default condition when PNG_BUILD_DLL is defined. + Use MSC _RPTn debugging instead of fprintf if _MSC_VER is defined. + Added png_access_version_number() function. + Check for mask&PNG_FREE_CHNK (for TEXT, SCAL, PCAL) in png_free_data(). + Expanded libpng.3/libpng.txt information about png_data_freer(). +version 1.0.7beta14 [May 17, 2000] (beta13 was not published) + Changed pnggccrd.c and pngvcrd.c to handle bad adaptive filter types as + warnings instead of errors, as pngrutil.c does. + Set the PNG_INFO_IDAT valid flag in png_set_rows() so png_write_png() + will actually write IDATs. + Made the default PNG_USE_LOCAL_ARRAYS depend on PNG_DLL instead of WIN32. + Make png_free_data() ignore its final parameter except when freeing data + that can have multiple instances (text, sPLT, unknowns). + Fixed a new bug in png_set_rows(). + Removed info_ptr->valid tests from png_free_data(), as in version 1.0.5. + Added png_set_invalid() function. + Fixed incorrect illustrations of png_destroy_write_struct() in example.c. +version 1.0.7beta15 [May 30, 2000] + Revised the deliberately erroneous Linux setjmp code in pngconf.h to produce + fewer error messages. + Rearranged checks for Z_OK to check the most likely path first in pngpread.c + and pngwutil.c. + Added checks in pngtest.c for png_create_*() returning NULL, and mentioned + in libpng.txt/libpng.3 the need for applications to check this. + Changed names of png_default_*() functions in pngtest to pngtest_*(). + Changed return type of png_get_x|y_offset_*() from png_uint_32 to png_int_32. + Fixed some bugs in the unused PNG_INCH_CONVERSIONS functions in pngget.c + Set each pointer to NULL after freeing it in png_free_data(). + Worked around a problem in pngconf.h; AIX's strings.h defines an "index" + macro that conflicts with libpng's png_color_16.index. (Dimitri Papadapoulos) + Added "msvc" directory with MSVC++ project files (Simon-Pierre Cadieux). +version 1.0.7beta16 [June 4, 2000] + Revised the workaround of AIX string.h "index" bug. + Added a check for overlength PLTE chunk in pngrutil.c. + Added PNG_NO_POINTER_INDEXING macro to use array-indexing instead of pointer + indexing in pngrutil.c and pngwutil.c to accommodate a buggy compiler. + Added a warning in png_decompress_chunk() when it runs out of data, e.g. + when it tries to read an erroneous PhotoShop iCCP chunk. + Added PNG_USE_DLL macro. + Revised the copyright/disclaimer/license notice. + Added contrib/msvctest directory +version 1.0.7rc1 [June 9, 2000] + Corrected the definition of PNG_TRANSFORM_INVERT_ALPHA (0x0400 not 0x0200) + Added contrib/visupng directory (Willem van Schaik) +version 1.0.7beta18 [June 23, 2000] + Revised PNGAPI definition, and pngvcrd.c to work with __GCC__ + and do not redefine PNGAPI if it is passed in via a compiler directive. + Revised visupng/PngFile.c to remove returns from within the Try block. + Removed leading underscores from "_PNG_H" and "_PNG_SAVE_BSD_SOURCE" macros. + Updated contrib/visupng/cexcept.h to version 1.0.0. + Fixed bugs in pngwrite.c and pngwutil.c that prevented writing iCCP chunks. +version 1.0.7rc2 [June 28, 2000] + Updated license to include disclaimers required by UCITA. + Fixed "DJBPP" typo in pnggccrd.c introduced in beta18. + +version 1.0.7 [July 1, 2000] + Revised the definition of "trans_values" in libpng.3/libpng.txt +version 1.0.8beta1 [July 8, 2000] + Added png_free(png_ptr, key) two places in pngpread.c to stop memory leaks. + Changed PNG_NO_STDIO to PNG_NO_CONSOLE_IO, several places in pngrutil.c and + pngwutil.c. + Changed PNG_EXPORT_VAR to use PNG_IMPEXP, in pngconf.h. + Removed unused "#include <assert.h>" from png.c + Added WindowsCE support. + Revised pnggccrd.c to work with gcc-2.95.2 and in the Cygwin environment. +version 1.0.8beta2 [July 10, 2000] + Added project files to the wince directory and made further revisions + of pngtest.c, pngrio.c, and pngwio.c in support of WindowsCE. +version 1.0.8beta3 [July 11, 2000] + Only set the PNG_FLAG_FREE_TRNS or PNG_FREE_TRNS flag in png_handle_tRNS() + for indexed-color input files to avoid potential double-freeing trans array + under some unusual conditions; problem was introduced in version 1.0.6f. + Further revisions to pngtest.c and files in the wince subdirectory. +version 1.0.8beta4 [July 14, 2000] + Added the files pngbar.png and pngbar.jpg to the distribution. + Added makefile.cygwin, and cygwin support in pngconf.h + Added PNG_NO_ZALLOC_ZERO macro (makes png_zalloc skip zeroing memory) +version 1.0.8rc1 [July 16, 2000] + Revised png_debug() macros and statements to eliminate compiler warnings. + +version 1.0.8 [July 24, 2000] + Added png_flush() in pngwrite.c, after png_write_IEND(). + Updated makefile.hpux to build a shared library. +version 1.0.9beta1 [November 10, 2000] + Fixed typo in scripts/makefile.hpux + Updated makevms.com in scripts and contrib/* and contrib/* (Martin Zinser) + Fixed seqence-point bug in contrib/pngminus/png2pnm (Martin Zinser) + Changed "cdrom.com" in documentation to "libpng.org" + Revised pnggccrd.c to get it all working, and updated makefile.gcmmx (Greg). + Changed type of "params" from voidp to png_voidp in png_read|write_png(). + Make sure PNGAPI and PNG_IMPEXP are defined in pngconf.h. + Revised the 3 instances of WRITEFILE in pngtest.c. + Relocated "msvc" and "wince" project subdirectories into "dll" subdirectory. + Updated png.rc in dll/msvc project + Revised makefile.dec to define and use LIBPATH and INCPATH + Increased size of global png_libpng_ver[] array from 12 to 18 chars. + Made global png_libpng_ver[], png_sig[] and png_pass_*[] arrays const. + Removed duplicate png_crc_finish() from png_handle_bKGD() function. + Added a warning when application calls png_read_update_info() multiple times. + Revised makefile.cygwin + Fixed bugs in iCCP support in pngrutil.c and pngwutil.c. + Replaced png_set_empty_plte_permitted() with png_permit_mng_features(). +version 1.0.9beta2 [November 19, 2000] + Renamed the "dll" subdirectory "projects". + Added borland project files to "projects" subdirectory. + Set VS_FF_PRERELEASE and VS_FF_PATCHED flags in msvc/png.rc when appropriate. + Add error message in png_set_compression_buffer_size() when malloc fails. +version 1.0.9beta3 [November 23, 2000] + Revised PNG_LIBPNG_BUILD_TYPE macro in png.h, used in the msvc project. + Removed the png_flush() in pngwrite.c that crashes some applications + that don't set png_output_flush_fn. + Added makefile.macosx and makefile.aix to scripts directory. +version 1.0.9beta4 [December 1, 2000] + Change png_chunk_warning to png_warning in png_check_keyword(). + Increased the first part of msg buffer from 16 to 18 in png_chunk_error(). +version 1.0.9beta5 [December 15, 2000] + Added support for filter method 64 (for PNG datastreams embedded in MNG). +version 1.0.9beta6 [December 18, 2000] + Revised png_set_filter() to accept filter method 64 when appropriate. + Added new PNG_HAVE_PNG_SIGNATURE bit to png_ptr->mode and use it to + help prevent applications from using MNG features in PNG datastreams. + Added png_permit_mng_features() function. + Revised libpng.3/libpng.txt. Changed "filter type" to "filter method". +version 1.0.9rc1 [December 23, 2000] + Revised test for PNG_HAVE_PNG_SIGNATURE in pngrutil.c + Fixed error handling of unknown compression type in png_decompress_chunk(). + In pngconf.h, define __cdecl when _MSC_VER is defined. +version 1.0.9beta7 [December 28, 2000] + Changed PNG_TEXT_COMPRESSION_zTXt to PNG_COMPRESSION_TYPE_BASE several places. + Revised memory management in png_set_hIST and png_handle_hIST in a backward + compatible manner. PLTE and tRNS were revised similarly. + Revised the iCCP chunk reader to ignore trailing garbage. +version 1.0.9beta8 [January 12, 2001] + Moved pngasmrd.h into pngconf.h. + Improved handling of out-of-spec garbage iCCP chunks generated by PhotoShop. +version 1.0.9beta9 [January 15, 2001] + Added png_set_invalid, png_permit_mng_features, and png_mmx_supported to + wince and msvc project module definition files. + Minor revision of makefile.cygwin. + Fixed bug with progressive reading of narrow interlaced images in pngpread.c +version 1.0.9beta10 [January 16, 2001] + Do not typedef png_FILE_p in pngconf.h when PNG_NO_STDIO is defined. + Fixed "png_mmx_supported" typo in project definition files. +version 1.0.9beta11 [January 19, 2001] + Updated makefile.sgi to make shared library. + Removed png_mmx_support() function and disabled PNG_MNG_FEATURES_SUPPORTED + by default, for the benefit of DLL forward compatibility. These will + be re-enabled in version 1.2.0. +version 1.0.9rc2 [January 22, 2001] + Revised cygwin support. + +version 1.0.9 [January 31, 2001] + Added check of cygwin's ALL_STATIC in pngconf.h + Added "-nommx" parameter to contrib/gregbook/rpng2-win and rpng2-x demos. +version 1.0.10beta1 [March 14, 2001] + Revised makefile.dec, makefile.sgi, and makefile.sggcc; added makefile.hpgcc. + Reformatted libpng.3 to eliminate bad line breaks. + Added checks for _mmx_supported in the read_filter_row function of pnggccrd.c + Added prototype for png_mmx_support() near the top of pnggccrd.c + Moved some error checking from png_handle_IHDR to png_set_IHDR. + Added PNG_NO_READ_SUPPORTED and PNG_NO_WRITE_SUPPORTED macros. + Revised png_mmx_support() function in pnggccrd.c + Restored version 1.0.8 PNG_WRITE_EMPTY_PLTE_SUPPORTED behavior in pngwutil.c + Fixed memory leak in contrib/visupng/PngFile.c + Fixed bugs in png_combine_row() in pnggccrd.c and pngvcrd.c (C version) + Added warnings when retrieving or setting gamma=0. + Increased the first part of msg buffer from 16 to 18 in png_chunk_warning(). +version 1.0.10rc1 [March 23, 2001] + Changed all instances of memcpy, strcpy, and strlen to png_memcpy, png_strcpy, + and png_strlen. + Revised png_mmx_supported() function in pnggccrd.c to return proper value. + Fixed bug in progressive reading (pngpread.c) with small images (height < 8). + +version 1.0.10 [March 30, 2001] + Deleted extraneous space (introduced in 1.0.9) from line 42 of makefile.cygwin + Added beos project files (Chris Herborth) +version 1.0.11beta1 [April 3, 2001] + Added type casts on several png_malloc() calls (Dimitri Papadapoulos). + Removed a no-longer needed AIX work-around from pngconf.h + Changed several "//" single-line comments to C-style in pnggccrd.c +version 1.0.11beta2 [April 11, 2001] + Removed PNGAPI from several functions whose prototypes did not have PNGAPI. + Updated scripts/pngos2.def +version 1.0.11beta3 [April 14, 2001] + Added checking the results of many instances of png_malloc() for NULL +version 1.0.11beta4 [April 20, 2001] + Undid the changes from version 1.0.11beta3. Added a check for NULL return + from user's malloc_fn(). + Removed some useless type casts of the NULL pointer. + Added makefile.netbsd + +version 1.0.11 [April 27, 2001] + Revised makefile.netbsd +version 1.0.12beta1 [May 14, 2001] + Test for Windows platform in pngconf.h when including malloc.h (Emmanuel Blot) + Updated makefile.cygwin and handling of Cygwin's ALL_STATIC in pngconf.h + Added some never-to-be-executed code in pnggccrd.c to quiet compiler warnings. + Eliminated the png_error about apps using png_read|write_init(). Instead, + libpng will reallocate the png_struct and info_struct if they are too small. + This retains future binary compatibility for old applications written for + libpng-0.88 and earlier. +version 1.2.0beta1 [May 6, 2001] + Bumped DLLNUM to 2. + Re-enabled PNG_MNG_FEATURES_SUPPORTED and enabled PNG_ASSEMBLER_CODE_SUPPORTED + by default. + Added runtime selection of MMX features. + Added png_set_strip_error_numbers function and related macros. +version 1.2.0beta2 [May 7, 2001] + Finished merging 1.2.0beta1 with version 1.0.11 + Added a check for attempts to read or write PLTE in grayscale PNG datastreams. +version 1.2.0beta3 [May 17, 2001] + Enabled user memory function by default. + Modified png_create_struct so it passes user mem_ptr to user memory allocator. + Increased png_mng_features flag from png_byte to png_uint_32. + Bumped shared-library (so-number) and dll-number to 3. +version 1.2.0beta4 [June 23, 2001] + Check for missing profile length field in iCCP chunk and free chunk_data + in case of truncated iCCP chunk. + Bumped shared-library number to 3 in makefile.sgi and makefile.sggcc + Bumped dll-number from 2 to 3 in makefile.cygwin + Revised contrib/gregbook/rpng*-x.c to avoid a memory leak and to exit cleanly + if user attempts to run it on an 8-bit display. + Updated contrib/gregbook + Use png_malloc instead of png_zalloc to allocate palette in pngset.c + Updated makefile.ibmc + Added some typecasts to eliminate gcc 3.0 warnings. Changed prototypes + of png_write_oFFS width and height from png_uint_32 to png_int_32. + Updated example.c + Revised prototypes for png_debug_malloc and png_debug_free in pngtest.c +version 1.2.0beta5 [August 8, 2001] + Revised contrib/gregbook + Revised makefile.gcmmx + Revised pnggccrd.c to conditionally compile some thread-unsafe code only + when PNG_THREAD_UNSAFE_OK is defined. + Added tests to prevent pngwutil.c from writing a bKGD or tRNS chunk with + value exceeding 2^bit_depth-1 + Revised makefile.sgi and makefile.sggcc + Replaced calls to fprintf(stderr,...) with png_warning() in pnggccrd.c + Removed restriction that do_invert_mono only operate on 1-bit opaque files + +version 1.2.0 [September 1, 2001] + Changed a png_warning() to png_debug() in pnggccrd.c + Fixed contrib/gregbook/rpng-x.c, rpng2-x.c to avoid crash with XFreeGC(). +version 1.2.1beta1 [October 19, 2001] + Revised makefile.std in contrib/pngminus + Include background_1 in png_struct regardless of gamma support. + Revised makefile.netbsd and makefile.macosx, added makefile.darwin. + Revised example.c to provide more details about using row_callback(). +version 1.2.1beta2 [October 25, 2001] + Added type cast to each NULL appearing in a function call, except for + WINCE functions. + Added makefile.so9. +version 1.2.1beta3 [October 27, 2001] + Removed type casts from all NULLs. + Simplified png_create_struct_2(). +version 1.2.1beta4 [November 7, 2001] + Revised png_create_info_struct() and png_creat_struct_2(). + Added error message if png_write_info() was omitted. + Type cast NULLs appearing in function calls when _NO_PROTO or + PNG_TYPECAST_NULL is defined. +version 1.2.1rc1 [November 24, 2001] + Type cast NULLs appearing in function calls except when PNG_NO_TYPECAST_NULL + is defined. + Changed typecast of "size" argument to png_size_t in pngmem.c calls to + the user malloc_fn, to agree with the prototype in png.h + Added a pop/push operation to pnggccrd.c, to preserve Eflag (Maxim Sobolev) + Updated makefile.sgi to recognize LIBPATH and INCPATH. + Updated various makefiles so "make clean" does not remove previous major + version of the shared library. +version 1.2.1rc2 [December 4, 2001] + Always allocate 256-entry internal palette, hist, and trans arrays, to + avoid out-of-bounds memory reference caused by invalid PNG datastreams. + Added a check for prefix_length > data_length in iCCP chunk handler. + +version 1.2.1 [December 7, 2001] + None. +version 1.2.2beta1 [February 22, 2002] + Fixed a bug with reading the length of iCCP profiles (Larry Reeves). + Revised makefile.linux, makefile.gcmmx, and makefile.sgi to generate + libpng.a, libpng12.so (not libpng.so.3), and libpng12/png.h + Revised makefile.darwin to remove "-undefined suppress" option. + Added checks for gamma and chromaticity values over 21474.83, which exceed + the limit for PNG unsigned 32-bit integers when encoded. + Revised calls to png_create_read_struct() and png_create_write_struct() + for simpler debugging. + Revised png_zalloc() so zlib handles errors (uses PNG_FLAG_MALLOC_NULL_MEM_OK) +version 1.2.2beta2 [February 23, 2002] + Check chunk_length and idat_size for invalid (over PNG_MAX_UINT) lengths. + Check for invalid image dimensions in png_get_IHDR. + Added missing "fi;" in the install target of the SGI makefiles. + Added install-static to all makefiles that make shared libraries. + Always do gamma compensation when image is partially transparent. +version 1.2.2beta3 [March 7, 2002] + Compute background.gray and background_1.gray even when color_type is RGB + in case image gets reduced to gray later. + Modified shared-library makefiles to install pkgconfig/libpngNN.pc. + Export (with PNGAPI) png_zalloc, png_zfree, and png_handle_as_unknown + Removed unused png_write_destroy_info prototype from png.h + Eliminated incorrect use of width_mmx from pnggccrd.c in pixel_bytes == 8 case + Added install-shared target to all makefiles that make shared libraries. + Stopped a double free of palette, hist, and trans when not using free_me. + Added makefile.32sunu for Sun Ultra 32 and makefile.64sunu for Sun Ultra 64. +version 1.2.2beta4 [March 8, 2002] + Compute background.gray and background_1.gray even when color_type is RGB + in case image gets reduced to gray later (Jason Summers). + Relocated a misplaced /bin/rm in the "install-shared" makefile targets + Added PNG_1_0_X macro which can be used to build a 1.0.x-compatible library. +version 1.2.2beta5 [March 26, 2002] + Added missing PNGAPI to several function definitions. + Check for invalid bit_depth or color_type in png_get_IHDR(), and + check for missing PLTE or IHDR in png_push_read_chunk() (Matthias Clasen). + Revised iTXt support to accept NULL for lang and lang_key. + Compute gamma for color components of background even when color_type is gray. + Changed "()" to "{}" in scripts/libpng.pc.in. + Revised makefiles to put png.h and pngconf.h only in $prefix/include/libpngNN + Revised makefiles to make symlink to libpng.so.NN in addition to libpngNN.so +version 1.2.2beta6 [March 31, 2002] +version 1.0.13beta1 [March 31, 2002] + Prevent png_zalloc() from trying to memset memory that it failed to acquire. + Add typecasts of PNG_MAX_UINT in pngset_cHRM_fixed() (Matt Holgate). + Ensure that the right function (user or default) is used to free the + png_struct after an error in png_create_read_struct_2(). +version 1.2.2rc1 [April 7, 2002] +version 1.0.13rc1 [April 7, 2002] + Save the ebx register in pnggccrd.c (Sami Farin) + Add "mem_ptr = png_ptr->mem_ptr" in png_destroy_write_struct() (Paul Gardner). + Updated makefiles to put headers in include/libpng and remove old include/*.h. + +version 1.2.2 [April 15, 2002] +version 1.0.13 [April 15, 2002] + Revised description of png_set_filter() in libpng.3/libpng.txt. + Revised makefile.netbsd and added makefile.neNNbsd and makefile.freebsd +version 1.0.13patch01 [April 17, 2002] +version 1.2.2patch01 [April 17, 2002] + Changed ${PNGMAJ}.${PNGVER} bug to ${PNGVER} in makefile.sgi and makefile.sggcc + Fixed VER -> PNGVER typo in makefile.macosx and added install-static to install + Added install: target to makefile.32sunu and makefile.64sunu +version 1.0.13patch03 [April 18, 2002] +version 1.2.2patch03 [April 18, 2002] + Revised 15 makefiles to link libpng.a to libpngNN.a and the include libpng + subdirectory to libpngNN subdirectory without the full pathname. + Moved generation of libpng.pc from "install" to "all" in 15 makefiles. +version 1.2.3rc1 [April 28, 2002] + Added install-man target to 15 makefiles (Dimitri Papadopolous-Orfanos). + Added $(DESTDIR) feature to 24 makefiles (Tim Mooney) + Fixed bug with $prefix, should be $(prefix) in makefile.hpux. + Updated cygwin-specific portion of pngconf.h and revised makefile.cygwin + Added a link from libpngNN.pc to libpng.pc in 15 makefiles. + Added links from include/libpngNN/*.h to include/*.h in 24 makefiles. + Revised makefile.darwin to make relative links without full pathname. + Added setjmp() at the end of png_create_*_struct_2() in case user forgets + to put one in their application. + Restored png_zalloc() and png_zfree() prototypes to version 1.2.1 and + removed them from module definition files. +version 1.2.3rc2 [May 1, 2002] + Fixed bug in reporting number of channels in pngget.c and pngset.c, + that was introduced in version 1.2.2beta5. + Exported png_zalloc(), png_zfree(), png_default_read(), png_default_write(), + png_default_flush(), and png_push_fill_buffer() and included them in + module definition files. + Added "libpng.pc" dependency to the "install-shared" target in 15 makefiles. +version 1.2.3rc3 [May 1, 2002] + Revised prototype for png_default_flush() + Remove old libpng.pc and libpngNN.pc before installing new ones. +version 1.2.3rc4 [May 2, 2002] + Typos in *.def files (png_default_read|write -> png_default_read|write_data) + In makefiles, changed rm libpng.NN.pc to rm libpngNN.pc + Added libpng-config and libpngNN-config and modified makefiles to install them. + Changed $(MANPATH) to $(DESTDIR)$(MANPATH) in makefiles + Added "Win32 DLL VB" configuration to projects/msvc/libpng.dsp +version 1.2.3rc5 [May 11, 2002] + Changed "error" and "message" in prototypes to "error_message" and + "warning_message" to avoid namespace conflict. + Revised 15 makefiles to build libpng-config from libpng-config-*.in + Once more restored png_zalloc and png_zfree to regular nonexported form. + Restored png_default_read|write_data, png_default_flush, png_read_fill_buffer + to nonexported form, but with PNGAPI, and removed them from module def files. +version 1.2.3rc6 [May 14, 2002] + Removed "PNGAPI" from png_zalloc() and png_zfree() in png.c + Changed "Gz" to "Gd" in projects/msvc/libpng.dsp and zlib.dsp. + Removed leftover libpng-config "sed" script from four makefiles. + Revised libpng-config creating script in 16 makefiles. + +version 1.2.3 [May 22, 2002] + Revised libpng-config target in makefile.cygwin. + Removed description of png_set_mem_fn() from documentation. + Revised makefile.freebsd. + Minor cosmetic changes to 15 makefiles, e.g., $(DI) = $(DESTDIR)/$(INCDIR). + Revised projects/msvc/README.txt + Changed -lpng to -lpngNN in LDFLAGS in several makefiles. +version 1.2.4beta1 [May 24, 2002] + Added libpng.pc and libpng-config to "all:" target in 16 makefiles. + Fixed bug in 16 makefiles: $(DESTDIR)/$(LIBPATH) to $(DESTDIR)$(LIBPATH) + Added missing "\" before closing double quote in makefile.gcmmx. + Plugged various memory leaks; added png_malloc_warn() and png_set_text_2() + functions. +version 1.2.4beta2 [June 25, 2002] + Plugged memory leak of png_ptr->current_text (Matt Holgate). + Check for buffer overflow before reading CRC in pngpread.c (Warwick Allison) + Added -soname to the loader flags in makefile.dec, makefile.sgi, and + makefile.sggcc. + Added "test-installed" target to makefile.linux, makefile.gcmmx, + makefile.sgi, and makefile.sggcc. +version 1.2.4beta3 [June 28, 2002] + Plugged memory leak of row_buf in pngtest.c when there is a png_error(). + Detect buffer overflow in pngpread.c when IDAT is corrupted with extra data. + Added "test-installed" target to makefile.32sunu, makefile.64sunu, + makefile.beos, makefile.darwin, makefile.dec, makefile.macosx, + makefile.solaris, makefile.hpux, makefile.hpgcc, and makefile.so9. +version 1.2.4rc1 and 1.0.14rc1 [July 2, 2002] + Added "test-installed" target to makefile.cygwin and makefile.sco. + Revised pnggccrd.c to be able to back out version 1.0.x via PNG_1_0_X macro. + +version 1.2.4 and 1.0.14 [July 8, 2002] + Changed png_warning() to png_error() when width is too large to process. +version 1.2.4patch01 [July 20, 2002] + Revised makefile.cygwin to use DLL number 12 instead of 13. +version 1.2.5beta1 [August 6, 2002] + Added code to contrib/gregbook/readpng2.c to ignore unused chunks. + Replaced toucan.png in contrib/gregbook (it has been corrupt since 1.0.11) + Removed some stray *.o files from contrib/gregbook. + Changed png_error() to png_warning() about "Too much data" in pngpread.c + and about "Extra compressed data" in pngrutil.c. + Prevent png_ptr->pass from exceeding 7 in png_push_finish_row(). + Updated makefile.hpgcc + Updated png.c and pnggccrd.c handling of return from png_mmx_support() +version 1.2.5beta2 [August 15, 2002] + Only issue png_warning() about "Too much data" in pngpread.c when avail_in + is nonzero. + Updated makefiles to install a separate libpng.so.3 with its own rpath. +version 1.2.5rc1 and 1.0.15rc1 [August 24, 2002] + Revised makefiles to not remove previous minor versions of shared libraries. +version 1.2.5rc2 and 1.0.15rc2 [September 16, 2002] + Revised 13 makefiles to remove "-lz" and "-L$(ZLIBLIB)", etc., from shared + library loader directive. + Added missing "$OBJSDLL" line to makefile.gcmmx. + Added missing "; fi" to makefile.32sunu. +version 1.2.5rc3 and 1.0.15rc3 [September 18, 2002] + Revised libpng-config script. + +version 1.2.5 and 1.0.15 [October 3, 2002] + Revised makefile.macosx, makefile.darwin, makefile.hpgcc, and makefile.hpux, + and makefile.aix. + Relocated two misplaced PNGAPI lines in pngtest.c +version 1.2.6beta1 [October 22, 2002] + Commented out warning about uninitialized mmx_support in pnggccrd.c. + Changed "IBMCPP__" flag to "__IBMCPP__" in pngconf.h. + Relocated two more misplaced PNGAPI lines in pngtest.c + Fixed memory overrun bug in png_do_read_filler() with 16-bit datastreams, + introduced in version 1.0.2. + Revised makefile.macosx, makefile.dec, makefile.aix, and makefile.32sunu. +version 1.2.6beta2 [November 1, 2002] + Added libpng-config "--ldopts" output. + Added "AR=ar" and "ARFLAGS=rc" and changed "ar rc" to "$(AR) $(ARFLAGS)" + in makefiles. +version 1.2.6beta3 [July 18, 2004] + Reverted makefile changes from version 1.2.6beta2 and some of the changes + from version 1.2.6beta1; these will be postponed until version 1.2.7. + Version 1.2.6 is going to be a simple bugfix release. + Changed the one instance of "ln -sf" to "ln -f -s" in each Sun makefile. + Fixed potential overrun in pngerror.c by using strncpy instead of memcpy. + Added "#!/bin/sh" at the top of configure, for recognition of the + 'x' flag under Cygwin (Cosmin). + Optimized vacuous tests that silence compiler warnings, in png.c (Cosmin). + Added support for PNG_USER_CONFIG, in pngconf.h (Cosmin). + Fixed the special memory handler for Borland C under DOS, in pngmem.c + (Cosmin). + Removed some spurious assignments in pngrutil.c (Cosmin). + Replaced 65536 with 65536L, and 0xffff with 0xffffL, to silence warnings + on 16-bit platforms (Cosmin). + Enclosed shift op expressions in parentheses, to silence warnings (Cosmin). + Used proper type png_fixed_point, to avoid problems on 16-bit platforms, + in png_handle_sRGB() (Cosmin). + Added compression_type to png_struct, and optimized the window size + inside the deflate stream (Cosmin). + Fixed definition of isnonalpha(), in pngerror.c and pngrutil.c (Cosmin). + Fixed handling of unknown chunks that come after IDAT (Cosmin). + Allowed png_error() and png_warning() to work even if png_ptr == NULL + (Cosmin). + Replaced row_info->rowbytes with row_bytes in png_write_find_filter() + (Cosmin). + Fixed definition of PNG_LIBPNG_VER_DLLNUM (Simon-Pierre). + Used PNG_LIBPNG_VER and PNG_LIBPNG_VER_STRING instead of the hardcoded + values in png.c (Simon-Pierre, Cosmin). + Initialized png_libpng_ver[] with PNG_LIBPNG_VER_STRING (Simon-Pierre). + Replaced PNG_LIBPNG_VER_MAJOR with PNG_LIBPNG_VER_DLLNUM in png.rc + (Simon-Pierre). + Moved the definition of PNG_HEADER_VERSION_STRING near the definitions + of the other PNG_LIBPNG_VER_... symbols in png.h (Cosmin). + Relocated #ifndef PNGAPI guards in pngconf.h (Simon-Pierre, Cosmin). + Updated scripts/makefile.vc(a)win32 (Cosmin). + Updated the MSVC project (Simon-Pierre, Cosmin). + Updated the Borland C++ Builder project (Cosmin). + Avoided access to asm_flags in pngvcrd.c, if PNG_1_0_X is defined (Cosmin). + Commented out warning about uninitialized mmx_support in pngvcrd.c (Cosmin). + Removed scripts/makefile.bd32 and scripts/pngdef.pas (Cosmin). + Added extra guard around inclusion of Turbo C memory headers, in pngconf.h + (Cosmin). + Renamed projects/msvc/ to projects/visualc6/, and projects/borland/ to + projects/cbuilder5/ (Cosmin). + Moved projects/visualc6/png32ms.def to scripts/pngw32.def, + and projects/visualc6/png.rc to scripts/pngw32.rc (Cosmin). + Added projects/visualc6/pngtest.dsp; removed contrib/msvctest/ (Cosmin). + Changed line endings to DOS style in cbuilder5 and visualc6 files, even + in the tar.* distributions (Cosmin). + Updated contrib/visupng/VisualPng.dsp (Cosmin). + Updated contrib/visupng/cexcept.h to version 2.0.0 (Cosmin). + Added a separate distribution with "configure" and supporting files (Junichi). +version 1.2.6beta4 [July 28, 2004] + Added user ability to change png_size_t via a PNG_SIZE_T macro. + Added png_sizeof() and png_convert_size() functions. + Added PNG_SIZE_MAX (maximum value of a png_size_t variable. + Added check in png_malloc_default() for (size_t)size != (png_uint_32)size + which would indicate an overflow. + Changed sPLT failure action from png_error to png_warning and abandon chunk. + Changed sCAL and iCCP failures from png_error to png_warning and abandon. + Added png_get_uint_31(png_ptr, buf) function. + Added PNG_UINT_32_MAX macro. + Renamed PNG_MAX_UINT to PNG_UINT_31_MAX. + Made png_zalloc() issue a png_warning and return NULL on potential + overflow. + Turn on PNG_NO_ZALLOC_ZERO by default in version 1.2.x + Revised "clobber list" in pnggccrd.c so it will compile under gcc-3.4. + Revised Borland portion of png_malloc() to return NULL or issue + png_error() according to setting of PNG_FLAG_MALLOC_NULL_MEM_OK. + Added PNG_NO_SEQUENTIAL_READ_SUPPORTED macro to conditionally remove + sequential read support. + Added some "#if PNG_WRITE_SUPPORTED" blocks. + #ifdef'ed out some redundancy in png_malloc_default(). + Use png_malloc instead of png_zalloc to allocate the pallete. +version 1.0.16rc1 and 1.2.6rc1 [August 4, 2004] + Fixed buffer overflow vulnerability in png_handle_tRNS() + Fixed integer arithmetic overflow vulnerability in png_read_png(). + Fixed some harmless bugs in png_handle_sBIT, etc, that would cause + duplicate chunk types to go undetected. + Fixed some timestamps in the -config version + Rearranged order of processing of color types in png_handle_tRNS(). + Added ROWBYTES macro to calculate rowbytes without integer overflow. + Updated makefile.darwin and removed makefile.macosx from scripts directory. + Imposed default one million column, one-million row limits on the image + dimensions, and added png_set_user_limits() function to override them. + Revised use of PNG_SET_USER_LIMITS_SUPPORTED macro. + Fixed wrong cast of returns from png_get_user_width|height_max(). + Changed some "keep the compiler happy" from empty statements to returns, + Revised libpng.txt to remove 1.2.x stuff from the 1.0.x distribution +version 1.0.16rc2 and 1.2.6rc2 [August 7, 2004] + Revised makefile.darwin and makefile.solaris. Removed makefile.macosx. + Revised pngtest's png_debug_malloc() to use png_malloc() instead of + png_malloc_default() which is not supposed to be exported. + Fixed off-by-one error in one of the conversions to PNG_ROWBYTES() in + pngpread.c. Bug was introduced in 1.2.6rc1. + Fixed bug in RGB to RGBX transformation introduced in 1.2.6rc1. + Fixed old bug in RGB to Gray transformation. + Fixed problem with 64-bit compilers by casting arguments to abs() + to png_int_32. + Changed "ln -sf" to "ln -f -s" in three makefiles (solaris, sco, so9). + Changed "HANDLE_CHUNK_*" to "PNG_HANDLE_CHUNK_*" (Cosmin) + Added "-@/bin/rm -f $(DL)/$(LIBNAME).so.$(PNGMAJ)" to 15 *NIX makefiles. + Added code to update the row_info->colortype in png_do_read_filler() (MSB). +version 1.0.16rc3 and 1.2.6rc3 [August 9, 2004] + Eliminated use of "abs()" in testing cHRM and gAMA values, to avoid + trouble with some 64-bit compilers. Created PNG_OUT_OF_RANGE() macro. + Revised documentation of png_set_keep_unknown_chunks(). + Check handle_as_unknown status in pngpread.c, as in pngread.c previously. + Moved "PNG_HANDLE_CHUNK_*" macros out of PNG_INTERNAL section of png.h + Added "rim" definitions for CONST4 and CONST6 in pnggccrd.c +version 1.0.16rc4 and 1.2.6rc4 [August 10, 2004] + Fixed mistake in pngtest.c introduced in 1.2.6rc2 (declaration of + "pinfo" was out of place). +version 1.0.16rc5 and 1.2.6rc5 [August 10, 2004] + Moved "PNG_HANDLE_CHUNK_*" macros out of PNG_ASSEMBLER_CODE_SUPPORTED + section of png.h where they were inadvertently placed in version rc3. + +version 1.2.6 and 1.0.16 [August 15, 2004] + Revised pngtest so memory allocation testing is only done when PNG_DEBUG==1. +version 1.2.7beta1 [August 26, 2004] + Removed unused pngasmrd.h file. + Removed references to uu.net for archived files. Added references to + PNG Spec (second edition) and the PNG ISO/IEC Standard. + Added "test-dd" target in 15 makefiles, to run pngtest in DESTDIR. + Fixed bug with "optimized window size" in the IDAT datastream, that + causes libpng to write PNG files with incorrect zlib header bytes. +version 1.2.7beta2 [August 28, 2004] + Fixed bug with sCAL chunk and big-endian machines (David Munro). + Undid new code added in 1.2.6rc2 to update the color_type in + png_set_filler(). + Added png_set_add_alpha() that updates color type. +version 1.0.17rc1 and 1.2.7rc1 [September 4, 2004] + Revised png_set_strip_filler() to not remove alpha if color_type has alpha. + +version 1.2.7 and 1.0.17 [September 12, 2004] + Added makefile.hp64 + Changed projects/msvc/png32ms.def to scripts/png32ms.def in makefile.cygwin +version 1.2.8beta1 [November 1, 2004] + Fixed bug in png_text_compress() that would fail to complete a large block. + Fixed bug, introduced in libpng-1.2.7, that overruns a buffer during + strip alpha operation in png_do_strip_filler(). + Added PNG_1_2_X definition in pngconf.h + #ifdef out png_info_init in png.c and png_read_init in pngread.c (as of 1.3.0) +version 1.2.8beta2 [November 2, 2004] + Reduce color_type to a nonalpha type after strip alpha operation in + png_do_strip_filler(). +version 1.2.8beta3 [November 3, 2004] + Revised definitions of PNG_MAX_UINT_32, PNG_MAX_SIZE, and PNG_MAXSUM +version 1.2.8beta4 [November 12, 2004] + Fixed (again) definition of PNG_LIBPNG_VER_DLLNUM in png.h (Cosmin). + Added PNG_LIBPNG_BUILD_PRIVATE in png.h (Cosmin). + Set png_ptr->zstream.data_type to Z_BINARY, to avoid unnecessary detection + of data type in deflate (Cosmin). + Deprecated but continue to support SPECIALBUILD and PRIVATEBUILD in favor of + PNG_LIBPNG_BUILD_SPECIAL_STRING and PNG_LIBPNG_BUILD_PRIVATE_STRING. +version 1.2.8beta5 [November 20, 2004] + Use png_ptr->flags instead of png_ptr->transformations to pass + PNG_STRIP_ALPHA info to png_do_strip_filler(), to preserve ABI + compatibility. + Revised handling of SPECIALBUILD, PRIVATEBUILD, + PNG_LIBPNG_BUILD_SPECIAL_STRING and PNG_LIBPNG_BUILD_PRIVATE_STRING. +version 1.2.8rc1 [November 24, 2004] + Moved handling of BUILD macros from pngconf.h to png.h + Added definition of PNG_LIBPNG_BASE_TYPE in png.h, inadvertently + omitted from beta5. + Revised scripts/pngw32.rc + Despammed mailing addresses by masking "@" with "at". + Inadvertently installed a supposedly faster test version of pngrutil.c +version 1.2.8rc2 [November 26, 2004] + Added two missing "\" in png.h + Change tests in pngread.c and pngpread.c to + if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA)) + png_do_read_transformations(png_ptr); +version 1.2.8rc3 [November 28, 2004] + Reverted pngrutil.c to version libpng-1.2.8beta5. + Added scripts/makefile.elf with supporting code in pngconf.h for symbol + versioning (John Bowler). +version 1.2.8rc4 [November 29, 2004] + Added projects/visualc7 (Simon-pierre). +version 1.2.8rc5 [November 29, 2004] + Fixed new typo in scripts/pngw32.rc + +version 1.2.8 [December 3, 2004] + Removed projects/visualc7, added projects/visualc71. + +version 1.2.9beta1 [February 21, 2006] + + Initialized some structure members in pngwutil.c to avoid gcc-4.0.0 complaints + Revised man page and libpng.txt to make it clear that one should not call + png_read_end or png_write_end after png_read_png or png_write_png. + Updated references to png-mng-implement mailing list. + Fixed an incorrect typecast in pngrutil.c + Added PNG_NO_READ_SUPPORTED conditional for making a write-only library. + Added PNG_NO_WRITE_INTERLACING_SUPPORTED conditional. + Optimized alpha-inversion loops in pngwtran.c + Moved test for nonzero gamma outside of png_build_gamma_table() in pngrtran.c + Make sure num_trans is <= 256 before copying data in png_set_tRNS(). + Make sure num_palette is <= 256 before copying data in png_set_PLTE(). + Interchanged order of write_swap_alpha and write_invert_alpha transforms. + Added parentheses in the definition of PNG_LIBPNG_BUILD_TYPE (Cosmin). + Optimized zlib window flag (CINFO) in contrib/pngsuite/*.png (Cosmin). + Updated scripts/makefile.bc32 for Borland C++ 5.6 (Cosmin). + Exported png_get_uint_32, png_save_uint_32, png_get_uint_16, png_save_uint_16, + png_get_int_32, png_save_int_32, png_get_uint_31 (Cosmin). + Added type cast (png_byte) in png_write_sCAL() (Cosmin). + Fixed scripts/makefile.cygwin (Christian Biesinger, Cosmin). + Default iTXt support was inadvertently enabled. + +version 1.2.9beta2 [February 21, 2006] + + Check for png_rgb_to_gray and png_gray_to_rgb read transformations before + checking for png_read_dither in pngrtran.c + Revised checking of chromaticity limits to accommodate extended RGB + colorspace (John Denker). + Changed line endings in some of the project files to CRLF, even in the + "Unix" tar distributions (Cosmin). + Made png_get_int_32 and png_save_int_32 always available (Cosmin). + Updated scripts/pngos2.def, scripts/pngw32.def and projects/wince/png32ce.def + with the newly exported functions. + Eliminated distributions without the "configure" script. + Updated INSTALL instructions. + +version 1.2.9beta3 [February 24, 2006] + + Fixed CRCRLF line endings in contrib/visupng/VisualPng.dsp + Made libpng.pc respect EXEC_PREFIX (D. P. Kreil, J. Bowler) + Removed reference to pngasmrd.h from Makefile.am + Renamed CHANGES to ChangeLog. + Renamed LICENSE to COPYING. + Renamed ANNOUNCE to NEWS. + Created AUTHORS file. + +version 1.2.9beta4 [March 3, 2006] + + Changed definition of PKGCONFIG from $prefix/lib to $libdir in configure.ac + Reverted to filenames LICENSE and ANNOUNCE; removed AUTHORS and COPYING. + Removed newline from the end of some error and warning messages. + Removed test for sqrt() from configure.ac and configure. + Made swap tables in pngtrans.c PNG_CONST (Carlo Bramix). + Disabled default iTXt support that was inadvertently enabled in + libpng-1.2.9beta1. + Added "OS2" to list of systems that don't need underscores, in pnggccrd.c + Removed libpng version and date from *.c files. + +version 1.2.9beta5 [March 4, 2006] + Removed trailing blanks from source files. + Put version and date of latest change in each source file, and changed + copyright year accordingly. + More cleanup of configure.ac, Makefile.ac, and associated scripts. + Restored scripts/makefile.elf which was inadvertently deleted. + +version 1.2.9beta6 [March 6, 2006] + Fixed typo (12) in configuration files. + +version 1.2.9beta7 [March 7, 2006] + Removed libpng.vers and libpng.sym from libpng12_la_SOURCES in Makefile.am + Fixed inconsistent #ifdef's around png_sig_bytes() and png_set_sCAL_s() + in png.h. + Updated makefile.elf as suggested by debian. + Made cosmetic changes to some makefiles, adding LN_SF and other macros. + Made some makefiles accept "exec_prefix". + +version 1.2.9beta8 [March 9, 2006] + Fixed some "#if defined (..." which should be "#if defined(..." + Bug introduced in libpng-1.2.8. + Fixed inconsistency in definition of png_default_read_data() + Restored blank that was lost from makefile.sggcc "clean" target in beta7. + Revised calculation of "current" and "major" for irix in ltmain.sh + Changed "mkdir" to "MKDIR_P" in some makefiles. + Separated PNG_EXPAND and PNG_EXPAND_tRNS. + Added png_set_expand_gray_1_2_4_to_8() and deprecated + png_set_gray_1_2_4_to_8() which also expands tRNS to alpha. + +version 1.2.9beta9 [March 10, 2006] + Include "config.h" in pngconf.h when available. + Added some checks for NULL png_ptr or NULL info_ptr (timeless) + +version 1.2.9beta10 [March 20, 2006] + Removed extra CR from contrib/visualpng/VisualPng.dsw (Cosmin) + Made pnggccrd.c PIC-compliant (Christian Aichinger). + Added makefile.mingw (Wolfgang Glas). + Revised pngconf.h MMX checking. + +version 1.2.9beta11 [March 22, 2006] + Fixed out-of-order declaration in pngwrite.c that was introduced in beta9 + Simplified some makefiles by using LIBSO, LIBSOMAJ, and LIBSOVER macros. + +version 1.2.9rc1 [March 31, 2006] + Defined PNG_USER_PRIVATEBUILD when including "pngusr.h" (Cosmin). + Removed nonsensical assertion check from pngtest.c (Cosmin). + +version 1.2.9 [April 14, 2006] + Revised makefile.beos and added "none" selector in ltmain.sh + +version 1.2.10beta1 [April 15, 2006] + Renamed "config.h" to "png_conf.h" and revised Makefile.am to add + -DPNG_BUILDING_LIBPNG to compile directive, and modified pngconf.h + to include png_conf.h only when PNG_BUILDING_LIBPNG is defined. + +version 1.2.10beta2 [April 15, 2006] + Manually updated Makefile.in and configure. Changed png_conf.h.in + back to config.h. + +version 1.2.10beta3 [April 15, 2006] + Change png_conf.h back to config.h in pngconf.h. + +version 1.2.10beta4 [April 16, 2006] + Change PNG_BUILDING_LIBPNG to PNG_CONFIGURE_LIBPNG in config/Makefile*. + +version 1.2.10beta5 [April 16, 2006] + Added a configure check for compiling assembler code in pnggccrd.c + +version 1.2.10beta6 [April 17, 2006] + Revised the configure check for pnggccrd.c + Moved -DPNG_CONFIGURE_LIBPNG into @LIBPNG_DEFINES@ + Added @LIBPNG_DEFINES@ to arguments when building libpng.sym + +version 1.2.10beta7 [April 18, 2006] + Change "exec_prefix=$prefix" to "exec_prefix=$(prefix)" in makefiles. + +version 1.2.10rc1 [April 19, 2006] + Ensure pngconf.h doesn't define both PNG_USE_PNGGCCRD and PNG_USE_PNGVCRD + Fixed "LN_FS" typo in makefile.sco and makefile.solaris. + +version 1.2.10rc2 [April 20, 2006] + Added a backslash between -DPNG_CONFIGURE_LIBPNG and -DPNG_NO_ASSEMBLER_CODE + in configure.ac and configure + Made the configure warning about versioned symbols less arrogant. + +version 1.2.10rc3 [April 21, 2006] + Added a note in libpng.txt that png_set_sig_bytes(8) can be used when + writing an embedded PNG without the 8-byte signature. + Revised makefiles and configure to avoid making links to libpng.so.* + +version 1.2.10 [April 23, 2006] + Reverted configure to "rc2" state. + +version 1.2.11beta1 [May 31, 2006] + scripts/libpng.pc.in contained "configure" style version info and would + not work with makefiles. + The shared-library makefiles were linking to libpng.so.0 instead of + libpng.so.3 compatibility as the library. + +version 1.2.11beta2 [June 2, 2006] + Increased sprintf buffer from 50 to 52 chars in pngrutil.c to avoid + buffer overflow. + Fixed bug in example.c (png_set_palette_rgb -> png_set_palette_to_rgb) + +version 1.2.11beta3 [June 5, 2006] + Prepended "#! /bin/sh" to ltmail.sh and contrib/pngminus/*.sh (Cosmin). + Removed the accidental leftover Makefile.in~ (Cosmin). + Avoided potential buffer overflow and optimized buffer in + png_write_sCAL(), png_write_sCAL_s() (Cosmin). + Removed the include directories and libraries from CFLAGS and LDFLAGS + in scripts/makefile.gcc (Nelson A. de Oliveira, Cosmin). + +version 1.2.11beta4 [June 6, 2006] + Allow zero-length IDAT chunks after the entire zlib datastream, but not + after another intervening chunk type. + +version 1.0.19rc1, 1.2.11rc1 [June 13, 2006] + Deleted extraneous square brackets from [config.h] in configure.ac + +version 1.0.19rc2, 1.2.11rc2 [June 14, 2006] + Added prototypes for PNG_INCH_CONVERSIONS functions to png.h + Revised INSTALL and autogen.sh + Fixed typo in several makefiles (-W1 should be -Wl) + Added typedef for png_int_32 and png_uint_32 on 64-bit systems. + +version 1.0.19rc3, 1.2.11rc3 [June 15, 2006] + Removed the new typedefs for 64-bit systems (delay until version 1.4.0) + Added one zero element to png_gamma_shift[] array in pngrtran.c to avoid + reading out of bounds. + +version 1.0.19rc4, 1.2.11rc4 [June 15, 2006] + Really removed the new typedefs for 64-bit systems. + +version 1.0.19rc5, 1.2.11rc5 [June 22, 2006] + Removed png_sig_bytes entry from scripts/pngw32.def + +version 1.0.19, 1.2.11 [June 26, 2006] + None. + +version 1.0.20, 1.2.12 [June 27, 2006] + Really increased sprintf buffer from 50 to 52 chars in pngrutil.c to avoid + buffer overflow. + +Send comments/corrections/commendations to png-mng-implement at lists.sf.net +(subscription required; visit +https://lists.sourceforge.net/lists/listinfo/png-mng-implement +to subscribe) +or to glennrp at users.sourceforge.net + +Glenn R-P diff --git a/mod/pub.mod/libpng.mod/INSTALL b/mod/pub.mod/libpng.mod/INSTALL new file mode 100644 index 0000000..eee2822 --- /dev/null +++ b/mod/pub.mod/libpng.mod/INSTALL @@ -0,0 +1,195 @@ + +Installing libpng version 1.2.12 - June 27, 2006 + +On Unix/Linux and similar systems, you can simply type + + ./configure [--prefix=$HOME] + make check + make install + +and ignore the rest of this document. + +If configure does not work on your system and you have a reasonably +up-to-date set of tools, running ./autogen.sh before running ./configure +may fix the problem. You can also run the individual commands in +autogen.sh with the --force option, if supported by your version of +the tools. If you run 'libtoolize --force', though, this will replace +the distributed, patched, version of ltmain.sh with an unpatched version +and your shared library builds may fail to produce libraries with the +correct version numbers. + +Instead, you can use one of the custom-built makefiles in the +"scripts" directory + + cp scripts/makefile.system makefile + make test + make install + +Or you can use one of the "projects" in the "projects" directory. + +Before installing libpng, you must first install zlib, if it +is not already on your system. zlib can usually be found +wherever you got libpng. zlib can be placed in another directory, +at the same level as libpng. + +If your system already has a preinstalled zlib you will still need +to have access to the zlib.h and zconf.h include files that +correspond to the version of zlib that's installed. + +You can rename the directories that you downloaded (they +might be called "libpng-1.2.12" or "lpng109" and "zlib-1.2.1" +or "zlib121") so that you have directories called "zlib" and "libpng". + +Your directory structure should look like this: + + .. (the parent directory) + libpng (this directory) + INSTALL (this file) + README + *.h + *.c + contrib + gregbook + pngminus + pngsuite + visupng + projects + beos + c5builder (Borland) + visualc6 (msvc) + netware.txt + wince.txt + scripts + makefile.* + pngtest.png + etc. + zlib + README + *.h + *.c + contrib + etc. + +If the line endings in the files look funny, you may wish to get the other +distribution of libpng. It is available in both tar.gz (UNIX style line +endings) and zip (DOS style line endings) formats. + +If you are building libpng with MSVC, you can enter the +libpng projects\visualc6 directory and follow the instructions in +projects\visualc6\README.txt. + +You can build libpng for WindowsCE by downloading and installing +the projects\wince directory as instructed in the projects\wince.txt file, and +then following the instructions in the README* files. Similarly, you can +build libpng for Netware or Beos as instructed in projects\netware.txt +or projects\beos. + +Else enter the zlib directory and follow the instructions in zlib/README, +then come back here and run "configure" or choose the appropriate +makefile.sys in the scripts directory. + +The files that are presently available in the scripts directory +include + + makefile.std => Generic UNIX makefile (cc, creates static libpng.a) + makefile.elf => Linux/ELF makefile symbol versioning, + gcc, creates libpng12.so.0.1.2.12) + makefile.linux => Linux/ELF makefile + (gcc, creates libpng12.so.0.1.2.12) + makefile.gcmmx => Linux/ELF makefile + (gcc, creates libpng12.so.0.1.2.12, + uses assembler code tuned for Intel MMX platform) + makefile.gcc => Generic makefile (gcc, creates static libpng.a) + makefile.knr => Archaic UNIX Makefile that converts files with + ansi2knr (Requires ansi2knr.c from + ftp://ftp.cs.wisc.edu/ghost) + makefile.aix => AIX/gcc makefile + makefile.cygwin => Cygwin/gcc makefile + makefile.darwin => Darwin makefile, can use on MacosX + makefile.dec => DEC Alpha UNIX makefile + makefile.freebsd => FreeBSD makefile + makefile.hpgcc => HPUX makefile using gcc + makefile.hpux => HPUX (10.20 and 11.00) makefile + makefile.hp64 => HPUX (10.20 and 11.00) makefile, 64-bit + makefile.ibmc => IBM C/C++ version 3.x for Win32 and OS/2 (static) + makefile.intel => Intel C/C++ version 4.0 and later + libpng.icc => Project file for IBM VisualAge/C++ version 4.0 or later + makefile.netbsd => NetBSD/cc makefile, uses PNGGCCRD, makes libpng.so. + makefile.ne12bsd => NetBSD/cc makefile, uses PNGGCCRD, + makes libpng12.so + makefile.openbsd => OpenBSD makefile + makefile.sgi => Silicon Graphics IRIX makefile (cc, creates static lib) + makefile.sggcc => Silicon Graphics (gcc, + creates libpng12.so.0.1.2.12) + makefile.sunos => Sun makefile + makefile.solaris => Solaris 2.X makefile (gcc, + creates libpng12.so.0.1.2.12) + makefile.so9 => Solaris 9 makefile (gcc, + creates libpng12.so.0.1.2.12) + makefile.32sunu => Sun Ultra 32-bit makefile + makefile.64sunu => Sun Ultra 64-bit makefile + makefile.sco => For SCO OSr5 ELF and Unixware 7 with Native cc + makefile.mips => MIPS makefile + makefile.acorn => Acorn makefile + makefile.amiga => Amiga makefile + smakefile.ppc => AMIGA smakefile for SAS C V6.58/7.00 PPC compiler + (Requires SCOPTIONS, copied from scripts/SCOPTIONS.ppc) + makefile.atari => Atari makefile + makefile.beos => BEOS makefile for X86 + makefile.bor => Borland makefile (uses bcc) + makefile.bc32 => 32-bit Borland C++ (all modules compiled in C mode) + makefile.tc3 => Turbo C 3.0 makefile + makefile.dj2 => DJGPP 2 makefile + makefile.msc => Microsoft C makefile + makefile.vcawin32 => makefile for Microsoft Visual C++ 5.0 and later (uses + assembler code tuned for Intel MMX platform) + makefile.vcwin32 => makefile for Microsoft Visual C++ 4.0 and later (does + not use assembler code) + makefile.os2 => OS/2 Makefile (gcc and emx, requires pngos2.def) + pngos2.def => OS/2 module definition file used by makefile.os2 + makefile.watcom => Watcom 10a+ Makefile, 32-bit flat memory model + makevms.com => VMS build script + descrip.mms => VMS makefile for MMS or MMK + SCOPTIONS.ppc => Used with smakefile.ppc + +Copy the file (or files) that you need from the +scripts directory into this directory, for example + + MSDOS example: copy scripts\makefile.msc makefile + UNIX example: cp scripts/makefile.std makefile + +Read the makefile to see if you need to change any source or +target directories to match your preferences. + +Then read pngconf.h to see if you want to make any configuration +changes. + +Then just run "make" which will create the libpng library in +this directory and "make test" which will run a quick test that reads +the "pngtest.png" file and writes a "pngout.png" file that should be +identical to it. Look for "9782 zero samples" in the output of the +test. For more confidence, you can run another test by typing +"pngtest pngnow.png" and looking for "289 zero samples" in the output. +Also, you can run "pngtest -m contrib/pngsuite/*.png" and compare +your output with the result shown in contrib/pngsuite/README. + +Most of the makefiles will allow you to run "make install" to +put the library in its final resting place (if you want to +do that, run "make install" in the zlib directory first if necessary). +Some also allow you to run "make test-installed" after you have +run "make install". + +If you encounter a compiler error message complaining about the +lines + __png.h__ already includes setjmp.h; + __dont__ include it again.; +This means you have compiled another module that includes setjmp.h, +which is hazardous because the two modules might not include exactly +the same setjmp.h. If you are sure that you know what you are doing +and that they are exactly the same, then you can comment out or +delete the two lines. Better yet, use the cexcept interface +instead, as demonstrated in contrib/visupng of the libpng distribution. + +Further information can be found in the README and libpng.txt +files, in the individual makefiles, in png.h, and the manual pages +libpng.3 and png.5. diff --git a/mod/pub.mod/libpng.mod/KNOWNBUG b/mod/pub.mod/libpng.mod/KNOWNBUG new file mode 100644 index 0000000..8db8bd2 --- /dev/null +++ b/mod/pub.mod/libpng.mod/KNOWNBUG @@ -0,0 +1,23 @@ + +Known bugs in libpng version 1.2.12 + +1. April 22, 2001: pnggccrd.c has been reported to crash on NetBSD when + reading interlaced PNG files, when assembler code is enabled but running + on a non-MMX i386 platform. + + STATUS: Under investigation. The change to pnggccrd.c in libpng-1.2.1 + fixed a problem under FreeBSD but not the problem with NetBSD, which + still fails as of libpng-1.2.2rc1. + +2. February 23, 2006: The custom makefiles don't build libpng with -lz. + + STATUS: This is a subject of debate. The change will probably be made + as a part of a major overhaul of the makefiles in libpng version 1.3.0. + +3. February 24, 2006: The Makefile generated by the "configure" script + fails to install symbolic links + libpng12.so => libpng12.so.0.1.2.9betaN + that are generated by the custom makefiles. + + STATUS: For now, system library builders should use the custom makefiles. + diff --git a/mod/pub.mod/libpng.mod/LICENSE b/mod/pub.mod/libpng.mod/LICENSE new file mode 100644 index 0000000..ef17df6 --- /dev/null +++ b/mod/pub.mod/libpng.mod/LICENSE @@ -0,0 +1,109 @@ + +This copy of the libpng notices is provided for your convenience. In case of +any discrepancy between this copy and the notices in the file png.h that is +included in the libpng distribution, the latter shall prevail. + +COPYRIGHT NOTICE, DISCLAIMER, and LICENSE: + +If you modify libpng you may insert additional notices immediately following +this sentence. + +libpng versions 1.2.6, August 15, 2004, through 1.2.12, June 27, 2006, are +Copyright (c) 2004, 2006 Glenn Randers-Pehrson, and are +distributed according to the same disclaimer and license as libpng-1.2.5 +with the following individual added to the list of Contributing Authors + + Cosmin Truta + +libpng versions 1.0.7, July 1, 2000, through 1.2.5 - October 3, 2002, are +Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are +distributed according to the same disclaimer and license as libpng-1.0.6 +with the following individuals added to the list of Contributing Authors + + Simon-Pierre Cadieux + Eric S. Raymond + Gilles Vollant + +and with the following additions to the disclaimer: + + There is no warranty against interference with your enjoyment of the + library or against infringement. There is no warranty that our + efforts or the library will fulfill any of your particular purposes + or needs. This library is provided with all faults, and the entire + risk of satisfactory quality, performance, accuracy, and effort is with + the user. + +libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are +Copyright (c) 1998, 1999 Glenn Randers-Pehrson, and are +distributed according to the same disclaimer and license as libpng-0.96, +with the following individuals added to the list of Contributing Authors: + + Tom Lane + Glenn Randers-Pehrson + Willem van Schaik + +libpng versions 0.89, June 1996, through 0.96, May 1997, are +Copyright (c) 1996, 1997 Andreas Dilger +Distributed according to the same disclaimer and license as libpng-0.88, +with the following individuals added to the list of Contributing Authors: + + John Bowler + Kevin Bracey + Sam Bushell + Magnus Holmgren + Greg Roelofs + Tom Tanner + +libpng versions 0.5, May 1995, through 0.88, January 1996, are +Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc. + +For the purposes of this copyright and license, "Contributing Authors" +is defined as the following set of individuals: + + Andreas Dilger + Dave Martindale + Guy Eric Schalnat + Paul Schmidt + Tim Wegner + +The PNG Reference Library is supplied "AS IS". The Contributing Authors +and Group 42, Inc. disclaim all warranties, expressed or implied, +including, without limitation, the warranties of merchantability and of +fitness for any purpose. The Contributing Authors and Group 42, Inc. +assume no liability for direct, indirect, incidental, special, exemplary, +or consequential damages, which may result from the use of the PNG +Reference Library, even if advised of the possibility of such damage. + +Permission is hereby granted to use, copy, modify, and distribute this +source code, or portions hereof, for any purpose, without fee, subject +to the following restrictions: + +1. The origin of this source code must not be misrepresented. + +2. Altered versions must be plainly marked as such and must not + be misrepresented as being the original source. + +3. This Copyright notice may not be removed or altered from any + source or altered source distribution. + +The Contributing Authors and Group 42, Inc. specifically permit, without +fee, and encourage the use of this source code as a component to +supporting the PNG file format in commercial products. If you use this +source code in a product, acknowledgment is not required but would be +appreciated. + + +A "png_get_copyright" function is available, for convenient use in "about" +boxes and the like: + + printf("%s",png_get_copyright(NULL)); + +Also, the PNG logo (in PNG format, of course) is supplied in the +files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31). + +Libpng is OSI Certified Open Source Software. OSI Certified Open Source is a +certification mark of the Open Source Initiative. + +Glenn Randers-Pehrson +glennrp at users.sourceforge.net +June 27, 2006 diff --git a/mod/pub.mod/libpng.mod/README b/mod/pub.mod/libpng.mod/README new file mode 100644 index 0000000..1ca0469 --- /dev/null +++ b/mod/pub.mod/libpng.mod/README @@ -0,0 +1,263 @@ +README for libpng version 1.2.12 - June 27, 2006 (shared library 12.0) +See the note about version numbers near the top of png.h + +See INSTALL for instructions on how to install libpng. + +Libpng comes in several distribution formats. Get libpng-*.tar.gz +or libpng-*.tar.bz2 if you want UNIX-style line endings in the text +files, or lpng*.zip if you want DOS-style line endings. + +Version 0.89 was the first official release of libpng. Don't let the +fact that it's the first release fool you. The libpng library has been in +extensive use and testing since mid-1995. By late 1997 it had +finally gotten to the stage where there hadn't been significant +changes to the API in some time, and people have a bad feeling about +libraries with versions < 1.0. Version 1.0.0 was released in +March 1998. + +**** +Note that some of the changes to the png_info structure render this +version of the library binary incompatible with libpng-0.89 or +earlier versions if you are using a shared library. The type of the +"filler" parameter for png_set_filler() has changed from png_byte to +png_uint_32, which will affect shared-library applications that use +this function. + +To avoid problems with changes to the internals of png_info_struct, +new APIs have been made available in 0.95 to avoid direct application +access to info_ptr. These functions are the png_set_<chunk> and +png_get_<chunk> functions. These functions should be used when +accessing/storing the info_struct data, rather than manipulating it +directly, to avoid such problems in the future. + +It is important to note that the APIs do not make current programs +that access the info struct directly incompatible with the new +library. However, it is strongly suggested that new programs use +the new APIs (as shown in example.c and pngtest.c), and older programs +be converted to the new format, to facilitate upgrades in the future. +**** + +Additions since 0.90 include the ability to compile libpng as a +Windows DLL, and new APIs for accessing data in the info struct. +Experimental functions include the ability to set weighting and cost +factors for row filter selection, direct reads of integers from buffers +on big-endian processors that support misaligned data access, faster +methods of doing alpha composition, and more accurate 16->8 bit color +conversion. + +The additions since 0.89 include the ability to read from a PNG stream +which has had some (or all) of the signature bytes read by the calling +application. This also allows the reading of embedded PNG streams that +do not have the PNG file signature. As well, it is now possible to set +the library action on the detection of chunk CRC errors. It is possible +to set different actions based on whether the CRC error occurred in a +critical or an ancillary chunk. + +The changes made to the library, and bugs fixed are based on discussions +on the PNG-implement mailing list +and not on material submitted privately to Guy, Andreas, or Glenn. They will +forward any good suggestions to the list. + +For a detailed description on using libpng, read libpng.txt. For +examples of libpng in a program, see example.c and pngtest.c. For usage +information and restrictions (what little they are) on libpng, see +png.h. For a description on using zlib (the compression library used by +libpng) and zlib's restrictions, see zlib.h + +I have included a general makefile, as well as several machine and +compiler specific ones, but you may have to modify one for your own needs. + +You should use zlib 1.0.4 or later to run this, but it MAY work with +versions as old as zlib 0.95. Even so, there are bugs in older zlib +versions which can cause the output of invalid compression streams for +some images. You will definitely need zlib 1.0.4 or later if you are +taking advantage of the MS-DOS "far" structure allocation for the small +and medium memory models. You should also note that zlib is a +compression library that is useful for more things than just PNG files. +You can use zlib as a drop-in replacement for fread() and fwrite() if +you are so inclined. + +zlib should be available at the same place that libpng is, or at. +ftp://ftp.info-zip.org/pub/infozip/zlib + +You may also want a copy of the PNG specification. It is available +as an RFC, a W3C Recommendation, and an ISO/IEC Standard. You can find +these at http://www.libpng.org/pub/png/documents/ + +This code is currently being archived at libpng.sf.net in the +[DOWNLOAD] area, and on CompuServe, Lib 20 (PNG SUPPORT) +at GO GRAPHSUP. If you can't find it in any of those places, +e-mail me, and I'll help you find it. + +If you have any code changes, requests, problems, etc., please e-mail +them to me. Also, I'd appreciate any make files or project files, +and any modifications you needed to make to get libpng to compile, +along with a #define variable to tell what compiler/system you are on. +If you needed to add transformations to libpng, or wish libpng would +provide the image in a different way, drop me a note (and code, if +possible), so I can consider supporting the transformation. +Finally, if you get any warning messages when compiling libpng +(note: not zlib), and they are easy to fix, I'd appreciate the +fix. Please mention "libpng" somewhere in the subject line. Thanks. + +This release was created and will be supported by myself (of course +based in a large way on Guy's and Andreas' earlier work), and the PNG group. + +Send comments/corrections/commendations to png-mng-implement at lists.sf.net +(subscription required; visit +https://lists.sourceforge.net/lists/listinfo/png-mng-implement +to subscribe) or to glennrp at users.sourceforge.net + +You can't reach Guy, the original libpng author, at the addresses +given in previous versions of this document. He and Andreas will read mail +addressed to the png-implement list, however. + +Please do not send general questions about PNG. Send them to +the (png-list at ccrc.wustl.edu, subscription required, write to +majordomo at ccrc.wustl.edu with "subscribe png-list" in your message). +On the other hand, +please do not send libpng questions to that address, send them to me +or to the png-implement list. I'll +get them in the end anyway. If you have a question about something +in the PNG specification that is related to using libpng, send it +to me. Send me any questions that start with "I was using libpng, +and ...". If in doubt, send questions to me. I'll bounce them +to others, if necessary. + +Please do not send suggestions on how to change PNG. We have +been discussing PNG for nine years now, and it is official and +finished. If you have suggestions for libpng, however, I'll +gladly listen. Even if your suggestion is not used immediately, +it may be used later. + +Files in this distribution: + + ANNOUNCE => Announcement of this version, with recent changes + CHANGES => Description of changes between libpng versions + KNOWNBUG => List of known bugs and deficiencies + LICENSE => License to use and redistribute libpng + README => This file + TODO => Things not implemented in the current library + Y2KINFO => Statement of Y2K compliance + example.c => Example code for using libpng functions + libpng.3 => manual page for libpng (includes libpng.txt) + libpng.txt => Description of libpng and its functions + libpngpf.3 => manual page for libpng's private functions + png.5 => manual page for the PNG format + png.c => Basic interface functions common to library + png.h => Library function and interface declarations + pngconf.h => System specific library configuration + pngasmrd.h => Header file for assembler-coded functions + pngerror.c => Error/warning message I/O functions + pngget.c => Functions for retrieving info from struct + pngmem.c => Memory handling functions + pngbar.png => PNG logo, 88x31 + pngnow.png => PNG logo, 98x31 + pngpread.c => Progressive reading functions + pngread.c => Read data/helper high-level functions + pngrio.c => Lowest-level data read I/O functions + pngrtran.c => Read data transformation functions + pngrutil.c => Read data utility functions + pngset.c => Functions for storing data into the info_struct + pngtest.c => Library test program + pngtest.png => Library test sample image + pngtrans.c => Common data transformation functions + pngwio.c => Lowest-level write I/O functions + pngwrite.c => High-level write functions + pngwtran.c => Write data transformations + pngwutil.c => Write utility functions + contrib => Contributions + gregbook => source code for PNG reading and writing, from + Greg Roelofs' "PNG: The Definitive Guide", + O'Reilly, 1999 + msvctest => Builds and runs pngtest using a MSVC workspace + pngminus => Simple pnm2png and png2pnm programs + pngsuite => Test images + visupng => Contains a MSVC workspace for VisualPng + projects => Contains project files and workspaces for building DLL + beos => Contains a Beos workspace for building libpng + c5builder => Contains a Borland workspace for building libpng + and zlib + visualc6 => Contains a Microsoft Visual C++ (MSVC) workspace + for building libpng and zlib + netware.txt => Contains instructions for downloading a set of + project files for building libpng and zlib on + Netware. + wince.txt => Contains instructions for downloading a Microsoft + Visual C++ (Windows CD Toolkit) workspace for + building libpng and zlib on WindowsCE + scripts => Directory containing scripts for building libpng: + descrip.mms => VMS makefile for MMS or MMK + makefile.std => Generic UNIX makefile (cc, creates static libpng.a) + makefile.elf => Linux/ELF makefile symbol versioning, + gcc, creates libpng12.so.0.1.2.12) + makefile.linux => Linux/ELF makefile + (gcc, creates libpng12.so.0.1.2.12) + makefile.gcmmx => Linux/ELF makefile + (gcc, creates libpng12.so.0.1.2.12, + uses assembler code tuned for Intel MMX platform) + makefile.gcc => Generic makefile (gcc, creates static libpng.a) + makefile.knr => Archaic UNIX Makefile that converts files with + ansi2knr (Requires ansi2knr.c from + ftp://ftp.cs.wisc.edu/ghost) + makefile.aix => AIX makefile + makefile.cygwin => Cygwin/gcc makefile + makefile.darwin => Darwin makefile + makefile.dec => DEC Alpha UNIX makefile + makefile.freebsd => FreeBSD makefile + makefile.hpgcc => HPUX makefile using gcc + makefile.hpux => HPUX (10.20 and 11.00) makefile + makefile.hp64 => HPUX (10.20 and 11.00) makefile, 64 bit + makefile.ibmc => IBM C/C++ version 3.x for Win32 and OS/2 (static) + makefile.intel => Intel C/C++ version 4.0 and later + libpng.icc => Project file, IBM VisualAge/C++ 4.0 or later + makefile.netbsd => NetBSD/cc makefile, PNGGCCRD, makes libpng.so. + makefile.ne12bsd => NetBSD/cc makefile, PNGGCCRD, makes libpng12.so + makefile.openbsd => OpenBSD makefile + makefile.sgi => Silicon Graphics IRIX (cc, creates static lib) + makefile.sggcc => Silicon Graphics + (gcc, creates libpng12.so.0.1.2.12) + makefile.sunos => Sun makefile + makefile.solaris => Solaris 2.X makefile + (gcc, creates libpng12.so.0.1.2.12) + makefile.so9 => Solaris 9 makefile + (gcc, creates libpng12.so.0.1.2.12) + makefile.32sunu => Sun Ultra 32-bit makefile + makefile.64sunu => Sun Ultra 64-bit makefile + makefile.sco => For SCO OSr5 ELF and Unixware 7 with Native cc + makefile.mips => MIPS makefile + makefile.acorn => Acorn makefile + makefile.amiga => Amiga makefile + smakefile.ppc => AMIGA smakefile for SAS C V6.58/7.00 PPC + compiler (Requires SCOPTIONS, copied from + scripts/SCOPTIONS.ppc) + makefile.atari => Atari makefile + makefile.beos => BEOS makefile for X86 + makefile.bor => Borland makefile (uses bcc) + makefile.bc32 => 32-bit Borland C++ (all modules compiled in C mode) + makefile.tc3 => Turbo C 3.0 makefile + makefile.dj2 => DJGPP 2 makefile + makefile.msc => Microsoft C makefile + makefile.vcawin32=> makefile for Microsoft Visual C++ 5.0 and + later (uses assembler code tuned for Intel MMX + platform) + makefile.vcwin32 => makefile for Microsoft Visual C++ 4.0 and + later (does not use assembler code) + makefile.os2 => OS/2 Makefile (gcc and emx, requires pngos2.def) + pngos2.def => OS/2 module definition file used by makefile.os2 + makefile.watcom => Watcom 10a+ Makefile, 32-bit flat memory model + makevms.com => VMS build script + SCOPTIONS.ppc => Used with smakefile.ppc + +Good luck, and happy coding. + +-Glenn Randers-Pehrson (current maintainer) + Internet: glennrp at users.sourceforge.net + +-Andreas Eric Dilger (former maintainer, 1996-1997) + Internet: adilger at enel.ucalgary.ca + Web: http://www-mddsp.enel.ucalgary.ca/People/adilger/ + +-Guy Eric Schalnat (original author and former maintainer, 1995-1996) + (formerly of Group 42, Inc) + Internet: gschal at infinet.com diff --git a/mod/pub.mod/libpng.mod/TODO b/mod/pub.mod/libpng.mod/TODO new file mode 100644 index 0000000..a5f6395 --- /dev/null +++ b/mod/pub.mod/libpng.mod/TODO @@ -0,0 +1,24 @@ +TODO - list of things to do for libpng: + +Final bug fixes. +Improve API by hiding the png_struct and png_info structs. +Finish work on the no-floating-point version (including gamma compensation) +Better C++ wrapper/full C++ implementation? +Fix problem with C++ and EXTERN "C". +cHRM transformation. +Improve setjmp/longjmp usage or remove it in favor of returning error codes. +Add "grayscale->palette" transformation and "palette->grayscale" detection. +Improved dithering. +Multi-lingual error and warning message support. +Complete sRGB transformation (presently it simply uses gamma=0.45455). +Man pages for function calls. +Better documentation. +Better filter selection + (counting huffman bits/precompression? filter inertia? filter costs?). +Histogram creation. +Text conversion between different code pages (Latin-1 -> Mac and DOS). +Should we always malloc 2^bit_depth PLTE/tRNS/hIST entries for safety? +Build gamma tables using fixed point (and do away with floating point entirely). +Use greater precision when changing to linear gamma for compositing against + background and doing rgb-to-gray transformation. +Investigate pre-incremented loop counters and other loop constructions. diff --git a/mod/pub.mod/libpng.mod/Y2KINFO b/mod/pub.mod/libpng.mod/Y2KINFO new file mode 100644 index 0000000..46fd481 --- /dev/null +++ b/mod/pub.mod/libpng.mod/Y2KINFO @@ -0,0 +1,55 @@ + Y2K compliance in libpng: + ========================= + + June 27, 2006 + + Since the PNG Development group is an ad-hoc body, we can't make + an official declaration. + + This is your unofficial assurance that libpng from version 0.71 and + upward through 1.2.12 are Y2K compliant. It is my belief that earlier + versions were also Y2K compliant. + + Libpng only has three year fields. One is a 2-byte unsigned integer + that will hold years up to 65535. The other two hold the date in text + format, and will hold years up to 9999. + + The integer is + "png_uint_16 year" in png_time_struct. + + The strings are + "png_charp time_buffer" in png_struct and + "near_time_buffer", which is a local character string in png.c. + + There are seven time-related functions: + + png_convert_to_rfc_1123() in png.c + (formerly png_convert_to_rfc_1152() in error) + png_convert_from_struct_tm() in pngwrite.c, called in pngwrite.c + png_convert_from_time_t() in pngwrite.c + png_get_tIME() in pngget.c + png_handle_tIME() in pngrutil.c, called in pngread.c + png_set_tIME() in pngset.c + png_write_tIME() in pngwutil.c, called in pngwrite.c + + All appear to handle dates properly in a Y2K environment. The + png_convert_from_time_t() function calls gmtime() to convert from system + clock time, which returns (year - 1900), which we properly convert to + the full 4-digit year. There is a possibility that applications using + libpng are not passing 4-digit years into the png_convert_to_rfc_1123() + function, or that they are incorrectly passing only a 2-digit year + instead of "year - 1900" into the png_convert_from_struct_tm() function, + but this is not under our control. The libpng documentation has always + stated that it works with 4-digit years, and the APIs have been + documented as such. + + The tIME chunk itself is also Y2K compliant. It uses a 2-byte unsigned + integer to hold the year, and can hold years as large as 65535. + + zlib, upon which libpng depends, is also Y2K compliant. It contains + no date-related code. + + + Glenn Randers-Pehrson + libpng maintainer + PNG Development Group diff --git a/mod/pub.mod/libpng.mod/configure b/mod/pub.mod/libpng.mod/configure new file mode 100644 index 0000000..bf8cad3 --- /dev/null +++ b/mod/pub.mod/libpng.mod/configure @@ -0,0 +1,13 @@ +#!/bin/sh +echo " + There is no \"configure\" script in this distribution of + libpng-1.2.12. + + Instead, please copy the appropriate makefile for your system from the + \"scripts\" directory. Read the INSTALL file for more details. + + Update, July 2004: you can get a \"configure\" based distribution + from the libpng distribution sites. Download the file + libpng-1.2.12.tar.gz or libpng-1.2.12.tar.bz2 +" + diff --git a/mod/pub.mod/libpng.mod/example.c b/mod/pub.mod/libpng.mod/example.c new file mode 100644 index 0000000..fd7096e --- /dev/null +++ b/mod/pub.mod/libpng.mod/example.c @@ -0,0 +1,814 @@ + +#if 0 /* in case someone actually tries to compile this */ + +/* example.c - an example of using libpng + * Last changed in libpng 1.2.1 December 7, 2001. + * This file has been placed in the public domain by the authors. + * Maintained 1998-2001 Glenn Randers-Pehrson + * Maintained 1996, 1997 Andreas Dilger) + * Written 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + */ + +/* This is an example of how to use libpng to read and write PNG files. + * The file libpng.txt is much more verbose then this. If you have not + * read it, do so first. This was designed to be a starting point of an + * implementation. This is not officially part of libpng, is hereby placed + * in the public domain, and therefore does not require a copyright notice. + * + * This file does not currently compile, because it is missing certain + * parts, like allocating memory to hold an image. You will have to + * supply these parts to get it to compile. For an example of a minimal + * working PNG reader/writer, see pngtest.c, included in this distribution; + * see also the programs in the contrib directory. + */ + +#include "png.h" + + /* The png_jmpbuf() macro, used in error handling, became available in + * libpng version 1.0.6. If you want to be able to run your code with older + * versions of libpng, you must define the macro yourself (but only if it + * is not already defined by libpng!). + */ + +#ifndef png_jmpbuf +# define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf) +#endif + +/* Check to see if a file is a PNG file using png_sig_cmp(). png_sig_cmp() + * returns zero if the image is a PNG and nonzero if it isn't a PNG. + * + * The function check_if_png() shown here, but not used, returns nonzero (true) + * if the file can be opened and is a PNG, 0 (false) otherwise. + * + * If this call is successful, and you are going to keep the file open, + * you should call png_set_sig_bytes(png_ptr, PNG_BYTES_TO_CHECK); once + * you have created the png_ptr, so that libpng knows your application + * has read that many bytes from the start of the file. Make sure you + * don't call png_set_sig_bytes() with more than 8 bytes read or give it + * an incorrect number of bytes read, or you will either have read too + * many bytes (your fault), or you are telling libpng to read the wrong + * number of magic bytes (also your fault). + * + * Many applications already read the first 2 or 4 bytes from the start + * of the image to determine the file type, so it would be easiest just + * to pass the bytes to png_sig_cmp() or even skip that if you know + * you have a PNG file, and call png_set_sig_bytes(). + */ +#define PNG_BYTES_TO_CHECK 4 +int check_if_png(char *file_name, FILE **fp) +{ + char buf[PNG_BYTES_TO_CHECK]; + + /* Open the prospective PNG file. */ + if ((*fp = fopen(file_name, "rb")) == NULL) + return 0; + + /* Read in some of the signature bytes */ + if (fread(buf, 1, PNG_BYTES_TO_CHECK, *fp) != PNG_BYTES_TO_CHECK) + return 0; + + /* Compare the first PNG_BYTES_TO_CHECK bytes of the signature. + Return nonzero (true) if they match */ + + return(!png_sig_cmp(buf, (png_size_t)0, PNG_BYTES_TO_CHECK)); +} + +/* Read a PNG file. You may want to return an error code if the read + * fails (depending upon the failure). There are two "prototypes" given + * here - one where we are given the filename, and we need to open the + * file, and the other where we are given an open file (possibly with + * some or all of the magic bytes read - see comments above). + */ +#ifdef open_file /* prototype 1 */ +void read_png(char *file_name) /* We need to open the file */ +{ + png_structp png_ptr; + png_infop info_ptr; + unsigned int sig_read = 0; + png_uint_32 width, height; + int bit_depth, color_type, interlace_type; + FILE *fp; + + if ((fp = fopen(file_name, "rb")) == NULL) + return (ERROR); +#else no_open_file /* prototype 2 */ +void read_png(FILE *fp, unsigned int sig_read) /* file is already open */ +{ + png_structp png_ptr; + png_infop info_ptr; + png_uint_32 width, height; + int bit_depth, color_type, interlace_type; +#endif no_open_file /* only use one prototype! */ + + /* Create and initialize the png_struct with the desired error handler + * functions. If you want to use the default stderr and longjump method, + * you can supply NULL for the last three parameters. We also supply the + * the compiler header file version, so that we know if the application + * was compiled with a compatible version of the library. REQUIRED + */ + png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, + png_voidp user_error_ptr, user_error_fn, user_warning_fn); + + if (png_ptr == NULL) + { + fclose(fp); + return (ERROR); + } + + /* Allocate/initialize the memory for image information. REQUIRED. */ + info_ptr = png_create_info_struct(png_ptr); + if (info_ptr == NULL) + { + fclose(fp); + png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL); + return (ERROR); + } + + /* Set error handling if you are using the setjmp/longjmp method (this is + * the normal method of doing things with libpng). REQUIRED unless you + * set up your own error handlers in the png_create_read_struct() earlier. + */ + + if (setjmp(png_jmpbuf(png_ptr))) + { + /* Free all of the memory associated with the png_ptr and info_ptr */ + png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL); + fclose(fp); + /* If we get here, we had a problem reading the file */ + return (ERROR); + } + + /* One of the following I/O initialization methods is REQUIRED */ +#ifdef streams /* PNG file I/O method 1 */ + /* Set up the input control if you are using standard C streams */ + png_init_io(png_ptr, fp); + +#else no_streams /* PNG file I/O method 2 */ + /* If you are using replacement read functions, instead of calling + * png_init_io() here you would call: + */ + png_set_read_fn(png_ptr, (void *)user_io_ptr, user_read_fn); + /* where user_io_ptr is a structure you want available to the callbacks */ +#endif no_streams /* Use only one I/O method! */ + + /* If we have already read some of the signature */ + png_set_sig_bytes(png_ptr, sig_read); + +#ifdef hilevel + /* + * If you have enough memory to read in the entire image at once, + * and you need to specify only transforms that can be controlled + * with one of the PNG_TRANSFORM_* bits (this presently excludes + * dithering, filling, setting background, and doing gamma + * adjustment), then you can read the entire image (including + * pixels) into the info structure with this call: + */ + png_read_png(png_ptr, info_ptr, png_transforms, png_voidp_NULL); +#else + /* OK, you're doing it the hard way, with the lower-level functions */ + + /* The call to png_read_info() gives us all of the information from the + * PNG file before the first IDAT (image data chunk). REQUIRED + */ + png_read_info(png_ptr, info_ptr); + + png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, + &interlace_type, int_p_NULL, int_p_NULL); + +/* Set up the data transformations you want. Note that these are all + * optional. Only call them if you want/need them. Many of the + * transformations only work on specific types of images, and many + * are mutually exclusive. + */ + + /* tell libpng to strip 16 bit/color files down to 8 bits/color */ + png_set_strip_16(png_ptr); + + /* Strip alpha bytes from the input data without combining with the + * background (not recommended). + */ + png_set_strip_alpha(png_ptr); + + /* Extract multiple pixels with bit depths of 1, 2, and 4 from a single + * byte into separate bytes (useful for paletted and grayscale images). + */ + png_set_packing(png_ptr); + + /* Change the order of packed pixels to least significant bit first + * (not useful if you are using png_set_packing). */ + png_set_packswap(png_ptr); + + /* Expand paletted colors into true RGB triplets */ + if (color_type == PNG_COLOR_TYPE_PALETTE) + png_set_palette_to_rgb(png_ptr); + + /* Expand grayscale images to the full 8 bits from 1, 2, or 4 bits/pixel */ + if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) + png_set_gray_1_2_4_to_8(png_ptr); + + /* Expand paletted or RGB images with transparency to full alpha channels + * so the data will be available as RGBA quartets. + */ + if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) + png_set_tRNS_to_alpha(png_ptr); + + /* Set the background color to draw transparent and alpha images over. + * It is possible to set the red, green, and blue components directly + * for paletted images instead of supplying a palette index. Note that + * even if the PNG file supplies a background, you are not required to + * use it - you should use the (solid) application background if it has one. + */ + + png_color_16 my_background, *image_background; + + if (png_get_bKGD(png_ptr, info_ptr, &image_background)) + png_set_background(png_ptr, image_background, + PNG_BACKGROUND_GAMMA_FILE, 1, 1.0); + else + png_set_background(png_ptr, &my_background, + PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0); + + /* Some suggestions as to how to get a screen gamma value */ + + /* Note that screen gamma is the display_exponent, which includes + * the CRT_exponent and any correction for viewing conditions */ + if (/* We have a user-defined screen gamma value */) + { + screen_gamma = user-defined screen_gamma; + } + /* This is one way that applications share the same screen gamma value */ + else if ((gamma_str = getenv("SCREEN_GAMMA")) != NULL) + { + screen_gamma = atof(gamma_str); + } + /* If we don't have another value */ + else + { + screen_gamma = 2.2; /* A good guess for a PC monitors in a dimly + lit room */ + screen_gamma = 1.7 or 1.0; /* A good guess for Mac systems */ + } + + /* Tell libpng to handle the gamma conversion for you. The final call + * is a good guess for PC generated images, but it should be configurable + * by the user at run time by the user. It is strongly suggested that + * your application support gamma correction. + */ + + int intent; + + if (png_get_sRGB(png_ptr, info_ptr, &intent)) + png_set_gamma(png_ptr, screen_gamma, 0.45455); + else + { + double image_gamma; + if (png_get_gAMA(png_ptr, info_ptr, &image_gamma)) + png_set_gamma(png_ptr, screen_gamma, image_gamma); + else + png_set_gamma(png_ptr, screen_gamma, 0.45455); + } + + /* Dither RGB files down to 8 bit palette or reduce palettes + * to the number of colors available on your screen. + */ + if (color_type & PNG_COLOR_MASK_COLOR) + { + int num_palette; + png_colorp palette; + + /* This reduces the image to the application supplied palette */ + if (/* we have our own palette */) + { + /* An array of colors to which the image should be dithered */ + png_color std_color_cube[MAX_SCREEN_COLORS]; + + png_set_dither(png_ptr, std_color_cube, MAX_SCREEN_COLORS, + MAX_SCREEN_COLORS, png_uint_16p_NULL, 0); + } + /* This reduces the image to the palette supplied in the file */ + else if (png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette)) + { + png_uint_16p histogram = NULL; + + png_get_hIST(png_ptr, info_ptr, &histogram); + + png_set_dither(png_ptr, palette, num_palette, + max_screen_colors, histogram, 0); + } + } + + /* invert monochrome files to have 0 as white and 1 as black */ + png_set_invert_mono(png_ptr); + + /* If you want to shift the pixel values from the range [0,255] or + * [0,65535] to the original [0,7] or [0,31], or whatever range the + * colors were originally in: + */ + if (png_get_valid(png_ptr, info_ptr, PNG_INFO_sBIT)) + { + png_color_8p sig_bit; + + png_get_sBIT(png_ptr, info_ptr, &sig_bit); + png_set_shift(png_ptr, sig_bit); + } + + /* flip the RGB pixels to BGR (or RGBA to BGRA) */ + if (color_type & PNG_COLOR_MASK_COLOR) + png_set_bgr(png_ptr); + + /* swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */ + png_set_swap_alpha(png_ptr); + + /* swap bytes of 16 bit files to least significant byte first */ + png_set_swap(png_ptr); + + /* Add filler (or alpha) byte (before/after each RGB triplet) */ + png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER); + + /* Turn on interlace handling. REQUIRED if you are not using + * png_read_image(). To see how to handle interlacing passes, + * see the png_read_row() method below: + */ + number_passes = png_set_interlace_handling(png_ptr); + + /* Optional call to gamma correct and add the background to the palette + * and update info structure. REQUIRED if you are expecting libpng to + * update the palette for you (ie you selected such a transform above). + */ + png_read_update_info(png_ptr, info_ptr); + + /* Allocate the memory to hold the image using the fields of info_ptr. */ + + /* The easiest way to read the image: */ + png_bytep row_pointers[height]; + + for (row = 0; row < height; row++) + { + row_pointers[row] = png_malloc(png_ptr, png_get_rowbytes(png_ptr, + info_ptr)); + } + + /* Now it's time to read the image. One of these methods is REQUIRED */ +#ifdef entire /* Read the entire image in one go */ + png_read_image(png_ptr, row_pointers); + +#else no_entire /* Read the image one or more scanlines at a time */ + /* The other way to read images - deal with interlacing: */ + + for (pass = 0; pass < number_passes; pass++) + { +#ifdef single /* Read the image a single row at a time */ + for (y = 0; y < height; y++) + { + png_read_rows(png_ptr, &row_pointers[y], png_bytepp_NULL, 1); + } + +#else no_single /* Read the image several rows at a time */ + for (y = 0; y < height; y += number_of_rows) + { +#ifdef sparkle /* Read the image using the "sparkle" effect. */ + png_read_rows(png_ptr, &row_pointers[y], png_bytepp_NULL, + number_of_rows); +#else no_sparkle /* Read the image using the "rectangle" effect */ + png_read_rows(png_ptr, png_bytepp_NULL, &row_pointers[y], + number_of_rows); +#endif no_sparkle /* use only one of these two methods */ + } + + /* if you want to display the image after every pass, do + so here */ +#endif no_single /* use only one of these two methods */ + } +#endif no_entire /* use only one of these two methods */ + + /* read rest of file, and get additional chunks in info_ptr - REQUIRED */ + png_read_end(png_ptr, info_ptr); +#endif hilevel + + /* At this point you have read the entire image */ + + /* clean up after the read, and free any memory allocated - REQUIRED */ + png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL); + + /* close the file */ + fclose(fp); + + /* that's it */ + return (OK); +} + +/* progressively read a file */ + +int +initialize_png_reader(png_structp *png_ptr, png_infop *info_ptr) +{ + /* Create and initialize the png_struct with the desired error handler + * functions. If you want to use the default stderr and longjump method, + * you can supply NULL for the last three parameters. We also check that + * the library version is compatible in case we are using dynamically + * linked libraries. + */ + *png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, + png_voidp user_error_ptr, user_error_fn, user_warning_fn); + + if (*png_ptr == NULL) + { + *info_ptr = NULL; + return (ERROR); + } + + *info_ptr = png_create_info_struct(png_ptr); + + if (*info_ptr == NULL) + { + png_destroy_read_struct(png_ptr, info_ptr, png_infopp_NULL); + return (ERROR); + } + + if (setjmp(png_jmpbuf((*png_ptr)))) + { + png_destroy_read_struct(png_ptr, info_ptr, png_infopp_NULL); + return (ERROR); + } + + /* This one's new. You will need to provide all three + * function callbacks, even if you aren't using them all. + * If you aren't using all functions, you can specify NULL + * parameters. Even when all three functions are NULL, + * you need to call png_set_progressive_read_fn(). + * These functions shouldn't be dependent on global or + * static variables if you are decoding several images + * simultaneously. You should store stream specific data + * in a separate struct, given as the second parameter, + * and retrieve the pointer from inside the callbacks using + * the function png_get_progressive_ptr(png_ptr). + */ + png_set_progressive_read_fn(*png_ptr, (void *)stream_data, + info_callback, row_callback, end_callback); + + return (OK); +} + +int +process_data(png_structp *png_ptr, png_infop *info_ptr, + png_bytep buffer, png_uint_32 length) +{ + if (setjmp(png_jmpbuf((*png_ptr)))) + { + /* Free the png_ptr and info_ptr memory on error */ + png_destroy_read_struct(png_ptr, info_ptr, png_infopp_NULL); + return (ERROR); + } + + /* This one's new also. Simply give it chunks of data as + * they arrive from the data stream (in order, of course). + * On Segmented machines, don't give it any more than 64K. + * The library seems to run fine with sizes of 4K, although + * you can give it much less if necessary (I assume you can + * give it chunks of 1 byte, but I haven't tried with less + * than 256 bytes yet). When this function returns, you may + * want to display any rows that were generated in the row + * callback, if you aren't already displaying them there. + */ + png_process_data(*png_ptr, *info_ptr, buffer, length); + return (OK); +} + +info_callback(png_structp png_ptr, png_infop info) +{ +/* do any setup here, including setting any of the transformations + * mentioned in the Reading PNG files section. For now, you _must_ + * call either png_start_read_image() or png_read_update_info() + * after all the transformations are set (even if you don't set + * any). You may start getting rows before png_process_data() + * returns, so this is your last chance to prepare for that. + */ +} + +row_callback(png_structp png_ptr, png_bytep new_row, + png_uint_32 row_num, int pass) +{ +/* + * This function is called for every row in the image. If the + * image is interlaced, and you turned on the interlace handler, + * this function will be called for every row in every pass. + * + * In this function you will receive a pointer to new row data from + * libpng called new_row that is to replace a corresponding row (of + * the same data format) in a buffer allocated by your application. + * + * The new row data pointer new_row may be NULL, indicating there is + * no new data to be replaced (in cases of interlace loading). + * + * If new_row is not NULL then you need to call + * png_progressive_combine_row() to replace the corresponding row as + * shown below: + */ + /* Check if row_num is in bounds. */ + if((row_num >= 0) && (row_num < height)) + { + /* Get pointer to corresponding row in our + * PNG read buffer. + */ + png_bytep old_row = ((png_bytep *)our_data)[row_num]; + + /* If both rows are allocated then copy the new row + * data to the corresponding row data. + */ + if((old_row != NULL) && (new_row != NULL)) + png_progressive_combine_row(png_ptr, old_row, new_row); + } +/* + * The rows and passes are called in order, so you don't really + * need the row_num and pass, but I'm supplying them because it + * may make your life easier. + * + * For the non-NULL rows of interlaced images, you must call + * png_progressive_combine_row() passing in the new row and the + * old row, as demonstrated above. You can call this function for + * NULL rows (it will just return) and for non-interlaced images + * (it just does the png_memcpy for you) if it will make the code + * easier. Thus, you can just do this for all cases: + */ + + png_progressive_combine_row(png_ptr, old_row, new_row); + +/* where old_row is what was displayed for previous rows. Note + * that the first pass (pass == 0 really) will completely cover + * the old row, so the rows do not have to be initialized. After + * the first pass (and only for interlaced images), you will have + * to pass the current row as new_row, and the function will combine + * the old row and the new row. + */ +} + +end_callback(png_structp png_ptr, png_infop info) +{ +/* this function is called when the whole image has been read, + * including any chunks after the image (up to and including + * the IEND). You will usually have the same info chunk as you + * had in the header, although some data may have been added + * to the comments and time fields. + * + * Most people won't do much here, perhaps setting a flag that + * marks the image as finished. + */ +} + +/* write a png file */ +void write_png(char *file_name /* , ... other image information ... */) +{ + FILE *fp; + png_structp png_ptr; + png_infop info_ptr; + png_colorp palette; + + /* open the file */ + fp = fopen(file_name, "wb"); + if (fp == NULL) + return (ERROR); + + /* Create and initialize the png_struct with the desired error handler + * functions. If you want to use the default stderr and longjump method, + * you can supply NULL for the last three parameters. We also check that + * the library version is compatible with the one used at compile time, + * in case we are using dynamically linked libraries. REQUIRED. + */ + png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, + png_voidp user_error_ptr, user_error_fn, user_warning_fn); + + if (png_ptr == NULL) + { + fclose(fp); + return (ERROR); + } + + /* Allocate/initialize the image information data. REQUIRED */ + info_ptr = png_create_info_struct(png_ptr); + if (info_ptr == NULL) + { + fclose(fp); + png_destroy_write_struct(&png_ptr, png_infopp_NULL); + return (ERROR); + } + + /* Set error handling. REQUIRED if you aren't supplying your own + * error handling functions in the png_create_write_struct() call. + */ + if (setjmp(png_jmpbuf(png_ptr))) + { + /* If we get here, we had a problem reading the file */ + fclose(fp); + png_destroy_write_struct(&png_ptr, &info_ptr); + return (ERROR); + } + + /* One of the following I/O initialization functions is REQUIRED */ +#ifdef streams /* I/O initialization method 1 */ + /* set up the output control if you are using standard C streams */ + png_init_io(png_ptr, fp); +#else no_streams /* I/O initialization method 2 */ + /* If you are using replacement read functions, instead of calling + * png_init_io() here you would call */ + png_set_write_fn(png_ptr, (void *)user_io_ptr, user_write_fn, + user_IO_flush_function); + /* where user_io_ptr is a structure you want available to the callbacks */ +#endif no_streams /* only use one initialization method */ + +#ifdef hilevel + /* This is the easy way. Use it if you already have all the + * image info living info in the structure. You could "|" many + * PNG_TRANSFORM flags into the png_transforms integer here. + */ + png_write_png(png_ptr, info_ptr, png_transforms, png_voidp_NULL); +#else + /* This is the hard way */ + + /* Set the image information here. Width and height are up to 2^31, + * bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on + * the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY, + * PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB, + * or PNG_COLOR_TYPE_RGB_ALPHA. interlace is either PNG_INTERLACE_NONE or + * PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST + * currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. REQUIRED + */ + png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, PNG_COLOR_TYPE_???, + PNG_INTERLACE_????, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); + + /* set the palette if there is one. REQUIRED for indexed-color images */ + palette = (png_colorp)png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH + * png_sizeof (png_color)); + /* ... set palette colors ... */ + png_set_PLTE(png_ptr, info_ptr, palette, PNG_MAX_PALETTE_LENGTH); + /* You must not free palette here, because png_set_PLTE only makes a link to + the palette that you malloced. Wait until you are about to destroy + the png structure. */ + + /* optional significant bit chunk */ + /* if we are dealing with a grayscale image then */ + sig_bit.gray = true_bit_depth; + /* otherwise, if we are dealing with a color image then */ + sig_bit.red = true_red_bit_depth; + sig_bit.green = true_green_bit_depth; + sig_bit.blue = true_blue_bit_depth; + /* if the image has an alpha channel then */ + sig_bit.alpha = true_alpha_bit_depth; + png_set_sBIT(png_ptr, info_ptr, sig_bit); + + + /* Optional gamma chunk is strongly suggested if you have any guess + * as to the correct gamma of the image. + */ + png_set_gAMA(png_ptr, info_ptr, gamma); + + /* Optionally write comments into the image */ + text_ptr[0].key = "Title"; + text_ptr[0].text = "Mona Lisa"; + text_ptr[0].compression = PNG_TEXT_COMPRESSION_NONE; + text_ptr[1].key = "Author"; + text_ptr[1].text = "Leonardo DaVinci"; + text_ptr[1].compression = PNG_TEXT_COMPRESSION_NONE; + text_ptr[2].key = "Description"; + text_ptr[2].text = "<long text>"; + text_ptr[2].compression = PNG_TEXT_COMPRESSION_zTXt; +#ifdef PNG_iTXt_SUPPORTED + text_ptr[0].lang = NULL; + text_ptr[1].lang = NULL; + text_ptr[2].lang = NULL; +#endif + png_set_text(png_ptr, info_ptr, text_ptr, 3); + + /* other optional chunks like cHRM, bKGD, tRNS, tIME, oFFs, pHYs, */ + /* note that if sRGB is present the gAMA and cHRM chunks must be ignored + * on read and must be written in accordance with the sRGB profile */ + + /* Write the file header information. REQUIRED */ + png_write_info(png_ptr, info_ptr); + + /* If you want, you can write the info in two steps, in case you need to + * write your private chunk ahead of PLTE: + * + * png_write_info_before_PLTE(write_ptr, write_info_ptr); + * write_my_chunk(); + * png_write_info(png_ptr, info_ptr); + * + * However, given the level of known- and unknown-chunk support in 1.1.0 + * and up, this should no longer be necessary. + */ + + /* Once we write out the header, the compression type on the text + * chunks gets changed to PNG_TEXT_COMPRESSION_NONE_WR or + * PNG_TEXT_COMPRESSION_zTXt_WR, so it doesn't get written out again + * at the end. + */ + + /* set up the transformations you want. Note that these are + * all optional. Only call them if you want them. + */ + + /* invert monochrome pixels */ + png_set_invert_mono(png_ptr); + + /* Shift the pixels up to a legal bit depth and fill in + * as appropriate to correctly scale the image. + */ + png_set_shift(png_ptr, &sig_bit); + + /* pack pixels into bytes */ + png_set_packing(png_ptr); + + /* swap location of alpha bytes from ARGB to RGBA */ + png_set_swap_alpha(png_ptr); + + /* Get rid of filler (OR ALPHA) bytes, pack XRGB/RGBX/ARGB/RGBA into + * RGB (4 channels -> 3 channels). The second parameter is not used. + */ + png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE); + + /* flip BGR pixels to RGB */ + png_set_bgr(png_ptr); + + /* swap bytes of 16-bit files to most significant byte first */ + png_set_swap(png_ptr); + + /* swap bits of 1, 2, 4 bit packed pixel formats */ + png_set_packswap(png_ptr); + + /* turn on interlace handling if you are not using png_write_image() */ + if (interlacing) + number_passes = png_set_interlace_handling(png_ptr); + else + number_passes = 1; + + /* The easiest way to write the image (you may have a different memory + * layout, however, so choose what fits your needs best). You need to + * use the first method if you aren't handling interlacing yourself. + */ + png_uint_32 k, height, width; + png_byte image[height][width*bytes_per_pixel]; + png_bytep row_pointers[height]; + + if (height > PNG_UINT_32_MAX/png_sizeof(png_bytep)) + png_error (png_ptr, "Image is too tall to process in memory"); + + for (k = 0; k < height; k++) + row_pointers[k] = image + k*width*bytes_per_pixel; + + /* One of the following output methods is REQUIRED */ +#ifdef entire /* write out the entire image data in one call */ + png_write_image(png_ptr, row_pointers); + + /* the other way to write the image - deal with interlacing */ + +#else no_entire /* write out the image data by one or more scanlines */ + /* The number of passes is either 1 for non-interlaced images, + * or 7 for interlaced images. + */ + for (pass = 0; pass < number_passes; pass++) + { + /* Write a few rows at a time. */ + png_write_rows(png_ptr, &row_pointers[first_row], number_of_rows); + + /* If you are only writing one row at a time, this works */ + for (y = 0; y < height; y++) + { + png_write_rows(png_ptr, &row_pointers[y], 1); + } + } +#endif no_entire /* use only one output method */ + + /* You can write optional chunks like tEXt, zTXt, and tIME at the end + * as well. Shouldn't be necessary in 1.1.0 and up as all the public + * chunks are supported and you can use png_set_unknown_chunks() to + * register unknown chunks into the info structure to be written out. + */ + + /* It is REQUIRED to call this to finish writing the rest of the file */ + png_write_end(png_ptr, info_ptr); +#endif hilevel + + /* If you png_malloced a palette, free it here (don't free info_ptr->palette, + as recommended in versions 1.0.5m and earlier of this example; if + libpng mallocs info_ptr->palette, libpng will free it). If you + allocated it with malloc() instead of png_malloc(), use free() instead + of png_free(). */ + png_free(png_ptr, palette); + palette=NULL; + + /* Similarly, if you png_malloced any data that you passed in with + png_set_something(), such as a hist or trans array, free it here, + when you can be sure that libpng is through with it. */ + png_free(png_ptr, trans); + trans=NULL; + + /* clean up after the write, and free any memory allocated */ + png_destroy_write_struct(&png_ptr, &info_ptr); + + /* close the file */ + fclose(fp); + + /* that's it */ + return (OK); +} + +#endif /* if 0 */ diff --git a/mod/pub.mod/libpng.mod/libpng.3 b/mod/pub.mod/libpng.mod/libpng.3 new file mode 100644 index 0000000..8ee76d6 --- /dev/null +++ b/mod/pub.mod/libpng.mod/libpng.3 @@ -0,0 +1,4092 @@ +.TH LIBPNG 3 "June 27, 2006" +.SH NAME +libpng \- Portable Network Graphics (PNG) Reference Library 1.2.12 +.SH SYNOPSIS +\fI\fB + +\fB#include <png.h>\fP + +\fI\fB + +\fBpng_uint_32 png_access_version_number \fI(void\fP\fB);\fP + +\fI\fB + +\fBint png_check_sig (png_bytep \fP\fIsig\fP\fB, int \fInum\fP\fB);\fP + +\fI\fB + +\fBvoid png_chunk_error (png_structp \fP\fIpng_ptr\fP\fB, png_const_charp \fIerror\fP\fB);\fP + +\fI\fB + +\fBvoid png_chunk_warning (png_structp \fP\fIpng_ptr\fP\fB, png_const_charp \fImessage\fP\fB);\fP + +\fI\fB + +\fBvoid png_convert_from_struct_tm (png_timep \fP\fIptime\fP\fB, struct tm FAR * \fIttime\fP\fB);\fP + +\fI\fB + +\fBvoid png_convert_from_time_t (png_timep \fP\fIptime\fP\fB, time_t \fIttime\fP\fB);\fP + +\fI\fB + +\fBpng_charp png_convert_to_rfc1123 (png_structp \fP\fIpng_ptr\fP\fB, png_timep \fIptime\fP\fB);\fP + +\fI\fB + +\fBpng_infop png_create_info_struct (png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fBpng_structp png_create_read_struct (png_const_charp \fP\fIuser_png_ver\fP\fB, png_voidp \fP\fIerror_ptr\fP\fB, png_error_ptr \fP\fIerror_fn\fP\fB, png_error_ptr \fIwarn_fn\fP\fB);\fP + +\fI\fB + +\fBpng_structp png_create_read_struct_2(png_const_charp \fP\fIuser_png_ver\fP\fB, png_voidp \fP\fIerror_ptr\fP\fB, png_error_ptr \fP\fIerror_fn\fP\fB, png_error_ptr \fP\fIwarn_fn\fP\fB, png_voidp \fP\fImem_ptr\fP\fB, png_malloc_ptr \fP\fImalloc_fn\fP\fB, png_free_ptr \fIfree_fn\fP\fB);\fP + +\fI\fB + +\fBpng_structp png_create_write_struct (png_const_charp \fP\fIuser_png_ver\fP\fB, png_voidp \fP\fIerror_ptr\fP\fB, png_error_ptr \fP\fIerror_fn\fP\fB, png_error_ptr \fIwarn_fn\fP\fB);\fP + +\fI\fB + +\fBpng_structp png_create_write_struct_2(png_const_charp \fP\fIuser_png_ver\fP\fB, png_voidp \fP\fIerror_ptr\fP\fB, png_error_ptr \fP\fIerror_fn\fP\fB, png_error_ptr \fP\fIwarn_fn\fP\fB, png_voidp \fP\fImem_ptr\fP\fB, png_malloc_ptr \fP\fImalloc_fn\fP\fB, png_free_ptr \fIfree_fn\fP\fB);\fP + +\fI\fB + +\fBint png_debug(int \fP\fIlevel\fP\fB, png_const_charp \fImessage\fP\fB);\fP + +\fI\fB + +\fBint png_debug1(int \fP\fIlevel\fP\fB, png_const_charp \fP\fImessage\fP\fB, \fIp1\fP\fB);\fP + +\fI\fB + +\fBint png_debug2(int \fP\fIlevel\fP\fB, png_const_charp \fP\fImessage\fP\fB, \fP\fIp1\fP\fB, \fIp2\fP\fB);\fP + +\fI\fB + +\fBvoid png_destroy_info_struct (png_structp \fP\fIpng_ptr\fP\fB, png_infopp \fIinfo_ptr_ptr\fP\fB);\fP + +\fI\fB + +\fBvoid png_destroy_read_struct (png_structpp \fP\fIpng_ptr_ptr\fP\fB, png_infopp \fP\fIinfo_ptr_ptr\fP\fB, png_infopp \fIend_info_ptr_ptr\fP\fB);\fP + +\fI\fB + +\fBvoid png_destroy_write_struct (png_structpp \fP\fIpng_ptr_ptr\fP\fB, png_infopp \fIinfo_ptr_ptr\fP\fB);\fP + +\fI\fB + +\fBvoid png_error (png_structp \fP\fIpng_ptr\fP\fB, png_const_charp \fIerror\fP\fB);\fP + +\fI\fB + +\fBvoid png_free (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fIptr\fP\fB);\fP + +\fI\fB + +\fBvoid png_free_chunk_list (png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fBvoid png_free_default(png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fIptr\fP\fB);\fP + +\fI\fB + +\fBvoid png_free_data (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fInum\fP\fB);\fP + +\fI\fB + +\fBpng_byte png_get_bit_depth (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fI\fB + +\fBpng_uint_32 png_get_bKGD (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_color_16p \fI*background\fP\fB);\fP + +\fI\fB + +\fBpng_byte png_get_channels (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fI\fB + +\fBpng_uint_32 png_get_cHRM (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, double \fP\fI*white_x\fP\fB, double \fP\fI*white_y\fP\fB, double \fP\fI*red_x\fP\fB, double \fP\fI*red_y\fP\fB, double \fP\fI*green_x\fP\fB, double \fP\fI*green_y\fP\fB, double \fP\fI*blue_x\fP\fB, double \fI*blue_y\fP\fB);\fP + +\fI\fB + +\fBpng_uint_32 png_get_cHRM_fixed (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fI*white_x\fP\fB, png_uint_32 \fP\fI*white_y\fP\fB, png_uint_32 \fP\fI*red_x\fP\fB, png_uint_32 \fP\fI*red_y\fP\fB, png_uint_32 \fP\fI*green_x\fP\fB, png_uint_32 \fP\fI*green_y\fP\fB, png_uint_32 \fP\fI*blue_x\fP\fB, png_uint_32 \fI*blue_y\fP\fB);\fP + +\fI\fB + +\fBpng_byte png_get_color_type (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fI\fB + +\fBpng_byte png_get_compression_type (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fI\fB + +\fBpng_byte png_get_copyright (png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fBpng_voidp png_get_error_ptr (png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fBpng_byte png_get_filter_type (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fI\fB + +\fBpng_uint_32 png_get_gAMA (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, double \fI*file_gamma\fP\fB);\fP + +\fI\fB + +\fBpng_uint_32 png_get_gAMA_fixed (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fI*int_file_gamma\fP\fB);\fP + +\fI\fB + +\fBpng_byte png_get_header_ver (png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fBpng_byte png_get_header_version (png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fBpng_uint_32 png_get_hIST (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_16p \fI*hist\fP\fB);\fP + +\fI\fB + +\fBpng_uint_32 png_get_iCCP (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_charpp \fP\fIname\fP\fB, int \fP\fI*compression_type\fP\fB, png_charpp \fP\fIprofile\fP\fB, png_uint_32 \fI*proflen\fP\fB);\fP + +\fI\fB + +\fBpng_uint_32 png_get_IHDR (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fI*width\fP\fB, png_uint_32 \fP\fI*height\fP\fB, int \fP\fI*bit_depth\fP\fB, int \fP\fI*color_type\fP\fB, int \fP\fI*interlace_type\fP\fB, int \fP\fI*compression_type\fP\fB, int \fI*filter_type\fP\fB);\fP + +\fI\fB + +\fBpng_uint_32 png_get_image_height (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fI\fB + +\fBpng_uint_32 png_get_image_width (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fI\fB + +\fB#if \fI!defined(PNG_1_0_X) + +\fBpng_int_32 png_get_int_32 (png_bytep \fIbuf\fP\fB);\fP + +\fI\fB#endif + +\fI\fB + +\fBpng_byte png_get_interlace_type (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fI\fB + +\fBpng_voidp png_get_io_ptr (png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fBpng_byte png_get_libpng_ver (png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fBpng_voidp png_get_mem_ptr(png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fBpng_uint_32 png_get_oFFs (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fI*offset_x\fP\fB, png_uint_32 \fP\fI*offset_y\fP\fB, int \fI*unit_type\fP\fB);\fP + +\fI\fB + +\fBpng_uint_32 png_get_pCAL (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_charp \fP\fI*purpose\fP\fB, png_int_32 \fP\fI*X0\fP\fB, png_int_32 \fP\fI*X1\fP\fB, int \fP\fI*type\fP\fB, int \fP\fI*nparams\fP\fB, png_charp \fP\fI*units\fP\fB, png_charpp \fI*params\fP\fB);\fP + +\fI\fB + +\fBpng_uint_32 png_get_pHYs (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fI*res_x\fP\fB, png_uint_32 \fP\fI*res_y\fP\fB, int \fI*unit_type\fP\fB);\fP + +\fI\fB + +\fBfloat png_get_pixel_aspect_ratio (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fI\fB + +\fBpng_uint_32 png_get_pixels_per_meter (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fI\fB + +\fBpng_voidp png_get_progressive_ptr (png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fBpng_uint_32 png_get_PLTE (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_colorp \fP\fI*palette\fP\fB, int \fI*num_palette\fP\fB);\fP + +\fI\fB + +\fBpng_byte png_get_rgb_to_gray_status (png_structp \fIpng_ptr) + +\fBpng_uint_32 png_get_rowbytes (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fI\fB + +\fBpng_bytepp png_get_rows (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fI\fB + +\fBpng_uint_32 png_get_sBIT (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_color_8p \fI*sig_bit\fP\fB);\fP + +\fI\fB + +\fBpng_bytep png_get_signature (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fI\fB + +\fBpng_uint_32 png_get_sPLT (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_spalette_p \fI*splt_ptr\fP\fB);\fP + +\fI\fB + +\fBpng_uint_32 png_get_sRGB (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fI*intent\fP\fB);\fP + +\fI\fB + +\fBpng_uint_32 png_get_text (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_textp \fP\fI*text_ptr\fP\fB, int \fI*num_text\fP\fB);\fP + +\fI\fB + +\fBpng_uint_32 png_get_tIME (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_timep \fI*mod_time\fP\fB);\fP + +\fI\fB + +\fBpng_uint_32 png_get_tRNS (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_bytep \fP\fI*trans\fP\fB, int \fP\fI*num_trans\fP\fB, png_color_16p \fI*trans_values\fP\fB);\fP + +\fI\fB + +\fB#if \fI!defined(PNG_1_0_X) + +\fBpng_uint_16 png_get_uint_16 (png_bytep \fIbuf\fP\fB);\fP + +\fI\fB + +\fBpng_uint_32 png_get_uint_31 (png_bytep \fIbuf\fP\fB);\fP + +\fI\fB + +\fBpng_uint_32 png_get_uint_32 (png_bytep \fIbuf\fP\fB);\fP + +\fI\fB#endif + +\fI\fB + +\fBpng_uint_32 png_get_unknown_chunks (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_unknown_chunkpp \fIunknowns\fP\fB);\fP + +\fI\fB + +\fBpng_voidp png_get_user_chunk_ptr (png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fBpng_uint_32 png_get_user_height_max( png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fBpng_voidp png_get_user_transform_ptr (png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fBpng_uint_32 png_get_user_width_max (png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fBpng_uint_32 png_get_valid (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIflag\fP\fB);\fP + +\fI\fB + +\fBpng_int_32 png_get_x_offset_microns (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fI\fB + +\fBpng_int_32 png_get_x_offset_pixels (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fI\fB + +\fBpng_uint_32 png_get_x_pixels_per_meter (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fI\fB + +\fBpng_int_32 png_get_y_offset_microns (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fI\fB + +\fBpng_int_32 png_get_y_offset_pixels (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fI\fB + +\fBpng_uint_32 png_get_y_pixels_per_meter (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fI\fB + +\fBpng_uint_32 png_get_compression_buffer_size (png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fBint png_handle_as_unknown (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fIchunk_name\fP\fB);\fP + +\fI\fB + +\fBvoid png_init_io (png_structp \fP\fIpng_ptr\fP\fB, FILE \fI*fp\fP\fB);\fP + +\fI\fB + +\fBDEPRECATED: void png_info_init (png_infop \fIinfo_ptr\fP\fB);\fP + +\fI\fB + +\fBDEPRECATED: void png_info_init_2 (png_infopp \fP\fIptr_ptr\fP\fB, png_size_t \fIpng_info_struct_size\fP\fB);\fP + +\fI\fB + +\fBpng_voidp png_malloc (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fIsize\fP\fB);\fP + +\fI\fB + +\fBpng_voidp png_malloc_default(png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fIsize\fP\fB);\fP + +\fI\fB + +\fBvoidp png_memcpy (png_voidp \fP\fIs1\fP\fB, png_voidp \fP\fIs2\fP\fB, png_size_t \fIsize\fP\fB);\fP + +\fI\fB + +\fBpng_voidp png_memcpy_check (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIs1\fP\fB, png_voidp \fP\fIs2\fP\fB, png_uint_32 \fIsize\fP\fB);\fP + +\fI\fB + +\fBvoidp png_memset (png_voidp \fP\fIs1\fP\fB, int \fP\fIvalue\fP\fB, png_size_t \fIsize\fP\fB);\fP + +\fI\fB + +\fBpng_voidp png_memset_check (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIs1\fP\fB, int \fP\fIvalue\fP\fB, png_uint_32 \fIsize\fP\fB);\fP + +\fI\fB + +\fBDEPRECATED: void png_permit_empty_plte (png_structp \fP\fIpng_ptr\fP\fB, int \fIempty_plte_permitted\fP\fB);\fP + +\fI\fB + +\fBvoid png_process_data (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_bytep \fP\fIbuffer\fP\fB, png_size_t \fIbuffer_size\fP\fB);\fP + +\fI\fB + +\fBvoid png_progressive_combine_row (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIold_row\fP\fB, png_bytep \fInew_row\fP\fB);\fP + +\fI\fB + +\fBvoid png_read_destroy (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_infop \fIend_info_ptr\fP\fB);\fP + +\fI\fB + +\fBvoid png_read_end (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fI\fB + +\fBvoid png_read_image (png_structp \fP\fIpng_ptr\fP\fB, png_bytepp \fIimage\fP\fB);\fP + +\fI\fB + +\fBDEPRECATED: void png_read_init (png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fBDEPRECATED: void png_read_init_2 (png_structpp \fP\fIptr_ptr\fP\fB, png_const_charp \fP\fIuser_png_ver\fP\fB, png_size_t \fP\fIpng_struct_size\fP\fB, png_size_t \fIpng_info_size\fP\fB);\fP + +\fI\fB + +\fBvoid png_read_info (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fI\fB + +\fBvoid png_read_png (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fP\fItransforms\fP\fB, png_voidp \fIparams\fP\fB);\fP + +\fI\fB + +\fBvoid png_read_row (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIrow\fP\fB, png_bytep \fIdisplay_row\fP\fB);\fP + +\fI\fB + +\fBvoid png_read_rows (png_structp \fP\fIpng_ptr\fP\fB, png_bytepp \fP\fIrow\fP\fB, png_bytepp \fP\fIdisplay_row\fP\fB, png_uint_32 \fInum_rows\fP\fB);\fP + +\fI\fB + +\fBvoid png_read_update_info (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fI\fB + +\fB#if \fI!defined(PNG_1_0_X) + +\fBpng_save_int_32 (png_bytep \fP\fIbuf\fP\fB, png_int_32 \fIi\fP\fB);\fP + +\fI\fB + +\fBvoid png_save_uint_16 (png_bytep \fP\fIbuf\fP\fB, unsigned int \fIi\fP\fB);\fP + +\fI\fB + +\fBvoid png_save_uint_32 (png_bytep \fP\fIbuf\fP\fB, png_uint_32 \fIi\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_add_alpha (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fP\fIfiller\fP\fB, int \fIflags\fP\fB);\fP + +\fI\fB#endif + +\fI\fB + +\fBvoid png_set_background (png_structp \fP\fIpng_ptr\fP\fB, png_color_16p \fP\fIbackground_color\fP\fB, int \fP\fIbackground_gamma_code\fP\fB, int \fP\fIneed_expand\fP\fB, double \fIbackground_gamma\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_bgr (png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_bKGD (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_color_16p \fIbackground\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_cHRM (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, double \fP\fIwhite_x\fP\fB, double \fP\fIwhite_y\fP\fB, double \fP\fIred_x\fP\fB, double \fP\fIred_y\fP\fB, double \fP\fIgreen_x\fP\fB, double \fP\fIgreen_y\fP\fB, double \fP\fIblue_x\fP\fB, double \fIblue_y\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_cHRM_fixed (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fIwhite_x\fP\fB, png_uint_32 \fP\fIwhite_y\fP\fB, png_uint_32 \fP\fIred_x\fP\fB, png_uint_32 \fP\fIred_y\fP\fB, png_uint_32 \fP\fIgreen_x\fP\fB, png_uint_32 \fP\fIgreen_y\fP\fB, png_uint_32 \fP\fIblue_x\fP\fB, png_uint_32 \fIblue_y\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_compression_level (png_structp \fP\fIpng_ptr\fP\fB, int \fIlevel\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_compression_mem_level (png_structp \fP\fIpng_ptr\fP\fB, int \fImem_level\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_compression_method (png_structp \fP\fIpng_ptr\fP\fB, int \fImethod\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_compression_strategy (png_structp \fP\fIpng_ptr\fP\fB, int \fIstrategy\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_compression_window_bits (png_structp \fP\fIpng_ptr\fP\fB, int \fIwindow_bits\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_crc_action (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fIcrit_action\fP\fB, int \fIancil_action\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_dither (png_structp \fP\fIpng_ptr\fP\fB, png_colorp \fP\fIpalette\fP\fB, int \fP\fInum_palette\fP\fB, int \fP\fImaximum_colors\fP\fB, png_uint_16p \fP\fIhistogram\fP\fB, int \fIfull_dither\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_error_fn (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIerror_ptr\fP\fB, png_error_ptr \fP\fIerror_fn\fP\fB, png_error_ptr \fIwarning_fn\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_expand (png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_expand_gray_1_2_4_to_8(png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_filler (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fP\fIfiller\fP\fB, int \fIflags\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_filter (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fImethod\fP\fB, int \fIfilters\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_filter_heuristics (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fIheuristic_method\fP\fB, int \fP\fInum_weights\fP\fB, png_doublep \fP\fIfilter_weights\fP\fB, png_doublep \fIfilter_costs\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_flush (png_structp \fP\fIpng_ptr\fP\fB, int \fInrows\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_gamma (png_structp \fP\fIpng_ptr\fP\fB, double \fP\fIscreen_gamma\fP\fB, double \fIdefault_file_gamma\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_gAMA (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, double \fIfile_gamma\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_gAMA_fixed (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIfile_gamma\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_gray_1_2_4_to_8(png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_gray_to_rgb (png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_hIST (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_16p \fIhist\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_iCCP (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_charp \fP\fIname\fP\fB, int \fP\fIcompression_type\fP\fB, png_charp \fP\fIprofile\fP\fB, png_uint_32 \fIproflen\fP\fB);\fP + +\fI\fB + +\fBint png_set_interlace_handling (png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_invalid (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fImask\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_invert_alpha (png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_invert_mono (png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_IHDR (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fIwidth\fP\fB, png_uint_32 \fP\fIheight\fP\fB, int \fP\fIbit_depth\fP\fB, int \fP\fIcolor_type\fP\fB, int \fP\fIinterlace_type\fP\fB, int \fP\fIcompression_type\fP\fB, int \fIfilter_type\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_keep_unknown_chunks (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fIkeep\fP\fB, png_bytep \fP\fIchunk_list\fP\fB, int \fInum_chunks\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_mem_fn(png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fImem_ptr\fP\fB, png_malloc_ptr \fP\fImalloc_fn\fP\fB, png_free_ptr \fIfree_fn\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_oFFs (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fIoffset_x\fP\fB, png_uint_32 \fP\fIoffset_y\fP\fB, int \fIunit_type\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_packing (png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_packswap (png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_palette_to_rgb(png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_pCAL (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_charp \fP\fIpurpose\fP\fB, png_int_32 \fP\fIX0\fP\fB, png_int_32 \fP\fIX1\fP\fB, int \fP\fItype\fP\fB, int \fP\fInparams\fP\fB, png_charp \fP\fIunits\fP\fB, png_charpp \fIparams\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_pHYs (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fIres_x\fP\fB, png_uint_32 \fP\fIres_y\fP\fB, int \fIunit_type\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_progressive_read_fn (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIprogressive_ptr\fP\fB, png_progressive_info_ptr \fP\fIinfo_fn\fP\fB, png_progressive_row_ptr \fP\fIrow_fn\fP\fB, png_progressive_end_ptr \fIend_fn\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_PLTE (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_colorp \fP\fIpalette\fP\fB, int \fInum_palette\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_read_fn (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIio_ptr\fP\fB, png_rw_ptr \fIread_data_fn\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_read_status_fn (png_structp \fP\fIpng_ptr\fP\fB, png_read_status_ptr \fIread_row_fn\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_read_user_transform_fn (png_structp \fP\fIpng_ptr\fP\fB, png_user_transform_ptr \fIread_user_transform_fn\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_rgb_to_gray (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fIerror_action\fP\fB, double \fP\fIred\fP\fB, double \fIgreen\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_rgb_to_gray_fixed (png_structp \fP\fIpng_ptr\fP\fB, int error_action png_fixed_point \fP\fIred\fP\fB, png_fixed_point \fIgreen\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_rows (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_bytepp \fIrow_pointers\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_sBIT (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_color_8p \fIsig_bit\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_sCAL (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_charp \fP\fIunit\fP\fB, double \fP\fIwidth\fP\fB, double \fIheight\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_shift (png_structp \fP\fIpng_ptr\fP\fB, png_color_8p \fItrue_bits\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_sig_bytes (png_structp \fP\fIpng_ptr\fP\fB, int \fInum_bytes\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_sPLT (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_spalette_p \fP\fIsplt_ptr\fP\fB, int \fInum_spalettes\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_sRGB (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fIintent\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_sRGB_gAMA_and_cHRM (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fIintent\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_strip_16 (png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_strip_alpha (png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_swap (png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_swap_alpha (png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_text (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_textp \fP\fItext_ptr\fP\fB, int \fInum_text\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_tIME (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_timep \fImod_time\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_tRNS (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_bytep \fP\fItrans\fP\fB, int \fP\fInum_trans\fP\fB, png_color_16p \fItrans_values\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_tRNS_to_alpha(png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fBpng_uint_32 png_set_unknown_chunks (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_unknown_chunkp \fP\fIunknowns\fP\fB, int \fP\fInum\fP\fB, int \fIlocation\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_unknown_chunk_location(png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fP\fIchunk\fP\fB, int \fIlocation\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_read_user_chunk_fn (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIuser_chunk_ptr\fP\fB, png_user_chunk_ptr \fIread_user_chunk_fn\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_user_limits (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fP\fIuser_width_max\fP\fB, png_uint_32 \fIuser_height_max\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_user_transform_info (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIuser_transform_ptr\fP\fB, int \fP\fIuser_transform_depth\fP\fB, int \fIuser_transform_channels\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_write_fn (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIio_ptr\fP\fB, png_rw_ptr \fP\fIwrite_data_fn\fP\fB, png_flush_ptr \fIoutput_flush_fn\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_write_status_fn (png_structp \fP\fIpng_ptr\fP\fB, png_write_status_ptr \fIwrite_row_fn\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_write_user_transform_fn (png_structp \fP\fIpng_ptr\fP\fB, png_user_transform_ptr \fIwrite_user_transform_fn\fP\fB);\fP + +\fI\fB + +\fBvoid png_set_compression_buffer_size(png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fIsize\fP\fB);\fP + +\fI\fB + +\fBint png_sig_cmp (png_bytep \fP\fIsig\fP\fB, png_size_t \fP\fIstart\fP\fB, png_size_t \fInum_to_check\fP\fB);\fP + +\fI\fB + +\fBvoid png_start_read_image (png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fBvoid png_warning (png_structp \fP\fIpng_ptr\fP\fB, png_const_charp \fImessage\fP\fB);\fP + +\fI\fB + +\fBvoid png_write_chunk (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIchunk_name\fP\fB, png_bytep \fP\fIdata\fP\fB, png_size_t \fIlength\fP\fB);\fP + +\fI\fB + +\fBvoid png_write_chunk_data (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIdata\fP\fB, png_size_t \fIlength\fP\fB);\fP + +\fI\fB + +\fBvoid png_write_chunk_end (png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fBvoid png_write_chunk_start (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIchunk_name\fP\fB, png_uint_32 \fIlength\fP\fB);\fP + +\fI\fB + +\fBvoid png_write_destroy (png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fBvoid png_write_end (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fI\fB + +\fBvoid png_write_flush (png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fBvoid png_write_image (png_structp \fP\fIpng_ptr\fP\fB, png_bytepp \fIimage\fP\fB);\fP + +\fI\fB + +\fBDEPRECATED: void png_write_init (png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fBDEPRECATED: void png_write_init_2 (png_structpp \fP\fIptr_ptr\fP\fB, png_const_charp \fP\fIuser_png_ver\fP\fB, png_size_t \fP\fIpng_struct_size\fP\fB, png_size_t \fIpng_info_size\fP\fB);\fP + +\fI\fB + +\fBvoid png_write_info (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fI\fB + +\fBvoid png_write_info_before_PLTE (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fI\fB + +\fBvoid png_write_png (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fP\fItransforms\fP\fB, png_voidp \fIparams\fP\fB);\fP + +\fI\fB + +\fBvoid png_write_row (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fIrow\fP\fB);\fP + +\fI\fB + +\fBvoid png_write_rows (png_structp \fP\fIpng_ptr\fP\fB, png_bytepp \fP\fIrow\fP\fB, png_uint_32 \fInum_rows\fP\fB);\fP + +\fI\fB + +\fBvoidpf png_zalloc (voidpf \fP\fIpng_ptr\fP\fB, uInt \fP\fIitems\fP\fB, uInt \fIsize\fP\fB);\fP + +\fI\fB + +\fBvoid png_zfree (voidpf \fP\fIpng_ptr\fP\fB, voidpf \fIptr\fP\fB);\fP + +\fI\fB + +.SH DESCRIPTION +The +.I libpng +library supports encoding, decoding, and various manipulations of +the Portable Network Graphics (PNG) format image files. It uses the +.IR zlib(3) +compression library. +Following is a copy of the libpng.txt file that accompanies libpng. +.SH LIBPNG.TXT +libpng.txt - A description on how to use and modify libpng + + libpng version 1.2.12 - June 27, 2006 + Updated and distributed by Glenn Randers-Pehrson + <glennrp at users.sourceforge.net> + Copyright (c) 1998-2005 Glenn Randers-Pehrson + For conditions of distribution and use, see copyright + notice in png.h. + + based on: + + libpng 1.0 beta 6 version 0.96 May 28, 1997 + Updated and distributed by Andreas Dilger + Copyright (c) 1996, 1997 Andreas Dilger + + libpng 1.0 beta 2 - version 0.88 January 26, 1996 + For conditions of distribution and use, see copyright + notice in png.h. Copyright (c) 1995, 1996 Guy Eric + Schalnat, Group 42, Inc. + + Updated/rewritten per request in the libpng FAQ + Copyright (c) 1995, 1996 Frank J. T. Wojcik + December 18, 1995 & January 20, 1996 + +.SH I. Introduction + +This file describes how to use and modify the PNG reference library +(known as libpng) for your own use. There are five sections to this +file: introduction, structures, reading, writing, and modification and +configuration notes for various special platforms. In addition to this +file, example.c is a good starting point for using the library, as +it is heavily commented and should include everything most people +will need. We assume that libpng is already installed; see the +INSTALL file for instructions on how to install libpng. + +Libpng was written as a companion to the PNG specification, as a way +of reducing the amount of time and effort it takes to support the PNG +file format in application programs. + +The PNG specification (second edition), November 2003, is available as +a W3C Recommendation and as an ISO Standard (ISO/IEC 15948:2003 (E)) at +<http://www.w3.org/TR/2003/REC-PNG-20031110/ +The W3C and ISO documents have identical technical content. + +The PNG-1.2 specification is available at +<http://www.libpng.org/pub/png/documents/> + +The PNG-1.0 specification is available +as RFC 2083 <http://www.libpng.org/pub/png/documents/> and as a +W3C Recommendation <http://www.w3.org/TR/REC.png.html>. Some +additional chunks are described in the special-purpose public chunks +documents at <http://www.libpng.org/pub/png/documents/>. + +Other information +about PNG, and the latest version of libpng, can be found at the PNG home +page, <http://www.libpng.org/pub/png/>. + +Most users will not have to modify the library significantly; advanced +users may want to modify it more. All attempts were made to make it as +complete as possible, while keeping the code easy to understand. +Currently, this library only supports C. Support for other languages +is being considered. + +Libpng has been designed to handle multiple sessions at one time, +to be easily modifiable, to be portable to the vast majority of +machines (ANSI, K&R, 16-, 32-, and 64-bit) available, and to be easy +to use. The ultimate goal of libpng is to promote the acceptance of +the PNG file format in whatever way possible. While there is still +work to be done (see the TODO file), libpng should cover the +majority of the needs of its users. + +Libpng uses zlib for its compression and decompression of PNG files. +Further information about zlib, and the latest version of zlib, can +be found at the zlib home page, <http://www.info-zip.org/pub/infozip/zlib/>. +The zlib compression utility is a general purpose utility that is +useful for more than PNG files, and can be used without libpng. +See the documentation delivered with zlib for more details. +You can usually find the source files for the zlib utility wherever you +find the libpng source files. + +Libpng is thread safe, provided the threads are using different +instances of the structures. Each thread should have its own +png_struct and png_info instances, and thus its own image. +Libpng does not protect itself against two threads using the +same instance of a structure. Note: thread safety may be defeated +by use of some of the MMX assembler code in pnggccrd.c, which is only +compiled when the user defines PNG_THREAD_UNSAFE_OK. + +.SH II. Structures + +There are two main structures that are important to libpng, png_struct +and png_info. The first, png_struct, is an internal structure that +will not, for the most part, be used by a user except as the first +variable passed to every libpng function call. + +The png_info structure is designed to provide information about the +PNG file. At one time, the fields of png_info were intended to be +directly accessible to the user. However, this tended to cause problems +with applications using dynamically loaded libraries, and as a result +a set of interface functions for png_info (the png_get_*() and png_set_*() +functions) was developed. The fields of png_info are still available for +older applications, but it is suggested that applications use the new +interfaces if at all possible. + +Applications that do make direct access to the members of png_struct (except +for png_ptr->jmpbuf) must be recompiled whenever the library is updated, +and applications that make direct access to the members of png_info must +be recompiled if they were compiled or loaded with libpng version 1.0.6, +in which the members were in a different order. In version 1.0.7, the +members of the png_info structure reverted to the old order, as they were +in versions 0.97c through 1.0.5. Starting with version 2.0.0, both +structures are going to be hidden, and the contents of the structures will +only be accessible through the png_get/png_set functions. + +The png.h header file is an invaluable reference for programming with libpng. +And while I'm on the topic, make sure you include the libpng header file: + +#include <png.h> + +.SH III. Reading + +We'll now walk you through the possible functions to call when reading +in a PNG file sequentially, briefly explaining the syntax and purpose +of each one. See example.c and png.h for more detail. While +progressive reading is covered in the next section, you will still +need some of the functions discussed in this section to read a PNG +file. + +.SS Setup + +You will want to do the I/O initialization(*) before you get into libpng, +so if it doesn't work, you don't have much to undo. Of course, you +will also want to insure that you are, in fact, dealing with a PNG +file. Libpng provides a simple check to see if a file is a PNG file. +To use it, pass in the first 1 to 8 bytes of the file to the function +png_sig_cmp(), and it will return 0 if the bytes match the corresponding +bytes of the PNG signature, or nonzero otherwise. Of course, the more bytes +you pass in, the greater the accuracy of the prediction. + +If you are intending to keep the file pointer open for use in libpng, +you must ensure you don't read more than 8 bytes from the beginning +of the file, and you also have to make a call to png_set_sig_bytes_read() +with the number of bytes you read from the beginning. Libpng will +then only check the bytes (if any) that your program didn't read. + +(*): If you are not using the standard I/O functions, you will need +to replace them with custom functions. See the discussion under +Customizing libpng. + + + FILE *fp = fopen(file_name, "rb"); + if (!fp) + { + return (ERROR); + } + fread(header, 1, number, fp); + is_png = !png_sig_cmp(header, 0, number); + if (!is_png) + { + return (NOT_PNG); + } + + +Next, png_struct and png_info need to be allocated and initialized. In +order to ensure that the size of these structures is correct even with a +dynamically linked libpng, there are functions to initialize and +allocate the structures. We also pass the library version, optional +pointers to error handling functions, and a pointer to a data struct for +use by the error functions, if necessary (the pointer and functions can +be NULL if the default error handlers are to be used). See the section +on Changes to Libpng below regarding the old initialization functions. +The structure allocation functions quietly return NULL if they fail to +create the structure, so your application should check for that. + + png_structp png_ptr = png_create_read_struct + (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr, + user_error_fn, user_warning_fn); + if (!png_ptr) + return (ERROR); + + png_infop info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) + { + png_destroy_read_struct(&png_ptr, + (png_infopp)NULL, (png_infopp)NULL); + return (ERROR); + } + + png_infop end_info = png_create_info_struct(png_ptr); + if (!end_info) + { + png_destroy_read_struct(&png_ptr, &info_ptr, + (png_infopp)NULL); + return (ERROR); + } + +If you want to use your own memory allocation routines, +define PNG_USER_MEM_SUPPORTED and use +png_create_read_struct_2() instead of png_create_read_struct(): + + png_structp png_ptr = png_create_read_struct_2 + (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr, + user_error_fn, user_warning_fn, (png_voidp) + user_mem_ptr, user_malloc_fn, user_free_fn); + +The error handling routines passed to png_create_read_struct() +and the memory alloc/free routines passed to png_create_struct_2() +are only necessary if you are not using the libpng supplied error +handling and memory alloc/free functions. + +When libpng encounters an error, it expects to longjmp back +to your routine. Therefore, you will need to call setjmp and pass +your png_jmpbuf(png_ptr). If you read the file from different +routines, you will need to update the jmpbuf field every time you enter +a new routine that will call a png_*() function. + +See your documentation of setjmp/longjmp for your compiler for more +information on setjmp/longjmp. See the discussion on libpng error +handling in the Customizing Libpng section below for more information +on the libpng error handling. If an error occurs, and libpng longjmp's +back to your setjmp, you will want to call png_destroy_read_struct() to +free any memory. + + if (setjmp(png_jmpbuf(png_ptr))) + { + png_destroy_read_struct(&png_ptr, &info_ptr, + &end_info); + fclose(fp); + return (ERROR); + } + +If you would rather avoid the complexity of setjmp/longjmp issues, +you can compile libpng with PNG_SETJMP_NOT_SUPPORTED, in which case +errors will result in a call to PNG_ABORT() which defaults to abort(). + +Now you need to set up the input code. The default for libpng is to +use the C function fread(). If you use this, you will need to pass a +valid FILE * in the function png_init_io(). Be sure that the file is +opened in binary mode. If you wish to handle reading data in another +way, you need not call the png_init_io() function, but you must then +implement the libpng I/O methods discussed in the Customizing Libpng +section below. + + png_init_io(png_ptr, fp); + +If you had previously opened the file and read any of the signature from +the beginning in order to see if this was a PNG file, you need to let +libpng know that there are some bytes missing from the start of the file. + + png_set_sig_bytes(png_ptr, number); + +.SS Setting up callback code + +You can set up a callback function to handle any unknown chunks in the +input stream. You must supply the function + + read_chunk_callback(png_ptr ptr, + png_unknown_chunkp chunk); + { + /* The unknown chunk structure contains your + chunk data: */ + png_byte name[5]; + png_byte *data; + png_size_t size; + /* Note that libpng has already taken care of + the CRC handling */ + + /* put your code here. Return one of the + following: */ + + return (-n); /* chunk had an error */ + return (0); /* did not recognize */ + return (n); /* success */ + } + +(You can give your function another name that you like instead of +"read_chunk_callback") + +To inform libpng about your function, use + + png_set_read_user_chunk_fn(png_ptr, user_chunk_ptr, + read_chunk_callback); + +This names not only the callback function, but also a user pointer that +you can retrieve with + + png_get_user_chunk_ptr(png_ptr); + +At this point, you can set up a callback function that will be +called after each row has been read, which you can use to control +a progress meter or the like. It's demonstrated in pngtest.c. +You must supply a function + + void read_row_callback(png_ptr ptr, png_uint_32 row, + int pass); + { + /* put your code here */ + } + +(You can give it another name that you like instead of "read_row_callback") + +To inform libpng about your function, use + + png_set_read_status_fn(png_ptr, read_row_callback); + +.SS Width and height limits + +The PNG specification allows the width and height of an image to be as +large as 2^31-1 (0x7fffffff), or about 2.147 billion rows and columns. +Since very few applications really need to process such large images, +we have imposed an arbitrary 1-million limit on rows and columns. +Larger images will be rejected immediately with a png_error() call. If +you wish to override this limit, you can use + + png_set_user_limits(png_ptr, width_max, height_max); + +to set your own limits, or use width_max = height_max = 0x7fffffffL +to allow all valid dimensions (libpng may reject some very large images +anyway because of potential buffer overflow conditions). + +You should put this statement after you create the PNG structure and +before calling png_read_info(), png_read_png(), or png_process_data(). +If you need to retrieve the limits that are being applied, use + + width_max = png_get_user_width_max(png_ptr); + height_max = png_get_user_height_max(png_ptr); + +.SS Unknown-chunk handling + +Now you get to set the way the library processes unknown chunks in the +input PNG stream. Both known and unknown chunks will be read. Normal +behavior is that known chunks will be parsed into information in +various info_ptr members; unknown chunks will be discarded. To change +this, you can call: + + png_set_keep_unknown_chunks(png_ptr, keep, + chunk_list, num_chunks); + keep - 0: do not handle as unknown + 1: do not keep + 2: keep only if safe-to-copy + 3: keep even if unsafe-to-copy + You can use these definitions: + PNG_HANDLE_CHUNK_AS_DEFAULT 0 + PNG_HANDLE_CHUNK_NEVER 1 + PNG_HANDLE_CHUNK_IF_SAFE 2 + PNG_HANDLE_CHUNK_ALWAYS 3 + chunk_list - list of chunks affected (a byte string, + five bytes per chunk, NULL or '\0' if + num_chunks is 0) + num_chunks - number of chunks affected; if 0, all + unknown chunks are affected. If nonzero, + only the chunks in the list are affected + +Unknown chunks declared in this way will be saved as raw data onto a +list of png_unknown_chunk structures. If a chunk that is normally +known to libpng is named in the list, it will be handled as unknown, +according to the "keep" directive. If a chunk is named in successive +instances of png_set_keep_unknown_chunks(), the final instance will +take precedence. The IHDR and IEND chunks should not be named in +chunk_list; if they are, libpng will process them normally anyway. + +.SS The high-level read interface + +At this point there are two ways to proceed; through the high-level +read interface, or through a sequence of low-level read operations. +You can use the high-level interface if (a) you are willing to read +the entire image into memory, and (b) the input transformations +you want to do are limited to the following set: + + PNG_TRANSFORM_IDENTITY No transformation + PNG_TRANSFORM_STRIP_16 Strip 16-bit samples to + 8 bits + PNG_TRANSFORM_STRIP_ALPHA Discard the alpha channel + PNG_TRANSFORM_PACKING Expand 1, 2 and 4-bit + samples to bytes + PNG_TRANSFORM_PACKSWAP Change order of packed + pixels to LSB first + PNG_TRANSFORM_EXPAND Perform set_expand() + PNG_TRANSFORM_INVERT_MONO Invert monochrome images + PNG_TRANSFORM_SHIFT Normalize pixels to the + sBIT depth + PNG_TRANSFORM_BGR Flip RGB to BGR, RGBA + to BGRA + PNG_TRANSFORM_SWAP_ALPHA Flip RGBA to ARGB or GA + to AG + PNG_TRANSFORM_INVERT_ALPHA Change alpha from opacity + to transparency + PNG_TRANSFORM_SWAP_ENDIAN Byte-swap 16-bit samples + +(This excludes setting a background color, doing gamma transformation, +dithering, and setting filler.) If this is the case, simply do this: + + png_read_png(png_ptr, info_ptr, png_transforms, NULL) + +where png_transforms is an integer containing the logical OR of +some set of transformation flags. This call is equivalent to png_read_info(), +followed the set of transformations indicated by the transform mask, +then png_read_image(), and finally png_read_end(). + +(The final parameter of this call is not yet used. Someday it might point +to transformation parameters required by some future input transform.) + +You must use png_transforms and not call any png_set_transform() functions +when you use png_read_png(). + +After you have called png_read_png(), you can retrieve the image data +with + + row_pointers = png_get_rows(png_ptr, info_ptr); + +where row_pointers is an array of pointers to the pixel data for each row: + + png_bytep row_pointers[height]; + +If you know your image size and pixel size ahead of time, you can allocate +row_pointers prior to calling png_read_png() with + + if (height > PNG_UINT_32_MAX/png_sizeof(png_byte)) + png_error (png_ptr, + "Image is too tall to process in memory"); + if (width > PNG_UINT_32_MAX/pixel_size) + png_error (png_ptr, + "Image is too wide to process in memory"); + row_pointers = png_malloc(png_ptr, + height*png_sizeof(png_bytep)); + for (int i=0; i<height, i++) + row_pointers[i]=png_malloc(png_ptr, + width*pixel_size); + png_set_rows(png_ptr, info_ptr, &row_pointers); + +Alternatively you could allocate your image in one big block and define +row_pointers[i] to point into the proper places in your block. + +If you use png_set_rows(), the application is responsible for freeing +row_pointers (and row_pointers[i], if they were separately allocated). + +If you don't allocate row_pointers ahead of time, png_read_png() will +do it, and it'll be free'ed when you call png_destroy_*(). + +.SS The low-level read interface + +If you are going the low-level route, you are now ready to read all +the file information up to the actual image data. You do this with a +call to png_read_info(). + + png_read_info(png_ptr, info_ptr); + +This will process all chunks up to but not including the image data. + +.SS Querying the info structure + +Functions are used to get the information from the info_ptr once it +has been read. Note that these fields may not be completely filled +in until png_read_end() has read the chunk data following the image. + + png_get_IHDR(png_ptr, info_ptr, &width, &height, + &bit_depth, &color_type, &interlace_type, + &compression_type, &filter_method); + + width - holds the width of the image + in pixels (up to 2^31). + height - holds the height of the image + in pixels (up to 2^31). + bit_depth - holds the bit depth of one of the + image channels. (valid values are + 1, 2, 4, 8, 16 and depend also on + the color_type. See also + significant bits (sBIT) below). + color_type - describes which color/alpha channels + are present. + PNG_COLOR_TYPE_GRAY + (bit depths 1, 2, 4, 8, 16) + PNG_COLOR_TYPE_GRAY_ALPHA + (bit depths 8, 16) + PNG_COLOR_TYPE_PALETTE + (bit depths 1, 2, 4, 8) + PNG_COLOR_TYPE_RGB + (bit_depths 8, 16) + PNG_COLOR_TYPE_RGB_ALPHA + (bit_depths 8, 16) + + PNG_COLOR_MASK_PALETTE + PNG_COLOR_MASK_COLOR + PNG_COLOR_MASK_ALPHA + + filter_method - (must be PNG_FILTER_TYPE_BASE + for PNG 1.0, and can also be + PNG_INTRAPIXEL_DIFFERENCING if + the PNG datastream is embedded in + a MNG-1.0 datastream) + compression_type - (must be PNG_COMPRESSION_TYPE_BASE + for PNG 1.0) + interlace_type - (PNG_INTERLACE_NONE or + PNG_INTERLACE_ADAM7) + Any or all of interlace_type, compression_type, of + filter_method can be NULL if you are + not interested in their values. + + channels = png_get_channels(png_ptr, info_ptr); + channels - number of channels of info for the + color type (valid values are 1 (GRAY, + PALETTE), 2 (GRAY_ALPHA), 3 (RGB), + 4 (RGB_ALPHA or RGB + filler byte)) + rowbytes = png_get_rowbytes(png_ptr, info_ptr); + rowbytes - number of bytes needed to hold a row + + signature = png_get_signature(png_ptr, info_ptr); + signature - holds the signature read from the + file (if any). The data is kept in + the same offset it would be if the + whole signature were read (i.e. if an + application had already read in 4 + bytes of signature before starting + libpng, the remaining 4 bytes would + be in signature[4] through signature[7] + (see png_set_sig_bytes())). + + + width = png_get_image_width(png_ptr, + info_ptr); + height = png_get_image_height(png_ptr, + info_ptr); + bit_depth = png_get_bit_depth(png_ptr, + info_ptr); + color_type = png_get_color_type(png_ptr, + info_ptr); + filter_method = png_get_filter_type(png_ptr, + info_ptr); + compression_type = png_get_compression_type(png_ptr, + info_ptr); + interlace_type = png_get_interlace_type(png_ptr, + info_ptr); + + +These are also important, but their validity depends on whether the chunk +has been read. The png_get_valid(png_ptr, info_ptr, PNG_INFO_<chunk>) and +png_get_<chunk>(png_ptr, info_ptr, ...) functions return non-zero if the +data has been read, or zero if it is missing. The parameters to the +png_get_<chunk> are set directly if they are simple data types, or a pointer +into the info_ptr is returned for any complex types. + + png_get_PLTE(png_ptr, info_ptr, &palette, + &num_palette); + palette - the palette for the file + (array of png_color) + num_palette - number of entries in the palette + + png_get_gAMA(png_ptr, info_ptr, &gamma); + gamma - the gamma the file is written + at (PNG_INFO_gAMA) + + png_get_sRGB(png_ptr, info_ptr, &srgb_intent); + srgb_intent - the rendering intent (PNG_INFO_sRGB) + The presence of the sRGB chunk + means that the pixel data is in the + sRGB color space. This chunk also + implies specific values of gAMA and + cHRM. + + png_get_iCCP(png_ptr, info_ptr, &name, + &compression_type, &profile, &proflen); + name - The profile name. + compression - The compression type; always + PNG_COMPRESSION_TYPE_BASE for PNG 1.0. + You may give NULL to this argument to + ignore it. + profile - International Color Consortium color + profile data. May contain NULs. + proflen - length of profile data in bytes. + + png_get_sBIT(png_ptr, info_ptr, &sig_bit); + sig_bit - the number of significant bits for + (PNG_INFO_sBIT) each of the gray, + red, green, and blue channels, + whichever are appropriate for the + given color type (png_color_16) + + png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, + &trans_values); + trans - array of transparent entries for + palette (PNG_INFO_tRNS) + trans_values - graylevel or color sample values of + the single transparent color for + non-paletted images (PNG_INFO_tRNS) + num_trans - number of transparent entries + (PNG_INFO_tRNS) + + png_get_hIST(png_ptr, info_ptr, &hist); + (PNG_INFO_hIST) + hist - histogram of palette (array of + png_uint_16) + + png_get_tIME(png_ptr, info_ptr, &mod_time); + mod_time - time image was last modified + (PNG_VALID_tIME) + + png_get_bKGD(png_ptr, info_ptr, &background); + background - background color (PNG_VALID_bKGD) + valid 16-bit red, green and blue + values, regardless of color_type + + num_comments = png_get_text(png_ptr, info_ptr, + &text_ptr, &num_text); + num_comments - number of comments + text_ptr - array of png_text holding image + comments + text_ptr[i].compression - type of compression used + on "text" PNG_TEXT_COMPRESSION_NONE + PNG_TEXT_COMPRESSION_zTXt + PNG_ITXT_COMPRESSION_NONE + PNG_ITXT_COMPRESSION_zTXt + text_ptr[i].key - keyword for comment. Must contain + 1-79 characters. + text_ptr[i].text - text comments for current + keyword. Can be empty. + text_ptr[i].text_length - length of text string, + after decompression, 0 for iTXt + text_ptr[i].itxt_length - length of itxt string, + after decompression, 0 for tEXt/zTXt + text_ptr[i].lang - language of comment (empty + string for unknown). + text_ptr[i].lang_key - keyword in UTF-8 + (empty string for unknown). + num_text - number of comments (same as + num_comments; you can put NULL here + to avoid the duplication) + Note while png_set_text() will accept text, language, + and translated keywords that can be NULL pointers, the + structure returned by png_get_text will always contain + regular zero-terminated C strings. They might be + empty strings but they will never be NULL pointers. + + num_spalettes = png_get_sPLT(png_ptr, info_ptr, + &palette_ptr); + palette_ptr - array of palette structures holding + contents of one or more sPLT chunks + read. + num_spalettes - number of sPLT chunks read. + + png_get_oFFs(png_ptr, info_ptr, &offset_x, &offset_y, + &unit_type); + offset_x - positive offset from the left edge + of the screen + offset_y - positive offset from the top edge + of the screen + unit_type - PNG_OFFSET_PIXEL, PNG_OFFSET_MICROMETER + + png_get_pHYs(png_ptr, info_ptr, &res_x, &res_y, + &unit_type); + res_x - pixels/unit physical resolution in + x direction + res_y - pixels/unit physical resolution in + x direction + unit_type - PNG_RESOLUTION_UNKNOWN, + PNG_RESOLUTION_METER + + png_get_sCAL(png_ptr, info_ptr, &unit, &width, + &height) + unit - physical scale units (an integer) + width - width of a pixel in physical scale units + height - height of a pixel in physical scale units + (width and height are doubles) + + png_get_sCAL_s(png_ptr, info_ptr, &unit, &width, + &height) + unit - physical scale units (an integer) + width - width of a pixel in physical scale units + height - height of a pixel in physical scale units + (width and height are strings like "2.54") + + num_unknown_chunks = png_get_unknown_chunks(png_ptr, + info_ptr, &unknowns) + unknowns - array of png_unknown_chunk + structures holding unknown chunks + unknowns[i].name - name of unknown chunk + unknowns[i].data - data of unknown chunk + unknowns[i].size - size of unknown chunk's data + unknowns[i].location - position of chunk in file + + The value of "i" corresponds to the order in which the + chunks were read from the PNG file or inserted with the + png_set_unknown_chunks() function. + +The data from the pHYs chunk can be retrieved in several convenient +forms: + + res_x = png_get_x_pixels_per_meter(png_ptr, + info_ptr) + res_y = png_get_y_pixels_per_meter(png_ptr, + info_ptr) + res_x_and_y = png_get_pixels_per_meter(png_ptr, + info_ptr) + res_x = png_get_x_pixels_per_inch(png_ptr, + info_ptr) + res_y = png_get_y_pixels_per_inch(png_ptr, + info_ptr) + res_x_and_y = png_get_pixels_per_inch(png_ptr, + info_ptr) + aspect_ratio = png_get_pixel_aspect_ratio(png_ptr, + info_ptr) + + (Each of these returns 0 [signifying "unknown"] if + the data is not present or if res_x is 0; + res_x_and_y is 0 if res_x != res_y) + +The data from the oFFs chunk can be retrieved in several convenient +forms: + + x_offset = png_get_x_offset_microns(png_ptr, info_ptr); + y_offset = png_get_y_offset_microns(png_ptr, info_ptr); + x_offset = png_get_x_offset_inches(png_ptr, info_ptr); + y_offset = png_get_y_offset_inches(png_ptr, info_ptr); + + (Each of these returns 0 [signifying "unknown" if both + x and y are 0] if the data is not present or if the + chunk is present but the unit is the pixel) + +For more information, see the png_info definition in png.h and the +PNG specification for chunk contents. Be careful with trusting +rowbytes, as some of the transformations could increase the space +needed to hold a row (expand, filler, gray_to_rgb, etc.). +See png_read_update_info(), below. + +A quick word about text_ptr and num_text. PNG stores comments in +keyword/text pairs, one pair per chunk, with no limit on the number +of text chunks, and a 2^31 byte limit on their size. While there are +suggested keywords, there is no requirement to restrict the use to these +strings. It is strongly suggested that keywords and text be sensible +to humans (that's the point), so don't use abbreviations. Non-printing +symbols are not allowed. See the PNG specification for more details. +There is also no requirement to have text after the keyword. + +Keywords should be limited to 79 Latin-1 characters without leading or +trailing spaces, but non-consecutive spaces are allowed within the +keyword. It is possible to have the same keyword any number of times. +The text_ptr is an array of png_text structures, each holding a +pointer to a language string, a pointer to a keyword and a pointer to +a text string. The text string, language code, and translated +keyword may be empty or NULL pointers. The keyword/text +pairs are put into the array in the order that they are received. +However, some or all of the text chunks may be after the image, so, to +make sure you have read all the text chunks, don't mess with these +until after you read the stuff after the image. This will be +mentioned again below in the discussion that goes with png_read_end(). + +.SS Input transformations + +After you've read the header information, you can set up the library +to handle any special transformations of the image data. The various +ways to transform the data will be described in the order that they +should occur. This is important, as some of these change the color +type and/or bit depth of the data, and some others only work on +certain color types and bit depths. Even though each transformation +checks to see if it has data that it can do something with, you should +make sure to only enable a transformation if it will be valid for the +data. For example, don't swap red and blue on grayscale data. + +The colors used for the background and transparency values should be +supplied in the same format/depth as the current image data. They +are stored in the same format/depth as the image data in a bKGD or tRNS +chunk, so this is what libpng expects for this data. The colors are +transformed to keep in sync with the image data when an application +calls the png_read_update_info() routine (see below). + +Data will be decoded into the supplied row buffers packed into bytes +unless the library has been told to transform it into another format. +For example, 4 bit/pixel paletted or grayscale data will be returned +2 pixels/byte with the leftmost pixel in the high-order bits of the +byte, unless png_set_packing() is called. 8-bit RGB data will be stored +in RGB RGB RGB format unless png_set_filler() or png_set_add_alpha() +is called to insert filler bytes, either before or after each RGB triplet. +16-bit RGB data will be returned RRGGBB RRGGBB, with the most significant +byte of the color value first, unless png_set_strip_16() is called to +transform it to regular RGB RGB triplets, or png_set_filler() or +png_set_add alpha() is called to insert filler bytes, either before or +after each RRGGBB triplet. Similarly, 8-bit or 16-bit grayscale data can +be modified with +png_set_filler(), png_set_add_alpha(), or png_set_strip_16(). + +The following code transforms grayscale images of less than 8 to 8 bits, +changes paletted images to RGB, and adds a full alpha channel if there is +transparency information in a tRNS chunk. This is most useful on +grayscale images with bit depths of 2 or 4 or if there is a multiple-image +viewing application that wishes to treat all images in the same way. + + if (color_type == PNG_COLOR_TYPE_PALETTE) + png_set_palette_to_rgb(png_ptr); + + if (color_type == PNG_COLOR_TYPE_GRAY && + bit_depth < 8) png_set_expand_gray_1_2_4_to_8(png_ptr); + + if (png_get_valid(png_ptr, info_ptr, + PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png_ptr); + +These three functions are actually aliases for png_set_expand(), added +in libpng version 1.0.4, with the function names expanded to improve code +readability. In some future version they may actually do different +things. + +As of libpng version 1.2.9, png_set_expand_gray_1_2_4_to_8() was +added. It expands the sample depth without changing tRNS to alpha. +At the same time, png_set_gray_1_2_4_to_8() was deprecated, and it +will be removed from a future version. + +PNG can have files with 16 bits per channel. If you only can handle +8 bits per channel, this will strip the pixels down to 8 bit. + + if (bit_depth == 16) + png_set_strip_16(png_ptr); + +If, for some reason, you don't need the alpha channel on an image, +and you want to remove it rather than combining it with the background +(but the image author certainly had in mind that you *would* combine +it with the background, so that's what you should probably do): + + if (color_type & PNG_COLOR_MASK_ALPHA) + png_set_strip_alpha(png_ptr); + +In PNG files, the alpha channel in an image +is the level of opacity. If you need the alpha channel in an image to +be the level of transparency instead of opacity, you can invert the +alpha channel (or the tRNS chunk data) after it's read, so that 0 is +fully opaque and 255 (in 8-bit or paletted images) or 65535 (in 16-bit +images) is fully transparent, with + + png_set_invert_alpha(png_ptr); + +PNG files pack pixels of bit depths 1, 2, and 4 into bytes as small as +they can, resulting in, for example, 8 pixels per byte for 1 bit +files. This code expands to 1 pixel per byte without changing the +values of the pixels: + + if (bit_depth < 8) + png_set_packing(png_ptr); + +PNG files have possible bit depths of 1, 2, 4, 8, and 16. All pixels +stored in a PNG image have been "scaled" or "shifted" up to the next +higher possible bit depth (e.g. from 5 bits/sample in the range [0,31] to +8 bits/sample in the range [0, 255]). However, it is also possible to +convert the PNG pixel data back to the original bit depth of the image. +This call reduces the pixels back down to the original bit depth: + + png_color_8p sig_bit; + + if (png_get_sBIT(png_ptr, info_ptr, &sig_bit)) + png_set_shift(png_ptr, sig_bit); + +PNG files store 3-color pixels in red, green, blue order. This code +changes the storage of the pixels to blue, green, red: + + if (color_type == PNG_COLOR_TYPE_RGB || + color_type == PNG_COLOR_TYPE_RGB_ALPHA) + png_set_bgr(png_ptr); + +PNG files store RGB pixels packed into 3 or 6 bytes. This code expands them +into 4 or 8 bytes for windowing systems that need them in this format: + + if (color_type == PNG_COLOR_TYPE_RGB) + png_set_filler(png_ptr, filler, PNG_FILLER_BEFORE); + +where "filler" is the 8 or 16-bit number to fill with, and the location is +either PNG_FILLER_BEFORE or PNG_FILLER_AFTER, depending upon whether +you want the filler before the RGB or after. This transformation +does not affect images that already have full alpha channels. To add an +opaque alpha channel, use filler=0xff or 0xffff and PNG_FILLER_AFTER which +will generate RGBA pixels. + +Note that png_set_filler() does not change the color type. If you want +to do that, you can add a true alpha channel with + + if (color_type == PNG_COLOR_TYPE_RGB || + color_type == PNG_COLOR_TYPE_GRAY) + png_set_add_alpha(png_ptr, filler, PNG_FILLER_AFTER); + +where "filler" contains the alpha value to assign to each pixel. +This function was added in libpng-1.2.7. + +If you are reading an image with an alpha channel, and you need the +data as ARGB instead of the normal PNG format RGBA: + + if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) + png_set_swap_alpha(png_ptr); + +For some uses, you may want a grayscale image to be represented as +RGB. This code will do that conversion: + + if (color_type == PNG_COLOR_TYPE_GRAY || + color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + png_set_gray_to_rgb(png_ptr); + +Conversely, you can convert an RGB or RGBA image to grayscale or grayscale +with alpha. + + if (color_type == PNG_COLOR_TYPE_RGB || + color_type == PNG_COLOR_TYPE_RGB_ALPHA) + png_set_rgb_to_gray_fixed(png_ptr, error_action, + int red_weight, int green_weight); + + error_action = 1: silently do the conversion + error_action = 2: issue a warning if the original + image has any pixel where + red != green or red != blue + error_action = 3: issue an error and abort the + conversion if the original + image has any pixel where + red != green or red != blue + + red_weight: weight of red component times 100000 + green_weight: weight of green component times 100000 + If either weight is negative, default + weights (21268, 71514) are used. + +If you have set error_action = 1 or 2, you can +later check whether the image really was gray, after processing +the image rows, with the png_get_rgb_to_gray_status(png_ptr) function. +It will return a png_byte that is zero if the image was gray or +1 if there were any non-gray pixels. bKGD and sBIT data +will be silently converted to grayscale, using the green channel +data, regardless of the error_action setting. + +With red_weight+green_weight<=100000, +the normalized graylevel is computed: + + int rw = red_weight * 65536; + int gw = green_weight * 65536; + int bw = 65536 - (rw + gw); + gray = (rw*red + gw*green + bw*blue)/65536; + +The default values approximate those recommended in the Charles +Poynton's Color FAQ, <http://www.inforamp.net/~poynton/> +Copyright (c) 1998-01-04 Charles Poynton <poynton at inforamp.net> + + Y = 0.212671 * R + 0.715160 * G + 0.072169 * B + +Libpng approximates this with + + Y = 0.21268 * R + 0.7151 * G + 0.07217 * B + +which can be expressed with integers as + + Y = (6969 * R + 23434 * G + 2365 * B)/32768 + +The calculation is done in a linear colorspace, if the image gamma +is known. + +If you have a grayscale and you are using png_set_expand_depth(), +png_set_expand(), or png_set_gray_to_rgb to change to truecolor or to +a higher bit-depth, you must either supply the background color as a gray +value at the original file bit-depth (need_expand = 1) or else supply the +background color as an RGB triplet at the final, expanded bit depth +(need_expand = 0). Similarly, if you are reading a paletted image, you +must either supply the background color as a palette index (need_expand = 1) +or as an RGB triplet that may or may not be in the palette (need_expand = 0). + + png_color_16 my_background; + png_color_16p image_background; + + if (png_get_bKGD(png_ptr, info_ptr, &image_background)) + png_set_background(png_ptr, image_background, + PNG_BACKGROUND_GAMMA_FILE, 1, 1.0); + else + png_set_background(png_ptr, &my_background, + PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0); + +The png_set_background() function tells libpng to composite images +with alpha or simple transparency against the supplied background +color. If the PNG file contains a bKGD chunk (PNG_INFO_bKGD valid), +you may use this color, or supply another color more suitable for +the current display (e.g., the background color from a web page). You +need to tell libpng whether the color is in the gamma space of the +display (PNG_BACKGROUND_GAMMA_SCREEN for colors you supply), the file +(PNG_BACKGROUND_GAMMA_FILE for colors from the bKGD chunk), or one +that is neither of these gammas (PNG_BACKGROUND_GAMMA_UNIQUE - I don't +know why anyone would use this, but it's here). + +To properly display PNG images on any kind of system, the application needs +to know what the display gamma is. Ideally, the user will know this, and +the application will allow them to set it. One method of allowing the user +to set the display gamma separately for each system is to check for a +SCREEN_GAMMA or DISPLAY_GAMMA environment variable, which will hopefully be +correctly set. + +Note that display_gamma is the overall gamma correction required to produce +pleasing results, which depends on the lighting conditions in the surrounding +environment. In a dim or brightly lit room, no compensation other than +the physical gamma exponent of the monitor is needed, while in a dark room +a slightly smaller exponent is better. + + double gamma, screen_gamma; + + if (/* We have a user-defined screen + gamma value */) + { + screen_gamma = user_defined_screen_gamma; + } + /* One way that applications can share the same + screen gamma value */ + else if ((gamma_str = getenv("SCREEN_GAMMA")) + != NULL) + { + screen_gamma = (double)atof(gamma_str); + } + /* If we don't have another value */ + else + { + screen_gamma = 2.2; /* A good guess for a + PC monitor in a bright office or a dim room */ + screen_gamma = 2.0; /* A good guess for a + PC monitor in a dark room */ + screen_gamma = 1.7 or 1.0; /* A good + guess for Mac systems */ + } + +The png_set_gamma() function handles gamma transformations of the data. +Pass both the file gamma and the current screen_gamma. If the file does +not have a gamma value, you can pass one anyway if you have an idea what +it is (usually 0.45455 is a good guess for GIF images on PCs). Note +that file gammas are inverted from screen gammas. See the discussions +on gamma in the PNG specification for an excellent description of what +gamma is, and why all applications should support it. It is strongly +recommended that PNG viewers support gamma correction. + + if (png_get_gAMA(png_ptr, info_ptr, &gamma)) + png_set_gamma(png_ptr, screen_gamma, gamma); + else + png_set_gamma(png_ptr, screen_gamma, 0.45455); + +If you need to reduce an RGB file to a paletted file, or if a paletted +file has more entries then will fit on your screen, png_set_dither() +will do that. Note that this is a simple match dither that merely +finds the closest color available. This should work fairly well with +optimized palettes, and fairly badly with linear color cubes. If you +pass a palette that is larger then maximum_colors, the file will +reduce the number of colors in the palette so it will fit into +maximum_colors. If there is a histogram, it will use it to make +more intelligent choices when reducing the palette. If there is no +histogram, it may not do as good a job. + + if (color_type & PNG_COLOR_MASK_COLOR) + { + if (png_get_valid(png_ptr, info_ptr, + PNG_INFO_PLTE)) + { + png_uint_16p histogram = NULL; + + png_get_hIST(png_ptr, info_ptr, + &histogram); + png_set_dither(png_ptr, palette, num_palette, + max_screen_colors, histogram, 1); + } + else + { + png_color std_color_cube[MAX_SCREEN_COLORS] = + { ... colors ... }; + + png_set_dither(png_ptr, std_color_cube, + MAX_SCREEN_COLORS, MAX_SCREEN_COLORS, + NULL,0); + } + } + +PNG files describe monochrome as black being zero and white being one. +The following code will reverse this (make black be one and white be +zero): + + if (bit_depth == 1 && color_type == PNG_COLOR_TYPE_GRAY) + png_set_invert_mono(png_ptr); + +This function can also be used to invert grayscale and gray-alpha images: + + if (color_type == PNG_COLOR_TYPE_GRAY || + color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + png_set_invert_mono(png_ptr); + +PNG files store 16 bit pixels in network byte order (big-endian, +ie. most significant bits first). This code changes the storage to the +other way (little-endian, i.e. least significant bits first, the +way PCs store them): + + if (bit_depth == 16) + png_set_swap(png_ptr); + +If you are using packed-pixel images (1, 2, or 4 bits/pixel), and you +need to change the order the pixels are packed into bytes, you can use: + + if (bit_depth < 8) + png_set_packswap(png_ptr); + +Finally, you can write your own transformation function if none of +the existing ones meets your needs. This is done by setting a callback +with + + png_set_read_user_transform_fn(png_ptr, + read_transform_fn); + +You must supply the function + + void read_transform_fn(png_ptr ptr, row_info_ptr + row_info, png_bytep data) + +See pngtest.c for a working example. Your function will be called +after all of the other transformations have been processed. + +You can also set up a pointer to a user structure for use by your +callback function, and you can inform libpng that your transform +function will change the number of channels or bit depth with the +function + + png_set_user_transform_info(png_ptr, user_ptr, + user_depth, user_channels); + +The user's application, not libpng, is responsible for allocating and +freeing any memory required for the user structure. + +You can retrieve the pointer via the function +png_get_user_transform_ptr(). For example: + + voidp read_user_transform_ptr = + png_get_user_transform_ptr(png_ptr); + +The last thing to handle is interlacing; this is covered in detail below, +but you must call the function here if you want libpng to handle expansion +of the interlaced image. + + number_of_passes = png_set_interlace_handling(png_ptr); + +After setting the transformations, libpng can update your png_info +structure to reflect any transformations you've requested with this +call. This is most useful to update the info structure's rowbytes +field so you can use it to allocate your image memory. This function +will also update your palette with the correct screen_gamma and +background if these have been given with the calls above. + + png_read_update_info(png_ptr, info_ptr); + +After you call png_read_update_info(), you can allocate any +memory you need to hold the image. The row data is simply +raw byte data for all forms of images. As the actual allocation +varies among applications, no example will be given. If you +are allocating one large chunk, you will need to build an +array of pointers to each row, as it will be needed for some +of the functions below. + +.SS Reading image data + +After you've allocated memory, you can read the image data. +The simplest way to do this is in one function call. If you are +allocating enough memory to hold the whole image, you can just +call png_read_image() and libpng will read in all the image data +and put it in the memory area supplied. You will need to pass in +an array of pointers to each row. + +This function automatically handles interlacing, so you don't need +to call png_set_interlace_handling() or call this function multiple +times, or any of that other stuff necessary with png_read_rows(). + + png_read_image(png_ptr, row_pointers); + +where row_pointers is: + + png_bytep row_pointers[height]; + +You can point to void or char or whatever you use for pixels. + +If you don't want to read in the whole image at once, you can +use png_read_rows() instead. If there is no interlacing (check +interlace_type == PNG_INTERLACE_NONE), this is simple: + + png_read_rows(png_ptr, row_pointers, NULL, + number_of_rows); + +where row_pointers is the same as in the png_read_image() call. + +If you are doing this just one row at a time, you can do this with +a single row_pointer instead of an array of row_pointers: + + png_bytep row_pointer = row; + png_read_row(png_ptr, row_pointer, NULL); + +If the file is interlaced (interlace_type != 0 in the IHDR chunk), things +get somewhat harder. The only current (PNG Specification version 1.2) +interlacing type for PNG is (interlace_type == PNG_INTERLACE_ADAM7) +is a somewhat complicated 2D interlace scheme, known as Adam7, that +breaks down an image into seven smaller images of varying size, based +on an 8x8 grid. + +libpng can fill out those images or it can give them to you "as is". +If you want them filled out, there are two ways to do that. The one +mentioned in the PNG specification is to expand each pixel to cover +those pixels that have not been read yet (the "rectangle" method). +This results in a blocky image for the first pass, which gradually +smooths out as more pixels are read. The other method is the "sparkle" +method, where pixels are drawn only in their final locations, with the +rest of the image remaining whatever colors they were initialized to +before the start of the read. The first method usually looks better, +but tends to be slower, as there are more pixels to put in the rows. + +If you don't want libpng to handle the interlacing details, just call +png_read_rows() seven times to read in all seven images. Each of the +images is a valid image by itself, or they can all be combined on an +8x8 grid to form a single image (although if you intend to combine them +you would be far better off using the libpng interlace handling). + +The first pass will return an image 1/8 as wide as the entire image +(every 8th column starting in column 0) and 1/8 as high as the original +(every 8th row starting in row 0), the second will be 1/8 as wide +(starting in column 4) and 1/8 as high (also starting in row 0). The +third pass will be 1/4 as wide (every 4th pixel starting in column 0) and +1/8 as high (every 8th row starting in row 4), and the fourth pass will +be 1/4 as wide and 1/4 as high (every 4th column starting in column 2, +and every 4th row starting in row 0). The fifth pass will return an +image 1/2 as wide, and 1/4 as high (starting at column 0 and row 2), +while the sixth pass will be 1/2 as wide and 1/2 as high as the original +(starting in column 1 and row 0). The seventh and final pass will be as +wide as the original, and 1/2 as high, containing all of the odd +numbered scanlines. Phew! + +If you want libpng to expand the images, call this before calling +png_start_read_image() or png_read_update_info(): + + if (interlace_type == PNG_INTERLACE_ADAM7) + number_of_passes + = png_set_interlace_handling(png_ptr); + +This will return the number of passes needed. Currently, this +is seven, but may change if another interlace type is added. +This function can be called even if the file is not interlaced, +where it will return one pass. + +If you are not going to display the image after each pass, but are +going to wait until the entire image is read in, use the sparkle +effect. This effect is faster and the end result of either method +is exactly the same. If you are planning on displaying the image +after each pass, the "rectangle" effect is generally considered the +better looking one. + +If you only want the "sparkle" effect, just call png_read_rows() as +normal, with the third parameter NULL. Make sure you make pass over +the image number_of_passes times, and you don't change the data in the +rows between calls. You can change the locations of the data, just +not the data. Each pass only writes the pixels appropriate for that +pass, and assumes the data from previous passes is still valid. + + png_read_rows(png_ptr, row_pointers, NULL, + number_of_rows); + +If you only want the first effect (the rectangles), do the same as +before except pass the row buffer in the third parameter, and leave +the second parameter NULL. + + png_read_rows(png_ptr, NULL, row_pointers, + number_of_rows); + +.SS Finishing a sequential read + +After you are finished reading the image through the +low-level interface, you can finish reading the file. If you are +interested in comments or time, which may be stored either before or +after the image data, you should pass the separate png_info struct if +you want to keep the comments from before and after the image +separate. If you are not interested, you can pass NULL. + + png_read_end(png_ptr, end_info); + +When you are done, you can free all memory allocated by libpng like this: + + png_destroy_read_struct(&png_ptr, &info_ptr, + &end_info); + +It is also possible to individually free the info_ptr members that +point to libpng-allocated storage with the following function: + + png_free_data(png_ptr, info_ptr, mask, seq) + mask - identifies data to be freed, a mask + containing the logical OR of one or + more of + PNG_FREE_PLTE, PNG_FREE_TRNS, + PNG_FREE_HIST, PNG_FREE_ICCP, + PNG_FREE_PCAL, PNG_FREE_ROWS, + PNG_FREE_SCAL, PNG_FREE_SPLT, + PNG_FREE_TEXT, PNG_FREE_UNKN, + or simply PNG_FREE_ALL + seq - sequence number of item to be freed + (-1 for all items) + +This function may be safely called when the relevant storage has +already been freed, or has not yet been allocated, or was allocated +by the user and not by libpng, and will in those +cases do nothing. The "seq" parameter is ignored if only one item +of the selected data type, such as PLTE, is allowed. If "seq" is not +-1, and multiple items are allowed for the data type identified in +the mask, such as text or sPLT, only the n'th item in the structure +is freed, where n is "seq". + +The default behavior is only to free data that was allocated internally +by libpng. This can be changed, so that libpng will not free the data, +or so that it will free data that was allocated by the user with png_malloc() +or png_zalloc() and passed in via a png_set_*() function, with + + png_data_freer(png_ptr, info_ptr, freer, mask) + mask - which data elements are affected + same choices as in png_free_data() + freer - one of + PNG_DESTROY_WILL_FREE_DATA + PNG_SET_WILL_FREE_DATA + PNG_USER_WILL_FREE_DATA + +This function only affects data that has already been allocated. +You can call this function after reading the PNG data but before calling +any png_set_*() functions, to control whether the user or the png_set_*() +function is responsible for freeing any existing data that might be present, +and again after the png_set_*() functions to control whether the user +or png_destroy_*() is supposed to free the data. When the user assumes +responsibility for libpng-allocated data, the application must use +png_free() to free it, and when the user transfers responsibility to libpng +for data that the user has allocated, the user must have used png_malloc() +or png_zalloc() to allocate it. + +If you allocated your row_pointers in a single block, as suggested above in +the description of the high level read interface, you must not transfer +responsibility for freeing it to the png_set_rows or png_read_destroy function, +because they would also try to free the individual row_pointers[i]. + +If you allocated text_ptr.text, text_ptr.lang, and text_ptr.translated_keyword +separately, do not transfer responsibility for freeing text_ptr to libpng, +because when libpng fills a png_text structure it combines these members with +the key member, and png_free_data() will free only text_ptr.key. Similarly, +if you transfer responsibility for free'ing text_ptr from libpng to your +application, your application must not separately free those members. + +The png_free_data() function will turn off the "valid" flag for anything +it frees. If you need to turn the flag off for a chunk that was freed by your +application instead of by libpng, you can use + + png_set_invalid(png_ptr, info_ptr, mask); + mask - identifies the chunks to be made invalid, + containing the logical OR of one or + more of + PNG_INFO_gAMA, PNG_INFO_sBIT, + PNG_INFO_cHRM, PNG_INFO_PLTE, + PNG_INFO_tRNS, PNG_INFO_bKGD, + PNG_INFO_hIST, PNG_INFO_pHYs, + PNG_INFO_oFFs, PNG_INFO_tIME, + PNG_INFO_pCAL, PNG_INFO_sRGB, + PNG_INFO_iCCP, PNG_INFO_sPLT, + PNG_INFO_sCAL, PNG_INFO_IDAT + +For a more compact example of reading a PNG image, see the file example.c. + +.SS Reading PNG files progressively + +The progressive reader is slightly different then the non-progressive +reader. Instead of calling png_read_info(), png_read_rows(), and +png_read_end(), you make one call to png_process_data(), which calls +callbacks when it has the info, a row, or the end of the image. You +set up these callbacks with png_set_progressive_read_fn(). You don't +have to worry about the input/output functions of libpng, as you are +giving the library the data directly in png_process_data(). I will +assume that you have read the section on reading PNG files above, +so I will only highlight the differences (although I will show +all of the code). + +png_structp png_ptr; +png_infop info_ptr; + + /* An example code fragment of how you would + initialize the progressive reader in your + application. */ + int + initialize_png_reader() + { + png_ptr = png_create_read_struct + (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr, + user_error_fn, user_warning_fn); + if (!png_ptr) + return (ERROR); + info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) + { + png_destroy_read_struct(&png_ptr, (png_infopp)NULL, + (png_infopp)NULL); + return (ERROR); + } + + if (setjmp(png_jmpbuf(png_ptr))) + { + png_destroy_read_struct(&png_ptr, &info_ptr, + (png_infopp)NULL); + return (ERROR); + } + + /* This one's new. You can provide functions + to be called when the header info is valid, + when each row is completed, and when the image + is finished. If you aren't using all functions, + you can specify NULL parameters. Even when all + three functions are NULL, you need to call + png_set_progressive_read_fn(). You can use + any struct as the user_ptr (cast to a void pointer + for the function call), and retrieve the pointer + from inside the callbacks using the function + + png_get_progressive_ptr(png_ptr); + + which will return a void pointer, which you have + to cast appropriately. + */ + png_set_progressive_read_fn(png_ptr, (void *)user_ptr, + info_callback, row_callback, end_callback); + + return 0; + } + + /* A code fragment that you call as you receive blocks + of data */ + int + process_data(png_bytep buffer, png_uint_32 length) + { + if (setjmp(png_jmpbuf(png_ptr))) + { + png_destroy_read_struct(&png_ptr, &info_ptr, + (png_infopp)NULL); + return (ERROR); + } + + /* This one's new also. Simply give it a chunk + of data from the file stream (in order, of + course). On machines with segmented memory + models machines, don't give it any more than + 64K. The library seems to run fine with sizes + of 4K. Although you can give it much less if + necessary (I assume you can give it chunks of + 1 byte, I haven't tried less then 256 bytes + yet). When this function returns, you may + want to display any rows that were generated + in the row callback if you don't already do + so there. + */ + png_process_data(png_ptr, info_ptr, buffer, length); + return 0; + } + + /* This function is called (as set by + png_set_progressive_read_fn() above) when enough data + has been supplied so all of the header has been + read. + */ + void + info_callback(png_structp png_ptr, png_infop info) + { + /* Do any setup here, including setting any of + the transformations mentioned in the Reading + PNG files section. For now, you _must_ call + either png_start_read_image() or + png_read_update_info() after all the + transformations are set (even if you don't set + any). You may start getting rows before + png_process_data() returns, so this is your + last chance to prepare for that. + */ + } + + /* This function is called when each row of image + data is complete */ + void + row_callback(png_structp png_ptr, png_bytep new_row, + png_uint_32 row_num, int pass) + { + /* If the image is interlaced, and you turned + on the interlace handler, this function will + be called for every row in every pass. Some + of these rows will not be changed from the + previous pass. When the row is not changed, + the new_row variable will be NULL. The rows + and passes are called in order, so you don't + really need the row_num and pass, but I'm + supplying them because it may make your life + easier. + + For the non-NULL rows of interlaced images, + you must call png_progressive_combine_row() + passing in the row and the old row. You can + call this function for NULL rows (it will just + return) and for non-interlaced images (it just + does the memcpy for you) if it will make the + code easier. Thus, you can just do this for + all cases: + */ + + png_progressive_combine_row(png_ptr, old_row, + new_row); + + /* where old_row is what was displayed for + previously for the row. Note that the first + pass (pass == 0, really) will completely cover + the old row, so the rows do not have to be + initialized. After the first pass (and only + for interlaced images), you will have to pass + the current row, and the function will combine + the old row and the new row. + */ + } + + void + end_callback(png_structp png_ptr, png_infop info) + { + /* This function is called after the whole image + has been read, including any chunks after the + image (up to and including the IEND). You + will usually have the same info chunk as you + had in the header, although some data may have + been added to the comments and time fields. + + Most people won't do much here, perhaps setting + a flag that marks the image as finished. + */ + } + + + +.SH IV. Writing + +Much of this is very similar to reading. However, everything of +importance is repeated here, so you won't have to constantly look +back up in the reading section to understand writing. + +.SS Setup + +You will want to do the I/O initialization before you get into libpng, +so if it doesn't work, you don't have anything to undo. If you are not +using the standard I/O functions, you will need to replace them with +custom writing functions. See the discussion under Customizing libpng. + + FILE *fp = fopen(file_name, "wb"); + if (!fp) + { + return (ERROR); + } + +Next, png_struct and png_info need to be allocated and initialized. +As these can be both relatively large, you may not want to store these +on the stack, unless you have stack space to spare. Of course, you +will want to check if they return NULL. If you are also reading, +you won't want to name your read structure and your write structure +both "png_ptr"; you can call them anything you like, such as +"read_ptr" and "write_ptr". Look at pngtest.c, for example. + + png_structp png_ptr = png_create_write_struct + (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr, + user_error_fn, user_warning_fn); + if (!png_ptr) + return (ERROR); + + png_infop info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) + { + png_destroy_write_struct(&png_ptr, + (png_infopp)NULL); + return (ERROR); + } + +If you want to use your own memory allocation routines, +define PNG_USER_MEM_SUPPORTED and use +png_create_write_struct_2() instead of png_create_write_struct(): + + png_structp png_ptr = png_create_write_struct_2 + (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr, + user_error_fn, user_warning_fn, (png_voidp) + user_mem_ptr, user_malloc_fn, user_free_fn); + +After you have these structures, you will need to set up the +error handling. When libpng encounters an error, it expects to +longjmp() back to your routine. Therefore, you will need to call +setjmp() and pass the png_jmpbuf(png_ptr). If you +write the file from different routines, you will need to update +the png_jmpbuf(png_ptr) every time you enter a new routine that will +call a png_*() function. See your documentation of setjmp/longjmp +for your compiler for more information on setjmp/longjmp. See +the discussion on libpng error handling in the Customizing Libpng +section below for more information on the libpng error handling. + + if (setjmp(png_jmpbuf(png_ptr))) + { + png_destroy_write_struct(&png_ptr, &info_ptr); + fclose(fp); + return (ERROR); + } + ... + return; + +If you would rather avoid the complexity of setjmp/longjmp issues, +you can compile libpng with PNG_SETJMP_NOT_SUPPORTED, in which case +errors will result in a call to PNG_ABORT() which defaults to abort(). + +Now you need to set up the output code. The default for libpng is to +use the C function fwrite(). If you use this, you will need to pass a +valid FILE * in the function png_init_io(). Be sure that the file is +opened in binary mode. Again, if you wish to handle writing data in +another way, see the discussion on libpng I/O handling in the Customizing +Libpng section below. + + png_init_io(png_ptr, fp); + +If you are embedding your PNG into a datastream such as MNG, and don't +want libpng to write the 8-byte signature, or if you have already +written the signature in your application, use + + png_set_sig_bytes(png_ptr, 8); + +to inform libpng that it should not write a signature. + +.SS Write callbacks + +At this point, you can set up a callback function that will be +called after each row has been written, which you can use to control +a progress meter or the like. It's demonstrated in pngtest.c. +You must supply a function + + void write_row_callback(png_ptr, png_uint_32 row, + int pass); + { + /* put your code here */ + } + +(You can give it another name that you like instead of "write_row_callback") + +To inform libpng about your function, use + + png_set_write_status_fn(png_ptr, write_row_callback); + +You now have the option of modifying how the compression library will +run. The following functions are mainly for testing, but may be useful +in some cases, like if you need to write PNG files extremely fast and +are willing to give up some compression, or if you want to get the +maximum possible compression at the expense of slower writing. If you +have no special needs in this area, let the library do what it wants by +not calling this function at all, as it has been tuned to deliver a good +speed/compression ratio. The second parameter to png_set_filter() is +the filter method, for which the only valid values are 0 (as of the +July 1999 PNG specification, version 1.2) or 64 (if you are writing +a PNG datastream that is to be embedded in a MNG datastream). The third +parameter is a flag that indicates which filter type(s) are to be tested +for each scanline. See the PNG specification for details on the specific filter +types. + + + /* turn on or off filtering, and/or choose + specific filters. You can use either a single + PNG_FILTER_VALUE_NAME or the logical OR of one + or more PNG_FILTER_NAME masks. */ + png_set_filter(png_ptr, 0, + PNG_FILTER_NONE | PNG_FILTER_VALUE_NONE | + PNG_FILTER_SUB | PNG_FILTER_VALUE_SUB | + PNG_FILTER_UP | PNG_FILTER_VALUE_UP | + PNG_FILTER_AVE | PNG_FILTER_VALUE_AVE | + PNG_FILTER_PAETH | PNG_FILTER_VALUE_PAETH| + PNG_ALL_FILTERS); + +If an application +wants to start and stop using particular filters during compression, +it should start out with all of the filters (to ensure that the previous +row of pixels will be stored in case it's needed later), and then add +and remove them after the start of compression. + +If you are writing a PNG datastream that is to be embedded in a MNG +datastream, the second parameter can be either 0 or 64. + +The png_set_compression_*() functions interface to the zlib compression +library, and should mostly be ignored unless you really know what you are +doing. The only generally useful call is png_set_compression_level() +which changes how much time zlib spends on trying to compress the image +data. See the Compression Library (zlib.h and algorithm.txt, distributed +with zlib) for details on the compression levels. + + /* set the zlib compression level */ + png_set_compression_level(png_ptr, + Z_BEST_COMPRESSION); + + /* set other zlib parameters */ + png_set_compression_mem_level(png_ptr, 8); + png_set_compression_strategy(png_ptr, + Z_DEFAULT_STRATEGY); + png_set_compression_window_bits(png_ptr, 15); + png_set_compression_method(png_ptr, 8); + png_set_compression_buffer_size(png_ptr, 8192) + +extern PNG_EXPORT(void,png_set_zbuf_size) + +.SS Setting the contents of info for output + +You now need to fill in the png_info structure with all the data you +wish to write before the actual image. Note that the only thing you +are allowed to write after the image is the text chunks and the time +chunk (as of PNG Specification 1.2, anyway). See png_write_end() and +the latest PNG specification for more information on that. If you +wish to write them before the image, fill them in now, and flag that +data as being valid. If you want to wait until after the data, don't +fill them until png_write_end(). For all the fields in png_info and +their data types, see png.h. For explanations of what the fields +contain, see the PNG specification. + +Some of the more important parts of the png_info are: + + png_set_IHDR(png_ptr, info_ptr, width, height, + bit_depth, color_type, interlace_type, + compression_type, filter_method) + width - holds the width of the image + in pixels (up to 2^31). + height - holds the height of the image + in pixels (up to 2^31). + bit_depth - holds the bit depth of one of the + image channels. + (valid values are 1, 2, 4, 8, 16 + and depend also on the + color_type. See also significant + bits (sBIT) below). + color_type - describes which color/alpha + channels are present. + PNG_COLOR_TYPE_GRAY + (bit depths 1, 2, 4, 8, 16) + PNG_COLOR_TYPE_GRAY_ALPHA + (bit depths 8, 16) + PNG_COLOR_TYPE_PALETTE + (bit depths 1, 2, 4, 8) + PNG_COLOR_TYPE_RGB + (bit_depths 8, 16) + PNG_COLOR_TYPE_RGB_ALPHA + (bit_depths 8, 16) + + PNG_COLOR_MASK_PALETTE + PNG_COLOR_MASK_COLOR + PNG_COLOR_MASK_ALPHA + + interlace_type - PNG_INTERLACE_NONE or + PNG_INTERLACE_ADAM7 + compression_type - (must be + PNG_COMPRESSION_TYPE_DEFAULT) + filter_method - (must be PNG_FILTER_TYPE_DEFAULT + or, if you are writing a PNG to + be embedded in a MNG datastream, + can also be + PNG_INTRAPIXEL_DIFFERENCING) + + png_set_PLTE(png_ptr, info_ptr, palette, + num_palette); + palette - the palette for the file + (array of png_color) + num_palette - number of entries in the palette + + png_set_gAMA(png_ptr, info_ptr, gamma); + gamma - the gamma the image was created + at (PNG_INFO_gAMA) + + png_set_sRGB(png_ptr, info_ptr, srgb_intent); + srgb_intent - the rendering intent + (PNG_INFO_sRGB) The presence of + the sRGB chunk means that the pixel + data is in the sRGB color space. + This chunk also implies specific + values of gAMA and cHRM. Rendering + intent is the CSS-1 property that + has been defined by the International + Color Consortium + (http://www.color.org). + It can be one of + PNG_sRGB_INTENT_SATURATION, + PNG_sRGB_INTENT_PERCEPTUAL, + PNG_sRGB_INTENT_ABSOLUTE, or + PNG_sRGB_INTENT_RELATIVE. + + + png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, + srgb_intent); + srgb_intent - the rendering intent + (PNG_INFO_sRGB) The presence of the + sRGB chunk means that the pixel + data is in the sRGB color space. + This function also causes gAMA and + cHRM chunks with the specific values + that are consistent with sRGB to be + written. + + png_set_iCCP(png_ptr, info_ptr, name, compression_type, + profile, proflen); + name - The profile name. + compression - The compression type; always + PNG_COMPRESSION_TYPE_BASE for PNG 1.0. + You may give NULL to this argument to + ignore it. + profile - International Color Consortium color + profile data. May contain NULs. + proflen - length of profile data in bytes. + + png_set_sBIT(png_ptr, info_ptr, sig_bit); + sig_bit - the number of significant bits for + (PNG_INFO_sBIT) each of the gray, red, + green, and blue channels, whichever are + appropriate for the given color type + (png_color_16) + + png_set_tRNS(png_ptr, info_ptr, trans, num_trans, + trans_values); + trans - array of transparent entries for + palette (PNG_INFO_tRNS) + trans_values - graylevel or color sample values of + the single transparent color for + non-paletted images (PNG_INFO_tRNS) + num_trans - number of transparent entries + (PNG_INFO_tRNS) + + png_set_hIST(png_ptr, info_ptr, hist); + (PNG_INFO_hIST) + hist - histogram of palette (array of + png_uint_16) + + png_set_tIME(png_ptr, info_ptr, mod_time); + mod_time - time image was last modified + (PNG_VALID_tIME) + + png_set_bKGD(png_ptr, info_ptr, background); + background - background color (PNG_VALID_bKGD) + + png_set_text(png_ptr, info_ptr, text_ptr, num_text); + text_ptr - array of png_text holding image + comments + text_ptr[i].compression - type of compression used + on "text" PNG_TEXT_COMPRESSION_NONE + PNG_TEXT_COMPRESSION_zTXt + PNG_ITXT_COMPRESSION_NONE + PNG_ITXT_COMPRESSION_zTXt + text_ptr[i].key - keyword for comment. Must contain + 1-79 characters. + text_ptr[i].text - text comments for current + keyword. Can be NULL or empty. + text_ptr[i].text_length - length of text string, + after decompression, 0 for iTXt + text_ptr[i].itxt_length - length of itxt string, + after decompression, 0 for tEXt/zTXt + text_ptr[i].lang - language of comment (NULL or + empty for unknown). + text_ptr[i].translated_keyword - keyword in UTF-8 (NULL + or empty for unknown). + num_text - number of comments + + png_set_sPLT(png_ptr, info_ptr, &palette_ptr, + num_spalettes); + palette_ptr - array of png_sPLT_struct structures + to be added to the list of palettes + in the info structure. + num_spalettes - number of palette structures to be + added. + + png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, + unit_type); + offset_x - positive offset from the left + edge of the screen + offset_y - positive offset from the top + edge of the screen + unit_type - PNG_OFFSET_PIXEL, PNG_OFFSET_MICROMETER + + png_set_pHYs(png_ptr, info_ptr, res_x, res_y, + unit_type); + res_x - pixels/unit physical resolution + in x direction + res_y - pixels/unit physical resolution + in y direction + unit_type - PNG_RESOLUTION_UNKNOWN, + PNG_RESOLUTION_METER + + png_set_sCAL(png_ptr, info_ptr, unit, width, height) + unit - physical scale units (an integer) + width - width of a pixel in physical scale units + height - height of a pixel in physical scale units + (width and height are doubles) + + png_set_sCAL_s(png_ptr, info_ptr, unit, width, height) + unit - physical scale units (an integer) + width - width of a pixel in physical scale units + height - height of a pixel in physical scale units + (width and height are strings like "2.54") + + png_set_unknown_chunks(png_ptr, info_ptr, &unknowns, + num_unknowns) + unknowns - array of png_unknown_chunk + structures holding unknown chunks + unknowns[i].name - name of unknown chunk + unknowns[i].data - data of unknown chunk + unknowns[i].size - size of unknown chunk's data + unknowns[i].location - position to write chunk in file + 0: do not write chunk + PNG_HAVE_IHDR: before PLTE + PNG_HAVE_PLTE: before IDAT + PNG_AFTER_IDAT: after IDAT + +The "location" member is set automatically according to +what part of the output file has already been written. +You can change its value after calling png_set_unknown_chunks() +as demonstrated in pngtest.c. Within each of the "locations", +the chunks are sequenced according to their position in the +structure (that is, the value of "i", which is the order in which +the chunk was either read from the input file or defined with +png_set_unknown_chunks). + +A quick word about text and num_text. text is an array of png_text +structures. num_text is the number of valid structures in the array. +Each png_text structure holds a language code, a keyword, a text value, +and a compression type. + +The compression types have the same valid numbers as the compression +types of the image data. Currently, the only valid number is zero. +However, you can store text either compressed or uncompressed, unlike +images, which always have to be compressed. So if you don't want the +text compressed, set the compression type to PNG_TEXT_COMPRESSION_NONE. +Because tEXt and zTXt chunks don't have a language field, if you +specify PNG_TEXT_COMPRESSION_NONE or PNG_TEXT_COMPRESSION_zTXt +any language code or translated keyword will not be written out. + +Until text gets around 1000 bytes, it is not worth compressing it. +After the text has been written out to the file, the compression type +is set to PNG_TEXT_COMPRESSION_NONE_WR or PNG_TEXT_COMPRESSION_zTXt_WR, +so that it isn't written out again at the end (in case you are calling +png_write_end() with the same struct. + +The keywords that are given in the PNG Specification are: + + Title Short (one line) title or + caption for image + Author Name of image's creator + Description Description of image (possibly long) + Copyright Copyright notice + Creation Time Time of original image creation + (usually RFC 1123 format, see below) + Software Software used to create the image + Disclaimer Legal disclaimer + Warning Warning of nature of content + Source Device used to create the image + Comment Miscellaneous comment; conversion + from other image format + +The keyword-text pairs work like this. Keywords should be short +simple descriptions of what the comment is about. Some typical +keywords are found in the PNG specification, as is some recommendations +on keywords. You can repeat keywords in a file. You can even write +some text before the image and some after. For example, you may want +to put a description of the image before the image, but leave the +disclaimer until after, so viewers working over modem connections +don't have to wait for the disclaimer to go over the modem before +they start seeing the image. Finally, keywords should be full +words, not abbreviations. Keywords and text are in the ISO 8859-1 +(Latin-1) character set (a superset of regular ASCII) and can not +contain NUL characters, and should not contain control or other +unprintable characters. To make the comments widely readable, stick +with basic ASCII, and avoid machine specific character set extensions +like the IBM-PC character set. The keyword must be present, but +you can leave off the text string on non-compressed pairs. +Compressed pairs must have a text string, as only the text string +is compressed anyway, so the compression would be meaningless. + +PNG supports modification time via the png_time structure. Two +conversion routines are provided, png_convert_from_time_t() for +time_t and png_convert_from_struct_tm() for struct tm. The +time_t routine uses gmtime(). You don't have to use either of +these, but if you wish to fill in the png_time structure directly, +you should provide the time in universal time (GMT) if possible +instead of your local time. Note that the year number is the full +year (e.g. 1998, rather than 98 - PNG is year 2000 compliant!), and +that months start with 1. + +If you want to store the time of the original image creation, you should +use a plain tEXt chunk with the "Creation Time" keyword. This is +necessary because the "creation time" of a PNG image is somewhat vague, +depending on whether you mean the PNG file, the time the image was +created in a non-PNG format, a still photo from which the image was +scanned, or possibly the subject matter itself. In order to facilitate +machine-readable dates, it is recommended that the "Creation Time" +tEXt chunk use RFC 1123 format dates (e.g. "22 May 1997 18:07:10 GMT"), +although this isn't a requirement. Unlike the tIME chunk, the +"Creation Time" tEXt chunk is not expected to be automatically changed +by the software. To facilitate the use of RFC 1123 dates, a function +png_convert_to_rfc1123(png_timep) is provided to convert from PNG +time to an RFC 1123 format string. + +.SS Writing unknown chunks + +You can use the png_set_unknown_chunks function to queue up chunks +for writing. You give it a chunk name, raw data, and a size; that's +all there is to it. The chunks will be written by the next following +png_write_info_before_PLTE, png_write_info, or png_write_end function. +Any chunks previously read into the info structure's unknown-chunk +list will also be written out in a sequence that satisfies the PNG +specification's ordering rules. + +.SS The high-level write interface + +At this point there are two ways to proceed; through the high-level +write interface, or through a sequence of low-level write operations. +You can use the high-level interface if your image data is present +in the info structure. All defined output +transformations are permitted, enabled by the following masks. + + PNG_TRANSFORM_IDENTITY No transformation + PNG_TRANSFORM_PACKING Pack 1, 2 and 4-bit samples + PNG_TRANSFORM_PACKSWAP Change order of packed + pixels to LSB first + PNG_TRANSFORM_INVERT_MONO Invert monochrome images + PNG_TRANSFORM_SHIFT Normalize pixels to the + sBIT depth + PNG_TRANSFORM_BGR Flip RGB to BGR, RGBA + to BGRA + PNG_TRANSFORM_SWAP_ALPHA Flip RGBA to ARGB or GA + to AG + PNG_TRANSFORM_INVERT_ALPHA Change alpha from opacity + to transparency + PNG_TRANSFORM_SWAP_ENDIAN Byte-swap 16-bit samples + PNG_TRANSFORM_STRIP_FILLER Strip out filler bytes. + +If you have valid image data in the info structure (you can use +png_set_rows() to put image data in the info structure), simply do this: + + png_write_png(png_ptr, info_ptr, png_transforms, NULL) + +where png_transforms is an integer containing the logical OR of some set of +transformation flags. This call is equivalent to png_write_info(), +followed the set of transformations indicated by the transform mask, +then png_write_image(), and finally png_write_end(). + +(The final parameter of this call is not yet used. Someday it might point +to transformation parameters required by some future output transform.) + +You must use png_transforms and not call any png_set_transform() functions +when you use png_write_png(). + +.SS The low-level write interface + +If you are going the low-level route instead, you are now ready to +write all the file information up to the actual image data. You do +this with a call to png_write_info(). + + png_write_info(png_ptr, info_ptr); + +Note that there is one transformation you may need to do before +png_write_info(). In PNG files, the alpha channel in an image is the +level of opacity. If your data is supplied as a level of +transparency, you can invert the alpha channel before you write it, so +that 0 is fully transparent and 255 (in 8-bit or paletted images) or +65535 (in 16-bit images) is fully opaque, with + + png_set_invert_alpha(png_ptr); + +This must appear before png_write_info() instead of later with the +other transformations because in the case of paletted images the tRNS +chunk data has to be inverted before the tRNS chunk is written. If +your image is not a paletted image, the tRNS data (which in such cases +represents a single color to be rendered as transparent) won't need to +be changed, and you can safely do this transformation after your +png_write_info() call. + +If you need to write a private chunk that you want to appear before +the PLTE chunk when PLTE is present, you can write the PNG info in +two steps, and insert code to write your own chunk between them: + + png_write_info_before_PLTE(png_ptr, info_ptr); + png_set_unknown_chunks(png_ptr, info_ptr, ...); + png_write_info(png_ptr, info_ptr); + +After you've written the file information, you can set up the library +to handle any special transformations of the image data. The various +ways to transform the data will be described in the order that they +should occur. This is important, as some of these change the color +type and/or bit depth of the data, and some others only work on +certain color types and bit depths. Even though each transformation +checks to see if it has data that it can do something with, you should +make sure to only enable a transformation if it will be valid for the +data. For example, don't swap red and blue on grayscale data. + +PNG files store RGB pixels packed into 3 or 6 bytes. This code tells +the library to strip input data that has 4 or 8 bytes per pixel down +to 3 or 6 bytes (or strip 2 or 4-byte grayscale+filler data to 1 or 2 +bytes per pixel). + + png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE); + +where the 0 is unused, and the location is either PNG_FILLER_BEFORE or +PNG_FILLER_AFTER, depending upon whether the filler byte in the pixel +is stored XRGB or RGBX. + +PNG files pack pixels of bit depths 1, 2, and 4 into bytes as small as +they can, resulting in, for example, 8 pixels per byte for 1 bit files. +If the data is supplied at 1 pixel per byte, use this code, which will +correctly pack the pixels into a single byte: + + png_set_packing(png_ptr); + +PNG files reduce possible bit depths to 1, 2, 4, 8, and 16. If your +data is of another bit depth, you can write an sBIT chunk into the +file so that decoders can recover the original data if desired. + + /* Set the true bit depth of the image data */ + if (color_type & PNG_COLOR_MASK_COLOR) + { + sig_bit.red = true_bit_depth; + sig_bit.green = true_bit_depth; + sig_bit.blue = true_bit_depth; + } + else + { + sig_bit.gray = true_bit_depth; + } + if (color_type & PNG_COLOR_MASK_ALPHA) + { + sig_bit.alpha = true_bit_depth; + } + + png_set_sBIT(png_ptr, info_ptr, &sig_bit); + +If the data is stored in the row buffer in a bit depth other than +one supported by PNG (e.g. 3 bit data in the range 0-7 for a 4-bit PNG), +this will scale the values to appear to be the correct bit depth as +is required by PNG. + + png_set_shift(png_ptr, &sig_bit); + +PNG files store 16 bit pixels in network byte order (big-endian, +ie. most significant bits first). This code would be used if they are +supplied the other way (little-endian, i.e. least significant bits +first, the way PCs store them): + + if (bit_depth > 8) + png_set_swap(png_ptr); + +If you are using packed-pixel images (1, 2, or 4 bits/pixel), and you +need to change the order the pixels are packed into bytes, you can use: + + if (bit_depth < 8) + png_set_packswap(png_ptr); + +PNG files store 3 color pixels in red, green, blue order. This code +would be used if they are supplied as blue, green, red: + + png_set_bgr(png_ptr); + +PNG files describe monochrome as black being zero and white being +one. This code would be used if the pixels are supplied with this reversed +(black being one and white being zero): + + png_set_invert_mono(png_ptr); + +Finally, you can write your own transformation function if none of +the existing ones meets your needs. This is done by setting a callback +with + + png_set_write_user_transform_fn(png_ptr, + write_transform_fn); + +You must supply the function + + void write_transform_fn(png_ptr ptr, row_info_ptr + row_info, png_bytep data) + +See pngtest.c for a working example. Your function will be called +before any of the other transformations are processed. + +You can also set up a pointer to a user structure for use by your +callback function. + + png_set_user_transform_info(png_ptr, user_ptr, 0, 0); + +The user_channels and user_depth parameters of this function are ignored +when writing; you can set them to zero as shown. + +You can retrieve the pointer via the function png_get_user_transform_ptr(). +For example: + + voidp write_user_transform_ptr = + png_get_user_transform_ptr(png_ptr); + +It is possible to have libpng flush any pending output, either manually, +or automatically after a certain number of lines have been written. To +flush the output stream a single time call: + + png_write_flush(png_ptr); + +and to have libpng flush the output stream periodically after a certain +number of scanlines have been written, call: + + png_set_flush(png_ptr, nrows); + +Note that the distance between rows is from the last time png_write_flush() +was called, or the first row of the image if it has never been called. +So if you write 50 lines, and then png_set_flush 25, it will flush the +output on the next scanline, and every 25 lines thereafter, unless +png_write_flush() is called before 25 more lines have been written. +If nrows is too small (less than about 10 lines for a 640 pixel wide +RGB image) the image compression may decrease noticeably (although this +may be acceptable for real-time applications). Infrequent flushing will +only degrade the compression performance by a few percent over images +that do not use flushing. + +.SS Writing the image data + +That's it for the transformations. Now you can write the image data. +The simplest way to do this is in one function call. If you have the +whole image in memory, you can just call png_write_image() and libpng +will write the image. You will need to pass in an array of pointers to +each row. This function automatically handles interlacing, so you don't +need to call png_set_interlace_handling() or call this function multiple +times, or any of that other stuff necessary with png_write_rows(). + + png_write_image(png_ptr, row_pointers); + +where row_pointers is: + + png_byte *row_pointers[height]; + +You can point to void or char or whatever you use for pixels. + +If you don't want to write the whole image at once, you can +use png_write_rows() instead. If the file is not interlaced, +this is simple: + + png_write_rows(png_ptr, row_pointers, + number_of_rows); + +row_pointers is the same as in the png_write_image() call. + +If you are just writing one row at a time, you can do this with +a single row_pointer instead of an array of row_pointers: + + png_bytep row_pointer = row; + + png_write_row(png_ptr, row_pointer); + +When the file is interlaced, things can get a good deal more +complicated. The only currently (as of the PNG Specification +version 1.2, dated July 1999) defined interlacing scheme for PNG files +is the "Adam7" interlace scheme, that breaks down an +image into seven smaller images of varying size. libpng will build +these images for you, or you can do them yourself. If you want to +build them yourself, see the PNG specification for details of which +pixels to write when. + +If you don't want libpng to handle the interlacing details, just +use png_set_interlace_handling() and call png_write_rows() the +correct number of times to write all seven sub-images. + +If you want libpng to build the sub-images, call this before you start +writing any rows: + + number_of_passes = + png_set_interlace_handling(png_ptr); + +This will return the number of passes needed. Currently, this +is seven, but may change if another interlace type is added. + +Then write the complete image number_of_passes times. + + png_write_rows(png_ptr, row_pointers, + number_of_rows); + +As some of these rows are not used, and thus return immediately, +you may want to read about interlacing in the PNG specification, +and only update the rows that are actually used. + +.SS Finishing a sequential write + +After you are finished writing the image, you should finish writing +the file. If you are interested in writing comments or time, you should +pass an appropriately filled png_info pointer. If you are not interested, +you can pass NULL. + + png_write_end(png_ptr, info_ptr); + +When you are done, you can free all memory used by libpng like this: + + png_destroy_write_struct(&png_ptr, &info_ptr); + +It is also possible to individually free the info_ptr members that +point to libpng-allocated storage with the following function: + + png_free_data(png_ptr, info_ptr, mask, seq) + mask - identifies data to be freed, a mask + containing the logical OR of one or + more of + PNG_FREE_PLTE, PNG_FREE_TRNS, + PNG_FREE_HIST, PNG_FREE_ICCP, + PNG_FREE_PCAL, PNG_FREE_ROWS, + PNG_FREE_SCAL, PNG_FREE_SPLT, + PNG_FREE_TEXT, PNG_FREE_UNKN, + or simply PNG_FREE_ALL + seq - sequence number of item to be freed + (-1 for all items) + +This function may be safely called when the relevant storage has +already been freed, or has not yet been allocated, or was allocated +by the user and not by libpng, and will in those +cases do nothing. The "seq" parameter is ignored if only one item +of the selected data type, such as PLTE, is allowed. If "seq" is not +-1, and multiple items are allowed for the data type identified in +the mask, such as text or sPLT, only the n'th item in the structure +is freed, where n is "seq". + +If you allocated data such as a palette that you passed +in to libpng with png_set_*, you must not free it until just before the call to +png_destroy_write_struct(). + +The default behavior is only to free data that was allocated internally +by libpng. This can be changed, so that libpng will not free the data, +or so that it will free data that was allocated by the user with png_malloc() +or png_zalloc() and passed in via a png_set_*() function, with + + png_data_freer(png_ptr, info_ptr, freer, mask) + mask - which data elements are affected + same choices as in png_free_data() + freer - one of + PNG_DESTROY_WILL_FREE_DATA + PNG_SET_WILL_FREE_DATA + PNG_USER_WILL_FREE_DATA + +For example, to transfer responsibility for some data from a read structure +to a write structure, you could use + + png_data_freer(read_ptr, read_info_ptr, + PNG_USER_WILL_FREE_DATA, + PNG_FREE_PLTE|PNG_FREE_tRNS|PNG_FREE_hIST) + png_data_freer(write_ptr, write_info_ptr, + PNG_DESTROY_WILL_FREE_DATA, + PNG_FREE_PLTE|PNG_FREE_tRNS|PNG_FREE_hIST) + +thereby briefly reassigning responsibility for freeing to the user but +immediately afterwards reassigning it once more to the write_destroy +function. Having done this, it would then be safe to destroy the read +structure and continue to use the PLTE, tRNS, and hIST data in the write +structure. + +This function only affects data that has already been allocated. +You can call this function before calling after the png_set_*() functions +to control whether the user or png_destroy_*() is supposed to free the data. +When the user assumes responsibility for libpng-allocated data, the +application must use +png_free() to free it, and when the user transfers responsibility to libpng +for data that the user has allocated, the user must have used png_malloc() +or png_zalloc() to allocate it. + +If you allocated text_ptr.text, text_ptr.lang, and text_ptr.translated_keyword +separately, do not transfer responsibility for freeing text_ptr to libpng, +because when libpng fills a png_text structure it combines these members with +the key member, and png_free_data() will free only text_ptr.key. Similarly, +if you transfer responsibility for free'ing text_ptr from libpng to your +application, your application must not separately free those members. +For a more compact example of writing a PNG image, see the file example.c. + +.SH V. Modifying/Customizing libpng: + +There are three issues here. The first is changing how libpng does +standard things like memory allocation, input/output, and error handling. +The second deals with more complicated things like adding new chunks, +adding new transformations, and generally changing how libpng works. +Both of those are compile-time issues; that is, they are generally +determined at the time the code is written, and there is rarely a need +to provide the user with a means of changing them. The third is a +run-time issue: choosing between and/or tuning one or more alternate +versions of computationally intensive routines; specifically, optimized +assembly-language (and therefore compiler- and platform-dependent) +versions. + +Memory allocation, input/output, and error handling + +All of the memory allocation, input/output, and error handling in libpng +goes through callbacks that are user-settable. The default routines are +in pngmem.c, pngrio.c, pngwio.c, and pngerror.c, respectively. To change +these functions, call the appropriate png_set_*_fn() function. + +Memory allocation is done through the functions png_malloc() +and png_free(). These currently just call the standard C functions. If +your pointers can't access more then 64K at a time, you will want to set +MAXSEG_64K in zlib.h. Since it is unlikely that the method of handling +memory allocation on a platform will change between applications, these +functions must be modified in the library at compile time. If you prefer +to use a different method of allocating and freeing data, you can use +png_create_read_struct_2() or png_create_write_struct_2() to register +your own functions as described above. +These functions also provide a void pointer that can be retrieved via + + mem_ptr=png_get_mem_ptr(png_ptr); + +Your replacement memory functions must have prototypes as follows: + + png_voidp malloc_fn(png_structp png_ptr, + png_size_t size); + void free_fn(png_structp png_ptr, png_voidp ptr); + +Your malloc_fn() must return NULL in case of failure. The png_malloc() +function will normally call png_error() if it receives a NULL from the +system memory allocator or from your replacement malloc_fn(). + +Input/Output in libpng is done through png_read() and png_write(), +which currently just call fread() and fwrite(). The FILE * is stored in +png_struct and is initialized via png_init_io(). If you wish to change +the method of I/O, the library supplies callbacks that you can set +through the function png_set_read_fn() and png_set_write_fn() at run +time, instead of calling the png_init_io() function. These functions +also provide a void pointer that can be retrieved via the function +png_get_io_ptr(). For example: + + png_set_read_fn(png_structp read_ptr, + voidp read_io_ptr, png_rw_ptr read_data_fn) + + png_set_write_fn(png_structp write_ptr, + voidp write_io_ptr, png_rw_ptr write_data_fn, + png_flush_ptr output_flush_fn); + + voidp read_io_ptr = png_get_io_ptr(read_ptr); + voidp write_io_ptr = png_get_io_ptr(write_ptr); + +The replacement I/O functions must have prototypes as follows: + + void user_read_data(png_structp png_ptr, + png_bytep data, png_size_t length); + void user_write_data(png_structp png_ptr, + png_bytep data, png_size_t length); + void user_flush_data(png_structp png_ptr); + +Supplying NULL for the read, write, or flush functions sets them back +to using the default C stream functions. It is an error to read from +a write stream, and vice versa. + +Error handling in libpng is done through png_error() and png_warning(). +Errors handled through png_error() are fatal, meaning that png_error() +should never return to its caller. Currently, this is handled via +setjmp() and longjmp() (unless you have compiled libpng with +PNG_SETJMP_NOT_SUPPORTED, in which case it is handled via PNG_ABORT()), +but you could change this to do things like exit() if you should wish. + +On non-fatal errors, png_warning() is called +to print a warning message, and then control returns to the calling code. +By default png_error() and png_warning() print a message on stderr via +fprintf() unless the library is compiled with PNG_NO_CONSOLE_IO defined +(because you don't want the messages) or PNG_NO_STDIO defined (because +fprintf() isn't available). If you wish to change the behavior of the error +functions, you will need to set up your own message callbacks. These +functions are normally supplied at the time that the png_struct is created. +It is also possible to redirect errors and warnings to your own replacement +functions after png_create_*_struct() has been called by calling: + + png_set_error_fn(png_structp png_ptr, + png_voidp error_ptr, png_error_ptr error_fn, + png_error_ptr warning_fn); + + png_voidp error_ptr = png_get_error_ptr(png_ptr); + +If NULL is supplied for either error_fn or warning_fn, then the libpng +default function will be used, calling fprintf() and/or longjmp() if a +problem is encountered. The replacement error functions should have +parameters as follows: + + void user_error_fn(png_structp png_ptr, + png_const_charp error_msg); + void user_warning_fn(png_structp png_ptr, + png_const_charp warning_msg); + +The motivation behind using setjmp() and longjmp() is the C++ throw and +catch exception handling methods. This makes the code much easier to write, +as there is no need to check every return code of every function call. +However, there are some uncertainties about the status of local variables +after a longjmp, so the user may want to be careful about doing anything after +setjmp returns non-zero besides returning itself. Consult your compiler +documentation for more details. For an alternative approach, you may wish +to use the "cexcept" facility (see http://cexcept.sourceforge.net). + +.SS Custom chunks + +If you need to read or write custom chunks, you may need to get deeper +into the libpng code. The library now has mechanisms for storing +and writing chunks of unknown type; you can even declare callbacks +for custom chunks. However, this may not be good enough if the +library code itself needs to know about interactions between your +chunk and existing `intrinsic' chunks. + +If you need to write a new intrinsic chunk, first read the PNG +specification. Acquire a first level of +understanding of how it works. Pay particular attention to the +sections that describe chunk names, and look at how other chunks were +designed, so you can do things similarly. Second, check out the +sections of libpng that read and write chunks. Try to find a chunk +that is similar to yours and use it as a template. More details can +be found in the comments inside the code. It is best to handle unknown +chunks in a generic method, via callback functions, instead of by +modifying libpng functions. + +If you wish to write your own transformation for the data, look through +the part of the code that does the transformations, and check out some of +the simpler ones to get an idea of how they work. Try to find a similar +transformation to the one you want to add and copy off of it. More details +can be found in the comments inside the code itself. + +.SS Configuring for 16 bit platforms + +You will want to look into zconf.h to tell zlib (and thus libpng) that +it cannot allocate more then 64K at a time. Even if you can, the memory +won't be accessible. So limit zlib and libpng to 64K by defining MAXSEG_64K. + +.SS Configuring for DOS + +For DOS users who only have access to the lower 640K, you will +have to limit zlib's memory usage via a png_set_compression_mem_level() +call. See zlib.h or zconf.h in the zlib library for more information. + +.SS Configuring for Medium Model + +Libpng's support for medium model has been tested on most of the popular +compilers. Make sure MAXSEG_64K gets defined, USE_FAR_KEYWORD gets +defined, and FAR gets defined to far in pngconf.h, and you should be +all set. Everything in the library (except for zlib's structure) is +expecting far data. You must use the typedefs with the p or pp on +the end for pointers (or at least look at them and be careful). Make +note that the rows of data are defined as png_bytepp, which is an +unsigned char far * far *. + +.SS Configuring for gui/windowing platforms: + +You will need to write new error and warning functions that use the GUI +interface, as described previously, and set them to be the error and +warning functions at the time that png_create_*_struct() is called, +in order to have them available during the structure initialization. +They can be changed later via png_set_error_fn(). On some compilers, +you may also have to change the memory allocators (png_malloc, etc.). + +.SS Configuring for compiler xxx: + +All includes for libpng are in pngconf.h. If you need to add/change/delete +an include, this is the place to do it. The includes that are not +needed outside libpng are protected by the PNG_INTERNAL definition, +which is only defined for those routines inside libpng itself. The +files in libpng proper only include png.h, which includes pngconf.h. + +.SS Configuring zlib: + +There are special functions to configure the compression. Perhaps the +most useful one changes the compression level, which currently uses +input compression values in the range 0 - 9. The library normally +uses the default compression level (Z_DEFAULT_COMPRESSION = 6). Tests +have shown that for a large majority of images, compression values in +the range 3-6 compress nearly as well as higher levels, and do so much +faster. For online applications it may be desirable to have maximum speed +(Z_BEST_SPEED = 1). With versions of zlib after v0.99, you can also +specify no compression (Z_NO_COMPRESSION = 0), but this would create +files larger than just storing the raw bitmap. You can specify the +compression level by calling: + + png_set_compression_level(png_ptr, level); + +Another useful one is to reduce the memory level used by the library. +The memory level defaults to 8, but it can be lowered if you are +short on memory (running DOS, for example, where you only have 640K). +Note that the memory level does have an effect on compression; among +other things, lower levels will result in sections of incompressible +data being emitted in smaller stored blocks, with a correspondingly +larger relative overhead of up to 15% in the worst case. + + png_set_compression_mem_level(png_ptr, level); + +The other functions are for configuring zlib. They are not recommended +for normal use and may result in writing an invalid PNG file. See +zlib.h for more information on what these mean. + + png_set_compression_strategy(png_ptr, + strategy); + png_set_compression_window_bits(png_ptr, + window_bits); + png_set_compression_method(png_ptr, method); + png_set_compression_buffer_size(png_ptr, size); + +.SS Controlling row filtering + +If you want to control whether libpng uses filtering or not, which +filters are used, and how it goes about picking row filters, you +can call one of these functions. The selection and configuration +of row filters can have a significant impact on the size and +encoding speed and a somewhat lesser impact on the decoding speed +of an image. Filtering is enabled by default for RGB and grayscale +images (with and without alpha), but not for paletted images nor +for any images with bit depths less than 8 bits/pixel. + +The 'method' parameter sets the main filtering method, which is +currently only '0' in the PNG 1.2 specification. The 'filters' +parameter sets which filter(s), if any, should be used for each +scanline. Possible values are PNG_ALL_FILTERS and PNG_NO_FILTERS +to turn filtering on and off, respectively. + +Individual filter types are PNG_FILTER_NONE, PNG_FILTER_SUB, +PNG_FILTER_UP, PNG_FILTER_AVG, PNG_FILTER_PAETH, which can be bitwise +ORed together with '|' to specify one or more filters to use. +These filters are described in more detail in the PNG specification. +If you intend to change the filter type during the course of writing +the image, you should start with flags set for all of the filters +you intend to use so that libpng can initialize its internal +structures appropriately for all of the filter types. (Note that this +means the first row must always be adaptively filtered, because libpng +currently does not allocate the filter buffers until png_write_row() +is called for the first time.) + + filters = PNG_FILTER_NONE | PNG_FILTER_SUB + PNG_FILTER_UP | PNG_FILTER_AVE | + PNG_FILTER_PAETH | PNG_ALL_FILTERS; + + png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, + filters); + The second parameter can also be + PNG_INTRAPIXEL_DIFFERENCING if you are + writing a PNG to be embedded in a MNG + datastream. This parameter must be the + same as the value of filter_method used + in png_set_IHDR(). + +It is also possible to influence how libpng chooses from among the +available filters. This is done in one or both of two ways - by +telling it how important it is to keep the same filter for successive +rows, and by telling it the relative computational costs of the filters. + + double weights[3] = {1.5, 1.3, 1.1}, + costs[PNG_FILTER_VALUE_LAST] = + {1.0, 1.3, 1.3, 1.5, 1.7}; + + png_set_filter_heuristics(png_ptr, + PNG_FILTER_HEURISTIC_WEIGHTED, 3, + weights, costs); + +The weights are multiplying factors that indicate to libpng that the +row filter should be the same for successive rows unless another row filter +is that many times better than the previous filter. In the above example, +if the previous 3 filters were SUB, SUB, NONE, the SUB filter could have a +"sum of absolute differences" 1.5 x 1.3 times higher than other filters +and still be chosen, while the NONE filter could have a sum 1.1 times +higher than other filters and still be chosen. Unspecified weights are +taken to be 1.0, and the specified weights should probably be declining +like those above in order to emphasize recent filters over older filters. + +The filter costs specify for each filter type a relative decoding cost +to be considered when selecting row filters. This means that filters +with higher costs are less likely to be chosen over filters with lower +costs, unless their "sum of absolute differences" is that much smaller. +The costs do not necessarily reflect the exact computational speeds of +the various filters, since this would unduly influence the final image +size. + +Note that the numbers above were invented purely for this example and +are given only to help explain the function usage. Little testing has +been done to find optimum values for either the costs or the weights. + +.SS Removing unwanted object code + +There are a bunch of #define's in pngconf.h that control what parts of +libpng are compiled. All the defines end in _SUPPORTED. If you are +never going to use a capability, you can change the #define to #undef +before recompiling libpng and save yourself code and data space, or +you can turn off individual capabilities with defines that begin with +PNG_NO_. + +You can also turn all of the transforms and ancillary chunk capabilities +off en masse with compiler directives that define +PNG_NO_READ[or WRITE]_TRANSFORMS, or PNG_NO_READ[or WRITE]_ANCILLARY_CHUNKS, +or all four, +along with directives to turn on any of the capabilities that you do +want. The PNG_NO_READ[or WRITE]_TRANSFORMS directives disable +the extra transformations but still leave the library fully capable of reading +and writing PNG files with all known public chunks +Use of the PNG_NO_READ[or WRITE]_ANCILLARY_CHUNKS directive +produces a library that is incapable of reading or writing ancillary chunks. +If you are not using the progressive reading capability, you can +turn that off with PNG_NO_PROGRESSIVE_READ (don't confuse +this with the INTERLACING capability, which you'll still have). + +All the reading and writing specific code are in separate files, so the +linker should only grab the files it needs. However, if you want to +make sure, or if you are building a stand alone library, all the +reading files start with pngr and all the writing files start with +pngw. The files that don't match either (like png.c, pngtrans.c, etc.) +are used for both reading and writing, and always need to be included. +The progressive reader is in pngpread.c + +If you are creating or distributing a dynamically linked library (a .so +or DLL file), you should not remove or disable any parts of the library, +as this will cause applications linked with different versions of the +library to fail if they call functions not available in your library. +The size of the library itself should not be an issue, because only +those sections that are actually used will be loaded into memory. + +.SS Requesting debug printout + +The macro definition PNG_DEBUG can be used to request debugging +printout. Set it to an integer value in the range 0 to 3. Higher +numbers result in increasing amounts of debugging information. The +information is printed to the "stderr" file, unless another file +name is specified in the PNG_DEBUG_FILE macro definition. + +When PNG_DEBUG > 0, the following functions (macros) become available: + + png_debug(level, message) + png_debug1(level, message, p1) + png_debug2(level, message, p1, p2) + +in which "level" is compared to PNG_DEBUG to decide whether to print +the message, "message" is the formatted string to be printed, +and p1 and p2 are parameters that are to be embedded in the string +according to printf-style formatting directives. For example, + + png_debug1(2, "foo=%d\n", foo); + +is expanded to + + if(PNG_DEBUG > 2) + fprintf(PNG_DEBUG_FILE, "foo=%d\n", foo); + +When PNG_DEBUG is defined but is zero, the macros aren't defined, but you +can still use PNG_DEBUG to control your own debugging: + + #ifdef PNG_DEBUG + fprintf(stderr, ... + #endif + +When PNG_DEBUG = 1, the macros are defined, but only png_debug statements +having level = 0 will be printed. There aren't any such statements in +this version of libpng, but if you insert some they will be printed. + +.SH VI. Runtime optimization + +A new feature in libpng 1.2.0 is the ability to dynamically switch between +standard and optimized versions of some routines. Currently these are +limited to three computationally intensive tasks when reading PNG files: +decoding row filters, expanding interlacing, and combining interlaced or +transparent row data with previous row data. Currently the optimized +versions are available only for x86 (Intel, AMD, etc.) platforms with +MMX support, though this may change in future versions. (For example, +the non-MMX assembler optimizations for zlib might become similarly +runtime-selectable in future releases, in which case libpng could be +extended to support them. Alternatively, the compile-time choice of +floating-point versus integer routines for gamma correction might become +runtime-selectable.) + +Because such optimizations tend to be very platform- and compiler-dependent, +both in how they are written and in how they perform, the new runtime code +in libpng has been written to allow programs to query, enable, and disable +either specific optimizations or all such optimizations. For example, to +enable all possible optimizations (bearing in mind that some "optimizations" +may actually run more slowly in rare cases): + + #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200) + png_uint_32 mask, flags; + + flags = png_get_asm_flags(png_ptr); + mask = png_get_asm_flagmask(PNG_SELECT_READ | PNG_SELECT_WRITE); + png_set_asm_flags(png_ptr, flags | mask); + #endif + +To enable only optimizations relevant to reading PNGs, use PNG_SELECT_READ +by itself when calling png_get_asm_flagmask(); similarly for optimizing +only writing. To disable all optimizations: + + #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200) + flags = png_get_asm_flags(png_ptr); + mask = png_get_asm_flagmask(PNG_SELECT_READ | PNG_SELECT_WRITE); + png_set_asm_flags(png_ptr, flags & ~mask); + #endif + +To enable or disable only MMX-related features, use png_get_mmx_flagmask() +in place of png_get_asm_flagmask(). The mmx version takes one additional +parameter: + + #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200) + int selection = PNG_SELECT_READ | PNG_SELECT_WRITE; + int compilerID; + + mask = png_get_mmx_flagmask(selection, &compilerID); + #endif + +On return, compilerID will indicate which version of the MMX assembler +optimizations was compiled. Currently two flavors exist: Microsoft +Visual C++ (compilerID == 1) and GNU C (a.k.a. gcc/gas, compilerID == 2). +On non-x86 platforms or on systems compiled without MMX optimizations, a +value of -1 is used. + +Note that both png_get_asm_flagmask() and png_get_mmx_flagmask() return +all valid, settable optimization bits for the version of the library that's +currently in use. In the case of shared (dynamically linked) libraries, +this may include optimizations that did not exist at the time the code was +written and compiled. It is also possible, of course, to enable only known, +specific optimizations; for example: + + #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200) + flags = PNG_ASM_FLAG_MMX_READ_COMBINE_ROW \ + | PNG_ASM_FLAG_MMX_READ_INTERLACE \ + | PNG_ASM_FLAG_MMX_READ_FILTER_SUB \ + | PNG_ASM_FLAG_MMX_READ_FILTER_UP \ + | PNG_ASM_FLAG_MMX_READ_FILTER_AVG \ + | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ; + png_set_asm_flags(png_ptr, flags); + #endif + +This method would enable only the MMX read-optimizations available at the +time of libpng 1.2.0's release, regardless of whether a later version of +the DLL were actually being used. (Also note that these functions did not +exist in versions older than 1.2.0, so any attempt to run a dynamically +linked app on such an older version would fail.) + +To determine whether the processor supports MMX instructions at all, use +the png_mmx_support() function: + + #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200) + mmxsupport = png_mmx_support(); + #endif + +It returns -1 if MMX support is not compiled into libpng, 0 if MMX code +is compiled but MMX is not supported by the processor, or 1 if MMX support +is fully available. Note that png_mmx_support(), png_get_mmx_flagmask(), +and png_get_asm_flagmask() all may be called without allocating and ini- +tializing any PNG structures (for example, as part of a usage screen or +"about" box). + +The following code can be used to prevent an application from using the +thread_unsafe features, even if libpng was built with PNG_THREAD_UNSAFE_OK +defined: + +#if defined(PNG_USE_PNGGCCRD) && defined(PNG_ASSEMBLER_CODE_SUPPORTED) \ + && defined(PNG_THREAD_UNSAFE_OK) + /* Disable thread-unsafe features of pnggccrd */ + if (png_access_version_number() >= 10200) + { + png_uint_32 mmx_disable_mask = 0; + png_uint_32 asm_flags; + + mmx_disable_mask |= ( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW \ + | PNG_ASM_FLAG_MMX_READ_FILTER_SUB \ + | PNG_ASM_FLAG_MMX_READ_FILTER_AVG \ + | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ); + asm_flags = png_get_asm_flags(png_ptr); + png_set_asm_flags(png_ptr, asm_flags & ~mmx_disable_mask); + } +#endif + +For more extensive examples of runtime querying, enabling and disabling +of optimized features, see contrib/gregbook/readpng2.c in the libpng +source-code distribution. + +.SH VII. MNG support + +The MNG specification (available at http://www.libpng.org/pub/mng) allows +certain extensions to PNG for PNG images that are embedded in MNG datastreams. +Libpng can support some of these extensions. To enable them, use the +png_permit_mng_features() function: + + feature_set = png_permit_mng_features(png_ptr, mask) + mask is a png_uint_32 containing the logical OR of the + features you want to enable. These include + PNG_FLAG_MNG_EMPTY_PLTE + PNG_FLAG_MNG_FILTER_64 + PNG_ALL_MNG_FEATURES + feature_set is a png_uint_32 that is the logical AND of + your mask with the set of MNG features that is + supported by the version of libpng that you are using. + +It is an error to use this function when reading or writing a standalone +PNG file with the PNG 8-byte signature. The PNG datastream must be wrapped +in a MNG datastream. As a minimum, it must have the MNG 8-byte signature +and the MHDR and MEND chunks. Libpng does not provide support for these +or any other MNG chunks; your application must provide its own support for +them. You may wish to consider using libmng (available at +http://www.libmng.com) instead. + +.SH VIII. Changes to Libpng from version 0.88 + +It should be noted that versions of libpng later than 0.96 are not +distributed by the original libpng author, Guy Schalnat, nor by +Andreas Dilger, who had taken over from Guy during 1996 and 1997, and +distributed versions 0.89 through 0.96, but rather by another member +of the original PNG Group, Glenn Randers-Pehrson. Guy and Andreas are +still alive and well, but they have moved on to other things. + +The old libpng functions png_read_init(), png_write_init(), +png_info_init(), png_read_destroy(), and png_write_destroy() have been +moved to PNG_INTERNAL in version 0.95 to discourage their use. These +functions will be removed from libpng version 2.0.0. + +The preferred method of creating and initializing the libpng structures is +via the png_create_read_struct(), png_create_write_struct(), and +png_create_info_struct() because they isolate the size of the structures +from the application, allow version error checking, and also allow the +use of custom error handling routines during the initialization, which +the old functions do not. The functions png_read_destroy() and +png_write_destroy() do not actually free the memory that libpng +allocated for these structs, but just reset the data structures, so they +can be used instead of png_destroy_read_struct() and +png_destroy_write_struct() if you feel there is too much system overhead +allocating and freeing the png_struct for each image read. + +Setting the error callbacks via png_set_message_fn() before +png_read_init() as was suggested in libpng-0.88 is no longer supported +because this caused applications that do not use custom error functions +to fail if the png_ptr was not initialized to zero. It is still possible +to set the error callbacks AFTER png_read_init(), or to change them with +png_set_error_fn(), which is essentially the same function, but with a new +name to force compilation errors with applications that try to use the old +method. + +Starting with version 1.0.7, you can find out which version of the library +you are using at run-time: + + png_uint_32 libpng_vn = png_access_version_number(); + +The number libpng_vn is constructed from the major version, minor +version with leading zero, and release number with leading zero, +(e.g., libpng_vn for version 1.0.7 is 10007). + +You can also check which version of png.h you used when compiling your +application: + + png_uint_32 application_vn = PNG_LIBPNG_VER; + +.SH IX. Y2K Compliance in libpng + +June 27, 2006 + +Since the PNG Development group is an ad-hoc body, we can't make +an official declaration. + +This is your unofficial assurance that libpng from version 0.71 and +upward through 1.2.12 are Y2K compliant. It is my belief that earlier +versions were also Y2K compliant. + +Libpng only has three year fields. One is a 2-byte unsigned integer that +will hold years up to 65535. The other two hold the date in text +format, and will hold years up to 9999. + +The integer is + "png_uint_16 year" in png_time_struct. + +The strings are + "png_charp time_buffer" in png_struct and + "near_time_buffer", which is a local character string in png.c. + +There are seven time-related functions: + + png_convert_to_rfc_1123() in png.c + (formerly png_convert_to_rfc_1152() in error) + png_convert_from_struct_tm() in pngwrite.c, called + in pngwrite.c + png_convert_from_time_t() in pngwrite.c + png_get_tIME() in pngget.c + png_handle_tIME() in pngrutil.c, called in pngread.c + png_set_tIME() in pngset.c + png_write_tIME() in pngwutil.c, called in pngwrite.c + +All appear to handle dates properly in a Y2K environment. The +png_convert_from_time_t() function calls gmtime() to convert from system +clock time, which returns (year - 1900), which we properly convert to +the full 4-digit year. There is a possibility that applications using +libpng are not passing 4-digit years into the png_convert_to_rfc_1123() +function, or that they are incorrectly passing only a 2-digit year +instead of "year - 1900" into the png_convert_from_struct_tm() function, +but this is not under our control. The libpng documentation has always +stated that it works with 4-digit years, and the APIs have been +documented as such. + +The tIME chunk itself is also Y2K compliant. It uses a 2-byte unsigned +integer to hold the year, and can hold years as large as 65535. + +zlib, upon which libpng depends, is also Y2K compliant. It contains +no date-related code. + + + Glenn Randers-Pehrson + libpng maintainer + PNG Development Group + +.SH NOTE + +Note about libpng version numbers: + +Due to various miscommunications, unforeseen code incompatibilities +and occasional factors outside the authors' control, version numbering +on the library has not always been consistent and straightforward. +The following table summarizes matters since version 0.89c, which was +the first widely used release: + + source png.h png.h shared-lib + version string int version + ------- ------ ----- ---------- + 0.89c ("beta 3") 0.89 89 1.0.89 + 0.90 ("beta 4") 0.90 90 0.90 + 0.95 ("beta 5") 0.95 95 0.95 + 0.96 ("beta 6") 0.96 96 0.96 + 0.97b ("beta 7") 1.00.97 97 1.0.1 + 0.97c 0.97 97 2.0.97 + 0.98 0.98 98 2.0.98 + 0.99 0.99 98 2.0.99 + 0.99a-m 0.99 99 2.0.99 + 1.00 1.00 100 2.1.0 + 1.0.0 1.0.0 100 2.1.0 + 1.0.0 (from here on, the 100 2.1.0 + 1.0.1 png.h string is 10001 2.1.0 + 1.0.1a-e identical to the 10002 from here on, the + 1.0.2 source version) 10002 shared library is 2.V + 1.0.2a-b 10003 where V is the source + 1.0.1 10001 code version except as + 1.0.1a-e 10002 2.1.0.1a-e noted. + 1.0.2 10002 2.1.0.2 + 1.0.2a-b 10003 2.1.0.2a-b + 1.0.3 10003 2.1.0.3 + 1.0.3a-d 10004 2.1.0.3a-d + 1.0.4 10004 2.1.0.4 + 1.0.4a-f 10005 2.1.0.4a-f + 1.0.5 (+ 2 patches) 10005 2.1.0.5 + 1.0.5a-d 10006 2.1.0.5a-d + 1.0.5e-r 10100 2.1.0.5e-r + 1.0.5s-v 10006 2.1.0.5s-v + 1.0.6 (+ 3 patches) 10006 2.1.0.6 + 1.0.6d-g 10007 2.1.0.6d-g + 1.0.6h 10007 10.6h + 1.0.6i 10007 10.6i + 1.0.6j 10007 2.1.0.6j + 1.0.7beta11-14 DLLNUM 10007 2.1.0.7beta11-14 + 1.0.7beta15-18 1 10007 2.1.0.7beta15-18 + 1.0.7rc1-2 1 10007 2.1.0.7rc1-2 + 1.0.7 1 10007 2.1.0.7 + 1.0.8beta1-4 1 10008 2.1.0.8beta1-4 + 1.0.8rc1 1 10008 2.1.0.8rc1 + 1.0.8 1 10008 2.1.0.8 + 1.0.9beta1-6 1 10009 2.1.0.9beta1-6 + 1.0.9rc1 1 10009 2.1.0.9rc1 + 1.0.9beta7-10 1 10009 2.1.0.9beta7-10 + 1.0.9rc2 1 10009 2.1.0.9rc2 + 1.0.9 1 10009 2.1.0.9 + 1.0.10beta1 1 10010 2.1.0.10beta1 + 1.0.10rc1 1 10010 2.1.0.10rc1 + 1.0.10 1 10010 2.1.0.10 + 1.0.11beta1-3 1 10011 2.1.0.11beta1-3 + 1.0.11rc1 1 10011 2.1.0.11rc1 + 1.0.11 1 10011 2.1.0.11 + 1.0.12beta1-2 2 10012 2.1.0.12beta1-2 + 1.0.12rc1 2 10012 2.1.0.12rc1 + 1.0.12 2 10012 2.1.0.12 + 1.1.0a-f - 10100 2.1.1.0a-f abandoned + 1.2.0beta1-2 2 10200 2.1.2.0beta1-2 + 1.2.0beta3-5 3 10200 3.1.2.0beta3-5 + 1.2.0rc1 3 10200 3.1.2.0rc1 + 1.2.0 3 10200 3.1.2.0 + 1.2.1beta-4 3 10201 3.1.2.1beta1-4 + 1.2.1rc1-2 3 10201 3.1.2.1rc1-2 + 1.2.1 3 10201 3.1.2.1 + 1.2.2beta1-6 12 10202 12.so.0.1.2.2beta1-6 + 1.0.13beta1 10 10013 10.so.0.1.0.13beta1 + 1.0.13rc1 10 10013 10.so.0.1.0.13rc1 + 1.2.2rc1 12 10202 12.so.0.1.2.2rc1 + 1.0.13 10 10013 10.so.0.1.0.13 + 1.2.2 12 10202 12.so.0.1.2.2 + 1.2.3rc1-6 12 10203 12.so.0.1.2.3rc1-6 + 1.2.3 12 10203 12.so.0.1.2.3 + 1.2.4beta1-3 13 10204 12.so.0.1.2.4beta1-3 + 1.2.4rc1 13 10204 12.so.0.1.2.4rc1 + 1.0.14 10 10014 10.so.0.1.0.14 + 1.2.4 13 10204 12.so.0.1.2.4 + 1.2.5beta1-2 13 10205 12.so.0.1.2.5beta1-2 + 1.0.15rc1 10 10015 10.so.0.1.0.15rc1 + 1.0.15 10 10015 10.so.0.1.0.15 + 1.2.5 13 10205 12.so.0.1.2.5 + 1.2.6beta1-4 13 10206 12.so.0.1.2.6beta1-4 + 1.2.6rc1-5 13 10206 12.so.0.1.2.6rc1-5 + 1.0.16 10 10016 10.so.0.1.0.16 + 1.2.6 13 10206 12.so.0.1.2.6 + 1.2.7beta1-2 13 10207 12.so.0.1.2.7beta1-2 + 1.0.17rc1 10 10017 10.so.0.1.0.17rc1 + 1.2.7rc1 13 10207 12.so.0.1.2.7rc1 + 1.0.17 10 10017 10.so.0.1.0.17 + 1.2.7 13 10207 12.so.0.1.2.7 + 1.2.8beta1-5 13 10208 12.so.0.1.2.8beta1-5 + 1.0.18rc1-5 10 10018 10.so.0.1.0.18rc1-5 + 1.2.8rc1-5 13 10208 12.so.0.1.2.8rc1-5 + 1.0.18 10 10018 10.so.0.1.0.18 + 1.2.8 13 10208 12.so.0.1.2.8 + 1.2.9beta1-3 13 10209 12.so.0.1.2.9beta1-3 + 1.2.9beta4-11 13 10209 12.so.0.9[.0] + 1.2.9rc1 13 10209 12.so.0.9[.0] + 1.2.9 13 10209 12.so.0.9[.0] + 1.2.10beta1-8 13 10210 12.so.0.10[.0] + 1.2.10rc1-3 13 10210 12.so.0.10[.0] + 1.2.10 13 10210 12.so.0.10[.0] + 1.2.11beta1-4 13 10211 12.so.0.11[.0] + 1.0.19rc1-5 10 10019 10.so.0.19[.0] + 1.2.11rc1-5 13 10211 12.so.0.11[.0] + 1.0.19 10 10019 10.so.0.19[.0] + 1.2.11 13 10211 12.so.0.11[.0] + 1.0.20 10 10020 10.so.0.20[.0] + 1.2.12 13 10212 12.so.0.12[.0] + +Henceforth the source version will match the shared-library minor +and patch numbers; the shared-library major version number will be +used for changes in backward compatibility, as it is intended. The +PNG_PNGLIB_VER macro, which is not used within libpng but is available +for applications, is an unsigned integer of the form xyyzz corresponding +to the source version x.y.z (leading zeros in y and z). Beta versions +were given the previous public release number plus a letter, until +version 1.0.6j; from then on they were given the upcoming public +release number plus "betaNN" or "rcN". + +.SH "SEE ALSO" +libpngpf(3), png(5) +.LP +.IR libpng : +.IP +http://libpng.sourceforge.net (follow the [DOWNLOAD] link) +http://www.libpng.org/pub/png + +.LP +.IR zlib : +.IP +(generally) at the same location as +.I libpng +or at +.br +ftp://ftp.info-zip.org/pub/infozip/zlib + +.LP +.IR PNG specification: RFC 2083 +.IP +(generally) at the same location as +.I libpng +or at +.br +ftp://ds.internic.net/rfc/rfc2083.txt +.br +or (as a W3C Recommendation) at +.br +http://www.w3.org/TR/REC-png.html + +.LP +In the case of any inconsistency between the PNG specification +and this library, the specification takes precedence. + +.SH AUTHORS +This man page: Glenn Randers-Pehrson +<glennrp at users.sourceforge.net> + +The contributing authors would like to thank all those who helped +with testing, bug fixes, and patience. This wouldn't have been +possible without all of you. + +Thanks to Frank J. T. Wojcik for helping with the documentation. + +Libpng version 1.2.12 - June 27, 2006: +Initially created in 1995 by Guy Eric Schalnat, then of Group 42, Inc. +Currently maintained by Glenn Randers-Pehrson (glennrp at users.sourceforge.net). + +Supported by the PNG development group +.br +png-mng-implement at lists.sf.net +(subscription required; visit +png-mng-implement at lists.sourceforge.net (subscription required; visit +https://lists.sourceforge.net/lists/listinfo/png-mng-implement +to subscribe). + +.SH COPYRIGHT NOTICE, DISCLAIMER, and LICENSE: + +(This copy of the libpng notices is provided for your convenience. In case of +any discrepancy between this copy and the notices in the file png.h that is +included in the libpng distribution, the latter shall prevail.) + +If you modify libpng you may insert additional notices immediately following +this sentence. + +libpng versions 1.2.6, August 15, 2004, through 1.2.12, June 27, 2006, are +Copyright (c) 2004-2006 Glenn Randers-Pehrson, and are +distributed according to the same disclaimer and license as libpng-1.2.5 +with the following individual added to the list of Contributing Authors + + Cosmin Truta + +libpng versions 1.0.7, July 1, 2000, through 1.2.5 - October 3, 2002, are +Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are +distributed according to the same disclaimer and license as libpng-1.0.6 +with the following individuals added to the list of Contributing Authors + + Simon-Pierre Cadieux + Eric S. Raymond + Gilles Vollant + +and with the following additions to the disclaimer: + + There is no warranty against interference with your + enjoyment of the library or against infringement. + There is no warranty that our efforts or the library + will fulfill any of your particular purposes or needs. + This library is provided with all faults, and the entire + risk of satisfactory quality, performance, accuracy, and + effort is with the user. + +libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are +Copyright (c) 1998, 1999 Glenn Randers-Pehrson +Distributed according to the same disclaimer and license as libpng-0.96, +with the following individuals added to the list of Contributing Authors: + + Tom Lane + Glenn Randers-Pehrson + Willem van Schaik + +libpng versions 0.89, June 1996, through 0.96, May 1997, are +Copyright (c) 1996, 1997 Andreas Dilger +Distributed according to the same disclaimer and license as libpng-0.88, +with the following individuals added to the list of Contributing Authors: + + John Bowler + Kevin Bracey + Sam Bushell + Magnus Holmgren + Greg Roelofs + Tom Tanner + +libpng versions 0.5, May 1995, through 0.88, January 1996, are +Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc. + +For the purposes of this copyright and license, "Contributing Authors" +is defined as the following set of individuals: + + Andreas Dilger + Dave Martindale + Guy Eric Schalnat + Paul Schmidt + Tim Wegner + +The PNG Reference Library is supplied "AS IS". The Contributing Authors +and Group 42, Inc. disclaim all warranties, expressed or implied, +including, without limitation, the warranties of merchantability and of +fitness for any purpose. The Contributing Authors and Group 42, Inc. +assume no liability for direct, indirect, incidental, special, exemplary, +or consequential damages, which may result from the use of the PNG +Reference Library, even if advised of the possibility of such damage. + +Permission is hereby granted to use, copy, modify, and distribute this +source code, or portions hereof, for any purpose, without fee, subject +to the following restrictions: + +1. The origin of this source code must not be misrepresented. + +2. Altered versions must be plainly marked as such and + must not be misrepresented as being the original source. + +3. This Copyright notice may not be removed or altered from + any source or altered source distribution. + +The Contributing Authors and Group 42, Inc. specifically permit, without +fee, and encourage the use of this source code as a component to +supporting the PNG file format in commercial products. If you use this +source code in a product, acknowledgment is not required but would be +appreciated. + + +A "png_get_copyright" function is available, for convenient use in "about" +boxes and the like: + + printf("%s",png_get_copyright(NULL)); + +Also, the PNG logo (in PNG format, of course) is supplied in the +files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31). + +Libpng is OSI Certified Open Source Software. OSI Certified Open Source is a +certification mark of the Open Source Initiative. + +Glenn Randers-Pehrson +glennrp at users.sourceforge.net +June 27, 2006 + +.\" end of man page + diff --git a/mod/pub.mod/libpng.mod/libpng.bmx b/mod/pub.mod/libpng.mod/libpng.bmx new file mode 100644 index 0000000..9c90c96 --- /dev/null +++ b/mod/pub.mod/libpng.mod/libpng.bmx @@ -0,0 +1,105 @@ + +Module Pub.LibPNG + +ModuleInfo "Version: 1.03" +ModuleInfo "Author: Guy Eric Schalnat, Andreas Dilger, Glenn Randers-Pehrson, Others" +ModuleInfo "License: ZLib/PNG License" +ModuleInfo "Modserver: BRL" +ModuleInfo "Credit: Adapted for BlitzMax by Mark Sibly" + +ModuleInfo "History: 1.03" +ModuleInfo "History: Fixed for Intel Macs" +ModuleInfo "History: 1.02" +ModuleInfo "History: Update to libpng 1.2.12" + +Import Pub.ZLib + +Import "png.c" +Import "pngerror.c" +Import "pngget.c" +Import "pngmem.c" +Import "pngpread.c" +Import "pngread.c" +Import "pngrio.c" +Import "pngrtran.c" +Import "pngrutil.c" +Import "pngset.c" +Import "pngtrans.c" +Import "pngwio.c" +Import "pngwrite.c" +Import "pngwtran.c" +Import "pngwutil.c" +'Import "pngvcrd.c" +?MacosX86 +Import "pnggccrd.c" +? + +Extern + +Const PNG_COLOR_MASK_PALETTE= 1 +Const PNG_COLOR_MASK_COLOR= 2 +Const PNG_COLOR_MASK_ALPHA= 4 + +Const PNG_COLOR_TYPE_GRAY= 0 +Const PNG_COLOR_TYPE_PALETTE= (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_PALETTE) +Const PNG_COLOR_TYPE_RGB= (PNG_COLOR_MASK_COLOR) +Const PNG_COLOR_TYPE_RGB_ALPHA= (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_ALPHA) +Const PNG_COLOR_TYPE_GRAY_ALPHA= (PNG_COLOR_MASK_ALPHA) +Const PNG_COLOR_TYPE_RGBA= PNG_COLOR_TYPE_RGB_ALPHA +Const PNG_COLOR_TYPE_GA= PNG_COLOR_TYPE_GRAY_ALPHA + +Const PNG_TRANSFORM_IDENTITY= $0000 'read and write +Const PNG_TRANSFORM_STRIP_16= $0001 'read only +Const PNG_TRANSFORM_STRIP_ALPHA= $0002 'read only +Const PNG_TRANSFORM_PACKING= $0004 'read and write +Const PNG_TRANSFORM_PACKSWAP= $0008 'read and write +Const PNG_TRANSFORM_EXPAND= $0010 'read only +Const PNG_TRANSFORM_INVERT_MONO= $0020 'read and write +Const PNG_TRANSFORM_SHIFT= $0040 'read and write +Const PNG_TRANSFORM_BGR= $0080 'read and write +Const PNG_TRANSFORM_SWAP_ALPHA= $0100 'read and write +Const PNG_TRANSFORM_SWAP_ENDIAN= $0200 'read and write +Const PNG_TRANSFORM_INVERT_ALPHA= $0400 'read and write +Const PNG_TRANSFORM_STRIP_FILLER= $0800 'write only + +Const PNG_COMPRESSION_TYPE_DEFAULT= 0 + +Const PNG_FILTER_TYPE_DEFAULT= 0 +Const PNG_INTRAPIXEL_DIFFERENCING= 64 + +Const PNG_INTERLACE_NONE= 0 +Const PNG_INTERLACE_ADAM7= 1 + +Function png_sig_cmp( buf:Byte Ptr,start,count ) + +Function png_create_read_struct( ver_string$z,user_error_ptr:Byte Ptr,user_error_fn:Byte Ptr,user_warning_fn:Byte Ptr) +Function png_create_write_struct( ver_string$z,user_error_ptr:Byte Ptr,user_error_fn:Byte Ptr,user_warning_fn:Byte Ptr) + +Function png_destroy_read_struct( png_ptr Ptr,info_ptr1 Ptr,info_ptr2 Ptr ) +Function png_destroy_write_struct( png_ptr Ptr,info_ptr1 Ptr,info_ptr2 Ptr ) + +Function png_create_info_struct( png_ptr ) + +Function png_init_io( png_ptr,c_stream ) +Function png_set_sig_bytes( png_ptr,number ) + +Function png_set_read_fn( png_ptr,user:Byte Ptr,read_fn(png_ptr,buf:Byte Ptr,size) ) +Function png_set_write_fn( png_ptr,user:Byte Ptr,write_fn(png_ptr,buf:Byte Ptr,size),flush_fn(png_ptr) ) + +Function png_set_expand( png_ptr ) +Function png_set_strip_16( png_ptr ) +Function png_set_gray_to_rgb( png_ptr ) + +Function png_set_compression_level( png_ptr,level ) +Function png_set_compression_strategy( png_ptr,strategy ) + +Function png_read_png( png_ptr,info_ptr,png_transforms,reserved ) +Function png_write_png( png_ptr,info_ptr,png_transforms,reserved ) + +Function png_get_rows:Byte Ptr Ptr( png_ptr,info_ptr ) +Function png_set_rows( png_ptr,info_ptr,rows:Byte Ptr ) + +Function png_get_IHDR( png_ptr,info_ptr,width Var,height Var,bit_depth Var,color_type Var,interlace_type Var,compression_type Var,filter_method Var ) +Function png_set_IHDR( png_ptr,info_ptr,width,height,bit_depth,color_type,interlace_type,compression_type,filter_method ) + +End Extern diff --git a/mod/pub.mod/libpng.mod/libpng.txt b/mod/pub.mod/libpng.mod/libpng.txt new file mode 100644 index 0000000..25a276b --- /dev/null +++ b/mod/pub.mod/libpng.mod/libpng.txt @@ -0,0 +1,2972 @@ +libpng.txt - A description on how to use and modify libpng + + libpng version 1.2.12 - June 27, 2006 + Updated and distributed by Glenn Randers-Pehrson + <glennrp at users.sourceforge.net> + Copyright (c) 1998-2005 Glenn Randers-Pehrson + For conditions of distribution and use, see copyright + notice in png.h. + + based on: + + libpng 1.0 beta 6 version 0.96 May 28, 1997 + Updated and distributed by Andreas Dilger + Copyright (c) 1996, 1997 Andreas Dilger + + libpng 1.0 beta 2 - version 0.88 January 26, 1996 + For conditions of distribution and use, see copyright + notice in png.h. Copyright (c) 1995, 1996 Guy Eric + Schalnat, Group 42, Inc. + + Updated/rewritten per request in the libpng FAQ + Copyright (c) 1995, 1996 Frank J. T. Wojcik + December 18, 1995 & January 20, 1996 + +I. Introduction + +This file describes how to use and modify the PNG reference library +(known as libpng) for your own use. There are five sections to this +file: introduction, structures, reading, writing, and modification and +configuration notes for various special platforms. In addition to this +file, example.c is a good starting point for using the library, as +it is heavily commented and should include everything most people +will need. We assume that libpng is already installed; see the +INSTALL file for instructions on how to install libpng. + +Libpng was written as a companion to the PNG specification, as a way +of reducing the amount of time and effort it takes to support the PNG +file format in application programs. + +The PNG specification (second edition), November 2003, is available as +a W3C Recommendation and as an ISO Standard (ISO/IEC 15948:2003 (E)) at +<http://www.w3.org/TR/2003/REC-PNG-20031110/ +The W3C and ISO documents have identical technical content. + +The PNG-1.2 specification is available at +<http://www.libpng.org/pub/png/documents/> + +The PNG-1.0 specification is available +as RFC 2083 <http://www.libpng.org/pub/png/documents/> and as a +W3C Recommendation <http://www.w3.org/TR/REC.png.html>. Some +additional chunks are described in the special-purpose public chunks +documents at <http://www.libpng.org/pub/png/documents/>. + +Other information +about PNG, and the latest version of libpng, can be found at the PNG home +page, <http://www.libpng.org/pub/png/>. + +Most users will not have to modify the library significantly; advanced +users may want to modify it more. All attempts were made to make it as +complete as possible, while keeping the code easy to understand. +Currently, this library only supports C. Support for other languages +is being considered. + +Libpng has been designed to handle multiple sessions at one time, +to be easily modifiable, to be portable to the vast majority of +machines (ANSI, K&R, 16-, 32-, and 64-bit) available, and to be easy +to use. The ultimate goal of libpng is to promote the acceptance of +the PNG file format in whatever way possible. While there is still +work to be done (see the TODO file), libpng should cover the +majority of the needs of its users. + +Libpng uses zlib for its compression and decompression of PNG files. +Further information about zlib, and the latest version of zlib, can +be found at the zlib home page, <http://www.info-zip.org/pub/infozip/zlib/>. +The zlib compression utility is a general purpose utility that is +useful for more than PNG files, and can be used without libpng. +See the documentation delivered with zlib for more details. +You can usually find the source files for the zlib utility wherever you +find the libpng source files. + +Libpng is thread safe, provided the threads are using different +instances of the structures. Each thread should have its own +png_struct and png_info instances, and thus its own image. +Libpng does not protect itself against two threads using the +same instance of a structure. Note: thread safety may be defeated +by use of some of the MMX assembler code in pnggccrd.c, which is only +compiled when the user defines PNG_THREAD_UNSAFE_OK. + +II. Structures + +There are two main structures that are important to libpng, png_struct +and png_info. The first, png_struct, is an internal structure that +will not, for the most part, be used by a user except as the first +variable passed to every libpng function call. + +The png_info structure is designed to provide information about the +PNG file. At one time, the fields of png_info were intended to be +directly accessible to the user. However, this tended to cause problems +with applications using dynamically loaded libraries, and as a result +a set of interface functions for png_info (the png_get_*() and png_set_*() +functions) was developed. The fields of png_info are still available for +older applications, but it is suggested that applications use the new +interfaces if at all possible. + +Applications that do make direct access to the members of png_struct (except +for png_ptr->jmpbuf) must be recompiled whenever the library is updated, +and applications that make direct access to the members of png_info must +be recompiled if they were compiled or loaded with libpng version 1.0.6, +in which the members were in a different order. In version 1.0.7, the +members of the png_info structure reverted to the old order, as they were +in versions 0.97c through 1.0.5. Starting with version 2.0.0, both +structures are going to be hidden, and the contents of the structures will +only be accessible through the png_get/png_set functions. + +The png.h header file is an invaluable reference for programming with libpng. +And while I'm on the topic, make sure you include the libpng header file: + +#include <png.h> + +III. Reading + +We'll now walk you through the possible functions to call when reading +in a PNG file sequentially, briefly explaining the syntax and purpose +of each one. See example.c and png.h for more detail. While +progressive reading is covered in the next section, you will still +need some of the functions discussed in this section to read a PNG +file. + +Setup + +You will want to do the I/O initialization(*) before you get into libpng, +so if it doesn't work, you don't have much to undo. Of course, you +will also want to insure that you are, in fact, dealing with a PNG +file. Libpng provides a simple check to see if a file is a PNG file. +To use it, pass in the first 1 to 8 bytes of the file to the function +png_sig_cmp(), and it will return 0 if the bytes match the corresponding +bytes of the PNG signature, or nonzero otherwise. Of course, the more bytes +you pass in, the greater the accuracy of the prediction. + +If you are intending to keep the file pointer open for use in libpng, +you must ensure you don't read more than 8 bytes from the beginning +of the file, and you also have to make a call to png_set_sig_bytes_read() +with the number of bytes you read from the beginning. Libpng will +then only check the bytes (if any) that your program didn't read. + +(*): If you are not using the standard I/O functions, you will need +to replace them with custom functions. See the discussion under +Customizing libpng. + + + FILE *fp = fopen(file_name, "rb"); + if (!fp) + { + return (ERROR); + } + fread(header, 1, number, fp); + is_png = !png_sig_cmp(header, 0, number); + if (!is_png) + { + return (NOT_PNG); + } + + +Next, png_struct and png_info need to be allocated and initialized. In +order to ensure that the size of these structures is correct even with a +dynamically linked libpng, there are functions to initialize and +allocate the structures. We also pass the library version, optional +pointers to error handling functions, and a pointer to a data struct for +use by the error functions, if necessary (the pointer and functions can +be NULL if the default error handlers are to be used). See the section +on Changes to Libpng below regarding the old initialization functions. +The structure allocation functions quietly return NULL if they fail to +create the structure, so your application should check for that. + + png_structp png_ptr = png_create_read_struct + (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr, + user_error_fn, user_warning_fn); + if (!png_ptr) + return (ERROR); + + png_infop info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) + { + png_destroy_read_struct(&png_ptr, + (png_infopp)NULL, (png_infopp)NULL); + return (ERROR); + } + + png_infop end_info = png_create_info_struct(png_ptr); + if (!end_info) + { + png_destroy_read_struct(&png_ptr, &info_ptr, + (png_infopp)NULL); + return (ERROR); + } + +If you want to use your own memory allocation routines, +define PNG_USER_MEM_SUPPORTED and use +png_create_read_struct_2() instead of png_create_read_struct(): + + png_structp png_ptr = png_create_read_struct_2 + (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr, + user_error_fn, user_warning_fn, (png_voidp) + user_mem_ptr, user_malloc_fn, user_free_fn); + +The error handling routines passed to png_create_read_struct() +and the memory alloc/free routines passed to png_create_struct_2() +are only necessary if you are not using the libpng supplied error +handling and memory alloc/free functions. + +When libpng encounters an error, it expects to longjmp back +to your routine. Therefore, you will need to call setjmp and pass +your png_jmpbuf(png_ptr). If you read the file from different +routines, you will need to update the jmpbuf field every time you enter +a new routine that will call a png_*() function. + +See your documentation of setjmp/longjmp for your compiler for more +information on setjmp/longjmp. See the discussion on libpng error +handling in the Customizing Libpng section below for more information +on the libpng error handling. If an error occurs, and libpng longjmp's +back to your setjmp, you will want to call png_destroy_read_struct() to +free any memory. + + if (setjmp(png_jmpbuf(png_ptr))) + { + png_destroy_read_struct(&png_ptr, &info_ptr, + &end_info); + fclose(fp); + return (ERROR); + } + +If you would rather avoid the complexity of setjmp/longjmp issues, +you can compile libpng with PNG_SETJMP_NOT_SUPPORTED, in which case +errors will result in a call to PNG_ABORT() which defaults to abort(). + +Now you need to set up the input code. The default for libpng is to +use the C function fread(). If you use this, you will need to pass a +valid FILE * in the function png_init_io(). Be sure that the file is +opened in binary mode. If you wish to handle reading data in another +way, you need not call the png_init_io() function, but you must then +implement the libpng I/O methods discussed in the Customizing Libpng +section below. + + png_init_io(png_ptr, fp); + +If you had previously opened the file and read any of the signature from +the beginning in order to see if this was a PNG file, you need to let +libpng know that there are some bytes missing from the start of the file. + + png_set_sig_bytes(png_ptr, number); + +Setting up callback code + +You can set up a callback function to handle any unknown chunks in the +input stream. You must supply the function + + read_chunk_callback(png_ptr ptr, + png_unknown_chunkp chunk); + { + /* The unknown chunk structure contains your + chunk data: */ + png_byte name[5]; + png_byte *data; + png_size_t size; + /* Note that libpng has already taken care of + the CRC handling */ + + /* put your code here. Return one of the + following: */ + + return (-n); /* chunk had an error */ + return (0); /* did not recognize */ + return (n); /* success */ + } + +(You can give your function another name that you like instead of +"read_chunk_callback") + +To inform libpng about your function, use + + png_set_read_user_chunk_fn(png_ptr, user_chunk_ptr, + read_chunk_callback); + +This names not only the callback function, but also a user pointer that +you can retrieve with + + png_get_user_chunk_ptr(png_ptr); + +At this point, you can set up a callback function that will be +called after each row has been read, which you can use to control +a progress meter or the like. It's demonstrated in pngtest.c. +You must supply a function + + void read_row_callback(png_ptr ptr, png_uint_32 row, + int pass); + { + /* put your code here */ + } + +(You can give it another name that you like instead of "read_row_callback") + +To inform libpng about your function, use + + png_set_read_status_fn(png_ptr, read_row_callback); + +Width and height limits + +The PNG specification allows the width and height of an image to be as +large as 2^31-1 (0x7fffffff), or about 2.147 billion rows and columns. +Since very few applications really need to process such large images, +we have imposed an arbitrary 1-million limit on rows and columns. +Larger images will be rejected immediately with a png_error() call. If +you wish to override this limit, you can use + + png_set_user_limits(png_ptr, width_max, height_max); + +to set your own limits, or use width_max = height_max = 0x7fffffffL +to allow all valid dimensions (libpng may reject some very large images +anyway because of potential buffer overflow conditions). + +You should put this statement after you create the PNG structure and +before calling png_read_info(), png_read_png(), or png_process_data(). +If you need to retrieve the limits that are being applied, use + + width_max = png_get_user_width_max(png_ptr); + height_max = png_get_user_height_max(png_ptr); + +Unknown-chunk handling + +Now you get to set the way the library processes unknown chunks in the +input PNG stream. Both known and unknown chunks will be read. Normal +behavior is that known chunks will be parsed into information in +various info_ptr members; unknown chunks will be discarded. To change +this, you can call: + + png_set_keep_unknown_chunks(png_ptr, keep, + chunk_list, num_chunks); + keep - 0: do not handle as unknown + 1: do not keep + 2: keep only if safe-to-copy + 3: keep even if unsafe-to-copy + You can use these definitions: + PNG_HANDLE_CHUNK_AS_DEFAULT 0 + PNG_HANDLE_CHUNK_NEVER 1 + PNG_HANDLE_CHUNK_IF_SAFE 2 + PNG_HANDLE_CHUNK_ALWAYS 3 + chunk_list - list of chunks affected (a byte string, + five bytes per chunk, NULL or '\0' if + num_chunks is 0) + num_chunks - number of chunks affected; if 0, all + unknown chunks are affected. If nonzero, + only the chunks in the list are affected + +Unknown chunks declared in this way will be saved as raw data onto a +list of png_unknown_chunk structures. If a chunk that is normally +known to libpng is named in the list, it will be handled as unknown, +according to the "keep" directive. If a chunk is named in successive +instances of png_set_keep_unknown_chunks(), the final instance will +take precedence. The IHDR and IEND chunks should not be named in +chunk_list; if they are, libpng will process them normally anyway. + +The high-level read interface + +At this point there are two ways to proceed; through the high-level +read interface, or through a sequence of low-level read operations. +You can use the high-level interface if (a) you are willing to read +the entire image into memory, and (b) the input transformations +you want to do are limited to the following set: + + PNG_TRANSFORM_IDENTITY No transformation + PNG_TRANSFORM_STRIP_16 Strip 16-bit samples to + 8 bits + PNG_TRANSFORM_STRIP_ALPHA Discard the alpha channel + PNG_TRANSFORM_PACKING Expand 1, 2 and 4-bit + samples to bytes + PNG_TRANSFORM_PACKSWAP Change order of packed + pixels to LSB first + PNG_TRANSFORM_EXPAND Perform set_expand() + PNG_TRANSFORM_INVERT_MONO Invert monochrome images + PNG_TRANSFORM_SHIFT Normalize pixels to the + sBIT depth + PNG_TRANSFORM_BGR Flip RGB to BGR, RGBA + to BGRA + PNG_TRANSFORM_SWAP_ALPHA Flip RGBA to ARGB or GA + to AG + PNG_TRANSFORM_INVERT_ALPHA Change alpha from opacity + to transparency + PNG_TRANSFORM_SWAP_ENDIAN Byte-swap 16-bit samples + +(This excludes setting a background color, doing gamma transformation, +dithering, and setting filler.) If this is the case, simply do this: + + png_read_png(png_ptr, info_ptr, png_transforms, NULL) + +where png_transforms is an integer containing the logical OR of +some set of transformation flags. This call is equivalent to png_read_info(), +followed the set of transformations indicated by the transform mask, +then png_read_image(), and finally png_read_end(). + +(The final parameter of this call is not yet used. Someday it might point +to transformation parameters required by some future input transform.) + +You must use png_transforms and not call any png_set_transform() functions +when you use png_read_png(). + +After you have called png_read_png(), you can retrieve the image data +with + + row_pointers = png_get_rows(png_ptr, info_ptr); + +where row_pointers is an array of pointers to the pixel data for each row: + + png_bytep row_pointers[height]; + +If you know your image size and pixel size ahead of time, you can allocate +row_pointers prior to calling png_read_png() with + + if (height > PNG_UINT_32_MAX/png_sizeof(png_byte)) + png_error (png_ptr, + "Image is too tall to process in memory"); + if (width > PNG_UINT_32_MAX/pixel_size) + png_error (png_ptr, + "Image is too wide to process in memory"); + row_pointers = png_malloc(png_ptr, + height*png_sizeof(png_bytep)); + for (int i=0; i<height, i++) + row_pointers[i]=png_malloc(png_ptr, + width*pixel_size); + png_set_rows(png_ptr, info_ptr, &row_pointers); + +Alternatively you could allocate your image in one big block and define +row_pointers[i] to point into the proper places in your block. + +If you use png_set_rows(), the application is responsible for freeing +row_pointers (and row_pointers[i], if they were separately allocated). + +If you don't allocate row_pointers ahead of time, png_read_png() will +do it, and it'll be free'ed when you call png_destroy_*(). + +The low-level read interface + +If you are going the low-level route, you are now ready to read all +the file information up to the actual image data. You do this with a +call to png_read_info(). + + png_read_info(png_ptr, info_ptr); + +This will process all chunks up to but not including the image data. + +Querying the info structure + +Functions are used to get the information from the info_ptr once it +has been read. Note that these fields may not be completely filled +in until png_read_end() has read the chunk data following the image. + + png_get_IHDR(png_ptr, info_ptr, &width, &height, + &bit_depth, &color_type, &interlace_type, + &compression_type, &filter_method); + + width - holds the width of the image + in pixels (up to 2^31). + height - holds the height of the image + in pixels (up to 2^31). + bit_depth - holds the bit depth of one of the + image channels. (valid values are + 1, 2, 4, 8, 16 and depend also on + the color_type. See also + significant bits (sBIT) below). + color_type - describes which color/alpha channels + are present. + PNG_COLOR_TYPE_GRAY + (bit depths 1, 2, 4, 8, 16) + PNG_COLOR_TYPE_GRAY_ALPHA + (bit depths 8, 16) + PNG_COLOR_TYPE_PALETTE + (bit depths 1, 2, 4, 8) + PNG_COLOR_TYPE_RGB + (bit_depths 8, 16) + PNG_COLOR_TYPE_RGB_ALPHA + (bit_depths 8, 16) + + PNG_COLOR_MASK_PALETTE + PNG_COLOR_MASK_COLOR + PNG_COLOR_MASK_ALPHA + + filter_method - (must be PNG_FILTER_TYPE_BASE + for PNG 1.0, and can also be + PNG_INTRAPIXEL_DIFFERENCING if + the PNG datastream is embedded in + a MNG-1.0 datastream) + compression_type - (must be PNG_COMPRESSION_TYPE_BASE + for PNG 1.0) + interlace_type - (PNG_INTERLACE_NONE or + PNG_INTERLACE_ADAM7) + Any or all of interlace_type, compression_type, of + filter_method can be NULL if you are + not interested in their values. + + channels = png_get_channels(png_ptr, info_ptr); + channels - number of channels of info for the + color type (valid values are 1 (GRAY, + PALETTE), 2 (GRAY_ALPHA), 3 (RGB), + 4 (RGB_ALPHA or RGB + filler byte)) + rowbytes = png_get_rowbytes(png_ptr, info_ptr); + rowbytes - number of bytes needed to hold a row + + signature = png_get_signature(png_ptr, info_ptr); + signature - holds the signature read from the + file (if any). The data is kept in + the same offset it would be if the + whole signature were read (i.e. if an + application had already read in 4 + bytes of signature before starting + libpng, the remaining 4 bytes would + be in signature[4] through signature[7] + (see png_set_sig_bytes())). + + + width = png_get_image_width(png_ptr, + info_ptr); + height = png_get_image_height(png_ptr, + info_ptr); + bit_depth = png_get_bit_depth(png_ptr, + info_ptr); + color_type = png_get_color_type(png_ptr, + info_ptr); + filter_method = png_get_filter_type(png_ptr, + info_ptr); + compression_type = png_get_compression_type(png_ptr, + info_ptr); + interlace_type = png_get_interlace_type(png_ptr, + info_ptr); + + +These are also important, but their validity depends on whether the chunk +has been read. The png_get_valid(png_ptr, info_ptr, PNG_INFO_<chunk>) and +png_get_<chunk>(png_ptr, info_ptr, ...) functions return non-zero if the +data has been read, or zero if it is missing. The parameters to the +png_get_<chunk> are set directly if they are simple data types, or a pointer +into the info_ptr is returned for any complex types. + + png_get_PLTE(png_ptr, info_ptr, &palette, + &num_palette); + palette - the palette for the file + (array of png_color) + num_palette - number of entries in the palette + + png_get_gAMA(png_ptr, info_ptr, &gamma); + gamma - the gamma the file is written + at (PNG_INFO_gAMA) + + png_get_sRGB(png_ptr, info_ptr, &srgb_intent); + srgb_intent - the rendering intent (PNG_INFO_sRGB) + The presence of the sRGB chunk + means that the pixel data is in the + sRGB color space. This chunk also + implies specific values of gAMA and + cHRM. + + png_get_iCCP(png_ptr, info_ptr, &name, + &compression_type, &profile, &proflen); + name - The profile name. + compression - The compression type; always + PNG_COMPRESSION_TYPE_BASE for PNG 1.0. + You may give NULL to this argument to + ignore it. + profile - International Color Consortium color + profile data. May contain NULs. + proflen - length of profile data in bytes. + + png_get_sBIT(png_ptr, info_ptr, &sig_bit); + sig_bit - the number of significant bits for + (PNG_INFO_sBIT) each of the gray, + red, green, and blue channels, + whichever are appropriate for the + given color type (png_color_16) + + png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, + &trans_values); + trans - array of transparent entries for + palette (PNG_INFO_tRNS) + trans_values - graylevel or color sample values of + the single transparent color for + non-paletted images (PNG_INFO_tRNS) + num_trans - number of transparent entries + (PNG_INFO_tRNS) + + png_get_hIST(png_ptr, info_ptr, &hist); + (PNG_INFO_hIST) + hist - histogram of palette (array of + png_uint_16) + + png_get_tIME(png_ptr, info_ptr, &mod_time); + mod_time - time image was last modified + (PNG_VALID_tIME) + + png_get_bKGD(png_ptr, info_ptr, &background); + background - background color (PNG_VALID_bKGD) + valid 16-bit red, green and blue + values, regardless of color_type + + num_comments = png_get_text(png_ptr, info_ptr, + &text_ptr, &num_text); + num_comments - number of comments + text_ptr - array of png_text holding image + comments + text_ptr[i].compression - type of compression used + on "text" PNG_TEXT_COMPRESSION_NONE + PNG_TEXT_COMPRESSION_zTXt + PNG_ITXT_COMPRESSION_NONE + PNG_ITXT_COMPRESSION_zTXt + text_ptr[i].key - keyword for comment. Must contain + 1-79 characters. + text_ptr[i].text - text comments for current + keyword. Can be empty. + text_ptr[i].text_length - length of text string, + after decompression, 0 for iTXt + text_ptr[i].itxt_length - length of itxt string, + after decompression, 0 for tEXt/zTXt + text_ptr[i].lang - language of comment (empty + string for unknown). + text_ptr[i].lang_key - keyword in UTF-8 + (empty string for unknown). + num_text - number of comments (same as + num_comments; you can put NULL here + to avoid the duplication) + Note while png_set_text() will accept text, language, + and translated keywords that can be NULL pointers, the + structure returned by png_get_text will always contain + regular zero-terminated C strings. They might be + empty strings but they will never be NULL pointers. + + num_spalettes = png_get_sPLT(png_ptr, info_ptr, + &palette_ptr); + palette_ptr - array of palette structures holding + contents of one or more sPLT chunks + read. + num_spalettes - number of sPLT chunks read. + + png_get_oFFs(png_ptr, info_ptr, &offset_x, &offset_y, + &unit_type); + offset_x - positive offset from the left edge + of the screen + offset_y - positive offset from the top edge + of the screen + unit_type - PNG_OFFSET_PIXEL, PNG_OFFSET_MICROMETER + + png_get_pHYs(png_ptr, info_ptr, &res_x, &res_y, + &unit_type); + res_x - pixels/unit physical resolution in + x direction + res_y - pixels/unit physical resolution in + x direction + unit_type - PNG_RESOLUTION_UNKNOWN, + PNG_RESOLUTION_METER + + png_get_sCAL(png_ptr, info_ptr, &unit, &width, + &height) + unit - physical scale units (an integer) + width - width of a pixel in physical scale units + height - height of a pixel in physical scale units + (width and height are doubles) + + png_get_sCAL_s(png_ptr, info_ptr, &unit, &width, + &height) + unit - physical scale units (an integer) + width - width of a pixel in physical scale units + height - height of a pixel in physical scale units + (width and height are strings like "2.54") + + num_unknown_chunks = png_get_unknown_chunks(png_ptr, + info_ptr, &unknowns) + unknowns - array of png_unknown_chunk + structures holding unknown chunks + unknowns[i].name - name of unknown chunk + unknowns[i].data - data of unknown chunk + unknowns[i].size - size of unknown chunk's data + unknowns[i].location - position of chunk in file + + The value of "i" corresponds to the order in which the + chunks were read from the PNG file or inserted with the + png_set_unknown_chunks() function. + +The data from the pHYs chunk can be retrieved in several convenient +forms: + + res_x = png_get_x_pixels_per_meter(png_ptr, + info_ptr) + res_y = png_get_y_pixels_per_meter(png_ptr, + info_ptr) + res_x_and_y = png_get_pixels_per_meter(png_ptr, + info_ptr) + res_x = png_get_x_pixels_per_inch(png_ptr, + info_ptr) + res_y = png_get_y_pixels_per_inch(png_ptr, + info_ptr) + res_x_and_y = png_get_pixels_per_inch(png_ptr, + info_ptr) + aspect_ratio = png_get_pixel_aspect_ratio(png_ptr, + info_ptr) + + (Each of these returns 0 [signifying "unknown"] if + the data is not present or if res_x is 0; + res_x_and_y is 0 if res_x != res_y) + +The data from the oFFs chunk can be retrieved in several convenient +forms: + + x_offset = png_get_x_offset_microns(png_ptr, info_ptr); + y_offset = png_get_y_offset_microns(png_ptr, info_ptr); + x_offset = png_get_x_offset_inches(png_ptr, info_ptr); + y_offset = png_get_y_offset_inches(png_ptr, info_ptr); + + (Each of these returns 0 [signifying "unknown" if both + x and y are 0] if the data is not present or if the + chunk is present but the unit is the pixel) + +For more information, see the png_info definition in png.h and the +PNG specification for chunk contents. Be careful with trusting +rowbytes, as some of the transformations could increase the space +needed to hold a row (expand, filler, gray_to_rgb, etc.). +See png_read_update_info(), below. + +A quick word about text_ptr and num_text. PNG stores comments in +keyword/text pairs, one pair per chunk, with no limit on the number +of text chunks, and a 2^31 byte limit on their size. While there are +suggested keywords, there is no requirement to restrict the use to these +strings. It is strongly suggested that keywords and text be sensible +to humans (that's the point), so don't use abbreviations. Non-printing +symbols are not allowed. See the PNG specification for more details. +There is also no requirement to have text after the keyword. + +Keywords should be limited to 79 Latin-1 characters without leading or +trailing spaces, but non-consecutive spaces are allowed within the +keyword. It is possible to have the same keyword any number of times. +The text_ptr is an array of png_text structures, each holding a +pointer to a language string, a pointer to a keyword and a pointer to +a text string. The text string, language code, and translated +keyword may be empty or NULL pointers. The keyword/text +pairs are put into the array in the order that they are received. +However, some or all of the text chunks may be after the image, so, to +make sure you have read all the text chunks, don't mess with these +until after you read the stuff after the image. This will be +mentioned again below in the discussion that goes with png_read_end(). + +Input transformations + +After you've read the header information, you can set up the library +to handle any special transformations of the image data. The various +ways to transform the data will be described in the order that they +should occur. This is important, as some of these change the color +type and/or bit depth of the data, and some others only work on +certain color types and bit depths. Even though each transformation +checks to see if it has data that it can do something with, you should +make sure to only enable a transformation if it will be valid for the +data. For example, don't swap red and blue on grayscale data. + +The colors used for the background and transparency values should be +supplied in the same format/depth as the current image data. They +are stored in the same format/depth as the image data in a bKGD or tRNS +chunk, so this is what libpng expects for this data. The colors are +transformed to keep in sync with the image data when an application +calls the png_read_update_info() routine (see below). + +Data will be decoded into the supplied row buffers packed into bytes +unless the library has been told to transform it into another format. +For example, 4 bit/pixel paletted or grayscale data will be returned +2 pixels/byte with the leftmost pixel in the high-order bits of the +byte, unless png_set_packing() is called. 8-bit RGB data will be stored +in RGB RGB RGB format unless png_set_filler() or png_set_add_alpha() +is called to insert filler bytes, either before or after each RGB triplet. +16-bit RGB data will be returned RRGGBB RRGGBB, with the most significant +byte of the color value first, unless png_set_strip_16() is called to +transform it to regular RGB RGB triplets, or png_set_filler() or +png_set_add alpha() is called to insert filler bytes, either before or +after each RRGGBB triplet. Similarly, 8-bit or 16-bit grayscale data can +be modified with +png_set_filler(), png_set_add_alpha(), or png_set_strip_16(). + +The following code transforms grayscale images of less than 8 to 8 bits, +changes paletted images to RGB, and adds a full alpha channel if there is +transparency information in a tRNS chunk. This is most useful on +grayscale images with bit depths of 2 or 4 or if there is a multiple-image +viewing application that wishes to treat all images in the same way. + + if (color_type == PNG_COLOR_TYPE_PALETTE) + png_set_palette_to_rgb(png_ptr); + + if (color_type == PNG_COLOR_TYPE_GRAY && + bit_depth < 8) png_set_expand_gray_1_2_4_to_8(png_ptr); + + if (png_get_valid(png_ptr, info_ptr, + PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png_ptr); + +These three functions are actually aliases for png_set_expand(), added +in libpng version 1.0.4, with the function names expanded to improve code +readability. In some future version they may actually do different +things. + +As of libpng version 1.2.9, png_set_expand_gray_1_2_4_to_8() was +added. It expands the sample depth without changing tRNS to alpha. +At the same time, png_set_gray_1_2_4_to_8() was deprecated, and it +will be removed from a future version. + +PNG can have files with 16 bits per channel. If you only can handle +8 bits per channel, this will strip the pixels down to 8 bit. + + if (bit_depth == 16) + png_set_strip_16(png_ptr); + +If, for some reason, you don't need the alpha channel on an image, +and you want to remove it rather than combining it with the background +(but the image author certainly had in mind that you *would* combine +it with the background, so that's what you should probably do): + + if (color_type & PNG_COLOR_MASK_ALPHA) + png_set_strip_alpha(png_ptr); + +In PNG files, the alpha channel in an image +is the level of opacity. If you need the alpha channel in an image to +be the level of transparency instead of opacity, you can invert the +alpha channel (or the tRNS chunk data) after it's read, so that 0 is +fully opaque and 255 (in 8-bit or paletted images) or 65535 (in 16-bit +images) is fully transparent, with + + png_set_invert_alpha(png_ptr); + +PNG files pack pixels of bit depths 1, 2, and 4 into bytes as small as +they can, resulting in, for example, 8 pixels per byte for 1 bit +files. This code expands to 1 pixel per byte without changing the +values of the pixels: + + if (bit_depth < 8) + png_set_packing(png_ptr); + +PNG files have possible bit depths of 1, 2, 4, 8, and 16. All pixels +stored in a PNG image have been "scaled" or "shifted" up to the next +higher possible bit depth (e.g. from 5 bits/sample in the range [0,31] to +8 bits/sample in the range [0, 255]). However, it is also possible to +convert the PNG pixel data back to the original bit depth of the image. +This call reduces the pixels back down to the original bit depth: + + png_color_8p sig_bit; + + if (png_get_sBIT(png_ptr, info_ptr, &sig_bit)) + png_set_shift(png_ptr, sig_bit); + +PNG files store 3-color pixels in red, green, blue order. This code +changes the storage of the pixels to blue, green, red: + + if (color_type == PNG_COLOR_TYPE_RGB || + color_type == PNG_COLOR_TYPE_RGB_ALPHA) + png_set_bgr(png_ptr); + +PNG files store RGB pixels packed into 3 or 6 bytes. This code expands them +into 4 or 8 bytes for windowing systems that need them in this format: + + if (color_type == PNG_COLOR_TYPE_RGB) + png_set_filler(png_ptr, filler, PNG_FILLER_BEFORE); + +where "filler" is the 8 or 16-bit number to fill with, and the location is +either PNG_FILLER_BEFORE or PNG_FILLER_AFTER, depending upon whether +you want the filler before the RGB or after. This transformation +does not affect images that already have full alpha channels. To add an +opaque alpha channel, use filler=0xff or 0xffff and PNG_FILLER_AFTER which +will generate RGBA pixels. + +Note that png_set_filler() does not change the color type. If you want +to do that, you can add a true alpha channel with + + if (color_type == PNG_COLOR_TYPE_RGB || + color_type == PNG_COLOR_TYPE_GRAY) + png_set_add_alpha(png_ptr, filler, PNG_FILLER_AFTER); + +where "filler" contains the alpha value to assign to each pixel. +This function was added in libpng-1.2.7. + +If you are reading an image with an alpha channel, and you need the +data as ARGB instead of the normal PNG format RGBA: + + if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) + png_set_swap_alpha(png_ptr); + +For some uses, you may want a grayscale image to be represented as +RGB. This code will do that conversion: + + if (color_type == PNG_COLOR_TYPE_GRAY || + color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + png_set_gray_to_rgb(png_ptr); + +Conversely, you can convert an RGB or RGBA image to grayscale or grayscale +with alpha. + + if (color_type == PNG_COLOR_TYPE_RGB || + color_type == PNG_COLOR_TYPE_RGB_ALPHA) + png_set_rgb_to_gray_fixed(png_ptr, error_action, + int red_weight, int green_weight); + + error_action = 1: silently do the conversion + error_action = 2: issue a warning if the original + image has any pixel where + red != green or red != blue + error_action = 3: issue an error and abort the + conversion if the original + image has any pixel where + red != green or red != blue + + red_weight: weight of red component times 100000 + green_weight: weight of green component times 100000 + If either weight is negative, default + weights (21268, 71514) are used. + +If you have set error_action = 1 or 2, you can +later check whether the image really was gray, after processing +the image rows, with the png_get_rgb_to_gray_status(png_ptr) function. +It will return a png_byte that is zero if the image was gray or +1 if there were any non-gray pixels. bKGD and sBIT data +will be silently converted to grayscale, using the green channel +data, regardless of the error_action setting. + +With red_weight+green_weight<=100000, +the normalized graylevel is computed: + + int rw = red_weight * 65536; + int gw = green_weight * 65536; + int bw = 65536 - (rw + gw); + gray = (rw*red + gw*green + bw*blue)/65536; + +The default values approximate those recommended in the Charles +Poynton's Color FAQ, <http://www.inforamp.net/~poynton/> +Copyright (c) 1998-01-04 Charles Poynton <poynton at inforamp.net> + + Y = 0.212671 * R + 0.715160 * G + 0.072169 * B + +Libpng approximates this with + + Y = 0.21268 * R + 0.7151 * G + 0.07217 * B + +which can be expressed with integers as + + Y = (6969 * R + 23434 * G + 2365 * B)/32768 + +The calculation is done in a linear colorspace, if the image gamma +is known. + +If you have a grayscale and you are using png_set_expand_depth(), +png_set_expand(), or png_set_gray_to_rgb to change to truecolor or to +a higher bit-depth, you must either supply the background color as a gray +value at the original file bit-depth (need_expand = 1) or else supply the +background color as an RGB triplet at the final, expanded bit depth +(need_expand = 0). Similarly, if you are reading a paletted image, you +must either supply the background color as a palette index (need_expand = 1) +or as an RGB triplet that may or may not be in the palette (need_expand = 0). + + png_color_16 my_background; + png_color_16p image_background; + + if (png_get_bKGD(png_ptr, info_ptr, &image_background)) + png_set_background(png_ptr, image_background, + PNG_BACKGROUND_GAMMA_FILE, 1, 1.0); + else + png_set_background(png_ptr, &my_background, + PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0); + +The png_set_background() function tells libpng to composite images +with alpha or simple transparency against the supplied background +color. If the PNG file contains a bKGD chunk (PNG_INFO_bKGD valid), +you may use this color, or supply another color more suitable for +the current display (e.g., the background color from a web page). You +need to tell libpng whether the color is in the gamma space of the +display (PNG_BACKGROUND_GAMMA_SCREEN for colors you supply), the file +(PNG_BACKGROUND_GAMMA_FILE for colors from the bKGD chunk), or one +that is neither of these gammas (PNG_BACKGROUND_GAMMA_UNIQUE - I don't +know why anyone would use this, but it's here). + +To properly display PNG images on any kind of system, the application needs +to know what the display gamma is. Ideally, the user will know this, and +the application will allow them to set it. One method of allowing the user +to set the display gamma separately for each system is to check for a +SCREEN_GAMMA or DISPLAY_GAMMA environment variable, which will hopefully be +correctly set. + +Note that display_gamma is the overall gamma correction required to produce +pleasing results, which depends on the lighting conditions in the surrounding +environment. In a dim or brightly lit room, no compensation other than +the physical gamma exponent of the monitor is needed, while in a dark room +a slightly smaller exponent is better. + + double gamma, screen_gamma; + + if (/* We have a user-defined screen + gamma value */) + { + screen_gamma = user_defined_screen_gamma; + } + /* One way that applications can share the same + screen gamma value */ + else if ((gamma_str = getenv("SCREEN_GAMMA")) + != NULL) + { + screen_gamma = (double)atof(gamma_str); + } + /* If we don't have another value */ + else + { + screen_gamma = 2.2; /* A good guess for a + PC monitor in a bright office or a dim room */ + screen_gamma = 2.0; /* A good guess for a + PC monitor in a dark room */ + screen_gamma = 1.7 or 1.0; /* A good + guess for Mac systems */ + } + +The png_set_gamma() function handles gamma transformations of the data. +Pass both the file gamma and the current screen_gamma. If the file does +not have a gamma value, you can pass one anyway if you have an idea what +it is (usually 0.45455 is a good guess for GIF images on PCs). Note +that file gammas are inverted from screen gammas. See the discussions +on gamma in the PNG specification for an excellent description of what +gamma is, and why all applications should support it. It is strongly +recommended that PNG viewers support gamma correction. + + if (png_get_gAMA(png_ptr, info_ptr, &gamma)) + png_set_gamma(png_ptr, screen_gamma, gamma); + else + png_set_gamma(png_ptr, screen_gamma, 0.45455); + +If you need to reduce an RGB file to a paletted file, or if a paletted +file has more entries then will fit on your screen, png_set_dither() +will do that. Note that this is a simple match dither that merely +finds the closest color available. This should work fairly well with +optimized palettes, and fairly badly with linear color cubes. If you +pass a palette that is larger then maximum_colors, the file will +reduce the number of colors in the palette so it will fit into +maximum_colors. If there is a histogram, it will use it to make +more intelligent choices when reducing the palette. If there is no +histogram, it may not do as good a job. + + if (color_type & PNG_COLOR_MASK_COLOR) + { + if (png_get_valid(png_ptr, info_ptr, + PNG_INFO_PLTE)) + { + png_uint_16p histogram = NULL; + + png_get_hIST(png_ptr, info_ptr, + &histogram); + png_set_dither(png_ptr, palette, num_palette, + max_screen_colors, histogram, 1); + } + else + { + png_color std_color_cube[MAX_SCREEN_COLORS] = + { ... colors ... }; + + png_set_dither(png_ptr, std_color_cube, + MAX_SCREEN_COLORS, MAX_SCREEN_COLORS, + NULL,0); + } + } + +PNG files describe monochrome as black being zero and white being one. +The following code will reverse this (make black be one and white be +zero): + + if (bit_depth == 1 && color_type == PNG_COLOR_TYPE_GRAY) + png_set_invert_mono(png_ptr); + +This function can also be used to invert grayscale and gray-alpha images: + + if (color_type == PNG_COLOR_TYPE_GRAY || + color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + png_set_invert_mono(png_ptr); + +PNG files store 16 bit pixels in network byte order (big-endian, +ie. most significant bits first). This code changes the storage to the +other way (little-endian, i.e. least significant bits first, the +way PCs store them): + + if (bit_depth == 16) + png_set_swap(png_ptr); + +If you are using packed-pixel images (1, 2, or 4 bits/pixel), and you +need to change the order the pixels are packed into bytes, you can use: + + if (bit_depth < 8) + png_set_packswap(png_ptr); + +Finally, you can write your own transformation function if none of +the existing ones meets your needs. This is done by setting a callback +with + + png_set_read_user_transform_fn(png_ptr, + read_transform_fn); + +You must supply the function + + void read_transform_fn(png_ptr ptr, row_info_ptr + row_info, png_bytep data) + +See pngtest.c for a working example. Your function will be called +after all of the other transformations have been processed. + +You can also set up a pointer to a user structure for use by your +callback function, and you can inform libpng that your transform +function will change the number of channels or bit depth with the +function + + png_set_user_transform_info(png_ptr, user_ptr, + user_depth, user_channels); + +The user's application, not libpng, is responsible for allocating and +freeing any memory required for the user structure. + +You can retrieve the pointer via the function +png_get_user_transform_ptr(). For example: + + voidp read_user_transform_ptr = + png_get_user_transform_ptr(png_ptr); + +The last thing to handle is interlacing; this is covered in detail below, +but you must call the function here if you want libpng to handle expansion +of the interlaced image. + + number_of_passes = png_set_interlace_handling(png_ptr); + +After setting the transformations, libpng can update your png_info +structure to reflect any transformations you've requested with this +call. This is most useful to update the info structure's rowbytes +field so you can use it to allocate your image memory. This function +will also update your palette with the correct screen_gamma and +background if these have been given with the calls above. + + png_read_update_info(png_ptr, info_ptr); + +After you call png_read_update_info(), you can allocate any +memory you need to hold the image. The row data is simply +raw byte data for all forms of images. As the actual allocation +varies among applications, no example will be given. If you +are allocating one large chunk, you will need to build an +array of pointers to each row, as it will be needed for some +of the functions below. + +Reading image data + +After you've allocated memory, you can read the image data. +The simplest way to do this is in one function call. If you are +allocating enough memory to hold the whole image, you can just +call png_read_image() and libpng will read in all the image data +and put it in the memory area supplied. You will need to pass in +an array of pointers to each row. + +This function automatically handles interlacing, so you don't need +to call png_set_interlace_handling() or call this function multiple +times, or any of that other stuff necessary with png_read_rows(). + + png_read_image(png_ptr, row_pointers); + +where row_pointers is: + + png_bytep row_pointers[height]; + +You can point to void or char or whatever you use for pixels. + +If you don't want to read in the whole image at once, you can +use png_read_rows() instead. If there is no interlacing (check +interlace_type == PNG_INTERLACE_NONE), this is simple: + + png_read_rows(png_ptr, row_pointers, NULL, + number_of_rows); + +where row_pointers is the same as in the png_read_image() call. + +If you are doing this just one row at a time, you can do this with +a single row_pointer instead of an array of row_pointers: + + png_bytep row_pointer = row; + png_read_row(png_ptr, row_pointer, NULL); + +If the file is interlaced (interlace_type != 0 in the IHDR chunk), things +get somewhat harder. The only current (PNG Specification version 1.2) +interlacing type for PNG is (interlace_type == PNG_INTERLACE_ADAM7) +is a somewhat complicated 2D interlace scheme, known as Adam7, that +breaks down an image into seven smaller images of varying size, based +on an 8x8 grid. + +libpng can fill out those images or it can give them to you "as is". +If you want them filled out, there are two ways to do that. The one +mentioned in the PNG specification is to expand each pixel to cover +those pixels that have not been read yet (the "rectangle" method). +This results in a blocky image for the first pass, which gradually +smooths out as more pixels are read. The other method is the "sparkle" +method, where pixels are drawn only in their final locations, with the +rest of the image remaining whatever colors they were initialized to +before the start of the read. The first method usually looks better, +but tends to be slower, as there are more pixels to put in the rows. + +If you don't want libpng to handle the interlacing details, just call +png_read_rows() seven times to read in all seven images. Each of the +images is a valid image by itself, or they can all be combined on an +8x8 grid to form a single image (although if you intend to combine them +you would be far better off using the libpng interlace handling). + +The first pass will return an image 1/8 as wide as the entire image +(every 8th column starting in column 0) and 1/8 as high as the original +(every 8th row starting in row 0), the second will be 1/8 as wide +(starting in column 4) and 1/8 as high (also starting in row 0). The +third pass will be 1/4 as wide (every 4th pixel starting in column 0) and +1/8 as high (every 8th row starting in row 4), and the fourth pass will +be 1/4 as wide and 1/4 as high (every 4th column starting in column 2, +and every 4th row starting in row 0). The fifth pass will return an +image 1/2 as wide, and 1/4 as high (starting at column 0 and row 2), +while the sixth pass will be 1/2 as wide and 1/2 as high as the original +(starting in column 1 and row 0). The seventh and final pass will be as +wide as the original, and 1/2 as high, containing all of the odd +numbered scanlines. Phew! + +If you want libpng to expand the images, call this before calling +png_start_read_image() or png_read_update_info(): + + if (interlace_type == PNG_INTERLACE_ADAM7) + number_of_passes + = png_set_interlace_handling(png_ptr); + +This will return the number of passes needed. Currently, this +is seven, but may change if another interlace type is added. +This function can be called even if the file is not interlaced, +where it will return one pass. + +If you are not going to display the image after each pass, but are +going to wait until the entire image is read in, use the sparkle +effect. This effect is faster and the end result of either method +is exactly the same. If you are planning on displaying the image +after each pass, the "rectangle" effect is generally considered the +better looking one. + +If you only want the "sparkle" effect, just call png_read_rows() as +normal, with the third parameter NULL. Make sure you make pass over +the image number_of_passes times, and you don't change the data in the +rows between calls. You can change the locations of the data, just +not the data. Each pass only writes the pixels appropriate for that +pass, and assumes the data from previous passes is still valid. + + png_read_rows(png_ptr, row_pointers, NULL, + number_of_rows); + +If you only want the first effect (the rectangles), do the same as +before except pass the row buffer in the third parameter, and leave +the second parameter NULL. + + png_read_rows(png_ptr, NULL, row_pointers, + number_of_rows); + +Finishing a sequential read + +After you are finished reading the image through the +low-level interface, you can finish reading the file. If you are +interested in comments or time, which may be stored either before or +after the image data, you should pass the separate png_info struct if +you want to keep the comments from before and after the image +separate. If you are not interested, you can pass NULL. + + png_read_end(png_ptr, end_info); + +When you are done, you can free all memory allocated by libpng like this: + + png_destroy_read_struct(&png_ptr, &info_ptr, + &end_info); + +It is also possible to individually free the info_ptr members that +point to libpng-allocated storage with the following function: + + png_free_data(png_ptr, info_ptr, mask, seq) + mask - identifies data to be freed, a mask + containing the logical OR of one or + more of + PNG_FREE_PLTE, PNG_FREE_TRNS, + PNG_FREE_HIST, PNG_FREE_ICCP, + PNG_FREE_PCAL, PNG_FREE_ROWS, + PNG_FREE_SCAL, PNG_FREE_SPLT, + PNG_FREE_TEXT, PNG_FREE_UNKN, + or simply PNG_FREE_ALL + seq - sequence number of item to be freed + (-1 for all items) + +This function may be safely called when the relevant storage has +already been freed, or has not yet been allocated, or was allocated +by the user and not by libpng, and will in those +cases do nothing. The "seq" parameter is ignored if only one item +of the selected data type, such as PLTE, is allowed. If "seq" is not +-1, and multiple items are allowed for the data type identified in +the mask, such as text or sPLT, only the n'th item in the structure +is freed, where n is "seq". + +The default behavior is only to free data that was allocated internally +by libpng. This can be changed, so that libpng will not free the data, +or so that it will free data that was allocated by the user with png_malloc() +or png_zalloc() and passed in via a png_set_*() function, with + + png_data_freer(png_ptr, info_ptr, freer, mask) + mask - which data elements are affected + same choices as in png_free_data() + freer - one of + PNG_DESTROY_WILL_FREE_DATA + PNG_SET_WILL_FREE_DATA + PNG_USER_WILL_FREE_DATA + +This function only affects data that has already been allocated. +You can call this function after reading the PNG data but before calling +any png_set_*() functions, to control whether the user or the png_set_*() +function is responsible for freeing any existing data that might be present, +and again after the png_set_*() functions to control whether the user +or png_destroy_*() is supposed to free the data. When the user assumes +responsibility for libpng-allocated data, the application must use +png_free() to free it, and when the user transfers responsibility to libpng +for data that the user has allocated, the user must have used png_malloc() +or png_zalloc() to allocate it. + +If you allocated your row_pointers in a single block, as suggested above in +the description of the high level read interface, you must not transfer +responsibility for freeing it to the png_set_rows or png_read_destroy function, +because they would also try to free the individual row_pointers[i]. + +If you allocated text_ptr.text, text_ptr.lang, and text_ptr.translated_keyword +separately, do not transfer responsibility for freeing text_ptr to libpng, +because when libpng fills a png_text structure it combines these members with +the key member, and png_free_data() will free only text_ptr.key. Similarly, +if you transfer responsibility for free'ing text_ptr from libpng to your +application, your application must not separately free those members. + +The png_free_data() function will turn off the "valid" flag for anything +it frees. If you need to turn the flag off for a chunk that was freed by your +application instead of by libpng, you can use + + png_set_invalid(png_ptr, info_ptr, mask); + mask - identifies the chunks to be made invalid, + containing the logical OR of one or + more of + PNG_INFO_gAMA, PNG_INFO_sBIT, + PNG_INFO_cHRM, PNG_INFO_PLTE, + PNG_INFO_tRNS, PNG_INFO_bKGD, + PNG_INFO_hIST, PNG_INFO_pHYs, + PNG_INFO_oFFs, PNG_INFO_tIME, + PNG_INFO_pCAL, PNG_INFO_sRGB, + PNG_INFO_iCCP, PNG_INFO_sPLT, + PNG_INFO_sCAL, PNG_INFO_IDAT + +For a more compact example of reading a PNG image, see the file example.c. + +Reading PNG files progressively + +The progressive reader is slightly different then the non-progressive +reader. Instead of calling png_read_info(), png_read_rows(), and +png_read_end(), you make one call to png_process_data(), which calls +callbacks when it has the info, a row, or the end of the image. You +set up these callbacks with png_set_progressive_read_fn(). You don't +have to worry about the input/output functions of libpng, as you are +giving the library the data directly in png_process_data(). I will +assume that you have read the section on reading PNG files above, +so I will only highlight the differences (although I will show +all of the code). + +png_structp png_ptr; +png_infop info_ptr; + + /* An example code fragment of how you would + initialize the progressive reader in your + application. */ + int + initialize_png_reader() + { + png_ptr = png_create_read_struct + (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr, + user_error_fn, user_warning_fn); + if (!png_ptr) + return (ERROR); + info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) + { + png_destroy_read_struct(&png_ptr, (png_infopp)NULL, + (png_infopp)NULL); + return (ERROR); + } + + if (setjmp(png_jmpbuf(png_ptr))) + { + png_destroy_read_struct(&png_ptr, &info_ptr, + (png_infopp)NULL); + return (ERROR); + } + + /* This one's new. You can provide functions + to be called when the header info is valid, + when each row is completed, and when the image + is finished. If you aren't using all functions, + you can specify NULL parameters. Even when all + three functions are NULL, you need to call + png_set_progressive_read_fn(). You can use + any struct as the user_ptr (cast to a void pointer + for the function call), and retrieve the pointer + from inside the callbacks using the function + + png_get_progressive_ptr(png_ptr); + + which will return a void pointer, which you have + to cast appropriately. + */ + png_set_progressive_read_fn(png_ptr, (void *)user_ptr, + info_callback, row_callback, end_callback); + + return 0; + } + + /* A code fragment that you call as you receive blocks + of data */ + int + process_data(png_bytep buffer, png_uint_32 length) + { + if (setjmp(png_jmpbuf(png_ptr))) + { + png_destroy_read_struct(&png_ptr, &info_ptr, + (png_infopp)NULL); + return (ERROR); + } + + /* This one's new also. Simply give it a chunk + of data from the file stream (in order, of + course). On machines with segmented memory + models machines, don't give it any more than + 64K. The library seems to run fine with sizes + of 4K. Although you can give it much less if + necessary (I assume you can give it chunks of + 1 byte, I haven't tried less then 256 bytes + yet). When this function returns, you may + want to display any rows that were generated + in the row callback if you don't already do + so there. + */ + png_process_data(png_ptr, info_ptr, buffer, length); + return 0; + } + + /* This function is called (as set by + png_set_progressive_read_fn() above) when enough data + has been supplied so all of the header has been + read. + */ + void + info_callback(png_structp png_ptr, png_infop info) + { + /* Do any setup here, including setting any of + the transformations mentioned in the Reading + PNG files section. For now, you _must_ call + either png_start_read_image() or + png_read_update_info() after all the + transformations are set (even if you don't set + any). You may start getting rows before + png_process_data() returns, so this is your + last chance to prepare for that. + */ + } + + /* This function is called when each row of image + data is complete */ + void + row_callback(png_structp png_ptr, png_bytep new_row, + png_uint_32 row_num, int pass) + { + /* If the image is interlaced, and you turned + on the interlace handler, this function will + be called for every row in every pass. Some + of these rows will not be changed from the + previous pass. When the row is not changed, + the new_row variable will be NULL. The rows + and passes are called in order, so you don't + really need the row_num and pass, but I'm + supplying them because it may make your life + easier. + + For the non-NULL rows of interlaced images, + you must call png_progressive_combine_row() + passing in the row and the old row. You can + call this function for NULL rows (it will just + return) and for non-interlaced images (it just + does the memcpy for you) if it will make the + code easier. Thus, you can just do this for + all cases: + */ + + png_progressive_combine_row(png_ptr, old_row, + new_row); + + /* where old_row is what was displayed for + previously for the row. Note that the first + pass (pass == 0, really) will completely cover + the old row, so the rows do not have to be + initialized. After the first pass (and only + for interlaced images), you will have to pass + the current row, and the function will combine + the old row and the new row. + */ + } + + void + end_callback(png_structp png_ptr, png_infop info) + { + /* This function is called after the whole image + has been read, including any chunks after the + image (up to and including the IEND). You + will usually have the same info chunk as you + had in the header, although some data may have + been added to the comments and time fields. + + Most people won't do much here, perhaps setting + a flag that marks the image as finished. + */ + } + + + +IV. Writing + +Much of this is very similar to reading. However, everything of +importance is repeated here, so you won't have to constantly look +back up in the reading section to understand writing. + +Setup + +You will want to do the I/O initialization before you get into libpng, +so if it doesn't work, you don't have anything to undo. If you are not +using the standard I/O functions, you will need to replace them with +custom writing functions. See the discussion under Customizing libpng. + + FILE *fp = fopen(file_name, "wb"); + if (!fp) + { + return (ERROR); + } + +Next, png_struct and png_info need to be allocated and initialized. +As these can be both relatively large, you may not want to store these +on the stack, unless you have stack space to spare. Of course, you +will want to check if they return NULL. If you are also reading, +you won't want to name your read structure and your write structure +both "png_ptr"; you can call them anything you like, such as +"read_ptr" and "write_ptr". Look at pngtest.c, for example. + + png_structp png_ptr = png_create_write_struct + (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr, + user_error_fn, user_warning_fn); + if (!png_ptr) + return (ERROR); + + png_infop info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) + { + png_destroy_write_struct(&png_ptr, + (png_infopp)NULL); + return (ERROR); + } + +If you want to use your own memory allocation routines, +define PNG_USER_MEM_SUPPORTED and use +png_create_write_struct_2() instead of png_create_write_struct(): + + png_structp png_ptr = png_create_write_struct_2 + (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr, + user_error_fn, user_warning_fn, (png_voidp) + user_mem_ptr, user_malloc_fn, user_free_fn); + +After you have these structures, you will need to set up the +error handling. When libpng encounters an error, it expects to +longjmp() back to your routine. Therefore, you will need to call +setjmp() and pass the png_jmpbuf(png_ptr). If you +write the file from different routines, you will need to update +the png_jmpbuf(png_ptr) every time you enter a new routine that will +call a png_*() function. See your documentation of setjmp/longjmp +for your compiler for more information on setjmp/longjmp. See +the discussion on libpng error handling in the Customizing Libpng +section below for more information on the libpng error handling. + + if (setjmp(png_jmpbuf(png_ptr))) + { + png_destroy_write_struct(&png_ptr, &info_ptr); + fclose(fp); + return (ERROR); + } + ... + return; + +If you would rather avoid the complexity of setjmp/longjmp issues, +you can compile libpng with PNG_SETJMP_NOT_SUPPORTED, in which case +errors will result in a call to PNG_ABORT() which defaults to abort(). + +Now you need to set up the output code. The default for libpng is to +use the C function fwrite(). If you use this, you will need to pass a +valid FILE * in the function png_init_io(). Be sure that the file is +opened in binary mode. Again, if you wish to handle writing data in +another way, see the discussion on libpng I/O handling in the Customizing +Libpng section below. + + png_init_io(png_ptr, fp); + +If you are embedding your PNG into a datastream such as MNG, and don't +want libpng to write the 8-byte signature, or if you have already +written the signature in your application, use + + png_set_sig_bytes(png_ptr, 8); + +to inform libpng that it should not write a signature. + +Write callbacks + +At this point, you can set up a callback function that will be +called after each row has been written, which you can use to control +a progress meter or the like. It's demonstrated in pngtest.c. +You must supply a function + + void write_row_callback(png_ptr, png_uint_32 row, + int pass); + { + /* put your code here */ + } + +(You can give it another name that you like instead of "write_row_callback") + +To inform libpng about your function, use + + png_set_write_status_fn(png_ptr, write_row_callback); + +You now have the option of modifying how the compression library will +run. The following functions are mainly for testing, but may be useful +in some cases, like if you need to write PNG files extremely fast and +are willing to give up some compression, or if you want to get the +maximum possible compression at the expense of slower writing. If you +have no special needs in this area, let the library do what it wants by +not calling this function at all, as it has been tuned to deliver a good +speed/compression ratio. The second parameter to png_set_filter() is +the filter method, for which the only valid values are 0 (as of the +July 1999 PNG specification, version 1.2) or 64 (if you are writing +a PNG datastream that is to be embedded in a MNG datastream). The third +parameter is a flag that indicates which filter type(s) are to be tested +for each scanline. See the PNG specification for details on the specific filter +types. + + + /* turn on or off filtering, and/or choose + specific filters. You can use either a single + PNG_FILTER_VALUE_NAME or the logical OR of one + or more PNG_FILTER_NAME masks. */ + png_set_filter(png_ptr, 0, + PNG_FILTER_NONE | PNG_FILTER_VALUE_NONE | + PNG_FILTER_SUB | PNG_FILTER_VALUE_SUB | + PNG_FILTER_UP | PNG_FILTER_VALUE_UP | + PNG_FILTER_AVE | PNG_FILTER_VALUE_AVE | + PNG_FILTER_PAETH | PNG_FILTER_VALUE_PAETH| + PNG_ALL_FILTERS); + +If an application +wants to start and stop using particular filters during compression, +it should start out with all of the filters (to ensure that the previous +row of pixels will be stored in case it's needed later), and then add +and remove them after the start of compression. + +If you are writing a PNG datastream that is to be embedded in a MNG +datastream, the second parameter can be either 0 or 64. + +The png_set_compression_*() functions interface to the zlib compression +library, and should mostly be ignored unless you really know what you are +doing. The only generally useful call is png_set_compression_level() +which changes how much time zlib spends on trying to compress the image +data. See the Compression Library (zlib.h and algorithm.txt, distributed +with zlib) for details on the compression levels. + + /* set the zlib compression level */ + png_set_compression_level(png_ptr, + Z_BEST_COMPRESSION); + + /* set other zlib parameters */ + png_set_compression_mem_level(png_ptr, 8); + png_set_compression_strategy(png_ptr, + Z_DEFAULT_STRATEGY); + png_set_compression_window_bits(png_ptr, 15); + png_set_compression_method(png_ptr, 8); + png_set_compression_buffer_size(png_ptr, 8192) + +extern PNG_EXPORT(void,png_set_zbuf_size) + +Setting the contents of info for output + +You now need to fill in the png_info structure with all the data you +wish to write before the actual image. Note that the only thing you +are allowed to write after the image is the text chunks and the time +chunk (as of PNG Specification 1.2, anyway). See png_write_end() and +the latest PNG specification for more information on that. If you +wish to write them before the image, fill them in now, and flag that +data as being valid. If you want to wait until after the data, don't +fill them until png_write_end(). For all the fields in png_info and +their data types, see png.h. For explanations of what the fields +contain, see the PNG specification. + +Some of the more important parts of the png_info are: + + png_set_IHDR(png_ptr, info_ptr, width, height, + bit_depth, color_type, interlace_type, + compression_type, filter_method) + width - holds the width of the image + in pixels (up to 2^31). + height - holds the height of the image + in pixels (up to 2^31). + bit_depth - holds the bit depth of one of the + image channels. + (valid values are 1, 2, 4, 8, 16 + and depend also on the + color_type. See also significant + bits (sBIT) below). + color_type - describes which color/alpha + channels are present. + PNG_COLOR_TYPE_GRAY + (bit depths 1, 2, 4, 8, 16) + PNG_COLOR_TYPE_GRAY_ALPHA + (bit depths 8, 16) + PNG_COLOR_TYPE_PALETTE + (bit depths 1, 2, 4, 8) + PNG_COLOR_TYPE_RGB + (bit_depths 8, 16) + PNG_COLOR_TYPE_RGB_ALPHA + (bit_depths 8, 16) + + PNG_COLOR_MASK_PALETTE + PNG_COLOR_MASK_COLOR + PNG_COLOR_MASK_ALPHA + + interlace_type - PNG_INTERLACE_NONE or + PNG_INTERLACE_ADAM7 + compression_type - (must be + PNG_COMPRESSION_TYPE_DEFAULT) + filter_method - (must be PNG_FILTER_TYPE_DEFAULT + or, if you are writing a PNG to + be embedded in a MNG datastream, + can also be + PNG_INTRAPIXEL_DIFFERENCING) + + png_set_PLTE(png_ptr, info_ptr, palette, + num_palette); + palette - the palette for the file + (array of png_color) + num_palette - number of entries in the palette + + png_set_gAMA(png_ptr, info_ptr, gamma); + gamma - the gamma the image was created + at (PNG_INFO_gAMA) + + png_set_sRGB(png_ptr, info_ptr, srgb_intent); + srgb_intent - the rendering intent + (PNG_INFO_sRGB) The presence of + the sRGB chunk means that the pixel + data is in the sRGB color space. + This chunk also implies specific + values of gAMA and cHRM. Rendering + intent is the CSS-1 property that + has been defined by the International + Color Consortium + (http://www.color.org). + It can be one of + PNG_sRGB_INTENT_SATURATION, + PNG_sRGB_INTENT_PERCEPTUAL, + PNG_sRGB_INTENT_ABSOLUTE, or + PNG_sRGB_INTENT_RELATIVE. + + + png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, + srgb_intent); + srgb_intent - the rendering intent + (PNG_INFO_sRGB) The presence of the + sRGB chunk means that the pixel + data is in the sRGB color space. + This function also causes gAMA and + cHRM chunks with the specific values + that are consistent with sRGB to be + written. + + png_set_iCCP(png_ptr, info_ptr, name, compression_type, + profile, proflen); + name - The profile name. + compression - The compression type; always + PNG_COMPRESSION_TYPE_BASE for PNG 1.0. + You may give NULL to this argument to + ignore it. + profile - International Color Consortium color + profile data. May contain NULs. + proflen - length of profile data in bytes. + + png_set_sBIT(png_ptr, info_ptr, sig_bit); + sig_bit - the number of significant bits for + (PNG_INFO_sBIT) each of the gray, red, + green, and blue channels, whichever are + appropriate for the given color type + (png_color_16) + + png_set_tRNS(png_ptr, info_ptr, trans, num_trans, + trans_values); + trans - array of transparent entries for + palette (PNG_INFO_tRNS) + trans_values - graylevel or color sample values of + the single transparent color for + non-paletted images (PNG_INFO_tRNS) + num_trans - number of transparent entries + (PNG_INFO_tRNS) + + png_set_hIST(png_ptr, info_ptr, hist); + (PNG_INFO_hIST) + hist - histogram of palette (array of + png_uint_16) + + png_set_tIME(png_ptr, info_ptr, mod_time); + mod_time - time image was last modified + (PNG_VALID_tIME) + + png_set_bKGD(png_ptr, info_ptr, background); + background - background color (PNG_VALID_bKGD) + + png_set_text(png_ptr, info_ptr, text_ptr, num_text); + text_ptr - array of png_text holding image + comments + text_ptr[i].compression - type of compression used + on "text" PNG_TEXT_COMPRESSION_NONE + PNG_TEXT_COMPRESSION_zTXt + PNG_ITXT_COMPRESSION_NONE + PNG_ITXT_COMPRESSION_zTXt + text_ptr[i].key - keyword for comment. Must contain + 1-79 characters. + text_ptr[i].text - text comments for current + keyword. Can be NULL or empty. + text_ptr[i].text_length - length of text string, + after decompression, 0 for iTXt + text_ptr[i].itxt_length - length of itxt string, + after decompression, 0 for tEXt/zTXt + text_ptr[i].lang - language of comment (NULL or + empty for unknown). + text_ptr[i].translated_keyword - keyword in UTF-8 (NULL + or empty for unknown). + num_text - number of comments + + png_set_sPLT(png_ptr, info_ptr, &palette_ptr, + num_spalettes); + palette_ptr - array of png_sPLT_struct structures + to be added to the list of palettes + in the info structure. + num_spalettes - number of palette structures to be + added. + + png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, + unit_type); + offset_x - positive offset from the left + edge of the screen + offset_y - positive offset from the top + edge of the screen + unit_type - PNG_OFFSET_PIXEL, PNG_OFFSET_MICROMETER + + png_set_pHYs(png_ptr, info_ptr, res_x, res_y, + unit_type); + res_x - pixels/unit physical resolution + in x direction + res_y - pixels/unit physical resolution + in y direction + unit_type - PNG_RESOLUTION_UNKNOWN, + PNG_RESOLUTION_METER + + png_set_sCAL(png_ptr, info_ptr, unit, width, height) + unit - physical scale units (an integer) + width - width of a pixel in physical scale units + height - height of a pixel in physical scale units + (width and height are doubles) + + png_set_sCAL_s(png_ptr, info_ptr, unit, width, height) + unit - physical scale units (an integer) + width - width of a pixel in physical scale units + height - height of a pixel in physical scale units + (width and height are strings like "2.54") + + png_set_unknown_chunks(png_ptr, info_ptr, &unknowns, + num_unknowns) + unknowns - array of png_unknown_chunk + structures holding unknown chunks + unknowns[i].name - name of unknown chunk + unknowns[i].data - data of unknown chunk + unknowns[i].size - size of unknown chunk's data + unknowns[i].location - position to write chunk in file + 0: do not write chunk + PNG_HAVE_IHDR: before PLTE + PNG_HAVE_PLTE: before IDAT + PNG_AFTER_IDAT: after IDAT + +The "location" member is set automatically according to +what part of the output file has already been written. +You can change its value after calling png_set_unknown_chunks() +as demonstrated in pngtest.c. Within each of the "locations", +the chunks are sequenced according to their position in the +structure (that is, the value of "i", which is the order in which +the chunk was either read from the input file or defined with +png_set_unknown_chunks). + +A quick word about text and num_text. text is an array of png_text +structures. num_text is the number of valid structures in the array. +Each png_text structure holds a language code, a keyword, a text value, +and a compression type. + +The compression types have the same valid numbers as the compression +types of the image data. Currently, the only valid number is zero. +However, you can store text either compressed or uncompressed, unlike +images, which always have to be compressed. So if you don't want the +text compressed, set the compression type to PNG_TEXT_COMPRESSION_NONE. +Because tEXt and zTXt chunks don't have a language field, if you +specify PNG_TEXT_COMPRESSION_NONE or PNG_TEXT_COMPRESSION_zTXt +any language code or translated keyword will not be written out. + +Until text gets around 1000 bytes, it is not worth compressing it. +After the text has been written out to the file, the compression type +is set to PNG_TEXT_COMPRESSION_NONE_WR or PNG_TEXT_COMPRESSION_zTXt_WR, +so that it isn't written out again at the end (in case you are calling +png_write_end() with the same struct. + +The keywords that are given in the PNG Specification are: + + Title Short (one line) title or + caption for image + Author Name of image's creator + Description Description of image (possibly long) + Copyright Copyright notice + Creation Time Time of original image creation + (usually RFC 1123 format, see below) + Software Software used to create the image + Disclaimer Legal disclaimer + Warning Warning of nature of content + Source Device used to create the image + Comment Miscellaneous comment; conversion + from other image format + +The keyword-text pairs work like this. Keywords should be short +simple descriptions of what the comment is about. Some typical +keywords are found in the PNG specification, as is some recommendations +on keywords. You can repeat keywords in a file. You can even write +some text before the image and some after. For example, you may want +to put a description of the image before the image, but leave the +disclaimer until after, so viewers working over modem connections +don't have to wait for the disclaimer to go over the modem before +they start seeing the image. Finally, keywords should be full +words, not abbreviations. Keywords and text are in the ISO 8859-1 +(Latin-1) character set (a superset of regular ASCII) and can not +contain NUL characters, and should not contain control or other +unprintable characters. To make the comments widely readable, stick +with basic ASCII, and avoid machine specific character set extensions +like the IBM-PC character set. The keyword must be present, but +you can leave off the text string on non-compressed pairs. +Compressed pairs must have a text string, as only the text string +is compressed anyway, so the compression would be meaningless. + +PNG supports modification time via the png_time structure. Two +conversion routines are provided, png_convert_from_time_t() for +time_t and png_convert_from_struct_tm() for struct tm. The +time_t routine uses gmtime(). You don't have to use either of +these, but if you wish to fill in the png_time structure directly, +you should provide the time in universal time (GMT) if possible +instead of your local time. Note that the year number is the full +year (e.g. 1998, rather than 98 - PNG is year 2000 compliant!), and +that months start with 1. + +If you want to store the time of the original image creation, you should +use a plain tEXt chunk with the "Creation Time" keyword. This is +necessary because the "creation time" of a PNG image is somewhat vague, +depending on whether you mean the PNG file, the time the image was +created in a non-PNG format, a still photo from which the image was +scanned, or possibly the subject matter itself. In order to facilitate +machine-readable dates, it is recommended that the "Creation Time" +tEXt chunk use RFC 1123 format dates (e.g. "22 May 1997 18:07:10 GMT"), +although this isn't a requirement. Unlike the tIME chunk, the +"Creation Time" tEXt chunk is not expected to be automatically changed +by the software. To facilitate the use of RFC 1123 dates, a function +png_convert_to_rfc1123(png_timep) is provided to convert from PNG +time to an RFC 1123 format string. + +Writing unknown chunks + +You can use the png_set_unknown_chunks function to queue up chunks +for writing. You give it a chunk name, raw data, and a size; that's +all there is to it. The chunks will be written by the next following +png_write_info_before_PLTE, png_write_info, or png_write_end function. +Any chunks previously read into the info structure's unknown-chunk +list will also be written out in a sequence that satisfies the PNG +specification's ordering rules. + +The high-level write interface + +At this point there are two ways to proceed; through the high-level +write interface, or through a sequence of low-level write operations. +You can use the high-level interface if your image data is present +in the info structure. All defined output +transformations are permitted, enabled by the following masks. + + PNG_TRANSFORM_IDENTITY No transformation + PNG_TRANSFORM_PACKING Pack 1, 2 and 4-bit samples + PNG_TRANSFORM_PACKSWAP Change order of packed + pixels to LSB first + PNG_TRANSFORM_INVERT_MONO Invert monochrome images + PNG_TRANSFORM_SHIFT Normalize pixels to the + sBIT depth + PNG_TRANSFORM_BGR Flip RGB to BGR, RGBA + to BGRA + PNG_TRANSFORM_SWAP_ALPHA Flip RGBA to ARGB or GA + to AG + PNG_TRANSFORM_INVERT_ALPHA Change alpha from opacity + to transparency + PNG_TRANSFORM_SWAP_ENDIAN Byte-swap 16-bit samples + PNG_TRANSFORM_STRIP_FILLER Strip out filler bytes. + +If you have valid image data in the info structure (you can use +png_set_rows() to put image data in the info structure), simply do this: + + png_write_png(png_ptr, info_ptr, png_transforms, NULL) + +where png_transforms is an integer containing the logical OR of some set of +transformation flags. This call is equivalent to png_write_info(), +followed the set of transformations indicated by the transform mask, +then png_write_image(), and finally png_write_end(). + +(The final parameter of this call is not yet used. Someday it might point +to transformation parameters required by some future output transform.) + +You must use png_transforms and not call any png_set_transform() functions +when you use png_write_png(). + +The low-level write interface + +If you are going the low-level route instead, you are now ready to +write all the file information up to the actual image data. You do +this with a call to png_write_info(). + + png_write_info(png_ptr, info_ptr); + +Note that there is one transformation you may need to do before +png_write_info(). In PNG files, the alpha channel in an image is the +level of opacity. If your data is supplied as a level of +transparency, you can invert the alpha channel before you write it, so +that 0 is fully transparent and 255 (in 8-bit or paletted images) or +65535 (in 16-bit images) is fully opaque, with + + png_set_invert_alpha(png_ptr); + +This must appear before png_write_info() instead of later with the +other transformations because in the case of paletted images the tRNS +chunk data has to be inverted before the tRNS chunk is written. If +your image is not a paletted image, the tRNS data (which in such cases +represents a single color to be rendered as transparent) won't need to +be changed, and you can safely do this transformation after your +png_write_info() call. + +If you need to write a private chunk that you want to appear before +the PLTE chunk when PLTE is present, you can write the PNG info in +two steps, and insert code to write your own chunk between them: + + png_write_info_before_PLTE(png_ptr, info_ptr); + png_set_unknown_chunks(png_ptr, info_ptr, ...); + png_write_info(png_ptr, info_ptr); + +After you've written the file information, you can set up the library +to handle any special transformations of the image data. The various +ways to transform the data will be described in the order that they +should occur. This is important, as some of these change the color +type and/or bit depth of the data, and some others only work on +certain color types and bit depths. Even though each transformation +checks to see if it has data that it can do something with, you should +make sure to only enable a transformation if it will be valid for the +data. For example, don't swap red and blue on grayscale data. + +PNG files store RGB pixels packed into 3 or 6 bytes. This code tells +the library to strip input data that has 4 or 8 bytes per pixel down +to 3 or 6 bytes (or strip 2 or 4-byte grayscale+filler data to 1 or 2 +bytes per pixel). + + png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE); + +where the 0 is unused, and the location is either PNG_FILLER_BEFORE or +PNG_FILLER_AFTER, depending upon whether the filler byte in the pixel +is stored XRGB or RGBX. + +PNG files pack pixels of bit depths 1, 2, and 4 into bytes as small as +they can, resulting in, for example, 8 pixels per byte for 1 bit files. +If the data is supplied at 1 pixel per byte, use this code, which will +correctly pack the pixels into a single byte: + + png_set_packing(png_ptr); + +PNG files reduce possible bit depths to 1, 2, 4, 8, and 16. If your +data is of another bit depth, you can write an sBIT chunk into the +file so that decoders can recover the original data if desired. + + /* Set the true bit depth of the image data */ + if (color_type & PNG_COLOR_MASK_COLOR) + { + sig_bit.red = true_bit_depth; + sig_bit.green = true_bit_depth; + sig_bit.blue = true_bit_depth; + } + else + { + sig_bit.gray = true_bit_depth; + } + if (color_type & PNG_COLOR_MASK_ALPHA) + { + sig_bit.alpha = true_bit_depth; + } + + png_set_sBIT(png_ptr, info_ptr, &sig_bit); + +If the data is stored in the row buffer in a bit depth other than +one supported by PNG (e.g. 3 bit data in the range 0-7 for a 4-bit PNG), +this will scale the values to appear to be the correct bit depth as +is required by PNG. + + png_set_shift(png_ptr, &sig_bit); + +PNG files store 16 bit pixels in network byte order (big-endian, +ie. most significant bits first). This code would be used if they are +supplied the other way (little-endian, i.e. least significant bits +first, the way PCs store them): + + if (bit_depth > 8) + png_set_swap(png_ptr); + +If you are using packed-pixel images (1, 2, or 4 bits/pixel), and you +need to change the order the pixels are packed into bytes, you can use: + + if (bit_depth < 8) + png_set_packswap(png_ptr); + +PNG files store 3 color pixels in red, green, blue order. This code +would be used if they are supplied as blue, green, red: + + png_set_bgr(png_ptr); + +PNG files describe monochrome as black being zero and white being +one. This code would be used if the pixels are supplied with this reversed +(black being one and white being zero): + + png_set_invert_mono(png_ptr); + +Finally, you can write your own transformation function if none of +the existing ones meets your needs. This is done by setting a callback +with + + png_set_write_user_transform_fn(png_ptr, + write_transform_fn); + +You must supply the function + + void write_transform_fn(png_ptr ptr, row_info_ptr + row_info, png_bytep data) + +See pngtest.c for a working example. Your function will be called +before any of the other transformations are processed. + +You can also set up a pointer to a user structure for use by your +callback function. + + png_set_user_transform_info(png_ptr, user_ptr, 0, 0); + +The user_channels and user_depth parameters of this function are ignored +when writing; you can set them to zero as shown. + +You can retrieve the pointer via the function png_get_user_transform_ptr(). +For example: + + voidp write_user_transform_ptr = + png_get_user_transform_ptr(png_ptr); + +It is possible to have libpng flush any pending output, either manually, +or automatically after a certain number of lines have been written. To +flush the output stream a single time call: + + png_write_flush(png_ptr); + +and to have libpng flush the output stream periodically after a certain +number of scanlines have been written, call: + + png_set_flush(png_ptr, nrows); + +Note that the distance between rows is from the last time png_write_flush() +was called, or the first row of the image if it has never been called. +So if you write 50 lines, and then png_set_flush 25, it will flush the +output on the next scanline, and every 25 lines thereafter, unless +png_write_flush() is called before 25 more lines have been written. +If nrows is too small (less than about 10 lines for a 640 pixel wide +RGB image) the image compression may decrease noticeably (although this +may be acceptable for real-time applications). Infrequent flushing will +only degrade the compression performance by a few percent over images +that do not use flushing. + +Writing the image data + +That's it for the transformations. Now you can write the image data. +The simplest way to do this is in one function call. If you have the +whole image in memory, you can just call png_write_image() and libpng +will write the image. You will need to pass in an array of pointers to +each row. This function automatically handles interlacing, so you don't +need to call png_set_interlace_handling() or call this function multiple +times, or any of that other stuff necessary with png_write_rows(). + + png_write_image(png_ptr, row_pointers); + +where row_pointers is: + + png_byte *row_pointers[height]; + +You can point to void or char or whatever you use for pixels. + +If you don't want to write the whole image at once, you can +use png_write_rows() instead. If the file is not interlaced, +this is simple: + + png_write_rows(png_ptr, row_pointers, + number_of_rows); + +row_pointers is the same as in the png_write_image() call. + +If you are just writing one row at a time, you can do this with +a single row_pointer instead of an array of row_pointers: + + png_bytep row_pointer = row; + + png_write_row(png_ptr, row_pointer); + +When the file is interlaced, things can get a good deal more +complicated. The only currently (as of the PNG Specification +version 1.2, dated July 1999) defined interlacing scheme for PNG files +is the "Adam7" interlace scheme, that breaks down an +image into seven smaller images of varying size. libpng will build +these images for you, or you can do them yourself. If you want to +build them yourself, see the PNG specification for details of which +pixels to write when. + +If you don't want libpng to handle the interlacing details, just +use png_set_interlace_handling() and call png_write_rows() the +correct number of times to write all seven sub-images. + +If you want libpng to build the sub-images, call this before you start +writing any rows: + + number_of_passes = + png_set_interlace_handling(png_ptr); + +This will return the number of passes needed. Currently, this +is seven, but may change if another interlace type is added. + +Then write the complete image number_of_passes times. + + png_write_rows(png_ptr, row_pointers, + number_of_rows); + +As some of these rows are not used, and thus return immediately, +you may want to read about interlacing in the PNG specification, +and only update the rows that are actually used. + +Finishing a sequential write + +After you are finished writing the image, you should finish writing +the file. If you are interested in writing comments or time, you should +pass an appropriately filled png_info pointer. If you are not interested, +you can pass NULL. + + png_write_end(png_ptr, info_ptr); + +When you are done, you can free all memory used by libpng like this: + + png_destroy_write_struct(&png_ptr, &info_ptr); + +It is also possible to individually free the info_ptr members that +point to libpng-allocated storage with the following function: + + png_free_data(png_ptr, info_ptr, mask, seq) + mask - identifies data to be freed, a mask + containing the logical OR of one or + more of + PNG_FREE_PLTE, PNG_FREE_TRNS, + PNG_FREE_HIST, PNG_FREE_ICCP, + PNG_FREE_PCAL, PNG_FREE_ROWS, + PNG_FREE_SCAL, PNG_FREE_SPLT, + PNG_FREE_TEXT, PNG_FREE_UNKN, + or simply PNG_FREE_ALL + seq - sequence number of item to be freed + (-1 for all items) + +This function may be safely called when the relevant storage has +already been freed, or has not yet been allocated, or was allocated +by the user and not by libpng, and will in those +cases do nothing. The "seq" parameter is ignored if only one item +of the selected data type, such as PLTE, is allowed. If "seq" is not +-1, and multiple items are allowed for the data type identified in +the mask, such as text or sPLT, only the n'th item in the structure +is freed, where n is "seq". + +If you allocated data such as a palette that you passed +in to libpng with png_set_*, you must not free it until just before the call to +png_destroy_write_struct(). + +The default behavior is only to free data that was allocated internally +by libpng. This can be changed, so that libpng will not free the data, +or so that it will free data that was allocated by the user with png_malloc() +or png_zalloc() and passed in via a png_set_*() function, with + + png_data_freer(png_ptr, info_ptr, freer, mask) + mask - which data elements are affected + same choices as in png_free_data() + freer - one of + PNG_DESTROY_WILL_FREE_DATA + PNG_SET_WILL_FREE_DATA + PNG_USER_WILL_FREE_DATA + +For example, to transfer responsibility for some data from a read structure +to a write structure, you could use + + png_data_freer(read_ptr, read_info_ptr, + PNG_USER_WILL_FREE_DATA, + PNG_FREE_PLTE|PNG_FREE_tRNS|PNG_FREE_hIST) + png_data_freer(write_ptr, write_info_ptr, + PNG_DESTROY_WILL_FREE_DATA, + PNG_FREE_PLTE|PNG_FREE_tRNS|PNG_FREE_hIST) + +thereby briefly reassigning responsibility for freeing to the user but +immediately afterwards reassigning it once more to the write_destroy +function. Having done this, it would then be safe to destroy the read +structure and continue to use the PLTE, tRNS, and hIST data in the write +structure. + +This function only affects data that has already been allocated. +You can call this function before calling after the png_set_*() functions +to control whether the user or png_destroy_*() is supposed to free the data. +When the user assumes responsibility for libpng-allocated data, the +application must use +png_free() to free it, and when the user transfers responsibility to libpng +for data that the user has allocated, the user must have used png_malloc() +or png_zalloc() to allocate it. + +If you allocated text_ptr.text, text_ptr.lang, and text_ptr.translated_keyword +separately, do not transfer responsibility for freeing text_ptr to libpng, +because when libpng fills a png_text structure it combines these members with +the key member, and png_free_data() will free only text_ptr.key. Similarly, +if you transfer responsibility for free'ing text_ptr from libpng to your +application, your application must not separately free those members. +For a more compact example of writing a PNG image, see the file example.c. + +V. Modifying/Customizing libpng: + +There are three issues here. The first is changing how libpng does +standard things like memory allocation, input/output, and error handling. +The second deals with more complicated things like adding new chunks, +adding new transformations, and generally changing how libpng works. +Both of those are compile-time issues; that is, they are generally +determined at the time the code is written, and there is rarely a need +to provide the user with a means of changing them. The third is a +run-time issue: choosing between and/or tuning one or more alternate +versions of computationally intensive routines; specifically, optimized +assembly-language (and therefore compiler- and platform-dependent) +versions. + +Memory allocation, input/output, and error handling + +All of the memory allocation, input/output, and error handling in libpng +goes through callbacks that are user-settable. The default routines are +in pngmem.c, pngrio.c, pngwio.c, and pngerror.c, respectively. To change +these functions, call the appropriate png_set_*_fn() function. + +Memory allocation is done through the functions png_malloc() +and png_free(). These currently just call the standard C functions. If +your pointers can't access more then 64K at a time, you will want to set +MAXSEG_64K in zlib.h. Since it is unlikely that the method of handling +memory allocation on a platform will change between applications, these +functions must be modified in the library at compile time. If you prefer +to use a different method of allocating and freeing data, you can use +png_create_read_struct_2() or png_create_write_struct_2() to register +your own functions as described above. +These functions also provide a void pointer that can be retrieved via + + mem_ptr=png_get_mem_ptr(png_ptr); + +Your replacement memory functions must have prototypes as follows: + + png_voidp malloc_fn(png_structp png_ptr, + png_size_t size); + void free_fn(png_structp png_ptr, png_voidp ptr); + +Your malloc_fn() must return NULL in case of failure. The png_malloc() +function will normally call png_error() if it receives a NULL from the +system memory allocator or from your replacement malloc_fn(). + +Input/Output in libpng is done through png_read() and png_write(), +which currently just call fread() and fwrite(). The FILE * is stored in +png_struct and is initialized via png_init_io(). If you wish to change +the method of I/O, the library supplies callbacks that you can set +through the function png_set_read_fn() and png_set_write_fn() at run +time, instead of calling the png_init_io() function. These functions +also provide a void pointer that can be retrieved via the function +png_get_io_ptr(). For example: + + png_set_read_fn(png_structp read_ptr, + voidp read_io_ptr, png_rw_ptr read_data_fn) + + png_set_write_fn(png_structp write_ptr, + voidp write_io_ptr, png_rw_ptr write_data_fn, + png_flush_ptr output_flush_fn); + + voidp read_io_ptr = png_get_io_ptr(read_ptr); + voidp write_io_ptr = png_get_io_ptr(write_ptr); + +The replacement I/O functions must have prototypes as follows: + + void user_read_data(png_structp png_ptr, + png_bytep data, png_size_t length); + void user_write_data(png_structp png_ptr, + png_bytep data, png_size_t length); + void user_flush_data(png_structp png_ptr); + +Supplying NULL for the read, write, or flush functions sets them back +to using the default C stream functions. It is an error to read from +a write stream, and vice versa. + +Error handling in libpng is done through png_error() and png_warning(). +Errors handled through png_error() are fatal, meaning that png_error() +should never return to its caller. Currently, this is handled via +setjmp() and longjmp() (unless you have compiled libpng with +PNG_SETJMP_NOT_SUPPORTED, in which case it is handled via PNG_ABORT()), +but you could change this to do things like exit() if you should wish. + +On non-fatal errors, png_warning() is called +to print a warning message, and then control returns to the calling code. +By default png_error() and png_warning() print a message on stderr via +fprintf() unless the library is compiled with PNG_NO_CONSOLE_IO defined +(because you don't want the messages) or PNG_NO_STDIO defined (because +fprintf() isn't available). If you wish to change the behavior of the error +functions, you will need to set up your own message callbacks. These +functions are normally supplied at the time that the png_struct is created. +It is also possible to redirect errors and warnings to your own replacement +functions after png_create_*_struct() has been called by calling: + + png_set_error_fn(png_structp png_ptr, + png_voidp error_ptr, png_error_ptr error_fn, + png_error_ptr warning_fn); + + png_voidp error_ptr = png_get_error_ptr(png_ptr); + +If NULL is supplied for either error_fn or warning_fn, then the libpng +default function will be used, calling fprintf() and/or longjmp() if a +problem is encountered. The replacement error functions should have +parameters as follows: + + void user_error_fn(png_structp png_ptr, + png_const_charp error_msg); + void user_warning_fn(png_structp png_ptr, + png_const_charp warning_msg); + +The motivation behind using setjmp() and longjmp() is the C++ throw and +catch exception handling methods. This makes the code much easier to write, +as there is no need to check every return code of every function call. +However, there are some uncertainties about the status of local variables +after a longjmp, so the user may want to be careful about doing anything after +setjmp returns non-zero besides returning itself. Consult your compiler +documentation for more details. For an alternative approach, you may wish +to use the "cexcept" facility (see http://cexcept.sourceforge.net). + +Custom chunks + +If you need to read or write custom chunks, you may need to get deeper +into the libpng code. The library now has mechanisms for storing +and writing chunks of unknown type; you can even declare callbacks +for custom chunks. However, this may not be good enough if the +library code itself needs to know about interactions between your +chunk and existing `intrinsic' chunks. + +If you need to write a new intrinsic chunk, first read the PNG +specification. Acquire a first level of +understanding of how it works. Pay particular attention to the +sections that describe chunk names, and look at how other chunks were +designed, so you can do things similarly. Second, check out the +sections of libpng that read and write chunks. Try to find a chunk +that is similar to yours and use it as a template. More details can +be found in the comments inside the code. It is best to handle unknown +chunks in a generic method, via callback functions, instead of by +modifying libpng functions. + +If you wish to write your own transformation for the data, look through +the part of the code that does the transformations, and check out some of +the simpler ones to get an idea of how they work. Try to find a similar +transformation to the one you want to add and copy off of it. More details +can be found in the comments inside the code itself. + +Configuring for 16 bit platforms + +You will want to look into zconf.h to tell zlib (and thus libpng) that +it cannot allocate more then 64K at a time. Even if you can, the memory +won't be accessible. So limit zlib and libpng to 64K by defining MAXSEG_64K. + +Configuring for DOS + +For DOS users who only have access to the lower 640K, you will +have to limit zlib's memory usage via a png_set_compression_mem_level() +call. See zlib.h or zconf.h in the zlib library for more information. + +Configuring for Medium Model + +Libpng's support for medium model has been tested on most of the popular +compilers. Make sure MAXSEG_64K gets defined, USE_FAR_KEYWORD gets +defined, and FAR gets defined to far in pngconf.h, and you should be +all set. Everything in the library (except for zlib's structure) is +expecting far data. You must use the typedefs with the p or pp on +the end for pointers (or at least look at them and be careful). Make +note that the rows of data are defined as png_bytepp, which is an +unsigned char far * far *. + +Configuring for gui/windowing platforms: + +You will need to write new error and warning functions that use the GUI +interface, as described previously, and set them to be the error and +warning functions at the time that png_create_*_struct() is called, +in order to have them available during the structure initialization. +They can be changed later via png_set_error_fn(). On some compilers, +you may also have to change the memory allocators (png_malloc, etc.). + +Configuring for compiler xxx: + +All includes for libpng are in pngconf.h. If you need to add/change/delete +an include, this is the place to do it. The includes that are not +needed outside libpng are protected by the PNG_INTERNAL definition, +which is only defined for those routines inside libpng itself. The +files in libpng proper only include png.h, which includes pngconf.h. + +Configuring zlib: + +There are special functions to configure the compression. Perhaps the +most useful one changes the compression level, which currently uses +input compression values in the range 0 - 9. The library normally +uses the default compression level (Z_DEFAULT_COMPRESSION = 6). Tests +have shown that for a large majority of images, compression values in +the range 3-6 compress nearly as well as higher levels, and do so much +faster. For online applications it may be desirable to have maximum speed +(Z_BEST_SPEED = 1). With versions of zlib after v0.99, you can also +specify no compression (Z_NO_COMPRESSION = 0), but this would create +files larger than just storing the raw bitmap. You can specify the +compression level by calling: + + png_set_compression_level(png_ptr, level); + +Another useful one is to reduce the memory level used by the library. +The memory level defaults to 8, but it can be lowered if you are +short on memory (running DOS, for example, where you only have 640K). +Note that the memory level does have an effect on compression; among +other things, lower levels will result in sections of incompressible +data being emitted in smaller stored blocks, with a correspondingly +larger relative overhead of up to 15% in the worst case. + + png_set_compression_mem_level(png_ptr, level); + +The other functions are for configuring zlib. They are not recommended +for normal use and may result in writing an invalid PNG file. See +zlib.h for more information on what these mean. + + png_set_compression_strategy(png_ptr, + strategy); + png_set_compression_window_bits(png_ptr, + window_bits); + png_set_compression_method(png_ptr, method); + png_set_compression_buffer_size(png_ptr, size); + +Controlling row filtering + +If you want to control whether libpng uses filtering or not, which +filters are used, and how it goes about picking row filters, you +can call one of these functions. The selection and configuration +of row filters can have a significant impact on the size and +encoding speed and a somewhat lesser impact on the decoding speed +of an image. Filtering is enabled by default for RGB and grayscale +images (with and without alpha), but not for paletted images nor +for any images with bit depths less than 8 bits/pixel. + +The 'method' parameter sets the main filtering method, which is +currently only '0' in the PNG 1.2 specification. The 'filters' +parameter sets which filter(s), if any, should be used for each +scanline. Possible values are PNG_ALL_FILTERS and PNG_NO_FILTERS +to turn filtering on and off, respectively. + +Individual filter types are PNG_FILTER_NONE, PNG_FILTER_SUB, +PNG_FILTER_UP, PNG_FILTER_AVG, PNG_FILTER_PAETH, which can be bitwise +ORed together with '|' to specify one or more filters to use. +These filters are described in more detail in the PNG specification. +If you intend to change the filter type during the course of writing +the image, you should start with flags set for all of the filters +you intend to use so that libpng can initialize its internal +structures appropriately for all of the filter types. (Note that this +means the first row must always be adaptively filtered, because libpng +currently does not allocate the filter buffers until png_write_row() +is called for the first time.) + + filters = PNG_FILTER_NONE | PNG_FILTER_SUB + PNG_FILTER_UP | PNG_FILTER_AVE | + PNG_FILTER_PAETH | PNG_ALL_FILTERS; + + png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, + filters); + The second parameter can also be + PNG_INTRAPIXEL_DIFFERENCING if you are + writing a PNG to be embedded in a MNG + datastream. This parameter must be the + same as the value of filter_method used + in png_set_IHDR(). + +It is also possible to influence how libpng chooses from among the +available filters. This is done in one or both of two ways - by +telling it how important it is to keep the same filter for successive +rows, and by telling it the relative computational costs of the filters. + + double weights[3] = {1.5, 1.3, 1.1}, + costs[PNG_FILTER_VALUE_LAST] = + {1.0, 1.3, 1.3, 1.5, 1.7}; + + png_set_filter_heuristics(png_ptr, + PNG_FILTER_HEURISTIC_WEIGHTED, 3, + weights, costs); + +The weights are multiplying factors that indicate to libpng that the +row filter should be the same for successive rows unless another row filter +is that many times better than the previous filter. In the above example, +if the previous 3 filters were SUB, SUB, NONE, the SUB filter could have a +"sum of absolute differences" 1.5 x 1.3 times higher than other filters +and still be chosen, while the NONE filter could have a sum 1.1 times +higher than other filters and still be chosen. Unspecified weights are +taken to be 1.0, and the specified weights should probably be declining +like those above in order to emphasize recent filters over older filters. + +The filter costs specify for each filter type a relative decoding cost +to be considered when selecting row filters. This means that filters +with higher costs are less likely to be chosen over filters with lower +costs, unless their "sum of absolute differences" is that much smaller. +The costs do not necessarily reflect the exact computational speeds of +the various filters, since this would unduly influence the final image +size. + +Note that the numbers above were invented purely for this example and +are given only to help explain the function usage. Little testing has +been done to find optimum values for either the costs or the weights. + +Removing unwanted object code + +There are a bunch of #define's in pngconf.h that control what parts of +libpng are compiled. All the defines end in _SUPPORTED. If you are +never going to use a capability, you can change the #define to #undef +before recompiling libpng and save yourself code and data space, or +you can turn off individual capabilities with defines that begin with +PNG_NO_. + +You can also turn all of the transforms and ancillary chunk capabilities +off en masse with compiler directives that define +PNG_NO_READ[or WRITE]_TRANSFORMS, or PNG_NO_READ[or WRITE]_ANCILLARY_CHUNKS, +or all four, +along with directives to turn on any of the capabilities that you do +want. The PNG_NO_READ[or WRITE]_TRANSFORMS directives disable +the extra transformations but still leave the library fully capable of reading +and writing PNG files with all known public chunks +Use of the PNG_NO_READ[or WRITE]_ANCILLARY_CHUNKS directive +produces a library that is incapable of reading or writing ancillary chunks. +If you are not using the progressive reading capability, you can +turn that off with PNG_NO_PROGRESSIVE_READ (don't confuse +this with the INTERLACING capability, which you'll still have). + +All the reading and writing specific code are in separate files, so the +linker should only grab the files it needs. However, if you want to +make sure, or if you are building a stand alone library, all the +reading files start with pngr and all the writing files start with +pngw. The files that don't match either (like png.c, pngtrans.c, etc.) +are used for both reading and writing, and always need to be included. +The progressive reader is in pngpread.c + +If you are creating or distributing a dynamically linked library (a .so +or DLL file), you should not remove or disable any parts of the library, +as this will cause applications linked with different versions of the +library to fail if they call functions not available in your library. +The size of the library itself should not be an issue, because only +those sections that are actually used will be loaded into memory. + +Requesting debug printout + +The macro definition PNG_DEBUG can be used to request debugging +printout. Set it to an integer value in the range 0 to 3. Higher +numbers result in increasing amounts of debugging information. The +information is printed to the "stderr" file, unless another file +name is specified in the PNG_DEBUG_FILE macro definition. + +When PNG_DEBUG > 0, the following functions (macros) become available: + + png_debug(level, message) + png_debug1(level, message, p1) + png_debug2(level, message, p1, p2) + +in which "level" is compared to PNG_DEBUG to decide whether to print +the message, "message" is the formatted string to be printed, +and p1 and p2 are parameters that are to be embedded in the string +according to printf-style formatting directives. For example, + + png_debug1(2, "foo=%d\n", foo); + +is expanded to + + if(PNG_DEBUG > 2) + fprintf(PNG_DEBUG_FILE, "foo=%d\n", foo); + +When PNG_DEBUG is defined but is zero, the macros aren't defined, but you +can still use PNG_DEBUG to control your own debugging: + + #ifdef PNG_DEBUG + fprintf(stderr, ... + #endif + +When PNG_DEBUG = 1, the macros are defined, but only png_debug statements +having level = 0 will be printed. There aren't any such statements in +this version of libpng, but if you insert some they will be printed. + +VI. Runtime optimization + +A new feature in libpng 1.2.0 is the ability to dynamically switch between +standard and optimized versions of some routines. Currently these are +limited to three computationally intensive tasks when reading PNG files: +decoding row filters, expanding interlacing, and combining interlaced or +transparent row data with previous row data. Currently the optimized +versions are available only for x86 (Intel, AMD, etc.) platforms with +MMX support, though this may change in future versions. (For example, +the non-MMX assembler optimizations for zlib might become similarly +runtime-selectable in future releases, in which case libpng could be +extended to support them. Alternatively, the compile-time choice of +floating-point versus integer routines for gamma correction might become +runtime-selectable.) + +Because such optimizations tend to be very platform- and compiler-dependent, +both in how they are written and in how they perform, the new runtime code +in libpng has been written to allow programs to query, enable, and disable +either specific optimizations or all such optimizations. For example, to +enable all possible optimizations (bearing in mind that some "optimizations" +may actually run more slowly in rare cases): + + #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200) + png_uint_32 mask, flags; + + flags = png_get_asm_flags(png_ptr); + mask = png_get_asm_flagmask(PNG_SELECT_READ | PNG_SELECT_WRITE); + png_set_asm_flags(png_ptr, flags | mask); + #endif + +To enable only optimizations relevant to reading PNGs, use PNG_SELECT_READ +by itself when calling png_get_asm_flagmask(); similarly for optimizing +only writing. To disable all optimizations: + + #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200) + flags = png_get_asm_flags(png_ptr); + mask = png_get_asm_flagmask(PNG_SELECT_READ | PNG_SELECT_WRITE); + png_set_asm_flags(png_ptr, flags & ~mask); + #endif + +To enable or disable only MMX-related features, use png_get_mmx_flagmask() +in place of png_get_asm_flagmask(). The mmx version takes one additional +parameter: + + #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200) + int selection = PNG_SELECT_READ | PNG_SELECT_WRITE; + int compilerID; + + mask = png_get_mmx_flagmask(selection, &compilerID); + #endif + +On return, compilerID will indicate which version of the MMX assembler +optimizations was compiled. Currently two flavors exist: Microsoft +Visual C++ (compilerID == 1) and GNU C (a.k.a. gcc/gas, compilerID == 2). +On non-x86 platforms or on systems compiled without MMX optimizations, a +value of -1 is used. + +Note that both png_get_asm_flagmask() and png_get_mmx_flagmask() return +all valid, settable optimization bits for the version of the library that's +currently in use. In the case of shared (dynamically linked) libraries, +this may include optimizations that did not exist at the time the code was +written and compiled. It is also possible, of course, to enable only known, +specific optimizations; for example: + + #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200) + flags = PNG_ASM_FLAG_MMX_READ_COMBINE_ROW \ + | PNG_ASM_FLAG_MMX_READ_INTERLACE \ + | PNG_ASM_FLAG_MMX_READ_FILTER_SUB \ + | PNG_ASM_FLAG_MMX_READ_FILTER_UP \ + | PNG_ASM_FLAG_MMX_READ_FILTER_AVG \ + | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ; + png_set_asm_flags(png_ptr, flags); + #endif + +This method would enable only the MMX read-optimizations available at the +time of libpng 1.2.0's release, regardless of whether a later version of +the DLL were actually being used. (Also note that these functions did not +exist in versions older than 1.2.0, so any attempt to run a dynamically +linked app on such an older version would fail.) + +To determine whether the processor supports MMX instructions at all, use +the png_mmx_support() function: + + #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200) + mmxsupport = png_mmx_support(); + #endif + +It returns -1 if MMX support is not compiled into libpng, 0 if MMX code +is compiled but MMX is not supported by the processor, or 1 if MMX support +is fully available. Note that png_mmx_support(), png_get_mmx_flagmask(), +and png_get_asm_flagmask() all may be called without allocating and ini- +tializing any PNG structures (for example, as part of a usage screen or +"about" box). + +The following code can be used to prevent an application from using the +thread_unsafe features, even if libpng was built with PNG_THREAD_UNSAFE_OK +defined: + +#if defined(PNG_USE_PNGGCCRD) && defined(PNG_ASSEMBLER_CODE_SUPPORTED) \ + && defined(PNG_THREAD_UNSAFE_OK) + /* Disable thread-unsafe features of pnggccrd */ + if (png_access_version_number() >= 10200) + { + png_uint_32 mmx_disable_mask = 0; + png_uint_32 asm_flags; + + mmx_disable_mask |= ( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW \ + | PNG_ASM_FLAG_MMX_READ_FILTER_SUB \ + | PNG_ASM_FLAG_MMX_READ_FILTER_AVG \ + | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ); + asm_flags = png_get_asm_flags(png_ptr); + png_set_asm_flags(png_ptr, asm_flags & ~mmx_disable_mask); + } +#endif + +For more extensive examples of runtime querying, enabling and disabling +of optimized features, see contrib/gregbook/readpng2.c in the libpng +source-code distribution. + +VII. MNG support + +The MNG specification (available at http://www.libpng.org/pub/mng) allows +certain extensions to PNG for PNG images that are embedded in MNG datastreams. +Libpng can support some of these extensions. To enable them, use the +png_permit_mng_features() function: + + feature_set = png_permit_mng_features(png_ptr, mask) + mask is a png_uint_32 containing the logical OR of the + features you want to enable. These include + PNG_FLAG_MNG_EMPTY_PLTE + PNG_FLAG_MNG_FILTER_64 + PNG_ALL_MNG_FEATURES + feature_set is a png_uint_32 that is the logical AND of + your mask with the set of MNG features that is + supported by the version of libpng that you are using. + +It is an error to use this function when reading or writing a standalone +PNG file with the PNG 8-byte signature. The PNG datastream must be wrapped +in a MNG datastream. As a minimum, it must have the MNG 8-byte signature +and the MHDR and MEND chunks. Libpng does not provide support for these +or any other MNG chunks; your application must provide its own support for +them. You may wish to consider using libmng (available at +http://www.libmng.com) instead. + +VIII. Changes to Libpng from version 0.88 + +It should be noted that versions of libpng later than 0.96 are not +distributed by the original libpng author, Guy Schalnat, nor by +Andreas Dilger, who had taken over from Guy during 1996 and 1997, and +distributed versions 0.89 through 0.96, but rather by another member +of the original PNG Group, Glenn Randers-Pehrson. Guy and Andreas are +still alive and well, but they have moved on to other things. + +The old libpng functions png_read_init(), png_write_init(), +png_info_init(), png_read_destroy(), and png_write_destroy() have been +moved to PNG_INTERNAL in version 0.95 to discourage their use. These +functions will be removed from libpng version 2.0.0. + +The preferred method of creating and initializing the libpng structures is +via the png_create_read_struct(), png_create_write_struct(), and +png_create_info_struct() because they isolate the size of the structures +from the application, allow version error checking, and also allow the +use of custom error handling routines during the initialization, which +the old functions do not. The functions png_read_destroy() and +png_write_destroy() do not actually free the memory that libpng +allocated for these structs, but just reset the data structures, so they +can be used instead of png_destroy_read_struct() and +png_destroy_write_struct() if you feel there is too much system overhead +allocating and freeing the png_struct for each image read. + +Setting the error callbacks via png_set_message_fn() before +png_read_init() as was suggested in libpng-0.88 is no longer supported +because this caused applications that do not use custom error functions +to fail if the png_ptr was not initialized to zero. It is still possible +to set the error callbacks AFTER png_read_init(), or to change them with +png_set_error_fn(), which is essentially the same function, but with a new +name to force compilation errors with applications that try to use the old +method. + +Starting with version 1.0.7, you can find out which version of the library +you are using at run-time: + + png_uint_32 libpng_vn = png_access_version_number(); + +The number libpng_vn is constructed from the major version, minor +version with leading zero, and release number with leading zero, +(e.g., libpng_vn for version 1.0.7 is 10007). + +You can also check which version of png.h you used when compiling your +application: + + png_uint_32 application_vn = PNG_LIBPNG_VER; + +IX. Y2K Compliance in libpng + +June 27, 2006 + +Since the PNG Development group is an ad-hoc body, we can't make +an official declaration. + +This is your unofficial assurance that libpng from version 0.71 and +upward through 1.2.12 are Y2K compliant. It is my belief that earlier +versions were also Y2K compliant. + +Libpng only has three year fields. One is a 2-byte unsigned integer that +will hold years up to 65535. The other two hold the date in text +format, and will hold years up to 9999. + +The integer is + "png_uint_16 year" in png_time_struct. + +The strings are + "png_charp time_buffer" in png_struct and + "near_time_buffer", which is a local character string in png.c. + +There are seven time-related functions: + + png_convert_to_rfc_1123() in png.c + (formerly png_convert_to_rfc_1152() in error) + png_convert_from_struct_tm() in pngwrite.c, called + in pngwrite.c + png_convert_from_time_t() in pngwrite.c + png_get_tIME() in pngget.c + png_handle_tIME() in pngrutil.c, called in pngread.c + png_set_tIME() in pngset.c + png_write_tIME() in pngwutil.c, called in pngwrite.c + +All appear to handle dates properly in a Y2K environment. The +png_convert_from_time_t() function calls gmtime() to convert from system +clock time, which returns (year - 1900), which we properly convert to +the full 4-digit year. There is a possibility that applications using +libpng are not passing 4-digit years into the png_convert_to_rfc_1123() +function, or that they are incorrectly passing only a 2-digit year +instead of "year - 1900" into the png_convert_from_struct_tm() function, +but this is not under our control. The libpng documentation has always +stated that it works with 4-digit years, and the APIs have been +documented as such. + +The tIME chunk itself is also Y2K compliant. It uses a 2-byte unsigned +integer to hold the year, and can hold years as large as 65535. + +zlib, upon which libpng depends, is also Y2K compliant. It contains +no date-related code. + + + Glenn Randers-Pehrson + libpng maintainer + PNG Development Group diff --git a/mod/pub.mod/libpng.mod/libpngpf.3 b/mod/pub.mod/libpng.mod/libpngpf.3 new file mode 100644 index 0000000..46ff40c --- /dev/null +++ b/mod/pub.mod/libpng.mod/libpngpf.3 @@ -0,0 +1,784 @@ +.TH LIBPNGPF 3 "June 27, 2006" +.SH NAME +libpng \- Portable Network Graphics (PNG) Reference Library 1.2.12 +(private functions) +.SH SYNOPSIS +\fB#include <png.h>\fP + +\fI\fB + +\fI\fB + +\fBvoid png_build_gamma_table (png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_build_grayscale_palette (int \fP\fIbit_depth\fP\fB, png_colorp \fIpalette\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_calculate_crc (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIptr\fP\fB, png_size_t \fIlength\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_check_chunk_name (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fIchunk_name\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBpng_size_t png_check_keyword (png_structp \fP\fIpng_ptr\fP\fB, png_charp \fP\fIkey\fP\fB, png_charpp \fInew_key\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_combine_row (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIrow\fP\fB, int \fImask\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_correct_palette (png_structp \fP\fIpng_ptr\fP\fB, png_colorp \fP\fIpalette\fP\fB, int \fInum_palette\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBint png_crc_error (png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBint png_crc_finish (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fIskip\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_crc_read (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIbuf\fP\fB, png_size_t \fIlength\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBpng_voidp png_create_struct (int \fItype\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBpng_voidp png_create_struct_2 (int \fP\fItype\fP\fB, png_malloc_ptr \fP\fImalloc_fn\fP\fB, png_voidp \fImem_ptr\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBpng_charp png_decompress_chunk (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fIcomp_type\fP\fB, png_charp \fP\fIchunkdata\fP\fB, png_size_t \fP\fIchunklength\fP\fB, png_size_t \fP\fIprefix_length\fP\fB, png_size_t \fI*data_length\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_destroy_struct (png_voidp \fIstruct_ptr\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_destroy_struct_2 (png_voidp \fP\fIstruct_ptr\fP\fB, png_free_ptr \fP\fIfree_fn\fP\fB, png_voidp \fImem_ptr\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_do_background (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_color_16p \fP\fItrans_values\fP\fB, png_color_16p \fP\fIbackground\fP\fB, png_color_16p \fP\fIbackground_1\fP\fB, png_bytep \fP\fIgamma_table\fP\fB, png_bytep \fP\fIgamma_from_1\fP\fB, png_bytep \fP\fIgamma_to_1\fP\fB, png_uint_16pp \fP\fIgamma_16\fP\fB, png_uint_16pp \fP\fIgamma_16_from_1\fP\fB, png_uint_16pp \fP\fIgamma_16_to_1\fP\fB, int \fIgamma_shift\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_do_bgr (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_do_chop (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_do_dither (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_bytep \fP\fIpalette_lookup\fP\fB, png_bytep \fIdither_lookup\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_do_expand (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_color_16p \fItrans_value\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_do_expand_palette (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_colorp \fP\fIpalette\fP\fB, png_bytep \fP\fItrans\fP\fB, int \fInum_trans\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_do_gamma (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_bytep \fP\fIgamma_table\fP\fB, png_uint_16pp \fP\fIgamma_16_table\fP\fB, int \fIgamma_shift\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_do_gray_to_rgb (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_do_invert (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_do_pack (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_uint_32 \fIbit_depth\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_do_packswap (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_do_read_filler (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_uint_32 \fP\fIfiller\fP\fB, png_uint_32 \fIflags\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_do_read_interlace (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, int \fP\fIpass\fP\fB, png_uint_32 \fItransformations\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_do_read_invert_alpha (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_do_read_swap_alpha (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_do_read_transformations (png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBint png_do_rgb_to_gray (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_do_shift (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_color_8p \fIbit_depth\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_do_strip_filler (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_uint_32 \fIflags\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_do_swap (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_do_unpack (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_do_unshift (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_color_8p \fIsig_bits\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_do_write_interlace (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, int \fIpass\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_do_write_invert_alpha (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_do_write_swap_alpha (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_do_write_transformations (png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid *png_far_to_near (png_structp png_ptr,png_voidp \fP\fIptr\fP\fB, int \fIcheck\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_flush (png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_handle_bKGD (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_handle_cHRM (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_handle_gAMA (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_handle_hIST (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_handle_IEND (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_handle_IHDR (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_handle_iCCP (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_handle_iTXt (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_handle_oFFs (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_handle_pCAL (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_handle_pHYs (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_handle_PLTE (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_handle_sBIT (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_handle_sCAL (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_handle_sPLT (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_handle_sRGB (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_handle_tEXt (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_handle_tIME (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_handle_tRNS (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_handle_unknown (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_handle_zTXt (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_info_destroy (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_init_mmx_flags (png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_init_read_transformations (png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_process_IDAT_data (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIbuffer\fP\fB, png_size_t \fIbuffer_length\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_process_some_data (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_push_check_crc (png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_push_crc_finish (png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_push_crc_skip (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_push_fill_buffer (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIbuffer\fP\fB, png_size_t \fIlength\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_push_handle_tEXt (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_push_handle_unknown (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_push_handle_zTXt (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_push_have_end (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_push_have_info (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_push_have_row (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fIrow\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_push_process_row (png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_push_read_chunk (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_push_read_end (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_push_read_IDAT (png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_push_read_sig (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_push_read_tEXt (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_push_read_zTXt (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_push_restore_buffer (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIbuffer\fP\fB, png_size_t \fIbuffer_length\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_push_save_buffer (png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_read_data (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIdata\fP\fB, png_size_t \fIlength\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_read_filter_row (png_structp \fP\fIpng_ptr\fP\fB, png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_bytep \fP\fIprev_row\fP\fB, int \fIfilter\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_read_finish_row (png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_read_push_finish_row (png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_read_start_row (png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_read_transform_info (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_reset_crc (png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBint png_set_text_2 (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_textp \fP\fItext_ptr\fP\fB, int \fInum_text\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_write_cHRM (png_structp \fP\fIpng_ptr\fP\fB, double \fP\fIwhite_x\fP\fB, double \fP\fIwhite_y\fP\fB, double \fP\fIred_x\fP\fB, double \fP\fIred_y\fP\fB, double \fP\fIgreen_x\fP\fB, double \fP\fIgreen_y\fP\fB, double \fP\fIblue_x\fP\fB, double \fIblue_y\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_write_cHRM_fixed (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fP\fIwhite_x\fP\fB, png_uint_32 \fP\fIwhite_y\fP\fB, png_uint_32 \fP\fIred_x\fP\fB, png_uint_32 \fP\fIred_y\fP\fB, png_uint_32 \fP\fIgreen_x\fP\fB, png_uint_32 \fP\fIgreen_y\fP\fB, png_uint_32 \fP\fIblue_x\fP\fB, png_uint_32 \fIblue_y\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_write_data (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIdata\fP\fB, png_size_t \fIlength\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_write_filtered_row (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fIfiltered_row\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_write_find_filter (png_structp \fP\fIpng_ptr\fP\fB, png_row_infop \fIrow_info\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_write_finish_row (png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_write_gAMA (png_structp \fP\fIpng_ptr\fP\fB, double \fIfile_gamma\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_write_gAMA_fixed (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fIint_file_gamma\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_write_hIST (png_structp \fP\fIpng_ptr\fP\fB, png_uint_16p \fP\fIhist\fP\fB, int \fInum_hist\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_write_iCCP (png_structp \fP\fIpng_ptr\fP\fB, png_charp \fP\fIname\fP\fB, int \fP\fIcompression_type\fP\fB, png_charp \fP\fIprofile\fP\fB, int \fIproflen\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_write_IDAT (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIdata\fP\fB, png_size_t \fIlength\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_write_IEND (png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_write_IHDR (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fP\fIwidth\fP\fB, png_uint_32 \fP\fIheight\fP\fB, int \fP\fIbit_depth\fP\fB, int \fP\fIcolor_type\fP\fB, int \fP\fIcompression_type\fP\fB, int \fP\fIfilter_type\fP\fB, int \fIinterlace_type\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_write_iTXt (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fIcompression\fP\fB, png_charp \fP\fIkey\fP\fB, png_charp \fP\fIlang\fP\fB, png_charp \fP\fItranslated_key\fP\fB, png_charp \fItext\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_write_oFFs (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fP\fIx_offset\fP\fB, png_uint_32 \fP\fIy_offset\fP\fB, int \fIunit_type\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_write_pCAL (png_structp \fP\fIpng_ptr\fP\fB, png_charp \fP\fIpurpose\fP\fB, png_int_32 \fP\fIX0\fP\fB, png_int_32 \fP\fIX1\fP\fB, int \fP\fItype\fP\fB, int \fP\fInparams\fP\fB, png_charp \fP\fIunits\fP\fB, png_charpp \fIparams\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_write_pHYs (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fP\fIx_pixels_per_unit\fP\fB, png_uint_32 \fP\fIy_pixels_per_unit\fP\fB, int \fIunit_type\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_write_PLTE (png_structp \fP\fIpng_ptr\fP\fB, png_colorp \fP\fIpalette\fP\fB, png_uint_32 \fInum_pal\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_write_sBIT (png_structp \fP\fIpng_ptr\fP\fB, png_color_8p \fP\fIsbit\fP\fB, int \fIcolor_type\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_write_sCAL (png_structp \fP\fIpng_ptr\fP\fB, png_charp \fP\fIunit\fP\fB, double \fP\fIwidth\fP\fB, double \fIheight\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_write_sCAL_s (png_structp \fP\fIpng_ptr\fP\fB, png_charp \fP\fIunit\fP\fB, png_charp \fP\fIwidth\fP\fB, png_charp \fIheight\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_write_sig (png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_write_sRGB (png_structp \fP\fIpng_ptr\fP\fB, int \fIintent\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_write_sPLT (png_structp \fP\fIpng_ptr\fP\fB, png_spalette_p \fIpalette\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_write_start_row (png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_write_tEXt (png_structp \fP\fIpng_ptr\fP\fB, png_charp \fP\fIkey\fP\fB, png_charp \fP\fItext\fP\fB, png_size_t \fItext_len\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_write_tIME (png_structp \fP\fIpng_ptr\fP\fB, png_timep \fImod_time\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_write_tRNS (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fItrans\fP\fB, png_color_16p \fP\fIvalues\fP\fB, int \fP\fInumber\fP\fB, int \fIcolor_type\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_write_zTXt (png_structp \fP\fIpng_ptr\fP\fB, png_charp \fP\fIkey\fP\fB, png_charp \fP\fItext\fP\fB, png_size_t \fP\fItext_len\fP\fB, int \fIcompression\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoidpf png_zalloc (voidpf \fP\fIpng_ptr\fP\fB, uInt \fP\fIitems\fP\fB, uInt \fIsize\fP\fB);\fP + +\fI\fB + +\fI\fB + +\fBvoid png_zfree (voidpf \fP\fIpng_ptr\fP\fB, voidpf \fIptr\fP\fB);\fP + +\fI\fB + +\fI\fB + +.SH DESCRIPTION +The functions listed above are used privately by libpng +and are not recommended for use by applications. They are +not "exported" to applications using shared libraries. They +are listed alphabetically here as an aid to libpng maintainers. +See png.h for more information on these functions. + +.SH SEE ALSO +libpng(3), png(5) +.SH AUTHOR +Glenn Randers-Pehrson diff --git a/mod/pub.mod/libpng.mod/png.5 b/mod/pub.mod/libpng.mod/png.5 new file mode 100644 index 0000000..a908750 --- /dev/null +++ b/mod/pub.mod/libpng.mod/png.5 @@ -0,0 +1,74 @@ +.TH PNG 5 "June 27, 2006" +.SH NAME +png \- Portable Network Graphics (PNG) format +.SH DESCRIPTION +PNG (Portable Network Graphics) is an extensible file format for the +lossless, portable, well-compressed storage of raster images. PNG provides +a patent-free replacement for GIF and can also replace many +common uses of TIFF. Indexed-color, grayscale, and truecolor images are +supported, plus an optional alpha channel. Sample depths range from +1 to 16 bits. +.br + +PNG is designed to work well in online viewing applications, such as the +World Wide Web, so it is fully streamable with a progressive display +option. PNG is robust, providing both full file integrity checking and +fast, simple detection of common transmission errors. Also, PNG can store +gamma and chromaticity data for improved color matching on heterogeneous +platforms. + +.SH "SEE ALSO" +.IR libpng(3), zlib(3), deflate(5), and zlib(5) +.LP +PNG specification (second edition), November 2003: +.IP +.br + <http://www.w3.org/TR/2003/REC-PNG-20031110/ +PNG 1.2 specification, July 1999: +.IP +.br +http://www.libpng.org/pub/png +.LP +PNG 1.0 specification, October 1996: +.IP +.br +RFC 2083 +.IP +.br +ftp://ds.internic.net/rfc/rfc2083.txt +.br +or (as a W3C Recommendation) at +.br +http://www.w3.org/TR/REC-png.html +.SH AUTHORS +This man page: Glenn Randers-Pehrson +.LP +Portable Network Graphics (PNG) Specification (Second Edition) +Information technology - Computer graphics and image processing - +Portable Network Graphics (PNG): Functional specification. +ISO/IEC 15948:2003 (E) (November 10, 2003): David Duce and others. +.LP +Portable Network Graphics (PNG) Specification Version 1.2 (July 8, 1999): +Glenn Randers-Pehrson and others (png-list). +.LP +Portable Network Graphics (PNG) Specification Version 1.0 (October 1, 1996): +Thomas Boutell and others (png-list). +.LP + + +.SH COPYRIGHT NOTICE +.LP +This man page is Copyright (c) 1998-2006 Glenn Randers-Pehrson. See png.h +for conditions of use and distribution. +.LP +The PNG Specification (Second Edition) is +Copyright (c) 2003 W3C. (MIT, ERCIM, Keio), All Rights Reserved. +.LP +The PNG-1.2 specification is copyright (c) 1999 Glenn Randers-Pehrson. +See the specification for conditions of use and distribution. +.LP +The PNG-1.0 specification is copyright (c) 1996 Massachusetts Institute of +Technology. See the specification for conditions of use and distribution. +.LP +.\" end of man page + diff --git a/mod/pub.mod/libpng.mod/png.c b/mod/pub.mod/libpng.mod/png.c new file mode 100644 index 0000000..1118e3c --- /dev/null +++ b/mod/pub.mod/libpng.mod/png.c @@ -0,0 +1,847 @@ + +/* png.c - location for general purpose libpng functions + * + * Last changed in libpng 1.2.9 April 14, 2006 + * For conditions of distribution and use, see copyright notice in png.h + * Copyright (c) 1998-2006 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + */ + +#define PNG_INTERNAL +#define PNG_NO_EXTERN +#include "png.h" + +/* Generate a compiler error if there is an old png.h in the search path. */ +typedef version_1_2_12 Your_png_h_is_not_version_1_2_12; + +/* Version information for C files. This had better match the version + * string defined in png.h. */ + +#ifdef PNG_USE_GLOBAL_ARRAYS +/* png_libpng_ver was changed to a function in version 1.0.5c */ +const char png_libpng_ver[18] = PNG_LIBPNG_VER_STRING; + +#ifdef PNG_READ_SUPPORTED + +/* png_sig was changed to a function in version 1.0.5c */ +/* Place to hold the signature string for a PNG file. */ +const png_byte FARDATA png_sig[8] = {137, 80, 78, 71, 13, 10, 26, 10}; +#endif /* PNG_READ_SUPPORTED */ + +/* Invoke global declarations for constant strings for known chunk types */ +PNG_IHDR; +PNG_IDAT; +PNG_IEND; +PNG_PLTE; +PNG_bKGD; +PNG_cHRM; +PNG_gAMA; +PNG_hIST; +PNG_iCCP; +PNG_iTXt; +PNG_oFFs; +PNG_pCAL; +PNG_sCAL; +PNG_pHYs; +PNG_sBIT; +PNG_sPLT; +PNG_sRGB; +PNG_tEXt; +PNG_tIME; +PNG_tRNS; +PNG_zTXt; + +#ifdef PNG_READ_SUPPORTED +/* arrays to facilitate easy interlacing - use pass (0 - 6) as index */ + +/* start of interlace block */ +const int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; + +/* offset to next interlace block */ +const int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; + +/* start of interlace block in the y direction */ +const int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1}; + +/* offset to next interlace block in the y direction */ +const int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2}; + +/* width of interlace block (used in assembler routines only) */ +#ifdef PNG_HAVE_ASSEMBLER_COMBINE_ROW +const int FARDATA png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; +#endif + +/* Height of interlace block. This is not currently used - if you need + * it, uncomment it here and in png.h +const int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1}; +*/ + +/* Mask to determine which pixels are valid in a pass */ +const int FARDATA png_pass_mask[] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff}; + +/* Mask to determine which pixels to overwrite while displaying */ +const int FARDATA png_pass_dsp_mask[] + = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff}; + +#endif /* PNG_READ_SUPPORTED */ +#endif /* PNG_USE_GLOBAL_ARRAYS */ + +/* Tells libpng that we have already handled the first "num_bytes" bytes + * of the PNG file signature. If the PNG data is embedded into another + * stream we can set num_bytes = 8 so that libpng will not attempt to read + * or write any of the magic bytes before it starts on the IHDR. + */ + +#ifdef PNG_READ_SUPPORTED +void PNGAPI +png_set_sig_bytes(png_structp png_ptr, int num_bytes) +{ + png_debug(1, "in png_set_sig_bytes\n"); + if (num_bytes > 8) + png_error(png_ptr, "Too many bytes for PNG signature."); + + png_ptr->sig_bytes = (png_byte)(num_bytes < 0 ? 0 : num_bytes); +} + +/* Checks whether the supplied bytes match the PNG signature. We allow + * checking less than the full 8-byte signature so that those apps that + * already read the first few bytes of a file to determine the file type + * can simply check the remaining bytes for extra assurance. Returns + * an integer less than, equal to, or greater than zero if sig is found, + * respectively, to be less than, to match, or be greater than the correct + * PNG signature (this is the same behaviour as strcmp, memcmp, etc). + */ +int PNGAPI +png_sig_cmp(png_bytep sig, png_size_t start, png_size_t num_to_check) +{ + png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10}; + if (num_to_check > 8) + num_to_check = 8; + else if (num_to_check < 1) + return (-1); + + if (start > 7) + return (-1); + + if (start + num_to_check > 8) + num_to_check = 8 - start; + + return ((int)(png_memcmp(&sig[start], &png_signature[start], num_to_check))); +} + +#if defined(PNG_1_0_X) || defined(PNG_1_2_X) +/* (Obsolete) function to check signature bytes. It does not allow one + * to check a partial signature. This function might be removed in the + * future - use png_sig_cmp(). Returns true (nonzero) if the file is a PNG. + */ +int PNGAPI +png_check_sig(png_bytep sig, int num) +{ + return ((int)!png_sig_cmp(sig, (png_size_t)0, (png_size_t)num)); +} +#endif +#endif /* PNG_READ_SUPPORTED */ + +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) +/* Function to allocate memory for zlib and clear it to 0. */ +#ifdef PNG_1_0_X +voidpf PNGAPI +#else +voidpf /* private */ +#endif +png_zalloc(voidpf png_ptr, uInt items, uInt size) +{ + png_voidp ptr; + png_structp p=png_ptr; + png_uint_32 save_flags=p->flags; + png_uint_32 num_bytes; + + if (items > PNG_UINT_32_MAX/size) + { + png_warning (png_ptr, "Potential overflow in png_zalloc()"); + return (NULL); + } + num_bytes = (png_uint_32)items * size; + + p->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK; + ptr = (png_voidp)png_malloc((png_structp)png_ptr, num_bytes); + p->flags=save_flags; + +#if defined(PNG_1_0_X) && !defined(PNG_NO_ZALLOC_ZERO) + if (ptr == NULL) + return ((voidpf)ptr); + + if (num_bytes > (png_uint_32)0x8000L) + { + png_memset(ptr, 0, (png_size_t)0x8000L); + png_memset((png_bytep)ptr + (png_size_t)0x8000L, 0, + (png_size_t)(num_bytes - (png_uint_32)0x8000L)); + } + else + { + png_memset(ptr, 0, (png_size_t)num_bytes); + } +#endif + return ((voidpf)ptr); +} + +/* function to free memory for zlib */ +#ifdef PNG_1_0_X +void PNGAPI +#else +void /* private */ +#endif +png_zfree(voidpf png_ptr, voidpf ptr) +{ + png_free((png_structp)png_ptr, (png_voidp)ptr); +} + +/* Reset the CRC variable to 32 bits of 1's. Care must be taken + * in case CRC is > 32 bits to leave the top bits 0. + */ +void /* PRIVATE */ +png_reset_crc(png_structp png_ptr) +{ + png_ptr->crc = crc32(0, Z_NULL, 0); +} + +/* Calculate the CRC over a section of data. We can only pass as + * much data to this routine as the largest single buffer size. We + * also check that this data will actually be used before going to the + * trouble of calculating it. + */ +void /* PRIVATE */ +png_calculate_crc(png_structp png_ptr, png_bytep ptr, png_size_t length) +{ + int need_crc = 1; + + if (png_ptr->chunk_name[0] & 0x20) /* ancillary */ + { + if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) == + (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN)) + need_crc = 0; + } + else /* critical */ + { + if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) + need_crc = 0; + } + + if (need_crc) + png_ptr->crc = crc32(png_ptr->crc, ptr, (uInt)length); +} + +/* Allocate the memory for an info_struct for the application. We don't + * really need the png_ptr, but it could potentially be useful in the + * future. This should be used in favour of malloc(png_sizeof(png_info)) + * and png_info_init() so that applications that want to use a shared + * libpng don't have to be recompiled if png_info changes size. + */ +png_infop PNGAPI +png_create_info_struct(png_structp png_ptr) +{ + png_infop info_ptr; + + png_debug(1, "in png_create_info_struct\n"); + if(png_ptr == NULL) return (NULL); +#ifdef PNG_USER_MEM_SUPPORTED + info_ptr = (png_infop)png_create_struct_2(PNG_STRUCT_INFO, + png_ptr->malloc_fn, png_ptr->mem_ptr); +#else + info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO); +#endif + if (info_ptr != NULL) + png_info_init_3(&info_ptr, png_sizeof(png_info)); + + return (info_ptr); +} + +/* This function frees the memory associated with a single info struct. + * Normally, one would use either png_destroy_read_struct() or + * png_destroy_write_struct() to free an info struct, but this may be + * useful for some applications. + */ +void PNGAPI +png_destroy_info_struct(png_structp png_ptr, png_infopp info_ptr_ptr) +{ + png_infop info_ptr = NULL; + + png_debug(1, "in png_destroy_info_struct\n"); + if (info_ptr_ptr != NULL) + info_ptr = *info_ptr_ptr; + + if (info_ptr != NULL) + { + png_info_destroy(png_ptr, info_ptr); + +#ifdef PNG_USER_MEM_SUPPORTED + png_destroy_struct_2((png_voidp)info_ptr, png_ptr->free_fn, + png_ptr->mem_ptr); +#else + png_destroy_struct((png_voidp)info_ptr); +#endif + *info_ptr_ptr = NULL; + } +} + +/* Initialize the info structure. This is now an internal function (0.89) + * and applications using it are urged to use png_create_info_struct() + * instead. + */ +#if defined(PNG_1_0_X) || defined(PNG_1_2_X) +#undef png_info_init +void PNGAPI +png_info_init(png_infop info_ptr) +{ + /* We only come here via pre-1.0.12-compiled applications */ + png_info_init_3(&info_ptr, 0); +} +#endif + +void PNGAPI +png_info_init_3(png_infopp ptr_ptr, png_size_t png_info_struct_size) +{ + png_infop info_ptr = *ptr_ptr; + + png_debug(1, "in png_info_init_3\n"); + + if(png_sizeof(png_info) > png_info_struct_size) + { + png_destroy_struct(info_ptr); + info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO); + *ptr_ptr = info_ptr; + } + + /* set everything to 0 */ + png_memset(info_ptr, 0, png_sizeof (png_info)); +} + +#ifdef PNG_FREE_ME_SUPPORTED +void PNGAPI +png_data_freer(png_structp png_ptr, png_infop info_ptr, + int freer, png_uint_32 mask) +{ + png_debug(1, "in png_data_freer\n"); + if (png_ptr == NULL || info_ptr == NULL) + return; + if(freer == PNG_DESTROY_WILL_FREE_DATA) + info_ptr->free_me |= mask; + else if(freer == PNG_USER_WILL_FREE_DATA) + info_ptr->free_me &= ~mask; + else + png_warning(png_ptr, + "Unknown freer parameter in png_data_freer."); +} +#endif + +void PNGAPI +png_free_data(png_structp png_ptr, png_infop info_ptr, png_uint_32 mask, + int num) +{ + png_debug(1, "in png_free_data\n"); + if (png_ptr == NULL || info_ptr == NULL) + return; + +#if defined(PNG_TEXT_SUPPORTED) +/* free text item num or (if num == -1) all text items */ +#ifdef PNG_FREE_ME_SUPPORTED +if ((mask & PNG_FREE_TEXT) & info_ptr->free_me) +#else +if (mask & PNG_FREE_TEXT) +#endif +{ + if (num != -1) + { + if (info_ptr->text && info_ptr->text[num].key) + { + png_free(png_ptr, info_ptr->text[num].key); + info_ptr->text[num].key = NULL; + } + } + else + { + int i; + for (i = 0; i < info_ptr->num_text; i++) + png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, i); + png_free(png_ptr, info_ptr->text); + info_ptr->text = NULL; + info_ptr->num_text=0; + } +} +#endif + +#if defined(PNG_tRNS_SUPPORTED) +/* free any tRNS entry */ +#ifdef PNG_FREE_ME_SUPPORTED +if ((mask & PNG_FREE_TRNS) & info_ptr->free_me) +#else +if ((mask & PNG_FREE_TRNS) && (png_ptr->flags & PNG_FLAG_FREE_TRNS)) +#endif +{ + png_free(png_ptr, info_ptr->trans); + info_ptr->valid &= ~PNG_INFO_tRNS; +#ifndef PNG_FREE_ME_SUPPORTED + png_ptr->flags &= ~PNG_FLAG_FREE_TRNS; +#endif + info_ptr->trans = NULL; +} +#endif + +#if defined(PNG_sCAL_SUPPORTED) +/* free any sCAL entry */ +#ifdef PNG_FREE_ME_SUPPORTED +if ((mask & PNG_FREE_SCAL) & info_ptr->free_me) +#else +if (mask & PNG_FREE_SCAL) +#endif +{ +#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED) + png_free(png_ptr, info_ptr->scal_s_width); + png_free(png_ptr, info_ptr->scal_s_height); + info_ptr->scal_s_width = NULL; + info_ptr->scal_s_height = NULL; +#endif + info_ptr->valid &= ~PNG_INFO_sCAL; +} +#endif + +#if defined(PNG_pCAL_SUPPORTED) +/* free any pCAL entry */ +#ifdef PNG_FREE_ME_SUPPORTED +if ((mask & PNG_FREE_PCAL) & info_ptr->free_me) +#else +if (mask & PNG_FREE_PCAL) +#endif +{ + png_free(png_ptr, info_ptr->pcal_purpose); + png_free(png_ptr, info_ptr->pcal_units); + info_ptr->pcal_purpose = NULL; + info_ptr->pcal_units = NULL; + if (info_ptr->pcal_params != NULL) + { + int i; + for (i = 0; i < (int)info_ptr->pcal_nparams; i++) + { + png_free(png_ptr, info_ptr->pcal_params[i]); + info_ptr->pcal_params[i]=NULL; + } + png_free(png_ptr, info_ptr->pcal_params); + info_ptr->pcal_params = NULL; + } + info_ptr->valid &= ~PNG_INFO_pCAL; +} +#endif + +#if defined(PNG_iCCP_SUPPORTED) +/* free any iCCP entry */ +#ifdef PNG_FREE_ME_SUPPORTED +if ((mask & PNG_FREE_ICCP) & info_ptr->free_me) +#else +if (mask & PNG_FREE_ICCP) +#endif +{ + png_free(png_ptr, info_ptr->iccp_name); + png_free(png_ptr, info_ptr->iccp_profile); + info_ptr->iccp_name = NULL; + info_ptr->iccp_profile = NULL; + info_ptr->valid &= ~PNG_INFO_iCCP; +} +#endif + +#if defined(PNG_sPLT_SUPPORTED) +/* free a given sPLT entry, or (if num == -1) all sPLT entries */ +#ifdef PNG_FREE_ME_SUPPORTED +if ((mask & PNG_FREE_SPLT) & info_ptr->free_me) +#else +if (mask & PNG_FREE_SPLT) +#endif +{ + if (num != -1) + { + if(info_ptr->splt_palettes) + { + png_free(png_ptr, info_ptr->splt_palettes[num].name); + png_free(png_ptr, info_ptr->splt_palettes[num].entries); + info_ptr->splt_palettes[num].name = NULL; + info_ptr->splt_palettes[num].entries = NULL; + } + } + else + { + if(info_ptr->splt_palettes_num) + { + int i; + for (i = 0; i < (int)info_ptr->splt_palettes_num; i++) + png_free_data(png_ptr, info_ptr, PNG_FREE_SPLT, i); + + png_free(png_ptr, info_ptr->splt_palettes); + info_ptr->splt_palettes = NULL; + info_ptr->splt_palettes_num = 0; + } + info_ptr->valid &= ~PNG_INFO_sPLT; + } +} +#endif + +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) +#ifdef PNG_FREE_ME_SUPPORTED +if ((mask & PNG_FREE_UNKN) & info_ptr->free_me) +#else +if (mask & PNG_FREE_UNKN) +#endif +{ + if (num != -1) + { + if(info_ptr->unknown_chunks) + { + png_free(png_ptr, info_ptr->unknown_chunks[num].data); + info_ptr->unknown_chunks[num].data = NULL; + } + } + else + { + int i; + + if(info_ptr->unknown_chunks_num) + { + for (i = 0; i < (int)info_ptr->unknown_chunks_num; i++) + png_free_data(png_ptr, info_ptr, PNG_FREE_UNKN, i); + + png_free(png_ptr, info_ptr->unknown_chunks); + info_ptr->unknown_chunks = NULL; + info_ptr->unknown_chunks_num = 0; + } + } +} +#endif + +#if defined(PNG_hIST_SUPPORTED) +/* free any hIST entry */ +#ifdef PNG_FREE_ME_SUPPORTED +if ((mask & PNG_FREE_HIST) & info_ptr->free_me) +#else +if ((mask & PNG_FREE_HIST) && (png_ptr->flags & PNG_FLAG_FREE_HIST)) +#endif +{ + png_free(png_ptr, info_ptr->hist); + info_ptr->hist = NULL; + info_ptr->valid &= ~PNG_INFO_hIST; +#ifndef PNG_FREE_ME_SUPPORTED + png_ptr->flags &= ~PNG_FLAG_FREE_HIST; +#endif +} +#endif + +/* free any PLTE entry that was internally allocated */ +#ifdef PNG_FREE_ME_SUPPORTED +if ((mask & PNG_FREE_PLTE) & info_ptr->free_me) +#else +if ((mask & PNG_FREE_PLTE) && (png_ptr->flags & PNG_FLAG_FREE_PLTE)) +#endif +{ + png_zfree(png_ptr, info_ptr->palette); + info_ptr->palette = NULL; + info_ptr->valid &= ~PNG_INFO_PLTE; +#ifndef PNG_FREE_ME_SUPPORTED + png_ptr->flags &= ~PNG_FLAG_FREE_PLTE; +#endif + info_ptr->num_palette = 0; +} + +#if defined(PNG_INFO_IMAGE_SUPPORTED) +/* free any image bits attached to the info structure */ +#ifdef PNG_FREE_ME_SUPPORTED +if ((mask & PNG_FREE_ROWS) & info_ptr->free_me) +#else +if (mask & PNG_FREE_ROWS) +#endif +{ + if(info_ptr->row_pointers) + { + int row; + for (row = 0; row < (int)info_ptr->height; row++) + { + png_free(png_ptr, info_ptr->row_pointers[row]); + info_ptr->row_pointers[row]=NULL; + } + png_free(png_ptr, info_ptr->row_pointers); + info_ptr->row_pointers=NULL; + } + info_ptr->valid &= ~PNG_INFO_IDAT; +} +#endif + +#ifdef PNG_FREE_ME_SUPPORTED + if(num == -1) + info_ptr->free_me &= ~mask; + else + info_ptr->free_me &= ~(mask & ~PNG_FREE_MUL); +#endif +} + +/* This is an internal routine to free any memory that the info struct is + * pointing to before re-using it or freeing the struct itself. Recall + * that png_free() checks for NULL pointers for us. + */ +void /* PRIVATE */ +png_info_destroy(png_structp png_ptr, png_infop info_ptr) +{ + png_debug(1, "in png_info_destroy\n"); + + png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1); + +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) + if (png_ptr->num_chunk_list) + { + png_free(png_ptr, png_ptr->chunk_list); + png_ptr->chunk_list=NULL; + png_ptr->num_chunk_list=0; + } +#endif + + png_info_init_3(&info_ptr, png_sizeof(png_info)); +} +#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */ + +/* This function returns a pointer to the io_ptr associated with the user + * functions. The application should free any memory associated with this + * pointer before png_write_destroy() or png_read_destroy() are called. + */ +png_voidp PNGAPI +png_get_io_ptr(png_structp png_ptr) +{ + return (png_ptr->io_ptr); +} + +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) +#if !defined(PNG_NO_STDIO) +/* Initialize the default input/output functions for the PNG file. If you + * use your own read or write routines, you can call either png_set_read_fn() + * or png_set_write_fn() instead of png_init_io(). If you have defined + * PNG_NO_STDIO, you must use a function of your own because "FILE *" isn't + * necessarily available. + */ +void PNGAPI +png_init_io(png_structp png_ptr, png_FILE_p fp) +{ + png_debug(1, "in png_init_io\n"); + png_ptr->io_ptr = (png_voidp)fp; +} +#endif + +#if defined(PNG_TIME_RFC1123_SUPPORTED) +/* Convert the supplied time into an RFC 1123 string suitable for use in + * a "Creation Time" or other text-based time string. + */ +png_charp PNGAPI +png_convert_to_rfc1123(png_structp png_ptr, png_timep ptime) +{ + static PNG_CONST char short_months[12][4] = + {"Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; + + if (png_ptr->time_buffer == NULL) + { + png_ptr->time_buffer = (png_charp)png_malloc(png_ptr, (png_uint_32)(29* + png_sizeof(char))); + } + +#if defined(_WIN32_WCE) + { + wchar_t time_buf[29]; + wsprintf(time_buf, TEXT("%d %S %d %02d:%02d:%02d +0000"), + ptime->day % 32, short_months[(ptime->month - 1) % 12], + ptime->year, ptime->hour % 24, ptime->minute % 60, + ptime->second % 61); + WideCharToMultiByte(CP_ACP, 0, time_buf, -1, png_ptr->time_buffer, 29, + NULL, NULL); + } +#else +#ifdef USE_FAR_KEYWORD + { + char near_time_buf[29]; + sprintf(near_time_buf, "%d %s %d %02d:%02d:%02d +0000", + ptime->day % 32, short_months[(ptime->month - 1) % 12], + ptime->year, ptime->hour % 24, ptime->minute % 60, + ptime->second % 61); + png_memcpy(png_ptr->time_buffer, near_time_buf, + 29*png_sizeof(char)); + } +#else + sprintf(png_ptr->time_buffer, "%d %s %d %02d:%02d:%02d +0000", + ptime->day % 32, short_months[(ptime->month - 1) % 12], + ptime->year, ptime->hour % 24, ptime->minute % 60, + ptime->second % 61); +#endif +#endif /* _WIN32_WCE */ + return ((png_charp)png_ptr->time_buffer); +} +#endif /* PNG_TIME_RFC1123_SUPPORTED */ + +#if 0 +/* Signature string for a PNG file. */ +png_bytep PNGAPI +png_sig_bytes(void) +{ + return ((png_bytep)"\211\120\116\107\015\012\032\012"); +} +#endif +#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */ + +png_charp PNGAPI +png_get_copyright(png_structp png_ptr) +{ + if (&png_ptr != NULL) /* silence compiler warning about unused png_ptr */ + return ((png_charp) "\n libpng version 1.2.12 - June 27, 2006\n\ + Copyright (c) 1998-2006 Glenn Randers-Pehrson\n\ + Copyright (c) 1996-1997 Andreas Dilger\n\ + Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.\n"); + return ((png_charp) ""); +} + +/* The following return the library version as a short string in the + * format 1.0.0 through 99.99.99zz. To get the version of *.h files + * used with your application, print out PNG_LIBPNG_VER_STRING, which + * is defined in png.h. + * Note: now there is no difference between png_get_libpng_ver() and + * png_get_header_ver(). Due to the version_nn_nn_nn typedef guard, + * it is guaranteed that png.c uses the correct version of png.h. + */ +png_charp PNGAPI +png_get_libpng_ver(png_structp png_ptr) +{ + /* Version of *.c files used when building libpng */ + if (&png_ptr != NULL) /* silence compiler warning about unused png_ptr */ + return ((png_charp) PNG_LIBPNG_VER_STRING); + return ((png_charp) ""); +} + +png_charp PNGAPI +png_get_header_ver(png_structp png_ptr) +{ + /* Version of *.h files used when building libpng */ + if (&png_ptr != NULL) /* silence compiler warning about unused png_ptr */ + return ((png_charp) PNG_LIBPNG_VER_STRING); + return ((png_charp) ""); +} + +png_charp PNGAPI +png_get_header_version(png_structp png_ptr) +{ + /* Returns longer string containing both version and date */ + if (&png_ptr != NULL) /* silence compiler warning about unused png_ptr */ + return ((png_charp) PNG_HEADER_VERSION_STRING); + return ((png_charp) ""); +} + +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED +int PNGAPI +png_handle_as_unknown(png_structp png_ptr, png_bytep chunk_name) +{ + /* check chunk_name and return "keep" value if it's on the list, else 0 */ + int i; + png_bytep p; + if((png_ptr == NULL && chunk_name == NULL) || png_ptr->num_chunk_list<=0) + return 0; + p=png_ptr->chunk_list+png_ptr->num_chunk_list*5-5; + for (i = png_ptr->num_chunk_list; i; i--, p-=5) + if (!png_memcmp(chunk_name, p, 4)) + return ((int)*(p+4)); + return 0; +} +#endif + +/* This function, added to libpng-1.0.6g, is untested. */ +int PNGAPI +png_reset_zstream(png_structp png_ptr) +{ + return (inflateReset(&png_ptr->zstream)); +} +#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */ + +/* This function was added to libpng-1.0.7 */ +png_uint_32 PNGAPI +png_access_version_number(void) +{ + /* Version of *.c files used when building libpng */ + return((png_uint_32) PNG_LIBPNG_VER); +} + + +#if defined(PNG_READ_SUPPORTED) +#if !defined(PNG_1_0_X) +#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) + /* GRR: could add this: && defined(PNG_MMX_CODE_SUPPORTED) */ +/* this INTERNAL function was added to libpng 1.2.0 */ +void /* PRIVATE */ +png_init_mmx_flags (png_structp png_ptr) +{ + png_ptr->mmx_rowbytes_threshold = 0; + png_ptr->mmx_bitdepth_threshold = 0; + +# if (defined(PNG_USE_PNGVCRD) || defined(PNG_USE_PNGGCCRD)) + + png_ptr->asm_flags |= PNG_ASM_FLAG_MMX_SUPPORT_COMPILED; + + if (png_mmx_support() > 0) { + png_ptr->asm_flags |= PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU +# ifdef PNG_HAVE_ASSEMBLER_COMBINE_ROW + | PNG_ASM_FLAG_MMX_READ_COMBINE_ROW +# endif +# ifdef PNG_HAVE_ASSEMBLER_READ_INTERLACE + | PNG_ASM_FLAG_MMX_READ_INTERLACE +# endif +# ifndef PNG_HAVE_ASSEMBLER_READ_FILTER_ROW + ; +# else + | PNG_ASM_FLAG_MMX_READ_FILTER_SUB + | PNG_ASM_FLAG_MMX_READ_FILTER_UP + | PNG_ASM_FLAG_MMX_READ_FILTER_AVG + | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ; + + png_ptr->mmx_rowbytes_threshold = PNG_MMX_ROWBYTES_THRESHOLD_DEFAULT; + png_ptr->mmx_bitdepth_threshold = PNG_MMX_BITDEPTH_THRESHOLD_DEFAULT; +# endif + } else { + png_ptr->asm_flags &= ~( PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU + | PNG_MMX_READ_FLAGS + | PNG_MMX_WRITE_FLAGS ); + } + +# else /* !((PNGVCRD || PNGGCCRD) && PNG_ASSEMBLER_CODE_SUPPORTED)) */ + + /* clear all MMX flags; no support is compiled in */ + png_ptr->asm_flags &= ~( PNG_MMX_FLAGS ); + +# endif /* ?(PNGVCRD || PNGGCCRD) */ +} + +#endif /* !(PNG_ASSEMBLER_CODE_SUPPORTED) */ + +/* this function was added to libpng 1.2.0 */ +#if !defined(PNG_USE_PNGGCCRD) && \ + !(defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_USE_PNGVCRD)) +int PNGAPI +png_mmx_support(void) +{ + return -1; +} +#endif +#endif /* PNG_1_0_X */ +#endif /* PNG_READ_SUPPORTED */ + +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) +#ifdef PNG_SIZE_T +/* Added at libpng version 1.2.6 */ + PNG_EXTERN png_size_t PNGAPI png_convert_size PNGARG((size_t size)); +png_size_t PNGAPI +png_convert_size(size_t size) +{ + if (size > (png_size_t)-1) + PNG_ABORT(); /* We haven't got access to png_ptr, so no png_error() */ + return ((png_size_t)size); +} +#endif /* PNG_SIZE_T */ +#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */ diff --git a/mod/pub.mod/libpng.mod/png.h b/mod/pub.mod/libpng.mod/png.h new file mode 100644 index 0000000..fd7ea88 --- /dev/null +++ b/mod/pub.mod/libpng.mod/png.h @@ -0,0 +1,3481 @@ + +/* png.h - header file for PNG reference library + * + * libpng version 1.2.12 - June 27, 2006 + * Copyright (c) 1998-2006 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * + * Authors and maintainers: + * libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat + * libpng versions 0.89c, June 1996, through 0.96, May 1997: Andreas Dilger + * libpng versions 0.97, January 1998, through 1.2.12 - June 27, 2006: Glenn + * See also "Contributing Authors", below. + * + * Note about libpng version numbers: + * + * Due to various miscommunications, unforeseen code incompatibilities + * and occasional factors outside the authors' control, version numbering + * on the library has not always been consistent and straightforward. + * The following table summarizes matters since version 0.89c, which was + * the first widely used release: + * + * source png.h png.h shared-lib + * version string int version + * ------- ------ ----- ---------- + * 0.89c "1.0 beta 3" 0.89 89 1.0.89 + * 0.90 "1.0 beta 4" 0.90 90 0.90 [should have been 2.0.90] + * 0.95 "1.0 beta 5" 0.95 95 0.95 [should have been 2.0.95] + * 0.96 "1.0 beta 6" 0.96 96 0.96 [should have been 2.0.96] + * 0.97b "1.00.97 beta 7" 1.00.97 97 1.0.1 [should have been 2.0.97] + * 0.97c 0.97 97 2.0.97 + * 0.98 0.98 98 2.0.98 + * 0.99 0.99 98 2.0.99 + * 0.99a-m 0.99 99 2.0.99 + * 1.00 1.00 100 2.1.0 [100 should be 10000] + * 1.0.0 (from here on, the 100 2.1.0 [100 should be 10000] + * 1.0.1 png.h string is 10001 2.1.0 + * 1.0.1a-e identical to the 10002 from here on, the shared library + * 1.0.2 source version) 10002 is 2.V where V is the source code + * 1.0.2a-b 10003 version, except as noted. + * 1.0.3 10003 + * 1.0.3a-d 10004 + * 1.0.4 10004 + * 1.0.4a-f 10005 + * 1.0.5 (+ 2 patches) 10005 + * 1.0.5a-d 10006 + * 1.0.5e-r 10100 (not source compatible) + * 1.0.5s-v 10006 (not binary compatible) + * 1.0.6 (+ 3 patches) 10006 (still binary incompatible) + * 1.0.6d-f 10007 (still binary incompatible) + * 1.0.6g 10007 + * 1.0.6h 10007 10.6h (testing xy.z so-numbering) + * 1.0.6i 10007 10.6i + * 1.0.6j 10007 2.1.0.6j (incompatible with 1.0.0) + * 1.0.7beta11-14 DLLNUM 10007 2.1.0.7beta11-14 (binary compatible) + * 1.0.7beta15-18 1 10007 2.1.0.7beta15-18 (binary compatible) + * 1.0.7rc1-2 1 10007 2.1.0.7rc1-2 (binary compatible) + * 1.0.7 1 10007 (still compatible) + * 1.0.8beta1-4 1 10008 2.1.0.8beta1-4 + * 1.0.8rc1 1 10008 2.1.0.8rc1 + * 1.0.8 1 10008 2.1.0.8 + * 1.0.9beta1-6 1 10009 2.1.0.9beta1-6 + * 1.0.9rc1 1 10009 2.1.0.9rc1 + * 1.0.9beta7-10 1 10009 2.1.0.9beta7-10 + * 1.0.9rc2 1 10009 2.1.0.9rc2 + * 1.0.9 1 10009 2.1.0.9 + * 1.0.10beta1 1 10010 2.1.0.10beta1 + * 1.0.10rc1 1 10010 2.1.0.10rc1 + * 1.0.10 1 10010 2.1.0.10 + * 1.0.11beta1-3 1 10011 2.1.0.11beta1-3 + * 1.0.11rc1 1 10011 2.1.0.11rc1 + * 1.0.11 1 10011 2.1.0.11 + * 1.0.12beta1-2 2 10012 2.1.0.12beta1-2 + * 1.0.12rc1 2 10012 2.1.0.12rc1 + * 1.0.12 2 10012 2.1.0.12 + * 1.1.0a-f - 10100 2.1.1.0a-f (branch abandoned) + * 1.2.0beta1-2 2 10200 2.1.2.0beta1-2 + * 1.2.0beta3-5 3 10200 3.1.2.0beta3-5 + * 1.2.0rc1 3 10200 3.1.2.0rc1 + * 1.2.0 3 10200 3.1.2.0 + * 1.2.1beta1-4 3 10201 3.1.2.1beta1-4 + * 1.2.1rc1-2 3 10201 3.1.2.1rc1-2 + * 1.2.1 3 10201 3.1.2.1 + * 1.2.2beta1-6 12 10202 12.so.0.1.2.2beta1-6 + * 1.0.13beta1 10 10013 10.so.0.1.0.13beta1 + * 1.0.13rc1 10 10013 10.so.0.1.0.13rc1 + * 1.2.2rc1 12 10202 12.so.0.1.2.2rc1 + * 1.0.13 10 10013 10.so.0.1.0.13 + * 1.2.2 12 10202 12.so.0.1.2.2 + * 1.2.3rc1-6 12 10203 12.so.0.1.2.3rc1-6 + * 1.2.3 12 10203 12.so.0.1.2.3 + * 1.2.4beta1-3 13 10204 12.so.0.1.2.4beta1-3 + * 1.0.14rc1 13 10014 10.so.0.1.0.14rc1 + * 1.2.4rc1 13 10204 12.so.0.1.2.4rc1 + * 1.0.14 10 10014 10.so.0.1.0.14 + * 1.2.4 13 10204 12.so.0.1.2.4 + * 1.2.5beta1-2 13 10205 12.so.0.1.2.5beta1-2 + * 1.0.15rc1-3 10 10015 10.so.0.1.0.15rc1-3 + * 1.2.5rc1-3 13 10205 12.so.0.1.2.5rc1-3 + * 1.0.15 10 10015 10.so.0.1.0.15 + * 1.2.5 13 10205 12.so.0.1.2.5 + * 1.2.6beta1-4 13 10206 12.so.0.1.2.6beta1-4 + * 1.0.16 10 10016 10.so.0.1.0.16 + * 1.2.6 13 10206 12.so.0.1.2.6 + * 1.2.7beta1-2 13 10207 12.so.0.1.2.7beta1-2 + * 1.0.17rc1 10 10017 10.so.0.1.0.17rc1 + * 1.2.7rc1 13 10207 12.so.0.1.2.7rc1 + * 1.0.17 10 10017 10.so.0.1.0.17 + * 1.2.7 13 10207 12.so.0.1.2.7 + * 1.2.8beta1-5 13 10208 12.so.0.1.2.8beta1-5 + * 1.0.18rc1-5 10 10018 10.so.0.1.0.18rc1-5 + * 1.2.8rc1-5 13 10208 12.so.0.1.2.8rc1-5 + * 1.0.18 10 10018 10.so.0.1.0.18 + * 1.2.8 13 10208 12.so.0.1.2.8 + * 1.2.9beta1-3 13 10209 12.so.0.1.2.9beta1-3 + * 1.2.9beta4-11 13 10209 12.so.0.9[.0] + * 1.2.9rc1 13 10209 12.so.0.9[.0] + * 1.2.9 13 10209 12.so.0.9[.0] + * 1.2.10beta1-8 13 10210 12.so.0.10[.0] + * 1.2.10rc1-3 13 10210 12.so.0.10[.0] + * 1.2.10 13 10210 12.so.0.10[.0] + * 1.2.11beta1-4 13 10211 12.so.0.11[.0] + * 1.0.19rc1-5 10 10019 10.so.0.19[.0] + * 1.2.11rc1-5 13 10211 12.so.0.11[.0] + * 1.0.19 10 10019 10.so.0.19[.0] + * 1.2.11 13 10211 12.so.0.11[.0] + * 1.0.20 10 10020 10.so.0.20[.0] + * 1.2.12 13 10212 12.so.0.12[.0] + * + * Henceforth the source version will match the shared-library major + * and minor numbers; the shared-library major version number will be + * used for changes in backward compatibility, as it is intended. The + * PNG_LIBPNG_VER macro, which is not used within libpng but is available + * for applications, is an unsigned integer of the form xyyzz corresponding + * to the source version x.y.z (leading zeros in y and z). Beta versions + * were given the previous public release number plus a letter, until + * version 1.0.6j; from then on they were given the upcoming public + * release number plus "betaNN" or "rcN". + * + * Binary incompatibility exists only when applications make direct access + * to the info_ptr or png_ptr members through png.h, and the compiled + * application is loaded with a different version of the library. + * + * DLLNUM will change each time there are forward or backward changes + * in binary compatibility (e.g., when a new feature is added). + * + * See libpng.txt or libpng.3 for more information. The PNG specification + * is available as a W3C Recommendation and as an ISO Specification, + * <http://www.w3.org/TR/2003/REC-PNG-20031110/ + */ + +/* + * COPYRIGHT NOTICE, DISCLAIMER, and LICENSE: + * + * If you modify libpng you may insert additional notices immediately following + * this sentence. + * + * libpng versions 1.2.6, August 15, 2004, through 1.2.12, June 27, 2006, are + * Copyright (c) 2004, 2006 Glenn Randers-Pehrson, and are + * distributed according to the same disclaimer and license as libpng-1.2.5 + * with the following individual added to the list of Contributing Authors: + * + * Cosmin Truta + * + * libpng versions 1.0.7, July 1, 2000, through 1.2.5, October 3, 2002, are + * Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are + * distributed according to the same disclaimer and license as libpng-1.0.6 + * with the following individuals added to the list of Contributing Authors: + * + * Simon-Pierre Cadieux + * Eric S. Raymond + * Gilles Vollant + * + * and with the following additions to the disclaimer: + * + * There is no warranty against interference with your enjoyment of the + * library or against infringement. There is no warranty that our + * efforts or the library will fulfill any of your particular purposes + * or needs. This library is provided with all faults, and the entire + * risk of satisfactory quality, performance, accuracy, and effort is with + * the user. + * + * libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are + * Copyright (c) 1998, 1999, 2000 Glenn Randers-Pehrson, and are + * distributed according to the same disclaimer and license as libpng-0.96, + * with the following individuals added to the list of Contributing Authors: + * + * Tom Lane + * Glenn Randers-Pehrson + * Willem van Schaik + * + * libpng versions 0.89, June 1996, through 0.96, May 1997, are + * Copyright (c) 1996, 1997 Andreas Dilger + * Distributed according to the same disclaimer and license as libpng-0.88, + * with the following individuals added to the list of Contributing Authors: + * + * John Bowler + * Kevin Bracey + * Sam Bushell + * Magnus Holmgren + * Greg Roelofs + * Tom Tanner + * + * libpng versions 0.5, May 1995, through 0.88, January 1996, are + * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc. + * + * For the purposes of this copyright and license, "Contributing Authors" + * is defined as the following set of individuals: + * + * Andreas Dilger + * Dave Martindale + * Guy Eric Schalnat + * Paul Schmidt + * Tim Wegner + * + * The PNG Reference Library is supplied "AS IS". The Contributing Authors + * and Group 42, Inc. disclaim all warranties, expressed or implied, + * including, without limitation, the warranties of merchantability and of + * fitness for any purpose. The Contributing Authors and Group 42, Inc. + * assume no liability for direct, indirect, incidental, special, exemplary, + * or consequential damages, which may result from the use of the PNG + * Reference Library, even if advised of the possibility of such damage. + * + * Permission is hereby granted to use, copy, modify, and distribute this + * source code, or portions hereof, for any purpose, without fee, subject + * to the following restrictions: + * + * 1. The origin of this source code must not be misrepresented. + * + * 2. Altered versions must be plainly marked as such and + * must not be misrepresented as being the original source. + * + * 3. This Copyright notice may not be removed or altered from + * any source or altered source distribution. + * + * The Contributing Authors and Group 42, Inc. specifically permit, without + * fee, and encourage the use of this source code as a component to + * supporting the PNG file format in commercial products. If you use this + * source code in a product, acknowledgment is not required but would be + * appreciated. + */ + +/* + * A "png_get_copyright" function is available, for convenient use in "about" + * boxes and the like: + * + * printf("%s",png_get_copyright(NULL)); + * + * Also, the PNG logo (in PNG format, of course) is supplied in the + * files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31). + */ + +/* + * Libpng is OSI Certified Open Source Software. OSI Certified is a + * certification mark of the Open Source Initiative. + */ + +/* + * The contributing authors would like to thank all those who helped + * with testing, bug fixes, and patience. This wouldn't have been + * possible without all of you. + * + * Thanks to Frank J. T. Wojcik for helping with the documentation. + */ + +/* + * Y2K compliance in libpng: + * ========================= + * + * June 27, 2006 + * + * Since the PNG Development group is an ad-hoc body, we can't make + * an official declaration. + * + * This is your unofficial assurance that libpng from version 0.71 and + * upward through 1.2.12 are Y2K compliant. It is my belief that earlier + * versions were also Y2K compliant. + * + * Libpng only has three year fields. One is a 2-byte unsigned integer + * that will hold years up to 65535. The other two hold the date in text + * format, and will hold years up to 9999. + * + * The integer is + * "png_uint_16 year" in png_time_struct. + * + * The strings are + * "png_charp time_buffer" in png_struct and + * "near_time_buffer", which is a local character string in png.c. + * + * There are seven time-related functions: + * png.c: png_convert_to_rfc_1123() in png.c + * (formerly png_convert_to_rfc_1152() in error) + * png_convert_from_struct_tm() in pngwrite.c, called in pngwrite.c + * png_convert_from_time_t() in pngwrite.c + * png_get_tIME() in pngget.c + * png_handle_tIME() in pngrutil.c, called in pngread.c + * png_set_tIME() in pngset.c + * png_write_tIME() in pngwutil.c, called in pngwrite.c + * + * All handle dates properly in a Y2K environment. The + * png_convert_from_time_t() function calls gmtime() to convert from system + * clock time, which returns (year - 1900), which we properly convert to + * the full 4-digit year. There is a possibility that applications using + * libpng are not passing 4-digit years into the png_convert_to_rfc_1123() + * function, or that they are incorrectly passing only a 2-digit year + * instead of "year - 1900" into the png_convert_from_struct_tm() function, + * but this is not under our control. The libpng documentation has always + * stated that it works with 4-digit years, and the APIs have been + * documented as such. + * + * The tIME chunk itself is also Y2K compliant. It uses a 2-byte unsigned + * integer to hold the year, and can hold years as large as 65535. + * + * zlib, upon which libpng depends, is also Y2K compliant. It contains + * no date-related code. + * + * Glenn Randers-Pehrson + * libpng maintainer + * PNG Development Group + */ + +#ifndef PNG_H +#define PNG_H + +/* This is not the place to learn how to use libpng. The file libpng.txt + * describes how to use libpng, and the file example.c summarizes it + * with some code on which to build. This file is useful for looking + * at the actual function definitions and structure components. + */ + +/* Version information for png.h - this should match the version in png.c */ +#define PNG_LIBPNG_VER_STRING "1.2.12" +#define PNG_HEADER_VERSION_STRING \ + " libpng version 1.2.12 - June 27, 2006 (header)\n" + +#define PNG_LIBPNG_VER_SONUM 0 +#define PNG_LIBPNG_VER_DLLNUM 13 + +/* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */ +#define PNG_LIBPNG_VER_MAJOR 1 +#define PNG_LIBPNG_VER_MINOR 2 +#define PNG_LIBPNG_VER_RELEASE 12 +/* This should match the numeric part of the final component of + * PNG_LIBPNG_VER_STRING, omitting any leading zero: */ + +#define PNG_LIBPNG_VER_BUILD 0 + +/* Release Status */ +#define PNG_LIBPNG_BUILD_ALPHA 1 +#define PNG_LIBPNG_BUILD_BETA 2 +#define PNG_LIBPNG_BUILD_RC 3 +#define PNG_LIBPNG_BUILD_STABLE 4 +#define PNG_LIBPNG_BUILD_RELEASE_STATUS_MASK 7 + +/* Release-Specific Flags */ +#define PNG_LIBPNG_BUILD_PATCH 8 /* Can be OR'ed with + PNG_LIBPNG_BUILD_STABLE only */ +#define PNG_LIBPNG_BUILD_PRIVATE 16 /* Cannot be OR'ed with + PNG_LIBPNG_BUILD_SPECIAL */ +#define PNG_LIBPNG_BUILD_SPECIAL 32 /* Cannot be OR'ed with + PNG_LIBPNG_BUILD_PRIVATE */ + +#define PNG_LIBPNG_BUILD_BASE_TYPE PNG_LIBPNG_BUILD_STABLE + +/* Careful here. At one time, Guy wanted to use 082, but that would be octal. + * We must not include leading zeros. + * Versions 0.7 through 1.0.0 were in the range 0 to 100 here (only + * version 1.0.0 was mis-numbered 100 instead of 10000). From + * version 1.0.1 it's xxyyzz, where x=major, y=minor, z=release */ +#define PNG_LIBPNG_VER 10212 /* 1.2.12 */ + +#ifndef PNG_VERSION_INFO_ONLY +/* include the compression library's header */ +#include "zlib.h" +#endif + +/* include all user configurable info, including optional assembler routines */ +#include "pngconf.h" + +/* + * Added at libpng-1.2.8 */ +/* Ref MSDN: Private as priority over Special + * VS_FF_PRIVATEBUILD File *was not* built using standard release + * procedures. If this value is given, the StringFileInfo block must + * contain a PrivateBuild string. + * + * VS_FF_SPECIALBUILD File *was* built by the original company using + * standard release procedures but is a variation of the standard + * file of the same version number. If this value is given, the + * StringFileInfo block must contain a SpecialBuild string. + */ + +#if defined(PNG_USER_PRIVATEBUILD) +# define PNG_LIBPNG_BUILD_TYPE \ + (PNG_LIBPNG_BUILD_BASE_TYPE | PNG_LIBPNG_BUILD_PRIVATE) +#else +# if defined(PNG_LIBPNG_SPECIALBUILD) +# define PNG_LIBPNG_BUILD_TYPE \ + (PNG_LIBPNG_BUILD_BASE_TYPE | PNG_LIBPNG_BUILD_SPECIAL) +# else +# define PNG_LIBPNG_BUILD_TYPE (PNG_LIBPNG_BUILD_BASE_TYPE) +# endif +#endif + +#ifndef PNG_VERSION_INFO_ONLY + +/* Inhibit C++ name-mangling for libpng functions but not for system calls. */ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* This file is arranged in several sections. The first section contains + * structure and type definitions. The second section contains the external + * library functions, while the third has the internal library functions, + * which applications aren't expected to use directly. + */ + +#ifndef PNG_NO_TYPECAST_NULL +#define int_p_NULL (int *)NULL +#define png_bytep_NULL (png_bytep)NULL +#define png_bytepp_NULL (png_bytepp)NULL +#define png_doublep_NULL (png_doublep)NULL +#define png_error_ptr_NULL (png_error_ptr)NULL +#define png_flush_ptr_NULL (png_flush_ptr)NULL +#define png_free_ptr_NULL (png_free_ptr)NULL +#define png_infopp_NULL (png_infopp)NULL +#define png_malloc_ptr_NULL (png_malloc_ptr)NULL +#define png_read_status_ptr_NULL (png_read_status_ptr)NULL +#define png_rw_ptr_NULL (png_rw_ptr)NULL +#define png_structp_NULL (png_structp)NULL +#define png_uint_16p_NULL (png_uint_16p)NULL +#define png_voidp_NULL (png_voidp)NULL +#define png_write_status_ptr_NULL (png_write_status_ptr)NULL +#else +#define int_p_NULL NULL +#define png_bytep_NULL NULL +#define png_bytepp_NULL NULL +#define png_doublep_NULL NULL +#define png_error_ptr_NULL NULL +#define png_flush_ptr_NULL NULL +#define png_free_ptr_NULL NULL +#define png_infopp_NULL NULL +#define png_malloc_ptr_NULL NULL +#define png_read_status_ptr_NULL NULL +#define png_rw_ptr_NULL NULL +#define png_structp_NULL NULL +#define png_uint_16p_NULL NULL +#define png_voidp_NULL NULL +#define png_write_status_ptr_NULL NULL +#endif + +/* variables declared in png.c - only it needs to define PNG_NO_EXTERN */ +#if !defined(PNG_NO_EXTERN) || defined(PNG_ALWAYS_EXTERN) +/* Version information for C files, stored in png.c. This had better match + * the version above. + */ +#ifdef PNG_USE_GLOBAL_ARRAYS +PNG_EXPORT_VAR (const char) png_libpng_ver[18]; + /* need room for 99.99.99beta99z */ +#else +#define png_libpng_ver png_get_header_ver(NULL) +#endif + +#ifdef PNG_USE_GLOBAL_ARRAYS +/* This was removed in version 1.0.5c */ +/* Structures to facilitate easy interlacing. See png.c for more details */ +PNG_EXPORT_VAR (const int FARDATA) png_pass_start[7]; +PNG_EXPORT_VAR (const int FARDATA) png_pass_inc[7]; +PNG_EXPORT_VAR (const int FARDATA) png_pass_ystart[7]; +PNG_EXPORT_VAR (const int FARDATA) png_pass_yinc[7]; +PNG_EXPORT_VAR (const int FARDATA) png_pass_mask[7]; +PNG_EXPORT_VAR (const int FARDATA) png_pass_dsp_mask[7]; +#ifdef PNG_USE_PNGGCCRD +PNG_EXPORT_VAR (const int FARDATA) png_pass_width[7]; +#endif +/* This isn't currently used. If you need it, see png.c for more details. +PNG_EXPORT_VAR (const int FARDATA) png_pass_height[7]; +*/ +#endif + +#endif /* PNG_NO_EXTERN */ + +/* Three color definitions. The order of the red, green, and blue, (and the + * exact size) is not important, although the size of the fields need to + * be png_byte or png_uint_16 (as defined below). + */ +typedef struct png_color_struct +{ + png_byte red; + png_byte green; + png_byte blue; +} png_color; +typedef png_color FAR * png_colorp; +typedef png_color FAR * FAR * png_colorpp; + +typedef struct png_color_16_struct +{ + png_byte index; /* used for palette files */ + png_uint_16 red; /* for use in red green blue files */ + png_uint_16 green; + png_uint_16 blue; + png_uint_16 gray; /* for use in grayscale files */ +} png_color_16; +typedef png_color_16 FAR * png_color_16p; +typedef png_color_16 FAR * FAR * png_color_16pp; + +typedef struct png_color_8_struct +{ + png_byte red; /* for use in red green blue files */ + png_byte green; + png_byte blue; + png_byte gray; /* for use in grayscale files */ + png_byte alpha; /* for alpha channel files */ +} png_color_8; +typedef png_color_8 FAR * png_color_8p; +typedef png_color_8 FAR * FAR * png_color_8pp; + +/* + * The following two structures are used for the in-core representation + * of sPLT chunks. + */ +typedef struct png_sPLT_entry_struct +{ + png_uint_16 red; + png_uint_16 green; + png_uint_16 blue; + png_uint_16 alpha; + png_uint_16 frequency; +} png_sPLT_entry; +typedef png_sPLT_entry FAR * png_sPLT_entryp; +typedef png_sPLT_entry FAR * FAR * png_sPLT_entrypp; + +/* When the depth of the sPLT palette is 8 bits, the color and alpha samples + * occupy the LSB of their respective members, and the MSB of each member + * is zero-filled. The frequency member always occupies the full 16 bits. + */ + +typedef struct png_sPLT_struct +{ + png_charp name; /* palette name */ + png_byte depth; /* depth of palette samples */ + png_sPLT_entryp entries; /* palette entries */ + png_int_32 nentries; /* number of palette entries */ +} png_sPLT_t; +typedef png_sPLT_t FAR * png_sPLT_tp; +typedef png_sPLT_t FAR * FAR * png_sPLT_tpp; + +#ifdef PNG_TEXT_SUPPORTED +/* png_text holds the contents of a text/ztxt/itxt chunk in a PNG file, + * and whether that contents is compressed or not. The "key" field + * points to a regular zero-terminated C string. The "text", "lang", and + * "lang_key" fields can be regular C strings, empty strings, or NULL pointers. + * However, the * structure returned by png_get_text() will always contain + * regular zero-terminated C strings (possibly empty), never NULL pointers, + * so they can be safely used in printf() and other string-handling functions. + */ +typedef struct png_text_struct +{ + int compression; /* compression value: + -1: tEXt, none + 0: zTXt, deflate + 1: iTXt, none + 2: iTXt, deflate */ + png_charp key; /* keyword, 1-79 character description of "text" */ + png_charp text; /* comment, may be an empty string (ie "") + or a NULL pointer */ + png_size_t text_length; /* length of the text string */ +#ifdef PNG_iTXt_SUPPORTED + png_size_t itxt_length; /* length of the itxt string */ + png_charp lang; /* language code, 0-79 characters + or a NULL pointer */ + png_charp lang_key; /* keyword translated UTF-8 string, 0 or more + chars or a NULL pointer */ +#endif +} png_text; +typedef png_text FAR * png_textp; +typedef png_text FAR * FAR * png_textpp; +#endif + +/* Supported compression types for text in PNG files (tEXt, and zTXt). + * The values of the PNG_TEXT_COMPRESSION_ defines should NOT be changed. */ +#define PNG_TEXT_COMPRESSION_NONE_WR -3 +#define PNG_TEXT_COMPRESSION_zTXt_WR -2 +#define PNG_TEXT_COMPRESSION_NONE -1 +#define PNG_TEXT_COMPRESSION_zTXt 0 +#define PNG_ITXT_COMPRESSION_NONE 1 +#define PNG_ITXT_COMPRESSION_zTXt 2 +#define PNG_TEXT_COMPRESSION_LAST 3 /* Not a valid value */ + +/* png_time is a way to hold the time in an machine independent way. + * Two conversions are provided, both from time_t and struct tm. There + * is no portable way to convert to either of these structures, as far + * as I know. If you know of a portable way, send it to me. As a side + * note - PNG has always been Year 2000 compliant! + */ +typedef struct png_time_struct +{ + png_uint_16 year; /* full year, as in, 1995 */ + png_byte month; /* month of year, 1 - 12 */ + png_byte day; /* day of month, 1 - 31 */ + png_byte hour; /* hour of day, 0 - 23 */ + png_byte minute; /* minute of hour, 0 - 59 */ + png_byte second; /* second of minute, 0 - 60 (for leap seconds) */ +} png_time; +typedef png_time FAR * png_timep; +typedef png_time FAR * FAR * png_timepp; + +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) +/* png_unknown_chunk is a structure to hold queued chunks for which there is + * no specific support. The idea is that we can use this to queue + * up private chunks for output even though the library doesn't actually + * know about their semantics. + */ +typedef struct png_unknown_chunk_t +{ + png_byte name[5]; + png_byte *data; + png_size_t size; + + /* libpng-using applications should NOT directly modify this byte. */ + png_byte location; /* mode of operation at read time */ +} +png_unknown_chunk; +typedef png_unknown_chunk FAR * png_unknown_chunkp; +typedef png_unknown_chunk FAR * FAR * png_unknown_chunkpp; +#endif + +/* png_info is a structure that holds the information in a PNG file so + * that the application can find out the characteristics of the image. + * If you are reading the file, this structure will tell you what is + * in the PNG file. If you are writing the file, fill in the information + * you want to put into the PNG file, then call png_write_info(). + * The names chosen should be very close to the PNG specification, so + * consult that document for information about the meaning of each field. + * + * With libpng < 0.95, it was only possible to directly set and read the + * the values in the png_info_struct, which meant that the contents and + * order of the values had to remain fixed. With libpng 0.95 and later, + * however, there are now functions that abstract the contents of + * png_info_struct from the application, so this makes it easier to use + * libpng with dynamic libraries, and even makes it possible to use + * libraries that don't have all of the libpng ancillary chunk-handing + * functionality. + * + * In any case, the order of the parameters in png_info_struct should NOT + * be changed for as long as possible to keep compatibility with applications + * that use the old direct-access method with png_info_struct. + * + * The following members may have allocated storage attached that should be + * cleaned up before the structure is discarded: palette, trans, text, + * pcal_purpose, pcal_units, pcal_params, hist, iccp_name, iccp_profile, + * splt_palettes, scal_unit, row_pointers, and unknowns. By default, these + * are automatically freed when the info structure is deallocated, if they were + * allocated internally by libpng. This behavior can be changed by means + * of the png_data_freer() function. + * + * More allocation details: all the chunk-reading functions that + * change these members go through the corresponding png_set_* + * functions. A function to clear these members is available: see + * png_free_data(). The png_set_* functions do not depend on being + * able to point info structure members to any of the storage they are + * passed (they make their own copies), EXCEPT that the png_set_text + * functions use the same storage passed to them in the text_ptr or + * itxt_ptr structure argument, and the png_set_rows and png_set_unknowns + * functions do not make their own copies. + */ +typedef struct png_info_struct +{ + /* the following are necessary for every PNG file */ + png_uint_32 width; /* width of image in pixels (from IHDR) */ + png_uint_32 height; /* height of image in pixels (from IHDR) */ + png_uint_32 valid; /* valid chunk data (see PNG_INFO_ below) */ + png_uint_32 rowbytes; /* bytes needed to hold an untransformed row */ + png_colorp palette; /* array of color values (valid & PNG_INFO_PLTE) */ + png_uint_16 num_palette; /* number of color entries in "palette" (PLTE) */ + png_uint_16 num_trans; /* number of transparent palette color (tRNS) */ + png_byte bit_depth; /* 1, 2, 4, 8, or 16 bits/channel (from IHDR) */ + png_byte color_type; /* see PNG_COLOR_TYPE_ below (from IHDR) */ + /* The following three should have been named *_method not *_type */ + png_byte compression_type; /* must be PNG_COMPRESSION_TYPE_BASE (IHDR) */ + png_byte filter_type; /* must be PNG_FILTER_TYPE_BASE (from IHDR) */ + png_byte interlace_type; /* One of PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */ + + /* The following is informational only on read, and not used on writes. */ + png_byte channels; /* number of data channels per pixel (1, 2, 3, 4) */ + png_byte pixel_depth; /* number of bits per pixel */ + png_byte spare_byte; /* to align the data, and for future use */ + png_byte signature[8]; /* magic bytes read by libpng from start of file */ + + /* The rest of the data is optional. If you are reading, check the + * valid field to see if the information in these are valid. If you + * are writing, set the valid field to those chunks you want written, + * and initialize the appropriate fields below. + */ + +#if defined(PNG_gAMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED) + /* The gAMA chunk describes the gamma characteristics of the system + * on which the image was created, normally in the range [1.0, 2.5]. + * Data is valid if (valid & PNG_INFO_gAMA) is non-zero. + */ + float gamma; /* gamma value of image, if (valid & PNG_INFO_gAMA) */ +#endif + +#if defined(PNG_sRGB_SUPPORTED) + /* GR-P, 0.96a */ + /* Data valid if (valid & PNG_INFO_sRGB) non-zero. */ + png_byte srgb_intent; /* sRGB rendering intent [0, 1, 2, or 3] */ +#endif + +#if defined(PNG_TEXT_SUPPORTED) + /* The tEXt, and zTXt chunks contain human-readable textual data in + * uncompressed, compressed, and optionally compressed forms, respectively. + * The data in "text" is an array of pointers to uncompressed, + * null-terminated C strings. Each chunk has a keyword that describes the + * textual data contained in that chunk. Keywords are not required to be + * unique, and the text string may be empty. Any number of text chunks may + * be in an image. + */ + int num_text; /* number of comments read/to write */ + int max_text; /* current size of text array */ + png_textp text; /* array of comments read/to write */ +#endif /* PNG_TEXT_SUPPORTED */ + +#if defined(PNG_tIME_SUPPORTED) + /* The tIME chunk holds the last time the displayed image data was + * modified. See the png_time struct for the contents of this struct. + */ + png_time mod_time; +#endif + +#if defined(PNG_sBIT_SUPPORTED) + /* The sBIT chunk specifies the number of significant high-order bits + * in the pixel data. Values are in the range [1, bit_depth], and are + * only specified for the channels in the pixel data. The contents of + * the low-order bits is not specified. Data is valid if + * (valid & PNG_INFO_sBIT) is non-zero. + */ + png_color_8 sig_bit; /* significant bits in color channels */ +#endif + +#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_EXPAND_SUPPORTED) || \ +defined(PNG_READ_BACKGROUND_SUPPORTED) + /* The tRNS chunk supplies transparency data for paletted images and + * other image types that don't need a full alpha channel. There are + * "num_trans" transparency values for a paletted image, stored in the + * same order as the palette colors, starting from index 0. Values + * for the data are in the range [0, 255], ranging from fully transparent + * to fully opaque, respectively. For non-paletted images, there is a + * single color specified that should be treated as fully transparent. + * Data is valid if (valid & PNG_INFO_tRNS) is non-zero. + */ + png_bytep trans; /* transparent values for paletted image */ + png_color_16 trans_values; /* transparent color for non-palette image */ +#endif + +#if defined(PNG_bKGD_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) + /* The bKGD chunk gives the suggested image background color if the + * display program does not have its own background color and the image + * is needs to composited onto a background before display. The colors + * in "background" are normally in the same color space/depth as the + * pixel data. Data is valid if (valid & PNG_INFO_bKGD) is non-zero. + */ + png_color_16 background; +#endif + +#if defined(PNG_oFFs_SUPPORTED) + /* The oFFs chunk gives the offset in "offset_unit_type" units rightwards + * and downwards from the top-left corner of the display, page, or other + * application-specific co-ordinate space. See the PNG_OFFSET_ defines + * below for the unit types. Valid if (valid & PNG_INFO_oFFs) non-zero. + */ + png_int_32 x_offset; /* x offset on page */ + png_int_32 y_offset; /* y offset on page */ + png_byte offset_unit_type; /* offset units type */ +#endif + +#if defined(PNG_pHYs_SUPPORTED) + /* The pHYs chunk gives the physical pixel density of the image for + * display or printing in "phys_unit_type" units (see PNG_RESOLUTION_ + * defines below). Data is valid if (valid & PNG_INFO_pHYs) is non-zero. + */ + png_uint_32 x_pixels_per_unit; /* horizontal pixel density */ + png_uint_32 y_pixels_per_unit; /* vertical pixel density */ + png_byte phys_unit_type; /* resolution type (see PNG_RESOLUTION_ below) */ +#endif + +#if defined(PNG_hIST_SUPPORTED) + /* The hIST chunk contains the relative frequency or importance of the + * various palette entries, so that a viewer can intelligently select a + * reduced-color palette, if required. Data is an array of "num_palette" + * values in the range [0,65535]. Data valid if (valid & PNG_INFO_hIST) + * is non-zero. + */ + png_uint_16p hist; +#endif + +#ifdef PNG_cHRM_SUPPORTED + /* The cHRM chunk describes the CIE color characteristics of the monitor + * on which the PNG was created. This data allows the viewer to do gamut + * mapping of the input image to ensure that the viewer sees the same + * colors in the image as the creator. Values are in the range + * [0.0, 0.8]. Data valid if (valid & PNG_INFO_cHRM) non-zero. + */ +#ifdef PNG_FLOATING_POINT_SUPPORTED + float x_white; + float y_white; + float x_red; + float y_red; + float x_green; + float y_green; + float x_blue; + float y_blue; +#endif +#endif + +#if defined(PNG_pCAL_SUPPORTED) + /* The pCAL chunk describes a transformation between the stored pixel + * values and original physical data values used to create the image. + * The integer range [0, 2^bit_depth - 1] maps to the floating-point + * range given by [pcal_X0, pcal_X1], and are further transformed by a + * (possibly non-linear) transformation function given by "pcal_type" + * and "pcal_params" into "pcal_units". Please see the PNG_EQUATION_ + * defines below, and the PNG-Group's PNG extensions document for a + * complete description of the transformations and how they should be + * implemented, and for a description of the ASCII parameter strings. + * Data values are valid if (valid & PNG_INFO_pCAL) non-zero. + */ + png_charp pcal_purpose; /* pCAL chunk description string */ + png_int_32 pcal_X0; /* minimum value */ + png_int_32 pcal_X1; /* maximum value */ + png_charp pcal_units; /* Latin-1 string giving physical units */ + png_charpp pcal_params; /* ASCII strings containing parameter values */ + png_byte pcal_type; /* equation type (see PNG_EQUATION_ below) */ + png_byte pcal_nparams; /* number of parameters given in pcal_params */ +#endif + +/* New members added in libpng-1.0.6 */ +#ifdef PNG_FREE_ME_SUPPORTED + png_uint_32 free_me; /* flags items libpng is responsible for freeing */ +#endif + +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) + /* storage for unknown chunks that the library doesn't recognize. */ + png_unknown_chunkp unknown_chunks; + png_size_t unknown_chunks_num; +#endif + +#if defined(PNG_iCCP_SUPPORTED) + /* iCCP chunk data. */ + png_charp iccp_name; /* profile name */ + png_charp iccp_profile; /* International Color Consortium profile data */ + /* Note to maintainer: should be png_bytep */ + png_uint_32 iccp_proflen; /* ICC profile data length */ + png_byte iccp_compression; /* Always zero */ +#endif + +#if defined(PNG_sPLT_SUPPORTED) + /* data on sPLT chunks (there may be more than one). */ + png_sPLT_tp splt_palettes; + png_uint_32 splt_palettes_num; +#endif + +#if defined(PNG_sCAL_SUPPORTED) + /* The sCAL chunk describes the actual physical dimensions of the + * subject matter of the graphic. The chunk contains a unit specification + * a byte value, and two ASCII strings representing floating-point + * values. The values are width and height corresponsing to one pixel + * in the image. This external representation is converted to double + * here. Data values are valid if (valid & PNG_INFO_sCAL) is non-zero. + */ + png_byte scal_unit; /* unit of physical scale */ +#ifdef PNG_FLOATING_POINT_SUPPORTED + double scal_pixel_width; /* width of one pixel */ + double scal_pixel_height; /* height of one pixel */ +#endif +#ifdef PNG_FIXED_POINT_SUPPORTED + png_charp scal_s_width; /* string containing height */ + png_charp scal_s_height; /* string containing width */ +#endif +#endif + +#if defined(PNG_INFO_IMAGE_SUPPORTED) + /* Memory has been allocated if (valid & PNG_ALLOCATED_INFO_ROWS) non-zero */ + /* Data valid if (valid & PNG_INFO_IDAT) non-zero */ + png_bytepp row_pointers; /* the image bits */ +#endif + +#if defined(PNG_FIXED_POINT_SUPPORTED) && defined(PNG_gAMA_SUPPORTED) + png_fixed_point int_gamma; /* gamma of image, if (valid & PNG_INFO_gAMA) */ +#endif + +#if defined(PNG_cHRM_SUPPORTED) && defined(PNG_FIXED_POINT_SUPPORTED) + png_fixed_point int_x_white; + png_fixed_point int_y_white; + png_fixed_point int_x_red; + png_fixed_point int_y_red; + png_fixed_point int_x_green; + png_fixed_point int_y_green; + png_fixed_point int_x_blue; + png_fixed_point int_y_blue; +#endif + +} png_info; + +typedef png_info FAR * png_infop; +typedef png_info FAR * FAR * png_infopp; + +/* Maximum positive integer used in PNG is (2^31)-1 */ +#define PNG_UINT_31_MAX ((png_uint_32)0x7fffffffL) +#define PNG_UINT_32_MAX ((png_uint_32)(-1)) +#define PNG_SIZE_MAX ((png_size_t)(-1)) +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) +/* PNG_MAX_UINT is deprecated; use PNG_UINT_31_MAX instead. */ +#define PNG_MAX_UINT PNG_UINT_31_MAX +#endif + +/* These describe the color_type field in png_info. */ +/* color type masks */ +#define PNG_COLOR_MASK_PALETTE 1 +#define PNG_COLOR_MASK_COLOR 2 +#define PNG_COLOR_MASK_ALPHA 4 + +/* color types. Note that not all combinations are legal */ +#define PNG_COLOR_TYPE_GRAY 0 +#define PNG_COLOR_TYPE_PALETTE (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_PALETTE) +#define PNG_COLOR_TYPE_RGB (PNG_COLOR_MASK_COLOR) +#define PNG_COLOR_TYPE_RGB_ALPHA (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_ALPHA) +#define PNG_COLOR_TYPE_GRAY_ALPHA (PNG_COLOR_MASK_ALPHA) +/* aliases */ +#define PNG_COLOR_TYPE_RGBA PNG_COLOR_TYPE_RGB_ALPHA +#define PNG_COLOR_TYPE_GA PNG_COLOR_TYPE_GRAY_ALPHA + +/* This is for compression type. PNG 1.0-1.2 only define the single type. */ +#define PNG_COMPRESSION_TYPE_BASE 0 /* Deflate method 8, 32K window */ +#define PNG_COMPRESSION_TYPE_DEFAULT PNG_COMPRESSION_TYPE_BASE + +/* This is for filter type. PNG 1.0-1.2 only define the single type. */ +#define PNG_FILTER_TYPE_BASE 0 /* Single row per-byte filtering */ +#define PNG_INTRAPIXEL_DIFFERENCING 64 /* Used only in MNG datastreams */ +#define PNG_FILTER_TYPE_DEFAULT PNG_FILTER_TYPE_BASE + +/* These are for the interlacing type. These values should NOT be changed. */ +#define PNG_INTERLACE_NONE 0 /* Non-interlaced image */ +#define PNG_INTERLACE_ADAM7 1 /* Adam7 interlacing */ +#define PNG_INTERLACE_LAST 2 /* Not a valid value */ + +/* These are for the oFFs chunk. These values should NOT be changed. */ +#define PNG_OFFSET_PIXEL 0 /* Offset in pixels */ +#define PNG_OFFSET_MICROMETER 1 /* Offset in micrometers (1/10^6 meter) */ +#define PNG_OFFSET_LAST 2 /* Not a valid value */ + +/* These are for the pCAL chunk. These values should NOT be changed. */ +#define PNG_EQUATION_LINEAR 0 /* Linear transformation */ +#define PNG_EQUATION_BASE_E 1 /* Exponential base e transform */ +#define PNG_EQUATION_ARBITRARY 2 /* Arbitrary base exponential transform */ +#define PNG_EQUATION_HYPERBOLIC 3 /* Hyperbolic sine transformation */ +#define PNG_EQUATION_LAST 4 /* Not a valid value */ + +/* These are for the sCAL chunk. These values should NOT be changed. */ +#define PNG_SCALE_UNKNOWN 0 /* unknown unit (image scale) */ +#define PNG_SCALE_METER 1 /* meters per pixel */ +#define PNG_SCALE_RADIAN 2 /* radians per pixel */ +#define PNG_SCALE_LAST 3 /* Not a valid value */ + +/* These are for the pHYs chunk. These values should NOT be changed. */ +#define PNG_RESOLUTION_UNKNOWN 0 /* pixels/unknown unit (aspect ratio) */ +#define PNG_RESOLUTION_METER 1 /* pixels/meter */ +#define PNG_RESOLUTION_LAST 2 /* Not a valid value */ + +/* These are for the sRGB chunk. These values should NOT be changed. */ +#define PNG_sRGB_INTENT_PERCEPTUAL 0 +#define PNG_sRGB_INTENT_RELATIVE 1 +#define PNG_sRGB_INTENT_SATURATION 2 +#define PNG_sRGB_INTENT_ABSOLUTE 3 +#define PNG_sRGB_INTENT_LAST 4 /* Not a valid value */ + +/* This is for text chunks */ +#define PNG_KEYWORD_MAX_LENGTH 79 + +/* Maximum number of entries in PLTE/sPLT/tRNS arrays */ +#define PNG_MAX_PALETTE_LENGTH 256 + +/* These determine if an ancillary chunk's data has been successfully read + * from the PNG header, or if the application has filled in the corresponding + * data in the info_struct to be written into the output file. The values + * of the PNG_INFO_<chunk> defines should NOT be changed. + */ +#define PNG_INFO_gAMA 0x0001 +#define PNG_INFO_sBIT 0x0002 +#define PNG_INFO_cHRM 0x0004 +#define PNG_INFO_PLTE 0x0008 +#define PNG_INFO_tRNS 0x0010 +#define PNG_INFO_bKGD 0x0020 +#define PNG_INFO_hIST 0x0040 +#define PNG_INFO_pHYs 0x0080 +#define PNG_INFO_oFFs 0x0100 +#define PNG_INFO_tIME 0x0200 +#define PNG_INFO_pCAL 0x0400 +#define PNG_INFO_sRGB 0x0800 /* GR-P, 0.96a */ +#define PNG_INFO_iCCP 0x1000 /* ESR, 1.0.6 */ +#define PNG_INFO_sPLT 0x2000 /* ESR, 1.0.6 */ +#define PNG_INFO_sCAL 0x4000 /* ESR, 1.0.6 */ +#define PNG_INFO_IDAT 0x8000L /* ESR, 1.0.6 */ + +/* This is used for the transformation routines, as some of them + * change these values for the row. It also should enable using + * the routines for other purposes. + */ +typedef struct png_row_info_struct +{ + png_uint_32 width; /* width of row */ + png_uint_32 rowbytes; /* number of bytes in row */ + png_byte color_type; /* color type of row */ + png_byte bit_depth; /* bit depth of row */ + png_byte channels; /* number of channels (1, 2, 3, or 4) */ + png_byte pixel_depth; /* bits per pixel (depth * channels) */ +} png_row_info; + +typedef png_row_info FAR * png_row_infop; +typedef png_row_info FAR * FAR * png_row_infopp; + +/* These are the function types for the I/O functions and for the functions + * that allow the user to override the default I/O functions with his or her + * own. The png_error_ptr type should match that of user-supplied warning + * and error functions, while the png_rw_ptr type should match that of the + * user read/write data functions. + */ +typedef struct png_struct_def png_struct; +typedef png_struct FAR * png_structp; + +typedef void (PNGAPI *png_error_ptr) PNGARG((png_structp, png_const_charp)); +typedef void (PNGAPI *png_rw_ptr) PNGARG((png_structp, png_bytep, png_size_t)); +typedef void (PNGAPI *png_flush_ptr) PNGARG((png_structp)); +typedef void (PNGAPI *png_read_status_ptr) PNGARG((png_structp, png_uint_32, + int)); +typedef void (PNGAPI *png_write_status_ptr) PNGARG((png_structp, png_uint_32, + int)); + +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +typedef void (PNGAPI *png_progressive_info_ptr) PNGARG((png_structp, png_infop)); +typedef void (PNGAPI *png_progressive_end_ptr) PNGARG((png_structp, png_infop)); +typedef void (PNGAPI *png_progressive_row_ptr) PNGARG((png_structp, png_bytep, + png_uint_32, int)); +#endif + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_LEGACY_SUPPORTED) +typedef void (PNGAPI *png_user_transform_ptr) PNGARG((png_structp, + png_row_infop, png_bytep)); +#endif + +#if defined(PNG_USER_CHUNKS_SUPPORTED) +typedef int (PNGAPI *png_user_chunk_ptr) PNGARG((png_structp, png_unknown_chunkp)); +#endif +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) +typedef void (PNGAPI *png_unknown_chunk_ptr) PNGARG((png_structp)); +#endif + +/* Transform masks for the high-level interface */ +#define PNG_TRANSFORM_IDENTITY 0x0000 /* read and write */ +#define PNG_TRANSFORM_STRIP_16 0x0001 /* read only */ +#define PNG_TRANSFORM_STRIP_ALPHA 0x0002 /* read only */ +#define PNG_TRANSFORM_PACKING 0x0004 /* read and write */ +#define PNG_TRANSFORM_PACKSWAP 0x0008 /* read and write */ +#define PNG_TRANSFORM_EXPAND 0x0010 /* read only */ +#define PNG_TRANSFORM_INVERT_MONO 0x0020 /* read and write */ +#define PNG_TRANSFORM_SHIFT 0x0040 /* read and write */ +#define PNG_TRANSFORM_BGR 0x0080 /* read and write */ +#define PNG_TRANSFORM_SWAP_ALPHA 0x0100 /* read and write */ +#define PNG_TRANSFORM_SWAP_ENDIAN 0x0200 /* read and write */ +#define PNG_TRANSFORM_INVERT_ALPHA 0x0400 /* read and write */ +#define PNG_TRANSFORM_STRIP_FILLER 0x0800 /* WRITE only */ + +/* Flags for MNG supported features */ +#define PNG_FLAG_MNG_EMPTY_PLTE 0x01 +#define PNG_FLAG_MNG_FILTER_64 0x04 +#define PNG_ALL_MNG_FEATURES 0x05 + +typedef png_voidp (*png_malloc_ptr) PNGARG((png_structp, png_size_t)); +typedef void (*png_free_ptr) PNGARG((png_structp, png_voidp)); + +/* The structure that holds the information to read and write PNG files. + * The only people who need to care about what is inside of this are the + * people who will be modifying the library for their own special needs. + * It should NOT be accessed directly by an application, except to store + * the jmp_buf. + */ + +struct png_struct_def +{ +#ifdef PNG_SETJMP_SUPPORTED + jmp_buf jmpbuf; /* used in png_error */ +#endif + png_error_ptr error_fn; /* function for printing errors and aborting */ + png_error_ptr warning_fn; /* function for printing warnings */ + png_voidp error_ptr; /* user supplied struct for error functions */ + png_rw_ptr write_data_fn; /* function for writing output data */ + png_rw_ptr read_data_fn; /* function for reading input data */ + png_voidp io_ptr; /* ptr to application struct for I/O functions */ + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) + png_user_transform_ptr read_user_transform_fn; /* user read transform */ +#endif + +#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) + png_user_transform_ptr write_user_transform_fn; /* user write transform */ +#endif + +/* These were added in libpng-1.0.2 */ +#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) + png_voidp user_transform_ptr; /* user supplied struct for user transform */ + png_byte user_transform_depth; /* bit depth of user transformed pixels */ + png_byte user_transform_channels; /* channels in user transformed pixels */ +#endif +#endif + + png_uint_32 mode; /* tells us where we are in the PNG file */ + png_uint_32 flags; /* flags indicating various things to libpng */ + png_uint_32 transformations; /* which transformations to perform */ + + z_stream zstream; /* pointer to decompression structure (below) */ + png_bytep zbuf; /* buffer for zlib */ + png_size_t zbuf_size; /* size of zbuf */ + int zlib_level; /* holds zlib compression level */ + int zlib_method; /* holds zlib compression method */ + int zlib_window_bits; /* holds zlib compression window bits */ + int zlib_mem_level; /* holds zlib compression memory level */ + int zlib_strategy; /* holds zlib compression strategy */ + + png_uint_32 width; /* width of image in pixels */ + png_uint_32 height; /* height of image in pixels */ + png_uint_32 num_rows; /* number of rows in current pass */ + png_uint_32 usr_width; /* width of row at start of write */ + png_uint_32 rowbytes; /* size of row in bytes */ + png_uint_32 irowbytes; /* size of current interlaced row in bytes */ + png_uint_32 iwidth; /* width of current interlaced row in pixels */ + png_uint_32 row_number; /* current row in interlace pass */ + png_bytep prev_row; /* buffer to save previous (unfiltered) row */ + png_bytep row_buf; /* buffer to save current (unfiltered) row */ + png_bytep sub_row; /* buffer to save "sub" row when filtering */ + png_bytep up_row; /* buffer to save "up" row when filtering */ + png_bytep avg_row; /* buffer to save "avg" row when filtering */ + png_bytep paeth_row; /* buffer to save "Paeth" row when filtering */ + png_row_info row_info; /* used for transformation routines */ + + png_uint_32 idat_size; /* current IDAT size for read */ + png_uint_32 crc; /* current chunk CRC value */ + png_colorp palette; /* palette from the input file */ + png_uint_16 num_palette; /* number of color entries in palette */ + png_uint_16 num_trans; /* number of transparency values */ + png_byte chunk_name[5]; /* null-terminated name of current chunk */ + png_byte compression; /* file compression type (always 0) */ + png_byte filter; /* file filter type (always 0) */ + png_byte interlaced; /* PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */ + png_byte pass; /* current interlace pass (0 - 6) */ + png_byte do_filter; /* row filter flags (see PNG_FILTER_ below ) */ + png_byte color_type; /* color type of file */ + png_byte bit_depth; /* bit depth of file */ + png_byte usr_bit_depth; /* bit depth of users row */ + png_byte pixel_depth; /* number of bits per pixel */ + png_byte channels; /* number of channels in file */ + png_byte usr_channels; /* channels at start of write */ + png_byte sig_bytes; /* magic bytes read/written from start of file */ + +#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) +#ifdef PNG_LEGACY_SUPPORTED + png_byte filler; /* filler byte for pixel expansion */ +#else + png_uint_16 filler; /* filler bytes for pixel expansion */ +#endif +#endif + +#if defined(PNG_bKGD_SUPPORTED) + png_byte background_gamma_type; +# ifdef PNG_FLOATING_POINT_SUPPORTED + float background_gamma; +# endif + png_color_16 background; /* background color in screen gamma space */ +#if defined(PNG_READ_GAMMA_SUPPORTED) + png_color_16 background_1; /* background normalized to gamma 1.0 */ +#endif +#endif /* PNG_bKGD_SUPPORTED */ + +#if defined(PNG_WRITE_FLUSH_SUPPORTED) + png_flush_ptr output_flush_fn;/* Function for flushing output */ + png_uint_32 flush_dist; /* how many rows apart to flush, 0 - no flush */ + png_uint_32 flush_rows; /* number of rows written since last flush */ +#endif + +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) + int gamma_shift; /* number of "insignificant" bits 16-bit gamma */ +#ifdef PNG_FLOATING_POINT_SUPPORTED + float gamma; /* file gamma value */ + float screen_gamma; /* screen gamma value (display_exponent) */ +#endif +#endif + +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) + png_bytep gamma_table; /* gamma table for 8-bit depth files */ + png_bytep gamma_from_1; /* converts from 1.0 to screen */ + png_bytep gamma_to_1; /* converts from file to 1.0 */ + png_uint_16pp gamma_16_table; /* gamma table for 16-bit depth files */ + png_uint_16pp gamma_16_from_1; /* converts from 1.0 to screen */ + png_uint_16pp gamma_16_to_1; /* converts from file to 1.0 */ +#endif + +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_sBIT_SUPPORTED) + png_color_8 sig_bit; /* significant bits in each available channel */ +#endif + +#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) + png_color_8 shift; /* shift for significant bit tranformation */ +#endif + +#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) \ + || defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) + png_bytep trans; /* transparency values for paletted files */ + png_color_16 trans_values; /* transparency values for non-paletted files */ +#endif + + png_read_status_ptr read_row_fn; /* called after each row is decoded */ + png_write_status_ptr write_row_fn; /* called after each row is encoded */ +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED + png_progressive_info_ptr info_fn; /* called after header data fully read */ + png_progressive_row_ptr row_fn; /* called after each prog. row is decoded */ + png_progressive_end_ptr end_fn; /* called after image is complete */ + png_bytep save_buffer_ptr; /* current location in save_buffer */ + png_bytep save_buffer; /* buffer for previously read data */ + png_bytep current_buffer_ptr; /* current location in current_buffer */ + png_bytep current_buffer; /* buffer for recently used data */ + png_uint_32 push_length; /* size of current input chunk */ + png_uint_32 skip_length; /* bytes to skip in input data */ + png_size_t save_buffer_size; /* amount of data now in save_buffer */ + png_size_t save_buffer_max; /* total size of save_buffer */ + png_size_t buffer_size; /* total amount of available input data */ + png_size_t current_buffer_size; /* amount of data now in current_buffer */ + int process_mode; /* what push library is currently doing */ + int cur_palette; /* current push library palette index */ + +# if defined(PNG_TEXT_SUPPORTED) + png_size_t current_text_size; /* current size of text input data */ + png_size_t current_text_left; /* how much text left to read in input */ + png_charp current_text; /* current text chunk buffer */ + png_charp current_text_ptr; /* current location in current_text */ +# endif /* PNG_PROGRESSIVE_READ_SUPPORTED && PNG_TEXT_SUPPORTED */ + +#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ + +#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__) +/* for the Borland special 64K segment handler */ + png_bytepp offset_table_ptr; + png_bytep offset_table; + png_uint_16 offset_table_number; + png_uint_16 offset_table_count; + png_uint_16 offset_table_count_free; +#endif + +#if defined(PNG_READ_DITHER_SUPPORTED) + png_bytep palette_lookup; /* lookup table for dithering */ + png_bytep dither_index; /* index translation for palette files */ +#endif + +#if defined(PNG_READ_DITHER_SUPPORTED) || defined(PNG_hIST_SUPPORTED) + png_uint_16p hist; /* histogram */ +#endif + +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) + png_byte heuristic_method; /* heuristic for row filter selection */ + png_byte num_prev_filters; /* number of weights for previous rows */ + png_bytep prev_filters; /* filter type(s) of previous row(s) */ + png_uint_16p filter_weights; /* weight(s) for previous line(s) */ + png_uint_16p inv_filter_weights; /* 1/weight(s) for previous line(s) */ + png_uint_16p filter_costs; /* relative filter calculation cost */ + png_uint_16p inv_filter_costs; /* 1/relative filter calculation cost */ +#endif + +#if defined(PNG_TIME_RFC1123_SUPPORTED) + png_charp time_buffer; /* String to hold RFC 1123 time text */ +#endif + +/* New members added in libpng-1.0.6 */ + +#ifdef PNG_FREE_ME_SUPPORTED + png_uint_32 free_me; /* flags items libpng is responsible for freeing */ +#endif + +#if defined(PNG_USER_CHUNKS_SUPPORTED) + png_voidp user_chunk_ptr; + png_user_chunk_ptr read_user_chunk_fn; /* user read chunk handler */ +#endif + +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) + int num_chunk_list; + png_bytep chunk_list; +#endif + +/* New members added in libpng-1.0.3 */ +#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) + png_byte rgb_to_gray_status; + /* These were changed from png_byte in libpng-1.0.6 */ + png_uint_16 rgb_to_gray_red_coeff; + png_uint_16 rgb_to_gray_green_coeff; + png_uint_16 rgb_to_gray_blue_coeff; +#endif + +/* New member added in libpng-1.0.4 (renamed in 1.0.9) */ +#if defined(PNG_MNG_FEATURES_SUPPORTED) || \ + defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \ + defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) +/* changed from png_byte to png_uint_32 at version 1.2.0 */ +#ifdef PNG_1_0_X + png_byte mng_features_permitted; +#else + png_uint_32 mng_features_permitted; +#endif /* PNG_1_0_X */ +#endif + +/* New member added in libpng-1.0.7 */ +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) + png_fixed_point int_gamma; +#endif + +/* New member added in libpng-1.0.9, ifdef'ed out in 1.0.12, enabled in 1.2.0 */ +#if defined(PNG_MNG_FEATURES_SUPPORTED) + png_byte filter_type; +#endif + +#if defined(PNG_1_0_X) || (defined(PNG_DEBUG) && defined(PNG_USE_PNGGCCRD)) +/* New member added in libpng-1.0.10, ifdef'ed out in 1.2.0 */ + png_uint_32 row_buf_size; +#endif + +/* New members added in libpng-1.2.0 */ +#if !defined(PNG_1_0_X) && defined(PNG_ASSEMBLER_CODE_SUPPORTED) + png_byte mmx_bitdepth_threshold; + png_uint_32 mmx_rowbytes_threshold; + png_uint_32 asm_flags; +#endif + +/* New members added in libpng-1.0.2 but first enabled by default in 1.2.0 */ +#ifdef PNG_USER_MEM_SUPPORTED + png_voidp mem_ptr; /* user supplied struct for mem functions */ + png_malloc_ptr malloc_fn; /* function for allocating memory */ + png_free_ptr free_fn; /* function for freeing memory */ +#endif + +/* New member added in libpng-1.0.13 and 1.2.0 */ + png_bytep big_row_buf; /* buffer to save current (unfiltered) row */ + +#if defined(PNG_READ_DITHER_SUPPORTED) +/* The following three members were added at version 1.0.14 and 1.2.4 */ + png_bytep dither_sort; /* working sort array */ + png_bytep index_to_palette; /* where the original index currently is */ + /* in the palette */ + png_bytep palette_to_index; /* which original index points to this */ + /* palette color */ +#endif + +/* New members added in libpng-1.0.16 and 1.2.6 */ + png_byte compression_type; + +#ifdef PNG_SET_USER_LIMITS_SUPPORTED + png_uint_32 user_width_max; + png_uint_32 user_height_max; +#endif + +}; + + +/* This triggers a compiler error in png.c, if png.c and png.h + * do not agree upon the version number. + */ +typedef png_structp version_1_2_12; + +typedef png_struct FAR * FAR * png_structpp; + +/* Here are the function definitions most commonly used. This is not + * the place to find out how to use libpng. See libpng.txt for the + * full explanation, see example.c for the summary. This just provides + * a simple one line description of the use of each function. + */ + +/* Returns the version number of the library */ +extern PNG_EXPORT(png_uint_32,png_access_version_number) PNGARG((void)); + +/* Tell lib we have already handled the first <num_bytes> magic bytes. + * Handling more than 8 bytes from the beginning of the file is an error. + */ +extern PNG_EXPORT(void,png_set_sig_bytes) PNGARG((png_structp png_ptr, + int num_bytes)); + +/* Check sig[start] through sig[start + num_to_check - 1] to see if it's a + * PNG file. Returns zero if the supplied bytes match the 8-byte PNG + * signature, and non-zero otherwise. Having num_to_check == 0 or + * start > 7 will always fail (ie return non-zero). + */ +extern PNG_EXPORT(int,png_sig_cmp) PNGARG((png_bytep sig, png_size_t start, + png_size_t num_to_check)); + +/* Simple signature checking function. This is the same as calling + * png_check_sig(sig, n) := !png_sig_cmp(sig, 0, n). + */ +extern PNG_EXPORT(int,png_check_sig) PNGARG((png_bytep sig, int num)); + +/* Allocate and initialize png_ptr struct for reading, and any other memory. */ +extern PNG_EXPORT(png_structp,png_create_read_struct) + PNGARG((png_const_charp user_png_ver, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warn_fn)); + +/* Allocate and initialize png_ptr struct for writing, and any other memory */ +extern PNG_EXPORT(png_structp,png_create_write_struct) + PNGARG((png_const_charp user_png_ver, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warn_fn)); + +#ifdef PNG_WRITE_SUPPORTED +extern PNG_EXPORT(png_uint_32,png_get_compression_buffer_size) + PNGARG((png_structp png_ptr)); +#endif + +#ifdef PNG_WRITE_SUPPORTED +extern PNG_EXPORT(void,png_set_compression_buffer_size) + PNGARG((png_structp png_ptr, png_uint_32 size)); +#endif + +/* Reset the compression stream */ +extern PNG_EXPORT(int,png_reset_zstream) PNGARG((png_structp png_ptr)); + +/* New functions added in libpng-1.0.2 (not enabled by default until 1.2.0) */ +#ifdef PNG_USER_MEM_SUPPORTED +extern PNG_EXPORT(png_structp,png_create_read_struct_2) + PNGARG((png_const_charp user_png_ver, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, + png_malloc_ptr malloc_fn, png_free_ptr free_fn)); +extern PNG_EXPORT(png_structp,png_create_write_struct_2) + PNGARG((png_const_charp user_png_ver, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, + png_malloc_ptr malloc_fn, png_free_ptr free_fn)); +#endif + +/* Write a PNG chunk - size, type, (optional) data, CRC. */ +extern PNG_EXPORT(void,png_write_chunk) PNGARG((png_structp png_ptr, + png_bytep chunk_name, png_bytep data, png_size_t length)); + +/* Write the start of a PNG chunk - length and chunk name. */ +extern PNG_EXPORT(void,png_write_chunk_start) PNGARG((png_structp png_ptr, + png_bytep chunk_name, png_uint_32 length)); + +/* Write the data of a PNG chunk started with png_write_chunk_start(). */ +extern PNG_EXPORT(void,png_write_chunk_data) PNGARG((png_structp png_ptr, + png_bytep data, png_size_t length)); + +/* Finish a chunk started with png_write_chunk_start() (includes CRC). */ +extern PNG_EXPORT(void,png_write_chunk_end) PNGARG((png_structp png_ptr)); + +/* Allocate and initialize the info structure */ +extern PNG_EXPORT(png_infop,png_create_info_struct) + PNGARG((png_structp png_ptr)); + +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) +/* Initialize the info structure (old interface - DEPRECATED) */ +extern PNG_EXPORT(void,png_info_init) PNGARG((png_infop info_ptr)); +#undef png_info_init +#define png_info_init(info_ptr) png_info_init_3(&info_ptr,\ + png_sizeof(png_info)); +#endif + +extern PNG_EXPORT(void,png_info_init_3) PNGARG((png_infopp info_ptr, + png_size_t png_info_struct_size)); + +/* Writes all the PNG information before the image. */ +extern PNG_EXPORT(void,png_write_info_before_PLTE) PNGARG((png_structp png_ptr, + png_infop info_ptr)); +extern PNG_EXPORT(void,png_write_info) PNGARG((png_structp png_ptr, + png_infop info_ptr)); + +#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED +/* read the information before the actual image data. */ +extern PNG_EXPORT(void,png_read_info) PNGARG((png_structp png_ptr, + png_infop info_ptr)); +#endif + +#if defined(PNG_TIME_RFC1123_SUPPORTED) +extern PNG_EXPORT(png_charp,png_convert_to_rfc1123) + PNGARG((png_structp png_ptr, png_timep ptime)); +#endif + +#if !defined(_WIN32_WCE) +/* "time.h" functions are not supported on WindowsCE */ +#if defined(PNG_WRITE_tIME_SUPPORTED) +/* convert from a struct tm to png_time */ +extern PNG_EXPORT(void,png_convert_from_struct_tm) PNGARG((png_timep ptime, + struct tm FAR * ttime)); + +/* convert from time_t to png_time. Uses gmtime() */ +extern PNG_EXPORT(void,png_convert_from_time_t) PNGARG((png_timep ptime, + time_t ttime)); +#endif /* PNG_WRITE_tIME_SUPPORTED */ +#endif /* _WIN32_WCE */ + +#if defined(PNG_READ_EXPAND_SUPPORTED) +/* Expand data to 24-bit RGB, or 8-bit grayscale, with alpha if available. */ +extern PNG_EXPORT(void,png_set_expand) PNGARG((png_structp png_ptr)); +#if !defined(PNG_1_0_X) +extern PNG_EXPORT(void,png_set_expand_gray_1_2_4_to_8) PNGARG((png_structp + png_ptr)); +#endif +extern PNG_EXPORT(void,png_set_palette_to_rgb) PNGARG((png_structp png_ptr)); +extern PNG_EXPORT(void,png_set_tRNS_to_alpha) PNGARG((png_structp png_ptr)); +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) +/* Deprecated */ +extern PNG_EXPORT(void,png_set_gray_1_2_4_to_8) PNGARG((png_structp png_ptr)); +#endif +#endif + +#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) +/* Use blue, green, red order for pixels. */ +extern PNG_EXPORT(void,png_set_bgr) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) +/* Expand the grayscale to 24-bit RGB if necessary. */ +extern PNG_EXPORT(void,png_set_gray_to_rgb) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) +/* Reduce RGB to grayscale. */ +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(void,png_set_rgb_to_gray) PNGARG((png_structp png_ptr, + int error_action, double red, double green )); +#endif +extern PNG_EXPORT(void,png_set_rgb_to_gray_fixed) PNGARG((png_structp png_ptr, + int error_action, png_fixed_point red, png_fixed_point green )); +extern PNG_EXPORT(png_byte,png_get_rgb_to_gray_status) PNGARG((png_structp + png_ptr)); +#endif + +extern PNG_EXPORT(void,png_build_grayscale_palette) PNGARG((int bit_depth, + png_colorp palette)); + +#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED) +extern PNG_EXPORT(void,png_set_strip_alpha) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \ + defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) +extern PNG_EXPORT(void,png_set_swap_alpha) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \ + defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) +extern PNG_EXPORT(void,png_set_invert_alpha) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) +/* Add a filler byte to 8-bit Gray or 24-bit RGB images. */ +extern PNG_EXPORT(void,png_set_filler) PNGARG((png_structp png_ptr, + png_uint_32 filler, int flags)); +/* The values of the PNG_FILLER_ defines should NOT be changed */ +#define PNG_FILLER_BEFORE 0 +#define PNG_FILLER_AFTER 1 +/* Add an alpha byte to 8-bit Gray or 24-bit RGB images. */ +#if !defined(PNG_1_0_X) +extern PNG_EXPORT(void,png_set_add_alpha) PNGARG((png_structp png_ptr, + png_uint_32 filler, int flags)); +#endif +#endif /* PNG_READ_FILLER_SUPPORTED || PNG_WRITE_FILLER_SUPPORTED */ + +#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) +/* Swap bytes in 16-bit depth files. */ +extern PNG_EXPORT(void,png_set_swap) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED) +/* Use 1 byte per pixel in 1, 2, or 4-bit depth files. */ +extern PNG_EXPORT(void,png_set_packing) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_PACKSWAP_SUPPORTED) || defined(PNG_WRITE_PACKSWAP_SUPPORTED) +/* Swap packing order of pixels in bytes. */ +extern PNG_EXPORT(void,png_set_packswap) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) +/* Converts files to legal bit depths. */ +extern PNG_EXPORT(void,png_set_shift) PNGARG((png_structp png_ptr, + png_color_8p true_bits)); +#endif + +#if defined(PNG_READ_INTERLACING_SUPPORTED) || \ + defined(PNG_WRITE_INTERLACING_SUPPORTED) +/* Have the code handle the interlacing. Returns the number of passes. */ +extern PNG_EXPORT(int,png_set_interlace_handling) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) +/* Invert monochrome files */ +extern PNG_EXPORT(void,png_set_invert_mono) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_BACKGROUND_SUPPORTED) +/* Handle alpha and tRNS by replacing with a background color. */ +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(void,png_set_background) PNGARG((png_structp png_ptr, + png_color_16p background_color, int background_gamma_code, + int need_expand, double background_gamma)); +#endif +#define PNG_BACKGROUND_GAMMA_UNKNOWN 0 +#define PNG_BACKGROUND_GAMMA_SCREEN 1 +#define PNG_BACKGROUND_GAMMA_FILE 2 +#define PNG_BACKGROUND_GAMMA_UNIQUE 3 +#endif + +#if defined(PNG_READ_16_TO_8_SUPPORTED) +/* strip the second byte of information from a 16-bit depth file. */ +extern PNG_EXPORT(void,png_set_strip_16) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_DITHER_SUPPORTED) +/* Turn on dithering, and reduce the palette to the number of colors available. */ +extern PNG_EXPORT(void,png_set_dither) PNGARG((png_structp png_ptr, + png_colorp palette, int num_palette, int maximum_colors, + png_uint_16p histogram, int full_dither)); +#endif + +#if defined(PNG_READ_GAMMA_SUPPORTED) +/* Handle gamma correction. Screen_gamma=(display_exponent) */ +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(void,png_set_gamma) PNGARG((png_structp png_ptr, + double screen_gamma, double default_file_gamma)); +#endif +#endif + +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) +#if defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \ + defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) +/* Permit or disallow empty PLTE (0: not permitted, 1: permitted) */ +/* Deprecated and will be removed. Use png_permit_mng_features() instead. */ +extern PNG_EXPORT(void,png_permit_empty_plte) PNGARG((png_structp png_ptr, + int empty_plte_permitted)); +#endif +#endif + +#if defined(PNG_WRITE_FLUSH_SUPPORTED) +/* Set how many lines between output flushes - 0 for no flushing */ +extern PNG_EXPORT(void,png_set_flush) PNGARG((png_structp png_ptr, int nrows)); +/* Flush the current PNG output buffer */ +extern PNG_EXPORT(void,png_write_flush) PNGARG((png_structp png_ptr)); +#endif + +/* optional update palette with requested transformations */ +extern PNG_EXPORT(void,png_start_read_image) PNGARG((png_structp png_ptr)); + +/* optional call to update the users info structure */ +extern PNG_EXPORT(void,png_read_update_info) PNGARG((png_structp png_ptr, + png_infop info_ptr)); + +#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED +/* read one or more rows of image data. */ +extern PNG_EXPORT(void,png_read_rows) PNGARG((png_structp png_ptr, + png_bytepp row, png_bytepp display_row, png_uint_32 num_rows)); +#endif + +#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED +/* read a row of data. */ +extern PNG_EXPORT(void,png_read_row) PNGARG((png_structp png_ptr, + png_bytep row, + png_bytep display_row)); +#endif + +#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED +/* read the whole image into memory at once. */ +extern PNG_EXPORT(void,png_read_image) PNGARG((png_structp png_ptr, + png_bytepp image)); +#endif + +/* write a row of image data */ +extern PNG_EXPORT(void,png_write_row) PNGARG((png_structp png_ptr, + png_bytep row)); + +/* write a few rows of image data */ +extern PNG_EXPORT(void,png_write_rows) PNGARG((png_structp png_ptr, + png_bytepp row, png_uint_32 num_rows)); + +/* write the image data */ +extern PNG_EXPORT(void,png_write_image) PNGARG((png_structp png_ptr, + png_bytepp image)); + +/* writes the end of the PNG file. */ +extern PNG_EXPORT(void,png_write_end) PNGARG((png_structp png_ptr, + png_infop info_ptr)); + +#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED +/* read the end of the PNG file. */ +extern PNG_EXPORT(void,png_read_end) PNGARG((png_structp png_ptr, + png_infop info_ptr)); +#endif + +/* free any memory associated with the png_info_struct */ +extern PNG_EXPORT(void,png_destroy_info_struct) PNGARG((png_structp png_ptr, + png_infopp info_ptr_ptr)); + +/* free any memory associated with the png_struct and the png_info_structs */ +extern PNG_EXPORT(void,png_destroy_read_struct) PNGARG((png_structpp + png_ptr_ptr, png_infopp info_ptr_ptr, png_infopp end_info_ptr_ptr)); + +/* free all memory used by the read (old method - NOT DLL EXPORTED) */ +extern void png_read_destroy PNGARG((png_structp png_ptr, png_infop info_ptr, + png_infop end_info_ptr)); + +/* free any memory associated with the png_struct and the png_info_structs */ +extern PNG_EXPORT(void,png_destroy_write_struct) + PNGARG((png_structpp png_ptr_ptr, png_infopp info_ptr_ptr)); + +/* free any memory used in png_ptr struct (old method - NOT DLL EXPORTED) */ +extern void png_write_destroy PNGARG((png_structp png_ptr)); + +/* set the libpng method of handling chunk CRC errors */ +extern PNG_EXPORT(void,png_set_crc_action) PNGARG((png_structp png_ptr, + int crit_action, int ancil_action)); + +/* Values for png_set_crc_action() to say how to handle CRC errors in + * ancillary and critical chunks, and whether to use the data contained + * therein. Note that it is impossible to "discard" data in a critical + * chunk. For versions prior to 0.90, the action was always error/quit, + * whereas in version 0.90 and later, the action for CRC errors in ancillary + * chunks is warn/discard. These values should NOT be changed. + * + * value action:critical action:ancillary + */ +#define PNG_CRC_DEFAULT 0 /* error/quit warn/discard data */ +#define PNG_CRC_ERROR_QUIT 1 /* error/quit error/quit */ +#define PNG_CRC_WARN_DISCARD 2 /* (INVALID) warn/discard data */ +#define PNG_CRC_WARN_USE 3 /* warn/use data warn/use data */ +#define PNG_CRC_QUIET_USE 4 /* quiet/use data quiet/use data */ +#define PNG_CRC_NO_CHANGE 5 /* use current value use current value */ + +/* These functions give the user control over the scan-line filtering in + * libpng and the compression methods used by zlib. These functions are + * mainly useful for testing, as the defaults should work with most users. + * Those users who are tight on memory or want faster performance at the + * expense of compression can modify them. See the compression library + * header file (zlib.h) for an explination of the compression functions. + */ + +/* set the filtering method(s) used by libpng. Currently, the only valid + * value for "method" is 0. + */ +extern PNG_EXPORT(void,png_set_filter) PNGARG((png_structp png_ptr, int method, + int filters)); + +/* Flags for png_set_filter() to say which filters to use. The flags + * are chosen so that they don't conflict with real filter types + * below, in case they are supplied instead of the #defined constants. + * These values should NOT be changed. + */ +#define PNG_NO_FILTERS 0x00 +#define PNG_FILTER_NONE 0x08 +#define PNG_FILTER_SUB 0x10 +#define PNG_FILTER_UP 0x20 +#define PNG_FILTER_AVG 0x40 +#define PNG_FILTER_PAETH 0x80 +#define PNG_ALL_FILTERS (PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP | \ + PNG_FILTER_AVG | PNG_FILTER_PAETH) + +/* Filter values (not flags) - used in pngwrite.c, pngwutil.c for now. + * These defines should NOT be changed. + */ +#define PNG_FILTER_VALUE_NONE 0 +#define PNG_FILTER_VALUE_SUB 1 +#define PNG_FILTER_VALUE_UP 2 +#define PNG_FILTER_VALUE_AVG 3 +#define PNG_FILTER_VALUE_PAETH 4 +#define PNG_FILTER_VALUE_LAST 5 + +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) /* EXPERIMENTAL */ +/* The "heuristic_method" is given by one of the PNG_FILTER_HEURISTIC_ + * defines, either the default (minimum-sum-of-absolute-differences), or + * the experimental method (weighted-minimum-sum-of-absolute-differences). + * + * Weights are factors >= 1.0, indicating how important it is to keep the + * filter type consistent between rows. Larger numbers mean the current + * filter is that many times as likely to be the same as the "num_weights" + * previous filters. This is cumulative for each previous row with a weight. + * There needs to be "num_weights" values in "filter_weights", or it can be + * NULL if the weights aren't being specified. Weights have no influence on + * the selection of the first row filter. Well chosen weights can (in theory) + * improve the compression for a given image. + * + * Costs are factors >= 1.0 indicating the relative decoding costs of a + * filter type. Higher costs indicate more decoding expense, and are + * therefore less likely to be selected over a filter with lower computational + * costs. There needs to be a value in "filter_costs" for each valid filter + * type (given by PNG_FILTER_VALUE_LAST), or it can be NULL if you aren't + * setting the costs. Costs try to improve the speed of decompression without + * unduly increasing the compressed image size. + * + * A negative weight or cost indicates the default value is to be used, and + * values in the range [0.0, 1.0) indicate the value is to remain unchanged. + * The default values for both weights and costs are currently 1.0, but may + * change if good general weighting/cost heuristics can be found. If both + * the weights and costs are set to 1.0, this degenerates the WEIGHTED method + * to the UNWEIGHTED method, but with added encoding time/computation. + */ +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(void,png_set_filter_heuristics) PNGARG((png_structp png_ptr, + int heuristic_method, int num_weights, png_doublep filter_weights, + png_doublep filter_costs)); +#endif +#endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */ + +/* Heuristic used for row filter selection. These defines should NOT be + * changed. + */ +#define PNG_FILTER_HEURISTIC_DEFAULT 0 /* Currently "UNWEIGHTED" */ +#define PNG_FILTER_HEURISTIC_UNWEIGHTED 1 /* Used by libpng < 0.95 */ +#define PNG_FILTER_HEURISTIC_WEIGHTED 2 /* Experimental feature */ +#define PNG_FILTER_HEURISTIC_LAST 3 /* Not a valid value */ + +/* Set the library compression level. Currently, valid values range from + * 0 - 9, corresponding directly to the zlib compression levels 0 - 9 + * (0 - no compression, 9 - "maximal" compression). Note that tests have + * shown that zlib compression levels 3-6 usually perform as well as level 9 + * for PNG images, and do considerably fewer caclulations. In the future, + * these values may not correspond directly to the zlib compression levels. + */ +extern PNG_EXPORT(void,png_set_compression_level) PNGARG((png_structp png_ptr, + int level)); + +extern PNG_EXPORT(void,png_set_compression_mem_level) + PNGARG((png_structp png_ptr, int mem_level)); + +extern PNG_EXPORT(void,png_set_compression_strategy) + PNGARG((png_structp png_ptr, int strategy)); + +extern PNG_EXPORT(void,png_set_compression_window_bits) + PNGARG((png_structp png_ptr, int window_bits)); + +extern PNG_EXPORT(void,png_set_compression_method) PNGARG((png_structp png_ptr, + int method)); + +/* These next functions are called for input/output, memory, and error + * handling. They are in the file pngrio.c, pngwio.c, and pngerror.c, + * and call standard C I/O routines such as fread(), fwrite(), and + * fprintf(). These functions can be made to use other I/O routines + * at run time for those applications that need to handle I/O in a + * different manner by calling png_set_???_fn(). See libpng.txt for + * more information. + */ + +#if !defined(PNG_NO_STDIO) +/* Initialize the input/output for the PNG file to the default functions. */ +extern PNG_EXPORT(void,png_init_io) PNGARG((png_structp png_ptr, png_FILE_p fp)); +#endif + +/* Replace the (error and abort), and warning functions with user + * supplied functions. If no messages are to be printed you must still + * write and use replacement functions. The replacement error_fn should + * still do a longjmp to the last setjmp location if you are using this + * method of error handling. If error_fn or warning_fn is NULL, the + * default function will be used. + */ + +extern PNG_EXPORT(void,png_set_error_fn) PNGARG((png_structp png_ptr, + png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warning_fn)); + +/* Return the user pointer associated with the error functions */ +extern PNG_EXPORT(png_voidp,png_get_error_ptr) PNGARG((png_structp png_ptr)); + +/* Replace the default data output functions with a user supplied one(s). + * If buffered output is not used, then output_flush_fn can be set to NULL. + * If PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile time + * output_flush_fn will be ignored (and thus can be NULL). + */ +extern PNG_EXPORT(void,png_set_write_fn) PNGARG((png_structp png_ptr, + png_voidp io_ptr, png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn)); + +/* Replace the default data input function with a user supplied one. */ +extern PNG_EXPORT(void,png_set_read_fn) PNGARG((png_structp png_ptr, + png_voidp io_ptr, png_rw_ptr read_data_fn)); + +/* Return the user pointer associated with the I/O functions */ +extern PNG_EXPORT(png_voidp,png_get_io_ptr) PNGARG((png_structp png_ptr)); + +extern PNG_EXPORT(void,png_set_read_status_fn) PNGARG((png_structp png_ptr, + png_read_status_ptr read_row_fn)); + +extern PNG_EXPORT(void,png_set_write_status_fn) PNGARG((png_structp png_ptr, + png_write_status_ptr write_row_fn)); + +#ifdef PNG_USER_MEM_SUPPORTED +/* Replace the default memory allocation functions with user supplied one(s). */ +extern PNG_EXPORT(void,png_set_mem_fn) PNGARG((png_structp png_ptr, + png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn)); +/* Return the user pointer associated with the memory functions */ +extern PNG_EXPORT(png_voidp,png_get_mem_ptr) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_LEGACY_SUPPORTED) +extern PNG_EXPORT(void,png_set_read_user_transform_fn) PNGARG((png_structp + png_ptr, png_user_transform_ptr read_user_transform_fn)); +#endif + +#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_LEGACY_SUPPORTED) +extern PNG_EXPORT(void,png_set_write_user_transform_fn) PNGARG((png_structp + png_ptr, png_user_transform_ptr write_user_transform_fn)); +#endif + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_LEGACY_SUPPORTED) +extern PNG_EXPORT(void,png_set_user_transform_info) PNGARG((png_structp + png_ptr, png_voidp user_transform_ptr, int user_transform_depth, + int user_transform_channels)); +/* Return the user pointer associated with the user transform functions */ +extern PNG_EXPORT(png_voidp,png_get_user_transform_ptr) + PNGARG((png_structp png_ptr)); +#endif + +#ifdef PNG_USER_CHUNKS_SUPPORTED +extern PNG_EXPORT(void,png_set_read_user_chunk_fn) PNGARG((png_structp png_ptr, + png_voidp user_chunk_ptr, png_user_chunk_ptr read_user_chunk_fn)); +extern PNG_EXPORT(png_voidp,png_get_user_chunk_ptr) PNGARG((png_structp + png_ptr)); +#endif + +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +/* Sets the function callbacks for the push reader, and a pointer to a + * user-defined structure available to the callback functions. + */ +extern PNG_EXPORT(void,png_set_progressive_read_fn) PNGARG((png_structp png_ptr, + png_voidp progressive_ptr, + png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn, + png_progressive_end_ptr end_fn)); + +/* returns the user pointer associated with the push read functions */ +extern PNG_EXPORT(png_voidp,png_get_progressive_ptr) + PNGARG((png_structp png_ptr)); + +/* function to be called when data becomes available */ +extern PNG_EXPORT(void,png_process_data) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_bytep buffer, png_size_t buffer_size)); + +/* function that combines rows. Not very much different than the + * png_combine_row() call. Is this even used????? + */ +extern PNG_EXPORT(void,png_progressive_combine_row) PNGARG((png_structp png_ptr, + png_bytep old_row, png_bytep new_row)); +#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ + +extern PNG_EXPORT(png_voidp,png_malloc) PNGARG((png_structp png_ptr, + png_uint_32 size)); + +#if defined(PNG_1_0_X) +# define png_malloc_warn png_malloc +#else +/* Added at libpng version 1.2.4 */ +extern PNG_EXPORT(png_voidp,png_malloc_warn) PNGARG((png_structp png_ptr, + png_uint_32 size)); +#endif + +/* frees a pointer allocated by png_malloc() */ +extern PNG_EXPORT(void,png_free) PNGARG((png_structp png_ptr, png_voidp ptr)); + +#if defined(PNG_1_0_X) +/* Function to allocate memory for zlib. */ +extern PNG_EXPORT(voidpf,png_zalloc) PNGARG((voidpf png_ptr, uInt items, + uInt size)); + +/* Function to free memory for zlib */ +extern PNG_EXPORT(void,png_zfree) PNGARG((voidpf png_ptr, voidpf ptr)); +#endif + +/* Free data that was allocated internally */ +extern PNG_EXPORT(void,png_free_data) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 free_me, int num)); +#ifdef PNG_FREE_ME_SUPPORTED +/* Reassign responsibility for freeing existing data, whether allocated + * by libpng or by the application */ +extern PNG_EXPORT(void,png_data_freer) PNGARG((png_structp png_ptr, + png_infop info_ptr, int freer, png_uint_32 mask)); +#endif +/* assignments for png_data_freer */ +#define PNG_DESTROY_WILL_FREE_DATA 1 +#define PNG_SET_WILL_FREE_DATA 1 +#define PNG_USER_WILL_FREE_DATA 2 +/* Flags for png_ptr->free_me and info_ptr->free_me */ +#define PNG_FREE_HIST 0x0008 +#define PNG_FREE_ICCP 0x0010 +#define PNG_FREE_SPLT 0x0020 +#define PNG_FREE_ROWS 0x0040 +#define PNG_FREE_PCAL 0x0080 +#define PNG_FREE_SCAL 0x0100 +#define PNG_FREE_UNKN 0x0200 +#define PNG_FREE_LIST 0x0400 +#define PNG_FREE_PLTE 0x1000 +#define PNG_FREE_TRNS 0x2000 +#define PNG_FREE_TEXT 0x4000 +#define PNG_FREE_ALL 0x7fff +#define PNG_FREE_MUL 0x4220 /* PNG_FREE_SPLT|PNG_FREE_TEXT|PNG_FREE_UNKN */ + +#ifdef PNG_USER_MEM_SUPPORTED +extern PNG_EXPORT(png_voidp,png_malloc_default) PNGARG((png_structp png_ptr, + png_uint_32 size)); +extern PNG_EXPORT(void,png_free_default) PNGARG((png_structp png_ptr, + png_voidp ptr)); +#endif + +extern PNG_EXPORT(png_voidp,png_memcpy_check) PNGARG((png_structp png_ptr, + png_voidp s1, png_voidp s2, png_uint_32 size)); + +extern PNG_EXPORT(png_voidp,png_memset_check) PNGARG((png_structp png_ptr, + png_voidp s1, int value, png_uint_32 size)); + +#if defined(USE_FAR_KEYWORD) /* memory model conversion function */ +extern void *png_far_to_near PNGARG((png_structp png_ptr,png_voidp ptr, + int check)); +#endif /* USE_FAR_KEYWORD */ + +/* Fatal error in PNG image of libpng - can't continue */ +extern PNG_EXPORT(void,png_error) PNGARG((png_structp png_ptr, + png_const_charp error_message)); + +/* The same, but the chunk name is prepended to the error string. */ +extern PNG_EXPORT(void,png_chunk_error) PNGARG((png_structp png_ptr, + png_const_charp error_message)); + +/* Non-fatal error in libpng. Can continue, but may have a problem. */ +extern PNG_EXPORT(void,png_warning) PNGARG((png_structp png_ptr, + png_const_charp warning_message)); + +/* Non-fatal error in libpng, chunk name is prepended to message. */ +extern PNG_EXPORT(void,png_chunk_warning) PNGARG((png_structp png_ptr, + png_const_charp warning_message)); + +/* The png_set_<chunk> functions are for storing values in the png_info_struct. + * Similarly, the png_get_<chunk> calls are used to read values from the + * png_info_struct, either storing the parameters in the passed variables, or + * setting pointers into the png_info_struct where the data is stored. The + * png_get_<chunk> functions return a non-zero value if the data was available + * in info_ptr, or return zero and do not change any of the parameters if the + * data was not available. + * + * These functions should be used instead of directly accessing png_info + * to avoid problems with future changes in the size and internal layout of + * png_info_struct. + */ +/* Returns "flag" if chunk data is valid in info_ptr. */ +extern PNG_EXPORT(png_uint_32,png_get_valid) PNGARG((png_structp png_ptr, +png_infop info_ptr, png_uint_32 flag)); + +/* Returns number of bytes needed to hold a transformed row. */ +extern PNG_EXPORT(png_uint_32,png_get_rowbytes) PNGARG((png_structp png_ptr, +png_infop info_ptr)); + +#if defined(PNG_INFO_IMAGE_SUPPORTED) +/* Returns row_pointers, which is an array of pointers to scanlines that was +returned from png_read_png(). */ +extern PNG_EXPORT(png_bytepp,png_get_rows) PNGARG((png_structp png_ptr, +png_infop info_ptr)); +/* Set row_pointers, which is an array of pointers to scanlines for use +by png_write_png(). */ +extern PNG_EXPORT(void,png_set_rows) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_bytepp row_pointers)); +#endif + +/* Returns number of color channels in image. */ +extern PNG_EXPORT(png_byte,png_get_channels) PNGARG((png_structp png_ptr, +png_infop info_ptr)); + +#ifdef PNG_EASY_ACCESS_SUPPORTED +/* Returns image width in pixels. */ +extern PNG_EXPORT(png_uint_32, png_get_image_width) PNGARG((png_structp +png_ptr, png_infop info_ptr)); + +/* Returns image height in pixels. */ +extern PNG_EXPORT(png_uint_32, png_get_image_height) PNGARG((png_structp +png_ptr, png_infop info_ptr)); + +/* Returns image bit_depth. */ +extern PNG_EXPORT(png_byte, png_get_bit_depth) PNGARG((png_structp +png_ptr, png_infop info_ptr)); + +/* Returns image color_type. */ +extern PNG_EXPORT(png_byte, png_get_color_type) PNGARG((png_structp +png_ptr, png_infop info_ptr)); + +/* Returns image filter_type. */ +extern PNG_EXPORT(png_byte, png_get_filter_type) PNGARG((png_structp +png_ptr, png_infop info_ptr)); + +/* Returns image interlace_type. */ +extern PNG_EXPORT(png_byte, png_get_interlace_type) PNGARG((png_structp +png_ptr, png_infop info_ptr)); + +/* Returns image compression_type. */ +extern PNG_EXPORT(png_byte, png_get_compression_type) PNGARG((png_structp +png_ptr, png_infop info_ptr)); + +/* Returns image resolution in pixels per meter, from pHYs chunk data. */ +extern PNG_EXPORT(png_uint_32, png_get_pixels_per_meter) PNGARG((png_structp +png_ptr, png_infop info_ptr)); +extern PNG_EXPORT(png_uint_32, png_get_x_pixels_per_meter) PNGARG((png_structp +png_ptr, png_infop info_ptr)); +extern PNG_EXPORT(png_uint_32, png_get_y_pixels_per_meter) PNGARG((png_structp +png_ptr, png_infop info_ptr)); + +/* Returns pixel aspect ratio, computed from pHYs chunk data. */ +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(float, png_get_pixel_aspect_ratio) PNGARG((png_structp +png_ptr, png_infop info_ptr)); +#endif + +/* Returns image x, y offset in pixels or microns, from oFFs chunk data. */ +extern PNG_EXPORT(png_int_32, png_get_x_offset_pixels) PNGARG((png_structp +png_ptr, png_infop info_ptr)); +extern PNG_EXPORT(png_int_32, png_get_y_offset_pixels) PNGARG((png_structp +png_ptr, png_infop info_ptr)); +extern PNG_EXPORT(png_int_32, png_get_x_offset_microns) PNGARG((png_structp +png_ptr, png_infop info_ptr)); +extern PNG_EXPORT(png_int_32, png_get_y_offset_microns) PNGARG((png_structp +png_ptr, png_infop info_ptr)); + +#endif /* PNG_EASY_ACCESS_SUPPORTED */ + +/* Returns pointer to signature string read from PNG header */ +extern PNG_EXPORT(png_bytep,png_get_signature) PNGARG((png_structp png_ptr, +png_infop info_ptr)); + +#if defined(PNG_bKGD_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_bKGD) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_color_16p *background)); +#endif + +#if defined(PNG_bKGD_SUPPORTED) +extern PNG_EXPORT(void,png_set_bKGD) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_color_16p background)); +#endif + +#if defined(PNG_cHRM_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(png_uint_32,png_get_cHRM) PNGARG((png_structp png_ptr, + png_infop info_ptr, double *white_x, double *white_y, double *red_x, + double *red_y, double *green_x, double *green_y, double *blue_x, + double *blue_y)); +#endif +#ifdef PNG_FIXED_POINT_SUPPORTED +extern PNG_EXPORT(png_uint_32,png_get_cHRM_fixed) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_fixed_point *int_white_x, png_fixed_point + *int_white_y, png_fixed_point *int_red_x, png_fixed_point *int_red_y, + png_fixed_point *int_green_x, png_fixed_point *int_green_y, png_fixed_point + *int_blue_x, png_fixed_point *int_blue_y)); +#endif +#endif + +#if defined(PNG_cHRM_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(void,png_set_cHRM) PNGARG((png_structp png_ptr, + png_infop info_ptr, double white_x, double white_y, double red_x, + double red_y, double green_x, double green_y, double blue_x, double blue_y)); +#endif +#ifdef PNG_FIXED_POINT_SUPPORTED +extern PNG_EXPORT(void,png_set_cHRM_fixed) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_fixed_point int_white_x, png_fixed_point int_white_y, + png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point + int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x, + png_fixed_point int_blue_y)); +#endif +#endif + +#if defined(PNG_gAMA_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(png_uint_32,png_get_gAMA) PNGARG((png_structp png_ptr, + png_infop info_ptr, double *file_gamma)); +#endif +extern PNG_EXPORT(png_uint_32,png_get_gAMA_fixed) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_fixed_point *int_file_gamma)); +#endif + +#if defined(PNG_gAMA_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(void,png_set_gAMA) PNGARG((png_structp png_ptr, + png_infop info_ptr, double file_gamma)); +#endif +extern PNG_EXPORT(void,png_set_gAMA_fixed) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_fixed_point int_file_gamma)); +#endif + +#if defined(PNG_hIST_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_hIST) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_16p *hist)); +#endif + +#if defined(PNG_hIST_SUPPORTED) +extern PNG_EXPORT(void,png_set_hIST) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_16p hist)); +#endif + +extern PNG_EXPORT(png_uint_32,png_get_IHDR) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 *width, png_uint_32 *height, + int *bit_depth, int *color_type, int *interlace_method, + int *compression_method, int *filter_method)); + +extern PNG_EXPORT(void,png_set_IHDR) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 width, png_uint_32 height, int bit_depth, + int color_type, int interlace_method, int compression_method, + int filter_method)); + +#if defined(PNG_oFFs_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_oFFs) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_int_32 *offset_x, png_int_32 *offset_y, + int *unit_type)); +#endif + +#if defined(PNG_oFFs_SUPPORTED) +extern PNG_EXPORT(void,png_set_oFFs) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_int_32 offset_x, png_int_32 offset_y, + int unit_type)); +#endif + +#if defined(PNG_pCAL_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_pCAL) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_charp *purpose, png_int_32 *X0, png_int_32 *X1, + int *type, int *nparams, png_charp *units, png_charpp *params)); +#endif + +#if defined(PNG_pCAL_SUPPORTED) +extern PNG_EXPORT(void,png_set_pCAL) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_charp purpose, png_int_32 X0, png_int_32 X1, + int type, int nparams, png_charp units, png_charpp params)); +#endif + +#if defined(PNG_pHYs_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_pHYs) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)); +#endif + +#if defined(PNG_pHYs_SUPPORTED) +extern PNG_EXPORT(void,png_set_pHYs) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 res_x, png_uint_32 res_y, int unit_type)); +#endif + +extern PNG_EXPORT(png_uint_32,png_get_PLTE) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_colorp *palette, int *num_palette)); + +extern PNG_EXPORT(void,png_set_PLTE) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_colorp palette, int num_palette)); + +#if defined(PNG_sBIT_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_sBIT) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_color_8p *sig_bit)); +#endif + +#if defined(PNG_sBIT_SUPPORTED) +extern PNG_EXPORT(void,png_set_sBIT) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_color_8p sig_bit)); +#endif + +#if defined(PNG_sRGB_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_sRGB) PNGARG((png_structp png_ptr, + png_infop info_ptr, int *intent)); +#endif + +#if defined(PNG_sRGB_SUPPORTED) +extern PNG_EXPORT(void,png_set_sRGB) PNGARG((png_structp png_ptr, + png_infop info_ptr, int intent)); +extern PNG_EXPORT(void,png_set_sRGB_gAMA_and_cHRM) PNGARG((png_structp png_ptr, + png_infop info_ptr, int intent)); +#endif + +#if defined(PNG_iCCP_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_iCCP) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_charpp name, int *compression_type, + png_charpp profile, png_uint_32 *proflen)); + /* Note to maintainer: profile should be png_bytepp */ +#endif + +#if defined(PNG_iCCP_SUPPORTED) +extern PNG_EXPORT(void,png_set_iCCP) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_charp name, int compression_type, + png_charp profile, png_uint_32 proflen)); + /* Note to maintainer: profile should be png_bytep */ +#endif + +#if defined(PNG_sPLT_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_sPLT) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_sPLT_tpp entries)); +#endif + +#if defined(PNG_sPLT_SUPPORTED) +extern PNG_EXPORT(void,png_set_sPLT) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_sPLT_tp entries, int nentries)); +#endif + +#if defined(PNG_TEXT_SUPPORTED) +/* png_get_text also returns the number of text chunks in *num_text */ +extern PNG_EXPORT(png_uint_32,png_get_text) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_textp *text_ptr, int *num_text)); +#endif + +/* + * Note while png_set_text() will accept a structure whose text, + * language, and translated keywords are NULL pointers, the structure + * returned by png_get_text will always contain regular + * zero-terminated C strings. They might be empty strings but + * they will never be NULL pointers. + */ + +#if defined(PNG_TEXT_SUPPORTED) +extern PNG_EXPORT(void,png_set_text) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_textp text_ptr, int num_text)); +#endif + +#if defined(PNG_tIME_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_tIME) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_timep *mod_time)); +#endif + +#if defined(PNG_tIME_SUPPORTED) +extern PNG_EXPORT(void,png_set_tIME) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_timep mod_time)); +#endif + +#if defined(PNG_tRNS_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_tRNS) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_bytep *trans, int *num_trans, + png_color_16p *trans_values)); +#endif + +#if defined(PNG_tRNS_SUPPORTED) +extern PNG_EXPORT(void,png_set_tRNS) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_bytep trans, int num_trans, + png_color_16p trans_values)); +#endif + +#if defined(PNG_tRNS_SUPPORTED) +#endif + +#if defined(PNG_sCAL_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(png_uint_32,png_get_sCAL) PNGARG((png_structp png_ptr, + png_infop info_ptr, int *unit, double *width, double *height)); +#else +#ifdef PNG_FIXED_POINT_SUPPORTED +extern PNG_EXPORT(png_uint_32,png_get_sCAL_s) PNGARG((png_structp png_ptr, + png_infop info_ptr, int *unit, png_charpp swidth, png_charpp sheight)); +#endif +#endif +#endif /* PNG_sCAL_SUPPORTED */ + +#if defined(PNG_sCAL_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(void,png_set_sCAL) PNGARG((png_structp png_ptr, + png_infop info_ptr, int unit, double width, double height)); +#else +#ifdef PNG_FIXED_POINT_SUPPORTED +extern PNG_EXPORT(void,png_set_sCAL_s) PNGARG((png_structp png_ptr, + png_infop info_ptr, int unit, png_charp swidth, png_charp sheight)); +#endif +#endif +#endif /* PNG_sCAL_SUPPORTED || PNG_WRITE_sCAL_SUPPORTED */ + +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) +/* provide a list of chunks and how they are to be handled, if the built-in + handling or default unknown chunk handling is not desired. Any chunks not + listed will be handled in the default manner. The IHDR and IEND chunks + must not be listed. + keep = 0: follow default behavour + = 1: do not keep + = 2: keep only if safe-to-copy + = 3: keep even if unsafe-to-copy +*/ +extern PNG_EXPORT(void, png_set_keep_unknown_chunks) PNGARG((png_structp + png_ptr, int keep, png_bytep chunk_list, int num_chunks)); +extern PNG_EXPORT(void, png_set_unknown_chunks) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_unknown_chunkp unknowns, int num_unknowns)); +extern PNG_EXPORT(void, png_set_unknown_chunk_location) + PNGARG((png_structp png_ptr, png_infop info_ptr, int chunk, int location)); +extern PNG_EXPORT(png_uint_32,png_get_unknown_chunks) PNGARG((png_structp + png_ptr, png_infop info_ptr, png_unknown_chunkpp entries)); +#endif +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED +PNG_EXPORT(int,png_handle_as_unknown) PNGARG((png_structp png_ptr, png_bytep + chunk_name)); +#endif + +/* Png_free_data() will turn off the "valid" flag for anything it frees. + If you need to turn it off for a chunk that your application has freed, + you can use png_set_invalid(png_ptr, info_ptr, PNG_INFO_CHNK); */ +extern PNG_EXPORT(void, png_set_invalid) PNGARG((png_structp png_ptr, + png_infop info_ptr, int mask)); + +#if defined(PNG_INFO_IMAGE_SUPPORTED) +/* The "params" pointer is currently not used and is for future expansion. */ +extern PNG_EXPORT(void, png_read_png) PNGARG((png_structp png_ptr, + png_infop info_ptr, + int transforms, + png_voidp params)); +extern PNG_EXPORT(void, png_write_png) PNGARG((png_structp png_ptr, + png_infop info_ptr, + int transforms, + png_voidp params)); +#endif + +/* Define PNG_DEBUG at compile time for debugging information. Higher + * numbers for PNG_DEBUG mean more debugging information. This has + * only been added since version 0.95 so it is not implemented throughout + * libpng yet, but more support will be added as needed. + */ +#ifdef PNG_DEBUG +#if (PNG_DEBUG > 0) +#if !defined(PNG_DEBUG_FILE) && defined(_MSC_VER) +#include <crtdbg.h> +#if (PNG_DEBUG > 1) +#define png_debug(l,m) _RPT0(_CRT_WARN,m) +#define png_debug1(l,m,p1) _RPT1(_CRT_WARN,m,p1) +#define png_debug2(l,m,p1,p2) _RPT2(_CRT_WARN,m,p1,p2) +#endif +#else /* PNG_DEBUG_FILE || !_MSC_VER */ +#ifndef PNG_DEBUG_FILE +#define PNG_DEBUG_FILE stderr +#endif /* PNG_DEBUG_FILE */ +#if (PNG_DEBUG > 1) +#define png_debug(l,m) \ +{ \ + int num_tabs=l; \ + fprintf(PNG_DEBUG_FILE,"%s"m,(num_tabs==1 ? "\t" : \ + (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":"")))); \ +} +#define png_debug1(l,m,p1) \ +{ \ + int num_tabs=l; \ + fprintf(PNG_DEBUG_FILE,"%s"m,(num_tabs==1 ? "\t" : \ + (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1); \ +} +#define png_debug2(l,m,p1,p2) \ +{ \ + int num_tabs=l; \ + fprintf(PNG_DEBUG_FILE,"%s"m,(num_tabs==1 ? "\t" : \ + (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1,p2); \ +} +#endif /* (PNG_DEBUG > 1) */ +#endif /* _MSC_VER */ +#endif /* (PNG_DEBUG > 0) */ +#endif /* PNG_DEBUG */ +#ifndef png_debug +#define png_debug(l, m) +#endif +#ifndef png_debug1 +#define png_debug1(l, m, p1) +#endif +#ifndef png_debug2 +#define png_debug2(l, m, p1, p2) +#endif + +#if 0 +extern PNG_EXPORT(png_bytep,png_sig_bytes) PNGARG((void)); +#endif + +extern PNG_EXPORT(png_charp,png_get_copyright) PNGARG((png_structp png_ptr)); +extern PNG_EXPORT(png_charp,png_get_header_ver) PNGARG((png_structp png_ptr)); +extern PNG_EXPORT(png_charp,png_get_header_version) PNGARG((png_structp png_ptr)); +extern PNG_EXPORT(png_charp,png_get_libpng_ver) PNGARG((png_structp png_ptr)); + +#ifdef PNG_MNG_FEATURES_SUPPORTED +extern PNG_EXPORT(png_uint_32,png_permit_mng_features) PNGARG((png_structp + png_ptr, png_uint_32 mng_features_permitted)); +#endif + +/* For use in png_set_keep_unknown, added to version 1.2.6 */ +#define PNG_HANDLE_CHUNK_AS_DEFAULT 0 +#define PNG_HANDLE_CHUNK_NEVER 1 +#define PNG_HANDLE_CHUNK_IF_SAFE 2 +#define PNG_HANDLE_CHUNK_ALWAYS 3 + +/* Added to version 1.2.0 */ +#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) +#define PNG_ASM_FLAG_MMX_SUPPORT_COMPILED 0x01 /* not user-settable */ +#define PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU 0x02 /* not user-settable */ +#define PNG_ASM_FLAG_MMX_READ_COMBINE_ROW 0x04 +#define PNG_ASM_FLAG_MMX_READ_INTERLACE 0x08 +#define PNG_ASM_FLAG_MMX_READ_FILTER_SUB 0x10 +#define PNG_ASM_FLAG_MMX_READ_FILTER_UP 0x20 +#define PNG_ASM_FLAG_MMX_READ_FILTER_AVG 0x40 +#define PNG_ASM_FLAG_MMX_READ_FILTER_PAETH 0x80 +#define PNG_ASM_FLAGS_INITIALIZED 0x80000000 /* not user-settable */ + +#define PNG_MMX_READ_FLAGS ( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW \ + | PNG_ASM_FLAG_MMX_READ_INTERLACE \ + | PNG_ASM_FLAG_MMX_READ_FILTER_SUB \ + | PNG_ASM_FLAG_MMX_READ_FILTER_UP \ + | PNG_ASM_FLAG_MMX_READ_FILTER_AVG \ + | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ) +#define PNG_MMX_WRITE_FLAGS ( 0 ) + +#define PNG_MMX_FLAGS ( PNG_ASM_FLAG_MMX_SUPPORT_COMPILED \ + | PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU \ + | PNG_MMX_READ_FLAGS \ + | PNG_MMX_WRITE_FLAGS ) + +#define PNG_SELECT_READ 1 +#define PNG_SELECT_WRITE 2 + +#if !defined(PNG_1_0_X) +/* pngget.c */ +extern PNG_EXPORT(png_uint_32,png_get_mmx_flagmask) + PNGARG((int flag_select, int *compilerID)); + +/* pngget.c */ +extern PNG_EXPORT(png_uint_32,png_get_asm_flagmask) + PNGARG((int flag_select)); + +/* pngget.c */ +extern PNG_EXPORT(png_uint_32,png_get_asm_flags) + PNGARG((png_structp png_ptr)); + +/* pngget.c */ +extern PNG_EXPORT(png_byte,png_get_mmx_bitdepth_threshold) + PNGARG((png_structp png_ptr)); + +/* pngget.c */ +extern PNG_EXPORT(png_uint_32,png_get_mmx_rowbytes_threshold) + PNGARG((png_structp png_ptr)); + +/* pngset.c */ +extern PNG_EXPORT(void,png_set_asm_flags) + PNGARG((png_structp png_ptr, png_uint_32 asm_flags)); + +/* pngset.c */ +extern PNG_EXPORT(void,png_set_mmx_thresholds) + PNGARG((png_structp png_ptr, png_byte mmx_bitdepth_threshold, + png_uint_32 mmx_rowbytes_threshold)); + +#endif /* PNG_1_0_X */ +#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ + +#if !defined(PNG_1_0_X) +/* png.c, pnggccrd.c, or pngvcrd.c */ +extern PNG_EXPORT(int,png_mmx_support) PNGARG((void)); + +/* Strip the prepended error numbers ("#nnn ") from error and warning + * messages before passing them to the error or warning handler. */ +#ifdef PNG_ERROR_NUMBERS_SUPPORTED +extern PNG_EXPORT(void,png_set_strip_error_numbers) PNGARG((png_structp + png_ptr, png_uint_32 strip_mode)); +#endif + +#endif /* PNG_1_0_X */ + +/* Added at libpng-1.2.6 */ +#ifdef PNG_SET_USER_LIMITS_SUPPORTED +extern PNG_EXPORT(void,png_set_user_limits) PNGARG((png_structp + png_ptr, png_uint_32 user_width_max, png_uint_32 user_height_max)); +extern PNG_EXPORT(png_uint_32,png_get_user_width_max) PNGARG((png_structp + png_ptr)); +extern PNG_EXPORT(png_uint_32,png_get_user_height_max) PNGARG((png_structp + png_ptr)); +#endif + +/* Maintainer: Put new public prototypes here ^, in libpng.3, and project defs */ + +#ifdef PNG_READ_COMPOSITE_NODIV_SUPPORTED +/* With these routines we avoid an integer divide, which will be slower on + * most machines. However, it does take more operations than the corresponding + * divide method, so it may be slower on a few RISC systems. There are two + * shifts (by 8 or 16 bits) and an addition, versus a single integer divide. + * + * Note that the rounding factors are NOT supposed to be the same! 128 and + * 32768 are correct for the NODIV code; 127 and 32767 are correct for the + * standard method. + * + * [Optimized code by Greg Roelofs and Mark Adler...blame us for bugs. :-) ] + */ + + /* fg and bg should be in `gamma 1.0' space; alpha is the opacity */ + +# define png_composite(composite, fg, alpha, bg) \ + { png_uint_16 temp = (png_uint_16)((png_uint_16)(fg) * (png_uint_16)(alpha) \ + + (png_uint_16)(bg)*(png_uint_16)(255 - \ + (png_uint_16)(alpha)) + (png_uint_16)128); \ + (composite) = (png_byte)((temp + (temp >> 8)) >> 8); } + +# define png_composite_16(composite, fg, alpha, bg) \ + { png_uint_32 temp = (png_uint_32)((png_uint_32)(fg) * (png_uint_32)(alpha) \ + + (png_uint_32)(bg)*(png_uint_32)(65535L - \ + (png_uint_32)(alpha)) + (png_uint_32)32768L); \ + (composite) = (png_uint_16)((temp + (temp >> 16)) >> 16); } + +#else /* standard method using integer division */ + +# define png_composite(composite, fg, alpha, bg) \ + (composite) = (png_byte)(((png_uint_16)(fg) * (png_uint_16)(alpha) + \ + (png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) + \ + (png_uint_16)127) / 255) + +# define png_composite_16(composite, fg, alpha, bg) \ + (composite) = (png_uint_16)(((png_uint_32)(fg) * (png_uint_32)(alpha) + \ + (png_uint_32)(bg)*(png_uint_32)(65535L - (png_uint_32)(alpha)) + \ + (png_uint_32)32767) / (png_uint_32)65535L) + +#endif /* PNG_READ_COMPOSITE_NODIV_SUPPORTED */ + +/* Inline macros to do direct reads of bytes from the input buffer. These + * require that you are using an architecture that uses PNG byte ordering + * (MSB first) and supports unaligned data storage. I think that PowerPC + * in big-endian mode and 680x0 are the only ones that will support this. + * The x86 line of processors definitely do not. The png_get_int_32() + * routine also assumes we are using two's complement format for negative + * values, which is almost certainly true. + */ +#if defined(PNG_READ_BIG_ENDIAN_SUPPORTED) +# define png_get_uint_32(buf) ( *((png_uint_32p) (buf))) +# define png_get_uint_16(buf) ( *((png_uint_16p) (buf))) +# define png_get_int_32(buf) ( *((png_int_32p) (buf))) +#else +extern PNG_EXPORT(png_uint_32,png_get_uint_32) PNGARG((png_bytep buf)); +extern PNG_EXPORT(png_uint_16,png_get_uint_16) PNGARG((png_bytep buf)); +extern PNG_EXPORT(png_int_32,png_get_int_32) PNGARG((png_bytep buf)); +#endif /* !PNG_READ_BIG_ENDIAN_SUPPORTED */ +extern PNG_EXPORT(png_uint_32,png_get_uint_31) + PNGARG((png_structp png_ptr, png_bytep buf)); +/* No png_get_int_16 -- may be added if there's a real need for it. */ + +/* Place a 32-bit number into a buffer in PNG byte order (big-endian). + */ +extern PNG_EXPORT(void,png_save_uint_32) + PNGARG((png_bytep buf, png_uint_32 i)); +extern PNG_EXPORT(void,png_save_int_32) + PNGARG((png_bytep buf, png_int_32 i)); + +/* Place a 16-bit number into a buffer in PNG byte order. + * The parameter is declared unsigned int, not png_uint_16, + * just to avoid potential problems on pre-ANSI C compilers. + */ +extern PNG_EXPORT(void,png_save_uint_16) + PNGARG((png_bytep buf, unsigned int i)); +/* No png_save_int_16 -- may be added if there's a real need for it. */ + +/* ************************************************************************* */ + +/* These next functions are used internally in the code. They generally + * shouldn't be used unless you are writing code to add or replace some + * functionality in libpng. More information about most functions can + * be found in the files where the functions are located. + */ + +#if defined(PNG_INTERNAL) + +/* Various modes of operation. Note that after an init, mode is set to + * zero automatically when the structure is created. + */ +#define PNG_HAVE_IHDR 0x01 +#define PNG_HAVE_PLTE 0x02 +#define PNG_HAVE_IDAT 0x04 +#define PNG_AFTER_IDAT 0x08 /* Have complete zlib datastream */ +#define PNG_HAVE_IEND 0x10 +#define PNG_HAVE_gAMA 0x20 +#define PNG_HAVE_cHRM 0x40 +#define PNG_HAVE_sRGB 0x80 +#define PNG_HAVE_CHUNK_HEADER 0x100 +#define PNG_WROTE_tIME 0x200 +#define PNG_WROTE_INFO_BEFORE_PLTE 0x400 +#define PNG_BACKGROUND_IS_GRAY 0x800 +#define PNG_HAVE_PNG_SIGNATURE 0x1000 +#define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000 /* Have another chunk after IDAT */ + +/* flags for the transformations the PNG library does on the image data */ +#define PNG_BGR 0x0001 +#define PNG_INTERLACE 0x0002 +#define PNG_PACK 0x0004 +#define PNG_SHIFT 0x0008 +#define PNG_SWAP_BYTES 0x0010 +#define PNG_INVERT_MONO 0x0020 +#define PNG_DITHER 0x0040 +#define PNG_BACKGROUND 0x0080 +#define PNG_BACKGROUND_EXPAND 0x0100 + /* 0x0200 unused */ +#define PNG_16_TO_8 0x0400 +#define PNG_RGBA 0x0800 +#define PNG_EXPAND 0x1000 +#define PNG_GAMMA 0x2000 +#define PNG_GRAY_TO_RGB 0x4000 +#define PNG_FILLER 0x8000L +#define PNG_PACKSWAP 0x10000L +#define PNG_SWAP_ALPHA 0x20000L +#define PNG_STRIP_ALPHA 0x40000L +#define PNG_INVERT_ALPHA 0x80000L +#define PNG_USER_TRANSFORM 0x100000L +#define PNG_RGB_TO_GRAY_ERR 0x200000L +#define PNG_RGB_TO_GRAY_WARN 0x400000L +#define PNG_RGB_TO_GRAY 0x600000L /* two bits, RGB_TO_GRAY_ERR|WARN */ + /* 0x800000L Unused */ +#define PNG_ADD_ALPHA 0x1000000L /* Added to libpng-1.2.7 */ +#define PNG_EXPAND_tRNS 0x2000000L /* Added to libpng-1.2.9 */ + /* 0x4000000L unused */ + /* 0x8000000L unused */ + /* 0x10000000L unused */ + /* 0x20000000L unused */ + /* 0x40000000L unused */ + +/* flags for png_create_struct */ +#define PNG_STRUCT_PNG 0x0001 +#define PNG_STRUCT_INFO 0x0002 + +/* Scaling factor for filter heuristic weighting calculations */ +#define PNG_WEIGHT_SHIFT 8 +#define PNG_WEIGHT_FACTOR (1<<(PNG_WEIGHT_SHIFT)) +#define PNG_COST_SHIFT 3 +#define PNG_COST_FACTOR (1<<(PNG_COST_SHIFT)) + +/* flags for the png_ptr->flags rather than declaring a byte for each one */ +#define PNG_FLAG_ZLIB_CUSTOM_STRATEGY 0x0001 +#define PNG_FLAG_ZLIB_CUSTOM_LEVEL 0x0002 +#define PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL 0x0004 +#define PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS 0x0008 +#define PNG_FLAG_ZLIB_CUSTOM_METHOD 0x0010 +#define PNG_FLAG_ZLIB_FINISHED 0x0020 +#define PNG_FLAG_ROW_INIT 0x0040 +#define PNG_FLAG_FILLER_AFTER 0x0080 +#define PNG_FLAG_CRC_ANCILLARY_USE 0x0100 +#define PNG_FLAG_CRC_ANCILLARY_NOWARN 0x0200 +#define PNG_FLAG_CRC_CRITICAL_USE 0x0400 +#define PNG_FLAG_CRC_CRITICAL_IGNORE 0x0800 +#define PNG_FLAG_FREE_PLTE 0x1000 +#define PNG_FLAG_FREE_TRNS 0x2000 +#define PNG_FLAG_FREE_HIST 0x4000 +#define PNG_FLAG_KEEP_UNKNOWN_CHUNKS 0x8000L +#define PNG_FLAG_KEEP_UNSAFE_CHUNKS 0x10000L +#define PNG_FLAG_LIBRARY_MISMATCH 0x20000L +#define PNG_FLAG_STRIP_ERROR_NUMBERS 0x40000L +#define PNG_FLAG_STRIP_ERROR_TEXT 0x80000L +#define PNG_FLAG_MALLOC_NULL_MEM_OK 0x100000L +#define PNG_FLAG_ADD_ALPHA 0x200000L /* Added to libpng-1.2.8 */ +#define PNG_FLAG_STRIP_ALPHA 0x400000L /* Added to libpng-1.2.8 */ + /* 0x800000L unused */ + /* 0x1000000L unused */ + /* 0x2000000L unused */ + /* 0x4000000L unused */ + /* 0x8000000L unused */ + /* 0x10000000L unused */ + /* 0x20000000L unused */ + /* 0x40000000L unused */ + +#define PNG_FLAG_CRC_ANCILLARY_MASK (PNG_FLAG_CRC_ANCILLARY_USE | \ + PNG_FLAG_CRC_ANCILLARY_NOWARN) + +#define PNG_FLAG_CRC_CRITICAL_MASK (PNG_FLAG_CRC_CRITICAL_USE | \ + PNG_FLAG_CRC_CRITICAL_IGNORE) + +#define PNG_FLAG_CRC_MASK (PNG_FLAG_CRC_ANCILLARY_MASK | \ + PNG_FLAG_CRC_CRITICAL_MASK) + +/* save typing and make code easier to understand */ + +#define PNG_COLOR_DIST(c1, c2) (abs((int)((c1).red) - (int)((c2).red)) + \ + abs((int)((c1).green) - (int)((c2).green)) + \ + abs((int)((c1).blue) - (int)((c2).blue))) + +/* Added to libpng-1.2.6 JB */ +#define PNG_ROWBYTES(pixel_bits, width) \ + ((pixel_bits) >= 8 ? \ + ((width) * (((png_uint_32)(pixel_bits)) >> 3)) : \ + (( ((width) * ((png_uint_32)(pixel_bits))) + 7) >> 3) ) + +/* PNG_OUT_OF_RANGE returns true if value is outside the range + ideal-delta..ideal+delta. Each argument is evaluated twice. + "ideal" and "delta" should be constants, normally simple + integers, "value" a variable. Added to libpng-1.2.6 JB */ +#define PNG_OUT_OF_RANGE(value, ideal, delta) \ + ( (value) < (ideal)-(delta) || (value) > (ideal)+(delta) ) + +/* variables declared in png.c - only it needs to define PNG_NO_EXTERN */ +#if !defined(PNG_NO_EXTERN) || defined(PNG_ALWAYS_EXTERN) +/* place to hold the signature string for a PNG file. */ +#ifdef PNG_USE_GLOBAL_ARRAYS + PNG_EXPORT_VAR (const png_byte FARDATA) png_sig[8]; +#else +#if 0 +#define png_sig png_sig_bytes(NULL) +#endif +#endif +#endif /* PNG_NO_EXTERN */ + +/* Constant strings for known chunk types. If you need to add a chunk, + * define the name here, and add an invocation of the macro in png.c and + * wherever it's needed. + */ +#define PNG_IHDR const png_byte png_IHDR[5] = { 73, 72, 68, 82, '\0'} +#define PNG_IDAT const png_byte png_IDAT[5] = { 73, 68, 65, 84, '\0'} +#define PNG_IEND const png_byte png_IEND[5] = { 73, 69, 78, 68, '\0'} +#define PNG_PLTE const png_byte png_PLTE[5] = { 80, 76, 84, 69, '\0'} +#define PNG_bKGD const png_byte png_bKGD[5] = { 98, 75, 71, 68, '\0'} +#define PNG_cHRM const png_byte png_cHRM[5] = { 99, 72, 82, 77, '\0'} +#define PNG_gAMA const png_byte png_gAMA[5] = {103, 65, 77, 65, '\0'} +#define PNG_hIST const png_byte png_hIST[5] = {104, 73, 83, 84, '\0'} +#define PNG_iCCP const png_byte png_iCCP[5] = {105, 67, 67, 80, '\0'} +#define PNG_iTXt const png_byte png_iTXt[5] = {105, 84, 88, 116, '\0'} +#define PNG_oFFs const png_byte png_oFFs[5] = {111, 70, 70, 115, '\0'} +#define PNG_pCAL const png_byte png_pCAL[5] = {112, 67, 65, 76, '\0'} +#define PNG_sCAL const png_byte png_sCAL[5] = {115, 67, 65, 76, '\0'} +#define PNG_pHYs const png_byte png_pHYs[5] = {112, 72, 89, 115, '\0'} +#define PNG_sBIT const png_byte png_sBIT[5] = {115, 66, 73, 84, '\0'} +#define PNG_sPLT const png_byte png_sPLT[5] = {115, 80, 76, 84, '\0'} +#define PNG_sRGB const png_byte png_sRGB[5] = {115, 82, 71, 66, '\0'} +#define PNG_tEXt const png_byte png_tEXt[5] = {116, 69, 88, 116, '\0'} +#define PNG_tIME const png_byte png_tIME[5] = {116, 73, 77, 69, '\0'} +#define PNG_tRNS const png_byte png_tRNS[5] = {116, 82, 78, 83, '\0'} +#define PNG_zTXt const png_byte png_zTXt[5] = {122, 84, 88, 116, '\0'} + +#ifdef PNG_USE_GLOBAL_ARRAYS +PNG_EXPORT_VAR (const png_byte FARDATA) png_IHDR[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_IDAT[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_IEND[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_PLTE[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_bKGD[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_cHRM[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_gAMA[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_hIST[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_iCCP[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_iTXt[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_oFFs[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_pCAL[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_sCAL[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_pHYs[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_sBIT[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_sPLT[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_sRGB[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_tEXt[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_tIME[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_tRNS[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_zTXt[5]; +#endif /* PNG_USE_GLOBAL_ARRAYS */ + +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) +/* Initialize png_ptr struct for reading, and allocate any other memory. + * (old interface - DEPRECATED - use png_create_read_struct instead). + */ +extern PNG_EXPORT(void,png_read_init) PNGARG((png_structp png_ptr)); +#undef png_read_init +#define png_read_init(png_ptr) png_read_init_3(&png_ptr, \ + PNG_LIBPNG_VER_STRING, png_sizeof(png_struct)); +#endif + +extern PNG_EXPORT(void,png_read_init_3) PNGARG((png_structpp ptr_ptr, + png_const_charp user_png_ver, png_size_t png_struct_size)); +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) +extern PNG_EXPORT(void,png_read_init_2) PNGARG((png_structp png_ptr, + png_const_charp user_png_ver, png_size_t png_struct_size, png_size_t + png_info_size)); +#endif + +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) +/* Initialize png_ptr struct for writing, and allocate any other memory. + * (old interface - DEPRECATED - use png_create_write_struct instead). + */ +extern PNG_EXPORT(void,png_write_init) PNGARG((png_structp png_ptr)); +#undef png_write_init +#define png_write_init(png_ptr) png_write_init_3(&png_ptr, \ + PNG_LIBPNG_VER_STRING, png_sizeof(png_struct)); +#endif + +extern PNG_EXPORT(void,png_write_init_3) PNGARG((png_structpp ptr_ptr, + png_const_charp user_png_ver, png_size_t png_struct_size)); +extern PNG_EXPORT(void,png_write_init_2) PNGARG((png_structp png_ptr, + png_const_charp user_png_ver, png_size_t png_struct_size, png_size_t + png_info_size)); + +/* Allocate memory for an internal libpng struct */ +PNG_EXTERN png_voidp png_create_struct PNGARG((int type)); + +/* Free memory from internal libpng struct */ +PNG_EXTERN void png_destroy_struct PNGARG((png_voidp struct_ptr)); + +PNG_EXTERN png_voidp png_create_struct_2 PNGARG((int type, png_malloc_ptr + malloc_fn, png_voidp mem_ptr)); +PNG_EXTERN void png_destroy_struct_2 PNGARG((png_voidp struct_ptr, + png_free_ptr free_fn, png_voidp mem_ptr)); + +/* Free any memory that info_ptr points to and reset struct. */ +PNG_EXTERN void png_info_destroy PNGARG((png_structp png_ptr, + png_infop info_ptr)); + +#ifndef PNG_1_0_X +/* Function to allocate memory for zlib. */ +PNG_EXTERN voidpf png_zalloc PNGARG((voidpf png_ptr, uInt items, uInt size)); + +/* Function to free memory for zlib */ +PNG_EXTERN void png_zfree PNGARG((voidpf png_ptr, voidpf ptr)); + +#ifdef PNG_SIZE_T +/* Function to convert a sizeof an item to png_sizeof item */ + PNG_EXTERN png_size_t PNGAPI png_convert_size PNGARG((size_t size)); +#endif + +/* Next four functions are used internally as callbacks. PNGAPI is required + * but not PNG_EXPORT. PNGAPI added at libpng version 1.2.3. */ + +PNG_EXTERN void PNGAPI png_default_read_data PNGARG((png_structp png_ptr, + png_bytep data, png_size_t length)); + +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +PNG_EXTERN void PNGAPI png_push_fill_buffer PNGARG((png_structp png_ptr, + png_bytep buffer, png_size_t length)); +#endif + +PNG_EXTERN void PNGAPI png_default_write_data PNGARG((png_structp png_ptr, + png_bytep data, png_size_t length)); + +#if defined(PNG_WRITE_FLUSH_SUPPORTED) +#if !defined(PNG_NO_STDIO) +PNG_EXTERN void PNGAPI png_default_flush PNGARG((png_structp png_ptr)); +#endif +#endif +#else /* PNG_1_0_X */ +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +PNG_EXTERN void png_push_fill_buffer PNGARG((png_structp png_ptr, + png_bytep buffer, png_size_t length)); +#endif +#endif /* PNG_1_0_X */ + +/* Reset the CRC variable */ +PNG_EXTERN void png_reset_crc PNGARG((png_structp png_ptr)); + +/* Write the "data" buffer to whatever output you are using. */ +PNG_EXTERN void png_write_data PNGARG((png_structp png_ptr, png_bytep data, + png_size_t length)); + +/* Read data from whatever input you are using into the "data" buffer */ +PNG_EXTERN void png_read_data PNGARG((png_structp png_ptr, png_bytep data, + png_size_t length)); + +/* Read bytes into buf, and update png_ptr->crc */ +PNG_EXTERN void png_crc_read PNGARG((png_structp png_ptr, png_bytep buf, + png_size_t length)); + +/* Decompress data in a chunk that uses compression */ +#if defined(PNG_zTXt_SUPPORTED) || defined(PNG_iTXt_SUPPORTED) || \ + defined(PNG_iCCP_SUPPORTED) || defined(PNG_sPLT_SUPPORTED) +PNG_EXTERN png_charp png_decompress_chunk PNGARG((png_structp png_ptr, + int comp_type, png_charp chunkdata, png_size_t chunklength, + png_size_t prefix_length, png_size_t *data_length)); +#endif + +/* Read "skip" bytes, read the file crc, and (optionally) verify png_ptr->crc */ +PNG_EXTERN int png_crc_finish PNGARG((png_structp png_ptr, png_uint_32 skip)); + +/* Read the CRC from the file and compare it to the libpng calculated CRC */ +PNG_EXTERN int png_crc_error PNGARG((png_structp png_ptr)); + +/* Calculate the CRC over a section of data. Note that we are only + * passing a maximum of 64K on systems that have this as a memory limit, + * since this is the maximum buffer size we can specify. + */ +PNG_EXTERN void png_calculate_crc PNGARG((png_structp png_ptr, png_bytep ptr, + png_size_t length)); + +#if defined(PNG_WRITE_FLUSH_SUPPORTED) +PNG_EXTERN void png_flush PNGARG((png_structp png_ptr)); +#endif + +/* simple function to write the signature */ +PNG_EXTERN void png_write_sig PNGARG((png_structp png_ptr)); + +/* write various chunks */ + +/* Write the IHDR chunk, and update the png_struct with the necessary + * information. + */ +PNG_EXTERN void png_write_IHDR PNGARG((png_structp png_ptr, png_uint_32 width, + png_uint_32 height, + int bit_depth, int color_type, int compression_method, int filter_method, + int interlace_method)); + +PNG_EXTERN void png_write_PLTE PNGARG((png_structp png_ptr, png_colorp palette, + png_uint_32 num_pal)); + +PNG_EXTERN void png_write_IDAT PNGARG((png_structp png_ptr, png_bytep data, + png_size_t length)); + +PNG_EXTERN void png_write_IEND PNGARG((png_structp png_ptr)); + +#if defined(PNG_WRITE_gAMA_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED +PNG_EXTERN void png_write_gAMA PNGARG((png_structp png_ptr, double file_gamma)); +#endif +#ifdef PNG_FIXED_POINT_SUPPORTED +PNG_EXTERN void png_write_gAMA_fixed PNGARG((png_structp png_ptr, png_fixed_point + file_gamma)); +#endif +#endif + +#if defined(PNG_WRITE_sBIT_SUPPORTED) +PNG_EXTERN void png_write_sBIT PNGARG((png_structp png_ptr, png_color_8p sbit, + int color_type)); +#endif + +#if defined(PNG_WRITE_cHRM_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED +PNG_EXTERN void png_write_cHRM PNGARG((png_structp png_ptr, + double white_x, double white_y, + double red_x, double red_y, double green_x, double green_y, + double blue_x, double blue_y)); +#endif +#ifdef PNG_FIXED_POINT_SUPPORTED +PNG_EXTERN void png_write_cHRM_fixed PNGARG((png_structp png_ptr, + png_fixed_point int_white_x, png_fixed_point int_white_y, + png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point + int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x, + png_fixed_point int_blue_y)); +#endif +#endif + +#if defined(PNG_WRITE_sRGB_SUPPORTED) +PNG_EXTERN void png_write_sRGB PNGARG((png_structp png_ptr, + int intent)); +#endif + +#if defined(PNG_WRITE_iCCP_SUPPORTED) +PNG_EXTERN void png_write_iCCP PNGARG((png_structp png_ptr, + png_charp name, int compression_type, + png_charp profile, int proflen)); + /* Note to maintainer: profile should be png_bytep */ +#endif + +#if defined(PNG_WRITE_sPLT_SUPPORTED) +PNG_EXTERN void png_write_sPLT PNGARG((png_structp png_ptr, + png_sPLT_tp palette)); +#endif + +#if defined(PNG_WRITE_tRNS_SUPPORTED) +PNG_EXTERN void png_write_tRNS PNGARG((png_structp png_ptr, png_bytep trans, + png_color_16p values, int number, int color_type)); +#endif + +#if defined(PNG_WRITE_bKGD_SUPPORTED) +PNG_EXTERN void png_write_bKGD PNGARG((png_structp png_ptr, + png_color_16p values, int color_type)); +#endif + +#if defined(PNG_WRITE_hIST_SUPPORTED) +PNG_EXTERN void png_write_hIST PNGARG((png_structp png_ptr, png_uint_16p hist, + int num_hist)); +#endif + +#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \ + defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED) +PNG_EXTERN png_size_t png_check_keyword PNGARG((png_structp png_ptr, + png_charp key, png_charpp new_key)); +#endif + +#if defined(PNG_WRITE_tEXt_SUPPORTED) +PNG_EXTERN void png_write_tEXt PNGARG((png_structp png_ptr, png_charp key, + png_charp text, png_size_t text_len)); +#endif + +#if defined(PNG_WRITE_zTXt_SUPPORTED) +PNG_EXTERN void png_write_zTXt PNGARG((png_structp png_ptr, png_charp key, + png_charp text, png_size_t text_len, int compression)); +#endif + +#if defined(PNG_WRITE_iTXt_SUPPORTED) +PNG_EXTERN void png_write_iTXt PNGARG((png_structp png_ptr, + int compression, png_charp key, png_charp lang, png_charp lang_key, + png_charp text)); +#endif + +#if defined(PNG_TEXT_SUPPORTED) /* Added at version 1.0.14 and 1.2.4 */ +PNG_EXTERN int png_set_text_2 PNGARG((png_structp png_ptr, + png_infop info_ptr, png_textp text_ptr, int num_text)); +#endif + +#if defined(PNG_WRITE_oFFs_SUPPORTED) +PNG_EXTERN void png_write_oFFs PNGARG((png_structp png_ptr, + png_int_32 x_offset, png_int_32 y_offset, int unit_type)); +#endif + +#if defined(PNG_WRITE_pCAL_SUPPORTED) +PNG_EXTERN void png_write_pCAL PNGARG((png_structp png_ptr, png_charp purpose, + png_int_32 X0, png_int_32 X1, int type, int nparams, + png_charp units, png_charpp params)); +#endif + +#if defined(PNG_WRITE_pHYs_SUPPORTED) +PNG_EXTERN void png_write_pHYs PNGARG((png_structp png_ptr, + png_uint_32 x_pixels_per_unit, png_uint_32 y_pixels_per_unit, + int unit_type)); +#endif + +#if defined(PNG_WRITE_tIME_SUPPORTED) +PNG_EXTERN void png_write_tIME PNGARG((png_structp png_ptr, + png_timep mod_time)); +#endif + +#if defined(PNG_WRITE_sCAL_SUPPORTED) +#if defined(PNG_FLOATING_POINT_SUPPORTED) && !defined(PNG_NO_STDIO) +PNG_EXTERN void png_write_sCAL PNGARG((png_structp png_ptr, + int unit, double width, double height)); +#else +#ifdef PNG_FIXED_POINT_SUPPORTED +PNG_EXTERN void png_write_sCAL_s PNGARG((png_structp png_ptr, + int unit, png_charp width, png_charp height)); +#endif +#endif +#endif + +/* Called when finished processing a row of data */ +PNG_EXTERN void png_write_finish_row PNGARG((png_structp png_ptr)); + +/* Internal use only. Called before first row of data */ +PNG_EXTERN void png_write_start_row PNGARG((png_structp png_ptr)); + +#if defined(PNG_READ_GAMMA_SUPPORTED) +PNG_EXTERN void png_build_gamma_table PNGARG((png_structp png_ptr)); +#endif + +/* combine a row of data, dealing with alpha, etc. if requested */ +PNG_EXTERN void png_combine_row PNGARG((png_structp png_ptr, png_bytep row, + int mask)); + +#if defined(PNG_READ_INTERLACING_SUPPORTED) +/* expand an interlaced row */ +/* OLD pre-1.0.9 interface: +PNG_EXTERN void png_do_read_interlace PNGARG((png_row_infop row_info, + png_bytep row, int pass, png_uint_32 transformations)); + */ +PNG_EXTERN void png_do_read_interlace PNGARG((png_structp png_ptr)); +#endif + +/* GRR TO DO (2.0 or whenever): simplify other internal calling interfaces */ + +#if defined(PNG_WRITE_INTERLACING_SUPPORTED) +/* grab pixels out of a row for an interlaced pass */ +PNG_EXTERN void png_do_write_interlace PNGARG((png_row_infop row_info, + png_bytep row, int pass)); +#endif + +/* unfilter a row */ +PNG_EXTERN void png_read_filter_row PNGARG((png_structp png_ptr, + png_row_infop row_info, png_bytep row, png_bytep prev_row, int filter)); + +/* Choose the best filter to use and filter the row data */ +PNG_EXTERN void png_write_find_filter PNGARG((png_structp png_ptr, + png_row_infop row_info)); + +/* Write out the filtered row. */ +PNG_EXTERN void png_write_filtered_row PNGARG((png_structp png_ptr, + png_bytep filtered_row)); +/* finish a row while reading, dealing with interlacing passes, etc. */ +PNG_EXTERN void png_read_finish_row PNGARG((png_structp png_ptr)); + +/* initialize the row buffers, etc. */ +PNG_EXTERN void png_read_start_row PNGARG((png_structp png_ptr)); +/* optional call to update the users info structure */ +PNG_EXTERN void png_read_transform_info PNGARG((png_structp png_ptr, + png_infop info_ptr)); + +/* these are the functions that do the transformations */ +#if defined(PNG_READ_FILLER_SUPPORTED) +PNG_EXTERN void png_do_read_filler PNGARG((png_row_infop row_info, + png_bytep row, png_uint_32 filler, png_uint_32 flags)); +#endif + +#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) +PNG_EXTERN void png_do_read_swap_alpha PNGARG((png_row_infop row_info, + png_bytep row)); +#endif + +#if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) +PNG_EXTERN void png_do_write_swap_alpha PNGARG((png_row_infop row_info, + png_bytep row)); +#endif + +#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) +PNG_EXTERN void png_do_read_invert_alpha PNGARG((png_row_infop row_info, + png_bytep row)); +#endif + +#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) +PNG_EXTERN void png_do_write_invert_alpha PNGARG((png_row_infop row_info, + png_bytep row)); +#endif + +#if defined(PNG_WRITE_FILLER_SUPPORTED) || \ + defined(PNG_READ_STRIP_ALPHA_SUPPORTED) +PNG_EXTERN void png_do_strip_filler PNGARG((png_row_infop row_info, + png_bytep row, png_uint_32 flags)); +#endif + +#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) +PNG_EXTERN void png_do_swap PNGARG((png_row_infop row_info, png_bytep row)); +#endif + +#if defined(PNG_READ_PACKSWAP_SUPPORTED) || defined(PNG_WRITE_PACKSWAP_SUPPORTED) +PNG_EXTERN void png_do_packswap PNGARG((png_row_infop row_info, png_bytep row)); +#endif + +#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) +PNG_EXTERN int png_do_rgb_to_gray PNGARG((png_structp png_ptr, png_row_infop + row_info, png_bytep row)); +#endif + +#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) +PNG_EXTERN void png_do_gray_to_rgb PNGARG((png_row_infop row_info, + png_bytep row)); +#endif + +#if defined(PNG_READ_PACK_SUPPORTED) +PNG_EXTERN void png_do_unpack PNGARG((png_row_infop row_info, png_bytep row)); +#endif + +#if defined(PNG_READ_SHIFT_SUPPORTED) +PNG_EXTERN void png_do_unshift PNGARG((png_row_infop row_info, png_bytep row, + png_color_8p sig_bits)); +#endif + +#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) +PNG_EXTERN void png_do_invert PNGARG((png_row_infop row_info, png_bytep row)); +#endif + +#if defined(PNG_READ_16_TO_8_SUPPORTED) +PNG_EXTERN void png_do_chop PNGARG((png_row_infop row_info, png_bytep row)); +#endif + +#if defined(PNG_READ_DITHER_SUPPORTED) +PNG_EXTERN void png_do_dither PNGARG((png_row_infop row_info, + png_bytep row, png_bytep palette_lookup, png_bytep dither_lookup)); + +# if defined(PNG_CORRECT_PALETTE_SUPPORTED) +PNG_EXTERN void png_correct_palette PNGARG((png_structp png_ptr, + png_colorp palette, int num_palette)); +# endif +#endif + +#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) +PNG_EXTERN void png_do_bgr PNGARG((png_row_infop row_info, png_bytep row)); +#endif + +#if defined(PNG_WRITE_PACK_SUPPORTED) +PNG_EXTERN void png_do_pack PNGARG((png_row_infop row_info, + png_bytep row, png_uint_32 bit_depth)); +#endif + +#if defined(PNG_WRITE_SHIFT_SUPPORTED) +PNG_EXTERN void png_do_shift PNGARG((png_row_infop row_info, png_bytep row, + png_color_8p bit_depth)); +#endif + +#if defined(PNG_READ_BACKGROUND_SUPPORTED) +#if defined(PNG_READ_GAMMA_SUPPORTED) +PNG_EXTERN void png_do_background PNGARG((png_row_infop row_info, png_bytep row, + png_color_16p trans_values, png_color_16p background, + png_color_16p background_1, + png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1, + png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1, + png_uint_16pp gamma_16_to_1, int gamma_shift)); +#else +PNG_EXTERN void png_do_background PNGARG((png_row_infop row_info, png_bytep row, + png_color_16p trans_values, png_color_16p background)); +#endif +#endif + +#if defined(PNG_READ_GAMMA_SUPPORTED) +PNG_EXTERN void png_do_gamma PNGARG((png_row_infop row_info, png_bytep row, + png_bytep gamma_table, png_uint_16pp gamma_16_table, + int gamma_shift)); +#endif + +#if defined(PNG_READ_EXPAND_SUPPORTED) +PNG_EXTERN void png_do_expand_palette PNGARG((png_row_infop row_info, + png_bytep row, png_colorp palette, png_bytep trans, int num_trans)); +PNG_EXTERN void png_do_expand PNGARG((png_row_infop row_info, + png_bytep row, png_color_16p trans_value)); +#endif + +/* The following decodes the appropriate chunks, and does error correction, + * then calls the appropriate callback for the chunk if it is valid. + */ + +/* decode the IHDR chunk */ +PNG_EXTERN void png_handle_IHDR PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +PNG_EXTERN void png_handle_PLTE PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +PNG_EXTERN void png_handle_IEND PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); + +#if defined(PNG_READ_bKGD_SUPPORTED) +PNG_EXTERN void png_handle_bKGD PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_cHRM_SUPPORTED) +PNG_EXTERN void png_handle_cHRM PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_gAMA_SUPPORTED) +PNG_EXTERN void png_handle_gAMA PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_hIST_SUPPORTED) +PNG_EXTERN void png_handle_hIST PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_iCCP_SUPPORTED) +extern void png_handle_iCCP PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif /* PNG_READ_iCCP_SUPPORTED */ + +#if defined(PNG_READ_iTXt_SUPPORTED) +PNG_EXTERN void png_handle_iTXt PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_oFFs_SUPPORTED) +PNG_EXTERN void png_handle_oFFs PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_pCAL_SUPPORTED) +PNG_EXTERN void png_handle_pCAL PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_pHYs_SUPPORTED) +PNG_EXTERN void png_handle_pHYs PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_sBIT_SUPPORTED) +PNG_EXTERN void png_handle_sBIT PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_sCAL_SUPPORTED) +PNG_EXTERN void png_handle_sCAL PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_sPLT_SUPPORTED) +extern void png_handle_sPLT PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif /* PNG_READ_sPLT_SUPPORTED */ + +#if defined(PNG_READ_sRGB_SUPPORTED) +PNG_EXTERN void png_handle_sRGB PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_tEXt_SUPPORTED) +PNG_EXTERN void png_handle_tEXt PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_tIME_SUPPORTED) +PNG_EXTERN void png_handle_tIME PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_tRNS_SUPPORTED) +PNG_EXTERN void png_handle_tRNS PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_zTXt_SUPPORTED) +PNG_EXTERN void png_handle_zTXt PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +PNG_EXTERN void png_handle_unknown PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 length)); + +PNG_EXTERN void png_check_chunk_name PNGARG((png_structp png_ptr, + png_bytep chunk_name)); + +/* handle the transformations for reading and writing */ +PNG_EXTERN void png_do_read_transformations PNGARG((png_structp png_ptr)); +PNG_EXTERN void png_do_write_transformations PNGARG((png_structp png_ptr)); + +PNG_EXTERN void png_init_read_transformations PNGARG((png_structp png_ptr)); + +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +PNG_EXTERN void png_push_read_chunk PNGARG((png_structp png_ptr, + png_infop info_ptr)); +PNG_EXTERN void png_push_read_sig PNGARG((png_structp png_ptr, + png_infop info_ptr)); +PNG_EXTERN void png_push_check_crc PNGARG((png_structp png_ptr)); +PNG_EXTERN void png_push_crc_skip PNGARG((png_structp png_ptr, + png_uint_32 length)); +PNG_EXTERN void png_push_crc_finish PNGARG((png_structp png_ptr)); +PNG_EXTERN void png_push_save_buffer PNGARG((png_structp png_ptr)); +PNG_EXTERN void png_push_restore_buffer PNGARG((png_structp png_ptr, + png_bytep buffer, png_size_t buffer_length)); +PNG_EXTERN void png_push_read_IDAT PNGARG((png_structp png_ptr)); +PNG_EXTERN void png_process_IDAT_data PNGARG((png_structp png_ptr, + png_bytep buffer, png_size_t buffer_length)); +PNG_EXTERN void png_push_process_row PNGARG((png_structp png_ptr)); +PNG_EXTERN void png_push_handle_unknown PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 length)); +PNG_EXTERN void png_push_have_info PNGARG((png_structp png_ptr, + png_infop info_ptr)); +PNG_EXTERN void png_push_have_end PNGARG((png_structp png_ptr, + png_infop info_ptr)); +PNG_EXTERN void png_push_have_row PNGARG((png_structp png_ptr, png_bytep row)); +PNG_EXTERN void png_push_read_end PNGARG((png_structp png_ptr, + png_infop info_ptr)); +PNG_EXTERN void png_process_some_data PNGARG((png_structp png_ptr, + png_infop info_ptr)); +PNG_EXTERN void png_read_push_finish_row PNGARG((png_structp png_ptr)); +#if defined(PNG_READ_tEXt_SUPPORTED) +PNG_EXTERN void png_push_handle_tEXt PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 length)); +PNG_EXTERN void png_push_read_tEXt PNGARG((png_structp png_ptr, + png_infop info_ptr)); +#endif +#if defined(PNG_READ_zTXt_SUPPORTED) +PNG_EXTERN void png_push_handle_zTXt PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 length)); +PNG_EXTERN void png_push_read_zTXt PNGARG((png_structp png_ptr, + png_infop info_ptr)); +#endif +#if defined(PNG_READ_iTXt_SUPPORTED) +PNG_EXTERN void png_push_handle_iTXt PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 length)); +PNG_EXTERN void png_push_read_iTXt PNGARG((png_structp png_ptr, + png_infop info_ptr)); +#endif + +#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ + +#ifdef PNG_MNG_FEATURES_SUPPORTED +PNG_EXTERN void png_do_read_intrapixel PNGARG((png_row_infop row_info, + png_bytep row)); +PNG_EXTERN void png_do_write_intrapixel PNGARG((png_row_infop row_info, + png_bytep row)); +#endif + +#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) +/* png.c */ /* PRIVATE */ +PNG_EXTERN void png_init_mmx_flags PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_INCH_CONVERSIONS) && defined(PNG_FLOATING_POINT_SUPPORTED) +PNG_EXTERN png_uint_32 png_get_pixels_per_inch PNGARG((png_structp png_ptr, +png_infop info_ptr)); + +PNG_EXTERN png_uint_32 png_get_x_pixels_per_inch PNGARG((png_structp png_ptr, +png_infop info_ptr)); + +PNG_EXTERN png_uint_32 png_get_y_pixels_per_inch PNGARG((png_structp png_ptr, +png_infop info_ptr)); + +PNG_EXTERN float png_get_x_offset_inches PNGARG((png_structp png_ptr, +png_infop info_ptr)); + +PNG_EXTERN float png_get_y_offset_inches PNGARG((png_structp png_ptr, +png_infop info_ptr)); + +#if defined(PNG_pHYs_SUPPORTED) +PNG_EXTERN png_uint_32 png_get_pHYs_dpi PNGARG((png_structp png_ptr, +png_infop info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)); +#endif /* PNG_pHYs_SUPPORTED */ +#endif /* PNG_INCH_CONVERSIONS && PNG_FLOATING_POINT_SUPPORTED */ + +/* Maintainer: Put new private prototypes here ^ and in libpngpf.3 */ + +#endif /* PNG_INTERNAL */ + +#ifdef __cplusplus +} +#endif + +#endif /* PNG_VERSION_INFO_ONLY */ +/* do not put anything past this line */ +#endif /* PNG_H */ diff --git a/mod/pub.mod/libpng.mod/pngbar.jpg b/mod/pub.mod/libpng.mod/pngbar.jpg new file mode 100644 index 0000000000000000000000000000000000000000..70ba8d817ce433788c7933dbe3c29c3e384b2b0a GIT binary patch literal 2498 zcmb79cR1UN8ve<!Vud7}HYCK}tM;Y{Z5^vrsFE6uJ&GDt6fJ6Y=`oAe-h^XIQ7v*# zZO1A~(WaF)HOtle+~>LX-}`>=f8Y0x?_}m=8Q`%n#hU_5OiaM90Zxtq1>=CgTfsNH zyhE`{nwsjeShHXcFRV>~hi`yq2v*YHBRtd~Fu*+^LY^4lCw1}<U<`mkpkF)%<djfW zC=>#Lva_%-vvRO=aKPAMFitLB9!@Se7YxRO;(_xakVqs4H@^T1A;613B7T`LfloCM zC>s>YhTw#8BK~ij^a5~J00TIJnM42(oCyqPI(Y@00RRyA^t=CpnFWBbLcymyB_03- z0x_M|W@3T<`-BN}TAvxt!Yd50@*zZ&*pN77LnCW9lz^y8aNMcnEYqn3{J(Y(W-t^0 zvHZ$XfCC^V5CqH&h5jdw2?Phg5ME(JD6^7?wOdfuSH8H0zP}N;;+36~Ie_ET2?Phj z0ewJu_XPOzrM!FkVBFSWa?9PHSVQF9@l6YED#^WWRML1J9VDQieoKN{=G;@B(Vmqw zMZd`y)ni0|7a{dGH#QBu4Xb>^8Ml-38dtbR*{4J6CiE}A`n<^Swi_b~53dp@Oz5&x zqIb>@R2bY|^Eg5Q^oZrcolUy~e~ev4`E;SpK(~nwOpGHYx7IEN6TgtCZ%ql2@{}O= zB=jD|t!NkbZ`gujXu2t1GZEV?OI;QB^sVbc{HllYU92vX0u%;zs?5Dy7i5b^Vr}Pn zO2G4GXu7^$QmgA^)I4+H4Ve#&F8{pR>+ENwX4HwzetiUp&~J{h-wxp)&2&qMG9ULl z$1sGXW1&H@50#Izy=lZUfjypz`|x(CS!BmIDmt4<-iM+7vJJYh6Ok&Y`9uL<Z7G&l z=3{Ft5*;tKL?$<)?4vlk;&S(F^p?OABxel=x4PsX`WCZ|W62+S?$a?rPIXSZEfap* zCA#P4K5cAmskO?sY&lfF8?d~sK}__NwBcG0#y>Dz-dii|{T@&nMOnhYGW-(Yq<%v= zZ{=JMeWTwA?P4UG8a$$%3#A_D7*<`B{srsRec$8y$6ez;HO0+<=@)~a+C#KD$fFie zOF5lh(}n6`?kJ=#rB8?(qO_~`d`n%$zP0)o`DHOCeo?6M-Pn1fN6p1D_{#*0&JIPU zL@9JFTVPL!MG(xN{Pyi$)cs@-UVOt7&mCx*p!Qt+LYRr<MCQctCLjHK$pfn;z1hy? zhFmm?j52ZVvPpd!#yTf?y@~zp8GfD<V5X=(OGEIkLe9d<@#vRl>oDYFGACZJ{8Pxa zhc4YRL#jc2?yi*%aQ(San~2E>x<f&P-V^$lGs#wBuczC`M-$FkId!>W1QR0J9uq>9 zE|N+~DEC)g{=F~&W?nheQJ?`Q<2i%Wz?M||p-DL5&AOs`qIe3z=N#%2ExTl7#Mi~t zZT<r>vmnY2L6R<L?}=!a^}0y&tDneUO^{=jlDX0*0(q0An3ZpRXs~aFWj?wc!@|JS zoJ}8?kQEZIJ!~X}(Vq=O=WA*G<etkK*1WN3e@z>G=bnbgRr9M+u}{jp7ydMJN^<vU z8*REm8S<<yCi!ysyt-_fBK15S#&Iq4Oq_vqqaqf#rB}lM37i1)g%&n6z5cj6HKXWp zr;h82KDrgS%U_=1+gE9qzAg3XQVK|IImkvV0~c{%yDN6Z@(53<9w56F`59!DfVj&f zA{jKZDuFHuxr|G-E@O6G7LMzx1?E@JDXU&Y$E}*0N^361T4w0bA&iZK_zlU8unP|# z$;UYVwd$Vq*B^YkFeM97(bDysc!@yvV@4JpY6i}*op6?HwY<|z2_K`pntZ8OR(!AD zrNx^-_2va7POIEZbah179#k-76p9WDU!vrtxfFcr2UMI&bDD%3^reQ;KMK)x%U^XO zscl{Psv|9LCyKoutCNAc%qc&Ma^a$s5gU9ie{#6Iz9gH(=i5t{dScHG8Eb9QSa2b@ zo{jo&2E!NKU^_h*F=y_X*}?2({66=|&QF~TYAO0@cj|?)>)W@t){SwRelgUb%&^y1 zM;W@kz|uUoUabJ?0dbrrlPe>APntXLz&pJ5ZWI7}GEh1`;2^(^ytgu48%@k}`m_4R zx8US1L-x+#p75_R@wMZVM}ykuYvioTTGW)v@utp6&FdCbVm5jv1($E4n`7P(vX8P^ zVZA#7-KlKgbTX}&!a_R%ta^0&^b~I$WKg~SIROeW8CO-de{#3jS6!TXFi85;P@Hrz zD3>)2F0f1;VrK&%21hW;jd0Cjw4<mw8CV7UVXS`sw)0`|tmkMbu5>?npnIr&aVCT_ zW9a^Bg^fd&pImbNpxTP+{rooTc`NU48`F^mV8?f=97sYHnM7{LO)G6#omwpLj@zjk z*`m5o3~<=GP<O*VmcrpnAG_a2N{tsh-f|k`i<yyGXGABaCFyG%>;|qAvDunf<-pg& zIH~t>Us-XJV%rkrKOD99=3flubRj$V{UNE2PCJI@Qi7&wDXM|x@Dll=Tj)D@Y(u1P z7_yCfQ%}|zKKprCcz*XtvG}TKViW44NE~ZF&3pW4f2!sm`cI`U`Bl!2_PqS3Dvok5 z=2eTiaWh#`Q&nhOeYk8Y2gu}DUKS%W-&K5bD>U`DQo92*Z9Jvl-A7zo%D^O5+z3<A zbZxr1jz3UJH7r5k@GR}7Xwvu0Va8I?Z1teASZu_c|HVgndKPR!oZo+l5bV~?C&3wM zcS{g1%h_fUL#vYy-qs4us(E#Y$?z+_>*TS2sjBs^v)SGJg_-$$y+3;FN@u#o{#rqd z=-;Zemc);1)~-n;ZNYgD*QCx)qTS?(6>`Yxu0|T02j9{jA-iY!XBs6VtKgN(?M>3M zXitp$#9|Y^aqefnpO5s_bc&VI`Mol8lb36szrH?8J9^Y{Sh=Zut;vy9EAFY*!eBw< zUh1>Fup<1+##XO=O2huD7w?@yH~akK6(i-EANrw@1tl$;?SdE;AJIJyTU&yrti_SX zqL2K}JyH4R*vHyPyly4H@@Qky6>b`Z!-~dp<=^<0ql8jCIzJ{n2`02PuA?k^A&hB? zljJT{WGG{Bb%mft`m0YCNhgQcH?}Ga`o4KT7r9mpTO|G-ajjf)r<b9NJD^U_OV|bd zIMdC?AJ;m0ml-XtGZF8}Md-?DEBEKdcw6^ppy?MF7!EU&=q;1{qeKi<pjux17~xi1 V^??kj$kLq2r$#fD{2!gn{tGu6WuyQA literal 0 HcmV?d00001 diff --git a/mod/pub.mod/libpng.mod/pngbar.png b/mod/pub.mod/libpng.mod/pngbar.png new file mode 100644 index 0000000000000000000000000000000000000000..49798c8ed957b407692306792a73df4312f80cbb GIT binary patch literal 2399 zcmV-l3840gP)<h;3K|Lk000e1NJLTq003A30018d0{{R3R2KTu00004XF*Lt006O% z3;baP00001b5ch_0olnce*gdiyHHG2MF0Q*ud%PGtErit!ESMRrKhFdNl9>Uae~l{ z0Rja6`T3xspr4_iba{e!dVHCinSz3e@1>=%j($2G9;~mjBv2nTG{hSR28W4<;$UEa zfq+#nVBJJS0RaHmC@AQFfQX5U(+mu00070t%A%vz78nt@y3y1S5N2m)Kc7E!n|s1o zS3*LZ`|ImCIy_xnT}Vn#B_<}-6cj!`B>eC1D=aTfO-&XS7mt#WfPvpvG$H~507gef za(0FG_V)er^K^NAv$WC-3=ME`<MOzf3JMF!%gqM}2pkm_0s;d800IC20TmAqQ&m}$ zl-e*cFfT7J>ynZ!EiHe1F4i6%tFFzXq(o3jLNqluBO@b<ijo~29n8+mJUv1g9T{I> zVbTT$78e$QPf^Cm#xylL6B84MYEWEsVPscG4Gj%}gp7rShJJ*J1_uTQ1qZgcwgm+R zTU=lS0|Z`PB(t=$0s#U60RaF30IsgC78d%fuB?oX+;MYqIXXKmD<L8^7p1I`Gcq+L z9~!KzMU#}1>vVH6GZr>DJ8*F|pP|?3h={zu&lnR8iH(zuj*X0tj8%hK4-gJ}V^=2} z6>oEP2?_mre}vT-7)}5HC?_Km6cv1ad;tIecYA?^h0qZY6Aum%b9;T@R8)kCkwQa5 zadmqS2M0SlJZ)}m(EtEcS6dMa3_n3bUt?)wWMf%cS%!(3`QP6|MM@eP`5+-7d3AOF z|Nm+%D{E|VNkkrIXlz47LkkNGKtMq3?d<#K=S5UV_RGudo}K{#0%vG&=I7>ARK#Xx zZ!<JA@vpCkjf^!&IBjluDk>^wXXe#HK_DO?>Sbn6Qdo$IQAs2u8X6iK7#qpU$!=|P zH#j{eCMlYoeM(75KtVqc5c_+8WeN%km6n;gySbjFueP_g0|EoHwX*;K|7dG)!Bu-G z000IGNkl<ZNXNC-{a4dg7zgm%Ds#$9aO%_!5vM|gK|v(Ehyz7o$gsR91A7@%tg}GH zwKWa|Q79-#2MmNMGLQ`^NO|i30hx+!1_g#nR$;(u883gvZUS1+9rXu&&Pkh-_I%FG zH}|<WpzZxsDro!s_jgt6jnxW3+i&oVwP|2r!0*Bv|5j_PA6ZyHzqU-E=XA1mTI>Ht z*vcw)0ZfC}7KY%R=*angFf7GDQDX{kit>gDqYzS58b_&yP)Sh~f_vJw^;p^2y#yCM zISs%G832=BMOOfjy#g<itZ8sjh%qAAW^Bv`*60mTj5P%F2ncxs9uL7=tJa71X0`2K z0Fy^{M|5Pb+EOU@+MSv0n!aVTywC_UQP^}tC@~Q!V)zipp-xQjU?GoCv#<-!V>7m@ zt+jh(w*X#u^vDspeASlpa4&Rno;k@j!sy{`WCR+Uq@`vIjHM+IP*3zXu&|I&vvBhr zt5-6<$<K?VzkYb!TlQ6k@NB?sS(^L&C?LcJbxBeV4P!bPxB&n$q*1yoOw7%S($HnS z*7M-)+qaW{S-Kae)!%Tptav&c{nXvky?Qv11bdAzqy|N}f`*+93>;<(2f0#8w1lUp z1?ZrY7`SR}R`W7r#`?tgl6cdPoX?M$DvQtWI;4E?_jQN%)H5pc$G$QI+vc!SEpCkx z#+g9_7fww<Ob59J3^Re~!wel*92>>9<vl%HjU$dOFRnk@>KozuLwWI;j6+9TpA<P9 z^!O+Gv8tR#@ILK62><YWiw3doY0iqB7loixbLERs)q}vZn(CFBj4y*vlf@G*mx4&A z#KUY9s5`U+a0(5K8Jrmxni<f*xjYVYjl<l5$<$mFw;W52u(PJ~Y?ErS>hcZ3t)y?l zdFG(xs{LWrE<if(Vc~I42F4{cZ9@aP%LPv6r}8nqK*B}Wq^3BIi41HMZ9dI+=E0g7 z^F_8z^&!U!ZcA%+<m}Ld1loT%61KFZuCA_yf&H}p42&~(3}Bo-MYM#lsVRdE!RT5e zjyKZJ*eLcdY-zH1X85z8H1de_f&$lwUz(Z{Gt=$uzsZzqW}e2MV_<)+-|UD53=I3# z1ks;FbKo-yr|>9KT-raI@mim4p&N{FMfnYvkx$&R<(ms07RfJb`ikXw53l+@$=(}P z?MpK-^c){YFoBt|a4?lG5TfY@J<<>?PQod%2Mgco&28>|0SA}+mYBOllOs`!S5By% zPP)yMN8hY0FHucYC;n_6!ovRAX#_Va6gmb@(5FOo!%@D@y8%T(VK`nksAFI>hf954 z%;R4p&z*B}R#o1+ANee}?qI;Zm|;~&O?-uKytC6Dx4SG1Pcbm+Lj?nKq_BGl<cL6& z0l_s1IIa`6GVq<;+E_=c`7M1i?-E&AIXQIfxDaGy0HG{kNLEo9G~3b;`fob$KNDAn z#=meL|LNn{ylm@ycy*OSUS@~aqoIz7JO_uo2>H;X_Kt|nbMUG0>1pkOx7k6gb9<~7 zEJCZ>+w;OZR<y6^2+x~49dZqygKaNrbM_@`A<7c1j$E{mrQ&LXNj}6do<i42m_idG zhHdGp(6!btt!~$jfdKNv^%F~Pf@{}6Kp=U2GALj!3cqPvwDEaD+=UP)KtA9=x+|;( zEonGTVf=o+#6ZV{H8QY|V_Vy;()sXZo3KF}_YliH(H4`BJIT&qnMJ)MUN8#}B%?Gu zJvX8U6{ChxV-}EBaA;naq7lI&E-X_NrX(pD*wNbVgWLrfSN4qv`{<FrU6J=?Ep_1A z7U{j=!ag@6tWBQYiPMx=VW9K7(TD}3JoFoa0TVAD46^X@tXDVFAV7k3Bmj58T@o<g z>w?IW&lmbl5aqEGH3-e+iMsSUx=|fB7lp(Cl}Z05;e)elg=25lhPU3OFC-`X4O~Pp z(+u8SxX6@Nu-gU$cM%?iDf;}>eg@uPwZ7NbAfwc4%LKv$AESApwMAQTgR)Bj)d}7P zwCAfKkJo5opoC@6Lg<3Mcwvcs4!^5<=}qW6{9V<j###+PoD95|`VaK6Ze=au@=X8$ z04#JxSad^gaCvfRXJ~W)F*!LmAV+d#XCP8<Wo&O|b08>gWp{KyaBpI7crIgaZ7IUp RQSJZ$002ovPDHLkV1iCKFfIT9 literal 0 HcmV?d00001 diff --git a/mod/pub.mod/libpng.mod/pngconf.h b/mod/pub.mod/libpng.mod/pngconf.h new file mode 100644 index 0000000..19acee6 --- /dev/null +++ b/mod/pub.mod/libpng.mod/pngconf.h @@ -0,0 +1,1474 @@ + +/* pngconf.h - machine configurable file for libpng + * + * libpng version 1.2.12 - June 27, 2006 + * For conditions of distribution and use, see copyright notice in png.h + * Copyright (c) 1998-2005 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + */ + +/* Any machine specific code is near the front of this file, so if you + * are configuring libpng for a machine, you may want to read the section + * starting here down to where it starts to typedef png_color, png_text, + * and png_info. + */ + +#ifndef PNGCONF_H +#define PNGCONF_H + +#define PNG_1_2_X + +/* + * PNG_USER_CONFIG has to be defined on the compiler command line. This + * includes the resource compiler for Windows DLL configurations. + */ +#ifdef PNG_USER_CONFIG +# ifndef PNG_USER_PRIVATEBUILD +# define PNG_USER_PRIVATEBUILD +# endif +#include "pngusr.h" +#endif + +/* PNG_CONFIGURE_LIBPNG is set by the "configure" script. */ +#ifdef PNG_CONFIGURE_LIBPNG +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#endif + +/* + * Added at libpng-1.2.8 + * + * If you create a private DLL you need to define in "pngusr.h" the followings: + * #define PNG_USER_PRIVATEBUILD <Describes by whom and why this version of + * the DLL was built> + * e.g. #define PNG_USER_PRIVATEBUILD "Build by MyCompany for xyz reasons." + * #define PNG_USER_DLLFNAME_POSTFIX <two-letter postfix that serve to + * distinguish your DLL from those of the official release. These + * correspond to the trailing letters that come after the version + * number and must match your private DLL name> + * e.g. // private DLL "libpng13gx.dll" + * #define PNG_USER_DLLFNAME_POSTFIX "gx" + * + * The following macros are also at your disposal if you want to complete the + * DLL VERSIONINFO structure. + * - PNG_USER_VERSIONINFO_COMMENTS + * - PNG_USER_VERSIONINFO_COMPANYNAME + * - PNG_USER_VERSIONINFO_LEGALTRADEMARKS + */ + +#ifdef __STDC__ +#ifdef SPECIALBUILD +# pragma message("PNG_LIBPNG_SPECIALBUILD (and deprecated SPECIALBUILD)\ + are now LIBPNG reserved macros. Use PNG_USER_PRIVATEBUILD instead.") +#endif + +#ifdef PRIVATEBUILD +# pragma message("PRIVATEBUILD is deprecated.\ + Use PNG_USER_PRIVATEBUILD instead.") +# define PNG_USER_PRIVATEBUILD PRIVATEBUILD +#endif +#endif /* __STDC__ */ + +#ifndef PNG_VERSION_INFO_ONLY + +/* End of material added to libpng-1.2.8 */ + +/* This is the size of the compression buffer, and thus the size of + * an IDAT chunk. Make this whatever size you feel is best for your + * machine. One of these will be allocated per png_struct. When this + * is full, it writes the data to the disk, and does some other + * calculations. Making this an extremely small size will slow + * the library down, but you may want to experiment to determine + * where it becomes significant, if you are concerned with memory + * usage. Note that zlib allocates at least 32Kb also. For readers, + * this describes the size of the buffer available to read the data in. + * Unless this gets smaller than the size of a row (compressed), + * it should not make much difference how big this is. + */ + +#ifndef PNG_ZBUF_SIZE +# define PNG_ZBUF_SIZE 8192 +#endif + +/* Enable if you want a write-only libpng */ + +#ifndef PNG_NO_READ_SUPPORTED +# define PNG_READ_SUPPORTED +#endif + +/* Enable if you want a read-only libpng */ + +#ifndef PNG_NO_WRITE_SUPPORTED +# define PNG_WRITE_SUPPORTED +#endif + +/* Enabled by default in 1.2.0. You can disable this if you don't need to + support PNGs that are embedded in MNG datastreams */ +#if !defined(PNG_1_0_X) && !defined(PNG_NO_MNG_FEATURES) +# ifndef PNG_MNG_FEATURES_SUPPORTED +# define PNG_MNG_FEATURES_SUPPORTED +# endif +#endif + +#ifndef PNG_NO_FLOATING_POINT_SUPPORTED +# ifndef PNG_FLOATING_POINT_SUPPORTED +# define PNG_FLOATING_POINT_SUPPORTED +# endif +#endif + +/* If you are running on a machine where you cannot allocate more + * than 64K of memory at once, uncomment this. While libpng will not + * normally need that much memory in a chunk (unless you load up a very + * large file), zlib needs to know how big of a chunk it can use, and + * libpng thus makes sure to check any memory allocation to verify it + * will fit into memory. +#define PNG_MAX_MALLOC_64K + */ +#if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K) +# define PNG_MAX_MALLOC_64K +#endif + +/* Special munging to support doing things the 'cygwin' way: + * 'Normal' png-on-win32 defines/defaults: + * PNG_BUILD_DLL -- building dll + * PNG_USE_DLL -- building an application, linking to dll + * (no define) -- building static library, or building an + * application and linking to the static lib + * 'Cygwin' defines/defaults: + * PNG_BUILD_DLL -- (ignored) building the dll + * (no define) -- (ignored) building an application, linking to the dll + * PNG_STATIC -- (ignored) building the static lib, or building an + * application that links to the static lib. + * ALL_STATIC -- (ignored) building various static libs, or building an + * application that links to the static libs. + * Thus, + * a cygwin user should define either PNG_BUILD_DLL or PNG_STATIC, and + * this bit of #ifdefs will define the 'correct' config variables based on + * that. If a cygwin user *wants* to define 'PNG_USE_DLL' that's okay, but + * unnecessary. + * + * Also, the precedence order is: + * ALL_STATIC (since we can't #undef something outside our namespace) + * PNG_BUILD_DLL + * PNG_STATIC + * (nothing) == PNG_USE_DLL + * + * CYGWIN (2002-01-20): The preceding is now obsolete. With the advent + * of auto-import in binutils, we no longer need to worry about + * __declspec(dllexport) / __declspec(dllimport) and friends. Therefore, + * we don't need to worry about PNG_STATIC or ALL_STATIC when it comes + * to __declspec() stuff. However, we DO need to worry about + * PNG_BUILD_DLL and PNG_STATIC because those change some defaults + * such as CONSOLE_IO and whether GLOBAL_ARRAYS are allowed. + */ +#if defined(__CYGWIN__) +# if defined(ALL_STATIC) +# if defined(PNG_BUILD_DLL) +# undef PNG_BUILD_DLL +# endif +# if defined(PNG_USE_DLL) +# undef PNG_USE_DLL +# endif +# if defined(PNG_DLL) +# undef PNG_DLL +# endif +# if !defined(PNG_STATIC) +# define PNG_STATIC +# endif +# else +# if defined (PNG_BUILD_DLL) +# if defined(PNG_STATIC) +# undef PNG_STATIC +# endif +# if defined(PNG_USE_DLL) +# undef PNG_USE_DLL +# endif +# if !defined(PNG_DLL) +# define PNG_DLL +# endif +# else +# if defined(PNG_STATIC) +# if defined(PNG_USE_DLL) +# undef PNG_USE_DLL +# endif +# if defined(PNG_DLL) +# undef PNG_DLL +# endif +# else +# if !defined(PNG_USE_DLL) +# define PNG_USE_DLL +# endif +# if !defined(PNG_DLL) +# define PNG_DLL +# endif +# endif +# endif +# endif +#endif + +/* This protects us against compilers that run on a windowing system + * and thus don't have or would rather us not use the stdio types: + * stdin, stdout, and stderr. The only one currently used is stderr + * in png_error() and png_warning(). #defining PNG_NO_CONSOLE_IO will + * prevent these from being compiled and used. #defining PNG_NO_STDIO + * will also prevent these, plus will prevent the entire set of stdio + * macros and functions (FILE *, printf, etc.) from being compiled and used, + * unless (PNG_DEBUG > 0) has been #defined. + * + * #define PNG_NO_CONSOLE_IO + * #define PNG_NO_STDIO + */ + +#define PNG_NO_CONSOLE_IO + +#if defined(_WIN32_WCE) +# include <windows.h> + /* Console I/O functions are not supported on WindowsCE */ +# define PNG_NO_CONSOLE_IO +# ifdef PNG_DEBUG +# undef PNG_DEBUG +# endif +#endif + +#ifdef PNG_BUILD_DLL +# ifndef PNG_CONSOLE_IO_SUPPORTED +# ifndef PNG_NO_CONSOLE_IO +# define PNG_NO_CONSOLE_IO +# endif +# endif +#endif + +# ifdef PNG_NO_STDIO +# ifndef PNG_NO_CONSOLE_IO +# define PNG_NO_CONSOLE_IO +# endif +# ifdef PNG_DEBUG +# if (PNG_DEBUG > 0) +# include <stdio.h> +# endif +# endif +# else +# if !defined(_WIN32_WCE) +/* "stdio.h" functions are not supported on WindowsCE */ +# include <stdio.h> +# endif +# endif + +/* This macro protects us against machines that don't have function + * prototypes (ie K&R style headers). If your compiler does not handle + * function prototypes, define this macro and use the included ansi2knr. + * I've always been able to use _NO_PROTO as the indicator, but you may + * need to drag the empty declaration out in front of here, or change the + * ifdef to suit your own needs. + */ +#ifndef PNGARG + +#ifdef OF /* zlib prototype munger */ +# define PNGARG(arglist) OF(arglist) +#else + +#ifdef _NO_PROTO +# define PNGARG(arglist) () +# ifndef PNG_TYPECAST_NULL +# define PNG_TYPECAST_NULL +# endif +#else +# define PNGARG(arglist) arglist +#endif /* _NO_PROTO */ + +#endif /* OF */ + +#endif /* PNGARG */ + +/* Try to determine if we are compiling on a Mac. Note that testing for + * just __MWERKS__ is not good enough, because the Codewarrior is now used + * on non-Mac platforms. + */ +#ifndef MACOS +# if (defined(__MWERKS__) && defined(macintosh)) || defined(applec) || \ + defined(THINK_C) || defined(__SC__) || defined(TARGET_OS_MAC) +# define MACOS +# endif +#endif + +/* enough people need this for various reasons to include it here */ +#if !defined(MACOS) && !defined(RISCOS) && !defined(_WIN32_WCE) +# include <sys/types.h> +#endif + +#if !defined(PNG_SETJMP_NOT_SUPPORTED) && !defined(PNG_NO_SETJMP_SUPPORTED) +# define PNG_SETJMP_SUPPORTED +#endif + +#ifdef PNG_SETJMP_SUPPORTED +/* This is an attempt to force a single setjmp behaviour on Linux. If + * the X config stuff didn't define _BSD_SOURCE we wouldn't need this. + */ + +# ifdef __linux__ +# ifdef _BSD_SOURCE +# define PNG_SAVE_BSD_SOURCE +# undef _BSD_SOURCE +# endif +# ifdef _SETJMP_H + /* If you encounter a compiler error here, see the explanation + * near the end of INSTALL. + */ + __png.h__ already includes setjmp.h; + __dont__ include it again.; +# endif +# endif /* __linux__ */ + + /* include setjmp.h for error handling */ +# include <setjmp.h> + +# ifdef __linux__ +# ifdef PNG_SAVE_BSD_SOURCE +# define _BSD_SOURCE +# undef PNG_SAVE_BSD_SOURCE +# endif +# endif /* __linux__ */ +#endif /* PNG_SETJMP_SUPPORTED */ + +#ifdef BSD +# include <strings.h> +#else +# include <string.h> +#endif + +/* Other defines for things like memory and the like can go here. */ +#ifdef PNG_INTERNAL + +#include <stdlib.h> + +/* The functions exported by PNG_EXTERN are PNG_INTERNAL functions, which + * aren't usually used outside the library (as far as I know), so it is + * debatable if they should be exported at all. In the future, when it is + * possible to have run-time registry of chunk-handling functions, some of + * these will be made available again. +#define PNG_EXTERN extern + */ +#define PNG_EXTERN + +/* Other defines specific to compilers can go here. Try to keep + * them inside an appropriate ifdef/endif pair for portability. + */ + +#if defined(PNG_FLOATING_POINT_SUPPORTED) +# if defined(MACOS) + /* We need to check that <math.h> hasn't already been included earlier + * as it seems it doesn't agree with <fp.h>, yet we should really use + * <fp.h> if possible. + */ +# if !defined(__MATH_H__) && !defined(__MATH_H) && !defined(__cmath__) +# include <fp.h> +# endif +# else +# include <math.h> +# endif +# if defined(_AMIGA) && defined(__SASC) && defined(_M68881) + /* Amiga SAS/C: We must include builtin FPU functions when compiling using + * MATH=68881 + */ +# include <m68881.h> +# endif +#endif + +/* Codewarrior on NT has linking problems without this. */ +#if (defined(__MWERKS__) && defined(WIN32)) || defined(__STDC__) +# define PNG_ALWAYS_EXTERN +#endif + +/* This provides the non-ANSI (far) memory allocation routines. */ +#if defined(__TURBOC__) && defined(__MSDOS__) +# include <mem.h> +# include <alloc.h> +#endif + +/* I have no idea why is this necessary... */ +#if defined(_MSC_VER) && (defined(WIN32) || defined(_Windows) || \ + defined(_WINDOWS) || defined(_WIN32) || defined(__WIN32__)) +# include <malloc.h> +#endif + +/* This controls how fine the dithering gets. As this allocates + * a largish chunk of memory (32K), those who are not as concerned + * with dithering quality can decrease some or all of these. + */ +#ifndef PNG_DITHER_RED_BITS +# define PNG_DITHER_RED_BITS 5 +#endif +#ifndef PNG_DITHER_GREEN_BITS +# define PNG_DITHER_GREEN_BITS 5 +#endif +#ifndef PNG_DITHER_BLUE_BITS +# define PNG_DITHER_BLUE_BITS 5 +#endif + +/* This controls how fine the gamma correction becomes when you + * are only interested in 8 bits anyway. Increasing this value + * results in more memory being used, and more pow() functions + * being called to fill in the gamma tables. Don't set this value + * less then 8, and even that may not work (I haven't tested it). + */ + +#ifndef PNG_MAX_GAMMA_8 +# define PNG_MAX_GAMMA_8 11 +#endif + +/* This controls how much a difference in gamma we can tolerate before + * we actually start doing gamma conversion. + */ +#ifndef PNG_GAMMA_THRESHOLD +# define PNG_GAMMA_THRESHOLD 0.05 +#endif + +#endif /* PNG_INTERNAL */ + +/* The following uses const char * instead of char * for error + * and warning message functions, so some compilers won't complain. + * If you do not want to use const, define PNG_NO_CONST here. + */ + +#ifndef PNG_NO_CONST +# define PNG_CONST const +#else +# define PNG_CONST +#endif + +/* The following defines give you the ability to remove code from the + * library that you will not be using. I wish I could figure out how to + * automate this, but I can't do that without making it seriously hard + * on the users. So if you are not using an ability, change the #define + * to and #undef, and that part of the library will not be compiled. If + * your linker can't find a function, you may want to make sure the + * ability is defined here. Some of these depend upon some others being + * defined. I haven't figured out all the interactions here, so you may + * have to experiment awhile to get everything to compile. If you are + * creating or using a shared library, you probably shouldn't touch this, + * as it will affect the size of the structures, and this will cause bad + * things to happen if the library and/or application ever change. + */ + +/* Any features you will not be using can be undef'ed here */ + +/* GR-P, 0.96a: Set "*TRANSFORMS_SUPPORTED as default but allow user + * to turn it off with "*TRANSFORMS_NOT_SUPPORTED" or *PNG_NO_*_TRANSFORMS + * on the compile line, then pick and choose which ones to define without + * having to edit this file. It is safe to use the *TRANSFORMS_NOT_SUPPORTED + * if you only want to have a png-compliant reader/writer but don't need + * any of the extra transformations. This saves about 80 kbytes in a + * typical installation of the library. (PNG_NO_* form added in version + * 1.0.1c, for consistency) + */ + +/* The size of the png_text structure changed in libpng-1.0.6 when + * iTXt support was added. iTXt support was turned off by default through + * libpng-1.2.x, to support old apps that malloc the png_text structure + * instead of calling png_set_text() and letting libpng malloc it. It + * was turned on by default in libpng-1.3.0. + */ + +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) +# ifndef PNG_NO_iTXt_SUPPORTED +# define PNG_NO_iTXt_SUPPORTED +# endif +# ifndef PNG_NO_READ_iTXt +# define PNG_NO_READ_iTXt +# endif +# ifndef PNG_NO_WRITE_iTXt +# define PNG_NO_WRITE_iTXt +# endif +#endif + +#if !defined(PNG_NO_iTXt_SUPPORTED) +# if !defined(PNG_READ_iTXt_SUPPORTED) && !defined(PNG_NO_READ_iTXt) +# define PNG_READ_iTXt +# endif +# if !defined(PNG_WRITE_iTXt_SUPPORTED) && !defined(PNG_NO_WRITE_iTXt) +# define PNG_WRITE_iTXt +# endif +#endif + +/* The following support, added after version 1.0.0, can be turned off here en + * masse by defining PNG_LEGACY_SUPPORTED in case you need binary compatibility + * with old applications that require the length of png_struct and png_info + * to remain unchanged. + */ + +#ifdef PNG_LEGACY_SUPPORTED +# define PNG_NO_FREE_ME +# define PNG_NO_READ_UNKNOWN_CHUNKS +# define PNG_NO_WRITE_UNKNOWN_CHUNKS +# define PNG_NO_READ_USER_CHUNKS +# define PNG_NO_READ_iCCP +# define PNG_NO_WRITE_iCCP +# define PNG_NO_READ_iTXt +# define PNG_NO_WRITE_iTXt +# define PNG_NO_READ_sCAL +# define PNG_NO_WRITE_sCAL +# define PNG_NO_READ_sPLT +# define PNG_NO_WRITE_sPLT +# define PNG_NO_INFO_IMAGE +# define PNG_NO_READ_RGB_TO_GRAY +# define PNG_NO_READ_USER_TRANSFORM +# define PNG_NO_WRITE_USER_TRANSFORM +# define PNG_NO_USER_MEM +# define PNG_NO_READ_EMPTY_PLTE +# define PNG_NO_MNG_FEATURES +# define PNG_NO_FIXED_POINT_SUPPORTED +#endif + +/* Ignore attempt to turn off both floating and fixed point support */ +#if !defined(PNG_FLOATING_POINT_SUPPORTED) || \ + !defined(PNG_NO_FIXED_POINT_SUPPORTED) +# define PNG_FIXED_POINT_SUPPORTED +#endif + +#ifndef PNG_NO_FREE_ME +# define PNG_FREE_ME_SUPPORTED +#endif + +#if defined(PNG_READ_SUPPORTED) + +#if !defined(PNG_READ_TRANSFORMS_NOT_SUPPORTED) && \ + !defined(PNG_NO_READ_TRANSFORMS) +# define PNG_READ_TRANSFORMS_SUPPORTED +#endif + +#ifdef PNG_READ_TRANSFORMS_SUPPORTED +# ifndef PNG_NO_READ_EXPAND +# define PNG_READ_EXPAND_SUPPORTED +# endif +# ifndef PNG_NO_READ_SHIFT +# define PNG_READ_SHIFT_SUPPORTED +# endif +# ifndef PNG_NO_READ_PACK +# define PNG_READ_PACK_SUPPORTED +# endif +# ifndef PNG_NO_READ_BGR +# define PNG_READ_BGR_SUPPORTED +# endif +# ifndef PNG_NO_READ_SWAP +# define PNG_READ_SWAP_SUPPORTED +# endif +# ifndef PNG_NO_READ_PACKSWAP +# define PNG_READ_PACKSWAP_SUPPORTED +# endif +# ifndef PNG_NO_READ_INVERT +# define PNG_READ_INVERT_SUPPORTED +# endif +# ifndef PNG_NO_READ_DITHER +# define PNG_READ_DITHER_SUPPORTED +# endif +# ifndef PNG_NO_READ_BACKGROUND +# define PNG_READ_BACKGROUND_SUPPORTED +# endif +# ifndef PNG_NO_READ_16_TO_8 +# define PNG_READ_16_TO_8_SUPPORTED +# endif +# ifndef PNG_NO_READ_FILLER +# define PNG_READ_FILLER_SUPPORTED +# endif +# ifndef PNG_NO_READ_GAMMA +# define PNG_READ_GAMMA_SUPPORTED +# endif +# ifndef PNG_NO_READ_GRAY_TO_RGB +# define PNG_READ_GRAY_TO_RGB_SUPPORTED +# endif +# ifndef PNG_NO_READ_SWAP_ALPHA +# define PNG_READ_SWAP_ALPHA_SUPPORTED +# endif +# ifndef PNG_NO_READ_INVERT_ALPHA +# define PNG_READ_INVERT_ALPHA_SUPPORTED +# endif +# ifndef PNG_NO_READ_STRIP_ALPHA +# define PNG_READ_STRIP_ALPHA_SUPPORTED +# endif +# ifndef PNG_NO_READ_USER_TRANSFORM +# define PNG_READ_USER_TRANSFORM_SUPPORTED +# endif +# ifndef PNG_NO_READ_RGB_TO_GRAY +# define PNG_READ_RGB_TO_GRAY_SUPPORTED +# endif +#endif /* PNG_READ_TRANSFORMS_SUPPORTED */ + +#if !defined(PNG_NO_PROGRESSIVE_READ) && \ + !defined(PNG_PROGRESSIVE_READ_NOT_SUPPORTED) /* if you don't do progressive */ +# define PNG_PROGRESSIVE_READ_SUPPORTED /* reading. This is not talking */ +#endif /* about interlacing capability! You'll */ + /* still have interlacing unless you change the following line: */ + +#define PNG_READ_INTERLACING_SUPPORTED /* required for PNG-compliant decoders */ + +#ifndef PNG_NO_READ_COMPOSITE_NODIV +# ifndef PNG_NO_READ_COMPOSITED_NODIV /* libpng-1.0.x misspelling */ +# define PNG_READ_COMPOSITE_NODIV_SUPPORTED /* well tested on Intel, SGI */ +# endif +#endif + +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) +/* Deprecated, will be removed from version 2.0.0. + Use PNG_MNG_FEATURES_SUPPORTED instead. */ +#ifndef PNG_NO_READ_EMPTY_PLTE +# define PNG_READ_EMPTY_PLTE_SUPPORTED +#endif +#endif + +#endif /* PNG_READ_SUPPORTED */ + +#if defined(PNG_WRITE_SUPPORTED) + +# if !defined(PNG_WRITE_TRANSFORMS_NOT_SUPPORTED) && \ + !defined(PNG_NO_WRITE_TRANSFORMS) +# define PNG_WRITE_TRANSFORMS_SUPPORTED +#endif + +#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED +# ifndef PNG_NO_WRITE_SHIFT +# define PNG_WRITE_SHIFT_SUPPORTED +# endif +# ifndef PNG_NO_WRITE_PACK +# define PNG_WRITE_PACK_SUPPORTED +# endif +# ifndef PNG_NO_WRITE_BGR +# define PNG_WRITE_BGR_SUPPORTED +# endif +# ifndef PNG_NO_WRITE_SWAP +# define PNG_WRITE_SWAP_SUPPORTED +# endif +# ifndef PNG_NO_WRITE_PACKSWAP +# define PNG_WRITE_PACKSWAP_SUPPORTED +# endif +# ifndef PNG_NO_WRITE_INVERT +# define PNG_WRITE_INVERT_SUPPORTED +# endif +# ifndef PNG_NO_WRITE_FILLER +# define PNG_WRITE_FILLER_SUPPORTED /* same as WRITE_STRIP_ALPHA */ +# endif +# ifndef PNG_NO_WRITE_SWAP_ALPHA +# define PNG_WRITE_SWAP_ALPHA_SUPPORTED +# endif +# ifndef PNG_NO_WRITE_INVERT_ALPHA +# define PNG_WRITE_INVERT_ALPHA_SUPPORTED +# endif +# ifndef PNG_NO_WRITE_USER_TRANSFORM +# define PNG_WRITE_USER_TRANSFORM_SUPPORTED +# endif +#endif /* PNG_WRITE_TRANSFORMS_SUPPORTED */ + +#if !defined(PNG_NO_WRITE_INTERLACING_SUPPORTED) && \ + !defined(PNG_WRITE_INTERLACING_SUPPORTED) +#define PNG_WRITE_INTERLACING_SUPPORTED /* not required for PNG-compliant + encoders, but can cause trouble + if left undefined */ +#endif + +#if !defined(PNG_NO_WRITE_WEIGHTED_FILTER) && \ + !defined(PNG_WRITE_WEIGHTED_FILTER) && \ + defined(PNG_FLOATING_POINT_SUPPORTED) +# define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED +#endif + +#ifndef PNG_NO_WRITE_FLUSH +# define PNG_WRITE_FLUSH_SUPPORTED +#endif + +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) +/* Deprecated, see PNG_MNG_FEATURES_SUPPORTED, above */ +#ifndef PNG_NO_WRITE_EMPTY_PLTE +# define PNG_WRITE_EMPTY_PLTE_SUPPORTED +#endif +#endif + +#endif /* PNG_WRITE_SUPPORTED */ + +#ifndef PNG_1_0_X +# ifndef PNG_NO_ERROR_NUMBERS +# define PNG_ERROR_NUMBERS_SUPPORTED +# endif +#endif /* PNG_1_0_X */ + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) +# ifndef PNG_NO_USER_TRANSFORM_PTR +# define PNG_USER_TRANSFORM_PTR_SUPPORTED +# endif +#endif + +#ifndef PNG_NO_STDIO +# define PNG_TIME_RFC1123_SUPPORTED +#endif + +/* This adds extra functions in pngget.c for accessing data from the + * info pointer (added in version 0.99) + * png_get_image_width() + * png_get_image_height() + * png_get_bit_depth() + * png_get_color_type() + * png_get_compression_type() + * png_get_filter_type() + * png_get_interlace_type() + * png_get_pixel_aspect_ratio() + * png_get_pixels_per_meter() + * png_get_x_offset_pixels() + * png_get_y_offset_pixels() + * png_get_x_offset_microns() + * png_get_y_offset_microns() + */ +#if !defined(PNG_NO_EASY_ACCESS) && !defined(PNG_EASY_ACCESS_SUPPORTED) +# define PNG_EASY_ACCESS_SUPPORTED +#endif + +/* PNG_ASSEMBLER_CODE was enabled by default in version 1.2.0 + even when PNG_USE_PNGVCRD or PNG_USE_PNGGCCRD is not defined */ +#if defined(PNG_READ_SUPPORTED) && !defined(PNG_NO_ASSEMBLER_CODE) +# ifndef PNG_ASSEMBLER_CODE_SUPPORTED +# define PNG_ASSEMBLER_CODE_SUPPORTED +# endif +# if !defined(PNG_MMX_CODE_SUPPORTED) && !defined(PNG_NO_MMX_CODE) && \ + defined(__MMX__) +# define PNG_MMX_CODE_SUPPORTED +# endif +# if !defined(PNG_USE_PNGGCCRD) && !defined(PNG_NO_MMX_CODE) && \ + !defined(PNG_USE_PNGVCRD) && defined(__MMX__) +# define PNG_USE_PNGGCCRD +# endif +#endif + +/* If you are sure that you don't need thread safety and you are compiling + with PNG_USE_PNGCCRD for an MMX application, you can define this for + faster execution. See pnggccrd.c. +#define PNG_THREAD_UNSAFE_OK +*/ + +#if !defined(PNG_1_0_X) +#if !defined(PNG_NO_USER_MEM) && !defined(PNG_USER_MEM_SUPPORTED) +# define PNG_USER_MEM_SUPPORTED +#endif +#endif /* PNG_1_0_X */ + +/* Added at libpng-1.2.6 */ +#if !defined(PNG_1_0_X) +#ifndef PNG_SET_USER_LIMITS_SUPPORTED +#if !defined(PNG_NO_SET_USER_LIMITS) && !defined(PNG_SET_USER_LIMITS_SUPPORTED) +# define PNG_SET_USER_LIMITS_SUPPORTED +#endif +#endif +#endif /* PNG_1_0_X */ + +/* Added at libpng-1.0.16 and 1.2.6. To accept all valid PNGS no matter + * how large, set these limits to 0x7fffffffL + */ +#ifndef PNG_USER_WIDTH_MAX +# define PNG_USER_WIDTH_MAX 1000000L +#endif +#ifndef PNG_USER_HEIGHT_MAX +# define PNG_USER_HEIGHT_MAX 1000000L +#endif + +/* These are currently experimental features, define them if you want */ + +/* very little testing */ +/* +#ifdef PNG_READ_SUPPORTED +# ifndef PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED +# define PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED +# endif +#endif +*/ + +/* This is only for PowerPC big-endian and 680x0 systems */ +/* some testing */ +/* +#ifndef PNG_READ_BIG_ENDIAN_SUPPORTED +# define PNG_READ_BIG_ENDIAN_SUPPORTED +#endif +*/ + +/* Buggy compilers (e.g., gcc 2.7.2.2) need this */ +/* +#define PNG_NO_POINTER_INDEXING +*/ + +/* These functions are turned off by default, as they will be phased out. */ +/* +#define PNG_USELESS_TESTS_SUPPORTED +#define PNG_CORRECT_PALETTE_SUPPORTED +*/ + +/* Any chunks you are not interested in, you can undef here. The + * ones that allocate memory may be expecially important (hIST, + * tEXt, zTXt, tRNS, pCAL). Others will just save time and make png_info + * a bit smaller. + */ + +#if defined(PNG_READ_SUPPORTED) && \ + !defined(PNG_READ_ANCILLARY_CHUNKS_NOT_SUPPORTED) && \ + !defined(PNG_NO_READ_ANCILLARY_CHUNKS) +# define PNG_READ_ANCILLARY_CHUNKS_SUPPORTED +#endif + +#if defined(PNG_WRITE_SUPPORTED) && \ + !defined(PNG_WRITE_ANCILLARY_CHUNKS_NOT_SUPPORTED) && \ + !defined(PNG_NO_WRITE_ANCILLARY_CHUNKS) +# define PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED +#endif + +#ifdef PNG_READ_ANCILLARY_CHUNKS_SUPPORTED + +#ifdef PNG_NO_READ_TEXT +# define PNG_NO_READ_iTXt +# define PNG_NO_READ_tEXt +# define PNG_NO_READ_zTXt +#endif +#ifndef PNG_NO_READ_bKGD +# define PNG_READ_bKGD_SUPPORTED +# define PNG_bKGD_SUPPORTED +#endif +#ifndef PNG_NO_READ_cHRM +# define PNG_READ_cHRM_SUPPORTED +# define PNG_cHRM_SUPPORTED +#endif +#ifndef PNG_NO_READ_gAMA +# define PNG_READ_gAMA_SUPPORTED +# define PNG_gAMA_SUPPORTED +#endif +#ifndef PNG_NO_READ_hIST +# define PNG_READ_hIST_SUPPORTED +# define PNG_hIST_SUPPORTED +#endif +#ifndef PNG_NO_READ_iCCP +# define PNG_READ_iCCP_SUPPORTED +# define PNG_iCCP_SUPPORTED +#endif +#ifndef PNG_NO_READ_iTXt +# ifndef PNG_READ_iTXt_SUPPORTED +# define PNG_READ_iTXt_SUPPORTED +# endif +# ifndef PNG_iTXt_SUPPORTED +# define PNG_iTXt_SUPPORTED +# endif +#endif +#ifndef PNG_NO_READ_oFFs +# define PNG_READ_oFFs_SUPPORTED +# define PNG_oFFs_SUPPORTED +#endif +#ifndef PNG_NO_READ_pCAL +# define PNG_READ_pCAL_SUPPORTED +# define PNG_pCAL_SUPPORTED +#endif +#ifndef PNG_NO_READ_sCAL +# define PNG_READ_sCAL_SUPPORTED +# define PNG_sCAL_SUPPORTED +#endif +#ifndef PNG_NO_READ_pHYs +# define PNG_READ_pHYs_SUPPORTED +# define PNG_pHYs_SUPPORTED +#endif +#ifndef PNG_NO_READ_sBIT +# define PNG_READ_sBIT_SUPPORTED +# define PNG_sBIT_SUPPORTED +#endif +#ifndef PNG_NO_READ_sPLT +# define PNG_READ_sPLT_SUPPORTED +# define PNG_sPLT_SUPPORTED +#endif +#ifndef PNG_NO_READ_sRGB +# define PNG_READ_sRGB_SUPPORTED +# define PNG_sRGB_SUPPORTED +#endif +#ifndef PNG_NO_READ_tEXt +# define PNG_READ_tEXt_SUPPORTED +# define PNG_tEXt_SUPPORTED +#endif +#ifndef PNG_NO_READ_tIME +# define PNG_READ_tIME_SUPPORTED +# define PNG_tIME_SUPPORTED +#endif +#ifndef PNG_NO_READ_tRNS +# define PNG_READ_tRNS_SUPPORTED +# define PNG_tRNS_SUPPORTED +#endif +#ifndef PNG_NO_READ_zTXt +# define PNG_READ_zTXt_SUPPORTED +# define PNG_zTXt_SUPPORTED +#endif +#ifndef PNG_NO_READ_UNKNOWN_CHUNKS +# define PNG_READ_UNKNOWN_CHUNKS_SUPPORTED +# ifndef PNG_UNKNOWN_CHUNKS_SUPPORTED +# define PNG_UNKNOWN_CHUNKS_SUPPORTED +# endif +# ifndef PNG_NO_HANDLE_AS_UNKNOWN +# define PNG_HANDLE_AS_UNKNOWN_SUPPORTED +# endif +#endif +#if !defined(PNG_NO_READ_USER_CHUNKS) && \ + defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) +# define PNG_READ_USER_CHUNKS_SUPPORTED +# define PNG_USER_CHUNKS_SUPPORTED +# ifdef PNG_NO_READ_UNKNOWN_CHUNKS +# undef PNG_NO_READ_UNKNOWN_CHUNKS +# endif +# ifdef PNG_NO_HANDLE_AS_UNKNOWN +# undef PNG_NO_HANDLE_AS_UNKNOWN +# endif +#endif +#ifndef PNG_NO_READ_OPT_PLTE +# define PNG_READ_OPT_PLTE_SUPPORTED /* only affects support of the */ +#endif /* optional PLTE chunk in RGB and RGBA images */ +#if defined(PNG_READ_iTXt_SUPPORTED) || defined(PNG_READ_tEXt_SUPPORTED) || \ + defined(PNG_READ_zTXt_SUPPORTED) +# define PNG_READ_TEXT_SUPPORTED +# define PNG_TEXT_SUPPORTED +#endif + +#endif /* PNG_READ_ANCILLARY_CHUNKS_SUPPORTED */ + +#ifdef PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED + +#ifdef PNG_NO_WRITE_TEXT +# define PNG_NO_WRITE_iTXt +# define PNG_NO_WRITE_tEXt +# define PNG_NO_WRITE_zTXt +#endif +#ifndef PNG_NO_WRITE_bKGD +# define PNG_WRITE_bKGD_SUPPORTED +# ifndef PNG_bKGD_SUPPORTED +# define PNG_bKGD_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_cHRM +# define PNG_WRITE_cHRM_SUPPORTED +# ifndef PNG_cHRM_SUPPORTED +# define PNG_cHRM_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_gAMA +# define PNG_WRITE_gAMA_SUPPORTED +# ifndef PNG_gAMA_SUPPORTED +# define PNG_gAMA_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_hIST +# define PNG_WRITE_hIST_SUPPORTED +# ifndef PNG_hIST_SUPPORTED +# define PNG_hIST_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_iCCP +# define PNG_WRITE_iCCP_SUPPORTED +# ifndef PNG_iCCP_SUPPORTED +# define PNG_iCCP_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_iTXt +# ifndef PNG_WRITE_iTXt_SUPPORTED +# define PNG_WRITE_iTXt_SUPPORTED +# endif +# ifndef PNG_iTXt_SUPPORTED +# define PNG_iTXt_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_oFFs +# define PNG_WRITE_oFFs_SUPPORTED +# ifndef PNG_oFFs_SUPPORTED +# define PNG_oFFs_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_pCAL +# define PNG_WRITE_pCAL_SUPPORTED +# ifndef PNG_pCAL_SUPPORTED +# define PNG_pCAL_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_sCAL +# define PNG_WRITE_sCAL_SUPPORTED +# ifndef PNG_sCAL_SUPPORTED +# define PNG_sCAL_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_pHYs +# define PNG_WRITE_pHYs_SUPPORTED +# ifndef PNG_pHYs_SUPPORTED +# define PNG_pHYs_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_sBIT +# define PNG_WRITE_sBIT_SUPPORTED +# ifndef PNG_sBIT_SUPPORTED +# define PNG_sBIT_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_sPLT +# define PNG_WRITE_sPLT_SUPPORTED +# ifndef PNG_sPLT_SUPPORTED +# define PNG_sPLT_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_sRGB +# define PNG_WRITE_sRGB_SUPPORTED +# ifndef PNG_sRGB_SUPPORTED +# define PNG_sRGB_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_tEXt +# define PNG_WRITE_tEXt_SUPPORTED +# ifndef PNG_tEXt_SUPPORTED +# define PNG_tEXt_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_tIME +# define PNG_WRITE_tIME_SUPPORTED +# ifndef PNG_tIME_SUPPORTED +# define PNG_tIME_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_tRNS +# define PNG_WRITE_tRNS_SUPPORTED +# ifndef PNG_tRNS_SUPPORTED +# define PNG_tRNS_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_zTXt +# define PNG_WRITE_zTXt_SUPPORTED +# ifndef PNG_zTXt_SUPPORTED +# define PNG_zTXt_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_UNKNOWN_CHUNKS +# define PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED +# ifndef PNG_UNKNOWN_CHUNKS_SUPPORTED +# define PNG_UNKNOWN_CHUNKS_SUPPORTED +# endif +# ifndef PNG_NO_HANDLE_AS_UNKNOWN +# ifndef PNG_HANDLE_AS_UNKNOWN_SUPPORTED +# define PNG_HANDLE_AS_UNKNOWN_SUPPORTED +# endif +# endif +#endif +#if defined(PNG_WRITE_iTXt_SUPPORTED) || defined(PNG_WRITE_tEXt_SUPPORTED) || \ + defined(PNG_WRITE_zTXt_SUPPORTED) +# define PNG_WRITE_TEXT_SUPPORTED +# ifndef PNG_TEXT_SUPPORTED +# define PNG_TEXT_SUPPORTED +# endif +#endif + +#endif /* PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED */ + +/* Turn this off to disable png_read_png() and + * png_write_png() and leave the row_pointers member + * out of the info structure. + */ +#ifndef PNG_NO_INFO_IMAGE +# define PNG_INFO_IMAGE_SUPPORTED +#endif + +/* need the time information for reading tIME chunks */ +#if defined(PNG_tIME_SUPPORTED) +# if !defined(_WIN32_WCE) + /* "time.h" functions are not supported on WindowsCE */ +# include <time.h> +# endif +#endif + +/* Some typedefs to get us started. These should be safe on most of the + * common platforms. The typedefs should be at least as large as the + * numbers suggest (a png_uint_32 must be at least 32 bits long), but they + * don't have to be exactly that size. Some compilers dislike passing + * unsigned shorts as function parameters, so you may be better off using + * unsigned int for png_uint_16. Likewise, for 64-bit systems, you may + * want to have unsigned int for png_uint_32 instead of unsigned long. + */ + +typedef unsigned long png_uint_32; +typedef long png_int_32; +typedef unsigned short png_uint_16; +typedef short png_int_16; +typedef unsigned char png_byte; + +/* This is usually size_t. It is typedef'ed just in case you need it to + change (I'm not sure if you will or not, so I thought I'd be safe) */ +#ifdef PNG_SIZE_T + typedef PNG_SIZE_T png_size_t; +# define png_sizeof(x) png_convert_size(sizeof (x)) +#else + typedef size_t png_size_t; +# define png_sizeof(x) sizeof (x) +#endif + +/* The following is needed for medium model support. It cannot be in the + * PNG_INTERNAL section. Needs modification for other compilers besides + * MSC. Model independent support declares all arrays and pointers to be + * large using the far keyword. The zlib version used must also support + * model independent data. As of version zlib 1.0.4, the necessary changes + * have been made in zlib. The USE_FAR_KEYWORD define triggers other + * changes that are needed. (Tim Wegner) + */ + +/* Separate compiler dependencies (problem here is that zlib.h always + defines FAR. (SJT) */ +#ifdef __BORLANDC__ +# if defined(__LARGE__) || defined(__HUGE__) || defined(__COMPACT__) +# define LDATA 1 +# else +# define LDATA 0 +# endif + /* GRR: why is Cygwin in here? Cygwin is not Borland C... */ +# if !defined(__WIN32__) && !defined(__FLAT__) && !defined(__CYGWIN__) +# define PNG_MAX_MALLOC_64K +# if (LDATA != 1) +# ifndef FAR +# define FAR __far +# endif +# define USE_FAR_KEYWORD +# endif /* LDATA != 1 */ + /* Possibly useful for moving data out of default segment. + * Uncomment it if you want. Could also define FARDATA as + * const if your compiler supports it. (SJT) +# define FARDATA FAR + */ +# endif /* __WIN32__, __FLAT__, __CYGWIN__ */ +#endif /* __BORLANDC__ */ + + +/* Suggest testing for specific compiler first before testing for + * FAR. The Watcom compiler defines both __MEDIUM__ and M_I86MM, + * making reliance oncertain keywords suspect. (SJT) + */ + +/* MSC Medium model */ +#if defined(FAR) +# if defined(M_I86MM) +# define USE_FAR_KEYWORD +# define FARDATA FAR +# include <dos.h> +# endif +#endif + +/* SJT: default case */ +#ifndef FAR +# define FAR +#endif + +/* At this point FAR is always defined */ +#ifndef FARDATA +# define FARDATA +#endif + +/* Typedef for floating-point numbers that are converted + to fixed-point with a multiple of 100,000, e.g., int_gamma */ +typedef png_int_32 png_fixed_point; + +/* Add typedefs for pointers */ +typedef void FAR * png_voidp; +typedef png_byte FAR * png_bytep; +typedef png_uint_32 FAR * png_uint_32p; +typedef png_int_32 FAR * png_int_32p; +typedef png_uint_16 FAR * png_uint_16p; +typedef png_int_16 FAR * png_int_16p; +typedef PNG_CONST char FAR * png_const_charp; +typedef char FAR * png_charp; +typedef png_fixed_point FAR * png_fixed_point_p; + +#ifndef PNG_NO_STDIO +#if defined(_WIN32_WCE) +typedef HANDLE png_FILE_p; +#else +typedef FILE * png_FILE_p; +#endif +#endif + +#ifdef PNG_FLOATING_POINT_SUPPORTED +typedef double FAR * png_doublep; +#endif + +/* Pointers to pointers; i.e. arrays */ +typedef png_byte FAR * FAR * png_bytepp; +typedef png_uint_32 FAR * FAR * png_uint_32pp; +typedef png_int_32 FAR * FAR * png_int_32pp; +typedef png_uint_16 FAR * FAR * png_uint_16pp; +typedef png_int_16 FAR * FAR * png_int_16pp; +typedef PNG_CONST char FAR * FAR * png_const_charpp; +typedef char FAR * FAR * png_charpp; +typedef png_fixed_point FAR * FAR * png_fixed_point_pp; +#ifdef PNG_FLOATING_POINT_SUPPORTED +typedef double FAR * FAR * png_doublepp; +#endif + +/* Pointers to pointers to pointers; i.e., pointer to array */ +typedef char FAR * FAR * FAR * png_charppp; + +#if defined(PNG_1_0_X) || defined(PNG_1_2_X) +/* SPC - Is this stuff deprecated? */ +/* It'll be removed as of libpng-1.3.0 - GR-P */ +/* libpng typedefs for types in zlib. If zlib changes + * or another compression library is used, then change these. + * Eliminates need to change all the source files. + */ +typedef charf * png_zcharp; +typedef charf * FAR * png_zcharpp; +typedef z_stream FAR * png_zstreamp; +#endif /* (PNG_1_0_X) || defined(PNG_1_2_X) */ + +/* + * Define PNG_BUILD_DLL if the module being built is a Windows + * LIBPNG DLL. + * + * Define PNG_USE_DLL if you want to *link* to the Windows LIBPNG DLL. + * It is equivalent to Microsoft predefined macro _DLL that is + * automatically defined when you compile using the share + * version of the CRT (C Run-Time library) + * + * The cygwin mods make this behavior a little different: + * Define PNG_BUILD_DLL if you are building a dll for use with cygwin + * Define PNG_STATIC if you are building a static library for use with cygwin, + * -or- if you are building an application that you want to link to the + * static library. + * PNG_USE_DLL is defined by default (no user action needed) unless one of + * the other flags is defined. + */ + +#if !defined(PNG_DLL) && (defined(PNG_BUILD_DLL) || defined(PNG_USE_DLL)) +# define PNG_DLL +#endif +/* If CYGWIN, then disallow GLOBAL ARRAYS unless building a static lib. + * When building a static lib, default to no GLOBAL ARRAYS, but allow + * command-line override + */ +#if defined(__CYGWIN__) +# if !defined(PNG_STATIC) +# if defined(PNG_USE_GLOBAL_ARRAYS) +# undef PNG_USE_GLOBAL_ARRAYS +# endif +# if !defined(PNG_USE_LOCAL_ARRAYS) +# define PNG_USE_LOCAL_ARRAYS +# endif +# else +# if defined(PNG_USE_LOCAL_ARRAYS) || defined(PNG_NO_GLOBAL_ARRAYS) +# if defined(PNG_USE_GLOBAL_ARRAYS) +# undef PNG_USE_GLOBAL_ARRAYS +# endif +# endif +# endif +# if !defined(PNG_USE_LOCAL_ARRAYS) && !defined(PNG_USE_GLOBAL_ARRAYS) +# define PNG_USE_LOCAL_ARRAYS +# endif +#endif + +/* Do not use global arrays (helps with building DLL's) + * They are no longer used in libpng itself, since version 1.0.5c, + * but might be required for some pre-1.0.5c applications. + */ +#if !defined(PNG_USE_LOCAL_ARRAYS) && !defined(PNG_USE_GLOBAL_ARRAYS) +# if defined(PNG_NO_GLOBAL_ARRAYS) || (defined(__GNUC__) && defined(PNG_DLL)) +# define PNG_USE_LOCAL_ARRAYS +# else +# define PNG_USE_GLOBAL_ARRAYS +# endif +#endif + +#if defined(__CYGWIN__) +# undef PNGAPI +# define PNGAPI __cdecl +# undef PNG_IMPEXP +# define PNG_IMPEXP +#endif + +/* If you define PNGAPI, e.g., with compiler option "-DPNGAPI=__stdcall", + * you may get warnings regarding the linkage of png_zalloc and png_zfree. + * Don't ignore those warnings; you must also reset the default calling + * convention in your compiler to match your PNGAPI, and you must build + * zlib and your applications the same way you build libpng. + */ + +#if defined(__MINGW32__) && !defined(PNG_MODULEDEF) +# ifndef PNG_NO_MODULEDEF +# define PNG_NO_MODULEDEF +# endif +#endif + +#if !defined(PNG_IMPEXP) && defined(PNG_BUILD_DLL) && !defined(PNG_NO_MODULEDEF) +# define PNG_IMPEXP +#endif + +#if defined(PNG_DLL) || defined(_DLL) || defined(__DLL__ ) || \ + (( defined(_Windows) || defined(_WINDOWS) || \ + defined(WIN32) || defined(_WIN32) || defined(__WIN32__) )) + +# ifndef PNGAPI +# if defined(__GNUC__) || (defined (_MSC_VER) && (_MSC_VER >= 800)) +# define PNGAPI __cdecl +# else +# define PNGAPI _cdecl +# endif +# endif + +# if !defined(PNG_IMPEXP) && (!defined(PNG_DLL) || \ + 0 /* WINCOMPILER_WITH_NO_SUPPORT_FOR_DECLIMPEXP */) +# define PNG_IMPEXP +# endif + +# if !defined(PNG_IMPEXP) + +# define PNG_EXPORT_TYPE1(type,symbol) PNG_IMPEXP type PNGAPI symbol +# define PNG_EXPORT_TYPE2(type,symbol) type PNG_IMPEXP PNGAPI symbol + + /* Borland/Microsoft */ +# if defined(_MSC_VER) || defined(__BORLANDC__) +# if (_MSC_VER >= 800) || (__BORLANDC__ >= 0x500) +# define PNG_EXPORT PNG_EXPORT_TYPE1 +# else +# define PNG_EXPORT PNG_EXPORT_TYPE2 +# if defined(PNG_BUILD_DLL) +# define PNG_IMPEXP __export +# else +# define PNG_IMPEXP /*__import */ /* doesn't exist AFAIK in + VC++ */ +# endif /* Exists in Borland C++ for + C++ classes (== huge) */ +# endif +# endif + +# if !defined(PNG_IMPEXP) +# if defined(PNG_BUILD_DLL) +# define PNG_IMPEXP __declspec(dllexport) +# else +# define PNG_IMPEXP __declspec(dllimport) +# endif +# endif +# endif /* PNG_IMPEXP */ +#else /* !(DLL || non-cygwin WINDOWS) */ +# if (defined(__IBMC__) || defined(__IBMCPP__)) && defined(__OS2__) +# ifndef PNGAPI +# define PNGAPI _System +# endif +# else +# if 0 /* ... other platforms, with other meanings */ +# endif +# endif +#endif + +#ifndef PNGAPI +# define PNGAPI +#endif +#ifndef PNG_IMPEXP +# define PNG_IMPEXP +#endif + +#ifdef PNG_BUILDSYMS +# ifndef PNG_EXPORT +# define PNG_EXPORT(type,symbol) PNG_FUNCTION_EXPORT symbol END +# endif +# ifdef PNG_USE_GLOBAL_ARRAYS +# ifndef PNG_EXPORT_VAR +# define PNG_EXPORT_VAR(type) PNG_DATA_EXPORT +# endif +# endif +#endif + +#ifndef PNG_EXPORT +# define PNG_EXPORT(type,symbol) PNG_IMPEXP type PNGAPI symbol +#endif + +#ifdef PNG_USE_GLOBAL_ARRAYS +# ifndef PNG_EXPORT_VAR +# define PNG_EXPORT_VAR(type) extern PNG_IMPEXP type +# endif +#endif + +/* User may want to use these so they are not in PNG_INTERNAL. Any library + * functions that are passed far data must be model independent. + */ + +#ifndef PNG_ABORT +# define PNG_ABORT() bbExThrowCString( "PNG ERROR" ) +#endif + +#ifdef PNG_SETJMP_SUPPORTED +# define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf) +#else +# define png_jmpbuf(png_ptr) \ + (LIBPNG_WAS_COMPILED_WITH__PNG_SETJMP_NOT_SUPPORTED) +#endif + +#if defined(USE_FAR_KEYWORD) /* memory model independent fns */ +/* use this to make far-to-near assignments */ +# define CHECK 1 +# define NOCHECK 0 +# define CVT_PTR(ptr) (png_far_to_near(png_ptr,ptr,CHECK)) +# define CVT_PTR_NOCHECK(ptr) (png_far_to_near(png_ptr,ptr,NOCHECK)) +# define png_strcpy _fstrcpy +# define png_strncpy _fstrncpy /* Added to v 1.2.6 */ +# define png_strlen _fstrlen +# define png_memcmp _fmemcmp /* SJT: added */ +# define png_memcpy _fmemcpy +# define png_memset _fmemset +#else /* use the usual functions */ +# define CVT_PTR(ptr) (ptr) +# define CVT_PTR_NOCHECK(ptr) (ptr) +# define png_strcpy strcpy +# define png_strncpy strncpy /* Added to v 1.2.6 */ +# define png_strlen strlen +# define png_memcmp memcmp /* SJT: added */ +# define png_memcpy memcpy +# define png_memset memset +#endif +/* End of memory model independent support */ + +/* Just a little check that someone hasn't tried to define something + * contradictory. + */ +#if (PNG_ZBUF_SIZE > 65536L) && defined(PNG_MAX_MALLOC_64K) +# undef PNG_ZBUF_SIZE +# define PNG_ZBUF_SIZE 65536L +#endif + +#ifdef PNG_READ_SUPPORTED +/* Prior to libpng-1.0.9, this block was in pngasmrd.h */ +#if defined(PNG_INTERNAL) + +/* These are the default thresholds before the MMX code kicks in; if either + * rowbytes or bitdepth is below the threshold, plain C code is used. These + * can be overridden at runtime via the png_set_mmx_thresholds() call in + * libpng 1.2.0 and later. The values below were chosen by Intel. + */ + +#ifndef PNG_MMX_ROWBYTES_THRESHOLD_DEFAULT +# define PNG_MMX_ROWBYTES_THRESHOLD_DEFAULT 128 /* >= */ +#endif +#ifndef PNG_MMX_BITDEPTH_THRESHOLD_DEFAULT +# define PNG_MMX_BITDEPTH_THRESHOLD_DEFAULT 9 /* >= */ +#endif + +/* Set this in the makefile for VC++ on Pentium, not here. */ +/* Platform must be Pentium. Makefile must assemble and load pngvcrd.c . + * MMX will be detected at run time and used if present. + */ +#ifdef PNG_USE_PNGVCRD +# define PNG_HAVE_ASSEMBLER_COMBINE_ROW +# define PNG_HAVE_ASSEMBLER_READ_INTERLACE +# define PNG_HAVE_ASSEMBLER_READ_FILTER_ROW +#endif + +/* Set this in the makefile for gcc/as on Pentium, not here. */ +/* Platform must be Pentium. Makefile must assemble and load pnggccrd.c . + * MMX will be detected at run time and used if present. + */ +#ifdef PNG_USE_PNGGCCRD +# define PNG_HAVE_ASSEMBLER_COMBINE_ROW +# define PNG_HAVE_ASSEMBLER_READ_INTERLACE +# define PNG_HAVE_ASSEMBLER_READ_FILTER_ROW +#endif +/* - see pnggccrd.c for info about what is currently enabled */ + +#endif /* PNG_INTERNAL */ +#endif /* PNG_READ_SUPPORTED */ + +/* Added at libpng-1.2.8 */ +#endif /* PNG_VERSION_INFO_ONLY */ + +#endif /* PNGCONF_H */ diff --git a/mod/pub.mod/libpng.mod/pngerror.c b/mod/pub.mod/libpng.mod/pngerror.c new file mode 100644 index 0000000..ad6ae0e --- /dev/null +++ b/mod/pub.mod/libpng.mod/pngerror.c @@ -0,0 +1,313 @@ + +/* pngerror.c - stub functions for i/o and memory allocation + * + * Last changed in libpng 1.2.9 April 14, 2006 + * For conditions of distribution and use, see copyright notice in png.h + * Copyright (c) 1998-2006 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * + * This file provides a location for all error handling. Users who + * need special error handling are expected to write replacement functions + * and use png_set_error_fn() to use those functions. See the instructions + * at each function. + */ + +#define PNG_INTERNAL +#include "png.h" + +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) +static void /* PRIVATE */ +png_default_error PNGARG((png_structp png_ptr, + png_const_charp error_message)); +static void /* PRIVATE */ +png_default_warning PNGARG((png_structp png_ptr, + png_const_charp warning_message)); + +/* This function is called whenever there is a fatal error. This function + * should not be changed. If there is a need to handle errors differently, + * you should supply a replacement error function and use png_set_error_fn() + * to replace the error function at run-time. + */ +void PNGAPI +png_error(png_structp png_ptr, png_const_charp error_message) +{ +#ifdef PNG_ERROR_NUMBERS_SUPPORTED + char msg[16]; + if (png_ptr != NULL) + { + if (png_ptr->flags& + (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) + { + if (*error_message == '#') + { + int offset; + for (offset=1; offset<15; offset++) + if (*(error_message+offset) == ' ') + break; + if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT) + { + int i; + for (i=0; i<offset-1; i++) + msg[i]=error_message[i+1]; + msg[i]='\0'; + error_message=msg; + } + else + error_message+=offset; + } + else + { + if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT) + { + msg[0]='0'; + msg[1]='\0'; + error_message=msg; + } + } + } + } +#endif + if (png_ptr != NULL && png_ptr->error_fn != NULL) + (*(png_ptr->error_fn))(png_ptr, error_message); + + /* If the custom handler doesn't exist, or if it returns, + use the default handler, which will not return. */ + png_default_error(png_ptr, error_message); +} + +/* This function is called whenever there is a non-fatal error. This function + * should not be changed. If there is a need to handle warnings differently, + * you should supply a replacement warning function and use + * png_set_error_fn() to replace the warning function at run-time. + */ +void PNGAPI +png_warning(png_structp png_ptr, png_const_charp warning_message) +{ + int offset = 0; + if (png_ptr != NULL) + { +#ifdef PNG_ERROR_NUMBERS_SUPPORTED + if (png_ptr->flags& + (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) +#endif + { + if (*warning_message == '#') + { + for (offset=1; offset<15; offset++) + if (*(warning_message+offset) == ' ') + break; + } + } + if (png_ptr != NULL && png_ptr->warning_fn != NULL) + (*(png_ptr->warning_fn))(png_ptr, warning_message+offset); + } + else + png_default_warning(png_ptr, warning_message+offset); +} + +/* These utilities are used internally to build an error message that relates + * to the current chunk. The chunk name comes from png_ptr->chunk_name, + * this is used to prefix the message. The message is limited in length + * to 63 bytes, the name characters are output as hex digits wrapped in [] + * if the character is invalid. + */ +#define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97)) +static PNG_CONST char png_digit[16] = { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'A', 'B', 'C', 'D', 'E', 'F' +}; + +static void /* PRIVATE */ +png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp + error_message) +{ + int iout = 0, iin = 0; + + while (iin < 4) + { + int c = png_ptr->chunk_name[iin++]; + if (isnonalpha(c)) + { + buffer[iout++] = '['; + buffer[iout++] = png_digit[(c & 0xf0) >> 4]; + buffer[iout++] = png_digit[c & 0x0f]; + buffer[iout++] = ']'; + } + else + { + buffer[iout++] = (png_byte)c; + } + } + + if (error_message == NULL) + buffer[iout] = 0; + else + { + buffer[iout++] = ':'; + buffer[iout++] = ' '; + png_strncpy(buffer+iout, error_message, 63); + buffer[iout+63] = 0; + } +} + +void PNGAPI +png_chunk_error(png_structp png_ptr, png_const_charp error_message) +{ + char msg[18+64]; + if (png_ptr == NULL) + png_error(png_ptr, error_message); + png_format_buffer(png_ptr, msg, error_message); + png_error(png_ptr, msg); +} + +void PNGAPI +png_chunk_warning(png_structp png_ptr, png_const_charp warning_message) +{ + char msg[18+64]; + if (png_ptr == NULL) + png_warning(png_ptr, warning_message); + png_format_buffer(png_ptr, msg, warning_message); + png_warning(png_ptr, msg); +} + +/* This is the default error handling function. Note that replacements for + * this function MUST NOT RETURN, or the program will likely crash. This + * function is used by default, or if the program supplies NULL for the + * error function pointer in png_set_error_fn(). + */ +static void /* PRIVATE */ +png_default_error(png_structp png_ptr, png_const_charp error_message) +{ +#ifndef PNG_NO_CONSOLE_IO +#ifdef PNG_ERROR_NUMBERS_SUPPORTED + if (*error_message == '#') + { + int offset; + char error_number[16]; + for (offset=0; offset<15; offset++) + { + error_number[offset] = *(error_message+offset+1); + if (*(error_message+offset) == ' ') + break; + } + if((offset > 1) && (offset < 15)) + { + error_number[offset-1]='\0'; + fprintf(stderr, "libpng error no. %s: %s\n", error_number, + error_message+offset); + } + else + fprintf(stderr, "libpng error: %s, offset=%d\n", error_message,offset); + } + else +#endif + fprintf(stderr, "libpng error: %s\n", error_message); +#endif + +#ifdef PNG_SETJMP_SUPPORTED +# ifdef USE_FAR_KEYWORD + { + jmp_buf jmpbuf; + png_memcpy(jmpbuf,png_ptr->jmpbuf,png_sizeof(jmp_buf)); + longjmp(jmpbuf, 1); + } +# else + longjmp(png_ptr->jmpbuf, 1); +# endif +#else + /* make compiler happy */ ; + if (png_ptr) + PNG_ABORT(); +#endif +#ifdef PNG_NO_CONSOLE_IO + /* make compiler happy */ ; + if (&error_message != NULL) + return; +#endif +} + +/* This function is called when there is a warning, but the library thinks + * it can continue anyway. Replacement functions don't have to do anything + * here if you don't want them to. In the default configuration, png_ptr is + * not used, but it is passed in case it may be useful. + */ +static void /* PRIVATE */ +png_default_warning(png_structp png_ptr, png_const_charp warning_message) +{ +#ifndef PNG_NO_CONSOLE_IO +# ifdef PNG_ERROR_NUMBERS_SUPPORTED + if (*warning_message == '#') + { + int offset; + char warning_number[16]; + for (offset=0; offset<15; offset++) + { + warning_number[offset]=*(warning_message+offset+1); + if (*(warning_message+offset) == ' ') + break; + } + if((offset > 1) && (offset < 15)) + { + warning_number[offset-1]='\0'; + fprintf(stderr, "libpng warning no. %s: %s\n", warning_number, + warning_message+offset); + } + else + fprintf(stderr, "libpng warning: %s\n", warning_message); + } + else +# endif + fprintf(stderr, "libpng warning: %s\n", warning_message); +#else + /* make compiler happy */ ; + if (warning_message) + return; +#endif + /* make compiler happy */ ; + if (png_ptr) + return; +} + +/* This function is called when the application wants to use another method + * of handling errors and warnings. Note that the error function MUST NOT + * return to the calling routine or serious problems will occur. The return + * method used in the default routine calls longjmp(png_ptr->jmpbuf, 1) + */ +void PNGAPI +png_set_error_fn(png_structp png_ptr, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warning_fn) +{ + if (png_ptr == NULL) + return; + png_ptr->error_ptr = error_ptr; + png_ptr->error_fn = error_fn; + png_ptr->warning_fn = warning_fn; +} + + +/* This function returns a pointer to the error_ptr associated with the user + * functions. The application should free any memory associated with this + * pointer before png_write_destroy and png_read_destroy are called. + */ +png_voidp PNGAPI +png_get_error_ptr(png_structp png_ptr) +{ + if (png_ptr == NULL) + return NULL; + return ((png_voidp)png_ptr->error_ptr); +} + + +#ifdef PNG_ERROR_NUMBERS_SUPPORTED +void PNGAPI +png_set_strip_error_numbers(png_structp png_ptr, png_uint_32 strip_mode) +{ + if(png_ptr != NULL) + { + png_ptr->flags &= + ((~(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))&strip_mode); + } +} +#endif +#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */ diff --git a/mod/pub.mod/libpng.mod/pnggccrd.c b/mod/pub.mod/libpng.mod/pnggccrd.c new file mode 100644 index 0000000..8dc9c53 --- /dev/null +++ b/mod/pub.mod/libpng.mod/pnggccrd.c @@ -0,0 +1,5420 @@ + +/* pnggccrd.c - mixed C/assembler version of utilities to read a PNG file + * + * For Intel x86 CPU (Pentium-MMX or later) and GNU C compiler. + * + * See http://www.intel.com/drg/pentiumII/appnotes/916/916.htm + * and http://www.intel.com/drg/pentiumII/appnotes/923/923.htm + * for Intel's performance analysis of the MMX vs. non-MMX code. + * + * Last changed in libpng 1.2.9 April 14, 2006 + * For conditions of distribution and use, see copyright notice in png.h + * Copyright (c) 1998-2006 Glenn Randers-Pehrson + * Copyright (c) 1998, Intel Corporation + * + * Based on MSVC code contributed by Nirav Chhatrapati, Intel Corp., 1998. + * Interface to libpng contributed by Gilles Vollant, 1999. + * GNU C port by Greg Roelofs, 1999-2001. + * + * Lines 2350-4300 converted in place with intel2gas 1.3.1: + * + * intel2gas -mdI pnggccrd.c.partially-msvc -o pnggccrd.c + * + * and then cleaned up by hand. See http://hermes.terminal.at/intel2gas/ . + * + * NOTE: A sufficiently recent version of GNU as (or as.exe under DOS/Windows) + * is required to assemble the newer MMX instructions such as movq. + * For djgpp, see + * + * ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2gnu/bnu281b.zip + * + * (or a later version in the same directory). For Linux, check your + * distribution's web site(s) or try these links: + * + * http://rufus.w3.org/linux/RPM/binutils.html + * http://www.debian.org/Packages/stable/devel/binutils.html + * ftp://ftp.slackware.com/pub/linux/slackware/slackware/slakware/d1/ + * binutils.tgz + * + * For other platforms, see the main GNU site: + * + * ftp://ftp.gnu.org/pub/gnu/binutils/ + * + * Version 2.5.2l.15 is definitely too old... + */ + +/* + * TEMPORARY PORTING NOTES AND CHANGELOG (mostly by Greg Roelofs) + * ===================================== + * + * 19991006: + * - fixed sign error in post-MMX cleanup code (16- & 32-bit cases) + * + * 19991007: + * - additional optimizations (possible or definite): + * x [DONE] write MMX code for 64-bit case (pixel_bytes == 8) [not tested] + * - write MMX code for 48-bit case (pixel_bytes == 6) + * - figure out what's up with 24-bit case (pixel_bytes == 3): + * why subtract 8 from width_mmx in the pass 4/5 case? + * (only width_mmx case) (near line 1606) + * x [DONE] replace pixel_bytes within each block with the true + * constant value (or are compilers smart enough to do that?) + * - rewrite all MMX interlacing code so it's aligned with + * the *beginning* of the row buffer, not the end. This + * would not only allow one to eliminate half of the memory + * writes for odd passes (that is, pass == odd), it may also + * eliminate some unaligned-data-access exceptions (assuming + * there's a penalty for not aligning 64-bit accesses on + * 64-bit boundaries). The only catch is that the "leftover" + * pixel(s) at the end of the row would have to be saved, + * but there are enough unused MMX registers in every case, + * so this is not a problem. A further benefit is that the + * post-MMX cleanup code (C code) in at least some of the + * cases could be done within the assembler block. + * x [DONE] the "v3 v2 v1 v0 v7 v6 v5 v4" comments are confusing, + * inconsistent, and don't match the MMX Programmer's Reference + * Manual conventions anyway. They should be changed to + * "b7 b6 b5 b4 b3 b2 b1 b0," where b0 indicates the byte that + * was lowest in memory (e.g., corresponding to a left pixel) + * and b7 is the byte that was highest (e.g., a right pixel). + * + * 19991016: + * - Brennan's Guide notwithstanding, gcc under Linux does *not* + * want globals prefixed by underscores when referencing them-- + * i.e., if the variable is const4, then refer to it as const4, + * not _const4. This seems to be a djgpp-specific requirement. + * Also, such variables apparently *must* be declared outside + * of functions; neither static nor automatic variables work if + * defined within the scope of a single function, but both + * static and truly global (multi-module) variables work fine. + * + * 19991023: + * - fixed png_combine_row() non-MMX replication bug (odd passes only?) + * - switched from string-concatenation-with-macros to cleaner method of + * renaming global variables for djgpp--i.e., always use prefixes in + * inlined assembler code (== strings) and conditionally rename the + * variables, not the other way around. Hence _const4, _mask8_0, etc. + * + * 19991024: + * - fixed mmxsupport()/png_do_read_interlace() first-row bug + * This one was severely weird: even though mmxsupport() doesn't touch + * ebx (where "row" pointer was stored), it nevertheless managed to zero + * the register (even in static/non-fPIC code--see below), which in turn + * caused png_do_read_interlace() to return prematurely on the first row of + * interlaced images (i.e., without expanding the interlaced pixels). + * Inspection of the generated assembly code didn't turn up any clues, + * although it did point at a minor optimization (i.e., get rid of + * mmx_supported_local variable and just use eax). Possibly the CPUID + * instruction is more destructive than it looks? (Not yet checked.) + * - "info gcc" was next to useless, so compared fPIC and non-fPIC assembly + * listings... Apparently register spillage has to do with ebx, since + * it's used to index the global offset table. Commenting it out of the + * input-reg lists in png_combine_row() eliminated compiler barfage, so + * ifdef'd with __PIC__ macro: if defined, use a global for unmask + * + * 19991107: + * - verified CPUID clobberage: 12-char string constant ("GenuineIntel", + * "AuthenticAMD", etc.) placed in ebx:ecx:edx. Still need to polish. + * + * 19991120: + * - made "diff" variable (now "_dif") global to simplify conversion of + * filtering routines (running out of regs, sigh). "diff" is still used + * in interlacing routines, however. + * - fixed up both versions of mmxsupport() (ORIG_THAT_USED_TO_CLOBBER_EBX + * macro determines which is used); original not yet tested. + * + * 20000213: + * - when compiling with gcc, be sure to use -fomit-frame-pointer + * + * 20000319: + * - fixed a register-name typo in png_do_read_interlace(), default (MMX) case, + * pass == 4 or 5, that caused visible corruption of interlaced images + * + * 20000623: + * - Various problems were reported with gcc 2.95.2 in the Cygwin environment, + * many of the form "forbidden register 0 (ax) was spilled for class AREG." + * This is explained at http://gcc.gnu.org/fom_serv/cache/23.html, and + * Chuck Wilson supplied a patch involving dummy output registers. See + * http://sourceforge.net/bugs/?func=detailbug&bug_id=108741&group_id=5624 + * for the original (anonymous) SourceForge bug report. + * + * 20000706: + * - Chuck Wilson passed along these remaining gcc 2.95.2 errors: + * pnggccrd.c: In function `png_combine_row': + * pnggccrd.c:525: more than 10 operands in `asm' + * pnggccrd.c:669: more than 10 operands in `asm' + * pnggccrd.c:828: more than 10 operands in `asm' + * pnggccrd.c:994: more than 10 operands in `asm' + * pnggccrd.c:1177: more than 10 operands in `asm' + * They are all the same problem and can be worked around by using the + * global _unmask variable unconditionally, not just in the -fPIC case. + * Reportedly earlier versions of gcc also have the problem with more than + * 10 operands; they just don't report it. Much strangeness ensues, etc. + * + * 20000729: + * - enabled png_read_filter_row_mmx_up() (shortest remaining unconverted + * MMX routine); began converting png_read_filter_row_mmx_sub() + * - to finish remaining sections: + * - clean up indentation and comments + * - preload local variables + * - add output and input regs (order of former determines numerical + * mapping of latter) + * - avoid all usage of ebx (including bx, bh, bl) register [20000823] + * - remove "$" from addressing of Shift and Mask variables [20000823] + * + * 20000731: + * - global union vars causing segfaults in png_read_filter_row_mmx_sub()? + * + * 20000822: + * - ARGH, stupid png_read_filter_row_mmx_sub() segfault only happens with + * shared-library (-fPIC) version! Code works just fine as part of static + * library. Damn damn damn damn damn, should have tested that sooner. + * ebx is getting clobbered again (explicitly this time); need to save it + * on stack or rewrite asm code to avoid using it altogether. Blargh! + * + * 20000823: + * - first section was trickiest; all remaining sections have ebx -> edx now. + * (-fPIC works again.) Also added missing underscores to various Shift* + * and *Mask* globals and got rid of leading "$" signs. + * + * 20000826: + * - added visual separators to help navigate microscopic printed copies + * (http://pobox.com/~newt/code/gpr-latest.zip, mode 10); started working + * on png_read_filter_row_mmx_avg() + * + * 20000828: + * - finished png_read_filter_row_mmx_avg(): only Paeth left! (930 lines...) + * What the hell, did png_read_filter_row_mmx_paeth(), too. Comments not + * cleaned up/shortened in either routine, but functionality is complete + * and seems to be working fine. + * + * 20000829: + * - ahhh, figured out last(?) bit of gcc/gas asm-fu: if register is listed + * as an input reg (with dummy output variables, etc.), then it *cannot* + * also appear in the clobber list or gcc 2.95.2 will barf. The solution + * is simple enough... + * + * 20000914: + * - bug in png_read_filter_row_mmx_avg(): 16-bit grayscale not handled + * correctly (but 48-bit RGB just fine) + * + * 20000916: + * - fixed bug in png_read_filter_row_mmx_avg(), bpp == 2 case; three errors: + * - "_ShiftBpp.use = 24;" should have been "_ShiftBpp.use = 16;" + * - "_ShiftRem.use = 40;" should have been "_ShiftRem.use = 48;" + * - "psllq _ShiftRem, %%mm2" should have been "psrlq _ShiftRem, %%mm2" + * + * 20010101: + * - added new png_init_mmx_flags() function (here only because it needs to + * call mmxsupport(), which should probably become global png_mmxsupport()); + * modified other MMX routines to run conditionally (png_ptr->asm_flags) + * + * 20010103: + * - renamed mmxsupport() to png_mmx_support(), with auto-set of mmx_supported, + * and made it public; moved png_init_mmx_flags() to png.c as internal func + * + * 20010104: + * - removed dependency on png_read_filter_row_c() (C code already duplicated + * within MMX version of png_read_filter_row()) so no longer necessary to + * compile it into pngrutil.o + * + * 20010310: + * - fixed buffer-overrun bug in png_combine_row() C code (non-MMX) + * + * 20020304: + * - eliminated incorrect use of width_mmx in pixel_bytes == 8 case + * + * 20040724: + * - more tinkering with clobber list at lines 4529 and 5033, to get + * it to compile on gcc-3.4. + * + * STILL TO DO: + * - test png_do_read_interlace() 64-bit case (pixel_bytes == 8) + * - write MMX code for 48-bit case (pixel_bytes == 6) + * - figure out what's up with 24-bit case (pixel_bytes == 3): + * why subtract 8 from width_mmx in the pass 4/5 case? + * (only width_mmx case) (near line 1606) + * - rewrite all MMX interlacing code so it's aligned with beginning + * of the row buffer, not the end (see 19991007 for details) + * x pick one version of mmxsupport() and get rid of the other + * - add error messages to any remaining bogus default cases + * - enable pixel_depth == 8 cases in png_read_filter_row()? (test speed) + * x add support for runtime enable/disable/query of various MMX routines + */ + +#define PNG_INTERNAL +#include "png.h" + +#if defined(PNG_USE_PNGGCCRD) + +int PNGAPI png_mmx_support(void); + +#ifdef PNG_USE_LOCAL_ARRAYS +static const int FARDATA png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; +static const int FARDATA png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; +static const int FARDATA png_pass_width[7] = {8, 4, 4, 2, 2, 1, 1}; +#endif + +#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) +/* djgpp, Win32, Cygwin, and OS2 add their own underscores to global variables, + * so define them without: */ +#if defined(__DJGPP__) || defined(WIN32) || defined(__CYGWIN__) || \ + defined(__OS2__) +# define _mmx_supported mmx_supported +# define _const4 const4 +# define _const6 const6 +# define _mask8_0 mask8_0 +# define _mask16_1 mask16_1 +# define _mask16_0 mask16_0 +# define _mask24_2 mask24_2 +# define _mask24_1 mask24_1 +# define _mask24_0 mask24_0 +# define _mask32_3 mask32_3 +# define _mask32_2 mask32_2 +# define _mask32_1 mask32_1 +# define _mask32_0 mask32_0 +# define _mask48_5 mask48_5 +# define _mask48_4 mask48_4 +# define _mask48_3 mask48_3 +# define _mask48_2 mask48_2 +# define _mask48_1 mask48_1 +# define _mask48_0 mask48_0 +# define _LBCarryMask LBCarryMask +# define _HBClearMask HBClearMask +# define _ActiveMask ActiveMask +# define _ActiveMask2 ActiveMask2 +# define _ActiveMaskEnd ActiveMaskEnd +# define _ShiftBpp ShiftBpp +# define _ShiftRem ShiftRem +#ifdef PNG_THREAD_UNSAFE_OK +# define _unmask unmask +# define _FullLength FullLength +# define _MMXLength MMXLength +# define _dif dif +# define _patemp patemp +# define _pbtemp pbtemp +# define _pctemp pctemp +#endif +#endif + + +/* These constants are used in the inlined MMX assembly code. + Ignore gcc's "At top level: defined but not used" warnings. */ + +/* GRR 20000706: originally _unmask was needed only when compiling with -fPIC, + * since that case uses the %ebx register for indexing the Global Offset Table + * and there were no other registers available. But gcc 2.95 and later emit + * "more than 10 operands in `asm'" errors when %ebx is used to preload unmask + * in the non-PIC case, so we'll just use the global unconditionally now. + */ +#ifdef PNG_THREAD_UNSAFE_OK +static int _unmask; +#endif + +static unsigned long long _mask8_0 = 0x0102040810204080LL; + +static unsigned long long _mask16_1 = 0x0101020204040808LL; +static unsigned long long _mask16_0 = 0x1010202040408080LL; + +static unsigned long long _mask24_2 = 0x0101010202020404LL; +static unsigned long long _mask24_1 = 0x0408080810101020LL; +static unsigned long long _mask24_0 = 0x2020404040808080LL; + +static unsigned long long _mask32_3 = 0x0101010102020202LL; +static unsigned long long _mask32_2 = 0x0404040408080808LL; +static unsigned long long _mask32_1 = 0x1010101020202020LL; +static unsigned long long _mask32_0 = 0x4040404080808080LL; + +static unsigned long long _mask48_5 = 0x0101010101010202LL; +static unsigned long long _mask48_4 = 0x0202020204040404LL; +static unsigned long long _mask48_3 = 0x0404080808080808LL; +static unsigned long long _mask48_2 = 0x1010101010102020LL; +static unsigned long long _mask48_1 = 0x2020202040404040LL; +static unsigned long long _mask48_0 = 0x4040808080808080LL; + +static unsigned long long _const4 = 0x0000000000FFFFFFLL; +//static unsigned long long _const5 = 0x000000FFFFFF0000LL; // NOT USED +static unsigned long long _const6 = 0x00000000000000FFLL; + +// These are used in the row-filter routines and should/would be local +// variables if not for gcc addressing limitations. +// WARNING: Their presence probably defeats the thread safety of libpng. + +#ifdef PNG_THREAD_UNSAFE_OK +static png_uint_32 _FullLength; +static png_uint_32 _MMXLength; +static int _dif; +static int _patemp; // temp variables for Paeth routine +static int _pbtemp; +static int _pctemp; +#endif + +void /* PRIVATE */ +png_squelch_warnings(void) +{ +#ifdef PNG_THREAD_UNSAFE_OK + _dif = _dif; + _patemp = _patemp; + _pbtemp = _pbtemp; + _pctemp = _pctemp; + _MMXLength = _MMXLength; +#endif + _const4 = _const4; + _const6 = _const6; + _mask8_0 = _mask8_0; + _mask16_1 = _mask16_1; + _mask16_0 = _mask16_0; + _mask24_2 = _mask24_2; + _mask24_1 = _mask24_1; + _mask24_0 = _mask24_0; + _mask32_3 = _mask32_3; + _mask32_2 = _mask32_2; + _mask32_1 = _mask32_1; + _mask32_0 = _mask32_0; + _mask48_5 = _mask48_5; + _mask48_4 = _mask48_4; + _mask48_3 = _mask48_3; + _mask48_2 = _mask48_2; + _mask48_1 = _mask48_1; + _mask48_0 = _mask48_0; +} +#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ + + +static int _mmx_supported = 2; + +/*===========================================================================*/ +/* */ +/* P N G _ C O M B I N E _ R O W */ +/* */ +/*===========================================================================*/ + +#if defined(PNG_HAVE_ASSEMBLER_COMBINE_ROW) + +#define BPP2 2 +#define BPP3 3 /* bytes per pixel (a.k.a. pixel_bytes) */ +#define BPP4 4 +#define BPP6 6 /* (defined only to help avoid cut-and-paste errors) */ +#define BPP8 8 + +/* Combines the row recently read in with the previous row. + This routine takes care of alpha and transparency if requested. + This routine also handles the two methods of progressive display + of interlaced images, depending on the mask value. + The mask value describes which pixels are to be combined with + the row. The pattern always repeats every 8 pixels, so just 8 + bits are needed. A one indicates the pixel is to be combined; a + zero indicates the pixel is to be skipped. This is in addition + to any alpha or transparency value associated with the pixel. + If you want all pixels to be combined, pass 0xff (255) in mask. */ + +/* Use this routine for the x86 platform - it uses a faster MMX routine + if the machine supports MMX. */ + +void /* PRIVATE */ +png_combine_row(png_structp png_ptr, png_bytep row, int mask) +{ + png_debug(1, "in png_combine_row (pnggccrd.c)\n"); + +#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) + if (_mmx_supported == 2) { +#if !defined(PNG_1_0_X) + /* this should have happened in png_init_mmx_flags() already */ + png_warning(png_ptr, "asm_flags may not have been initialized"); +#endif + png_mmx_support(); + } +#endif + + if (mask == 0xff) + { + png_debug(2,"mask == 0xff: doing single png_memcpy()\n"); + png_memcpy(row, png_ptr->row_buf + 1, + (png_size_t)PNG_ROWBYTES(png_ptr->row_info.pixel_depth,png_ptr->width)); + } + else /* (png_combine_row() is never called with mask == 0) */ + { + switch (png_ptr->row_info.pixel_depth) + { + case 1: /* png_ptr->row_info.pixel_depth */ + { + png_bytep sp; + png_bytep dp; + int s_inc, s_start, s_end; + int m; + int shift; + png_uint_32 i; + + sp = png_ptr->row_buf + 1; + dp = row; + m = 0x80; +#if defined(PNG_READ_PACKSWAP_SUPPORTED) + if (png_ptr->transformations & PNG_PACKSWAP) + { + s_start = 0; + s_end = 7; + s_inc = 1; + } + else +#endif + { + s_start = 7; + s_end = 0; + s_inc = -1; + } + + shift = s_start; + + for (i = 0; i < png_ptr->width; i++) + { + if (m & mask) + { + int value; + + value = (*sp >> shift) & 0x1; + *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff); + *dp |= (png_byte)(value << shift); + } + + if (shift == s_end) + { + shift = s_start; + sp++; + dp++; + } + else + shift += s_inc; + + if (m == 1) + m = 0x80; + else + m >>= 1; + } + break; + } + + case 2: /* png_ptr->row_info.pixel_depth */ + { + png_bytep sp; + png_bytep dp; + int s_start, s_end, s_inc; + int m; + int shift; + png_uint_32 i; + int value; + + sp = png_ptr->row_buf + 1; + dp = row; + m = 0x80; +#if defined(PNG_READ_PACKSWAP_SUPPORTED) + if (png_ptr->transformations & PNG_PACKSWAP) + { + s_start = 0; + s_end = 6; + s_inc = 2; + } + else +#endif + { + s_start = 6; + s_end = 0; + s_inc = -2; + } + + shift = s_start; + + for (i = 0; i < png_ptr->width; i++) + { + if (m & mask) + { + value = (*sp >> shift) & 0x3; + *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); + *dp |= (png_byte)(value << shift); + } + + if (shift == s_end) + { + shift = s_start; + sp++; + dp++; + } + else + shift += s_inc; + if (m == 1) + m = 0x80; + else + m >>= 1; + } + break; + } + + case 4: /* png_ptr->row_info.pixel_depth */ + { + png_bytep sp; + png_bytep dp; + int s_start, s_end, s_inc; + int m; + int shift; + png_uint_32 i; + int value; + + sp = png_ptr->row_buf + 1; + dp = row; + m = 0x80; +#if defined(PNG_READ_PACKSWAP_SUPPORTED) + if (png_ptr->transformations & PNG_PACKSWAP) + { + s_start = 0; + s_end = 4; + s_inc = 4; + } + else +#endif + { + s_start = 4; + s_end = 0; + s_inc = -4; + } + shift = s_start; + + for (i = 0; i < png_ptr->width; i++) + { + if (m & mask) + { + value = (*sp >> shift) & 0xf; + *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); + *dp |= (png_byte)(value << shift); + } + + if (shift == s_end) + { + shift = s_start; + sp++; + dp++; + } + else + shift += s_inc; + if (m == 1) + m = 0x80; + else + m >>= 1; + } + break; + } + + case 8: /* png_ptr->row_info.pixel_depth */ + { + png_bytep srcptr; + png_bytep dstptr; + +#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) +#if !defined(PNG_1_0_X) + if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) + /* && _mmx_supported */ ) +#else + if (_mmx_supported) +#endif + { + png_uint_32 len; + int diff; + int dummy_value_a; // fix 'forbidden register spilled' error + int dummy_value_d; + int dummy_value_c; + int dummy_value_S; + int dummy_value_D; + _unmask = ~mask; // global variable for -fPIC version + srcptr = png_ptr->row_buf + 1; + dstptr = row; + len = png_ptr->width &~7; // reduce to multiple of 8 + diff = (int) (png_ptr->width & 7); // amount lost + + __asm__ __volatile__ ( + "movd _unmask, %%mm7 \n\t" // load bit pattern + "psubb %%mm6, %%mm6 \n\t" // zero mm6 + "punpcklbw %%mm7, %%mm7 \n\t" + "punpcklwd %%mm7, %%mm7 \n\t" + "punpckldq %%mm7, %%mm7 \n\t" // fill reg with 8 masks + + "movq _mask8_0, %%mm0 \n\t" + "pand %%mm7, %%mm0 \n\t" // nonzero if keep byte + "pcmpeqb %%mm6, %%mm0 \n\t" // zeros->1s, v versa + +// preload "movl len, %%ecx \n\t" // load length of line +// preload "movl srcptr, %%esi \n\t" // load source +// preload "movl dstptr, %%edi \n\t" // load dest + + "cmpl $0, %%ecx \n\t" // len == 0 ? + "je mainloop8end \n\t" + + "mainloop8: \n\t" + "movq (%%esi), %%mm4 \n\t" // *srcptr + "pand %%mm0, %%mm4 \n\t" + "movq %%mm0, %%mm6 \n\t" + "pandn (%%edi), %%mm6 \n\t" // *dstptr + "por %%mm6, %%mm4 \n\t" + "movq %%mm4, (%%edi) \n\t" + "addl $8, %%esi \n\t" // inc by 8 bytes processed + "addl $8, %%edi \n\t" + "subl $8, %%ecx \n\t" // dec by 8 pixels processed + "ja mainloop8 \n\t" + + "mainloop8end: \n\t" +// preload "movl diff, %%ecx \n\t" // (diff is in eax) + "movl %%eax, %%ecx \n\t" + "cmpl $0, %%ecx \n\t" + "jz end8 \n\t" +// preload "movl mask, %%edx \n\t" + "sall $24, %%edx \n\t" // make low byte, high byte + + "secondloop8: \n\t" + "sall %%edx \n\t" // move high bit to CF + "jnc skip8 \n\t" // if CF = 0 + "movb (%%esi), %%al \n\t" + "movb %%al, (%%edi) \n\t" + + "skip8: \n\t" + "incl %%esi \n\t" + "incl %%edi \n\t" + "decl %%ecx \n\t" + "jnz secondloop8 \n\t" + + "end8: \n\t" + "EMMS \n\t" // DONE + + : "=a" (dummy_value_a), // output regs (dummy) + "=d" (dummy_value_d), + "=c" (dummy_value_c), + "=S" (dummy_value_S), + "=D" (dummy_value_D) + + : "3" (srcptr), // esi // input regs + "4" (dstptr), // edi + "0" (diff), // eax +// was (unmask) "b" RESERVED // ebx // Global Offset Table idx + "2" (len), // ecx + "1" (mask) // edx + +#if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */ + : "%mm0", "%mm4", "%mm6", "%mm7" // clobber list +#endif + ); + } + else /* mmx _not supported - Use modified C routine */ +#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ + { + register png_uint_32 i; + png_uint_32 initial_val = png_pass_start[png_ptr->pass]; + /* png.c: png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; */ + register int stride = png_pass_inc[png_ptr->pass]; + /* png.c: png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; */ + register int rep_bytes = png_pass_width[png_ptr->pass]; + /* png.c: png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; */ + png_uint_32 len = png_ptr->width &~7; /* reduce to mult. of 8 */ + int diff = (int) (png_ptr->width & 7); /* amount lost */ + register png_uint_32 final_val = len; /* GRR bugfix */ + + srcptr = png_ptr->row_buf + 1 + initial_val; + dstptr = row + initial_val; + + for (i = initial_val; i < final_val; i += stride) + { + png_memcpy(dstptr, srcptr, rep_bytes); + srcptr += stride; + dstptr += stride; + } + if (diff) /* number of leftover pixels: 3 for pngtest */ + { + final_val+=diff /* *BPP1 */ ; + for (; i < final_val; i += stride) + { + if (rep_bytes > (int)(final_val-i)) + rep_bytes = (int)(final_val-i); + png_memcpy(dstptr, srcptr, rep_bytes); + srcptr += stride; + dstptr += stride; + } + } + + } /* end of else (_mmx_supported) */ + + break; + } /* end 8 bpp */ + + case 16: /* png_ptr->row_info.pixel_depth */ + { + png_bytep srcptr; + png_bytep dstptr; + +#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) +#if !defined(PNG_1_0_X) + if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) + /* && _mmx_supported */ ) +#else + if (_mmx_supported) +#endif + { + png_uint_32 len; + int diff; + int dummy_value_a; // fix 'forbidden register spilled' error + int dummy_value_d; + int dummy_value_c; + int dummy_value_S; + int dummy_value_D; + _unmask = ~mask; // global variable for -fPIC version + srcptr = png_ptr->row_buf + 1; + dstptr = row; + len = png_ptr->width &~7; // reduce to multiple of 8 + diff = (int) (png_ptr->width & 7); // amount lost // + + __asm__ __volatile__ ( + "movd _unmask, %%mm7 \n\t" // load bit pattern + "psubb %%mm6, %%mm6 \n\t" // zero mm6 + "punpcklbw %%mm7, %%mm7 \n\t" + "punpcklwd %%mm7, %%mm7 \n\t" + "punpckldq %%mm7, %%mm7 \n\t" // fill reg with 8 masks + + "movq _mask16_0, %%mm0 \n\t" + "movq _mask16_1, %%mm1 \n\t" + + "pand %%mm7, %%mm0 \n\t" + "pand %%mm7, %%mm1 \n\t" + + "pcmpeqb %%mm6, %%mm0 \n\t" + "pcmpeqb %%mm6, %%mm1 \n\t" + +// preload "movl len, %%ecx \n\t" // load length of line +// preload "movl srcptr, %%esi \n\t" // load source +// preload "movl dstptr, %%edi \n\t" // load dest + + "cmpl $0, %%ecx \n\t" + "jz mainloop16end \n\t" + + "mainloop16: \n\t" + "movq (%%esi), %%mm4 \n\t" + "pand %%mm0, %%mm4 \n\t" + "movq %%mm0, %%mm6 \n\t" + "movq (%%edi), %%mm7 \n\t" + "pandn %%mm7, %%mm6 \n\t" + "por %%mm6, %%mm4 \n\t" + "movq %%mm4, (%%edi) \n\t" + + "movq 8(%%esi), %%mm5 \n\t" + "pand %%mm1, %%mm5 \n\t" + "movq %%mm1, %%mm7 \n\t" + "movq 8(%%edi), %%mm6 \n\t" + "pandn %%mm6, %%mm7 \n\t" + "por %%mm7, %%mm5 \n\t" + "movq %%mm5, 8(%%edi) \n\t" + + "addl $16, %%esi \n\t" // inc by 16 bytes processed + "addl $16, %%edi \n\t" + "subl $8, %%ecx \n\t" // dec by 8 pixels processed + "ja mainloop16 \n\t" + + "mainloop16end: \n\t" +// preload "movl diff, %%ecx \n\t" // (diff is in eax) + "movl %%eax, %%ecx \n\t" + "cmpl $0, %%ecx \n\t" + "jz end16 \n\t" +// preload "movl mask, %%edx \n\t" + "sall $24, %%edx \n\t" // make low byte, high byte + + "secondloop16: \n\t" + "sall %%edx \n\t" // move high bit to CF + "jnc skip16 \n\t" // if CF = 0 + "movw (%%esi), %%ax \n\t" + "movw %%ax, (%%edi) \n\t" + + "skip16: \n\t" + "addl $2, %%esi \n\t" + "addl $2, %%edi \n\t" + "decl %%ecx \n\t" + "jnz secondloop16 \n\t" + + "end16: \n\t" + "EMMS \n\t" // DONE + + : "=a" (dummy_value_a), // output regs (dummy) + "=c" (dummy_value_c), + "=d" (dummy_value_d), + "=S" (dummy_value_S), + "=D" (dummy_value_D) + + : "0" (diff), // eax // input regs +// was (unmask) " " RESERVED // ebx // Global Offset Table idx + "1" (len), // ecx + "2" (mask), // edx + "3" (srcptr), // esi + "4" (dstptr) // edi + +#if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */ + : "%mm0", "%mm1", "%mm4" // clobber list + , "%mm5", "%mm6", "%mm7" +#endif + ); + } + else /* mmx _not supported - Use modified C routine */ +#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ + { + register png_uint_32 i; + png_uint_32 initial_val = BPP2 * png_pass_start[png_ptr->pass]; + /* png.c: png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; */ + register int stride = BPP2 * png_pass_inc[png_ptr->pass]; + /* png.c: png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; */ + register int rep_bytes = BPP2 * png_pass_width[png_ptr->pass]; + /* png.c: png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; */ + png_uint_32 len = png_ptr->width &~7; /* reduce to mult. of 8 */ + int diff = (int) (png_ptr->width & 7); /* amount lost */ + register png_uint_32 final_val = BPP2 * len; /* GRR bugfix */ + + srcptr = png_ptr->row_buf + 1 + initial_val; + dstptr = row + initial_val; + + for (i = initial_val; i < final_val; i += stride) + { + png_memcpy(dstptr, srcptr, rep_bytes); + srcptr += stride; + dstptr += stride; + } + if (diff) /* number of leftover pixels: 3 for pngtest */ + { + final_val+=diff*BPP2; + for (; i < final_val; i += stride) + { + if (rep_bytes > (int)(final_val-i)) + rep_bytes = (int)(final_val-i); + png_memcpy(dstptr, srcptr, rep_bytes); + srcptr += stride; + dstptr += stride; + } + } + } /* end of else (_mmx_supported) */ + + break; + } /* end 16 bpp */ + + case 24: /* png_ptr->row_info.pixel_depth */ + { + png_bytep srcptr; + png_bytep dstptr; + +#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) +#if !defined(PNG_1_0_X) + if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) + /* && _mmx_supported */ ) +#else + if (_mmx_supported) +#endif + { + png_uint_32 len; + int diff; + int dummy_value_a; // fix 'forbidden register spilled' error + int dummy_value_d; + int dummy_value_c; + int dummy_value_S; + int dummy_value_D; + _unmask = ~mask; // global variable for -fPIC version + srcptr = png_ptr->row_buf + 1; + dstptr = row; + len = png_ptr->width &~7; // reduce to multiple of 8 + diff = (int) (png_ptr->width & 7); // amount lost // + + __asm__ __volatile__ ( + "movd _unmask, %%mm7 \n\t" // load bit pattern + "psubb %%mm6, %%mm6 \n\t" // zero mm6 + "punpcklbw %%mm7, %%mm7 \n\t" + "punpcklwd %%mm7, %%mm7 \n\t" + "punpckldq %%mm7, %%mm7 \n\t" // fill reg with 8 masks + + "movq _mask24_0, %%mm0 \n\t" + "movq _mask24_1, %%mm1 \n\t" + "movq _mask24_2, %%mm2 \n\t" + + "pand %%mm7, %%mm0 \n\t" + "pand %%mm7, %%mm1 \n\t" + "pand %%mm7, %%mm2 \n\t" + + "pcmpeqb %%mm6, %%mm0 \n\t" + "pcmpeqb %%mm6, %%mm1 \n\t" + "pcmpeqb %%mm6, %%mm2 \n\t" + +// preload "movl len, %%ecx \n\t" // load length of line +// preload "movl srcptr, %%esi \n\t" // load source +// preload "movl dstptr, %%edi \n\t" // load dest + + "cmpl $0, %%ecx \n\t" + "jz mainloop24end \n\t" + + "mainloop24: \n\t" + "movq (%%esi), %%mm4 \n\t" + "pand %%mm0, %%mm4 \n\t" + "movq %%mm0, %%mm6 \n\t" + "movq (%%edi), %%mm7 \n\t" + "pandn %%mm7, %%mm6 \n\t" + "por %%mm6, %%mm4 \n\t" + "movq %%mm4, (%%edi) \n\t" + + "movq 8(%%esi), %%mm5 \n\t" + "pand %%mm1, %%mm5 \n\t" + "movq %%mm1, %%mm7 \n\t" + "movq 8(%%edi), %%mm6 \n\t" + "pandn %%mm6, %%mm7 \n\t" + "por %%mm7, %%mm5 \n\t" + "movq %%mm5, 8(%%edi) \n\t" + + "movq 16(%%esi), %%mm6 \n\t" + "pand %%mm2, %%mm6 \n\t" + "movq %%mm2, %%mm4 \n\t" + "movq 16(%%edi), %%mm7 \n\t" + "pandn %%mm7, %%mm4 \n\t" + "por %%mm4, %%mm6 \n\t" + "movq %%mm6, 16(%%edi) \n\t" + + "addl $24, %%esi \n\t" // inc by 24 bytes processed + "addl $24, %%edi \n\t" + "subl $8, %%ecx \n\t" // dec by 8 pixels processed + + "ja mainloop24 \n\t" + + "mainloop24end: \n\t" +// preload "movl diff, %%ecx \n\t" // (diff is in eax) + "movl %%eax, %%ecx \n\t" + "cmpl $0, %%ecx \n\t" + "jz end24 \n\t" +// preload "movl mask, %%edx \n\t" + "sall $24, %%edx \n\t" // make low byte, high byte + + "secondloop24: \n\t" + "sall %%edx \n\t" // move high bit to CF + "jnc skip24 \n\t" // if CF = 0 + "movw (%%esi), %%ax \n\t" + "movw %%ax, (%%edi) \n\t" + "xorl %%eax, %%eax \n\t" + "movb 2(%%esi), %%al \n\t" + "movb %%al, 2(%%edi) \n\t" + + "skip24: \n\t" + "addl $3, %%esi \n\t" + "addl $3, %%edi \n\t" + "decl %%ecx \n\t" + "jnz secondloop24 \n\t" + + "end24: \n\t" + "EMMS \n\t" // DONE + + : "=a" (dummy_value_a), // output regs (dummy) + "=d" (dummy_value_d), + "=c" (dummy_value_c), + "=S" (dummy_value_S), + "=D" (dummy_value_D) + + : "3" (srcptr), // esi // input regs + "4" (dstptr), // edi + "0" (diff), // eax +// was (unmask) "b" RESERVED // ebx // Global Offset Table idx + "2" (len), // ecx + "1" (mask) // edx + +#if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */ + : "%mm0", "%mm1", "%mm2" // clobber list + , "%mm4", "%mm5", "%mm6", "%mm7" +#endif + ); + } + else /* mmx _not supported - Use modified C routine */ +#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ + { + register png_uint_32 i; + png_uint_32 initial_val = BPP3 * png_pass_start[png_ptr->pass]; + /* png.c: png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; */ + register int stride = BPP3 * png_pass_inc[png_ptr->pass]; + /* png.c: png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; */ + register int rep_bytes = BPP3 * png_pass_width[png_ptr->pass]; + /* png.c: png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; */ + png_uint_32 len = png_ptr->width &~7; /* reduce to mult. of 8 */ + int diff = (int) (png_ptr->width & 7); /* amount lost */ + register png_uint_32 final_val = BPP3 * len; /* GRR bugfix */ + + srcptr = png_ptr->row_buf + 1 + initial_val; + dstptr = row + initial_val; + + for (i = initial_val; i < final_val; i += stride) + { + png_memcpy(dstptr, srcptr, rep_bytes); + srcptr += stride; + dstptr += stride; + } + if (diff) /* number of leftover pixels: 3 for pngtest */ + { + final_val+=diff*BPP3; + for (; i < final_val; i += stride) + { + if (rep_bytes > (int)(final_val-i)) + rep_bytes = (int)(final_val-i); + png_memcpy(dstptr, srcptr, rep_bytes); + srcptr += stride; + dstptr += stride; + } + } + } /* end of else (_mmx_supported) */ + + break; + } /* end 24 bpp */ + + case 32: /* png_ptr->row_info.pixel_depth */ + { + png_bytep srcptr; + png_bytep dstptr; + +#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) +#if !defined(PNG_1_0_X) + if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) + /* && _mmx_supported */ ) +#else + if (_mmx_supported) +#endif + { + png_uint_32 len; + int diff; + int dummy_value_a; // fix 'forbidden register spilled' error + int dummy_value_d; + int dummy_value_c; + int dummy_value_S; + int dummy_value_D; + _unmask = ~mask; // global variable for -fPIC version + srcptr = png_ptr->row_buf + 1; + dstptr = row; + len = png_ptr->width &~7; // reduce to multiple of 8 + diff = (int) (png_ptr->width & 7); // amount lost // + + __asm__ __volatile__ ( + "movd _unmask, %%mm7 \n\t" // load bit pattern + "psubb %%mm6, %%mm6 \n\t" // zero mm6 + "punpcklbw %%mm7, %%mm7 \n\t" + "punpcklwd %%mm7, %%mm7 \n\t" + "punpckldq %%mm7, %%mm7 \n\t" // fill reg with 8 masks + + "movq _mask32_0, %%mm0 \n\t" + "movq _mask32_1, %%mm1 \n\t" + "movq _mask32_2, %%mm2 \n\t" + "movq _mask32_3, %%mm3 \n\t" + + "pand %%mm7, %%mm0 \n\t" + "pand %%mm7, %%mm1 \n\t" + "pand %%mm7, %%mm2 \n\t" + "pand %%mm7, %%mm3 \n\t" + + "pcmpeqb %%mm6, %%mm0 \n\t" + "pcmpeqb %%mm6, %%mm1 \n\t" + "pcmpeqb %%mm6, %%mm2 \n\t" + "pcmpeqb %%mm6, %%mm3 \n\t" + +// preload "movl len, %%ecx \n\t" // load length of line +// preload "movl srcptr, %%esi \n\t" // load source +// preload "movl dstptr, %%edi \n\t" // load dest + + "cmpl $0, %%ecx \n\t" // lcr + "jz mainloop32end \n\t" + + "mainloop32: \n\t" + "movq (%%esi), %%mm4 \n\t" + "pand %%mm0, %%mm4 \n\t" + "movq %%mm0, %%mm6 \n\t" + "movq (%%edi), %%mm7 \n\t" + "pandn %%mm7, %%mm6 \n\t" + "por %%mm6, %%mm4 \n\t" + "movq %%mm4, (%%edi) \n\t" + + "movq 8(%%esi), %%mm5 \n\t" + "pand %%mm1, %%mm5 \n\t" + "movq %%mm1, %%mm7 \n\t" + "movq 8(%%edi), %%mm6 \n\t" + "pandn %%mm6, %%mm7 \n\t" + "por %%mm7, %%mm5 \n\t" + "movq %%mm5, 8(%%edi) \n\t" + + "movq 16(%%esi), %%mm6 \n\t" + "pand %%mm2, %%mm6 \n\t" + "movq %%mm2, %%mm4 \n\t" + "movq 16(%%edi), %%mm7 \n\t" + "pandn %%mm7, %%mm4 \n\t" + "por %%mm4, %%mm6 \n\t" + "movq %%mm6, 16(%%edi) \n\t" + + "movq 24(%%esi), %%mm7 \n\t" + "pand %%mm3, %%mm7 \n\t" + "movq %%mm3, %%mm5 \n\t" + "movq 24(%%edi), %%mm4 \n\t" + "pandn %%mm4, %%mm5 \n\t" + "por %%mm5, %%mm7 \n\t" + "movq %%mm7, 24(%%edi) \n\t" + + "addl $32, %%esi \n\t" // inc by 32 bytes processed + "addl $32, %%edi \n\t" + "subl $8, %%ecx \n\t" // dec by 8 pixels processed + "ja mainloop32 \n\t" + + "mainloop32end: \n\t" +// preload "movl diff, %%ecx \n\t" // (diff is in eax) + "movl %%eax, %%ecx \n\t" + "cmpl $0, %%ecx \n\t" + "jz end32 \n\t" +// preload "movl mask, %%edx \n\t" + "sall $24, %%edx \n\t" // low byte => high byte + + "secondloop32: \n\t" + "sall %%edx \n\t" // move high bit to CF + "jnc skip32 \n\t" // if CF = 0 + "movl (%%esi), %%eax \n\t" + "movl %%eax, (%%edi) \n\t" + + "skip32: \n\t" + "addl $4, %%esi \n\t" + "addl $4, %%edi \n\t" + "decl %%ecx \n\t" + "jnz secondloop32 \n\t" + + "end32: \n\t" + "EMMS \n\t" // DONE + + : "=a" (dummy_value_a), // output regs (dummy) + "=d" (dummy_value_d), + "=c" (dummy_value_c), + "=S" (dummy_value_S), + "=D" (dummy_value_D) + + : "3" (srcptr), // esi // input regs + "4" (dstptr), // edi + "0" (diff), // eax +// was (unmask) "b" RESERVED // ebx // Global Offset Table idx + "2" (len), // ecx + "1" (mask) // edx + +#if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */ + : "%mm0", "%mm1", "%mm2", "%mm3" // clobber list + , "%mm4", "%mm5", "%mm6", "%mm7" +#endif + ); + } + else /* mmx _not supported - Use modified C routine */ +#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ + { + register png_uint_32 i; + png_uint_32 initial_val = BPP4 * png_pass_start[png_ptr->pass]; + /* png.c: png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; */ + register int stride = BPP4 * png_pass_inc[png_ptr->pass]; + /* png.c: png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; */ + register int rep_bytes = BPP4 * png_pass_width[png_ptr->pass]; + /* png.c: png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; */ + png_uint_32 len = png_ptr->width &~7; /* reduce to mult. of 8 */ + int diff = (int) (png_ptr->width & 7); /* amount lost */ + register png_uint_32 final_val = BPP4 * len; /* GRR bugfix */ + + srcptr = png_ptr->row_buf + 1 + initial_val; + dstptr = row + initial_val; + + for (i = initial_val; i < final_val; i += stride) + { + png_memcpy(dstptr, srcptr, rep_bytes); + srcptr += stride; + dstptr += stride; + } + if (diff) /* number of leftover pixels: 3 for pngtest */ + { + final_val+=diff*BPP4; + for (; i < final_val; i += stride) + { + if (rep_bytes > (int)(final_val-i)) + rep_bytes = (int)(final_val-i); + png_memcpy(dstptr, srcptr, rep_bytes); + srcptr += stride; + dstptr += stride; + } + } + } /* end of else (_mmx_supported) */ + + break; + } /* end 32 bpp */ + + case 48: /* png_ptr->row_info.pixel_depth */ + { + png_bytep srcptr; + png_bytep dstptr; + +#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) +#if !defined(PNG_1_0_X) + if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) + /* && _mmx_supported */ ) +#else + if (_mmx_supported) +#endif + { + png_uint_32 len; + int diff; + int dummy_value_a; // fix 'forbidden register spilled' error + int dummy_value_d; + int dummy_value_c; + int dummy_value_S; + int dummy_value_D; + _unmask = ~mask; // global variable for -fPIC version + srcptr = png_ptr->row_buf + 1; + dstptr = row; + len = png_ptr->width &~7; // reduce to multiple of 8 + diff = (int) (png_ptr->width & 7); // amount lost // + + __asm__ __volatile__ ( + "movd _unmask, %%mm7 \n\t" // load bit pattern + "psubb %%mm6, %%mm6 \n\t" // zero mm6 + "punpcklbw %%mm7, %%mm7 \n\t" + "punpcklwd %%mm7, %%mm7 \n\t" + "punpckldq %%mm7, %%mm7 \n\t" // fill reg with 8 masks + + "movq _mask48_0, %%mm0 \n\t" + "movq _mask48_1, %%mm1 \n\t" + "movq _mask48_2, %%mm2 \n\t" + "movq _mask48_3, %%mm3 \n\t" + "movq _mask48_4, %%mm4 \n\t" + "movq _mask48_5, %%mm5 \n\t" + + "pand %%mm7, %%mm0 \n\t" + "pand %%mm7, %%mm1 \n\t" + "pand %%mm7, %%mm2 \n\t" + "pand %%mm7, %%mm3 \n\t" + "pand %%mm7, %%mm4 \n\t" + "pand %%mm7, %%mm5 \n\t" + + "pcmpeqb %%mm6, %%mm0 \n\t" + "pcmpeqb %%mm6, %%mm1 \n\t" + "pcmpeqb %%mm6, %%mm2 \n\t" + "pcmpeqb %%mm6, %%mm3 \n\t" + "pcmpeqb %%mm6, %%mm4 \n\t" + "pcmpeqb %%mm6, %%mm5 \n\t" + +// preload "movl len, %%ecx \n\t" // load length of line +// preload "movl srcptr, %%esi \n\t" // load source +// preload "movl dstptr, %%edi \n\t" // load dest + + "cmpl $0, %%ecx \n\t" + "jz mainloop48end \n\t" + + "mainloop48: \n\t" + "movq (%%esi), %%mm7 \n\t" + "pand %%mm0, %%mm7 \n\t" + "movq %%mm0, %%mm6 \n\t" + "pandn (%%edi), %%mm6 \n\t" + "por %%mm6, %%mm7 \n\t" + "movq %%mm7, (%%edi) \n\t" + + "movq 8(%%esi), %%mm6 \n\t" + "pand %%mm1, %%mm6 \n\t" + "movq %%mm1, %%mm7 \n\t" + "pandn 8(%%edi), %%mm7 \n\t" + "por %%mm7, %%mm6 \n\t" + "movq %%mm6, 8(%%edi) \n\t" + + "movq 16(%%esi), %%mm6 \n\t" + "pand %%mm2, %%mm6 \n\t" + "movq %%mm2, %%mm7 \n\t" + "pandn 16(%%edi), %%mm7 \n\t" + "por %%mm7, %%mm6 \n\t" + "movq %%mm6, 16(%%edi) \n\t" + + "movq 24(%%esi), %%mm7 \n\t" + "pand %%mm3, %%mm7 \n\t" + "movq %%mm3, %%mm6 \n\t" + "pandn 24(%%edi), %%mm6 \n\t" + "por %%mm6, %%mm7 \n\t" + "movq %%mm7, 24(%%edi) \n\t" + + "movq 32(%%esi), %%mm6 \n\t" + "pand %%mm4, %%mm6 \n\t" + "movq %%mm4, %%mm7 \n\t" + "pandn 32(%%edi), %%mm7 \n\t" + "por %%mm7, %%mm6 \n\t" + "movq %%mm6, 32(%%edi) \n\t" + + "movq 40(%%esi), %%mm7 \n\t" + "pand %%mm5, %%mm7 \n\t" + "movq %%mm5, %%mm6 \n\t" + "pandn 40(%%edi), %%mm6 \n\t" + "por %%mm6, %%mm7 \n\t" + "movq %%mm7, 40(%%edi) \n\t" + + "addl $48, %%esi \n\t" // inc by 48 bytes processed + "addl $48, %%edi \n\t" + "subl $8, %%ecx \n\t" // dec by 8 pixels processed + + "ja mainloop48 \n\t" + + "mainloop48end: \n\t" +// preload "movl diff, %%ecx \n\t" // (diff is in eax) + "movl %%eax, %%ecx \n\t" + "cmpl $0, %%ecx \n\t" + "jz end48 \n\t" +// preload "movl mask, %%edx \n\t" + "sall $24, %%edx \n\t" // make low byte, high byte + + "secondloop48: \n\t" + "sall %%edx \n\t" // move high bit to CF + "jnc skip48 \n\t" // if CF = 0 + "movl (%%esi), %%eax \n\t" + "movl %%eax, (%%edi) \n\t" + + "skip48: \n\t" + "addl $4, %%esi \n\t" + "addl $4, %%edi \n\t" + "decl %%ecx \n\t" + "jnz secondloop48 \n\t" + + "end48: \n\t" + "EMMS \n\t" // DONE + + : "=a" (dummy_value_a), // output regs (dummy) + "=d" (dummy_value_d), + "=c" (dummy_value_c), + "=S" (dummy_value_S), + "=D" (dummy_value_D) + + : "3" (srcptr), // esi // input regs + "4" (dstptr), // edi + "0" (diff), // eax +// was (unmask) "b" RESERVED // ebx // Global Offset Table idx + "2" (len), // ecx + "1" (mask) // edx + +#if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */ + : "%mm0", "%mm1", "%mm2", "%mm3" // clobber list + , "%mm4", "%mm5", "%mm6", "%mm7" +#endif + ); + } + else /* mmx _not supported - Use modified C routine */ +#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ + { + register png_uint_32 i; + png_uint_32 initial_val = BPP6 * png_pass_start[png_ptr->pass]; + /* png.c: png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; */ + register int stride = BPP6 * png_pass_inc[png_ptr->pass]; + /* png.c: png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; */ + register int rep_bytes = BPP6 * png_pass_width[png_ptr->pass]; + /* png.c: png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; */ + png_uint_32 len = png_ptr->width &~7; /* reduce to mult. of 8 */ + int diff = (int) (png_ptr->width & 7); /* amount lost */ + register png_uint_32 final_val = BPP6 * len; /* GRR bugfix */ + + srcptr = png_ptr->row_buf + 1 + initial_val; + dstptr = row + initial_val; + + for (i = initial_val; i < final_val; i += stride) + { + png_memcpy(dstptr, srcptr, rep_bytes); + srcptr += stride; + dstptr += stride; + } + if (diff) /* number of leftover pixels: 3 for pngtest */ + { + final_val+=diff*BPP6; + for (; i < final_val; i += stride) + { + if (rep_bytes > (int)(final_val-i)) + rep_bytes = (int)(final_val-i); + png_memcpy(dstptr, srcptr, rep_bytes); + srcptr += stride; + dstptr += stride; + } + } + } /* end of else (_mmx_supported) */ + + break; + } /* end 48 bpp */ + + case 64: /* png_ptr->row_info.pixel_depth */ + { + png_bytep srcptr; + png_bytep dstptr; + register png_uint_32 i; + png_uint_32 initial_val = BPP8 * png_pass_start[png_ptr->pass]; + /* png.c: png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; */ + register int stride = BPP8 * png_pass_inc[png_ptr->pass]; + /* png.c: png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; */ + register int rep_bytes = BPP8 * png_pass_width[png_ptr->pass]; + /* png.c: png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; */ + png_uint_32 len = png_ptr->width &~7; /* reduce to mult. of 8 */ + int diff = (int) (png_ptr->width & 7); /* amount lost */ + register png_uint_32 final_val = BPP8 * len; /* GRR bugfix */ + + srcptr = png_ptr->row_buf + 1 + initial_val; + dstptr = row + initial_val; + + for (i = initial_val; i < final_val; i += stride) + { + png_memcpy(dstptr, srcptr, rep_bytes); + srcptr += stride; + dstptr += stride; + } + if (diff) /* number of leftover pixels: 3 for pngtest */ + { + final_val+=diff*BPP8; + for (; i < final_val; i += stride) + { + if (rep_bytes > (int)(final_val-i)) + rep_bytes = (int)(final_val-i); + png_memcpy(dstptr, srcptr, rep_bytes); + srcptr += stride; + dstptr += stride; + } + } + + break; + } /* end 64 bpp */ + + default: /* png_ptr->row_info.pixel_depth != 1,2,4,8,16,24,32,48,64 */ + { + /* this should never happen */ + png_warning(png_ptr, "Invalid row_info.pixel_depth in pnggccrd"); + break; + } + } /* end switch (png_ptr->row_info.pixel_depth) */ + + } /* end if (non-trivial mask) */ + +} /* end png_combine_row() */ + +#endif /* PNG_HAVE_ASSEMBLER_COMBINE_ROW */ + + + + +/*===========================================================================*/ +/* */ +/* P N G _ D O _ R E A D _ I N T E R L A C E */ +/* */ +/*===========================================================================*/ + +#if defined(PNG_READ_INTERLACING_SUPPORTED) +#if defined(PNG_HAVE_ASSEMBLER_READ_INTERLACE) + +/* png_do_read_interlace() is called after any 16-bit to 8-bit conversion + * has taken place. [GRR: what other steps come before and/or after?] + */ + +void /* PRIVATE */ +png_do_read_interlace(png_structp png_ptr) +{ + png_row_infop row_info = &(png_ptr->row_info); + png_bytep row = png_ptr->row_buf + 1; + int pass = png_ptr->pass; +#if defined(PNG_READ_PACKSWAP_SUPPORTED) + png_uint_32 transformations = png_ptr->transformations; +#endif + + png_debug(1, "in png_do_read_interlace (pnggccrd.c)\n"); + +#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) + if (_mmx_supported == 2) { +#if !defined(PNG_1_0_X) + /* this should have happened in png_init_mmx_flags() already */ + png_warning(png_ptr, "asm_flags may not have been initialized"); +#endif + png_mmx_support(); + } +#endif + + if (row != NULL && row_info != NULL) + { + png_uint_32 final_width; + + final_width = row_info->width * png_pass_inc[pass]; + + switch (row_info->pixel_depth) + { + case 1: + { + png_bytep sp, dp; + int sshift, dshift; + int s_start, s_end, s_inc; + png_byte v; + png_uint_32 i; + int j; + + sp = row + (png_size_t)((row_info->width - 1) >> 3); + dp = row + (png_size_t)((final_width - 1) >> 3); +#if defined(PNG_READ_PACKSWAP_SUPPORTED) + if (transformations & PNG_PACKSWAP) + { + sshift = (int)((row_info->width + 7) & 7); + dshift = (int)((final_width + 7) & 7); + s_start = 7; + s_end = 0; + s_inc = -1; + } + else +#endif + { + sshift = 7 - (int)((row_info->width + 7) & 7); + dshift = 7 - (int)((final_width + 7) & 7); + s_start = 0; + s_end = 7; + s_inc = 1; + } + + for (i = row_info->width; i; i--) + { + v = (png_byte)((*sp >> sshift) & 0x1); + for (j = 0; j < png_pass_inc[pass]; j++) + { + *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff); + *dp |= (png_byte)(v << dshift); + if (dshift == s_end) + { + dshift = s_start; + dp--; + } + else + dshift += s_inc; + } + if (sshift == s_end) + { + sshift = s_start; + sp--; + } + else + sshift += s_inc; + } + break; + } + + case 2: + { + png_bytep sp, dp; + int sshift, dshift; + int s_start, s_end, s_inc; + png_uint_32 i; + + sp = row + (png_size_t)((row_info->width - 1) >> 2); + dp = row + (png_size_t)((final_width - 1) >> 2); +#if defined(PNG_READ_PACKSWAP_SUPPORTED) + if (transformations & PNG_PACKSWAP) + { + sshift = (png_size_t)(((row_info->width + 3) & 3) << 1); + dshift = (png_size_t)(((final_width + 3) & 3) << 1); + s_start = 6; + s_end = 0; + s_inc = -2; + } + else +#endif + { + sshift = (png_size_t)((3 - ((row_info->width + 3) & 3)) << 1); + dshift = (png_size_t)((3 - ((final_width + 3) & 3)) << 1); + s_start = 0; + s_end = 6; + s_inc = 2; + } + + for (i = row_info->width; i; i--) + { + png_byte v; + int j; + + v = (png_byte)((*sp >> sshift) & 0x3); + for (j = 0; j < png_pass_inc[pass]; j++) + { + *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff); + *dp |= (png_byte)(v << dshift); + if (dshift == s_end) + { + dshift = s_start; + dp--; + } + else + dshift += s_inc; + } + if (sshift == s_end) + { + sshift = s_start; + sp--; + } + else + sshift += s_inc; + } + break; + } + + case 4: + { + png_bytep sp, dp; + int sshift, dshift; + int s_start, s_end, s_inc; + png_uint_32 i; + + sp = row + (png_size_t)((row_info->width - 1) >> 1); + dp = row + (png_size_t)((final_width - 1) >> 1); +#if defined(PNG_READ_PACKSWAP_SUPPORTED) + if (transformations & PNG_PACKSWAP) + { + sshift = (png_size_t)(((row_info->width + 1) & 1) << 2); + dshift = (png_size_t)(((final_width + 1) & 1) << 2); + s_start = 4; + s_end = 0; + s_inc = -4; + } + else +#endif + { + sshift = (png_size_t)((1 - ((row_info->width + 1) & 1)) << 2); + dshift = (png_size_t)((1 - ((final_width + 1) & 1)) << 2); + s_start = 0; + s_end = 4; + s_inc = 4; + } + + for (i = row_info->width; i; i--) + { + png_byte v; + int j; + + v = (png_byte)((*sp >> sshift) & 0xf); + for (j = 0; j < png_pass_inc[pass]; j++) + { + *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff); + *dp |= (png_byte)(v << dshift); + if (dshift == s_end) + { + dshift = s_start; + dp--; + } + else + dshift += s_inc; + } + if (sshift == s_end) + { + sshift = s_start; + sp--; + } + else + sshift += s_inc; + } + break; + } + + /*====================================================================*/ + + default: /* 8-bit or larger (this is where the routine is modified) */ + { +#if 0 +// static unsigned long long _const4 = 0x0000000000FFFFFFLL; no good +// static unsigned long long const4 = 0x0000000000FFFFFFLL; no good +// unsigned long long _const4 = 0x0000000000FFFFFFLL; no good +// unsigned long long const4 = 0x0000000000FFFFFFLL; no good +#endif + png_bytep sptr, dp; + png_uint_32 i; + png_size_t pixel_bytes; + int width = (int)row_info->width; + + pixel_bytes = (row_info->pixel_depth >> 3); + + /* point sptr at the last pixel in the pre-expanded row: */ + sptr = row + (width - 1) * pixel_bytes; + + /* point dp at the last pixel position in the expanded row: */ + dp = row + (final_width - 1) * pixel_bytes; + + /* New code by Nirav Chhatrapati - Intel Corporation */ + +#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) +#if !defined(PNG_1_0_X) + if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_INTERLACE) + /* && _mmx_supported */ ) +#else + if (_mmx_supported) +#endif + { + //-------------------------------------------------------------- + if (pixel_bytes == 3) + { + if (((pass == 0) || (pass == 1)) && width) + { + int dummy_value_c; // fix 'forbidden register spilled' + int dummy_value_S; + int dummy_value_D; + int dummy_value_a; + + __asm__ __volatile__ ( + "subl $21, %%edi \n\t" + // (png_pass_inc[pass] - 1)*pixel_bytes + + ".loop3_pass0: \n\t" + "movd (%%esi), %%mm0 \n\t" // x x x x x 2 1 0 + "pand (%3), %%mm0 \n\t" // z z z z z 2 1 0 + "movq %%mm0, %%mm1 \n\t" // z z z z z 2 1 0 + "psllq $16, %%mm0 \n\t" // z z z 2 1 0 z z + "movq %%mm0, %%mm2 \n\t" // z z z 2 1 0 z z + "psllq $24, %%mm0 \n\t" // 2 1 0 z z z z z + "psrlq $8, %%mm1 \n\t" // z z z z z z 2 1 + "por %%mm2, %%mm0 \n\t" // 2 1 0 2 1 0 z z + "por %%mm1, %%mm0 \n\t" // 2 1 0 2 1 0 2 1 + "movq %%mm0, %%mm3 \n\t" // 2 1 0 2 1 0 2 1 + "psllq $16, %%mm0 \n\t" // 0 2 1 0 2 1 z z + "movq %%mm3, %%mm4 \n\t" // 2 1 0 2 1 0 2 1 + "punpckhdq %%mm0, %%mm3 \n\t" // 0 2 1 0 2 1 0 2 + "movq %%mm4, 16(%%edi) \n\t" + "psrlq $32, %%mm0 \n\t" // z z z z 0 2 1 0 + "movq %%mm3, 8(%%edi) \n\t" + "punpckldq %%mm4, %%mm0 \n\t" // 1 0 2 1 0 2 1 0 + "subl $3, %%esi \n\t" + "movq %%mm0, (%%edi) \n\t" + "subl $24, %%edi \n\t" + "decl %%ecx \n\t" + "jnz .loop3_pass0 \n\t" + "EMMS \n\t" // DONE + + : "=c" (dummy_value_c), // output regs (dummy) + "=S" (dummy_value_S), + "=D" (dummy_value_D), + "=a" (dummy_value_a) + + + : "1" (sptr), // esi // input regs + "2" (dp), // edi + "0" (width), // ecx + "3" (&_const4) // %1(?) (0x0000000000FFFFFFLL) + +#if 0 /* %mm0, ..., %mm4 not supported by gcc 2.7.2.3 or egcs 1.1 */ + : "%mm0", "%mm1", "%mm2" // clobber list + , "%mm3", "%mm4" +#endif + ); + } + else if (((pass == 2) || (pass == 3)) && width) + { + int dummy_value_c; // fix 'forbidden register spilled' + int dummy_value_S; + int dummy_value_D; + int dummy_value_a; + + __asm__ __volatile__ ( + "subl $9, %%edi \n\t" + // (png_pass_inc[pass] - 1)*pixel_bytes + + ".loop3_pass2: \n\t" + "movd (%%esi), %%mm0 \n\t" // x x x x x 2 1 0 + "pand (%3), %%mm0 \n\t" // z z z z z 2 1 0 + "movq %%mm0, %%mm1 \n\t" // z z z z z 2 1 0 + "psllq $16, %%mm0 \n\t" // z z z 2 1 0 z z + "movq %%mm0, %%mm2 \n\t" // z z z 2 1 0 z z + "psllq $24, %%mm0 \n\t" // 2 1 0 z z z z z + "psrlq $8, %%mm1 \n\t" // z z z z z z 2 1 + "por %%mm2, %%mm0 \n\t" // 2 1 0 2 1 0 z z + "por %%mm1, %%mm0 \n\t" // 2 1 0 2 1 0 2 1 + "movq %%mm0, 4(%%edi) \n\t" + "psrlq $16, %%mm0 \n\t" // z z 2 1 0 2 1 0 + "subl $3, %%esi \n\t" + "movd %%mm0, (%%edi) \n\t" + "subl $12, %%edi \n\t" + "decl %%ecx \n\t" + "jnz .loop3_pass2 \n\t" + "EMMS \n\t" // DONE + + : "=c" (dummy_value_c), // output regs (dummy) + "=S" (dummy_value_S), + "=D" (dummy_value_D), + "=a" (dummy_value_a) + + : "1" (sptr), // esi // input regs + "2" (dp), // edi + "0" (width), // ecx + "3" (&_const4) // (0x0000000000FFFFFFLL) + +#if 0 /* %mm0, ..., %mm2 not supported by gcc 2.7.2.3 or egcs 1.1 */ + : "%mm0", "%mm1", "%mm2" // clobber list +#endif + ); + } + else if (width) /* && ((pass == 4) || (pass == 5)) */ + { + int width_mmx = ((width >> 1) << 1) - 8; // GRR: huh? + if (width_mmx < 0) + width_mmx = 0; + width -= width_mmx; // 8 or 9 pix, 24 or 27 bytes + if (width_mmx) + { + // png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; + // sptr points at last pixel in pre-expanded row + // dp points at last pixel position in expanded row + int dummy_value_c; // fix 'forbidden register spilled' + int dummy_value_S; + int dummy_value_D; + int dummy_value_a; + int dummy_value_d; + + __asm__ __volatile__ ( + "subl $3, %%esi \n\t" + "subl $9, %%edi \n\t" + // (png_pass_inc[pass] + 1)*pixel_bytes + + ".loop3_pass4: \n\t" + "movq (%%esi), %%mm0 \n\t" // x x 5 4 3 2 1 0 + "movq %%mm0, %%mm1 \n\t" // x x 5 4 3 2 1 0 + "movq %%mm0, %%mm2 \n\t" // x x 5 4 3 2 1 0 + "psllq $24, %%mm0 \n\t" // 4 3 2 1 0 z z z + "pand (%3), %%mm1 \n\t" // z z z z z 2 1 0 + "psrlq $24, %%mm2 \n\t" // z z z x x 5 4 3 + "por %%mm1, %%mm0 \n\t" // 4 3 2 1 0 2 1 0 + "movq %%mm2, %%mm3 \n\t" // z z z x x 5 4 3 + "psllq $8, %%mm2 \n\t" // z z x x 5 4 3 z + "movq %%mm0, (%%edi) \n\t" + "psrlq $16, %%mm3 \n\t" // z z z z z x x 5 + "pand (%4), %%mm3 \n\t" // z z z z z z z 5 + "por %%mm3, %%mm2 \n\t" // z z x x 5 4 3 5 + "subl $6, %%esi \n\t" + "movd %%mm2, 8(%%edi) \n\t" + "subl $12, %%edi \n\t" + "subl $2, %%ecx \n\t" + "jnz .loop3_pass4 \n\t" + "EMMS \n\t" // DONE + + : "=c" (dummy_value_c), // output regs (dummy) + "=S" (dummy_value_S), + "=D" (dummy_value_D), + "=a" (dummy_value_a), + "=d" (dummy_value_d) + + : "1" (sptr), // esi // input regs + "2" (dp), // edi + "0" (width_mmx), // ecx + "3" (&_const4), // 0x0000000000FFFFFFLL + "4" (&_const6) // 0x00000000000000FFLL + +#if 0 /* %mm0, ..., %mm3 not supported by gcc 2.7.2.3 or egcs 1.1 */ + : "%mm0", "%mm1" // clobber list + , "%mm2", "%mm3" +#endif + ); + } + + sptr -= width_mmx*3; + dp -= width_mmx*6; + for (i = width; i; i--) + { + png_byte v[8]; + int j; + + png_memcpy(v, sptr, 3); + for (j = 0; j < png_pass_inc[pass]; j++) + { + png_memcpy(dp, v, 3); + dp -= 3; + } + sptr -= 3; + } + } + } /* end of pixel_bytes == 3 */ + + //-------------------------------------------------------------- + else if (pixel_bytes == 1) + { + if (((pass == 0) || (pass == 1)) && width) + { + int width_mmx = ((width >> 2) << 2); + width -= width_mmx; // 0-3 pixels => 0-3 bytes + if (width_mmx) + { + int dummy_value_c; // fix 'forbidden register spilled' + int dummy_value_S; + int dummy_value_D; + + __asm__ __volatile__ ( + "subl $3, %%esi \n\t" + "subl $31, %%edi \n\t" + + ".loop1_pass0: \n\t" + "movd (%%esi), %%mm0 \n\t" // x x x x 3 2 1 0 + "movq %%mm0, %%mm1 \n\t" // x x x x 3 2 1 0 + "punpcklbw %%mm0, %%mm0 \n\t" // 3 3 2 2 1 1 0 0 + "movq %%mm0, %%mm2 \n\t" // 3 3 2 2 1 1 0 0 + "punpcklwd %%mm0, %%mm0 \n\t" // 1 1 1 1 0 0 0 0 + "movq %%mm0, %%mm3 \n\t" // 1 1 1 1 0 0 0 0 + "punpckldq %%mm0, %%mm0 \n\t" // 0 0 0 0 0 0 0 0 + "punpckhdq %%mm3, %%mm3 \n\t" // 1 1 1 1 1 1 1 1 + "movq %%mm0, (%%edi) \n\t" + "punpckhwd %%mm2, %%mm2 \n\t" // 3 3 3 3 2 2 2 2 + "movq %%mm3, 8(%%edi) \n\t" + "movq %%mm2, %%mm4 \n\t" // 3 3 3 3 2 2 2 2 + "punpckldq %%mm2, %%mm2 \n\t" // 2 2 2 2 2 2 2 2 + "punpckhdq %%mm4, %%mm4 \n\t" // 3 3 3 3 3 3 3 3 + "movq %%mm2, 16(%%edi) \n\t" + "subl $4, %%esi \n\t" + "movq %%mm4, 24(%%edi) \n\t" + "subl $32, %%edi \n\t" + "subl $4, %%ecx \n\t" + "jnz .loop1_pass0 \n\t" + "EMMS \n\t" // DONE + + : "=c" (dummy_value_c), // output regs (dummy) + "=S" (dummy_value_S), + "=D" (dummy_value_D) + + : "1" (sptr), // esi // input regs + "2" (dp), // edi + "0" (width_mmx) // ecx + +#if 0 /* %mm0, ..., %mm4 not supported by gcc 2.7.2.3 or egcs 1.1 */ + : "%mm0", "%mm1", "%mm2" // clobber list + , "%mm3", "%mm4" +#endif + ); + } + + sptr -= width_mmx; + dp -= width_mmx*8; + for (i = width; i; i--) + { + int j; + + /* I simplified this part in version 1.0.4e + * here and in several other instances where + * pixel_bytes == 1 -- GR-P + * + * Original code: + * + * png_byte v[8]; + * png_memcpy(v, sptr, pixel_bytes); + * for (j = 0; j < png_pass_inc[pass]; j++) + * { + * png_memcpy(dp, v, pixel_bytes); + * dp -= pixel_bytes; + * } + * sptr -= pixel_bytes; + * + * Replacement code is in the next three lines: + */ + + for (j = 0; j < png_pass_inc[pass]; j++) + { + *dp-- = *sptr; + } + --sptr; + } + } + else if (((pass == 2) || (pass == 3)) && width) + { + int width_mmx = ((width >> 2) << 2); + width -= width_mmx; // 0-3 pixels => 0-3 bytes + if (width_mmx) + { + int dummy_value_c; // fix 'forbidden register spilled' + int dummy_value_S; + int dummy_value_D; + + __asm__ __volatile__ ( + "subl $3, %%esi \n\t" + "subl $15, %%edi \n\t" + + ".loop1_pass2: \n\t" + "movd (%%esi), %%mm0 \n\t" // x x x x 3 2 1 0 + "punpcklbw %%mm0, %%mm0 \n\t" // 3 3 2 2 1 1 0 0 + "movq %%mm0, %%mm1 \n\t" // 3 3 2 2 1 1 0 0 + "punpcklwd %%mm0, %%mm0 \n\t" // 1 1 1 1 0 0 0 0 + "punpckhwd %%mm1, %%mm1 \n\t" // 3 3 3 3 2 2 2 2 + "movq %%mm0, (%%edi) \n\t" + "subl $4, %%esi \n\t" + "movq %%mm1, 8(%%edi) \n\t" + "subl $16, %%edi \n\t" + "subl $4, %%ecx \n\t" + "jnz .loop1_pass2 \n\t" + "EMMS \n\t" // DONE + + : "=c" (dummy_value_c), // output regs (dummy) + "=S" (dummy_value_S), + "=D" (dummy_value_D) + + : "1" (sptr), // esi // input regs + "2" (dp), // edi + "0" (width_mmx) // ecx + +#if 0 /* %mm0, %mm1 not supported by gcc 2.7.2.3 or egcs 1.1 */ + : "%mm0", "%mm1" // clobber list +#endif + ); + } + + sptr -= width_mmx; + dp -= width_mmx*4; + for (i = width; i; i--) + { + int j; + + for (j = 0; j < png_pass_inc[pass]; j++) + { + *dp-- = *sptr; + } + --sptr; + } + } + else if (width) /* && ((pass == 4) || (pass == 5)) */ + { + int width_mmx = ((width >> 3) << 3); + width -= width_mmx; // 0-3 pixels => 0-3 bytes + if (width_mmx) + { + int dummy_value_c; // fix 'forbidden register spilled' + int dummy_value_S; + int dummy_value_D; + + __asm__ __volatile__ ( + "subl $7, %%esi \n\t" + "subl $15, %%edi \n\t" + + ".loop1_pass4: \n\t" + "movq (%%esi), %%mm0 \n\t" // 7 6 5 4 3 2 1 0 + "movq %%mm0, %%mm1 \n\t" // 7 6 5 4 3 2 1 0 + "punpcklbw %%mm0, %%mm0 \n\t" // 3 3 2 2 1 1 0 0 + "punpckhbw %%mm1, %%mm1 \n\t" // 7 7 6 6 5 5 4 4 + "movq %%mm1, 8(%%edi) \n\t" + "subl $8, %%esi \n\t" + "movq %%mm0, (%%edi) \n\t" + "subl $16, %%edi \n\t" + "subl $8, %%ecx \n\t" + "jnz .loop1_pass4 \n\t" + "EMMS \n\t" // DONE + + : "=c" (dummy_value_c), // output regs (none) + "=S" (dummy_value_S), + "=D" (dummy_value_D) + + : "1" (sptr), // esi // input regs + "2" (dp), // edi + "0" (width_mmx) // ecx + +#if 0 /* %mm0, %mm1 not supported by gcc 2.7.2.3 or egcs 1.1 */ + : "%mm0", "%mm1" // clobber list +#endif + ); + } + + sptr -= width_mmx; + dp -= width_mmx*2; + for (i = width; i; i--) + { + int j; + + for (j = 0; j < png_pass_inc[pass]; j++) + { + *dp-- = *sptr; + } + --sptr; + } + } + } /* end of pixel_bytes == 1 */ + + //-------------------------------------------------------------- + else if (pixel_bytes == 2) + { + if (((pass == 0) || (pass == 1)) && width) + { + int width_mmx = ((width >> 1) << 1); + width -= width_mmx; // 0,1 pixels => 0,2 bytes + if (width_mmx) + { + int dummy_value_c; // fix 'forbidden register spilled' + int dummy_value_S; + int dummy_value_D; + + __asm__ __volatile__ ( + "subl $2, %%esi \n\t" + "subl $30, %%edi \n\t" + + ".loop2_pass0: \n\t" + "movd (%%esi), %%mm0 \n\t" // x x x x 3 2 1 0 + "punpcklwd %%mm0, %%mm0 \n\t" // 3 2 3 2 1 0 1 0 + "movq %%mm0, %%mm1 \n\t" // 3 2 3 2 1 0 1 0 + "punpckldq %%mm0, %%mm0 \n\t" // 1 0 1 0 1 0 1 0 + "punpckhdq %%mm1, %%mm1 \n\t" // 3 2 3 2 3 2 3 2 + "movq %%mm0, (%%edi) \n\t" + "movq %%mm0, 8(%%edi) \n\t" + "movq %%mm1, 16(%%edi) \n\t" + "subl $4, %%esi \n\t" + "movq %%mm1, 24(%%edi) \n\t" + "subl $32, %%edi \n\t" + "subl $2, %%ecx \n\t" + "jnz .loop2_pass0 \n\t" + "EMMS \n\t" // DONE + + : "=c" (dummy_value_c), // output regs (dummy) + "=S" (dummy_value_S), + "=D" (dummy_value_D) + + : "1" (sptr), // esi // input regs + "2" (dp), // edi + "0" (width_mmx) // ecx + +#if 0 /* %mm0, %mm1 not supported by gcc 2.7.2.3 or egcs 1.1 */ + : "%mm0", "%mm1" // clobber list +#endif + ); + } + + sptr -= (width_mmx*2 - 2); // sign fixed + dp -= (width_mmx*16 - 2); // sign fixed + for (i = width; i; i--) + { + png_byte v[8]; + int j; + sptr -= 2; + png_memcpy(v, sptr, 2); + for (j = 0; j < png_pass_inc[pass]; j++) + { + dp -= 2; + png_memcpy(dp, v, 2); + } + } + } + else if (((pass == 2) || (pass == 3)) && width) + { + int width_mmx = ((width >> 1) << 1) ; + width -= width_mmx; // 0,1 pixels => 0,2 bytes + if (width_mmx) + { + int dummy_value_c; // fix 'forbidden register spilled' + int dummy_value_S; + int dummy_value_D; + + __asm__ __volatile__ ( + "subl $2, %%esi \n\t" + "subl $14, %%edi \n\t" + + ".loop2_pass2: \n\t" + "movd (%%esi), %%mm0 \n\t" // x x x x 3 2 1 0 + "punpcklwd %%mm0, %%mm0 \n\t" // 3 2 3 2 1 0 1 0 + "movq %%mm0, %%mm1 \n\t" // 3 2 3 2 1 0 1 0 + "punpckldq %%mm0, %%mm0 \n\t" // 1 0 1 0 1 0 1 0 + "punpckhdq %%mm1, %%mm1 \n\t" // 3 2 3 2 3 2 3 2 + "movq %%mm0, (%%edi) \n\t" + "subl $4, %%esi \n\t" + "movq %%mm1, 8(%%edi) \n\t" + "subl $16, %%edi \n\t" + "subl $2, %%ecx \n\t" + "jnz .loop2_pass2 \n\t" + "EMMS \n\t" // DONE + + : "=c" (dummy_value_c), // output regs (dummy) + "=S" (dummy_value_S), + "=D" (dummy_value_D) + + : "1" (sptr), // esi // input regs + "2" (dp), // edi + "0" (width_mmx) // ecx + +#if 0 /* %mm0, %mm1 not supported by gcc 2.7.2.3 or egcs 1.1 */ + : "%mm0", "%mm1" // clobber list +#endif + ); + } + + sptr -= (width_mmx*2 - 2); // sign fixed + dp -= (width_mmx*8 - 2); // sign fixed + for (i = width; i; i--) + { + png_byte v[8]; + int j; + sptr -= 2; + png_memcpy(v, sptr, 2); + for (j = 0; j < png_pass_inc[pass]; j++) + { + dp -= 2; + png_memcpy(dp, v, 2); + } + } + } + else if (width) // pass == 4 or 5 + { + int width_mmx = ((width >> 1) << 1) ; + width -= width_mmx; // 0,1 pixels => 0,2 bytes + if (width_mmx) + { + int dummy_value_c; // fix 'forbidden register spilled' + int dummy_value_S; + int dummy_value_D; + + __asm__ __volatile__ ( + "subl $2, %%esi \n\t" + "subl $6, %%edi \n\t" + + ".loop2_pass4: \n\t" + "movd (%%esi), %%mm0 \n\t" // x x x x 3 2 1 0 + "punpcklwd %%mm0, %%mm0 \n\t" // 3 2 3 2 1 0 1 0 + "subl $4, %%esi \n\t" + "movq %%mm0, (%%edi) \n\t" + "subl $8, %%edi \n\t" + "subl $2, %%ecx \n\t" + "jnz .loop2_pass4 \n\t" + "EMMS \n\t" // DONE + + : "=c" (dummy_value_c), // output regs (dummy) + "=S" (dummy_value_S), + "=D" (dummy_value_D) + + : "1" (sptr), // esi // input regs + "2" (dp), // edi + "0" (width_mmx) // ecx + +#if 0 /* %mm0 not supported by gcc 2.7.2.3 or egcs 1.1 */ + : "%mm0" // clobber list +#endif + ); + } + + sptr -= (width_mmx*2 - 2); // sign fixed + dp -= (width_mmx*4 - 2); // sign fixed + for (i = width; i; i--) + { + png_byte v[8]; + int j; + sptr -= 2; + png_memcpy(v, sptr, 2); + for (j = 0; j < png_pass_inc[pass]; j++) + { + dp -= 2; + png_memcpy(dp, v, 2); + } + } + } + } /* end of pixel_bytes == 2 */ + + //-------------------------------------------------------------- + else if (pixel_bytes == 4) + { + if (((pass == 0) || (pass == 1)) && width) + { + int width_mmx = ((width >> 1) << 1); + width -= width_mmx; // 0,1 pixels => 0,4 bytes + if (width_mmx) + { + int dummy_value_c; // fix 'forbidden register spilled' + int dummy_value_S; + int dummy_value_D; + + __asm__ __volatile__ ( + "subl $4, %%esi \n\t" + "subl $60, %%edi \n\t" + + ".loop4_pass0: \n\t" + "movq (%%esi), %%mm0 \n\t" // 7 6 5 4 3 2 1 0 + "movq %%mm0, %%mm1 \n\t" // 7 6 5 4 3 2 1 0 + "punpckldq %%mm0, %%mm0 \n\t" // 3 2 1 0 3 2 1 0 + "punpckhdq %%mm1, %%mm1 \n\t" // 7 6 5 4 7 6 5 4 + "movq %%mm0, (%%edi) \n\t" + "movq %%mm0, 8(%%edi) \n\t" + "movq %%mm0, 16(%%edi) \n\t" + "movq %%mm0, 24(%%edi) \n\t" + "movq %%mm1, 32(%%edi) \n\t" + "movq %%mm1, 40(%%edi) \n\t" + "movq %%mm1, 48(%%edi) \n\t" + "subl $8, %%esi \n\t" + "movq %%mm1, 56(%%edi) \n\t" + "subl $64, %%edi \n\t" + "subl $2, %%ecx \n\t" + "jnz .loop4_pass0 \n\t" + "EMMS \n\t" // DONE + + : "=c" (dummy_value_c), // output regs (dummy) + "=S" (dummy_value_S), + "=D" (dummy_value_D) + + : "1" (sptr), // esi // input regs + "2" (dp), // edi + "0" (width_mmx) // ecx + +#if 0 /* %mm0, %mm1 not supported by gcc 2.7.2.3 or egcs 1.1 */ + : "%mm0", "%mm1" // clobber list +#endif + ); + } + + sptr -= (width_mmx*4 - 4); // sign fixed + dp -= (width_mmx*32 - 4); // sign fixed + for (i = width; i; i--) + { + png_byte v[8]; + int j; + sptr -= 4; + png_memcpy(v, sptr, 4); + for (j = 0; j < png_pass_inc[pass]; j++) + { + dp -= 4; + png_memcpy(dp, v, 4); + } + } + } + else if (((pass == 2) || (pass == 3)) && width) + { + int width_mmx = ((width >> 1) << 1); + width -= width_mmx; // 0,1 pixels => 0,4 bytes + if (width_mmx) + { + int dummy_value_c; // fix 'forbidden register spilled' + int dummy_value_S; + int dummy_value_D; + + __asm__ __volatile__ ( + "subl $4, %%esi \n\t" + "subl $28, %%edi \n\t" + + ".loop4_pass2: \n\t" + "movq (%%esi), %%mm0 \n\t" // 7 6 5 4 3 2 1 0 + "movq %%mm0, %%mm1 \n\t" // 7 6 5 4 3 2 1 0 + "punpckldq %%mm0, %%mm0 \n\t" // 3 2 1 0 3 2 1 0 + "punpckhdq %%mm1, %%mm1 \n\t" // 7 6 5 4 7 6 5 4 + "movq %%mm0, (%%edi) \n\t" + "movq %%mm0, 8(%%edi) \n\t" + "movq %%mm1, 16(%%edi) \n\t" + "movq %%mm1, 24(%%edi) \n\t" + "subl $8, %%esi \n\t" + "subl $32, %%edi \n\t" + "subl $2, %%ecx \n\t" + "jnz .loop4_pass2 \n\t" + "EMMS \n\t" // DONE + + : "=c" (dummy_value_c), // output regs (dummy) + "=S" (dummy_value_S), + "=D" (dummy_value_D) + + : "1" (sptr), // esi // input regs + "2" (dp), // edi + "0" (width_mmx) // ecx + +#if 0 /* %mm0, %mm1 not supported by gcc 2.7.2.3 or egcs 1.1 */ + : "%mm0", "%mm1" // clobber list +#endif + ); + } + + sptr -= (width_mmx*4 - 4); // sign fixed + dp -= (width_mmx*16 - 4); // sign fixed + for (i = width; i; i--) + { + png_byte v[8]; + int j; + sptr -= 4; + png_memcpy(v, sptr, 4); + for (j = 0; j < png_pass_inc[pass]; j++) + { + dp -= 4; + png_memcpy(dp, v, 4); + } + } + } + else if (width) // pass == 4 or 5 + { + int width_mmx = ((width >> 1) << 1) ; + width -= width_mmx; // 0,1 pixels => 0,4 bytes + if (width_mmx) + { + int dummy_value_c; // fix 'forbidden register spilled' + int dummy_value_S; + int dummy_value_D; + + __asm__ __volatile__ ( + "subl $4, %%esi \n\t" + "subl $12, %%edi \n\t" + + ".loop4_pass4: \n\t" + "movq (%%esi), %%mm0 \n\t" // 7 6 5 4 3 2 1 0 + "movq %%mm0, %%mm1 \n\t" // 7 6 5 4 3 2 1 0 + "punpckldq %%mm0, %%mm0 \n\t" // 3 2 1 0 3 2 1 0 + "punpckhdq %%mm1, %%mm1 \n\t" // 7 6 5 4 7 6 5 4 + "movq %%mm0, (%%edi) \n\t" + "subl $8, %%esi \n\t" + "movq %%mm1, 8(%%edi) \n\t" + "subl $16, %%edi \n\t" + "subl $2, %%ecx \n\t" + "jnz .loop4_pass4 \n\t" + "EMMS \n\t" // DONE + + : "=c" (dummy_value_c), // output regs (dummy) + "=S" (dummy_value_S), + "=D" (dummy_value_D) + + : "1" (sptr), // esi // input regs + "2" (dp), // edi + "0" (width_mmx) // ecx + +#if 0 /* %mm0, %mm1 not supported by gcc 2.7.2.3 or egcs 1.1 */ + : "%mm0", "%mm1" // clobber list +#endif + ); + } + + sptr -= (width_mmx*4 - 4); // sign fixed + dp -= (width_mmx*8 - 4); // sign fixed + for (i = width; i; i--) + { + png_byte v[8]; + int j; + sptr -= 4; + png_memcpy(v, sptr, 4); + for (j = 0; j < png_pass_inc[pass]; j++) + { + dp -= 4; + png_memcpy(dp, v, 4); + } + } + } + } /* end of pixel_bytes == 4 */ + + //-------------------------------------------------------------- + else if (pixel_bytes == 8) + { +// GRR TEST: should work, but needs testing (special 64-bit version of rpng2?) + // GRR NOTE: no need to combine passes here! + if (((pass == 0) || (pass == 1)) && width) + { + int dummy_value_c; // fix 'forbidden register spilled' + int dummy_value_S; + int dummy_value_D; + + // source is 8-byte RRGGBBAA + // dest is 64-byte RRGGBBAA RRGGBBAA RRGGBBAA RRGGBBAA ... + __asm__ __volatile__ ( + "subl $56, %%edi \n\t" // start of last block + + ".loop8_pass0: \n\t" + "movq (%%esi), %%mm0 \n\t" // 7 6 5 4 3 2 1 0 + "movq %%mm0, (%%edi) \n\t" + "movq %%mm0, 8(%%edi) \n\t" + "movq %%mm0, 16(%%edi) \n\t" + "movq %%mm0, 24(%%edi) \n\t" + "movq %%mm0, 32(%%edi) \n\t" + "movq %%mm0, 40(%%edi) \n\t" + "movq %%mm0, 48(%%edi) \n\t" + "subl $8, %%esi \n\t" + "movq %%mm0, 56(%%edi) \n\t" + "subl $64, %%edi \n\t" + "decl %%ecx \n\t" + "jnz .loop8_pass0 \n\t" + "EMMS \n\t" // DONE + + : "=c" (dummy_value_c), // output regs (dummy) + "=S" (dummy_value_S), + "=D" (dummy_value_D) + + : "1" (sptr), // esi // input regs + "2" (dp), // edi + "0" (width) // ecx + +#if 0 /* %mm0 not supported by gcc 2.7.2.3 or egcs 1.1 */ + : "%mm0" // clobber list +#endif + ); + } + else if (((pass == 2) || (pass == 3)) && width) + { + // source is 8-byte RRGGBBAA + // dest is 32-byte RRGGBBAA RRGGBBAA RRGGBBAA RRGGBBAA + // (recall that expansion is _in place_: sptr and dp + // both point at locations within same row buffer) + { + int dummy_value_c; // fix 'forbidden register spilled' + int dummy_value_S; + int dummy_value_D; + + __asm__ __volatile__ ( + "subl $24, %%edi \n\t" // start of last block + + ".loop8_pass2: \n\t" + "movq (%%esi), %%mm0 \n\t" // 7 6 5 4 3 2 1 0 + "movq %%mm0, (%%edi) \n\t" + "movq %%mm0, 8(%%edi) \n\t" + "movq %%mm0, 16(%%edi) \n\t" + "subl $8, %%esi \n\t" + "movq %%mm0, 24(%%edi) \n\t" + "subl $32, %%edi \n\t" + "decl %%ecx \n\t" + "jnz .loop8_pass2 \n\t" + "EMMS \n\t" // DONE + + : "=c" (dummy_value_c), // output regs (dummy) + "=S" (dummy_value_S), + "=D" (dummy_value_D) + + : "1" (sptr), // esi // input regs + "2" (dp), // edi + "0" (width) // ecx + +#if 0 /* %mm0 not supported by gcc 2.7.2.3 or egcs 1.1 */ + : "%mm0" // clobber list +#endif + ); + } + } + else if (width) // pass == 4 or 5 + { + // source is 8-byte RRGGBBAA + // dest is 16-byte RRGGBBAA RRGGBBAA + { + int dummy_value_c; // fix 'forbidden register spilled' + int dummy_value_S; + int dummy_value_D; + + __asm__ __volatile__ ( + "subl $8, %%edi \n\t" // start of last block + + ".loop8_pass4: \n\t" + "movq (%%esi), %%mm0 \n\t" // 7 6 5 4 3 2 1 0 + "movq %%mm0, (%%edi) \n\t" + "subl $8, %%esi \n\t" + "movq %%mm0, 8(%%edi) \n\t" + "subl $16, %%edi \n\t" + "decl %%ecx \n\t" + "jnz .loop8_pass4 \n\t" + "EMMS \n\t" // DONE + + : "=c" (dummy_value_c), // output regs (dummy) + "=S" (dummy_value_S), + "=D" (dummy_value_D) + + : "1" (sptr), // esi // input regs + "2" (dp), // edi + "0" (width) // ecx + +#if 0 /* %mm0 not supported by gcc 2.7.2.3 or egcs 1.1 */ + : "%mm0" // clobber list +#endif + ); + } + } + + } /* end of pixel_bytes == 8 */ + + //-------------------------------------------------------------- + else if (pixel_bytes == 6) + { + for (i = width; i; i--) + { + png_byte v[8]; + int j; + png_memcpy(v, sptr, 6); + for (j = 0; j < png_pass_inc[pass]; j++) + { + png_memcpy(dp, v, 6); + dp -= 6; + } + sptr -= 6; + } + } /* end of pixel_bytes == 6 */ + + //-------------------------------------------------------------- + else + { + for (i = width; i; i--) + { + png_byte v[8]; + int j; + png_memcpy(v, sptr, pixel_bytes); + for (j = 0; j < png_pass_inc[pass]; j++) + { + png_memcpy(dp, v, pixel_bytes); + dp -= pixel_bytes; + } + sptr-= pixel_bytes; + } + } + } // end of _mmx_supported ======================================== + + else /* MMX not supported: use modified C code - takes advantage + * of inlining of png_memcpy for a constant */ + /* GRR 19991007: does it? or should pixel_bytes in each + * block be replaced with immediate value (e.g., 1)? */ + /* GRR 19991017: replaced with constants in each case */ +#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ + { + if (pixel_bytes == 1) + { + for (i = width; i; i--) + { + int j; + for (j = 0; j < png_pass_inc[pass]; j++) + { + *dp-- = *sptr; + } + --sptr; + } + } + else if (pixel_bytes == 3) + { + for (i = width; i; i--) + { + png_byte v[8]; + int j; + png_memcpy(v, sptr, 3); + for (j = 0; j < png_pass_inc[pass]; j++) + { + png_memcpy(dp, v, 3); + dp -= 3; + } + sptr -= 3; + } + } + else if (pixel_bytes == 2) + { + for (i = width; i; i--) + { + png_byte v[8]; + int j; + png_memcpy(v, sptr, 2); + for (j = 0; j < png_pass_inc[pass]; j++) + { + png_memcpy(dp, v, 2); + dp -= 2; + } + sptr -= 2; + } + } + else if (pixel_bytes == 4) + { + for (i = width; i; i--) + { + png_byte v[8]; + int j; + png_memcpy(v, sptr, 4); + for (j = 0; j < png_pass_inc[pass]; j++) + { +#ifdef PNG_DEBUG + if (dp < row || dp+3 > row+png_ptr->row_buf_size) + { + printf("dp out of bounds: row=%d, dp=%d, rp=%d\n", + row, dp, row+png_ptr->row_buf_size); + printf("row_buf=%d\n",png_ptr->row_buf_size); + } +#endif + png_memcpy(dp, v, 4); + dp -= 4; + } + sptr -= 4; + } + } + else if (pixel_bytes == 6) + { + for (i = width; i; i--) + { + png_byte v[8]; + int j; + png_memcpy(v, sptr, 6); + for (j = 0; j < png_pass_inc[pass]; j++) + { + png_memcpy(dp, v, 6); + dp -= 6; + } + sptr -= 6; + } + } + else if (pixel_bytes == 8) + { + for (i = width; i; i--) + { + png_byte v[8]; + int j; + png_memcpy(v, sptr, 8); + for (j = 0; j < png_pass_inc[pass]; j++) + { + png_memcpy(dp, v, 8); + dp -= 8; + } + sptr -= 8; + } + } + else /* GRR: should never be reached */ + { + for (i = width; i; i--) + { + png_byte v[8]; + int j; + png_memcpy(v, sptr, pixel_bytes); + for (j = 0; j < png_pass_inc[pass]; j++) + { + png_memcpy(dp, v, pixel_bytes); + dp -= pixel_bytes; + } + sptr -= pixel_bytes; + } + } + + } /* end if (MMX not supported) */ + break; + } + } /* end switch (row_info->pixel_depth) */ + + row_info->width = final_width; + + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,final_width); + } + +} /* end png_do_read_interlace() */ + +#endif /* PNG_HAVE_ASSEMBLER_READ_INTERLACE */ +#endif /* PNG_READ_INTERLACING_SUPPORTED */ + + + +#if defined(PNG_HAVE_ASSEMBLER_READ_FILTER_ROW) +#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) + +// These variables are utilized in the functions below. They are declared +// globally here to ensure alignment on 8-byte boundaries. + +union uAll { + long long use; + double align; +} _LBCarryMask = {0x0101010101010101LL}, + _HBClearMask = {0x7f7f7f7f7f7f7f7fLL}, + _ActiveMask, _ActiveMask2, _ActiveMaskEnd, _ShiftBpp, _ShiftRem; + +#ifdef PNG_THREAD_UNSAFE_OK +//===========================================================================// +// // +// P N G _ R E A D _ F I L T E R _ R O W _ M M X _ A V G // +// // +//===========================================================================// + +// Optimized code for PNG Average filter decoder + +static void /* PRIVATE */ +png_read_filter_row_mmx_avg(png_row_infop row_info, png_bytep row, + png_bytep prev_row) +{ + int bpp; + int dummy_value_c; // fix 'forbidden register 2 (cx) was spilled' error + int dummy_value_S; + int dummy_value_D; + + bpp = (row_info->pixel_depth + 7) >> 3; // get # bytes per pixel + _FullLength = row_info->rowbytes; // # of bytes to filter + + __asm__ __volatile__ ( + // initialize address pointers and offset +#ifdef __PIC__ + "pushl %%ebx \n\t" // save index to Global Offset Table +#endif +//pre "movl row, %%edi \n\t" // edi: Avg(x) + "xorl %%ebx, %%ebx \n\t" // ebx: x + "movl %%edi, %%edx \n\t" +//pre "movl prev_row, %%esi \n\t" // esi: Prior(x) +//pre "subl bpp, %%edx \n\t" // (bpp is preloaded into ecx) + "subl %%ecx, %%edx \n\t" // edx: Raw(x-bpp) + + "xorl %%eax,%%eax \n\t" + + // Compute the Raw value for the first bpp bytes + // Raw(x) = Avg(x) + (Prior(x)/2) + "avg_rlp: \n\t" + "movb (%%esi,%%ebx,),%%al \n\t" // load al with Prior(x) + "incl %%ebx \n\t" + "shrb %%al \n\t" // divide by 2 + "addb -1(%%edi,%%ebx,),%%al \n\t" // add Avg(x); -1 to offset inc ebx +//pre "cmpl bpp, %%ebx \n\t" // (bpp is preloaded into ecx) + "cmpl %%ecx, %%ebx \n\t" + "movb %%al,-1(%%edi,%%ebx,) \n\t" // write Raw(x); -1 to offset inc ebx + "jb avg_rlp \n\t" // mov does not affect flags + + // get # of bytes to alignment + "movl %%edi, _dif \n\t" // take start of row + "addl %%ebx, _dif \n\t" // add bpp + "addl $0xf, _dif \n\t" // add 7+8 to incr past alignment bdry + "andl $0xfffffff8, _dif \n\t" // mask to alignment boundary + "subl %%edi, _dif \n\t" // subtract from start => value ebx at + "jz avg_go \n\t" // alignment + + // fix alignment + // Compute the Raw value for the bytes up to the alignment boundary + // Raw(x) = Avg(x) + ((Raw(x-bpp) + Prior(x))/2) + "xorl %%ecx, %%ecx \n\t" + + "avg_lp1: \n\t" + "xorl %%eax, %%eax \n\t" + "movb (%%esi,%%ebx,), %%cl \n\t" // load cl with Prior(x) + "movb (%%edx,%%ebx,), %%al \n\t" // load al with Raw(x-bpp) + "addw %%cx, %%ax \n\t" + "incl %%ebx \n\t" + "shrw %%ax \n\t" // divide by 2 + "addb -1(%%edi,%%ebx,), %%al \n\t" // add Avg(x); -1 to offset inc ebx + "cmpl _dif, %%ebx \n\t" // check if at alignment boundary + "movb %%al, -1(%%edi,%%ebx,) \n\t" // write Raw(x); -1 to offset inc ebx + "jb avg_lp1 \n\t" // repeat until at alignment boundary + + "avg_go: \n\t" + "movl _FullLength, %%eax \n\t" + "movl %%eax, %%ecx \n\t" + "subl %%ebx, %%eax \n\t" // subtract alignment fix + "andl $0x00000007, %%eax \n\t" // calc bytes over mult of 8 + "subl %%eax, %%ecx \n\t" // drop over bytes from original length + "movl %%ecx, _MMXLength \n\t" +#ifdef __PIC__ + "popl %%ebx \n\t" // restore index to Global Offset Table +#endif + + : "=c" (dummy_value_c), // output regs (dummy) + "=S" (dummy_value_S), + "=D" (dummy_value_D) + + : "0" (bpp), // ecx // input regs + "1" (prev_row), // esi + "2" (row) // edi + + : "%eax", "%edx" // clobber list +#ifndef __PIC__ + , "%ebx" +#endif + // GRR: INCLUDE "memory" as clobbered? (_dif, _MMXLength) + // (seems to work fine without...) + ); + + // now do the math for the rest of the row + switch (bpp) + { + case 3: + { + _ActiveMask.use = 0x0000000000ffffffLL; + _ShiftBpp.use = 24; // == 3 * 8 + _ShiftRem.use = 40; // == 64 - 24 + + __asm__ __volatile__ ( + // re-init address pointers and offset + "movq _ActiveMask, %%mm7 \n\t" + "movl _dif, %%ecx \n\t" // ecx: x = offset to + "movq _LBCarryMask, %%mm5 \n\t" // alignment boundary +// preload "movl row, %%edi \n\t" // edi: Avg(x) + "movq _HBClearMask, %%mm4 \n\t" +// preload "movl prev_row, %%esi \n\t" // esi: Prior(x) + + // prime the pump: load the first Raw(x-bpp) data set + "movq -8(%%edi,%%ecx,), %%mm2 \n\t" // load previous aligned 8 bytes + // (correct pos. in loop below) + "avg_3lp: \n\t" + "movq (%%edi,%%ecx,), %%mm0 \n\t" // load mm0 with Avg(x) + "movq %%mm5, %%mm3 \n\t" + "psrlq _ShiftRem, %%mm2 \n\t" // correct position Raw(x-bpp) + // data + "movq (%%esi,%%ecx,), %%mm1 \n\t" // load mm1 with Prior(x) + "movq %%mm7, %%mm6 \n\t" + "pand %%mm1, %%mm3 \n\t" // get lsb for each prev_row byte + "psrlq $1, %%mm1 \n\t" // divide prev_row bytes by 2 + "pand %%mm4, %%mm1 \n\t" // clear invalid bit 7 of each + // byte + "paddb %%mm1, %%mm0 \n\t" // add (Prev_row/2) to Avg for + // each byte + // add 1st active group (Raw(x-bpp)/2) to average with LBCarry + "movq %%mm3, %%mm1 \n\t" // now use mm1 for getting + // LBCarrys + "pand %%mm2, %%mm1 \n\t" // get LBCarrys for each byte + // where both + // lsb's were == 1 (only valid for active group) + "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2 + "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7 of each + // byte + "paddb %%mm1, %%mm2 \n\t" // add LBCarrys to (Raw(x-bpp)/2) + // for each byte + "pand %%mm6, %%mm2 \n\t" // leave only Active Group 1 + // bytes to add to Avg + "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) + LBCarrys to + // Avg for each Active + // byte + // add 2nd active group (Raw(x-bpp)/2) to average with _LBCarry + "psllq _ShiftBpp, %%mm6 \n\t" // shift the mm6 mask to cover + // bytes 3-5 + "movq %%mm0, %%mm2 \n\t" // mov updated Raws to mm2 + "psllq _ShiftBpp, %%mm2 \n\t" // shift data to pos. correctly + "movq %%mm3, %%mm1 \n\t" // now use mm1 for getting + // LBCarrys + "pand %%mm2, %%mm1 \n\t" // get LBCarrys for each byte + // where both + // lsb's were == 1 (only valid for active group) + "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2 + "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7 of each + // byte + "paddb %%mm1, %%mm2 \n\t" // add LBCarrys to (Raw(x-bpp)/2) + // for each byte + "pand %%mm6, %%mm2 \n\t" // leave only Active Group 2 + // bytes to add to Avg + "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) + LBCarrys to + // Avg for each Active + // byte + + // add 3rd active group (Raw(x-bpp)/2) to average with _LBCarry + "psllq _ShiftBpp, %%mm6 \n\t" // shift mm6 mask to cover last + // two + // bytes + "movq %%mm0, %%mm2 \n\t" // mov updated Raws to mm2 + "psllq _ShiftBpp, %%mm2 \n\t" // shift data to pos. correctly + // Data only needs to be shifted once here to + // get the correct x-bpp offset. + "movq %%mm3, %%mm1 \n\t" // now use mm1 for getting + // LBCarrys + "pand %%mm2, %%mm1 \n\t" // get LBCarrys for each byte + // where both + // lsb's were == 1 (only valid for active group) + "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2 + "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7 of each + // byte + "paddb %%mm1, %%mm2 \n\t" // add LBCarrys to (Raw(x-bpp)/2) + // for each byte + "pand %%mm6, %%mm2 \n\t" // leave only Active Group 2 + // bytes to add to Avg + "addl $8, %%ecx \n\t" + "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) + LBCarrys to + // Avg for each Active + // byte + // now ready to write back to memory + "movq %%mm0, -8(%%edi,%%ecx,) \n\t" + // move updated Raw(x) to use as Raw(x-bpp) for next loop + "cmpl _MMXLength, %%ecx \n\t" + "movq %%mm0, %%mm2 \n\t" // mov updated Raw(x) to mm2 + "jb avg_3lp \n\t" + + : "=S" (dummy_value_S), // output regs (dummy) + "=D" (dummy_value_D) + + : "0" (prev_row), // esi // input regs + "1" (row) // edi + + : "%ecx" // clobber list +#if 0 /* %mm0, ..., %mm7 not supported by gcc 2.7.2.3 or egcs 1.1 */ + , "%mm0", "%mm1", "%mm2", "%mm3" + , "%mm4", "%mm5", "%mm6", "%mm7" +#endif + ); + } + break; // end 3 bpp + + case 6: + case 4: + //case 7: // who wrote this? PNG doesn't support 5 or 7 bytes/pixel + //case 5: // GRR BOGUS + { + _ActiveMask.use = 0xffffffffffffffffLL; // use shift below to clear + // appropriate inactive bytes + _ShiftBpp.use = bpp << 3; + _ShiftRem.use = 64 - _ShiftBpp.use; + + __asm__ __volatile__ ( + "movq _HBClearMask, %%mm4 \n\t" + + // re-init address pointers and offset + "movl _dif, %%ecx \n\t" // ecx: x = offset to + // alignment boundary + + // load _ActiveMask and clear all bytes except for 1st active group + "movq _ActiveMask, %%mm7 \n\t" +// preload "movl row, %%edi \n\t" // edi: Avg(x) + "psrlq _ShiftRem, %%mm7 \n\t" +// preload "movl prev_row, %%esi \n\t" // esi: Prior(x) + "movq %%mm7, %%mm6 \n\t" + "movq _LBCarryMask, %%mm5 \n\t" + "psllq _ShiftBpp, %%mm6 \n\t" // create mask for 2nd active + // group + + // prime the pump: load the first Raw(x-bpp) data set + "movq -8(%%edi,%%ecx,), %%mm2 \n\t" // load previous aligned 8 bytes + // (we correct pos. in loop below) + "avg_4lp: \n\t" + "movq (%%edi,%%ecx,), %%mm0 \n\t" + "psrlq _ShiftRem, %%mm2 \n\t" // shift data to pos. correctly + "movq (%%esi,%%ecx,), %%mm1 \n\t" + // add (Prev_row/2) to average + "movq %%mm5, %%mm3 \n\t" + "pand %%mm1, %%mm3 \n\t" // get lsb for each prev_row byte + "psrlq $1, %%mm1 \n\t" // divide prev_row bytes by 2 + "pand %%mm4, %%mm1 \n\t" // clear invalid bit 7 of each + // byte + "paddb %%mm1, %%mm0 \n\t" // add (Prev_row/2) to Avg for + // each byte + // add 1st active group (Raw(x-bpp)/2) to average with _LBCarry + "movq %%mm3, %%mm1 \n\t" // now use mm1 for getting + // LBCarrys + "pand %%mm2, %%mm1 \n\t" // get LBCarrys for each byte + // where both + // lsb's were == 1 (only valid for active group) + "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2 + "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7 of each + // byte + "paddb %%mm1, %%mm2 \n\t" // add LBCarrys to (Raw(x-bpp)/2) + // for each byte + "pand %%mm7, %%mm2 \n\t" // leave only Active Group 1 + // bytes to add to Avg + "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) + LBCarrys to Avg + // for each Active + // byte + // add 2nd active group (Raw(x-bpp)/2) to average with _LBCarry + "movq %%mm0, %%mm2 \n\t" // mov updated Raws to mm2 + "psllq _ShiftBpp, %%mm2 \n\t" // shift data to pos. correctly + "addl $8, %%ecx \n\t" + "movq %%mm3, %%mm1 \n\t" // now use mm1 for getting + // LBCarrys + "pand %%mm2, %%mm1 \n\t" // get LBCarrys for each byte + // where both + // lsb's were == 1 (only valid for active group) + "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2 + "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7 of each + // byte + "paddb %%mm1, %%mm2 \n\t" // add LBCarrys to (Raw(x-bpp)/2) + // for each byte + "pand %%mm6, %%mm2 \n\t" // leave only Active Group 2 + // bytes to add to Avg + "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) + LBCarrys to + // Avg for each Active + // byte + "cmpl _MMXLength, %%ecx \n\t" + // now ready to write back to memory + "movq %%mm0, -8(%%edi,%%ecx,) \n\t" + // prep Raw(x-bpp) for next loop + "movq %%mm0, %%mm2 \n\t" // mov updated Raws to mm2 + "jb avg_4lp \n\t" + + : "=S" (dummy_value_S), // output regs (dummy) + "=D" (dummy_value_D) + + : "0" (prev_row), // esi // input regs + "1" (row) // edi + + : "%ecx" // clobber list +#if 0 /* %mm0, ..., %mm7 not supported by gcc 2.7.2.3 or egcs 1.1 */ + , "%mm0", "%mm1", "%mm2", "%mm3" + , "%mm4", "%mm5", "%mm6", "%mm7" +#endif + ); + } + break; // end 4,6 bpp + + case 2: + { + _ActiveMask.use = 0x000000000000ffffLL; + _ShiftBpp.use = 16; // == 2 * 8 + _ShiftRem.use = 48; // == 64 - 16 + + __asm__ __volatile__ ( + // load _ActiveMask + "movq _ActiveMask, %%mm7 \n\t" + // re-init address pointers and offset + "movl _dif, %%ecx \n\t" // ecx: x = offset to alignment + // boundary + "movq _LBCarryMask, %%mm5 \n\t" +// preload "movl row, %%edi \n\t" // edi: Avg(x) + "movq _HBClearMask, %%mm4 \n\t" +// preload "movl prev_row, %%esi \n\t" // esi: Prior(x) + + // prime the pump: load the first Raw(x-bpp) data set + "movq -8(%%edi,%%ecx,), %%mm2 \n\t" // load previous aligned 8 bytes + // (we correct pos. in loop below) + "avg_2lp: \n\t" + "movq (%%edi,%%ecx,), %%mm0 \n\t" + "psrlq _ShiftRem, %%mm2 \n\t" // shift data to pos. correctly + "movq (%%esi,%%ecx,), %%mm1 \n\t" // (GRR BUGFIX: was psllq) + // add (Prev_row/2) to average + "movq %%mm5, %%mm3 \n\t" + "pand %%mm1, %%mm3 \n\t" // get lsb for each prev_row byte + "psrlq $1, %%mm1 \n\t" // divide prev_row bytes by 2 + "pand %%mm4, %%mm1 \n\t" // clear invalid bit 7 of each + // byte + "movq %%mm7, %%mm6 \n\t" + "paddb %%mm1, %%mm0 \n\t" // add (Prev_row/2) to Avg for + // each byte + + // add 1st active group (Raw(x-bpp)/2) to average with _LBCarry + "movq %%mm3, %%mm1 \n\t" // now use mm1 for getting + // LBCarrys + "pand %%mm2, %%mm1 \n\t" // get LBCarrys for each byte + // where both + // lsb's were == 1 (only valid + // for active group) + "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2 + "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7 of each + // byte + "paddb %%mm1, %%mm2 \n\t" // add LBCarrys to (Raw(x-bpp)/2) + // for each byte + "pand %%mm6, %%mm2 \n\t" // leave only Active Group 1 + // bytes to add to Avg + "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) + LBCarrys to Avg + // for each Active byte + + // add 2nd active group (Raw(x-bpp)/2) to average with _LBCarry + "psllq _ShiftBpp, %%mm6 \n\t" // shift the mm6 mask to cover + // bytes 2 & 3 + "movq %%mm0, %%mm2 \n\t" // mov updated Raws to mm2 + "psllq _ShiftBpp, %%mm2 \n\t" // shift data to pos. correctly + "movq %%mm3, %%mm1 \n\t" // now use mm1 for getting + // LBCarrys + "pand %%mm2, %%mm1 \n\t" // get LBCarrys for each byte + // where both + // lsb's were == 1 (only valid + // for active group) + "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2 + "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7 of each + // byte + "paddb %%mm1, %%mm2 \n\t" // add LBCarrys to (Raw(x-bpp)/2) + // for each byte + "pand %%mm6, %%mm2 \n\t" // leave only Active Group 2 + // bytes to add to Avg + "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) + LBCarrys to + // Avg for each Active byte + + // add 3rd active group (Raw(x-bpp)/2) to average with _LBCarry + "psllq _ShiftBpp, %%mm6 \n\t" // shift the mm6 mask to cover + // bytes 4 & 5 + "movq %%mm0, %%mm2 \n\t" // mov updated Raws to mm2 + "psllq _ShiftBpp, %%mm2 \n\t" // shift data to pos. correctly + "movq %%mm3, %%mm1 \n\t" // now use mm1 for getting + // LBCarrys + "pand %%mm2, %%mm1 \n\t" // get LBCarrys for each byte + // where both lsb's were == 1 + // (only valid for active group) + "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2 + "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7 of each + // byte + "paddb %%mm1, %%mm2 \n\t" // add LBCarrys to (Raw(x-bpp)/2) + // for each byte + "pand %%mm6, %%mm2 \n\t" // leave only Active Group 2 + // bytes to add to Avg + "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) + LBCarrys to + // Avg for each Active byte + + // add 4th active group (Raw(x-bpp)/2) to average with _LBCarry + "psllq _ShiftBpp, %%mm6 \n\t" // shift the mm6 mask to cover + // bytes 6 & 7 + "movq %%mm0, %%mm2 \n\t" // mov updated Raws to mm2 + "psllq _ShiftBpp, %%mm2 \n\t" // shift data to pos. correctly + "addl $8, %%ecx \n\t" + "movq %%mm3, %%mm1 \n\t" // now use mm1 for getting + // LBCarrys + "pand %%mm2, %%mm1 \n\t" // get LBCarrys for each byte + // where both + // lsb's were == 1 (only valid + // for active group) + "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2 + "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7 of each + // byte + "paddb %%mm1, %%mm2 \n\t" // add LBCarrys to (Raw(x-bpp)/2) + // for each byte + "pand %%mm6, %%mm2 \n\t" // leave only Active Group 2 + // bytes to add to Avg + "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) + LBCarrys to + // Avg for each Active byte + + "cmpl _MMXLength, %%ecx \n\t" + // now ready to write back to memory + "movq %%mm0, -8(%%edi,%%ecx,) \n\t" + // prep Raw(x-bpp) for next loop + "movq %%mm0, %%mm2 \n\t" // mov updated Raws to mm2 + "jb avg_2lp \n\t" + + : "=S" (dummy_value_S), // output regs (dummy) + "=D" (dummy_value_D) + + : "0" (prev_row), // esi // input regs + "1" (row) // edi + + : "%ecx" // clobber list +#if 0 /* %mm0, ..., %mm7 not supported by gcc 2.7.2.3 or egcs 1.1 */ + , "%mm0", "%mm1", "%mm2", "%mm3" + , "%mm4", "%mm5", "%mm6", "%mm7" +#endif + ); + } + break; // end 2 bpp + + case 1: + { + __asm__ __volatile__ ( + // re-init address pointers and offset +#ifdef __PIC__ + "pushl %%ebx \n\t" // save Global Offset Table index +#endif + "movl _dif, %%ebx \n\t" // ebx: x = offset to alignment + // boundary +// preload "movl row, %%edi \n\t" // edi: Avg(x) + "cmpl _FullLength, %%ebx \n\t" // test if offset at end of array + "jnb avg_1end \n\t" + // do Paeth decode for remaining bytes +// preload "movl prev_row, %%esi \n\t" // esi: Prior(x) + "movl %%edi, %%edx \n\t" +// preload "subl bpp, %%edx \n\t" // (bpp is preloaded into ecx) + "subl %%ecx, %%edx \n\t" // edx: Raw(x-bpp) + "xorl %%ecx, %%ecx \n\t" // zero ecx before using cl & cx + // in loop below + "avg_1lp: \n\t" + // Raw(x) = Avg(x) + ((Raw(x-bpp) + Prior(x))/2) + "xorl %%eax, %%eax \n\t" + "movb (%%esi,%%ebx,), %%cl \n\t" // load cl with Prior(x) + "movb (%%edx,%%ebx,), %%al \n\t" // load al with Raw(x-bpp) + "addw %%cx, %%ax \n\t" + "incl %%ebx \n\t" + "shrw %%ax \n\t" // divide by 2 + "addb -1(%%edi,%%ebx,), %%al \n\t" // add Avg(x); -1 to offset + // inc ebx + "cmpl _FullLength, %%ebx \n\t" // check if at end of array + "movb %%al, -1(%%edi,%%ebx,) \n\t" // write back Raw(x); + // mov does not affect flags; -1 to offset inc ebx + "jb avg_1lp \n\t" + + "avg_1end: \n\t" +#ifdef __PIC__ + "popl %%ebx \n\t" // Global Offset Table index +#endif + + : "=c" (dummy_value_c), // output regs (dummy) + "=S" (dummy_value_S), + "=D" (dummy_value_D) + + : "0" (bpp), // ecx // input regs + "1" (prev_row), // esi + "2" (row) // edi + + : "%eax", "%edx" // clobber list +#ifndef __PIC__ + , "%ebx" +#endif + ); + } + return; // end 1 bpp + + case 8: + { + __asm__ __volatile__ ( + // re-init address pointers and offset + "movl _dif, %%ecx \n\t" // ecx: x == offset to alignment + "movq _LBCarryMask, %%mm5 \n\t" // boundary +// preload "movl row, %%edi \n\t" // edi: Avg(x) + "movq _HBClearMask, %%mm4 \n\t" +// preload "movl prev_row, %%esi \n\t" // esi: Prior(x) + + // prime the pump: load the first Raw(x-bpp) data set + "movq -8(%%edi,%%ecx,), %%mm2 \n\t" // load previous aligned 8 bytes + // (NO NEED to correct pos. in loop below) + + "avg_8lp: \n\t" + "movq (%%edi,%%ecx,), %%mm0 \n\t" + "movq %%mm5, %%mm3 \n\t" + "movq (%%esi,%%ecx,), %%mm1 \n\t" + "addl $8, %%ecx \n\t" + "pand %%mm1, %%mm3 \n\t" // get lsb for each prev_row byte + "psrlq $1, %%mm1 \n\t" // divide prev_row bytes by 2 + "pand %%mm2, %%mm3 \n\t" // get LBCarrys for each byte + // where both lsb's were == 1 + "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2 + "pand %%mm4, %%mm1 \n\t" // clear invalid bit 7, each byte + "paddb %%mm3, %%mm0 \n\t" // add LBCarrys to Avg, each byte + "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7, each byte + "paddb %%mm1, %%mm0 \n\t" // add (Prev_row/2) to Avg, each + "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) to Avg for each + "cmpl _MMXLength, %%ecx \n\t" + "movq %%mm0, -8(%%edi,%%ecx,) \n\t" + "movq %%mm0, %%mm2 \n\t" // reuse as Raw(x-bpp) + "jb avg_8lp \n\t" + + : "=S" (dummy_value_S), // output regs (dummy) + "=D" (dummy_value_D) + + : "0" (prev_row), // esi // input regs + "1" (row) // edi + + : "%ecx" // clobber list +#if 0 /* %mm0, ..., %mm5 not supported by gcc 2.7.2.3 or egcs 1.1 */ + , "%mm0", "%mm1", "%mm2" + , "%mm3", "%mm4", "%mm5" +#endif + ); + } + break; // end 8 bpp + + default: // bpp greater than 8 (!= 1,2,3,4,[5],6,[7],8) + { + +#ifdef PNG_DEBUG + // GRR: PRINT ERROR HERE: SHOULD NEVER BE REACHED + png_debug(1, + "Internal logic error in pnggccrd (png_read_filter_row_mmx_avg())\n"); +#endif + +#if 0 + __asm__ __volatile__ ( + "movq _LBCarryMask, %%mm5 \n\t" + // re-init address pointers and offset + "movl _dif, %%ebx \n\t" // ebx: x = offset to + // alignment boundary + "movl row, %%edi \n\t" // edi: Avg(x) + "movq _HBClearMask, %%mm4 \n\t" + "movl %%edi, %%edx \n\t" + "movl prev_row, %%esi \n\t" // esi: Prior(x) + "subl bpp, %%edx \n\t" // edx: Raw(x-bpp) + "avg_Alp: \n\t" + "movq (%%edi,%%ebx,), %%mm0 \n\t" + "movq %%mm5, %%mm3 \n\t" + "movq (%%esi,%%ebx,), %%mm1 \n\t" + "pand %%mm1, %%mm3 \n\t" // get lsb for each prev_row byte + "movq (%%edx,%%ebx,), %%mm2 \n\t" + "psrlq $1, %%mm1 \n\t" // divide prev_row bytes by 2 + "pand %%mm2, %%mm3 \n\t" // get LBCarrys for each byte + // where both lsb's were == 1 + "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2 + "pand %%mm4, %%mm1 \n\t" // clear invalid bit 7 of each + // byte + "paddb %%mm3, %%mm0 \n\t" // add LBCarrys to Avg for each + // byte + "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7 of each + // byte + "paddb %%mm1, %%mm0 \n\t" // add (Prev_row/2) to Avg for + // each byte + "addl $8, %%ebx \n\t" + "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) to Avg for each + // byte + "cmpl _MMXLength, %%ebx \n\t" + "movq %%mm0, -8(%%edi,%%ebx,) \n\t" + "jb avg_Alp \n\t" + + : // FIXASM: output regs/vars go here, e.g.: "=m" (memory_var) + + : // FIXASM: input regs, e.g.: "c" (count), "S" (src), "D" (dest) + + : "%ebx", "%edx", "%edi", "%esi" // CHECKASM: clobber list + ); +#endif /* 0 - NEVER REACHED */ + } + break; + + } // end switch (bpp) + + __asm__ __volatile__ ( + // MMX acceleration complete; now do clean-up + // check if any remaining bytes left to decode +#ifdef __PIC__ + "pushl %%ebx \n\t" // save index to Global Offset Table +#endif + "movl _MMXLength, %%ebx \n\t" // ebx: x == offset bytes after MMX +//pre "movl row, %%edi \n\t" // edi: Avg(x) + "cmpl _FullLength, %%ebx \n\t" // test if offset at end of array + "jnb avg_end \n\t" + + // do Avg decode for remaining bytes +//pre "movl prev_row, %%esi \n\t" // esi: Prior(x) + "movl %%edi, %%edx \n\t" +//pre "subl bpp, %%edx \n\t" // (bpp is preloaded into ecx) + "subl %%ecx, %%edx \n\t" // edx: Raw(x-bpp) + "xorl %%ecx, %%ecx \n\t" // zero ecx before using cl & cx below + + "avg_lp2: \n\t" + // Raw(x) = Avg(x) + ((Raw(x-bpp) + Prior(x))/2) + "xorl %%eax, %%eax \n\t" + "movb (%%esi,%%ebx,), %%cl \n\t" // load cl with Prior(x) + "movb (%%edx,%%ebx,), %%al \n\t" // load al with Raw(x-bpp) + "addw %%cx, %%ax \n\t" + "incl %%ebx \n\t" + "shrw %%ax \n\t" // divide by 2 + "addb -1(%%edi,%%ebx,), %%al \n\t" // add Avg(x); -1 to offset inc ebx + "cmpl _FullLength, %%ebx \n\t" // check if at end of array + "movb %%al, -1(%%edi,%%ebx,) \n\t" // write back Raw(x) [mov does not + "jb avg_lp2 \n\t" // affect flags; -1 to offset inc ebx] + + "avg_end: \n\t" + "EMMS \n\t" // end MMX; prep for poss. FP instrs. +#ifdef __PIC__ + "popl %%ebx \n\t" // restore index to Global Offset Table +#endif + + : "=c" (dummy_value_c), // output regs (dummy) + "=S" (dummy_value_S), + "=D" (dummy_value_D) + + : "0" (bpp), // ecx // input regs + "1" (prev_row), // esi + "2" (row) // edi + + : "%eax", "%edx" // clobber list +#ifndef __PIC__ + , "%ebx" +#endif + ); + +} /* end png_read_filter_row_mmx_avg() */ +#endif + + + +#ifdef PNG_THREAD_UNSAFE_OK +//===========================================================================// +// // +// P N G _ R E A D _ F I L T E R _ R O W _ M M X _ P A E T H // +// // +//===========================================================================// + +// Optimized code for PNG Paeth filter decoder + +static void /* PRIVATE */ +png_read_filter_row_mmx_paeth(png_row_infop row_info, png_bytep row, + png_bytep prev_row) +{ + int bpp; + int dummy_value_c; // fix 'forbidden register 2 (cx) was spilled' error + int dummy_value_S; + int dummy_value_D; + + bpp = (row_info->pixel_depth + 7) >> 3; // Get # bytes per pixel + _FullLength = row_info->rowbytes; // # of bytes to filter + + __asm__ __volatile__ ( +#ifdef __PIC__ + "pushl %%ebx \n\t" // save index to Global Offset Table +#endif + "xorl %%ebx, %%ebx \n\t" // ebx: x offset +//pre "movl row, %%edi \n\t" + "xorl %%edx, %%edx \n\t" // edx: x-bpp offset +//pre "movl prev_row, %%esi \n\t" + "xorl %%eax, %%eax \n\t" + + // Compute the Raw value for the first bpp bytes + // Note: the formula works out to be always + // Paeth(x) = Raw(x) + Prior(x) where x < bpp + "paeth_rlp: \n\t" + "movb (%%edi,%%ebx,), %%al \n\t" + "addb (%%esi,%%ebx,), %%al \n\t" + "incl %%ebx \n\t" +//pre "cmpl bpp, %%ebx \n\t" (bpp is preloaded into ecx) + "cmpl %%ecx, %%ebx \n\t" + "movb %%al, -1(%%edi,%%ebx,) \n\t" + "jb paeth_rlp \n\t" + // get # of bytes to alignment + "movl %%edi, _dif \n\t" // take start of row + "addl %%ebx, _dif \n\t" // add bpp + "xorl %%ecx, %%ecx \n\t" + "addl $0xf, _dif \n\t" // add 7 + 8 to incr past alignment + // boundary + "andl $0xfffffff8, _dif \n\t" // mask to alignment boundary + "subl %%edi, _dif \n\t" // subtract from start ==> value ebx + // at alignment + "jz paeth_go \n\t" + // fix alignment + + "paeth_lp1: \n\t" + "xorl %%eax, %%eax \n\t" + // pav = p - a = (a + b - c) - a = b - c + "movb (%%esi,%%ebx,), %%al \n\t" // load Prior(x) into al + "movb (%%esi,%%edx,), %%cl \n\t" // load Prior(x-bpp) into cl + "subl %%ecx, %%eax \n\t" // subtract Prior(x-bpp) + "movl %%eax, _patemp \n\t" // Save pav for later use + "xorl %%eax, %%eax \n\t" + // pbv = p - b = (a + b - c) - b = a - c + "movb (%%edi,%%edx,), %%al \n\t" // load Raw(x-bpp) into al + "subl %%ecx, %%eax \n\t" // subtract Prior(x-bpp) + "movl %%eax, %%ecx \n\t" + // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv + "addl _patemp, %%eax \n\t" // pcv = pav + pbv + // pc = abs(pcv) + "testl $0x80000000, %%eax \n\t" + "jz paeth_pca \n\t" + "negl %%eax \n\t" // reverse sign of neg values + + "paeth_pca: \n\t" + "movl %%eax, _pctemp \n\t" // save pc for later use + // pb = abs(pbv) + "testl $0x80000000, %%ecx \n\t" + "jz paeth_pba \n\t" + "negl %%ecx \n\t" // reverse sign of neg values + + "paeth_pba: \n\t" + "movl %%ecx, _pbtemp \n\t" // save pb for later use + // pa = abs(pav) + "movl _patemp, %%eax \n\t" + "testl $0x80000000, %%eax \n\t" + "jz paeth_paa \n\t" + "negl %%eax \n\t" // reverse sign of neg values + + "paeth_paa: \n\t" + "movl %%eax, _patemp \n\t" // save pa for later use + // test if pa <= pb + "cmpl %%ecx, %%eax \n\t" + "jna paeth_abb \n\t" + // pa > pb; now test if pb <= pc + "cmpl _pctemp, %%ecx \n\t" + "jna paeth_bbc \n\t" + // pb > pc; Raw(x) = Paeth(x) + Prior(x-bpp) + "movb (%%esi,%%edx,), %%cl \n\t" // load Prior(x-bpp) into cl + "jmp paeth_paeth \n\t" + + "paeth_bbc: \n\t" + // pb <= pc; Raw(x) = Paeth(x) + Prior(x) + "movb (%%esi,%%ebx,), %%cl \n\t" // load Prior(x) into cl + "jmp paeth_paeth \n\t" + + "paeth_abb: \n\t" + // pa <= pb; now test if pa <= pc + "cmpl _pctemp, %%eax \n\t" + "jna paeth_abc \n\t" + // pa > pc; Raw(x) = Paeth(x) + Prior(x-bpp) + "movb (%%esi,%%edx,), %%cl \n\t" // load Prior(x-bpp) into cl + "jmp paeth_paeth \n\t" + + "paeth_abc: \n\t" + // pa <= pc; Raw(x) = Paeth(x) + Raw(x-bpp) + "movb (%%edi,%%edx,), %%cl \n\t" // load Raw(x-bpp) into cl + + "paeth_paeth: \n\t" + "incl %%ebx \n\t" + "incl %%edx \n\t" + // Raw(x) = (Paeth(x) + Paeth_Predictor( a, b, c )) mod 256 + "addb %%cl, -1(%%edi,%%ebx,) \n\t" + "cmpl _dif, %%ebx \n\t" + "jb paeth_lp1 \n\t" + + "paeth_go: \n\t" + "movl _FullLength, %%ecx \n\t" + "movl %%ecx, %%eax \n\t" + "subl %%ebx, %%eax \n\t" // subtract alignment fix + "andl $0x00000007, %%eax \n\t" // calc bytes over mult of 8 + "subl %%eax, %%ecx \n\t" // drop over bytes from original length + "movl %%ecx, _MMXLength \n\t" +#ifdef __PIC__ + "popl %%ebx \n\t" // restore index to Global Offset Table +#endif + + : "=c" (dummy_value_c), // output regs (dummy) + "=S" (dummy_value_S), + "=D" (dummy_value_D) + + : "0" (bpp), // ecx // input regs + "1" (prev_row), // esi + "2" (row) // edi + + : "%eax", "%edx" // clobber list +#ifndef __PIC__ + , "%ebx" +#endif + ); + + // now do the math for the rest of the row + switch (bpp) + { + case 3: + { + _ActiveMask.use = 0x0000000000ffffffLL; + _ActiveMaskEnd.use = 0xffff000000000000LL; + _ShiftBpp.use = 24; // == bpp(3) * 8 + _ShiftRem.use = 40; // == 64 - 24 + + __asm__ __volatile__ ( + "movl _dif, %%ecx \n\t" +// preload "movl row, %%edi \n\t" +// preload "movl prev_row, %%esi \n\t" + "pxor %%mm0, %%mm0 \n\t" + // prime the pump: load the first Raw(x-bpp) data set + "movq -8(%%edi,%%ecx,), %%mm1 \n\t" + "paeth_3lp: \n\t" + "psrlq _ShiftRem, %%mm1 \n\t" // shift last 3 bytes to 1st + // 3 bytes + "movq (%%esi,%%ecx,), %%mm2 \n\t" // load b=Prior(x) + "punpcklbw %%mm0, %%mm1 \n\t" // unpack High bytes of a + "movq -8(%%esi,%%ecx,), %%mm3 \n\t" // prep c=Prior(x-bpp) bytes + "punpcklbw %%mm0, %%mm2 \n\t" // unpack High bytes of b + "psrlq _ShiftRem, %%mm3 \n\t" // shift last 3 bytes to 1st + // 3 bytes + // pav = p - a = (a + b - c) - a = b - c + "movq %%mm2, %%mm4 \n\t" + "punpcklbw %%mm0, %%mm3 \n\t" // unpack High bytes of c + // pbv = p - b = (a + b - c) - b = a - c + "movq %%mm1, %%mm5 \n\t" + "psubw %%mm3, %%mm4 \n\t" + "pxor %%mm7, %%mm7 \n\t" + // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv + "movq %%mm4, %%mm6 \n\t" + "psubw %%mm3, %%mm5 \n\t" + + // pa = abs(p-a) = abs(pav) + // pb = abs(p-b) = abs(pbv) + // pc = abs(p-c) = abs(pcv) + "pcmpgtw %%mm4, %%mm0 \n\t" // create mask pav bytes < 0 + "paddw %%mm5, %%mm6 \n\t" + "pand %%mm4, %%mm0 \n\t" // only pav bytes < 0 in mm7 + "pcmpgtw %%mm5, %%mm7 \n\t" // create mask pbv bytes < 0 + "psubw %%mm0, %%mm4 \n\t" + "pand %%mm5, %%mm7 \n\t" // only pbv bytes < 0 in mm0 + "psubw %%mm0, %%mm4 \n\t" + "psubw %%mm7, %%mm5 \n\t" + "pxor %%mm0, %%mm0 \n\t" + "pcmpgtw %%mm6, %%mm0 \n\t" // create mask pcv bytes < 0 + "pand %%mm6, %%mm0 \n\t" // only pav bytes < 0 in mm7 + "psubw %%mm7, %%mm5 \n\t" + "psubw %%mm0, %%mm6 \n\t" + // test pa <= pb + "movq %%mm4, %%mm7 \n\t" + "psubw %%mm0, %%mm6 \n\t" + "pcmpgtw %%mm5, %%mm7 \n\t" // pa > pb? + "movq %%mm7, %%mm0 \n\t" + // use mm7 mask to merge pa & pb + "pand %%mm7, %%mm5 \n\t" + // use mm0 mask copy to merge a & b + "pand %%mm0, %%mm2 \n\t" + "pandn %%mm4, %%mm7 \n\t" + "pandn %%mm1, %%mm0 \n\t" + "paddw %%mm5, %%mm7 \n\t" + "paddw %%mm2, %%mm0 \n\t" + // test ((pa <= pb)? pa:pb) <= pc + "pcmpgtw %%mm6, %%mm7 \n\t" // pab > pc? + "pxor %%mm1, %%mm1 \n\t" + "pand %%mm7, %%mm3 \n\t" + "pandn %%mm0, %%mm7 \n\t" + "paddw %%mm3, %%mm7 \n\t" + "pxor %%mm0, %%mm0 \n\t" + "packuswb %%mm1, %%mm7 \n\t" + "movq (%%esi,%%ecx,), %%mm3 \n\t" // load c=Prior(x-bpp) + "pand _ActiveMask, %%mm7 \n\t" + "movq %%mm3, %%mm2 \n\t" // load b=Prior(x) step 1 + "paddb (%%edi,%%ecx,), %%mm7 \n\t" // add Paeth predictor with Raw(x) + "punpcklbw %%mm0, %%mm3 \n\t" // unpack High bytes of c + "movq %%mm7, (%%edi,%%ecx,) \n\t" // write back updated value + "movq %%mm7, %%mm1 \n\t" // now mm1 will be used as + // Raw(x-bpp) + // now do Paeth for 2nd set of bytes (3-5) + "psrlq _ShiftBpp, %%mm2 \n\t" // load b=Prior(x) step 2 + "punpcklbw %%mm0, %%mm1 \n\t" // unpack High bytes of a + "pxor %%mm7, %%mm7 \n\t" + "punpcklbw %%mm0, %%mm2 \n\t" // unpack High bytes of b + // pbv = p - b = (a + b - c) - b = a - c + "movq %%mm1, %%mm5 \n\t" + // pav = p - a = (a + b - c) - a = b - c + "movq %%mm2, %%mm4 \n\t" + "psubw %%mm3, %%mm5 \n\t" + "psubw %%mm3, %%mm4 \n\t" + // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = + // pav + pbv = pbv + pav + "movq %%mm5, %%mm6 \n\t" + "paddw %%mm4, %%mm6 \n\t" + + // pa = abs(p-a) = abs(pav) + // pb = abs(p-b) = abs(pbv) + // pc = abs(p-c) = abs(pcv) + "pcmpgtw %%mm5, %%mm0 \n\t" // create mask pbv bytes < 0 + "pcmpgtw %%mm4, %%mm7 \n\t" // create mask pav bytes < 0 + "pand %%mm5, %%mm0 \n\t" // only pbv bytes < 0 in mm0 + "pand %%mm4, %%mm7 \n\t" // only pav bytes < 0 in mm7 + "psubw %%mm0, %%mm5 \n\t" + "psubw %%mm7, %%mm4 \n\t" + "psubw %%mm0, %%mm5 \n\t" + "psubw %%mm7, %%mm4 \n\t" + "pxor %%mm0, %%mm0 \n\t" + "pcmpgtw %%mm6, %%mm0 \n\t" // create mask pcv bytes < 0 + "pand %%mm6, %%mm0 \n\t" // only pav bytes < 0 in mm7 + "psubw %%mm0, %%mm6 \n\t" + // test pa <= pb + "movq %%mm4, %%mm7 \n\t" + "psubw %%mm0, %%mm6 \n\t" + "pcmpgtw %%mm5, %%mm7 \n\t" // pa > pb? + "movq %%mm7, %%mm0 \n\t" + // use mm7 mask to merge pa & pb + "pand %%mm7, %%mm5 \n\t" + // use mm0 mask copy to merge a & b + "pand %%mm0, %%mm2 \n\t" + "pandn %%mm4, %%mm7 \n\t" + "pandn %%mm1, %%mm0 \n\t" + "paddw %%mm5, %%mm7 \n\t" + "paddw %%mm2, %%mm0 \n\t" + // test ((pa <= pb)? pa:pb) <= pc + "pcmpgtw %%mm6, %%mm7 \n\t" // pab > pc? + "movq (%%esi,%%ecx,), %%mm2 \n\t" // load b=Prior(x) + "pand %%mm7, %%mm3 \n\t" + "pandn %%mm0, %%mm7 \n\t" + "pxor %%mm1, %%mm1 \n\t" + "paddw %%mm3, %%mm7 \n\t" + "pxor %%mm0, %%mm0 \n\t" + "packuswb %%mm1, %%mm7 \n\t" + "movq %%mm2, %%mm3 \n\t" // load c=Prior(x-bpp) step 1 + "pand _ActiveMask, %%mm7 \n\t" + "punpckhbw %%mm0, %%mm2 \n\t" // unpack High bytes of b + "psllq _ShiftBpp, %%mm7 \n\t" // shift bytes to 2nd group of + // 3 bytes + // pav = p - a = (a + b - c) - a = b - c + "movq %%mm2, %%mm4 \n\t" + "paddb (%%edi,%%ecx,), %%mm7 \n\t" // add Paeth predictor with Raw(x) + "psllq _ShiftBpp, %%mm3 \n\t" // load c=Prior(x-bpp) step 2 + "movq %%mm7, (%%edi,%%ecx,) \n\t" // write back updated value + "movq %%mm7, %%mm1 \n\t" + "punpckhbw %%mm0, %%mm3 \n\t" // unpack High bytes of c + "psllq _ShiftBpp, %%mm1 \n\t" // shift bytes + // now mm1 will be used as Raw(x-bpp) + // now do Paeth for 3rd, and final, set of bytes (6-7) + "pxor %%mm7, %%mm7 \n\t" + "punpckhbw %%mm0, %%mm1 \n\t" // unpack High bytes of a + "psubw %%mm3, %%mm4 \n\t" + // pbv = p - b = (a + b - c) - b = a - c + "movq %%mm1, %%mm5 \n\t" + // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv + "movq %%mm4, %%mm6 \n\t" + "psubw %%mm3, %%mm5 \n\t" + "pxor %%mm0, %%mm0 \n\t" + "paddw %%mm5, %%mm6 \n\t" + + // pa = abs(p-a) = abs(pav) + // pb = abs(p-b) = abs(pbv) + // pc = abs(p-c) = abs(pcv) + "pcmpgtw %%mm4, %%mm0 \n\t" // create mask pav bytes < 0 + "pcmpgtw %%mm5, %%mm7 \n\t" // create mask pbv bytes < 0 + "pand %%mm4, %%mm0 \n\t" // only pav bytes < 0 in mm7 + "pand %%mm5, %%mm7 \n\t" // only pbv bytes < 0 in mm0 + "psubw %%mm0, %%mm4 \n\t" + "psubw %%mm7, %%mm5 \n\t" + "psubw %%mm0, %%mm4 \n\t" + "psubw %%mm7, %%mm5 \n\t" + "pxor %%mm0, %%mm0 \n\t" + "pcmpgtw %%mm6, %%mm0 \n\t" // create mask pcv bytes < 0 + "pand %%mm6, %%mm0 \n\t" // only pav bytes < 0 in mm7 + "psubw %%mm0, %%mm6 \n\t" + // test pa <= pb + "movq %%mm4, %%mm7 \n\t" + "psubw %%mm0, %%mm6 \n\t" + "pcmpgtw %%mm5, %%mm7 \n\t" // pa > pb? + "movq %%mm7, %%mm0 \n\t" + // use mm0 mask copy to merge a & b + "pand %%mm0, %%mm2 \n\t" + // use mm7 mask to merge pa & pb + "pand %%mm7, %%mm5 \n\t" + "pandn %%mm1, %%mm0 \n\t" + "pandn %%mm4, %%mm7 \n\t" + "paddw %%mm2, %%mm0 \n\t" + "paddw %%mm5, %%mm7 \n\t" + // test ((pa <= pb)? pa:pb) <= pc + "pcmpgtw %%mm6, %%mm7 \n\t" // pab > pc? + "pand %%mm7, %%mm3 \n\t" + "pandn %%mm0, %%mm7 \n\t" + "paddw %%mm3, %%mm7 \n\t" + "pxor %%mm1, %%mm1 \n\t" + "packuswb %%mm7, %%mm1 \n\t" + // step ecx to next set of 8 bytes and repeat loop til done + "addl $8, %%ecx \n\t" + "pand _ActiveMaskEnd, %%mm1 \n\t" + "paddb -8(%%edi,%%ecx,), %%mm1 \n\t" // add Paeth predictor with + // Raw(x) + + "cmpl _MMXLength, %%ecx \n\t" + "pxor %%mm0, %%mm0 \n\t" // pxor does not affect flags + "movq %%mm1, -8(%%edi,%%ecx,) \n\t" // write back updated value + // mm1 will be used as Raw(x-bpp) next loop + // mm3 ready to be used as Prior(x-bpp) next loop + "jb paeth_3lp \n\t" + + : "=S" (dummy_value_S), // output regs (dummy) + "=D" (dummy_value_D) + + : "0" (prev_row), // esi // input regs + "1" (row) // edi + + : "%ecx" // clobber list +#if 0 /* %mm0, ..., %mm7 not supported by gcc 2.7.2.3 or egcs 1.1 */ + , "%mm0", "%mm1", "%mm2", "%mm3" + , "%mm4", "%mm5", "%mm6", "%mm7" +#endif + ); + } + break; // end 3 bpp + + case 6: + //case 7: // GRR BOGUS + //case 5: // GRR BOGUS + { + _ActiveMask.use = 0x00000000ffffffffLL; + _ActiveMask2.use = 0xffffffff00000000LL; + _ShiftBpp.use = bpp << 3; // == bpp * 8 + _ShiftRem.use = 64 - _ShiftBpp.use; + + __asm__ __volatile__ ( + "movl _dif, %%ecx \n\t" +// preload "movl row, %%edi \n\t" +// preload "movl prev_row, %%esi \n\t" + // prime the pump: load the first Raw(x-bpp) data set + "movq -8(%%edi,%%ecx,), %%mm1 \n\t" + "pxor %%mm0, %%mm0 \n\t" + + "paeth_6lp: \n\t" + // must shift to position Raw(x-bpp) data + "psrlq _ShiftRem, %%mm1 \n\t" + // do first set of 4 bytes + "movq -8(%%esi,%%ecx,), %%mm3 \n\t" // read c=Prior(x-bpp) bytes + "punpcklbw %%mm0, %%mm1 \n\t" // unpack Low bytes of a + "movq (%%esi,%%ecx,), %%mm2 \n\t" // load b=Prior(x) + "punpcklbw %%mm0, %%mm2 \n\t" // unpack Low bytes of b + // must shift to position Prior(x-bpp) data + "psrlq _ShiftRem, %%mm3 \n\t" + // pav = p - a = (a + b - c) - a = b - c + "movq %%mm2, %%mm4 \n\t" + "punpcklbw %%mm0, %%mm3 \n\t" // unpack Low bytes of c + // pbv = p - b = (a + b - c) - b = a - c + "movq %%mm1, %%mm5 \n\t" + "psubw %%mm3, %%mm4 \n\t" + "pxor %%mm7, %%mm7 \n\t" + // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv + "movq %%mm4, %%mm6 \n\t" + "psubw %%mm3, %%mm5 \n\t" + // pa = abs(p-a) = abs(pav) + // pb = abs(p-b) = abs(pbv) + // pc = abs(p-c) = abs(pcv) + "pcmpgtw %%mm4, %%mm0 \n\t" // create mask pav bytes < 0 + "paddw %%mm5, %%mm6 \n\t" + "pand %%mm4, %%mm0 \n\t" // only pav bytes < 0 in mm7 + "pcmpgtw %%mm5, %%mm7 \n\t" // create mask pbv bytes < 0 + "psubw %%mm0, %%mm4 \n\t" + "pand %%mm5, %%mm7 \n\t" // only pbv bytes < 0 in mm0 + "psubw %%mm0, %%mm4 \n\t" + "psubw %%mm7, %%mm5 \n\t" + "pxor %%mm0, %%mm0 \n\t" + "pcmpgtw %%mm6, %%mm0 \n\t" // create mask pcv bytes < 0 + "pand %%mm6, %%mm0 \n\t" // only pav bytes < 0 in mm7 + "psubw %%mm7, %%mm5 \n\t" + "psubw %%mm0, %%mm6 \n\t" + // test pa <= pb + "movq %%mm4, %%mm7 \n\t" + "psubw %%mm0, %%mm6 \n\t" + "pcmpgtw %%mm5, %%mm7 \n\t" // pa > pb? + "movq %%mm7, %%mm0 \n\t" + // use mm7 mask to merge pa & pb + "pand %%mm7, %%mm5 \n\t" + // use mm0 mask copy to merge a & b + "pand %%mm0, %%mm2 \n\t" + "pandn %%mm4, %%mm7 \n\t" + "pandn %%mm1, %%mm0 \n\t" + "paddw %%mm5, %%mm7 \n\t" + "paddw %%mm2, %%mm0 \n\t" + // test ((pa <= pb)? pa:pb) <= pc + "pcmpgtw %%mm6, %%mm7 \n\t" // pab > pc? + "pxor %%mm1, %%mm1 \n\t" + "pand %%mm7, %%mm3 \n\t" + "pandn %%mm0, %%mm7 \n\t" + "paddw %%mm3, %%mm7 \n\t" + "pxor %%mm0, %%mm0 \n\t" + "packuswb %%mm1, %%mm7 \n\t" + "movq -8(%%esi,%%ecx,), %%mm3 \n\t" // load c=Prior(x-bpp) + "pand _ActiveMask, %%mm7 \n\t" + "psrlq _ShiftRem, %%mm3 \n\t" + "movq (%%esi,%%ecx,), %%mm2 \n\t" // load b=Prior(x) step 1 + "paddb (%%edi,%%ecx,), %%mm7 \n\t" // add Paeth predictor and Raw(x) + "movq %%mm2, %%mm6 \n\t" + "movq %%mm7, (%%edi,%%ecx,) \n\t" // write back updated value + "movq -8(%%edi,%%ecx,), %%mm1 \n\t" + "psllq _ShiftBpp, %%mm6 \n\t" + "movq %%mm7, %%mm5 \n\t" + "psrlq _ShiftRem, %%mm1 \n\t" + "por %%mm6, %%mm3 \n\t" + "psllq _ShiftBpp, %%mm5 \n\t" + "punpckhbw %%mm0, %%mm3 \n\t" // unpack High bytes of c + "por %%mm5, %%mm1 \n\t" + // do second set of 4 bytes + "punpckhbw %%mm0, %%mm2 \n\t" // unpack High bytes of b + "punpckhbw %%mm0, %%mm1 \n\t" // unpack High bytes of a + // pav = p - a = (a + b - c) - a = b - c + "movq %%mm2, %%mm4 \n\t" + // pbv = p - b = (a + b - c) - b = a - c + "movq %%mm1, %%mm5 \n\t" + "psubw %%mm3, %%mm4 \n\t" + "pxor %%mm7, %%mm7 \n\t" + // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv + "movq %%mm4, %%mm6 \n\t" + "psubw %%mm3, %%mm5 \n\t" + // pa = abs(p-a) = abs(pav) + // pb = abs(p-b) = abs(pbv) + // pc = abs(p-c) = abs(pcv) + "pcmpgtw %%mm4, %%mm0 \n\t" // create mask pav bytes < 0 + "paddw %%mm5, %%mm6 \n\t" + "pand %%mm4, %%mm0 \n\t" // only pav bytes < 0 in mm7 + "pcmpgtw %%mm5, %%mm7 \n\t" // create mask pbv bytes < 0 + "psubw %%mm0, %%mm4 \n\t" + "pand %%mm5, %%mm7 \n\t" // only pbv bytes < 0 in mm0 + "psubw %%mm0, %%mm4 \n\t" + "psubw %%mm7, %%mm5 \n\t" + "pxor %%mm0, %%mm0 \n\t" + "pcmpgtw %%mm6, %%mm0 \n\t" // create mask pcv bytes < 0 + "pand %%mm6, %%mm0 \n\t" // only pav bytes < 0 in mm7 + "psubw %%mm7, %%mm5 \n\t" + "psubw %%mm0, %%mm6 \n\t" + // test pa <= pb + "movq %%mm4, %%mm7 \n\t" + "psubw %%mm0, %%mm6 \n\t" + "pcmpgtw %%mm5, %%mm7 \n\t" // pa > pb? + "movq %%mm7, %%mm0 \n\t" + // use mm7 mask to merge pa & pb + "pand %%mm7, %%mm5 \n\t" + // use mm0 mask copy to merge a & b + "pand %%mm0, %%mm2 \n\t" + "pandn %%mm4, %%mm7 \n\t" + "pandn %%mm1, %%mm0 \n\t" + "paddw %%mm5, %%mm7 \n\t" + "paddw %%mm2, %%mm0 \n\t" + // test ((pa <= pb)? pa:pb) <= pc + "pcmpgtw %%mm6, %%mm7 \n\t" // pab > pc? + "pxor %%mm1, %%mm1 \n\t" + "pand %%mm7, %%mm3 \n\t" + "pandn %%mm0, %%mm7 \n\t" + "pxor %%mm1, %%mm1 \n\t" + "paddw %%mm3, %%mm7 \n\t" + "pxor %%mm0, %%mm0 \n\t" + // step ecx to next set of 8 bytes and repeat loop til done + "addl $8, %%ecx \n\t" + "packuswb %%mm7, %%mm1 \n\t" + "paddb -8(%%edi,%%ecx,), %%mm1 \n\t" // add Paeth predictor with Raw(x) + "cmpl _MMXLength, %%ecx \n\t" + "movq %%mm1, -8(%%edi,%%ecx,) \n\t" // write back updated value + // mm1 will be used as Raw(x-bpp) next loop + "jb paeth_6lp \n\t" + + : "=S" (dummy_value_S), // output regs (dummy) + "=D" (dummy_value_D) + + : "0" (prev_row), // esi // input regs + "1" (row) // edi + + : "%ecx" // clobber list +#if 0 /* %mm0, ..., %mm7 not supported by gcc 2.7.2.3 or egcs 1.1 */ + , "%mm0", "%mm1", "%mm2", "%mm3" + , "%mm4", "%mm5", "%mm6", "%mm7" +#endif + ); + } + break; // end 6 bpp + + case 4: + { + _ActiveMask.use = 0x00000000ffffffffLL; + + __asm__ __volatile__ ( + "movl _dif, %%ecx \n\t" +// preload "movl row, %%edi \n\t" +// preload "movl prev_row, %%esi \n\t" + "pxor %%mm0, %%mm0 \n\t" + // prime the pump: load the first Raw(x-bpp) data set + "movq -8(%%edi,%%ecx,), %%mm1 \n\t" // only time should need to read + // a=Raw(x-bpp) bytes + "paeth_4lp: \n\t" + // do first set of 4 bytes + "movq -8(%%esi,%%ecx,), %%mm3 \n\t" // read c=Prior(x-bpp) bytes + "punpckhbw %%mm0, %%mm1 \n\t" // unpack Low bytes of a + "movq (%%esi,%%ecx,), %%mm2 \n\t" // load b=Prior(x) + "punpcklbw %%mm0, %%mm2 \n\t" // unpack High bytes of b + // pav = p - a = (a + b - c) - a = b - c + "movq %%mm2, %%mm4 \n\t" + "punpckhbw %%mm0, %%mm3 \n\t" // unpack High bytes of c + // pbv = p - b = (a + b - c) - b = a - c + "movq %%mm1, %%mm5 \n\t" + "psubw %%mm3, %%mm4 \n\t" + "pxor %%mm7, %%mm7 \n\t" + // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv + "movq %%mm4, %%mm6 \n\t" + "psubw %%mm3, %%mm5 \n\t" + // pa = abs(p-a) = abs(pav) + // pb = abs(p-b) = abs(pbv) + // pc = abs(p-c) = abs(pcv) + "pcmpgtw %%mm4, %%mm0 \n\t" // create mask pav bytes < 0 + "paddw %%mm5, %%mm6 \n\t" + "pand %%mm4, %%mm0 \n\t" // only pav bytes < 0 in mm7 + "pcmpgtw %%mm5, %%mm7 \n\t" // create mask pbv bytes < 0 + "psubw %%mm0, %%mm4 \n\t" + "pand %%mm5, %%mm7 \n\t" // only pbv bytes < 0 in mm0 + "psubw %%mm0, %%mm4 \n\t" + "psubw %%mm7, %%mm5 \n\t" + "pxor %%mm0, %%mm0 \n\t" + "pcmpgtw %%mm6, %%mm0 \n\t" // create mask pcv bytes < 0 + "pand %%mm6, %%mm0 \n\t" // only pav bytes < 0 in mm7 + "psubw %%mm7, %%mm5 \n\t" + "psubw %%mm0, %%mm6 \n\t" + // test pa <= pb + "movq %%mm4, %%mm7 \n\t" + "psubw %%mm0, %%mm6 \n\t" + "pcmpgtw %%mm5, %%mm7 \n\t" // pa > pb? + "movq %%mm7, %%mm0 \n\t" + // use mm7 mask to merge pa & pb + "pand %%mm7, %%mm5 \n\t" + // use mm0 mask copy to merge a & b + "pand %%mm0, %%mm2 \n\t" + "pandn %%mm4, %%mm7 \n\t" + "pandn %%mm1, %%mm0 \n\t" + "paddw %%mm5, %%mm7 \n\t" + "paddw %%mm2, %%mm0 \n\t" + // test ((pa <= pb)? pa:pb) <= pc + "pcmpgtw %%mm6, %%mm7 \n\t" // pab > pc? + "pxor %%mm1, %%mm1 \n\t" + "pand %%mm7, %%mm3 \n\t" + "pandn %%mm0, %%mm7 \n\t" + "paddw %%mm3, %%mm7 \n\t" + "pxor %%mm0, %%mm0 \n\t" + "packuswb %%mm1, %%mm7 \n\t" + "movq (%%esi,%%ecx,), %%mm3 \n\t" // load c=Prior(x-bpp) + "pand _ActiveMask, %%mm7 \n\t" + "movq %%mm3, %%mm2 \n\t" // load b=Prior(x) step 1 + "paddb (%%edi,%%ecx,), %%mm7 \n\t" // add Paeth predictor with Raw(x) + "punpcklbw %%mm0, %%mm3 \n\t" // unpack High bytes of c + "movq %%mm7, (%%edi,%%ecx,) \n\t" // write back updated value + "movq %%mm7, %%mm1 \n\t" // now mm1 will be used as Raw(x-bpp) + // do second set of 4 bytes + "punpckhbw %%mm0, %%mm2 \n\t" // unpack Low bytes of b + "punpcklbw %%mm0, %%mm1 \n\t" // unpack Low bytes of a + // pav = p - a = (a + b - c) - a = b - c + "movq %%mm2, %%mm4 \n\t" + // pbv = p - b = (a + b - c) - b = a - c + "movq %%mm1, %%mm5 \n\t" + "psubw %%mm3, %%mm4 \n\t" + "pxor %%mm7, %%mm7 \n\t" + // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv + "movq %%mm4, %%mm6 \n\t" + "psubw %%mm3, %%mm5 \n\t" + // pa = abs(p-a) = abs(pav) + // pb = abs(p-b) = abs(pbv) + // pc = abs(p-c) = abs(pcv) + "pcmpgtw %%mm4, %%mm0 \n\t" // create mask pav bytes < 0 + "paddw %%mm5, %%mm6 \n\t" + "pand %%mm4, %%mm0 \n\t" // only pav bytes < 0 in mm7 + "pcmpgtw %%mm5, %%mm7 \n\t" // create mask pbv bytes < 0 + "psubw %%mm0, %%mm4 \n\t" + "pand %%mm5, %%mm7 \n\t" // only pbv bytes < 0 in mm0 + "psubw %%mm0, %%mm4 \n\t" + "psubw %%mm7, %%mm5 \n\t" + "pxor %%mm0, %%mm0 \n\t" + "pcmpgtw %%mm6, %%mm0 \n\t" // create mask pcv bytes < 0 + "pand %%mm6, %%mm0 \n\t" // only pav bytes < 0 in mm7 + "psubw %%mm7, %%mm5 \n\t" + "psubw %%mm0, %%mm6 \n\t" + // test pa <= pb + "movq %%mm4, %%mm7 \n\t" + "psubw %%mm0, %%mm6 \n\t" + "pcmpgtw %%mm5, %%mm7 \n\t" // pa > pb? + "movq %%mm7, %%mm0 \n\t" + // use mm7 mask to merge pa & pb + "pand %%mm7, %%mm5 \n\t" + // use mm0 mask copy to merge a & b + "pand %%mm0, %%mm2 \n\t" + "pandn %%mm4, %%mm7 \n\t" + "pandn %%mm1, %%mm0 \n\t" + "paddw %%mm5, %%mm7 \n\t" + "paddw %%mm2, %%mm0 \n\t" + // test ((pa <= pb)? pa:pb) <= pc + "pcmpgtw %%mm6, %%mm7 \n\t" // pab > pc? + "pxor %%mm1, %%mm1 \n\t" + "pand %%mm7, %%mm3 \n\t" + "pandn %%mm0, %%mm7 \n\t" + "pxor %%mm1, %%mm1 \n\t" + "paddw %%mm3, %%mm7 \n\t" + "pxor %%mm0, %%mm0 \n\t" + // step ecx to next set of 8 bytes and repeat loop til done + "addl $8, %%ecx \n\t" + "packuswb %%mm7, %%mm1 \n\t" + "paddb -8(%%edi,%%ecx,), %%mm1 \n\t" // add predictor with Raw(x) + "cmpl _MMXLength, %%ecx \n\t" + "movq %%mm1, -8(%%edi,%%ecx,) \n\t" // write back updated value + // mm1 will be used as Raw(x-bpp) next loop + "jb paeth_4lp \n\t" + + : "=S" (dummy_value_S), // output regs (dummy) + "=D" (dummy_value_D) + + : "0" (prev_row), // esi // input regs + "1" (row) // edi + + : "%ecx" // clobber list +#if 0 /* %mm0, ..., %mm7 not supported by gcc 2.7.2.3 or egcs 1.1 */ + , "%mm0", "%mm1", "%mm2", "%mm3" + , "%mm4", "%mm5", "%mm6", "%mm7" +#endif + ); + } + break; // end 4 bpp + + case 8: // bpp == 8 + { + _ActiveMask.use = 0x00000000ffffffffLL; + + __asm__ __volatile__ ( + "movl _dif, %%ecx \n\t" +// preload "movl row, %%edi \n\t" +// preload "movl prev_row, %%esi \n\t" + "pxor %%mm0, %%mm0 \n\t" + // prime the pump: load the first Raw(x-bpp) data set + "movq -8(%%edi,%%ecx,), %%mm1 \n\t" // only time should need to read + // a=Raw(x-bpp) bytes + "paeth_8lp: \n\t" + // do first set of 4 bytes + "movq -8(%%esi,%%ecx,), %%mm3 \n\t" // read c=Prior(x-bpp) bytes + "punpcklbw %%mm0, %%mm1 \n\t" // unpack Low bytes of a + "movq (%%esi,%%ecx,), %%mm2 \n\t" // load b=Prior(x) + "punpcklbw %%mm0, %%mm2 \n\t" // unpack Low bytes of b + // pav = p - a = (a + b - c) - a = b - c + "movq %%mm2, %%mm4 \n\t" + "punpcklbw %%mm0, %%mm3 \n\t" // unpack Low bytes of c + // pbv = p - b = (a + b - c) - b = a - c + "movq %%mm1, %%mm5 \n\t" + "psubw %%mm3, %%mm4 \n\t" + "pxor %%mm7, %%mm7 \n\t" + // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv + "movq %%mm4, %%mm6 \n\t" + "psubw %%mm3, %%mm5 \n\t" + // pa = abs(p-a) = abs(pav) + // pb = abs(p-b) = abs(pbv) + // pc = abs(p-c) = abs(pcv) + "pcmpgtw %%mm4, %%mm0 \n\t" // create mask pav bytes < 0 + "paddw %%mm5, %%mm6 \n\t" + "pand %%mm4, %%mm0 \n\t" // only pav bytes < 0 in mm7 + "pcmpgtw %%mm5, %%mm7 \n\t" // create mask pbv bytes < 0 + "psubw %%mm0, %%mm4 \n\t" + "pand %%mm5, %%mm7 \n\t" // only pbv bytes < 0 in mm0 + "psubw %%mm0, %%mm4 \n\t" + "psubw %%mm7, %%mm5 \n\t" + "pxor %%mm0, %%mm0 \n\t" + "pcmpgtw %%mm6, %%mm0 \n\t" // create mask pcv bytes < 0 + "pand %%mm6, %%mm0 \n\t" // only pav bytes < 0 in mm7 + "psubw %%mm7, %%mm5 \n\t" + "psubw %%mm0, %%mm6 \n\t" + // test pa <= pb + "movq %%mm4, %%mm7 \n\t" + "psubw %%mm0, %%mm6 \n\t" + "pcmpgtw %%mm5, %%mm7 \n\t" // pa > pb? + "movq %%mm7, %%mm0 \n\t" + // use mm7 mask to merge pa & pb + "pand %%mm7, %%mm5 \n\t" + // use mm0 mask copy to merge a & b + "pand %%mm0, %%mm2 \n\t" + "pandn %%mm4, %%mm7 \n\t" + "pandn %%mm1, %%mm0 \n\t" + "paddw %%mm5, %%mm7 \n\t" + "paddw %%mm2, %%mm0 \n\t" + // test ((pa <= pb)? pa:pb) <= pc + "pcmpgtw %%mm6, %%mm7 \n\t" // pab > pc? + "pxor %%mm1, %%mm1 \n\t" + "pand %%mm7, %%mm3 \n\t" + "pandn %%mm0, %%mm7 \n\t" + "paddw %%mm3, %%mm7 \n\t" + "pxor %%mm0, %%mm0 \n\t" + "packuswb %%mm1, %%mm7 \n\t" + "movq -8(%%esi,%%ecx,), %%mm3 \n\t" // read c=Prior(x-bpp) bytes + "pand _ActiveMask, %%mm7 \n\t" + "movq (%%esi,%%ecx,), %%mm2 \n\t" // load b=Prior(x) + "paddb (%%edi,%%ecx,), %%mm7 \n\t" // add Paeth predictor with Raw(x) + "punpckhbw %%mm0, %%mm3 \n\t" // unpack High bytes of c + "movq %%mm7, (%%edi,%%ecx,) \n\t" // write back updated value + "movq -8(%%edi,%%ecx,), %%mm1 \n\t" // read a=Raw(x-bpp) bytes + + // do second set of 4 bytes + "punpckhbw %%mm0, %%mm2 \n\t" // unpack High bytes of b + "punpckhbw %%mm0, %%mm1 \n\t" // unpack High bytes of a + // pav = p - a = (a + b - c) - a = b - c + "movq %%mm2, %%mm4 \n\t" + // pbv = p - b = (a + b - c) - b = a - c + "movq %%mm1, %%mm5 \n\t" + "psubw %%mm3, %%mm4 \n\t" + "pxor %%mm7, %%mm7 \n\t" + // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv + "movq %%mm4, %%mm6 \n\t" + "psubw %%mm3, %%mm5 \n\t" + // pa = abs(p-a) = abs(pav) + // pb = abs(p-b) = abs(pbv) + // pc = abs(p-c) = abs(pcv) + "pcmpgtw %%mm4, %%mm0 \n\t" // create mask pav bytes < 0 + "paddw %%mm5, %%mm6 \n\t" + "pand %%mm4, %%mm0 \n\t" // only pav bytes < 0 in mm7 + "pcmpgtw %%mm5, %%mm7 \n\t" // create mask pbv bytes < 0 + "psubw %%mm0, %%mm4 \n\t" + "pand %%mm5, %%mm7 \n\t" // only pbv bytes < 0 in mm0 + "psubw %%mm0, %%mm4 \n\t" + "psubw %%mm7, %%mm5 \n\t" + "pxor %%mm0, %%mm0 \n\t" + "pcmpgtw %%mm6, %%mm0 \n\t" // create mask pcv bytes < 0 + "pand %%mm6, %%mm0 \n\t" // only pav bytes < 0 in mm7 + "psubw %%mm7, %%mm5 \n\t" + "psubw %%mm0, %%mm6 \n\t" + // test pa <= pb + "movq %%mm4, %%mm7 \n\t" + "psubw %%mm0, %%mm6 \n\t" + "pcmpgtw %%mm5, %%mm7 \n\t" // pa > pb? + "movq %%mm7, %%mm0 \n\t" + // use mm7 mask to merge pa & pb + "pand %%mm7, %%mm5 \n\t" + // use mm0 mask copy to merge a & b + "pand %%mm0, %%mm2 \n\t" + "pandn %%mm4, %%mm7 \n\t" + "pandn %%mm1, %%mm0 \n\t" + "paddw %%mm5, %%mm7 \n\t" + "paddw %%mm2, %%mm0 \n\t" + // test ((pa <= pb)? pa:pb) <= pc + "pcmpgtw %%mm6, %%mm7 \n\t" // pab > pc? + "pxor %%mm1, %%mm1 \n\t" + "pand %%mm7, %%mm3 \n\t" + "pandn %%mm0, %%mm7 \n\t" + "pxor %%mm1, %%mm1 \n\t" + "paddw %%mm3, %%mm7 \n\t" + "pxor %%mm0, %%mm0 \n\t" + // step ecx to next set of 8 bytes and repeat loop til done + "addl $8, %%ecx \n\t" + "packuswb %%mm7, %%mm1 \n\t" + "paddb -8(%%edi,%%ecx,), %%mm1 \n\t" // add Paeth predictor with Raw(x) + "cmpl _MMXLength, %%ecx \n\t" + "movq %%mm1, -8(%%edi,%%ecx,) \n\t" // write back updated value + // mm1 will be used as Raw(x-bpp) next loop + "jb paeth_8lp \n\t" + + : "=S" (dummy_value_S), // output regs (dummy) + "=D" (dummy_value_D) + + : "0" (prev_row), // esi // input regs + "1" (row) // edi + + : "%ecx" // clobber list +#if 0 /* %mm0, ..., %mm7 not supported by gcc 2.7.2.3 or egcs 1.1 */ + , "%mm0", "%mm1", "%mm2", "%mm3" + , "%mm4", "%mm5", "%mm6", "%mm7" +#endif + ); + } + break; // end 8 bpp + + case 1: // bpp = 1 + case 2: // bpp = 2 + default: // bpp > 8 + { + __asm__ __volatile__ ( +#ifdef __PIC__ + "pushl %%ebx \n\t" // save Global Offset Table index +#endif + "movl _dif, %%ebx \n\t" + "cmpl _FullLength, %%ebx \n\t" + "jnb paeth_dend \n\t" + +// preload "movl row, %%edi \n\t" +// preload "movl prev_row, %%esi \n\t" + // do Paeth decode for remaining bytes + "movl %%ebx, %%edx \n\t" +// preload "subl bpp, %%edx \n\t" // (bpp is preloaded into ecx) + "subl %%ecx, %%edx \n\t" // edx = ebx - bpp + "xorl %%ecx, %%ecx \n\t" // zero ecx before using cl & cx + + "paeth_dlp: \n\t" + "xorl %%eax, %%eax \n\t" + // pav = p - a = (a + b - c) - a = b - c + "movb (%%esi,%%ebx,), %%al \n\t" // load Prior(x) into al + "movb (%%esi,%%edx,), %%cl \n\t" // load Prior(x-bpp) into cl + "subl %%ecx, %%eax \n\t" // subtract Prior(x-bpp) + "movl %%eax, _patemp \n\t" // Save pav for later use + "xorl %%eax, %%eax \n\t" + // pbv = p - b = (a + b - c) - b = a - c + "movb (%%edi,%%edx,), %%al \n\t" // load Raw(x-bpp) into al + "subl %%ecx, %%eax \n\t" // subtract Prior(x-bpp) + "movl %%eax, %%ecx \n\t" + // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv + "addl _patemp, %%eax \n\t" // pcv = pav + pbv + // pc = abs(pcv) + "testl $0x80000000, %%eax \n\t" + "jz paeth_dpca \n\t" + "negl %%eax \n\t" // reverse sign of neg values + + "paeth_dpca: \n\t" + "movl %%eax, _pctemp \n\t" // save pc for later use + // pb = abs(pbv) + "testl $0x80000000, %%ecx \n\t" + "jz paeth_dpba \n\t" + "negl %%ecx \n\t" // reverse sign of neg values + + "paeth_dpba: \n\t" + "movl %%ecx, _pbtemp \n\t" // save pb for later use + // pa = abs(pav) + "movl _patemp, %%eax \n\t" + "testl $0x80000000, %%eax \n\t" + "jz paeth_dpaa \n\t" + "negl %%eax \n\t" // reverse sign of neg values + + "paeth_dpaa: \n\t" + "movl %%eax, _patemp \n\t" // save pa for later use + // test if pa <= pb + "cmpl %%ecx, %%eax \n\t" + "jna paeth_dabb \n\t" + // pa > pb; now test if pb <= pc + "cmpl _pctemp, %%ecx \n\t" + "jna paeth_dbbc \n\t" + // pb > pc; Raw(x) = Paeth(x) + Prior(x-bpp) + "movb (%%esi,%%edx,), %%cl \n\t" // load Prior(x-bpp) into cl + "jmp paeth_dpaeth \n\t" + + "paeth_dbbc: \n\t" + // pb <= pc; Raw(x) = Paeth(x) + Prior(x) + "movb (%%esi,%%ebx,), %%cl \n\t" // load Prior(x) into cl + "jmp paeth_dpaeth \n\t" + + "paeth_dabb: \n\t" + // pa <= pb; now test if pa <= pc + "cmpl _pctemp, %%eax \n\t" + "jna paeth_dabc \n\t" + // pa > pc; Raw(x) = Paeth(x) + Prior(x-bpp) + "movb (%%esi,%%edx,), %%cl \n\t" // load Prior(x-bpp) into cl + "jmp paeth_dpaeth \n\t" + + "paeth_dabc: \n\t" + // pa <= pc; Raw(x) = Paeth(x) + Raw(x-bpp) + "movb (%%edi,%%edx,), %%cl \n\t" // load Raw(x-bpp) into cl + + "paeth_dpaeth: \n\t" + "incl %%ebx \n\t" + "incl %%edx \n\t" + // Raw(x) = (Paeth(x) + Paeth_Predictor( a, b, c )) mod 256 + "addb %%cl, -1(%%edi,%%ebx,) \n\t" + "cmpl _FullLength, %%ebx \n\t" + "jb paeth_dlp \n\t" + + "paeth_dend: \n\t" +#ifdef __PIC__ + "popl %%ebx \n\t" // index to Global Offset Table +#endif + + : "=c" (dummy_value_c), // output regs (dummy) + "=S" (dummy_value_S), + "=D" (dummy_value_D) + + : "0" (bpp), // ecx // input regs + "1" (prev_row), // esi + "2" (row) // edi + + : "%eax", "%edx" // clobber list +#ifndef __PIC__ + , "%ebx" +#endif + ); + } + return; // No need to go further with this one + + } // end switch (bpp) + + __asm__ __volatile__ ( + // MMX acceleration complete; now do clean-up + // check if any remaining bytes left to decode +#ifdef __PIC__ + "pushl %%ebx \n\t" // save index to Global Offset Table +#endif + "movl _MMXLength, %%ebx \n\t" + "cmpl _FullLength, %%ebx \n\t" + "jnb paeth_end \n\t" +//pre "movl row, %%edi \n\t" +//pre "movl prev_row, %%esi \n\t" + // do Paeth decode for remaining bytes + "movl %%ebx, %%edx \n\t" +//pre "subl bpp, %%edx \n\t" // (bpp is preloaded into ecx) + "subl %%ecx, %%edx \n\t" // edx = ebx - bpp + "xorl %%ecx, %%ecx \n\t" // zero ecx before using cl & cx below + + "paeth_lp2: \n\t" + "xorl %%eax, %%eax \n\t" + // pav = p - a = (a + b - c) - a = b - c + "movb (%%esi,%%ebx,), %%al \n\t" // load Prior(x) into al + "movb (%%esi,%%edx,), %%cl \n\t" // load Prior(x-bpp) into cl + "subl %%ecx, %%eax \n\t" // subtract Prior(x-bpp) + "movl %%eax, _patemp \n\t" // Save pav for later use + "xorl %%eax, %%eax \n\t" + // pbv = p - b = (a + b - c) - b = a - c + "movb (%%edi,%%edx,), %%al \n\t" // load Raw(x-bpp) into al + "subl %%ecx, %%eax \n\t" // subtract Prior(x-bpp) + "movl %%eax, %%ecx \n\t" + // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv + "addl _patemp, %%eax \n\t" // pcv = pav + pbv + // pc = abs(pcv) + "testl $0x80000000, %%eax \n\t" + "jz paeth_pca2 \n\t" + "negl %%eax \n\t" // reverse sign of neg values + + "paeth_pca2: \n\t" + "movl %%eax, _pctemp \n\t" // save pc for later use + // pb = abs(pbv) + "testl $0x80000000, %%ecx \n\t" + "jz paeth_pba2 \n\t" + "negl %%ecx \n\t" // reverse sign of neg values + + "paeth_pba2: \n\t" + "movl %%ecx, _pbtemp \n\t" // save pb for later use + // pa = abs(pav) + "movl _patemp, %%eax \n\t" + "testl $0x80000000, %%eax \n\t" + "jz paeth_paa2 \n\t" + "negl %%eax \n\t" // reverse sign of neg values + + "paeth_paa2: \n\t" + "movl %%eax, _patemp \n\t" // save pa for later use + // test if pa <= pb + "cmpl %%ecx, %%eax \n\t" + "jna paeth_abb2 \n\t" + // pa > pb; now test if pb <= pc + "cmpl _pctemp, %%ecx \n\t" + "jna paeth_bbc2 \n\t" + // pb > pc; Raw(x) = Paeth(x) + Prior(x-bpp) + "movb (%%esi,%%edx,), %%cl \n\t" // load Prior(x-bpp) into cl + "jmp paeth_paeth2 \n\t" + + "paeth_bbc2: \n\t" + // pb <= pc; Raw(x) = Paeth(x) + Prior(x) + "movb (%%esi,%%ebx,), %%cl \n\t" // load Prior(x) into cl + "jmp paeth_paeth2 \n\t" + + "paeth_abb2: \n\t" + // pa <= pb; now test if pa <= pc + "cmpl _pctemp, %%eax \n\t" + "jna paeth_abc2 \n\t" + // pa > pc; Raw(x) = Paeth(x) + Prior(x-bpp) + "movb (%%esi,%%edx,), %%cl \n\t" // load Prior(x-bpp) into cl + "jmp paeth_paeth2 \n\t" + + "paeth_abc2: \n\t" + // pa <= pc; Raw(x) = Paeth(x) + Raw(x-bpp) + "movb (%%edi,%%edx,), %%cl \n\t" // load Raw(x-bpp) into cl + + "paeth_paeth2: \n\t" + "incl %%ebx \n\t" + "incl %%edx \n\t" + // Raw(x) = (Paeth(x) + Paeth_Predictor( a, b, c )) mod 256 + "addb %%cl, -1(%%edi,%%ebx,) \n\t" + "cmpl _FullLength, %%ebx \n\t" + "jb paeth_lp2 \n\t" + + "paeth_end: \n\t" + "EMMS \n\t" // end MMX; prep for poss. FP instrs. +#ifdef __PIC__ + "popl %%ebx \n\t" // restore index to Global Offset Table +#endif + + : "=c" (dummy_value_c), // output regs (dummy) + "=S" (dummy_value_S), + "=D" (dummy_value_D) + + : "0" (bpp), // ecx // input regs + "1" (prev_row), // esi + "2" (row) // edi + + : "%eax", "%edx" // clobber list (no input regs!) +#ifndef __PIC__ + , "%ebx" +#endif + ); + +} /* end png_read_filter_row_mmx_paeth() */ +#endif + + + + +#ifdef PNG_THREAD_UNSAFE_OK +//===========================================================================// +// // +// P N G _ R E A D _ F I L T E R _ R O W _ M M X _ S U B // +// // +//===========================================================================// + +// Optimized code for PNG Sub filter decoder + +static void /* PRIVATE */ +png_read_filter_row_mmx_sub(png_row_infop row_info, png_bytep row) +{ + int bpp; + int dummy_value_a; + int dummy_value_D; + + bpp = (row_info->pixel_depth + 7) >> 3; // calc number of bytes per pixel + _FullLength = row_info->rowbytes - bpp; // number of bytes to filter + + __asm__ __volatile__ ( +//pre "movl row, %%edi \n\t" + "movl %%edi, %%esi \n\t" // lp = row +//pre "movl bpp, %%eax \n\t" + "addl %%eax, %%edi \n\t" // rp = row + bpp +//irr "xorl %%eax, %%eax \n\t" + // get # of bytes to alignment + "movl %%edi, _dif \n\t" // take start of row + "addl $0xf, _dif \n\t" // add 7 + 8 to incr past + // alignment boundary + "xorl %%ecx, %%ecx \n\t" + "andl $0xfffffff8, _dif \n\t" // mask to alignment boundary + "subl %%edi, _dif \n\t" // subtract from start ==> value + "jz sub_go \n\t" // ecx at alignment + + "sub_lp1: \n\t" // fix alignment + "movb (%%esi,%%ecx,), %%al \n\t" + "addb %%al, (%%edi,%%ecx,) \n\t" + "incl %%ecx \n\t" + "cmpl _dif, %%ecx \n\t" + "jb sub_lp1 \n\t" + + "sub_go: \n\t" + "movl _FullLength, %%eax \n\t" + "movl %%eax, %%edx \n\t" + "subl %%ecx, %%edx \n\t" // subtract alignment fix + "andl $0x00000007, %%edx \n\t" // calc bytes over mult of 8 + "subl %%edx, %%eax \n\t" // drop over bytes from length + "movl %%eax, _MMXLength \n\t" + + : "=a" (dummy_value_a), // 0 // output regs (dummy) + "=D" (dummy_value_D) // 1 + + : "0" (bpp), // eax // input regs + "1" (row) // edi + + : "%esi", "%ecx", "%edx" // clobber list + +#if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */ + , "%mm0", "%mm1", "%mm2", "%mm3" + , "%mm4", "%mm5", "%mm6", "%mm7" +#endif + ); + + // now do the math for the rest of the row + switch (bpp) + { + case 3: + { + _ActiveMask.use = 0x0000ffffff000000LL; + _ShiftBpp.use = 24; // == 3 * 8 + _ShiftRem.use = 40; // == 64 - 24 + + __asm__ __volatile__ ( +// preload "movl row, %%edi \n\t" + "movq _ActiveMask, %%mm7 \n\t" // load _ActiveMask for 2nd + // active byte group + "movl %%edi, %%esi \n\t" // lp = row +// preload "movl bpp, %%eax \n\t" + "addl %%eax, %%edi \n\t" // rp = row + bpp + "movq %%mm7, %%mm6 \n\t" + "movl _dif, %%edx \n\t" + "psllq _ShiftBpp, %%mm6 \n\t" // move mask in mm6 to cover + // 3rd active byte group + // prime the pump: load the first Raw(x-bpp) data set + "movq -8(%%edi,%%edx,), %%mm1 \n\t" + + "sub_3lp: \n\t" // shift data for adding first + "psrlq _ShiftRem, %%mm1 \n\t" // bpp bytes (no need for mask; + // shift clears inactive bytes) + // add 1st active group + "movq (%%edi,%%edx,), %%mm0 \n\t" + "paddb %%mm1, %%mm0 \n\t" + + // add 2nd active group + "movq %%mm0, %%mm1 \n\t" // mov updated Raws to mm1 + "psllq _ShiftBpp, %%mm1 \n\t" // shift data to pos. correctly + "pand %%mm7, %%mm1 \n\t" // mask to use 2nd active group + "paddb %%mm1, %%mm0 \n\t" + + // add 3rd active group + "movq %%mm0, %%mm1 \n\t" // mov updated Raws to mm1 + "psllq _ShiftBpp, %%mm1 \n\t" // shift data to pos. correctly + "pand %%mm6, %%mm1 \n\t" // mask to use 3rd active group + "addl $8, %%edx \n\t" + "paddb %%mm1, %%mm0 \n\t" + + "cmpl _MMXLength, %%edx \n\t" + "movq %%mm0, -8(%%edi,%%edx,) \n\t" // write updated Raws to array + "movq %%mm0, %%mm1 \n\t" // prep 1st add at top of loop + "jb sub_3lp \n\t" + + : "=a" (dummy_value_a), // 0 // output regs (dummy) + "=D" (dummy_value_D) // 1 + + : "0" (bpp), // eax // input regs + "1" (row) // edi + + : "%edx", "%esi" // clobber list +#if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */ + , "%mm0", "%mm1", "%mm6", "%mm7" +#endif + ); + } + break; + + case 1: + { + __asm__ __volatile__ ( + "movl _dif, %%edx \n\t" +// preload "movl row, %%edi \n\t" + "cmpl _FullLength, %%edx \n\t" + "jnb sub_1end \n\t" + "movl %%edi, %%esi \n\t" // lp = row + "xorl %%eax, %%eax \n\t" +// preload "movl bpp, %%eax \n\t" + "addl %%eax, %%edi \n\t" // rp = row + bpp + + "sub_1lp: \n\t" + "movb (%%esi,%%edx,), %%al \n\t" + "addb %%al, (%%edi,%%edx,) \n\t" + "incl %%edx \n\t" + "cmpl _FullLength, %%edx \n\t" + "jb sub_1lp \n\t" + + "sub_1end: \n\t" + + : "=a" (dummy_value_a), // 0 // output regs (dummy) + "=D" (dummy_value_D) // 1 + + : "0" (bpp), // eax // input regs + "1" (row) // edi + + : "%edx", "%esi" // clobber list + ); + } + return; + + case 6: + case 4: + //case 7: // GRR BOGUS + //case 5: // GRR BOGUS + { + _ShiftBpp.use = bpp << 3; + _ShiftRem.use = 64 - _ShiftBpp.use; + + __asm__ __volatile__ ( +// preload "movl row, %%edi \n\t" + "movl _dif, %%edx \n\t" + "movl %%edi, %%esi \n\t" // lp = row +// preload "movl bpp, %%eax \n\t" + "addl %%eax, %%edi \n\t" // rp = row + bpp + + // prime the pump: load the first Raw(x-bpp) data set + "movq -8(%%edi,%%edx,), %%mm1 \n\t" + + "sub_4lp: \n\t" // shift data for adding first + "psrlq _ShiftRem, %%mm1 \n\t" // bpp bytes (no need for mask; + // shift clears inactive bytes) + "movq (%%edi,%%edx,), %%mm0 \n\t" + "paddb %%mm1, %%mm0 \n\t" + + // add 2nd active group + "movq %%mm0, %%mm1 \n\t" // mov updated Raws to mm1 + "psllq _ShiftBpp, %%mm1 \n\t" // shift data to pos. correctly + "addl $8, %%edx \n\t" + "paddb %%mm1, %%mm0 \n\t" + + "cmpl _MMXLength, %%edx \n\t" + "movq %%mm0, -8(%%edi,%%edx,) \n\t" + "movq %%mm0, %%mm1 \n\t" // prep 1st add at top of loop + "jb sub_4lp \n\t" + + : "=a" (dummy_value_a), // 0 // output regs (dummy) + "=D" (dummy_value_D) // 1 + + : "0" (bpp), // eax // input regs + "1" (row) // edi + + : "%edx", "%esi" // clobber list +#if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */ + , "%mm0", "%mm1" +#endif + ); + } + break; + + case 2: + { + _ActiveMask.use = 0x00000000ffff0000LL; + _ShiftBpp.use = 16; // == 2 * 8 + _ShiftRem.use = 48; // == 64 - 16 + + __asm__ __volatile__ ( + "movq _ActiveMask, %%mm7 \n\t" // load _ActiveMask for 2nd + // active byte group + "movl _dif, %%edx \n\t" + "movq %%mm7, %%mm6 \n\t" +// preload "movl row, %%edi \n\t" + "psllq _ShiftBpp, %%mm6 \n\t" // move mask in mm6 to cover + // 3rd active byte group + "movl %%edi, %%esi \n\t" // lp = row + "movq %%mm6, %%mm5 \n\t" +// preload "movl bpp, %%eax \n\t" + "addl %%eax, %%edi \n\t" // rp = row + bpp + "psllq _ShiftBpp, %%mm5 \n\t" // move mask in mm5 to cover + // 4th active byte group + // prime the pump: load the first Raw(x-bpp) data set + "movq -8(%%edi,%%edx,), %%mm1 \n\t" + + "sub_2lp: \n\t" // shift data for adding first + "psrlq _ShiftRem, %%mm1 \n\t" // bpp bytes (no need for mask; + // shift clears inactive bytes) + // add 1st active group + "movq (%%edi,%%edx,), %%mm0 \n\t" + "paddb %%mm1, %%mm0 \n\t" + + // add 2nd active group + "movq %%mm0, %%mm1 \n\t" // mov updated Raws to mm1 + "psllq _ShiftBpp, %%mm1 \n\t" // shift data to pos. correctly + "pand %%mm7, %%mm1 \n\t" // mask to use 2nd active group + "paddb %%mm1, %%mm0 \n\t" + + // add 3rd active group + "movq %%mm0, %%mm1 \n\t" // mov updated Raws to mm1 + "psllq _ShiftBpp, %%mm1 \n\t" // shift data to pos. correctly + "pand %%mm6, %%mm1 \n\t" // mask to use 3rd active group + "paddb %%mm1, %%mm0 \n\t" + + // add 4th active group + "movq %%mm0, %%mm1 \n\t" // mov updated Raws to mm1 + "psllq _ShiftBpp, %%mm1 \n\t" // shift data to pos. correctly + "pand %%mm5, %%mm1 \n\t" // mask to use 4th active group + "addl $8, %%edx \n\t" + "paddb %%mm1, %%mm0 \n\t" + "cmpl _MMXLength, %%edx \n\t" + "movq %%mm0, -8(%%edi,%%edx,) \n\t" // write updated Raws to array + "movq %%mm0, %%mm1 \n\t" // prep 1st add at top of loop + "jb sub_2lp \n\t" + + : "=a" (dummy_value_a), // 0 // output regs (dummy) + "=D" (dummy_value_D) // 1 + + : "0" (bpp), // eax // input regs + "1" (row) // edi + + : "%edx", "%esi" // clobber list +#if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */ + , "%mm0", "%mm1", "%mm5", "%mm6", "%mm7" +#endif + ); + } + break; + + case 8: + { + __asm__ __volatile__ ( +// preload "movl row, %%edi \n\t" + "movl _dif, %%edx \n\t" + "movl %%edi, %%esi \n\t" // lp = row +// preload "movl bpp, %%eax \n\t" + "addl %%eax, %%edi \n\t" // rp = row + bpp + "movl _MMXLength, %%ecx \n\t" + + // prime the pump: load the first Raw(x-bpp) data set + "movq -8(%%edi,%%edx,), %%mm7 \n\t" + "andl $0x0000003f, %%ecx \n\t" // calc bytes over mult of 64 + + "sub_8lp: \n\t" + "movq (%%edi,%%edx,), %%mm0 \n\t" // load Sub(x) for 1st 8 bytes + "paddb %%mm7, %%mm0 \n\t" + "movq 8(%%edi,%%edx,), %%mm1 \n\t" // load Sub(x) for 2nd 8 bytes + "movq %%mm0, (%%edi,%%edx,) \n\t" // write Raw(x) for 1st 8 bytes + + // Now mm0 will be used as Raw(x-bpp) for the 2nd group of 8 bytes. + // This will be repeated for each group of 8 bytes with the 8th + // group being used as the Raw(x-bpp) for the 1st group of the + // next loop. + + "paddb %%mm0, %%mm1 \n\t" + "movq 16(%%edi,%%edx,), %%mm2 \n\t" // load Sub(x) for 3rd 8 bytes + "movq %%mm1, 8(%%edi,%%edx,) \n\t" // write Raw(x) for 2nd 8 bytes + "paddb %%mm1, %%mm2 \n\t" + "movq 24(%%edi,%%edx,), %%mm3 \n\t" // load Sub(x) for 4th 8 bytes + "movq %%mm2, 16(%%edi,%%edx,) \n\t" // write Raw(x) for 3rd 8 bytes + "paddb %%mm2, %%mm3 \n\t" + "movq 32(%%edi,%%edx,), %%mm4 \n\t" // load Sub(x) for 5th 8 bytes + "movq %%mm3, 24(%%edi,%%edx,) \n\t" // write Raw(x) for 4th 8 bytes + "paddb %%mm3, %%mm4 \n\t" + "movq 40(%%edi,%%edx,), %%mm5 \n\t" // load Sub(x) for 6th 8 bytes + "movq %%mm4, 32(%%edi,%%edx,) \n\t" // write Raw(x) for 5th 8 bytes + "paddb %%mm4, %%mm5 \n\t" + "movq 48(%%edi,%%edx,), %%mm6 \n\t" // load Sub(x) for 7th 8 bytes + "movq %%mm5, 40(%%edi,%%edx,) \n\t" // write Raw(x) for 6th 8 bytes + "paddb %%mm5, %%mm6 \n\t" + "movq 56(%%edi,%%edx,), %%mm7 \n\t" // load Sub(x) for 8th 8 bytes + "movq %%mm6, 48(%%edi,%%edx,) \n\t" // write Raw(x) for 7th 8 bytes + "addl $64, %%edx \n\t" + "paddb %%mm6, %%mm7 \n\t" + "cmpl %%ecx, %%edx \n\t" + "movq %%mm7, -8(%%edi,%%edx,) \n\t" // write Raw(x) for 8th 8 bytes + "jb sub_8lp \n\t" + + "cmpl _MMXLength, %%edx \n\t" + "jnb sub_8lt8 \n\t" + + "sub_8lpA: \n\t" + "movq (%%edi,%%edx,), %%mm0 \n\t" + "addl $8, %%edx \n\t" + "paddb %%mm7, %%mm0 \n\t" + "cmpl _MMXLength, %%edx \n\t" + "movq %%mm0, -8(%%edi,%%edx,) \n\t" // -8 to offset early addl edx + "movq %%mm0, %%mm7 \n\t" // move calculated Raw(x) data + // to mm1 to be new Raw(x-bpp) + // for next loop + "jb sub_8lpA \n\t" + + "sub_8lt8: \n\t" + + : "=a" (dummy_value_a), // 0 // output regs (dummy) + "=D" (dummy_value_D) // 1 + + : "0" (bpp), // eax // input regs + "1" (row) // edi + + : "%ecx", "%edx", "%esi" // clobber list +#if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */ + , "%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7" +#endif + ); + } + break; + + default: // bpp greater than 8 bytes GRR BOGUS + { + __asm__ __volatile__ ( + "movl _dif, %%edx \n\t" +// preload "movl row, %%edi \n\t" + "movl %%edi, %%esi \n\t" // lp = row +// preload "movl bpp, %%eax \n\t" + "addl %%eax, %%edi \n\t" // rp = row + bpp + + "sub_Alp: \n\t" + "movq (%%edi,%%edx,), %%mm0 \n\t" + "movq (%%esi,%%edx,), %%mm1 \n\t" + "addl $8, %%edx \n\t" + "paddb %%mm1, %%mm0 \n\t" + "cmpl _MMXLength, %%edx \n\t" + "movq %%mm0, -8(%%edi,%%edx,) \n\t" // mov does not affect flags; + // -8 to offset addl edx + "jb sub_Alp \n\t" + + : "=a" (dummy_value_a), // 0 // output regs (dummy) + "=D" (dummy_value_D) // 1 + + : "0" (bpp), // eax // input regs + "1" (row) // edi + + : "%edx", "%esi" // clobber list +#if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */ + , "%mm0", "%mm1" +#endif + ); + } + break; + + } // end switch (bpp) + + __asm__ __volatile__ ( + "movl _MMXLength, %%edx \n\t" +//pre "movl row, %%edi \n\t" + "cmpl _FullLength, %%edx \n\t" + "jnb sub_end \n\t" + + "movl %%edi, %%esi \n\t" // lp = row +//pre "movl bpp, %%eax \n\t" + "addl %%eax, %%edi \n\t" // rp = row + bpp + "xorl %%eax, %%eax \n\t" + + "sub_lp2: \n\t" + "movb (%%esi,%%edx,), %%al \n\t" + "addb %%al, (%%edi,%%edx,) \n\t" + "incl %%edx \n\t" + "cmpl _FullLength, %%edx \n\t" + "jb sub_lp2 \n\t" + + "sub_end: \n\t" + "EMMS \n\t" // end MMX instructions + + : "=a" (dummy_value_a), // 0 // output regs (dummy) + "=D" (dummy_value_D) // 1 + + : "0" (bpp), // eax // input regs + "1" (row) // edi + + : "%edx", "%esi" // clobber list + ); + +} // end of png_read_filter_row_mmx_sub() +#endif + + + + +//===========================================================================// +// // +// P N G _ R E A D _ F I L T E R _ R O W _ M M X _ U P // +// // +//===========================================================================// + +// Optimized code for PNG Up filter decoder + +static void /* PRIVATE */ +png_read_filter_row_mmx_up(png_row_infop row_info, png_bytep row, + png_bytep prev_row) +{ + png_uint_32 len; + int dummy_value_d; // fix 'forbidden register 3 (dx) was spilled' error + int dummy_value_S; + int dummy_value_D; + + len = row_info->rowbytes; // number of bytes to filter + + __asm__ __volatile__ ( +//pre "movl row, %%edi \n\t" + // get # of bytes to alignment +#ifdef __PIC__ + "pushl %%ebx \n\t" +#endif + "movl %%edi, %%ecx \n\t" + "xorl %%ebx, %%ebx \n\t" + "addl $0x7, %%ecx \n\t" + "xorl %%eax, %%eax \n\t" + "andl $0xfffffff8, %%ecx \n\t" +//pre "movl prev_row, %%esi \n\t" + "subl %%edi, %%ecx \n\t" + "jz up_go \n\t" + + "up_lp1: \n\t" // fix alignment + "movb (%%edi,%%ebx,), %%al \n\t" + "addb (%%esi,%%ebx,), %%al \n\t" + "incl %%ebx \n\t" + "cmpl %%ecx, %%ebx \n\t" + "movb %%al, -1(%%edi,%%ebx,) \n\t" // mov does not affect flags; -1 to + "jb up_lp1 \n\t" // offset incl ebx + + "up_go: \n\t" +//pre "movl len, %%edx \n\t" + "movl %%edx, %%ecx \n\t" + "subl %%ebx, %%edx \n\t" // subtract alignment fix + "andl $0x0000003f, %%edx \n\t" // calc bytes over mult of 64 + "subl %%edx, %%ecx \n\t" // drop over bytes from length + + // unrolled loop - use all MMX registers and interleave to reduce + // number of branch instructions (loops) and reduce partial stalls + "up_loop: \n\t" + "movq (%%esi,%%ebx,), %%mm1 \n\t" + "movq (%%edi,%%ebx,), %%mm0 \n\t" + "movq 8(%%esi,%%ebx,), %%mm3 \n\t" + "paddb %%mm1, %%mm0 \n\t" + "movq 8(%%edi,%%ebx,), %%mm2 \n\t" + "movq %%mm0, (%%edi,%%ebx,) \n\t" + "paddb %%mm3, %%mm2 \n\t" + "movq 16(%%esi,%%ebx,), %%mm5 \n\t" + "movq %%mm2, 8(%%edi,%%ebx,) \n\t" + "movq 16(%%edi,%%ebx,), %%mm4 \n\t" + "movq 24(%%esi,%%ebx,), %%mm7 \n\t" + "paddb %%mm5, %%mm4 \n\t" + "movq 24(%%edi,%%ebx,), %%mm6 \n\t" + "movq %%mm4, 16(%%edi,%%ebx,) \n\t" + "paddb %%mm7, %%mm6 \n\t" + "movq 32(%%esi,%%ebx,), %%mm1 \n\t" + "movq %%mm6, 24(%%edi,%%ebx,) \n\t" + "movq 32(%%edi,%%ebx,), %%mm0 \n\t" + "movq 40(%%esi,%%ebx,), %%mm3 \n\t" + "paddb %%mm1, %%mm0 \n\t" + "movq 40(%%edi,%%ebx,), %%mm2 \n\t" + "movq %%mm0, 32(%%edi,%%ebx,) \n\t" + "paddb %%mm3, %%mm2 \n\t" + "movq 48(%%esi,%%ebx,), %%mm5 \n\t" + "movq %%mm2, 40(%%edi,%%ebx,) \n\t" + "movq 48(%%edi,%%ebx,), %%mm4 \n\t" + "movq 56(%%esi,%%ebx,), %%mm7 \n\t" + "paddb %%mm5, %%mm4 \n\t" + "movq 56(%%edi,%%ebx,), %%mm6 \n\t" + "movq %%mm4, 48(%%edi,%%ebx,) \n\t" + "addl $64, %%ebx \n\t" + "paddb %%mm7, %%mm6 \n\t" + "cmpl %%ecx, %%ebx \n\t" + "movq %%mm6, -8(%%edi,%%ebx,) \n\t" // (+56)movq does not affect flags; + "jb up_loop \n\t" // -8 to offset addl ebx + + "cmpl $0, %%edx \n\t" // test for bytes over mult of 64 + "jz up_end \n\t" + + "cmpl $8, %%edx \n\t" // test for less than 8 bytes + "jb up_lt8 \n\t" // [added by lcreeve at netins.net] + + "addl %%edx, %%ecx \n\t" + "andl $0x00000007, %%edx \n\t" // calc bytes over mult of 8 + "subl %%edx, %%ecx \n\t" // drop over bytes from length + "jz up_lt8 \n\t" + + "up_lpA: \n\t" // use MMX regs to update 8 bytes sim. + "movq (%%esi,%%ebx,), %%mm1 \n\t" + "movq (%%edi,%%ebx,), %%mm0 \n\t" + "addl $8, %%ebx \n\t" + "paddb %%mm1, %%mm0 \n\t" + "cmpl %%ecx, %%ebx \n\t" + "movq %%mm0, -8(%%edi,%%ebx,) \n\t" // movq does not affect flags; -8 to + "jb up_lpA \n\t" // offset add ebx + "cmpl $0, %%edx \n\t" // test for bytes over mult of 8 + "jz up_end \n\t" + + "up_lt8: \n\t" + "xorl %%eax, %%eax \n\t" + "addl %%edx, %%ecx \n\t" // move over byte count into counter + + "up_lp2: \n\t" // use x86 regs for remaining bytes + "movb (%%edi,%%ebx,), %%al \n\t" + "addb (%%esi,%%ebx,), %%al \n\t" + "incl %%ebx \n\t" + "cmpl %%ecx, %%ebx \n\t" + "movb %%al, -1(%%edi,%%ebx,) \n\t" // mov does not affect flags; -1 to + "jb up_lp2 \n\t" // offset inc ebx + + "up_end: \n\t" + "EMMS \n\t" // conversion of filtered row complete +#ifdef __PIC__ + "popl %%ebx \n\t" +#endif + + : "=d" (dummy_value_d), // 0 // output regs (dummy) + "=S" (dummy_value_S), // 1 + "=D" (dummy_value_D) // 2 + + : "0" (len), // edx // input regs + "1" (prev_row), // esi + "2" (row) // edi + + : "%eax", "%ecx" // clobber list (no input regs!) +#ifndef __PIC__ + , "%ebx" +#endif + +#if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */ + , "%mm0", "%mm1", "%mm2", "%mm3" + , "%mm4", "%mm5", "%mm6", "%mm7" +#endif + ); + +} // end of png_read_filter_row_mmx_up() + +#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ + + + + +/*===========================================================================*/ +/* */ +/* P N G _ R E A D _ F I L T E R _ R O W */ +/* */ +/*===========================================================================*/ + + +/* Optimized png_read_filter_row routines */ + +void /* PRIVATE */ +png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep + row, png_bytep prev_row, int filter) +{ +#ifdef PNG_DEBUG + char filnm[10]; +#endif + +#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) +/* GRR: these are superseded by png_ptr->asm_flags: */ +#define UseMMX_sub 1 // GRR: converted 20000730 +#define UseMMX_up 1 // GRR: converted 20000729 +#define UseMMX_avg 1 // GRR: converted 20000828 (+ 16-bit bugfix 20000916) +#define UseMMX_paeth 1 // GRR: converted 20000828 + + if (_mmx_supported == 2) { + /* this should have happened in png_init_mmx_flags() already */ +#if !defined(PNG_1_0_X) + png_warning(png_ptr, "asm_flags may not have been initialized"); +#endif + png_mmx_support(); + } +#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ + +#ifdef PNG_DEBUG + png_debug(1, "in png_read_filter_row (pnggccrd.c)\n"); + switch (filter) + { + case 0: sprintf(filnm, "none"); + break; + case 1: sprintf(filnm, "sub-%s", +#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) +#if !defined(PNG_1_0_X) + (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_SUB)? "MMX" : +#endif +#endif +"x86"); + break; + case 2: sprintf(filnm, "up-%s", +#ifdef PNG_ASSEMBLER_CODE_SUPPORTED +#if !defined(PNG_1_0_X) + (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_UP)? "MMX" : +#endif +#endif + "x86"); + break; + case 3: sprintf(filnm, "avg-%s", +#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) +#if !defined(PNG_1_0_X) + (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_AVG)? "MMX" : +#endif +#endif + "x86"); + break; + case 4: sprintf(filnm, "Paeth-%s", +#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) +#if !defined(PNG_1_0_X) + (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_PAETH)? "MMX": +#endif +#endif +"x86"); + break; + default: sprintf(filnm, "unknw"); + break; + } + png_debug2(0, "row_number=%5ld, %5s, ", png_ptr->row_number, filnm); + png_debug1(0, "row=0x%08lx, ", (unsigned long)row); + png_debug2(0, "pixdepth=%2d, bytes=%d, ", (int)row_info->pixel_depth, + (int)((row_info->pixel_depth + 7) >> 3)); + png_debug1(0,"rowbytes=%8ld\n", row_info->rowbytes); +#endif /* PNG_DEBUG */ + + switch (filter) + { + case PNG_FILTER_VALUE_NONE: + break; + + case PNG_FILTER_VALUE_SUB: +#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) +#if !defined(PNG_1_0_X) + if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_SUB) && + (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) && + (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold)) +#else + if (_mmx_supported) +#endif + { + png_read_filter_row_mmx_sub(row_info, row); + } + else +#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ + { + png_uint_32 i; + png_uint_32 istop = row_info->rowbytes; + png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3; + png_bytep rp = row + bpp; + png_bytep lp = row; + + for (i = bpp; i < istop; i++) + { + *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff); + rp++; + } + } /* end !UseMMX_sub */ + break; + + case PNG_FILTER_VALUE_UP: +#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) +#if !defined(PNG_1_0_X) + if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_UP) && + (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) && + (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold)) +#else + if (_mmx_supported) +#endif + { + png_read_filter_row_mmx_up(row_info, row, prev_row); + } + else +#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ + { + png_uint_32 i; + png_uint_32 istop = row_info->rowbytes; + png_bytep rp = row; + png_bytep pp = prev_row; + + for (i = 0; i < istop; ++i) + { + *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff); + rp++; + } + } /* end !UseMMX_up */ + break; + + case PNG_FILTER_VALUE_AVG: +#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) +#if !defined(PNG_1_0_X) + if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_AVG) && + (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) && + (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold)) +#else + if (_mmx_supported) +#endif + { + png_read_filter_row_mmx_avg(row_info, row, prev_row); + } + else +#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ + { + png_uint_32 i; + png_bytep rp = row; + png_bytep pp = prev_row; + png_bytep lp = row; + png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3; + png_uint_32 istop = row_info->rowbytes - bpp; + + for (i = 0; i < bpp; i++) + { + *rp = (png_byte)(((int)(*rp) + + ((int)(*pp++) >> 1)) & 0xff); + rp++; + } + + for (i = 0; i < istop; i++) + { + *rp = (png_byte)(((int)(*rp) + + ((int)(*pp++ + *lp++) >> 1)) & 0xff); + rp++; + } + } /* end !UseMMX_avg */ + break; + + case PNG_FILTER_VALUE_PAETH: +#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) +#if !defined(PNG_1_0_X) + if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_PAETH) && + (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) && + (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold)) +#else + if (_mmx_supported) +#endif + { + png_read_filter_row_mmx_paeth(row_info, row, prev_row); + } + else +#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ + { + png_uint_32 i; + png_bytep rp = row; + png_bytep pp = prev_row; + png_bytep lp = row; + png_bytep cp = prev_row; + png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3; + png_uint_32 istop = row_info->rowbytes - bpp; + + for (i = 0; i < bpp; i++) + { + *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff); + rp++; + } + + for (i = 0; i < istop; i++) /* use leftover rp,pp */ + { + int a, b, c, pa, pb, pc, p; + + a = *lp++; + b = *pp++; + c = *cp++; + + p = b - c; + pc = a - c; + +#ifdef PNG_USE_ABS + pa = abs(p); + pb = abs(pc); + pc = abs(p + pc); +#else + pa = p < 0 ? -p : p; + pb = pc < 0 ? -pc : pc; + pc = (p + pc) < 0 ? -(p + pc) : p + pc; +#endif + + /* + if (pa <= pb && pa <= pc) + p = a; + else if (pb <= pc) + p = b; + else + p = c; + */ + + p = (pa <= pb && pa <= pc) ? a : (pb <= pc) ? b : c; + + *rp = (png_byte)(((int)(*rp) + p) & 0xff); + rp++; + } + } /* end !UseMMX_paeth */ + break; + + default: + png_warning(png_ptr, "Ignoring bad row-filter type"); + *row=0; + break; + } +} + +#endif /* PNG_HAVE_ASSEMBLER_READ_FILTER_ROW */ + + +/*===========================================================================*/ +/* */ +/* P N G _ M M X _ S U P P O R T */ +/* */ +/*===========================================================================*/ + +/* GRR NOTES: (1) the following code assumes 386 or better (pushfl/popfl) + * (2) all instructions compile with gcc 2.7.2.3 and later + * (3) the function is moved down here to prevent gcc from + * inlining it in multiple places and then barfing be- + * cause the ".NOT_SUPPORTED" label is multiply defined + * [is there a way to signal that a *single* function should + * not be inlined? is there a way to modify the label for + * each inlined instance, e.g., by appending _1, _2, etc.? + * maybe if don't use leading "." in label name? (nope...sigh)] + */ + +int PNGAPI +png_mmx_support(void) +{ +#if defined(PNG_MMX_CODE_SUPPORTED) + int result; + __asm__ __volatile__ ( + "pushl %%ebx \n\t" // ebx gets clobbered by CPUID instruction + "pushl %%ecx \n\t" // so does ecx... + "pushl %%edx \n\t" // ...and edx (but ecx & edx safe on Linux) +// ".byte 0x66 \n\t" // convert 16-bit pushf to 32-bit pushfd +// "pushf \n\t" // 16-bit pushf + "pushfl \n\t" // save Eflag to stack + "popl %%eax \n\t" // get Eflag from stack into eax + "movl %%eax, %%ecx \n\t" // make another copy of Eflag in ecx + "xorl $0x200000, %%eax \n\t" // toggle ID bit in Eflag (i.e., bit 21) + "pushl %%eax \n\t" // save modified Eflag back to stack +// ".byte 0x66 \n\t" // convert 16-bit popf to 32-bit popfd +// "popf \n\t" // 16-bit popf + "popfl \n\t" // restore modified value to Eflag reg + "pushfl \n\t" // save Eflag to stack + "popl %%eax \n\t" // get Eflag from stack + "pushl %%ecx \n\t" // save original Eflag to stack + "popfl \n\t" // restore original Eflag + "xorl %%ecx, %%eax \n\t" // compare new Eflag with original Eflag + "jz 0f \n\t" // if same, CPUID instr. is not supported + + "xorl %%eax, %%eax \n\t" // set eax to zero +// ".byte 0x0f, 0xa2 \n\t" // CPUID instruction (two-byte opcode) + "cpuid \n\t" // get the CPU identification info + "cmpl $1, %%eax \n\t" // make sure eax return non-zero value + "jl 0f \n\t" // if eax is zero, MMX is not supported + + "xorl %%eax, %%eax \n\t" // set eax to zero and... + "incl %%eax \n\t" // ...increment eax to 1. This pair is + // faster than the instruction "mov eax, 1" + "cpuid \n\t" // get the CPU identification info again + "andl $0x800000, %%edx \n\t" // mask out all bits but MMX bit (23) + "cmpl $0, %%edx \n\t" // 0 = MMX not supported + "jz 0f \n\t" // non-zero = yes, MMX IS supported + + "movl $1, %%eax \n\t" // set return value to 1 + "jmp 1f \n\t" // DONE: have MMX support + + "0: \n\t" // .NOT_SUPPORTED: target label for jump instructions + "movl $0, %%eax \n\t" // set return value to 0 + "1: \n\t" // .RETURN: target label for jump instructions + "popl %%edx \n\t" // restore edx + "popl %%ecx \n\t" // restore ecx + "popl %%ebx \n\t" // restore ebx + +// "ret \n\t" // DONE: no MMX support + // (fall through to standard C "ret") + + : "=a" (result) // output list + + : // any variables used on input (none) + + // no clobber list +// , "%ebx", "%ecx", "%edx" // GRR: we handle these manually +// , "memory" // if write to a variable gcc thought was in a reg +// , "cc" // "condition codes" (flag bits) + ); + _mmx_supported = result; +#else + _mmx_supported = 0; +#endif /* PNG_MMX_CODE_SUPPORTED */ + + return _mmx_supported; +} + + +#endif /* PNG_USE_PNGGCCRD */ diff --git a/mod/pub.mod/libpng.mod/pngget.c b/mod/pub.mod/libpng.mod/pngget.c new file mode 100644 index 0000000..df76585 --- /dev/null +++ b/mod/pub.mod/libpng.mod/pngget.c @@ -0,0 +1,937 @@ + +/* pngget.c - retrieval of values from info struct + * + * Last changed in libpng 1.2.9 April 14, 2006 + * For conditions of distribution and use, see copyright notice in png.h + * Copyright (c) 1998-2006 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + */ + +#define PNG_INTERNAL +#include "png.h" + +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) + +png_uint_32 PNGAPI +png_get_valid(png_structp png_ptr, png_infop info_ptr, png_uint_32 flag) +{ + if (png_ptr != NULL && info_ptr != NULL) + return(info_ptr->valid & flag); + else + return(0); +} + +png_uint_32 PNGAPI +png_get_rowbytes(png_structp png_ptr, png_infop info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) + return(info_ptr->rowbytes); + else + return(0); +} + +#if defined(PNG_INFO_IMAGE_SUPPORTED) +png_bytepp PNGAPI +png_get_rows(png_structp png_ptr, png_infop info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) + return(info_ptr->row_pointers); + else + return(0); +} +#endif + +#ifdef PNG_EASY_ACCESS_SUPPORTED +/* easy access to info, added in libpng-0.99 */ +png_uint_32 PNGAPI +png_get_image_width(png_structp png_ptr, png_infop info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) + { + return info_ptr->width; + } + return (0); +} + +png_uint_32 PNGAPI +png_get_image_height(png_structp png_ptr, png_infop info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) + { + return info_ptr->height; + } + return (0); +} + +png_byte PNGAPI +png_get_bit_depth(png_structp png_ptr, png_infop info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) + { + return info_ptr->bit_depth; + } + return (0); +} + +png_byte PNGAPI +png_get_color_type(png_structp png_ptr, png_infop info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) + { + return info_ptr->color_type; + } + return (0); +} + +png_byte PNGAPI +png_get_filter_type(png_structp png_ptr, png_infop info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) + { + return info_ptr->filter_type; + } + return (0); +} + +png_byte PNGAPI +png_get_interlace_type(png_structp png_ptr, png_infop info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) + { + return info_ptr->interlace_type; + } + return (0); +} + +png_byte PNGAPI +png_get_compression_type(png_structp png_ptr, png_infop info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) + { + return info_ptr->compression_type; + } + return (0); +} + +png_uint_32 PNGAPI +png_get_x_pixels_per_meter(png_structp png_ptr, png_infop info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) +#if defined(PNG_pHYs_SUPPORTED) + if (info_ptr->valid & PNG_INFO_pHYs) + { + png_debug1(1, "in %s retrieval function\n", "png_get_x_pixels_per_meter"); + if(info_ptr->phys_unit_type != PNG_RESOLUTION_METER) + return (0); + else return (info_ptr->x_pixels_per_unit); + } +#else + return (0); +#endif + return (0); +} + +png_uint_32 PNGAPI +png_get_y_pixels_per_meter(png_structp png_ptr, png_infop info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) +#if defined(PNG_pHYs_SUPPORTED) + if (info_ptr->valid & PNG_INFO_pHYs) + { + png_debug1(1, "in %s retrieval function\n", "png_get_y_pixels_per_meter"); + if(info_ptr->phys_unit_type != PNG_RESOLUTION_METER) + return (0); + else return (info_ptr->y_pixels_per_unit); + } +#else + return (0); +#endif + return (0); +} + +png_uint_32 PNGAPI +png_get_pixels_per_meter(png_structp png_ptr, png_infop info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) +#if defined(PNG_pHYs_SUPPORTED) + if (info_ptr->valid & PNG_INFO_pHYs) + { + png_debug1(1, "in %s retrieval function\n", "png_get_pixels_per_meter"); + if(info_ptr->phys_unit_type != PNG_RESOLUTION_METER || + info_ptr->x_pixels_per_unit != info_ptr->y_pixels_per_unit) + return (0); + else return (info_ptr->x_pixels_per_unit); + } +#else + return (0); +#endif + return (0); +} + +#ifdef PNG_FLOATING_POINT_SUPPORTED +float PNGAPI +png_get_pixel_aspect_ratio(png_structp png_ptr, png_infop info_ptr) + { + if (png_ptr != NULL && info_ptr != NULL) +#if defined(PNG_pHYs_SUPPORTED) + if (info_ptr->valid & PNG_INFO_pHYs) + { + png_debug1(1, "in %s retrieval function\n", "png_get_aspect_ratio"); + if (info_ptr->x_pixels_per_unit == 0) + return ((float)0.0); + else + return ((float)((float)info_ptr->y_pixels_per_unit + /(float)info_ptr->x_pixels_per_unit)); + } +#else + return (0.0); +#endif + return ((float)0.0); +} +#endif + +png_int_32 PNGAPI +png_get_x_offset_microns(png_structp png_ptr, png_infop info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) +#if defined(PNG_oFFs_SUPPORTED) + if (info_ptr->valid & PNG_INFO_oFFs) + { + png_debug1(1, "in %s retrieval function\n", "png_get_x_offset_microns"); + if(info_ptr->offset_unit_type != PNG_OFFSET_MICROMETER) + return (0); + else return (info_ptr->x_offset); + } +#else + return (0); +#endif + return (0); +} + +png_int_32 PNGAPI +png_get_y_offset_microns(png_structp png_ptr, png_infop info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) +#if defined(PNG_oFFs_SUPPORTED) + if (info_ptr->valid & PNG_INFO_oFFs) + { + png_debug1(1, "in %s retrieval function\n", "png_get_y_offset_microns"); + if(info_ptr->offset_unit_type != PNG_OFFSET_MICROMETER) + return (0); + else return (info_ptr->y_offset); + } +#else + return (0); +#endif + return (0); +} + +png_int_32 PNGAPI +png_get_x_offset_pixels(png_structp png_ptr, png_infop info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) +#if defined(PNG_oFFs_SUPPORTED) + if (info_ptr->valid & PNG_INFO_oFFs) + { + png_debug1(1, "in %s retrieval function\n", "png_get_x_offset_microns"); + if(info_ptr->offset_unit_type != PNG_OFFSET_PIXEL) + return (0); + else return (info_ptr->x_offset); + } +#else + return (0); +#endif + return (0); +} + +png_int_32 PNGAPI +png_get_y_offset_pixels(png_structp png_ptr, png_infop info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) +#if defined(PNG_oFFs_SUPPORTED) + if (info_ptr->valid & PNG_INFO_oFFs) + { + png_debug1(1, "in %s retrieval function\n", "png_get_y_offset_microns"); + if(info_ptr->offset_unit_type != PNG_OFFSET_PIXEL) + return (0); + else return (info_ptr->y_offset); + } +#else + return (0); +#endif + return (0); +} + +#if defined(PNG_INCH_CONVERSIONS) && defined(PNG_FLOATING_POINT_SUPPORTED) +png_uint_32 PNGAPI +png_get_pixels_per_inch(png_structp png_ptr, png_infop info_ptr) +{ + return ((png_uint_32)((float)png_get_pixels_per_meter(png_ptr, info_ptr) + *.0254 +.5)); +} + +png_uint_32 PNGAPI +png_get_x_pixels_per_inch(png_structp png_ptr, png_infop info_ptr) +{ + return ((png_uint_32)((float)png_get_x_pixels_per_meter(png_ptr, info_ptr) + *.0254 +.5)); +} + +png_uint_32 PNGAPI +png_get_y_pixels_per_inch(png_structp png_ptr, png_infop info_ptr) +{ + return ((png_uint_32)((float)png_get_y_pixels_per_meter(png_ptr, info_ptr) + *.0254 +.5)); +} + +float PNGAPI +png_get_x_offset_inches(png_structp png_ptr, png_infop info_ptr) +{ + return ((float)png_get_x_offset_microns(png_ptr, info_ptr) + *.00003937); +} + +float PNGAPI +png_get_y_offset_inches(png_structp png_ptr, png_infop info_ptr) +{ + return ((float)png_get_y_offset_microns(png_ptr, info_ptr) + *.00003937); +} + +#if defined(PNG_pHYs_SUPPORTED) +png_uint_32 PNGAPI +png_get_pHYs_dpi(png_structp png_ptr, png_infop info_ptr, + png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type) +{ + png_uint_32 retval = 0; + + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) + { + png_debug1(1, "in %s retrieval function\n", "pHYs"); + if (res_x != NULL) + { + *res_x = info_ptr->x_pixels_per_unit; + retval |= PNG_INFO_pHYs; + } + if (res_y != NULL) + { + *res_y = info_ptr->y_pixels_per_unit; + retval |= PNG_INFO_pHYs; + } + if (unit_type != NULL) + { + *unit_type = (int)info_ptr->phys_unit_type; + retval |= PNG_INFO_pHYs; + if(*unit_type == 1) + { + if (res_x != NULL) *res_x = (png_uint_32)(*res_x * .0254 + .50); + if (res_y != NULL) *res_y = (png_uint_32)(*res_y * .0254 + .50); + } + } + } + return (retval); +} +#endif /* PNG_pHYs_SUPPORTED */ +#endif /* PNG_INCH_CONVERSIONS && PNG_FLOATING_POINT_SUPPORTED */ + +/* png_get_channels really belongs in here, too, but it's been around longer */ + +#endif /* PNG_EASY_ACCESS_SUPPORTED */ + +png_byte PNGAPI +png_get_channels(png_structp png_ptr, png_infop info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) + return(info_ptr->channels); + else + return (0); +} + +png_bytep PNGAPI +png_get_signature(png_structp png_ptr, png_infop info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) + return(info_ptr->signature); + else + return (NULL); +} + +#if defined(PNG_bKGD_SUPPORTED) +png_uint_32 PNGAPI +png_get_bKGD(png_structp png_ptr, png_infop info_ptr, + png_color_16p *background) +{ + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD) + && background != NULL) + { + png_debug1(1, "in %s retrieval function\n", "bKGD"); + *background = &(info_ptr->background); + return (PNG_INFO_bKGD); + } + return (0); +} +#endif + +#if defined(PNG_cHRM_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED +png_uint_32 PNGAPI +png_get_cHRM(png_structp png_ptr, png_infop info_ptr, + double *white_x, double *white_y, double *red_x, double *red_y, + double *green_x, double *green_y, double *blue_x, double *blue_y) +{ + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)) + { + png_debug1(1, "in %s retrieval function\n", "cHRM"); + if (white_x != NULL) + *white_x = (double)info_ptr->x_white; + if (white_y != NULL) + *white_y = (double)info_ptr->y_white; + if (red_x != NULL) + *red_x = (double)info_ptr->x_red; + if (red_y != NULL) + *red_y = (double)info_ptr->y_red; + if (green_x != NULL) + *green_x = (double)info_ptr->x_green; + if (green_y != NULL) + *green_y = (double)info_ptr->y_green; + if (blue_x != NULL) + *blue_x = (double)info_ptr->x_blue; + if (blue_y != NULL) + *blue_y = (double)info_ptr->y_blue; + return (PNG_INFO_cHRM); + } + return (0); +} +#endif +#ifdef PNG_FIXED_POINT_SUPPORTED +png_uint_32 PNGAPI +png_get_cHRM_fixed(png_structp png_ptr, png_infop info_ptr, + png_fixed_point *white_x, png_fixed_point *white_y, png_fixed_point *red_x, + png_fixed_point *red_y, png_fixed_point *green_x, png_fixed_point *green_y, + png_fixed_point *blue_x, png_fixed_point *blue_y) +{ + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)) + { + png_debug1(1, "in %s retrieval function\n", "cHRM"); + if (white_x != NULL) + *white_x = info_ptr->int_x_white; + if (white_y != NULL) + *white_y = info_ptr->int_y_white; + if (red_x != NULL) + *red_x = info_ptr->int_x_red; + if (red_y != NULL) + *red_y = info_ptr->int_y_red; + if (green_x != NULL) + *green_x = info_ptr->int_x_green; + if (green_y != NULL) + *green_y = info_ptr->int_y_green; + if (blue_x != NULL) + *blue_x = info_ptr->int_x_blue; + if (blue_y != NULL) + *blue_y = info_ptr->int_y_blue; + return (PNG_INFO_cHRM); + } + return (0); +} +#endif +#endif + +#if defined(PNG_gAMA_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED +png_uint_32 PNGAPI +png_get_gAMA(png_structp png_ptr, png_infop info_ptr, double *file_gamma) +{ + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA) + && file_gamma != NULL) + { + png_debug1(1, "in %s retrieval function\n", "gAMA"); + *file_gamma = (double)info_ptr->gamma; + return (PNG_INFO_gAMA); + } + return (0); +} +#endif +#ifdef PNG_FIXED_POINT_SUPPORTED +png_uint_32 PNGAPI +png_get_gAMA_fixed(png_structp png_ptr, png_infop info_ptr, + png_fixed_point *int_file_gamma) +{ + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA) + && int_file_gamma != NULL) + { + png_debug1(1, "in %s retrieval function\n", "gAMA"); + *int_file_gamma = info_ptr->int_gamma; + return (PNG_INFO_gAMA); + } + return (0); +} +#endif +#endif + +#if defined(PNG_sRGB_SUPPORTED) +png_uint_32 PNGAPI +png_get_sRGB(png_structp png_ptr, png_infop info_ptr, int *file_srgb_intent) +{ + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB) + && file_srgb_intent != NULL) + { + png_debug1(1, "in %s retrieval function\n", "sRGB"); + *file_srgb_intent = (int)info_ptr->srgb_intent; + return (PNG_INFO_sRGB); + } + return (0); +} +#endif + +#if defined(PNG_iCCP_SUPPORTED) +png_uint_32 PNGAPI +png_get_iCCP(png_structp png_ptr, png_infop info_ptr, + png_charpp name, int *compression_type, + png_charpp profile, png_uint_32 *proflen) +{ + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP) + && name != NULL && profile != NULL && proflen != NULL) + { + png_debug1(1, "in %s retrieval function\n", "iCCP"); + *name = info_ptr->iccp_name; + *profile = info_ptr->iccp_profile; + /* compression_type is a dummy so the API won't have to change + if we introduce multiple compression types later. */ + *proflen = (int)info_ptr->iccp_proflen; + *compression_type = (int)info_ptr->iccp_compression; + return (PNG_INFO_iCCP); + } + return (0); +} +#endif + +#if defined(PNG_sPLT_SUPPORTED) +png_uint_32 PNGAPI +png_get_sPLT(png_structp png_ptr, png_infop info_ptr, + png_sPLT_tpp spalettes) +{ + if (png_ptr != NULL && info_ptr != NULL && spalettes != NULL) + *spalettes = info_ptr->splt_palettes; + return ((png_uint_32)info_ptr->splt_palettes_num); +} +#endif + +#if defined(PNG_hIST_SUPPORTED) +png_uint_32 PNGAPI +png_get_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_16p *hist) +{ + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST) + && hist != NULL) + { + png_debug1(1, "in %s retrieval function\n", "hIST"); + *hist = info_ptr->hist; + return (PNG_INFO_hIST); + } + return (0); +} +#endif + +png_uint_32 PNGAPI +png_get_IHDR(png_structp png_ptr, png_infop info_ptr, + png_uint_32 *width, png_uint_32 *height, int *bit_depth, + int *color_type, int *interlace_type, int *compression_type, + int *filter_type) + +{ + if (png_ptr != NULL && info_ptr != NULL && width != NULL && height != NULL && + bit_depth != NULL && color_type != NULL) + { + png_debug1(1, "in %s retrieval function\n", "IHDR"); + *width = info_ptr->width; + *height = info_ptr->height; + *bit_depth = info_ptr->bit_depth; + if (info_ptr->bit_depth < 1 || info_ptr->bit_depth > 16) + png_error(png_ptr, "Invalid bit depth"); + *color_type = info_ptr->color_type; + if (info_ptr->color_type > 6) + png_error(png_ptr, "Invalid color type"); + if (compression_type != NULL) + *compression_type = info_ptr->compression_type; + if (filter_type != NULL) + *filter_type = info_ptr->filter_type; + if (interlace_type != NULL) + *interlace_type = info_ptr->interlace_type; + + /* check for potential overflow of rowbytes */ + if (*width == 0 || *width > PNG_UINT_31_MAX) + png_error(png_ptr, "Invalid image width"); + if (*height == 0 || *height > PNG_UINT_31_MAX) + png_error(png_ptr, "Invalid image height"); + if (info_ptr->width > (PNG_UINT_32_MAX + >> 3) /* 8-byte RGBA pixels */ + - 64 /* bigrowbuf hack */ + - 1 /* filter byte */ + - 7*8 /* rounding of width to multiple of 8 pixels */ + - 8) /* extra max_pixel_depth pad */ + { + png_warning(png_ptr, + "Width too large for libpng to process image data."); + } + return (1); + } + return (0); +} + +#if defined(PNG_oFFs_SUPPORTED) +png_uint_32 PNGAPI +png_get_oFFs(png_structp png_ptr, png_infop info_ptr, + png_int_32 *offset_x, png_int_32 *offset_y, int *unit_type) +{ + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs) + && offset_x != NULL && offset_y != NULL && unit_type != NULL) + { + png_debug1(1, "in %s retrieval function\n", "oFFs"); + *offset_x = info_ptr->x_offset; + *offset_y = info_ptr->y_offset; + *unit_type = (int)info_ptr->offset_unit_type; + return (PNG_INFO_oFFs); + } + return (0); +} +#endif + +#if defined(PNG_pCAL_SUPPORTED) +png_uint_32 PNGAPI +png_get_pCAL(png_structp png_ptr, png_infop info_ptr, + png_charp *purpose, png_int_32 *X0, png_int_32 *X1, int *type, int *nparams, + png_charp *units, png_charpp *params) +{ + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL) + && purpose != NULL && X0 != NULL && X1 != NULL && type != NULL && + nparams != NULL && units != NULL && params != NULL) + { + png_debug1(1, "in %s retrieval function\n", "pCAL"); + *purpose = info_ptr->pcal_purpose; + *X0 = info_ptr->pcal_X0; + *X1 = info_ptr->pcal_X1; + *type = (int)info_ptr->pcal_type; + *nparams = (int)info_ptr->pcal_nparams; + *units = info_ptr->pcal_units; + *params = info_ptr->pcal_params; + return (PNG_INFO_pCAL); + } + return (0); +} +#endif + +#if defined(PNG_sCAL_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED +png_uint_32 PNGAPI +png_get_sCAL(png_structp png_ptr, png_infop info_ptr, + int *unit, double *width, double *height) +{ + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->valid & PNG_INFO_sCAL)) + { + *unit = info_ptr->scal_unit; + *width = info_ptr->scal_pixel_width; + *height = info_ptr->scal_pixel_height; + return (PNG_INFO_sCAL); + } + return(0); +} +#else +#ifdef PNG_FIXED_POINT_SUPPORTED +png_uint_32 PNGAPI +png_get_sCAL_s(png_structp png_ptr, png_infop info_ptr, + int *unit, png_charpp width, png_charpp height) +{ + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->valid & PNG_INFO_sCAL)) + { + *unit = info_ptr->scal_unit; + *width = info_ptr->scal_s_width; + *height = info_ptr->scal_s_height; + return (PNG_INFO_sCAL); + } + return(0); +} +#endif +#endif +#endif + +#if defined(PNG_pHYs_SUPPORTED) +png_uint_32 PNGAPI +png_get_pHYs(png_structp png_ptr, png_infop info_ptr, + png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type) +{ + png_uint_32 retval = 0; + + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->valid & PNG_INFO_pHYs)) + { + png_debug1(1, "in %s retrieval function\n", "pHYs"); + if (res_x != NULL) + { + *res_x = info_ptr->x_pixels_per_unit; + retval |= PNG_INFO_pHYs; + } + if (res_y != NULL) + { + *res_y = info_ptr->y_pixels_per_unit; + retval |= PNG_INFO_pHYs; + } + if (unit_type != NULL) + { + *unit_type = (int)info_ptr->phys_unit_type; + retval |= PNG_INFO_pHYs; + } + } + return (retval); +} +#endif + +png_uint_32 PNGAPI +png_get_PLTE(png_structp png_ptr, png_infop info_ptr, png_colorp *palette, + int *num_palette) +{ + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_PLTE) + && palette != NULL) + { + png_debug1(1, "in %s retrieval function\n", "PLTE"); + *palette = info_ptr->palette; + *num_palette = info_ptr->num_palette; + png_debug1(3, "num_palette = %d\n", *num_palette); + return (PNG_INFO_PLTE); + } + return (0); +} + +#if defined(PNG_sBIT_SUPPORTED) +png_uint_32 PNGAPI +png_get_sBIT(png_structp png_ptr, png_infop info_ptr, png_color_8p *sig_bit) +{ + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT) + && sig_bit != NULL) + { + png_debug1(1, "in %s retrieval function\n", "sBIT"); + *sig_bit = &(info_ptr->sig_bit); + return (PNG_INFO_sBIT); + } + return (0); +} +#endif + +#if defined(PNG_TEXT_SUPPORTED) +png_uint_32 PNGAPI +png_get_text(png_structp png_ptr, png_infop info_ptr, png_textp *text_ptr, + int *num_text) +{ + if (png_ptr != NULL && info_ptr != NULL && info_ptr->num_text > 0) + { + png_debug1(1, "in %s retrieval function\n", + (png_ptr->chunk_name[0] == '\0' ? "text" + : (png_const_charp)png_ptr->chunk_name)); + if (text_ptr != NULL) + *text_ptr = info_ptr->text; + if (num_text != NULL) + *num_text = info_ptr->num_text; + return ((png_uint_32)info_ptr->num_text); + } + if (num_text != NULL) + *num_text = 0; + return(0); +} +#endif + +#if defined(PNG_tIME_SUPPORTED) +png_uint_32 PNGAPI +png_get_tIME(png_structp png_ptr, png_infop info_ptr, png_timep *mod_time) +{ + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME) + && mod_time != NULL) + { + png_debug1(1, "in %s retrieval function\n", "tIME"); + *mod_time = &(info_ptr->mod_time); + return (PNG_INFO_tIME); + } + return (0); +} +#endif + +#if defined(PNG_tRNS_SUPPORTED) +png_uint_32 PNGAPI +png_get_tRNS(png_structp png_ptr, png_infop info_ptr, + png_bytep *trans, int *num_trans, png_color_16p *trans_values) +{ + png_uint_32 retval = 0; + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS)) + { + png_debug1(1, "in %s retrieval function\n", "tRNS"); + if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { + if (trans != NULL) + { + *trans = info_ptr->trans; + retval |= PNG_INFO_tRNS; + } + if (trans_values != NULL) + *trans_values = &(info_ptr->trans_values); + } + else /* if (info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) */ + { + if (trans_values != NULL) + { + *trans_values = &(info_ptr->trans_values); + retval |= PNG_INFO_tRNS; + } + if(trans != NULL) + *trans = NULL; + } + if(num_trans != NULL) + { + *num_trans = info_ptr->num_trans; + retval |= PNG_INFO_tRNS; + } + } + return (retval); +} +#endif + +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) +png_uint_32 PNGAPI +png_get_unknown_chunks(png_structp png_ptr, png_infop info_ptr, + png_unknown_chunkpp unknowns) +{ + if (png_ptr != NULL && info_ptr != NULL && unknowns != NULL) + *unknowns = info_ptr->unknown_chunks; + return ((png_uint_32)info_ptr->unknown_chunks_num); +} +#endif + +#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) +png_byte PNGAPI +png_get_rgb_to_gray_status (png_structp png_ptr) +{ + return (png_byte)(png_ptr? png_ptr->rgb_to_gray_status : 0); +} +#endif + +#if defined(PNG_USER_CHUNKS_SUPPORTED) +png_voidp PNGAPI +png_get_user_chunk_ptr(png_structp png_ptr) +{ + return (png_ptr? png_ptr->user_chunk_ptr : NULL); +} +#endif + +#ifdef PNG_WRITE_SUPPORTED +png_uint_32 PNGAPI +png_get_compression_buffer_size(png_structp png_ptr) +{ + return (png_uint_32)(png_ptr? png_ptr->zbuf_size : 0L); +} +#endif + +#ifndef PNG_1_0_X +#ifdef PNG_ASSEMBLER_CODE_SUPPORTED +/* this function was added to libpng 1.2.0 and should exist by default */ +png_uint_32 PNGAPI +png_get_asm_flags (png_structp png_ptr) +{ + return (png_uint_32)(png_ptr? png_ptr->asm_flags : 0L); +} + +/* this function was added to libpng 1.2.0 and should exist by default */ +png_uint_32 PNGAPI +png_get_asm_flagmask (int flag_select) +{ + png_uint_32 settable_asm_flags = 0; + + if (flag_select & PNG_SELECT_READ) + settable_asm_flags |= + PNG_ASM_FLAG_MMX_READ_COMBINE_ROW | + PNG_ASM_FLAG_MMX_READ_INTERLACE | + PNG_ASM_FLAG_MMX_READ_FILTER_SUB | + PNG_ASM_FLAG_MMX_READ_FILTER_UP | + PNG_ASM_FLAG_MMX_READ_FILTER_AVG | + PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ; + /* no non-MMX flags yet */ + +#if 0 + /* GRR: no write-flags yet, either, but someday... */ + if (flag_select & PNG_SELECT_WRITE) + settable_asm_flags |= + PNG_ASM_FLAG_MMX_WRITE_ [whatever] ; +#endif /* 0 */ + + return settable_asm_flags; /* _theoretically_ settable capabilities only */ +} +#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ + + +#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) + /* GRR: could add this: && defined(PNG_MMX_CODE_SUPPORTED) */ +/* this function was added to libpng 1.2.0 */ +png_uint_32 PNGAPI +png_get_mmx_flagmask (int flag_select, int *compilerID) +{ + png_uint_32 settable_mmx_flags = 0; + + if (flag_select & PNG_SELECT_READ) + settable_mmx_flags |= + PNG_ASM_FLAG_MMX_READ_COMBINE_ROW | + PNG_ASM_FLAG_MMX_READ_INTERLACE | + PNG_ASM_FLAG_MMX_READ_FILTER_SUB | + PNG_ASM_FLAG_MMX_READ_FILTER_UP | + PNG_ASM_FLAG_MMX_READ_FILTER_AVG | + PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ; +#if 0 + /* GRR: no MMX write support yet, but someday... */ + if (flag_select & PNG_SELECT_WRITE) + settable_mmx_flags |= + PNG_ASM_FLAG_MMX_WRITE_ [whatever] ; +#endif /* 0 */ + + if (compilerID != NULL) { +#ifdef PNG_USE_PNGVCRD + *compilerID = 1; /* MSVC */ +#else +#ifdef PNG_USE_PNGGCCRD + *compilerID = 2; /* gcc/gas */ +#else + *compilerID = -1; /* unknown (i.e., no asm/MMX code compiled) */ +#endif +#endif + } + + return settable_mmx_flags; /* _theoretically_ settable capabilities only */ +} + +/* this function was added to libpng 1.2.0 */ +png_byte PNGAPI +png_get_mmx_bitdepth_threshold (png_structp png_ptr) +{ + return (png_byte)(png_ptr? png_ptr->mmx_bitdepth_threshold : 0); +} + +/* this function was added to libpng 1.2.0 */ +png_uint_32 PNGAPI +png_get_mmx_rowbytes_threshold (png_structp png_ptr) +{ + return (png_uint_32)(png_ptr? png_ptr->mmx_rowbytes_threshold : 0L); +} +#endif /* ?PNG_ASSEMBLER_CODE_SUPPORTED */ +#endif /* ?PNG_1_0_X */ + +#ifdef PNG_SET_USER_LIMITS_SUPPORTED +/* these functions were added to libpng 1.2.6 */ +png_uint_32 PNGAPI +png_get_user_width_max (png_structp png_ptr) +{ + return (png_ptr? png_ptr->user_width_max : 0); +} +png_uint_32 PNGAPI +png_get_user_height_max (png_structp png_ptr) +{ + return (png_ptr? png_ptr->user_height_max : 0); +} +#endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */ + +#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */ diff --git a/mod/pub.mod/libpng.mod/pngmem.c b/mod/pub.mod/libpng.mod/pngmem.c new file mode 100644 index 0000000..cfe3e0f --- /dev/null +++ b/mod/pub.mod/libpng.mod/pngmem.c @@ -0,0 +1,598 @@ + +/* pngmem.c - stub functions for memory allocation + * + * Last changed in libpng 1.2.9 April 14, 2006 + * For conditions of distribution and use, see copyright notice in png.h + * Copyright (c) 1998-2006 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * + * This file provides a location for all memory allocation. Users who + * need special memory handling are expected to supply replacement + * functions for png_malloc() and png_free(), and to use + * png_create_read_struct_2() and png_create_write_struct_2() to + * identify the replacement functions. + */ + +#define PNG_INTERNAL +#include "png.h" + +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) + +/* Borland DOS special memory handler */ +#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__) +/* if you change this, be sure to change the one in png.h also */ + +/* Allocate memory for a png_struct. The malloc and memset can be replaced + by a single call to calloc() if this is thought to improve performance. */ +png_voidp /* PRIVATE */ +png_create_struct(int type) +{ +#ifdef PNG_USER_MEM_SUPPORTED + return (png_create_struct_2(type, png_malloc_ptr_NULL, png_voidp_NULL)); +} + +/* Alternate version of png_create_struct, for use with user-defined malloc. */ +png_voidp /* PRIVATE */ +png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr) +{ +#endif /* PNG_USER_MEM_SUPPORTED */ + png_size_t size; + png_voidp struct_ptr; + + if (type == PNG_STRUCT_INFO) + size = png_sizeof(png_info); + else if (type == PNG_STRUCT_PNG) + size = png_sizeof(png_struct); + else + return (png_get_copyright(NULL)); + +#ifdef PNG_USER_MEM_SUPPORTED + if(malloc_fn != NULL) + { + png_struct dummy_struct; + png_structp png_ptr = &dummy_struct; + png_ptr->mem_ptr=mem_ptr; + struct_ptr = (*(malloc_fn))(png_ptr, (png_uint_32)size); + } + else +#endif /* PNG_USER_MEM_SUPPORTED */ + struct_ptr = (png_voidp)farmalloc(size); + if (struct_ptr != NULL) + png_memset(struct_ptr, 0, size); + return (struct_ptr); +} + +/* Free memory allocated by a png_create_struct() call */ +void /* PRIVATE */ +png_destroy_struct(png_voidp struct_ptr) +{ +#ifdef PNG_USER_MEM_SUPPORTED + png_destroy_struct_2(struct_ptr, png_free_ptr_NULL, png_voidp_NULL); +} + +/* Free memory allocated by a png_create_struct() call */ +void /* PRIVATE */ +png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn, + png_voidp mem_ptr) +{ +#endif + if (struct_ptr != NULL) + { +#ifdef PNG_USER_MEM_SUPPORTED + if(free_fn != NULL) + { + png_struct dummy_struct; + png_structp png_ptr = &dummy_struct; + png_ptr->mem_ptr=mem_ptr; + (*(free_fn))(png_ptr, struct_ptr); + return; + } +#endif /* PNG_USER_MEM_SUPPORTED */ + farfree (struct_ptr); + } +} + +/* Allocate memory. For reasonable files, size should never exceed + * 64K. However, zlib may allocate more then 64K if you don't tell + * it not to. See zconf.h and png.h for more information. zlib does + * need to allocate exactly 64K, so whatever you call here must + * have the ability to do that. + * + * Borland seems to have a problem in DOS mode for exactly 64K. + * It gives you a segment with an offset of 8 (perhaps to store its + * memory stuff). zlib doesn't like this at all, so we have to + * detect and deal with it. This code should not be needed in + * Windows or OS/2 modes, and only in 16 bit mode. This code has + * been updated by Alexander Lehmann for version 0.89 to waste less + * memory. + * + * Note that we can't use png_size_t for the "size" declaration, + * since on some systems a png_size_t is a 16-bit quantity, and as a + * result, we would be truncating potentially larger memory requests + * (which should cause a fatal error) and introducing major problems. + */ + +png_voidp PNGAPI +png_malloc(png_structp png_ptr, png_uint_32 size) +{ + png_voidp ret; + + if (png_ptr == NULL || size == 0) + return (NULL); + +#ifdef PNG_USER_MEM_SUPPORTED + if(png_ptr->malloc_fn != NULL) + ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size)); + else + ret = (png_malloc_default(png_ptr, size)); + if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) + png_error(png_ptr, "Out of memory!"); + return (ret); +} + +png_voidp PNGAPI +png_malloc_default(png_structp png_ptr, png_uint_32 size) +{ + png_voidp ret; +#endif /* PNG_USER_MEM_SUPPORTED */ + +#ifdef PNG_MAX_MALLOC_64K + if (size > (png_uint_32)65536L) + { + png_warning(png_ptr, "Cannot Allocate > 64K"); + ret = NULL; + } + else +#endif + + if (size != (size_t)size) + ret = NULL; + else if (size == (png_uint_32)65536L) + { + if (png_ptr->offset_table == NULL) + { + /* try to see if we need to do any of this fancy stuff */ + ret = farmalloc(size); + if (ret == NULL || ((png_size_t)ret & 0xffff)) + { + int num_blocks; + png_uint_32 total_size; + png_bytep table; + int i; + png_byte huge * hptr; + + if (ret != NULL) + { + farfree(ret); + ret = NULL; + } + + if(png_ptr->zlib_window_bits > 14) + num_blocks = (int)(1 << (png_ptr->zlib_window_bits - 14)); + else + num_blocks = 1; + if (png_ptr->zlib_mem_level >= 7) + num_blocks += (int)(1 << (png_ptr->zlib_mem_level - 7)); + else + num_blocks++; + + total_size = ((png_uint_32)65536L) * (png_uint_32)num_blocks+16; + + table = farmalloc(total_size); + + if (table == NULL) + { +#ifndef PNG_USER_MEM_SUPPORTED + if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) + png_error(png_ptr, "Out Of Memory."); /* Note "O" and "M" */ + else + png_warning(png_ptr, "Out Of Memory."); +#endif + return (NULL); + } + + if ((png_size_t)table & 0xfff0) + { +#ifndef PNG_USER_MEM_SUPPORTED + if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) + png_error(png_ptr, + "Farmalloc didn't return normalized pointer"); + else + png_warning(png_ptr, + "Farmalloc didn't return normalized pointer"); +#endif + return (NULL); + } + + png_ptr->offset_table = table; + png_ptr->offset_table_ptr = farmalloc(num_blocks * + png_sizeof (png_bytep)); + + if (png_ptr->offset_table_ptr == NULL) + { +#ifndef PNG_USER_MEM_SUPPORTED + if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) + png_error(png_ptr, "Out Of memory."); /* Note "O" and "M" */ + else + png_warning(png_ptr, "Out Of memory."); +#endif + return (NULL); + } + + hptr = (png_byte huge *)table; + if ((png_size_t)hptr & 0xf) + { + hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L); + hptr = hptr + 16L; /* "hptr += 16L" fails on Turbo C++ 3.0 */ + } + for (i = 0; i < num_blocks; i++) + { + png_ptr->offset_table_ptr[i] = (png_bytep)hptr; + hptr = hptr + (png_uint_32)65536L; /* "+=" fails on TC++3.0 */ + } + + png_ptr->offset_table_number = num_blocks; + png_ptr->offset_table_count = 0; + png_ptr->offset_table_count_free = 0; + } + } + + if (png_ptr->offset_table_count >= png_ptr->offset_table_number) + { +#ifndef PNG_USER_MEM_SUPPORTED + if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) + png_error(png_ptr, "Out of Memory."); /* Note "o" and "M" */ + else + png_warning(png_ptr, "Out of Memory."); +#endif + return (NULL); + } + + ret = png_ptr->offset_table_ptr[png_ptr->offset_table_count++]; + } + else + ret = farmalloc(size); + +#ifndef PNG_USER_MEM_SUPPORTED + if (ret == NULL) + { + if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) + png_error(png_ptr, "Out of memory."); /* Note "o" and "m" */ + else + png_warning(png_ptr, "Out of memory."); /* Note "o" and "m" */ + } +#endif + + return (ret); +} + +/* free a pointer allocated by png_malloc(). In the default + configuration, png_ptr is not used, but is passed in case it + is needed. If ptr is NULL, return without taking any action. */ +void PNGAPI +png_free(png_structp png_ptr, png_voidp ptr) +{ + if (png_ptr == NULL || ptr == NULL) + return; + +#ifdef PNG_USER_MEM_SUPPORTED + if (png_ptr->free_fn != NULL) + { + (*(png_ptr->free_fn))(png_ptr, ptr); + return; + } + else png_free_default(png_ptr, ptr); +} + +void PNGAPI +png_free_default(png_structp png_ptr, png_voidp ptr) +{ +#endif /* PNG_USER_MEM_SUPPORTED */ + + if (png_ptr->offset_table != NULL) + { + int i; + + for (i = 0; i < png_ptr->offset_table_count; i++) + { + if (ptr == png_ptr->offset_table_ptr[i]) + { + ptr = NULL; + png_ptr->offset_table_count_free++; + break; + } + } + if (png_ptr->offset_table_count_free == png_ptr->offset_table_count) + { + farfree(png_ptr->offset_table); + farfree(png_ptr->offset_table_ptr); + png_ptr->offset_table = NULL; + png_ptr->offset_table_ptr = NULL; + } + } + + if (ptr != NULL) + { + farfree(ptr); + } +} + +#else /* Not the Borland DOS special memory handler */ + +/* Allocate memory for a png_struct or a png_info. The malloc and + memset can be replaced by a single call to calloc() if this is thought + to improve performance noticably. */ +png_voidp /* PRIVATE */ +png_create_struct(int type) +{ +#ifdef PNG_USER_MEM_SUPPORTED + return (png_create_struct_2(type, png_malloc_ptr_NULL, png_voidp_NULL)); +} + +/* Allocate memory for a png_struct or a png_info. The malloc and + memset can be replaced by a single call to calloc() if this is thought + to improve performance noticably. */ +png_voidp /* PRIVATE */ +png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr) +{ +#endif /* PNG_USER_MEM_SUPPORTED */ + png_size_t size; + png_voidp struct_ptr; + + if (type == PNG_STRUCT_INFO) + size = png_sizeof(png_info); + else if (type == PNG_STRUCT_PNG) + size = png_sizeof(png_struct); + else + return (NULL); + +#ifdef PNG_USER_MEM_SUPPORTED + if(malloc_fn != NULL) + { + png_struct dummy_struct; + png_structp png_ptr = &dummy_struct; + png_ptr->mem_ptr=mem_ptr; + struct_ptr = (*(malloc_fn))(png_ptr, size); + if (struct_ptr != NULL) + png_memset(struct_ptr, 0, size); + return (struct_ptr); + } +#endif /* PNG_USER_MEM_SUPPORTED */ + +#if defined(__TURBOC__) && !defined(__FLAT__) + struct_ptr = (png_voidp)farmalloc(size); +#else +# if defined(_MSC_VER) && defined(MAXSEG_64K) + struct_ptr = (png_voidp)halloc(size,1); +# else + struct_ptr = (png_voidp)malloc(size); +# endif +#endif + if (struct_ptr != NULL) + png_memset(struct_ptr, 0, size); + + return (struct_ptr); +} + + +/* Free memory allocated by a png_create_struct() call */ +void /* PRIVATE */ +png_destroy_struct(png_voidp struct_ptr) +{ +#ifdef PNG_USER_MEM_SUPPORTED + png_destroy_struct_2(struct_ptr, png_free_ptr_NULL, png_voidp_NULL); +} + +/* Free memory allocated by a png_create_struct() call */ +void /* PRIVATE */ +png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn, + png_voidp mem_ptr) +{ +#endif /* PNG_USER_MEM_SUPPORTED */ + if (struct_ptr != NULL) + { +#ifdef PNG_USER_MEM_SUPPORTED + if(free_fn != NULL) + { + png_struct dummy_struct; + png_structp png_ptr = &dummy_struct; + png_ptr->mem_ptr=mem_ptr; + (*(free_fn))(png_ptr, struct_ptr); + return; + } +#endif /* PNG_USER_MEM_SUPPORTED */ +#if defined(__TURBOC__) && !defined(__FLAT__) + farfree(struct_ptr); +#else +# if defined(_MSC_VER) && defined(MAXSEG_64K) + hfree(struct_ptr); +# else + free(struct_ptr); +# endif +#endif + } +} + +/* Allocate memory. For reasonable files, size should never exceed + 64K. However, zlib may allocate more then 64K if you don't tell + it not to. See zconf.h and png.h for more information. zlib does + need to allocate exactly 64K, so whatever you call here must + have the ability to do that. */ + +png_voidp PNGAPI +png_malloc(png_structp png_ptr, png_uint_32 size) +{ + png_voidp ret; + +#ifdef PNG_USER_MEM_SUPPORTED + if (png_ptr == NULL || size == 0) + return (NULL); + + if(png_ptr->malloc_fn != NULL) + ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size)); + else + ret = (png_malloc_default(png_ptr, size)); + if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) + png_error(png_ptr, "Out of Memory!"); + return (ret); +} + +png_voidp PNGAPI +png_malloc_default(png_structp png_ptr, png_uint_32 size) +{ + png_voidp ret; +#endif /* PNG_USER_MEM_SUPPORTED */ + + if (png_ptr == NULL || size == 0) + return (NULL); + +#ifdef PNG_MAX_MALLOC_64K + if (size > (png_uint_32)65536L) + { +#ifndef PNG_USER_MEM_SUPPORTED + if(png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) + png_error(png_ptr, "Cannot Allocate > 64K"); + else +#endif + return NULL; + } +#endif + + /* Check for overflow */ +#if defined(__TURBOC__) && !defined(__FLAT__) + if (size != (unsigned long)size) + ret = NULL; + else + ret = farmalloc(size); +#else +# if defined(_MSC_VER) && defined(MAXSEG_64K) + if (size != (unsigned long)size) + ret = NULL; + else + ret = halloc(size, 1); +# else + if (size != (size_t)size) + ret = NULL; + else + ret = malloc((size_t)size); +# endif +#endif + +#ifndef PNG_USER_MEM_SUPPORTED + if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) + png_error(png_ptr, "Out of Memory"); +#endif + + return (ret); +} + +/* Free a pointer allocated by png_malloc(). If ptr is NULL, return + without taking any action. */ +void PNGAPI +png_free(png_structp png_ptr, png_voidp ptr) +{ + if (png_ptr == NULL || ptr == NULL) + return; + +#ifdef PNG_USER_MEM_SUPPORTED + if (png_ptr->free_fn != NULL) + { + (*(png_ptr->free_fn))(png_ptr, ptr); + return; + } + else png_free_default(png_ptr, ptr); +} +void PNGAPI +png_free_default(png_structp png_ptr, png_voidp ptr) +{ + if (png_ptr == NULL || ptr == NULL) + return; + +#endif /* PNG_USER_MEM_SUPPORTED */ + +#if defined(__TURBOC__) && !defined(__FLAT__) + farfree(ptr); +#else +# if defined(_MSC_VER) && defined(MAXSEG_64K) + hfree(ptr); +# else + free(ptr); +# endif +#endif +} + +#endif /* Not Borland DOS special memory handler */ + +#if defined(PNG_1_0_X) +# define png_malloc_warn png_malloc +#else +/* This function was added at libpng version 1.2.3. The png_malloc_warn() + * function will set up png_malloc() to issue a png_warning and return NULL + * instead of issuing a png_error, if it fails to allocate the requested + * memory. + */ +png_voidp PNGAPI +png_malloc_warn(png_structp png_ptr, png_uint_32 size) +{ + png_voidp ptr; + png_uint_32 save_flags=png_ptr->flags; + + png_ptr->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK; + ptr = (png_voidp)png_malloc((png_structp)png_ptr, size); + png_ptr->flags=save_flags; + return(ptr); +} +#endif + +png_voidp PNGAPI +png_memcpy_check (png_structp png_ptr, png_voidp s1, png_voidp s2, + png_uint_32 length) +{ + png_size_t size; + + size = (png_size_t)length; + if ((png_uint_32)size != length) + png_error(png_ptr,"Overflow in png_memcpy_check."); + + return(png_memcpy (s1, s2, size)); +} + +png_voidp PNGAPI +png_memset_check (png_structp png_ptr, png_voidp s1, int value, + png_uint_32 length) +{ + png_size_t size; + + size = (png_size_t)length; + if ((png_uint_32)size != length) + png_error(png_ptr,"Overflow in png_memset_check."); + + return (png_memset (s1, value, size)); + +} + +#ifdef PNG_USER_MEM_SUPPORTED +/* This function is called when the application wants to use another method + * of allocating and freeing memory. + */ +void PNGAPI +png_set_mem_fn(png_structp png_ptr, png_voidp mem_ptr, png_malloc_ptr + malloc_fn, png_free_ptr free_fn) +{ + png_ptr->mem_ptr = mem_ptr; + png_ptr->malloc_fn = malloc_fn; + png_ptr->free_fn = free_fn; +} + +/* This function returns a pointer to the mem_ptr associated with the user + * functions. The application should free any memory associated with this + * pointer before png_write_destroy and png_read_destroy are called. + */ +png_voidp PNGAPI +png_get_mem_ptr(png_structp png_ptr) +{ + return ((png_voidp)png_ptr->mem_ptr); +} +#endif /* PNG_USER_MEM_SUPPORTED */ +#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */ diff --git a/mod/pub.mod/libpng.mod/pngnow.png b/mod/pub.mod/libpng.mod/pngnow.png new file mode 100644 index 0000000000000000000000000000000000000000..82793ebddb7863266a66ffc6ab2c01ca32100808 GIT binary patch literal 2069 zcmWkudpuN&7T#y<o7ZOO?uNrAM`M(Bqr(m{w;MC#)h4E)!`WVA8`6x?7}PYRX;947 zYi{S{OgK0lO7ci3y*zsHQ=-nPq!KFhKE-q<-MN3P^{sFHv3}ogt?#$?MT7@gnAw>D z0ALXk%;6bOV2GtAMuxod+KXid08{<L`~jeOzqvl?9|rzS7B46OXdFad8i-SJFfR-M z<O~2PPyxVaL#yBg0A#NQfayd4@ckJ8Y%;ayB3S@HNs7SvT>XL`q<{m10|OLLYbYp~ zqD01zCx~<rUrv(wDk5D$q|5jM66ZCL!U?@lJK%v40urR?F^^gO;DEkd3z<P`DT;f* zbW2DU03*(HI>Qa;aTH3$83tYNL5@^&dW%qu3E?~lv;*N57-E2|bs(K#(iIEOmeFx% zkcfvMOG`)&LHQ673#pIPl0s5bu0h@0>CO<}7a`Ws2_Xc#K~M$^F+q|Eqco5dLWna2 z#X^t(LKq<CfuKw}ClE(yFyaW(-Bw|~ESLu3p*T$Y7F)*w7lEWeq&if~k4?s73B-|( z*dauG8XiqR6cA-%WR8LmN>oD8nRJmzN=KPsmsFupvRG!&XgFV8A;Y6t95Zm1LFa^q z^92erLk2B|aULIYLrE_dC!DV+A~6Qa3B~AUAmL0W(=n6@Y2+%tkPyj9RsagyA*csN zrps7?xTc~3G=mlSYRm(ZDb=D31>#001TxH*!;$k@LY&S-QNy%At*T6qc|mvuj(MT{ zShXyF6!Ad#Eru11piDK&6sbyVIXSpO33CD<Rv>}%6q-XYOk*K|bUdDgx`AW{hwjYa zM<-xjEZA^`|H~$2a<yJa!izz~5#h&^EZ_Br9ZCp9Bn@UQwo=%^Fa^ZSKoJdw93i?R zsHMS*90*wis%Wt02+Z<@dL8LF4eoNLql-X=974??RnY<15)?@bMCpna%>>8bLQKZ} zLB^Jd#VHvwfGx?~A>ERiCUg3J?OJcAAZbdf6Hk&Nk_fY$mS?2o%GPH}1d{E{WQll1 z=-8g42GdW4aQykf``V&Q6W}O#EGzZC`E*NWZcMk35*qfRc}Z6Nnc{k=W$S9olPI;+ z@nk_TpA-koOx36tuc^5+8y2dJKCX$4z2CENV(>!in*_$fq1N2jW1W6k7j=WW!K2we zQx6hfTZ3TdyW^y&(Mek}jvhFo%!~{*FP%!sE17a%?j{}9boS=;RS0g0Vl+OX*4!KG zS9cV3_T@Rcztag#Ba8Akz?VEN{KY|&-cj^8X4hI9rOS7jb^I*rs9{W6y2#E2G^qzi zdmWmqMl3bFs8=?8X$*f<{;;}lLq<aErk&T0<vw!gcs_PHFT^CBy}c_N_r3dVI6}4g z^`o@-<+%=%TyDgFDO@$rrLyk}mG#4Uk&aDuZ>--wF|=g=DWXjt<5enf565lt)AmHV zIxOb73llA}$8Ct~8-~_=j#_ZB`OnsJr4>ai);+T_!|ZPhrkXB?{B)};+#9l2+7C4G z(7Hc=^#UXHmZ|>h%+um(yvmbWw|yz{+FO@id!cP~py}<7RoWpJ*Fa-`$lS+tJjBR& z6tlD4Ti8JxCZ<oj)kn9)bof1rv#;FCx_{x_in-y^iXBI|-s0CUv$^L#cmH?@ZR{bd zZcC*@8`~R~ZqInDE4TUU-c6h0`1Jdq-rru?yt$pazl-MSV%}d`@-e2haCu#{-pB9Z zFgh~tgcZLid*3@_-=KRCek#Q_C;Q_`peOE&m%00*n`~Ql4DV)LA0b%6K&Z}MO{!H7 zrq0=w9+^+9lf+9J;#VnyYbA3P-ebu9zoVBc_t}QsEu@+o<yi+p$JXpcu9-X=YBycV zov4eT?b{}JUfuf!UD1Do+vUA5cu|lHMZYe7ZDjoTUmX`d-Cmfhx;k6hY5weN_0<a( z1%j<BimGtf_@4>9NMtT44qLLkP~+BFVn!|dbm^=AtK$C64)M~7nwq6^V!syIo2Oxw z>Q`G3RCIQRk}|{IuYEXq#p2PEEha{j+{?DX0X|%93;f$J-{g|;y0D)gO{G>+cUcD` z4y@ax<21CZK45QAznB)#Ufr}OXGc|jX9Ltdv+b8XbyW6-6`@zUuVY!hSGtpO`!`Qz z&NQEk%buN|_~W2YVMOhus;$a%yh2m*KG^m|>9yn4nuBHYyEpCJ)0$=<bSQ^;97(x3 zqVa4$=elgzb>kK9Wtr0td+%|?D^-C{{MH<3%xF3Nr{}sKhiFd5L0;yj%{mN`D2E@j zb9elGv{mRmpa=e4(SIT%(x!E1a$=RXWcVrny?jLXA=RCjub+PYvh*imzV73lzO2;z z^IhX}vi&XOSKIaiO6bz9{*4VIPX4pcSiyJsOr)&7MIV0tt;fiC&DW%|Q{u`km5!dp z!Uvmke~-D&46c>G#Z1ofQ!2y69!2#V?{T-pgjb1Z<)$Z0{jJ!Cd*WSVOiYG2O~X$e zkOZV!x9`)jqV>P+UU{SXLBcfJe~UZ${fApm5?rT^HZwk-)*@r4(symdMMs05ch4L& zKD%kQ5%->$aqgk4nHpEI84+blJ(2ds3O8Z;4>JTe4@PSyKg=thMLwxcsc|nVEJ)aH z*B04qWpUia=q@`HDRXoAnzt<~x%EzDW7^4`nuh7CO5MicxId`hJsvyinB5bmk2>6A rInt*5>ynshr7qiTo&3Aj@9hWbNS~fK{3iQ`;bQ_J+;C1~K%(-0k;znQ literal 0 HcmV?d00001 diff --git a/mod/pub.mod/libpng.mod/pngpread.c b/mod/pub.mod/libpng.mod/pngpread.c new file mode 100644 index 0000000..7a0d13a --- /dev/null +++ b/mod/pub.mod/libpng.mod/pngpread.c @@ -0,0 +1,1578 @@ + +/* pngpread.c - read a png file in push mode + * + * Last changed in libpng 1.2.11 - June 7, 2004 + * For conditions of distribution and use, see copyright notice in png.h + * Copyright (c) 1998-2006 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + */ + +#define PNG_INTERNAL +#include "png.h" + +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED + +/* push model modes */ +#define PNG_READ_SIG_MODE 0 +#define PNG_READ_CHUNK_MODE 1 +#define PNG_READ_IDAT_MODE 2 +#define PNG_SKIP_MODE 3 +#define PNG_READ_tEXt_MODE 4 +#define PNG_READ_zTXt_MODE 5 +#define PNG_READ_DONE_MODE 6 +#define PNG_READ_iTXt_MODE 7 +#define PNG_ERROR_MODE 8 + +void PNGAPI +png_process_data(png_structp png_ptr, png_infop info_ptr, + png_bytep buffer, png_size_t buffer_size) +{ + png_push_restore_buffer(png_ptr, buffer, buffer_size); + + while (png_ptr->buffer_size) + { + png_process_some_data(png_ptr, info_ptr); + } +} + +/* What we do with the incoming data depends on what we were previously + * doing before we ran out of data... + */ +void /* PRIVATE */ +png_process_some_data(png_structp png_ptr, png_infop info_ptr) +{ + switch (png_ptr->process_mode) + { + case PNG_READ_SIG_MODE: + { + png_push_read_sig(png_ptr, info_ptr); + break; + } + case PNG_READ_CHUNK_MODE: + { + png_push_read_chunk(png_ptr, info_ptr); + break; + } + case PNG_READ_IDAT_MODE: + { + png_push_read_IDAT(png_ptr); + break; + } +#if defined(PNG_READ_tEXt_SUPPORTED) + case PNG_READ_tEXt_MODE: + { + png_push_read_tEXt(png_ptr, info_ptr); + break; + } +#endif +#if defined(PNG_READ_zTXt_SUPPORTED) + case PNG_READ_zTXt_MODE: + { + png_push_read_zTXt(png_ptr, info_ptr); + break; + } +#endif +#if defined(PNG_READ_iTXt_SUPPORTED) + case PNG_READ_iTXt_MODE: + { + png_push_read_iTXt(png_ptr, info_ptr); + break; + } +#endif + case PNG_SKIP_MODE: + { + png_push_crc_finish(png_ptr); + break; + } + default: + { + png_ptr->buffer_size = 0; + break; + } + } +} + +/* Read any remaining signature bytes from the stream and compare them with + * the correct PNG signature. It is possible that this routine is called + * with bytes already read from the signature, either because they have been + * checked by the calling application, or because of multiple calls to this + * routine. + */ +void /* PRIVATE */ +png_push_read_sig(png_structp png_ptr, png_infop info_ptr) +{ + png_size_t num_checked = png_ptr->sig_bytes, + num_to_check = 8 - num_checked; + + if (png_ptr->buffer_size < num_to_check) + { + num_to_check = png_ptr->buffer_size; + } + + png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]), + num_to_check); + png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes+num_to_check); + + if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check)) + { + if (num_checked < 4 && + png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4)) + png_error(png_ptr, "Not a PNG file"); + else + png_error(png_ptr, "PNG file corrupted by ASCII conversion"); + } + else + { + if (png_ptr->sig_bytes >= 8) + { + png_ptr->process_mode = PNG_READ_CHUNK_MODE; + } + } +} + +void /* PRIVATE */ +png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_IHDR; + PNG_IDAT; + PNG_IEND; + PNG_PLTE; +#if defined(PNG_READ_bKGD_SUPPORTED) + PNG_bKGD; +#endif +#if defined(PNG_READ_cHRM_SUPPORTED) + PNG_cHRM; +#endif +#if defined(PNG_READ_gAMA_SUPPORTED) + PNG_gAMA; +#endif +#if defined(PNG_READ_hIST_SUPPORTED) + PNG_hIST; +#endif +#if defined(PNG_READ_iCCP_SUPPORTED) + PNG_iCCP; +#endif +#if defined(PNG_READ_iTXt_SUPPORTED) + PNG_iTXt; +#endif +#if defined(PNG_READ_oFFs_SUPPORTED) + PNG_oFFs; +#endif +#if defined(PNG_READ_pCAL_SUPPORTED) + PNG_pCAL; +#endif +#if defined(PNG_READ_pHYs_SUPPORTED) + PNG_pHYs; +#endif +#if defined(PNG_READ_sBIT_SUPPORTED) + PNG_sBIT; +#endif +#if defined(PNG_READ_sCAL_SUPPORTED) + PNG_sCAL; +#endif +#if defined(PNG_READ_sRGB_SUPPORTED) + PNG_sRGB; +#endif +#if defined(PNG_READ_sPLT_SUPPORTED) + PNG_sPLT; +#endif +#if defined(PNG_READ_tEXt_SUPPORTED) + PNG_tEXt; +#endif +#if defined(PNG_READ_tIME_SUPPORTED) + PNG_tIME; +#endif +#if defined(PNG_READ_tRNS_SUPPORTED) + PNG_tRNS; +#endif +#if defined(PNG_READ_zTXt_SUPPORTED) + PNG_zTXt; +#endif +#endif /* PNG_USE_LOCAL_ARRAYS */ + /* First we make sure we have enough data for the 4 byte chunk name + * and the 4 byte chunk length before proceeding with decoding the + * chunk data. To fully decode each of these chunks, we also make + * sure we have enough data in the buffer for the 4 byte CRC at the + * end of every chunk (except IDAT, which is handled separately). + */ + if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER)) + { + png_byte chunk_length[4]; + + if (png_ptr->buffer_size < 8) + { + png_push_save_buffer(png_ptr); + return; + } + + png_push_fill_buffer(png_ptr, chunk_length, 4); + png_ptr->push_length = png_get_uint_31(png_ptr,chunk_length); + png_reset_crc(png_ptr); + png_crc_read(png_ptr, png_ptr->chunk_name, 4); + png_ptr->mode |= PNG_HAVE_CHUNK_HEADER; + } + + if (!png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4)) + if(png_ptr->mode & PNG_AFTER_IDAT) + png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT; + + if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4)) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length); + } + else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4)) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length); + + png_ptr->process_mode = PNG_READ_DONE_MODE; + png_push_have_end(png_ptr, info_ptr); + } +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED + else if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name)) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) + png_ptr->mode |= PNG_HAVE_IDAT; + png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length); + if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4)) + png_ptr->mode |= PNG_HAVE_PLTE; + else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) + { + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before IDAT"); + else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && + !(png_ptr->mode & PNG_HAVE_PLTE)) + png_error(png_ptr, "Missing PLTE before IDAT"); + } + } +#endif + else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4)) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length); + } + else if (!png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4)) + { + /* If we reach an IDAT chunk, this means we have read all of the + * header chunks, and we can start reading the image (or if this + * is called after the image has been read - we have an error). + */ + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before IDAT"); + else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && + !(png_ptr->mode & PNG_HAVE_PLTE)) + png_error(png_ptr, "Missing PLTE before IDAT"); + + if (png_ptr->mode & PNG_HAVE_IDAT) + { + if (!(png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT)) + if (png_ptr->push_length == 0) + return; + + if (png_ptr->mode & PNG_AFTER_IDAT) + png_error(png_ptr, "Too many IDAT's found"); + } + + png_ptr->idat_size = png_ptr->push_length; + png_ptr->mode |= PNG_HAVE_IDAT; + png_ptr->process_mode = PNG_READ_IDAT_MODE; + png_push_have_info(png_ptr, info_ptr); + png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes; + png_ptr->zstream.next_out = png_ptr->row_buf; + return; + } +#if defined(PNG_READ_gAMA_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4)) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length); + } +#endif +#if defined(PNG_READ_sBIT_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4)) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length); + } +#endif +#if defined(PNG_READ_cHRM_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4)) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length); + } +#endif +#if defined(PNG_READ_sRGB_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4)) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length); + } +#endif +#if defined(PNG_READ_iCCP_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4)) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length); + } +#endif +#if defined(PNG_READ_sPLT_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4)) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length); + } +#endif +#if defined(PNG_READ_tRNS_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4)) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length); + } +#endif +#if defined(PNG_READ_bKGD_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4)) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length); + } +#endif +#if defined(PNG_READ_hIST_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4)) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length); + } +#endif +#if defined(PNG_READ_pHYs_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4)) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length); + } +#endif +#if defined(PNG_READ_oFFs_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4)) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length); + } +#endif +#if defined(PNG_READ_pCAL_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4)) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length); + } +#endif +#if defined(PNG_READ_sCAL_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4)) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length); + } +#endif +#if defined(PNG_READ_tIME_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4)) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length); + } +#endif +#if defined(PNG_READ_tEXt_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4)) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + png_push_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length); + } +#endif +#if defined(PNG_READ_zTXt_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4)) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + png_push_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length); + } +#endif +#if defined(PNG_READ_iTXt_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4)) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + png_push_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length); + } +#endif + else + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + png_push_handle_unknown(png_ptr, info_ptr, png_ptr->push_length); + } + + png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER; +} + +void /* PRIVATE */ +png_push_crc_skip(png_structp png_ptr, png_uint_32 skip) +{ + png_ptr->process_mode = PNG_SKIP_MODE; + png_ptr->skip_length = skip; +} + +void /* PRIVATE */ +png_push_crc_finish(png_structp png_ptr) +{ + if (png_ptr->skip_length && png_ptr->save_buffer_size) + { + png_size_t save_size; + + if (png_ptr->skip_length < (png_uint_32)png_ptr->save_buffer_size) + save_size = (png_size_t)png_ptr->skip_length; + else + save_size = png_ptr->save_buffer_size; + + png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size); + + png_ptr->skip_length -= save_size; + png_ptr->buffer_size -= save_size; + png_ptr->save_buffer_size -= save_size; + png_ptr->save_buffer_ptr += save_size; + } + if (png_ptr->skip_length && png_ptr->current_buffer_size) + { + png_size_t save_size; + + if (png_ptr->skip_length < (png_uint_32)png_ptr->current_buffer_size) + save_size = (png_size_t)png_ptr->skip_length; + else + save_size = png_ptr->current_buffer_size; + + png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size); + + png_ptr->skip_length -= save_size; + png_ptr->buffer_size -= save_size; + png_ptr->current_buffer_size -= save_size; + png_ptr->current_buffer_ptr += save_size; + } + if (!png_ptr->skip_length) + { + if (png_ptr->buffer_size < 4) + { + png_push_save_buffer(png_ptr); + return; + } + + png_crc_finish(png_ptr, 0); + png_ptr->process_mode = PNG_READ_CHUNK_MODE; + } +} + +void PNGAPI +png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length) +{ + png_bytep ptr; + + ptr = buffer; + if (png_ptr->save_buffer_size) + { + png_size_t save_size; + + if (length < png_ptr->save_buffer_size) + save_size = length; + else + save_size = png_ptr->save_buffer_size; + + png_memcpy(ptr, png_ptr->save_buffer_ptr, save_size); + length -= save_size; + ptr += save_size; + png_ptr->buffer_size -= save_size; + png_ptr->save_buffer_size -= save_size; + png_ptr->save_buffer_ptr += save_size; + } + if (length && png_ptr->current_buffer_size) + { + png_size_t save_size; + + if (length < png_ptr->current_buffer_size) + save_size = length; + else + save_size = png_ptr->current_buffer_size; + + png_memcpy(ptr, png_ptr->current_buffer_ptr, save_size); + png_ptr->buffer_size -= save_size; + png_ptr->current_buffer_size -= save_size; + png_ptr->current_buffer_ptr += save_size; + } +} + +void /* PRIVATE */ +png_push_save_buffer(png_structp png_ptr) +{ + if (png_ptr->save_buffer_size) + { + if (png_ptr->save_buffer_ptr != png_ptr->save_buffer) + { + png_size_t i,istop; + png_bytep sp; + png_bytep dp; + + istop = png_ptr->save_buffer_size; + for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer; + i < istop; i++, sp++, dp++) + { + *dp = *sp; + } + } + } + if (png_ptr->save_buffer_size + png_ptr->current_buffer_size > + png_ptr->save_buffer_max) + { + png_size_t new_max; + png_bytep old_buffer; + + if (png_ptr->save_buffer_size > PNG_SIZE_MAX - + (png_ptr->current_buffer_size + 256)) + { + png_error(png_ptr, "Potential overflow of save_buffer"); + } + new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256; + old_buffer = png_ptr->save_buffer; + png_ptr->save_buffer = (png_bytep)png_malloc(png_ptr, + (png_uint_32)new_max); + png_memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size); + png_free(png_ptr, old_buffer); + png_ptr->save_buffer_max = new_max; + } + if (png_ptr->current_buffer_size) + { + png_memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size, + png_ptr->current_buffer_ptr, png_ptr->current_buffer_size); + png_ptr->save_buffer_size += png_ptr->current_buffer_size; + png_ptr->current_buffer_size = 0; + } + png_ptr->save_buffer_ptr = png_ptr->save_buffer; + png_ptr->buffer_size = 0; +} + +void /* PRIVATE */ +png_push_restore_buffer(png_structp png_ptr, png_bytep buffer, + png_size_t buffer_length) +{ + png_ptr->current_buffer = buffer; + png_ptr->current_buffer_size = buffer_length; + png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size; + png_ptr->current_buffer_ptr = png_ptr->current_buffer; +} + +void /* PRIVATE */ +png_push_read_IDAT(png_structp png_ptr) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_IDAT; +#endif + if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER)) + { + png_byte chunk_length[4]; + + if (png_ptr->buffer_size < 8) + { + png_push_save_buffer(png_ptr); + return; + } + + png_push_fill_buffer(png_ptr, chunk_length, 4); + png_ptr->push_length = png_get_uint_31(png_ptr,chunk_length); + png_reset_crc(png_ptr); + png_crc_read(png_ptr, png_ptr->chunk_name, 4); + png_ptr->mode |= PNG_HAVE_CHUNK_HEADER; + + if (png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4)) + { + png_ptr->process_mode = PNG_READ_CHUNK_MODE; + if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) + png_error(png_ptr, "Not enough compressed data"); + return; + } + + png_ptr->idat_size = png_ptr->push_length; + } + if (png_ptr->idat_size && png_ptr->save_buffer_size) + { + png_size_t save_size; + + if (png_ptr->idat_size < (png_uint_32)png_ptr->save_buffer_size) + { + save_size = (png_size_t)png_ptr->idat_size; + /* check for overflow */ + if((png_uint_32)save_size != png_ptr->idat_size) + png_error(png_ptr, "save_size overflowed in pngpread"); + } + else + save_size = png_ptr->save_buffer_size; + + png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size); + if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) + png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size); + png_ptr->idat_size -= save_size; + png_ptr->buffer_size -= save_size; + png_ptr->save_buffer_size -= save_size; + png_ptr->save_buffer_ptr += save_size; + } + if (png_ptr->idat_size && png_ptr->current_buffer_size) + { + png_size_t save_size; + + if (png_ptr->idat_size < (png_uint_32)png_ptr->current_buffer_size) + { + save_size = (png_size_t)png_ptr->idat_size; + /* check for overflow */ + if((png_uint_32)save_size != png_ptr->idat_size) + png_error(png_ptr, "save_size overflowed in pngpread"); + } + else + save_size = png_ptr->current_buffer_size; + + png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size); + if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) + png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size); + + png_ptr->idat_size -= save_size; + png_ptr->buffer_size -= save_size; + png_ptr->current_buffer_size -= save_size; + png_ptr->current_buffer_ptr += save_size; + } + if (!png_ptr->idat_size) + { + if (png_ptr->buffer_size < 4) + { + png_push_save_buffer(png_ptr); + return; + } + + png_crc_finish(png_ptr, 0); + png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER; + png_ptr->mode |= PNG_AFTER_IDAT; + } +} + +void /* PRIVATE */ +png_process_IDAT_data(png_structp png_ptr, png_bytep buffer, + png_size_t buffer_length) +{ + int ret; + + if ((png_ptr->flags & PNG_FLAG_ZLIB_FINISHED) && buffer_length) + png_error(png_ptr, "Extra compression data"); + + png_ptr->zstream.next_in = buffer; + png_ptr->zstream.avail_in = (uInt)buffer_length; + for(;;) + { + ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH); + if (ret != Z_OK) + { + if (ret == Z_STREAM_END) + { + if (png_ptr->zstream.avail_in) + png_error(png_ptr, "Extra compressed data"); + if (!(png_ptr->zstream.avail_out)) + { + png_push_process_row(png_ptr); + } + + png_ptr->mode |= PNG_AFTER_IDAT; + png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; + break; + } + else if (ret == Z_BUF_ERROR) + break; + else + png_error(png_ptr, "Decompression Error"); + } + if (!(png_ptr->zstream.avail_out)) + { + if (( +#if defined(PNG_READ_INTERLACING_SUPPORTED) + png_ptr->interlaced && png_ptr->pass > 6) || + (!png_ptr->interlaced && +#endif + png_ptr->row_number == png_ptr->num_rows)) + { + if (png_ptr->zstream.avail_in) + png_warning(png_ptr, "Too much data in IDAT chunks"); + png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; + break; + } + png_push_process_row(png_ptr); + png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes; + png_ptr->zstream.next_out = png_ptr->row_buf; + } + else + break; + } +} + +void /* PRIVATE */ +png_push_process_row(png_structp png_ptr) +{ + png_ptr->row_info.color_type = png_ptr->color_type; + png_ptr->row_info.width = png_ptr->iwidth; + png_ptr->row_info.channels = png_ptr->channels; + png_ptr->row_info.bit_depth = png_ptr->bit_depth; + png_ptr->row_info.pixel_depth = png_ptr->pixel_depth; + + png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth, + png_ptr->row_info.width); + + png_read_filter_row(png_ptr, &(png_ptr->row_info), + png_ptr->row_buf + 1, png_ptr->prev_row + 1, + (int)(png_ptr->row_buf[0])); + + png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf, + png_ptr->rowbytes + 1); + + if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA)) + png_do_read_transformations(png_ptr); + +#if defined(PNG_READ_INTERLACING_SUPPORTED) + /* blow up interlaced rows to full size */ + if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE)) + { + if (png_ptr->pass < 6) +/* old interface (pre-1.0.9): + png_do_read_interlace(&(png_ptr->row_info), + png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations); + */ + png_do_read_interlace(png_ptr); + + switch (png_ptr->pass) + { + case 0: + { + int i; + for (i = 0; i < 8 && png_ptr->pass == 0; i++) + { + png_push_have_row(png_ptr, png_ptr->row_buf + 1); + png_read_push_finish_row(png_ptr); /* updates png_ptr->pass */ + } + if (png_ptr->pass == 2) /* pass 1 might be empty */ + { + for (i = 0; i < 4 && png_ptr->pass == 2; i++) + { + png_push_have_row(png_ptr, png_bytep_NULL); + png_read_push_finish_row(png_ptr); + } + } + if (png_ptr->pass == 4 && png_ptr->height <= 4) + { + for (i = 0; i < 2 && png_ptr->pass == 4; i++) + { + png_push_have_row(png_ptr, png_bytep_NULL); + png_read_push_finish_row(png_ptr); + } + } + if (png_ptr->pass == 6 && png_ptr->height <= 4) + { + png_push_have_row(png_ptr, png_bytep_NULL); + png_read_push_finish_row(png_ptr); + } + break; + } + case 1: + { + int i; + for (i = 0; i < 8 && png_ptr->pass == 1; i++) + { + png_push_have_row(png_ptr, png_ptr->row_buf + 1); + png_read_push_finish_row(png_ptr); + } + if (png_ptr->pass == 2) /* skip top 4 generated rows */ + { + for (i = 0; i < 4 && png_ptr->pass == 2; i++) + { + png_push_have_row(png_ptr, png_bytep_NULL); + png_read_push_finish_row(png_ptr); + } + } + break; + } + case 2: + { + int i; + for (i = 0; i < 4 && png_ptr->pass == 2; i++) + { + png_push_have_row(png_ptr, png_ptr->row_buf + 1); + png_read_push_finish_row(png_ptr); + } + for (i = 0; i < 4 && png_ptr->pass == 2; i++) + { + png_push_have_row(png_ptr, png_bytep_NULL); + png_read_push_finish_row(png_ptr); + } + if (png_ptr->pass == 4) /* pass 3 might be empty */ + { + for (i = 0; i < 2 && png_ptr->pass == 4; i++) + { + png_push_have_row(png_ptr, png_bytep_NULL); + png_read_push_finish_row(png_ptr); + } + } + break; + } + case 3: + { + int i; + for (i = 0; i < 4 && png_ptr->pass == 3; i++) + { + png_push_have_row(png_ptr, png_ptr->row_buf + 1); + png_read_push_finish_row(png_ptr); + } + if (png_ptr->pass == 4) /* skip top two generated rows */ + { + for (i = 0; i < 2 && png_ptr->pass == 4; i++) + { + png_push_have_row(png_ptr, png_bytep_NULL); + png_read_push_finish_row(png_ptr); + } + } + break; + } + case 4: + { + int i; + for (i = 0; i < 2 && png_ptr->pass == 4; i++) + { + png_push_have_row(png_ptr, png_ptr->row_buf + 1); + png_read_push_finish_row(png_ptr); + } + for (i = 0; i < 2 && png_ptr->pass == 4; i++) + { + png_push_have_row(png_ptr, png_bytep_NULL); + png_read_push_finish_row(png_ptr); + } + if (png_ptr->pass == 6) /* pass 5 might be empty */ + { + png_push_have_row(png_ptr, png_bytep_NULL); + png_read_push_finish_row(png_ptr); + } + break; + } + case 5: + { + int i; + for (i = 0; i < 2 && png_ptr->pass == 5; i++) + { + png_push_have_row(png_ptr, png_ptr->row_buf + 1); + png_read_push_finish_row(png_ptr); + } + if (png_ptr->pass == 6) /* skip top generated row */ + { + png_push_have_row(png_ptr, png_bytep_NULL); + png_read_push_finish_row(png_ptr); + } + break; + } + case 6: + { + png_push_have_row(png_ptr, png_ptr->row_buf + 1); + png_read_push_finish_row(png_ptr); + if (png_ptr->pass != 6) + break; + png_push_have_row(png_ptr, png_bytep_NULL); + png_read_push_finish_row(png_ptr); + } + } + } + else +#endif + { + png_push_have_row(png_ptr, png_ptr->row_buf + 1); + png_read_push_finish_row(png_ptr); + } +} + +void /* PRIVATE */ +png_read_push_finish_row(png_structp png_ptr) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */ + + /* start of interlace block */ + const int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; + + /* offset to next interlace block */ + const int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; + + /* start of interlace block in the y direction */ + const int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1}; + + /* offset to next interlace block in the y direction */ + const int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2}; + + /* Width of interlace block. This is not currently used - if you need + * it, uncomment it here and in png.h + const int FARDATA png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; + */ + + /* Height of interlace block. This is not currently used - if you need + * it, uncomment it here and in png.h + const int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1}; + */ +#endif + + png_ptr->row_number++; + if (png_ptr->row_number < png_ptr->num_rows) + return; + + if (png_ptr->interlaced) + { + png_ptr->row_number = 0; + png_memset_check(png_ptr, png_ptr->prev_row, 0, + png_ptr->rowbytes + 1); + do + { + png_ptr->pass++; + if ((png_ptr->pass == 1 && png_ptr->width < 5) || + (png_ptr->pass == 3 && png_ptr->width < 3) || + (png_ptr->pass == 5 && png_ptr->width < 2)) + png_ptr->pass++; + + if (png_ptr->pass > 7) + png_ptr->pass--; + if (png_ptr->pass >= 7) + break; + + png_ptr->iwidth = (png_ptr->width + + png_pass_inc[png_ptr->pass] - 1 - + png_pass_start[png_ptr->pass]) / + png_pass_inc[png_ptr->pass]; + + png_ptr->irowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, + png_ptr->iwidth) + 1; + + if (png_ptr->transformations & PNG_INTERLACE) + break; + + png_ptr->num_rows = (png_ptr->height + + png_pass_yinc[png_ptr->pass] - 1 - + png_pass_ystart[png_ptr->pass]) / + png_pass_yinc[png_ptr->pass]; + + } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0); + } +} + +#if defined(PNG_READ_tEXt_SUPPORTED) +void /* PRIVATE */ +png_push_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 + length) +{ + if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND)) + { + png_error(png_ptr, "Out of place tEXt"); + /* to quiet some compiler warnings */ + if(info_ptr == NULL) return; + } + +#ifdef PNG_MAX_MALLOC_64K + png_ptr->skip_length = 0; /* This may not be necessary */ + + if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */ + { + png_warning(png_ptr, "tEXt chunk too large to fit in memory"); + png_ptr->skip_length = length - (png_uint_32)65535L; + length = (png_uint_32)65535L; + } +#endif + + png_ptr->current_text = (png_charp)png_malloc(png_ptr, + (png_uint_32)(length+1)); + png_ptr->current_text[length] = '\0'; + png_ptr->current_text_ptr = png_ptr->current_text; + png_ptr->current_text_size = (png_size_t)length; + png_ptr->current_text_left = (png_size_t)length; + png_ptr->process_mode = PNG_READ_tEXt_MODE; +} + +void /* PRIVATE */ +png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr) +{ + if (png_ptr->buffer_size && png_ptr->current_text_left) + { + png_size_t text_size; + + if (png_ptr->buffer_size < png_ptr->current_text_left) + text_size = png_ptr->buffer_size; + else + text_size = png_ptr->current_text_left; + png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size); + png_ptr->current_text_left -= text_size; + png_ptr->current_text_ptr += text_size; + } + if (!(png_ptr->current_text_left)) + { + png_textp text_ptr; + png_charp text; + png_charp key; + int ret; + + if (png_ptr->buffer_size < 4) + { + png_push_save_buffer(png_ptr); + return; + } + + png_push_crc_finish(png_ptr); + +#if defined(PNG_MAX_MALLOC_64K) + if (png_ptr->skip_length) + return; +#endif + + key = png_ptr->current_text; + + for (text = key; *text; text++) + /* empty loop */ ; + + if (text != key + png_ptr->current_text_size) + text++; + + text_ptr = (png_textp)png_malloc(png_ptr, + (png_uint_32)png_sizeof(png_text)); + text_ptr->compression = PNG_TEXT_COMPRESSION_NONE; + text_ptr->key = key; +#ifdef PNG_iTXt_SUPPORTED + text_ptr->lang = NULL; + text_ptr->lang_key = NULL; +#endif + text_ptr->text = text; + + ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); + + png_free(png_ptr, key); + png_free(png_ptr, text_ptr); + png_ptr->current_text = NULL; + + if (ret) + png_warning(png_ptr, "Insufficient memory to store text chunk."); + } +} +#endif + +#if defined(PNG_READ_zTXt_SUPPORTED) +void /* PRIVATE */ +png_push_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 + length) +{ + if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND)) + { + png_error(png_ptr, "Out of place zTXt"); + /* to quiet some compiler warnings */ + if(info_ptr == NULL) return; + } + +#ifdef PNG_MAX_MALLOC_64K + /* We can't handle zTXt chunks > 64K, since we don't have enough space + * to be able to store the uncompressed data. Actually, the threshold + * is probably around 32K, but it isn't as definite as 64K is. + */ + if (length > (png_uint_32)65535L) + { + png_warning(png_ptr, "zTXt chunk too large to fit in memory"); + png_push_crc_skip(png_ptr, length); + return; + } +#endif + + png_ptr->current_text = (png_charp)png_malloc(png_ptr, + (png_uint_32)(length+1)); + png_ptr->current_text[length] = '\0'; + png_ptr->current_text_ptr = png_ptr->current_text; + png_ptr->current_text_size = (png_size_t)length; + png_ptr->current_text_left = (png_size_t)length; + png_ptr->process_mode = PNG_READ_zTXt_MODE; +} + +void /* PRIVATE */ +png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr) +{ + if (png_ptr->buffer_size && png_ptr->current_text_left) + { + png_size_t text_size; + + if (png_ptr->buffer_size < (png_uint_32)png_ptr->current_text_left) + text_size = png_ptr->buffer_size; + else + text_size = png_ptr->current_text_left; + png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size); + png_ptr->current_text_left -= text_size; + png_ptr->current_text_ptr += text_size; + } + if (!(png_ptr->current_text_left)) + { + png_textp text_ptr; + png_charp text; + png_charp key; + int ret; + png_size_t text_size, key_size; + + if (png_ptr->buffer_size < 4) + { + png_push_save_buffer(png_ptr); + return; + } + + png_push_crc_finish(png_ptr); + + key = png_ptr->current_text; + + for (text = key; *text; text++) + /* empty loop */ ; + + /* zTXt can't have zero text */ + if (text == key + png_ptr->current_text_size) + { + png_ptr->current_text = NULL; + png_free(png_ptr, key); + return; + } + + text++; + + if (*text != PNG_TEXT_COMPRESSION_zTXt) /* check compression byte */ + { + png_ptr->current_text = NULL; + png_free(png_ptr, key); + return; + } + + text++; + + png_ptr->zstream.next_in = (png_bytep )text; + png_ptr->zstream.avail_in = (uInt)(png_ptr->current_text_size - + (text - key)); + png_ptr->zstream.next_out = png_ptr->zbuf; + png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; + + key_size = text - key; + text_size = 0; + text = NULL; + ret = Z_STREAM_END; + + while (png_ptr->zstream.avail_in) + { + ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH); + if (ret != Z_OK && ret != Z_STREAM_END) + { + inflateReset(&png_ptr->zstream); + png_ptr->zstream.avail_in = 0; + png_ptr->current_text = NULL; + png_free(png_ptr, key); + png_free(png_ptr, text); + return; + } + if (!(png_ptr->zstream.avail_out) || ret == Z_STREAM_END) + { + if (text == NULL) + { + text = (png_charp)png_malloc(png_ptr, + (png_uint_32)(png_ptr->zbuf_size - png_ptr->zstream.avail_out + + key_size + 1)); + png_memcpy(text + key_size, png_ptr->zbuf, + png_ptr->zbuf_size - png_ptr->zstream.avail_out); + png_memcpy(text, key, key_size); + text_size = key_size + png_ptr->zbuf_size - + png_ptr->zstream.avail_out; + *(text + text_size) = '\0'; + } + else + { + png_charp tmp; + + tmp = text; + text = (png_charp)png_malloc(png_ptr, text_size + + (png_uint_32)(png_ptr->zbuf_size - png_ptr->zstream.avail_out + + 1)); + png_memcpy(text, tmp, text_size); + png_free(png_ptr, tmp); + png_memcpy(text + text_size, png_ptr->zbuf, + png_ptr->zbuf_size - png_ptr->zstream.avail_out); + text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out; + *(text + text_size) = '\0'; + } + if (ret != Z_STREAM_END) + { + png_ptr->zstream.next_out = png_ptr->zbuf; + png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; + } + } + else + { + break; + } + + if (ret == Z_STREAM_END) + break; + } + + inflateReset(&png_ptr->zstream); + png_ptr->zstream.avail_in = 0; + + if (ret != Z_STREAM_END) + { + png_ptr->current_text = NULL; + png_free(png_ptr, key); + png_free(png_ptr, text); + return; + } + + png_ptr->current_text = NULL; + png_free(png_ptr, key); + key = text; + text += key_size; + + text_ptr = (png_textp)png_malloc(png_ptr, + (png_uint_32)png_sizeof(png_text)); + text_ptr->compression = PNG_TEXT_COMPRESSION_zTXt; + text_ptr->key = key; +#ifdef PNG_iTXt_SUPPORTED + text_ptr->lang = NULL; + text_ptr->lang_key = NULL; +#endif + text_ptr->text = text; + + ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); + + png_free(png_ptr, key); + png_free(png_ptr, text_ptr); + + if (ret) + png_warning(png_ptr, "Insufficient memory to store text chunk."); + } +} +#endif + +#if defined(PNG_READ_iTXt_SUPPORTED) +void /* PRIVATE */ +png_push_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 + length) +{ + if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND)) + { + png_error(png_ptr, "Out of place iTXt"); + /* to quiet some compiler warnings */ + if(info_ptr == NULL) return; + } + +#ifdef PNG_MAX_MALLOC_64K + png_ptr->skip_length = 0; /* This may not be necessary */ + + if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */ + { + png_warning(png_ptr, "iTXt chunk too large to fit in memory"); + png_ptr->skip_length = length - (png_uint_32)65535L; + length = (png_uint_32)65535L; + } +#endif + + png_ptr->current_text = (png_charp)png_malloc(png_ptr, + (png_uint_32)(length+1)); + png_ptr->current_text[length] = '\0'; + png_ptr->current_text_ptr = png_ptr->current_text; + png_ptr->current_text_size = (png_size_t)length; + png_ptr->current_text_left = (png_size_t)length; + png_ptr->process_mode = PNG_READ_iTXt_MODE; +} + +void /* PRIVATE */ +png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr) +{ + + if (png_ptr->buffer_size && png_ptr->current_text_left) + { + png_size_t text_size; + + if (png_ptr->buffer_size < png_ptr->current_text_left) + text_size = png_ptr->buffer_size; + else + text_size = png_ptr->current_text_left; + png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size); + png_ptr->current_text_left -= text_size; + png_ptr->current_text_ptr += text_size; + } + if (!(png_ptr->current_text_left)) + { + png_textp text_ptr; + png_charp key; + int comp_flag; + png_charp lang; + png_charp lang_key; + png_charp text; + int ret; + + if (png_ptr->buffer_size < 4) + { + png_push_save_buffer(png_ptr); + return; + } + + png_push_crc_finish(png_ptr); + +#if defined(PNG_MAX_MALLOC_64K) + if (png_ptr->skip_length) + return; +#endif + + key = png_ptr->current_text; + + for (lang = key; *lang; lang++) + /* empty loop */ ; + + if (lang != key + png_ptr->current_text_size) + lang++; + + comp_flag = *lang++; + lang++; /* skip comp_type, always zero */ + + for (lang_key = lang; *lang_key; lang_key++) + /* empty loop */ ; + lang_key++; /* skip NUL separator */ + + for (text = lang_key; *text; text++) + /* empty loop */ ; + + if (text != key + png_ptr->current_text_size) + text++; + + text_ptr = (png_textp)png_malloc(png_ptr, + (png_uint_32)png_sizeof(png_text)); + text_ptr->compression = comp_flag + 2; + text_ptr->key = key; + text_ptr->lang = lang; + text_ptr->lang_key = lang_key; + text_ptr->text = text; + text_ptr->text_length = 0; + text_ptr->itxt_length = png_strlen(text); + + ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); + + png_ptr->current_text = NULL; + + png_free(png_ptr, text_ptr); + if (ret) + png_warning(png_ptr, "Insufficient memory to store iTXt chunk."); + } +} +#endif + +/* This function is called when we haven't found a handler for this + * chunk. If there isn't a problem with the chunk itself (ie a bad chunk + * name or a critical chunk), the chunk is (currently) silently ignored. + */ +void /* PRIVATE */ +png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 + length) +{ + png_uint_32 skip=0; + png_check_chunk_name(png_ptr, png_ptr->chunk_name); + + if (!(png_ptr->chunk_name[0] & 0x20)) + { +#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) + if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != + PNG_HANDLE_CHUNK_ALWAYS +#if defined(PNG_READ_USER_CHUNKS_SUPPORTED) + && png_ptr->read_user_chunk_fn == NULL +#endif + ) +#endif + png_chunk_error(png_ptr, "unknown critical chunk"); + + /* to quiet compiler warnings about unused info_ptr */ + if (info_ptr == NULL) + return; + } + +#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) + if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS) + { + png_unknown_chunk chunk; + +#ifdef PNG_MAX_MALLOC_64K + if (length > (png_uint_32)65535L) + { + png_warning(png_ptr, "unknown chunk too large to fit in memory"); + skip = length - (png_uint_32)65535L; + length = (png_uint_32)65535L; + } +#endif + + png_strcpy((png_charp)chunk.name, (png_charp)png_ptr->chunk_name); + chunk.data = (png_bytep)png_malloc(png_ptr, length); + png_crc_read(png_ptr, chunk.data, length); + chunk.size = length; +#if defined(PNG_READ_USER_CHUNKS_SUPPORTED) + if(png_ptr->read_user_chunk_fn != NULL) + { + /* callback to user unknown chunk handler */ + if ((*(png_ptr->read_user_chunk_fn)) (png_ptr, &chunk) <= 0) + { + if (!(png_ptr->chunk_name[0] & 0x20)) + if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != + PNG_HANDLE_CHUNK_ALWAYS) + png_chunk_error(png_ptr, "unknown critical chunk"); + } + png_set_unknown_chunks(png_ptr, info_ptr, &chunk, 1); + } + else +#endif + png_set_unknown_chunks(png_ptr, info_ptr, &chunk, 1); + png_free(png_ptr, chunk.data); + } + else +#endif + skip=length; + png_push_crc_skip(png_ptr, skip); +} + +void /* PRIVATE */ +png_push_have_info(png_structp png_ptr, png_infop info_ptr) +{ + if (png_ptr->info_fn != NULL) + (*(png_ptr->info_fn))(png_ptr, info_ptr); +} + +void /* PRIVATE */ +png_push_have_end(png_structp png_ptr, png_infop info_ptr) +{ + if (png_ptr->end_fn != NULL) + (*(png_ptr->end_fn))(png_ptr, info_ptr); +} + +void /* PRIVATE */ +png_push_have_row(png_structp png_ptr, png_bytep row) +{ + if (png_ptr->row_fn != NULL) + (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number, + (int)png_ptr->pass); +} + +void PNGAPI +png_progressive_combine_row (png_structp png_ptr, + png_bytep old_row, png_bytep new_row) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + const int FARDATA png_pass_dsp_mask[7] = + {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff}; +#endif + if (new_row != NULL) /* new_row must == png_ptr->row_buf here. */ + png_combine_row(png_ptr, old_row, png_pass_dsp_mask[png_ptr->pass]); +} + +void PNGAPI +png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr, + png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn, + png_progressive_end_ptr end_fn) +{ + png_ptr->info_fn = info_fn; + png_ptr->row_fn = row_fn; + png_ptr->end_fn = end_fn; + + png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer); +} + +png_voidp PNGAPI +png_get_progressive_ptr(png_structp png_ptr) +{ + return png_ptr->io_ptr; +} +#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ diff --git a/mod/pub.mod/libpng.mod/pngread.c b/mod/pub.mod/libpng.mod/pngread.c new file mode 100644 index 0000000..28706aa --- /dev/null +++ b/mod/pub.mod/libpng.mod/pngread.c @@ -0,0 +1,1461 @@ + +/* pngread.c - read a PNG file + * + * Last changed in libpng 1.2.11 June 7, 2006 + * For conditions of distribution and use, see copyright notice in png.h + * Copyright (c) 1998-2006 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * + * This file contains routines that an application calls directly to + * read a PNG file or stream. + */ + +#define PNG_INTERNAL +#include "png.h" + +#if defined(PNG_READ_SUPPORTED) + +/* Create a PNG structure for reading, and allocate any memory needed. */ +png_structp PNGAPI +png_create_read_struct(png_const_charp user_png_ver, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warn_fn) +{ + +#ifdef PNG_USER_MEM_SUPPORTED + return (png_create_read_struct_2(user_png_ver, error_ptr, error_fn, + warn_fn, png_voidp_NULL, png_malloc_ptr_NULL, png_free_ptr_NULL)); +} + +/* Alternate create PNG structure for reading, and allocate any memory needed. */ +png_structp PNGAPI +png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, + png_malloc_ptr malloc_fn, png_free_ptr free_fn) +{ +#endif /* PNG_USER_MEM_SUPPORTED */ + + png_structp png_ptr; + +#ifdef PNG_SETJMP_SUPPORTED +#ifdef USE_FAR_KEYWORD + jmp_buf jmpbuf; +#endif +#endif + + int i; + + png_debug(1, "in png_create_read_struct\n"); +#ifdef PNG_USER_MEM_SUPPORTED + png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG, + (png_malloc_ptr)malloc_fn, (png_voidp)mem_ptr); +#else + png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG); +#endif + if (png_ptr == NULL) + return (NULL); + +#if !defined(PNG_1_0_X) +#ifdef PNG_ASSEMBLER_CODE_SUPPORTED + png_init_mmx_flags(png_ptr); /* 1.2.0 addition */ +#endif +#endif /* PNG_1_0_X */ + + /* added at libpng-1.2.6 */ +#ifdef PNG_SET_USER_LIMITS_SUPPORTED + png_ptr->user_width_max=PNG_USER_WIDTH_MAX; + png_ptr->user_height_max=PNG_USER_HEIGHT_MAX; +#endif + +#ifdef PNG_SETJMP_SUPPORTED +#ifdef USE_FAR_KEYWORD + if (setjmp(jmpbuf)) +#else + if (setjmp(png_ptr->jmpbuf)) +#endif + { + png_free(png_ptr, png_ptr->zbuf); + png_ptr->zbuf=NULL; +#ifdef PNG_USER_MEM_SUPPORTED + png_destroy_struct_2((png_voidp)png_ptr, + (png_free_ptr)free_fn, (png_voidp)mem_ptr); +#else + png_destroy_struct((png_voidp)png_ptr); +#endif + return (NULL); + } +#ifdef USE_FAR_KEYWORD + png_memcpy(png_ptr->jmpbuf,jmpbuf,png_sizeof(jmp_buf)); +#endif +#endif + +#ifdef PNG_USER_MEM_SUPPORTED + png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn); +#endif + + png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn); + + i=0; + do + { + if(user_png_ver[i] != png_libpng_ver[i]) + png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH; + } while (png_libpng_ver[i++]); + + if (png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH) + { + /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so + * we must recompile any applications that use any older library version. + * For versions after libpng 1.0, we will be compatible, so we need + * only check the first digit. + */ + if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] || + (user_png_ver[0] == '1' && user_png_ver[2] != png_libpng_ver[2]) || + (user_png_ver[0] == '0' && user_png_ver[2] < '9')) + { +#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE) + char msg[80]; + if (user_png_ver) + { + sprintf(msg, "Application was compiled with png.h from libpng-%.20s", + user_png_ver); + png_warning(png_ptr, msg); + } + sprintf(msg, "Application is running with png.c from libpng-%.20s", + png_libpng_ver); + png_warning(png_ptr, msg); +#endif +#ifdef PNG_ERROR_NUMBERS_SUPPORTED + png_ptr->flags=0; +#endif + png_error(png_ptr, + "Incompatible libpng version in application and library"); + } + } + + /* initialize zbuf - compression buffer */ + png_ptr->zbuf_size = PNG_ZBUF_SIZE; + png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, + (png_uint_32)png_ptr->zbuf_size); + png_ptr->zstream.zalloc = png_zalloc; + png_ptr->zstream.zfree = png_zfree; + png_ptr->zstream.opaque = (voidpf)png_ptr; + + switch (inflateInit(&png_ptr->zstream)) + { + case Z_OK: /* Do nothing */ break; + case Z_MEM_ERROR: + case Z_STREAM_ERROR: png_error(png_ptr, "zlib memory error"); break; + case Z_VERSION_ERROR: png_error(png_ptr, "zlib version error"); break; + default: png_error(png_ptr, "Unknown zlib error"); + } + + png_ptr->zstream.next_out = png_ptr->zbuf; + png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; + + png_set_read_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL); + +#ifdef PNG_SETJMP_SUPPORTED +/* Applications that neglect to set up their own setjmp() and then encounter + a png_error() will longjmp here. Since the jmpbuf is then meaningless we + abort instead of returning. */ +#ifdef USE_FAR_KEYWORD + if (setjmp(jmpbuf)) + PNG_ABORT(); + png_memcpy(png_ptr->jmpbuf,jmpbuf,png_sizeof(jmp_buf)); +#else + if (setjmp(png_ptr->jmpbuf)) + PNG_ABORT(); +#endif +#endif + return (png_ptr); +} + +#if defined(PNG_1_0_X) || defined(PNG_1_2_X) +/* Initialize PNG structure for reading, and allocate any memory needed. + This interface is deprecated in favour of the png_create_read_struct(), + and it will disappear as of libpng-1.3.0. */ +#undef png_read_init +void PNGAPI +png_read_init(png_structp png_ptr) +{ + /* We only come here via pre-1.0.7-compiled applications */ + png_read_init_2(png_ptr, "1.0.6 or earlier", 0, 0); +} + +void PNGAPI +png_read_init_2(png_structp png_ptr, png_const_charp user_png_ver, + png_size_t png_struct_size, png_size_t png_info_size) +{ + /* We only come here via pre-1.0.12-compiled applications */ +#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE) + if(png_sizeof(png_struct) > png_struct_size || + png_sizeof(png_info) > png_info_size) + { + char msg[80]; + png_ptr->warning_fn=NULL; + if (user_png_ver) + { + sprintf(msg, "Application was compiled with png.h from libpng-%.20s", + user_png_ver); + png_warning(png_ptr, msg); + } + sprintf(msg, "Application is running with png.c from libpng-%.20s", + png_libpng_ver); + png_warning(png_ptr, msg); + } +#endif + if(png_sizeof(png_struct) > png_struct_size) + { + png_ptr->error_fn=NULL; +#ifdef PNG_ERROR_NUMBERS_SUPPORTED + png_ptr->flags=0; +#endif + png_error(png_ptr, + "The png struct allocated by the application for reading is too small."); + } + if(png_sizeof(png_info) > png_info_size) + { + png_ptr->error_fn=NULL; +#ifdef PNG_ERROR_NUMBERS_SUPPORTED + png_ptr->flags=0; +#endif + png_error(png_ptr, + "The info struct allocated by application for reading is too small."); + } + png_read_init_3(&png_ptr, user_png_ver, png_struct_size); +} +#endif /* PNG_1_0_X || PNG_1_2_X */ + +void PNGAPI +png_read_init_3(png_structpp ptr_ptr, png_const_charp user_png_ver, + png_size_t png_struct_size) +{ +#ifdef PNG_SETJMP_SUPPORTED + jmp_buf tmp_jmp; /* to save current jump buffer */ +#endif + + int i=0; + + png_structp png_ptr=*ptr_ptr; + + do + { + if(user_png_ver[i] != png_libpng_ver[i]) + { +#ifdef PNG_LEGACY_SUPPORTED + png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH; +#else + png_ptr->warning_fn=NULL; + png_warning(png_ptr, + "Application uses deprecated png_read_init() and should be recompiled."); + break; +#endif + } + } while (png_libpng_ver[i++]); + + png_debug(1, "in png_read_init_3\n"); + +#ifdef PNG_SETJMP_SUPPORTED + /* save jump buffer and error functions */ + png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof (jmp_buf)); +#endif + + if(png_sizeof(png_struct) > png_struct_size) + { + png_destroy_struct(png_ptr); + *ptr_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG); + png_ptr = *ptr_ptr; + } + + /* reset all variables to 0 */ + png_memset(png_ptr, 0, png_sizeof (png_struct)); + +#ifdef PNG_SETJMP_SUPPORTED + /* restore jump buffer */ + png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof (jmp_buf)); +#endif + + /* added at libpng-1.2.6 */ +#ifdef PNG_SET_USER_LIMITS_SUPPORTED + png_ptr->user_width_max=PNG_USER_WIDTH_MAX; + png_ptr->user_height_max=PNG_USER_HEIGHT_MAX; +#endif + + /* initialize zbuf - compression buffer */ + png_ptr->zbuf_size = PNG_ZBUF_SIZE; + png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, + (png_uint_32)png_ptr->zbuf_size); + png_ptr->zstream.zalloc = png_zalloc; + png_ptr->zstream.zfree = png_zfree; + png_ptr->zstream.opaque = (voidpf)png_ptr; + + switch (inflateInit(&png_ptr->zstream)) + { + case Z_OK: /* Do nothing */ break; + case Z_MEM_ERROR: + case Z_STREAM_ERROR: png_error(png_ptr, "zlib memory"); break; + case Z_VERSION_ERROR: png_error(png_ptr, "zlib version"); break; + default: png_error(png_ptr, "Unknown zlib error"); + } + + png_ptr->zstream.next_out = png_ptr->zbuf; + png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; + + png_set_read_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL); +} + +#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED +/* Read the information before the actual image data. This has been + * changed in v0.90 to allow reading a file that already has the magic + * bytes read from the stream. You can tell libpng how many bytes have + * been read from the beginning of the stream (up to the maximum of 8) + * via png_set_sig_bytes(), and we will only check the remaining bytes + * here. The application can then have access to the signature bytes we + * read if it is determined that this isn't a valid PNG file. + */ +void PNGAPI +png_read_info(png_structp png_ptr, png_infop info_ptr) +{ + png_debug(1, "in png_read_info\n"); + /* If we haven't checked all of the PNG signature bytes, do so now. */ + if (png_ptr->sig_bytes < 8) + { + png_size_t num_checked = png_ptr->sig_bytes, + num_to_check = 8 - num_checked; + + png_read_data(png_ptr, &(info_ptr->signature[num_checked]), num_to_check); + png_ptr->sig_bytes = 8; + + if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check)) + { + if (num_checked < 4 && + png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4)) + png_error(png_ptr, "Not a PNG file"); + else + png_error(png_ptr, "PNG file corrupted by ASCII conversion"); + } + if (num_checked < 3) + png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE; + } + + for(;;) + { +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_IHDR; + PNG_IDAT; + PNG_IEND; + PNG_PLTE; +#if defined(PNG_READ_bKGD_SUPPORTED) + PNG_bKGD; +#endif +#if defined(PNG_READ_cHRM_SUPPORTED) + PNG_cHRM; +#endif +#if defined(PNG_READ_gAMA_SUPPORTED) + PNG_gAMA; +#endif +#if defined(PNG_READ_hIST_SUPPORTED) + PNG_hIST; +#endif +#if defined(PNG_READ_iCCP_SUPPORTED) + PNG_iCCP; +#endif +#if defined(PNG_READ_iTXt_SUPPORTED) + PNG_iTXt; +#endif +#if defined(PNG_READ_oFFs_SUPPORTED) + PNG_oFFs; +#endif +#if defined(PNG_READ_pCAL_SUPPORTED) + PNG_pCAL; +#endif +#if defined(PNG_READ_pHYs_SUPPORTED) + PNG_pHYs; +#endif +#if defined(PNG_READ_sBIT_SUPPORTED) + PNG_sBIT; +#endif +#if defined(PNG_READ_sCAL_SUPPORTED) + PNG_sCAL; +#endif +#if defined(PNG_READ_sPLT_SUPPORTED) + PNG_sPLT; +#endif +#if defined(PNG_READ_sRGB_SUPPORTED) + PNG_sRGB; +#endif +#if defined(PNG_READ_tEXt_SUPPORTED) + PNG_tEXt; +#endif +#if defined(PNG_READ_tIME_SUPPORTED) + PNG_tIME; +#endif +#if defined(PNG_READ_tRNS_SUPPORTED) + PNG_tRNS; +#endif +#if defined(PNG_READ_zTXt_SUPPORTED) + PNG_zTXt; +#endif +#endif /* PNG_USE_LOCAL_ARRAYS */ + png_byte chunk_length[4]; + png_uint_32 length; + + png_read_data(png_ptr, chunk_length, 4); + length = png_get_uint_31(png_ptr,chunk_length); + + png_reset_crc(png_ptr); + png_crc_read(png_ptr, png_ptr->chunk_name, 4); + + png_debug2(0, "Reading %s chunk, length=%lu.\n", png_ptr->chunk_name, + length); + + /* This should be a binary subdivision search or a hash for + * matching the chunk name rather than a linear search. + */ + if (!png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4)) + if(png_ptr->mode & PNG_AFTER_IDAT) + png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT; + + if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4)) + png_handle_IHDR(png_ptr, info_ptr, length); + else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4)) + png_handle_IEND(png_ptr, info_ptr, length); +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED + else if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name)) + { + if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) + png_ptr->mode |= PNG_HAVE_IDAT; + png_handle_unknown(png_ptr, info_ptr, length); + if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4)) + png_ptr->mode |= PNG_HAVE_PLTE; + else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) + { + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before IDAT"); + else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && + !(png_ptr->mode & PNG_HAVE_PLTE)) + png_error(png_ptr, "Missing PLTE before IDAT"); + break; + } + } +#endif + else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4)) + png_handle_PLTE(png_ptr, info_ptr, length); + else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) + { + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before IDAT"); + else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && + !(png_ptr->mode & PNG_HAVE_PLTE)) + png_error(png_ptr, "Missing PLTE before IDAT"); + + png_ptr->idat_size = length; + png_ptr->mode |= PNG_HAVE_IDAT; + break; + } +#if defined(PNG_READ_bKGD_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4)) + png_handle_bKGD(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_cHRM_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4)) + png_handle_cHRM(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_gAMA_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4)) + png_handle_gAMA(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_hIST_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4)) + png_handle_hIST(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_oFFs_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4)) + png_handle_oFFs(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_pCAL_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4)) + png_handle_pCAL(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_sCAL_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4)) + png_handle_sCAL(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_pHYs_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4)) + png_handle_pHYs(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_sBIT_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4)) + png_handle_sBIT(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_sRGB_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4)) + png_handle_sRGB(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_iCCP_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4)) + png_handle_iCCP(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_sPLT_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4)) + png_handle_sPLT(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_tEXt_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4)) + png_handle_tEXt(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_tIME_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4)) + png_handle_tIME(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_tRNS_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4)) + png_handle_tRNS(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_zTXt_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4)) + png_handle_zTXt(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_iTXt_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4)) + png_handle_iTXt(png_ptr, info_ptr, length); +#endif + else + png_handle_unknown(png_ptr, info_ptr, length); + } +} +#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */ + +/* optional call to update the users info_ptr structure */ +void PNGAPI +png_read_update_info(png_structp png_ptr, png_infop info_ptr) +{ + png_debug(1, "in png_read_update_info\n"); + if (!(png_ptr->flags & PNG_FLAG_ROW_INIT)) + png_read_start_row(png_ptr); + else + png_warning(png_ptr, + "Ignoring extra png_read_update_info() call; row buffer not reallocated"); + png_read_transform_info(png_ptr, info_ptr); +} + +#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED +/* Initialize palette, background, etc, after transformations + * are set, but before any reading takes place. This allows + * the user to obtain a gamma-corrected palette, for example. + * If the user doesn't call this, we will do it ourselves. + */ +void PNGAPI +png_start_read_image(png_structp png_ptr) +{ + png_debug(1, "in png_start_read_image\n"); + if (!(png_ptr->flags & PNG_FLAG_ROW_INIT)) + png_read_start_row(png_ptr); +} +#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */ + +#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED +void PNGAPI +png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_IDAT; + const int png_pass_dsp_mask[7] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff}; + const int png_pass_mask[7] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff}; +#endif + int ret; + png_debug2(1, "in png_read_row (row %lu, pass %d)\n", + png_ptr->row_number, png_ptr->pass); + if (!(png_ptr->flags & PNG_FLAG_ROW_INIT)) + png_read_start_row(png_ptr); + if (png_ptr->row_number == 0 && png_ptr->pass == 0) + { + /* check for transforms that have been set but were defined out */ +#if defined(PNG_WRITE_INVERT_SUPPORTED) && !defined(PNG_READ_INVERT_SUPPORTED) + if (png_ptr->transformations & PNG_INVERT_MONO) + png_warning(png_ptr, "PNG_READ_INVERT_SUPPORTED is not defined."); +#endif +#if defined(PNG_WRITE_FILLER_SUPPORTED) && !defined(PNG_READ_FILLER_SUPPORTED) + if (png_ptr->transformations & PNG_FILLER) + png_warning(png_ptr, "PNG_READ_FILLER_SUPPORTED is not defined."); +#endif +#if defined(PNG_WRITE_PACKSWAP_SUPPORTED) && !defined(PNG_READ_PACKSWAP_SUPPORTED) + if (png_ptr->transformations & PNG_PACKSWAP) + png_warning(png_ptr, "PNG_READ_PACKSWAP_SUPPORTED is not defined."); +#endif +#if defined(PNG_WRITE_PACK_SUPPORTED) && !defined(PNG_READ_PACK_SUPPORTED) + if (png_ptr->transformations & PNG_PACK) + png_warning(png_ptr, "PNG_READ_PACK_SUPPORTED is not defined."); +#endif +#if defined(PNG_WRITE_SHIFT_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED) + if (png_ptr->transformations & PNG_SHIFT) + png_warning(png_ptr, "PNG_READ_SHIFT_SUPPORTED is not defined."); +#endif +#if defined(PNG_WRITE_BGR_SUPPORTED) && !defined(PNG_READ_BGR_SUPPORTED) + if (png_ptr->transformations & PNG_BGR) + png_warning(png_ptr, "PNG_READ_BGR_SUPPORTED is not defined."); +#endif +#if defined(PNG_WRITE_SWAP_SUPPORTED) && !defined(PNG_READ_SWAP_SUPPORTED) + if (png_ptr->transformations & PNG_SWAP_BYTES) + png_warning(png_ptr, "PNG_READ_SWAP_SUPPORTED is not defined."); +#endif + } + +#if defined(PNG_READ_INTERLACING_SUPPORTED) + /* if interlaced and we do not need a new row, combine row and return */ + if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE)) + { + switch (png_ptr->pass) + { + case 0: + if (png_ptr->row_number & 0x07) + { + if (dsp_row != NULL) + png_combine_row(png_ptr, dsp_row, + png_pass_dsp_mask[png_ptr->pass]); + png_read_finish_row(png_ptr); + return; + } + break; + case 1: + if ((png_ptr->row_number & 0x07) || png_ptr->width < 5) + { + if (dsp_row != NULL) + png_combine_row(png_ptr, dsp_row, + png_pass_dsp_mask[png_ptr->pass]); + png_read_finish_row(png_ptr); + return; + } + break; + case 2: + if ((png_ptr->row_number & 0x07) != 4) + { + if (dsp_row != NULL && (png_ptr->row_number & 4)) + png_combine_row(png_ptr, dsp_row, + png_pass_dsp_mask[png_ptr->pass]); + png_read_finish_row(png_ptr); + return; + } + break; + case 3: + if ((png_ptr->row_number & 3) || png_ptr->width < 3) + { + if (dsp_row != NULL) + png_combine_row(png_ptr, dsp_row, + png_pass_dsp_mask[png_ptr->pass]); + png_read_finish_row(png_ptr); + return; + } + break; + case 4: + if ((png_ptr->row_number & 3) != 2) + { + if (dsp_row != NULL && (png_ptr->row_number & 2)) + png_combine_row(png_ptr, dsp_row, + png_pass_dsp_mask[png_ptr->pass]); + png_read_finish_row(png_ptr); + return; + } + break; + case 5: + if ((png_ptr->row_number & 1) || png_ptr->width < 2) + { + if (dsp_row != NULL) + png_combine_row(png_ptr, dsp_row, + png_pass_dsp_mask[png_ptr->pass]); + png_read_finish_row(png_ptr); + return; + } + break; + case 6: + if (!(png_ptr->row_number & 1)) + { + png_read_finish_row(png_ptr); + return; + } + break; + } + } +#endif + + if (!(png_ptr->mode & PNG_HAVE_IDAT)) + png_error(png_ptr, "Invalid attempt to read row data"); + + png_ptr->zstream.next_out = png_ptr->row_buf; + png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes; + do + { + if (!(png_ptr->zstream.avail_in)) + { + while (!png_ptr->idat_size) + { + png_byte chunk_length[4]; + + png_crc_finish(png_ptr, 0); + + png_read_data(png_ptr, chunk_length, 4); + png_ptr->idat_size = png_get_uint_31(png_ptr,chunk_length); + + png_reset_crc(png_ptr); + png_crc_read(png_ptr, png_ptr->chunk_name, 4); + if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) + png_error(png_ptr, "Not enough image data"); + } + png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size; + png_ptr->zstream.next_in = png_ptr->zbuf; + if (png_ptr->zbuf_size > png_ptr->idat_size) + png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size; + png_crc_read(png_ptr, png_ptr->zbuf, + (png_size_t)png_ptr->zstream.avail_in); + png_ptr->idat_size -= png_ptr->zstream.avail_in; + } + ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH); + if (ret == Z_STREAM_END) + { + if (png_ptr->zstream.avail_out || png_ptr->zstream.avail_in || + png_ptr->idat_size) + png_error(png_ptr, "Extra compressed data"); + png_ptr->mode |= PNG_AFTER_IDAT; + png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; + break; + } + if (ret != Z_OK) + png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg : + "Decompression error"); + + } while (png_ptr->zstream.avail_out); + + png_ptr->row_info.color_type = png_ptr->color_type; + png_ptr->row_info.width = png_ptr->iwidth; + png_ptr->row_info.channels = png_ptr->channels; + png_ptr->row_info.bit_depth = png_ptr->bit_depth; + png_ptr->row_info.pixel_depth = png_ptr->pixel_depth; + png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth, + png_ptr->row_info.width); + + if(png_ptr->row_buf[0]) + png_read_filter_row(png_ptr, &(png_ptr->row_info), + png_ptr->row_buf + 1, png_ptr->prev_row + 1, + (int)(png_ptr->row_buf[0])); + + png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf, + png_ptr->rowbytes + 1); + +#if defined(PNG_MNG_FEATURES_SUPPORTED) + if((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && + (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING)) + { + /* Intrapixel differencing */ + png_do_read_intrapixel(&(png_ptr->row_info), png_ptr->row_buf + 1); + } +#endif + + + if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA)) + png_do_read_transformations(png_ptr); + +#if defined(PNG_READ_INTERLACING_SUPPORTED) + /* blow up interlaced rows to full size */ + if (png_ptr->interlaced && + (png_ptr->transformations & PNG_INTERLACE)) + { + if (png_ptr->pass < 6) +/* old interface (pre-1.0.9): + png_do_read_interlace(&(png_ptr->row_info), + png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations); + */ + png_do_read_interlace(png_ptr); + + if (dsp_row != NULL) + png_combine_row(png_ptr, dsp_row, + png_pass_dsp_mask[png_ptr->pass]); + if (row != NULL) + png_combine_row(png_ptr, row, + png_pass_mask[png_ptr->pass]); + } + else +#endif + { + if (row != NULL) + png_combine_row(png_ptr, row, 0xff); + if (dsp_row != NULL) + png_combine_row(png_ptr, dsp_row, 0xff); + } + png_read_finish_row(png_ptr); + + if (png_ptr->read_row_fn != NULL) + (*(png_ptr->read_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass); +} +#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */ + +#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED +/* Read one or more rows of image data. If the image is interlaced, + * and png_set_interlace_handling() has been called, the rows need to + * contain the contents of the rows from the previous pass. If the + * image has alpha or transparency, and png_handle_alpha()[*] has been + * called, the rows contents must be initialized to the contents of the + * screen. + * + * "row" holds the actual image, and pixels are placed in it + * as they arrive. If the image is displayed after each pass, it will + * appear to "sparkle" in. "display_row" can be used to display a + * "chunky" progressive image, with finer detail added as it becomes + * available. If you do not want this "chunky" display, you may pass + * NULL for display_row. If you do not want the sparkle display, and + * you have not called png_handle_alpha(), you may pass NULL for rows. + * If you have called png_handle_alpha(), and the image has either an + * alpha channel or a transparency chunk, you must provide a buffer for + * rows. In this case, you do not have to provide a display_row buffer + * also, but you may. If the image is not interlaced, or if you have + * not called png_set_interlace_handling(), the display_row buffer will + * be ignored, so pass NULL to it. + * + * [*] png_handle_alpha() does not exist yet, as of this version of libpng + */ + +void PNGAPI +png_read_rows(png_structp png_ptr, png_bytepp row, + png_bytepp display_row, png_uint_32 num_rows) +{ + png_uint_32 i; + png_bytepp rp; + png_bytepp dp; + + png_debug(1, "in png_read_rows\n"); + rp = row; + dp = display_row; + if (rp != NULL && dp != NULL) + for (i = 0; i < num_rows; i++) + { + png_bytep rptr = *rp++; + png_bytep dptr = *dp++; + + png_read_row(png_ptr, rptr, dptr); + } + else if(rp != NULL) + for (i = 0; i < num_rows; i++) + { + png_bytep rptr = *rp; + png_read_row(png_ptr, rptr, png_bytep_NULL); + rp++; + } + else if(dp != NULL) + for (i = 0; i < num_rows; i++) + { + png_bytep dptr = *dp; + png_read_row(png_ptr, png_bytep_NULL, dptr); + dp++; + } +} +#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */ + +#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED +/* Read the entire image. If the image has an alpha channel or a tRNS + * chunk, and you have called png_handle_alpha()[*], you will need to + * initialize the image to the current image that PNG will be overlaying. + * We set the num_rows again here, in case it was incorrectly set in + * png_read_start_row() by a call to png_read_update_info() or + * png_start_read_image() if png_set_interlace_handling() wasn't called + * prior to either of these functions like it should have been. You can + * only call this function once. If you desire to have an image for + * each pass of a interlaced image, use png_read_rows() instead. + * + * [*] png_handle_alpha() does not exist yet, as of this version of libpng + */ +void PNGAPI +png_read_image(png_structp png_ptr, png_bytepp image) +{ + png_uint_32 i,image_height; + int pass, j; + png_bytepp rp; + + png_debug(1, "in png_read_image\n"); + +#ifdef PNG_READ_INTERLACING_SUPPORTED + pass = png_set_interlace_handling(png_ptr); +#else + if (png_ptr->interlaced) + png_error(png_ptr, + "Cannot read interlaced image -- interlace handler disabled."); + pass = 1; +#endif + + + image_height=png_ptr->height; + png_ptr->num_rows = image_height; /* Make sure this is set correctly */ + + for (j = 0; j < pass; j++) + { + rp = image; + for (i = 0; i < image_height; i++) + { + png_read_row(png_ptr, *rp, png_bytep_NULL); + rp++; + } + } +} +#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */ + +#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED +/* Read the end of the PNG file. Will not read past the end of the + * file, will verify the end is accurate, and will read any comments + * or time information at the end of the file, if info is not NULL. + */ +void PNGAPI +png_read_end(png_structp png_ptr, png_infop info_ptr) +{ + png_byte chunk_length[4]; + png_uint_32 length; + + png_debug(1, "in png_read_end\n"); + png_crc_finish(png_ptr, 0); /* Finish off CRC from last IDAT chunk */ + + do + { +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_IHDR; + PNG_IDAT; + PNG_IEND; + PNG_PLTE; +#if defined(PNG_READ_bKGD_SUPPORTED) + PNG_bKGD; +#endif +#if defined(PNG_READ_cHRM_SUPPORTED) + PNG_cHRM; +#endif +#if defined(PNG_READ_gAMA_SUPPORTED) + PNG_gAMA; +#endif +#if defined(PNG_READ_hIST_SUPPORTED) + PNG_hIST; +#endif +#if defined(PNG_READ_iCCP_SUPPORTED) + PNG_iCCP; +#endif +#if defined(PNG_READ_iTXt_SUPPORTED) + PNG_iTXt; +#endif +#if defined(PNG_READ_oFFs_SUPPORTED) + PNG_oFFs; +#endif +#if defined(PNG_READ_pCAL_SUPPORTED) + PNG_pCAL; +#endif +#if defined(PNG_READ_pHYs_SUPPORTED) + PNG_pHYs; +#endif +#if defined(PNG_READ_sBIT_SUPPORTED) + PNG_sBIT; +#endif +#if defined(PNG_READ_sCAL_SUPPORTED) + PNG_sCAL; +#endif +#if defined(PNG_READ_sPLT_SUPPORTED) + PNG_sPLT; +#endif +#if defined(PNG_READ_sRGB_SUPPORTED) + PNG_sRGB; +#endif +#if defined(PNG_READ_tEXt_SUPPORTED) + PNG_tEXt; +#endif +#if defined(PNG_READ_tIME_SUPPORTED) + PNG_tIME; +#endif +#if defined(PNG_READ_tRNS_SUPPORTED) + PNG_tRNS; +#endif +#if defined(PNG_READ_zTXt_SUPPORTED) + PNG_zTXt; +#endif +#endif /* PNG_USE_LOCAL_ARRAYS */ + + png_read_data(png_ptr, chunk_length, 4); + length = png_get_uint_31(png_ptr,chunk_length); + + png_reset_crc(png_ptr); + png_crc_read(png_ptr, png_ptr->chunk_name, 4); + + png_debug1(0, "Reading %s chunk.\n", png_ptr->chunk_name); + + if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4)) + png_handle_IHDR(png_ptr, info_ptr, length); + else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4)) + png_handle_IEND(png_ptr, info_ptr, length); +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED + else if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name)) + { + if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) + { + if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT)) + png_error(png_ptr, "Too many IDAT's found"); + } + png_handle_unknown(png_ptr, info_ptr, length); + if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4)) + png_ptr->mode |= PNG_HAVE_PLTE; + } +#endif + else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) + { + /* Zero length IDATs are legal after the last IDAT has been + * read, but not after other chunks have been read. + */ + if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT)) + png_error(png_ptr, "Too many IDAT's found"); + png_crc_finish(png_ptr, length); + } + else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4)) + png_handle_PLTE(png_ptr, info_ptr, length); +#if defined(PNG_READ_bKGD_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4)) + png_handle_bKGD(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_cHRM_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4)) + png_handle_cHRM(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_gAMA_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4)) + png_handle_gAMA(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_hIST_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4)) + png_handle_hIST(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_oFFs_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4)) + png_handle_oFFs(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_pCAL_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4)) + png_handle_pCAL(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_sCAL_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4)) + png_handle_sCAL(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_pHYs_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4)) + png_handle_pHYs(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_sBIT_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4)) + png_handle_sBIT(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_sRGB_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4)) + png_handle_sRGB(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_iCCP_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4)) + png_handle_iCCP(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_sPLT_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4)) + png_handle_sPLT(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_tEXt_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4)) + png_handle_tEXt(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_tIME_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4)) + png_handle_tIME(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_tRNS_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4)) + png_handle_tRNS(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_zTXt_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4)) + png_handle_zTXt(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_iTXt_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4)) + png_handle_iTXt(png_ptr, info_ptr, length); +#endif + else + png_handle_unknown(png_ptr, info_ptr, length); + } while (!(png_ptr->mode & PNG_HAVE_IEND)); +} +#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */ + +/* free all memory used by the read */ +void PNGAPI +png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr, + png_infopp end_info_ptr_ptr) +{ + png_structp png_ptr = NULL; + png_infop info_ptr = NULL, end_info_ptr = NULL; +#ifdef PNG_USER_MEM_SUPPORTED + png_free_ptr free_fn; + png_voidp mem_ptr; +#endif + + png_debug(1, "in png_destroy_read_struct\n"); + if (png_ptr_ptr != NULL) + png_ptr = *png_ptr_ptr; + + if (info_ptr_ptr != NULL) + info_ptr = *info_ptr_ptr; + + if (end_info_ptr_ptr != NULL) + end_info_ptr = *end_info_ptr_ptr; + +#ifdef PNG_USER_MEM_SUPPORTED + free_fn = png_ptr->free_fn; + mem_ptr = png_ptr->mem_ptr; +#endif + + png_read_destroy(png_ptr, info_ptr, end_info_ptr); + + if (info_ptr != NULL) + { +#if defined(PNG_TEXT_SUPPORTED) + png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, -1); +#endif + +#ifdef PNG_USER_MEM_SUPPORTED + png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn, + (png_voidp)mem_ptr); +#else + png_destroy_struct((png_voidp)info_ptr); +#endif + *info_ptr_ptr = NULL; + } + + if (end_info_ptr != NULL) + { +#if defined(PNG_READ_TEXT_SUPPORTED) + png_free_data(png_ptr, end_info_ptr, PNG_FREE_TEXT, -1); +#endif +#ifdef PNG_USER_MEM_SUPPORTED + png_destroy_struct_2((png_voidp)end_info_ptr, (png_free_ptr)free_fn, + (png_voidp)mem_ptr); +#else + png_destroy_struct((png_voidp)end_info_ptr); +#endif + *end_info_ptr_ptr = NULL; + } + + if (png_ptr != NULL) + { +#ifdef PNG_USER_MEM_SUPPORTED + png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn, + (png_voidp)mem_ptr); +#else + png_destroy_struct((png_voidp)png_ptr); +#endif + *png_ptr_ptr = NULL; + } +} + +/* free all memory used by the read (old method) */ +void /* PRIVATE */ +png_read_destroy(png_structp png_ptr, png_infop info_ptr, png_infop end_info_ptr) +{ +#ifdef PNG_SETJMP_SUPPORTED + jmp_buf tmp_jmp; +#endif + png_error_ptr error_fn; + png_error_ptr warning_fn; + png_voidp error_ptr; +#ifdef PNG_USER_MEM_SUPPORTED + png_free_ptr free_fn; +#endif + + png_debug(1, "in png_read_destroy\n"); + if (info_ptr != NULL) + png_info_destroy(png_ptr, info_ptr); + + if (end_info_ptr != NULL) + png_info_destroy(png_ptr, end_info_ptr); + + png_free(png_ptr, png_ptr->zbuf); + png_free(png_ptr, png_ptr->big_row_buf); + png_free(png_ptr, png_ptr->prev_row); +#if defined(PNG_READ_DITHER_SUPPORTED) + png_free(png_ptr, png_ptr->palette_lookup); + png_free(png_ptr, png_ptr->dither_index); +#endif +#if defined(PNG_READ_GAMMA_SUPPORTED) + png_free(png_ptr, png_ptr->gamma_table); +#endif +#if defined(PNG_READ_BACKGROUND_SUPPORTED) + png_free(png_ptr, png_ptr->gamma_from_1); + png_free(png_ptr, png_ptr->gamma_to_1); +#endif +#ifdef PNG_FREE_ME_SUPPORTED + if (png_ptr->free_me & PNG_FREE_PLTE) + png_zfree(png_ptr, png_ptr->palette); + png_ptr->free_me &= ~PNG_FREE_PLTE; +#else + if (png_ptr->flags & PNG_FLAG_FREE_PLTE) + png_zfree(png_ptr, png_ptr->palette); + png_ptr->flags &= ~PNG_FLAG_FREE_PLTE; +#endif +#if defined(PNG_tRNS_SUPPORTED) || \ + defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) +#ifdef PNG_FREE_ME_SUPPORTED + if (png_ptr->free_me & PNG_FREE_TRNS) + png_free(png_ptr, png_ptr->trans); + png_ptr->free_me &= ~PNG_FREE_TRNS; +#else + if (png_ptr->flags & PNG_FLAG_FREE_TRNS) + png_free(png_ptr, png_ptr->trans); + png_ptr->flags &= ~PNG_FLAG_FREE_TRNS; +#endif +#endif +#if defined(PNG_READ_hIST_SUPPORTED) +#ifdef PNG_FREE_ME_SUPPORTED + if (png_ptr->free_me & PNG_FREE_HIST) + png_free(png_ptr, png_ptr->hist); + png_ptr->free_me &= ~PNG_FREE_HIST; +#else + if (png_ptr->flags & PNG_FLAG_FREE_HIST) + png_free(png_ptr, png_ptr->hist); + png_ptr->flags &= ~PNG_FLAG_FREE_HIST; +#endif +#endif +#if defined(PNG_READ_GAMMA_SUPPORTED) + if (png_ptr->gamma_16_table != NULL) + { + int i; + int istop = (1 << (8 - png_ptr->gamma_shift)); + for (i = 0; i < istop; i++) + { + png_free(png_ptr, png_ptr->gamma_16_table[i]); + } + png_free(png_ptr, png_ptr->gamma_16_table); + } +#if defined(PNG_READ_BACKGROUND_SUPPORTED) + if (png_ptr->gamma_16_from_1 != NULL) + { + int i; + int istop = (1 << (8 - png_ptr->gamma_shift)); + for (i = 0; i < istop; i++) + { + png_free(png_ptr, png_ptr->gamma_16_from_1[i]); + } + png_free(png_ptr, png_ptr->gamma_16_from_1); + } + if (png_ptr->gamma_16_to_1 != NULL) + { + int i; + int istop = (1 << (8 - png_ptr->gamma_shift)); + for (i = 0; i < istop; i++) + { + png_free(png_ptr, png_ptr->gamma_16_to_1[i]); + } + png_free(png_ptr, png_ptr->gamma_16_to_1); + } +#endif +#endif +#if defined(PNG_TIME_RFC1123_SUPPORTED) + png_free(png_ptr, png_ptr->time_buffer); +#endif + + inflateEnd(&png_ptr->zstream); +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED + png_free(png_ptr, png_ptr->save_buffer); +#endif + +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +#ifdef PNG_TEXT_SUPPORTED + png_free(png_ptr, png_ptr->current_text); +#endif /* PNG_TEXT_SUPPORTED */ +#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ + + /* Save the important info out of the png_struct, in case it is + * being used again. + */ +#ifdef PNG_SETJMP_SUPPORTED + png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof (jmp_buf)); +#endif + + error_fn = png_ptr->error_fn; + warning_fn = png_ptr->warning_fn; + error_ptr = png_ptr->error_ptr; +#ifdef PNG_USER_MEM_SUPPORTED + free_fn = png_ptr->free_fn; +#endif + + png_memset(png_ptr, 0, png_sizeof (png_struct)); + + png_ptr->error_fn = error_fn; + png_ptr->warning_fn = warning_fn; + png_ptr->error_ptr = error_ptr; +#ifdef PNG_USER_MEM_SUPPORTED + png_ptr->free_fn = free_fn; +#endif + +#ifdef PNG_SETJMP_SUPPORTED + png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof (jmp_buf)); +#endif + +} + +void PNGAPI +png_set_read_status_fn(png_structp png_ptr, png_read_status_ptr read_row_fn) +{ + png_ptr->read_row_fn = read_row_fn; +} + + +#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED +#if defined(PNG_INFO_IMAGE_SUPPORTED) +void PNGAPI +png_read_png(png_structp png_ptr, png_infop info_ptr, + int transforms, + voidp params) +{ + int row; + +#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) + /* invert the alpha channel from opacity to transparency + */ + if (transforms & PNG_TRANSFORM_INVERT_ALPHA) + png_set_invert_alpha(png_ptr); +#endif + + /* png_read_info() gives us all of the information from the + * PNG file before the first IDAT (image data chunk). + */ + png_read_info(png_ptr, info_ptr); + if (info_ptr->height > PNG_UINT_32_MAX/png_sizeof(png_bytep)) + png_error(png_ptr,"Image is too high to process with png_read_png()"); + + /* -------------- image transformations start here ------------------- */ + +#if defined(PNG_READ_16_TO_8_SUPPORTED) + /* tell libpng to strip 16 bit/color files down to 8 bits per color + */ + if (transforms & PNG_TRANSFORM_STRIP_16) + png_set_strip_16(png_ptr); +#endif + +#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED) + /* Strip alpha bytes from the input data without combining with + * the background (not recommended). + */ + if (transforms & PNG_TRANSFORM_STRIP_ALPHA) + png_set_strip_alpha(png_ptr); +#endif + +#if defined(PNG_READ_PACK_SUPPORTED) && !defined(PNG_READ_EXPAND_SUPPORTED) + /* Extract multiple pixels with bit depths of 1, 2, or 4 from a single + * byte into separate bytes (useful for paletted and grayscale images). + */ + if (transforms & PNG_TRANSFORM_PACKING) + png_set_packing(png_ptr); +#endif + +#if defined(PNG_READ_PACKSWAP_SUPPORTED) + /* Change the order of packed pixels to least significant bit first + * (not useful if you are using png_set_packing). + */ + if (transforms & PNG_TRANSFORM_PACKSWAP) + png_set_packswap(png_ptr); +#endif + +#if defined(PNG_READ_EXPAND_SUPPORTED) + /* Expand paletted colors into true RGB triplets + * Expand grayscale images to full 8 bits from 1, 2, or 4 bits/pixel + * Expand paletted or RGB images with transparency to full alpha + * channels so the data will be available as RGBA quartets. + */ + if (transforms & PNG_TRANSFORM_EXPAND) + if ((png_ptr->bit_depth < 8) || + (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) || + (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))) + png_set_expand(png_ptr); +#endif + + /* We don't handle background color or gamma transformation or dithering. + */ + +#if defined(PNG_READ_INVERT_SUPPORTED) + /* invert monochrome files to have 0 as white and 1 as black + */ + if (transforms & PNG_TRANSFORM_INVERT_MONO) + png_set_invert_mono(png_ptr); +#endif + +#if defined(PNG_READ_SHIFT_SUPPORTED) + /* If you want to shift the pixel values from the range [0,255] or + * [0,65535] to the original [0,7] or [0,31], or whatever range the + * colors were originally in: + */ + if ((transforms & PNG_TRANSFORM_SHIFT) + && png_get_valid(png_ptr, info_ptr, PNG_INFO_sBIT)) + { + png_color_8p sig_bit; + + png_get_sBIT(png_ptr, info_ptr, &sig_bit); + png_set_shift(png_ptr, sig_bit); + } +#endif + +#if defined(PNG_READ_BGR_SUPPORTED) + /* flip the RGB pixels to BGR (or RGBA to BGRA) + */ + if (transforms & PNG_TRANSFORM_BGR) + png_set_bgr(png_ptr); +#endif + +#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) + /* swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) + */ + if (transforms & PNG_TRANSFORM_SWAP_ALPHA) + png_set_swap_alpha(png_ptr); +#endif + +#if defined(PNG_READ_SWAP_SUPPORTED) + /* swap bytes of 16 bit files to least significant byte first + */ + if (transforms & PNG_TRANSFORM_SWAP_ENDIAN) + png_set_swap(png_ptr); +#endif + + /* We don't handle adding filler bytes */ + + /* Optional call to gamma correct and add the background to the palette + * and update info structure. REQUIRED if you are expecting libpng to + * update the palette for you (i.e., you selected such a transform above). + */ + png_read_update_info(png_ptr, info_ptr); + + /* -------------- image transformations end here ------------------- */ + +#ifdef PNG_FREE_ME_SUPPORTED + png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0); +#endif + if(info_ptr->row_pointers == NULL) + { + info_ptr->row_pointers = (png_bytepp)png_malloc(png_ptr, + info_ptr->height * png_sizeof(png_bytep)); +#ifdef PNG_FREE_ME_SUPPORTED + info_ptr->free_me |= PNG_FREE_ROWS; +#endif + for (row = 0; row < (int)info_ptr->height; row++) + { + info_ptr->row_pointers[row] = (png_bytep)png_malloc(png_ptr, + png_get_rowbytes(png_ptr, info_ptr)); + } + } + + png_read_image(png_ptr, info_ptr->row_pointers); + info_ptr->valid |= PNG_INFO_IDAT; + + /* read rest of file, and get additional chunks in info_ptr - REQUIRED */ + png_read_end(png_ptr, info_ptr); + + if(transforms == 0 || params == NULL) + /* quiet compiler warnings */ return; + +} +#endif /* PNG_INFO_IMAGE_SUPPORTED */ +#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */ +#endif /* PNG_READ_SUPPORTED */ diff --git a/mod/pub.mod/libpng.mod/pngrio.c b/mod/pub.mod/libpng.mod/pngrio.c new file mode 100644 index 0000000..ce05cad --- /dev/null +++ b/mod/pub.mod/libpng.mod/pngrio.c @@ -0,0 +1,164 @@ + +/* pngrio.c - functions for data input + * + * Last changed in libpng 1.2.9 April 14, 2006 + * For conditions of distribution and use, see copyright notice in png.h + * Copyright (c) 1998-2006 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * + * This file provides a location for all input. Users who need + * special handling are expected to write a function that has the same + * arguments as this and performs a similar function, but that possibly + * has a different input method. Note that you shouldn't change this + * function, but rather write a replacement function and then make + * libpng use it at run time with png_set_read_fn(...). + */ + +#define PNG_INTERNAL +#include "png.h" + +#if defined(PNG_READ_SUPPORTED) + +/* Read the data from whatever input you are using. The default routine + reads from a file pointer. Note that this routine sometimes gets called + with very small lengths, so you should implement some kind of simple + buffering if you are using unbuffered reads. This should never be asked + to read more then 64K on a 16 bit machine. */ +void /* PRIVATE */ +png_read_data(png_structp png_ptr, png_bytep data, png_size_t length) +{ + png_debug1(4,"reading %d bytes\n", (int)length); + if (png_ptr->read_data_fn != NULL) + (*(png_ptr->read_data_fn))(png_ptr, data, length); + else + png_error(png_ptr, "Call to NULL read function"); +} + +#if !defined(PNG_NO_STDIO) +/* This is the function that does the actual reading of data. If you are + not reading from a standard C stream, you should create a replacement + read_data function and use it at run time with png_set_read_fn(), rather + than changing the library. */ +#ifndef USE_FAR_KEYWORD +void PNGAPI +png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length) +{ + png_size_t check; + + /* fread() returns 0 on error, so it is OK to store this in a png_size_t + * instead of an int, which is what fread() actually returns. + */ +#if defined(_WIN32_WCE) + if ( !ReadFile((HANDLE)(png_ptr->io_ptr), data, length, &check, NULL) ) + check = 0; +#else + check = (png_size_t)fread(data, (png_size_t)1, length, + (png_FILE_p)png_ptr->io_ptr); +#endif + + if (check != length) + png_error(png_ptr, "Read Error"); +} +#else +/* this is the model-independent version. Since the standard I/O library + can't handle far buffers in the medium and small models, we have to copy + the data. +*/ + +#define NEAR_BUF_SIZE 1024 +#define MIN(a,b) (a <= b ? a : b) + +static void PNGAPI +png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length) +{ + int check; + png_byte *n_data; + png_FILE_p io_ptr; + + /* Check if data really is near. If so, use usual code. */ + n_data = (png_byte *)CVT_PTR_NOCHECK(data); + io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr); + if ((png_bytep)n_data == data) + { +#if defined(_WIN32_WCE) + if ( !ReadFile((HANDLE)(png_ptr->io_ptr), data, length, &check, NULL) ) + check = 0; +#else + check = fread(n_data, 1, length, io_ptr); +#endif + } + else + { + png_byte buf[NEAR_BUF_SIZE]; + png_size_t read, remaining, err; + check = 0; + remaining = length; + do + { + read = MIN(NEAR_BUF_SIZE, remaining); +#if defined(_WIN32_WCE) + if ( !ReadFile((HANDLE)(io_ptr), buf, read, &err, NULL) ) + err = 0; +#else + err = fread(buf, (png_size_t)1, read, io_ptr); +#endif + png_memcpy(data, buf, read); /* copy far buffer to near buffer */ + if(err != read) + break; + else + check += err; + data += read; + remaining -= read; + } + while (remaining != 0); + } + if ((png_uint_32)check != (png_uint_32)length) + png_error(png_ptr, "read Error"); +} +#endif +#endif + +/* This function allows the application to supply a new input function + for libpng if standard C streams aren't being used. + + This function takes as its arguments: + png_ptr - pointer to a png input data structure + io_ptr - pointer to user supplied structure containing info about + the input functions. May be NULL. + read_data_fn - pointer to a new input function that takes as its + arguments a pointer to a png_struct, a pointer to + a location where input data can be stored, and a 32-bit + unsigned int that is the number of bytes to be read. + To exit and output any fatal error messages the new write + function should call png_error(png_ptr, "Error msg"). */ +void PNGAPI +png_set_read_fn(png_structp png_ptr, png_voidp io_ptr, + png_rw_ptr read_data_fn) +{ + png_ptr->io_ptr = io_ptr; + +#if !defined(PNG_NO_STDIO) + if (read_data_fn != NULL) + png_ptr->read_data_fn = read_data_fn; + else + png_ptr->read_data_fn = png_default_read_data; +#else + png_ptr->read_data_fn = read_data_fn; +#endif + + /* It is an error to write to a read device */ + if (png_ptr->write_data_fn != NULL) + { + png_ptr->write_data_fn = NULL; + png_warning(png_ptr, + "It's an error to set both read_data_fn and write_data_fn in the "); + png_warning(png_ptr, + "same structure. Resetting write_data_fn to NULL."); + } + +#if defined(PNG_WRITE_FLUSH_SUPPORTED) + png_ptr->output_flush_fn = NULL; +#endif +} +#endif /* PNG_READ_SUPPORTED */ diff --git a/mod/pub.mod/libpng.mod/pngrtran.c b/mod/pub.mod/libpng.mod/pngrtran.c new file mode 100644 index 0000000..bd1f597 --- /dev/null +++ b/mod/pub.mod/libpng.mod/pngrtran.c @@ -0,0 +1,4219 @@ + +/* pngrtran.c - transforms the data in a row for PNG readers + * + * Last changed in libpng 1.2.11 June 15, 2006 + * For conditions of distribution and use, see copyright notice in png.h + * Copyright (c) 1998-2006 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * + * This file contains functions optionally called by an application + * in order to tell libpng how to handle data when reading a PNG. + * Transformations that are used in both reading and writing are + * in pngtrans.c. + */ + +#define PNG_INTERNAL +#include "png.h" + +#if defined(PNG_READ_SUPPORTED) + +/* Set the action on getting a CRC error for an ancillary or critical chunk. */ +void PNGAPI +png_set_crc_action(png_structp png_ptr, int crit_action, int ancil_action) +{ + png_debug(1, "in png_set_crc_action\n"); + /* Tell libpng how we react to CRC errors in critical chunks */ + switch (crit_action) + { + case PNG_CRC_NO_CHANGE: /* leave setting as is */ + break; + case PNG_CRC_WARN_USE: /* warn/use data */ + png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK; + png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE; + break; + case PNG_CRC_QUIET_USE: /* quiet/use data */ + png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK; + png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE | + PNG_FLAG_CRC_CRITICAL_IGNORE; + break; + case PNG_CRC_WARN_DISCARD: /* not a valid action for critical data */ + png_warning(png_ptr, "Can't discard critical data on CRC error."); + case PNG_CRC_ERROR_QUIT: /* error/quit */ + case PNG_CRC_DEFAULT: + default: + png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK; + break; + } + + switch (ancil_action) + { + case PNG_CRC_NO_CHANGE: /* leave setting as is */ + break; + case PNG_CRC_WARN_USE: /* warn/use data */ + png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK; + png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE; + break; + case PNG_CRC_QUIET_USE: /* quiet/use data */ + png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK; + png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE | + PNG_FLAG_CRC_ANCILLARY_NOWARN; + break; + case PNG_CRC_ERROR_QUIT: /* error/quit */ + png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK; + png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_NOWARN; + break; + case PNG_CRC_WARN_DISCARD: /* warn/discard data */ + case PNG_CRC_DEFAULT: + default: + png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK; + break; + } +} + +#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \ + defined(PNG_FLOATING_POINT_SUPPORTED) +/* handle alpha and tRNS via a background color */ +void PNGAPI +png_set_background(png_structp png_ptr, + png_color_16p background_color, int background_gamma_code, + int need_expand, double background_gamma) +{ + png_debug(1, "in png_set_background\n"); + if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN) + { + png_warning(png_ptr, "Application must supply a known background gamma"); + return; + } + + png_ptr->transformations |= PNG_BACKGROUND; + png_memcpy(&(png_ptr->background), background_color, + png_sizeof(png_color_16)); + png_ptr->background_gamma = (float)background_gamma; + png_ptr->background_gamma_type = (png_byte)(background_gamma_code); + png_ptr->transformations |= (need_expand ? PNG_BACKGROUND_EXPAND : 0); + + /* Note: if need_expand is set and color_type is either RGB or RGB_ALPHA + * (in which case need_expand is superfluous anyway), the background color + * might actually be gray yet not be flagged as such. This is not a problem + * for the current code, which uses PNG_BACKGROUND_IS_GRAY only to + * decide when to do the png_do_gray_to_rgb() transformation. + */ + if ((need_expand && !(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) || + (!need_expand && background_color->red == background_color->green && + background_color->red == background_color->blue)) + png_ptr->mode |= PNG_BACKGROUND_IS_GRAY; +} +#endif + +#if defined(PNG_READ_16_TO_8_SUPPORTED) +/* strip 16 bit depth files to 8 bit depth */ +void PNGAPI +png_set_strip_16(png_structp png_ptr) +{ + png_debug(1, "in png_set_strip_16\n"); + png_ptr->transformations |= PNG_16_TO_8; +} +#endif + +#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED) +void PNGAPI +png_set_strip_alpha(png_structp png_ptr) +{ + png_debug(1, "in png_set_strip_alpha\n"); + png_ptr->flags |= PNG_FLAG_STRIP_ALPHA; +} +#endif + +#if defined(PNG_READ_DITHER_SUPPORTED) +/* Dither file to 8 bit. Supply a palette, the current number + * of elements in the palette, the maximum number of elements + * allowed, and a histogram if possible. If the current number + * of colors is greater then the maximum number, the palette will be + * modified to fit in the maximum number. "full_dither" indicates + * whether we need a dithering cube set up for RGB images, or if we + * simply are reducing the number of colors in a paletted image. + */ + +typedef struct png_dsort_struct +{ + struct png_dsort_struct FAR * next; + png_byte left; + png_byte right; +} png_dsort; +typedef png_dsort FAR * png_dsortp; +typedef png_dsort FAR * FAR * png_dsortpp; + +void PNGAPI +png_set_dither(png_structp png_ptr, png_colorp palette, + int num_palette, int maximum_colors, png_uint_16p histogram, + int full_dither) +{ + png_debug(1, "in png_set_dither\n"); + png_ptr->transformations |= PNG_DITHER; + + if (!full_dither) + { + int i; + + png_ptr->dither_index = (png_bytep)png_malloc(png_ptr, + (png_uint_32)(num_palette * png_sizeof (png_byte))); + for (i = 0; i < num_palette; i++) + png_ptr->dither_index[i] = (png_byte)i; + } + + if (num_palette > maximum_colors) + { + if (histogram != NULL) + { + /* This is easy enough, just throw out the least used colors. + Perhaps not the best solution, but good enough. */ + + int i; + + /* initialize an array to sort colors */ + png_ptr->dither_sort = (png_bytep)png_malloc(png_ptr, + (png_uint_32)(num_palette * png_sizeof (png_byte))); + + /* initialize the dither_sort array */ + for (i = 0; i < num_palette; i++) + png_ptr->dither_sort[i] = (png_byte)i; + + /* Find the least used palette entries by starting a + bubble sort, and running it until we have sorted + out enough colors. Note that we don't care about + sorting all the colors, just finding which are + least used. */ + + for (i = num_palette - 1; i >= maximum_colors; i--) + { + int done; /* to stop early if the list is pre-sorted */ + int j; + + done = 1; + for (j = 0; j < i; j++) + { + if (histogram[png_ptr->dither_sort[j]] + < histogram[png_ptr->dither_sort[j + 1]]) + { + png_byte t; + + t = png_ptr->dither_sort[j]; + png_ptr->dither_sort[j] = png_ptr->dither_sort[j + 1]; + png_ptr->dither_sort[j + 1] = t; + done = 0; + } + } + if (done) + break; + } + + /* swap the palette around, and set up a table, if necessary */ + if (full_dither) + { + int j = num_palette; + + /* put all the useful colors within the max, but don't + move the others */ + for (i = 0; i < maximum_colors; i++) + { + if ((int)png_ptr->dither_sort[i] >= maximum_colors) + { + do + j--; + while ((int)png_ptr->dither_sort[j] >= maximum_colors); + palette[i] = palette[j]; + } + } + } + else + { + int j = num_palette; + + /* move all the used colors inside the max limit, and + develop a translation table */ + for (i = 0; i < maximum_colors; i++) + { + /* only move the colors we need to */ + if ((int)png_ptr->dither_sort[i] >= maximum_colors) + { + png_color tmp_color; + + do + j--; + while ((int)png_ptr->dither_sort[j] >= maximum_colors); + + tmp_color = palette[j]; + palette[j] = palette[i]; + palette[i] = tmp_color; + /* indicate where the color went */ + png_ptr->dither_index[j] = (png_byte)i; + png_ptr->dither_index[i] = (png_byte)j; + } + } + + /* find closest color for those colors we are not using */ + for (i = 0; i < num_palette; i++) + { + if ((int)png_ptr->dither_index[i] >= maximum_colors) + { + int min_d, k, min_k, d_index; + + /* find the closest color to one we threw out */ + d_index = png_ptr->dither_index[i]; + min_d = PNG_COLOR_DIST(palette[d_index], palette[0]); + for (k = 1, min_k = 0; k < maximum_colors; k++) + { + int d; + + d = PNG_COLOR_DIST(palette[d_index], palette[k]); + + if (d < min_d) + { + min_d = d; + min_k = k; + } + } + /* point to closest color */ + png_ptr->dither_index[i] = (png_byte)min_k; + } + } + } + png_free(png_ptr, png_ptr->dither_sort); + png_ptr->dither_sort=NULL; + } + else + { + /* This is much harder to do simply (and quickly). Perhaps + we need to go through a median cut routine, but those + don't always behave themselves with only a few colors + as input. So we will just find the closest two colors, + and throw out one of them (chosen somewhat randomly). + [We don't understand this at all, so if someone wants to + work on improving it, be our guest - AED, GRP] + */ + int i; + int max_d; + int num_new_palette; + png_dsortp t; + png_dsortpp hash; + + t=NULL; + + /* initialize palette index arrays */ + png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr, + (png_uint_32)(num_palette * png_sizeof (png_byte))); + png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr, + (png_uint_32)(num_palette * png_sizeof (png_byte))); + + /* initialize the sort array */ + for (i = 0; i < num_palette; i++) + { + png_ptr->index_to_palette[i] = (png_byte)i; + png_ptr->palette_to_index[i] = (png_byte)i; + } + + hash = (png_dsortpp)png_malloc(png_ptr, (png_uint_32)(769 * + png_sizeof (png_dsortp))); + for (i = 0; i < 769; i++) + hash[i] = NULL; +/* png_memset(hash, 0, 769 * png_sizeof (png_dsortp)); */ + + num_new_palette = num_palette; + + /* initial wild guess at how far apart the farthest pixel + pair we will be eliminating will be. Larger + numbers mean more areas will be allocated, Smaller + numbers run the risk of not saving enough data, and + having to do this all over again. + + I have not done extensive checking on this number. + */ + max_d = 96; + + while (num_new_palette > maximum_colors) + { + for (i = 0; i < num_new_palette - 1; i++) + { + int j; + + for (j = i + 1; j < num_new_palette; j++) + { + int d; + + d = PNG_COLOR_DIST(palette[i], palette[j]); + + if (d <= max_d) + { + + t = (png_dsortp)png_malloc_warn(png_ptr, + (png_uint_32)(png_sizeof(png_dsort))); + if (t == NULL) + break; + t->next = hash[d]; + t->left = (png_byte)i; + t->right = (png_byte)j; + hash[d] = t; + } + } + if (t == NULL) + break; + } + + if (t != NULL) + for (i = 0; i <= max_d; i++) + { + if (hash[i] != NULL) + { + png_dsortp p; + + for (p = hash[i]; p; p = p->next) + { + if ((int)png_ptr->index_to_palette[p->left] + < num_new_palette && + (int)png_ptr->index_to_palette[p->right] + < num_new_palette) + { + int j, next_j; + + if (num_new_palette & 0x01) + { + j = p->left; + next_j = p->right; + } + else + { + j = p->right; + next_j = p->left; + } + + num_new_palette--; + palette[png_ptr->index_to_palette[j]] + = palette[num_new_palette]; + if (!full_dither) + { + int k; + + for (k = 0; k < num_palette; k++) + { + if (png_ptr->dither_index[k] == + png_ptr->index_to_palette[j]) + png_ptr->dither_index[k] = + png_ptr->index_to_palette[next_j]; + if ((int)png_ptr->dither_index[k] == + num_new_palette) + png_ptr->dither_index[k] = + png_ptr->index_to_palette[j]; + } + } + + png_ptr->index_to_palette[png_ptr->palette_to_index + [num_new_palette]] = png_ptr->index_to_palette[j]; + png_ptr->palette_to_index[png_ptr->index_to_palette[j]] + = png_ptr->palette_to_index[num_new_palette]; + + png_ptr->index_to_palette[j] = (png_byte)num_new_palette; + png_ptr->palette_to_index[num_new_palette] = (png_byte)j; + } + if (num_new_palette <= maximum_colors) + break; + } + if (num_new_palette <= maximum_colors) + break; + } + } + + for (i = 0; i < 769; i++) + { + if (hash[i] != NULL) + { + png_dsortp p = hash[i]; + while (p) + { + t = p->next; + png_free(png_ptr, p); + p = t; + } + } + hash[i] = 0; + } + max_d += 96; + } + png_free(png_ptr, hash); + png_free(png_ptr, png_ptr->palette_to_index); + png_free(png_ptr, png_ptr->index_to_palette); + png_ptr->palette_to_index=NULL; + png_ptr->index_to_palette=NULL; + } + num_palette = maximum_colors; + } + if (png_ptr->palette == NULL) + { + png_ptr->palette = palette; + } + png_ptr->num_palette = (png_uint_16)num_palette; + + if (full_dither) + { + int i; + png_bytep distance; + int total_bits = PNG_DITHER_RED_BITS + PNG_DITHER_GREEN_BITS + + PNG_DITHER_BLUE_BITS; + int num_red = (1 << PNG_DITHER_RED_BITS); + int num_green = (1 << PNG_DITHER_GREEN_BITS); + int num_blue = (1 << PNG_DITHER_BLUE_BITS); + png_size_t num_entries = ((png_size_t)1 << total_bits); + + png_ptr->palette_lookup = (png_bytep )png_malloc(png_ptr, + (png_uint_32)(num_entries * png_sizeof (png_byte))); + + png_memset(png_ptr->palette_lookup, 0, num_entries * + png_sizeof (png_byte)); + + distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries * + png_sizeof(png_byte))); + + png_memset(distance, 0xff, num_entries * png_sizeof(png_byte)); + + for (i = 0; i < num_palette; i++) + { + int ir, ig, ib; + int r = (palette[i].red >> (8 - PNG_DITHER_RED_BITS)); + int g = (palette[i].green >> (8 - PNG_DITHER_GREEN_BITS)); + int b = (palette[i].blue >> (8 - PNG_DITHER_BLUE_BITS)); + + for (ir = 0; ir < num_red; ir++) + { + /* int dr = abs(ir - r); */ + int dr = ((ir > r) ? ir - r : r - ir); + int index_r = (ir << (PNG_DITHER_BLUE_BITS + PNG_DITHER_GREEN_BITS)); + + for (ig = 0; ig < num_green; ig++) + { + /* int dg = abs(ig - g); */ + int dg = ((ig > g) ? ig - g : g - ig); + int dt = dr + dg; + int dm = ((dr > dg) ? dr : dg); + int index_g = index_r | (ig << PNG_DITHER_BLUE_BITS); + + for (ib = 0; ib < num_blue; ib++) + { + int d_index = index_g | ib; + /* int db = abs(ib - b); */ + int db = ((ib > b) ? ib - b : b - ib); + int dmax = ((dm > db) ? dm : db); + int d = dmax + dt + db; + + if (d < (int)distance[d_index]) + { + distance[d_index] = (png_byte)d; + png_ptr->palette_lookup[d_index] = (png_byte)i; + } + } + } + } + } + + png_free(png_ptr, distance); + } +} +#endif + +#if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED) +/* Transform the image from the file_gamma to the screen_gamma. We + * only do transformations on images where the file_gamma and screen_gamma + * are not close reciprocals, otherwise it slows things down slightly, and + * also needlessly introduces small errors. + * + * We will turn off gamma transformation later if no semitransparent entries + * are present in the tRNS array for palette images. We can't do it here + * because we don't necessarily have the tRNS chunk yet. + */ +void PNGAPI +png_set_gamma(png_structp png_ptr, double scrn_gamma, double file_gamma) +{ + png_debug(1, "in png_set_gamma\n"); + if ((fabs(scrn_gamma * file_gamma - 1.0) > PNG_GAMMA_THRESHOLD) || + (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) || + (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)) + png_ptr->transformations |= PNG_GAMMA; + png_ptr->gamma = (float)file_gamma; + png_ptr->screen_gamma = (float)scrn_gamma; +} +#endif + +#if defined(PNG_READ_EXPAND_SUPPORTED) +/* Expand paletted images to RGB, expand grayscale images of + * less than 8-bit depth to 8-bit depth, and expand tRNS chunks + * to alpha channels. + */ +void PNGAPI +png_set_expand(png_structp png_ptr) +{ + png_debug(1, "in png_set_expand\n"); + png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); +} + +/* GRR 19990627: the following three functions currently are identical + * to png_set_expand(). However, it is entirely reasonable that someone + * might wish to expand an indexed image to RGB but *not* expand a single, + * fully transparent palette entry to a full alpha channel--perhaps instead + * convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace + * the transparent color with a particular RGB value, or drop tRNS entirely. + * IOW, a future version of the library may make the transformations flag + * a bit more fine-grained, with separate bits for each of these three + * functions. + * + * More to the point, these functions make it obvious what libpng will be + * doing, whereas "expand" can (and does) mean any number of things. + * + * GRP 20060307: In libpng-1.4.0, png_set_gray_1_2_4_to_8() was modified + * to expand only the sample depth but not to expand the tRNS to alpha. + */ + +/* Expand paletted images to RGB. */ +void PNGAPI +png_set_palette_to_rgb(png_structp png_ptr) +{ + png_debug(1, "in png_set_palette_to_rgb\n"); + png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); +} + +#if !defined(PNG_1_0_X) +/* Expand grayscale images of less than 8-bit depth to 8 bits. */ +void PNGAPI +png_set_expand_gray_1_2_4_to_8(png_structp png_ptr) +{ + png_debug(1, "in png_set_expand_gray_1_2_4_to_8\n"); + png_ptr->transformations |= PNG_EXPAND_tRNS; +} +#endif + +#if defined(PNG_1_0_X) || defined(PNG_1_2_X) +/* Expand grayscale images of less than 8-bit depth to 8 bits. */ +/* Deprecated as of libpng-1.2.9 */ +void PNGAPI +png_set_gray_1_2_4_to_8(png_structp png_ptr) +{ + png_debug(1, "in png_set_gray_1_2_4_to_8\n"); + png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); +} +#endif + + +/* Expand tRNS chunks to alpha channels. */ +void PNGAPI +png_set_tRNS_to_alpha(png_structp png_ptr) +{ + png_debug(1, "in png_set_expand\n"); + png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); +} +#endif /* defined(PNG_READ_EXPAND_SUPPORTED) */ + +#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) +void PNGAPI +png_set_gray_to_rgb(png_structp png_ptr) +{ + png_debug(1, "in png_set_gray_to_rgb\n"); + png_ptr->transformations |= PNG_GRAY_TO_RGB; +} +#endif + +#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) +#if defined(PNG_FLOATING_POINT_SUPPORTED) +/* Convert a RGB image to a grayscale of the same width. This allows us, + * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image. + */ + +void PNGAPI +png_set_rgb_to_gray(png_structp png_ptr, int error_action, double red, + double green) +{ + int red_fixed = (int)((float)red*100000.0 + 0.5); + int green_fixed = (int)((float)green*100000.0 + 0.5); + png_set_rgb_to_gray_fixed(png_ptr, error_action, red_fixed, green_fixed); +} +#endif + +void PNGAPI +png_set_rgb_to_gray_fixed(png_structp png_ptr, int error_action, + png_fixed_point red, png_fixed_point green) +{ + png_debug(1, "in png_set_rgb_to_gray\n"); + switch(error_action) + { + case 1: png_ptr->transformations |= PNG_RGB_TO_GRAY; + break; + case 2: png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN; + break; + case 3: png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR; + } + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) +#if defined(PNG_READ_EXPAND_SUPPORTED) + png_ptr->transformations |= PNG_EXPAND; +#else + { + png_warning(png_ptr, "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED."); + png_ptr->transformations &= ~PNG_RGB_TO_GRAY; + } +#endif + { + png_uint_16 red_int, green_int; + if(red < 0 || green < 0) + { + red_int = 6968; /* .212671 * 32768 + .5 */ + green_int = 23434; /* .715160 * 32768 + .5 */ + } + else if(red + green < 100000L) + { + red_int = (png_uint_16)(((png_uint_32)red*32768L)/100000L); + green_int = (png_uint_16)(((png_uint_32)green*32768L)/100000L); + } + else + { + png_warning(png_ptr, "ignoring out of range rgb_to_gray coefficients"); + red_int = 6968; + green_int = 23434; + } + png_ptr->rgb_to_gray_red_coeff = red_int; + png_ptr->rgb_to_gray_green_coeff = green_int; + png_ptr->rgb_to_gray_blue_coeff = (png_uint_16)(32768-red_int-green_int); + } +} +#endif + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_LEGACY_SUPPORTED) +void PNGAPI +png_set_read_user_transform_fn(png_structp png_ptr, png_user_transform_ptr + read_user_transform_fn) +{ + png_debug(1, "in png_set_read_user_transform_fn\n"); +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) + png_ptr->transformations |= PNG_USER_TRANSFORM; + png_ptr->read_user_transform_fn = read_user_transform_fn; +#endif +#ifdef PNG_LEGACY_SUPPORTED + if(read_user_transform_fn) + png_warning(png_ptr, + "This version of libpng does not support user transforms"); +#endif +} +#endif + +/* Initialize everything needed for the read. This includes modifying + * the palette. + */ +void /* PRIVATE */ +png_init_read_transformations(png_structp png_ptr) +{ + png_debug(1, "in png_init_read_transformations\n"); +#if defined(PNG_USELESS_TESTS_SUPPORTED) + if(png_ptr != NULL) +#endif + { +#if defined(PNG_READ_BACKGROUND_SUPPORTED) || defined(PNG_READ_SHIFT_SUPPORTED) \ + || defined(PNG_READ_GAMMA_SUPPORTED) + int color_type = png_ptr->color_type; +#endif + +#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED) + if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) && + (png_ptr->transformations & PNG_EXPAND)) + { + if (!(color_type & PNG_COLOR_MASK_COLOR)) /* i.e., GRAY or GRAY_ALPHA */ + { + /* expand background and tRNS chunks */ + switch (png_ptr->bit_depth) + { + case 1: + png_ptr->background.gray *= (png_uint_16)0xff; + png_ptr->background.red = png_ptr->background.green + = png_ptr->background.blue = png_ptr->background.gray; + if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) + { + png_ptr->trans_values.gray *= (png_uint_16)0xff; + png_ptr->trans_values.red = png_ptr->trans_values.green + = png_ptr->trans_values.blue = png_ptr->trans_values.gray; + } + break; + case 2: + png_ptr->background.gray *= (png_uint_16)0x55; + png_ptr->background.red = png_ptr->background.green + = png_ptr->background.blue = png_ptr->background.gray; + if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) + { + png_ptr->trans_values.gray *= (png_uint_16)0x55; + png_ptr->trans_values.red = png_ptr->trans_values.green + = png_ptr->trans_values.blue = png_ptr->trans_values.gray; + } + break; + case 4: + png_ptr->background.gray *= (png_uint_16)0x11; + png_ptr->background.red = png_ptr->background.green + = png_ptr->background.blue = png_ptr->background.gray; + if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) + { + png_ptr->trans_values.gray *= (png_uint_16)0x11; + png_ptr->trans_values.red = png_ptr->trans_values.green + = png_ptr->trans_values.blue = png_ptr->trans_values.gray; + } + break; + case 8: + case 16: + png_ptr->background.red = png_ptr->background.green + = png_ptr->background.blue = png_ptr->background.gray; + break; + } + } + else if (color_type == PNG_COLOR_TYPE_PALETTE) + { + png_ptr->background.red = + png_ptr->palette[png_ptr->background.index].red; + png_ptr->background.green = + png_ptr->palette[png_ptr->background.index].green; + png_ptr->background.blue = + png_ptr->palette[png_ptr->background.index].blue; + +#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) + if (png_ptr->transformations & PNG_INVERT_ALPHA) + { +#if defined(PNG_READ_EXPAND_SUPPORTED) + if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) +#endif + { + /* invert the alpha channel (in tRNS) unless the pixels are + going to be expanded, in which case leave it for later */ + int i,istop; + istop=(int)png_ptr->num_trans; + for (i=0; i<istop; i++) + png_ptr->trans[i] = (png_byte)(255 - png_ptr->trans[i]); + } + } +#endif + + } + } +#endif + +#if defined(PNG_READ_BACKGROUND_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED) + png_ptr->background_1 = png_ptr->background; +#endif +#if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED) + + if ((color_type == PNG_COLOR_TYPE_PALETTE && png_ptr->num_trans != 0) + && (fabs(png_ptr->screen_gamma * png_ptr->gamma - 1.0) + < PNG_GAMMA_THRESHOLD)) + { + int i,k; + k=0; + for (i=0; i<png_ptr->num_trans; i++) + { + if (png_ptr->trans[i] != 0 && png_ptr->trans[i] != 0xff) + k=1; /* partial transparency is present */ + } + if (k == 0) + png_ptr->transformations &= (~PNG_GAMMA); + } + + if ((png_ptr->transformations & (PNG_GAMMA | PNG_RGB_TO_GRAY)) && + png_ptr->gamma != 0.0) + { + png_build_gamma_table(png_ptr); +#if defined(PNG_READ_BACKGROUND_SUPPORTED) + if (png_ptr->transformations & PNG_BACKGROUND) + { + if (color_type == PNG_COLOR_TYPE_PALETTE) + { + /* could skip if no transparency and + */ + png_color back, back_1; + png_colorp palette = png_ptr->palette; + int num_palette = png_ptr->num_palette; + int i; + if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE) + { + back.red = png_ptr->gamma_table[png_ptr->background.red]; + back.green = png_ptr->gamma_table[png_ptr->background.green]; + back.blue = png_ptr->gamma_table[png_ptr->background.blue]; + + back_1.red = png_ptr->gamma_to_1[png_ptr->background.red]; + back_1.green = png_ptr->gamma_to_1[png_ptr->background.green]; + back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue]; + } + else + { + double g, gs; + + switch (png_ptr->background_gamma_type) + { + case PNG_BACKGROUND_GAMMA_SCREEN: + g = (png_ptr->screen_gamma); + gs = 1.0; + break; + case PNG_BACKGROUND_GAMMA_FILE: + g = 1.0 / (png_ptr->gamma); + gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma); + break; + case PNG_BACKGROUND_GAMMA_UNIQUE: + g = 1.0 / (png_ptr->background_gamma); + gs = 1.0 / (png_ptr->background_gamma * + png_ptr->screen_gamma); + break; + default: + g = 1.0; /* back_1 */ + gs = 1.0; /* back */ + } + + if ( fabs(gs - 1.0) < PNG_GAMMA_THRESHOLD) + { + back.red = (png_byte)png_ptr->background.red; + back.green = (png_byte)png_ptr->background.green; + back.blue = (png_byte)png_ptr->background.blue; + } + else + { + back.red = (png_byte)(pow( + (double)png_ptr->background.red/255, gs) * 255.0 + .5); + back.green = (png_byte)(pow( + (double)png_ptr->background.green/255, gs) * 255.0 + .5); + back.blue = (png_byte)(pow( + (double)png_ptr->background.blue/255, gs) * 255.0 + .5); + } + + back_1.red = (png_byte)(pow( + (double)png_ptr->background.red/255, g) * 255.0 + .5); + back_1.green = (png_byte)(pow( + (double)png_ptr->background.green/255, g) * 255.0 + .5); + back_1.blue = (png_byte)(pow( + (double)png_ptr->background.blue/255, g) * 255.0 + .5); + } + for (i = 0; i < num_palette; i++) + { + if (i < (int)png_ptr->num_trans && png_ptr->trans[i] != 0xff) + { + if (png_ptr->trans[i] == 0) + { + palette[i] = back; + } + else /* if (png_ptr->trans[i] != 0xff) */ + { + png_byte v, w; + + v = png_ptr->gamma_to_1[palette[i].red]; + png_composite(w, v, png_ptr->trans[i], back_1.red); + palette[i].red = png_ptr->gamma_from_1[w]; + + v = png_ptr->gamma_to_1[palette[i].green]; + png_composite(w, v, png_ptr->trans[i], back_1.green); + palette[i].green = png_ptr->gamma_from_1[w]; + + v = png_ptr->gamma_to_1[palette[i].blue]; + png_composite(w, v, png_ptr->trans[i], back_1.blue); + palette[i].blue = png_ptr->gamma_from_1[w]; + } + } + else + { + palette[i].red = png_ptr->gamma_table[palette[i].red]; + palette[i].green = png_ptr->gamma_table[palette[i].green]; + palette[i].blue = png_ptr->gamma_table[palette[i].blue]; + } + } + } + /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */ + else + /* color_type != PNG_COLOR_TYPE_PALETTE */ + { + double m = (double)(((png_uint_32)1 << png_ptr->bit_depth) - 1); + double g = 1.0; + double gs = 1.0; + + switch (png_ptr->background_gamma_type) + { + case PNG_BACKGROUND_GAMMA_SCREEN: + g = (png_ptr->screen_gamma); + gs = 1.0; + break; + case PNG_BACKGROUND_GAMMA_FILE: + g = 1.0 / (png_ptr->gamma); + gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma); + break; + case PNG_BACKGROUND_GAMMA_UNIQUE: + g = 1.0 / (png_ptr->background_gamma); + gs = 1.0 / (png_ptr->background_gamma * + png_ptr->screen_gamma); + break; + } + + png_ptr->background_1.gray = (png_uint_16)(pow( + (double)png_ptr->background.gray / m, g) * m + .5); + png_ptr->background.gray = (png_uint_16)(pow( + (double)png_ptr->background.gray / m, gs) * m + .5); + + if ((png_ptr->background.red != png_ptr->background.green) || + (png_ptr->background.red != png_ptr->background.blue) || + (png_ptr->background.red != png_ptr->background.gray)) + { + /* RGB or RGBA with color background */ + png_ptr->background_1.red = (png_uint_16)(pow( + (double)png_ptr->background.red / m, g) * m + .5); + png_ptr->background_1.green = (png_uint_16)(pow( + (double)png_ptr->background.green / m, g) * m + .5); + png_ptr->background_1.blue = (png_uint_16)(pow( + (double)png_ptr->background.blue / m, g) * m + .5); + png_ptr->background.red = (png_uint_16)(pow( + (double)png_ptr->background.red / m, gs) * m + .5); + png_ptr->background.green = (png_uint_16)(pow( + (double)png_ptr->background.green / m, gs) * m + .5); + png_ptr->background.blue = (png_uint_16)(pow( + (double)png_ptr->background.blue / m, gs) * m + .5); + } + else + { + /* GRAY, GRAY ALPHA, RGB, or RGBA with gray background */ + png_ptr->background_1.red = png_ptr->background_1.green + = png_ptr->background_1.blue = png_ptr->background_1.gray; + png_ptr->background.red = png_ptr->background.green + = png_ptr->background.blue = png_ptr->background.gray; + } + } + } + else + /* transformation does not include PNG_BACKGROUND */ +#endif /* PNG_READ_BACKGROUND_SUPPORTED */ + if (color_type == PNG_COLOR_TYPE_PALETTE) + { + png_colorp palette = png_ptr->palette; + int num_palette = png_ptr->num_palette; + int i; + + for (i = 0; i < num_palette; i++) + { + palette[i].red = png_ptr->gamma_table[palette[i].red]; + palette[i].green = png_ptr->gamma_table[palette[i].green]; + palette[i].blue = png_ptr->gamma_table[palette[i].blue]; + } + } + } +#if defined(PNG_READ_BACKGROUND_SUPPORTED) + else +#endif +#endif /* PNG_READ_GAMMA_SUPPORTED && PNG_FLOATING_POINT_SUPPORTED */ +#if defined(PNG_READ_BACKGROUND_SUPPORTED) + /* No GAMMA transformation */ + if ((png_ptr->transformations & PNG_BACKGROUND) && + (color_type == PNG_COLOR_TYPE_PALETTE)) + { + int i; + int istop = (int)png_ptr->num_trans; + png_color back; + png_colorp palette = png_ptr->palette; + + back.red = (png_byte)png_ptr->background.red; + back.green = (png_byte)png_ptr->background.green; + back.blue = (png_byte)png_ptr->background.blue; + + for (i = 0; i < istop; i++) + { + if (png_ptr->trans[i] == 0) + { + palette[i] = back; + } + else if (png_ptr->trans[i] != 0xff) + { + /* The png_composite() macro is defined in png.h */ + png_composite(palette[i].red, palette[i].red, + png_ptr->trans[i], back.red); + png_composite(palette[i].green, palette[i].green, + png_ptr->trans[i], back.green); + png_composite(palette[i].blue, palette[i].blue, + png_ptr->trans[i], back.blue); + } + } + } +#endif /* PNG_READ_BACKGROUND_SUPPORTED */ + +#if defined(PNG_READ_SHIFT_SUPPORTED) + if ((png_ptr->transformations & PNG_SHIFT) && + (color_type == PNG_COLOR_TYPE_PALETTE)) + { + png_uint_16 i; + png_uint_16 istop = png_ptr->num_palette; + int sr = 8 - png_ptr->sig_bit.red; + int sg = 8 - png_ptr->sig_bit.green; + int sb = 8 - png_ptr->sig_bit.blue; + + if (sr < 0 || sr > 8) + sr = 0; + if (sg < 0 || sg > 8) + sg = 0; + if (sb < 0 || sb > 8) + sb = 0; + for (i = 0; i < istop; i++) + { + png_ptr->palette[i].red >>= sr; + png_ptr->palette[i].green >>= sg; + png_ptr->palette[i].blue >>= sb; + } + } +#endif /* PNG_READ_SHIFT_SUPPORTED */ + } +#if !defined(PNG_READ_GAMMA_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED) \ + && !defined(PNG_READ_BACKGROUND_SUPPORTED) + if(png_ptr) + return; +#endif +} + +/* Modify the info structure to reflect the transformations. The + * info should be updated so a PNG file could be written with it, + * assuming the transformations result in valid PNG data. + */ +void /* PRIVATE */ +png_read_transform_info(png_structp png_ptr, png_infop info_ptr) +{ + png_debug(1, "in png_read_transform_info\n"); +#if defined(PNG_READ_EXPAND_SUPPORTED) + if (png_ptr->transformations & PNG_EXPAND) + { + if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { + if (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND_tRNS)) + info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA; + else + info_ptr->color_type = PNG_COLOR_TYPE_RGB; + info_ptr->bit_depth = 8; + info_ptr->num_trans = 0; + } + else + { + if (png_ptr->num_trans) + { + if (png_ptr->transformations & PNG_EXPAND_tRNS) + info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; + else + info_ptr->color_type |= PNG_COLOR_MASK_COLOR; + } + if (info_ptr->bit_depth < 8) + info_ptr->bit_depth = 8; + info_ptr->num_trans = 0; + } + } +#endif + +#if defined(PNG_READ_BACKGROUND_SUPPORTED) + if (png_ptr->transformations & PNG_BACKGROUND) + { + info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA; + info_ptr->num_trans = 0; + info_ptr->background = png_ptr->background; + } +#endif + +#if defined(PNG_READ_GAMMA_SUPPORTED) + if (png_ptr->transformations & PNG_GAMMA) + { +#ifdef PNG_FLOATING_POINT_SUPPORTED + info_ptr->gamma = png_ptr->gamma; +#endif +#ifdef PNG_FIXED_POINT_SUPPORTED + info_ptr->int_gamma = png_ptr->int_gamma; +#endif + } +#endif + +#if defined(PNG_READ_16_TO_8_SUPPORTED) + if ((png_ptr->transformations & PNG_16_TO_8) && (info_ptr->bit_depth == 16)) + info_ptr->bit_depth = 8; +#endif + +#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) + if (png_ptr->transformations & PNG_GRAY_TO_RGB) + info_ptr->color_type |= PNG_COLOR_MASK_COLOR; +#endif + +#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) + if (png_ptr->transformations & PNG_RGB_TO_GRAY) + info_ptr->color_type &= ~PNG_COLOR_MASK_COLOR; +#endif + +#if defined(PNG_READ_DITHER_SUPPORTED) + if (png_ptr->transformations & PNG_DITHER) + { + if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) || + (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) && + png_ptr->palette_lookup && info_ptr->bit_depth == 8) + { + info_ptr->color_type = PNG_COLOR_TYPE_PALETTE; + } + } +#endif + +#if defined(PNG_READ_PACK_SUPPORTED) + if ((png_ptr->transformations & PNG_PACK) && (info_ptr->bit_depth < 8)) + info_ptr->bit_depth = 8; +#endif + + if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + info_ptr->channels = 1; + else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR) + info_ptr->channels = 3; + else + info_ptr->channels = 1; + +#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED) + if (png_ptr->flags & PNG_FLAG_STRIP_ALPHA) + info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA; +#endif + + if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA) + info_ptr->channels++; + +#if defined(PNG_READ_FILLER_SUPPORTED) + /* STRIP_ALPHA and FILLER allowed: MASK_ALPHA bit stripped above */ + if ((png_ptr->transformations & PNG_FILLER) && + ((info_ptr->color_type == PNG_COLOR_TYPE_RGB) || + (info_ptr->color_type == PNG_COLOR_TYPE_GRAY))) + { + info_ptr->channels++; + /* if adding a true alpha channel not just filler */ +#if !defined(PNG_1_0_X) + if (png_ptr->transformations & PNG_ADD_ALPHA) + info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; +#endif + } +#endif + +#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \ +defined(PNG_READ_USER_TRANSFORM_SUPPORTED) + if(png_ptr->transformations & PNG_USER_TRANSFORM) + { + if(info_ptr->bit_depth < png_ptr->user_transform_depth) + info_ptr->bit_depth = png_ptr->user_transform_depth; + if(info_ptr->channels < png_ptr->user_transform_channels) + info_ptr->channels = png_ptr->user_transform_channels; + } +#endif + + info_ptr->pixel_depth = (png_byte)(info_ptr->channels * + info_ptr->bit_depth); + + info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth,info_ptr->width); + +#if !defined(PNG_READ_EXPAND_SUPPORTED) + if(png_ptr) + return; +#endif +} + +/* Transform the row. The order of transformations is significant, + * and is very touchy. If you add a transformation, take care to + * decide how it fits in with the other transformations here. + */ +void /* PRIVATE */ +png_do_read_transformations(png_structp png_ptr) +{ + png_debug(1, "in png_do_read_transformations\n"); +#if !defined(PNG_USELESS_TESTS_SUPPORTED) + if (png_ptr->row_buf == NULL) + { +#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE) + char msg[50]; + + sprintf(msg, "NULL row buffer for row %ld, pass %d", png_ptr->row_number, + png_ptr->pass); + png_error(png_ptr, msg); +#else + png_error(png_ptr, "NULL row buffer"); +#endif + } +#endif + +#if defined(PNG_READ_EXPAND_SUPPORTED) + if (png_ptr->transformations & PNG_EXPAND) + { + if (png_ptr->row_info.color_type == PNG_COLOR_TYPE_PALETTE) + { + png_do_expand_palette(&(png_ptr->row_info), png_ptr->row_buf + 1, + png_ptr->palette, png_ptr->trans, png_ptr->num_trans); + } + else + { + if (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND_tRNS)) + png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1, + &(png_ptr->trans_values)); + else + png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1, + NULL); + } + } +#endif + +#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED) + if (png_ptr->flags & PNG_FLAG_STRIP_ALPHA) + png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1, + PNG_FLAG_FILLER_AFTER | (png_ptr->flags & PNG_FLAG_STRIP_ALPHA)); +#endif + +#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) + if (png_ptr->transformations & PNG_RGB_TO_GRAY) + { + int rgb_error = + png_do_rgb_to_gray(png_ptr, &(png_ptr->row_info), png_ptr->row_buf + 1); + if(rgb_error) + { + png_ptr->rgb_to_gray_status=1; + if(png_ptr->transformations == PNG_RGB_TO_GRAY_WARN) + png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel"); + if(png_ptr->transformations == PNG_RGB_TO_GRAY_ERR) + png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel"); + } + } +#endif + +/* +From Andreas Dilger e-mail to png-implement, 26 March 1998: + + In most cases, the "simple transparency" should be done prior to doing + gray-to-RGB, or you will have to test 3x as many bytes to check if a + pixel is transparent. You would also need to make sure that the + transparency information is upgraded to RGB. + + To summarize, the current flow is: + - Gray + simple transparency -> compare 1 or 2 gray bytes and composite + with background "in place" if transparent, + convert to RGB if necessary + - Gray + alpha -> composite with gray background and remove alpha bytes, + convert to RGB if necessary + + To support RGB backgrounds for gray images we need: + - Gray + simple transparency -> convert to RGB + simple transparency, compare + 3 or 6 bytes and composite with background + "in place" if transparent (3x compare/pixel + compared to doing composite with gray bkgrnd) + - Gray + alpha -> convert to RGB + alpha, composite with background and + remove alpha bytes (3x float operations/pixel + compared with composite on gray background) + + Greg's change will do this. The reason it wasn't done before is for + performance, as this increases the per-pixel operations. If we would check + in advance if the background was gray or RGB, and position the gray-to-RGB + transform appropriately, then it would save a lot of work/time. + */ + +#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) + /* if gray -> RGB, do so now only if background is non-gray; else do later + * for performance reasons */ + if ((png_ptr->transformations & PNG_GRAY_TO_RGB) && + !(png_ptr->mode & PNG_BACKGROUND_IS_GRAY)) + png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1); +#endif + +#if defined(PNG_READ_BACKGROUND_SUPPORTED) + if ((png_ptr->transformations & PNG_BACKGROUND) && + ((png_ptr->num_trans != 0 ) || + (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) + png_do_background(&(png_ptr->row_info), png_ptr->row_buf + 1, + &(png_ptr->trans_values), &(png_ptr->background) +#if defined(PNG_READ_GAMMA_SUPPORTED) + , &(png_ptr->background_1), + png_ptr->gamma_table, png_ptr->gamma_from_1, + png_ptr->gamma_to_1, png_ptr->gamma_16_table, + png_ptr->gamma_16_from_1, png_ptr->gamma_16_to_1, + png_ptr->gamma_shift +#endif +); +#endif + +#if defined(PNG_READ_GAMMA_SUPPORTED) + if ((png_ptr->transformations & PNG_GAMMA) && +#if defined(PNG_READ_BACKGROUND_SUPPORTED) + !((png_ptr->transformations & PNG_BACKGROUND) && + ((png_ptr->num_trans != 0) || + (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) && +#endif + (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)) + png_do_gamma(&(png_ptr->row_info), png_ptr->row_buf + 1, + png_ptr->gamma_table, png_ptr->gamma_16_table, + png_ptr->gamma_shift); +#endif + +#if defined(PNG_READ_16_TO_8_SUPPORTED) + if (png_ptr->transformations & PNG_16_TO_8) + png_do_chop(&(png_ptr->row_info), png_ptr->row_buf + 1); +#endif + +#if defined(PNG_READ_DITHER_SUPPORTED) + if (png_ptr->transformations & PNG_DITHER) + { + png_do_dither((png_row_infop)&(png_ptr->row_info), png_ptr->row_buf + 1, + png_ptr->palette_lookup, png_ptr->dither_index); + if(png_ptr->row_info.rowbytes == (png_uint_32)0) + png_error(png_ptr, "png_do_dither returned rowbytes=0"); + } +#endif + +#if defined(PNG_READ_INVERT_SUPPORTED) + if (png_ptr->transformations & PNG_INVERT_MONO) + png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1); +#endif + +#if defined(PNG_READ_SHIFT_SUPPORTED) + if (png_ptr->transformations & PNG_SHIFT) + png_do_unshift(&(png_ptr->row_info), png_ptr->row_buf + 1, + &(png_ptr->shift)); +#endif + +#if defined(PNG_READ_PACK_SUPPORTED) + if (png_ptr->transformations & PNG_PACK) + png_do_unpack(&(png_ptr->row_info), png_ptr->row_buf + 1); +#endif + +#if defined(PNG_READ_BGR_SUPPORTED) + if (png_ptr->transformations & PNG_BGR) + png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1); +#endif + +#if defined(PNG_READ_PACKSWAP_SUPPORTED) + if (png_ptr->transformations & PNG_PACKSWAP) + png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1); +#endif + +#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) + /* if gray -> RGB, do so now only if we did not do so above */ + if ((png_ptr->transformations & PNG_GRAY_TO_RGB) && + (png_ptr->mode & PNG_BACKGROUND_IS_GRAY)) + png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1); +#endif + +#if defined(PNG_READ_FILLER_SUPPORTED) + if (png_ptr->transformations & PNG_FILLER) + png_do_read_filler(&(png_ptr->row_info), png_ptr->row_buf + 1, + (png_uint_32)png_ptr->filler, png_ptr->flags); +#endif + +#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) + if (png_ptr->transformations & PNG_INVERT_ALPHA) + png_do_read_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1); +#endif + +#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) + if (png_ptr->transformations & PNG_SWAP_ALPHA) + png_do_read_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1); +#endif + +#if defined(PNG_READ_SWAP_SUPPORTED) + if (png_ptr->transformations & PNG_SWAP_BYTES) + png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1); +#endif + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) + if (png_ptr->transformations & PNG_USER_TRANSFORM) + { + if(png_ptr->read_user_transform_fn != NULL) + (*(png_ptr->read_user_transform_fn)) /* user read transform function */ + (png_ptr, /* png_ptr */ + &(png_ptr->row_info), /* row_info: */ + /* png_uint_32 width; width of row */ + /* png_uint_32 rowbytes; number of bytes in row */ + /* png_byte color_type; color type of pixels */ + /* png_byte bit_depth; bit depth of samples */ + /* png_byte channels; number of channels (1-4) */ + /* png_byte pixel_depth; bits per pixel (depth*channels) */ + png_ptr->row_buf + 1); /* start of pixel data for row */ +#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) + if(png_ptr->user_transform_depth) + png_ptr->row_info.bit_depth = png_ptr->user_transform_depth; + if(png_ptr->user_transform_channels) + png_ptr->row_info.channels = png_ptr->user_transform_channels; +#endif + png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.bit_depth * + png_ptr->row_info.channels); + png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth, + png_ptr->row_info.width); + } +#endif + +} + +#if defined(PNG_READ_PACK_SUPPORTED) +/* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel, + * without changing the actual values. Thus, if you had a row with + * a bit depth of 1, you would end up with bytes that only contained + * the numbers 0 or 1. If you would rather they contain 0 and 255, use + * png_do_shift() after this. + */ +void /* PRIVATE */ +png_do_unpack(png_row_infop row_info, png_bytep row) +{ + png_debug(1, "in png_do_unpack\n"); +#if defined(PNG_USELESS_TESTS_SUPPORTED) + if (row != NULL && row_info != NULL && row_info->bit_depth < 8) +#else + if (row_info->bit_depth < 8) +#endif + { + png_uint_32 i; + png_uint_32 row_width=row_info->width; + + switch (row_info->bit_depth) + { + case 1: + { + png_bytep sp = row + (png_size_t)((row_width - 1) >> 3); + png_bytep dp = row + (png_size_t)row_width - 1; + png_uint_32 shift = 7 - (int)((row_width + 7) & 0x07); + for (i = 0; i < row_width; i++) + { + *dp = (png_byte)((*sp >> shift) & 0x01); + if (shift == 7) + { + shift = 0; + sp--; + } + else + shift++; + + dp--; + } + break; + } + case 2: + { + + png_bytep sp = row + (png_size_t)((row_width - 1) >> 2); + png_bytep dp = row + (png_size_t)row_width - 1; + png_uint_32 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1); + for (i = 0; i < row_width; i++) + { + *dp = (png_byte)((*sp >> shift) & 0x03); + if (shift == 6) + { + shift = 0; + sp--; + } + else + shift += 2; + + dp--; + } + break; + } + case 4: + { + png_bytep sp = row + (png_size_t)((row_width - 1) >> 1); + png_bytep dp = row + (png_size_t)row_width - 1; + png_uint_32 shift = (int)((1 - ((row_width + 1) & 0x01)) << 2); + for (i = 0; i < row_width; i++) + { + *dp = (png_byte)((*sp >> shift) & 0x0f); + if (shift == 4) + { + shift = 0; + sp--; + } + else + shift = 4; + + dp--; + } + break; + } + } + row_info->bit_depth = 8; + row_info->pixel_depth = (png_byte)(8 * row_info->channels); + row_info->rowbytes = row_width * row_info->channels; + } +} +#endif + +#if defined(PNG_READ_SHIFT_SUPPORTED) +/* Reverse the effects of png_do_shift. This routine merely shifts the + * pixels back to their significant bits values. Thus, if you have + * a row of bit depth 8, but only 5 are significant, this will shift + * the values back to 0 through 31. + */ +void /* PRIVATE */ +png_do_unshift(png_row_infop row_info, png_bytep row, png_color_8p sig_bits) +{ + png_debug(1, "in png_do_unshift\n"); + if ( +#if defined(PNG_USELESS_TESTS_SUPPORTED) + row != NULL && row_info != NULL && sig_bits != NULL && +#endif + row_info->color_type != PNG_COLOR_TYPE_PALETTE) + { + int shift[4]; + int channels = 0; + int c; + png_uint_16 value = 0; + png_uint_32 row_width = row_info->width; + + if (row_info->color_type & PNG_COLOR_MASK_COLOR) + { + shift[channels++] = row_info->bit_depth - sig_bits->red; + shift[channels++] = row_info->bit_depth - sig_bits->green; + shift[channels++] = row_info->bit_depth - sig_bits->blue; + } + else + { + shift[channels++] = row_info->bit_depth - sig_bits->gray; + } + if (row_info->color_type & PNG_COLOR_MASK_ALPHA) + { + shift[channels++] = row_info->bit_depth - sig_bits->alpha; + } + + for (c = 0; c < channels; c++) + { + if (shift[c] <= 0) + shift[c] = 0; + else + value = 1; + } + + if (!value) + return; + + switch (row_info->bit_depth) + { + case 2: + { + png_bytep bp; + png_uint_32 i; + png_uint_32 istop = row_info->rowbytes; + + for (bp = row, i = 0; i < istop; i++) + { + *bp >>= 1; + *bp++ &= 0x55; + } + break; + } + case 4: + { + png_bytep bp = row; + png_uint_32 i; + png_uint_32 istop = row_info->rowbytes; + png_byte mask = (png_byte)((((int)0xf0 >> shift[0]) & (int)0xf0) | + (png_byte)((int)0xf >> shift[0])); + + for (i = 0; i < istop; i++) + { + *bp >>= shift[0]; + *bp++ &= mask; + } + break; + } + case 8: + { + png_bytep bp = row; + png_uint_32 i; + png_uint_32 istop = row_width * channels; + + for (i = 0; i < istop; i++) + { + *bp++ >>= shift[i%channels]; + } + break; + } + case 16: + { + png_bytep bp = row; + png_uint_32 i; + png_uint_32 istop = channels * row_width; + + for (i = 0; i < istop; i++) + { + value = (png_uint_16)((*bp << 8) + *(bp + 1)); + value >>= shift[i%channels]; + *bp++ = (png_byte)(value >> 8); + *bp++ = (png_byte)(value & 0xff); + } + break; + } + } + } +} +#endif + +#if defined(PNG_READ_16_TO_8_SUPPORTED) +/* chop rows of bit depth 16 down to 8 */ +void /* PRIVATE */ +png_do_chop(png_row_infop row_info, png_bytep row) +{ + png_debug(1, "in png_do_chop\n"); +#if defined(PNG_USELESS_TESTS_SUPPORTED) + if (row != NULL && row_info != NULL && row_info->bit_depth == 16) +#else + if (row_info->bit_depth == 16) +#endif + { + png_bytep sp = row; + png_bytep dp = row; + png_uint_32 i; + png_uint_32 istop = row_info->width * row_info->channels; + + for (i = 0; i<istop; i++, sp += 2, dp++) + { +#if defined(PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED) + /* This does a more accurate scaling of the 16-bit color + * value, rather than a simple low-byte truncation. + * + * What the ideal calculation should be: + * *dp = (((((png_uint_32)(*sp) << 8) | + * (png_uint_32)(*(sp + 1))) * 255 + 127) / (png_uint_32)65535L; + * + * GRR: no, I think this is what it really should be: + * *dp = (((((png_uint_32)(*sp) << 8) | + * (png_uint_32)(*(sp + 1))) + 128L) / (png_uint_32)257L; + * + * GRR: here's the exact calculation with shifts: + * temp = (((png_uint_32)(*sp) << 8) | (png_uint_32)(*(sp + 1))) + 128L; + * *dp = (temp - (temp >> 8)) >> 8; + * + * Approximate calculation with shift/add instead of multiply/divide: + * *dp = ((((png_uint_32)(*sp) << 8) | + * (png_uint_32)((int)(*(sp + 1)) - *sp)) + 128) >> 8; + * + * What we actually do to avoid extra shifting and conversion: + */ + + *dp = *sp + ((((int)(*(sp + 1)) - *sp) > 128) ? 1 : 0); +#else + /* Simply discard the low order byte */ + *dp = *sp; +#endif + } + row_info->bit_depth = 8; + row_info->pixel_depth = (png_byte)(8 * row_info->channels); + row_info->rowbytes = row_info->width * row_info->channels; + } +} +#endif + +#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) +void /* PRIVATE */ +png_do_read_swap_alpha(png_row_infop row_info, png_bytep row) +{ + png_debug(1, "in png_do_read_swap_alpha\n"); +#if defined(PNG_USELESS_TESTS_SUPPORTED) + if (row != NULL && row_info != NULL) +#endif + { + png_uint_32 row_width = row_info->width; + if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + { + /* This converts from RGBA to ARGB */ + if (row_info->bit_depth == 8) + { + png_bytep sp = row + row_info->rowbytes; + png_bytep dp = sp; + png_byte save; + png_uint_32 i; + + for (i = 0; i < row_width; i++) + { + save = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = save; + } + } + /* This converts from RRGGBBAA to AARRGGBB */ + else + { + png_bytep sp = row + row_info->rowbytes; + png_bytep dp = sp; + png_byte save[2]; + png_uint_32 i; + + for (i = 0; i < row_width; i++) + { + save[0] = *(--sp); + save[1] = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = save[0]; + *(--dp) = save[1]; + } + } + } + else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + { + /* This converts from GA to AG */ + if (row_info->bit_depth == 8) + { + png_bytep sp = row + row_info->rowbytes; + png_bytep dp = sp; + png_byte save; + png_uint_32 i; + + for (i = 0; i < row_width; i++) + { + save = *(--sp); + *(--dp) = *(--sp); + *(--dp) = save; + } + } + /* This converts from GGAA to AAGG */ + else + { + png_bytep sp = row + row_info->rowbytes; + png_bytep dp = sp; + png_byte save[2]; + png_uint_32 i; + + for (i = 0; i < row_width; i++) + { + save[0] = *(--sp); + save[1] = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = save[0]; + *(--dp) = save[1]; + } + } + } + } +} +#endif + +#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) +void /* PRIVATE */ +png_do_read_invert_alpha(png_row_infop row_info, png_bytep row) +{ + png_debug(1, "in png_do_read_invert_alpha\n"); +#if defined(PNG_USELESS_TESTS_SUPPORTED) + if (row != NULL && row_info != NULL) +#endif + { + png_uint_32 row_width = row_info->width; + if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + { + /* This inverts the alpha channel in RGBA */ + if (row_info->bit_depth == 8) + { + png_bytep sp = row + row_info->rowbytes; + png_bytep dp = sp; + png_uint_32 i; + + for (i = 0; i < row_width; i++) + { + *(--dp) = (png_byte)(255 - *(--sp)); + +/* This does nothing: + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + We can replace it with: +*/ + sp-=3; + dp=sp; + } + } + /* This inverts the alpha channel in RRGGBBAA */ + else + { + png_bytep sp = row + row_info->rowbytes; + png_bytep dp = sp; + png_uint_32 i; + + for (i = 0; i < row_width; i++) + { + *(--dp) = (png_byte)(255 - *(--sp)); + *(--dp) = (png_byte)(255 - *(--sp)); + +/* This does nothing: + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + We can replace it with: +*/ + sp-=6; + dp=sp; + } + } + } + else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + { + /* This inverts the alpha channel in GA */ + if (row_info->bit_depth == 8) + { + png_bytep sp = row + row_info->rowbytes; + png_bytep dp = sp; + png_uint_32 i; + + for (i = 0; i < row_width; i++) + { + *(--dp) = (png_byte)(255 - *(--sp)); + *(--dp) = *(--sp); + } + } + /* This inverts the alpha channel in GGAA */ + else + { + png_bytep sp = row + row_info->rowbytes; + png_bytep dp = sp; + png_uint_32 i; + + for (i = 0; i < row_width; i++) + { + *(--dp) = (png_byte)(255 - *(--sp)); + *(--dp) = (png_byte)(255 - *(--sp)); +/* + *(--dp) = *(--sp); + *(--dp) = *(--sp); +*/ + sp-=2; + dp=sp; + } + } + } + } +} +#endif + +#if defined(PNG_READ_FILLER_SUPPORTED) +/* Add filler channel if we have RGB color */ +void /* PRIVATE */ +png_do_read_filler(png_row_infop row_info, png_bytep row, + png_uint_32 filler, png_uint_32 flags) +{ + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + png_byte hi_filler = (png_byte)((filler>>8) & 0xff); + png_byte lo_filler = (png_byte)(filler & 0xff); + + png_debug(1, "in png_do_read_filler\n"); + if ( +#if defined(PNG_USELESS_TESTS_SUPPORTED) + row != NULL && row_info != NULL && +#endif + row_info->color_type == PNG_COLOR_TYPE_GRAY) + { + if(row_info->bit_depth == 8) + { + /* This changes the data from G to GX */ + if (flags & PNG_FLAG_FILLER_AFTER) + { + png_bytep sp = row + (png_size_t)row_width; + png_bytep dp = sp + (png_size_t)row_width; + for (i = 1; i < row_width; i++) + { + *(--dp) = lo_filler; + *(--dp) = *(--sp); + } + *(--dp) = lo_filler; + row_info->channels = 2; + row_info->pixel_depth = 16; + row_info->rowbytes = row_width * 2; + } + /* This changes the data from G to XG */ + else + { + png_bytep sp = row + (png_size_t)row_width; + png_bytep dp = sp + (png_size_t)row_width; + for (i = 0; i < row_width; i++) + { + *(--dp) = *(--sp); + *(--dp) = lo_filler; + } + row_info->channels = 2; + row_info->pixel_depth = 16; + row_info->rowbytes = row_width * 2; + } + } + else if(row_info->bit_depth == 16) + { + /* This changes the data from GG to GGXX */ + if (flags & PNG_FLAG_FILLER_AFTER) + { + png_bytep sp = row + (png_size_t)row_width * 2; + png_bytep dp = sp + (png_size_t)row_width * 2; + for (i = 1; i < row_width; i++) + { + *(--dp) = hi_filler; + *(--dp) = lo_filler; + *(--dp) = *(--sp); + *(--dp) = *(--sp); + } + *(--dp) = hi_filler; + *(--dp) = lo_filler; + row_info->channels = 2; + row_info->pixel_depth = 32; + row_info->rowbytes = row_width * 4; + } + /* This changes the data from GG to XXGG */ + else + { + png_bytep sp = row + (png_size_t)row_width * 2; + png_bytep dp = sp + (png_size_t)row_width * 2; + for (i = 0; i < row_width; i++) + { + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = hi_filler; + *(--dp) = lo_filler; + } + row_info->channels = 2; + row_info->pixel_depth = 32; + row_info->rowbytes = row_width * 4; + } + } + } /* COLOR_TYPE == GRAY */ + else if (row_info->color_type == PNG_COLOR_TYPE_RGB) + { + if(row_info->bit_depth == 8) + { + /* This changes the data from RGB to RGBX */ + if (flags & PNG_FLAG_FILLER_AFTER) + { + png_bytep sp = row + (png_size_t)row_width * 3; + png_bytep dp = sp + (png_size_t)row_width; + for (i = 1; i < row_width; i++) + { + *(--dp) = lo_filler; + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + } + *(--dp) = lo_filler; + row_info->channels = 4; + row_info->pixel_depth = 32; + row_info->rowbytes = row_width * 4; + } + /* This changes the data from RGB to XRGB */ + else + { + png_bytep sp = row + (png_size_t)row_width * 3; + png_bytep dp = sp + (png_size_t)row_width; + for (i = 0; i < row_width; i++) + { + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = lo_filler; + } + row_info->channels = 4; + row_info->pixel_depth = 32; + row_info->rowbytes = row_width * 4; + } + } + else if(row_info->bit_depth == 16) + { + /* This changes the data from RRGGBB to RRGGBBXX */ + if (flags & PNG_FLAG_FILLER_AFTER) + { + png_bytep sp = row + (png_size_t)row_width * 6; + png_bytep dp = sp + (png_size_t)row_width * 2; + for (i = 1; i < row_width; i++) + { + *(--dp) = hi_filler; + *(--dp) = lo_filler; + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + } + *(--dp) = hi_filler; + *(--dp) = lo_filler; + row_info->channels = 4; + row_info->pixel_depth = 64; + row_info->rowbytes = row_width * 8; + } + /* This changes the data from RRGGBB to XXRRGGBB */ + else + { + png_bytep sp = row + (png_size_t)row_width * 6; + png_bytep dp = sp + (png_size_t)row_width * 2; + for (i = 0; i < row_width; i++) + { + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = hi_filler; + *(--dp) = lo_filler; + } + row_info->channels = 4; + row_info->pixel_depth = 64; + row_info->rowbytes = row_width * 8; + } + } + } /* COLOR_TYPE == RGB */ +} +#endif + +#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) +/* expand grayscale files to RGB, with or without alpha */ +void /* PRIVATE */ +png_do_gray_to_rgb(png_row_infop row_info, png_bytep row) +{ + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + png_debug(1, "in png_do_gray_to_rgb\n"); + if (row_info->bit_depth >= 8 && +#if defined(PNG_USELESS_TESTS_SUPPORTED) + row != NULL && row_info != NULL && +#endif + !(row_info->color_type & PNG_COLOR_MASK_COLOR)) + { + if (row_info->color_type == PNG_COLOR_TYPE_GRAY) + { + if (row_info->bit_depth == 8) + { + png_bytep sp = row + (png_size_t)row_width - 1; + png_bytep dp = sp + (png_size_t)row_width * 2; + for (i = 0; i < row_width; i++) + { + *(dp--) = *sp; + *(dp--) = *sp; + *(dp--) = *(sp--); + } + } + else + { + png_bytep sp = row + (png_size_t)row_width * 2 - 1; + png_bytep dp = sp + (png_size_t)row_width * 4; + for (i = 0; i < row_width; i++) + { + *(dp--) = *sp; + *(dp--) = *(sp - 1); + *(dp--) = *sp; + *(dp--) = *(sp - 1); + *(dp--) = *(sp--); + *(dp--) = *(sp--); + } + } + } + else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + { + if (row_info->bit_depth == 8) + { + png_bytep sp = row + (png_size_t)row_width * 2 - 1; + png_bytep dp = sp + (png_size_t)row_width * 2; + for (i = 0; i < row_width; i++) + { + *(dp--) = *(sp--); + *(dp--) = *sp; + *(dp--) = *sp; + *(dp--) = *(sp--); + } + } + else + { + png_bytep sp = row + (png_size_t)row_width * 4 - 1; + png_bytep dp = sp + (png_size_t)row_width * 4; + for (i = 0; i < row_width; i++) + { + *(dp--) = *(sp--); + *(dp--) = *(sp--); + *(dp--) = *sp; + *(dp--) = *(sp - 1); + *(dp--) = *sp; + *(dp--) = *(sp - 1); + *(dp--) = *(sp--); + *(dp--) = *(sp--); + } + } + } + row_info->channels += (png_byte)2; + row_info->color_type |= PNG_COLOR_MASK_COLOR; + row_info->pixel_depth = (png_byte)(row_info->channels * + row_info->bit_depth); + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width); + } +} +#endif + +#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) +/* reduce RGB files to grayscale, with or without alpha + * using the equation given in Poynton's ColorFAQ at + * <http://www.inforamp.net/~poynton/> + * Copyright (c) 1998-01-04 Charles Poynton poynton at inforamp.net + * + * Y = 0.212671 * R + 0.715160 * G + 0.072169 * B + * + * We approximate this with + * + * Y = 0.21268 * R + 0.7151 * G + 0.07217 * B + * + * which can be expressed with integers as + * + * Y = (6969 * R + 23434 * G + 2365 * B)/32768 + * + * The calculation is to be done in a linear colorspace. + * + * Other integer coefficents can be used via png_set_rgb_to_gray(). + */ +int /* PRIVATE */ +png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row) + +{ + png_uint_32 i; + + png_uint_32 row_width = row_info->width; + int rgb_error = 0; + + png_debug(1, "in png_do_rgb_to_gray\n"); + if ( +#if defined(PNG_USELESS_TESTS_SUPPORTED) + row != NULL && row_info != NULL && +#endif + (row_info->color_type & PNG_COLOR_MASK_COLOR)) + { + png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff; + png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff; + png_uint_32 bc = png_ptr->rgb_to_gray_blue_coeff; + + if (row_info->color_type == PNG_COLOR_TYPE_RGB) + { + if (row_info->bit_depth == 8) + { +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) + if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL) + { + png_bytep sp = row; + png_bytep dp = row; + + for (i = 0; i < row_width; i++) + { + png_byte red = png_ptr->gamma_to_1[*(sp++)]; + png_byte green = png_ptr->gamma_to_1[*(sp++)]; + png_byte blue = png_ptr->gamma_to_1[*(sp++)]; + if(red != green || red != blue) + { + rgb_error |= 1; + *(dp++) = png_ptr->gamma_from_1[ + (rc*red+gc*green+bc*blue)>>15]; + } + else + *(dp++) = *(sp-1); + } + } + else +#endif + { + png_bytep sp = row; + png_bytep dp = row; + for (i = 0; i < row_width; i++) + { + png_byte red = *(sp++); + png_byte green = *(sp++); + png_byte blue = *(sp++); + if(red != green || red != blue) + { + rgb_error |= 1; + *(dp++) = (png_byte)((rc*red+gc*green+bc*blue)>>15); + } + else + *(dp++) = *(sp-1); + } + } + } + + else /* RGB bit_depth == 16 */ + { +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) + if (png_ptr->gamma_16_to_1 != NULL && + png_ptr->gamma_16_from_1 != NULL) + { + png_bytep sp = row; + png_bytep dp = row; + for (i = 0; i < row_width; i++) + { + png_uint_16 red, green, blue, w; + + red = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2; + green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2; + blue = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2; + + if(red == green && red == blue) + w = red; + else + { + png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff) >> + png_ptr->gamma_shift][red>>8]; + png_uint_16 green_1 = png_ptr->gamma_16_to_1[(green&0xff) >> + png_ptr->gamma_shift][green>>8]; + png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff) >> + png_ptr->gamma_shift][blue>>8]; + png_uint_16 gray16 = (png_uint_16)((rc*red_1 + gc*green_1 + + bc*blue_1)>>15); + w = png_ptr->gamma_16_from_1[(gray16&0xff) >> + png_ptr->gamma_shift][gray16 >> 8]; + rgb_error |= 1; + } + + *(dp++) = (png_byte)((w>>8) & 0xff); + *(dp++) = (png_byte)(w & 0xff); + } + } + else +#endif + { + png_bytep sp = row; + png_bytep dp = row; + for (i = 0; i < row_width; i++) + { + png_uint_16 red, green, blue, gray16; + + red = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2; + green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2; + blue = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2; + + if(red != green || red != blue) + rgb_error |= 1; + gray16 = (png_uint_16)((rc*red + gc*green + bc*blue)>>15); + *(dp++) = (png_byte)((gray16>>8) & 0xff); + *(dp++) = (png_byte)(gray16 & 0xff); + } + } + } + } + if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + { + if (row_info->bit_depth == 8) + { +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) + if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL) + { + png_bytep sp = row; + png_bytep dp = row; + for (i = 0; i < row_width; i++) + { + png_byte red = png_ptr->gamma_to_1[*(sp++)]; + png_byte green = png_ptr->gamma_to_1[*(sp++)]; + png_byte blue = png_ptr->gamma_to_1[*(sp++)]; + if(red != green || red != blue) + rgb_error |= 1; + *(dp++) = png_ptr->gamma_from_1 + [(rc*red + gc*green + bc*blue)>>15]; + *(dp++) = *(sp++); /* alpha */ + } + } + else +#endif + { + png_bytep sp = row; + png_bytep dp = row; + for (i = 0; i < row_width; i++) + { + png_byte red = *(sp++); + png_byte green = *(sp++); + png_byte blue = *(sp++); + if(red != green || red != blue) + rgb_error |= 1; + *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15); + *(dp++) = *(sp++); /* alpha */ + } + } + } + else /* RGBA bit_depth == 16 */ + { +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) + if (png_ptr->gamma_16_to_1 != NULL && + png_ptr->gamma_16_from_1 != NULL) + { + png_bytep sp = row; + png_bytep dp = row; + for (i = 0; i < row_width; i++) + { + png_uint_16 red, green, blue, w; + + red = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2; + green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2; + blue = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2; + + if(red == green && red == blue) + w = red; + else + { + png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff) >> + png_ptr->gamma_shift][red>>8]; + png_uint_16 green_1 = png_ptr->gamma_16_to_1[(green&0xff) >> + png_ptr->gamma_shift][green>>8]; + png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff) >> + png_ptr->gamma_shift][blue>>8]; + png_uint_16 gray16 = (png_uint_16)((rc * red_1 + + gc * green_1 + bc * blue_1)>>15); + w = png_ptr->gamma_16_from_1[(gray16&0xff) >> + png_ptr->gamma_shift][gray16 >> 8]; + rgb_error |= 1; + } + + *(dp++) = (png_byte)((w>>8) & 0xff); + *(dp++) = (png_byte)(w & 0xff); + *(dp++) = *(sp++); /* alpha */ + *(dp++) = *(sp++); + } + } + else +#endif + { + png_bytep sp = row; + png_bytep dp = row; + for (i = 0; i < row_width; i++) + { + png_uint_16 red, green, blue, gray16; + red = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2; + green = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2; + blue = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2; + if(red != green || red != blue) + rgb_error |= 1; + gray16 = (png_uint_16)((rc*red + gc*green + bc*blue)>>15); + *(dp++) = (png_byte)((gray16>>8) & 0xff); + *(dp++) = (png_byte)(gray16 & 0xff); + *(dp++) = *(sp++); /* alpha */ + *(dp++) = *(sp++); + } + } + } + } + row_info->channels -= (png_byte)2; + row_info->color_type &= ~PNG_COLOR_MASK_COLOR; + row_info->pixel_depth = (png_byte)(row_info->channels * + row_info->bit_depth); + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width); + } + return rgb_error; +} +#endif + +/* Build a grayscale palette. Palette is assumed to be 1 << bit_depth + * large of png_color. This lets grayscale images be treated as + * paletted. Most useful for gamma correction and simplification + * of code. + */ +void PNGAPI +png_build_grayscale_palette(int bit_depth, png_colorp palette) +{ + int num_palette; + int color_inc; + int i; + int v; + + png_debug(1, "in png_do_build_grayscale_palette\n"); + if (palette == NULL) + return; + + switch (bit_depth) + { + case 1: + num_palette = 2; + color_inc = 0xff; + break; + case 2: + num_palette = 4; + color_inc = 0x55; + break; + case 4: + num_palette = 16; + color_inc = 0x11; + break; + case 8: + num_palette = 256; + color_inc = 1; + break; + default: + num_palette = 0; + color_inc = 0; + break; + } + + for (i = 0, v = 0; i < num_palette; i++, v += color_inc) + { + palette[i].red = (png_byte)v; + palette[i].green = (png_byte)v; + palette[i].blue = (png_byte)v; + } +} + +/* This function is currently unused. Do we really need it? */ +#if defined(PNG_READ_DITHER_SUPPORTED) && defined(PNG_CORRECT_PALETTE_SUPPORTED) +void /* PRIVATE */ +png_correct_palette(png_structp png_ptr, png_colorp palette, + int num_palette) +{ + png_debug(1, "in png_correct_palette\n"); +#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \ + defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED) + if (png_ptr->transformations & (PNG_GAMMA | PNG_BACKGROUND)) + { + png_color back, back_1; + + if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE) + { + back.red = png_ptr->gamma_table[png_ptr->background.red]; + back.green = png_ptr->gamma_table[png_ptr->background.green]; + back.blue = png_ptr->gamma_table[png_ptr->background.blue]; + + back_1.red = png_ptr->gamma_to_1[png_ptr->background.red]; + back_1.green = png_ptr->gamma_to_1[png_ptr->background.green]; + back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue]; + } + else + { + double g; + + g = 1.0 / (png_ptr->background_gamma * png_ptr->screen_gamma); + + if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_SCREEN || + fabs(g - 1.0) < PNG_GAMMA_THRESHOLD) + { + back.red = png_ptr->background.red; + back.green = png_ptr->background.green; + back.blue = png_ptr->background.blue; + } + else + { + back.red = + (png_byte)(pow((double)png_ptr->background.red/255, g) * + 255.0 + 0.5); + back.green = + (png_byte)(pow((double)png_ptr->background.green/255, g) * + 255.0 + 0.5); + back.blue = + (png_byte)(pow((double)png_ptr->background.blue/255, g) * + 255.0 + 0.5); + } + + g = 1.0 / png_ptr->background_gamma; + + back_1.red = + (png_byte)(pow((double)png_ptr->background.red/255, g) * + 255.0 + 0.5); + back_1.green = + (png_byte)(pow((double)png_ptr->background.green/255, g) * + 255.0 + 0.5); + back_1.blue = + (png_byte)(pow((double)png_ptr->background.blue/255, g) * + 255.0 + 0.5); + } + + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { + png_uint_32 i; + + for (i = 0; i < (png_uint_32)num_palette; i++) + { + if (i < png_ptr->num_trans && png_ptr->trans[i] == 0) + { + palette[i] = back; + } + else if (i < png_ptr->num_trans && png_ptr->trans[i] != 0xff) + { + png_byte v, w; + + v = png_ptr->gamma_to_1[png_ptr->palette[i].red]; + png_composite(w, v, png_ptr->trans[i], back_1.red); + palette[i].red = png_ptr->gamma_from_1[w]; + + v = png_ptr->gamma_to_1[png_ptr->palette[i].green]; + png_composite(w, v, png_ptr->trans[i], back_1.green); + palette[i].green = png_ptr->gamma_from_1[w]; + + v = png_ptr->gamma_to_1[png_ptr->palette[i].blue]; + png_composite(w, v, png_ptr->trans[i], back_1.blue); + palette[i].blue = png_ptr->gamma_from_1[w]; + } + else + { + palette[i].red = png_ptr->gamma_table[palette[i].red]; + palette[i].green = png_ptr->gamma_table[palette[i].green]; + palette[i].blue = png_ptr->gamma_table[palette[i].blue]; + } + } + } + else + { + int i; + + for (i = 0; i < num_palette; i++) + { + if (palette[i].red == (png_byte)png_ptr->trans_values.gray) + { + palette[i] = back; + } + else + { + palette[i].red = png_ptr->gamma_table[palette[i].red]; + palette[i].green = png_ptr->gamma_table[palette[i].green]; + palette[i].blue = png_ptr->gamma_table[palette[i].blue]; + } + } + } + } + else +#endif +#if defined(PNG_READ_GAMMA_SUPPORTED) + if (png_ptr->transformations & PNG_GAMMA) + { + int i; + + for (i = 0; i < num_palette; i++) + { + palette[i].red = png_ptr->gamma_table[palette[i].red]; + palette[i].green = png_ptr->gamma_table[palette[i].green]; + palette[i].blue = png_ptr->gamma_table[palette[i].blue]; + } + } +#if defined(PNG_READ_BACKGROUND_SUPPORTED) + else +#endif +#endif +#if defined(PNG_READ_BACKGROUND_SUPPORTED) + if (png_ptr->transformations & PNG_BACKGROUND) + { + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { + png_color back; + + back.red = (png_byte)png_ptr->background.red; + back.green = (png_byte)png_ptr->background.green; + back.blue = (png_byte)png_ptr->background.blue; + + for (i = 0; i < (int)png_ptr->num_trans; i++) + { + if (png_ptr->trans[i] == 0) + { + palette[i].red = back.red; + palette[i].green = back.green; + palette[i].blue = back.blue; + } + else if (png_ptr->trans[i] != 0xff) + { + png_composite(palette[i].red, png_ptr->palette[i].red, + png_ptr->trans[i], back.red); + png_composite(palette[i].green, png_ptr->palette[i].green, + png_ptr->trans[i], back.green); + png_composite(palette[i].blue, png_ptr->palette[i].blue, + png_ptr->trans[i], back.blue); + } + } + } + else /* assume grayscale palette (what else could it be?) */ + { + int i; + + for (i = 0; i < num_palette; i++) + { + if (i == (png_byte)png_ptr->trans_values.gray) + { + palette[i].red = (png_byte)png_ptr->background.red; + palette[i].green = (png_byte)png_ptr->background.green; + palette[i].blue = (png_byte)png_ptr->background.blue; + } + } + } + } +#endif +} +#endif + +#if defined(PNG_READ_BACKGROUND_SUPPORTED) +/* Replace any alpha or transparency with the supplied background color. + * "background" is already in the screen gamma, while "background_1" is + * at a gamma of 1.0. Paletted files have already been taken care of. + */ +void /* PRIVATE */ +png_do_background(png_row_infop row_info, png_bytep row, + png_color_16p trans_values, png_color_16p background +#if defined(PNG_READ_GAMMA_SUPPORTED) + , png_color_16p background_1, + png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1, + png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1, + png_uint_16pp gamma_16_to_1, int gamma_shift +#endif + ) +{ + png_bytep sp, dp; + png_uint_32 i; + png_uint_32 row_width=row_info->width; + int shift; + + png_debug(1, "in png_do_background\n"); + if (background != NULL && +#if defined(PNG_USELESS_TESTS_SUPPORTED) + row != NULL && row_info != NULL && +#endif + (!(row_info->color_type & PNG_COLOR_MASK_ALPHA) || + (row_info->color_type != PNG_COLOR_TYPE_PALETTE && trans_values))) + { + switch (row_info->color_type) + { + case PNG_COLOR_TYPE_GRAY: + { + switch (row_info->bit_depth) + { + case 1: + { + sp = row; + shift = 7; + for (i = 0; i < row_width; i++) + { + if ((png_uint_16)((*sp >> shift) & 0x01) + == trans_values->gray) + { + *sp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff); + *sp |= (png_byte)(background->gray << shift); + } + if (!shift) + { + shift = 7; + sp++; + } + else + shift--; + } + break; + } + case 2: + { +#if defined(PNG_READ_GAMMA_SUPPORTED) + if (gamma_table != NULL) + { + sp = row; + shift = 6; + for (i = 0; i < row_width; i++) + { + if ((png_uint_16)((*sp >> shift) & 0x03) + == trans_values->gray) + { + *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); + *sp |= (png_byte)(background->gray << shift); + } + else + { + png_byte p = (png_byte)((*sp >> shift) & 0x03); + png_byte g = (png_byte)((gamma_table [p | (p << 2) | + (p << 4) | (p << 6)] >> 6) & 0x03); + *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); + *sp |= (png_byte)(g << shift); + } + if (!shift) + { + shift = 6; + sp++; + } + else + shift -= 2; + } + } + else +#endif + { + sp = row; + shift = 6; + for (i = 0; i < row_width; i++) + { + if ((png_uint_16)((*sp >> shift) & 0x03) + == trans_values->gray) + { + *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); + *sp |= (png_byte)(background->gray << shift); + } + if (!shift) + { + shift = 6; + sp++; + } + else + shift -= 2; + } + } + break; + } + case 4: + { +#if defined(PNG_READ_GAMMA_SUPPORTED) + if (gamma_table != NULL) + { + sp = row; + shift = 4; + for (i = 0; i < row_width; i++) + { + if ((png_uint_16)((*sp >> shift) & 0x0f) + == trans_values->gray) + { + *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); + *sp |= (png_byte)(background->gray << shift); + } + else + { + png_byte p = (png_byte)((*sp >> shift) & 0x0f); + png_byte g = (png_byte)((gamma_table[p | + (p << 4)] >> 4) & 0x0f); + *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); + *sp |= (png_byte)(g << shift); + } + if (!shift) + { + shift = 4; + sp++; + } + else + shift -= 4; + } + } + else +#endif + { + sp = row; + shift = 4; + for (i = 0; i < row_width; i++) + { + if ((png_uint_16)((*sp >> shift) & 0x0f) + == trans_values->gray) + { + *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); + *sp |= (png_byte)(background->gray << shift); + } + if (!shift) + { + shift = 4; + sp++; + } + else + shift -= 4; + } + } + break; + } + case 8: + { +#if defined(PNG_READ_GAMMA_SUPPORTED) + if (gamma_table != NULL) + { + sp = row; + for (i = 0; i < row_width; i++, sp++) + { + if (*sp == trans_values->gray) + { + *sp = (png_byte)background->gray; + } + else + { + *sp = gamma_table[*sp]; + } + } + } + else +#endif + { + sp = row; + for (i = 0; i < row_width; i++, sp++) + { + if (*sp == trans_values->gray) + { + *sp = (png_byte)background->gray; + } + } + } + break; + } + case 16: + { +#if defined(PNG_READ_GAMMA_SUPPORTED) + if (gamma_16 != NULL) + { + sp = row; + for (i = 0; i < row_width; i++, sp += 2) + { + png_uint_16 v; + + v = (png_uint_16)(((*sp) << 8) + *(sp + 1)); + if (v == trans_values->gray) + { + /* background is already in screen gamma */ + *sp = (png_byte)((background->gray >> 8) & 0xff); + *(sp + 1) = (png_byte)(background->gray & 0xff); + } + else + { + v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + } + } + } + else +#endif + { + sp = row; + for (i = 0; i < row_width; i++, sp += 2) + { + png_uint_16 v; + + v = (png_uint_16)(((*sp) << 8) + *(sp + 1)); + if (v == trans_values->gray) + { + *sp = (png_byte)((background->gray >> 8) & 0xff); + *(sp + 1) = (png_byte)(background->gray & 0xff); + } + } + } + break; + } + } + break; + } + case PNG_COLOR_TYPE_RGB: + { + if (row_info->bit_depth == 8) + { +#if defined(PNG_READ_GAMMA_SUPPORTED) + if (gamma_table != NULL) + { + sp = row; + for (i = 0; i < row_width; i++, sp += 3) + { + if (*sp == trans_values->red && + *(sp + 1) == trans_values->green && + *(sp + 2) == trans_values->blue) + { + *sp = (png_byte)background->red; + *(sp + 1) = (png_byte)background->green; + *(sp + 2) = (png_byte)background->blue; + } + else + { + *sp = gamma_table[*sp]; + *(sp + 1) = gamma_table[*(sp + 1)]; + *(sp + 2) = gamma_table[*(sp + 2)]; + } + } + } + else +#endif + { + sp = row; + for (i = 0; i < row_width; i++, sp += 3) + { + if (*sp == trans_values->red && + *(sp + 1) == trans_values->green && + *(sp + 2) == trans_values->blue) + { + *sp = (png_byte)background->red; + *(sp + 1) = (png_byte)background->green; + *(sp + 2) = (png_byte)background->blue; + } + } + } + } + else /* if (row_info->bit_depth == 16) */ + { +#if defined(PNG_READ_GAMMA_SUPPORTED) + if (gamma_16 != NULL) + { + sp = row; + for (i = 0; i < row_width; i++, sp += 6) + { + png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1)); + png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3)); + png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5)); + if (r == trans_values->red && g == trans_values->green && + b == trans_values->blue) + { + /* background is already in screen gamma */ + *sp = (png_byte)((background->red >> 8) & 0xff); + *(sp + 1) = (png_byte)(background->red & 0xff); + *(sp + 2) = (png_byte)((background->green >> 8) & 0xff); + *(sp + 3) = (png_byte)(background->green & 0xff); + *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff); + *(sp + 5) = (png_byte)(background->blue & 0xff); + } + else + { + png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)]; + *(sp + 2) = (png_byte)((v >> 8) & 0xff); + *(sp + 3) = (png_byte)(v & 0xff); + v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)]; + *(sp + 4) = (png_byte)((v >> 8) & 0xff); + *(sp + 5) = (png_byte)(v & 0xff); + } + } + } + else +#endif + { + sp = row; + for (i = 0; i < row_width; i++, sp += 6) + { + png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp+1)); + png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3)); + png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5)); + + if (r == trans_values->red && g == trans_values->green && + b == trans_values->blue) + { + *sp = (png_byte)((background->red >> 8) & 0xff); + *(sp + 1) = (png_byte)(background->red & 0xff); + *(sp + 2) = (png_byte)((background->green >> 8) & 0xff); + *(sp + 3) = (png_byte)(background->green & 0xff); + *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff); + *(sp + 5) = (png_byte)(background->blue & 0xff); + } + } + } + } + break; + } + case PNG_COLOR_TYPE_GRAY_ALPHA: + { + if (row_info->bit_depth == 8) + { +#if defined(PNG_READ_GAMMA_SUPPORTED) + if (gamma_to_1 != NULL && gamma_from_1 != NULL && + gamma_table != NULL) + { + sp = row; + dp = row; + for (i = 0; i < row_width; i++, sp += 2, dp++) + { + png_uint_16 a = *(sp + 1); + + if (a == 0xff) + { + *dp = gamma_table[*sp]; + } + else if (a == 0) + { + /* background is already in screen gamma */ + *dp = (png_byte)background->gray; + } + else + { + png_byte v, w; + + v = gamma_to_1[*sp]; + png_composite(w, v, a, background_1->gray); + *dp = gamma_from_1[w]; + } + } + } + else +#endif + { + sp = row; + dp = row; + for (i = 0; i < row_width; i++, sp += 2, dp++) + { + png_byte a = *(sp + 1); + + if (a == 0xff) + { + *dp = *sp; + } +#if defined(PNG_READ_GAMMA_SUPPORTED) + else if (a == 0) + { + *dp = (png_byte)background->gray; + } + else + { + png_composite(*dp, *sp, a, background_1->gray); + } +#else + *dp = (png_byte)background->gray; +#endif + } + } + } + else /* if (png_ptr->bit_depth == 16) */ + { +#if defined(PNG_READ_GAMMA_SUPPORTED) + if (gamma_16 != NULL && gamma_16_from_1 != NULL && + gamma_16_to_1 != NULL) + { + sp = row; + dp = row; + for (i = 0; i < row_width; i++, sp += 4, dp += 2) + { + png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3)); + + if (a == (png_uint_16)0xffff) + { + png_uint_16 v; + + v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; + *dp = (png_byte)((v >> 8) & 0xff); + *(dp + 1) = (png_byte)(v & 0xff); + } +#if defined(PNG_READ_GAMMA_SUPPORTED) + else if (a == 0) +#else + else +#endif + { + /* background is already in screen gamma */ + *dp = (png_byte)((background->gray >> 8) & 0xff); + *(dp + 1) = (png_byte)(background->gray & 0xff); + } +#if defined(PNG_READ_GAMMA_SUPPORTED) + else + { + png_uint_16 g, v, w; + + g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp]; + png_composite_16(v, g, a, background_1->gray); + w = gamma_16_from_1[(v&0xff) >> gamma_shift][v >> 8]; + *dp = (png_byte)((w >> 8) & 0xff); + *(dp + 1) = (png_byte)(w & 0xff); + } +#endif + } + } + else +#endif + { + sp = row; + dp = row; + for (i = 0; i < row_width; i++, sp += 4, dp += 2) + { + png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3)); + if (a == (png_uint_16)0xffff) + { + png_memcpy(dp, sp, 2); + } +#if defined(PNG_READ_GAMMA_SUPPORTED) + else if (a == 0) +#else + else +#endif + { + *dp = (png_byte)((background->gray >> 8) & 0xff); + *(dp + 1) = (png_byte)(background->gray & 0xff); + } +#if defined(PNG_READ_GAMMA_SUPPORTED) + else + { + png_uint_16 g, v; + + g = (png_uint_16)(((*sp) << 8) + *(sp + 1)); + png_composite_16(v, g, a, background_1->gray); + *dp = (png_byte)((v >> 8) & 0xff); + *(dp + 1) = (png_byte)(v & 0xff); + } +#endif + } + } + } + break; + } + case PNG_COLOR_TYPE_RGB_ALPHA: + { + if (row_info->bit_depth == 8) + { +#if defined(PNG_READ_GAMMA_SUPPORTED) + if (gamma_to_1 != NULL && gamma_from_1 != NULL && + gamma_table != NULL) + { + sp = row; + dp = row; + for (i = 0; i < row_width; i++, sp += 4, dp += 3) + { + png_byte a = *(sp + 3); + + if (a == 0xff) + { + *dp = gamma_table[*sp]; + *(dp + 1) = gamma_table[*(sp + 1)]; + *(dp + 2) = gamma_table[*(sp + 2)]; + } + else if (a == 0) + { + /* background is already in screen gamma */ + *dp = (png_byte)background->red; + *(dp + 1) = (png_byte)background->green; + *(dp + 2) = (png_byte)background->blue; + } + else + { + png_byte v, w; + + v = gamma_to_1[*sp]; + png_composite(w, v, a, background_1->red); + *dp = gamma_from_1[w]; + v = gamma_to_1[*(sp + 1)]; + png_composite(w, v, a, background_1->green); + *(dp + 1) = gamma_from_1[w]; + v = gamma_to_1[*(sp + 2)]; + png_composite(w, v, a, background_1->blue); + *(dp + 2) = gamma_from_1[w]; + } + } + } + else +#endif + { + sp = row; + dp = row; + for (i = 0; i < row_width; i++, sp += 4, dp += 3) + { + png_byte a = *(sp + 3); + + if (a == 0xff) + { + *dp = *sp; + *(dp + 1) = *(sp + 1); + *(dp + 2) = *(sp + 2); + } + else if (a == 0) + { + *dp = (png_byte)background->red; + *(dp + 1) = (png_byte)background->green; + *(dp + 2) = (png_byte)background->blue; + } + else + { + png_composite(*dp, *sp, a, background->red); + png_composite(*(dp + 1), *(sp + 1), a, + background->green); + png_composite(*(dp + 2), *(sp + 2), a, + background->blue); + } + } + } + } + else /* if (row_info->bit_depth == 16) */ + { +#if defined(PNG_READ_GAMMA_SUPPORTED) + if (gamma_16 != NULL && gamma_16_from_1 != NULL && + gamma_16_to_1 != NULL) + { + sp = row; + dp = row; + for (i = 0; i < row_width; i++, sp += 8, dp += 6) + { + png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6)) + << 8) + (png_uint_16)(*(sp + 7))); + if (a == (png_uint_16)0xffff) + { + png_uint_16 v; + + v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; + *dp = (png_byte)((v >> 8) & 0xff); + *(dp + 1) = (png_byte)(v & 0xff); + v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)]; + *(dp + 2) = (png_byte)((v >> 8) & 0xff); + *(dp + 3) = (png_byte)(v & 0xff); + v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)]; + *(dp + 4) = (png_byte)((v >> 8) & 0xff); + *(dp + 5) = (png_byte)(v & 0xff); + } + else if (a == 0) + { + /* background is already in screen gamma */ + *dp = (png_byte)((background->red >> 8) & 0xff); + *(dp + 1) = (png_byte)(background->red & 0xff); + *(dp + 2) = (png_byte)((background->green >> 8) & 0xff); + *(dp + 3) = (png_byte)(background->green & 0xff); + *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff); + *(dp + 5) = (png_byte)(background->blue & 0xff); + } + else + { + png_uint_16 v, w, x; + + v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp]; + png_composite_16(w, v, a, background_1->red); + x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8]; + *dp = (png_byte)((x >> 8) & 0xff); + *(dp + 1) = (png_byte)(x & 0xff); + v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)]; + png_composite_16(w, v, a, background_1->green); + x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8]; + *(dp + 2) = (png_byte)((x >> 8) & 0xff); + *(dp + 3) = (png_byte)(x & 0xff); + v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)]; + png_composite_16(w, v, a, background_1->blue); + x = gamma_16_from_1[(w & 0xff) >> gamma_shift][w >> 8]; + *(dp + 4) = (png_byte)((x >> 8) & 0xff); + *(dp + 5) = (png_byte)(x & 0xff); + } + } + } + else +#endif + { + sp = row; + dp = row; + for (i = 0; i < row_width; i++, sp += 8, dp += 6) + { + png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6)) + << 8) + (png_uint_16)(*(sp + 7))); + if (a == (png_uint_16)0xffff) + { + png_memcpy(dp, sp, 6); + } + else if (a == 0) + { + *dp = (png_byte)((background->red >> 8) & 0xff); + *(dp + 1) = (png_byte)(background->red & 0xff); + *(dp + 2) = (png_byte)((background->green >> 8) & 0xff); + *(dp + 3) = (png_byte)(background->green & 0xff); + *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff); + *(dp + 5) = (png_byte)(background->blue & 0xff); + } + else + { + png_uint_16 v; + + png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1)); + png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8) + + *(sp + 3)); + png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8) + + *(sp + 5)); + + png_composite_16(v, r, a, background->red); + *dp = (png_byte)((v >> 8) & 0xff); + *(dp + 1) = (png_byte)(v & 0xff); + png_composite_16(v, g, a, background->green); + *(dp + 2) = (png_byte)((v >> 8) & 0xff); + *(dp + 3) = (png_byte)(v & 0xff); + png_composite_16(v, b, a, background->blue); + *(dp + 4) = (png_byte)((v >> 8) & 0xff); + *(dp + 5) = (png_byte)(v & 0xff); + } + } + } + } + break; + } + } + + if (row_info->color_type & PNG_COLOR_MASK_ALPHA) + { + row_info->color_type &= ~PNG_COLOR_MASK_ALPHA; + row_info->channels--; + row_info->pixel_depth = (png_byte)(row_info->channels * + row_info->bit_depth); + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width); + } + } +} +#endif + +#if defined(PNG_READ_GAMMA_SUPPORTED) +/* Gamma correct the image, avoiding the alpha channel. Make sure + * you do this after you deal with the transparency issue on grayscale + * or RGB images. If your bit depth is 8, use gamma_table, if it + * is 16, use gamma_16_table and gamma_shift. Build these with + * build_gamma_table(). + */ +void /* PRIVATE */ +png_do_gamma(png_row_infop row_info, png_bytep row, + png_bytep gamma_table, png_uint_16pp gamma_16_table, + int gamma_shift) +{ + png_bytep sp; + png_uint_32 i; + png_uint_32 row_width=row_info->width; + + png_debug(1, "in png_do_gamma\n"); + if ( +#if defined(PNG_USELESS_TESTS_SUPPORTED) + row != NULL && row_info != NULL && +#endif + ((row_info->bit_depth <= 8 && gamma_table != NULL) || + (row_info->bit_depth == 16 && gamma_16_table != NULL))) + { + switch (row_info->color_type) + { + case PNG_COLOR_TYPE_RGB: + { + if (row_info->bit_depth == 8) + { + sp = row; + for (i = 0; i < row_width; i++) + { + *sp = gamma_table[*sp]; + sp++; + *sp = gamma_table[*sp]; + sp++; + *sp = gamma_table[*sp]; + sp++; + } + } + else /* if (row_info->bit_depth == 16) */ + { + sp = row; + for (i = 0; i < row_width; i++) + { + png_uint_16 v; + + v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + sp += 2; + v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + sp += 2; + v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + sp += 2; + } + } + break; + } + case PNG_COLOR_TYPE_RGB_ALPHA: + { + if (row_info->bit_depth == 8) + { + sp = row; + for (i = 0; i < row_width; i++) + { + *sp = gamma_table[*sp]; + sp++; + *sp = gamma_table[*sp]; + sp++; + *sp = gamma_table[*sp]; + sp++; + sp++; + } + } + else /* if (row_info->bit_depth == 16) */ + { + sp = row; + for (i = 0; i < row_width; i++) + { + png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + sp += 2; + v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + sp += 2; + v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + sp += 4; + } + } + break; + } + case PNG_COLOR_TYPE_GRAY_ALPHA: + { + if (row_info->bit_depth == 8) + { + sp = row; + for (i = 0; i < row_width; i++) + { + *sp = gamma_table[*sp]; + sp += 2; + } + } + else /* if (row_info->bit_depth == 16) */ + { + sp = row; + for (i = 0; i < row_width; i++) + { + png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + sp += 4; + } + } + break; + } + case PNG_COLOR_TYPE_GRAY: + { + if (row_info->bit_depth == 2) + { + sp = row; + for (i = 0; i < row_width; i += 4) + { + int a = *sp & 0xc0; + int b = *sp & 0x30; + int c = *sp & 0x0c; + int d = *sp & 0x03; + + *sp = (png_byte)( + ((((int)gamma_table[a|(a>>2)|(a>>4)|(a>>6)]) ) & 0xc0)| + ((((int)gamma_table[(b<<2)|b|(b>>2)|(b>>4)])>>2) & 0x30)| + ((((int)gamma_table[(c<<4)|(c<<2)|c|(c>>2)])>>4) & 0x0c)| + ((((int)gamma_table[(d<<6)|(d<<4)|(d<<2)|d])>>6) )); + sp++; + } + } + if (row_info->bit_depth == 4) + { + sp = row; + for (i = 0; i < row_width; i += 2) + { + int msb = *sp & 0xf0; + int lsb = *sp & 0x0f; + + *sp = (png_byte)((((int)gamma_table[msb | (msb >> 4)]) & 0xf0) + | (((int)gamma_table[(lsb << 4) | lsb]) >> 4)); + sp++; + } + } + else if (row_info->bit_depth == 8) + { + sp = row; + for (i = 0; i < row_width; i++) + { + *sp = gamma_table[*sp]; + sp++; + } + } + else if (row_info->bit_depth == 16) + { + sp = row; + for (i = 0; i < row_width; i++) + { + png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + sp += 2; + } + } + break; + } + } + } +} +#endif + +#if defined(PNG_READ_EXPAND_SUPPORTED) +/* Expands a palette row to an RGB or RGBA row depending + * upon whether you supply trans and num_trans. + */ +void /* PRIVATE */ +png_do_expand_palette(png_row_infop row_info, png_bytep row, + png_colorp palette, png_bytep trans, int num_trans) +{ + int shift, value; + png_bytep sp, dp; + png_uint_32 i; + png_uint_32 row_width=row_info->width; + + png_debug(1, "in png_do_expand_palette\n"); + if ( +#if defined(PNG_USELESS_TESTS_SUPPORTED) + row != NULL && row_info != NULL && +#endif + row_info->color_type == PNG_COLOR_TYPE_PALETTE) + { + if (row_info->bit_depth < 8) + { + switch (row_info->bit_depth) + { + case 1: + { + sp = row + (png_size_t)((row_width - 1) >> 3); + dp = row + (png_size_t)row_width - 1; + shift = 7 - (int)((row_width + 7) & 0x07); + for (i = 0; i < row_width; i++) + { + if ((*sp >> shift) & 0x01) + *dp = 1; + else + *dp = 0; + if (shift == 7) + { + shift = 0; + sp--; + } + else + shift++; + + dp--; + } + break; + } + case 2: + { + sp = row + (png_size_t)((row_width - 1) >> 2); + dp = row + (png_size_t)row_width - 1; + shift = (int)((3 - ((row_width + 3) & 0x03)) << 1); + for (i = 0; i < row_width; i++) + { + value = (*sp >> shift) & 0x03; + *dp = (png_byte)value; + if (shift == 6) + { + shift = 0; + sp--; + } + else + shift += 2; + + dp--; + } + break; + } + case 4: + { + sp = row + (png_size_t)((row_width - 1) >> 1); + dp = row + (png_size_t)row_width - 1; + shift = (int)((row_width & 0x01) << 2); + for (i = 0; i < row_width; i++) + { + value = (*sp >> shift) & 0x0f; + *dp = (png_byte)value; + if (shift == 4) + { + shift = 0; + sp--; + } + else + shift += 4; + + dp--; + } + break; + } + } + row_info->bit_depth = 8; + row_info->pixel_depth = 8; + row_info->rowbytes = row_width; + } + switch (row_info->bit_depth) + { + case 8: + { + if (trans != NULL) + { + sp = row + (png_size_t)row_width - 1; + dp = row + (png_size_t)(row_width << 2) - 1; + + for (i = 0; i < row_width; i++) + { + if ((int)(*sp) >= num_trans) + *dp-- = 0xff; + else + *dp-- = trans[*sp]; + *dp-- = palette[*sp].blue; + *dp-- = palette[*sp].green; + *dp-- = palette[*sp].red; + sp--; + } + row_info->bit_depth = 8; + row_info->pixel_depth = 32; + row_info->rowbytes = row_width * 4; + row_info->color_type = 6; + row_info->channels = 4; + } + else + { + sp = row + (png_size_t)row_width - 1; + dp = row + (png_size_t)(row_width * 3) - 1; + + for (i = 0; i < row_width; i++) + { + *dp-- = palette[*sp].blue; + *dp-- = palette[*sp].green; + *dp-- = palette[*sp].red; + sp--; + } + row_info->bit_depth = 8; + row_info->pixel_depth = 24; + row_info->rowbytes = row_width * 3; + row_info->color_type = 2; + row_info->channels = 3; + } + break; + } + } + } +} + +/* If the bit depth < 8, it is expanded to 8. Also, if the already + * expanded transparency value is supplied, an alpha channel is built. + */ +void /* PRIVATE */ +png_do_expand(png_row_infop row_info, png_bytep row, + png_color_16p trans_value) +{ + int shift, value; + png_bytep sp, dp; + png_uint_32 i; + png_uint_32 row_width=row_info->width; + + png_debug(1, "in png_do_expand\n"); +#if defined(PNG_USELESS_TESTS_SUPPORTED) + if (row != NULL && row_info != NULL) +#endif + { + if (row_info->color_type == PNG_COLOR_TYPE_GRAY) + { + png_uint_16 gray = (png_uint_16)(trans_value ? trans_value->gray : 0); + + if (row_info->bit_depth < 8) + { + switch (row_info->bit_depth) + { + case 1: + { + gray = (png_uint_16)(gray*0xff); + sp = row + (png_size_t)((row_width - 1) >> 3); + dp = row + (png_size_t)row_width - 1; + shift = 7 - (int)((row_width + 7) & 0x07); + for (i = 0; i < row_width; i++) + { + if ((*sp >> shift) & 0x01) + *dp = 0xff; + else + *dp = 0; + if (shift == 7) + { + shift = 0; + sp--; + } + else + shift++; + + dp--; + } + break; + } + case 2: + { + gray = (png_uint_16)(gray*0x55); + sp = row + (png_size_t)((row_width - 1) >> 2); + dp = row + (png_size_t)row_width - 1; + shift = (int)((3 - ((row_width + 3) & 0x03)) << 1); + for (i = 0; i < row_width; i++) + { + value = (*sp >> shift) & 0x03; + *dp = (png_byte)(value | (value << 2) | (value << 4) | + (value << 6)); + if (shift == 6) + { + shift = 0; + sp--; + } + else + shift += 2; + + dp--; + } + break; + } + case 4: + { + gray = (png_uint_16)(gray*0x11); + sp = row + (png_size_t)((row_width - 1) >> 1); + dp = row + (png_size_t)row_width - 1; + shift = (int)((1 - ((row_width + 1) & 0x01)) << 2); + for (i = 0; i < row_width; i++) + { + value = (*sp >> shift) & 0x0f; + *dp = (png_byte)(value | (value << 4)); + if (shift == 4) + { + shift = 0; + sp--; + } + else + shift = 4; + + dp--; + } + break; + } + } + row_info->bit_depth = 8; + row_info->pixel_depth = 8; + row_info->rowbytes = row_width; + } + + if (trans_value != NULL) + { + if (row_info->bit_depth == 8) + { + sp = row + (png_size_t)row_width - 1; + dp = row + (png_size_t)(row_width << 1) - 1; + for (i = 0; i < row_width; i++) + { + if (*sp == gray) + *dp-- = 0; + else + *dp-- = 0xff; + *dp-- = *sp--; + } + } + else if (row_info->bit_depth == 16) + { + sp = row + row_info->rowbytes - 1; + dp = row + (row_info->rowbytes << 1) - 1; + for (i = 0; i < row_width; i++) + { + if (((png_uint_16)*(sp) | + ((png_uint_16)*(sp - 1) << 8)) == gray) + { + *dp-- = 0; + *dp-- = 0; + } + else + { + *dp-- = 0xff; + *dp-- = 0xff; + } + *dp-- = *sp--; + *dp-- = *sp--; + } + } + row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA; + row_info->channels = 2; + row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1); + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, + row_width); + } + } + else if (row_info->color_type == PNG_COLOR_TYPE_RGB && trans_value) + { + if (row_info->bit_depth == 8) + { + sp = row + (png_size_t)row_info->rowbytes - 1; + dp = row + (png_size_t)(row_width << 2) - 1; + for (i = 0; i < row_width; i++) + { + if (*(sp - 2) == trans_value->red && + *(sp - 1) == trans_value->green && + *(sp - 0) == trans_value->blue) + *dp-- = 0; + else + *dp-- = 0xff; + *dp-- = *sp--; + *dp-- = *sp--; + *dp-- = *sp--; + } + } + else if (row_info->bit_depth == 16) + { + sp = row + row_info->rowbytes - 1; + dp = row + (png_size_t)(row_width << 3) - 1; + for (i = 0; i < row_width; i++) + { + if ((((png_uint_16)*(sp - 4) | + ((png_uint_16)*(sp - 5) << 8)) == trans_value->red) && + (((png_uint_16)*(sp - 2) | + ((png_uint_16)*(sp - 3) << 8)) == trans_value->green) && + (((png_uint_16)*(sp - 0) | + ((png_uint_16)*(sp - 1) << 8)) == trans_value->blue)) + { + *dp-- = 0; + *dp-- = 0; + } + else + { + *dp-- = 0xff; + *dp-- = 0xff; + } + *dp-- = *sp--; + *dp-- = *sp--; + *dp-- = *sp--; + *dp-- = *sp--; + *dp-- = *sp--; + *dp-- = *sp--; + } + } + row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA; + row_info->channels = 4; + row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2); + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width); + } + } +} +#endif + +#if defined(PNG_READ_DITHER_SUPPORTED) +void /* PRIVATE */ +png_do_dither(png_row_infop row_info, png_bytep row, + png_bytep palette_lookup, png_bytep dither_lookup) +{ + png_bytep sp, dp; + png_uint_32 i; + png_uint_32 row_width=row_info->width; + + png_debug(1, "in png_do_dither\n"); +#if defined(PNG_USELESS_TESTS_SUPPORTED) + if (row != NULL && row_info != NULL) +#endif + { + if (row_info->color_type == PNG_COLOR_TYPE_RGB && + palette_lookup && row_info->bit_depth == 8) + { + int r, g, b, p; + sp = row; + dp = row; + for (i = 0; i < row_width; i++) + { + r = *sp++; + g = *sp++; + b = *sp++; + + /* this looks real messy, but the compiler will reduce + it down to a reasonable formula. For example, with + 5 bits per color, we get: + p = (((r >> 3) & 0x1f) << 10) | + (((g >> 3) & 0x1f) << 5) | + ((b >> 3) & 0x1f); + */ + p = (((r >> (8 - PNG_DITHER_RED_BITS)) & + ((1 << PNG_DITHER_RED_BITS) - 1)) << + (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) | + (((g >> (8 - PNG_DITHER_GREEN_BITS)) & + ((1 << PNG_DITHER_GREEN_BITS) - 1)) << + (PNG_DITHER_BLUE_BITS)) | + ((b >> (8 - PNG_DITHER_BLUE_BITS)) & + ((1 << PNG_DITHER_BLUE_BITS) - 1)); + + *dp++ = palette_lookup[p]; + } + row_info->color_type = PNG_COLOR_TYPE_PALETTE; + row_info->channels = 1; + row_info->pixel_depth = row_info->bit_depth; + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width); + } + else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA && + palette_lookup != NULL && row_info->bit_depth == 8) + { + int r, g, b, p; + sp = row; + dp = row; + for (i = 0; i < row_width; i++) + { + r = *sp++; + g = *sp++; + b = *sp++; + sp++; + + p = (((r >> (8 - PNG_DITHER_RED_BITS)) & + ((1 << PNG_DITHER_RED_BITS) - 1)) << + (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) | + (((g >> (8 - PNG_DITHER_GREEN_BITS)) & + ((1 << PNG_DITHER_GREEN_BITS) - 1)) << + (PNG_DITHER_BLUE_BITS)) | + ((b >> (8 - PNG_DITHER_BLUE_BITS)) & + ((1 << PNG_DITHER_BLUE_BITS) - 1)); + + *dp++ = palette_lookup[p]; + } + row_info->color_type = PNG_COLOR_TYPE_PALETTE; + row_info->channels = 1; + row_info->pixel_depth = row_info->bit_depth; + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width); + } + else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE && + dither_lookup && row_info->bit_depth == 8) + { + sp = row; + for (i = 0; i < row_width; i++, sp++) + { + *sp = dither_lookup[*sp]; + } + } + } +} +#endif + +#ifdef PNG_FLOATING_POINT_SUPPORTED +#if defined(PNG_READ_GAMMA_SUPPORTED) +static int png_gamma_shift[] = + {0x10, 0x21, 0x42, 0x84, 0x110, 0x248, 0x550, 0xff0, 0x00}; + +/* We build the 8- or 16-bit gamma tables here. Note that for 16-bit + * tables, we don't make a full table if we are reducing to 8-bit in + * the future. Note also how the gamma_16 tables are segmented so that + * we don't need to allocate > 64K chunks for a full 16-bit table. + */ +void /* PRIVATE */ +png_build_gamma_table(png_structp png_ptr) +{ + png_debug(1, "in png_build_gamma_table\n"); + + if (png_ptr->bit_depth <= 8) + { + int i; + double g; + + if (png_ptr->screen_gamma > .000001) + g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma); + else + g = 1.0; + + png_ptr->gamma_table = (png_bytep)png_malloc(png_ptr, + (png_uint_32)256); + + for (i = 0; i < 256; i++) + { + png_ptr->gamma_table[i] = (png_byte)(pow((double)i / 255.0, + g) * 255.0 + .5); + } + +#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ + defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) + if (png_ptr->transformations & ((PNG_BACKGROUND) | PNG_RGB_TO_GRAY)) + { + + g = 1.0 / (png_ptr->gamma); + + png_ptr->gamma_to_1 = (png_bytep)png_malloc(png_ptr, + (png_uint_32)256); + + for (i = 0; i < 256; i++) + { + png_ptr->gamma_to_1[i] = (png_byte)(pow((double)i / 255.0, + g) * 255.0 + .5); + } + + + png_ptr->gamma_from_1 = (png_bytep)png_malloc(png_ptr, + (png_uint_32)256); + + if(png_ptr->screen_gamma > 0.000001) + g = 1.0 / png_ptr->screen_gamma; + else + g = png_ptr->gamma; /* probably doing rgb_to_gray */ + + for (i = 0; i < 256; i++) + { + png_ptr->gamma_from_1[i] = (png_byte)(pow((double)i / 255.0, + g) * 255.0 + .5); + + } + } +#endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */ + } + else + { + double g; + int i, j, shift, num; + int sig_bit; + png_uint_32 ig; + + if (png_ptr->color_type & PNG_COLOR_MASK_COLOR) + { + sig_bit = (int)png_ptr->sig_bit.red; + if ((int)png_ptr->sig_bit.green > sig_bit) + sig_bit = png_ptr->sig_bit.green; + if ((int)png_ptr->sig_bit.blue > sig_bit) + sig_bit = png_ptr->sig_bit.blue; + } + else + { + sig_bit = (int)png_ptr->sig_bit.gray; + } + + if (sig_bit > 0) + shift = 16 - sig_bit; + else + shift = 0; + + if (png_ptr->transformations & PNG_16_TO_8) + { + if (shift < (16 - PNG_MAX_GAMMA_8)) + shift = (16 - PNG_MAX_GAMMA_8); + } + + if (shift > 8) + shift = 8; + if (shift < 0) + shift = 0; + + png_ptr->gamma_shift = (png_byte)shift; + + num = (1 << (8 - shift)); + + if (png_ptr->screen_gamma > .000001) + g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma); + else + g = 1.0; + + png_ptr->gamma_16_table = (png_uint_16pp)png_malloc(png_ptr, + (png_uint_32)(num * png_sizeof (png_uint_16p))); + + if (png_ptr->transformations & (PNG_16_TO_8 | PNG_BACKGROUND)) + { + double fin, fout; + png_uint_32 last, max; + + for (i = 0; i < num; i++) + { + png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr, + (png_uint_32)(256 * png_sizeof (png_uint_16))); + } + + g = 1.0 / g; + last = 0; + for (i = 0; i < 256; i++) + { + fout = ((double)i + 0.5) / 256.0; + fin = pow(fout, g); + max = (png_uint_32)(fin * (double)((png_uint_32)num << 8)); + while (last <= max) + { + png_ptr->gamma_16_table[(int)(last & (0xff >> shift))] + [(int)(last >> (8 - shift))] = (png_uint_16)( + (png_uint_16)i | ((png_uint_16)i << 8)); + last++; + } + } + while (last < ((png_uint_32)num << 8)) + { + png_ptr->gamma_16_table[(int)(last & (0xff >> shift))] + [(int)(last >> (8 - shift))] = (png_uint_16)65535L; + last++; + } + } + else + { + for (i = 0; i < num; i++) + { + png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr, + (png_uint_32)(256 * png_sizeof (png_uint_16))); + + ig = (((png_uint_32)i * (png_uint_32)png_gamma_shift[shift]) >> 4); + for (j = 0; j < 256; j++) + { + png_ptr->gamma_16_table[i][j] = + (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) / + 65535.0, g) * 65535.0 + .5); + } + } + } + +#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ + defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) + if (png_ptr->transformations & (PNG_BACKGROUND | PNG_RGB_TO_GRAY)) + { + + g = 1.0 / (png_ptr->gamma); + + png_ptr->gamma_16_to_1 = (png_uint_16pp)png_malloc(png_ptr, + (png_uint_32)(num * png_sizeof (png_uint_16p ))); + + for (i = 0; i < num; i++) + { + png_ptr->gamma_16_to_1[i] = (png_uint_16p)png_malloc(png_ptr, + (png_uint_32)(256 * png_sizeof (png_uint_16))); + + ig = (((png_uint_32)i * + (png_uint_32)png_gamma_shift[shift]) >> 4); + for (j = 0; j < 256; j++) + { + png_ptr->gamma_16_to_1[i][j] = + (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) / + 65535.0, g) * 65535.0 + .5); + } + } + + if(png_ptr->screen_gamma > 0.000001) + g = 1.0 / png_ptr->screen_gamma; + else + g = png_ptr->gamma; /* probably doing rgb_to_gray */ + + png_ptr->gamma_16_from_1 = (png_uint_16pp)png_malloc(png_ptr, + (png_uint_32)(num * png_sizeof (png_uint_16p))); + + for (i = 0; i < num; i++) + { + png_ptr->gamma_16_from_1[i] = (png_uint_16p)png_malloc(png_ptr, + (png_uint_32)(256 * png_sizeof (png_uint_16))); + + ig = (((png_uint_32)i * + (png_uint_32)png_gamma_shift[shift]) >> 4); + for (j = 0; j < 256; j++) + { + png_ptr->gamma_16_from_1[i][j] = + (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) / + 65535.0, g) * 65535.0 + .5); + } + } + } +#endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */ + } +} +#endif +/* To do: install integer version of png_build_gamma_table here */ +#endif + +#if defined(PNG_MNG_FEATURES_SUPPORTED) +/* undoes intrapixel differencing */ +void /* PRIVATE */ +png_do_read_intrapixel(png_row_infop row_info, png_bytep row) +{ + png_debug(1, "in png_do_read_intrapixel\n"); + if ( +#if defined(PNG_USELESS_TESTS_SUPPORTED) + row != NULL && row_info != NULL && +#endif + (row_info->color_type & PNG_COLOR_MASK_COLOR)) + { + int bytes_per_pixel; + png_uint_32 row_width = row_info->width; + if (row_info->bit_depth == 8) + { + png_bytep rp; + png_uint_32 i; + + if (row_info->color_type == PNG_COLOR_TYPE_RGB) + bytes_per_pixel = 3; + else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + bytes_per_pixel = 4; + else + return; + + for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) + { + *(rp) = (png_byte)((256 + *rp + *(rp+1))&0xff); + *(rp+2) = (png_byte)((256 + *(rp+2) + *(rp+1))&0xff); + } + } + else if (row_info->bit_depth == 16) + { + png_bytep rp; + png_uint_32 i; + + if (row_info->color_type == PNG_COLOR_TYPE_RGB) + bytes_per_pixel = 6; + else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + bytes_per_pixel = 8; + else + return; + + for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) + { + png_uint_32 s0 = (*(rp ) << 8) | *(rp+1); + png_uint_32 s1 = (*(rp+2) << 8) | *(rp+3); + png_uint_32 s2 = (*(rp+4) << 8) | *(rp+5); + png_uint_32 red = (png_uint_32)((s0+s1+65536L) & 0xffffL); + png_uint_32 blue = (png_uint_32)((s2+s1+65536L) & 0xffffL); + *(rp ) = (png_byte)((red >> 8) & 0xff); + *(rp+1) = (png_byte)(red & 0xff); + *(rp+4) = (png_byte)((blue >> 8) & 0xff); + *(rp+5) = (png_byte)(blue & 0xff); + } + } + } +} +#endif /* PNG_MNG_FEATURES_SUPPORTED */ +#endif /* PNG_READ_SUPPORTED */ diff --git a/mod/pub.mod/libpng.mod/pngrutil.c b/mod/pub.mod/libpng.mod/pngrutil.c new file mode 100644 index 0000000..5b68b21 --- /dev/null +++ b/mod/pub.mod/libpng.mod/pngrutil.c @@ -0,0 +1,3123 @@ + +/* pngrutil.c - utilities to read a PNG file + * + * Last changed in libpng 1.2.11 June 4, 2006 + * For conditions of distribution and use, see copyright notice in png.h + * Copyright (c) 1998-2006 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * + * This file contains routines that are only called from within + * libpng itself during the course of reading an image. + */ + +#define PNG_INTERNAL +#include "png.h" + +#if defined(PNG_READ_SUPPORTED) + +#if defined(_WIN32_WCE) +/* strtod() function is not supported on WindowsCE */ +# ifdef PNG_FLOATING_POINT_SUPPORTED +__inline double strtod(const char *nptr, char **endptr) +{ + double result = 0; + int len; + wchar_t *str, *end; + + len = MultiByteToWideChar(CP_ACP, 0, nptr, -1, NULL, 0); + str = (wchar_t *)malloc(len * sizeof(wchar_t)); + if ( NULL != str ) + { + MultiByteToWideChar(CP_ACP, 0, nptr, -1, str, len); + result = wcstod(str, &end); + len = WideCharToMultiByte(CP_ACP, 0, end, -1, NULL, 0, NULL, NULL); + *endptr = (char *)nptr + (png_strlen(nptr) - len + 1); + free(str); + } + return result; +} +# endif +#endif + +png_uint_32 PNGAPI +png_get_uint_31(png_structp png_ptr, png_bytep buf) +{ + png_uint_32 i = png_get_uint_32(buf); + if (i > PNG_UINT_31_MAX) + png_error(png_ptr, "PNG unsigned integer out of range."); + return (i); +} +#ifndef PNG_READ_BIG_ENDIAN_SUPPORTED +/* Grab an unsigned 32-bit integer from a buffer in big-endian format. */ +png_uint_32 PNGAPI +png_get_uint_32(png_bytep buf) +{ + png_uint_32 i = ((png_uint_32)(*buf) << 24) + + ((png_uint_32)(*(buf + 1)) << 16) + + ((png_uint_32)(*(buf + 2)) << 8) + + (png_uint_32)(*(buf + 3)); + + return (i); +} + +/* Grab a signed 32-bit integer from a buffer in big-endian format. The + * data is stored in the PNG file in two's complement format, and it is + * assumed that the machine format for signed integers is the same. */ +png_int_32 PNGAPI +png_get_int_32(png_bytep buf) +{ + png_int_32 i = ((png_int_32)(*buf) << 24) + + ((png_int_32)(*(buf + 1)) << 16) + + ((png_int_32)(*(buf + 2)) << 8) + + (png_int_32)(*(buf + 3)); + + return (i); +} + +/* Grab an unsigned 16-bit integer from a buffer in big-endian format. */ +png_uint_16 PNGAPI +png_get_uint_16(png_bytep buf) +{ + png_uint_16 i = (png_uint_16)(((png_uint_16)(*buf) << 8) + + (png_uint_16)(*(buf + 1))); + + return (i); +} +#endif /* PNG_READ_BIG_ENDIAN_SUPPORTED */ + +/* Read data, and (optionally) run it through the CRC. */ +void /* PRIVATE */ +png_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length) +{ + png_read_data(png_ptr, buf, length); + png_calculate_crc(png_ptr, buf, length); +} + +/* Optionally skip data and then check the CRC. Depending on whether we + are reading a ancillary or critical chunk, and how the program has set + things up, we may calculate the CRC on the data and print a message. + Returns '1' if there was a CRC error, '0' otherwise. */ +int /* PRIVATE */ +png_crc_finish(png_structp png_ptr, png_uint_32 skip) +{ + png_size_t i; + png_size_t istop = png_ptr->zbuf_size; + + for (i = (png_size_t)skip; i > istop; i -= istop) + { + png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size); + } + if (i) + { + png_crc_read(png_ptr, png_ptr->zbuf, i); + } + + if (png_crc_error(png_ptr)) + { + if (((png_ptr->chunk_name[0] & 0x20) && /* Ancillary */ + !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) || + (!(png_ptr->chunk_name[0] & 0x20) && /* Critical */ + (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE))) + { + png_chunk_warning(png_ptr, "CRC error"); + } + else + { + png_chunk_error(png_ptr, "CRC error"); + } + return (1); + } + + return (0); +} + +/* Compare the CRC stored in the PNG file with that calculated by libpng from + the data it has read thus far. */ +int /* PRIVATE */ +png_crc_error(png_structp png_ptr) +{ + png_byte crc_bytes[4]; + png_uint_32 crc; + int need_crc = 1; + + if (png_ptr->chunk_name[0] & 0x20) /* ancillary */ + { + if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) == + (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN)) + need_crc = 0; + } + else /* critical */ + { + if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) + need_crc = 0; + } + + png_read_data(png_ptr, crc_bytes, 4); + + if (need_crc) + { + crc = png_get_uint_32(crc_bytes); + return ((int)(crc != png_ptr->crc)); + } + else + return (0); +} + +#if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) || \ + defined(PNG_READ_iCCP_SUPPORTED) +/* + * Decompress trailing data in a chunk. The assumption is that chunkdata + * points at an allocated area holding the contents of a chunk with a + * trailing compressed part. What we get back is an allocated area + * holding the original prefix part and an uncompressed version of the + * trailing part (the malloc area passed in is freed). + */ +png_charp /* PRIVATE */ +png_decompress_chunk(png_structp png_ptr, int comp_type, + png_charp chunkdata, png_size_t chunklength, + png_size_t prefix_size, png_size_t *newlength) +{ + static char msg[] = "Error decoding compressed text"; + png_charp text; + png_size_t text_size; + + if (comp_type == PNG_COMPRESSION_TYPE_BASE) + { + int ret = Z_OK; + png_ptr->zstream.next_in = (png_bytep)(chunkdata + prefix_size); + png_ptr->zstream.avail_in = (uInt)(chunklength - prefix_size); + png_ptr->zstream.next_out = png_ptr->zbuf; + png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; + + text_size = 0; + text = NULL; + + while (png_ptr->zstream.avail_in) + { + ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH); + if (ret != Z_OK && ret != Z_STREAM_END) + { + if (png_ptr->zstream.msg != NULL) + png_warning(png_ptr, png_ptr->zstream.msg); + else + png_warning(png_ptr, msg); + inflateReset(&png_ptr->zstream); + png_ptr->zstream.avail_in = 0; + + if (text == NULL) + { + text_size = prefix_size + png_sizeof(msg) + 1; + text = (png_charp)png_malloc_warn(png_ptr, text_size); + if (text == NULL) + { + png_free(png_ptr,chunkdata); + png_error(png_ptr,"Not enough memory to decompress chunk"); + } + png_memcpy(text, chunkdata, prefix_size); + } + + text[text_size - 1] = 0x00; + + /* Copy what we can of the error message into the text chunk */ + text_size = (png_size_t)(chunklength - (text - chunkdata) - 1); + text_size = png_sizeof(msg) > text_size ? text_size : + png_sizeof(msg); + png_memcpy(text + prefix_size, msg, text_size + 1); + break; + } + if (!png_ptr->zstream.avail_out || ret == Z_STREAM_END) + { + if (text == NULL) + { + text_size = prefix_size + + png_ptr->zbuf_size - png_ptr->zstream.avail_out; + text = (png_charp)png_malloc_warn(png_ptr, text_size + 1); + if (text == NULL) + { + png_free(png_ptr,chunkdata); + png_error(png_ptr,"Not enough memory to decompress chunk."); + } + png_memcpy(text + prefix_size, png_ptr->zbuf, + text_size - prefix_size); + png_memcpy(text, chunkdata, prefix_size); + *(text + text_size) = 0x00; + } + else + { + png_charp tmp; + + tmp = text; + text = (png_charp)png_malloc_warn(png_ptr, + (png_uint_32)(text_size + + png_ptr->zbuf_size - png_ptr->zstream.avail_out + 1)); + if (text == NULL) + { + png_free(png_ptr, tmp); + png_free(png_ptr, chunkdata); + png_error(png_ptr,"Not enough memory to decompress chunk.."); + } + png_memcpy(text, tmp, text_size); + png_free(png_ptr, tmp); + png_memcpy(text + text_size, png_ptr->zbuf, + (png_ptr->zbuf_size - png_ptr->zstream.avail_out)); + text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out; + *(text + text_size) = 0x00; + } + if (ret == Z_STREAM_END) + break; + else + { + png_ptr->zstream.next_out = png_ptr->zbuf; + png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; + } + } + } + if (ret != Z_STREAM_END) + { +#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE) + char umsg[52]; + + if (ret == Z_BUF_ERROR) + sprintf(umsg,"Buffer error in compressed datastream in %s chunk", + png_ptr->chunk_name); + else if (ret == Z_DATA_ERROR) + sprintf(umsg,"Data error in compressed datastream in %s chunk", + png_ptr->chunk_name); + else + sprintf(umsg,"Incomplete compressed datastream in %s chunk", + png_ptr->chunk_name); + png_warning(png_ptr, umsg); +#else + png_warning(png_ptr, + "Incomplete compressed datastream in chunk other than IDAT"); +#endif + text_size=prefix_size; + if (text == NULL) + { + text = (png_charp)png_malloc_warn(png_ptr, text_size+1); + if (text == NULL) + { + png_free(png_ptr, chunkdata); + png_error(png_ptr,"Not enough memory for text."); + } + png_memcpy(text, chunkdata, prefix_size); + } + *(text + text_size) = 0x00; + } + + inflateReset(&png_ptr->zstream); + png_ptr->zstream.avail_in = 0; + + png_free(png_ptr, chunkdata); + chunkdata = text; + *newlength=text_size; + } + else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */ + { +#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE) + char umsg[50]; + + sprintf(umsg, "Unknown zTXt compression type %d", comp_type); + png_warning(png_ptr, umsg); +#else + png_warning(png_ptr, "Unknown zTXt compression type"); +#endif + + *(chunkdata + prefix_size) = 0x00; + *newlength=prefix_size; + } + + return chunkdata; +} +#endif + +/* read and check the IDHR chunk */ +void /* PRIVATE */ +png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + png_byte buf[13]; + png_uint_32 width, height; + int bit_depth, color_type, compression_type, filter_type; + int interlace_type; + + png_debug(1, "in png_handle_IHDR\n"); + + if (png_ptr->mode & PNG_HAVE_IHDR) + png_error(png_ptr, "Out of place IHDR"); + + /* check the length */ + if (length != 13) + png_error(png_ptr, "Invalid IHDR chunk"); + + png_ptr->mode |= PNG_HAVE_IHDR; + + png_crc_read(png_ptr, buf, 13); + png_crc_finish(png_ptr, 0); + + width = png_get_uint_31(png_ptr, buf); + height = png_get_uint_31(png_ptr, buf + 4); + bit_depth = buf[8]; + color_type = buf[9]; + compression_type = buf[10]; + filter_type = buf[11]; + interlace_type = buf[12]; + + /* set internal variables */ + png_ptr->width = width; + png_ptr->height = height; + png_ptr->bit_depth = (png_byte)bit_depth; + png_ptr->interlaced = (png_byte)interlace_type; + png_ptr->color_type = (png_byte)color_type; +#if defined(PNG_MNG_FEATURES_SUPPORTED) + png_ptr->filter_type = (png_byte)filter_type; +#endif + png_ptr->compression_type = (png_byte)compression_type; + + /* find number of channels */ + switch (png_ptr->color_type) + { + case PNG_COLOR_TYPE_GRAY: + case PNG_COLOR_TYPE_PALETTE: + png_ptr->channels = 1; + break; + case PNG_COLOR_TYPE_RGB: + png_ptr->channels = 3; + break; + case PNG_COLOR_TYPE_GRAY_ALPHA: + png_ptr->channels = 2; + break; + case PNG_COLOR_TYPE_RGB_ALPHA: + png_ptr->channels = 4; + break; + } + + /* set up other useful info */ + png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth * + png_ptr->channels); + png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,png_ptr->width); + png_debug1(3,"bit_depth = %d\n", png_ptr->bit_depth); + png_debug1(3,"channels = %d\n", png_ptr->channels); + png_debug1(3,"rowbytes = %lu\n", png_ptr->rowbytes); + png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, + color_type, interlace_type, compression_type, filter_type); +} + +/* read and check the palette */ +void /* PRIVATE */ +png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + png_color palette[PNG_MAX_PALETTE_LENGTH]; + int num, i; +#ifndef PNG_NO_POINTER_INDEXING + png_colorp pal_ptr; +#endif + + png_debug(1, "in png_handle_PLTE\n"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before PLTE"); + else if (png_ptr->mode & PNG_HAVE_IDAT) + { + png_warning(png_ptr, "Invalid PLTE after IDAT"); + png_crc_finish(png_ptr, length); + return; + } + else if (png_ptr->mode & PNG_HAVE_PLTE) + png_error(png_ptr, "Duplicate PLTE chunk"); + + png_ptr->mode |= PNG_HAVE_PLTE; + + if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR)) + { + png_warning(png_ptr, + "Ignoring PLTE chunk in grayscale PNG"); + png_crc_finish(png_ptr, length); + return; + } +#if !defined(PNG_READ_OPT_PLTE_SUPPORTED) + if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE) + { + png_crc_finish(png_ptr, length); + return; + } +#endif + + if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3) + { + if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE) + { + png_warning(png_ptr, "Invalid palette chunk"); + png_crc_finish(png_ptr, length); + return; + } + else + { + png_error(png_ptr, "Invalid palette chunk"); + } + } + + num = (int)length / 3; + +#ifndef PNG_NO_POINTER_INDEXING + for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++) + { + png_byte buf[3]; + + png_crc_read(png_ptr, buf, 3); + pal_ptr->red = buf[0]; + pal_ptr->green = buf[1]; + pal_ptr->blue = buf[2]; + } +#else + for (i = 0; i < num; i++) + { + png_byte buf[3]; + + png_crc_read(png_ptr, buf, 3); + /* don't depend upon png_color being any order */ + palette[i].red = buf[0]; + palette[i].green = buf[1]; + palette[i].blue = buf[2]; + } +#endif + + /* If we actually NEED the PLTE chunk (ie for a paletted image), we do + whatever the normal CRC configuration tells us. However, if we + have an RGB image, the PLTE can be considered ancillary, so + we will act as though it is. */ +#if !defined(PNG_READ_OPT_PLTE_SUPPORTED) + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) +#endif + { + png_crc_finish(png_ptr, 0); + } +#if !defined(PNG_READ_OPT_PLTE_SUPPORTED) + else if (png_crc_error(png_ptr)) /* Only if we have a CRC error */ + { + /* If we don't want to use the data from an ancillary chunk, + we have two options: an error abort, or a warning and we + ignore the data in this chunk (which should be OK, since + it's considered ancillary for a RGB or RGBA image). */ + if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE)) + { + if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) + { + png_chunk_error(png_ptr, "CRC error"); + } + else + { + png_chunk_warning(png_ptr, "CRC error"); + return; + } + } + /* Otherwise, we (optionally) emit a warning and use the chunk. */ + else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) + { + png_chunk_warning(png_ptr, "CRC error"); + } + } +#endif + + png_set_PLTE(png_ptr, info_ptr, palette, num); + +#if defined(PNG_READ_tRNS_SUPPORTED) + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { + if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS)) + { + if (png_ptr->num_trans > (png_uint_16)num) + { + png_warning(png_ptr, "Truncating incorrect tRNS chunk length"); + png_ptr->num_trans = (png_uint_16)num; + } + if (info_ptr->num_trans > (png_uint_16)num) + { + png_warning(png_ptr, "Truncating incorrect info tRNS chunk length"); + info_ptr->num_trans = (png_uint_16)num; + } + } + } +#endif + +} + +void /* PRIVATE */ +png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + png_debug(1, "in png_handle_IEND\n"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT)) + { + png_error(png_ptr, "No image in file"); + } + + png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND); + + if (length != 0) + { + png_warning(png_ptr, "Incorrect IEND chunk length"); + } + png_crc_finish(png_ptr, length); + + if (&info_ptr == NULL) /* quiet compiler warnings about unused info_ptr */ + return; +} + +#if defined(PNG_READ_gAMA_SUPPORTED) +void /* PRIVATE */ +png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + png_fixed_point igamma; +#ifdef PNG_FLOATING_POINT_SUPPORTED + float file_gamma; +#endif + png_byte buf[4]; + + png_debug(1, "in png_handle_gAMA\n"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before gAMA"); + else if (png_ptr->mode & PNG_HAVE_IDAT) + { + png_warning(png_ptr, "Invalid gAMA after IDAT"); + png_crc_finish(png_ptr, length); + return; + } + else if (png_ptr->mode & PNG_HAVE_PLTE) + /* Should be an error, but we can cope with it */ + png_warning(png_ptr, "Out of place gAMA chunk"); + + if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA) +#if defined(PNG_READ_sRGB_SUPPORTED) + && !(info_ptr->valid & PNG_INFO_sRGB) +#endif + ) + { + png_warning(png_ptr, "Duplicate gAMA chunk"); + png_crc_finish(png_ptr, length); + return; + } + + if (length != 4) + { + png_warning(png_ptr, "Incorrect gAMA chunk length"); + png_crc_finish(png_ptr, length); + return; + } + + png_crc_read(png_ptr, buf, 4); + if (png_crc_finish(png_ptr, 0)) + return; + + igamma = (png_fixed_point)png_get_uint_32(buf); + /* check for zero gamma */ + if (igamma == 0) + { + png_warning(png_ptr, + "Ignoring gAMA chunk with gamma=0"); + return; + } + +#if defined(PNG_READ_sRGB_SUPPORTED) + if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB)) + if (PNG_OUT_OF_RANGE(igamma, 45500L, 500)) + { + png_warning(png_ptr, + "Ignoring incorrect gAMA value when sRGB is also present"); +#ifndef PNG_NO_CONSOLE_IO + fprintf(stderr, "gamma = (%d/100000)\n", (int)igamma); +#endif + return; + } +#endif /* PNG_READ_sRGB_SUPPORTED */ + +#ifdef PNG_FLOATING_POINT_SUPPORTED + file_gamma = (float)igamma / (float)100000.0; +# ifdef PNG_READ_GAMMA_SUPPORTED + png_ptr->gamma = file_gamma; +# endif + png_set_gAMA(png_ptr, info_ptr, file_gamma); +#endif +#ifdef PNG_FIXED_POINT_SUPPORTED + png_set_gAMA_fixed(png_ptr, info_ptr, igamma); +#endif +} +#endif + +#if defined(PNG_READ_sBIT_SUPPORTED) +void /* PRIVATE */ +png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + png_size_t truelen; + png_byte buf[4]; + + png_debug(1, "in png_handle_sBIT\n"); + + buf[0] = buf[1] = buf[2] = buf[3] = 0; + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before sBIT"); + else if (png_ptr->mode & PNG_HAVE_IDAT) + { + png_warning(png_ptr, "Invalid sBIT after IDAT"); + png_crc_finish(png_ptr, length); + return; + } + else if (png_ptr->mode & PNG_HAVE_PLTE) + { + /* Should be an error, but we can cope with it */ + png_warning(png_ptr, "Out of place sBIT chunk"); + } + if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT)) + { + png_warning(png_ptr, "Duplicate sBIT chunk"); + png_crc_finish(png_ptr, length); + return; + } + + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + truelen = 3; + else + truelen = (png_size_t)png_ptr->channels; + + if (length != truelen || length > 4) + { + png_warning(png_ptr, "Incorrect sBIT chunk length"); + png_crc_finish(png_ptr, length); + return; + } + + png_crc_read(png_ptr, buf, truelen); + if (png_crc_finish(png_ptr, 0)) + return; + + if (png_ptr->color_type & PNG_COLOR_MASK_COLOR) + { + png_ptr->sig_bit.red = buf[0]; + png_ptr->sig_bit.green = buf[1]; + png_ptr->sig_bit.blue = buf[2]; + png_ptr->sig_bit.alpha = buf[3]; + } + else + { + png_ptr->sig_bit.gray = buf[0]; + png_ptr->sig_bit.red = buf[0]; + png_ptr->sig_bit.green = buf[0]; + png_ptr->sig_bit.blue = buf[0]; + png_ptr->sig_bit.alpha = buf[1]; + } + png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit)); +} +#endif + +#if defined(PNG_READ_cHRM_SUPPORTED) +void /* PRIVATE */ +png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + png_byte buf[4]; +#ifdef PNG_FLOATING_POINT_SUPPORTED + float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y; +#endif + png_fixed_point int_x_white, int_y_white, int_x_red, int_y_red, int_x_green, + int_y_green, int_x_blue, int_y_blue; + + png_uint_32 uint_x, uint_y; + + png_debug(1, "in png_handle_cHRM\n"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before cHRM"); + else if (png_ptr->mode & PNG_HAVE_IDAT) + { + png_warning(png_ptr, "Invalid cHRM after IDAT"); + png_crc_finish(png_ptr, length); + return; + } + else if (png_ptr->mode & PNG_HAVE_PLTE) + /* Should be an error, but we can cope with it */ + png_warning(png_ptr, "Missing PLTE before cHRM"); + + if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM) +#if defined(PNG_READ_sRGB_SUPPORTED) + && !(info_ptr->valid & PNG_INFO_sRGB) +#endif + ) + { + png_warning(png_ptr, "Duplicate cHRM chunk"); + png_crc_finish(png_ptr, length); + return; + } + + if (length != 32) + { + png_warning(png_ptr, "Incorrect cHRM chunk length"); + png_crc_finish(png_ptr, length); + return; + } + + png_crc_read(png_ptr, buf, 4); + uint_x = png_get_uint_32(buf); + + png_crc_read(png_ptr, buf, 4); + uint_y = png_get_uint_32(buf); + + if (uint_x > 80000L || uint_y > 80000L || + uint_x + uint_y > 100000L) + { + png_warning(png_ptr, "Invalid cHRM white point"); + png_crc_finish(png_ptr, 24); + return; + } + int_x_white = (png_fixed_point)uint_x; + int_y_white = (png_fixed_point)uint_y; + + png_crc_read(png_ptr, buf, 4); + uint_x = png_get_uint_32(buf); + + png_crc_read(png_ptr, buf, 4); + uint_y = png_get_uint_32(buf); + + if (uint_x + uint_y > 100000L) + { + png_warning(png_ptr, "Invalid cHRM red point"); + png_crc_finish(png_ptr, 16); + return; + } + int_x_red = (png_fixed_point)uint_x; + int_y_red = (png_fixed_point)uint_y; + + png_crc_read(png_ptr, buf, 4); + uint_x = png_get_uint_32(buf); + + png_crc_read(png_ptr, buf, 4); + uint_y = png_get_uint_32(buf); + + if (uint_x + uint_y > 100000L) + { + png_warning(png_ptr, "Invalid cHRM green point"); + png_crc_finish(png_ptr, 8); + return; + } + int_x_green = (png_fixed_point)uint_x; + int_y_green = (png_fixed_point)uint_y; + + png_crc_read(png_ptr, buf, 4); + uint_x = png_get_uint_32(buf); + + png_crc_read(png_ptr, buf, 4); + uint_y = png_get_uint_32(buf); + + if (uint_x + uint_y > 100000L) + { + png_warning(png_ptr, "Invalid cHRM blue point"); + png_crc_finish(png_ptr, 0); + return; + } + int_x_blue = (png_fixed_point)uint_x; + int_y_blue = (png_fixed_point)uint_y; + +#ifdef PNG_FLOATING_POINT_SUPPORTED + white_x = (float)int_x_white / (float)100000.0; + white_y = (float)int_y_white / (float)100000.0; + red_x = (float)int_x_red / (float)100000.0; + red_y = (float)int_y_red / (float)100000.0; + green_x = (float)int_x_green / (float)100000.0; + green_y = (float)int_y_green / (float)100000.0; + blue_x = (float)int_x_blue / (float)100000.0; + blue_y = (float)int_y_blue / (float)100000.0; +#endif + +#if defined(PNG_READ_sRGB_SUPPORTED) + if ((info_ptr != NULL) && (info_ptr->valid & PNG_INFO_sRGB)) + { + if (PNG_OUT_OF_RANGE(int_x_white, 31270, 1000) || + PNG_OUT_OF_RANGE(int_y_white, 32900, 1000) || + PNG_OUT_OF_RANGE(int_x_red, 64000L, 1000) || + PNG_OUT_OF_RANGE(int_y_red, 33000, 1000) || + PNG_OUT_OF_RANGE(int_x_green, 30000, 1000) || + PNG_OUT_OF_RANGE(int_y_green, 60000L, 1000) || + PNG_OUT_OF_RANGE(int_x_blue, 15000, 1000) || + PNG_OUT_OF_RANGE(int_y_blue, 6000, 1000)) + { + png_warning(png_ptr, + "Ignoring incorrect cHRM value when sRGB is also present"); +#ifndef PNG_NO_CONSOLE_IO +#ifdef PNG_FLOATING_POINT_SUPPORTED + fprintf(stderr,"wx=%f, wy=%f, rx=%f, ry=%f\n", + white_x, white_y, red_x, red_y); + fprintf(stderr,"gx=%f, gy=%f, bx=%f, by=%f\n", + green_x, green_y, blue_x, blue_y); +#else + fprintf(stderr,"wx=%ld, wy=%ld, rx=%ld, ry=%ld\n", + int_x_white, int_y_white, int_x_red, int_y_red); + fprintf(stderr,"gx=%ld, gy=%ld, bx=%ld, by=%ld\n", + int_x_green, int_y_green, int_x_blue, int_y_blue); +#endif +#endif /* PNG_NO_CONSOLE_IO */ + } + png_crc_finish(png_ptr, 0); + return; + } +#endif /* PNG_READ_sRGB_SUPPORTED */ + +#ifdef PNG_FLOATING_POINT_SUPPORTED + png_set_cHRM(png_ptr, info_ptr, + white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y); +#endif +#ifdef PNG_FIXED_POINT_SUPPORTED + png_set_cHRM_fixed(png_ptr, info_ptr, + int_x_white, int_y_white, int_x_red, int_y_red, int_x_green, + int_y_green, int_x_blue, int_y_blue); +#endif + if (png_crc_finish(png_ptr, 0)) + return; +} +#endif + +#if defined(PNG_READ_sRGB_SUPPORTED) +void /* PRIVATE */ +png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + int intent; + png_byte buf[1]; + + png_debug(1, "in png_handle_sRGB\n"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before sRGB"); + else if (png_ptr->mode & PNG_HAVE_IDAT) + { + png_warning(png_ptr, "Invalid sRGB after IDAT"); + png_crc_finish(png_ptr, length); + return; + } + else if (png_ptr->mode & PNG_HAVE_PLTE) + /* Should be an error, but we can cope with it */ + png_warning(png_ptr, "Out of place sRGB chunk"); + + if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB)) + { + png_warning(png_ptr, "Duplicate sRGB chunk"); + png_crc_finish(png_ptr, length); + return; + } + + if (length != 1) + { + png_warning(png_ptr, "Incorrect sRGB chunk length"); + png_crc_finish(png_ptr, length); + return; + } + + png_crc_read(png_ptr, buf, 1); + if (png_crc_finish(png_ptr, 0)) + return; + + intent = buf[0]; + /* check for bad intent */ + if (intent >= PNG_sRGB_INTENT_LAST) + { + png_warning(png_ptr, "Unknown sRGB intent"); + return; + } + +#if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED) + if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)) + { + png_fixed_point igamma; +#ifdef PNG_FIXED_POINT_SUPPORTED + igamma=info_ptr->int_gamma; +#else +# ifdef PNG_FLOATING_POINT_SUPPORTED + igamma=(png_fixed_point)(info_ptr->gamma * 100000.); +# endif +#endif + if (PNG_OUT_OF_RANGE(igamma, 45500L, 500)) + { + png_warning(png_ptr, + "Ignoring incorrect gAMA value when sRGB is also present"); +#ifndef PNG_NO_CONSOLE_IO +# ifdef PNG_FIXED_POINT_SUPPORTED + fprintf(stderr,"incorrect gamma=(%d/100000)\n",(int)png_ptr->int_gamma); +# else +# ifdef PNG_FLOATING_POINT_SUPPORTED + fprintf(stderr,"incorrect gamma=%f\n",png_ptr->gamma); +# endif +# endif +#endif + } + } +#endif /* PNG_READ_gAMA_SUPPORTED */ + +#ifdef PNG_READ_cHRM_SUPPORTED +#ifdef PNG_FIXED_POINT_SUPPORTED + if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)) + if (PNG_OUT_OF_RANGE(info_ptr->int_x_white, 31270, 1000) || + PNG_OUT_OF_RANGE(info_ptr->int_y_white, 32900, 1000) || + PNG_OUT_OF_RANGE(info_ptr->int_x_red, 64000L, 1000) || + PNG_OUT_OF_RANGE(info_ptr->int_y_red, 33000, 1000) || + PNG_OUT_OF_RANGE(info_ptr->int_x_green, 30000, 1000) || + PNG_OUT_OF_RANGE(info_ptr->int_y_green, 60000L, 1000) || + PNG_OUT_OF_RANGE(info_ptr->int_x_blue, 15000, 1000) || + PNG_OUT_OF_RANGE(info_ptr->int_y_blue, 6000, 1000)) + { + png_warning(png_ptr, + "Ignoring incorrect cHRM value when sRGB is also present"); + } +#endif /* PNG_FIXED_POINT_SUPPORTED */ +#endif /* PNG_READ_cHRM_SUPPORTED */ + + png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent); +} +#endif /* PNG_READ_sRGB_SUPPORTED */ + +#if defined(PNG_READ_iCCP_SUPPORTED) +void /* PRIVATE */ +png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +/* Note: this does not properly handle chunks that are > 64K under DOS */ +{ + png_charp chunkdata; + png_byte compression_type; + png_bytep pC; + png_charp profile; + png_uint_32 skip = 0; + png_uint_32 profile_size, profile_length; + png_size_t slength, prefix_length, data_length; + + png_debug(1, "in png_handle_iCCP\n"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before iCCP"); + else if (png_ptr->mode & PNG_HAVE_IDAT) + { + png_warning(png_ptr, "Invalid iCCP after IDAT"); + png_crc_finish(png_ptr, length); + return; + } + else if (png_ptr->mode & PNG_HAVE_PLTE) + /* Should be an error, but we can cope with it */ + png_warning(png_ptr, "Out of place iCCP chunk"); + + if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP)) + { + png_warning(png_ptr, "Duplicate iCCP chunk"); + png_crc_finish(png_ptr, length); + return; + } + +#ifdef PNG_MAX_MALLOC_64K + if (length > (png_uint_32)65535L) + { + png_warning(png_ptr, "iCCP chunk too large to fit in memory"); + skip = length - (png_uint_32)65535L; + length = (png_uint_32)65535L; + } +#endif + + chunkdata = (png_charp)png_malloc(png_ptr, length + 1); + slength = (png_size_t)length; + png_crc_read(png_ptr, (png_bytep)chunkdata, slength); + + if (png_crc_finish(png_ptr, skip)) + { + png_free(png_ptr, chunkdata); + return; + } + + chunkdata[slength] = 0x00; + + for (profile = chunkdata; *profile; profile++) + /* empty loop to find end of name */ ; + + ++profile; + + /* there should be at least one zero (the compression type byte) + following the separator, and we should be on it */ + if ( profile >= chunkdata + slength) + { + png_free(png_ptr, chunkdata); + png_warning(png_ptr, "Malformed iCCP chunk"); + return; + } + + /* compression_type should always be zero */ + compression_type = *profile++; + if (compression_type) + { + png_warning(png_ptr, "Ignoring nonzero compression type in iCCP chunk"); + compression_type=0x00; /* Reset it to zero (libpng-1.0.6 through 1.0.8 + wrote nonzero) */ + } + + prefix_length = profile - chunkdata; + chunkdata = png_decompress_chunk(png_ptr, compression_type, chunkdata, + slength, prefix_length, &data_length); + + profile_length = data_length - prefix_length; + + if ( prefix_length > data_length || profile_length < 4) + { + png_free(png_ptr, chunkdata); + png_warning(png_ptr, "Profile size field missing from iCCP chunk"); + return; + } + + /* Check the profile_size recorded in the first 32 bits of the ICC profile */ + pC = (png_bytep)(chunkdata+prefix_length); + profile_size = ((*(pC ))<<24) | + ((*(pC+1))<<16) | + ((*(pC+2))<< 8) | + ((*(pC+3)) ); + + if(profile_size < profile_length) + profile_length = profile_size; + + if(profile_size > profile_length) + { + png_free(png_ptr, chunkdata); + png_warning(png_ptr, "Ignoring truncated iCCP profile."); + return; + } + + png_set_iCCP(png_ptr, info_ptr, chunkdata, compression_type, + chunkdata + prefix_length, profile_length); + png_free(png_ptr, chunkdata); +} +#endif /* PNG_READ_iCCP_SUPPORTED */ + +#if defined(PNG_READ_sPLT_SUPPORTED) +void /* PRIVATE */ +png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +/* Note: this does not properly handle chunks that are > 64K under DOS */ +{ + png_bytep chunkdata; + png_bytep entry_start; + png_sPLT_t new_palette; +#ifdef PNG_NO_POINTER_INDEXING + png_sPLT_entryp pp; +#endif + int data_length, entry_size, i; + png_uint_32 skip = 0; + png_size_t slength; + + png_debug(1, "in png_handle_sPLT\n"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before sPLT"); + else if (png_ptr->mode & PNG_HAVE_IDAT) + { + png_warning(png_ptr, "Invalid sPLT after IDAT"); + png_crc_finish(png_ptr, length); + return; + } + +#ifdef PNG_MAX_MALLOC_64K + if (length > (png_uint_32)65535L) + { + png_warning(png_ptr, "sPLT chunk too large to fit in memory"); + skip = length - (png_uint_32)65535L; + length = (png_uint_32)65535L; + } +#endif + + chunkdata = (png_bytep)png_malloc(png_ptr, length + 1); + slength = (png_size_t)length; + png_crc_read(png_ptr, (png_bytep)chunkdata, slength); + + if (png_crc_finish(png_ptr, skip)) + { + png_free(png_ptr, chunkdata); + return; + } + + chunkdata[slength] = 0x00; + + for (entry_start = chunkdata; *entry_start; entry_start++) + /* empty loop to find end of name */ ; + ++entry_start; + + /* a sample depth should follow the separator, and we should be on it */ + if (entry_start > chunkdata + slength) + { + png_free(png_ptr, chunkdata); + png_warning(png_ptr, "malformed sPLT chunk"); + return; + } + + new_palette.depth = *entry_start++; + entry_size = (new_palette.depth == 8 ? 6 : 10); + data_length = (slength - (entry_start - chunkdata)); + + /* integrity-check the data length */ + if (data_length % entry_size) + { + png_free(png_ptr, chunkdata); + png_warning(png_ptr, "sPLT chunk has bad length"); + return; + } + + new_palette.nentries = (png_int_32) ( data_length / entry_size); + if ((png_uint_32) new_palette.nentries > (png_uint_32) (PNG_SIZE_MAX / + png_sizeof(png_sPLT_entry))) + { + png_warning(png_ptr, "sPLT chunk too long"); + return; + } + new_palette.entries = (png_sPLT_entryp)png_malloc_warn( + png_ptr, new_palette.nentries * png_sizeof(png_sPLT_entry)); + if (new_palette.entries == NULL) + { + png_warning(png_ptr, "sPLT chunk requires too much memory"); + return; + } + +#ifndef PNG_NO_POINTER_INDEXING + for (i = 0; i < new_palette.nentries; i++) + { + png_sPLT_entryp pp = new_palette.entries + i; + + if (new_palette.depth == 8) + { + pp->red = *entry_start++; + pp->green = *entry_start++; + pp->blue = *entry_start++; + pp->alpha = *entry_start++; + } + else + { + pp->red = png_get_uint_16(entry_start); entry_start += 2; + pp->green = png_get_uint_16(entry_start); entry_start += 2; + pp->blue = png_get_uint_16(entry_start); entry_start += 2; + pp->alpha = png_get_uint_16(entry_start); entry_start += 2; + } + pp->frequency = png_get_uint_16(entry_start); entry_start += 2; + } +#else + pp = new_palette.entries; + for (i = 0; i < new_palette.nentries; i++) + { + + if (new_palette.depth == 8) + { + pp[i].red = *entry_start++; + pp[i].green = *entry_start++; + pp[i].blue = *entry_start++; + pp[i].alpha = *entry_start++; + } + else + { + pp[i].red = png_get_uint_16(entry_start); entry_start += 2; + pp[i].green = png_get_uint_16(entry_start); entry_start += 2; + pp[i].blue = png_get_uint_16(entry_start); entry_start += 2; + pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2; + } + pp->frequency = png_get_uint_16(entry_start); entry_start += 2; + } +#endif + + /* discard all chunk data except the name and stash that */ + new_palette.name = (png_charp)chunkdata; + + png_set_sPLT(png_ptr, info_ptr, &new_palette, 1); + + png_free(png_ptr, chunkdata); + png_free(png_ptr, new_palette.entries); +} +#endif /* PNG_READ_sPLT_SUPPORTED */ + +#if defined(PNG_READ_tRNS_SUPPORTED) +void /* PRIVATE */ +png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + png_byte readbuf[PNG_MAX_PALETTE_LENGTH]; + + png_debug(1, "in png_handle_tRNS\n"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before tRNS"); + else if (png_ptr->mode & PNG_HAVE_IDAT) + { + png_warning(png_ptr, "Invalid tRNS after IDAT"); + png_crc_finish(png_ptr, length); + return; + } + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS)) + { + png_warning(png_ptr, "Duplicate tRNS chunk"); + png_crc_finish(png_ptr, length); + return; + } + + if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) + { + png_byte buf[2]; + + if (length != 2) + { + png_warning(png_ptr, "Incorrect tRNS chunk length"); + png_crc_finish(png_ptr, length); + return; + } + + png_crc_read(png_ptr, buf, 2); + png_ptr->num_trans = 1; + png_ptr->trans_values.gray = png_get_uint_16(buf); + } + else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) + { + png_byte buf[6]; + + if (length != 6) + { + png_warning(png_ptr, "Incorrect tRNS chunk length"); + png_crc_finish(png_ptr, length); + return; + } + png_crc_read(png_ptr, buf, (png_size_t)length); + png_ptr->num_trans = 1; + png_ptr->trans_values.red = png_get_uint_16(buf); + png_ptr->trans_values.green = png_get_uint_16(buf + 2); + png_ptr->trans_values.blue = png_get_uint_16(buf + 4); + } + else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { + if (!(png_ptr->mode & PNG_HAVE_PLTE)) + { + /* Should be an error, but we can cope with it. */ + png_warning(png_ptr, "Missing PLTE before tRNS"); + } + if (length > (png_uint_32)png_ptr->num_palette || + length > PNG_MAX_PALETTE_LENGTH) + { + png_warning(png_ptr, "Incorrect tRNS chunk length"); + png_crc_finish(png_ptr, length); + return; + } + if (length == 0) + { + png_warning(png_ptr, "Zero length tRNS chunk"); + png_crc_finish(png_ptr, length); + return; + } + png_crc_read(png_ptr, readbuf, (png_size_t)length); + png_ptr->num_trans = (png_uint_16)length; + } + else + { + png_warning(png_ptr, "tRNS chunk not allowed with alpha channel"); + png_crc_finish(png_ptr, length); + return; + } + + if (png_crc_finish(png_ptr, 0)) + return; + + png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans, + &(png_ptr->trans_values)); +} +#endif + +#if defined(PNG_READ_bKGD_SUPPORTED) +void /* PRIVATE */ +png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + png_size_t truelen; + png_byte buf[6]; + + png_debug(1, "in png_handle_bKGD\n"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before bKGD"); + else if (png_ptr->mode & PNG_HAVE_IDAT) + { + png_warning(png_ptr, "Invalid bKGD after IDAT"); + png_crc_finish(png_ptr, length); + return; + } + else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && + !(png_ptr->mode & PNG_HAVE_PLTE)) + { + png_warning(png_ptr, "Missing PLTE before bKGD"); + png_crc_finish(png_ptr, length); + return; + } + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD)) + { + png_warning(png_ptr, "Duplicate bKGD chunk"); + png_crc_finish(png_ptr, length); + return; + } + + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + truelen = 1; + else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR) + truelen = 6; + else + truelen = 2; + + if (length != truelen) + { + png_warning(png_ptr, "Incorrect bKGD chunk length"); + png_crc_finish(png_ptr, length); + return; + } + + png_crc_read(png_ptr, buf, truelen); + if (png_crc_finish(png_ptr, 0)) + return; + + /* We convert the index value into RGB components so that we can allow + * arbitrary RGB values for background when we have transparency, and + * so it is easy to determine the RGB values of the background color + * from the info_ptr struct. */ + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { + png_ptr->background.index = buf[0]; + if(info_ptr->num_palette) + { + if(buf[0] > info_ptr->num_palette) + { + png_warning(png_ptr, "Incorrect bKGD chunk index value"); + return; + } + png_ptr->background.red = + (png_uint_16)png_ptr->palette[buf[0]].red; + png_ptr->background.green = + (png_uint_16)png_ptr->palette[buf[0]].green; + png_ptr->background.blue = + (png_uint_16)png_ptr->palette[buf[0]].blue; + } + } + else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */ + { + png_ptr->background.red = + png_ptr->background.green = + png_ptr->background.blue = + png_ptr->background.gray = png_get_uint_16(buf); + } + else + { + png_ptr->background.red = png_get_uint_16(buf); + png_ptr->background.green = png_get_uint_16(buf + 2); + png_ptr->background.blue = png_get_uint_16(buf + 4); + } + + png_set_bKGD(png_ptr, info_ptr, &(png_ptr->background)); +} +#endif + +#if defined(PNG_READ_hIST_SUPPORTED) +void /* PRIVATE */ +png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + unsigned int num, i; + png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH]; + + png_debug(1, "in png_handle_hIST\n"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before hIST"); + else if (png_ptr->mode & PNG_HAVE_IDAT) + { + png_warning(png_ptr, "Invalid hIST after IDAT"); + png_crc_finish(png_ptr, length); + return; + } + else if (!(png_ptr->mode & PNG_HAVE_PLTE)) + { + png_warning(png_ptr, "Missing PLTE before hIST"); + png_crc_finish(png_ptr, length); + return; + } + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST)) + { + png_warning(png_ptr, "Duplicate hIST chunk"); + png_crc_finish(png_ptr, length); + return; + } + + num = length / 2 ; + if (num != (unsigned int) png_ptr->num_palette || num > + (unsigned int) PNG_MAX_PALETTE_LENGTH) + { + png_warning(png_ptr, "Incorrect hIST chunk length"); + png_crc_finish(png_ptr, length); + return; + } + + for (i = 0; i < num; i++) + { + png_byte buf[2]; + + png_crc_read(png_ptr, buf, 2); + readbuf[i] = png_get_uint_16(buf); + } + + if (png_crc_finish(png_ptr, 0)) + return; + + png_set_hIST(png_ptr, info_ptr, readbuf); +} +#endif + +#if defined(PNG_READ_pHYs_SUPPORTED) +void /* PRIVATE */ +png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + png_byte buf[9]; + png_uint_32 res_x, res_y; + int unit_type; + + png_debug(1, "in png_handle_pHYs\n"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before pHYs"); + else if (png_ptr->mode & PNG_HAVE_IDAT) + { + png_warning(png_ptr, "Invalid pHYs after IDAT"); + png_crc_finish(png_ptr, length); + return; + } + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) + { + png_warning(png_ptr, "Duplicate pHYs chunk"); + png_crc_finish(png_ptr, length); + return; + } + + if (length != 9) + { + png_warning(png_ptr, "Incorrect pHYs chunk length"); + png_crc_finish(png_ptr, length); + return; + } + + png_crc_read(png_ptr, buf, 9); + if (png_crc_finish(png_ptr, 0)) + return; + + res_x = png_get_uint_32(buf); + res_y = png_get_uint_32(buf + 4); + unit_type = buf[8]; + png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type); +} +#endif + +#if defined(PNG_READ_oFFs_SUPPORTED) +void /* PRIVATE */ +png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + png_byte buf[9]; + png_int_32 offset_x, offset_y; + int unit_type; + + png_debug(1, "in png_handle_oFFs\n"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before oFFs"); + else if (png_ptr->mode & PNG_HAVE_IDAT) + { + png_warning(png_ptr, "Invalid oFFs after IDAT"); + png_crc_finish(png_ptr, length); + return; + } + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)) + { + png_warning(png_ptr, "Duplicate oFFs chunk"); + png_crc_finish(png_ptr, length); + return; + } + + if (length != 9) + { + png_warning(png_ptr, "Incorrect oFFs chunk length"); + png_crc_finish(png_ptr, length); + return; + } + + png_crc_read(png_ptr, buf, 9); + if (png_crc_finish(png_ptr, 0)) + return; + + offset_x = png_get_int_32(buf); + offset_y = png_get_int_32(buf + 4); + unit_type = buf[8]; + png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type); +} +#endif + +#if defined(PNG_READ_pCAL_SUPPORTED) +/* read the pCAL chunk (described in the PNG Extensions document) */ +void /* PRIVATE */ +png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + png_charp purpose; + png_int_32 X0, X1; + png_byte type, nparams; + png_charp buf, units, endptr; + png_charpp params; + png_size_t slength; + int i; + + png_debug(1, "in png_handle_pCAL\n"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before pCAL"); + else if (png_ptr->mode & PNG_HAVE_IDAT) + { + png_warning(png_ptr, "Invalid pCAL after IDAT"); + png_crc_finish(png_ptr, length); + return; + } + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL)) + { + png_warning(png_ptr, "Duplicate pCAL chunk"); + png_crc_finish(png_ptr, length); + return; + } + + png_debug1(2, "Allocating and reading pCAL chunk data (%lu bytes)\n", + length + 1); + purpose = (png_charp)png_malloc_warn(png_ptr, length + 1); + if (purpose == NULL) + { + png_warning(png_ptr, "No memory for pCAL purpose."); + return; + } + slength = (png_size_t)length; + png_crc_read(png_ptr, (png_bytep)purpose, slength); + + if (png_crc_finish(png_ptr, 0)) + { + png_free(png_ptr, purpose); + return; + } + + purpose[slength] = 0x00; /* null terminate the last string */ + + png_debug(3, "Finding end of pCAL purpose string\n"); + for (buf = purpose; *buf; buf++) + /* empty loop */ ; + + endptr = purpose + slength; + + /* We need to have at least 12 bytes after the purpose string + in order to get the parameter information. */ + if (endptr <= buf + 12) + { + png_warning(png_ptr, "Invalid pCAL data"); + png_free(png_ptr, purpose); + return; + } + + png_debug(3, "Reading pCAL X0, X1, type, nparams, and units\n"); + X0 = png_get_int_32((png_bytep)buf+1); + X1 = png_get_int_32((png_bytep)buf+5); + type = buf[9]; + nparams = buf[10]; + units = buf + 11; + + png_debug(3, "Checking pCAL equation type and number of parameters\n"); + /* Check that we have the right number of parameters for known + equation types. */ + if ((type == PNG_EQUATION_LINEAR && nparams != 2) || + (type == PNG_EQUATION_BASE_E && nparams != 3) || + (type == PNG_EQUATION_ARBITRARY && nparams != 3) || + (type == PNG_EQUATION_HYPERBOLIC && nparams != 4)) + { + png_warning(png_ptr, "Invalid pCAL parameters for equation type"); + png_free(png_ptr, purpose); + return; + } + else if (type >= PNG_EQUATION_LAST) + { + png_warning(png_ptr, "Unrecognized equation type for pCAL chunk"); + } + + for (buf = units; *buf; buf++) + /* Empty loop to move past the units string. */ ; + + png_debug(3, "Allocating pCAL parameters array\n"); + params = (png_charpp)png_malloc_warn(png_ptr, (png_uint_32)(nparams + *png_sizeof(png_charp))) ; + if (params == NULL) + { + png_free(png_ptr, purpose); + png_warning(png_ptr, "No memory for pCAL params."); + return; + } + + /* Get pointers to the start of each parameter string. */ + for (i = 0; i < (int)nparams; i++) + { + buf++; /* Skip the null string terminator from previous parameter. */ + + png_debug1(3, "Reading pCAL parameter %d\n", i); + for (params[i] = buf; *buf != 0x00 && buf <= endptr; buf++) + /* Empty loop to move past each parameter string */ ; + + /* Make sure we haven't run out of data yet */ + if (buf > endptr) + { + png_warning(png_ptr, "Invalid pCAL data"); + png_free(png_ptr, purpose); + png_free(png_ptr, params); + return; + } + } + + png_set_pCAL(png_ptr, info_ptr, purpose, X0, X1, type, nparams, + units, params); + + png_free(png_ptr, purpose); + png_free(png_ptr, params); +} +#endif + +#if defined(PNG_READ_sCAL_SUPPORTED) +/* read the sCAL chunk */ +void /* PRIVATE */ +png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + png_charp buffer, ep; +#ifdef PNG_FLOATING_POINT_SUPPORTED + double width, height; + png_charp vp; +#else +#ifdef PNG_FIXED_POINT_SUPPORTED + png_charp swidth, sheight; +#endif +#endif + png_size_t slength; + + png_debug(1, "in png_handle_sCAL\n"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before sCAL"); + else if (png_ptr->mode & PNG_HAVE_IDAT) + { + png_warning(png_ptr, "Invalid sCAL after IDAT"); + png_crc_finish(png_ptr, length); + return; + } + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL)) + { + png_warning(png_ptr, "Duplicate sCAL chunk"); + png_crc_finish(png_ptr, length); + return; + } + + png_debug1(2, "Allocating and reading sCAL chunk data (%lu bytes)\n", + length + 1); + buffer = (png_charp)png_malloc_warn(png_ptr, length + 1); + if (buffer == NULL) + { + png_warning(png_ptr, "Out of memory while processing sCAL chunk"); + return; + } + slength = (png_size_t)length; + png_crc_read(png_ptr, (png_bytep)buffer, slength); + + if (png_crc_finish(png_ptr, 0)) + { + png_free(png_ptr, buffer); + return; + } + + buffer[slength] = 0x00; /* null terminate the last string */ + + ep = buffer + 1; /* skip unit byte */ + +#ifdef PNG_FLOATING_POINT_SUPPORTED + width = strtod(ep, &vp); + if (*vp) + { + png_warning(png_ptr, "malformed width string in sCAL chunk"); + return; + } +#else +#ifdef PNG_FIXED_POINT_SUPPORTED + swidth = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1); + if (swidth == NULL) + { + png_warning(png_ptr, "Out of memory while processing sCAL chunk width"); + return; + } + png_memcpy(swidth, ep, (png_size_t)png_strlen(ep)); +#endif +#endif + + for (ep = buffer; *ep; ep++) + /* empty loop */ ; + ep++; + +#ifdef PNG_FLOATING_POINT_SUPPORTED + height = strtod(ep, &vp); + if (*vp) + { + png_warning(png_ptr, "malformed height string in sCAL chunk"); + return; + } +#else +#ifdef PNG_FIXED_POINT_SUPPORTED + sheight = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1); + if (swidth == NULL) + { + png_warning(png_ptr, "Out of memory while processing sCAL chunk height"); + return; + } + png_memcpy(sheight, ep, (png_size_t)png_strlen(ep)); +#endif +#endif + + if (buffer + slength < ep +#ifdef PNG_FLOATING_POINT_SUPPORTED + || width <= 0. || height <= 0. +#endif + ) + { + png_warning(png_ptr, "Invalid sCAL data"); + png_free(png_ptr, buffer); +#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED) + png_free(png_ptr, swidth); + png_free(png_ptr, sheight); +#endif + return; + } + + +#ifdef PNG_FLOATING_POINT_SUPPORTED + png_set_sCAL(png_ptr, info_ptr, buffer[0], width, height); +#else +#ifdef PNG_FIXED_POINT_SUPPORTED + png_set_sCAL_s(png_ptr, info_ptr, buffer[0], swidth, sheight); +#endif +#endif + + png_free(png_ptr, buffer); +#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED) + png_free(png_ptr, swidth); + png_free(png_ptr, sheight); +#endif +} +#endif + +#if defined(PNG_READ_tIME_SUPPORTED) +void /* PRIVATE */ +png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + png_byte buf[7]; + png_time mod_time; + + png_debug(1, "in png_handle_tIME\n"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Out of place tIME chunk"); + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME)) + { + png_warning(png_ptr, "Duplicate tIME chunk"); + png_crc_finish(png_ptr, length); + return; + } + + if (png_ptr->mode & PNG_HAVE_IDAT) + png_ptr->mode |= PNG_AFTER_IDAT; + + if (length != 7) + { + png_warning(png_ptr, "Incorrect tIME chunk length"); + png_crc_finish(png_ptr, length); + return; + } + + png_crc_read(png_ptr, buf, 7); + if (png_crc_finish(png_ptr, 0)) + return; + + mod_time.second = buf[6]; + mod_time.minute = buf[5]; + mod_time.hour = buf[4]; + mod_time.day = buf[3]; + mod_time.month = buf[2]; + mod_time.year = png_get_uint_16(buf); + + png_set_tIME(png_ptr, info_ptr, &mod_time); +} +#endif + +#if defined(PNG_READ_tEXt_SUPPORTED) +/* Note: this does not properly handle chunks that are > 64K under DOS */ +void /* PRIVATE */ +png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + png_textp text_ptr; + png_charp key; + png_charp text; + png_uint_32 skip = 0; + png_size_t slength; + int ret; + + png_debug(1, "in png_handle_tEXt\n"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before tEXt"); + + if (png_ptr->mode & PNG_HAVE_IDAT) + png_ptr->mode |= PNG_AFTER_IDAT; + +#ifdef PNG_MAX_MALLOC_64K + if (length > (png_uint_32)65535L) + { + png_warning(png_ptr, "tEXt chunk too large to fit in memory"); + skip = length - (png_uint_32)65535L; + length = (png_uint_32)65535L; + } +#endif + + key = (png_charp)png_malloc_warn(png_ptr, length + 1); + if (key == NULL) + { + png_warning(png_ptr, "No memory to process text chunk."); + return; + } + slength = (png_size_t)length; + png_crc_read(png_ptr, (png_bytep)key, slength); + + if (png_crc_finish(png_ptr, skip)) + { + png_free(png_ptr, key); + return; + } + + key[slength] = 0x00; + + for (text = key; *text; text++) + /* empty loop to find end of key */ ; + + if (text != key + slength) + text++; + + text_ptr = (png_textp)png_malloc_warn(png_ptr, + (png_uint_32)png_sizeof(png_text)); + if (text_ptr == NULL) + { + png_warning(png_ptr, "Not enough memory to process text chunk."); + png_free(png_ptr, key); + return; + } + text_ptr->compression = PNG_TEXT_COMPRESSION_NONE; + text_ptr->key = key; +#ifdef PNG_iTXt_SUPPORTED + text_ptr->lang = NULL; + text_ptr->lang_key = NULL; + text_ptr->itxt_length = 0; +#endif + text_ptr->text = text; + text_ptr->text_length = png_strlen(text); + + ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1); + + png_free(png_ptr, key); + png_free(png_ptr, text_ptr); + if (ret) + png_warning(png_ptr, "Insufficient memory to process text chunk."); +} +#endif + +#if defined(PNG_READ_zTXt_SUPPORTED) +/* note: this does not correctly handle chunks that are > 64K under DOS */ +void /* PRIVATE */ +png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + png_textp text_ptr; + png_charp chunkdata; + png_charp text; + int comp_type; + int ret; + png_size_t slength, prefix_len, data_len; + + png_debug(1, "in png_handle_zTXt\n"); + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before zTXt"); + + if (png_ptr->mode & PNG_HAVE_IDAT) + png_ptr->mode |= PNG_AFTER_IDAT; + +#ifdef PNG_MAX_MALLOC_64K + /* We will no doubt have problems with chunks even half this size, but + there is no hard and fast rule to tell us where to stop. */ + if (length > (png_uint_32)65535L) + { + png_warning(png_ptr,"zTXt chunk too large to fit in memory"); + png_crc_finish(png_ptr, length); + return; + } +#endif + + chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); + if (chunkdata == NULL) + { + png_warning(png_ptr,"Out of memory processing zTXt chunk."); + return; + } + slength = (png_size_t)length; + png_crc_read(png_ptr, (png_bytep)chunkdata, slength); + if (png_crc_finish(png_ptr, 0)) + { + png_free(png_ptr, chunkdata); + return; + } + + chunkdata[slength] = 0x00; + + for (text = chunkdata; *text; text++) + /* empty loop */ ; + + /* zTXt must have some text after the chunkdataword */ + if (text == chunkdata + slength) + { + comp_type = PNG_TEXT_COMPRESSION_NONE; + png_warning(png_ptr, "Zero length zTXt chunk"); + } + else + { + comp_type = *(++text); + if (comp_type != PNG_TEXT_COMPRESSION_zTXt) + { + png_warning(png_ptr, "Unknown compression type in zTXt chunk"); + comp_type = PNG_TEXT_COMPRESSION_zTXt; + } + text++; /* skip the compression_method byte */ + } + prefix_len = text - chunkdata; + + chunkdata = (png_charp)png_decompress_chunk(png_ptr, comp_type, chunkdata, + (png_size_t)length, prefix_len, &data_len); + + text_ptr = (png_textp)png_malloc_warn(png_ptr, + (png_uint_32)png_sizeof(png_text)); + if (text_ptr == NULL) + { + png_warning(png_ptr,"Not enough memory to process zTXt chunk."); + png_free(png_ptr, chunkdata); + return; + } + text_ptr->compression = comp_type; + text_ptr->key = chunkdata; +#ifdef PNG_iTXt_SUPPORTED + text_ptr->lang = NULL; + text_ptr->lang_key = NULL; + text_ptr->itxt_length = 0; +#endif + text_ptr->text = chunkdata + prefix_len; + text_ptr->text_length = data_len; + + ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1); + + png_free(png_ptr, text_ptr); + png_free(png_ptr, chunkdata); + if (ret) + png_error(png_ptr, "Insufficient memory to store zTXt chunk."); +} +#endif + +#if defined(PNG_READ_iTXt_SUPPORTED) +/* note: this does not correctly handle chunks that are > 64K under DOS */ +void /* PRIVATE */ +png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + png_textp text_ptr; + png_charp chunkdata; + png_charp key, lang, text, lang_key; + int comp_flag; + int comp_type = 0; + int ret; + png_size_t slength, prefix_len, data_len; + + png_debug(1, "in png_handle_iTXt\n"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before iTXt"); + + if (png_ptr->mode & PNG_HAVE_IDAT) + png_ptr->mode |= PNG_AFTER_IDAT; + +#ifdef PNG_MAX_MALLOC_64K + /* We will no doubt have problems with chunks even half this size, but + there is no hard and fast rule to tell us where to stop. */ + if (length > (png_uint_32)65535L) + { + png_warning(png_ptr,"iTXt chunk too large to fit in memory"); + png_crc_finish(png_ptr, length); + return; + } +#endif + + chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); + if (chunkdata == NULL) + { + png_warning(png_ptr, "No memory to process iTXt chunk."); + return; + } + slength = (png_size_t)length; + png_crc_read(png_ptr, (png_bytep)chunkdata, slength); + if (png_crc_finish(png_ptr, 0)) + { + png_free(png_ptr, chunkdata); + return; + } + + chunkdata[slength] = 0x00; + + for (lang = chunkdata; *lang; lang++) + /* empty loop */ ; + lang++; /* skip NUL separator */ + + /* iTXt must have a language tag (possibly empty), two compression bytes, + translated keyword (possibly empty), and possibly some text after the + keyword */ + + if (lang >= chunkdata + slength) + { + comp_flag = PNG_TEXT_COMPRESSION_NONE; + png_warning(png_ptr, "Zero length iTXt chunk"); + } + else + { + comp_flag = *lang++; + comp_type = *lang++; + } + + for (lang_key = lang; *lang_key; lang_key++) + /* empty loop */ ; + lang_key++; /* skip NUL separator */ + + for (text = lang_key; *text; text++) + /* empty loop */ ; + text++; /* skip NUL separator */ + + prefix_len = text - chunkdata; + + key=chunkdata; + if (comp_flag) + chunkdata = png_decompress_chunk(png_ptr, comp_type, chunkdata, + (size_t)length, prefix_len, &data_len); + else + data_len=png_strlen(chunkdata + prefix_len); + text_ptr = (png_textp)png_malloc_warn(png_ptr, + (png_uint_32)png_sizeof(png_text)); + if (text_ptr == NULL) + { + png_warning(png_ptr,"Not enough memory to process iTXt chunk."); + png_free(png_ptr, chunkdata); + return; + } + text_ptr->compression = (int)comp_flag + 1; + text_ptr->lang_key = chunkdata+(lang_key-key); + text_ptr->lang = chunkdata+(lang-key); + text_ptr->itxt_length = data_len; + text_ptr->text_length = 0; + text_ptr->key = chunkdata; + text_ptr->text = chunkdata + prefix_len; + + ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1); + + png_free(png_ptr, text_ptr); + png_free(png_ptr, chunkdata); + if (ret) + png_error(png_ptr, "Insufficient memory to store iTXt chunk."); +} +#endif + +/* This function is called when we haven't found a handler for a + chunk. If there isn't a problem with the chunk itself (ie bad + chunk name, CRC, or a critical chunk), the chunk is silently ignored + -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which + case it will be saved away to be written out later. */ +void /* PRIVATE */ +png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + png_uint_32 skip = 0; + + png_debug(1, "in png_handle_unknown\n"); + + if (png_ptr->mode & PNG_HAVE_IDAT) + { +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_IDAT; +#endif + if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) /* not an IDAT */ + png_ptr->mode |= PNG_AFTER_IDAT; + } + + png_check_chunk_name(png_ptr, png_ptr->chunk_name); + + if (!(png_ptr->chunk_name[0] & 0x20)) + { +#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) + if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != + PNG_HANDLE_CHUNK_ALWAYS +#if defined(PNG_READ_USER_CHUNKS_SUPPORTED) + && png_ptr->read_user_chunk_fn == NULL +#endif + ) +#endif + png_chunk_error(png_ptr, "unknown critical chunk"); + } + +#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) + if ((png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS) || + (png_ptr->read_user_chunk_fn != NULL)) + { + png_unknown_chunk chunk; + +#ifdef PNG_MAX_MALLOC_64K + if (length > (png_uint_32)65535L) + { + png_warning(png_ptr, "unknown chunk too large to fit in memory"); + skip = length - (png_uint_32)65535L; + length = (png_uint_32)65535L; + } +#endif + png_strcpy((png_charp)chunk.name, (png_charp)png_ptr->chunk_name); + chunk.data = (png_bytep)png_malloc(png_ptr, length); + chunk.size = (png_size_t)length; + png_crc_read(png_ptr, (png_bytep)chunk.data, length); +#if defined(PNG_READ_USER_CHUNKS_SUPPORTED) + if(png_ptr->read_user_chunk_fn != NULL) + { + /* callback to user unknown chunk handler */ + if ((*(png_ptr->read_user_chunk_fn)) (png_ptr, &chunk) <= 0) + { + if (!(png_ptr->chunk_name[0] & 0x20)) + if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != + PNG_HANDLE_CHUNK_ALWAYS) + { + png_free(png_ptr, chunk.data); + png_chunk_error(png_ptr, "unknown critical chunk"); + } + png_set_unknown_chunks(png_ptr, info_ptr, &chunk, 1); + } + } + else +#endif + png_set_unknown_chunks(png_ptr, info_ptr, &chunk, 1); + png_free(png_ptr, chunk.data); + } + else +#endif + skip = length; + + png_crc_finish(png_ptr, skip); + +#if !defined(PNG_READ_USER_CHUNKS_SUPPORTED) + if (&info_ptr == NULL) /* quiet compiler warnings about unused info_ptr */ + return; +#endif +} + +/* This function is called to verify that a chunk name is valid. + This function can't have the "critical chunk check" incorporated + into it, since in the future we will need to be able to call user + functions to handle unknown critical chunks after we check that + the chunk name itself is valid. */ + +#define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97)) + +void /* PRIVATE */ +png_check_chunk_name(png_structp png_ptr, png_bytep chunk_name) +{ + png_debug(1, "in png_check_chunk_name\n"); + if (isnonalpha(chunk_name[0]) || isnonalpha(chunk_name[1]) || + isnonalpha(chunk_name[2]) || isnonalpha(chunk_name[3])) + { + png_chunk_error(png_ptr, "invalid chunk type"); + } +} + +/* Combines the row recently read in with the existing pixels in the + row. This routine takes care of alpha and transparency if requested. + This routine also handles the two methods of progressive display + of interlaced images, depending on the mask value. + The mask value describes which pixels are to be combined with + the row. The pattern always repeats every 8 pixels, so just 8 + bits are needed. A one indicates the pixel is to be combined, + a zero indicates the pixel is to be skipped. This is in addition + to any alpha or transparency value associated with the pixel. If + you want all pixels to be combined, pass 0xff (255) in mask. */ +#ifndef PNG_HAVE_ASSEMBLER_COMBINE_ROW +void /* PRIVATE */ +png_combine_row(png_structp png_ptr, png_bytep row, int mask) +{ + png_debug(1,"in png_combine_row\n"); + if (mask == 0xff) + { + png_memcpy(row, png_ptr->row_buf + 1, + PNG_ROWBYTES(png_ptr->row_info.pixel_depth, png_ptr->width)); + } + else + { + switch (png_ptr->row_info.pixel_depth) + { + case 1: + { + png_bytep sp = png_ptr->row_buf + 1; + png_bytep dp = row; + int s_inc, s_start, s_end; + int m = 0x80; + int shift; + png_uint_32 i; + png_uint_32 row_width = png_ptr->width; + +#if defined(PNG_READ_PACKSWAP_SUPPORTED) + if (png_ptr->transformations & PNG_PACKSWAP) + { + s_start = 0; + s_end = 7; + s_inc = 1; + } + else +#endif + { + s_start = 7; + s_end = 0; + s_inc = -1; + } + + shift = s_start; + + for (i = 0; i < row_width; i++) + { + if (m & mask) + { + int value; + + value = (*sp >> shift) & 0x01; + *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff); + *dp |= (png_byte)(value << shift); + } + + if (shift == s_end) + { + shift = s_start; + sp++; + dp++; + } + else + shift += s_inc; + + if (m == 1) + m = 0x80; + else + m >>= 1; + } + break; + } + case 2: + { + png_bytep sp = png_ptr->row_buf + 1; + png_bytep dp = row; + int s_start, s_end, s_inc; + int m = 0x80; + int shift; + png_uint_32 i; + png_uint_32 row_width = png_ptr->width; + int value; + +#if defined(PNG_READ_PACKSWAP_SUPPORTED) + if (png_ptr->transformations & PNG_PACKSWAP) + { + s_start = 0; + s_end = 6; + s_inc = 2; + } + else +#endif + { + s_start = 6; + s_end = 0; + s_inc = -2; + } + + shift = s_start; + + for (i = 0; i < row_width; i++) + { + if (m & mask) + { + value = (*sp >> shift) & 0x03; + *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); + *dp |= (png_byte)(value << shift); + } + + if (shift == s_end) + { + shift = s_start; + sp++; + dp++; + } + else + shift += s_inc; + if (m == 1) + m = 0x80; + else + m >>= 1; + } + break; + } + case 4: + { + png_bytep sp = png_ptr->row_buf + 1; + png_bytep dp = row; + int s_start, s_end, s_inc; + int m = 0x80; + int shift; + png_uint_32 i; + png_uint_32 row_width = png_ptr->width; + int value; + +#if defined(PNG_READ_PACKSWAP_SUPPORTED) + if (png_ptr->transformations & PNG_PACKSWAP) + { + s_start = 0; + s_end = 4; + s_inc = 4; + } + else +#endif + { + s_start = 4; + s_end = 0; + s_inc = -4; + } + shift = s_start; + + for (i = 0; i < row_width; i++) + { + if (m & mask) + { + value = (*sp >> shift) & 0xf; + *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); + *dp |= (png_byte)(value << shift); + } + + if (shift == s_end) + { + shift = s_start; + sp++; + dp++; + } + else + shift += s_inc; + if (m == 1) + m = 0x80; + else + m >>= 1; + } + break; + } + default: + { + png_bytep sp = png_ptr->row_buf + 1; + png_bytep dp = row; + png_size_t pixel_bytes = (png_ptr->row_info.pixel_depth >> 3); + png_uint_32 i; + png_uint_32 row_width = png_ptr->width; + png_byte m = 0x80; + + + for (i = 0; i < row_width; i++) + { + if (m & mask) + { + png_memcpy(dp, sp, pixel_bytes); + } + + sp += pixel_bytes; + dp += pixel_bytes; + + if (m == 1) + m = 0x80; + else + m >>= 1; + } + break; + } + } + } +} +#endif /* !PNG_HAVE_ASSEMBLER_COMBINE_ROW */ + +#ifdef PNG_READ_INTERLACING_SUPPORTED +#ifndef PNG_HAVE_ASSEMBLER_READ_INTERLACE /* else in pngvcrd.c, pnggccrd.c */ +/* OLD pre-1.0.9 interface: +void png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass, + png_uint_32 transformations) + */ +void /* PRIVATE */ +png_do_read_interlace(png_structp png_ptr) +{ + png_row_infop row_info = &(png_ptr->row_info); + png_bytep row = png_ptr->row_buf + 1; + int pass = png_ptr->pass; + png_uint_32 transformations = png_ptr->transformations; +#ifdef PNG_USE_LOCAL_ARRAYS + /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */ + /* offset to next interlace block */ + const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; +#endif + + png_debug(1,"in png_do_read_interlace (stock C version)\n"); + if (row != NULL && row_info != NULL) + { + png_uint_32 final_width; + + final_width = row_info->width * png_pass_inc[pass]; + + switch (row_info->pixel_depth) + { + case 1: + { + png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3); + png_bytep dp = row + (png_size_t)((final_width - 1) >> 3); + int sshift, dshift; + int s_start, s_end, s_inc; + int jstop = png_pass_inc[pass]; + png_byte v; + png_uint_32 i; + int j; + +#if defined(PNG_READ_PACKSWAP_SUPPORTED) + if (transformations & PNG_PACKSWAP) + { + sshift = (int)((row_info->width + 7) & 0x07); + dshift = (int)((final_width + 7) & 0x07); + s_start = 7; + s_end = 0; + s_inc = -1; + } + else +#endif + { + sshift = 7 - (int)((row_info->width + 7) & 0x07); + dshift = 7 - (int)((final_width + 7) & 0x07); + s_start = 0; + s_end = 7; + s_inc = 1; + } + + for (i = 0; i < row_info->width; i++) + { + v = (png_byte)((*sp >> sshift) & 0x01); + for (j = 0; j < jstop; j++) + { + *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff); + *dp |= (png_byte)(v << dshift); + if (dshift == s_end) + { + dshift = s_start; + dp--; + } + else + dshift += s_inc; + } + if (sshift == s_end) + { + sshift = s_start; + sp--; + } + else + sshift += s_inc; + } + break; + } + case 2: + { + png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2); + png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2); + int sshift, dshift; + int s_start, s_end, s_inc; + int jstop = png_pass_inc[pass]; + png_uint_32 i; + +#if defined(PNG_READ_PACKSWAP_SUPPORTED) + if (transformations & PNG_PACKSWAP) + { + sshift = (int)(((row_info->width + 3) & 0x03) << 1); + dshift = (int)(((final_width + 3) & 0x03) << 1); + s_start = 6; + s_end = 0; + s_inc = -2; + } + else +#endif + { + sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1); + dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1); + s_start = 0; + s_end = 6; + s_inc = 2; + } + + for (i = 0; i < row_info->width; i++) + { + png_byte v; + int j; + + v = (png_byte)((*sp >> sshift) & 0x03); + for (j = 0; j < jstop; j++) + { + *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff); + *dp |= (png_byte)(v << dshift); + if (dshift == s_end) + { + dshift = s_start; + dp--; + } + else + dshift += s_inc; + } + if (sshift == s_end) + { + sshift = s_start; + sp--; + } + else + sshift += s_inc; + } + break; + } + case 4: + { + png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1); + png_bytep dp = row + (png_size_t)((final_width - 1) >> 1); + int sshift, dshift; + int s_start, s_end, s_inc; + png_uint_32 i; + int jstop = png_pass_inc[pass]; + +#if defined(PNG_READ_PACKSWAP_SUPPORTED) + if (transformations & PNG_PACKSWAP) + { + sshift = (int)(((row_info->width + 1) & 0x01) << 2); + dshift = (int)(((final_width + 1) & 0x01) << 2); + s_start = 4; + s_end = 0; + s_inc = -4; + } + else +#endif + { + sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2); + dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2); + s_start = 0; + s_end = 4; + s_inc = 4; + } + + for (i = 0; i < row_info->width; i++) + { + png_byte v = (png_byte)((*sp >> sshift) & 0xf); + int j; + + for (j = 0; j < jstop; j++) + { + *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff); + *dp |= (png_byte)(v << dshift); + if (dshift == s_end) + { + dshift = s_start; + dp--; + } + else + dshift += s_inc; + } + if (sshift == s_end) + { + sshift = s_start; + sp--; + } + else + sshift += s_inc; + } + break; + } + default: + { + png_size_t pixel_bytes = (row_info->pixel_depth >> 3); + png_bytep sp = row + (png_size_t)(row_info->width - 1) * pixel_bytes; + png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes; + + int jstop = png_pass_inc[pass]; + png_uint_32 i; + + for (i = 0; i < row_info->width; i++) + { + png_byte v[8]; + int j; + + png_memcpy(v, sp, pixel_bytes); + for (j = 0; j < jstop; j++) + { + png_memcpy(dp, v, pixel_bytes); + dp -= pixel_bytes; + } + sp -= pixel_bytes; + } + break; + } + } + row_info->width = final_width; + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,final_width); + } +#if !defined(PNG_READ_PACKSWAP_SUPPORTED) + if (&transformations == NULL) /* silence compiler warning */ + return; +#endif +} +#endif /* !PNG_HAVE_ASSEMBLER_READ_INTERLACE */ +#endif /* PNG_READ_INTERLACING_SUPPORTED */ + +#ifndef PNG_HAVE_ASSEMBLER_READ_FILTER_ROW +void /* PRIVATE */ +png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row, + png_bytep prev_row, int filter) +{ + png_debug(1, "in png_read_filter_row\n"); + png_debug2(2,"row = %lu, filter = %d\n", png_ptr->row_number, filter); + switch (filter) + { + case PNG_FILTER_VALUE_NONE: + break; + case PNG_FILTER_VALUE_SUB: + { + png_uint_32 i; + png_uint_32 istop = row_info->rowbytes; + png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3; + png_bytep rp = row + bpp; + png_bytep lp = row; + + for (i = bpp; i < istop; i++) + { + *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff); + rp++; + } + break; + } + case PNG_FILTER_VALUE_UP: + { + png_uint_32 i; + png_uint_32 istop = row_info->rowbytes; + png_bytep rp = row; + png_bytep pp = prev_row; + + for (i = 0; i < istop; i++) + { + *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff); + rp++; + } + break; + } + case PNG_FILTER_VALUE_AVG: + { + png_uint_32 i; + png_bytep rp = row; + png_bytep pp = prev_row; + png_bytep lp = row; + png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3; + png_uint_32 istop = row_info->rowbytes - bpp; + + for (i = 0; i < bpp; i++) + { + *rp = (png_byte)(((int)(*rp) + + ((int)(*pp++) / 2 )) & 0xff); + rp++; + } + + for (i = 0; i < istop; i++) + { + *rp = (png_byte)(((int)(*rp) + + (int)(*pp++ + *lp++) / 2 ) & 0xff); + rp++; + } + break; + } + case PNG_FILTER_VALUE_PAETH: + { + png_uint_32 i; + png_bytep rp = row; + png_bytep pp = prev_row; + png_bytep lp = row; + png_bytep cp = prev_row; + png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3; + png_uint_32 istop=row_info->rowbytes - bpp; + + for (i = 0; i < bpp; i++) + { + *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff); + rp++; + } + + for (i = 0; i < istop; i++) /* use leftover rp,pp */ + { + int a, b, c, pa, pb, pc, p; + + a = *lp++; + b = *pp++; + c = *cp++; + + p = b - c; + pc = a - c; + +#ifdef PNG_USE_ABS + pa = abs(p); + pb = abs(pc); + pc = abs(p + pc); +#else + pa = p < 0 ? -p : p; + pb = pc < 0 ? -pc : pc; + pc = (p + pc) < 0 ? -(p + pc) : p + pc; +#endif + + /* + if (pa <= pb && pa <= pc) + p = a; + else if (pb <= pc) + p = b; + else + p = c; + */ + + p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c; + + *rp = (png_byte)(((int)(*rp) + p) & 0xff); + rp++; + } + break; + } + default: + png_warning(png_ptr, "Ignoring bad adaptive filter type"); + *row=0; + break; + } +} +#endif /* !PNG_HAVE_ASSEMBLER_READ_FILTER_ROW */ + +void /* PRIVATE */ +png_read_finish_row(png_structp png_ptr) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */ + + /* start of interlace block */ + const int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; + + /* offset to next interlace block */ + const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + + /* start of interlace block in the y direction */ + const int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; + + /* offset to next interlace block in the y direction */ + const int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; +#endif + + png_debug(1, "in png_read_finish_row\n"); + png_ptr->row_number++; + if (png_ptr->row_number < png_ptr->num_rows) + return; + + if (png_ptr->interlaced) + { + png_ptr->row_number = 0; + png_memset_check(png_ptr, png_ptr->prev_row, 0, png_ptr->rowbytes + 1); + do + { + png_ptr->pass++; + if (png_ptr->pass >= 7) + break; + png_ptr->iwidth = (png_ptr->width + + png_pass_inc[png_ptr->pass] - 1 - + png_pass_start[png_ptr->pass]) / + png_pass_inc[png_ptr->pass]; + + png_ptr->irowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, + png_ptr->iwidth) + 1; + + if (!(png_ptr->transformations & PNG_INTERLACE)) + { + png_ptr->num_rows = (png_ptr->height + + png_pass_yinc[png_ptr->pass] - 1 - + png_pass_ystart[png_ptr->pass]) / + png_pass_yinc[png_ptr->pass]; + if (!(png_ptr->num_rows)) + continue; + } + else /* if (png_ptr->transformations & PNG_INTERLACE) */ + break; + } while (png_ptr->iwidth == 0); + + if (png_ptr->pass < 7) + return; + } + + if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) + { +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_IDAT; +#endif + char extra; + int ret; + + png_ptr->zstream.next_out = (Byte *)&extra; + png_ptr->zstream.avail_out = (uInt)1; + for(;;) + { + if (!(png_ptr->zstream.avail_in)) + { + while (!png_ptr->idat_size) + { + png_byte chunk_length[4]; + + png_crc_finish(png_ptr, 0); + + png_read_data(png_ptr, chunk_length, 4); + png_ptr->idat_size = png_get_uint_31(png_ptr, chunk_length); + png_reset_crc(png_ptr); + png_crc_read(png_ptr, png_ptr->chunk_name, 4); + if (png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4)) + png_error(png_ptr, "Not enough image data"); + + } + png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size; + png_ptr->zstream.next_in = png_ptr->zbuf; + if (png_ptr->zbuf_size > png_ptr->idat_size) + png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size; + png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in); + png_ptr->idat_size -= png_ptr->zstream.avail_in; + } + ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH); + if (ret == Z_STREAM_END) + { + if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in || + png_ptr->idat_size) + png_warning(png_ptr, "Extra compressed data"); + png_ptr->mode |= PNG_AFTER_IDAT; + png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; + break; + } + if (ret != Z_OK) + png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg : + "Decompression Error"); + + if (!(png_ptr->zstream.avail_out)) + { + png_warning(png_ptr, "Extra compressed data."); + png_ptr->mode |= PNG_AFTER_IDAT; + png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; + break; + } + + } + png_ptr->zstream.avail_out = 0; + } + + if (png_ptr->idat_size || png_ptr->zstream.avail_in) + png_warning(png_ptr, "Extra compression data"); + + inflateReset(&png_ptr->zstream); + + png_ptr->mode |= PNG_AFTER_IDAT; +} + +void /* PRIVATE */ +png_read_start_row(png_structp png_ptr) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */ + + /* start of interlace block */ + const int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; + + /* offset to next interlace block */ + const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + + /* start of interlace block in the y direction */ + const int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; + + /* offset to next interlace block in the y direction */ + const int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; +#endif + + int max_pixel_depth; + png_uint_32 row_bytes; + + png_debug(1, "in png_read_start_row\n"); + png_ptr->zstream.avail_in = 0; + png_init_read_transformations(png_ptr); + if (png_ptr->interlaced) + { + if (!(png_ptr->transformations & PNG_INTERLACE)) + png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 - + png_pass_ystart[0]) / png_pass_yinc[0]; + else + png_ptr->num_rows = png_ptr->height; + + png_ptr->iwidth = (png_ptr->width + + png_pass_inc[png_ptr->pass] - 1 - + png_pass_start[png_ptr->pass]) / + png_pass_inc[png_ptr->pass]; + + row_bytes = PNG_ROWBYTES(png_ptr->pixel_depth,png_ptr->iwidth) + 1; + + png_ptr->irowbytes = (png_size_t)row_bytes; + if((png_uint_32)png_ptr->irowbytes != row_bytes) + png_error(png_ptr, "Rowbytes overflow in png_read_start_row"); + } + else + { + png_ptr->num_rows = png_ptr->height; + png_ptr->iwidth = png_ptr->width; + png_ptr->irowbytes = png_ptr->rowbytes + 1; + } + max_pixel_depth = png_ptr->pixel_depth; + +#if defined(PNG_READ_PACK_SUPPORTED) + if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8) + max_pixel_depth = 8; +#endif + +#if defined(PNG_READ_EXPAND_SUPPORTED) + if (png_ptr->transformations & PNG_EXPAND) + { + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { + if (png_ptr->num_trans) + max_pixel_depth = 32; + else + max_pixel_depth = 24; + } + else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) + { + if (max_pixel_depth < 8) + max_pixel_depth = 8; + if (png_ptr->num_trans) + max_pixel_depth *= 2; + } + else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) + { + if (png_ptr->num_trans) + { + max_pixel_depth *= 4; + max_pixel_depth /= 3; + } + } + } +#endif + +#if defined(PNG_READ_FILLER_SUPPORTED) + if (png_ptr->transformations & (PNG_FILLER)) + { + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + max_pixel_depth = 32; + else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) + { + if (max_pixel_depth <= 8) + max_pixel_depth = 16; + else + max_pixel_depth = 32; + } + else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) + { + if (max_pixel_depth <= 32) + max_pixel_depth = 32; + else + max_pixel_depth = 64; + } + } +#endif + +#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) + if (png_ptr->transformations & PNG_GRAY_TO_RGB) + { + if ( +#if defined(PNG_READ_EXPAND_SUPPORTED) + (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) || +#endif +#if defined(PNG_READ_FILLER_SUPPORTED) + (png_ptr->transformations & (PNG_FILLER)) || +#endif + png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + { + if (max_pixel_depth <= 16) + max_pixel_depth = 32; + else + max_pixel_depth = 64; + } + else + { + if (max_pixel_depth <= 8) + { + if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + max_pixel_depth = 32; + else + max_pixel_depth = 24; + } + else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + max_pixel_depth = 64; + else + max_pixel_depth = 48; + } + } +#endif + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \ +defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) + if(png_ptr->transformations & PNG_USER_TRANSFORM) + { + int user_pixel_depth=png_ptr->user_transform_depth* + png_ptr->user_transform_channels; + if(user_pixel_depth > max_pixel_depth) + max_pixel_depth=user_pixel_depth; + } +#endif + + /* align the width on the next larger 8 pixels. Mainly used + for interlacing */ + row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7)); + /* calculate the maximum bytes needed, adding a byte and a pixel + for safety's sake */ + row_bytes = PNG_ROWBYTES(max_pixel_depth,row_bytes) + + 1 + ((max_pixel_depth + 7) >> 3); +#ifdef PNG_MAX_MALLOC_64K + if (row_bytes > (png_uint_32)65536L) + png_error(png_ptr, "This image requires a row greater than 64KB"); +#endif + png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes+64); + png_ptr->row_buf = png_ptr->big_row_buf+32; +#if defined(PNG_DEBUG) && defined(PNG_USE_PNGGCCRD) + png_ptr->row_buf_size = row_bytes; +#endif + +#ifdef PNG_MAX_MALLOC_64K + if ((png_uint_32)png_ptr->rowbytes + 1 > (png_uint_32)65536L) + png_error(png_ptr, "This image requires a row greater than 64KB"); +#endif + if ((png_uint_32)png_ptr->rowbytes > PNG_SIZE_MAX - 1) + png_error(png_ptr, "Row has too many bytes to allocate in memory."); + png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)( + png_ptr->rowbytes + 1)); + + png_memset_check(png_ptr, png_ptr->prev_row, 0, png_ptr->rowbytes + 1); + + png_debug1(3, "width = %lu,\n", png_ptr->width); + png_debug1(3, "height = %lu,\n", png_ptr->height); + png_debug1(3, "iwidth = %lu,\n", png_ptr->iwidth); + png_debug1(3, "num_rows = %lu\n", png_ptr->num_rows); + png_debug1(3, "rowbytes = %lu,\n", png_ptr->rowbytes); + png_debug1(3, "irowbytes = %lu,\n", png_ptr->irowbytes); + + png_ptr->flags |= PNG_FLAG_ROW_INIT; +} +#endif /* PNG_READ_SUPPORTED */ diff --git a/mod/pub.mod/libpng.mod/pngset.c b/mod/pub.mod/libpng.mod/pngset.c new file mode 100644 index 0000000..9e499c9 --- /dev/null +++ b/mod/pub.mod/libpng.mod/pngset.c @@ -0,0 +1,1265 @@ + +/* pngset.c - storage of image information into info struct + * + * Last changed in libpng 1.2.9 April 14, 2006 + * For conditions of distribution and use, see copyright notice in png.h + * Copyright (c) 1998-2006 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * + * The functions here are used during reads to store data from the file + * into the info struct, and during writes to store application data + * into the info struct for writing into the file. This abstracts the + * info struct and allows us to change the structure in the future. + */ + +#define PNG_INTERNAL +#include "png.h" + +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) + +#if defined(PNG_bKGD_SUPPORTED) +void PNGAPI +png_set_bKGD(png_structp png_ptr, png_infop info_ptr, png_color_16p background) +{ + png_debug1(1, "in %s storage function\n", "bKGD"); + if (png_ptr == NULL || info_ptr == NULL) + return; + + png_memcpy(&(info_ptr->background), background, png_sizeof(png_color_16)); + info_ptr->valid |= PNG_INFO_bKGD; +} +#endif + +#if defined(PNG_cHRM_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED +void PNGAPI +png_set_cHRM(png_structp png_ptr, png_infop info_ptr, + double white_x, double white_y, double red_x, double red_y, + double green_x, double green_y, double blue_x, double blue_y) +{ + png_debug1(1, "in %s storage function\n", "cHRM"); + if (png_ptr == NULL || info_ptr == NULL) + return; + + if (white_x < 0.0 || white_y < 0.0 || + red_x < 0.0 || red_y < 0.0 || + green_x < 0.0 || green_y < 0.0 || + blue_x < 0.0 || blue_y < 0.0) + { + png_warning(png_ptr, + "Ignoring attempt to set negative chromaticity value"); + return; + } + if (white_x > 21474.83 || white_y > 21474.83 || + red_x > 21474.83 || red_y > 21474.83 || + green_x > 21474.83 || green_y > 21474.83 || + blue_x > 21474.83 || blue_y > 21474.83) + { + png_warning(png_ptr, + "Ignoring attempt to set chromaticity value exceeding 21474.83"); + return; + } + + info_ptr->x_white = (float)white_x; + info_ptr->y_white = (float)white_y; + info_ptr->x_red = (float)red_x; + info_ptr->y_red = (float)red_y; + info_ptr->x_green = (float)green_x; + info_ptr->y_green = (float)green_y; + info_ptr->x_blue = (float)blue_x; + info_ptr->y_blue = (float)blue_y; +#ifdef PNG_FIXED_POINT_SUPPORTED + info_ptr->int_x_white = (png_fixed_point)(white_x*100000.+0.5); + info_ptr->int_y_white = (png_fixed_point)(white_y*100000.+0.5); + info_ptr->int_x_red = (png_fixed_point)( red_x*100000.+0.5); + info_ptr->int_y_red = (png_fixed_point)( red_y*100000.+0.5); + info_ptr->int_x_green = (png_fixed_point)(green_x*100000.+0.5); + info_ptr->int_y_green = (png_fixed_point)(green_y*100000.+0.5); + info_ptr->int_x_blue = (png_fixed_point)( blue_x*100000.+0.5); + info_ptr->int_y_blue = (png_fixed_point)( blue_y*100000.+0.5); +#endif + info_ptr->valid |= PNG_INFO_cHRM; +} +#endif +#ifdef PNG_FIXED_POINT_SUPPORTED +void PNGAPI +png_set_cHRM_fixed(png_structp png_ptr, png_infop info_ptr, + png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x, + png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y, + png_fixed_point blue_x, png_fixed_point blue_y) +{ + png_debug1(1, "in %s storage function\n", "cHRM"); + if (png_ptr == NULL || info_ptr == NULL) + return; + + if (white_x < 0 || white_y < 0 || + red_x < 0 || red_y < 0 || + green_x < 0 || green_y < 0 || + blue_x < 0 || blue_y < 0) + { + png_warning(png_ptr, + "Ignoring attempt to set negative chromaticity value"); + return; + } +#ifdef PNG_FLOATING_POINT_SUPPORTED + if (white_x > (double) PNG_UINT_31_MAX || + white_y > (double) PNG_UINT_31_MAX || + red_x > (double) PNG_UINT_31_MAX || + red_y > (double) PNG_UINT_31_MAX || + green_x > (double) PNG_UINT_31_MAX || + green_y > (double) PNG_UINT_31_MAX || + blue_x > (double) PNG_UINT_31_MAX || + blue_y > (double) PNG_UINT_31_MAX) +#else + if (white_x > (png_fixed_point) PNG_UINT_31_MAX/100000L || + white_y > (png_fixed_point) PNG_UINT_31_MAX/100000L || + red_x > (png_fixed_point) PNG_UINT_31_MAX/100000L || + red_y > (png_fixed_point) PNG_UINT_31_MAX/100000L || + green_x > (png_fixed_point) PNG_UINT_31_MAX/100000L || + green_y > (png_fixed_point) PNG_UINT_31_MAX/100000L || + blue_x > (png_fixed_point) PNG_UINT_31_MAX/100000L || + blue_y > (png_fixed_point) PNG_UINT_31_MAX/100000L) +#endif + { + png_warning(png_ptr, + "Ignoring attempt to set chromaticity value exceeding 21474.83"); + return; + } + info_ptr->int_x_white = white_x; + info_ptr->int_y_white = white_y; + info_ptr->int_x_red = red_x; + info_ptr->int_y_red = red_y; + info_ptr->int_x_green = green_x; + info_ptr->int_y_green = green_y; + info_ptr->int_x_blue = blue_x; + info_ptr->int_y_blue = blue_y; +#ifdef PNG_FLOATING_POINT_SUPPORTED + info_ptr->x_white = (float)(white_x/100000.); + info_ptr->y_white = (float)(white_y/100000.); + info_ptr->x_red = (float)( red_x/100000.); + info_ptr->y_red = (float)( red_y/100000.); + info_ptr->x_green = (float)(green_x/100000.); + info_ptr->y_green = (float)(green_y/100000.); + info_ptr->x_blue = (float)( blue_x/100000.); + info_ptr->y_blue = (float)( blue_y/100000.); +#endif + info_ptr->valid |= PNG_INFO_cHRM; +} +#endif +#endif + +#if defined(PNG_gAMA_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED +void PNGAPI +png_set_gAMA(png_structp png_ptr, png_infop info_ptr, double file_gamma) +{ + double gamma; + png_debug1(1, "in %s storage function\n", "gAMA"); + if (png_ptr == NULL || info_ptr == NULL) + return; + + /* Check for overflow */ + if (file_gamma > 21474.83) + { + png_warning(png_ptr, "Limiting gamma to 21474.83"); + gamma=21474.83; + } + else + gamma=file_gamma; + info_ptr->gamma = (float)gamma; +#ifdef PNG_FIXED_POINT_SUPPORTED + info_ptr->int_gamma = (int)(gamma*100000.+.5); +#endif + info_ptr->valid |= PNG_INFO_gAMA; + if(gamma == 0.0) + png_warning(png_ptr, "Setting gamma=0"); +} +#endif +void PNGAPI +png_set_gAMA_fixed(png_structp png_ptr, png_infop info_ptr, png_fixed_point + int_gamma) +{ + png_fixed_point gamma; + + png_debug1(1, "in %s storage function\n", "gAMA"); + if (png_ptr == NULL || info_ptr == NULL) + return; + + if (int_gamma > (png_fixed_point) PNG_UINT_31_MAX) + { + png_warning(png_ptr, "Limiting gamma to 21474.83"); + gamma=PNG_UINT_31_MAX; + } + else + { + if (int_gamma < 0) + { + png_warning(png_ptr, "Setting negative gamma to zero"); + gamma=0; + } + else + gamma=int_gamma; + } +#ifdef PNG_FLOATING_POINT_SUPPORTED + info_ptr->gamma = (float)(gamma/100000.); +#endif +#ifdef PNG_FIXED_POINT_SUPPORTED + info_ptr->int_gamma = gamma; +#endif + info_ptr->valid |= PNG_INFO_gAMA; + if(gamma == 0) + png_warning(png_ptr, "Setting gamma=0"); +} +#endif + +#if defined(PNG_hIST_SUPPORTED) +void PNGAPI +png_set_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_16p hist) +{ + int i; + + png_debug1(1, "in %s storage function\n", "hIST"); + if (png_ptr == NULL || info_ptr == NULL) + return; + if (info_ptr->num_palette <= 0 || info_ptr->num_palette + > PNG_MAX_PALETTE_LENGTH) + { + png_warning(png_ptr, + "Invalid palette size, hIST allocation skipped."); + return; + } + +#ifdef PNG_FREE_ME_SUPPORTED + png_free_data(png_ptr, info_ptr, PNG_FREE_HIST, 0); +#endif + /* Changed from info->num_palette to PNG_MAX_PALETTE_LENGTH in version + 1.2.1 */ + png_ptr->hist = (png_uint_16p)png_malloc_warn(png_ptr, + (png_uint_32)(PNG_MAX_PALETTE_LENGTH * png_sizeof (png_uint_16))); + if (png_ptr->hist == NULL) + { + png_warning(png_ptr, "Insufficient memory for hIST chunk data."); + return; + } + + for (i = 0; i < info_ptr->num_palette; i++) + png_ptr->hist[i] = hist[i]; + info_ptr->hist = png_ptr->hist; + info_ptr->valid |= PNG_INFO_hIST; + +#ifdef PNG_FREE_ME_SUPPORTED + info_ptr->free_me |= PNG_FREE_HIST; +#else + png_ptr->flags |= PNG_FLAG_FREE_HIST; +#endif +} +#endif + +void PNGAPI +png_set_IHDR(png_structp png_ptr, png_infop info_ptr, + png_uint_32 width, png_uint_32 height, int bit_depth, + int color_type, int interlace_type, int compression_type, + int filter_type) +{ + png_debug1(1, "in %s storage function\n", "IHDR"); + if (png_ptr == NULL || info_ptr == NULL) + return; + + /* check for width and height valid values */ + if (width == 0 || height == 0) + png_error(png_ptr, "Image width or height is zero in IHDR"); +#ifdef PNG_SET_USER_LIMITS_SUPPORTED + if (width > png_ptr->user_width_max || height > png_ptr->user_height_max) + png_error(png_ptr, "image size exceeds user limits in IHDR"); +#else + if (width > PNG_USER_WIDTH_MAX || height > PNG_USER_HEIGHT_MAX) + png_error(png_ptr, "image size exceeds user limits in IHDR"); +#endif + if (width > PNG_UINT_31_MAX || height > PNG_UINT_31_MAX) + png_error(png_ptr, "Invalid image size in IHDR"); + if ( width > (PNG_UINT_32_MAX + >> 3) /* 8-byte RGBA pixels */ + - 64 /* bigrowbuf hack */ + - 1 /* filter byte */ + - 7*8 /* rounding of width to multiple of 8 pixels */ + - 8) /* extra max_pixel_depth pad */ + png_warning(png_ptr, "Width is too large for libpng to process pixels"); + + /* check other values */ + if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 && + bit_depth != 8 && bit_depth != 16) + png_error(png_ptr, "Invalid bit depth in IHDR"); + + if (color_type < 0 || color_type == 1 || + color_type == 5 || color_type > 6) + png_error(png_ptr, "Invalid color type in IHDR"); + + if (((color_type == PNG_COLOR_TYPE_PALETTE) && bit_depth > 8) || + ((color_type == PNG_COLOR_TYPE_RGB || + color_type == PNG_COLOR_TYPE_GRAY_ALPHA || + color_type == PNG_COLOR_TYPE_RGB_ALPHA) && bit_depth < 8)) + png_error(png_ptr, "Invalid color type/bit depth combination in IHDR"); + + if (interlace_type >= PNG_INTERLACE_LAST) + png_error(png_ptr, "Unknown interlace method in IHDR"); + + if (compression_type != PNG_COMPRESSION_TYPE_BASE) + png_error(png_ptr, "Unknown compression method in IHDR"); + +#if defined(PNG_MNG_FEATURES_SUPPORTED) + /* Accept filter_method 64 (intrapixel differencing) only if + * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and + * 2. Libpng did not read a PNG signature (this filter_method is only + * used in PNG datastreams that are embedded in MNG datastreams) and + * 3. The application called png_permit_mng_features with a mask that + * included PNG_FLAG_MNG_FILTER_64 and + * 4. The filter_method is 64 and + * 5. The color_type is RGB or RGBA + */ + if((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE)&&png_ptr->mng_features_permitted) + png_warning(png_ptr,"MNG features are not allowed in a PNG datastream"); + if(filter_type != PNG_FILTER_TYPE_BASE) + { + if(!((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && + (filter_type == PNG_INTRAPIXEL_DIFFERENCING) && + ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) == 0) && + (color_type == PNG_COLOR_TYPE_RGB || + color_type == PNG_COLOR_TYPE_RGB_ALPHA))) + png_error(png_ptr, "Unknown filter method in IHDR"); + if(png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) + png_warning(png_ptr, "Invalid filter method in IHDR"); + } +#else + if(filter_type != PNG_FILTER_TYPE_BASE) + png_error(png_ptr, "Unknown filter method in IHDR"); +#endif + + info_ptr->width = width; + info_ptr->height = height; + info_ptr->bit_depth = (png_byte)bit_depth; + info_ptr->color_type =(png_byte) color_type; + info_ptr->compression_type = (png_byte)compression_type; + info_ptr->filter_type = (png_byte)filter_type; + info_ptr->interlace_type = (png_byte)interlace_type; + if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + info_ptr->channels = 1; + else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR) + info_ptr->channels = 3; + else + info_ptr->channels = 1; + if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA) + info_ptr->channels++; + info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth); + + /* check for potential overflow */ + if ( width > (PNG_UINT_32_MAX + >> 3) /* 8-byte RGBA pixels */ + - 64 /* bigrowbuf hack */ + - 1 /* filter byte */ + - 7*8 /* rounding of width to multiple of 8 pixels */ + - 8) /* extra max_pixel_depth pad */ + info_ptr->rowbytes = (png_size_t)0; + else + info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth,width); +} + +#if defined(PNG_oFFs_SUPPORTED) +void PNGAPI +png_set_oFFs(png_structp png_ptr, png_infop info_ptr, + png_int_32 offset_x, png_int_32 offset_y, int unit_type) +{ + png_debug1(1, "in %s storage function\n", "oFFs"); + if (png_ptr == NULL || info_ptr == NULL) + return; + + info_ptr->x_offset = offset_x; + info_ptr->y_offset = offset_y; + info_ptr->offset_unit_type = (png_byte)unit_type; + info_ptr->valid |= PNG_INFO_oFFs; +} +#endif + +#if defined(PNG_pCAL_SUPPORTED) +void PNGAPI +png_set_pCAL(png_structp png_ptr, png_infop info_ptr, + png_charp purpose, png_int_32 X0, png_int_32 X1, int type, int nparams, + png_charp units, png_charpp params) +{ + png_uint_32 length; + int i; + + png_debug1(1, "in %s storage function\n", "pCAL"); + if (png_ptr == NULL || info_ptr == NULL) + return; + + length = png_strlen(purpose) + 1; + png_debug1(3, "allocating purpose for info (%lu bytes)\n", length); + info_ptr->pcal_purpose = (png_charp)png_malloc_warn(png_ptr, length); + if (info_ptr->pcal_purpose == NULL) + { + png_warning(png_ptr, "Insufficient memory for pCAL purpose."); + return; + } + png_memcpy(info_ptr->pcal_purpose, purpose, (png_size_t)length); + + png_debug(3, "storing X0, X1, type, and nparams in info\n"); + info_ptr->pcal_X0 = X0; + info_ptr->pcal_X1 = X1; + info_ptr->pcal_type = (png_byte)type; + info_ptr->pcal_nparams = (png_byte)nparams; + + length = png_strlen(units) + 1; + png_debug1(3, "allocating units for info (%lu bytes)\n", length); + info_ptr->pcal_units = (png_charp)png_malloc_warn(png_ptr, length); + if (info_ptr->pcal_units == NULL) + { + png_warning(png_ptr, "Insufficient memory for pCAL units."); + return; + } + png_memcpy(info_ptr->pcal_units, units, (png_size_t)length); + + info_ptr->pcal_params = (png_charpp)png_malloc_warn(png_ptr, + (png_uint_32)((nparams + 1) * png_sizeof(png_charp))); + if (info_ptr->pcal_params == NULL) + { + png_warning(png_ptr, "Insufficient memory for pCAL params."); + return; + } + + info_ptr->pcal_params[nparams] = NULL; + + for (i = 0; i < nparams; i++) + { + length = png_strlen(params[i]) + 1; + png_debug2(3, "allocating parameter %d for info (%lu bytes)\n", i, length); + info_ptr->pcal_params[i] = (png_charp)png_malloc_warn(png_ptr, length); + if (info_ptr->pcal_params[i] == NULL) + { + png_warning(png_ptr, "Insufficient memory for pCAL parameter."); + return; + } + png_memcpy(info_ptr->pcal_params[i], params[i], (png_size_t)length); + } + + info_ptr->valid |= PNG_INFO_pCAL; +#ifdef PNG_FREE_ME_SUPPORTED + info_ptr->free_me |= PNG_FREE_PCAL; +#endif +} +#endif + +#if defined(PNG_READ_sCAL_SUPPORTED) || defined(PNG_WRITE_sCAL_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED +void PNGAPI +png_set_sCAL(png_structp png_ptr, png_infop info_ptr, + int unit, double width, double height) +{ + png_debug1(1, "in %s storage function\n", "sCAL"); + if (png_ptr == NULL || info_ptr == NULL) + return; + + info_ptr->scal_unit = (png_byte)unit; + info_ptr->scal_pixel_width = width; + info_ptr->scal_pixel_height = height; + + info_ptr->valid |= PNG_INFO_sCAL; +} +#else +#ifdef PNG_FIXED_POINT_SUPPORTED +void PNGAPI +png_set_sCAL_s(png_structp png_ptr, png_infop info_ptr, + int unit, png_charp swidth, png_charp sheight) +{ + png_uint_32 length; + + png_debug1(1, "in %s storage function\n", "sCAL"); + if (png_ptr == NULL || info_ptr == NULL) + return; + + info_ptr->scal_unit = (png_byte)unit; + + length = png_strlen(swidth) + 1; + png_debug1(3, "allocating unit for info (%d bytes)\n", length); + info_ptr->scal_s_width = (png_charp)png_malloc_warn(png_ptr, length); + if (info_ptr->scal_s_width == NULL) + { + png_warning(png_ptr, "Memory allocation failed while processing sCAL."); + } + png_memcpy(info_ptr->scal_s_width, swidth, (png_size_t)length); + + length = png_strlen(sheight) + 1; + png_debug1(3, "allocating unit for info (%d bytes)\n", length); + info_ptr->scal_s_height = (png_charp)png_malloc_warn(png_ptr, length); + if (info_ptr->scal_s_height == NULL) + { + png_free (png_ptr, info_ptr->scal_s_width); + png_warning(png_ptr, "Memory allocation failed while processing sCAL."); + } + png_memcpy(info_ptr->scal_s_height, sheight, (png_size_t)length); + + info_ptr->valid |= PNG_INFO_sCAL; +#ifdef PNG_FREE_ME_SUPPORTED + info_ptr->free_me |= PNG_FREE_SCAL; +#endif +} +#endif +#endif +#endif + +#if defined(PNG_pHYs_SUPPORTED) +void PNGAPI +png_set_pHYs(png_structp png_ptr, png_infop info_ptr, + png_uint_32 res_x, png_uint_32 res_y, int unit_type) +{ + png_debug1(1, "in %s storage function\n", "pHYs"); + if (png_ptr == NULL || info_ptr == NULL) + return; + + info_ptr->x_pixels_per_unit = res_x; + info_ptr->y_pixels_per_unit = res_y; + info_ptr->phys_unit_type = (png_byte)unit_type; + info_ptr->valid |= PNG_INFO_pHYs; +} +#endif + +void PNGAPI +png_set_PLTE(png_structp png_ptr, png_infop info_ptr, + png_colorp palette, int num_palette) +{ + + png_debug1(1, "in %s storage function\n", "PLTE"); + if (png_ptr == NULL || info_ptr == NULL) + return; + + if (num_palette < 0 || num_palette > PNG_MAX_PALETTE_LENGTH) + { + if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + png_error(png_ptr, "Invalid palette length"); + else + { + png_warning(png_ptr, "Invalid palette length"); + return; + } + } + + /* + * It may not actually be necessary to set png_ptr->palette here; + * we do it for backward compatibility with the way the png_handle_tRNS + * function used to do the allocation. + */ +#ifdef PNG_FREE_ME_SUPPORTED + png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0); +#endif + + /* Changed in libpng-1.2.1 to allocate PNG_MAX_PALETTE_LENGTH instead + of num_palette entries, + in case of an invalid PNG file that has too-large sample values. */ + png_ptr->palette = (png_colorp)png_malloc(png_ptr, + PNG_MAX_PALETTE_LENGTH * png_sizeof(png_color)); + png_memset(png_ptr->palette, 0, PNG_MAX_PALETTE_LENGTH * + png_sizeof(png_color)); + png_memcpy(png_ptr->palette, palette, num_palette * png_sizeof (png_color)); + info_ptr->palette = png_ptr->palette; + info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette; + +#ifdef PNG_FREE_ME_SUPPORTED + info_ptr->free_me |= PNG_FREE_PLTE; +#else + png_ptr->flags |= PNG_FLAG_FREE_PLTE; +#endif + + info_ptr->valid |= PNG_INFO_PLTE; +} + +#if defined(PNG_sBIT_SUPPORTED) +void PNGAPI +png_set_sBIT(png_structp png_ptr, png_infop info_ptr, + png_color_8p sig_bit) +{ + png_debug1(1, "in %s storage function\n", "sBIT"); + if (png_ptr == NULL || info_ptr == NULL) + return; + + png_memcpy(&(info_ptr->sig_bit), sig_bit, png_sizeof (png_color_8)); + info_ptr->valid |= PNG_INFO_sBIT; +} +#endif + +#if defined(PNG_sRGB_SUPPORTED) +void PNGAPI +png_set_sRGB(png_structp png_ptr, png_infop info_ptr, int intent) +{ + png_debug1(1, "in %s storage function\n", "sRGB"); + if (png_ptr == NULL || info_ptr == NULL) + return; + + info_ptr->srgb_intent = (png_byte)intent; + info_ptr->valid |= PNG_INFO_sRGB; +} + +void PNGAPI +png_set_sRGB_gAMA_and_cHRM(png_structp png_ptr, png_infop info_ptr, + int intent) +{ +#if defined(PNG_gAMA_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED + float file_gamma; +#endif +#ifdef PNG_FIXED_POINT_SUPPORTED + png_fixed_point int_file_gamma; +#endif +#endif +#if defined(PNG_cHRM_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED + float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y; +#endif +#ifdef PNG_FIXED_POINT_SUPPORTED + png_fixed_point int_white_x, int_white_y, int_red_x, int_red_y, int_green_x, + int_green_y, int_blue_x, int_blue_y; +#endif +#endif + png_debug1(1, "in %s storage function\n", "sRGB_gAMA_and_cHRM"); + if (png_ptr == NULL || info_ptr == NULL) + return; + + png_set_sRGB(png_ptr, info_ptr, intent); + +#if defined(PNG_gAMA_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED + file_gamma = (float).45455; + png_set_gAMA(png_ptr, info_ptr, file_gamma); +#endif +#ifdef PNG_FIXED_POINT_SUPPORTED + int_file_gamma = 45455L; + png_set_gAMA_fixed(png_ptr, info_ptr, int_file_gamma); +#endif +#endif + +#if defined(PNG_cHRM_SUPPORTED) +#ifdef PNG_FIXED_POINT_SUPPORTED + int_white_x = 31270L; + int_white_y = 32900L; + int_red_x = 64000L; + int_red_y = 33000L; + int_green_x = 30000L; + int_green_y = 60000L; + int_blue_x = 15000L; + int_blue_y = 6000L; + + png_set_cHRM_fixed(png_ptr, info_ptr, + int_white_x, int_white_y, int_red_x, int_red_y, int_green_x, int_green_y, + int_blue_x, int_blue_y); +#endif +#ifdef PNG_FLOATING_POINT_SUPPORTED + white_x = (float).3127; + white_y = (float).3290; + red_x = (float).64; + red_y = (float).33; + green_x = (float).30; + green_y = (float).60; + blue_x = (float).15; + blue_y = (float).06; + + png_set_cHRM(png_ptr, info_ptr, + white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y); +#endif +#endif +} +#endif + + +#if defined(PNG_iCCP_SUPPORTED) +void PNGAPI +png_set_iCCP(png_structp png_ptr, png_infop info_ptr, + png_charp name, int compression_type, + png_charp profile, png_uint_32 proflen) +{ + png_charp new_iccp_name; + png_charp new_iccp_profile; + + png_debug1(1, "in %s storage function\n", "iCCP"); + if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL) + return; + + new_iccp_name = (png_charp)png_malloc_warn(png_ptr, png_strlen(name)+1); + if (new_iccp_name == NULL) + { + png_warning(png_ptr, "Insufficient memory to process iCCP chunk."); + return; + } + png_strcpy(new_iccp_name, name); + new_iccp_profile = (png_charp)png_malloc_warn(png_ptr, proflen); + if (new_iccp_profile == NULL) + { + png_free (png_ptr, new_iccp_name); + png_warning(png_ptr, "Insufficient memory to process iCCP profile."); + return; + } + png_memcpy(new_iccp_profile, profile, (png_size_t)proflen); + + png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, 0); + + info_ptr->iccp_proflen = proflen; + info_ptr->iccp_name = new_iccp_name; + info_ptr->iccp_profile = new_iccp_profile; + /* Compression is always zero but is here so the API and info structure + * does not have to change if we introduce multiple compression types */ + info_ptr->iccp_compression = (png_byte)compression_type; +#ifdef PNG_FREE_ME_SUPPORTED + info_ptr->free_me |= PNG_FREE_ICCP; +#endif + info_ptr->valid |= PNG_INFO_iCCP; +} +#endif + +#if defined(PNG_TEXT_SUPPORTED) +void PNGAPI +png_set_text(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr, + int num_text) +{ + int ret; + ret=png_set_text_2(png_ptr, info_ptr, text_ptr, num_text); + if (ret) + png_error(png_ptr, "Insufficient memory to store text"); +} + +int /* PRIVATE */ +png_set_text_2(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr, + int num_text) +{ + int i; + + png_debug1(1, "in %s storage function\n", (png_ptr->chunk_name[0] == '\0' ? + "text" : (png_const_charp)png_ptr->chunk_name)); + + if (png_ptr == NULL || info_ptr == NULL || num_text == 0) + return(0); + + /* Make sure we have enough space in the "text" array in info_struct + * to hold all of the incoming text_ptr objects. + */ + if (info_ptr->num_text + num_text > info_ptr->max_text) + { + if (info_ptr->text != NULL) + { + png_textp old_text; + int old_max; + + old_max = info_ptr->max_text; + info_ptr->max_text = info_ptr->num_text + num_text + 8; + old_text = info_ptr->text; + info_ptr->text = (png_textp)png_malloc_warn(png_ptr, + (png_uint_32)(info_ptr->max_text * png_sizeof (png_text))); + if (info_ptr->text == NULL) + { + png_free(png_ptr, old_text); + return(1); + } + png_memcpy(info_ptr->text, old_text, (png_size_t)(old_max * + png_sizeof(png_text))); + png_free(png_ptr, old_text); + } + else + { + info_ptr->max_text = num_text + 8; + info_ptr->num_text = 0; + info_ptr->text = (png_textp)png_malloc_warn(png_ptr, + (png_uint_32)(info_ptr->max_text * png_sizeof (png_text))); + if (info_ptr->text == NULL) + return(1); +#ifdef PNG_FREE_ME_SUPPORTED + info_ptr->free_me |= PNG_FREE_TEXT; +#endif + } + png_debug1(3, "allocated %d entries for info_ptr->text\n", + info_ptr->max_text); + } + for (i = 0; i < num_text; i++) + { + png_size_t text_length,key_len; + png_size_t lang_len,lang_key_len; + png_textp textp = &(info_ptr->text[info_ptr->num_text]); + + if (text_ptr[i].key == NULL) + continue; + + key_len = png_strlen(text_ptr[i].key); + + if(text_ptr[i].compression <= 0) + { + lang_len = 0; + lang_key_len = 0; + } + else +#ifdef PNG_iTXt_SUPPORTED + { + /* set iTXt data */ + if (text_ptr[i].lang != NULL) + lang_len = png_strlen(text_ptr[i].lang); + else + lang_len = 0; + if (text_ptr[i].lang_key != NULL) + lang_key_len = png_strlen(text_ptr[i].lang_key); + else + lang_key_len = 0; + } +#else + { + png_warning(png_ptr, "iTXt chunk not supported."); + continue; + } +#endif + + if (text_ptr[i].text == NULL || text_ptr[i].text[0] == '\0') + { + text_length = 0; +#ifdef PNG_iTXt_SUPPORTED + if(text_ptr[i].compression > 0) + textp->compression = PNG_ITXT_COMPRESSION_NONE; + else +#endif + textp->compression = PNG_TEXT_COMPRESSION_NONE; + } + else + { + text_length = png_strlen(text_ptr[i].text); + textp->compression = text_ptr[i].compression; + } + + textp->key = (png_charp)png_malloc_warn(png_ptr, + (png_uint_32)(key_len + text_length + lang_len + lang_key_len + 4)); + if (textp->key == NULL) + return(1); + png_debug2(2, "Allocated %lu bytes at %x in png_set_text\n", + (png_uint_32)(key_len + lang_len + lang_key_len + text_length + 4), + (int)textp->key); + + png_memcpy(textp->key, text_ptr[i].key, + (png_size_t)(key_len)); + *(textp->key+key_len) = '\0'; +#ifdef PNG_iTXt_SUPPORTED + if (text_ptr[i].compression > 0) + { + textp->lang=textp->key + key_len + 1; + png_memcpy(textp->lang, text_ptr[i].lang, lang_len); + *(textp->lang+lang_len) = '\0'; + textp->lang_key=textp->lang + lang_len + 1; + png_memcpy(textp->lang_key, text_ptr[i].lang_key, lang_key_len); + *(textp->lang_key+lang_key_len) = '\0'; + textp->text=textp->lang_key + lang_key_len + 1; + } + else +#endif + { +#ifdef PNG_iTXt_SUPPORTED + textp->lang=NULL; + textp->lang_key=NULL; +#endif + textp->text=textp->key + key_len + 1; + } + if(text_length) + png_memcpy(textp->text, text_ptr[i].text, + (png_size_t)(text_length)); + *(textp->text+text_length) = '\0'; + +#ifdef PNG_iTXt_SUPPORTED + if(textp->compression > 0) + { + textp->text_length = 0; + textp->itxt_length = text_length; + } + else +#endif + { + textp->text_length = text_length; +#ifdef PNG_iTXt_SUPPORTED + textp->itxt_length = 0; +#endif + } + info_ptr->text[info_ptr->num_text]= *textp; + info_ptr->num_text++; + png_debug1(3, "transferred text chunk %d\n", info_ptr->num_text); + } + return(0); +} +#endif + +#if defined(PNG_tIME_SUPPORTED) +void PNGAPI +png_set_tIME(png_structp png_ptr, png_infop info_ptr, png_timep mod_time) +{ + png_debug1(1, "in %s storage function\n", "tIME"); + if (png_ptr == NULL || info_ptr == NULL || + (png_ptr->mode & PNG_WROTE_tIME)) + return; + + png_memcpy(&(info_ptr->mod_time), mod_time, png_sizeof (png_time)); + info_ptr->valid |= PNG_INFO_tIME; +} +#endif + +#if defined(PNG_tRNS_SUPPORTED) +void PNGAPI +png_set_tRNS(png_structp png_ptr, png_infop info_ptr, + png_bytep trans, int num_trans, png_color_16p trans_values) +{ + png_debug1(1, "in %s storage function\n", "tRNS"); + if (png_ptr == NULL || info_ptr == NULL) + return; + + if (trans != NULL) + { + /* + * It may not actually be necessary to set png_ptr->trans here; + * we do it for backward compatibility with the way the png_handle_tRNS + * function used to do the allocation. + */ +#ifdef PNG_FREE_ME_SUPPORTED + png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0); +#endif + /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */ + png_ptr->trans = info_ptr->trans = (png_bytep)png_malloc(png_ptr, + (png_uint_32)PNG_MAX_PALETTE_LENGTH); + if (num_trans <= PNG_MAX_PALETTE_LENGTH) + png_memcpy(info_ptr->trans, trans, (png_size_t)num_trans); +#ifdef PNG_FREE_ME_SUPPORTED + info_ptr->free_me |= PNG_FREE_TRNS; +#else + png_ptr->flags |= PNG_FLAG_FREE_TRNS; +#endif + } + + if (trans_values != NULL) + { + png_memcpy(&(info_ptr->trans_values), trans_values, + png_sizeof(png_color_16)); + if (num_trans == 0) + num_trans = 1; + } + info_ptr->num_trans = (png_uint_16)num_trans; + info_ptr->valid |= PNG_INFO_tRNS; +} +#endif + +#if defined(PNG_sPLT_SUPPORTED) +void PNGAPI +png_set_sPLT(png_structp png_ptr, + png_infop info_ptr, png_sPLT_tp entries, int nentries) +{ + png_sPLT_tp np; + int i; + + if (png_ptr == NULL || info_ptr == NULL) + return; + + np = (png_sPLT_tp)png_malloc_warn(png_ptr, + (info_ptr->splt_palettes_num + nentries) * png_sizeof(png_sPLT_t)); + if (np == NULL) + { + png_warning(png_ptr, "No memory for sPLT palettes."); + return; + } + + png_memcpy(np, info_ptr->splt_palettes, + info_ptr->splt_palettes_num * png_sizeof(png_sPLT_t)); + png_free(png_ptr, info_ptr->splt_palettes); + info_ptr->splt_palettes=NULL; + + for (i = 0; i < nentries; i++) + { + png_sPLT_tp to = np + info_ptr->splt_palettes_num + i; + png_sPLT_tp from = entries + i; + + to->name = (png_charp)png_malloc(png_ptr, + png_strlen(from->name) + 1); + /* TODO: use png_malloc_warn */ + png_strcpy(to->name, from->name); + to->entries = (png_sPLT_entryp)png_malloc(png_ptr, + from->nentries * png_sizeof(png_sPLT_t)); + /* TODO: use png_malloc_warn */ + png_memcpy(to->entries, from->entries, + from->nentries * png_sizeof(png_sPLT_t)); + to->nentries = from->nentries; + to->depth = from->depth; + } + + info_ptr->splt_palettes = np; + info_ptr->splt_palettes_num += nentries; + info_ptr->valid |= PNG_INFO_sPLT; +#ifdef PNG_FREE_ME_SUPPORTED + info_ptr->free_me |= PNG_FREE_SPLT; +#endif +} +#endif /* PNG_sPLT_SUPPORTED */ + +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) +void PNGAPI +png_set_unknown_chunks(png_structp png_ptr, + png_infop info_ptr, png_unknown_chunkp unknowns, int num_unknowns) +{ + png_unknown_chunkp np; + int i; + + if (png_ptr == NULL || info_ptr == NULL || num_unknowns == 0) + return; + + np = (png_unknown_chunkp)png_malloc_warn(png_ptr, + (info_ptr->unknown_chunks_num + num_unknowns) * + png_sizeof(png_unknown_chunk)); + if (np == NULL) + { + png_warning(png_ptr, "Out of memory while processing unknown chunk."); + return; + } + + png_memcpy(np, info_ptr->unknown_chunks, + info_ptr->unknown_chunks_num * png_sizeof(png_unknown_chunk)); + png_free(png_ptr, info_ptr->unknown_chunks); + info_ptr->unknown_chunks=NULL; + + for (i = 0; i < num_unknowns; i++) + { + png_unknown_chunkp to = np + info_ptr->unknown_chunks_num + i; + png_unknown_chunkp from = unknowns + i; + + png_strncpy((png_charp)to->name, (png_charp)from->name, 5); + to->data = (png_bytep)png_malloc_warn(png_ptr, from->size); + if (to->data == NULL) + { + png_warning(png_ptr, "Out of memory processing unknown chunk."); + } + else + { + png_memcpy(to->data, from->data, from->size); + to->size = from->size; + + /* note our location in the read or write sequence */ + to->location = (png_byte)(png_ptr->mode & 0xff); + } + } + + info_ptr->unknown_chunks = np; + info_ptr->unknown_chunks_num += num_unknowns; +#ifdef PNG_FREE_ME_SUPPORTED + info_ptr->free_me |= PNG_FREE_UNKN; +#endif +} +void PNGAPI +png_set_unknown_chunk_location(png_structp png_ptr, png_infop info_ptr, + int chunk, int location) +{ + if(png_ptr != NULL && info_ptr != NULL && chunk >= 0 && chunk < + (int)info_ptr->unknown_chunks_num) + info_ptr->unknown_chunks[chunk].location = (png_byte)location; +} +#endif + +#if defined(PNG_1_0_X) || defined(PNG_1_2_X) +#if defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \ + defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) +void PNGAPI +png_permit_empty_plte (png_structp png_ptr, int empty_plte_permitted) +{ + /* This function is deprecated in favor of png_permit_mng_features() + and will be removed from libpng-1.3.0 */ + png_debug(1, "in png_permit_empty_plte, DEPRECATED.\n"); + if (png_ptr == NULL) + return; + png_ptr->mng_features_permitted = (png_byte) + ((png_ptr->mng_features_permitted & (~(PNG_FLAG_MNG_EMPTY_PLTE))) | + ((empty_plte_permitted & PNG_FLAG_MNG_EMPTY_PLTE))); +} +#endif +#endif + +#if defined(PNG_MNG_FEATURES_SUPPORTED) +png_uint_32 PNGAPI +png_permit_mng_features (png_structp png_ptr, png_uint_32 mng_features) +{ + png_debug(1, "in png_permit_mng_features\n"); + if (png_ptr == NULL) + return (png_uint_32)0; + png_ptr->mng_features_permitted = + (png_byte)(mng_features & PNG_ALL_MNG_FEATURES); + return (png_uint_32)png_ptr->mng_features_permitted; +} +#endif + +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) +void PNGAPI +png_set_keep_unknown_chunks(png_structp png_ptr, int keep, png_bytep + chunk_list, int num_chunks) +{ + png_bytep new_list, p; + int i, old_num_chunks; + if (png_ptr == NULL) + return; + if (num_chunks == 0) + { + if(keep == PNG_HANDLE_CHUNK_ALWAYS || keep == PNG_HANDLE_CHUNK_IF_SAFE) + png_ptr->flags |= PNG_FLAG_KEEP_UNKNOWN_CHUNKS; + else + png_ptr->flags &= ~PNG_FLAG_KEEP_UNKNOWN_CHUNKS; + + if(keep == PNG_HANDLE_CHUNK_ALWAYS) + png_ptr->flags |= PNG_FLAG_KEEP_UNSAFE_CHUNKS; + else + png_ptr->flags &= ~PNG_FLAG_KEEP_UNSAFE_CHUNKS; + return; + } + if (chunk_list == NULL) + return; + old_num_chunks=png_ptr->num_chunk_list; + new_list=(png_bytep)png_malloc(png_ptr, + (png_uint_32)(5*(num_chunks+old_num_chunks))); + if(png_ptr->chunk_list != NULL) + { + png_memcpy(new_list, png_ptr->chunk_list, + (png_size_t)(5*old_num_chunks)); + png_free(png_ptr, png_ptr->chunk_list); + png_ptr->chunk_list=NULL; + } + png_memcpy(new_list+5*old_num_chunks, chunk_list, + (png_size_t)(5*num_chunks)); + for (p=new_list+5*old_num_chunks+4, i=0; i<num_chunks; i++, p+=5) + *p=(png_byte)keep; + png_ptr->num_chunk_list=old_num_chunks+num_chunks; + png_ptr->chunk_list=new_list; +#ifdef PNG_FREE_ME_SUPPORTED + png_ptr->free_me |= PNG_FREE_LIST; +#endif +} +#endif + +#if defined(PNG_READ_USER_CHUNKS_SUPPORTED) +void PNGAPI +png_set_read_user_chunk_fn(png_structp png_ptr, png_voidp user_chunk_ptr, + png_user_chunk_ptr read_user_chunk_fn) +{ + png_debug(1, "in png_set_read_user_chunk_fn\n"); + if (png_ptr == NULL) + return; + png_ptr->read_user_chunk_fn = read_user_chunk_fn; + png_ptr->user_chunk_ptr = user_chunk_ptr; +} +#endif + +#if defined(PNG_INFO_IMAGE_SUPPORTED) +void PNGAPI +png_set_rows(png_structp png_ptr, png_infop info_ptr, png_bytepp row_pointers) +{ + png_debug1(1, "in %s storage function\n", "rows"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + if(info_ptr->row_pointers && (info_ptr->row_pointers != row_pointers)) + png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0); + info_ptr->row_pointers = row_pointers; + if(row_pointers) + info_ptr->valid |= PNG_INFO_IDAT; +} +#endif + +#ifdef PNG_WRITE_SUPPORTED +void PNGAPI +png_set_compression_buffer_size(png_structp png_ptr, png_uint_32 size) +{ + if (png_ptr == NULL) + return; + if(png_ptr->zbuf) + png_free(png_ptr, png_ptr->zbuf); + png_ptr->zbuf_size = (png_size_t)size; + png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, size); + png_ptr->zstream.next_out = png_ptr->zbuf; + png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; +} +#endif + +void PNGAPI +png_set_invalid(png_structp png_ptr, png_infop info_ptr, int mask) +{ + if (png_ptr && info_ptr) + info_ptr->valid &= ~(mask); +} + + +#ifndef PNG_1_0_X +#ifdef PNG_ASSEMBLER_CODE_SUPPORTED +/* this function was added to libpng 1.2.0 and should always exist by default */ +void PNGAPI +png_set_asm_flags (png_structp png_ptr, png_uint_32 asm_flags) +{ + png_uint_32 settable_asm_flags; + png_uint_32 settable_mmx_flags; + + if (png_ptr == NULL) + return; + + settable_mmx_flags = +#ifdef PNG_HAVE_ASSEMBLER_COMBINE_ROW + PNG_ASM_FLAG_MMX_READ_COMBINE_ROW | +#endif +#ifdef PNG_HAVE_ASSEMBLER_READ_INTERLACE + PNG_ASM_FLAG_MMX_READ_INTERLACE | +#endif +#ifdef PNG_HAVE_ASSEMBLER_READ_FILTER_ROW + PNG_ASM_FLAG_MMX_READ_FILTER_SUB | + PNG_ASM_FLAG_MMX_READ_FILTER_UP | + PNG_ASM_FLAG_MMX_READ_FILTER_AVG | + PNG_ASM_FLAG_MMX_READ_FILTER_PAETH | +#endif + 0; + + /* could be some non-MMX ones in the future, but not currently: */ + settable_asm_flags = settable_mmx_flags; + + if (!(png_ptr->asm_flags & PNG_ASM_FLAG_MMX_SUPPORT_COMPILED) || + !(png_ptr->asm_flags & PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU)) + { + /* clear all MMX flags if MMX isn't supported */ + settable_asm_flags &= ~settable_mmx_flags; + png_ptr->asm_flags &= ~settable_mmx_flags; + } + + /* we're replacing the settable bits with those passed in by the user, + * so first zero them out of the master copy, then logical-OR in the + * allowed subset that was requested */ + + png_ptr->asm_flags &= ~settable_asm_flags; /* zero them */ + png_ptr->asm_flags |= (asm_flags & settable_asm_flags); /* set them */ +} +#endif /* ?PNG_ASSEMBLER_CODE_SUPPORTED */ + +#ifdef PNG_ASSEMBLER_CODE_SUPPORTED +/* this function was added to libpng 1.2.0 */ +void PNGAPI +png_set_mmx_thresholds (png_structp png_ptr, + png_byte mmx_bitdepth_threshold, + png_uint_32 mmx_rowbytes_threshold) +{ + if (png_ptr == NULL) + return; + png_ptr->mmx_bitdepth_threshold = mmx_bitdepth_threshold; + png_ptr->mmx_rowbytes_threshold = mmx_rowbytes_threshold; +} +#endif /* ?PNG_ASSEMBLER_CODE_SUPPORTED */ + +#ifdef PNG_SET_USER_LIMITS_SUPPORTED +/* this function was added to libpng 1.2.6 */ +void PNGAPI +png_set_user_limits (png_structp png_ptr, png_uint_32 user_width_max, + png_uint_32 user_height_max) +{ + /* Images with dimensions larger than these limits will be + * rejected by png_set_IHDR(). To accept any PNG datastream + * regardless of dimensions, set both limits to 0x7ffffffL. + */ + png_ptr->user_width_max = user_width_max; + png_ptr->user_height_max = user_height_max; +} +#endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */ + +#endif /* ?PNG_1_0_X */ +#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */ diff --git a/mod/pub.mod/libpng.mod/pngtest.c b/mod/pub.mod/libpng.mod/pngtest.c new file mode 100644 index 0000000..924c6ba --- /dev/null +++ b/mod/pub.mod/libpng.mod/pngtest.c @@ -0,0 +1,1552 @@ + +/* pngtest.c - a simple test program to test libpng + * + * Last changed in libpng 1.2.6 - August 15, 2004 + * For conditions of distribution and use, see copyright notice in png.h + * Copyright (c) 1998-2004 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * + * This program reads in a PNG image, writes it out again, and then + * compares the two files. If the files are identical, this shows that + * the basic chunk handling, filtering, and (de)compression code is working + * properly. It does not currently test all of the transforms, although + * it probably should. + * + * The program will report "FAIL" in certain legitimate cases: + * 1) when the compression level or filter selection method is changed. + * 2) when the maximum IDAT size (PNG_ZBUF_SIZE in pngconf.h) is not 8192. + * 3) unknown unsafe-to-copy ancillary chunks or unknown critical chunks + * exist in the input file. + * 4) others not listed here... + * In these cases, it is best to check with another tool such as "pngcheck" + * to see what the differences between the two files are. + * + * If a filename is given on the command-line, then this file is used + * for the input, rather than the default "pngtest.png". This allows + * testing a wide variety of files easily. You can also test a number + * of files at once by typing "pngtest -m file1.png file2.png ..." + */ + +#include "png.h" + +#if defined(_WIN32_WCE) +# if _WIN32_WCE < 211 + __error__ (f|w)printf functions are not supported on old WindowsCE.; +# endif +# include <windows.h> +# include <stdlib.h> +# define READFILE(file, data, length, check) \ + if (ReadFile(file, data, length, &check,NULL)) check = 0 +# define WRITEFILE(file, data, length, check)) \ + if (WriteFile(file, data, length, &check, NULL)) check = 0 +# define FCLOSE(file) CloseHandle(file) +#else +# include <stdio.h> +# include <stdlib.h> +# define READFILE(file, data, length, check) \ + check=(png_size_t)fread(data,(png_size_t)1,length,file) +# define WRITEFILE(file, data, length, check) \ + check=(png_size_t)fwrite(data,(png_size_t)1, length, file) +# define FCLOSE(file) fclose(file) +#endif + +#if defined(PNG_NO_STDIO) +# if defined(_WIN32_WCE) + typedef HANDLE png_FILE_p; +# else + typedef FILE * png_FILE_p; +# endif +#endif + +/* Makes pngtest verbose so we can find problems (needs to be before png.h) */ +#ifndef PNG_DEBUG +# define PNG_DEBUG 0 +#endif + +#if !PNG_DEBUG +# define SINGLE_ROWBUF_ALLOC /* makes buffer overruns easier to nail */ +#endif + +/* Turn on CPU timing +#define PNGTEST_TIMING +*/ + +#ifdef PNG_NO_FLOATING_POINT_SUPPORTED +#undef PNGTEST_TIMING +#endif + +#ifdef PNGTEST_TIMING +static float t_start, t_stop, t_decode, t_encode, t_misc; +#include <time.h> +#endif + +/* Define png_jmpbuf() in case we are using a pre-1.0.6 version of libpng */ +#ifndef png_jmpbuf +# define png_jmpbuf(png_ptr) png_ptr->jmpbuf +#endif + +#ifdef PNGTEST_TIMING +static float t_start, t_stop, t_decode, t_encode, t_misc; +#if !defined(PNG_tIME_SUPPORTED) +#include <time.h> +#endif +#endif + +#if defined(PNG_TIME_RFC1123_SUPPORTED) +static int tIME_chunk_present=0; +static char tIME_string[30] = "no tIME chunk present in file"; +#endif + +static int verbose = 0; + +int test_one_file PNGARG((PNG_CONST char *inname, PNG_CONST char *outname)); + +#ifdef __TURBOC__ +#include <mem.h> +#endif + +/* defined so I can write to a file on gui/windowing platforms */ +/* #define STDERR stderr */ +#define STDERR stdout /* for DOS */ + +/* example of using row callbacks to make a simple progress meter */ +static int status_pass=1; +static int status_dots_requested=0; +static int status_dots=1; + +void +#ifdef PNG_1_0_X +PNGAPI +#endif +read_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass); +void +#ifdef PNG_1_0_X +PNGAPI +#endif +read_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass) +{ + if(png_ptr == NULL || row_number > PNG_UINT_31_MAX) return; + if(status_pass != pass) + { + fprintf(stdout,"\n Pass %d: ",pass); + status_pass = pass; + status_dots = 31; + } + status_dots--; + if(status_dots == 0) + { + fprintf(stdout, "\n "); + status_dots=30; + } + fprintf(stdout, "r"); +} + +void +#ifdef PNG_1_0_X +PNGAPI +#endif +write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass); +void +#ifdef PNG_1_0_X +PNGAPI +#endif +write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass) +{ + if(png_ptr == NULL || row_number > PNG_UINT_31_MAX || pass > 7) return; + fprintf(stdout, "w"); +} + + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) +/* Example of using user transform callback (we don't transform anything, + but merely examine the row filters. We set this to 256 rather than + 5 in case illegal filter values are present.) */ +static png_uint_32 filters_used[256]; +void +#ifdef PNG_1_0_X +PNGAPI +#endif +count_filters(png_structp png_ptr, png_row_infop row_info, png_bytep data); +void +#ifdef PNG_1_0_X +PNGAPI +#endif +count_filters(png_structp png_ptr, png_row_infop row_info, png_bytep data) +{ + if(png_ptr != NULL && row_info != NULL) + ++filters_used[*(data-1)]; +} +#endif + +#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) +/* example of using user transform callback (we don't transform anything, + but merely count the zero samples) */ + +static png_uint_32 zero_samples; + +void +#ifdef PNG_1_0_X +PNGAPI +#endif +count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data); +void +#ifdef PNG_1_0_X +PNGAPI +#endif +count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data) +{ + png_bytep dp = data; + if(png_ptr == NULL)return; + + /* contents of row_info: + * png_uint_32 width width of row + * png_uint_32 rowbytes number of bytes in row + * png_byte color_type color type of pixels + * png_byte bit_depth bit depth of samples + * png_byte channels number of channels (1-4) + * png_byte pixel_depth bits per pixel (depth*channels) + */ + + + /* counts the number of zero samples (or zero pixels if color_type is 3 */ + + if(row_info->color_type == 0 || row_info->color_type == 3) + { + int pos=0; + png_uint_32 n, nstop; + for (n=0, nstop=row_info->width; n<nstop; n++) + { + if(row_info->bit_depth == 1) + { + if(((*dp << pos++ ) & 0x80) == 0) zero_samples++; + if(pos == 8) + { + pos = 0; + dp++; + } + } + if(row_info->bit_depth == 2) + { + if(((*dp << (pos+=2)) & 0xc0) == 0) zero_samples++; + if(pos == 8) + { + pos = 0; + dp++; + } + } + if(row_info->bit_depth == 4) + { + if(((*dp << (pos+=4)) & 0xf0) == 0) zero_samples++; + if(pos == 8) + { + pos = 0; + dp++; + } + } + if(row_info->bit_depth == 8) + if(*dp++ == 0) zero_samples++; + if(row_info->bit_depth == 16) + { + if((*dp | *(dp+1)) == 0) zero_samples++; + dp+=2; + } + } + } + else /* other color types */ + { + png_uint_32 n, nstop; + int channel; + int color_channels = row_info->channels; + if(row_info->color_type > 3)color_channels--; + + for (n=0, nstop=row_info->width; n<nstop; n++) + { + for (channel = 0; channel < color_channels; channel++) + { + if(row_info->bit_depth == 8) + if(*dp++ == 0) zero_samples++; + if(row_info->bit_depth == 16) + { + if((*dp | *(dp+1)) == 0) zero_samples++; + dp+=2; + } + } + if(row_info->color_type > 3) + { + dp++; + if(row_info->bit_depth == 16)dp++; + } + } + } +} +#endif /* PNG_WRITE_USER_TRANSFORM_SUPPORTED */ + +static int wrote_question = 0; + +#if defined(PNG_NO_STDIO) +/* START of code to validate stdio-free compilation */ +/* These copies of the default read/write functions come from pngrio.c and */ +/* pngwio.c. They allow "don't include stdio" testing of the library. */ +/* This is the function that does the actual reading of data. If you are + not reading from a standard C stream, you should create a replacement + read_data function and use it at run time with png_set_read_fn(), rather + than changing the library. */ + +#ifndef USE_FAR_KEYWORD +static void +pngtest_read_data(png_structp png_ptr, png_bytep data, png_size_t length) +{ + png_size_t check; + + /* fread() returns 0 on error, so it is OK to store this in a png_size_t + * instead of an int, which is what fread() actually returns. + */ + READFILE((png_FILE_p)png_ptr->io_ptr, data, length, check); + + if (check != length) + { + png_error(png_ptr, "Read Error!"); + } +} +#else +/* this is the model-independent version. Since the standard I/O library + can't handle far buffers in the medium and small models, we have to copy + the data. +*/ + +#define NEAR_BUF_SIZE 1024 +#define MIN(a,b) (a <= b ? a : b) + +static void +pngtest_read_data(png_structp png_ptr, png_bytep data, png_size_t length) +{ + int check; + png_byte *n_data; + png_FILE_p io_ptr; + + /* Check if data really is near. If so, use usual code. */ + n_data = (png_byte *)CVT_PTR_NOCHECK(data); + io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr); + if ((png_bytep)n_data == data) + { + READFILE(io_ptr, n_data, length, check); + } + else + { + png_byte buf[NEAR_BUF_SIZE]; + png_size_t read, remaining, err; + check = 0; + remaining = length; + do + { + read = MIN(NEAR_BUF_SIZE, remaining); + READFILE(io_ptr, buf, 1, err); + png_memcpy(data, buf, read); /* copy far buffer to near buffer */ + if(err != read) + break; + else + check += err; + data += read; + remaining -= read; + } + while (remaining != 0); + } + if (check != length) + { + png_error(png_ptr, "read Error"); + } +} +#endif /* USE_FAR_KEYWORD */ + +#if defined(PNG_WRITE_FLUSH_SUPPORTED) +static void +pngtest_flush(png_structp png_ptr) +{ +#if !defined(_WIN32_WCE) + png_FILE_p io_ptr; + io_ptr = (png_FILE_p)CVT_PTR((png_ptr->io_ptr)); + if (io_ptr != NULL) + fflush(io_ptr); +#endif +} +#endif + +/* This is the function that does the actual writing of data. If you are + not writing to a standard C stream, you should create a replacement + write_data function and use it at run time with png_set_write_fn(), rather + than changing the library. */ +#ifndef USE_FAR_KEYWORD +static void +pngtest_write_data(png_structp png_ptr, png_bytep data, png_size_t length) +{ + png_uint_32 check; + + WRITEFILE((png_FILE_p)png_ptr->io_ptr, data, length, check); + if (check != length) + { + png_error(png_ptr, "Write Error"); + } +} +#else +/* this is the model-independent version. Since the standard I/O library + can't handle far buffers in the medium and small models, we have to copy + the data. +*/ + +#define NEAR_BUF_SIZE 1024 +#define MIN(a,b) (a <= b ? a : b) + +static void +pngtest_write_data(png_structp png_ptr, png_bytep data, png_size_t length) +{ + png_uint_32 check; + png_byte *near_data; /* Needs to be "png_byte *" instead of "png_bytep" */ + png_FILE_p io_ptr; + + /* Check if data really is near. If so, use usual code. */ + near_data = (png_byte *)CVT_PTR_NOCHECK(data); + io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr); + if ((png_bytep)near_data == data) + { + WRITEFILE(io_ptr, near_data, length, check); + } + else + { + png_byte buf[NEAR_BUF_SIZE]; + png_size_t written, remaining, err; + check = 0; + remaining = length; + do + { + written = MIN(NEAR_BUF_SIZE, remaining); + png_memcpy(buf, data, written); /* copy far buffer to near buffer */ + WRITEFILE(io_ptr, buf, written, err); + if (err != written) + break; + else + check += err; + data += written; + remaining -= written; + } + while (remaining != 0); + } + if (check != length) + { + png_error(png_ptr, "Write Error"); + } +} + +#endif /* USE_FAR_KEYWORD */ + +/* This function is called when there is a warning, but the library thinks + * it can continue anyway. Replacement functions don't have to do anything + * here if you don't want to. In the default configuration, png_ptr is + * not used, but it is passed in case it may be useful. + */ +static void +pngtest_warning(png_structp png_ptr, png_const_charp message) +{ + PNG_CONST char *name = "UNKNOWN (ERROR!)"; + if (png_ptr != NULL && png_ptr->error_ptr != NULL) + name = png_ptr->error_ptr; + fprintf(STDERR, "%s: libpng warning: %s\n", name, message); +} + +/* This is the default error handling function. Note that replacements for + * this function MUST NOT RETURN, or the program will likely crash. This + * function is used by default, or if the program supplies NULL for the + * error function pointer in png_set_error_fn(). + */ +static void +pngtest_error(png_structp png_ptr, png_const_charp message) +{ + pngtest_warning(png_ptr, message); + /* We can return because png_error calls the default handler, which is + * actually OK in this case. */ +} +#endif /* PNG_NO_STDIO */ +/* END of code to validate stdio-free compilation */ + +/* START of code to validate memory allocation and deallocation */ +#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG + +/* Allocate memory. For reasonable files, size should never exceed + 64K. However, zlib may allocate more then 64K if you don't tell + it not to. See zconf.h and png.h for more information. zlib does + need to allocate exactly 64K, so whatever you call here must + have the ability to do that. + + This piece of code can be compiled to validate max 64K allocations + by setting MAXSEG_64K in zlib zconf.h *or* PNG_MAX_MALLOC_64K. */ +typedef struct memory_information +{ + png_uint_32 size; + png_voidp pointer; + struct memory_information FAR *next; +} memory_information; +typedef memory_information FAR *memory_infop; + +static memory_infop pinformation = NULL; +static int current_allocation = 0; +static int maximum_allocation = 0; +static int total_allocation = 0; +static int num_allocations = 0; + +png_voidp png_debug_malloc PNGARG((png_structp png_ptr, png_uint_32 size)); +void png_debug_free PNGARG((png_structp png_ptr, png_voidp ptr)); + +png_voidp +png_debug_malloc(png_structp png_ptr, png_uint_32 size) +{ + + /* png_malloc has already tested for NULL; png_create_struct calls + png_debug_malloc directly, with png_ptr == NULL which is OK */ + + if (size == 0) + return (NULL); + + /* This calls the library allocator twice, once to get the requested + buffer and once to get a new free list entry. */ + { + /* Disable malloc_fn and free_fn */ + memory_infop pinfo; + png_set_mem_fn(png_ptr, NULL, NULL, NULL); + pinfo = (memory_infop)png_malloc(png_ptr, + (png_uint_32)png_sizeof (*pinfo)); + pinfo->size = size; + current_allocation += size; + total_allocation += size; + num_allocations ++; + if (current_allocation > maximum_allocation) + maximum_allocation = current_allocation; + pinfo->pointer = (png_voidp)png_malloc(png_ptr, size); + /* Restore malloc_fn and free_fn */ + png_set_mem_fn(png_ptr, png_voidp_NULL, (png_malloc_ptr)png_debug_malloc, + (png_free_ptr)png_debug_free); + if (size != 0 && pinfo->pointer == NULL) + { + current_allocation -= size; + total_allocation -= size; + png_error(png_ptr, + "out of memory in pngtest->png_debug_malloc."); + } + pinfo->next = pinformation; + pinformation = pinfo; + /* Make sure the caller isn't assuming zeroed memory. */ + png_memset(pinfo->pointer, 0xdd, pinfo->size); + if(verbose) + printf("png_malloc %lu bytes at %x\n",size,pinfo->pointer); + return (png_voidp)(pinfo->pointer); + } +} + +/* Free a pointer. It is removed from the list at the same time. */ +void +png_debug_free(png_structp png_ptr, png_voidp ptr) +{ + if (png_ptr == NULL) + fprintf(STDERR, "NULL pointer to png_debug_free.\n"); + if (ptr == 0) + { +#if 0 /* This happens all the time. */ + fprintf(STDERR, "WARNING: freeing NULL pointer\n"); +#endif + return; + } + + /* Unlink the element from the list. */ + { + memory_infop FAR *ppinfo = &pinformation; + for (;;) + { + memory_infop pinfo = *ppinfo; + if (pinfo->pointer == ptr) + { + *ppinfo = pinfo->next; + current_allocation -= pinfo->size; + if (current_allocation < 0) + fprintf(STDERR, "Duplicate free of memory\n"); + /* We must free the list element too, but first kill + the memory that is to be freed. */ + png_memset(ptr, 0x55, pinfo->size); + png_free_default(png_ptr, pinfo); + pinfo=NULL; + break; + } + if (pinfo->next == NULL) + { + fprintf(STDERR, "Pointer %x not found\n", (unsigned int)ptr); + break; + } + ppinfo = &pinfo->next; + } + } + + /* Finally free the data. */ + if(verbose) + printf("Freeing %x\n",ptr); + png_free_default(png_ptr, ptr); + ptr=NULL; +} +#endif /* PNG_USER_MEM_SUPPORTED && PNG_DEBUG */ +/* END of code to test memory allocation/deallocation */ + +/* Test one file */ +int +test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) +{ + static png_FILE_p fpin; + static png_FILE_p fpout; /* "static" prevents setjmp corruption */ + png_structp read_ptr; + png_infop read_info_ptr, end_info_ptr; +#ifdef PNG_WRITE_SUPPORTED + png_structp write_ptr; + png_infop write_info_ptr; + png_infop write_end_info_ptr; +#else + png_structp write_ptr = NULL; + png_infop write_info_ptr = NULL; + png_infop write_end_info_ptr = NULL; +#endif + png_bytep row_buf; + png_uint_32 y; + png_uint_32 width, height; + int num_pass, pass; + int bit_depth, color_type; +#ifdef PNG_SETJMP_SUPPORTED +#ifdef USE_FAR_KEYWORD + jmp_buf jmpbuf; +#endif +#endif + +#if defined(_WIN32_WCE) + TCHAR path[MAX_PATH]; +#endif + char inbuf[256], outbuf[256]; + + row_buf = NULL; + +#if defined(_WIN32_WCE) + MultiByteToWideChar(CP_ACP, 0, inname, -1, path, MAX_PATH); + if ((fpin = CreateFile(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE) +#else + if ((fpin = fopen(inname, "rb")) == NULL) +#endif + { + fprintf(STDERR, "Could not find input file %s\n", inname); + return (1); + } + +#if defined(_WIN32_WCE) + MultiByteToWideChar(CP_ACP, 0, outname, -1, path, MAX_PATH); + if ((fpout = CreateFile(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL)) == INVALID_HANDLE_VALUE) +#else + if ((fpout = fopen(outname, "wb")) == NULL) +#endif + { + fprintf(STDERR, "Could not open output file %s\n", outname); + FCLOSE(fpin); + return (1); + } + + png_debug(0, "Allocating read and write structures\n"); +#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG + read_ptr = png_create_read_struct_2(PNG_LIBPNG_VER_STRING, png_voidp_NULL, + png_error_ptr_NULL, png_error_ptr_NULL, png_voidp_NULL, + (png_malloc_ptr)png_debug_malloc, (png_free_ptr)png_debug_free); +#else + read_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, png_voidp_NULL, + png_error_ptr_NULL, png_error_ptr_NULL); +#endif +#if defined(PNG_NO_STDIO) + png_set_error_fn(read_ptr, (png_voidp)inname, pngtest_error, + pngtest_warning); +#endif +#ifdef PNG_WRITE_SUPPORTED +#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG + write_ptr = png_create_write_struct_2(PNG_LIBPNG_VER_STRING, png_voidp_NULL, + png_error_ptr_NULL, png_error_ptr_NULL, png_voidp_NULL, + (png_malloc_ptr)png_debug_malloc, (png_free_ptr)png_debug_free); +#else + write_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, png_voidp_NULL, + png_error_ptr_NULL, png_error_ptr_NULL); +#endif +#if defined(PNG_NO_STDIO) + png_set_error_fn(write_ptr, (png_voidp)inname, pngtest_error, + pngtest_warning); +#endif +#endif + png_debug(0, "Allocating read_info, write_info and end_info structures\n"); + read_info_ptr = png_create_info_struct(read_ptr); + end_info_ptr = png_create_info_struct(read_ptr); +#ifdef PNG_WRITE_SUPPORTED + write_info_ptr = png_create_info_struct(write_ptr); + write_end_info_ptr = png_create_info_struct(write_ptr); +#endif + +#ifdef PNG_SETJMP_SUPPORTED + png_debug(0, "Setting jmpbuf for read struct\n"); +#ifdef USE_FAR_KEYWORD + if (setjmp(jmpbuf)) +#else + if (setjmp(png_jmpbuf(read_ptr))) +#endif + { + fprintf(STDERR, "%s -> %s: libpng read error\n", inname, outname); + if (row_buf) + png_free(read_ptr, row_buf); + png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr); +#ifdef PNG_WRITE_SUPPORTED + png_destroy_info_struct(write_ptr, &write_end_info_ptr); + png_destroy_write_struct(&write_ptr, &write_info_ptr); +#endif + FCLOSE(fpin); + FCLOSE(fpout); + return (1); + } +#ifdef USE_FAR_KEYWORD + png_memcpy(png_jmpbuf(read_ptr),jmpbuf,png_sizeof(jmp_buf)); +#endif + +#ifdef PNG_WRITE_SUPPORTED + png_debug(0, "Setting jmpbuf for write struct\n"); +#ifdef USE_FAR_KEYWORD + if (setjmp(jmpbuf)) +#else + if (setjmp(png_jmpbuf(write_ptr))) +#endif + { + fprintf(STDERR, "%s -> %s: libpng write error\n", inname, outname); + png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr); + png_destroy_info_struct(write_ptr, &write_end_info_ptr); +#ifdef PNG_WRITE_SUPPORTED + png_destroy_write_struct(&write_ptr, &write_info_ptr); +#endif + FCLOSE(fpin); + FCLOSE(fpout); + return (1); + } +#ifdef USE_FAR_KEYWORD + png_memcpy(png_jmpbuf(write_ptr),jmpbuf,png_sizeof(jmp_buf)); +#endif +#endif +#endif + + png_debug(0, "Initializing input and output streams\n"); +#if !defined(PNG_NO_STDIO) + png_init_io(read_ptr, fpin); +# ifdef PNG_WRITE_SUPPORTED + png_init_io(write_ptr, fpout); +# endif +#else + png_set_read_fn(read_ptr, (png_voidp)fpin, pngtest_read_data); +# ifdef PNG_WRITE_SUPPORTED + png_set_write_fn(write_ptr, (png_voidp)fpout, pngtest_write_data, +# if defined(PNG_WRITE_FLUSH_SUPPORTED) + pngtest_flush); +# else + NULL); +# endif +# endif +#endif + if(status_dots_requested == 1) + { +#ifdef PNG_WRITE_SUPPORTED + png_set_write_status_fn(write_ptr, write_row_callback); +#endif + png_set_read_status_fn(read_ptr, read_row_callback); + } + else + { +#ifdef PNG_WRITE_SUPPORTED + png_set_write_status_fn(write_ptr, png_write_status_ptr_NULL); +#endif + png_set_read_status_fn(read_ptr, png_read_status_ptr_NULL); + } + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) + { + int i; + for(i=0; i<256; i++) + filters_used[i]=0; + png_set_read_user_transform_fn(read_ptr, count_filters); + } +#endif +#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) + zero_samples=0; + png_set_write_user_transform_fn(write_ptr, count_zero_samples); +#endif + +#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) +# ifndef PNG_HANDLE_CHUNK_ALWAYS +# define PNG_HANDLE_CHUNK_ALWAYS 3 +# endif + png_set_keep_unknown_chunks(read_ptr, PNG_HANDLE_CHUNK_ALWAYS, + png_bytep_NULL, 0); +#endif +#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED) +# ifndef PNG_HANDLE_CHUNK_IF_SAFE +# define PNG_HANDLE_CHUNK_IF_SAFE 2 +# endif + png_set_keep_unknown_chunks(write_ptr, PNG_HANDLE_CHUNK_IF_SAFE, + png_bytep_NULL, 0); +#endif + + png_debug(0, "Reading info struct\n"); + png_read_info(read_ptr, read_info_ptr); + + png_debug(0, "Transferring info struct\n"); + { + int interlace_type, compression_type, filter_type; + + if (png_get_IHDR(read_ptr, read_info_ptr, &width, &height, &bit_depth, + &color_type, &interlace_type, &compression_type, &filter_type)) + { + png_set_IHDR(write_ptr, write_info_ptr, width, height, bit_depth, +#if defined(PNG_WRITE_INTERLACING_SUPPORTED) + color_type, interlace_type, compression_type, filter_type); +#else + color_type, PNG_INTERLACE_NONE, compression_type, filter_type); +#endif + } + } +#if defined(PNG_FIXED_POINT_SUPPORTED) +#if defined(PNG_cHRM_SUPPORTED) + { + png_fixed_point white_x, white_y, red_x, red_y, green_x, green_y, blue_x, + blue_y; + if (png_get_cHRM_fixed(read_ptr, read_info_ptr, &white_x, &white_y, &red_x, + &red_y, &green_x, &green_y, &blue_x, &blue_y)) + { + png_set_cHRM_fixed(write_ptr, write_info_ptr, white_x, white_y, red_x, + red_y, green_x, green_y, blue_x, blue_y); + } + } +#endif +#if defined(PNG_gAMA_SUPPORTED) + { + png_fixed_point gamma; + + if (png_get_gAMA_fixed(read_ptr, read_info_ptr, &gamma)) + { + png_set_gAMA_fixed(write_ptr, write_info_ptr, gamma); + } + } +#endif +#else /* Use floating point versions */ +#if defined(PNG_FLOATING_POINT_SUPPORTED) +#if defined(PNG_cHRM_SUPPORTED) + { + double white_x, white_y, red_x, red_y, green_x, green_y, blue_x, + blue_y; + if (png_get_cHRM(read_ptr, read_info_ptr, &white_x, &white_y, &red_x, + &red_y, &green_x, &green_y, &blue_x, &blue_y)) + { + png_set_cHRM(write_ptr, write_info_ptr, white_x, white_y, red_x, + red_y, green_x, green_y, blue_x, blue_y); + } + } +#endif +#if defined(PNG_gAMA_SUPPORTED) + { + double gamma; + + if (png_get_gAMA(read_ptr, read_info_ptr, &gamma)) + { + png_set_gAMA(write_ptr, write_info_ptr, gamma); + } + } +#endif +#endif /* floating point */ +#endif /* fixed point */ +#if defined(PNG_iCCP_SUPPORTED) + { + png_charp name; + png_charp profile; + png_uint_32 proflen; + int compression_type; + + if (png_get_iCCP(read_ptr, read_info_ptr, &name, &compression_type, + &profile, &proflen)) + { + png_set_iCCP(write_ptr, write_info_ptr, name, compression_type, + profile, proflen); + } + } +#endif +#if defined(PNG_sRGB_SUPPORTED) + { + int intent; + + if (png_get_sRGB(read_ptr, read_info_ptr, &intent)) + { + png_set_sRGB(write_ptr, write_info_ptr, intent); + } + } +#endif + { + png_colorp palette; + int num_palette; + + if (png_get_PLTE(read_ptr, read_info_ptr, &palette, &num_palette)) + { + png_set_PLTE(write_ptr, write_info_ptr, palette, num_palette); + } + } +#if defined(PNG_bKGD_SUPPORTED) + { + png_color_16p background; + + if (png_get_bKGD(read_ptr, read_info_ptr, &background)) + { + png_set_bKGD(write_ptr, write_info_ptr, background); + } + } +#endif +#if defined(PNG_hIST_SUPPORTED) + { + png_uint_16p hist; + + if (png_get_hIST(read_ptr, read_info_ptr, &hist)) + { + png_set_hIST(write_ptr, write_info_ptr, hist); + } + } +#endif +#if defined(PNG_oFFs_SUPPORTED) + { + png_int_32 offset_x, offset_y; + int unit_type; + + if (png_get_oFFs(read_ptr, read_info_ptr,&offset_x,&offset_y,&unit_type)) + { + png_set_oFFs(write_ptr, write_info_ptr, offset_x, offset_y, unit_type); + } + } +#endif +#if defined(PNG_pCAL_SUPPORTED) + { + png_charp purpose, units; + png_charpp params; + png_int_32 X0, X1; + int type, nparams; + + if (png_get_pCAL(read_ptr, read_info_ptr, &purpose, &X0, &X1, &type, + &nparams, &units, ¶ms)) + { + png_set_pCAL(write_ptr, write_info_ptr, purpose, X0, X1, type, + nparams, units, params); + } + } +#endif +#if defined(PNG_pHYs_SUPPORTED) + { + png_uint_32 res_x, res_y; + int unit_type; + + if (png_get_pHYs(read_ptr, read_info_ptr, &res_x, &res_y, &unit_type)) + { + png_set_pHYs(write_ptr, write_info_ptr, res_x, res_y, unit_type); + } + } +#endif +#if defined(PNG_sBIT_SUPPORTED) + { + png_color_8p sig_bit; + + if (png_get_sBIT(read_ptr, read_info_ptr, &sig_bit)) + { + png_set_sBIT(write_ptr, write_info_ptr, sig_bit); + } + } +#endif +#if defined(PNG_sCAL_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED + { + int unit; + double scal_width, scal_height; + + if (png_get_sCAL(read_ptr, read_info_ptr, &unit, &scal_width, + &scal_height)) + { + png_set_sCAL(write_ptr, write_info_ptr, unit, scal_width, scal_height); + } + } +#else +#ifdef PNG_FIXED_POINT_SUPPORTED + { + int unit; + png_charp scal_width, scal_height; + + if (png_get_sCAL_s(read_ptr, read_info_ptr, &unit, &scal_width, + &scal_height)) + { + png_set_sCAL_s(write_ptr, write_info_ptr, unit, scal_width, scal_height); + } + } +#endif +#endif +#endif +#if defined(PNG_TEXT_SUPPORTED) + { + png_textp text_ptr; + int num_text; + + if (png_get_text(read_ptr, read_info_ptr, &text_ptr, &num_text) > 0) + { + png_debug1(0, "Handling %d iTXt/tEXt/zTXt chunks\n", num_text); + png_set_text(write_ptr, write_info_ptr, text_ptr, num_text); + } + } +#endif +#if defined(PNG_tIME_SUPPORTED) + { + png_timep mod_time; + + if (png_get_tIME(read_ptr, read_info_ptr, &mod_time)) + { + png_set_tIME(write_ptr, write_info_ptr, mod_time); +#if defined(PNG_TIME_RFC1123_SUPPORTED) + /* we have to use png_strcpy instead of "=" because the string + pointed to by png_convert_to_rfc1123() gets free'ed before + we use it */ + png_strcpy(tIME_string,png_convert_to_rfc1123(read_ptr, mod_time)); + tIME_chunk_present++; +#endif /* PNG_TIME_RFC1123_SUPPORTED */ + } + } +#endif +#if defined(PNG_tRNS_SUPPORTED) + { + png_bytep trans; + int num_trans; + png_color_16p trans_values; + + if (png_get_tRNS(read_ptr, read_info_ptr, &trans, &num_trans, + &trans_values)) + { + png_set_tRNS(write_ptr, write_info_ptr, trans, num_trans, + trans_values); + } + } +#endif +#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED) + { + png_unknown_chunkp unknowns; + int num_unknowns = (int)png_get_unknown_chunks(read_ptr, read_info_ptr, + &unknowns); + if (num_unknowns) + { + png_size_t i; + png_set_unknown_chunks(write_ptr, write_info_ptr, unknowns, + num_unknowns); + /* copy the locations from the read_info_ptr. The automatically + generated locations in write_info_ptr are wrong because we + haven't written anything yet */ + for (i = 0; i < (png_size_t)num_unknowns; i++) + png_set_unknown_chunk_location(write_ptr, write_info_ptr, i, + unknowns[i].location); + } + } +#endif + +#ifdef PNG_WRITE_SUPPORTED + png_debug(0, "\nWriting info struct\n"); + +/* If we wanted, we could write info in two steps: + png_write_info_before_PLTE(write_ptr, write_info_ptr); + */ + png_write_info(write_ptr, write_info_ptr); +#endif + +#ifdef SINGLE_ROWBUF_ALLOC + png_debug(0, "\nAllocating row buffer..."); + row_buf = (png_bytep)png_malloc(read_ptr, + png_get_rowbytes(read_ptr, read_info_ptr)); + png_debug1(0, "0x%08lx\n\n", (unsigned long)row_buf); +#endif /* SINGLE_ROWBUF_ALLOC */ + png_debug(0, "Writing row data\n"); + +#if defined(PNG_READ_INTERLACING_SUPPORTED) || \ + defined(PNG_WRITE_INTERLACING_SUPPORTED) + num_pass = png_set_interlace_handling(read_ptr); +# ifdef PNG_WRITE_SUPPORTED + png_set_interlace_handling(write_ptr); +# endif +#else + num_pass=1; +#endif + +#ifdef PNGTEST_TIMING + t_stop = (float)clock(); + t_misc += (t_stop - t_start); + t_start = t_stop; +#endif + for (pass = 0; pass < num_pass; pass++) + { + png_debug1(0, "Writing row data for pass %d\n",pass); + for (y = 0; y < height; y++) + { +#ifndef SINGLE_ROWBUF_ALLOC + png_debug2(0, "\nAllocating row buffer (pass %d, y = %ld)...", pass,y); + row_buf = (png_bytep)png_malloc(read_ptr, + png_get_rowbytes(read_ptr, read_info_ptr)); + png_debug2(0, "0x%08lx (%ld bytes)\n", (unsigned long)row_buf, + png_get_rowbytes(read_ptr, read_info_ptr)); +#endif /* !SINGLE_ROWBUF_ALLOC */ + png_read_rows(read_ptr, (png_bytepp)&row_buf, png_bytepp_NULL, 1); + +#ifdef PNG_WRITE_SUPPORTED +#ifdef PNGTEST_TIMING + t_stop = (float)clock(); + t_decode += (t_stop - t_start); + t_start = t_stop; +#endif + png_write_rows(write_ptr, (png_bytepp)&row_buf, 1); +#ifdef PNGTEST_TIMING + t_stop = (float)clock(); + t_encode += (t_stop - t_start); + t_start = t_stop; +#endif +#endif /* PNG_WRITE_SUPPORTED */ + +#ifndef SINGLE_ROWBUF_ALLOC + png_debug2(0, "Freeing row buffer (pass %d, y = %ld)\n\n", pass, y); + png_free(read_ptr, row_buf); +#endif /* !SINGLE_ROWBUF_ALLOC */ + } + } + +#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) + png_free_data(read_ptr, read_info_ptr, PNG_FREE_UNKN, -1); +#endif +#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED) + png_free_data(write_ptr, write_info_ptr, PNG_FREE_UNKN, -1); +#endif + + png_debug(0, "Reading and writing end_info data\n"); + + png_read_end(read_ptr, end_info_ptr); +#if defined(PNG_TEXT_SUPPORTED) + { + png_textp text_ptr; + int num_text; + + if (png_get_text(read_ptr, end_info_ptr, &text_ptr, &num_text) > 0) + { + png_debug1(0, "Handling %d iTXt/tEXt/zTXt chunks\n", num_text); + png_set_text(write_ptr, write_end_info_ptr, text_ptr, num_text); + } + } +#endif +#if defined(PNG_tIME_SUPPORTED) + { + png_timep mod_time; + + if (png_get_tIME(read_ptr, end_info_ptr, &mod_time)) + { + png_set_tIME(write_ptr, write_end_info_ptr, mod_time); +#if defined(PNG_TIME_RFC1123_SUPPORTED) + /* we have to use png_strcpy instead of "=" because the string + pointed to by png_convert_to_rfc1123() gets free'ed before + we use it */ + png_strcpy(tIME_string,png_convert_to_rfc1123(read_ptr, mod_time)); + tIME_chunk_present++; +#endif /* PNG_TIME_RFC1123_SUPPORTED */ + } + } +#endif +#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED) + { + png_unknown_chunkp unknowns; + int num_unknowns; + num_unknowns = (int)png_get_unknown_chunks(read_ptr, end_info_ptr, + &unknowns); + if (num_unknowns) + { + png_size_t i; + png_set_unknown_chunks(write_ptr, write_end_info_ptr, unknowns, + num_unknowns); + /* copy the locations from the read_info_ptr. The automatically + generated locations in write_end_info_ptr are wrong because we + haven't written the end_info yet */ + for (i = 0; i < (png_size_t)num_unknowns; i++) + png_set_unknown_chunk_location(write_ptr, write_end_info_ptr, i, + unknowns[i].location); + } + } +#endif +#ifdef PNG_WRITE_SUPPORTED + png_write_end(write_ptr, write_end_info_ptr); +#endif + +#ifdef PNG_EASY_ACCESS_SUPPORTED + if(verbose) + { + png_uint_32 iwidth, iheight; + iwidth = png_get_image_width(write_ptr, write_info_ptr); + iheight = png_get_image_height(write_ptr, write_info_ptr); + fprintf(STDERR, "Image width = %lu, height = %lu\n", + iwidth, iheight); + } +#endif + + png_debug(0, "Destroying data structs\n"); +#ifdef SINGLE_ROWBUF_ALLOC + png_debug(1, "destroying row_buf for read_ptr\n"); + png_free(read_ptr, row_buf); + row_buf=NULL; +#endif /* SINGLE_ROWBUF_ALLOC */ + png_debug(1, "destroying read_ptr, read_info_ptr, end_info_ptr\n"); + png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr); +#ifdef PNG_WRITE_SUPPORTED + png_debug(1, "destroying write_end_info_ptr\n"); + png_destroy_info_struct(write_ptr, &write_end_info_ptr); + png_debug(1, "destroying write_ptr, write_info_ptr\n"); + png_destroy_write_struct(&write_ptr, &write_info_ptr); +#endif + png_debug(0, "Destruction complete.\n"); + + FCLOSE(fpin); + FCLOSE(fpout); + + png_debug(0, "Opening files for comparison\n"); +#if defined(_WIN32_WCE) + MultiByteToWideChar(CP_ACP, 0, inname, -1, path, MAX_PATH); + if ((fpin = CreateFile(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE) +#else + if ((fpin = fopen(inname, "rb")) == NULL) +#endif + { + fprintf(STDERR, "Could not find file %s\n", inname); + return (1); + } + +#if defined(_WIN32_WCE) + MultiByteToWideChar(CP_ACP, 0, outname, -1, path, MAX_PATH); + if ((fpout = CreateFile(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE) +#else + if ((fpout = fopen(outname, "rb")) == NULL) +#endif + { + fprintf(STDERR, "Could not find file %s\n", outname); + FCLOSE(fpin); + return (1); + } + + for(;;) + { + png_size_t num_in, num_out; + + READFILE(fpin, inbuf, 1, num_in); + READFILE(fpout, outbuf, 1, num_out); + + if (num_in != num_out) + { + fprintf(STDERR, "\nFiles %s and %s are of a different size\n", + inname, outname); + if(wrote_question == 0) + { + fprintf(STDERR, + " Was %s written with the same maximum IDAT chunk size (%d bytes),", + inname,PNG_ZBUF_SIZE); + fprintf(STDERR, + "\n filtering heuristic (libpng default), compression"); + fprintf(STDERR, + " level (zlib default),\n and zlib version (%s)?\n\n", + ZLIB_VERSION); + wrote_question=1; + } + FCLOSE(fpin); + FCLOSE(fpout); + return (0); + } + + if (!num_in) + break; + + if (png_memcmp(inbuf, outbuf, num_in)) + { + fprintf(STDERR, "\nFiles %s and %s are different\n", inname, outname); + if(wrote_question == 0) + { + fprintf(STDERR, + " Was %s written with the same maximum IDAT chunk size (%d bytes),", + inname,PNG_ZBUF_SIZE); + fprintf(STDERR, + "\n filtering heuristic (libpng default), compression"); + fprintf(STDERR, + " level (zlib default),\n and zlib version (%s)?\n\n", + ZLIB_VERSION); + wrote_question=1; + } + FCLOSE(fpin); + FCLOSE(fpout); + return (0); + } + } + + FCLOSE(fpin); + FCLOSE(fpout); + + return (0); +} + +/* input and output filenames */ +#ifdef RISCOS +static PNG_CONST char *inname = "pngtest/png"; +static PNG_CONST char *outname = "pngout/png"; +#else +static PNG_CONST char *inname = "pngtest.png"; +static PNG_CONST char *outname = "pngout.png"; +#endif + +int +main(int argc, char *argv[]) +{ + int multiple = 0; + int ierror = 0; + + fprintf(STDERR, "Testing libpng version %s\n", PNG_LIBPNG_VER_STRING); + fprintf(STDERR, " with zlib version %s\n", ZLIB_VERSION); + fprintf(STDERR,"%s",png_get_copyright(NULL)); + /* Show the version of libpng used in building the library */ + fprintf(STDERR," library (%lu):%s", png_access_version_number(), + png_get_header_version(NULL)); + /* Show the version of libpng used in building the application */ + fprintf(STDERR," pngtest (%lu):%s", (unsigned long)PNG_LIBPNG_VER, + PNG_HEADER_VERSION_STRING); + fprintf(STDERR," png_sizeof(png_struct)=%ld, png_sizeof(png_info)=%ld\n", + (long)png_sizeof(png_struct), (long)png_sizeof(png_info)); + + /* Do some consistency checking on the memory allocation settings, I'm + not sure this matters, but it is nice to know, the first of these + tests should be impossible because of the way the macros are set + in pngconf.h */ +#if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K) + fprintf(STDERR, " NOTE: Zlib compiled for max 64k, libpng not\n"); +#endif + /* I think the following can happen. */ +#if !defined(MAXSEG_64K) && defined(PNG_MAX_MALLOC_64K) + fprintf(STDERR, " NOTE: libpng compiled for max 64k, zlib not\n"); +#endif + + if (strcmp(png_libpng_ver, PNG_LIBPNG_VER_STRING)) + { + fprintf(STDERR, + "Warning: versions are different between png.h and png.c\n"); + fprintf(STDERR, " png.h version: %s\n", PNG_LIBPNG_VER_STRING); + fprintf(STDERR, " png.c version: %s\n\n", png_libpng_ver); + ++ierror; + } + + if (argc > 1) + { + if (strcmp(argv[1], "-m") == 0) + { + multiple = 1; + status_dots_requested = 0; + } + else if (strcmp(argv[1], "-mv") == 0 || + strcmp(argv[1], "-vm") == 0 ) + { + multiple = 1; + verbose = 1; + status_dots_requested = 1; + } + else if (strcmp(argv[1], "-v") == 0) + { + verbose = 1; + status_dots_requested = 1; + inname = argv[2]; + } + else + { + inname = argv[1]; + status_dots_requested = 0; + } + } + + if (!multiple && argc == 3+verbose) + outname = argv[2+verbose]; + + if ((!multiple && argc > 3+verbose) || (multiple && argc < 2)) + { + fprintf(STDERR, + "usage: %s [infile.png] [outfile.png]\n\t%s -m {infile.png}\n", + argv[0], argv[0]); + fprintf(STDERR, + " reads/writes one PNG file (without -m) or multiple files (-m)\n"); + fprintf(STDERR, + " with -m %s is used as a temporary file\n", outname); + exit(1); + } + + if (multiple) + { + int i; +#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG + int allocation_now = current_allocation; +#endif + for (i=2; i<argc; ++i) + { +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) + int k; +#endif + int kerror; + fprintf(STDERR, "Testing %s:",argv[i]); + kerror = test_one_file(argv[i], outname); + if (kerror == 0) + { +#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) + fprintf(STDERR, "\n PASS (%lu zero samples)\n",zero_samples); +#else + fprintf(STDERR, " PASS\n"); +#endif +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) + for (k=0; k<256; k++) + if(filters_used[k]) + fprintf(STDERR, " Filter %d was used %lu times\n", + k,filters_used[k]); +#endif +#if defined(PNG_TIME_RFC1123_SUPPORTED) + if(tIME_chunk_present != 0) + fprintf(STDERR, " tIME = %s\n",tIME_string); + tIME_chunk_present = 0; +#endif /* PNG_TIME_RFC1123_SUPPORTED */ + } + else + { + fprintf(STDERR, " FAIL\n"); + ierror += kerror; + } +#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG + if (allocation_now != current_allocation) + fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n", + current_allocation-allocation_now); + if (current_allocation != 0) + { + memory_infop pinfo = pinformation; + + fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n", + current_allocation); + while (pinfo != NULL) + { + fprintf(STDERR, " %lu bytes at %x\n", pinfo->size, + (unsigned int) pinfo->pointer); + pinfo = pinfo->next; + } + } +#endif + } +#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG + fprintf(STDERR, " Current memory allocation: %10d bytes\n", + current_allocation); + fprintf(STDERR, " Maximum memory allocation: %10d bytes\n", + maximum_allocation); + fprintf(STDERR, " Total memory allocation: %10d bytes\n", + total_allocation); + fprintf(STDERR, " Number of allocations: %10d\n", + num_allocations); +#endif + } + else + { + int i; + for (i=0; i<3; ++i) + { + int kerror; +#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG + int allocation_now = current_allocation; +#endif + if (i == 1) status_dots_requested = 1; + else if(verbose == 0)status_dots_requested = 0; + if (i == 0 || verbose == 1 || ierror != 0) + fprintf(STDERR, "Testing %s:",inname); + kerror = test_one_file(inname, outname); + if(kerror == 0) + { + if(verbose == 1 || i == 2) + { +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) + int k; +#endif +#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) + fprintf(STDERR, "\n PASS (%lu zero samples)\n",zero_samples); +#else + fprintf(STDERR, " PASS\n"); +#endif +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) + for (k=0; k<256; k++) + if(filters_used[k]) + fprintf(STDERR, " Filter %d was used %lu times\n", + k,filters_used[k]); +#endif +#if defined(PNG_TIME_RFC1123_SUPPORTED) + if(tIME_chunk_present != 0) + fprintf(STDERR, " tIME = %s\n",tIME_string); +#endif /* PNG_TIME_RFC1123_SUPPORTED */ + } + } + else + { + if(verbose == 0 && i != 2) + fprintf(STDERR, "Testing %s:",inname); + fprintf(STDERR, " FAIL\n"); + ierror += kerror; + } +#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG + if (allocation_now != current_allocation) + fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n", + current_allocation-allocation_now); + if (current_allocation != 0) + { + memory_infop pinfo = pinformation; + + fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n", + current_allocation); + while (pinfo != NULL) + { + fprintf(STDERR," %lu bytes at %x\n", + pinfo->size, (unsigned int)pinfo->pointer); + pinfo = pinfo->next; + } + } +#endif + } +#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG + fprintf(STDERR, " Current memory allocation: %10d bytes\n", + current_allocation); + fprintf(STDERR, " Maximum memory allocation: %10d bytes\n", + maximum_allocation); + fprintf(STDERR, " Total memory allocation: %10d bytes\n", + total_allocation); + fprintf(STDERR, " Number of allocations: %10d\n", + num_allocations); +#endif + } + +#ifdef PNGTEST_TIMING + t_stop = (float)clock(); + t_misc += (t_stop - t_start); + t_start = t_stop; + fprintf(STDERR," CPU time used = %.3f seconds", + (t_misc+t_decode+t_encode)/(float)CLOCKS_PER_SEC); + fprintf(STDERR," (decoding %.3f,\n", + t_decode/(float)CLOCKS_PER_SEC); + fprintf(STDERR," encoding %.3f ,", + t_encode/(float)CLOCKS_PER_SEC); + fprintf(STDERR," other %.3f seconds)\n\n", + t_misc/(float)CLOCKS_PER_SEC); +#endif + + if (ierror == 0) + fprintf(STDERR, "libpng passes test\n"); + else + fprintf(STDERR, "libpng FAILS test\n"); + return (int)(ierror != 0); +} + +/* Generate a compiler error if there is an old png.h in the search path. */ +typedef version_1_2_12 your_png_h_is_not_version_1_2_12; diff --git a/mod/pub.mod/libpng.mod/pngtest.png b/mod/pub.mod/libpng.mod/pngtest.png new file mode 100644 index 0000000000000000000000000000000000000000..f3a6df4483fc9d020c028d4e4f417767bfa72877 GIT binary patch literal 8574 zcmV-^A%WhBP)<h;3K|Lk000e1NJLTq003J6002b@1^@s7Qthhb00004XF*Lt006O% z3;baP00004b3#c}1qB5KO{FdN00006VoOIv0N?=N0DzUvFCYK_010nKMsolF00000 z00054ErwVC001m-LqSYpZ)bILAa!nObaMaz000000RR600%mV-FJfVG05L8wWiS9X zH7+$XHDxnbKzkej000SaNLh0L01FZT01FZU(%pXi00007bV*G`2h0Ws5jqHt|0a3> z000SeMObuHX>@F508max+yQwt001AiNkl<Zc%1E=PiSPxo##I}lY-v^2_nFP7lty# zKo2~@8d3*C=7JBo-~koPAq8uw+MDJuP<>O)sr#@4<(ul(br`VbraBmuhk@3?%j97U znXm>WOoQH`mkmQV#Dgk$0iE!|kWKC(UZ$ifRdrR{?y-0LgGZ$*Gb7{uBI5Vw`}_VL z{2^pm*wxREhAV)-c=gTo8wWkR0{G-;xXP6<o;m=!01t-6dFAWTuxA)wx~C%K0zBv! zE2D(xv$6w_E9w6Q!1GCYm@7?T3`*qq$-|*{p&kRon11b`XIE8-v(1!3jFhe>%b;|g zqv8I@RW)^t7%eD~>nQ>F*f4b!06nYt@O07vs6LIyqkVe<@%GI=8WyVu!(s*S(Wtjd zU(82uRNY!T->v-XN2ArS$X5V=dGn1YqyG7%{PGt7XU7MtdHKc8=PzFjmdlKMM?UM^ zob$|iirnz{`J^*FIa-}hE}4{WHg{nFts1NPT7|xL{NGPcR<p?zV+7-M-}LlqSmf6_ z2QXT=@-;tudOB_zMxkAxrh%R{X_MtTqg^oejOKJw9uD^m7jxI?7lue=?!xsQkJ=r0 zethsoo&N<uY<~{m@aaY8+p77UMTESUtI<Kv`t|>H-}Z&O<ddV}Dguw&O?q_DTRG=Z zk|83*8=LjkDLp?vSbcIdT%A0)-is$k{ngnGJ)KRjuu1{xQ1*>RBqPLzDn!OJ*ST}> zsq;*)JZ0ti<Y>6+7x~Kj$aL=b^rKPwfk=f2HdiZa6`2T=xibJt!J~uT>R;Q>-WuGr z>+kD`02wfMflFU=HkosFJX+0N)tk;s`c_j_0VTpgzwk;lMDRY`trmcRH5e^iTso}L zSR)vfk!8Zs)3G@}KJdl}&u6aFG!TgtM$iI<%`sXitMK~Zh0#o0vVhXw#p$H%4EJ)< zKvegiUUY;EfakNabNKY4^Rw~1)3XMnGcGROU~Q3Z$tOp{)u?Y*kA}Tf&#DuEgPuJ< zdC*_IZS#MlC?WsWU;dMp2Yq`2w{6F3yXAdFiR2%R`l~FH<D+4*TKk{(9(-8jqn{rg ztd3gO190+i=u4jrZ__{(-f;Y1l}{cFSDzdWH-^ahz|1+$CZz#5c`#hfy+;u0I#Pwm z*|dCp@SatpC!_xAUq2eHjt_e00OR@9jOKb5DJ_F!oTwi3i<M-8^MNYVM8Mbe_+oyC zZ8;hi=T|;(Iw=|U?C8-!v6`0E$Qa?tQGcxl>wVxszgShFX5T7G=b4mM=VI<UWfczB z>bo_#Z_>Y62CfQ-2%~=COJAeNI2!g&<}MtD*f6g=O-we(h1e-_b-s>1&W{gPQ&&xI z4Q{e@r0Y83e2s2by@`>FOULnOaGd^zVPV;`niwO)B41gfH?f2O1Dg+S4X&?u5LyYB zuA&MNYcxt=S~{*id9>0hqh}3u6KRNuWC+O?2{3mx*67=VySkZ0B7ugU(P#uE$?S#* zA3nP<^U`hNs1O=L-7qMUC0zeN6G4f*GI$lH`!?sJg8@$`B`(yg)nK%6bkOr3pG^n% z_bo<XQdXVwnWHco-$bktbOuPoD&4;|`1#bG2=L+a3AqT?XtWlprm31Hd3+bb%-8kC zOU_)?i4h(S3P2DM2G;Q5^JH>whLx3&VU^x2Ow&-EjORV01z*P*z~kq$j`Q_qeI7o$ z=uAsL(~_}ob#?znsBz2tN5E=nXC^$K&CNm2o+B`syUmU$t1!O#y{8xR0e8r)<FB%` zC`yE9lX(Z=;h-4l_EfGvcRDE#?;7l_a(;ZUTF1e^S5YGWIXzL4tJkuLKYW1t9&&zs zuqs0h4Op!afzs9V3d8-Mjc?8My<^;OD?OW!J|68qyO_JP(@FXG=6j!hG+Oy8^6cW0 zTqRrUbf9Tq-zs8^uZ{Ny)p)L?zi-WSSXhh}PA6qGDN{HMDYqT&TLhR~IwB29lI@8^ zVoW)3VbtbCujN~7{Gez3!-36x-C&L8$#{A=cem}0(aENll}BmIdeTZ{bU3i*qkch% zk<-Z~LWUAeh-tzABI$BIpoBccYxA?2c)OJ6b%<1Tg9y|yQo6vt&FL40x%2oK8Bg8e z#oU>Tx#MV9OqJICk4J;^N$F?LZW%`z)S<x|#lB67e$X#gS(f~I2$4EQngB>c6#*Ki zt{TM1>}`sBZL26De?02@1_<k*ET-)2pl7LLWPItcnSg*%3Lhe)o}~(bItm}2Ub~8Z zk*_k~qoYHfom~)OgOZFvk<+t=7$f)Jkj3_GKDytx&x9;5tS~R@*~jDAZO^=x5UB*% zH~QA3)5}Px8xHnzE`3dm;H!X9!qba6B7#<M{?XAYSIKsVI<|OCO(1!CNbb&65f>uE zB1KZ8o?We9AN1@>tL*%;tn$JtLWry<edojhq>Z|`ahk7ujjJ0ZgU~?b1D{?xE?te% z89p?ePD-v^jnVMz@k4+9<ap{sJgXy&Cncl(0-NiU#6{2wid+E=(%y_p3%R)<DW^_A z)$v;=z82p^$~xleNCv1Z!zj(AtLPV&L1D1DCirHP>d#%p;PGiE)*gfJpB<0RQ*0Ko zN{BHMiCnr0=WD7E$(7#310sUf>5}&Es%|K9MPbz2HST;pgJgyZqc|vXjz{~%2F|7> zu4)LeMo8F1VKqi{iXJ0aC8LK=FFIGQ!iT`a!5+Sj_z;;of9R`*xvy~{<=4YKgVtb8 z((!u2I%@;@5C}11)O8Gf=fo$M?j*)YCP_n+vf|_CQ_f~rNG4d7OqbSzM({q;YaK;l z75&1T1N`0Tq!VMTL}0j|V{@SjaXfQX$5o+Ix_Z{ch*3ge3?O7#vSxK15fQ9X^sT{% z+fL|>4k)2O4QCTak!Qr1G?8T~4b&Ob4TKnHb!<-V7xvu8fFP}HE;nNrxf&e}_s`qN z`L*8^$e%pud)1z;*np2UR%^0$qd$B$c}EA-Bvhox16rpo5S#0}77?D`@Mez>_VHyP zrWLyto0e4=e>|R;lZQk9sw07ft~`D|doM5k#>1)g^|?-9QbaOPBFsv6`1Im>(nrH$ z<wK;d6L{r99KSkVj8qBMkyqdPR`SNXJbRR|j5^jhA3>5sy14})f%DGQXERs5HrYR< z+&S@+2mO^~3DKODZv5$`JE=l^s|)_K{Qn@ilKy}69KKQdMSgrVEKZb==SoIT9`s*J ze!sJ<=bPlosP9FSN1#xeA~(l{5kkUe@(|<3Z2sk2#`(_V<iXHy?`-A&GX0$9tKTyJ z{3Tz!4E&YZp^i)3%dcitSZuJ!-x;BO7ZD*p=-K0+AH9yOKN|L?DwF(daz(B(LQENs z*21Tk9s%~PzJ=2KLAS@*qk|QaLedc7^y2cCXS7O=hdt95krYjah*B*;*%mlvSDxOU z8NeN&?;k=wy)5~3TH*tII(1CS%G`K6|LEc11mLWN4UM_>oa=<xg@}2@f_y7Y+g$ZO zy1zfJnkMgC!+(1P)42X&kk*C23L%Vo)`L)oNEK?dWSeh=$gPC9boH(8ek)D;D!9_u zxz!nS7v5R|4Kb1lOr78C%Tdp+v`!&z)qqHb62aGzD$qum=_10}w0wGV%-1xng#2(& zJnLCAicLe$8eA37N_hD6!bGSdR8KGFo#TVvs<0{N9QEzVc;;>aI3YCTDkTm^D^rDv zzRjnIaL}`ez@$vIwp0aa5J{nN9h++Is?l9p{AO7{Jszz>4Ail~*O7f|n9Ln@0}lrl zA5y|KxpLKbb`8{=9UrWk049g~Kf9fQCyk~6-^DndUOHD;b1cAz_j}Y$<ZM>rT)l~< zeI3W^n#G%Bvpw!V9d{l+n{*;zjpm}AaEOud+_7gBv4O!}o<ABEt6`C!1F0mTz=y~u zcd!!#@G+8$n8N7e7$YG@oDcXA3H3Us42P4l>bz;fN+f^KFHYc&?cwVbjtU@cniXSY za_Q+6nz?IQ&|i-pS-nyjl)gsDutw<Fd^B&v)r-;%2G&lk5e7ZmpOp^Pmaf}652f=1 zcSjVNE9nmkbNFyj9M>To>A!2Sm)8!W7O9lZsGC&Wsq1u%eT>Y@n!;#8XmE9G4@}0D zt0=6($H=3D!TEZu7@7IH#@7L@HNK8aU8*$E=8Sd3wVE9DY(5<p`D)ZJR(r-wLtq0d zWH<7N*Ct(uG@1Q9h1MxkPAd?|O@{L|4cECys2j3OcsiaEW5b@&Tz>LsvrX2#i8@9k z6ZWmas0^)=F?={E{IIaAL1E5~%KDHIV?<h~bXj_01G#!jE!5TF48Z%8N;R#<Lu|-y zd`?MvPqK`ri8Q1n6&mUQ{lfMEu6#P&S_GSCsaPd~3w5%`#0}L1xb->$u8wG(66iNh zx^(qa0AsE(iR6kioNq8XqpBm5GO;Cu<f64?Ov{QZAIJnQP99AGv?OwX5D^kNCP_ve zQbvChb$a!RF}Zf<-!kd7V{&z*ZrT_if)5Qnt8u<TWw2)yS~Skrh(L@DN(-~nL9Dr) zmz*3OOs&!6N>lo}MXA!YUTvG}YfrLK^UXv!Ap>$_nP0OW&WC9xZH67M=^aL8ls=N1 z4C{28xu+@UObDT&@-?~AOs}d+GRcidU$yL+=Em~2=MbY3+vC#RoMXaUXk=qyB9YA> zcWF9AswO6DVcKF}1cuh4G|bByYgFR8yrLi_8Ij22=M$p^as~JIEkrN^zG^6|gvypa zRrc3WozB>7$ELZSV@5I#H#L1{?2!o+I=Sb<C`S7htp(>BO7EF_zv0Q1E>IYg%FS|( zn|yL{c?i%D*)MWjh?G7UEmGB?;o{Qcd`*a{(5sYCH|g72OM4Tk6kXK~`fb)D{ZKMx z{lZWvO=ud<FH0t+qlu79hElSL#EeRa=$hcuxB2<ZRpYV>RCU7|0<%U9CS_$J@oAn3 zK195a7_FJR(3-kbHdjg|%R(Zv0oXP~y*tW_P*}~yrDI-sKAk&!XfP^E!Fo(f*)(8` z+JJ^ax)H511MuPLq@%JdX`ulvSb(_;kLRv3zD~9~HmP>6b#ld3h*TkvE5YPy1OEFM z-5V!ub4BTDOeS19PmGDKmoyt&t)?Z6F}9%jwLNvd-gw2*`LQvQ2ng0}!qW)V^I6%M zJ72AVeyh}G+vO^a)ugC`i@AFmTTJlINzYxNXOo!{5sEyy;KC?$mS}M401Bs*vSadO zZIwXXM0|+T^;pj)<)M&F)=kH8{r=p<rm1Scnv8v`DRPC?8mkl;a5}j<yjiz=Ly3b~ z=_5UBHW`K0Y3b{hAtAuCi@AYhzI2u%LaP-a-VT5spG^m`fqiT4B(OeyJ~Pk8vzDeO z6h<fNURgc;cs%R8iWlCQZuz=lU^PBma~$dh;F^PZap@kfsR%yAw*sSO6=ssX9XpMY z>Q!9&O>(EEOCP4G!m2l3F@rX4fLZCsWfiVdpeDh=b^RJ+cq5NbXPukz!|x(*upZIZ zG1<qp<Yvv(iA>6B6Q~b+DH+%^I&m1Ce<Sq!@%iPQER)~Mq)T5rlMCzo&$jTC2t0cQ zr?y&;)~SDCHNK8#Z~8G;h2INg{3Zy&`!<iaMksy2WWv*n@+NLU&#F<=Fg|>G@&44B z-$Cx2w9)#I7zyp}(3x<4=?-slfB@z$j9)GMe;4xFr29pF^5~#AjuD*qv+<=nd6fb6 zM<;jDcm6DYmOsn4m0Zc_LBH^ihQ;|eefE#0^76+fHdp=OzIkem>ZhzM!{&mkS_rGI zXH|&(rh&npL4*O5@~vb3S=l$F$W{O2!@=0sF}FsTI?v>?g4m!`hBzU%oR8tY=?@D< zSp~ERxsv?Va@?!(M^T>pj}|55PyYMxm%}~#KX<<;+b@3`d3N#dgzz=_Htgyh;$q1n zF4-2yvMyh~T<~JC;0G<ps<lvsMfLex0>nQmzU}*p63Gjr2K&}L9290Gl9H+f&<fMi zaW*XnZzEL<i~QulaPL^R5YFjjPK*t?N`Pc&^LP=+vKE@mxB-Ag_HB;Qnk(<eKO4{A z7y$ptnh~p{Kis#|x{264DQZp3o0gusj?7B;_)UsdLjU2Qn3`OnB|%BfdyGzrWJ)j+ zTDg{{NkCqGgG(8KNm+4FWDE;C`Wf>#&iOw~*&^gUn?JNln}Ich)7j<8duADCjZI&= z3LC*_jaEW*k&C$-yoztErDxT7k(<%5XIt)SBs2}B55$;I#$5CU)?EYbkw~nsq2L?$ z!qj;rOLo6}gDLq=mHlYgn+^-pS1lA)$4KQHv=&Yt49_QXH~ZNe`bAz7xmnT{st~X( zDR}Dq)4LR{L`K8HoQnvD1B>&KJ)`j<a#<$7wyr9#m0UM1H#|Zr-eenG=O&UCVx;sn zJ!=ksugcDq^tFiTSv|PFZy&ZlonJX$g~)Vr<xcMU!Do~C;B+$2hdn!2BKdI7kn4=P zP8j5{XZu=-e=?r+UgajfDuP%a8?>ZCna(6t^r8?OZpFMJ^oNBVE0H`Bu|@%cX<>)h zG#mVB-K6E~n0EO_GK6acP1*%;bv^bWoP@~i;>{KWc!RQ)NN$u2dR9N&Gir2m39U}` z03RZ;X>dMu8RRP21sCF|$n}U8Lmf}ucrtg7*5E{h>Z0u!u0nl28t#ouTiXf&3ZwHU zM??SkbYkLL6fPM?OJaWS+iO;LZUmLd2EFOqd}>tIUz>ys;r_nG`Gk&_RVs$Zw#Iy0 z!EERU06sP|=fX*har!FQ@-A{GE!XC1(6jpCU@sp<z(|Ix8`h3^edG|3EEN))CgE$t z!UBmfUHOLGWT~SfRaj@<$6G+lgT6f<?AeiB7Zck>s$#?0r{&?BK$)J+&#lTvAvPQH zAqYnY`<zZL#}}8*^{hUor7%a*Vp=1N`UQ}H%LW)vOPsGat#SZOq;hpQsX}~u*YAHD z`Nq(%$kk{xEY5YdF3W*)^@fMk+}H?JNHqN6zC|g)SAo!eVCpJ#CNxciOfVu$O7~cc zFznfrIz)y&O9&BPM`{}Ov}WpFZEZ=CD;e!u^DMo*4$&SR4v9^}>BS5YA%sY52{IzE zZ*%fYvu71oJ~ebac|M($K1@T5Cwz+?yWXI~J@e4y$_QD%XBBf7X3s9B$7?3WH`?s7 z3S*t6bT!lszU88<Wld%f0i#u`SdUc+*49e!p+;xvc@suuXp(2&x8_7CL20OCB9}cJ zrd>x3jliHVeQS(=ayIGR%+9J1#}{)q?iabQLz8Fg`VWHE5MpW$K~jx1v`mr0rl!W` z2JgLU;_;gz7f6m(1Z$0YoI#!|&Heqvda6Ujv}wGMYH?MFe0Vx}?Nq*#gS@<|#>0I( zGD;&M;z>;-H+OZ@R&UnQv*7Dge6}W|XH(}*jBpi_(q-K%(>4rdS>$vwXSkPI;CzUf zT%mHwPmf3b*~RQ|GIzIbAk@*RO!9Rrb0RUd>lK@JN<yk6WDp@Ui5a+O6jv^wG8q)P zdMud?w2;e<>i3%CmR>iTqWk%@+}!QKzQroRg|rdd<Z4q3T+2J9>mS_HKixr!mmwnA z7GDE#5y^IhEL$eWlO;0}mS3@0Ms~Ni`M_wFoetHDRG0qEiv=RE!xm;YIjn9Mwz^$j zMp(uO%O(Hzxo1hl?CuaF{J?0soh^R6U;Ommz1^K(%|HL;dTu*i)QcE@BAqT@v*d$& zhV88_UM?1duwZvPL(3Mjy@d$;^$)h`(gC`3yRcX+`I`8X<#Jh=?QEOw)~$Q*c5lAk zVhMDYYgT32tuev}c9*z_gnG&DPM3fFRrwFE>hYZzldh`I3acrs-mLO9kqhdY4O1o& z1T=L>-AGzUT&bqPhZ<MaxX^G}rpAgjh12R3Zk1I!E~TrPUi#!Ce2r-d2lxBEWB=(V zn<p@=o%Z_mnkZ?M-gL4j7DUVWX%iuRBeh?DcXKXVn&~FKzVVtHpIiTzs{<jlO;I%X zcy|-_J1ILh>E=sUr=yf*Xbp))5;w_(NTNSgEvZ)k=bJ?6tpc%G^SR=N<+eWlMzWUE zmBvt#0g-v>@F7q-kCBLTj@rBY>gOM=iahU!5YMbh%nU6Vmsbw&Yx4H_LpLu-=3}F* zn3zntQe^Ftt#J?~DdrZH=qqZ?;o-(5*L`-rj^s*EnI_bc!-2iUdWCm1BRkuoj(+^t zN5*8tWrr`mYM49E%a@TwTq4~q7O^45C0{L<>_~=^ZN9H}FuNHq>#uMx0$Ux}$#&4& z8QpF=*1J2xa+wHri{+9pUPiW9BHLRmA}r#P%hJz6T>g4@TZ$Kp1)*A?v#;5=_l_dV zO6dF~lME%G^)}mCG6in)V4g^1$ucfkEF$-e5M!r(_)nLeY>U#rM2XPtc5htCOmyLu z|8KAMy(O@nbul|z>?$GtHnL<{{i>{f@!rY~i}<D0-~0QQA#QiKw%FQQ@>Ts?mTb}O zZn2=DS;CfN>~3%I;}3H7?`hnN8outp))xLnWLrAyYN1OPz0-wdm*o-`aarBl-r0V+ zSWt(^Ru^JirUe0hV0P}EO+FizRXw}^U(8RxS}cf5fF<{KcYd<7-R1KyU(l5;mMs%! zSA_rd+2<_j5SOj(ZLjU^E?Y~`I^&D5z-)I}(xvltq_YKE?X_IKu8S;#ttD(_*PqL_ zU>l*k)j@9yVG+r)Okd31tr-2CS?+r_qu1K(x=wK8jVWLx!)jr;XMqgg(l%UOGk3l< zHR-smaffvXnPn;2$W=<YQ%rnK4^31&v2$0AkDgtaOavbSs>MengM;24AzZiQ`WUGr zPwUv=e9hdYt8_KvnM=)|A-37KVA=?zZmy#&opHnFr@!0V1#X+D(3bRXv>?1@v){RR zpt~}NON#E+7Q1?j-JLG?)HZf^m%sgC>Ot-<x6nJnJ>BJ3pLzbJ{E{z21eW+k!*64U z?QR0!x3-drpu2?Sa`D&qcDHr5Md=sGKJExF>lB@QU=&)mbXkR8#3hUIuRs6Co>hO7 zZDse&c9)lRL}gq2=!1JWzhGCxPB-K1-^#=PQ-yz6EaE@?=mYaV?(JsV%in^~CB(0> zMsrUIAuh?XF3T>sYC&8s+0D9$2-^bEg%FplH@W~_5wfhix#%Wev$eHkcU!3HCI9<# z_fK)j;=Pq^c6aXm?cm-|I^88NUo^Z}M1J#f!DnB*<TGFKtFq$7BJ!E5xG2BCFBUA9 zOLn?jbi42ay@PbSES5`_EYUmLkW2{DmF=txJJ}X57m=;4E{i&{EyC{ZHroP=Nb$kF zoxd-?Ohl$%mDOonE_Z%pcLy&QDNKB^i2Ue-T^4l*qqmuV{>7|X#BvFX&#UmX{4)IG zA})XV!+ZLESJ*DU2>j6Q^3?)%w;?P#6h9D_bg7q17Rv=4z`a<IExX8$u-)ylz1>B3 zg`IAfZg)v|5$Sf8nC%p*>YXl&ua}fx)U%h1xG7A&v$D4{jM?7(>C2Z5-`mOfzRqwj z7j)_JGJeHZaY+>dA;P`wWV^qwcUZC{29n};y6j|K^wu_U8QI!`UA;}GlXk<Rbzon# ziq;uvffkXljQFbg<(FZxaXOz@;g@Cg)n`Bc;rD+U7E81UUo2|6TT8Us!ByeQvI@Vv zc^`4P{IaaVQ}<=~CzZ)x0mbgl4qF0ou|)4~v0TD-SIFqHE!%wk^^#@@olY|TVUZw( z7mG;e>m}dY6$ZsUmR~RFZo!Up`RB>MKmPS^UjFmV-+t$^m{qEO@^CO+m!4c*Gbw%h zID!NM75SRm9*N<)YYuK>C~MnSlg!`r%0DiQ=Hak7S@-B<?IVta6vygJIG^5K5D+1M zGV1%HZAkJ>gUK>t)65<}pM4`fE|8xb4ZRkjjuGE9?CFdqLTDQ5$c6-*kwCVF#8od$ zA|l(C9{cH~8$X}j{n({<#<N`rGlUH?w{HzD#LeS2VoaqZX*su|rRCwuri_%HtCb%2 zrnNvFs?)a7DMJ4U5+S$>n^-rIk%hX6)tm5(7*ikq$%Fn>$olI?qbZ%)ce%I7x>X)V zJ$o|P&yQ2guZh6ENl$06CLxmty@WEBz6Js3!tBX-Hu@$E{=EvmNB!dbU|>fgf^&g+ z<?%jlc5rHsxUSXFlJ2winE@fj^}p5m)Qw(M-p?PUrmT7CN!6T`rCK9g%>C23t6obK zUX_EMJsIxj$23q_!^5Xz^G!;4lPDn{7WT1D36kBn%1p~@I`{SYx1m|SSEWWW95E#e z#t38vA!W|%27#N3CQC;xWmh0km^(kdNq*goE##qn+>x{kQ`d>*8zcBSyaw#tB^Pt| z_|p0Fj}Hga5F&-m2eb0qJxd`(s`31~|MB_n$YOo3Zqm}%-nS1qiLE`m0U4yOJ(ALM zlhS38b#G1NbTT)0DLPlue>f=o8iQElFIo$x-Qm?8Ps(_cR3XkjJe_pv7%MIBW=g&b zd9R&a*U?#(SU^?@d6se2Tz8OIqmb6lRw0q)s}Px7y2HC3D*{Q;_xJ78w(SLVOhwpB zUvCPlSN_dZ@3+Z^rxWwdpZf0PJ<W)0Oo(e8hH0PcvR1Nht2Gh9)!|mB@2iq4=^qV? zX-4wu0Mko9))`E${8^0A-_>vWrz-E|AZ@PtpBxRRuHD(Ck0_lG!4M<9iI_Hxe^Z$D zpIP2Hsp(mDa{M>@r!N-~Ba(pkua^n@2X=P_mdn}aU(~-C|N1xoH7=K5{sHIxCn?{! zvqyb<KCt=7=nPjkvrAV^=dM2YA-K0u4gM^z%l`vNK`Zq2AkLKl0072%R9JLGWpiV4 zX>fFDZ*Bkpc$`hkK}y6x5CzbEPVtutGhsmR1maE|;t<z8-9Je|Qq^=-Msj<%zWp1h zg^dOG16MW|4{9cC!YD4Lc#7>ALppG4DYJDWn~N!4`pXHsi_VCJxXDJxCx0>6mK2j| zAZfwd$NP_2dF{Jz(M(*w#`BO46r)2eP^2-halrRltp!AbZB3a4wnyFL)Wsr>NmgP> zjytKyrVqAYK^T($U$Ui{ct}F(s(GAivrKo<86K?tA8rU&BlmN~0000007*qoM6N<$ Ef`FLc{r~^~ literal 0 HcmV?d00001 diff --git a/mod/pub.mod/libpng.mod/pngtrans.c b/mod/pub.mod/libpng.mod/pngtrans.c new file mode 100644 index 0000000..9c4d67c --- /dev/null +++ b/mod/pub.mod/libpng.mod/pngtrans.c @@ -0,0 +1,652 @@ + +/* pngtrans.c - transforms the data in a row (used by both readers and writers) + * + * Last changed in libpng 1.2.9 April 14, 2006 + * For conditions of distribution and use, see copyright notice in png.h + * Copyright (c) 1998-2006 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + */ + +#define PNG_INTERNAL +#include "png.h" + +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) +#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) +/* turn on BGR-to-RGB mapping */ +void PNGAPI +png_set_bgr(png_structp png_ptr) +{ + png_debug(1, "in png_set_bgr\n"); + png_ptr->transformations |= PNG_BGR; +} +#endif + +#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) +/* turn on 16 bit byte swapping */ +void PNGAPI +png_set_swap(png_structp png_ptr) +{ + png_debug(1, "in png_set_swap\n"); + if (png_ptr->bit_depth == 16) + png_ptr->transformations |= PNG_SWAP_BYTES; +} +#endif + +#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED) +/* turn on pixel packing */ +void PNGAPI +png_set_packing(png_structp png_ptr) +{ + png_debug(1, "in png_set_packing\n"); + if (png_ptr->bit_depth < 8) + { + png_ptr->transformations |= PNG_PACK; + png_ptr->usr_bit_depth = 8; + } +} +#endif + +#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED) +/* turn on packed pixel swapping */ +void PNGAPI +png_set_packswap(png_structp png_ptr) +{ + png_debug(1, "in png_set_packswap\n"); + if (png_ptr->bit_depth < 8) + png_ptr->transformations |= PNG_PACKSWAP; +} +#endif + +#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) +void PNGAPI +png_set_shift(png_structp png_ptr, png_color_8p true_bits) +{ + png_debug(1, "in png_set_shift\n"); + png_ptr->transformations |= PNG_SHIFT; + png_ptr->shift = *true_bits; +} +#endif + +#if defined(PNG_READ_INTERLACING_SUPPORTED) || \ + defined(PNG_WRITE_INTERLACING_SUPPORTED) +int PNGAPI +png_set_interlace_handling(png_structp png_ptr) +{ + png_debug(1, "in png_set_interlace handling\n"); + if (png_ptr->interlaced) + { + png_ptr->transformations |= PNG_INTERLACE; + return (7); + } + + return (1); +} +#endif + +#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) +/* Add a filler byte on read, or remove a filler or alpha byte on write. + * The filler type has changed in v0.95 to allow future 2-byte fillers + * for 48-bit input data, as well as to avoid problems with some compilers + * that don't like bytes as parameters. + */ +void PNGAPI +png_set_filler(png_structp png_ptr, png_uint_32 filler, int filler_loc) +{ + png_debug(1, "in png_set_filler\n"); + png_ptr->transformations |= PNG_FILLER; + png_ptr->filler = (png_byte)filler; + if (filler_loc == PNG_FILLER_AFTER) + png_ptr->flags |= PNG_FLAG_FILLER_AFTER; + else + png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER; + + /* This should probably go in the "do_read_filler" routine. + * I attempted to do that in libpng-1.0.1a but that caused problems + * so I restored it in libpng-1.0.2a + */ + + if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) + { + png_ptr->usr_channels = 4; + } + + /* Also I added this in libpng-1.0.2a (what happens when we expand + * a less-than-8-bit grayscale to GA? */ + + if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY && png_ptr->bit_depth >= 8) + { + png_ptr->usr_channels = 2; + } +} + +#if !defined(PNG_1_0_X) +/* Added to libpng-1.2.7 */ +void PNGAPI +png_set_add_alpha(png_structp png_ptr, png_uint_32 filler, int filler_loc) +{ + png_debug(1, "in png_set_add_alpha\n"); + png_set_filler(png_ptr, filler, filler_loc); + png_ptr->transformations |= PNG_ADD_ALPHA; +} +#endif + +#endif + +#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \ + defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) +void PNGAPI +png_set_swap_alpha(png_structp png_ptr) +{ + png_debug(1, "in png_set_swap_alpha\n"); + png_ptr->transformations |= PNG_SWAP_ALPHA; +} +#endif + +#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \ + defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) +void PNGAPI +png_set_invert_alpha(png_structp png_ptr) +{ + png_debug(1, "in png_set_invert_alpha\n"); + png_ptr->transformations |= PNG_INVERT_ALPHA; +} +#endif + +#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) +void PNGAPI +png_set_invert_mono(png_structp png_ptr) +{ + png_debug(1, "in png_set_invert_mono\n"); + png_ptr->transformations |= PNG_INVERT_MONO; +} + +/* invert monochrome grayscale data */ +void /* PRIVATE */ +png_do_invert(png_row_infop row_info, png_bytep row) +{ + png_debug(1, "in png_do_invert\n"); + /* This test removed from libpng version 1.0.13 and 1.2.0: + * if (row_info->bit_depth == 1 && + */ +#if defined(PNG_USELESS_TESTS_SUPPORTED) + if (row == NULL || row_info == NULL) + return; +#endif + if (row_info->color_type == PNG_COLOR_TYPE_GRAY) + { + png_bytep rp = row; + png_uint_32 i; + png_uint_32 istop = row_info->rowbytes; + + for (i = 0; i < istop; i++) + { + *rp = (png_byte)(~(*rp)); + rp++; + } + } + else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA && + row_info->bit_depth == 8) + { + png_bytep rp = row; + png_uint_32 i; + png_uint_32 istop = row_info->rowbytes; + + for (i = 0; i < istop; i+=2) + { + *rp = (png_byte)(~(*rp)); + rp+=2; + } + } + else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA && + row_info->bit_depth == 16) + { + png_bytep rp = row; + png_uint_32 i; + png_uint_32 istop = row_info->rowbytes; + + for (i = 0; i < istop; i+=4) + { + *rp = (png_byte)(~(*rp)); + *(rp+1) = (png_byte)(~(*(rp+1))); + rp+=4; + } + } +} +#endif + +#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) +/* swaps byte order on 16 bit depth images */ +void /* PRIVATE */ +png_do_swap(png_row_infop row_info, png_bytep row) +{ + png_debug(1, "in png_do_swap\n"); + if ( +#if defined(PNG_USELESS_TESTS_SUPPORTED) + row != NULL && row_info != NULL && +#endif + row_info->bit_depth == 16) + { + png_bytep rp = row; + png_uint_32 i; + png_uint_32 istop= row_info->width * row_info->channels; + + for (i = 0; i < istop; i++, rp += 2) + { + png_byte t = *rp; + *rp = *(rp + 1); + *(rp + 1) = t; + } + } +} +#endif + +#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED) +static PNG_CONST png_byte onebppswaptable[256] = { + 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, + 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0, + 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, + 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, + 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, + 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4, + 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, + 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC, + 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, + 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2, + 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, + 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA, + 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, + 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6, + 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, + 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE, + 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, + 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1, + 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, + 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9, + 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, + 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5, + 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, + 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD, + 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, + 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3, + 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, + 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB, + 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, + 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7, + 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, + 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF +}; + +static PNG_CONST png_byte twobppswaptable[256] = { + 0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0, + 0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0, + 0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4, + 0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4, + 0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8, + 0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8, + 0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC, + 0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC, + 0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1, + 0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1, + 0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5, + 0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5, + 0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9, + 0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9, + 0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD, + 0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD, + 0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2, + 0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2, + 0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6, + 0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6, + 0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA, + 0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA, + 0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE, + 0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE, + 0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3, + 0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3, + 0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7, + 0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7, + 0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB, + 0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB, + 0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF, + 0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF +}; + +static PNG_CONST png_byte fourbppswaptable[256] = { + 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, + 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0, + 0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71, + 0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1, + 0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72, + 0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2, + 0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73, + 0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3, + 0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74, + 0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4, + 0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75, + 0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5, + 0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76, + 0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6, + 0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77, + 0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7, + 0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78, + 0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8, + 0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79, + 0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9, + 0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A, + 0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA, + 0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B, + 0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB, + 0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C, + 0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC, + 0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D, + 0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD, + 0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E, + 0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE, + 0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F, + 0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF +}; + +/* swaps pixel packing order within bytes */ +void /* PRIVATE */ +png_do_packswap(png_row_infop row_info, png_bytep row) +{ + png_debug(1, "in png_do_packswap\n"); + if ( +#if defined(PNG_USELESS_TESTS_SUPPORTED) + row != NULL && row_info != NULL && +#endif + row_info->bit_depth < 8) + { + png_bytep rp, end, table; + + end = row + row_info->rowbytes; + + if (row_info->bit_depth == 1) + table = (png_bytep)onebppswaptable; + else if (row_info->bit_depth == 2) + table = (png_bytep)twobppswaptable; + else if (row_info->bit_depth == 4) + table = (png_bytep)fourbppswaptable; + else + return; + + for (rp = row; rp < end; rp++) + *rp = table[*rp]; + } +} +#endif /* PNG_READ_PACKSWAP_SUPPORTED or PNG_WRITE_PACKSWAP_SUPPORTED */ + +#if defined(PNG_WRITE_FILLER_SUPPORTED) || \ + defined(PNG_READ_STRIP_ALPHA_SUPPORTED) +/* remove filler or alpha byte(s) */ +void /* PRIVATE */ +png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags) +{ + png_debug(1, "in png_do_strip_filler\n"); +#if defined(PNG_USELESS_TESTS_SUPPORTED) + if (row != NULL && row_info != NULL) +#endif + { + png_bytep sp=row; + png_bytep dp=row; + png_uint_32 row_width=row_info->width; + png_uint_32 i; + + if ((row_info->color_type == PNG_COLOR_TYPE_RGB || + (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA && + (flags & PNG_FLAG_STRIP_ALPHA))) && + row_info->channels == 4) + { + if (row_info->bit_depth == 8) + { + /* This converts from RGBX or RGBA to RGB */ + if (flags & PNG_FLAG_FILLER_AFTER) + { + dp+=3; sp+=4; + for (i = 1; i < row_width; i++) + { + *dp++ = *sp++; + *dp++ = *sp++; + *dp++ = *sp++; + sp++; + } + } + /* This converts from XRGB or ARGB to RGB */ + else + { + for (i = 0; i < row_width; i++) + { + sp++; + *dp++ = *sp++; + *dp++ = *sp++; + *dp++ = *sp++; + } + } + row_info->pixel_depth = 24; + row_info->rowbytes = row_width * 3; + } + else /* if (row_info->bit_depth == 16) */ + { + if (flags & PNG_FLAG_FILLER_AFTER) + { + /* This converts from RRGGBBXX or RRGGBBAA to RRGGBB */ + sp += 8; dp += 6; + for (i = 1; i < row_width; i++) + { + /* This could be (although png_memcpy is probably slower): + png_memcpy(dp, sp, 6); + sp += 8; + dp += 6; + */ + + *dp++ = *sp++; + *dp++ = *sp++; + *dp++ = *sp++; + *dp++ = *sp++; + *dp++ = *sp++; + *dp++ = *sp++; + sp += 2; + } + } + else + { + /* This converts from XXRRGGBB or AARRGGBB to RRGGBB */ + for (i = 0; i < row_width; i++) + { + /* This could be (although png_memcpy is probably slower): + png_memcpy(dp, sp, 6); + sp += 8; + dp += 6; + */ + + sp+=2; + *dp++ = *sp++; + *dp++ = *sp++; + *dp++ = *sp++; + *dp++ = *sp++; + *dp++ = *sp++; + *dp++ = *sp++; + } + } + row_info->pixel_depth = 48; + row_info->rowbytes = row_width * 6; + } + row_info->channels = 3; + } + else if ((row_info->color_type == PNG_COLOR_TYPE_GRAY || + (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA && + (flags & PNG_FLAG_STRIP_ALPHA))) && + row_info->channels == 2) + { + if (row_info->bit_depth == 8) + { + /* This converts from GX or GA to G */ + if (flags & PNG_FLAG_FILLER_AFTER) + { + for (i = 0; i < row_width; i++) + { + *dp++ = *sp++; + sp++; + } + } + /* This converts from XG or AG to G */ + else + { + for (i = 0; i < row_width; i++) + { + sp++; + *dp++ = *sp++; + } + } + row_info->pixel_depth = 8; + row_info->rowbytes = row_width; + } + else /* if (row_info->bit_depth == 16) */ + { + if (flags & PNG_FLAG_FILLER_AFTER) + { + /* This converts from GGXX or GGAA to GG */ + sp += 4; dp += 2; + for (i = 1; i < row_width; i++) + { + *dp++ = *sp++; + *dp++ = *sp++; + sp += 2; + } + } + else + { + /* This converts from XXGG or AAGG to GG */ + for (i = 0; i < row_width; i++) + { + sp += 2; + *dp++ = *sp++; + *dp++ = *sp++; + } + } + row_info->pixel_depth = 16; + row_info->rowbytes = row_width * 2; + } + row_info->channels = 1; + } + if (flags & PNG_FLAG_STRIP_ALPHA) + row_info->color_type &= ~PNG_COLOR_MASK_ALPHA; + } +} +#endif + +#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) +/* swaps red and blue bytes within a pixel */ +void /* PRIVATE */ +png_do_bgr(png_row_infop row_info, png_bytep row) +{ + png_debug(1, "in png_do_bgr\n"); + if ( +#if defined(PNG_USELESS_TESTS_SUPPORTED) + row != NULL && row_info != NULL && +#endif + (row_info->color_type & PNG_COLOR_MASK_COLOR)) + { + png_uint_32 row_width = row_info->width; + if (row_info->bit_depth == 8) + { + if (row_info->color_type == PNG_COLOR_TYPE_RGB) + { + png_bytep rp; + png_uint_32 i; + + for (i = 0, rp = row; i < row_width; i++, rp += 3) + { + png_byte save = *rp; + *rp = *(rp + 2); + *(rp + 2) = save; + } + } + else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + { + png_bytep rp; + png_uint_32 i; + + for (i = 0, rp = row; i < row_width; i++, rp += 4) + { + png_byte save = *rp; + *rp = *(rp + 2); + *(rp + 2) = save; + } + } + } + else if (row_info->bit_depth == 16) + { + if (row_info->color_type == PNG_COLOR_TYPE_RGB) + { + png_bytep rp; + png_uint_32 i; + + for (i = 0, rp = row; i < row_width; i++, rp += 6) + { + png_byte save = *rp; + *rp = *(rp + 4); + *(rp + 4) = save; + save = *(rp + 1); + *(rp + 1) = *(rp + 5); + *(rp + 5) = save; + } + } + else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + { + png_bytep rp; + png_uint_32 i; + + for (i = 0, rp = row; i < row_width; i++, rp += 8) + { + png_byte save = *rp; + *rp = *(rp + 4); + *(rp + 4) = save; + save = *(rp + 1); + *(rp + 1) = *(rp + 5); + *(rp + 5) = save; + } + } + } + } +} +#endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */ + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_LEGACY_SUPPORTED) +void PNGAPI +png_set_user_transform_info(png_structp png_ptr, png_voidp + user_transform_ptr, int user_transform_depth, int user_transform_channels) +{ + png_debug(1, "in png_set_user_transform_info\n"); +#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) + png_ptr->user_transform_ptr = user_transform_ptr; + png_ptr->user_transform_depth = (png_byte)user_transform_depth; + png_ptr->user_transform_channels = (png_byte)user_transform_channels; +#else + if(user_transform_ptr || user_transform_depth || user_transform_channels) + png_warning(png_ptr, + "This version of libpng does not support user transform info"); +#endif +} +#endif + +/* This function returns a pointer to the user_transform_ptr associated with + * the user transform functions. The application should free any memory + * associated with this pointer before png_write_destroy and png_read_destroy + * are called. + */ +png_voidp PNGAPI +png_get_user_transform_ptr(png_structp png_ptr) +{ +#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) + return ((png_voidp)png_ptr->user_transform_ptr); +#else + if(png_ptr) + return (NULL); + return (NULL); +#endif +} +#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */ diff --git a/mod/pub.mod/libpng.mod/pngvcrd.c b/mod/pub.mod/libpng.mod/pngvcrd.c new file mode 100644 index 0000000..d1c6405 --- /dev/null +++ b/mod/pub.mod/libpng.mod/pngvcrd.c @@ -0,0 +1,3904 @@ + +/* pngvcrd.c - mixed C/assembler version of utilities to read a PNG file + * + * For Intel x86 CPU and Microsoft Visual C++ compiler + * + * Last changed in libpng 1.2.6 - August 15, 2004 + * For conditions of distribution and use, see copyright notice in png.h + * Copyright (c) 1998-2004 Glenn Randers-Pehrson + * Copyright (c) 1998, Intel Corporation + * + * Contributed by Nirav Chhatrapati, Intel Corporation, 1998 + * Interface to libpng contributed by Gilles Vollant, 1999 + * + * + * In png_do_read_interlace() in libpng versions 1.0.3a through 1.0.4d, + * a sign error in the post-MMX cleanup code for each pixel_depth resulted + * in bad pixels at the beginning of some rows of some images, and also + * (due to out-of-range memory reads and writes) caused heap corruption + * when compiled with MSVC 6.0. The error was fixed in version 1.0.4e. + * + * [png_read_filter_row_mmx_avg() bpp == 2 bugfix, GRR 20000916] + * + * [runtime MMX configuration, GRR 20010102] + * + */ + +#define PNG_INTERNAL +#include "png.h" + +#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_USE_PNGVCRD) + +static int mmx_supported=2; + + +int PNGAPI +png_mmx_support(void) +{ + int mmx_supported_local = 0; + _asm { + push ebx //CPUID will trash these + push ecx + push edx + + pushfd //Save Eflag to stack + pop eax //Get Eflag from stack into eax + mov ecx, eax //Make another copy of Eflag in ecx + xor eax, 0x200000 //Toggle ID bit in Eflag [i.e. bit(21)] + push eax //Save modified Eflag back to stack + + popfd //Restored modified value back to Eflag reg + pushfd //Save Eflag to stack + pop eax //Get Eflag from stack + push ecx // save original Eflag to stack + popfd // restore original Eflag + xor eax, ecx //Compare the new Eflag with the original Eflag + jz NOT_SUPPORTED //If the same, CPUID instruction is not supported, + //skip following instructions and jump to + //NOT_SUPPORTED label + + xor eax, eax //Set eax to zero + + _asm _emit 0x0f //CPUID instruction (two bytes opcode) + _asm _emit 0xa2 + + cmp eax, 1 //make sure eax return non-zero value + jl NOT_SUPPORTED //If eax is zero, mmx not supported + + xor eax, eax //set eax to zero + inc eax //Now increment eax to 1. This instruction is + //faster than the instruction "mov eax, 1" + + _asm _emit 0x0f //CPUID instruction + _asm _emit 0xa2 + + and edx, 0x00800000 //mask out all bits but mmx bit(24) + cmp edx, 0 // 0 = mmx not supported + jz NOT_SUPPORTED // non-zero = Yes, mmx IS supported + + mov mmx_supported_local, 1 //set return value to 1 + +NOT_SUPPORTED: + mov eax, mmx_supported_local //move return value to eax + pop edx //CPUID trashed these + pop ecx + pop ebx + } + + //mmx_supported_local=0; // test code for force don't support MMX + //printf("MMX : %u (1=MMX supported)\n",mmx_supported_local); + + mmx_supported = mmx_supported_local; + return mmx_supported_local; +} + +/* Combines the row recently read in with the previous row. + This routine takes care of alpha and transparency if requested. + This routine also handles the two methods of progressive display + of interlaced images, depending on the mask value. + The mask value describes which pixels are to be combined with + the row. The pattern always repeats every 8 pixels, so just 8 + bits are needed. A one indicates the pixel is to be combined; a + zero indicates the pixel is to be skipped. This is in addition + to any alpha or transparency value associated with the pixel. If + you want all pixels to be combined, pass 0xff (255) in mask. */ + +/* Use this routine for x86 platform - uses faster MMX routine if machine + supports MMX */ + +void /* PRIVATE */ +png_combine_row(png_structp png_ptr, png_bytep row, int mask) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; +#endif + + png_debug(1,"in png_combine_row_asm\n"); + + if (mmx_supported == 2) { +#if !defined(PNG_1_0_X) + /* this should have happened in png_init_mmx_flags() already */ + png_warning(png_ptr, "asm_flags may not have been initialized"); +#endif + png_mmx_support(); + } + + if (mask == 0xff) + { + png_memcpy(row, png_ptr->row_buf + 1, + (png_size_t)PNG_ROWBYTES(png_ptr->row_info.pixel_depth, + png_ptr->width)); + } + /* GRR: add "else if (mask == 0)" case? + * or does png_combine_row() not even get called in that case? */ + else + { + switch (png_ptr->row_info.pixel_depth) + { + case 1: + { + png_bytep sp; + png_bytep dp; + int s_inc, s_start, s_end; + int m; + int shift; + png_uint_32 i; + + sp = png_ptr->row_buf + 1; + dp = row; + m = 0x80; +#if defined(PNG_READ_PACKSWAP_SUPPORTED) + if (png_ptr->transformations & PNG_PACKSWAP) + { + s_start = 0; + s_end = 7; + s_inc = 1; + } + else +#endif + { + s_start = 7; + s_end = 0; + s_inc = -1; + } + + shift = s_start; + + for (i = 0; i < png_ptr->width; i++) + { + if (m & mask) + { + int value; + + value = (*sp >> shift) & 0x1; + *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff); + *dp |= (png_byte)(value << shift); + } + + if (shift == s_end) + { + shift = s_start; + sp++; + dp++; + } + else + shift += s_inc; + + if (m == 1) + m = 0x80; + else + m >>= 1; + } + break; + } + + case 2: + { + png_bytep sp; + png_bytep dp; + int s_start, s_end, s_inc; + int m; + int shift; + png_uint_32 i; + int value; + + sp = png_ptr->row_buf + 1; + dp = row; + m = 0x80; +#if defined(PNG_READ_PACKSWAP_SUPPORTED) + if (png_ptr->transformations & PNG_PACKSWAP) + { + s_start = 0; + s_end = 6; + s_inc = 2; + } + else +#endif + { + s_start = 6; + s_end = 0; + s_inc = -2; + } + + shift = s_start; + + for (i = 0; i < png_ptr->width; i++) + { + if (m & mask) + { + value = (*sp >> shift) & 0x3; + *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); + *dp |= (png_byte)(value << shift); + } + + if (shift == s_end) + { + shift = s_start; + sp++; + dp++; + } + else + shift += s_inc; + if (m == 1) + m = 0x80; + else + m >>= 1; + } + break; + } + + case 4: + { + png_bytep sp; + png_bytep dp; + int s_start, s_end, s_inc; + int m; + int shift; + png_uint_32 i; + int value; + + sp = png_ptr->row_buf + 1; + dp = row; + m = 0x80; +#if defined(PNG_READ_PACKSWAP_SUPPORTED) + if (png_ptr->transformations & PNG_PACKSWAP) + { + s_start = 0; + s_end = 4; + s_inc = 4; + } + else +#endif + { + s_start = 4; + s_end = 0; + s_inc = -4; + } + shift = s_start; + + for (i = 0; i < png_ptr->width; i++) + { + if (m & mask) + { + value = (*sp >> shift) & 0xf; + *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); + *dp |= (png_byte)(value << shift); + } + + if (shift == s_end) + { + shift = s_start; + sp++; + dp++; + } + else + shift += s_inc; + if (m == 1) + m = 0x80; + else + m >>= 1; + } + break; + } + + case 8: + { + png_bytep srcptr; + png_bytep dstptr; + png_uint_32 len; + int m; + int diff, unmask; + + __int64 mask0=0x0102040810204080; + +#if !defined(PNG_1_0_X) + if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) + /* && mmx_supported */ ) +#else + if (mmx_supported) +#endif + { + srcptr = png_ptr->row_buf + 1; + dstptr = row; + m = 0x80; + unmask = ~mask; + len = png_ptr->width &~7; //reduce to multiple of 8 + diff = png_ptr->width & 7; //amount lost + + _asm + { + movd mm7, unmask //load bit pattern + psubb mm6,mm6 //zero mm6 + punpcklbw mm7,mm7 + punpcklwd mm7,mm7 + punpckldq mm7,mm7 //fill register with 8 masks + + movq mm0,mask0 + + pand mm0,mm7 //nonzero if keep byte + pcmpeqb mm0,mm6 //zeros->1s, v versa + + mov ecx,len //load length of line (pixels) + mov esi,srcptr //load source + mov ebx,dstptr //load dest + cmp ecx,0 //lcr + je mainloop8end + +mainloop8: + movq mm4,[esi] + pand mm4,mm0 + movq mm6,mm0 + pandn mm6,[ebx] + por mm4,mm6 + movq [ebx],mm4 + + add esi,8 //inc by 8 bytes processed + add ebx,8 + sub ecx,8 //dec by 8 pixels processed + + ja mainloop8 +mainloop8end: + + mov ecx,diff + cmp ecx,0 + jz end8 + + mov edx,mask + sal edx,24 //make low byte the high byte + +secondloop8: + sal edx,1 //move high bit to CF + jnc skip8 //if CF = 0 + mov al,[esi] + mov [ebx],al +skip8: + inc esi + inc ebx + + dec ecx + jnz secondloop8 +end8: + emms + } + } + else /* mmx not supported - use modified C routine */ + { + register unsigned int incr1, initial_val, final_val; + png_size_t pixel_bytes; + png_uint_32 i; + register int disp = png_pass_inc[png_ptr->pass]; + int offset_table[7] = {0, 4, 0, 2, 0, 1, 0}; + + pixel_bytes = (png_ptr->row_info.pixel_depth >> 3); + srcptr = png_ptr->row_buf + 1 + offset_table[png_ptr->pass]* + pixel_bytes; + dstptr = row + offset_table[png_ptr->pass]*pixel_bytes; + initial_val = offset_table[png_ptr->pass]*pixel_bytes; + final_val = png_ptr->width*pixel_bytes; + incr1 = (disp)*pixel_bytes; + for (i = initial_val; i < final_val; i += incr1) + { + png_memcpy(dstptr, srcptr, pixel_bytes); + srcptr += incr1; + dstptr += incr1; + } + } /* end of else */ + + break; + } // end 8 bpp + + case 16: + { + png_bytep srcptr; + png_bytep dstptr; + png_uint_32 len; + int unmask, diff; + __int64 mask1=0x0101020204040808, + mask0=0x1010202040408080; + +#if !defined(PNG_1_0_X) + if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) + /* && mmx_supported */ ) +#else + if (mmx_supported) +#endif + { + srcptr = png_ptr->row_buf + 1; + dstptr = row; + + unmask = ~mask; + len = (png_ptr->width)&~7; + diff = (png_ptr->width)&7; + _asm + { + movd mm7, unmask //load bit pattern + psubb mm6,mm6 //zero mm6 + punpcklbw mm7,mm7 + punpcklwd mm7,mm7 + punpckldq mm7,mm7 //fill register with 8 masks + + movq mm0,mask0 + movq mm1,mask1 + + pand mm0,mm7 + pand mm1,mm7 + + pcmpeqb mm0,mm6 + pcmpeqb mm1,mm6 + + mov ecx,len //load length of line + mov esi,srcptr //load source + mov ebx,dstptr //load dest + cmp ecx,0 //lcr + jz mainloop16end + +mainloop16: + movq mm4,[esi] + pand mm4,mm0 + movq mm6,mm0 + movq mm7,[ebx] + pandn mm6,mm7 + por mm4,mm6 + movq [ebx],mm4 + + movq mm5,[esi+8] + pand mm5,mm1 + movq mm7,mm1 + movq mm6,[ebx+8] + pandn mm7,mm6 + por mm5,mm7 + movq [ebx+8],mm5 + + add esi,16 //inc by 16 bytes processed + add ebx,16 + sub ecx,8 //dec by 8 pixels processed + + ja mainloop16 + +mainloop16end: + mov ecx,diff + cmp ecx,0 + jz end16 + + mov edx,mask + sal edx,24 //make low byte the high byte +secondloop16: + sal edx,1 //move high bit to CF + jnc skip16 //if CF = 0 + mov ax,[esi] + mov [ebx],ax +skip16: + add esi,2 + add ebx,2 + + dec ecx + jnz secondloop16 +end16: + emms + } + } + else /* mmx not supported - use modified C routine */ + { + register unsigned int incr1, initial_val, final_val; + png_size_t pixel_bytes; + png_uint_32 i; + register int disp = png_pass_inc[png_ptr->pass]; + int offset_table[7] = {0, 4, 0, 2, 0, 1, 0}; + + pixel_bytes = (png_ptr->row_info.pixel_depth >> 3); + srcptr = png_ptr->row_buf + 1 + offset_table[png_ptr->pass]* + pixel_bytes; + dstptr = row + offset_table[png_ptr->pass]*pixel_bytes; + initial_val = offset_table[png_ptr->pass]*pixel_bytes; + final_val = png_ptr->width*pixel_bytes; + incr1 = (disp)*pixel_bytes; + for (i = initial_val; i < final_val; i += incr1) + { + png_memcpy(dstptr, srcptr, pixel_bytes); + srcptr += incr1; + dstptr += incr1; + } + } /* end of else */ + + break; + } // end 16 bpp + + case 24: + { + png_bytep srcptr; + png_bytep dstptr; + png_uint_32 len; + int unmask, diff; + + __int64 mask2=0x0101010202020404, //24bpp + mask1=0x0408080810101020, + mask0=0x2020404040808080; + + srcptr = png_ptr->row_buf + 1; + dstptr = row; + + unmask = ~mask; + len = (png_ptr->width)&~7; + diff = (png_ptr->width)&7; + +#if !defined(PNG_1_0_X) + if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) + /* && mmx_supported */ ) +#else + if (mmx_supported) +#endif + { + _asm + { + movd mm7, unmask //load bit pattern + psubb mm6,mm6 //zero mm6 + punpcklbw mm7,mm7 + punpcklwd mm7,mm7 + punpckldq mm7,mm7 //fill register with 8 masks + + movq mm0,mask0 + movq mm1,mask1 + movq mm2,mask2 + + pand mm0,mm7 + pand mm1,mm7 + pand mm2,mm7 + + pcmpeqb mm0,mm6 + pcmpeqb mm1,mm6 + pcmpeqb mm2,mm6 + + mov ecx,len //load length of line + mov esi,srcptr //load source + mov ebx,dstptr //load dest + cmp ecx,0 + jz mainloop24end + +mainloop24: + movq mm4,[esi] + pand mm4,mm0 + movq mm6,mm0 + movq mm7,[ebx] + pandn mm6,mm7 + por mm4,mm6 + movq [ebx],mm4 + + + movq mm5,[esi+8] + pand mm5,mm1 + movq mm7,mm1 + movq mm6,[ebx+8] + pandn mm7,mm6 + por mm5,mm7 + movq [ebx+8],mm5 + + movq mm6,[esi+16] + pand mm6,mm2 + movq mm4,mm2 + movq mm7,[ebx+16] + pandn mm4,mm7 + por mm6,mm4 + movq [ebx+16],mm6 + + add esi,24 //inc by 24 bytes processed + add ebx,24 + sub ecx,8 //dec by 8 pixels processed + + ja mainloop24 + +mainloop24end: + mov ecx,diff + cmp ecx,0 + jz end24 + + mov edx,mask + sal edx,24 //make low byte the high byte +secondloop24: + sal edx,1 //move high bit to CF + jnc skip24 //if CF = 0 + mov ax,[esi] + mov [ebx],ax + xor eax,eax + mov al,[esi+2] + mov [ebx+2],al +skip24: + add esi,3 + add ebx,3 + + dec ecx + jnz secondloop24 + +end24: + emms + } + } + else /* mmx not supported - use modified C routine */ + { + register unsigned int incr1, initial_val, final_val; + png_size_t pixel_bytes; + png_uint_32 i; + register int disp = png_pass_inc[png_ptr->pass]; + int offset_table[7] = {0, 4, 0, 2, 0, 1, 0}; + + pixel_bytes = (png_ptr->row_info.pixel_depth >> 3); + srcptr = png_ptr->row_buf + 1 + offset_table[png_ptr->pass]* + pixel_bytes; + dstptr = row + offset_table[png_ptr->pass]*pixel_bytes; + initial_val = offset_table[png_ptr->pass]*pixel_bytes; + final_val = png_ptr->width*pixel_bytes; + incr1 = (disp)*pixel_bytes; + for (i = initial_val; i < final_val; i += incr1) + { + png_memcpy(dstptr, srcptr, pixel_bytes); + srcptr += incr1; + dstptr += incr1; + } + } /* end of else */ + + break; + } // end 24 bpp + + case 32: + { + png_bytep srcptr; + png_bytep dstptr; + png_uint_32 len; + int unmask, diff; + + __int64 mask3=0x0101010102020202, //32bpp + mask2=0x0404040408080808, + mask1=0x1010101020202020, + mask0=0x4040404080808080; + + srcptr = png_ptr->row_buf + 1; + dstptr = row; + + unmask = ~mask; + len = (png_ptr->width)&~7; + diff = (png_ptr->width)&7; + +#if !defined(PNG_1_0_X) + if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) + /* && mmx_supported */ ) +#else + if (mmx_supported) +#endif + { + _asm + { + movd mm7, unmask //load bit pattern + psubb mm6,mm6 //zero mm6 + punpcklbw mm7,mm7 + punpcklwd mm7,mm7 + punpckldq mm7,mm7 //fill register with 8 masks + + movq mm0,mask0 + movq mm1,mask1 + movq mm2,mask2 + movq mm3,mask3 + + pand mm0,mm7 + pand mm1,mm7 + pand mm2,mm7 + pand mm3,mm7 + + pcmpeqb mm0,mm6 + pcmpeqb mm1,mm6 + pcmpeqb mm2,mm6 + pcmpeqb mm3,mm6 + + mov ecx,len //load length of line + mov esi,srcptr //load source + mov ebx,dstptr //load dest + + cmp ecx,0 //lcr + jz mainloop32end + +mainloop32: + movq mm4,[esi] + pand mm4,mm0 + movq mm6,mm0 + movq mm7,[ebx] + pandn mm6,mm7 + por mm4,mm6 + movq [ebx],mm4 + + movq mm5,[esi+8] + pand mm5,mm1 + movq mm7,mm1 + movq mm6,[ebx+8] + pandn mm7,mm6 + por mm5,mm7 + movq [ebx+8],mm5 + + movq mm6,[esi+16] + pand mm6,mm2 + movq mm4,mm2 + movq mm7,[ebx+16] + pandn mm4,mm7 + por mm6,mm4 + movq [ebx+16],mm6 + + movq mm7,[esi+24] + pand mm7,mm3 + movq mm5,mm3 + movq mm4,[ebx+24] + pandn mm5,mm4 + por mm7,mm5 + movq [ebx+24],mm7 + + add esi,32 //inc by 32 bytes processed + add ebx,32 + sub ecx,8 //dec by 8 pixels processed + + ja mainloop32 + +mainloop32end: + mov ecx,diff + cmp ecx,0 + jz end32 + + mov edx,mask + sal edx,24 //make low byte the high byte +secondloop32: + sal edx,1 //move high bit to CF + jnc skip32 //if CF = 0 + mov eax,[esi] + mov [ebx],eax +skip32: + add esi,4 + add ebx,4 + + dec ecx + jnz secondloop32 + +end32: + emms + } + } + else /* mmx _not supported - Use modified C routine */ + { + register unsigned int incr1, initial_val, final_val; + png_size_t pixel_bytes; + png_uint_32 i; + register int disp = png_pass_inc[png_ptr->pass]; + int offset_table[7] = {0, 4, 0, 2, 0, 1, 0}; + + pixel_bytes = (png_ptr->row_info.pixel_depth >> 3); + srcptr = png_ptr->row_buf + 1 + offset_table[png_ptr->pass]* + pixel_bytes; + dstptr = row + offset_table[png_ptr->pass]*pixel_bytes; + initial_val = offset_table[png_ptr->pass]*pixel_bytes; + final_val = png_ptr->width*pixel_bytes; + incr1 = (disp)*pixel_bytes; + for (i = initial_val; i < final_val; i += incr1) + { + png_memcpy(dstptr, srcptr, pixel_bytes); + srcptr += incr1; + dstptr += incr1; + } + } /* end of else */ + + break; + } // end 32 bpp + + case 48: + { + png_bytep srcptr; + png_bytep dstptr; + png_uint_32 len; + int unmask, diff; + + __int64 mask5=0x0101010101010202, + mask4=0x0202020204040404, + mask3=0x0404080808080808, + mask2=0x1010101010102020, + mask1=0x2020202040404040, + mask0=0x4040808080808080; + +#if !defined(PNG_1_0_X) + if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) + /* && mmx_supported */ ) +#else + if (mmx_supported) +#endif + { + srcptr = png_ptr->row_buf + 1; + dstptr = row; + + unmask = ~mask; + len = (png_ptr->width)&~7; + diff = (png_ptr->width)&7; + _asm + { + movd mm7, unmask //load bit pattern + psubb mm6,mm6 //zero mm6 + punpcklbw mm7,mm7 + punpcklwd mm7,mm7 + punpckldq mm7,mm7 //fill register with 8 masks + + movq mm0,mask0 + movq mm1,mask1 + movq mm2,mask2 + movq mm3,mask3 + movq mm4,mask4 + movq mm5,mask5 + + pand mm0,mm7 + pand mm1,mm7 + pand mm2,mm7 + pand mm3,mm7 + pand mm4,mm7 + pand mm5,mm7 + + pcmpeqb mm0,mm6 + pcmpeqb mm1,mm6 + pcmpeqb mm2,mm6 + pcmpeqb mm3,mm6 + pcmpeqb mm4,mm6 + pcmpeqb mm5,mm6 + + mov ecx,len //load length of line + mov esi,srcptr //load source + mov ebx,dstptr //load dest + + cmp ecx,0 + jz mainloop48end + +mainloop48: + movq mm7,[esi] + pand mm7,mm0 + movq mm6,mm0 + pandn mm6,[ebx] + por mm7,mm6 + movq [ebx],mm7 + + movq mm6,[esi+8] + pand mm6,mm1 + movq mm7,mm1 + pandn mm7,[ebx+8] + por mm6,mm7 + movq [ebx+8],mm6 + + movq mm6,[esi+16] + pand mm6,mm2 + movq mm7,mm2 + pandn mm7,[ebx+16] + por mm6,mm7 + movq [ebx+16],mm6 + + movq mm7,[esi+24] + pand mm7,mm3 + movq mm6,mm3 + pandn mm6,[ebx+24] + por mm7,mm6 + movq [ebx+24],mm7 + + movq mm6,[esi+32] + pand mm6,mm4 + movq mm7,mm4 + pandn mm7,[ebx+32] + por mm6,mm7 + movq [ebx+32],mm6 + + movq mm7,[esi+40] + pand mm7,mm5 + movq mm6,mm5 + pandn mm6,[ebx+40] + por mm7,mm6 + movq [ebx+40],mm7 + + add esi,48 //inc by 32 bytes processed + add ebx,48 + sub ecx,8 //dec by 8 pixels processed + + ja mainloop48 +mainloop48end: + + mov ecx,diff + cmp ecx,0 + jz end48 + + mov edx,mask + sal edx,24 //make low byte the high byte + +secondloop48: + sal edx,1 //move high bit to CF + jnc skip48 //if CF = 0 + mov eax,[esi] + mov [ebx],eax +skip48: + add esi,4 + add ebx,4 + + dec ecx + jnz secondloop48 + +end48: + emms + } + } + else /* mmx _not supported - Use modified C routine */ + { + register unsigned int incr1, initial_val, final_val; + png_size_t pixel_bytes; + png_uint_32 i; + register int disp = png_pass_inc[png_ptr->pass]; + int offset_table[7] = {0, 4, 0, 2, 0, 1, 0}; + + pixel_bytes = (png_ptr->row_info.pixel_depth >> 3); + srcptr = png_ptr->row_buf + 1 + offset_table[png_ptr->pass]* + pixel_bytes; + dstptr = row + offset_table[png_ptr->pass]*pixel_bytes; + initial_val = offset_table[png_ptr->pass]*pixel_bytes; + final_val = png_ptr->width*pixel_bytes; + incr1 = (disp)*pixel_bytes; + for (i = initial_val; i < final_val; i += incr1) + { + png_memcpy(dstptr, srcptr, pixel_bytes); + srcptr += incr1; + dstptr += incr1; + } + } /* end of else */ + + break; + } // end 48 bpp + + default: + { + png_bytep sptr; + png_bytep dp; + png_size_t pixel_bytes; + int offset_table[7] = {0, 4, 0, 2, 0, 1, 0}; + unsigned int i; + register int disp = png_pass_inc[png_ptr->pass]; // get the offset + register unsigned int incr1, initial_val, final_val; + + pixel_bytes = (png_ptr->row_info.pixel_depth >> 3); + sptr = png_ptr->row_buf + 1 + offset_table[png_ptr->pass]* + pixel_bytes; + dp = row + offset_table[png_ptr->pass]*pixel_bytes; + initial_val = offset_table[png_ptr->pass]*pixel_bytes; + final_val = png_ptr->width*pixel_bytes; + incr1 = (disp)*pixel_bytes; + for (i = initial_val; i < final_val; i += incr1) + { + png_memcpy(dp, sptr, pixel_bytes); + sptr += incr1; + dp += incr1; + } + break; + } + } /* end switch (png_ptr->row_info.pixel_depth) */ + } /* end if (non-trivial mask) */ + +} /* end png_combine_row() */ + + +#if defined(PNG_READ_INTERLACING_SUPPORTED) + +void /* PRIVATE */ +png_do_read_interlace(png_structp png_ptr) +{ + png_row_infop row_info = &(png_ptr->row_info); + png_bytep row = png_ptr->row_buf + 1; + int pass = png_ptr->pass; + png_uint_32 transformations = png_ptr->transformations; +#ifdef PNG_USE_LOCAL_ARRAYS + const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; +#endif + + png_debug(1,"in png_do_read_interlace\n"); + + if (mmx_supported == 2) { +#if !defined(PNG_1_0_X) + /* this should have happened in png_init_mmx_flags() already */ + png_warning(png_ptr, "asm_flags may not have been initialized"); +#endif + png_mmx_support(); + } + + if (row != NULL && row_info != NULL) + { + png_uint_32 final_width; + + final_width = row_info->width * png_pass_inc[pass]; + + switch (row_info->pixel_depth) + { + case 1: + { + png_bytep sp, dp; + int sshift, dshift; + int s_start, s_end, s_inc; + png_byte v; + png_uint_32 i; + int j; + + sp = row + (png_size_t)((row_info->width - 1) >> 3); + dp = row + (png_size_t)((final_width - 1) >> 3); +#if defined(PNG_READ_PACKSWAP_SUPPORTED) + if (transformations & PNG_PACKSWAP) + { + sshift = (int)((row_info->width + 7) & 7); + dshift = (int)((final_width + 7) & 7); + s_start = 7; + s_end = 0; + s_inc = -1; + } + else +#endif + { + sshift = 7 - (int)((row_info->width + 7) & 7); + dshift = 7 - (int)((final_width + 7) & 7); + s_start = 0; + s_end = 7; + s_inc = 1; + } + + for (i = row_info->width; i; i--) + { + v = (png_byte)((*sp >> sshift) & 0x1); + for (j = 0; j < png_pass_inc[pass]; j++) + { + *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff); + *dp |= (png_byte)(v << dshift); + if (dshift == s_end) + { + dshift = s_start; + dp--; + } + else + dshift += s_inc; + } + if (sshift == s_end) + { + sshift = s_start; + sp--; + } + else + sshift += s_inc; + } + break; + } + + case 2: + { + png_bytep sp, dp; + int sshift, dshift; + int s_start, s_end, s_inc; + png_uint_32 i; + + sp = row + (png_size_t)((row_info->width - 1) >> 2); + dp = row + (png_size_t)((final_width - 1) >> 2); +#if defined(PNG_READ_PACKSWAP_SUPPORTED) + if (transformations & PNG_PACKSWAP) + { + sshift = (png_size_t)(((row_info->width + 3) & 3) << 1); + dshift = (png_size_t)(((final_width + 3) & 3) << 1); + s_start = 6; + s_end = 0; + s_inc = -2; + } + else +#endif + { + sshift = (png_size_t)((3 - ((row_info->width + 3) & 3)) << 1); + dshift = (png_size_t)((3 - ((final_width + 3) & 3)) << 1); + s_start = 0; + s_end = 6; + s_inc = 2; + } + + for (i = row_info->width; i; i--) + { + png_byte v; + int j; + + v = (png_byte)((*sp >> sshift) & 0x3); + for (j = 0; j < png_pass_inc[pass]; j++) + { + *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff); + *dp |= (png_byte)(v << dshift); + if (dshift == s_end) + { + dshift = s_start; + dp--; + } + else + dshift += s_inc; + } + if (sshift == s_end) + { + sshift = s_start; + sp--; + } + else + sshift += s_inc; + } + break; + } + + case 4: + { + png_bytep sp, dp; + int sshift, dshift; + int s_start, s_end, s_inc; + png_uint_32 i; + + sp = row + (png_size_t)((row_info->width - 1) >> 1); + dp = row + (png_size_t)((final_width - 1) >> 1); +#if defined(PNG_READ_PACKSWAP_SUPPORTED) + if (transformations & PNG_PACKSWAP) + { + sshift = (png_size_t)(((row_info->width + 1) & 1) << 2); + dshift = (png_size_t)(((final_width + 1) & 1) << 2); + s_start = 4; + s_end = 0; + s_inc = -4; + } + else +#endif + { + sshift = (png_size_t)((1 - ((row_info->width + 1) & 1)) << 2); + dshift = (png_size_t)((1 - ((final_width + 1) & 1)) << 2); + s_start = 0; + s_end = 4; + s_inc = 4; + } + + for (i = row_info->width; i; i--) + { + png_byte v; + int j; + + v = (png_byte)((*sp >> sshift) & 0xf); + for (j = 0; j < png_pass_inc[pass]; j++) + { + *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff); + *dp |= (png_byte)(v << dshift); + if (dshift == s_end) + { + dshift = s_start; + dp--; + } + else + dshift += s_inc; + } + if (sshift == s_end) + { + sshift = s_start; + sp--; + } + else + sshift += s_inc; + } + break; + } + + default: // This is the place where the routine is modified + { + __int64 const4 = 0x0000000000FFFFFF; + // __int64 const5 = 0x000000FFFFFF0000; // unused... + __int64 const6 = 0x00000000000000FF; + png_bytep sptr, dp; + png_uint_32 i; + png_size_t pixel_bytes; + int width = row_info->width; + + pixel_bytes = (row_info->pixel_depth >> 3); + + sptr = row + (width - 1) * pixel_bytes; + dp = row + (final_width - 1) * pixel_bytes; + // New code by Nirav Chhatrapati - Intel Corporation + // sign fix by GRR + // NOTE: there is NO MMX code for 48-bit and 64-bit images + + // use MMX routine if machine supports it +#if !defined(PNG_1_0_X) + if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_INTERLACE) + /* && mmx_supported */ ) +#else + if (mmx_supported) +#endif + { + if (pixel_bytes == 3) + { + if (((pass == 0) || (pass == 1)) && width) + { + _asm + { + mov esi, sptr + mov edi, dp + mov ecx, width + sub edi, 21 // (png_pass_inc[pass] - 1)*pixel_bytes +loop_pass0: + movd mm0, [esi] ; X X X X X v2 v1 v0 + pand mm0, const4 ; 0 0 0 0 0 v2 v1 v0 + movq mm1, mm0 ; 0 0 0 0 0 v2 v1 v0 + psllq mm0, 16 ; 0 0 0 v2 v1 v0 0 0 + movq mm2, mm0 ; 0 0 0 v2 v1 v0 0 0 + psllq mm0, 24 ; v2 v1 v0 0 0 0 0 0 + psrlq mm1, 8 ; 0 0 0 0 0 0 v2 v1 + por mm0, mm2 ; v2 v1 v0 v2 v1 v0 0 0 + por mm0, mm1 ; v2 v1 v0 v2 v1 v0 v2 v1 + movq mm3, mm0 ; v2 v1 v0 v2 v1 v0 v2 v1 + psllq mm0, 16 ; v0 v2 v1 v0 v2 v1 0 0 + movq mm4, mm3 ; v2 v1 v0 v2 v1 v0 v2 v1 + punpckhdq mm3, mm0 ; v0 v2 v1 v0 v2 v1 v0 v2 + movq [edi+16] , mm4 + psrlq mm0, 32 ; 0 0 0 0 v0 v2 v1 v0 + movq [edi+8] , mm3 + punpckldq mm0, mm4 ; v1 v0 v2 v1 v0 v2 v1 v0 + sub esi, 3 + movq [edi], mm0 + sub edi, 24 + //sub esi, 3 + dec ecx + jnz loop_pass0 + EMMS + } + } + else if (((pass == 2) || (pass == 3)) && width) + { + _asm + { + mov esi, sptr + mov edi, dp + mov ecx, width + sub edi, 9 // (png_pass_inc[pass] - 1)*pixel_bytes +loop_pass2: + movd mm0, [esi] ; X X X X X v2 v1 v0 + pand mm0, const4 ; 0 0 0 0 0 v2 v1 v0 + movq mm1, mm0 ; 0 0 0 0 0 v2 v1 v0 + psllq mm0, 16 ; 0 0 0 v2 v1 v0 0 0 + movq mm2, mm0 ; 0 0 0 v2 v1 v0 0 0 + psllq mm0, 24 ; v2 v1 v0 0 0 0 0 0 + psrlq mm1, 8 ; 0 0 0 0 0 0 v2 v1 + por mm0, mm2 ; v2 v1 v0 v2 v1 v0 0 0 + por mm0, mm1 ; v2 v1 v0 v2 v1 v0 v2 v1 + movq [edi+4], mm0 ; move to memory + psrlq mm0, 16 ; 0 0 v2 v1 v0 v2 v1 v0 + movd [edi], mm0 ; move to memory + sub esi, 3 + sub edi, 12 + dec ecx + jnz loop_pass2 + EMMS + } + } + else if (width) /* && ((pass == 4) || (pass == 5)) */ + { + int width_mmx = ((width >> 1) << 1) - 8; + if (width_mmx < 0) + width_mmx = 0; + width -= width_mmx; // 8 or 9 pix, 24 or 27 bytes + if (width_mmx) + { + _asm + { + mov esi, sptr + mov edi, dp + mov ecx, width_mmx + sub esi, 3 + sub edi, 9 +loop_pass4: + movq mm0, [esi] ; X X v2 v1 v0 v5 v4 v3 + movq mm7, mm0 ; X X v2 v1 v0 v5 v4 v3 + movq mm6, mm0 ; X X v2 v1 v0 v5 v4 v3 + psllq mm0, 24 ; v1 v0 v5 v4 v3 0 0 0 + pand mm7, const4 ; 0 0 0 0 0 v5 v4 v3 + psrlq mm6, 24 ; 0 0 0 X X v2 v1 v0 + por mm0, mm7 ; v1 v0 v5 v4 v3 v5 v4 v3 + movq mm5, mm6 ; 0 0 0 X X v2 v1 v0 + psllq mm6, 8 ; 0 0 X X v2 v1 v0 0 + movq [edi], mm0 ; move quad to memory + psrlq mm5, 16 ; 0 0 0 0 0 X X v2 + pand mm5, const6 ; 0 0 0 0 0 0 0 v2 + por mm6, mm5 ; 0 0 X X v2 v1 v0 v2 + movd [edi+8], mm6 ; move double to memory + sub esi, 6 + sub edi, 12 + sub ecx, 2 + jnz loop_pass4 + EMMS + } + } + + sptr -= width_mmx*3; + dp -= width_mmx*6; + for (i = width; i; i--) + { + png_byte v[8]; + int j; + + png_memcpy(v, sptr, 3); + for (j = 0; j < png_pass_inc[pass]; j++) + { + png_memcpy(dp, v, 3); + dp -= 3; + } + sptr -= 3; + } + } + } /* end of pixel_bytes == 3 */ + + else if (pixel_bytes == 1) + { + if (((pass == 0) || (pass == 1)) && width) + { + int width_mmx = ((width >> 2) << 2); + width -= width_mmx; + if (width_mmx) + { + _asm + { + mov esi, sptr + mov edi, dp + mov ecx, width_mmx + sub edi, 31 + sub esi, 3 +loop1_pass0: + movd mm0, [esi] ; X X X X v0 v1 v2 v3 + movq mm1, mm0 ; X X X X v0 v1 v2 v3 + punpcklbw mm0, mm0 ; v0 v0 v1 v1 v2 v2 v3 v3 + movq mm2, mm0 ; v0 v0 v1 v1 v2 v2 v3 v3 + punpcklwd mm0, mm0 ; v2 v2 v2 v2 v3 v3 v3 v3 + movq mm3, mm0 ; v2 v2 v2 v2 v3 v3 v3 v3 + punpckldq mm0, mm0 ; v3 v3 v3 v3 v3 v3 v3 v3 + punpckhdq mm3, mm3 ; v2 v2 v2 v2 v2 v2 v2 v2 + movq [edi], mm0 ; move to memory v3 + punpckhwd mm2, mm2 ; v0 v0 v0 v0 v1 v1 v1 v1 + movq [edi+8], mm3 ; move to memory v2 + movq mm4, mm2 ; v0 v0 v0 v0 v1 v1 v1 v1 + punpckldq mm2, mm2 ; v1 v1 v1 v1 v1 v1 v1 v1 + punpckhdq mm4, mm4 ; v0 v0 v0 v0 v0 v0 v0 v0 + movq [edi+16], mm2 ; move to memory v1 + movq [edi+24], mm4 ; move to memory v0 + sub esi, 4 + sub edi, 32 + sub ecx, 4 + jnz loop1_pass0 + EMMS + } + } + + sptr -= width_mmx; + dp -= width_mmx*8; + for (i = width; i; i--) + { + int j; + + /* I simplified this part in version 1.0.4e + * here and in several other instances where + * pixel_bytes == 1 -- GR-P + * + * Original code: + * + * png_byte v[8]; + * png_memcpy(v, sptr, pixel_bytes); + * for (j = 0; j < png_pass_inc[pass]; j++) + * { + * png_memcpy(dp, v, pixel_bytes); + * dp -= pixel_bytes; + * } + * sptr -= pixel_bytes; + * + * Replacement code is in the next three lines: + */ + + for (j = 0; j < png_pass_inc[pass]; j++) + *dp-- = *sptr; + sptr--; + } + } + else if (((pass == 2) || (pass == 3)) && width) + { + int width_mmx = ((width >> 2) << 2); + width -= width_mmx; + if (width_mmx) + { + _asm + { + mov esi, sptr + mov edi, dp + mov ecx, width_mmx + sub edi, 15 + sub esi, 3 +loop1_pass2: + movd mm0, [esi] ; X X X X v0 v1 v2 v3 + punpcklbw mm0, mm0 ; v0 v0 v1 v1 v2 v2 v3 v3 + movq mm1, mm0 ; v0 v0 v1 v1 v2 v2 v3 v3 + punpcklwd mm0, mm0 ; v2 v2 v2 v2 v3 v3 v3 v3 + punpckhwd mm1, mm1 ; v0 v0 v0 v0 v1 v1 v1 v1 + movq [edi], mm0 ; move to memory v2 and v3 + sub esi, 4 + movq [edi+8], mm1 ; move to memory v1 and v0 + sub edi, 16 + sub ecx, 4 + jnz loop1_pass2 + EMMS + } + } + + sptr -= width_mmx; + dp -= width_mmx*4; + for (i = width; i; i--) + { + int j; + + for (j = 0; j < png_pass_inc[pass]; j++) + { + *dp-- = *sptr; + } + sptr --; + } + } + else if (width) /* && ((pass == 4) || (pass == 5))) */ + { + int width_mmx = ((width >> 3) << 3); + width -= width_mmx; + if (width_mmx) + { + _asm + { + mov esi, sptr + mov edi, dp + mov ecx, width_mmx + sub edi, 15 + sub esi, 7 +loop1_pass4: + movq mm0, [esi] ; v0 v1 v2 v3 v4 v5 v6 v7 + movq mm1, mm0 ; v0 v1 v2 v3 v4 v5 v6 v7 + punpcklbw mm0, mm0 ; v4 v4 v5 v5 v6 v6 v7 v7 + //movq mm1, mm0 ; v0 v0 v1 v1 v2 v2 v3 v3 + punpckhbw mm1, mm1 ;v0 v0 v1 v1 v2 v2 v3 v3 + movq [edi+8], mm1 ; move to memory v0 v1 v2 and v3 + sub esi, 8 + movq [edi], mm0 ; move to memory v4 v5 v6 and v7 + //sub esi, 4 + sub edi, 16 + sub ecx, 8 + jnz loop1_pass4 + EMMS + } + } + + sptr -= width_mmx; + dp -= width_mmx*2; + for (i = width; i; i--) + { + int j; + + for (j = 0; j < png_pass_inc[pass]; j++) + { + *dp-- = *sptr; + } + sptr --; + } + } + } /* end of pixel_bytes == 1 */ + + else if (pixel_bytes == 2) + { + if (((pass == 0) || (pass == 1)) && width) + { + int width_mmx = ((width >> 1) << 1); + width -= width_mmx; + if (width_mmx) + { + _asm + { + mov esi, sptr + mov edi, dp + mov ecx, width_mmx + sub esi, 2 + sub edi, 30 +loop2_pass0: + movd mm0, [esi] ; X X X X v1 v0 v3 v2 + punpcklwd mm0, mm0 ; v1 v0 v1 v0 v3 v2 v3 v2 + movq mm1, mm0 ; v1 v0 v1 v0 v3 v2 v3 v2 + punpckldq mm0, mm0 ; v3 v2 v3 v2 v3 v2 v3 v2 + punpckhdq mm1, mm1 ; v1 v0 v1 v0 v1 v0 v1 v0 + movq [edi], mm0 + movq [edi + 8], mm0 + movq [edi + 16], mm1 + movq [edi + 24], mm1 + sub esi, 4 + sub edi, 32 + sub ecx, 2 + jnz loop2_pass0 + EMMS + } + } + + sptr -= (width_mmx*2 - 2); // sign fixed + dp -= (width_mmx*16 - 2); // sign fixed + for (i = width; i; i--) + { + png_byte v[8]; + int j; + sptr -= 2; + png_memcpy(v, sptr, 2); + for (j = 0; j < png_pass_inc[pass]; j++) + { + dp -= 2; + png_memcpy(dp, v, 2); + } + } + } + else if (((pass == 2) || (pass == 3)) && width) + { + int width_mmx = ((width >> 1) << 1) ; + width -= width_mmx; + if (width_mmx) + { + _asm + { + mov esi, sptr + mov edi, dp + mov ecx, width_mmx + sub esi, 2 + sub edi, 14 +loop2_pass2: + movd mm0, [esi] ; X X X X v1 v0 v3 v2 + punpcklwd mm0, mm0 ; v1 v0 v1 v0 v3 v2 v3 v2 + movq mm1, mm0 ; v1 v0 v1 v0 v3 v2 v3 v2 + punpckldq mm0, mm0 ; v3 v2 v3 v2 v3 v2 v3 v2 + punpckhdq mm1, mm1 ; v1 v0 v1 v0 v1 v0 v1 v0 + movq [edi], mm0 + sub esi, 4 + movq [edi + 8], mm1 + //sub esi, 4 + sub edi, 16 + sub ecx, 2 + jnz loop2_pass2 + EMMS + } + } + + sptr -= (width_mmx*2 - 2); // sign fixed + dp -= (width_mmx*8 - 2); // sign fixed + for (i = width; i; i--) + { + png_byte v[8]; + int j; + sptr -= 2; + png_memcpy(v, sptr, 2); + for (j = 0; j < png_pass_inc[pass]; j++) + { + dp -= 2; + png_memcpy(dp, v, 2); + } + } + } + else if (width) // pass == 4 or 5 + { + int width_mmx = ((width >> 1) << 1) ; + width -= width_mmx; + if (width_mmx) + { + _asm + { + mov esi, sptr + mov edi, dp + mov ecx, width_mmx + sub esi, 2 + sub edi, 6 +loop2_pass4: + movd mm0, [esi] ; X X X X v1 v0 v3 v2 + punpcklwd mm0, mm0 ; v1 v0 v1 v0 v3 v2 v3 v2 + sub esi, 4 + movq [edi], mm0 + sub edi, 8 + sub ecx, 2 + jnz loop2_pass4 + EMMS + } + } + + sptr -= (width_mmx*2 - 2); // sign fixed + dp -= (width_mmx*4 - 2); // sign fixed + for (i = width; i; i--) + { + png_byte v[8]; + int j; + sptr -= 2; + png_memcpy(v, sptr, 2); + for (j = 0; j < png_pass_inc[pass]; j++) + { + dp -= 2; + png_memcpy(dp, v, 2); + } + } + } + } /* end of pixel_bytes == 2 */ + + else if (pixel_bytes == 4) + { + if (((pass == 0) || (pass == 1)) && width) + { + int width_mmx = ((width >> 1) << 1) ; + width -= width_mmx; + if (width_mmx) + { + _asm + { + mov esi, sptr + mov edi, dp + mov ecx, width_mmx + sub esi, 4 + sub edi, 60 +loop4_pass0: + movq mm0, [esi] ; v3 v2 v1 v0 v7 v6 v5 v4 + movq mm1, mm0 ; v3 v2 v1 v0 v7 v6 v5 v4 + punpckldq mm0, mm0 ; v7 v6 v5 v4 v7 v6 v5 v4 + punpckhdq mm1, mm1 ; v3 v2 v1 v0 v3 v2 v1 v0 + movq [edi], mm0 + movq [edi + 8], mm0 + movq [edi + 16], mm0 + movq [edi + 24], mm0 + movq [edi+32], mm1 + movq [edi + 40], mm1 + movq [edi+ 48], mm1 + sub esi, 8 + movq [edi + 56], mm1 + sub edi, 64 + sub ecx, 2 + jnz loop4_pass0 + EMMS + } + } + + sptr -= (width_mmx*4 - 4); // sign fixed + dp -= (width_mmx*32 - 4); // sign fixed + for (i = width; i; i--) + { + png_byte v[8]; + int j; + sptr -= 4; + png_memcpy(v, sptr, 4); + for (j = 0; j < png_pass_inc[pass]; j++) + { + dp -= 4; + png_memcpy(dp, v, 4); + } + } + } + else if (((pass == 2) || (pass == 3)) && width) + { + int width_mmx = ((width >> 1) << 1) ; + width -= width_mmx; + if (width_mmx) + { + _asm + { + mov esi, sptr + mov edi, dp + mov ecx, width_mmx + sub esi, 4 + sub edi, 28 +loop4_pass2: + movq mm0, [esi] ; v3 v2 v1 v0 v7 v6 v5 v4 + movq mm1, mm0 ; v3 v2 v1 v0 v7 v6 v5 v4 + punpckldq mm0, mm0 ; v7 v6 v5 v4 v7 v6 v5 v4 + punpckhdq mm1, mm1 ; v3 v2 v1 v0 v3 v2 v1 v0 + movq [edi], mm0 + movq [edi + 8], mm0 + movq [edi+16], mm1 + movq [edi + 24], mm1 + sub esi, 8 + sub edi, 32 + sub ecx, 2 + jnz loop4_pass2 + EMMS + } + } + + sptr -= (width_mmx*4 - 4); // sign fixed + dp -= (width_mmx*16 - 4); // sign fixed + for (i = width; i; i--) + { + png_byte v[8]; + int j; + sptr -= 4; + png_memcpy(v, sptr, 4); + for (j = 0; j < png_pass_inc[pass]; j++) + { + dp -= 4; + png_memcpy(dp, v, 4); + } + } + } + else if (width) // pass == 4 or 5 + { + int width_mmx = ((width >> 1) << 1) ; + width -= width_mmx; + if (width_mmx) + { + _asm + { + mov esi, sptr + mov edi, dp + mov ecx, width_mmx + sub esi, 4 + sub edi, 12 +loop4_pass4: + movq mm0, [esi] ; v3 v2 v1 v0 v7 v6 v5 v4 + movq mm1, mm0 ; v3 v2 v1 v0 v7 v6 v5 v4 + punpckldq mm0, mm0 ; v7 v6 v5 v4 v7 v6 v5 v4 + punpckhdq mm1, mm1 ; v3 v2 v1 v0 v3 v2 v1 v0 + movq [edi], mm0 + sub esi, 8 + movq [edi + 8], mm1 + sub edi, 16 + sub ecx, 2 + jnz loop4_pass4 + EMMS + } + } + + sptr -= (width_mmx*4 - 4); // sign fixed + dp -= (width_mmx*8 - 4); // sign fixed + for (i = width; i; i--) + { + png_byte v[8]; + int j; + sptr -= 4; + png_memcpy(v, sptr, 4); + for (j = 0; j < png_pass_inc[pass]; j++) + { + dp -= 4; + png_memcpy(dp, v, 4); + } + } + } + + } /* end of pixel_bytes == 4 */ + + else if (pixel_bytes == 6) + { + for (i = width; i; i--) + { + png_byte v[8]; + int j; + png_memcpy(v, sptr, 6); + for (j = 0; j < png_pass_inc[pass]; j++) + { + png_memcpy(dp, v, 6); + dp -= 6; + } + sptr -= 6; + } + } /* end of pixel_bytes == 6 */ + + else + { + for (i = width; i; i--) + { + png_byte v[8]; + int j; + png_memcpy(v, sptr, pixel_bytes); + for (j = 0; j < png_pass_inc[pass]; j++) + { + png_memcpy(dp, v, pixel_bytes); + dp -= pixel_bytes; + } + sptr-= pixel_bytes; + } + } + } /* end of mmx_supported */ + + else /* MMX not supported: use modified C code - takes advantage + * of inlining of memcpy for a constant */ + { + if (pixel_bytes == 1) + { + for (i = width; i; i--) + { + int j; + for (j = 0; j < png_pass_inc[pass]; j++) + *dp-- = *sptr; + sptr--; + } + } + else if (pixel_bytes == 3) + { + for (i = width; i; i--) + { + png_byte v[8]; + int j; + png_memcpy(v, sptr, pixel_bytes); + for (j = 0; j < png_pass_inc[pass]; j++) + { + png_memcpy(dp, v, pixel_bytes); + dp -= pixel_bytes; + } + sptr -= pixel_bytes; + } + } + else if (pixel_bytes == 2) + { + for (i = width; i; i--) + { + png_byte v[8]; + int j; + png_memcpy(v, sptr, pixel_bytes); + for (j = 0; j < png_pass_inc[pass]; j++) + { + png_memcpy(dp, v, pixel_bytes); + dp -= pixel_bytes; + } + sptr -= pixel_bytes; + } + } + else if (pixel_bytes == 4) + { + for (i = width; i; i--) + { + png_byte v[8]; + int j; + png_memcpy(v, sptr, pixel_bytes); + for (j = 0; j < png_pass_inc[pass]; j++) + { + png_memcpy(dp, v, pixel_bytes); + dp -= pixel_bytes; + } + sptr -= pixel_bytes; + } + } + else if (pixel_bytes == 6) + { + for (i = width; i; i--) + { + png_byte v[8]; + int j; + png_memcpy(v, sptr, pixel_bytes); + for (j = 0; j < png_pass_inc[pass]; j++) + { + png_memcpy(dp, v, pixel_bytes); + dp -= pixel_bytes; + } + sptr -= pixel_bytes; + } + } + else + { + for (i = width; i; i--) + { + png_byte v[8]; + int j; + png_memcpy(v, sptr, pixel_bytes); + for (j = 0; j < png_pass_inc[pass]; j++) + { + png_memcpy(dp, v, pixel_bytes); + dp -= pixel_bytes; + } + sptr -= pixel_bytes; + } + } + + } /* end of MMX not supported */ + break; + } + } /* end switch (row_info->pixel_depth) */ + + row_info->width = final_width; + + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,final_width); + } + +} + +#endif /* PNG_READ_INTERLACING_SUPPORTED */ + + +// These variables are utilized in the functions below. They are declared +// globally here to ensure alignment on 8-byte boundaries. + +union uAll { + __int64 use; + double align; +} LBCarryMask = {0x0101010101010101}, + HBClearMask = {0x7f7f7f7f7f7f7f7f}, + ActiveMask, ActiveMask2, ActiveMaskEnd, ShiftBpp, ShiftRem; + + +// Optimized code for PNG Average filter decoder +void /* PRIVATE */ +png_read_filter_row_mmx_avg(png_row_infop row_info, png_bytep row + , png_bytep prev_row) +{ + int bpp; + png_uint_32 FullLength; + png_uint_32 MMXLength; + //png_uint_32 len; + int diff; + + bpp = (row_info->pixel_depth + 7) >> 3; // Get # bytes per pixel + FullLength = row_info->rowbytes; // # of bytes to filter + _asm { + // Init address pointers and offset + mov edi, row // edi ==> Avg(x) + xor ebx, ebx // ebx ==> x + mov edx, edi + mov esi, prev_row // esi ==> Prior(x) + sub edx, bpp // edx ==> Raw(x-bpp) + + xor eax, eax + // Compute the Raw value for the first bpp bytes + // Raw(x) = Avg(x) + (Prior(x)/2) +davgrlp: + mov al, [esi + ebx] // Load al with Prior(x) + inc ebx + shr al, 1 // divide by 2 + add al, [edi+ebx-1] // Add Avg(x); -1 to offset inc ebx + cmp ebx, bpp + mov [edi+ebx-1], al // Write back Raw(x); + // mov does not affect flags; -1 to offset inc ebx + jb davgrlp + // get # of bytes to alignment + mov diff, edi // take start of row + add diff, ebx // add bpp + add diff, 0xf // add 7 + 8 to incr past alignment boundary + and diff, 0xfffffff8 // mask to alignment boundary + sub diff, edi // subtract from start ==> value ebx at alignment + jz davggo + // fix alignment + // Compute the Raw value for the bytes upto the alignment boundary + // Raw(x) = Avg(x) + ((Raw(x-bpp) + Prior(x))/2) + xor ecx, ecx +davglp1: + xor eax, eax + mov cl, [esi + ebx] // load cl with Prior(x) + mov al, [edx + ebx] // load al with Raw(x-bpp) + add ax, cx + inc ebx + shr ax, 1 // divide by 2 + add al, [edi+ebx-1] // Add Avg(x); -1 to offset inc ebx + cmp ebx, diff // Check if at alignment boundary + mov [edi+ebx-1], al // Write back Raw(x); + // mov does not affect flags; -1 to offset inc ebx + jb davglp1 // Repeat until at alignment boundary +davggo: + mov eax, FullLength + mov ecx, eax + sub eax, ebx // subtract alignment fix + and eax, 0x00000007 // calc bytes over mult of 8 + sub ecx, eax // drop over bytes from original length + mov MMXLength, ecx + } // end _asm block + // Now do the math for the rest of the row + switch ( bpp ) + { + case 3: + { + ActiveMask.use = 0x0000000000ffffff; + ShiftBpp.use = 24; // == 3 * 8 + ShiftRem.use = 40; // == 64 - 24 + _asm { + // Re-init address pointers and offset + movq mm7, ActiveMask + mov ebx, diff // ebx ==> x = offset to alignment boundary + movq mm5, LBCarryMask + mov edi, row // edi ==> Avg(x) + movq mm4, HBClearMask + mov esi, prev_row // esi ==> Prior(x) + // PRIME the pump (load the first Raw(x-bpp) data set + movq mm2, [edi + ebx - 8] // Load previous aligned 8 bytes + // (we correct position in loop below) +davg3lp: + movq mm0, [edi + ebx] // Load mm0 with Avg(x) + // Add (Prev_row/2) to Average + movq mm3, mm5 + psrlq mm2, ShiftRem // Correct position Raw(x-bpp) data + movq mm1, [esi + ebx] // Load mm1 with Prior(x) + movq mm6, mm7 + pand mm3, mm1 // get lsb for each prev_row byte + psrlq mm1, 1 // divide prev_row bytes by 2 + pand mm1, mm4 // clear invalid bit 7 of each byte + paddb mm0, mm1 // add (Prev_row/2) to Avg for each byte + // Add 1st active group (Raw(x-bpp)/2) to Average with LBCarry + movq mm1, mm3 // now use mm1 for getting LBCarrys + pand mm1, mm2 // get LBCarrys for each byte where both + // lsb's were == 1 (Only valid for active group) + psrlq mm2, 1 // divide raw bytes by 2 + pand mm2, mm4 // clear invalid bit 7 of each byte + paddb mm2, mm1 // add LBCarrys to (Raw(x-bpp)/2) for each byte + pand mm2, mm6 // Leave only Active Group 1 bytes to add to Avg + paddb mm0, mm2 // add (Raw/2) + LBCarrys to Avg for each Active + // byte + // Add 2nd active group (Raw(x-bpp)/2) to Average with LBCarry + psllq mm6, ShiftBpp // shift the mm6 mask to cover bytes 3-5 + movq mm2, mm0 // mov updated Raws to mm2 + psllq mm2, ShiftBpp // shift data to position correctly + movq mm1, mm3 // now use mm1 for getting LBCarrys + pand mm1, mm2 // get LBCarrys for each byte where both + // lsb's were == 1 (Only valid for active group) + psrlq mm2, 1 // divide raw bytes by 2 + pand mm2, mm4 // clear invalid bit 7 of each byte + paddb mm2, mm1 // add LBCarrys to (Raw(x-bpp)/2) for each byte + pand mm2, mm6 // Leave only Active Group 2 bytes to add to Avg + paddb mm0, mm2 // add (Raw/2) + LBCarrys to Avg for each Active + // byte + + // Add 3rd active group (Raw(x-bpp)/2) to Average with LBCarry + psllq mm6, ShiftBpp // shift the mm6 mask to cover the last two + // bytes + movq mm2, mm0 // mov updated Raws to mm2 + psllq mm2, ShiftBpp // shift data to position correctly + // Data only needs to be shifted once here to + // get the correct x-bpp offset. + movq mm1, mm3 // now use mm1 for getting LBCarrys + pand mm1, mm2 // get LBCarrys for each byte where both + // lsb's were == 1 (Only valid for active group) + psrlq mm2, 1 // divide raw bytes by 2 + pand mm2, mm4 // clear invalid bit 7 of each byte + paddb mm2, mm1 // add LBCarrys to (Raw(x-bpp)/2) for each byte + pand mm2, mm6 // Leave only Active Group 2 bytes to add to Avg + add ebx, 8 + paddb mm0, mm2 // add (Raw/2) + LBCarrys to Avg for each Active + // byte + + // Now ready to write back to memory + movq [edi + ebx - 8], mm0 + // Move updated Raw(x) to use as Raw(x-bpp) for next loop + cmp ebx, MMXLength + movq mm2, mm0 // mov updated Raw(x) to mm2 + jb davg3lp + } // end _asm block + } + break; + + case 6: + case 4: + case 7: + case 5: + { + ActiveMask.use = 0xffffffffffffffff; // use shift below to clear + // appropriate inactive bytes + ShiftBpp.use = bpp << 3; + ShiftRem.use = 64 - ShiftBpp.use; + _asm { + movq mm4, HBClearMask + // Re-init address pointers and offset + mov ebx, diff // ebx ==> x = offset to alignment boundary + // Load ActiveMask and clear all bytes except for 1st active group + movq mm7, ActiveMask + mov edi, row // edi ==> Avg(x) + psrlq mm7, ShiftRem + mov esi, prev_row // esi ==> Prior(x) + movq mm6, mm7 + movq mm5, LBCarryMask + psllq mm6, ShiftBpp // Create mask for 2nd active group + // PRIME the pump (load the first Raw(x-bpp) data set + movq mm2, [edi + ebx - 8] // Load previous aligned 8 bytes + // (we correct position in loop below) +davg4lp: + movq mm0, [edi + ebx] + psrlq mm2, ShiftRem // shift data to position correctly + movq mm1, [esi + ebx] + // Add (Prev_row/2) to Average + movq mm3, mm5 + pand mm3, mm1 // get lsb for each prev_row byte + psrlq mm1, 1 // divide prev_row bytes by 2 + pand mm1, mm4 // clear invalid bit 7 of each byte + paddb mm0, mm1 // add (Prev_row/2) to Avg for each byte + // Add 1st active group (Raw(x-bpp)/2) to Average with LBCarry + movq mm1, mm3 // now use mm1 for getting LBCarrys + pand mm1, mm2 // get LBCarrys for each byte where both + // lsb's were == 1 (Only valid for active group) + psrlq mm2, 1 // divide raw bytes by 2 + pand mm2, mm4 // clear invalid bit 7 of each byte + paddb mm2, mm1 // add LBCarrys to (Raw(x-bpp)/2) for each byte + pand mm2, mm7 // Leave only Active Group 1 bytes to add to Avg + paddb mm0, mm2 // add (Raw/2) + LBCarrys to Avg for each Active + // byte + // Add 2nd active group (Raw(x-bpp)/2) to Average with LBCarry + movq mm2, mm0 // mov updated Raws to mm2 + psllq mm2, ShiftBpp // shift data to position correctly + add ebx, 8 + movq mm1, mm3 // now use mm1 for getting LBCarrys + pand mm1, mm2 // get LBCarrys for each byte where both + // lsb's were == 1 (Only valid for active group) + psrlq mm2, 1 // divide raw bytes by 2 + pand mm2, mm4 // clear invalid bit 7 of each byte + paddb mm2, mm1 // add LBCarrys to (Raw(x-bpp)/2) for each byte + pand mm2, mm6 // Leave only Active Group 2 bytes to add to Avg + paddb mm0, mm2 // add (Raw/2) + LBCarrys to Avg for each Active + // byte + cmp ebx, MMXLength + // Now ready to write back to memory + movq [edi + ebx - 8], mm0 + // Prep Raw(x-bpp) for next loop + movq mm2, mm0 // mov updated Raws to mm2 + jb davg4lp + } // end _asm block + } + break; + case 2: + { + ActiveMask.use = 0x000000000000ffff; + ShiftBpp.use = 16; // == 2 * 8 [BUGFIX] + ShiftRem.use = 48; // == 64 - 16 [BUGFIX] + _asm { + // Load ActiveMask + movq mm7, ActiveMask + // Re-init address pointers and offset + mov ebx, diff // ebx ==> x = offset to alignment boundary + movq mm5, LBCarryMask + mov edi, row // edi ==> Avg(x) + movq mm4, HBClearMask + mov esi, prev_row // esi ==> Prior(x) + // PRIME the pump (load the first Raw(x-bpp) data set + movq mm2, [edi + ebx - 8] // Load previous aligned 8 bytes + // (we correct position in loop below) +davg2lp: + movq mm0, [edi + ebx] + psrlq mm2, ShiftRem // shift data to position correctly [BUGFIX] + movq mm1, [esi + ebx] + // Add (Prev_row/2) to Average + movq mm3, mm5 + pand mm3, mm1 // get lsb for each prev_row byte + psrlq mm1, 1 // divide prev_row bytes by 2 + pand mm1, mm4 // clear invalid bit 7 of each byte + movq mm6, mm7 + paddb mm0, mm1 // add (Prev_row/2) to Avg for each byte + // Add 1st active group (Raw(x-bpp)/2) to Average with LBCarry + movq mm1, mm3 // now use mm1 for getting LBCarrys + pand mm1, mm2 // get LBCarrys for each byte where both + // lsb's were == 1 (Only valid for active group) + psrlq mm2, 1 // divide raw bytes by 2 + pand mm2, mm4 // clear invalid bit 7 of each byte + paddb mm2, mm1 // add LBCarrys to (Raw(x-bpp)/2) for each byte + pand mm2, mm6 // Leave only Active Group 1 bytes to add to Avg + paddb mm0, mm2 // add (Raw/2) + LBCarrys to Avg for each Active byte + // Add 2nd active group (Raw(x-bpp)/2) to Average with LBCarry + psllq mm6, ShiftBpp // shift the mm6 mask to cover bytes 2 & 3 + movq mm2, mm0 // mov updated Raws to mm2 + psllq mm2, ShiftBpp // shift data to position correctly + movq mm1, mm3 // now use mm1 for getting LBCarrys + pand mm1, mm2 // get LBCarrys for each byte where both + // lsb's were == 1 (Only valid for active group) + psrlq mm2, 1 // divide raw bytes by 2 + pand mm2, mm4 // clear invalid bit 7 of each byte + paddb mm2, mm1 // add LBCarrys to (Raw(x-bpp)/2) for each byte + pand mm2, mm6 // Leave only Active Group 2 bytes to add to Avg + paddb mm0, mm2 // add (Raw/2) + LBCarrys to Avg for each Active byte + + // Add rdd active group (Raw(x-bpp)/2) to Average with LBCarry + psllq mm6, ShiftBpp // shift the mm6 mask to cover bytes 4 & 5 + movq mm2, mm0 // mov updated Raws to mm2 + psllq mm2, ShiftBpp // shift data to position correctly + // Data only needs to be shifted once here to + // get the correct x-bpp offset. + movq mm1, mm3 // now use mm1 for getting LBCarrys + pand mm1, mm2 // get LBCarrys for each byte where both + // lsb's were == 1 (Only valid for active group) + psrlq mm2, 1 // divide raw bytes by 2 + pand mm2, mm4 // clear invalid bit 7 of each byte + paddb mm2, mm1 // add LBCarrys to (Raw(x-bpp)/2) for each byte + pand mm2, mm6 // Leave only Active Group 2 bytes to add to Avg + paddb mm0, mm2 // add (Raw/2) + LBCarrys to Avg for each Active byte + + // Add 4th active group (Raw(x-bpp)/2) to Average with LBCarry + psllq mm6, ShiftBpp // shift the mm6 mask to cover bytes 6 & 7 + movq mm2, mm0 // mov updated Raws to mm2 + psllq mm2, ShiftBpp // shift data to position correctly + // Data only needs to be shifted once here to + // get the correct x-bpp offset. + add ebx, 8 + movq mm1, mm3 // now use mm1 for getting LBCarrys + pand mm1, mm2 // get LBCarrys for each byte where both + // lsb's were == 1 (Only valid for active group) + psrlq mm2, 1 // divide raw bytes by 2 + pand mm2, mm4 // clear invalid bit 7 of each byte + paddb mm2, mm1 // add LBCarrys to (Raw(x-bpp)/2) for each byte + pand mm2, mm6 // Leave only Active Group 2 bytes to add to Avg + paddb mm0, mm2 // add (Raw/2) + LBCarrys to Avg for each Active byte + + cmp ebx, MMXLength + // Now ready to write back to memory + movq [edi + ebx - 8], mm0 + // Prep Raw(x-bpp) for next loop + movq mm2, mm0 // mov updated Raws to mm2 + jb davg2lp + } // end _asm block + } + break; + + case 1: // bpp == 1 + { + _asm { + // Re-init address pointers and offset + mov ebx, diff // ebx ==> x = offset to alignment boundary + mov edi, row // edi ==> Avg(x) + cmp ebx, FullLength // Test if offset at end of array + jnb davg1end + // Do Paeth decode for remaining bytes + mov esi, prev_row // esi ==> Prior(x) + mov edx, edi + xor ecx, ecx // zero ecx before using cl & cx in loop below + sub edx, bpp // edx ==> Raw(x-bpp) +davg1lp: + // Raw(x) = Avg(x) + ((Raw(x-bpp) + Prior(x))/2) + xor eax, eax + mov cl, [esi + ebx] // load cl with Prior(x) + mov al, [edx + ebx] // load al with Raw(x-bpp) + add ax, cx + inc ebx + shr ax, 1 // divide by 2 + add al, [edi+ebx-1] // Add Avg(x); -1 to offset inc ebx + cmp ebx, FullLength // Check if at end of array + mov [edi+ebx-1], al // Write back Raw(x); + // mov does not affect flags; -1 to offset inc ebx + jb davg1lp +davg1end: + } // end _asm block + } + return; + + case 8: // bpp == 8 + { + _asm { + // Re-init address pointers and offset + mov ebx, diff // ebx ==> x = offset to alignment boundary + movq mm5, LBCarryMask + mov edi, row // edi ==> Avg(x) + movq mm4, HBClearMask + mov esi, prev_row // esi ==> Prior(x) + // PRIME the pump (load the first Raw(x-bpp) data set + movq mm2, [edi + ebx - 8] // Load previous aligned 8 bytes + // (NO NEED to correct position in loop below) +davg8lp: + movq mm0, [edi + ebx] + movq mm3, mm5 + movq mm1, [esi + ebx] + add ebx, 8 + pand mm3, mm1 // get lsb for each prev_row byte + psrlq mm1, 1 // divide prev_row bytes by 2 + pand mm3, mm2 // get LBCarrys for each byte where both + // lsb's were == 1 + psrlq mm2, 1 // divide raw bytes by 2 + pand mm1, mm4 // clear invalid bit 7 of each byte + paddb mm0, mm3 // add LBCarrys to Avg for each byte + pand mm2, mm4 // clear invalid bit 7 of each byte + paddb mm0, mm1 // add (Prev_row/2) to Avg for each byte + paddb mm0, mm2 // add (Raw/2) to Avg for each byte + cmp ebx, MMXLength + movq [edi + ebx - 8], mm0 + movq mm2, mm0 // reuse as Raw(x-bpp) + jb davg8lp + } // end _asm block + } + break; + default: // bpp greater than 8 + { + _asm { + movq mm5, LBCarryMask + // Re-init address pointers and offset + mov ebx, diff // ebx ==> x = offset to alignment boundary + mov edi, row // edi ==> Avg(x) + movq mm4, HBClearMask + mov edx, edi + mov esi, prev_row // esi ==> Prior(x) + sub edx, bpp // edx ==> Raw(x-bpp) +davgAlp: + movq mm0, [edi + ebx] + movq mm3, mm5 + movq mm1, [esi + ebx] + pand mm3, mm1 // get lsb for each prev_row byte + movq mm2, [edx + ebx] + psrlq mm1, 1 // divide prev_row bytes by 2 + pand mm3, mm2 // get LBCarrys for each byte where both + // lsb's were == 1 + psrlq mm2, 1 // divide raw bytes by 2 + pand mm1, mm4 // clear invalid bit 7 of each byte + paddb mm0, mm3 // add LBCarrys to Avg for each byte + pand mm2, mm4 // clear invalid bit 7 of each byte + paddb mm0, mm1 // add (Prev_row/2) to Avg for each byte + add ebx, 8 + paddb mm0, mm2 // add (Raw/2) to Avg for each byte + cmp ebx, MMXLength + movq [edi + ebx - 8], mm0 + jb davgAlp + } // end _asm block + } + break; + } // end switch ( bpp ) + + _asm { + // MMX acceleration complete now do clean-up + // Check if any remaining bytes left to decode + mov ebx, MMXLength // ebx ==> x = offset bytes remaining after MMX + mov edi, row // edi ==> Avg(x) + cmp ebx, FullLength // Test if offset at end of array + jnb davgend + // Do Paeth decode for remaining bytes + mov esi, prev_row // esi ==> Prior(x) + mov edx, edi + xor ecx, ecx // zero ecx before using cl & cx in loop below + sub edx, bpp // edx ==> Raw(x-bpp) +davglp2: + // Raw(x) = Avg(x) + ((Raw(x-bpp) + Prior(x))/2) + xor eax, eax + mov cl, [esi + ebx] // load cl with Prior(x) + mov al, [edx + ebx] // load al with Raw(x-bpp) + add ax, cx + inc ebx + shr ax, 1 // divide by 2 + add al, [edi+ebx-1] // Add Avg(x); -1 to offset inc ebx + cmp ebx, FullLength // Check if at end of array + mov [edi+ebx-1], al // Write back Raw(x); + // mov does not affect flags; -1 to offset inc ebx + jb davglp2 +davgend: + emms // End MMX instructions; prep for possible FP instrs. + } // end _asm block +} + +// Optimized code for PNG Paeth filter decoder +void /* PRIVATE */ +png_read_filter_row_mmx_paeth(png_row_infop row_info, png_bytep row, + png_bytep prev_row) +{ + png_uint_32 FullLength; + png_uint_32 MMXLength; + //png_uint_32 len; + int bpp; + int diff; + //int ptemp; + int patemp, pbtemp, pctemp; + + bpp = (row_info->pixel_depth + 7) >> 3; // Get # bytes per pixel + FullLength = row_info->rowbytes; // # of bytes to filter + _asm + { + xor ebx, ebx // ebx ==> x offset + mov edi, row + xor edx, edx // edx ==> x-bpp offset + mov esi, prev_row + xor eax, eax + + // Compute the Raw value for the first bpp bytes + // Note: the formula works out to be always + // Paeth(x) = Raw(x) + Prior(x) where x < bpp +dpthrlp: + mov al, [edi + ebx] + add al, [esi + ebx] + inc ebx + cmp ebx, bpp + mov [edi + ebx - 1], al + jb dpthrlp + // get # of bytes to alignment + mov diff, edi // take start of row + add diff, ebx // add bpp + xor ecx, ecx + add diff, 0xf // add 7 + 8 to incr past alignment boundary + and diff, 0xfffffff8 // mask to alignment boundary + sub diff, edi // subtract from start ==> value ebx at alignment + jz dpthgo + // fix alignment +dpthlp1: + xor eax, eax + // pav = p - a = (a + b - c) - a = b - c + mov al, [esi + ebx] // load Prior(x) into al + mov cl, [esi + edx] // load Prior(x-bpp) into cl + sub eax, ecx // subtract Prior(x-bpp) + mov patemp, eax // Save pav for later use + xor eax, eax + // pbv = p - b = (a + b - c) - b = a - c + mov al, [edi + edx] // load Raw(x-bpp) into al + sub eax, ecx // subtract Prior(x-bpp) + mov ecx, eax + // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv + add eax, patemp // pcv = pav + pbv + // pc = abs(pcv) + test eax, 0x80000000 + jz dpthpca + neg eax // reverse sign of neg values +dpthpca: + mov pctemp, eax // save pc for later use + // pb = abs(pbv) + test ecx, 0x80000000 + jz dpthpba + neg ecx // reverse sign of neg values +dpthpba: + mov pbtemp, ecx // save pb for later use + // pa = abs(pav) + mov eax, patemp + test eax, 0x80000000 + jz dpthpaa + neg eax // reverse sign of neg values +dpthpaa: + mov patemp, eax // save pa for later use + // test if pa <= pb + cmp eax, ecx + jna dpthabb + // pa > pb; now test if pb <= pc + cmp ecx, pctemp + jna dpthbbc + // pb > pc; Raw(x) = Paeth(x) + Prior(x-bpp) + mov cl, [esi + edx] // load Prior(x-bpp) into cl + jmp dpthpaeth +dpthbbc: + // pb <= pc; Raw(x) = Paeth(x) + Prior(x) + mov cl, [esi + ebx] // load Prior(x) into cl + jmp dpthpaeth +dpthabb: + // pa <= pb; now test if pa <= pc + cmp eax, pctemp + jna dpthabc + // pa > pc; Raw(x) = Paeth(x) + Prior(x-bpp) + mov cl, [esi + edx] // load Prior(x-bpp) into cl + jmp dpthpaeth +dpthabc: + // pa <= pc; Raw(x) = Paeth(x) + Raw(x-bpp) + mov cl, [edi + edx] // load Raw(x-bpp) into cl +dpthpaeth: + inc ebx + inc edx + // Raw(x) = (Paeth(x) + Paeth_Predictor( a, b, c )) mod 256 + add [edi + ebx - 1], cl + cmp ebx, diff + jb dpthlp1 +dpthgo: + mov ecx, FullLength + mov eax, ecx + sub eax, ebx // subtract alignment fix + and eax, 0x00000007 // calc bytes over mult of 8 + sub ecx, eax // drop over bytes from original length + mov MMXLength, ecx + } // end _asm block + // Now do the math for the rest of the row + switch ( bpp ) + { + case 3: + { + ActiveMask.use = 0x0000000000ffffff; + ActiveMaskEnd.use = 0xffff000000000000; + ShiftBpp.use = 24; // == bpp(3) * 8 + ShiftRem.use = 40; // == 64 - 24 + _asm + { + mov ebx, diff + mov edi, row + mov esi, prev_row + pxor mm0, mm0 + // PRIME the pump (load the first Raw(x-bpp) data set + movq mm1, [edi+ebx-8] +dpth3lp: + psrlq mm1, ShiftRem // shift last 3 bytes to 1st 3 bytes + movq mm2, [esi + ebx] // load b=Prior(x) + punpcklbw mm1, mm0 // Unpack High bytes of a + movq mm3, [esi+ebx-8] // Prep c=Prior(x-bpp) bytes + punpcklbw mm2, mm0 // Unpack High bytes of b + psrlq mm3, ShiftRem // shift last 3 bytes to 1st 3 bytes + // pav = p - a = (a + b - c) - a = b - c + movq mm4, mm2 + punpcklbw mm3, mm0 // Unpack High bytes of c + // pbv = p - b = (a + b - c) - b = a - c + movq mm5, mm1 + psubw mm4, mm3 + pxor mm7, mm7 + // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv + movq mm6, mm4 + psubw mm5, mm3 + + // pa = abs(p-a) = abs(pav) + // pb = abs(p-b) = abs(pbv) + // pc = abs(p-c) = abs(pcv) + pcmpgtw mm0, mm4 // Create mask pav bytes < 0 + paddw mm6, mm5 + pand mm0, mm4 // Only pav bytes < 0 in mm7 + pcmpgtw mm7, mm5 // Create mask pbv bytes < 0 + psubw mm4, mm0 + pand mm7, mm5 // Only pbv bytes < 0 in mm0 + psubw mm4, mm0 + psubw mm5, mm7 + pxor mm0, mm0 + pcmpgtw mm0, mm6 // Create mask pcv bytes < 0 + pand mm0, mm6 // Only pav bytes < 0 in mm7 + psubw mm5, mm7 + psubw mm6, mm0 + // test pa <= pb + movq mm7, mm4 + psubw mm6, mm0 + pcmpgtw mm7, mm5 // pa > pb? + movq mm0, mm7 + // use mm7 mask to merge pa & pb + pand mm5, mm7 + // use mm0 mask copy to merge a & b + pand mm2, mm0 + pandn mm7, mm4 + pandn mm0, mm1 + paddw mm7, mm5 + paddw mm0, mm2 + // test ((pa <= pb)? pa:pb) <= pc + pcmpgtw mm7, mm6 // pab > pc? + pxor mm1, mm1 + pand mm3, mm7 + pandn mm7, mm0 + paddw mm7, mm3 + pxor mm0, mm0 + packuswb mm7, mm1 + movq mm3, [esi + ebx] // load c=Prior(x-bpp) + pand mm7, ActiveMask + movq mm2, mm3 // load b=Prior(x) step 1 + paddb mm7, [edi + ebx] // add Paeth predictor with Raw(x) + punpcklbw mm3, mm0 // Unpack High bytes of c + movq [edi + ebx], mm7 // write back updated value + movq mm1, mm7 // Now mm1 will be used as Raw(x-bpp) + // Now do Paeth for 2nd set of bytes (3-5) + psrlq mm2, ShiftBpp // load b=Prior(x) step 2 + punpcklbw mm1, mm0 // Unpack High bytes of a + pxor mm7, mm7 + punpcklbw mm2, mm0 // Unpack High bytes of b + // pbv = p - b = (a + b - c) - b = a - c + movq mm5, mm1 + // pav = p - a = (a + b - c) - a = b - c + movq mm4, mm2 + psubw mm5, mm3 + psubw mm4, mm3 + // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = + // pav + pbv = pbv + pav + movq mm6, mm5 + paddw mm6, mm4 + + // pa = abs(p-a) = abs(pav) + // pb = abs(p-b) = abs(pbv) + // pc = abs(p-c) = abs(pcv) + pcmpgtw mm0, mm5 // Create mask pbv bytes < 0 + pcmpgtw mm7, mm4 // Create mask pav bytes < 0 + pand mm0, mm5 // Only pbv bytes < 0 in mm0 + pand mm7, mm4 // Only pav bytes < 0 in mm7 + psubw mm5, mm0 + psubw mm4, mm7 + psubw mm5, mm0 + psubw mm4, mm7 + pxor mm0, mm0 + pcmpgtw mm0, mm6 // Create mask pcv bytes < 0 + pand mm0, mm6 // Only pav bytes < 0 in mm7 + psubw mm6, mm0 + // test pa <= pb + movq mm7, mm4 + psubw mm6, mm0 + pcmpgtw mm7, mm5 // pa > pb? + movq mm0, mm7 + // use mm7 mask to merge pa & pb + pand mm5, mm7 + // use mm0 mask copy to merge a & b + pand mm2, mm0 + pandn mm7, mm4 + pandn mm0, mm1 + paddw mm7, mm5 + paddw mm0, mm2 + // test ((pa <= pb)? pa:pb) <= pc + pcmpgtw mm7, mm6 // pab > pc? + movq mm2, [esi + ebx] // load b=Prior(x) + pand mm3, mm7 + pandn mm7, mm0 + pxor mm1, mm1 + paddw mm7, mm3 + pxor mm0, mm0 + packuswb mm7, mm1 + movq mm3, mm2 // load c=Prior(x-bpp) step 1 + pand mm7, ActiveMask + punpckhbw mm2, mm0 // Unpack High bytes of b + psllq mm7, ShiftBpp // Shift bytes to 2nd group of 3 bytes + // pav = p - a = (a + b - c) - a = b - c + movq mm4, mm2 + paddb mm7, [edi + ebx] // add Paeth predictor with Raw(x) + psllq mm3, ShiftBpp // load c=Prior(x-bpp) step 2 + movq [edi + ebx], mm7 // write back updated value + movq mm1, mm7 + punpckhbw mm3, mm0 // Unpack High bytes of c + psllq mm1, ShiftBpp // Shift bytes + // Now mm1 will be used as Raw(x-bpp) + // Now do Paeth for 3rd, and final, set of bytes (6-7) + pxor mm7, mm7 + punpckhbw mm1, mm0 // Unpack High bytes of a + psubw mm4, mm3 + // pbv = p - b = (a + b - c) - b = a - c + movq mm5, mm1 + // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv + movq mm6, mm4 + psubw mm5, mm3 + pxor mm0, mm0 + paddw mm6, mm5 + + // pa = abs(p-a) = abs(pav) + // pb = abs(p-b) = abs(pbv) + // pc = abs(p-c) = abs(pcv) + pcmpgtw mm0, mm4 // Create mask pav bytes < 0 + pcmpgtw mm7, mm5 // Create mask pbv bytes < 0 + pand mm0, mm4 // Only pav bytes < 0 in mm7 + pand mm7, mm5 // Only pbv bytes < 0 in mm0 + psubw mm4, mm0 + psubw mm5, mm7 + psubw mm4, mm0 + psubw mm5, mm7 + pxor mm0, mm0 + pcmpgtw mm0, mm6 // Create mask pcv bytes < 0 + pand mm0, mm6 // Only pav bytes < 0 in mm7 + psubw mm6, mm0 + // test pa <= pb + movq mm7, mm4 + psubw mm6, mm0 + pcmpgtw mm7, mm5 // pa > pb? + movq mm0, mm7 + // use mm0 mask copy to merge a & b + pand mm2, mm0 + // use mm7 mask to merge pa & pb + pand mm5, mm7 + pandn mm0, mm1 + pandn mm7, mm4 + paddw mm0, mm2 + paddw mm7, mm5 + // test ((pa <= pb)? pa:pb) <= pc + pcmpgtw mm7, mm6 // pab > pc? + pand mm3, mm7 + pandn mm7, mm0 + paddw mm7, mm3 + pxor mm1, mm1 + packuswb mm1, mm7 + // Step ebx to next set of 8 bytes and repeat loop til done + add ebx, 8 + pand mm1, ActiveMaskEnd + paddb mm1, [edi + ebx - 8] // add Paeth predictor with Raw(x) + + cmp ebx, MMXLength + pxor mm0, mm0 // pxor does not affect flags + movq [edi + ebx - 8], mm1 // write back updated value + // mm1 will be used as Raw(x-bpp) next loop + // mm3 ready to be used as Prior(x-bpp) next loop + jb dpth3lp + } // end _asm block + } + break; + + case 6: + case 7: + case 5: + { + ActiveMask.use = 0x00000000ffffffff; + ActiveMask2.use = 0xffffffff00000000; + ShiftBpp.use = bpp << 3; // == bpp * 8 + ShiftRem.use = 64 - ShiftBpp.use; + _asm + { + mov ebx, diff + mov edi, row + mov esi, prev_row + // PRIME the pump (load the first Raw(x-bpp) data set + movq mm1, [edi+ebx-8] + pxor mm0, mm0 +dpth6lp: + // Must shift to position Raw(x-bpp) data + psrlq mm1, ShiftRem + // Do first set of 4 bytes + movq mm3, [esi+ebx-8] // read c=Prior(x-bpp) bytes + punpcklbw mm1, mm0 // Unpack Low bytes of a + movq mm2, [esi + ebx] // load b=Prior(x) + punpcklbw mm2, mm0 // Unpack Low bytes of b + // Must shift to position Prior(x-bpp) data + psrlq mm3, ShiftRem + // pav = p - a = (a + b - c) - a = b - c + movq mm4, mm2 + punpcklbw mm3, mm0 // Unpack Low bytes of c + // pbv = p - b = (a + b - c) - b = a - c + movq mm5, mm1 + psubw mm4, mm3 + pxor mm7, mm7 + // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv + movq mm6, mm4 + psubw mm5, mm3 + // pa = abs(p-a) = abs(pav) + // pb = abs(p-b) = abs(pbv) + // pc = abs(p-c) = abs(pcv) + pcmpgtw mm0, mm4 // Create mask pav bytes < 0 + paddw mm6, mm5 + pand mm0, mm4 // Only pav bytes < 0 in mm7 + pcmpgtw mm7, mm5 // Create mask pbv bytes < 0 + psubw mm4, mm0 + pand mm7, mm5 // Only pbv bytes < 0 in mm0 + psubw mm4, mm0 + psubw mm5, mm7 + pxor mm0, mm0 + pcmpgtw mm0, mm6 // Create mask pcv bytes < 0 + pand mm0, mm6 // Only pav bytes < 0 in mm7 + psubw mm5, mm7 + psubw mm6, mm0 + // test pa <= pb + movq mm7, mm4 + psubw mm6, mm0 + pcmpgtw mm7, mm5 // pa > pb? + movq mm0, mm7 + // use mm7 mask to merge pa & pb + pand mm5, mm7 + // use mm0 mask copy to merge a & b + pand mm2, mm0 + pandn mm7, mm4 + pandn mm0, mm1 + paddw mm7, mm5 + paddw mm0, mm2 + // test ((pa <= pb)? pa:pb) <= pc + pcmpgtw mm7, mm6 // pab > pc? + pxor mm1, mm1 + pand mm3, mm7 + pandn mm7, mm0 + paddw mm7, mm3 + pxor mm0, mm0 + packuswb mm7, mm1 + movq mm3, [esi + ebx - 8] // load c=Prior(x-bpp) + pand mm7, ActiveMask + psrlq mm3, ShiftRem + movq mm2, [esi + ebx] // load b=Prior(x) step 1 + paddb mm7, [edi + ebx] // add Paeth predictor with Raw(x) + movq mm6, mm2 + movq [edi + ebx], mm7 // write back updated value + movq mm1, [edi+ebx-8] + psllq mm6, ShiftBpp + movq mm5, mm7 + psrlq mm1, ShiftRem + por mm3, mm6 + psllq mm5, ShiftBpp + punpckhbw mm3, mm0 // Unpack High bytes of c + por mm1, mm5 + // Do second set of 4 bytes + punpckhbw mm2, mm0 // Unpack High bytes of b + punpckhbw mm1, mm0 // Unpack High bytes of a + // pav = p - a = (a + b - c) - a = b - c + movq mm4, mm2 + // pbv = p - b = (a + b - c) - b = a - c + movq mm5, mm1 + psubw mm4, mm3 + pxor mm7, mm7 + // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv + movq mm6, mm4 + psubw mm5, mm3 + // pa = abs(p-a) = abs(pav) + // pb = abs(p-b) = abs(pbv) + // pc = abs(p-c) = abs(pcv) + pcmpgtw mm0, mm4 // Create mask pav bytes < 0 + paddw mm6, mm5 + pand mm0, mm4 // Only pav bytes < 0 in mm7 + pcmpgtw mm7, mm5 // Create mask pbv bytes < 0 + psubw mm4, mm0 + pand mm7, mm5 // Only pbv bytes < 0 in mm0 + psubw mm4, mm0 + psubw mm5, mm7 + pxor mm0, mm0 + pcmpgtw mm0, mm6 // Create mask pcv bytes < 0 + pand mm0, mm6 // Only pav bytes < 0 in mm7 + psubw mm5, mm7 + psubw mm6, mm0 + // test pa <= pb + movq mm7, mm4 + psubw mm6, mm0 + pcmpgtw mm7, mm5 // pa > pb? + movq mm0, mm7 + // use mm7 mask to merge pa & pb + pand mm5, mm7 + // use mm0 mask copy to merge a & b + pand mm2, mm0 + pandn mm7, mm4 + pandn mm0, mm1 + paddw mm7, mm5 + paddw mm0, mm2 + // test ((pa <= pb)? pa:pb) <= pc + pcmpgtw mm7, mm6 // pab > pc? + pxor mm1, mm1 + pand mm3, mm7 + pandn mm7, mm0 + pxor mm1, mm1 + paddw mm7, mm3 + pxor mm0, mm0 + // Step ex to next set of 8 bytes and repeat loop til done + add ebx, 8 + packuswb mm1, mm7 + paddb mm1, [edi + ebx - 8] // add Paeth predictor with Raw(x) + cmp ebx, MMXLength + movq [edi + ebx - 8], mm1 // write back updated value + // mm1 will be used as Raw(x-bpp) next loop + jb dpth6lp + } // end _asm block + } + break; + + case 4: + { + ActiveMask.use = 0x00000000ffffffff; + _asm { + mov ebx, diff + mov edi, row + mov esi, prev_row + pxor mm0, mm0 + // PRIME the pump (load the first Raw(x-bpp) data set + movq mm1, [edi+ebx-8] // Only time should need to read + // a=Raw(x-bpp) bytes +dpth4lp: + // Do first set of 4 bytes + movq mm3, [esi+ebx-8] // read c=Prior(x-bpp) bytes + punpckhbw mm1, mm0 // Unpack Low bytes of a + movq mm2, [esi + ebx] // load b=Prior(x) + punpcklbw mm2, mm0 // Unpack High bytes of b + // pav = p - a = (a + b - c) - a = b - c + movq mm4, mm2 + punpckhbw mm3, mm0 // Unpack High bytes of c + // pbv = p - b = (a + b - c) - b = a - c + movq mm5, mm1 + psubw mm4, mm3 + pxor mm7, mm7 + // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv + movq mm6, mm4 + psubw mm5, mm3 + // pa = abs(p-a) = abs(pav) + // pb = abs(p-b) = abs(pbv) + // pc = abs(p-c) = abs(pcv) + pcmpgtw mm0, mm4 // Create mask pav bytes < 0 + paddw mm6, mm5 + pand mm0, mm4 // Only pav bytes < 0 in mm7 + pcmpgtw mm7, mm5 // Create mask pbv bytes < 0 + psubw mm4, mm0 + pand mm7, mm5 // Only pbv bytes < 0 in mm0 + psubw mm4, mm0 + psubw mm5, mm7 + pxor mm0, mm0 + pcmpgtw mm0, mm6 // Create mask pcv bytes < 0 + pand mm0, mm6 // Only pav bytes < 0 in mm7 + psubw mm5, mm7 + psubw mm6, mm0 + // test pa <= pb + movq mm7, mm4 + psubw mm6, mm0 + pcmpgtw mm7, mm5 // pa > pb? + movq mm0, mm7 + // use mm7 mask to merge pa & pb + pand mm5, mm7 + // use mm0 mask copy to merge a & b + pand mm2, mm0 + pandn mm7, mm4 + pandn mm0, mm1 + paddw mm7, mm5 + paddw mm0, mm2 + // test ((pa <= pb)? pa:pb) <= pc + pcmpgtw mm7, mm6 // pab > pc? + pxor mm1, mm1 + pand mm3, mm7 + pandn mm7, mm0 + paddw mm7, mm3 + pxor mm0, mm0 + packuswb mm7, mm1 + movq mm3, [esi + ebx] // load c=Prior(x-bpp) + pand mm7, ActiveMask + movq mm2, mm3 // load b=Prior(x) step 1 + paddb mm7, [edi + ebx] // add Paeth predictor with Raw(x) + punpcklbw mm3, mm0 // Unpack High bytes of c + movq [edi + ebx], mm7 // write back updated value + movq mm1, mm7 // Now mm1 will be used as Raw(x-bpp) + // Do second set of 4 bytes + punpckhbw mm2, mm0 // Unpack Low bytes of b + punpcklbw mm1, mm0 // Unpack Low bytes of a + // pav = p - a = (a + b - c) - a = b - c + movq mm4, mm2 + // pbv = p - b = (a + b - c) - b = a - c + movq mm5, mm1 + psubw mm4, mm3 + pxor mm7, mm7 + // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv + movq mm6, mm4 + psubw mm5, mm3 + // pa = abs(p-a) = abs(pav) + // pb = abs(p-b) = abs(pbv) + // pc = abs(p-c) = abs(pcv) + pcmpgtw mm0, mm4 // Create mask pav bytes < 0 + paddw mm6, mm5 + pand mm0, mm4 // Only pav bytes < 0 in mm7 + pcmpgtw mm7, mm5 // Create mask pbv bytes < 0 + psubw mm4, mm0 + pand mm7, mm5 // Only pbv bytes < 0 in mm0 + psubw mm4, mm0 + psubw mm5, mm7 + pxor mm0, mm0 + pcmpgtw mm0, mm6 // Create mask pcv bytes < 0 + pand mm0, mm6 // Only pav bytes < 0 in mm7 + psubw mm5, mm7 + psubw mm6, mm0 + // test pa <= pb + movq mm7, mm4 + psubw mm6, mm0 + pcmpgtw mm7, mm5 // pa > pb? + movq mm0, mm7 + // use mm7 mask to merge pa & pb + pand mm5, mm7 + // use mm0 mask copy to merge a & b + pand mm2, mm0 + pandn mm7, mm4 + pandn mm0, mm1 + paddw mm7, mm5 + paddw mm0, mm2 + // test ((pa <= pb)? pa:pb) <= pc + pcmpgtw mm7, mm6 // pab > pc? + pxor mm1, mm1 + pand mm3, mm7 + pandn mm7, mm0 + pxor mm1, mm1 + paddw mm7, mm3 + pxor mm0, mm0 + // Step ex to next set of 8 bytes and repeat loop til done + add ebx, 8 + packuswb mm1, mm7 + paddb mm1, [edi + ebx - 8] // add Paeth predictor with Raw(x) + cmp ebx, MMXLength + movq [edi + ebx - 8], mm1 // write back updated value + // mm1 will be used as Raw(x-bpp) next loop + jb dpth4lp + } // end _asm block + } + break; + case 8: // bpp == 8 + { + ActiveMask.use = 0x00000000ffffffff; + _asm { + mov ebx, diff + mov edi, row + mov esi, prev_row + pxor mm0, mm0 + // PRIME the pump (load the first Raw(x-bpp) data set + movq mm1, [edi+ebx-8] // Only time should need to read + // a=Raw(x-bpp) bytes +dpth8lp: + // Do first set of 4 bytes + movq mm3, [esi+ebx-8] // read c=Prior(x-bpp) bytes + punpcklbw mm1, mm0 // Unpack Low bytes of a + movq mm2, [esi + ebx] // load b=Prior(x) + punpcklbw mm2, mm0 // Unpack Low bytes of b + // pav = p - a = (a + b - c) - a = b - c + movq mm4, mm2 + punpcklbw mm3, mm0 // Unpack Low bytes of c + // pbv = p - b = (a + b - c) - b = a - c + movq mm5, mm1 + psubw mm4, mm3 + pxor mm7, mm7 + // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv + movq mm6, mm4 + psubw mm5, mm3 + // pa = abs(p-a) = abs(pav) + // pb = abs(p-b) = abs(pbv) + // pc = abs(p-c) = abs(pcv) + pcmpgtw mm0, mm4 // Create mask pav bytes < 0 + paddw mm6, mm5 + pand mm0, mm4 // Only pav bytes < 0 in mm7 + pcmpgtw mm7, mm5 // Create mask pbv bytes < 0 + psubw mm4, mm0 + pand mm7, mm5 // Only pbv bytes < 0 in mm0 + psubw mm4, mm0 + psubw mm5, mm7 + pxor mm0, mm0 + pcmpgtw mm0, mm6 // Create mask pcv bytes < 0 + pand mm0, mm6 // Only pav bytes < 0 in mm7 + psubw mm5, mm7 + psubw mm6, mm0 + // test pa <= pb + movq mm7, mm4 + psubw mm6, mm0 + pcmpgtw mm7, mm5 // pa > pb? + movq mm0, mm7 + // use mm7 mask to merge pa & pb + pand mm5, mm7 + // use mm0 mask copy to merge a & b + pand mm2, mm0 + pandn mm7, mm4 + pandn mm0, mm1 + paddw mm7, mm5 + paddw mm0, mm2 + // test ((pa <= pb)? pa:pb) <= pc + pcmpgtw mm7, mm6 // pab > pc? + pxor mm1, mm1 + pand mm3, mm7 + pandn mm7, mm0 + paddw mm7, mm3 + pxor mm0, mm0 + packuswb mm7, mm1 + movq mm3, [esi+ebx-8] // read c=Prior(x-bpp) bytes + pand mm7, ActiveMask + movq mm2, [esi + ebx] // load b=Prior(x) + paddb mm7, [edi + ebx] // add Paeth predictor with Raw(x) + punpckhbw mm3, mm0 // Unpack High bytes of c + movq [edi + ebx], mm7 // write back updated value + movq mm1, [edi+ebx-8] // read a=Raw(x-bpp) bytes + + // Do second set of 4 bytes + punpckhbw mm2, mm0 // Unpack High bytes of b + punpckhbw mm1, mm0 // Unpack High bytes of a + // pav = p - a = (a + b - c) - a = b - c + movq mm4, mm2 + // pbv = p - b = (a + b - c) - b = a - c + movq mm5, mm1 + psubw mm4, mm3 + pxor mm7, mm7 + // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv + movq mm6, mm4 + psubw mm5, mm3 + // pa = abs(p-a) = abs(pav) + // pb = abs(p-b) = abs(pbv) + // pc = abs(p-c) = abs(pcv) + pcmpgtw mm0, mm4 // Create mask pav bytes < 0 + paddw mm6, mm5 + pand mm0, mm4 // Only pav bytes < 0 in mm7 + pcmpgtw mm7, mm5 // Create mask pbv bytes < 0 + psubw mm4, mm0 + pand mm7, mm5 // Only pbv bytes < 0 in mm0 + psubw mm4, mm0 + psubw mm5, mm7 + pxor mm0, mm0 + pcmpgtw mm0, mm6 // Create mask pcv bytes < 0 + pand mm0, mm6 // Only pav bytes < 0 in mm7 + psubw mm5, mm7 + psubw mm6, mm0 + // test pa <= pb + movq mm7, mm4 + psubw mm6, mm0 + pcmpgtw mm7, mm5 // pa > pb? + movq mm0, mm7 + // use mm7 mask to merge pa & pb + pand mm5, mm7 + // use mm0 mask copy to merge a & b + pand mm2, mm0 + pandn mm7, mm4 + pandn mm0, mm1 + paddw mm7, mm5 + paddw mm0, mm2 + // test ((pa <= pb)? pa:pb) <= pc + pcmpgtw mm7, mm6 // pab > pc? + pxor mm1, mm1 + pand mm3, mm7 + pandn mm7, mm0 + pxor mm1, mm1 + paddw mm7, mm3 + pxor mm0, mm0 + // Step ex to next set of 8 bytes and repeat loop til done + add ebx, 8 + packuswb mm1, mm7 + paddb mm1, [edi + ebx - 8] // add Paeth predictor with Raw(x) + cmp ebx, MMXLength + movq [edi + ebx - 8], mm1 // write back updated value + // mm1 will be used as Raw(x-bpp) next loop + jb dpth8lp + } // end _asm block + } + break; + + case 1: // bpp = 1 + case 2: // bpp = 2 + default: // bpp > 8 + { + _asm { + mov ebx, diff + cmp ebx, FullLength + jnb dpthdend + mov edi, row + mov esi, prev_row + // Do Paeth decode for remaining bytes + mov edx, ebx + xor ecx, ecx // zero ecx before using cl & cx in loop below + sub edx, bpp // Set edx = ebx - bpp +dpthdlp: + xor eax, eax + // pav = p - a = (a + b - c) - a = b - c + mov al, [esi + ebx] // load Prior(x) into al + mov cl, [esi + edx] // load Prior(x-bpp) into cl + sub eax, ecx // subtract Prior(x-bpp) + mov patemp, eax // Save pav for later use + xor eax, eax + // pbv = p - b = (a + b - c) - b = a - c + mov al, [edi + edx] // load Raw(x-bpp) into al + sub eax, ecx // subtract Prior(x-bpp) + mov ecx, eax + // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv + add eax, patemp // pcv = pav + pbv + // pc = abs(pcv) + test eax, 0x80000000 + jz dpthdpca + neg eax // reverse sign of neg values +dpthdpca: + mov pctemp, eax // save pc for later use + // pb = abs(pbv) + test ecx, 0x80000000 + jz dpthdpba + neg ecx // reverse sign of neg values +dpthdpba: + mov pbtemp, ecx // save pb for later use + // pa = abs(pav) + mov eax, patemp + test eax, 0x80000000 + jz dpthdpaa + neg eax // reverse sign of neg values +dpthdpaa: + mov patemp, eax // save pa for later use + // test if pa <= pb + cmp eax, ecx + jna dpthdabb + // pa > pb; now test if pb <= pc + cmp ecx, pctemp + jna dpthdbbc + // pb > pc; Raw(x) = Paeth(x) + Prior(x-bpp) + mov cl, [esi + edx] // load Prior(x-bpp) into cl + jmp dpthdpaeth +dpthdbbc: + // pb <= pc; Raw(x) = Paeth(x) + Prior(x) + mov cl, [esi + ebx] // load Prior(x) into cl + jmp dpthdpaeth +dpthdabb: + // pa <= pb; now test if pa <= pc + cmp eax, pctemp + jna dpthdabc + // pa > pc; Raw(x) = Paeth(x) + Prior(x-bpp) + mov cl, [esi + edx] // load Prior(x-bpp) into cl + jmp dpthdpaeth +dpthdabc: + // pa <= pc; Raw(x) = Paeth(x) + Raw(x-bpp) + mov cl, [edi + edx] // load Raw(x-bpp) into cl +dpthdpaeth: + inc ebx + inc edx + // Raw(x) = (Paeth(x) + Paeth_Predictor( a, b, c )) mod 256 + add [edi + ebx - 1], cl + cmp ebx, FullLength + jb dpthdlp +dpthdend: + } // end _asm block + } + return; // No need to go further with this one + } // end switch ( bpp ) + _asm + { + // MMX acceleration complete now do clean-up + // Check if any remaining bytes left to decode + mov ebx, MMXLength + cmp ebx, FullLength + jnb dpthend + mov edi, row + mov esi, prev_row + // Do Paeth decode for remaining bytes + mov edx, ebx + xor ecx, ecx // zero ecx before using cl & cx in loop below + sub edx, bpp // Set edx = ebx - bpp +dpthlp2: + xor eax, eax + // pav = p - a = (a + b - c) - a = b - c + mov al, [esi + ebx] // load Prior(x) into al + mov cl, [esi + edx] // load Prior(x-bpp) into cl + sub eax, ecx // subtract Prior(x-bpp) + mov patemp, eax // Save pav for later use + xor eax, eax + // pbv = p - b = (a + b - c) - b = a - c + mov al, [edi + edx] // load Raw(x-bpp) into al + sub eax, ecx // subtract Prior(x-bpp) + mov ecx, eax + // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv + add eax, patemp // pcv = pav + pbv + // pc = abs(pcv) + test eax, 0x80000000 + jz dpthpca2 + neg eax // reverse sign of neg values +dpthpca2: + mov pctemp, eax // save pc for later use + // pb = abs(pbv) + test ecx, 0x80000000 + jz dpthpba2 + neg ecx // reverse sign of neg values +dpthpba2: + mov pbtemp, ecx // save pb for later use + // pa = abs(pav) + mov eax, patemp + test eax, 0x80000000 + jz dpthpaa2 + neg eax // reverse sign of neg values +dpthpaa2: + mov patemp, eax // save pa for later use + // test if pa <= pb + cmp eax, ecx + jna dpthabb2 + // pa > pb; now test if pb <= pc + cmp ecx, pctemp + jna dpthbbc2 + // pb > pc; Raw(x) = Paeth(x) + Prior(x-bpp) + mov cl, [esi + edx] // load Prior(x-bpp) into cl + jmp dpthpaeth2 +dpthbbc2: + // pb <= pc; Raw(x) = Paeth(x) + Prior(x) + mov cl, [esi + ebx] // load Prior(x) into cl + jmp dpthpaeth2 +dpthabb2: + // pa <= pb; now test if pa <= pc + cmp eax, pctemp + jna dpthabc2 + // pa > pc; Raw(x) = Paeth(x) + Prior(x-bpp) + mov cl, [esi + edx] // load Prior(x-bpp) into cl + jmp dpthpaeth2 +dpthabc2: + // pa <= pc; Raw(x) = Paeth(x) + Raw(x-bpp) + mov cl, [edi + edx] // load Raw(x-bpp) into cl +dpthpaeth2: + inc ebx + inc edx + // Raw(x) = (Paeth(x) + Paeth_Predictor( a, b, c )) mod 256 + add [edi + ebx - 1], cl + cmp ebx, FullLength + jb dpthlp2 +dpthend: + emms // End MMX instructions; prep for possible FP instrs. + } // end _asm block +} + +// Optimized code for PNG Sub filter decoder +void /* PRIVATE */ +png_read_filter_row_mmx_sub(png_row_infop row_info, png_bytep row) +{ + //int test; + int bpp; + png_uint_32 FullLength; + png_uint_32 MMXLength; + int diff; + + bpp = (row_info->pixel_depth + 7) >> 3; // Get # bytes per pixel + FullLength = row_info->rowbytes - bpp; // # of bytes to filter + _asm { + mov edi, row + mov esi, edi // lp = row + add edi, bpp // rp = row + bpp + xor eax, eax + // get # of bytes to alignment + mov diff, edi // take start of row + add diff, 0xf // add 7 + 8 to incr past + // alignment boundary + xor ebx, ebx + and diff, 0xfffffff8 // mask to alignment boundary + sub diff, edi // subtract from start ==> value + // ebx at alignment + jz dsubgo + // fix alignment +dsublp1: + mov al, [esi+ebx] + add [edi+ebx], al + inc ebx + cmp ebx, diff + jb dsublp1 +dsubgo: + mov ecx, FullLength + mov edx, ecx + sub edx, ebx // subtract alignment fix + and edx, 0x00000007 // calc bytes over mult of 8 + sub ecx, edx // drop over bytes from length + mov MMXLength, ecx + } // end _asm block + + // Now do the math for the rest of the row + switch ( bpp ) + { + case 3: + { + ActiveMask.use = 0x0000ffffff000000; + ShiftBpp.use = 24; // == 3 * 8 + ShiftRem.use = 40; // == 64 - 24 + _asm { + mov edi, row + movq mm7, ActiveMask // Load ActiveMask for 2nd active byte group + mov esi, edi // lp = row + add edi, bpp // rp = row + bpp + movq mm6, mm7 + mov ebx, diff + psllq mm6, ShiftBpp // Move mask in mm6 to cover 3rd active + // byte group + // PRIME the pump (load the first Raw(x-bpp) data set + movq mm1, [edi+ebx-8] +dsub3lp: + psrlq mm1, ShiftRem // Shift data for adding 1st bpp bytes + // no need for mask; shift clears inactive bytes + // Add 1st active group + movq mm0, [edi+ebx] + paddb mm0, mm1 + // Add 2nd active group + movq mm1, mm0 // mov updated Raws to mm1 + psllq mm1, ShiftBpp // shift data to position correctly + pand mm1, mm7 // mask to use only 2nd active group + paddb mm0, mm1 + // Add 3rd active group + movq mm1, mm0 // mov updated Raws to mm1 + psllq mm1, ShiftBpp // shift data to position correctly + pand mm1, mm6 // mask to use only 3rd active group + add ebx, 8 + paddb mm0, mm1 + cmp ebx, MMXLength + movq [edi+ebx-8], mm0 // Write updated Raws back to array + // Prep for doing 1st add at top of loop + movq mm1, mm0 + jb dsub3lp + } // end _asm block + } + break; + + case 1: + { + // Placed here just in case this is a duplicate of the + // non-MMX code for the SUB filter in png_read_filter_row below + // + // png_bytep rp; + // png_bytep lp; + // png_uint_32 i; + // bpp = (row_info->pixel_depth + 7) >> 3; + // for (i = (png_uint_32)bpp, rp = row + bpp, lp = row; + // i < row_info->rowbytes; i++, rp++, lp++) + // { + // *rp = (png_byte)(((int)(*rp) + (int)(*lp)) & 0xff); + // } + _asm { + mov ebx, diff + mov edi, row + cmp ebx, FullLength + jnb dsub1end + mov esi, edi // lp = row + xor eax, eax + add edi, bpp // rp = row + bpp +dsub1lp: + mov al, [esi+ebx] + add [edi+ebx], al + inc ebx + cmp ebx, FullLength + jb dsub1lp +dsub1end: + } // end _asm block + } + return; + + case 6: + case 7: + case 4: + case 5: + { + ShiftBpp.use = bpp << 3; + ShiftRem.use = 64 - ShiftBpp.use; + _asm { + mov edi, row + mov ebx, diff + mov esi, edi // lp = row + add edi, bpp // rp = row + bpp + // PRIME the pump (load the first Raw(x-bpp) data set + movq mm1, [edi+ebx-8] +dsub4lp: + psrlq mm1, ShiftRem // Shift data for adding 1st bpp bytes + // no need for mask; shift clears inactive bytes + movq mm0, [edi+ebx] + paddb mm0, mm1 + // Add 2nd active group + movq mm1, mm0 // mov updated Raws to mm1 + psllq mm1, ShiftBpp // shift data to position correctly + // there is no need for any mask + // since shift clears inactive bits/bytes + add ebx, 8 + paddb mm0, mm1 + cmp ebx, MMXLength + movq [edi+ebx-8], mm0 + movq mm1, mm0 // Prep for doing 1st add at top of loop + jb dsub4lp + } // end _asm block + } + break; + + case 2: + { + ActiveMask.use = 0x00000000ffff0000; + ShiftBpp.use = 16; // == 2 * 8 + ShiftRem.use = 48; // == 64 - 16 + _asm { + movq mm7, ActiveMask // Load ActiveMask for 2nd active byte group + mov ebx, diff + movq mm6, mm7 + mov edi, row + psllq mm6, ShiftBpp // Move mask in mm6 to cover 3rd active + // byte group + mov esi, edi // lp = row + movq mm5, mm6 + add edi, bpp // rp = row + bpp + psllq mm5, ShiftBpp // Move mask in mm5 to cover 4th active + // byte group + // PRIME the pump (load the first Raw(x-bpp) data set + movq mm1, [edi+ebx-8] +dsub2lp: + // Add 1st active group + psrlq mm1, ShiftRem // Shift data for adding 1st bpp bytes + // no need for mask; shift clears inactive + // bytes + movq mm0, [edi+ebx] + paddb mm0, mm1 + // Add 2nd active group + movq mm1, mm0 // mov updated Raws to mm1 + psllq mm1, ShiftBpp // shift data to position correctly + pand mm1, mm7 // mask to use only 2nd active group + paddb mm0, mm1 + // Add 3rd active group + movq mm1, mm0 // mov updated Raws to mm1 + psllq mm1, ShiftBpp // shift data to position correctly + pand mm1, mm6 // mask to use only 3rd active group + paddb mm0, mm1 + // Add 4th active group + movq mm1, mm0 // mov updated Raws to mm1 + psllq mm1, ShiftBpp // shift data to position correctly + pand mm1, mm5 // mask to use only 4th active group + add ebx, 8 + paddb mm0, mm1 + cmp ebx, MMXLength + movq [edi+ebx-8], mm0 // Write updated Raws back to array + movq mm1, mm0 // Prep for doing 1st add at top of loop + jb dsub2lp + } // end _asm block + } + break; + case 8: + { + _asm { + mov edi, row + mov ebx, diff + mov esi, edi // lp = row + add edi, bpp // rp = row + bpp + mov ecx, MMXLength + movq mm7, [edi+ebx-8] // PRIME the pump (load the first + // Raw(x-bpp) data set + and ecx, 0x0000003f // calc bytes over mult of 64 +dsub8lp: + movq mm0, [edi+ebx] // Load Sub(x) for 1st 8 bytes + paddb mm0, mm7 + movq mm1, [edi+ebx+8] // Load Sub(x) for 2nd 8 bytes + movq [edi+ebx], mm0 // Write Raw(x) for 1st 8 bytes + // Now mm0 will be used as Raw(x-bpp) for + // the 2nd group of 8 bytes. This will be + // repeated for each group of 8 bytes with + // the 8th group being used as the Raw(x-bpp) + // for the 1st group of the next loop. + paddb mm1, mm0 + movq mm2, [edi+ebx+16] // Load Sub(x) for 3rd 8 bytes + movq [edi+ebx+8], mm1 // Write Raw(x) for 2nd 8 bytes + paddb mm2, mm1 + movq mm3, [edi+ebx+24] // Load Sub(x) for 4th 8 bytes + movq [edi+ebx+16], mm2 // Write Raw(x) for 3rd 8 bytes + paddb mm3, mm2 + movq mm4, [edi+ebx+32] // Load Sub(x) for 5th 8 bytes + movq [edi+ebx+24], mm3 // Write Raw(x) for 4th 8 bytes + paddb mm4, mm3 + movq mm5, [edi+ebx+40] // Load Sub(x) for 6th 8 bytes + movq [edi+ebx+32], mm4 // Write Raw(x) for 5th 8 bytes + paddb mm5, mm4 + movq mm6, [edi+ebx+48] // Load Sub(x) for 7th 8 bytes + movq [edi+ebx+40], mm5 // Write Raw(x) for 6th 8 bytes + paddb mm6, mm5 + movq mm7, [edi+ebx+56] // Load Sub(x) for 8th 8 bytes + movq [edi+ebx+48], mm6 // Write Raw(x) for 7th 8 bytes + add ebx, 64 + paddb mm7, mm6 + cmp ebx, ecx + movq [edi+ebx-8], mm7 // Write Raw(x) for 8th 8 bytes + jb dsub8lp + cmp ebx, MMXLength + jnb dsub8lt8 +dsub8lpA: + movq mm0, [edi+ebx] + add ebx, 8 + paddb mm0, mm7 + cmp ebx, MMXLength + movq [edi+ebx-8], mm0 // use -8 to offset early add to ebx + movq mm7, mm0 // Move calculated Raw(x) data to mm1 to + // be the new Raw(x-bpp) for the next loop + jb dsub8lpA +dsub8lt8: + } // end _asm block + } + break; + + default: // bpp greater than 8 bytes + { + _asm { + mov ebx, diff + mov edi, row + mov esi, edi // lp = row + add edi, bpp // rp = row + bpp +dsubAlp: + movq mm0, [edi+ebx] + movq mm1, [esi+ebx] + add ebx, 8 + paddb mm0, mm1 + cmp ebx, MMXLength + movq [edi+ebx-8], mm0 // mov does not affect flags; -8 to offset + // add ebx + jb dsubAlp + } // end _asm block + } + break; + + } // end switch ( bpp ) + + _asm { + mov ebx, MMXLength + mov edi, row + cmp ebx, FullLength + jnb dsubend + mov esi, edi // lp = row + xor eax, eax + add edi, bpp // rp = row + bpp +dsublp2: + mov al, [esi+ebx] + add [edi+ebx], al + inc ebx + cmp ebx, FullLength + jb dsublp2 +dsubend: + emms // End MMX instructions; prep for possible FP instrs. + } // end _asm block +} + +// Optimized code for PNG Up filter decoder +void /* PRIVATE */ +png_read_filter_row_mmx_up(png_row_infop row_info, png_bytep row, + png_bytep prev_row) +{ + png_uint_32 len; + len = row_info->rowbytes; // # of bytes to filter + _asm { + mov edi, row + // get # of bytes to alignment + mov ecx, edi + xor ebx, ebx + add ecx, 0x7 + xor eax, eax + and ecx, 0xfffffff8 + mov esi, prev_row + sub ecx, edi + jz dupgo + // fix alignment +duplp1: + mov al, [edi+ebx] + add al, [esi+ebx] + inc ebx + cmp ebx, ecx + mov [edi + ebx-1], al // mov does not affect flags; -1 to offset inc ebx + jb duplp1 +dupgo: + mov ecx, len + mov edx, ecx + sub edx, ebx // subtract alignment fix + and edx, 0x0000003f // calc bytes over mult of 64 + sub ecx, edx // drop over bytes from length + // Unrolled loop - use all MMX registers and interleave to reduce + // number of branch instructions (loops) and reduce partial stalls +duploop: + movq mm1, [esi+ebx] + movq mm0, [edi+ebx] + movq mm3, [esi+ebx+8] + paddb mm0, mm1 + movq mm2, [edi+ebx+8] + movq [edi+ebx], mm0 + paddb mm2, mm3 + movq mm5, [esi+ebx+16] + movq [edi+ebx+8], mm2 + movq mm4, [edi+ebx+16] + movq mm7, [esi+ebx+24] + paddb mm4, mm5 + movq mm6, [edi+ebx+24] + movq [edi+ebx+16], mm4 + paddb mm6, mm7 + movq mm1, [esi+ebx+32] + movq [edi+ebx+24], mm6 + movq mm0, [edi+ebx+32] + movq mm3, [esi+ebx+40] + paddb mm0, mm1 + movq mm2, [edi+ebx+40] + movq [edi+ebx+32], mm0 + paddb mm2, mm3 + movq mm5, [esi+ebx+48] + movq [edi+ebx+40], mm2 + movq mm4, [edi+ebx+48] + movq mm7, [esi+ebx+56] + paddb mm4, mm5 + movq mm6, [edi+ebx+56] + movq [edi+ebx+48], mm4 + add ebx, 64 + paddb mm6, mm7 + cmp ebx, ecx + movq [edi+ebx-8], mm6 // (+56)movq does not affect flags; + // -8 to offset add ebx + jb duploop + + cmp edx, 0 // Test for bytes over mult of 64 + jz dupend + + + // 2 lines added by lcreeve at netins.net + // (mail 11 Jul 98 in png-implement list) + cmp edx, 8 //test for less than 8 bytes + jb duplt8 + + + add ecx, edx + and edx, 0x00000007 // calc bytes over mult of 8 + sub ecx, edx // drop over bytes from length + jz duplt8 + // Loop using MMX registers mm0 & mm1 to update 8 bytes simultaneously +duplpA: + movq mm1, [esi+ebx] + movq mm0, [edi+ebx] + add ebx, 8 + paddb mm0, mm1 + cmp ebx, ecx + movq [edi+ebx-8], mm0 // movq does not affect flags; -8 to offset add ebx + jb duplpA + cmp edx, 0 // Test for bytes over mult of 8 + jz dupend +duplt8: + xor eax, eax + add ecx, edx // move over byte count into counter + // Loop using x86 registers to update remaining bytes +duplp2: + mov al, [edi + ebx] + add al, [esi + ebx] + inc ebx + cmp ebx, ecx + mov [edi + ebx-1], al // mov does not affect flags; -1 to offset inc ebx + jb duplp2 +dupend: + // Conversion of filtered row completed + emms // End MMX instructions; prep for possible FP instrs. + } // end _asm block +} + + +// Optimized png_read_filter_row routines +void /* PRIVATE */ +png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep + row, png_bytep prev_row, int filter) +{ +#ifdef PNG_DEBUG + char filnm[10]; +#endif + + if (mmx_supported == 2) { +#if !defined(PNG_1_0_X) + /* this should have happened in png_init_mmx_flags() already */ + png_warning(png_ptr, "asm_flags may not have been initialized"); +#endif + png_mmx_support(); + } + +#ifdef PNG_DEBUG + png_debug(1, "in png_read_filter_row\n"); + switch (filter) + { + case 0: sprintf(filnm, "none"); + break; +#if !defined(PNG_1_0_X) + case 1: sprintf(filnm, "sub-%s", + (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_SUB)? "MMX" : "x86"); + break; + case 2: sprintf(filnm, "up-%s", + (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_UP)? "MMX" : "x86"); + break; + case 3: sprintf(filnm, "avg-%s", + (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_AVG)? "MMX" : "x86"); + break; + case 4: sprintf(filnm, "Paeth-%s", + (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_PAETH)? "MMX":"x86"); + break; +#else + case 1: sprintf(filnm, "sub"); + break; + case 2: sprintf(filnm, "up"); + break; + case 3: sprintf(filnm, "avg"); + break; + case 4: sprintf(filnm, "Paeth"); + break; +#endif + default: sprintf(filnm, "unknw"); + break; + } + png_debug2(0,"row=%5d, %s, ", png_ptr->row_number, filnm); + png_debug2(0, "pd=%2d, b=%d, ", (int)row_info->pixel_depth, + (int)((row_info->pixel_depth + 7) >> 3)); + png_debug1(0,"len=%8d, ", row_info->rowbytes); +#endif /* PNG_DEBUG */ + + switch (filter) + { + case PNG_FILTER_VALUE_NONE: + break; + + case PNG_FILTER_VALUE_SUB: + { +#if !defined(PNG_1_0_X) + if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_SUB) && + (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) && + (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold)) +#else + if (mmx_supported) +#endif + { + png_read_filter_row_mmx_sub(row_info, row); + } + else + { + png_uint_32 i; + png_uint_32 istop = row_info->rowbytes; + png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3; + png_bytep rp = row + bpp; + png_bytep lp = row; + + for (i = bpp; i < istop; i++) + { + *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff); + rp++; + } + } + break; + } + + case PNG_FILTER_VALUE_UP: + { +#if !defined(PNG_1_0_X) + if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_UP) && + (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) && + (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold)) +#else + if (mmx_supported) +#endif + { + png_read_filter_row_mmx_up(row_info, row, prev_row); + } + else + { + png_uint_32 i; + png_uint_32 istop = row_info->rowbytes; + png_bytep rp = row; + png_bytep pp = prev_row; + + for (i = 0; i < istop; ++i) + { + *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff); + rp++; + } + } + break; + } + + case PNG_FILTER_VALUE_AVG: + { +#if !defined(PNG_1_0_X) + if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_AVG) && + (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) && + (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold)) +#else + if (mmx_supported) +#endif + { + png_read_filter_row_mmx_avg(row_info, row, prev_row); + } + else + { + png_uint_32 i; + png_bytep rp = row; + png_bytep pp = prev_row; + png_bytep lp = row; + png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3; + png_uint_32 istop = row_info->rowbytes - bpp; + + for (i = 0; i < bpp; i++) + { + *rp = (png_byte)(((int)(*rp) + + ((int)(*pp++) >> 1)) & 0xff); + rp++; + } + + for (i = 0; i < istop; i++) + { + *rp = (png_byte)(((int)(*rp) + + ((int)(*pp++ + *lp++) >> 1)) & 0xff); + rp++; + } + } + break; + } + + case PNG_FILTER_VALUE_PAETH: + { +#if !defined(PNG_1_0_X) + if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_PAETH) && + (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) && + (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold)) +#else + if (mmx_supported) +#endif + { + png_read_filter_row_mmx_paeth(row_info, row, prev_row); + } + else + { + png_uint_32 i; + png_bytep rp = row; + png_bytep pp = prev_row; + png_bytep lp = row; + png_bytep cp = prev_row; + png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3; + png_uint_32 istop=row_info->rowbytes - bpp; + + for (i = 0; i < bpp; i++) + { + *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff); + rp++; + } + + for (i = 0; i < istop; i++) // use leftover rp,pp + { + int a, b, c, pa, pb, pc, p; + + a = *lp++; + b = *pp++; + c = *cp++; + + p = b - c; + pc = a - c; + +#ifdef PNG_USE_ABS + pa = abs(p); + pb = abs(pc); + pc = abs(p + pc); +#else + pa = p < 0 ? -p : p; + pb = pc < 0 ? -pc : pc; + pc = (p + pc) < 0 ? -(p + pc) : p + pc; +#endif + + /* + if (pa <= pb && pa <= pc) + p = a; + else if (pb <= pc) + p = b; + else + p = c; + */ + + p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c; + + *rp = (png_byte)(((int)(*rp) + p) & 0xff); + rp++; + } + } + break; + } + + default: + png_warning(png_ptr, "Ignoring bad row filter type"); + *row=0; + break; + } +} + +#endif /* PNG_ASSEMBLER_CODE_SUPPORTED && PNG_USE_PNGVCRD */ diff --git a/mod/pub.mod/libpng.mod/pngwio.c b/mod/pub.mod/libpng.mod/pngwio.c new file mode 100644 index 0000000..a9c1dc5 --- /dev/null +++ b/mod/pub.mod/libpng.mod/pngwio.c @@ -0,0 +1,228 @@ + +/* pngwio.c - functions for data output + * + * Last changed in libpng 1.2.3 - May 21, 2002 + * For conditions of distribution and use, see copyright notice in png.h + * Copyright (c) 1998-2002 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * + * This file provides a location for all output. Users who need + * special handling are expected to write functions that have the same + * arguments as these and perform similar functions, but that possibly + * use different output methods. Note that you shouldn't change these + * functions, but rather write replacement functions and then change + * them at run time with png_set_write_fn(...). + */ + +#define PNG_INTERNAL +#include "png.h" +#ifdef PNG_WRITE_SUPPORTED + +/* Write the data to whatever output you are using. The default routine + writes to a file pointer. Note that this routine sometimes gets called + with very small lengths, so you should implement some kind of simple + buffering if you are using unbuffered writes. This should never be asked + to write more than 64K on a 16 bit machine. */ + +void /* PRIVATE */ +png_write_data(png_structp png_ptr, png_bytep data, png_size_t length) +{ + if (png_ptr->write_data_fn != NULL ) + (*(png_ptr->write_data_fn))(png_ptr, data, length); + else + png_error(png_ptr, "Call to NULL write function"); +} + +#if !defined(PNG_NO_STDIO) +/* This is the function that does the actual writing of data. If you are + not writing to a standard C stream, you should create a replacement + write_data function and use it at run time with png_set_write_fn(), rather + than changing the library. */ +#ifndef USE_FAR_KEYWORD +void PNGAPI +png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length) +{ + png_uint_32 check; + +#if defined(_WIN32_WCE) + if ( !WriteFile((HANDLE)(png_ptr->io_ptr), data, length, &check, NULL) ) + check = 0; +#else + check = fwrite(data, 1, length, (png_FILE_p)(png_ptr->io_ptr)); +#endif + if (check != length) + png_error(png_ptr, "Write Error"); +} +#else +/* this is the model-independent version. Since the standard I/O library + can't handle far buffers in the medium and small models, we have to copy + the data. +*/ + +#define NEAR_BUF_SIZE 1024 +#define MIN(a,b) (a <= b ? a : b) + +void PNGAPI +png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length) +{ + png_uint_32 check; + png_byte *near_data; /* Needs to be "png_byte *" instead of "png_bytep" */ + png_FILE_p io_ptr; + + /* Check if data really is near. If so, use usual code. */ + near_data = (png_byte *)CVT_PTR_NOCHECK(data); + io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr); + if ((png_bytep)near_data == data) + { +#if defined(_WIN32_WCE) + if ( !WriteFile(io_ptr, near_data, length, &check, NULL) ) + check = 0; +#else + check = fwrite(near_data, 1, length, io_ptr); +#endif + } + else + { + png_byte buf[NEAR_BUF_SIZE]; + png_size_t written, remaining, err; + check = 0; + remaining = length; + do + { + written = MIN(NEAR_BUF_SIZE, remaining); + png_memcpy(buf, data, written); /* copy far buffer to near buffer */ +#if defined(_WIN32_WCE) + if ( !WriteFile(io_ptr, buf, written, &err, NULL) ) + err = 0; +#else + err = fwrite(buf, 1, written, io_ptr); +#endif + if (err != written) + break; + else + check += err; + data += written; + remaining -= written; + } + while (remaining != 0); + } + if (check != length) + png_error(png_ptr, "Write Error"); +} + +#endif +#endif + +/* This function is called to output any data pending writing (normally + to disk). After png_flush is called, there should be no data pending + writing in any buffers. */ +#if defined(PNG_WRITE_FLUSH_SUPPORTED) +void /* PRIVATE */ +png_flush(png_structp png_ptr) +{ + if (png_ptr->output_flush_fn != NULL) + (*(png_ptr->output_flush_fn))(png_ptr); +} + +#if !defined(PNG_NO_STDIO) +void PNGAPI +png_default_flush(png_structp png_ptr) +{ +#if !defined(_WIN32_WCE) + png_FILE_p io_ptr; + io_ptr = (png_FILE_p)CVT_PTR((png_ptr->io_ptr)); + if (io_ptr != NULL) + fflush(io_ptr); +#endif +} +#endif +#endif + +/* This function allows the application to supply new output functions for + libpng if standard C streams aren't being used. + + This function takes as its arguments: + png_ptr - pointer to a png output data structure + io_ptr - pointer to user supplied structure containing info about + the output functions. May be NULL. + write_data_fn - pointer to a new output function that takes as its + arguments a pointer to a png_struct, a pointer to + data to be written, and a 32-bit unsigned int that is + the number of bytes to be written. The new write + function should call png_error(png_ptr, "Error msg") + to exit and output any fatal error messages. + flush_data_fn - pointer to a new flush function that takes as its + arguments a pointer to a png_struct. After a call to + the flush function, there should be no data in any buffers + or pending transmission. If the output method doesn't do + any buffering of ouput, a function prototype must still be + supplied although it doesn't have to do anything. If + PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile + time, output_flush_fn will be ignored, although it must be + supplied for compatibility. */ +void PNGAPI +png_set_write_fn(png_structp png_ptr, png_voidp io_ptr, + png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn) +{ + png_ptr->io_ptr = io_ptr; + +#if !defined(PNG_NO_STDIO) + if (write_data_fn != NULL) + png_ptr->write_data_fn = write_data_fn; + else + png_ptr->write_data_fn = png_default_write_data; +#else + png_ptr->write_data_fn = write_data_fn; +#endif + +#if defined(PNG_WRITE_FLUSH_SUPPORTED) +#if !defined(PNG_NO_STDIO) + if (output_flush_fn != NULL) + png_ptr->output_flush_fn = output_flush_fn; + else + png_ptr->output_flush_fn = png_default_flush; +#else + png_ptr->output_flush_fn = output_flush_fn; +#endif +#endif /* PNG_WRITE_FLUSH_SUPPORTED */ + + /* It is an error to read while writing a png file */ + if (png_ptr->read_data_fn != NULL) + { + png_ptr->read_data_fn = NULL; + png_warning(png_ptr, + "Attempted to set both read_data_fn and write_data_fn in"); + png_warning(png_ptr, + "the same structure. Resetting read_data_fn to NULL."); + } +} + +#if defined(USE_FAR_KEYWORD) +#if defined(_MSC_VER) +void *png_far_to_near(png_structp png_ptr,png_voidp ptr, int check) +{ + void *near_ptr; + void FAR *far_ptr; + FP_OFF(near_ptr) = FP_OFF(ptr); + far_ptr = (void FAR *)near_ptr; + if(check != 0) + if(FP_SEG(ptr) != FP_SEG(far_ptr)) + png_error(png_ptr,"segment lost in conversion"); + return(near_ptr); +} +# else +void *png_far_to_near(png_structp png_ptr,png_voidp ptr, int check) +{ + void *near_ptr; + void FAR *far_ptr; + near_ptr = (void FAR *)ptr; + far_ptr = (void FAR *)near_ptr; + if(check != 0) + if(far_ptr != ptr) + png_error(png_ptr,"segment lost in conversion"); + return(near_ptr); +} +# endif +# endif +#endif /* PNG_WRITE_SUPPORTED */ diff --git a/mod/pub.mod/libpng.mod/pngwrite.c b/mod/pub.mod/libpng.mod/pngwrite.c new file mode 100644 index 0000000..95984f6 --- /dev/null +++ b/mod/pub.mod/libpng.mod/pngwrite.c @@ -0,0 +1,1513 @@ + +/* pngwrite.c - general routines to write a PNG file + * + * Last changed in libpng 1.2.9 April 14, 2006 + * For conditions of distribution and use, see copyright notice in png.h + * Copyright (c) 1998-2006 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + */ + +/* get internal access to png.h */ +#define PNG_INTERNAL +#include "png.h" +#ifdef PNG_WRITE_SUPPORTED + +/* Writes all the PNG information. This is the suggested way to use the + * library. If you have a new chunk to add, make a function to write it, + * and put it in the correct location here. If you want the chunk written + * after the image data, put it in png_write_end(). I strongly encourage + * you to supply a PNG_INFO_ flag, and check info_ptr->valid before writing + * the chunk, as that will keep the code from breaking if you want to just + * write a plain PNG file. If you have long comments, I suggest writing + * them in png_write_end(), and compressing them. + */ +void PNGAPI +png_write_info_before_PLTE(png_structp png_ptr, png_infop info_ptr) +{ + png_debug(1, "in png_write_info_before_PLTE\n"); + if (png_ptr == NULL || info_ptr == NULL) + return; + if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE)) + { + png_write_sig(png_ptr); /* write PNG signature */ +#if defined(PNG_MNG_FEATURES_SUPPORTED) + if((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE)&&(png_ptr->mng_features_permitted)) + { + png_warning(png_ptr,"MNG features are not allowed in a PNG datastream"); + png_ptr->mng_features_permitted=0; + } +#endif + /* write IHDR information. */ + png_write_IHDR(png_ptr, info_ptr->width, info_ptr->height, + info_ptr->bit_depth, info_ptr->color_type, info_ptr->compression_type, + info_ptr->filter_type, +#if defined(PNG_WRITE_INTERLACING_SUPPORTED) + info_ptr->interlace_type); +#else + 0); +#endif + /* the rest of these check to see if the valid field has the appropriate + flag set, and if it does, writes the chunk. */ +#if defined(PNG_WRITE_gAMA_SUPPORTED) + if (info_ptr->valid & PNG_INFO_gAMA) + { +# ifdef PNG_FLOATING_POINT_SUPPORTED + png_write_gAMA(png_ptr, info_ptr->gamma); +#else +#ifdef PNG_FIXED_POINT_SUPPORTED + png_write_gAMA_fixed(png_ptr, info_ptr->int_gamma); +# endif +#endif + } +#endif +#if defined(PNG_WRITE_sRGB_SUPPORTED) + if (info_ptr->valid & PNG_INFO_sRGB) + png_write_sRGB(png_ptr, (int)info_ptr->srgb_intent); +#endif +#if defined(PNG_WRITE_iCCP_SUPPORTED) + if (info_ptr->valid & PNG_INFO_iCCP) + png_write_iCCP(png_ptr, info_ptr->iccp_name, PNG_COMPRESSION_TYPE_BASE, + info_ptr->iccp_profile, (int)info_ptr->iccp_proflen); +#endif +#if defined(PNG_WRITE_sBIT_SUPPORTED) + if (info_ptr->valid & PNG_INFO_sBIT) + png_write_sBIT(png_ptr, &(info_ptr->sig_bit), info_ptr->color_type); +#endif +#if defined(PNG_WRITE_cHRM_SUPPORTED) + if (info_ptr->valid & PNG_INFO_cHRM) + { +#ifdef PNG_FLOATING_POINT_SUPPORTED + png_write_cHRM(png_ptr, + info_ptr->x_white, info_ptr->y_white, + info_ptr->x_red, info_ptr->y_red, + info_ptr->x_green, info_ptr->y_green, + info_ptr->x_blue, info_ptr->y_blue); +#else +# ifdef PNG_FIXED_POINT_SUPPORTED + png_write_cHRM_fixed(png_ptr, + info_ptr->int_x_white, info_ptr->int_y_white, + info_ptr->int_x_red, info_ptr->int_y_red, + info_ptr->int_x_green, info_ptr->int_y_green, + info_ptr->int_x_blue, info_ptr->int_y_blue); +# endif +#endif + } +#endif +#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED) + if (info_ptr->unknown_chunks_num) + { + png_unknown_chunk *up; + + png_debug(5, "writing extra chunks\n"); + + for (up = info_ptr->unknown_chunks; + up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num; + up++) + { + int keep=png_handle_as_unknown(png_ptr, up->name); + if (keep != PNG_HANDLE_CHUNK_NEVER && + up->location && !(up->location & PNG_HAVE_PLTE) && + !(up->location & PNG_HAVE_IDAT) && + ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS || + (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS))) + { + png_write_chunk(png_ptr, up->name, up->data, up->size); + } + } + } +#endif + png_ptr->mode |= PNG_WROTE_INFO_BEFORE_PLTE; + } +} + +void PNGAPI +png_write_info(png_structp png_ptr, png_infop info_ptr) +{ +#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED) + int i; +#endif + + png_debug(1, "in png_write_info\n"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + png_write_info_before_PLTE(png_ptr, info_ptr); + + if (info_ptr->valid & PNG_INFO_PLTE) + png_write_PLTE(png_ptr, info_ptr->palette, + (png_uint_32)info_ptr->num_palette); + else if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + png_error(png_ptr, "Valid palette required for paletted images"); + +#if defined(PNG_WRITE_tRNS_SUPPORTED) + if (info_ptr->valid & PNG_INFO_tRNS) + { +#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) + /* invert the alpha channel (in tRNS) */ + if ((png_ptr->transformations & PNG_INVERT_ALPHA) && + info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { + int j; + for (j=0; j<(int)info_ptr->num_trans; j++) + info_ptr->trans[j] = (png_byte)(255 - info_ptr->trans[j]); + } +#endif + png_write_tRNS(png_ptr, info_ptr->trans, &(info_ptr->trans_values), + info_ptr->num_trans, info_ptr->color_type); + } +#endif +#if defined(PNG_WRITE_bKGD_SUPPORTED) + if (info_ptr->valid & PNG_INFO_bKGD) + png_write_bKGD(png_ptr, &(info_ptr->background), info_ptr->color_type); +#endif +#if defined(PNG_WRITE_hIST_SUPPORTED) + if (info_ptr->valid & PNG_INFO_hIST) + png_write_hIST(png_ptr, info_ptr->hist, info_ptr->num_palette); +#endif +#if defined(PNG_WRITE_oFFs_SUPPORTED) + if (info_ptr->valid & PNG_INFO_oFFs) + png_write_oFFs(png_ptr, info_ptr->x_offset, info_ptr->y_offset, + info_ptr->offset_unit_type); +#endif +#if defined(PNG_WRITE_pCAL_SUPPORTED) + if (info_ptr->valid & PNG_INFO_pCAL) + png_write_pCAL(png_ptr, info_ptr->pcal_purpose, info_ptr->pcal_X0, + info_ptr->pcal_X1, info_ptr->pcal_type, info_ptr->pcal_nparams, + info_ptr->pcal_units, info_ptr->pcal_params); +#endif +#if defined(PNG_WRITE_sCAL_SUPPORTED) + if (info_ptr->valid & PNG_INFO_sCAL) +#if defined(PNG_FLOATING_POINT_SUPPORTED) && !defined(PNG_NO_STDIO) + png_write_sCAL(png_ptr, (int)info_ptr->scal_unit, + info_ptr->scal_pixel_width, info_ptr->scal_pixel_height); +#else +#ifdef PNG_FIXED_POINT_SUPPORTED + png_write_sCAL_s(png_ptr, (int)info_ptr->scal_unit, + info_ptr->scal_s_width, info_ptr->scal_s_height); +#else + png_warning(png_ptr, + "png_write_sCAL not supported; sCAL chunk not written."); +#endif +#endif +#endif +#if defined(PNG_WRITE_pHYs_SUPPORTED) + if (info_ptr->valid & PNG_INFO_pHYs) + png_write_pHYs(png_ptr, info_ptr->x_pixels_per_unit, + info_ptr->y_pixels_per_unit, info_ptr->phys_unit_type); +#endif +#if defined(PNG_WRITE_tIME_SUPPORTED) + if (info_ptr->valid & PNG_INFO_tIME) + { + png_write_tIME(png_ptr, &(info_ptr->mod_time)); + png_ptr->mode |= PNG_WROTE_tIME; + } +#endif +#if defined(PNG_WRITE_sPLT_SUPPORTED) + if (info_ptr->valid & PNG_INFO_sPLT) + for (i = 0; i < (int)info_ptr->splt_palettes_num; i++) + png_write_sPLT(png_ptr, info_ptr->splt_palettes + i); +#endif +#if defined(PNG_WRITE_TEXT_SUPPORTED) + /* Check to see if we need to write text chunks */ + for (i = 0; i < info_ptr->num_text; i++) + { + png_debug2(2, "Writing header text chunk %d, type %d\n", i, + info_ptr->text[i].compression); + /* an internationalized chunk? */ + if (info_ptr->text[i].compression > 0) + { +#if defined(PNG_WRITE_iTXt_SUPPORTED) + /* write international chunk */ + png_write_iTXt(png_ptr, + info_ptr->text[i].compression, + info_ptr->text[i].key, + info_ptr->text[i].lang, + info_ptr->text[i].lang_key, + info_ptr->text[i].text); +#else + png_warning(png_ptr, "Unable to write international text"); +#endif + /* Mark this chunk as written */ + info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; + } + /* If we want a compressed text chunk */ + else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_zTXt) + { +#if defined(PNG_WRITE_zTXt_SUPPORTED) + /* write compressed chunk */ + png_write_zTXt(png_ptr, info_ptr->text[i].key, + info_ptr->text[i].text, 0, + info_ptr->text[i].compression); +#else + png_warning(png_ptr, "Unable to write compressed text"); +#endif + /* Mark this chunk as written */ + info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR; + } + else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE) + { +#if defined(PNG_WRITE_tEXt_SUPPORTED) + /* write uncompressed chunk */ + png_write_tEXt(png_ptr, info_ptr->text[i].key, + info_ptr->text[i].text, + 0); +#else + png_warning(png_ptr, "Unable to write uncompressed text"); +#endif + /* Mark this chunk as written */ + info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; + } + } +#endif +#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED) + if (info_ptr->unknown_chunks_num) + { + png_unknown_chunk *up; + + png_debug(5, "writing extra chunks\n"); + + for (up = info_ptr->unknown_chunks; + up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num; + up++) + { + int keep=png_handle_as_unknown(png_ptr, up->name); + if (keep != PNG_HANDLE_CHUNK_NEVER && + up->location && (up->location & PNG_HAVE_PLTE) && + !(up->location & PNG_HAVE_IDAT) && + ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS || + (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS))) + { + png_write_chunk(png_ptr, up->name, up->data, up->size); + } + } + } +#endif +} + +/* Writes the end of the PNG file. If you don't want to write comments or + * time information, you can pass NULL for info. If you already wrote these + * in png_write_info(), do not write them again here. If you have long + * comments, I suggest writing them here, and compressing them. + */ +void PNGAPI +png_write_end(png_structp png_ptr, png_infop info_ptr) +{ + png_debug(1, "in png_write_end\n"); + if (png_ptr == NULL) + return; + if (!(png_ptr->mode & PNG_HAVE_IDAT)) + png_error(png_ptr, "No IDATs written into file"); + + /* see if user wants us to write information chunks */ + if (info_ptr != NULL) + { +#if defined(PNG_WRITE_TEXT_SUPPORTED) + int i; /* local index variable */ +#endif +#if defined(PNG_WRITE_tIME_SUPPORTED) + /* check to see if user has supplied a time chunk */ + if ((info_ptr->valid & PNG_INFO_tIME) && + !(png_ptr->mode & PNG_WROTE_tIME)) + png_write_tIME(png_ptr, &(info_ptr->mod_time)); +#endif +#if defined(PNG_WRITE_TEXT_SUPPORTED) + /* loop through comment chunks */ + for (i = 0; i < info_ptr->num_text; i++) + { + png_debug2(2, "Writing trailer text chunk %d, type %d\n", i, + info_ptr->text[i].compression); + /* an internationalized chunk? */ + if (info_ptr->text[i].compression > 0) + { +#if defined(PNG_WRITE_iTXt_SUPPORTED) + /* write international chunk */ + png_write_iTXt(png_ptr, + info_ptr->text[i].compression, + info_ptr->text[i].key, + info_ptr->text[i].lang, + info_ptr->text[i].lang_key, + info_ptr->text[i].text); +#else + png_warning(png_ptr, "Unable to write international text"); +#endif + /* Mark this chunk as written */ + info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; + } + else if (info_ptr->text[i].compression >= PNG_TEXT_COMPRESSION_zTXt) + { +#if defined(PNG_WRITE_zTXt_SUPPORTED) + /* write compressed chunk */ + png_write_zTXt(png_ptr, info_ptr->text[i].key, + info_ptr->text[i].text, 0, + info_ptr->text[i].compression); +#else + png_warning(png_ptr, "Unable to write compressed text"); +#endif + /* Mark this chunk as written */ + info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR; + } + else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE) + { +#if defined(PNG_WRITE_tEXt_SUPPORTED) + /* write uncompressed chunk */ + png_write_tEXt(png_ptr, info_ptr->text[i].key, + info_ptr->text[i].text, 0); +#else + png_warning(png_ptr, "Unable to write uncompressed text"); +#endif + + /* Mark this chunk as written */ + info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; + } + } +#endif +#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED) + if (info_ptr->unknown_chunks_num) + { + png_unknown_chunk *up; + + png_debug(5, "writing extra chunks\n"); + + for (up = info_ptr->unknown_chunks; + up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num; + up++) + { + int keep=png_handle_as_unknown(png_ptr, up->name); + if (keep != PNG_HANDLE_CHUNK_NEVER && + up->location && (up->location & PNG_AFTER_IDAT) && + ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS || + (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS))) + { + png_write_chunk(png_ptr, up->name, up->data, up->size); + } + } + } +#endif + } + + png_ptr->mode |= PNG_AFTER_IDAT; + + /* write end of PNG file */ + png_write_IEND(png_ptr); +#if 0 +/* This flush, added in libpng-1.0.8, causes some applications to crash + because they do not set png_ptr->output_flush_fn */ + png_flush(png_ptr); +#endif +} + +#if defined(PNG_WRITE_tIME_SUPPORTED) +#if !defined(_WIN32_WCE) +/* "time.h" functions are not supported on WindowsCE */ +void PNGAPI +png_convert_from_struct_tm(png_timep ptime, struct tm FAR * ttime) +{ + png_debug(1, "in png_convert_from_struct_tm\n"); + ptime->year = (png_uint_16)(1900 + ttime->tm_year); + ptime->month = (png_byte)(ttime->tm_mon + 1); + ptime->day = (png_byte)ttime->tm_mday; + ptime->hour = (png_byte)ttime->tm_hour; + ptime->minute = (png_byte)ttime->tm_min; + ptime->second = (png_byte)ttime->tm_sec; +} + +void PNGAPI +png_convert_from_time_t(png_timep ptime, time_t ttime) +{ + struct tm *tbuf; + + png_debug(1, "in png_convert_from_time_t\n"); + tbuf = gmtime(&ttime); + png_convert_from_struct_tm(ptime, tbuf); +} +#endif +#endif + +/* Initialize png_ptr structure, and allocate any memory needed */ +png_structp PNGAPI +png_create_write_struct(png_const_charp user_png_ver, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warn_fn) +{ +#ifdef PNG_USER_MEM_SUPPORTED + return (png_create_write_struct_2(user_png_ver, error_ptr, error_fn, + warn_fn, png_voidp_NULL, png_malloc_ptr_NULL, png_free_ptr_NULL)); +} + +/* Alternate initialize png_ptr structure, and allocate any memory needed */ +png_structp PNGAPI +png_create_write_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, + png_malloc_ptr malloc_fn, png_free_ptr free_fn) +{ +#endif /* PNG_USER_MEM_SUPPORTED */ + png_structp png_ptr; +#ifdef PNG_SETJMP_SUPPORTED +#ifdef USE_FAR_KEYWORD + jmp_buf jmpbuf; +#endif +#endif + int i; + png_debug(1, "in png_create_write_struct\n"); +#ifdef PNG_USER_MEM_SUPPORTED + png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG, + (png_malloc_ptr)malloc_fn, (png_voidp)mem_ptr); +#else + png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG); +#endif /* PNG_USER_MEM_SUPPORTED */ + if (png_ptr == NULL) + return (NULL); + +#if !defined(PNG_1_0_X) +#ifdef PNG_ASSEMBLER_CODE_SUPPORTED + png_init_mmx_flags(png_ptr); /* 1.2.0 addition */ +#endif +#endif /* PNG_1_0_X */ + + /* added at libpng-1.2.6 */ +#ifdef PNG_SET_USER_LIMITS_SUPPORTED + png_ptr->user_width_max=PNG_USER_WIDTH_MAX; + png_ptr->user_height_max=PNG_USER_HEIGHT_MAX; +#endif + +#ifdef PNG_SETJMP_SUPPORTED +#ifdef USE_FAR_KEYWORD + if (setjmp(jmpbuf)) +#else + if (setjmp(png_ptr->jmpbuf)) +#endif + { + png_free(png_ptr, png_ptr->zbuf); + png_ptr->zbuf=NULL; + png_destroy_struct(png_ptr); + return (NULL); + } +#ifdef USE_FAR_KEYWORD + png_memcpy(png_ptr->jmpbuf,jmpbuf,png_sizeof(jmp_buf)); +#endif +#endif + +#ifdef PNG_USER_MEM_SUPPORTED + png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn); +#endif /* PNG_USER_MEM_SUPPORTED */ + png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn); + + i=0; + do + { + if(user_png_ver[i] != png_libpng_ver[i]) + png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH; + } while (png_libpng_ver[i++]); + + if (png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH) + { + /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so + * we must recompile any applications that use any older library version. + * For versions after libpng 1.0, we will be compatible, so we need + * only check the first digit. + */ + if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] || + (user_png_ver[0] == '1' && user_png_ver[2] != png_libpng_ver[2]) || + (user_png_ver[0] == '0' && user_png_ver[2] < '9')) + { +#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE) + char msg[80]; + if (user_png_ver) + { + sprintf(msg, "Application was compiled with png.h from libpng-%.20s", + user_png_ver); + png_warning(png_ptr, msg); + } + sprintf(msg, "Application is running with png.c from libpng-%.20s", + png_libpng_ver); + png_warning(png_ptr, msg); +#endif +#ifdef PNG_ERROR_NUMBERS_SUPPORTED + png_ptr->flags=0; +#endif + png_error(png_ptr, + "Incompatible libpng version in application and library"); + } + } + + /* initialize zbuf - compression buffer */ + png_ptr->zbuf_size = PNG_ZBUF_SIZE; + png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, + (png_uint_32)png_ptr->zbuf_size); + + png_set_write_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL, + png_flush_ptr_NULL); + +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) + png_set_filter_heuristics(png_ptr, PNG_FILTER_HEURISTIC_DEFAULT, + 1, png_doublep_NULL, png_doublep_NULL); +#endif + +#ifdef PNG_SETJMP_SUPPORTED +/* Applications that neglect to set up their own setjmp() and then encounter + a png_error() will longjmp here. Since the jmpbuf is then meaningless we + abort instead of returning. */ +#ifdef USE_FAR_KEYWORD + if (setjmp(jmpbuf)) + PNG_ABORT(); + png_memcpy(png_ptr->jmpbuf,jmpbuf,png_sizeof(jmp_buf)); +#else + if (setjmp(png_ptr->jmpbuf)) + PNG_ABORT(); +#endif +#endif + return (png_ptr); +} + +/* Initialize png_ptr structure, and allocate any memory needed */ +#if defined(PNG_1_0_X) || defined(PNG_1_2_X) +/* Deprecated. */ +#undef png_write_init +void PNGAPI +png_write_init(png_structp png_ptr) +{ + /* We only come here via pre-1.0.7-compiled applications */ + png_write_init_2(png_ptr, "1.0.6 or earlier", 0, 0); +} + +void PNGAPI +png_write_init_2(png_structp png_ptr, png_const_charp user_png_ver, + png_size_t png_struct_size, png_size_t png_info_size) +{ + /* We only come here via pre-1.0.12-compiled applications */ +#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE) + if(png_sizeof(png_struct) > png_struct_size || + png_sizeof(png_info) > png_info_size) + { + char msg[80]; + png_ptr->warning_fn=NULL; + if (user_png_ver) + { + sprintf(msg, "Application was compiled with png.h from libpng-%.20s", + user_png_ver); + png_warning(png_ptr, msg); + } + sprintf(msg, "Application is running with png.c from libpng-%.20s", + png_libpng_ver); + png_warning(png_ptr, msg); + } +#endif + if(png_sizeof(png_struct) > png_struct_size) + { + png_ptr->error_fn=NULL; +#ifdef PNG_ERROR_NUMBERS_SUPPORTED + png_ptr->flags=0; +#endif + png_error(png_ptr, + "The png struct allocated by the application for writing is too small."); + } + if(png_sizeof(png_info) > png_info_size) + { + png_ptr->error_fn=NULL; +#ifdef PNG_ERROR_NUMBERS_SUPPORTED + png_ptr->flags=0; +#endif + png_error(png_ptr, + "The info struct allocated by the application for writing is too small."); + } + png_write_init_3(&png_ptr, user_png_ver, png_struct_size); +} +#endif /* PNG_1_0_X || PNG_1_2_X */ + + +void PNGAPI +png_write_init_3(png_structpp ptr_ptr, png_const_charp user_png_ver, + png_size_t png_struct_size) +{ + png_structp png_ptr=*ptr_ptr; +#ifdef PNG_SETJMP_SUPPORTED + jmp_buf tmp_jmp; /* to save current jump buffer */ +#endif + + int i = 0; + + if (png_ptr == NULL) + return; + + do + { + if (user_png_ver[i] != png_libpng_ver[i]) + { +#ifdef PNG_LEGACY_SUPPORTED + png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH; +#else + png_ptr->warning_fn=NULL; + png_warning(png_ptr, + "Application uses deprecated png_write_init() and should be recompiled."); + break; +#endif + } + } while (png_libpng_ver[i++]); + + png_debug(1, "in png_write_init_3\n"); + +#ifdef PNG_SETJMP_SUPPORTED + /* save jump buffer and error functions */ + png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof (jmp_buf)); +#endif + + if (png_sizeof(png_struct) > png_struct_size) + { + png_destroy_struct(png_ptr); + png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG); + *ptr_ptr = png_ptr; + } + + /* reset all variables to 0 */ + png_memset(png_ptr, 0, png_sizeof (png_struct)); + + /* added at libpng-1.2.6 */ +#ifdef PNG_SET_USER_LIMITS_SUPPORTED + png_ptr->user_width_max=PNG_USER_WIDTH_MAX; + png_ptr->user_height_max=PNG_USER_HEIGHT_MAX; +#endif + +#if !defined(PNG_1_0_X) +#ifdef PNG_ASSEMBLER_CODE_SUPPORTED + png_init_mmx_flags(png_ptr); /* 1.2.0 addition */ +#endif +#endif /* PNG_1_0_X */ + +#ifdef PNG_SETJMP_SUPPORTED + /* restore jump buffer */ + png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof (jmp_buf)); +#endif + + png_set_write_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL, + png_flush_ptr_NULL); + + /* initialize zbuf - compression buffer */ + png_ptr->zbuf_size = PNG_ZBUF_SIZE; + png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, + (png_uint_32)png_ptr->zbuf_size); + +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) + png_set_filter_heuristics(png_ptr, PNG_FILTER_HEURISTIC_DEFAULT, + 1, png_doublep_NULL, png_doublep_NULL); +#endif +} + +/* Write a few rows of image data. If the image is interlaced, + * either you will have to write the 7 sub images, or, if you + * have called png_set_interlace_handling(), you will have to + * "write" the image seven times. + */ +void PNGAPI +png_write_rows(png_structp png_ptr, png_bytepp row, + png_uint_32 num_rows) +{ + png_uint_32 i; /* row counter */ + png_bytepp rp; /* row pointer */ + + png_debug(1, "in png_write_rows\n"); + + if (png_ptr == NULL) + return; + + /* loop through the rows */ + for (i = 0, rp = row; i < num_rows; i++, rp++) + { + png_write_row(png_ptr, *rp); + } +} + +/* Write the image. You only need to call this function once, even + * if you are writing an interlaced image. + */ +void PNGAPI +png_write_image(png_structp png_ptr, png_bytepp image) +{ + png_uint_32 i; /* row index */ + int pass, num_pass; /* pass variables */ + png_bytepp rp; /* points to current row */ + + if (png_ptr == NULL) + return; + + png_debug(1, "in png_write_image\n"); +#if defined(PNG_WRITE_INTERLACING_SUPPORTED) + /* intialize interlace handling. If image is not interlaced, + this will set pass to 1 */ + num_pass = png_set_interlace_handling(png_ptr); +#else + num_pass = 1; +#endif + /* loop through passes */ + for (pass = 0; pass < num_pass; pass++) + { + /* loop through image */ + for (i = 0, rp = image; i < png_ptr->height; i++, rp++) + { + png_write_row(png_ptr, *rp); + } + } +} + +/* called by user to write a row of image data */ +void PNGAPI +png_write_row(png_structp png_ptr, png_bytep row) +{ + if (png_ptr == NULL) + return; + png_debug2(1, "in png_write_row (row %ld, pass %d)\n", + png_ptr->row_number, png_ptr->pass); + + /* initialize transformations and other stuff if first time */ + if (png_ptr->row_number == 0 && png_ptr->pass == 0) + { + /* make sure we wrote the header info */ + if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE)) + png_error(png_ptr, + "png_write_info was never called before png_write_row."); + + /* check for transforms that have been set but were defined out */ +#if !defined(PNG_WRITE_INVERT_SUPPORTED) && defined(PNG_READ_INVERT_SUPPORTED) + if (png_ptr->transformations & PNG_INVERT_MONO) + png_warning(png_ptr, "PNG_WRITE_INVERT_SUPPORTED is not defined."); +#endif +#if !defined(PNG_WRITE_FILLER_SUPPORTED) && defined(PNG_READ_FILLER_SUPPORTED) + if (png_ptr->transformations & PNG_FILLER) + png_warning(png_ptr, "PNG_WRITE_FILLER_SUPPORTED is not defined."); +#endif +#if !defined(PNG_WRITE_PACKSWAP_SUPPORTED) && defined(PNG_READ_PACKSWAP_SUPPORTED) + if (png_ptr->transformations & PNG_PACKSWAP) + png_warning(png_ptr, "PNG_WRITE_PACKSWAP_SUPPORTED is not defined."); +#endif +#if !defined(PNG_WRITE_PACK_SUPPORTED) && defined(PNG_READ_PACK_SUPPORTED) + if (png_ptr->transformations & PNG_PACK) + png_warning(png_ptr, "PNG_WRITE_PACK_SUPPORTED is not defined."); +#endif +#if !defined(PNG_WRITE_SHIFT_SUPPORTED) && defined(PNG_READ_SHIFT_SUPPORTED) + if (png_ptr->transformations & PNG_SHIFT) + png_warning(png_ptr, "PNG_WRITE_SHIFT_SUPPORTED is not defined."); +#endif +#if !defined(PNG_WRITE_BGR_SUPPORTED) && defined(PNG_READ_BGR_SUPPORTED) + if (png_ptr->transformations & PNG_BGR) + png_warning(png_ptr, "PNG_WRITE_BGR_SUPPORTED is not defined."); +#endif +#if !defined(PNG_WRITE_SWAP_SUPPORTED) && defined(PNG_READ_SWAP_SUPPORTED) + if (png_ptr->transformations & PNG_SWAP_BYTES) + png_warning(png_ptr, "PNG_WRITE_SWAP_SUPPORTED is not defined."); +#endif + + png_write_start_row(png_ptr); + } + +#if defined(PNG_WRITE_INTERLACING_SUPPORTED) + /* if interlaced and not interested in row, return */ + if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE)) + { + switch (png_ptr->pass) + { + case 0: + if (png_ptr->row_number & 0x07) + { + png_write_finish_row(png_ptr); + return; + } + break; + case 1: + if ((png_ptr->row_number & 0x07) || png_ptr->width < 5) + { + png_write_finish_row(png_ptr); + return; + } + break; + case 2: + if ((png_ptr->row_number & 0x07) != 4) + { + png_write_finish_row(png_ptr); + return; + } + break; + case 3: + if ((png_ptr->row_number & 0x03) || png_ptr->width < 3) + { + png_write_finish_row(png_ptr); + return; + } + break; + case 4: + if ((png_ptr->row_number & 0x03) != 2) + { + png_write_finish_row(png_ptr); + return; + } + break; + case 5: + if ((png_ptr->row_number & 0x01) || png_ptr->width < 2) + { + png_write_finish_row(png_ptr); + return; + } + break; + case 6: + if (!(png_ptr->row_number & 0x01)) + { + png_write_finish_row(png_ptr); + return; + } + break; + } + } +#endif + + /* set up row info for transformations */ + png_ptr->row_info.color_type = png_ptr->color_type; + png_ptr->row_info.width = png_ptr->usr_width; + png_ptr->row_info.channels = png_ptr->usr_channels; + png_ptr->row_info.bit_depth = png_ptr->usr_bit_depth; + png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.bit_depth * + png_ptr->row_info.channels); + + png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth, + png_ptr->row_info.width); + + png_debug1(3, "row_info->color_type = %d\n", png_ptr->row_info.color_type); + png_debug1(3, "row_info->width = %lu\n", png_ptr->row_info.width); + png_debug1(3, "row_info->channels = %d\n", png_ptr->row_info.channels); + png_debug1(3, "row_info->bit_depth = %d\n", png_ptr->row_info.bit_depth); + png_debug1(3, "row_info->pixel_depth = %d\n", png_ptr->row_info.pixel_depth); + png_debug1(3, "row_info->rowbytes = %lu\n", png_ptr->row_info.rowbytes); + + /* Copy user's row into buffer, leaving room for filter byte. */ + png_memcpy_check(png_ptr, png_ptr->row_buf + 1, row, + png_ptr->row_info.rowbytes); + +#if defined(PNG_WRITE_INTERLACING_SUPPORTED) + /* handle interlacing */ + if (png_ptr->interlaced && png_ptr->pass < 6 && + (png_ptr->transformations & PNG_INTERLACE)) + { + png_do_write_interlace(&(png_ptr->row_info), + png_ptr->row_buf + 1, png_ptr->pass); + /* this should always get caught above, but still ... */ + if (!(png_ptr->row_info.width)) + { + png_write_finish_row(png_ptr); + return; + } + } +#endif + + /* handle other transformations */ + if (png_ptr->transformations) + png_do_write_transformations(png_ptr); + +#if defined(PNG_MNG_FEATURES_SUPPORTED) + /* Write filter_method 64 (intrapixel differencing) only if + * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and + * 2. Libpng did not write a PNG signature (this filter_method is only + * used in PNG datastreams that are embedded in MNG datastreams) and + * 3. The application called png_permit_mng_features with a mask that + * included PNG_FLAG_MNG_FILTER_64 and + * 4. The filter_method is 64 and + * 5. The color_type is RGB or RGBA + */ + if((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && + (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING)) + { + /* Intrapixel differencing */ + png_do_write_intrapixel(&(png_ptr->row_info), png_ptr->row_buf + 1); + } +#endif + + /* Find a filter if necessary, filter the row and write it out. */ + png_write_find_filter(png_ptr, &(png_ptr->row_info)); + + if (png_ptr->write_row_fn != NULL) + (*(png_ptr->write_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass); +} + +#if defined(PNG_WRITE_FLUSH_SUPPORTED) +/* Set the automatic flush interval or 0 to turn flushing off */ +void PNGAPI +png_set_flush(png_structp png_ptr, int nrows) +{ + png_debug(1, "in png_set_flush\n"); + if (png_ptr == NULL) + return; + png_ptr->flush_dist = (nrows < 0 ? 0 : nrows); +} + +/* flush the current output buffers now */ +void PNGAPI +png_write_flush(png_structp png_ptr) +{ + int wrote_IDAT; + + png_debug(1, "in png_write_flush\n"); + if (png_ptr == NULL) + return; + /* We have already written out all of the data */ + if (png_ptr->row_number >= png_ptr->num_rows) + return; + + do + { + int ret; + + /* compress the data */ + ret = deflate(&png_ptr->zstream, Z_SYNC_FLUSH); + wrote_IDAT = 0; + + /* check for compression errors */ + if (ret != Z_OK) + { + if (png_ptr->zstream.msg != NULL) + png_error(png_ptr, png_ptr->zstream.msg); + else + png_error(png_ptr, "zlib error"); + } + + if (!(png_ptr->zstream.avail_out)) + { + /* write the IDAT and reset the zlib output buffer */ + png_write_IDAT(png_ptr, png_ptr->zbuf, + png_ptr->zbuf_size); + png_ptr->zstream.next_out = png_ptr->zbuf; + png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; + wrote_IDAT = 1; + } + } while(wrote_IDAT == 1); + + /* If there is any data left to be output, write it into a new IDAT */ + if (png_ptr->zbuf_size != png_ptr->zstream.avail_out) + { + /* write the IDAT and reset the zlib output buffer */ + png_write_IDAT(png_ptr, png_ptr->zbuf, + png_ptr->zbuf_size - png_ptr->zstream.avail_out); + png_ptr->zstream.next_out = png_ptr->zbuf; + png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; + } + png_ptr->flush_rows = 0; + png_flush(png_ptr); +} +#endif /* PNG_WRITE_FLUSH_SUPPORTED */ + +/* free all memory used by the write */ +void PNGAPI +png_destroy_write_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr) +{ + png_structp png_ptr = NULL; + png_infop info_ptr = NULL; +#ifdef PNG_USER_MEM_SUPPORTED + png_free_ptr free_fn = NULL; + png_voidp mem_ptr = NULL; +#endif + + png_debug(1, "in png_destroy_write_struct\n"); + if (png_ptr_ptr != NULL) + { + png_ptr = *png_ptr_ptr; +#ifdef PNG_USER_MEM_SUPPORTED + free_fn = png_ptr->free_fn; + mem_ptr = png_ptr->mem_ptr; +#endif + } + + if (info_ptr_ptr != NULL) + info_ptr = *info_ptr_ptr; + + if (info_ptr != NULL) + { + png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1); + +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) + if (png_ptr->num_chunk_list) + { + png_free(png_ptr, png_ptr->chunk_list); + png_ptr->chunk_list=NULL; + png_ptr->num_chunk_list=0; + } +#endif + +#ifdef PNG_USER_MEM_SUPPORTED + png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn, + (png_voidp)mem_ptr); +#else + png_destroy_struct((png_voidp)info_ptr); +#endif + *info_ptr_ptr = NULL; + } + + if (png_ptr != NULL) + { + png_write_destroy(png_ptr); +#ifdef PNG_USER_MEM_SUPPORTED + png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn, + (png_voidp)mem_ptr); +#else + png_destroy_struct((png_voidp)png_ptr); +#endif + *png_ptr_ptr = NULL; + } +} + + +/* Free any memory used in png_ptr struct (old method) */ +void /* PRIVATE */ +png_write_destroy(png_structp png_ptr) +{ +#ifdef PNG_SETJMP_SUPPORTED + jmp_buf tmp_jmp; /* save jump buffer */ +#endif + png_error_ptr error_fn; + png_error_ptr warning_fn; + png_voidp error_ptr; +#ifdef PNG_USER_MEM_SUPPORTED + png_free_ptr free_fn; +#endif + + png_debug(1, "in png_write_destroy\n"); + /* free any memory zlib uses */ + deflateEnd(&png_ptr->zstream); + + /* free our memory. png_free checks NULL for us. */ + png_free(png_ptr, png_ptr->zbuf); + png_free(png_ptr, png_ptr->row_buf); + png_free(png_ptr, png_ptr->prev_row); + png_free(png_ptr, png_ptr->sub_row); + png_free(png_ptr, png_ptr->up_row); + png_free(png_ptr, png_ptr->avg_row); + png_free(png_ptr, png_ptr->paeth_row); + +#if defined(PNG_TIME_RFC1123_SUPPORTED) + png_free(png_ptr, png_ptr->time_buffer); +#endif + +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) + png_free(png_ptr, png_ptr->prev_filters); + png_free(png_ptr, png_ptr->filter_weights); + png_free(png_ptr, png_ptr->inv_filter_weights); + png_free(png_ptr, png_ptr->filter_costs); + png_free(png_ptr, png_ptr->inv_filter_costs); +#endif + +#ifdef PNG_SETJMP_SUPPORTED + /* reset structure */ + png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof (jmp_buf)); +#endif + + error_fn = png_ptr->error_fn; + warning_fn = png_ptr->warning_fn; + error_ptr = png_ptr->error_ptr; +#ifdef PNG_USER_MEM_SUPPORTED + free_fn = png_ptr->free_fn; +#endif + + png_memset(png_ptr, 0, png_sizeof (png_struct)); + + png_ptr->error_fn = error_fn; + png_ptr->warning_fn = warning_fn; + png_ptr->error_ptr = error_ptr; +#ifdef PNG_USER_MEM_SUPPORTED + png_ptr->free_fn = free_fn; +#endif + +#ifdef PNG_SETJMP_SUPPORTED + png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof (jmp_buf)); +#endif +} + +/* Allow the application to select one or more row filters to use. */ +void PNGAPI +png_set_filter(png_structp png_ptr, int method, int filters) +{ + png_debug(1, "in png_set_filter\n"); + if (png_ptr == NULL) + return; +#if defined(PNG_MNG_FEATURES_SUPPORTED) + if((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && + (method == PNG_INTRAPIXEL_DIFFERENCING)) + method = PNG_FILTER_TYPE_BASE; +#endif + if (method == PNG_FILTER_TYPE_BASE) + { + switch (filters & (PNG_ALL_FILTERS | 0x07)) + { + case 5: + case 6: + case 7: png_warning(png_ptr, "Unknown row filter for method 0"); + case PNG_FILTER_VALUE_NONE: png_ptr->do_filter=PNG_FILTER_NONE; break; + case PNG_FILTER_VALUE_SUB: png_ptr->do_filter=PNG_FILTER_SUB; break; + case PNG_FILTER_VALUE_UP: png_ptr->do_filter=PNG_FILTER_UP; break; + case PNG_FILTER_VALUE_AVG: png_ptr->do_filter=PNG_FILTER_AVG; break; + case PNG_FILTER_VALUE_PAETH: png_ptr->do_filter=PNG_FILTER_PAETH;break; + default: png_ptr->do_filter = (png_byte)filters; break; + } + + /* If we have allocated the row_buf, this means we have already started + * with the image and we should have allocated all of the filter buffers + * that have been selected. If prev_row isn't already allocated, then + * it is too late to start using the filters that need it, since we + * will be missing the data in the previous row. If an application + * wants to start and stop using particular filters during compression, + * it should start out with all of the filters, and then add and + * remove them after the start of compression. + */ + if (png_ptr->row_buf != NULL) + { + if ((png_ptr->do_filter & PNG_FILTER_SUB) && png_ptr->sub_row == NULL) + { + png_ptr->sub_row = (png_bytep)png_malloc(png_ptr, + (png_ptr->rowbytes + 1)); + png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB; + } + + if ((png_ptr->do_filter & PNG_FILTER_UP) && png_ptr->up_row == NULL) + { + if (png_ptr->prev_row == NULL) + { + png_warning(png_ptr, "Can't add Up filter after starting"); + png_ptr->do_filter &= ~PNG_FILTER_UP; + } + else + { + png_ptr->up_row = (png_bytep)png_malloc(png_ptr, + (png_ptr->rowbytes + 1)); + png_ptr->up_row[0] = PNG_FILTER_VALUE_UP; + } + } + + if ((png_ptr->do_filter & PNG_FILTER_AVG) && png_ptr->avg_row == NULL) + { + if (png_ptr->prev_row == NULL) + { + png_warning(png_ptr, "Can't add Average filter after starting"); + png_ptr->do_filter &= ~PNG_FILTER_AVG; + } + else + { + png_ptr->avg_row = (png_bytep)png_malloc(png_ptr, + (png_ptr->rowbytes + 1)); + png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG; + } + } + + if ((png_ptr->do_filter & PNG_FILTER_PAETH) && + png_ptr->paeth_row == NULL) + { + if (png_ptr->prev_row == NULL) + { + png_warning(png_ptr, "Can't add Paeth filter after starting"); + png_ptr->do_filter &= (png_byte)(~PNG_FILTER_PAETH); + } + else + { + png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr, + (png_ptr->rowbytes + 1)); + png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH; + } + } + + if (png_ptr->do_filter == PNG_NO_FILTERS) + png_ptr->do_filter = PNG_FILTER_NONE; + } + } + else + png_error(png_ptr, "Unknown custom filter method"); +} + +/* This allows us to influence the way in which libpng chooses the "best" + * filter for the current scanline. While the "minimum-sum-of-absolute- + * differences metric is relatively fast and effective, there is some + * question as to whether it can be improved upon by trying to keep the + * filtered data going to zlib more consistent, hopefully resulting in + * better compression. + */ +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) /* GRR 970116 */ +void PNGAPI +png_set_filter_heuristics(png_structp png_ptr, int heuristic_method, + int num_weights, png_doublep filter_weights, + png_doublep filter_costs) +{ + int i; + + png_debug(1, "in png_set_filter_heuristics\n"); + if (png_ptr == NULL) + return; + if (heuristic_method >= PNG_FILTER_HEURISTIC_LAST) + { + png_warning(png_ptr, "Unknown filter heuristic method"); + return; + } + + if (heuristic_method == PNG_FILTER_HEURISTIC_DEFAULT) + { + heuristic_method = PNG_FILTER_HEURISTIC_UNWEIGHTED; + } + + if (num_weights < 0 || filter_weights == NULL || + heuristic_method == PNG_FILTER_HEURISTIC_UNWEIGHTED) + { + num_weights = 0; + } + + png_ptr->num_prev_filters = (png_byte)num_weights; + png_ptr->heuristic_method = (png_byte)heuristic_method; + + if (num_weights > 0) + { + if (png_ptr->prev_filters == NULL) + { + png_ptr->prev_filters = (png_bytep)png_malloc(png_ptr, + (png_uint_32)(png_sizeof(png_byte) * num_weights)); + + /* To make sure that the weighting starts out fairly */ + for (i = 0; i < num_weights; i++) + { + png_ptr->prev_filters[i] = 255; + } + } + + if (png_ptr->filter_weights == NULL) + { + png_ptr->filter_weights = (png_uint_16p)png_malloc(png_ptr, + (png_uint_32)(png_sizeof(png_uint_16) * num_weights)); + + png_ptr->inv_filter_weights = (png_uint_16p)png_malloc(png_ptr, + (png_uint_32)(png_sizeof(png_uint_16) * num_weights)); + for (i = 0; i < num_weights; i++) + { + png_ptr->inv_filter_weights[i] = + png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR; + } + } + + for (i = 0; i < num_weights; i++) + { + if (filter_weights[i] < 0.0) + { + png_ptr->inv_filter_weights[i] = + png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR; + } + else + { + png_ptr->inv_filter_weights[i] = + (png_uint_16)((double)PNG_WEIGHT_FACTOR*filter_weights[i]+0.5); + png_ptr->filter_weights[i] = + (png_uint_16)((double)PNG_WEIGHT_FACTOR/filter_weights[i]+0.5); + } + } + } + + /* If, in the future, there are other filter methods, this would + * need to be based on png_ptr->filter. + */ + if (png_ptr->filter_costs == NULL) + { + png_ptr->filter_costs = (png_uint_16p)png_malloc(png_ptr, + (png_uint_32)(png_sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST)); + + png_ptr->inv_filter_costs = (png_uint_16p)png_malloc(png_ptr, + (png_uint_32)(png_sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST)); + + for (i = 0; i < PNG_FILTER_VALUE_LAST; i++) + { + png_ptr->inv_filter_costs[i] = + png_ptr->filter_costs[i] = PNG_COST_FACTOR; + } + } + + /* Here is where we set the relative costs of the different filters. We + * should take the desired compression level into account when setting + * the costs, so that Paeth, for instance, has a high relative cost at low + * compression levels, while it has a lower relative cost at higher + * compression settings. The filter types are in order of increasing + * relative cost, so it would be possible to do this with an algorithm. + */ + for (i = 0; i < PNG_FILTER_VALUE_LAST; i++) + { + if (filter_costs == NULL || filter_costs[i] < 0.0) + { + png_ptr->inv_filter_costs[i] = + png_ptr->filter_costs[i] = PNG_COST_FACTOR; + } + else if (filter_costs[i] >= 1.0) + { + png_ptr->inv_filter_costs[i] = + (png_uint_16)((double)PNG_COST_FACTOR / filter_costs[i] + 0.5); + png_ptr->filter_costs[i] = + (png_uint_16)((double)PNG_COST_FACTOR * filter_costs[i] + 0.5); + } + } +} +#endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */ + +void PNGAPI +png_set_compression_level(png_structp png_ptr, int level) +{ + png_debug(1, "in png_set_compression_level\n"); + if (png_ptr == NULL) + return; + png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_LEVEL; + png_ptr->zlib_level = level; +} + +void PNGAPI +png_set_compression_mem_level(png_structp png_ptr, int mem_level) +{ + png_debug(1, "in png_set_compression_mem_level\n"); + if (png_ptr == NULL) + return; + png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL; + png_ptr->zlib_mem_level = mem_level; +} + +void PNGAPI +png_set_compression_strategy(png_structp png_ptr, int strategy) +{ + png_debug(1, "in png_set_compression_strategy\n"); + if (png_ptr == NULL) + return; + png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_STRATEGY; + png_ptr->zlib_strategy = strategy; +} + +void PNGAPI +png_set_compression_window_bits(png_structp png_ptr, int window_bits) +{ + if (png_ptr == NULL) + return; + if (window_bits > 15) + png_warning(png_ptr, "Only compression windows <= 32k supported by PNG"); + else if (window_bits < 8) + png_warning(png_ptr, "Only compression windows >= 256 supported by PNG"); +#ifndef WBITS_8_OK + /* avoid libpng bug with 256-byte windows */ + if (window_bits == 8) + { + png_warning(png_ptr, "Compression window is being reset to 512"); + window_bits=9; + } +#endif + png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS; + png_ptr->zlib_window_bits = window_bits; +} + +void PNGAPI +png_set_compression_method(png_structp png_ptr, int method) +{ + png_debug(1, "in png_set_compression_method\n"); + if (png_ptr == NULL) + return; + if (method != 8) + png_warning(png_ptr, "Only compression method 8 is supported by PNG"); + png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_METHOD; + png_ptr->zlib_method = method; +} + +void PNGAPI +png_set_write_status_fn(png_structp png_ptr, png_write_status_ptr write_row_fn) +{ + if (png_ptr == NULL) + return; + png_ptr->write_row_fn = write_row_fn; +} + +#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) +void PNGAPI +png_set_write_user_transform_fn(png_structp png_ptr, png_user_transform_ptr + write_user_transform_fn) +{ + png_debug(1, "in png_set_write_user_transform_fn\n"); + if (png_ptr == NULL) + return; + png_ptr->transformations |= PNG_USER_TRANSFORM; + png_ptr->write_user_transform_fn = write_user_transform_fn; +} +#endif + + +#if defined(PNG_INFO_IMAGE_SUPPORTED) +void PNGAPI +png_write_png(png_structp png_ptr, png_infop info_ptr, + int transforms, voidp params) +{ + if (png_ptr == NULL || info_ptr == NULL) + return; +#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) + /* invert the alpha channel from opacity to transparency */ + if (transforms & PNG_TRANSFORM_INVERT_ALPHA) + png_set_invert_alpha(png_ptr); +#endif + + /* Write the file header information. */ + png_write_info(png_ptr, info_ptr); + + /* ------ these transformations don't touch the info structure ------- */ + +#if defined(PNG_WRITE_INVERT_SUPPORTED) + /* invert monochrome pixels */ + if (transforms & PNG_TRANSFORM_INVERT_MONO) + png_set_invert_mono(png_ptr); +#endif + +#if defined(PNG_WRITE_SHIFT_SUPPORTED) + /* Shift the pixels up to a legal bit depth and fill in + * as appropriate to correctly scale the image. + */ + if ((transforms & PNG_TRANSFORM_SHIFT) + && (info_ptr->valid & PNG_INFO_sBIT)) + png_set_shift(png_ptr, &info_ptr->sig_bit); +#endif + +#if defined(PNG_WRITE_PACK_SUPPORTED) + /* pack pixels into bytes */ + if (transforms & PNG_TRANSFORM_PACKING) + png_set_packing(png_ptr); +#endif + +#if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) + /* swap location of alpha bytes from ARGB to RGBA */ + if (transforms & PNG_TRANSFORM_SWAP_ALPHA) + png_set_swap_alpha(png_ptr); +#endif + +#if defined(PNG_WRITE_FILLER_SUPPORTED) + /* Get rid of filler (OR ALPHA) bytes, pack XRGB/RGBX/ARGB/RGBA into + * RGB (4 channels -> 3 channels). The second parameter is not used. + */ + if (transforms & PNG_TRANSFORM_STRIP_FILLER) + png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE); +#endif + +#if defined(PNG_WRITE_BGR_SUPPORTED) + /* flip BGR pixels to RGB */ + if (transforms & PNG_TRANSFORM_BGR) + png_set_bgr(png_ptr); +#endif + +#if defined(PNG_WRITE_SWAP_SUPPORTED) + /* swap bytes of 16-bit files to most significant byte first */ + if (transforms & PNG_TRANSFORM_SWAP_ENDIAN) + png_set_swap(png_ptr); +#endif + +#if defined(PNG_WRITE_PACKSWAP_SUPPORTED) + /* swap bits of 1, 2, 4 bit packed pixel formats */ + if (transforms & PNG_TRANSFORM_PACKSWAP) + png_set_packswap(png_ptr); +#endif + + /* ----------------------- end of transformations ------------------- */ + + /* write the bits */ + if (info_ptr->valid & PNG_INFO_IDAT) + png_write_image(png_ptr, info_ptr->row_pointers); + + /* It is REQUIRED to call this to finish writing the rest of the file */ + png_write_end(png_ptr, info_ptr); + + if(transforms == 0 || params == NULL) + /* quiet compiler warnings */ return; +} +#endif +#endif /* PNG_WRITE_SUPPORTED */ diff --git a/mod/pub.mod/libpng.mod/pngwtran.c b/mod/pub.mod/libpng.mod/pngwtran.c new file mode 100644 index 0000000..0372fe6 --- /dev/null +++ b/mod/pub.mod/libpng.mod/pngwtran.c @@ -0,0 +1,572 @@ + +/* pngwtran.c - transforms the data in a row for PNG writers + * + * Last changed in libpng 1.2.9 April 14, 2006 + * For conditions of distribution and use, see copyright notice in png.h + * Copyright (c) 1998-2006 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + */ + +#define PNG_INTERNAL +#include "png.h" +#ifdef PNG_WRITE_SUPPORTED + +/* Transform the data according to the user's wishes. The order of + * transformations is significant. + */ +void /* PRIVATE */ +png_do_write_transformations(png_structp png_ptr) +{ + png_debug(1, "in png_do_write_transformations\n"); + + if (png_ptr == NULL) + return; + +#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) + if (png_ptr->transformations & PNG_USER_TRANSFORM) + if(png_ptr->write_user_transform_fn != NULL) + (*(png_ptr->write_user_transform_fn)) /* user write transform function */ + (png_ptr, /* png_ptr */ + &(png_ptr->row_info), /* row_info: */ + /* png_uint_32 width; width of row */ + /* png_uint_32 rowbytes; number of bytes in row */ + /* png_byte color_type; color type of pixels */ + /* png_byte bit_depth; bit depth of samples */ + /* png_byte channels; number of channels (1-4) */ + /* png_byte pixel_depth; bits per pixel (depth*channels) */ + png_ptr->row_buf + 1); /* start of pixel data for row */ +#endif +#if defined(PNG_WRITE_FILLER_SUPPORTED) + if (png_ptr->transformations & PNG_FILLER) + png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1, + png_ptr->flags); +#endif +#if defined(PNG_WRITE_PACKSWAP_SUPPORTED) + if (png_ptr->transformations & PNG_PACKSWAP) + png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1); +#endif +#if defined(PNG_WRITE_PACK_SUPPORTED) + if (png_ptr->transformations & PNG_PACK) + png_do_pack(&(png_ptr->row_info), png_ptr->row_buf + 1, + (png_uint_32)png_ptr->bit_depth); +#endif +#if defined(PNG_WRITE_SWAP_SUPPORTED) + if (png_ptr->transformations & PNG_SWAP_BYTES) + png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1); +#endif +#if defined(PNG_WRITE_SHIFT_SUPPORTED) + if (png_ptr->transformations & PNG_SHIFT) + png_do_shift(&(png_ptr->row_info), png_ptr->row_buf + 1, + &(png_ptr->shift)); +#endif +#if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) + if (png_ptr->transformations & PNG_SWAP_ALPHA) + png_do_write_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1); +#endif +#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) + if (png_ptr->transformations & PNG_INVERT_ALPHA) + png_do_write_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1); +#endif +#if defined(PNG_WRITE_BGR_SUPPORTED) + if (png_ptr->transformations & PNG_BGR) + png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1); +#endif +#if defined(PNG_WRITE_INVERT_SUPPORTED) + if (png_ptr->transformations & PNG_INVERT_MONO) + png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1); +#endif +} + +#if defined(PNG_WRITE_PACK_SUPPORTED) +/* Pack pixels into bytes. Pass the true bit depth in bit_depth. The + * row_info bit depth should be 8 (one pixel per byte). The channels + * should be 1 (this only happens on grayscale and paletted images). + */ +void /* PRIVATE */ +png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth) +{ + png_debug(1, "in png_do_pack\n"); + if (row_info->bit_depth == 8 && +#if defined(PNG_USELESS_TESTS_SUPPORTED) + row != NULL && row_info != NULL && +#endif + row_info->channels == 1) + { + switch ((int)bit_depth) + { + case 1: + { + png_bytep sp, dp; + int mask, v; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + sp = row; + dp = row; + mask = 0x80; + v = 0; + + for (i = 0; i < row_width; i++) + { + if (*sp != 0) + v |= mask; + sp++; + if (mask > 1) + mask >>= 1; + else + { + mask = 0x80; + *dp = (png_byte)v; + dp++; + v = 0; + } + } + if (mask != 0x80) + *dp = (png_byte)v; + break; + } + case 2: + { + png_bytep sp, dp; + int shift, v; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + sp = row; + dp = row; + shift = 6; + v = 0; + for (i = 0; i < row_width; i++) + { + png_byte value; + + value = (png_byte)(*sp & 0x03); + v |= (value << shift); + if (shift == 0) + { + shift = 6; + *dp = (png_byte)v; + dp++; + v = 0; + } + else + shift -= 2; + sp++; + } + if (shift != 6) + *dp = (png_byte)v; + break; + } + case 4: + { + png_bytep sp, dp; + int shift, v; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + sp = row; + dp = row; + shift = 4; + v = 0; + for (i = 0; i < row_width; i++) + { + png_byte value; + + value = (png_byte)(*sp & 0x0f); + v |= (value << shift); + + if (shift == 0) + { + shift = 4; + *dp = (png_byte)v; + dp++; + v = 0; + } + else + shift -= 4; + + sp++; + } + if (shift != 4) + *dp = (png_byte)v; + break; + } + } + row_info->bit_depth = (png_byte)bit_depth; + row_info->pixel_depth = (png_byte)(bit_depth * row_info->channels); + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, + row_info->width); + } +} +#endif + +#if defined(PNG_WRITE_SHIFT_SUPPORTED) +/* Shift pixel values to take advantage of whole range. Pass the + * true number of bits in bit_depth. The row should be packed + * according to row_info->bit_depth. Thus, if you had a row of + * bit depth 4, but the pixels only had values from 0 to 7, you + * would pass 3 as bit_depth, and this routine would translate the + * data to 0 to 15. + */ +void /* PRIVATE */ +png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth) +{ + png_debug(1, "in png_do_shift\n"); +#if defined(PNG_USELESS_TESTS_SUPPORTED) + if (row != NULL && row_info != NULL && +#else + if ( +#endif + row_info->color_type != PNG_COLOR_TYPE_PALETTE) + { + int shift_start[4], shift_dec[4]; + int channels = 0; + + if (row_info->color_type & PNG_COLOR_MASK_COLOR) + { + shift_start[channels] = row_info->bit_depth - bit_depth->red; + shift_dec[channels] = bit_depth->red; + channels++; + shift_start[channels] = row_info->bit_depth - bit_depth->green; + shift_dec[channels] = bit_depth->green; + channels++; + shift_start[channels] = row_info->bit_depth - bit_depth->blue; + shift_dec[channels] = bit_depth->blue; + channels++; + } + else + { + shift_start[channels] = row_info->bit_depth - bit_depth->gray; + shift_dec[channels] = bit_depth->gray; + channels++; + } + if (row_info->color_type & PNG_COLOR_MASK_ALPHA) + { + shift_start[channels] = row_info->bit_depth - bit_depth->alpha; + shift_dec[channels] = bit_depth->alpha; + channels++; + } + + /* with low row depths, could only be grayscale, so one channel */ + if (row_info->bit_depth < 8) + { + png_bytep bp = row; + png_uint_32 i; + png_byte mask; + png_uint_32 row_bytes = row_info->rowbytes; + + if (bit_depth->gray == 1 && row_info->bit_depth == 2) + mask = 0x55; + else if (row_info->bit_depth == 4 && bit_depth->gray == 3) + mask = 0x11; + else + mask = 0xff; + + for (i = 0; i < row_bytes; i++, bp++) + { + png_uint_16 v; + int j; + + v = *bp; + *bp = 0; + for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0]) + { + if (j > 0) + *bp |= (png_byte)((v << j) & 0xff); + else + *bp |= (png_byte)((v >> (-j)) & mask); + } + } + } + else if (row_info->bit_depth == 8) + { + png_bytep bp = row; + png_uint_32 i; + png_uint_32 istop = channels * row_info->width; + + for (i = 0; i < istop; i++, bp++) + { + + png_uint_16 v; + int j; + int c = (int)(i%channels); + + v = *bp; + *bp = 0; + for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c]) + { + if (j > 0) + *bp |= (png_byte)((v << j) & 0xff); + else + *bp |= (png_byte)((v >> (-j)) & 0xff); + } + } + } + else + { + png_bytep bp; + png_uint_32 i; + png_uint_32 istop = channels * row_info->width; + + for (bp = row, i = 0; i < istop; i++) + { + int c = (int)(i%channels); + png_uint_16 value, v; + int j; + + v = (png_uint_16)(((png_uint_16)(*bp) << 8) + *(bp + 1)); + value = 0; + for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c]) + { + if (j > 0) + value |= (png_uint_16)((v << j) & (png_uint_16)0xffff); + else + value |= (png_uint_16)((v >> (-j)) & (png_uint_16)0xffff); + } + *bp++ = (png_byte)(value >> 8); + *bp++ = (png_byte)(value & 0xff); + } + } + } +} +#endif + +#if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) +void /* PRIVATE */ +png_do_write_swap_alpha(png_row_infop row_info, png_bytep row) +{ + png_debug(1, "in png_do_write_swap_alpha\n"); +#if defined(PNG_USELESS_TESTS_SUPPORTED) + if (row != NULL && row_info != NULL) +#endif + { + if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + { + /* This converts from ARGB to RGBA */ + if (row_info->bit_depth == 8) + { + png_bytep sp, dp; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + for (i = 0, sp = dp = row; i < row_width; i++) + { + png_byte save = *(sp++); + *(dp++) = *(sp++); + *(dp++) = *(sp++); + *(dp++) = *(sp++); + *(dp++) = save; + } + } + /* This converts from AARRGGBB to RRGGBBAA */ + else + { + png_bytep sp, dp; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + for (i = 0, sp = dp = row; i < row_width; i++) + { + png_byte save[2]; + save[0] = *(sp++); + save[1] = *(sp++); + *(dp++) = *(sp++); + *(dp++) = *(sp++); + *(dp++) = *(sp++); + *(dp++) = *(sp++); + *(dp++) = *(sp++); + *(dp++) = *(sp++); + *(dp++) = save[0]; + *(dp++) = save[1]; + } + } + } + else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + { + /* This converts from AG to GA */ + if (row_info->bit_depth == 8) + { + png_bytep sp, dp; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + for (i = 0, sp = dp = row; i < row_width; i++) + { + png_byte save = *(sp++); + *(dp++) = *(sp++); + *(dp++) = save; + } + } + /* This converts from AAGG to GGAA */ + else + { + png_bytep sp, dp; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + for (i = 0, sp = dp = row; i < row_width; i++) + { + png_byte save[2]; + save[0] = *(sp++); + save[1] = *(sp++); + *(dp++) = *(sp++); + *(dp++) = *(sp++); + *(dp++) = save[0]; + *(dp++) = save[1]; + } + } + } + } +} +#endif + +#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) +void /* PRIVATE */ +png_do_write_invert_alpha(png_row_infop row_info, png_bytep row) +{ + png_debug(1, "in png_do_write_invert_alpha\n"); +#if defined(PNG_USELESS_TESTS_SUPPORTED) + if (row != NULL && row_info != NULL) +#endif + { + if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + { + /* This inverts the alpha channel in RGBA */ + if (row_info->bit_depth == 8) + { + png_bytep sp, dp; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + for (i = 0, sp = dp = row; i < row_width; i++) + { + /* does nothing + *(dp++) = *(sp++); + *(dp++) = *(sp++); + *(dp++) = *(sp++); + */ + sp+=3; dp = sp; + *(dp++) = (png_byte)(255 - *(sp++)); + } + } + /* This inverts the alpha channel in RRGGBBAA */ + else + { + png_bytep sp, dp; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + for (i = 0, sp = dp = row; i < row_width; i++) + { + /* does nothing + *(dp++) = *(sp++); + *(dp++) = *(sp++); + *(dp++) = *(sp++); + *(dp++) = *(sp++); + *(dp++) = *(sp++); + *(dp++) = *(sp++); + */ + sp+=6; dp = sp; + *(dp++) = (png_byte)(255 - *(sp++)); + *(dp++) = (png_byte)(255 - *(sp++)); + } + } + } + else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + { + /* This inverts the alpha channel in GA */ + if (row_info->bit_depth == 8) + { + png_bytep sp, dp; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + for (i = 0, sp = dp = row; i < row_width; i++) + { + *(dp++) = *(sp++); + *(dp++) = (png_byte)(255 - *(sp++)); + } + } + /* This inverts the alpha channel in GGAA */ + else + { + png_bytep sp, dp; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + for (i = 0, sp = dp = row; i < row_width; i++) + { + /* does nothing + *(dp++) = *(sp++); + *(dp++) = *(sp++); + */ + sp+=2; dp = sp; + *(dp++) = (png_byte)(255 - *(sp++)); + *(dp++) = (png_byte)(255 - *(sp++)); + } + } + } + } +} +#endif + +#if defined(PNG_MNG_FEATURES_SUPPORTED) +/* undoes intrapixel differencing */ +void /* PRIVATE */ +png_do_write_intrapixel(png_row_infop row_info, png_bytep row) +{ + png_debug(1, "in png_do_write_intrapixel\n"); + if ( +#if defined(PNG_USELESS_TESTS_SUPPORTED) + row != NULL && row_info != NULL && +#endif + (row_info->color_type & PNG_COLOR_MASK_COLOR)) + { + int bytes_per_pixel; + png_uint_32 row_width = row_info->width; + if (row_info->bit_depth == 8) + { + png_bytep rp; + png_uint_32 i; + + if (row_info->color_type == PNG_COLOR_TYPE_RGB) + bytes_per_pixel = 3; + else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + bytes_per_pixel = 4; + else + return; + + for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) + { + *(rp) = (png_byte)((*rp - *(rp+1))&0xff); + *(rp+2) = (png_byte)((*(rp+2) - *(rp+1))&0xff); + } + } + else if (row_info->bit_depth == 16) + { + png_bytep rp; + png_uint_32 i; + + if (row_info->color_type == PNG_COLOR_TYPE_RGB) + bytes_per_pixel = 6; + else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + bytes_per_pixel = 8; + else + return; + + for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) + { + png_uint_32 s0 = (*(rp ) << 8) | *(rp+1); + png_uint_32 s1 = (*(rp+2) << 8) | *(rp+3); + png_uint_32 s2 = (*(rp+4) << 8) | *(rp+5); + png_uint_32 red = (png_uint_32)((s0-s1) & 0xffffL); + png_uint_32 blue = (png_uint_32)((s2-s1) & 0xffffL); + *(rp ) = (png_byte)((red >> 8) & 0xff); + *(rp+1) = (png_byte)(red & 0xff); + *(rp+4) = (png_byte)((blue >> 8) & 0xff); + *(rp+5) = (png_byte)(blue & 0xff); + } + } + } +} +#endif /* PNG_MNG_FEATURES_SUPPORTED */ +#endif /* PNG_WRITE_SUPPORTED */ diff --git a/mod/pub.mod/libpng.mod/pngwutil.c b/mod/pub.mod/libpng.mod/pngwutil.c new file mode 100644 index 0000000..4a9c52b --- /dev/null +++ b/mod/pub.mod/libpng.mod/pngwutil.c @@ -0,0 +1,2750 @@ + +/* pngwutil.c - utilities to write a PNG file + * + * Last changed in libpng 1.2.11 June 4, 2006 + * For conditions of distribution and use, see copyright notice in png.h + * Copyright (c) 1998-2006 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + */ + +#define PNG_INTERNAL +#include "png.h" +#ifdef PNG_WRITE_SUPPORTED + +/* Place a 32-bit number into a buffer in PNG byte order. We work + * with unsigned numbers for convenience, although one supported + * ancillary chunk uses signed (two's complement) numbers. + */ +void PNGAPI +png_save_uint_32(png_bytep buf, png_uint_32 i) +{ + buf[0] = (png_byte)((i >> 24) & 0xff); + buf[1] = (png_byte)((i >> 16) & 0xff); + buf[2] = (png_byte)((i >> 8) & 0xff); + buf[3] = (png_byte)(i & 0xff); +} + +/* The png_save_int_32 function assumes integers are stored in two's + * complement format. If this isn't the case, then this routine needs to + * be modified to write data in two's complement format. + */ +void PNGAPI +png_save_int_32(png_bytep buf, png_int_32 i) +{ + buf[0] = (png_byte)((i >> 24) & 0xff); + buf[1] = (png_byte)((i >> 16) & 0xff); + buf[2] = (png_byte)((i >> 8) & 0xff); + buf[3] = (png_byte)(i & 0xff); +} + +/* Place a 16-bit number into a buffer in PNG byte order. + * The parameter is declared unsigned int, not png_uint_16, + * just to avoid potential problems on pre-ANSI C compilers. + */ +void PNGAPI +png_save_uint_16(png_bytep buf, unsigned int i) +{ + buf[0] = (png_byte)((i >> 8) & 0xff); + buf[1] = (png_byte)(i & 0xff); +} + +/* Write a PNG chunk all at once. The type is an array of ASCII characters + * representing the chunk name. The array must be at least 4 bytes in + * length, and does not need to be null terminated. To be safe, pass the + * pre-defined chunk names here, and if you need a new one, define it + * where the others are defined. The length is the length of the data. + * All the data must be present. If that is not possible, use the + * png_write_chunk_start(), png_write_chunk_data(), and png_write_chunk_end() + * functions instead. + */ +void PNGAPI +png_write_chunk(png_structp png_ptr, png_bytep chunk_name, + png_bytep data, png_size_t length) +{ + png_write_chunk_start(png_ptr, chunk_name, (png_uint_32)length); + png_write_chunk_data(png_ptr, data, length); + png_write_chunk_end(png_ptr); +} + +/* Write the start of a PNG chunk. The type is the chunk type. + * The total_length is the sum of the lengths of all the data you will be + * passing in png_write_chunk_data(). + */ +void PNGAPI +png_write_chunk_start(png_structp png_ptr, png_bytep chunk_name, + png_uint_32 length) +{ + png_byte buf[4]; + png_debug2(0, "Writing %s chunk (%lu bytes)\n", chunk_name, length); + + /* write the length */ + png_save_uint_32(buf, length); + png_write_data(png_ptr, buf, (png_size_t)4); + + /* write the chunk name */ + png_write_data(png_ptr, chunk_name, (png_size_t)4); + /* reset the crc and run it over the chunk name */ + png_reset_crc(png_ptr); + png_calculate_crc(png_ptr, chunk_name, (png_size_t)4); +} + +/* Write the data of a PNG chunk started with png_write_chunk_start(). + * Note that multiple calls to this function are allowed, and that the + * sum of the lengths from these calls *must* add up to the total_length + * given to png_write_chunk_start(). + */ +void PNGAPI +png_write_chunk_data(png_structp png_ptr, png_bytep data, png_size_t length) +{ + /* write the data, and run the CRC over it */ + if (data != NULL && length > 0) + { + png_calculate_crc(png_ptr, data, length); + png_write_data(png_ptr, data, length); + } +} + +/* Finish a chunk started with png_write_chunk_start(). */ +void PNGAPI +png_write_chunk_end(png_structp png_ptr) +{ + png_byte buf[4]; + + /* write the crc */ + png_save_uint_32(buf, png_ptr->crc); + + png_write_data(png_ptr, buf, (png_size_t)4); +} + +/* Simple function to write the signature. If we have already written + * the magic bytes of the signature, or more likely, the PNG stream is + * being embedded into another stream and doesn't need its own signature, + * we should call png_set_sig_bytes() to tell libpng how many of the + * bytes have already been written. + */ +void /* PRIVATE */ +png_write_sig(png_structp png_ptr) +{ + png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10}; + /* write the rest of the 8 byte signature */ + png_write_data(png_ptr, &png_signature[png_ptr->sig_bytes], + (png_size_t)8 - png_ptr->sig_bytes); + if(png_ptr->sig_bytes < 3) + png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE; +} + +#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_iCCP_SUPPORTED) +/* + * This pair of functions encapsulates the operation of (a) compressing a + * text string, and (b) issuing it later as a series of chunk data writes. + * The compression_state structure is shared context for these functions + * set up by the caller in order to make the whole mess thread-safe. + */ + +typedef struct +{ + char *input; /* the uncompressed input data */ + int input_len; /* its length */ + int num_output_ptr; /* number of output pointers used */ + int max_output_ptr; /* size of output_ptr */ + png_charpp output_ptr; /* array of pointers to output */ +} compression_state; + +/* compress given text into storage in the png_ptr structure */ +static int /* PRIVATE */ +png_text_compress(png_structp png_ptr, + png_charp text, png_size_t text_len, int compression, + compression_state *comp) +{ + int ret; + + comp->num_output_ptr = 0; + comp->max_output_ptr = 0; + comp->output_ptr = NULL; + comp->input = NULL; + comp->input_len = 0; + + /* we may just want to pass the text right through */ + if (compression == PNG_TEXT_COMPRESSION_NONE) + { + comp->input = text; + comp->input_len = text_len; + return((int)text_len); + } + + if (compression >= PNG_TEXT_COMPRESSION_LAST) + { +#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE) + char msg[50]; + sprintf(msg, "Unknown compression type %d", compression); + png_warning(png_ptr, msg); +#else + png_warning(png_ptr, "Unknown compression type"); +#endif + } + + /* We can't write the chunk until we find out how much data we have, + * which means we need to run the compressor first and save the + * output. This shouldn't be a problem, as the vast majority of + * comments should be reasonable, but we will set up an array of + * malloc'd pointers to be sure. + * + * If we knew the application was well behaved, we could simplify this + * greatly by assuming we can always malloc an output buffer large + * enough to hold the compressed text ((1001 * text_len / 1000) + 12) + * and malloc this directly. The only time this would be a bad idea is + * if we can't malloc more than 64K and we have 64K of random input + * data, or if the input string is incredibly large (although this + * wouldn't cause a failure, just a slowdown due to swapping). + */ + + /* set up the compression buffers */ + png_ptr->zstream.avail_in = (uInt)text_len; + png_ptr->zstream.next_in = (Bytef *)text; + png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; + png_ptr->zstream.next_out = (Bytef *)png_ptr->zbuf; + + /* this is the same compression loop as in png_write_row() */ + do + { + /* compress the data */ + ret = deflate(&png_ptr->zstream, Z_NO_FLUSH); + if (ret != Z_OK) + { + /* error */ + if (png_ptr->zstream.msg != NULL) + png_error(png_ptr, png_ptr->zstream.msg); + else + png_error(png_ptr, "zlib error"); + } + /* check to see if we need more room */ + if (!(png_ptr->zstream.avail_out)) + { + /* make sure the output array has room */ + if (comp->num_output_ptr >= comp->max_output_ptr) + { + int old_max; + + old_max = comp->max_output_ptr; + comp->max_output_ptr = comp->num_output_ptr + 4; + if (comp->output_ptr != NULL) + { + png_charpp old_ptr; + + old_ptr = comp->output_ptr; + comp->output_ptr = (png_charpp)png_malloc(png_ptr, + (png_uint_32)(comp->max_output_ptr * + png_sizeof (png_charpp))); + png_memcpy(comp->output_ptr, old_ptr, old_max + * png_sizeof (png_charp)); + png_free(png_ptr, old_ptr); + } + else + comp->output_ptr = (png_charpp)png_malloc(png_ptr, + (png_uint_32)(comp->max_output_ptr * + png_sizeof (png_charp))); + } + + /* save the data */ + comp->output_ptr[comp->num_output_ptr] = (png_charp)png_malloc(png_ptr, + (png_uint_32)png_ptr->zbuf_size); + png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf, + png_ptr->zbuf_size); + comp->num_output_ptr++; + + /* and reset the buffer */ + png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; + png_ptr->zstream.next_out = png_ptr->zbuf; + } + /* continue until we don't have any more to compress */ + } while (png_ptr->zstream.avail_in); + + /* finish the compression */ + do + { + /* tell zlib we are finished */ + ret = deflate(&png_ptr->zstream, Z_FINISH); + + if (ret == Z_OK) + { + /* check to see if we need more room */ + if (!(png_ptr->zstream.avail_out)) + { + /* check to make sure our output array has room */ + if (comp->num_output_ptr >= comp->max_output_ptr) + { + int old_max; + + old_max = comp->max_output_ptr; + comp->max_output_ptr = comp->num_output_ptr + 4; + if (comp->output_ptr != NULL) + { + png_charpp old_ptr; + + old_ptr = comp->output_ptr; + /* This could be optimized to realloc() */ + comp->output_ptr = (png_charpp)png_malloc(png_ptr, + (png_uint_32)(comp->max_output_ptr * + png_sizeof (png_charpp))); + png_memcpy(comp->output_ptr, old_ptr, + old_max * png_sizeof (png_charp)); + png_free(png_ptr, old_ptr); + } + else + comp->output_ptr = (png_charpp)png_malloc(png_ptr, + (png_uint_32)(comp->max_output_ptr * + png_sizeof (png_charp))); + } + + /* save off the data */ + comp->output_ptr[comp->num_output_ptr] = + (png_charp)png_malloc(png_ptr, (png_uint_32)png_ptr->zbuf_size); + png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf, + png_ptr->zbuf_size); + comp->num_output_ptr++; + + /* and reset the buffer pointers */ + png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; + png_ptr->zstream.next_out = png_ptr->zbuf; + } + } + else if (ret != Z_STREAM_END) + { + /* we got an error */ + if (png_ptr->zstream.msg != NULL) + png_error(png_ptr, png_ptr->zstream.msg); + else + png_error(png_ptr, "zlib error"); + } + } while (ret != Z_STREAM_END); + + /* text length is number of buffers plus last buffer */ + text_len = png_ptr->zbuf_size * comp->num_output_ptr; + if (png_ptr->zstream.avail_out < png_ptr->zbuf_size) + text_len += png_ptr->zbuf_size - (png_size_t)png_ptr->zstream.avail_out; + + return((int)text_len); +} + +/* ship the compressed text out via chunk writes */ +static void /* PRIVATE */ +png_write_compressed_data_out(png_structp png_ptr, compression_state *comp) +{ + int i; + + /* handle the no-compression case */ + if (comp->input) + { + png_write_chunk_data(png_ptr, (png_bytep)comp->input, + (png_size_t)comp->input_len); + return; + } + + /* write saved output buffers, if any */ + for (i = 0; i < comp->num_output_ptr; i++) + { + png_write_chunk_data(png_ptr,(png_bytep)comp->output_ptr[i], + png_ptr->zbuf_size); + png_free(png_ptr, comp->output_ptr[i]); + comp->output_ptr[i]=NULL; + } + if (comp->max_output_ptr != 0) + png_free(png_ptr, comp->output_ptr); + comp->output_ptr=NULL; + /* write anything left in zbuf */ + if (png_ptr->zstream.avail_out < (png_uint_32)png_ptr->zbuf_size) + png_write_chunk_data(png_ptr, png_ptr->zbuf, + png_ptr->zbuf_size - png_ptr->zstream.avail_out); + + /* reset zlib for another zTXt/iTXt or image data */ + deflateReset(&png_ptr->zstream); + png_ptr->zstream.data_type = Z_BINARY; +} +#endif + +/* Write the IHDR chunk, and update the png_struct with the necessary + * information. Note that the rest of this code depends upon this + * information being correct. + */ +void /* PRIVATE */ +png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height, + int bit_depth, int color_type, int compression_type, int filter_type, + int interlace_type) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_IHDR; +#endif + png_byte buf[13]; /* buffer to store the IHDR info */ + + png_debug(1, "in png_write_IHDR\n"); + /* Check that we have valid input data from the application info */ + switch (color_type) + { + case PNG_COLOR_TYPE_GRAY: + switch (bit_depth) + { + case 1: + case 2: + case 4: + case 8: + case 16: png_ptr->channels = 1; break; + default: png_error(png_ptr,"Invalid bit depth for grayscale image"); + } + break; + case PNG_COLOR_TYPE_RGB: + if (bit_depth != 8 && bit_depth != 16) + png_error(png_ptr, "Invalid bit depth for RGB image"); + png_ptr->channels = 3; + break; + case PNG_COLOR_TYPE_PALETTE: + switch (bit_depth) + { + case 1: + case 2: + case 4: + case 8: png_ptr->channels = 1; break; + default: png_error(png_ptr, "Invalid bit depth for paletted image"); + } + break; + case PNG_COLOR_TYPE_GRAY_ALPHA: + if (bit_depth != 8 && bit_depth != 16) + png_error(png_ptr, "Invalid bit depth for grayscale+alpha image"); + png_ptr->channels = 2; + break; + case PNG_COLOR_TYPE_RGB_ALPHA: + if (bit_depth != 8 && bit_depth != 16) + png_error(png_ptr, "Invalid bit depth for RGBA image"); + png_ptr->channels = 4; + break; + default: + png_error(png_ptr, "Invalid image color type specified"); + } + + if (compression_type != PNG_COMPRESSION_TYPE_BASE) + { + png_warning(png_ptr, "Invalid compression type specified"); + compression_type = PNG_COMPRESSION_TYPE_BASE; + } + + /* Write filter_method 64 (intrapixel differencing) only if + * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and + * 2. Libpng did not write a PNG signature (this filter_method is only + * used in PNG datastreams that are embedded in MNG datastreams) and + * 3. The application called png_permit_mng_features with a mask that + * included PNG_FLAG_MNG_FILTER_64 and + * 4. The filter_method is 64 and + * 5. The color_type is RGB or RGBA + */ + if ( +#if defined(PNG_MNG_FEATURES_SUPPORTED) + !((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && + ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) == 0) && + (color_type == PNG_COLOR_TYPE_RGB || + color_type == PNG_COLOR_TYPE_RGB_ALPHA) && + (filter_type == PNG_INTRAPIXEL_DIFFERENCING)) && +#endif + filter_type != PNG_FILTER_TYPE_BASE) + { + png_warning(png_ptr, "Invalid filter type specified"); + filter_type = PNG_FILTER_TYPE_BASE; + } + +#ifdef PNG_WRITE_INTERLACING_SUPPORTED + if (interlace_type != PNG_INTERLACE_NONE && + interlace_type != PNG_INTERLACE_ADAM7) + { + png_warning(png_ptr, "Invalid interlace type specified"); + interlace_type = PNG_INTERLACE_ADAM7; + } +#else + interlace_type=PNG_INTERLACE_NONE; +#endif + + /* save off the relevent information */ + png_ptr->bit_depth = (png_byte)bit_depth; + png_ptr->color_type = (png_byte)color_type; + png_ptr->interlaced = (png_byte)interlace_type; +#if defined(PNG_MNG_FEATURES_SUPPORTED) + png_ptr->filter_type = (png_byte)filter_type; +#endif + png_ptr->compression_type = (png_byte)compression_type; + png_ptr->width = width; + png_ptr->height = height; + + png_ptr->pixel_depth = (png_byte)(bit_depth * png_ptr->channels); + png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, width); + /* set the usr info, so any transformations can modify it */ + png_ptr->usr_width = png_ptr->width; + png_ptr->usr_bit_depth = png_ptr->bit_depth; + png_ptr->usr_channels = png_ptr->channels; + + /* pack the header information into the buffer */ + png_save_uint_32(buf, width); + png_save_uint_32(buf + 4, height); + buf[8] = (png_byte)bit_depth; + buf[9] = (png_byte)color_type; + buf[10] = (png_byte)compression_type; + buf[11] = (png_byte)filter_type; + buf[12] = (png_byte)interlace_type; + + /* write the chunk */ + png_write_chunk(png_ptr, (png_bytep)png_IHDR, buf, (png_size_t)13); + + /* initialize zlib with PNG info */ + png_ptr->zstream.zalloc = png_zalloc; + png_ptr->zstream.zfree = png_zfree; + png_ptr->zstream.opaque = (voidpf)png_ptr; + if (!(png_ptr->do_filter)) + { + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE || + png_ptr->bit_depth < 8) + png_ptr->do_filter = PNG_FILTER_NONE; + else + png_ptr->do_filter = PNG_ALL_FILTERS; + } + if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_STRATEGY)) + { + if (png_ptr->do_filter != PNG_FILTER_NONE) + png_ptr->zlib_strategy = Z_FILTERED; + else + png_ptr->zlib_strategy = Z_DEFAULT_STRATEGY; + } + if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_LEVEL)) + png_ptr->zlib_level = Z_DEFAULT_COMPRESSION; + if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL)) + png_ptr->zlib_mem_level = 8; + if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS)) + png_ptr->zlib_window_bits = 15; + if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_METHOD)) + png_ptr->zlib_method = 8; + deflateInit2(&png_ptr->zstream, png_ptr->zlib_level, + png_ptr->zlib_method, png_ptr->zlib_window_bits, + png_ptr->zlib_mem_level, png_ptr->zlib_strategy); + png_ptr->zstream.next_out = png_ptr->zbuf; + png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; + /* libpng is not interested in zstream.data_type */ + /* set it to a predefined value, to avoid its evaluation inside zlib */ + png_ptr->zstream.data_type = Z_BINARY; + + png_ptr->mode = PNG_HAVE_IHDR; +} + +/* write the palette. We are careful not to trust png_color to be in the + * correct order for PNG, so people can redefine it to any convenient + * structure. + */ +void /* PRIVATE */ +png_write_PLTE(png_structp png_ptr, png_colorp palette, png_uint_32 num_pal) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_PLTE; +#endif + png_uint_32 i; + png_colorp pal_ptr; + png_byte buf[3]; + + png_debug(1, "in png_write_PLTE\n"); + if (( +#if defined(PNG_MNG_FEATURES_SUPPORTED) + !(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) && +#endif + num_pal == 0) || num_pal > 256) + { + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { + png_error(png_ptr, "Invalid number of colors in palette"); + } + else + { + png_warning(png_ptr, "Invalid number of colors in palette"); + return; + } + } + + if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR)) + { + png_warning(png_ptr, + "Ignoring request to write a PLTE chunk in grayscale PNG"); + return; + } + + png_ptr->num_palette = (png_uint_16)num_pal; + png_debug1(3, "num_palette = %d\n", png_ptr->num_palette); + + png_write_chunk_start(png_ptr, (png_bytep)png_PLTE, num_pal * 3); +#ifndef PNG_NO_POINTER_INDEXING + for (i = 0, pal_ptr = palette; i < num_pal; i++, pal_ptr++) + { + buf[0] = pal_ptr->red; + buf[1] = pal_ptr->green; + buf[2] = pal_ptr->blue; + png_write_chunk_data(png_ptr, buf, (png_size_t)3); + } +#else + /* This is a little slower but some buggy compilers need to do this instead */ + pal_ptr=palette; + for (i = 0; i < num_pal; i++) + { + buf[0] = pal_ptr[i].red; + buf[1] = pal_ptr[i].green; + buf[2] = pal_ptr[i].blue; + png_write_chunk_data(png_ptr, buf, (png_size_t)3); + } +#endif + png_write_chunk_end(png_ptr); + png_ptr->mode |= PNG_HAVE_PLTE; +} + +/* write an IDAT chunk */ +void /* PRIVATE */ +png_write_IDAT(png_structp png_ptr, png_bytep data, png_size_t length) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_IDAT; +#endif + png_debug(1, "in png_write_IDAT\n"); + + /* Optimize the CMF field in the zlib stream. */ + /* This hack of the zlib stream is compliant to the stream specification. */ + if (!(png_ptr->mode & PNG_HAVE_IDAT) && + png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE) + { + unsigned int z_cmf = data[0]; /* zlib compression method and flags */ + if ((z_cmf & 0x0f) == 8 && (z_cmf & 0xf0) <= 0x70) + { + /* Avoid memory underflows and multiplication overflows. */ + /* The conditions below are practically always satisfied; + however, they still must be checked. */ + if (length >= 2 && + png_ptr->height < 16384 && png_ptr->width < 16384) + { + png_uint_32 uncompressed_idat_size = png_ptr->height * + ((png_ptr->width * + png_ptr->channels * png_ptr->bit_depth + 15) >> 3); + unsigned int z_cinfo = z_cmf >> 4; + unsigned int half_z_window_size = 1 << (z_cinfo + 7); + while (uncompressed_idat_size <= half_z_window_size && + half_z_window_size >= 256) + { + z_cinfo--; + half_z_window_size >>= 1; + } + z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4); + if (data[0] != (png_byte)z_cmf) + { + data[0] = (png_byte)z_cmf; + data[1] &= 0xe0; + data[1] += (png_byte)(0x1f - ((z_cmf << 8) + data[1]) % 0x1f); + } + } + } + else + png_error(png_ptr, + "Invalid zlib compression method or flags in IDAT"); + } + + png_write_chunk(png_ptr, (png_bytep)png_IDAT, data, length); + png_ptr->mode |= PNG_HAVE_IDAT; +} + +/* write an IEND chunk */ +void /* PRIVATE */ +png_write_IEND(png_structp png_ptr) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_IEND; +#endif + png_debug(1, "in png_write_IEND\n"); + png_write_chunk(png_ptr, (png_bytep)png_IEND, png_bytep_NULL, + (png_size_t)0); + png_ptr->mode |= PNG_HAVE_IEND; +} + +#if defined(PNG_WRITE_gAMA_SUPPORTED) +/* write a gAMA chunk */ +#ifdef PNG_FLOATING_POINT_SUPPORTED +void /* PRIVATE */ +png_write_gAMA(png_structp png_ptr, double file_gamma) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_gAMA; +#endif + png_uint_32 igamma; + png_byte buf[4]; + + png_debug(1, "in png_write_gAMA\n"); + /* file_gamma is saved in 1/100,000ths */ + igamma = (png_uint_32)(file_gamma * 100000.0 + 0.5); + png_save_uint_32(buf, igamma); + png_write_chunk(png_ptr, (png_bytep)png_gAMA, buf, (png_size_t)4); +} +#endif +#ifdef PNG_FIXED_POINT_SUPPORTED +void /* PRIVATE */ +png_write_gAMA_fixed(png_structp png_ptr, png_fixed_point file_gamma) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_gAMA; +#endif + png_byte buf[4]; + + png_debug(1, "in png_write_gAMA\n"); + /* file_gamma is saved in 1/100,000ths */ + png_save_uint_32(buf, (png_uint_32)file_gamma); + png_write_chunk(png_ptr, (png_bytep)png_gAMA, buf, (png_size_t)4); +} +#endif +#endif + +#if defined(PNG_WRITE_sRGB_SUPPORTED) +/* write a sRGB chunk */ +void /* PRIVATE */ +png_write_sRGB(png_structp png_ptr, int srgb_intent) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_sRGB; +#endif + png_byte buf[1]; + + png_debug(1, "in png_write_sRGB\n"); + if(srgb_intent >= PNG_sRGB_INTENT_LAST) + png_warning(png_ptr, + "Invalid sRGB rendering intent specified"); + buf[0]=(png_byte)srgb_intent; + png_write_chunk(png_ptr, (png_bytep)png_sRGB, buf, (png_size_t)1); +} +#endif + +#if defined(PNG_WRITE_iCCP_SUPPORTED) +/* write an iCCP chunk */ +void /* PRIVATE */ +png_write_iCCP(png_structp png_ptr, png_charp name, int compression_type, + png_charp profile, int profile_len) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_iCCP; +#endif + png_size_t name_len; + png_charp new_name; + compression_state comp; + + png_debug(1, "in png_write_iCCP\n"); + + comp.num_output_ptr = 0; + comp.max_output_ptr = 0; + comp.output_ptr = NULL; + comp.input = NULL; + comp.input_len = 0; + + if (name == NULL || (name_len = png_check_keyword(png_ptr, name, + &new_name)) == 0) + { + png_warning(png_ptr, "Empty keyword in iCCP chunk"); + return; + } + + if (compression_type != PNG_COMPRESSION_TYPE_BASE) + png_warning(png_ptr, "Unknown compression type in iCCP chunk"); + + if (profile == NULL) + profile_len = 0; + + if (profile_len) + profile_len = png_text_compress(png_ptr, profile, (png_size_t)profile_len, + PNG_COMPRESSION_TYPE_BASE, &comp); + + /* make sure we include the NULL after the name and the compression type */ + png_write_chunk_start(png_ptr, (png_bytep)png_iCCP, + (png_uint_32)name_len+profile_len+2); + new_name[name_len+1]=0x00; + png_write_chunk_data(png_ptr, (png_bytep)new_name, name_len + 2); + + if (profile_len) + png_write_compressed_data_out(png_ptr, &comp); + + png_write_chunk_end(png_ptr); + png_free(png_ptr, new_name); +} +#endif + +#if defined(PNG_WRITE_sPLT_SUPPORTED) +/* write a sPLT chunk */ +void /* PRIVATE */ +png_write_sPLT(png_structp png_ptr, png_sPLT_tp spalette) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_sPLT; +#endif + png_size_t name_len; + png_charp new_name; + png_byte entrybuf[10]; + int entry_size = (spalette->depth == 8 ? 6 : 10); + int palette_size = entry_size * spalette->nentries; + png_sPLT_entryp ep; +#ifdef PNG_NO_POINTER_INDEXING + int i; +#endif + + png_debug(1, "in png_write_sPLT\n"); + if (spalette->name == NULL || (name_len = png_check_keyword(png_ptr, + spalette->name, &new_name))==0) + { + png_warning(png_ptr, "Empty keyword in sPLT chunk"); + return; + } + + /* make sure we include the NULL after the name */ + png_write_chunk_start(png_ptr, (png_bytep)png_sPLT, + (png_uint_32)(name_len + 2 + palette_size)); + png_write_chunk_data(png_ptr, (png_bytep)new_name, name_len + 1); + png_write_chunk_data(png_ptr, (png_bytep)&spalette->depth, 1); + + /* loop through each palette entry, writing appropriately */ +#ifndef PNG_NO_POINTER_INDEXING + for (ep = spalette->entries; ep<spalette->entries+spalette->nentries; ep++) + { + if (spalette->depth == 8) + { + entrybuf[0] = (png_byte)ep->red; + entrybuf[1] = (png_byte)ep->green; + entrybuf[2] = (png_byte)ep->blue; + entrybuf[3] = (png_byte)ep->alpha; + png_save_uint_16(entrybuf + 4, ep->frequency); + } + else + { + png_save_uint_16(entrybuf + 0, ep->red); + png_save_uint_16(entrybuf + 2, ep->green); + png_save_uint_16(entrybuf + 4, ep->blue); + png_save_uint_16(entrybuf + 6, ep->alpha); + png_save_uint_16(entrybuf + 8, ep->frequency); + } + png_write_chunk_data(png_ptr, entrybuf, (png_size_t)entry_size); + } +#else + ep=spalette->entries; + for (i=0; i>spalette->nentries; i++) + { + if (spalette->depth == 8) + { + entrybuf[0] = (png_byte)ep[i].red; + entrybuf[1] = (png_byte)ep[i].green; + entrybuf[2] = (png_byte)ep[i].blue; + entrybuf[3] = (png_byte)ep[i].alpha; + png_save_uint_16(entrybuf + 4, ep[i].frequency); + } + else + { + png_save_uint_16(entrybuf + 0, ep[i].red); + png_save_uint_16(entrybuf + 2, ep[i].green); + png_save_uint_16(entrybuf + 4, ep[i].blue); + png_save_uint_16(entrybuf + 6, ep[i].alpha); + png_save_uint_16(entrybuf + 8, ep[i].frequency); + } + png_write_chunk_data(png_ptr, entrybuf, entry_size); + } +#endif + + png_write_chunk_end(png_ptr); + png_free(png_ptr, new_name); +} +#endif + +#if defined(PNG_WRITE_sBIT_SUPPORTED) +/* write the sBIT chunk */ +void /* PRIVATE */ +png_write_sBIT(png_structp png_ptr, png_color_8p sbit, int color_type) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_sBIT; +#endif + png_byte buf[4]; + png_size_t size; + + png_debug(1, "in png_write_sBIT\n"); + /* make sure we don't depend upon the order of PNG_COLOR_8 */ + if (color_type & PNG_COLOR_MASK_COLOR) + { + png_byte maxbits; + + maxbits = (png_byte)(color_type==PNG_COLOR_TYPE_PALETTE ? 8 : + png_ptr->usr_bit_depth); + if (sbit->red == 0 || sbit->red > maxbits || + sbit->green == 0 || sbit->green > maxbits || + sbit->blue == 0 || sbit->blue > maxbits) + { + png_warning(png_ptr, "Invalid sBIT depth specified"); + return; + } + buf[0] = sbit->red; + buf[1] = sbit->green; + buf[2] = sbit->blue; + size = 3; + } + else + { + if (sbit->gray == 0 || sbit->gray > png_ptr->usr_bit_depth) + { + png_warning(png_ptr, "Invalid sBIT depth specified"); + return; + } + buf[0] = sbit->gray; + size = 1; + } + + if (color_type & PNG_COLOR_MASK_ALPHA) + { + if (sbit->alpha == 0 || sbit->alpha > png_ptr->usr_bit_depth) + { + png_warning(png_ptr, "Invalid sBIT depth specified"); + return; + } + buf[size++] = sbit->alpha; + } + + png_write_chunk(png_ptr, (png_bytep)png_sBIT, buf, size); +} +#endif + +#if defined(PNG_WRITE_cHRM_SUPPORTED) +/* write the cHRM chunk */ +#ifdef PNG_FLOATING_POINT_SUPPORTED +void /* PRIVATE */ +png_write_cHRM(png_structp png_ptr, double white_x, double white_y, + double red_x, double red_y, double green_x, double green_y, + double blue_x, double blue_y) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_cHRM; +#endif + png_byte buf[32]; + png_uint_32 itemp; + + png_debug(1, "in png_write_cHRM\n"); + /* each value is saved in 1/100,000ths */ + if (white_x < 0 || white_x > 0.8 || white_y < 0 || white_y > 0.8 || + white_x + white_y > 1.0) + { + png_warning(png_ptr, "Invalid cHRM white point specified"); +#if !defined(PNG_NO_CONSOLE_IO) + fprintf(stderr,"white_x=%f, white_y=%f\n",white_x, white_y); +#endif + return; + } + itemp = (png_uint_32)(white_x * 100000.0 + 0.5); + png_save_uint_32(buf, itemp); + itemp = (png_uint_32)(white_y * 100000.0 + 0.5); + png_save_uint_32(buf + 4, itemp); + + if (red_x < 0 || red_y < 0 || red_x + red_y > 1.0) + { + png_warning(png_ptr, "Invalid cHRM red point specified"); + return; + } + itemp = (png_uint_32)(red_x * 100000.0 + 0.5); + png_save_uint_32(buf + 8, itemp); + itemp = (png_uint_32)(red_y * 100000.0 + 0.5); + png_save_uint_32(buf + 12, itemp); + + if (green_x < 0 || green_y < 0 || green_x + green_y > 1.0) + { + png_warning(png_ptr, "Invalid cHRM green point specified"); + return; + } + itemp = (png_uint_32)(green_x * 100000.0 + 0.5); + png_save_uint_32(buf + 16, itemp); + itemp = (png_uint_32)(green_y * 100000.0 + 0.5); + png_save_uint_32(buf + 20, itemp); + + if (blue_x < 0 || blue_y < 0 || blue_x + blue_y > 1.0) + { + png_warning(png_ptr, "Invalid cHRM blue point specified"); + return; + } + itemp = (png_uint_32)(blue_x * 100000.0 + 0.5); + png_save_uint_32(buf + 24, itemp); + itemp = (png_uint_32)(blue_y * 100000.0 + 0.5); + png_save_uint_32(buf + 28, itemp); + + png_write_chunk(png_ptr, (png_bytep)png_cHRM, buf, (png_size_t)32); +} +#endif +#ifdef PNG_FIXED_POINT_SUPPORTED +void /* PRIVATE */ +png_write_cHRM_fixed(png_structp png_ptr, png_fixed_point white_x, + png_fixed_point white_y, png_fixed_point red_x, png_fixed_point red_y, + png_fixed_point green_x, png_fixed_point green_y, png_fixed_point blue_x, + png_fixed_point blue_y) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_cHRM; +#endif + png_byte buf[32]; + + png_debug(1, "in png_write_cHRM\n"); + /* each value is saved in 1/100,000ths */ + if (white_x > 80000L || white_y > 80000L || white_x + white_y > 100000L) + { + png_warning(png_ptr, "Invalid fixed cHRM white point specified"); +#if !defined(PNG_NO_CONSOLE_IO) + fprintf(stderr,"white_x=%ld, white_y=%ld\n",white_x, white_y); +#endif + return; + } + png_save_uint_32(buf, (png_uint_32)white_x); + png_save_uint_32(buf + 4, (png_uint_32)white_y); + + if (red_x + red_y > 100000L) + { + png_warning(png_ptr, "Invalid cHRM fixed red point specified"); + return; + } + png_save_uint_32(buf + 8, (png_uint_32)red_x); + png_save_uint_32(buf + 12, (png_uint_32)red_y); + + if (green_x + green_y > 100000L) + { + png_warning(png_ptr, "Invalid fixed cHRM green point specified"); + return; + } + png_save_uint_32(buf + 16, (png_uint_32)green_x); + png_save_uint_32(buf + 20, (png_uint_32)green_y); + + if (blue_x + blue_y > 100000L) + { + png_warning(png_ptr, "Invalid fixed cHRM blue point specified"); + return; + } + png_save_uint_32(buf + 24, (png_uint_32)blue_x); + png_save_uint_32(buf + 28, (png_uint_32)blue_y); + + png_write_chunk(png_ptr, (png_bytep)png_cHRM, buf, (png_size_t)32); +} +#endif +#endif + +#if defined(PNG_WRITE_tRNS_SUPPORTED) +/* write the tRNS chunk */ +void /* PRIVATE */ +png_write_tRNS(png_structp png_ptr, png_bytep trans, png_color_16p tran, + int num_trans, int color_type) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_tRNS; +#endif + png_byte buf[6]; + + png_debug(1, "in png_write_tRNS\n"); + if (color_type == PNG_COLOR_TYPE_PALETTE) + { + if (num_trans <= 0 || num_trans > (int)png_ptr->num_palette) + { + png_warning(png_ptr,"Invalid number of transparent colors specified"); + return; + } + /* write the chunk out as it is */ + png_write_chunk(png_ptr, (png_bytep)png_tRNS, trans, (png_size_t)num_trans); + } + else if (color_type == PNG_COLOR_TYPE_GRAY) + { + /* one 16 bit value */ + if(tran->gray >= (1 << png_ptr->bit_depth)) + { + png_warning(png_ptr, + "Ignoring attempt to write tRNS chunk out-of-range for bit_depth"); + return; + } + png_save_uint_16(buf, tran->gray); + png_write_chunk(png_ptr, (png_bytep)png_tRNS, buf, (png_size_t)2); + } + else if (color_type == PNG_COLOR_TYPE_RGB) + { + /* three 16 bit values */ + png_save_uint_16(buf, tran->red); + png_save_uint_16(buf + 2, tran->green); + png_save_uint_16(buf + 4, tran->blue); + if(png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4])) + { + png_warning(png_ptr, + "Ignoring attempt to write 16-bit tRNS chunk when bit_depth is 8"); + return; + } + png_write_chunk(png_ptr, (png_bytep)png_tRNS, buf, (png_size_t)6); + } + else + { + png_warning(png_ptr, "Can't write tRNS with an alpha channel"); + } +} +#endif + +#if defined(PNG_WRITE_bKGD_SUPPORTED) +/* write the background chunk */ +void /* PRIVATE */ +png_write_bKGD(png_structp png_ptr, png_color_16p back, int color_type) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_bKGD; +#endif + png_byte buf[6]; + + png_debug(1, "in png_write_bKGD\n"); + if (color_type == PNG_COLOR_TYPE_PALETTE) + { + if ( +#if defined(PNG_MNG_FEATURES_SUPPORTED) + (png_ptr->num_palette || + (!(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE))) && +#endif + back->index > png_ptr->num_palette) + { + png_warning(png_ptr, "Invalid background palette index"); + return; + } + buf[0] = back->index; + png_write_chunk(png_ptr, (png_bytep)png_bKGD, buf, (png_size_t)1); + } + else if (color_type & PNG_COLOR_MASK_COLOR) + { + png_save_uint_16(buf, back->red); + png_save_uint_16(buf + 2, back->green); + png_save_uint_16(buf + 4, back->blue); + if(png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4])) + { + png_warning(png_ptr, + "Ignoring attempt to write 16-bit bKGD chunk when bit_depth is 8"); + return; + } + png_write_chunk(png_ptr, (png_bytep)png_bKGD, buf, (png_size_t)6); + } + else + { + if(back->gray >= (1 << png_ptr->bit_depth)) + { + png_warning(png_ptr, + "Ignoring attempt to write bKGD chunk out-of-range for bit_depth"); + return; + } + png_save_uint_16(buf, back->gray); + png_write_chunk(png_ptr, (png_bytep)png_bKGD, buf, (png_size_t)2); + } +} +#endif + +#if defined(PNG_WRITE_hIST_SUPPORTED) +/* write the histogram */ +void /* PRIVATE */ +png_write_hIST(png_structp png_ptr, png_uint_16p hist, int num_hist) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_hIST; +#endif + int i; + png_byte buf[3]; + + png_debug(1, "in png_write_hIST\n"); + if (num_hist > (int)png_ptr->num_palette) + { + png_debug2(3, "num_hist = %d, num_palette = %d\n", num_hist, + png_ptr->num_palette); + png_warning(png_ptr, "Invalid number of histogram entries specified"); + return; + } + + png_write_chunk_start(png_ptr, (png_bytep)png_hIST, (png_uint_32)(num_hist * 2)); + for (i = 0; i < num_hist; i++) + { + png_save_uint_16(buf, hist[i]); + png_write_chunk_data(png_ptr, buf, (png_size_t)2); + } + png_write_chunk_end(png_ptr); +} +#endif + +#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \ + defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED) +/* Check that the tEXt or zTXt keyword is valid per PNG 1.0 specification, + * and if invalid, correct the keyword rather than discarding the entire + * chunk. The PNG 1.0 specification requires keywords 1-79 characters in + * length, forbids leading or trailing whitespace, multiple internal spaces, + * and the non-break space (0x80) from ISO 8859-1. Returns keyword length. + * + * The new_key is allocated to hold the corrected keyword and must be freed + * by the calling routine. This avoids problems with trying to write to + * static keywords without having to have duplicate copies of the strings. + */ +png_size_t /* PRIVATE */ +png_check_keyword(png_structp png_ptr, png_charp key, png_charpp new_key) +{ + png_size_t key_len; + png_charp kp, dp; + int kflag; + int kwarn=0; + + png_debug(1, "in png_check_keyword\n"); + *new_key = NULL; + + if (key == NULL || (key_len = png_strlen(key)) == 0) + { + png_warning(png_ptr, "zero length keyword"); + return ((png_size_t)0); + } + + png_debug1(2, "Keyword to be checked is '%s'\n", key); + + *new_key = (png_charp)png_malloc_warn(png_ptr, (png_uint_32)(key_len + 2)); + if (*new_key == NULL) + { + png_warning(png_ptr, "Out of memory while procesing keyword"); + return ((png_size_t)0); + } + + /* Replace non-printing characters with a blank and print a warning */ + for (kp = key, dp = *new_key; *kp != '\0'; kp++, dp++) + { + if (*kp < 0x20 || (*kp > 0x7E && (png_byte)*kp < 0xA1)) + { +#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE) + char msg[40]; + + sprintf(msg, "invalid keyword character 0x%02X", *kp); + png_warning(png_ptr, msg); +#else + png_warning(png_ptr, "invalid character in keyword"); +#endif + *dp = ' '; + } + else + { + *dp = *kp; + } + } + *dp = '\0'; + + /* Remove any trailing white space. */ + kp = *new_key + key_len - 1; + if (*kp == ' ') + { + png_warning(png_ptr, "trailing spaces removed from keyword"); + + while (*kp == ' ') + { + *(kp--) = '\0'; + key_len--; + } + } + + /* Remove any leading white space. */ + kp = *new_key; + if (*kp == ' ') + { + png_warning(png_ptr, "leading spaces removed from keyword"); + + while (*kp == ' ') + { + kp++; + key_len--; + } + } + + png_debug1(2, "Checking for multiple internal spaces in '%s'\n", kp); + + /* Remove multiple internal spaces. */ + for (kflag = 0, dp = *new_key; *kp != '\0'; kp++) + { + if (*kp == ' ' && kflag == 0) + { + *(dp++) = *kp; + kflag = 1; + } + else if (*kp == ' ') + { + key_len--; + kwarn=1; + } + else + { + *(dp++) = *kp; + kflag = 0; + } + } + *dp = '\0'; + if(kwarn) + png_warning(png_ptr, "extra interior spaces removed from keyword"); + + if (key_len == 0) + { + png_free(png_ptr, *new_key); + *new_key=NULL; + png_warning(png_ptr, "Zero length keyword"); + } + + if (key_len > 79) + { + png_warning(png_ptr, "keyword length must be 1 - 79 characters"); + new_key[79] = '\0'; + key_len = 79; + } + + return (key_len); +} +#endif + +#if defined(PNG_WRITE_tEXt_SUPPORTED) +/* write a tEXt chunk */ +void /* PRIVATE */ +png_write_tEXt(png_structp png_ptr, png_charp key, png_charp text, + png_size_t text_len) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_tEXt; +#endif + png_size_t key_len; + png_charp new_key; + + png_debug(1, "in png_write_tEXt\n"); + if (key == NULL || (key_len = png_check_keyword(png_ptr, key, &new_key))==0) + { + png_warning(png_ptr, "Empty keyword in tEXt chunk"); + return; + } + + if (text == NULL || *text == '\0') + text_len = 0; + else + text_len = png_strlen(text); + + /* make sure we include the 0 after the key */ + png_write_chunk_start(png_ptr, (png_bytep)png_tEXt, (png_uint_32)key_len+text_len+1); + /* + * We leave it to the application to meet PNG-1.0 requirements on the + * contents of the text. PNG-1.0 through PNG-1.2 discourage the use of + * any non-Latin-1 characters except for NEWLINE. ISO PNG will forbid them. + * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG. + */ + png_write_chunk_data(png_ptr, (png_bytep)new_key, key_len + 1); + if (text_len) + png_write_chunk_data(png_ptr, (png_bytep)text, text_len); + + png_write_chunk_end(png_ptr); + png_free(png_ptr, new_key); +} +#endif + +#if defined(PNG_WRITE_zTXt_SUPPORTED) +/* write a compressed text chunk */ +void /* PRIVATE */ +png_write_zTXt(png_structp png_ptr, png_charp key, png_charp text, + png_size_t text_len, int compression) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_zTXt; +#endif + png_size_t key_len; + char buf[1]; + png_charp new_key; + compression_state comp; + + png_debug(1, "in png_write_zTXt\n"); + + comp.num_output_ptr = 0; + comp.max_output_ptr = 0; + comp.output_ptr = NULL; + comp.input = NULL; + comp.input_len = 0; + + if (key == NULL || (key_len = png_check_keyword(png_ptr, key, &new_key))==0) + { + png_warning(png_ptr, "Empty keyword in zTXt chunk"); + return; + } + + if (text == NULL || *text == '\0' || compression==PNG_TEXT_COMPRESSION_NONE) + { + png_write_tEXt(png_ptr, new_key, text, (png_size_t)0); + png_free(png_ptr, new_key); + return; + } + + text_len = png_strlen(text); + + png_free(png_ptr, new_key); + + /* compute the compressed data; do it now for the length */ + text_len = png_text_compress(png_ptr, text, text_len, compression, + &comp); + + /* write start of chunk */ + png_write_chunk_start(png_ptr, (png_bytep)png_zTXt, (png_uint_32) + (key_len+text_len+2)); + /* write key */ + png_write_chunk_data(png_ptr, (png_bytep)key, key_len + 1); + buf[0] = (png_byte)compression; + /* write compression */ + png_write_chunk_data(png_ptr, (png_bytep)buf, (png_size_t)1); + /* write the compressed data */ + png_write_compressed_data_out(png_ptr, &comp); + + /* close the chunk */ + png_write_chunk_end(png_ptr); +} +#endif + +#if defined(PNG_WRITE_iTXt_SUPPORTED) +/* write an iTXt chunk */ +void /* PRIVATE */ +png_write_iTXt(png_structp png_ptr, int compression, png_charp key, + png_charp lang, png_charp lang_key, png_charp text) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_iTXt; +#endif + png_size_t lang_len, key_len, lang_key_len, text_len; + png_charp new_lang, new_key; + png_byte cbuf[2]; + compression_state comp; + + png_debug(1, "in png_write_iTXt\n"); + + comp.num_output_ptr = 0; + comp.max_output_ptr = 0; + comp.output_ptr = NULL; + comp.input = NULL; + + if (key == NULL || (key_len = png_check_keyword(png_ptr, key, &new_key))==0) + { + png_warning(png_ptr, "Empty keyword in iTXt chunk"); + return; + } + if (lang == NULL || (lang_len = png_check_keyword(png_ptr, lang, &new_lang))==0) + { + png_warning(png_ptr, "Empty language field in iTXt chunk"); + new_lang = NULL; + lang_len = 0; + } + + if (lang_key == NULL) + lang_key_len = 0; + else + lang_key_len = png_strlen(lang_key); + + if (text == NULL) + text_len = 0; + else + text_len = png_strlen(text); + + /* compute the compressed data; do it now for the length */ + text_len = png_text_compress(png_ptr, text, text_len, compression-2, + &comp); + + + /* make sure we include the compression flag, the compression byte, + * and the NULs after the key, lang, and lang_key parts */ + + png_write_chunk_start(png_ptr, (png_bytep)png_iTXt, + (png_uint_32)( + 5 /* comp byte, comp flag, terminators for key, lang and lang_key */ + + key_len + + lang_len + + lang_key_len + + text_len)); + + /* + * We leave it to the application to meet PNG-1.0 requirements on the + * contents of the text. PNG-1.0 through PNG-1.2 discourage the use of + * any non-Latin-1 characters except for NEWLINE. ISO PNG will forbid them. + * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG. + */ + png_write_chunk_data(png_ptr, (png_bytep)new_key, key_len + 1); + + /* set the compression flag */ + if (compression == PNG_ITXT_COMPRESSION_NONE || \ + compression == PNG_TEXT_COMPRESSION_NONE) + cbuf[0] = 0; + else /* compression == PNG_ITXT_COMPRESSION_zTXt */ + cbuf[0] = 1; + /* set the compression method */ + cbuf[1] = 0; + png_write_chunk_data(png_ptr, cbuf, 2); + + cbuf[0] = 0; + png_write_chunk_data(png_ptr, (new_lang ? (png_bytep)new_lang : cbuf), lang_len + 1); + png_write_chunk_data(png_ptr, (lang_key ? (png_bytep)lang_key : cbuf), lang_key_len + 1); + png_write_compressed_data_out(png_ptr, &comp); + + png_write_chunk_end(png_ptr); + png_free(png_ptr, new_key); + if (new_lang) + png_free(png_ptr, new_lang); +} +#endif + +#if defined(PNG_WRITE_oFFs_SUPPORTED) +/* write the oFFs chunk */ +void /* PRIVATE */ +png_write_oFFs(png_structp png_ptr, png_int_32 x_offset, png_int_32 y_offset, + int unit_type) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_oFFs; +#endif + png_byte buf[9]; + + png_debug(1, "in png_write_oFFs\n"); + if (unit_type >= PNG_OFFSET_LAST) + png_warning(png_ptr, "Unrecognized unit type for oFFs chunk"); + + png_save_int_32(buf, x_offset); + png_save_int_32(buf + 4, y_offset); + buf[8] = (png_byte)unit_type; + + png_write_chunk(png_ptr, (png_bytep)png_oFFs, buf, (png_size_t)9); +} +#endif + +#if defined(PNG_WRITE_pCAL_SUPPORTED) +/* write the pCAL chunk (described in the PNG extensions document) */ +void /* PRIVATE */ +png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0, + png_int_32 X1, int type, int nparams, png_charp units, png_charpp params) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_pCAL; +#endif + png_size_t purpose_len, units_len, total_len; + png_uint_32p params_len; + png_byte buf[10]; + png_charp new_purpose; + int i; + + png_debug1(1, "in png_write_pCAL (%d parameters)\n", nparams); + if (type >= PNG_EQUATION_LAST) + png_warning(png_ptr, "Unrecognized equation type for pCAL chunk"); + + purpose_len = png_check_keyword(png_ptr, purpose, &new_purpose) + 1; + png_debug1(3, "pCAL purpose length = %d\n", (int)purpose_len); + units_len = png_strlen(units) + (nparams == 0 ? 0 : 1); + png_debug1(3, "pCAL units length = %d\n", (int)units_len); + total_len = purpose_len + units_len + 10; + + params_len = (png_uint_32p)png_malloc(png_ptr, (png_uint_32)(nparams + *png_sizeof(png_uint_32))); + + /* Find the length of each parameter, making sure we don't count the + null terminator for the last parameter. */ + for (i = 0; i < nparams; i++) + { + params_len[i] = png_strlen(params[i]) + (i == nparams - 1 ? 0 : 1); + png_debug2(3, "pCAL parameter %d length = %lu\n", i, params_len[i]); + total_len += (png_size_t)params_len[i]; + } + + png_debug1(3, "pCAL total length = %d\n", (int)total_len); + png_write_chunk_start(png_ptr, (png_bytep)png_pCAL, (png_uint_32)total_len); + png_write_chunk_data(png_ptr, (png_bytep)new_purpose, purpose_len); + png_save_int_32(buf, X0); + png_save_int_32(buf + 4, X1); + buf[8] = (png_byte)type; + buf[9] = (png_byte)nparams; + png_write_chunk_data(png_ptr, buf, (png_size_t)10); + png_write_chunk_data(png_ptr, (png_bytep)units, (png_size_t)units_len); + + png_free(png_ptr, new_purpose); + + for (i = 0; i < nparams; i++) + { + png_write_chunk_data(png_ptr, (png_bytep)params[i], + (png_size_t)params_len[i]); + } + + png_free(png_ptr, params_len); + png_write_chunk_end(png_ptr); +} +#endif + +#if defined(PNG_WRITE_sCAL_SUPPORTED) +/* write the sCAL chunk */ +#if defined(PNG_FLOATING_POINT_SUPPORTED) && !defined(PNG_NO_STDIO) +void /* PRIVATE */ +png_write_sCAL(png_structp png_ptr, int unit, double width, double height) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_sCAL; +#endif + char buf[64]; + png_size_t total_len; + + png_debug(1, "in png_write_sCAL\n"); + + buf[0] = (char)unit; +#if defined(_WIN32_WCE) +/* sprintf() function is not supported on WindowsCE */ + { + wchar_t wc_buf[32]; + size_t wc_len; + swprintf(wc_buf, TEXT("%12.12e"), width); + wc_len = wcslen(wc_buf); + WideCharToMultiByte(CP_ACP, 0, wc_buf, -1, buf + 1, wc_len, NULL, NULL); + total_len = wc_len + 2; + swprintf(wc_buf, TEXT("%12.12e"), height); + wc_len = wcslen(wc_buf); + WideCharToMultiByte(CP_ACP, 0, wc_buf, -1, buf + total_len, wc_len, + NULL, NULL); + total_len += wc_len; + } +#else + sprintf(buf + 1, "%12.12e", width); + total_len = 1 + png_strlen(buf + 1) + 1; + sprintf(buf + total_len, "%12.12e", height); + total_len += png_strlen(buf + total_len); +#endif + + png_debug1(3, "sCAL total length = %u\n", (unsigned int)total_len); + png_write_chunk(png_ptr, (png_bytep)png_sCAL, (png_bytep)buf, total_len); +} +#else +#ifdef PNG_FIXED_POINT_SUPPORTED +void /* PRIVATE */ +png_write_sCAL_s(png_structp png_ptr, int unit, png_charp width, + png_charp height) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_sCAL; +#endif + png_byte buf[64]; + png_size_t wlen, hlen, total_len; + + png_debug(1, "in png_write_sCAL_s\n"); + + wlen = png_strlen(width); + hlen = png_strlen(height); + total_len = wlen + hlen + 2; + if (total_len > 64) + { + png_warning(png_ptr, "Can't write sCAL (buffer too small)"); + return; + } + + buf[0] = (png_byte)unit; + png_memcpy(buf + 1, width, wlen + 1); /* append the '\0' here */ + png_memcpy(buf + wlen + 2, height, hlen); /* do NOT append the '\0' here */ + + png_debug1(3, "sCAL total length = %u\n", (unsigned int)total_len); + png_write_chunk(png_ptr, (png_bytep)png_sCAL, buf, total_len); +} +#endif +#endif +#endif + +#if defined(PNG_WRITE_pHYs_SUPPORTED) +/* write the pHYs chunk */ +void /* PRIVATE */ +png_write_pHYs(png_structp png_ptr, png_uint_32 x_pixels_per_unit, + png_uint_32 y_pixels_per_unit, + int unit_type) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_pHYs; +#endif + png_byte buf[9]; + + png_debug(1, "in png_write_pHYs\n"); + if (unit_type >= PNG_RESOLUTION_LAST) + png_warning(png_ptr, "Unrecognized unit type for pHYs chunk"); + + png_save_uint_32(buf, x_pixels_per_unit); + png_save_uint_32(buf + 4, y_pixels_per_unit); + buf[8] = (png_byte)unit_type; + + png_write_chunk(png_ptr, (png_bytep)png_pHYs, buf, (png_size_t)9); +} +#endif + +#if defined(PNG_WRITE_tIME_SUPPORTED) +/* Write the tIME chunk. Use either png_convert_from_struct_tm() + * or png_convert_from_time_t(), or fill in the structure yourself. + */ +void /* PRIVATE */ +png_write_tIME(png_structp png_ptr, png_timep mod_time) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_tIME; +#endif + png_byte buf[7]; + + png_debug(1, "in png_write_tIME\n"); + if (mod_time->month > 12 || mod_time->month < 1 || + mod_time->day > 31 || mod_time->day < 1 || + mod_time->hour > 23 || mod_time->second > 60) + { + png_warning(png_ptr, "Invalid time specified for tIME chunk"); + return; + } + + png_save_uint_16(buf, mod_time->year); + buf[2] = mod_time->month; + buf[3] = mod_time->day; + buf[4] = mod_time->hour; + buf[5] = mod_time->minute; + buf[6] = mod_time->second; + + png_write_chunk(png_ptr, (png_bytep)png_tIME, buf, (png_size_t)7); +} +#endif + +/* initializes the row writing capability of libpng */ +void /* PRIVATE */ +png_write_start_row(png_structp png_ptr) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */ + + /* start of interlace block */ + int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; + + /* offset to next interlace block */ + int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + + /* start of interlace block in the y direction */ + int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; + + /* offset to next interlace block in the y direction */ + int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; +#endif + + png_size_t buf_size; + + png_debug(1, "in png_write_start_row\n"); + buf_size = (png_size_t)(PNG_ROWBYTES( + png_ptr->usr_channels*png_ptr->usr_bit_depth,png_ptr->width)+1); + + /* set up row buffer */ + png_ptr->row_buf = (png_bytep)png_malloc(png_ptr, (png_uint_32)buf_size); + png_ptr->row_buf[0] = PNG_FILTER_VALUE_NONE; + + /* set up filtering buffer, if using this filter */ + if (png_ptr->do_filter & PNG_FILTER_SUB) + { + png_ptr->sub_row = (png_bytep)png_malloc(png_ptr, + (png_ptr->rowbytes + 1)); + png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB; + } + + /* We only need to keep the previous row if we are using one of these. */ + if (png_ptr->do_filter & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH)) + { + /* set up previous row buffer */ + png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)buf_size); + png_memset(png_ptr->prev_row, 0, buf_size); + + if (png_ptr->do_filter & PNG_FILTER_UP) + { + png_ptr->up_row = (png_bytep )png_malloc(png_ptr, + (png_ptr->rowbytes + 1)); + png_ptr->up_row[0] = PNG_FILTER_VALUE_UP; + } + + if (png_ptr->do_filter & PNG_FILTER_AVG) + { + png_ptr->avg_row = (png_bytep)png_malloc(png_ptr, + (png_ptr->rowbytes + 1)); + png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG; + } + + if (png_ptr->do_filter & PNG_FILTER_PAETH) + { + png_ptr->paeth_row = (png_bytep )png_malloc(png_ptr, + (png_ptr->rowbytes + 1)); + png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH; + } + } + +#ifdef PNG_WRITE_INTERLACING_SUPPORTED + /* if interlaced, we need to set up width and height of pass */ + if (png_ptr->interlaced) + { + if (!(png_ptr->transformations & PNG_INTERLACE)) + { + png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 - + png_pass_ystart[0]) / png_pass_yinc[0]; + png_ptr->usr_width = (png_ptr->width + png_pass_inc[0] - 1 - + png_pass_start[0]) / png_pass_inc[0]; + } + else + { + png_ptr->num_rows = png_ptr->height; + png_ptr->usr_width = png_ptr->width; + } + } + else +#endif + { + png_ptr->num_rows = png_ptr->height; + png_ptr->usr_width = png_ptr->width; + } + png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; + png_ptr->zstream.next_out = png_ptr->zbuf; +} + +/* Internal use only. Called when finished processing a row of data. */ +void /* PRIVATE */ +png_write_finish_row(png_structp png_ptr) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */ + + /* start of interlace block */ + int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; + + /* offset to next interlace block */ + int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + + /* start of interlace block in the y direction */ + int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; + + /* offset to next interlace block in the y direction */ + int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; +#endif + + int ret; + + png_debug(1, "in png_write_finish_row\n"); + /* next row */ + png_ptr->row_number++; + + /* see if we are done */ + if (png_ptr->row_number < png_ptr->num_rows) + return; + +#ifdef PNG_WRITE_INTERLACING_SUPPORTED + /* if interlaced, go to next pass */ + if (png_ptr->interlaced) + { + png_ptr->row_number = 0; + if (png_ptr->transformations & PNG_INTERLACE) + { + png_ptr->pass++; + } + else + { + /* loop until we find a non-zero width or height pass */ + do + { + png_ptr->pass++; + if (png_ptr->pass >= 7) + break; + png_ptr->usr_width = (png_ptr->width + + png_pass_inc[png_ptr->pass] - 1 - + png_pass_start[png_ptr->pass]) / + png_pass_inc[png_ptr->pass]; + png_ptr->num_rows = (png_ptr->height + + png_pass_yinc[png_ptr->pass] - 1 - + png_pass_ystart[png_ptr->pass]) / + png_pass_yinc[png_ptr->pass]; + if (png_ptr->transformations & PNG_INTERLACE) + break; + } while (png_ptr->usr_width == 0 || png_ptr->num_rows == 0); + + } + + /* reset the row above the image for the next pass */ + if (png_ptr->pass < 7) + { + if (png_ptr->prev_row != NULL) + png_memset(png_ptr->prev_row, 0, + (png_size_t)(PNG_ROWBYTES(png_ptr->usr_channels* + png_ptr->usr_bit_depth,png_ptr->width))+1); + return; + } + } +#endif + + /* if we get here, we've just written the last row, so we need + to flush the compressor */ + do + { + /* tell the compressor we are done */ + ret = deflate(&png_ptr->zstream, Z_FINISH); + /* check for an error */ + if (ret == Z_OK) + { + /* check to see if we need more room */ + if (!(png_ptr->zstream.avail_out)) + { + png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size); + png_ptr->zstream.next_out = png_ptr->zbuf; + png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; + } + } + else if (ret != Z_STREAM_END) + { + if (png_ptr->zstream.msg != NULL) + png_error(png_ptr, png_ptr->zstream.msg); + else + png_error(png_ptr, "zlib error"); + } + } while (ret != Z_STREAM_END); + + /* write any extra space */ + if (png_ptr->zstream.avail_out < png_ptr->zbuf_size) + { + png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size - + png_ptr->zstream.avail_out); + } + + deflateReset(&png_ptr->zstream); + png_ptr->zstream.data_type = Z_BINARY; +} + +#if defined(PNG_WRITE_INTERLACING_SUPPORTED) +/* Pick out the correct pixels for the interlace pass. + * The basic idea here is to go through the row with a source + * pointer and a destination pointer (sp and dp), and copy the + * correct pixels for the pass. As the row gets compacted, + * sp will always be >= dp, so we should never overwrite anything. + * See the default: case for the easiest code to understand. + */ +void /* PRIVATE */ +png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */ + + /* start of interlace block */ + int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; + + /* offset to next interlace block */ + int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; +#endif + + png_debug(1, "in png_do_write_interlace\n"); + /* we don't have to do anything on the last pass (6) */ +#if defined(PNG_USELESS_TESTS_SUPPORTED) + if (row != NULL && row_info != NULL && pass < 6) +#else + if (pass < 6) +#endif + { + /* each pixel depth is handled separately */ + switch (row_info->pixel_depth) + { + case 1: + { + png_bytep sp; + png_bytep dp; + int shift; + int d; + int value; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + dp = row; + d = 0; + shift = 7; + for (i = png_pass_start[pass]; i < row_width; + i += png_pass_inc[pass]) + { + sp = row + (png_size_t)(i >> 3); + value = (int)(*sp >> (7 - (int)(i & 0x07))) & 0x01; + d |= (value << shift); + + if (shift == 0) + { + shift = 7; + *dp++ = (png_byte)d; + d = 0; + } + else + shift--; + + } + if (shift != 7) + *dp = (png_byte)d; + break; + } + case 2: + { + png_bytep sp; + png_bytep dp; + int shift; + int d; + int value; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + dp = row; + shift = 6; + d = 0; + for (i = png_pass_start[pass]; i < row_width; + i += png_pass_inc[pass]) + { + sp = row + (png_size_t)(i >> 2); + value = (*sp >> ((3 - (int)(i & 0x03)) << 1)) & 0x03; + d |= (value << shift); + + if (shift == 0) + { + shift = 6; + *dp++ = (png_byte)d; + d = 0; + } + else + shift -= 2; + } + if (shift != 6) + *dp = (png_byte)d; + break; + } + case 4: + { + png_bytep sp; + png_bytep dp; + int shift; + int d; + int value; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + dp = row; + shift = 4; + d = 0; + for (i = png_pass_start[pass]; i < row_width; + i += png_pass_inc[pass]) + { + sp = row + (png_size_t)(i >> 1); + value = (*sp >> ((1 - (int)(i & 0x01)) << 2)) & 0x0f; + d |= (value << shift); + + if (shift == 0) + { + shift = 4; + *dp++ = (png_byte)d; + d = 0; + } + else + shift -= 4; + } + if (shift != 4) + *dp = (png_byte)d; + break; + } + default: + { + png_bytep sp; + png_bytep dp; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + png_size_t pixel_bytes; + + /* start at the beginning */ + dp = row; + /* find out how many bytes each pixel takes up */ + pixel_bytes = (row_info->pixel_depth >> 3); + /* loop through the row, only looking at the pixels that + matter */ + for (i = png_pass_start[pass]; i < row_width; + i += png_pass_inc[pass]) + { + /* find out where the original pixel is */ + sp = row + (png_size_t)i * pixel_bytes; + /* move the pixel */ + if (dp != sp) + png_memcpy(dp, sp, pixel_bytes); + /* next pixel */ + dp += pixel_bytes; + } + break; + } + } + /* set new row width */ + row_info->width = (row_info->width + + png_pass_inc[pass] - 1 - + png_pass_start[pass]) / + png_pass_inc[pass]; + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, + row_info->width); + } +} +#endif + +/* This filters the row, chooses which filter to use, if it has not already + * been specified by the application, and then writes the row out with the + * chosen filter. + */ +#define PNG_MAXSUM (((png_uint_32)(-1)) >> 1) +#define PNG_HISHIFT 10 +#define PNG_LOMASK ((png_uint_32)0xffffL) +#define PNG_HIMASK ((png_uint_32)(~PNG_LOMASK >> PNG_HISHIFT)) +void /* PRIVATE */ +png_write_find_filter(png_structp png_ptr, png_row_infop row_info) +{ + png_bytep prev_row, best_row, row_buf; + png_uint_32 mins, bpp; + png_byte filter_to_do = png_ptr->do_filter; + png_uint_32 row_bytes = row_info->rowbytes; +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) + int num_p_filters = (int)png_ptr->num_prev_filters; +#endif + + png_debug(1, "in png_write_find_filter\n"); + /* find out how many bytes offset each pixel is */ + bpp = (row_info->pixel_depth + 7) >> 3; + + prev_row = png_ptr->prev_row; + best_row = row_buf = png_ptr->row_buf; + mins = PNG_MAXSUM; + + /* The prediction method we use is to find which method provides the + * smallest value when summing the absolute values of the distances + * from zero, using anything >= 128 as negative numbers. This is known + * as the "minimum sum of absolute differences" heuristic. Other + * heuristics are the "weighted minimum sum of absolute differences" + * (experimental and can in theory improve compression), and the "zlib + * predictive" method (not implemented yet), which does test compressions + * of lines using different filter methods, and then chooses the + * (series of) filter(s) that give minimum compressed data size (VERY + * computationally expensive). + * + * GRR 980525: consider also + * (1) minimum sum of absolute differences from running average (i.e., + * keep running sum of non-absolute differences & count of bytes) + * [track dispersion, too? restart average if dispersion too large?] + * (1b) minimum sum of absolute differences from sliding average, probably + * with window size <= deflate window (usually 32K) + * (2) minimum sum of squared differences from zero or running average + * (i.e., ~ root-mean-square approach) + */ + + + /* We don't need to test the 'no filter' case if this is the only filter + * that has been chosen, as it doesn't actually do anything to the data. + */ + if ((filter_to_do & PNG_FILTER_NONE) && + filter_to_do != PNG_FILTER_NONE) + { + png_bytep rp; + png_uint_32 sum = 0; + png_uint_32 i; + int v; + + for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++) + { + v = *rp; + sum += (v < 128) ? v : 256 - v; + } + +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) + if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) + { + png_uint_32 sumhi, sumlo; + int j; + sumlo = sum & PNG_LOMASK; + sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; /* Gives us some footroom */ + + /* Reduce the sum if we match any of the previous rows */ + for (j = 0; j < num_p_filters; j++) + { + if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE) + { + sumlo = (sumlo * png_ptr->filter_weights[j]) >> + PNG_WEIGHT_SHIFT; + sumhi = (sumhi * png_ptr->filter_weights[j]) >> + PNG_WEIGHT_SHIFT; + } + } + + /* Factor in the cost of this filter (this is here for completeness, + * but it makes no sense to have a "cost" for the NONE filter, as + * it has the minimum possible computational cost - none). + */ + sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >> + PNG_COST_SHIFT; + sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >> + PNG_COST_SHIFT; + + if (sumhi > PNG_HIMASK) + sum = PNG_MAXSUM; + else + sum = (sumhi << PNG_HISHIFT) + sumlo; + } +#endif + mins = sum; + } + + /* sub filter */ + if (filter_to_do == PNG_FILTER_SUB) + /* it's the only filter so no testing is needed */ + { + png_bytep rp, lp, dp; + png_uint_32 i; + for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp; + i++, rp++, dp++) + { + *dp = *rp; + } + for (lp = row_buf + 1; i < row_bytes; + i++, rp++, lp++, dp++) + { + *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff); + } + best_row = png_ptr->sub_row; + } + + else if (filter_to_do & PNG_FILTER_SUB) + { + png_bytep rp, dp, lp; + png_uint_32 sum = 0, lmins = mins; + png_uint_32 i; + int v; + +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) + /* We temporarily increase the "minimum sum" by the factor we + * would reduce the sum of this filter, so that we can do the + * early exit comparison without scaling the sum each time. + */ + if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) + { + int j; + png_uint_32 lmhi, lmlo; + lmlo = lmins & PNG_LOMASK; + lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK; + + for (j = 0; j < num_p_filters; j++) + { + if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB) + { + lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >> + PNG_WEIGHT_SHIFT; + lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >> + PNG_WEIGHT_SHIFT; + } + } + + lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >> + PNG_COST_SHIFT; + lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >> + PNG_COST_SHIFT; + + if (lmhi > PNG_HIMASK) + lmins = PNG_MAXSUM; + else + lmins = (lmhi << PNG_HISHIFT) + lmlo; + } +#endif + + for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp; + i++, rp++, dp++) + { + v = *dp = *rp; + + sum += (v < 128) ? v : 256 - v; + } + for (lp = row_buf + 1; i < row_bytes; + i++, rp++, lp++, dp++) + { + v = *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff); + + sum += (v < 128) ? v : 256 - v; + + if (sum > lmins) /* We are already worse, don't continue. */ + break; + } + +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) + if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) + { + int j; + png_uint_32 sumhi, sumlo; + sumlo = sum & PNG_LOMASK; + sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; + + for (j = 0; j < num_p_filters; j++) + { + if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB) + { + sumlo = (sumlo * png_ptr->inv_filter_weights[j]) >> + PNG_WEIGHT_SHIFT; + sumhi = (sumhi * png_ptr->inv_filter_weights[j]) >> + PNG_WEIGHT_SHIFT; + } + } + + sumlo = (sumlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >> + PNG_COST_SHIFT; + sumhi = (sumhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >> + PNG_COST_SHIFT; + + if (sumhi > PNG_HIMASK) + sum = PNG_MAXSUM; + else + sum = (sumhi << PNG_HISHIFT) + sumlo; + } +#endif + + if (sum < mins) + { + mins = sum; + best_row = png_ptr->sub_row; + } + } + + /* up filter */ + if (filter_to_do == PNG_FILTER_UP) + { + png_bytep rp, dp, pp; + png_uint_32 i; + + for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1, + pp = prev_row + 1; i < row_bytes; + i++, rp++, pp++, dp++) + { + *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff); + } + best_row = png_ptr->up_row; + } + + else if (filter_to_do & PNG_FILTER_UP) + { + png_bytep rp, dp, pp; + png_uint_32 sum = 0, lmins = mins; + png_uint_32 i; + int v; + + +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) + if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) + { + int j; + png_uint_32 lmhi, lmlo; + lmlo = lmins & PNG_LOMASK; + lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK; + + for (j = 0; j < num_p_filters; j++) + { + if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP) + { + lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >> + PNG_WEIGHT_SHIFT; + lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >> + PNG_WEIGHT_SHIFT; + } + } + + lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >> + PNG_COST_SHIFT; + lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >> + PNG_COST_SHIFT; + + if (lmhi > PNG_HIMASK) + lmins = PNG_MAXSUM; + else + lmins = (lmhi << PNG_HISHIFT) + lmlo; + } +#endif + + for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1, + pp = prev_row + 1; i < row_bytes; i++) + { + v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff); + + sum += (v < 128) ? v : 256 - v; + + if (sum > lmins) /* We are already worse, don't continue. */ + break; + } + +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) + if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) + { + int j; + png_uint_32 sumhi, sumlo; + sumlo = sum & PNG_LOMASK; + sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; + + for (j = 0; j < num_p_filters; j++) + { + if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP) + { + sumlo = (sumlo * png_ptr->filter_weights[j]) >> + PNG_WEIGHT_SHIFT; + sumhi = (sumhi * png_ptr->filter_weights[j]) >> + PNG_WEIGHT_SHIFT; + } + } + + sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >> + PNG_COST_SHIFT; + sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >> + PNG_COST_SHIFT; + + if (sumhi > PNG_HIMASK) + sum = PNG_MAXSUM; + else + sum = (sumhi << PNG_HISHIFT) + sumlo; + } +#endif + + if (sum < mins) + { + mins = sum; + best_row = png_ptr->up_row; + } + } + + /* avg filter */ + if (filter_to_do == PNG_FILTER_AVG) + { + png_bytep rp, dp, pp, lp; + png_uint_32 i; + for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1, + pp = prev_row + 1; i < bpp; i++) + { + *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff); + } + for (lp = row_buf + 1; i < row_bytes; i++) + { + *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2)) + & 0xff); + } + best_row = png_ptr->avg_row; + } + + else if (filter_to_do & PNG_FILTER_AVG) + { + png_bytep rp, dp, pp, lp; + png_uint_32 sum = 0, lmins = mins; + png_uint_32 i; + int v; + +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) + if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) + { + int j; + png_uint_32 lmhi, lmlo; + lmlo = lmins & PNG_LOMASK; + lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK; + + for (j = 0; j < num_p_filters; j++) + { + if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_AVG) + { + lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >> + PNG_WEIGHT_SHIFT; + lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >> + PNG_WEIGHT_SHIFT; + } + } + + lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >> + PNG_COST_SHIFT; + lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >> + PNG_COST_SHIFT; + + if (lmhi > PNG_HIMASK) + lmins = PNG_MAXSUM; + else + lmins = (lmhi << PNG_HISHIFT) + lmlo; + } +#endif + + for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1, + pp = prev_row + 1; i < bpp; i++) + { + v = *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff); + + sum += (v < 128) ? v : 256 - v; + } + for (lp = row_buf + 1; i < row_bytes; i++) + { + v = *dp++ = + (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2)) & 0xff); + + sum += (v < 128) ? v : 256 - v; + + if (sum > lmins) /* We are already worse, don't continue. */ + break; + } + +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) + if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) + { + int j; + png_uint_32 sumhi, sumlo; + sumlo = sum & PNG_LOMASK; + sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; + + for (j = 0; j < num_p_filters; j++) + { + if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE) + { + sumlo = (sumlo * png_ptr->filter_weights[j]) >> + PNG_WEIGHT_SHIFT; + sumhi = (sumhi * png_ptr->filter_weights[j]) >> + PNG_WEIGHT_SHIFT; + } + } + + sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >> + PNG_COST_SHIFT; + sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >> + PNG_COST_SHIFT; + + if (sumhi > PNG_HIMASK) + sum = PNG_MAXSUM; + else + sum = (sumhi << PNG_HISHIFT) + sumlo; + } +#endif + + if (sum < mins) + { + mins = sum; + best_row = png_ptr->avg_row; + } + } + + /* Paeth filter */ + if (filter_to_do == PNG_FILTER_PAETH) + { + png_bytep rp, dp, pp, cp, lp; + png_uint_32 i; + for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1, + pp = prev_row + 1; i < bpp; i++) + { + *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff); + } + + for (lp = row_buf + 1, cp = prev_row + 1; i < row_bytes; i++) + { + int a, b, c, pa, pb, pc, p; + + b = *pp++; + c = *cp++; + a = *lp++; + + p = b - c; + pc = a - c; + +#ifdef PNG_USE_ABS + pa = abs(p); + pb = abs(pc); + pc = abs(p + pc); +#else + pa = p < 0 ? -p : p; + pb = pc < 0 ? -pc : pc; + pc = (p + pc) < 0 ? -(p + pc) : p + pc; +#endif + + p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c; + + *dp++ = (png_byte)(((int)*rp++ - p) & 0xff); + } + best_row = png_ptr->paeth_row; + } + + else if (filter_to_do & PNG_FILTER_PAETH) + { + png_bytep rp, dp, pp, cp, lp; + png_uint_32 sum = 0, lmins = mins; + png_uint_32 i; + int v; + +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) + if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) + { + int j; + png_uint_32 lmhi, lmlo; + lmlo = lmins & PNG_LOMASK; + lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK; + + for (j = 0; j < num_p_filters; j++) + { + if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH) + { + lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >> + PNG_WEIGHT_SHIFT; + lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >> + PNG_WEIGHT_SHIFT; + } + } + + lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >> + PNG_COST_SHIFT; + lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >> + PNG_COST_SHIFT; + + if (lmhi > PNG_HIMASK) + lmins = PNG_MAXSUM; + else + lmins = (lmhi << PNG_HISHIFT) + lmlo; + } +#endif + + for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1, + pp = prev_row + 1; i < bpp; i++) + { + v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff); + + sum += (v < 128) ? v : 256 - v; + } + + for (lp = row_buf + 1, cp = prev_row + 1; i < row_bytes; i++) + { + int a, b, c, pa, pb, pc, p; + + b = *pp++; + c = *cp++; + a = *lp++; + +#ifndef PNG_SLOW_PAETH + p = b - c; + pc = a - c; +#ifdef PNG_USE_ABS + pa = abs(p); + pb = abs(pc); + pc = abs(p + pc); +#else + pa = p < 0 ? -p : p; + pb = pc < 0 ? -pc : pc; + pc = (p + pc) < 0 ? -(p + pc) : p + pc; +#endif + p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c; +#else /* PNG_SLOW_PAETH */ + p = a + b - c; + pa = abs(p - a); + pb = abs(p - b); + pc = abs(p - c); + if (pa <= pb && pa <= pc) + p = a; + else if (pb <= pc) + p = b; + else + p = c; +#endif /* PNG_SLOW_PAETH */ + + v = *dp++ = (png_byte)(((int)*rp++ - p) & 0xff); + + sum += (v < 128) ? v : 256 - v; + + if (sum > lmins) /* We are already worse, don't continue. */ + break; + } + +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) + if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) + { + int j; + png_uint_32 sumhi, sumlo; + sumlo = sum & PNG_LOMASK; + sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; + + for (j = 0; j < num_p_filters; j++) + { + if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH) + { + sumlo = (sumlo * png_ptr->filter_weights[j]) >> + PNG_WEIGHT_SHIFT; + sumhi = (sumhi * png_ptr->filter_weights[j]) >> + PNG_WEIGHT_SHIFT; + } + } + + sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >> + PNG_COST_SHIFT; + sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >> + PNG_COST_SHIFT; + + if (sumhi > PNG_HIMASK) + sum = PNG_MAXSUM; + else + sum = (sumhi << PNG_HISHIFT) + sumlo; + } +#endif + + if (sum < mins) + { + best_row = png_ptr->paeth_row; + } + } + + /* Do the actual writing of the filtered row data from the chosen filter. */ + + png_write_filtered_row(png_ptr, best_row); + +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) + /* Save the type of filter we picked this time for future calculations */ + if (png_ptr->num_prev_filters > 0) + { + int j; + for (j = 1; j < num_p_filters; j++) + { + png_ptr->prev_filters[j] = png_ptr->prev_filters[j - 1]; + } + png_ptr->prev_filters[j] = best_row[0]; + } +#endif +} + + +/* Do the actual writing of a previously filtered row. */ +void /* PRIVATE */ +png_write_filtered_row(png_structp png_ptr, png_bytep filtered_row) +{ + png_debug(1, "in png_write_filtered_row\n"); + png_debug1(2, "filter = %d\n", filtered_row[0]); + /* set up the zlib input buffer */ + + png_ptr->zstream.next_in = filtered_row; + png_ptr->zstream.avail_in = (uInt)png_ptr->row_info.rowbytes + 1; + /* repeat until we have compressed all the data */ + do + { + int ret; /* return of zlib */ + + /* compress the data */ + ret = deflate(&png_ptr->zstream, Z_NO_FLUSH); + /* check for compression errors */ + if (ret != Z_OK) + { + if (png_ptr->zstream.msg != NULL) + png_error(png_ptr, png_ptr->zstream.msg); + else + png_error(png_ptr, "zlib error"); + } + + /* see if it is time to write another IDAT */ + if (!(png_ptr->zstream.avail_out)) + { + /* write the IDAT and reset the zlib output buffer */ + png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size); + png_ptr->zstream.next_out = png_ptr->zbuf; + png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; + } + /* repeat until all data has been compressed */ + } while (png_ptr->zstream.avail_in); + + /* swap the current and previous rows */ + if (png_ptr->prev_row != NULL) + { + png_bytep tptr; + + tptr = png_ptr->prev_row; + png_ptr->prev_row = png_ptr->row_buf; + png_ptr->row_buf = tptr; + } + + /* finish row - updates counters and flushes zlib if last row */ + png_write_finish_row(png_ptr); + +#if defined(PNG_WRITE_FLUSH_SUPPORTED) + png_ptr->flush_rows++; + + if (png_ptr->flush_dist > 0 && + png_ptr->flush_rows >= png_ptr->flush_dist) + { + png_write_flush(png_ptr); + } +#endif +} +#endif /* PNG_WRITE_SUPPORTED */ diff --git a/mod/pub.mod/lua.mod/doc/Lua-Logo_32x32.png b/mod/pub.mod/lua.mod/doc/Lua-Logo_32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..486508d3365df146fb76a7fe0afc2bfd82db45ef GIT binary patch literal 1856 zcmV-G2fz4<P)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800006VoOIv00000 z008+zyMF)x010qNS#tmY009610096`CB)VM000McNliru*8~a<Iv`Dp6DR-x2F*!C zK~#90otIf`T-6!Je|P52jAylH>>2N4Cox&Zc1RpVnkH^jiI$|~g%E)R=?j7iQK_^q zjX;R1JXE|O!5gAdg?MSeifTmEicM`$(@G{GL5v+c3Ql6Yjy;}z^~}9}_^vZE$=GrG zm#%crIo~<o{+;ib`M=T72u(duNI_#Km@TlD-F%PL0X7$uOQ352>ed;WR4|#L`yp7l z0g4&yO%PYW;RDSLr5v;kz~TfH(ts{|RU7Pl3_?$W-3!a(aOKai6jrvzyrmCZeweu= zS`^Ztm+z%h6k$-zfWJ@pFI|I&ehEMMBUl?Nw2`YYdfL1><G^k)S#loYv!IorRH$fH z4{JHl%8-jgxhSrB^lfklYw4V=P|9rJf^~D3i;!A^wS4WGD*#Q~z!?CO1+*fh7a=hN z>1EK?pu7gzRcPA}?#?<)6lfW!Cx8OMgAls~(do*x)df9AVBjfee;8bypf-SFl7K2@ zA-w?eV-Wre%v=;#6jM-4gUx#{tK9NkF`$?vU{o9A5`Zpq?fc;H8QAtHSl#ulR*hm3 zrvDEAdIMIb;HPiE(61zL*O6a=(O=vZ11&qi(+08IhPllUdK?~m2Re^{*|s@j1&70m z(`mP9TFXGW96Sn%n=n2Csw#fh)*w0oU;Y86{-)II#_kb+mkJWm{ion(Z-b-temdK1 z7EYZC@ys(1(%fukdOF6t?_T1<h47rFoqqwo`y4zSU~xbu0+}eFS6QIrLC7b?UjQ9L z@bh=T-F-jiielo~XNP#}t>c73emXkb^!EoidUP9?FRyrJX6!?7`ya4!9Wu+Z%i9gP zn5m+DDKAwGB;XF8fyV9kV-C>V?BMz558!rNYvzN&MxJ}_0IKTW4L|&yXb+Oko;FZS zh5!v7SiLO^0KGqg?Z>vl9Ki2)(ADLsyVlp|!)~_#51fGRAINOE2s2-SSv3S`8;}YI zlINjQU~z3#fOtGlG@7fswy=<<P$(l+u>Z+QCfGdCHDm~|@C{^R^6zSe&O=*e4iJfC z_~3)E!Ki|0G{<}IU7=Vs3`^%BaJI;QJ^|62W~pk8osf>mLSO(6ydWv3aPVL^Uay@< zB(tFax(-*bE|5wUX>E0~wx;pzw-H`{{hxgN@g$n28I)!frbeY|>KZgOszxc*D#tnf zQsD$oKRw8;TM5G9rA=(0lT7A$^UaIA|Na$RE-TS!j(9vz?X{sg!Qror8@o)BldIoV z5!r$D>_AaK*K6+{lgY&1y=}PNQkQ%_2cb{^P1DKeOYGRu%!v~_86NJzW>af+8s{5W z_{Id@Ug+3gnJndjDvR6;n@#1+nPGZ+eE{s+*Un2X9ipMZ!Yi-*nA4~C5)3x++G|HS zetc)Or8FoPD&y9E6;g{(NLD5@OVU_aESm{ov6xX5#n4MJ#xOQE%h=c)>2v{?%StHZ zXLNLZS1~RAUq^XOmEzOjk@V2Z5TAk6JoxG-wgE+vuNs=BqiH%XzdQ^;C=}qc&#Jsj zY8Fy+#t9~fO&h-U2EpbuED(XY|I{*5fa*_}n@lopZnmSU3c+9#FTVINBO~Ly`sx>) zKR<PcMlgF3vQhbW_@FgpM9BA-xf8Bh3BqS#*Arm#=(@tOV}1C1k{IQ(&dA6(*=&iE zC-)EtI5>GSL_S|a*L4&{p{2#a@Nf^0JhGkH*(5HPm2^58gYgg7n^AGc(xka!(B4Ck zm=}WdBKUVfU@(!$6NzMq$MeMFd1A3Vlania{q;P9g8|yx-JCl&!PwXw<Kq#QmeL$P z9K>cb^U+6Bc)fNeCL($=dG$lM^e0i!Y?Z4&F<0e9Z&2E=k`bkCd*O+*;N7)B6x=n| z@61c;R#emV<uIIk3YI4g^LxP^fTgMG4kaO1WT_}kLplPf83+!8b<=>{9I4yz$**Dd zD;Znt(&)tJ0PgCDoGo%G<>E4q-hkMYv}E>{I%;nQ9ah5d>2IVNSvOJVKB>I<cpU+< ztMa;O3QBXLYa+zVm(neHg4JbuV-#X=?JRuyTljvAJH4gTC+&T9b)B-#yFdrp_J{x_ zqaDvg;KnB~_ird?C5X(b9EvV3D<)v|I$ZxNT==~NT)OH4@dm-y3#+%Pxou=p1uQmb z-2;o)DuRIc&+Y?Hm%Izi4bqZlmZi{SW3{g)s|y<2g|Swyq~YcQ7;D}j<YIC)=M&P& zY!#|agmw7=6Rh6c`rdm4X&;2v-4ekrzhU}1FsV}E%of;w1bjVPIQ)M>gGb(ri(&BX u5K~8|p>sdP3=NxtFn2{Fz1{=17XJlCh;|v_hWm;D0000<MNUMnLSTa5f_EPP literal 0 HcmV?d00001 diff --git a/mod/pub.mod/lua.mod/doc/commands.html b/mod/pub.mod/lua.mod/doc/commands.html new file mode 100644 index 0000000..1c22a2d --- /dev/null +++ b/mod/pub.mod/lua.mod/doc/commands.html @@ -0,0 +1,1201 @@ +<html><head><title>Lua Core reference + + +
      %c    %c\n", + p[0],(p-compose_pairs)/2+0xA0); + else + printf("%c%c   %c\n", + p[0],p[1],(p-compose_pairs)/2+0xA0); + } + printf("
      + + + + +
       axe.lua:FunctionsModinfoSource 
      +

      Lua Core

      +
      "Lua is an extension programming +language designed to support general procedural programming with data +description facilities. It also offers good support for object-oriented +programming, functional programming, and data-driven programming. Lua +is intended to be used as a powerful, light-weight scripting language +for any program that needs one. " (from "Lua 5.1 Reference +Manual" by Roberto Ierusalimschy, Luiz Henrique de +Figueiredo, Waldemar Celes)

      This module provides a +BlitzMax interface to the Lua main and auxiliary APIs. It is almost +complete, the only functions missing are those with variable argument +lists (which are not yet supported by BlitzMax).

      The +axe.lua package also contains the full Lua 5.1.4 distribution. The Lua +source code is completely integrated into the module, additional DLLs +(or shared libraries, resp.) are no longer required.

      Lua +Documentation

      The Lua Reference Manual is part of this +distribution and may be directly visited from here:
      Additional +information can be found on the Lua +web site; the Lua +wiki contains further material about this module +and related packages.

      Introduction

      The +following description is not meant as a tutorial, but may still help +you to start Lua programming within BlitzMax. More API-related +information can be found in the Lua Reference manual

      Setting +up a Lua VM

      Running Lua scripts always require the +instantiation of at least one Lua VM:
       local LuaState:byte ptr = luaL_newstate()
      The +result of this instantiation is a pointer to a structure +which contains the full state of the new VM and has to be +passed as the first argument to almost any other Lua API function.

      It +is now time to "open" the intrinsic Lua libraries (note: these +libraries are part of axe.lua now, external DLLs or shared libraries +are not necessary):
       luaL_openlibs(LuaState)
      Always +initialize the Lua VM by opening its libraries unless you really know +what you are doing!

      Usually, creating a single Lua +state is sufficient, even further (Lua) threads share the basic Lua +state (and its associated environment).

      Shutting +down a Lua VM

      At the end, it's always a good idea to shut +down the Lua VM
       lua_close(LuaState)
      The +Lua interpreter has now been terminated and its state variable is no +longer valid.

      Accessing Lua Globals

      The +code
        lua_pushstring(LuaState, "BMXString")
      lua_setglobal (LuaState, "luaglobal")
      defines +a global Lua variable (called luaglobal) +which contains a string (namely "BMXString").

      Registering +BlitzMax Functions

      In order to access BlitzMax features from +within a Lua script, it is necessary to implement suitable BlitzMax +functions and register them in the Lua VM.

      Such +BlitzMax functions typically look as follows:
       function BMXName:int (LuaState:Byte Ptr)
      ... ' handling of parameters passed from Lua (if required)
      ... ' actual function body
      ... ' passing results back to Lua (if required)
      return 0 ' number of values returned to Lua
      end function
      Such +a function is then registered using
       lua_register(LuaState, "luaname", BMXName)
      This +command registers a BlitzMax function (called BMXName) +with the (global) name luaname +under Lua. Both names may be equal, but they do not have to.

      Running +Lua Scripts From Within BlitzMax

      The code
       local Result:int = luaL_loadString(LuaState,LuaScript)
      if (Result <> 0) then
      ' ERROR!!!
      lua_close(LuaState) ' just to be complete
      end
      end if
      loads +and compiles a (BlitzMax) string containing a LuaScript. The result (of +compilation) is left on the (Lua) stack.
       lua_getfield(LuaState, LUA_GLOBALSINDEX, "debug")' get global "debug"
      lua_getfield(LuaState, -1, "traceback") ' get "debug.traceback"
      lua_remove (LuaState, -2) ' remove "debug" table from stack

      Result = lua_pcall(LuaState,1,-1,-1)' use "debug.traceback" as err.hdlr
      if (Result <> 0) then
      ' ERROR
      lua_close(LuaState) ' just to be complete
      end
      end if
      actually +evaluates the previously loaded script. The initially mentioned Lua +commands just prepare for proper error messages should the Lua script +fail.
      +

      Functions Summary

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      lua_atpanic +see Lua Reference Manual +
      lua_call +see Lua Reference Manual +
      lua_checkstack +see Lua Reference Manual +
      lua_close +see Lua Reference Manual +
      lua_concat +see Lua Reference Manual +
      lua_cpcall +see Lua Reference Manual +
      lua_createtable +see Lua Reference Manual +
      lua_dump +see Lua Reference Manual +
      lua_equal +see Lua Reference Manual +
      lua_error +see Lua Reference Manual +
      lua_gc +see Lua Reference Manual +
      lua_getallocf +see Lua Reference Manual +
      lua_getfenv +see Lua Reference Manual +
      lua_getfield +see Lua Reference Manual +
      lua_getglobal +see Lua Reference Manual +
      lua_gethook +see Lua Reference Manual +
      lua_gethookcount +see Lua Reference Manual +
      lua_gethookmask +see Lua Reference Manual +
      lua_getinfo +see Lua Reference Manual +
      lua_getlocal +see Lua Reference Manual +
      lua_getmetatable +see Lua Reference Manual +
      lua_getstack +see Lua Reference Manual +
      lua_gettable +see Lua Reference Manual +
      lua_gettop +see Lua Reference Manual +
      lua_getupvalue +see Lua Reference Manual +
      lua_insert +see Lua Reference Manual +
      lua_isboolean +see Lua Reference Manual +
      lua_iscfunction +see Lua Reference Manual +
      lua_isfunction +see Lua Reference Manual +
      lua_islightuserdata +see Lua Reference Manual +
      lua_isnil +see Lua Reference Manual +
      lua_isnone +see Lua Reference Manual +
      lua_isnoneornil +see Lua Reference Manual +
      lua_isnumber +see Lua Reference Manual +
      lua_isstring +see Lua Reference Manual +
      lua_istable +see Lua Reference Manual +
      lua_isthread +see Lua Reference Manual +
      lua_isuserdata +see Lua Reference Manual +
      lua_lessthan +see Lua Reference Manual +
      lua_load +see Lua Reference Manual +
      lua_newstate +see Lua Reference Manual +
      lua_newtable +see Lua Reference Manual +
      lua_newthread +see Lua Reference Manual +
      lua_newuserdata +see Lua Reference Manual +
      lua_next +see Lua Reference Manual +
      lua_objlen +see Lua Reference Manual +
      lua_pcall +see Lua Reference Manual +
      lua_pop +see Lua Reference Manual +
      lua_pushboolean +see Lua Reference Manual +
      lua_pushcclosure +see Lua Reference Manual +
      lua_pushcfunction +see Lua Reference Manual +
      lua_pushinteger +see Lua Reference Manual +
      lua_pushlightuserdata +see Lua Reference Manual +
      lua_pushlstring +see Lua Reference Manual +
      lua_pushnil +see Lua Reference Manual +
      lua_pushnumber +see Lua Reference Manual +
      lua_pushstring +see Lua Reference Manual +
      lua_pushthread +see Lua Reference Manual +
      lua_pushvalue +see Lua Reference Manual +
      lua_rawequal +see Lua Reference Manual +
      lua_rawget +see Lua Reference Manual +
      lua_rawgeti +see Lua Reference Manual +
      lua_rawset +see Lua Reference Manual +
      lua_rawseti +see Lua Reference Manual +
      lua_register +see Lua Reference Manual +
      lua_remove +see Lua Reference Manual +
      lua_replace +see Lua Reference Manual +
      lua_resume +see Lua Reference Manual +
      lua_setallocf +see Lua Reference Manual +
      lua_setfenv +see Lua Reference Manual +
      lua_setfield +see Lua Reference Manual +
      lua_setglobal +see Lua Reference Manual +
      lua_sethook +see Lua Reference Manual +
      lua_setlocal +see Lua Reference Manual +
      lua_setmetatable +see Lua Reference Manual +
      lua_settable +see Lua Reference Manual +
      lua_settop +see Lua Reference Manual +
      lua_setupvalue +see Lua Reference Manual +
      lua_status +see Lua Reference Manual +
      lua_toboolean +see Lua Reference Manual +
      lua_tocfunction +see Lua Reference Manual +
      lua_tointeger +see Lua Reference Manual +
      lua_tolstring +see Lua Reference Manual +
      lua_tonumber +see Lua Reference Manual +
      lua_topointer +see Lua Reference Manual +
      lua_tostring +see Lua Reference Manual +
      lua_tothread +see Lua Reference Manual +
      lua_touserdata +see Lua Reference Manual +
      lua_type +see Lua Reference Manual +
      lua_typename +see Lua Reference Manual +
      lua_xmove +see Lua Reference Manual +
      lua_yield +see Lua Reference Manual +
      luaL_addchar +see Lua Reference Manual +
      luaL_addlstring +see Lua Reference Manual +
      luaL_addsize +see Lua Reference Manual +
      luaL_addstring +see Lua Reference Manual +
      luaL_addvalue +see Lua Reference Manual +
      luaL_argcheck +see Lua Reference Manual +
      luaL_argerror +see Lua Reference Manual +
      luaL_buffinit +see Lua Reference Manual +
      luaL_callmeta +see Lua Reference Manual +
      luaL_checkany +see Lua Reference Manual +
      luaL_checkint +see Lua Reference Manual +
      luaL_checkinteger +see Lua Reference Manual +
      luaL_checklong +see Lua Reference Manual +
      luaL_checklstring +see Lua Reference Manual +
      luaL_checknumber +see Lua Reference Manual +
      luaL_checkstack +see Lua Reference Manual +
      luaL_checkstring +see Lua Reference Manual +
      luaL_checktype +see Lua Reference Manual +
      luaL_checkudata +see Lua Reference Manual +
      luaL_dofile +see Lua Reference Manual +
      luaL_dostring +see Lua Reference Manual +
      luaL_getmetafield +see Lua Reference Manual +
      luaL_getmetatable +see Lua Reference Manual +
      luaL_gsub +see Lua Reference Manual +
      luaL_loadbuffer +see Lua Reference Manual +
      luaL_loadfile +see Lua Reference Manual +
      luaL_loadstring +see Lua Reference Manual +
      luaL_newmetatable +see Lua Reference Manual +
      luaL_newstate +see Lua Reference Manual +
      luaL_openlibs +see Lua Reference Manual +
      luaL_optint +see Lua Reference Manual +
      luaL_optinteger +see Lua Reference Manual +
      luaL_optlong +see Lua Reference Manual +
      luaL_optlstring +see Lua Reference Manual +
      luaL_optnumber +see Lua Reference Manual +
      luaL_optstring +see Lua Reference Manual +
      luaL_prepbuffer +see Lua Reference Manual +
      luaL_pushresult +see Lua Reference Manual +
      luaL_ref +see Lua Reference Manual +
      luaL_register +see Lua Reference Manual +
      luaL_typename +see Lua Reference Manual +
      luaL_typerror +see Lua Reference Manual +
      luaL_unref +see Lua Reference Manual +
      luaL_where +see Lua Reference Manual +
      +

      Functions +

      + + + +
      function lua_atpanic:byte ptr (lua_state:byte ptr, panicf:int(ls:byte ptr))
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_call (lua_state:byte ptr, nargs:int, nresults:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_checkstack:int (lua_state:byte ptr, extra:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_close (lua_state:byte ptr)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_concat (lua_state:byte ptr, n:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_cpcall:int (lua_state:byte ptr, func:int(ls:byte ptr), ud:byte ptr)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_createtable (lua_state:byte ptr, narr:int, nrec:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_dump:int (lua_state:byte ptr, writer:int(ls:byte ptr,p:byte ptr,sz:int,ud:byte ptr), data:byte ptr)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_equal:int (lua_state:byte ptr, index1:int, index2:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_error:int (lua_state:byte ptr)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_gc:int (lua_state:byte ptr, what:int, data:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_getallocf:byte ptr (lua_state:byte ptr, ud:byte ptr ptr)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_getfenv (lua_state:byte ptr, index:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_getfield (lua_state:byte ptr, index:int, k$z) ' no ~0 expected
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_getglobal (lua_state:byte ptr, name:string)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_gethook:byte ptr (lua_state:byte ptr)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_gethookcount:int (lua_state:byte ptr)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_gethookmask:int (lua_state:byte ptr)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_getinfo:int (lua_state:byte ptr, what$z, ar:lua_Debug ptr) ' no ~0 expected
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_getlocal$z (lua_state:byte ptr, ar:lua_Debug ptr, n:int) ' no ~0 expected
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_getmetatable:int (lua_state:byte ptr, index:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_getstack:int (lua_state:byte ptr, level:int, ar:lua_Debug ptr) ' no ~0 expected
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_gettable (lua_state:byte ptr, index:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_gettop:int (lua_state:byte ptr)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_getupvalue$z (lua_state:byte ptr, funcindex:int, n:int) ' no ~0 expected
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_insert (lua_state:byte ptr, index:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_isboolean:int (lua_state:byte ptr, index:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_iscfunction:int (lua_state:byte ptr, index:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_isfunction:int (lua_state:byte ptr, index:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_islightuserdata:int (lua_state:byte ptr, index:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_isnil:int (lua_state:byte ptr, index:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_isnone:int (lua_state:byte ptr, index:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_isnoneornil:int (lua_state:byte ptr, index:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_isnumber:int (lua_state:byte ptr, index:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_isstring:int (lua_state:byte ptr, index:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_istable:int (lua_state:byte ptr, index:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_isthread:int (lua_state:byte ptr, index:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_isuserdata:int (lua_state:byte ptr, index:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_lessthan:int (lua_state:byte ptr, index1:int, index2:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_load:int (lua_state:byte ptr, reader:byte ptr(ls:byte ptr,data:byte ptr,sz:int ptr), data:byte ptr, chunkname$z) ' no ~0 expected
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_newstate:byte ptr (f:byte ptr(ud:byte ptr, p:byte ptr, osize:int, nsize:int), ud:byte ptr)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_newtable (lua_state:byte ptr)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_newthread:byte ptr (lua_state:byte ptr)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_newuserdata:byte ptr (lua_state:byte ptr, size:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_next:int (lua_state:byte ptr, index:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_objlen:int (lua_state:byte ptr, index:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_pcall:int (lua_state:byte ptr, nargs:int, nresults:int, errfunc:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_pop (lua_state:byte ptr, n:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_pushboolean (lua_state:byte ptr, b:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_pushcclosure (lua_state:byte ptr, fn:int(ls:byte ptr), n:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_pushcfunction (lua_state:byte ptr, fn:int(ls:byte ptr))
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_pushinteger (lua_state:byte ptr, n:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_pushlightuserdata (lua_state:byte ptr, p:byte ptr)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_pushlstring (lua_state:byte ptr, s:byte ptr, size:int) ' without any conversion!
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_pushnil (lua_state:byte ptr)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_pushnumber (lua_state:byte ptr, n:double)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_pushstring (lua_state:byte ptr, s$z) ' no ~0 expected
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_pushthread:int (lua_state:byte ptr)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_pushvalue (lua_state:byte ptr, index:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_rawequal:int (lua_state:byte ptr, index1:int, index2:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_rawget (lua_state:byte ptr, index:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_rawgeti (lua_state:byte ptr, index:int, n:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_rawset (lua_state:byte ptr, index:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_rawseti (lua_state:byte ptr, index:int, n:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_register (lua_state:byte ptr, name:string, f:int(ls:byte ptr))
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_remove (lua_state:byte ptr, index:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_replace (lua_state:byte ptr, index:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_resume:int (lua_state:byte ptr, narg:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_setallocf (lua_state:byte ptr, f:byte ptr(ud:byte ptr, p:byte ptr, osize:int, nsize:int), ud:byte ptr)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_setfenv:int (lua_state:byte ptr, index:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_setfield (lua_state:byte ptr, index:int, k$z) ' no ~0 expected
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_setglobal (lua_state:byte ptr, name:string)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_sethook:int (lua_state:byte ptr, f(ls:byte ptr,ar:lua_Debug ptr), mask:int, count:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_setlocal$z (lua_state:byte ptr, ar:lua_Debug ptr, n:int) ' no ~0 expected
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_setmetatable:int (lua_state:byte ptr, index:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_settable (lua_state:byte ptr, index:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_settop (lua_state:byte ptr, index:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_setupvalue$z (lua_state:byte ptr, funcindex:int, n:int) ' no ~0 expected
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_status:int (lua_state:byte ptr)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_toboolean:int (lua_state:byte ptr, index:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_tocfunction:byte ptr (lua_state:byte ptr, index:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_tointeger:int (lua_state:byte ptr, index:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_tolstring:byte ptr (lua_state:byte ptr, index:int, size:int ptr) ' without any conversion!
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_tonumber:double (lua_state:byte ptr, index:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_topointer:byte ptr (lua_state:byte ptr, index:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_tostring:string (lua_state:byte ptr, index:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_tothread:byte ptr (lua_state:byte ptr, index:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_touserdata:byte ptr (lua_state:byte ptr, index:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_type:int (lua_state:byte ptr, index:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_typename$z (lua_state:byte ptr, tp:int) ' no ~0 expected
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_xmove (fromState:byte ptr, toState:byte ptr, n:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function lua_yield:int (lua_state:byte ptr, nresults:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function luaL_addchar (B:byte ptr, c:string)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function luaL_addlstring (B:byte ptr, s:byte ptr, l:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function luaL_addsize (B:byte ptr, size:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function luaL_addstring (B:byte ptr, s$z) ' no ~0 allowed!
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function luaL_addvalue (B:byte ptr)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function luaL_argcheck (lua_state:byte ptr, cond:int, narg:int, extramsg:string)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function luaL_argerror:int (lua_state:byte ptr, narg:int, extramsg$z) ' no ~0 expected
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function luaL_buffinit (lua_state:byte ptr, B:byte ptr)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function luaL_callmeta:int (lua_state:byte ptr, obj:int, e$z) ' no ~0 expected
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function luaL_checkany (lua_state:byte ptr, narg:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function luaL_checkint:int (lua_state:byte ptr, narg:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function luaL_checkinteger:int (lua_state:byte ptr, narg:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function luaL_checklong:long (lua_state:byte ptr, narg:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function luaL_checklstring:byte ptr (lua_state:byte ptr, narg:int, size:int ptr)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function luaL_checknumber:double (lua_state:byte ptr, narg:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function luaL_checkstack (lua_state:byte ptr, sz:int, msg$z) ' no ~0 expected
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function luaL_checkstring:string (lua_state:byte ptr, narg:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function luaL_checktype (lua_state:byte ptr, narg:int, t:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function luaL_checkudata:byte ptr (lua_state:byte ptr, narg:int, tname$z) ' no ~0 expected
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function luaL_dofile:int (lua_state:byte ptr, filename:string)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function luaL_dostring:int (lua_state:byte ptr, str:string)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function luaL_getmetafield:int (lua_state:byte ptr, obj:int, e$z) ' no ~0 expected
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function luaL_getmetatable (lua_state:byte ptr, tname:string)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function luaL_gsub$z (lua_state:byte ptr, s$z, p$z, r$z) ' no ~0 expected
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function luaL_loadbuffer:int (lua_state:byte ptr, buff:byte ptr, sz:int, name$z) ' no ~0 expected
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function luaL_loadfile:int (lua_state:byte ptr, filename$z) ' no ~0 expected
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function luaL_loadstring:int (lua_state:byte ptr, s$z) ' no ~0 allowed!
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function luaL_newmetatable:int (lua_state:byte ptr, tname$z) ' no ~0 expected
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function luaL_newstate:byte ptr ()
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function luaL_openlibs (lua_state:byte ptr)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function luaL_optint:int (lua_state:byte ptr, narg:int, d:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function luaL_optinteger:int (lua_state:byte ptr, narg:int, d:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function luaL_optlong:long (lua_state:byte ptr, narg:int, d:long)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function luaL_optlstring:byte ptr (lua_state:byte ptr, narg:int, d$z, size:int ptr) ' no ~0 expected in "d"
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function luaL_optnumber:double (lua_state:byte ptr, narg:int, d:double)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function luaL_optstring:string (lua_state:byte ptr, narg:int, d:string)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function luaL_prepbuffer:byte ptr (B:byte ptr)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function luaL_pushresult (B:byte ptr)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function luaL_ref:int (lua_state:byte ptr, t:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function luaL_register (lua_state:byte ptr, libname$z, l:lua_Reg ptr) ' no ~0 expected
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function luaL_typename:string (lua_state:byte ptr, idx:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function luaL_typerror:int (lua_state:byte ptr, narg:int, tname$z) ' no ~0 expected
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function luaL_unref (lua_state:byte ptr, t:int, ref:int)
      Descriptionsee Lua Reference Manual
      +
      + + + +
      function luaL_where (lua_state:byte ptr, lvl:int)
      Descriptionsee Lua Reference Manual
      +
      +

      Module Information

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mod/pub.mod/lua.mod/doc/intro.bbdoc b/mod/pub.mod/lua.mod/doc/intro.bbdoc new file mode 100644 index 0000000..be52e4d --- /dev/null +++ b/mod/pub.mod/lua.mod/doc/intro.bbdoc @@ -0,0 +1,56 @@ +
      "Lua is an extension programming +language designed to support general procedural programming with data +description facilities. It also offers good support for object-oriented +programming, functional programming, and data-driven programming. Lua +is intended to be used as a powerful, light-weight scripting language +for any program that needs one. " (from "Lua 5.1 Reference +Manual" by Roberto Ierusalimschy, Luiz Henrique de +Figueiredo, Waldemar Celes)

      This module provides a +BlitzMax interface to the Lua main and auxiliary APIs. It is almost +complete, the only functions missing are those with variable argument +lists (which are not yet supported by BlitzMax).

      The +axe.lua package also contains the full Lua 5.1.4 distribution. The Lua +source code is completely integrated into the module, additional DLLs +(or shared libraries, resp.) are no longer required.

      Lua +Documentation

      The Lua Reference Manual is part of this +distribution and may be directly visited from here:
      Additional +information can be found on the Lua +web site; the Lua +wiki contains further material about this module +and related packages.

      Introduction

      The +following description is not meant as a tutorial, but may still help +you to start Lua programming within BlitzMax. More API-related +information can be found in the Lua Reference manual

      Setting +up a Lua VM

      Running Lua scripts always require the +instantiation of at least one Lua VM:
       local LuaState:byte ptr = luaL_newstate()
      The +result of this instantiation is a pointer to a structure +which contains the full state of the new VM and has to be +passed as the first argument to almost any other Lua API function.

      It +is now time to "open" the intrinsic Lua libraries (note: these +libraries are part of axe.lua now, external DLLs or shared libraries +are not necessary):
       luaL_openlibs(LuaState)
      Always +initialize the Lua VM by opening its libraries unless you really know +what you are doing!

      Usually, creating a single Lua +state is sufficient, even further (Lua) threads share the basic Lua +state (and its associated environment).

      Shutting +down a Lua VM

      At the end, it's always a good idea to shut +down the Lua VM
       lua_close(LuaState)
      The +Lua interpreter has now been terminated and its state variable is no +longer valid.

      Accessing Lua Globals

      The +code
        lua_pushstring(LuaState, "BMXString")
      lua_setglobal (LuaState, "luaglobal")
      defines +a global Lua variable (called luaglobal) +which contains a string (namely "BMXString").

      Registering +BlitzMax Functions

      In order to access BlitzMax features from +within a Lua script, it is necessary to implement suitable BlitzMax +functions and register them in the Lua VM.

      Such +BlitzMax functions typically look as follows:
       function BMXName:int (LuaState:Byte Ptr)
      ... ' handling of parameters passed from Lua (if required)
      ... ' actual function body
      ... ' passing results back to Lua (if required)
      return 0 ' number of values returned to Lua
      end function
      Such +a function is then registered using
       lua_register(LuaState, "luaname", BMXName)
      This +command registers a BlitzMax function (called BMXName) +with the (global) name luaname +under Lua. Both names may be equal, but they do not have to.

      Running +Lua Scripts From Within BlitzMax

      The code
       local Result:int = luaL_loadString(LuaState,LuaScript)
      if (Result <> 0) then
      ' ERROR!!!
      lua_close(LuaState) ' just to be complete
      end
      end if
      loads +and compiles a (BlitzMax) string containing a LuaScript. The result (of +compilation) is left on the (Lua) stack.
       lua_getfield(LuaState, LUA_GLOBALSINDEX, "debug")' get global "debug"
      lua_getfield(LuaState, -1, "traceback") ' get "debug.traceback"
      lua_remove (LuaState, -2) ' remove "debug" table from stack

      Result = lua_pcall(LuaState,1,-1,-1)' use "debug.traceback" as err.hdlr
      if (Result <> 0) then
      ' ERROR
      lua_close(LuaState) ' just to be complete
      end
      end if
      actually +evaluates the previously loaded script. The initially mentioned Lua +commands just prepare for proper error messages should the Lua script +fail.
      \ No newline at end of file diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/COPYRIGHT b/mod/pub.mod/lua.mod/lua-5.1.4/COPYRIGHT new file mode 100644 index 0000000..3a53e74 --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/COPYRIGHT @@ -0,0 +1,34 @@ +Lua License +----------- + +Lua is licensed under the terms of the MIT license reproduced below. +This means that Lua is free software and can be used for both academic +and commercial purposes at absolutely no cost. + +For details and rationale, see http://www.lua.org/license.html . + +=============================================================================== + +Copyright (C) 1994-2008 Lua.org, PUC-Rio. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +=============================================================================== + +(end of COPYRIGHT) diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/HISTORY b/mod/pub.mod/lua.mod/lua-5.1.4/HISTORY new file mode 100644 index 0000000..ce0c95b --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/HISTORY @@ -0,0 +1,183 @@ +HISTORY for Lua 5.1 + +* Changes from version 5.0 to 5.1 + ------------------------------- + Language: + + new module system. + + new semantics for control variables of fors. + + new semantics for setn/getn. + + new syntax/semantics for varargs. + + new long strings and comments. + + new `mod' operator (`%') + + new length operator #t + + metatables for all types + API: + + new functions: lua_createtable, lua_get(set)field, lua_push(to)integer. + + user supplies memory allocator (lua_open becomes lua_newstate). + + luaopen_* functions must be called through Lua. + Implementation: + + new configuration scheme via luaconf.h. + + incremental garbage collection. + + better handling of end-of-line in the lexer. + + fully reentrant parser (new Lua function `load') + + better support for 64-bit machines. + + native loadlib support for Mac OS X. + + standard distribution in only one library (lualib.a merged into lua.a) + +* Changes from version 4.0 to 5.0 + ------------------------------- + Language: + + lexical scoping. + + Lua coroutines. + + standard libraries now packaged in tables. + + tags replaced by metatables and tag methods replaced by metamethods, + stored in metatables. + + proper tail calls. + + each function can have its own global table, which can be shared. + + new __newindex metamethod, called when we insert a new key into a table. + + new block comments: --[[ ... ]]. + + new generic for. + + new weak tables. + + new boolean type. + + new syntax "local function". + + (f()) returns the first value returned by f. + + {f()} fills a table with all values returned by f. + + \n ignored in [[\n . + + fixed and-or priorities. + + more general syntax for function definition (e.g. function a.x.y:f()...end). + + more general syntax for function calls (e.g. (print or write)(9)). + + new functions (time/date, tmpfile, unpack, require, load*, etc.). + API: + + chunks are loaded by using lua_load; new luaL_loadfile and luaL_loadbuffer. + + introduced lightweight userdata, a simple "void*" without a metatable. + + new error handling protocol: the core no longer prints error messages; + all errors are reported to the caller on the stack. + + new lua_atpanic for host cleanup. + + new, signal-safe, hook scheme. + Implementation: + + new license: MIT. + + new, faster, register-based virtual machine. + + support for external multithreading and coroutines. + + new and consistent error message format. + + the core no longer needs "stdio.h" for anything (except for a single + use of sprintf to convert numbers to strings). + + lua.c now runs the environment variable LUA_INIT, if present. It can + be "@filename", to run a file, or the chunk itself. + + support for user extensions in lua.c. + sample implementation given for command line editing. + + new dynamic loading library, active by default on several platforms. + + safe garbage-collector metamethods. + + precompiled bytecodes checked for integrity (secure binary dostring). + + strings are fully aligned. + + position capture in string.find. + + read('*l') can read lines with embedded zeros. + +* Changes from version 3.2 to 4.0 + ------------------------------- + Language: + + new "break" and "for" statements (both numerical and for tables). + + uniform treatment of globals: globals are now stored in a Lua table. + + improved error messages. + + no more '$debug': full speed *and* full debug information. + + new read form: read(N) for next N bytes. + + general read patterns now deprecated. + (still available with -DCOMPAT_READPATTERNS.) + + all return values are passed as arguments for the last function + (old semantics still available with -DLUA_COMPAT_ARGRET) + + garbage collection tag methods for tables now deprecated. + + there is now only one tag method for order. + API: + + New API: fully re-entrant, simpler, and more efficient. + + New debug API. + Implementation: + + faster than ever: cleaner virtual machine and new hashing algorithm. + + non-recursive garbage-collector algorithm. + + reduced memory usage for programs with many strings. + + improved treatment for memory allocation errors. + + improved support for 16-bit machines (we hope). + + code now compiles unmodified as both ANSI C and C++. + + numbers in bases other than 10 are converted using strtoul. + + new -f option in Lua to support #! scripts. + + luac can now combine text and binaries. + +* Changes from version 3.1 to 3.2 + ------------------------------- + + redirected all output in Lua's core to _ERRORMESSAGE and _ALERT. + + increased limit on the number of constants and globals per function + (from 2^16 to 2^24). + + debugging info (lua_debug and hooks) moved into lua_state and new API + functions provided to get and set this info. + + new debug lib gives full debugging access within Lua. + + new table functions "foreachi", "sort", "tinsert", "tremove", "getn". + + new io functions "flush", "seek". + +* Changes from version 3.0 to 3.1 + ------------------------------- + + NEW FEATURE: anonymous functions with closures (via "upvalues"). + + new syntax: + - local variables in chunks. + - better scope control with DO block END. + - constructors can now be also written: { record-part; list-part }. + - more general syntax for function calls and lvalues, e.g.: + f(x).y=1 + o:f(x,y):g(z) + f"string" is sugar for f("string") + + strings may now contain arbitrary binary data (e.g., embedded zeros). + + major code re-organization and clean-up; reduced module interdependecies. + + no arbitrary limits on the total number of constants and globals. + + support for multiple global contexts. + + better syntax error messages. + + new traversal functions "foreach" and "foreachvar". + + the default for numbers is now double. + changing it to use floats or longs is easy. + + complete debug information stored in pre-compiled chunks. + + sample interpreter now prompts user when run interactively, and also + handles control-C interruptions gracefully. + +* Changes from version 2.5 to 3.0 + ------------------------------- + + NEW CONCEPT: "tag methods". + Tag methods replace fallbacks as the meta-mechanism for extending the + semantics of Lua. Whereas fallbacks had a global nature, tag methods + work on objects having the same tag (e.g., groups of tables). + Existing code that uses fallbacks should work without change. + + new, general syntax for constructors {[exp] = exp, ... }. + + support for handling variable number of arguments in functions (varargs). + + support for conditional compilation ($if ... $else ... $end). + + cleaner semantics in API simplifies host code. + + better support for writing libraries (auxlib.h). + + better type checking and error messages in the standard library. + + luac can now also undump. + +* Changes from version 2.4 to 2.5 + ------------------------------- + + io and string libraries are now based on pattern matching; + the old libraries are still available for compatibility + + dofile and dostring can now return values (via return statement) + + better support for 16- and 64-bit machines + + expanded documentation, with more examples + +* Changes from version 2.2 to 2.4 + ------------------------------- + + external compiler creates portable binary files that can be loaded faster + + interface for debugging and profiling + + new "getglobal" fallback + + new functions for handling references to Lua objects + + new functions in standard lib + + only one copy of each string is stored + + expanded documentation, with more examples + +* Changes from version 2.1 to 2.2 + ------------------------------- + + functions now may be declared with any "lvalue" as a name + + garbage collection of functions + + support for pipes + +* Changes from version 1.1 to 2.1 + ------------------------------- + + object-oriented support + + fallbacks + + simplified syntax for tables + + many internal improvements + +(end of HISTORY) diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/INSTALL b/mod/pub.mod/lua.mod/lua-5.1.4/INSTALL new file mode 100644 index 0000000..17eb8ae --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/INSTALL @@ -0,0 +1,99 @@ +INSTALL for Lua 5.1 + +* Building Lua + ------------ + Lua is built in the src directory, but the build process can be + controlled from the top-level Makefile. + + Building Lua on Unix systems should be very easy. First do "make" and + see if your platform is listed. If so, just do "make xxx", where xxx + is your platform name. The platforms currently supported are: + aix ansi bsd freebsd generic linux macosx mingw posix solaris + + If your platform is not listed, try the closest one or posix, generic, + ansi, in this order. + + See below for customization instructions and for instructions on how + to build with other Windows compilers. + + If you want to check that Lua has been built correctly, do "make test" + after building Lua. Also, have a look at the example programs in test. + +* Installing Lua + -------------- + Once you have built Lua, you may want to install it in an official + place in your system. In this case, do "make install". The official + place and the way to install files are defined in Makefile. You must + have the right permissions to install files. + + If you want to build and install Lua in one step, do "make xxx install", + where xxx is your platform name. + + If you want to install Lua locally, then do "make local". This will + create directories bin, include, lib, man, and install Lua there as + follows: + + bin: lua luac + include: lua.h luaconf.h lualib.h lauxlib.h lua.hpp + lib: liblua.a + man/man1: lua.1 luac.1 + + These are the only directories you need for development. + + There are man pages for lua and luac, in both nroff and html, and a + reference manual in html in doc, some sample code in test, and some + useful stuff in etc. You don't need these directories for development. + + If you want to install Lua locally, but in some other directory, do + "make install INSTALL_TOP=xxx", where xxx is your chosen directory. + + See below for instructions for Windows and other systems. + +* Customization + ------------- + Three things can be customized by editing a file: + - Where and how to install Lua -- edit Makefile. + - How to build Lua -- edit src/Makefile. + - Lua features -- edit src/luaconf.h. + + You don't actually need to edit the Makefiles because you may set the + relevant variables when invoking make. + + On the other hand, if you need to select some Lua features, you'll need + to edit src/luaconf.h. The edited file will be the one installed, and + it will be used by any Lua clients that you build, to ensure consistency. + + We strongly recommend that you enable dynamic loading. This is done + automatically for all platforms listed above that have this feature + (and also Windows). See src/luaconf.h and also src/Makefile. + +* Building Lua on Windows and other systems + ----------------------------------------- + If you're not using the usual Unix tools, then the instructions for + building Lua depend on the compiler you use. You'll need to create + projects (or whatever your compiler uses) for building the library, + the interpreter, and the compiler, as follows: + + library: lapi.c lcode.c ldebug.c ldo.c ldump.c lfunc.c lgc.c llex.c + lmem.c lobject.c lopcodes.c lparser.c lstate.c lstring.c + ltable.c ltm.c lundump.c lvm.c lzio.c + lauxlib.c lbaselib.c ldblib.c liolib.c lmathlib.c loslib.c + ltablib.c lstrlib.c loadlib.c linit.c + + interpreter: library, lua.c + + compiler: library, luac.c print.c + + If you use Visual Studio .NET, you can use etc/luavs.bat in its + "Command Prompt". + + If all you want is to build the Lua interpreter, you may put all .c files + in a single project, except for luac.c and print.c. Or just use etc/all.c. + + To use Lua as a library in your own programs, you'll need to know how to + create and use libraries with your compiler. + + As mentioned above, you may edit luaconf.h to select some features before + building Lua. + +(end of INSTALL) diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/Makefile b/mod/pub.mod/lua.mod/lua-5.1.4/Makefile new file mode 100644 index 0000000..6e78f66 --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/Makefile @@ -0,0 +1,128 @@ +# makefile for installing Lua +# see INSTALL for installation instructions +# see src/Makefile and src/luaconf.h for further customization + +# == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT ======================= + +# Your platform. See PLATS for possible values. +PLAT= none + +# Where to install. The installation starts in the src and doc directories, +# so take care if INSTALL_TOP is not an absolute path. +INSTALL_TOP= /usr/local +INSTALL_BIN= $(INSTALL_TOP)/bin +INSTALL_INC= $(INSTALL_TOP)/include +INSTALL_LIB= $(INSTALL_TOP)/lib +INSTALL_MAN= $(INSTALL_TOP)/man/man1 +# +# You probably want to make INSTALL_LMOD and INSTALL_CMOD consistent with +# LUA_ROOT, LUA_LDIR, and LUA_CDIR in luaconf.h (and also with etc/lua.pc). +INSTALL_LMOD= $(INSTALL_TOP)/share/lua/$V +INSTALL_CMOD= $(INSTALL_TOP)/lib/lua/$V + +# How to install. If your install program does not support "-p", then you +# may have to run ranlib on the installed liblua.a (do "make ranlib"). +INSTALL= install -p +INSTALL_EXEC= $(INSTALL) -m 0755 +INSTALL_DATA= $(INSTALL) -m 0644 +# +# If you don't have install you can use cp instead. +# INSTALL= cp -p +# INSTALL_EXEC= $(INSTALL) +# INSTALL_DATA= $(INSTALL) + +# Utilities. +MKDIR= mkdir -p +RANLIB= ranlib + +# == END OF USER SETTINGS. NO NEED TO CHANGE ANYTHING BELOW THIS LINE ========= + +# Convenience platforms targets. +PLATS= aix ansi bsd freebsd generic linux macosx mingw posix solaris + +# What to install. +TO_BIN= lua luac +TO_INC= lua.h luaconf.h lualib.h lauxlib.h ../etc/lua.hpp +TO_LIB= liblua.a +TO_MAN= lua.1 luac.1 + +# Lua version and release. +V= 5.1 +R= 5.1.4 + +all: $(PLAT) + +$(PLATS) clean: + cd src && $(MAKE) $@ + +test: dummy + src/lua test/hello.lua + +install: dummy + cd src && $(MKDIR) $(INSTALL_BIN) $(INSTALL_INC) $(INSTALL_LIB) $(INSTALL_MAN) $(INSTALL_LMOD) $(INSTALL_CMOD) + cd src && $(INSTALL_EXEC) $(TO_BIN) $(INSTALL_BIN) + cd src && $(INSTALL_DATA) $(TO_INC) $(INSTALL_INC) + cd src && $(INSTALL_DATA) $(TO_LIB) $(INSTALL_LIB) + cd doc && $(INSTALL_DATA) $(TO_MAN) $(INSTALL_MAN) + +ranlib: + cd src && cd $(INSTALL_LIB) && $(RANLIB) $(TO_LIB) + +local: + $(MAKE) install INSTALL_TOP=.. + +none: + @echo "Please do" + @echo " make PLATFORM" + @echo "where PLATFORM is one of these:" + @echo " $(PLATS)" + @echo "See INSTALL for complete instructions." + +# make may get confused with test/ and INSTALL in a case-insensitive OS +dummy: + +# echo config parameters +echo: + @echo "" + @echo "These are the parameters currently set in src/Makefile to build Lua $R:" + @echo "" + @cd src && $(MAKE) -s echo + @echo "" + @echo "These are the parameters currently set in Makefile to install Lua $R:" + @echo "" + @echo "PLAT = $(PLAT)" + @echo "INSTALL_TOP = $(INSTALL_TOP)" + @echo "INSTALL_BIN = $(INSTALL_BIN)" + @echo "INSTALL_INC = $(INSTALL_INC)" + @echo "INSTALL_LIB = $(INSTALL_LIB)" + @echo "INSTALL_MAN = $(INSTALL_MAN)" + @echo "INSTALL_LMOD = $(INSTALL_LMOD)" + @echo "INSTALL_CMOD = $(INSTALL_CMOD)" + @echo "INSTALL_EXEC = $(INSTALL_EXEC)" + @echo "INSTALL_DATA = $(INSTALL_DATA)" + @echo "" + @echo "See also src/luaconf.h ." + @echo "" + +# echo private config parameters +pecho: + @echo "V = $(V)" + @echo "R = $(R)" + @echo "TO_BIN = $(TO_BIN)" + @echo "TO_INC = $(TO_INC)" + @echo "TO_LIB = $(TO_LIB)" + @echo "TO_MAN = $(TO_MAN)" + +# echo config parameters as Lua code +# uncomment the last sed expression if you want nil instead of empty strings +lecho: + @echo "-- installation parameters for Lua $R" + @echo "VERSION = '$V'" + @echo "RELEASE = '$R'" + @$(MAKE) echo | grep = | sed -e 's/= /= "/' -e 's/$$/"/' #-e 's/""/nil/' + @echo "-- EOF" + +# list targets that do not create files (but not all makes understand .PHONY) +.PHONY: all $(PLATS) clean test install local none dummy echo pecho lecho + +# (end of Makefile) diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/README b/mod/pub.mod/lua.mod/lua-5.1.4/README new file mode 100644 index 0000000..11b4dff --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/README @@ -0,0 +1,37 @@ +README for Lua 5.1 + +See INSTALL for installation instructions. +See HISTORY for a summary of changes since the last released version. + +* What is Lua? + ------------ + Lua is a powerful, light-weight programming language designed for extending + applications. Lua is also frequently used as a general-purpose, stand-alone + language. Lua is free software. + + For complete information, visit Lua's web site at http://www.lua.org/ . + For an executive summary, see http://www.lua.org/about.html . + + Lua has been used in many different projects around the world. + For a short list, see http://www.lua.org/uses.html . + +* Availability + ------------ + Lua is freely available for both academic and commercial purposes. + See COPYRIGHT and http://www.lua.org/license.html for details. + Lua can be downloaded at http://www.lua.org/download.html . + +* Installation + ------------ + Lua is implemented in pure ANSI C, and compiles unmodified in all known + platforms that have an ANSI C compiler. In most Unix-like platforms, simply + do "make" with a suitable target. See INSTALL for detailed instructions. + +* Origin + ------ + Lua is developed at Lua.org, a laboratory of the Department of Computer + Science of PUC-Rio (the Pontifical Catholic University of Rio de Janeiro + in Brazil). + For more information about the authors, see http://www.lua.org/authors.html . + +(end of README) diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/doc/amazon.gif b/mod/pub.mod/lua.mod/lua-5.1.4/doc/amazon.gif new file mode 100644 index 0000000000000000000000000000000000000000..f2586d5765361bb8a33a72401449f3abdefe4e16 GIT binary patch literal 797 zcmV+&1LFKgNk%w1VOjtj0K^&q@9)h50%r{k3;+NBK0Y<5t#HiDnQw1j_x9wkua=aQ zf8O4{J3ExYz@^dAvgzr__o-L@ehvGQF7LT?@$1I#;Ij3_g2%_+^3u}mmw|9dEECm0Kc!X!@|#@3&?4Fr)=|m57&HqxlCDW&_KZ+1;`8vSj33YC_e@b zLW(B90kQ_n9Ds8N3z4jU4HiAyWz9`JYknO6suY&Mn*c`+`V13=EEIuKH*uwDKrGlz zo{tDTNaHR5yf%>5cyj}g-^zXgiM@QV=g%Gh303A)7B84EpbPvE-6X=O$DmxJ`b(9|4E82-m%Ds!U< zI=HL8TMx@{~>s4%C(a0wK8Wjd@n+|5vxOvSr(vuAh- z5-e0mzlK5u3lKm6pnB`22G3HYpfaDDC`;MbMg*4 b)M@9Pc;4WH3w-wJ=bwNED(Iksh5!INDePJ9 literal 0 HcmV?d00001 diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/doc/contents.html b/mod/pub.mod/lua.mod/lua-5.1.4/doc/contents.html new file mode 100644 index 0000000..8e58e18 --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/doc/contents.html @@ -0,0 +1,499 @@ + + + +Lua 5.1 Reference Manual - contents + + + + + + + +
      +

      + +Lua 5.1 Reference Manual +

      + +This is an online version of +
      + + + +Lua 5.1 Reference Manual +
      by R. Ierusalimschy, L. H. de Figueiredo, W. Celes +
      Lua.org, August 2006 +
      ISBN 85-903798-3-3 +
      +[Buy from Amazon] +
      +
      +

      + +Buy a copy of this book and +help to support +the Lua project. +

      + +The reference manual is the official definition of the Lua language. +For a complete introduction to Lua programming, see the book +Programming in Lua. +

      + +start +· +contents +· +index +· +portuguΓͺs +· +espaΓ±ol +


      + +Copyright © 2006-2008 Lua.org, PUC-Rio. +Freely available under the terms of the +Lua license. + +

      + +

      Contents

      + + +

      Index

      +
      Version1.25
      AuthorTecgraf,PUC-Rio
      LicenseMIT License
      ModserverBRL
      CreditAdapted for BlitzMax by Thomas Mayer, Noel Cower, Andreas Rozek and Simon Armstrong
      History1.25
      HistoryUpdated to Lua 5.1.4 - Htbaa
      History1.24
      Historyfixed int<->long discrepancies between Lua and BlitzMAX
      History1.23
      Historyseveral bugfixes and extensions
      Historysupport for strings with embedded ~0 (and byte arrays)
      Historymodifications for Lua 5.1.2
      Historysource code is now 'superstrict'-compliant
      Historyadded some documentation
      History1.22
      Historyadded lots of definitions to support most of the official Lua 5.1.1 API
      History1.21
      Historyremoved luac.c from build list
      History1.20
      Historyfixed missing paramters in lua_createtable definition
      History1.19
      Historyupdated with lua5.1.1 source
      History1.18
      Historyadded extra Imports and luaL_openlibs decl
      History1.17
      Historyadded luaL_loadstring fixed missing lua_dostring
      History1.16
      HistoryAdded lua_newtable as a BMax function
      HistoryChanged extern'd lua_newtable to lua_createtable
      HistoryAdded lua_load, lua_dostring and lua_dobuffer.
      History1.15 Release
      HistoryNew LUA 5.1 based build
      HistoryModified constants and added new wrappers for 5.1 compatability
      History1.14 Release
      HistoryAdded luaopen_debug and ldblib.c
      HistoryReplaced byte ptr with $z (CString) where a C string is expected
      History1.12 Release
      HistoryRemoved lua.h import
      + + + + + + +
      +

      Lua functions

      +_G
      +_VERSION
      +assert
      +collectgarbage
      +dofile
      +error
      +getfenv
      +getmetatable
      +ipairs
      +load
      +loadfile
      +loadstring
      +module
      +next
      +pairs
      +pcall
      +print
      +rawequal
      +rawget
      +rawset
      +require
      +select
      +setfenv
      +setmetatable
      +tonumber
      +tostring
      +type
      +unpack
      +xpcall
      +

      + +coroutine.create
      +coroutine.resume
      +coroutine.running
      +coroutine.status
      +coroutine.wrap
      +coroutine.yield
      +

      + +debug.debug
      +debug.getfenv
      +debug.gethook
      +debug.getinfo
      +debug.getlocal
      +debug.getmetatable
      +debug.getregistry
      +debug.getupvalue
      +debug.setfenv
      +debug.sethook
      +debug.setlocal
      +debug.setmetatable
      +debug.setupvalue
      +debug.traceback
      + +

      +

       

      +file:close
      +file:flush
      +file:lines
      +file:read
      +file:seek
      +file:setvbuf
      +file:write
      +

      + +io.close
      +io.flush
      +io.input
      +io.lines
      +io.open
      +io.output
      +io.popen
      +io.read
      +io.stderr
      +io.stdin
      +io.stdout
      +io.tmpfile
      +io.type
      +io.write
      +

      + +math.abs
      +math.acos
      +math.asin
      +math.atan
      +math.atan2
      +math.ceil
      +math.cos
      +math.cosh
      +math.deg
      +math.exp
      +math.floor
      +math.fmod
      +math.frexp
      +math.huge
      +math.ldexp
      +math.log
      +math.log10
      +math.max
      +math.min
      +math.modf
      +math.pi
      +math.pow
      +math.rad
      +math.random
      +math.randomseed
      +math.sin
      +math.sinh
      +math.sqrt
      +math.tan
      +math.tanh
      +

      + +os.clock
      +os.date
      +os.difftime
      +os.execute
      +os.exit
      +os.getenv
      +os.remove
      +os.rename
      +os.setlocale
      +os.time
      +os.tmpname
      +

      + +package.cpath
      +package.loaded
      +package.loaders
      +package.loadlib
      +package.path
      +package.preload
      +package.seeall
      +

      + +string.byte
      +string.char
      +string.dump
      +string.find
      +string.format
      +string.gmatch
      +string.gsub
      +string.len
      +string.lower
      +string.match
      +string.rep
      +string.reverse
      +string.sub
      +string.upper
      +

      + +table.concat
      +table.insert
      +table.maxn
      +table.remove
      +table.sort
      + +

      +

      C API

      +lua_Alloc
      +lua_CFunction
      +lua_Debug
      +lua_Hook
      +lua_Integer
      +lua_Number
      +lua_Reader
      +lua_State
      +lua_Writer
      +

      + +lua_atpanic
      +lua_call
      +lua_checkstack
      +lua_close
      +lua_concat
      +lua_cpcall
      +lua_createtable
      +lua_dump
      +lua_equal
      +lua_error
      +lua_gc
      +lua_getallocf
      +lua_getfenv
      +lua_getfield
      +lua_getglobal
      +lua_gethook
      +lua_gethookcount
      +lua_gethookmask
      +lua_getinfo
      +lua_getlocal
      +lua_getmetatable
      +lua_getstack
      +lua_gettable
      +lua_gettop
      +lua_getupvalue
      +lua_insert
      +lua_isboolean
      +lua_iscfunction
      +lua_isfunction
      +lua_islightuserdata
      +lua_isnil
      +lua_isnone
      +lua_isnoneornil
      +lua_isnumber
      +lua_isstring
      +lua_istable
      +lua_isthread
      +lua_isuserdata
      +lua_lessthan
      +lua_load
      +lua_newstate
      +lua_newtable
      +lua_newthread
      +lua_newuserdata
      +lua_next
      +lua_objlen
      +lua_pcall
      +lua_pop
      +lua_pushboolean
      +lua_pushcclosure
      +lua_pushcfunction
      +lua_pushfstring
      +lua_pushinteger
      +lua_pushlightuserdata
      +lua_pushliteral
      +lua_pushlstring
      +lua_pushnil
      +lua_pushnumber
      +lua_pushstring
      +lua_pushthread
      +lua_pushvalue
      +lua_pushvfstring
      +lua_rawequal
      +lua_rawget
      +lua_rawgeti
      +lua_rawset
      +lua_rawseti
      +lua_register
      +lua_remove
      +lua_replace
      +lua_resume
      +lua_setallocf
      +lua_setfenv
      +lua_setfield
      +lua_setglobal
      +lua_sethook
      +lua_setlocal
      +lua_setmetatable
      +lua_settable
      +lua_settop
      +lua_setupvalue
      +lua_status
      +lua_toboolean
      +lua_tocfunction
      +lua_tointeger
      +lua_tolstring
      +lua_tonumber
      +lua_topointer
      +lua_tostring
      +lua_tothread
      +lua_touserdata
      +lua_type
      +lua_typename
      +lua_upvalueindex
      +lua_xmove
      +lua_yield
      + +

      +

      auxiliary library

      +luaL_Buffer
      +luaL_Reg
      +

      + +luaL_addchar
      +luaL_addlstring
      +luaL_addsize
      +luaL_addstring
      +luaL_addvalue
      +luaL_argcheck
      +luaL_argerror
      +luaL_buffinit
      +luaL_callmeta
      +luaL_checkany
      +luaL_checkint
      +luaL_checkinteger
      +luaL_checklong
      +luaL_checklstring
      +luaL_checknumber
      +luaL_checkoption
      +luaL_checkstack
      +luaL_checkstring
      +luaL_checktype
      +luaL_checkudata
      +luaL_dofile
      +luaL_dostring
      +luaL_error
      +luaL_getmetafield
      +luaL_getmetatable
      +luaL_gsub
      +luaL_loadbuffer
      +luaL_loadfile
      +luaL_loadstring
      +luaL_newmetatable
      +luaL_newstate
      +luaL_openlibs
      +luaL_optint
      +luaL_optinteger
      +luaL_optlong
      +luaL_optlstring
      +luaL_optnumber
      +luaL_optstring
      +luaL_prepbuffer
      +luaL_pushresult
      +luaL_ref
      +luaL_register
      +luaL_typename
      +luaL_typerror
      +luaL_unref
      +luaL_where
      + +

      +

      + +


      + +Last update: +Sat Jan 19 13:24:29 BRST 2008 + + + + + diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/doc/cover.png b/mod/pub.mod/lua.mod/lua-5.1.4/doc/cover.png new file mode 100644 index 0000000000000000000000000000000000000000..2dbb198123f03a7250bfa57c8253739962d69afb GIT binary patch literal 3305 zcmVNc=P)V>IGcGYOVIUw=dB=aTYv^*htKxL4xjCf9X{I|EBQ!hu?+M>5oT>TE}0ye97P9R7S8qXycMFZ&6rBQl2xq6d5z1RT?1tMWggH(oGfxZ3MRwMW* zhWcm<0o+gGDNJLnwySJIYqTbnA(cT&JjHAh%b?&;aM%-PVunbF`4oU{acLCOU~~ed z=Xys9YZpo#i8bMPc#43D)u4sMGKqI^_da6LW&~0K*cO4+ z_PRNFEtj+pK65RYy#Eh+iK_)|A>ml%LRW(G?uWEPuP@)V__gB&q{E^1Drx0`;n)|1&{JZ#-e7eMcd1S~0(ChdB8 zS0!Ap-8R#X^0X5R7@pQ0wmH~jKhYj`l%C2tznfmz5?4vXD&s9-{r%L{8o|B1n{hn> zX-7F)1C|g{Fjw^QO3xSEM8WF{nF8))ijLB@AziK0j<-dAU&NHQAw-4j8oelO%2Dg_ z37hiyuBd>qbbcrr0xb~*rLW9q2cyBcq8kgCW9j_Jd}=!9R2g|I=9{KHXtr2}hFHKH zPZ!2Bg|$47mFu;Duqg$YQfQ4vD~-}9t!+atHYg~SbM=?ElxgB&vnLeLny@Jo1@}ra zw-%pO_5&GLRc)GAp8w;^w0pr+)}6{$xN2*=h1(z&s0B5@zOQ2Cj<++EgPm6D*KdLp^Jc$%i(A&wq1mn{*M;Pu$%2I-|s;8_q`68Jd zLJ$dITeas|8_h>+9GB??ksz(jj7@SsNq-j_f;Mf@l8W*L-v0vui)W9N64OhM7aV?n zo{!IxNC9-U@zPPgc8EYtsn)ggZ<}BOc#01{#gH6*gjm!cMXYMFiJ5! z$8SI7^a#mxl?1n2Bwr+veIkV`2fdd@*by0Naq>o!4A;Y!nrTV7gj#l-OAs* zvT_zQj8DKsyvuDrVn7=m8 z&;O0T{VN_DroW5Nu5jxvQZU%ZlLv@3)#xH@icfQd{R930nH<0P?=qQ<5s3ufc;l~s z^rLTdbhJn*9LK$Q@z$Gf{__VPoYQ~*AN<{S=xOJbXHXg;Sjdpd5Nq1FU!ZP(bkV*K z5BX<_uE(!VaN&B59T#f)0@ixmc3_}Kkful!<-+AYa=bk&rr9RA^GG2#cH|o2Jo3*;M^C0Z#I`l`S@(jjq^e|^t7&J*rAXei$y>%zrcxe zzKVokW{ylvDyoN%5F8rxOC(&6ljrfOA4aT&iHZA4RiB-iOg@n)*W;YNOgdZoU&C~Q zYvZ-d>YDjzn4Be*DQQDPBE@KZ$^kz7@cjMzsnv(*TI*A%M(*BC03b*t8J+ZR_jR(6 zttGy#T|b&jH^^6g-e(O?=xBjqSdb8D)Kd$tjjQa}6Izo*l=AOHBZzP@%TWj?-Z2yYmt`$ryp=SGWT>kg8zlLgEEs(4iVm;4Q>56I~!I5E_!W;Hjvwox?Uqoq) z@&EyI&Dg6UFbzN8)tb&2Y&=@c`Y|NW9`Pe8A!)AFN8A)Nk)Urp8ZM1e+_>zsWuw3Gwz#h*<|ZTYWyBV&rD^+OOrPXFnaE_T4H3gMI7NJvIPCeSU~lbZRURtjFJ3 zOtR_n9@p1NEV@-WX*<9pdwg@TE&lANPj7A1!>6YW%k<@shB-1^pOm#iGtfhChrf42 zsVsLR)XYafILOn7Dzbrs7oH##T<@vPK}ueH!cSN`F26lfqvKnrf9<;5xmTWYf?eG_ zeX!9}PBYlclLvflOw3@&T9Q?4=KSZAi+(6#NWSqr9j%R{qzT%*cARj9+M7Z={YZ`Z zkUIHTCXWs=UG`IipsSVd{5f`@zJAseNAl`14({FT2Xbx{9&lM)RVZ}_{lVes;w@a^N+fz49V zNXZM2^W9f`Rcp=JFX(8gt1f+0`B4G4?=d#PKzC_k7?Qz0y4x6=B$uz#sndjmeCtJC zJ5DgL%uYf!d*Z&jYQX0B2)f!R6lrVmT}CPC?c~T_GI?g_YxBM}hQWc|eD9k)^C*Fe z?D1?8AQoMD2D71Pn?G+{G@(R_)@FY(T|5yQo#5loxID%}wj5$qei{Hm5DK!lj~Ach z@X#`~XwB_uPF>*Z&(R#ISEvU#FA)Nz`TQED$+JgFvs?%)ll=n>_cNbnY=Y|(+?{11 zL&3o^iG=8GW2ldzK00F6PjxbRUOh&1<7lUfP!D<@?6{2FWT>x{XIvqi2CY#FPoWf2 zVo0P!tZu2v=D9u1zJZdTwyAHS9=M*uGC8uBNRUK|GgrvwmU;C8q`)+=EkZW7g=ru~ z6RQpkqkiq>Ru+?vAkXbSVK7dSLn?*gy_ zjjN{!SUh^+iEFRr=;K9At8qQ=c=~M}HT#)sT^Fg(`nT>?C{y%_^R>wBb&6$ nh%8`n`v3p{2XskIMF-Xh6%#iZwFs;u00000NkvXXu0mjfd@Wp4 literal 0 HcmV?d00001 diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/doc/logo.gif b/mod/pub.mod/lua.mod/lua-5.1.4/doc/logo.gif new file mode 100644 index 0000000000000000000000000000000000000000..2f5e4ac2e742fbb7675e739879211553758aea9c GIT binary patch literal 4232 zcmeH``9G8i;K!fm@ywWE@XWZzZ5SF?A>^uN#>^O6HI%DVL*tw8h1>$H%uPC0$QQ=txe!o}PX)Ev+jn>*nFZ-TC=<^76WcLZL(=DJm)| zEiIKwrInSHXU?3duCC_u@5try#>U2`rlw1mF15F}U%!66tE;QKyIUmcDJ<+QF77*W zFJd#&)VAl)kJ6K zi<>tmZ{3>g>+2gB7#JQNe(>OdLh;A=`1q42PbMZNCMPF*dXxhLZw3aYhlZwyhu@Bj z%#4n{d-Q1b$&i4QMce4L#8^!oMdw{PDnm4D66&3*dxX=-YIX6DQL_g`jbzkd4k zZDCoLf=%jL&vIeE zO=XcZ9fxt`f}-DQ^%H*PHMUs(JN%UWkI|Y8h9#6~I$Cw@{RqzO4&P-x;jHCPJ6Ks2 zoU%foi)nXd_sdkiuJa@@5J4RrreKfWSnz5>eMa5yTP=)16uu)TIdx~Fhho))6jZl) z($*i>QrIX4u}u3>m{WSn_ehkUGQ& zs})aUlTH1Cj1g3ZE3=MPXsSniEwJ{e6C3N#HjD=B4`8rWIsz!a7ecYpec?WuH+y?Wsm18^$cS4WmHhH3_=r zh*ILlm*X1dB^E5($KVl&zT524%l}vpHg%;Y+LezV_&TAJCmH`idhuj-n$4FZ)UE|jXLayXa-&O3Q z?Iyo!x*$5hD_HfFnDfGYj-RD|eIb7I?%>Y_kf%}Nbd`BXb4l1(Pc+}zoUR|9%_!7f zum2T;wbx&pohtI+&@~wm3nH9xLbOYkg*`phY~TK5iC#3tZNXo9s`cahx+8j2)rh5C zQgZh6D7Ekgib|hpdhxYf{r!PTJc z!vsYG@{hA}l5kL)g)0N_)(nC<*L0qdUi*3fD5<0sn58>zklX@6Tyv3*X^}m=Cqc40 zQ6GfjG@kd1mFIm`qaubWunm_?P>WUZ`9|f_z%gGHi{n|uu(N8!L=aw5(qAcDj$-QK zu;D#j6e42OXTQD>)i zlvM$LX`$n9EEjxM$_QDF&a z7cme_rat}aXmiN&7`6Q98}dh4Z@8L_uAb#nK&GQiZOOUnA9kAEVb-csuN1AWL=sXt z{z9GCN%%l0N9QvJM;tl1nf?rrhT{*sE%4WqR?{0~aIrfCcCPxf4eh_*jjQ=`$p53Y z@_|Rsx2i}|3dNFetMQQ5y8agTK-E0D&7;@3-LUxfvZ7 z7~!p@&mFe^oca2^F|CBt+4Ly?^ViUVSAhAH>JH1GN{^TQb3QnM*x0ZiZgDyNI@_c3 z@{}(WH4*e3T~}n_^0}da4ElIxAf9B!IaL7z9X0Icvj@cIkE*~W--17&WN`Ea5)Gn> z#gpfRb#44;jVTOS{FuaZgd(-ZD848=fQzgST2MxR>wSLc1P=2HDvByz$B$IsNCC6L zCM?nK*OHj6JA9gz4|b<~2%RqelN^1Y)jIqnRs!mDKV^BQTfo@hOtz7*Ug}Ee^cbsj zNNlumRgAmt`1$b5MO;&X#5-EP<}AaY;52ihIpem&MTea$?3!DrwbYa?V`NjEfWF3z zUq5JY8Ch;L{kx&J<1K&Fe_Vn;8gk{%c;n?nA2(%(f%DCRHko3uT~VI7RE^JWEqaCq z)i|%nfj(*4|V*XhY3W%M# z*yn6SN4eUOHFxAD7B&9E_PO`G5bqgs^@J{9bk>&;PlUAiqo`j3rjQDgD!}mqLUtb` zCB}ZD@m@s#pf7bV4jreOC*JVfHZ|hyHkX!rauVdd_I9FL45d{gWH!DNYu;i(|8wVx z!)eLY6YXxZ2{Coae0xuTnxo1ACb5wtED?VJAz&@114$Ao6uG9YSy*!K;m5_mj=0^j zw%?b%AOs}ql@$TGC-!^^*_#RT5+y_kTzQG9?LPPZNAtt6cJ%d2$q(I)ws21*?xF%p zN+NeGnWRQ<5w70Rc(bl|S0Xr&5@WrmdurS|IgPB|EyuZO#=tf!35)G!HJ`E1jh^lH zTBu~rL#DhQO*XAWtBt}JHH$lc>3%r0yD|maW_(W=B_J+y164F>O4dO|@&@N3Z3p=B zmVl{|^Z&#atHY|9n&la)SBo}=3AFIF=_~LDJk6MTlA73CXtX+4bnn+c!}N}IPa5pp zwyqbqIkN|I3j_3vD6$zlu{Ps(N-J|*qzEt<$5Soh;s^AuKv_ z-Tz+O1_~6*9CJh4r}`}mbUtjbf#fX58RIIkP6&@*y9kI|5fK*_eZ%jv3U$5*x<>D_ za2M(TV8?XY+9xy>0En#Te<6X4$0&dbyd(go$~eq4u(u)EA2msyF<5ssLZ zDP|I}=~Bi_q)whWv=Ri~L1TYaNrR;5cMB@s78HF1{w&r(6GJ;_2@bD?#1p&P4n_?n0#9Vx~$qjMX=Lk?*!@aKo8m&$iPO7S{g3sFUwr`*<53(68xx7?z`2xf# zGSicy_zI(PJ|%qc2VxT+6bOE--a{k&aq7$<<= zFt)C<@|TPs`+eycPGoGL1Wn9|Ed&a2JyAmjnkm3DQBECX&`bt~odH9cUPq4M{#$-q?G3!)qO-it*&YHw+j-O* zYy78V*`4Q=kQ@^Yz*b6Tal4(Me7BGeS^;phWAW8+L^5A(=D)t?k!rLIwVAKtq=f7h z&^n&VX1-T$ScvN~639QLZ^d@niMaS{C-Q)8oHHBhwD*r~-1Ze#Q)GFOFptW32a-uF z;M@ux%i%a25NwIgXt*=GHX$3~aZfwovGL!}sf?j9TsVo^cn(%&a<--0mIXYqGe>c PWz_J}_#7St0k8iB@FZjZ literal 0 HcmV?d00001 diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/doc/lua.1 b/mod/pub.mod/lua.mod/lua-5.1.4/doc/lua.1 new file mode 100644 index 0000000..24809cc --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/doc/lua.1 @@ -0,0 +1,163 @@ +.\" $Id: lua.man,v 1.11 2006/01/06 16:03:34 lhf Exp $ +.TH LUA 1 "$Date: 2006/01/06 16:03:34 $" +.SH NAME +lua \- Lua interpreter +.SH SYNOPSIS +.B lua +[ +.I options +] +[ +.I script +[ +.I args +] +] +.SH DESCRIPTION +.B lua +is the stand-alone Lua interpreter. +It loads and executes Lua programs, +either in textual source form or +in precompiled binary form. +(Precompiled binaries are output by +.BR luac , +the Lua compiler.) +.B lua +can be used as a batch interpreter and also interactively. +.LP +The given +.I options +(see below) +are executed and then +the Lua program in file +.I script +is loaded and executed. +The given +.I args +are available to +.I script +as strings in a global table named +.BR arg . +If these arguments contain spaces or other characters special to the shell, +then they should be quoted +(but note that the quotes will be removed by the shell). +The arguments in +.B arg +start at 0, +which contains the string +.RI ' script '. +The index of the last argument is stored in +.BR arg.n . +The arguments given in the command line before +.IR script , +including the name of the interpreter, +are available in negative indices in +.BR arg . +.LP +At the very start, +before even handling the command line, +.B lua +executes the contents of the environment variable +.BR LUA_INIT , +if it is defined. +If the value of +.B LUA_INIT +is of the form +.RI '@ filename ', +then +.I filename +is executed. +Otherwise, the string is assumed to be a Lua statement and is executed. +.LP +Options start with +.B '\-' +and are described below. +You can use +.B "'\--'" +to signal the end of options. +.LP +If no arguments are given, +then +.B "\-v \-i" +is assumed when the standard input is a terminal; +otherwise, +.B "\-" +is assumed. +.LP +In interactive mode, +.B lua +prompts the user, +reads lines from the standard input, +and executes them as they are read. +If a line does not contain a complete statement, +then a secondary prompt is displayed and +lines are read until a complete statement is formed or +a syntax error is found. +So, one way to interrupt the reading of an incomplete statement is +to force a syntax error: +adding a +.B ';' +in the middle of a statement is a sure way of forcing a syntax error +(except inside multiline strings and comments; these must be closed explicitly). +If a line starts with +.BR '=' , +then +.B lua +displays the values of all the expressions in the remainder of the +line. The expressions must be separated by commas. +The primary prompt is the value of the global variable +.BR _PROMPT , +if this value is a string; +otherwise, the default prompt is used. +Similarly, the secondary prompt is the value of the global variable +.BR _PROMPT2 . +So, +to change the prompts, +set the corresponding variable to a string of your choice. +You can do that after calling the interpreter +or on the command line +(but in this case you have to be careful with quotes +if the prompt string contains a space; otherwise you may confuse the shell.) +The default prompts are "> " and ">> ". +.SH OPTIONS +.TP +.B \- +load and execute the standard input as a file, +that is, +not interactively, +even when the standard input is a terminal. +.TP +.BI \-e " stat" +execute statement +.IR stat . +You need to quote +.I stat +if it contains spaces, quotes, +or other characters special to the shell. +.TP +.B \-i +enter interactive mode after +.I script +is executed. +.TP +.BI \-l " name" +call +.BI require(' name ') +before executing +.IR script . +Typically used to load libraries. +.TP +.B \-v +show version information. +.SH "SEE ALSO" +.BR luac (1) +.br +http://www.lua.org/ +.SH DIAGNOSTICS +Error messages should be self explanatory. +.SH AUTHORS +R. Ierusalimschy, +L. H. de Figueiredo, +and +W. Celes +.\" EOF diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/doc/lua.css b/mod/pub.mod/lua.mod/lua-5.1.4/doc/lua.css new file mode 100644 index 0000000..039cf11 --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/doc/lua.css @@ -0,0 +1,41 @@ +body { + color: #000000 ; + background-color: #FFFFFF ; + font-family: sans-serif ; + text-align: justify ; + margin-right: 20px ; + margin-left: 20px ; +} + +h1, h2, h3, h4 { + font-weight: normal ; + font-style: italic ; +} + +a:link { + color: #000080 ; + background-color: inherit ; + text-decoration: none ; +} + +a:visited { + background-color: inherit ; + text-decoration: none ; +} + +a:link:hover, a:visited:hover { + color: #000080 ; + background-color: #E0E0FF ; +} + +a:link:active, a:visited:active { + color: #FF0000 ; +} + +hr { + border: 0 ; + height: 1px ; + color: #a0a0a0 ; + background-color: #a0a0a0 ; +} + diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/doc/lua.html b/mod/pub.mod/lua.mod/lua-5.1.4/doc/lua.html new file mode 100644 index 0000000..1d435ab --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/doc/lua.html @@ -0,0 +1,172 @@ + + + +LUA man page + + + + + +

      NAME

      +lua - Lua interpreter +

      SYNOPSIS

      +lua +[ +options +] +[ +script +[ +args +] +] +

      DESCRIPTION

      +lua +is the stand-alone Lua interpreter. +It loads and executes Lua programs, +either in textual source form or +in precompiled binary form. +(Precompiled binaries are output by +luac, +the Lua compiler.) +lua +can be used as a batch interpreter and also interactively. +

      +The given +options +(see below) +are executed and then +the Lua program in file +script +is loaded and executed. +The given +args +are available to +script +as strings in a global table named +arg. +If these arguments contain spaces or other characters special to the shell, +then they should be quoted +(but note that the quotes will be removed by the shell). +The arguments in +arg +start at 0, +which contains the string +'script'. +The index of the last argument is stored in +arg.n. +The arguments given in the command line before +script, +including the name of the interpreter, +are available in negative indices in +arg. +

      +At the very start, +before even handling the command line, +lua +executes the contents of the environment variable +LUA_INIT, +if it is defined. +If the value of +LUA_INIT +is of the form +'@filename', +then +filename +is executed. +Otherwise, the string is assumed to be a Lua statement and is executed. +

      +Options start with +'-' +and are described below. +You can use +'--' +to signal the end of options. +

      +If no arguments are given, +then +"-v -i" +is assumed when the standard input is a terminal; +otherwise, +"-" +is assumed. +

      +In interactive mode, +lua +prompts the user, +reads lines from the standard input, +and executes them as they are read. +If a line does not contain a complete statement, +then a secondary prompt is displayed and +lines are read until a complete statement is formed or +a syntax error is found. +So, one way to interrupt the reading of an incomplete statement is +to force a syntax error: +adding a +';' +in the middle of a statement is a sure way of forcing a syntax error +(except inside multiline strings and comments; these must be closed explicitly). +If a line starts with +'=', +then +lua +displays the values of all the expressions in the remainder of the +line. The expressions must be separated by commas. +The primary prompt is the value of the global variable +_PROMPT, +if this value is a string; +otherwise, the default prompt is used. +Similarly, the secondary prompt is the value of the global variable +_PROMPT2. +So, +to change the prompts, +set the corresponding variable to a string of your choice. +You can do that after calling the interpreter +or on the command line +(but in this case you have to be careful with quotes +if the prompt string contains a space; otherwise you may confuse the shell.) +The default prompts are "> " and ">> ". +

      OPTIONS

      +

      +- +load and execute the standard input as a file, +that is, +not interactively, +even when the standard input is a terminal. +

      +-e stat +execute statement +stat. +You need to quote +stat +if it contains spaces, quotes, +or other characters special to the shell. +

      +-i +enter interactive mode after +script +is executed. +

      +-l name +call +require('name') +before executing +script. +Typically used to load libraries. +

      +-v +show version information. +

      SEE ALSO

      +luac(1) +
      +http://www.lua.org/ +

      DIAGNOSTICS

      +Error messages should be self explanatory. +

      AUTHORS

      +R. Ierusalimschy, +L. H. de Figueiredo, +and +W. Celes + + + diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/doc/luac.1 b/mod/pub.mod/lua.mod/lua-5.1.4/doc/luac.1 new file mode 100644 index 0000000..d814678 --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/doc/luac.1 @@ -0,0 +1,136 @@ +.\" $Id: luac.man,v 1.28 2006/01/06 16:03:34 lhf Exp $ +.TH LUAC 1 "$Date: 2006/01/06 16:03:34 $" +.SH NAME +luac \- Lua compiler +.SH SYNOPSIS +.B luac +[ +.I options +] [ +.I filenames +] +.SH DESCRIPTION +.B luac +is the Lua compiler. +It translates programs written in the Lua programming language +into binary files that can be later loaded and executed. +.LP +The main advantages of precompiling chunks are: +faster loading, +protecting source code from accidental user changes, +and +off-line syntax checking. +.LP +Pre-compiling does not imply faster execution +because in Lua chunks are always compiled into bytecodes before being executed. +.B luac +simply allows those bytecodes to be saved in a file for later execution. +.LP +Pre-compiled chunks are not necessarily smaller than the corresponding source. +The main goal in pre-compiling is faster loading. +.LP +The binary files created by +.B luac +are portable only among architectures with the same word size and byte order. +.LP +.B luac +produces a single output file containing the bytecodes +for all source files given. +By default, +the output file is named +.BR luac.out , +but you can change this with the +.B \-o +option. +.LP +In the command line, +you can mix +text files containing Lua source and +binary files containing precompiled chunks. +This is useful to combine several precompiled chunks, +even from different (but compatible) platforms, +into a single precompiled chunk. +.LP +You can use +.B "'\-'" +to indicate the standard input as a source file +and +.B "'\--'" +to signal the end of options +(that is, +all remaining arguments will be treated as files even if they start with +.BR "'\-'" ). +.LP +The internal format of the binary files produced by +.B luac +is likely to change when a new version of Lua is released. +So, +save the source files of all Lua programs that you precompile. +.LP +.SH OPTIONS +Options must be separate. +.TP +.B \-l +produce a listing of the compiled bytecode for Lua's virtual machine. +Listing bytecodes is useful to learn about Lua's virtual machine. +If no files are given, then +.B luac +loads +.B luac.out +and lists its contents. +.TP +.BI \-o " file" +output to +.IR file , +instead of the default +.BR luac.out . +(You can use +.B "'\-'" +for standard output, +but not on platforms that open standard output in text mode.) +The output file may be a source file because +all files are loaded before the output file is written. +Be careful not to overwrite precious files. +.TP +.B \-p +load files but do not generate any output file. +Used mainly for syntax checking and for testing precompiled chunks: +corrupted files will probably generate errors when loaded. +Lua always performs a thorough integrity test on precompiled chunks. +Bytecode that passes this test is completely safe, +in the sense that it will not break the interpreter. +However, +there is no guarantee that such code does anything sensible. +(None can be given, because the halting problem is unsolvable.) +If no files are given, then +.B luac +loads +.B luac.out +and tests its contents. +No messages are displayed if the file passes the integrity test. +.TP +.B \-s +strip debug information before writing the output file. +This saves some space in very large chunks, +but if errors occur when running a stripped chunk, +then the error messages may not contain the full information they usually do. +For instance, +line numbers and names of local variables are lost. +.TP +.B \-v +show version information. +.SH FILES +.TP 15 +.B luac.out +default output file +.SH "SEE ALSO" +.BR lua (1) +.br +http://www.lua.org/ +.SH DIAGNOSTICS +Error messages should be self explanatory. +.SH AUTHORS +L. H. de Figueiredo, +R. Ierusalimschy and +W. Celes +.\" EOF diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/doc/luac.html b/mod/pub.mod/lua.mod/lua-5.1.4/doc/luac.html new file mode 100644 index 0000000..179ffe8 --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/doc/luac.html @@ -0,0 +1,145 @@ + + + +LUAC man page + + + + + +

      NAME

      +luac - Lua compiler +

      SYNOPSIS

      +luac +[ +options +] [ +filenames +] +

      DESCRIPTION

      +luac +is the Lua compiler. +It translates programs written in the Lua programming language +into binary files that can be later loaded and executed. +

      +The main advantages of precompiling chunks are: +faster loading, +protecting source code from accidental user changes, +and +off-line syntax checking. +

      +Precompiling does not imply faster execution +because in Lua chunks are always compiled into bytecodes before being executed. +luac +simply allows those bytecodes to be saved in a file for later execution. +

      +Precompiled chunks are not necessarily smaller than the corresponding source. +The main goal in precompiling is faster loading. +

      +The binary files created by +luac +are portable only among architectures with the same word size and byte order. +

      +luac +produces a single output file containing the bytecodes +for all source files given. +By default, +the output file is named +luac.out, +but you can change this with the +-o +option. +

      +In the command line, +you can mix +text files containing Lua source and +binary files containing precompiled chunks. +This is useful because several precompiled chunks, +even from different (but compatible) platforms, +can be combined into a single precompiled chunk. +

      +You can use +'-' +to indicate the standard input as a source file +and +'--' +to signal the end of options +(that is, +all remaining arguments will be treated as files even if they start with +'-'). +

      +The internal format of the binary files produced by +luac +is likely to change when a new version of Lua is released. +So, +save the source files of all Lua programs that you precompile. +

      +

      OPTIONS

      +Options must be separate. +

      +-l +produce a listing of the compiled bytecode for Lua's virtual machine. +Listing bytecodes is useful to learn about Lua's virtual machine. +If no files are given, then +luac +loads +luac.out +and lists its contents. +

      +-o file +output to +file, +instead of the default +luac.out. +(You can use +'-' +for standard output, +but not on platforms that open standard output in text mode.) +The output file may be a source file because +all files are loaded before the output file is written. +Be careful not to overwrite precious files. +

      +-p +load files but do not generate any output file. +Used mainly for syntax checking and for testing precompiled chunks: +corrupted files will probably generate errors when loaded. +Lua always performs a thorough integrity test on precompiled chunks. +Bytecode that passes this test is completely safe, +in the sense that it will not break the interpreter. +However, +there is no guarantee that such code does anything sensible. +(None can be given, because the halting problem is unsolvable.) +If no files are given, then +luac +loads +luac.out +and tests its contents. +No messages are displayed if the file passes the integrity test. +

      +-s +strip debug information before writing the output file. +This saves some space in very large chunks, +but if errors occur when running a stripped chunk, +then the error messages may not contain the full information they usually do. +For instance, +line numbers and names of local variables are lost. +

      +-v +show version information. +

      FILES

      +

      +luac.out +default output file +

      SEE ALSO

      +lua(1) +
      +http://www.lua.org/ +

      DIAGNOSTICS

      +Error messages should be self explanatory. +

      AUTHORS

      +L. H. de Figueiredo, +R. Ierusalimschy and +W. Celes + + + diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/doc/manual.css b/mod/pub.mod/lua.mod/lua-5.1.4/doc/manual.css new file mode 100644 index 0000000..eed5afd --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/doc/manual.css @@ -0,0 +1,13 @@ +h3 code { + font-family: inherit ; +} + +pre { + font-size: 105% ; +} + +span.apii { + float: right ; + font-family: inherit ; +} + diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/doc/manual.html b/mod/pub.mod/lua.mod/lua-5.1.4/doc/manual.html new file mode 100644 index 0000000..f46f17c --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/doc/manual.html @@ -0,0 +1,8801 @@ + + + + +Lua 5.1 Reference Manual + + + + + + + +
      +

      + +Lua 5.1 Reference Manual +

      + +by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes +

      + +Copyright © 2006-2008 Lua.org, PUC-Rio. +Freely available under the terms of the +Lua license. + +


      +

      + +contents +· +index + + +

      + + + + + + +

      1 - Introduction

      + +

      +Lua is an extension programming language designed to support +general procedural programming with data description +facilities. +It also offers good support for object-oriented programming, +functional programming, and data-driven programming. +Lua is intended to be used as a powerful, light-weight +scripting language for any program that needs one. +Lua is implemented as a library, written in clean C +(that is, in the common subset of ANSI C and C++). + + +

      +Being an extension language, Lua has no notion of a "main" program: +it only works embedded in a host client, +called the embedding program or simply the host. +This host program can invoke functions to execute a piece of Lua code, +can write and read Lua variables, +and can register C functions to be called by Lua code. +Through the use of C functions, Lua can be augmented to cope with +a wide range of different domains, +thus creating customized programming languages sharing a syntactical framework. +The Lua distribution includes a sample host program called lua, +which uses the Lua library to offer a complete, stand-alone Lua interpreter. + + +

      +Lua is free software, +and is provided as usual with no guarantees, +as stated in its license. +The implementation described in this manual is available +at Lua's official web site, www.lua.org. + + +

      +Like any other reference manual, +this document is dry in places. +For a discussion of the decisions behind the design of Lua, +see the technical papers available at Lua's web site. +For a detailed introduction to programming in Lua, +see Roberto's book, Programming in Lua (Second Edition). + + + +

      2 - The Language

      + +

      +This section describes the lexis, the syntax, and the semantics of Lua. +In other words, +this section describes +which tokens are valid, +how they can be combined, +and what their combinations mean. + + +

      +The language constructs will be explained using the usual extended BNF notation, +in which +{a} means 0 or more a's, and +[a] means an optional a. +Non-terminals are shown like non-terminal, +keywords are shown like kword, +and other terminal symbols are shown like `=´. +The complete syntax of Lua can be found in §8 +at the end of this manual. + + + +

      2.1 - Lexical Conventions

      + +

      +Names +(also called identifiers) +in Lua can be any string of letters, +digits, and underscores, +not beginning with a digit. +This coincides with the definition of names in most languages. +(The definition of letter depends on the current locale: +any character considered alphabetic by the current locale +can be used in an identifier.) +Identifiers are used to name variables and table fields. + + +

      +The following keywords are reserved +and cannot be used as names: + + +

      +     and       break     do        else      elseif
      +     end       false     for       function  if
      +     in        local     nil       not       or
      +     repeat    return    then      true      until     while
      +
      + +

      +Lua is a case-sensitive language: +and is a reserved word, but And and AND +are two different, valid names. +As a convention, names starting with an underscore followed by +uppercase letters (such as _VERSION) +are reserved for internal global variables used by Lua. + + +

      +The following strings denote other tokens: + +

      +     +     -     *     /     %     ^     #
      +     ==    ~=    <=    >=    <     >     =
      +     (     )     {     }     [     ]
      +     ;     :     ,     .     ..    ...
      +
      + +

      +Literal strings +can be delimited by matching single or double quotes, +and can contain the following C-like escape sequences: +'\a' (bell), +'\b' (backspace), +'\f' (form feed), +'\n' (newline), +'\r' (carriage return), +'\t' (horizontal tab), +'\v' (vertical tab), +'\\' (backslash), +'\"' (quotation mark [double quote]), +and '\'' (apostrophe [single quote]). +Moreover, a backslash followed by a real newline +results in a newline in the string. +A character in a string can also be specified by its numerical value +using the escape sequence \ddd, +where ddd is a sequence of up to three decimal digits. +(Note that if a numerical escape is to be followed by a digit, +it must be expressed using exactly three digits.) +Strings in Lua can contain any 8-bit value, including embedded zeros, +which can be specified as '\0'. + + +

      +Literal strings can also be defined using a long format +enclosed by long brackets. +We define an opening long bracket of level n as an opening +square bracket followed by n equal signs followed by another +opening square bracket. +So, an opening long bracket of level 0 is written as [[, +an opening long bracket of level 1 is written as [=[, +and so on. +A closing long bracket is defined similarly; +for instance, a closing long bracket of level 4 is written as ]====]. +A long string starts with an opening long bracket of any level and +ends at the first closing long bracket of the same level. +Literals in this bracketed form can run for several lines, +do not interpret any escape sequences, +and ignore long brackets of any other level. +They can contain anything except a closing bracket of the proper level. + + +

      +For convenience, +when the opening long bracket is immediately followed by a newline, +the newline is not included in the string. +As an example, in a system using ASCII +(in which 'a' is coded as 97, +newline is coded as 10, and '1' is coded as 49), +the five literal strings below denote the same string: + +

      +     a = 'alo\n123"'
      +     a = "alo\n123\""
      +     a = '\97lo\10\04923"'
      +     a = [[alo
      +     123"]]
      +     a = [==[
      +     alo
      +     123"]==]
      +
      + +

      +A numerical constant can be written with an optional decimal part +and an optional decimal exponent. +Lua also accepts integer hexadecimal constants, +by prefixing them with 0x. +Examples of valid numerical constants are + +

      +     3   3.0   3.1416   314.16e-2   0.31416E1   0xff   0x56
      +
      + +

      +A comment starts with a double hyphen (--) +anywhere outside a string. +If the text immediately after -- is not an opening long bracket, +the comment is a short comment, +which runs until the end of the line. +Otherwise, it is a long comment, +which runs until the corresponding closing long bracket. +Long comments are frequently used to disable code temporarily. + + + + + +

      2.2 - Values and Types

      + +

      +Lua is a dynamically typed language. +This means that +variables do not have types; only values do. +There are no type definitions in the language. +All values carry their own type. + + +

      +All values in Lua are first-class values. +This means that all values can be stored in variables, +passed as arguments to other functions, and returned as results. + + +

      +There are eight basic types in Lua: +nil, boolean, number, +string, function, userdata, +thread, and table. +Nil is the type of the value nil, +whose main property is to be different from any other value; +it usually represents the absence of a useful value. +Boolean is the type of the values false and true. +Both nil and false make a condition false; +any other value makes it true. +Number represents real (double-precision floating-point) numbers. +(It is easy to build Lua interpreters that use other +internal representations for numbers, +such as single-precision float or long integers; +see file luaconf.h.) +String represents arrays of characters. + +Lua is 8-bit clean: +strings can contain any 8-bit character, +including embedded zeros ('\0') (see §2.1). + + +

      +Lua can call (and manipulate) functions written in Lua and +functions written in C +(see §2.5.8). + + +

      +The type userdata is provided to allow arbitrary C data to +be stored in Lua variables. +This type corresponds to a block of raw memory +and has no pre-defined operations in Lua, +except assignment and identity test. +However, by using metatables, +the programmer can define operations for userdata values +(see §2.8). +Userdata values cannot be created or modified in Lua, +only through the C API. +This guarantees the integrity of data owned by the host program. + + +

      +The type thread represents independent threads of execution +and it is used to implement coroutines (see §2.11). +Do not confuse Lua threads with operating-system threads. +Lua supports coroutines on all systems, +even those that do not support threads. + + +

      +The type table implements associative arrays, +that is, arrays that can be indexed not only with numbers, +but with any value (except nil). +Tables can be heterogeneous; +that is, they can contain values of all types (except nil). +Tables are the sole data structuring mechanism in Lua; +they can be used to represent ordinary arrays, +symbol tables, sets, records, graphs, trees, etc. +To represent records, Lua uses the field name as an index. +The language supports this representation by +providing a.name as syntactic sugar for a["name"]. +There are several convenient ways to create tables in Lua +(see §2.5.7). + + +

      +Like indices, +the value of a table field can be of any type (except nil). +In particular, +because functions are first-class values, +table fields can contain functions. +Thus tables can also carry methods (see §2.5.9). + + +

      +Tables, functions, threads, and (full) userdata values are objects: +variables do not actually contain these values, +only references to them. +Assignment, parameter passing, and function returns +always manipulate references to such values; +these operations do not imply any kind of copy. + + +

      +The library function type returns a string describing the type +of a given value. + + + +

      2.2.1 - Coercion

      + +

      +Lua provides automatic conversion between +string and number values at run time. +Any arithmetic operation applied to a string tries to convert +this string to a number, following the usual conversion rules. +Conversely, whenever a number is used where a string is expected, +the number is converted to a string, in a reasonable format. +For complete control over how numbers are converted to strings, +use the format function from the string library +(see string.format). + + + + + + + +

      2.3 - Variables

      + +

      +Variables are places that store values. + +There are three kinds of variables in Lua: +global variables, local variables, and table fields. + + +

      +A single name can denote a global variable or a local variable +(or a function's formal parameter, +which is a particular kind of local variable): + +

      +	var ::= Name
      +

      +Name denotes identifiers, as defined in §2.1. + + +

      +Any variable is assumed to be global unless explicitly declared +as a local (see §2.4.7). +Local variables are lexically scoped: +local variables can be freely accessed by functions +defined inside their scope (see §2.6). + + +

      +Before the first assignment to a variable, its value is nil. + + +

      +Square brackets are used to index a table: + +

      +	var ::= prefixexp `[´ exp `]´
      +

      +The meaning of accesses to global variables +and table fields can be changed via metatables. +An access to an indexed variable t[i] is equivalent to +a call gettable_event(t,i). +(See §2.8 for a complete description of the +gettable_event function. +This function is not defined or callable in Lua. +We use it here only for explanatory purposes.) + + +

      +The syntax var.Name is just syntactic sugar for +var["Name"]: + +

      +	var ::= prefixexp `.´ Name
      +
      + +

      +All global variables live as fields in ordinary Lua tables, +called environment tables or simply +environments (see §2.9). +Each function has its own reference to an environment, +so that all global variables in this function +will refer to this environment table. +When a function is created, +it inherits the environment from the function that created it. +To get the environment table of a Lua function, +you call getfenv. +To replace it, +you call setfenv. +(You can only manipulate the environment of C functions +through the debug library; (see §5.9).) + + +

      +An access to a global variable x +is equivalent to _env.x, +which in turn is equivalent to + +

      +     gettable_event(_env, "x")
      +

      +where _env is the environment of the running function. +(See §2.8 for a complete description of the +gettable_event function. +This function is not defined or callable in Lua. +Similarly, the _env variable is not defined in Lua. +We use them here only for explanatory purposes.) + + + + + +

      2.4 - Statements

      + +

      +Lua supports an almost conventional set of statements, +similar to those in Pascal or C. +This set includes +assignments, control structures, function calls, +and variable declarations. + + + +

      2.4.1 - Chunks

      + +

      +The unit of execution of Lua is called a chunk. +A chunk is simply a sequence of statements, +which are executed sequentially. +Each statement can be optionally followed by a semicolon: + +

      +	chunk ::= {stat [`;´]}
      +

      +There are no empty statements and thus ';;' is not legal. + + +

      +Lua handles a chunk as the body of an anonymous function +with a variable number of arguments +(see §2.5.9). +As such, chunks can define local variables, +receive arguments, and return values. + + +

      +A chunk can be stored in a file or in a string inside the host program. +To execute a chunk, +Lua first pre-compiles the chunk into instructions for a virtual machine, +and then it executes the compiled code +with an interpreter for the virtual machine. + + +

      +Chunks can also be pre-compiled into binary form; +see program luac for details. +Programs in source and compiled forms are interchangeable; +Lua automatically detects the file type and acts accordingly. + + + + + + +

      2.4.2 - Blocks

      +A block is a list of statements; +syntactically, a block is the same as a chunk: + +

      +	block ::= chunk
      +
      + +

      +A block can be explicitly delimited to produce a single statement: + +

      +	stat ::= do block end
      +

      +Explicit blocks are useful +to control the scope of variable declarations. +Explicit blocks are also sometimes used to +add a return or break statement in the middle +of another block (see §2.4.4). + + + + + +

      2.4.3 - Assignment

      + +

      +Lua allows multiple assignments. +Therefore, the syntax for assignment +defines a list of variables on the left side +and a list of expressions on the right side. +The elements in both lists are separated by commas: + +

      +	stat ::= varlist `=´ explist
      +	varlist ::= var {`,´ var}
      +	explist ::= exp {`,´ exp}
      +

      +Expressions are discussed in §2.5. + + +

      +Before the assignment, +the list of values is adjusted to the length of +the list of variables. +If there are more values than needed, +the excess values are thrown away. +If there are fewer values than needed, +the list is extended with as many nil's as needed. +If the list of expressions ends with a function call, +then all values returned by that call enter the list of values, +before the adjustment +(except when the call is enclosed in parentheses; see §2.5). + + +

      +The assignment statement first evaluates all its expressions +and only then are the assignments performed. +Thus the code + +

      +     i = 3
      +     i, a[i] = i+1, 20
      +

      +sets a[3] to 20, without affecting a[4] +because the i in a[i] is evaluated (to 3) +before it is assigned 4. +Similarly, the line + +

      +     x, y = y, x
      +

      +exchanges the values of x and y, +and + +

      +     x, y, z = y, z, x
      +

      +cyclically permutes the values of x, y, and z. + + +

      +The meaning of assignments to global variables +and table fields can be changed via metatables. +An assignment to an indexed variable t[i] = val is equivalent to +settable_event(t,i,val). +(See §2.8 for a complete description of the +settable_event function. +This function is not defined or callable in Lua. +We use it here only for explanatory purposes.) + + +

      +An assignment to a global variable x = val +is equivalent to the assignment +_env.x = val, +which in turn is equivalent to + +

      +     settable_event(_env, "x", val)
      +

      +where _env is the environment of the running function. +(The _env variable is not defined in Lua. +We use it here only for explanatory purposes.) + + + + + +

      2.4.4 - Control Structures

      +The control structures +if, while, and repeat have the usual meaning and +familiar syntax: + + + + +

      +	stat ::= while exp do block end
      +	stat ::= repeat block until exp
      +	stat ::= if exp then block {elseif exp then block} [else block] end
      +

      +Lua also has a for statement, in two flavors (see §2.4.5). + + +

      +The condition expression of a +control structure can return any value. +Both false and nil are considered false. +All values different from nil and false are considered true +(in particular, the number 0 and the empty string are also true). + + +

      +In the repeatuntil loop, +the inner block does not end at the until keyword, +but only after the condition. +So, the condition can refer to local variables +declared inside the loop block. + + +

      +The return statement is used to return values +from a function or a chunk (which is just a function). + +Functions and chunks can return more than one value, +and so the syntax for the return statement is + +

      +	stat ::= return [explist]
      +
      + +

      +The break statement is used to terminate the execution of a +while, repeat, or for loop, +skipping to the next statement after the loop: + + +

      +	stat ::= break
      +

      +A break ends the innermost enclosing loop. + + +

      +The return and break +statements can only be written as the last statement of a block. +If it is really necessary to return or break in the +middle of a block, +then an explicit inner block can be used, +as in the idioms +do return end and do break end, +because now return and break are the last statements in +their (inner) blocks. + + + + + +

      2.4.5 - For Statement

      + +

      + +The for statement has two forms: +one numeric and one generic. + + +

      +The numeric for loop repeats a block of code while a +control variable runs through an arithmetic progression. +It has the following syntax: + +

      +	stat ::= for Name `=´ exp `,´ exp [`,´ exp] do block end
      +

      +The block is repeated for name starting at the value of +the first exp, until it passes the second exp by steps of the +third exp. +More precisely, a for statement like + +

      +     for v = e1, e2, e3 do block end
      +

      +is equivalent to the code: + +

      +     do
      +       local var, limit, step = tonumber(e1), tonumber(e2), tonumber(e3)
      +       if not (var and limit and step) then error() end
      +       while (step > 0 and var <= limit) or (step <= 0 and var >= limit) do
      +         local v = var
      +         block
      +         var = var + step
      +       end
      +     end
      +

      +Note the following: + +

        + +
      • +All three control expressions are evaluated only once, +before the loop starts. +They must all result in numbers. +
      • + +
      • +var, limit, and step are invisible variables. +The names shown here are for explanatory purposes only. +
      • + +
      • +If the third expression (the step) is absent, +then a step of 1 is used. +
      • + +
      • +You can use break to exit a for loop. +
      • + +
      • +The loop variable v is local to the loop; +you cannot use its value after the for ends or is broken. +If you need this value, +assign it to another variable before breaking or exiting the loop. +
      • + +
      + +

      +The generic for statement works over functions, +called iterators. +On each iteration, the iterator function is called to produce a new value, +stopping when this new value is nil. +The generic for loop has the following syntax: + +

      +	stat ::= for namelist in explist do block end
      +	namelist ::= Name {`,´ Name}
      +

      +A for statement like + +

      +     for var_1, ···, var_n in explist do block end
      +

      +is equivalent to the code: + +

      +     do
      +       local f, s, var = explist
      +       while true do
      +         local var_1, ···, var_n = f(s, var)
      +         var = var_1
      +         if var == nil then break end
      +         block
      +       end
      +     end
      +

      +Note the following: + +

        + +
      • +explist is evaluated only once. +Its results are an iterator function, +a state, +and an initial value for the first iterator variable. +
      • + +
      • +f, s, and var are invisible variables. +The names are here for explanatory purposes only. +
      • + +
      • +You can use break to exit a for loop. +
      • + +
      • +The loop variables var_i are local to the loop; +you cannot use their values after the for ends. +If you need these values, +then assign them to other variables before breaking or exiting the loop. +
      • + +
      + + + + +

      2.4.6 - Function Calls as Statements

      +To allow possible side-effects, +function calls can be executed as statements: + +

      +	stat ::= functioncall
      +

      +In this case, all returned values are thrown away. +Function calls are explained in §2.5.8. + + + + + +

      2.4.7 - Local Declarations

      +Local variables can be declared anywhere inside a block. +The declaration can include an initial assignment: + +

      +	stat ::= local namelist [`=´ explist]
      +

      +If present, an initial assignment has the same semantics +of a multiple assignment (see §2.4.3). +Otherwise, all variables are initialized with nil. + + +

      +A chunk is also a block (see §2.4.1), +and so local variables can be declared in a chunk outside any explicit block. +The scope of such local variables extends until the end of the chunk. + + +

      +The visibility rules for local variables are explained in §2.6. + + + + + + + +

      2.5 - Expressions

      + +

      +The basic expressions in Lua are the following: + +

      +	exp ::= prefixexp
      +	exp ::= nil | false | true
      +	exp ::= Number
      +	exp ::= String
      +	exp ::= function
      +	exp ::= tableconstructor
      +	exp ::= `...´
      +	exp ::= exp binop exp
      +	exp ::= unop exp
      +	prefixexp ::= var | functioncall | `(´ exp `)´
      +
      + +

      +Numbers and literal strings are explained in §2.1; +variables are explained in §2.3; +function definitions are explained in §2.5.9; +function calls are explained in §2.5.8; +table constructors are explained in §2.5.7. +Vararg expressions, +denoted by three dots ('...'), can only be used when +directly inside a vararg function; +they are explained in §2.5.9. + + +

      +Binary operators comprise arithmetic operators (see §2.5.1), +relational operators (see §2.5.2), logical operators (see §2.5.3), +and the concatenation operator (see §2.5.4). +Unary operators comprise the unary minus (see §2.5.1), +the unary not (see §2.5.3), +and the unary length operator (see §2.5.5). + + +

      +Both function calls and vararg expressions can result in multiple values. +If an expression is used as a statement +(only possible for function calls (see §2.4.6)), +then its return list is adjusted to zero elements, +thus discarding all returned values. +If an expression is used as the last (or the only) element +of a list of expressions, +then no adjustment is made +(unless the call is enclosed in parentheses). +In all other contexts, +Lua adjusts the result list to one element, +discarding all values except the first one. + + +

      +Here are some examples: + +

      +     f()                -- adjusted to 0 results
      +     g(f(), x)          -- f() is adjusted to 1 result
      +     g(x, f())          -- g gets x plus all results from f()
      +     a,b,c = f(), x     -- f() is adjusted to 1 result (c gets nil)
      +     a,b = ...          -- a gets the first vararg parameter, b gets
      +                        -- the second (both a and b can get nil if there
      +                        -- is no corresponding vararg parameter)
      +     
      +     a,b,c = x, f()     -- f() is adjusted to 2 results
      +     a,b,c = f()        -- f() is adjusted to 3 results
      +     return f()         -- returns all results from f()
      +     return ...         -- returns all received vararg parameters
      +     return x,y,f()     -- returns x, y, and all results from f()
      +     {f()}              -- creates a list with all results from f()
      +     {...}              -- creates a list with all vararg parameters
      +     {f(), nil}         -- f() is adjusted to 1 result
      +
      + +

      +Any expression enclosed in parentheses always results in only one value. +Thus, +(f(x,y,z)) is always a single value, +even if f returns several values. +(The value of (f(x,y,z)) is the first value returned by f +or nil if f does not return any values.) + + + +

      2.5.1 - Arithmetic Operators

      +Lua supports the usual arithmetic operators: +the binary + (addition), +- (subtraction), * (multiplication), +/ (division), % (modulo), and ^ (exponentiation); +and unary - (negation). +If the operands are numbers, or strings that can be converted to +numbers (see §2.2.1), +then all operations have the usual meaning. +Exponentiation works for any exponent. +For instance, x^(-0.5) computes the inverse of the square root of x. +Modulo is defined as + +

      +     a % b == a - math.floor(a/b)*b
      +

      +That is, it is the remainder of a division that rounds +the quotient towards minus infinity. + + + + + +

      2.5.2 - Relational Operators

      +The relational operators in Lua are + +

      +     ==    ~=    <     >     <=    >=
      +

      +These operators always result in false or true. + + +

      +Equality (==) first compares the type of its operands. +If the types are different, then the result is false. +Otherwise, the values of the operands are compared. +Numbers and strings are compared in the usual way. +Objects (tables, userdata, threads, and functions) +are compared by reference: +two objects are considered equal only if they are the same object. +Every time you create a new object +(a table, userdata, thread, or function), +this new object is different from any previously existing object. + + +

      +You can change the way that Lua compares tables and userdata +by using the "eq" metamethod (see §2.8). + + +

      +The conversion rules of §2.2.1 +do not apply to equality comparisons. +Thus, "0"==0 evaluates to false, +and t[0] and t["0"] denote different +entries in a table. + + +

      +The operator ~= is exactly the negation of equality (==). + + +

      +The order operators work as follows. +If both arguments are numbers, then they are compared as such. +Otherwise, if both arguments are strings, +then their values are compared according to the current locale. +Otherwise, Lua tries to call the "lt" or the "le" +metamethod (see §2.8). +A comparison a > b is translated to b < a +and a >= b is translated to b <= a. + + + + + +

      2.5.3 - Logical Operators

      +The logical operators in Lua are +and, or, and not. +Like the control structures (see §2.4.4), +all logical operators consider both false and nil as false +and anything else as true. + + +

      +The negation operator not always returns false or true. +The conjunction operator and returns its first argument +if this value is false or nil; +otherwise, and returns its second argument. +The disjunction operator or returns its first argument +if this value is different from nil and false; +otherwise, or returns its second argument. +Both and and or use short-cut evaluation; +that is, +the second operand is evaluated only if necessary. +Here are some examples: + +

      +     10 or 20            --> 10
      +     10 or error()       --> 10
      +     nil or "a"          --> "a"
      +     nil and 10          --> nil
      +     false and error()   --> false
      +     false and nil       --> false
      +     false or nil        --> nil
      +     10 and 20           --> 20
      +

      +(In this manual, +--> indicates the result of the preceding expression.) + + + + + +

      2.5.4 - Concatenation

      +The string concatenation operator in Lua is +denoted by two dots ('..'). +If both operands are strings or numbers, then they are converted to +strings according to the rules mentioned in §2.2.1. +Otherwise, the "concat" metamethod is called (see §2.8). + + + + + +

      2.5.5 - The Length Operator

      + +

      +The length operator is denoted by the unary operator #. +The length of a string is its number of bytes +(that is, the usual meaning of string length when each +character is one byte). + + +

      +The length of a table t is defined to be any +integer index n +such that t[n] is not nil and t[n+1] is nil; +moreover, if t[1] is nil, n can be zero. +For a regular array, with non-nil values from 1 to a given n, +its length is exactly that n, +the index of its last value. +If the array has "holes" +(that is, nil values between other non-nil values), +then #t can be any of the indices that +directly precedes a nil value +(that is, it may consider any such nil value as the end of +the array). + + + + + +

      2.5.6 - Precedence

      +Operator precedence in Lua follows the table below, +from lower to higher priority: + +

      +     or
      +     and
      +     <     >     <=    >=    ~=    ==
      +     ..
      +     +     -
      +     *     /     %
      +     not   #     - (unary)
      +     ^
      +

      +As usual, +you can use parentheses to change the precedences of an expression. +The concatenation ('..') and exponentiation ('^') +operators are right associative. +All other binary operators are left associative. + + + + + +

      2.5.7 - Table Constructors

      +Table constructors are expressions that create tables. +Every time a constructor is evaluated, a new table is created. +A constructor can be used to create an empty table +or to create a table and initialize some of its fields. +The general syntax for constructors is + +

      +	tableconstructor ::= `{´ [fieldlist] `}´
      +	fieldlist ::= field {fieldsep field} [fieldsep]
      +	field ::= `[´ exp `]´ `=´ exp | Name `=´ exp | exp
      +	fieldsep ::= `,´ | `;´
      +
      + +

      +Each field of the form [exp1] = exp2 adds to the new table an entry +with key exp1 and value exp2. +A field of the form name = exp is equivalent to +["name"] = exp. +Finally, fields of the form exp are equivalent to +[i] = exp, where i are consecutive numerical integers, +starting with 1. +Fields in the other formats do not affect this counting. +For example, + +

      +     a = { [f(1)] = g; "x", "y"; x = 1, f(x), [30] = 23; 45 }
      +

      +is equivalent to + +

      +     do
      +       local t = {}
      +       t[f(1)] = g
      +       t[1] = "x"         -- 1st exp
      +       t[2] = "y"         -- 2nd exp
      +       t.x = 1            -- t["x"] = 1
      +       t[3] = f(x)        -- 3rd exp
      +       t[30] = 23
      +       t[4] = 45          -- 4th exp
      +       a = t
      +     end
      +
      + +

      +If the last field in the list has the form exp +and the expression is a function call or a vararg expression, +then all values returned by this expression enter the list consecutively +(see §2.5.8). +To avoid this, +enclose the function call or the vararg expression +in parentheses (see §2.5). + + +

      +The field list can have an optional trailing separator, +as a convenience for machine-generated code. + + + + + +

      2.5.8 - Function Calls

      +A function call in Lua has the following syntax: + +

      +	functioncall ::= prefixexp args
      +

      +In a function call, +first prefixexp and args are evaluated. +If the value of prefixexp has type function, +then this function is called +with the given arguments. +Otherwise, the prefixexp "call" metamethod is called, +having as first parameter the value of prefixexp, +followed by the original call arguments +(see §2.8). + + +

      +The form + +

      +	functioncall ::= prefixexp `:´ Name args
      +

      +can be used to call "methods". +A call v:name(args) +is syntactic sugar for v.name(v,args), +except that v is evaluated only once. + + +

      +Arguments have the following syntax: + +

      +	args ::= `(´ [explist] `)´
      +	args ::= tableconstructor
      +	args ::= String
      +

      +All argument expressions are evaluated before the call. +A call of the form f{fields} is +syntactic sugar for f({fields}); +that is, the argument list is a single new table. +A call of the form f'string' +(or f"string" or f[[string]]) +is syntactic sugar for f('string'); +that is, the argument list is a single literal string. + + +

      +As an exception to the free-format syntax of Lua, +you cannot put a line break before the '(' in a function call. +This restriction avoids some ambiguities in the language. +If you write + +

      +     a = f
      +     (g).x(a)
      +

      +Lua would see that as a single statement, a = f(g).x(a). +So, if you want two statements, you must add a semi-colon between them. +If you actually want to call f, +you must remove the line break before (g). + + +

      +A call of the form return functioncall is called +a tail call. +Lua implements proper tail calls +(or proper tail recursion): +in a tail call, +the called function reuses the stack entry of the calling function. +Therefore, there is no limit on the number of nested tail calls that +a program can execute. +However, a tail call erases any debug information about the +calling function. +Note that a tail call only happens with a particular syntax, +where the return has one single function call as argument; +this syntax makes the calling function return exactly +the returns of the called function. +So, none of the following examples are tail calls: + +

      +     return (f(x))        -- results adjusted to 1
      +     return 2 * f(x)
      +     return x, f(x)       -- additional results
      +     f(x); return         -- results discarded
      +     return x or f(x)     -- results adjusted to 1
      +
      + + + + +

      2.5.9 - Function Definitions

      + +

      +The syntax for function definition is + +

      +	function ::= function funcbody
      +	funcbody ::= `(´ [parlist] `)´ block end
      +
      + +

      +The following syntactic sugar simplifies function definitions: + +

      +	stat ::= function funcname funcbody
      +	stat ::= local function Name funcbody
      +	funcname ::= Name {`.´ Name} [`:´ Name]
      +

      +The statement + +

      +     function f () body end
      +

      +translates to + +

      +     f = function () body end
      +

      +The statement + +

      +     function t.a.b.c.f () body end
      +

      +translates to + +

      +     t.a.b.c.f = function () body end
      +

      +The statement + +

      +     local function f () body end
      +

      +translates to + +

      +     local f; f = function () body end
      +

      +not to + +

      +     local f = function () body end
      +

      +(This only makes a difference when the body of the function +contains references to f.) + + +

      +A function definition is an executable expression, +whose value has type function. +When Lua pre-compiles a chunk, +all its function bodies are pre-compiled too. +Then, whenever Lua executes the function definition, +the function is instantiated (or closed). +This function instance (or closure) +is the final value of the expression. +Different instances of the same function +can refer to different external local variables +and can have different environment tables. + + +

      +Parameters act as local variables that are +initialized with the argument values: + +

      +	parlist ::= namelist [`,´ `...´] | `...´
      +

      +When a function is called, +the list of arguments is adjusted to +the length of the list of parameters, +unless the function is a variadic or vararg function, +which is +indicated by three dots ('...') at the end of its parameter list. +A vararg function does not adjust its argument list; +instead, it collects all extra arguments and supplies them +to the function through a vararg expression, +which is also written as three dots. +The value of this expression is a list of all actual extra arguments, +similar to a function with multiple results. +If a vararg expression is used inside another expression +or in the middle of a list of expressions, +then its return list is adjusted to one element. +If the expression is used as the last element of a list of expressions, +then no adjustment is made +(unless that last expression is enclosed in parentheses). + + +

      +As an example, consider the following definitions: + +

      +     function f(a, b) end
      +     function g(a, b, ...) end
      +     function r() return 1,2,3 end
      +

      +Then, we have the following mapping from arguments to parameters and +to the vararg expression: + +

      +     CALL            PARAMETERS
      +     
      +     f(3)             a=3, b=nil
      +     f(3, 4)          a=3, b=4
      +     f(3, 4, 5)       a=3, b=4
      +     f(r(), 10)       a=1, b=10
      +     f(r())           a=1, b=2
      +     
      +     g(3)             a=3, b=nil, ... -->  (nothing)
      +     g(3, 4)          a=3, b=4,   ... -->  (nothing)
      +     g(3, 4, 5, 8)    a=3, b=4,   ... -->  5  8
      +     g(5, r())        a=5, b=1,   ... -->  2  3
      +
      + +

      +Results are returned using the return statement (see §2.4.4). +If control reaches the end of a function +without encountering a return statement, +then the function returns with no results. + + +

      +The colon syntax +is used for defining methods, +that is, functions that have an implicit extra parameter self. +Thus, the statement + +

      +     function t.a.b.c:f (params) body end
      +

      +is syntactic sugar for + +

      +     t.a.b.c.f = function (self, params) body end
      +
      + + + + + + +

      2.6 - Visibility Rules

      + +

      + +Lua is a lexically scoped language. +The scope of variables begins at the first statement after +their declaration and lasts until the end of the innermost block that +includes the declaration. +Consider the following example: + +

      +     x = 10                -- global variable
      +     do                    -- new block
      +       local x = x         -- new 'x', with value 10
      +       print(x)            --> 10
      +       x = x+1
      +       do                  -- another block
      +         local x = x+1     -- another 'x'
      +         print(x)          --> 12
      +       end
      +       print(x)            --> 11
      +     end
      +     print(x)              --> 10  (the global one)
      +
      + +

      +Notice that, in a declaration like local x = x, +the new x being declared is not in scope yet, +and so the second x refers to the outside variable. + + +

      +Because of the lexical scoping rules, +local variables can be freely accessed by functions +defined inside their scope. +A local variable used by an inner function is called +an upvalue, or external local variable, +inside the inner function. + + +

      +Notice that each execution of a local statement +defines new local variables. +Consider the following example: + +

      +     a = {}
      +     local x = 20
      +     for i=1,10 do
      +       local y = 0
      +       a[i] = function () y=y+1; return x+y end
      +     end
      +

      +The loop creates ten closures +(that is, ten instances of the anonymous function). +Each of these closures uses a different y variable, +while all of them share the same x. + + + + + +

      2.7 - Error Handling

      + +

      +Because Lua is an embedded extension language, +all Lua actions start from C code in the host program +calling a function from the Lua library (see lua_pcall). +Whenever an error occurs during Lua compilation or execution, +control returns to C, +which can take appropriate measures +(such as printing an error message). + + +

      +Lua code can explicitly generate an error by calling the +error function. +If you need to catch errors in Lua, +you can use the pcall function. + + + + + +

      2.8 - Metatables

      + +

      +Every value in Lua can have a metatable. +This metatable is an ordinary Lua table +that defines the behavior of the original value +under certain special operations. +You can change several aspects of the behavior +of operations over a value by setting specific fields in its metatable. +For instance, when a non-numeric value is the operand of an addition, +Lua checks for a function in the field "__add" in its metatable. +If it finds one, +Lua calls this function to perform the addition. + + +

      +We call the keys in a metatable events +and the values metamethods. +In the previous example, the event is "add" +and the metamethod is the function that performs the addition. + + +

      +You can query the metatable of any value +through the getmetatable function. + + +

      +You can replace the metatable of tables +through the setmetatable +function. +You cannot change the metatable of other types from Lua +(except by using the debug library); +you must use the C API for that. + + +

      +Tables and full userdata have individual metatables +(although multiple tables and userdata can share their metatables). +Values of all other types share one single metatable per type; +that is, there is one single metatable for all numbers, +one for all strings, etc. + + +

      +A metatable controls how an object behaves in arithmetic operations, +order comparisons, concatenation, length operation, and indexing. +A metatable also can define a function to be called when a userdata +is garbage collected. +For each of these operations Lua associates a specific key +called an event. +When Lua performs one of these operations over a value, +it checks whether this value has a metatable with the corresponding event. +If so, the value associated with that key (the metamethod) +controls how Lua will perform the operation. + + +

      +Metatables control the operations listed next. +Each operation is identified by its corresponding name. +The key for each operation is a string with its name prefixed by +two underscores, '__'; +for instance, the key for operation "add" is the +string "__add". +The semantics of these operations is better explained by a Lua function +describing how the interpreter executes the operation. + + +

      +The code shown here in Lua is only illustrative; +the real behavior is hard coded in the interpreter +and it is much more efficient than this simulation. +All functions used in these descriptions +(rawget, tonumber, etc.) +are described in §5.1. +In particular, to retrieve the metamethod of a given object, +we use the expression + +

      +     metatable(obj)[event]
      +

      +This should be read as + +

      +     rawget(getmetatable(obj) or {}, event)
      +

      + +That is, the access to a metamethod does not invoke other metamethods, +and the access to objects with no metatables does not fail +(it simply results in nil). + + + +

        + +
      • "add": +the + operation. + + + +

        +The function getbinhandler below defines how Lua chooses a handler +for a binary operation. +First, Lua tries the first operand. +If its type does not define a handler for the operation, +then Lua tries the second operand. + +

        +     function getbinhandler (op1, op2, event)
        +       return metatable(op1)[event] or metatable(op2)[event]
        +     end
        +

        +By using this function, +the behavior of the op1 + op2 is + +

        +     function add_event (op1, op2)
        +       local o1, o2 = tonumber(op1), tonumber(op2)
        +       if o1 and o2 then  -- both operands are numeric?
        +         return o1 + o2   -- '+' here is the primitive 'add'
        +       else  -- at least one of the operands is not numeric
        +         local h = getbinhandler(op1, op2, "__add")
        +         if h then
        +           -- call the handler with both operands
        +           return (h(op1, op2))
        +         else  -- no handler available: default behavior
        +           error(···)
        +         end
        +       end
        +     end
        +

        +

      • + +
      • "sub": +the - operation. + +Behavior similar to the "add" operation. +
      • + +
      • "mul": +the * operation. + +Behavior similar to the "add" operation. +
      • + +
      • "div": +the / operation. + +Behavior similar to the "add" operation. +
      • + +
      • "mod": +the % operation. + +Behavior similar to the "add" operation, +with the operation +o1 - floor(o1/o2)*o2 as the primitive operation. +
      • + +
      • "pow": +the ^ (exponentiation) operation. + +Behavior similar to the "add" operation, +with the function pow (from the C math library) +as the primitive operation. +
      • + +
      • "unm": +the unary - operation. + + +
        +     function unm_event (op)
        +       local o = tonumber(op)
        +       if o then  -- operand is numeric?
        +         return -o  -- '-' here is the primitive 'unm'
        +       else  -- the operand is not numeric.
        +         -- Try to get a handler from the operand
        +         local h = metatable(op).__unm
        +         if h then
        +           -- call the handler with the operand
        +           return (h(op))
        +         else  -- no handler available: default behavior
        +           error(···)
        +         end
        +       end
        +     end
        +

        +

      • + +
      • "concat": +the .. (concatenation) operation. + + +
        +     function concat_event (op1, op2)
        +       if (type(op1) == "string" or type(op1) == "number") and
        +          (type(op2) == "string" or type(op2) == "number") then
        +         return op1 .. op2  -- primitive string concatenation
        +       else
        +         local h = getbinhandler(op1, op2, "__concat")
        +         if h then
        +           return (h(op1, op2))
        +         else
        +           error(···)
        +         end
        +       end
        +     end
        +

        +

      • + +
      • "len": +the # operation. + + +
        +     function len_event (op)
        +       if type(op) == "string" then
        +         return strlen(op)         -- primitive string length
        +       elseif type(op) == "table" then
        +         return #op                -- primitive table length
        +       else
        +         local h = metatable(op).__len
        +         if h then
        +           -- call the handler with the operand
        +           return (h(op))
        +         else  -- no handler available: default behavior
        +           error(···)
        +         end
        +       end
        +     end
        +

        +See §2.5.5 for a description of the length of a table. +

      • + +
      • "eq": +the == operation. + +The function getcomphandler defines how Lua chooses a metamethod +for comparison operators. +A metamethod only is selected when both objects +being compared have the same type +and the same metamethod for the selected operation. + +
        +     function getcomphandler (op1, op2, event)
        +       if type(op1) ~= type(op2) then return nil end
        +       local mm1 = metatable(op1)[event]
        +       local mm2 = metatable(op2)[event]
        +       if mm1 == mm2 then return mm1 else return nil end
        +     end
        +

        +The "eq" event is defined as follows: + +

        +     function eq_event (op1, op2)
        +       if type(op1) ~= type(op2) then  -- different types?
        +         return false   -- different objects
        +       end
        +       if op1 == op2 then   -- primitive equal?
        +         return true   -- objects are equal
        +       end
        +       -- try metamethod
        +       local h = getcomphandler(op1, op2, "__eq")
        +       if h then
        +         return (h(op1, op2))
        +       else
        +         return false
        +       end
        +     end
        +

        +a ~= b is equivalent to not (a == b). +

      • + +
      • "lt": +the < operation. + + +
        +     function lt_event (op1, op2)
        +       if type(op1) == "number" and type(op2) == "number" then
        +         return op1 < op2   -- numeric comparison
        +       elseif type(op1) == "string" and type(op2) == "string" then
        +         return op1 < op2   -- lexicographic comparison
        +       else
        +         local h = getcomphandler(op1, op2, "__lt")
        +         if h then
        +           return (h(op1, op2))
        +         else
        +           error(···)
        +         end
        +       end
        +     end
        +

        +a > b is equivalent to b < a. +

      • + +
      • "le": +the <= operation. + + +
        +     function le_event (op1, op2)
        +       if type(op1) == "number" and type(op2) == "number" then
        +         return op1 <= op2   -- numeric comparison
        +       elseif type(op1) == "string" and type(op2) == "string" then
        +         return op1 <= op2   -- lexicographic comparison
        +       else
        +         local h = getcomphandler(op1, op2, "__le")
        +         if h then
        +           return (h(op1, op2))
        +         else
        +           h = getcomphandler(op1, op2, "__lt")
        +           if h then
        +             return not h(op2, op1)
        +           else
        +             error(···)
        +           end
        +         end
        +       end
        +     end
        +

        +a >= b is equivalent to b <= a. +Note that, in the absence of a "le" metamethod, +Lua tries the "lt", assuming that a <= b is +equivalent to not (b < a). +

      • + +
      • "index": +The indexing access table[key]. + + +
        +     function gettable_event (table, key)
        +       local h
        +       if type(table) == "table" then
        +         local v = rawget(table, key)
        +         if v ~= nil then return v end
        +         h = metatable(table).__index
        +         if h == nil then return nil end
        +       else
        +         h = metatable(table).__index
        +         if h == nil then
        +           error(···)
        +         end
        +       end
        +       if type(h) == "function" then
        +         return (h(table, key))     -- call the handler
        +       else return h[key]           -- or repeat operation on it
        +       end
        +     end
        +

        +

      • + +
      • "newindex": +The indexing assignment table[key] = value. + + +
        +     function settable_event (table, key, value)
        +       local h
        +       if type(table) == "table" then
        +         local v = rawget(table, key)
        +         if v ~= nil then rawset(table, key, value); return end
        +         h = metatable(table).__newindex
        +         if h == nil then rawset(table, key, value); return end
        +       else
        +         h = metatable(table).__newindex
        +         if h == nil then
        +           error(···)
        +         end
        +       end
        +       if type(h) == "function" then
        +         h(table, key,value)           -- call the handler
        +       else h[key] = value             -- or repeat operation on it
        +       end
        +     end
        +

        +

      • + +
      • "call": +called when Lua calls a value. + + +
        +     function function_event (func, ...)
        +       if type(func) == "function" then
        +         return func(...)   -- primitive call
        +       else
        +         local h = metatable(func).__call
        +         if h then
        +           return h(func, ...)
        +         else
        +           error(···)
        +         end
        +       end
        +     end
        +

        +

      • + +
      + + + + +

      2.9 - Environments

      + +

      +Besides metatables, +objects of types thread, function, and userdata +have another table associated with them, +called their environment. +Like metatables, environments are regular tables and +multiple objects can share the same environment. + + +

      +Threads are created sharing the environment of the creating thread. +Userdata and C functions are created sharing the environment +of the creating C function. +Non-nested Lua functions +(created by loadfile, loadstring or load) +are created sharing the environment of the creating thread. +Nested Lua functions are created sharing the environment of +the creating Lua function. + + +

      +Environments associated with userdata have no meaning for Lua. +It is only a convenience feature for programmers to associate a table to +a userdata. + + +

      +Environments associated with threads are called +global environments. +They are used as the default environment for threads and +non-nested Lua functions created by the thread +and can be directly accessed by C code (see §3.3). + + +

      +The environment associated with a C function can be directly +accessed by C code (see §3.3). +It is used as the default environment for other C functions +and userdata created by the function. + + +

      +Environments associated with Lua functions are used to resolve +all accesses to global variables within the function (see §2.3). +They are used as the default environment for nested Lua functions +created by the function. + + +

      +You can change the environment of a Lua function or the +running thread by calling setfenv. +You can get the environment of a Lua function or the running thread +by calling getfenv. +To manipulate the environment of other objects +(userdata, C functions, other threads) you must +use the C API. + + + + + +

      2.10 - Garbage Collection

      + +

      +Lua performs automatic memory management. +This means that +you have to worry neither about allocating memory for new objects +nor about freeing it when the objects are no longer needed. +Lua manages memory automatically by running +a garbage collector from time to time +to collect all dead objects +(that is, objects that are no longer accessible from Lua). +All memory used by Lua is subject to automatic management: +tables, userdata, functions, threads, strings, etc. + + +

      +Lua implements an incremental mark-and-sweep collector. +It uses two numbers to control its garbage-collection cycles: +the garbage-collector pause and +the garbage-collector step multiplier. +Both use percentage points as units +(so that a value of 100 means an internal value of 1). + + +

      +The garbage-collector pause +controls how long the collector waits before starting a new cycle. +Larger values make the collector less aggressive. +Values smaller than 100 mean the collector will not wait to +start a new cycle. +A value of 200 means that the collector waits for the total memory in use +to double before starting a new cycle. + + +

      +The step multiplier +controls the relative speed of the collector relative to +memory allocation. +Larger values make the collector more aggressive but also increase +the size of each incremental step. +Values smaller than 100 make the collector too slow and +can result in the collector never finishing a cycle. +The default, 200, means that the collector runs at "twice" +the speed of memory allocation. + + +

      +You can change these numbers by calling lua_gc in C +or collectgarbage in Lua. +With these functions you can also control +the collector directly (e.g., stop and restart it). + + + +

      2.10.1 - Garbage-Collection Metamethods

      + +

      +Using the C API, +you can set garbage-collector metamethods for userdata (see §2.8). +These metamethods are also called finalizers. +Finalizers allow you to coordinate Lua's garbage collection +with external resource management +(such as closing files, network or database connections, +or freeing your own memory). + + +

      +Garbage userdata with a field __gc in their metatables are not +collected immediately by the garbage collector. +Instead, Lua puts them in a list. +After the collection, +Lua does the equivalent of the following function +for each userdata in that list: + +

      +     function gc_event (udata)
      +       local h = metatable(udata).__gc
      +       if h then
      +         h(udata)
      +       end
      +     end
      +
      + +

      +At the end of each garbage-collection cycle, +the finalizers for userdata are called in reverse +order of their creation, +among those collected in that cycle. +That is, the first finalizer to be called is the one associated +with the userdata created last in the program. +The userdata itself is freed only in the next garbage-collection cycle. + + + + + +

      2.10.2 - Weak Tables

      + +

      +A weak table is a table whose elements are +weak references. +A weak reference is ignored by the garbage collector. +In other words, +if the only references to an object are weak references, +then the garbage collector will collect this object. + + +

      +A weak table can have weak keys, weak values, or both. +A table with weak keys allows the collection of its keys, +but prevents the collection of its values. +A table with both weak keys and weak values allows the collection of +both keys and values. +In any case, if either the key or the value is collected, +the whole pair is removed from the table. +The weakness of a table is controlled by the +__mode field of its metatable. +If the __mode field is a string containing the character 'k', +the keys in the table are weak. +If __mode contains 'v', +the values in the table are weak. + + +

      +After you use a table as a metatable, +you should not change the value of its __mode field. +Otherwise, the weak behavior of the tables controlled by this +metatable is undefined. + + + + + + + +

      2.11 - Coroutines

      + +

      +Lua supports coroutines, +also called collaborative multithreading. +A coroutine in Lua represents an independent thread of execution. +Unlike threads in multithread systems, however, +a coroutine only suspends its execution by explicitly calling +a yield function. + + +

      +You create a coroutine with a call to coroutine.create. +Its sole argument is a function +that is the main function of the coroutine. +The create function only creates a new coroutine and +returns a handle to it (an object of type thread); +it does not start the coroutine execution. + + +

      +When you first call coroutine.resume, +passing as its first argument +a thread returned by coroutine.create, +the coroutine starts its execution, +at the first line of its main function. +Extra arguments passed to coroutine.resume are passed on +to the coroutine main function. +After the coroutine starts running, +it runs until it terminates or yields. + + +

      +A coroutine can terminate its execution in two ways: +normally, when its main function returns +(explicitly or implicitly, after the last instruction); +and abnormally, if there is an unprotected error. +In the first case, coroutine.resume returns true, +plus any values returned by the coroutine main function. +In case of errors, coroutine.resume returns false +plus an error message. + + +

      +A coroutine yields by calling coroutine.yield. +When a coroutine yields, +the corresponding coroutine.resume returns immediately, +even if the yield happens inside nested function calls +(that is, not in the main function, +but in a function directly or indirectly called by the main function). +In the case of a yield, coroutine.resume also returns true, +plus any values passed to coroutine.yield. +The next time you resume the same coroutine, +it continues its execution from the point where it yielded, +with the call to coroutine.yield returning any extra +arguments passed to coroutine.resume. + + +

      +Like coroutine.create, +the coroutine.wrap function also creates a coroutine, +but instead of returning the coroutine itself, +it returns a function that, when called, resumes the coroutine. +Any arguments passed to this function +go as extra arguments to coroutine.resume. +coroutine.wrap returns all the values returned by coroutine.resume, +except the first one (the boolean error code). +Unlike coroutine.resume, +coroutine.wrap does not catch errors; +any error is propagated to the caller. + + +

      +As an example, +consider the following code: + +

      +     function foo (a)
      +       print("foo", a)
      +       return coroutine.yield(2*a)
      +     end
      +     
      +     co = coroutine.create(function (a,b)
      +           print("co-body", a, b)
      +           local r = foo(a+1)
      +           print("co-body", r)
      +           local r, s = coroutine.yield(a+b, a-b)
      +           print("co-body", r, s)
      +           return b, "end"
      +     end)
      +            
      +     print("main", coroutine.resume(co, 1, 10))
      +     print("main", coroutine.resume(co, "r"))
      +     print("main", coroutine.resume(co, "x", "y"))
      +     print("main", coroutine.resume(co, "x", "y"))
      +

      +When you run it, it produces the following output: + +

      +     co-body 1       10
      +     foo     2
      +     
      +     main    true    4
      +     co-body r
      +     main    true    11      -9
      +     co-body x       y
      +     main    true    10      end
      +     main    false   cannot resume dead coroutine
      +
      + + + + +

      3 - The Application Program Interface

      + +

      + +This section describes the C API for Lua, that is, +the set of C functions available to the host program to communicate +with Lua. +All API functions and related types and constants +are declared in the header file lua.h. + + +

      +Even when we use the term "function", +any facility in the API may be provided as a macro instead. +All such macros use each of their arguments exactly once +(except for the first argument, which is always a Lua state), +and so do not generate any hidden side-effects. + + +

      +As in most C libraries, +the Lua API functions do not check their arguments for validity or consistency. +However, you can change this behavior by compiling Lua +with a proper definition for the macro luai_apicheck, +in file luaconf.h. + + + +

      3.1 - The Stack

      + +

      +Lua uses a virtual stack to pass values to and from C. +Each element in this stack represents a Lua value +(nil, number, string, etc.). + + +

      +Whenever Lua calls C, the called function gets a new stack, +which is independent of previous stacks and of stacks of +C functions that are still active. +This stack initially contains any arguments to the C function +and it is where the C function pushes its results +to be returned to the caller (see lua_CFunction). + + +

      +For convenience, +most query operations in the API do not follow a strict stack discipline. +Instead, they can refer to any element in the stack +by using an index: +A positive index represents an absolute stack position +(starting at 1); +a negative index represents an offset relative to the top of the stack. +More specifically, if the stack has n elements, +then index 1 represents the first element +(that is, the element that was pushed onto the stack first) +and +index n represents the last element; +index -1 also represents the last element +(that is, the element at the top) +and index -n represents the first element. +We say that an index is valid +if it lies between 1 and the stack top +(that is, if 1 ≤ abs(index) ≤ top). + + + + + + +

      3.2 - Stack Size

      + +

      +When you interact with Lua API, +you are responsible for ensuring consistency. +In particular, +you are responsible for controlling stack overflow. +You can use the function lua_checkstack +to grow the stack size. + + +

      +Whenever Lua calls C, +it ensures that at least LUA_MINSTACK stack positions are available. +LUA_MINSTACK is defined as 20, +so that usually you do not have to worry about stack space +unless your code has loops pushing elements onto the stack. + + +

      +Most query functions accept as indices any value inside the +available stack space, that is, indices up to the maximum stack size +you have set through lua_checkstack. +Such indices are called acceptable indices. +More formally, we define an acceptable index +as follows: + +

      +     (index < 0 && abs(index) <= top) ||
      +     (index > 0 && index <= stackspace)
      +

      +Note that 0 is never an acceptable index. + + + + + +

      3.3 - Pseudo-Indices

      + +

      +Unless otherwise noted, +any function that accepts valid indices can also be called with +pseudo-indices, +which represent some Lua values that are accessible to C code +but which are not in the stack. +Pseudo-indices are used to access the thread environment, +the function environment, +the registry, +and the upvalues of a C function (see §3.4). + + +

      +The thread environment (where global variables live) is +always at pseudo-index LUA_GLOBALSINDEX. +The environment of the running C function is always +at pseudo-index LUA_ENVIRONINDEX. + + +

      +To access and change the value of global variables, +you can use regular table operations over an environment table. +For instance, to access the value of a global variable, do + +

      +     lua_getfield(L, LUA_GLOBALSINDEX, varname);
      +
      + + + + +

      3.4 - C Closures

      + +

      +When a C function is created, +it is possible to associate some values with it, +thus creating a C closure; +these values are called upvalues and are +accessible to the function whenever it is called +(see lua_pushcclosure). + + +

      +Whenever a C function is called, +its upvalues are located at specific pseudo-indices. +These pseudo-indices are produced by the macro +lua_upvalueindex. +The first value associated with a function is at position +lua_upvalueindex(1), and so on. +Any access to lua_upvalueindex(n), +where n is greater than the number of upvalues of the +current function (but not greater than 256), +produces an acceptable (but invalid) index. + + + + + +

      3.5 - Registry

      + +

      +Lua provides a registry, +a pre-defined table that can be used by any C code to +store whatever Lua value it needs to store. +This table is always located at pseudo-index +LUA_REGISTRYINDEX. +Any C library can store data into this table, +but it should take care to choose keys different from those used +by other libraries, to avoid collisions. +Typically, you should use as key a string containing your library name +or a light userdata with the address of a C object in your code. + + +

      +The integer keys in the registry are used by the reference mechanism, +implemented by the auxiliary library, +and therefore should not be used for other purposes. + + + + + +

      3.6 - Error Handling in C

      + +

      +Internally, Lua uses the C longjmp facility to handle errors. +(You can also choose to use exceptions if you use C++; +see file luaconf.h.) +When Lua faces any error +(such as memory allocation errors, type errors, syntax errors, +and runtime errors) +it raises an error; +that is, it does a long jump. +A protected environment uses setjmp +to set a recover point; +any error jumps to the most recent active recover point. + + +

      +Most functions in the API can throw an error, +for instance due to a memory allocation error. +The documentation for each function indicates whether +it can throw errors. + + +

      +Inside a C function you can throw an error by calling lua_error. + + + + + +

      3.7 - Functions and Types

      + +

      +Here we list all functions and types from the C API in +alphabetical order. +Each function has an indicator like this: +[-o, +p, x] + + +

      +The first field, o, +is how many elements the function pops from the stack. +The second field, p, +is how many elements the function pushes onto the stack. +(Any function always pushes its results after popping its arguments.) +A field in the form x|y means the function can push (or pop) +x or y elements, +depending on the situation; +an interrogation mark '?' means that +we cannot know how many elements the function pops/pushes +by looking only at its arguments +(e.g., they may depend on what is on the stack). +The third field, x, +tells whether the function may throw errors: +'-' means the function never throws any error; +'m' means the function may throw an error +only due to not enough memory; +'e' means the function may throw other kinds of errors; +'v' means the function may throw an error on purpose. + + + +


      lua_Alloc

      +
      typedef void * (*lua_Alloc) (void *ud,
      +                             void *ptr,
      +                             size_t osize,
      +                             size_t nsize);
      + +

      +The type of the memory-allocation function used by Lua states. +The allocator function must provide a +functionality similar to realloc, +but not exactly the same. +Its arguments are +ud, an opaque pointer passed to lua_newstate; +ptr, a pointer to the block being allocated/reallocated/freed; +osize, the original size of the block; +nsize, the new size of the block. +ptr is NULL if and only if osize is zero. +When nsize is zero, the allocator must return NULL; +if osize is not zero, +it should free the block pointed to by ptr. +When nsize is not zero, the allocator returns NULL +if and only if it cannot fill the request. +When nsize is not zero and osize is zero, +the allocator should behave like malloc. +When nsize and osize are not zero, +the allocator behaves like realloc. +Lua assumes that the allocator never fails when +osize >= nsize. + + +

      +Here is a simple implementation for the allocator function. +It is used in the auxiliary library by luaL_newstate. + +

      +     static void *l_alloc (void *ud, void *ptr, size_t osize,
      +                                                size_t nsize) {
      +       (void)ud;  (void)osize;  /* not used */
      +       if (nsize == 0) {
      +         free(ptr);
      +         return NULL;
      +       }
      +       else
      +         return realloc(ptr, nsize);
      +     }
      +

      +This code assumes +that free(NULL) has no effect and that +realloc(NULL, size) is equivalent to malloc(size). +ANSI C ensures both behaviors. + + + + + +


      lua_atpanic

      +[-0, +0, -] +

      lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf);
      + +

      +Sets a new panic function and returns the old one. + + +

      +If an error happens outside any protected environment, +Lua calls a panic function +and then calls exit(EXIT_FAILURE), +thus exiting the host application. +Your panic function can avoid this exit by +never returning (e.g., doing a long jump). + + +

      +The panic function can access the error message at the top of the stack. + + + + + +


      lua_call

      +[-(nargs + 1), +nresults, e] +

      void lua_call (lua_State *L, int nargs, int nresults);
      + +

      +Calls a function. + + +

      +To call a function you must use the following protocol: +first, the function to be called is pushed onto the stack; +then, the arguments to the function are pushed +in direct order; +that is, the first argument is pushed first. +Finally you call lua_call; +nargs is the number of arguments that you pushed onto the stack. +All arguments and the function value are popped from the stack +when the function is called. +The function results are pushed onto the stack when the function returns. +The number of results is adjusted to nresults, +unless nresults is LUA_MULTRET. +In this case, all results from the function are pushed. +Lua takes care that the returned values fit into the stack space. +The function results are pushed onto the stack in direct order +(the first result is pushed first), +so that after the call the last result is on the top of the stack. + + +

      +Any error inside the called function is propagated upwards +(with a longjmp). + + +

      +The following example shows how the host program can do the +equivalent to this Lua code: + +

      +     a = f("how", t.x, 14)
      +

      +Here it is in C: + +

      +     lua_getfield(L, LUA_GLOBALSINDEX, "f"); /* function to be called */
      +     lua_pushstring(L, "how");                        /* 1st argument */
      +     lua_getfield(L, LUA_GLOBALSINDEX, "t");   /* table to be indexed */
      +     lua_getfield(L, -1, "x");        /* push result of t.x (2nd arg) */
      +     lua_remove(L, -2);                  /* remove 't' from the stack */
      +     lua_pushinteger(L, 14);                          /* 3rd argument */
      +     lua_call(L, 3, 1);     /* call 'f' with 3 arguments and 1 result */
      +     lua_setfield(L, LUA_GLOBALSINDEX, "a");        /* set global 'a' */
      +

      +Note that the code above is "balanced": +at its end, the stack is back to its original configuration. +This is considered good programming practice. + + + + + +


      lua_CFunction

      +
      typedef int (*lua_CFunction) (lua_State *L);
      + +

      +Type for C functions. + + +

      +In order to communicate properly with Lua, +a C function must use the following protocol, +which defines the way parameters and results are passed: +a C function receives its arguments from Lua in its stack +in direct order (the first argument is pushed first). +So, when the function starts, +lua_gettop(L) returns the number of arguments received by the function. +The first argument (if any) is at index 1 +and its last argument is at index lua_gettop(L). +To return values to Lua, a C function just pushes them onto the stack, +in direct order (the first result is pushed first), +and returns the number of results. +Any other value in the stack below the results will be properly +discarded by Lua. +Like a Lua function, a C function called by Lua can also return +many results. + + +

      +As an example, the following function receives a variable number +of numerical arguments and returns their average and sum: + +

      +     static int foo (lua_State *L) {
      +       int n = lua_gettop(L);    /* number of arguments */
      +       lua_Number sum = 0;
      +       int i;
      +       for (i = 1; i <= n; i++) {
      +         if (!lua_isnumber(L, i)) {
      +           lua_pushstring(L, "incorrect argument");
      +           lua_error(L);
      +         }
      +         sum += lua_tonumber(L, i);
      +       }
      +       lua_pushnumber(L, sum/n);        /* first result */
      +       lua_pushnumber(L, sum);         /* second result */
      +       return 2;                   /* number of results */
      +     }
      +
      + + + + +

      lua_checkstack

      +[-0, +0, m] +

      int lua_checkstack (lua_State *L, int extra);
      + +

      +Ensures that there are at least extra free stack slots in the stack. +It returns false if it cannot grow the stack to that size. +This function never shrinks the stack; +if the stack is already larger than the new size, +it is left unchanged. + + + + + +


      lua_close

      +[-0, +0, -] +

      void lua_close (lua_State *L);
      + +

      +Destroys all objects in the given Lua state +(calling the corresponding garbage-collection metamethods, if any) +and frees all dynamic memory used by this state. +On several platforms, you may not need to call this function, +because all resources are naturally released when the host program ends. +On the other hand, long-running programs, +such as a daemon or a web server, +might need to release states as soon as they are not needed, +to avoid growing too large. + + + + + +


      lua_concat

      +[-n, +1, e] +

      void lua_concat (lua_State *L, int n);
      + +

      +Concatenates the n values at the top of the stack, +pops them, and leaves the result at the top. +If n is 1, the result is the single value on the stack +(that is, the function does nothing); +if n is 0, the result is the empty string. +Concatenation is performed following the usual semantics of Lua +(see §2.5.4). + + + + + +


      lua_cpcall

      +[-0, +(0|1), -] +

      int lua_cpcall (lua_State *L, lua_CFunction func, void *ud);
      + +

      +Calls the C function func in protected mode. +func starts with only one element in its stack, +a light userdata containing ud. +In case of errors, +lua_cpcall returns the same error codes as lua_pcall, +plus the error object on the top of the stack; +otherwise, it returns zero, and does not change the stack. +All values returned by func are discarded. + + + + + +


      lua_createtable

      +[-0, +1, m] +

      void lua_createtable (lua_State *L, int narr, int nrec);
      + +

      +Creates a new empty table and pushes it onto the stack. +The new table has space pre-allocated +for narr array elements and nrec non-array elements. +This pre-allocation is useful when you know exactly how many elements +the table will have. +Otherwise you can use the function lua_newtable. + + + + + +


      lua_dump

      +[-0, +0, m] +

      int lua_dump (lua_State *L, lua_Writer writer, void *data);
      + +

      +Dumps a function as a binary chunk. +Receives a Lua function on the top of the stack +and produces a binary chunk that, +if loaded again, +results in a function equivalent to the one dumped. +As it produces parts of the chunk, +lua_dump calls function writer (see lua_Writer) +with the given data +to write them. + + +

      +The value returned is the error code returned by the last +call to the writer; +0 means no errors. + + +

      +This function does not pop the Lua function from the stack. + + + + + +


      lua_equal

      +[-0, +0, e] +

      int lua_equal (lua_State *L, int index1, int index2);
      + +

      +Returns 1 if the two values in acceptable indices index1 and +index2 are equal, +following the semantics of the Lua == operator +(that is, may call metamethods). +Otherwise returns 0. +Also returns 0 if any of the indices is non valid. + + + + + +


      lua_error

      +[-1, +0, v] +

      int lua_error (lua_State *L);
      + +

      +Generates a Lua error. +The error message (which can actually be a Lua value of any type) +must be on the stack top. +This function does a long jump, +and therefore never returns. +(see luaL_error). + + + + + +


      lua_gc

      +[-0, +0, e] +

      int lua_gc (lua_State *L, int what, int data);
      + +

      +Controls the garbage collector. + + +

      +This function performs several tasks, +according to the value of the parameter what: + +

        + +
      • LUA_GCSTOP: +stops the garbage collector. +
      • + +
      • LUA_GCRESTART: +restarts the garbage collector. +
      • + +
      • LUA_GCCOLLECT: +performs a full garbage-collection cycle. +
      • + +
      • LUA_GCCOUNT: +returns the current amount of memory (in Kbytes) in use by Lua. +
      • + +
      • LUA_GCCOUNTB: +returns the remainder of dividing the current amount of bytes of +memory in use by Lua by 1024. +
      • + +
      • LUA_GCSTEP: +performs an incremental step of garbage collection. +The step "size" is controlled by data +(larger values mean more steps) in a non-specified way. +If you want to control the step size +you must experimentally tune the value of data. +The function returns 1 if the step finished a +garbage-collection cycle. +
      • + +
      • LUA_GCSETPAUSE: +sets data as the new value +for the pause of the collector (see §2.10). +The function returns the previous value of the pause. +
      • + +
      • LUA_GCSETSTEPMUL: +sets data as the new value for the step multiplier of +the collector (see §2.10). +The function returns the previous value of the step multiplier. +
      • + +
      + + + + +

      lua_getallocf

      +[-0, +0, -] +

      lua_Alloc lua_getallocf (lua_State *L, void **ud);
      + +

      +Returns the memory-allocation function of a given state. +If ud is not NULL, Lua stores in *ud the +opaque pointer passed to lua_newstate. + + + + + +


      lua_getfenv

      +[-0, +1, -] +

      void lua_getfenv (lua_State *L, int index);
      + +

      +Pushes onto the stack the environment table of +the value at the given index. + + + + + +


      lua_getfield

      +[-0, +1, e] +

      void lua_getfield (lua_State *L, int index, const char *k);
      + +

      +Pushes onto the stack the value t[k], +where t is the value at the given valid index. +As in Lua, this function may trigger a metamethod +for the "index" event (see §2.8). + + + + + +


      lua_getglobal

      +[-0, +1, e] +

      void lua_getglobal (lua_State *L, const char *name);
      + +

      +Pushes onto the stack the value of the global name. +It is defined as a macro: + +

      +     #define lua_getglobal(L,s)  lua_getfield(L, LUA_GLOBALSINDEX, s)
      +
      + + + + +

      lua_getmetatable

      +[-0, +(0|1), -] +

      int lua_getmetatable (lua_State *L, int index);
      + +

      +Pushes onto the stack the metatable of the value at the given +acceptable index. +If the index is not valid, +or if the value does not have a metatable, +the function returns 0 and pushes nothing on the stack. + + + + + +


      lua_gettable

      +[-1, +1, e] +

      void lua_gettable (lua_State *L, int index);
      + +

      +Pushes onto the stack the value t[k], +where t is the value at the given valid index +and k is the value at the top of the stack. + + +

      +This function pops the key from the stack +(putting the resulting value in its place). +As in Lua, this function may trigger a metamethod +for the "index" event (see §2.8). + + + + + +


      lua_gettop

      +[-0, +0, -] +

      int lua_gettop (lua_State *L);
      + +

      +Returns the index of the top element in the stack. +Because indices start at 1, +this result is equal to the number of elements in the stack +(and so 0 means an empty stack). + + + + + +


      lua_insert

      +[-1, +1, -] +

      void lua_insert (lua_State *L, int index);
      + +

      +Moves the top element into the given valid index, +shifting up the elements above this index to open space. +Cannot be called with a pseudo-index, +because a pseudo-index is not an actual stack position. + + + + + +


      lua_Integer

      +
      typedef ptrdiff_t lua_Integer;
      + +

      +The type used by the Lua API to represent integral values. + + +

      +By default it is a ptrdiff_t, +which is usually the largest signed integral type the machine handles +"comfortably". + + + + + +


      lua_isboolean

      +[-0, +0, -] +

      int lua_isboolean (lua_State *L, int index);
      + +

      +Returns 1 if the value at the given acceptable index has type boolean, +and 0 otherwise. + + + + + +


      lua_iscfunction

      +[-0, +0, -] +

      int lua_iscfunction (lua_State *L, int index);
      + +

      +Returns 1 if the value at the given acceptable index is a C function, +and 0 otherwise. + + + + + +


      lua_isfunction

      +[-0, +0, -] +

      int lua_isfunction (lua_State *L, int index);
      + +

      +Returns 1 if the value at the given acceptable index is a function +(either C or Lua), and 0 otherwise. + + + + + +


      lua_islightuserdata

      +[-0, +0, -] +

      int lua_islightuserdata (lua_State *L, int index);
      + +

      +Returns 1 if the value at the given acceptable index is a light userdata, +and 0 otherwise. + + + + + +


      lua_isnil

      +[-0, +0, -] +

      int lua_isnil (lua_State *L, int index);
      + +

      +Returns 1 if the value at the given acceptable index is nil, +and 0 otherwise. + + + + + +


      lua_isnone

      +[-0, +0, -] +

      int lua_isnone (lua_State *L, int index);
      + +

      +Returns 1 if the given acceptable index is not valid +(that is, it refers to an element outside the current stack), +and 0 otherwise. + + + + + +


      lua_isnoneornil

      +[-0, +0, -] +

      int lua_isnoneornil (lua_State *L, int index);
      + +

      +Returns 1 if the given acceptable index is not valid +(that is, it refers to an element outside the current stack) +or if the value at this index is nil, +and 0 otherwise. + + + + + +


      lua_isnumber

      +[-0, +0, -] +

      int lua_isnumber (lua_State *L, int index);
      + +

      +Returns 1 if the value at the given acceptable index is a number +or a string convertible to a number, +and 0 otherwise. + + + + + +


      lua_isstring

      +[-0, +0, -] +

      int lua_isstring (lua_State *L, int index);
      + +

      +Returns 1 if the value at the given acceptable index is a string +or a number (which is always convertible to a string), +and 0 otherwise. + + + + + +


      lua_istable

      +[-0, +0, -] +

      int lua_istable (lua_State *L, int index);
      + +

      +Returns 1 if the value at the given acceptable index is a table, +and 0 otherwise. + + + + + +


      lua_isthread

      +[-0, +0, -] +

      int lua_isthread (lua_State *L, int index);
      + +

      +Returns 1 if the value at the given acceptable index is a thread, +and 0 otherwise. + + + + + +


      lua_isuserdata

      +[-0, +0, -] +

      int lua_isuserdata (lua_State *L, int index);
      + +

      +Returns 1 if the value at the given acceptable index is a userdata +(either full or light), and 0 otherwise. + + + + + +


      lua_lessthan

      +[-0, +0, e] +

      int lua_lessthan (lua_State *L, int index1, int index2);
      + +

      +Returns 1 if the value at acceptable index index1 is smaller +than the value at acceptable index index2, +following the semantics of the Lua < operator +(that is, may call metamethods). +Otherwise returns 0. +Also returns 0 if any of the indices is non valid. + + + + + +


      lua_load

      +[-0, +1, -] +

      int lua_load (lua_State *L,
      +              lua_Reader reader,
      +              void *data,
      +              const char *chunkname);
      + +

      +Loads a Lua chunk. +If there are no errors, +lua_load pushes the compiled chunk as a Lua +function on top of the stack. +Otherwise, it pushes an error message. +The return values of lua_load are: + +

        + +
      • 0: no errors;
      • + +
      • LUA_ERRSYNTAX: +syntax error during pre-compilation;
      • + +
      • LUA_ERRMEM: +memory allocation error.
      • + +
      + +

      +This function only loads a chunk; +it does not run it. + + +

      +lua_load automatically detects whether the chunk is text or binary, +and loads it accordingly (see program luac). + + +

      +The lua_load function uses a user-supplied reader function +to read the chunk (see lua_Reader). +The data argument is an opaque value passed to the reader function. + + +

      +The chunkname argument gives a name to the chunk, +which is used for error messages and in debug information (see §3.8). + + + + + +


      lua_newstate

      +[-0, +0, -] +

      lua_State *lua_newstate (lua_Alloc f, void *ud);
      + +

      +Creates a new, independent state. +Returns NULL if cannot create the state +(due to lack of memory). +The argument f is the allocator function; +Lua does all memory allocation for this state through this function. +The second argument, ud, is an opaque pointer that Lua +simply passes to the allocator in every call. + + + + + +


      lua_newtable

      +[-0, +1, m] +

      void lua_newtable (lua_State *L);
      + +

      +Creates a new empty table and pushes it onto the stack. +It is equivalent to lua_createtable(L, 0, 0). + + + + + +


      lua_newthread

      +[-0, +1, m] +

      lua_State *lua_newthread (lua_State *L);
      + +

      +Creates a new thread, pushes it on the stack, +and returns a pointer to a lua_State that represents this new thread. +The new state returned by this function shares with the original state +all global objects (such as tables), +but has an independent execution stack. + + +

      +There is no explicit function to close or to destroy a thread. +Threads are subject to garbage collection, +like any Lua object. + + + + + +


      lua_newuserdata

      +[-0, +1, m] +

      void *lua_newuserdata (lua_State *L, size_t size);
      + +

      +This function allocates a new block of memory with the given size, +pushes onto the stack a new full userdata with the block address, +and returns this address. + + +

      +Userdata represent C values in Lua. +A full userdata represents a block of memory. +It is an object (like a table): +you must create it, it can have its own metatable, +and you can detect when it is being collected. +A full userdata is only equal to itself (under raw equality). + + +

      +When Lua collects a full userdata with a gc metamethod, +Lua calls the metamethod and marks the userdata as finalized. +When this userdata is collected again then +Lua frees its corresponding memory. + + + + + +


      lua_next

      +[-1, +(2|0), e] +

      int lua_next (lua_State *L, int index);
      + +

      +Pops a key from the stack, +and pushes a key-value pair from the table at the given index +(the "next" pair after the given key). +If there are no more elements in the table, +then lua_next returns 0 (and pushes nothing). + + +

      +A typical traversal looks like this: + +

      +     /* table is in the stack at index 't' */
      +     lua_pushnil(L);  /* first key */
      +     while (lua_next(L, t) != 0) {
      +       /* uses 'key' (at index -2) and 'value' (at index -1) */
      +       printf("%s - %s\n",
      +              lua_typename(L, lua_type(L, -2)),
      +              lua_typename(L, lua_type(L, -1)));
      +       /* removes 'value'; keeps 'key' for next iteration */
      +       lua_pop(L, 1);
      +     }
      +
      + +

      +While traversing a table, +do not call lua_tolstring directly on a key, +unless you know that the key is actually a string. +Recall that lua_tolstring changes +the value at the given index; +this confuses the next call to lua_next. + + + + + +


      lua_Number

      +
      typedef double lua_Number;
      + +

      +The type of numbers in Lua. +By default, it is double, but that can be changed in luaconf.h. + + +

      +Through the configuration file you can change +Lua to operate with another type for numbers (e.g., float or long). + + + + + +


      lua_objlen

      +[-0, +0, -] +

      size_t lua_objlen (lua_State *L, int index);
      + +

      +Returns the "length" of the value at the given acceptable index: +for strings, this is the string length; +for tables, this is the result of the length operator ('#'); +for userdata, this is the size of the block of memory allocated +for the userdata; +for other values, it is 0. + + + + + +


      lua_pcall

      +[-(nargs + 1), +(nresults|1), -] +

      int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc);
      + +

      +Calls a function in protected mode. + + +

      +Both nargs and nresults have the same meaning as +in lua_call. +If there are no errors during the call, +lua_pcall behaves exactly like lua_call. +However, if there is any error, +lua_pcall catches it, +pushes a single value on the stack (the error message), +and returns an error code. +Like lua_call, +lua_pcall always removes the function +and its arguments from the stack. + + +

      +If errfunc is 0, +then the error message returned on the stack +is exactly the original error message. +Otherwise, errfunc is the stack index of an +error handler function. +(In the current implementation, this index cannot be a pseudo-index.) +In case of runtime errors, +this function will be called with the error message +and its return value will be the message returned on the stack by lua_pcall. + + +

      +Typically, the error handler function is used to add more debug +information to the error message, such as a stack traceback. +Such information cannot be gathered after the return of lua_pcall, +since by then the stack has unwound. + + +

      +The lua_pcall function returns 0 in case of success +or one of the following error codes +(defined in lua.h): + +

        + +
      • LUA_ERRRUN: +a runtime error. +
      • + +
      • LUA_ERRMEM: +memory allocation error. +For such errors, Lua does not call the error handler function. +
      • + +
      • LUA_ERRERR: +error while running the error handler function. +
      • + +
      + + + + +

      lua_pop

      +[-n, +0, -] +

      void lua_pop (lua_State *L, int n);
      + +

      +Pops n elements from the stack. + + + + + +


      lua_pushboolean

      +[-0, +1, -] +

      void lua_pushboolean (lua_State *L, int b);
      + +

      +Pushes a boolean value with value b onto the stack. + + + + + +


      lua_pushcclosure

      +[-n, +1, m] +

      void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n);
      + +

      +Pushes a new C closure onto the stack. + + +

      +When a C function is created, +it is possible to associate some values with it, +thus creating a C closure (see §3.4); +these values are then accessible to the function whenever it is called. +To associate values with a C function, +first these values should be pushed onto the stack +(when there are multiple values, the first value is pushed first). +Then lua_pushcclosure +is called to create and push the C function onto the stack, +with the argument n telling how many values should be +associated with the function. +lua_pushcclosure also pops these values from the stack. + + +

      +The maximum value for n is 255. + + + + + +


      lua_pushcfunction

      +[-0, +1, m] +

      void lua_pushcfunction (lua_State *L, lua_CFunction f);
      + +

      +Pushes a C function onto the stack. +This function receives a pointer to a C function +and pushes onto the stack a Lua value of type function that, +when called, invokes the corresponding C function. + + +

      +Any function to be registered in Lua must +follow the correct protocol to receive its parameters +and return its results (see lua_CFunction). + + +

      +lua_pushcfunction is defined as a macro: + +

      +     #define lua_pushcfunction(L,f)  lua_pushcclosure(L,f,0)
      +
      + + + + +

      lua_pushfstring

      +[-0, +1, m] +

      const char *lua_pushfstring (lua_State *L, const char *fmt, ...);
      + +

      +Pushes onto the stack a formatted string +and returns a pointer to this string. +It is similar to the C function sprintf, +but has some important differences: + +

        + +
      • +You do not have to allocate space for the result: +the result is a Lua string and Lua takes care of memory allocation +(and deallocation, through garbage collection). +
      • + +
      • +The conversion specifiers are quite restricted. +There are no flags, widths, or precisions. +The conversion specifiers can only be +'%%' (inserts a '%' in the string), +'%s' (inserts a zero-terminated string, with no size restrictions), +'%f' (inserts a lua_Number), +'%p' (inserts a pointer as a hexadecimal numeral), +'%d' (inserts an int), and +'%c' (inserts an int as a character). +
      • + +
      + + + + +

      lua_pushinteger

      +[-0, +1, -] +

      void lua_pushinteger (lua_State *L, lua_Integer n);
      + +

      +Pushes a number with value n onto the stack. + + + + + +


      lua_pushlightuserdata

      +[-0, +1, -] +

      void lua_pushlightuserdata (lua_State *L, void *p);
      + +

      +Pushes a light userdata onto the stack. + + +

      +Userdata represent C values in Lua. +A light userdata represents a pointer. +It is a value (like a number): +you do not create it, it has no individual metatable, +and it is not collected (as it was never created). +A light userdata is equal to "any" +light userdata with the same C address. + + + + + +


      lua_pushliteral

      +[-0, +1, m] +

      void lua_pushliteral (lua_State *L, const char *s);
      + +

      +This macro is equivalent to lua_pushlstring, +but can be used only when s is a literal string. +In these cases, it automatically provides the string length. + + + + + +


      lua_pushlstring

      +[-0, +1, m] +

      void lua_pushlstring (lua_State *L, const char *s, size_t len);
      + +

      +Pushes the string pointed to by s with size len +onto the stack. +Lua makes (or reuses) an internal copy of the given string, +so the memory at s can be freed or reused immediately after +the function returns. +The string can contain embedded zeros. + + + + + +


      lua_pushnil

      +[-0, +1, -] +

      void lua_pushnil (lua_State *L);
      + +

      +Pushes a nil value onto the stack. + + + + + +


      lua_pushnumber

      +[-0, +1, -] +

      void lua_pushnumber (lua_State *L, lua_Number n);
      + +

      +Pushes a number with value n onto the stack. + + + + + +


      lua_pushstring

      +[-0, +1, m] +

      void lua_pushstring (lua_State *L, const char *s);
      + +

      +Pushes the zero-terminated string pointed to by s +onto the stack. +Lua makes (or reuses) an internal copy of the given string, +so the memory at s can be freed or reused immediately after +the function returns. +The string cannot contain embedded zeros; +it is assumed to end at the first zero. + + + + + +


      lua_pushthread

      +[-0, +1, -] +

      int lua_pushthread (lua_State *L);
      + +

      +Pushes the thread represented by L onto the stack. +Returns 1 if this thread is the main thread of its state. + + + + + +


      lua_pushvalue

      +[-0, +1, -] +

      void lua_pushvalue (lua_State *L, int index);
      + +

      +Pushes a copy of the element at the given valid index +onto the stack. + + + + + +


      lua_pushvfstring

      +[-0, +1, m] +

      const char *lua_pushvfstring (lua_State *L,
      +                              const char *fmt,
      +                              va_list argp);
      + +

      +Equivalent to lua_pushfstring, except that it receives a va_list +instead of a variable number of arguments. + + + + + +


      lua_rawequal

      +[-0, +0, -] +

      int lua_rawequal (lua_State *L, int index1, int index2);
      + +

      +Returns 1 if the two values in acceptable indices index1 and +index2 are primitively equal +(that is, without calling metamethods). +Otherwise returns 0. +Also returns 0 if any of the indices are non valid. + + + + + +


      lua_rawget

      +[-1, +1, -] +

      void lua_rawget (lua_State *L, int index);
      + +

      +Similar to lua_gettable, but does a raw access +(i.e., without metamethods). + + + + + +


      lua_rawgeti

      +[-0, +1, -] +

      void lua_rawgeti (lua_State *L, int index, int n);
      + +

      +Pushes onto the stack the value t[n], +where t is the value at the given valid index. +The access is raw; +that is, it does not invoke metamethods. + + + + + +


      lua_rawset

      +[-2, +0, m] +

      void lua_rawset (lua_State *L, int index);
      + +

      +Similar to lua_settable, but does a raw assignment +(i.e., without metamethods). + + + + + +


      lua_rawseti

      +[-1, +0, m] +

      void lua_rawseti (lua_State *L, int index, int n);
      + +

      +Does the equivalent of t[n] = v, +where t is the value at the given valid index +and v is the value at the top of the stack. + + +

      +This function pops the value from the stack. +The assignment is raw; +that is, it does not invoke metamethods. + + + + + +


      lua_Reader

      +
      typedef const char * (*lua_Reader) (lua_State *L,
      +                                    void *data,
      +                                    size_t *size);
      + +

      +The reader function used by lua_load. +Every time it needs another piece of the chunk, +lua_load calls the reader, +passing along its data parameter. +The reader must return a pointer to a block of memory +with a new piece of the chunk +and set size to the block size. +The block must exist until the reader function is called again. +To signal the end of the chunk, +the reader must return NULL or set size to zero. +The reader function may return pieces of any size greater than zero. + + + + + +


      lua_register

      +[-0, +0, e] +

      void lua_register (lua_State *L,
      +                   const char *name,
      +                   lua_CFunction f);
      + +

      +Sets the C function f as the new value of global name. +It is defined as a macro: + +

      +     #define lua_register(L,n,f) \
      +            (lua_pushcfunction(L, f), lua_setglobal(L, n))
      +
      + + + + +

      lua_remove

      +[-1, +0, -] +

      void lua_remove (lua_State *L, int index);
      + +

      +Removes the element at the given valid index, +shifting down the elements above this index to fill the gap. +Cannot be called with a pseudo-index, +because a pseudo-index is not an actual stack position. + + + + + +


      lua_replace

      +[-1, +0, -] +

      void lua_replace (lua_State *L, int index);
      + +

      +Moves the top element into the given position (and pops it), +without shifting any element +(therefore replacing the value at the given position). + + + + + +


      lua_resume

      +[-?, +?, -] +

      int lua_resume (lua_State *L, int narg);
      + +

      +Starts and resumes a coroutine in a given thread. + + +

      +To start a coroutine, you first create a new thread +(see lua_newthread); +then you push onto its stack the main function plus any arguments; +then you call lua_resume, +with narg being the number of arguments. +This call returns when the coroutine suspends or finishes its execution. +When it returns, the stack contains all values passed to lua_yield, +or all values returned by the body function. +lua_resume returns +LUA_YIELD if the coroutine yields, +0 if the coroutine finishes its execution +without errors, +or an error code in case of errors (see lua_pcall). +In case of errors, +the stack is not unwound, +so you can use the debug API over it. +The error message is on the top of the stack. +To restart a coroutine, you put on its stack only the values to +be passed as results from yield, +and then call lua_resume. + + + + + +


      lua_setallocf

      +[-0, +0, -] +

      void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);
      + +

      +Changes the allocator function of a given state to f +with user data ud. + + + + + +


      lua_setfenv

      +[-1, +0, -] +

      int lua_setfenv (lua_State *L, int index);
      + +

      +Pops a table from the stack and sets it as +the new environment for the value at the given index. +If the value at the given index is +neither a function nor a thread nor a userdata, +lua_setfenv returns 0. +Otherwise it returns 1. + + + + + +


      lua_setfield

      +[-1, +0, e] +

      void lua_setfield (lua_State *L, int index, const char *k);
      + +

      +Does the equivalent to t[k] = v, +where t is the value at the given valid index +and v is the value at the top of the stack. + + +

      +This function pops the value from the stack. +As in Lua, this function may trigger a metamethod +for the "newindex" event (see §2.8). + + + + + +


      lua_setglobal

      +[-1, +0, e] +

      void lua_setglobal (lua_State *L, const char *name);
      + +

      +Pops a value from the stack and +sets it as the new value of global name. +It is defined as a macro: + +

      +     #define lua_setglobal(L,s)   lua_setfield(L, LUA_GLOBALSINDEX, s)
      +
      + + + + +

      lua_setmetatable

      +[-1, +0, -] +

      int lua_setmetatable (lua_State *L, int index);
      + +

      +Pops a table from the stack and +sets it as the new metatable for the value at the given +acceptable index. + + + + + +


      lua_settable

      +[-2, +0, e] +

      void lua_settable (lua_State *L, int index);
      + +

      +Does the equivalent to t[k] = v, +where t is the value at the given valid index, +v is the value at the top of the stack, +and k is the value just below the top. + + +

      +This function pops both the key and the value from the stack. +As in Lua, this function may trigger a metamethod +for the "newindex" event (see §2.8). + + + + + +


      lua_settop

      +[-?, +?, -] +

      void lua_settop (lua_State *L, int index);
      + +

      +Accepts any acceptable index, or 0, +and sets the stack top to this index. +If the new top is larger than the old one, +then the new elements are filled with nil. +If index is 0, then all stack elements are removed. + + + + + +


      lua_State

      +
      typedef struct lua_State lua_State;
      + +

      +Opaque structure that keeps the whole state of a Lua interpreter. +The Lua library is fully reentrant: +it has no global variables. +All information about a state is kept in this structure. + + +

      +A pointer to this state must be passed as the first argument to +every function in the library, except to lua_newstate, +which creates a Lua state from scratch. + + + + + +


      lua_status

      +[-0, +0, -] +

      int lua_status (lua_State *L);
      + +

      +Returns the status of the thread L. + + +

      +The status can be 0 for a normal thread, +an error code if the thread finished its execution with an error, +or LUA_YIELD if the thread is suspended. + + + + + +


      lua_toboolean

      +[-0, +0, -] +

      int lua_toboolean (lua_State *L, int index);
      + +

      +Converts the Lua value at the given acceptable index to a C boolean +value (0 or 1). +Like all tests in Lua, +lua_toboolean returns 1 for any Lua value +different from false and nil; +otherwise it returns 0. +It also returns 0 when called with a non-valid index. +(If you want to accept only actual boolean values, +use lua_isboolean to test the value's type.) + + + + + +


      lua_tocfunction

      +[-0, +0, -] +

      lua_CFunction lua_tocfunction (lua_State *L, int index);
      + +

      +Converts a value at the given acceptable index to a C function. +That value must be a C function; +otherwise, returns NULL. + + + + + +


      lua_tointeger

      +[-0, +0, -] +

      lua_Integer lua_tointeger (lua_State *L, int index);
      + +

      +Converts the Lua value at the given acceptable index +to the signed integral type lua_Integer. +The Lua value must be a number or a string convertible to a number +(see §2.2.1); +otherwise, lua_tointeger returns 0. + + +

      +If the number is not an integer, +it is truncated in some non-specified way. + + + + + +


      lua_tolstring

      +[-0, +0, m] +

      const char *lua_tolstring (lua_State *L, int index, size_t *len);
      + +

      +Converts the Lua value at the given acceptable index to a C string. +If len is not NULL, +it also sets *len with the string length. +The Lua value must be a string or a number; +otherwise, the function returns NULL. +If the value is a number, +then lua_tolstring also +changes the actual value in the stack to a string. +(This change confuses lua_next +when lua_tolstring is applied to keys during a table traversal.) + + +

      +lua_tolstring returns a fully aligned pointer +to a string inside the Lua state. +This string always has a zero ('\0') +after its last character (as in C), +but can contain other zeros in its body. +Because Lua has garbage collection, +there is no guarantee that the pointer returned by lua_tolstring +will be valid after the corresponding value is removed from the stack. + + + + + +


      lua_tonumber

      +[-0, +0, -] +

      lua_Number lua_tonumber (lua_State *L, int index);
      + +

      +Converts the Lua value at the given acceptable index +to the C type lua_Number (see lua_Number). +The Lua value must be a number or a string convertible to a number +(see §2.2.1); +otherwise, lua_tonumber returns 0. + + + + + +


      lua_topointer

      +[-0, +0, -] +

      const void *lua_topointer (lua_State *L, int index);
      + +

      +Converts the value at the given acceptable index to a generic +C pointer (void*). +The value can be a userdata, a table, a thread, or a function; +otherwise, lua_topointer returns NULL. +Different objects will give different pointers. +There is no way to convert the pointer back to its original value. + + +

      +Typically this function is used only for debug information. + + + + + +


      lua_tostring

      +[-0, +0, m] +

      const char *lua_tostring (lua_State *L, int index);
      + +

      +Equivalent to lua_tolstring with len equal to NULL. + + + + + +


      lua_tothread

      +[-0, +0, -] +

      lua_State *lua_tothread (lua_State *L, int index);
      + +

      +Converts the value at the given acceptable index to a Lua thread +(represented as lua_State*). +This value must be a thread; +otherwise, the function returns NULL. + + + + + +


      lua_touserdata

      +[-0, +0, -] +

      void *lua_touserdata (lua_State *L, int index);
      + +

      +If the value at the given acceptable index is a full userdata, +returns its block address. +If the value is a light userdata, +returns its pointer. +Otherwise, returns NULL. + + + + + +


      lua_type

      +[-0, +0, -] +

      int lua_type (lua_State *L, int index);
      + +

      +Returns the type of the value in the given acceptable index, +or LUA_TNONE for a non-valid index +(that is, an index to an "empty" stack position). +The types returned by lua_type are coded by the following constants +defined in lua.h: +LUA_TNIL, +LUA_TNUMBER, +LUA_TBOOLEAN, +LUA_TSTRING, +LUA_TTABLE, +LUA_TFUNCTION, +LUA_TUSERDATA, +LUA_TTHREAD, +and +LUA_TLIGHTUSERDATA. + + + + + +


      lua_typename

      +[-0, +0, -] +

      const char *lua_typename  (lua_State *L, int tp);
      + +

      +Returns the name of the type encoded by the value tp, +which must be one the values returned by lua_type. + + + + + +


      lua_Writer

      +
      typedef int (*lua_Writer) (lua_State *L,
      +                           const void* p,
      +                           size_t sz,
      +                           void* ud);
      + +

      +The type of the writer function used by lua_dump. +Every time it produces another piece of chunk, +lua_dump calls the writer, +passing along the buffer to be written (p), +its size (sz), +and the data parameter supplied to lua_dump. + + +

      +The writer returns an error code: +0 means no errors; +any other value means an error and stops lua_dump from +calling the writer again. + + + + + +


      lua_xmove

      +[-?, +?, -] +

      void lua_xmove (lua_State *from, lua_State *to, int n);
      + +

      +Exchange values between different threads of the same global state. + + +

      +This function pops n values from the stack from, +and pushes them onto the stack to. + + + + + +


      lua_yield

      +[-?, +?, -] +

      int lua_yield  (lua_State *L, int nresults);
      + +

      +Yields a coroutine. + + +

      +This function should only be called as the +return expression of a C function, as follows: + +

      +     return lua_yield (L, nresults);
      +

      +When a C function calls lua_yield in that way, +the running coroutine suspends its execution, +and the call to lua_resume that started this coroutine returns. +The parameter nresults is the number of values from the stack +that are passed as results to lua_resume. + + + + + + + +

      3.8 - The Debug Interface

      + +

      +Lua has no built-in debugging facilities. +Instead, it offers a special interface +by means of functions and hooks. +This interface allows the construction of different +kinds of debuggers, profilers, and other tools +that need "inside information" from the interpreter. + + + +


      lua_Debug

      +
      typedef struct lua_Debug {
      +  int event;
      +  const char *name;           /* (n) */
      +  const char *namewhat;       /* (n) */
      +  const char *what;           /* (S) */
      +  const char *source;         /* (S) */
      +  int currentline;            /* (l) */
      +  int nups;                   /* (u) number of upvalues */
      +  int linedefined;            /* (S) */
      +  int lastlinedefined;        /* (S) */
      +  char short_src[LUA_IDSIZE]; /* (S) */
      +  /* private part */
      +  other fields
      +} lua_Debug;
      + +

      +A structure used to carry different pieces of +information about an active function. +lua_getstack fills only the private part +of this structure, for later use. +To fill the other fields of lua_Debug with useful information, +call lua_getinfo. + + +

      +The fields of lua_Debug have the following meaning: + +

        + +
      • source: +If the function was defined in a string, +then source is that string. +If the function was defined in a file, +then source starts with a '@' followed by the file name. +
      • + +
      • short_src: +a "printable" version of source, to be used in error messages. +
      • + +
      • linedefined: +the line number where the definition of the function starts. +
      • + +
      • lastlinedefined: +the line number where the definition of the function ends. +
      • + +
      • what: +the string "Lua" if the function is a Lua function, +"C" if it is a C function, +"main" if it is the main part of a chunk, +and "tail" if it was a function that did a tail call. +In the latter case, +Lua has no other information about the function. +
      • + +
      • currentline: +the current line where the given function is executing. +When no line information is available, +currentline is set to -1. +
      • + +
      • name: +a reasonable name for the given function. +Because functions in Lua are first-class values, +they do not have a fixed name: +some functions can be the value of multiple global variables, +while others can be stored only in a table field. +The lua_getinfo function checks how the function was +called to find a suitable name. +If it cannot find a name, +then name is set to NULL. +
      • + +
      • namewhat: +explains the name field. +The value of namewhat can be +"global", "local", "method", +"field", "upvalue", or "" (the empty string), +according to how the function was called. +(Lua uses the empty string when no other option seems to apply.) +
      • + +
      • nups: +the number of upvalues of the function. +
      • + +
      + + + + +

      lua_gethook

      +[-0, +0, -] +

      lua_Hook lua_gethook (lua_State *L);
      + +

      +Returns the current hook function. + + + + + +


      lua_gethookcount

      +[-0, +0, -] +

      int lua_gethookcount (lua_State *L);
      + +

      +Returns the current hook count. + + + + + +


      lua_gethookmask

      +[-0, +0, -] +

      int lua_gethookmask (lua_State *L);
      + +

      +Returns the current hook mask. + + + + + +


      lua_getinfo

      +[-(0|1), +(0|1|2), m] +

      int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar);
      + +

      +Returns information about a specific function or function invocation. + + +

      +To get information about a function invocation, +the parameter ar must be a valid activation record that was +filled by a previous call to lua_getstack or +given as argument to a hook (see lua_Hook). + + +

      +To get information about a function you push it onto the stack +and start the what string with the character '>'. +(In that case, +lua_getinfo pops the function in the top of the stack.) +For instance, to know in which line a function f was defined, +you can write the following code: + +

      +     lua_Debug ar;
      +     lua_getfield(L, LUA_GLOBALSINDEX, "f");  /* get global 'f' */
      +     lua_getinfo(L, ">S", &ar);
      +     printf("%d\n", ar.linedefined);
      +
      + +

      +Each character in the string what +selects some fields of the structure ar to be filled or +a value to be pushed on the stack: + +

        + +
      • 'n': fills in the field name and namewhat; +
      • + +
      • 'S': +fills in the fields source, short_src, +linedefined, lastlinedefined, and what; +
      • + +
      • 'l': fills in the field currentline; +
      • + +
      • 'u': fills in the field nups; +
      • + +
      • 'f': +pushes onto the stack the function that is +running at the given level; +
      • + +
      • 'L': +pushes onto the stack a table whose indices are the +numbers of the lines that are valid on the function. +(A valid line is a line with some associated code, +that is, a line where you can put a break point. +Non-valid lines include empty lines and comments.) +
      • + +
      + +

      +This function returns 0 on error +(for instance, an invalid option in what). + + + + + +


      lua_getlocal

      +[-0, +(0|1), -] +

      const char *lua_getlocal (lua_State *L, lua_Debug *ar, int n);
      + +

      +Gets information about a local variable of a given activation record. +The parameter ar must be a valid activation record that was +filled by a previous call to lua_getstack or +given as argument to a hook (see lua_Hook). +The index n selects which local variable to inspect +(1 is the first parameter or active local variable, and so on, +until the last active local variable). +lua_getlocal pushes the variable's value onto the stack +and returns its name. + + +

      +Variable names starting with '(' (open parentheses) +represent internal variables +(loop control variables, temporaries, and C function locals). + + +

      +Returns NULL (and pushes nothing) +when the index is greater than +the number of active local variables. + + + + + +


      lua_getstack

      +[-0, +0, -] +

      int lua_getstack (lua_State *L, int level, lua_Debug *ar);
      + +

      +Get information about the interpreter runtime stack. + + +

      +This function fills parts of a lua_Debug structure with +an identification of the activation record +of the function executing at a given level. +Level 0 is the current running function, +whereas level n+1 is the function that has called level n. +When there are no errors, lua_getstack returns 1; +when called with a level greater than the stack depth, +it returns 0. + + + + + +


      lua_getupvalue

      +[-0, +(0|1), -] +

      const char *lua_getupvalue (lua_State *L, int funcindex, int n);
      + +

      +Gets information about a closure's upvalue. +(For Lua functions, +upvalues are the external local variables that the function uses, +and that are consequently included in its closure.) +lua_getupvalue gets the index n of an upvalue, +pushes the upvalue's value onto the stack, +and returns its name. +funcindex points to the closure in the stack. +(Upvalues have no particular order, +as they are active through the whole function. +So, they are numbered in an arbitrary order.) + + +

      +Returns NULL (and pushes nothing) +when the index is greater than the number of upvalues. +For C functions, this function uses the empty string "" +as a name for all upvalues. + + + + + +


      lua_Hook

      +
      typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);
      + +

      +Type for debugging hook functions. + + +

      +Whenever a hook is called, its ar argument has its field +event set to the specific event that triggered the hook. +Lua identifies these events with the following constants: +LUA_HOOKCALL, LUA_HOOKRET, +LUA_HOOKTAILRET, LUA_HOOKLINE, +and LUA_HOOKCOUNT. +Moreover, for line events, the field currentline is also set. +To get the value of any other field in ar, +the hook must call lua_getinfo. +For return events, event can be LUA_HOOKRET, +the normal value, or LUA_HOOKTAILRET. +In the latter case, Lua is simulating a return from +a function that did a tail call; +in this case, it is useless to call lua_getinfo. + + +

      +While Lua is running a hook, it disables other calls to hooks. +Therefore, if a hook calls back Lua to execute a function or a chunk, +this execution occurs without any calls to hooks. + + + + + +


      lua_sethook

      +[-0, +0, -] +

      int lua_sethook (lua_State *L, lua_Hook f, int mask, int count);
      + +

      +Sets the debugging hook function. + + +

      +Argument f is the hook function. +mask specifies on which events the hook will be called: +it is formed by a bitwise or of the constants +LUA_MASKCALL, +LUA_MASKRET, +LUA_MASKLINE, +and LUA_MASKCOUNT. +The count argument is only meaningful when the mask +includes LUA_MASKCOUNT. +For each event, the hook is called as explained below: + +

        + +
      • The call hook: is called when the interpreter calls a function. +The hook is called just after Lua enters the new function, +before the function gets its arguments. +
      • + +
      • The return hook: is called when the interpreter returns from a function. +The hook is called just before Lua leaves the function. +You have no access to the values to be returned by the function. +
      • + +
      • The line hook: is called when the interpreter is about to +start the execution of a new line of code, +or when it jumps back in the code (even to the same line). +(This event only happens while Lua is executing a Lua function.) +
      • + +
      • The count hook: is called after the interpreter executes every +count instructions. +(This event only happens while Lua is executing a Lua function.) +
      • + +
      + +

      +A hook is disabled by setting mask to zero. + + + + + +


      lua_setlocal

      +[-(0|1), +0, -] +

      const char *lua_setlocal (lua_State *L, lua_Debug *ar, int n);
      + +

      +Sets the value of a local variable of a given activation record. +Parameters ar and n are as in lua_getlocal +(see lua_getlocal). +lua_setlocal assigns the value at the top of the stack +to the variable and returns its name. +It also pops the value from the stack. + + +

      +Returns NULL (and pops nothing) +when the index is greater than +the number of active local variables. + + + + + +


      lua_setupvalue

      +[-(0|1), +0, -] +

      const char *lua_setupvalue (lua_State *L, int funcindex, int n);
      + +

      +Sets the value of a closure's upvalue. +It assigns the value at the top of the stack +to the upvalue and returns its name. +It also pops the value from the stack. +Parameters funcindex and n are as in the lua_getupvalue +(see lua_getupvalue). + + +

      +Returns NULL (and pops nothing) +when the index is greater than the number of upvalues. + + + + + + + +

      4 - The Auxiliary Library

      + +

      + +The auxiliary library provides several convenient functions +to interface C with Lua. +While the basic API provides the primitive functions for all +interactions between C and Lua, +the auxiliary library provides higher-level functions for some +common tasks. + + +

      +All functions from the auxiliary library +are defined in header file lauxlib.h and +have a prefix luaL_. + + +

      +All functions in the auxiliary library are built on +top of the basic API, +and so they provide nothing that cannot be done with this API. + + +

      +Several functions in the auxiliary library are used to +check C function arguments. +Their names are always luaL_check* or luaL_opt*. +All of these functions throw an error if the check is not satisfied. +Because the error message is formatted for arguments +(e.g., "bad argument #1"), +you should not use these functions for other stack values. + + + +

      4.1 - Functions and Types

      + +

      +Here we list all functions and types from the auxiliary library +in alphabetical order. + + + +


      luaL_addchar

      +[-0, +0, m] +

      void luaL_addchar (luaL_Buffer *B, char c);
      + +

      +Adds the character c to the buffer B +(see luaL_Buffer). + + + + + +


      luaL_addlstring

      +[-0, +0, m] +

      void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l);
      + +

      +Adds the string pointed to by s with length l to +the buffer B +(see luaL_Buffer). +The string may contain embedded zeros. + + + + + +


      luaL_addsize

      +[-0, +0, m] +

      void luaL_addsize (luaL_Buffer *B, size_t n);
      + +

      +Adds to the buffer B (see luaL_Buffer) +a string of length n previously copied to the +buffer area (see luaL_prepbuffer). + + + + + +


      luaL_addstring

      +[-0, +0, m] +

      void luaL_addstring (luaL_Buffer *B, const char *s);
      + +

      +Adds the zero-terminated string pointed to by s +to the buffer B +(see luaL_Buffer). +The string may not contain embedded zeros. + + + + + +


      luaL_addvalue

      +[-1, +0, m] +

      void luaL_addvalue (luaL_Buffer *B);
      + +

      +Adds the value at the top of the stack +to the buffer B +(see luaL_Buffer). +Pops the value. + + +

      +This is the only function on string buffers that can (and must) +be called with an extra element on the stack, +which is the value to be added to the buffer. + + + + + +


      luaL_argcheck

      +[-0, +0, v] +

      void luaL_argcheck (lua_State *L,
      +                    int cond,
      +                    int narg,
      +                    const char *extramsg);
      + +

      +Checks whether cond is true. +If not, raises an error with the following message, +where func is retrieved from the call stack: + +

      +     bad argument #<narg> to <func> (<extramsg>)
      +
      + + + + +

      luaL_argerror

      +[-0, +0, v] +

      int luaL_argerror (lua_State *L, int narg, const char *extramsg);
      + +

      +Raises an error with the following message, +where func is retrieved from the call stack: + +

      +     bad argument #<narg> to <func> (<extramsg>)
      +
      + +

      +This function never returns, +but it is an idiom to use it in C functions +as return luaL_argerror(args). + + + + + +


      luaL_Buffer

      +
      typedef struct luaL_Buffer luaL_Buffer;
      + +

      +Type for a string buffer. + + +

      +A string buffer allows C code to build Lua strings piecemeal. +Its pattern of use is as follows: + +

        + +
      • First you declare a variable b of type luaL_Buffer.
      • + +
      • Then you initialize it with a call luaL_buffinit(L, &b).
      • + +
      • +Then you add string pieces to the buffer calling any of +the luaL_add* functions. +
      • + +
      • +You finish by calling luaL_pushresult(&b). +This call leaves the final string on the top of the stack. +
      • + +
      + +

      +During its normal operation, +a string buffer uses a variable number of stack slots. +So, while using a buffer, you cannot assume that you know where +the top of the stack is. +You can use the stack between successive calls to buffer operations +as long as that use is balanced; +that is, +when you call a buffer operation, +the stack is at the same level +it was immediately after the previous buffer operation. +(The only exception to this rule is luaL_addvalue.) +After calling luaL_pushresult the stack is back to its +level when the buffer was initialized, +plus the final string on its top. + + + + + +


      luaL_buffinit

      +[-0, +0, -] +

      void luaL_buffinit (lua_State *L, luaL_Buffer *B);
      + +

      +Initializes a buffer B. +This function does not allocate any space; +the buffer must be declared as a variable +(see luaL_Buffer). + + + + + +


      luaL_callmeta

      +[-0, +(0|1), e] +

      int luaL_callmeta (lua_State *L, int obj, const char *e);
      + +

      +Calls a metamethod. + + +

      +If the object at index obj has a metatable and this +metatable has a field e, +this function calls this field and passes the object as its only argument. +In this case this function returns 1 and pushes onto the +stack the value returned by the call. +If there is no metatable or no metamethod, +this function returns 0 (without pushing any value on the stack). + + + + + +


      luaL_checkany

      +[-0, +0, v] +

      void luaL_checkany (lua_State *L, int narg);
      + +

      +Checks whether the function has an argument +of any type (including nil) at position narg. + + + + + +


      luaL_checkint

      +[-0, +0, v] +

      int luaL_checkint (lua_State *L, int narg);
      + +

      +Checks whether the function argument narg is a number +and returns this number cast to an int. + + + + + +


      luaL_checkinteger

      +[-0, +0, v] +

      lua_Integer luaL_checkinteger (lua_State *L, int narg);
      + +

      +Checks whether the function argument narg is a number +and returns this number cast to a lua_Integer. + + + + + +


      luaL_checklong

      +[-0, +0, v] +

      long luaL_checklong (lua_State *L, int narg);
      + +

      +Checks whether the function argument narg is a number +and returns this number cast to a long. + + + + + +


      luaL_checklstring

      +[-0, +0, v] +

      const char *luaL_checklstring (lua_State *L, int narg, size_t *l);
      + +

      +Checks whether the function argument narg is a string +and returns this string; +if l is not NULL fills *l +with the string's length. + + +

      +This function uses lua_tolstring to get its result, +so all conversions and caveats of that function apply here. + + + + + +


      luaL_checknumber

      +[-0, +0, v] +

      lua_Number luaL_checknumber (lua_State *L, int narg);
      + +

      +Checks whether the function argument narg is a number +and returns this number. + + + + + +


      luaL_checkoption

      +[-0, +0, v] +

      int luaL_checkoption (lua_State *L,
      +                      int narg,
      +                      const char *def,
      +                      const char *const lst[]);
      + +

      +Checks whether the function argument narg is a string and +searches for this string in the array lst +(which must be NULL-terminated). +Returns the index in the array where the string was found. +Raises an error if the argument is not a string or +if the string cannot be found. + + +

      +If def is not NULL, +the function uses def as a default value when +there is no argument narg or if this argument is nil. + + +

      +This is a useful function for mapping strings to C enums. +(The usual convention in Lua libraries is +to use strings instead of numbers to select options.) + + + + + +


      luaL_checkstack

      +[-0, +0, v] +

      void luaL_checkstack (lua_State *L, int sz, const char *msg);
      + +

      +Grows the stack size to top + sz elements, +raising an error if the stack cannot grow to that size. +msg is an additional text to go into the error message. + + + + + +


      luaL_checkstring

      +[-0, +0, v] +

      const char *luaL_checkstring (lua_State *L, int narg);
      + +

      +Checks whether the function argument narg is a string +and returns this string. + + +

      +This function uses lua_tolstring to get its result, +so all conversions and caveats of that function apply here. + + + + + +


      luaL_checktype

      +[-0, +0, v] +

      void luaL_checktype (lua_State *L, int narg, int t);
      + +

      +Checks whether the function argument narg has type t. +See lua_type for the encoding of types for t. + + + + + +


      luaL_checkudata

      +[-0, +0, v] +

      void *luaL_checkudata (lua_State *L, int narg, const char *tname);
      + +

      +Checks whether the function argument narg is a userdata +of the type tname (see luaL_newmetatable). + + + + + +


      luaL_dofile

      +[-0, +?, m] +

      int luaL_dofile (lua_State *L, const char *filename);
      + +

      +Loads and runs the given file. +It is defined as the following macro: + +

      +     (luaL_loadfile(L, filename) || lua_pcall(L, 0, LUA_MULTRET, 0))
      +

      +It returns 0 if there are no errors +or 1 in case of errors. + + + + + +


      luaL_dostring

      +[-0, +?, m] +

      int luaL_dostring (lua_State *L, const char *str);
      + +

      +Loads and runs the given string. +It is defined as the following macro: + +

      +     (luaL_loadstring(L, str) || lua_pcall(L, 0, LUA_MULTRET, 0))
      +

      +It returns 0 if there are no errors +or 1 in case of errors. + + + + + +


      luaL_error

      +[-0, +0, v] +

      int luaL_error (lua_State *L, const char *fmt, ...);
      + +

      +Raises an error. +The error message format is given by fmt +plus any extra arguments, +following the same rules of lua_pushfstring. +It also adds at the beginning of the message the file name and +the line number where the error occurred, +if this information is available. + + +

      +This function never returns, +but it is an idiom to use it in C functions +as return luaL_error(args). + + + + + +


      luaL_getmetafield

      +[-0, +(0|1), m] +

      int luaL_getmetafield (lua_State *L, int obj, const char *e);
      + +

      +Pushes onto the stack the field e from the metatable +of the object at index obj. +If the object does not have a metatable, +or if the metatable does not have this field, +returns 0 and pushes nothing. + + + + + +


      luaL_getmetatable

      +[-0, +1, -] +

      void luaL_getmetatable (lua_State *L, const char *tname);
      + +

      +Pushes onto the stack the metatable associated with name tname +in the registry (see luaL_newmetatable). + + + + + +


      luaL_gsub

      +[-0, +1, m] +

      const char *luaL_gsub (lua_State *L,
      +                       const char *s,
      +                       const char *p,
      +                       const char *r);
      + +

      +Creates a copy of string s by replacing +any occurrence of the string p +with the string r. +Pushes the resulting string on the stack and returns it. + + + + + +


      luaL_loadbuffer

      +[-0, +1, m] +

      int luaL_loadbuffer (lua_State *L,
      +                     const char *buff,
      +                     size_t sz,
      +                     const char *name);
      + +

      +Loads a buffer as a Lua chunk. +This function uses lua_load to load the chunk in the +buffer pointed to by buff with size sz. + + +

      +This function returns the same results as lua_load. +name is the chunk name, +used for debug information and error messages. + + + + + +


      luaL_loadfile

      +[-0, +1, m] +

      int luaL_loadfile (lua_State *L, const char *filename);
      + +

      +Loads a file as a Lua chunk. +This function uses lua_load to load the chunk in the file +named filename. +If filename is NULL, +then it loads from the standard input. +The first line in the file is ignored if it starts with a #. + + +

      +This function returns the same results as lua_load, +but it has an extra error code LUA_ERRFILE +if it cannot open/read the file. + + +

      +As lua_load, this function only loads the chunk; +it does not run it. + + + + + +


      luaL_loadstring

      +[-0, +1, m] +

      int luaL_loadstring (lua_State *L, const char *s);
      + +

      +Loads a string as a Lua chunk. +This function uses lua_load to load the chunk in +the zero-terminated string s. + + +

      +This function returns the same results as lua_load. + + +

      +Also as lua_load, this function only loads the chunk; +it does not run it. + + + + + +


      luaL_newmetatable

      +[-0, +1, m] +

      int luaL_newmetatable (lua_State *L, const char *tname);
      + +

      +If the registry already has the key tname, +returns 0. +Otherwise, +creates a new table to be used as a metatable for userdata, +adds it to the registry with key tname, +and returns 1. + + +

      +In both cases pushes onto the stack the final value associated +with tname in the registry. + + + + + +


      luaL_newstate

      +[-0, +0, -] +

      lua_State *luaL_newstate (void);
      + +

      +Creates a new Lua state. +It calls lua_newstate with an +allocator based on the standard C realloc function +and then sets a panic function (see lua_atpanic) that prints +an error message to the standard error output in case of fatal +errors. + + +

      +Returns the new state, +or NULL if there is a memory allocation error. + + + + + +


      luaL_openlibs

      +[-0, +0, m] +

      void luaL_openlibs (lua_State *L);
      + +

      +Opens all standard Lua libraries into the given state. + + + + + +


      luaL_optint

      +[-0, +0, v] +

      int luaL_optint (lua_State *L, int narg, int d);
      + +

      +If the function argument narg is a number, +returns this number cast to an int. +If this argument is absent or is nil, +returns d. +Otherwise, raises an error. + + + + + +


      luaL_optinteger

      +[-0, +0, v] +

      lua_Integer luaL_optinteger (lua_State *L,
      +                             int narg,
      +                             lua_Integer d);
      + +

      +If the function argument narg is a number, +returns this number cast to a lua_Integer. +If this argument is absent or is nil, +returns d. +Otherwise, raises an error. + + + + + +


      luaL_optlong

      +[-0, +0, v] +

      long luaL_optlong (lua_State *L, int narg, long d);
      + +

      +If the function argument narg is a number, +returns this number cast to a long. +If this argument is absent or is nil, +returns d. +Otherwise, raises an error. + + + + + +


      luaL_optlstring

      +[-0, +0, v] +

      const char *luaL_optlstring (lua_State *L,
      +                             int narg,
      +                             const char *d,
      +                             size_t *l);
      + +

      +If the function argument narg is a string, +returns this string. +If this argument is absent or is nil, +returns d. +Otherwise, raises an error. + + +

      +If l is not NULL, +fills the position *l with the results's length. + + + + + +


      luaL_optnumber

      +[-0, +0, v] +

      lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number d);
      + +

      +If the function argument narg is a number, +returns this number. +If this argument is absent or is nil, +returns d. +Otherwise, raises an error. + + + + + +


      luaL_optstring

      +[-0, +0, v] +

      const char *luaL_optstring (lua_State *L,
      +                            int narg,
      +                            const char *d);
      + +

      +If the function argument narg is a string, +returns this string. +If this argument is absent or is nil, +returns d. +Otherwise, raises an error. + + + + + +


      luaL_prepbuffer

      +[-0, +0, -] +

      char *luaL_prepbuffer (luaL_Buffer *B);
      + +

      +Returns an address to a space of size LUAL_BUFFERSIZE +where you can copy a string to be added to buffer B +(see luaL_Buffer). +After copying the string into this space you must call +luaL_addsize with the size of the string to actually add +it to the buffer. + + + + + +


      luaL_pushresult

      +[-?, +1, m] +

      void luaL_pushresult (luaL_Buffer *B);
      + +

      +Finishes the use of buffer B leaving the final string on +the top of the stack. + + + + + +


      luaL_ref

      +[-1, +0, m] +

      int luaL_ref (lua_State *L, int t);
      + +

      +Creates and returns a reference, +in the table at index t, +for the object at the top of the stack (and pops the object). + + +

      +A reference is a unique integer key. +As long as you do not manually add integer keys into table t, +luaL_ref ensures the uniqueness of the key it returns. +You can retrieve an object referred by reference r +by calling lua_rawgeti(L, t, r). +Function luaL_unref frees a reference and its associated object. + + +

      +If the object at the top of the stack is nil, +luaL_ref returns the constant LUA_REFNIL. +The constant LUA_NOREF is guaranteed to be different +from any reference returned by luaL_ref. + + + + + +


      luaL_Reg

      +
      typedef struct luaL_Reg {
      +  const char *name;
      +  lua_CFunction func;
      +} luaL_Reg;
      + +

      +Type for arrays of functions to be registered by +luaL_register. +name is the function name and func is a pointer to +the function. +Any array of luaL_Reg must end with an sentinel entry +in which both name and func are NULL. + + + + + +


      luaL_register

      +[-(0|1), +1, m] +

      void luaL_register (lua_State *L,
      +                    const char *libname,
      +                    const luaL_Reg *l);
      + +

      +Opens a library. + + +

      +When called with libname equal to NULL, +it simply registers all functions in the list l +(see luaL_Reg) into the table on the top of the stack. + + +

      +When called with a non-null libname, +luaL_register creates a new table t, +sets it as the value of the global variable libname, +sets it as the value of package.loaded[libname], +and registers on it all functions in the list l. +If there is a table in package.loaded[libname] or in +variable libname, +reuses this table instead of creating a new one. + + +

      +In any case the function leaves the table +on the top of the stack. + + + + + +


      luaL_typename

      +[-0, +0, -] +

      const char *luaL_typename (lua_State *L, int index);
      + +

      +Returns the name of the type of the value at the given index. + + + + + +


      luaL_typerror

      +[-0, +0, v] +

      int luaL_typerror (lua_State *L, int narg, const char *tname);
      + +

      +Generates an error with a message like the following: + +

      +     location: bad argument narg to 'func' (tname expected, got rt)
      +

      +where location is produced by luaL_where, +func is the name of the current function, +and rt is the type name of the actual argument. + + + + + +


      luaL_unref

      +[-0, +0, -] +

      void luaL_unref (lua_State *L, int t, int ref);
      + +

      +Releases reference ref from the table at index t +(see luaL_ref). +The entry is removed from the table, +so that the referred object can be collected. +The reference ref is also freed to be used again. + + +

      +If ref is LUA_NOREF or LUA_REFNIL, +luaL_unref does nothing. + + + + + +


      luaL_where

      +[-0, +1, m] +

      void luaL_where (lua_State *L, int lvl);
      + +

      +Pushes onto the stack a string identifying the current position +of the control at level lvl in the call stack. +Typically this string has the following format: + +

      +     chunkname:currentline:
      +

      +Level 0 is the running function, +level 1 is the function that called the running function, +etc. + + +

      +This function is used to build a prefix for error messages. + + + + + + + +

      5 - Standard Libraries

      + +

      +The standard Lua libraries provide useful functions +that are implemented directly through the C API. +Some of these functions provide essential services to the language +(e.g., type and getmetatable); +others provide access to "outside" services (e.g., I/O); +and others could be implemented in Lua itself, +but are quite useful or have critical performance requirements that +deserve an implementation in C (e.g., table.sort). + + +

      +All libraries are implemented through the official C API +and are provided as separate C modules. +Currently, Lua has the following standard libraries: + +

        + +
      • basic library,
      • which includes the coroutine sub-library; + +
      • package library;
      • + +
      • string manipulation;
      • + +
      • table manipulation;
      • + +
      • mathematical functions (sin, log, etc.);
      • + +
      • input and output;
      • + +
      • operating system facilities;
      • + +
      • debug facilities.
      • + +

      +Except for the basic and package libraries, +each library provides all its functions as fields of a global table +or as methods of its objects. + + +

      +To have access to these libraries, +the C host program should call the luaL_openlibs function, +which opens all standard libraries. +Alternatively, +it can open them individually by calling +luaopen_base (for the basic library), +luaopen_package (for the package library), +luaopen_string (for the string library), +luaopen_table (for the table library), +luaopen_math (for the mathematical library), +luaopen_io (for the I/O library), +luaopen_os (for the Operating System library), +and luaopen_debug (for the debug library). +These functions are declared in lualib.h +and should not be called directly: +you must call them like any other Lua C function, +e.g., by using lua_call. + + + +

      5.1 - Basic Functions

      + +

      +The basic library provides some core functions to Lua. +If you do not include this library in your application, +you should check carefully whether you need to provide +implementations for some of its facilities. + + +

      +


      assert (v [, message])

      +Issues an error when +the value of its argument v is false (i.e., nil or false); +otherwise, returns all its arguments. +message is an error message; +when absent, it defaults to "assertion failed!" + + + + +

      +


      collectgarbage (opt [, arg])

      + + +

      +This function is a generic interface to the garbage collector. +It performs different functions according to its first argument, opt: + +

        + +
      • "stop": +stops the garbage collector. +
      • + +
      • "restart": +restarts the garbage collector. +
      • + +
      • "collect": +performs a full garbage-collection cycle. +
      • + +
      • "count": +returns the total memory in use by Lua (in Kbytes). +
      • + +
      • "step": +performs a garbage-collection step. +The step "size" is controlled by arg +(larger values mean more steps) in a non-specified way. +If you want to control the step size +you must experimentally tune the value of arg. +Returns true if the step finished a collection cycle. +
      • + +
      • "setpause": +sets arg as the new value for the pause of +the collector (see §2.10). +Returns the previous value for pause. +
      • + +
      • "setstepmul": +sets arg as the new value for the step multiplier of +the collector (see §2.10). +Returns the previous value for step. +
      • + +
      + + + +

      +


      dofile (filename)

      +Opens the named file and executes its contents as a Lua chunk. +When called without arguments, +dofile executes the contents of the standard input (stdin). +Returns all values returned by the chunk. +In case of errors, dofile propagates the error +to its caller (that is, dofile does not run in protected mode). + + + + +

      +


      error (message [, level])

      +Terminates the last protected function called +and returns message as the error message. +Function error never returns. + + +

      +Usually, error adds some information about the error position +at the beginning of the message. +The level argument specifies how to get the error position. +With level 1 (the default), the error position is where the +error function was called. +Level 2 points the error to where the function +that called error was called; and so on. +Passing a level 0 avoids the addition of error position information +to the message. + + + + +

      +


      _G

      +A global variable (not a function) that +holds the global environment (that is, _G._G = _G). +Lua itself does not use this variable; +changing its value does not affect any environment, +nor vice-versa. +(Use setfenv to change environments.) + + + + +

      +


      getfenv ([f])

      +Returns the current environment in use by the function. +f can be a Lua function or a number +that specifies the function at that stack level: +Level 1 is the function calling getfenv. +If the given function is not a Lua function, +or if f is 0, +getfenv returns the global environment. +The default for f is 1. + + + + +

      +


      getmetatable (object)

      + + +

      +If object does not have a metatable, returns nil. +Otherwise, +if the object's metatable has a "__metatable" field, +returns the associated value. +Otherwise, returns the metatable of the given object. + + + + +

      +


      ipairs (t)

      + + +

      +Returns three values: an iterator function, the table t, and 0, +so that the construction + +

      +     for i,v in ipairs(t) do body end
      +

      +will iterate over the pairs (1,t[1]), (2,t[2]), ···, +up to the first integer key absent from the table. + + + + +

      +


      load (func [, chunkname])

      + + +

      +Loads a chunk using function func to get its pieces. +Each call to func must return a string that concatenates +with previous results. +A return of an empty string, nil, or no value signals the end of the chunk. + + +

      +If there are no errors, +returns the compiled chunk as a function; +otherwise, returns nil plus the error message. +The environment of the returned function is the global environment. + + +

      +chunkname is used as the chunk name for error messages +and debug information. +When absent, +it defaults to "=(load)". + + + + +

      +


      loadfile ([filename])

      + + +

      +Similar to load, +but gets the chunk from file filename +or from the standard input, +if no file name is given. + + + + +

      +


      loadstring (string [, chunkname])

      + + +

      +Similar to load, +but gets the chunk from the given string. + + +

      +To load and run a given string, use the idiom + +

      +     assert(loadstring(s))()
      +
      + +

      +When absent, +chunkname defaults to the given string. + + + + +

      +


      next (table [, index])

      + + +

      +Allows a program to traverse all fields of a table. +Its first argument is a table and its second argument +is an index in this table. +next returns the next index of the table +and its associated value. +When called with nil as its second argument, +next returns an initial index +and its associated value. +When called with the last index, +or with nil in an empty table, +next returns nil. +If the second argument is absent, then it is interpreted as nil. +In particular, +you can use next(t) to check whether a table is empty. + + +

      +The order in which the indices are enumerated is not specified, +even for numeric indices. +(To traverse a table in numeric order, +use a numerical for or the ipairs function.) + + +

      +The behavior of next is undefined if, +during the traversal, +you assign any value to a non-existent field in the table. +You may however modify existing fields. +In particular, you may clear existing fields. + + + + +

      +


      pairs (t)

      + + +

      +Returns three values: the next function, the table t, and nil, +so that the construction + +

      +     for k,v in pairs(t) do body end
      +

      +will iterate over all key–value pairs of table t. + + +

      +See function next for the caveats of modifying +the table during its traversal. + + + + +

      +


      pcall (f, arg1, ···)

      + + +

      +Calls function f with +the given arguments in protected mode. +This means that any error inside f is not propagated; +instead, pcall catches the error +and returns a status code. +Its first result is the status code (a boolean), +which is true if the call succeeds without errors. +In such case, pcall also returns all results from the call, +after this first result. +In case of any error, pcall returns false plus the error message. + + + + +

      +


      print (···)

      +Receives any number of arguments, +and prints their values to stdout, +using the tostring function to convert them to strings. +print is not intended for formatted output, +but only as a quick way to show a value, +typically for debugging. +For formatted output, use string.format. + + + + +

      +


      rawequal (v1, v2)

      +Checks whether v1 is equal to v2, +without invoking any metamethod. +Returns a boolean. + + + + +

      +


      rawget (table, index)

      +Gets the real value of table[index], +without invoking any metamethod. +table must be a table; +index may be any value. + + + + +

      +


      rawset (table, index, value)

      +Sets the real value of table[index] to value, +without invoking any metamethod. +table must be a table, +index any value different from nil, +and value any Lua value. + + +

      +This function returns table. + + + + +

      +


      select (index, ···)

      + + +

      +If index is a number, +returns all arguments after argument number index. +Otherwise, index must be the string "#", +and select returns the total number of extra arguments it received. + + + + +

      +


      setfenv (f, table)

      + + +

      +Sets the environment to be used by the given function. +f can be a Lua function or a number +that specifies the function at that stack level: +Level 1 is the function calling setfenv. +setfenv returns the given function. + + +

      +As a special case, when f is 0 setfenv changes +the environment of the running thread. +In this case, setfenv returns no values. + + + + +

      +


      setmetatable (table, metatable)

      + + +

      +Sets the metatable for the given table. +(You cannot change the metatable of other types from Lua, only from C.) +If metatable is nil, +removes the metatable of the given table. +If the original metatable has a "__metatable" field, +raises an error. + + +

      +This function returns table. + + + + +

      +


      tonumber (e [, base])

      +Tries to convert its argument to a number. +If the argument is already a number or a string convertible +to a number, then tonumber returns this number; +otherwise, it returns nil. + + +

      +An optional argument specifies the base to interpret the numeral. +The base may be any integer between 2 and 36, inclusive. +In bases above 10, the letter 'A' (in either upper or lower case) +represents 10, 'B' represents 11, and so forth, +with 'Z' representing 35. +In base 10 (the default), the number can have a decimal part, +as well as an optional exponent part (see §2.1). +In other bases, only unsigned integers are accepted. + + + + +

      +


      tostring (e)

      +Receives an argument of any type and +converts it to a string in a reasonable format. +For complete control of how numbers are converted, +use string.format. + + +

      +If the metatable of e has a "__tostring" field, +then tostring calls the corresponding value +with e as argument, +and uses the result of the call as its result. + + + + +

      +


      type (v)

      +Returns the type of its only argument, coded as a string. +The possible results of this function are +"nil" (a string, not the value nil), +"number", +"string", +"boolean", +"table", +"function", +"thread", +and "userdata". + + + + +

      +


      unpack (list [, i [, j]])

      +Returns the elements from the given table. +This function is equivalent to + +
      +     return list[i], list[i+1], ···, list[j]
      +

      +except that the above code can be written only for a fixed number +of elements. +By default, i is 1 and j is the length of the list, +as defined by the length operator (see §2.5.5). + + + + +

      +


      _VERSION

      +A global variable (not a function) that +holds a string containing the current interpreter version. +The current contents of this variable is "Lua 5.1". + + + + +

      +


      xpcall (f, err)

      + + +

      +This function is similar to pcall, +except that you can set a new error handler. + + +

      +xpcall calls function f in protected mode, +using err as the error handler. +Any error inside f is not propagated; +instead, xpcall catches the error, +calls the err function with the original error object, +and returns a status code. +Its first result is the status code (a boolean), +which is true if the call succeeds without errors. +In this case, xpcall also returns all results from the call, +after this first result. +In case of any error, +xpcall returns false plus the result from err. + + + + + + + +

      5.2 - Coroutine Manipulation

      + +

      +The operations related to coroutines comprise a sub-library of +the basic library and come inside the table coroutine. +See §2.11 for a general description of coroutines. + + +

      +


      coroutine.create (f)

      + + +

      +Creates a new coroutine, with body f. +f must be a Lua function. +Returns this new coroutine, +an object with type "thread". + + + + +

      +


      coroutine.resume (co [, val1, ···])

      + + +

      +Starts or continues the execution of coroutine co. +The first time you resume a coroutine, +it starts running its body. +The values val1, ··· are passed +as the arguments to the body function. +If the coroutine has yielded, +resume restarts it; +the values val1, ··· are passed +as the results from the yield. + + +

      +If the coroutine runs without any errors, +resume returns true plus any values passed to yield +(if the coroutine yields) or any values returned by the body function +(if the coroutine terminates). +If there is any error, +resume returns false plus the error message. + + + + +

      +


      coroutine.running ()

      + + +

      +Returns the running coroutine, +or nil when called by the main thread. + + + + +

      +


      coroutine.status (co)

      + + +

      +Returns the status of coroutine co, as a string: +"running", +if the coroutine is running (that is, it called status); +"suspended", if the coroutine is suspended in a call to yield, +or if it has not started running yet; +"normal" if the coroutine is active but not running +(that is, it has resumed another coroutine); +and "dead" if the coroutine has finished its body function, +or if it has stopped with an error. + + + + +

      +


      coroutine.wrap (f)

      + + +

      +Creates a new coroutine, with body f. +f must be a Lua function. +Returns a function that resumes the coroutine each time it is called. +Any arguments passed to the function behave as the +extra arguments to resume. +Returns the same values returned by resume, +except the first boolean. +In case of error, propagates the error. + + + + +

      +


      coroutine.yield (···)

      + + +

      +Suspends the execution of the calling coroutine. +The coroutine cannot be running a C function, +a metamethod, or an iterator. +Any arguments to yield are passed as extra results to resume. + + + + + + + +

      5.3 - Modules

      + +

      +The package library provides basic +facilities for loading and building modules in Lua. +It exports two of its functions directly in the global environment: +require and module. +Everything else is exported in a table package. + + +

      +


      module (name [, ···])

      + + +

      +Creates a module. +If there is a table in package.loaded[name], +this table is the module. +Otherwise, if there is a global table t with the given name, +this table is the module. +Otherwise creates a new table t and +sets it as the value of the global name and +the value of package.loaded[name]. +This function also initializes t._NAME with the given name, +t._M with the module (t itself), +and t._PACKAGE with the package name +(the full module name minus last component; see below). +Finally, module sets t as the new environment +of the current function and the new value of package.loaded[name], +so that require returns t. + + +

      +If name is a compound name +(that is, one with components separated by dots), +module creates (or reuses, if they already exist) +tables for each component. +For instance, if name is a.b.c, +then module stores the module table in field c of +field b of global a. + + +

      +This function can receive optional options after +the module name, +where each option is a function to be applied over the module. + + + + +

      +


      require (modname)

      + + +

      +Loads the given module. +The function starts by looking into the package.loaded table +to determine whether modname is already loaded. +If it is, then require returns the value stored +at package.loaded[modname]. +Otherwise, it tries to find a loader for the module. + + +

      +To find a loader, +require is guided by the package.loaders array. +By changing this array, +we can change how require looks for a module. +The following explanation is based on the default configuration +for package.loaders. + + +

      +First require queries package.preload[modname]. +If it has a value, +this value (which should be a function) is the loader. +Otherwise require searches for a Lua loader using the +path stored in package.path. +If that also fails, it searches for a C loader using the +path stored in package.cpath. +If that also fails, +it tries an all-in-one loader (see package.loaders). + + +

      +Once a loader is found, +require calls the loader with a single argument, modname. +If the loader returns any value, +require assigns the returned value to package.loaded[modname]. +If the loader returns no value and +has not assigned any value to package.loaded[modname], +then require assigns true to this entry. +In any case, require returns the +final value of package.loaded[modname]. + + +

      +If there is any error loading or running the module, +or if it cannot find any loader for the module, +then require signals an error. + + + + +

      +


      package.cpath

      + + +

      +The path used by require to search for a C loader. + + +

      +Lua initializes the C path package.cpath in the same way +it initializes the Lua path package.path, +using the environment variable LUA_CPATH +or a default path defined in luaconf.h. + + + + +

      + +


      package.loaded

      + + +

      +A table used by require to control which +modules are already loaded. +When you require a module modname and +package.loaded[modname] is not false, +require simply returns the value stored there. + + + + +

      +


      package.loaders

      + + +

      +A table used by require to control how to load modules. + + +

      +Each entry in this table is a searcher function. +When looking for a module, +require calls each of these searchers in ascending order, +with the module name (the argument given to require) as its +sole parameter. +The function can return another function (the module loader) +or a string explaining why it did not find that module +(or nil if it has nothing to say). +Lua initializes this table with four functions. + + +

      +The first searcher simply looks for a loader in the +package.preload table. + + +

      +The second searcher looks for a loader as a Lua library, +using the path stored at package.path. +A path is a sequence of templates separated by semicolons. +For each template, +the searcher will change each interrogation +mark in the template by filename, +which is the module name with each dot replaced by a +"directory separator" (such as "/" in Unix); +then it will try to open the resulting file name. +So, for instance, if the Lua path is the string + +

      +     "./?.lua;./?.lc;/usr/local/?/init.lua"
      +

      +the search for a Lua file for module foo +will try to open the files +./foo.lua, ./foo.lc, and +/usr/local/foo/init.lua, in that order. + + +

      +The third searcher looks for a loader as a C library, +using the path given by the variable package.cpath. +For instance, +if the C path is the string + +

      +     "./?.so;./?.dll;/usr/local/?/init.so"
      +

      +the searcher for module foo +will try to open the files ./foo.so, ./foo.dll, +and /usr/local/foo/init.so, in that order. +Once it finds a C library, +this searcher first uses a dynamic link facility to link the +application with the library. +Then it tries to find a C function inside the library to +be used as the loader. +The name of this C function is the string "luaopen_" +concatenated with a copy of the module name where each dot +is replaced by an underscore. +Moreover, if the module name has a hyphen, +its prefix up to (and including) the first hyphen is removed. +For instance, if the module name is a.v1-b.c, +the function name will be luaopen_b_c. + + +

      +The fourth searcher tries an all-in-one loader. +It searches the C path for a library for +the root name of the given module. +For instance, when requiring a.b.c, +it will search for a C library for a. +If found, it looks into it for an open function for +the submodule; +in our example, that would be luaopen_a_b_c. +With this facility, a package can pack several C submodules +into one single library, +with each submodule keeping its original open function. + + + + +

      +


      package.loadlib (libname, funcname)

      + + +

      +Dynamically links the host program with the C library libname. +Inside this library, looks for a function funcname +and returns this function as a C function. +(So, funcname must follow the protocol (see lua_CFunction)). + + +

      +This is a low-level function. +It completely bypasses the package and module system. +Unlike require, +it does not perform any path searching and +does not automatically adds extensions. +libname must be the complete file name of the C library, +including if necessary a path and extension. +funcname must be the exact name exported by the C library +(which may depend on the C compiler and linker used). + + +

      +This function is not supported by ANSI C. +As such, it is only available on some platforms +(Windows, Linux, Mac OS X, Solaris, BSD, +plus other Unix systems that support the dlfcn standard). + + + + +

      +


      package.path

      + + +

      +The path used by require to search for a Lua loader. + + +

      +At start-up, Lua initializes this variable with +the value of the environment variable LUA_PATH or +with a default path defined in luaconf.h, +if the environment variable is not defined. +Any ";;" in the value of the environment variable +is replaced by the default path. + + + + +

      +


      package.preload

      + + +

      +A table to store loaders for specific modules +(see require). + + + + +

      +


      package.seeall (module)

      + + +

      +Sets a metatable for module with +its __index field referring to the global environment, +so that this module inherits values +from the global environment. +To be used as an option to function module. + + + + + + + +

      5.4 - String Manipulation

      + +

      +This library provides generic functions for string manipulation, +such as finding and extracting substrings, and pattern matching. +When indexing a string in Lua, the first character is at position 1 +(not at 0, as in C). +Indices are allowed to be negative and are interpreted as indexing backwards, +from the end of the string. +Thus, the last character is at position -1, and so on. + + +

      +The string library provides all its functions inside the table +string. +It also sets a metatable for strings +where the __index field points to the string table. +Therefore, you can use the string functions in object-oriented style. +For instance, string.byte(s, i) +can be written as s:byte(i). + + +

      +The string library assumes one-byte character encodings. + + +

      +


      string.byte (s [, i [, j]])

      +Returns the internal numerical codes of the characters s[i], +s[i+1], ···, s[j]. +The default value for i is 1; +the default value for j is i. + + +

      +Note that numerical codes are not necessarily portable across platforms. + + + + +

      +


      string.char (···)

      +Receives zero or more integers. +Returns a string with length equal to the number of arguments, +in which each character has the internal numerical code equal +to its corresponding argument. + + +

      +Note that numerical codes are not necessarily portable across platforms. + + + + +

      +


      string.dump (function)

      + + +

      +Returns a string containing a binary representation of the given function, +so that a later loadstring on this string returns +a copy of the function. +function must be a Lua function without upvalues. + + + + +

      +


      string.find (s, pattern [, init [, plain]])

      +Looks for the first match of +pattern in the string s. +If it finds a match, then find returns the indices of s +where this occurrence starts and ends; +otherwise, it returns nil. +A third, optional numerical argument init specifies +where to start the search; +its default value is 1 and can be negative. +A value of true as a fourth, optional argument plain +turns off the pattern matching facilities, +so the function does a plain "find substring" operation, +with no characters in pattern being considered "magic". +Note that if plain is given, then init must be given as well. + + +

      +If the pattern has captures, +then in a successful match +the captured values are also returned, +after the two indices. + + + + +

      +


      string.format (formatstring, ···)

      +Returns a formatted version of its variable number of arguments +following the description given in its first argument (which must be a string). +The format string follows the same rules as the printf family of +standard C functions. +The only differences are that the options/modifiers +*, l, L, n, p, +and h are not supported +and that there is an extra option, q. +The q option formats a string in a form suitable to be safely read +back by the Lua interpreter: +the string is written between double quotes, +and all double quotes, newlines, embedded zeros, +and backslashes in the string +are correctly escaped when written. +For instance, the call + +
      +     string.format('%q', 'a string with "quotes" and \n new line')
      +

      +will produce the string: + +

      +     "a string with \"quotes\" and \
      +      new line"
      +
      + +

      +The options c, d, E, e, f, +g, G, i, o, u, X, and x all +expect a number as argument, +whereas q and s expect a string. + + +

      +This function does not accept string values +containing embedded zeros, +except as arguments to the q option. + + + + +

      +


      string.gmatch (s, pattern)

      +Returns an iterator function that, +each time it is called, +returns the next captures from pattern over string s. +If pattern specifies no captures, +then the whole match is produced in each call. + + +

      +As an example, the following loop + +

      +     s = "hello world from Lua"
      +     for w in string.gmatch(s, "%a+") do
      +       print(w)
      +     end
      +

      +will iterate over all the words from string s, +printing one per line. +The next example collects all pairs key=value from the +given string into a table: + +

      +     t = {}
      +     s = "from=world, to=Lua"
      +     for k, v in string.gmatch(s, "(%w+)=(%w+)") do
      +       t[k] = v
      +     end
      +
      + +

      +For this function, a '^' at the start of a pattern does not +work as an anchor, as this would prevent the iteration. + + + + +

      +


      string.gsub (s, pattern, repl [, n])

      +Returns a copy of s +in which all (or the first n, if given) +occurrences of the pattern have been +replaced by a replacement string specified by repl, +which can be a string, a table, or a function. +gsub also returns, as its second value, +the total number of matches that occurred. + + +

      +If repl is a string, then its value is used for replacement. +The character % works as an escape character: +any sequence in repl of the form %n, +with n between 1 and 9, +stands for the value of the n-th captured substring (see below). +The sequence %0 stands for the whole match. +The sequence %% stands for a single %. + + +

      +If repl is a table, then the table is queried for every match, +using the first capture as the key; +if the pattern specifies no captures, +then the whole match is used as the key. + + +

      +If repl is a function, then this function is called every time a +match occurs, with all captured substrings passed as arguments, +in order; +if the pattern specifies no captures, +then the whole match is passed as a sole argument. + + +

      +If the value returned by the table query or by the function call +is a string or a number, +then it is used as the replacement string; +otherwise, if it is false or nil, +then there is no replacement +(that is, the original match is kept in the string). + + +

      +Here are some examples: + +

      +     x = string.gsub("hello world", "(%w+)", "%1 %1")
      +     --> x="hello hello world world"
      +     
      +     x = string.gsub("hello world", "%w+", "%0 %0", 1)
      +     --> x="hello hello world"
      +     
      +     x = string.gsub("hello world from Lua", "(%w+)%s*(%w+)", "%2 %1")
      +     --> x="world hello Lua from"
      +     
      +     x = string.gsub("home = $HOME, user = $USER", "%$(%w+)", os.getenv)
      +     --> x="home = /home/roberto, user = roberto"
      +     
      +     x = string.gsub("4+5 = $return 4+5$", "%$(.-)%$", function (s)
      +           return loadstring(s)()
      +         end)
      +     --> x="4+5 = 9"
      +     
      +     local t = {name="lua", version="5.1"}
      +     x = string.gsub("$name-$version.tar.gz", "%$(%w+)", t)
      +     --> x="lua-5.1.tar.gz"
      +
      + + + +

      +


      string.len (s)

      +Receives a string and returns its length. +The empty string "" has length 0. +Embedded zeros are counted, +so "a\000bc\000" has length 5. + + + + +

      +


      string.lower (s)

      +Receives a string and returns a copy of this string with all +uppercase letters changed to lowercase. +All other characters are left unchanged. +The definition of what an uppercase letter is depends on the current locale. + + + + +

      +


      string.match (s, pattern [, init])

      +Looks for the first match of +pattern in the string s. +If it finds one, then match returns +the captures from the pattern; +otherwise it returns nil. +If pattern specifies no captures, +then the whole match is returned. +A third, optional numerical argument init specifies +where to start the search; +its default value is 1 and can be negative. + + + + +

      +


      string.rep (s, n)

      +Returns a string that is the concatenation of n copies of +the string s. + + + + +

      +


      string.reverse (s)

      +Returns a string that is the string s reversed. + + + + +

      +


      string.sub (s, i [, j])

      +Returns the substring of s that +starts at i and continues until j; +i and j can be negative. +If j is absent, then it is assumed to be equal to -1 +(which is the same as the string length). +In particular, +the call string.sub(s,1,j) returns a prefix of s +with length j, +and string.sub(s, -i) returns a suffix of s +with length i. + + + + +

      +


      string.upper (s)

      +Receives a string and returns a copy of this string with all +lowercase letters changed to uppercase. +All other characters are left unchanged. +The definition of what a lowercase letter is depends on the current locale. + + + +

      5.4.1 - Patterns

      + + +

      Character Class:

      +A character class is used to represent a set of characters. +The following combinations are allowed in describing a character class: + +

        + +
      • x: +(where x is not one of the magic characters +^$()%.[]*+-?) +represents the character x itself. +
      • + +
      • .: (a dot) represents all characters.
      • + +
      • %a: represents all letters.
      • + +
      • %c: represents all control characters.
      • + +
      • %d: represents all digits.
      • + +
      • %l: represents all lowercase letters.
      • + +
      • %p: represents all punctuation characters.
      • + +
      • %s: represents all space characters.
      • + +
      • %u: represents all uppercase letters.
      • + +
      • %w: represents all alphanumeric characters.
      • + +
      • %x: represents all hexadecimal digits.
      • + +
      • %z: represents the character with representation 0.
      • + +
      • %x: (where x is any non-alphanumeric character) +represents the character x. +This is the standard way to escape the magic characters. +Any punctuation character (even the non magic) +can be preceded by a '%' +when used to represent itself in a pattern. +
      • + +
      • [set]: +represents the class which is the union of all +characters in set. +A range of characters can be specified by +separating the end characters of the range with a '-'. +All classes %x described above can also be used as +components in set. +All other characters in set represent themselves. +For example, [%w_] (or [_%w]) +represents all alphanumeric characters plus the underscore, +[0-7] represents the octal digits, +and [0-7%l%-] represents the octal digits plus +the lowercase letters plus the '-' character. + + +

        +The interaction between ranges and classes is not defined. +Therefore, patterns like [%a-z] or [a-%%] +have no meaning. +

      • + +
      • [^set]: +represents the complement of set, +where set is interpreted as above. +
      • + +

      +For all classes represented by single letters (%a, %c, etc.), +the corresponding uppercase letter represents the complement of the class. +For instance, %S represents all non-space characters. + + +

      +The definitions of letter, space, and other character groups +depend on the current locale. +In particular, the class [a-z] may not be equivalent to %l. + + + + + +

      Pattern Item:

      +A pattern item can be + +

        + +
      • +a single character class, +which matches any single character in the class; +
      • + +
      • +a single character class followed by '*', +which matches 0 or more repetitions of characters in the class. +These repetition items will always match the longest possible sequence; +
      • + +
      • +a single character class followed by '+', +which matches 1 or more repetitions of characters in the class. +These repetition items will always match the longest possible sequence; +
      • + +
      • +a single character class followed by '-', +which also matches 0 or more repetitions of characters in the class. +Unlike '*', +these repetition items will always match the shortest possible sequence; +
      • + +
      • +a single character class followed by '?', +which matches 0 or 1 occurrence of a character in the class; +
      • + +
      • +%n, for n between 1 and 9; +such item matches a substring equal to the n-th captured string +(see below); +
      • + +
      • +%bxy, where x and y are two distinct characters; +such item matches strings that start with x, end with y, +and where the x and y are balanced. +This means that, if one reads the string from left to right, +counting +1 for an x and -1 for a y, +the ending y is the first y where the count reaches 0. +For instance, the item %b() matches expressions with +balanced parentheses. +
      • + +
      + + + + +

      Pattern:

      +A pattern is a sequence of pattern items. +A '^' at the beginning of a pattern anchors the match at the +beginning of the subject string. +A '$' at the end of a pattern anchors the match at the +end of the subject string. +At other positions, +'^' and '$' have no special meaning and represent themselves. + + + + + +

      Captures:

      +A pattern can contain sub-patterns enclosed in parentheses; +they describe captures. +When a match succeeds, the substrings of the subject string +that match captures are stored (captured) for future use. +Captures are numbered according to their left parentheses. +For instance, in the pattern "(a*(.)%w(%s*))", +the part of the string matching "a*(.)%w(%s*)" is +stored as the first capture (and therefore has number 1); +the character matching "." is captured with number 2, +and the part matching "%s*" has number 3. + + +

      +As a special case, the empty capture () captures +the current string position (a number). +For instance, if we apply the pattern "()aa()" on the +string "flaaap", there will be two captures: 3 and 5. + + +

      +A pattern cannot contain embedded zeros. Use %z instead. + + + + + + + + + + + +

      5.5 - Table Manipulation

      +This library provides generic functions for table manipulation. +It provides all its functions inside the table table. + + +

      +Most functions in the table library assume that the table +represents an array or a list. +For these functions, when we talk about the "length" of a table +we mean the result of the length operator. + + +

      +


      table.concat (table [, sep [, i [, j]]])

      +Given an array where all elements are strings or numbers, +returns table[i]..sep..table[i+1] ··· sep..table[j]. +The default value for sep is the empty string, +the default for i is 1, +and the default for j is the length of the table. +If i is greater than j, returns the empty string. + + + + +

      +


      table.insert (table, [pos,] value)

      + + +

      +Inserts element value at position pos in table, +shifting up other elements to open space, if necessary. +The default value for pos is n+1, +where n is the length of the table (see §2.5.5), +so that a call table.insert(t,x) inserts x at the end +of table t. + + + + +

      +


      table.maxn (table)

      + + +

      +Returns the largest positive numerical index of the given table, +or zero if the table has no positive numerical indices. +(To do its job this function does a linear traversal of +the whole table.) + + + + +

      +


      table.remove (table [, pos])

      + + +

      +Removes from table the element at position pos, +shifting down other elements to close the space, if necessary. +Returns the value of the removed element. +The default value for pos is n, +where n is the length of the table, +so that a call table.remove(t) removes the last element +of table t. + + + + +

      +


      table.sort (table [, comp])

      +Sorts table elements in a given order, in-place, +from table[1] to table[n], +where n is the length of the table. +If comp is given, +then it must be a function that receives two table elements, +and returns true +when the first is less than the second +(so that not comp(a[i+1],a[i]) will be true after the sort). +If comp is not given, +then the standard Lua operator < is used instead. + + +

      +The sort algorithm is not stable; +that is, elements considered equal by the given order +may have their relative positions changed by the sort. + + + + + + + +

      5.6 - Mathematical Functions

      + +

      +This library is an interface to the standard C math library. +It provides all its functions inside the table math. + + +

      +


      math.abs (x)

      + + +

      +Returns the absolute value of x. + + + + +

      +


      math.acos (x)

      + + +

      +Returns the arc cosine of x (in radians). + + + + +

      +


      math.asin (x)

      + + +

      +Returns the arc sine of x (in radians). + + + + +

      +


      math.atan (x)

      + + +

      +Returns the arc tangent of x (in radians). + + + + +

      +


      math.atan2 (y, x)

      + + +

      +Returns the arc tangent of y/x (in radians), +but uses the signs of both parameters to find the +quadrant of the result. +(It also handles correctly the case of x being zero.) + + + + +

      +


      math.ceil (x)

      + + +

      +Returns the smallest integer larger than or equal to x. + + + + +

      +


      math.cos (x)

      + + +

      +Returns the cosine of x (assumed to be in radians). + + + + +

      +


      math.cosh (x)

      + + +

      +Returns the hyperbolic cosine of x. + + + + +

      +


      math.deg (x)

      + + +

      +Returns the angle x (given in radians) in degrees. + + + + +

      +


      math.exp (x)

      + + +

      +Returns the value ex. + + + + +

      +


      math.floor (x)

      + + +

      +Returns the largest integer smaller than or equal to x. + + + + +

      +


      math.fmod (x, y)

      + + +

      +Returns the remainder of the division of x by y +that rounds the quotient towards zero. + + + + +

      +


      math.frexp (x)

      + + +

      +Returns m and e such that x = m2e, +e is an integer and the absolute value of m is +in the range [0.5, 1) +(or zero when x is zero). + + + + +

      +


      math.huge

      + + +

      +The value HUGE_VAL, +a value larger than or equal to any other numerical value. + + + + +

      +


      math.ldexp (m, e)

      + + +

      +Returns m2e (e should be an integer). + + + + +

      +


      math.log (x)

      + + +

      +Returns the natural logarithm of x. + + + + +

      +


      math.log10 (x)

      + + +

      +Returns the base-10 logarithm of x. + + + + +

      +


      math.max (x, ···)

      + + +

      +Returns the maximum value among its arguments. + + + + +

      +


      math.min (x, ···)

      + + +

      +Returns the minimum value among its arguments. + + + + +

      +


      math.modf (x)

      + + +

      +Returns two numbers, +the integral part of x and the fractional part of x. + + + + +

      +


      math.pi

      + + +

      +The value of pi. + + + + +

      +


      math.pow (x, y)

      + + +

      +Returns xy. +(You can also use the expression x^y to compute this value.) + + + + +

      +


      math.rad (x)

      + + +

      +Returns the angle x (given in degrees) in radians. + + + + +

      +


      math.random ([m [, n]])

      + + +

      +This function is an interface to the simple +pseudo-random generator function rand provided by ANSI C. +(No guarantees can be given for its statistical properties.) + + +

      +When called without arguments, +returns a uniform pseudo-random real number +in the range [0,1). +When called with an integer number m, +math.random returns +a uniform pseudo-random integer in the range [1, m]. +When called with two integer numbers m and n, +math.random returns a uniform pseudo-random +integer in the range [m, n]. + + + + +

      +


      math.randomseed (x)

      + + +

      +Sets x as the "seed" +for the pseudo-random generator: +equal seeds produce equal sequences of numbers. + + + + +

      +


      math.sin (x)

      + + +

      +Returns the sine of x (assumed to be in radians). + + + + +

      +


      math.sinh (x)

      + + +

      +Returns the hyperbolic sine of x. + + + + +

      +


      math.sqrt (x)

      + + +

      +Returns the square root of x. +(You can also use the expression x^0.5 to compute this value.) + + + + +

      +


      math.tan (x)

      + + +

      +Returns the tangent of x (assumed to be in radians). + + + + +

      +


      math.tanh (x)

      + + +

      +Returns the hyperbolic tangent of x. + + + + + + + +

      5.7 - Input and Output Facilities

      + +

      +The I/O library provides two different styles for file manipulation. +The first one uses implicit file descriptors; +that is, there are operations to set a default input file and a +default output file, +and all input/output operations are over these default files. +The second style uses explicit file descriptors. + + +

      +When using implicit file descriptors, +all operations are supplied by table io. +When using explicit file descriptors, +the operation io.open returns a file descriptor +and then all operations are supplied as methods of the file descriptor. + + +

      +The table io also provides +three predefined file descriptors with their usual meanings from C: +io.stdin, io.stdout, and io.stderr. +The I/O library never closes these files. + + +

      +Unless otherwise stated, +all I/O functions return nil on failure +(plus an error message as a second result and +a system-dependent error code as a third result) +and some value different from nil on success. + + +

      +


      io.close ([file])

      + + +

      +Equivalent to file:close(). +Without a file, closes the default output file. + + + + +

      +


      io.flush ()

      + + +

      +Equivalent to file:flush over the default output file. + + + + +

      +


      io.input ([file])

      + + +

      +When called with a file name, it opens the named file (in text mode), +and sets its handle as the default input file. +When called with a file handle, +it simply sets this file handle as the default input file. +When called without parameters, +it returns the current default input file. + + +

      +In case of errors this function raises the error, +instead of returning an error code. + + + + +

      +


      io.lines ([filename])

      + + +

      +Opens the given file name in read mode +and returns an iterator function that, +each time it is called, +returns a new line from the file. +Therefore, the construction + +

      +     for line in io.lines(filename) do body end
      +

      +will iterate over all lines of the file. +When the iterator function detects the end of file, +it returns nil (to finish the loop) and automatically closes the file. + + +

      +The call io.lines() (with no file name) is equivalent +to io.input():lines(); +that is, it iterates over the lines of the default input file. +In this case it does not close the file when the loop ends. + + + + +

      +


      io.open (filename [, mode])

      + + +

      +This function opens a file, +in the mode specified in the string mode. +It returns a new file handle, +or, in case of errors, nil plus an error message. + + +

      +The mode string can be any of the following: + +

        +
      • "r": read mode (the default);
      • +
      • "w": write mode;
      • +
      • "a": append mode;
      • +
      • "r+": update mode, all previous data is preserved;
      • +
      • "w+": update mode, all previous data is erased;
      • +
      • "a+": append update mode, previous data is preserved, + writing is only allowed at the end of file.
      • +

      +The mode string can also have a 'b' at the end, +which is needed in some systems to open the file in binary mode. +This string is exactly what is used in the +standard C function fopen. + + + + +

      +


      io.output ([file])

      + + +

      +Similar to io.input, but operates over the default output file. + + + + +

      +


      io.popen (prog [, mode])

      + + +

      +Starts program prog in a separated process and returns +a file handle that you can use to read data from this program +(if mode is "r", the default) +or to write data to this program +(if mode is "w"). + + +

      +This function is system dependent and is not available +on all platforms. + + + + +

      +


      io.read (···)

      + + +

      +Equivalent to io.input():read. + + + + +

      +


      io.tmpfile ()

      + + +

      +Returns a handle for a temporary file. +This file is opened in update mode +and it is automatically removed when the program ends. + + + + +

      +


      io.type (obj)

      + + +

      +Checks whether obj is a valid file handle. +Returns the string "file" if obj is an open file handle, +"closed file" if obj is a closed file handle, +or nil if obj is not a file handle. + + + + +

      +


      io.write (···)

      + + +

      +Equivalent to io.output():write. + + + + +

      +


      file:close ()

      + + +

      +Closes file. +Note that files are automatically closed when +their handles are garbage collected, +but that takes an unpredictable amount of time to happen. + + + + +

      +


      file:flush ()

      + + +

      +Saves any written data to file. + + + + +

      +


      file:lines ()

      + + +

      +Returns an iterator function that, +each time it is called, +returns a new line from the file. +Therefore, the construction + +

      +     for line in file:lines() do body end
      +

      +will iterate over all lines of the file. +(Unlike io.lines, this function does not close the file +when the loop ends.) + + + + +

      +


      file:read (···)

      + + +

      +Reads the file file, +according to the given formats, which specify what to read. +For each format, +the function returns a string (or a number) with the characters read, +or nil if it cannot read data with the specified format. +When called without formats, +it uses a default format that reads the entire next line +(see below). + + +

      +The available formats are + +

        + +
      • "*n": +reads a number; +this is the only format that returns a number instead of a string. +
      • + +
      • "*a": +reads the whole file, starting at the current position. +On end of file, it returns the empty string. +
      • + +
      • "*l": +reads the next line (skipping the end of line), +returning nil on end of file. +This is the default format. +
      • + +
      • number: +reads a string with up to this number of characters, +returning nil on end of file. +If number is zero, +it reads nothing and returns an empty string, +or nil on end of file. +
      • + +
      + + + +

      +


      file:seek ([whence] [, offset])

      + + +

      +Sets and gets the file position, +measured from the beginning of the file, +to the position given by offset plus a base +specified by the string whence, as follows: + +

        +
      • "set": base is position 0 (beginning of the file);
      • +
      • "cur": base is current position;
      • +
      • "end": base is end of file;
      • +

      +In case of success, function seek returns the final file position, +measured in bytes from the beginning of the file. +If this function fails, it returns nil, +plus a string describing the error. + + +

      +The default value for whence is "cur", +and for offset is 0. +Therefore, the call file:seek() returns the current +file position, without changing it; +the call file:seek("set") sets the position to the +beginning of the file (and returns 0); +and the call file:seek("end") sets the position to the +end of the file, and returns its size. + + + + +

      +


      file:setvbuf (mode [, size])

      + + +

      +Sets the buffering mode for an output file. +There are three available modes: + +

        + +
      • "no": +no buffering; the result of any output operation appears immediately. +
      • + +
      • "full": +full buffering; output operation is performed only +when the buffer is full (or when you explicitly flush the file +(see io.flush)). +
      • + +
      • "line": +line buffering; output is buffered until a newline is output +or there is any input from some special files +(such as a terminal device). +
      • + +

      +For the last two cases, size +specifies the size of the buffer, in bytes. +The default is an appropriate size. + + + + +

      +


      file:write (···)

      + + +

      +Writes the value of each of its arguments to +the file. +The arguments must be strings or numbers. +To write other values, +use tostring or string.format before write. + + + + + + + +

      5.8 - Operating System Facilities

      + +

      +This library is implemented through table os. + + +

      +


      os.clock ()

      + + +

      +Returns an approximation of the amount in seconds of CPU time +used by the program. + + + + +

      +


      os.date ([format [, time]])

      + + +

      +Returns a string or a table containing date and time, +formatted according to the given string format. + + +

      +If the time argument is present, +this is the time to be formatted +(see the os.time function for a description of this value). +Otherwise, date formats the current time. + + +

      +If format starts with '!', +then the date is formatted in Coordinated Universal Time. +After this optional character, +if format is the string "*t", +then date returns a table with the following fields: +year (four digits), month (1--12), day (1--31), +hour (0--23), min (0--59), sec (0--61), +wday (weekday, Sunday is 1), +yday (day of the year), +and isdst (daylight saving flag, a boolean). + + +

      +If format is not "*t", +then date returns the date as a string, +formatted according to the same rules as the C function strftime. + + +

      +When called without arguments, +date returns a reasonable date and time representation that depends on +the host system and on the current locale +(that is, os.date() is equivalent to os.date("%c")). + + + + +

      +


      os.difftime (t2, t1)

      + + +

      +Returns the number of seconds from time t1 to time t2. +In POSIX, Windows, and some other systems, +this value is exactly t2-t1. + + + + +

      +


      os.execute ([command])

      + + +

      +This function is equivalent to the C function system. +It passes command to be executed by an operating system shell. +It returns a status code, which is system-dependent. +If command is absent, then it returns nonzero if a shell is available +and zero otherwise. + + + + +

      +


      os.exit ([code])

      + + +

      +Calls the C function exit, +with an optional code, +to terminate the host program. +The default value for code is the success code. + + + + +

      +


      os.getenv (varname)

      + + +

      +Returns the value of the process environment variable varname, +or nil if the variable is not defined. + + + + +

      +


      os.remove (filename)

      + + +

      +Deletes the file or directory with the given name. +Directories must be empty to be removed. +If this function fails, it returns nil, +plus a string describing the error. + + + + +

      +


      os.rename (oldname, newname)

      + + +

      +Renames file or directory named oldname to newname. +If this function fails, it returns nil, +plus a string describing the error. + + + + +

      +


      os.setlocale (locale [, category])

      + + +

      +Sets the current locale of the program. +locale is a string specifying a locale; +category is an optional string describing which category to change: +"all", "collate", "ctype", +"monetary", "numeric", or "time"; +the default category is "all". +The function returns the name of the new locale, +or nil if the request cannot be honored. + + +

      +If locale is the empty string, +the current locale is set to an implementation-defined native locale. +If locale is the string "C", +the current locale is set to the standard C locale. + + +

      +When called with nil as the first argument, +this function only returns the name of the current locale +for the given category. + + + + +

      +


      os.time ([table])

      + + +

      +Returns the current time when called without arguments, +or a time representing the date and time specified by the given table. +This table must have fields year, month, and day, +and may have fields hour, min, sec, and isdst +(for a description of these fields, see the os.date function). + + +

      +The returned value is a number, whose meaning depends on your system. +In POSIX, Windows, and some other systems, this number counts the number +of seconds since some given start time (the "epoch"). +In other systems, the meaning is not specified, +and the number returned by time can be used only as an argument to +date and difftime. + + + + +

      +


      os.tmpname ()

      + + +

      +Returns a string with a file name that can +be used for a temporary file. +The file must be explicitly opened before its use +and explicitly removed when no longer needed. + + +

      +On some systems (POSIX), +this function also creates a file with that name, +to avoid security risks. +(Someone else might create the file with wrong permissions +in the time between getting the name and creating the file.) +You still have to open the file to use it +and to remove it (even if you do not use it). + + +

      +When possible, +you may prefer to use io.tmpfile, +which automatically removes the file when the program ends. + + + + + + + +

      5.9 - The Debug Library

      + +

      +This library provides +the functionality of the debug interface to Lua programs. +You should exert care when using this library. +The functions provided here should be used exclusively for debugging +and similar tasks, such as profiling. +Please resist the temptation to use them as a +usual programming tool: +they can be very slow. +Moreover, several of these functions +violate some assumptions about Lua code +(e.g., that variables local to a function +cannot be accessed from outside or +that userdata metatables cannot be changed by Lua code) +and therefore can compromise otherwise secure code. + + +

      +All functions in this library are provided +inside the debug table. +All functions that operate over a thread +have an optional first argument which is the +thread to operate over. +The default is always the current thread. + + +

      +


      debug.debug ()

      + + +

      +Enters an interactive mode with the user, +running each string that the user enters. +Using simple commands and other debug facilities, +the user can inspect global and local variables, +change their values, evaluate expressions, and so on. +A line containing only the word cont finishes this function, +so that the caller continues its execution. + + +

      +Note that commands for debug.debug are not lexically nested +within any function, and so have no direct access to local variables. + + + + +

      +


      debug.getfenv (o)

      +Returns the environment of object o. + + + + +

      +


      debug.gethook ([thread])

      + + +

      +Returns the current hook settings of the thread, as three values: +the current hook function, the current hook mask, +and the current hook count +(as set by the debug.sethook function). + + + + +

      +


      debug.getinfo ([thread,] function [, what])

      + + +

      +Returns a table with information about a function. +You can give the function directly, +or you can give a number as the value of function, +which means the function running at level function of the call stack +of the given thread: +level 0 is the current function (getinfo itself); +level 1 is the function that called getinfo; +and so on. +If function is a number larger than the number of active functions, +then getinfo returns nil. + + +

      +The returned table can contain all the fields returned by lua_getinfo, +with the string what describing which fields to fill in. +The default for what is to get all information available, +except the table of valid lines. +If present, +the option 'f' +adds a field named func with the function itself. +If present, +the option 'L' +adds a field named activelines with the table of +valid lines. + + +

      +For instance, the expression debug.getinfo(1,"n").name returns +a table with a name for the current function, +if a reasonable name can be found, +and the expression debug.getinfo(print) +returns a table with all available information +about the print function. + + + + +

      +


      debug.getlocal ([thread,] level, local)

      + + +

      +This function returns the name and the value of the local variable +with index local of the function at level level of the stack. +(The first parameter or local variable has index 1, and so on, +until the last active local variable.) +The function returns nil if there is no local +variable with the given index, +and raises an error when called with a level out of range. +(You can call debug.getinfo to check whether the level is valid.) + + +

      +Variable names starting with '(' (open parentheses) +represent internal variables +(loop control variables, temporaries, and C function locals). + + + + +

      +


      debug.getmetatable (object)

      + + +

      +Returns the metatable of the given object +or nil if it does not have a metatable. + + + + +

      +


      debug.getregistry ()

      + + +

      +Returns the registry table (see §3.5). + + + + +

      +


      debug.getupvalue (func, up)

      + + +

      +This function returns the name and the value of the upvalue +with index up of the function func. +The function returns nil if there is no upvalue with the given index. + + + + +

      +


      debug.setfenv (object, table)

      + + +

      +Sets the environment of the given object to the given table. +Returns object. + + + + +

      +


      debug.sethook ([thread,] hook, mask [, count])

      + + +

      +Sets the given function as a hook. +The string mask and the number count describe +when the hook will be called. +The string mask may have the following characters, +with the given meaning: + +

        +
      • "c": the hook is called every time Lua calls a function;
      • +
      • "r": the hook is called every time Lua returns from a function;
      • +
      • "l": the hook is called every time Lua enters a new line of code.
      • +

      +With a count different from zero, +the hook is called after every count instructions. + + +

      +When called without arguments, +debug.sethook turns off the hook. + + +

      +When the hook is called, its first parameter is a string +describing the event that has triggered its call: +"call", "return" (or "tail return", +when simulating a return from a tail call), +"line", and "count". +For line events, +the hook also gets the new line number as its second parameter. +Inside a hook, +you can call getinfo with level 2 to get more information about +the running function +(level 0 is the getinfo function, +and level 1 is the hook function), +unless the event is "tail return". +In this case, Lua is only simulating the return, +and a call to getinfo will return invalid data. + + + + +

      +


      debug.setlocal ([thread,] level, local, value)

      + + +

      +This function assigns the value value to the local variable +with index local of the function at level level of the stack. +The function returns nil if there is no local +variable with the given index, +and raises an error when called with a level out of range. +(You can call getinfo to check whether the level is valid.) +Otherwise, it returns the name of the local variable. + + + + +

      +


      debug.setmetatable (object, table)

      + + +

      +Sets the metatable for the given object to the given table +(which can be nil). + + + + +

      +


      debug.setupvalue (func, up, value)

      + + +

      +This function assigns the value value to the upvalue +with index up of the function func. +The function returns nil if there is no upvalue +with the given index. +Otherwise, it returns the name of the upvalue. + + + + +

      +


      debug.traceback ([thread,] [message] [, level])

      + + +

      +Returns a string with a traceback of the call stack. +An optional message string is appended +at the beginning of the traceback. +An optional level number tells at which level +to start the traceback +(default is 1, the function calling traceback). + + + + + + + +

      6 - Lua Stand-alone

      + +

      +Although Lua has been designed as an extension language, +to be embedded in a host C program, +it is also frequently used as a stand-alone language. +An interpreter for Lua as a stand-alone language, +called simply lua, +is provided with the standard distribution. +The stand-alone interpreter includes +all standard libraries, including the debug library. +Its usage is: + +

      +     lua [options] [script [args]]
      +

      +The options are: + +

        +
      • -e stat: executes string stat;
      • +
      • -l mod: "requires" mod;
      • +
      • -i: enters interactive mode after running script;
      • +
      • -v: prints version information;
      • +
      • --: stops handling options;
      • +
      • -: executes stdin as a file and stops handling options.
      • +

      +After handling its options, lua runs the given script, +passing to it the given args as string arguments. +When called without arguments, +lua behaves as lua -v -i +when the standard input (stdin) is a terminal, +and as lua - otherwise. + + +

      +Before running any argument, +the interpreter checks for an environment variable LUA_INIT. +If its format is @filename, +then lua executes the file. +Otherwise, lua executes the string itself. + + +

      +All options are handled in order, except -i. +For instance, an invocation like + +

      +     $ lua -e'a=1' -e 'print(a)' script.lua
      +

      +will first set a to 1, then print the value of a (which is '1'), +and finally run the file script.lua with no arguments. +(Here $ is the shell prompt. Your prompt may be different.) + + +

      +Before starting to run the script, +lua collects all arguments in the command line +in a global table called arg. +The script name is stored at index 0, +the first argument after the script name goes to index 1, +and so on. +Any arguments before the script name +(that is, the interpreter name plus the options) +go to negative indices. +For instance, in the call + +

      +     $ lua -la b.lua t1 t2
      +

      +the interpreter first runs the file a.lua, +then creates a table + +

      +     arg = { [-2] = "lua", [-1] = "-la",
      +             [0] = "b.lua",
      +             [1] = "t1", [2] = "t2" }
      +

      +and finally runs the file b.lua. +The script is called with arg[1], arg[2], ··· +as arguments; +it can also access these arguments with the vararg expression '...'. + + +

      +In interactive mode, +if you write an incomplete statement, +the interpreter waits for its completion +by issuing a different prompt. + + +

      +If the global variable _PROMPT contains a string, +then its value is used as the prompt. +Similarly, if the global variable _PROMPT2 contains a string, +its value is used as the secondary prompt +(issued during incomplete statements). +Therefore, both prompts can be changed directly on the command line +or in any Lua programs by assigning to _PROMPT. +See the next example: + +

      +     $ lua -e"_PROMPT='myprompt> '" -i
      +

      +(The outer pair of quotes is for the shell, +the inner pair is for Lua.) +Note the use of -i to enter interactive mode; +otherwise, +the program would just end silently +right after the assignment to _PROMPT. + + +

      +To allow the use of Lua as a +script interpreter in Unix systems, +the stand-alone interpreter skips +the first line of a chunk if it starts with #. +Therefore, Lua scripts can be made into executable programs +by using chmod +x and the #! form, +as in + +

      +     #!/usr/local/bin/lua
      +

      +(Of course, +the location of the Lua interpreter may be different in your machine. +If lua is in your PATH, +then + +

      +     #!/usr/bin/env lua
      +

      +is a more portable solution.) + + + +

      7 - Incompatibilities with the Previous Version

      + +

      +Here we list the incompatibilities that you may find when moving a program +from Lua 5.0 to Lua 5.1. +You can avoid most of the incompatibilities compiling Lua with +appropriate options (see file luaconf.h). +However, +all these compatibility options will be removed in the next version of Lua. + + + +

      7.1 - Changes in the Language

      +
        + +
      • +The vararg system changed from the pseudo-argument arg with a +table with the extra arguments to the vararg expression. +(See compile-time option LUA_COMPAT_VARARG in luaconf.h.) +
      • + +
      • +There was a subtle change in the scope of the implicit +variables of the for statement and for the repeat statement. +
      • + +
      • +The long string/long comment syntax ([[string]]) +does not allow nesting. +You can use the new syntax ([=[string]=]) in these cases. +(See compile-time option LUA_COMPAT_LSTR in luaconf.h.) +
      • + +
      + + + + +

      7.2 - Changes in the Libraries

      +
        + +
      • +Function string.gfind was renamed string.gmatch. +(See compile-time option LUA_COMPAT_GFIND in luaconf.h.) +
      • + +
      • +When string.gsub is called with a function as its +third argument, +whenever this function returns nil or false the +replacement string is the whole match, +instead of the empty string. +
      • + +
      • +Function table.setn was deprecated. +Function table.getn corresponds +to the new length operator (#); +use the operator instead of the function. +(See compile-time option LUA_COMPAT_GETN in luaconf.h.) +
      • + +
      • +Function loadlib was renamed package.loadlib. +(See compile-time option LUA_COMPAT_LOADLIB in luaconf.h.) +
      • + +
      • +Function math.mod was renamed math.fmod. +(See compile-time option LUA_COMPAT_MOD in luaconf.h.) +
      • + +
      • +Functions table.foreach and table.foreachi are deprecated. +You can use a for loop with pairs or ipairs instead. +
      • + +
      • +There were substantial changes in function require due to +the new module system. +However, the new behavior is mostly compatible with the old, +but require gets the path from package.path instead +of from LUA_PATH. +
      • + +
      • +Function collectgarbage has different arguments. +Function gcinfo is deprecated; +use collectgarbage("count") instead. +
      • + +
      + + + + +

      7.3 - Changes in the API

      +
        + +
      • +The luaopen_* functions (to open libraries) +cannot be called directly, +like a regular C function. +They must be called through Lua, +like a Lua function. +
      • + +
      • +Function lua_open was replaced by lua_newstate to +allow the user to set a memory-allocation function. +You can use luaL_newstate from the standard library to +create a state with a standard allocation function +(based on realloc). +
      • + +
      • +Functions luaL_getn and luaL_setn +(from the auxiliary library) are deprecated. +Use lua_objlen instead of luaL_getn +and nothing instead of luaL_setn. +
      • + +
      • +Function luaL_openlib was replaced by luaL_register. +
      • + +
      • +Function luaL_checkudata now throws an error when the given value +is not a userdata of the expected type. +(In Lua 5.0 it returned NULL.) +
      • + +
      + + + + +

      8 - The Complete Syntax of Lua

      + +

      +Here is the complete syntax of Lua in extended BNF. +(It does not describe operator precedences.) + + + + +

      +
      +	chunk ::= {stat [`;´]} [laststat [`;´]]
      +
      +	block ::= chunk
      +
      +	stat ::=  varlist `=´ explist | 
      +		 functioncall | 
      +		 do block end | 
      +		 while exp do block end | 
      +		 repeat block until exp | 
      +		 if exp then block {elseif exp then block} [else block] end | 
      +		 for Name `=´ exp `,´ exp [`,´ exp] do block end | 
      +		 for namelist in explist do block end | 
      +		 function funcname funcbody | 
      +		 local function Name funcbody | 
      +		 local namelist [`=´ explist] 
      +
      +	laststat ::= return [explist] | break
      +
      +	funcname ::= Name {`.´ Name} [`:´ Name]
      +
      +	varlist ::= var {`,´ var}
      +
      +	var ::=  Name | prefixexp `[´ exp `]´ | prefixexp `.´ Name 
      +
      +	namelist ::= Name {`,´ Name}
      +
      +	explist ::= {exp `,´} exp
      +
      +	exp ::=  nil | false | true | Number | String | `...´ | function | 
      +		 prefixexp | tableconstructor | exp binop exp | unop exp 
      +
      +	prefixexp ::= var | functioncall | `(´ exp `)´
      +
      +	functioncall ::=  prefixexp args | prefixexp `:´ Name args 
      +
      +	args ::=  `(´ [explist] `)´ | tableconstructor | String 
      +
      +	function ::= function funcbody
      +
      +	funcbody ::= `(´ [parlist] `)´ block end
      +
      +	parlist ::= namelist [`,´ `...´] | `...´
      +
      +	tableconstructor ::= `{´ [fieldlist] `}´
      +
      +	fieldlist ::= field {fieldsep field} [fieldsep]
      +
      +	field ::= `[´ exp `]´ `=´ exp | Name `=´ exp | exp
      +
      +	fieldsep ::= `,´ | `;´
      +
      +	binop ::= `+´ | `-´ | `*´ | `/´ | `^´ | `%´ | `..´ | 
      +		 `<´ | `<=´ | `>´ | `>=´ | `==´ | `~=´ | 
      +		 and | or
      +
      +	unop ::= `-´ | not | `#´
      +
      +
      + +

      + + + + + + + +


      + +Last update: +Mon Aug 18 13:25:46 BRT 2008 + + + + + diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/doc/readme.html b/mod/pub.mod/lua.mod/lua-5.1.4/doc/readme.html new file mode 100644 index 0000000..38be6db --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/doc/readme.html @@ -0,0 +1,40 @@ + + +Lua documentation + + + + + +
      +

      +Lua +Documentation +

      + +This is the documentation included in the source distribution of Lua 5.1.4. + + + +Lua's +official web site +contains updated documentation, +especially the +reference manual. +

      + +


      + +Last update: +Tue Aug 12 14:46:07 BRT 2008 + + + + diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/etc/Makefile b/mod/pub.mod/lua.mod/lua-5.1.4/etc/Makefile new file mode 100644 index 0000000..6d00008 --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/etc/Makefile @@ -0,0 +1,44 @@ +# makefile for Lua etc + +TOP= .. +LIB= $(TOP)/src +INC= $(TOP)/src +BIN= $(TOP)/src +SRC= $(TOP)/src +TST= $(TOP)/test + +CC= gcc +CFLAGS= -O2 -Wall -I$(INC) $(MYCFLAGS) +MYCFLAGS= +MYLDFLAGS= -Wl,-E +MYLIBS= -lm +#MYLIBS= -lm -Wl,-E -ldl -lreadline -lhistory -lncurses +RM= rm -f + +default: + @echo 'Please choose a target: min noparser one strict clean' + +min: min.c + $(CC) $(CFLAGS) $@.c -L$(LIB) -llua $(MYLIBS) + echo 'print"Hello there!"' | ./a.out + +noparser: noparser.o + $(CC) noparser.o $(SRC)/lua.o -L$(LIB) -llua $(MYLIBS) + $(BIN)/luac $(TST)/hello.lua + -./a.out luac.out + -./a.out -e'a=1' + +one: + $(CC) $(CFLAGS) all.c $(MYLIBS) + ./a.out $(TST)/hello.lua + +strict: + -$(BIN)/lua -e 'print(a);b=2' + -$(BIN)/lua -lstrict -e 'print(a)' + -$(BIN)/lua -e 'function f() b=2 end f()' + -$(BIN)/lua -lstrict -e 'function f() b=2 end f()' + +clean: + $(RM) a.out core core.* *.o luac.out + +.PHONY: default min noparser one strict clean diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/etc/README b/mod/pub.mod/lua.mod/lua-5.1.4/etc/README new file mode 100644 index 0000000..5149fc9 --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/etc/README @@ -0,0 +1,37 @@ +This directory contains some useful files and code. +Unlike the code in ../src, everything here is in the public domain. + +If any of the makes fail, you're probably not using the same libraries +used to build Lua. Set MYLIBS in Makefile accordingly. + +all.c + Full Lua interpreter in a single file. + Do "make one" for a demo. + +lua.hpp + Lua header files for C++ using 'extern "C"'. + +lua.ico + A Lua icon for Windows (and web sites: save as favicon.ico). + Drawn by hand by Markus Gritsch . + +lua.pc + pkg-config data for Lua + +luavs.bat + Script to build Lua under "Visual Studio .NET Command Prompt". + Run it from the toplevel as etc\luavs.bat. + +min.c + A minimal Lua interpreter. + Good for learning and for starting your own. + Do "make min" for a demo. + +noparser.c + Linking with noparser.o avoids loading the parsing modules in lualib.a. + Do "make noparser" for a demo. + +strict.lua + Traps uses of undeclared global variables. + Do "make strict" for a demo. + diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/etc/all.c b/mod/pub.mod/lua.mod/lua-5.1.4/etc/all.c new file mode 100644 index 0000000..dab68fa --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/etc/all.c @@ -0,0 +1,38 @@ +/* +* all.c -- Lua core, libraries and interpreter in a single file +*/ + +#define luaall_c + +#include "lapi.c" +#include "lcode.c" +#include "ldebug.c" +#include "ldo.c" +#include "ldump.c" +#include "lfunc.c" +#include "lgc.c" +#include "llex.c" +#include "lmem.c" +#include "lobject.c" +#include "lopcodes.c" +#include "lparser.c" +#include "lstate.c" +#include "lstring.c" +#include "ltable.c" +#include "ltm.c" +#include "lundump.c" +#include "lvm.c" +#include "lzio.c" + +#include "lauxlib.c" +#include "lbaselib.c" +#include "ldblib.c" +#include "liolib.c" +#include "linit.c" +#include "lmathlib.c" +#include "loadlib.c" +#include "loslib.c" +#include "lstrlib.c" +#include "ltablib.c" + +#include "lua.c" diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/etc/lua.hpp b/mod/pub.mod/lua.mod/lua-5.1.4/etc/lua.hpp new file mode 100644 index 0000000..ec417f5 --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/etc/lua.hpp @@ -0,0 +1,9 @@ +// lua.hpp +// Lua header files for C++ +// <> not supplied automatically because Lua also compiles as C++ + +extern "C" { +#include "lua.h" +#include "lualib.h" +#include "lauxlib.h" +} diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/etc/lua.ico b/mod/pub.mod/lua.mod/lua-5.1.4/etc/lua.ico new file mode 100644 index 0000000000000000000000000000000000000000..ccbabc4e2004683f29598a991006d7caff6d837d GIT binary patch literal 1078 zcma)5y>7xl4E|D3VJbX9VX7GW1~6FSw!BIQq_T0tNo32b^bxZ4H5fZGR7xh?&v!Y3 zDh3=J`#b+#Yy%W{!g4u>(a#g`Mme7+yefc~5wPOflDr`o81qe{?|t$BfABsDzNw;V z8cH*0{6W<;G9Np#7ik(qoR4aR5-A@{5)}DJ9&}FRBA#X_5+im4-kQSzMF^)-t2(Vi ztw-^|Sn8@O_lM9`oos+0wMZGt&`Bq(aK&XCv1Gfr&Jtd6%lKPdD{s=unqGWyb3%y{X9SS{jB~HMh0oKMISQrDC zJ;K?)>ElnpmN^UNE-rXxtyk{c#rCe~`P=qnFT7 bCxwx*w%~s~=?o*z_6Fk4@7l(poWF`cPpA(! literal 0 HcmV?d00001 diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/etc/lua.pc b/mod/pub.mod/lua.mod/lua-5.1.4/etc/lua.pc new file mode 100644 index 0000000..f52f55b --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/etc/lua.pc @@ -0,0 +1,31 @@ +# lua.pc -- pkg-config data for Lua + +# vars from install Makefile + +# grep '^V=' ../Makefile +V= 5.1 +# grep '^R=' ../Makefile +R= 5.1.4 + +# grep '^INSTALL_.*=' ../Makefile | sed 's/INSTALL_TOP/prefix/' +prefix= /usr/local +INSTALL_BIN= ${prefix}/bin +INSTALL_INC= ${prefix}/include +INSTALL_LIB= ${prefix}/lib +INSTALL_MAN= ${prefix}/man/man1 +INSTALL_LMOD= ${prefix}/share/lua/${V} +INSTALL_CMOD= ${prefix}/lib/lua/${V} + +# canonical vars +exec_prefix=${prefix} +libdir=${exec_prefix}/lib +includedir=${prefix}/include + +Name: Lua +Description: An Extensible Extension Language +Version: ${R} +Requires: +Libs: -L${libdir} -llua -lm +Cflags: -I${includedir} + +# (end of lua.pc) diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/etc/luavs.bat b/mod/pub.mod/lua.mod/lua-5.1.4/etc/luavs.bat new file mode 100644 index 0000000..054b462 --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/etc/luavs.bat @@ -0,0 +1,28 @@ +@rem Script to build Lua under "Visual Studio .NET Command Prompt". +@rem Do not run from this directory; run it from the toplevel: etc\luavs.bat . +@rem It creates lua51.dll, lua51.lib, lua.exe, and luac.exe in src. +@rem (contributed by David Manura and Mike Pall) + +@setlocal +@set MYCOMPILE=cl /nologo /MD /O2 /W3 /c /D_CRT_SECURE_NO_DEPRECATE +@set MYLINK=link /nologo +@set MYMT=mt /nologo + +cd src +%MYCOMPILE% /DLUA_BUILD_AS_DLL l*.c +del lua.obj luac.obj +%MYLINK% /DLL /out:lua51.dll l*.obj +if exist lua51.dll.manifest^ + %MYMT% -manifest lua51.dll.manifest -outputresource:lua51.dll;2 +%MYCOMPILE% /DLUA_BUILD_AS_DLL lua.c +%MYLINK% /out:lua.exe lua.obj lua51.lib +if exist lua.exe.manifest^ + %MYMT% -manifest lua.exe.manifest -outputresource:lua.exe +%MYCOMPILE% l*.c print.c +del lua.obj linit.obj lbaselib.obj ldblib.obj liolib.obj lmathlib.obj^ + loslib.obj ltablib.obj lstrlib.obj loadlib.obj +%MYLINK% /out:luac.exe *.obj +if exist luac.exe.manifest^ + %MYMT% -manifest luac.exe.manifest -outputresource:luac.exe +del *.obj *.manifest +cd .. diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/etc/min.c b/mod/pub.mod/lua.mod/lua-5.1.4/etc/min.c new file mode 100644 index 0000000..6a85a4d --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/etc/min.c @@ -0,0 +1,39 @@ +/* +* min.c -- a minimal Lua interpreter +* loads stdin only with minimal error handling. +* no interaction, and no standard library, only a "print" function. +*/ + +#include + +#include "lua.h" +#include "lauxlib.h" + +static int print(lua_State *L) +{ + int n=lua_gettop(L); + int i; + for (i=1; i<=n; i++) + { + if (i>1) printf("\t"); + if (lua_isstring(L,i)) + printf("%s",lua_tostring(L,i)); + else if (lua_isnil(L,i)) + printf("%s","nil"); + else if (lua_isboolean(L,i)) + printf("%s",lua_toboolean(L,i) ? "true" : "false"); + else + printf("%s:%p",luaL_typename(L,i),lua_topointer(L,i)); + } + printf("\n"); + return 0; +} + +int main(void) +{ + lua_State *L=lua_open(); + lua_register(L,"print",print); + if (luaL_dofile(L,NULL)!=0) fprintf(stderr,"%s\n",lua_tostring(L,-1)); + lua_close(L); + return 0; +} diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/etc/noparser.c b/mod/pub.mod/lua.mod/lua-5.1.4/etc/noparser.c new file mode 100644 index 0000000..13ba546 --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/etc/noparser.c @@ -0,0 +1,50 @@ +/* +* The code below can be used to make a Lua core that does not contain the +* parsing modules (lcode, llex, lparser), which represent 35% of the total core. +* You'll only be able to load binary files and strings, precompiled with luac. +* (Of course, you'll have to build luac with the original parsing modules!) +* +* To use this module, simply compile it ("make noparser" does that) and list +* its object file before the Lua libraries. The linker should then not load +* the parsing modules. To try it, do "make luab". +* +* If you also want to avoid the dump module (ldump.o), define NODUMP. +* #define NODUMP +*/ + +#define LUA_CORE + +#include "llex.h" +#include "lparser.h" +#include "lzio.h" + +LUAI_FUNC void luaX_init (lua_State *L) { + UNUSED(L); +} + +LUAI_FUNC Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) { + UNUSED(z); + UNUSED(buff); + UNUSED(name); + lua_pushliteral(L,"parser not loaded"); + lua_error(L); + return NULL; +} + +#ifdef NODUMP +#include "lundump.h" + +LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip) { + UNUSED(f); + UNUSED(w); + UNUSED(data); + UNUSED(strip); +#if 1 + UNUSED(L); + return 0; +#else + lua_pushliteral(L,"dumper not loaded"); + lua_error(L); +#endif +} +#endif diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/etc/strict.lua b/mod/pub.mod/lua.mod/lua-5.1.4/etc/strict.lua new file mode 100644 index 0000000..604619d --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/etc/strict.lua @@ -0,0 +1,41 @@ +-- +-- strict.lua +-- checks uses of undeclared global variables +-- All global variables must be 'declared' through a regular assignment +-- (even assigning nil will do) in a main chunk before being used +-- anywhere or assigned to inside a function. +-- + +local getinfo, error, rawset, rawget = debug.getinfo, error, rawset, rawget + +local mt = getmetatable(_G) +if mt == nil then + mt = {} + setmetatable(_G, mt) +end + +mt.__declared = {} + +local function what () + local d = getinfo(3, "S") + return d and d.what or "C" +end + +mt.__newindex = function (t, n, v) + if not mt.__declared[n] then + local w = what() + if w ~= "main" and w ~= "C" then + error("assign to undeclared variable '"..n.."'", 2) + end + mt.__declared[n] = true + end + rawset(t, n, v) +end + +mt.__index = function (t, n) + if not mt.__declared[n] and what() ~= "C" then + error("variable '"..n.."' is not declared", 2) + end + return rawget(t, n) +end + diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/src/Makefile b/mod/pub.mod/lua.mod/lua-5.1.4/src/Makefile new file mode 100644 index 0000000..e4a3cd6 --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/src/Makefile @@ -0,0 +1,182 @@ +# makefile for building Lua +# see ../INSTALL for installation instructions +# see ../Makefile and luaconf.h for further customization + +# == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT ======================= + +# Your platform. See PLATS for possible values. +PLAT= none + +CC= gcc +CFLAGS= -O2 -Wall $(MYCFLAGS) +AR= ar rcu +RANLIB= ranlib +RM= rm -f +LIBS= -lm $(MYLIBS) + +MYCFLAGS= +MYLDFLAGS= +MYLIBS= + +# == END OF USER SETTINGS. NO NEED TO CHANGE ANYTHING BELOW THIS LINE ========= + +PLATS= aix ansi bsd freebsd generic linux macosx mingw posix solaris + +LUA_A= liblua.a +CORE_O= lapi.o lcode.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o lmem.o \ + lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o ltm.o \ + lundump.o lvm.o lzio.o +LIB_O= lauxlib.o lbaselib.o ldblib.o liolib.o lmathlib.o loslib.o ltablib.o \ + lstrlib.o loadlib.o linit.o + +LUA_T= lua +LUA_O= lua.o + +LUAC_T= luac +LUAC_O= luac.o print.o + +ALL_O= $(CORE_O) $(LIB_O) $(LUA_O) $(LUAC_O) +ALL_T= $(LUA_A) $(LUA_T) $(LUAC_T) +ALL_A= $(LUA_A) + +default: $(PLAT) + +all: $(ALL_T) + +o: $(ALL_O) + +a: $(ALL_A) + +$(LUA_A): $(CORE_O) $(LIB_O) + $(AR) $@ $? + $(RANLIB) $@ + +$(LUA_T): $(LUA_O) $(LUA_A) + $(CC) -o $@ $(MYLDFLAGS) $(LUA_O) $(LUA_A) $(LIBS) + +$(LUAC_T): $(LUAC_O) $(LUA_A) + $(CC) -o $@ $(MYLDFLAGS) $(LUAC_O) $(LUA_A) $(LIBS) + +clean: + $(RM) $(ALL_T) $(ALL_O) + +depend: + @$(CC) $(CFLAGS) -MM l*.c print.c + +echo: + @echo "PLAT = $(PLAT)" + @echo "CC = $(CC)" + @echo "CFLAGS = $(CFLAGS)" + @echo "AR = $(AR)" + @echo "RANLIB = $(RANLIB)" + @echo "RM = $(RM)" + @echo "MYCFLAGS = $(MYCFLAGS)" + @echo "MYLDFLAGS = $(MYLDFLAGS)" + @echo "MYLIBS = $(MYLIBS)" + +# convenience targets for popular platforms + +none: + @echo "Please choose a platform:" + @echo " $(PLATS)" + +aix: + $(MAKE) all CC="xlc" CFLAGS="-O2 -DLUA_USE_POSIX -DLUA_USE_DLOPEN" MYLIBS="-ldl" MYLDFLAGS="-brtl -bexpall" + +ansi: + $(MAKE) all MYCFLAGS=-DLUA_ANSI + +bsd: + $(MAKE) all MYCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" MYLIBS="-Wl,-E" + +freebsd: + $(MAKE) all MYCFLAGS="-DLUA_USE_LINUX" MYLIBS="-Wl,-E -lreadline" + +generic: + $(MAKE) all MYCFLAGS= + +linux: + $(MAKE) all MYCFLAGS=-DLUA_USE_LINUX MYLIBS="-Wl,-E -ldl -lreadline -lhistory -lncurses" + +macosx: + $(MAKE) all MYCFLAGS=-DLUA_USE_LINUX MYLIBS="-lreadline" +# use this on Mac OS X 10.3- +# $(MAKE) all MYCFLAGS=-DLUA_USE_MACOSX + +mingw: + $(MAKE) "LUA_A=lua51.dll" "LUA_T=lua.exe" \ + "AR=$(CC) -shared -o" "RANLIB=strip --strip-unneeded" \ + "MYCFLAGS=-DLUA_BUILD_AS_DLL" "MYLIBS=" "MYLDFLAGS=-s" lua.exe + $(MAKE) "LUAC_T=luac.exe" luac.exe + +posix: + $(MAKE) all MYCFLAGS=-DLUA_USE_POSIX + +solaris: + $(MAKE) all MYCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" MYLIBS="-ldl" + +# list targets that do not create files (but not all makes understand .PHONY) +.PHONY: all $(PLATS) default o a clean depend echo none + +# DO NOT DELETE + +lapi.o: lapi.c lua.h luaconf.h lapi.h lobject.h llimits.h ldebug.h \ + lstate.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h \ + lundump.h lvm.h +lauxlib.o: lauxlib.c lua.h luaconf.h lauxlib.h +lbaselib.o: lbaselib.c lua.h luaconf.h lauxlib.h lualib.h +lcode.o: lcode.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h \ + lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h lgc.h \ + ltable.h +ldblib.o: ldblib.c lua.h luaconf.h lauxlib.h lualib.h +ldebug.o: ldebug.c lua.h luaconf.h lapi.h lobject.h llimits.h lcode.h \ + llex.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h \ + lfunc.h lstring.h lgc.h ltable.h lvm.h +ldo.o: ldo.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \ + lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lparser.h lstring.h \ + ltable.h lundump.h lvm.h +ldump.o: ldump.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h \ + lzio.h lmem.h lundump.h +lfunc.o: lfunc.c lua.h luaconf.h lfunc.h lobject.h llimits.h lgc.h lmem.h \ + lstate.h ltm.h lzio.h +lgc.o: lgc.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \ + lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h +linit.o: linit.c lua.h luaconf.h lualib.h lauxlib.h +liolib.o: liolib.c lua.h luaconf.h lauxlib.h lualib.h +llex.o: llex.c lua.h luaconf.h ldo.h lobject.h llimits.h lstate.h ltm.h \ + lzio.h lmem.h llex.h lparser.h lstring.h lgc.h ltable.h +lmathlib.o: lmathlib.c lua.h luaconf.h lauxlib.h lualib.h +lmem.o: lmem.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \ + ltm.h lzio.h lmem.h ldo.h +loadlib.o: loadlib.c lua.h luaconf.h lauxlib.h lualib.h +lobject.o: lobject.c lua.h luaconf.h ldo.h lobject.h llimits.h lstate.h \ + ltm.h lzio.h lmem.h lstring.h lgc.h lvm.h +lopcodes.o: lopcodes.c lopcodes.h llimits.h lua.h luaconf.h +loslib.o: loslib.c lua.h luaconf.h lauxlib.h lualib.h +lparser.o: lparser.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h \ + lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h \ + lfunc.h lstring.h lgc.h ltable.h +lstate.o: lstate.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \ + ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h llex.h lstring.h ltable.h +lstring.o: lstring.c lua.h luaconf.h lmem.h llimits.h lobject.h lstate.h \ + ltm.h lzio.h lstring.h lgc.h +lstrlib.o: lstrlib.c lua.h luaconf.h lauxlib.h lualib.h +ltable.o: ltable.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \ + ltm.h lzio.h lmem.h ldo.h lgc.h ltable.h +ltablib.o: ltablib.c lua.h luaconf.h lauxlib.h lualib.h +ltm.o: ltm.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h lzio.h \ + lmem.h lstring.h lgc.h ltable.h +lua.o: lua.c lua.h luaconf.h lauxlib.h lualib.h +luac.o: luac.c lua.h luaconf.h lauxlib.h ldo.h lobject.h llimits.h \ + lstate.h ltm.h lzio.h lmem.h lfunc.h lopcodes.h lstring.h lgc.h \ + lundump.h +lundump.o: lundump.c lua.h luaconf.h ldebug.h lstate.h lobject.h \ + llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lstring.h lgc.h lundump.h +lvm.o: lvm.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \ + lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h ltable.h lvm.h +lzio.o: lzio.c lua.h luaconf.h llimits.h lmem.h lstate.h lobject.h ltm.h \ + lzio.h +print.o: print.c ldebug.h lstate.h lua.h luaconf.h lobject.h llimits.h \ + ltm.h lzio.h lmem.h lopcodes.h lundump.h + +# (end of Makefile) diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/src/lapi.c b/mod/pub.mod/lua.mod/lua-5.1.4/src/lapi.c new file mode 100644 index 0000000..5d5145d --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/src/lapi.c @@ -0,0 +1,1087 @@ +/* +** $Id: lapi.c,v 2.55.1.5 2008/07/04 18:41:18 roberto Exp $ +** Lua API +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include +#include + +#define lapi_c +#define LUA_CORE + +#include "lua.h" + +#include "lapi.h" +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" +#include "lundump.h" +#include "lvm.h" + + + +const char lua_ident[] = + "$Lua: " LUA_RELEASE " " LUA_COPYRIGHT " $\n" + "$Authors: " LUA_AUTHORS " $\n" + "$URL: www.lua.org $\n"; + + + +#define api_checknelems(L, n) api_check(L, (n) <= (L->top - L->base)) + +#define api_checkvalidindex(L, i) api_check(L, (i) != luaO_nilobject) + +#define api_incr_top(L) {api_check(L, L->top < L->ci->top); L->top++;} + + + +static TValue *index2adr (lua_State *L, int idx) { + if (idx > 0) { + TValue *o = L->base + (idx - 1); + api_check(L, idx <= L->ci->top - L->base); + if (o >= L->top) return cast(TValue *, luaO_nilobject); + else return o; + } + else if (idx > LUA_REGISTRYINDEX) { + api_check(L, idx != 0 && -idx <= L->top - L->base); + return L->top + idx; + } + else switch (idx) { /* pseudo-indices */ + case LUA_REGISTRYINDEX: return registry(L); + case LUA_ENVIRONINDEX: { + Closure *func = curr_func(L); + sethvalue(L, &L->env, func->c.env); + return &L->env; + } + case LUA_GLOBALSINDEX: return gt(L); + default: { + Closure *func = curr_func(L); + idx = LUA_GLOBALSINDEX - idx; + return (idx <= func->c.nupvalues) + ? &func->c.upvalue[idx-1] + : cast(TValue *, luaO_nilobject); + } + } +} + + +static Table *getcurrenv (lua_State *L) { + if (L->ci == L->base_ci) /* no enclosing function? */ + return hvalue(gt(L)); /* use global table as environment */ + else { + Closure *func = curr_func(L); + return func->c.env; + } +} + + +void luaA_pushobject (lua_State *L, const TValue *o) { + setobj2s(L, L->top, o); + api_incr_top(L); +} + + +LUA_API int lua_checkstack (lua_State *L, int size) { + int res = 1; + lua_lock(L); + if (size > LUAI_MAXCSTACK || (L->top - L->base + size) > LUAI_MAXCSTACK) + res = 0; /* stack overflow */ + else if (size > 0) { + luaD_checkstack(L, size); + if (L->ci->top < L->top + size) + L->ci->top = L->top + size; + } + lua_unlock(L); + return res; +} + + +LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) { + int i; + if (from == to) return; + lua_lock(to); + api_checknelems(from, n); + api_check(from, G(from) == G(to)); + api_check(from, to->ci->top - to->top >= n); + from->top -= n; + for (i = 0; i < n; i++) { + setobj2s(to, to->top++, from->top + i); + } + lua_unlock(to); +} + + +LUA_API void lua_setlevel (lua_State *from, lua_State *to) { + to->nCcalls = from->nCcalls; +} + + +LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) { + lua_CFunction old; + lua_lock(L); + old = G(L)->panic; + G(L)->panic = panicf; + lua_unlock(L); + return old; +} + + +LUA_API lua_State *lua_newthread (lua_State *L) { + lua_State *L1; + lua_lock(L); + luaC_checkGC(L); + L1 = luaE_newthread(L); + setthvalue(L, L->top, L1); + api_incr_top(L); + lua_unlock(L); + luai_userstatethread(L, L1); + return L1; +} + + + +/* +** basic stack manipulation +*/ + + +LUA_API int lua_gettop (lua_State *L) { + return cast_int(L->top - L->base); +} + + +LUA_API void lua_settop (lua_State *L, int idx) { + lua_lock(L); + if (idx >= 0) { + api_check(L, idx <= L->stack_last - L->base); + while (L->top < L->base + idx) + setnilvalue(L->top++); + L->top = L->base + idx; + } + else { + api_check(L, -(idx+1) <= (L->top - L->base)); + L->top += idx+1; /* `subtract' index (index is negative) */ + } + lua_unlock(L); +} + + +LUA_API void lua_remove (lua_State *L, int idx) { + StkId p; + lua_lock(L); + p = index2adr(L, idx); + api_checkvalidindex(L, p); + while (++p < L->top) setobjs2s(L, p-1, p); + L->top--; + lua_unlock(L); +} + + +LUA_API void lua_insert (lua_State *L, int idx) { + StkId p; + StkId q; + lua_lock(L); + p = index2adr(L, idx); + api_checkvalidindex(L, p); + for (q = L->top; q>p; q--) setobjs2s(L, q, q-1); + setobjs2s(L, p, L->top); + lua_unlock(L); +} + + +LUA_API void lua_replace (lua_State *L, int idx) { + StkId o; + lua_lock(L); + /* explicit test for incompatible code */ + if (idx == LUA_ENVIRONINDEX && L->ci == L->base_ci) + luaG_runerror(L, "no calling environment"); + api_checknelems(L, 1); + o = index2adr(L, idx); + api_checkvalidindex(L, o); + if (idx == LUA_ENVIRONINDEX) { + Closure *func = curr_func(L); + api_check(L, ttistable(L->top - 1)); + func->c.env = hvalue(L->top - 1); + luaC_barrier(L, func, L->top - 1); + } + else { + setobj(L, o, L->top - 1); + if (idx < LUA_GLOBALSINDEX) /* function upvalue? */ + luaC_barrier(L, curr_func(L), L->top - 1); + } + L->top--; + lua_unlock(L); +} + + +LUA_API void lua_pushvalue (lua_State *L, int idx) { + lua_lock(L); + setobj2s(L, L->top, index2adr(L, idx)); + api_incr_top(L); + lua_unlock(L); +} + + + +/* +** access functions (stack -> C) +*/ + + +LUA_API int lua_type (lua_State *L, int idx) { + StkId o = index2adr(L, idx); + return (o == luaO_nilobject) ? LUA_TNONE : ttype(o); +} + + +LUA_API const char *lua_typename (lua_State *L, int t) { + UNUSED(L); + return (t == LUA_TNONE) ? "no value" : luaT_typenames[t]; +} + + +LUA_API int lua_iscfunction (lua_State *L, int idx) { + StkId o = index2adr(L, idx); + return iscfunction(o); +} + + +LUA_API int lua_isnumber (lua_State *L, int idx) { + TValue n; + const TValue *o = index2adr(L, idx); + return tonumber(o, &n); +} + + +LUA_API int lua_isstring (lua_State *L, int idx) { + int t = lua_type(L, idx); + return (t == LUA_TSTRING || t == LUA_TNUMBER); +} + + +LUA_API int lua_isuserdata (lua_State *L, int idx) { + const TValue *o = index2adr(L, idx); + return (ttisuserdata(o) || ttislightuserdata(o)); +} + + +LUA_API int lua_rawequal (lua_State *L, int index1, int index2) { + StkId o1 = index2adr(L, index1); + StkId o2 = index2adr(L, index2); + return (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 + : luaO_rawequalObj(o1, o2); +} + + +LUA_API int lua_equal (lua_State *L, int index1, int index2) { + StkId o1, o2; + int i; + lua_lock(L); /* may call tag method */ + o1 = index2adr(L, index1); + o2 = index2adr(L, index2); + i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 : equalobj(L, o1, o2); + lua_unlock(L); + return i; +} + + +LUA_API int lua_lessthan (lua_State *L, int index1, int index2) { + StkId o1, o2; + int i; + lua_lock(L); /* may call tag method */ + o1 = index2adr(L, index1); + o2 = index2adr(L, index2); + i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 + : luaV_lessthan(L, o1, o2); + lua_unlock(L); + return i; +} + + + +LUA_API lua_Number lua_tonumber (lua_State *L, int idx) { + TValue n; + const TValue *o = index2adr(L, idx); + if (tonumber(o, &n)) + return nvalue(o); + else + return 0; +} + + +LUA_API lua_Integer lua_tointeger (lua_State *L, int idx) { + TValue n; + const TValue *o = index2adr(L, idx); + if (tonumber(o, &n)) { + lua_Integer res; + lua_Number num = nvalue(o); + lua_number2integer(res, num); + return res; + } + else + return 0; +} + + +LUA_API int lua_toboolean (lua_State *L, int idx) { + const TValue *o = index2adr(L, idx); + return !l_isfalse(o); +} + + +LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) { + StkId o = index2adr(L, idx); + if (!ttisstring(o)) { + lua_lock(L); /* `luaV_tostring' may create a new string */ + if (!luaV_tostring(L, o)) { /* conversion failed? */ + if (len != NULL) *len = 0; + lua_unlock(L); + return NULL; + } + luaC_checkGC(L); + o = index2adr(L, idx); /* previous call may reallocate the stack */ + lua_unlock(L); + } + if (len != NULL) *len = tsvalue(o)->len; + return svalue(o); +} + + +LUA_API size_t lua_objlen (lua_State *L, int idx) { + StkId o = index2adr(L, idx); + switch (ttype(o)) { + case LUA_TSTRING: return tsvalue(o)->len; + case LUA_TUSERDATA: return uvalue(o)->len; + case LUA_TTABLE: return luaH_getn(hvalue(o)); + case LUA_TNUMBER: { + size_t l; + lua_lock(L); /* `luaV_tostring' may create a new string */ + l = (luaV_tostring(L, o) ? tsvalue(o)->len : 0); + lua_unlock(L); + return l; + } + default: return 0; + } +} + + +LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) { + StkId o = index2adr(L, idx); + return (!iscfunction(o)) ? NULL : clvalue(o)->c.f; +} + + +LUA_API void *lua_touserdata (lua_State *L, int idx) { + StkId o = index2adr(L, idx); + switch (ttype(o)) { + case LUA_TUSERDATA: return (rawuvalue(o) + 1); + case LUA_TLIGHTUSERDATA: return pvalue(o); + default: return NULL; + } +} + + +LUA_API lua_State *lua_tothread (lua_State *L, int idx) { + StkId o = index2adr(L, idx); + return (!ttisthread(o)) ? NULL : thvalue(o); +} + + +LUA_API const void *lua_topointer (lua_State *L, int idx) { + StkId o = index2adr(L, idx); + switch (ttype(o)) { + case LUA_TTABLE: return hvalue(o); + case LUA_TFUNCTION: return clvalue(o); + case LUA_TTHREAD: return thvalue(o); + case LUA_TUSERDATA: + case LUA_TLIGHTUSERDATA: + return lua_touserdata(L, idx); + default: return NULL; + } +} + + + +/* +** push functions (C -> stack) +*/ + + +LUA_API void lua_pushnil (lua_State *L) { + lua_lock(L); + setnilvalue(L->top); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_pushnumber (lua_State *L, lua_Number n) { + lua_lock(L); + setnvalue(L->top, n); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) { + lua_lock(L); + setnvalue(L->top, cast_num(n)); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len) { + lua_lock(L); + luaC_checkGC(L); + setsvalue2s(L, L->top, luaS_newlstr(L, s, len)); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_pushstring (lua_State *L, const char *s) { + if (s == NULL) + lua_pushnil(L); + else + lua_pushlstring(L, s, strlen(s)); +} + + +LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt, + va_list argp) { + const char *ret; + lua_lock(L); + luaC_checkGC(L); + ret = luaO_pushvfstring(L, fmt, argp); + lua_unlock(L); + return ret; +} + + +LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) { + const char *ret; + va_list argp; + lua_lock(L); + luaC_checkGC(L); + va_start(argp, fmt); + ret = luaO_pushvfstring(L, fmt, argp); + va_end(argp); + lua_unlock(L); + return ret; +} + + +LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { + Closure *cl; + lua_lock(L); + luaC_checkGC(L); + api_checknelems(L, n); + cl = luaF_newCclosure(L, n, getcurrenv(L)); + cl->c.f = fn; + L->top -= n; + while (n--) + setobj2n(L, &cl->c.upvalue[n], L->top+n); + setclvalue(L, L->top, cl); + lua_assert(iswhite(obj2gco(cl))); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_pushboolean (lua_State *L, int b) { + lua_lock(L); + setbvalue(L->top, (b != 0)); /* ensure that true is 1 */ + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_pushlightuserdata (lua_State *L, void *p) { + lua_lock(L); + setpvalue(L->top, p); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API int lua_pushthread (lua_State *L) { + lua_lock(L); + setthvalue(L, L->top, L); + api_incr_top(L); + lua_unlock(L); + return (G(L)->mainthread == L); +} + + + +/* +** get functions (Lua -> stack) +*/ + + +LUA_API void lua_gettable (lua_State *L, int idx) { + StkId t; + lua_lock(L); + t = index2adr(L, idx); + api_checkvalidindex(L, t); + luaV_gettable(L, t, L->top - 1, L->top - 1); + lua_unlock(L); +} + + +LUA_API void lua_getfield (lua_State *L, int idx, const char *k) { + StkId t; + TValue key; + lua_lock(L); + t = index2adr(L, idx); + api_checkvalidindex(L, t); + setsvalue(L, &key, luaS_new(L, k)); + luaV_gettable(L, t, &key, L->top); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_rawget (lua_State *L, int idx) { + StkId t; + lua_lock(L); + t = index2adr(L, idx); + api_check(L, ttistable(t)); + setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1)); + lua_unlock(L); +} + + +LUA_API void lua_rawgeti (lua_State *L, int idx, int n) { + StkId o; + lua_lock(L); + o = index2adr(L, idx); + api_check(L, ttistable(o)); + setobj2s(L, L->top, luaH_getnum(hvalue(o), n)); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_createtable (lua_State *L, int narray, int nrec) { + lua_lock(L); + luaC_checkGC(L); + sethvalue(L, L->top, luaH_new(L, narray, nrec)); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API int lua_getmetatable (lua_State *L, int objindex) { + const TValue *obj; + Table *mt = NULL; + int res; + lua_lock(L); + obj = index2adr(L, objindex); + switch (ttype(obj)) { + case LUA_TTABLE: + mt = hvalue(obj)->metatable; + break; + case LUA_TUSERDATA: + mt = uvalue(obj)->metatable; + break; + default: + mt = G(L)->mt[ttype(obj)]; + break; + } + if (mt == NULL) + res = 0; + else { + sethvalue(L, L->top, mt); + api_incr_top(L); + res = 1; + } + lua_unlock(L); + return res; +} + + +LUA_API void lua_getfenv (lua_State *L, int idx) { + StkId o; + lua_lock(L); + o = index2adr(L, idx); + api_checkvalidindex(L, o); + switch (ttype(o)) { + case LUA_TFUNCTION: + sethvalue(L, L->top, clvalue(o)->c.env); + break; + case LUA_TUSERDATA: + sethvalue(L, L->top, uvalue(o)->env); + break; + case LUA_TTHREAD: + setobj2s(L, L->top, gt(thvalue(o))); + break; + default: + setnilvalue(L->top); + break; + } + api_incr_top(L); + lua_unlock(L); +} + + +/* +** set functions (stack -> Lua) +*/ + + +LUA_API void lua_settable (lua_State *L, int idx) { + StkId t; + lua_lock(L); + api_checknelems(L, 2); + t = index2adr(L, idx); + api_checkvalidindex(L, t); + luaV_settable(L, t, L->top - 2, L->top - 1); + L->top -= 2; /* pop index and value */ + lua_unlock(L); +} + + +LUA_API void lua_setfield (lua_State *L, int idx, const char *k) { + StkId t; + TValue key; + lua_lock(L); + api_checknelems(L, 1); + t = index2adr(L, idx); + api_checkvalidindex(L, t); + setsvalue(L, &key, luaS_new(L, k)); + luaV_settable(L, t, &key, L->top - 1); + L->top--; /* pop value */ + lua_unlock(L); +} + + +LUA_API void lua_rawset (lua_State *L, int idx) { + StkId t; + lua_lock(L); + api_checknelems(L, 2); + t = index2adr(L, idx); + api_check(L, ttistable(t)); + setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1); + luaC_barriert(L, hvalue(t), L->top-1); + L->top -= 2; + lua_unlock(L); +} + + +LUA_API void lua_rawseti (lua_State *L, int idx, int n) { + StkId o; + lua_lock(L); + api_checknelems(L, 1); + o = index2adr(L, idx); + api_check(L, ttistable(o)); + setobj2t(L, luaH_setnum(L, hvalue(o), n), L->top-1); + luaC_barriert(L, hvalue(o), L->top-1); + L->top--; + lua_unlock(L); +} + + +LUA_API int lua_setmetatable (lua_State *L, int objindex) { + TValue *obj; + Table *mt; + lua_lock(L); + api_checknelems(L, 1); + obj = index2adr(L, objindex); + api_checkvalidindex(L, obj); + if (ttisnil(L->top - 1)) + mt = NULL; + else { + api_check(L, ttistable(L->top - 1)); + mt = hvalue(L->top - 1); + } + switch (ttype(obj)) { + case LUA_TTABLE: { + hvalue(obj)->metatable = mt; + if (mt) + luaC_objbarriert(L, hvalue(obj), mt); + break; + } + case LUA_TUSERDATA: { + uvalue(obj)->metatable = mt; + if (mt) + luaC_objbarrier(L, rawuvalue(obj), mt); + break; + } + default: { + G(L)->mt[ttype(obj)] = mt; + break; + } + } + L->top--; + lua_unlock(L); + return 1; +} + + +LUA_API int lua_setfenv (lua_State *L, int idx) { + StkId o; + int res = 1; + lua_lock(L); + api_checknelems(L, 1); + o = index2adr(L, idx); + api_checkvalidindex(L, o); + api_check(L, ttistable(L->top - 1)); + switch (ttype(o)) { + case LUA_TFUNCTION: + clvalue(o)->c.env = hvalue(L->top - 1); + break; + case LUA_TUSERDATA: + uvalue(o)->env = hvalue(L->top - 1); + break; + case LUA_TTHREAD: + sethvalue(L, gt(thvalue(o)), hvalue(L->top - 1)); + break; + default: + res = 0; + break; + } + if (res) luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1)); + L->top--; + lua_unlock(L); + return res; +} + + +/* +** `load' and `call' functions (run Lua code) +*/ + + +#define adjustresults(L,nres) \ + { if (nres == LUA_MULTRET && L->top >= L->ci->top) L->ci->top = L->top; } + + +#define checkresults(L,na,nr) \ + api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na))) + + +LUA_API void lua_call (lua_State *L, int nargs, int nresults) { + StkId func; + lua_lock(L); + api_checknelems(L, nargs+1); + checkresults(L, nargs, nresults); + func = L->top - (nargs+1); + luaD_call(L, func, nresults); + adjustresults(L, nresults); + lua_unlock(L); +} + + + +/* +** Execute a protected call. +*/ +struct CallS { /* data to `f_call' */ + StkId func; + int nresults; +}; + + +static void f_call (lua_State *L, void *ud) { + struct CallS *c = cast(struct CallS *, ud); + luaD_call(L, c->func, c->nresults); +} + + + +LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc) { + struct CallS c; + int status; + ptrdiff_t func; + lua_lock(L); + api_checknelems(L, nargs+1); + checkresults(L, nargs, nresults); + if (errfunc == 0) + func = 0; + else { + StkId o = index2adr(L, errfunc); + api_checkvalidindex(L, o); + func = savestack(L, o); + } + c.func = L->top - (nargs+1); /* function to be called */ + c.nresults = nresults; + status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func); + adjustresults(L, nresults); + lua_unlock(L); + return status; +} + + +/* +** Execute a protected C call. +*/ +struct CCallS { /* data to `f_Ccall' */ + lua_CFunction func; + void *ud; +}; + + +static void f_Ccall (lua_State *L, void *ud) { + struct CCallS *c = cast(struct CCallS *, ud); + Closure *cl; + cl = luaF_newCclosure(L, 0, getcurrenv(L)); + cl->c.f = c->func; + setclvalue(L, L->top, cl); /* push function */ + api_incr_top(L); + setpvalue(L->top, c->ud); /* push only argument */ + api_incr_top(L); + luaD_call(L, L->top - 2, 0); +} + + +LUA_API int lua_cpcall (lua_State *L, lua_CFunction func, void *ud) { + struct CCallS c; + int status; + lua_lock(L); + c.func = func; + c.ud = ud; + status = luaD_pcall(L, f_Ccall, &c, savestack(L, L->top), 0); + lua_unlock(L); + return status; +} + + +LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data, + const char *chunkname) { + ZIO z; + int status; + lua_lock(L); + if (!chunkname) chunkname = "?"; + luaZ_init(L, &z, reader, data); + status = luaD_protectedparser(L, &z, chunkname); + lua_unlock(L); + return status; +} + + +LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data) { + int status; + TValue *o; + lua_lock(L); + api_checknelems(L, 1); + o = L->top - 1; + if (isLfunction(o)) + status = luaU_dump(L, clvalue(o)->l.p, writer, data, 0); + else + status = 1; + lua_unlock(L); + return status; +} + + +LUA_API int lua_status (lua_State *L) { + return L->status; +} + + +/* +** Garbage-collection function +*/ + +LUA_API int lua_gc (lua_State *L, int what, int data) { + int res = 0; + global_State *g; + lua_lock(L); + g = G(L); + switch (what) { + case LUA_GCSTOP: { + g->GCthreshold = MAX_LUMEM; + break; + } + case LUA_GCRESTART: { + g->GCthreshold = g->totalbytes; + break; + } + case LUA_GCCOLLECT: { + luaC_fullgc(L); + break; + } + case LUA_GCCOUNT: { + /* GC values are expressed in Kbytes: #bytes/2^10 */ + res = cast_int(g->totalbytes >> 10); + break; + } + case LUA_GCCOUNTB: { + res = cast_int(g->totalbytes & 0x3ff); + break; + } + case LUA_GCSTEP: { + lu_mem a = (cast(lu_mem, data) << 10); + if (a <= g->totalbytes) + g->GCthreshold = g->totalbytes - a; + else + g->GCthreshold = 0; + while (g->GCthreshold <= g->totalbytes) { + luaC_step(L); + if (g->gcstate == GCSpause) { /* end of cycle? */ + res = 1; /* signal it */ + break; + } + } + break; + } + case LUA_GCSETPAUSE: { + res = g->gcpause; + g->gcpause = data; + break; + } + case LUA_GCSETSTEPMUL: { + res = g->gcstepmul; + g->gcstepmul = data; + break; + } + default: res = -1; /* invalid option */ + } + lua_unlock(L); + return res; +} + + + +/* +** miscellaneous functions +*/ + + +LUA_API int lua_error (lua_State *L) { + lua_lock(L); + api_checknelems(L, 1); + luaG_errormsg(L); + lua_unlock(L); + return 0; /* to avoid warnings */ +} + + +LUA_API int lua_next (lua_State *L, int idx) { + StkId t; + int more; + lua_lock(L); + t = index2adr(L, idx); + api_check(L, ttistable(t)); + more = luaH_next(L, hvalue(t), L->top - 1); + if (more) { + api_incr_top(L); + } + else /* no more elements */ + L->top -= 1; /* remove key */ + lua_unlock(L); + return more; +} + + +LUA_API void lua_concat (lua_State *L, int n) { + lua_lock(L); + api_checknelems(L, n); + if (n >= 2) { + luaC_checkGC(L); + luaV_concat(L, n, cast_int(L->top - L->base) - 1); + L->top -= (n-1); + } + else if (n == 0) { /* push empty string */ + setsvalue2s(L, L->top, luaS_newlstr(L, "", 0)); + api_incr_top(L); + } + /* else n == 1; nothing to do */ + lua_unlock(L); +} + + +LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) { + lua_Alloc f; + lua_lock(L); + if (ud) *ud = G(L)->ud; + f = G(L)->frealloc; + lua_unlock(L); + return f; +} + + +LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) { + lua_lock(L); + G(L)->ud = ud; + G(L)->frealloc = f; + lua_unlock(L); +} + + +LUA_API void *lua_newuserdata (lua_State *L, size_t size) { + Udata *u; + lua_lock(L); + luaC_checkGC(L); + u = luaS_newudata(L, size, getcurrenv(L)); + setuvalue(L, L->top, u); + api_incr_top(L); + lua_unlock(L); + return u + 1; +} + + + + +static const char *aux_upvalue (StkId fi, int n, TValue **val) { + Closure *f; + if (!ttisfunction(fi)) return NULL; + f = clvalue(fi); + if (f->c.isC) { + if (!(1 <= n && n <= f->c.nupvalues)) return NULL; + *val = &f->c.upvalue[n-1]; + return ""; + } + else { + Proto *p = f->l.p; + if (!(1 <= n && n <= p->sizeupvalues)) return NULL; + *val = f->l.upvals[n-1]->v; + return getstr(p->upvalues[n-1]); + } +} + + +LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) { + const char *name; + TValue *val; + lua_lock(L); + name = aux_upvalue(index2adr(L, funcindex), n, &val); + if (name) { + setobj2s(L, L->top, val); + api_incr_top(L); + } + lua_unlock(L); + return name; +} + + +LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) { + const char *name; + TValue *val; + StkId fi; + lua_lock(L); + fi = index2adr(L, funcindex); + api_checknelems(L, 1); + name = aux_upvalue(fi, n, &val); + if (name) { + L->top--; + setobj(L, val, L->top); + luaC_barrier(L, clvalue(fi), L->top); + } + lua_unlock(L); + return name; +} + diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/src/lapi.h b/mod/pub.mod/lua.mod/lua-5.1.4/src/lapi.h new file mode 100644 index 0000000..2c3fab2 --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/src/lapi.h @@ -0,0 +1,16 @@ +/* +** $Id: lapi.h,v 2.2.1.1 2007/12/27 13:02:25 roberto Exp $ +** Auxiliary functions from Lua API +** See Copyright Notice in lua.h +*/ + +#ifndef lapi_h +#define lapi_h + + +#include "lobject.h" + + +LUAI_FUNC void luaA_pushobject (lua_State *L, const TValue *o); + +#endif diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/src/lauxlib.c b/mod/pub.mod/lua.mod/lua-5.1.4/src/lauxlib.c new file mode 100644 index 0000000..10f14e2 --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/src/lauxlib.c @@ -0,0 +1,652 @@ +/* +** $Id: lauxlib.c,v 1.159.1.3 2008/01/21 13:20:51 roberto Exp $ +** Auxiliary functions for building Lua libraries +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include +#include +#include +#include + + +/* This file uses only the official API of Lua. +** Any function declared here could be written as an application function. +*/ + +#define lauxlib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" + + +#define FREELIST_REF 0 /* free list of references */ + + +/* convert a stack index to positive */ +#define abs_index(L, i) ((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : \ + lua_gettop(L) + (i) + 1) + + +/* +** {====================================================== +** Error-report functions +** ======================================================= +*/ + + +LUALIB_API int luaL_argerror (lua_State *L, int narg, const char *extramsg) { + lua_Debug ar; + if (!lua_getstack(L, 0, &ar)) /* no stack frame? */ + return luaL_error(L, "bad argument #%d (%s)", narg, extramsg); + lua_getinfo(L, "n", &ar); + if (strcmp(ar.namewhat, "method") == 0) { + narg--; /* do not count `self' */ + if (narg == 0) /* error is in the self argument itself? */ + return luaL_error(L, "calling " LUA_QS " on bad self (%s)", + ar.name, extramsg); + } + if (ar.name == NULL) + ar.name = "?"; + return luaL_error(L, "bad argument #%d to " LUA_QS " (%s)", + narg, ar.name, extramsg); +} + + +LUALIB_API int luaL_typerror (lua_State *L, int narg, const char *tname) { + const char *msg = lua_pushfstring(L, "%s expected, got %s", + tname, luaL_typename(L, narg)); + return luaL_argerror(L, narg, msg); +} + + +static void tag_error (lua_State *L, int narg, int tag) { + luaL_typerror(L, narg, lua_typename(L, tag)); +} + + +LUALIB_API void luaL_where (lua_State *L, int level) { + lua_Debug ar; + if (lua_getstack(L, level, &ar)) { /* check function at level */ + lua_getinfo(L, "Sl", &ar); /* get info about it */ + if (ar.currentline > 0) { /* is there info? */ + lua_pushfstring(L, "%s:%d: ", ar.short_src, ar.currentline); + return; + } + } + lua_pushliteral(L, ""); /* else, no information available... */ +} + + +LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) { + va_list argp; + va_start(argp, fmt); + luaL_where(L, 1); + lua_pushvfstring(L, fmt, argp); + va_end(argp); + lua_concat(L, 2); + return lua_error(L); +} + +/* }====================================================== */ + + +LUALIB_API int luaL_checkoption (lua_State *L, int narg, const char *def, + const char *const lst[]) { + const char *name = (def) ? luaL_optstring(L, narg, def) : + luaL_checkstring(L, narg); + int i; + for (i=0; lst[i]; i++) + if (strcmp(lst[i], name) == 0) + return i; + return luaL_argerror(L, narg, + lua_pushfstring(L, "invalid option " LUA_QS, name)); +} + + +LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) { + lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get registry.name */ + if (!lua_isnil(L, -1)) /* name already in use? */ + return 0; /* leave previous value on top, but return 0 */ + lua_pop(L, 1); + lua_newtable(L); /* create metatable */ + lua_pushvalue(L, -1); + lua_setfield(L, LUA_REGISTRYINDEX, tname); /* registry.name = metatable */ + return 1; +} + + +LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) { + void *p = lua_touserdata(L, ud); + if (p != NULL) { /* value is a userdata? */ + if (lua_getmetatable(L, ud)) { /* does it have a metatable? */ + lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get correct metatable */ + if (lua_rawequal(L, -1, -2)) { /* does it have the correct mt? */ + lua_pop(L, 2); /* remove both metatables */ + return p; + } + } + } + luaL_typerror(L, ud, tname); /* else error */ + return NULL; /* to avoid warnings */ +} + + +LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *mes) { + if (!lua_checkstack(L, space)) + luaL_error(L, "stack overflow (%s)", mes); +} + + +LUALIB_API void luaL_checktype (lua_State *L, int narg, int t) { + if (lua_type(L, narg) != t) + tag_error(L, narg, t); +} + + +LUALIB_API void luaL_checkany (lua_State *L, int narg) { + if (lua_type(L, narg) == LUA_TNONE) + luaL_argerror(L, narg, "value expected"); +} + + +LUALIB_API const char *luaL_checklstring (lua_State *L, int narg, size_t *len) { + const char *s = lua_tolstring(L, narg, len); + if (!s) tag_error(L, narg, LUA_TSTRING); + return s; +} + + +LUALIB_API const char *luaL_optlstring (lua_State *L, int narg, + const char *def, size_t *len) { + if (lua_isnoneornil(L, narg)) { + if (len) + *len = (def ? strlen(def) : 0); + return def; + } + else return luaL_checklstring(L, narg, len); +} + + +LUALIB_API lua_Number luaL_checknumber (lua_State *L, int narg) { + lua_Number d = lua_tonumber(L, narg); + if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */ + tag_error(L, narg, LUA_TNUMBER); + return d; +} + + +LUALIB_API lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number def) { + return luaL_opt(L, luaL_checknumber, narg, def); +} + + +LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int narg) { + lua_Integer d = lua_tointeger(L, narg); + if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */ + tag_error(L, narg, LUA_TNUMBER); + return d; +} + + +LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int narg, + lua_Integer def) { + return luaL_opt(L, luaL_checkinteger, narg, def); +} + + +LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) { + if (!lua_getmetatable(L, obj)) /* no metatable? */ + return 0; + lua_pushstring(L, event); + lua_rawget(L, -2); + if (lua_isnil(L, -1)) { + lua_pop(L, 2); /* remove metatable and metafield */ + return 0; + } + else { + lua_remove(L, -2); /* remove only metatable */ + return 1; + } +} + + +LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) { + obj = abs_index(L, obj); + if (!luaL_getmetafield(L, obj, event)) /* no metafield? */ + return 0; + lua_pushvalue(L, obj); + lua_call(L, 1, 1); + return 1; +} + + +LUALIB_API void (luaL_register) (lua_State *L, const char *libname, + const luaL_Reg *l) { + luaI_openlib(L, libname, l, 0); +} + + +static int libsize (const luaL_Reg *l) { + int size = 0; + for (; l->name; l++) size++; + return size; +} + + +LUALIB_API void luaI_openlib (lua_State *L, const char *libname, + const luaL_Reg *l, int nup) { + if (libname) { + int size = libsize(l); + /* check whether lib already exists */ + luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1); + lua_getfield(L, -1, libname); /* get _LOADED[libname] */ + if (!lua_istable(L, -1)) { /* not found? */ + lua_pop(L, 1); /* remove previous result */ + /* try global variable (and create one if it does not exist) */ + if (luaL_findtable(L, LUA_GLOBALSINDEX, libname, size) != NULL) + luaL_error(L, "name conflict for module " LUA_QS, libname); + lua_pushvalue(L, -1); + lua_setfield(L, -3, libname); /* _LOADED[libname] = new table */ + } + lua_remove(L, -2); /* remove _LOADED table */ + lua_insert(L, -(nup+1)); /* move library table to below upvalues */ + } + for (; l->name; l++) { + int i; + for (i=0; ifunc, nup); + lua_setfield(L, -(nup+2), l->name); + } + lua_pop(L, nup); /* remove upvalues */ +} + + + +/* +** {====================================================== +** getn-setn: size for arrays +** ======================================================= +*/ + +#if defined(LUA_COMPAT_GETN) + +static int checkint (lua_State *L, int topop) { + int n = (lua_type(L, -1) == LUA_TNUMBER) ? lua_tointeger(L, -1) : -1; + lua_pop(L, topop); + return n; +} + + +static void getsizes (lua_State *L) { + lua_getfield(L, LUA_REGISTRYINDEX, "LUA_SIZES"); + if (lua_isnil(L, -1)) { /* no `size' table? */ + lua_pop(L, 1); /* remove nil */ + lua_newtable(L); /* create it */ + lua_pushvalue(L, -1); /* `size' will be its own metatable */ + lua_setmetatable(L, -2); + lua_pushliteral(L, "kv"); + lua_setfield(L, -2, "__mode"); /* metatable(N).__mode = "kv" */ + lua_pushvalue(L, -1); + lua_setfield(L, LUA_REGISTRYINDEX, "LUA_SIZES"); /* store in register */ + } +} + + +LUALIB_API void luaL_setn (lua_State *L, int t, int n) { + t = abs_index(L, t); + lua_pushliteral(L, "n"); + lua_rawget(L, t); + if (checkint(L, 1) >= 0) { /* is there a numeric field `n'? */ + lua_pushliteral(L, "n"); /* use it */ + lua_pushinteger(L, n); + lua_rawset(L, t); + } + else { /* use `sizes' */ + getsizes(L); + lua_pushvalue(L, t); + lua_pushinteger(L, n); + lua_rawset(L, -3); /* sizes[t] = n */ + lua_pop(L, 1); /* remove `sizes' */ + } +} + + +LUALIB_API int luaL_getn (lua_State *L, int t) { + int n; + t = abs_index(L, t); + lua_pushliteral(L, "n"); /* try t.n */ + lua_rawget(L, t); + if ((n = checkint(L, 1)) >= 0) return n; + getsizes(L); /* else try sizes[t] */ + lua_pushvalue(L, t); + lua_rawget(L, -2); + if ((n = checkint(L, 2)) >= 0) return n; + return (int)lua_objlen(L, t); +} + +#endif + +/* }====================================================== */ + + + +LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, const char *p, + const char *r) { + const char *wild; + size_t l = strlen(p); + luaL_Buffer b; + luaL_buffinit(L, &b); + while ((wild = strstr(s, p)) != NULL) { + luaL_addlstring(&b, s, wild - s); /* push prefix */ + luaL_addstring(&b, r); /* push replacement in place of pattern */ + s = wild + l; /* continue after `p' */ + } + luaL_addstring(&b, s); /* push last suffix */ + luaL_pushresult(&b); + return lua_tostring(L, -1); +} + + +LUALIB_API const char *luaL_findtable (lua_State *L, int idx, + const char *fname, int szhint) { + const char *e; + lua_pushvalue(L, idx); + do { + e = strchr(fname, '.'); + if (e == NULL) e = fname + strlen(fname); + lua_pushlstring(L, fname, e - fname); + lua_rawget(L, -2); + if (lua_isnil(L, -1)) { /* no such field? */ + lua_pop(L, 1); /* remove this nil */ + lua_createtable(L, 0, (*e == '.' ? 1 : szhint)); /* new table for field */ + lua_pushlstring(L, fname, e - fname); + lua_pushvalue(L, -2); + lua_settable(L, -4); /* set new table into field */ + } + else if (!lua_istable(L, -1)) { /* field has a non-table value? */ + lua_pop(L, 2); /* remove table and value */ + return fname; /* return problematic part of the name */ + } + lua_remove(L, -2); /* remove previous table */ + fname = e + 1; + } while (*e == '.'); + return NULL; +} + + + +/* +** {====================================================== +** Generic Buffer manipulation +** ======================================================= +*/ + + +#define bufflen(B) ((B)->p - (B)->buffer) +#define bufffree(B) ((size_t)(LUAL_BUFFERSIZE - bufflen(B))) + +#define LIMIT (LUA_MINSTACK/2) + + +static int emptybuffer (luaL_Buffer *B) { + size_t l = bufflen(B); + if (l == 0) return 0; /* put nothing on stack */ + else { + lua_pushlstring(B->L, B->buffer, l); + B->p = B->buffer; + B->lvl++; + return 1; + } +} + + +static void adjuststack (luaL_Buffer *B) { + if (B->lvl > 1) { + lua_State *L = B->L; + int toget = 1; /* number of levels to concat */ + size_t toplen = lua_strlen(L, -1); + do { + size_t l = lua_strlen(L, -(toget+1)); + if (B->lvl - toget + 1 >= LIMIT || toplen > l) { + toplen += l; + toget++; + } + else break; + } while (toget < B->lvl); + lua_concat(L, toget); + B->lvl = B->lvl - toget + 1; + } +} + + +LUALIB_API char *luaL_prepbuffer (luaL_Buffer *B) { + if (emptybuffer(B)) + adjuststack(B); + return B->buffer; +} + + +LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) { + while (l--) + luaL_addchar(B, *s++); +} + + +LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) { + luaL_addlstring(B, s, strlen(s)); +} + + +LUALIB_API void luaL_pushresult (luaL_Buffer *B) { + emptybuffer(B); + lua_concat(B->L, B->lvl); + B->lvl = 1; +} + + +LUALIB_API void luaL_addvalue (luaL_Buffer *B) { + lua_State *L = B->L; + size_t vl; + const char *s = lua_tolstring(L, -1, &vl); + if (vl <= bufffree(B)) { /* fit into buffer? */ + memcpy(B->p, s, vl); /* put it there */ + B->p += vl; + lua_pop(L, 1); /* remove from stack */ + } + else { + if (emptybuffer(B)) + lua_insert(L, -2); /* put buffer before new value */ + B->lvl++; /* add new value into B stack */ + adjuststack(B); + } +} + + +LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) { + B->L = L; + B->p = B->buffer; + B->lvl = 0; +} + +/* }====================================================== */ + + +LUALIB_API int luaL_ref (lua_State *L, int t) { + int ref; + t = abs_index(L, t); + if (lua_isnil(L, -1)) { + lua_pop(L, 1); /* remove from stack */ + return LUA_REFNIL; /* `nil' has a unique fixed reference */ + } + lua_rawgeti(L, t, FREELIST_REF); /* get first free element */ + ref = (int)lua_tointeger(L, -1); /* ref = t[FREELIST_REF] */ + lua_pop(L, 1); /* remove it from stack */ + if (ref != 0) { /* any free element? */ + lua_rawgeti(L, t, ref); /* remove it from list */ + lua_rawseti(L, t, FREELIST_REF); /* (t[FREELIST_REF] = t[ref]) */ + } + else { /* no free elements */ + ref = (int)lua_objlen(L, t); + ref++; /* create new reference */ + } + lua_rawseti(L, t, ref); + return ref; +} + + +LUALIB_API void luaL_unref (lua_State *L, int t, int ref) { + if (ref >= 0) { + t = abs_index(L, t); + lua_rawgeti(L, t, FREELIST_REF); + lua_rawseti(L, t, ref); /* t[ref] = t[FREELIST_REF] */ + lua_pushinteger(L, ref); + lua_rawseti(L, t, FREELIST_REF); /* t[FREELIST_REF] = ref */ + } +} + + + +/* +** {====================================================== +** Load functions +** ======================================================= +*/ + +typedef struct LoadF { + int extraline; + FILE *f; + char buff[LUAL_BUFFERSIZE]; +} LoadF; + + +static const char *getF (lua_State *L, void *ud, size_t *size) { + LoadF *lf = (LoadF *)ud; + (void)L; + if (lf->extraline) { + lf->extraline = 0; + *size = 1; + return "\n"; + } + if (feof(lf->f)) return NULL; + *size = fread(lf->buff, 1, sizeof(lf->buff), lf->f); + return (*size > 0) ? lf->buff : NULL; +} + + +static int errfile (lua_State *L, const char *what, int fnameindex) { + const char *serr = strerror(errno); + const char *filename = lua_tostring(L, fnameindex) + 1; + lua_pushfstring(L, "cannot %s %s: %s", what, filename, serr); + lua_remove(L, fnameindex); + return LUA_ERRFILE; +} + + +LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) { + LoadF lf; + int status, readstatus; + int c; + int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */ + lf.extraline = 0; + if (filename == NULL) { + lua_pushliteral(L, "=stdin"); + lf.f = stdin; + } + else { + lua_pushfstring(L, "@%s", filename); + lf.f = fopen(filename, "r"); + if (lf.f == NULL) return errfile(L, "open", fnameindex); + } + c = getc(lf.f); + if (c == '#') { /* Unix exec. file? */ + lf.extraline = 1; + while ((c = getc(lf.f)) != EOF && c != '\n') ; /* skip first line */ + if (c == '\n') c = getc(lf.f); + } + if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */ + lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */ + if (lf.f == NULL) return errfile(L, "reopen", fnameindex); + /* skip eventual `#!...' */ + while ((c = getc(lf.f)) != EOF && c != LUA_SIGNATURE[0]) ; + lf.extraline = 0; + } + ungetc(c, lf.f); + status = lua_load(L, getF, &lf, lua_tostring(L, -1)); + readstatus = ferror(lf.f); + if (filename) fclose(lf.f); /* close file (even in case of errors) */ + if (readstatus) { + lua_settop(L, fnameindex); /* ignore results from `lua_load' */ + return errfile(L, "read", fnameindex); + } + lua_remove(L, fnameindex); + return status; +} + + +typedef struct LoadS { + const char *s; + size_t size; +} LoadS; + + +static const char *getS (lua_State *L, void *ud, size_t *size) { + LoadS *ls = (LoadS *)ud; + (void)L; + if (ls->size == 0) return NULL; + *size = ls->size; + ls->size = 0; + return ls->s; +} + + +LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t size, + const char *name) { + LoadS ls; + ls.s = buff; + ls.size = size; + return lua_load(L, getS, &ls, name); +} + + +LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s) { + return luaL_loadbuffer(L, s, strlen(s), s); +} + + + +/* }====================================================== */ + + +static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) { + (void)ud; + (void)osize; + if (nsize == 0) { + free(ptr); + return NULL; + } + else + return realloc(ptr, nsize); +} + + +static int panic (lua_State *L) { + (void)L; /* to avoid warnings */ + fprintf(stderr, "PANIC: unprotected error in call to Lua API (%s)\n", + lua_tostring(L, -1)); + return 0; +} + + +LUALIB_API lua_State *luaL_newstate (void) { + lua_State *L = lua_newstate(l_alloc, NULL); + if (L) lua_atpanic(L, &panic); + return L; +} + diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/src/lauxlib.h b/mod/pub.mod/lua.mod/lua-5.1.4/src/lauxlib.h new file mode 100644 index 0000000..3425823 --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/src/lauxlib.h @@ -0,0 +1,174 @@ +/* +** $Id: lauxlib.h,v 1.88.1.1 2007/12/27 13:02:25 roberto Exp $ +** Auxiliary functions for building Lua libraries +** See Copyright Notice in lua.h +*/ + + +#ifndef lauxlib_h +#define lauxlib_h + + +#include +#include + +#include "lua.h" + + +#if defined(LUA_COMPAT_GETN) +LUALIB_API int (luaL_getn) (lua_State *L, int t); +LUALIB_API void (luaL_setn) (lua_State *L, int t, int n); +#else +#define luaL_getn(L,i) ((int)lua_objlen(L, i)) +#define luaL_setn(L,i,j) ((void)0) /* no op! */ +#endif + +#if defined(LUA_COMPAT_OPENLIB) +#define luaI_openlib luaL_openlib +#endif + + +/* extra error code for `luaL_load' */ +#define LUA_ERRFILE (LUA_ERRERR+1) + + +typedef struct luaL_Reg { + const char *name; + lua_CFunction func; +} luaL_Reg; + + + +LUALIB_API void (luaI_openlib) (lua_State *L, const char *libname, + const luaL_Reg *l, int nup); +LUALIB_API void (luaL_register) (lua_State *L, const char *libname, + const luaL_Reg *l); +LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e); +LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e); +LUALIB_API int (luaL_typerror) (lua_State *L, int narg, const char *tname); +LUALIB_API int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg); +LUALIB_API const char *(luaL_checklstring) (lua_State *L, int numArg, + size_t *l); +LUALIB_API const char *(luaL_optlstring) (lua_State *L, int numArg, + const char *def, size_t *l); +LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int numArg); +LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int nArg, lua_Number def); + +LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg); +LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg, + lua_Integer def); + +LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg); +LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t); +LUALIB_API void (luaL_checkany) (lua_State *L, int narg); + +LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname); +LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname); + +LUALIB_API void (luaL_where) (lua_State *L, int lvl); +LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...); + +LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def, + const char *const lst[]); + +LUALIB_API int (luaL_ref) (lua_State *L, int t); +LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref); + +LUALIB_API int (luaL_loadfile) (lua_State *L, const char *filename); +LUALIB_API int (luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz, + const char *name); +LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s); + +LUALIB_API lua_State *(luaL_newstate) (void); + + +LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p, + const char *r); + +LUALIB_API const char *(luaL_findtable) (lua_State *L, int idx, + const char *fname, int szhint); + + + + +/* +** =============================================================== +** some useful macros +** =============================================================== +*/ + +#define luaL_argcheck(L, cond,numarg,extramsg) \ + ((void)((cond) || luaL_argerror(L, (numarg), (extramsg)))) +#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL)) +#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL)) +#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n))) +#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d))) +#define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n))) +#define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d))) + +#define luaL_typename(L,i) lua_typename(L, lua_type(L,(i))) + +#define luaL_dofile(L, fn) \ + (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0)) + +#define luaL_dostring(L, s) \ + (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0)) + +#define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n))) + +#define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n))) + +/* +** {====================================================== +** Generic Buffer manipulation +** ======================================================= +*/ + + + +typedef struct luaL_Buffer { + char *p; /* current position in buffer */ + int lvl; /* number of strings in the stack (level) */ + lua_State *L; + char buffer[LUAL_BUFFERSIZE]; +} luaL_Buffer; + +#define luaL_addchar(B,c) \ + ((void)((B)->p < ((B)->buffer+LUAL_BUFFERSIZE) || luaL_prepbuffer(B)), \ + (*(B)->p++ = (char)(c))) + +/* compatibility only */ +#define luaL_putchar(B,c) luaL_addchar(B,c) + +#define luaL_addsize(B,n) ((B)->p += (n)) + +LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B); +LUALIB_API char *(luaL_prepbuffer) (luaL_Buffer *B); +LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l); +LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s); +LUALIB_API void (luaL_addvalue) (luaL_Buffer *B); +LUALIB_API void (luaL_pushresult) (luaL_Buffer *B); + + +/* }====================================================== */ + + +/* compatibility with ref system */ + +/* pre-defined references */ +#define LUA_NOREF (-2) +#define LUA_REFNIL (-1) + +#define lua_ref(L,lock) ((lock) ? luaL_ref(L, LUA_REGISTRYINDEX) : \ + (lua_pushstring(L, "unlocked references are obsolete"), lua_error(L), 0)) + +#define lua_unref(L,ref) luaL_unref(L, LUA_REGISTRYINDEX, (ref)) + +#define lua_getref(L,ref) lua_rawgeti(L, LUA_REGISTRYINDEX, (ref)) + + +#define luaL_reg luaL_Reg + +#endif + + diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/src/lbaselib.c b/mod/pub.mod/lua.mod/lua-5.1.4/src/lbaselib.c new file mode 100644 index 0000000..2a4c079 --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/src/lbaselib.c @@ -0,0 +1,653 @@ +/* +** $Id: lbaselib.c,v 1.191.1.6 2008/02/14 16:46:22 roberto Exp $ +** Basic library +** See Copyright Notice in lua.h +*/ + + + +#include +#include +#include +#include + +#define lbaselib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + + + +/* +** If your system does not support `stdout', you can just remove this function. +** If you need, you can define your own `print' function, following this +** model but changing `fputs' to put the strings at a proper place +** (a console window or a log file, for instance). +*/ +static int luaB_print (lua_State *L) { + int n = lua_gettop(L); /* number of arguments */ + int i; + lua_getglobal(L, "tostring"); + for (i=1; i<=n; i++) { + const char *s; + lua_pushvalue(L, -1); /* function to be called */ + lua_pushvalue(L, i); /* value to print */ + lua_call(L, 1, 1); + s = lua_tostring(L, -1); /* get result */ + if (s == NULL) + return luaL_error(L, LUA_QL("tostring") " must return a string to " + LUA_QL("print")); + if (i>1) fputs("\t", stdout); + fputs(s, stdout); + lua_pop(L, 1); /* pop result */ + } + fputs("\n", stdout); + return 0; +} + + +static int luaB_tonumber (lua_State *L) { + int base = luaL_optint(L, 2, 10); + if (base == 10) { /* standard conversion */ + luaL_checkany(L, 1); + if (lua_isnumber(L, 1)) { + lua_pushnumber(L, lua_tonumber(L, 1)); + return 1; + } + } + else { + const char *s1 = luaL_checkstring(L, 1); + char *s2; + unsigned long n; + luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range"); + n = strtoul(s1, &s2, base); + if (s1 != s2) { /* at least one valid digit? */ + while (isspace((unsigned char)(*s2))) s2++; /* skip trailing spaces */ + if (*s2 == '\0') { /* no invalid trailing characters? */ + lua_pushnumber(L, (lua_Number)n); + return 1; + } + } + } + lua_pushnil(L); /* else not a number */ + return 1; +} + + +static int luaB_error (lua_State *L) { + int level = luaL_optint(L, 2, 1); + lua_settop(L, 1); + if (lua_isstring(L, 1) && level > 0) { /* add extra information? */ + luaL_where(L, level); + lua_pushvalue(L, 1); + lua_concat(L, 2); + } + return lua_error(L); +} + + +static int luaB_getmetatable (lua_State *L) { + luaL_checkany(L, 1); + if (!lua_getmetatable(L, 1)) { + lua_pushnil(L); + return 1; /* no metatable */ + } + luaL_getmetafield(L, 1, "__metatable"); + return 1; /* returns either __metatable field (if present) or metatable */ +} + + +static int luaB_setmetatable (lua_State *L) { + int t = lua_type(L, 2); + luaL_checktype(L, 1, LUA_TTABLE); + luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2, + "nil or table expected"); + if (luaL_getmetafield(L, 1, "__metatable")) + luaL_error(L, "cannot change a protected metatable"); + lua_settop(L, 2); + lua_setmetatable(L, 1); + return 1; +} + + +static void getfunc (lua_State *L, int opt) { + if (lua_isfunction(L, 1)) lua_pushvalue(L, 1); + else { + lua_Debug ar; + int level = opt ? luaL_optint(L, 1, 1) : luaL_checkint(L, 1); + luaL_argcheck(L, level >= 0, 1, "level must be non-negative"); + if (lua_getstack(L, level, &ar) == 0) + luaL_argerror(L, 1, "invalid level"); + lua_getinfo(L, "f", &ar); + if (lua_isnil(L, -1)) + luaL_error(L, "no function environment for tail call at level %d", + level); + } +} + + +static int luaB_getfenv (lua_State *L) { + getfunc(L, 1); + if (lua_iscfunction(L, -1)) /* is a C function? */ + lua_pushvalue(L, LUA_GLOBALSINDEX); /* return the thread's global env. */ + else + lua_getfenv(L, -1); + return 1; +} + + +static int luaB_setfenv (lua_State *L) { + luaL_checktype(L, 2, LUA_TTABLE); + getfunc(L, 0); + lua_pushvalue(L, 2); + if (lua_isnumber(L, 1) && lua_tonumber(L, 1) == 0) { + /* change environment of current thread */ + lua_pushthread(L); + lua_insert(L, -2); + lua_setfenv(L, -2); + return 0; + } + else if (lua_iscfunction(L, -2) || lua_setfenv(L, -2) == 0) + luaL_error(L, + LUA_QL("setfenv") " cannot change environment of given object"); + return 1; +} + + +static int luaB_rawequal (lua_State *L) { + luaL_checkany(L, 1); + luaL_checkany(L, 2); + lua_pushboolean(L, lua_rawequal(L, 1, 2)); + return 1; +} + + +static int luaB_rawget (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + luaL_checkany(L, 2); + lua_settop(L, 2); + lua_rawget(L, 1); + return 1; +} + +static int luaB_rawset (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + luaL_checkany(L, 2); + luaL_checkany(L, 3); + lua_settop(L, 3); + lua_rawset(L, 1); + return 1; +} + + +static int luaB_gcinfo (lua_State *L) { + lua_pushinteger(L, lua_getgccount(L)); + return 1; +} + + +static int luaB_collectgarbage (lua_State *L) { + static const char *const opts[] = {"stop", "restart", "collect", + "count", "step", "setpause", "setstepmul", NULL}; + static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT, + LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL}; + int o = luaL_checkoption(L, 1, "collect", opts); + int ex = luaL_optint(L, 2, 0); + int res = lua_gc(L, optsnum[o], ex); + switch (optsnum[o]) { + case LUA_GCCOUNT: { + int b = lua_gc(L, LUA_GCCOUNTB, 0); + lua_pushnumber(L, res + ((lua_Number)b/1024)); + return 1; + } + case LUA_GCSTEP: { + lua_pushboolean(L, res); + return 1; + } + default: { + lua_pushnumber(L, res); + return 1; + } + } +} + + +static int luaB_type (lua_State *L) { + luaL_checkany(L, 1); + lua_pushstring(L, luaL_typename(L, 1)); + return 1; +} + + +static int luaB_next (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + lua_settop(L, 2); /* create a 2nd argument if there isn't one */ + if (lua_next(L, 1)) + return 2; + else { + lua_pushnil(L); + return 1; + } +} + + +static int luaB_pairs (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */ + lua_pushvalue(L, 1); /* state, */ + lua_pushnil(L); /* and initial value */ + return 3; +} + + +static int ipairsaux (lua_State *L) { + int i = luaL_checkint(L, 2); + luaL_checktype(L, 1, LUA_TTABLE); + i++; /* next value */ + lua_pushinteger(L, i); + lua_rawgeti(L, 1, i); + return (lua_isnil(L, -1)) ? 0 : 2; +} + + +static int luaB_ipairs (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */ + lua_pushvalue(L, 1); /* state, */ + lua_pushinteger(L, 0); /* and initial value */ + return 3; +} + + +static int load_aux (lua_State *L, int status) { + if (status == 0) /* OK? */ + return 1; + else { + lua_pushnil(L); + lua_insert(L, -2); /* put before error message */ + return 2; /* return nil plus error message */ + } +} + + +static int luaB_loadstring (lua_State *L) { + size_t l; + const char *s = luaL_checklstring(L, 1, &l); + const char *chunkname = luaL_optstring(L, 2, s); + return load_aux(L, luaL_loadbuffer(L, s, l, chunkname)); +} + + +static int luaB_loadfile (lua_State *L) { + const char *fname = luaL_optstring(L, 1, NULL); + return load_aux(L, luaL_loadfile(L, fname)); +} + + +/* +** Reader for generic `load' function: `lua_load' uses the +** stack for internal stuff, so the reader cannot change the +** stack top. Instead, it keeps its resulting string in a +** reserved slot inside the stack. +*/ +static const char *generic_reader (lua_State *L, void *ud, size_t *size) { + (void)ud; /* to avoid warnings */ + luaL_checkstack(L, 2, "too many nested functions"); + lua_pushvalue(L, 1); /* get function */ + lua_call(L, 0, 1); /* call it */ + if (lua_isnil(L, -1)) { + *size = 0; + return NULL; + } + else if (lua_isstring(L, -1)) { + lua_replace(L, 3); /* save string in a reserved stack slot */ + return lua_tolstring(L, 3, size); + } + else luaL_error(L, "reader function must return a string"); + return NULL; /* to avoid warnings */ +} + + +static int luaB_load (lua_State *L) { + int status; + const char *cname = luaL_optstring(L, 2, "=(load)"); + luaL_checktype(L, 1, LUA_TFUNCTION); + lua_settop(L, 3); /* function, eventual name, plus one reserved slot */ + status = lua_load(L, generic_reader, NULL, cname); + return load_aux(L, status); +} + + +static int luaB_dofile (lua_State *L) { + const char *fname = luaL_optstring(L, 1, NULL); + int n = lua_gettop(L); + if (luaL_loadfile(L, fname) != 0) lua_error(L); + lua_call(L, 0, LUA_MULTRET); + return lua_gettop(L) - n; +} + + +static int luaB_assert (lua_State *L) { + luaL_checkany(L, 1); + if (!lua_toboolean(L, 1)) + return luaL_error(L, "%s", luaL_optstring(L, 2, "assertion failed!")); + return lua_gettop(L); +} + + +static int luaB_unpack (lua_State *L) { + int i, e, n; + luaL_checktype(L, 1, LUA_TTABLE); + i = luaL_optint(L, 2, 1); + e = luaL_opt(L, luaL_checkint, 3, luaL_getn(L, 1)); + if (i > e) return 0; /* empty range */ + n = e - i + 1; /* number of elements */ + if (n <= 0 || !lua_checkstack(L, n)) /* n <= 0 means arith. overflow */ + return luaL_error(L, "too many results to unpack"); + lua_rawgeti(L, 1, i); /* push arg[i] (avoiding overflow problems) */ + while (i++ < e) /* push arg[i + 1...e] */ + lua_rawgeti(L, 1, i); + return n; +} + + +static int luaB_select (lua_State *L) { + int n = lua_gettop(L); + if (lua_type(L, 1) == LUA_TSTRING && *lua_tostring(L, 1) == '#') { + lua_pushinteger(L, n-1); + return 1; + } + else { + int i = luaL_checkint(L, 1); + if (i < 0) i = n + i; + else if (i > n) i = n; + luaL_argcheck(L, 1 <= i, 1, "index out of range"); + return n - i; + } +} + + +static int luaB_pcall (lua_State *L) { + int status; + luaL_checkany(L, 1); + status = lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0); + lua_pushboolean(L, (status == 0)); + lua_insert(L, 1); + return lua_gettop(L); /* return status + all results */ +} + + +static int luaB_xpcall (lua_State *L) { + int status; + luaL_checkany(L, 2); + lua_settop(L, 2); + lua_insert(L, 1); /* put error function under function to be called */ + status = lua_pcall(L, 0, LUA_MULTRET, 1); + lua_pushboolean(L, (status == 0)); + lua_replace(L, 1); + return lua_gettop(L); /* return status + all results */ +} + + +static int luaB_tostring (lua_State *L) { + luaL_checkany(L, 1); + if (luaL_callmeta(L, 1, "__tostring")) /* is there a metafield? */ + return 1; /* use its value */ + switch (lua_type(L, 1)) { + case LUA_TNUMBER: + lua_pushstring(L, lua_tostring(L, 1)); + break; + case LUA_TSTRING: + lua_pushvalue(L, 1); + break; + case LUA_TBOOLEAN: + lua_pushstring(L, (lua_toboolean(L, 1) ? "true" : "false")); + break; + case LUA_TNIL: + lua_pushliteral(L, "nil"); + break; + default: + lua_pushfstring(L, "%s: %p", luaL_typename(L, 1), lua_topointer(L, 1)); + break; + } + return 1; +} + + +static int luaB_newproxy (lua_State *L) { + lua_settop(L, 1); + lua_newuserdata(L, 0); /* create proxy */ + if (lua_toboolean(L, 1) == 0) + return 1; /* no metatable */ + else if (lua_isboolean(L, 1)) { + lua_newtable(L); /* create a new metatable `m' ... */ + lua_pushvalue(L, -1); /* ... and mark `m' as a valid metatable */ + lua_pushboolean(L, 1); + lua_rawset(L, lua_upvalueindex(1)); /* weaktable[m] = true */ + } + else { + int validproxy = 0; /* to check if weaktable[metatable(u)] == true */ + if (lua_getmetatable(L, 1)) { + lua_rawget(L, lua_upvalueindex(1)); + validproxy = lua_toboolean(L, -1); + lua_pop(L, 1); /* remove value */ + } + luaL_argcheck(L, validproxy, 1, "boolean or proxy expected"); + lua_getmetatable(L, 1); /* metatable is valid; get it */ + } + lua_setmetatable(L, 2); + return 1; +} + + +static const luaL_Reg base_funcs[] = { + {"assert", luaB_assert}, + {"collectgarbage", luaB_collectgarbage}, + {"dofile", luaB_dofile}, + {"error", luaB_error}, + {"gcinfo", luaB_gcinfo}, + {"getfenv", luaB_getfenv}, + {"getmetatable", luaB_getmetatable}, + {"loadfile", luaB_loadfile}, + {"load", luaB_load}, + {"loadstring", luaB_loadstring}, + {"next", luaB_next}, + {"pcall", luaB_pcall}, + {"print", luaB_print}, + {"rawequal", luaB_rawequal}, + {"rawget", luaB_rawget}, + {"rawset", luaB_rawset}, + {"select", luaB_select}, + {"setfenv", luaB_setfenv}, + {"setmetatable", luaB_setmetatable}, + {"tonumber", luaB_tonumber}, + {"tostring", luaB_tostring}, + {"type", luaB_type}, + {"unpack", luaB_unpack}, + {"xpcall", luaB_xpcall}, + {NULL, NULL} +}; + + +/* +** {====================================================== +** Coroutine library +** ======================================================= +*/ + +#define CO_RUN 0 /* running */ +#define CO_SUS 1 /* suspended */ +#define CO_NOR 2 /* 'normal' (it resumed another coroutine) */ +#define CO_DEAD 3 + +static const char *const statnames[] = + {"running", "suspended", "normal", "dead"}; + +static int costatus (lua_State *L, lua_State *co) { + if (L == co) return CO_RUN; + switch (lua_status(co)) { + case LUA_YIELD: + return CO_SUS; + case 0: { + lua_Debug ar; + if (lua_getstack(co, 0, &ar) > 0) /* does it have frames? */ + return CO_NOR; /* it is running */ + else if (lua_gettop(co) == 0) + return CO_DEAD; + else + return CO_SUS; /* initial state */ + } + default: /* some error occured */ + return CO_DEAD; + } +} + + +static int luaB_costatus (lua_State *L) { + lua_State *co = lua_tothread(L, 1); + luaL_argcheck(L, co, 1, "coroutine expected"); + lua_pushstring(L, statnames[costatus(L, co)]); + return 1; +} + + +static int auxresume (lua_State *L, lua_State *co, int narg) { + int status = costatus(L, co); + if (!lua_checkstack(co, narg)) + luaL_error(L, "too many arguments to resume"); + if (status != CO_SUS) { + lua_pushfstring(L, "cannot resume %s coroutine", statnames[status]); + return -1; /* error flag */ + } + lua_xmove(L, co, narg); + lua_setlevel(L, co); + status = lua_resume(co, narg); + if (status == 0 || status == LUA_YIELD) { + int nres = lua_gettop(co); + if (!lua_checkstack(L, nres + 1)) + luaL_error(L, "too many results to resume"); + lua_xmove(co, L, nres); /* move yielded values */ + return nres; + } + else { + lua_xmove(co, L, 1); /* move error message */ + return -1; /* error flag */ + } +} + + +static int luaB_coresume (lua_State *L) { + lua_State *co = lua_tothread(L, 1); + int r; + luaL_argcheck(L, co, 1, "coroutine expected"); + r = auxresume(L, co, lua_gettop(L) - 1); + if (r < 0) { + lua_pushboolean(L, 0); + lua_insert(L, -2); + return 2; /* return false + error message */ + } + else { + lua_pushboolean(L, 1); + lua_insert(L, -(r + 1)); + return r + 1; /* return true + `resume' returns */ + } +} + + +static int luaB_auxwrap (lua_State *L) { + lua_State *co = lua_tothread(L, lua_upvalueindex(1)); + int r = auxresume(L, co, lua_gettop(L)); + if (r < 0) { + if (lua_isstring(L, -1)) { /* error object is a string? */ + luaL_where(L, 1); /* add extra info */ + lua_insert(L, -2); + lua_concat(L, 2); + } + lua_error(L); /* propagate error */ + } + return r; +} + + +static int luaB_cocreate (lua_State *L) { + lua_State *NL = lua_newthread(L); + luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1, + "Lua function expected"); + lua_pushvalue(L, 1); /* move function to top */ + lua_xmove(L, NL, 1); /* move function from L to NL */ + return 1; +} + + +static int luaB_cowrap (lua_State *L) { + luaB_cocreate(L); + lua_pushcclosure(L, luaB_auxwrap, 1); + return 1; +} + + +static int luaB_yield (lua_State *L) { + return lua_yield(L, lua_gettop(L)); +} + + +static int luaB_corunning (lua_State *L) { + if (lua_pushthread(L)) + lua_pushnil(L); /* main thread is not a coroutine */ + return 1; +} + + +static const luaL_Reg co_funcs[] = { + {"create", luaB_cocreate}, + {"resume", luaB_coresume}, + {"running", luaB_corunning}, + {"status", luaB_costatus}, + {"wrap", luaB_cowrap}, + {"yield", luaB_yield}, + {NULL, NULL} +}; + +/* }====================================================== */ + + +static void auxopen (lua_State *L, const char *name, + lua_CFunction f, lua_CFunction u) { + lua_pushcfunction(L, u); + lua_pushcclosure(L, f, 1); + lua_setfield(L, -2, name); +} + + +static void base_open (lua_State *L) { + /* set global _G */ + lua_pushvalue(L, LUA_GLOBALSINDEX); + lua_setglobal(L, "_G"); + /* open lib into global table */ + luaL_register(L, "_G", base_funcs); + lua_pushliteral(L, LUA_VERSION); + lua_setglobal(L, "_VERSION"); /* set global _VERSION */ + /* `ipairs' and `pairs' need auxliliary functions as upvalues */ + auxopen(L, "ipairs", luaB_ipairs, ipairsaux); + auxopen(L, "pairs", luaB_pairs, luaB_next); + /* `newproxy' needs a weaktable as upvalue */ + lua_createtable(L, 0, 1); /* new table `w' */ + lua_pushvalue(L, -1); /* `w' will be its own metatable */ + lua_setmetatable(L, -2); + lua_pushliteral(L, "kv"); + lua_setfield(L, -2, "__mode"); /* metatable(w).__mode = "kv" */ + lua_pushcclosure(L, luaB_newproxy, 1); + lua_setglobal(L, "newproxy"); /* set global `newproxy' */ +} + + +LUALIB_API int luaopen_base (lua_State *L) { + base_open(L); + luaL_register(L, LUA_COLIBNAME, co_funcs); + return 2; +} + diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/src/lcode.c b/mod/pub.mod/lua.mod/lua-5.1.4/src/lcode.c new file mode 100644 index 0000000..cff626b --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/src/lcode.c @@ -0,0 +1,839 @@ +/* +** $Id: lcode.c,v 2.25.1.3 2007/12/28 15:32:23 roberto Exp $ +** Code generator for Lua +** See Copyright Notice in lua.h +*/ + + +#include + +#define lcode_c +#define LUA_CORE + +#include "lua.h" + +#include "lcode.h" +#include "ldebug.h" +#include "ldo.h" +#include "lgc.h" +#include "llex.h" +#include "lmem.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lparser.h" +#include "ltable.h" + + +#define hasjumps(e) ((e)->t != (e)->f) + + +static int isnumeral(expdesc *e) { + return (e->k == VKNUM && e->t == NO_JUMP && e->f == NO_JUMP); +} + + +void luaK_nil (FuncState *fs, int from, int n) { + Instruction *previous; + if (fs->pc > fs->lasttarget) { /* no jumps to current position? */ + if (fs->pc == 0) { /* function start? */ + if (from >= fs->nactvar) + return; /* positions are already clean */ + } + else { + previous = &fs->f->code[fs->pc-1]; + if (GET_OPCODE(*previous) == OP_LOADNIL) { + int pfrom = GETARG_A(*previous); + int pto = GETARG_B(*previous); + if (pfrom <= from && from <= pto+1) { /* can connect both? */ + if (from+n-1 > pto) + SETARG_B(*previous, from+n-1); + return; + } + } + } + } + luaK_codeABC(fs, OP_LOADNIL, from, from+n-1, 0); /* else no optimization */ +} + + +int luaK_jump (FuncState *fs) { + int jpc = fs->jpc; /* save list of jumps to here */ + int j; + fs->jpc = NO_JUMP; + j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP); + luaK_concat(fs, &j, jpc); /* keep them on hold */ + return j; +} + + +void luaK_ret (FuncState *fs, int first, int nret) { + luaK_codeABC(fs, OP_RETURN, first, nret+1, 0); +} + + +static int condjump (FuncState *fs, OpCode op, int A, int B, int C) { + luaK_codeABC(fs, op, A, B, C); + return luaK_jump(fs); +} + + +static void fixjump (FuncState *fs, int pc, int dest) { + Instruction *jmp = &fs->f->code[pc]; + int offset = dest-(pc+1); + lua_assert(dest != NO_JUMP); + if (abs(offset) > MAXARG_sBx) + luaX_syntaxerror(fs->ls, "control structure too long"); + SETARG_sBx(*jmp, offset); +} + + +/* +** returns current `pc' and marks it as a jump target (to avoid wrong +** optimizations with consecutive instructions not in the same basic block). +*/ +int luaK_getlabel (FuncState *fs) { + fs->lasttarget = fs->pc; + return fs->pc; +} + + +static int getjump (FuncState *fs, int pc) { + int offset = GETARG_sBx(fs->f->code[pc]); + if (offset == NO_JUMP) /* point to itself represents end of list */ + return NO_JUMP; /* end of list */ + else + return (pc+1)+offset; /* turn offset into absolute position */ +} + + +static Instruction *getjumpcontrol (FuncState *fs, int pc) { + Instruction *pi = &fs->f->code[pc]; + if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1)))) + return pi-1; + else + return pi; +} + + +/* +** check whether list has any jump that do not produce a value +** (or produce an inverted value) +*/ +static int need_value (FuncState *fs, int list) { + for (; list != NO_JUMP; list = getjump(fs, list)) { + Instruction i = *getjumpcontrol(fs, list); + if (GET_OPCODE(i) != OP_TESTSET) return 1; + } + return 0; /* not found */ +} + + +static int patchtestreg (FuncState *fs, int node, int reg) { + Instruction *i = getjumpcontrol(fs, node); + if (GET_OPCODE(*i) != OP_TESTSET) + return 0; /* cannot patch other instructions */ + if (reg != NO_REG && reg != GETARG_B(*i)) + SETARG_A(*i, reg); + else /* no register to put value or register already has the value */ + *i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i)); + + return 1; +} + + +static void removevalues (FuncState *fs, int list) { + for (; list != NO_JUMP; list = getjump(fs, list)) + patchtestreg(fs, list, NO_REG); +} + + +static void patchlistaux (FuncState *fs, int list, int vtarget, int reg, + int dtarget) { + while (list != NO_JUMP) { + int next = getjump(fs, list); + if (patchtestreg(fs, list, reg)) + fixjump(fs, list, vtarget); + else + fixjump(fs, list, dtarget); /* jump to default target */ + list = next; + } +} + + +static void dischargejpc (FuncState *fs) { + patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc); + fs->jpc = NO_JUMP; +} + + +void luaK_patchlist (FuncState *fs, int list, int target) { + if (target == fs->pc) + luaK_patchtohere(fs, list); + else { + lua_assert(target < fs->pc); + patchlistaux(fs, list, target, NO_REG, target); + } +} + + +void luaK_patchtohere (FuncState *fs, int list) { + luaK_getlabel(fs); + luaK_concat(fs, &fs->jpc, list); +} + + +void luaK_concat (FuncState *fs, int *l1, int l2) { + if (l2 == NO_JUMP) return; + else if (*l1 == NO_JUMP) + *l1 = l2; + else { + int list = *l1; + int next; + while ((next = getjump(fs, list)) != NO_JUMP) /* find last element */ + list = next; + fixjump(fs, list, l2); + } +} + + +void luaK_checkstack (FuncState *fs, int n) { + int newstack = fs->freereg + n; + if (newstack > fs->f->maxstacksize) { + if (newstack >= MAXSTACK) + luaX_syntaxerror(fs->ls, "function or expression too complex"); + fs->f->maxstacksize = cast_byte(newstack); + } +} + + +void luaK_reserveregs (FuncState *fs, int n) { + luaK_checkstack(fs, n); + fs->freereg += n; +} + + +static void freereg (FuncState *fs, int reg) { + if (!ISK(reg) && reg >= fs->nactvar) { + fs->freereg--; + lua_assert(reg == fs->freereg); + } +} + + +static void freeexp (FuncState *fs, expdesc *e) { + if (e->k == VNONRELOC) + freereg(fs, e->u.s.info); +} + + +static int addk (FuncState *fs, TValue *k, TValue *v) { + lua_State *L = fs->L; + TValue *idx = luaH_set(L, fs->h, k); + Proto *f = fs->f; + int oldsize = f->sizek; + if (ttisnumber(idx)) { + lua_assert(luaO_rawequalObj(&fs->f->k[cast_int(nvalue(idx))], v)); + return cast_int(nvalue(idx)); + } + else { /* constant not found; create a new entry */ + setnvalue(idx, cast_num(fs->nk)); + luaM_growvector(L, f->k, fs->nk, f->sizek, TValue, + MAXARG_Bx, "constant table overflow"); + while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]); + setobj(L, &f->k[fs->nk], v); + luaC_barrier(L, f, v); + return fs->nk++; + } +} + + +int luaK_stringK (FuncState *fs, TString *s) { + TValue o; + setsvalue(fs->L, &o, s); + return addk(fs, &o, &o); +} + + +int luaK_numberK (FuncState *fs, lua_Number r) { + TValue o; + setnvalue(&o, r); + return addk(fs, &o, &o); +} + + +static int boolK (FuncState *fs, int b) { + TValue o; + setbvalue(&o, b); + return addk(fs, &o, &o); +} + + +static int nilK (FuncState *fs) { + TValue k, v; + setnilvalue(&v); + /* cannot use nil as key; instead use table itself to represent nil */ + sethvalue(fs->L, &k, fs->h); + return addk(fs, &k, &v); +} + + +void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) { + if (e->k == VCALL) { /* expression is an open function call? */ + SETARG_C(getcode(fs, e), nresults+1); + } + else if (e->k == VVARARG) { + SETARG_B(getcode(fs, e), nresults+1); + SETARG_A(getcode(fs, e), fs->freereg); + luaK_reserveregs(fs, 1); + } +} + + +void luaK_setoneret (FuncState *fs, expdesc *e) { + if (e->k == VCALL) { /* expression is an open function call? */ + e->k = VNONRELOC; + e->u.s.info = GETARG_A(getcode(fs, e)); + } + else if (e->k == VVARARG) { + SETARG_B(getcode(fs, e), 2); + e->k = VRELOCABLE; /* can relocate its simple result */ + } +} + + +void luaK_dischargevars (FuncState *fs, expdesc *e) { + switch (e->k) { + case VLOCAL: { + e->k = VNONRELOC; + break; + } + case VUPVAL: { + e->u.s.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.s.info, 0); + e->k = VRELOCABLE; + break; + } + case VGLOBAL: { + e->u.s.info = luaK_codeABx(fs, OP_GETGLOBAL, 0, e->u.s.info); + e->k = VRELOCABLE; + break; + } + case VINDEXED: { + freereg(fs, e->u.s.aux); + freereg(fs, e->u.s.info); + e->u.s.info = luaK_codeABC(fs, OP_GETTABLE, 0, e->u.s.info, e->u.s.aux); + e->k = VRELOCABLE; + break; + } + case VVARARG: + case VCALL: { + luaK_setoneret(fs, e); + break; + } + default: break; /* there is one value available (somewhere) */ + } +} + + +static int code_label (FuncState *fs, int A, int b, int jump) { + luaK_getlabel(fs); /* those instructions may be jump targets */ + return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump); +} + + +static void discharge2reg (FuncState *fs, expdesc *e, int reg) { + luaK_dischargevars(fs, e); + switch (e->k) { + case VNIL: { + luaK_nil(fs, reg, 1); + break; + } + case VFALSE: case VTRUE: { + luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0); + break; + } + case VK: { + luaK_codeABx(fs, OP_LOADK, reg, e->u.s.info); + break; + } + case VKNUM: { + luaK_codeABx(fs, OP_LOADK, reg, luaK_numberK(fs, e->u.nval)); + break; + } + case VRELOCABLE: { + Instruction *pc = &getcode(fs, e); + SETARG_A(*pc, reg); + break; + } + case VNONRELOC: { + if (reg != e->u.s.info) + luaK_codeABC(fs, OP_MOVE, reg, e->u.s.info, 0); + break; + } + default: { + lua_assert(e->k == VVOID || e->k == VJMP); + return; /* nothing to do... */ + } + } + e->u.s.info = reg; + e->k = VNONRELOC; +} + + +static void discharge2anyreg (FuncState *fs, expdesc *e) { + if (e->k != VNONRELOC) { + luaK_reserveregs(fs, 1); + discharge2reg(fs, e, fs->freereg-1); + } +} + + +static void exp2reg (FuncState *fs, expdesc *e, int reg) { + discharge2reg(fs, e, reg); + if (e->k == VJMP) + luaK_concat(fs, &e->t, e->u.s.info); /* put this jump in `t' list */ + if (hasjumps(e)) { + int final; /* position after whole expression */ + int p_f = NO_JUMP; /* position of an eventual LOAD false */ + int p_t = NO_JUMP; /* position of an eventual LOAD true */ + if (need_value(fs, e->t) || need_value(fs, e->f)) { + int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs); + p_f = code_label(fs, reg, 0, 1); + p_t = code_label(fs, reg, 1, 0); + luaK_patchtohere(fs, fj); + } + final = luaK_getlabel(fs); + patchlistaux(fs, e->f, final, reg, p_f); + patchlistaux(fs, e->t, final, reg, p_t); + } + e->f = e->t = NO_JUMP; + e->u.s.info = reg; + e->k = VNONRELOC; +} + + +void luaK_exp2nextreg (FuncState *fs, expdesc *e) { + luaK_dischargevars(fs, e); + freeexp(fs, e); + luaK_reserveregs(fs, 1); + exp2reg(fs, e, fs->freereg - 1); +} + + +int luaK_exp2anyreg (FuncState *fs, expdesc *e) { + luaK_dischargevars(fs, e); + if (e->k == VNONRELOC) { + if (!hasjumps(e)) return e->u.s.info; /* exp is already in a register */ + if (e->u.s.info >= fs->nactvar) { /* reg. is not a local? */ + exp2reg(fs, e, e->u.s.info); /* put value on it */ + return e->u.s.info; + } + } + luaK_exp2nextreg(fs, e); /* default */ + return e->u.s.info; +} + + +void luaK_exp2val (FuncState *fs, expdesc *e) { + if (hasjumps(e)) + luaK_exp2anyreg(fs, e); + else + luaK_dischargevars(fs, e); +} + + +int luaK_exp2RK (FuncState *fs, expdesc *e) { + luaK_exp2val(fs, e); + switch (e->k) { + case VKNUM: + case VTRUE: + case VFALSE: + case VNIL: { + if (fs->nk <= MAXINDEXRK) { /* constant fit in RK operand? */ + e->u.s.info = (e->k == VNIL) ? nilK(fs) : + (e->k == VKNUM) ? luaK_numberK(fs, e->u.nval) : + boolK(fs, (e->k == VTRUE)); + e->k = VK; + return RKASK(e->u.s.info); + } + else break; + } + case VK: { + if (e->u.s.info <= MAXINDEXRK) /* constant fit in argC? */ + return RKASK(e->u.s.info); + else break; + } + default: break; + } + /* not a constant in the right range: put it in a register */ + return luaK_exp2anyreg(fs, e); +} + + +void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) { + switch (var->k) { + case VLOCAL: { + freeexp(fs, ex); + exp2reg(fs, ex, var->u.s.info); + return; + } + case VUPVAL: { + int e = luaK_exp2anyreg(fs, ex); + luaK_codeABC(fs, OP_SETUPVAL, e, var->u.s.info, 0); + break; + } + case VGLOBAL: { + int e = luaK_exp2anyreg(fs, ex); + luaK_codeABx(fs, OP_SETGLOBAL, e, var->u.s.info); + break; + } + case VINDEXED: { + int e = luaK_exp2RK(fs, ex); + luaK_codeABC(fs, OP_SETTABLE, var->u.s.info, var->u.s.aux, e); + break; + } + default: { + lua_assert(0); /* invalid var kind to store */ + break; + } + } + freeexp(fs, ex); +} + + +void luaK_self (FuncState *fs, expdesc *e, expdesc *key) { + int func; + luaK_exp2anyreg(fs, e); + freeexp(fs, e); + func = fs->freereg; + luaK_reserveregs(fs, 2); + luaK_codeABC(fs, OP_SELF, func, e->u.s.info, luaK_exp2RK(fs, key)); + freeexp(fs, key); + e->u.s.info = func; + e->k = VNONRELOC; +} + + +static void invertjump (FuncState *fs, expdesc *e) { + Instruction *pc = getjumpcontrol(fs, e->u.s.info); + lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET && + GET_OPCODE(*pc) != OP_TEST); + SETARG_A(*pc, !(GETARG_A(*pc))); +} + + +static int jumponcond (FuncState *fs, expdesc *e, int cond) { + if (e->k == VRELOCABLE) { + Instruction ie = getcode(fs, e); + if (GET_OPCODE(ie) == OP_NOT) { + fs->pc--; /* remove previous OP_NOT */ + return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond); + } + /* else go through */ + } + discharge2anyreg(fs, e); + freeexp(fs, e); + return condjump(fs, OP_TESTSET, NO_REG, e->u.s.info, cond); +} + + +void luaK_goiftrue (FuncState *fs, expdesc *e) { + int pc; /* pc of last jump */ + luaK_dischargevars(fs, e); + switch (e->k) { + case VK: case VKNUM: case VTRUE: { + pc = NO_JUMP; /* always true; do nothing */ + break; + } + case VFALSE: { + pc = luaK_jump(fs); /* always jump */ + break; + } + case VJMP: { + invertjump(fs, e); + pc = e->u.s.info; + break; + } + default: { + pc = jumponcond(fs, e, 0); + break; + } + } + luaK_concat(fs, &e->f, pc); /* insert last jump in `f' list */ + luaK_patchtohere(fs, e->t); + e->t = NO_JUMP; +} + + +static void luaK_goiffalse (FuncState *fs, expdesc *e) { + int pc; /* pc of last jump */ + luaK_dischargevars(fs, e); + switch (e->k) { + case VNIL: case VFALSE: { + pc = NO_JUMP; /* always false; do nothing */ + break; + } + case VTRUE: { + pc = luaK_jump(fs); /* always jump */ + break; + } + case VJMP: { + pc = e->u.s.info; + break; + } + default: { + pc = jumponcond(fs, e, 1); + break; + } + } + luaK_concat(fs, &e->t, pc); /* insert last jump in `t' list */ + luaK_patchtohere(fs, e->f); + e->f = NO_JUMP; +} + + +static void codenot (FuncState *fs, expdesc *e) { + luaK_dischargevars(fs, e); + switch (e->k) { + case VNIL: case VFALSE: { + e->k = VTRUE; + break; + } + case VK: case VKNUM: case VTRUE: { + e->k = VFALSE; + break; + } + case VJMP: { + invertjump(fs, e); + break; + } + case VRELOCABLE: + case VNONRELOC: { + discharge2anyreg(fs, e); + freeexp(fs, e); + e->u.s.info = luaK_codeABC(fs, OP_NOT, 0, e->u.s.info, 0); + e->k = VRELOCABLE; + break; + } + default: { + lua_assert(0); /* cannot happen */ + break; + } + } + /* interchange true and false lists */ + { int temp = e->f; e->f = e->t; e->t = temp; } + removevalues(fs, e->f); + removevalues(fs, e->t); +} + + +void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { + t->u.s.aux = luaK_exp2RK(fs, k); + t->k = VINDEXED; +} + + +static int constfolding (OpCode op, expdesc *e1, expdesc *e2) { + lua_Number v1, v2, r; + if (!isnumeral(e1) || !isnumeral(e2)) return 0; + v1 = e1->u.nval; + v2 = e2->u.nval; + switch (op) { + case OP_ADD: r = luai_numadd(v1, v2); break; + case OP_SUB: r = luai_numsub(v1, v2); break; + case OP_MUL: r = luai_nummul(v1, v2); break; + case OP_DIV: + if (v2 == 0) return 0; /* do not attempt to divide by 0 */ + r = luai_numdiv(v1, v2); break; + case OP_MOD: + if (v2 == 0) return 0; /* do not attempt to divide by 0 */ + r = luai_nummod(v1, v2); break; + case OP_POW: r = luai_numpow(v1, v2); break; + case OP_UNM: r = luai_numunm(v1); break; + case OP_LEN: return 0; /* no constant folding for 'len' */ + default: lua_assert(0); r = 0; break; + } + if (luai_numisnan(r)) return 0; /* do not attempt to produce NaN */ + e1->u.nval = r; + return 1; +} + + +static void codearith (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) { + if (constfolding(op, e1, e2)) + return; + else { + int o2 = (op != OP_UNM && op != OP_LEN) ? luaK_exp2RK(fs, e2) : 0; + int o1 = luaK_exp2RK(fs, e1); + if (o1 > o2) { + freeexp(fs, e1); + freeexp(fs, e2); + } + else { + freeexp(fs, e2); + freeexp(fs, e1); + } + e1->u.s.info = luaK_codeABC(fs, op, 0, o1, o2); + e1->k = VRELOCABLE; + } +} + + +static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1, + expdesc *e2) { + int o1 = luaK_exp2RK(fs, e1); + int o2 = luaK_exp2RK(fs, e2); + freeexp(fs, e2); + freeexp(fs, e1); + if (cond == 0 && op != OP_EQ) { + int temp; /* exchange args to replace by `<' or `<=' */ + temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */ + cond = 1; + } + e1->u.s.info = condjump(fs, op, cond, o1, o2); + e1->k = VJMP; +} + + +void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) { + expdesc e2; + e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0; + switch (op) { + case OPR_MINUS: { + if (!isnumeral(e)) + luaK_exp2anyreg(fs, e); /* cannot operate on non-numeric constants */ + codearith(fs, OP_UNM, e, &e2); + break; + } + case OPR_NOT: codenot(fs, e); break; + case OPR_LEN: { + luaK_exp2anyreg(fs, e); /* cannot operate on constants */ + codearith(fs, OP_LEN, e, &e2); + break; + } + default: lua_assert(0); + } +} + + +void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) { + switch (op) { + case OPR_AND: { + luaK_goiftrue(fs, v); + break; + } + case OPR_OR: { + luaK_goiffalse(fs, v); + break; + } + case OPR_CONCAT: { + luaK_exp2nextreg(fs, v); /* operand must be on the `stack' */ + break; + } + case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV: + case OPR_MOD: case OPR_POW: { + if (!isnumeral(v)) luaK_exp2RK(fs, v); + break; + } + default: { + luaK_exp2RK(fs, v); + break; + } + } +} + + +void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) { + switch (op) { + case OPR_AND: { + lua_assert(e1->t == NO_JUMP); /* list must be closed */ + luaK_dischargevars(fs, e2); + luaK_concat(fs, &e2->f, e1->f); + *e1 = *e2; + break; + } + case OPR_OR: { + lua_assert(e1->f == NO_JUMP); /* list must be closed */ + luaK_dischargevars(fs, e2); + luaK_concat(fs, &e2->t, e1->t); + *e1 = *e2; + break; + } + case OPR_CONCAT: { + luaK_exp2val(fs, e2); + if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) { + lua_assert(e1->u.s.info == GETARG_B(getcode(fs, e2))-1); + freeexp(fs, e1); + SETARG_B(getcode(fs, e2), e1->u.s.info); + e1->k = VRELOCABLE; e1->u.s.info = e2->u.s.info; + } + else { + luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */ + codearith(fs, OP_CONCAT, e1, e2); + } + break; + } + case OPR_ADD: codearith(fs, OP_ADD, e1, e2); break; + case OPR_SUB: codearith(fs, OP_SUB, e1, e2); break; + case OPR_MUL: codearith(fs, OP_MUL, e1, e2); break; + case OPR_DIV: codearith(fs, OP_DIV, e1, e2); break; + case OPR_MOD: codearith(fs, OP_MOD, e1, e2); break; + case OPR_POW: codearith(fs, OP_POW, e1, e2); break; + case OPR_EQ: codecomp(fs, OP_EQ, 1, e1, e2); break; + case OPR_NE: codecomp(fs, OP_EQ, 0, e1, e2); break; + case OPR_LT: codecomp(fs, OP_LT, 1, e1, e2); break; + case OPR_LE: codecomp(fs, OP_LE, 1, e1, e2); break; + case OPR_GT: codecomp(fs, OP_LT, 0, e1, e2); break; + case OPR_GE: codecomp(fs, OP_LE, 0, e1, e2); break; + default: lua_assert(0); + } +} + + +void luaK_fixline (FuncState *fs, int line) { + fs->f->lineinfo[fs->pc - 1] = line; +} + + +static int luaK_code (FuncState *fs, Instruction i, int line) { + Proto *f = fs->f; + dischargejpc(fs); /* `pc' will change */ + /* put new instruction in code array */ + luaM_growvector(fs->L, f->code, fs->pc, f->sizecode, Instruction, + MAX_INT, "code size overflow"); + f->code[fs->pc] = i; + /* save corresponding line information */ + luaM_growvector(fs->L, f->lineinfo, fs->pc, f->sizelineinfo, int, + MAX_INT, "code size overflow"); + f->lineinfo[fs->pc] = line; + return fs->pc++; +} + + +int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) { + lua_assert(getOpMode(o) == iABC); + lua_assert(getBMode(o) != OpArgN || b == 0); + lua_assert(getCMode(o) != OpArgN || c == 0); + return luaK_code(fs, CREATE_ABC(o, a, b, c), fs->ls->lastline); +} + + +int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) { + lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx); + lua_assert(getCMode(o) == OpArgN); + return luaK_code(fs, CREATE_ABx(o, a, bc), fs->ls->lastline); +} + + +void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) { + int c = (nelems - 1)/LFIELDS_PER_FLUSH + 1; + int b = (tostore == LUA_MULTRET) ? 0 : tostore; + lua_assert(tostore != 0); + if (c <= MAXARG_C) + luaK_codeABC(fs, OP_SETLIST, base, b, c); + else { + luaK_codeABC(fs, OP_SETLIST, base, b, 0); + luaK_code(fs, cast(Instruction, c), fs->ls->lastline); + } + fs->freereg = base + 1; /* free registers with list values */ +} + diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/src/lcode.h b/mod/pub.mod/lua.mod/lua-5.1.4/src/lcode.h new file mode 100644 index 0000000..b941c60 --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/src/lcode.h @@ -0,0 +1,76 @@ +/* +** $Id: lcode.h,v 1.48.1.1 2007/12/27 13:02:25 roberto Exp $ +** Code generator for Lua +** See Copyright Notice in lua.h +*/ + +#ifndef lcode_h +#define lcode_h + +#include "llex.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lparser.h" + + +/* +** Marks the end of a patch list. It is an invalid value both as an absolute +** address, and as a list link (would link an element to itself). +*/ +#define NO_JUMP (-1) + + +/* +** grep "ORDER OPR" if you change these enums +*/ +typedef enum BinOpr { + OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW, + OPR_CONCAT, + OPR_NE, OPR_EQ, + OPR_LT, OPR_LE, OPR_GT, OPR_GE, + OPR_AND, OPR_OR, + OPR_NOBINOPR +} BinOpr; + + +typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr; + + +#define getcode(fs,e) ((fs)->f->code[(e)->u.s.info]) + +#define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx) + +#define luaK_setmultret(fs,e) luaK_setreturns(fs, e, LUA_MULTRET) + +LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx); +LUAI_FUNC int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C); +LUAI_FUNC void luaK_fixline (FuncState *fs, int line); +LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n); +LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n); +LUAI_FUNC void luaK_checkstack (FuncState *fs, int n); +LUAI_FUNC int luaK_stringK (FuncState *fs, TString *s); +LUAI_FUNC int luaK_numberK (FuncState *fs, lua_Number r); +LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e); +LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e); +LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key); +LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k); +LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e); +LUAI_FUNC void luaK_setreturns (FuncState *fs, expdesc *e, int nresults); +LUAI_FUNC void luaK_setoneret (FuncState *fs, expdesc *e); +LUAI_FUNC int luaK_jump (FuncState *fs); +LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret); +LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target); +LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list); +LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2); +LUAI_FUNC int luaK_getlabel (FuncState *fs); +LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v); +LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v); +LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, expdesc *v2); +LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore); + + +#endif diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/src/ldblib.c b/mod/pub.mod/lua.mod/lua-5.1.4/src/ldblib.c new file mode 100644 index 0000000..67de122 --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/src/ldblib.c @@ -0,0 +1,397 @@ +/* +** $Id: ldblib.c,v 1.104.1.3 2008/01/21 13:11:21 roberto Exp $ +** Interface from Lua to its debug API +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include + +#define ldblib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + + +static int db_getregistry (lua_State *L) { + lua_pushvalue(L, LUA_REGISTRYINDEX); + return 1; +} + + +static int db_getmetatable (lua_State *L) { + luaL_checkany(L, 1); + if (!lua_getmetatable(L, 1)) { + lua_pushnil(L); /* no metatable */ + } + return 1; +} + + +static int db_setmetatable (lua_State *L) { + int t = lua_type(L, 2); + luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2, + "nil or table expected"); + lua_settop(L, 2); + lua_pushboolean(L, lua_setmetatable(L, 1)); + return 1; +} + + +static int db_getfenv (lua_State *L) { + lua_getfenv(L, 1); + return 1; +} + + +static int db_setfenv (lua_State *L) { + luaL_checktype(L, 2, LUA_TTABLE); + lua_settop(L, 2); + if (lua_setfenv(L, 1) == 0) + luaL_error(L, LUA_QL("setfenv") + " cannot change environment of given object"); + return 1; +} + + +static void settabss (lua_State *L, const char *i, const char *v) { + lua_pushstring(L, v); + lua_setfield(L, -2, i); +} + + +static void settabsi (lua_State *L, const char *i, int v) { + lua_pushinteger(L, v); + lua_setfield(L, -2, i); +} + + +static lua_State *getthread (lua_State *L, int *arg) { + if (lua_isthread(L, 1)) { + *arg = 1; + return lua_tothread(L, 1); + } + else { + *arg = 0; + return L; + } +} + + +static void treatstackoption (lua_State *L, lua_State *L1, const char *fname) { + if (L == L1) { + lua_pushvalue(L, -2); + lua_remove(L, -3); + } + else + lua_xmove(L1, L, 1); + lua_setfield(L, -2, fname); +} + + +static int db_getinfo (lua_State *L) { + lua_Debug ar; + int arg; + lua_State *L1 = getthread(L, &arg); + const char *options = luaL_optstring(L, arg+2, "flnSu"); + if (lua_isnumber(L, arg+1)) { + if (!lua_getstack(L1, (int)lua_tointeger(L, arg+1), &ar)) { + lua_pushnil(L); /* level out of range */ + return 1; + } + } + else if (lua_isfunction(L, arg+1)) { + lua_pushfstring(L, ">%s", options); + options = lua_tostring(L, -1); + lua_pushvalue(L, arg+1); + lua_xmove(L, L1, 1); + } + else + return luaL_argerror(L, arg+1, "function or level expected"); + if (!lua_getinfo(L1, options, &ar)) + return luaL_argerror(L, arg+2, "invalid option"); + lua_createtable(L, 0, 2); + if (strchr(options, 'S')) { + settabss(L, "source", ar.source); + settabss(L, "short_src", ar.short_src); + settabsi(L, "linedefined", ar.linedefined); + settabsi(L, "lastlinedefined", ar.lastlinedefined); + settabss(L, "what", ar.what); + } + if (strchr(options, 'l')) + settabsi(L, "currentline", ar.currentline); + if (strchr(options, 'u')) + settabsi(L, "nups", ar.nups); + if (strchr(options, 'n')) { + settabss(L, "name", ar.name); + settabss(L, "namewhat", ar.namewhat); + } + if (strchr(options, 'L')) + treatstackoption(L, L1, "activelines"); + if (strchr(options, 'f')) + treatstackoption(L, L1, "func"); + return 1; /* return table */ +} + + +static int db_getlocal (lua_State *L) { + int arg; + lua_State *L1 = getthread(L, &arg); + lua_Debug ar; + const char *name; + if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */ + return luaL_argerror(L, arg+1, "level out of range"); + name = lua_getlocal(L1, &ar, luaL_checkint(L, arg+2)); + if (name) { + lua_xmove(L1, L, 1); + lua_pushstring(L, name); + lua_pushvalue(L, -2); + return 2; + } + else { + lua_pushnil(L); + return 1; + } +} + + +static int db_setlocal (lua_State *L) { + int arg; + lua_State *L1 = getthread(L, &arg); + lua_Debug ar; + if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */ + return luaL_argerror(L, arg+1, "level out of range"); + luaL_checkany(L, arg+3); + lua_settop(L, arg+3); + lua_xmove(L, L1, 1); + lua_pushstring(L, lua_setlocal(L1, &ar, luaL_checkint(L, arg+2))); + return 1; +} + + +static int auxupvalue (lua_State *L, int get) { + const char *name; + int n = luaL_checkint(L, 2); + luaL_checktype(L, 1, LUA_TFUNCTION); + if (lua_iscfunction(L, 1)) return 0; /* cannot touch C upvalues from Lua */ + name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n); + if (name == NULL) return 0; + lua_pushstring(L, name); + lua_insert(L, -(get+1)); + return get + 1; +} + + +static int db_getupvalue (lua_State *L) { + return auxupvalue(L, 1); +} + + +static int db_setupvalue (lua_State *L) { + luaL_checkany(L, 3); + return auxupvalue(L, 0); +} + + + +static const char KEY_HOOK = 'h'; + + +static void hookf (lua_State *L, lua_Debug *ar) { + static const char *const hooknames[] = + {"call", "return", "line", "count", "tail return"}; + lua_pushlightuserdata(L, (void *)&KEY_HOOK); + lua_rawget(L, LUA_REGISTRYINDEX); + lua_pushlightuserdata(L, L); + lua_rawget(L, -2); + if (lua_isfunction(L, -1)) { + lua_pushstring(L, hooknames[(int)ar->event]); + if (ar->currentline >= 0) + lua_pushinteger(L, ar->currentline); + else lua_pushnil(L); + lua_assert(lua_getinfo(L, "lS", ar)); + lua_call(L, 2, 0); + } +} + + +static int makemask (const char *smask, int count) { + int mask = 0; + if (strchr(smask, 'c')) mask |= LUA_MASKCALL; + if (strchr(smask, 'r')) mask |= LUA_MASKRET; + if (strchr(smask, 'l')) mask |= LUA_MASKLINE; + if (count > 0) mask |= LUA_MASKCOUNT; + return mask; +} + + +static char *unmakemask (int mask, char *smask) { + int i = 0; + if (mask & LUA_MASKCALL) smask[i++] = 'c'; + if (mask & LUA_MASKRET) smask[i++] = 'r'; + if (mask & LUA_MASKLINE) smask[i++] = 'l'; + smask[i] = '\0'; + return smask; +} + + +static void gethooktable (lua_State *L) { + lua_pushlightuserdata(L, (void *)&KEY_HOOK); + lua_rawget(L, LUA_REGISTRYINDEX); + if (!lua_istable(L, -1)) { + lua_pop(L, 1); + lua_createtable(L, 0, 1); + lua_pushlightuserdata(L, (void *)&KEY_HOOK); + lua_pushvalue(L, -2); + lua_rawset(L, LUA_REGISTRYINDEX); + } +} + + +static int db_sethook (lua_State *L) { + int arg, mask, count; + lua_Hook func; + lua_State *L1 = getthread(L, &arg); + if (lua_isnoneornil(L, arg+1)) { + lua_settop(L, arg+1); + func = NULL; mask = 0; count = 0; /* turn off hooks */ + } + else { + const char *smask = luaL_checkstring(L, arg+2); + luaL_checktype(L, arg+1, LUA_TFUNCTION); + count = luaL_optint(L, arg+3, 0); + func = hookf; mask = makemask(smask, count); + } + gethooktable(L); + lua_pushlightuserdata(L, L1); + lua_pushvalue(L, arg+1); + lua_rawset(L, -3); /* set new hook */ + lua_pop(L, 1); /* remove hook table */ + lua_sethook(L1, func, mask, count); /* set hooks */ + return 0; +} + + +static int db_gethook (lua_State *L) { + int arg; + lua_State *L1 = getthread(L, &arg); + char buff[5]; + int mask = lua_gethookmask(L1); + lua_Hook hook = lua_gethook(L1); + if (hook != NULL && hook != hookf) /* external hook? */ + lua_pushliteral(L, "external hook"); + else { + gethooktable(L); + lua_pushlightuserdata(L, L1); + lua_rawget(L, -2); /* get hook */ + lua_remove(L, -2); /* remove hook table */ + } + lua_pushstring(L, unmakemask(mask, buff)); + lua_pushinteger(L, lua_gethookcount(L1)); + return 3; +} + + +static int db_debug (lua_State *L) { + for (;;) { + char buffer[250]; + fputs("lua_debug> ", stderr); + if (fgets(buffer, sizeof(buffer), stdin) == 0 || + strcmp(buffer, "cont\n") == 0) + return 0; + if (luaL_loadbuffer(L, buffer, strlen(buffer), "=(debug command)") || + lua_pcall(L, 0, 0, 0)) { + fputs(lua_tostring(L, -1), stderr); + fputs("\n", stderr); + } + lua_settop(L, 0); /* remove eventual returns */ + } +} + + +#define LEVELS1 12 /* size of the first part of the stack */ +#define LEVELS2 10 /* size of the second part of the stack */ + +static int db_errorfb (lua_State *L) { + int level; + int firstpart = 1; /* still before eventual `...' */ + int arg; + lua_State *L1 = getthread(L, &arg); + lua_Debug ar; + if (lua_isnumber(L, arg+2)) { + level = (int)lua_tointeger(L, arg+2); + lua_pop(L, 1); + } + else + level = (L == L1) ? 1 : 0; /* level 0 may be this own function */ + if (lua_gettop(L) == arg) + lua_pushliteral(L, ""); + else if (!lua_isstring(L, arg+1)) return 1; /* message is not a string */ + else lua_pushliteral(L, "\n"); + lua_pushliteral(L, "stack traceback:"); + while (lua_getstack(L1, level++, &ar)) { + if (level > LEVELS1 && firstpart) { + /* no more than `LEVELS2' more levels? */ + if (!lua_getstack(L1, level+LEVELS2, &ar)) + level--; /* keep going */ + else { + lua_pushliteral(L, "\n\t..."); /* too many levels */ + while (lua_getstack(L1, level+LEVELS2, &ar)) /* find last levels */ + level++; + } + firstpart = 0; + continue; + } + lua_pushliteral(L, "\n\t"); + lua_getinfo(L1, "Snl", &ar); + lua_pushfstring(L, "%s:", ar.short_src); + if (ar.currentline > 0) + lua_pushfstring(L, "%d:", ar.currentline); + if (*ar.namewhat != '\0') /* is there a name? */ + lua_pushfstring(L, " in function " LUA_QS, ar.name); + else { + if (*ar.what == 'm') /* main? */ + lua_pushfstring(L, " in main chunk"); + else if (*ar.what == 'C' || *ar.what == 't') + lua_pushliteral(L, " ?"); /* C function or tail call */ + else + lua_pushfstring(L, " in function <%s:%d>", + ar.short_src, ar.linedefined); + } + lua_concat(L, lua_gettop(L) - arg); + } + lua_concat(L, lua_gettop(L) - arg); + return 1; +} + + +static const luaL_Reg dblib[] = { + {"debug", db_debug}, + {"getfenv", db_getfenv}, + {"gethook", db_gethook}, + {"getinfo", db_getinfo}, + {"getlocal", db_getlocal}, + {"getregistry", db_getregistry}, + {"getmetatable", db_getmetatable}, + {"getupvalue", db_getupvalue}, + {"setfenv", db_setfenv}, + {"sethook", db_sethook}, + {"setlocal", db_setlocal}, + {"setmetatable", db_setmetatable}, + {"setupvalue", db_setupvalue}, + {"traceback", db_errorfb}, + {NULL, NULL} +}; + + +LUALIB_API int luaopen_debug (lua_State *L) { + luaL_register(L, LUA_DBLIBNAME, dblib); + return 1; +} + diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/src/ldebug.c b/mod/pub.mod/lua.mod/lua-5.1.4/src/ldebug.c new file mode 100644 index 0000000..50ad3d3 --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/src/ldebug.c @@ -0,0 +1,638 @@ +/* +** $Id: ldebug.c,v 2.29.1.6 2008/05/08 16:56:26 roberto Exp $ +** Debug Interface +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include + + +#define ldebug_c +#define LUA_CORE + +#include "lua.h" + +#include "lapi.h" +#include "lcode.h" +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" +#include "lvm.h" + + + +static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name); + + +static int currentpc (lua_State *L, CallInfo *ci) { + if (!isLua(ci)) return -1; /* function is not a Lua function? */ + if (ci == L->ci) + ci->savedpc = L->savedpc; + return pcRel(ci->savedpc, ci_func(ci)->l.p); +} + + +static int currentline (lua_State *L, CallInfo *ci) { + int pc = currentpc(L, ci); + if (pc < 0) + return -1; /* only active lua functions have current-line information */ + else + return getline(ci_func(ci)->l.p, pc); +} + + +/* +** this function can be called asynchronous (e.g. during a signal) +*/ +LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count) { + if (func == NULL || mask == 0) { /* turn off hooks? */ + mask = 0; + func = NULL; + } + L->hook = func; + L->basehookcount = count; + resethookcount(L); + L->hookmask = cast_byte(mask); + return 1; +} + + +LUA_API lua_Hook lua_gethook (lua_State *L) { + return L->hook; +} + + +LUA_API int lua_gethookmask (lua_State *L) { + return L->hookmask; +} + + +LUA_API int lua_gethookcount (lua_State *L) { + return L->basehookcount; +} + + +LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) { + int status; + CallInfo *ci; + lua_lock(L); + for (ci = L->ci; level > 0 && ci > L->base_ci; ci--) { + level--; + if (f_isLua(ci)) /* Lua function? */ + level -= ci->tailcalls; /* skip lost tail calls */ + } + if (level == 0 && ci > L->base_ci) { /* level found? */ + status = 1; + ar->i_ci = cast_int(ci - L->base_ci); + } + else if (level < 0) { /* level is of a lost tail call? */ + status = 1; + ar->i_ci = 0; + } + else status = 0; /* no such level */ + lua_unlock(L); + return status; +} + + +static Proto *getluaproto (CallInfo *ci) { + return (isLua(ci) ? ci_func(ci)->l.p : NULL); +} + + +static const char *findlocal (lua_State *L, CallInfo *ci, int n) { + const char *name; + Proto *fp = getluaproto(ci); + if (fp && (name = luaF_getlocalname(fp, n, currentpc(L, ci))) != NULL) + return name; /* is a local variable in a Lua function */ + else { + StkId limit = (ci == L->ci) ? L->top : (ci+1)->func; + if (limit - ci->base >= n && n > 0) /* is 'n' inside 'ci' stack? */ + return "(*temporary)"; + else + return NULL; + } +} + + +LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { + CallInfo *ci = L->base_ci + ar->i_ci; + const char *name = findlocal(L, ci, n); + lua_lock(L); + if (name) + luaA_pushobject(L, ci->base + (n - 1)); + lua_unlock(L); + return name; +} + + +LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) { + CallInfo *ci = L->base_ci + ar->i_ci; + const char *name = findlocal(L, ci, n); + lua_lock(L); + if (name) + setobjs2s(L, ci->base + (n - 1), L->top - 1); + L->top--; /* pop value */ + lua_unlock(L); + return name; +} + + +static void funcinfo (lua_Debug *ar, Closure *cl) { + if (cl->c.isC) { + ar->source = "=[C]"; + ar->linedefined = -1; + ar->lastlinedefined = -1; + ar->what = "C"; + } + else { + ar->source = getstr(cl->l.p->source); + ar->linedefined = cl->l.p->linedefined; + ar->lastlinedefined = cl->l.p->lastlinedefined; + ar->what = (ar->linedefined == 0) ? "main" : "Lua"; + } + luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE); +} + + +static void info_tailcall (lua_Debug *ar) { + ar->name = ar->namewhat = ""; + ar->what = "tail"; + ar->lastlinedefined = ar->linedefined = ar->currentline = -1; + ar->source = "=(tail call)"; + luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE); + ar->nups = 0; +} + + +static void collectvalidlines (lua_State *L, Closure *f) { + if (f == NULL || f->c.isC) { + setnilvalue(L->top); + } + else { + Table *t = luaH_new(L, 0, 0); + int *lineinfo = f->l.p->lineinfo; + int i; + for (i=0; il.p->sizelineinfo; i++) + setbvalue(luaH_setnum(L, t, lineinfo[i]), 1); + sethvalue(L, L->top, t); + } + incr_top(L); +} + + +static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, + Closure *f, CallInfo *ci) { + int status = 1; + if (f == NULL) { + info_tailcall(ar); + return status; + } + for (; *what; what++) { + switch (*what) { + case 'S': { + funcinfo(ar, f); + break; + } + case 'l': { + ar->currentline = (ci) ? currentline(L, ci) : -1; + break; + } + case 'u': { + ar->nups = f->c.nupvalues; + break; + } + case 'n': { + ar->namewhat = (ci) ? getfuncname(L, ci, &ar->name) : NULL; + if (ar->namewhat == NULL) { + ar->namewhat = ""; /* not found */ + ar->name = NULL; + } + break; + } + case 'L': + case 'f': /* handled by lua_getinfo */ + break; + default: status = 0; /* invalid option */ + } + } + return status; +} + + +LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { + int status; + Closure *f = NULL; + CallInfo *ci = NULL; + lua_lock(L); + if (*what == '>') { + StkId func = L->top - 1; + luai_apicheck(L, ttisfunction(func)); + what++; /* skip the '>' */ + f = clvalue(func); + L->top--; /* pop function */ + } + else if (ar->i_ci != 0) { /* no tail call? */ + ci = L->base_ci + ar->i_ci; + lua_assert(ttisfunction(ci->func)); + f = clvalue(ci->func); + } + status = auxgetinfo(L, what, ar, f, ci); + if (strchr(what, 'f')) { + if (f == NULL) setnilvalue(L->top); + else setclvalue(L, L->top, f); + incr_top(L); + } + if (strchr(what, 'L')) + collectvalidlines(L, f); + lua_unlock(L); + return status; +} + + +/* +** {====================================================== +** Symbolic Execution and code checker +** ======================================================= +*/ + +#define check(x) if (!(x)) return 0; + +#define checkjump(pt,pc) check(0 <= pc && pc < pt->sizecode) + +#define checkreg(pt,reg) check((reg) < (pt)->maxstacksize) + + + +static int precheck (const Proto *pt) { + check(pt->maxstacksize <= MAXSTACK); + check(pt->numparams+(pt->is_vararg & VARARG_HASARG) <= pt->maxstacksize); + check(!(pt->is_vararg & VARARG_NEEDSARG) || + (pt->is_vararg & VARARG_HASARG)); + check(pt->sizeupvalues <= pt->nups); + check(pt->sizelineinfo == pt->sizecode || pt->sizelineinfo == 0); + check(pt->sizecode > 0 && GET_OPCODE(pt->code[pt->sizecode-1]) == OP_RETURN); + return 1; +} + + +#define checkopenop(pt,pc) luaG_checkopenop((pt)->code[(pc)+1]) + +int luaG_checkopenop (Instruction i) { + switch (GET_OPCODE(i)) { + case OP_CALL: + case OP_TAILCALL: + case OP_RETURN: + case OP_SETLIST: { + check(GETARG_B(i) == 0); + return 1; + } + default: return 0; /* invalid instruction after an open call */ + } +} + + +static int checkArgMode (const Proto *pt, int r, enum OpArgMask mode) { + switch (mode) { + case OpArgN: check(r == 0); break; + case OpArgU: break; + case OpArgR: checkreg(pt, r); break; + case OpArgK: + check(ISK(r) ? INDEXK(r) < pt->sizek : r < pt->maxstacksize); + break; + } + return 1; +} + + +static Instruction symbexec (const Proto *pt, int lastpc, int reg) { + int pc; + int last; /* stores position of last instruction that changed `reg' */ + last = pt->sizecode-1; /* points to final return (a `neutral' instruction) */ + check(precheck(pt)); + for (pc = 0; pc < lastpc; pc++) { + Instruction i = pt->code[pc]; + OpCode op = GET_OPCODE(i); + int a = GETARG_A(i); + int b = 0; + int c = 0; + check(op < NUM_OPCODES); + checkreg(pt, a); + switch (getOpMode(op)) { + case iABC: { + b = GETARG_B(i); + c = GETARG_C(i); + check(checkArgMode(pt, b, getBMode(op))); + check(checkArgMode(pt, c, getCMode(op))); + break; + } + case iABx: { + b = GETARG_Bx(i); + if (getBMode(op) == OpArgK) check(b < pt->sizek); + break; + } + case iAsBx: { + b = GETARG_sBx(i); + if (getBMode(op) == OpArgR) { + int dest = pc+1+b; + check(0 <= dest && dest < pt->sizecode); + if (dest > 0) { + int j; + /* check that it does not jump to a setlist count; this + is tricky, because the count from a previous setlist may + have the same value of an invalid setlist; so, we must + go all the way back to the first of them (if any) */ + for (j = 0; j < dest; j++) { + Instruction d = pt->code[dest-1-j]; + if (!(GET_OPCODE(d) == OP_SETLIST && GETARG_C(d) == 0)) break; + } + /* if 'j' is even, previous value is not a setlist (even if + it looks like one) */ + check((j&1) == 0); + } + } + break; + } + } + if (testAMode(op)) { + if (a == reg) last = pc; /* change register `a' */ + } + if (testTMode(op)) { + check(pc+2 < pt->sizecode); /* check skip */ + check(GET_OPCODE(pt->code[pc+1]) == OP_JMP); + } + switch (op) { + case OP_LOADBOOL: { + if (c == 1) { /* does it jump? */ + check(pc+2 < pt->sizecode); /* check its jump */ + check(GET_OPCODE(pt->code[pc+1]) != OP_SETLIST || + GETARG_C(pt->code[pc+1]) != 0); + } + break; + } + case OP_LOADNIL: { + if (a <= reg && reg <= b) + last = pc; /* set registers from `a' to `b' */ + break; + } + case OP_GETUPVAL: + case OP_SETUPVAL: { + check(b < pt->nups); + break; + } + case OP_GETGLOBAL: + case OP_SETGLOBAL: { + check(ttisstring(&pt->k[b])); + break; + } + case OP_SELF: { + checkreg(pt, a+1); + if (reg == a+1) last = pc; + break; + } + case OP_CONCAT: { + check(b < c); /* at least two operands */ + break; + } + case OP_TFORLOOP: { + check(c >= 1); /* at least one result (control variable) */ + checkreg(pt, a+2+c); /* space for results */ + if (reg >= a+2) last = pc; /* affect all regs above its base */ + break; + } + case OP_FORLOOP: + case OP_FORPREP: + checkreg(pt, a+3); + /* go through */ + case OP_JMP: { + int dest = pc+1+b; + /* not full check and jump is forward and do not skip `lastpc'? */ + if (reg != NO_REG && pc < dest && dest <= lastpc) + pc += b; /* do the jump */ + break; + } + case OP_CALL: + case OP_TAILCALL: { + if (b != 0) { + checkreg(pt, a+b-1); + } + c--; /* c = num. returns */ + if (c == LUA_MULTRET) { + check(checkopenop(pt, pc)); + } + else if (c != 0) + checkreg(pt, a+c-1); + if (reg >= a) last = pc; /* affect all registers above base */ + break; + } + case OP_RETURN: { + b--; /* b = num. returns */ + if (b > 0) checkreg(pt, a+b-1); + break; + } + case OP_SETLIST: { + if (b > 0) checkreg(pt, a + b); + if (c == 0) { + pc++; + check(pc < pt->sizecode - 1); + } + break; + } + case OP_CLOSURE: { + int nup, j; + check(b < pt->sizep); + nup = pt->p[b]->nups; + check(pc + nup < pt->sizecode); + for (j = 1; j <= nup; j++) { + OpCode op1 = GET_OPCODE(pt->code[pc + j]); + check(op1 == OP_GETUPVAL || op1 == OP_MOVE); + } + if (reg != NO_REG) /* tracing? */ + pc += nup; /* do not 'execute' these pseudo-instructions */ + break; + } + case OP_VARARG: { + check((pt->is_vararg & VARARG_ISVARARG) && + !(pt->is_vararg & VARARG_NEEDSARG)); + b--; + if (b == LUA_MULTRET) check(checkopenop(pt, pc)); + checkreg(pt, a+b-1); + break; + } + default: break; + } + } + return pt->code[last]; +} + +#undef check +#undef checkjump +#undef checkreg + +/* }====================================================== */ + + +int luaG_checkcode (const Proto *pt) { + return (symbexec(pt, pt->sizecode, NO_REG) != 0); +} + + +static const char *kname (Proto *p, int c) { + if (ISK(c) && ttisstring(&p->k[INDEXK(c)])) + return svalue(&p->k[INDEXK(c)]); + else + return "?"; +} + + +static const char *getobjname (lua_State *L, CallInfo *ci, int stackpos, + const char **name) { + if (isLua(ci)) { /* a Lua function? */ + Proto *p = ci_func(ci)->l.p; + int pc = currentpc(L, ci); + Instruction i; + *name = luaF_getlocalname(p, stackpos+1, pc); + if (*name) /* is a local? */ + return "local"; + i = symbexec(p, pc, stackpos); /* try symbolic execution */ + lua_assert(pc != -1); + switch (GET_OPCODE(i)) { + case OP_GETGLOBAL: { + int g = GETARG_Bx(i); /* global index */ + lua_assert(ttisstring(&p->k[g])); + *name = svalue(&p->k[g]); + return "global"; + } + case OP_MOVE: { + int a = GETARG_A(i); + int b = GETARG_B(i); /* move from `b' to `a' */ + if (b < a) + return getobjname(L, ci, b, name); /* get name for `b' */ + break; + } + case OP_GETTABLE: { + int k = GETARG_C(i); /* key index */ + *name = kname(p, k); + return "field"; + } + case OP_GETUPVAL: { + int u = GETARG_B(i); /* upvalue index */ + *name = p->upvalues ? getstr(p->upvalues[u]) : "?"; + return "upvalue"; + } + case OP_SELF: { + int k = GETARG_C(i); /* key index */ + *name = kname(p, k); + return "method"; + } + default: break; + } + } + return NULL; /* no useful name found */ +} + + +static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) { + Instruction i; + if ((isLua(ci) && ci->tailcalls > 0) || !isLua(ci - 1)) + return NULL; /* calling function is not Lua (or is unknown) */ + ci--; /* calling function */ + i = ci_func(ci)->l.p->code[currentpc(L, ci)]; + if (GET_OPCODE(i) == OP_CALL || GET_OPCODE(i) == OP_TAILCALL || + GET_OPCODE(i) == OP_TFORLOOP) + return getobjname(L, ci, GETARG_A(i), name); + else + return NULL; /* no useful name can be found */ +} + + +/* only ANSI way to check whether a pointer points to an array */ +static int isinstack (CallInfo *ci, const TValue *o) { + StkId p; + for (p = ci->base; p < ci->top; p++) + if (o == p) return 1; + return 0; +} + + +void luaG_typeerror (lua_State *L, const TValue *o, const char *op) { + const char *name = NULL; + const char *t = luaT_typenames[ttype(o)]; + const char *kind = (isinstack(L->ci, o)) ? + getobjname(L, L->ci, cast_int(o - L->base), &name) : + NULL; + if (kind) + luaG_runerror(L, "attempt to %s %s " LUA_QS " (a %s value)", + op, kind, name, t); + else + luaG_runerror(L, "attempt to %s a %s value", op, t); +} + + +void luaG_concaterror (lua_State *L, StkId p1, StkId p2) { + if (ttisstring(p1) || ttisnumber(p1)) p1 = p2; + lua_assert(!ttisstring(p1) && !ttisnumber(p1)); + luaG_typeerror(L, p1, "concatenate"); +} + + +void luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) { + TValue temp; + if (luaV_tonumber(p1, &temp) == NULL) + p2 = p1; /* first operand is wrong */ + luaG_typeerror(L, p2, "perform arithmetic on"); +} + + +int luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) { + const char *t1 = luaT_typenames[ttype(p1)]; + const char *t2 = luaT_typenames[ttype(p2)]; + if (t1[2] == t2[2]) + luaG_runerror(L, "attempt to compare two %s values", t1); + else + luaG_runerror(L, "attempt to compare %s with %s", t1, t2); + return 0; +} + + +static void addinfo (lua_State *L, const char *msg) { + CallInfo *ci = L->ci; + if (isLua(ci)) { /* is Lua code? */ + char buff[LUA_IDSIZE]; /* add file:line information */ + int line = currentline(L, ci); + luaO_chunkid(buff, getstr(getluaproto(ci)->source), LUA_IDSIZE); + luaO_pushfstring(L, "%s:%d: %s", buff, line, msg); + } +} + + +void luaG_errormsg (lua_State *L) { + if (L->errfunc != 0) { /* is there an error handling function? */ + StkId errfunc = restorestack(L, L->errfunc); + if (!ttisfunction(errfunc)) luaD_throw(L, LUA_ERRERR); + setobjs2s(L, L->top, L->top - 1); /* move argument */ + setobjs2s(L, L->top - 1, errfunc); /* push function */ + incr_top(L); + luaD_call(L, L->top - 2, 1); /* call it */ + } + luaD_throw(L, LUA_ERRRUN); +} + + +void luaG_runerror (lua_State *L, const char *fmt, ...) { + va_list argp; + va_start(argp, fmt); + addinfo(L, luaO_pushvfstring(L, fmt, argp)); + va_end(argp); + luaG_errormsg(L); +} + diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/src/ldebug.h b/mod/pub.mod/lua.mod/lua-5.1.4/src/ldebug.h new file mode 100644 index 0000000..ba28a97 --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/src/ldebug.h @@ -0,0 +1,33 @@ +/* +** $Id: ldebug.h,v 2.3.1.1 2007/12/27 13:02:25 roberto Exp $ +** Auxiliary functions from Debug Interface module +** See Copyright Notice in lua.h +*/ + +#ifndef ldebug_h +#define ldebug_h + + +#include "lstate.h" + + +#define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1) + +#define getline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : 0) + +#define resethookcount(L) (L->hookcount = L->basehookcount) + + +LUAI_FUNC void luaG_typeerror (lua_State *L, const TValue *o, + const char *opname); +LUAI_FUNC void luaG_concaterror (lua_State *L, StkId p1, StkId p2); +LUAI_FUNC void luaG_aritherror (lua_State *L, const TValue *p1, + const TValue *p2); +LUAI_FUNC int luaG_ordererror (lua_State *L, const TValue *p1, + const TValue *p2); +LUAI_FUNC void luaG_runerror (lua_State *L, const char *fmt, ...); +LUAI_FUNC void luaG_errormsg (lua_State *L); +LUAI_FUNC int luaG_checkcode (const Proto *pt); +LUAI_FUNC int luaG_checkopenop (Instruction i); + +#endif diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/src/ldo.c b/mod/pub.mod/lua.mod/lua-5.1.4/src/ldo.c new file mode 100644 index 0000000..8de05f7 --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/src/ldo.c @@ -0,0 +1,518 @@ +/* +** $Id: ldo.c,v 2.38.1.3 2008/01/18 22:31:22 roberto Exp $ +** Stack and Call structure of Lua +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include + +#define ldo_c +#define LUA_CORE + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lparser.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" +#include "lundump.h" +#include "lvm.h" +#include "lzio.h" + + + + +/* +** {====================================================== +** Error-recovery functions +** ======================================================= +*/ + + +/* chain list of long jump buffers */ +struct lua_longjmp { + struct lua_longjmp *previous; + luai_jmpbuf b; + volatile int status; /* error code */ +}; + + +void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop) { + switch (errcode) { + case LUA_ERRMEM: { + setsvalue2s(L, oldtop, luaS_newliteral(L, MEMERRMSG)); + break; + } + case LUA_ERRERR: { + setsvalue2s(L, oldtop, luaS_newliteral(L, "error in error handling")); + break; + } + case LUA_ERRSYNTAX: + case LUA_ERRRUN: { + setobjs2s(L, oldtop, L->top - 1); /* error message on current top */ + break; + } + } + L->top = oldtop + 1; +} + + +static void restore_stack_limit (lua_State *L) { + lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1); + if (L->size_ci > LUAI_MAXCALLS) { /* there was an overflow? */ + int inuse = cast_int(L->ci - L->base_ci); + if (inuse + 1 < LUAI_MAXCALLS) /* can `undo' overflow? */ + luaD_reallocCI(L, LUAI_MAXCALLS); + } +} + + +static void resetstack (lua_State *L, int status) { + L->ci = L->base_ci; + L->base = L->ci->base; + luaF_close(L, L->base); /* close eventual pending closures */ + luaD_seterrorobj(L, status, L->base); + L->nCcalls = L->baseCcalls; + L->allowhook = 1; + restore_stack_limit(L); + L->errfunc = 0; + L->errorJmp = NULL; +} + + +void luaD_throw (lua_State *L, int errcode) { + if (L->errorJmp) { + L->errorJmp->status = errcode; + LUAI_THROW(L, L->errorJmp); + } + else { + L->status = cast_byte(errcode); + if (G(L)->panic) { + resetstack(L, errcode); + lua_unlock(L); + G(L)->panic(L); + } + exit(EXIT_FAILURE); + } +} + + +int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { + struct lua_longjmp lj; + lj.status = 0; + lj.previous = L->errorJmp; /* chain new error handler */ + L->errorJmp = &lj; + LUAI_TRY(L, &lj, + (*f)(L, ud); + ); + L->errorJmp = lj.previous; /* restore old error handler */ + return lj.status; +} + +/* }====================================================== */ + + +static void correctstack (lua_State *L, TValue *oldstack) { + CallInfo *ci; + GCObject *up; + L->top = (L->top - oldstack) + L->stack; + for (up = L->openupval; up != NULL; up = up->gch.next) + gco2uv(up)->v = (gco2uv(up)->v - oldstack) + L->stack; + for (ci = L->base_ci; ci <= L->ci; ci++) { + ci->top = (ci->top - oldstack) + L->stack; + ci->base = (ci->base - oldstack) + L->stack; + ci->func = (ci->func - oldstack) + L->stack; + } + L->base = (L->base - oldstack) + L->stack; +} + + +void luaD_reallocstack (lua_State *L, int newsize) { + TValue *oldstack = L->stack; + int realsize = newsize + 1 + EXTRA_STACK; + lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1); + luaM_reallocvector(L, L->stack, L->stacksize, realsize, TValue); + L->stacksize = realsize; + L->stack_last = L->stack+newsize; + correctstack(L, oldstack); +} + + +void luaD_reallocCI (lua_State *L, int newsize) { + CallInfo *oldci = L->base_ci; + luaM_reallocvector(L, L->base_ci, L->size_ci, newsize, CallInfo); + L->size_ci = newsize; + L->ci = (L->ci - oldci) + L->base_ci; + L->end_ci = L->base_ci + L->size_ci - 1; +} + + +void luaD_growstack (lua_State *L, int n) { + if (n <= L->stacksize) /* double size is enough? */ + luaD_reallocstack(L, 2*L->stacksize); + else + luaD_reallocstack(L, L->stacksize + n); +} + + +static CallInfo *growCI (lua_State *L) { + if (L->size_ci > LUAI_MAXCALLS) /* overflow while handling overflow? */ + luaD_throw(L, LUA_ERRERR); + else { + luaD_reallocCI(L, 2*L->size_ci); + if (L->size_ci > LUAI_MAXCALLS) + luaG_runerror(L, "stack overflow"); + } + return ++L->ci; +} + + +void luaD_callhook (lua_State *L, int event, int line) { + lua_Hook hook = L->hook; + if (hook && L->allowhook) { + ptrdiff_t top = savestack(L, L->top); + ptrdiff_t ci_top = savestack(L, L->ci->top); + lua_Debug ar; + ar.event = event; + ar.currentline = line; + if (event == LUA_HOOKTAILRET) + ar.i_ci = 0; /* tail call; no debug information about it */ + else + ar.i_ci = cast_int(L->ci - L->base_ci); + luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ + L->ci->top = L->top + LUA_MINSTACK; + lua_assert(L->ci->top <= L->stack_last); + L->allowhook = 0; /* cannot call hooks inside a hook */ + lua_unlock(L); + (*hook)(L, &ar); + lua_lock(L); + lua_assert(!L->allowhook); + L->allowhook = 1; + L->ci->top = restorestack(L, ci_top); + L->top = restorestack(L, top); + } +} + + +static StkId adjust_varargs (lua_State *L, Proto *p, int actual) { + int i; + int nfixargs = p->numparams; + Table *htab = NULL; + StkId base, fixed; + for (; actual < nfixargs; ++actual) + setnilvalue(L->top++); +#if defined(LUA_COMPAT_VARARG) + if (p->is_vararg & VARARG_NEEDSARG) { /* compat. with old-style vararg? */ + int nvar = actual - nfixargs; /* number of extra arguments */ + lua_assert(p->is_vararg & VARARG_HASARG); + luaC_checkGC(L); + htab = luaH_new(L, nvar, 1); /* create `arg' table */ + for (i=0; itop - nvar + i); + /* store counter in field `n' */ + setnvalue(luaH_setstr(L, htab, luaS_newliteral(L, "n")), cast_num(nvar)); + } +#endif + /* move fixed parameters to final position */ + fixed = L->top - actual; /* first fixed argument */ + base = L->top; /* final position of first argument */ + for (i=0; itop++, fixed+i); + setnilvalue(fixed+i); + } + /* add `arg' parameter */ + if (htab) { + sethvalue(L, L->top++, htab); + lua_assert(iswhite(obj2gco(htab))); + } + return base; +} + + +static StkId tryfuncTM (lua_State *L, StkId func) { + const TValue *tm = luaT_gettmbyobj(L, func, TM_CALL); + StkId p; + ptrdiff_t funcr = savestack(L, func); + if (!ttisfunction(tm)) + luaG_typeerror(L, func, "call"); + /* Open a hole inside the stack at `func' */ + for (p = L->top; p > func; p--) setobjs2s(L, p, p-1); + incr_top(L); + func = restorestack(L, funcr); /* previous call may change stack */ + setobj2s(L, func, tm); /* tag method is the new function to be called */ + return func; +} + + + +#define inc_ci(L) \ + ((L->ci == L->end_ci) ? growCI(L) : \ + (condhardstacktests(luaD_reallocCI(L, L->size_ci)), ++L->ci)) + + +int luaD_precall (lua_State *L, StkId func, int nresults) { + LClosure *cl; + ptrdiff_t funcr; + if (!ttisfunction(func)) /* `func' is not a function? */ + func = tryfuncTM(L, func); /* check the `function' tag method */ + funcr = savestack(L, func); + cl = &clvalue(func)->l; + L->ci->savedpc = L->savedpc; + if (!cl->isC) { /* Lua function? prepare its call */ + CallInfo *ci; + StkId st, base; + Proto *p = cl->p; + luaD_checkstack(L, p->maxstacksize); + func = restorestack(L, funcr); + if (!p->is_vararg) { /* no varargs? */ + base = func + 1; + if (L->top > base + p->numparams) + L->top = base + p->numparams; + } + else { /* vararg function */ + int nargs = cast_int(L->top - func) - 1; + base = adjust_varargs(L, p, nargs); + func = restorestack(L, funcr); /* previous call may change the stack */ + } + ci = inc_ci(L); /* now `enter' new function */ + ci->func = func; + L->base = ci->base = base; + ci->top = L->base + p->maxstacksize; + lua_assert(ci->top <= L->stack_last); + L->savedpc = p->code; /* starting point */ + ci->tailcalls = 0; + ci->nresults = nresults; + for (st = L->top; st < ci->top; st++) + setnilvalue(st); + L->top = ci->top; + if (L->hookmask & LUA_MASKCALL) { + L->savedpc++; /* hooks assume 'pc' is already incremented */ + luaD_callhook(L, LUA_HOOKCALL, -1); + L->savedpc--; /* correct 'pc' */ + } + return PCRLUA; + } + else { /* if is a C function, call it */ + CallInfo *ci; + int n; + luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ + ci = inc_ci(L); /* now `enter' new function */ + ci->func = restorestack(L, funcr); + L->base = ci->base = ci->func + 1; + ci->top = L->top + LUA_MINSTACK; + lua_assert(ci->top <= L->stack_last); + ci->nresults = nresults; + if (L->hookmask & LUA_MASKCALL) + luaD_callhook(L, LUA_HOOKCALL, -1); + lua_unlock(L); + n = (*curr_func(L)->c.f)(L); /* do the actual call */ + lua_lock(L); + if (n < 0) /* yielding? */ + return PCRYIELD; + else { + luaD_poscall(L, L->top - n); + return PCRC; + } + } +} + + +static StkId callrethooks (lua_State *L, StkId firstResult) { + ptrdiff_t fr = savestack(L, firstResult); /* next call may change stack */ + luaD_callhook(L, LUA_HOOKRET, -1); + if (f_isLua(L->ci)) { /* Lua function? */ + while ((L->hookmask & LUA_MASKRET) && L->ci->tailcalls--) /* tail calls */ + luaD_callhook(L, LUA_HOOKTAILRET, -1); + } + return restorestack(L, fr); +} + + +int luaD_poscall (lua_State *L, StkId firstResult) { + StkId res; + int wanted, i; + CallInfo *ci; + if (L->hookmask & LUA_MASKRET) + firstResult = callrethooks(L, firstResult); + ci = L->ci--; + res = ci->func; /* res == final position of 1st result */ + wanted = ci->nresults; + L->base = (ci - 1)->base; /* restore base */ + L->savedpc = (ci - 1)->savedpc; /* restore savedpc */ + /* move results to correct place */ + for (i = wanted; i != 0 && firstResult < L->top; i--) + setobjs2s(L, res++, firstResult++); + while (i-- > 0) + setnilvalue(res++); + L->top = res; + return (wanted - LUA_MULTRET); /* 0 iff wanted == LUA_MULTRET */ +} + + +/* +** Call a function (C or Lua). The function to be called is at *func. +** The arguments are on the stack, right after the function. +** When returns, all the results are on the stack, starting at the original +** function position. +*/ +void luaD_call (lua_State *L, StkId func, int nResults) { + if (++L->nCcalls >= LUAI_MAXCCALLS) { + if (L->nCcalls == LUAI_MAXCCALLS) + luaG_runerror(L, "C stack overflow"); + else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3))) + luaD_throw(L, LUA_ERRERR); /* error while handing stack error */ + } + if (luaD_precall(L, func, nResults) == PCRLUA) /* is a Lua function? */ + luaV_execute(L, 1); /* call it */ + L->nCcalls--; + luaC_checkGC(L); +} + + +static void resume (lua_State *L, void *ud) { + StkId firstArg = cast(StkId, ud); + CallInfo *ci = L->ci; + if (L->status == 0) { /* start coroutine? */ + lua_assert(ci == L->base_ci && firstArg > L->base); + if (luaD_precall(L, firstArg - 1, LUA_MULTRET) != PCRLUA) + return; + } + else { /* resuming from previous yield */ + lua_assert(L->status == LUA_YIELD); + L->status = 0; + if (!f_isLua(ci)) { /* `common' yield? */ + /* finish interrupted execution of `OP_CALL' */ + lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL || + GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_TAILCALL); + if (luaD_poscall(L, firstArg)) /* complete it... */ + L->top = L->ci->top; /* and correct top if not multiple results */ + } + else /* yielded inside a hook: just continue its execution */ + L->base = L->ci->base; + } + luaV_execute(L, cast_int(L->ci - L->base_ci)); +} + + +static int resume_error (lua_State *L, const char *msg) { + L->top = L->ci->base; + setsvalue2s(L, L->top, luaS_new(L, msg)); + incr_top(L); + lua_unlock(L); + return LUA_ERRRUN; +} + + +LUA_API int lua_resume (lua_State *L, int nargs) { + int status; + lua_lock(L); + if (L->status != LUA_YIELD && (L->status != 0 || L->ci != L->base_ci)) + return resume_error(L, "cannot resume non-suspended coroutine"); + if (L->nCcalls >= LUAI_MAXCCALLS) + return resume_error(L, "C stack overflow"); + luai_userstateresume(L, nargs); + lua_assert(L->errfunc == 0); + L->baseCcalls = ++L->nCcalls; + status = luaD_rawrunprotected(L, resume, L->top - nargs); + if (status != 0) { /* error? */ + L->status = cast_byte(status); /* mark thread as `dead' */ + luaD_seterrorobj(L, status, L->top); + L->ci->top = L->top; + } + else { + lua_assert(L->nCcalls == L->baseCcalls); + status = L->status; + } + --L->nCcalls; + lua_unlock(L); + return status; +} + + +LUA_API int lua_yield (lua_State *L, int nresults) { + luai_userstateyield(L, nresults); + lua_lock(L); + if (L->nCcalls > L->baseCcalls) + luaG_runerror(L, "attempt to yield across metamethod/C-call boundary"); + L->base = L->top - nresults; /* protect stack slots below */ + L->status = LUA_YIELD; + lua_unlock(L); + return -1; +} + + +int luaD_pcall (lua_State *L, Pfunc func, void *u, + ptrdiff_t old_top, ptrdiff_t ef) { + int status; + unsigned short oldnCcalls = L->nCcalls; + ptrdiff_t old_ci = saveci(L, L->ci); + lu_byte old_allowhooks = L->allowhook; + ptrdiff_t old_errfunc = L->errfunc; + L->errfunc = ef; + status = luaD_rawrunprotected(L, func, u); + if (status != 0) { /* an error occurred? */ + StkId oldtop = restorestack(L, old_top); + luaF_close(L, oldtop); /* close eventual pending closures */ + luaD_seterrorobj(L, status, oldtop); + L->nCcalls = oldnCcalls; + L->ci = restoreci(L, old_ci); + L->base = L->ci->base; + L->savedpc = L->ci->savedpc; + L->allowhook = old_allowhooks; + restore_stack_limit(L); + } + L->errfunc = old_errfunc; + return status; +} + + + +/* +** Execute a protected parser. +*/ +struct SParser { /* data to `f_parser' */ + ZIO *z; + Mbuffer buff; /* buffer to be used by the scanner */ + const char *name; +}; + +static void f_parser (lua_State *L, void *ud) { + int i; + Proto *tf; + Closure *cl; + struct SParser *p = cast(struct SParser *, ud); + int c = luaZ_lookahead(p->z); + luaC_checkGC(L); + tf = ((c == LUA_SIGNATURE[0]) ? luaU_undump : luaY_parser)(L, p->z, + &p->buff, p->name); + cl = luaF_newLclosure(L, tf->nups, hvalue(gt(L))); + cl->l.p = tf; + for (i = 0; i < tf->nups; i++) /* initialize eventual upvalues */ + cl->l.upvals[i] = luaF_newupval(L); + setclvalue(L, L->top, cl); + incr_top(L); +} + + +int luaD_protectedparser (lua_State *L, ZIO *z, const char *name) { + struct SParser p; + int status; + p.z = z; p.name = name; + luaZ_initbuffer(L, &p.buff); + status = luaD_pcall(L, f_parser, &p, savestack(L, L->top), L->errfunc); + luaZ_freebuffer(L, &p.buff); + return status; +} + + diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/src/ldo.h b/mod/pub.mod/lua.mod/lua-5.1.4/src/ldo.h new file mode 100644 index 0000000..98fddac --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/src/ldo.h @@ -0,0 +1,57 @@ +/* +** $Id: ldo.h,v 2.7.1.1 2007/12/27 13:02:25 roberto Exp $ +** Stack and Call structure of Lua +** See Copyright Notice in lua.h +*/ + +#ifndef ldo_h +#define ldo_h + + +#include "lobject.h" +#include "lstate.h" +#include "lzio.h" + + +#define luaD_checkstack(L,n) \ + if ((char *)L->stack_last - (char *)L->top <= (n)*(int)sizeof(TValue)) \ + luaD_growstack(L, n); \ + else condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1)); + + +#define incr_top(L) {luaD_checkstack(L,1); L->top++;} + +#define savestack(L,p) ((char *)(p) - (char *)L->stack) +#define restorestack(L,n) ((TValue *)((char *)L->stack + (n))) + +#define saveci(L,p) ((char *)(p) - (char *)L->base_ci) +#define restoreci(L,n) ((CallInfo *)((char *)L->base_ci + (n))) + + +/* results from luaD_precall */ +#define PCRLUA 0 /* initiated a call to a Lua function */ +#define PCRC 1 /* did a call to a C function */ +#define PCRYIELD 2 /* C funtion yielded */ + + +/* type of protected functions, to be ran by `runprotected' */ +typedef void (*Pfunc) (lua_State *L, void *ud); + +LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name); +LUAI_FUNC void luaD_callhook (lua_State *L, int event, int line); +LUAI_FUNC int luaD_precall (lua_State *L, StkId func, int nresults); +LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults); +LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u, + ptrdiff_t oldtop, ptrdiff_t ef); +LUAI_FUNC int luaD_poscall (lua_State *L, StkId firstResult); +LUAI_FUNC void luaD_reallocCI (lua_State *L, int newsize); +LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize); +LUAI_FUNC void luaD_growstack (lua_State *L, int n); + +LUAI_FUNC void luaD_throw (lua_State *L, int errcode); +LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud); + +LUAI_FUNC void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop); + +#endif + diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/src/ldump.c b/mod/pub.mod/lua.mod/lua-5.1.4/src/ldump.c new file mode 100644 index 0000000..c9d3d48 --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/src/ldump.c @@ -0,0 +1,164 @@ +/* +** $Id: ldump.c,v 2.8.1.1 2007/12/27 13:02:25 roberto Exp $ +** save precompiled Lua chunks +** See Copyright Notice in lua.h +*/ + +#include + +#define ldump_c +#define LUA_CORE + +#include "lua.h" + +#include "lobject.h" +#include "lstate.h" +#include "lundump.h" + +typedef struct { + lua_State* L; + lua_Writer writer; + void* data; + int strip; + int status; +} DumpState; + +#define DumpMem(b,n,size,D) DumpBlock(b,(n)*(size),D) +#define DumpVar(x,D) DumpMem(&x,1,sizeof(x),D) + +static void DumpBlock(const void* b, size_t size, DumpState* D) +{ + if (D->status==0) + { + lua_unlock(D->L); + D->status=(*D->writer)(D->L,b,size,D->data); + lua_lock(D->L); + } +} + +static void DumpChar(int y, DumpState* D) +{ + char x=(char)y; + DumpVar(x,D); +} + +static void DumpInt(int x, DumpState* D) +{ + DumpVar(x,D); +} + +static void DumpNumber(lua_Number x, DumpState* D) +{ + DumpVar(x,D); +} + +static void DumpVector(const void* b, int n, size_t size, DumpState* D) +{ + DumpInt(n,D); + DumpMem(b,n,size,D); +} + +static void DumpString(const TString* s, DumpState* D) +{ + if (s==NULL || getstr(s)==NULL) + { + size_t size=0; + DumpVar(size,D); + } + else + { + size_t size=s->tsv.len+1; /* include trailing '\0' */ + DumpVar(size,D); + DumpBlock(getstr(s),size,D); + } +} + +#define DumpCode(f,D) DumpVector(f->code,f->sizecode,sizeof(Instruction),D) + +static void DumpFunction(const Proto* f, const TString* p, DumpState* D); + +static void DumpConstants(const Proto* f, DumpState* D) +{ + int i,n=f->sizek; + DumpInt(n,D); + for (i=0; ik[i]; + DumpChar(ttype(o),D); + switch (ttype(o)) + { + case LUA_TNIL: + break; + case LUA_TBOOLEAN: + DumpChar(bvalue(o),D); + break; + case LUA_TNUMBER: + DumpNumber(nvalue(o),D); + break; + case LUA_TSTRING: + DumpString(rawtsvalue(o),D); + break; + default: + lua_assert(0); /* cannot happen */ + break; + } + } + n=f->sizep; + DumpInt(n,D); + for (i=0; ip[i],f->source,D); +} + +static void DumpDebug(const Proto* f, DumpState* D) +{ + int i,n; + n= (D->strip) ? 0 : f->sizelineinfo; + DumpVector(f->lineinfo,n,sizeof(int),D); + n= (D->strip) ? 0 : f->sizelocvars; + DumpInt(n,D); + for (i=0; ilocvars[i].varname,D); + DumpInt(f->locvars[i].startpc,D); + DumpInt(f->locvars[i].endpc,D); + } + n= (D->strip) ? 0 : f->sizeupvalues; + DumpInt(n,D); + for (i=0; iupvalues[i],D); +} + +static void DumpFunction(const Proto* f, const TString* p, DumpState* D) +{ + DumpString((f->source==p || D->strip) ? NULL : f->source,D); + DumpInt(f->linedefined,D); + DumpInt(f->lastlinedefined,D); + DumpChar(f->nups,D); + DumpChar(f->numparams,D); + DumpChar(f->is_vararg,D); + DumpChar(f->maxstacksize,D); + DumpCode(f,D); + DumpConstants(f,D); + DumpDebug(f,D); +} + +static void DumpHeader(DumpState* D) +{ + char h[LUAC_HEADERSIZE]; + luaU_header(h); + DumpBlock(h,LUAC_HEADERSIZE,D); +} + +/* +** dump Lua function as precompiled chunk +*/ +int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip) +{ + DumpState D; + D.L=L; + D.writer=w; + D.data=data; + D.strip=strip; + D.status=0; + DumpHeader(&D); + DumpFunction(f,NULL,&D); + return D.status; +} diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/src/lfunc.c b/mod/pub.mod/lua.mod/lua-5.1.4/src/lfunc.c new file mode 100644 index 0000000..813e88f --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/src/lfunc.c @@ -0,0 +1,174 @@ +/* +** $Id: lfunc.c,v 2.12.1.2 2007/12/28 14:58:43 roberto Exp $ +** Auxiliary functions to manipulate prototypes and closures +** See Copyright Notice in lua.h +*/ + + +#include + +#define lfunc_c +#define LUA_CORE + +#include "lua.h" + +#include "lfunc.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" + + + +Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e) { + Closure *c = cast(Closure *, luaM_malloc(L, sizeCclosure(nelems))); + luaC_link(L, obj2gco(c), LUA_TFUNCTION); + c->c.isC = 1; + c->c.env = e; + c->c.nupvalues = cast_byte(nelems); + return c; +} + + +Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e) { + Closure *c = cast(Closure *, luaM_malloc(L, sizeLclosure(nelems))); + luaC_link(L, obj2gco(c), LUA_TFUNCTION); + c->l.isC = 0; + c->l.env = e; + c->l.nupvalues = cast_byte(nelems); + while (nelems--) c->l.upvals[nelems] = NULL; + return c; +} + + +UpVal *luaF_newupval (lua_State *L) { + UpVal *uv = luaM_new(L, UpVal); + luaC_link(L, obj2gco(uv), LUA_TUPVAL); + uv->v = &uv->u.value; + setnilvalue(uv->v); + return uv; +} + + +UpVal *luaF_findupval (lua_State *L, StkId level) { + global_State *g = G(L); + GCObject **pp = &L->openupval; + UpVal *p; + UpVal *uv; + while (*pp != NULL && (p = ngcotouv(*pp))->v >= level) { + lua_assert(p->v != &p->u.value); + if (p->v == level) { /* found a corresponding upvalue? */ + if (isdead(g, obj2gco(p))) /* is it dead? */ + changewhite(obj2gco(p)); /* ressurect it */ + return p; + } + pp = &p->next; + } + uv = luaM_new(L, UpVal); /* not found: create a new one */ + uv->tt = LUA_TUPVAL; + uv->marked = luaC_white(g); + uv->v = level; /* current value lives in the stack */ + uv->next = *pp; /* chain it in the proper position */ + *pp = obj2gco(uv); + uv->u.l.prev = &g->uvhead; /* double link it in `uvhead' list */ + uv->u.l.next = g->uvhead.u.l.next; + uv->u.l.next->u.l.prev = uv; + g->uvhead.u.l.next = uv; + lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); + return uv; +} + + +static void unlinkupval (UpVal *uv) { + lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); + uv->u.l.next->u.l.prev = uv->u.l.prev; /* remove from `uvhead' list */ + uv->u.l.prev->u.l.next = uv->u.l.next; +} + + +void luaF_freeupval (lua_State *L, UpVal *uv) { + if (uv->v != &uv->u.value) /* is it open? */ + unlinkupval(uv); /* remove from open list */ + luaM_free(L, uv); /* free upvalue */ +} + + +void luaF_close (lua_State *L, StkId level) { + UpVal *uv; + global_State *g = G(L); + while (L->openupval != NULL && (uv = ngcotouv(L->openupval))->v >= level) { + GCObject *o = obj2gco(uv); + lua_assert(!isblack(o) && uv->v != &uv->u.value); + L->openupval = uv->next; /* remove from `open' list */ + if (isdead(g, o)) + luaF_freeupval(L, uv); /* free upvalue */ + else { + unlinkupval(uv); + setobj(L, &uv->u.value, uv->v); + uv->v = &uv->u.value; /* now current value lives here */ + luaC_linkupval(L, uv); /* link upvalue into `gcroot' list */ + } + } +} + + +Proto *luaF_newproto (lua_State *L) { + Proto *f = luaM_new(L, Proto); + luaC_link(L, obj2gco(f), LUA_TPROTO); + f->k = NULL; + f->sizek = 0; + f->p = NULL; + f->sizep = 0; + f->code = NULL; + f->sizecode = 0; + f->sizelineinfo = 0; + f->sizeupvalues = 0; + f->nups = 0; + f->upvalues = NULL; + f->numparams = 0; + f->is_vararg = 0; + f->maxstacksize = 0; + f->lineinfo = NULL; + f->sizelocvars = 0; + f->locvars = NULL; + f->linedefined = 0; + f->lastlinedefined = 0; + f->source = NULL; + return f; +} + + +void luaF_freeproto (lua_State *L, Proto *f) { + luaM_freearray(L, f->code, f->sizecode, Instruction); + luaM_freearray(L, f->p, f->sizep, Proto *); + luaM_freearray(L, f->k, f->sizek, TValue); + luaM_freearray(L, f->lineinfo, f->sizelineinfo, int); + luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar); + luaM_freearray(L, f->upvalues, f->sizeupvalues, TString *); + luaM_free(L, f); +} + + +void luaF_freeclosure (lua_State *L, Closure *c) { + int size = (c->c.isC) ? sizeCclosure(c->c.nupvalues) : + sizeLclosure(c->l.nupvalues); + luaM_freemem(L, c, size); +} + + +/* +** Look for n-th local variable at line `line' in function `func'. +** Returns NULL if not found. +*/ +const char *luaF_getlocalname (const Proto *f, int local_number, int pc) { + int i; + for (i = 0; isizelocvars && f->locvars[i].startpc <= pc; i++) { + if (pc < f->locvars[i].endpc) { /* is variable active? */ + local_number--; + if (local_number == 0) + return getstr(f->locvars[i].varname); + } + } + return NULL; /* not found */ +} + diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/src/lfunc.h b/mod/pub.mod/lua.mod/lua-5.1.4/src/lfunc.h new file mode 100644 index 0000000..a68cf51 --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/src/lfunc.h @@ -0,0 +1,34 @@ +/* +** $Id: lfunc.h,v 2.4.1.1 2007/12/27 13:02:25 roberto Exp $ +** Auxiliary functions to manipulate prototypes and closures +** See Copyright Notice in lua.h +*/ + +#ifndef lfunc_h +#define lfunc_h + + +#include "lobject.h" + + +#define sizeCclosure(n) (cast(int, sizeof(CClosure)) + \ + cast(int, sizeof(TValue)*((n)-1))) + +#define sizeLclosure(n) (cast(int, sizeof(LClosure)) + \ + cast(int, sizeof(TValue *)*((n)-1))) + + +LUAI_FUNC Proto *luaF_newproto (lua_State *L); +LUAI_FUNC Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e); +LUAI_FUNC Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e); +LUAI_FUNC UpVal *luaF_newupval (lua_State *L); +LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level); +LUAI_FUNC void luaF_close (lua_State *L, StkId level); +LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f); +LUAI_FUNC void luaF_freeclosure (lua_State *L, Closure *c); +LUAI_FUNC void luaF_freeupval (lua_State *L, UpVal *uv); +LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number, + int pc); + + +#endif diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/src/lgc.c b/mod/pub.mod/lua.mod/lua-5.1.4/src/lgc.c new file mode 100644 index 0000000..d9e0b78 --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/src/lgc.c @@ -0,0 +1,711 @@ +/* +** $Id: lgc.c,v 2.38.1.1 2007/12/27 13:02:25 roberto Exp $ +** Garbage Collector +** See Copyright Notice in lua.h +*/ + +#include + +#define lgc_c +#define LUA_CORE + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" + + +#define GCSTEPSIZE 1024u +#define GCSWEEPMAX 40 +#define GCSWEEPCOST 10 +#define GCFINALIZECOST 100 + + +#define maskmarks cast_byte(~(bitmask(BLACKBIT)|WHITEBITS)) + +#define makewhite(g,x) \ + ((x)->gch.marked = cast_byte(((x)->gch.marked & maskmarks) | luaC_white(g))) + +#define white2gray(x) reset2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT) +#define black2gray(x) resetbit((x)->gch.marked, BLACKBIT) + +#define stringmark(s) reset2bits((s)->tsv.marked, WHITE0BIT, WHITE1BIT) + + +#define isfinalized(u) testbit((u)->marked, FINALIZEDBIT) +#define markfinalized(u) l_setbit((u)->marked, FINALIZEDBIT) + + +#define KEYWEAK bitmask(KEYWEAKBIT) +#define VALUEWEAK bitmask(VALUEWEAKBIT) + + + +#define markvalue(g,o) { checkconsistency(o); \ + if (iscollectable(o) && iswhite(gcvalue(o))) reallymarkobject(g,gcvalue(o)); } + +#define markobject(g,t) { if (iswhite(obj2gco(t))) \ + reallymarkobject(g, obj2gco(t)); } + + +#define setthreshold(g) (g->GCthreshold = (g->estimate/100) * g->gcpause) + + +static void removeentry (Node *n) { + lua_assert(ttisnil(gval(n))); + if (iscollectable(gkey(n))) + setttype(gkey(n), LUA_TDEADKEY); /* dead key; remove it */ +} + + +static void reallymarkobject (global_State *g, GCObject *o) { + lua_assert(iswhite(o) && !isdead(g, o)); + white2gray(o); + switch (o->gch.tt) { + case LUA_TSTRING: { + return; + } + case LUA_TUSERDATA: { + Table *mt = gco2u(o)->metatable; + gray2black(o); /* udata are never gray */ + if (mt) markobject(g, mt); + markobject(g, gco2u(o)->env); + return; + } + case LUA_TUPVAL: { + UpVal *uv = gco2uv(o); + markvalue(g, uv->v); + if (uv->v == &uv->u.value) /* closed? */ + gray2black(o); /* open upvalues are never black */ + return; + } + case LUA_TFUNCTION: { + gco2cl(o)->c.gclist = g->gray; + g->gray = o; + break; + } + case LUA_TTABLE: { + gco2h(o)->gclist = g->gray; + g->gray = o; + break; + } + case LUA_TTHREAD: { + gco2th(o)->gclist = g->gray; + g->gray = o; + break; + } + case LUA_TPROTO: { + gco2p(o)->gclist = g->gray; + g->gray = o; + break; + } + default: lua_assert(0); + } +} + + +static void marktmu (global_State *g) { + GCObject *u = g->tmudata; + if (u) { + do { + u = u->gch.next; + makewhite(g, u); /* may be marked, if left from previous GC */ + reallymarkobject(g, u); + } while (u != g->tmudata); + } +} + + +/* move `dead' udata that need finalization to list `tmudata' */ +size_t luaC_separateudata (lua_State *L, int all) { + global_State *g = G(L); + size_t deadmem = 0; + GCObject **p = &g->mainthread->next; + GCObject *curr; + while ((curr = *p) != NULL) { + if (!(iswhite(curr) || all) || isfinalized(gco2u(curr))) + p = &curr->gch.next; /* don't bother with them */ + else if (fasttm(L, gco2u(curr)->metatable, TM_GC) == NULL) { + markfinalized(gco2u(curr)); /* don't need finalization */ + p = &curr->gch.next; + } + else { /* must call its gc method */ + deadmem += sizeudata(gco2u(curr)); + markfinalized(gco2u(curr)); + *p = curr->gch.next; + /* link `curr' at the end of `tmudata' list */ + if (g->tmudata == NULL) /* list is empty? */ + g->tmudata = curr->gch.next = curr; /* creates a circular list */ + else { + curr->gch.next = g->tmudata->gch.next; + g->tmudata->gch.next = curr; + g->tmudata = curr; + } + } + } + return deadmem; +} + + +static int traversetable (global_State *g, Table *h) { + int i; + int weakkey = 0; + int weakvalue = 0; + const TValue *mode; + if (h->metatable) + markobject(g, h->metatable); + mode = gfasttm(g, h->metatable, TM_MODE); + if (mode && ttisstring(mode)) { /* is there a weak mode? */ + weakkey = (strchr(svalue(mode), 'k') != NULL); + weakvalue = (strchr(svalue(mode), 'v') != NULL); + if (weakkey || weakvalue) { /* is really weak? */ + h->marked &= ~(KEYWEAK | VALUEWEAK); /* clear bits */ + h->marked |= cast_byte((weakkey << KEYWEAKBIT) | + (weakvalue << VALUEWEAKBIT)); + h->gclist = g->weak; /* must be cleared after GC, ... */ + g->weak = obj2gco(h); /* ... so put in the appropriate list */ + } + } + if (weakkey && weakvalue) return 1; + if (!weakvalue) { + i = h->sizearray; + while (i--) + markvalue(g, &h->array[i]); + } + i = sizenode(h); + while (i--) { + Node *n = gnode(h, i); + lua_assert(ttype(gkey(n)) != LUA_TDEADKEY || ttisnil(gval(n))); + if (ttisnil(gval(n))) + removeentry(n); /* remove empty entries */ + else { + lua_assert(!ttisnil(gkey(n))); + if (!weakkey) markvalue(g, gkey(n)); + if (!weakvalue) markvalue(g, gval(n)); + } + } + return weakkey || weakvalue; +} + + +/* +** All marks are conditional because a GC may happen while the +** prototype is still being created +*/ +static void traverseproto (global_State *g, Proto *f) { + int i; + if (f->source) stringmark(f->source); + for (i=0; isizek; i++) /* mark literals */ + markvalue(g, &f->k[i]); + for (i=0; isizeupvalues; i++) { /* mark upvalue names */ + if (f->upvalues[i]) + stringmark(f->upvalues[i]); + } + for (i=0; isizep; i++) { /* mark nested protos */ + if (f->p[i]) + markobject(g, f->p[i]); + } + for (i=0; isizelocvars; i++) { /* mark local-variable names */ + if (f->locvars[i].varname) + stringmark(f->locvars[i].varname); + } +} + + + +static void traverseclosure (global_State *g, Closure *cl) { + markobject(g, cl->c.env); + if (cl->c.isC) { + int i; + for (i=0; ic.nupvalues; i++) /* mark its upvalues */ + markvalue(g, &cl->c.upvalue[i]); + } + else { + int i; + lua_assert(cl->l.nupvalues == cl->l.p->nups); + markobject(g, cl->l.p); + for (i=0; il.nupvalues; i++) /* mark its upvalues */ + markobject(g, cl->l.upvals[i]); + } +} + + +static void checkstacksizes (lua_State *L, StkId max) { + int ci_used = cast_int(L->ci - L->base_ci); /* number of `ci' in use */ + int s_used = cast_int(max - L->stack); /* part of stack in use */ + if (L->size_ci > LUAI_MAXCALLS) /* handling overflow? */ + return; /* do not touch the stacks */ + if (4*ci_used < L->size_ci && 2*BASIC_CI_SIZE < L->size_ci) + luaD_reallocCI(L, L->size_ci/2); /* still big enough... */ + condhardstacktests(luaD_reallocCI(L, ci_used + 1)); + if (4*s_used < L->stacksize && + 2*(BASIC_STACK_SIZE+EXTRA_STACK) < L->stacksize) + luaD_reallocstack(L, L->stacksize/2); /* still big enough... */ + condhardstacktests(luaD_reallocstack(L, s_used)); +} + + +static void traversestack (global_State *g, lua_State *l) { + StkId o, lim; + CallInfo *ci; + markvalue(g, gt(l)); + lim = l->top; + for (ci = l->base_ci; ci <= l->ci; ci++) { + lua_assert(ci->top <= l->stack_last); + if (lim < ci->top) lim = ci->top; + } + for (o = l->stack; o < l->top; o++) + markvalue(g, o); + for (; o <= lim; o++) + setnilvalue(o); + checkstacksizes(l, lim); +} + + +/* +** traverse one gray object, turning it to black. +** Returns `quantity' traversed. +*/ +static l_mem propagatemark (global_State *g) { + GCObject *o = g->gray; + lua_assert(isgray(o)); + gray2black(o); + switch (o->gch.tt) { + case LUA_TTABLE: { + Table *h = gco2h(o); + g->gray = h->gclist; + if (traversetable(g, h)) /* table is weak? */ + black2gray(o); /* keep it gray */ + return sizeof(Table) + sizeof(TValue) * h->sizearray + + sizeof(Node) * sizenode(h); + } + case LUA_TFUNCTION: { + Closure *cl = gco2cl(o); + g->gray = cl->c.gclist; + traverseclosure(g, cl); + return (cl->c.isC) ? sizeCclosure(cl->c.nupvalues) : + sizeLclosure(cl->l.nupvalues); + } + case LUA_TTHREAD: { + lua_State *th = gco2th(o); + g->gray = th->gclist; + th->gclist = g->grayagain; + g->grayagain = o; + black2gray(o); + traversestack(g, th); + return sizeof(lua_State) + sizeof(TValue) * th->stacksize + + sizeof(CallInfo) * th->size_ci; + } + case LUA_TPROTO: { + Proto *p = gco2p(o); + g->gray = p->gclist; + traverseproto(g, p); + return sizeof(Proto) + sizeof(Instruction) * p->sizecode + + sizeof(Proto *) * p->sizep + + sizeof(TValue) * p->sizek + + sizeof(int) * p->sizelineinfo + + sizeof(LocVar) * p->sizelocvars + + sizeof(TString *) * p->sizeupvalues; + } + default: lua_assert(0); return 0; + } +} + + +static size_t propagateall (global_State *g) { + size_t m = 0; + while (g->gray) m += propagatemark(g); + return m; +} + + +/* +** The next function tells whether a key or value can be cleared from +** a weak table. Non-collectable objects are never removed from weak +** tables. Strings behave as `values', so are never removed too. for +** other objects: if really collected, cannot keep them; for userdata +** being finalized, keep them in keys, but not in values +*/ +static int iscleared (const TValue *o, int iskey) { + if (!iscollectable(o)) return 0; + if (ttisstring(o)) { + stringmark(rawtsvalue(o)); /* strings are `values', so are never weak */ + return 0; + } + return iswhite(gcvalue(o)) || + (ttisuserdata(o) && (!iskey && isfinalized(uvalue(o)))); +} + + +/* +** clear collected entries from weaktables +*/ +static void cleartable (GCObject *l) { + while (l) { + Table *h = gco2h(l); + int i = h->sizearray; + lua_assert(testbit(h->marked, VALUEWEAKBIT) || + testbit(h->marked, KEYWEAKBIT)); + if (testbit(h->marked, VALUEWEAKBIT)) { + while (i--) { + TValue *o = &h->array[i]; + if (iscleared(o, 0)) /* value was collected? */ + setnilvalue(o); /* remove value */ + } + } + i = sizenode(h); + while (i--) { + Node *n = gnode(h, i); + if (!ttisnil(gval(n)) && /* non-empty entry? */ + (iscleared(key2tval(n), 1) || iscleared(gval(n), 0))) { + setnilvalue(gval(n)); /* remove value ... */ + removeentry(n); /* remove entry from table */ + } + } + l = h->gclist; + } +} + + +static void freeobj (lua_State *L, GCObject *o) { + switch (o->gch.tt) { + case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break; + case LUA_TFUNCTION: luaF_freeclosure(L, gco2cl(o)); break; + case LUA_TUPVAL: luaF_freeupval(L, gco2uv(o)); break; + case LUA_TTABLE: luaH_free(L, gco2h(o)); break; + case LUA_TTHREAD: { + lua_assert(gco2th(o) != L && gco2th(o) != G(L)->mainthread); + luaE_freethread(L, gco2th(o)); + break; + } + case LUA_TSTRING: { + G(L)->strt.nuse--; + luaM_freemem(L, o, sizestring(gco2ts(o))); + break; + } + case LUA_TUSERDATA: { + luaM_freemem(L, o, sizeudata(gco2u(o))); + break; + } + default: lua_assert(0); + } +} + + + +#define sweepwholelist(L,p) sweeplist(L,p,MAX_LUMEM) + + +static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) { + GCObject *curr; + global_State *g = G(L); + int deadmask = otherwhite(g); + while ((curr = *p) != NULL && count-- > 0) { + if (curr->gch.tt == LUA_TTHREAD) /* sweep open upvalues of each thread */ + sweepwholelist(L, &gco2th(curr)->openupval); + if ((curr->gch.marked ^ WHITEBITS) & deadmask) { /* not dead? */ + lua_assert(!isdead(g, curr) || testbit(curr->gch.marked, FIXEDBIT)); + makewhite(g, curr); /* make it white (for next cycle) */ + p = &curr->gch.next; + } + else { /* must erase `curr' */ + lua_assert(isdead(g, curr) || deadmask == bitmask(SFIXEDBIT)); + *p = curr->gch.next; + if (curr == g->rootgc) /* is the first element of the list? */ + g->rootgc = curr->gch.next; /* adjust first */ + freeobj(L, curr); + } + } + return p; +} + + +static void checkSizes (lua_State *L) { + global_State *g = G(L); + /* check size of string hash */ + if (g->strt.nuse < cast(lu_int32, g->strt.size/4) && + g->strt.size > MINSTRTABSIZE*2) + luaS_resize(L, g->strt.size/2); /* table is too big */ + /* check size of buffer */ + if (luaZ_sizebuffer(&g->buff) > LUA_MINBUFFER*2) { /* buffer too big? */ + size_t newsize = luaZ_sizebuffer(&g->buff) / 2; + luaZ_resizebuffer(L, &g->buff, newsize); + } +} + + +static void GCTM (lua_State *L) { + global_State *g = G(L); + GCObject *o = g->tmudata->gch.next; /* get first element */ + Udata *udata = rawgco2u(o); + const TValue *tm; + /* remove udata from `tmudata' */ + if (o == g->tmudata) /* last element? */ + g->tmudata = NULL; + else + g->tmudata->gch.next = udata->uv.next; + udata->uv.next = g->mainthread->next; /* return it to `root' list */ + g->mainthread->next = o; + makewhite(g, o); + tm = fasttm(L, udata->uv.metatable, TM_GC); + if (tm != NULL) { + lu_byte oldah = L->allowhook; + lu_mem oldt = g->GCthreshold; + L->allowhook = 0; /* stop debug hooks during GC tag method */ + g->GCthreshold = 2*g->totalbytes; /* avoid GC steps */ + setobj2s(L, L->top, tm); + setuvalue(L, L->top+1, udata); + L->top += 2; + luaD_call(L, L->top - 2, 0); + L->allowhook = oldah; /* restore hooks */ + g->GCthreshold = oldt; /* restore threshold */ + } +} + + +/* +** Call all GC tag methods +*/ +void luaC_callGCTM (lua_State *L) { + while (G(L)->tmudata) + GCTM(L); +} + + +void luaC_freeall (lua_State *L) { + global_State *g = G(L); + int i; + g->currentwhite = WHITEBITS | bitmask(SFIXEDBIT); /* mask to collect all elements */ + sweepwholelist(L, &g->rootgc); + for (i = 0; i < g->strt.size; i++) /* free all string lists */ + sweepwholelist(L, &g->strt.hash[i]); +} + + +static void markmt (global_State *g) { + int i; + for (i=0; imt[i]) markobject(g, g->mt[i]); +} + + +/* mark root set */ +static void markroot (lua_State *L) { + global_State *g = G(L); + g->gray = NULL; + g->grayagain = NULL; + g->weak = NULL; + markobject(g, g->mainthread); + /* make global table be traversed before main stack */ + markvalue(g, gt(g->mainthread)); + markvalue(g, registry(L)); + markmt(g); + g->gcstate = GCSpropagate; +} + + +static void remarkupvals (global_State *g) { + UpVal *uv; + for (uv = g->uvhead.u.l.next; uv != &g->uvhead; uv = uv->u.l.next) { + lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); + if (isgray(obj2gco(uv))) + markvalue(g, uv->v); + } +} + + +static void atomic (lua_State *L) { + global_State *g = G(L); + size_t udsize; /* total size of userdata to be finalized */ + /* remark occasional upvalues of (maybe) dead threads */ + remarkupvals(g); + /* traverse objects cautch by write barrier and by 'remarkupvals' */ + propagateall(g); + /* remark weak tables */ + g->gray = g->weak; + g->weak = NULL; + lua_assert(!iswhite(obj2gco(g->mainthread))); + markobject(g, L); /* mark running thread */ + markmt(g); /* mark basic metatables (again) */ + propagateall(g); + /* remark gray again */ + g->gray = g->grayagain; + g->grayagain = NULL; + propagateall(g); + udsize = luaC_separateudata(L, 0); /* separate userdata to be finalized */ + marktmu(g); /* mark `preserved' userdata */ + udsize += propagateall(g); /* remark, to propagate `preserveness' */ + cleartable(g->weak); /* remove collected objects from weak tables */ + /* flip current white */ + g->currentwhite = cast_byte(otherwhite(g)); + g->sweepstrgc = 0; + g->sweepgc = &g->rootgc; + g->gcstate = GCSsweepstring; + g->estimate = g->totalbytes - udsize; /* first estimate */ +} + + +static l_mem singlestep (lua_State *L) { + global_State *g = G(L); + /*lua_checkmemory(L);*/ + switch (g->gcstate) { + case GCSpause: { + markroot(L); /* start a new collection */ + return 0; + } + case GCSpropagate: { + if (g->gray) + return propagatemark(g); + else { /* no more `gray' objects */ + atomic(L); /* finish mark phase */ + return 0; + } + } + case GCSsweepstring: { + lu_mem old = g->totalbytes; + sweepwholelist(L, &g->strt.hash[g->sweepstrgc++]); + if (g->sweepstrgc >= g->strt.size) /* nothing more to sweep? */ + g->gcstate = GCSsweep; /* end sweep-string phase */ + lua_assert(old >= g->totalbytes); + g->estimate -= old - g->totalbytes; + return GCSWEEPCOST; + } + case GCSsweep: { + lu_mem old = g->totalbytes; + g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX); + if (*g->sweepgc == NULL) { /* nothing more to sweep? */ + checkSizes(L); + g->gcstate = GCSfinalize; /* end sweep phase */ + } + lua_assert(old >= g->totalbytes); + g->estimate -= old - g->totalbytes; + return GCSWEEPMAX*GCSWEEPCOST; + } + case GCSfinalize: { + if (g->tmudata) { + GCTM(L); + if (g->estimate > GCFINALIZECOST) + g->estimate -= GCFINALIZECOST; + return GCFINALIZECOST; + } + else { + g->gcstate = GCSpause; /* end collection */ + g->gcdept = 0; + return 0; + } + } + default: lua_assert(0); return 0; + } +} + + +void luaC_step (lua_State *L) { + global_State *g = G(L); + l_mem lim = (GCSTEPSIZE/100) * g->gcstepmul; + if (lim == 0) + lim = (MAX_LUMEM-1)/2; /* no limit */ + g->gcdept += g->totalbytes - g->GCthreshold; + do { + lim -= singlestep(L); + if (g->gcstate == GCSpause) + break; + } while (lim > 0); + if (g->gcstate != GCSpause) { + if (g->gcdept < GCSTEPSIZE) + g->GCthreshold = g->totalbytes + GCSTEPSIZE; /* - lim/g->gcstepmul;*/ + else { + g->gcdept -= GCSTEPSIZE; + g->GCthreshold = g->totalbytes; + } + } + else { + lua_assert(g->totalbytes >= g->estimate); + setthreshold(g); + } +} + + +void luaC_fullgc (lua_State *L) { + global_State *g = G(L); + if (g->gcstate <= GCSpropagate) { + /* reset sweep marks to sweep all elements (returning them to white) */ + g->sweepstrgc = 0; + g->sweepgc = &g->rootgc; + /* reset other collector lists */ + g->gray = NULL; + g->grayagain = NULL; + g->weak = NULL; + g->gcstate = GCSsweepstring; + } + lua_assert(g->gcstate != GCSpause && g->gcstate != GCSpropagate); + /* finish any pending sweep phase */ + while (g->gcstate != GCSfinalize) { + lua_assert(g->gcstate == GCSsweepstring || g->gcstate == GCSsweep); + singlestep(L); + } + markroot(L); + while (g->gcstate != GCSpause) { + singlestep(L); + } + setthreshold(g); +} + + +void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) { + global_State *g = G(L); + lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); + lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause); + lua_assert(ttype(&o->gch) != LUA_TTABLE); + /* must keep invariant? */ + if (g->gcstate == GCSpropagate) + reallymarkobject(g, v); /* restore invariant */ + else /* don't mind */ + makewhite(g, o); /* mark as white just to avoid other barriers */ +} + + +void luaC_barrierback (lua_State *L, Table *t) { + global_State *g = G(L); + GCObject *o = obj2gco(t); + lua_assert(isblack(o) && !isdead(g, o)); + lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause); + black2gray(o); /* make table gray (again) */ + t->gclist = g->grayagain; + g->grayagain = o; +} + + +void luaC_link (lua_State *L, GCObject *o, lu_byte tt) { + global_State *g = G(L); + o->gch.next = g->rootgc; + g->rootgc = o; + o->gch.marked = luaC_white(g); + o->gch.tt = tt; +} + + +void luaC_linkupval (lua_State *L, UpVal *uv) { + global_State *g = G(L); + GCObject *o = obj2gco(uv); + o->gch.next = g->rootgc; /* link upvalue into `rootgc' list */ + g->rootgc = o; + if (isgray(o)) { + if (g->gcstate == GCSpropagate) { + gray2black(o); /* closed upvalues need barrier */ + luaC_barrier(L, uv, uv->v); + } + else { /* sweep phase: sweep it (turning it into white) */ + makewhite(g, o); + lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause); + } + } +} + diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/src/lgc.h b/mod/pub.mod/lua.mod/lua-5.1.4/src/lgc.h new file mode 100644 index 0000000..5a8dc60 --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/src/lgc.h @@ -0,0 +1,110 @@ +/* +** $Id: lgc.h,v 2.15.1.1 2007/12/27 13:02:25 roberto Exp $ +** Garbage Collector +** See Copyright Notice in lua.h +*/ + +#ifndef lgc_h +#define lgc_h + + +#include "lobject.h" + + +/* +** Possible states of the Garbage Collector +*/ +#define GCSpause 0 +#define GCSpropagate 1 +#define GCSsweepstring 2 +#define GCSsweep 3 +#define GCSfinalize 4 + + +/* +** some userful bit tricks +*/ +#define resetbits(x,m) ((x) &= cast(lu_byte, ~(m))) +#define setbits(x,m) ((x) |= (m)) +#define testbits(x,m) ((x) & (m)) +#define bitmask(b) (1<<(b)) +#define bit2mask(b1,b2) (bitmask(b1) | bitmask(b2)) +#define l_setbit(x,b) setbits(x, bitmask(b)) +#define resetbit(x,b) resetbits(x, bitmask(b)) +#define testbit(x,b) testbits(x, bitmask(b)) +#define set2bits(x,b1,b2) setbits(x, (bit2mask(b1, b2))) +#define reset2bits(x,b1,b2) resetbits(x, (bit2mask(b1, b2))) +#define test2bits(x,b1,b2) testbits(x, (bit2mask(b1, b2))) + + + +/* +** Layout for bit use in `marked' field: +** bit 0 - object is white (type 0) +** bit 1 - object is white (type 1) +** bit 2 - object is black +** bit 3 - for userdata: has been finalized +** bit 3 - for tables: has weak keys +** bit 4 - for tables: has weak values +** bit 5 - object is fixed (should not be collected) +** bit 6 - object is "super" fixed (only the main thread) +*/ + + +#define WHITE0BIT 0 +#define WHITE1BIT 1 +#define BLACKBIT 2 +#define FINALIZEDBIT 3 +#define KEYWEAKBIT 3 +#define VALUEWEAKBIT 4 +#define FIXEDBIT 5 +#define SFIXEDBIT 6 +#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) + + +#define iswhite(x) test2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT) +#define isblack(x) testbit((x)->gch.marked, BLACKBIT) +#define isgray(x) (!isblack(x) && !iswhite(x)) + +#define otherwhite(g) (g->currentwhite ^ WHITEBITS) +#define isdead(g,v) ((v)->gch.marked & otherwhite(g) & WHITEBITS) + +#define changewhite(x) ((x)->gch.marked ^= WHITEBITS) +#define gray2black(x) l_setbit((x)->gch.marked, BLACKBIT) + +#define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x))) + +#define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS) + + +#define luaC_checkGC(L) { \ + condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1)); \ + if (G(L)->totalbytes >= G(L)->GCthreshold) \ + luaC_step(L); } + + +#define luaC_barrier(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \ + luaC_barrierf(L,obj2gco(p),gcvalue(v)); } + +#define luaC_barriert(L,t,v) { if (valiswhite(v) && isblack(obj2gco(t))) \ + luaC_barrierback(L,t); } + +#define luaC_objbarrier(L,p,o) \ + { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \ + luaC_barrierf(L,obj2gco(p),obj2gco(o)); } + +#define luaC_objbarriert(L,t,o) \ + { if (iswhite(obj2gco(o)) && isblack(obj2gco(t))) luaC_barrierback(L,t); } + +LUAI_FUNC size_t luaC_separateudata (lua_State *L, int all); +LUAI_FUNC void luaC_callGCTM (lua_State *L); +LUAI_FUNC void luaC_freeall (lua_State *L); +LUAI_FUNC void luaC_step (lua_State *L); +LUAI_FUNC void luaC_fullgc (lua_State *L); +LUAI_FUNC void luaC_link (lua_State *L, GCObject *o, lu_byte tt); +LUAI_FUNC void luaC_linkupval (lua_State *L, UpVal *uv); +LUAI_FUNC void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v); +LUAI_FUNC void luaC_barrierback (lua_State *L, Table *t); + + +#endif diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/src/linit.c b/mod/pub.mod/lua.mod/lua-5.1.4/src/linit.c new file mode 100644 index 0000000..c1f90df --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/src/linit.c @@ -0,0 +1,38 @@ +/* +** $Id: linit.c,v 1.14.1.1 2007/12/27 13:02:25 roberto Exp $ +** Initialization of libraries for lua.c +** See Copyright Notice in lua.h +*/ + + +#define linit_c +#define LUA_LIB + +#include "lua.h" + +#include "lualib.h" +#include "lauxlib.h" + + +static const luaL_Reg lualibs[] = { + {"", luaopen_base}, + {LUA_LOADLIBNAME, luaopen_package}, + {LUA_TABLIBNAME, luaopen_table}, + {LUA_IOLIBNAME, luaopen_io}, + {LUA_OSLIBNAME, luaopen_os}, + {LUA_STRLIBNAME, luaopen_string}, + {LUA_MATHLIBNAME, luaopen_math}, + {LUA_DBLIBNAME, luaopen_debug}, + {NULL, NULL} +}; + + +LUALIB_API void luaL_openlibs (lua_State *L) { + const luaL_Reg *lib = lualibs; + for (; lib->func; lib++) { + lua_pushcfunction(L, lib->func); + lua_pushstring(L, lib->name); + lua_call(L, 1, 0); + } +} + diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/src/liolib.c b/mod/pub.mod/lua.mod/lua-5.1.4/src/liolib.c new file mode 100644 index 0000000..e79ed1c --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/src/liolib.c @@ -0,0 +1,553 @@ +/* +** $Id: liolib.c,v 2.73.1.3 2008/01/18 17:47:43 roberto Exp $ +** Standard I/O (and system) library +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include +#include + +#define liolib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + + +#define IO_INPUT 1 +#define IO_OUTPUT 2 + + +static const char *const fnames[] = {"input", "output"}; + + +static int pushresult (lua_State *L, int i, const char *filename) { + int en = errno; /* calls to Lua API may change this value */ + if (i) { + lua_pushboolean(L, 1); + return 1; + } + else { + lua_pushnil(L); + if (filename) + lua_pushfstring(L, "%s: %s", filename, strerror(en)); + else + lua_pushfstring(L, "%s", strerror(en)); + lua_pushinteger(L, en); + return 3; + } +} + + +static void fileerror (lua_State *L, int arg, const char *filename) { + lua_pushfstring(L, "%s: %s", filename, strerror(errno)); + luaL_argerror(L, arg, lua_tostring(L, -1)); +} + + +#define tofilep(L) ((FILE **)luaL_checkudata(L, 1, LUA_FILEHANDLE)) + + +static int io_type (lua_State *L) { + void *ud; + luaL_checkany(L, 1); + ud = lua_touserdata(L, 1); + lua_getfield(L, LUA_REGISTRYINDEX, LUA_FILEHANDLE); + if (ud == NULL || !lua_getmetatable(L, 1) || !lua_rawequal(L, -2, -1)) + lua_pushnil(L); /* not a file */ + else if (*((FILE **)ud) == NULL) + lua_pushliteral(L, "closed file"); + else + lua_pushliteral(L, "file"); + return 1; +} + + +static FILE *tofile (lua_State *L) { + FILE **f = tofilep(L); + if (*f == NULL) + luaL_error(L, "attempt to use a closed file"); + return *f; +} + + + +/* +** When creating file handles, always creates a `closed' file handle +** before opening the actual file; so, if there is a memory error, the +** file is not left opened. +*/ +static FILE **newfile (lua_State *L) { + FILE **pf = (FILE **)lua_newuserdata(L, sizeof(FILE *)); + *pf = NULL; /* file handle is currently `closed' */ + luaL_getmetatable(L, LUA_FILEHANDLE); + lua_setmetatable(L, -2); + return pf; +} + + +/* +** function to (not) close the standard files stdin, stdout, and stderr +*/ +static int io_noclose (lua_State *L) { + lua_pushnil(L); + lua_pushliteral(L, "cannot close standard file"); + return 2; +} + + +/* +** function to close 'popen' files +*/ +static int io_pclose (lua_State *L) { + FILE **p = tofilep(L); + int ok = lua_pclose(L, *p); + *p = NULL; + return pushresult(L, ok, NULL); +} + + +/* +** function to close regular files +*/ +static int io_fclose (lua_State *L) { + FILE **p = tofilep(L); + int ok = (fclose(*p) == 0); + *p = NULL; + return pushresult(L, ok, NULL); +} + + +static int aux_close (lua_State *L) { + lua_getfenv(L, 1); + lua_getfield(L, -1, "__close"); + return (lua_tocfunction(L, -1))(L); +} + + +static int io_close (lua_State *L) { + if (lua_isnone(L, 1)) + lua_rawgeti(L, LUA_ENVIRONINDEX, IO_OUTPUT); + tofile(L); /* make sure argument is a file */ + return aux_close(L); +} + + +static int io_gc (lua_State *L) { + FILE *f = *tofilep(L); + /* ignore closed files */ + if (f != NULL) + aux_close(L); + return 0; +} + + +static int io_tostring (lua_State *L) { + FILE *f = *tofilep(L); + if (f == NULL) + lua_pushliteral(L, "file (closed)"); + else + lua_pushfstring(L, "file (%p)", f); + return 1; +} + + +static int io_open (lua_State *L) { + const char *filename = luaL_checkstring(L, 1); + const char *mode = luaL_optstring(L, 2, "r"); + FILE **pf = newfile(L); + *pf = fopen(filename, mode); + return (*pf == NULL) ? pushresult(L, 0, filename) : 1; +} + + +/* +** this function has a separated environment, which defines the +** correct __close for 'popen' files +*/ +static int io_popen (lua_State *L) { + const char *filename = luaL_checkstring(L, 1); + const char *mode = luaL_optstring(L, 2, "r"); + FILE **pf = newfile(L); + *pf = lua_popen(L, filename, mode); + return (*pf == NULL) ? pushresult(L, 0, filename) : 1; +} + + +static int io_tmpfile (lua_State *L) { + FILE **pf = newfile(L); + *pf = tmpfile(); + return (*pf == NULL) ? pushresult(L, 0, NULL) : 1; +} + + +static FILE *getiofile (lua_State *L, int findex) { + FILE *f; + lua_rawgeti(L, LUA_ENVIRONINDEX, findex); + f = *(FILE **)lua_touserdata(L, -1); + if (f == NULL) + luaL_error(L, "standard %s file is closed", fnames[findex - 1]); + return f; +} + + +static int g_iofile (lua_State *L, int f, const char *mode) { + if (!lua_isnoneornil(L, 1)) { + const char *filename = lua_tostring(L, 1); + if (filename) { + FILE **pf = newfile(L); + *pf = fopen(filename, mode); + if (*pf == NULL) + fileerror(L, 1, filename); + } + else { + tofile(L); /* check that it's a valid file handle */ + lua_pushvalue(L, 1); + } + lua_rawseti(L, LUA_ENVIRONINDEX, f); + } + /* return current value */ + lua_rawgeti(L, LUA_ENVIRONINDEX, f); + return 1; +} + + +static int io_input (lua_State *L) { + return g_iofile(L, IO_INPUT, "r"); +} + + +static int io_output (lua_State *L) { + return g_iofile(L, IO_OUTPUT, "w"); +} + + +static int io_readline (lua_State *L); + + +static void aux_lines (lua_State *L, int idx, int toclose) { + lua_pushvalue(L, idx); + lua_pushboolean(L, toclose); /* close/not close file when finished */ + lua_pushcclosure(L, io_readline, 2); +} + + +static int f_lines (lua_State *L) { + tofile(L); /* check that it's a valid file handle */ + aux_lines(L, 1, 0); + return 1; +} + + +static int io_lines (lua_State *L) { + if (lua_isnoneornil(L, 1)) { /* no arguments? */ + /* will iterate over default input */ + lua_rawgeti(L, LUA_ENVIRONINDEX, IO_INPUT); + return f_lines(L); + } + else { + const char *filename = luaL_checkstring(L, 1); + FILE **pf = newfile(L); + *pf = fopen(filename, "r"); + if (*pf == NULL) + fileerror(L, 1, filename); + aux_lines(L, lua_gettop(L), 1); + return 1; + } +} + + +/* +** {====================================================== +** READ +** ======================================================= +*/ + + +static int read_number (lua_State *L, FILE *f) { + lua_Number d; + if (fscanf(f, LUA_NUMBER_SCAN, &d) == 1) { + lua_pushnumber(L, d); + return 1; + } + else return 0; /* read fails */ +} + + +static int test_eof (lua_State *L, FILE *f) { + int c = getc(f); + ungetc(c, f); + lua_pushlstring(L, NULL, 0); + return (c != EOF); +} + + +static int read_line (lua_State *L, FILE *f) { + luaL_Buffer b; + luaL_buffinit(L, &b); + for (;;) { + size_t l; + char *p = luaL_prepbuffer(&b); + if (fgets(p, LUAL_BUFFERSIZE, f) == NULL) { /* eof? */ + luaL_pushresult(&b); /* close buffer */ + return (lua_objlen(L, -1) > 0); /* check whether read something */ + } + l = strlen(p); + if (l == 0 || p[l-1] != '\n') + luaL_addsize(&b, l); + else { + luaL_addsize(&b, l - 1); /* do not include `eol' */ + luaL_pushresult(&b); /* close buffer */ + return 1; /* read at least an `eol' */ + } + } +} + + +static int read_chars (lua_State *L, FILE *f, size_t n) { + size_t rlen; /* how much to read */ + size_t nr; /* number of chars actually read */ + luaL_Buffer b; + luaL_buffinit(L, &b); + rlen = LUAL_BUFFERSIZE; /* try to read that much each time */ + do { + char *p = luaL_prepbuffer(&b); + if (rlen > n) rlen = n; /* cannot read more than asked */ + nr = fread(p, sizeof(char), rlen, f); + luaL_addsize(&b, nr); + n -= nr; /* still have to read `n' chars */ + } while (n > 0 && nr == rlen); /* until end of count or eof */ + luaL_pushresult(&b); /* close buffer */ + return (n == 0 || lua_objlen(L, -1) > 0); +} + + +static int g_read (lua_State *L, FILE *f, int first) { + int nargs = lua_gettop(L) - 1; + int success; + int n; + clearerr(f); + if (nargs == 0) { /* no arguments? */ + success = read_line(L, f); + n = first+1; /* to return 1 result */ + } + else { /* ensure stack space for all results and for auxlib's buffer */ + luaL_checkstack(L, nargs+LUA_MINSTACK, "too many arguments"); + success = 1; + for (n = first; nargs-- && success; n++) { + if (lua_type(L, n) == LUA_TNUMBER) { + size_t l = (size_t)lua_tointeger(L, n); + success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l); + } + else { + const char *p = lua_tostring(L, n); + luaL_argcheck(L, p && p[0] == '*', n, "invalid option"); + switch (p[1]) { + case 'n': /* number */ + success = read_number(L, f); + break; + case 'l': /* line */ + success = read_line(L, f); + break; + case 'a': /* file */ + read_chars(L, f, ~((size_t)0)); /* read MAX_SIZE_T chars */ + success = 1; /* always success */ + break; + default: + return luaL_argerror(L, n, "invalid format"); + } + } + } + } + if (ferror(f)) + return pushresult(L, 0, NULL); + if (!success) { + lua_pop(L, 1); /* remove last result */ + lua_pushnil(L); /* push nil instead */ + } + return n - first; +} + + +static int io_read (lua_State *L) { + return g_read(L, getiofile(L, IO_INPUT), 1); +} + + +static int f_read (lua_State *L) { + return g_read(L, tofile(L), 2); +} + + +static int io_readline (lua_State *L) { + FILE *f = *(FILE **)lua_touserdata(L, lua_upvalueindex(1)); + int sucess; + if (f == NULL) /* file is already closed? */ + luaL_error(L, "file is already closed"); + sucess = read_line(L, f); + if (ferror(f)) + return luaL_error(L, "%s", strerror(errno)); + if (sucess) return 1; + else { /* EOF */ + if (lua_toboolean(L, lua_upvalueindex(2))) { /* generator created file? */ + lua_settop(L, 0); + lua_pushvalue(L, lua_upvalueindex(1)); + aux_close(L); /* close it */ + } + return 0; + } +} + +/* }====================================================== */ + + +static int g_write (lua_State *L, FILE *f, int arg) { + int nargs = lua_gettop(L) - 1; + int status = 1; + for (; nargs--; arg++) { + if (lua_type(L, arg) == LUA_TNUMBER) { + /* optimization: could be done exactly as for strings */ + status = status && + fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0; + } + else { + size_t l; + const char *s = luaL_checklstring(L, arg, &l); + status = status && (fwrite(s, sizeof(char), l, f) == l); + } + } + return pushresult(L, status, NULL); +} + + +static int io_write (lua_State *L) { + return g_write(L, getiofile(L, IO_OUTPUT), 1); +} + + +static int f_write (lua_State *L) { + return g_write(L, tofile(L), 2); +} + + +static int f_seek (lua_State *L) { + static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END}; + static const char *const modenames[] = {"set", "cur", "end", NULL}; + FILE *f = tofile(L); + int op = luaL_checkoption(L, 2, "cur", modenames); + long offset = luaL_optlong(L, 3, 0); + op = fseek(f, offset, mode[op]); + if (op) + return pushresult(L, 0, NULL); /* error */ + else { + lua_pushinteger(L, ftell(f)); + return 1; + } +} + + +static int f_setvbuf (lua_State *L) { + static const int mode[] = {_IONBF, _IOFBF, _IOLBF}; + static const char *const modenames[] = {"no", "full", "line", NULL}; + FILE *f = tofile(L); + int op = luaL_checkoption(L, 2, NULL, modenames); + lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE); + int res = setvbuf(f, NULL, mode[op], sz); + return pushresult(L, res == 0, NULL); +} + + + +static int io_flush (lua_State *L) { + return pushresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL); +} + + +static int f_flush (lua_State *L) { + return pushresult(L, fflush(tofile(L)) == 0, NULL); +} + + +static const luaL_Reg iolib[] = { + {"close", io_close}, + {"flush", io_flush}, + {"input", io_input}, + {"lines", io_lines}, + {"open", io_open}, + {"output", io_output}, + {"popen", io_popen}, + {"read", io_read}, + {"tmpfile", io_tmpfile}, + {"type", io_type}, + {"write", io_write}, + {NULL, NULL} +}; + + +static const luaL_Reg flib[] = { + {"close", io_close}, + {"flush", f_flush}, + {"lines", f_lines}, + {"read", f_read}, + {"seek", f_seek}, + {"setvbuf", f_setvbuf}, + {"write", f_write}, + {"__gc", io_gc}, + {"__tostring", io_tostring}, + {NULL, NULL} +}; + + +static void createmeta (lua_State *L) { + luaL_newmetatable(L, LUA_FILEHANDLE); /* create metatable for file handles */ + lua_pushvalue(L, -1); /* push metatable */ + lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */ + luaL_register(L, NULL, flib); /* file methods */ +} + + +static void createstdfile (lua_State *L, FILE *f, int k, const char *fname) { + *newfile(L) = f; + if (k > 0) { + lua_pushvalue(L, -1); + lua_rawseti(L, LUA_ENVIRONINDEX, k); + } + lua_pushvalue(L, -2); /* copy environment */ + lua_setfenv(L, -2); /* set it */ + lua_setfield(L, -3, fname); +} + + +static void newfenv (lua_State *L, lua_CFunction cls) { + lua_createtable(L, 0, 1); + lua_pushcfunction(L, cls); + lua_setfield(L, -2, "__close"); +} + + +LUALIB_API int luaopen_io (lua_State *L) { + createmeta(L); + /* create (private) environment (with fields IO_INPUT, IO_OUTPUT, __close) */ + newfenv(L, io_fclose); + lua_replace(L, LUA_ENVIRONINDEX); + /* open library */ + luaL_register(L, LUA_IOLIBNAME, iolib); + /* create (and set) default files */ + newfenv(L, io_noclose); /* close function for default files */ + createstdfile(L, stdin, IO_INPUT, "stdin"); + createstdfile(L, stdout, IO_OUTPUT, "stdout"); + createstdfile(L, stderr, 0, "stderr"); + lua_pop(L, 1); /* pop environment for default files */ + lua_getfield(L, -1, "popen"); + newfenv(L, io_pclose); /* create environment for 'popen' */ + lua_setfenv(L, -2); /* set fenv for 'popen' */ + lua_pop(L, 1); /* pop 'popen' */ + return 1; +} + diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/src/llex.c b/mod/pub.mod/lua.mod/lua-5.1.4/src/llex.c new file mode 100644 index 0000000..6dc3193 --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/src/llex.c @@ -0,0 +1,461 @@ +/* +** $Id: llex.c,v 2.20.1.1 2007/12/27 13:02:25 roberto Exp $ +** Lexical Analyzer +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include + +#define llex_c +#define LUA_CORE + +#include "lua.h" + +#include "ldo.h" +#include "llex.h" +#include "lobject.h" +#include "lparser.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "lzio.h" + + + +#define next(ls) (ls->current = zgetc(ls->z)) + + + + +#define currIsNewline(ls) (ls->current == '\n' || ls->current == '\r') + + +/* ORDER RESERVED */ +const char *const luaX_tokens [] = { + "and", "break", "do", "else", "elseif", + "end", "false", "for", "function", "if", + "in", "local", "nil", "not", "or", "repeat", + "return", "then", "true", "until", "while", + "..", "...", "==", ">=", "<=", "~=", + "", "", "", "", + NULL +}; + + +#define save_and_next(ls) (save(ls, ls->current), next(ls)) + + +static void save (LexState *ls, int c) { + Mbuffer *b = ls->buff; + if (b->n + 1 > b->buffsize) { + size_t newsize; + if (b->buffsize >= MAX_SIZET/2) + luaX_lexerror(ls, "lexical element too long", 0); + newsize = b->buffsize * 2; + luaZ_resizebuffer(ls->L, b, newsize); + } + b->buffer[b->n++] = cast(char, c); +} + + +void luaX_init (lua_State *L) { + int i; + for (i=0; itsv.reserved = cast_byte(i+1); /* reserved word */ + } +} + + +#define MAXSRC 80 + + +const char *luaX_token2str (LexState *ls, int token) { + if (token < FIRST_RESERVED) { + lua_assert(token == cast(unsigned char, token)); + return (iscntrl(token)) ? luaO_pushfstring(ls->L, "char(%d)", token) : + luaO_pushfstring(ls->L, "%c", token); + } + else + return luaX_tokens[token-FIRST_RESERVED]; +} + + +static const char *txtToken (LexState *ls, int token) { + switch (token) { + case TK_NAME: + case TK_STRING: + case TK_NUMBER: + save(ls, '\0'); + return luaZ_buffer(ls->buff); + default: + return luaX_token2str(ls, token); + } +} + + +void luaX_lexerror (LexState *ls, const char *msg, int token) { + char buff[MAXSRC]; + luaO_chunkid(buff, getstr(ls->source), MAXSRC); + msg = luaO_pushfstring(ls->L, "%s:%d: %s", buff, ls->linenumber, msg); + if (token) + luaO_pushfstring(ls->L, "%s near " LUA_QS, msg, txtToken(ls, token)); + luaD_throw(ls->L, LUA_ERRSYNTAX); +} + + +void luaX_syntaxerror (LexState *ls, const char *msg) { + luaX_lexerror(ls, msg, ls->t.token); +} + + +TString *luaX_newstring (LexState *ls, const char *str, size_t l) { + lua_State *L = ls->L; + TString *ts = luaS_newlstr(L, str, l); + TValue *o = luaH_setstr(L, ls->fs->h, ts); /* entry for `str' */ + if (ttisnil(o)) + setbvalue(o, 1); /* make sure `str' will not be collected */ + return ts; +} + + +static void inclinenumber (LexState *ls) { + int old = ls->current; + lua_assert(currIsNewline(ls)); + next(ls); /* skip `\n' or `\r' */ + if (currIsNewline(ls) && ls->current != old) + next(ls); /* skip `\n\r' or `\r\n' */ + if (++ls->linenumber >= MAX_INT) + luaX_syntaxerror(ls, "chunk has too many lines"); +} + + +void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source) { + ls->decpoint = '.'; + ls->L = L; + ls->lookahead.token = TK_EOS; /* no look-ahead token */ + ls->z = z; + ls->fs = NULL; + ls->linenumber = 1; + ls->lastline = 1; + ls->source = source; + luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */ + next(ls); /* read first char */ +} + + + +/* +** ======================================================= +** LEXICAL ANALYZER +** ======================================================= +*/ + + + +static int check_next (LexState *ls, const char *set) { + if (!strchr(set, ls->current)) + return 0; + save_and_next(ls); + return 1; +} + + +static void buffreplace (LexState *ls, char from, char to) { + size_t n = luaZ_bufflen(ls->buff); + char *p = luaZ_buffer(ls->buff); + while (n--) + if (p[n] == from) p[n] = to; +} + + +static void trydecpoint (LexState *ls, SemInfo *seminfo) { + /* format error: try to update decimal point separator */ + struct lconv *cv = localeconv(); + char old = ls->decpoint; + ls->decpoint = (cv ? cv->decimal_point[0] : '.'); + buffreplace(ls, old, ls->decpoint); /* try updated decimal separator */ + if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) { + /* format error with correct decimal point: no more options */ + buffreplace(ls, ls->decpoint, '.'); /* undo change (for error message) */ + luaX_lexerror(ls, "malformed number", TK_NUMBER); + } +} + + +/* LUA_NUMBER */ +static void read_numeral (LexState *ls, SemInfo *seminfo) { + lua_assert(isdigit(ls->current)); + do { + save_and_next(ls); + } while (isdigit(ls->current) || ls->current == '.'); + if (check_next(ls, "Ee")) /* `E'? */ + check_next(ls, "+-"); /* optional exponent sign */ + while (isalnum(ls->current) || ls->current == '_') + save_and_next(ls); + save(ls, '\0'); + buffreplace(ls, '.', ls->decpoint); /* follow locale for decimal point */ + if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) /* format error? */ + trydecpoint(ls, seminfo); /* try to update decimal point separator */ +} + + +static int skip_sep (LexState *ls) { + int count = 0; + int s = ls->current; + lua_assert(s == '[' || s == ']'); + save_and_next(ls); + while (ls->current == '=') { + save_and_next(ls); + count++; + } + return (ls->current == s) ? count : (-count) - 1; +} + + +static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) { + int cont = 0; + (void)(cont); /* avoid warnings when `cont' is not used */ + save_and_next(ls); /* skip 2nd `[' */ + if (currIsNewline(ls)) /* string starts with a newline? */ + inclinenumber(ls); /* skip it */ + for (;;) { + switch (ls->current) { + case EOZ: + luaX_lexerror(ls, (seminfo) ? "unfinished long string" : + "unfinished long comment", TK_EOS); + break; /* to avoid warnings */ +#if defined(LUA_COMPAT_LSTR) + case '[': { + if (skip_sep(ls) == sep) { + save_and_next(ls); /* skip 2nd `[' */ + cont++; +#if LUA_COMPAT_LSTR == 1 + if (sep == 0) + luaX_lexerror(ls, "nesting of [[...]] is deprecated", '['); +#endif + } + break; + } +#endif + case ']': { + if (skip_sep(ls) == sep) { + save_and_next(ls); /* skip 2nd `]' */ +#if defined(LUA_COMPAT_LSTR) && LUA_COMPAT_LSTR == 2 + cont--; + if (sep == 0 && cont >= 0) break; +#endif + goto endloop; + } + break; + } + case '\n': + case '\r': { + save(ls, '\n'); + inclinenumber(ls); + if (!seminfo) luaZ_resetbuffer(ls->buff); /* avoid wasting space */ + break; + } + default: { + if (seminfo) save_and_next(ls); + else next(ls); + } + } + } endloop: + if (seminfo) + seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + (2 + sep), + luaZ_bufflen(ls->buff) - 2*(2 + sep)); +} + + +static void read_string (LexState *ls, int del, SemInfo *seminfo) { + save_and_next(ls); + while (ls->current != del) { + switch (ls->current) { + case EOZ: + luaX_lexerror(ls, "unfinished string", TK_EOS); + continue; /* to avoid warnings */ + case '\n': + case '\r': + luaX_lexerror(ls, "unfinished string", TK_STRING); + continue; /* to avoid warnings */ + case '\\': { + int c; + next(ls); /* do not save the `\' */ + switch (ls->current) { + case 'a': c = '\a'; break; + case 'b': c = '\b'; break; + case 'f': c = '\f'; break; + case 'n': c = '\n'; break; + case 'r': c = '\r'; break; + case 't': c = '\t'; break; + case 'v': c = '\v'; break; + case '\n': /* go through */ + case '\r': save(ls, '\n'); inclinenumber(ls); continue; + case EOZ: continue; /* will raise an error next loop */ + default: { + if (!isdigit(ls->current)) + save_and_next(ls); /* handles \\, \", \', and \? */ + else { /* \xxx */ + int i = 0; + c = 0; + do { + c = 10*c + (ls->current-'0'); + next(ls); + } while (++i<3 && isdigit(ls->current)); + if (c > UCHAR_MAX) + luaX_lexerror(ls, "escape sequence too large", TK_STRING); + save(ls, c); + } + continue; + } + } + save(ls, c); + next(ls); + continue; + } + default: + save_and_next(ls); + } + } + save_and_next(ls); /* skip delimiter */ + seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + 1, + luaZ_bufflen(ls->buff) - 2); +} + + +static int llex (LexState *ls, SemInfo *seminfo) { + luaZ_resetbuffer(ls->buff); + for (;;) { + switch (ls->current) { + case '\n': + case '\r': { + inclinenumber(ls); + continue; + } + case '-': { + next(ls); + if (ls->current != '-') return '-'; + /* else is a comment */ + next(ls); + if (ls->current == '[') { + int sep = skip_sep(ls); + luaZ_resetbuffer(ls->buff); /* `skip_sep' may dirty the buffer */ + if (sep >= 0) { + read_long_string(ls, NULL, sep); /* long comment */ + luaZ_resetbuffer(ls->buff); + continue; + } + } + /* else short comment */ + while (!currIsNewline(ls) && ls->current != EOZ) + next(ls); + continue; + } + case '[': { + int sep = skip_sep(ls); + if (sep >= 0) { + read_long_string(ls, seminfo, sep); + return TK_STRING; + } + else if (sep == -1) return '['; + else luaX_lexerror(ls, "invalid long string delimiter", TK_STRING); + } + case '=': { + next(ls); + if (ls->current != '=') return '='; + else { next(ls); return TK_EQ; } + } + case '<': { + next(ls); + if (ls->current != '=') return '<'; + else { next(ls); return TK_LE; } + } + case '>': { + next(ls); + if (ls->current != '=') return '>'; + else { next(ls); return TK_GE; } + } + case '~': { + next(ls); + if (ls->current != '=') return '~'; + else { next(ls); return TK_NE; } + } + case '"': + case '\'': { + read_string(ls, ls->current, seminfo); + return TK_STRING; + } + case '.': { + save_and_next(ls); + if (check_next(ls, ".")) { + if (check_next(ls, ".")) + return TK_DOTS; /* ... */ + else return TK_CONCAT; /* .. */ + } + else if (!isdigit(ls->current)) return '.'; + else { + read_numeral(ls, seminfo); + return TK_NUMBER; + } + } + case EOZ: { + return TK_EOS; + } + default: { + if (isspace(ls->current)) { + lua_assert(!currIsNewline(ls)); + next(ls); + continue; + } + else if (isdigit(ls->current)) { + read_numeral(ls, seminfo); + return TK_NUMBER; + } + else if (isalpha(ls->current) || ls->current == '_') { + /* identifier or reserved word */ + TString *ts; + do { + save_and_next(ls); + } while (isalnum(ls->current) || ls->current == '_'); + ts = luaX_newstring(ls, luaZ_buffer(ls->buff), + luaZ_bufflen(ls->buff)); + if (ts->tsv.reserved > 0) /* reserved word? */ + return ts->tsv.reserved - 1 + FIRST_RESERVED; + else { + seminfo->ts = ts; + return TK_NAME; + } + } + else { + int c = ls->current; + next(ls); + return c; /* single-char tokens (+ - / ...) */ + } + } + } + } +} + + +void luaX_next (LexState *ls) { + ls->lastline = ls->linenumber; + if (ls->lookahead.token != TK_EOS) { /* is there a look-ahead token? */ + ls->t = ls->lookahead; /* use this one */ + ls->lookahead.token = TK_EOS; /* and discharge it */ + } + else + ls->t.token = llex(ls, &ls->t.seminfo); /* read next token */ +} + + +void luaX_lookahead (LexState *ls) { + lua_assert(ls->lookahead.token == TK_EOS); + ls->lookahead.token = llex(ls, &ls->lookahead.seminfo); +} + diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/src/llex.h b/mod/pub.mod/lua.mod/lua-5.1.4/src/llex.h new file mode 100644 index 0000000..a9201ce --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/src/llex.h @@ -0,0 +1,81 @@ +/* +** $Id: llex.h,v 1.58.1.1 2007/12/27 13:02:25 roberto Exp $ +** Lexical Analyzer +** See Copyright Notice in lua.h +*/ + +#ifndef llex_h +#define llex_h + +#include "lobject.h" +#include "lzio.h" + + +#define FIRST_RESERVED 257 + +/* maximum length of a reserved word */ +#define TOKEN_LEN (sizeof("function")/sizeof(char)) + + +/* +* WARNING: if you change the order of this enumeration, +* grep "ORDER RESERVED" +*/ +enum RESERVED { + /* terminal symbols denoted by reserved words */ + TK_AND = FIRST_RESERVED, TK_BREAK, + TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION, + TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT, + TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE, + /* other terminal symbols */ + TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_NUMBER, + TK_NAME, TK_STRING, TK_EOS +}; + +/* number of reserved words */ +#define NUM_RESERVED (cast(int, TK_WHILE-FIRST_RESERVED+1)) + + +/* array with token `names' */ +LUAI_DATA const char *const luaX_tokens []; + + +typedef union { + lua_Number r; + TString *ts; +} SemInfo; /* semantics information */ + + +typedef struct Token { + int token; + SemInfo seminfo; +} Token; + + +typedef struct LexState { + int current; /* current character (charint) */ + int linenumber; /* input line counter */ + int lastline; /* line of last token `consumed' */ + Token t; /* current token */ + Token lookahead; /* look ahead token */ + struct FuncState *fs; /* `FuncState' is private to the parser */ + struct lua_State *L; + ZIO *z; /* input stream */ + Mbuffer *buff; /* buffer for tokens */ + TString *source; /* current source name */ + char decpoint; /* locale decimal point */ +} LexState; + + +LUAI_FUNC void luaX_init (lua_State *L); +LUAI_FUNC void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, + TString *source); +LUAI_FUNC TString *luaX_newstring (LexState *ls, const char *str, size_t l); +LUAI_FUNC void luaX_next (LexState *ls); +LUAI_FUNC void luaX_lookahead (LexState *ls); +LUAI_FUNC void luaX_lexerror (LexState *ls, const char *msg, int token); +LUAI_FUNC void luaX_syntaxerror (LexState *ls, const char *s); +LUAI_FUNC const char *luaX_token2str (LexState *ls, int token); + + +#endif diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/src/llimits.h b/mod/pub.mod/lua.mod/lua-5.1.4/src/llimits.h new file mode 100644 index 0000000..ca8dcb7 --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/src/llimits.h @@ -0,0 +1,128 @@ +/* +** $Id: llimits.h,v 1.69.1.1 2007/12/27 13:02:25 roberto Exp $ +** Limits, basic types, and some other `installation-dependent' definitions +** See Copyright Notice in lua.h +*/ + +#ifndef llimits_h +#define llimits_h + + +#include +#include + + +#include "lua.h" + + +typedef LUAI_UINT32 lu_int32; + +typedef LUAI_UMEM lu_mem; + +typedef LUAI_MEM l_mem; + + + +/* chars used as small naturals (so that `char' is reserved for characters) */ +typedef unsigned char lu_byte; + + +#define MAX_SIZET ((size_t)(~(size_t)0)-2) + +#define MAX_LUMEM ((lu_mem)(~(lu_mem)0)-2) + + +#define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */ + +/* +** conversion of pointer to integer +** this is for hashing only; there is no problem if the integer +** cannot hold the whole pointer value +*/ +#define IntPoint(p) ((unsigned int)(lu_mem)(p)) + + + +/* type to ensure maximum alignment */ +typedef LUAI_USER_ALIGNMENT_T L_Umaxalign; + + +/* result of a `usual argument conversion' over lua_Number */ +typedef LUAI_UACNUMBER l_uacNumber; + + +/* internal assertions for in-house debugging */ +#ifdef lua_assert + +#define check_exp(c,e) (lua_assert(c), (e)) +#define api_check(l,e) lua_assert(e) + +#else + +#define lua_assert(c) ((void)0) +#define check_exp(c,e) (e) +#define api_check luai_apicheck + +#endif + + +#ifndef UNUSED +#define UNUSED(x) ((void)(x)) /* to avoid warnings */ +#endif + + +#ifndef cast +#define cast(t, exp) ((t)(exp)) +#endif + +#define cast_byte(i) cast(lu_byte, (i)) +#define cast_num(i) cast(lua_Number, (i)) +#define cast_int(i) cast(int, (i)) + + + +/* +** type for virtual-machine instructions +** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h) +*/ +typedef lu_int32 Instruction; + + + +/* maximum stack for a Lua function */ +#define MAXSTACK 250 + + + +/* minimum size for the string table (must be power of 2) */ +#ifndef MINSTRTABSIZE +#define MINSTRTABSIZE 32 +#endif + + +/* minimum size for string buffer */ +#ifndef LUA_MINBUFFER +#define LUA_MINBUFFER 32 +#endif + + +#ifndef lua_lock +#define lua_lock(L) ((void) 0) +#define lua_unlock(L) ((void) 0) +#endif + +#ifndef luai_threadyield +#define luai_threadyield(L) {lua_unlock(L); lua_lock(L);} +#endif + + +/* +** macro to control inclusion of some hard tests on stack reallocation +*/ +#ifndef HARDSTACKTESTS +#define condhardstacktests(x) ((void)0) +#else +#define condhardstacktests(x) x +#endif + +#endif diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/src/lmathlib.c b/mod/pub.mod/lua.mod/lua-5.1.4/src/lmathlib.c new file mode 100644 index 0000000..441fbf7 --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/src/lmathlib.c @@ -0,0 +1,263 @@ +/* +** $Id: lmathlib.c,v 1.67.1.1 2007/12/27 13:02:25 roberto Exp $ +** Standard mathematical library +** See Copyright Notice in lua.h +*/ + + +#include +#include + +#define lmathlib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +#undef PI +#define PI (3.14159265358979323846) +#define RADIANS_PER_DEGREE (PI/180.0) + + + +static int math_abs (lua_State *L) { + lua_pushnumber(L, fabs(luaL_checknumber(L, 1))); + return 1; +} + +static int math_sin (lua_State *L) { + lua_pushnumber(L, sin(luaL_checknumber(L, 1))); + return 1; +} + +static int math_sinh (lua_State *L) { + lua_pushnumber(L, sinh(luaL_checknumber(L, 1))); + return 1; +} + +static int math_cos (lua_State *L) { + lua_pushnumber(L, cos(luaL_checknumber(L, 1))); + return 1; +} + +static int math_cosh (lua_State *L) { + lua_pushnumber(L, cosh(luaL_checknumber(L, 1))); + return 1; +} + +static int math_tan (lua_State *L) { + lua_pushnumber(L, tan(luaL_checknumber(L, 1))); + return 1; +} + +static int math_tanh (lua_State *L) { + lua_pushnumber(L, tanh(luaL_checknumber(L, 1))); + return 1; +} + +static int math_asin (lua_State *L) { + lua_pushnumber(L, asin(luaL_checknumber(L, 1))); + return 1; +} + +static int math_acos (lua_State *L) { + lua_pushnumber(L, acos(luaL_checknumber(L, 1))); + return 1; +} + +static int math_atan (lua_State *L) { + lua_pushnumber(L, atan(luaL_checknumber(L, 1))); + return 1; +} + +static int math_atan2 (lua_State *L) { + lua_pushnumber(L, atan2(luaL_checknumber(L, 1), luaL_checknumber(L, 2))); + return 1; +} + +static int math_ceil (lua_State *L) { + lua_pushnumber(L, ceil(luaL_checknumber(L, 1))); + return 1; +} + +static int math_floor (lua_State *L) { + lua_pushnumber(L, floor(luaL_checknumber(L, 1))); + return 1; +} + +static int math_fmod (lua_State *L) { + lua_pushnumber(L, fmod(luaL_checknumber(L, 1), luaL_checknumber(L, 2))); + return 1; +} + +static int math_modf (lua_State *L) { + double ip; + double fp = modf(luaL_checknumber(L, 1), &ip); + lua_pushnumber(L, ip); + lua_pushnumber(L, fp); + return 2; +} + +static int math_sqrt (lua_State *L) { + lua_pushnumber(L, sqrt(luaL_checknumber(L, 1))); + return 1; +} + +static int math_pow (lua_State *L) { + lua_pushnumber(L, pow(luaL_checknumber(L, 1), luaL_checknumber(L, 2))); + return 1; +} + +static int math_log (lua_State *L) { + lua_pushnumber(L, log(luaL_checknumber(L, 1))); + return 1; +} + +static int math_log10 (lua_State *L) { + lua_pushnumber(L, log10(luaL_checknumber(L, 1))); + return 1; +} + +static int math_exp (lua_State *L) { + lua_pushnumber(L, exp(luaL_checknumber(L, 1))); + return 1; +} + +static int math_deg (lua_State *L) { + lua_pushnumber(L, luaL_checknumber(L, 1)/RADIANS_PER_DEGREE); + return 1; +} + +static int math_rad (lua_State *L) { + lua_pushnumber(L, luaL_checknumber(L, 1)*RADIANS_PER_DEGREE); + return 1; +} + +static int math_frexp (lua_State *L) { + int e; + lua_pushnumber(L, frexp(luaL_checknumber(L, 1), &e)); + lua_pushinteger(L, e); + return 2; +} + +static int math_ldexp (lua_State *L) { + lua_pushnumber(L, ldexp(luaL_checknumber(L, 1), luaL_checkint(L, 2))); + return 1; +} + + + +static int math_min (lua_State *L) { + int n = lua_gettop(L); /* number of arguments */ + lua_Number dmin = luaL_checknumber(L, 1); + int i; + for (i=2; i<=n; i++) { + lua_Number d = luaL_checknumber(L, i); + if (d < dmin) + dmin = d; + } + lua_pushnumber(L, dmin); + return 1; +} + + +static int math_max (lua_State *L) { + int n = lua_gettop(L); /* number of arguments */ + lua_Number dmax = luaL_checknumber(L, 1); + int i; + for (i=2; i<=n; i++) { + lua_Number d = luaL_checknumber(L, i); + if (d > dmax) + dmax = d; + } + lua_pushnumber(L, dmax); + return 1; +} + + +static int math_random (lua_State *L) { + /* the `%' avoids the (rare) case of r==1, and is needed also because on + some systems (SunOS!) `rand()' may return a value larger than RAND_MAX */ + lua_Number r = (lua_Number)(rand()%RAND_MAX) / (lua_Number)RAND_MAX; + switch (lua_gettop(L)) { /* check number of arguments */ + case 0: { /* no arguments */ + lua_pushnumber(L, r); /* Number between 0 and 1 */ + break; + } + case 1: { /* only upper limit */ + int u = luaL_checkint(L, 1); + luaL_argcheck(L, 1<=u, 1, "interval is empty"); + lua_pushnumber(L, floor(r*u)+1); /* int between 1 and `u' */ + break; + } + case 2: { /* lower and upper limits */ + int l = luaL_checkint(L, 1); + int u = luaL_checkint(L, 2); + luaL_argcheck(L, l<=u, 2, "interval is empty"); + lua_pushnumber(L, floor(r*(u-l+1))+l); /* int between `l' and `u' */ + break; + } + default: return luaL_error(L, "wrong number of arguments"); + } + return 1; +} + + +static int math_randomseed (lua_State *L) { + srand(luaL_checkint(L, 1)); + return 0; +} + + +static const luaL_Reg mathlib[] = { + {"abs", math_abs}, + {"acos", math_acos}, + {"asin", math_asin}, + {"atan2", math_atan2}, + {"atan", math_atan}, + {"ceil", math_ceil}, + {"cosh", math_cosh}, + {"cos", math_cos}, + {"deg", math_deg}, + {"exp", math_exp}, + {"floor", math_floor}, + {"fmod", math_fmod}, + {"frexp", math_frexp}, + {"ldexp", math_ldexp}, + {"log10", math_log10}, + {"log", math_log}, + {"max", math_max}, + {"min", math_min}, + {"modf", math_modf}, + {"pow", math_pow}, + {"rad", math_rad}, + {"random", math_random}, + {"randomseed", math_randomseed}, + {"sinh", math_sinh}, + {"sin", math_sin}, + {"sqrt", math_sqrt}, + {"tanh", math_tanh}, + {"tan", math_tan}, + {NULL, NULL} +}; + + +/* +** Open math library +*/ +LUALIB_API int luaopen_math (lua_State *L) { + luaL_register(L, LUA_MATHLIBNAME, mathlib); + lua_pushnumber(L, PI); + lua_setfield(L, -2, "pi"); + lua_pushnumber(L, HUGE_VAL); + lua_setfield(L, -2, "huge"); +#if defined(LUA_COMPAT_MOD) + lua_getfield(L, -1, "fmod"); + lua_setfield(L, -2, "mod"); +#endif + return 1; +} + diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/src/lmem.c b/mod/pub.mod/lua.mod/lua-5.1.4/src/lmem.c new file mode 100644 index 0000000..ae7d8c9 --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/src/lmem.c @@ -0,0 +1,86 @@ +/* +** $Id: lmem.c,v 1.70.1.1 2007/12/27 13:02:25 roberto Exp $ +** Interface to Memory Manager +** See Copyright Notice in lua.h +*/ + + +#include + +#define lmem_c +#define LUA_CORE + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" + + + +/* +** About the realloc function: +** void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize); +** (`osize' is the old size, `nsize' is the new size) +** +** Lua ensures that (ptr == NULL) iff (osize == 0). +** +** * frealloc(ud, NULL, 0, x) creates a new block of size `x' +** +** * frealloc(ud, p, x, 0) frees the block `p' +** (in this specific case, frealloc must return NULL). +** particularly, frealloc(ud, NULL, 0, 0) does nothing +** (which is equivalent to free(NULL) in ANSI C) +** +** frealloc returns NULL if it cannot create or reallocate the area +** (any reallocation to an equal or smaller size cannot fail!) +*/ + + + +#define MINSIZEARRAY 4 + + +void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elems, + int limit, const char *errormsg) { + void *newblock; + int newsize; + if (*size >= limit/2) { /* cannot double it? */ + if (*size >= limit) /* cannot grow even a little? */ + luaG_runerror(L, errormsg); + newsize = limit; /* still have at least one free place */ + } + else { + newsize = (*size)*2; + if (newsize < MINSIZEARRAY) + newsize = MINSIZEARRAY; /* minimum size */ + } + newblock = luaM_reallocv(L, block, *size, newsize, size_elems); + *size = newsize; /* update only when everything else is OK */ + return newblock; +} + + +void *luaM_toobig (lua_State *L) { + luaG_runerror(L, "memory allocation error: block too big"); + return NULL; /* to avoid warnings */ +} + + + +/* +** generic allocation routine. +*/ +void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) { + global_State *g = G(L); + lua_assert((osize == 0) == (block == NULL)); + block = (*g->frealloc)(g->ud, block, osize, nsize); + if (block == NULL && nsize > 0) + luaD_throw(L, LUA_ERRMEM); + lua_assert((nsize == 0) == (block == NULL)); + g->totalbytes = (g->totalbytes - osize) + nsize; + return block; +} + diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/src/lmem.h b/mod/pub.mod/lua.mod/lua-5.1.4/src/lmem.h new file mode 100644 index 0000000..7c2dcb3 --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/src/lmem.h @@ -0,0 +1,49 @@ +/* +** $Id: lmem.h,v 1.31.1.1 2007/12/27 13:02:25 roberto Exp $ +** Interface to Memory Manager +** See Copyright Notice in lua.h +*/ + +#ifndef lmem_h +#define lmem_h + + +#include + +#include "llimits.h" +#include "lua.h" + +#define MEMERRMSG "not enough memory" + + +#define luaM_reallocv(L,b,on,n,e) \ + ((cast(size_t, (n)+1) <= MAX_SIZET/(e)) ? /* +1 to avoid warnings */ \ + luaM_realloc_(L, (b), (on)*(e), (n)*(e)) : \ + luaM_toobig(L)) + +#define luaM_freemem(L, b, s) luaM_realloc_(L, (b), (s), 0) +#define luaM_free(L, b) luaM_realloc_(L, (b), sizeof(*(b)), 0) +#define luaM_freearray(L, b, n, t) luaM_reallocv(L, (b), n, 0, sizeof(t)) + +#define luaM_malloc(L,t) luaM_realloc_(L, NULL, 0, (t)) +#define luaM_new(L,t) cast(t *, luaM_malloc(L, sizeof(t))) +#define luaM_newvector(L,n,t) \ + cast(t *, luaM_reallocv(L, NULL, 0, n, sizeof(t))) + +#define luaM_growvector(L,v,nelems,size,t,limit,e) \ + if ((nelems)+1 > (size)) \ + ((v)=cast(t *, luaM_growaux_(L,v,&(size),sizeof(t),limit,e))) + +#define luaM_reallocvector(L, v,oldn,n,t) \ + ((v)=cast(t *, luaM_reallocv(L, v, oldn, n, sizeof(t)))) + + +LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize, + size_t size); +LUAI_FUNC void *luaM_toobig (lua_State *L); +LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int *size, + size_t size_elem, int limit, + const char *errormsg); + +#endif + diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/src/loadlib.c b/mod/pub.mod/lua.mod/lua-5.1.4/src/loadlib.c new file mode 100644 index 0000000..0d401eb --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/src/loadlib.c @@ -0,0 +1,666 @@ +/* +** $Id: loadlib.c,v 1.52.1.3 2008/08/06 13:29:28 roberto Exp $ +** Dynamic library loader for Lua +** See Copyright Notice in lua.h +** +** This module contains an implementation of loadlib for Unix systems +** that have dlfcn, an implementation for Darwin (Mac OS X), an +** implementation for Windows, and a stub for other systems. +*/ + + +#include +#include + + +#define loadlib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +/* prefix for open functions in C libraries */ +#define LUA_POF "luaopen_" + +/* separator for open functions in C libraries */ +#define LUA_OFSEP "_" + + +#define LIBPREFIX "LOADLIB: " + +#define POF LUA_POF +#define LIB_FAIL "open" + + +/* error codes for ll_loadfunc */ +#define ERRLIB 1 +#define ERRFUNC 2 + +#define setprogdir(L) ((void)0) + + +static void ll_unloadlib (void *lib); +static void *ll_load (lua_State *L, const char *path); +static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym); + + + +#if defined(LUA_DL_DLOPEN) +/* +** {======================================================================== +** This is an implementation of loadlib based on the dlfcn interface. +** The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD, +** NetBSD, AIX 4.2, HPUX 11, and probably most other Unix flavors, at least +** as an emulation layer on top of native functions. +** ========================================================================= +*/ + +#include + +static void ll_unloadlib (void *lib) { + dlclose(lib); +} + + +static void *ll_load (lua_State *L, const char *path) { + void *lib = dlopen(path, RTLD_NOW); + if (lib == NULL) lua_pushstring(L, dlerror()); + return lib; +} + + +static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { + lua_CFunction f = (lua_CFunction)dlsym(lib, sym); + if (f == NULL) lua_pushstring(L, dlerror()); + return f; +} + +/* }====================================================== */ + + + +#elif defined(LUA_DL_DLL) +/* +** {====================================================================== +** This is an implementation of loadlib for Windows using native functions. +** ======================================================================= +*/ + +#include + + +#undef setprogdir + +static void setprogdir (lua_State *L) { + char buff[MAX_PATH + 1]; + char *lb; + DWORD nsize = sizeof(buff)/sizeof(char); + DWORD n = GetModuleFileNameA(NULL, buff, nsize); + if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL) + luaL_error(L, "unable to get ModuleFileName"); + else { + *lb = '\0'; + luaL_gsub(L, lua_tostring(L, -1), LUA_EXECDIR, buff); + lua_remove(L, -2); /* remove original string */ + } +} + + +static void pusherror (lua_State *L) { + int error = GetLastError(); + char buffer[128]; + if (FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, error, 0, buffer, sizeof(buffer), NULL)) + lua_pushstring(L, buffer); + else + lua_pushfstring(L, "system error %d\n", error); +} + +static void ll_unloadlib (void *lib) { + FreeLibrary((HINSTANCE)lib); +} + + +static void *ll_load (lua_State *L, const char *path) { + HINSTANCE lib = LoadLibraryA(path); + if (lib == NULL) pusherror(L); + return lib; +} + + +static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { + lua_CFunction f = (lua_CFunction)GetProcAddress((HINSTANCE)lib, sym); + if (f == NULL) pusherror(L); + return f; +} + +/* }====================================================== */ + + + +#elif defined(LUA_DL_DYLD) +/* +** {====================================================================== +** Native Mac OS X / Darwin Implementation +** ======================================================================= +*/ + +#include + + +/* Mac appends a `_' before C function names */ +#undef POF +#define POF "_" LUA_POF + + +static void pusherror (lua_State *L) { + const char *err_str; + const char *err_file; + NSLinkEditErrors err; + int err_num; + NSLinkEditError(&err, &err_num, &err_file, &err_str); + lua_pushstring(L, err_str); +} + + +static const char *errorfromcode (NSObjectFileImageReturnCode ret) { + switch (ret) { + case NSObjectFileImageInappropriateFile: + return "file is not a bundle"; + case NSObjectFileImageArch: + return "library is for wrong CPU type"; + case NSObjectFileImageFormat: + return "bad format"; + case NSObjectFileImageAccess: + return "cannot access file"; + case NSObjectFileImageFailure: + default: + return "unable to load library"; + } +} + + +static void ll_unloadlib (void *lib) { + NSUnLinkModule((NSModule)lib, NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES); +} + + +static void *ll_load (lua_State *L, const char *path) { + NSObjectFileImage img; + NSObjectFileImageReturnCode ret; + /* this would be a rare case, but prevents crashing if it happens */ + if(!_dyld_present()) { + lua_pushliteral(L, "dyld not present"); + return NULL; + } + ret = NSCreateObjectFileImageFromFile(path, &img); + if (ret == NSObjectFileImageSuccess) { + NSModule mod = NSLinkModule(img, path, NSLINKMODULE_OPTION_PRIVATE | + NSLINKMODULE_OPTION_RETURN_ON_ERROR); + NSDestroyObjectFileImage(img); + if (mod == NULL) pusherror(L); + return mod; + } + lua_pushstring(L, errorfromcode(ret)); + return NULL; +} + + +static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { + NSSymbol nss = NSLookupSymbolInModule((NSModule)lib, sym); + if (nss == NULL) { + lua_pushfstring(L, "symbol " LUA_QS " not found", sym); + return NULL; + } + return (lua_CFunction)NSAddressOfSymbol(nss); +} + +/* }====================================================== */ + + + +#else +/* +** {====================================================== +** Fallback for other systems +** ======================================================= +*/ + +#undef LIB_FAIL +#define LIB_FAIL "absent" + + +#define DLMSG "dynamic libraries not enabled; check your Lua installation" + + +static void ll_unloadlib (void *lib) { + (void)lib; /* to avoid warnings */ +} + + +static void *ll_load (lua_State *L, const char *path) { + (void)path; /* to avoid warnings */ + lua_pushliteral(L, DLMSG); + return NULL; +} + + +static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { + (void)lib; (void)sym; /* to avoid warnings */ + lua_pushliteral(L, DLMSG); + return NULL; +} + +/* }====================================================== */ +#endif + + + +static void **ll_register (lua_State *L, const char *path) { + void **plib; + lua_pushfstring(L, "%s%s", LIBPREFIX, path); + lua_gettable(L, LUA_REGISTRYINDEX); /* check library in registry? */ + if (!lua_isnil(L, -1)) /* is there an entry? */ + plib = (void **)lua_touserdata(L, -1); + else { /* no entry yet; create one */ + lua_pop(L, 1); + plib = (void **)lua_newuserdata(L, sizeof(const void *)); + *plib = NULL; + luaL_getmetatable(L, "_LOADLIB"); + lua_setmetatable(L, -2); + lua_pushfstring(L, "%s%s", LIBPREFIX, path); + lua_pushvalue(L, -2); + lua_settable(L, LUA_REGISTRYINDEX); + } + return plib; +} + + +/* +** __gc tag method: calls library's `ll_unloadlib' function with the lib +** handle +*/ +static int gctm (lua_State *L) { + void **lib = (void **)luaL_checkudata(L, 1, "_LOADLIB"); + if (*lib) ll_unloadlib(*lib); + *lib = NULL; /* mark library as closed */ + return 0; +} + + +static int ll_loadfunc (lua_State *L, const char *path, const char *sym) { + void **reg = ll_register(L, path); + if (*reg == NULL) *reg = ll_load(L, path); + if (*reg == NULL) + return ERRLIB; /* unable to load library */ + else { + lua_CFunction f = ll_sym(L, *reg, sym); + if (f == NULL) + return ERRFUNC; /* unable to find function */ + lua_pushcfunction(L, f); + return 0; /* return function */ + } +} + + +static int ll_loadlib (lua_State *L) { + const char *path = luaL_checkstring(L, 1); + const char *init = luaL_checkstring(L, 2); + int stat = ll_loadfunc(L, path, init); + if (stat == 0) /* no errors? */ + return 1; /* return the loaded function */ + else { /* error; error message is on stack top */ + lua_pushnil(L); + lua_insert(L, -2); + lua_pushstring(L, (stat == ERRLIB) ? LIB_FAIL : "init"); + return 3; /* return nil, error message, and where */ + } +} + + + +/* +** {====================================================== +** 'require' function +** ======================================================= +*/ + + +static int readable (const char *filename) { + FILE *f = fopen(filename, "r"); /* try to open file */ + if (f == NULL) return 0; /* open failed */ + fclose(f); + return 1; +} + + +static const char *pushnexttemplate (lua_State *L, const char *path) { + const char *l; + while (*path == *LUA_PATHSEP) path++; /* skip separators */ + if (*path == '\0') return NULL; /* no more templates */ + l = strchr(path, *LUA_PATHSEP); /* find next separator */ + if (l == NULL) l = path + strlen(path); + lua_pushlstring(L, path, l - path); /* template */ + return l; +} + + +static const char *findfile (lua_State *L, const char *name, + const char *pname) { + const char *path; + name = luaL_gsub(L, name, ".", LUA_DIRSEP); + lua_getfield(L, LUA_ENVIRONINDEX, pname); + path = lua_tostring(L, -1); + if (path == NULL) + luaL_error(L, LUA_QL("package.%s") " must be a string", pname); + lua_pushliteral(L, ""); /* error accumulator */ + while ((path = pushnexttemplate(L, path)) != NULL) { + const char *filename; + filename = luaL_gsub(L, lua_tostring(L, -1), LUA_PATH_MARK, name); + lua_remove(L, -2); /* remove path template */ + if (readable(filename)) /* does file exist and is readable? */ + return filename; /* return that file name */ + lua_pushfstring(L, "\n\tno file " LUA_QS, filename); + lua_remove(L, -2); /* remove file name */ + lua_concat(L, 2); /* add entry to possible error message */ + } + return NULL; /* not found */ +} + + +static void loaderror (lua_State *L, const char *filename) { + luaL_error(L, "error loading module " LUA_QS " from file " LUA_QS ":\n\t%s", + lua_tostring(L, 1), filename, lua_tostring(L, -1)); +} + + +static int loader_Lua (lua_State *L) { + const char *filename; + const char *name = luaL_checkstring(L, 1); + filename = findfile(L, name, "path"); + if (filename == NULL) return 1; /* library not found in this path */ + if (luaL_loadfile(L, filename) != 0) + loaderror(L, filename); + return 1; /* library loaded successfully */ +} + + +static const char *mkfuncname (lua_State *L, const char *modname) { + const char *funcname; + const char *mark = strchr(modname, *LUA_IGMARK); + if (mark) modname = mark + 1; + funcname = luaL_gsub(L, modname, ".", LUA_OFSEP); + funcname = lua_pushfstring(L, POF"%s", funcname); + lua_remove(L, -2); /* remove 'gsub' result */ + return funcname; +} + + +static int loader_C (lua_State *L) { + const char *funcname; + const char *name = luaL_checkstring(L, 1); + const char *filename = findfile(L, name, "cpath"); + if (filename == NULL) return 1; /* library not found in this path */ + funcname = mkfuncname(L, name); + if (ll_loadfunc(L, filename, funcname) != 0) + loaderror(L, filename); + return 1; /* library loaded successfully */ +} + + +static int loader_Croot (lua_State *L) { + const char *funcname; + const char *filename; + const char *name = luaL_checkstring(L, 1); + const char *p = strchr(name, '.'); + int stat; + if (p == NULL) return 0; /* is root */ + lua_pushlstring(L, name, p - name); + filename = findfile(L, lua_tostring(L, -1), "cpath"); + if (filename == NULL) return 1; /* root not found */ + funcname = mkfuncname(L, name); + if ((stat = ll_loadfunc(L, filename, funcname)) != 0) { + if (stat != ERRFUNC) loaderror(L, filename); /* real error */ + lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS, + name, filename); + return 1; /* function not found */ + } + return 1; +} + + +static int loader_preload (lua_State *L) { + const char *name = luaL_checkstring(L, 1); + lua_getfield(L, LUA_ENVIRONINDEX, "preload"); + if (!lua_istable(L, -1)) + luaL_error(L, LUA_QL("package.preload") " must be a table"); + lua_getfield(L, -1, name); + if (lua_isnil(L, -1)) /* not found? */ + lua_pushfstring(L, "\n\tno field package.preload['%s']", name); + return 1; +} + + +static const int sentinel_ = 0; +#define sentinel ((void *)&sentinel_) + + +static int ll_require (lua_State *L) { + const char *name = luaL_checkstring(L, 1); + int i; + lua_settop(L, 1); /* _LOADED table will be at index 2 */ + lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); + lua_getfield(L, 2, name); + if (lua_toboolean(L, -1)) { /* is it there? */ + if (lua_touserdata(L, -1) == sentinel) /* check loops */ + luaL_error(L, "loop or previous error loading module " LUA_QS, name); + return 1; /* package is already loaded */ + } + /* else must load it; iterate over available loaders */ + lua_getfield(L, LUA_ENVIRONINDEX, "loaders"); + if (!lua_istable(L, -1)) + luaL_error(L, LUA_QL("package.loaders") " must be a table"); + lua_pushliteral(L, ""); /* error message accumulator */ + for (i=1; ; i++) { + lua_rawgeti(L, -2, i); /* get a loader */ + if (lua_isnil(L, -1)) + luaL_error(L, "module " LUA_QS " not found:%s", + name, lua_tostring(L, -2)); + lua_pushstring(L, name); + lua_call(L, 1, 1); /* call it */ + if (lua_isfunction(L, -1)) /* did it find module? */ + break; /* module loaded successfully */ + else if (lua_isstring(L, -1)) /* loader returned error message? */ + lua_concat(L, 2); /* accumulate it */ + else + lua_pop(L, 1); + } + lua_pushlightuserdata(L, sentinel); + lua_setfield(L, 2, name); /* _LOADED[name] = sentinel */ + lua_pushstring(L, name); /* pass name as argument to module */ + lua_call(L, 1, 1); /* run loaded module */ + if (!lua_isnil(L, -1)) /* non-nil return? */ + lua_setfield(L, 2, name); /* _LOADED[name] = returned value */ + lua_getfield(L, 2, name); + if (lua_touserdata(L, -1) == sentinel) { /* module did not set a value? */ + lua_pushboolean(L, 1); /* use true as result */ + lua_pushvalue(L, -1); /* extra copy to be returned */ + lua_setfield(L, 2, name); /* _LOADED[name] = true */ + } + return 1; +} + +/* }====================================================== */ + + + +/* +** {====================================================== +** 'module' function +** ======================================================= +*/ + + +static void setfenv (lua_State *L) { + lua_Debug ar; + if (lua_getstack(L, 1, &ar) == 0 || + lua_getinfo(L, "f", &ar) == 0 || /* get calling function */ + lua_iscfunction(L, -1)) + luaL_error(L, LUA_QL("module") " not called from a Lua function"); + lua_pushvalue(L, -2); + lua_setfenv(L, -2); + lua_pop(L, 1); +} + + +static void dooptions (lua_State *L, int n) { + int i; + for (i = 2; i <= n; i++) { + lua_pushvalue(L, i); /* get option (a function) */ + lua_pushvalue(L, -2); /* module */ + lua_call(L, 1, 0); + } +} + + +static void modinit (lua_State *L, const char *modname) { + const char *dot; + lua_pushvalue(L, -1); + lua_setfield(L, -2, "_M"); /* module._M = module */ + lua_pushstring(L, modname); + lua_setfield(L, -2, "_NAME"); + dot = strrchr(modname, '.'); /* look for last dot in module name */ + if (dot == NULL) dot = modname; + else dot++; + /* set _PACKAGE as package name (full module name minus last part) */ + lua_pushlstring(L, modname, dot - modname); + lua_setfield(L, -2, "_PACKAGE"); +} + + +static int ll_module (lua_State *L) { + const char *modname = luaL_checkstring(L, 1); + int loaded = lua_gettop(L) + 1; /* index of _LOADED table */ + lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); + lua_getfield(L, loaded, modname); /* get _LOADED[modname] */ + if (!lua_istable(L, -1)) { /* not found? */ + lua_pop(L, 1); /* remove previous result */ + /* try global variable (and create one if it does not exist) */ + if (luaL_findtable(L, LUA_GLOBALSINDEX, modname, 1) != NULL) + return luaL_error(L, "name conflict for module " LUA_QS, modname); + lua_pushvalue(L, -1); + lua_setfield(L, loaded, modname); /* _LOADED[modname] = new table */ + } + /* check whether table already has a _NAME field */ + lua_getfield(L, -1, "_NAME"); + if (!lua_isnil(L, -1)) /* is table an initialized module? */ + lua_pop(L, 1); + else { /* no; initialize it */ + lua_pop(L, 1); + modinit(L, modname); + } + lua_pushvalue(L, -1); + setfenv(L); + dooptions(L, loaded - 1); + return 0; +} + + +static int ll_seeall (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + if (!lua_getmetatable(L, 1)) { + lua_createtable(L, 0, 1); /* create new metatable */ + lua_pushvalue(L, -1); + lua_setmetatable(L, 1); + } + lua_pushvalue(L, LUA_GLOBALSINDEX); + lua_setfield(L, -2, "__index"); /* mt.__index = _G */ + return 0; +} + + +/* }====================================================== */ + + + +/* auxiliary mark (for internal use) */ +#define AUXMARK "\1" + +static void setpath (lua_State *L, const char *fieldname, const char *envname, + const char *def) { + const char *path = getenv(envname); + if (path == NULL) /* no environment variable? */ + lua_pushstring(L, def); /* use default */ + else { + /* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */ + path = luaL_gsub(L, path, LUA_PATHSEP LUA_PATHSEP, + LUA_PATHSEP AUXMARK LUA_PATHSEP); + luaL_gsub(L, path, AUXMARK, def); + lua_remove(L, -2); + } + setprogdir(L); + lua_setfield(L, -2, fieldname); +} + + +static const luaL_Reg pk_funcs[] = { + {"loadlib", ll_loadlib}, + {"seeall", ll_seeall}, + {NULL, NULL} +}; + + +static const luaL_Reg ll_funcs[] = { + {"module", ll_module}, + {"require", ll_require}, + {NULL, NULL} +}; + + +static const lua_CFunction loaders[] = + {loader_preload, loader_Lua, loader_C, loader_Croot, NULL}; + + +LUALIB_API int luaopen_package (lua_State *L) { + int i; + /* create new type _LOADLIB */ + luaL_newmetatable(L, "_LOADLIB"); + lua_pushcfunction(L, gctm); + lua_setfield(L, -2, "__gc"); + /* create `package' table */ + luaL_register(L, LUA_LOADLIBNAME, pk_funcs); +#if defined(LUA_COMPAT_LOADLIB) + lua_getfield(L, -1, "loadlib"); + lua_setfield(L, LUA_GLOBALSINDEX, "loadlib"); +#endif + lua_pushvalue(L, -1); + lua_replace(L, LUA_ENVIRONINDEX); + /* create `loaders' table */ + lua_createtable(L, 0, sizeof(loaders)/sizeof(loaders[0]) - 1); + /* fill it with pre-defined loaders */ + for (i=0; loaders[i] != NULL; i++) { + lua_pushcfunction(L, loaders[i]); + lua_rawseti(L, -2, i+1); + } + lua_setfield(L, -2, "loaders"); /* put it in field `loaders' */ + setpath(L, "path", LUA_PATH, LUA_PATH_DEFAULT); /* set field `path' */ + setpath(L, "cpath", LUA_CPATH, LUA_CPATH_DEFAULT); /* set field `cpath' */ + /* store config information */ + lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATHSEP "\n" LUA_PATH_MARK "\n" + LUA_EXECDIR "\n" LUA_IGMARK); + lua_setfield(L, -2, "config"); + /* set field `loaded' */ + luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 2); + lua_setfield(L, -2, "loaded"); + /* set field `preload' */ + lua_newtable(L); + lua_setfield(L, -2, "preload"); + lua_pushvalue(L, LUA_GLOBALSINDEX); + luaL_register(L, NULL, ll_funcs); /* open lib into global table */ + lua_pop(L, 1); + return 1; /* return 'package' table */ +} + diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/src/lobject.c b/mod/pub.mod/lua.mod/lua-5.1.4/src/lobject.c new file mode 100644 index 0000000..4ff5073 --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/src/lobject.c @@ -0,0 +1,214 @@ +/* +** $Id: lobject.c,v 2.22.1.1 2007/12/27 13:02:25 roberto Exp $ +** Some generic functions over Lua objects +** See Copyright Notice in lua.h +*/ + +#include +#include +#include +#include +#include + +#define lobject_c +#define LUA_CORE + +#include "lua.h" + +#include "ldo.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" +#include "lvm.h" + + + +const TValue luaO_nilobject_ = {{NULL}, LUA_TNIL}; + + +/* +** converts an integer to a "floating point byte", represented as +** (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if +** eeeee != 0 and (xxx) otherwise. +*/ +int luaO_int2fb (unsigned int x) { + int e = 0; /* expoent */ + while (x >= 16) { + x = (x+1) >> 1; + e++; + } + if (x < 8) return x; + else return ((e+1) << 3) | (cast_int(x) - 8); +} + + +/* converts back */ +int luaO_fb2int (int x) { + int e = (x >> 3) & 31; + if (e == 0) return x; + else return ((x & 7)+8) << (e - 1); +} + + +int luaO_log2 (unsigned int x) { + static const lu_byte log_2[256] = { + 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8 + }; + int l = -1; + while (x >= 256) { l += 8; x >>= 8; } + return l + log_2[x]; + +} + + +int luaO_rawequalObj (const TValue *t1, const TValue *t2) { + if (ttype(t1) != ttype(t2)) return 0; + else switch (ttype(t1)) { + case LUA_TNIL: + return 1; + case LUA_TNUMBER: + return luai_numeq(nvalue(t1), nvalue(t2)); + case LUA_TBOOLEAN: + return bvalue(t1) == bvalue(t2); /* boolean true must be 1 !! */ + case LUA_TLIGHTUSERDATA: + return pvalue(t1) == pvalue(t2); + default: + lua_assert(iscollectable(t1)); + return gcvalue(t1) == gcvalue(t2); + } +} + + +int luaO_str2d (const char *s, lua_Number *result) { + char *endptr; + *result = lua_str2number(s, &endptr); + if (endptr == s) return 0; /* conversion failed */ + if (*endptr == 'x' || *endptr == 'X') /* maybe an hexadecimal constant? */ + *result = cast_num(strtoul(s, &endptr, 16)); + if (*endptr == '\0') return 1; /* most common case */ + while (isspace(cast(unsigned char, *endptr))) endptr++; + if (*endptr != '\0') return 0; /* invalid trailing characters? */ + return 1; +} + + + +static void pushstr (lua_State *L, const char *str) { + setsvalue2s(L, L->top, luaS_new(L, str)); + incr_top(L); +} + + +/* this function handles only `%d', `%c', %f, %p, and `%s' formats */ +const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { + int n = 1; + pushstr(L, ""); + for (;;) { + const char *e = strchr(fmt, '%'); + if (e == NULL) break; + setsvalue2s(L, L->top, luaS_newlstr(L, fmt, e-fmt)); + incr_top(L); + switch (*(e+1)) { + case 's': { + const char *s = va_arg(argp, char *); + if (s == NULL) s = "(null)"; + pushstr(L, s); + break; + } + case 'c': { + char buff[2]; + buff[0] = cast(char, va_arg(argp, int)); + buff[1] = '\0'; + pushstr(L, buff); + break; + } + case 'd': { + setnvalue(L->top, cast_num(va_arg(argp, int))); + incr_top(L); + break; + } + case 'f': { + setnvalue(L->top, cast_num(va_arg(argp, l_uacNumber))); + incr_top(L); + break; + } + case 'p': { + char buff[4*sizeof(void *) + 8]; /* should be enough space for a `%p' */ + sprintf(buff, "%p", va_arg(argp, void *)); + pushstr(L, buff); + break; + } + case '%': { + pushstr(L, "%"); + break; + } + default: { + char buff[3]; + buff[0] = '%'; + buff[1] = *(e+1); + buff[2] = '\0'; + pushstr(L, buff); + break; + } + } + n += 2; + fmt = e+2; + } + pushstr(L, fmt); + luaV_concat(L, n+1, cast_int(L->top - L->base) - 1); + L->top -= n; + return svalue(L->top - 1); +} + + +const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) { + const char *msg; + va_list argp; + va_start(argp, fmt); + msg = luaO_pushvfstring(L, fmt, argp); + va_end(argp); + return msg; +} + + +void luaO_chunkid (char *out, const char *source, size_t bufflen) { + if (*source == '=') { + strncpy(out, source+1, bufflen); /* remove first char */ + out[bufflen-1] = '\0'; /* ensures null termination */ + } + else { /* out = "source", or "...source" */ + if (*source == '@') { + size_t l; + source++; /* skip the `@' */ + bufflen -= sizeof(" '...' "); + l = strlen(source); + strcpy(out, ""); + if (l > bufflen) { + source += (l-bufflen); /* get last part of file name */ + strcat(out, "..."); + } + strcat(out, source); + } + else { /* out = [string "string"] */ + size_t len = strcspn(source, "\n\r"); /* stop at first newline */ + bufflen -= sizeof(" [string \"...\"] "); + if (len > bufflen) len = bufflen; + strcpy(out, "[string \""); + if (source[len] != '\0') { /* must truncate? */ + strncat(out, source, len); + strcat(out, "..."); + } + else + strcat(out, source); + strcat(out, "\"]"); + } + } +} diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/src/lobject.h b/mod/pub.mod/lua.mod/lua-5.1.4/src/lobject.h new file mode 100644 index 0000000..f1e447e --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/src/lobject.h @@ -0,0 +1,381 @@ +/* +** $Id: lobject.h,v 2.20.1.2 2008/08/06 13:29:48 roberto Exp $ +** Type definitions for Lua objects +** See Copyright Notice in lua.h +*/ + + +#ifndef lobject_h +#define lobject_h + + +#include + + +#include "llimits.h" +#include "lua.h" + + +/* tags for values visible from Lua */ +#define LAST_TAG LUA_TTHREAD + +#define NUM_TAGS (LAST_TAG+1) + + +/* +** Extra tags for non-values +*/ +#define LUA_TPROTO (LAST_TAG+1) +#define LUA_TUPVAL (LAST_TAG+2) +#define LUA_TDEADKEY (LAST_TAG+3) + + +/* +** Union of all collectable objects +*/ +typedef union GCObject GCObject; + + +/* +** Common Header for all collectable objects (in macro form, to be +** included in other objects) +*/ +#define CommonHeader GCObject *next; lu_byte tt; lu_byte marked + + +/* +** Common header in struct form +*/ +typedef struct GCheader { + CommonHeader; +} GCheader; + + + + +/* +** Union of all Lua values +*/ +typedef union { + GCObject *gc; + void *p; + lua_Number n; + int b; +} Value; + + +/* +** Tagged Values +*/ + +#define TValuefields Value value; int tt + +typedef struct lua_TValue { + TValuefields; +} TValue; + + +/* Macros to test type */ +#define ttisnil(o) (ttype(o) == LUA_TNIL) +#define ttisnumber(o) (ttype(o) == LUA_TNUMBER) +#define ttisstring(o) (ttype(o) == LUA_TSTRING) +#define ttistable(o) (ttype(o) == LUA_TTABLE) +#define ttisfunction(o) (ttype(o) == LUA_TFUNCTION) +#define ttisboolean(o) (ttype(o) == LUA_TBOOLEAN) +#define ttisuserdata(o) (ttype(o) == LUA_TUSERDATA) +#define ttisthread(o) (ttype(o) == LUA_TTHREAD) +#define ttislightuserdata(o) (ttype(o) == LUA_TLIGHTUSERDATA) + +/* Macros to access values */ +#define ttype(o) ((o)->tt) +#define gcvalue(o) check_exp(iscollectable(o), (o)->value.gc) +#define pvalue(o) check_exp(ttislightuserdata(o), (o)->value.p) +#define nvalue(o) check_exp(ttisnumber(o), (o)->value.n) +#define rawtsvalue(o) check_exp(ttisstring(o), &(o)->value.gc->ts) +#define tsvalue(o) (&rawtsvalue(o)->tsv) +#define rawuvalue(o) check_exp(ttisuserdata(o), &(o)->value.gc->u) +#define uvalue(o) (&rawuvalue(o)->uv) +#define clvalue(o) check_exp(ttisfunction(o), &(o)->value.gc->cl) +#define hvalue(o) check_exp(ttistable(o), &(o)->value.gc->h) +#define bvalue(o) check_exp(ttisboolean(o), (o)->value.b) +#define thvalue(o) check_exp(ttisthread(o), &(o)->value.gc->th) + +#define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0)) + +/* +** for internal debug only +*/ +#define checkconsistency(obj) \ + lua_assert(!iscollectable(obj) || (ttype(obj) == (obj)->value.gc->gch.tt)) + +#define checkliveness(g,obj) \ + lua_assert(!iscollectable(obj) || \ + ((ttype(obj) == (obj)->value.gc->gch.tt) && !isdead(g, (obj)->value.gc))) + + +/* Macros to set values */ +#define setnilvalue(obj) ((obj)->tt=LUA_TNIL) + +#define setnvalue(obj,x) \ + { TValue *i_o=(obj); i_o->value.n=(x); i_o->tt=LUA_TNUMBER; } + +#define setpvalue(obj,x) \ + { TValue *i_o=(obj); i_o->value.p=(x); i_o->tt=LUA_TLIGHTUSERDATA; } + +#define setbvalue(obj,x) \ + { TValue *i_o=(obj); i_o->value.b=(x); i_o->tt=LUA_TBOOLEAN; } + +#define setsvalue(L,obj,x) \ + { TValue *i_o=(obj); \ + i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TSTRING; \ + checkliveness(G(L),i_o); } + +#define setuvalue(L,obj,x) \ + { TValue *i_o=(obj); \ + i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TUSERDATA; \ + checkliveness(G(L),i_o); } + +#define setthvalue(L,obj,x) \ + { TValue *i_o=(obj); \ + i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTHREAD; \ + checkliveness(G(L),i_o); } + +#define setclvalue(L,obj,x) \ + { TValue *i_o=(obj); \ + i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TFUNCTION; \ + checkliveness(G(L),i_o); } + +#define sethvalue(L,obj,x) \ + { TValue *i_o=(obj); \ + i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTABLE; \ + checkliveness(G(L),i_o); } + +#define setptvalue(L,obj,x) \ + { TValue *i_o=(obj); \ + i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TPROTO; \ + checkliveness(G(L),i_o); } + + + + +#define setobj(L,obj1,obj2) \ + { const TValue *o2=(obj2); TValue *o1=(obj1); \ + o1->value = o2->value; o1->tt=o2->tt; \ + checkliveness(G(L),o1); } + + +/* +** different types of sets, according to destination +*/ + +/* from stack to (same) stack */ +#define setobjs2s setobj +/* to stack (not from same stack) */ +#define setobj2s setobj +#define setsvalue2s setsvalue +#define sethvalue2s sethvalue +#define setptvalue2s setptvalue +/* from table to same table */ +#define setobjt2t setobj +/* to table */ +#define setobj2t setobj +/* to new object */ +#define setobj2n setobj +#define setsvalue2n setsvalue + +#define setttype(obj, tt) (ttype(obj) = (tt)) + + +#define iscollectable(o) (ttype(o) >= LUA_TSTRING) + + + +typedef TValue *StkId; /* index to stack elements */ + + +/* +** String headers for string table +*/ +typedef union TString { + L_Umaxalign dummy; /* ensures maximum alignment for strings */ + struct { + CommonHeader; + lu_byte reserved; + unsigned int hash; + size_t len; + } tsv; +} TString; + + +#define getstr(ts) cast(const char *, (ts) + 1) +#define svalue(o) getstr(rawtsvalue(o)) + + + +typedef union Udata { + L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */ + struct { + CommonHeader; + struct Table *metatable; + struct Table *env; + size_t len; + } uv; +} Udata; + + + + +/* +** Function Prototypes +*/ +typedef struct Proto { + CommonHeader; + TValue *k; /* constants used by the function */ + Instruction *code; + struct Proto **p; /* functions defined inside the function */ + int *lineinfo; /* map from opcodes to source lines */ + struct LocVar *locvars; /* information about local variables */ + TString **upvalues; /* upvalue names */ + TString *source; + int sizeupvalues; + int sizek; /* size of `k' */ + int sizecode; + int sizelineinfo; + int sizep; /* size of `p' */ + int sizelocvars; + int linedefined; + int lastlinedefined; + GCObject *gclist; + lu_byte nups; /* number of upvalues */ + lu_byte numparams; + lu_byte is_vararg; + lu_byte maxstacksize; +} Proto; + + +/* masks for new-style vararg */ +#define VARARG_HASARG 1 +#define VARARG_ISVARARG 2 +#define VARARG_NEEDSARG 4 + + +typedef struct LocVar { + TString *varname; + int startpc; /* first point where variable is active */ + int endpc; /* first point where variable is dead */ +} LocVar; + + + +/* +** Upvalues +*/ + +typedef struct UpVal { + CommonHeader; + TValue *v; /* points to stack or to its own value */ + union { + TValue value; /* the value (when closed) */ + struct { /* double linked list (when open) */ + struct UpVal *prev; + struct UpVal *next; + } l; + } u; +} UpVal; + + +/* +** Closures +*/ + +#define ClosureHeader \ + CommonHeader; lu_byte isC; lu_byte nupvalues; GCObject *gclist; \ + struct Table *env + +typedef struct CClosure { + ClosureHeader; + lua_CFunction f; + TValue upvalue[1]; +} CClosure; + + +typedef struct LClosure { + ClosureHeader; + struct Proto *p; + UpVal *upvals[1]; +} LClosure; + + +typedef union Closure { + CClosure c; + LClosure l; +} Closure; + + +#define iscfunction(o) (ttype(o) == LUA_TFUNCTION && clvalue(o)->c.isC) +#define isLfunction(o) (ttype(o) == LUA_TFUNCTION && !clvalue(o)->c.isC) + + +/* +** Tables +*/ + +typedef union TKey { + struct { + TValuefields; + struct Node *next; /* for chaining */ + } nk; + TValue tvk; +} TKey; + + +typedef struct Node { + TValue i_val; + TKey i_key; +} Node; + + +typedef struct Table { + CommonHeader; + lu_byte flags; /* 1<

      lsizenode)) + + +#define luaO_nilobject (&luaO_nilobject_) + +LUAI_DATA const TValue luaO_nilobject_; + +#define ceillog2(x) (luaO_log2((x)-1) + 1) + +LUAI_FUNC int luaO_log2 (unsigned int x); +LUAI_FUNC int luaO_int2fb (unsigned int x); +LUAI_FUNC int luaO_fb2int (int x); +LUAI_FUNC int luaO_rawequalObj (const TValue *t1, const TValue *t2); +LUAI_FUNC int luaO_str2d (const char *s, lua_Number *result); +LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt, + va_list argp); +LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...); +LUAI_FUNC void luaO_chunkid (char *out, const char *source, size_t len); + + +#endif + diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/src/lopcodes.c b/mod/pub.mod/lua.mod/lua-5.1.4/src/lopcodes.c new file mode 100644 index 0000000..4cc7452 --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/src/lopcodes.c @@ -0,0 +1,102 @@ +/* +** $Id: lopcodes.c,v 1.37.1.1 2007/12/27 13:02:25 roberto Exp $ +** See Copyright Notice in lua.h +*/ + + +#define lopcodes_c +#define LUA_CORE + + +#include "lopcodes.h" + + +/* ORDER OP */ + +const char *const luaP_opnames[NUM_OPCODES+1] = { + "MOVE", + "LOADK", + "LOADBOOL", + "LOADNIL", + "GETUPVAL", + "GETGLOBAL", + "GETTABLE", + "SETGLOBAL", + "SETUPVAL", + "SETTABLE", + "NEWTABLE", + "SELF", + "ADD", + "SUB", + "MUL", + "DIV", + "MOD", + "POW", + "UNM", + "NOT", + "LEN", + "CONCAT", + "JMP", + "EQ", + "LT", + "LE", + "TEST", + "TESTSET", + "CALL", + "TAILCALL", + "RETURN", + "FORLOOP", + "FORPREP", + "TFORLOOP", + "SETLIST", + "CLOSE", + "CLOSURE", + "VARARG", + NULL +}; + + +#define opmode(t,a,b,c,m) (((t)<<7) | ((a)<<6) | ((b)<<4) | ((c)<<2) | (m)) + +const lu_byte luaP_opmodes[NUM_OPCODES] = { +/* T A B C mode opcode */ + opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */ + ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_LOADK */ + ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_LOADBOOL */ + ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LOADNIL */ + ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_GETUPVAL */ + ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_GETGLOBAL */ + ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_GETTABLE */ + ,opmode(0, 0, OpArgK, OpArgN, iABx) /* OP_SETGLOBAL */ + ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_SETUPVAL */ + ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABLE */ + ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_NEWTABLE */ + ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_SELF */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_ADD */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SUB */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MUL */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_DIV */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MOD */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_POW */ + ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */ + ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */ + ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LEN */ + ,opmode(0, 1, OpArgR, OpArgR, iABC) /* OP_CONCAT */ + ,opmode(0, 0, OpArgR, OpArgN, iAsBx) /* OP_JMP */ + ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_EQ */ + ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LT */ + ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LE */ + ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TEST */ + ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TESTSET */ + ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_CALL */ + ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_TAILCALL */ + ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RETURN */ + ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORLOOP */ + ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */ + ,opmode(1, 0, OpArgN, OpArgU, iABC) /* OP_TFORLOOP */ + ,opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */ + ,opmode(0, 0, OpArgN, OpArgN, iABC) /* OP_CLOSE */ + ,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */ + ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */ +}; + diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/src/lopcodes.h b/mod/pub.mod/lua.mod/lua-5.1.4/src/lopcodes.h new file mode 100644 index 0000000..41224d6 --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/src/lopcodes.h @@ -0,0 +1,268 @@ +/* +** $Id: lopcodes.h,v 1.125.1.1 2007/12/27 13:02:25 roberto Exp $ +** Opcodes for Lua virtual machine +** See Copyright Notice in lua.h +*/ + +#ifndef lopcodes_h +#define lopcodes_h + +#include "llimits.h" + + +/*=========================================================================== + We assume that instructions are unsigned numbers. + All instructions have an opcode in the first 6 bits. + Instructions can have the following fields: + `A' : 8 bits + `B' : 9 bits + `C' : 9 bits + `Bx' : 18 bits (`B' and `C' together) + `sBx' : signed Bx + + A signed argument is represented in excess K; that is, the number + value is the unsigned value minus K. K is exactly the maximum value + for that argument (so that -max is represented by 0, and +max is + represented by 2*max), which is half the maximum for the corresponding + unsigned argument. +===========================================================================*/ + + +enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */ + + +/* +** size and position of opcode arguments. +*/ +#define SIZE_C 9 +#define SIZE_B 9 +#define SIZE_Bx (SIZE_C + SIZE_B) +#define SIZE_A 8 + +#define SIZE_OP 6 + +#define POS_OP 0 +#define POS_A (POS_OP + SIZE_OP) +#define POS_C (POS_A + SIZE_A) +#define POS_B (POS_C + SIZE_C) +#define POS_Bx POS_C + + +/* +** limits for opcode arguments. +** we use (signed) int to manipulate most arguments, +** so they must fit in LUAI_BITSINT-1 bits (-1 for sign) +*/ +#if SIZE_Bx < LUAI_BITSINT-1 +#define MAXARG_Bx ((1<>1) /* `sBx' is signed */ +#else +#define MAXARG_Bx MAX_INT +#define MAXARG_sBx MAX_INT +#endif + + +#define MAXARG_A ((1<>POS_OP) & MASK1(SIZE_OP,0))) +#define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \ + ((cast(Instruction, o)<>POS_A) & MASK1(SIZE_A,0))) +#define SETARG_A(i,u) ((i) = (((i)&MASK0(SIZE_A,POS_A)) | \ + ((cast(Instruction, u)<>POS_B) & MASK1(SIZE_B,0))) +#define SETARG_B(i,b) ((i) = (((i)&MASK0(SIZE_B,POS_B)) | \ + ((cast(Instruction, b)<>POS_C) & MASK1(SIZE_C,0))) +#define SETARG_C(i,b) ((i) = (((i)&MASK0(SIZE_C,POS_C)) | \ + ((cast(Instruction, b)<>POS_Bx) & MASK1(SIZE_Bx,0))) +#define SETARG_Bx(i,b) ((i) = (((i)&MASK0(SIZE_Bx,POS_Bx)) | \ + ((cast(Instruction, b)< C) then pc++ */ +OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */ + +OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */ +OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */ +OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see note) */ + +OP_FORLOOP,/* A sBx R(A)+=R(A+2); + if R(A) =) R(A)*/ +OP_CLOSURE,/* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */ + +OP_VARARG/* A B R(A), R(A+1), ..., R(A+B-1) = vararg */ +} OpCode; + + +#define NUM_OPCODES (cast(int, OP_VARARG) + 1) + + + +/*=========================================================================== + Notes: + (*) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1, + and can be 0: OP_CALL then sets `top' to last_result+1, so + next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use `top'. + + (*) In OP_VARARG, if (B == 0) then use actual number of varargs and + set top (like in OP_CALL with C == 0). + + (*) In OP_RETURN, if (B == 0) then return up to `top' + + (*) In OP_SETLIST, if (B == 0) then B = `top'; + if (C == 0) then next `instruction' is real C + + (*) For comparisons, A specifies what condition the test should accept + (true or false). + + (*) All `skips' (pc++) assume that next instruction is a jump +===========================================================================*/ + + +/* +** masks for instruction properties. The format is: +** bits 0-1: op mode +** bits 2-3: C arg mode +** bits 4-5: B arg mode +** bit 6: instruction set register A +** bit 7: operator is a test +*/ + +enum OpArgMask { + OpArgN, /* argument is not used */ + OpArgU, /* argument is used */ + OpArgR, /* argument is a register or a jump offset */ + OpArgK /* argument is a constant or register/constant */ +}; + +LUAI_DATA const lu_byte luaP_opmodes[NUM_OPCODES]; + +#define getOpMode(m) (cast(enum OpMode, luaP_opmodes[m] & 3)) +#define getBMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 4) & 3)) +#define getCMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 2) & 3)) +#define testAMode(m) (luaP_opmodes[m] & (1 << 6)) +#define testTMode(m) (luaP_opmodes[m] & (1 << 7)) + + +LUAI_DATA const char *const luaP_opnames[NUM_OPCODES+1]; /* opcode names */ + + +/* number of list items to accumulate before a SETLIST instruction */ +#define LFIELDS_PER_FLUSH 50 + + +#endif diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/src/loslib.c b/mod/pub.mod/lua.mod/lua-5.1.4/src/loslib.c new file mode 100644 index 0000000..da06a57 --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/src/loslib.c @@ -0,0 +1,243 @@ +/* +** $Id: loslib.c,v 1.19.1.3 2008/01/18 16:38:18 roberto Exp $ +** Standard Operating System library +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include +#include +#include + +#define loslib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +static int os_pushresult (lua_State *L, int i, const char *filename) { + int en = errno; /* calls to Lua API may change this value */ + if (i) { + lua_pushboolean(L, 1); + return 1; + } + else { + lua_pushnil(L); + lua_pushfstring(L, "%s: %s", filename, strerror(en)); + lua_pushinteger(L, en); + return 3; + } +} + + +static int os_execute (lua_State *L) { + lua_pushinteger(L, system(luaL_optstring(L, 1, NULL))); + return 1; +} + + +static int os_remove (lua_State *L) { + const char *filename = luaL_checkstring(L, 1); + return os_pushresult(L, remove(filename) == 0, filename); +} + + +static int os_rename (lua_State *L) { + const char *fromname = luaL_checkstring(L, 1); + const char *toname = luaL_checkstring(L, 2); + return os_pushresult(L, rename(fromname, toname) == 0, fromname); +} + + +static int os_tmpname (lua_State *L) { + char buff[LUA_TMPNAMBUFSIZE]; + int err; + lua_tmpnam(buff, err); + if (err) + return luaL_error(L, "unable to generate a unique filename"); + lua_pushstring(L, buff); + return 1; +} + + +static int os_getenv (lua_State *L) { + lua_pushstring(L, getenv(luaL_checkstring(L, 1))); /* if NULL push nil */ + return 1; +} + + +static int os_clock (lua_State *L) { + lua_pushnumber(L, ((lua_Number)clock())/(lua_Number)CLOCKS_PER_SEC); + return 1; +} + + +/* +** {====================================================== +** Time/Date operations +** { year=%Y, month=%m, day=%d, hour=%H, min=%M, sec=%S, +** wday=%w+1, yday=%j, isdst=? } +** ======================================================= +*/ + +static void setfield (lua_State *L, const char *key, int value) { + lua_pushinteger(L, value); + lua_setfield(L, -2, key); +} + +static void setboolfield (lua_State *L, const char *key, int value) { + if (value < 0) /* undefined? */ + return; /* does not set field */ + lua_pushboolean(L, value); + lua_setfield(L, -2, key); +} + +static int getboolfield (lua_State *L, const char *key) { + int res; + lua_getfield(L, -1, key); + res = lua_isnil(L, -1) ? -1 : lua_toboolean(L, -1); + lua_pop(L, 1); + return res; +} + + +static int getfield (lua_State *L, const char *key, int d) { + int res; + lua_getfield(L, -1, key); + if (lua_isnumber(L, -1)) + res = (int)lua_tointeger(L, -1); + else { + if (d < 0) + return luaL_error(L, "field " LUA_QS " missing in date table", key); + res = d; + } + lua_pop(L, 1); + return res; +} + + +static int os_date (lua_State *L) { + const char *s = luaL_optstring(L, 1, "%c"); + time_t t = luaL_opt(L, (time_t)luaL_checknumber, 2, time(NULL)); + struct tm *stm; + if (*s == '!') { /* UTC? */ + stm = gmtime(&t); + s++; /* skip `!' */ + } + else + stm = localtime(&t); + if (stm == NULL) /* invalid date? */ + lua_pushnil(L); + else if (strcmp(s, "*t") == 0) { + lua_createtable(L, 0, 9); /* 9 = number of fields */ + setfield(L, "sec", stm->tm_sec); + setfield(L, "min", stm->tm_min); + setfield(L, "hour", stm->tm_hour); + setfield(L, "day", stm->tm_mday); + setfield(L, "month", stm->tm_mon+1); + setfield(L, "year", stm->tm_year+1900); + setfield(L, "wday", stm->tm_wday+1); + setfield(L, "yday", stm->tm_yday+1); + setboolfield(L, "isdst", stm->tm_isdst); + } + else { + char cc[3]; + luaL_Buffer b; + cc[0] = '%'; cc[2] = '\0'; + luaL_buffinit(L, &b); + for (; *s; s++) { + if (*s != '%' || *(s + 1) == '\0') /* no conversion specifier? */ + luaL_addchar(&b, *s); + else { + size_t reslen; + char buff[200]; /* should be big enough for any conversion result */ + cc[1] = *(++s); + reslen = strftime(buff, sizeof(buff), cc, stm); + luaL_addlstring(&b, buff, reslen); + } + } + luaL_pushresult(&b); + } + return 1; +} + + +static int os_time (lua_State *L) { + time_t t; + if (lua_isnoneornil(L, 1)) /* called without args? */ + t = time(NULL); /* get current time */ + else { + struct tm ts; + luaL_checktype(L, 1, LUA_TTABLE); + lua_settop(L, 1); /* make sure table is at the top */ + ts.tm_sec = getfield(L, "sec", 0); + ts.tm_min = getfield(L, "min", 0); + ts.tm_hour = getfield(L, "hour", 12); + ts.tm_mday = getfield(L, "day", -1); + ts.tm_mon = getfield(L, "month", -1) - 1; + ts.tm_year = getfield(L, "year", -1) - 1900; + ts.tm_isdst = getboolfield(L, "isdst"); + t = mktime(&ts); + } + if (t == (time_t)(-1)) + lua_pushnil(L); + else + lua_pushnumber(L, (lua_Number)t); + return 1; +} + + +static int os_difftime (lua_State *L) { + lua_pushnumber(L, difftime((time_t)(luaL_checknumber(L, 1)), + (time_t)(luaL_optnumber(L, 2, 0)))); + return 1; +} + +/* }====================================================== */ + + +static int os_setlocale (lua_State *L) { + static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, + LC_NUMERIC, LC_TIME}; + static const char *const catnames[] = {"all", "collate", "ctype", "monetary", + "numeric", "time", NULL}; + const char *l = luaL_optstring(L, 1, NULL); + int op = luaL_checkoption(L, 2, "all", catnames); + lua_pushstring(L, setlocale(cat[op], l)); + return 1; +} + + +static int os_exit (lua_State *L) { + exit(luaL_optint(L, 1, EXIT_SUCCESS)); +} + +static const luaL_Reg syslib[] = { + {"clock", os_clock}, + {"date", os_date}, + {"difftime", os_difftime}, + {"execute", os_execute}, + {"exit", os_exit}, + {"getenv", os_getenv}, + {"remove", os_remove}, + {"rename", os_rename}, + {"setlocale", os_setlocale}, + {"time", os_time}, + {"tmpname", os_tmpname}, + {NULL, NULL} +}; + +/* }====================================================== */ + + + +LUALIB_API int luaopen_os (lua_State *L) { + luaL_register(L, LUA_OSLIBNAME, syslib); + return 1; +} + diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/src/lparser.c b/mod/pub.mod/lua.mod/lua-5.1.4/src/lparser.c new file mode 100644 index 0000000..1e2a9a8 --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/src/lparser.c @@ -0,0 +1,1339 @@ +/* +** $Id: lparser.c,v 2.42.1.3 2007/12/28 15:32:23 roberto Exp $ +** Lua Parser +** See Copyright Notice in lua.h +*/ + + +#include + +#define lparser_c +#define LUA_CORE + +#include "lua.h" + +#include "lcode.h" +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "llex.h" +#include "lmem.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lparser.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" + + + +#define hasmultret(k) ((k) == VCALL || (k) == VVARARG) + +#define getlocvar(fs, i) ((fs)->f->locvars[(fs)->actvar[i]]) + +#define luaY_checklimit(fs,v,l,m) if ((v)>(l)) errorlimit(fs,l,m) + + +/* +** nodes for block list (list of active blocks) +*/ +typedef struct BlockCnt { + struct BlockCnt *previous; /* chain */ + int breaklist; /* list of jumps out of this loop */ + lu_byte nactvar; /* # active locals outside the breakable structure */ + lu_byte upval; /* true if some variable in the block is an upvalue */ + lu_byte isbreakable; /* true if `block' is a loop */ +} BlockCnt; + + + +/* +** prototypes for recursive non-terminal functions +*/ +static void chunk (LexState *ls); +static void expr (LexState *ls, expdesc *v); + + +static void anchor_token (LexState *ls) { + if (ls->t.token == TK_NAME || ls->t.token == TK_STRING) { + TString *ts = ls->t.seminfo.ts; + luaX_newstring(ls, getstr(ts), ts->tsv.len); + } +} + + +static void error_expected (LexState *ls, int token) { + luaX_syntaxerror(ls, + luaO_pushfstring(ls->L, LUA_QS " expected", luaX_token2str(ls, token))); +} + + +static void errorlimit (FuncState *fs, int limit, const char *what) { + const char *msg = (fs->f->linedefined == 0) ? + luaO_pushfstring(fs->L, "main function has more than %d %s", limit, what) : + luaO_pushfstring(fs->L, "function at line %d has more than %d %s", + fs->f->linedefined, limit, what); + luaX_lexerror(fs->ls, msg, 0); +} + + +static int testnext (LexState *ls, int c) { + if (ls->t.token == c) { + luaX_next(ls); + return 1; + } + else return 0; +} + + +static void check (LexState *ls, int c) { + if (ls->t.token != c) + error_expected(ls, c); +} + +static void checknext (LexState *ls, int c) { + check(ls, c); + luaX_next(ls); +} + + +#define check_condition(ls,c,msg) { if (!(c)) luaX_syntaxerror(ls, msg); } + + + +static void check_match (LexState *ls, int what, int who, int where) { + if (!testnext(ls, what)) { + if (where == ls->linenumber) + error_expected(ls, what); + else { + luaX_syntaxerror(ls, luaO_pushfstring(ls->L, + LUA_QS " expected (to close " LUA_QS " at line %d)", + luaX_token2str(ls, what), luaX_token2str(ls, who), where)); + } + } +} + + +static TString *str_checkname (LexState *ls) { + TString *ts; + check(ls, TK_NAME); + ts = ls->t.seminfo.ts; + luaX_next(ls); + return ts; +} + + +static void init_exp (expdesc *e, expkind k, int i) { + e->f = e->t = NO_JUMP; + e->k = k; + e->u.s.info = i; +} + + +static void codestring (LexState *ls, expdesc *e, TString *s) { + init_exp(e, VK, luaK_stringK(ls->fs, s)); +} + + +static void checkname(LexState *ls, expdesc *e) { + codestring(ls, e, str_checkname(ls)); +} + + +static int registerlocalvar (LexState *ls, TString *varname) { + FuncState *fs = ls->fs; + Proto *f = fs->f; + int oldsize = f->sizelocvars; + luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars, + LocVar, SHRT_MAX, "too many local variables"); + while (oldsize < f->sizelocvars) f->locvars[oldsize++].varname = NULL; + f->locvars[fs->nlocvars].varname = varname; + luaC_objbarrier(ls->L, f, varname); + return fs->nlocvars++; +} + + +#define new_localvarliteral(ls,v,n) \ + new_localvar(ls, luaX_newstring(ls, "" v, (sizeof(v)/sizeof(char))-1), n) + + +static void new_localvar (LexState *ls, TString *name, int n) { + FuncState *fs = ls->fs; + luaY_checklimit(fs, fs->nactvar+n+1, LUAI_MAXVARS, "local variables"); + fs->actvar[fs->nactvar+n] = cast(unsigned short, registerlocalvar(ls, name)); +} + + +static void adjustlocalvars (LexState *ls, int nvars) { + FuncState *fs = ls->fs; + fs->nactvar = cast_byte(fs->nactvar + nvars); + for (; nvars; nvars--) { + getlocvar(fs, fs->nactvar - nvars).startpc = fs->pc; + } +} + + +static void removevars (LexState *ls, int tolevel) { + FuncState *fs = ls->fs; + while (fs->nactvar > tolevel) + getlocvar(fs, --fs->nactvar).endpc = fs->pc; +} + + +static int indexupvalue (FuncState *fs, TString *name, expdesc *v) { + int i; + Proto *f = fs->f; + int oldsize = f->sizeupvalues; + for (i=0; inups; i++) { + if (fs->upvalues[i].k == v->k && fs->upvalues[i].info == v->u.s.info) { + lua_assert(f->upvalues[i] == name); + return i; + } + } + /* new one */ + luaY_checklimit(fs, f->nups + 1, LUAI_MAXUPVALUES, "upvalues"); + luaM_growvector(fs->L, f->upvalues, f->nups, f->sizeupvalues, + TString *, MAX_INT, ""); + while (oldsize < f->sizeupvalues) f->upvalues[oldsize++] = NULL; + f->upvalues[f->nups] = name; + luaC_objbarrier(fs->L, f, name); + lua_assert(v->k == VLOCAL || v->k == VUPVAL); + fs->upvalues[f->nups].k = cast_byte(v->k); + fs->upvalues[f->nups].info = cast_byte(v->u.s.info); + return f->nups++; +} + + +static int searchvar (FuncState *fs, TString *n) { + int i; + for (i=fs->nactvar-1; i >= 0; i--) { + if (n == getlocvar(fs, i).varname) + return i; + } + return -1; /* not found */ +} + + +static void markupval (FuncState *fs, int level) { + BlockCnt *bl = fs->bl; + while (bl && bl->nactvar > level) bl = bl->previous; + if (bl) bl->upval = 1; +} + + +static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { + if (fs == NULL) { /* no more levels? */ + init_exp(var, VGLOBAL, NO_REG); /* default is global variable */ + return VGLOBAL; + } + else { + int v = searchvar(fs, n); /* look up at current level */ + if (v >= 0) { + init_exp(var, VLOCAL, v); + if (!base) + markupval(fs, v); /* local will be used as an upval */ + return VLOCAL; + } + else { /* not found at current level; try upper one */ + if (singlevaraux(fs->prev, n, var, 0) == VGLOBAL) + return VGLOBAL; + var->u.s.info = indexupvalue(fs, n, var); /* else was LOCAL or UPVAL */ + var->k = VUPVAL; /* upvalue in this level */ + return VUPVAL; + } + } +} + + +static void singlevar (LexState *ls, expdesc *var) { + TString *varname = str_checkname(ls); + FuncState *fs = ls->fs; + if (singlevaraux(fs, varname, var, 1) == VGLOBAL) + var->u.s.info = luaK_stringK(fs, varname); /* info points to global name */ +} + + +static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) { + FuncState *fs = ls->fs; + int extra = nvars - nexps; + if (hasmultret(e->k)) { + extra++; /* includes call itself */ + if (extra < 0) extra = 0; + luaK_setreturns(fs, e, extra); /* last exp. provides the difference */ + if (extra > 1) luaK_reserveregs(fs, extra-1); + } + else { + if (e->k != VVOID) luaK_exp2nextreg(fs, e); /* close last expression */ + if (extra > 0) { + int reg = fs->freereg; + luaK_reserveregs(fs, extra); + luaK_nil(fs, reg, extra); + } + } +} + + +static void enterlevel (LexState *ls) { + if (++ls->L->nCcalls > LUAI_MAXCCALLS) + luaX_lexerror(ls, "chunk has too many syntax levels", 0); +} + + +#define leavelevel(ls) ((ls)->L->nCcalls--) + + +static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isbreakable) { + bl->breaklist = NO_JUMP; + bl->isbreakable = isbreakable; + bl->nactvar = fs->nactvar; + bl->upval = 0; + bl->previous = fs->bl; + fs->bl = bl; + lua_assert(fs->freereg == fs->nactvar); +} + + +static void leaveblock (FuncState *fs) { + BlockCnt *bl = fs->bl; + fs->bl = bl->previous; + removevars(fs->ls, bl->nactvar); + if (bl->upval) + luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0); + /* a block either controls scope or breaks (never both) */ + lua_assert(!bl->isbreakable || !bl->upval); + lua_assert(bl->nactvar == fs->nactvar); + fs->freereg = fs->nactvar; /* free registers */ + luaK_patchtohere(fs, bl->breaklist); +} + + +static void pushclosure (LexState *ls, FuncState *func, expdesc *v) { + FuncState *fs = ls->fs; + Proto *f = fs->f; + int oldsize = f->sizep; + int i; + luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *, + MAXARG_Bx, "constant table overflow"); + while (oldsize < f->sizep) f->p[oldsize++] = NULL; + f->p[fs->np++] = func->f; + luaC_objbarrier(ls->L, f, func->f); + init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1)); + for (i=0; if->nups; i++) { + OpCode o = (func->upvalues[i].k == VLOCAL) ? OP_MOVE : OP_GETUPVAL; + luaK_codeABC(fs, o, 0, func->upvalues[i].info, 0); + } +} + + +static void open_func (LexState *ls, FuncState *fs) { + lua_State *L = ls->L; + Proto *f = luaF_newproto(L); + fs->f = f; + fs->prev = ls->fs; /* linked list of funcstates */ + fs->ls = ls; + fs->L = L; + ls->fs = fs; + fs->pc = 0; + fs->lasttarget = -1; + fs->jpc = NO_JUMP; + fs->freereg = 0; + fs->nk = 0; + fs->np = 0; + fs->nlocvars = 0; + fs->nactvar = 0; + fs->bl = NULL; + f->source = ls->source; + f->maxstacksize = 2; /* registers 0/1 are always valid */ + fs->h = luaH_new(L, 0, 0); + /* anchor table of constants and prototype (to avoid being collected) */ + sethvalue2s(L, L->top, fs->h); + incr_top(L); + setptvalue2s(L, L->top, f); + incr_top(L); +} + + +static void close_func (LexState *ls) { + lua_State *L = ls->L; + FuncState *fs = ls->fs; + Proto *f = fs->f; + removevars(ls, 0); + luaK_ret(fs, 0, 0); /* final return */ + luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction); + f->sizecode = fs->pc; + luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int); + f->sizelineinfo = fs->pc; + luaM_reallocvector(L, f->k, f->sizek, fs->nk, TValue); + f->sizek = fs->nk; + luaM_reallocvector(L, f->p, f->sizep, fs->np, Proto *); + f->sizep = fs->np; + luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar); + f->sizelocvars = fs->nlocvars; + luaM_reallocvector(L, f->upvalues, f->sizeupvalues, f->nups, TString *); + f->sizeupvalues = f->nups; + lua_assert(luaG_checkcode(f)); + lua_assert(fs->bl == NULL); + ls->fs = fs->prev; + L->top -= 2; /* remove table and prototype from the stack */ + /* last token read was anchored in defunct function; must reanchor it */ + if (fs) anchor_token(ls); +} + + +Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) { + struct LexState lexstate; + struct FuncState funcstate; + lexstate.buff = buff; + luaX_setinput(L, &lexstate, z, luaS_new(L, name)); + open_func(&lexstate, &funcstate); + funcstate.f->is_vararg = VARARG_ISVARARG; /* main func. is always vararg */ + luaX_next(&lexstate); /* read first token */ + chunk(&lexstate); + check(&lexstate, TK_EOS); + close_func(&lexstate); + lua_assert(funcstate.prev == NULL); + lua_assert(funcstate.f->nups == 0); + lua_assert(lexstate.fs == NULL); + return funcstate.f; +} + + + +/*============================================================*/ +/* GRAMMAR RULES */ +/*============================================================*/ + + +static void field (LexState *ls, expdesc *v) { + /* field -> ['.' | ':'] NAME */ + FuncState *fs = ls->fs; + expdesc key; + luaK_exp2anyreg(fs, v); + luaX_next(ls); /* skip the dot or colon */ + checkname(ls, &key); + luaK_indexed(fs, v, &key); +} + + +static void yindex (LexState *ls, expdesc *v) { + /* index -> '[' expr ']' */ + luaX_next(ls); /* skip the '[' */ + expr(ls, v); + luaK_exp2val(ls->fs, v); + checknext(ls, ']'); +} + + +/* +** {====================================================================== +** Rules for Constructors +** ======================================================================= +*/ + + +struct ConsControl { + expdesc v; /* last list item read */ + expdesc *t; /* table descriptor */ + int nh; /* total number of `record' elements */ + int na; /* total number of array elements */ + int tostore; /* number of array elements pending to be stored */ +}; + + +static void recfield (LexState *ls, struct ConsControl *cc) { + /* recfield -> (NAME | `['exp1`]') = exp1 */ + FuncState *fs = ls->fs; + int reg = ls->fs->freereg; + expdesc key, val; + int rkkey; + if (ls->t.token == TK_NAME) { + luaY_checklimit(fs, cc->nh, MAX_INT, "items in a constructor"); + checkname(ls, &key); + } + else /* ls->t.token == '[' */ + yindex(ls, &key); + cc->nh++; + checknext(ls, '='); + rkkey = luaK_exp2RK(fs, &key); + expr(ls, &val); + luaK_codeABC(fs, OP_SETTABLE, cc->t->u.s.info, rkkey, luaK_exp2RK(fs, &val)); + fs->freereg = reg; /* free registers */ +} + + +static void closelistfield (FuncState *fs, struct ConsControl *cc) { + if (cc->v.k == VVOID) return; /* there is no list item */ + luaK_exp2nextreg(fs, &cc->v); + cc->v.k = VVOID; + if (cc->tostore == LFIELDS_PER_FLUSH) { + luaK_setlist(fs, cc->t->u.s.info, cc->na, cc->tostore); /* flush */ + cc->tostore = 0; /* no more items pending */ + } +} + + +static void lastlistfield (FuncState *fs, struct ConsControl *cc) { + if (cc->tostore == 0) return; + if (hasmultret(cc->v.k)) { + luaK_setmultret(fs, &cc->v); + luaK_setlist(fs, cc->t->u.s.info, cc->na, LUA_MULTRET); + cc->na--; /* do not count last expression (unknown number of elements) */ + } + else { + if (cc->v.k != VVOID) + luaK_exp2nextreg(fs, &cc->v); + luaK_setlist(fs, cc->t->u.s.info, cc->na, cc->tostore); + } +} + + +static void listfield (LexState *ls, struct ConsControl *cc) { + expr(ls, &cc->v); + luaY_checklimit(ls->fs, cc->na, MAX_INT, "items in a constructor"); + cc->na++; + cc->tostore++; +} + + +static void constructor (LexState *ls, expdesc *t) { + /* constructor -> ?? */ + FuncState *fs = ls->fs; + int line = ls->linenumber; + int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0); + struct ConsControl cc; + cc.na = cc.nh = cc.tostore = 0; + cc.t = t; + init_exp(t, VRELOCABLE, pc); + init_exp(&cc.v, VVOID, 0); /* no value (yet) */ + luaK_exp2nextreg(ls->fs, t); /* fix it at stack top (for gc) */ + checknext(ls, '{'); + do { + lua_assert(cc.v.k == VVOID || cc.tostore > 0); + if (ls->t.token == '}') break; + closelistfield(fs, &cc); + switch(ls->t.token) { + case TK_NAME: { /* may be listfields or recfields */ + luaX_lookahead(ls); + if (ls->lookahead.token != '=') /* expression? */ + listfield(ls, &cc); + else + recfield(ls, &cc); + break; + } + case '[': { /* constructor_item -> recfield */ + recfield(ls, &cc); + break; + } + default: { /* constructor_part -> listfield */ + listfield(ls, &cc); + break; + } + } + } while (testnext(ls, ',') || testnext(ls, ';')); + check_match(ls, '}', '{', line); + lastlistfield(fs, &cc); + SETARG_B(fs->f->code[pc], luaO_int2fb(cc.na)); /* set initial array size */ + SETARG_C(fs->f->code[pc], luaO_int2fb(cc.nh)); /* set initial table size */ +} + +/* }====================================================================== */ + + + +static void parlist (LexState *ls) { + /* parlist -> [ param { `,' param } ] */ + FuncState *fs = ls->fs; + Proto *f = fs->f; + int nparams = 0; + f->is_vararg = 0; + if (ls->t.token != ')') { /* is `parlist' not empty? */ + do { + switch (ls->t.token) { + case TK_NAME: { /* param -> NAME */ + new_localvar(ls, str_checkname(ls), nparams++); + break; + } + case TK_DOTS: { /* param -> `...' */ + luaX_next(ls); +#if defined(LUA_COMPAT_VARARG) + /* use `arg' as default name */ + new_localvarliteral(ls, "arg", nparams++); + f->is_vararg = VARARG_HASARG | VARARG_NEEDSARG; +#endif + f->is_vararg |= VARARG_ISVARARG; + break; + } + default: luaX_syntaxerror(ls, " or " LUA_QL("...") " expected"); + } + } while (!f->is_vararg && testnext(ls, ',')); + } + adjustlocalvars(ls, nparams); + f->numparams = cast_byte(fs->nactvar - (f->is_vararg & VARARG_HASARG)); + luaK_reserveregs(fs, fs->nactvar); /* reserve register for parameters */ +} + + +static void body (LexState *ls, expdesc *e, int needself, int line) { + /* body -> `(' parlist `)' chunk END */ + FuncState new_fs; + open_func(ls, &new_fs); + new_fs.f->linedefined = line; + checknext(ls, '('); + if (needself) { + new_localvarliteral(ls, "self", 0); + adjustlocalvars(ls, 1); + } + parlist(ls); + checknext(ls, ')'); + chunk(ls); + new_fs.f->lastlinedefined = ls->linenumber; + check_match(ls, TK_END, TK_FUNCTION, line); + close_func(ls); + pushclosure(ls, &new_fs, e); +} + + +static int explist1 (LexState *ls, expdesc *v) { + /* explist1 -> expr { `,' expr } */ + int n = 1; /* at least one expression */ + expr(ls, v); + while (testnext(ls, ',')) { + luaK_exp2nextreg(ls->fs, v); + expr(ls, v); + n++; + } + return n; +} + + +static void funcargs (LexState *ls, expdesc *f) { + FuncState *fs = ls->fs; + expdesc args; + int base, nparams; + int line = ls->linenumber; + switch (ls->t.token) { + case '(': { /* funcargs -> `(' [ explist1 ] `)' */ + if (line != ls->lastline) + luaX_syntaxerror(ls,"ambiguous syntax (function call x new statement)"); + luaX_next(ls); + if (ls->t.token == ')') /* arg list is empty? */ + args.k = VVOID; + else { + explist1(ls, &args); + luaK_setmultret(fs, &args); + } + check_match(ls, ')', '(', line); + break; + } + case '{': { /* funcargs -> constructor */ + constructor(ls, &args); + break; + } + case TK_STRING: { /* funcargs -> STRING */ + codestring(ls, &args, ls->t.seminfo.ts); + luaX_next(ls); /* must use `seminfo' before `next' */ + break; + } + default: { + luaX_syntaxerror(ls, "function arguments expected"); + return; + } + } + lua_assert(f->k == VNONRELOC); + base = f->u.s.info; /* base register for call */ + if (hasmultret(args.k)) + nparams = LUA_MULTRET; /* open call */ + else { + if (args.k != VVOID) + luaK_exp2nextreg(fs, &args); /* close last argument */ + nparams = fs->freereg - (base+1); + } + init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2)); + luaK_fixline(fs, line); + fs->freereg = base+1; /* call remove function and arguments and leaves + (unless changed) one result */ +} + + + + +/* +** {====================================================================== +** Expression parsing +** ======================================================================= +*/ + + +static void prefixexp (LexState *ls, expdesc *v) { + /* prefixexp -> NAME | '(' expr ')' */ + switch (ls->t.token) { + case '(': { + int line = ls->linenumber; + luaX_next(ls); + expr(ls, v); + check_match(ls, ')', '(', line); + luaK_dischargevars(ls->fs, v); + return; + } + case TK_NAME: { + singlevar(ls, v); + return; + } + default: { + luaX_syntaxerror(ls, "unexpected symbol"); + return; + } + } +} + + +static void primaryexp (LexState *ls, expdesc *v) { + /* primaryexp -> + prefixexp { `.' NAME | `[' exp `]' | `:' NAME funcargs | funcargs } */ + FuncState *fs = ls->fs; + prefixexp(ls, v); + for (;;) { + switch (ls->t.token) { + case '.': { /* field */ + field(ls, v); + break; + } + case '[': { /* `[' exp1 `]' */ + expdesc key; + luaK_exp2anyreg(fs, v); + yindex(ls, &key); + luaK_indexed(fs, v, &key); + break; + } + case ':': { /* `:' NAME funcargs */ + expdesc key; + luaX_next(ls); + checkname(ls, &key); + luaK_self(fs, v, &key); + funcargs(ls, v); + break; + } + case '(': case TK_STRING: case '{': { /* funcargs */ + luaK_exp2nextreg(fs, v); + funcargs(ls, v); + break; + } + default: return; + } + } +} + + +static void simpleexp (LexState *ls, expdesc *v) { + /* simpleexp -> NUMBER | STRING | NIL | true | false | ... | + constructor | FUNCTION body | primaryexp */ + switch (ls->t.token) { + case TK_NUMBER: { + init_exp(v, VKNUM, 0); + v->u.nval = ls->t.seminfo.r; + break; + } + case TK_STRING: { + codestring(ls, v, ls->t.seminfo.ts); + break; + } + case TK_NIL: { + init_exp(v, VNIL, 0); + break; + } + case TK_TRUE: { + init_exp(v, VTRUE, 0); + break; + } + case TK_FALSE: { + init_exp(v, VFALSE, 0); + break; + } + case TK_DOTS: { /* vararg */ + FuncState *fs = ls->fs; + check_condition(ls, fs->f->is_vararg, + "cannot use " LUA_QL("...") " outside a vararg function"); + fs->f->is_vararg &= ~VARARG_NEEDSARG; /* don't need 'arg' */ + init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0)); + break; + } + case '{': { /* constructor */ + constructor(ls, v); + return; + } + case TK_FUNCTION: { + luaX_next(ls); + body(ls, v, 0, ls->linenumber); + return; + } + default: { + primaryexp(ls, v); + return; + } + } + luaX_next(ls); +} + + +static UnOpr getunopr (int op) { + switch (op) { + case TK_NOT: return OPR_NOT; + case '-': return OPR_MINUS; + case '#': return OPR_LEN; + default: return OPR_NOUNOPR; + } +} + + +static BinOpr getbinopr (int op) { + switch (op) { + case '+': return OPR_ADD; + case '-': return OPR_SUB; + case '*': return OPR_MUL; + case '/': return OPR_DIV; + case '%': return OPR_MOD; + case '^': return OPR_POW; + case TK_CONCAT: return OPR_CONCAT; + case TK_NE: return OPR_NE; + case TK_EQ: return OPR_EQ; + case '<': return OPR_LT; + case TK_LE: return OPR_LE; + case '>': return OPR_GT; + case TK_GE: return OPR_GE; + case TK_AND: return OPR_AND; + case TK_OR: return OPR_OR; + default: return OPR_NOBINOPR; + } +} + + +static const struct { + lu_byte left; /* left priority for each binary operator */ + lu_byte right; /* right priority */ +} priority[] = { /* ORDER OPR */ + {6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7}, /* `+' `-' `/' `%' */ + {10, 9}, {5, 4}, /* power and concat (right associative) */ + {3, 3}, {3, 3}, /* equality and inequality */ + {3, 3}, {3, 3}, {3, 3}, {3, 3}, /* order */ + {2, 2}, {1, 1} /* logical (and/or) */ +}; + +#define UNARY_PRIORITY 8 /* priority for unary operators */ + + +/* +** subexpr -> (simpleexp | unop subexpr) { binop subexpr } +** where `binop' is any binary operator with a priority higher than `limit' +*/ +static BinOpr subexpr (LexState *ls, expdesc *v, unsigned int limit) { + BinOpr op; + UnOpr uop; + enterlevel(ls); + uop = getunopr(ls->t.token); + if (uop != OPR_NOUNOPR) { + luaX_next(ls); + subexpr(ls, v, UNARY_PRIORITY); + luaK_prefix(ls->fs, uop, v); + } + else simpleexp(ls, v); + /* expand while operators have priorities higher than `limit' */ + op = getbinopr(ls->t.token); + while (op != OPR_NOBINOPR && priority[op].left > limit) { + expdesc v2; + BinOpr nextop; + luaX_next(ls); + luaK_infix(ls->fs, op, v); + /* read sub-expression with higher priority */ + nextop = subexpr(ls, &v2, priority[op].right); + luaK_posfix(ls->fs, op, v, &v2); + op = nextop; + } + leavelevel(ls); + return op; /* return first untreated operator */ +} + + +static void expr (LexState *ls, expdesc *v) { + subexpr(ls, v, 0); +} + +/* }==================================================================== */ + + + +/* +** {====================================================================== +** Rules for Statements +** ======================================================================= +*/ + + +static int block_follow (int token) { + switch (token) { + case TK_ELSE: case TK_ELSEIF: case TK_END: + case TK_UNTIL: case TK_EOS: + return 1; + default: return 0; + } +} + + +static void block (LexState *ls) { + /* block -> chunk */ + FuncState *fs = ls->fs; + BlockCnt bl; + enterblock(fs, &bl, 0); + chunk(ls); + lua_assert(bl.breaklist == NO_JUMP); + leaveblock(fs); +} + + +/* +** structure to chain all variables in the left-hand side of an +** assignment +*/ +struct LHS_assign { + struct LHS_assign *prev; + expdesc v; /* variable (global, local, upvalue, or indexed) */ +}; + + +/* +** check whether, in an assignment to a local variable, the local variable +** is needed in a previous assignment (to a table). If so, save original +** local value in a safe place and use this safe copy in the previous +** assignment. +*/ +static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) { + FuncState *fs = ls->fs; + int extra = fs->freereg; /* eventual position to save local variable */ + int conflict = 0; + for (; lh; lh = lh->prev) { + if (lh->v.k == VINDEXED) { + if (lh->v.u.s.info == v->u.s.info) { /* conflict? */ + conflict = 1; + lh->v.u.s.info = extra; /* previous assignment will use safe copy */ + } + if (lh->v.u.s.aux == v->u.s.info) { /* conflict? */ + conflict = 1; + lh->v.u.s.aux = extra; /* previous assignment will use safe copy */ + } + } + } + if (conflict) { + luaK_codeABC(fs, OP_MOVE, fs->freereg, v->u.s.info, 0); /* make copy */ + luaK_reserveregs(fs, 1); + } +} + + +static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) { + expdesc e; + check_condition(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED, + "syntax error"); + if (testnext(ls, ',')) { /* assignment -> `,' primaryexp assignment */ + struct LHS_assign nv; + nv.prev = lh; + primaryexp(ls, &nv.v); + if (nv.v.k == VLOCAL) + check_conflict(ls, lh, &nv.v); + luaY_checklimit(ls->fs, nvars, LUAI_MAXCCALLS - ls->L->nCcalls, + "variables in assignment"); + assignment(ls, &nv, nvars+1); + } + else { /* assignment -> `=' explist1 */ + int nexps; + checknext(ls, '='); + nexps = explist1(ls, &e); + if (nexps != nvars) { + adjust_assign(ls, nvars, nexps, &e); + if (nexps > nvars) + ls->fs->freereg -= nexps - nvars; /* remove extra values */ + } + else { + luaK_setoneret(ls->fs, &e); /* close last expression */ + luaK_storevar(ls->fs, &lh->v, &e); + return; /* avoid default */ + } + } + init_exp(&e, VNONRELOC, ls->fs->freereg-1); /* default assignment */ + luaK_storevar(ls->fs, &lh->v, &e); +} + + +static int cond (LexState *ls) { + /* cond -> exp */ + expdesc v; + expr(ls, &v); /* read condition */ + if (v.k == VNIL) v.k = VFALSE; /* `falses' are all equal here */ + luaK_goiftrue(ls->fs, &v); + return v.f; +} + + +static void breakstat (LexState *ls) { + FuncState *fs = ls->fs; + BlockCnt *bl = fs->bl; + int upval = 0; + while (bl && !bl->isbreakable) { + upval |= bl->upval; + bl = bl->previous; + } + if (!bl) + luaX_syntaxerror(ls, "no loop to break"); + if (upval) + luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0); + luaK_concat(fs, &bl->breaklist, luaK_jump(fs)); +} + + +static void whilestat (LexState *ls, int line) { + /* whilestat -> WHILE cond DO block END */ + FuncState *fs = ls->fs; + int whileinit; + int condexit; + BlockCnt bl; + luaX_next(ls); /* skip WHILE */ + whileinit = luaK_getlabel(fs); + condexit = cond(ls); + enterblock(fs, &bl, 1); + checknext(ls, TK_DO); + block(ls); + luaK_patchlist(fs, luaK_jump(fs), whileinit); + check_match(ls, TK_END, TK_WHILE, line); + leaveblock(fs); + luaK_patchtohere(fs, condexit); /* false conditions finish the loop */ +} + + +static void repeatstat (LexState *ls, int line) { + /* repeatstat -> REPEAT block UNTIL cond */ + int condexit; + FuncState *fs = ls->fs; + int repeat_init = luaK_getlabel(fs); + BlockCnt bl1, bl2; + enterblock(fs, &bl1, 1); /* loop block */ + enterblock(fs, &bl2, 0); /* scope block */ + luaX_next(ls); /* skip REPEAT */ + chunk(ls); + check_match(ls, TK_UNTIL, TK_REPEAT, line); + condexit = cond(ls); /* read condition (inside scope block) */ + if (!bl2.upval) { /* no upvalues? */ + leaveblock(fs); /* finish scope */ + luaK_patchlist(ls->fs, condexit, repeat_init); /* close the loop */ + } + else { /* complete semantics when there are upvalues */ + breakstat(ls); /* if condition then break */ + luaK_patchtohere(ls->fs, condexit); /* else... */ + leaveblock(fs); /* finish scope... */ + luaK_patchlist(ls->fs, luaK_jump(fs), repeat_init); /* and repeat */ + } + leaveblock(fs); /* finish loop */ +} + + +static int exp1 (LexState *ls) { + expdesc e; + int k; + expr(ls, &e); + k = e.k; + luaK_exp2nextreg(ls->fs, &e); + return k; +} + + +static void forbody (LexState *ls, int base, int line, int nvars, int isnum) { + /* forbody -> DO block */ + BlockCnt bl; + FuncState *fs = ls->fs; + int prep, endfor; + adjustlocalvars(ls, 3); /* control variables */ + checknext(ls, TK_DO); + prep = isnum ? luaK_codeAsBx(fs, OP_FORPREP, base, NO_JUMP) : luaK_jump(fs); + enterblock(fs, &bl, 0); /* scope for declared variables */ + adjustlocalvars(ls, nvars); + luaK_reserveregs(fs, nvars); + block(ls); + leaveblock(fs); /* end of scope for declared variables */ + luaK_patchtohere(fs, prep); + endfor = (isnum) ? luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP) : + luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars); + luaK_fixline(fs, line); /* pretend that `OP_FOR' starts the loop */ + luaK_patchlist(fs, (isnum ? endfor : luaK_jump(fs)), prep + 1); +} + + +static void fornum (LexState *ls, TString *varname, int line) { + /* fornum -> NAME = exp1,exp1[,exp1] forbody */ + FuncState *fs = ls->fs; + int base = fs->freereg; + new_localvarliteral(ls, "(for index)", 0); + new_localvarliteral(ls, "(for limit)", 1); + new_localvarliteral(ls, "(for step)", 2); + new_localvar(ls, varname, 3); + checknext(ls, '='); + exp1(ls); /* initial value */ + checknext(ls, ','); + exp1(ls); /* limit */ + if (testnext(ls, ',')) + exp1(ls); /* optional step */ + else { /* default step = 1 */ + luaK_codeABx(fs, OP_LOADK, fs->freereg, luaK_numberK(fs, 1)); + luaK_reserveregs(fs, 1); + } + forbody(ls, base, line, 1, 1); +} + + +static void forlist (LexState *ls, TString *indexname) { + /* forlist -> NAME {,NAME} IN explist1 forbody */ + FuncState *fs = ls->fs; + expdesc e; + int nvars = 0; + int line; + int base = fs->freereg; + /* create control variables */ + new_localvarliteral(ls, "(for generator)", nvars++); + new_localvarliteral(ls, "(for state)", nvars++); + new_localvarliteral(ls, "(for control)", nvars++); + /* create declared variables */ + new_localvar(ls, indexname, nvars++); + while (testnext(ls, ',')) + new_localvar(ls, str_checkname(ls), nvars++); + checknext(ls, TK_IN); + line = ls->linenumber; + adjust_assign(ls, 3, explist1(ls, &e), &e); + luaK_checkstack(fs, 3); /* extra space to call generator */ + forbody(ls, base, line, nvars - 3, 0); +} + + +static void forstat (LexState *ls, int line) { + /* forstat -> FOR (fornum | forlist) END */ + FuncState *fs = ls->fs; + TString *varname; + BlockCnt bl; + enterblock(fs, &bl, 1); /* scope for loop and control variables */ + luaX_next(ls); /* skip `for' */ + varname = str_checkname(ls); /* first variable name */ + switch (ls->t.token) { + case '=': fornum(ls, varname, line); break; + case ',': case TK_IN: forlist(ls, varname); break; + default: luaX_syntaxerror(ls, LUA_QL("=") " or " LUA_QL("in") " expected"); + } + check_match(ls, TK_END, TK_FOR, line); + leaveblock(fs); /* loop scope (`break' jumps to this point) */ +} + + +static int test_then_block (LexState *ls) { + /* test_then_block -> [IF | ELSEIF] cond THEN block */ + int condexit; + luaX_next(ls); /* skip IF or ELSEIF */ + condexit = cond(ls); + checknext(ls, TK_THEN); + block(ls); /* `then' part */ + return condexit; +} + + +static void ifstat (LexState *ls, int line) { + /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */ + FuncState *fs = ls->fs; + int flist; + int escapelist = NO_JUMP; + flist = test_then_block(ls); /* IF cond THEN block */ + while (ls->t.token == TK_ELSEIF) { + luaK_concat(fs, &escapelist, luaK_jump(fs)); + luaK_patchtohere(fs, flist); + flist = test_then_block(ls); /* ELSEIF cond THEN block */ + } + if (ls->t.token == TK_ELSE) { + luaK_concat(fs, &escapelist, luaK_jump(fs)); + luaK_patchtohere(fs, flist); + luaX_next(ls); /* skip ELSE (after patch, for correct line info) */ + block(ls); /* `else' part */ + } + else + luaK_concat(fs, &escapelist, flist); + luaK_patchtohere(fs, escapelist); + check_match(ls, TK_END, TK_IF, line); +} + + +static void localfunc (LexState *ls) { + expdesc v, b; + FuncState *fs = ls->fs; + new_localvar(ls, str_checkname(ls), 0); + init_exp(&v, VLOCAL, fs->freereg); + luaK_reserveregs(fs, 1); + adjustlocalvars(ls, 1); + body(ls, &b, 0, ls->linenumber); + luaK_storevar(fs, &v, &b); + /* debug information will only see the variable after this point! */ + getlocvar(fs, fs->nactvar - 1).startpc = fs->pc; +} + + +static void localstat (LexState *ls) { + /* stat -> LOCAL NAME {`,' NAME} [`=' explist1] */ + int nvars = 0; + int nexps; + expdesc e; + do { + new_localvar(ls, str_checkname(ls), nvars++); + } while (testnext(ls, ',')); + if (testnext(ls, '=')) + nexps = explist1(ls, &e); + else { + e.k = VVOID; + nexps = 0; + } + adjust_assign(ls, nvars, nexps, &e); + adjustlocalvars(ls, nvars); +} + + +static int funcname (LexState *ls, expdesc *v) { + /* funcname -> NAME {field} [`:' NAME] */ + int needself = 0; + singlevar(ls, v); + while (ls->t.token == '.') + field(ls, v); + if (ls->t.token == ':') { + needself = 1; + field(ls, v); + } + return needself; +} + + +static void funcstat (LexState *ls, int line) { + /* funcstat -> FUNCTION funcname body */ + int needself; + expdesc v, b; + luaX_next(ls); /* skip FUNCTION */ + needself = funcname(ls, &v); + body(ls, &b, needself, line); + luaK_storevar(ls->fs, &v, &b); + luaK_fixline(ls->fs, line); /* definition `happens' in the first line */ +} + + +static void exprstat (LexState *ls) { + /* stat -> func | assignment */ + FuncState *fs = ls->fs; + struct LHS_assign v; + primaryexp(ls, &v.v); + if (v.v.k == VCALL) /* stat -> func */ + SETARG_C(getcode(fs, &v.v), 1); /* call statement uses no results */ + else { /* stat -> assignment */ + v.prev = NULL; + assignment(ls, &v, 1); + } +} + + +static void retstat (LexState *ls) { + /* stat -> RETURN explist */ + FuncState *fs = ls->fs; + expdesc e; + int first, nret; /* registers with returned values */ + luaX_next(ls); /* skip RETURN */ + if (block_follow(ls->t.token) || ls->t.token == ';') + first = nret = 0; /* return no values */ + else { + nret = explist1(ls, &e); /* optional return values */ + if (hasmultret(e.k)) { + luaK_setmultret(fs, &e); + if (e.k == VCALL && nret == 1) { /* tail call? */ + SET_OPCODE(getcode(fs,&e), OP_TAILCALL); + lua_assert(GETARG_A(getcode(fs,&e)) == fs->nactvar); + } + first = fs->nactvar; + nret = LUA_MULTRET; /* return all values */ + } + else { + if (nret == 1) /* only one single value? */ + first = luaK_exp2anyreg(fs, &e); + else { + luaK_exp2nextreg(fs, &e); /* values must go to the `stack' */ + first = fs->nactvar; /* return all `active' values */ + lua_assert(nret == fs->freereg - first); + } + } + } + luaK_ret(fs, first, nret); +} + + +static int statement (LexState *ls) { + int line = ls->linenumber; /* may be needed for error messages */ + switch (ls->t.token) { + case TK_IF: { /* stat -> ifstat */ + ifstat(ls, line); + return 0; + } + case TK_WHILE: { /* stat -> whilestat */ + whilestat(ls, line); + return 0; + } + case TK_DO: { /* stat -> DO block END */ + luaX_next(ls); /* skip DO */ + block(ls); + check_match(ls, TK_END, TK_DO, line); + return 0; + } + case TK_FOR: { /* stat -> forstat */ + forstat(ls, line); + return 0; + } + case TK_REPEAT: { /* stat -> repeatstat */ + repeatstat(ls, line); + return 0; + } + case TK_FUNCTION: { + funcstat(ls, line); /* stat -> funcstat */ + return 0; + } + case TK_LOCAL: { /* stat -> localstat */ + luaX_next(ls); /* skip LOCAL */ + if (testnext(ls, TK_FUNCTION)) /* local function? */ + localfunc(ls); + else + localstat(ls); + return 0; + } + case TK_RETURN: { /* stat -> retstat */ + retstat(ls); + return 1; /* must be last statement */ + } + case TK_BREAK: { /* stat -> breakstat */ + luaX_next(ls); /* skip BREAK */ + breakstat(ls); + return 1; /* must be last statement */ + } + default: { + exprstat(ls); + return 0; /* to avoid warnings */ + } + } +} + + +static void chunk (LexState *ls) { + /* chunk -> { stat [`;'] } */ + int islast = 0; + enterlevel(ls); + while (!islast && !block_follow(ls->t.token)) { + islast = statement(ls); + testnext(ls, ';'); + lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg && + ls->fs->freereg >= ls->fs->nactvar); + ls->fs->freereg = ls->fs->nactvar; /* free registers */ + } + leavelevel(ls); +} + +/* }====================================================================== */ diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/src/lparser.h b/mod/pub.mod/lua.mod/lua-5.1.4/src/lparser.h new file mode 100644 index 0000000..18836af --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/src/lparser.h @@ -0,0 +1,82 @@ +/* +** $Id: lparser.h,v 1.57.1.1 2007/12/27 13:02:25 roberto Exp $ +** Lua Parser +** See Copyright Notice in lua.h +*/ + +#ifndef lparser_h +#define lparser_h + +#include "llimits.h" +#include "lobject.h" +#include "lzio.h" + + +/* +** Expression descriptor +*/ + +typedef enum { + VVOID, /* no value */ + VNIL, + VTRUE, + VFALSE, + VK, /* info = index of constant in `k' */ + VKNUM, /* nval = numerical value */ + VLOCAL, /* info = local register */ + VUPVAL, /* info = index of upvalue in `upvalues' */ + VGLOBAL, /* info = index of table; aux = index of global name in `k' */ + VINDEXED, /* info = table register; aux = index register (or `k') */ + VJMP, /* info = instruction pc */ + VRELOCABLE, /* info = instruction pc */ + VNONRELOC, /* info = result register */ + VCALL, /* info = instruction pc */ + VVARARG /* info = instruction pc */ +} expkind; + +typedef struct expdesc { + expkind k; + union { + struct { int info, aux; } s; + lua_Number nval; + } u; + int t; /* patch list of `exit when true' */ + int f; /* patch list of `exit when false' */ +} expdesc; + + +typedef struct upvaldesc { + lu_byte k; + lu_byte info; +} upvaldesc; + + +struct BlockCnt; /* defined in lparser.c */ + + +/* state needed to generate code for a given function */ +typedef struct FuncState { + Proto *f; /* current function header */ + Table *h; /* table to find (and reuse) elements in `k' */ + struct FuncState *prev; /* enclosing function */ + struct LexState *ls; /* lexical state */ + struct lua_State *L; /* copy of the Lua state */ + struct BlockCnt *bl; /* chain of current blocks */ + int pc; /* next position to code (equivalent to `ncode') */ + int lasttarget; /* `pc' of last `jump target' */ + int jpc; /* list of pending jumps to `pc' */ + int freereg; /* first free register */ + int nk; /* number of elements in `k' */ + int np; /* number of elements in `p' */ + short nlocvars; /* number of elements in `locvars' */ + lu_byte nactvar; /* number of active local variables */ + upvaldesc upvalues[LUAI_MAXUPVALUES]; /* upvalues */ + unsigned short actvar[LUAI_MAXVARS]; /* declared-variable stack */ +} FuncState; + + +LUAI_FUNC Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, + const char *name); + + +#endif diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/src/lstate.c b/mod/pub.mod/lua.mod/lua-5.1.4/src/lstate.c new file mode 100644 index 0000000..4313b83 --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/src/lstate.c @@ -0,0 +1,214 @@ +/* +** $Id: lstate.c,v 2.36.1.2 2008/01/03 15:20:39 roberto Exp $ +** Global State +** See Copyright Notice in lua.h +*/ + + +#include + +#define lstate_c +#define LUA_CORE + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "llex.h" +#include "lmem.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" + + +#define state_size(x) (sizeof(x) + LUAI_EXTRASPACE) +#define fromstate(l) (cast(lu_byte *, (l)) - LUAI_EXTRASPACE) +#define tostate(l) (cast(lua_State *, cast(lu_byte *, l) + LUAI_EXTRASPACE)) + + +/* +** Main thread combines a thread state and the global state +*/ +typedef struct LG { + lua_State l; + global_State g; +} LG; + + + +static void stack_init (lua_State *L1, lua_State *L) { + /* initialize CallInfo array */ + L1->base_ci = luaM_newvector(L, BASIC_CI_SIZE, CallInfo); + L1->ci = L1->base_ci; + L1->size_ci = BASIC_CI_SIZE; + L1->end_ci = L1->base_ci + L1->size_ci - 1; + /* initialize stack array */ + L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, TValue); + L1->stacksize = BASIC_STACK_SIZE + EXTRA_STACK; + L1->top = L1->stack; + L1->stack_last = L1->stack+(L1->stacksize - EXTRA_STACK)-1; + /* initialize first ci */ + L1->ci->func = L1->top; + setnilvalue(L1->top++); /* `function' entry for this `ci' */ + L1->base = L1->ci->base = L1->top; + L1->ci->top = L1->top + LUA_MINSTACK; +} + + +static void freestack (lua_State *L, lua_State *L1) { + luaM_freearray(L, L1->base_ci, L1->size_ci, CallInfo); + luaM_freearray(L, L1->stack, L1->stacksize, TValue); +} + + +/* +** open parts that may cause memory-allocation errors +*/ +static void f_luaopen (lua_State *L, void *ud) { + global_State *g = G(L); + UNUSED(ud); + stack_init(L, L); /* init stack */ + sethvalue(L, gt(L), luaH_new(L, 0, 2)); /* table of globals */ + sethvalue(L, registry(L), luaH_new(L, 0, 2)); /* registry */ + luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */ + luaT_init(L); + luaX_init(L); + luaS_fix(luaS_newliteral(L, MEMERRMSG)); + g->GCthreshold = 4*g->totalbytes; +} + + +static void preinit_state (lua_State *L, global_State *g) { + G(L) = g; + L->stack = NULL; + L->stacksize = 0; + L->errorJmp = NULL; + L->hook = NULL; + L->hookmask = 0; + L->basehookcount = 0; + L->allowhook = 1; + resethookcount(L); + L->openupval = NULL; + L->size_ci = 0; + L->nCcalls = L->baseCcalls = 0; + L->status = 0; + L->base_ci = L->ci = NULL; + L->savedpc = NULL; + L->errfunc = 0; + setnilvalue(gt(L)); +} + + +static void close_state (lua_State *L) { + global_State *g = G(L); + luaF_close(L, L->stack); /* close all upvalues for this thread */ + luaC_freeall(L); /* collect all objects */ + lua_assert(g->rootgc == obj2gco(L)); + lua_assert(g->strt.nuse == 0); + luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size, TString *); + luaZ_freebuffer(L, &g->buff); + freestack(L, L); + lua_assert(g->totalbytes == sizeof(LG)); + (*g->frealloc)(g->ud, fromstate(L), state_size(LG), 0); +} + + +lua_State *luaE_newthread (lua_State *L) { + lua_State *L1 = tostate(luaM_malloc(L, state_size(lua_State))); + luaC_link(L, obj2gco(L1), LUA_TTHREAD); + preinit_state(L1, G(L)); + stack_init(L1, L); /* init stack */ + setobj2n(L, gt(L1), gt(L)); /* share table of globals */ + L1->hookmask = L->hookmask; + L1->basehookcount = L->basehookcount; + L1->hook = L->hook; + resethookcount(L1); + lua_assert(iswhite(obj2gco(L1))); + return L1; +} + + +void luaE_freethread (lua_State *L, lua_State *L1) { + luaF_close(L1, L1->stack); /* close all upvalues for this thread */ + lua_assert(L1->openupval == NULL); + luai_userstatefree(L1); + freestack(L, L1); + luaM_freemem(L, fromstate(L1), state_size(lua_State)); +} + + +LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { + int i; + lua_State *L; + global_State *g; + void *l = (*f)(ud, NULL, 0, state_size(LG)); + if (l == NULL) return NULL; + L = tostate(l); + g = &((LG *)L)->g; + L->next = NULL; + L->tt = LUA_TTHREAD; + g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT); + L->marked = luaC_white(g); + set2bits(L->marked, FIXEDBIT, SFIXEDBIT); + preinit_state(L, g); + g->frealloc = f; + g->ud = ud; + g->mainthread = L; + g->uvhead.u.l.prev = &g->uvhead; + g->uvhead.u.l.next = &g->uvhead; + g->GCthreshold = 0; /* mark it as unfinished state */ + g->strt.size = 0; + g->strt.nuse = 0; + g->strt.hash = NULL; + setnilvalue(registry(L)); + luaZ_initbuffer(L, &g->buff); + g->panic = NULL; + g->gcstate = GCSpause; + g->rootgc = obj2gco(L); + g->sweepstrgc = 0; + g->sweepgc = &g->rootgc; + g->gray = NULL; + g->grayagain = NULL; + g->weak = NULL; + g->tmudata = NULL; + g->totalbytes = sizeof(LG); + g->gcpause = LUAI_GCPAUSE; + g->gcstepmul = LUAI_GCMUL; + g->gcdept = 0; + for (i=0; imt[i] = NULL; + if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) { + /* memory allocation error: free partial state */ + close_state(L); + L = NULL; + } + else + luai_userstateopen(L); + return L; +} + + +static void callallgcTM (lua_State *L, void *ud) { + UNUSED(ud); + luaC_callGCTM(L); /* call GC metamethods for all udata */ +} + + +LUA_API void lua_close (lua_State *L) { + L = G(L)->mainthread; /* only the main thread can be closed */ + lua_lock(L); + luaF_close(L, L->stack); /* close all upvalues for this thread */ + luaC_separateudata(L, 1); /* separate udata that have GC metamethods */ + L->errfunc = 0; /* no error function during GC metamethods */ + do { /* repeat until no more errors */ + L->ci = L->base_ci; + L->base = L->top = L->ci->base; + L->nCcalls = L->baseCcalls = 0; + } while (luaD_rawrunprotected(L, callallgcTM, NULL) != 0); + lua_assert(G(L)->tmudata == NULL); + luai_userstateclose(L); + close_state(L); +} + diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/src/lstate.h b/mod/pub.mod/lua.mod/lua-5.1.4/src/lstate.h new file mode 100644 index 0000000..3bc575b --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/src/lstate.h @@ -0,0 +1,169 @@ +/* +** $Id: lstate.h,v 2.24.1.2 2008/01/03 15:20:39 roberto Exp $ +** Global State +** See Copyright Notice in lua.h +*/ + +#ifndef lstate_h +#define lstate_h + +#include "lua.h" + +#include "lobject.h" +#include "ltm.h" +#include "lzio.h" + + + +struct lua_longjmp; /* defined in ldo.c */ + + +/* table of globals */ +#define gt(L) (&L->l_gt) + +/* registry */ +#define registry(L) (&G(L)->l_registry) + + +/* extra stack space to handle TM calls and some other extras */ +#define EXTRA_STACK 5 + + +#define BASIC_CI_SIZE 8 + +#define BASIC_STACK_SIZE (2*LUA_MINSTACK) + + + +typedef struct stringtable { + GCObject **hash; + lu_int32 nuse; /* number of elements */ + int size; +} stringtable; + + +/* +** informations about a call +*/ +typedef struct CallInfo { + StkId base; /* base for this function */ + StkId func; /* function index in the stack */ + StkId top; /* top for this function */ + const Instruction *savedpc; + int nresults; /* expected number of results from this function */ + int tailcalls; /* number of tail calls lost under this entry */ +} CallInfo; + + + +#define curr_func(L) (clvalue(L->ci->func)) +#define ci_func(ci) (clvalue((ci)->func)) +#define f_isLua(ci) (!ci_func(ci)->c.isC) +#define isLua(ci) (ttisfunction((ci)->func) && f_isLua(ci)) + + +/* +** `global state', shared by all threads of this state +*/ +typedef struct global_State { + stringtable strt; /* hash table for strings */ + lua_Alloc frealloc; /* function to reallocate memory */ + void *ud; /* auxiliary data to `frealloc' */ + lu_byte currentwhite; + lu_byte gcstate; /* state of garbage collector */ + int sweepstrgc; /* position of sweep in `strt' */ + GCObject *rootgc; /* list of all collectable objects */ + GCObject **sweepgc; /* position of sweep in `rootgc' */ + GCObject *gray; /* list of gray objects */ + GCObject *grayagain; /* list of objects to be traversed atomically */ + GCObject *weak; /* list of weak tables (to be cleared) */ + GCObject *tmudata; /* last element of list of userdata to be GC */ + Mbuffer buff; /* temporary buffer for string concatentation */ + lu_mem GCthreshold; + lu_mem totalbytes; /* number of bytes currently allocated */ + lu_mem estimate; /* an estimate of number of bytes actually in use */ + lu_mem gcdept; /* how much GC is `behind schedule' */ + int gcpause; /* size of pause between successive GCs */ + int gcstepmul; /* GC `granularity' */ + lua_CFunction panic; /* to be called in unprotected errors */ + TValue l_registry; + struct lua_State *mainthread; + UpVal uvhead; /* head of double-linked list of all open upvalues */ + struct Table *mt[NUM_TAGS]; /* metatables for basic types */ + TString *tmname[TM_N]; /* array with tag-method names */ +} global_State; + + +/* +** `per thread' state +*/ +struct lua_State { + CommonHeader; + lu_byte status; + StkId top; /* first free slot in the stack */ + StkId base; /* base of current function */ + global_State *l_G; + CallInfo *ci; /* call info for current function */ + const Instruction *savedpc; /* `savedpc' of current function */ + StkId stack_last; /* last free slot in the stack */ + StkId stack; /* stack base */ + CallInfo *end_ci; /* points after end of ci array*/ + CallInfo *base_ci; /* array of CallInfo's */ + int stacksize; + int size_ci; /* size of array `base_ci' */ + unsigned short nCcalls; /* number of nested C calls */ + unsigned short baseCcalls; /* nested C calls when resuming coroutine */ + lu_byte hookmask; + lu_byte allowhook; + int basehookcount; + int hookcount; + lua_Hook hook; + TValue l_gt; /* table of globals */ + TValue env; /* temporary place for environments */ + GCObject *openupval; /* list of open upvalues in this stack */ + GCObject *gclist; + struct lua_longjmp *errorJmp; /* current error recover point */ + ptrdiff_t errfunc; /* current error handling function (stack index) */ +}; + + +#define G(L) (L->l_G) + + +/* +** Union of all collectable objects +*/ +union GCObject { + GCheader gch; + union TString ts; + union Udata u; + union Closure cl; + struct Table h; + struct Proto p; + struct UpVal uv; + struct lua_State th; /* thread */ +}; + + +/* macros to convert a GCObject into a specific value */ +#define rawgco2ts(o) check_exp((o)->gch.tt == LUA_TSTRING, &((o)->ts)) +#define gco2ts(o) (&rawgco2ts(o)->tsv) +#define rawgco2u(o) check_exp((o)->gch.tt == LUA_TUSERDATA, &((o)->u)) +#define gco2u(o) (&rawgco2u(o)->uv) +#define gco2cl(o) check_exp((o)->gch.tt == LUA_TFUNCTION, &((o)->cl)) +#define gco2h(o) check_exp((o)->gch.tt == LUA_TTABLE, &((o)->h)) +#define gco2p(o) check_exp((o)->gch.tt == LUA_TPROTO, &((o)->p)) +#define gco2uv(o) check_exp((o)->gch.tt == LUA_TUPVAL, &((o)->uv)) +#define ngcotouv(o) \ + check_exp((o) == NULL || (o)->gch.tt == LUA_TUPVAL, &((o)->uv)) +#define gco2th(o) check_exp((o)->gch.tt == LUA_TTHREAD, &((o)->th)) + +/* macro to convert any Lua object into a GCObject */ +#define obj2gco(v) (cast(GCObject *, (v))) + + +LUAI_FUNC lua_State *luaE_newthread (lua_State *L); +LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1); + +#endif + diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/src/lstring.c b/mod/pub.mod/lua.mod/lua-5.1.4/src/lstring.c new file mode 100644 index 0000000..4911315 --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/src/lstring.c @@ -0,0 +1,111 @@ +/* +** $Id: lstring.c,v 2.8.1.1 2007/12/27 13:02:25 roberto Exp $ +** String table (keeps all strings handled by Lua) +** See Copyright Notice in lua.h +*/ + + +#include + +#define lstring_c +#define LUA_CORE + +#include "lua.h" + +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" + + + +void luaS_resize (lua_State *L, int newsize) { + GCObject **newhash; + stringtable *tb; + int i; + if (G(L)->gcstate == GCSsweepstring) + return; /* cannot resize during GC traverse */ + newhash = luaM_newvector(L, newsize, GCObject *); + tb = &G(L)->strt; + for (i=0; isize; i++) { + GCObject *p = tb->hash[i]; + while (p) { /* for each node in the list */ + GCObject *next = p->gch.next; /* save next */ + unsigned int h = gco2ts(p)->hash; + int h1 = lmod(h, newsize); /* new position */ + lua_assert(cast_int(h%newsize) == lmod(h, newsize)); + p->gch.next = newhash[h1]; /* chain it */ + newhash[h1] = p; + p = next; + } + } + luaM_freearray(L, tb->hash, tb->size, TString *); + tb->size = newsize; + tb->hash = newhash; +} + + +static TString *newlstr (lua_State *L, const char *str, size_t l, + unsigned int h) { + TString *ts; + stringtable *tb; + if (l+1 > (MAX_SIZET - sizeof(TString))/sizeof(char)) + luaM_toobig(L); + ts = cast(TString *, luaM_malloc(L, (l+1)*sizeof(char)+sizeof(TString))); + ts->tsv.len = l; + ts->tsv.hash = h; + ts->tsv.marked = luaC_white(G(L)); + ts->tsv.tt = LUA_TSTRING; + ts->tsv.reserved = 0; + memcpy(ts+1, str, l*sizeof(char)); + ((char *)(ts+1))[l] = '\0'; /* ending 0 */ + tb = &G(L)->strt; + h = lmod(h, tb->size); + ts->tsv.next = tb->hash[h]; /* chain new entry */ + tb->hash[h] = obj2gco(ts); + tb->nuse++; + if (tb->nuse > cast(lu_int32, tb->size) && tb->size <= MAX_INT/2) + luaS_resize(L, tb->size*2); /* too crowded */ + return ts; +} + + +TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { + GCObject *o; + unsigned int h = cast(unsigned int, l); /* seed */ + size_t step = (l>>5)+1; /* if string is too long, don't hash all its chars */ + size_t l1; + for (l1=l; l1>=step; l1-=step) /* compute hash */ + h = h ^ ((h<<5)+(h>>2)+cast(unsigned char, str[l1-1])); + for (o = G(L)->strt.hash[lmod(h, G(L)->strt.size)]; + o != NULL; + o = o->gch.next) { + TString *ts = rawgco2ts(o); + if (ts->tsv.len == l && (memcmp(str, getstr(ts), l) == 0)) { + /* string may be dead */ + if (isdead(G(L), o)) changewhite(o); + return ts; + } + } + return newlstr(L, str, l, h); /* not found */ +} + + +Udata *luaS_newudata (lua_State *L, size_t s, Table *e) { + Udata *u; + if (s > MAX_SIZET - sizeof(Udata)) + luaM_toobig(L); + u = cast(Udata *, luaM_malloc(L, s + sizeof(Udata))); + u->uv.marked = luaC_white(G(L)); /* is not finalized */ + u->uv.tt = LUA_TUSERDATA; + u->uv.len = s; + u->uv.metatable = NULL; + u->uv.env = e; + /* chain it on udata list (after main thread) */ + u->uv.next = G(L)->mainthread->next; + G(L)->mainthread->next = obj2gco(u); + return u; +} + diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/src/lstring.h b/mod/pub.mod/lua.mod/lua-5.1.4/src/lstring.h new file mode 100644 index 0000000..73a2ff8 --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/src/lstring.h @@ -0,0 +1,31 @@ +/* +** $Id: lstring.h,v 1.43.1.1 2007/12/27 13:02:25 roberto Exp $ +** String table (keep all strings handled by Lua) +** See Copyright Notice in lua.h +*/ + +#ifndef lstring_h +#define lstring_h + + +#include "lgc.h" +#include "lobject.h" +#include "lstate.h" + + +#define sizestring(s) (sizeof(union TString)+((s)->len+1)*sizeof(char)) + +#define sizeudata(u) (sizeof(union Udata)+(u)->len) + +#define luaS_new(L, s) (luaS_newlstr(L, s, strlen(s))) +#define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ + (sizeof(s)/sizeof(char))-1)) + +#define luaS_fix(s) l_setbit((s)->tsv.marked, FIXEDBIT) + +LUAI_FUNC void luaS_resize (lua_State *L, int newsize); +LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e); +LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l); + + +#endif diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/src/lstrlib.c b/mod/pub.mod/lua.mod/lua-5.1.4/src/lstrlib.c new file mode 100644 index 0000000..1b4763d --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/src/lstrlib.c @@ -0,0 +1,869 @@ +/* +** $Id: lstrlib.c,v 1.132.1.4 2008/07/11 17:27:21 roberto Exp $ +** Standard library for string operations and pattern-matching +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include +#include +#include + +#define lstrlib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +/* macro to `unsign' a character */ +#define uchar(c) ((unsigned char)(c)) + + + +static int str_len (lua_State *L) { + size_t l; + luaL_checklstring(L, 1, &l); + lua_pushinteger(L, l); + return 1; +} + + +static ptrdiff_t posrelat (ptrdiff_t pos, size_t len) { + /* relative string position: negative means back from end */ + if (pos < 0) pos += (ptrdiff_t)len + 1; + return (pos >= 0) ? pos : 0; +} + + +static int str_sub (lua_State *L) { + size_t l; + const char *s = luaL_checklstring(L, 1, &l); + ptrdiff_t start = posrelat(luaL_checkinteger(L, 2), l); + ptrdiff_t end = posrelat(luaL_optinteger(L, 3, -1), l); + if (start < 1) start = 1; + if (end > (ptrdiff_t)l) end = (ptrdiff_t)l; + if (start <= end) + lua_pushlstring(L, s+start-1, end-start+1); + else lua_pushliteral(L, ""); + return 1; +} + + +static int str_reverse (lua_State *L) { + size_t l; + luaL_Buffer b; + const char *s = luaL_checklstring(L, 1, &l); + luaL_buffinit(L, &b); + while (l--) luaL_addchar(&b, s[l]); + luaL_pushresult(&b); + return 1; +} + + +static int str_lower (lua_State *L) { + size_t l; + size_t i; + luaL_Buffer b; + const char *s = luaL_checklstring(L, 1, &l); + luaL_buffinit(L, &b); + for (i=0; i 0) + luaL_addlstring(&b, s, l); + luaL_pushresult(&b); + return 1; +} + + +static int str_byte (lua_State *L) { + size_t l; + const char *s = luaL_checklstring(L, 1, &l); + ptrdiff_t posi = posrelat(luaL_optinteger(L, 2, 1), l); + ptrdiff_t pose = posrelat(luaL_optinteger(L, 3, posi), l); + int n, i; + if (posi <= 0) posi = 1; + if ((size_t)pose > l) pose = l; + if (posi > pose) return 0; /* empty interval; return no values */ + n = (int)(pose - posi + 1); + if (posi + n <= pose) /* overflow? */ + luaL_error(L, "string slice too long"); + luaL_checkstack(L, n, "string slice too long"); + for (i=0; i= ms->level || ms->capture[l].len == CAP_UNFINISHED) + return luaL_error(ms->L, "invalid capture index"); + return l; +} + + +static int capture_to_close (MatchState *ms) { + int level = ms->level; + for (level--; level>=0; level--) + if (ms->capture[level].len == CAP_UNFINISHED) return level; + return luaL_error(ms->L, "invalid pattern capture"); +} + + +static const char *classend (MatchState *ms, const char *p) { + switch (*p++) { + case L_ESC: { + if (*p == '\0') + luaL_error(ms->L, "malformed pattern (ends with " LUA_QL("%%") ")"); + return p+1; + } + case '[': { + if (*p == '^') p++; + do { /* look for a `]' */ + if (*p == '\0') + luaL_error(ms->L, "malformed pattern (missing " LUA_QL("]") ")"); + if (*(p++) == L_ESC && *p != '\0') + p++; /* skip escapes (e.g. `%]') */ + } while (*p != ']'); + return p+1; + } + default: { + return p; + } + } +} + + +static int match_class (int c, int cl) { + int res; + switch (tolower(cl)) { + case 'a' : res = isalpha(c); break; + case 'c' : res = iscntrl(c); break; + case 'd' : res = isdigit(c); break; + case 'l' : res = islower(c); break; + case 'p' : res = ispunct(c); break; + case 's' : res = isspace(c); break; + case 'u' : res = isupper(c); break; + case 'w' : res = isalnum(c); break; + case 'x' : res = isxdigit(c); break; + case 'z' : res = (c == 0); break; + default: return (cl == c); + } + return (islower(cl) ? res : !res); +} + + +static int matchbracketclass (int c, const char *p, const char *ec) { + int sig = 1; + if (*(p+1) == '^') { + sig = 0; + p++; /* skip the `^' */ + } + while (++p < ec) { + if (*p == L_ESC) { + p++; + if (match_class(c, uchar(*p))) + return sig; + } + else if ((*(p+1) == '-') && (p+2 < ec)) { + p+=2; + if (uchar(*(p-2)) <= c && c <= uchar(*p)) + return sig; + } + else if (uchar(*p) == c) return sig; + } + return !sig; +} + + +static int singlematch (int c, const char *p, const char *ep) { + switch (*p) { + case '.': return 1; /* matches any char */ + case L_ESC: return match_class(c, uchar(*(p+1))); + case '[': return matchbracketclass(c, p, ep-1); + default: return (uchar(*p) == c); + } +} + + +static const char *match (MatchState *ms, const char *s, const char *p); + + +static const char *matchbalance (MatchState *ms, const char *s, + const char *p) { + if (*p == 0 || *(p+1) == 0) + luaL_error(ms->L, "unbalanced pattern"); + if (*s != *p) return NULL; + else { + int b = *p; + int e = *(p+1); + int cont = 1; + while (++s < ms->src_end) { + if (*s == e) { + if (--cont == 0) return s+1; + } + else if (*s == b) cont++; + } + } + return NULL; /* string ends out of balance */ +} + + +static const char *max_expand (MatchState *ms, const char *s, + const char *p, const char *ep) { + ptrdiff_t i = 0; /* counts maximum expand for item */ + while ((s+i)src_end && singlematch(uchar(*(s+i)), p, ep)) + i++; + /* keeps trying to match with the maximum repetitions */ + while (i>=0) { + const char *res = match(ms, (s+i), ep+1); + if (res) return res; + i--; /* else didn't match; reduce 1 repetition to try again */ + } + return NULL; +} + + +static const char *min_expand (MatchState *ms, const char *s, + const char *p, const char *ep) { + for (;;) { + const char *res = match(ms, s, ep+1); + if (res != NULL) + return res; + else if (ssrc_end && singlematch(uchar(*s), p, ep)) + s++; /* try with one more repetition */ + else return NULL; + } +} + + +static const char *start_capture (MatchState *ms, const char *s, + const char *p, int what) { + const char *res; + int level = ms->level; + if (level >= LUA_MAXCAPTURES) luaL_error(ms->L, "too many captures"); + ms->capture[level].init = s; + ms->capture[level].len = what; + ms->level = level+1; + if ((res=match(ms, s, p)) == NULL) /* match failed? */ + ms->level--; /* undo capture */ + return res; +} + + +static const char *end_capture (MatchState *ms, const char *s, + const char *p) { + int l = capture_to_close(ms); + const char *res; + ms->capture[l].len = s - ms->capture[l].init; /* close capture */ + if ((res = match(ms, s, p)) == NULL) /* match failed? */ + ms->capture[l].len = CAP_UNFINISHED; /* undo capture */ + return res; +} + + +static const char *match_capture (MatchState *ms, const char *s, int l) { + size_t len; + l = check_capture(ms, l); + len = ms->capture[l].len; + if ((size_t)(ms->src_end-s) >= len && + memcmp(ms->capture[l].init, s, len) == 0) + return s+len; + else return NULL; +} + + +static const char *match (MatchState *ms, const char *s, const char *p) { + init: /* using goto's to optimize tail recursion */ + switch (*p) { + case '(': { /* start capture */ + if (*(p+1) == ')') /* position capture? */ + return start_capture(ms, s, p+2, CAP_POSITION); + else + return start_capture(ms, s, p+1, CAP_UNFINISHED); + } + case ')': { /* end capture */ + return end_capture(ms, s, p+1); + } + case L_ESC: { + switch (*(p+1)) { + case 'b': { /* balanced string? */ + s = matchbalance(ms, s, p+2); + if (s == NULL) return NULL; + p+=4; goto init; /* else return match(ms, s, p+4); */ + } + case 'f': { /* frontier? */ + const char *ep; char previous; + p += 2; + if (*p != '[') + luaL_error(ms->L, "missing " LUA_QL("[") " after " + LUA_QL("%%f") " in pattern"); + ep = classend(ms, p); /* points to what is next */ + previous = (s == ms->src_init) ? '\0' : *(s-1); + if (matchbracketclass(uchar(previous), p, ep-1) || + !matchbracketclass(uchar(*s), p, ep-1)) return NULL; + p=ep; goto init; /* else return match(ms, s, ep); */ + } + default: { + if (isdigit(uchar(*(p+1)))) { /* capture results (%0-%9)? */ + s = match_capture(ms, s, uchar(*(p+1))); + if (s == NULL) return NULL; + p+=2; goto init; /* else return match(ms, s, p+2) */ + } + goto dflt; /* case default */ + } + } + } + case '\0': { /* end of pattern */ + return s; /* match succeeded */ + } + case '$': { + if (*(p+1) == '\0') /* is the `$' the last char in pattern? */ + return (s == ms->src_end) ? s : NULL; /* check end of string */ + else goto dflt; + } + default: dflt: { /* it is a pattern item */ + const char *ep = classend(ms, p); /* points to what is next */ + int m = ssrc_end && singlematch(uchar(*s), p, ep); + switch (*ep) { + case '?': { /* optional */ + const char *res; + if (m && ((res=match(ms, s+1, ep+1)) != NULL)) + return res; + p=ep+1; goto init; /* else return match(ms, s, ep+1); */ + } + case '*': { /* 0 or more repetitions */ + return max_expand(ms, s, p, ep); + } + case '+': { /* 1 or more repetitions */ + return (m ? max_expand(ms, s+1, p, ep) : NULL); + } + case '-': { /* 0 or more repetitions (minimum) */ + return min_expand(ms, s, p, ep); + } + default: { + if (!m) return NULL; + s++; p=ep; goto init; /* else return match(ms, s+1, ep); */ + } + } + } + } +} + + + +static const char *lmemfind (const char *s1, size_t l1, + const char *s2, size_t l2) { + if (l2 == 0) return s1; /* empty strings are everywhere */ + else if (l2 > l1) return NULL; /* avoids a negative `l1' */ + else { + const char *init; /* to search for a `*s2' inside `s1' */ + l2--; /* 1st char will be checked by `memchr' */ + l1 = l1-l2; /* `s2' cannot be found after that */ + while (l1 > 0 && (init = (const char *)memchr(s1, *s2, l1)) != NULL) { + init++; /* 1st char is already checked */ + if (memcmp(init, s2+1, l2) == 0) + return init-1; + else { /* correct `l1' and `s1' to try again */ + l1 -= init-s1; + s1 = init; + } + } + return NULL; /* not found */ + } +} + + +static void push_onecapture (MatchState *ms, int i, const char *s, + const char *e) { + if (i >= ms->level) { + if (i == 0) /* ms->level == 0, too */ + lua_pushlstring(ms->L, s, e - s); /* add whole match */ + else + luaL_error(ms->L, "invalid capture index"); + } + else { + ptrdiff_t l = ms->capture[i].len; + if (l == CAP_UNFINISHED) luaL_error(ms->L, "unfinished capture"); + if (l == CAP_POSITION) + lua_pushinteger(ms->L, ms->capture[i].init - ms->src_init + 1); + else + lua_pushlstring(ms->L, ms->capture[i].init, l); + } +} + + +static int push_captures (MatchState *ms, const char *s, const char *e) { + int i; + int nlevels = (ms->level == 0 && s) ? 1 : ms->level; + luaL_checkstack(ms->L, nlevels, "too many captures"); + for (i = 0; i < nlevels; i++) + push_onecapture(ms, i, s, e); + return nlevels; /* number of strings pushed */ +} + + +static int str_find_aux (lua_State *L, int find) { + size_t l1, l2; + const char *s = luaL_checklstring(L, 1, &l1); + const char *p = luaL_checklstring(L, 2, &l2); + ptrdiff_t init = posrelat(luaL_optinteger(L, 3, 1), l1) - 1; + if (init < 0) init = 0; + else if ((size_t)(init) > l1) init = (ptrdiff_t)l1; + if (find && (lua_toboolean(L, 4) || /* explicit request? */ + strpbrk(p, SPECIALS) == NULL)) { /* or no special characters? */ + /* do a plain search */ + const char *s2 = lmemfind(s+init, l1-init, p, l2); + if (s2) { + lua_pushinteger(L, s2-s+1); + lua_pushinteger(L, s2-s+l2); + return 2; + } + } + else { + MatchState ms; + int anchor = (*p == '^') ? (p++, 1) : 0; + const char *s1=s+init; + ms.L = L; + ms.src_init = s; + ms.src_end = s+l1; + do { + const char *res; + ms.level = 0; + if ((res=match(&ms, s1, p)) != NULL) { + if (find) { + lua_pushinteger(L, s1-s+1); /* start */ + lua_pushinteger(L, res-s); /* end */ + return push_captures(&ms, NULL, 0) + 2; + } + else + return push_captures(&ms, s1, res); + } + } while (s1++ < ms.src_end && !anchor); + } + lua_pushnil(L); /* not found */ + return 1; +} + + +static int str_find (lua_State *L) { + return str_find_aux(L, 1); +} + + +static int str_match (lua_State *L) { + return str_find_aux(L, 0); +} + + +static int gmatch_aux (lua_State *L) { + MatchState ms; + size_t ls; + const char *s = lua_tolstring(L, lua_upvalueindex(1), &ls); + const char *p = lua_tostring(L, lua_upvalueindex(2)); + const char *src; + ms.L = L; + ms.src_init = s; + ms.src_end = s+ls; + for (src = s + (size_t)lua_tointeger(L, lua_upvalueindex(3)); + src <= ms.src_end; + src++) { + const char *e; + ms.level = 0; + if ((e = match(&ms, src, p)) != NULL) { + lua_Integer newstart = e-s; + if (e == src) newstart++; /* empty match? go at least one position */ + lua_pushinteger(L, newstart); + lua_replace(L, lua_upvalueindex(3)); + return push_captures(&ms, src, e); + } + } + return 0; /* not found */ +} + + +static int gmatch (lua_State *L) { + luaL_checkstring(L, 1); + luaL_checkstring(L, 2); + lua_settop(L, 2); + lua_pushinteger(L, 0); + lua_pushcclosure(L, gmatch_aux, 3); + return 1; +} + + +static int gfind_nodef (lua_State *L) { + return luaL_error(L, LUA_QL("string.gfind") " was renamed to " + LUA_QL("string.gmatch")); +} + + +static void add_s (MatchState *ms, luaL_Buffer *b, const char *s, + const char *e) { + size_t l, i; + const char *news = lua_tolstring(ms->L, 3, &l); + for (i = 0; i < l; i++) { + if (news[i] != L_ESC) + luaL_addchar(b, news[i]); + else { + i++; /* skip ESC */ + if (!isdigit(uchar(news[i]))) + luaL_addchar(b, news[i]); + else if (news[i] == '0') + luaL_addlstring(b, s, e - s); + else { + push_onecapture(ms, news[i] - '1', s, e); + luaL_addvalue(b); /* add capture to accumulated result */ + } + } + } +} + + +static void add_value (MatchState *ms, luaL_Buffer *b, const char *s, + const char *e) { + lua_State *L = ms->L; + switch (lua_type(L, 3)) { + case LUA_TNUMBER: + case LUA_TSTRING: { + add_s(ms, b, s, e); + return; + } + case LUA_TFUNCTION: { + int n; + lua_pushvalue(L, 3); + n = push_captures(ms, s, e); + lua_call(L, n, 1); + break; + } + case LUA_TTABLE: { + push_onecapture(ms, 0, s, e); + lua_gettable(L, 3); + break; + } + } + if (!lua_toboolean(L, -1)) { /* nil or false? */ + lua_pop(L, 1); + lua_pushlstring(L, s, e - s); /* keep original text */ + } + else if (!lua_isstring(L, -1)) + luaL_error(L, "invalid replacement value (a %s)", luaL_typename(L, -1)); + luaL_addvalue(b); /* add result to accumulator */ +} + + +static int str_gsub (lua_State *L) { + size_t srcl; + const char *src = luaL_checklstring(L, 1, &srcl); + const char *p = luaL_checkstring(L, 2); + int tr = lua_type(L, 3); + int max_s = luaL_optint(L, 4, srcl+1); + int anchor = (*p == '^') ? (p++, 1) : 0; + int n = 0; + MatchState ms; + luaL_Buffer b; + luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING || + tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3, + "string/function/table expected"); + luaL_buffinit(L, &b); + ms.L = L; + ms.src_init = src; + ms.src_end = src+srcl; + while (n < max_s) { + const char *e; + ms.level = 0; + e = match(&ms, src, p); + if (e) { + n++; + add_value(&ms, &b, src, e); + } + if (e && e>src) /* non empty match? */ + src = e; /* skip it */ + else if (src < ms.src_end) + luaL_addchar(&b, *src++); + else break; + if (anchor) break; + } + luaL_addlstring(&b, src, ms.src_end-src); + luaL_pushresult(&b); + lua_pushinteger(L, n); /* number of substitutions */ + return 2; +} + +/* }====================================================== */ + + +/* maximum size of each formatted item (> len(format('%99.99f', -1e308))) */ +#define MAX_ITEM 512 +/* valid flags in a format specification */ +#define FLAGS "-+ #0" +/* +** maximum size of each format specification (such as '%-099.99d') +** (+10 accounts for %99.99x plus margin of error) +*/ +#define MAX_FORMAT (sizeof(FLAGS) + sizeof(LUA_INTFRMLEN) + 10) + + +static void addquoted (lua_State *L, luaL_Buffer *b, int arg) { + size_t l; + const char *s = luaL_checklstring(L, arg, &l); + luaL_addchar(b, '"'); + while (l--) { + switch (*s) { + case '"': case '\\': case '\n': { + luaL_addchar(b, '\\'); + luaL_addchar(b, *s); + break; + } + case '\r': { + luaL_addlstring(b, "\\r", 2); + break; + } + case '\0': { + luaL_addlstring(b, "\\000", 4); + break; + } + default: { + luaL_addchar(b, *s); + break; + } + } + s++; + } + luaL_addchar(b, '"'); +} + +static const char *scanformat (lua_State *L, const char *strfrmt, char *form) { + const char *p = strfrmt; + while (*p != '\0' && strchr(FLAGS, *p) != NULL) p++; /* skip flags */ + if ((size_t)(p - strfrmt) >= sizeof(FLAGS)) + luaL_error(L, "invalid format (repeated flags)"); + if (isdigit(uchar(*p))) p++; /* skip width */ + if (isdigit(uchar(*p))) p++; /* (2 digits at most) */ + if (*p == '.') { + p++; + if (isdigit(uchar(*p))) p++; /* skip precision */ + if (isdigit(uchar(*p))) p++; /* (2 digits at most) */ + } + if (isdigit(uchar(*p))) + luaL_error(L, "invalid format (width or precision too long)"); + *(form++) = '%'; + strncpy(form, strfrmt, p - strfrmt + 1); + form += p - strfrmt + 1; + *form = '\0'; + return p; +} + + +static void addintlen (char *form) { + size_t l = strlen(form); + char spec = form[l - 1]; + strcpy(form + l - 1, LUA_INTFRMLEN); + form[l + sizeof(LUA_INTFRMLEN) - 2] = spec; + form[l + sizeof(LUA_INTFRMLEN) - 1] = '\0'; +} + + +static int str_format (lua_State *L) { + int arg = 1; + size_t sfl; + const char *strfrmt = luaL_checklstring(L, arg, &sfl); + const char *strfrmt_end = strfrmt+sfl; + luaL_Buffer b; + luaL_buffinit(L, &b); + while (strfrmt < strfrmt_end) { + if (*strfrmt != L_ESC) + luaL_addchar(&b, *strfrmt++); + else if (*++strfrmt == L_ESC) + luaL_addchar(&b, *strfrmt++); /* %% */ + else { /* format item */ + char form[MAX_FORMAT]; /* to store the format (`%...') */ + char buff[MAX_ITEM]; /* to store the formatted item */ + arg++; + strfrmt = scanformat(L, strfrmt, form); + switch (*strfrmt++) { + case 'c': { + sprintf(buff, form, (int)luaL_checknumber(L, arg)); + break; + } + case 'd': case 'i': { + addintlen(form); + sprintf(buff, form, (LUA_INTFRM_T)luaL_checknumber(L, arg)); + break; + } + case 'o': case 'u': case 'x': case 'X': { + addintlen(form); + sprintf(buff, form, (unsigned LUA_INTFRM_T)luaL_checknumber(L, arg)); + break; + } + case 'e': case 'E': case 'f': + case 'g': case 'G': { + sprintf(buff, form, (double)luaL_checknumber(L, arg)); + break; + } + case 'q': { + addquoted(L, &b, arg); + continue; /* skip the 'addsize' at the end */ + } + case 's': { + size_t l; + const char *s = luaL_checklstring(L, arg, &l); + if (!strchr(form, '.') && l >= 100) { + /* no precision and string is too long to be formatted; + keep original string */ + lua_pushvalue(L, arg); + luaL_addvalue(&b); + continue; /* skip the `addsize' at the end */ + } + else { + sprintf(buff, form, s); + break; + } + } + default: { /* also treat cases `pnLlh' */ + return luaL_error(L, "invalid option " LUA_QL("%%%c") " to " + LUA_QL("format"), *(strfrmt - 1)); + } + } + luaL_addlstring(&b, buff, strlen(buff)); + } + } + luaL_pushresult(&b); + return 1; +} + + +static const luaL_Reg strlib[] = { + {"byte", str_byte}, + {"char", str_char}, + {"dump", str_dump}, + {"find", str_find}, + {"format", str_format}, + {"gfind", gfind_nodef}, + {"gmatch", gmatch}, + {"gsub", str_gsub}, + {"len", str_len}, + {"lower", str_lower}, + {"match", str_match}, + {"rep", str_rep}, + {"reverse", str_reverse}, + {"sub", str_sub}, + {"upper", str_upper}, + {NULL, NULL} +}; + + +static void createmetatable (lua_State *L) { + lua_createtable(L, 0, 1); /* create metatable for strings */ + lua_pushliteral(L, ""); /* dummy string */ + lua_pushvalue(L, -2); + lua_setmetatable(L, -2); /* set string metatable */ + lua_pop(L, 1); /* pop dummy string */ + lua_pushvalue(L, -2); /* string library... */ + lua_setfield(L, -2, "__index"); /* ...is the __index metamethod */ + lua_pop(L, 1); /* pop metatable */ +} + + +/* +** Open string library +*/ +LUALIB_API int luaopen_string (lua_State *L) { + luaL_register(L, LUA_STRLIBNAME, strlib); +#if defined(LUA_COMPAT_GFIND) + lua_getfield(L, -1, "gmatch"); + lua_setfield(L, -2, "gfind"); +#endif + createmetatable(L); + return 1; +} + diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/src/ltable.c b/mod/pub.mod/lua.mod/lua-5.1.4/src/ltable.c new file mode 100644 index 0000000..ec84f4f --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/src/ltable.c @@ -0,0 +1,588 @@ +/* +** $Id: ltable.c,v 2.32.1.2 2007/12/28 15:32:23 roberto Exp $ +** Lua tables (hash) +** See Copyright Notice in lua.h +*/ + + +/* +** Implementation of tables (aka arrays, objects, or hash tables). +** Tables keep its elements in two parts: an array part and a hash part. +** Non-negative integer keys are all candidates to be kept in the array +** part. The actual size of the array is the largest `n' such that at +** least half the slots between 0 and n are in use. +** Hash uses a mix of chained scatter table with Brent's variation. +** A main invariant of these tables is that, if an element is not +** in its main position (i.e. the `original' position that its hash gives +** to it), then the colliding element is in its own main position. +** Hence even when the load factor reaches 100%, performance remains good. +*/ + +#include +#include + +#define ltable_c +#define LUA_CORE + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "ltable.h" + + +/* +** max size of array part is 2^MAXBITS +*/ +#if LUAI_BITSINT > 26 +#define MAXBITS 26 +#else +#define MAXBITS (LUAI_BITSINT-2) +#endif + +#define MAXASIZE (1 << MAXBITS) + + +#define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t)))) + +#define hashstr(t,str) hashpow2(t, (str)->tsv.hash) +#define hashboolean(t,p) hashpow2(t, p) + + +/* +** for some types, it is better to avoid modulus by power of 2, as +** they tend to have many 2 factors. +*/ +#define hashmod(t,n) (gnode(t, ((n) % ((sizenode(t)-1)|1)))) + + +#define hashpointer(t,p) hashmod(t, IntPoint(p)) + + +/* +** number of ints inside a lua_Number +*/ +#define numints cast_int(sizeof(lua_Number)/sizeof(int)) + + + +#define dummynode (&dummynode_) + +static const Node dummynode_ = { + {{NULL}, LUA_TNIL}, /* value */ + {{{NULL}, LUA_TNIL, NULL}} /* key */ +}; + + +/* +** hash for lua_Numbers +*/ +static Node *hashnum (const Table *t, lua_Number n) { + unsigned int a[numints]; + int i; + if (luai_numeq(n, 0)) /* avoid problems with -0 */ + return gnode(t, 0); + memcpy(a, &n, sizeof(a)); + for (i = 1; i < numints; i++) a[0] += a[i]; + return hashmod(t, a[0]); +} + + + +/* +** returns the `main' position of an element in a table (that is, the index +** of its hash value) +*/ +static Node *mainposition (const Table *t, const TValue *key) { + switch (ttype(key)) { + case LUA_TNUMBER: + return hashnum(t, nvalue(key)); + case LUA_TSTRING: + return hashstr(t, rawtsvalue(key)); + case LUA_TBOOLEAN: + return hashboolean(t, bvalue(key)); + case LUA_TLIGHTUSERDATA: + return hashpointer(t, pvalue(key)); + default: + return hashpointer(t, gcvalue(key)); + } +} + + +/* +** returns the index for `key' if `key' is an appropriate key to live in +** the array part of the table, -1 otherwise. +*/ +static int arrayindex (const TValue *key) { + if (ttisnumber(key)) { + lua_Number n = nvalue(key); + int k; + lua_number2int(k, n); + if (luai_numeq(cast_num(k), n)) + return k; + } + return -1; /* `key' did not match some condition */ +} + + +/* +** returns the index of a `key' for table traversals. First goes all +** elements in the array part, then elements in the hash part. The +** beginning of a traversal is signalled by -1. +*/ +static int findindex (lua_State *L, Table *t, StkId key) { + int i; + if (ttisnil(key)) return -1; /* first iteration */ + i = arrayindex(key); + if (0 < i && i <= t->sizearray) /* is `key' inside array part? */ + return i-1; /* yes; that's the index (corrected to C) */ + else { + Node *n = mainposition(t, key); + do { /* check whether `key' is somewhere in the chain */ + /* key may be dead already, but it is ok to use it in `next' */ + if (luaO_rawequalObj(key2tval(n), key) || + (ttype(gkey(n)) == LUA_TDEADKEY && iscollectable(key) && + gcvalue(gkey(n)) == gcvalue(key))) { + i = cast_int(n - gnode(t, 0)); /* key index in hash table */ + /* hash elements are numbered after array ones */ + return i + t->sizearray; + } + else n = gnext(n); + } while (n); + luaG_runerror(L, "invalid key to " LUA_QL("next")); /* key not found */ + return 0; /* to avoid warnings */ + } +} + + +int luaH_next (lua_State *L, Table *t, StkId key) { + int i = findindex(L, t, key); /* find original element */ + for (i++; i < t->sizearray; i++) { /* try first array part */ + if (!ttisnil(&t->array[i])) { /* a non-nil value? */ + setnvalue(key, cast_num(i+1)); + setobj2s(L, key+1, &t->array[i]); + return 1; + } + } + for (i -= t->sizearray; i < sizenode(t); i++) { /* then hash part */ + if (!ttisnil(gval(gnode(t, i)))) { /* a non-nil value? */ + setobj2s(L, key, key2tval(gnode(t, i))); + setobj2s(L, key+1, gval(gnode(t, i))); + return 1; + } + } + return 0; /* no more elements */ +} + + +/* +** {============================================================= +** Rehash +** ============================================================== +*/ + + +static int computesizes (int nums[], int *narray) { + int i; + int twotoi; /* 2^i */ + int a = 0; /* number of elements smaller than 2^i */ + int na = 0; /* number of elements to go to array part */ + int n = 0; /* optimal size for array part */ + for (i = 0, twotoi = 1; twotoi/2 < *narray; i++, twotoi *= 2) { + if (nums[i] > 0) { + a += nums[i]; + if (a > twotoi/2) { /* more than half elements present? */ + n = twotoi; /* optimal size (till now) */ + na = a; /* all elements smaller than n will go to array part */ + } + } + if (a == *narray) break; /* all elements already counted */ + } + *narray = n; + lua_assert(*narray/2 <= na && na <= *narray); + return na; +} + + +static int countint (const TValue *key, int *nums) { + int k = arrayindex(key); + if (0 < k && k <= MAXASIZE) { /* is `key' an appropriate array index? */ + nums[ceillog2(k)]++; /* count as such */ + return 1; + } + else + return 0; +} + + +static int numusearray (const Table *t, int *nums) { + int lg; + int ttlg; /* 2^lg */ + int ause = 0; /* summation of `nums' */ + int i = 1; /* count to traverse all array keys */ + for (lg=0, ttlg=1; lg<=MAXBITS; lg++, ttlg*=2) { /* for each slice */ + int lc = 0; /* counter */ + int lim = ttlg; + if (lim > t->sizearray) { + lim = t->sizearray; /* adjust upper limit */ + if (i > lim) + break; /* no more elements to count */ + } + /* count elements in range (2^(lg-1), 2^lg] */ + for (; i <= lim; i++) { + if (!ttisnil(&t->array[i-1])) + lc++; + } + nums[lg] += lc; + ause += lc; + } + return ause; +} + + +static int numusehash (const Table *t, int *nums, int *pnasize) { + int totaluse = 0; /* total number of elements */ + int ause = 0; /* summation of `nums' */ + int i = sizenode(t); + while (i--) { + Node *n = &t->node[i]; + if (!ttisnil(gval(n))) { + ause += countint(key2tval(n), nums); + totaluse++; + } + } + *pnasize += ause; + return totaluse; +} + + +static void setarrayvector (lua_State *L, Table *t, int size) { + int i; + luaM_reallocvector(L, t->array, t->sizearray, size, TValue); + for (i=t->sizearray; iarray[i]); + t->sizearray = size; +} + + +static void setnodevector (lua_State *L, Table *t, int size) { + int lsize; + if (size == 0) { /* no elements to hash part? */ + t->node = cast(Node *, dummynode); /* use common `dummynode' */ + lsize = 0; + } + else { + int i; + lsize = ceillog2(size); + if (lsize > MAXBITS) + luaG_runerror(L, "table overflow"); + size = twoto(lsize); + t->node = luaM_newvector(L, size, Node); + for (i=0; ilsizenode = cast_byte(lsize); + t->lastfree = gnode(t, size); /* all positions are free */ +} + + +static void resize (lua_State *L, Table *t, int nasize, int nhsize) { + int i; + int oldasize = t->sizearray; + int oldhsize = t->lsizenode; + Node *nold = t->node; /* save old hash ... */ + if (nasize > oldasize) /* array part must grow? */ + setarrayvector(L, t, nasize); + /* create new hash part with appropriate size */ + setnodevector(L, t, nhsize); + if (nasize < oldasize) { /* array part must shrink? */ + t->sizearray = nasize; + /* re-insert elements from vanishing slice */ + for (i=nasize; iarray[i])) + setobjt2t(L, luaH_setnum(L, t, i+1), &t->array[i]); + } + /* shrink array */ + luaM_reallocvector(L, t->array, oldasize, nasize, TValue); + } + /* re-insert elements from hash part */ + for (i = twoto(oldhsize) - 1; i >= 0; i--) { + Node *old = nold+i; + if (!ttisnil(gval(old))) + setobjt2t(L, luaH_set(L, t, key2tval(old)), gval(old)); + } + if (nold != dummynode) + luaM_freearray(L, nold, twoto(oldhsize), Node); /* free old array */ +} + + +void luaH_resizearray (lua_State *L, Table *t, int nasize) { + int nsize = (t->node == dummynode) ? 0 : sizenode(t); + resize(L, t, nasize, nsize); +} + + +static void rehash (lua_State *L, Table *t, const TValue *ek) { + int nasize, na; + int nums[MAXBITS+1]; /* nums[i] = number of keys between 2^(i-1) and 2^i */ + int i; + int totaluse; + for (i=0; i<=MAXBITS; i++) nums[i] = 0; /* reset counts */ + nasize = numusearray(t, nums); /* count keys in array part */ + totaluse = nasize; /* all those keys are integer keys */ + totaluse += numusehash(t, nums, &nasize); /* count keys in hash part */ + /* count extra key */ + nasize += countint(ek, nums); + totaluse++; + /* compute new size for array part */ + na = computesizes(nums, &nasize); + /* resize the table to new computed sizes */ + resize(L, t, nasize, totaluse - na); +} + + + +/* +** }============================================================= +*/ + + +Table *luaH_new (lua_State *L, int narray, int nhash) { + Table *t = luaM_new(L, Table); + luaC_link(L, obj2gco(t), LUA_TTABLE); + t->metatable = NULL; + t->flags = cast_byte(~0); + /* temporary values (kept only if some malloc fails) */ + t->array = NULL; + t->sizearray = 0; + t->lsizenode = 0; + t->node = cast(Node *, dummynode); + setarrayvector(L, t, narray); + setnodevector(L, t, nhash); + return t; +} + + +void luaH_free (lua_State *L, Table *t) { + if (t->node != dummynode) + luaM_freearray(L, t->node, sizenode(t), Node); + luaM_freearray(L, t->array, t->sizearray, TValue); + luaM_free(L, t); +} + + +static Node *getfreepos (Table *t) { + while (t->lastfree-- > t->node) { + if (ttisnil(gkey(t->lastfree))) + return t->lastfree; + } + return NULL; /* could not find a free place */ +} + + + +/* +** inserts a new key into a hash table; first, check whether key's main +** position is free. If not, check whether colliding node is in its main +** position or not: if it is not, move colliding node to an empty place and +** put new key in its main position; otherwise (colliding node is in its main +** position), new key goes to an empty position. +*/ +static TValue *newkey (lua_State *L, Table *t, const TValue *key) { + Node *mp = mainposition(t, key); + if (!ttisnil(gval(mp)) || mp == dummynode) { + Node *othern; + Node *n = getfreepos(t); /* get a free place */ + if (n == NULL) { /* cannot find a free place? */ + rehash(L, t, key); /* grow table */ + return luaH_set(L, t, key); /* re-insert key into grown table */ + } + lua_assert(n != dummynode); + othern = mainposition(t, key2tval(mp)); + if (othern != mp) { /* is colliding node out of its main position? */ + /* yes; move colliding node into free position */ + while (gnext(othern) != mp) othern = gnext(othern); /* find previous */ + gnext(othern) = n; /* redo the chain with `n' in place of `mp' */ + *n = *mp; /* copy colliding node into free pos. (mp->next also goes) */ + gnext(mp) = NULL; /* now `mp' is free */ + setnilvalue(gval(mp)); + } + else { /* colliding node is in its own main position */ + /* new node will go into free position */ + gnext(n) = gnext(mp); /* chain new position */ + gnext(mp) = n; + mp = n; + } + } + gkey(mp)->value = key->value; gkey(mp)->tt = key->tt; + luaC_barriert(L, t, key); + lua_assert(ttisnil(gval(mp))); + return gval(mp); +} + + +/* +** search function for integers +*/ +const TValue *luaH_getnum (Table *t, int key) { + /* (1 <= key && key <= t->sizearray) */ + if (cast(unsigned int, key-1) < cast(unsigned int, t->sizearray)) + return &t->array[key-1]; + else { + lua_Number nk = cast_num(key); + Node *n = hashnum(t, nk); + do { /* check whether `key' is somewhere in the chain */ + if (ttisnumber(gkey(n)) && luai_numeq(nvalue(gkey(n)), nk)) + return gval(n); /* that's it */ + else n = gnext(n); + } while (n); + return luaO_nilobject; + } +} + + +/* +** search function for strings +*/ +const TValue *luaH_getstr (Table *t, TString *key) { + Node *n = hashstr(t, key); + do { /* check whether `key' is somewhere in the chain */ + if (ttisstring(gkey(n)) && rawtsvalue(gkey(n)) == key) + return gval(n); /* that's it */ + else n = gnext(n); + } while (n); + return luaO_nilobject; +} + + +/* +** main search function +*/ +const TValue *luaH_get (Table *t, const TValue *key) { + switch (ttype(key)) { + case LUA_TNIL: return luaO_nilobject; + case LUA_TSTRING: return luaH_getstr(t, rawtsvalue(key)); + case LUA_TNUMBER: { + int k; + lua_Number n = nvalue(key); + lua_number2int(k, n); + if (luai_numeq(cast_num(k), nvalue(key))) /* index is int? */ + return luaH_getnum(t, k); /* use specialized version */ + /* else go through */ + } + default: { + Node *n = mainposition(t, key); + do { /* check whether `key' is somewhere in the chain */ + if (luaO_rawequalObj(key2tval(n), key)) + return gval(n); /* that's it */ + else n = gnext(n); + } while (n); + return luaO_nilobject; + } + } +} + + +TValue *luaH_set (lua_State *L, Table *t, const TValue *key) { + const TValue *p = luaH_get(t, key); + t->flags = 0; + if (p != luaO_nilobject) + return cast(TValue *, p); + else { + if (ttisnil(key)) luaG_runerror(L, "table index is nil"); + else if (ttisnumber(key) && luai_numisnan(nvalue(key))) + luaG_runerror(L, "table index is NaN"); + return newkey(L, t, key); + } +} + + +TValue *luaH_setnum (lua_State *L, Table *t, int key) { + const TValue *p = luaH_getnum(t, key); + if (p != luaO_nilobject) + return cast(TValue *, p); + else { + TValue k; + setnvalue(&k, cast_num(key)); + return newkey(L, t, &k); + } +} + + +TValue *luaH_setstr (lua_State *L, Table *t, TString *key) { + const TValue *p = luaH_getstr(t, key); + if (p != luaO_nilobject) + return cast(TValue *, p); + else { + TValue k; + setsvalue(L, &k, key); + return newkey(L, t, &k); + } +} + + +static int unbound_search (Table *t, unsigned int j) { + unsigned int i = j; /* i is zero or a present index */ + j++; + /* find `i' and `j' such that i is present and j is not */ + while (!ttisnil(luaH_getnum(t, j))) { + i = j; + j *= 2; + if (j > cast(unsigned int, MAX_INT)) { /* overflow? */ + /* table was built with bad purposes: resort to linear search */ + i = 1; + while (!ttisnil(luaH_getnum(t, i))) i++; + return i - 1; + } + } + /* now do a binary search between them */ + while (j - i > 1) { + unsigned int m = (i+j)/2; + if (ttisnil(luaH_getnum(t, m))) j = m; + else i = m; + } + return i; +} + + +/* +** Try to find a boundary in table `t'. A `boundary' is an integer index +** such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil). +*/ +int luaH_getn (Table *t) { + unsigned int j = t->sizearray; + if (j > 0 && ttisnil(&t->array[j - 1])) { + /* there is a boundary in the array part: (binary) search for it */ + unsigned int i = 0; + while (j - i > 1) { + unsigned int m = (i+j)/2; + if (ttisnil(&t->array[m - 1])) j = m; + else i = m; + } + return i; + } + /* else must find a boundary in hash part */ + else if (t->node == dummynode) /* hash part is empty? */ + return j; /* that is easy... */ + else return unbound_search(t, j); +} + + + +#if defined(LUA_DEBUG) + +Node *luaH_mainposition (const Table *t, const TValue *key) { + return mainposition(t, key); +} + +int luaH_isdummy (Node *n) { return n == dummynode; } + +#endif diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/src/ltable.h b/mod/pub.mod/lua.mod/lua-5.1.4/src/ltable.h new file mode 100644 index 0000000..f5b9d5e --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/src/ltable.h @@ -0,0 +1,40 @@ +/* +** $Id: ltable.h,v 2.10.1.1 2007/12/27 13:02:25 roberto Exp $ +** Lua tables (hash) +** See Copyright Notice in lua.h +*/ + +#ifndef ltable_h +#define ltable_h + +#include "lobject.h" + + +#define gnode(t,i) (&(t)->node[i]) +#define gkey(n) (&(n)->i_key.nk) +#define gval(n) (&(n)->i_val) +#define gnext(n) ((n)->i_key.nk.next) + +#define key2tval(n) (&(n)->i_key.tvk) + + +LUAI_FUNC const TValue *luaH_getnum (Table *t, int key); +LUAI_FUNC TValue *luaH_setnum (lua_State *L, Table *t, int key); +LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key); +LUAI_FUNC TValue *luaH_setstr (lua_State *L, Table *t, TString *key); +LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key); +LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key); +LUAI_FUNC Table *luaH_new (lua_State *L, int narray, int lnhash); +LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, int nasize); +LUAI_FUNC void luaH_free (lua_State *L, Table *t); +LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key); +LUAI_FUNC int luaH_getn (Table *t); + + +#if defined(LUA_DEBUG) +LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key); +LUAI_FUNC int luaH_isdummy (Node *n); +#endif + + +#endif diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/src/ltablib.c b/mod/pub.mod/lua.mod/lua-5.1.4/src/ltablib.c new file mode 100644 index 0000000..b6d9cb4 --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/src/ltablib.c @@ -0,0 +1,287 @@ +/* +** $Id: ltablib.c,v 1.38.1.3 2008/02/14 16:46:58 roberto Exp $ +** Library for Table Manipulation +** See Copyright Notice in lua.h +*/ + + +#include + +#define ltablib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +#define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n)) + + +static int foreachi (lua_State *L) { + int i; + int n = aux_getn(L, 1); + luaL_checktype(L, 2, LUA_TFUNCTION); + for (i=1; i <= n; i++) { + lua_pushvalue(L, 2); /* function */ + lua_pushinteger(L, i); /* 1st argument */ + lua_rawgeti(L, 1, i); /* 2nd argument */ + lua_call(L, 2, 1); + if (!lua_isnil(L, -1)) + return 1; + lua_pop(L, 1); /* remove nil result */ + } + return 0; +} + + +static int foreach (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + luaL_checktype(L, 2, LUA_TFUNCTION); + lua_pushnil(L); /* first key */ + while (lua_next(L, 1)) { + lua_pushvalue(L, 2); /* function */ + lua_pushvalue(L, -3); /* key */ + lua_pushvalue(L, -3); /* value */ + lua_call(L, 2, 1); + if (!lua_isnil(L, -1)) + return 1; + lua_pop(L, 2); /* remove value and result */ + } + return 0; +} + + +static int maxn (lua_State *L) { + lua_Number max = 0; + luaL_checktype(L, 1, LUA_TTABLE); + lua_pushnil(L); /* first key */ + while (lua_next(L, 1)) { + lua_pop(L, 1); /* remove value */ + if (lua_type(L, -1) == LUA_TNUMBER) { + lua_Number v = lua_tonumber(L, -1); + if (v > max) max = v; + } + } + lua_pushnumber(L, max); + return 1; +} + + +static int getn (lua_State *L) { + lua_pushinteger(L, aux_getn(L, 1)); + return 1; +} + + +static int setn (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); +#ifndef luaL_setn + luaL_setn(L, 1, luaL_checkint(L, 2)); +#else + luaL_error(L, LUA_QL("setn") " is obsolete"); +#endif + lua_pushvalue(L, 1); + return 1; +} + + +static int tinsert (lua_State *L) { + int e = aux_getn(L, 1) + 1; /* first empty element */ + int pos; /* where to insert new element */ + switch (lua_gettop(L)) { + case 2: { /* called with only 2 arguments */ + pos = e; /* insert new element at the end */ + break; + } + case 3: { + int i; + pos = luaL_checkint(L, 2); /* 2nd argument is the position */ + if (pos > e) e = pos; /* `grow' array if necessary */ + for (i = e; i > pos; i--) { /* move up elements */ + lua_rawgeti(L, 1, i-1); + lua_rawseti(L, 1, i); /* t[i] = t[i-1] */ + } + break; + } + default: { + return luaL_error(L, "wrong number of arguments to " LUA_QL("insert")); + } + } + luaL_setn(L, 1, e); /* new size */ + lua_rawseti(L, 1, pos); /* t[pos] = v */ + return 0; +} + + +static int tremove (lua_State *L) { + int e = aux_getn(L, 1); + int pos = luaL_optint(L, 2, e); + if (!(1 <= pos && pos <= e)) /* position is outside bounds? */ + return 0; /* nothing to remove */ + luaL_setn(L, 1, e - 1); /* t.n = n-1 */ + lua_rawgeti(L, 1, pos); /* result = t[pos] */ + for ( ;pos= P */ + while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) { + if (i>u) luaL_error(L, "invalid order function for sorting"); + lua_pop(L, 1); /* remove a[i] */ + } + /* repeat --j until a[j] <= P */ + while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) { + if (j + +#define ltm_c +#define LUA_CORE + +#include "lua.h" + +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" + + + +const char *const luaT_typenames[] = { + "nil", "boolean", "userdata", "number", + "string", "table", "function", "userdata", "thread", + "proto", "upval" +}; + + +void luaT_init (lua_State *L) { + static const char *const luaT_eventname[] = { /* ORDER TM */ + "__index", "__newindex", + "__gc", "__mode", "__eq", + "__add", "__sub", "__mul", "__div", "__mod", + "__pow", "__unm", "__len", "__lt", "__le", + "__concat", "__call" + }; + int i; + for (i=0; itmname[i] = luaS_new(L, luaT_eventname[i]); + luaS_fix(G(L)->tmname[i]); /* never collect these names */ + } +} + + +/* +** function to be used with macro "fasttm": optimized for absence of +** tag methods +*/ +const TValue *luaT_gettm (Table *events, TMS event, TString *ename) { + const TValue *tm = luaH_getstr(events, ename); + lua_assert(event <= TM_EQ); + if (ttisnil(tm)) { /* no tag method? */ + events->flags |= cast_byte(1u<metatable; + break; + case LUA_TUSERDATA: + mt = uvalue(o)->metatable; + break; + default: + mt = G(L)->mt[ttype(o)]; + } + return (mt ? luaH_getstr(mt, G(L)->tmname[event]) : luaO_nilobject); +} + diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/src/ltm.h b/mod/pub.mod/lua.mod/lua-5.1.4/src/ltm.h new file mode 100644 index 0000000..64343b7 --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/src/ltm.h @@ -0,0 +1,54 @@ +/* +** $Id: ltm.h,v 2.6.1.1 2007/12/27 13:02:25 roberto Exp $ +** Tag methods +** See Copyright Notice in lua.h +*/ + +#ifndef ltm_h +#define ltm_h + + +#include "lobject.h" + + +/* +* WARNING: if you change the order of this enumeration, +* grep "ORDER TM" +*/ +typedef enum { + TM_INDEX, + TM_NEWINDEX, + TM_GC, + TM_MODE, + TM_EQ, /* last tag method with `fast' access */ + TM_ADD, + TM_SUB, + TM_MUL, + TM_DIV, + TM_MOD, + TM_POW, + TM_UNM, + TM_LEN, + TM_LT, + TM_LE, + TM_CONCAT, + TM_CALL, + TM_N /* number of elements in the enum */ +} TMS; + + + +#define gfasttm(g,et,e) ((et) == NULL ? NULL : \ + ((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e])) + +#define fasttm(l,et,e) gfasttm(G(l), et, e) + +LUAI_DATA const char *const luaT_typenames[]; + + +LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename); +LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, + TMS event); +LUAI_FUNC void luaT_init (lua_State *L); + +#endif diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/src/lua.c b/mod/pub.mod/lua.mod/lua-5.1.4/src/lua.c new file mode 100644 index 0000000..3a46609 --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/src/lua.c @@ -0,0 +1,392 @@ +/* +** $Id: lua.c,v 1.160.1.2 2007/12/28 15:32:23 roberto Exp $ +** Lua stand-alone interpreter +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include +#include + +#define lua_c + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + + +static lua_State *globalL = NULL; + +static const char *progname = LUA_PROGNAME; + + + +static void lstop (lua_State *L, lua_Debug *ar) { + (void)ar; /* unused arg. */ + lua_sethook(L, NULL, 0, 0); + luaL_error(L, "interrupted!"); +} + + +static void laction (int i) { + signal(i, SIG_DFL); /* if another SIGINT happens before lstop, + terminate process (default action) */ + lua_sethook(globalL, lstop, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1); +} + + +static void print_usage (void) { + fprintf(stderr, + "usage: %s [options] [script [args]].\n" + "Available options are:\n" + " -e stat execute string " LUA_QL("stat") "\n" + " -l name require library " LUA_QL("name") "\n" + " -i enter interactive mode after executing " LUA_QL("script") "\n" + " -v show version information\n" + " -- stop handling options\n" + " - execute stdin and stop handling options\n" + , + progname); + fflush(stderr); +} + + +static void l_message (const char *pname, const char *msg) { + if (pname) fprintf(stderr, "%s: ", pname); + fprintf(stderr, "%s\n", msg); + fflush(stderr); +} + + +static int report (lua_State *L, int status) { + if (status && !lua_isnil(L, -1)) { + const char *msg = lua_tostring(L, -1); + if (msg == NULL) msg = "(error object is not a string)"; + l_message(progname, msg); + lua_pop(L, 1); + } + return status; +} + + +static int traceback (lua_State *L) { + if (!lua_isstring(L, 1)) /* 'message' not a string? */ + return 1; /* keep it intact */ + lua_getfield(L, LUA_GLOBALSINDEX, "debug"); + if (!lua_istable(L, -1)) { + lua_pop(L, 1); + return 1; + } + lua_getfield(L, -1, "traceback"); + if (!lua_isfunction(L, -1)) { + lua_pop(L, 2); + return 1; + } + lua_pushvalue(L, 1); /* pass error message */ + lua_pushinteger(L, 2); /* skip this function and traceback */ + lua_call(L, 2, 1); /* call debug.traceback */ + return 1; +} + + +static int docall (lua_State *L, int narg, int clear) { + int status; + int base = lua_gettop(L) - narg; /* function index */ + lua_pushcfunction(L, traceback); /* push traceback function */ + lua_insert(L, base); /* put it under chunk and args */ + signal(SIGINT, laction); + status = lua_pcall(L, narg, (clear ? 0 : LUA_MULTRET), base); + signal(SIGINT, SIG_DFL); + lua_remove(L, base); /* remove traceback function */ + /* force a complete garbage collection in case of errors */ + if (status != 0) lua_gc(L, LUA_GCCOLLECT, 0); + return status; +} + + +static void print_version (void) { + l_message(NULL, LUA_RELEASE " " LUA_COPYRIGHT); +} + + +static int getargs (lua_State *L, char **argv, int n) { + int narg; + int i; + int argc = 0; + while (argv[argc]) argc++; /* count total number of arguments */ + narg = argc - (n + 1); /* number of arguments to the script */ + luaL_checkstack(L, narg + 3, "too many arguments to script"); + for (i=n+1; i < argc; i++) + lua_pushstring(L, argv[i]); + lua_createtable(L, narg, n + 1); + for (i=0; i < argc; i++) { + lua_pushstring(L, argv[i]); + lua_rawseti(L, -2, i - n); + } + return narg; +} + + +static int dofile (lua_State *L, const char *name) { + int status = luaL_loadfile(L, name) || docall(L, 0, 1); + return report(L, status); +} + + +static int dostring (lua_State *L, const char *s, const char *name) { + int status = luaL_loadbuffer(L, s, strlen(s), name) || docall(L, 0, 1); + return report(L, status); +} + + +static int dolibrary (lua_State *L, const char *name) { + lua_getglobal(L, "require"); + lua_pushstring(L, name); + return report(L, docall(L, 1, 1)); +} + + +static const char *get_prompt (lua_State *L, int firstline) { + const char *p; + lua_getfield(L, LUA_GLOBALSINDEX, firstline ? "_PROMPT" : "_PROMPT2"); + p = lua_tostring(L, -1); + if (p == NULL) p = (firstline ? LUA_PROMPT : LUA_PROMPT2); + lua_pop(L, 1); /* remove global */ + return p; +} + + +static int incomplete (lua_State *L, int status) { + if (status == LUA_ERRSYNTAX) { + size_t lmsg; + const char *msg = lua_tolstring(L, -1, &lmsg); + const char *tp = msg + lmsg - (sizeof(LUA_QL("")) - 1); + if (strstr(msg, LUA_QL("")) == tp) { + lua_pop(L, 1); + return 1; + } + } + return 0; /* else... */ +} + + +static int pushline (lua_State *L, int firstline) { + char buffer[LUA_MAXINPUT]; + char *b = buffer; + size_t l; + const char *prmt = get_prompt(L, firstline); + if (lua_readline(L, b, prmt) == 0) + return 0; /* no input */ + l = strlen(b); + if (l > 0 && b[l-1] == '\n') /* line ends with newline? */ + b[l-1] = '\0'; /* remove it */ + if (firstline && b[0] == '=') /* first line starts with `=' ? */ + lua_pushfstring(L, "return %s", b+1); /* change it to `return' */ + else + lua_pushstring(L, b); + lua_freeline(L, b); + return 1; +} + + +static int loadline (lua_State *L) { + int status; + lua_settop(L, 0); + if (!pushline(L, 1)) + return -1; /* no input */ + for (;;) { /* repeat until gets a complete line */ + status = luaL_loadbuffer(L, lua_tostring(L, 1), lua_strlen(L, 1), "=stdin"); + if (!incomplete(L, status)) break; /* cannot try to add lines? */ + if (!pushline(L, 0)) /* no more input? */ + return -1; + lua_pushliteral(L, "\n"); /* add a new line... */ + lua_insert(L, -2); /* ...between the two lines */ + lua_concat(L, 3); /* join them */ + } + lua_saveline(L, 1); + lua_remove(L, 1); /* remove line */ + return status; +} + + +static void dotty (lua_State *L) { + int status; + const char *oldprogname = progname; + progname = NULL; + while ((status = loadline(L)) != -1) { + if (status == 0) status = docall(L, 0, 0); + report(L, status); + if (status == 0 && lua_gettop(L) > 0) { /* any result to print? */ + lua_getglobal(L, "print"); + lua_insert(L, 1); + if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != 0) + l_message(progname, lua_pushfstring(L, + "error calling " LUA_QL("print") " (%s)", + lua_tostring(L, -1))); + } + } + lua_settop(L, 0); /* clear stack */ + fputs("\n", stdout); + fflush(stdout); + progname = oldprogname; +} + + +static int handle_script (lua_State *L, char **argv, int n) { + int status; + const char *fname; + int narg = getargs(L, argv, n); /* collect arguments */ + lua_setglobal(L, "arg"); + fname = argv[n]; + if (strcmp(fname, "-") == 0 && strcmp(argv[n-1], "--") != 0) + fname = NULL; /* stdin */ + status = luaL_loadfile(L, fname); + lua_insert(L, -(narg+1)); + if (status == 0) + status = docall(L, narg, 0); + else + lua_pop(L, narg); + return report(L, status); +} + + +/* check that argument has no extra characters at the end */ +#define notail(x) {if ((x)[2] != '\0') return -1;} + + +static int collectargs (char **argv, int *pi, int *pv, int *pe) { + int i; + for (i = 1; argv[i] != NULL; i++) { + if (argv[i][0] != '-') /* not an option? */ + return i; + switch (argv[i][1]) { /* option */ + case '-': + notail(argv[i]); + return (argv[i+1] != NULL ? i+1 : 0); + case '\0': + return i; + case 'i': + notail(argv[i]); + *pi = 1; /* go through */ + case 'v': + notail(argv[i]); + *pv = 1; + break; + case 'e': + *pe = 1; /* go through */ + case 'l': + if (argv[i][2] == '\0') { + i++; + if (argv[i] == NULL) return -1; + } + break; + default: return -1; /* invalid option */ + } + } + return 0; +} + + +static int runargs (lua_State *L, char **argv, int n) { + int i; + for (i = 1; i < n; i++) { + if (argv[i] == NULL) continue; + lua_assert(argv[i][0] == '-'); + switch (argv[i][1]) { /* option */ + case 'e': { + const char *chunk = argv[i] + 2; + if (*chunk == '\0') chunk = argv[++i]; + lua_assert(chunk != NULL); + if (dostring(L, chunk, "=(command line)") != 0) + return 1; + break; + } + case 'l': { + const char *filename = argv[i] + 2; + if (*filename == '\0') filename = argv[++i]; + lua_assert(filename != NULL); + if (dolibrary(L, filename)) + return 1; /* stop if file fails */ + break; + } + default: break; + } + } + return 0; +} + + +static int handle_luainit (lua_State *L) { + const char *init = getenv(LUA_INIT); + if (init == NULL) return 0; /* status OK */ + else if (init[0] == '@') + return dofile(L, init+1); + else + return dostring(L, init, "=" LUA_INIT); +} + + +struct Smain { + int argc; + char **argv; + int status; +}; + + +static int pmain (lua_State *L) { + struct Smain *s = (struct Smain *)lua_touserdata(L, 1); + char **argv = s->argv; + int script; + int has_i = 0, has_v = 0, has_e = 0; + globalL = L; + if (argv[0] && argv[0][0]) progname = argv[0]; + lua_gc(L, LUA_GCSTOP, 0); /* stop collector during initialization */ + luaL_openlibs(L); /* open libraries */ + lua_gc(L, LUA_GCRESTART, 0); + s->status = handle_luainit(L); + if (s->status != 0) return 0; + script = collectargs(argv, &has_i, &has_v, &has_e); + if (script < 0) { /* invalid args? */ + print_usage(); + s->status = 1; + return 0; + } + if (has_v) print_version(); + s->status = runargs(L, argv, (script > 0) ? script : s->argc); + if (s->status != 0) return 0; + if (script) + s->status = handle_script(L, argv, script); + if (s->status != 0) return 0; + if (has_i) + dotty(L); + else if (script == 0 && !has_e && !has_v) { + if (lua_stdin_is_tty()) { + print_version(); + dotty(L); + } + else dofile(L, NULL); /* executes stdin as a file */ + } + return 0; +} + + +int main (int argc, char **argv) { + int status; + struct Smain s; + lua_State *L = lua_open(); /* create state */ + if (L == NULL) { + l_message(argv[0], "cannot create state: not enough memory"); + return EXIT_FAILURE; + } + s.argc = argc; + s.argv = argv; + status = lua_cpcall(L, &pmain, &s); + report(L, status); + lua_close(L); + return (status || s.status) ? EXIT_FAILURE : EXIT_SUCCESS; +} + diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/src/lua.h b/mod/pub.mod/lua.mod/lua-5.1.4/src/lua.h new file mode 100644 index 0000000..e4bdfd3 --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/src/lua.h @@ -0,0 +1,388 @@ +/* +** $Id: lua.h,v 1.218.1.5 2008/08/06 13:30:12 roberto Exp $ +** Lua - An Extensible Extension Language +** Lua.org, PUC-Rio, Brazil (http://www.lua.org) +** See Copyright Notice at the end of this file +*/ + + +#ifndef lua_h +#define lua_h + +#include +#include + + +#include "luaconf.h" + + +#define LUA_VERSION "Lua 5.1" +#define LUA_RELEASE "Lua 5.1.4" +#define LUA_VERSION_NUM 501 +#define LUA_COPYRIGHT "Copyright (C) 1994-2008 Lua.org, PUC-Rio" +#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes" + + +/* mark for precompiled code (`Lua') */ +#define LUA_SIGNATURE "\033Lua" + +/* option for multiple returns in `lua_pcall' and `lua_call' */ +#define LUA_MULTRET (-1) + + +/* +** pseudo-indices +*/ +#define LUA_REGISTRYINDEX (-10000) +#define LUA_ENVIRONINDEX (-10001) +#define LUA_GLOBALSINDEX (-10002) +#define lua_upvalueindex(i) (LUA_GLOBALSINDEX-(i)) + + +/* thread status; 0 is OK */ +#define LUA_YIELD 1 +#define LUA_ERRRUN 2 +#define LUA_ERRSYNTAX 3 +#define LUA_ERRMEM 4 +#define LUA_ERRERR 5 + + +typedef struct lua_State lua_State; + +typedef int (*lua_CFunction) (lua_State *L); + + +/* +** functions that read/write blocks when loading/dumping Lua chunks +*/ +typedef const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz); + +typedef int (*lua_Writer) (lua_State *L, const void* p, size_t sz, void* ud); + + +/* +** prototype for memory-allocation functions +*/ +typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize); + + +/* +** basic types +*/ +#define LUA_TNONE (-1) + +#define LUA_TNIL 0 +#define LUA_TBOOLEAN 1 +#define LUA_TLIGHTUSERDATA 2 +#define LUA_TNUMBER 3 +#define LUA_TSTRING 4 +#define LUA_TTABLE 5 +#define LUA_TFUNCTION 6 +#define LUA_TUSERDATA 7 +#define LUA_TTHREAD 8 + + + +/* minimum Lua stack available to a C function */ +#define LUA_MINSTACK 20 + + +/* +** generic extra include file +*/ +#if defined(LUA_USER_H) +#include LUA_USER_H +#endif + + +/* type of numbers in Lua */ +typedef LUA_NUMBER lua_Number; + + +/* type for integer functions */ +typedef LUA_INTEGER lua_Integer; + + + +/* +** state manipulation +*/ +LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud); +LUA_API void (lua_close) (lua_State *L); +LUA_API lua_State *(lua_newthread) (lua_State *L); + +LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf); + + +/* +** basic stack manipulation +*/ +LUA_API int (lua_gettop) (lua_State *L); +LUA_API void (lua_settop) (lua_State *L, int idx); +LUA_API void (lua_pushvalue) (lua_State *L, int idx); +LUA_API void (lua_remove) (lua_State *L, int idx); +LUA_API void (lua_insert) (lua_State *L, int idx); +LUA_API void (lua_replace) (lua_State *L, int idx); +LUA_API int (lua_checkstack) (lua_State *L, int sz); + +LUA_API void (lua_xmove) (lua_State *from, lua_State *to, int n); + + +/* +** access functions (stack -> C) +*/ + +LUA_API int (lua_isnumber) (lua_State *L, int idx); +LUA_API int (lua_isstring) (lua_State *L, int idx); +LUA_API int (lua_iscfunction) (lua_State *L, int idx); +LUA_API int (lua_isuserdata) (lua_State *L, int idx); +LUA_API int (lua_type) (lua_State *L, int idx); +LUA_API const char *(lua_typename) (lua_State *L, int tp); + +LUA_API int (lua_equal) (lua_State *L, int idx1, int idx2); +LUA_API int (lua_rawequal) (lua_State *L, int idx1, int idx2); +LUA_API int (lua_lessthan) (lua_State *L, int idx1, int idx2); + +LUA_API lua_Number (lua_tonumber) (lua_State *L, int idx); +LUA_API lua_Integer (lua_tointeger) (lua_State *L, int idx); +LUA_API int (lua_toboolean) (lua_State *L, int idx); +LUA_API const char *(lua_tolstring) (lua_State *L, int idx, size_t *len); +LUA_API size_t (lua_objlen) (lua_State *L, int idx); +LUA_API lua_CFunction (lua_tocfunction) (lua_State *L, int idx); +LUA_API void *(lua_touserdata) (lua_State *L, int idx); +LUA_API lua_State *(lua_tothread) (lua_State *L, int idx); +LUA_API const void *(lua_topointer) (lua_State *L, int idx); + + +/* +** push functions (C -> stack) +*/ +LUA_API void (lua_pushnil) (lua_State *L); +LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n); +LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n); +LUA_API void (lua_pushlstring) (lua_State *L, const char *s, size_t l); +LUA_API void (lua_pushstring) (lua_State *L, const char *s); +LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt, + va_list argp); +LUA_API const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...); +LUA_API void (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n); +LUA_API void (lua_pushboolean) (lua_State *L, int b); +LUA_API void (lua_pushlightuserdata) (lua_State *L, void *p); +LUA_API int (lua_pushthread) (lua_State *L); + + +/* +** get functions (Lua -> stack) +*/ +LUA_API void (lua_gettable) (lua_State *L, int idx); +LUA_API void (lua_getfield) (lua_State *L, int idx, const char *k); +LUA_API void (lua_rawget) (lua_State *L, int idx); +LUA_API void (lua_rawgeti) (lua_State *L, int idx, int n); +LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec); +LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz); +LUA_API int (lua_getmetatable) (lua_State *L, int objindex); +LUA_API void (lua_getfenv) (lua_State *L, int idx); + + +/* +** set functions (stack -> Lua) +*/ +LUA_API void (lua_settable) (lua_State *L, int idx); +LUA_API void (lua_setfield) (lua_State *L, int idx, const char *k); +LUA_API void (lua_rawset) (lua_State *L, int idx); +LUA_API void (lua_rawseti) (lua_State *L, int idx, int n); +LUA_API int (lua_setmetatable) (lua_State *L, int objindex); +LUA_API int (lua_setfenv) (lua_State *L, int idx); + + +/* +** `load' and `call' functions (load and run Lua code) +*/ +LUA_API void (lua_call) (lua_State *L, int nargs, int nresults); +LUA_API int (lua_pcall) (lua_State *L, int nargs, int nresults, int errfunc); +LUA_API int (lua_cpcall) (lua_State *L, lua_CFunction func, void *ud); +LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt, + const char *chunkname); + +LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data); + + +/* +** coroutine functions +*/ +LUA_API int (lua_yield) (lua_State *L, int nresults); +LUA_API int (lua_resume) (lua_State *L, int narg); +LUA_API int (lua_status) (lua_State *L); + +/* +** garbage-collection function and options +*/ + +#define LUA_GCSTOP 0 +#define LUA_GCRESTART 1 +#define LUA_GCCOLLECT 2 +#define LUA_GCCOUNT 3 +#define LUA_GCCOUNTB 4 +#define LUA_GCSTEP 5 +#define LUA_GCSETPAUSE 6 +#define LUA_GCSETSTEPMUL 7 + +LUA_API int (lua_gc) (lua_State *L, int what, int data); + + +/* +** miscellaneous functions +*/ + +LUA_API int (lua_error) (lua_State *L); + +LUA_API int (lua_next) (lua_State *L, int idx); + +LUA_API void (lua_concat) (lua_State *L, int n); + +LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud); +LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud); + + + +/* +** =============================================================== +** some useful macros +** =============================================================== +*/ + +#define lua_pop(L,n) lua_settop(L, -(n)-1) + +#define lua_newtable(L) lua_createtable(L, 0, 0) + +#define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n))) + +#define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0) + +#define lua_strlen(L,i) lua_objlen(L, (i)) + +#define lua_isfunction(L,n) (lua_type(L, (n)) == LUA_TFUNCTION) +#define lua_istable(L,n) (lua_type(L, (n)) == LUA_TTABLE) +#define lua_islightuserdata(L,n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA) +#define lua_isnil(L,n) (lua_type(L, (n)) == LUA_TNIL) +#define lua_isboolean(L,n) (lua_type(L, (n)) == LUA_TBOOLEAN) +#define lua_isthread(L,n) (lua_type(L, (n)) == LUA_TTHREAD) +#define lua_isnone(L,n) (lua_type(L, (n)) == LUA_TNONE) +#define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0) + +#define lua_pushliteral(L, s) \ + lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1) + +#define lua_setglobal(L,s) lua_setfield(L, LUA_GLOBALSINDEX, (s)) +#define lua_getglobal(L,s) lua_getfield(L, LUA_GLOBALSINDEX, (s)) + +#define lua_tostring(L,i) lua_tolstring(L, (i), NULL) + + + +/* +** compatibility macros and functions +*/ + +#define lua_open() luaL_newstate() + +#define lua_getregistry(L) lua_pushvalue(L, LUA_REGISTRYINDEX) + +#define lua_getgccount(L) lua_gc(L, LUA_GCCOUNT, 0) + +#define lua_Chunkreader lua_Reader +#define lua_Chunkwriter lua_Writer + + +/* hack */ +LUA_API void lua_setlevel (lua_State *from, lua_State *to); + + +/* +** {====================================================================== +** Debug API +** ======================================================================= +*/ + + +/* +** Event codes +*/ +#define LUA_HOOKCALL 0 +#define LUA_HOOKRET 1 +#define LUA_HOOKLINE 2 +#define LUA_HOOKCOUNT 3 +#define LUA_HOOKTAILRET 4 + + +/* +** Event masks +*/ +#define LUA_MASKCALL (1 << LUA_HOOKCALL) +#define LUA_MASKRET (1 << LUA_HOOKRET) +#define LUA_MASKLINE (1 << LUA_HOOKLINE) +#define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT) + +typedef struct lua_Debug lua_Debug; /* activation record */ + + +/* Functions to be called by the debuger in specific events */ +typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar); + + +LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar); +LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar); +LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n); +LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n); +LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n); +LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n); + +LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count); +LUA_API lua_Hook lua_gethook (lua_State *L); +LUA_API int lua_gethookmask (lua_State *L); +LUA_API int lua_gethookcount (lua_State *L); + + +struct lua_Debug { + int event; + const char *name; /* (n) */ + const char *namewhat; /* (n) `global', `local', `field', `method' */ + const char *what; /* (S) `Lua', `C', `main', `tail' */ + const char *source; /* (S) */ + int currentline; /* (l) */ + int nups; /* (u) number of upvalues */ + int linedefined; /* (S) */ + int lastlinedefined; /* (S) */ + char short_src[LUA_IDSIZE]; /* (S) */ + /* private part */ + int i_ci; /* active function */ +}; + +/* }====================================================================== */ + + +/****************************************************************************** +* Copyright (C) 1994-2008 Lua.org, PUC-Rio. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be +* included in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +******************************************************************************/ + + +#endif diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/src/luac.c b/mod/pub.mod/lua.mod/lua-5.1.4/src/luac.c new file mode 100644 index 0000000..d070173 --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/src/luac.c @@ -0,0 +1,200 @@ +/* +** $Id: luac.c,v 1.54 2006/06/02 17:37:11 lhf Exp $ +** Lua compiler (saves bytecodes to files; also list bytecodes) +** See Copyright Notice in lua.h +*/ + +#include +#include +#include +#include + +#define luac_c +#define LUA_CORE + +#include "lua.h" +#include "lauxlib.h" + +#include "ldo.h" +#include "lfunc.h" +#include "lmem.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lstring.h" +#include "lundump.h" + +#define PROGNAME "luac" /* default program name */ +#define OUTPUT PROGNAME ".out" /* default output file */ + +static int listing=0; /* list bytecodes? */ +static int dumping=1; /* dump bytecodes? */ +static int stripping=0; /* strip debug information? */ +static char Output[]={ OUTPUT }; /* default output file name */ +static const char* output=Output; /* actual output file name */ +static const char* progname=PROGNAME; /* actual program name */ + +static void fatal(const char* message) +{ + fprintf(stderr,"%s: %s\n",progname,message); + exit(EXIT_FAILURE); +} + +static void cannot(const char* what) +{ + fprintf(stderr,"%s: cannot %s %s: %s\n",progname,what,output,strerror(errno)); + exit(EXIT_FAILURE); +} + +static void usage(const char* message) +{ + if (*message=='-') + fprintf(stderr,"%s: unrecognized option " LUA_QS "\n",progname,message); + else + fprintf(stderr,"%s: %s\n",progname,message); + fprintf(stderr, + "usage: %s [options] [filenames].\n" + "Available options are:\n" + " - process stdin\n" + " -l list\n" + " -o name output to file " LUA_QL("name") " (default is \"%s\")\n" + " -p parse only\n" + " -s strip debug information\n" + " -v show version information\n" + " -- stop handling options\n", + progname,Output); + exit(EXIT_FAILURE); +} + +#define IS(s) (strcmp(argv[i],s)==0) + +static int doargs(int argc, char* argv[]) +{ + int i; + int version=0; + if (argv[0]!=NULL && *argv[0]!=0) progname=argv[0]; + for (i=1; itop+(i))->l.p) + +static const Proto* combine(lua_State* L, int n) +{ + if (n==1) + return toproto(L,-1); + else + { + int i,pc; + Proto* f=luaF_newproto(L); + setptvalue2s(L,L->top,f); incr_top(L); + f->source=luaS_newliteral(L,"=(" PROGNAME ")"); + f->maxstacksize=1; + pc=2*n+1; + f->code=luaM_newvector(L,pc,Instruction); + f->sizecode=pc; + f->p=luaM_newvector(L,n,Proto*); + f->sizep=n; + pc=0; + for (i=0; ip[i]=toproto(L,i-n-1); + f->code[pc++]=CREATE_ABx(OP_CLOSURE,0,i); + f->code[pc++]=CREATE_ABC(OP_CALL,0,1,1); + } + f->code[pc++]=CREATE_ABC(OP_RETURN,0,1,0); + return f; + } +} + +static int writer(lua_State* L, const void* p, size_t size, void* u) +{ + UNUSED(L); + return (fwrite(p,size,1,(FILE*)u)!=1) && (size!=0); +} + +struct Smain { + int argc; + char** argv; +}; + +static int pmain(lua_State* L) +{ + struct Smain* s = (struct Smain*)lua_touserdata(L, 1); + int argc=s->argc; + char** argv=s->argv; + const Proto* f; + int i; + if (!lua_checkstack(L,argc)) fatal("too many input files"); + for (i=0; i1); + if (dumping) + { + FILE* D= (output==NULL) ? stdout : fopen(output,"wb"); + if (D==NULL) cannot("open"); + lua_lock(L); + luaU_dump(L,f,writer,D,stripping); + lua_unlock(L); + if (ferror(D)) cannot("write"); + if (fclose(D)) cannot("close"); + } + return 0; +} + +int main(int argc, char* argv[]) +{ + lua_State* L; + struct Smain s; + int i=doargs(argc,argv); + argc-=i; argv+=i; + if (argc<=0) usage("no input files given"); + L=lua_open(); + if (L==NULL) fatal("not enough memory for state"); + s.argc=argc; + s.argv=argv; + if (lua_cpcall(L,pmain,&s)!=0) fatal(lua_tostring(L,-1)); + lua_close(L); + return EXIT_SUCCESS; +} diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/src/luaconf.h b/mod/pub.mod/lua.mod/lua-5.1.4/src/luaconf.h new file mode 100644 index 0000000..ddef65c --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/src/luaconf.h @@ -0,0 +1,772 @@ +/* +** $Id: luaconf.h,v 1.82.1.7 2008/02/11 16:25:08 roberto Exp $ +** Configuration file for Lua +** See Copyright Notice in lua.h +*/ + + +#ifndef lconfig_h +#define lconfig_h + +#include +#include + +/* +** BRL: Added by Mark - autodetect for linux/macos. +** +*/ +#if __linux +#define LUA_USE_LINUX +#elif __APPLE__ +#define LUA_USE_MACOSX +#endif + +/* +** ================================================================== +** Search for "@@" to find all configurable definitions. +** =================================================================== +*/ + + +/* +@@ LUA_ANSI controls the use of non-ansi features. +** CHANGE it (define it) if you want Lua to avoid the use of any +** non-ansi feature or library. +*/ +#if defined(__STRICT_ANSI__) +#define LUA_ANSI +#endif + + +#if !defined(LUA_ANSI) && defined(_WIN32) +#define LUA_WIN +#endif + +#if defined(LUA_USE_LINUX) +#define LUA_USE_POSIX +#define LUA_USE_DLOPEN /* needs an extra library: -ldl */ +#define LUA_USE_READLINE /* needs some extra libraries */ +#endif + +#if defined(LUA_USE_MACOSX) +#define LUA_USE_POSIX +#define LUA_DL_DYLD /* does not need extra library */ +#endif + + + +/* +@@ LUA_USE_POSIX includes all functionallity listed as X/Open System +@* Interfaces Extension (XSI). +** CHANGE it (define it) if your system is XSI compatible. +*/ +#if defined(LUA_USE_POSIX) +#define LUA_USE_MKSTEMP +#define LUA_USE_ISATTY +#define LUA_USE_POPEN +#define LUA_USE_ULONGJMP +#endif + + +/* +@@ LUA_PATH and LUA_CPATH are the names of the environment variables that +@* Lua check to set its paths. +@@ LUA_INIT is the name of the environment variable that Lua +@* checks for initialization code. +** CHANGE them if you want different names. +*/ +#define LUA_PATH "LUA_PATH" +#define LUA_CPATH "LUA_CPATH" +#define LUA_INIT "LUA_INIT" + + +/* +@@ LUA_PATH_DEFAULT is the default path that Lua uses to look for +@* Lua libraries. +@@ LUA_CPATH_DEFAULT is the default path that Lua uses to look for +@* C libraries. +** CHANGE them if your machine has a non-conventional directory +** hierarchy or if you want to install your libraries in +** non-conventional directories. +*/ +#if defined(_WIN32) +/* +** In Windows, any exclamation mark ('!') in the path is replaced by the +** path of the directory of the executable file of the current process. +*/ +#define LUA_LDIR "!\\lua\\" +#define LUA_CDIR "!\\" +#define LUA_PATH_DEFAULT \ + ".\\?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \ + LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua" +#define LUA_CPATH_DEFAULT \ + ".\\?.dll;" LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll" + +#else +#define LUA_ROOT "/usr/local/" +#define LUA_LDIR LUA_ROOT "share/lua/5.1/" +#define LUA_CDIR LUA_ROOT "lib/lua/5.1/" +#define LUA_PATH_DEFAULT \ + "./?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \ + LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua" +#define LUA_CPATH_DEFAULT \ + "./?.so;" LUA_CDIR"?.so;" LUA_CDIR"loadall.so" +#endif + + +/* +@@ LUA_DIRSEP is the directory separator (for submodules). +** CHANGE it if your machine does not use "/" as the directory separator +** and is not Windows. (On Windows Lua automatically uses "\".) +*/ +#if defined(_WIN32) +#define LUA_DIRSEP "\\" +#else +#define LUA_DIRSEP "/" +#endif + + +/* +@@ LUA_PATHSEP is the character that separates templates in a path. +@@ LUA_PATH_MARK is the string that marks the substitution points in a +@* template. +@@ LUA_EXECDIR in a Windows path is replaced by the executable's +@* directory. +@@ LUA_IGMARK is a mark to ignore all before it when bulding the +@* luaopen_ function name. +** CHANGE them if for some reason your system cannot use those +** characters. (E.g., if one of those characters is a common character +** in file/directory names.) Probably you do not need to change them. +*/ +#define LUA_PATHSEP ";" +#define LUA_PATH_MARK "?" +#define LUA_EXECDIR "!" +#define LUA_IGMARK "-" + + +/* +@@ LUA_INTEGER is the integral type used by lua_pushinteger/lua_tointeger. +** CHANGE that if ptrdiff_t is not adequate on your machine. (On most +** machines, ptrdiff_t gives a good choice between int or long.) +*/ +#define LUA_INTEGER ptrdiff_t + + +/* +@@ LUA_API is a mark for all core API functions. +@@ LUALIB_API is a mark for all standard library functions. +** CHANGE them if you need to define those functions in some special way. +** For instance, if you want to create one Windows DLL with the core and +** the libraries, you may want to use the following definition (define +** LUA_BUILD_AS_DLL to get it). +*/ +#if defined(LUA_BUILD_AS_DLL) + +#if defined(LUA_CORE) || defined(LUA_LIB) +#define LUA_API __declspec(dllexport) +#else +#define LUA_API __declspec(dllimport) +#endif + +#else + +#define LUA_API extern + +#endif + +/* more often than not the libs go together with the core */ +#define LUALIB_API LUA_API + + +/* +@@ LUAI_FUNC is a mark for all extern functions that are not to be +@* exported to outside modules. +@@ LUAI_DATA is a mark for all extern (const) variables that are not to +@* be exported to outside modules. +** CHANGE them if you need to mark them in some special way. Elf/gcc +** (versions 3.2 and later) mark them as "hidden" to optimize access +** when Lua is compiled as a shared library. +*/ +#if defined(luaall_c) +#define LUAI_FUNC static +#define LUAI_DATA /* empty */ + +#elif defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \ + defined(__ELF__) +#define LUAI_FUNC __attribute__((visibility("hidden"))) extern +#define LUAI_DATA LUAI_FUNC + +#else +#define LUAI_FUNC extern +#define LUAI_DATA extern +#endif + + + +/* +@@ LUA_QL describes how error messages quote program elements. +** CHANGE it if you want a different appearance. +*/ +#define LUA_QL(x) "'" x "'" +#define LUA_QS LUA_QL("%s") + + +/* +@@ LUA_IDSIZE gives the maximum size for the description of the source +@* of a function in debug information. +** CHANGE it if you want a different size. +*/ +#define LUA_IDSIZE 60 + + +/* +** {================================================================== +** Stand-alone configuration +** =================================================================== +*/ + +#if defined(lua_c) || defined(luaall_c) + +/* +@@ lua_stdin_is_tty detects whether the standard input is a 'tty' (that +@* is, whether we're running lua interactively). +** CHANGE it if you have a better definition for non-POSIX/non-Windows +** systems. +*/ +#if defined(LUA_USE_ISATTY) +#include +#define lua_stdin_is_tty() isatty(0) +#elif defined(LUA_WIN) +#include +#include +#define lua_stdin_is_tty() _isatty(_fileno(stdin)) +#else +#define lua_stdin_is_tty() 1 /* assume stdin is a tty */ +#endif + + +/* +@@ LUA_PROMPT is the default prompt used by stand-alone Lua. +@@ LUA_PROMPT2 is the default continuation prompt used by stand-alone Lua. +** CHANGE them if you want different prompts. (You can also change the +** prompts dynamically, assigning to globals _PROMPT/_PROMPT2.) +*/ +#define LUA_PROMPT "> " +#define LUA_PROMPT2 ">> " + + +/* +@@ LUA_PROGNAME is the default name for the stand-alone Lua program. +** CHANGE it if your stand-alone interpreter has a different name and +** your system is not able to detect that name automatically. +*/ +#define LUA_PROGNAME "lua" + + +/* +@@ LUA_MAXINPUT is the maximum length for an input line in the +@* stand-alone interpreter. +** CHANGE it if you need longer lines. +*/ +#define LUA_MAXINPUT 512 + + +/* +@@ lua_readline defines how to show a prompt and then read a line from +@* the standard input. +@@ lua_saveline defines how to "save" a read line in a "history". +@@ lua_freeline defines how to free a line read by lua_readline. +** CHANGE them if you want to improve this functionality (e.g., by using +** GNU readline and history facilities). +*/ +#if defined(LUA_USE_READLINE) +#include +#include +#include +#define lua_readline(L,b,p) ((void)L, ((b)=readline(p)) != NULL) +#define lua_saveline(L,idx) \ + if (lua_strlen(L,idx) > 0) /* non-empty line? */ \ + add_history(lua_tostring(L, idx)); /* add it to history */ +#define lua_freeline(L,b) ((void)L, free(b)) +#else +#define lua_readline(L,b,p) \ + ((void)L, fputs(p, stdout), fflush(stdout), /* show prompt */ \ + fgets(b, LUA_MAXINPUT, stdin) != NULL) /* get line */ +#define lua_saveline(L,idx) { (void)L; (void)idx; } +#define lua_freeline(L,b) { (void)L; (void)b; } +#endif + +#endif + +/* }================================================================== */ + + +/* +@@ LUAI_GCPAUSE defines the default pause between garbage-collector cycles +@* as a percentage. +** CHANGE it if you want the GC to run faster or slower (higher values +** mean larger pauses which mean slower collection.) You can also change +** this value dynamically. +*/ +#define LUAI_GCPAUSE 200 /* 200% (wait memory to double before next GC) */ + + +/* +@@ LUAI_GCMUL defines the default speed of garbage collection relative to +@* memory allocation as a percentage. +** CHANGE it if you want to change the granularity of the garbage +** collection. (Higher values mean coarser collections. 0 represents +** infinity, where each step performs a full collection.) You can also +** change this value dynamically. +*/ +#define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */ + + + +/* +@@ LUA_COMPAT_GETN controls compatibility with old getn behavior. +** CHANGE it (define it) if you want exact compatibility with the +** behavior of setn/getn in Lua 5.0. +*/ +#undef LUA_COMPAT_GETN + +/* +@@ LUA_COMPAT_LOADLIB controls compatibility about global loadlib. +** CHANGE it to undefined as soon as you do not need a global 'loadlib' +** function (the function is still available as 'package.loadlib'). +*/ +#undef LUA_COMPAT_LOADLIB + +/* +@@ LUA_COMPAT_VARARG controls compatibility with old vararg feature. +** CHANGE it to undefined as soon as your programs use only '...' to +** access vararg parameters (instead of the old 'arg' table). +*/ +#define LUA_COMPAT_VARARG + +/* +@@ LUA_COMPAT_MOD controls compatibility with old math.mod function. +** CHANGE it to undefined as soon as your programs use 'math.fmod' or +** the new '%' operator instead of 'math.mod'. +*/ +#define LUA_COMPAT_MOD + +/* +@@ LUA_COMPAT_LSTR controls compatibility with old long string nesting +@* facility. +** CHANGE it to 2 if you want the old behaviour, or undefine it to turn +** off the advisory error when nesting [[...]]. +*/ +#define LUA_COMPAT_LSTR 1 + +/* +@@ LUA_COMPAT_GFIND controls compatibility with old 'string.gfind' name. +** CHANGE it to undefined as soon as you rename 'string.gfind' to +** 'string.gmatch'. +*/ +#define LUA_COMPAT_GFIND + +/* +@@ LUA_COMPAT_OPENLIB controls compatibility with old 'luaL_openlib' +@* behavior. +** CHANGE it to undefined as soon as you replace to 'luaL_register' +** your uses of 'luaL_openlib' +*/ +#define LUA_COMPAT_OPENLIB + + + +/* +@@ luai_apicheck is the assert macro used by the Lua-C API. +** CHANGE luai_apicheck if you want Lua to perform some checks in the +** parameters it gets from API calls. This may slow down the interpreter +** a bit, but may be quite useful when debugging C code that interfaces +** with Lua. A useful redefinition is to use assert.h. +*/ +#if defined(LUA_USE_APICHECK) +#include +#define luai_apicheck(L,o) { (void)L; assert(o); } +#else +#define luai_apicheck(L,o) { (void)L; } +#endif + + +/* +@@ LUAI_BITSINT defines the number of bits in an int. +** CHANGE here if Lua cannot automatically detect the number of bits of +** your machine. Probably you do not need to change this. +*/ +/* avoid overflows in comparison */ +#if INT_MAX-20 < 32760 +#define LUAI_BITSINT 16 +#elif INT_MAX > 2147483640L +/* int has at least 32 bits */ +#define LUAI_BITSINT 32 +#else +#error "you must define LUA_BITSINT with number of bits in an integer" +#endif + + +/* +@@ LUAI_UINT32 is an unsigned integer with at least 32 bits. +@@ LUAI_INT32 is an signed integer with at least 32 bits. +@@ LUAI_UMEM is an unsigned integer big enough to count the total +@* memory used by Lua. +@@ LUAI_MEM is a signed integer big enough to count the total memory +@* used by Lua. +** CHANGE here if for some weird reason the default definitions are not +** good enough for your machine. (The definitions in the 'else' +** part always works, but may waste space on machines with 64-bit +** longs.) Probably you do not need to change this. +*/ +#if LUAI_BITSINT >= 32 +#define LUAI_UINT32 unsigned int +#define LUAI_INT32 int +#define LUAI_MAXINT32 INT_MAX +#define LUAI_UMEM size_t +#define LUAI_MEM ptrdiff_t +#else +/* 16-bit ints */ +#define LUAI_UINT32 unsigned long +#define LUAI_INT32 long +#define LUAI_MAXINT32 LONG_MAX +#define LUAI_UMEM unsigned long +#define LUAI_MEM long +#endif + + +/* +@@ LUAI_MAXCALLS limits the number of nested calls. +** CHANGE it if you need really deep recursive calls. This limit is +** arbitrary; its only purpose is to stop infinite recursion before +** exhausting memory. +*/ +#define LUAI_MAXCALLS 20000 + + +/* +@@ LUAI_MAXCSTACK limits the number of Lua stack slots that a C function +@* can use. +** CHANGE it if you need lots of (Lua) stack space for your C +** functions. This limit is arbitrary; its only purpose is to stop C +** functions to consume unlimited stack space. (must be smaller than +** -LUA_REGISTRYINDEX) +*/ +#define LUAI_MAXCSTACK 8000 + + + +/* +** {================================================================== +** CHANGE (to smaller values) the following definitions if your system +** has a small C stack. (Or you may want to change them to larger +** values if your system has a large C stack and these limits are +** too rigid for you.) Some of these constants control the size of +** stack-allocated arrays used by the compiler or the interpreter, while +** others limit the maximum number of recursive calls that the compiler +** or the interpreter can perform. Values too large may cause a C stack +** overflow for some forms of deep constructs. +** =================================================================== +*/ + + +/* +@@ LUAI_MAXCCALLS is the maximum depth for nested C calls (short) and +@* syntactical nested non-terminals in a program. +*/ +#define LUAI_MAXCCALLS 200 + + +/* +@@ LUAI_MAXVARS is the maximum number of local variables per function +@* (must be smaller than 250). +*/ +#define LUAI_MAXVARS 200 + + +/* +@@ LUAI_MAXUPVALUES is the maximum number of upvalues per function +@* (must be smaller than 250). +*/ +#define LUAI_MAXUPVALUES 60 + + +/* +@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system. +*/ +#define LUAL_BUFFERSIZE BUFSIZ + +/* }================================================================== */ + + + + +/* +** {================================================================== +@@ LUA_NUMBER is the type of numbers in Lua. +** CHANGE the following definitions only if you want to build Lua +** with a number type different from double. You may also need to +** change lua_number2int & lua_number2integer. +** =================================================================== +*/ + +#define LUA_NUMBER_DOUBLE +#define LUA_NUMBER double + +/* +@@ LUAI_UACNUMBER is the result of an 'usual argument conversion' +@* over a number. +*/ +#define LUAI_UACNUMBER double + + +/* +@@ LUA_NUMBER_SCAN is the format for reading numbers. +@@ LUA_NUMBER_FMT is the format for writing numbers. +@@ lua_number2str converts a number to a string. +@@ LUAI_MAXNUMBER2STR is maximum size of previous conversion. +@@ lua_str2number converts a string to a number. +*/ +#define LUA_NUMBER_SCAN "%lf" +#define LUA_NUMBER_FMT "%.14g" +#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n)) +#define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */ +#define lua_str2number(s,p) strtod((s), (p)) + + +/* +@@ The luai_num* macros define the primitive operations over numbers. +*/ +#if defined(LUA_CORE) +#include +#define luai_numadd(a,b) ((a)+(b)) +#define luai_numsub(a,b) ((a)-(b)) +#define luai_nummul(a,b) ((a)*(b)) +#define luai_numdiv(a,b) ((a)/(b)) +#define luai_nummod(a,b) ((a) - floor((a)/(b))*(b)) +#define luai_numpow(a,b) (pow(a,b)) +#define luai_numunm(a) (-(a)) +#define luai_numeq(a,b) ((a)==(b)) +#define luai_numlt(a,b) ((a)<(b)) +#define luai_numle(a,b) ((a)<=(b)) +#define luai_numisnan(a) (!luai_numeq((a), (a))) +#endif + + +/* +@@ lua_number2int is a macro to convert lua_Number to int. +@@ lua_number2integer is a macro to convert lua_Number to lua_Integer. +** CHANGE them if you know a faster way to convert a lua_Number to +** int (with any rounding method and without throwing errors) in your +** system. In Pentium machines, a naive typecast from double to int +** in C is extremely slow, so any alternative is worth trying. +*/ + +/* On a Pentium, resort to a trick */ +#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) && !defined(__SSE2__) && \ + (defined(__i386) || defined (_M_IX86) || defined(__i386__)) + +/* On a Microsoft compiler, use assembler */ +#if defined(_MSC_VER) + +#define lua_number2int(i,d) __asm fld d __asm fistp i +#define lua_number2integer(i,n) lua_number2int(i, n) + +/* the next trick should work on any Pentium, but sometimes clashes + with a DirectX idiosyncrasy */ +#else + +union luai_Cast { double l_d; long l_l; }; +#define lua_number2int(i,d) \ + { volatile union luai_Cast u; u.l_d = (d) + 6755399441055744.0; (i) = u.l_l; } +#define lua_number2integer(i,n) lua_number2int(i, n) + +#endif + + +/* this option always works, but may be slow */ +#else +#define lua_number2int(i,d) ((i)=(int)(d)) +#define lua_number2integer(i,d) ((i)=(lua_Integer)(d)) + +#endif + +/* }================================================================== */ + + +/* +@@ LUAI_USER_ALIGNMENT_T is a type that requires maximum alignment. +** CHANGE it if your system requires alignments larger than double. (For +** instance, if your system supports long doubles and they must be +** aligned in 16-byte boundaries, then you should add long double in the +** union.) Probably you do not need to change this. +*/ +#define LUAI_USER_ALIGNMENT_T union { double u; void *s; long l; } + + +/* +@@ LUAI_THROW/LUAI_TRY define how Lua does exception handling. +** CHANGE them if you prefer to use longjmp/setjmp even with C++ +** or if want/don't to use _longjmp/_setjmp instead of regular +** longjmp/setjmp. By default, Lua handles errors with exceptions when +** compiling as C++ code, with _longjmp/_setjmp when asked to use them, +** and with longjmp/setjmp otherwise. +*/ +#if defined(__cplusplus) +/* C++ exceptions */ +#define LUAI_THROW(L,c) throw(c) +#define LUAI_TRY(L,c,a) try { a } catch(...) \ + { if ((c)->status == 0) (c)->status = -1; } +#define luai_jmpbuf int /* dummy variable */ + +#elif defined(LUA_USE_ULONGJMP) +/* in Unix, try _longjmp/_setjmp (more efficient) */ +#define LUAI_THROW(L,c) _longjmp((c)->b, 1) +#define LUAI_TRY(L,c,a) if (_setjmp((c)->b) == 0) { a } +#define luai_jmpbuf jmp_buf + +#else +/* default handling with long jumps */ +#define LUAI_THROW(L,c) longjmp((c)->b, 1) +#define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a } +#define luai_jmpbuf jmp_buf + +#endif + + +/* +@@ LUA_MAXCAPTURES is the maximum number of captures that a pattern +@* can do during pattern-matching. +** CHANGE it if you need more captures. This limit is arbitrary. +*/ +#define LUA_MAXCAPTURES 32 + + +/* +@@ lua_tmpnam is the function that the OS library uses to create a +@* temporary name. +@@ LUA_TMPNAMBUFSIZE is the maximum size of a name created by lua_tmpnam. +** CHANGE them if you have an alternative to tmpnam (which is considered +** insecure) or if you want the original tmpnam anyway. By default, Lua +** uses tmpnam except when POSIX is available, where it uses mkstemp. +*/ +#if defined(loslib_c) || defined(luaall_c) + +#if defined(LUA_USE_MKSTEMP) +#include +#define LUA_TMPNAMBUFSIZE 32 +#define lua_tmpnam(b,e) { \ + strcpy(b, "/tmp/lua_XXXXXX"); \ + e = mkstemp(b); \ + if (e != -1) close(e); \ + e = (e == -1); } + +#else +#define LUA_TMPNAMBUFSIZE L_tmpnam +#define lua_tmpnam(b,e) { e = (tmpnam(b) == NULL); } +#endif + +#endif + + +/* +@@ lua_popen spawns a new process connected to the current one through +@* the file streams. +** CHANGE it if you have a way to implement it in your system. +*/ +#if defined(LUA_USE_POPEN) + +#define lua_popen(L,c,m) ((void)L, fflush(NULL), popen(c,m)) +#define lua_pclose(L,file) ((void)L, (pclose(file) != -1)) + +#elif defined(LUA_WIN) + +#define lua_popen(L,c,m) ((void)L, _popen(c,m)) +#define lua_pclose(L,file) ((void)L, (_pclose(file) != -1)) + +#else + +#define lua_popen(L,c,m) ((void)((void)c, m), \ + luaL_error(L, LUA_QL("popen") " not supported"), (FILE*)0) +#define lua_pclose(L,file) ((void)((void)L, file), 0) + +#endif + +/* +@@ LUA_DL_* define which dynamic-library system Lua should use. +** CHANGE here if Lua has problems choosing the appropriate +** dynamic-library system for your platform (either Windows' DLL, Mac's +** dyld, or Unix's dlopen). If your system is some kind of Unix, there +** is a good chance that it has dlopen, so LUA_DL_DLOPEN will work for +** it. To use dlopen you also need to adapt the src/Makefile (probably +** adding -ldl to the linker options), so Lua does not select it +** automatically. (When you change the makefile to add -ldl, you must +** also add -DLUA_USE_DLOPEN.) +** If you do not want any kind of dynamic library, undefine all these +** options. +** By default, _WIN32 gets LUA_DL_DLL and MAC OS X gets LUA_DL_DYLD. +*/ +#if defined(LUA_USE_DLOPEN) +#define LUA_DL_DLOPEN +#endif + +#if defined(LUA_WIN) +#define LUA_DL_DLL +#endif + + +/* +@@ LUAI_EXTRASPACE allows you to add user-specific data in a lua_State +@* (the data goes just *before* the lua_State pointer). +** CHANGE (define) this if you really need that. This value must be +** a multiple of the maximum alignment required for your machine. +*/ +#define LUAI_EXTRASPACE 0 + + +/* +@@ luai_userstate* allow user-specific actions on threads. +** CHANGE them if you defined LUAI_EXTRASPACE and need to do something +** extra when a thread is created/deleted/resumed/yielded. +*/ +#define luai_userstateopen(L) ((void)L) +#define luai_userstateclose(L) ((void)L) +#define luai_userstatethread(L,L1) ((void)L) +#define luai_userstatefree(L) ((void)L) +#define luai_userstateresume(L,n) ((void)L) +#define luai_userstateyield(L,n) ((void)L) + + +/* +@@ LUA_INTFRMLEN is the length modifier for integer conversions +@* in 'string.format'. +@@ LUA_INTFRM_T is the integer type correspoding to the previous length +@* modifier. +** CHANGE them if your system supports long long or does not support long. +*/ + +#if defined(LUA_USELONGLONG) + +#define LUA_INTFRMLEN "ll" +#define LUA_INTFRM_T long long + +#else + +#define LUA_INTFRMLEN "l" +#define LUA_INTFRM_T long + +#endif + + + +/* =================================================================== */ + +/* +** Local configuration. You can use this space to add your redefinitions +** without modifying the main part of the file. +*/ + + + +#endif + diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/src/lualib.h b/mod/pub.mod/lua.mod/lua-5.1.4/src/lualib.h new file mode 100644 index 0000000..469417f --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/src/lualib.h @@ -0,0 +1,53 @@ +/* +** $Id: lualib.h,v 1.36.1.1 2007/12/27 13:02:25 roberto Exp $ +** Lua standard libraries +** See Copyright Notice in lua.h +*/ + + +#ifndef lualib_h +#define lualib_h + +#include "lua.h" + + +/* Key to file-handle type */ +#define LUA_FILEHANDLE "FILE*" + + +#define LUA_COLIBNAME "coroutine" +LUALIB_API int (luaopen_base) (lua_State *L); + +#define LUA_TABLIBNAME "table" +LUALIB_API int (luaopen_table) (lua_State *L); + +#define LUA_IOLIBNAME "io" +LUALIB_API int (luaopen_io) (lua_State *L); + +#define LUA_OSLIBNAME "os" +LUALIB_API int (luaopen_os) (lua_State *L); + +#define LUA_STRLIBNAME "string" +LUALIB_API int (luaopen_string) (lua_State *L); + +#define LUA_MATHLIBNAME "math" +LUALIB_API int (luaopen_math) (lua_State *L); + +#define LUA_DBLIBNAME "debug" +LUALIB_API int (luaopen_debug) (lua_State *L); + +#define LUA_LOADLIBNAME "package" +LUALIB_API int (luaopen_package) (lua_State *L); + + +/* open all previous libraries */ +LUALIB_API void (luaL_openlibs) (lua_State *L); + + + +#ifndef lua_assert +#define lua_assert(x) ((void)0) +#endif + + +#endif diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/src/lundump.c b/mod/pub.mod/lua.mod/lua-5.1.4/src/lundump.c new file mode 100644 index 0000000..8010a45 --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/src/lundump.c @@ -0,0 +1,227 @@ +/* +** $Id: lundump.c,v 2.7.1.4 2008/04/04 19:51:41 roberto Exp $ +** load precompiled Lua chunks +** See Copyright Notice in lua.h +*/ + +#include + +#define lundump_c +#define LUA_CORE + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstring.h" +#include "lundump.h" +#include "lzio.h" + +typedef struct { + lua_State* L; + ZIO* Z; + Mbuffer* b; + const char* name; +} LoadState; + +#ifdef LUAC_TRUST_BINARIES +#define IF(c,s) +#define error(S,s) +#else +#define IF(c,s) if (c) error(S,s) + +static void error(LoadState* S, const char* why) +{ + luaO_pushfstring(S->L,"%s: %s in precompiled chunk",S->name,why); + luaD_throw(S->L,LUA_ERRSYNTAX); +} +#endif + +#define LoadMem(S,b,n,size) LoadBlock(S,b,(n)*(size)) +#define LoadByte(S) (lu_byte)LoadChar(S) +#define LoadVar(S,x) LoadMem(S,&x,1,sizeof(x)) +#define LoadVector(S,b,n,size) LoadMem(S,b,n,size) + +static void LoadBlock(LoadState* S, void* b, size_t size) +{ + size_t r=luaZ_read(S->Z,b,size); + IF (r!=0, "unexpected end"); +} + +static int LoadChar(LoadState* S) +{ + char x; + LoadVar(S,x); + return x; +} + +static int LoadInt(LoadState* S) +{ + int x; + LoadVar(S,x); + IF (x<0, "bad integer"); + return x; +} + +static lua_Number LoadNumber(LoadState* S) +{ + lua_Number x; + LoadVar(S,x); + return x; +} + +static TString* LoadString(LoadState* S) +{ + size_t size; + LoadVar(S,size); + if (size==0) + return NULL; + else + { + char* s=luaZ_openspace(S->L,S->b,size); + LoadBlock(S,s,size); + return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */ + } +} + +static void LoadCode(LoadState* S, Proto* f) +{ + int n=LoadInt(S); + f->code=luaM_newvector(S->L,n,Instruction); + f->sizecode=n; + LoadVector(S,f->code,n,sizeof(Instruction)); +} + +static Proto* LoadFunction(LoadState* S, TString* p); + +static void LoadConstants(LoadState* S, Proto* f) +{ + int i,n; + n=LoadInt(S); + f->k=luaM_newvector(S->L,n,TValue); + f->sizek=n; + for (i=0; ik[i]); + for (i=0; ik[i]; + int t=LoadChar(S); + switch (t) + { + case LUA_TNIL: + setnilvalue(o); + break; + case LUA_TBOOLEAN: + setbvalue(o,LoadChar(S)!=0); + break; + case LUA_TNUMBER: + setnvalue(o,LoadNumber(S)); + break; + case LUA_TSTRING: + setsvalue2n(S->L,o,LoadString(S)); + break; + default: + error(S,"bad constant"); + break; + } + } + n=LoadInt(S); + f->p=luaM_newvector(S->L,n,Proto*); + f->sizep=n; + for (i=0; ip[i]=NULL; + for (i=0; ip[i]=LoadFunction(S,f->source); +} + +static void LoadDebug(LoadState* S, Proto* f) +{ + int i,n; + n=LoadInt(S); + f->lineinfo=luaM_newvector(S->L,n,int); + f->sizelineinfo=n; + LoadVector(S,f->lineinfo,n,sizeof(int)); + n=LoadInt(S); + f->locvars=luaM_newvector(S->L,n,LocVar); + f->sizelocvars=n; + for (i=0; ilocvars[i].varname=NULL; + for (i=0; ilocvars[i].varname=LoadString(S); + f->locvars[i].startpc=LoadInt(S); + f->locvars[i].endpc=LoadInt(S); + } + n=LoadInt(S); + f->upvalues=luaM_newvector(S->L,n,TString*); + f->sizeupvalues=n; + for (i=0; iupvalues[i]=NULL; + for (i=0; iupvalues[i]=LoadString(S); +} + +static Proto* LoadFunction(LoadState* S, TString* p) +{ + Proto* f; + if (++S->L->nCcalls > LUAI_MAXCCALLS) error(S,"code too deep"); + f=luaF_newproto(S->L); + setptvalue2s(S->L,S->L->top,f); incr_top(S->L); + f->source=LoadString(S); if (f->source==NULL) f->source=p; + f->linedefined=LoadInt(S); + f->lastlinedefined=LoadInt(S); + f->nups=LoadByte(S); + f->numparams=LoadByte(S); + f->is_vararg=LoadByte(S); + f->maxstacksize=LoadByte(S); + LoadCode(S,f); + LoadConstants(S,f); + LoadDebug(S,f); + IF (!luaG_checkcode(f), "bad code"); + S->L->top--; + S->L->nCcalls--; + return f; +} + +static void LoadHeader(LoadState* S) +{ + char h[LUAC_HEADERSIZE]; + char s[LUAC_HEADERSIZE]; + luaU_header(h); + LoadBlock(S,s,LUAC_HEADERSIZE); + IF (memcmp(h,s,LUAC_HEADERSIZE)!=0, "bad header"); +} + +/* +** load precompiled chunk +*/ +Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name) +{ + LoadState S; + if (*name=='@' || *name=='=') + S.name=name+1; + else if (*name==LUA_SIGNATURE[0]) + S.name="binary string"; + else + S.name=name; + S.L=L; + S.Z=Z; + S.b=buff; + LoadHeader(&S); + return LoadFunction(&S,luaS_newliteral(L,"=?")); +} + +/* +* make header +*/ +void luaU_header (char* h) +{ + int x=1; + memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-1); + h+=sizeof(LUA_SIGNATURE)-1; + *h++=(char)LUAC_VERSION; + *h++=(char)LUAC_FORMAT; + *h++=(char)*(char*)&x; /* endianness */ + *h++=(char)sizeof(int); + *h++=(char)sizeof(size_t); + *h++=(char)sizeof(Instruction); + *h++=(char)sizeof(lua_Number); + *h++=(char)(((lua_Number)0.5)==0); /* is lua_Number integral? */ +} diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/src/lundump.h b/mod/pub.mod/lua.mod/lua-5.1.4/src/lundump.h new file mode 100644 index 0000000..c80189d --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/src/lundump.h @@ -0,0 +1,36 @@ +/* +** $Id: lundump.h,v 1.37.1.1 2007/12/27 13:02:25 roberto Exp $ +** load precompiled Lua chunks +** See Copyright Notice in lua.h +*/ + +#ifndef lundump_h +#define lundump_h + +#include "lobject.h" +#include "lzio.h" + +/* load one chunk; from lundump.c */ +LUAI_FUNC Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name); + +/* make header; from lundump.c */ +LUAI_FUNC void luaU_header (char* h); + +/* dump one chunk; from ldump.c */ +LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip); + +#ifdef luac_c +/* print one chunk; from print.c */ +LUAI_FUNC void luaU_print (const Proto* f, int full); +#endif + +/* for header of binary files -- this is Lua 5.1 */ +#define LUAC_VERSION 0x51 + +/* for header of binary files -- this is the official format */ +#define LUAC_FORMAT 0 + +/* size of header of binary files */ +#define LUAC_HEADERSIZE 12 + +#endif diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/src/lvm.c b/mod/pub.mod/lua.mod/lua-5.1.4/src/lvm.c new file mode 100644 index 0000000..ee3256a --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/src/lvm.c @@ -0,0 +1,763 @@ +/* +** $Id: lvm.c,v 2.63.1.3 2007/12/28 15:32:23 roberto Exp $ +** Lua virtual machine +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include + +#define lvm_c +#define LUA_CORE + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" +#include "lvm.h" + + + +/* limit for table tag-method chains (to avoid loops) */ +#define MAXTAGLOOP 100 + + +const TValue *luaV_tonumber (const TValue *obj, TValue *n) { + lua_Number num; + if (ttisnumber(obj)) return obj; + if (ttisstring(obj) && luaO_str2d(svalue(obj), &num)) { + setnvalue(n, num); + return n; + } + else + return NULL; +} + + +int luaV_tostring (lua_State *L, StkId obj) { + if (!ttisnumber(obj)) + return 0; + else { + char s[LUAI_MAXNUMBER2STR]; + lua_Number n = nvalue(obj); + lua_number2str(s, n); + setsvalue2s(L, obj, luaS_new(L, s)); + return 1; + } +} + + +static void traceexec (lua_State *L, const Instruction *pc) { + lu_byte mask = L->hookmask; + const Instruction *oldpc = L->savedpc; + L->savedpc = pc; + if ((mask & LUA_MASKCOUNT) && L->hookcount == 0) { + resethookcount(L); + luaD_callhook(L, LUA_HOOKCOUNT, -1); + } + if (mask & LUA_MASKLINE) { + Proto *p = ci_func(L->ci)->l.p; + int npc = pcRel(pc, p); + int newline = getline(p, npc); + /* call linehook when enter a new function, when jump back (loop), + or when enter a new line */ + if (npc == 0 || pc <= oldpc || newline != getline(p, pcRel(oldpc, p))) + luaD_callhook(L, LUA_HOOKLINE, newline); + } +} + + +static void callTMres (lua_State *L, StkId res, const TValue *f, + const TValue *p1, const TValue *p2) { + ptrdiff_t result = savestack(L, res); + setobj2s(L, L->top, f); /* push function */ + setobj2s(L, L->top+1, p1); /* 1st argument */ + setobj2s(L, L->top+2, p2); /* 2nd argument */ + luaD_checkstack(L, 3); + L->top += 3; + luaD_call(L, L->top - 3, 1); + res = restorestack(L, result); + L->top--; + setobjs2s(L, res, L->top); +} + + + +static void callTM (lua_State *L, const TValue *f, const TValue *p1, + const TValue *p2, const TValue *p3) { + setobj2s(L, L->top, f); /* push function */ + setobj2s(L, L->top+1, p1); /* 1st argument */ + setobj2s(L, L->top+2, p2); /* 2nd argument */ + setobj2s(L, L->top+3, p3); /* 3th argument */ + luaD_checkstack(L, 4); + L->top += 4; + luaD_call(L, L->top - 4, 0); +} + + +void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) { + int loop; + for (loop = 0; loop < MAXTAGLOOP; loop++) { + const TValue *tm; + if (ttistable(t)) { /* `t' is a table? */ + Table *h = hvalue(t); + const TValue *res = luaH_get(h, key); /* do a primitive get */ + if (!ttisnil(res) || /* result is no nil? */ + (tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */ + setobj2s(L, val, res); + return; + } + /* else will try the tag method */ + } + else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX))) + luaG_typeerror(L, t, "index"); + if (ttisfunction(tm)) { + callTMres(L, val, tm, t, key); + return; + } + t = tm; /* else repeat with `tm' */ + } + luaG_runerror(L, "loop in gettable"); +} + + +void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) { + int loop; + for (loop = 0; loop < MAXTAGLOOP; loop++) { + const TValue *tm; + if (ttistable(t)) { /* `t' is a table? */ + Table *h = hvalue(t); + TValue *oldval = luaH_set(L, h, key); /* do a primitive set */ + if (!ttisnil(oldval) || /* result is no nil? */ + (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */ + setobj2t(L, oldval, val); + luaC_barriert(L, h, val); + return; + } + /* else will try the tag method */ + } + else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX))) + luaG_typeerror(L, t, "index"); + if (ttisfunction(tm)) { + callTM(L, tm, t, key, val); + return; + } + t = tm; /* else repeat with `tm' */ + } + luaG_runerror(L, "loop in settable"); +} + + +static int call_binTM (lua_State *L, const TValue *p1, const TValue *p2, + StkId res, TMS event) { + const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */ + if (ttisnil(tm)) + tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ + if (ttisnil(tm)) return 0; + callTMres(L, res, tm, p1, p2); + return 1; +} + + +static const TValue *get_compTM (lua_State *L, Table *mt1, Table *mt2, + TMS event) { + const TValue *tm1 = fasttm(L, mt1, event); + const TValue *tm2; + if (tm1 == NULL) return NULL; /* no metamethod */ + if (mt1 == mt2) return tm1; /* same metatables => same metamethods */ + tm2 = fasttm(L, mt2, event); + if (tm2 == NULL) return NULL; /* no metamethod */ + if (luaO_rawequalObj(tm1, tm2)) /* same metamethods? */ + return tm1; + return NULL; +} + + +static int call_orderTM (lua_State *L, const TValue *p1, const TValue *p2, + TMS event) { + const TValue *tm1 = luaT_gettmbyobj(L, p1, event); + const TValue *tm2; + if (ttisnil(tm1)) return -1; /* no metamethod? */ + tm2 = luaT_gettmbyobj(L, p2, event); + if (!luaO_rawequalObj(tm1, tm2)) /* different metamethods? */ + return -1; + callTMres(L, L->top, tm1, p1, p2); + return !l_isfalse(L->top); +} + + +static int l_strcmp (const TString *ls, const TString *rs) { + const char *l = getstr(ls); + size_t ll = ls->tsv.len; + const char *r = getstr(rs); + size_t lr = rs->tsv.len; + for (;;) { + int temp = strcoll(l, r); + if (temp != 0) return temp; + else { /* strings are equal up to a `\0' */ + size_t len = strlen(l); /* index of first `\0' in both strings */ + if (len == lr) /* r is finished? */ + return (len == ll) ? 0 : 1; + else if (len == ll) /* l is finished? */ + return -1; /* l is smaller than r (because r is not finished) */ + /* both strings longer than `len'; go on comparing (after the `\0') */ + len++; + l += len; ll -= len; r += len; lr -= len; + } + } +} + + +int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) { + int res; + if (ttype(l) != ttype(r)) + return luaG_ordererror(L, l, r); + else if (ttisnumber(l)) + return luai_numlt(nvalue(l), nvalue(r)); + else if (ttisstring(l)) + return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0; + else if ((res = call_orderTM(L, l, r, TM_LT)) != -1) + return res; + return luaG_ordererror(L, l, r); +} + + +static int lessequal (lua_State *L, const TValue *l, const TValue *r) { + int res; + if (ttype(l) != ttype(r)) + return luaG_ordererror(L, l, r); + else if (ttisnumber(l)) + return luai_numle(nvalue(l), nvalue(r)); + else if (ttisstring(l)) + return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0; + else if ((res = call_orderTM(L, l, r, TM_LE)) != -1) /* first try `le' */ + return res; + else if ((res = call_orderTM(L, r, l, TM_LT)) != -1) /* else try `lt' */ + return !res; + return luaG_ordererror(L, l, r); +} + + +int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2) { + const TValue *tm; + lua_assert(ttype(t1) == ttype(t2)); + switch (ttype(t1)) { + case LUA_TNIL: return 1; + case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2)); + case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */ + case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2); + case LUA_TUSERDATA: { + if (uvalue(t1) == uvalue(t2)) return 1; + tm = get_compTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable, + TM_EQ); + break; /* will try TM */ + } + case LUA_TTABLE: { + if (hvalue(t1) == hvalue(t2)) return 1; + tm = get_compTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ); + break; /* will try TM */ + } + default: return gcvalue(t1) == gcvalue(t2); + } + if (tm == NULL) return 0; /* no TM? */ + callTMres(L, L->top, tm, t1, t2); /* call TM */ + return !l_isfalse(L->top); +} + + +void luaV_concat (lua_State *L, int total, int last) { + do { + StkId top = L->base + last + 1; + int n = 2; /* number of elements handled in this pass (at least 2) */ + if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1)) { + if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT)) + luaG_concaterror(L, top-2, top-1); + } else if (tsvalue(top-1)->len == 0) /* second op is empty? */ + (void)tostring(L, top - 2); /* result is first op (as string) */ + else { + /* at least two string values; get as many as possible */ + size_t tl = tsvalue(top-1)->len; + char *buffer; + int i; + /* collect total length */ + for (n = 1; n < total && tostring(L, top-n-1); n++) { + size_t l = tsvalue(top-n-1)->len; + if (l >= MAX_SIZET - tl) luaG_runerror(L, "string length overflow"); + tl += l; + } + buffer = luaZ_openspace(L, &G(L)->buff, tl); + tl = 0; + for (i=n; i>0; i--) { /* concat all strings */ + size_t l = tsvalue(top-i)->len; + memcpy(buffer+tl, svalue(top-i), l); + tl += l; + } + setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl)); + } + total -= n-1; /* got `n' strings to create 1 new */ + last -= n-1; + } while (total > 1); /* repeat until only 1 result left */ +} + + +static void Arith (lua_State *L, StkId ra, const TValue *rb, + const TValue *rc, TMS op) { + TValue tempb, tempc; + const TValue *b, *c; + if ((b = luaV_tonumber(rb, &tempb)) != NULL && + (c = luaV_tonumber(rc, &tempc)) != NULL) { + lua_Number nb = nvalue(b), nc = nvalue(c); + switch (op) { + case TM_ADD: setnvalue(ra, luai_numadd(nb, nc)); break; + case TM_SUB: setnvalue(ra, luai_numsub(nb, nc)); break; + case TM_MUL: setnvalue(ra, luai_nummul(nb, nc)); break; + case TM_DIV: setnvalue(ra, luai_numdiv(nb, nc)); break; + case TM_MOD: setnvalue(ra, luai_nummod(nb, nc)); break; + case TM_POW: setnvalue(ra, luai_numpow(nb, nc)); break; + case TM_UNM: setnvalue(ra, luai_numunm(nb)); break; + default: lua_assert(0); break; + } + } + else if (!call_binTM(L, rb, rc, ra, op)) + luaG_aritherror(L, rb, rc); +} + + + +/* +** some macros for common tasks in `luaV_execute' +*/ + +#define runtime_check(L, c) { if (!(c)) break; } + +#define RA(i) (base+GETARG_A(i)) +/* to be used after possible stack reallocation */ +#define RB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_B(i)) +#define RC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgR, base+GETARG_C(i)) +#define RKB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, \ + ISK(GETARG_B(i)) ? k+INDEXK(GETARG_B(i)) : base+GETARG_B(i)) +#define RKC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgK, \ + ISK(GETARG_C(i)) ? k+INDEXK(GETARG_C(i)) : base+GETARG_C(i)) +#define KBx(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, k+GETARG_Bx(i)) + + +#define dojump(L,pc,i) {(pc) += (i); luai_threadyield(L);} + + +#define Protect(x) { L->savedpc = pc; {x;}; base = L->base; } + + +#define arith_op(op,tm) { \ + TValue *rb = RKB(i); \ + TValue *rc = RKC(i); \ + if (ttisnumber(rb) && ttisnumber(rc)) { \ + lua_Number nb = nvalue(rb), nc = nvalue(rc); \ + setnvalue(ra, op(nb, nc)); \ + } \ + else \ + Protect(Arith(L, ra, rb, rc, tm)); \ + } + + + +void luaV_execute (lua_State *L, int nexeccalls) { + LClosure *cl; + StkId base; + TValue *k; + const Instruction *pc; + reentry: /* entry point */ + lua_assert(isLua(L->ci)); + pc = L->savedpc; + cl = &clvalue(L->ci->func)->l; + base = L->base; + k = cl->p->k; + /* main loop of interpreter */ + for (;;) { + const Instruction i = *pc++; + StkId ra; + if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) && + (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) { + traceexec(L, pc); + if (L->status == LUA_YIELD) { /* did hook yield? */ + L->savedpc = pc - 1; + return; + } + base = L->base; + } + /* warning!! several calls may realloc the stack and invalidate `ra' */ + ra = RA(i); + lua_assert(base == L->base && L->base == L->ci->base); + lua_assert(base <= L->top && L->top <= L->stack + L->stacksize); + lua_assert(L->top == L->ci->top || luaG_checkopenop(i)); + switch (GET_OPCODE(i)) { + case OP_MOVE: { + setobjs2s(L, ra, RB(i)); + continue; + } + case OP_LOADK: { + setobj2s(L, ra, KBx(i)); + continue; + } + case OP_LOADBOOL: { + setbvalue(ra, GETARG_B(i)); + if (GETARG_C(i)) pc++; /* skip next instruction (if C) */ + continue; + } + case OP_LOADNIL: { + TValue *rb = RB(i); + do { + setnilvalue(rb--); + } while (rb >= ra); + continue; + } + case OP_GETUPVAL: { + int b = GETARG_B(i); + setobj2s(L, ra, cl->upvals[b]->v); + continue; + } + case OP_GETGLOBAL: { + TValue g; + TValue *rb = KBx(i); + sethvalue(L, &g, cl->env); + lua_assert(ttisstring(rb)); + Protect(luaV_gettable(L, &g, rb, ra)); + continue; + } + case OP_GETTABLE: { + Protect(luaV_gettable(L, RB(i), RKC(i), ra)); + continue; + } + case OP_SETGLOBAL: { + TValue g; + sethvalue(L, &g, cl->env); + lua_assert(ttisstring(KBx(i))); + Protect(luaV_settable(L, &g, KBx(i), ra)); + continue; + } + case OP_SETUPVAL: { + UpVal *uv = cl->upvals[GETARG_B(i)]; + setobj(L, uv->v, ra); + luaC_barrier(L, uv, ra); + continue; + } + case OP_SETTABLE: { + Protect(luaV_settable(L, ra, RKB(i), RKC(i))); + continue; + } + case OP_NEWTABLE: { + int b = GETARG_B(i); + int c = GETARG_C(i); + sethvalue(L, ra, luaH_new(L, luaO_fb2int(b), luaO_fb2int(c))); + Protect(luaC_checkGC(L)); + continue; + } + case OP_SELF: { + StkId rb = RB(i); + setobjs2s(L, ra+1, rb); + Protect(luaV_gettable(L, rb, RKC(i), ra)); + continue; + } + case OP_ADD: { + arith_op(luai_numadd, TM_ADD); + continue; + } + case OP_SUB: { + arith_op(luai_numsub, TM_SUB); + continue; + } + case OP_MUL: { + arith_op(luai_nummul, TM_MUL); + continue; + } + case OP_DIV: { + arith_op(luai_numdiv, TM_DIV); + continue; + } + case OP_MOD: { + arith_op(luai_nummod, TM_MOD); + continue; + } + case OP_POW: { + arith_op(luai_numpow, TM_POW); + continue; + } + case OP_UNM: { + TValue *rb = RB(i); + if (ttisnumber(rb)) { + lua_Number nb = nvalue(rb); + setnvalue(ra, luai_numunm(nb)); + } + else { + Protect(Arith(L, ra, rb, rb, TM_UNM)); + } + continue; + } + case OP_NOT: { + int res = l_isfalse(RB(i)); /* next assignment may change this value */ + setbvalue(ra, res); + continue; + } + case OP_LEN: { + const TValue *rb = RB(i); + switch (ttype(rb)) { + case LUA_TTABLE: { + setnvalue(ra, cast_num(luaH_getn(hvalue(rb)))); + break; + } + case LUA_TSTRING: { + setnvalue(ra, cast_num(tsvalue(rb)->len)); + break; + } + default: { /* try metamethod */ + Protect( + if (!call_binTM(L, rb, luaO_nilobject, ra, TM_LEN)) + luaG_typeerror(L, rb, "get length of"); + ) + } + } + continue; + } + case OP_CONCAT: { + int b = GETARG_B(i); + int c = GETARG_C(i); + Protect(luaV_concat(L, c-b+1, c); luaC_checkGC(L)); + setobjs2s(L, RA(i), base+b); + continue; + } + case OP_JMP: { + dojump(L, pc, GETARG_sBx(i)); + continue; + } + case OP_EQ: { + TValue *rb = RKB(i); + TValue *rc = RKC(i); + Protect( + if (equalobj(L, rb, rc) == GETARG_A(i)) + dojump(L, pc, GETARG_sBx(*pc)); + ) + pc++; + continue; + } + case OP_LT: { + Protect( + if (luaV_lessthan(L, RKB(i), RKC(i)) == GETARG_A(i)) + dojump(L, pc, GETARG_sBx(*pc)); + ) + pc++; + continue; + } + case OP_LE: { + Protect( + if (lessequal(L, RKB(i), RKC(i)) == GETARG_A(i)) + dojump(L, pc, GETARG_sBx(*pc)); + ) + pc++; + continue; + } + case OP_TEST: { + if (l_isfalse(ra) != GETARG_C(i)) + dojump(L, pc, GETARG_sBx(*pc)); + pc++; + continue; + } + case OP_TESTSET: { + TValue *rb = RB(i); + if (l_isfalse(rb) != GETARG_C(i)) { + setobjs2s(L, ra, rb); + dojump(L, pc, GETARG_sBx(*pc)); + } + pc++; + continue; + } + case OP_CALL: { + int b = GETARG_B(i); + int nresults = GETARG_C(i) - 1; + if (b != 0) L->top = ra+b; /* else previous instruction set top */ + L->savedpc = pc; + switch (luaD_precall(L, ra, nresults)) { + case PCRLUA: { + nexeccalls++; + goto reentry; /* restart luaV_execute over new Lua function */ + } + case PCRC: { + /* it was a C function (`precall' called it); adjust results */ + if (nresults >= 0) L->top = L->ci->top; + base = L->base; + continue; + } + default: { + return; /* yield */ + } + } + } + case OP_TAILCALL: { + int b = GETARG_B(i); + if (b != 0) L->top = ra+b; /* else previous instruction set top */ + L->savedpc = pc; + lua_assert(GETARG_C(i) - 1 == LUA_MULTRET); + switch (luaD_precall(L, ra, LUA_MULTRET)) { + case PCRLUA: { + /* tail call: put new frame in place of previous one */ + CallInfo *ci = L->ci - 1; /* previous frame */ + int aux; + StkId func = ci->func; + StkId pfunc = (ci+1)->func; /* previous function index */ + if (L->openupval) luaF_close(L, ci->base); + L->base = ci->base = ci->func + ((ci+1)->base - pfunc); + for (aux = 0; pfunc+aux < L->top; aux++) /* move frame down */ + setobjs2s(L, func+aux, pfunc+aux); + ci->top = L->top = func+aux; /* correct top */ + lua_assert(L->top == L->base + clvalue(func)->l.p->maxstacksize); + ci->savedpc = L->savedpc; + ci->tailcalls++; /* one more call lost */ + L->ci--; /* remove new frame */ + goto reentry; + } + case PCRC: { /* it was a C function (`precall' called it) */ + base = L->base; + continue; + } + default: { + return; /* yield */ + } + } + } + case OP_RETURN: { + int b = GETARG_B(i); + if (b != 0) L->top = ra+b-1; + if (L->openupval) luaF_close(L, base); + L->savedpc = pc; + b = luaD_poscall(L, ra); + if (--nexeccalls == 0) /* was previous function running `here'? */ + return; /* no: return */ + else { /* yes: continue its execution */ + if (b) L->top = L->ci->top; + lua_assert(isLua(L->ci)); + lua_assert(GET_OPCODE(*((L->ci)->savedpc - 1)) == OP_CALL); + goto reentry; + } + } + case OP_FORLOOP: { + lua_Number step = nvalue(ra+2); + lua_Number idx = luai_numadd(nvalue(ra), step); /* increment index */ + lua_Number limit = nvalue(ra+1); + if (luai_numlt(0, step) ? luai_numle(idx, limit) + : luai_numle(limit, idx)) { + dojump(L, pc, GETARG_sBx(i)); /* jump back */ + setnvalue(ra, idx); /* update internal index... */ + setnvalue(ra+3, idx); /* ...and external index */ + } + continue; + } + case OP_FORPREP: { + const TValue *init = ra; + const TValue *plimit = ra+1; + const TValue *pstep = ra+2; + L->savedpc = pc; /* next steps may throw errors */ + if (!tonumber(init, ra)) + luaG_runerror(L, LUA_QL("for") " initial value must be a number"); + else if (!tonumber(plimit, ra+1)) + luaG_runerror(L, LUA_QL("for") " limit must be a number"); + else if (!tonumber(pstep, ra+2)) + luaG_runerror(L, LUA_QL("for") " step must be a number"); + setnvalue(ra, luai_numsub(nvalue(ra), nvalue(pstep))); + dojump(L, pc, GETARG_sBx(i)); + continue; + } + case OP_TFORLOOP: { + StkId cb = ra + 3; /* call base */ + setobjs2s(L, cb+2, ra+2); + setobjs2s(L, cb+1, ra+1); + setobjs2s(L, cb, ra); + L->top = cb+3; /* func. + 2 args (state and index) */ + Protect(luaD_call(L, cb, GETARG_C(i))); + L->top = L->ci->top; + cb = RA(i) + 3; /* previous call may change the stack */ + if (!ttisnil(cb)) { /* continue loop? */ + setobjs2s(L, cb-1, cb); /* save control variable */ + dojump(L, pc, GETARG_sBx(*pc)); /* jump back */ + } + pc++; + continue; + } + case OP_SETLIST: { + int n = GETARG_B(i); + int c = GETARG_C(i); + int last; + Table *h; + if (n == 0) { + n = cast_int(L->top - ra) - 1; + L->top = L->ci->top; + } + if (c == 0) c = cast_int(*pc++); + runtime_check(L, ttistable(ra)); + h = hvalue(ra); + last = ((c-1)*LFIELDS_PER_FLUSH) + n; + if (last > h->sizearray) /* needs more space? */ + luaH_resizearray(L, h, last); /* pre-alloc it at once */ + for (; n > 0; n--) { + TValue *val = ra+n; + setobj2t(L, luaH_setnum(L, h, last--), val); + luaC_barriert(L, h, val); + } + continue; + } + case OP_CLOSE: { + luaF_close(L, ra); + continue; + } + case OP_CLOSURE: { + Proto *p; + Closure *ncl; + int nup, j; + p = cl->p->p[GETARG_Bx(i)]; + nup = p->nups; + ncl = luaF_newLclosure(L, nup, cl->env); + ncl->l.p = p; + for (j=0; jl.upvals[j] = cl->upvals[GETARG_B(*pc)]; + else { + lua_assert(GET_OPCODE(*pc) == OP_MOVE); + ncl->l.upvals[j] = luaF_findupval(L, base + GETARG_B(*pc)); + } + } + setclvalue(L, ra, ncl); + Protect(luaC_checkGC(L)); + continue; + } + case OP_VARARG: { + int b = GETARG_B(i) - 1; + int j; + CallInfo *ci = L->ci; + int n = cast_int(ci->base - ci->func) - cl->p->numparams - 1; + if (b == LUA_MULTRET) { + Protect(luaD_checkstack(L, n)); + ra = RA(i); /* previous call may change the stack */ + b = n; + L->top = ra + n; + } + for (j = 0; j < b; j++) { + if (j < n) { + setobjs2s(L, ra + j, ci->base - n + j); + } + else { + setnilvalue(ra + j); + } + } + continue; + } + } + } +} + diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/src/lvm.h b/mod/pub.mod/lua.mod/lua-5.1.4/src/lvm.h new file mode 100644 index 0000000..bfe4f56 --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/src/lvm.h @@ -0,0 +1,36 @@ +/* +** $Id: lvm.h,v 2.5.1.1 2007/12/27 13:02:25 roberto Exp $ +** Lua virtual machine +** See Copyright Notice in lua.h +*/ + +#ifndef lvm_h +#define lvm_h + + +#include "ldo.h" +#include "lobject.h" +#include "ltm.h" + + +#define tostring(L,o) ((ttype(o) == LUA_TSTRING) || (luaV_tostring(L, o))) + +#define tonumber(o,n) (ttype(o) == LUA_TNUMBER || \ + (((o) = luaV_tonumber(o,n)) != NULL)) + +#define equalobj(L,o1,o2) \ + (ttype(o1) == ttype(o2) && luaV_equalval(L, o1, o2)) + + +LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r); +LUAI_FUNC int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2); +LUAI_FUNC const TValue *luaV_tonumber (const TValue *obj, TValue *n); +LUAI_FUNC int luaV_tostring (lua_State *L, StkId obj); +LUAI_FUNC void luaV_gettable (lua_State *L, const TValue *t, TValue *key, + StkId val); +LUAI_FUNC void luaV_settable (lua_State *L, const TValue *t, TValue *key, + StkId val); +LUAI_FUNC void luaV_execute (lua_State *L, int nexeccalls); +LUAI_FUNC void luaV_concat (lua_State *L, int total, int last); + +#endif diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/src/lzio.c b/mod/pub.mod/lua.mod/lua-5.1.4/src/lzio.c new file mode 100644 index 0000000..293edd5 --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/src/lzio.c @@ -0,0 +1,82 @@ +/* +** $Id: lzio.c,v 1.31.1.1 2007/12/27 13:02:25 roberto Exp $ +** a generic input stream interface +** See Copyright Notice in lua.h +*/ + + +#include + +#define lzio_c +#define LUA_CORE + +#include "lua.h" + +#include "llimits.h" +#include "lmem.h" +#include "lstate.h" +#include "lzio.h" + + +int luaZ_fill (ZIO *z) { + size_t size; + lua_State *L = z->L; + const char *buff; + lua_unlock(L); + buff = z->reader(L, z->data, &size); + lua_lock(L); + if (buff == NULL || size == 0) return EOZ; + z->n = size - 1; + z->p = buff; + return char2int(*(z->p++)); +} + + +int luaZ_lookahead (ZIO *z) { + if (z->n == 0) { + if (luaZ_fill(z) == EOZ) + return EOZ; + else { + z->n++; /* luaZ_fill removed first byte; put back it */ + z->p--; + } + } + return char2int(*z->p); +} + + +void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) { + z->L = L; + z->reader = reader; + z->data = data; + z->n = 0; + z->p = NULL; +} + + +/* --------------------------------------------------------------- read --- */ +size_t luaZ_read (ZIO *z, void *b, size_t n) { + while (n) { + size_t m; + if (luaZ_lookahead(z) == EOZ) + return n; /* return number of missing bytes */ + m = (n <= z->n) ? n : z->n; /* min. between n and z->n */ + memcpy(b, z->p, m); + z->n -= m; + z->p += m; + b = (char *)b + m; + n -= m; + } + return 0; +} + +/* ------------------------------------------------------------------------ */ +char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n) { + if (n > buff->buffsize) { + if (n < LUA_MINBUFFER) n = LUA_MINBUFFER; + luaZ_resizebuffer(L, buff, n); + } + return buff->buffer; +} + + diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/src/lzio.h b/mod/pub.mod/lua.mod/lua-5.1.4/src/lzio.h new file mode 100644 index 0000000..51d695d --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/src/lzio.h @@ -0,0 +1,67 @@ +/* +** $Id: lzio.h,v 1.21.1.1 2007/12/27 13:02:25 roberto Exp $ +** Buffered streams +** See Copyright Notice in lua.h +*/ + + +#ifndef lzio_h +#define lzio_h + +#include "lua.h" + +#include "lmem.h" + + +#define EOZ (-1) /* end of stream */ + +typedef struct Zio ZIO; + +#define char2int(c) cast(int, cast(unsigned char, (c))) + +#define zgetc(z) (((z)->n--)>0 ? char2int(*(z)->p++) : luaZ_fill(z)) + +typedef struct Mbuffer { + char *buffer; + size_t n; + size_t buffsize; +} Mbuffer; + +#define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0) + +#define luaZ_buffer(buff) ((buff)->buffer) +#define luaZ_sizebuffer(buff) ((buff)->buffsize) +#define luaZ_bufflen(buff) ((buff)->n) + +#define luaZ_resetbuffer(buff) ((buff)->n = 0) + + +#define luaZ_resizebuffer(L, buff, size) \ + (luaM_reallocvector(L, (buff)->buffer, (buff)->buffsize, size, char), \ + (buff)->buffsize = size) + +#define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0) + + +LUAI_FUNC char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n); +LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, + void *data); +LUAI_FUNC size_t luaZ_read (ZIO* z, void* b, size_t n); /* read next n bytes */ +LUAI_FUNC int luaZ_lookahead (ZIO *z); + + + +/* --------- Private Part ------------------ */ + +struct Zio { + size_t n; /* bytes still unread */ + const char *p; /* current position in buffer */ + lua_Reader reader; + void* data; /* additional data */ + lua_State *L; /* Lua state (for reader) */ +}; + + +LUAI_FUNC int luaZ_fill (ZIO *z); + +#endif diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/src/print.c b/mod/pub.mod/lua.mod/lua-5.1.4/src/print.c new file mode 100644 index 0000000..e240cfc --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/src/print.c @@ -0,0 +1,227 @@ +/* +** $Id: print.c,v 1.55a 2006/05/31 13:30:05 lhf Exp $ +** print bytecodes +** See Copyright Notice in lua.h +*/ + +#include +#include + +#define luac_c +#define LUA_CORE + +#include "ldebug.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lundump.h" + +#define PrintFunction luaU_print + +#define Sizeof(x) ((int)sizeof(x)) +#define VOID(p) ((const void*)(p)) + +static void PrintString(const TString* ts) +{ + const char* s=getstr(ts); + size_t i,n=ts->tsv.len; + putchar('"'); + for (i=0; ik[i]; + switch (ttype(o)) + { + case LUA_TNIL: + printf("nil"); + break; + case LUA_TBOOLEAN: + printf(bvalue(o) ? "true" : "false"); + break; + case LUA_TNUMBER: + printf(LUA_NUMBER_FMT,nvalue(o)); + break; + case LUA_TSTRING: + PrintString(rawtsvalue(o)); + break; + default: /* cannot happen */ + printf("? type=%d",ttype(o)); + break; + } +} + +static void PrintCode(const Proto* f) +{ + const Instruction* code=f->code; + int pc,n=f->sizecode; + for (pc=0; pc0) printf("[%d]\t",line); else printf("[-]\t"); + printf("%-9s\t",luaP_opnames[o]); + switch (getOpMode(o)) + { + case iABC: + printf("%d",a); + if (getBMode(o)!=OpArgN) printf(" %d",ISK(b) ? (-1-INDEXK(b)) : b); + if (getCMode(o)!=OpArgN) printf(" %d",ISK(c) ? (-1-INDEXK(c)) : c); + break; + case iABx: + if (getBMode(o)==OpArgK) printf("%d %d",a,-1-bx); else printf("%d %d",a,bx); + break; + case iAsBx: + if (o==OP_JMP) printf("%d",sbx); else printf("%d %d",a,sbx); + break; + } + switch (o) + { + case OP_LOADK: + printf("\t; "); PrintConstant(f,bx); + break; + case OP_GETUPVAL: + case OP_SETUPVAL: + printf("\t; %s", (f->sizeupvalues>0) ? getstr(f->upvalues[b]) : "-"); + break; + case OP_GETGLOBAL: + case OP_SETGLOBAL: + printf("\t; %s",svalue(&f->k[bx])); + break; + case OP_GETTABLE: + case OP_SELF: + if (ISK(c)) { printf("\t; "); PrintConstant(f,INDEXK(c)); } + break; + case OP_SETTABLE: + case OP_ADD: + case OP_SUB: + case OP_MUL: + case OP_DIV: + case OP_POW: + case OP_EQ: + case OP_LT: + case OP_LE: + if (ISK(b) || ISK(c)) + { + printf("\t; "); + if (ISK(b)) PrintConstant(f,INDEXK(b)); else printf("-"); + printf(" "); + if (ISK(c)) PrintConstant(f,INDEXK(c)); else printf("-"); + } + break; + case OP_JMP: + case OP_FORLOOP: + case OP_FORPREP: + printf("\t; to %d",sbx+pc+2); + break; + case OP_CLOSURE: + printf("\t; %p",VOID(f->p[bx])); + break; + case OP_SETLIST: + if (c==0) printf("\t; %d",(int)code[++pc]); + else printf("\t; %d",c); + break; + default: + break; + } + printf("\n"); + } +} + +#define SS(x) (x==1)?"":"s" +#define S(x) x,SS(x) + +static void PrintHeader(const Proto* f) +{ + const char* s=getstr(f->source); + if (*s=='@' || *s=='=') + s++; + else if (*s==LUA_SIGNATURE[0]) + s="(bstring)"; + else + s="(string)"; + printf("\n%s <%s:%d,%d> (%d instruction%s, %d bytes at %p)\n", + (f->linedefined==0)?"main":"function",s, + f->linedefined,f->lastlinedefined, + S(f->sizecode),f->sizecode*Sizeof(Instruction),VOID(f)); + printf("%d%s param%s, %d slot%s, %d upvalue%s, ", + f->numparams,f->is_vararg?"+":"",SS(f->numparams), + S(f->maxstacksize),S(f->nups)); + printf("%d local%s, %d constant%s, %d function%s\n", + S(f->sizelocvars),S(f->sizek),S(f->sizep)); +} + +static void PrintConstants(const Proto* f) +{ + int i,n=f->sizek; + printf("constants (%d) for %p:\n",n,VOID(f)); + for (i=0; isizelocvars; + printf("locals (%d) for %p:\n",n,VOID(f)); + for (i=0; ilocvars[i].varname),f->locvars[i].startpc+1,f->locvars[i].endpc+1); + } +} + +static void PrintUpvalues(const Proto* f) +{ + int i,n=f->sizeupvalues; + printf("upvalues (%d) for %p:\n",n,VOID(f)); + if (f->upvalues==NULL) return; + for (i=0; iupvalues[i])); + } +} + +void PrintFunction(const Proto* f, int full) +{ + int i,n=f->sizep; + PrintHeader(f); + PrintCode(f); + if (full) + { + PrintConstants(f); + PrintLocals(f); + PrintUpvalues(f); + } + for (i=0; ip[i],full); +} diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/test/README b/mod/pub.mod/lua.mod/lua-5.1.4/test/README new file mode 100644 index 0000000..0c7f38b --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/test/README @@ -0,0 +1,26 @@ +These are simple tests for Lua. Some of them contain useful code. +They are meant to be run to make sure Lua is built correctly and also +to be read, to see how Lua programs look. + +Here is a one-line summary of each program: + + bisect.lua bisection method for solving non-linear equations + cf.lua temperature conversion table (celsius to farenheit) + echo.lua echo command line arguments + env.lua environment variables as automatic global variables + factorial.lua factorial without recursion + fib.lua fibonacci function with cache + fibfor.lua fibonacci numbers with coroutines and generators + globals.lua report global variable usage + hello.lua the first program in every language + life.lua Conway's Game of Life + luac.lua bare-bones luac + printf.lua an implementation of printf + readonly.lua make global variables readonly + sieve.lua the sieve of of Eratosthenes programmed with coroutines + sort.lua two implementations of a sort function + table.lua make table, grouping all data for the same item + trace-calls.lua trace calls + trace-globals.lua trace assigments to global variables + xd.lua hex dump + diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/test/bisect.lua b/mod/pub.mod/lua.mod/lua-5.1.4/test/bisect.lua new file mode 100644 index 0000000..f91e69b --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/test/bisect.lua @@ -0,0 +1,27 @@ +-- bisection method for solving non-linear equations + +delta=1e-6 -- tolerance + +function bisect(f,a,b,fa,fb) + local c=(a+b)/2 + io.write(n," c=",c," a=",a," b=",b,"\n") + if c==a or c==b or math.abs(a-b) posted to lua-l +-- modified to use ANSI terminal escape sequences +-- modified to use for instead of while + +local write=io.write + +ALIVE="Β₯" DEAD="ΓΎ" +ALIVE="O" DEAD="-" + +function delay() -- NOTE: SYSTEM-DEPENDENT, adjust as necessary + for i=1,10000 do end + -- local i=os.clock()+1 while(os.clock() 0 do + local xm1,x,xp1,xi=self.w-1,self.w,1,self.w + while xi > 0 do + local sum = self[ym1][xm1] + self[ym1][x] + self[ym1][xp1] + + self[y][xm1] + self[y][xp1] + + self[yp1][xm1] + self[yp1][x] + self[yp1][xp1] + next[y][x] = ((sum==2) and self[y][x]) or ((sum==3) and 1) or 0 + xm1,x,xp1,xi = x,xp1,xp1+1,xi-1 + end + ym1,y,yp1,yi = y,yp1,yp1+1,yi-1 + end +end + +-- output the array to screen +function _CELLS:draw() + local out="" -- accumulate to reduce flicker + for y=1,self.h do + for x=1,self.w do + out=out..(((self[y][x]>0) and ALIVE) or DEAD) + end + out=out.."\n" + end + write(out) +end + +-- constructor +function CELLS(w,h) + local c = ARRAY2D(w,h) + c.spawn = _CELLS.spawn + c.evolve = _CELLS.evolve + c.draw = _CELLS.draw + return c +end + +-- +-- shapes suitable for use with spawn() above +-- +HEART = { 1,0,1,1,0,1,1,1,1; w=3,h=3 } +GLIDER = { 0,0,1,1,0,1,0,1,1; w=3,h=3 } +EXPLODE = { 0,1,0,1,1,1,1,0,1,0,1,0; w=3,h=4 } +FISH = { 0,1,1,1,1,1,0,0,0,1,0,0,0,0,1,1,0,0,1,0; w=5,h=4 } +BUTTERFLY = { 1,0,0,0,1,0,1,1,1,0,1,0,0,0,1,1,0,1,0,1,1,0,0,0,1; w=5,h=5 } + +-- the main routine +function LIFE(w,h) + -- create two arrays + local thisgen = CELLS(w,h) + local nextgen = CELLS(w,h) + + -- create some life + -- about 1000 generations of fun, then a glider steady-state + thisgen:spawn(GLIDER,5,4) + thisgen:spawn(EXPLODE,25,10) + thisgen:spawn(FISH,4,12) + + -- run until break + local gen=1 + write("\027[2J") -- ANSI clear screen + while 1 do + thisgen:evolve(nextgen) + thisgen,nextgen = nextgen,thisgen + write("\027[H") -- ANSI home cursor + thisgen:draw() + write("Life - generation ",gen,"\n") + gen=gen+1 + if gen>2000 then break end + --delay() -- no delay + end +end + +LIFE(40,20) diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/test/luac.lua b/mod/pub.mod/lua.mod/lua-5.1.4/test/luac.lua new file mode 100644 index 0000000..96a0a97 --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/test/luac.lua @@ -0,0 +1,7 @@ +-- bare-bones luac in Lua +-- usage: lua luac.lua file.lua + +assert(arg[1]~=nil and arg[2]==nil,"usage: lua luac.lua file.lua") +f=assert(io.open("luac.out","wb")) +assert(f:write(string.dump(assert(loadfile(arg[1]))))) +assert(f:close()) diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/test/printf.lua b/mod/pub.mod/lua.mod/lua-5.1.4/test/printf.lua new file mode 100644 index 0000000..58c63ff --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/test/printf.lua @@ -0,0 +1,7 @@ +-- an implementation of printf + +function printf(...) + io.write(string.format(...)) +end + +printf("Hello %s from %s on %s\n",os.getenv"USER" or "there",_VERSION,os.date()) diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/test/readonly.lua b/mod/pub.mod/lua.mod/lua-5.1.4/test/readonly.lua new file mode 100644 index 0000000..85c0b4e --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/test/readonly.lua @@ -0,0 +1,12 @@ +-- make global variables readonly + +local f=function (t,i) error("cannot redefine global variable `"..i.."'",2) end +local g={} +local G=getfenv() +setmetatable(g,{__index=G,__newindex=f}) +setfenv(1,g) + +-- an example +rawset(g,"x",3) +x=2 +y=1 -- cannot redefine `y' diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/test/sieve.lua b/mod/pub.mod/lua.mod/lua-5.1.4/test/sieve.lua new file mode 100644 index 0000000..0871bb2 --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/test/sieve.lua @@ -0,0 +1,29 @@ +-- the sieve of of Eratosthenes programmed with coroutines +-- typical usage: lua -e N=1000 sieve.lua | column + +-- generate all the numbers from 2 to n +function gen (n) + return coroutine.wrap(function () + for i=2,n do coroutine.yield(i) end + end) +end + +-- filter the numbers generated by `g', removing multiples of `p' +function filter (p, g) + return coroutine.wrap(function () + while 1 do + local n = g() + if n == nil then return end + if math.mod(n, p) ~= 0 then coroutine.yield(n) end + end + end) +end + +N=N or 1000 -- from command line +x = gen(N) -- generate primes up to N +while 1 do + local n = x() -- pick a number until done + if n == nil then break end + print(n) -- must be a prime number + x = filter(n, x) -- now remove its multiples +end diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/test/sort.lua b/mod/pub.mod/lua.mod/lua-5.1.4/test/sort.lua new file mode 100644 index 0000000..0bcb15f --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/test/sort.lua @@ -0,0 +1,66 @@ +-- two implementations of a sort function +-- this is an example only. Lua has now a built-in function "sort" + +-- extracted from Programming Pearls, page 110 +function qsort(x,l,u,f) + if ly end) + show("after reverse selection sort",x) + qsort(x,1,n,function (x,y) return x>> ",string.rep(" ",level)) + if t~=nil and t.currentline>=0 then io.write(t.short_src,":",t.currentline," ") end + t=debug.getinfo(2) + if event=="call" then + level=level+1 + else + level=level-1 if level<0 then level=0 end + end + if t.what=="main" then + if event=="call" then + io.write("begin ",t.short_src) + else + io.write("end ",t.short_src) + end + elseif t.what=="Lua" then +-- table.foreach(t,print) + io.write(event," ",t.name or "(Lua)"," <",t.linedefined,":",t.short_src,">") + else + io.write(event," ",t.name or "(C)"," [",t.what,"] ") + end + io.write("\n") +end + +debug.sethook(hook,"cr") +level=0 diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/test/trace-globals.lua b/mod/pub.mod/lua.mod/lua-5.1.4/test/trace-globals.lua new file mode 100644 index 0000000..295e670 --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/test/trace-globals.lua @@ -0,0 +1,38 @@ +-- trace assigments to global variables + +do + -- a tostring that quotes strings. note the use of the original tostring. + local _tostring=tostring + local tostring=function(a) + if type(a)=="string" then + return string.format("%q",a) + else + return _tostring(a) + end + end + + local log=function (name,old,new) + local t=debug.getinfo(3,"Sl") + local line=t.currentline + io.write(t.short_src) + if line>=0 then io.write(":",line) end + io.write(": ",name," is now ",tostring(new)," (was ",tostring(old),")","\n") + end + + local g={} + local set=function (t,name,value) + log(name,g[name],value) + g[name]=value + end + setmetatable(getfenv(),{__index=g,__newindex=set}) +end + +-- an example + +a=1 +b=2 +a=10 +b=20 +b=nil +b=200 +print(a,b,c) diff --git a/mod/pub.mod/lua.mod/lua-5.1.4/test/xd.lua b/mod/pub.mod/lua.mod/lua-5.1.4/test/xd.lua new file mode 100644 index 0000000..ebc3eff --- /dev/null +++ b/mod/pub.mod/lua.mod/lua-5.1.4/test/xd.lua @@ -0,0 +1,14 @@ +-- hex dump +-- usage: lua xd.lua < file + +local offset=0 +while true do + local s=io.read(16) + if s==nil then return end + io.write(string.format("%08X ",offset)) + string.gsub(s,"(.)", + function (c) io.write(string.format("%02X ",string.byte(c))) end) + io.write(string.rep(" ",3*(16-string.len(s)))) + io.write(" ",string.gsub(s,"%c","."),"\n") + offset=offset+16 +end diff --git a/mod/pub.mod/lua.mod/lua.bmx b/mod/pub.mod/lua.mod/lua.bmx new file mode 100644 index 0000000..31bf157 --- /dev/null +++ b/mod/pub.mod/lua.mod/lua.bmx @@ -0,0 +1,929 @@ +SuperStrict + +Rem +bbdoc: Lua Core +end rem +Module Pub.Lua + +ModuleInfo "Version: 1.27" +ModuleInfo "Author: Tecgraf,PUC-Rio" +ModuleInfo "License: MIT License" +ModuleInfo "Modserver: BRL" +ModuleInfo "Credit: Adapted for BlitzMax by Thomas Mayer, Noel Cower, Andreas Rozek and Simon Armstrong" + +ModuleInfo "History: 1.27" +ModuleInfo "History: Modified luaconf.h (line 14) to autodetect LUA_USE_LINUX and LUA_USE_MACOSX" +ModuleInfo "History: 1.26" +ModuleInfo "History: Removed BRL.Retro dependancy & replaced Left() with [..1]" +ModuleInfo "History: 1.25" +ModuleInfo "History: Updated to Lua 5.1.4 - Htbaa" +ModuleInfo "History: 1.24" +ModuleInfo "History: fixed int<->long discrepancies between Lua and BlitzMAX" +ModuleInfo "History: 1.23" +ModuleInfo "History: several bugfixes and extensions" +ModuleInfo "History: support for strings with embedded ~0 (and byte arrays)" +ModuleInfo "History: modifications for Lua 5.1.2" +ModuleInfo "History: source code is now 'superstrict'-compliant" +ModuleInfo "History: added some documentation" +ModuleInfo "History: 1.22" +ModuleInfo "History: added lots of definitions to support most of the official Lua 5.1.1 API" +ModuleInfo "History: 1.21" +ModuleInfo "History: removed luac.c from build list" +ModuleInfo "History: 1.20" +ModuleInfo "History: fixed missing paramters in lua_createtable definition" +ModuleInfo "History: 1.19" +ModuleInfo "History: updated with lua5.1.1 source" +ModuleInfo "History: 1.18" +ModuleInfo "History: added extra Imports and luaL_openlibs decl" +ModuleInfo "History: 1.17" +ModuleInfo "History: added luaL_loadstring fixed missing lua_dostring" +ModuleInfo "History: 1.16" +ModuleInfo "History: Added lua_newtable as a BMax function" +ModuleInfo "History: Changed extern'd lua_newtable to lua_createtable" +ModuleInfo "History: Added lua_load, lua_dostring and lua_dobuffer." +ModuleInfo "History: 1.15 Release" +ModuleInfo "History: New LUA 5.1 based build" +ModuleInfo "History: Modified constants and added new wrappers for 5.1 compatability" +ModuleInfo "History: 1.14 Release" +ModuleInfo "History: Added luaopen_debug and ldblib.c" +ModuleInfo "History: Replaced byte ptr with $z (CString) where a C string is expected" +ModuleInfo "History: 1.12 Release" +ModuleInfo "History: Removed lua.h import" + +Import "lua-5.1.4/src/lstate.c" +Import "lua-5.1.4/src/llex.c" +Import "lua-5.1.4/src/ltm.c" +Import "lua-5.1.4/src/lstring.c" +Import "lua-5.1.4/src/ltable.c" +Import "lua-5.1.4/src/lfunc.c" +Import "lua-5.1.4/src/ldo.c" +Import "lua-5.1.4/src/lgc.c" +Import "lua-5.1.4/src/lzio.c" +Import "lua-5.1.4/src/lobject.c" +Import "lua-5.1.4/src/lparser.c" +Import "lua-5.1.4/src/lvm.c" +Import "lua-5.1.4/src/lundump.c" +Import "lua-5.1.4/src/lmem.c" +Import "lua-5.1.4/src/lcode.c" +Import "lua-5.1.4/src/ldebug.c" +Import "lua-5.1.4/src/lopcodes.c" +Import "lua-5.1.4/src/lapi.c" +Import "lua-5.1.4/src/ldump.c" +Import "lua-5.1.4/src/lbaselib.c" +Import "lua-5.1.4/src/lauxlib.c" +Import "lua-5.1.4/src/liolib.c" +Import "lua-5.1.4/src/lmathlib.c" +Import "lua-5.1.4/src/lstrlib.c" +Import "lua-5.1.4/src/ltablib.c" +Import "lua-5.1.4/src/ldblib.c" + +Import "lua-5.1.4/src/linit.c" +Import "lua-5.1.4/src/loadlib.c" +Import "lua-5.1.4/src/loslib.c" +'import "lua-5.1.4/src/lua.c" +'Import "lua-5.1.4/src/luac.c" +Import "lua-5.1.4/src/print.c" + +' ****************************************************************************** +' * * +' * Constant Definitions * +' * * +' ****************************************************************************** + + Const LUA_IDSIZE:Int = 60 + +' **** (lua.h) some basic definitions - just to be complete **** + + Const LUA_VERSION:String = "Lua 5.1" + Const LUA_RELEASE:String = "Lua 5.1.4" + Const LUA_VERSION_NUM:Int = 501 + Const LUA_COPYRIGHT:String = "Copyright (C) 1994-2008 Lua.org, PUC-Rio" + Const LUA_AUTHORS:String = "R. Ierusalimschy, L. H. de Figueiredo & W. Celes" + +' **** (lua.h) option for multiple returns in `lua_pcall' and `lua_call' **** + + Const LUA_MULTRET:Int = -1 + +' **** (lua.h) pseudo-indices **** + + Const LUA_REGISTRYINDEX:Int = -10000 + Const LUA_ENVIRONINDEX:Int = -10001 + Const LUA_GLOBALSINDEX:Int = -10002 + +' **** (lua.h) thread status (0 is OK) **** + + Const LUA_YIELD_:Int = 1 ' added _ after LUA_YIELD because of lua_yield function + Const LUA_ERRRUN:Int = 2 + Const LUA_ERRSYNTAX:Int = 3 + Const LUA_ERRMEM:Int = 4 + Const LUA_ERRERR:Int = 5 + +' **** (lua.h) basic types **** + + Const LUA_TNONE:Int = -1 + Const LUA_TNIL:Int = 0 + Const LUA_TBOOLEAN:Int = 1 + Const LUA_TLIGHTUSERDATA:Int = 2 + Const LUA_TNUMBER:Int = 3 + Const LUA_TSTRING:Int = 4 + Const LUA_TTABLE:Int = 5 + Const LUA_TFUNCTION:Int = 6 + Const LUA_TUSERDATA:Int = 7 + Const LUA_TTHREAD:Int = 8 + +' **** (lua.h) garbage-collection options **** + + Const LUA_GCSTOP:Int = 0 + Const LUA_GCRESTART:Int = 1 + Const LUA_GCCOLLECT:Int = 2 + Const LUA_GCCOUNT:Int = 3 + Const LUA_GCCOUNTB:Int = 4 + Const LUA_GCSTEP:Int = 5 + Const LUA_GCSETPAUSE:Int = 6 + Const LUA_GCSETSTEPMUL:Int = 7 + +' **** (lua.h) event codes **** + + Const LUA_HOOKCALL:Int = 0 + Const LUA_HOOKRET:Int = 1 + Const LUA_HOOKLINE:Int = 2 + Const LUA_HOOKCOUNT:Int = 3 + Const LUA_HOOKTAILRET:Int = 4 + +' **** (lua.h) event masks **** + + Const LUA_MASKCALL:Int = (1 Shl LUA_HOOKCALL) + Const LUA_MASKRET:Int = (1 Shl LUA_HOOKRET) + Const LUA_MASKLINE:Int = (1 Shl LUA_HOOKLINE) + Const LUA_MASKCOUNT:Int = (1 Shl LUA_HOOKCOUNT) + +' ****************************************************************************** +' * * +' * The Lua API (Functions) * +' * * +' ****************************************************************************** + +Extern + Type lua_Debug + Field event:Int + Field name:Byte Ptr ' no ~0 expected + Field namewhat:Byte Ptr ' dto. + Field what:Byte Ptr ' dto. + Field source:Byte Ptr ' dto. + Field currentline:Int + Field nups:Int + Field linedefined:Int + Field lastlinedefined:Int +' field short_src:byte[LUA_IDSIZE] ' we use padding to occupy 60 bytes + Field short_src:Byte, short_src_01:Byte, short_src_02:Byte, short_src_03:Byte + Field short_src_04:Long, short_src_12:Long, short_src_20:Long + Field short_src_28:Long, short_src_36:Long, short_src_44:Long + Field short_src_52:Long + Field i_ci:Int ' "private" field - mentioned here to get the right size + End Type +End Extern + +Extern +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_atpanic:Byte Ptr (lua_state:Byte Ptr, panicf:Int(ls:Byte Ptr)) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_call (lua_state:Byte Ptr, nargs:Int, nresults:Int) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_checkstack:Int (lua_state:Byte Ptr, extra:Int) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_close (lua_state:Byte Ptr) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_concat (lua_state:Byte Ptr, n:Int) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_cpcall:Int (lua_state:Byte Ptr, func:Int(ls:Byte Ptr), ud:Byte Ptr) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_createtable (lua_state:Byte Ptr, narr:Int, nrec:Int) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_dump:Int (lua_state:Byte Ptr, writer:Int(ls:Byte Ptr,p:Byte Ptr,sz:Int,ud:Byte Ptr), data:Byte Ptr) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_equal:Int (lua_state:Byte Ptr, index1:Int, index2:Int) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_error:Int (lua_state:Byte Ptr) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_gc:Int (lua_state:Byte Ptr, what:Int, data:Int) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_getallocf:Byte Ptr (lua_state:Byte Ptr, ud:Byte Ptr Ptr) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_getfenv (lua_state:Byte Ptr, index:Int) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_getfield (lua_state:Byte Ptr, index:Int, k$z) ' no ~0 expected +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_gethook:Byte Ptr (lua_state:Byte Ptr) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_gethookcount:Int (lua_state:Byte Ptr) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_gethookmask:Int (lua_state:Byte Ptr) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_getinfo:Int (lua_state:Byte Ptr, what$z, ar:lua_Debug Ptr) ' no ~0 expected +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_getlocal$z (lua_state:Byte Ptr, ar:lua_Debug Ptr, n:Int) ' no ~0 expected +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_getmetatable:Int (lua_state:Byte Ptr, index:Int) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_getstack:Int (lua_state:Byte Ptr, level:Int, ar:lua_Debug Ptr) ' no ~0 expected +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_gettable (lua_state:Byte Ptr, index:Int) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_gettop:Int (lua_state:Byte Ptr) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_getupvalue$z (lua_state:Byte Ptr, funcindex:Int, n:Int) ' no ~0 expected +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_insert (lua_state:Byte Ptr, index:Int) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_iscfunction:Int (lua_state:Byte Ptr, index:Int) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_isnumber:Int (lua_state:Byte Ptr, index:Int) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_isstring:Int (lua_state:Byte Ptr, index:Int) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_isuserdata:Int (lua_state:Byte Ptr, index:Int) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_lessthan:Int (lua_state:Byte Ptr, index1:Int, index2:Int) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_load:Int (lua_state:Byte Ptr, reader:Byte Ptr(ls:Byte Ptr,data:Byte Ptr,sz:Int Ptr), data:Byte Ptr, chunkname$z) ' no ~0 expected +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_newstate:Byte Ptr (f:Byte Ptr(ud:Byte Ptr, p:Byte Ptr, osize:Int, nsize:Int), ud:Byte Ptr) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_newthread:Byte Ptr (lua_state:Byte Ptr) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_newuserdata:Byte Ptr (lua_state:Byte Ptr, size:Int) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_next:Int (lua_state:Byte Ptr, index:Int) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_objlen:Int (lua_state:Byte Ptr, index:Int) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_pcall:Int (lua_state:Byte Ptr, nargs:Int, nresults:Int, errfunc:Int) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_pushboolean (lua_state:Byte Ptr, b:Int) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_pushcclosure (lua_state:Byte Ptr, fn:Int(ls:Byte Ptr), n:Int) +' function lua_pushfstring$z (lua_state:byte ptr, fmt$z, ...) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_pushinteger (lua_state:Byte Ptr, n:Int) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_pushlightuserdata (lua_state:Byte Ptr, p:Byte Ptr) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_pushlstring (lua_state:Byte Ptr, s:Byte Ptr, size:Int) ' without any conversion! +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_pushnil (lua_state:Byte Ptr) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_pushnumber (lua_state:Byte Ptr, n:Double) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_pushstring (lua_state:Byte Ptr, s$z) ' no ~0 expected +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_pushthread:Int (lua_state:Byte Ptr) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_pushvalue (lua_state:Byte Ptr, index:Int) +' function lua_pushvfstring$z (lua_state:byte ptr, fmt$z, argp:???) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_rawequal:Int (lua_state:Byte Ptr, index1:Int, index2:Int) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_rawget (lua_state:Byte Ptr, index:Int) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_rawgeti (lua_state:Byte Ptr, index:Int, n:Int) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_rawset (lua_state:Byte Ptr, index:Int) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_rawseti (lua_state:Byte Ptr, index:Int, n:Int) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_remove (lua_state:Byte Ptr, index:Int) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_replace (lua_state:Byte Ptr, index:Int) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_resume:Int (lua_state:Byte Ptr, narg:Int) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_setallocf (lua_state:Byte Ptr, f:Byte Ptr(ud:Byte Ptr, p:Byte Ptr, osize:Int, nsize:Int), ud:Byte Ptr) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_setfenv:Int (lua_state:Byte Ptr, index:Int) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_setfield (lua_state:Byte Ptr, index:Int, k$z) ' no ~0 expected +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_sethook:Int (lua_state:Byte Ptr, f(ls:Byte Ptr,ar:lua_Debug Ptr), mask:Int, count:Int) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_setlocal$z (lua_state:Byte Ptr, ar:lua_Debug Ptr, n:Int) ' no ~0 expected +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_setmetatable:Int (lua_state:Byte Ptr, index:Int) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_settable (lua_state:Byte Ptr, index:Int) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_settop (lua_state:Byte Ptr, index:Int) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_setupvalue$z (lua_state:Byte Ptr, funcindex:Int, n:Int) ' no ~0 expected +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_status:Int (lua_state:Byte Ptr) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_toboolean:Int (lua_state:Byte Ptr, index:Int) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_tocfunction:Byte Ptr (lua_state:Byte Ptr, index:Int) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_tointeger:Int (lua_state:Byte Ptr, index:Int) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_tolstring:Byte Ptr (lua_state:Byte Ptr, index:Int, size:Int Ptr) ' without any conversion! +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_tonumber:Double (lua_state:Byte Ptr, index:Int) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_topointer:Byte Ptr (lua_state:Byte Ptr, index:Int) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_tothread:Byte Ptr (lua_state:Byte Ptr, index:Int) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_touserdata:Byte Ptr (lua_state:Byte Ptr, index:Int) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_type:Int (lua_state:Byte Ptr, index:Int) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_typename$z (lua_state:Byte Ptr, tp:Int) ' no ~0 expected +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_xmove (fromState:Byte Ptr, toState:Byte Ptr, n:Int) +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_yield:Int (lua_state:Byte Ptr, nresults:Int) +End Extern + +' ****************************************************************************** +' * * +' * The Lua API (Macros) * +' * * +' ****************************************************************************** + +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_getglobal (lua_state:Byte Ptr, name:String) + lua_getfield(lua_state, LUA_GLOBALSINDEX, name) + End Function + +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_isboolean:Int (lua_state:Byte Ptr, index:Int) + Return (lua_type(lua_state,index) = LUA_TBOOLEAN) + End Function + +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_isfunction:Int (lua_state:Byte Ptr, index:Int) + Return (lua_type(lua_state,index) = LUA_TFUNCTION) + End Function + +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_islightuserdata:Int (lua_state:Byte Ptr, index:Int) + Return (lua_type(lua_state,index) = LUA_TLIGHTUSERDATA) + End Function + +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_isnil:Int (lua_state:Byte Ptr, index:Int) + Return (lua_type(lua_state,index) = LUA_TNIL) + End Function + +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_isnone:Int (lua_state:Byte Ptr, index:Int) + Return (lua_type(lua_state,index) = LUA_TNONE) + End Function + +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_isnoneornil:Int (lua_state:Byte Ptr, index:Int) + Return (lua_type(lua_state,index) <= 0) + End Function + +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_istable:Int (lua_state:Byte Ptr, index:Int) + Return (lua_type(lua_state,index) = LUA_TTABLE) + End Function + +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_isthread:Int (lua_state:Byte Ptr, index:Int) + Return (lua_type(lua_state,index) = LUA_TTHREAD) + End Function + +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_newtable (lua_state:Byte Ptr) + lua_createtable(lua_state,0,0) + End Function + +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_pop (lua_state:Byte Ptr, n:Int) + lua_settop(lua_state,-(n)-1) + End Function + + Function lua_pushbytearray (lua_state:Byte Ptr, Buffer:Byte[]) + lua_pushlstring(lua_state, Varptr Buffer[0], Buffer.length) + End Function + +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_pushcfunction (lua_state:Byte Ptr, fn:Int(ls:Byte Ptr)) + lua_pushcclosure(lua_state, fn, 0) + End Function + +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_register (lua_state:Byte Ptr, name:String, f:Int(ls:Byte Ptr)) + lua_pushcfunction(lua_state, f) + lua_setglobal (lua_state, name) + End Function + +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_setglobal (lua_state:Byte Ptr, name:String) + lua_setfield(lua_state, LUA_GLOBALSINDEX, name) + End Function + + Function lua_tobytearray:Byte[] (lua_state:Byte Ptr, index:Int) + Local Length:Int + Local DataPtr:Byte Ptr = lua_tolstring(lua_state, index, Varptr Length) + If (DataPtr = Null) Then + Return Null + Else + Local Result:Byte[] = New Byte[Length] + MemCopy(Varptr Result[0], DataPtr, Length); + Return Result + End If + End Function + +Rem +bbdoc: see Lua Reference Manual +end rem + Function lua_tostring:String (lua_state:Byte Ptr, index:Int) + Local Length:Int + Local StringPtr:Byte Ptr = lua_tolstring(lua_state, index, Varptr Length) + If (StringPtr = Null) Then + Return Null + Else + Return String.fromBytes(StringPtr,Length) + End If + End Function + +' ****************************************************************************** +' * * +' * The Auxiliary Library (Functions) * +' * * +' ****************************************************************************** + +Extern + Type lua_Reg + Field name:Byte Ptr ' no ~0 expected + Field func:Int(ls:Byte Ptr) + End Type +End Extern + +Extern +Rem +bbdoc: see Lua Reference Manual +end rem + Function luaL_addlstring (B:Byte Ptr, s:Byte Ptr, l:Int) +Rem +bbdoc: see Lua Reference Manual +end rem + Function luaL_addsize (B:Byte Ptr, size:Int) +Rem +bbdoc: see Lua Reference Manual +end rem + Function luaL_addstring (B:Byte Ptr, s$z) ' no ~0 allowed! +Rem +bbdoc: see Lua Reference Manual +end rem + Function luaL_addvalue (B:Byte Ptr) +Rem +bbdoc: see Lua Reference Manual +end rem + Function luaL_argerror:Int (lua_state:Byte Ptr, narg:Int, extramsg$z) ' no ~0 expected +Rem +bbdoc: see Lua Reference Manual +end rem + Function luaL_buffinit (lua_state:Byte Ptr, B:Byte Ptr) +Rem +bbdoc: see Lua Reference Manual +end rem + Function luaL_callmeta:Int (lua_state:Byte Ptr, obj:Int, e$z) ' no ~0 expected +Rem +bbdoc: see Lua Reference Manual +end rem + Function luaL_checkany (lua_state:Byte Ptr, narg:Int) +Rem +bbdoc: see Lua Reference Manual +end rem + Function luaL_checkinteger:Int (lua_state:Byte Ptr, narg:Int) +Rem +bbdoc: see Lua Reference Manual +end rem + Function luaL_checklstring:Byte Ptr (lua_state:Byte Ptr, narg:Int, size:Int Ptr) +Rem +bbdoc: see Lua Reference Manual +end rem + Function luaL_checknumber:Double (lua_state:Byte Ptr, narg:Int) +' function luaL_checkoption:int (lua_state:byte ptr, narg:int, def$z, lst$z[]) +Rem +bbdoc: see Lua Reference Manual +end rem + Function luaL_checkstack (lua_state:Byte Ptr, sz:Int, msg$z) ' no ~0 expected +Rem +bbdoc: see Lua Reference Manual +end rem + Function luaL_checktype (lua_state:Byte Ptr, narg:Int, t:Int) +Rem +bbdoc: see Lua Reference Manual +end rem + Function luaL_checkudata:Byte Ptr (lua_state:Byte Ptr, narg:Int, tname$z) ' no ~0 expected +' function luaL_error:int (lua_state:byte ptr, fmt$z, ...) +Rem +bbdoc: see Lua Reference Manual +end rem + Function luaL_getmetafield:Int (lua_state:Byte Ptr, obj:Int, e$z) ' no ~0 expected +Rem +bbdoc: see Lua Reference Manual +end rem + Function luaL_gsub$z (lua_state:Byte Ptr, s$z, p$z, r$z) ' no ~0 expected +Rem +bbdoc: see Lua Reference Manual +end rem + Function luaL_loadbuffer:Int (lua_state:Byte Ptr, buff:Byte Ptr, sz:Int, name$z) ' no ~0 expected +Rem +bbdoc: see Lua Reference Manual +end rem + Function luaL_loadfile:Int (lua_state:Byte Ptr, filename$z) ' no ~0 expected +Rem +bbdoc: see Lua Reference Manual +end rem + Function luaL_loadstring:Int (lua_state:Byte Ptr, s$z) ' no ~0 allowed! +Rem +bbdoc: see Lua Reference Manual +end rem + Function luaL_newmetatable:Int (lua_state:Byte Ptr, tname$z) ' no ~0 expected +Rem +bbdoc: see Lua Reference Manual +end rem + Function luaL_newstate:Byte Ptr () +Rem +bbdoc: see Lua Reference Manual +end rem + Function luaL_openlibs (lua_state:Byte Ptr) +Rem +bbdoc: see Lua Reference Manual +end rem + Function luaL_optinteger:Int (lua_state:Byte Ptr, narg:Int, d:Int) +Rem +bbdoc: see Lua Reference Manual +end rem + Function luaL_optlstring:Byte Ptr (lua_state:Byte Ptr, narg:Int, d$z, size:Int Ptr) ' no ~0 expected in "d" +Rem +bbdoc: see Lua Reference Manual +end rem + Function luaL_optnumber:Double (lua_state:Byte Ptr, narg:Int, d:Double) +Rem +bbdoc: see Lua Reference Manual +end rem + Function luaL_prepbuffer:Byte Ptr (B:Byte Ptr) +Rem +bbdoc: see Lua Reference Manual +end rem + Function luaL_pushresult (B:Byte Ptr) +Rem +bbdoc: see Lua Reference Manual +end rem + Function luaL_ref:Int (lua_state:Byte Ptr, t:Int) +Rem +bbdoc: see Lua Reference Manual +end rem + Function luaL_register (lua_state:Byte Ptr, libname$z, l:lua_Reg Ptr) ' no ~0 expected +Rem +bbdoc: see Lua Reference Manual +end rem + Function luaL_typerror:Int (lua_state:Byte Ptr, narg:Int, tname$z) ' no ~0 expected +Rem +bbdoc: see Lua Reference Manual +end rem + Function luaL_unref (lua_state:Byte Ptr, t:Int, ref:Int) +Rem +bbdoc: see Lua Reference Manual +end rem + Function luaL_where (lua_state:Byte Ptr, lvl:Int) +End Extern + +' ****************************************************************************** +' * * +' * The Auxiliary Library (Macros) * +' * * +' ****************************************************************************** + +Rem +bbdoc: see Lua Reference Manual +end rem + Function luaL_addchar (B:Byte Ptr, c:String) +' luaL_addstring(B,Left$(c,1)) ' not really efficient, just to be complete + luaL_addstring( B,c[..Min(c.Length,1)] ) 'functionally equivalent? + End Function + +Rem +bbdoc: see Lua Reference Manual +end rem + Function luaL_argcheck (lua_state:Byte Ptr, cond:Int, narg:Int, extramsg:String) + If (Not cond) Then luaL_argerror(lua_state, narg, extramsg) + End Function + +Rem +bbdoc: see Lua Reference Manual +end rem + Function luaL_checkint:Int (lua_state:Byte Ptr, narg:Int) + Return Int(luaL_checkinteger(lua_state, narg)) ' Lua itself does the same! + End Function + +Rem +bbdoc: see Lua Reference Manual +end rem + Function luaL_checklong:Long (lua_state:Byte Ptr, narg:Int) + Return luaL_checkinteger(lua_state, narg) + End Function + +Rem +bbdoc: see Lua Reference Manual +end rem + Function luaL_checkstring:String (lua_state:Byte Ptr, narg:Int) + Local Size:Int + Local StringPtr:Byte Ptr = luaL_checklstring(lua_state, narg, Varptr Size) + If (StringPtr = Null) Then + Return Null + Else + Return String.fromBytes(StringPtr,Size) + End If + End Function + +Rem +bbdoc: see Lua Reference Manual +end rem + Function luaL_dofile:Int (lua_state:Byte Ptr, filename:String) + If (luaL_loadfile(lua_state,filename) <> 0) Then + Return 1 + Else + Return lua_pcall(lua_state, 0, LUA_MULTRET, 0) + End If + End Function + +Rem +bbdoc: see Lua Reference Manual +end rem + Function luaL_dostring:Int (lua_state:Byte Ptr, str:String) + If (luaL_loadstring(lua_state,str) <> 0) Then + Return 1 + Else + Return lua_pcall(lua_state, 0, LUA_MULTRET, 0) + End If + End Function + +Rem +bbdoc: see Lua Reference Manual +end rem + Function luaL_getmetatable (lua_state:Byte Ptr, tname:String) + lua_getfield(lua_state, LUA_REGISTRYINDEX, tname) + End Function + +Rem +bbdoc: see Lua Reference Manual +end rem + Function luaL_optint:Int (lua_state:Byte Ptr, narg:Int, d:Int) + Return luaL_optinteger(lua_state, narg, d) + End Function + +Rem +bbdoc: see Lua Reference Manual +end rem + Function luaL_optlong:Long (lua_state:Byte Ptr, narg:Int, d:Long) + If ((Abs(narg) > lua_gettop(lua_state)) Or lua_isnil(lua_state,narg)) Then + Return d + Else + Return luaL_checklong(lua_state,narg) + End If + End Function + +Rem +bbdoc: see Lua Reference Manual +end rem + Function luaL_optstring:String (lua_state:Byte Ptr, narg:Int, d:String) + Local Size:Int + Local StringPtr:Byte Ptr = luaL_optlstring(lua_state, narg, d, Varptr Size) + If (StringPtr = Null) Then + Return Null + Else + Return String.fromBytes(StringPtr,Size) + End If + End Function + +Rem +bbdoc: see Lua Reference Manual +end rem + Function luaL_typename:String (lua_state:Byte Ptr, idx:Int) + Return lua_typename(lua_state, lua_type (lua_state,idx)) + End Function + +' ****************************************************************************** +' * * +' * compatibility extensions (not to break existing axe.lua programs) * +' * * +' ****************************************************************************** + +Extern + Function luaopen_base:Int (lua_state:Byte Ptr) + Function luaopen_debug:Int (lua_state:Byte Ptr) + Function luaopen_io:Int (lua_state:Byte Ptr) + Function luaopen_math:Int (lua_state:Byte Ptr) + Function luaopen_os:Int (lua_state:Byte Ptr) + Function luaopen_package:Int (lua_state:Byte Ptr) + Function luaopen_string:Int (lua_state:Byte Ptr) + Function luaopen_table:Int (lua_state:Byte Ptr) +End Extern + + Function lua_dobuffer:Int (lua_state:Byte Ptr, buff:String, sz:Int, name:String) + If (luaL_loadbuffer(lua_state,buff,sz,name) <> 0) Then + Return 1 + Else + Return lua_pcall(lua_state, 0, LUA_MULTRET, 0) + End If + End Function + + Function lua_dofile:Int (lua_state:Byte Ptr, filename:String) + Return luaL_dofile(lua_state,filename) + End Function + + Function lua_dostring:Int (lua_state:Byte Ptr, str:String) + Return luaL_dostring(lua_state,str) + End Function + + Function lua_strlen:Int (lua_state:Byte Ptr, index:Int) + Return lua_objlen(lua_state,index) + End Function diff --git a/mod/pub.mod/macos.mod/macos.bmx b/mod/pub.mod/macos.mod/macos.bmx new file mode 100644 index 0000000..c372797 --- /dev/null +++ b/mod/pub.mod/macos.mod/macos.bmx @@ -0,0 +1,31 @@ + +Strict + +Module Pub.MacOS + +ModuleInfo "Version: 1.01" +ModuleInfo "Author: Mark Sibly" +ModuleInfo "License: zlib/libpng" +ModuleInfo "Copyright: Blitz Research Ltd" +ModuleInfo "ModServer: BRL" + +ModuleInfo "History: 1.01 Release" + +?MacOS +Import "macos.m" + +Extern + +Function is_pid_native( pid ) +Function Gestalt( tag,result Var ) +Function bbStringFromNSString$( ns_string ) +Function NSStringFromBBString( bb_string$ ) + +End Extern +? + + + + + + diff --git a/mod/pub.mod/macos.mod/macos.h b/mod/pub.mod/macos.mod/macos.h new file mode 100644 index 0000000..06577cb --- /dev/null +++ b/mod/pub.mod/macos.mod/macos.h @@ -0,0 +1,19 @@ + +#ifndef PUB_MACOS_MACOS_H +#define PUB_MACOS_MACOS_H + +#include +#include + +#include +#include +#include +#include + +int is_pid_native( pid_t pid ); + +BBString *bbStringFromNSString( NSString *s ); + +NSString *NSStringFromBBString( BBString *s ); + +#endif diff --git a/mod/pub.mod/macos.mod/macos.m b/mod/pub.mod/macos.mod/macos.m new file mode 100644 index 0000000..2913b80 --- /dev/null +++ b/mod/pub.mod/macos.mod/macos.m @@ -0,0 +1,59 @@ + +//pinched from ADC - no idea how it works! + +#include "macos.h" + +static int sysctlbyname_with_pid (const char *name, pid_t pid, + void *oldp, size_t *oldlenp, + void *newp, size_t newlen) +{ + if (pid == 0) { + if (sysctlbyname(name, oldp, oldlenp, newp, newlen) == -1) { + return -1; + } + }else{ + int mib[CTL_MAXNAME]; + size_t len = CTL_MAXNAME; + if (sysctlnametomib(name, mib, &len) == -1) { + return -1; + } + mib[len] = pid; + len++; + if (sysctl(mib, len, oldp, oldlenp, newp, newlen) == -1) { + return -1; + } + } + return 0; +} + +int is_pid_native( pid_t pid ) +{ + int ret = 0; + size_t sz = sizeof(ret); + + if (sysctlbyname_with_pid("sysctl.proc_native", pid, &ret, &sz, NULL, 0) == -1) { + if (errno == ENOENT) { + // sysctl doesn't exist, which means that this version of Mac OS + // pre-dates Rosetta, so the application must be native. + return 1; + } + return -1; + } + return ret; +} + +BBString *bbStringFromNSString( NSString *s ){ + BBString *bbstring; + unsigned short *buff; + int n; + n=[s length]; + buff=malloc( n*2 ); + [s getCharacters:buff]; + bbstring=bbStringFromShorts( buff,n ); + free( buff ); + return bbstring; +} + +NSString *NSStringFromBBString( BBString *s ){ + return [NSString stringWithCharacters:s->buf length:s->length]; +} diff --git a/mod/pub.mod/oggvorbis.mod/libogg-1.1.3/AUTHORS b/mod/pub.mod/oggvorbis.mod/libogg-1.1.3/AUTHORS new file mode 100644 index 0000000..80c787c --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libogg-1.1.3/AUTHORS @@ -0,0 +1,4 @@ +Monty + +and the rest of the Xiph.Org Foundation. + diff --git a/mod/pub.mod/oggvorbis.mod/libogg-1.1.3/CHANGES b/mod/pub.mod/oggvorbis.mod/libogg-1.1.3/CHANGES new file mode 100644 index 0000000..cab24c3 --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libogg-1.1.3/CHANGES @@ -0,0 +1,33 @@ +Version 1.1.3 (2005 November 27) + + * Correct a bug in the granulepos field of pages where no packet ends + * New VS2003 and XCode builds, minor fixes to other builds + * documentation fixes and cleanup + +Version 1.1.2 (2004 September 23) + + * fix a bug with multipage packet assembly after seek + +Version 1.1.1 (2004 September 12) + + * various bugfixes + * important bugfix for 64-bit platforms + * various portability fixes + * autotools cleanup from Thomas Vander Stichele + * Symbian OS build support from Colin Ward at CSIRO + * new multiplexed Ogg stream documentation + +Version 1.1 (2003 November 17) + + * big-endian bitpacker routines for Theora + * various portability fixes + * improved API documenation + * RFC 3533 documentation of the format by Silvia Pfeiffer at CSIRO + * RFC 3534 documentation of the application/ogg mime-type by Linus Walleij + +Version 1.0 (2002 July 19) + + * First stable release + * little-endian bitpacker routines for Vorbis + * basic Ogg bitstream sync and coding support + diff --git a/mod/pub.mod/oggvorbis.mod/libogg-1.1.3/COPYING b/mod/pub.mod/oggvorbis.mod/libogg-1.1.3/COPYING new file mode 100644 index 0000000..6111c6c --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libogg-1.1.3/COPYING @@ -0,0 +1,28 @@ +Copyright (c) 2002, Xiph.org Foundation + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +- Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +- Neither the name of the Xiph.org Foundation nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/mod/pub.mod/oggvorbis.mod/libogg-1.1.3/README b/mod/pub.mod/oggvorbis.mod/libogg-1.1.3/README new file mode 100644 index 0000000..b36195e --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libogg-1.1.3/README @@ -0,0 +1,103 @@ +******************************************************************** +* * +* THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * +* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * +* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * +* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * +* * +* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * +* by the Xiph.Org Foundation http://www.xiph.org/ * +* * +******************************************************************** + +WHAT'S HERE: + +This source distribution includes libogg and nothing else. Other modules +(eg, the modules vorbis, vorbis-tools and vorbis-plugins for the Vorbis +codec) contain the codec libraries for use with Ogg bitstreams. + +Directory: + +./src The source for libogg, a BSD-license inplementation of + the public domain Ogg bitstream format + +./include Library API headers and codebooks + +./debian Rules/spec files for building Debian .deb packages + +./doc Ogg specification documents + +./win32 Win32 projects and build automation + +./mac MacOS 9 projects and build automation + +WHAT IS OGG?: + +Ogg project codecs use the Ogg bitstream format to arrange the raw, +compressed bitstream into a more robust, useful form. For example, +the Ogg bitstream makes seeking, time stamping and error recovery +possible, as well as mixing several sepearate, concurrent media +streams into a single physical bitstream. + +CONTACT: + +The Ogg homepage is located at 'http://www.xiph.org/ogg/'. +Up to date technical documents, contact information, source code and +pre-built utilities may be found there. + +BUILDING FROM REPOSITORY SOURCE: + +A standard svn build should consist of nothing more than: + +./autogen.sh +make + +and as root if desired : + +make install + +This will install the Ogg libraries (static and shared) into +/usr/local/lib, includes into /usr/local/include and API manpages +(once we write some) into /usr/local/man. + +BUILDING FROM TARBALL DISTRIBUTIONS: + +./configure +make + +and optionally (as root): +make install + +BUILDING RPMS: + +RPMs may be built by: + +make dist +rpm -ta libogg-.tar.gz + +BUILDING ON WIN32: + +Use the project file in the win32 directory. It should compile out of the box. +You can also run one of the batch files from the commandline. + +E.g.: build_ogg_dynamic + +BUILDING ON MACOS 9: + +Ogg on MacOS 9 is built using CodeWarrior 5.3. To build it, first +open ogg/mac/libogg.mcp, switch to the "Targets" pane, select +everything, and make the project. In ogg/mac/Output you will now have +both debug and final versions of Ogg shared libraries to link your +projects against. + +To build a project using Ogg, add access paths to your CodeWarrior +project for the ogg/include and ogg/mac/Output folders. Be sure that +"interpret DOS and Unix paths" is turned on in your project; it can be +found in the "access paths" pane in your project settings. Now simply +add the shared libraries you need to your project (OggLib at least) +and #include "ogg/ogg.h" wherever you need to acces Ogg functionality. + +(Build instructions for Ogg codecs such as vorbis are similar and may +be found in those source modules' README files) + +$Id: README 10478 2005-11-28 04:23:35Z giles $ diff --git a/mod/pub.mod/oggvorbis.mod/libogg-1.1.3/include/ogg/ogg.h b/mod/pub.mod/oggvorbis.mod/libogg-1.1.3/include/ogg/ogg.h new file mode 100644 index 0000000..9082679 --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libogg-1.1.3/include/ogg/ogg.h @@ -0,0 +1,202 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the Xiph.Org Foundation http://www.xiph.org/ * + * * + ******************************************************************** + + function: toplevel libogg include + last mod: $Id: ogg.h 7188 2004-07-20 07:26:04Z xiphmont $ + + ********************************************************************/ +#ifndef _OGG_H +#define _OGG_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +typedef struct { + long endbyte; + int endbit; + + unsigned char *buffer; + unsigned char *ptr; + long storage; +} oggpack_buffer; + +/* ogg_page is used to encapsulate the data in one Ogg bitstream page *****/ + +typedef struct { + unsigned char *header; + long header_len; + unsigned char *body; + long body_len; +} ogg_page; + +/* ogg_stream_state contains the current encode/decode state of a logical + Ogg bitstream **********************************************************/ + +typedef struct { + unsigned char *body_data; /* bytes from packet bodies */ + long body_storage; /* storage elements allocated */ + long body_fill; /* elements stored; fill mark */ + long body_returned; /* elements of fill returned */ + + + int *lacing_vals; /* The values that will go to the segment table */ + ogg_int64_t *granule_vals; /* granulepos values for headers. Not compact + this way, but it is simple coupled to the + lacing fifo */ + long lacing_storage; + long lacing_fill; + long lacing_packet; + long lacing_returned; + + unsigned char header[282]; /* working space for header encode */ + int header_fill; + + int e_o_s; /* set when we have buffered the last packet in the + logical bitstream */ + int b_o_s; /* set after we've written the initial page + of a logical bitstream */ + long serialno; + long pageno; + ogg_int64_t packetno; /* sequence number for decode; the framing + knows where there's a hole in the data, + but we need coupling so that the codec + (which is in a seperate abstraction + layer) also knows about the gap */ + ogg_int64_t granulepos; + +} ogg_stream_state; + +/* ogg_packet is used to encapsulate the data and metadata belonging + to a single raw Ogg/Vorbis packet *************************************/ + +typedef struct { + unsigned char *packet; + long bytes; + long b_o_s; + long e_o_s; + + ogg_int64_t granulepos; + + ogg_int64_t packetno; /* sequence number for decode; the framing + knows where there's a hole in the data, + but we need coupling so that the codec + (which is in a seperate abstraction + layer) also knows about the gap */ +} ogg_packet; + +typedef struct { + unsigned char *data; + int storage; + int fill; + int returned; + + int unsynced; + int headerbytes; + int bodybytes; +} ogg_sync_state; + +/* Ogg BITSTREAM PRIMITIVES: bitstream ************************/ + +extern void oggpack_writeinit(oggpack_buffer *b); +extern void oggpack_writetrunc(oggpack_buffer *b,long bits); +extern void oggpack_writealign(oggpack_buffer *b); +extern void oggpack_writecopy(oggpack_buffer *b,void *source,long bits); +extern void oggpack_reset(oggpack_buffer *b); +extern void oggpack_writeclear(oggpack_buffer *b); +extern void oggpack_readinit(oggpack_buffer *b,unsigned char *buf,int bytes); +extern void oggpack_write(oggpack_buffer *b,unsigned long value,int bits); +extern long oggpack_look(oggpack_buffer *b,int bits); +extern long oggpack_look1(oggpack_buffer *b); +extern void oggpack_adv(oggpack_buffer *b,int bits); +extern void oggpack_adv1(oggpack_buffer *b); +extern long oggpack_read(oggpack_buffer *b,int bits); +extern long oggpack_read1(oggpack_buffer *b); +extern long oggpack_bytes(oggpack_buffer *b); +extern long oggpack_bits(oggpack_buffer *b); +extern unsigned char *oggpack_get_buffer(oggpack_buffer *b); + +extern void oggpackB_writeinit(oggpack_buffer *b); +extern void oggpackB_writetrunc(oggpack_buffer *b,long bits); +extern void oggpackB_writealign(oggpack_buffer *b); +extern void oggpackB_writecopy(oggpack_buffer *b,void *source,long bits); +extern void oggpackB_reset(oggpack_buffer *b); +extern void oggpackB_writeclear(oggpack_buffer *b); +extern void oggpackB_readinit(oggpack_buffer *b,unsigned char *buf,int bytes); +extern void oggpackB_write(oggpack_buffer *b,unsigned long value,int bits); +extern long oggpackB_look(oggpack_buffer *b,int bits); +extern long oggpackB_look1(oggpack_buffer *b); +extern void oggpackB_adv(oggpack_buffer *b,int bits); +extern void oggpackB_adv1(oggpack_buffer *b); +extern long oggpackB_read(oggpack_buffer *b,int bits); +extern long oggpackB_read1(oggpack_buffer *b); +extern long oggpackB_bytes(oggpack_buffer *b); +extern long oggpackB_bits(oggpack_buffer *b); +extern unsigned char *oggpackB_get_buffer(oggpack_buffer *b); + +/* Ogg BITSTREAM PRIMITIVES: encoding **************************/ + +extern int ogg_stream_packetin(ogg_stream_state *os, ogg_packet *op); +extern int ogg_stream_pageout(ogg_stream_state *os, ogg_page *og); +extern int ogg_stream_flush(ogg_stream_state *os, ogg_page *og); + +/* Ogg BITSTREAM PRIMITIVES: decoding **************************/ + +extern int ogg_sync_init(ogg_sync_state *oy); +extern int ogg_sync_clear(ogg_sync_state *oy); +extern int ogg_sync_reset(ogg_sync_state *oy); +extern int ogg_sync_destroy(ogg_sync_state *oy); + +extern char *ogg_sync_buffer(ogg_sync_state *oy, long size); +extern int ogg_sync_wrote(ogg_sync_state *oy, long bytes); +extern long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og); +extern int ogg_sync_pageout(ogg_sync_state *oy, ogg_page *og); +extern int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og); +extern int ogg_stream_packetout(ogg_stream_state *os,ogg_packet *op); +extern int ogg_stream_packetpeek(ogg_stream_state *os,ogg_packet *op); + +/* Ogg BITSTREAM PRIMITIVES: general ***************************/ + +extern int ogg_stream_init(ogg_stream_state *os,int serialno); +extern int ogg_stream_clear(ogg_stream_state *os); +extern int ogg_stream_reset(ogg_stream_state *os); +extern int ogg_stream_reset_serialno(ogg_stream_state *os,int serialno); +extern int ogg_stream_destroy(ogg_stream_state *os); +extern int ogg_stream_eos(ogg_stream_state *os); + +extern void ogg_page_checksum_set(ogg_page *og); + +extern int ogg_page_version(ogg_page *og); +extern int ogg_page_continued(ogg_page *og); +extern int ogg_page_bos(ogg_page *og); +extern int ogg_page_eos(ogg_page *og); +extern ogg_int64_t ogg_page_granulepos(ogg_page *og); +extern int ogg_page_serialno(ogg_page *og); +extern long ogg_page_pageno(ogg_page *og); +extern int ogg_page_packets(ogg_page *og); + +extern void ogg_packet_clear(ogg_packet *op); + + +#ifdef __cplusplus +} +#endif + +#endif /* _OGG_H */ + + + + + + diff --git a/mod/pub.mod/oggvorbis.mod/libogg-1.1.3/include/ogg/os_types.h b/mod/pub.mod/oggvorbis.mod/libogg-1.1.3/include/ogg/os_types.h new file mode 100644 index 0000000..d6778c7 --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libogg-1.1.3/include/ogg/os_types.h @@ -0,0 +1,136 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the Xiph.Org Foundation http://www.xiph.org/ * + * * + ******************************************************************** + + function: #ifdef jail to whip a few platforms into the UNIX ideal. + last mod: $Id: os_types.h 7524 2004-08-11 04:20:36Z conrad $ + + ********************************************************************/ +#ifndef _OS_TYPES_H +#define _OS_TYPES_H + +/* make it easy on the folks that want to compile the libs with a + different malloc than stdlib */ +#define _ogg_malloc malloc +#define _ogg_calloc calloc +#define _ogg_realloc realloc +#define _ogg_free free + +#if defined(_WIN32) + +# if defined(__CYGWIN__) +# include <_G_config.h> + typedef _G_int64_t ogg_int64_t; + typedef _G_int32_t ogg_int32_t; + typedef _G_uint32_t ogg_uint32_t; + typedef _G_int16_t ogg_int16_t; + typedef _G_uint16_t ogg_uint16_t; +# elif defined(__MINGW32__) + typedef short ogg_int16_t; + typedef unsigned short ogg_uint16_t; + typedef int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef long long ogg_int64_t; + typedef unsigned long long ogg_uint64_t; +# elif defined(__MWERKS__) + typedef long long ogg_int64_t; + typedef int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef short ogg_int16_t; + typedef unsigned short ogg_uint16_t; +# else + /* MSVC/Borland */ + typedef __int64 ogg_int64_t; + typedef __int32 ogg_int32_t; + typedef unsigned __int32 ogg_uint32_t; + typedef __int16 ogg_int16_t; + typedef unsigned __int16 ogg_uint16_t; +# endif + +#elif defined(__MACOS__) + +# include + typedef SInt16 ogg_int16_t; + typedef UInt16 ogg_uint16_t; + typedef SInt32 ogg_int32_t; + typedef UInt32 ogg_uint32_t; + typedef SInt64 ogg_int64_t; + +#elif defined(__APPLE__) /* MacOS X Framework build */ + +# include + typedef int16_t ogg_int16_t; + typedef u_int16_t ogg_uint16_t; + typedef int32_t ogg_int32_t; + typedef u_int32_t ogg_uint32_t; + typedef int64_t ogg_int64_t; + +#elif defined(__BEOS__) + + /* Be */ +# include + typedef int16_t ogg_int16_t; + typedef u_int16_t ogg_uint16_t; + typedef int32_t ogg_int32_t; + typedef u_int32_t ogg_uint32_t; + typedef int64_t ogg_int64_t; + +#elif defined (__EMX__) + + /* OS/2 GCC */ + typedef short ogg_int16_t; + typedef unsigned short ogg_uint16_t; + typedef int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef long long ogg_int64_t; + +#elif defined (DJGPP) + + /* DJGPP */ + typedef short ogg_int16_t; + typedef int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef long long ogg_int64_t; + +#elif defined(R5900) + + /* PS2 EE */ + typedef long ogg_int64_t; + typedef int ogg_int32_t; + typedef unsigned ogg_uint32_t; + typedef short ogg_int16_t; + +#elif defined(__SYMBIAN32__) + + /* Symbian GCC */ + typedef signed short ogg_int16_t; + typedef unsigned short ogg_uint16_t; + typedef signed int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef long long int ogg_int64_t; + +#elif defined(__linux) //simon was here + + typedef short ogg_int16_t; + typedef unsigned short ogg_uint16_t; + typedef int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef long long ogg_int64_t; + typedef unsigned long long ogg_uint64_t; + +#else + +# include +# include + +#endif + +#endif /* _OS_TYPES_H */ diff --git a/mod/pub.mod/oggvorbis.mod/libogg-1.1.3/src/bitwise.c b/mod/pub.mod/oggvorbis.mod/libogg-1.1.3/src/bitwise.c new file mode 100644 index 0000000..15246db --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libogg-1.1.3/src/bitwise.c @@ -0,0 +1,784 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the Xiph.Org Foundation http://www.xiph.org/ * + * * + ******************************************************************** + + function: packing variable sized words into an octet stream + last mod: $Id: bitwise.c 7675 2004-09-01 00:34:39Z xiphmont $ + + ********************************************************************/ + +/* We're 'LSb' endian; if we write a word but read individual bits, + then we'll read the lsb first */ + +#include +#include +#include + +#define BUFFER_INCREMENT 256 + +static const unsigned long mask[]= +{0x00000000,0x00000001,0x00000003,0x00000007,0x0000000f, + 0x0000001f,0x0000003f,0x0000007f,0x000000ff,0x000001ff, + 0x000003ff,0x000007ff,0x00000fff,0x00001fff,0x00003fff, + 0x00007fff,0x0000ffff,0x0001ffff,0x0003ffff,0x0007ffff, + 0x000fffff,0x001fffff,0x003fffff,0x007fffff,0x00ffffff, + 0x01ffffff,0x03ffffff,0x07ffffff,0x0fffffff,0x1fffffff, + 0x3fffffff,0x7fffffff,0xffffffff }; + +static const unsigned int mask8B[]= +{0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff}; + +void oggpack_writeinit(oggpack_buffer *b){ + memset(b,0,sizeof(*b)); + b->ptr=b->buffer=_ogg_malloc(BUFFER_INCREMENT); + b->buffer[0]='\0'; + b->storage=BUFFER_INCREMENT; +} + +void oggpackB_writeinit(oggpack_buffer *b){ + oggpack_writeinit(b); +} + +void oggpack_writetrunc(oggpack_buffer *b,long bits){ + long bytes=bits>>3; + bits-=bytes*8; + b->ptr=b->buffer+bytes; + b->endbit=bits; + b->endbyte=bytes; + *b->ptr&=mask[bits]; +} + +void oggpackB_writetrunc(oggpack_buffer *b,long bits){ + long bytes=bits>>3; + bits-=bytes*8; + b->ptr=b->buffer+bytes; + b->endbit=bits; + b->endbyte=bytes; + *b->ptr&=mask8B[bits]; +} + +/* Takes only up to 32 bits. */ +void oggpack_write(oggpack_buffer *b,unsigned long value,int bits){ + if(b->endbyte+4>=b->storage){ + b->buffer=_ogg_realloc(b->buffer,b->storage+BUFFER_INCREMENT); + b->storage+=BUFFER_INCREMENT; + b->ptr=b->buffer+b->endbyte; + } + + value&=mask[bits]; + bits+=b->endbit; + + b->ptr[0]|=value<endbit; + + if(bits>=8){ + b->ptr[1]=(unsigned char)(value>>(8-b->endbit)); + if(bits>=16){ + b->ptr[2]=(unsigned char)(value>>(16-b->endbit)); + if(bits>=24){ + b->ptr[3]=(unsigned char)(value>>(24-b->endbit)); + if(bits>=32){ + if(b->endbit) + b->ptr[4]=(unsigned char)(value>>(32-b->endbit)); + else + b->ptr[4]=0; + } + } + } + } + + b->endbyte+=bits/8; + b->ptr+=bits/8; + b->endbit=bits&7; +} + +/* Takes only up to 32 bits. */ +void oggpackB_write(oggpack_buffer *b,unsigned long value,int bits){ + if(b->endbyte+4>=b->storage){ + b->buffer=_ogg_realloc(b->buffer,b->storage+BUFFER_INCREMENT); + b->storage+=BUFFER_INCREMENT; + b->ptr=b->buffer+b->endbyte; + } + + value=(value&mask[bits])<<(32-bits); + bits+=b->endbit; + + b->ptr[0]|=value>>(24+b->endbit); + + if(bits>=8){ + b->ptr[1]=(unsigned char)(value>>(16+b->endbit)); + if(bits>=16){ + b->ptr[2]=(unsigned char)(value>>(8+b->endbit)); + if(bits>=24){ + b->ptr[3]=(unsigned char)(value>>(b->endbit)); + if(bits>=32){ + if(b->endbit) + b->ptr[4]=(unsigned char)(value<<(8-b->endbit)); + else + b->ptr[4]=0; + } + } + } + } + + b->endbyte+=bits/8; + b->ptr+=bits/8; + b->endbit=bits&7; +} + +void oggpack_writealign(oggpack_buffer *b){ + int bits=8-b->endbit; + if(bits<8) + oggpack_write(b,0,bits); +} + +void oggpackB_writealign(oggpack_buffer *b){ + int bits=8-b->endbit; + if(bits<8) + oggpackB_write(b,0,bits); +} + +static void oggpack_writecopy_helper(oggpack_buffer *b, + void *source, + long bits, + void (*w)(oggpack_buffer *, + unsigned long, + int), + int msb){ + unsigned char *ptr=(unsigned char *)source; + + long bytes=bits/8; + bits-=bytes*8; + + if(b->endbit){ + int i; + /* unaligned copy. Do it the hard way. */ + for(i=0;iendbyte+bytes+1>=b->storage){ + b->storage=b->endbyte+bytes+BUFFER_INCREMENT; + b->buffer=_ogg_realloc(b->buffer,b->storage); + b->ptr=b->buffer+b->endbyte; + } + + memmove(b->ptr,source,bytes); + b->ptr+=bytes; + b->endbyte+=bytes; + *b->ptr=0; + + } + if(bits){ + if(msb) + w(b,(unsigned long)(ptr[bytes]>>(8-bits)),bits); + else + w(b,(unsigned long)(ptr[bytes]),bits); + } +} + +void oggpack_writecopy(oggpack_buffer *b,void *source,long bits){ + oggpack_writecopy_helper(b,source,bits,oggpack_write,0); +} + +void oggpackB_writecopy(oggpack_buffer *b,void *source,long bits){ + oggpack_writecopy_helper(b,source,bits,oggpackB_write,1); +} + +void oggpack_reset(oggpack_buffer *b){ + b->ptr=b->buffer; + b->buffer[0]=0; + b->endbit=b->endbyte=0; +} + +void oggpackB_reset(oggpack_buffer *b){ + oggpack_reset(b); +} + +void oggpack_writeclear(oggpack_buffer *b){ + _ogg_free(b->buffer); + memset(b,0,sizeof(*b)); +} + +void oggpackB_writeclear(oggpack_buffer *b){ + oggpack_writeclear(b); +} + +void oggpack_readinit(oggpack_buffer *b,unsigned char *buf,int bytes){ + memset(b,0,sizeof(*b)); + b->buffer=b->ptr=buf; + b->storage=bytes; +} + +void oggpackB_readinit(oggpack_buffer *b,unsigned char *buf,int bytes){ + oggpack_readinit(b,buf,bytes); +} + +/* Read in bits without advancing the bitptr; bits <= 32 */ +long oggpack_look(oggpack_buffer *b,int bits){ + unsigned long ret; + unsigned long m=mask[bits]; + + bits+=b->endbit; + + if(b->endbyte+4>=b->storage){ + /* not the main path */ + if(b->endbyte*8+bits>b->storage*8)return(-1); + } + + ret=b->ptr[0]>>b->endbit; + if(bits>8){ + ret|=b->ptr[1]<<(8-b->endbit); + if(bits>16){ + ret|=b->ptr[2]<<(16-b->endbit); + if(bits>24){ + ret|=b->ptr[3]<<(24-b->endbit); + if(bits>32 && b->endbit) + ret|=b->ptr[4]<<(32-b->endbit); + } + } + } + return(m&ret); +} + +/* Read in bits without advancing the bitptr; bits <= 32 */ +long oggpackB_look(oggpack_buffer *b,int bits){ + unsigned long ret; + int m=32-bits; + + bits+=b->endbit; + + if(b->endbyte+4>=b->storage){ + /* not the main path */ + if(b->endbyte*8+bits>b->storage*8)return(-1); + } + + ret=b->ptr[0]<<(24+b->endbit); + if(bits>8){ + ret|=b->ptr[1]<<(16+b->endbit); + if(bits>16){ + ret|=b->ptr[2]<<(8+b->endbit); + if(bits>24){ + ret|=b->ptr[3]<<(b->endbit); + if(bits>32 && b->endbit) + ret|=b->ptr[4]>>(8-b->endbit); + } + } + } + return ((ret&0xffffffff)>>(m>>1))>>((m+1)>>1); +} + +long oggpack_look1(oggpack_buffer *b){ + if(b->endbyte>=b->storage)return(-1); + return((b->ptr[0]>>b->endbit)&1); +} + +long oggpackB_look1(oggpack_buffer *b){ + if(b->endbyte>=b->storage)return(-1); + return((b->ptr[0]>>(7-b->endbit))&1); +} + +void oggpack_adv(oggpack_buffer *b,int bits){ + bits+=b->endbit; + b->ptr+=bits/8; + b->endbyte+=bits/8; + b->endbit=bits&7; +} + +void oggpackB_adv(oggpack_buffer *b,int bits){ + oggpack_adv(b,bits); +} + +void oggpack_adv1(oggpack_buffer *b){ + if(++(b->endbit)>7){ + b->endbit=0; + b->ptr++; + b->endbyte++; + } +} + +void oggpackB_adv1(oggpack_buffer *b){ + oggpack_adv1(b); +} + +/* bits <= 32 */ +long oggpack_read(oggpack_buffer *b,int bits){ + long ret; + unsigned long m=mask[bits]; + + bits+=b->endbit; + + if(b->endbyte+4>=b->storage){ + /* not the main path */ + ret=-1L; + if(b->endbyte*8+bits>b->storage*8)goto overflow; + } + + ret=b->ptr[0]>>b->endbit; + if(bits>8){ + ret|=b->ptr[1]<<(8-b->endbit); + if(bits>16){ + ret|=b->ptr[2]<<(16-b->endbit); + if(bits>24){ + ret|=b->ptr[3]<<(24-b->endbit); + if(bits>32 && b->endbit){ + ret|=b->ptr[4]<<(32-b->endbit); + } + } + } + } + ret&=m; + + overflow: + + b->ptr+=bits/8; + b->endbyte+=bits/8; + b->endbit=bits&7; + return(ret); +} + +/* bits <= 32 */ +long oggpackB_read(oggpack_buffer *b,int bits){ + long ret; + long m=32-bits; + + bits+=b->endbit; + + if(b->endbyte+4>=b->storage){ + /* not the main path */ + ret=-1L; + if(b->endbyte*8+bits>b->storage*8)goto overflow; + } + + ret=b->ptr[0]<<(24+b->endbit); + if(bits>8){ + ret|=b->ptr[1]<<(16+b->endbit); + if(bits>16){ + ret|=b->ptr[2]<<(8+b->endbit); + if(bits>24){ + ret|=b->ptr[3]<<(b->endbit); + if(bits>32 && b->endbit) + ret|=b->ptr[4]>>(8-b->endbit); + } + } + } + ret=((ret&0xffffffffUL)>>(m>>1))>>((m+1)>>1); + + overflow: + + b->ptr+=bits/8; + b->endbyte+=bits/8; + b->endbit=bits&7; + return(ret); +} + +long oggpack_read1(oggpack_buffer *b){ + long ret; + + if(b->endbyte>=b->storage){ + /* not the main path */ + ret=-1L; + goto overflow; + } + + ret=(b->ptr[0]>>b->endbit)&1; + + overflow: + + b->endbit++; + if(b->endbit>7){ + b->endbit=0; + b->ptr++; + b->endbyte++; + } + return(ret); +} + +long oggpackB_read1(oggpack_buffer *b){ + long ret; + + if(b->endbyte>=b->storage){ + /* not the main path */ + ret=-1L; + goto overflow; + } + + ret=(b->ptr[0]>>(7-b->endbit))&1; + + overflow: + + b->endbit++; + if(b->endbit>7){ + b->endbit=0; + b->ptr++; + b->endbyte++; + } + return(ret); +} + +long oggpack_bytes(oggpack_buffer *b){ + return(b->endbyte+(b->endbit+7)/8); +} + +long oggpack_bits(oggpack_buffer *b){ + return(b->endbyte*8+b->endbit); +} + +long oggpackB_bytes(oggpack_buffer *b){ + return oggpack_bytes(b); +} + +long oggpackB_bits(oggpack_buffer *b){ + return oggpack_bits(b); +} + +unsigned char *oggpack_get_buffer(oggpack_buffer *b){ + return(b->buffer); +} + +unsigned char *oggpackB_get_buffer(oggpack_buffer *b){ + return oggpack_get_buffer(b); +} + +/* Self test of the bitwise routines; everything else is based on + them, so they damned well better be solid. */ + +#ifdef _V_SELFTEST +#include + +static int ilog(unsigned int v){ + int ret=0; + while(v){ + ret++; + v>>=1; + } + return(ret); +} + +oggpack_buffer o; +oggpack_buffer r; + +void report(char *in){ + fprintf(stderr,"%s",in); + exit(1); +} + +void cliptest(unsigned long *b,int vals,int bits,int *comp,int compsize){ + long bytes,i; + unsigned char *buffer; + + oggpack_reset(&o); + for(i=0;i +#include +#include + +/* A complete description of Ogg framing exists in docs/framing.html */ + +int ogg_page_version(ogg_page *og){ + return((int)(og->header[4])); +} + +int ogg_page_continued(ogg_page *og){ + return((int)(og->header[5]&0x01)); +} + +int ogg_page_bos(ogg_page *og){ + return((int)(og->header[5]&0x02)); +} + +int ogg_page_eos(ogg_page *og){ + return((int)(og->header[5]&0x04)); +} + +ogg_int64_t ogg_page_granulepos(ogg_page *og){ + unsigned char *page=og->header; + ogg_int64_t granulepos=page[13]&(0xff); + granulepos= (granulepos<<8)|(page[12]&0xff); + granulepos= (granulepos<<8)|(page[11]&0xff); + granulepos= (granulepos<<8)|(page[10]&0xff); + granulepos= (granulepos<<8)|(page[9]&0xff); + granulepos= (granulepos<<8)|(page[8]&0xff); + granulepos= (granulepos<<8)|(page[7]&0xff); + granulepos= (granulepos<<8)|(page[6]&0xff); + return(granulepos); +} + +int ogg_page_serialno(ogg_page *og){ + return(og->header[14] | + (og->header[15]<<8) | + (og->header[16]<<16) | + (og->header[17]<<24)); +} + +long ogg_page_pageno(ogg_page *og){ + return(og->header[18] | + (og->header[19]<<8) | + (og->header[20]<<16) | + (og->header[21]<<24)); +} + + + +/* returns the number of packets that are completed on this page (if + the leading packet is begun on a previous page, but ends on this + page, it's counted */ + +/* NOTE: +If a page consists of a packet begun on a previous page, and a new +packet begun (but not completed) on this page, the return will be: + ogg_page_packets(page) ==1, + ogg_page_continued(page) !=0 + +If a page happens to be a single packet that was begun on a +previous page, and spans to the next page (in the case of a three or +more page packet), the return will be: + ogg_page_packets(page) ==0, + ogg_page_continued(page) !=0 +*/ + +int ogg_page_packets(ogg_page *og){ + int i,n=og->header[26],count=0; + for(i=0;iheader[27+i]<255)count++; + return(count); +} + + +#if 0 +/* helper to initialize lookup for direct-table CRC (illustrative; we + use the static init below) */ + +static ogg_uint32_t _ogg_crc_entry(unsigned long index){ + int i; + unsigned long r; + + r = index << 24; + for (i=0; i<8; i++) + if (r & 0x80000000UL) + r = (r << 1) ^ 0x04c11db7; /* The same as the ethernet generator + polynomial, although we use an + unreflected alg and an init/final + of 0, not 0xffffffff */ + else + r<<=1; + return (r & 0xffffffffUL); +} +#endif + +static const ogg_uint32_t crc_lookup[256]={ + 0x00000000,0x04c11db7,0x09823b6e,0x0d4326d9, + 0x130476dc,0x17c56b6b,0x1a864db2,0x1e475005, + 0x2608edb8,0x22c9f00f,0x2f8ad6d6,0x2b4bcb61, + 0x350c9b64,0x31cd86d3,0x3c8ea00a,0x384fbdbd, + 0x4c11db70,0x48d0c6c7,0x4593e01e,0x4152fda9, + 0x5f15adac,0x5bd4b01b,0x569796c2,0x52568b75, + 0x6a1936c8,0x6ed82b7f,0x639b0da6,0x675a1011, + 0x791d4014,0x7ddc5da3,0x709f7b7a,0x745e66cd, + 0x9823b6e0,0x9ce2ab57,0x91a18d8e,0x95609039, + 0x8b27c03c,0x8fe6dd8b,0x82a5fb52,0x8664e6e5, + 0xbe2b5b58,0xbaea46ef,0xb7a96036,0xb3687d81, + 0xad2f2d84,0xa9ee3033,0xa4ad16ea,0xa06c0b5d, + 0xd4326d90,0xd0f37027,0xddb056fe,0xd9714b49, + 0xc7361b4c,0xc3f706fb,0xceb42022,0xca753d95, + 0xf23a8028,0xf6fb9d9f,0xfbb8bb46,0xff79a6f1, + 0xe13ef6f4,0xe5ffeb43,0xe8bccd9a,0xec7dd02d, + 0x34867077,0x30476dc0,0x3d044b19,0x39c556ae, + 0x278206ab,0x23431b1c,0x2e003dc5,0x2ac12072, + 0x128e9dcf,0x164f8078,0x1b0ca6a1,0x1fcdbb16, + 0x018aeb13,0x054bf6a4,0x0808d07d,0x0cc9cdca, + 0x7897ab07,0x7c56b6b0,0x71159069,0x75d48dde, + 0x6b93dddb,0x6f52c06c,0x6211e6b5,0x66d0fb02, + 0x5e9f46bf,0x5a5e5b08,0x571d7dd1,0x53dc6066, + 0x4d9b3063,0x495a2dd4,0x44190b0d,0x40d816ba, + 0xaca5c697,0xa864db20,0xa527fdf9,0xa1e6e04e, + 0xbfa1b04b,0xbb60adfc,0xb6238b25,0xb2e29692, + 0x8aad2b2f,0x8e6c3698,0x832f1041,0x87ee0df6, + 0x99a95df3,0x9d684044,0x902b669d,0x94ea7b2a, + 0xe0b41de7,0xe4750050,0xe9362689,0xedf73b3e, + 0xf3b06b3b,0xf771768c,0xfa325055,0xfef34de2, + 0xc6bcf05f,0xc27dede8,0xcf3ecb31,0xcbffd686, + 0xd5b88683,0xd1799b34,0xdc3abded,0xd8fba05a, + 0x690ce0ee,0x6dcdfd59,0x608edb80,0x644fc637, + 0x7a089632,0x7ec98b85,0x738aad5c,0x774bb0eb, + 0x4f040d56,0x4bc510e1,0x46863638,0x42472b8f, + 0x5c007b8a,0x58c1663d,0x558240e4,0x51435d53, + 0x251d3b9e,0x21dc2629,0x2c9f00f0,0x285e1d47, + 0x36194d42,0x32d850f5,0x3f9b762c,0x3b5a6b9b, + 0x0315d626,0x07d4cb91,0x0a97ed48,0x0e56f0ff, + 0x1011a0fa,0x14d0bd4d,0x19939b94,0x1d528623, + 0xf12f560e,0xf5ee4bb9,0xf8ad6d60,0xfc6c70d7, + 0xe22b20d2,0xe6ea3d65,0xeba91bbc,0xef68060b, + 0xd727bbb6,0xd3e6a601,0xdea580d8,0xda649d6f, + 0xc423cd6a,0xc0e2d0dd,0xcda1f604,0xc960ebb3, + 0xbd3e8d7e,0xb9ff90c9,0xb4bcb610,0xb07daba7, + 0xae3afba2,0xaafbe615,0xa7b8c0cc,0xa379dd7b, + 0x9b3660c6,0x9ff77d71,0x92b45ba8,0x9675461f, + 0x8832161a,0x8cf30bad,0x81b02d74,0x857130c3, + 0x5d8a9099,0x594b8d2e,0x5408abf7,0x50c9b640, + 0x4e8ee645,0x4a4ffbf2,0x470cdd2b,0x43cdc09c, + 0x7b827d21,0x7f436096,0x7200464f,0x76c15bf8, + 0x68860bfd,0x6c47164a,0x61043093,0x65c52d24, + 0x119b4be9,0x155a565e,0x18197087,0x1cd86d30, + 0x029f3d35,0x065e2082,0x0b1d065b,0x0fdc1bec, + 0x3793a651,0x3352bbe6,0x3e119d3f,0x3ad08088, + 0x2497d08d,0x2056cd3a,0x2d15ebe3,0x29d4f654, + 0xc5a92679,0xc1683bce,0xcc2b1d17,0xc8ea00a0, + 0xd6ad50a5,0xd26c4d12,0xdf2f6bcb,0xdbee767c, + 0xe3a1cbc1,0xe760d676,0xea23f0af,0xeee2ed18, + 0xf0a5bd1d,0xf464a0aa,0xf9278673,0xfde69bc4, + 0x89b8fd09,0x8d79e0be,0x803ac667,0x84fbdbd0, + 0x9abc8bd5,0x9e7d9662,0x933eb0bb,0x97ffad0c, + 0xafb010b1,0xab710d06,0xa6322bdf,0xa2f33668, + 0xbcb4666d,0xb8757bda,0xb5365d03,0xb1f740b4}; + +/* init the encode/decode logical stream state */ + +int ogg_stream_init(ogg_stream_state *os,int serialno){ + if(os){ + memset(os,0,sizeof(*os)); + os->body_storage=16*1024; + os->body_data=_ogg_malloc(os->body_storage*sizeof(*os->body_data)); + + os->lacing_storage=1024; + os->lacing_vals=_ogg_malloc(os->lacing_storage*sizeof(*os->lacing_vals)); + os->granule_vals=_ogg_malloc(os->lacing_storage*sizeof(*os->granule_vals)); + + os->serialno=serialno; + + return(0); + } + return(-1); +} + +/* _clear does not free os, only the non-flat storage within */ +int ogg_stream_clear(ogg_stream_state *os){ + if(os){ + if(os->body_data)_ogg_free(os->body_data); + if(os->lacing_vals)_ogg_free(os->lacing_vals); + if(os->granule_vals)_ogg_free(os->granule_vals); + + memset(os,0,sizeof(*os)); + } + return(0); +} + +int ogg_stream_destroy(ogg_stream_state *os){ + if(os){ + ogg_stream_clear(os); + _ogg_free(os); + } + return(0); +} + +/* Helpers for ogg_stream_encode; this keeps the structure and + what's happening fairly clear */ + +static void _os_body_expand(ogg_stream_state *os,int needed){ + if(os->body_storage<=os->body_fill+needed){ + os->body_storage+=(needed+1024); + os->body_data=_ogg_realloc(os->body_data,os->body_storage*sizeof(*os->body_data)); + } +} + +static void _os_lacing_expand(ogg_stream_state *os,int needed){ + if(os->lacing_storage<=os->lacing_fill+needed){ + os->lacing_storage+=(needed+32); + os->lacing_vals=_ogg_realloc(os->lacing_vals,os->lacing_storage*sizeof(*os->lacing_vals)); + os->granule_vals=_ogg_realloc(os->granule_vals,os->lacing_storage*sizeof(*os->granule_vals)); + } +} + +/* checksum the page */ +/* Direct table CRC; note that this will be faster in the future if we + perform the checksum silmultaneously with other copies */ + +void ogg_page_checksum_set(ogg_page *og){ + if(og){ + ogg_uint32_t crc_reg=0; + int i; + + /* safety; needed for API behavior, but not framing code */ + og->header[22]=0; + og->header[23]=0; + og->header[24]=0; + og->header[25]=0; + + for(i=0;iheader_len;i++) + crc_reg=(crc_reg<<8)^crc_lookup[((crc_reg >> 24)&0xff)^og->header[i]]; + for(i=0;ibody_len;i++) + crc_reg=(crc_reg<<8)^crc_lookup[((crc_reg >> 24)&0xff)^og->body[i]]; + + og->header[22]=(unsigned char)(crc_reg&0xff); + og->header[23]=(unsigned char)((crc_reg>>8)&0xff); + og->header[24]=(unsigned char)((crc_reg>>16)&0xff); + og->header[25]=(unsigned char)((crc_reg>>24)&0xff); + } +} + +/* submit data to the internal buffer of the framing engine */ +int ogg_stream_packetin(ogg_stream_state *os,ogg_packet *op){ + int lacing_vals=op->bytes/255+1,i; + + if(os->body_returned){ + /* advance packet data according to the body_returned pointer. We + had to keep it around to return a pointer into the buffer last + call */ + + os->body_fill-=os->body_returned; + if(os->body_fill) + memmove(os->body_data,os->body_data+os->body_returned, + os->body_fill); + os->body_returned=0; + } + + /* make sure we have the buffer storage */ + _os_body_expand(os,op->bytes); + _os_lacing_expand(os,lacing_vals); + + /* Copy in the submitted packet. Yes, the copy is a waste; this is + the liability of overly clean abstraction for the time being. It + will actually be fairly easy to eliminate the extra copy in the + future */ + + memcpy(os->body_data+os->body_fill,op->packet,op->bytes); + os->body_fill+=op->bytes; + + /* Store lacing vals for this packet */ + for(i=0;ilacing_vals[os->lacing_fill+i]=255; + os->granule_vals[os->lacing_fill+i]=os->granulepos; + } + os->lacing_vals[os->lacing_fill+i]=(op->bytes)%255; + os->granulepos=os->granule_vals[os->lacing_fill+i]=op->granulepos; + + /* flag the first segment as the beginning of the packet */ + os->lacing_vals[os->lacing_fill]|= 0x100; + + os->lacing_fill+=lacing_vals; + + /* for the sake of completeness */ + os->packetno++; + + if(op->e_o_s)os->e_o_s=1; + + return(0); +} + +/* This will flush remaining packets into a page (returning nonzero), + even if there is not enough data to trigger a flush normally + (undersized page). If there are no packets or partial packets to + flush, ogg_stream_flush returns 0. Note that ogg_stream_flush will + try to flush a normal sized page like ogg_stream_pageout; a call to + ogg_stream_flush does not guarantee that all packets have flushed. + Only a return value of 0 from ogg_stream_flush indicates all packet + data is flushed into pages. + + since ogg_stream_flush will flush the last page in a stream even if + it's undersized, you almost certainly want to use ogg_stream_pageout + (and *not* ogg_stream_flush) unless you specifically need to flush + an page regardless of size in the middle of a stream. */ + +int ogg_stream_flush(ogg_stream_state *os,ogg_page *og){ + int i; + int vals=0; + int maxvals=(os->lacing_fill>255?255:os->lacing_fill); + int bytes=0; + long acc=0; + ogg_int64_t granule_pos=-1; + + if(maxvals==0)return(0); + + /* construct a page */ + /* decide how many segments to include */ + + /* If this is the initial header case, the first page must only include + the initial header packet */ + if(os->b_o_s==0){ /* 'initial header page' case */ + granule_pos=0; + for(vals=0;valslacing_vals[vals]&0x0ff)<255){ + vals++; + break; + } + } + }else{ + for(vals=0;vals4096)break; + acc+=os->lacing_vals[vals]&0x0ff; + if((os->lacing_vals[vals]&0xff)<255) + granule_pos=os->granule_vals[vals]; + } + } + + /* construct the header in temp storage */ + memcpy(os->header,"OggS",4); + + /* stream structure version */ + os->header[4]=0x00; + + /* continued packet flag? */ + os->header[5]=0x00; + if((os->lacing_vals[0]&0x100)==0)os->header[5]|=0x01; + /* first page flag? */ + if(os->b_o_s==0)os->header[5]|=0x02; + /* last page flag? */ + if(os->e_o_s && os->lacing_fill==vals)os->header[5]|=0x04; + os->b_o_s=1; + + /* 64 bits of PCM position */ + for(i=6;i<14;i++){ + os->header[i]=(unsigned char)(granule_pos&0xff); + granule_pos>>=8; + } + + /* 32 bits of stream serial number */ + { + long serialno=os->serialno; + for(i=14;i<18;i++){ + os->header[i]=(unsigned char)(serialno&0xff); + serialno>>=8; + } + } + + /* 32 bits of page counter (we have both counter and page header + because this val can roll over) */ + if(os->pageno==-1)os->pageno=0; /* because someone called + stream_reset; this would be a + strange thing to do in an + encode stream, but it has + plausible uses */ + { + long pageno=os->pageno++; + for(i=18;i<22;i++){ + os->header[i]=(unsigned char)(pageno&0xff); + pageno>>=8; + } + } + + /* zero for computation; filled in later */ + os->header[22]=0; + os->header[23]=0; + os->header[24]=0; + os->header[25]=0; + + /* segment table */ + os->header[26]=(unsigned char)(vals&0xff); + for(i=0;iheader[i+27]=(unsigned char)(os->lacing_vals[i]&0xff); + + /* set pointers in the ogg_page struct */ + og->header=os->header; + og->header_len=os->header_fill=vals+27; + og->body=os->body_data+os->body_returned; + og->body_len=bytes; + + /* advance the lacing data and set the body_returned pointer */ + + os->lacing_fill-=vals; + memmove(os->lacing_vals,os->lacing_vals+vals,os->lacing_fill*sizeof(*os->lacing_vals)); + memmove(os->granule_vals,os->granule_vals+vals,os->lacing_fill*sizeof(*os->granule_vals)); + os->body_returned+=bytes; + + /* calculate the checksum */ + + ogg_page_checksum_set(og); + + /* done */ + return(1); +} + + +/* This constructs pages from buffered packet segments. The pointers +returned are to static buffers; do not free. The returned buffers are +good only until the next call (using the same ogg_stream_state) */ + +int ogg_stream_pageout(ogg_stream_state *os, ogg_page *og){ + + if((os->e_o_s&&os->lacing_fill) || /* 'were done, now flush' case */ + os->body_fill-os->body_returned > 4096 ||/* 'page nominal size' case */ + os->lacing_fill>=255 || /* 'segment table full' case */ + (os->lacing_fill&&!os->b_o_s)){ /* 'initial header page' case */ + + return(ogg_stream_flush(os,og)); + } + + /* not enough data to construct a page and not end of stream */ + return(0); +} + +int ogg_stream_eos(ogg_stream_state *os){ + return os->e_o_s; +} + +/* DECODING PRIMITIVES: packet streaming layer **********************/ + +/* This has two layers to place more of the multi-serialno and paging + control in the application's hands. First, we expose a data buffer + using ogg_sync_buffer(). The app either copies into the + buffer, or passes it directly to read(), etc. We then call + ogg_sync_wrote() to tell how many bytes we just added. + + Pages are returned (pointers into the buffer in ogg_sync_state) + by ogg_sync_pageout(). The page is then submitted to + ogg_stream_pagein() along with the appropriate + ogg_stream_state* (ie, matching serialno). We then get raw + packets out calling ogg_stream_packetout() with a + ogg_stream_state. */ + +/* initialize the struct to a known state */ +int ogg_sync_init(ogg_sync_state *oy){ + if(oy){ + memset(oy,0,sizeof(*oy)); + } + return(0); +} + +/* clear non-flat storage within */ +int ogg_sync_clear(ogg_sync_state *oy){ + if(oy){ + if(oy->data)_ogg_free(oy->data); + ogg_sync_init(oy); + } + return(0); +} + +int ogg_sync_destroy(ogg_sync_state *oy){ + if(oy){ + ogg_sync_clear(oy); + _ogg_free(oy); + } + return(0); +} + +char *ogg_sync_buffer(ogg_sync_state *oy, long size){ + + /* first, clear out any space that has been previously returned */ + if(oy->returned){ + oy->fill-=oy->returned; + if(oy->fill>0) + memmove(oy->data,oy->data+oy->returned,oy->fill); + oy->returned=0; + } + + if(size>oy->storage-oy->fill){ + /* We need to extend the internal buffer */ + long newsize=size+oy->fill+4096; /* an extra page to be nice */ + + if(oy->data) + oy->data=_ogg_realloc(oy->data,newsize); + else + oy->data=_ogg_malloc(newsize); + oy->storage=newsize; + } + + /* expose a segment at least as large as requested at the fill mark */ + return((char *)oy->data+oy->fill); +} + +int ogg_sync_wrote(ogg_sync_state *oy, long bytes){ + if(oy->fill+bytes>oy->storage)return(-1); + oy->fill+=bytes; + return(0); +} + +/* sync the stream. This is meant to be useful for finding page + boundaries. + + return values for this: + -n) skipped n bytes + 0) page not ready; more data (no bytes skipped) + n) page synced at current location; page length n bytes + +*/ + +long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og){ + unsigned char *page=oy->data+oy->returned; + unsigned char *next; + long bytes=oy->fill-oy->returned; + + if(oy->headerbytes==0){ + int headerbytes,i; + if(bytes<27)return(0); /* not enough for a header */ + + /* verify capture pattern */ + if(memcmp(page,"OggS",4))goto sync_fail; + + headerbytes=page[26]+27; + if(bytesbodybytes+=page[27+i]; + oy->headerbytes=headerbytes; + } + + if(oy->bodybytes+oy->headerbytes>bytes)return(0); + + /* The whole test page is buffered. Verify the checksum */ + { + /* Grab the checksum bytes, set the header field to zero */ + char chksum[4]; + ogg_page log; + + memcpy(chksum,page+22,4); + memset(page+22,0,4); + + /* set up a temp page struct and recompute the checksum */ + log.header=page; + log.header_len=oy->headerbytes; + log.body=page+oy->headerbytes; + log.body_len=oy->bodybytes; + ogg_page_checksum_set(&log); + + /* Compare */ + if(memcmp(chksum,page+22,4)){ + /* D'oh. Mismatch! Corrupt page (or miscapture and not a page + at all) */ + /* replace the computed checksum with the one actually read in */ + memcpy(page+22,chksum,4); + + /* Bad checksum. Lose sync */ + goto sync_fail; + } + } + + /* yes, have a whole page all ready to go */ + { + unsigned char *page=oy->data+oy->returned; + long bytes; + + if(og){ + og->header=page; + og->header_len=oy->headerbytes; + og->body=page+oy->headerbytes; + og->body_len=oy->bodybytes; + } + + oy->unsynced=0; + oy->returned+=(bytes=oy->headerbytes+oy->bodybytes); + oy->headerbytes=0; + oy->bodybytes=0; + return(bytes); + } + + sync_fail: + + oy->headerbytes=0; + oy->bodybytes=0; + + /* search for possible capture */ + next=memchr(page+1,'O',bytes-1); + if(!next) + next=oy->data+oy->fill; + + oy->returned=next-oy->data; + return(-(next-page)); +} + +/* sync the stream and get a page. Keep trying until we find a page. + Supress 'sync errors' after reporting the first. + + return values: + -1) recapture (hole in data) + 0) need more data + 1) page returned + + Returns pointers into buffered data; invalidated by next call to + _stream, _clear, _init, or _buffer */ + +int ogg_sync_pageout(ogg_sync_state *oy, ogg_page *og){ + + /* all we need to do is verify a page at the head of the stream + buffer. If it doesn't verify, we look for the next potential + frame */ + + for(;;){ + long ret=ogg_sync_pageseek(oy,og); + if(ret>0){ + /* have a page */ + return(1); + } + if(ret==0){ + /* need more data */ + return(0); + } + + /* head did not start a synced page... skipped some bytes */ + if(!oy->unsynced){ + oy->unsynced=1; + return(-1); + } + + /* loop. keep looking */ + + } +} + +/* add the incoming page to the stream state; we decompose the page + into packet segments here as well. */ + +int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og){ + unsigned char *header=og->header; + unsigned char *body=og->body; + long bodysize=og->body_len; + int segptr=0; + + int version=ogg_page_version(og); + int continued=ogg_page_continued(og); + int bos=ogg_page_bos(og); + int eos=ogg_page_eos(og); + ogg_int64_t granulepos=ogg_page_granulepos(og); + int serialno=ogg_page_serialno(og); + long pageno=ogg_page_pageno(og); + int segments=header[26]; + + /* clean up 'returned data' */ + { + long lr=os->lacing_returned; + long br=os->body_returned; + + /* body data */ + if(br){ + os->body_fill-=br; + if(os->body_fill) + memmove(os->body_data,os->body_data+br,os->body_fill); + os->body_returned=0; + } + + if(lr){ + /* segment table */ + if(os->lacing_fill-lr){ + memmove(os->lacing_vals,os->lacing_vals+lr, + (os->lacing_fill-lr)*sizeof(*os->lacing_vals)); + memmove(os->granule_vals,os->granule_vals+lr, + (os->lacing_fill-lr)*sizeof(*os->granule_vals)); + } + os->lacing_fill-=lr; + os->lacing_packet-=lr; + os->lacing_returned=0; + } + } + + /* check the serial number */ + if(serialno!=os->serialno)return(-1); + if(version>0)return(-1); + + _os_lacing_expand(os,segments+1); + + /* are we in sequence? */ + if(pageno!=os->pageno){ + int i; + + /* unroll previous partial packet (if any) */ + for(i=os->lacing_packet;ilacing_fill;i++) + os->body_fill-=os->lacing_vals[i]&0xff; + os->lacing_fill=os->lacing_packet; + + /* make a note of dropped data in segment table */ + if(os->pageno!=-1){ + os->lacing_vals[os->lacing_fill++]=0x400; + os->lacing_packet++; + } + } + + /* are we a 'continued packet' page? If so, we may need to skip + some segments */ + if(continued){ + if(os->lacing_fill<1 || + os->lacing_vals[os->lacing_fill-1]==0x400){ + bos=0; + for(;segptrbody_data+os->body_fill,body,bodysize); + os->body_fill+=bodysize; + } + + { + int saved=-1; + while(segptrlacing_vals[os->lacing_fill]=val; + os->granule_vals[os->lacing_fill]=-1; + + if(bos){ + os->lacing_vals[os->lacing_fill]|=0x100; + bos=0; + } + + if(val<255)saved=os->lacing_fill; + + os->lacing_fill++; + segptr++; + + if(val<255)os->lacing_packet=os->lacing_fill; + } + + /* set the granulepos on the last granuleval of the last full packet */ + if(saved!=-1){ + os->granule_vals[saved]=granulepos; + } + + } + + if(eos){ + os->e_o_s=1; + if(os->lacing_fill>0) + os->lacing_vals[os->lacing_fill-1]|=0x200; + } + + os->pageno=pageno+1; + + return(0); +} + +/* clear things to an initial state. Good to call, eg, before seeking */ +int ogg_sync_reset(ogg_sync_state *oy){ + oy->fill=0; + oy->returned=0; + oy->unsynced=0; + oy->headerbytes=0; + oy->bodybytes=0; + return(0); +} + +int ogg_stream_reset(ogg_stream_state *os){ + os->body_fill=0; + os->body_returned=0; + + os->lacing_fill=0; + os->lacing_packet=0; + os->lacing_returned=0; + + os->header_fill=0; + + os->e_o_s=0; + os->b_o_s=0; + os->pageno=-1; + os->packetno=0; + os->granulepos=0; + + return(0); +} + +int ogg_stream_reset_serialno(ogg_stream_state *os,int serialno){ + ogg_stream_reset(os); + os->serialno=serialno; + return(0); +} + +static int _packetout(ogg_stream_state *os,ogg_packet *op,int adv){ + + /* The last part of decode. We have the stream broken into packet + segments. Now we need to group them into packets (or return the + out of sync markers) */ + + int ptr=os->lacing_returned; + + if(os->lacing_packet<=ptr)return(0); + + if(os->lacing_vals[ptr]&0x400){ + /* we need to tell the codec there's a gap; it might need to + handle previous packet dependencies. */ + os->lacing_returned++; + os->packetno++; + return(-1); + } + + if(!op && !adv)return(1); /* just using peek as an inexpensive way + to ask if there's a whole packet + waiting */ + + /* Gather the whole packet. We'll have no holes or a partial packet */ + { + int size=os->lacing_vals[ptr]&0xff; + int bytes=size; + int eos=os->lacing_vals[ptr]&0x200; /* last packet of the stream? */ + int bos=os->lacing_vals[ptr]&0x100; /* first packet of the stream? */ + + while(size==255){ + int val=os->lacing_vals[++ptr]; + size=val&0xff; + if(val&0x200)eos=0x200; + bytes+=size; + } + + if(op){ + op->e_o_s=eos; + op->b_o_s=bos; + op->packet=os->body_data+os->body_returned; + op->packetno=os->packetno; + op->granulepos=os->granule_vals[ptr]; + op->bytes=bytes; + } + + if(adv){ + os->body_returned+=bytes; + os->lacing_returned=ptr+1; + os->packetno++; + } + } + return(1); +} + +int ogg_stream_packetout(ogg_stream_state *os,ogg_packet *op){ + return _packetout(os,op,1); +} + +int ogg_stream_packetpeek(ogg_stream_state *os,ogg_packet *op){ + return _packetout(os,op,0); +} + +void ogg_packet_clear(ogg_packet *op) { + _ogg_free(op->packet); + memset(op, 0, sizeof(*op)); +} + +#ifdef _V_SELFTEST +#include + +ogg_stream_state os_en, os_de; +ogg_sync_state oy; + +void checkpacket(ogg_packet *op,int len, int no, int pos){ + long j; + static int sequence=0; + static int lastno=0; + + if(op->bytes!=len){ + fprintf(stderr,"incorrect packet length!\n"); + exit(1); + } + if(op->granulepos!=pos){ + fprintf(stderr,"incorrect packet position!\n"); + exit(1); + } + + /* packet number just follows sequence/gap; adjust the input number + for that */ + if(no==0){ + sequence=0; + }else{ + sequence++; + if(no>lastno+1) + sequence++; + } + lastno=no; + if(op->packetno!=sequence){ + fprintf(stderr,"incorrect packet sequence %ld != %d\n", + (long)(op->packetno),sequence); + exit(1); + } + + /* Test data */ + for(j=0;jbytes;j++) + if(op->packet[j]!=((j+no)&0xff)){ + fprintf(stderr,"body data mismatch (1) at pos %ld: %x!=%lx!\n\n", + j,op->packet[j],(j+no)&0xff); + exit(1); + } +} + +void check_page(unsigned char *data,const int *header,ogg_page *og){ + long j; + /* Test data */ + for(j=0;jbody_len;j++) + if(og->body[j]!=data[j]){ + fprintf(stderr,"body data mismatch (2) at pos %ld: %x!=%x!\n\n", + j,data[j],og->body[j]); + exit(1); + } + + /* Test header */ + for(j=0;jheader_len;j++){ + if(og->header[j]!=header[j]){ + fprintf(stderr,"header content mismatch at pos %ld:\n",j); + for(j=0;jheader[j]); + fprintf(stderr,"\n"); + exit(1); + } + } + if(og->header_len!=header[26]+27){ + fprintf(stderr,"header length incorrect! (%ld!=%d)\n", + og->header_len,header[26]+27); + exit(1); + } +} + +void print_header(ogg_page *og){ + int j; + fprintf(stderr,"\nHEADER:\n"); + fprintf(stderr," capture: %c %c %c %c version: %d flags: %x\n", + og->header[0],og->header[1],og->header[2],og->header[3], + (int)og->header[4],(int)og->header[5]); + + fprintf(stderr," granulepos: %d serialno: %d pageno: %ld\n", + (og->header[9]<<24)|(og->header[8]<<16)| + (og->header[7]<<8)|og->header[6], + (og->header[17]<<24)|(og->header[16]<<16)| + (og->header[15]<<8)|og->header[14], + ((long)(og->header[21])<<24)|(og->header[20]<<16)| + (og->header[19]<<8)|og->header[18]); + + fprintf(stderr," checksum: %02x:%02x:%02x:%02x\n segments: %d (", + (int)og->header[22],(int)og->header[23], + (int)og->header[24],(int)og->header[25], + (int)og->header[26]); + + for(j=27;jheader_len;j++) + fprintf(stderr,"%d ",(int)og->header[j]); + fprintf(stderr,")\n\n"); +} + +void copy_page(ogg_page *og){ + unsigned char *temp=_ogg_malloc(og->header_len); + memcpy(temp,og->header,og->header_len); + og->header=temp; + + temp=_ogg_malloc(og->body_len); + memcpy(temp,og->body,og->body_len); + og->body=temp; +} + +void free_page(ogg_page *og){ + _ogg_free (og->header); + _ogg_free (og->body); +} + +void error(void){ + fprintf(stderr,"error!\n"); + exit(1); +} + +/* 17 only */ +const int head1_0[] = {0x4f,0x67,0x67,0x53,0,0x06, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x02,0x03,0x04,0,0,0,0, + 0x15,0xed,0xec,0x91, + 1, + 17}; + +/* 17, 254, 255, 256, 500, 510, 600 byte, pad */ +const int head1_1[] = {0x4f,0x67,0x67,0x53,0,0x02, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x02,0x03,0x04,0,0,0,0, + 0x59,0x10,0x6c,0x2c, + 1, + 17}; +const int head2_1[] = {0x4f,0x67,0x67,0x53,0,0x04, + 0x07,0x18,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x02,0x03,0x04,1,0,0,0, + 0x89,0x33,0x85,0xce, + 13, + 254,255,0,255,1,255,245,255,255,0, + 255,255,90}; + +/* nil packets; beginning,middle,end */ +const int head1_2[] = {0x4f,0x67,0x67,0x53,0,0x02, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x02,0x03,0x04,0,0,0,0, + 0xff,0x7b,0x23,0x17, + 1, + 0}; +const int head2_2[] = {0x4f,0x67,0x67,0x53,0,0x04, + 0x07,0x28,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x02,0x03,0x04,1,0,0,0, + 0x5c,0x3f,0x66,0xcb, + 17, + 17,254,255,0,0,255,1,0,255,245,255,255,0, + 255,255,90,0}; + +/* large initial packet */ +const int head1_3[] = {0x4f,0x67,0x67,0x53,0,0x02, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x02,0x03,0x04,0,0,0,0, + 0x01,0x27,0x31,0xaa, + 18, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,10}; + +const int head2_3[] = {0x4f,0x67,0x67,0x53,0,0x04, + 0x07,0x08,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x02,0x03,0x04,1,0,0,0, + 0x7f,0x4e,0x8a,0xd2, + 4, + 255,4,255,0}; + + +/* continuing packet test */ +const int head1_4[] = {0x4f,0x67,0x67,0x53,0,0x02, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x02,0x03,0x04,0,0,0,0, + 0xff,0x7b,0x23,0x17, + 1, + 0}; + +const int head2_4[] = {0x4f,0x67,0x67,0x53,0,0x00, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0x01,0x02,0x03,0x04,1,0,0,0, + 0x54,0x05,0x51,0xc8, + 17, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255}; + +const int head3_4[] = {0x4f,0x67,0x67,0x53,0,0x05, + 0x07,0x0c,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x02,0x03,0x04,2,0,0,0, + 0xc8,0xc3,0xcb,0xed, + 5, + 10,255,4,255,0}; + + +/* page with the 255 segment limit */ +const int head1_5[] = {0x4f,0x67,0x67,0x53,0,0x02, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x02,0x03,0x04,0,0,0,0, + 0xff,0x7b,0x23,0x17, + 1, + 0}; + +const int head2_5[] = {0x4f,0x67,0x67,0x53,0,0x00, + 0x07,0xfc,0x03,0x00,0x00,0x00,0x00,0x00, + 0x01,0x02,0x03,0x04,1,0,0,0, + 0xed,0x2a,0x2e,0xa7, + 255, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10}; + +const int head3_5[] = {0x4f,0x67,0x67,0x53,0,0x04, + 0x07,0x00,0x04,0x00,0x00,0x00,0x00,0x00, + 0x01,0x02,0x03,0x04,2,0,0,0, + 0x6c,0x3b,0x82,0x3d, + 1, + 50}; + + +/* packet that overspans over an entire page */ +const int head1_6[] = {0x4f,0x67,0x67,0x53,0,0x02, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x02,0x03,0x04,0,0,0,0, + 0xff,0x7b,0x23,0x17, + 1, + 0}; + +const int head2_6[] = {0x4f,0x67,0x67,0x53,0,0x00, + 0x07,0x04,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x02,0x03,0x04,1,0,0,0, + 0x3c,0xd9,0x4d,0x3f, + 17, + 100,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255}; + +const int head3_6[] = {0x4f,0x67,0x67,0x53,0,0x01, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0x01,0x02,0x03,0x04,2,0,0,0, + 0x01,0xd2,0xe5,0xe5, + 17, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255}; + +const int head4_6[] = {0x4f,0x67,0x67,0x53,0,0x05, + 0x07,0x10,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x02,0x03,0x04,3,0,0,0, + 0xef,0xdd,0x88,0xde, + 7, + 255,255,75,255,4,255,0}; + +/* packet that overspans over an entire page */ +const int head1_7[] = {0x4f,0x67,0x67,0x53,0,0x02, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x02,0x03,0x04,0,0,0,0, + 0xff,0x7b,0x23,0x17, + 1, + 0}; + +const int head2_7[] = {0x4f,0x67,0x67,0x53,0,0x00, + 0x07,0x04,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x02,0x03,0x04,1,0,0,0, + 0x3c,0xd9,0x4d,0x3f, + 17, + 100,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255}; + +const int head3_7[] = {0x4f,0x67,0x67,0x53,0,0x05, + 0x07,0x08,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x02,0x03,0x04,2,0,0,0, + 0xd4,0xe0,0x60,0xe5, + 1,0}; + +void test_pack(const int *pl, const int **headers, int byteskip, + int pageskip, int packetskip){ + unsigned char *data=_ogg_malloc(1024*1024); /* for scripted test cases only */ + long inptr=0; + long outptr=0; + long deptr=0; + long depacket=0; + long granule_pos=7,pageno=0; + int i,j,packets,pageout=pageskip; + int eosflag=0; + int bosflag=0; + + int byteskipcount=0; + + ogg_stream_reset(&os_en); + ogg_stream_reset(&os_de); + ogg_sync_reset(&oy); + + for(packets=0;packetsbyteskip){ + memcpy(next,og.header,byteskipcount-byteskip); + next+=byteskipcount-byteskip; + byteskipcount=byteskip; + } + + byteskipcount+=og.body_len; + if(byteskipcount>byteskip){ + memcpy(next,og.body,byteskipcount-byteskip); + next+=byteskipcount-byteskip; + byteskipcount=byteskip; + } + + ogg_sync_wrote(&oy,next-buf); + + while(1){ + int ret=ogg_sync_pageout(&oy,&og_de); + if(ret==0)break; + if(ret<0)continue; + /* got a page. Happy happy. Verify that it's good. */ + + fprintf(stderr,"(%ld), ",pageout); + + check_page(data+deptr,headers[pageout],&og_de); + deptr+=og_de.body_len; + pageout++; + + /* submit it to deconstitution */ + ogg_stream_pagein(&os_de,&og_de); + + /* packets out? */ + while(ogg_stream_packetpeek(&os_de,&op_de2)>0){ + ogg_stream_packetpeek(&os_de,NULL); + ogg_stream_packetout(&os_de,&op_de); /* just catching them all */ + + /* verify peek and out match */ + if(memcmp(&op_de,&op_de2,sizeof(op_de))){ + fprintf(stderr,"packetout != packetpeek! pos=%ld\n", + depacket); + exit(1); + } + + /* verify the packet! */ + /* check data */ + if(memcmp(data+depacket,op_de.packet,op_de.bytes)){ + fprintf(stderr,"packet data mismatch in decode! pos=%ld\n", + depacket); + exit(1); + } + /* check bos flag */ + if(bosflag==0 && op_de.b_o_s==0){ + fprintf(stderr,"b_o_s flag not set on packet!\n"); + exit(1); + } + if(bosflag && op_de.b_o_s){ + fprintf(stderr,"b_o_s flag incorrectly set on packet!\n"); + exit(1); + } + bosflag=1; + depacket+=op_de.bytes; + + /* check eos flag */ + if(eosflag){ + fprintf(stderr,"Multiple decoded packets with eos flag!\n"); + exit(1); + } + + if(op_de.e_o_s)eosflag=1; + + /* check granulepos flag */ + if(op_de.granulepos!=-1){ + fprintf(stderr," granule:%ld ",(long)op_de.granulepos); + } + } + } + } + } + } + } + _ogg_free(data); + if(headers[pageno]!=NULL){ + fprintf(stderr,"did not write last page!\n"); + exit(1); + } + if(headers[pageout]!=NULL){ + fprintf(stderr,"did not decode last page!\n"); + exit(1); + } + if(inptr!=outptr){ + fprintf(stderr,"encoded page data incomplete!\n"); + exit(1); + } + if(inptr!=deptr){ + fprintf(stderr,"decoded page data incomplete!\n"); + exit(1); + } + if(inptr!=depacket){ + fprintf(stderr,"decoded packet data incomplete!\n"); + exit(1); + } + if(!eosflag){ + fprintf(stderr,"Never got a packet with EOS set!\n"); + exit(1); + } + fprintf(stderr,"ok.\n"); +} + +int main(void){ + + ogg_stream_init(&os_en,0x04030201); + ogg_stream_init(&os_de,0x04030201); + ogg_sync_init(&oy); + + /* Exercise each code path in the framing code. Also verify that + the checksums are working. */ + + { + /* 17 only */ + const int packets[]={17, -1}; + const int *headret[]={head1_0,NULL}; + + fprintf(stderr,"testing single page encoding... "); + test_pack(packets,headret,0,0,0); + } + + { + /* 17, 254, 255, 256, 500, 510, 600 byte, pad */ + const int packets[]={17, 254, 255, 256, 500, 510, 600, -1}; + const int *headret[]={head1_1,head2_1,NULL}; + + fprintf(stderr,"testing basic page encoding... "); + test_pack(packets,headret,0,0,0); + } + + { + /* nil packets; beginning,middle,end */ + const int packets[]={0,17, 254, 255, 0, 256, 0, 500, 510, 600, 0, -1}; + const int *headret[]={head1_2,head2_2,NULL}; + + fprintf(stderr,"testing basic nil packets... "); + test_pack(packets,headret,0,0,0); + } + + { + /* large initial packet */ + const int packets[]={4345,259,255,-1}; + const int *headret[]={head1_3,head2_3,NULL}; + + fprintf(stderr,"testing initial-packet lacing > 4k... "); + test_pack(packets,headret,0,0,0); + } + + { + /* continuing packet test */ + const int packets[]={0,4345,259,255,-1}; + const int *headret[]={head1_4,head2_4,head3_4,NULL}; + + fprintf(stderr,"testing single packet page span... "); + test_pack(packets,headret,0,0,0); + } + + /* page with the 255 segment limit */ + { + + const int packets[]={0,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,50,-1}; + const int *headret[]={head1_5,head2_5,head3_5,NULL}; + + fprintf(stderr,"testing max packet segments... "); + test_pack(packets,headret,0,0,0); + } + + { + /* packet that overspans over an entire page */ + const int packets[]={0,100,9000,259,255,-1}; + const int *headret[]={head1_6,head2_6,head3_6,head4_6,NULL}; + + fprintf(stderr,"testing very large packets... "); + test_pack(packets,headret,0,0,0); + } + + { + /* test for the libogg 1.1.1 resync in large continuation bug + found by Josh Coalson) */ + const int packets[]={0,100,9000,259,255,-1}; + const int *headret[]={head1_6,head2_6,head3_6,head4_6,NULL}; + + fprintf(stderr,"testing continuation resync in very large packets... "); + test_pack(packets,headret,100,2,3); + } + + { + /* term only page. why not? */ + const int packets[]={0,100,4080,-1}; + const int *headret[]={head1_7,head2_7,head3_7,NULL}; + + fprintf(stderr,"testing zero data page (1 nil packet)... "); + test_pack(packets,headret,0,0,0); + } + + + + { + /* build a bunch of pages for testing */ + unsigned char *data=_ogg_malloc(1024*1024); + int pl[]={0,100,4079,2956,2057,76,34,912,0,234,1000,1000,1000,300,-1}; + int inptr=0,i,j; + ogg_page og[5]; + + ogg_stream_reset(&os_en); + + for(i=0;pl[i]!=-1;i++){ + ogg_packet op; + int len=pl[i]; + + op.packet=data+inptr; + op.bytes=len; + op.e_o_s=(pl[i+1]<0?1:0); + op.granulepos=(i+1)*1000; + + for(j=0;j0)error(); + + /* Test fractional page inputs: incomplete fixed header */ + memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+3, + 20); + ogg_sync_wrote(&oy,20); + if(ogg_sync_pageout(&oy,&og_de)>0)error(); + + /* Test fractional page inputs: incomplete header */ + memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+23, + 5); + ogg_sync_wrote(&oy,5); + if(ogg_sync_pageout(&oy,&og_de)>0)error(); + + /* Test fractional page inputs: incomplete body */ + + memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+28, + og[1].header_len-28); + ogg_sync_wrote(&oy,og[1].header_len-28); + if(ogg_sync_pageout(&oy,&og_de)>0)error(); + + memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,1000); + ogg_sync_wrote(&oy,1000); + if(ogg_sync_pageout(&oy,&og_de)>0)error(); + + memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body+1000, + og[1].body_len-1000); + ogg_sync_wrote(&oy,og[1].body_len-1000); + if(ogg_sync_pageout(&oy,&og_de)<=0)error(); + + fprintf(stderr,"ok.\n"); + } + + /* Test fractional page inputs: page + incomplete capture */ + { + ogg_page og_de; + fprintf(stderr,"Testing sync on 1+partial inputs... "); + ogg_sync_reset(&oy); + + memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header, + og[1].header_len); + ogg_sync_wrote(&oy,og[1].header_len); + + memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body, + og[1].body_len); + ogg_sync_wrote(&oy,og[1].body_len); + + memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header, + 20); + ogg_sync_wrote(&oy,20); + if(ogg_sync_pageout(&oy,&og_de)<=0)error(); + if(ogg_sync_pageout(&oy,&og_de)>0)error(); + + memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+20, + og[1].header_len-20); + ogg_sync_wrote(&oy,og[1].header_len-20); + memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body, + og[1].body_len); + ogg_sync_wrote(&oy,og[1].body_len); + if(ogg_sync_pageout(&oy,&og_de)<=0)error(); + + fprintf(stderr,"ok.\n"); + } + + /* Test recapture: garbage + page */ + { + ogg_page og_de; + fprintf(stderr,"Testing search for capture... "); + ogg_sync_reset(&oy); + + /* 'garbage' */ + memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body, + og[1].body_len); + ogg_sync_wrote(&oy,og[1].body_len); + + memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header, + og[1].header_len); + ogg_sync_wrote(&oy,og[1].header_len); + + memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body, + og[1].body_len); + ogg_sync_wrote(&oy,og[1].body_len); + + memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header, + 20); + ogg_sync_wrote(&oy,20); + if(ogg_sync_pageout(&oy,&og_de)>0)error(); + if(ogg_sync_pageout(&oy,&og_de)<=0)error(); + if(ogg_sync_pageout(&oy,&og_de)>0)error(); + + memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header+20, + og[2].header_len-20); + ogg_sync_wrote(&oy,og[2].header_len-20); + memcpy(ogg_sync_buffer(&oy,og[2].body_len),og[2].body, + og[2].body_len); + ogg_sync_wrote(&oy,og[2].body_len); + if(ogg_sync_pageout(&oy,&og_de)<=0)error(); + + fprintf(stderr,"ok.\n"); + } + + /* Test recapture: page + garbage + page */ + { + ogg_page og_de; + fprintf(stderr,"Testing recapture... "); + ogg_sync_reset(&oy); + + memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header, + og[1].header_len); + ogg_sync_wrote(&oy,og[1].header_len); + + memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body, + og[1].body_len); + ogg_sync_wrote(&oy,og[1].body_len); + + memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header, + og[2].header_len); + ogg_sync_wrote(&oy,og[2].header_len); + + memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header, + og[2].header_len); + ogg_sync_wrote(&oy,og[2].header_len); + + if(ogg_sync_pageout(&oy,&og_de)<=0)error(); + + memcpy(ogg_sync_buffer(&oy,og[2].body_len),og[2].body, + og[2].body_len-5); + ogg_sync_wrote(&oy,og[2].body_len-5); + + memcpy(ogg_sync_buffer(&oy,og[3].header_len),og[3].header, + og[3].header_len); + ogg_sync_wrote(&oy,og[3].header_len); + + memcpy(ogg_sync_buffer(&oy,og[3].body_len),og[3].body, + og[3].body_len); + ogg_sync_wrote(&oy,og[3].body_len); + + if(ogg_sync_pageout(&oy,&og_de)>0)error(); + if(ogg_sync_pageout(&oy,&og_de)<=0)error(); + + fprintf(stderr,"ok.\n"); + } + + /* Free page data that was previously copied */ + { + for(i=0;i<5;i++){ + free_page(&og[i]); + } + } + } + + return(0); +} + +#endif + + + + diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/AUTHORS b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/AUTHORS new file mode 100644 index 0000000..0da1036 --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/AUTHORS @@ -0,0 +1,3 @@ +Monty + +and the rest of the Xiph.org Foundation. diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/COPYING b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/COPYING new file mode 100644 index 0000000..7cf076b --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/COPYING @@ -0,0 +1,28 @@ +Copyright (c) 2002-2004 Xiph.org Foundation + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +- Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +- Neither the name of the Xiph.org Foundation nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/README b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/README new file mode 100644 index 0000000..79178e7 --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/README @@ -0,0 +1,132 @@ +******************************************************************** +* * +* THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * +* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * +* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * +* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * +* * +* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2004 * +* by the Xiph.org Foundation, http://www.xiph.org/ * +* * +******************************************************************** + +Vorbis is a general purpose audio and music encoding format +contemporary to MPEG-4's AAC and TwinVQ, the next generation beyond +MPEG audio layer 3. Unlike the MPEG sponsored formats (and other +proprietary formats such as RealAudio G2 and Windows' flavor of the +month), the Vorbis CODEC specification belongs to the public domain. +All the technical details are published and documented, and any +software entity may make full use of the format without license +fee, royalty or patent concerns. + +This package contains: + +* libvorbis, a BSD-style license software implementation of + the Vorbis specification by the Xiph.Org Foundation + (http://www.xiph.org/) + +* libvorbisfile, a BSD-style license convenience library + built on Vorbis designed to simplify common uses + +* libvorbisenc, a BSD-style license library that provides a simple, + programmatic encoding setup interface + +* example code making use of libogg, libvorbis, libvorbisfile and + libvorbisenc + +WHAT'S HERE: + +This source distribution includes libvorbis and an example +encoder/player to demonstrate use of libvorbis as well as +documentation on the Ogg Vorbis audio coding format. + +You'll need libogg (distributed separately) to compile this library. +A more comprehensive set of utilities is available in the vorbis-tools +package. + +Directory: + +./lib The source for the libraries, a BSD-license implementation + of the public domain Ogg Vorbis audio encoding format. + +./include Library API headers + +./debian Rules/spec files for building Debian .deb packages + +./doc Vorbis documentation + +./examples Example code illustrating programmatic use of libvorbis, + libvorbisfile and libvorbisenc + +./mac Codewarrior project files and build tweaks for MacOS. + +./macosx Project files for MacOS X. + +./win32 Win32 projects files and build automation + +./vq Internal utilities for training/building new LSP/residue + and auxiliary codebooks. + +CONTACT: + +The Ogg homepage is located at 'http://www.xiph.org/ogg/'. +Vorbis's homepage is located at 'http://www.xiph.org/vorbis/'. +Up to date technical documents, contact information, source code and +pre-built utilities may be found there. + +The user website for Ogg Vorbis software and audio is http://vorbis.com/ + +BUILDING FROM TRUNK: + +Development source is under subversion revision control at +http://svn.xiph.org/trunk/vorbis/. You will also need the +newest versions of autoconf, automake, and libtool in order +to compile vorbis from development source. A configure script +is provided for you in the source tarball distributions. + + [update or checkout latest source] + ./autogen.sh + make + +and as root if desired: + + make install + +This will install the vorbis libraries (static and shared) into +/usr/local/lib, includes into /usr/local/include and API manpages +(once we write some) into /usr/local/man. + +BUILDING FROM TARBALL DISTRIBUTIONS: + + ./configure + make + +and optionally (as root): + make install + +BUILDING RPMS: + +after normal configuring: + + make dist + rpm -ta libvorbis-.tar.gz + +BUILDING ON MACOS 9: + +Vorbis on MacOS 9 is built using Metroworks CodeWarrior. To build it, +first verify that the Ogg libraries are already built following the +instructions in the Ogg module README. Open vorbis/mac/libvorbis.mcp, +switch to the "Targets" pane, select everything, and make the project. +Do the same thing to build libvorbisenc.mcp, and libvorbisfile.mcp (in +that order). In vorbis/mac/Output you will now have both debug and final +versions of Vorbis shared libraries to link your projects against. + +To build a project using Ogg Vorbis, add access paths to your +CodeWarrior project for the ogg/include, ogg/mac/Output, +vorbis/include, and vorbis/mac/Output folders. Be sure that +"interpret DOS and Unix paths" is turned on in your project; it can +be found in the "access paths" pane in your project settings. Now +simply add the shared libraries you need to your project (OggLib and +VorbisLib at least) and #include "ogg/ogg.h" and "vorbis/codec.h" +wherever you need to access Ogg and Vorbis functionality. + diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/include/vorbis/codec.h b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/include/vorbis/codec.h new file mode 100644 index 0000000..03f29bf --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/include/vorbis/codec.h @@ -0,0 +1,240 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + + ******************************************************************** + + function: libvorbis codec headers + last mod: $Id: codec.h 7485 2004-08-05 14:54:23Z thomasvs $ + + ********************************************************************/ + +#ifndef _vorbis_codec_h_ +#define _vorbis_codec_h_ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#include + +typedef struct vorbis_info{ + int version; + int channels; + long rate; + + /* The below bitrate declarations are *hints*. + Combinations of the three values carry the following implications: + + all three set to the same value: + implies a fixed rate bitstream + only nominal set: + implies a VBR stream that averages the nominal bitrate. No hard + upper/lower limit + upper and or lower set: + implies a VBR bitstream that obeys the bitrate limits. nominal + may also be set to give a nominal rate. + none set: + the coder does not care to speculate. + */ + + long bitrate_upper; + long bitrate_nominal; + long bitrate_lower; + long bitrate_window; + + void *codec_setup; +} vorbis_info; + +/* vorbis_dsp_state buffers the current vorbis audio + analysis/synthesis state. The DSP state belongs to a specific + logical bitstream ****************************************************/ +typedef struct vorbis_dsp_state{ + int analysisp; + vorbis_info *vi; + + float **pcm; + float **pcmret; + int pcm_storage; + int pcm_current; + int pcm_returned; + + int preextrapolate; + int eofflag; + + long lW; + long W; + long nW; + long centerW; + + ogg_int64_t granulepos; + ogg_int64_t sequence; + + ogg_int64_t glue_bits; + ogg_int64_t time_bits; + ogg_int64_t floor_bits; + ogg_int64_t res_bits; + + void *backend_state; +} vorbis_dsp_state; + +typedef struct vorbis_block{ + /* necessary stream state for linking to the framing abstraction */ + float **pcm; /* this is a pointer into local storage */ + oggpack_buffer opb; + + long lW; + long W; + long nW; + int pcmend; + int mode; + + int eofflag; + ogg_int64_t granulepos; + ogg_int64_t sequence; + vorbis_dsp_state *vd; /* For read-only access of configuration */ + + /* local storage to avoid remallocing; it's up to the mapping to + structure it */ + void *localstore; + long localtop; + long localalloc; + long totaluse; + struct alloc_chain *reap; + + /* bitmetrics for the frame */ + long glue_bits; + long time_bits; + long floor_bits; + long res_bits; + + void *internal; + +} vorbis_block; + +/* vorbis_block is a single block of data to be processed as part of +the analysis/synthesis stream; it belongs to a specific logical +bitstream, but is independant from other vorbis_blocks belonging to +that logical bitstream. *************************************************/ + +struct alloc_chain{ + void *ptr; + struct alloc_chain *next; +}; + +/* vorbis_info contains all the setup information specific to the + specific compression/decompression mode in progress (eg, + psychoacoustic settings, channel setup, options, codebook + etc). vorbis_info and substructures are in backends.h. +*********************************************************************/ + +/* the comments are not part of vorbis_info so that vorbis_info can be + static storage */ +typedef struct vorbis_comment{ + /* unlimited user comment fields. libvorbis writes 'libvorbis' + whatever vendor is set to in encode */ + char **user_comments; + int *comment_lengths; + int comments; + char *vendor; + +} vorbis_comment; + + +/* libvorbis encodes in two abstraction layers; first we perform DSP + and produce a packet (see docs/analysis.txt). The packet is then + coded into a framed OggSquish bitstream by the second layer (see + docs/framing.txt). Decode is the reverse process; we sync/frame + the bitstream and extract individual packets, then decode the + packet back into PCM audio. + + The extra framing/packetizing is used in streaming formats, such as + files. Over the net (such as with UDP), the framing and + packetization aren't necessary as they're provided by the transport + and the streaming layer is not used */ + +/* Vorbis PRIMITIVES: general ***************************************/ + +extern void vorbis_info_init(vorbis_info *vi); +extern void vorbis_info_clear(vorbis_info *vi); +extern int vorbis_info_blocksize(vorbis_info *vi,int zo); +extern void vorbis_comment_init(vorbis_comment *vc); +extern void vorbis_comment_add(vorbis_comment *vc, char *comment); +extern void vorbis_comment_add_tag(vorbis_comment *vc, + char *tag, char *contents); +extern char *vorbis_comment_query(vorbis_comment *vc, char *tag, int count); +extern int vorbis_comment_query_count(vorbis_comment *vc, char *tag); +extern void vorbis_comment_clear(vorbis_comment *vc); + +extern int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb); +extern int vorbis_block_clear(vorbis_block *vb); +extern void vorbis_dsp_clear(vorbis_dsp_state *v); +extern double vorbis_granule_time(vorbis_dsp_state *v, + ogg_int64_t granulepos); + +/* Vorbis PRIMITIVES: analysis/DSP layer ****************************/ + +extern int vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi); +extern int vorbis_commentheader_out(vorbis_comment *vc, ogg_packet *op); +extern int vorbis_analysis_headerout(vorbis_dsp_state *v, + vorbis_comment *vc, + ogg_packet *op, + ogg_packet *op_comm, + ogg_packet *op_code); +extern float **vorbis_analysis_buffer(vorbis_dsp_state *v,int vals); +extern int vorbis_analysis_wrote(vorbis_dsp_state *v,int vals); +extern int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb); +extern int vorbis_analysis(vorbis_block *vb,ogg_packet *op); + +extern int vorbis_bitrate_addblock(vorbis_block *vb); +extern int vorbis_bitrate_flushpacket(vorbis_dsp_state *vd, + ogg_packet *op); + +/* Vorbis PRIMITIVES: synthesis layer *******************************/ +extern int vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc, + ogg_packet *op); + +extern int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi); +extern int vorbis_synthesis_restart(vorbis_dsp_state *v); +extern int vorbis_synthesis(vorbis_block *vb,ogg_packet *op); +extern int vorbis_synthesis_trackonly(vorbis_block *vb,ogg_packet *op); +extern int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb); +extern int vorbis_synthesis_pcmout(vorbis_dsp_state *v,float ***pcm); +extern int vorbis_synthesis_lapout(vorbis_dsp_state *v,float ***pcm); +extern int vorbis_synthesis_read(vorbis_dsp_state *v,int samples); +extern long vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op); + +extern int vorbis_synthesis_halfrate(vorbis_info *v,int flag); +extern int vorbis_synthesis_halfrate_p(vorbis_info *v); + +/* Vorbis ERRORS and return codes ***********************************/ + +#define OV_FALSE -1 +#define OV_EOF -2 +#define OV_HOLE -3 + +#define OV_EREAD -128 +#define OV_EFAULT -129 +#define OV_EIMPL -130 +#define OV_EINVAL -131 +#define OV_ENOTVORBIS -132 +#define OV_EBADHEADER -133 +#define OV_EVERSION -134 +#define OV_ENOTAUDIO -135 +#define OV_EBADPACKET -136 +#define OV_EBADLINK -137 +#define OV_ENOSEEK -138 + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif + diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/include/vorbis/vorbisenc.h b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/include/vorbis/vorbisenc.h new file mode 100644 index 0000000..a60081a --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/include/vorbis/vorbisenc.h @@ -0,0 +1,112 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: vorbis encode-engine setup + last mod: $Id: vorbisenc.h 7485 2004-08-05 14:54:23Z thomasvs $ + + ********************************************************************/ + +#ifndef _OV_ENC_H_ +#define _OV_ENC_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#include "codec.h" + +extern int vorbis_encode_init(vorbis_info *vi, + long channels, + long rate, + + long max_bitrate, + long nominal_bitrate, + long min_bitrate); + +extern int vorbis_encode_setup_managed(vorbis_info *vi, + long channels, + long rate, + + long max_bitrate, + long nominal_bitrate, + long min_bitrate); + +extern int vorbis_encode_setup_vbr(vorbis_info *vi, + long channels, + long rate, + + float quality /* quality level from 0. (lo) to 1. (hi) */ + ); + +extern int vorbis_encode_init_vbr(vorbis_info *vi, + long channels, + long rate, + + float base_quality /* quality level from 0. (lo) to 1. (hi) */ + ); + +extern int vorbis_encode_setup_init(vorbis_info *vi); + +extern int vorbis_encode_ctl(vorbis_info *vi,int number,void *arg); + + /* deprecated rate management supported only for compatability */ +#define OV_ECTL_RATEMANAGE_GET 0x10 +#define OV_ECTL_RATEMANAGE_SET 0x11 +#define OV_ECTL_RATEMANAGE_AVG 0x12 +#define OV_ECTL_RATEMANAGE_HARD 0x13 + +struct ovectl_ratemanage_arg { + int management_active; + + long bitrate_hard_min; + long bitrate_hard_max; + double bitrate_hard_window; + + long bitrate_av_lo; + long bitrate_av_hi; + double bitrate_av_window; + double bitrate_av_window_center; +}; + + + /* new rate setup */ +#define OV_ECTL_RATEMANAGE2_GET 0x14 +#define OV_ECTL_RATEMANAGE2_SET 0x15 + +struct ovectl_ratemanage2_arg { + int management_active; + + long bitrate_limit_min_kbps; + long bitrate_limit_max_kbps; + long bitrate_limit_reservoir_bits; + double bitrate_limit_reservoir_bias; + + long bitrate_average_kbps; + double bitrate_average_damping; +}; + + + +#define OV_ECTL_LOWPASS_GET 0x20 +#define OV_ECTL_LOWPASS_SET 0x21 + +#define OV_ECTL_IBLOCK_GET 0x30 +#define OV_ECTL_IBLOCK_SET 0x31 + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif + + diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/include/vorbis/vorbisfile.h b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/include/vorbis/vorbisfile.h new file mode 100644 index 0000000..259fa89 --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/include/vorbis/vorbisfile.h @@ -0,0 +1,143 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: stdio-based convenience library for opening/seeking/decoding + last mod: $Id: vorbisfile.h 7485 2004-08-05 14:54:23Z thomasvs $ + + ********************************************************************/ + +#ifndef _OV_FILE_H_ +#define _OV_FILE_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#include +#include "codec.h" + +/* The function prototypes for the callbacks are basically the same as for + * the stdio functions fread, fseek, fclose, ftell. + * The one difference is that the FILE * arguments have been replaced with + * a void * - this is to be used as a pointer to whatever internal data these + * functions might need. In the stdio case, it's just a FILE * cast to a void * + * + * If you use other functions, check the docs for these functions and return + * the right values. For seek_func(), you *MUST* return -1 if the stream is + * unseekable + */ +typedef struct { + size_t (*read_func) (void *ptr, size_t size, size_t nmemb, void *datasource); + int (*seek_func) (void *datasource, ogg_int64_t offset, int whence); + int (*close_func) (void *datasource); + long (*tell_func) (void *datasource); +} ov_callbacks; + +#define NOTOPEN 0 +#define PARTOPEN 1 +#define OPENED 2 +#define STREAMSET 3 +#define INITSET 4 + +typedef struct OggVorbis_File { + void *datasource; /* Pointer to a FILE *, etc. */ + int seekable; + ogg_int64_t offset; + ogg_int64_t end; + ogg_sync_state oy; + + /* If the FILE handle isn't seekable (eg, a pipe), only the current + stream appears */ + int links; + ogg_int64_t *offsets; + ogg_int64_t *dataoffsets; + long *serialnos; + ogg_int64_t *pcmlengths; /* overloaded to maintain binary + compatability; x2 size, stores both + beginning and end values */ + vorbis_info *vi; + vorbis_comment *vc; + + /* Decoding working state local storage */ + ogg_int64_t pcm_offset; + int ready_state; + long current_serialno; + int current_link; + + double bittrack; + double samptrack; + + ogg_stream_state os; /* take physical pages, weld into a logical + stream of packets */ + vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */ + vorbis_block vb; /* local working space for packet->PCM decode */ + + ov_callbacks callbacks; + +} OggVorbis_File; + +extern int ov_clear(OggVorbis_File *vf); +extern int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes); +extern int ov_open_callbacks(void *datasource, OggVorbis_File *vf, + char *initial, long ibytes, ov_callbacks callbacks); + +extern int ov_test(FILE *f,OggVorbis_File *vf,char *initial,long ibytes); +extern int ov_test_callbacks(void *datasource, OggVorbis_File *vf, + char *initial, long ibytes, ov_callbacks callbacks); +extern int ov_test_open(OggVorbis_File *vf); + +extern long ov_bitrate(OggVorbis_File *vf,int i); +extern long ov_bitrate_instant(OggVorbis_File *vf); +extern long ov_streams(OggVorbis_File *vf); +extern long ov_seekable(OggVorbis_File *vf); +extern long ov_serialnumber(OggVorbis_File *vf,int i); + +extern ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i); +extern ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i); +extern double ov_time_total(OggVorbis_File *vf,int i); + +extern int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_time_seek(OggVorbis_File *vf,double pos); +extern int ov_time_seek_page(OggVorbis_File *vf,double pos); + +extern int ov_raw_seek_lap(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_pcm_seek_lap(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_pcm_seek_page_lap(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_time_seek_lap(OggVorbis_File *vf,double pos); +extern int ov_time_seek_page_lap(OggVorbis_File *vf,double pos); + +extern ogg_int64_t ov_raw_tell(OggVorbis_File *vf); +extern ogg_int64_t ov_pcm_tell(OggVorbis_File *vf); +extern double ov_time_tell(OggVorbis_File *vf); + +extern vorbis_info *ov_info(OggVorbis_File *vf,int link); +extern vorbis_comment *ov_comment(OggVorbis_File *vf,int link); + +extern long ov_read_float(OggVorbis_File *vf,float ***pcm_channels,int samples, + int *bitstream); +extern long ov_read(OggVorbis_File *vf,char *buffer,int length, + int bigendianp,int word,int sgned,int *bitstream); +extern int ov_crosslap(OggVorbis_File *vf1,OggVorbis_File *vf2); + +extern int ov_halfrate(OggVorbis_File *vf,int flag); +extern int ov_halfrate_p(OggVorbis_File *vf); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif + + diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/analysis.c b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/analysis.c new file mode 100644 index 0000000..950b857 --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/analysis.c @@ -0,0 +1,121 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: single-block PCM analysis mode dispatch + last mod: $Id: analysis.c 7187 2004-07-20 07:24:27Z xiphmont $ + + ********************************************************************/ + +#include +#include +#include +#include +#include "vorbis/codec.h" +#include "codec_internal.h" +#include "registry.h" +#include "scales.h" +#include "os.h" +#include "misc.h" + +int analysis_noisy=1; + +/* decides between modes, dispatches to the appropriate mapping. */ +int vorbis_analysis(vorbis_block *vb, ogg_packet *op){ + int ret,i; + vorbis_block_internal *vbi=vb->internal; + + vb->glue_bits=0; + vb->time_bits=0; + vb->floor_bits=0; + vb->res_bits=0; + + /* first things first. Make sure encode is ready */ + for(i=0;ipacketblob[i]); + + /* we only have one mapping type (0), and we let the mapping code + itself figure out what soft mode to use. This allows easier + bitrate management */ + + if((ret=_mapping_P[0]->forward(vb))) + return(ret); + + if(op){ + if(vorbis_bitrate_managed(vb)) + /* The app is using a bitmanaged mode... but not using the + bitrate management interface. */ + return(OV_EINVAL); + + op->packet=oggpack_get_buffer(&vb->opb); + op->bytes=oggpack_bytes(&vb->opb); + op->b_o_s=0; + op->e_o_s=vb->eofflag; + op->granulepos=vb->granulepos; + op->packetno=vb->sequence; /* for sake of completeness */ + } + return(0); +} + +/* there was no great place to put this.... */ +void _analysis_output_always(char *base,int i,float *v,int n,int bark,int dB,ogg_int64_t off){ + int j; + FILE *of; + char buffer[80]; + + /* if(i==5870){*/ + sprintf(buffer,"%s_%d.m",base,i); + of=fopen(buffer,"w"); + + if(!of)perror("failed to open data dump file"); + + for(j=0;j +#include "scales.h" +int main(){ + int i; + double rate; + for(i=64;i<32000;i*=2){ + rate=48000.f; + fprintf(stderr,"rate=%gHz, block=%d, f(1)=%.2gHz bark(1)=%.2g (of %.2g)\n", + rate,i,rate/2 / (i/2),toBARK(rate/2 /(i/2)),toBARK(rate/2)); + + rate=44100.f; + fprintf(stderr,"rate=%gHz, block=%d, f(1)=%.2gHz bark(1)=%.2g (of %.2g)\n", + rate,i,rate/2 / (i/2),toBARK(rate/2 /(i/2)),toBARK(rate/2)); + + rate=32000.f; + fprintf(stderr,"rate=%gHz, block=%d, f(1)=%.2gHz bark(1)=%.2g (of %.2g)\n", + rate,i,rate/2 / (i/2),toBARK(rate/2 /(i/2)),toBARK(rate/2)); + + rate=22050.f; + fprintf(stderr,"rate=%gHz, block=%d, f(1)=%.2gHz bark(1)=%.2g (of %.2g)\n", + rate,i,rate/2 / (i/2),toBARK(rate/2 /(i/2)),toBARK(rate/2)); + + rate=16000.f; + fprintf(stderr,"rate=%gHz, block=%d, f(1)=%.2gHz bark(1)=%.2g (of %.2g)\n", + rate,i,rate/2 / (i/2),toBARK(rate/2 /(i/2)),toBARK(rate/2)); + + rate=11025.f; + fprintf(stderr,"rate=%gHz, block=%d, f(1)=%.2gHz bark(1)=%.2g (of %.2g)\n", + rate,i,rate/2 / (i/2),toBARK(rate/2 /(i/2)),toBARK(rate/2)); + + rate=8000.f; + fprintf(stderr,"rate=%gHz, block=%d, f(1)=%.2gHz bark(1)=%.2g (of %.2g)\n\n", + rate,i,rate/2 / (i/2),toBARK(rate/2 /(i/2)),toBARK(rate/2)); + + + } + { + float i; + int j; + for(i=0.,j=0;i<28;i+=1,j++){ + fprintf(stderr,"(%d) bark=%f %gHz (%d of 128)\n", + j,i,fromBARK(i),(int)(fromBARK(i)/22050.*128.)); + } + } + return(0); +} + diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/bitrate.c b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/bitrate.c new file mode 100644 index 0000000..001012b --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/bitrate.c @@ -0,0 +1,253 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: bitrate tracking and management + last mod: $Id: bitrate.c 7497 2004-08-08 04:31:40Z xiphmont $ + + ********************************************************************/ + +#include +#include +#include +#include +#include "vorbis/codec.h" +#include "codec_internal.h" +#include "os.h" +#include "misc.h" +#include "bitrate.h" + +/* compute bitrate tracking setup */ +void vorbis_bitrate_init(vorbis_info *vi,bitrate_manager_state *bm){ + codec_setup_info *ci=vi->codec_setup; + bitrate_manager_info *bi=&ci->bi; + + memset(bm,0,sizeof(*bm)); + + if(bi && (bi->reservoir_bits>0)){ + long ratesamples=vi->rate; + int halfsamples=ci->blocksizes[0]>>1; + + bm->short_per_long=ci->blocksizes[1]/ci->blocksizes[0]; + bm->managed=1; + + bm->avg_bitsper= rint(1.*bi->avg_rate*halfsamples/ratesamples); + bm->min_bitsper= rint(1.*bi->min_rate*halfsamples/ratesamples); + bm->max_bitsper= rint(1.*bi->max_rate*halfsamples/ratesamples); + + bm->avgfloat=PACKETBLOBS/2; + + /* not a necessary fix, but one that leads to a more balanced + typical initialization */ + { + long desired_fill=bi->reservoir_bits*bi->reservoir_bias; + bm->minmax_reservoir=desired_fill; + bm->avg_reservoir=desired_fill; + } + + } +} + +void vorbis_bitrate_clear(bitrate_manager_state *bm){ + memset(bm,0,sizeof(*bm)); + return; +} + +int vorbis_bitrate_managed(vorbis_block *vb){ + vorbis_dsp_state *vd=vb->vd; + private_state *b=vd->backend_state; + bitrate_manager_state *bm=&b->bms; + + if(bm && bm->managed)return(1); + return(0); +} + +/* finish taking in the block we just processed */ +int vorbis_bitrate_addblock(vorbis_block *vb){ + vorbis_block_internal *vbi=vb->internal; + vorbis_dsp_state *vd=vb->vd; + private_state *b=vd->backend_state; + bitrate_manager_state *bm=&b->bms; + vorbis_info *vi=vd->vi; + codec_setup_info *ci=vi->codec_setup; + bitrate_manager_info *bi=&ci->bi; + + int choice=rint(bm->avgfloat); + long this_bits=oggpack_bytes(vbi->packetblob[choice])*8; + long min_target_bits=(vb->W?bm->min_bitsper*bm->short_per_long:bm->min_bitsper); + long max_target_bits=(vb->W?bm->max_bitsper*bm->short_per_long:bm->max_bitsper); + int samples=ci->blocksizes[vb->W]>>1; + long desired_fill=bi->reservoir_bits*bi->reservoir_bias; + if(!bm->managed){ + /* not a bitrate managed stream, but for API simplicity, we'll + buffer the packet to keep the code path clean */ + + if(bm->vb)return(-1); /* one has been submitted without + being claimed */ + bm->vb=vb; + return(0); + } + + bm->vb=vb; + + /* look ahead for avg floater */ + if(bm->avg_bitsper>0){ + double slew=0.; + long avg_target_bits=(vb->W?bm->avg_bitsper*bm->short_per_long:bm->avg_bitsper); + double slewlimit= 15./bi->slew_damp; + + /* choosing a new floater: + if we're over target, we slew down + if we're under target, we slew up + + choose slew as follows: look through packetblobs of this frame + and set slew as the first in the appropriate direction that + gives us the slew we want. This may mean no slew if delta is + already favorable. + + Then limit slew to slew max */ + + if(bm->avg_reservoir+(this_bits-avg_target_bits)>desired_fill){ + while(choice>0 && this_bits>avg_target_bits && + bm->avg_reservoir+(this_bits-avg_target_bits)>desired_fill){ + choice--; + this_bits=oggpack_bytes(vbi->packetblob[choice])*8; + } + }else if(bm->avg_reservoir+(this_bits-avg_target_bits)avg_reservoir+(this_bits-avg_target_bits)packetblob[choice])*8; + } + } + + slew=rint(choice-bm->avgfloat)/samples*vi->rate; + if(slew<-slewlimit)slew=-slewlimit; + if(slew>slewlimit)slew=slewlimit; + choice=rint(bm->avgfloat+= slew/vi->rate*samples); + this_bits=oggpack_bytes(vbi->packetblob[choice])*8; + } + + + + /* enforce min(if used) on the current floater (if used) */ + if(bm->min_bitsper>0){ + /* do we need to force the bitrate up? */ + if(this_bitsminmax_reservoir-(min_target_bits-this_bits)<0){ + choice++; + if(choice>=PACKETBLOBS)break; + this_bits=oggpack_bytes(vbi->packetblob[choice])*8; + } + } + } + + /* enforce max (if used) on the current floater (if used) */ + if(bm->max_bitsper>0){ + /* do we need to force the bitrate down? */ + if(this_bits>max_target_bits){ + while(bm->minmax_reservoir+(this_bits-max_target_bits)>bi->reservoir_bits){ + choice--; + if(choice<0)break; + this_bits=oggpack_bytes(vbi->packetblob[choice])*8; + } + } + } + + /* Choice of packetblobs now made based on floater, and min/max + requirements. Now boundary check extreme choices */ + + if(choice<0){ + /* choosing a smaller packetblob is insufficient to trim bitrate. + frame will need to be truncated */ + long maxsize=(max_target_bits+(bi->reservoir_bits-bm->minmax_reservoir))/8; + bm->choice=choice=0; + + if(oggpack_bytes(vbi->packetblob[choice])>maxsize){ + + oggpack_writetrunc(vbi->packetblob[choice],maxsize*8); + this_bits=oggpack_bytes(vbi->packetblob[choice])*8; + } + }else{ + long minsize=(min_target_bits-bm->minmax_reservoir+7)/8; + if(choice>=PACKETBLOBS) + choice=PACKETBLOBS-1; + + bm->choice=choice; + + /* prop up bitrate according to demand. pad this frame out with zeroes */ + minsize-=oggpack_bytes(vbi->packetblob[choice]); + while(minsize-->0)oggpack_write(vbi->packetblob[choice],0,8); + this_bits=oggpack_bytes(vbi->packetblob[choice])*8; + + } + + /* now we have the final packet and the final packet size. Update statistics */ + /* min and max reservoir */ + if(bm->min_bitsper>0 || bm->max_bitsper>0){ + + if(max_target_bits>0 && this_bits>max_target_bits){ + bm->minmax_reservoir+=(this_bits-max_target_bits); + }else if(min_target_bits>0 && this_bitsminmax_reservoir+=(this_bits-min_target_bits); + }else{ + /* inbetween; we want to take reservoir toward but not past desired_fill */ + if(bm->minmax_reservoir>desired_fill){ + if(max_target_bits>0){ /* logical bulletproofing against initialization state */ + bm->minmax_reservoir+=(this_bits-max_target_bits); + if(bm->minmax_reservoirminmax_reservoir=desired_fill; + }else{ + bm->minmax_reservoir=desired_fill; + } + }else{ + if(min_target_bits>0){ /* logical bulletproofing against initialization state */ + bm->minmax_reservoir+=(this_bits-min_target_bits); + if(bm->minmax_reservoir>desired_fill)bm->minmax_reservoir=desired_fill; + }else{ + bm->minmax_reservoir=desired_fill; + } + } + } + } + + /* avg reservoir */ + if(bm->avg_bitsper>0){ + long avg_target_bits=(vb->W?bm->avg_bitsper*bm->short_per_long:bm->avg_bitsper); + bm->avg_reservoir+=this_bits-avg_target_bits; + } + + return(0); +} + +int vorbis_bitrate_flushpacket(vorbis_dsp_state *vd,ogg_packet *op){ + private_state *b=vd->backend_state; + bitrate_manager_state *bm=&b->bms; + vorbis_block *vb=bm->vb; + int choice=PACKETBLOBS/2; + if(!vb)return 0; + + if(op){ + vorbis_block_internal *vbi=vb->internal; + + if(vorbis_bitrate_managed(vb)) + choice=bm->choice; + + op->packet=oggpack_get_buffer(vbi->packetblob[choice]); + op->bytes=oggpack_bytes(vbi->packetblob[choice]); + op->b_o_s=0; + op->e_o_s=vb->eofflag; + op->granulepos=vb->granulepos; + op->packetno=vb->sequence; /* for sake of completeness */ + } + + bm->vb=0; + return(1); +} diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/bitrate.h b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/bitrate.h new file mode 100644 index 0000000..dfa1be7 --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/bitrate.h @@ -0,0 +1,59 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: bitrate tracking and management + last mod: $Id: bitrate.h 7187 2004-07-20 07:24:27Z xiphmont $ + + ********************************************************************/ + +#ifndef _V_BITRATE_H_ +#define _V_BITRATE_H_ + +#include "vorbis/codec.h" +#include "codec_internal.h" +#include "os.h" + +/* encode side bitrate tracking */ +typedef struct bitrate_manager_state { + int managed; + + long avg_reservoir; + long minmax_reservoir; + long avg_bitsper; + long min_bitsper; + long max_bitsper; + + long short_per_long; + double avgfloat; + + vorbis_block *vb; + int choice; +} bitrate_manager_state; + +typedef struct bitrate_manager_info{ + long avg_rate; + long min_rate; + long max_rate; + long reservoir_bits; + double reservoir_bias; + + double slew_damp; + +} bitrate_manager_info; + +extern void vorbis_bitrate_init(vorbis_info *vi,bitrate_manager_state *bs); +extern void vorbis_bitrate_clear(bitrate_manager_state *bs); +extern int vorbis_bitrate_managed(vorbis_block *vb); +extern int vorbis_bitrate_addblock(vorbis_block *vb); +extern int vorbis_bitrate_flushpacket(vorbis_dsp_state *vd, ogg_packet *op); + +#endif diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/block.c b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/block.c new file mode 100644 index 0000000..8619d9b --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/block.c @@ -0,0 +1,989 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2003 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: PCM data vector blocking, windowing and dis/reassembly + last mod: $Id: block.c 9513 2005-06-26 18:36:49Z giles $ + + Handle windowing, overlap-add, etc of the PCM vectors. This is made + more amusing by Vorbis' current two allowed block sizes. + + ********************************************************************/ + +#include +#include +#include +#include +#include "vorbis/codec.h" +#include "codec_internal.h" + +#include "window.h" +#include "mdct.h" +#include "lpc.h" +#include "registry.h" +#include "misc.h" + +static int ilog2(unsigned int v){ + int ret=0; + if(v)--v; + while(v){ + ret++; + v>>=1; + } + return(ret); +} + +/* pcm accumulator examples (not exhaustive): + + <-------------- lW ----------------> + <--------------- W ----------------> +: .....|..... _______________ | +: .''' | '''_--- | |\ | +:.....''' |_____--- '''......| | \_______| +:.................|__________________|_______|__|______| + |<------ Sl ------>| > Sr < |endW + |beginSl |endSl | |endSr + |beginW |endlW |beginSr + + + |< lW >| + <--------------- W ----------------> + | | .. ______________ | + | | ' `/ | ---_ | + |___.'___/`. | ---_____| + |_______|__|_______|_________________| + | >|Sl|< |<------ Sr ----->|endW + | | |endSl |beginSr |endSr + |beginW | |endlW + mult[0] |beginSl mult[n] + + <-------------- lW -----------------> + |<--W-->| +: .............. ___ | | +: .''' |`/ \ | | +:.....''' |/`....\|...| +:.........................|___|___|___| + |Sl |Sr |endW + | | |endSr + | |beginSr + | |endSl + |beginSl + |beginW +*/ + +/* block abstraction setup *********************************************/ + +#ifndef WORD_ALIGN +#define WORD_ALIGN 8 +#endif + +int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb){ + int i; + memset(vb,0,sizeof(*vb)); + vb->vd=v; + vb->localalloc=0; + vb->localstore=NULL; + if(v->analysisp){ + vorbis_block_internal *vbi= + vb->internal=_ogg_calloc(1,sizeof(vorbis_block_internal)); + vbi->ampmax=-9999; + + for(i=0;ipacketblob[i]=&vb->opb; + }else{ + vbi->packetblob[i]= + _ogg_calloc(1,sizeof(oggpack_buffer)); + } + oggpack_writeinit(vbi->packetblob[i]); + } + } + + return(0); +} + +void *_vorbis_block_alloc(vorbis_block *vb,long bytes){ + bytes=(bytes+(WORD_ALIGN-1)) & ~(WORD_ALIGN-1); + if(bytes+vb->localtop>vb->localalloc){ + /* can't just _ogg_realloc... there are outstanding pointers */ + if(vb->localstore){ + struct alloc_chain *link=_ogg_malloc(sizeof(*link)); + vb->totaluse+=vb->localtop; + link->next=vb->reap; + link->ptr=vb->localstore; + vb->reap=link; + } + /* highly conservative */ + vb->localalloc=bytes; + vb->localstore=_ogg_malloc(vb->localalloc); + vb->localtop=0; + } + { + void *ret=(void *)(((char *)vb->localstore)+vb->localtop); + vb->localtop+=bytes; + return ret; + } +} + +/* reap the chain, pull the ripcord */ +void _vorbis_block_ripcord(vorbis_block *vb){ + /* reap the chain */ + struct alloc_chain *reap=vb->reap; + while(reap){ + struct alloc_chain *next=reap->next; + _ogg_free(reap->ptr); + memset(reap,0,sizeof(*reap)); + _ogg_free(reap); + reap=next; + } + /* consolidate storage */ + if(vb->totaluse){ + vb->localstore=_ogg_realloc(vb->localstore,vb->totaluse+vb->localalloc); + vb->localalloc+=vb->totaluse; + vb->totaluse=0; + } + + /* pull the ripcord */ + vb->localtop=0; + vb->reap=NULL; +} + +int vorbis_block_clear(vorbis_block *vb){ + int i; + vorbis_block_internal *vbi=vb->internal; + + _vorbis_block_ripcord(vb); + if(vb->localstore)_ogg_free(vb->localstore); + + if(vbi){ + for(i=0;ipacketblob[i]); + if(i!=PACKETBLOBS/2)_ogg_free(vbi->packetblob[i]); + } + _ogg_free(vbi); + } + memset(vb,0,sizeof(*vb)); + return(0); +} + +/* Analysis side code, but directly related to blocking. Thus it's + here and not in analysis.c (which is for analysis transforms only). + The init is here because some of it is shared */ + +static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi,int encp){ + int i; + codec_setup_info *ci=vi->codec_setup; + private_state *b=NULL; + int hs; + + if(ci==NULL) return 1; + hs=ci->halfrate_flag; + + memset(v,0,sizeof(*v)); + b=v->backend_state=_ogg_calloc(1,sizeof(*b)); + + v->vi=vi; + b->modebits=ilog2(ci->modes); + + b->transform[0]=_ogg_calloc(VI_TRANSFORMB,sizeof(*b->transform[0])); + b->transform[1]=_ogg_calloc(VI_TRANSFORMB,sizeof(*b->transform[1])); + + /* MDCT is tranform 0 */ + + b->transform[0][0]=_ogg_calloc(1,sizeof(mdct_lookup)); + b->transform[1][0]=_ogg_calloc(1,sizeof(mdct_lookup)); + mdct_init(b->transform[0][0],ci->blocksizes[0]>>hs); + mdct_init(b->transform[1][0],ci->blocksizes[1]>>hs); + + /* Vorbis I uses only window type 0 */ + b->window[0]=ilog2(ci->blocksizes[0])-6; + b->window[1]=ilog2(ci->blocksizes[1])-6; + + if(encp){ /* encode/decode differ here */ + + /* analysis always needs an fft */ + drft_init(&b->fft_look[0],ci->blocksizes[0]); + drft_init(&b->fft_look[1],ci->blocksizes[1]); + + /* finish the codebooks */ + if(!ci->fullbooks){ + ci->fullbooks=_ogg_calloc(ci->books,sizeof(*ci->fullbooks)); + for(i=0;ibooks;i++) + vorbis_book_init_encode(ci->fullbooks+i,ci->book_param[i]); + } + + b->psy=_ogg_calloc(ci->psys,sizeof(*b->psy)); + for(i=0;ipsys;i++){ + _vp_psy_init(b->psy+i, + ci->psy_param[i], + &ci->psy_g_param, + ci->blocksizes[ci->psy_param[i]->blockflag]/2, + vi->rate); + } + + v->analysisp=1; + }else{ + /* finish the codebooks */ + if(!ci->fullbooks){ + ci->fullbooks=_ogg_calloc(ci->books,sizeof(*ci->fullbooks)); + for(i=0;ibooks;i++){ + vorbis_book_init_decode(ci->fullbooks+i,ci->book_param[i]); + /* decode codebooks are now standalone after init */ + vorbis_staticbook_destroy(ci->book_param[i]); + ci->book_param[i]=NULL; + } + } + } + + /* initialize the storage vectors. blocksize[1] is small for encode, + but the correct size for decode */ + v->pcm_storage=ci->blocksizes[1]; + v->pcm=_ogg_malloc(vi->channels*sizeof(*v->pcm)); + v->pcmret=_ogg_malloc(vi->channels*sizeof(*v->pcmret)); + { + int i; + for(i=0;ichannels;i++) + v->pcm[i]=_ogg_calloc(v->pcm_storage,sizeof(*v->pcm[i])); + } + + /* all 1 (large block) or 0 (small block) */ + /* explicitly set for the sake of clarity */ + v->lW=0; /* previous window size */ + v->W=0; /* current window size */ + + /* all vector indexes */ + v->centerW=ci->blocksizes[1]/2; + + v->pcm_current=v->centerW; + + /* initialize all the backend lookups */ + b->flr=_ogg_calloc(ci->floors,sizeof(*b->flr)); + b->residue=_ogg_calloc(ci->residues,sizeof(*b->residue)); + + for(i=0;ifloors;i++) + b->flr[i]=_floor_P[ci->floor_type[i]]-> + look(v,ci->floor_param[i]); + + for(i=0;iresidues;i++) + b->residue[i]=_residue_P[ci->residue_type[i]]-> + look(v,ci->residue_param[i]); + + return 0; +} + +/* arbitrary settings and spec-mandated numbers get filled in here */ +int vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi){ + private_state *b=NULL; + + if(_vds_shared_init(v,vi,1))return 1; + b=v->backend_state; + b->psy_g_look=_vp_global_look(vi); + + /* Initialize the envelope state storage */ + b->ve=_ogg_calloc(1,sizeof(*b->ve)); + _ve_envelope_init(b->ve,vi); + + vorbis_bitrate_init(vi,&b->bms); + + /* compressed audio packets start after the headers + with sequence number 3 */ + v->sequence=3; + + return(0); +} + +void vorbis_dsp_clear(vorbis_dsp_state *v){ + int i; + if(v){ + vorbis_info *vi=v->vi; + codec_setup_info *ci=(vi?vi->codec_setup:NULL); + private_state *b=v->backend_state; + + if(b){ + + if(b->ve){ + _ve_envelope_clear(b->ve); + _ogg_free(b->ve); + } + + if(b->transform[0]){ + mdct_clear(b->transform[0][0]); + _ogg_free(b->transform[0][0]); + _ogg_free(b->transform[0]); + } + if(b->transform[1]){ + mdct_clear(b->transform[1][0]); + _ogg_free(b->transform[1][0]); + _ogg_free(b->transform[1]); + } + + if(b->flr){ + for(i=0;ifloors;i++) + _floor_P[ci->floor_type[i]]-> + free_look(b->flr[i]); + _ogg_free(b->flr); + } + if(b->residue){ + for(i=0;iresidues;i++) + _residue_P[ci->residue_type[i]]-> + free_look(b->residue[i]); + _ogg_free(b->residue); + } + if(b->psy){ + for(i=0;ipsys;i++) + _vp_psy_clear(b->psy+i); + _ogg_free(b->psy); + } + + if(b->psy_g_look)_vp_global_free(b->psy_g_look); + vorbis_bitrate_clear(&b->bms); + + drft_clear(&b->fft_look[0]); + drft_clear(&b->fft_look[1]); + + } + + if(v->pcm){ + for(i=0;ichannels;i++) + if(v->pcm[i])_ogg_free(v->pcm[i]); + _ogg_free(v->pcm); + if(v->pcmret)_ogg_free(v->pcmret); + } + + if(b){ + /* free header, header1, header2 */ + if(b->header)_ogg_free(b->header); + if(b->header1)_ogg_free(b->header1); + if(b->header2)_ogg_free(b->header2); + _ogg_free(b); + } + + memset(v,0,sizeof(*v)); + } +} + +float **vorbis_analysis_buffer(vorbis_dsp_state *v, int vals){ + int i; + vorbis_info *vi=v->vi; + private_state *b=v->backend_state; + + /* free header, header1, header2 */ + if(b->header)_ogg_free(b->header);b->header=NULL; + if(b->header1)_ogg_free(b->header1);b->header1=NULL; + if(b->header2)_ogg_free(b->header2);b->header2=NULL; + + /* Do we have enough storage space for the requested buffer? If not, + expand the PCM (and envelope) storage */ + + if(v->pcm_current+vals>=v->pcm_storage){ + v->pcm_storage=v->pcm_current+vals*2; + + for(i=0;ichannels;i++){ + v->pcm[i]=_ogg_realloc(v->pcm[i],v->pcm_storage*sizeof(*v->pcm[i])); + } + } + + for(i=0;ichannels;i++) + v->pcmret[i]=v->pcm[i]+v->pcm_current; + + return(v->pcmret); +} + +static void _preextrapolate_helper(vorbis_dsp_state *v){ + int i; + int order=32; + float *lpc=alloca(order*sizeof(*lpc)); + float *work=alloca(v->pcm_current*sizeof(*work)); + long j; + v->preextrapolate=1; + + if(v->pcm_current-v->centerW>order*2){ /* safety */ + for(i=0;ivi->channels;i++){ + /* need to run the extrapolation in reverse! */ + for(j=0;jpcm_current;j++) + work[j]=v->pcm[i][v->pcm_current-j-1]; + + /* prime as above */ + vorbis_lpc_from_data(work,lpc,v->pcm_current-v->centerW,order); + + /* run the predictor filter */ + vorbis_lpc_predict(lpc,work+v->pcm_current-v->centerW-order, + order, + work+v->pcm_current-v->centerW, + v->centerW); + + for(j=0;jpcm_current;j++) + v->pcm[i][v->pcm_current-j-1]=work[j]; + + } + } +} + + +/* call with val<=0 to set eof */ + +int vorbis_analysis_wrote(vorbis_dsp_state *v, int vals){ + vorbis_info *vi=v->vi; + codec_setup_info *ci=vi->codec_setup; + + if(vals<=0){ + int order=32; + int i; + float *lpc=alloca(order*sizeof(*lpc)); + + /* if it wasn't done earlier (very short sample) */ + if(!v->preextrapolate) + _preextrapolate_helper(v); + + /* We're encoding the end of the stream. Just make sure we have + [at least] a few full blocks of zeroes at the end. */ + /* actually, we don't want zeroes; that could drop a large + amplitude off a cliff, creating spread spectrum noise that will + suck to encode. Extrapolate for the sake of cleanliness. */ + + vorbis_analysis_buffer(v,ci->blocksizes[1]*3); + v->eofflag=v->pcm_current; + v->pcm_current+=ci->blocksizes[1]*3; + + for(i=0;ichannels;i++){ + if(v->eofflag>order*2){ + /* extrapolate with LPC to fill in */ + long n; + + /* make a predictor filter */ + n=v->eofflag; + if(n>ci->blocksizes[1])n=ci->blocksizes[1]; + vorbis_lpc_from_data(v->pcm[i]+v->eofflag-n,lpc,n,order); + + /* run the predictor filter */ + vorbis_lpc_predict(lpc,v->pcm[i]+v->eofflag-order,order, + v->pcm[i]+v->eofflag,v->pcm_current-v->eofflag); + }else{ + /* not enough data to extrapolate (unlikely to happen due to + guarding the overlap, but bulletproof in case that + assumtion goes away). zeroes will do. */ + memset(v->pcm[i]+v->eofflag,0, + (v->pcm_current-v->eofflag)*sizeof(*v->pcm[i])); + + } + } + }else{ + + if(v->pcm_current+vals>v->pcm_storage) + return(OV_EINVAL); + + v->pcm_current+=vals; + + /* we may want to reverse extrapolate the beginning of a stream + too... in case we're beginning on a cliff! */ + /* clumsy, but simple. It only runs once, so simple is good. */ + if(!v->preextrapolate && v->pcm_current-v->centerW>ci->blocksizes[1]) + _preextrapolate_helper(v); + + } + return(0); +} + +/* do the deltas, envelope shaping, pre-echo and determine the size of + the next block on which to continue analysis */ +int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb){ + int i; + vorbis_info *vi=v->vi; + codec_setup_info *ci=vi->codec_setup; + private_state *b=v->backend_state; + vorbis_look_psy_global *g=b->psy_g_look; + long beginW=v->centerW-ci->blocksizes[v->W]/2,centerNext; + vorbis_block_internal *vbi=(vorbis_block_internal *)vb->internal; + + /* check to see if we're started... */ + if(!v->preextrapolate)return(0); + + /* check to see if we're done... */ + if(v->eofflag==-1)return(0); + + /* By our invariant, we have lW, W and centerW set. Search for + the next boundary so we can determine nW (the next window size) + which lets us compute the shape of the current block's window */ + + /* we do an envelope search even on a single blocksize; we may still + be throwing more bits at impulses, and envelope search handles + marking impulses too. */ + { + long bp=_ve_envelope_search(v); + if(bp==-1){ + + if(v->eofflag==0)return(0); /* not enough data currently to search for a + full long block */ + v->nW=0; + }else{ + + if(ci->blocksizes[0]==ci->blocksizes[1]) + v->nW=0; + else + v->nW=bp; + } + } + + centerNext=v->centerW+ci->blocksizes[v->W]/4+ci->blocksizes[v->nW]/4; + + { + /* center of next block + next block maximum right side. */ + + long blockbound=centerNext+ci->blocksizes[v->nW]/2; + if(v->pcm_currentlW=v->lW; + vb->W=v->W; + vb->nW=v->nW; + + if(v->W){ + if(!v->lW || !v->nW){ + vbi->blocktype=BLOCKTYPE_TRANSITION; + /*fprintf(stderr,"-");*/ + }else{ + vbi->blocktype=BLOCKTYPE_LONG; + /*fprintf(stderr,"_");*/ + } + }else{ + if(_ve_envelope_mark(v)){ + vbi->blocktype=BLOCKTYPE_IMPULSE; + /*fprintf(stderr,"|");*/ + + }else{ + vbi->blocktype=BLOCKTYPE_PADDING; + /*fprintf(stderr,".");*/ + + } + } + + vb->vd=v; + vb->sequence=v->sequence++; + vb->granulepos=v->granulepos; + vb->pcmend=ci->blocksizes[v->W]; + + /* copy the vectors; this uses the local storage in vb */ + + /* this tracks 'strongest peak' for later psychoacoustics */ + /* moved to the global psy state; clean this mess up */ + if(vbi->ampmax>g->ampmax)g->ampmax=vbi->ampmax; + g->ampmax=_vp_ampmax_decay(g->ampmax,v); + vbi->ampmax=g->ampmax; + + vb->pcm=_vorbis_block_alloc(vb,sizeof(*vb->pcm)*vi->channels); + vbi->pcmdelay=_vorbis_block_alloc(vb,sizeof(*vbi->pcmdelay)*vi->channels); + for(i=0;ichannels;i++){ + vbi->pcmdelay[i]= + _vorbis_block_alloc(vb,(vb->pcmend+beginW)*sizeof(*vbi->pcmdelay[i])); + memcpy(vbi->pcmdelay[i],v->pcm[i],(vb->pcmend+beginW)*sizeof(*vbi->pcmdelay[i])); + vb->pcm[i]=vbi->pcmdelay[i]+beginW; + + /* before we added the delay + vb->pcm[i]=_vorbis_block_alloc(vb,vb->pcmend*sizeof(*vb->pcm[i])); + memcpy(vb->pcm[i],v->pcm[i]+beginW,ci->blocksizes[v->W]*sizeof(*vb->pcm[i])); + */ + + } + + /* handle eof detection: eof==0 means that we've not yet received EOF + eof>0 marks the last 'real' sample in pcm[] + eof<0 'no more to do'; doesn't get here */ + + if(v->eofflag){ + if(v->centerW>=v->eofflag){ + v->eofflag=-1; + vb->eofflag=1; + return(1); + } + } + + /* advance storage vectors and clean up */ + { + int new_centerNext=ci->blocksizes[1]/2; + int movementW=centerNext-new_centerNext; + + if(movementW>0){ + + _ve_envelope_shift(b->ve,movementW); + v->pcm_current-=movementW; + + for(i=0;ichannels;i++) + memmove(v->pcm[i],v->pcm[i]+movementW, + v->pcm_current*sizeof(*v->pcm[i])); + + + v->lW=v->W; + v->W=v->nW; + v->centerW=new_centerNext; + + if(v->eofflag){ + v->eofflag-=movementW; + if(v->eofflag<=0)v->eofflag=-1; + /* do not add padding to end of stream! */ + if(v->centerW>=v->eofflag){ + v->granulepos+=movementW-(v->centerW-v->eofflag); + }else{ + v->granulepos+=movementW; + } + }else{ + v->granulepos+=movementW; + } + } + } + + /* done */ + return(1); +} + +int vorbis_synthesis_restart(vorbis_dsp_state *v){ + vorbis_info *vi=v->vi; + codec_setup_info *ci; + int hs; + + if(!v->backend_state)return -1; + if(!vi)return -1; + ci=vi->codec_setup; + if(!ci)return -1; + hs=ci->halfrate_flag; + + v->centerW=ci->blocksizes[1]>>(hs+1); + v->pcm_current=v->centerW>>hs; + + v->pcm_returned=-1; + v->granulepos=-1; + v->sequence=-1; + v->eofflag=0; + ((private_state *)(v->backend_state))->sample_count=-1; + + return(0); +} + +int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){ + if(_vds_shared_init(v,vi,0)) return 1; + vorbis_synthesis_restart(v); + + return 0; +} + +/* Unlike in analysis, the window is only partially applied for each + block. The time domain envelope is not yet handled at the point of + calling (as it relies on the previous block). */ + +int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){ + vorbis_info *vi=v->vi; + codec_setup_info *ci=vi->codec_setup; + private_state *b=v->backend_state; + int hs=ci->halfrate_flag; + int i,j; + + if(!vb)return(OV_EINVAL); + if(v->pcm_current>v->pcm_returned && v->pcm_returned!=-1)return(OV_EINVAL); + + v->lW=v->W; + v->W=vb->W; + v->nW=-1; + + if((v->sequence==-1)|| + (v->sequence+1 != vb->sequence)){ + v->granulepos=-1; /* out of sequence; lose count */ + b->sample_count=-1; + } + + v->sequence=vb->sequence; + + if(vb->pcm){ /* no pcm to process if vorbis_synthesis_trackonly + was called on block */ + int n=ci->blocksizes[v->W]>>(hs+1); + int n0=ci->blocksizes[0]>>(hs+1); + int n1=ci->blocksizes[1]>>(hs+1); + + int thisCenter; + int prevCenter; + + v->glue_bits+=vb->glue_bits; + v->time_bits+=vb->time_bits; + v->floor_bits+=vb->floor_bits; + v->res_bits+=vb->res_bits; + + if(v->centerW){ + thisCenter=n1; + prevCenter=0; + }else{ + thisCenter=0; + prevCenter=n1; + } + + /* v->pcm is now used like a two-stage double buffer. We don't want + to have to constantly shift *or* adjust memory usage. Don't + accept a new block until the old is shifted out */ + + for(j=0;jchannels;j++){ + /* the overlap/add section */ + if(v->lW){ + if(v->W){ + /* large/large */ + float *w=_vorbis_window_get(b->window[1]-hs); + float *pcm=v->pcm[j]+prevCenter; + float *p=vb->pcm[j]; + for(i=0;iwindow[0]-hs); + float *pcm=v->pcm[j]+prevCenter+n1/2-n0/2; + float *p=vb->pcm[j]; + for(i=0;iW){ + /* small/large */ + float *w=_vorbis_window_get(b->window[0]-hs); + float *pcm=v->pcm[j]+prevCenter; + float *p=vb->pcm[j]+n1/2-n0/2; + for(i=0;iwindow[0]-hs); + float *pcm=v->pcm[j]+prevCenter; + float *p=vb->pcm[j]; + for(i=0;ipcm[j]+thisCenter; + float *p=vb->pcm[j]+n; + for(i=0;icenterW) + v->centerW=0; + else + v->centerW=n1; + + /* deal with initial packet state; we do this using the explicit + pcm_returned==-1 flag otherwise we're sensitive to first block + being short or long */ + + if(v->pcm_returned==-1){ + v->pcm_returned=thisCenter; + v->pcm_current=thisCenter; + }else{ + v->pcm_returned=prevCenter; + v->pcm_current=prevCenter+ + ((ci->blocksizes[v->lW]/4+ + ci->blocksizes[v->W]/4)>>hs); + } + + } + + /* track the frame number... This is for convenience, but also + making sure our last packet doesn't end with added padding. If + the last packet is partial, the number of samples we'll have to + return will be past the vb->granulepos. + + This is not foolproof! It will be confused if we begin + decoding at the last page after a seek or hole. In that case, + we don't have a starting point to judge where the last frame + is. For this reason, vorbisfile will always try to make sure + it reads the last two marked pages in proper sequence */ + + if(b->sample_count==-1){ + b->sample_count=0; + }else{ + b->sample_count+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4; + } + + if(v->granulepos==-1){ + if(vb->granulepos!=-1){ /* only set if we have a position to set to */ + + v->granulepos=vb->granulepos; + + /* is this a short page? */ + if(b->sample_count>v->granulepos){ + /* corner case; if this is both the first and last audio page, + then spec says the end is cut, not beginning */ + if(vb->eofflag){ + /* trim the end */ + /* no preceeding granulepos; assume we started at zero (we'd + have to in a short single-page stream) */ + /* granulepos could be -1 due to a seek, but that would result + in a long count, not short count */ + + v->pcm_current-=(b->sample_count-v->granulepos)>>hs; + }else{ + /* trim the beginning */ + v->pcm_returned+=(b->sample_count-v->granulepos)>>hs; + if(v->pcm_returned>v->pcm_current) + v->pcm_returned=v->pcm_current; + } + + } + + } + }else{ + v->granulepos+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4; + if(vb->granulepos!=-1 && v->granulepos!=vb->granulepos){ + + if(v->granulepos>vb->granulepos){ + long extra=v->granulepos-vb->granulepos; + + if(extra) + if(vb->eofflag){ + /* partial last frame. Strip the extra samples off */ + v->pcm_current-=extra>>hs; + } /* else {Shouldn't happen *unless* the bitstream is out of + spec. Either way, believe the bitstream } */ + } /* else {Shouldn't happen *unless* the bitstream is out of + spec. Either way, believe the bitstream } */ + v->granulepos=vb->granulepos; + } + } + + /* Update, cleanup */ + + if(vb->eofflag)v->eofflag=1; + return(0); + +} + +/* pcm==NULL indicates we just want the pending samples, no more */ +int vorbis_synthesis_pcmout(vorbis_dsp_state *v,float ***pcm){ + vorbis_info *vi=v->vi; + + if(v->pcm_returned>-1 && v->pcm_returnedpcm_current){ + if(pcm){ + int i; + for(i=0;ichannels;i++) + v->pcmret[i]=v->pcm[i]+v->pcm_returned; + *pcm=v->pcmret; + } + return(v->pcm_current-v->pcm_returned); + } + return(0); +} + +int vorbis_synthesis_read(vorbis_dsp_state *v,int n){ + if(n && v->pcm_returned+n>v->pcm_current)return(OV_EINVAL); + v->pcm_returned+=n; + return(0); +} + +/* intended for use with a specific vorbisfile feature; we want access + to the [usually synthetic/postextrapolated] buffer and lapping at + the end of a decode cycle, specifically, a half-short-block worth. + This funtion works like pcmout above, except it will also expose + this implicit buffer data not normally decoded. */ +int vorbis_synthesis_lapout(vorbis_dsp_state *v,float ***pcm){ + vorbis_info *vi=v->vi; + codec_setup_info *ci=vi->codec_setup; + int hs=ci->halfrate_flag; + + int n=ci->blocksizes[v->W]>>(hs+1); + int n0=ci->blocksizes[0]>>(hs+1); + int n1=ci->blocksizes[1]>>(hs+1); + int i,j; + + if(v->pcm_returned<0)return 0; + + /* our returned data ends at pcm_returned; because the synthesis pcm + buffer is a two-fragment ring, that means our data block may be + fragmented by buffering, wrapping or a short block not filling + out a buffer. To simplify things, we unfragment if it's at all + possibly needed. Otherwise, we'd need to call lapout more than + once as well as hold additional dsp state. Opt for + simplicity. */ + + /* centerW was advanced by blockin; it would be the center of the + *next* block */ + if(v->centerW==n1){ + /* the data buffer wraps; swap the halves */ + /* slow, sure, small */ + for(j=0;jchannels;j++){ + float *p=v->pcm[j]; + for(i=0;ipcm_current-=n1; + v->pcm_returned-=n1; + v->centerW=0; + } + + /* solidify buffer into contiguous space */ + if((v->lW^v->W)==1){ + /* long/short or short/long */ + for(j=0;jchannels;j++){ + float *s=v->pcm[j]; + float *d=v->pcm[j]+(n1-n0)/2; + for(i=(n1+n0)/2-1;i>=0;--i) + d[i]=s[i]; + } + v->pcm_returned+=(n1-n0)/2; + v->pcm_current+=(n1-n0)/2; + }else{ + if(v->lW==0){ + /* short/short */ + for(j=0;jchannels;j++){ + float *s=v->pcm[j]; + float *d=v->pcm[j]+n1-n0; + for(i=n0-1;i>=0;--i) + d[i]=s[i]; + } + v->pcm_returned+=n1-n0; + v->pcm_current+=n1-n0; + } + } + + if(pcm){ + int i; + for(i=0;ichannels;i++) + v->pcmret[i]=v->pcm[i]+v->pcm_returned; + *pcm=v->pcmret; + } + + return(n1+n-v->pcm_returned); + +} + +float *vorbis_window(vorbis_dsp_state *v,int W){ + vorbis_info *vi=v->vi; + codec_setup_info *ci=vi->codec_setup; + int hs=ci->halfrate_flag; + private_state *b=v->backend_state; + + if(b->window[W]-1<0)return NULL; + return _vorbis_window_get(b->window[W]-hs); +} + diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/books/coupled/res_books_stereo.h b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/books/coupled/res_books_stereo.h new file mode 100644 index 0000000..d2dc0eb --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/books/coupled/res_books_stereo.h @@ -0,0 +1,20989 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the Xiph.Org Foundation http://www.xiph.org/ * + * * + ******************************************************************** + + function: static codebooks autogenerated by huff/huffbuld + last modified: $Id: res_books_stereo.h 7187 2004-07-20 07:24:27Z xiphmont $ + + ********************************************************************/ + +#include "codebook.h" +static long _vq_quantlist__16c0_s_p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__16c0_s_p1_0[] = { + 1, 4, 4, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 0, + 0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 5, 8, 8, 0, 0, 0, 0, 0, 0, 8, 9,10, 0, 0, 0, + 0, 0, 0, 7, 9,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 8, 8, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, + 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 8, 8, 0, 0, 0, 0, + 0, 0, 8,10,10, 0, 0, 0, 0, 0, 0, 8,10,10, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,10,10, 0, 0, 0, + 0, 0, 0, 9, 9,12, 0, 0, 0, 0, 0, 0,10,12,11, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,10,10, 0, 0, + 0, 0, 0, 0, 9,12,10, 0, 0, 0, 0, 0, 0,10,11,12, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 8, 8, 0, 0, 0, 0, 0, 0, 8,10,10, 0, 0, + 0, 0, 0, 0, 8,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 7,10,10, 0, 0, 0, 0, 0, 0,10,12,11, 0, + 0, 0, 0, 0, 0, 9,10,12, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7,10,10, 0, 0, 0, 0, 0, 0,10,11,12, + 0, 0, 0, 0, 0, 0, 9,12, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__16c0_s_p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__16c0_s_p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__16c0_s_p1_0 = { + _vq_quantthresh__16c0_s_p1_0, + _vq_quantmap__16c0_s_p1_0, + 3, + 3 +}; + +static static_codebook _16c0_s_p1_0 = { + 8, 6561, + _vq_lengthlist__16c0_s_p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__16c0_s_p1_0, + NULL, + &_vq_auxt__16c0_s_p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__16c0_s_p2_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__16c0_s_p2_0[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__16c0_s_p2_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__16c0_s_p2_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__16c0_s_p2_0 = { + _vq_quantthresh__16c0_s_p2_0, + _vq_quantmap__16c0_s_p2_0, + 5, + 5 +}; + +static static_codebook _16c0_s_p2_0 = { + 4, 625, + _vq_lengthlist__16c0_s_p2_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__16c0_s_p2_0, + NULL, + &_vq_auxt__16c0_s_p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__16c0_s_p3_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__16c0_s_p3_0[] = { + 1, 4, 4, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 6, 6, 7, 6, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 6, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6, 6, 6, 9, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__16c0_s_p3_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__16c0_s_p3_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__16c0_s_p3_0 = { + _vq_quantthresh__16c0_s_p3_0, + _vq_quantmap__16c0_s_p3_0, + 5, + 5 +}; + +static static_codebook _16c0_s_p3_0 = { + 4, 625, + _vq_lengthlist__16c0_s_p3_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__16c0_s_p3_0, + NULL, + &_vq_auxt__16c0_s_p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__16c0_s_p4_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__16c0_s_p4_0[] = { + 1, 3, 2, 7, 8, 0, 0, 0, 0, 0, 0, 0, 6, 6, 0, 0, + 0, 0, 0, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, 7, 7, + 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0, + 8, 8, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, + 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__16c0_s_p4_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__16c0_s_p4_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__16c0_s_p4_0 = { + _vq_quantthresh__16c0_s_p4_0, + _vq_quantmap__16c0_s_p4_0, + 9, + 9 +}; + +static static_codebook _16c0_s_p4_0 = { + 2, 81, + _vq_lengthlist__16c0_s_p4_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__16c0_s_p4_0, + NULL, + &_vq_auxt__16c0_s_p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__16c0_s_p5_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__16c0_s_p5_0[] = { + 1, 3, 3, 6, 6, 6, 6, 8, 8, 0, 0, 0, 7, 7, 7, 7, + 8, 8, 0, 0, 0, 7, 7, 7, 7, 8, 8, 0, 0, 0, 7, 7, + 8, 8, 9, 9, 0, 0, 0, 7, 7, 8, 8, 9, 9, 0, 0, 0, + 8, 9, 8, 8,10,10, 0, 0, 0, 8, 8, 8, 8,10,10, 0, + 0, 0,10,10, 9, 9,10,10, 0, 0, 0, 0, 0, 9, 9,10, + 10, +}; + +static float _vq_quantthresh__16c0_s_p5_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__16c0_s_p5_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__16c0_s_p5_0 = { + _vq_quantthresh__16c0_s_p5_0, + _vq_quantmap__16c0_s_p5_0, + 9, + 9 +}; + +static static_codebook _16c0_s_p5_0 = { + 2, 81, + _vq_lengthlist__16c0_s_p5_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__16c0_s_p5_0, + NULL, + &_vq_auxt__16c0_s_p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__16c0_s_p6_0[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__16c0_s_p6_0[] = { + 1, 3, 4, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,10,10,11, + 11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,10,10,11, + 11,11, 0, 0, 0, 6, 6, 8, 8, 9, 9, 9, 9,10,10,11, + 11,11,11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,10, + 11,11,12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10, + 10,11,11,12,12, 0, 0, 0, 8, 8, 9, 9,10,10,10,10, + 11,11,12,12,12,12, 0, 0, 0, 8, 8, 9, 9,10,10,10, + 10,11,11,12,12,12,13, 0, 0, 0, 9, 9, 9, 9,10,10, + 10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0,10,10,10, + 10,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9, 9, + 10,10,11,11,12,12,13,13,13,13, 0, 0, 0, 0, 0, 9, + 9,10,10,11,11,12,12,13,13,13,14, 0, 0, 0, 0, 0, + 10,10,10,11,11,11,12,12,13,13,13,14, 0, 0, 0, 0, + 0, 0, 0,10,10,11,11,12,12,13,13,14,14, 0, 0, 0, + 0, 0, 0, 0,11,11,12,12,13,13,13,13,14,14, 0, 0, + 0, 0, 0, 0, 0,11,11,12,12,12,13,13,14,15,14, 0, + 0, 0, 0, 0, 0, 0,12,12,12,12,13,13,13,14,14,15, + 0, 0, 0, 0, 0, 0, 0, 0, 0,12,12,13,13,14,13,14, + 14, +}; + +static float _vq_quantthresh__16c0_s_p6_0[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__16c0_s_p6_0[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__16c0_s_p6_0 = { + _vq_quantthresh__16c0_s_p6_0, + _vq_quantmap__16c0_s_p6_0, + 17, + 17 +}; + +static static_codebook _16c0_s_p6_0 = { + 2, 289, + _vq_lengthlist__16c0_s_p6_0, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__16c0_s_p6_0, + NULL, + &_vq_auxt__16c0_s_p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__16c0_s_p7_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__16c0_s_p7_0[] = { + 1, 4, 4, 6, 6, 6, 7, 6, 6, 4, 7, 7,11,10,10,11, + 11,10, 4, 7, 7,10,10,10,11,10,10, 6,10,10,11,11, + 11,11,11,10, 6, 9, 9,11,12,12,11, 9, 9, 6, 9,10, + 11,12,12,11, 9,10, 7,11,11,11,11,11,12,13,12, 6, + 9,10,11,10,10,12,13,13, 6,10, 9,11,10,10,11,12, + 13, +}; + +static float _vq_quantthresh__16c0_s_p7_0[] = { + -5.5, 5.5, +}; + +static long _vq_quantmap__16c0_s_p7_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__16c0_s_p7_0 = { + _vq_quantthresh__16c0_s_p7_0, + _vq_quantmap__16c0_s_p7_0, + 3, + 3 +}; + +static static_codebook _16c0_s_p7_0 = { + 4, 81, + _vq_lengthlist__16c0_s_p7_0, + 1, -529137664, 1618345984, 2, 0, + _vq_quantlist__16c0_s_p7_0, + NULL, + &_vq_auxt__16c0_s_p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__16c0_s_p7_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__16c0_s_p7_1[] = { + 1, 3, 4, 6, 6, 7, 7, 8, 8, 8, 8,10,10,10, 7, 7, + 8, 8, 8, 9, 9, 9,10,10,10, 6, 7, 8, 8, 8, 8, 9, + 8,10,10,10, 7, 7, 8, 8, 9, 9, 9, 9,10,10,10, 7, + 7, 8, 8, 9, 9, 8, 9,10,10,10, 8, 8, 9, 9, 9, 9, + 9, 9,11,11,11, 8, 8, 9, 9, 9, 9, 9,10,10,11,11, + 9, 9, 9, 9, 9, 9, 9,10,11,11,11,10,11, 9, 9, 9, + 9,10, 9,11,11,11,10,11,10,10, 9, 9,10,10,11,11, + 11,11,11, 9, 9, 9, 9,10,10, +}; + +static float _vq_quantthresh__16c0_s_p7_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__16c0_s_p7_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__16c0_s_p7_1 = { + _vq_quantthresh__16c0_s_p7_1, + _vq_quantmap__16c0_s_p7_1, + 11, + 11 +}; + +static static_codebook _16c0_s_p7_1 = { + 2, 121, + _vq_lengthlist__16c0_s_p7_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__16c0_s_p7_1, + NULL, + &_vq_auxt__16c0_s_p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__16c0_s_p8_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__16c0_s_p8_0[] = { + 1, 4, 4, 7, 7, 7, 7, 7, 6, 8, 8,10,10, 6, 5, 6, + 8, 8, 8, 8, 8, 8, 8, 9,10,10, 7, 6, 6, 8, 8, 8, + 8, 8, 8, 8, 8,10,10, 0, 8, 8, 8, 8, 9, 8, 9, 9, + 9,10,10,10, 0, 9, 8, 8, 8, 9, 9, 8, 8, 9, 9,10, + 10, 0,12,11, 8, 8, 9, 9, 9, 9,10,10,11,10, 0,12, + 13, 8, 8, 9,10, 9, 9,11,11,11,12, 0, 0, 0, 8, 8, + 8, 8,10, 9,12,13,12,14, 0, 0, 0, 8, 8, 8, 9,10, + 10,12,12,13,14, 0, 0, 0,13,13, 9, 9,11,11, 0, 0, + 14, 0, 0, 0, 0,14,14,10,10,12,11,12,14,14,14, 0, + 0, 0, 0, 0,11,11,13,13,14,13,14,14, 0, 0, 0, 0, + 0,12,13,13,12,13,14,14,14, +}; + +static float _vq_quantthresh__16c0_s_p8_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__16c0_s_p8_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__16c0_s_p8_0 = { + _vq_quantthresh__16c0_s_p8_0, + _vq_quantmap__16c0_s_p8_0, + 13, + 13 +}; + +static static_codebook _16c0_s_p8_0 = { + 2, 169, + _vq_lengthlist__16c0_s_p8_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__16c0_s_p8_0, + NULL, + &_vq_auxt__16c0_s_p8_0, + NULL, + 0 +}; + +static long _vq_quantlist__16c0_s_p8_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__16c0_s_p8_1[] = { + 1, 4, 3, 5, 5, 7, 7, 7, 6, 6, 7, 7, 7, 5, 5, 7, + 7, 7, 6, 6, 7, 7, 7, 6, 6, +}; + +static float _vq_quantthresh__16c0_s_p8_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__16c0_s_p8_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__16c0_s_p8_1 = { + _vq_quantthresh__16c0_s_p8_1, + _vq_quantmap__16c0_s_p8_1, + 5, + 5 +}; + +static static_codebook _16c0_s_p8_1 = { + 2, 25, + _vq_lengthlist__16c0_s_p8_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__16c0_s_p8_1, + NULL, + &_vq_auxt__16c0_s_p8_1, + NULL, + 0 +}; + +static long _vq_quantlist__16c0_s_p9_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__16c0_s_p9_0[] = { + 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, +}; + +static float _vq_quantthresh__16c0_s_p9_0[] = { + -157.5, 157.5, +}; + +static long _vq_quantmap__16c0_s_p9_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__16c0_s_p9_0 = { + _vq_quantthresh__16c0_s_p9_0, + _vq_quantmap__16c0_s_p9_0, + 3, + 3 +}; + +static static_codebook _16c0_s_p9_0 = { + 4, 81, + _vq_lengthlist__16c0_s_p9_0, + 1, -518803456, 1628680192, 2, 0, + _vq_quantlist__16c0_s_p9_0, + NULL, + &_vq_auxt__16c0_s_p9_0, + NULL, + 0 +}; + +static long _vq_quantlist__16c0_s_p9_1[] = { + 7, + 6, + 8, + 5, + 9, + 4, + 10, + 3, + 11, + 2, + 12, + 1, + 13, + 0, + 14, +}; + +static long _vq_lengthlist__16c0_s_p9_1[] = { + 1, 5, 5, 5, 5, 9,11,11,10,10,10,10,10,10,10, 7, + 6, 6, 6, 6,10,10,10,10,10,10,10,10,10,10, 7, 6, + 6, 6, 6,10, 9,10,10,10,10,10,10,10,10,10, 7, 7, + 8, 9,10,10,10,10,10,10,10,10,10,10,10, 8, 7,10, + 10,10, 9,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10, +}; + +static float _vq_quantthresh__16c0_s_p9_1[] = { + -136.5, -115.5, -94.5, -73.5, -52.5, -31.5, -10.5, 10.5, + 31.5, 52.5, 73.5, 94.5, 115.5, 136.5, +}; + +static long _vq_quantmap__16c0_s_p9_1[] = { + 13, 11, 9, 7, 5, 3, 1, 0, + 2, 4, 6, 8, 10, 12, 14, +}; + +static encode_aux_threshmatch _vq_auxt__16c0_s_p9_1 = { + _vq_quantthresh__16c0_s_p9_1, + _vq_quantmap__16c0_s_p9_1, + 15, + 15 +}; + +static static_codebook _16c0_s_p9_1 = { + 2, 225, + _vq_lengthlist__16c0_s_p9_1, + 1, -520986624, 1620377600, 4, 0, + _vq_quantlist__16c0_s_p9_1, + NULL, + &_vq_auxt__16c0_s_p9_1, + NULL, + 0 +}; + +static long _vq_quantlist__16c0_s_p9_2[] = { + 10, + 9, + 11, + 8, + 12, + 7, + 13, + 6, + 14, + 5, + 15, + 4, + 16, + 3, + 17, + 2, + 18, + 1, + 19, + 0, + 20, +}; + +static long _vq_lengthlist__16c0_s_p9_2[] = { + 1, 5, 5, 7, 8, 8, 7, 9, 9, 9,12,12,11,12,12,10, + 10,11,12,12,12,11,12,12, 8, 9, 8, 7, 9,10,10,11, + 11,10,11,12,10,12,10,12,12,12,11,12,11, 9, 8, 8, + 9,10, 9, 8, 9,10,12,12,11,11,12,11,10,11,12,11, + 12,12, 8, 9, 9, 9,10,11,12,11,12,11,11,11,11,12, + 12,11,11,12,12,11,11, 9, 9, 8, 9, 9,11, 9, 9,10, + 9,11,11,11,11,12,11,11,10,12,12,12, 9,12,11,10, + 11,11,11,11,12,12,12,11,11,11,12,10,12,12,12,10, + 10, 9,10, 9,10,10, 9, 9, 9,10,10,12,10,11,11, 9, + 11,11,10,11,11,11,10,10,10, 9, 9,10,10, 9, 9,10, + 11,11,10,11,10,11,10,11,11,10,11,11,11,10, 9,10, + 10, 9,10, 9, 9,11, 9, 9,11,10,10,11,11,10,10,11, + 10,11, 8, 9,11,11,10, 9,10,11,11,10,11,11,10,10, + 10,11,10, 9,10,10,11, 9,10,10, 9,11,10,10,10,10, + 11,10,11,11, 9,11,10,11,10,10,11,11,10,10,10, 9, + 10,10,11,11,11, 9,10,10,10,10,10,11,10,10,10, 9, + 10,10,11,10,10,10,10,10, 9,10,11,10,10,10,10,11, + 11,11,10,10,10,10,10,11,10,11,10,11,10,10,10, 9, + 11,11,10,10,10,11,11,10,10,10,10,10,10,10,10,11, + 11, 9,10,10,10,11,10,11,10,10,10,11, 9,10,11,10, + 11,10,10, 9,10,10,10,11,10,11,10,10,10,10,10,11, + 11,10,11,11,10,10,11,11,10, 9, 9,10,10,10,10,10, + 9,11, 9,10,10,10,11,11,10,10,10,10,11,11,11,10, + 9, 9,10,10,11,10,10,10,10,10,11,11,11,10,10,10, + 11,11,11, 9,10,10,10,10, 9,10, 9,10,11,10,11,10, + 10,11,11,10,11,11,11,11,11,10,11,10,10,10, 9,11, + 11,10,11,11,11,11,11,11,11,11,11,10,11,10,10,10, + 10,11,10,10,11, 9,10,10,10, +}; + +static float _vq_quantthresh__16c0_s_p9_2[] = { + -9.5, -8.5, -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, + -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, + 6.5, 7.5, 8.5, 9.5, +}; + +static long _vq_quantmap__16c0_s_p9_2[] = { + 19, 17, 15, 13, 11, 9, 7, 5, + 3, 1, 0, 2, 4, 6, 8, 10, + 12, 14, 16, 18, 20, +}; + +static encode_aux_threshmatch _vq_auxt__16c0_s_p9_2 = { + _vq_quantthresh__16c0_s_p9_2, + _vq_quantmap__16c0_s_p9_2, + 21, + 21 +}; + +static static_codebook _16c0_s_p9_2 = { + 2, 441, + _vq_lengthlist__16c0_s_p9_2, + 1, -529268736, 1611661312, 5, 0, + _vq_quantlist__16c0_s_p9_2, + NULL, + &_vq_auxt__16c0_s_p9_2, + NULL, + 0 +}; + +static long _huff_lengthlist__16c0_s_single[] = { + 3, 4,19, 7, 9, 7, 8,11, 9,12, 4, 1,19, 6, 7, 7, + 8,10,11,13,18,18,18,18,18,18,18,18,18,18, 8, 6, + 18, 8, 9, 9,11,12,14,18, 9, 6,18, 9, 7, 8, 9,11, + 12,18, 7, 6,18, 8, 7, 7, 7, 9,11,17, 8, 8,18, 9, + 7, 6, 6, 8,11,17,10,10,18,12, 9, 8, 7, 9,12,18, + 13,15,18,15,13,11,10,11,15,18,14,18,18,18,18,18, + 16,16,18,18, +}; + +static static_codebook _huff_book__16c0_s_single = { + 2, 100, + _huff_lengthlist__16c0_s_single, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__16c1_s_long[] = { + 2, 5,20, 7,10, 7, 8,10,11,11, 4, 2,20, 5, 8, 6, + 7, 9,10,10,20,20,20,20,19,19,19,19,19,19, 7, 5, + 19, 6,10, 7, 9,11,13,17,11, 8,19,10, 7, 7, 8,10, + 11,15, 7, 5,19, 7, 7, 5, 6, 9,11,16, 7, 6,19, 8, + 7, 6, 6, 7, 9,13, 9, 9,19,11, 9, 8, 6, 7, 8,13, + 12,14,19,16,13,10, 9, 8, 9,13,14,17,19,18,18,17, + 12,11,11,13, +}; + +static static_codebook _huff_book__16c1_s_long = { + 2, 100, + _huff_lengthlist__16c1_s_long, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__16c1_s_p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__16c1_s_p1_0[] = { + 1, 5, 5, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 0, + 0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 5, 8, 7, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, + 0, 0, 0, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 7, 8, 0, 0, 0, 0, 0, 0, 7, 9, 8, 0, 0, + 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 8, 7, 0, 0, 0, 0, + 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, + 0, 0, 0, 9, 9,11, 0, 0, 0, 0, 0, 0, 9,11,10, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, + 0, 0, 0, 0, 8,11, 9, 0, 0, 0, 0, 0, 0, 9,10,11, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 7, 8, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, + 0, 0, 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 9,11,10, 0, + 0, 0, 0, 0, 0, 8, 9,11, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 9,10,11, + 0, 0, 0, 0, 0, 0, 9,11, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__16c1_s_p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__16c1_s_p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__16c1_s_p1_0 = { + _vq_quantthresh__16c1_s_p1_0, + _vq_quantmap__16c1_s_p1_0, + 3, + 3 +}; + +static static_codebook _16c1_s_p1_0 = { + 8, 6561, + _vq_lengthlist__16c1_s_p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__16c1_s_p1_0, + NULL, + &_vq_auxt__16c1_s_p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__16c1_s_p2_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__16c1_s_p2_0[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__16c1_s_p2_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__16c1_s_p2_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__16c1_s_p2_0 = { + _vq_quantthresh__16c1_s_p2_0, + _vq_quantmap__16c1_s_p2_0, + 5, + 5 +}; + +static static_codebook _16c1_s_p2_0 = { + 4, 625, + _vq_lengthlist__16c1_s_p2_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__16c1_s_p2_0, + NULL, + &_vq_auxt__16c1_s_p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__16c1_s_p3_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__16c1_s_p3_0[] = { + 1, 4, 4, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 5, 7, 7, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 5, 5, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6, 7, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__16c1_s_p3_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__16c1_s_p3_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__16c1_s_p3_0 = { + _vq_quantthresh__16c1_s_p3_0, + _vq_quantmap__16c1_s_p3_0, + 5, + 5 +}; + +static static_codebook _16c1_s_p3_0 = { + 4, 625, + _vq_lengthlist__16c1_s_p3_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__16c1_s_p3_0, + NULL, + &_vq_auxt__16c1_s_p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__16c1_s_p4_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__16c1_s_p4_0[] = { + 1, 2, 3, 7, 7, 0, 0, 0, 0, 0, 0, 0, 6, 6, 0, 0, + 0, 0, 0, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, 7, 7, + 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0, + 8, 8, 0, 0, 0, 0, 0, 0, 0, 8, 9, 0, 0, 0, 0, 0, + 0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__16c1_s_p4_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__16c1_s_p4_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__16c1_s_p4_0 = { + _vq_quantthresh__16c1_s_p4_0, + _vq_quantmap__16c1_s_p4_0, + 9, + 9 +}; + +static static_codebook _16c1_s_p4_0 = { + 2, 81, + _vq_lengthlist__16c1_s_p4_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__16c1_s_p4_0, + NULL, + &_vq_auxt__16c1_s_p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__16c1_s_p5_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__16c1_s_p5_0[] = { + 1, 3, 3, 5, 5, 6, 6, 8, 8, 0, 0, 0, 7, 7, 7, 7, + 9, 9, 0, 0, 0, 7, 7, 7, 7, 9, 9, 0, 0, 0, 8, 8, + 8, 8, 9, 9, 0, 0, 0, 8, 8, 8, 8,10,10, 0, 0, 0, + 9, 9, 8, 8,10,10, 0, 0, 0, 9, 9, 8, 8,10,10, 0, + 0, 0,10,10, 9, 9,10,10, 0, 0, 0, 0, 0, 9, 9,10, + 10, +}; + +static float _vq_quantthresh__16c1_s_p5_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__16c1_s_p5_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__16c1_s_p5_0 = { + _vq_quantthresh__16c1_s_p5_0, + _vq_quantmap__16c1_s_p5_0, + 9, + 9 +}; + +static static_codebook _16c1_s_p5_0 = { + 2, 81, + _vq_lengthlist__16c1_s_p5_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__16c1_s_p5_0, + NULL, + &_vq_auxt__16c1_s_p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__16c1_s_p6_0[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__16c1_s_p6_0[] = { + 1, 3, 3, 6, 6, 8, 8, 9, 9, 9, 9,10,10,11,11,12, + 12, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,10,11,11, + 12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,10,11, + 11,12,12, 0, 0, 0, 8, 8, 8, 9,10, 9,10,10,10,10, + 11,11,12,12, 0, 0, 0, 8, 8, 9, 9,10,10,10,10,11, + 11,11,12,12,12, 0, 0, 0, 8, 8, 9, 9,10,10,10,10, + 11,11,12,12,12,12, 0, 0, 0, 8, 8, 9, 9,10,10,10, + 10,11,11,12,12,13,13, 0, 0, 0, 9, 9, 9, 9,10,10, + 10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9, 9,10, + 10,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9, 9, + 10,10,11,11,12,12,12,12,13,13, 0, 0, 0, 0, 0, 9, + 9,10,10,11,11,12,12,12,12,13,13, 0, 0, 0, 0, 0, + 10,10,11,10,11,11,12,12,13,13,13,13, 0, 0, 0, 0, + 0, 0, 0,10,10,11,11,12,12,13,13,13,13, 0, 0, 0, + 0, 0, 0, 0,11,11,12,12,12,12,13,13,14,14, 0, 0, + 0, 0, 0, 0, 0,11,11,12,12,12,12,13,13,14,14, 0, + 0, 0, 0, 0, 0, 0,12,12,12,12,13,13,13,13,14,14, + 0, 0, 0, 0, 0, 0, 0, 0, 0,12,12,13,13,13,13,14, + 14, +}; + +static float _vq_quantthresh__16c1_s_p6_0[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__16c1_s_p6_0[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__16c1_s_p6_0 = { + _vq_quantthresh__16c1_s_p6_0, + _vq_quantmap__16c1_s_p6_0, + 17, + 17 +}; + +static static_codebook _16c1_s_p6_0 = { + 2, 289, + _vq_lengthlist__16c1_s_p6_0, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__16c1_s_p6_0, + NULL, + &_vq_auxt__16c1_s_p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__16c1_s_p7_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__16c1_s_p7_0[] = { + 1, 4, 4, 6, 6, 6, 7, 6, 6, 4, 7, 7,10, 9,10,10, + 10, 9, 4, 7, 7,10,10,10,11,10,10, 6,10,10,11,11, + 11,11,10,10, 6,10, 9,11,11,11,11,10,10, 6,10,10, + 11,11,11,11,10,10, 7,11,11,11,11,11,12,12,11, 6, + 10,10,11,10,10,11,11,11, 6,10,10,10,11,10,11,11, + 11, +}; + +static float _vq_quantthresh__16c1_s_p7_0[] = { + -5.5, 5.5, +}; + +static long _vq_quantmap__16c1_s_p7_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__16c1_s_p7_0 = { + _vq_quantthresh__16c1_s_p7_0, + _vq_quantmap__16c1_s_p7_0, + 3, + 3 +}; + +static static_codebook _16c1_s_p7_0 = { + 4, 81, + _vq_lengthlist__16c1_s_p7_0, + 1, -529137664, 1618345984, 2, 0, + _vq_quantlist__16c1_s_p7_0, + NULL, + &_vq_auxt__16c1_s_p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__16c1_s_p7_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__16c1_s_p7_1[] = { + 2, 3, 3, 5, 6, 7, 7, 7, 7, 8, 8,10,10,10, 6, 6, + 7, 7, 8, 8, 8, 8,10,10,10, 6, 6, 7, 7, 8, 8, 8, + 8,10,10,10, 7, 7, 7, 7, 8, 8, 8, 8,10,10,10, 7, + 7, 7, 7, 8, 8, 8, 8,10,10,10, 7, 7, 8, 8, 8, 8, + 8, 8,10,10,10, 7, 7, 8, 8, 8, 8, 8, 8,10,10,10, + 8, 8, 8, 8, 8, 8, 9, 9,10,10,10,10,10, 8, 8, 8, + 8, 9, 9,10,10,10,10,10, 9, 9, 8, 8, 9, 9,10,10, + 10,10,10, 8, 8, 8, 8, 9, 9, +}; + +static float _vq_quantthresh__16c1_s_p7_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__16c1_s_p7_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__16c1_s_p7_1 = { + _vq_quantthresh__16c1_s_p7_1, + _vq_quantmap__16c1_s_p7_1, + 11, + 11 +}; + +static static_codebook _16c1_s_p7_1 = { + 2, 121, + _vq_lengthlist__16c1_s_p7_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__16c1_s_p7_1, + NULL, + &_vq_auxt__16c1_s_p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__16c1_s_p8_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__16c1_s_p8_0[] = { + 1, 4, 4, 6, 6, 7, 7, 7, 7, 8, 8, 9, 9, 6, 5, 5, + 7, 8, 8, 9, 8, 8, 9, 9,10,11, 6, 5, 5, 8, 8, 9, + 9, 8, 8, 9,10,10,11, 0, 8, 8, 8, 9, 9, 9, 9, 9, + 10,10,11,11, 0, 9, 9, 9, 8, 9, 9, 9, 9,10,10,11, + 11, 0,13,13, 9, 9,10,10,10,10,11,11,12,12, 0,14, + 13, 9, 9,10,10,10,10,11,11,12,12, 0, 0, 0,10,10, + 9, 9,11,11,12,12,13,12, 0, 0, 0,10,10, 9, 9,10, + 10,12,12,13,13, 0, 0, 0,13,14,11,10,11,11,12,12, + 13,14, 0, 0, 0,14,14,10,10,11,11,12,12,13,13, 0, + 0, 0, 0, 0,12,12,12,12,13,13,14,15, 0, 0, 0, 0, + 0,12,12,12,12,13,13,14,15, +}; + +static float _vq_quantthresh__16c1_s_p8_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__16c1_s_p8_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__16c1_s_p8_0 = { + _vq_quantthresh__16c1_s_p8_0, + _vq_quantmap__16c1_s_p8_0, + 13, + 13 +}; + +static static_codebook _16c1_s_p8_0 = { + 2, 169, + _vq_lengthlist__16c1_s_p8_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__16c1_s_p8_0, + NULL, + &_vq_auxt__16c1_s_p8_0, + NULL, + 0 +}; + +static long _vq_quantlist__16c1_s_p8_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__16c1_s_p8_1[] = { + 2, 3, 3, 5, 5, 6, 6, 6, 5, 5, 6, 6, 6, 5, 5, 6, + 6, 6, 5, 5, 6, 6, 6, 5, 5, +}; + +static float _vq_quantthresh__16c1_s_p8_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__16c1_s_p8_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__16c1_s_p8_1 = { + _vq_quantthresh__16c1_s_p8_1, + _vq_quantmap__16c1_s_p8_1, + 5, + 5 +}; + +static static_codebook _16c1_s_p8_1 = { + 2, 25, + _vq_lengthlist__16c1_s_p8_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__16c1_s_p8_1, + NULL, + &_vq_auxt__16c1_s_p8_1, + NULL, + 0 +}; + +static long _vq_quantlist__16c1_s_p9_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__16c1_s_p9_0[] = { + 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, +}; + +static float _vq_quantthresh__16c1_s_p9_0[] = { + -1732.5, -1417.5, -1102.5, -787.5, -472.5, -157.5, 157.5, 472.5, + 787.5, 1102.5, 1417.5, 1732.5, +}; + +static long _vq_quantmap__16c1_s_p9_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__16c1_s_p9_0 = { + _vq_quantthresh__16c1_s_p9_0, + _vq_quantmap__16c1_s_p9_0, + 13, + 13 +}; + +static static_codebook _16c1_s_p9_0 = { + 2, 169, + _vq_lengthlist__16c1_s_p9_0, + 1, -513964032, 1628680192, 4, 0, + _vq_quantlist__16c1_s_p9_0, + NULL, + &_vq_auxt__16c1_s_p9_0, + NULL, + 0 +}; + +static long _vq_quantlist__16c1_s_p9_1[] = { + 7, + 6, + 8, + 5, + 9, + 4, + 10, + 3, + 11, + 2, + 12, + 1, + 13, + 0, + 14, +}; + +static long _vq_lengthlist__16c1_s_p9_1[] = { + 1, 4, 4, 4, 4, 8, 8,12,13,14,14,14,14,14,14, 6, + 6, 6, 6, 6,10, 9,14,14,14,14,14,14,14,14, 7, 6, + 5, 6, 6,10, 9,12,13,13,13,13,13,13,13,13, 7, 7, + 9, 9,11,11,12,13,13,13,13,13,13,13,13, 7, 7, 8, + 8,11,12,13,13,13,13,13,13,13,13,13,12,12,10,10, + 13,12,13,13,13,13,13,13,13,13,13,12,12,10,10,13, + 13,13,13,13,13,13,13,13,13,13,13,13,13,12,13,12, + 13,13,13,13,13,13,13,13,13,13,13,13,12,13,13,13, + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, + 13,13,13,13,13,13,13,13,13,13,13,13,12,13,13,13, + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, + 13,13,13,13,13,13,13,13,13,12,13,13,13,13,13,13, + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, + 13, +}; + +static float _vq_quantthresh__16c1_s_p9_1[] = { + -136.5, -115.5, -94.5, -73.5, -52.5, -31.5, -10.5, 10.5, + 31.5, 52.5, 73.5, 94.5, 115.5, 136.5, +}; + +static long _vq_quantmap__16c1_s_p9_1[] = { + 13, 11, 9, 7, 5, 3, 1, 0, + 2, 4, 6, 8, 10, 12, 14, +}; + +static encode_aux_threshmatch _vq_auxt__16c1_s_p9_1 = { + _vq_quantthresh__16c1_s_p9_1, + _vq_quantmap__16c1_s_p9_1, + 15, + 15 +}; + +static static_codebook _16c1_s_p9_1 = { + 2, 225, + _vq_lengthlist__16c1_s_p9_1, + 1, -520986624, 1620377600, 4, 0, + _vq_quantlist__16c1_s_p9_1, + NULL, + &_vq_auxt__16c1_s_p9_1, + NULL, + 0 +}; + +static long _vq_quantlist__16c1_s_p9_2[] = { + 10, + 9, + 11, + 8, + 12, + 7, + 13, + 6, + 14, + 5, + 15, + 4, + 16, + 3, + 17, + 2, + 18, + 1, + 19, + 0, + 20, +}; + +static long _vq_lengthlist__16c1_s_p9_2[] = { + 1, 4, 4, 6, 6, 7, 7, 8, 7, 8, 8, 9, 9, 9, 9,10, + 10,10, 9,10,10,11,12,12, 8, 8, 8, 8, 9, 9, 9, 9, + 10,10,10,10,10,11,11,10,12,11,11,13,11, 7, 7, 8, + 8, 8, 8, 9, 9, 9,10,10,10,10, 9,10,10,11,11,12, + 11,11, 8, 8, 8, 8, 9, 9,10,10,10,10,11,11,11,11, + 11,11,11,12,11,12,12, 8, 8, 9, 9, 9, 9, 9,10,10, + 10,10,10,10,11,11,11,11,11,11,12,11, 9, 9, 9, 9, + 10,10,10,10,11,10,11,11,11,11,11,11,12,12,12,12, + 11, 9, 9, 9, 9,10,10,10,10,11,11,11,11,11,11,11, + 11,11,12,12,12,13, 9,10,10, 9,11,10,10,10,10,11, + 11,11,11,11,10,11,12,11,12,12,11,12,11,10, 9,10, + 10,11,10,11,11,11,11,11,11,11,11,11,12,12,11,12, + 12,12,10,10,10,11,10,11,11,11,11,11,11,11,11,11, + 11,11,12,13,12,12,11, 9,10,10,11,11,10,11,11,11, + 12,11,11,11,11,11,12,12,13,13,12,13,10,10,12,10, + 11,11,11,11,11,11,11,11,11,12,12,11,13,12,12,12, + 12,13,12,11,11,11,11,11,11,12,11,12,11,11,11,11, + 12,12,13,12,11,12,12,11,11,11,11,11,12,11,11,11, + 11,12,11,11,12,11,12,13,13,12,12,12,12,11,11,11, + 11,11,12,11,11,12,11,12,11,11,11,11,13,12,12,12, + 12,13,11,11,11,12,12,11,11,11,12,11,12,12,12,11, + 12,13,12,11,11,12,12,11,12,11,11,11,12,12,11,12, + 11,11,11,12,12,12,12,13,12,13,12,12,12,12,11,11, + 12,11,11,11,11,11,11,12,12,12,13,12,11,13,13,12, + 12,11,12,10,11,11,11,11,12,11,12,12,11,12,12,13, + 12,12,13,12,12,12,12,12,11,12,12,12,11,12,11,11, + 11,12,13,12,13,13,13,13,13,12,13,13,12,12,13,11, + 11,11,11,11,12,11,11,12,11, +}; + +static float _vq_quantthresh__16c1_s_p9_2[] = { + -9.5, -8.5, -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, + -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, + 6.5, 7.5, 8.5, 9.5, +}; + +static long _vq_quantmap__16c1_s_p9_2[] = { + 19, 17, 15, 13, 11, 9, 7, 5, + 3, 1, 0, 2, 4, 6, 8, 10, + 12, 14, 16, 18, 20, +}; + +static encode_aux_threshmatch _vq_auxt__16c1_s_p9_2 = { + _vq_quantthresh__16c1_s_p9_2, + _vq_quantmap__16c1_s_p9_2, + 21, + 21 +}; + +static static_codebook _16c1_s_p9_2 = { + 2, 441, + _vq_lengthlist__16c1_s_p9_2, + 1, -529268736, 1611661312, 5, 0, + _vq_quantlist__16c1_s_p9_2, + NULL, + &_vq_auxt__16c1_s_p9_2, + NULL, + 0 +}; + +static long _huff_lengthlist__16c1_s_short[] = { + 5, 6,17, 8,12, 9,10,10,12,13, 5, 2,17, 4, 9, 5, + 7, 8,11,13,16,16,16,16,16,16,16,16,16,16, 6, 4, + 16, 5,10, 5, 7,10,14,16,13, 9,16,11, 8, 7, 8, 9, + 13,16, 7, 4,16, 5, 7, 4, 6, 8,11,13, 8, 6,16, 7, + 8, 5, 5, 7, 9,13, 9, 8,16, 9, 8, 6, 6, 7, 9,13, + 11,11,16,10,10, 7, 7, 7, 9,13,13,13,16,13,13, 9, + 9, 9,10,13, +}; + +static static_codebook _huff_book__16c1_s_short = { + 2, 100, + _huff_lengthlist__16c1_s_short, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__16c2_s_long[] = { + 4, 7, 9, 9, 9, 8, 9,10,15,19, 5, 4, 5, 6, 7, 7, + 8, 9,14,16, 6, 5, 4, 5, 6, 7, 8,10,12,19, 7, 6, + 5, 4, 5, 6, 7, 9,11,18, 8, 7, 6, 5, 5, 5, 7, 9, + 10,17, 8, 7, 7, 5, 5, 5, 6, 7,12,18, 8, 8, 8, 7, + 7, 5, 5, 7,12,18, 8, 9,10, 9, 9, 7, 6, 7,12,17, + 14,18,16,16,15,12,11,10,12,18,15,17,18,18,18,15, + 14,14,16,18, +}; + +static static_codebook _huff_book__16c2_s_long = { + 2, 100, + _huff_lengthlist__16c2_s_long, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__16c2_s_p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__16c2_s_p1_0[] = { + 1, 3, 3, 0, 0, 0, 0, 0, 0, 4, 5, 5, 0, 0, 0, 0, + 0, 0, 4, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__16c2_s_p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__16c2_s_p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__16c2_s_p1_0 = { + _vq_quantthresh__16c2_s_p1_0, + _vq_quantmap__16c2_s_p1_0, + 3, + 3 +}; + +static static_codebook _16c2_s_p1_0 = { + 4, 81, + _vq_lengthlist__16c2_s_p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__16c2_s_p1_0, + NULL, + &_vq_auxt__16c2_s_p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__16c2_s_p2_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__16c2_s_p2_0[] = { + 2, 4, 3, 7, 7, 0, 0, 0, 7, 8, 0, 0, 0, 8, 8, 0, + 0, 0, 8, 8, 0, 0, 0, 8, 8, 4, 5, 4, 8, 8, 0, 0, + 0, 8, 8, 0, 0, 0, 8, 8, 0, 0, 0, 9, 9, 0, 0, 0, + 9, 9, 4, 4, 5, 8, 8, 0, 0, 0, 8, 8, 0, 0, 0, 8, + 8, 0, 0, 0, 9, 9, 0, 0, 0, 9, 9, 7, 8, 8,10,10, + 0, 0, 0,12,11, 0, 0, 0,11,11, 0, 0, 0,14,13, 0, + 0, 0,14,13, 7, 8, 8, 9,10, 0, 0, 0,11,12, 0, 0, + 0,11,11, 0, 0, 0,14,14, 0, 0, 0,13,14, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8,11,11, 0, 0, 0, + 11,11, 0, 0, 0,12,11, 0, 0, 0,12,12, 0, 0, 0,13, + 13, 8, 8, 8,11,11, 0, 0, 0,11,11, 0, 0, 0,11,12, + 0, 0, 0,12,13, 0, 0, 0,13,13, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 8, 8, 8,12,11, 0, 0, 0,12,11, 0, + 0, 0,11,11, 0, 0, 0,13,13, 0, 0, 0,13,12, 8, 8, + 8,11,12, 0, 0, 0,11,12, 0, 0, 0,11,11, 0, 0, 0, + 13,13, 0, 0, 0,12,13, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 8, 9, 9,14,13, 0, 0, 0,13,12, 0, 0, 0,13, + 13, 0, 0, 0,13,12, 0, 0, 0,13,13, 8, 9, 9,13,14, + 0, 0, 0,12,13, 0, 0, 0,13,13, 0, 0, 0,12,13, 0, + 0, 0,13,13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, + 9, 9,14,13, 0, 0, 0,13,13, 0, 0, 0,13,12, 0, 0, + 0,13,13, 0, 0, 0,13,12, 8, 9, 9,14,14, 0, 0, 0, + 13,13, 0, 0, 0,12,13, 0, 0, 0,13,13, 0, 0, 0,12, + 13, +}; + +static float _vq_quantthresh__16c2_s_p2_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__16c2_s_p2_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__16c2_s_p2_0 = { + _vq_quantthresh__16c2_s_p2_0, + _vq_quantmap__16c2_s_p2_0, + 5, + 5 +}; + +static static_codebook _16c2_s_p2_0 = { + 4, 625, + _vq_lengthlist__16c2_s_p2_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__16c2_s_p2_0, + NULL, + &_vq_auxt__16c2_s_p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__16c2_s_p3_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__16c2_s_p3_0[] = { + 1, 3, 3, 6, 6, 7, 7, 8, 8, 0, 0, 0, 6, 6, 7, 7, + 9, 9, 0, 0, 0, 6, 6, 7, 7, 9, 9, 0, 0, 0, 7, 7, + 8, 8,10,10, 0, 0, 0, 7, 7, 8, 8,10,10, 0, 0, 0, + 7, 7, 9, 9,10,10, 0, 0, 0, 7, 7, 9, 9,10,10, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__16c2_s_p3_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__16c2_s_p3_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__16c2_s_p3_0 = { + _vq_quantthresh__16c2_s_p3_0, + _vq_quantmap__16c2_s_p3_0, + 9, + 9 +}; + +static static_codebook _16c2_s_p3_0 = { + 2, 81, + _vq_lengthlist__16c2_s_p3_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__16c2_s_p3_0, + NULL, + &_vq_auxt__16c2_s_p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__16c2_s_p4_0[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__16c2_s_p4_0[] = { + 2, 3, 3, 5, 5, 6, 6, 7, 7, 7, 7, 8, 8, 9, 9,10, + 10, 0, 0, 0, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,10,10, + 11,11, 0, 0, 0, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,10, + 10,10,11, 0, 0, 0, 6, 6, 8, 8, 8, 8, 9, 9,10,10, + 10,11,11,11, 0, 0, 0, 6, 6, 8, 8, 9, 9, 9, 9,10, + 10,11,11,11,11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9, + 10,10,11,11,12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, + 9,10,10,11,11,12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9, + 10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0, 8, 8, 9, + 9,10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__16c2_s_p4_0[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__16c2_s_p4_0[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__16c2_s_p4_0 = { + _vq_quantthresh__16c2_s_p4_0, + _vq_quantmap__16c2_s_p4_0, + 17, + 17 +}; + +static static_codebook _16c2_s_p4_0 = { + 2, 289, + _vq_lengthlist__16c2_s_p4_0, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__16c2_s_p4_0, + NULL, + &_vq_auxt__16c2_s_p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__16c2_s_p5_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__16c2_s_p5_0[] = { + 1, 4, 4, 5, 7, 7, 6, 7, 7, 4, 6, 6,10,10,10,10, + 10,10, 4, 7, 6,10,10,10,10,10,10, 5, 9, 9, 9,12, + 11,10,11,12, 7,10,10,12,12,12,12,12,12, 7,10,10, + 11,12,12,12,12,13, 6,10,10,10,12,12,10,12,12, 7, + 10,10,11,13,12,12,12,12, 7,10,10,11,12,12,12,12, + 12, +}; + +static float _vq_quantthresh__16c2_s_p5_0[] = { + -5.5, 5.5, +}; + +static long _vq_quantmap__16c2_s_p5_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__16c2_s_p5_0 = { + _vq_quantthresh__16c2_s_p5_0, + _vq_quantmap__16c2_s_p5_0, + 3, + 3 +}; + +static static_codebook _16c2_s_p5_0 = { + 4, 81, + _vq_lengthlist__16c2_s_p5_0, + 1, -529137664, 1618345984, 2, 0, + _vq_quantlist__16c2_s_p5_0, + NULL, + &_vq_auxt__16c2_s_p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__16c2_s_p5_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__16c2_s_p5_1[] = { + 2, 3, 3, 6, 6, 7, 7, 7, 7, 8, 8,11,11,11, 6, 6, + 7, 7, 8, 8, 8, 8,11,11,11, 6, 6, 7, 7, 8, 8, 8, + 8,11,11,11, 6, 6, 8, 8, 8, 8, 9, 9,11,11,11, 6, + 6, 8, 8, 8, 8, 9, 9,11,11,11, 7, 7, 8, 8, 8, 8, + 8, 8,11,11,11, 7, 7, 8, 8, 8, 8, 8, 9,11,11,11, + 8, 8, 8, 8, 8, 8, 8, 8,11,11,11,11,11, 8, 8, 8, + 8, 8, 8,11,11,11,11,11, 8, 8, 8, 8, 8, 8,11,11, + 11,11,11, 7, 7, 8, 8, 8, 8, +}; + +static float _vq_quantthresh__16c2_s_p5_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__16c2_s_p5_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__16c2_s_p5_1 = { + _vq_quantthresh__16c2_s_p5_1, + _vq_quantmap__16c2_s_p5_1, + 11, + 11 +}; + +static static_codebook _16c2_s_p5_1 = { + 2, 121, + _vq_lengthlist__16c2_s_p5_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__16c2_s_p5_1, + NULL, + &_vq_auxt__16c2_s_p5_1, + NULL, + 0 +}; + +static long _vq_quantlist__16c2_s_p6_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__16c2_s_p6_0[] = { + 1, 4, 4, 7, 6, 8, 8, 9, 9,10,10,11,11, 5, 5, 5, + 7, 7, 9, 9, 9, 9,11,11,12,12, 6, 5, 5, 7, 7, 9, + 9,10,10,11,11,12,12, 0, 6, 6, 7, 7, 9, 9,10,10, + 11,11,12,12, 0, 7, 7, 7, 7, 9, 9,10,10,11,12,12, + 12, 0,11,11, 8, 8,10,10,11,11,12,12,13,13, 0,11, + 12, 8, 8,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +static float _vq_quantthresh__16c2_s_p6_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__16c2_s_p6_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__16c2_s_p6_0 = { + _vq_quantthresh__16c2_s_p6_0, + _vq_quantmap__16c2_s_p6_0, + 13, + 13 +}; + +static static_codebook _16c2_s_p6_0 = { + 2, 169, + _vq_lengthlist__16c2_s_p6_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__16c2_s_p6_0, + NULL, + &_vq_auxt__16c2_s_p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__16c2_s_p6_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__16c2_s_p6_1[] = { + 2, 3, 3, 5, 5, 6, 6, 6, 5, 5, 6, 6, 6, 5, 5, 6, + 6, 6, 5, 5, 6, 6, 6, 5, 5, +}; + +static float _vq_quantthresh__16c2_s_p6_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__16c2_s_p6_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__16c2_s_p6_1 = { + _vq_quantthresh__16c2_s_p6_1, + _vq_quantmap__16c2_s_p6_1, + 5, + 5 +}; + +static static_codebook _16c2_s_p6_1 = { + 2, 25, + _vq_lengthlist__16c2_s_p6_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__16c2_s_p6_1, + NULL, + &_vq_auxt__16c2_s_p6_1, + NULL, + 0 +}; + +static long _vq_quantlist__16c2_s_p7_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__16c2_s_p7_0[] = { + 1, 4, 4, 7, 7, 8, 8, 9, 9,10,10,11,11, 5, 5, 5, + 8, 8, 9, 9,10,10,11,11,12,12, 6, 5, 5, 8, 8, 9, + 9,10,10,11,11,12,13,18, 6, 6, 7, 7, 9, 9,10,10, + 12,12,13,13,18, 6, 6, 7, 7, 9, 9,10,10,12,12,13, + 13,18,11,10, 8, 8,10,10,11,11,12,12,13,13,18,11, + 11, 8, 8,10,10,11,11,12,13,13,13,18,18,18,10,11, + 11,11,12,12,13,13,14,14,18,18,18,11,11,11,11,12, + 12,13,13,14,14,18,18,18,14,14,12,12,12,12,14,14, + 15,14,18,18,18,15,15,11,12,12,12,13,13,15,15,18, + 18,18,18,18,13,13,13,13,13,14,17,16,18,18,18,18, + 18,13,14,13,13,14,13,15,14, +}; + +static float _vq_quantthresh__16c2_s_p7_0[] = { + -60.5, -49.5, -38.5, -27.5, -16.5, -5.5, 5.5, 16.5, + 27.5, 38.5, 49.5, 60.5, +}; + +static long _vq_quantmap__16c2_s_p7_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__16c2_s_p7_0 = { + _vq_quantthresh__16c2_s_p7_0, + _vq_quantmap__16c2_s_p7_0, + 13, + 13 +}; + +static static_codebook _16c2_s_p7_0 = { + 2, 169, + _vq_lengthlist__16c2_s_p7_0, + 1, -523206656, 1618345984, 4, 0, + _vq_quantlist__16c2_s_p7_0, + NULL, + &_vq_auxt__16c2_s_p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__16c2_s_p7_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__16c2_s_p7_1[] = { + 2, 4, 4, 6, 6, 7, 7, 7, 7, 7, 7, 9, 9, 9, 6, 6, + 7, 7, 8, 8, 8, 8, 9, 9, 9, 6, 6, 7, 7, 8, 8, 8, + 8, 9, 9, 9, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 7, + 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 7, 7, 7, 7, 8, 8, + 8, 8, 9, 9, 9, 7, 7, 7, 7, 7, 7, 8, 8, 9, 9, 9, + 7, 7, 8, 8, 7, 7, 8, 8, 9, 9, 9, 9, 9, 7, 7, 7, + 7, 8, 8, 9, 9, 9, 9, 9, 8, 8, 7, 7, 8, 8, 9, 9, + 9, 9, 9, 7, 7, 7, 7, 8, 8, +}; + +static float _vq_quantthresh__16c2_s_p7_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__16c2_s_p7_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__16c2_s_p7_1 = { + _vq_quantthresh__16c2_s_p7_1, + _vq_quantmap__16c2_s_p7_1, + 11, + 11 +}; + +static static_codebook _16c2_s_p7_1 = { + 2, 121, + _vq_lengthlist__16c2_s_p7_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__16c2_s_p7_1, + NULL, + &_vq_auxt__16c2_s_p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__16c2_s_p8_0[] = { + 7, + 6, + 8, + 5, + 9, + 4, + 10, + 3, + 11, + 2, + 12, + 1, + 13, + 0, + 14, +}; + +static long _vq_lengthlist__16c2_s_p8_0[] = { + 1, 4, 4, 7, 6, 7, 7, 6, 6, 8, 8, 9, 9,10,10, 6, + 6, 6, 8, 8, 9, 8, 8, 8, 9, 9,11,10,11,11, 7, 6, + 6, 8, 8, 9, 8, 7, 7, 9, 9,10,10,12,11,14, 8, 8, + 8, 9, 9, 9, 9, 9,10, 9,10,10,11,13,14, 8, 8, 8, + 8, 9, 9, 8, 8, 9, 9,10,10,11,12,14,13,11, 9, 9, + 9, 9, 9, 9, 9,10,11,10,13,12,14,11,13, 8, 9, 9, + 9, 9, 9,10,10,11,10,13,12,14,14,14, 8, 9, 9, 9, + 11,11,11,11,11,12,13,13,14,14,14, 9, 8, 9, 9,10, + 10,12,10,11,12,12,14,14,14,14,11,12,10,10,12,12, + 12,12,13,14,12,12,14,14,14,12,12, 9,10,11,11,12, + 14,12,14,14,14,14,14,14,14,14,11,11,12,11,12,14, + 14,14,14,14,14,14,14,14,14,12,11,11,11,11,14,14, + 14,14,14,14,14,14,14,14,14,14,13,12,14,14,14,14, + 14,14,14,14,14,14,14,14,14,12,12,12,13,14,14,13, + 13, +}; + +static float _vq_quantthresh__16c2_s_p8_0[] = { + -136.5, -115.5, -94.5, -73.5, -52.5, -31.5, -10.5, 10.5, + 31.5, 52.5, 73.5, 94.5, 115.5, 136.5, +}; + +static long _vq_quantmap__16c2_s_p8_0[] = { + 13, 11, 9, 7, 5, 3, 1, 0, + 2, 4, 6, 8, 10, 12, 14, +}; + +static encode_aux_threshmatch _vq_auxt__16c2_s_p8_0 = { + _vq_quantthresh__16c2_s_p8_0, + _vq_quantmap__16c2_s_p8_0, + 15, + 15 +}; + +static static_codebook _16c2_s_p8_0 = { + 2, 225, + _vq_lengthlist__16c2_s_p8_0, + 1, -520986624, 1620377600, 4, 0, + _vq_quantlist__16c2_s_p8_0, + NULL, + &_vq_auxt__16c2_s_p8_0, + NULL, + 0 +}; + +static long _vq_quantlist__16c2_s_p8_1[] = { + 10, + 9, + 11, + 8, + 12, + 7, + 13, + 6, + 14, + 5, + 15, + 4, + 16, + 3, + 17, + 2, + 18, + 1, + 19, + 0, + 20, +}; + +static long _vq_lengthlist__16c2_s_p8_1[] = { + 2, 4, 4, 6, 6, 7, 7, 7, 7, 8, 7, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8,11,12,11, 7, 7, 8, 8, 8, 8, 9, 9, + 9, 9, 9, 9, 9, 9, 9,10, 9, 9,11,11,10, 7, 7, 8, + 8, 8, 8, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,11, + 11,11, 8, 7, 8, 8, 9, 9, 9, 9, 9, 9,10,10, 9,10, + 10, 9,10,10,11,11,12, 8, 8, 8, 8, 9, 9, 9, 9, 9, + 9, 9, 9,10, 9,10,10,10,10,11,11,11, 8, 8, 9, 9, + 9, 9, 9, 9, 9,10,10,10,10,10,10,10,10,10,11,11, + 11, 8, 8, 9, 8, 9, 9, 9, 9,10, 9, 9, 9,10,10,10, + 10, 9,10,11,11,11, 9, 9, 9, 9,10, 9, 9, 9,10,10, + 9,10, 9,10,10,10,10,10,11,12,11,11,11, 9, 9, 9, + 9, 9,10,10, 9,10,10,10,10,10,10,10,10,12,11,13, + 13,11, 9, 9, 9, 9,10,10, 9,10,10,10,10,11,10,10, + 10,10,11,12,11,12,11, 9, 9, 9,10,10, 9,10,10,10, + 10,10,10,10,10,10,10,11,11,11,12,11, 9,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,11,12,12,12, + 11,11,11,10, 9,10,10,10,10,10,10,10,10,11,10,10, + 10,11,11,11,11,11,11,11,10,10,10,11,10,10,10,10, + 10,10,10,10,10,10,11,11,11,11,12,12,11,10,10,10, + 10,10,10,10,10,11,10,10,10,11,10,12,11,11,12,11, + 11,11,10,10,10,10,10,11,10,10,10,10,10,11,10,10, + 11,11,11,12,11,12,11,11,12,10,10,10,10,10,10,10, + 11,10,10,11,10,12,11,11,11,12,11,11,11,11,10,10, + 10,10,10,10,10,11,11,11,10,11,12,11,11,11,12,11, + 12,11,12,10,11,10,10,10,10,11,10,10,10,10,10,10, + 12,11,11,11,11,11,12,12,10,10,10,10,10,11,10,10, + 11,10,11,11,11,11,11,11,11,11,11,11,11,11,12,11, + 10,11,10,10,10,10,10,10,10, +}; + +static float _vq_quantthresh__16c2_s_p8_1[] = { + -9.5, -8.5, -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, + -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, + 6.5, 7.5, 8.5, 9.5, +}; + +static long _vq_quantmap__16c2_s_p8_1[] = { + 19, 17, 15, 13, 11, 9, 7, 5, + 3, 1, 0, 2, 4, 6, 8, 10, + 12, 14, 16, 18, 20, +}; + +static encode_aux_threshmatch _vq_auxt__16c2_s_p8_1 = { + _vq_quantthresh__16c2_s_p8_1, + _vq_quantmap__16c2_s_p8_1, + 21, + 21 +}; + +static static_codebook _16c2_s_p8_1 = { + 2, 441, + _vq_lengthlist__16c2_s_p8_1, + 1, -529268736, 1611661312, 5, 0, + _vq_quantlist__16c2_s_p8_1, + NULL, + &_vq_auxt__16c2_s_p8_1, + NULL, + 0 +}; + +static long _vq_quantlist__16c2_s_p9_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__16c2_s_p9_0[] = { + 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, +}; + +static float _vq_quantthresh__16c2_s_p9_0[] = { + -5120.5, -4189.5, -3258.5, -2327.5, -1396.5, -465.5, 465.5, 1396.5, + 2327.5, 3258.5, 4189.5, 5120.5, +}; + +static long _vq_quantmap__16c2_s_p9_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__16c2_s_p9_0 = { + _vq_quantthresh__16c2_s_p9_0, + _vq_quantmap__16c2_s_p9_0, + 13, + 13 +}; + +static static_codebook _16c2_s_p9_0 = { + 2, 169, + _vq_lengthlist__16c2_s_p9_0, + 1, -510275072, 1631393792, 4, 0, + _vq_quantlist__16c2_s_p9_0, + NULL, + &_vq_auxt__16c2_s_p9_0, + NULL, + 0 +}; + +static long _vq_quantlist__16c2_s_p9_1[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__16c2_s_p9_1[] = { + 1, 5, 5, 9, 8, 7, 7, 7, 6,10,11,11,11,11,11,11, + 11, 8, 7, 6, 8, 8,10, 9,10,10,10, 9,11,10,10,10, + 10,10, 8, 6, 6, 8, 8, 9, 8, 9, 8, 9,10,10,10,10, + 10,10,10,10, 8,10, 9, 9, 9, 9,10,10,10,10,10,10, + 10,10,10,10,10, 8, 9, 9, 9,10,10, 9,10,10,10,10, + 10,10,10,10,10,10,10,10, 9, 8, 9, 9,10,10,10,10, + 10,10,10,10,10,10,10,10, 9, 8, 8, 9, 9,10,10,10, + 10,10,10,10,10,10,10,10,10,10, 9,10, 9, 9,10,10, + 10,10,10,10,10,10,10,10,10,10,10, 9, 8, 9, 9,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, 9, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 8,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10, 9,10, 9,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10, 9,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10, +}; + +static float _vq_quantthresh__16c2_s_p9_1[] = { + -367.5, -318.5, -269.5, -220.5, -171.5, -122.5, -73.5, -24.5, + 24.5, 73.5, 122.5, 171.5, 220.5, 269.5, 318.5, 367.5, +}; + +static long _vq_quantmap__16c2_s_p9_1[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__16c2_s_p9_1 = { + _vq_quantthresh__16c2_s_p9_1, + _vq_quantmap__16c2_s_p9_1, + 17, + 17 +}; + +static static_codebook _16c2_s_p9_1 = { + 2, 289, + _vq_lengthlist__16c2_s_p9_1, + 1, -518488064, 1622704128, 5, 0, + _vq_quantlist__16c2_s_p9_1, + NULL, + &_vq_auxt__16c2_s_p9_1, + NULL, + 0 +}; + +static long _vq_quantlist__16c2_s_p9_2[] = { + 13, + 12, + 14, + 11, + 15, + 10, + 16, + 9, + 17, + 8, + 18, + 7, + 19, + 6, + 20, + 5, + 21, + 4, + 22, + 3, + 23, + 2, + 24, + 1, + 25, + 0, + 26, +}; + +static long _vq_lengthlist__16c2_s_p9_2[] = { + 1, 4, 4, 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 8, 7, 8, 7, 7, 4, 4, +}; + +static float _vq_quantthresh__16c2_s_p9_2[] = { + -12.5, -11.5, -10.5, -9.5, -8.5, -7.5, -6.5, -5.5, + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5, 10.5, + 11.5, 12.5, +}; + +static long _vq_quantmap__16c2_s_p9_2[] = { + 25, 23, 21, 19, 17, 15, 13, 11, + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, 12, 14, 16, 18, 20, + 22, 24, 26, +}; + +static encode_aux_threshmatch _vq_auxt__16c2_s_p9_2 = { + _vq_quantthresh__16c2_s_p9_2, + _vq_quantmap__16c2_s_p9_2, + 27, + 27 +}; + +static static_codebook _16c2_s_p9_2 = { + 1, 27, + _vq_lengthlist__16c2_s_p9_2, + 1, -528875520, 1611661312, 5, 0, + _vq_quantlist__16c2_s_p9_2, + NULL, + &_vq_auxt__16c2_s_p9_2, + NULL, + 0 +}; + +static long _huff_lengthlist__16c2_s_short[] = { + 7,10,11,11,11,14,15,15,17,14, 8, 6, 7, 7, 8, 9, + 11,11,14,17, 9, 6, 6, 6, 7, 7,10,11,15,16, 9, 6, + 6, 4, 4, 5, 8, 9,12,16,10, 6, 6, 4, 4, 4, 6, 9, + 13,16,10, 7, 6, 5, 4, 3, 5, 7,13,16,11, 9, 8, 7, + 6, 5, 5, 6,12,15,10,10,10, 9, 7, 6, 6, 7,11,15, + 13,13,13,13,11,10,10, 9,12,16,16,16,16,14,16,15, + 15,12,14,14, +}; + +static static_codebook _huff_book__16c2_s_short = { + 2, 100, + _huff_lengthlist__16c2_s_short, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__8c0_s_p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__8c0_s_p1_0[] = { + 1, 5, 4, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 0, + 0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 5, 8, 8, 0, 0, 0, 0, 0, 0, 7, 8, 9, 0, 0, 0, + 0, 0, 0, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 8, 8, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, + 0, 0, 0, 0, 7, 9, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 8, 8, 0, 0, 0, 0, + 0, 0, 8,10,10, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,10, 9, 0, 0, 0, + 0, 0, 0, 8, 9,11, 0, 0, 0, 0, 0, 0, 9,11,11, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9,10, 0, 0, + 0, 0, 0, 0, 9,11,10, 0, 0, 0, 0, 0, 0, 9,11,11, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 8, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0, + 0, 0, 0, 0, 8, 9,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 9,11,11, 0, + 0, 0, 0, 0, 0, 9,10,11, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7, 9,10, 0, 0, 0, 0, 0, 0, 9,11,11, + 0, 0, 0, 0, 0, 0, 8,11, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__8c0_s_p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__8c0_s_p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__8c0_s_p1_0 = { + _vq_quantthresh__8c0_s_p1_0, + _vq_quantmap__8c0_s_p1_0, + 3, + 3 +}; + +static static_codebook _8c0_s_p1_0 = { + 8, 6561, + _vq_lengthlist__8c0_s_p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__8c0_s_p1_0, + NULL, + &_vq_auxt__8c0_s_p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__8c0_s_p2_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__8c0_s_p2_0[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__8c0_s_p2_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__8c0_s_p2_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__8c0_s_p2_0 = { + _vq_quantthresh__8c0_s_p2_0, + _vq_quantmap__8c0_s_p2_0, + 5, + 5 +}; + +static static_codebook _8c0_s_p2_0 = { + 4, 625, + _vq_lengthlist__8c0_s_p2_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__8c0_s_p2_0, + NULL, + &_vq_auxt__8c0_s_p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__8c0_s_p3_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__8c0_s_p3_0[] = { + 1, 4, 4, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 6, 7, 7, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 5, 5, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 7, 8, 8, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6, 7, 7, 8, 8, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__8c0_s_p3_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__8c0_s_p3_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__8c0_s_p3_0 = { + _vq_quantthresh__8c0_s_p3_0, + _vq_quantmap__8c0_s_p3_0, + 5, + 5 +}; + +static static_codebook _8c0_s_p3_0 = { + 4, 625, + _vq_lengthlist__8c0_s_p3_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__8c0_s_p3_0, + NULL, + &_vq_auxt__8c0_s_p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__8c0_s_p4_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__8c0_s_p4_0[] = { + 1, 2, 3, 7, 7, 0, 0, 0, 0, 0, 0, 0, 6, 6, 0, 0, + 0, 0, 0, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, 7, 7, + 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0, + 8, 8, 0, 0, 0, 0, 0, 0, 0, 9, 8, 0, 0, 0, 0, 0, + 0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__8c0_s_p4_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__8c0_s_p4_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__8c0_s_p4_0 = { + _vq_quantthresh__8c0_s_p4_0, + _vq_quantmap__8c0_s_p4_0, + 9, + 9 +}; + +static static_codebook _8c0_s_p4_0 = { + 2, 81, + _vq_lengthlist__8c0_s_p4_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__8c0_s_p4_0, + NULL, + &_vq_auxt__8c0_s_p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__8c0_s_p5_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__8c0_s_p5_0[] = { + 1, 3, 3, 5, 5, 7, 6, 8, 8, 0, 0, 0, 7, 7, 7, 7, + 8, 8, 0, 0, 0, 7, 7, 7, 7, 8, 9, 0, 0, 0, 8, 8, + 8, 8, 9, 9, 0, 0, 0, 8, 8, 8, 8, 9, 9, 0, 0, 0, + 9, 9, 8, 8,10,10, 0, 0, 0, 9, 9, 8, 8,10,10, 0, + 0, 0,10,10, 9, 9,10,10, 0, 0, 0, 0, 0, 9, 9,10, + 10, +}; + +static float _vq_quantthresh__8c0_s_p5_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__8c0_s_p5_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__8c0_s_p5_0 = { + _vq_quantthresh__8c0_s_p5_0, + _vq_quantmap__8c0_s_p5_0, + 9, + 9 +}; + +static static_codebook _8c0_s_p5_0 = { + 2, 81, + _vq_lengthlist__8c0_s_p5_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__8c0_s_p5_0, + NULL, + &_vq_auxt__8c0_s_p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__8c0_s_p6_0[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__8c0_s_p6_0[] = { + 1, 3, 3, 6, 6, 8, 8, 9, 9, 8, 8,10, 9,10,10,11, + 11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,10,11,11, + 11,12, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,10,11, + 11,12,11, 0, 0, 0, 8, 8, 9, 9,10,10, 9, 9,10,10, + 11,11,12,12, 0, 0, 0, 8, 8, 9, 9,10,10, 9, 9,11, + 10,11,11,12,12, 0, 0, 0, 9, 9, 9, 9,10,10,10,10, + 11,11,11,12,12,12, 0, 0, 0, 9, 9, 9, 9,10,10,10, + 10,11,11,12,12,13,13, 0, 0, 0,10,10,10,10,11,11, + 10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0,10, 9,10, + 11,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9, 9, + 10, 9,10,11,12,12,13,13,14,13, 0, 0, 0, 0, 0, 9, + 9, 9,10,10,10,11,11,13,12,13,13, 0, 0, 0, 0, 0, + 10,10,10,10,11,11,12,12,13,13,14,14, 0, 0, 0, 0, + 0, 0, 0,10,10,11,11,12,12,13,13,13,14, 0, 0, 0, + 0, 0, 0, 0,11,11,11,11,12,12,13,14,14,14, 0, 0, + 0, 0, 0, 0, 0,11,11,11,11,12,12,13,13,14,13, 0, + 0, 0, 0, 0, 0, 0,11,11,12,12,13,13,14,14,14,14, + 0, 0, 0, 0, 0, 0, 0, 0, 0,12,12,12,12,13,13,14, + 14, +}; + +static float _vq_quantthresh__8c0_s_p6_0[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__8c0_s_p6_0[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__8c0_s_p6_0 = { + _vq_quantthresh__8c0_s_p6_0, + _vq_quantmap__8c0_s_p6_0, + 17, + 17 +}; + +static static_codebook _8c0_s_p6_0 = { + 2, 289, + _vq_lengthlist__8c0_s_p6_0, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__8c0_s_p6_0, + NULL, + &_vq_auxt__8c0_s_p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__8c0_s_p7_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__8c0_s_p7_0[] = { + 1, 4, 4, 7, 6, 6, 7, 6, 6, 4, 7, 7,11, 9,10,12, + 9,10, 4, 7, 7,10,10,10,11, 9, 9, 6,11,10,11,11, + 12,11,11,11, 6,10,10,11,11,12,11,10,10, 6, 9,10, + 11,11,11,11,10,10, 7,10,11,12,11,11,12,11,12, 6, + 9, 9,10, 9, 9,11,10,10, 6, 9, 9,10,10,10,11,10, + 10, +}; + +static float _vq_quantthresh__8c0_s_p7_0[] = { + -5.5, 5.5, +}; + +static long _vq_quantmap__8c0_s_p7_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__8c0_s_p7_0 = { + _vq_quantthresh__8c0_s_p7_0, + _vq_quantmap__8c0_s_p7_0, + 3, + 3 +}; + +static static_codebook _8c0_s_p7_0 = { + 4, 81, + _vq_lengthlist__8c0_s_p7_0, + 1, -529137664, 1618345984, 2, 0, + _vq_quantlist__8c0_s_p7_0, + NULL, + &_vq_auxt__8c0_s_p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__8c0_s_p7_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__8c0_s_p7_1[] = { + 1, 3, 3, 6, 6, 8, 8, 9, 9, 9, 9,10,10,10, 7, 7, + 8, 8, 9, 9, 9, 9,10,10, 9, 7, 7, 8, 8, 9, 9, 9, + 9,10,10,10, 8, 8, 9, 9, 9, 9, 9, 9,10,10,10, 8, + 8, 9, 9, 9, 9, 8, 9,10,10,10, 8, 8, 9, 9, 9,10, + 10,10,10,10,10, 9, 9, 9, 9, 9, 9,10,10,11,10,11, + 9, 9, 9, 9,10,10,10,10,11,11,11,10,10, 9, 9,10, + 10,10, 9,11,10,10,10,10,10,10, 9, 9,10,10,11,11, + 10,10,10, 9, 9, 9,10,10,10, +}; + +static float _vq_quantthresh__8c0_s_p7_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__8c0_s_p7_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__8c0_s_p7_1 = { + _vq_quantthresh__8c0_s_p7_1, + _vq_quantmap__8c0_s_p7_1, + 11, + 11 +}; + +static static_codebook _8c0_s_p7_1 = { + 2, 121, + _vq_lengthlist__8c0_s_p7_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__8c0_s_p7_1, + NULL, + &_vq_auxt__8c0_s_p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__8c0_s_p8_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__8c0_s_p8_0[] = { + 1, 4, 4, 7, 6, 7, 7, 7, 7, 8, 8, 9, 9, 7, 6, 6, + 7, 7, 8, 8, 7, 7, 8, 9,10,10, 7, 6, 6, 7, 7, 8, + 7, 7, 7, 9, 9,10,12, 0, 8, 8, 8, 8, 8, 9, 8, 8, + 9, 9,10,10, 0, 8, 8, 8, 8, 8, 9, 8, 9, 9, 9,11, + 10, 0, 0,13, 9, 8, 9, 9, 9, 9,10,10,11,11, 0,13, + 0, 9, 9, 9, 9, 9, 9,11,10,11,11, 0, 0, 0, 8, 9, + 10, 9,10,10,13,11,12,12, 0, 0, 0, 8, 9, 9, 9,10, + 10,13,12,12,13, 0, 0, 0,12, 0,10,10,12,11,10,11, + 12,12, 0, 0, 0,13,13,10,10,10,11,12, 0,13, 0, 0, + 0, 0, 0, 0,13,11, 0,12,12,12,13,12, 0, 0, 0, 0, + 0, 0,13,13,11,13,13,11,12, +}; + +static float _vq_quantthresh__8c0_s_p8_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__8c0_s_p8_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__8c0_s_p8_0 = { + _vq_quantthresh__8c0_s_p8_0, + _vq_quantmap__8c0_s_p8_0, + 13, + 13 +}; + +static static_codebook _8c0_s_p8_0 = { + 2, 169, + _vq_lengthlist__8c0_s_p8_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__8c0_s_p8_0, + NULL, + &_vq_auxt__8c0_s_p8_0, + NULL, + 0 +}; + +static long _vq_quantlist__8c0_s_p8_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__8c0_s_p8_1[] = { + 1, 3, 4, 5, 5, 7, 6, 6, 6, 5, 7, 7, 7, 6, 6, 7, + 7, 7, 6, 6, 7, 7, 7, 6, 6, +}; + +static float _vq_quantthresh__8c0_s_p8_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__8c0_s_p8_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__8c0_s_p8_1 = { + _vq_quantthresh__8c0_s_p8_1, + _vq_quantmap__8c0_s_p8_1, + 5, + 5 +}; + +static static_codebook _8c0_s_p8_1 = { + 2, 25, + _vq_lengthlist__8c0_s_p8_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__8c0_s_p8_1, + NULL, + &_vq_auxt__8c0_s_p8_1, + NULL, + 0 +}; + +static long _vq_quantlist__8c0_s_p9_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__8c0_s_p9_0[] = { + 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, +}; + +static float _vq_quantthresh__8c0_s_p9_0[] = { + -157.5, 157.5, +}; + +static long _vq_quantmap__8c0_s_p9_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__8c0_s_p9_0 = { + _vq_quantthresh__8c0_s_p9_0, + _vq_quantmap__8c0_s_p9_0, + 3, + 3 +}; + +static static_codebook _8c0_s_p9_0 = { + 4, 81, + _vq_lengthlist__8c0_s_p9_0, + 1, -518803456, 1628680192, 2, 0, + _vq_quantlist__8c0_s_p9_0, + NULL, + &_vq_auxt__8c0_s_p9_0, + NULL, + 0 +}; + +static long _vq_quantlist__8c0_s_p9_1[] = { + 7, + 6, + 8, + 5, + 9, + 4, + 10, + 3, + 11, + 2, + 12, + 1, + 13, + 0, + 14, +}; + +static long _vq_lengthlist__8c0_s_p9_1[] = { + 1, 4, 4, 5, 5,10, 8,11,11,11,11,11,11,11,11, 6, + 6, 6, 7, 6,11,10,11,11,11,11,11,11,11,11, 7, 5, + 6, 6, 6, 8, 7,11,11,11,11,11,11,11,11,11, 7, 8, + 8, 8, 9, 9,11,11,11,11,11,11,11,11,11, 9, 8, 7, + 8, 9,11,11,11,11,11,11,11,11,11,11,11,10,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,10,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11, +}; + +static float _vq_quantthresh__8c0_s_p9_1[] = { + -136.5, -115.5, -94.5, -73.5, -52.5, -31.5, -10.5, 10.5, + 31.5, 52.5, 73.5, 94.5, 115.5, 136.5, +}; + +static long _vq_quantmap__8c0_s_p9_1[] = { + 13, 11, 9, 7, 5, 3, 1, 0, + 2, 4, 6, 8, 10, 12, 14, +}; + +static encode_aux_threshmatch _vq_auxt__8c0_s_p9_1 = { + _vq_quantthresh__8c0_s_p9_1, + _vq_quantmap__8c0_s_p9_1, + 15, + 15 +}; + +static static_codebook _8c0_s_p9_1 = { + 2, 225, + _vq_lengthlist__8c0_s_p9_1, + 1, -520986624, 1620377600, 4, 0, + _vq_quantlist__8c0_s_p9_1, + NULL, + &_vq_auxt__8c0_s_p9_1, + NULL, + 0 +}; + +static long _vq_quantlist__8c0_s_p9_2[] = { + 10, + 9, + 11, + 8, + 12, + 7, + 13, + 6, + 14, + 5, + 15, + 4, + 16, + 3, + 17, + 2, + 18, + 1, + 19, + 0, + 20, +}; + +static long _vq_lengthlist__8c0_s_p9_2[] = { + 1, 5, 5, 7, 7, 8, 7, 8, 8,10,10, 9, 9,10,10,10, + 11,11,10,12,11,12,12,12, 9, 8, 8, 8, 8, 8, 9,10, + 10,10,10,11,11,11,10,11,11,12,12,11,12, 8, 8, 7, + 7, 8, 9,10,10,10, 9,10,10, 9,10,10,11,11,11,11, + 11,11, 9, 9, 9, 9, 8, 9,10,10,11,10,10,11,11,12, + 10,10,12,12,11,11,10, 9, 9,10, 8, 9,10,10,10, 9, + 10,10,11,11,10,11,10,10,10,12,12,12, 9,10, 9,10, + 9, 9,10,10,11,11,11,11,10,10,10,11,12,11,12,11, + 12,10,11,10,11, 9,10, 9,10, 9,10,10, 9,10,10,11, + 10,11,11,11,11,12,11, 9,10,10,10,10,11,11,11,11, + 11,10,11,11,11,11,10,12,10,12,12,11,12,10,10,11, + 10, 9,11,10,11, 9,10,11,10,10,10,11,11,11,11,12, + 12,10, 9, 9,11,10, 9,12,11,10,12,12,11,11,11,11, + 10,11,11,12,11,10,12, 9,11,10,11,10,10,11,10,11, + 9,10,10,10,11,12,11,11,12,11,10,10,11,11, 9,10, + 10,12,10,11,10,10,10, 9,10,10,10,10, 9,10,10,11, + 11,11,11,12,11,10,10,10,10,11,11,10,11,11, 9,11, + 10,12,10,12,11,10,11,10,10,10,11,10,10,11,11,10, + 11,10,10,10,10,11,11,12,10,10,10,11,10,11,12,11, + 10,11,10,10,11,11,10,12,10, 9,10,10,11,11,11,10, + 12,10,10,11,11,11,10,10,11,10,10,10,11,10,11,10, + 12,11,11,10,10,10,12,10,10,11, 9,10,11,11,11,10, + 10,11,10,10, 9,11,11,12,12,11,12,11,11,11,11,11, + 11, 9,10,11,10,12,10,10,10,10,11,10,10,11,10,10, + 12,10,10,10,10,10, 9,12,10,10,10,10,12, 9,11,10, + 10,11,10,12,12,10,12,12,12,10,10,10,10, 9,10,11, + 10,10,12,10,10,12,11,10,11,10,10,12,11,10,12,10, + 10,11, 9,11,10, 9,10, 9,10, +}; + +static float _vq_quantthresh__8c0_s_p9_2[] = { + -9.5, -8.5, -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, + -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, + 6.5, 7.5, 8.5, 9.5, +}; + +static long _vq_quantmap__8c0_s_p9_2[] = { + 19, 17, 15, 13, 11, 9, 7, 5, + 3, 1, 0, 2, 4, 6, 8, 10, + 12, 14, 16, 18, 20, +}; + +static encode_aux_threshmatch _vq_auxt__8c0_s_p9_2 = { + _vq_quantthresh__8c0_s_p9_2, + _vq_quantmap__8c0_s_p9_2, + 21, + 21 +}; + +static static_codebook _8c0_s_p9_2 = { + 2, 441, + _vq_lengthlist__8c0_s_p9_2, + 1, -529268736, 1611661312, 5, 0, + _vq_quantlist__8c0_s_p9_2, + NULL, + &_vq_auxt__8c0_s_p9_2, + NULL, + 0 +}; + +static long _huff_lengthlist__8c0_s_single[] = { + 4, 5,18, 7,10, 6, 7, 8, 9,10, 5, 2,18, 5, 7, 5, + 6, 7, 8,11,17,17,17,17,17,17,17,17,17,17, 7, 4, + 17, 6, 9, 6, 8,10,12,15,11, 7,17, 9, 6, 6, 7, 9, + 11,15, 6, 4,17, 6, 6, 4, 5, 8,11,16, 6, 6,17, 8, + 6, 5, 6, 9,13,16, 8, 9,17,11, 9, 8, 8,11,13,17, + 9,12,17,15,14,13,12,13,14,17,12,15,17,17,17,17, + 17,16,17,17, +}; + +static static_codebook _huff_book__8c0_s_single = { + 2, 100, + _huff_lengthlist__8c0_s_single, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__8c1_s_p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__8c1_s_p1_0[] = { + 1, 5, 5, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 0, + 0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 5, 8, 7, 0, 0, 0, 0, 0, 0, 7, 8, 9, 0, 0, 0, + 0, 0, 0, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 7, 8, 0, 0, 0, 0, 0, 0, 7, 9, 8, 0, 0, + 0, 0, 0, 0, 7, 9, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 8, 8, 0, 0, 0, 0, + 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, + 0, 0, 0, 8, 8,10, 0, 0, 0, 0, 0, 0, 9,10,10, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, + 0, 0, 0, 0, 8,10, 9, 0, 0, 0, 0, 0, 0, 9,10,10, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 8, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0, + 0, 0, 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 9,10,10, 0, + 0, 0, 0, 0, 0, 8, 9,10, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 9,10,10, + 0, 0, 0, 0, 0, 0, 8,10, 8, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__8c1_s_p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__8c1_s_p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__8c1_s_p1_0 = { + _vq_quantthresh__8c1_s_p1_0, + _vq_quantmap__8c1_s_p1_0, + 3, + 3 +}; + +static static_codebook _8c1_s_p1_0 = { + 8, 6561, + _vq_lengthlist__8c1_s_p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__8c1_s_p1_0, + NULL, + &_vq_auxt__8c1_s_p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__8c1_s_p2_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__8c1_s_p2_0[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__8c1_s_p2_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__8c1_s_p2_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__8c1_s_p2_0 = { + _vq_quantthresh__8c1_s_p2_0, + _vq_quantmap__8c1_s_p2_0, + 5, + 5 +}; + +static static_codebook _8c1_s_p2_0 = { + 4, 625, + _vq_lengthlist__8c1_s_p2_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__8c1_s_p2_0, + NULL, + &_vq_auxt__8c1_s_p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__8c1_s_p3_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__8c1_s_p3_0[] = { + 2, 4, 4, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 6, 6, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 4, 4, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 7, 7, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6, 6, 6, 7, 7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__8c1_s_p3_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__8c1_s_p3_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__8c1_s_p3_0 = { + _vq_quantthresh__8c1_s_p3_0, + _vq_quantmap__8c1_s_p3_0, + 5, + 5 +}; + +static static_codebook _8c1_s_p3_0 = { + 4, 625, + _vq_lengthlist__8c1_s_p3_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__8c1_s_p3_0, + NULL, + &_vq_auxt__8c1_s_p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__8c1_s_p4_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__8c1_s_p4_0[] = { + 1, 2, 3, 7, 7, 0, 0, 0, 0, 0, 0, 0, 6, 6, 0, 0, + 0, 0, 0, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, 7, 7, + 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0, + 8, 8, 0, 0, 0, 0, 0, 0, 0, 9, 8, 0, 0, 0, 0, 0, + 0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__8c1_s_p4_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__8c1_s_p4_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__8c1_s_p4_0 = { + _vq_quantthresh__8c1_s_p4_0, + _vq_quantmap__8c1_s_p4_0, + 9, + 9 +}; + +static static_codebook _8c1_s_p4_0 = { + 2, 81, + _vq_lengthlist__8c1_s_p4_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__8c1_s_p4_0, + NULL, + &_vq_auxt__8c1_s_p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__8c1_s_p5_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__8c1_s_p5_0[] = { + 1, 3, 3, 4, 5, 6, 6, 8, 8, 0, 0, 0, 8, 8, 7, 7, + 9, 9, 0, 0, 0, 8, 8, 7, 7, 9, 9, 0, 0, 0, 9,10, + 8, 8, 9, 9, 0, 0, 0,10,10, 8, 8, 9, 9, 0, 0, 0, + 11,10, 8, 8,10,10, 0, 0, 0,11,11, 8, 8,10,10, 0, + 0, 0,12,12, 9, 9,10,10, 0, 0, 0, 0, 0, 9, 9,10, + 10, +}; + +static float _vq_quantthresh__8c1_s_p5_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__8c1_s_p5_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__8c1_s_p5_0 = { + _vq_quantthresh__8c1_s_p5_0, + _vq_quantmap__8c1_s_p5_0, + 9, + 9 +}; + +static static_codebook _8c1_s_p5_0 = { + 2, 81, + _vq_lengthlist__8c1_s_p5_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__8c1_s_p5_0, + NULL, + &_vq_auxt__8c1_s_p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__8c1_s_p6_0[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__8c1_s_p6_0[] = { + 1, 3, 3, 5, 5, 8, 8, 8, 8, 9, 9,10,10,11,11,11, + 11, 0, 0, 0, 8, 8, 8, 8, 9, 9, 9, 9,10,10,11,11, + 12,12, 0, 0, 0, 8, 8, 8, 8, 9, 9, 9, 9,10,10,11, + 11,12,12, 0, 0, 0, 9, 9, 8, 8,10,10,10,10,11,11, + 12,12,12,12, 0, 0, 0, 9, 9, 8, 8,10,10,10,10,11, + 11,12,12,12,12, 0, 0, 0,10,10, 9, 9,10,10,10,10, + 11,11,12,12,13,13, 0, 0, 0,10,10, 9, 9,10,10,10, + 10,11,11,12,12,13,13, 0, 0, 0,11,11, 9, 9,10,10, + 10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9, 9,10, + 10,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9, 9, + 10,10,11,11,12,12,12,12,13,13, 0, 0, 0, 0, 0, 9, + 9,10,10,11,11,12,11,12,12,13,13, 0, 0, 0, 0, 0, + 10,10,11,11,11,11,12,12,13,12,13,13, 0, 0, 0, 0, + 0, 0, 0,11,10,11,11,12,12,13,13,13,13, 0, 0, 0, + 0, 0, 0, 0,11,11,12,12,12,12,13,13,13,14, 0, 0, + 0, 0, 0, 0, 0,11,11,12,12,12,12,13,13,14,13, 0, + 0, 0, 0, 0, 0, 0,12,12,12,12,13,13,13,13,14,14, + 0, 0, 0, 0, 0, 0, 0, 0, 0,12,12,13,13,13,13,14, + 14, +}; + +static float _vq_quantthresh__8c1_s_p6_0[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__8c1_s_p6_0[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__8c1_s_p6_0 = { + _vq_quantthresh__8c1_s_p6_0, + _vq_quantmap__8c1_s_p6_0, + 17, + 17 +}; + +static static_codebook _8c1_s_p6_0 = { + 2, 289, + _vq_lengthlist__8c1_s_p6_0, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__8c1_s_p6_0, + NULL, + &_vq_auxt__8c1_s_p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__8c1_s_p7_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__8c1_s_p7_0[] = { + 1, 4, 4, 6, 6, 6, 7, 6, 6, 4, 7, 7,10, 9, 9,10, + 9, 9, 5, 7, 7,10, 9, 9,10, 9, 9, 6,10,10,10,10, + 10,11,10,10, 6, 9, 9,10, 9,10,11,10,10, 6, 9, 9, + 10, 9, 9,11, 9,10, 7,10,10,11,11,11,11,10,10, 6, + 9, 9,10,10,10,11, 9, 9, 6, 9, 9,10,10,10,10, 9, + 9, +}; + +static float _vq_quantthresh__8c1_s_p7_0[] = { + -5.5, 5.5, +}; + +static long _vq_quantmap__8c1_s_p7_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__8c1_s_p7_0 = { + _vq_quantthresh__8c1_s_p7_0, + _vq_quantmap__8c1_s_p7_0, + 3, + 3 +}; + +static static_codebook _8c1_s_p7_0 = { + 4, 81, + _vq_lengthlist__8c1_s_p7_0, + 1, -529137664, 1618345984, 2, 0, + _vq_quantlist__8c1_s_p7_0, + NULL, + &_vq_auxt__8c1_s_p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__8c1_s_p7_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__8c1_s_p7_1[] = { + 2, 3, 3, 5, 5, 7, 7, 7, 7, 7, 7,10,10, 9, 7, 7, + 7, 7, 8, 8, 8, 8, 9, 9, 9, 7, 7, 7, 7, 8, 8, 8, + 8,10,10,10, 7, 7, 7, 7, 8, 8, 8, 8,10,10,10, 7, + 7, 7, 7, 8, 8, 8, 8,10,10,10, 8, 8, 8, 8, 8, 8, + 8, 8,10,10,10, 8, 8, 8, 8, 8, 8, 8, 8,10,10,10, + 8, 8, 8, 8, 8, 8, 8, 8,10,10,10,10,10, 8, 8, 8, + 8, 8, 8,10,10,10,10,10, 8, 8, 8, 8, 8, 8,10,10, + 10,10,10, 8, 8, 8, 8, 8, 8, +}; + +static float _vq_quantthresh__8c1_s_p7_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__8c1_s_p7_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__8c1_s_p7_1 = { + _vq_quantthresh__8c1_s_p7_1, + _vq_quantmap__8c1_s_p7_1, + 11, + 11 +}; + +static static_codebook _8c1_s_p7_1 = { + 2, 121, + _vq_lengthlist__8c1_s_p7_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__8c1_s_p7_1, + NULL, + &_vq_auxt__8c1_s_p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__8c1_s_p8_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__8c1_s_p8_0[] = { + 1, 4, 4, 6, 6, 8, 8, 8, 8, 9, 9,10,10, 7, 5, 5, + 7, 7, 8, 8, 8, 8, 9,10,11,11, 7, 5, 5, 7, 7, 8, + 8, 9, 9,10,10,11,11, 0, 8, 8, 8, 8, 9, 9, 9, 9, + 9,10,11,11, 0, 8, 8, 8, 8, 9, 9, 9, 9,10,10,11, + 11, 0,12,12, 9, 9, 9, 9,10, 9,10,11,11,11, 0,13, + 12, 9, 8, 9, 9,10,10,11,11,12,11, 0, 0, 0, 9, 9, + 9, 9,10,10,11,11,12,12, 0, 0, 0,10,10, 9, 9,10, + 10,11,11,12,12, 0, 0, 0,13,13,10,10,11,11,12,11, + 13,12, 0, 0, 0,14,14,10,10,11,10,11,11,12,12, 0, + 0, 0, 0, 0,12,12,11,11,12,12,13,13, 0, 0, 0, 0, + 0,12,12,11,10,12,11,13,12, +}; + +static float _vq_quantthresh__8c1_s_p8_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__8c1_s_p8_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__8c1_s_p8_0 = { + _vq_quantthresh__8c1_s_p8_0, + _vq_quantmap__8c1_s_p8_0, + 13, + 13 +}; + +static static_codebook _8c1_s_p8_0 = { + 2, 169, + _vq_lengthlist__8c1_s_p8_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__8c1_s_p8_0, + NULL, + &_vq_auxt__8c1_s_p8_0, + NULL, + 0 +}; + +static long _vq_quantlist__8c1_s_p8_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__8c1_s_p8_1[] = { + 2, 3, 3, 5, 5, 6, 6, 6, 5, 5, 6, 6, 6, 5, 5, 6, + 6, 6, 5, 5, 6, 6, 6, 5, 5, +}; + +static float _vq_quantthresh__8c1_s_p8_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__8c1_s_p8_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__8c1_s_p8_1 = { + _vq_quantthresh__8c1_s_p8_1, + _vq_quantmap__8c1_s_p8_1, + 5, + 5 +}; + +static static_codebook _8c1_s_p8_1 = { + 2, 25, + _vq_lengthlist__8c1_s_p8_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__8c1_s_p8_1, + NULL, + &_vq_auxt__8c1_s_p8_1, + NULL, + 0 +}; + +static long _vq_quantlist__8c1_s_p9_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__8c1_s_p9_0[] = { + 1, 3, 3,10,10,10,10,10,10,10,10,10,10, 5, 6, 6, + 10,10,10,10,10,10,10,10,10,10, 6, 7, 8,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10, 9, 9, 9, 9, +}; + +static float _vq_quantthresh__8c1_s_p9_0[] = { + -1732.5, -1417.5, -1102.5, -787.5, -472.5, -157.5, 157.5, 472.5, + 787.5, 1102.5, 1417.5, 1732.5, +}; + +static long _vq_quantmap__8c1_s_p9_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__8c1_s_p9_0 = { + _vq_quantthresh__8c1_s_p9_0, + _vq_quantmap__8c1_s_p9_0, + 13, + 13 +}; + +static static_codebook _8c1_s_p9_0 = { + 2, 169, + _vq_lengthlist__8c1_s_p9_0, + 1, -513964032, 1628680192, 4, 0, + _vq_quantlist__8c1_s_p9_0, + NULL, + &_vq_auxt__8c1_s_p9_0, + NULL, + 0 +}; + +static long _vq_quantlist__8c1_s_p9_1[] = { + 7, + 6, + 8, + 5, + 9, + 4, + 10, + 3, + 11, + 2, + 12, + 1, + 13, + 0, + 14, +}; + +static long _vq_lengthlist__8c1_s_p9_1[] = { + 1, 4, 4, 5, 5, 7, 7, 9, 9,11,11,12,12,13,13, 6, + 5, 5, 6, 6, 9, 9,10,10,12,12,12,13,15,14, 6, 5, + 5, 7, 7, 9, 9,10,10,12,12,12,13,14,13,17, 7, 7, + 8, 8,10,10,11,11,12,13,13,13,13,13,17, 7, 7, 8, + 8,10,10,11,11,13,13,13,13,14,14,17,11,11, 9, 9, + 11,11,12,12,12,13,13,14,15,13,17,12,12, 9, 9,11, + 11,12,12,13,13,13,13,14,16,17,17,17,11,12,12,12, + 13,13,13,14,15,14,15,15,17,17,17,12,12,11,11,13, + 13,14,14,15,14,15,15,17,17,17,15,15,13,13,14,14, + 15,14,15,15,16,15,17,17,17,15,15,13,13,13,14,14, + 15,15,15,15,16,17,17,17,17,16,14,15,14,14,15,14, + 14,15,15,15,17,17,17,17,17,14,14,16,14,15,15,15, + 15,15,15,17,17,17,17,17,17,16,16,15,17,15,15,14, + 17,15,17,16,17,17,17,17,16,15,14,15,15,15,15,15, + 15, +}; + +static float _vq_quantthresh__8c1_s_p9_1[] = { + -136.5, -115.5, -94.5, -73.5, -52.5, -31.5, -10.5, 10.5, + 31.5, 52.5, 73.5, 94.5, 115.5, 136.5, +}; + +static long _vq_quantmap__8c1_s_p9_1[] = { + 13, 11, 9, 7, 5, 3, 1, 0, + 2, 4, 6, 8, 10, 12, 14, +}; + +static encode_aux_threshmatch _vq_auxt__8c1_s_p9_1 = { + _vq_quantthresh__8c1_s_p9_1, + _vq_quantmap__8c1_s_p9_1, + 15, + 15 +}; + +static static_codebook _8c1_s_p9_1 = { + 2, 225, + _vq_lengthlist__8c1_s_p9_1, + 1, -520986624, 1620377600, 4, 0, + _vq_quantlist__8c1_s_p9_1, + NULL, + &_vq_auxt__8c1_s_p9_1, + NULL, + 0 +}; + +static long _vq_quantlist__8c1_s_p9_2[] = { + 10, + 9, + 11, + 8, + 12, + 7, + 13, + 6, + 14, + 5, + 15, + 4, + 16, + 3, + 17, + 2, + 18, + 1, + 19, + 0, + 20, +}; + +static long _vq_lengthlist__8c1_s_p9_2[] = { + 2, 4, 4, 6, 6, 7, 7, 8, 8, 8, 8, 9, 8, 9, 9, 9, + 9, 9, 9, 9, 9,11,11,12, 7, 7, 7, 7, 8, 8, 9, 9, + 9, 9,10,10,10,10,10,10,10,10,11,11,11, 7, 7, 7, + 7, 8, 8, 9, 8, 9, 9, 9, 9, 9, 9,10,10,10,10,11, + 11,12, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9,10,10,10,10, + 10,10,10,10,11,11,11, 7, 7, 8, 8, 8, 8, 9, 9, 9, + 9,10,10,10,10,10,10,10,10,11,11,11, 8, 8, 8, 8, + 9, 9, 9, 9, 9, 9,10,10,10,10,10,10,10,10,11,11, + 11, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9,10,10,10,10,10, + 10,10,10,11,12,11, 9, 9, 8, 9, 9, 9, 9, 9,10,10, + 10,10,10,10,10,10,10,10,11,11,11,11,11, 8, 8, 9, + 9, 9, 9,10,10,10,10,10,10,10,10,10,10,11,12,11, + 12,11, 9, 9, 9, 9, 9,10,10,10,10,10,10,10,10,10, + 10,10,11,11,11,11,11, 9, 9, 9, 9,10,10,10,10,10, + 10,10,10,10,10,10,10,12,11,12,11,11, 9, 9, 9,10, + 10,10,10,10,10,10,10,10,10,10,10,10,12,11,11,11, + 11,11,11,10,10,10,10,10,10,10,10,10,10,10,10,10, + 11,11,11,12,11,11,12,11,10,10,10,10,10,10,10,10, + 10,10,10,10,11,10,11,11,11,11,11,11,11,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,11,11,12,11,12, + 11,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 11,11,12,11,12,11,11,11,11,10,10,10,10,10,10,10, + 10,10,10,10,10,11,11,12,11,11,12,11,11,12,10,10, + 11,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11, + 11,11,11,10,10,10,10,10,10,10,10,10,10,10,10,12, + 12,11,12,11,11,12,12,12,11,11,10,10,10,10,10,10, + 10,10,10,11,12,12,11,12,12,11,12,11,11,11,11,10, + 10,10,10,10,10,10,10,10,10, +}; + +static float _vq_quantthresh__8c1_s_p9_2[] = { + -9.5, -8.5, -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, + -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, + 6.5, 7.5, 8.5, 9.5, +}; + +static long _vq_quantmap__8c1_s_p9_2[] = { + 19, 17, 15, 13, 11, 9, 7, 5, + 3, 1, 0, 2, 4, 6, 8, 10, + 12, 14, 16, 18, 20, +}; + +static encode_aux_threshmatch _vq_auxt__8c1_s_p9_2 = { + _vq_quantthresh__8c1_s_p9_2, + _vq_quantmap__8c1_s_p9_2, + 21, + 21 +}; + +static static_codebook _8c1_s_p9_2 = { + 2, 441, + _vq_lengthlist__8c1_s_p9_2, + 1, -529268736, 1611661312, 5, 0, + _vq_quantlist__8c1_s_p9_2, + NULL, + &_vq_auxt__8c1_s_p9_2, + NULL, + 0 +}; + +static long _huff_lengthlist__8c1_s_single[] = { + 4, 6,18, 8,11, 8, 8, 9, 9,10, 4, 4,18, 5, 9, 5, + 6, 7, 8,10,18,18,18,18,17,17,17,17,17,17, 7, 5, + 17, 6,11, 6, 7, 8, 9,12,12, 9,17,12, 8, 8, 9,10, + 10,13, 7, 5,17, 6, 8, 4, 5, 6, 8,10, 6, 5,17, 6, + 8, 5, 4, 5, 7, 9, 7, 7,17, 8, 9, 6, 5, 5, 6, 8, + 8, 8,17, 9,11, 8, 6, 6, 6, 7, 9,10,17,12,12,10, + 9, 7, 7, 8, +}; + +static static_codebook _huff_book__8c1_s_single = { + 2, 100, + _huff_lengthlist__8c1_s_single, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__44c2_s_long[] = { + 6, 6,12,10,10,10, 9,10,12,12, 6, 1,10, 5, 6, 6, + 7, 9,11,14,12, 9, 8,11, 7, 8, 9,11,13,15,10, 5, + 12, 7, 8, 7, 9,12,14,15,10, 6, 7, 8, 5, 6, 7, 9, + 12,14, 9, 6, 8, 7, 6, 6, 7, 9,12,12, 9, 7, 9, 9, + 7, 6, 6, 7,10,10,10, 9,10,11, 8, 7, 6, 6, 8,10, + 12,11,13,13,11,10, 8, 8, 8,10,11,13,15,15,14,13, + 10, 8, 8, 9, +}; + +static static_codebook _huff_book__44c2_s_long = { + 2, 100, + _huff_lengthlist__44c2_s_long, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__44c2_s_p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44c2_s_p1_0[] = { + 2, 4, 4, 0, 0, 0, 0, 0, 0, 5, 6, 6, 0, 0, 0, 0, + 0, 0, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, 0, + 0, 0, 0, 6, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 6, 8, 7, 0, 0, + 0, 0, 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 0, + 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, 0, + 0, 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 8, 8, 0, 0, + 0, 0, 0, 0, 8, 9, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 7, 7, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, + 0, 0, 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 6, 8, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, + 0, 0, 0, 0, 0, 8, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9, + 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c2_s_p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44c2_s_p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44c2_s_p1_0 = { + _vq_quantthresh__44c2_s_p1_0, + _vq_quantmap__44c2_s_p1_0, + 3, + 3 +}; + +static static_codebook _44c2_s_p1_0 = { + 8, 6561, + _vq_lengthlist__44c2_s_p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44c2_s_p1_0, + NULL, + &_vq_auxt__44c2_s_p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c2_s_p2_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c2_s_p2_0[] = { + 1, 4, 4, 0, 0, 0, 7, 7, 0, 0, 0, 7, 7, 0, 0, 0, + 8, 8, 0, 0, 0, 0, 0, 0, 0, 4, 6, 6, 0, 0, 0, 8, + 8, 0, 0, 0, 8, 8, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, + 0, 0, 4, 6, 6, 0, 0, 0, 8, 8, 0, 0, 0, 8, 8, 0, + 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, 0,11,11, 0, 0, + 0,11,11, 0, 0, 0,12,11, 0, 0, 0, 0, 0, 0, 0, 7, + 8, 8, 0, 0, 0,10,11, 0, 0, 0,11,11, 0, 0, 0,11, + 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 6, 8, 8, 0, 0, 0,11,11, 0, 0, 0,11,11, + 0, 0, 0,12,12, 0, 0, 0, 0, 0, 0, 0, 6, 8, 8, 0, + 0, 0,10,11, 0, 0, 0,10,11, 0, 0, 0,11,11, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 8, 9, 9, 0, 0, 0,11,12, 0, 0, 0,11,12, 0, 0, 0, + 12,11, 0, 0, 0, 0, 0, 0, 0, 8,10, 9, 0, 0, 0,12, + 11, 0, 0, 0,12,11, 0, 0, 0,11,12, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c2_s_p2_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c2_s_p2_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c2_s_p2_0 = { + _vq_quantthresh__44c2_s_p2_0, + _vq_quantmap__44c2_s_p2_0, + 5, + 5 +}; + +static static_codebook _44c2_s_p2_0 = { + 4, 625, + _vq_lengthlist__44c2_s_p2_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c2_s_p2_0, + NULL, + &_vq_auxt__44c2_s_p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c2_s_p3_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c2_s_p3_0[] = { + 2, 4, 3, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 6, 6, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 4, 4, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6, 6, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c2_s_p3_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c2_s_p3_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c2_s_p3_0 = { + _vq_quantthresh__44c2_s_p3_0, + _vq_quantmap__44c2_s_p3_0, + 5, + 5 +}; + +static static_codebook _44c2_s_p3_0 = { + 4, 625, + _vq_lengthlist__44c2_s_p3_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c2_s_p3_0, + NULL, + &_vq_auxt__44c2_s_p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c2_s_p4_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44c2_s_p4_0[] = { + 1, 3, 3, 6, 6, 0, 0, 0, 0, 0, 6, 6, 6, 6, 0, 0, + 0, 0, 0, 6, 6, 6, 6, 0, 0, 0, 0, 0, 7, 7, 6, 6, + 0, 0, 0, 0, 0, 0, 0, 6, 7, 0, 0, 0, 0, 0, 0, 0, + 7, 8, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, + 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c2_s_p4_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44c2_s_p4_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44c2_s_p4_0 = { + _vq_quantthresh__44c2_s_p4_0, + _vq_quantmap__44c2_s_p4_0, + 9, + 9 +}; + +static static_codebook _44c2_s_p4_0 = { + 2, 81, + _vq_lengthlist__44c2_s_p4_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44c2_s_p4_0, + NULL, + &_vq_auxt__44c2_s_p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c2_s_p5_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44c2_s_p5_0[] = { + 1, 3, 3, 6, 6, 7, 7, 9, 9, 0, 7, 7, 7, 7, 7, 7, + 9, 9, 0, 7, 7, 7, 7, 7, 7, 9, 9, 0, 8, 8, 7, 7, + 8, 8,10,10, 0, 0, 0, 7, 7, 8, 8,10,10, 0, 0, 0, + 9, 9, 8, 8,10,10, 0, 0, 0, 9, 9, 8, 8,10,10, 0, + 0, 0,10,10, 9, 9,11,11, 0, 0, 0, 0, 0, 9, 9,11, + 11, +}; + +static float _vq_quantthresh__44c2_s_p5_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44c2_s_p5_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44c2_s_p5_0 = { + _vq_quantthresh__44c2_s_p5_0, + _vq_quantmap__44c2_s_p5_0, + 9, + 9 +}; + +static static_codebook _44c2_s_p5_0 = { + 2, 81, + _vq_lengthlist__44c2_s_p5_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44c2_s_p5_0, + NULL, + &_vq_auxt__44c2_s_p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c2_s_p6_0[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44c2_s_p6_0[] = { + 1, 4, 3, 6, 6, 8, 8, 9, 9, 9, 9, 9, 9,10,10,11, + 11, 0, 7, 7, 7, 7, 8, 8, 9, 9, 9, 9,10,10,11,11, + 12,11, 0, 7, 7, 7, 7, 8, 8, 9, 9, 9, 9,10,10,11, + 11,11,12, 0, 8, 8, 7, 7, 9, 9,10,10, 9, 9,10,10, + 11,11,12,12, 0, 0, 0, 7, 7, 9, 9,10,10,10, 9,10, + 10,11,11,12,12, 0, 0, 0, 8, 8, 9, 9,10,10,10,10, + 11,11,11,11,12,12, 0, 0, 0, 8, 8, 9, 9,10,10,10, + 10,11,11,12,12,12,12, 0, 0, 0, 9, 9, 9, 9,10,10, + 10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0, 9, 9,10, + 10,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9, 9, + 10,10,11,11,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9, + 9,10,10,11,11,11,11,12,12,13,13, 0, 0, 0, 0, 0, + 10,10,10,10,11,11,12,12,13,12,13,13, 0, 0, 0, 0, + 0, 0, 0,10,10,11,11,12,12,13,13,13,13, 0, 0, 0, + 0, 0, 0, 0,11,11,12,12,12,12,13,13,13,14, 0, 0, + 0, 0, 0, 0, 0,11,11,12,12,12,12,13,13,13,14, 0, + 0, 0, 0, 0, 0, 0,12,12,12,12,13,13,13,13,14,14, + 0, 0, 0, 0, 0, 0, 0, 0, 0,12,12,13,13,13,13,14, + 14, +}; + +static float _vq_quantthresh__44c2_s_p6_0[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__44c2_s_p6_0[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44c2_s_p6_0 = { + _vq_quantthresh__44c2_s_p6_0, + _vq_quantmap__44c2_s_p6_0, + 17, + 17 +}; + +static static_codebook _44c2_s_p6_0 = { + 2, 289, + _vq_lengthlist__44c2_s_p6_0, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__44c2_s_p6_0, + NULL, + &_vq_auxt__44c2_s_p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c2_s_p7_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44c2_s_p7_0[] = { + 1, 4, 4, 7, 6, 6, 7, 6, 6, 4, 7, 7,10, 9, 9,11, + 9, 9, 4, 7, 7,10, 9, 9,10, 9, 9, 7,10,10,11,10, + 11,11,10,11, 6, 9, 9,11,10,10,11,10,10, 6, 9, 9, + 11,10,11,11,10,10, 7,11,10,11,11,11,12,11,11, 6, + 9, 9,11,10,10,11,11,10, 6, 9, 9,11,10,10,12,10, + 11, +}; + +static float _vq_quantthresh__44c2_s_p7_0[] = { + -5.5, 5.5, +}; + +static long _vq_quantmap__44c2_s_p7_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44c2_s_p7_0 = { + _vq_quantthresh__44c2_s_p7_0, + _vq_quantmap__44c2_s_p7_0, + 3, + 3 +}; + +static static_codebook _44c2_s_p7_0 = { + 4, 81, + _vq_lengthlist__44c2_s_p7_0, + 1, -529137664, 1618345984, 2, 0, + _vq_quantlist__44c2_s_p7_0, + NULL, + &_vq_auxt__44c2_s_p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c2_s_p7_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44c2_s_p7_1[] = { + 2, 3, 4, 6, 6, 7, 7, 7, 7, 7, 7, 9, 7, 7, 6, 6, + 7, 7, 8, 8, 8, 8, 9, 6, 6, 6, 6, 7, 7, 8, 8, 8, + 8,10, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8,10,10,10, 7, + 7, 7, 7, 8, 8, 8, 8,10,10,10, 7, 7, 8, 8, 8, 8, + 8, 8,10,10,10, 7, 8, 8, 8, 8, 8, 8, 8,10,10,10, + 8, 8, 8, 8, 8, 8, 8, 8,10,10,10,10,10, 8, 8, 8, + 8, 8, 8,10,10,10,10,10, 9, 9, 8, 8, 8, 8,10,10, + 10,10,10, 8, 8, 8, 8, 8, 8, +}; + +static float _vq_quantthresh__44c2_s_p7_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__44c2_s_p7_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44c2_s_p7_1 = { + _vq_quantthresh__44c2_s_p7_1, + _vq_quantmap__44c2_s_p7_1, + 11, + 11 +}; + +static static_codebook _44c2_s_p7_1 = { + 2, 121, + _vq_lengthlist__44c2_s_p7_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__44c2_s_p7_1, + NULL, + &_vq_auxt__44c2_s_p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c2_s_p8_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c2_s_p8_0[] = { + 1, 4, 4, 6, 6, 7, 7, 7, 7, 8, 8, 9, 9, 6, 5, 5, + 7, 7, 8, 8, 8, 8, 9, 9,10,10, 7, 6, 5, 7, 7, 8, + 8, 8, 8, 9, 9,10,10, 0, 8, 8, 8, 8, 9, 9, 9, 9, + 10,10,11,11, 0, 8, 8, 8, 8, 9, 9, 9, 9,10,10,11, + 11, 0,12,12, 9, 9,10,10,10,10,11,11,11,11, 0,13, + 13, 9, 9,10,10,10,10,11,11,12,12, 0, 0, 0,10,10, + 10,10,11,11,12,12,12,13, 0, 0, 0,10,10,10,10,11, + 11,12,12,12,12, 0, 0, 0,14,14,10,11,11,11,12,12, + 13,13, 0, 0, 0,14,14,11,10,11,11,13,12,13,13, 0, + 0, 0, 0, 0,12,12,11,12,13,12,14,14, 0, 0, 0, 0, + 0,12,12,12,12,13,12,14,14, +}; + +static float _vq_quantthresh__44c2_s_p8_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__44c2_s_p8_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c2_s_p8_0 = { + _vq_quantthresh__44c2_s_p8_0, + _vq_quantmap__44c2_s_p8_0, + 13, + 13 +}; + +static static_codebook _44c2_s_p8_0 = { + 2, 169, + _vq_lengthlist__44c2_s_p8_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__44c2_s_p8_0, + NULL, + &_vq_auxt__44c2_s_p8_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c2_s_p8_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c2_s_p8_1[] = { + 2, 4, 4, 5, 4, 6, 5, 5, 5, 5, 6, 5, 5, 5, 5, 6, + 5, 5, 5, 5, 6, 6, 6, 5, 5, +}; + +static float _vq_quantthresh__44c2_s_p8_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c2_s_p8_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c2_s_p8_1 = { + _vq_quantthresh__44c2_s_p8_1, + _vq_quantmap__44c2_s_p8_1, + 5, + 5 +}; + +static static_codebook _44c2_s_p8_1 = { + 2, 25, + _vq_lengthlist__44c2_s_p8_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c2_s_p8_1, + NULL, + &_vq_auxt__44c2_s_p8_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c2_s_p9_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c2_s_p9_0[] = { + 1, 5, 4,12,12,12,12,12,12,12,12,12,12, 4, 9, 8, + 11,11,11,11,11,11,11,11,11,11, 2, 8, 7,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,10,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11, +}; + +static float _vq_quantthresh__44c2_s_p9_0[] = { + -1215.5, -994.5, -773.5, -552.5, -331.5, -110.5, 110.5, 331.5, + 552.5, 773.5, 994.5, 1215.5, +}; + +static long _vq_quantmap__44c2_s_p9_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c2_s_p9_0 = { + _vq_quantthresh__44c2_s_p9_0, + _vq_quantmap__44c2_s_p9_0, + 13, + 13 +}; + +static static_codebook _44c2_s_p9_0 = { + 2, 169, + _vq_lengthlist__44c2_s_p9_0, + 1, -514541568, 1627103232, 4, 0, + _vq_quantlist__44c2_s_p9_0, + NULL, + &_vq_auxt__44c2_s_p9_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c2_s_p9_1[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c2_s_p9_1[] = { + 1, 4, 4, 6, 6, 7, 6, 8, 8,10, 9,10,10, 6, 5, 5, + 7, 7, 8, 7,10, 9,11,11,12,13, 6, 5, 5, 7, 7, 8, + 8,10,10,11,11,13,13,18, 8, 8, 8, 8, 9, 9,10,10, + 12,12,12,13,18, 8, 8, 8, 8, 9, 9,10,10,12,12,13, + 13,18,11,11, 8, 8,10,10,11,11,12,11,13,12,18,11, + 11, 9, 7,10,10,11,11,11,12,12,13,17,17,17,10,10, + 11,11,12,12,12,10,12,12,17,17,17,11,10,11,10,13, + 12,11,12,12,12,17,17,17,15,14,11,11,12,11,13,10, + 13,12,17,17,17,14,14,12,10,11,11,13,13,13,13,17, + 17,16,17,16,13,13,12,10,13,10,14,13,17,16,17,16, + 17,13,12,12,10,13,11,14,14, +}; + +static float _vq_quantthresh__44c2_s_p9_1[] = { + -93.5, -76.5, -59.5, -42.5, -25.5, -8.5, 8.5, 25.5, + 42.5, 59.5, 76.5, 93.5, +}; + +static long _vq_quantmap__44c2_s_p9_1[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c2_s_p9_1 = { + _vq_quantthresh__44c2_s_p9_1, + _vq_quantmap__44c2_s_p9_1, + 13, + 13 +}; + +static static_codebook _44c2_s_p9_1 = { + 2, 169, + _vq_lengthlist__44c2_s_p9_1, + 1, -522616832, 1620115456, 4, 0, + _vq_quantlist__44c2_s_p9_1, + NULL, + &_vq_auxt__44c2_s_p9_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c2_s_p9_2[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44c2_s_p9_2[] = { + 2, 4, 4, 6, 6, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, + 8,10, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, + 9, 9,10, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, + 9, 9, 9,10, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, + 9, 9, 9, 9,10,10,10, 8, 7, 8, 8, 8, 8, 9, 9, 9, + 9, 9, 9, 9, 9,10,11,11, 8, 8, 8, 8, 9, 9, 9, 9, + 9, 9,10, 9, 9, 9,10,11,10, 8, 8, 8, 8, 9, 9, 9, + 9, 9, 9, 9,10,10,10,10,11,10, 8, 8, 9, 9, 9, 9, + 9, 9,10, 9, 9,10, 9,10,11,10,11,11,11, 8, 8, 9, + 9, 9, 9, 9, 9, 9, 9,10,10,11,11,11,11,11, 9, 9, + 9, 9, 9, 9,10, 9, 9, 9,10,10,11,11,11,11,11, 9, + 9, 9, 9, 9, 9, 9, 9, 9,10, 9,10,11,11,11,11,11, + 9, 9, 9, 9,10,10, 9, 9, 9,10,10,10,11,11,11,11, + 11,11,11, 9, 9, 9,10, 9, 9,10,10,10,10,11,11,10, + 11,11,11,11,10, 9,10,10, 9, 9, 9, 9,10,10,11,10, + 11,11,11,11,11, 9, 9, 9, 9,10, 9,10,10,10,10,11, + 10,11,11,11,11,11,10,10, 9, 9,10, 9,10,10,10,10, + 10,10,10,11,11,11,11,11,11, 9, 9,10, 9,10, 9,10, + 10, +}; + +static float _vq_quantthresh__44c2_s_p9_2[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__44c2_s_p9_2[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44c2_s_p9_2 = { + _vq_quantthresh__44c2_s_p9_2, + _vq_quantmap__44c2_s_p9_2, + 17, + 17 +}; + +static static_codebook _44c2_s_p9_2 = { + 2, 289, + _vq_lengthlist__44c2_s_p9_2, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__44c2_s_p9_2, + NULL, + &_vq_auxt__44c2_s_p9_2, + NULL, + 0 +}; + +static long _huff_lengthlist__44c2_s_short[] = { + 11, 9,13,12,12,11,12,12,13,15, 8, 2,11, 4, 8, 5, + 7,10,12,15,13, 7,10, 9, 8, 8,10,13,17,17,11, 4, + 12, 5, 9, 5, 8,11,14,16,12, 6, 8, 7, 6, 6, 8,11, + 13,16,11, 4, 9, 5, 6, 4, 6,10,13,16,11, 6,11, 7, + 7, 6, 7,10,13,15,13, 9,12, 9, 8, 6, 8,10,12,14, + 14,10,10, 8, 6, 5, 6, 9,11,13,15,11,11, 9, 6, 5, + 6, 8, 9,12, +}; + +static static_codebook _huff_book__44c2_s_short = { + 2, 100, + _huff_lengthlist__44c2_s_short, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__44c3_s_long[] = { + 5, 6,11,11,11,11,10,10,12,11, 5, 2,11, 5, 6, 6, + 7, 9,11,13,13,10, 7,11, 6, 7, 8, 9,10,12,11, 5, + 11, 6, 8, 7, 9,11,14,15,11, 6, 6, 8, 4, 5, 7, 8, + 10,13,10, 5, 7, 7, 5, 5, 6, 8,10,11,10, 7, 7, 8, + 6, 5, 5, 7, 9, 9,11, 8, 8,11, 8, 7, 6, 6, 7, 9, + 12,11,10,13, 9, 9, 7, 7, 7, 9,11,13,12,15,12,11, + 9, 8, 8, 8, +}; + +static static_codebook _huff_book__44c3_s_long = { + 2, 100, + _huff_lengthlist__44c3_s_long, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__44c3_s_p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44c3_s_p1_0[] = { + 2, 4, 4, 0, 0, 0, 0, 0, 0, 5, 6, 6, 0, 0, 0, 0, + 0, 0, 5, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, 0, + 0, 0, 0, 6, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 6, 8, 7, 0, 0, + 0, 0, 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 0, + 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, 0, + 0, 0, 0, 8, 8, 9, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 8, 8, 0, 0, + 0, 0, 0, 0, 7, 9, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, + 0, 0, 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 6, 8, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, + 0, 0, 0, 0, 0, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6, 8, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9, + 0, 0, 0, 0, 0, 0, 8, 9, 8, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c3_s_p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44c3_s_p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44c3_s_p1_0 = { + _vq_quantthresh__44c3_s_p1_0, + _vq_quantmap__44c3_s_p1_0, + 3, + 3 +}; + +static static_codebook _44c3_s_p1_0 = { + 8, 6561, + _vq_lengthlist__44c3_s_p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44c3_s_p1_0, + NULL, + &_vq_auxt__44c3_s_p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c3_s_p2_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c3_s_p2_0[] = { + 2, 5, 5, 0, 0, 0, 5, 5, 0, 0, 0, 5, 5, 0, 0, 0, + 7, 8, 0, 0, 0, 0, 0, 0, 0, 5, 6, 6, 0, 0, 0, 7, + 7, 0, 0, 0, 7, 7, 0, 0, 0,10,10, 0, 0, 0, 0, 0, + 0, 0, 5, 6, 6, 0, 0, 0, 7, 7, 0, 0, 0, 7, 7, 0, + 0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 7, 7, 0, 0, + 0, 7, 7, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 5, + 7, 7, 0, 0, 0, 7, 7, 0, 0, 0, 7, 7, 0, 0, 0, 9, + 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 5, 7, 7, 0, 0, 0, 7, 7, 0, 0, 0, 7, 7, + 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, + 0, 0, 7, 7, 0, 0, 0, 7, 7, 0, 0, 0, 9, 9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 8,10,10, 0, 0, 0, 9, 9, 0, 0, 0, 9, 9, 0, 0, 0, + 10,10, 0, 0, 0, 0, 0, 0, 0, 8,10,10, 0, 0, 0, 9, + 9, 0, 0, 0, 9, 9, 0, 0, 0,10,10, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c3_s_p2_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c3_s_p2_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c3_s_p2_0 = { + _vq_quantthresh__44c3_s_p2_0, + _vq_quantmap__44c3_s_p2_0, + 5, + 5 +}; + +static static_codebook _44c3_s_p2_0 = { + 4, 625, + _vq_lengthlist__44c3_s_p2_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c3_s_p2_0, + NULL, + &_vq_auxt__44c3_s_p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c3_s_p3_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c3_s_p3_0[] = { + 2, 4, 3, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 6, 6, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 4, 4, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6, 6, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c3_s_p3_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c3_s_p3_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c3_s_p3_0 = { + _vq_quantthresh__44c3_s_p3_0, + _vq_quantmap__44c3_s_p3_0, + 5, + 5 +}; + +static static_codebook _44c3_s_p3_0 = { + 4, 625, + _vq_lengthlist__44c3_s_p3_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c3_s_p3_0, + NULL, + &_vq_auxt__44c3_s_p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c3_s_p4_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44c3_s_p4_0[] = { + 2, 3, 3, 6, 6, 0, 0, 0, 0, 0, 4, 4, 6, 6, 0, 0, + 0, 0, 0, 4, 4, 6, 6, 0, 0, 0, 0, 0, 5, 5, 6, 6, + 0, 0, 0, 0, 0, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, + 7, 8, 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, + 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c3_s_p4_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44c3_s_p4_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44c3_s_p4_0 = { + _vq_quantthresh__44c3_s_p4_0, + _vq_quantmap__44c3_s_p4_0, + 9, + 9 +}; + +static static_codebook _44c3_s_p4_0 = { + 2, 81, + _vq_lengthlist__44c3_s_p4_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44c3_s_p4_0, + NULL, + &_vq_auxt__44c3_s_p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c3_s_p5_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44c3_s_p5_0[] = { + 1, 3, 4, 6, 6, 7, 7, 9, 9, 0, 5, 5, 7, 7, 7, 8, + 9, 9, 0, 5, 5, 7, 7, 8, 8, 9, 9, 0, 7, 7, 8, 8, + 8, 8,10,10, 0, 0, 0, 8, 8, 8, 8,10,10, 0, 0, 0, + 9, 9, 9, 9,10,10, 0, 0, 0, 9, 9, 9, 9,10,10, 0, + 0, 0,10,10,10,10,11,11, 0, 0, 0, 0, 0,10,10,11, + 11, +}; + +static float _vq_quantthresh__44c3_s_p5_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44c3_s_p5_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44c3_s_p5_0 = { + _vq_quantthresh__44c3_s_p5_0, + _vq_quantmap__44c3_s_p5_0, + 9, + 9 +}; + +static static_codebook _44c3_s_p5_0 = { + 2, 81, + _vq_lengthlist__44c3_s_p5_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44c3_s_p5_0, + NULL, + &_vq_auxt__44c3_s_p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c3_s_p6_0[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44c3_s_p6_0[] = { + 2, 3, 3, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,10,10,11, + 10, 0, 5, 5, 7, 7, 8, 8, 9, 9, 9, 9,10,10,10,10, + 11,11, 0, 5, 5, 7, 7, 8, 8, 9, 9, 9, 9,10,10,10, + 10,11,11, 0, 6, 6, 7, 7, 8, 8, 9, 9, 9, 9,10,10, + 11,11,11,11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10, + 10,11,11,11,12, 0, 0, 0, 8, 8, 8, 8, 9, 9, 9, 9, + 10,10,11,11,12,12, 0, 0, 0, 8, 8, 8, 8, 9, 9, 9, + 9,10,10,11,11,12,12, 0, 0, 0, 9, 9, 9, 9,10,10, + 10,10,11,10,11,11,12,12, 0, 0, 0, 0, 0, 9, 9,10, + 10,10,10,11,11,11,11,12,12, 0, 0, 0, 0, 0, 9, 8, + 9, 9,10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0, 8, + 8, 9, 9,10,10,11,11,12,11,12,12, 0, 0, 0, 0, 0, + 9,10,10,10,11,11,11,11,12,12,13,13, 0, 0, 0, 0, + 0, 0, 0,10,10,10,10,11,11,12,12,13,13, 0, 0, 0, + 0, 0, 0, 0,11,11,11,11,12,12,12,12,13,13, 0, 0, + 0, 0, 0, 0, 0,11,11,11,11,12,12,12,12,13,13, 0, + 0, 0, 0, 0, 0, 0,11,11,12,12,12,12,13,13,13,13, + 0, 0, 0, 0, 0, 0, 0, 0, 0,12,12,12,12,13,13,13, + 13, +}; + +static float _vq_quantthresh__44c3_s_p6_0[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__44c3_s_p6_0[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44c3_s_p6_0 = { + _vq_quantthresh__44c3_s_p6_0, + _vq_quantmap__44c3_s_p6_0, + 17, + 17 +}; + +static static_codebook _44c3_s_p6_0 = { + 2, 289, + _vq_lengthlist__44c3_s_p6_0, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__44c3_s_p6_0, + NULL, + &_vq_auxt__44c3_s_p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c3_s_p7_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44c3_s_p7_0[] = { + 1, 4, 4, 7, 6, 6, 7, 6, 6, 4, 7, 7,10, 9, 9,11, + 9, 9, 4, 7, 7,10, 9, 9,11, 9, 9, 7,10,10,11,11, + 10,12,11,11, 6, 9, 9,11,10,10,11,10,10, 6, 9, 9, + 11,10,10,11,10,10, 7,11,11,11,11,11,12,11,11, 6, + 9, 9,11,10,10,11,10,10, 6, 9, 9,11,10,10,11,10, + 10, +}; + +static float _vq_quantthresh__44c3_s_p7_0[] = { + -5.5, 5.5, +}; + +static long _vq_quantmap__44c3_s_p7_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44c3_s_p7_0 = { + _vq_quantthresh__44c3_s_p7_0, + _vq_quantmap__44c3_s_p7_0, + 3, + 3 +}; + +static static_codebook _44c3_s_p7_0 = { + 4, 81, + _vq_lengthlist__44c3_s_p7_0, + 1, -529137664, 1618345984, 2, 0, + _vq_quantlist__44c3_s_p7_0, + NULL, + &_vq_auxt__44c3_s_p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c3_s_p7_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44c3_s_p7_1[] = { + 2, 4, 4, 6, 6, 7, 7, 7, 7, 8, 8,10, 5, 5, 6, 6, + 7, 7, 8, 8, 8, 8,10, 5, 5, 6, 6, 7, 7, 8, 8, 8, + 8,10, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8,10,10,10, 7, + 7, 8, 7, 8, 8, 8, 8,10,10,10, 8, 8, 8, 8, 8, 8, + 8, 8,10,10,10, 7, 8, 8, 8, 8, 8, 8, 8,10,10,10, + 8, 8, 8, 8, 8, 8, 8, 8,10,10,10,10,10, 8, 8, 8, + 8, 8, 8,10,10,10,10,10, 9, 9, 8, 8, 9, 8,10,10, + 10,10,10, 8, 8, 8, 8, 8, 8, +}; + +static float _vq_quantthresh__44c3_s_p7_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__44c3_s_p7_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44c3_s_p7_1 = { + _vq_quantthresh__44c3_s_p7_1, + _vq_quantmap__44c3_s_p7_1, + 11, + 11 +}; + +static static_codebook _44c3_s_p7_1 = { + 2, 121, + _vq_lengthlist__44c3_s_p7_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__44c3_s_p7_1, + NULL, + &_vq_auxt__44c3_s_p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c3_s_p8_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c3_s_p8_0[] = { + 1, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9,10,10, 6, 5, 5, + 7, 7, 8, 8, 8, 8, 9, 9,10,10, 7, 5, 5, 7, 7, 8, + 8, 8, 8, 9, 9,11,10, 0, 8, 8, 8, 8, 9, 9, 9, 9, + 10,10,11,11, 0, 8, 8, 8, 8, 9, 9, 9, 9,10,10,11, + 11, 0,12,12, 9, 9,10,10,10,10,11,11,11,12, 0,13, + 13, 9, 9,10,10,10,10,11,11,12,12, 0, 0, 0,10,10, + 10,10,11,11,12,12,12,12, 0, 0, 0,10,10,10,10,11, + 11,12,12,12,12, 0, 0, 0,14,14,11,11,11,11,12,12, + 13,13, 0, 0, 0,14,14,11,11,11,11,12,12,13,13, 0, + 0, 0, 0, 0,12,12,12,12,13,13,14,13, 0, 0, 0, 0, + 0,13,13,12,12,13,12,14,13, +}; + +static float _vq_quantthresh__44c3_s_p8_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__44c3_s_p8_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c3_s_p8_0 = { + _vq_quantthresh__44c3_s_p8_0, + _vq_quantmap__44c3_s_p8_0, + 13, + 13 +}; + +static static_codebook _44c3_s_p8_0 = { + 2, 169, + _vq_lengthlist__44c3_s_p8_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__44c3_s_p8_0, + NULL, + &_vq_auxt__44c3_s_p8_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c3_s_p8_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c3_s_p8_1[] = { + 2, 4, 4, 5, 5, 6, 5, 5, 5, 5, 6, 4, 5, 5, 5, 6, + 5, 5, 5, 5, 6, 6, 6, 5, 5, +}; + +static float _vq_quantthresh__44c3_s_p8_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c3_s_p8_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c3_s_p8_1 = { + _vq_quantthresh__44c3_s_p8_1, + _vq_quantmap__44c3_s_p8_1, + 5, + 5 +}; + +static static_codebook _44c3_s_p8_1 = { + 2, 25, + _vq_lengthlist__44c3_s_p8_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c3_s_p8_1, + NULL, + &_vq_auxt__44c3_s_p8_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c3_s_p9_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c3_s_p9_0[] = { + 1, 4, 4,12,12,12,12,12,12,12,12,12,12, 4, 9, 8, + 12,12,12,12,12,12,12,12,12,12, 2, 9, 7,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,11,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11, +}; + +static float _vq_quantthresh__44c3_s_p9_0[] = { + -1402.5, -1147.5, -892.5, -637.5, -382.5, -127.5, 127.5, 382.5, + 637.5, 892.5, 1147.5, 1402.5, +}; + +static long _vq_quantmap__44c3_s_p9_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c3_s_p9_0 = { + _vq_quantthresh__44c3_s_p9_0, + _vq_quantmap__44c3_s_p9_0, + 13, + 13 +}; + +static static_codebook _44c3_s_p9_0 = { + 2, 169, + _vq_lengthlist__44c3_s_p9_0, + 1, -514332672, 1627381760, 4, 0, + _vq_quantlist__44c3_s_p9_0, + NULL, + &_vq_auxt__44c3_s_p9_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c3_s_p9_1[] = { + 7, + 6, + 8, + 5, + 9, + 4, + 10, + 3, + 11, + 2, + 12, + 1, + 13, + 0, + 14, +}; + +static long _vq_lengthlist__44c3_s_p9_1[] = { + 1, 4, 4, 6, 6, 7, 7, 8, 7, 9, 9,10,10,10,10, 6, + 5, 5, 7, 7, 8, 8,10, 8,11,10,12,12,13,13, 6, 5, + 5, 7, 7, 8, 8,10, 9,11,11,12,12,13,12,18, 8, 8, + 8, 8, 9, 9,10, 9,11,10,12,12,13,13,18, 8, 8, 8, + 8, 9, 9,10,10,11,11,13,12,14,13,18,11,11, 9, 9, + 10,10,11,11,11,12,13,12,13,14,18,11,11, 9, 8,11, + 10,11,11,11,11,12,12,14,13,18,18,18,10,11,10,11, + 12,12,12,12,13,12,14,13,18,18,18,10,11,11, 9,12, + 11,12,12,12,13,13,13,18,18,17,14,14,11,11,12,12, + 13,12,14,12,14,13,18,18,18,14,14,11,10,12, 9,12, + 13,13,13,13,13,18,18,17,16,18,13,13,12,12,13,11, + 14,12,14,14,17,18,18,17,18,13,12,13,10,12,11,14, + 14,14,14,17,18,18,18,18,15,16,12,12,13,10,14,12, + 14,15,18,18,18,16,17,16,14,12,11,13,10,13,13,14, + 15, +}; + +static float _vq_quantthresh__44c3_s_p9_1[] = { + -110.5, -93.5, -76.5, -59.5, -42.5, -25.5, -8.5, 8.5, + 25.5, 42.5, 59.5, 76.5, 93.5, 110.5, +}; + +static long _vq_quantmap__44c3_s_p9_1[] = { + 13, 11, 9, 7, 5, 3, 1, 0, + 2, 4, 6, 8, 10, 12, 14, +}; + +static encode_aux_threshmatch _vq_auxt__44c3_s_p9_1 = { + _vq_quantthresh__44c3_s_p9_1, + _vq_quantmap__44c3_s_p9_1, + 15, + 15 +}; + +static static_codebook _44c3_s_p9_1 = { + 2, 225, + _vq_lengthlist__44c3_s_p9_1, + 1, -522338304, 1620115456, 4, 0, + _vq_quantlist__44c3_s_p9_1, + NULL, + &_vq_auxt__44c3_s_p9_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c3_s_p9_2[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44c3_s_p9_2[] = { + 2, 5, 5, 6, 6, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, + 8,10, 6, 6, 7, 7, 8, 7, 8, 8, 8, 8, 8, 9, 9, 9, + 9, 9,10, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, + 9, 9, 9,10, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, + 9, 9, 9, 9,10,10,10, 7, 7, 8, 8, 8, 9, 9, 9, 9, + 9, 9, 9, 9, 9,11,11,11, 8, 8, 8, 8, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9,10,10,10, 8, 8, 8, 8, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9,10,10,10, 8, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9,10, 9,10,10,10,11,11, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9,11,10,11,11,11, 9, 9, + 9, 9, 9, 9,10,10, 9, 9,10, 9,11,10,11,11,11, 9, + 9, 9, 9, 9, 9, 9, 9,10,10,10, 9,11,11,11,11,11, + 9, 9, 9, 9,10,10, 9, 9, 9, 9,10, 9,11,11,11,11, + 11,11,11, 9, 9, 9, 9, 9, 9,10,10,10,10,11,11,11, + 11,11,11,11,10, 9,10,10, 9,10, 9, 9,10, 9,11,10, + 10,11,11,11,11, 9,10, 9, 9, 9, 9,10,10,10,10,11, + 11,11,11,11,11,10,10,10, 9, 9,10, 9,10, 9,10,10, + 10,10,11,11,11,11,11,11,11, 9, 9, 9, 9, 9,10,10, + 10, +}; + +static float _vq_quantthresh__44c3_s_p9_2[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__44c3_s_p9_2[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44c3_s_p9_2 = { + _vq_quantthresh__44c3_s_p9_2, + _vq_quantmap__44c3_s_p9_2, + 17, + 17 +}; + +static static_codebook _44c3_s_p9_2 = { + 2, 289, + _vq_lengthlist__44c3_s_p9_2, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__44c3_s_p9_2, + NULL, + &_vq_auxt__44c3_s_p9_2, + NULL, + 0 +}; + +static long _huff_lengthlist__44c3_s_short[] = { + 10, 9,13,11,14,10,12,13,13,14, 7, 2,12, 5,10, 5, + 7,10,12,14,12, 6, 9, 8, 7, 7, 9,11,13,16,10, 4, + 12, 5,10, 6, 8,12,14,16,12, 6, 8, 7, 6, 5, 7,11, + 12,16,10, 4, 8, 5, 6, 4, 6, 9,13,16,10, 6,10, 7, + 7, 6, 7, 9,13,15,12, 9,11, 9, 8, 6, 7,10,12,14, + 14,11,10, 9, 6, 5, 6, 9,11,13,15,13,11,10, 6, 5, + 6, 8, 9,11, +}; + +static static_codebook _huff_book__44c3_s_short = { + 2, 100, + _huff_lengthlist__44c3_s_short, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__44c4_s_long[] = { + 4, 7,11,11,11,11,10,11,12,11, 5, 2,11, 5, 6, 6, + 7, 9,11,12,11, 9, 6,10, 6, 7, 8, 9,10,11,11, 5, + 11, 7, 8, 8, 9,11,13,14,11, 6, 5, 8, 4, 5, 7, 8, + 10,11,10, 6, 7, 7, 5, 5, 6, 8, 9,11,10, 7, 8, 9, + 6, 6, 6, 7, 8, 9,11, 9, 9,11, 7, 7, 6, 6, 7, 9, + 12,12,10,13, 9, 8, 7, 7, 7, 8,11,13,11,14,11,10, + 9, 8, 7, 7, +}; + +static static_codebook _huff_book__44c4_s_long = { + 2, 100, + _huff_lengthlist__44c4_s_long, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__44c4_s_p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44c4_s_p1_0[] = { + 2, 4, 4, 0, 0, 0, 0, 0, 0, 5, 6, 6, 0, 0, 0, 0, + 0, 0, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, 0, + 0, 0, 0, 6, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 6, 8, 7, 0, 0, + 0, 0, 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 0, + 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, 0, + 0, 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 8, 8, 0, 0, + 0, 0, 0, 0, 8, 9, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 7, 7, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, + 0, 0, 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 6, 8, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, + 0, 0, 0, 0, 0, 8, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9, + 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c4_s_p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44c4_s_p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44c4_s_p1_0 = { + _vq_quantthresh__44c4_s_p1_0, + _vq_quantmap__44c4_s_p1_0, + 3, + 3 +}; + +static static_codebook _44c4_s_p1_0 = { + 8, 6561, + _vq_lengthlist__44c4_s_p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44c4_s_p1_0, + NULL, + &_vq_auxt__44c4_s_p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c4_s_p2_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c4_s_p2_0[] = { + 2, 5, 5, 0, 0, 0, 5, 5, 0, 0, 0, 5, 5, 0, 0, 0, + 7, 7, 0, 0, 0, 0, 0, 0, 0, 5, 6, 6, 0, 0, 0, 7, + 7, 0, 0, 0, 7, 7, 0, 0, 0,10,10, 0, 0, 0, 0, 0, + 0, 0, 5, 6, 6, 0, 0, 0, 7, 7, 0, 0, 0, 7, 7, 0, + 0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 5, 8, 7, 0, 0, 0, 7, 7, 0, 0, + 0, 7, 7, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 5, + 7, 8, 0, 0, 0, 7, 7, 0, 0, 0, 7, 7, 0, 0, 0, 9, + 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 5, 7, 7, 0, 0, 0, 7, 7, 0, 0, 0, 7, 7, + 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, + 0, 0, 7, 7, 0, 0, 0, 7, 7, 0, 0, 0, 9, 9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 7,10,10, 0, 0, 0, 9, 9, 0, 0, 0, 9, 9, 0, 0, 0, + 10,10, 0, 0, 0, 0, 0, 0, 0, 8,10,10, 0, 0, 0, 9, + 9, 0, 0, 0, 9, 9, 0, 0, 0,10,10, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c4_s_p2_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c4_s_p2_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c4_s_p2_0 = { + _vq_quantthresh__44c4_s_p2_0, + _vq_quantmap__44c4_s_p2_0, + 5, + 5 +}; + +static static_codebook _44c4_s_p2_0 = { + 4, 625, + _vq_lengthlist__44c4_s_p2_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c4_s_p2_0, + NULL, + &_vq_auxt__44c4_s_p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c4_s_p3_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c4_s_p3_0[] = { + 2, 3, 3, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 4, 6, 6, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 4, 5, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6, 6, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c4_s_p3_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c4_s_p3_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c4_s_p3_0 = { + _vq_quantthresh__44c4_s_p3_0, + _vq_quantmap__44c4_s_p3_0, + 5, + 5 +}; + +static static_codebook _44c4_s_p3_0 = { + 4, 625, + _vq_lengthlist__44c4_s_p3_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c4_s_p3_0, + NULL, + &_vq_auxt__44c4_s_p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c4_s_p4_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44c4_s_p4_0[] = { + 2, 3, 3, 6, 6, 0, 0, 0, 0, 0, 4, 4, 6, 6, 0, 0, + 0, 0, 0, 4, 4, 6, 6, 0, 0, 0, 0, 0, 5, 5, 6, 6, + 0, 0, 0, 0, 0, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, + 7, 8, 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, + 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c4_s_p4_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44c4_s_p4_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44c4_s_p4_0 = { + _vq_quantthresh__44c4_s_p4_0, + _vq_quantmap__44c4_s_p4_0, + 9, + 9 +}; + +static static_codebook _44c4_s_p4_0 = { + 2, 81, + _vq_lengthlist__44c4_s_p4_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44c4_s_p4_0, + NULL, + &_vq_auxt__44c4_s_p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c4_s_p5_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44c4_s_p5_0[] = { + 2, 3, 3, 6, 6, 7, 7, 9, 9, 0, 4, 4, 6, 6, 7, 7, + 9, 9, 0, 4, 5, 6, 6, 7, 7, 9, 9, 0, 6, 6, 7, 7, + 8, 8,10,10, 0, 0, 0, 7, 7, 8, 8,10, 9, 0, 0, 0, + 9, 8, 8, 8,10,10, 0, 0, 0, 8, 8, 8, 8,10,10, 0, + 0, 0,10,10, 9, 9,11,11, 0, 0, 0, 0, 0, 9, 9,10, + 10, +}; + +static float _vq_quantthresh__44c4_s_p5_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44c4_s_p5_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44c4_s_p5_0 = { + _vq_quantthresh__44c4_s_p5_0, + _vq_quantmap__44c4_s_p5_0, + 9, + 9 +}; + +static static_codebook _44c4_s_p5_0 = { + 2, 81, + _vq_lengthlist__44c4_s_p5_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44c4_s_p5_0, + NULL, + &_vq_auxt__44c4_s_p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c4_s_p6_0[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44c4_s_p6_0[] = { + 2, 4, 4, 6, 6, 8, 8, 9, 9, 8, 8, 9, 9,10,10,11, + 11, 0, 4, 4, 6, 6, 8, 8, 9, 9, 9, 9,10,10,11,11, + 11,11, 0, 4, 4, 7, 6, 8, 8, 9, 9, 9, 9,10,10,11, + 11,11,11, 0, 6, 6, 7, 7, 8, 8, 9, 9, 9, 9,10,10, + 11,11,11,12, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10, + 10,11,11,12,12, 0, 0, 0, 8, 8, 8, 8, 9, 9, 9, 9, + 10,10,11,11,12,12, 0, 0, 0, 8, 8, 8, 8, 9, 9, 9, + 9,10,10,11,11,12,12, 0, 0, 0, 9, 9, 9, 9,10,10, + 10,10,11,11,11,11,12,12, 0, 0, 0, 0, 0, 9, 9,10, + 10,10,10,11,11,11,11,12,12, 0, 0, 0, 0, 0, 9, 9, + 9,10,10,10,11,11,11,11,12,12, 0, 0, 0, 0, 0, 9, + 9, 9, 9,10,10,11,11,11,12,12,12, 0, 0, 0, 0, 0, + 10,10,10,10,11,11,11,11,12,12,13,12, 0, 0, 0, 0, + 0, 0, 0,10,10,11,11,11,11,12,12,12,12, 0, 0, 0, + 0, 0, 0, 0,11,11,11,11,12,12,12,12,13,13, 0, 0, + 0, 0, 0, 0, 0,11,11,11,11,12,12,12,12,13,13, 0, + 0, 0, 0, 0, 0, 0,12,12,12,12,12,12,13,13,13,13, + 0, 0, 0, 0, 0, 0, 0, 0, 0,12,12,12,12,12,13,13, + 13, +}; + +static float _vq_quantthresh__44c4_s_p6_0[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__44c4_s_p6_0[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44c4_s_p6_0 = { + _vq_quantthresh__44c4_s_p6_0, + _vq_quantmap__44c4_s_p6_0, + 17, + 17 +}; + +static static_codebook _44c4_s_p6_0 = { + 2, 289, + _vq_lengthlist__44c4_s_p6_0, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__44c4_s_p6_0, + NULL, + &_vq_auxt__44c4_s_p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c4_s_p7_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44c4_s_p7_0[] = { + 1, 4, 4, 7, 6, 6, 7, 6, 6, 4, 7, 7,10, 9, 9,11, + 9, 9, 4, 7, 7,10, 9, 9,11, 9, 9, 7,10,10,11,11, + 10,11,11,11, 6, 9, 9,11,10,10,11,10,10, 6, 9, 9, + 11,10,10,11,10,10, 7,11,11,12,11,11,12,11,11, 6, + 9, 9,11,10,10,11,10,10, 6, 9, 9,11,10,10,11,10, + 10, +}; + +static float _vq_quantthresh__44c4_s_p7_0[] = { + -5.5, 5.5, +}; + +static long _vq_quantmap__44c4_s_p7_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44c4_s_p7_0 = { + _vq_quantthresh__44c4_s_p7_0, + _vq_quantmap__44c4_s_p7_0, + 3, + 3 +}; + +static static_codebook _44c4_s_p7_0 = { + 4, 81, + _vq_lengthlist__44c4_s_p7_0, + 1, -529137664, 1618345984, 2, 0, + _vq_quantlist__44c4_s_p7_0, + NULL, + &_vq_auxt__44c4_s_p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c4_s_p7_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44c4_s_p7_1[] = { + 2, 4, 4, 6, 6, 7, 7, 7, 7, 8, 8,10, 5, 5, 6, 6, + 7, 7, 8, 8, 8, 8,10, 5, 5, 6, 6, 7, 7, 8, 8, 8, + 8,10, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8,10,10,10, 7, + 7, 8, 8, 8, 8, 8, 8,10,10,10, 8, 7, 8, 8, 8, 8, + 8, 8,10,10,10, 7, 7, 8, 8, 8, 8, 8, 8,10,10,10, + 8, 8, 8, 8, 8, 8, 8, 8,10,10,10,10,10, 8, 8, 8, + 8, 8, 8,10,10,10,10,10, 9, 9, 8, 8, 9, 8,10,10, + 10,10,10, 8, 8, 8, 8, 9, 9, +}; + +static float _vq_quantthresh__44c4_s_p7_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__44c4_s_p7_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44c4_s_p7_1 = { + _vq_quantthresh__44c4_s_p7_1, + _vq_quantmap__44c4_s_p7_1, + 11, + 11 +}; + +static static_codebook _44c4_s_p7_1 = { + 2, 121, + _vq_lengthlist__44c4_s_p7_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__44c4_s_p7_1, + NULL, + &_vq_auxt__44c4_s_p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c4_s_p8_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c4_s_p8_0[] = { + 1, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9,10,10, 6, 5, 5, + 7, 7, 8, 8, 8, 8, 9,10,11,11, 7, 5, 5, 7, 7, 8, + 8, 9, 9,10,10,11,11, 0, 8, 8, 8, 8, 9, 9, 9, 9, + 10,10,11,11, 0, 8, 8, 8, 8, 9, 9, 9, 9,10,10,11, + 11, 0,12,12, 9, 9, 9, 9,10,10,10,10,11,11, 0,13, + 13, 9, 9,10, 9,10,10,11,11,11,12, 0, 0, 0,10,10, + 10,10,10,10,11,11,12,12, 0, 0, 0,10,10,10,10,10, + 10,11,11,12,12, 0, 0, 0,14,14,11,11,11,11,12,12, + 12,12, 0, 0, 0,14,14,11,11,11,11,12,12,12,13, 0, + 0, 0, 0, 0,12,12,12,12,12,12,13,13, 0, 0, 0, 0, + 0,13,12,12,12,12,12,13,13, +}; + +static float _vq_quantthresh__44c4_s_p8_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__44c4_s_p8_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c4_s_p8_0 = { + _vq_quantthresh__44c4_s_p8_0, + _vq_quantmap__44c4_s_p8_0, + 13, + 13 +}; + +static static_codebook _44c4_s_p8_0 = { + 2, 169, + _vq_lengthlist__44c4_s_p8_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__44c4_s_p8_0, + NULL, + &_vq_auxt__44c4_s_p8_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c4_s_p8_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c4_s_p8_1[] = { + 2, 4, 4, 5, 5, 6, 5, 5, 5, 5, 6, 5, 4, 5, 5, 6, + 5, 5, 5, 5, 6, 6, 6, 5, 5, +}; + +static float _vq_quantthresh__44c4_s_p8_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c4_s_p8_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c4_s_p8_1 = { + _vq_quantthresh__44c4_s_p8_1, + _vq_quantmap__44c4_s_p8_1, + 5, + 5 +}; + +static static_codebook _44c4_s_p8_1 = { + 2, 25, + _vq_lengthlist__44c4_s_p8_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c4_s_p8_1, + NULL, + &_vq_auxt__44c4_s_p8_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c4_s_p9_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c4_s_p9_0[] = { + 1, 3, 3,12,12,12,12,12,12,12,12,12,12, 4, 7, 7, + 12,12,12,12,12,12,12,12,12,12, 3, 8, 8,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12, +}; + +static float _vq_quantthresh__44c4_s_p9_0[] = { + -1732.5, -1417.5, -1102.5, -787.5, -472.5, -157.5, 157.5, 472.5, + 787.5, 1102.5, 1417.5, 1732.5, +}; + +static long _vq_quantmap__44c4_s_p9_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c4_s_p9_0 = { + _vq_quantthresh__44c4_s_p9_0, + _vq_quantmap__44c4_s_p9_0, + 13, + 13 +}; + +static static_codebook _44c4_s_p9_0 = { + 2, 169, + _vq_lengthlist__44c4_s_p9_0, + 1, -513964032, 1628680192, 4, 0, + _vq_quantlist__44c4_s_p9_0, + NULL, + &_vq_auxt__44c4_s_p9_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c4_s_p9_1[] = { + 7, + 6, + 8, + 5, + 9, + 4, + 10, + 3, + 11, + 2, + 12, + 1, + 13, + 0, + 14, +}; + +static long _vq_lengthlist__44c4_s_p9_1[] = { + 1, 4, 4, 5, 5, 7, 7, 9, 8,10, 9,10,10,10,10, 6, + 5, 5, 7, 7, 9, 8,10, 9,11,10,12,12,13,13, 6, 5, + 5, 7, 7, 9, 9,10,10,11,11,12,12,12,13,19, 8, 8, + 8, 8, 9, 9,10,10,12,11,12,12,13,13,19, 8, 8, 8, + 8, 9, 9,11,11,12,12,13,13,13,13,19,12,12, 9, 9, + 11,11,11,11,12,11,13,12,13,13,18,12,12, 9, 9,11, + 10,11,11,12,12,12,13,13,14,19,18,18,11,11,11,11, + 12,12,13,12,13,13,14,14,16,18,18,11,11,11,10,12, + 11,13,13,13,13,13,14,17,18,18,14,15,11,12,12,13, + 13,13,13,14,14,14,18,18,18,15,15,12,10,13,10,13, + 13,13,13,13,14,18,17,18,17,18,12,13,12,13,13,13, + 14,14,16,14,18,17,18,18,17,13,12,13,10,12,12,14, + 14,14,14,17,18,18,18,18,14,15,12,12,13,12,14,14, + 15,15,18,18,18,17,18,15,14,12,11,12,12,14,14,14, + 15, +}; + +static float _vq_quantthresh__44c4_s_p9_1[] = { + -136.5, -115.5, -94.5, -73.5, -52.5, -31.5, -10.5, 10.5, + 31.5, 52.5, 73.5, 94.5, 115.5, 136.5, +}; + +static long _vq_quantmap__44c4_s_p9_1[] = { + 13, 11, 9, 7, 5, 3, 1, 0, + 2, 4, 6, 8, 10, 12, 14, +}; + +static encode_aux_threshmatch _vq_auxt__44c4_s_p9_1 = { + _vq_quantthresh__44c4_s_p9_1, + _vq_quantmap__44c4_s_p9_1, + 15, + 15 +}; + +static static_codebook _44c4_s_p9_1 = { + 2, 225, + _vq_lengthlist__44c4_s_p9_1, + 1, -520986624, 1620377600, 4, 0, + _vq_quantlist__44c4_s_p9_1, + NULL, + &_vq_auxt__44c4_s_p9_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c4_s_p9_2[] = { + 10, + 9, + 11, + 8, + 12, + 7, + 13, + 6, + 14, + 5, + 15, + 4, + 16, + 3, + 17, + 2, + 18, + 1, + 19, + 0, + 20, +}; + +static long _vq_lengthlist__44c4_s_p9_2[] = { + 2, 5, 5, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, + 8, 9, 9, 9, 9,11, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, + 9, 9, 9, 9, 9, 9,10,10,10,10,11, 6, 6, 7, 7, 8, + 8, 8, 8, 9, 9, 9, 9, 9, 9,10, 9,10,10,10,10,11, + 7, 7, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9, 9,10,10,10, + 10,10,10,10,12,11,11, 7, 7, 8, 8, 9, 9, 9, 9, 9, + 9,10,10,10,10,10,10,10,10,12,11,12, 8, 8, 8, 8, + 9, 9, 9, 9, 9,10,10,10,10,10,10,10,10,10,11,11, + 11, 8, 8, 8, 8, 9, 9, 9, 9,10,10,10,10,10,10,10, + 10,10,10,11,11,12, 9, 9, 9, 9, 9, 9,10, 9,10,10, + 10,10,10,10,10,10,10,10,11,11,11,11,11, 9, 9, 9, + 9,10,10,10,10,10,10,10,10,10,10,10,10,11,12,11, + 11,11, 9, 9, 9,10,10,10,10,10,10,10,10,10,10,10, + 10,10,11,11,11,11,11, 9, 9, 9, 9,10,10,10,10,10, + 10,10,10,10,10,10,10,11,11,11,12,12,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,11,12,11,12, + 11,11,11, 9,10,10,10,10,10,10,10,10,10,10,10,10, + 10,11,12,11,11,11,11,11,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,11,11,11,12,11,11,11,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,12,11,11,12,11, + 11,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 11,11,11,11,11,11,11,11,11,10,10,10,10,10,10,10, + 10,10,10,10,10,11,11,11,11,12,12,11,11,11,11,11, + 11,11,10,10,10,10,10,10,10,10,12,12,12,11,11,11, + 12,11,11,11,10,10,10,10,10,10,10,10,10,10,10,12, + 11,12,12,12,12,12,11,12,11,11,10,10,10,10,10,10, + 10,10,10,10,12,12,12,12,11,11,11,11,11,11,11,10, + 10,10,10,10,10,10,10,10,10, +}; + +static float _vq_quantthresh__44c4_s_p9_2[] = { + -9.5, -8.5, -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, + -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, + 6.5, 7.5, 8.5, 9.5, +}; + +static long _vq_quantmap__44c4_s_p9_2[] = { + 19, 17, 15, 13, 11, 9, 7, 5, + 3, 1, 0, 2, 4, 6, 8, 10, + 12, 14, 16, 18, 20, +}; + +static encode_aux_threshmatch _vq_auxt__44c4_s_p9_2 = { + _vq_quantthresh__44c4_s_p9_2, + _vq_quantmap__44c4_s_p9_2, + 21, + 21 +}; + +static static_codebook _44c4_s_p9_2 = { + 2, 441, + _vq_lengthlist__44c4_s_p9_2, + 1, -529268736, 1611661312, 5, 0, + _vq_quantlist__44c4_s_p9_2, + NULL, + &_vq_auxt__44c4_s_p9_2, + NULL, + 0 +}; + +static long _huff_lengthlist__44c4_s_short[] = { + 4, 7,14,10,15,10,12,15,16,15, 4, 2,11, 5,10, 6, + 8,11,14,14,14,10, 7,11, 6, 8,10,11,13,15, 9, 4, + 11, 5, 9, 6, 9,12,14,15,14, 9, 6, 9, 4, 5, 7,10, + 12,13, 9, 5, 7, 6, 5, 5, 7,10,13,13,10, 8, 9, 8, + 7, 6, 8,10,14,14,13,11,10,10, 7, 7, 8,11,14,15, + 13,12, 9, 9, 6, 5, 7,10,14,17,15,13,11,10, 6, 6, + 7, 9,12,17, +}; + +static static_codebook _huff_book__44c4_s_short = { + 2, 100, + _huff_lengthlist__44c4_s_short, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__44c5_s_long[] = { + 3, 8, 9,13,10,12,12,12,12,12, 6, 4, 6, 8, 6, 8, + 10,10,11,12, 8, 5, 4,10, 4, 7, 8, 9,10,11,13, 8, + 10, 8, 9, 9,11,12,13,14,10, 6, 4, 9, 3, 5, 6, 8, + 10,11,11, 8, 6, 9, 5, 5, 6, 7, 9,11,12, 9, 7,11, + 6, 6, 6, 7, 8,10,12,11, 9,12, 7, 7, 6, 6, 7, 9, + 13,12,10,13, 9, 8, 7, 7, 7, 8,11,15,11,15,11,10, + 9, 8, 7, 7, +}; + +static static_codebook _huff_book__44c5_s_long = { + 2, 100, + _huff_lengthlist__44c5_s_long, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__44c5_s_p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44c5_s_p1_0[] = { + 2, 4, 4, 0, 0, 0, 0, 0, 0, 4, 7, 7, 0, 0, 0, 0, + 0, 0, 4, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, + 0, 0, 0, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 7, 7, 0, 0, 0, 0, 0, 0, 7, 9, 8, 0, 0, + 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 7, 7, 0, 0, 0, 0, + 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, + 0, 0, 0, 9,10,11, 0, 0, 0, 0, 0, 0, 9,10,10, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, + 0, 0, 0, 0, 8,10, 9, 0, 0, 0, 0, 0, 0, 9,10,11, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 7, 7, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, + 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 9,11,10, 0, + 0, 0, 0, 0, 0, 8, 9,10, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 9,10,10, + 0, 0, 0, 0, 0, 0, 9,11,10, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c5_s_p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44c5_s_p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44c5_s_p1_0 = { + _vq_quantthresh__44c5_s_p1_0, + _vq_quantmap__44c5_s_p1_0, + 3, + 3 +}; + +static static_codebook _44c5_s_p1_0 = { + 8, 6561, + _vq_lengthlist__44c5_s_p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44c5_s_p1_0, + NULL, + &_vq_auxt__44c5_s_p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c5_s_p2_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c5_s_p2_0[] = { + 2, 4, 4, 0, 0, 0, 5, 5, 0, 0, 0, 5, 5, 0, 0, 0, + 8, 7, 0, 0, 0, 0, 0, 0, 0, 4, 6, 6, 0, 0, 0, 8, + 8, 0, 0, 0, 8, 7, 0, 0, 0,10,10, 0, 0, 0, 0, 0, + 0, 0, 4, 6, 6, 0, 0, 0, 8, 8, 0, 0, 0, 7, 8, 0, + 0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 5, 8, 7, 0, 0, 0, 8, 8, 0, 0, + 0, 8, 8, 0, 0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 5, + 7, 8, 0, 0, 0, 8, 8, 0, 0, 0, 8, 8, 0, 0, 0,10, + 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 5, 8, 8, 0, 0, 0, 8, 8, 0, 0, 0, 8, 8, + 0, 0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 5, 8, 8, 0, + 0, 0, 8, 8, 0, 0, 0, 8, 8, 0, 0, 0,10,10, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 8,10,10, 0, 0, 0,10,10, 0, 0, 0, 9,10, 0, 0, 0, + 11,10, 0, 0, 0, 0, 0, 0, 0, 8,10,10, 0, 0, 0,10, + 10, 0, 0, 0,10,10, 0, 0, 0,10,11, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c5_s_p2_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c5_s_p2_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c5_s_p2_0 = { + _vq_quantthresh__44c5_s_p2_0, + _vq_quantmap__44c5_s_p2_0, + 5, + 5 +}; + +static static_codebook _44c5_s_p2_0 = { + 4, 625, + _vq_lengthlist__44c5_s_p2_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c5_s_p2_0, + NULL, + &_vq_auxt__44c5_s_p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c5_s_p3_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c5_s_p3_0[] = { + 2, 4, 3, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 5, 6, 6, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 3, 5, 5, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 8, 8, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 5, 6, 6, 8, 8, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c5_s_p3_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c5_s_p3_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c5_s_p3_0 = { + _vq_quantthresh__44c5_s_p3_0, + _vq_quantmap__44c5_s_p3_0, + 5, + 5 +}; + +static static_codebook _44c5_s_p3_0 = { + 4, 625, + _vq_lengthlist__44c5_s_p3_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c5_s_p3_0, + NULL, + &_vq_auxt__44c5_s_p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c5_s_p4_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44c5_s_p4_0[] = { + 2, 3, 3, 6, 6, 0, 0, 0, 0, 0, 4, 4, 6, 6, 0, 0, + 0, 0, 0, 4, 4, 6, 6, 0, 0, 0, 0, 0, 5, 5, 6, 6, + 0, 0, 0, 0, 0, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, + 7, 7, 0, 0, 0, 0, 0, 0, 0, 8, 7, 0, 0, 0, 0, 0, + 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c5_s_p4_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44c5_s_p4_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44c5_s_p4_0 = { + _vq_quantthresh__44c5_s_p4_0, + _vq_quantmap__44c5_s_p4_0, + 9, + 9 +}; + +static static_codebook _44c5_s_p4_0 = { + 2, 81, + _vq_lengthlist__44c5_s_p4_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44c5_s_p4_0, + NULL, + &_vq_auxt__44c5_s_p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c5_s_p5_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44c5_s_p5_0[] = { + 2, 4, 3, 6, 6, 7, 7, 9, 9, 0, 4, 4, 6, 6, 7, 7, + 9, 9, 0, 4, 4, 6, 6, 7, 7, 9, 9, 0, 6, 6, 7, 7, + 7, 7, 9, 9, 0, 0, 0, 7, 6, 7, 7, 9, 9, 0, 0, 0, + 8, 8, 8, 8,10,10, 0, 0, 0, 8, 8, 8, 8,10,10, 0, + 0, 0, 9, 9, 9, 9,10,10, 0, 0, 0, 0, 0, 9, 9,10, + 10, +}; + +static float _vq_quantthresh__44c5_s_p5_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44c5_s_p5_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44c5_s_p5_0 = { + _vq_quantthresh__44c5_s_p5_0, + _vq_quantmap__44c5_s_p5_0, + 9, + 9 +}; + +static static_codebook _44c5_s_p5_0 = { + 2, 81, + _vq_lengthlist__44c5_s_p5_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44c5_s_p5_0, + NULL, + &_vq_auxt__44c5_s_p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c5_s_p6_0[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44c5_s_p6_0[] = { + 2, 4, 4, 6, 6, 8, 8, 9, 9, 9, 9,10,10,10,10,11, + 11, 0, 4, 4, 6, 6, 8, 8, 9, 9, 9, 9,10,10,11,11, + 12,12, 0, 4, 4, 6, 6, 8, 8, 9, 9, 9, 9,10,10,11, + 11,12,12, 0, 6, 6, 7, 7, 8, 8, 9, 9, 9, 9,10,10, + 11,11,12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10, + 10,11,11,12,12, 0, 0, 0, 7, 7, 9, 9,10,10,10,10, + 11,11,11,11,12,12, 0, 0, 0, 7, 7, 8, 9,10,10,10, + 10,11,11,11,11,12,12, 0, 0, 0, 8, 8, 9, 9,10,10, + 10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0, 9, 9,10, + 10,10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0, 9, 9, + 10,10,10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0, 9, + 9, 9,10,10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0, + 10,10,10,10,11,11,11,12,12,12,13,13, 0, 0, 0, 0, + 0, 0, 0,10,10,11,11,11,11,12,12,13,13, 0, 0, 0, + 0, 0, 0, 0,11,11,11,11,12,12,12,13,13,13, 0, 0, + 0, 0, 0, 0, 0,11,11,11,11,12,12,12,12,13,13, 0, + 0, 0, 0, 0, 0, 0,12,12,12,12,13,12,13,13,13,13, + 0, 0, 0, 0, 0, 0, 0, 0, 0,12,12,12,12,13,13,13, + 13, +}; + +static float _vq_quantthresh__44c5_s_p6_0[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__44c5_s_p6_0[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44c5_s_p6_0 = { + _vq_quantthresh__44c5_s_p6_0, + _vq_quantmap__44c5_s_p6_0, + 17, + 17 +}; + +static static_codebook _44c5_s_p6_0 = { + 2, 289, + _vq_lengthlist__44c5_s_p6_0, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__44c5_s_p6_0, + NULL, + &_vq_auxt__44c5_s_p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c5_s_p7_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44c5_s_p7_0[] = { + 1, 4, 4, 7, 6, 6, 7, 6, 6, 4, 7, 7,10, 9, 9,11, + 9, 9, 4, 7, 7,10, 9, 9,11, 9, 9, 7,10,10,11,11, + 10,11,11,11, 6, 9, 9,11,10,10,11,10,10, 6, 9, 9, + 11,10,10,11,10,10, 7,11,11,12,11,11,12,11,11, 6, + 9, 9,11,10,10,11,10,10, 6, 9, 9,11,10,10,11,10, + 10, +}; + +static float _vq_quantthresh__44c5_s_p7_0[] = { + -5.5, 5.5, +}; + +static long _vq_quantmap__44c5_s_p7_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44c5_s_p7_0 = { + _vq_quantthresh__44c5_s_p7_0, + _vq_quantmap__44c5_s_p7_0, + 3, + 3 +}; + +static static_codebook _44c5_s_p7_0 = { + 4, 81, + _vq_lengthlist__44c5_s_p7_0, + 1, -529137664, 1618345984, 2, 0, + _vq_quantlist__44c5_s_p7_0, + NULL, + &_vq_auxt__44c5_s_p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c5_s_p7_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44c5_s_p7_1[] = { + 2, 4, 4, 6, 6, 7, 7, 8, 8, 8, 8,10, 5, 5, 6, 6, + 7, 7, 8, 8, 8, 8,10, 5, 5, 6, 6, 7, 7, 8, 8, 8, + 8,10, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8,10,10,10, 7, + 7, 8, 8, 8, 8, 8, 8,10,10,10, 7, 7, 8, 8, 8, 8, + 8, 8,10,10,10, 7, 7, 8, 8, 8, 8, 8, 8,10,10,10, + 8, 8, 8, 8, 8, 8, 8, 9,10,10,10,10,10, 8, 8, 8, + 8, 8, 8,10,10,10,10,10, 9, 9, 8, 8, 8, 8,10,10, + 10,10,10, 8, 8, 8, 8, 8, 8, +}; + +static float _vq_quantthresh__44c5_s_p7_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__44c5_s_p7_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44c5_s_p7_1 = { + _vq_quantthresh__44c5_s_p7_1, + _vq_quantmap__44c5_s_p7_1, + 11, + 11 +}; + +static static_codebook _44c5_s_p7_1 = { + 2, 121, + _vq_lengthlist__44c5_s_p7_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__44c5_s_p7_1, + NULL, + &_vq_auxt__44c5_s_p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c5_s_p8_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c5_s_p8_0[] = { + 1, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9,10,10, 6, 5, 5, + 7, 7, 8, 8, 8, 9,10,10,10,10, 7, 5, 5, 7, 7, 8, + 8, 9, 9,10,10,10,10, 0, 8, 8, 8, 8, 9, 9, 9, 9, + 10,10,11,11, 0, 8, 8, 8, 8, 9, 9, 9, 9,10,10,11, + 11, 0,12,12, 9, 9, 9,10,10,10,10,10,11,11, 0,13, + 13, 9, 9, 9, 9,10,10,11,11,11,11, 0, 0, 0,10,10, + 10,10,10,10,11,11,11,11, 0, 0, 0,10,10,10,10,10, + 10,11,11,12,12, 0, 0, 0,14,14,11,11,11,11,12,12, + 12,12, 0, 0, 0,14,14,11,11,11,11,12,12,12,12, 0, + 0, 0, 0, 0,12,12,12,12,12,12,13,13, 0, 0, 0, 0, + 0,12,12,12,12,12,12,13,13, +}; + +static float _vq_quantthresh__44c5_s_p8_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__44c5_s_p8_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c5_s_p8_0 = { + _vq_quantthresh__44c5_s_p8_0, + _vq_quantmap__44c5_s_p8_0, + 13, + 13 +}; + +static static_codebook _44c5_s_p8_0 = { + 2, 169, + _vq_lengthlist__44c5_s_p8_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__44c5_s_p8_0, + NULL, + &_vq_auxt__44c5_s_p8_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c5_s_p8_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c5_s_p8_1[] = { + 2, 4, 4, 5, 5, 6, 5, 5, 5, 5, 6, 4, 5, 5, 5, 6, + 5, 5, 5, 5, 6, 6, 6, 5, 5, +}; + +static float _vq_quantthresh__44c5_s_p8_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c5_s_p8_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c5_s_p8_1 = { + _vq_quantthresh__44c5_s_p8_1, + _vq_quantmap__44c5_s_p8_1, + 5, + 5 +}; + +static static_codebook _44c5_s_p8_1 = { + 2, 25, + _vq_lengthlist__44c5_s_p8_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c5_s_p8_1, + NULL, + &_vq_auxt__44c5_s_p8_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c5_s_p9_0[] = { + 7, + 6, + 8, + 5, + 9, + 4, + 10, + 3, + 11, + 2, + 12, + 1, + 13, + 0, + 14, +}; + +static long _vq_lengthlist__44c5_s_p9_0[] = { + 1, 3, 3,13,13,13,13,13,13,13,13,13,13,13,13, 4, + 7, 7,13,13,13,13,13,13,13,13,13,13,13,13, 3, 8, + 6,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, + 13,13,13,13,13,13,13,13,13,12,12,12,12,12,12,12, + 12, +}; + +static float _vq_quantthresh__44c5_s_p9_0[] = { + -2320.5, -1963.5, -1606.5, -1249.5, -892.5, -535.5, -178.5, 178.5, + 535.5, 892.5, 1249.5, 1606.5, 1963.5, 2320.5, +}; + +static long _vq_quantmap__44c5_s_p9_0[] = { + 13, 11, 9, 7, 5, 3, 1, 0, + 2, 4, 6, 8, 10, 12, 14, +}; + +static encode_aux_threshmatch _vq_auxt__44c5_s_p9_0 = { + _vq_quantthresh__44c5_s_p9_0, + _vq_quantmap__44c5_s_p9_0, + 15, + 15 +}; + +static static_codebook _44c5_s_p9_0 = { + 2, 225, + _vq_lengthlist__44c5_s_p9_0, + 1, -512522752, 1628852224, 4, 0, + _vq_quantlist__44c5_s_p9_0, + NULL, + &_vq_auxt__44c5_s_p9_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c5_s_p9_1[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44c5_s_p9_1[] = { + 1, 4, 4, 5, 5, 7, 7, 9, 8,10, 9,10,10,11,10,11, + 11, 6, 5, 5, 7, 7, 8, 9,10,10,11,10,12,11,12,11, + 13,12, 6, 5, 5, 7, 7, 9, 9,10,10,11,11,12,12,13, + 12,13,13,18, 8, 8, 8, 8, 9, 9,10,11,11,11,12,11, + 13,11,13,12,18, 8, 8, 8, 8,10,10,11,11,12,12,13, + 13,13,13,13,14,18,12,12, 9, 9,11,11,11,11,12,12, + 13,12,13,12,13,13,20,13,12, 9, 9,11,11,11,11,12, + 12,13,13,13,14,14,13,20,18,19,11,12,11,11,12,12, + 13,13,13,13,13,13,14,13,18,19,19,12,11,11,11,12, + 12,13,12,13,13,13,14,14,13,18,17,19,14,15,12,12, + 12,13,13,13,14,14,14,14,14,14,19,19,19,16,15,12, + 11,13,12,14,14,14,13,13,14,14,14,19,18,19,18,19, + 13,13,13,13,14,14,14,13,14,14,14,14,18,17,19,19, + 19,13,13,13,11,13,11,13,14,14,14,14,14,19,17,17, + 18,18,16,16,13,13,13,13,14,13,15,15,14,14,19,19, + 17,17,18,16,16,13,11,14,10,13,12,14,14,14,14,19, + 19,19,19,19,18,17,13,14,13,11,14,13,14,14,15,15, + 19,19,19,17,19,18,18,14,13,12,11,14,11,15,15,15, + 15, +}; + +static float _vq_quantthresh__44c5_s_p9_1[] = { + -157.5, -136.5, -115.5, -94.5, -73.5, -52.5, -31.5, -10.5, + 10.5, 31.5, 52.5, 73.5, 94.5, 115.5, 136.5, 157.5, +}; + +static long _vq_quantmap__44c5_s_p9_1[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44c5_s_p9_1 = { + _vq_quantthresh__44c5_s_p9_1, + _vq_quantmap__44c5_s_p9_1, + 17, + 17 +}; + +static static_codebook _44c5_s_p9_1 = { + 2, 289, + _vq_lengthlist__44c5_s_p9_1, + 1, -520814592, 1620377600, 5, 0, + _vq_quantlist__44c5_s_p9_1, + NULL, + &_vq_auxt__44c5_s_p9_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c5_s_p9_2[] = { + 10, + 9, + 11, + 8, + 12, + 7, + 13, + 6, + 14, + 5, + 15, + 4, + 16, + 3, + 17, + 2, + 18, + 1, + 19, + 0, + 20, +}; + +static long _vq_lengthlist__44c5_s_p9_2[] = { + 3, 5, 5, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 9,11, 5, 6, 7, 7, 8, 7, 8, 8, 8, 8, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,11, 5, 5, 7, 7, 7, + 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,11, + 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, + 9,10, 9,10,11,11,11, 7, 7, 8, 8, 8, 8, 9, 9, 9, + 9, 9, 9,10,10,10,10,10,10,11,11,11, 8, 8, 8, 8, + 9, 9, 9, 9, 9, 9, 9,10,10,10,10,10,10,10,11,11, + 11, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9,10,10,10,10,10, + 10,10,10,11,11,11, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 10,10,10,10,10,10,10,10,11,11,11,11,11, 9, 9, 9, + 9, 9, 9,10, 9,10,10,10,10,10,10,10,10,11,11,11, + 11,11, 9, 9, 9, 9, 9, 9,10,10,10,10,10,10,10,10, + 10,10,11,11,11,11,11, 9, 9, 9, 9, 9, 9,10,10,10, + 10,10,10,10,10,10,10,11,11,11,11,11, 9, 9,10, 9, + 10,10,10,10,10,10,10,10,10,10,10,10,11,11,11,11, + 11,11,11, 9, 9,10,10,10,10,10,10,10,10,10,10,10, + 10,11,11,11,11,11,11,11,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,11,11,11,11,11,11,11,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,11,11,11,11,11, + 11,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 11,11,11,11,11,11,11,11,11,10,10,10,10,10,10,10, + 10,10,10,10,10,11,11,11,11,11,11,11,11,11,10,10, + 10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11, + 11,11,11,10,10,10,10,10,10,10,10,10,10,10,10,11, + 11,11,11,11,11,11,11,11,10,10,10,10,10,10,10,10, + 10,10,10,10,11,11,11,11,11,11,11,11,11,11,11,10, + 10,10,10,10,10,10,10,10,10, +}; + +static float _vq_quantthresh__44c5_s_p9_2[] = { + -9.5, -8.5, -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, + -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, + 6.5, 7.5, 8.5, 9.5, +}; + +static long _vq_quantmap__44c5_s_p9_2[] = { + 19, 17, 15, 13, 11, 9, 7, 5, + 3, 1, 0, 2, 4, 6, 8, 10, + 12, 14, 16, 18, 20, +}; + +static encode_aux_threshmatch _vq_auxt__44c5_s_p9_2 = { + _vq_quantthresh__44c5_s_p9_2, + _vq_quantmap__44c5_s_p9_2, + 21, + 21 +}; + +static static_codebook _44c5_s_p9_2 = { + 2, 441, + _vq_lengthlist__44c5_s_p9_2, + 1, -529268736, 1611661312, 5, 0, + _vq_quantlist__44c5_s_p9_2, + NULL, + &_vq_auxt__44c5_s_p9_2, + NULL, + 0 +}; + +static long _huff_lengthlist__44c5_s_short[] = { + 5, 8,10,14,11,11,12,16,15,17, 5, 5, 7, 9, 7, 8, + 10,13,17,17, 7, 5, 5,10, 5, 7, 8,11,13,15,10, 8, + 10, 8, 8, 8,11,15,18,18, 8, 5, 5, 8, 3, 4, 6,10, + 14,16, 9, 7, 6, 7, 4, 3, 5, 9,14,18,10, 9, 8,10, + 6, 5, 6, 9,14,18,12,12,11,12, 8, 7, 8,11,14,18, + 14,13,12,10, 7, 5, 6, 9,14,18,14,14,13,10, 6, 5, + 6, 8,11,16, +}; + +static static_codebook _huff_book__44c5_s_short = { + 2, 100, + _huff_lengthlist__44c5_s_short, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__44c6_s_long[] = { + 3, 8,11,13,14,14,13,13,16,14, 6, 3, 4, 7, 9, 9, + 10,11,14,13,10, 4, 3, 5, 7, 7, 9,10,13,15,12, 7, + 4, 4, 6, 6, 8,10,13,15,12, 8, 6, 6, 6, 6, 8,10, + 13,14,11, 9, 7, 6, 6, 6, 7, 8,12,11,13,10, 9, 8, + 7, 6, 6, 7,11,11,13,11,10, 9, 9, 7, 7, 6,10,11, + 13,13,13,13,13,11, 9, 8,10,12,12,15,15,16,15,12, + 11,10,10,12, +}; + +static static_codebook _huff_book__44c6_s_long = { + 2, 100, + _huff_lengthlist__44c6_s_long, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__44c6_s_p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44c6_s_p1_0[] = { + 1, 5, 5, 0, 5, 5, 0, 5, 5, 5, 8, 7, 0, 9, 9, 0, + 9, 8, 5, 7, 8, 0, 9, 9, 0, 8, 9, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 5, 9, 8, 0, 8, 8, 0, 8, 8, 5, 8, 9, + 0, 8, 8, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, + 9, 9, 0, 8, 8, 0, 8, 8, 5, 9, 9, 0, 8, 8, 0, 8, + 8, +}; + +static float _vq_quantthresh__44c6_s_p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44c6_s_p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44c6_s_p1_0 = { + _vq_quantthresh__44c6_s_p1_0, + _vq_quantmap__44c6_s_p1_0, + 3, + 3 +}; + +static static_codebook _44c6_s_p1_0 = { + 4, 81, + _vq_lengthlist__44c6_s_p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44c6_s_p1_0, + NULL, + &_vq_auxt__44c6_s_p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c6_s_p2_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c6_s_p2_0[] = { + 3, 5, 5, 8, 8, 0, 5, 5, 8, 8, 0, 5, 5, 8, 8, 0, + 7, 7, 9, 9, 0, 0, 0, 9, 9, 5, 7, 7, 9, 9, 0, 8, + 8,10,10, 0, 8, 7,10, 9, 0,10,10,11,11, 0, 0, 0, + 11,11, 5, 7, 7, 9, 9, 0, 8, 8,10,10, 0, 7, 8, 9, + 10, 0,10,10,11,11, 0, 0, 0,11,11, 8, 9, 9,11,11, + 0,11,11,12,12, 0,11,10,12,12, 0,13,14,14,14, 0, + 0, 0,14,13, 8, 9, 9,11,11, 0,11,11,12,12, 0,10, + 11,12,12, 0,14,13,14,14, 0, 0, 0,13,14, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 5, 8, 7,11,10, 0, 7, 7,10,10, + 0, 7, 7,10,10, 0, 9, 9,11,10, 0, 0, 0,11,11, 5, + 7, 8,10,11, 0, 7, 7,10,10, 0, 7, 7,10,10, 0, 9, + 9,10,11, 0, 0, 0,11,11, 8,10, 9,12,12, 0,10,10, + 12,12, 0,10,10,12,12, 0,12,12,13,13, 0, 0, 0,13, + 13, 8, 9,10,12,12, 0,10,10,11,12, 0,10,10,12,12, + 0,12,12,13,13, 0, 0, 0,13,13, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 5, 8, 8,11,11, 0, 7, 7,10,10, 0, 7, 7, + 10,10, 0, 9, 9,10,11, 0, 0, 0,11,10, 5, 8, 8,11, + 11, 0, 7, 7,10,10, 0, 7, 7,10,10, 0, 9, 9,11,11, + 0, 0, 0,10,11, 8,10,10,12,12, 0,10,10,12,12, 0, + 10,10,12,12, 0,12,13,13,13, 0, 0, 0,14,13, 8,10, + 10,12,12, 0,10,10,12,12, 0,10,10,12,12, 0,13,12, + 13,13, 0, 0, 0,13,13, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 7,10,10,14,13, 0, 9, 9,13,12, 0, 9, 9,12,12, 0, + 10,10,12,12, 0, 0, 0,12,12, 7,10,10,13,14, 0, 9, + 9,12,13, 0, 9, 9,12,12, 0,10,10,12,12, 0, 0, 0, + 12,12, 9,11,11,14,13, 0,11,10,14,13, 0,11,11,13, + 13, 0,12,12,13,13, 0, 0, 0,13,13, 9,11,11,13,14, + 0,10,11,13,14, 0,11,11,13,13, 0,12,12,13,13, 0, + 0, 0,13,13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, + 11,11,14,14, 0,11,11,13,13, 0,11,10,13,13, 0,12, + 12,13,13, 0, 0, 0,13,13, 9,11,11,14,14, 0,11,11, + 13,13, 0,10,11,13,13, 0,12,12,14,13, 0, 0, 0,13, + 13, +}; + +static float _vq_quantthresh__44c6_s_p2_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c6_s_p2_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c6_s_p2_0 = { + _vq_quantthresh__44c6_s_p2_0, + _vq_quantmap__44c6_s_p2_0, + 5, + 5 +}; + +static static_codebook _44c6_s_p2_0 = { + 4, 625, + _vq_lengthlist__44c6_s_p2_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c6_s_p2_0, + NULL, + &_vq_auxt__44c6_s_p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c6_s_p3_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44c6_s_p3_0[] = { + 2, 3, 4, 6, 6, 7, 7, 9, 9, 0, 4, 4, 6, 6, 7, 7, + 9,10, 0, 4, 4, 6, 6, 7, 7,10, 9, 0, 5, 5, 7, 7, + 8, 8,10,10, 0, 0, 0, 7, 6, 8, 8,10,10, 0, 0, 0, + 7, 7, 9, 9,11,11, 0, 0, 0, 7, 7, 9, 9,11,11, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c6_s_p3_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44c6_s_p3_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44c6_s_p3_0 = { + _vq_quantthresh__44c6_s_p3_0, + _vq_quantmap__44c6_s_p3_0, + 9, + 9 +}; + +static static_codebook _44c6_s_p3_0 = { + 2, 81, + _vq_lengthlist__44c6_s_p3_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44c6_s_p3_0, + NULL, + &_vq_auxt__44c6_s_p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c6_s_p4_0[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44c6_s_p4_0[] = { + 2, 4, 4, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, 9,10,10, + 10, 0, 4, 4, 6, 6, 8, 8, 9, 9, 9, 9,10,10,10,10, + 11,11, 0, 4, 4, 6, 6, 8, 8, 9, 9, 9, 9,10,10,10, + 10,11,11, 0, 6, 6, 7, 7, 8, 8, 9, 9, 9, 9,10,10, + 11,11,11,11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10, + 10,11,11,11,11, 0, 0, 0, 7, 7, 9, 9,10,10,10,10, + 11,11,11,11,12,12, 0, 0, 0, 7, 7, 9, 9,10,10,10, + 10,11,11,11,11,12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9, + 10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0, 8, 8, 9, + 9,10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c6_s_p4_0[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__44c6_s_p4_0[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44c6_s_p4_0 = { + _vq_quantthresh__44c6_s_p4_0, + _vq_quantmap__44c6_s_p4_0, + 17, + 17 +}; + +static static_codebook _44c6_s_p4_0 = { + 2, 289, + _vq_lengthlist__44c6_s_p4_0, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__44c6_s_p4_0, + NULL, + &_vq_auxt__44c6_s_p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c6_s_p5_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44c6_s_p5_0[] = { + 1, 4, 4, 5, 7, 7, 6, 7, 7, 4, 6, 6, 9, 9,10,10, + 10, 9, 4, 6, 6, 9,10, 9,10, 9,10, 6, 9, 9,10,12, + 11,10,11,11, 7,10, 9,11,12,12,12,12,12, 7,10,10, + 11,12,12,12,12,12, 6,10,10,10,12,12,11,12,12, 7, + 9,10,11,12,12,12,12,12, 7,10, 9,12,12,12,12,12, + 12, +}; + +static float _vq_quantthresh__44c6_s_p5_0[] = { + -5.5, 5.5, +}; + +static long _vq_quantmap__44c6_s_p5_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44c6_s_p5_0 = { + _vq_quantthresh__44c6_s_p5_0, + _vq_quantmap__44c6_s_p5_0, + 3, + 3 +}; + +static static_codebook _44c6_s_p5_0 = { + 4, 81, + _vq_lengthlist__44c6_s_p5_0, + 1, -529137664, 1618345984, 2, 0, + _vq_quantlist__44c6_s_p5_0, + NULL, + &_vq_auxt__44c6_s_p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c6_s_p5_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44c6_s_p5_1[] = { + 3, 5, 4, 6, 6, 7, 7, 8, 8, 8, 8,11, 4, 4, 6, 6, + 7, 7, 8, 8, 8, 8,11, 4, 4, 6, 6, 7, 7, 8, 8, 8, + 8,11, 6, 6, 6, 6, 8, 8, 8, 8, 9, 9,11,11,11, 6, + 6, 7, 8, 8, 8, 8, 9,11,11,11, 7, 7, 8, 8, 8, 8, + 8, 8,11,11,11, 7, 7, 8, 8, 8, 8, 8, 8,11,11,11, + 8, 8, 8, 8, 8, 8, 8, 8,11,11,11,10,10, 8, 8, 8, + 8, 8, 8,11,11,11,10,10, 8, 8, 8, 8, 8, 8,11,11, + 11,10,10, 7, 7, 8, 8, 8, 8, +}; + +static float _vq_quantthresh__44c6_s_p5_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__44c6_s_p5_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44c6_s_p5_1 = { + _vq_quantthresh__44c6_s_p5_1, + _vq_quantmap__44c6_s_p5_1, + 11, + 11 +}; + +static static_codebook _44c6_s_p5_1 = { + 2, 121, + _vq_lengthlist__44c6_s_p5_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__44c6_s_p5_1, + NULL, + &_vq_auxt__44c6_s_p5_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c6_s_p6_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c6_s_p6_0[] = { + 1, 4, 4, 6, 6, 8, 8, 8, 8,10, 9,10,10, 6, 5, 5, + 7, 7, 9, 9, 9, 9,10,10,11,11, 6, 5, 5, 7, 7, 9, + 9,10, 9,11,10,11,11, 0, 6, 6, 7, 7, 9, 9,10,10, + 11,11,12,12, 0, 7, 7, 7, 7, 9, 9,10,10,11,11,12, + 12, 0,11,11, 8, 8,10,10,11,11,12,12,12,12, 0,11, + 12, 9, 8,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +static float _vq_quantthresh__44c6_s_p6_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__44c6_s_p6_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c6_s_p6_0 = { + _vq_quantthresh__44c6_s_p6_0, + _vq_quantmap__44c6_s_p6_0, + 13, + 13 +}; + +static static_codebook _44c6_s_p6_0 = { + 2, 169, + _vq_lengthlist__44c6_s_p6_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__44c6_s_p6_0, + NULL, + &_vq_auxt__44c6_s_p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c6_s_p6_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c6_s_p6_1[] = { + 3, 4, 4, 5, 5, 5, 4, 4, 5, 5, 5, 4, 4, 5, 5, 6, + 5, 5, 5, 5, 6, 6, 6, 5, 5, +}; + +static float _vq_quantthresh__44c6_s_p6_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c6_s_p6_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c6_s_p6_1 = { + _vq_quantthresh__44c6_s_p6_1, + _vq_quantmap__44c6_s_p6_1, + 5, + 5 +}; + +static static_codebook _44c6_s_p6_1 = { + 2, 25, + _vq_lengthlist__44c6_s_p6_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c6_s_p6_1, + NULL, + &_vq_auxt__44c6_s_p6_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c6_s_p7_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c6_s_p7_0[] = { + 1, 4, 4, 6, 6, 8, 8, 8, 8,10,10,11,10, 6, 5, 5, + 7, 7, 8, 8, 9, 9,10,10,12,11, 6, 5, 5, 7, 7, 8, + 8, 9, 9,10,10,12,11,21, 7, 7, 7, 7, 9, 9,10,10, + 11,11,12,12,21, 7, 7, 7, 7, 9, 9,10,10,11,11,12, + 12,21,12,12, 9, 9,10,10,11,11,11,11,12,12,21,12, + 12, 9, 9,10,10,11,11,12,12,12,12,21,21,21,11,11, + 10,10,11,12,12,12,13,13,21,21,21,11,11,10,10,12, + 12,12,12,13,13,21,21,21,15,15,11,11,12,12,13,13, + 13,13,21,21,21,15,16,11,11,12,12,13,13,14,14,21, + 21,21,21,20,13,13,13,13,13,13,14,14,20,20,20,20, + 20,13,13,13,13,13,13,14,14, +}; + +static float _vq_quantthresh__44c6_s_p7_0[] = { + -60.5, -49.5, -38.5, -27.5, -16.5, -5.5, 5.5, 16.5, + 27.5, 38.5, 49.5, 60.5, +}; + +static long _vq_quantmap__44c6_s_p7_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c6_s_p7_0 = { + _vq_quantthresh__44c6_s_p7_0, + _vq_quantmap__44c6_s_p7_0, + 13, + 13 +}; + +static static_codebook _44c6_s_p7_0 = { + 2, 169, + _vq_lengthlist__44c6_s_p7_0, + 1, -523206656, 1618345984, 4, 0, + _vq_quantlist__44c6_s_p7_0, + NULL, + &_vq_auxt__44c6_s_p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c6_s_p7_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44c6_s_p7_1[] = { + 3, 5, 5, 6, 6, 7, 7, 7, 7, 7, 7, 9, 5, 5, 6, 6, + 7, 7, 7, 7, 8, 7, 8, 5, 5, 6, 6, 7, 7, 7, 7, 7, + 7, 9, 6, 6, 7, 7, 7, 7, 8, 7, 7, 8, 9, 9, 9, 7, + 7, 7, 7, 7, 7, 7, 8, 9, 9, 9, 7, 7, 7, 7, 8, 8, + 8, 8, 9, 9, 9, 7, 7, 7, 7, 7, 7, 8, 8, 9, 9, 9, + 8, 8, 8, 8, 7, 7, 8, 8, 9, 9, 9, 9, 8, 8, 8, 7, + 7, 8, 8, 9, 9, 9, 8, 8, 8, 8, 7, 7, 8, 8, 9, 9, + 9, 8, 8, 7, 7, 7, 7, 8, 8, +}; + +static float _vq_quantthresh__44c6_s_p7_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__44c6_s_p7_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44c6_s_p7_1 = { + _vq_quantthresh__44c6_s_p7_1, + _vq_quantmap__44c6_s_p7_1, + 11, + 11 +}; + +static static_codebook _44c6_s_p7_1 = { + 2, 121, + _vq_lengthlist__44c6_s_p7_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__44c6_s_p7_1, + NULL, + &_vq_auxt__44c6_s_p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c6_s_p8_0[] = { + 7, + 6, + 8, + 5, + 9, + 4, + 10, + 3, + 11, + 2, + 12, + 1, + 13, + 0, + 14, +}; + +static long _vq_lengthlist__44c6_s_p8_0[] = { + 1, 4, 4, 7, 7, 8, 8, 7, 7, 8, 7, 9, 8,10, 9, 6, + 5, 5, 8, 8, 9, 9, 8, 8, 9, 9,11,10,11,10, 6, 5, + 5, 8, 8, 9, 9, 8, 8, 9, 9,10,10,11,11,18, 8, 8, + 9, 8,10,10, 9, 9,10,10,10,10,11,10,18, 8, 8, 9, + 9,10,10, 9, 9,10,10,11,11,12,12,18,12,13, 9,10, + 10,10, 9,10,10,10,11,11,12,11,18,13,13, 9, 9,10, + 10,10,10,10,10,11,11,12,12,18,18,18,10,10, 9, 9, + 11,11,11,11,11,12,12,12,18,18,18,10, 9,10, 9,11, + 10,11,11,11,11,13,12,18,18,18,14,13,10,10,11,11, + 12,12,12,12,12,12,18,18,18,14,13,10,10,11,10,12, + 12,12,12,12,12,18,18,18,18,18,12,12,11,11,12,12, + 13,13,13,14,18,18,18,18,18,12,12,11,11,12,11,13, + 13,14,13,18,18,18,18,18,16,16,11,12,12,13,13,13, + 14,13,18,18,18,18,18,16,15,12,11,12,11,13,11,15, + 14, +}; + +static float _vq_quantthresh__44c6_s_p8_0[] = { + -136.5, -115.5, -94.5, -73.5, -52.5, -31.5, -10.5, 10.5, + 31.5, 52.5, 73.5, 94.5, 115.5, 136.5, +}; + +static long _vq_quantmap__44c6_s_p8_0[] = { + 13, 11, 9, 7, 5, 3, 1, 0, + 2, 4, 6, 8, 10, 12, 14, +}; + +static encode_aux_threshmatch _vq_auxt__44c6_s_p8_0 = { + _vq_quantthresh__44c6_s_p8_0, + _vq_quantmap__44c6_s_p8_0, + 15, + 15 +}; + +static static_codebook _44c6_s_p8_0 = { + 2, 225, + _vq_lengthlist__44c6_s_p8_0, + 1, -520986624, 1620377600, 4, 0, + _vq_quantlist__44c6_s_p8_0, + NULL, + &_vq_auxt__44c6_s_p8_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c6_s_p8_1[] = { + 10, + 9, + 11, + 8, + 12, + 7, + 13, + 6, + 14, + 5, + 15, + 4, + 16, + 3, + 17, + 2, + 18, + 1, + 19, + 0, + 20, +}; + +static long _vq_lengthlist__44c6_s_p8_1[] = { + 3, 5, 5, 6, 6, 7, 7, 7, 7, 8, 7, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8,10, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10, 6, 6, 7, 7, 8, + 8, 8, 8, 8, 8, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9,10, + 7, 7, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9,10,11,11, 8, 7, 8, 8, 8, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9,11,11,11, 8, 8, 8, 8, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,11,11, + 11, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9,11,11,11, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9,11,11,11,11,11, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10, 9,11,11,11, + 11,11, 9, 9, 9, 9, 9, 9,10, 9, 9,10, 9,10, 9, 9, + 10, 9,11,11,11,11,11, 9, 9, 9, 9, 9, 9, 9,10,10, + 10,10, 9,10,10, 9,10,11,11,11,11,11, 9, 9, 9, 9, + 10,10,10, 9,10,10,10,10, 9,10,10, 9,11,11,11,11, + 11,11,11, 9, 9, 9, 9,10,10,10,10, 9,10,10,10,10, + 10,11,11,11,11,11,11,11,10, 9,10,10,10,10,10,10, + 10, 9,10, 9,10,10,11,11,11,11,11,11,11,10, 9,10, + 9,10,10, 9,10,10,10,10,10,10,10,11,11,11,11,11, + 11,11,10,10,10,10,10,10,10, 9,10,10,10,10,10, 9, + 11,11,11,11,11,11,11,11,11,10,10,10,10,10,10,10, + 10,10,10,10,10,11,11,11,11,11,11,11,11,11,10,10, + 10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11, + 11,11,11,10,10,10,10,10,10,10,10,10, 9,10,10,11, + 11,11,11,11,11,11,11,11,10,10,10, 9,10,10,10,10, + 10,10,10,10,10,11,11,11,11,11,11,11,11,10,11, 9, + 10,10,10,10,10,10,10,10,10, +}; + +static float _vq_quantthresh__44c6_s_p8_1[] = { + -9.5, -8.5, -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, + -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, + 6.5, 7.5, 8.5, 9.5, +}; + +static long _vq_quantmap__44c6_s_p8_1[] = { + 19, 17, 15, 13, 11, 9, 7, 5, + 3, 1, 0, 2, 4, 6, 8, 10, + 12, 14, 16, 18, 20, +}; + +static encode_aux_threshmatch _vq_auxt__44c6_s_p8_1 = { + _vq_quantthresh__44c6_s_p8_1, + _vq_quantmap__44c6_s_p8_1, + 21, + 21 +}; + +static static_codebook _44c6_s_p8_1 = { + 2, 441, + _vq_lengthlist__44c6_s_p8_1, + 1, -529268736, 1611661312, 5, 0, + _vq_quantlist__44c6_s_p8_1, + NULL, + &_vq_auxt__44c6_s_p8_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c6_s_p9_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c6_s_p9_0[] = { + 1, 3, 3,11,11,11,11,11,11,11,11,11,11, 4, 7, 7, + 11,11,11,11,11,11,11,11,11,11, 5, 8, 9,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10, +}; + +static float _vq_quantthresh__44c6_s_p9_0[] = { + -3503.5, -2866.5, -2229.5, -1592.5, -955.5, -318.5, 318.5, 955.5, + 1592.5, 2229.5, 2866.5, 3503.5, +}; + +static long _vq_quantmap__44c6_s_p9_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c6_s_p9_0 = { + _vq_quantthresh__44c6_s_p9_0, + _vq_quantmap__44c6_s_p9_0, + 13, + 13 +}; + +static static_codebook _44c6_s_p9_0 = { + 2, 169, + _vq_lengthlist__44c6_s_p9_0, + 1, -511845376, 1630791680, 4, 0, + _vq_quantlist__44c6_s_p9_0, + NULL, + &_vq_auxt__44c6_s_p9_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c6_s_p9_1[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c6_s_p9_1[] = { + 1, 4, 4, 7, 7, 7, 7, 7, 6, 8, 8, 8, 8, 6, 6, 6, + 8, 8, 8, 8, 8, 7, 9, 8,10,10, 5, 6, 6, 8, 8, 9, + 9, 8, 8,10,10,10,10,16, 9, 9, 9, 9, 9, 9, 9, 8, + 10, 9,11,11,16, 8, 9, 9, 9, 9, 9, 9, 9,10,10,11, + 11,16,13,13, 9, 9,10, 9, 9,10,11,11,11,12,16,13, + 14, 9, 8,10, 8, 9, 9,10,10,12,11,16,14,16, 9, 9, + 9, 9,11,11,12,11,12,11,16,16,16, 9, 7, 9, 6,11, + 11,11,10,11,11,16,16,16,11,12, 9,10,11,11,12,11, + 13,13,16,16,16,12,11,10, 7,12,10,12,12,12,12,16, + 16,15,16,16,10,11,10,11,13,13,14,12,16,16,16,15, + 15,12,10,11,11,13,11,12,13, +}; + +static float _vq_quantthresh__44c6_s_p9_1[] = { + -269.5, -220.5, -171.5, -122.5, -73.5, -24.5, 24.5, 73.5, + 122.5, 171.5, 220.5, 269.5, +}; + +static long _vq_quantmap__44c6_s_p9_1[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c6_s_p9_1 = { + _vq_quantthresh__44c6_s_p9_1, + _vq_quantmap__44c6_s_p9_1, + 13, + 13 +}; + +static static_codebook _44c6_s_p9_1 = { + 2, 169, + _vq_lengthlist__44c6_s_p9_1, + 1, -518889472, 1622704128, 4, 0, + _vq_quantlist__44c6_s_p9_1, + NULL, + &_vq_auxt__44c6_s_p9_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c6_s_p9_2[] = { + 24, + 23, + 25, + 22, + 26, + 21, + 27, + 20, + 28, + 19, + 29, + 18, + 30, + 17, + 31, + 16, + 32, + 15, + 33, + 14, + 34, + 13, + 35, + 12, + 36, + 11, + 37, + 10, + 38, + 9, + 39, + 8, + 40, + 7, + 41, + 6, + 42, + 5, + 43, + 4, + 44, + 3, + 45, + 2, + 46, + 1, + 47, + 0, + 48, +}; + +static long _vq_lengthlist__44c6_s_p9_2[] = { + 2, 4, 3, 4, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, +}; + +static float _vq_quantthresh__44c6_s_p9_2[] = { + -23.5, -22.5, -21.5, -20.5, -19.5, -18.5, -17.5, -16.5, + -15.5, -14.5, -13.5, -12.5, -11.5, -10.5, -9.5, -8.5, + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, + 8.5, 9.5, 10.5, 11.5, 12.5, 13.5, 14.5, 15.5, + 16.5, 17.5, 18.5, 19.5, 20.5, 21.5, 22.5, 23.5, +}; + +static long _vq_quantmap__44c6_s_p9_2[] = { + 47, 45, 43, 41, 39, 37, 35, 33, + 31, 29, 27, 25, 23, 21, 19, 17, + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, 18, 20, 22, 24, 26, 28, 30, + 32, 34, 36, 38, 40, 42, 44, 46, + 48, +}; + +static encode_aux_threshmatch _vq_auxt__44c6_s_p9_2 = { + _vq_quantthresh__44c6_s_p9_2, + _vq_quantmap__44c6_s_p9_2, + 49, + 49 +}; + +static static_codebook _44c6_s_p9_2 = { + 1, 49, + _vq_lengthlist__44c6_s_p9_2, + 1, -526909440, 1611661312, 6, 0, + _vq_quantlist__44c6_s_p9_2, + NULL, + &_vq_auxt__44c6_s_p9_2, + NULL, + 0 +}; + +static long _huff_lengthlist__44c6_s_short[] = { + 3, 9,11,11,13,14,19,17,17,19, 5, 4, 5, 8,10,10, + 13,16,18,19, 7, 4, 4, 5, 8, 9,12,14,17,19, 8, 6, + 5, 5, 7, 7,10,13,16,18,10, 8, 7, 6, 5, 5, 8,11, + 17,19,11, 9, 7, 7, 5, 4, 5, 8,17,19,13,11, 8, 7, + 7, 5, 5, 7,16,18,14,13, 8, 6, 6, 5, 5, 7,16,18, + 18,16,10, 8, 8, 7, 7, 9,16,18,18,18,12,10,10, 9, + 9,10,17,18, +}; + +static static_codebook _huff_book__44c6_s_short = { + 2, 100, + _huff_lengthlist__44c6_s_short, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__44c7_s_long[] = { + 3, 8,11,13,15,14,14,13,15,14, 6, 4, 5, 7, 9,10, + 11,11,14,13,10, 4, 3, 5, 7, 8, 9,10,13,13,12, 7, + 4, 4, 5, 6, 8, 9,12,14,13, 9, 6, 5, 5, 6, 8, 9, + 12,14,12, 9, 7, 6, 5, 5, 6, 8,11,11,12,11, 9, 8, + 7, 6, 6, 7,10,11,13,11,10, 9, 8, 7, 6, 6, 9,11, + 13,13,12,12,12,10, 9, 8, 9,11,12,14,15,15,14,12, + 11,10,10,12, +}; + +static static_codebook _huff_book__44c7_s_long = { + 2, 100, + _huff_lengthlist__44c7_s_long, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__44c7_s_p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44c7_s_p1_0[] = { + 1, 5, 5, 0, 5, 5, 0, 5, 5, 5, 8, 7, 0, 9, 9, 0, + 9, 8, 5, 7, 8, 0, 9, 9, 0, 8, 9, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 5, 9, 9, 0, 8, 8, 0, 8, 8, 5, 8, 9, + 0, 8, 8, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, + 9, 9, 0, 8, 8, 0, 8, 8, 5, 8, 9, 0, 8, 8, 0, 8, + 8, +}; + +static float _vq_quantthresh__44c7_s_p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44c7_s_p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44c7_s_p1_0 = { + _vq_quantthresh__44c7_s_p1_0, + _vq_quantmap__44c7_s_p1_0, + 3, + 3 +}; + +static static_codebook _44c7_s_p1_0 = { + 4, 81, + _vq_lengthlist__44c7_s_p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44c7_s_p1_0, + NULL, + &_vq_auxt__44c7_s_p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c7_s_p2_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c7_s_p2_0[] = { + 3, 5, 5, 8, 8, 0, 5, 5, 8, 8, 0, 5, 5, 8, 8, 0, + 7, 7, 9, 9, 0, 0, 0, 9, 9, 5, 7, 7, 9, 9, 0, 8, + 8,10,10, 0, 8, 7,10, 9, 0,10,10,11,11, 0, 0, 0, + 11,11, 5, 7, 7, 9, 9, 0, 8, 8,10,10, 0, 7, 8, 9, + 10, 0,10,10,11,11, 0, 0, 0,11,11, 8, 9, 9,11,10, + 0,11,11,12,12, 0,11,10,12,12, 0,13,14,14,14, 0, + 0, 0,14,13, 8, 9, 9,10,11, 0,11,11,12,12, 0,10, + 11,12,12, 0,13,13,14,14, 0, 0, 0,13,14, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 5, 8, 7,11,10, 0, 7, 7,10,10, + 0, 7, 7,10,10, 0, 9, 9,11,10, 0, 0, 0,11,11, 5, + 7, 8,10,11, 0, 7, 7,10,10, 0, 7, 7,10,10, 0, 9, + 9,10,11, 0, 0, 0,11,11, 8,10, 9,12,12, 0,10,10, + 12,12, 0,10,10,12,12, 0,12,12,13,13, 0, 0, 0,13, + 13, 8, 9,10,12,12, 0,10,10,12,12, 0,10,10,11,12, + 0,12,12,13,13, 0, 0, 0,13,13, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 5, 8, 8,11,11, 0, 7, 7,10,10, 0, 7, 7, + 10,10, 0, 9, 9,10,11, 0, 0, 0,11,10, 5, 8, 8,10, + 11, 0, 7, 7,10,10, 0, 7, 7,10,10, 0, 9, 9,11,10, + 0, 0, 0,10,11, 9,10,10,12,12, 0,10,10,12,12, 0, + 10,10,12,12, 0,12,13,13,13, 0, 0, 0,13,12, 9,10, + 10,12,12, 0,10,10,12,12, 0,10,10,12,12, 0,13,12, + 13,13, 0, 0, 0,12,13, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 7,10,10,14,13, 0, 9, 9,12,12, 0, 9, 9,12,12, 0, + 10,10,12,12, 0, 0, 0,12,12, 7,10,10,13,14, 0, 9, + 9,12,13, 0, 9, 9,12,12, 0,10,10,12,12, 0, 0, 0, + 12,12, 9,11,11,14,13, 0,11,10,13,12, 0,11,11,13, + 13, 0,12,12,13,13, 0, 0, 0,13,13, 9,11,11,13,14, + 0,10,11,12,13, 0,11,11,13,13, 0,12,12,13,13, 0, + 0, 0,13,13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, + 11,11,14,14, 0,10,11,13,13, 0,11,10,13,13, 0,12, + 12,13,13, 0, 0, 0,13,12, 9,11,11,14,14, 0,11,10, + 13,13, 0,10,11,13,13, 0,12,12,14,13, 0, 0, 0,13, + 13, +}; + +static float _vq_quantthresh__44c7_s_p2_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c7_s_p2_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c7_s_p2_0 = { + _vq_quantthresh__44c7_s_p2_0, + _vq_quantmap__44c7_s_p2_0, + 5, + 5 +}; + +static static_codebook _44c7_s_p2_0 = { + 4, 625, + _vq_lengthlist__44c7_s_p2_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c7_s_p2_0, + NULL, + &_vq_auxt__44c7_s_p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c7_s_p3_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44c7_s_p3_0[] = { + 2, 4, 4, 5, 5, 7, 7, 9, 9, 0, 4, 4, 6, 6, 7, 7, + 9, 9, 0, 4, 4, 6, 6, 7, 7, 9, 9, 0, 5, 5, 6, 6, + 8, 8,10,10, 0, 0, 0, 6, 6, 8, 8,10,10, 0, 0, 0, + 7, 7, 9, 9,10,10, 0, 0, 0, 7, 7, 8, 8,10,10, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c7_s_p3_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44c7_s_p3_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44c7_s_p3_0 = { + _vq_quantthresh__44c7_s_p3_0, + _vq_quantmap__44c7_s_p3_0, + 9, + 9 +}; + +static static_codebook _44c7_s_p3_0 = { + 2, 81, + _vq_lengthlist__44c7_s_p3_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44c7_s_p3_0, + NULL, + &_vq_auxt__44c7_s_p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c7_s_p4_0[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44c7_s_p4_0[] = { + 3, 4, 4, 5, 5, 7, 7, 8, 8, 8, 8, 9, 9,10,10,11, + 11, 0, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9,10,10,11,11, + 12,12, 0, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9,10,10,11, + 11,12,12, 0, 5, 5, 6, 6, 8, 8, 9, 9, 9, 9,10,10, + 11,12,12,12, 0, 0, 0, 6, 6, 8, 7, 9, 9, 9, 9,10, + 10,11,11,12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9,10,10, + 11,11,12,12,13,12, 0, 0, 0, 7, 7, 8, 8, 9, 9,10, + 10,11,11,12,12,12,13, 0, 0, 0, 7, 7, 8, 8, 9, 9, + 10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 8, 8, 9, + 9,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c7_s_p4_0[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__44c7_s_p4_0[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44c7_s_p4_0 = { + _vq_quantthresh__44c7_s_p4_0, + _vq_quantmap__44c7_s_p4_0, + 17, + 17 +}; + +static static_codebook _44c7_s_p4_0 = { + 2, 289, + _vq_lengthlist__44c7_s_p4_0, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__44c7_s_p4_0, + NULL, + &_vq_auxt__44c7_s_p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c7_s_p5_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44c7_s_p5_0[] = { + 1, 4, 4, 5, 7, 7, 6, 7, 7, 4, 6, 7,10,10,10,10, + 10, 9, 4, 6, 6,10,10,10,10, 9,10, 5,10,10, 9,11, + 12,10,11,12, 7,10,10,11,12,12,12,12,12, 7,10,10, + 11,12,12,12,12,12, 6,10,10,10,12,12,11,12,12, 7, + 10,10,12,12,12,12,11,12, 7,10,10,11,12,12,12,12, + 12, +}; + +static float _vq_quantthresh__44c7_s_p5_0[] = { + -5.5, 5.5, +}; + +static long _vq_quantmap__44c7_s_p5_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44c7_s_p5_0 = { + _vq_quantthresh__44c7_s_p5_0, + _vq_quantmap__44c7_s_p5_0, + 3, + 3 +}; + +static static_codebook _44c7_s_p5_0 = { + 4, 81, + _vq_lengthlist__44c7_s_p5_0, + 1, -529137664, 1618345984, 2, 0, + _vq_quantlist__44c7_s_p5_0, + NULL, + &_vq_auxt__44c7_s_p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c7_s_p5_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44c7_s_p5_1[] = { + 3, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8,11, 4, 4, 6, 6, + 7, 7, 8, 8, 9, 9,11, 4, 4, 6, 6, 7, 7, 8, 8, 9, + 9,12, 5, 5, 6, 6, 7, 7, 9, 9, 9, 9,12,12,12, 6, + 6, 7, 7, 9, 9, 9, 9,11,11,11, 7, 7, 7, 7, 8, 8, + 9, 9,11,11,11, 7, 7, 7, 7, 8, 8, 9, 9,11,11,11, + 7, 7, 8, 8, 8, 8, 9, 9,11,11,11,11,11, 8, 8, 8, + 8, 8, 9,11,11,11,11,11, 8, 8, 8, 8, 8, 8,11,11, + 11,11,11, 7, 7, 8, 8, 8, 8, +}; + +static float _vq_quantthresh__44c7_s_p5_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__44c7_s_p5_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44c7_s_p5_1 = { + _vq_quantthresh__44c7_s_p5_1, + _vq_quantmap__44c7_s_p5_1, + 11, + 11 +}; + +static static_codebook _44c7_s_p5_1 = { + 2, 121, + _vq_lengthlist__44c7_s_p5_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__44c7_s_p5_1, + NULL, + &_vq_auxt__44c7_s_p5_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c7_s_p6_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c7_s_p6_0[] = { + 1, 4, 4, 6, 6, 7, 7, 8, 7, 9, 8,10,10, 6, 5, 5, + 7, 7, 8, 8, 9, 9, 9,10,11,11, 7, 5, 5, 7, 7, 8, + 8, 9, 9,10,10,11,11, 0, 7, 7, 7, 7, 9, 8, 9, 9, + 10,10,11,11, 0, 8, 8, 7, 7, 8, 9, 9, 9,10,10,11, + 11, 0,11,11, 9, 9,10,10,11,10,11,11,12,12, 0,12, + 12, 9, 9,10,10,11,11,11,11,12,12, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +static float _vq_quantthresh__44c7_s_p6_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__44c7_s_p6_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c7_s_p6_0 = { + _vq_quantthresh__44c7_s_p6_0, + _vq_quantmap__44c7_s_p6_0, + 13, + 13 +}; + +static static_codebook _44c7_s_p6_0 = { + 2, 169, + _vq_lengthlist__44c7_s_p6_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__44c7_s_p6_0, + NULL, + &_vq_auxt__44c7_s_p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c7_s_p6_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c7_s_p6_1[] = { + 3, 4, 4, 5, 5, 5, 4, 4, 5, 5, 5, 4, 4, 5, 5, 6, + 5, 5, 5, 5, 6, 6, 6, 5, 5, +}; + +static float _vq_quantthresh__44c7_s_p6_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c7_s_p6_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c7_s_p6_1 = { + _vq_quantthresh__44c7_s_p6_1, + _vq_quantmap__44c7_s_p6_1, + 5, + 5 +}; + +static static_codebook _44c7_s_p6_1 = { + 2, 25, + _vq_lengthlist__44c7_s_p6_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c7_s_p6_1, + NULL, + &_vq_auxt__44c7_s_p6_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c7_s_p7_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c7_s_p7_0[] = { + 1, 4, 4, 6, 6, 7, 8, 9, 9,10,10,12,11, 6, 5, 5, + 7, 7, 8, 8, 9,10,11,11,12,12, 7, 5, 5, 7, 7, 8, + 8,10,10,11,11,12,12,20, 7, 7, 7, 7, 8, 9,10,10, + 11,11,12,13,20, 7, 7, 7, 7, 9, 9,10,10,11,12,13, + 13,20,11,11, 8, 8, 9, 9,11,11,12,12,13,13,20,11, + 11, 8, 8, 9, 9,11,11,12,12,13,13,20,20,20,10,10, + 10,10,12,12,13,13,13,13,20,20,20,10,10,10,10,12, + 12,13,13,13,14,20,20,20,14,14,11,11,12,12,13,13, + 14,14,20,20,20,14,14,11,11,12,12,13,13,14,14,20, + 20,20,20,19,13,13,13,13,14,14,15,14,19,19,19,19, + 19,13,13,13,13,14,14,15,15, +}; + +static float _vq_quantthresh__44c7_s_p7_0[] = { + -60.5, -49.5, -38.5, -27.5, -16.5, -5.5, 5.5, 16.5, + 27.5, 38.5, 49.5, 60.5, +}; + +static long _vq_quantmap__44c7_s_p7_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c7_s_p7_0 = { + _vq_quantthresh__44c7_s_p7_0, + _vq_quantmap__44c7_s_p7_0, + 13, + 13 +}; + +static static_codebook _44c7_s_p7_0 = { + 2, 169, + _vq_lengthlist__44c7_s_p7_0, + 1, -523206656, 1618345984, 4, 0, + _vq_quantlist__44c7_s_p7_0, + NULL, + &_vq_auxt__44c7_s_p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c7_s_p7_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44c7_s_p7_1[] = { + 4, 5, 5, 6, 6, 7, 7, 7, 7, 7, 7, 8, 6, 6, 7, 7, + 7, 7, 7, 7, 7, 7, 8, 6, 6, 6, 7, 7, 7, 7, 7, 7, + 7, 8, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 7, + 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 7, 7, 7, 7, 7, 7, + 7, 7, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, + 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 7, 7, 7, + 7, 7, 7, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 8, 8, + 8, 8, 8, 7, 7, 7, 7, 7, 7, +}; + +static float _vq_quantthresh__44c7_s_p7_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__44c7_s_p7_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44c7_s_p7_1 = { + _vq_quantthresh__44c7_s_p7_1, + _vq_quantmap__44c7_s_p7_1, + 11, + 11 +}; + +static static_codebook _44c7_s_p7_1 = { + 2, 121, + _vq_lengthlist__44c7_s_p7_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__44c7_s_p7_1, + NULL, + &_vq_auxt__44c7_s_p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c7_s_p8_0[] = { + 7, + 6, + 8, + 5, + 9, + 4, + 10, + 3, + 11, + 2, + 12, + 1, + 13, + 0, + 14, +}; + +static long _vq_lengthlist__44c7_s_p8_0[] = { + 1, 4, 4, 7, 7, 8, 8, 8, 7, 9, 8, 9, 9,10,10, 6, + 5, 5, 7, 7, 9, 9, 8, 8,10, 9,11,10,12,11, 6, 5, + 5, 8, 7, 9, 9, 8, 8,10,10,11,11,12,11,19, 8, 8, + 8, 8,10,10, 9, 9,10,10,11,11,12,11,19, 8, 8, 8, + 8,10,10, 9, 9,10,10,11,11,12,12,19,12,12, 9, 9, + 10,10, 9,10,10,10,11,11,12,12,19,12,12, 9, 9,10, + 10,10,10,10,10,12,12,12,12,19,19,19, 9, 9, 9, 9, + 11,10,11,11,12,11,13,13,19,19,19, 9, 9, 9, 9,11, + 10,11,11,11,12,13,13,19,19,19,13,13,10,10,11,11, + 12,12,12,12,13,12,19,19,19,14,13,10,10,11,11,12, + 12,12,13,13,13,19,19,19,19,19,12,12,12,11,12,13, + 14,13,13,13,19,19,19,19,19,12,12,12,11,12,12,13, + 14,13,14,19,19,19,19,19,16,16,12,13,12,13,13,14, + 15,14,19,18,18,18,18,16,15,12,11,12,11,14,12,14, + 14, +}; + +static float _vq_quantthresh__44c7_s_p8_0[] = { + -136.5, -115.5, -94.5, -73.5, -52.5, -31.5, -10.5, 10.5, + 31.5, 52.5, 73.5, 94.5, 115.5, 136.5, +}; + +static long _vq_quantmap__44c7_s_p8_0[] = { + 13, 11, 9, 7, 5, 3, 1, 0, + 2, 4, 6, 8, 10, 12, 14, +}; + +static encode_aux_threshmatch _vq_auxt__44c7_s_p8_0 = { + _vq_quantthresh__44c7_s_p8_0, + _vq_quantmap__44c7_s_p8_0, + 15, + 15 +}; + +static static_codebook _44c7_s_p8_0 = { + 2, 225, + _vq_lengthlist__44c7_s_p8_0, + 1, -520986624, 1620377600, 4, 0, + _vq_quantlist__44c7_s_p8_0, + NULL, + &_vq_auxt__44c7_s_p8_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c7_s_p8_1[] = { + 10, + 9, + 11, + 8, + 12, + 7, + 13, + 6, + 14, + 5, + 15, + 4, + 16, + 3, + 17, + 2, + 18, + 1, + 19, + 0, + 20, +}; + +static long _vq_lengthlist__44c7_s_p8_1[] = { + 3, 5, 5, 7, 6, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8,10, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10, 6, 6, 7, 7, 8, + 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10, + 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9,10,10,10, 8, 8, 8, 8, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10,10, 8, 8, 8, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10, + 10, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9,10,10,10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9,10,11,10,10,10, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9,10, 9, 9,10, 9, 9,10,11,10, + 11,10, 9, 9, 9, 9, 9, 9, 9,10,10,10, 9,10, 9, 9, + 9, 9,11,10,11,10,10, 9, 9, 9, 9, 9, 9,10, 9, 9, + 10, 9, 9,10, 9, 9,10,11,10,10,11,10, 9, 9, 9, 9, + 9,10,10, 9,10,10,10,10, 9,10,10,10,10,10,10,11, + 11,11,10, 9, 9, 9,10,10,10,10,10,10,10,10,10,10, + 10,10,10,11,11,10,10,10,10,10,10,10,10,10,10,10, + 10, 9,10,10, 9,10,11,11,10,11,10,11,10, 9,10,10, + 9,10,10,10,10,10,10,10,10,10,10,11,11,11,11,10, + 11,11,10,10,10,10,10,10, 9,10, 9,10,10, 9,10, 9, + 10,10,10,11,10,11,10,11,11,10,10,10,10,10,10, 9, + 10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,11,10,11, + 11,10,10,10,10, 9, 9,10,10, 9, 9,10, 9,10,10,10, + 10,11,11,10,10,10,10,10,10,10, 9, 9,10,10,10, 9, + 9,10,10,10,10,10,11,10,11,10,10,10,10,10,10, 9, + 10,10,10,10,10,10,10,10,10, +}; + +static float _vq_quantthresh__44c7_s_p8_1[] = { + -9.5, -8.5, -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, + -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, + 6.5, 7.5, 8.5, 9.5, +}; + +static long _vq_quantmap__44c7_s_p8_1[] = { + 19, 17, 15, 13, 11, 9, 7, 5, + 3, 1, 0, 2, 4, 6, 8, 10, + 12, 14, 16, 18, 20, +}; + +static encode_aux_threshmatch _vq_auxt__44c7_s_p8_1 = { + _vq_quantthresh__44c7_s_p8_1, + _vq_quantmap__44c7_s_p8_1, + 21, + 21 +}; + +static static_codebook _44c7_s_p8_1 = { + 2, 441, + _vq_lengthlist__44c7_s_p8_1, + 1, -529268736, 1611661312, 5, 0, + _vq_quantlist__44c7_s_p8_1, + NULL, + &_vq_auxt__44c7_s_p8_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c7_s_p9_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c7_s_p9_0[] = { + 1, 3, 3,11,11,11,11,11,11,11,11,11,11, 4, 6, 6, + 11,11,11,11,11,11,11,11,11,11, 4, 7, 7,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11, +}; + +static float _vq_quantthresh__44c7_s_p9_0[] = { + -3503.5, -2866.5, -2229.5, -1592.5, -955.5, -318.5, 318.5, 955.5, + 1592.5, 2229.5, 2866.5, 3503.5, +}; + +static long _vq_quantmap__44c7_s_p9_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c7_s_p9_0 = { + _vq_quantthresh__44c7_s_p9_0, + _vq_quantmap__44c7_s_p9_0, + 13, + 13 +}; + +static static_codebook _44c7_s_p9_0 = { + 2, 169, + _vq_lengthlist__44c7_s_p9_0, + 1, -511845376, 1630791680, 4, 0, + _vq_quantlist__44c7_s_p9_0, + NULL, + &_vq_auxt__44c7_s_p9_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c7_s_p9_1[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c7_s_p9_1[] = { + 1, 4, 4, 7, 7, 7, 7, 7, 6, 8, 8, 8, 8, 6, 6, 6, + 8, 8, 9, 8, 8, 7, 9, 8,11,10, 5, 6, 6, 8, 8, 9, + 8, 8, 8,10, 9,11,11,16, 8, 8, 9, 8, 9, 9, 9, 8, + 10, 9,11,10,16, 8, 8, 9, 9,10,10, 9, 9,10,10,11, + 11,16,13,13, 9, 9,10,10, 9,10,11,11,12,11,16,13, + 13, 9, 8,10, 9,10,10,10,10,11,11,16,14,16, 8, 9, + 9, 9,11,10,11,11,12,11,16,16,16, 9, 7,10, 7,11, + 10,11,11,12,11,16,16,16,12,12, 9,10,11,11,12,11, + 12,12,16,16,16,12,10,10, 7,11, 8,12,11,12,12,16, + 16,15,16,16,11,12,10,10,12,11,12,12,16,16,16,15, + 15,11,11,10,10,12,12,12,12, +}; + +static float _vq_quantthresh__44c7_s_p9_1[] = { + -269.5, -220.5, -171.5, -122.5, -73.5, -24.5, 24.5, 73.5, + 122.5, 171.5, 220.5, 269.5, +}; + +static long _vq_quantmap__44c7_s_p9_1[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c7_s_p9_1 = { + _vq_quantthresh__44c7_s_p9_1, + _vq_quantmap__44c7_s_p9_1, + 13, + 13 +}; + +static static_codebook _44c7_s_p9_1 = { + 2, 169, + _vq_lengthlist__44c7_s_p9_1, + 1, -518889472, 1622704128, 4, 0, + _vq_quantlist__44c7_s_p9_1, + NULL, + &_vq_auxt__44c7_s_p9_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c7_s_p9_2[] = { + 24, + 23, + 25, + 22, + 26, + 21, + 27, + 20, + 28, + 19, + 29, + 18, + 30, + 17, + 31, + 16, + 32, + 15, + 33, + 14, + 34, + 13, + 35, + 12, + 36, + 11, + 37, + 10, + 38, + 9, + 39, + 8, + 40, + 7, + 41, + 6, + 42, + 5, + 43, + 4, + 44, + 3, + 45, + 2, + 46, + 1, + 47, + 0, + 48, +}; + +static long _vq_lengthlist__44c7_s_p9_2[] = { + 2, 4, 3, 4, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, +}; + +static float _vq_quantthresh__44c7_s_p9_2[] = { + -23.5, -22.5, -21.5, -20.5, -19.5, -18.5, -17.5, -16.5, + -15.5, -14.5, -13.5, -12.5, -11.5, -10.5, -9.5, -8.5, + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, + 8.5, 9.5, 10.5, 11.5, 12.5, 13.5, 14.5, 15.5, + 16.5, 17.5, 18.5, 19.5, 20.5, 21.5, 22.5, 23.5, +}; + +static long _vq_quantmap__44c7_s_p9_2[] = { + 47, 45, 43, 41, 39, 37, 35, 33, + 31, 29, 27, 25, 23, 21, 19, 17, + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, 18, 20, 22, 24, 26, 28, 30, + 32, 34, 36, 38, 40, 42, 44, 46, + 48, +}; + +static encode_aux_threshmatch _vq_auxt__44c7_s_p9_2 = { + _vq_quantthresh__44c7_s_p9_2, + _vq_quantmap__44c7_s_p9_2, + 49, + 49 +}; + +static static_codebook _44c7_s_p9_2 = { + 1, 49, + _vq_lengthlist__44c7_s_p9_2, + 1, -526909440, 1611661312, 6, 0, + _vq_quantlist__44c7_s_p9_2, + NULL, + &_vq_auxt__44c7_s_p9_2, + NULL, + 0 +}; + +static long _huff_lengthlist__44c7_s_short[] = { + 4,11,12,14,15,15,17,17,18,18, 5, 6, 6, 8, 9,10, + 13,17,18,19, 7, 5, 4, 6, 8, 9,11,15,19,19, 8, 6, + 5, 5, 6, 7,11,14,16,17, 9, 7, 7, 6, 7, 7,10,13, + 15,19,10, 8, 7, 6, 7, 6, 7, 9,14,16,12,10, 9, 7, + 7, 6, 4, 5,10,15,14,13,11, 7, 6, 6, 4, 2, 7,13, + 16,16,15, 9, 8, 8, 8, 6, 9,13,19,19,17,12,11,10, + 10, 9,11,14, +}; + +static static_codebook _huff_book__44c7_s_short = { + 2, 100, + _huff_lengthlist__44c7_s_short, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__44c8_s_long[] = { + 3, 8,12,13,14,14,14,13,14,14, 6, 4, 5, 8,10,10, + 11,11,14,13, 9, 5, 4, 5, 7, 8, 9,10,13,13,12, 7, + 5, 4, 5, 6, 8, 9,12,13,13, 9, 6, 5, 5, 5, 7, 9, + 11,14,12,10, 7, 6, 5, 4, 6, 7,10,11,12,11, 9, 8, + 7, 5, 5, 6,10,10,13,12,10, 9, 8, 6, 6, 5, 8,10, + 14,13,12,12,11,10, 9, 7, 8,10,12,13,14,14,13,12, + 11, 9, 9,10, +}; + +static static_codebook _huff_book__44c8_s_long = { + 2, 100, + _huff_lengthlist__44c8_s_long, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__44c8_s_p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44c8_s_p1_0[] = { + 1, 5, 5, 0, 5, 5, 0, 5, 5, 5, 7, 7, 0, 9, 8, 0, + 9, 8, 6, 7, 7, 0, 8, 9, 0, 8, 9, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 5, 9, 8, 0, 8, 8, 0, 8, 8, 5, 8, 9, + 0, 8, 8, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, + 9, 8, 0, 8, 8, 0, 8, 8, 5, 8, 9, 0, 8, 8, 0, 8, + 8, +}; + +static float _vq_quantthresh__44c8_s_p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44c8_s_p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44c8_s_p1_0 = { + _vq_quantthresh__44c8_s_p1_0, + _vq_quantmap__44c8_s_p1_0, + 3, + 3 +}; + +static static_codebook _44c8_s_p1_0 = { + 4, 81, + _vq_lengthlist__44c8_s_p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44c8_s_p1_0, + NULL, + &_vq_auxt__44c8_s_p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c8_s_p2_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c8_s_p2_0[] = { + 3, 5, 5, 8, 8, 0, 5, 5, 8, 8, 0, 5, 5, 8, 8, 0, + 7, 7, 9, 9, 0, 0, 0, 9, 9, 5, 7, 7, 9, 9, 0, 8, + 7,10, 9, 0, 8, 7,10, 9, 0,10,10,11,11, 0, 0, 0, + 11,11, 5, 7, 7, 9, 9, 0, 7, 8, 9,10, 0, 7, 8, 9, + 10, 0,10,10,11,11, 0, 0, 0,11,11, 8, 9, 9,11,10, + 0,11,10,12,11, 0,11,10,12,12, 0,13,13,14,14, 0, + 0, 0,14,13, 8, 9, 9,10,11, 0,10,11,12,12, 0,10, + 11,12,12, 0,13,13,14,14, 0, 0, 0,13,14, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 5, 8, 7,11,10, 0, 7, 7,10,10, + 0, 7, 7,10,10, 0, 9, 9,10,10, 0, 0, 0,11,10, 5, + 7, 8,10,11, 0, 7, 7,10,10, 0, 7, 7,10,10, 0, 9, + 9,10,10, 0, 0, 0,10,10, 8,10, 9,12,12, 0,10,10, + 12,11, 0,10,10,12,12, 0,12,12,13,12, 0, 0, 0,13, + 12, 8, 9,10,12,12, 0,10,10,11,12, 0,10,10,11,12, + 0,12,12,13,13, 0, 0, 0,12,13, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 6, 8, 7,11,10, 0, 7, 7,10,10, 0, 7, 7, + 10,10, 0, 9, 9,10,11, 0, 0, 0,10,10, 6, 7, 8,10, + 11, 0, 7, 7,10,10, 0, 7, 7,10,10, 0, 9, 9,10,10, + 0, 0, 0,10,10, 9,10, 9,12,12, 0,10,10,12,12, 0, + 10,10,12,11, 0,12,12,13,13, 0, 0, 0,13,12, 8, 9, + 10,12,12, 0,10,10,12,12, 0,10,10,11,12, 0,12,12, + 13,13, 0, 0, 0,12,13, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 7,10,10,13,13, 0, 9, 9,12,12, 0, 9, 9,12,12, 0, + 10,10,12,12, 0, 0, 0,12,12, 7,10,10,13,13, 0, 9, + 9,12,12, 0, 9, 9,12,12, 0,10,10,12,12, 0, 0, 0, + 12,12, 9,11,11,14,13, 0,10,10,13,12, 0,11,10,13, + 12, 0,12,12,13,12, 0, 0, 0,13,13, 9,11,11,13,14, + 0,10,11,12,13, 0,10,11,13,13, 0,12,12,12,13, 0, + 0, 0,13,13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, + 11,11,14,14, 0,10,11,13,13, 0,11,10,13,13, 0,11, + 12,13,13, 0, 0, 0,13,12, 9,11,11,14,14, 0,11,10, + 13,13, 0,10,11,13,13, 0,12,12,13,13, 0, 0, 0,12, + 13, +}; + +static float _vq_quantthresh__44c8_s_p2_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c8_s_p2_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c8_s_p2_0 = { + _vq_quantthresh__44c8_s_p2_0, + _vq_quantmap__44c8_s_p2_0, + 5, + 5 +}; + +static static_codebook _44c8_s_p2_0 = { + 4, 625, + _vq_lengthlist__44c8_s_p2_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c8_s_p2_0, + NULL, + &_vq_auxt__44c8_s_p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c8_s_p3_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44c8_s_p3_0[] = { + 2, 4, 4, 5, 5, 7, 7, 9, 9, 0, 4, 4, 6, 6, 7, 7, + 9, 9, 0, 4, 4, 6, 6, 7, 7, 9, 9, 0, 5, 5, 6, 6, + 8, 8,10,10, 0, 0, 0, 6, 6, 8, 8,10,10, 0, 0, 0, + 7, 7, 9, 9,10,10, 0, 0, 0, 7, 7, 8, 8,10,10, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c8_s_p3_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44c8_s_p3_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44c8_s_p3_0 = { + _vq_quantthresh__44c8_s_p3_0, + _vq_quantmap__44c8_s_p3_0, + 9, + 9 +}; + +static static_codebook _44c8_s_p3_0 = { + 2, 81, + _vq_lengthlist__44c8_s_p3_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44c8_s_p3_0, + NULL, + &_vq_auxt__44c8_s_p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c8_s_p4_0[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44c8_s_p4_0[] = { + 3, 4, 4, 5, 5, 7, 7, 8, 8, 8, 8, 9, 9,10,10,11, + 11, 0, 4, 4, 6, 6, 7, 7, 8, 8, 9, 8,10,10,11,11, + 11,11, 0, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9,10,10,11, + 11,11,11, 0, 6, 5, 6, 6, 7, 7, 9, 9, 9, 9,10,10, + 11,11,12,12, 0, 0, 0, 6, 6, 7, 7, 9, 9, 9, 9,10, + 10,11,11,12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9,10,10, + 11,11,11,12,12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9,10, + 10,11,11,11,12,12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9, + 10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 8, 8, 9, + 9,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c8_s_p4_0[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__44c8_s_p4_0[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44c8_s_p4_0 = { + _vq_quantthresh__44c8_s_p4_0, + _vq_quantmap__44c8_s_p4_0, + 17, + 17 +}; + +static static_codebook _44c8_s_p4_0 = { + 2, 289, + _vq_lengthlist__44c8_s_p4_0, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__44c8_s_p4_0, + NULL, + &_vq_auxt__44c8_s_p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c8_s_p5_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44c8_s_p5_0[] = { + 1, 4, 4, 5, 7, 7, 6, 7, 7, 4, 7, 6,10,10,10,10, + 10,10, 4, 6, 6,10,10,10,10, 9,10, 5,10,10, 9,11, + 11,10,11,11, 7,10,10,11,12,12,12,12,12, 7,10,10, + 11,12,12,12,12,12, 6,10,10,10,12,12,10,12,12, 7, + 10,10,11,12,12,12,12,12, 7,10,10,11,12,12,12,12, + 12, +}; + +static float _vq_quantthresh__44c8_s_p5_0[] = { + -5.5, 5.5, +}; + +static long _vq_quantmap__44c8_s_p5_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44c8_s_p5_0 = { + _vq_quantthresh__44c8_s_p5_0, + _vq_quantmap__44c8_s_p5_0, + 3, + 3 +}; + +static static_codebook _44c8_s_p5_0 = { + 4, 81, + _vq_lengthlist__44c8_s_p5_0, + 1, -529137664, 1618345984, 2, 0, + _vq_quantlist__44c8_s_p5_0, + NULL, + &_vq_auxt__44c8_s_p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c8_s_p5_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44c8_s_p5_1[] = { + 3, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8,11, 4, 5, 6, 6, + 7, 7, 8, 8, 8, 8,11, 5, 5, 6, 6, 7, 7, 8, 8, 8, + 9,12, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,12,12,12, 6, + 6, 7, 7, 8, 8, 9, 9,11,11,11, 6, 6, 7, 7, 8, 8, + 8, 8,11,11,11, 6, 6, 7, 7, 8, 8, 8, 8,11,11,11, + 7, 7, 7, 8, 8, 8, 8, 8,11,11,11,11,11, 7, 7, 8, + 8, 8, 8,11,11,11,11,11, 7, 7, 7, 7, 8, 8,11,11, + 11,11,11, 7, 7, 7, 7, 8, 8, +}; + +static float _vq_quantthresh__44c8_s_p5_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__44c8_s_p5_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44c8_s_p5_1 = { + _vq_quantthresh__44c8_s_p5_1, + _vq_quantmap__44c8_s_p5_1, + 11, + 11 +}; + +static static_codebook _44c8_s_p5_1 = { + 2, 121, + _vq_lengthlist__44c8_s_p5_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__44c8_s_p5_1, + NULL, + &_vq_auxt__44c8_s_p5_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c8_s_p6_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c8_s_p6_0[] = { + 1, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9,10,10, 6, 5, 5, + 7, 7, 8, 8, 9, 9,10,10,11,11, 6, 5, 5, 7, 7, 8, + 8, 9, 9,10,10,11,11, 0, 7, 7, 7, 7, 9, 9,10,10, + 10,10,11,11, 0, 7, 7, 7, 7, 9, 9,10,10,10,10,11, + 11, 0,11,11, 9, 9,10,10,11,11,11,11,12,12, 0,12, + 12, 9, 9,10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +static float _vq_quantthresh__44c8_s_p6_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__44c8_s_p6_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c8_s_p6_0 = { + _vq_quantthresh__44c8_s_p6_0, + _vq_quantmap__44c8_s_p6_0, + 13, + 13 +}; + +static static_codebook _44c8_s_p6_0 = { + 2, 169, + _vq_lengthlist__44c8_s_p6_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__44c8_s_p6_0, + NULL, + &_vq_auxt__44c8_s_p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c8_s_p6_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c8_s_p6_1[] = { + 3, 4, 4, 5, 5, 5, 4, 4, 5, 5, 5, 4, 4, 5, 5, 6, + 5, 5, 5, 5, 6, 6, 6, 5, 5, +}; + +static float _vq_quantthresh__44c8_s_p6_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c8_s_p6_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c8_s_p6_1 = { + _vq_quantthresh__44c8_s_p6_1, + _vq_quantmap__44c8_s_p6_1, + 5, + 5 +}; + +static static_codebook _44c8_s_p6_1 = { + 2, 25, + _vq_lengthlist__44c8_s_p6_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c8_s_p6_1, + NULL, + &_vq_auxt__44c8_s_p6_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c8_s_p7_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c8_s_p7_0[] = { + 1, 4, 4, 6, 6, 8, 7, 9, 9,10,10,12,12, 6, 5, 5, + 7, 7, 8, 8,10,10,11,11,12,12, 7, 5, 5, 7, 7, 8, + 8,10,10,11,11,12,12,21, 7, 7, 7, 7, 8, 9,10,10, + 11,11,12,12,21, 7, 7, 7, 7, 9, 9,10,10,12,12,13, + 13,21,11,11, 8, 8, 9, 9,11,11,12,12,13,13,21,11, + 11, 8, 8, 9, 9,11,11,12,12,13,13,21,21,21,10,10, + 10,10,11,11,12,13,13,13,21,21,21,10,10,10,10,11, + 11,13,13,14,13,21,21,21,13,13,11,11,12,12,13,13, + 14,14,21,21,21,14,14,11,11,12,12,13,13,14,14,21, + 21,21,21,20,13,13,13,12,14,14,16,15,20,20,20,20, + 20,13,13,13,13,14,13,15,15, +}; + +static float _vq_quantthresh__44c8_s_p7_0[] = { + -60.5, -49.5, -38.5, -27.5, -16.5, -5.5, 5.5, 16.5, + 27.5, 38.5, 49.5, 60.5, +}; + +static long _vq_quantmap__44c8_s_p7_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c8_s_p7_0 = { + _vq_quantthresh__44c8_s_p7_0, + _vq_quantmap__44c8_s_p7_0, + 13, + 13 +}; + +static static_codebook _44c8_s_p7_0 = { + 2, 169, + _vq_lengthlist__44c8_s_p7_0, + 1, -523206656, 1618345984, 4, 0, + _vq_quantlist__44c8_s_p7_0, + NULL, + &_vq_auxt__44c8_s_p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c8_s_p7_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44c8_s_p7_1[] = { + 4, 5, 6, 6, 6, 7, 7, 7, 7, 7, 7, 8, 6, 6, 6, 7, + 7, 7, 7, 7, 7, 7, 8, 6, 6, 6, 6, 7, 7, 7, 7, 7, + 7, 8, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 7, + 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 7, 7, 7, 7, 7, 7, + 7, 7, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, + 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 7, 7, 7, + 7, 7, 7, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 8, 8, + 8, 8, 8, 7, 7, 7, 7, 7, 7, +}; + +static float _vq_quantthresh__44c8_s_p7_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__44c8_s_p7_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44c8_s_p7_1 = { + _vq_quantthresh__44c8_s_p7_1, + _vq_quantmap__44c8_s_p7_1, + 11, + 11 +}; + +static static_codebook _44c8_s_p7_1 = { + 2, 121, + _vq_lengthlist__44c8_s_p7_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__44c8_s_p7_1, + NULL, + &_vq_auxt__44c8_s_p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c8_s_p8_0[] = { + 7, + 6, + 8, + 5, + 9, + 4, + 10, + 3, + 11, + 2, + 12, + 1, + 13, + 0, + 14, +}; + +static long _vq_lengthlist__44c8_s_p8_0[] = { + 1, 4, 4, 7, 6, 8, 8, 8, 7, 9, 8,10,10,11,10, 6, + 5, 5, 7, 7, 9, 9, 8, 8,10,10,11,11,12,11, 6, 5, + 5, 7, 7, 9, 9, 9, 9,10,10,11,11,12,12,20, 8, 8, + 8, 8, 9, 9, 9, 9,10,10,11,11,12,12,20, 8, 8, 8, + 8,10, 9, 9, 9,10,10,11,11,12,12,20,12,12, 9, 9, + 10,10,10,10,10,11,12,12,12,12,20,12,12, 9, 9,10, + 10,10,10,11,11,12,12,13,13,20,20,20, 9, 9, 9, 9, + 11,10,11,11,12,12,12,13,20,19,19, 9, 9, 9, 9,11, + 11,11,12,12,12,13,13,19,19,19,13,13,10,10,11,11, + 12,12,13,13,13,13,19,19,19,14,13,11,10,11,11,12, + 12,12,13,13,13,19,19,19,19,19,12,12,12,12,13,13, + 13,13,14,13,19,19,19,19,19,12,12,12,11,12,12,13, + 14,14,14,19,19,19,19,19,16,15,13,12,13,13,13,14, + 14,14,19,19,19,19,19,17,17,13,12,13,11,14,13,15, + 15, +}; + +static float _vq_quantthresh__44c8_s_p8_0[] = { + -136.5, -115.5, -94.5, -73.5, -52.5, -31.5, -10.5, 10.5, + 31.5, 52.5, 73.5, 94.5, 115.5, 136.5, +}; + +static long _vq_quantmap__44c8_s_p8_0[] = { + 13, 11, 9, 7, 5, 3, 1, 0, + 2, 4, 6, 8, 10, 12, 14, +}; + +static encode_aux_threshmatch _vq_auxt__44c8_s_p8_0 = { + _vq_quantthresh__44c8_s_p8_0, + _vq_quantmap__44c8_s_p8_0, + 15, + 15 +}; + +static static_codebook _44c8_s_p8_0 = { + 2, 225, + _vq_lengthlist__44c8_s_p8_0, + 1, -520986624, 1620377600, 4, 0, + _vq_quantlist__44c8_s_p8_0, + NULL, + &_vq_auxt__44c8_s_p8_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c8_s_p8_1[] = { + 10, + 9, + 11, + 8, + 12, + 7, + 13, + 6, + 14, + 5, + 15, + 4, + 16, + 3, + 17, + 2, + 18, + 1, + 19, + 0, + 20, +}; + +static long _vq_lengthlist__44c8_s_p8_1[] = { + 4, 5, 5, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8,10, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10, 6, 6, 7, 7, 8, + 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10, + 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9,10,10,10, 8, 8, 8, 8, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10,10, 8, 8, 8, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10, + 10, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9,10,10,10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9,10,10,10,10,10, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10,10, + 10,10, 9, 9, 9, 9, 9, 9, 9, 9,10, 9, 9, 9, 9, 9, + 9, 9,10,10,10,10,10, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9,10,10,10,10,10, 9, 9, 9, 9, + 9, 9, 9, 9,10,10,10, 9, 9, 9, 9, 9,10,10,10,10, + 10,10,10, 9, 9, 9, 9, 9,10,10,10, 9, 9, 9, 9, 9, + 9,10,10,10,10,10,10,10, 9,10,10, 9,10,10,10,10, + 9,10, 9,10,10, 9,10,10,10,10,10,10,10, 9,10,10, + 10,10,10,10, 9, 9,10,10, 9,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, 9, 9, 9,10, 9, 9, 9, 9, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10, 9, 9, + 10, 9,10, 9,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10, 9, 9,10, 9, 9, 9,10,10,10,10,10,10, + 10,10,10,10,10, 9, 9, 9, 9, 9, 9,10, 9, 9,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10, 9,10, 9, + 9,10, 9, 9,10,10,10,10,10,10,10,10,10,10,10,10, + 10, 9, 9,10,10, 9,10, 9, 9, +}; + +static float _vq_quantthresh__44c8_s_p8_1[] = { + -9.5, -8.5, -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, + -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, + 6.5, 7.5, 8.5, 9.5, +}; + +static long _vq_quantmap__44c8_s_p8_1[] = { + 19, 17, 15, 13, 11, 9, 7, 5, + 3, 1, 0, 2, 4, 6, 8, 10, + 12, 14, 16, 18, 20, +}; + +static encode_aux_threshmatch _vq_auxt__44c8_s_p8_1 = { + _vq_quantthresh__44c8_s_p8_1, + _vq_quantmap__44c8_s_p8_1, + 21, + 21 +}; + +static static_codebook _44c8_s_p8_1 = { + 2, 441, + _vq_lengthlist__44c8_s_p8_1, + 1, -529268736, 1611661312, 5, 0, + _vq_quantlist__44c8_s_p8_1, + NULL, + &_vq_auxt__44c8_s_p8_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c8_s_p9_0[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44c8_s_p9_0[] = { + 1, 4, 3,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11, 4, 7, 7,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11, 4, 8,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10, +}; + +static float _vq_quantthresh__44c8_s_p9_0[] = { + -6982.5, -6051.5, -5120.5, -4189.5, -3258.5, -2327.5, -1396.5, -465.5, + 465.5, 1396.5, 2327.5, 3258.5, 4189.5, 5120.5, 6051.5, 6982.5, +}; + +static long _vq_quantmap__44c8_s_p9_0[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44c8_s_p9_0 = { + _vq_quantthresh__44c8_s_p9_0, + _vq_quantmap__44c8_s_p9_0, + 17, + 17 +}; + +static static_codebook _44c8_s_p9_0 = { + 2, 289, + _vq_lengthlist__44c8_s_p9_0, + 1, -509798400, 1631393792, 5, 0, + _vq_quantlist__44c8_s_p9_0, + NULL, + &_vq_auxt__44c8_s_p9_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c8_s_p9_1[] = { + 9, + 8, + 10, + 7, + 11, + 6, + 12, + 5, + 13, + 4, + 14, + 3, + 15, + 2, + 16, + 1, + 17, + 0, + 18, +}; + +static long _vq_lengthlist__44c8_s_p9_1[] = { + 1, 4, 4, 7, 6, 7, 7, 7, 7, 8, 8, 9, 9,10,10,10, + 10,11,11, 6, 6, 6, 8, 8, 9, 8, 8, 7,10, 8,11,10, + 12,11,12,12,13,13, 5, 5, 6, 8, 8, 9, 9, 8, 8,10, + 9,11,11,12,12,13,13,13,13,17, 8, 8, 9, 9, 9, 9, + 9, 9,10, 9,12,10,12,12,13,12,13,13,17, 9, 8, 9, + 9, 9, 9, 9, 9,10,10,12,12,12,12,13,13,13,13,17, + 13,13, 9, 9,10,10,10,10,11,11,12,11,13,12,13,13, + 14,15,17,13,13, 9, 8,10, 9,10,10,11,11,12,12,14, + 13,15,13,14,15,17,17,17, 9,10, 9,10,11,11,12,12, + 12,12,13,13,14,14,15,15,17,17,17, 9, 8, 9, 8,11, + 11,12,12,12,12,14,13,14,14,14,15,17,17,17,12,14, + 9,10,11,11,12,12,14,13,13,14,15,13,15,15,17,17, + 17,13,11,10, 8,11, 9,13,12,13,13,13,13,13,14,14, + 14,17,17,17,17,17,11,12,11,11,13,13,14,13,15,14, + 13,15,16,15,17,17,17,17,17,11,11,12, 8,13,12,14, + 13,17,14,15,14,15,14,17,17,17,17,17,15,15,12,12, + 12,12,13,14,14,14,15,14,17,14,17,17,17,17,17,16, + 17,12,12,13,12,13,13,14,14,14,14,14,14,17,17,17, + 17,17,17,17,14,14,13,12,13,13,15,15,14,13,15,17, + 17,17,17,17,17,17,17,13,14,13,13,13,13,14,15,15, + 15,14,15,17,17,17,17,17,17,17,16,15,13,14,13,13, + 14,14,15,14,14,16,17,17,17,17,17,17,17,16,16,13, + 14,13,13,14,14,15,14,15,14, +}; + +static float _vq_quantthresh__44c8_s_p9_1[] = { + -416.5, -367.5, -318.5, -269.5, -220.5, -171.5, -122.5, -73.5, + -24.5, 24.5, 73.5, 122.5, 171.5, 220.5, 269.5, 318.5, + 367.5, 416.5, +}; + +static long _vq_quantmap__44c8_s_p9_1[] = { + 17, 15, 13, 11, 9, 7, 5, 3, + 1, 0, 2, 4, 6, 8, 10, 12, + 14, 16, 18, +}; + +static encode_aux_threshmatch _vq_auxt__44c8_s_p9_1 = { + _vq_quantthresh__44c8_s_p9_1, + _vq_quantmap__44c8_s_p9_1, + 19, + 19 +}; + +static static_codebook _44c8_s_p9_1 = { + 2, 361, + _vq_lengthlist__44c8_s_p9_1, + 1, -518287360, 1622704128, 5, 0, + _vq_quantlist__44c8_s_p9_1, + NULL, + &_vq_auxt__44c8_s_p9_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c8_s_p9_2[] = { + 24, + 23, + 25, + 22, + 26, + 21, + 27, + 20, + 28, + 19, + 29, + 18, + 30, + 17, + 31, + 16, + 32, + 15, + 33, + 14, + 34, + 13, + 35, + 12, + 36, + 11, + 37, + 10, + 38, + 9, + 39, + 8, + 40, + 7, + 41, + 6, + 42, + 5, + 43, + 4, + 44, + 3, + 45, + 2, + 46, + 1, + 47, + 0, + 48, +}; + +static long _vq_lengthlist__44c8_s_p9_2[] = { + 2, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, +}; + +static float _vq_quantthresh__44c8_s_p9_2[] = { + -23.5, -22.5, -21.5, -20.5, -19.5, -18.5, -17.5, -16.5, + -15.5, -14.5, -13.5, -12.5, -11.5, -10.5, -9.5, -8.5, + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, + 8.5, 9.5, 10.5, 11.5, 12.5, 13.5, 14.5, 15.5, + 16.5, 17.5, 18.5, 19.5, 20.5, 21.5, 22.5, 23.5, +}; + +static long _vq_quantmap__44c8_s_p9_2[] = { + 47, 45, 43, 41, 39, 37, 35, 33, + 31, 29, 27, 25, 23, 21, 19, 17, + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, 18, 20, 22, 24, 26, 28, 30, + 32, 34, 36, 38, 40, 42, 44, 46, + 48, +}; + +static encode_aux_threshmatch _vq_auxt__44c8_s_p9_2 = { + _vq_quantthresh__44c8_s_p9_2, + _vq_quantmap__44c8_s_p9_2, + 49, + 49 +}; + +static static_codebook _44c8_s_p9_2 = { + 1, 49, + _vq_lengthlist__44c8_s_p9_2, + 1, -526909440, 1611661312, 6, 0, + _vq_quantlist__44c8_s_p9_2, + NULL, + &_vq_auxt__44c8_s_p9_2, + NULL, + 0 +}; + +static long _huff_lengthlist__44c8_s_short[] = { + 4,11,13,14,15,15,18,17,19,17, 5, 6, 8, 9,10,10, + 12,15,19,19, 6, 6, 6, 6, 8, 8,11,14,18,19, 8, 6, + 5, 4, 6, 7,10,13,16,17, 9, 7, 6, 5, 6, 7, 9,12, + 15,19,10, 8, 7, 6, 6, 6, 7, 9,13,15,12,10, 9, 8, + 7, 6, 4, 5,10,15,13,13,11, 8, 6, 6, 4, 2, 7,12, + 17,15,16,10, 8, 8, 7, 6, 9,12,19,18,17,13,11,10, + 10, 9,11,14, +}; + +static static_codebook _huff_book__44c8_s_short = { + 2, 100, + _huff_lengthlist__44c8_s_short, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__44c9_s_long[] = { + 3, 8,12,14,15,15,15,13,15,15, 6, 5, 8,10,12,12, + 13,12,14,13,10, 6, 5, 6, 8, 9,11,11,13,13,13, 8, + 5, 4, 5, 6, 8,10,11,13,14,10, 7, 5, 4, 5, 7, 9, + 11,12,13,11, 8, 6, 5, 4, 5, 7, 9,11,12,11,10, 8, + 7, 5, 4, 5, 9,10,13,13,11,10, 8, 6, 5, 4, 7, 9, + 15,14,13,12,10, 9, 8, 7, 8, 9,12,12,14,13,12,11, + 10, 9, 8, 9, +}; + +static static_codebook _huff_book__44c9_s_long = { + 2, 100, + _huff_lengthlist__44c9_s_long, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__44c9_s_p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44c9_s_p1_0[] = { + 1, 5, 5, 0, 5, 5, 0, 5, 5, 6, 8, 8, 0, 9, 8, 0, + 9, 8, 6, 8, 8, 0, 8, 9, 0, 8, 9, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 5, 8, 8, 0, 7, 7, 0, 8, 8, 5, 8, 8, + 0, 7, 8, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, + 9, 8, 0, 8, 8, 0, 7, 7, 5, 8, 9, 0, 8, 8, 0, 7, + 7, +}; + +static float _vq_quantthresh__44c9_s_p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44c9_s_p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44c9_s_p1_0 = { + _vq_quantthresh__44c9_s_p1_0, + _vq_quantmap__44c9_s_p1_0, + 3, + 3 +}; + +static static_codebook _44c9_s_p1_0 = { + 4, 81, + _vq_lengthlist__44c9_s_p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44c9_s_p1_0, + NULL, + &_vq_auxt__44c9_s_p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c9_s_p2_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c9_s_p2_0[] = { + 3, 5, 5, 8, 8, 0, 5, 5, 8, 8, 0, 5, 5, 8, 8, 0, + 7, 7, 9, 9, 0, 0, 0, 9, 9, 6, 7, 7, 9, 8, 0, 8, + 8, 9, 9, 0, 8, 7, 9, 9, 0, 9,10,10,10, 0, 0, 0, + 11,10, 6, 7, 7, 8, 9, 0, 8, 8, 9, 9, 0, 7, 8, 9, + 9, 0,10, 9,11,10, 0, 0, 0,10,10, 8, 9, 8,10,10, + 0,10,10,12,11, 0,10,10,11,11, 0,12,13,13,13, 0, + 0, 0,13,12, 8, 8, 9,10,10, 0,10,10,11,12, 0,10, + 10,11,11, 0,13,12,13,13, 0, 0, 0,13,13, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 6, 8, 7,10,10, 0, 7, 7,10, 9, + 0, 7, 7,10,10, 0, 9, 9,10,10, 0, 0, 0,10,10, 6, + 7, 8,10,10, 0, 7, 7, 9,10, 0, 7, 7,10,10, 0, 9, + 9,10,10, 0, 0, 0,10,10, 8, 9, 9,11,11, 0,10,10, + 11,11, 0,10,10,11,11, 0,12,12,12,12, 0, 0, 0,12, + 12, 8, 9,10,11,11, 0, 9,10,11,11, 0,10,10,11,11, + 0,12,12,12,12, 0, 0, 0,12,12, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 5, 8, 7,10,10, 0, 7, 7,10,10, 0, 7, 7, + 10, 9, 0, 9, 9,10,10, 0, 0, 0,10,10, 6, 7, 8,10, + 10, 0, 7, 7,10,10, 0, 7, 7, 9,10, 0, 9, 9,10,10, + 0, 0, 0,10,10, 8,10, 9,12,11, 0,10,10,12,11, 0, + 10, 9,11,11, 0,11,12,12,12, 0, 0, 0,12,12, 8, 9, + 10,11,12, 0,10,10,11,11, 0, 9,10,11,11, 0,12,11, + 12,12, 0, 0, 0,12,12, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 7,10, 9,12,12, 0, 9, 9,12,11, 0, 9, 9,11,11, 0, + 10,10,12,11, 0, 0, 0,11,12, 7, 9,10,12,12, 0, 9, + 9,11,12, 0, 9, 9,11,11, 0,10,10,11,12, 0, 0, 0, + 11,11, 9,11,10,13,12, 0,10,10,12,12, 0,10,10,12, + 12, 0,11,11,12,12, 0, 0, 0,13,12, 9,10,11,12,13, + 0,10,10,12,12, 0,10,10,12,12, 0,11,12,12,12, 0, + 0, 0,12,13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, + 11,10,13,13, 0,10,10,12,12, 0,10,10,12,12, 0,11, + 12,12,12, 0, 0, 0,12,12, 9,10,11,13,13, 0,10,10, + 12,12, 0,10,10,12,12, 0,12,11,13,12, 0, 0, 0,12, + 12, +}; + +static float _vq_quantthresh__44c9_s_p2_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c9_s_p2_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c9_s_p2_0 = { + _vq_quantthresh__44c9_s_p2_0, + _vq_quantmap__44c9_s_p2_0, + 5, + 5 +}; + +static static_codebook _44c9_s_p2_0 = { + 4, 625, + _vq_lengthlist__44c9_s_p2_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c9_s_p2_0, + NULL, + &_vq_auxt__44c9_s_p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c9_s_p3_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44c9_s_p3_0[] = { + 3, 4, 4, 5, 5, 6, 6, 8, 8, 0, 4, 4, 5, 5, 6, 7, + 8, 8, 0, 4, 4, 5, 5, 7, 7, 8, 8, 0, 5, 5, 6, 6, + 7, 7, 9, 9, 0, 0, 0, 6, 6, 7, 7, 9, 9, 0, 0, 0, + 7, 7, 8, 8, 9, 9, 0, 0, 0, 7, 7, 8, 8, 9, 9, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c9_s_p3_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44c9_s_p3_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44c9_s_p3_0 = { + _vq_quantthresh__44c9_s_p3_0, + _vq_quantmap__44c9_s_p3_0, + 9, + 9 +}; + +static static_codebook _44c9_s_p3_0 = { + 2, 81, + _vq_lengthlist__44c9_s_p3_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44c9_s_p3_0, + NULL, + &_vq_auxt__44c9_s_p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c9_s_p4_0[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44c9_s_p4_0[] = { + 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,10,10,10, + 10, 0, 5, 4, 5, 5, 7, 7, 8, 8, 8, 8, 9, 9,10,10, + 11,11, 0, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,10, + 10,11,11, 0, 6, 5, 6, 6, 7, 7, 8, 8, 9, 9,10,10, + 11,11,11,12, 0, 0, 0, 6, 6, 7, 7, 8, 8, 9, 9,10, + 10,11,11,12,12, 0, 0, 0, 7, 7, 7, 7, 9, 9, 9, 9, + 10,10,11,11,12,12, 0, 0, 0, 7, 7, 7, 8, 9, 9, 9, + 9,10,10,11,11,12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9, + 10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 8, 8, 9, + 9,10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c9_s_p4_0[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__44c9_s_p4_0[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44c9_s_p4_0 = { + _vq_quantthresh__44c9_s_p4_0, + _vq_quantmap__44c9_s_p4_0, + 17, + 17 +}; + +static static_codebook _44c9_s_p4_0 = { + 2, 289, + _vq_lengthlist__44c9_s_p4_0, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__44c9_s_p4_0, + NULL, + &_vq_auxt__44c9_s_p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c9_s_p5_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44c9_s_p5_0[] = { + 1, 4, 4, 5, 7, 7, 6, 7, 7, 4, 7, 6, 9,10,10,10, + 10, 9, 4, 6, 7, 9,10,10,10, 9,10, 5, 9, 9, 9,11, + 11,10,11,11, 7,10, 9,11,12,11,12,12,12, 7, 9,10, + 11,11,12,12,12,12, 6,10,10,10,12,12,10,12,11, 7, + 10,10,11,12,12,11,12,12, 7,10,10,11,12,12,12,12, + 12, +}; + +static float _vq_quantthresh__44c9_s_p5_0[] = { + -5.5, 5.5, +}; + +static long _vq_quantmap__44c9_s_p5_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44c9_s_p5_0 = { + _vq_quantthresh__44c9_s_p5_0, + _vq_quantmap__44c9_s_p5_0, + 3, + 3 +}; + +static static_codebook _44c9_s_p5_0 = { + 4, 81, + _vq_lengthlist__44c9_s_p5_0, + 1, -529137664, 1618345984, 2, 0, + _vq_quantlist__44c9_s_p5_0, + NULL, + &_vq_auxt__44c9_s_p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c9_s_p5_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44c9_s_p5_1[] = { + 4, 5, 5, 6, 6, 7, 7, 7, 7, 7, 7,11, 5, 5, 6, 6, + 7, 7, 7, 7, 8, 8,11, 5, 5, 6, 6, 7, 7, 7, 7, 8, + 8,11, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8,11,11,11, 6, + 6, 7, 7, 7, 8, 8, 8,11,11,11, 6, 6, 7, 7, 7, 8, + 8, 8,11,11,11, 6, 6, 7, 7, 7, 7, 8, 8,11,11,11, + 7, 7, 7, 7, 7, 7, 8, 8,11,11,11,10,10, 7, 7, 7, + 7, 8, 8,11,11,11,11,11, 7, 7, 7, 7, 7, 7,11,11, + 11,11,11, 7, 7, 7, 7, 7, 7, +}; + +static float _vq_quantthresh__44c9_s_p5_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__44c9_s_p5_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44c9_s_p5_1 = { + _vq_quantthresh__44c9_s_p5_1, + _vq_quantmap__44c9_s_p5_1, + 11, + 11 +}; + +static static_codebook _44c9_s_p5_1 = { + 2, 121, + _vq_lengthlist__44c9_s_p5_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__44c9_s_p5_1, + NULL, + &_vq_auxt__44c9_s_p5_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c9_s_p6_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c9_s_p6_0[] = { + 2, 4, 4, 6, 6, 7, 7, 7, 7, 8, 8, 9, 9, 5, 4, 4, + 6, 6, 8, 8, 9, 9, 9, 9,10,10, 6, 4, 4, 6, 6, 8, + 8, 9, 9, 9, 9,10,10, 0, 6, 6, 7, 7, 8, 8, 9, 9, + 10,10,11,11, 0, 6, 6, 7, 7, 8, 8, 9, 9,10,10,11, + 11, 0,10,10, 8, 8, 9, 9,10,10,11,11,12,12, 0,11, + 11, 8, 8, 9, 9,10,10,11,11,12,12, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +static float _vq_quantthresh__44c9_s_p6_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__44c9_s_p6_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c9_s_p6_0 = { + _vq_quantthresh__44c9_s_p6_0, + _vq_quantmap__44c9_s_p6_0, + 13, + 13 +}; + +static static_codebook _44c9_s_p6_0 = { + 2, 169, + _vq_lengthlist__44c9_s_p6_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__44c9_s_p6_0, + NULL, + &_vq_auxt__44c9_s_p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c9_s_p6_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c9_s_p6_1[] = { + 4, 4, 4, 5, 5, 5, 4, 4, 5, 5, 5, 4, 4, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, +}; + +static float _vq_quantthresh__44c9_s_p6_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c9_s_p6_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c9_s_p6_1 = { + _vq_quantthresh__44c9_s_p6_1, + _vq_quantmap__44c9_s_p6_1, + 5, + 5 +}; + +static static_codebook _44c9_s_p6_1 = { + 2, 25, + _vq_lengthlist__44c9_s_p6_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c9_s_p6_1, + NULL, + &_vq_auxt__44c9_s_p6_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c9_s_p7_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c9_s_p7_0[] = { + 2, 4, 4, 6, 6, 7, 7, 8, 8,10,10,11,11, 6, 4, 4, + 6, 6, 8, 8, 9, 9,10,10,12,12, 6, 4, 5, 6, 6, 8, + 8, 9, 9,10,10,12,12,20, 6, 6, 6, 6, 8, 8, 9,10, + 11,11,12,12,20, 6, 6, 6, 6, 8, 8,10,10,11,11,12, + 12,20,10,10, 7, 7, 9, 9,10,10,11,11,12,12,20,11, + 11, 7, 7, 9, 9,10,10,11,11,12,12,20,20,20, 9, 9, + 9, 9,11,11,12,12,13,13,20,20,20, 9, 9, 9, 9,11, + 11,12,12,13,13,20,20,20,13,13,10,10,11,11,12,13, + 13,13,20,20,20,13,13,10,10,11,11,12,13,13,13,20, + 20,20,20,19,12,12,12,12,13,13,14,15,19,19,19,19, + 19,12,12,12,12,13,13,14,14, +}; + +static float _vq_quantthresh__44c9_s_p7_0[] = { + -60.5, -49.5, -38.5, -27.5, -16.5, -5.5, 5.5, 16.5, + 27.5, 38.5, 49.5, 60.5, +}; + +static long _vq_quantmap__44c9_s_p7_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c9_s_p7_0 = { + _vq_quantthresh__44c9_s_p7_0, + _vq_quantmap__44c9_s_p7_0, + 13, + 13 +}; + +static static_codebook _44c9_s_p7_0 = { + 2, 169, + _vq_lengthlist__44c9_s_p7_0, + 1, -523206656, 1618345984, 4, 0, + _vq_quantlist__44c9_s_p7_0, + NULL, + &_vq_auxt__44c9_s_p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c9_s_p7_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44c9_s_p7_1[] = { + 5, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, + 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 7, 7, 7, 7, 7, + 7, 8, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 8, 8, 8, 6, + 6, 7, 7, 7, 7, 7, 7, 8, 8, 8, 7, 7, 7, 7, 7, 7, + 7, 7, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, + 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 7, 7, 7, + 7, 7, 7, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 8, 8, + 8, 8, 8, 7, 7, 7, 7, 7, 7, +}; + +static float _vq_quantthresh__44c9_s_p7_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__44c9_s_p7_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44c9_s_p7_1 = { + _vq_quantthresh__44c9_s_p7_1, + _vq_quantmap__44c9_s_p7_1, + 11, + 11 +}; + +static static_codebook _44c9_s_p7_1 = { + 2, 121, + _vq_lengthlist__44c9_s_p7_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__44c9_s_p7_1, + NULL, + &_vq_auxt__44c9_s_p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c9_s_p8_0[] = { + 7, + 6, + 8, + 5, + 9, + 4, + 10, + 3, + 11, + 2, + 12, + 1, + 13, + 0, + 14, +}; + +static long _vq_lengthlist__44c9_s_p8_0[] = { + 1, 4, 4, 7, 6, 8, 8, 8, 8, 9, 9,10,10,11,10, 6, + 5, 5, 7, 7, 9, 9, 8, 9,10,10,11,11,12,12, 6, 5, + 5, 7, 7, 9, 9, 9, 9,10,10,11,11,12,12,21, 7, 8, + 8, 8, 9, 9, 9, 9,10,10,11,11,12,12,21, 8, 8, 8, + 8, 9, 9, 9, 9,10,10,11,11,12,12,21,11,12, 9, 9, + 10,10,10,10,10,11,11,12,12,12,21,12,12, 9, 8,10, + 10,10,10,11,11,12,12,13,13,21,21,21, 9, 9, 9, 9, + 11,11,11,11,12,12,12,13,21,20,20, 9, 9, 9, 9,10, + 11,11,11,12,12,13,13,20,20,20,13,13,10,10,11,11, + 12,12,13,13,13,13,20,20,20,13,13,10,10,11,11,12, + 12,13,13,13,13,20,20,20,20,20,12,12,12,12,12,12, + 13,13,14,14,20,20,20,20,20,12,12,12,11,13,12,13, + 13,14,14,20,20,20,20,20,15,16,13,12,13,13,14,13, + 14,14,20,20,20,20,20,16,15,12,12,13,12,14,13,14, + 14, +}; + +static float _vq_quantthresh__44c9_s_p8_0[] = { + -136.5, -115.5, -94.5, -73.5, -52.5, -31.5, -10.5, 10.5, + 31.5, 52.5, 73.5, 94.5, 115.5, 136.5, +}; + +static long _vq_quantmap__44c9_s_p8_0[] = { + 13, 11, 9, 7, 5, 3, 1, 0, + 2, 4, 6, 8, 10, 12, 14, +}; + +static encode_aux_threshmatch _vq_auxt__44c9_s_p8_0 = { + _vq_quantthresh__44c9_s_p8_0, + _vq_quantmap__44c9_s_p8_0, + 15, + 15 +}; + +static static_codebook _44c9_s_p8_0 = { + 2, 225, + _vq_lengthlist__44c9_s_p8_0, + 1, -520986624, 1620377600, 4, 0, + _vq_quantlist__44c9_s_p8_0, + NULL, + &_vq_auxt__44c9_s_p8_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c9_s_p8_1[] = { + 10, + 9, + 11, + 8, + 12, + 7, + 13, + 6, + 14, + 5, + 15, + 4, + 16, + 3, + 17, + 2, + 18, + 1, + 19, + 0, + 20, +}; + +static long _vq_lengthlist__44c9_s_p8_1[] = { + 4, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8,10, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10, 6, 6, 7, 7, 8, + 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10, + 7, 7, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9,10,10,10, 8, 8, 8, 8, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10,10, 8, 8, 8, 8, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10, + 10, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9,10,10,10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9,10,10,10,10,10, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10,10, + 10,10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9,10,10,10,10,10, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9,10,10,10,10,10, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9,10, 9, 9, 9,10,10,10,10, + 10,10,10, 9, 9, 9, 9, 9, 9,10, 9, 9, 9, 9, 9, 9, + 9,10,10,10,10,10,10,10, 9, 9, 9,10,10,10,10,10, + 9, 9, 9, 9, 9, 9,10,10,10,10,10,10,10, 9, 9,10, + 9,10, 9, 9, 9, 9, 9, 9, 9, 9,10,10,10,10,10,10, + 10,10,10,10, 9, 9,10,10, 9, 9, 9, 9, 9, 9, 9, 9, + 10,10,10,10,10,10,10,10,10,10,10,10,10, 9, 9, 9, + 9, 9, 9, 9, 9,10,10,10,10,10,10,10,10,10,10,10, + 10,10, 9, 9,10, 9, 9, 9, 9, 9,10,10,10,10,10,10, + 10,10,10,10,10, 9, 9,10,10, 9, 9,10, 9, 9, 9,10, + 10,10,10,10,10,10,10,10,10,10, 9, 9,10, 9, 9, 9, + 9, 9, 9, 9,10,10,10,10,10,10,10,10,10,10,10, 9, + 9, 9, 9,10, 9, 9, 9, 9, 9, +}; + +static float _vq_quantthresh__44c9_s_p8_1[] = { + -9.5, -8.5, -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, + -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, + 6.5, 7.5, 8.5, 9.5, +}; + +static long _vq_quantmap__44c9_s_p8_1[] = { + 19, 17, 15, 13, 11, 9, 7, 5, + 3, 1, 0, 2, 4, 6, 8, 10, + 12, 14, 16, 18, 20, +}; + +static encode_aux_threshmatch _vq_auxt__44c9_s_p8_1 = { + _vq_quantthresh__44c9_s_p8_1, + _vq_quantmap__44c9_s_p8_1, + 21, + 21 +}; + +static static_codebook _44c9_s_p8_1 = { + 2, 441, + _vq_lengthlist__44c9_s_p8_1, + 1, -529268736, 1611661312, 5, 0, + _vq_quantlist__44c9_s_p8_1, + NULL, + &_vq_auxt__44c9_s_p8_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c9_s_p9_0[] = { + 9, + 8, + 10, + 7, + 11, + 6, + 12, + 5, + 13, + 4, + 14, + 3, + 15, + 2, + 16, + 1, + 17, + 0, + 18, +}; + +static long _vq_lengthlist__44c9_s_p9_0[] = { + 1, 4, 3,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12, 4, 5, 6,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12, 4, 6, 6,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,11,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11, +}; + +static float _vq_quantthresh__44c9_s_p9_0[] = { + -7913.5, -6982.5, -6051.5, -5120.5, -4189.5, -3258.5, -2327.5, -1396.5, + -465.5, 465.5, 1396.5, 2327.5, 3258.5, 4189.5, 5120.5, 6051.5, + 6982.5, 7913.5, +}; + +static long _vq_quantmap__44c9_s_p9_0[] = { + 17, 15, 13, 11, 9, 7, 5, 3, + 1, 0, 2, 4, 6, 8, 10, 12, + 14, 16, 18, +}; + +static encode_aux_threshmatch _vq_auxt__44c9_s_p9_0 = { + _vq_quantthresh__44c9_s_p9_0, + _vq_quantmap__44c9_s_p9_0, + 19, + 19 +}; + +static static_codebook _44c9_s_p9_0 = { + 2, 361, + _vq_lengthlist__44c9_s_p9_0, + 1, -508535424, 1631393792, 5, 0, + _vq_quantlist__44c9_s_p9_0, + NULL, + &_vq_auxt__44c9_s_p9_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c9_s_p9_1[] = { + 9, + 8, + 10, + 7, + 11, + 6, + 12, + 5, + 13, + 4, + 14, + 3, + 15, + 2, + 16, + 1, + 17, + 0, + 18, +}; + +static long _vq_lengthlist__44c9_s_p9_1[] = { + 1, 4, 4, 7, 7, 7, 7, 8, 7, 9, 8, 9, 9,10,10,11, + 11,11,11, 6, 5, 5, 8, 8, 9, 9, 9, 8,10, 9,11,10, + 12,12,13,12,13,13, 5, 5, 5, 8, 8, 9, 9, 9, 9,10, + 10,11,11,12,12,13,12,13,13,17, 8, 8, 9, 9, 9, 9, + 9, 9,10,10,12,11,13,12,13,13,13,13,18, 8, 8, 9, + 9, 9, 9, 9, 9,11,11,12,12,13,13,13,13,13,13,17, + 13,12, 9, 9,10,10,10,10,11,11,12,12,12,13,13,13, + 14,14,18,13,12, 9, 9,10,10,10,10,11,11,12,12,13, + 13,13,14,14,14,17,18,18,10,10,10,10,11,11,11,12, + 12,12,14,13,14,13,13,14,18,18,18,10, 9,10, 9,11, + 11,12,12,12,12,13,13,15,14,14,14,18,18,16,13,14, + 10,11,11,11,12,13,13,13,13,14,13,13,14,14,18,18, + 18,14,12,11, 9,11,10,13,12,13,13,13,14,14,14,13, + 14,18,18,17,18,18,11,12,12,12,13,13,14,13,14,14, + 13,14,14,14,18,18,18,18,17,12,10,12, 9,13,11,13, + 14,14,14,14,14,15,14,18,18,17,17,18,14,15,12,13, + 13,13,14,13,14,14,15,14,15,14,18,17,18,18,18,15, + 15,12,10,14,10,14,14,13,13,14,14,14,14,18,16,18, + 18,18,18,17,14,14,13,14,14,13,13,14,14,14,15,15, + 18,18,18,18,17,17,17,14,14,14,12,14,13,14,14,15, + 14,15,14,18,18,18,18,18,18,18,17,16,13,13,13,14, + 14,14,14,15,16,15,18,18,18,18,18,18,18,17,17,13, + 13,13,13,14,13,14,15,15,15, +}; + +static float _vq_quantthresh__44c9_s_p9_1[] = { + -416.5, -367.5, -318.5, -269.5, -220.5, -171.5, -122.5, -73.5, + -24.5, 24.5, 73.5, 122.5, 171.5, 220.5, 269.5, 318.5, + 367.5, 416.5, +}; + +static long _vq_quantmap__44c9_s_p9_1[] = { + 17, 15, 13, 11, 9, 7, 5, 3, + 1, 0, 2, 4, 6, 8, 10, 12, + 14, 16, 18, +}; + +static encode_aux_threshmatch _vq_auxt__44c9_s_p9_1 = { + _vq_quantthresh__44c9_s_p9_1, + _vq_quantmap__44c9_s_p9_1, + 19, + 19 +}; + +static static_codebook _44c9_s_p9_1 = { + 2, 361, + _vq_lengthlist__44c9_s_p9_1, + 1, -518287360, 1622704128, 5, 0, + _vq_quantlist__44c9_s_p9_1, + NULL, + &_vq_auxt__44c9_s_p9_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c9_s_p9_2[] = { + 24, + 23, + 25, + 22, + 26, + 21, + 27, + 20, + 28, + 19, + 29, + 18, + 30, + 17, + 31, + 16, + 32, + 15, + 33, + 14, + 34, + 13, + 35, + 12, + 36, + 11, + 37, + 10, + 38, + 9, + 39, + 8, + 40, + 7, + 41, + 6, + 42, + 5, + 43, + 4, + 44, + 3, + 45, + 2, + 46, + 1, + 47, + 0, + 48, +}; + +static long _vq_lengthlist__44c9_s_p9_2[] = { + 2, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, +}; + +static float _vq_quantthresh__44c9_s_p9_2[] = { + -23.5, -22.5, -21.5, -20.5, -19.5, -18.5, -17.5, -16.5, + -15.5, -14.5, -13.5, -12.5, -11.5, -10.5, -9.5, -8.5, + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, + 8.5, 9.5, 10.5, 11.5, 12.5, 13.5, 14.5, 15.5, + 16.5, 17.5, 18.5, 19.5, 20.5, 21.5, 22.5, 23.5, +}; + +static long _vq_quantmap__44c9_s_p9_2[] = { + 47, 45, 43, 41, 39, 37, 35, 33, + 31, 29, 27, 25, 23, 21, 19, 17, + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, 18, 20, 22, 24, 26, 28, 30, + 32, 34, 36, 38, 40, 42, 44, 46, + 48, +}; + +static encode_aux_threshmatch _vq_auxt__44c9_s_p9_2 = { + _vq_quantthresh__44c9_s_p9_2, + _vq_quantmap__44c9_s_p9_2, + 49, + 49 +}; + +static static_codebook _44c9_s_p9_2 = { + 1, 49, + _vq_lengthlist__44c9_s_p9_2, + 1, -526909440, 1611661312, 6, 0, + _vq_quantlist__44c9_s_p9_2, + NULL, + &_vq_auxt__44c9_s_p9_2, + NULL, + 0 +}; + +static long _huff_lengthlist__44c9_s_short[] = { + 5,13,18,16,17,17,19,18,19,19, 5, 7,10,11,12,12, + 13,16,17,18, 6, 6, 7, 7, 9, 9,10,14,17,19, 8, 7, + 6, 5, 6, 7, 9,12,19,17, 8, 7, 7, 6, 5, 6, 8,11, + 15,19, 9, 8, 7, 6, 5, 5, 6, 8,13,15,11,10, 8, 8, + 7, 5, 4, 4,10,14,12,13,11, 9, 7, 6, 4, 2, 6,12, + 18,16,16,13, 8, 7, 7, 5, 8,13,16,17,18,15,11, 9, + 9, 8,10,13, +}; + +static static_codebook _huff_book__44c9_s_short = { + 2, 100, + _huff_lengthlist__44c9_s_short, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__44c0_s_long[] = { + 5, 4, 8, 9, 8, 9,10,12,15, 4, 1, 5, 5, 6, 8,11, + 12,12, 8, 5, 8, 9, 9,11,13,12,12, 9, 5, 8, 5, 7, + 9,12,13,13, 8, 6, 8, 7, 7, 9,11,11,11, 9, 7, 9, + 7, 7, 7, 7,10,12,10,10,11, 9, 8, 7, 7, 9,11,11, + 12,13,12,11, 9, 8, 9,11,13,16,16,15,15,12,10,11, + 12, +}; + +static static_codebook _huff_book__44c0_s_long = { + 2, 81, + _huff_lengthlist__44c0_s_long, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__44c0_s_p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44c0_s_p1_0[] = { + 1, 5, 5, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 0, + 0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 5, 8, 7, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, + 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, + 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 0, + 0, 0, 8,10, 9, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, + 0, 0, 0, 9,10,11, 0, 0, 0, 0, 0, 0, 9,11,10, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, + 0, 0, 0, 0, 9,11, 9, 0, 0, 0, 0, 0, 0, 9,10,11, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, + 0, 0, 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 9,11,10, 0, + 0, 0, 0, 0, 0, 9, 9,11, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7, 9,10, 0, 0, 0, 0, 0, 0, 9,10,11, + 0, 0, 0, 0, 0, 0, 9,11,10, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c0_s_p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44c0_s_p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44c0_s_p1_0 = { + _vq_quantthresh__44c0_s_p1_0, + _vq_quantmap__44c0_s_p1_0, + 3, + 3 +}; + +static static_codebook _44c0_s_p1_0 = { + 8, 6561, + _vq_lengthlist__44c0_s_p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44c0_s_p1_0, + NULL, + &_vq_auxt__44c0_s_p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c0_s_p2_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c0_s_p2_0[] = { + 1, 4, 4, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 5, 7, 6, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 5, 6, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 7, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6, 7, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c0_s_p2_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c0_s_p2_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c0_s_p2_0 = { + _vq_quantthresh__44c0_s_p2_0, + _vq_quantmap__44c0_s_p2_0, + 5, + 5 +}; + +static static_codebook _44c0_s_p2_0 = { + 4, 625, + _vq_lengthlist__44c0_s_p2_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c0_s_p2_0, + NULL, + &_vq_auxt__44c0_s_p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c0_s_p3_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44c0_s_p3_0[] = { + 1, 3, 2, 8, 7, 0, 0, 0, 0, 0, 0, 0, 6, 6, 0, 0, + 0, 0, 0, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, 7, 7, + 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0, + 8, 8, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, + 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c0_s_p3_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44c0_s_p3_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44c0_s_p3_0 = { + _vq_quantthresh__44c0_s_p3_0, + _vq_quantmap__44c0_s_p3_0, + 9, + 9 +}; + +static static_codebook _44c0_s_p3_0 = { + 2, 81, + _vq_lengthlist__44c0_s_p3_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44c0_s_p3_0, + NULL, + &_vq_auxt__44c0_s_p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c0_s_p4_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44c0_s_p4_0[] = { + 1, 3, 3, 6, 6, 6, 6, 8, 8, 0, 0, 0, 7, 7, 7, 7, + 9, 9, 0, 0, 0, 7, 7, 7, 7, 9, 9, 0, 0, 0, 7, 7, + 7, 8, 9, 9, 0, 0, 0, 7, 7, 7, 7, 9, 9, 0, 0, 0, + 9, 9, 8, 8,10,10, 0, 0, 0, 8, 9, 8, 8,10,10, 0, + 0, 0,10,10, 9, 9,10,10, 0, 0, 0, 0, 0, 9, 9,10, + 10, +}; + +static float _vq_quantthresh__44c0_s_p4_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44c0_s_p4_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44c0_s_p4_0 = { + _vq_quantthresh__44c0_s_p4_0, + _vq_quantmap__44c0_s_p4_0, + 9, + 9 +}; + +static static_codebook _44c0_s_p4_0 = { + 2, 81, + _vq_lengthlist__44c0_s_p4_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44c0_s_p4_0, + NULL, + &_vq_auxt__44c0_s_p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c0_s_p5_0[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44c0_s_p5_0[] = { + 1, 4, 3, 6, 6, 8, 7, 8, 8, 8, 8, 9, 9,10,10,11, + 11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9, 9,10,10,10, + 11,11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,10,10, + 10,11,11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,10, + 11,11,11,11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10, + 10,11,11,11,11, 0, 0, 0, 8, 8, 9, 9, 9, 9,10,10, + 10,10,11,11,12,12, 0, 0, 0, 8, 8, 9, 9, 9, 9,10, + 10,10,10,11,11,12,12, 0, 0, 0, 9, 9, 9, 9,10,10, + 10,10,11,11,11,12,12,12, 0, 0, 0, 0, 0, 9, 9,10, + 10,10,10,11,11,11,11,12,12, 0, 0, 0, 0, 0, 9, 9, + 10,10,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9, + 9,10,10,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, + 10,10,11,11,11,11,11,12,12,12,13,13, 0, 0, 0, 0, + 0, 0, 0,11,10,11,11,11,11,12,12,13,13, 0, 0, 0, + 0, 0, 0, 0,11,11,12,11,12,12,12,12,13,13, 0, 0, + 0, 0, 0, 0, 0,11,11,11,12,12,12,12,13,13,13, 0, + 0, 0, 0, 0, 0, 0,12,12,12,12,12,13,13,13,14,14, + 0, 0, 0, 0, 0, 0, 0, 0, 0,12,12,12,12,13,13,14, + 14, +}; + +static float _vq_quantthresh__44c0_s_p5_0[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__44c0_s_p5_0[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44c0_s_p5_0 = { + _vq_quantthresh__44c0_s_p5_0, + _vq_quantmap__44c0_s_p5_0, + 17, + 17 +}; + +static static_codebook _44c0_s_p5_0 = { + 2, 289, + _vq_lengthlist__44c0_s_p5_0, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__44c0_s_p5_0, + NULL, + &_vq_auxt__44c0_s_p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c0_s_p6_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44c0_s_p6_0[] = { + 1, 4, 4, 7, 6, 6, 7, 6, 6, 4, 7, 7,10, 9, 9,10, + 9, 9, 4, 6, 7,10, 9, 9,11, 9, 9, 7,10,10,11,11, + 11,12,10,11, 6, 9, 9,11,10,11,11,10,10, 6, 9, 9, + 11,10,11,11,10,10, 7,11,10,12,11,11,11,11,11, 7, + 9, 9,10,10,10,11,11,10, 6, 9, 9,11,10,10,11,10, + 10, +}; + +static float _vq_quantthresh__44c0_s_p6_0[] = { + -5.5, 5.5, +}; + +static long _vq_quantmap__44c0_s_p6_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44c0_s_p6_0 = { + _vq_quantthresh__44c0_s_p6_0, + _vq_quantmap__44c0_s_p6_0, + 3, + 3 +}; + +static static_codebook _44c0_s_p6_0 = { + 4, 81, + _vq_lengthlist__44c0_s_p6_0, + 1, -529137664, 1618345984, 2, 0, + _vq_quantlist__44c0_s_p6_0, + NULL, + &_vq_auxt__44c0_s_p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c0_s_p6_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44c0_s_p6_1[] = { + 2, 3, 3, 6, 6, 7, 7, 7, 7, 7, 8,10,10,10, 6, 6, + 7, 7, 8, 8, 8, 8,10,10,10, 6, 6, 7, 7, 8, 8, 8, + 8,10,10,10, 7, 7, 7, 7, 8, 8, 8, 8,10,10,10, 7, + 7, 7, 7, 8, 8, 8, 8,10,10,10, 8, 7, 8, 8, 8, 8, + 8, 8,10,10,10, 7, 7, 8, 8, 8, 8, 8, 8,10,10,10, + 8, 8, 8, 8, 8, 8, 8, 8,10,10,10,10,10, 8, 8, 8, + 8, 8, 8,10,10,10,10,10, 9, 9, 8, 8, 8, 8,10,10, + 10,10,10, 8, 8, 8, 8, 8, 8, +}; + +static float _vq_quantthresh__44c0_s_p6_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__44c0_s_p6_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44c0_s_p6_1 = { + _vq_quantthresh__44c0_s_p6_1, + _vq_quantmap__44c0_s_p6_1, + 11, + 11 +}; + +static static_codebook _44c0_s_p6_1 = { + 2, 121, + _vq_lengthlist__44c0_s_p6_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__44c0_s_p6_1, + NULL, + &_vq_auxt__44c0_s_p6_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c0_s_p7_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c0_s_p7_0[] = { + 1, 4, 4, 6, 6, 7, 7, 7, 7, 8, 8, 9, 9, 7, 5, 5, + 7, 7, 8, 8, 8, 8, 9, 9,10,10, 7, 5, 6, 7, 7, 8, + 8, 8, 8, 9, 9,10,10, 0, 8, 8, 8, 8, 9, 9, 9, 9, + 10,10,11,11, 0, 8, 8, 8, 8, 9, 9, 9, 9,10,10,11, + 11, 0,12,12, 9, 9,10,10,10,10,11,11,11,11, 0,13, + 13, 9, 9, 9, 9,10,10,11,11,11,12, 0, 0, 0,10,10, + 10,10,11,11,11,11,12,12, 0, 0, 0,10,10, 9, 9,11, + 11,11,12,12,12, 0, 0, 0,13,13,10,10,11,11,12,12, + 13,13, 0, 0, 0,14,14,10,10,11,11,12,12,13,13, 0, + 0, 0, 0, 0,11,11,11,11,13,12,13,13, 0, 0, 0, 0, + 0,12,12,11,11,12,12,13,13, +}; + +static float _vq_quantthresh__44c0_s_p7_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__44c0_s_p7_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c0_s_p7_0 = { + _vq_quantthresh__44c0_s_p7_0, + _vq_quantmap__44c0_s_p7_0, + 13, + 13 +}; + +static static_codebook _44c0_s_p7_0 = { + 2, 169, + _vq_lengthlist__44c0_s_p7_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__44c0_s_p7_0, + NULL, + &_vq_auxt__44c0_s_p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c0_s_p7_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c0_s_p7_1[] = { + 2, 3, 3, 5, 5, 6, 6, 6, 5, 5, 6, 6, 6, 5, 5, 6, + 6, 6, 5, 5, 6, 6, 6, 5, 5, +}; + +static float _vq_quantthresh__44c0_s_p7_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c0_s_p7_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c0_s_p7_1 = { + _vq_quantthresh__44c0_s_p7_1, + _vq_quantmap__44c0_s_p7_1, + 5, + 5 +}; + +static static_codebook _44c0_s_p7_1 = { + 2, 25, + _vq_lengthlist__44c0_s_p7_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c0_s_p7_1, + NULL, + &_vq_auxt__44c0_s_p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c0_s_p8_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c0_s_p8_0[] = { + 1, 5, 5,10,10, 6, 9, 8,10,10, 6,10, 9,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10, 8,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,10,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11, +}; + +static float _vq_quantthresh__44c0_s_p8_0[] = { + -331.5, -110.5, 110.5, 331.5, +}; + +static long _vq_quantmap__44c0_s_p8_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c0_s_p8_0 = { + _vq_quantthresh__44c0_s_p8_0, + _vq_quantmap__44c0_s_p8_0, + 5, + 5 +}; + +static static_codebook _44c0_s_p8_0 = { + 4, 625, + _vq_lengthlist__44c0_s_p8_0, + 1, -518283264, 1627103232, 3, 0, + _vq_quantlist__44c0_s_p8_0, + NULL, + &_vq_auxt__44c0_s_p8_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c0_s_p8_1[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c0_s_p8_1[] = { + 1, 4, 4, 6, 6, 7, 7, 9, 9,11,12,13,12, 6, 5, 5, + 7, 7, 8, 8,10, 9,12,12,12,12, 6, 5, 5, 7, 7, 8, + 8,10, 9,12,11,11,13,16, 7, 7, 8, 8, 9, 9,10,10, + 12,12,13,12,16, 7, 7, 8, 7, 9, 9,10,10,11,12,12, + 13,16,10,10, 8, 8,10,10,11,12,12,12,13,13,16,11, + 10, 8, 7,11,10,11,11,12,11,13,13,16,16,16,10,10, + 10,10,11,11,13,12,13,13,16,16,16,11, 9,11, 9,15, + 13,12,13,13,13,16,16,16,15,13,11,11,12,13,12,12, + 14,13,16,16,16,14,13,11,11,13,12,14,13,13,13,16, + 16,16,16,16,13,13,13,12,14,13,14,14,16,16,16,16, + 16,13,13,12,12,14,14,15,13, +}; + +static float _vq_quantthresh__44c0_s_p8_1[] = { + -93.5, -76.5, -59.5, -42.5, -25.5, -8.5, 8.5, 25.5, + 42.5, 59.5, 76.5, 93.5, +}; + +static long _vq_quantmap__44c0_s_p8_1[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c0_s_p8_1 = { + _vq_quantthresh__44c0_s_p8_1, + _vq_quantmap__44c0_s_p8_1, + 13, + 13 +}; + +static static_codebook _44c0_s_p8_1 = { + 2, 169, + _vq_lengthlist__44c0_s_p8_1, + 1, -522616832, 1620115456, 4, 0, + _vq_quantlist__44c0_s_p8_1, + NULL, + &_vq_auxt__44c0_s_p8_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c0_s_p8_2[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44c0_s_p8_2[] = { + 2, 4, 4, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, + 8,10,10,10, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9, + 9, 9,10,10,10, 7, 7, 7, 7, 8, 8, 9, 9, 9, 9, 9, + 9, 9, 9,10,10,10, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, + 9,10, 9, 9,10,10,10, 7, 7, 8, 8, 9, 8, 9, 9, 9, + 9,10, 9, 9,10,10,10,10, 8, 8, 8, 8, 9, 8, 9, 9, + 9, 9, 9,10, 9,10,10,10,10, 7, 7, 8, 8, 9, 9, 9, + 9, 9, 9,10, 9,10,10,10,10,10, 8, 8, 8, 9, 9, 9, + 9, 9, 9, 9,10,10,10, 9,11,10,10,10,10, 8, 8, 9, + 9, 9, 9, 9,10, 9, 9, 9,10,10,10,10,11,11, 9, 9, + 9, 9, 9, 9, 9, 9,10, 9, 9,10,11,10,10,11,11, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9,10, 9,11,11,10,11,11, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10, 9,11,10,10,11, + 11,11,11, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10,10, + 11,11,11,11, 9,10, 9,10, 9, 9, 9, 9,10, 9,10,11, + 10,11,10,10,10,10,10, 9, 9, 9,10, 9, 9, 9,10,11, + 11,10,11,11,10,11,10,10,10, 9, 9, 9, 9,10, 9, 9, + 10,11,10,11,11,11,11,10,11,10,10, 9,10, 9, 9, 9, + 10, +}; + +static float _vq_quantthresh__44c0_s_p8_2[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__44c0_s_p8_2[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44c0_s_p8_2 = { + _vq_quantthresh__44c0_s_p8_2, + _vq_quantmap__44c0_s_p8_2, + 17, + 17 +}; + +static static_codebook _44c0_s_p8_2 = { + 2, 289, + _vq_lengthlist__44c0_s_p8_2, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__44c0_s_p8_2, + NULL, + &_vq_auxt__44c0_s_p8_2, + NULL, + 0 +}; + +static long _huff_lengthlist__44c0_s_short[] = { + 9, 8,12,11,12,13,14,14,16, 6, 1, 5, 6, 6, 9,12, + 14,17, 9, 4, 5, 9, 7, 9,13,15,16, 8, 5, 8, 6, 8, + 10,13,17,17, 9, 6, 7, 7, 8, 9,13,15,17,11, 8, 9, + 9, 9,10,12,16,16,13, 7, 8, 7, 7, 9,12,14,15,13, + 6, 7, 5, 5, 7,10,13,13,14, 7, 8, 5, 6, 7, 9,10, + 12, +}; + +static static_codebook _huff_book__44c0_s_short = { + 2, 81, + _huff_lengthlist__44c0_s_short, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__44c0_sm_long[] = { + 5, 4, 9,10, 9,10,11,12,13, 4, 1, 5, 7, 7, 9,11, + 12,14, 8, 5, 7, 9, 8,10,13,13,13,10, 7, 9, 4, 6, + 7,10,12,14, 9, 6, 7, 6, 6, 7,10,12,12, 9, 8, 9, + 7, 6, 7, 8,11,12,11,11,11, 9, 8, 7, 8,10,12,12, + 13,14,12,11, 9, 9, 9,12,12,17,17,15,16,12,10,11, + 13, +}; + +static static_codebook _huff_book__44c0_sm_long = { + 2, 81, + _huff_lengthlist__44c0_sm_long, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__44c0_sm_p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44c0_sm_p1_0[] = { + 1, 5, 5, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 0, + 0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 5, 8, 7, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, + 0, 0, 0, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 7, 9, 8, 0, 0, + 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 8, 7, 0, 0, 0, 0, + 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, + 0, 0, 0, 9,10,10, 0, 0, 0, 0, 0, 0, 9,10,10, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, + 0, 0, 0, 0, 8,10, 9, 0, 0, 0, 0, 0, 0, 9,10,10, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 7, 8, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, + 0, 0, 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 9,10,10, 0, + 0, 0, 0, 0, 0, 9, 9,10, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 9,10,10, + 0, 0, 0, 0, 0, 0, 9,10,10, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c0_sm_p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44c0_sm_p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44c0_sm_p1_0 = { + _vq_quantthresh__44c0_sm_p1_0, + _vq_quantmap__44c0_sm_p1_0, + 3, + 3 +}; + +static static_codebook _44c0_sm_p1_0 = { + 8, 6561, + _vq_lengthlist__44c0_sm_p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44c0_sm_p1_0, + NULL, + &_vq_auxt__44c0_sm_p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c0_sm_p2_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c0_sm_p2_0[] = { + 1, 4, 4, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 5, 7, 7, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 5, 5, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 7, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7, 7, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c0_sm_p2_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c0_sm_p2_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c0_sm_p2_0 = { + _vq_quantthresh__44c0_sm_p2_0, + _vq_quantmap__44c0_sm_p2_0, + 5, + 5 +}; + +static static_codebook _44c0_sm_p2_0 = { + 4, 625, + _vq_lengthlist__44c0_sm_p2_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c0_sm_p2_0, + NULL, + &_vq_auxt__44c0_sm_p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c0_sm_p3_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44c0_sm_p3_0[] = { + 1, 3, 3, 7, 7, 0, 0, 0, 0, 0, 5, 4, 7, 7, 0, 0, + 0, 0, 0, 5, 5, 7, 7, 0, 0, 0, 0, 0, 6, 7, 8, 8, + 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, + 9,10, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, + 0, 0,11,11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c0_sm_p3_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44c0_sm_p3_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44c0_sm_p3_0 = { + _vq_quantthresh__44c0_sm_p3_0, + _vq_quantmap__44c0_sm_p3_0, + 9, + 9 +}; + +static static_codebook _44c0_sm_p3_0 = { + 2, 81, + _vq_lengthlist__44c0_sm_p3_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44c0_sm_p3_0, + NULL, + &_vq_auxt__44c0_sm_p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c0_sm_p4_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44c0_sm_p4_0[] = { + 1, 4, 3, 6, 6, 7, 7, 9, 9, 0, 5, 5, 7, 7, 8, 7, + 9, 9, 0, 5, 5, 7, 7, 8, 8, 9, 9, 0, 7, 7, 8, 8, + 8, 8,10,10, 0, 0, 0, 8, 8, 8, 8,10,10, 0, 0, 0, + 9, 9, 9, 9,11,11, 0, 0, 0, 9, 9, 9, 9,11,11, 0, + 0, 0,10,10,10,10,11,11, 0, 0, 0, 0, 0, 9, 9,11, + 11, +}; + +static float _vq_quantthresh__44c0_sm_p4_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44c0_sm_p4_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44c0_sm_p4_0 = { + _vq_quantthresh__44c0_sm_p4_0, + _vq_quantmap__44c0_sm_p4_0, + 9, + 9 +}; + +static static_codebook _44c0_sm_p4_0 = { + 2, 81, + _vq_lengthlist__44c0_sm_p4_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44c0_sm_p4_0, + NULL, + &_vq_auxt__44c0_sm_p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c0_sm_p5_0[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44c0_sm_p5_0[] = { + 1, 4, 4, 6, 6, 8, 8, 8, 8, 8, 8, 9, 9,10,10,11, + 11, 0, 6, 6, 7, 7, 8, 8, 9, 9, 9, 9,10,10,10,11, + 11,11, 0, 5, 6, 7, 7, 8, 8, 9, 9, 9, 9,10,10,10, + 11,11,11, 0, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9,10,10, + 11,11,12,12, 0, 0, 0, 8, 8, 8, 8, 9, 9, 9, 9,10, + 10,11,11,12,12, 0, 0, 0, 8, 8, 9, 9,10,10,10,10, + 11,11,11,11,12,12, 0, 0, 0, 8, 8, 9, 9,10,10,10, + 10,11,11,11,11,12,12, 0, 0, 0, 9, 9, 9, 9,10,10, + 10,10,11,11,12,12,12,13, 0, 0, 0, 0, 0, 9, 9,10, + 10,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9, 9, + 10,10,11,11,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9, + 9,10,10,11,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, + 10,10,10,10,11,11,12,12,12,13,13,13, 0, 0, 0, 0, + 0, 0, 0,10,10,11,11,12,12,12,13,13,13, 0, 0, 0, + 0, 0, 0, 0,11,11,12,12,12,12,13,13,14,14, 0, 0, + 0, 0, 0, 0, 0,11,11,12,11,12,12,13,13,13,13, 0, + 0, 0, 0, 0, 0, 0,12,12,12,12,13,13,13,13,14,14, + 0, 0, 0, 0, 0, 0, 0, 0, 0,12,12,12,12,13,13,14, + 14, +}; + +static float _vq_quantthresh__44c0_sm_p5_0[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__44c0_sm_p5_0[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44c0_sm_p5_0 = { + _vq_quantthresh__44c0_sm_p5_0, + _vq_quantmap__44c0_sm_p5_0, + 17, + 17 +}; + +static static_codebook _44c0_sm_p5_0 = { + 2, 289, + _vq_lengthlist__44c0_sm_p5_0, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__44c0_sm_p5_0, + NULL, + &_vq_auxt__44c0_sm_p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c0_sm_p6_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44c0_sm_p6_0[] = { + 1, 4, 4, 7, 6, 6, 7, 6, 6, 4, 7, 7,10, 9, 9,11, + 9, 9, 4, 7, 7,10, 9, 9,11, 9, 9, 7,10,10,10,11, + 11,11,10,10, 6, 9, 9,11,11,10,11,10,10, 6, 9, 9, + 11,10,11,11,10,10, 7,11,10,11,11,11,11,11,11, 6, + 9, 9,11,10,10,11,11,10, 6, 9, 9,11,10,10,11,10, + 11, +}; + +static float _vq_quantthresh__44c0_sm_p6_0[] = { + -5.5, 5.5, +}; + +static long _vq_quantmap__44c0_sm_p6_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44c0_sm_p6_0 = { + _vq_quantthresh__44c0_sm_p6_0, + _vq_quantmap__44c0_sm_p6_0, + 3, + 3 +}; + +static static_codebook _44c0_sm_p6_0 = { + 4, 81, + _vq_lengthlist__44c0_sm_p6_0, + 1, -529137664, 1618345984, 2, 0, + _vq_quantlist__44c0_sm_p6_0, + NULL, + &_vq_auxt__44c0_sm_p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c0_sm_p6_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44c0_sm_p6_1[] = { + 2, 4, 4, 6, 6, 7, 7, 7, 7, 7, 8, 9, 5, 5, 6, 6, + 7, 7, 8, 8, 8, 8, 9, 5, 5, 6, 6, 7, 7, 8, 8, 8, + 8,10, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8,10,10,10, 7, + 7, 7, 7, 8, 8, 8, 8,10,10,10, 8, 8, 8, 8, 8, 8, + 8, 8,10,10,10, 8, 8, 8, 8, 8, 8, 8, 8,10,10,10, + 8, 8, 8, 8, 8, 8, 8, 8,10,10,10,10,10, 8, 8, 8, + 8, 8, 8,10,10,10,10,10, 9, 9, 8, 8, 8, 8,10,10, + 10,10,10, 8, 8, 8, 8, 8, 8, +}; + +static float _vq_quantthresh__44c0_sm_p6_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__44c0_sm_p6_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44c0_sm_p6_1 = { + _vq_quantthresh__44c0_sm_p6_1, + _vq_quantmap__44c0_sm_p6_1, + 11, + 11 +}; + +static static_codebook _44c0_sm_p6_1 = { + 2, 121, + _vq_lengthlist__44c0_sm_p6_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__44c0_sm_p6_1, + NULL, + &_vq_auxt__44c0_sm_p6_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c0_sm_p7_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c0_sm_p7_0[] = { + 1, 4, 4, 6, 6, 7, 7, 7, 7, 8, 8, 9, 9, 7, 5, 5, + 7, 7, 8, 8, 8, 8, 9, 9,10,10, 7, 6, 5, 7, 7, 8, + 8, 8, 8, 9, 9,10,10, 0, 8, 8, 8, 8, 9, 9, 9, 9, + 10,10,11,11, 0, 8, 8, 8, 8, 9, 9, 9, 9,10,10,11, + 11, 0,12,12, 9, 9,10,10,10,10,11,11,11,11, 0,13, + 13, 9, 9, 9, 9,10,10,11,11,11,12, 0, 0, 0, 9,10, + 10,10,11,11,12,11,12,12, 0, 0, 0,10,10, 9, 9,11, + 11,12,12,12,12, 0, 0, 0,13,13,10,10,11,11,12,12, + 13,13, 0, 0, 0,14,14,10,10,11,11,12,12,13,13, 0, + 0, 0, 0, 0,11,12,11,11,13,12,13,13, 0, 0, 0, 0, + 0,12,12,11,11,13,12,14,14, +}; + +static float _vq_quantthresh__44c0_sm_p7_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__44c0_sm_p7_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c0_sm_p7_0 = { + _vq_quantthresh__44c0_sm_p7_0, + _vq_quantmap__44c0_sm_p7_0, + 13, + 13 +}; + +static static_codebook _44c0_sm_p7_0 = { + 2, 169, + _vq_lengthlist__44c0_sm_p7_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__44c0_sm_p7_0, + NULL, + &_vq_auxt__44c0_sm_p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c0_sm_p7_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c0_sm_p7_1[] = { + 2, 4, 4, 4, 4, 6, 5, 5, 5, 5, 6, 5, 5, 5, 5, 6, + 6, 6, 5, 5, 6, 6, 6, 5, 5, +}; + +static float _vq_quantthresh__44c0_sm_p7_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c0_sm_p7_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c0_sm_p7_1 = { + _vq_quantthresh__44c0_sm_p7_1, + _vq_quantmap__44c0_sm_p7_1, + 5, + 5 +}; + +static static_codebook _44c0_sm_p7_1 = { + 2, 25, + _vq_lengthlist__44c0_sm_p7_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c0_sm_p7_1, + NULL, + &_vq_auxt__44c0_sm_p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c0_sm_p8_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44c0_sm_p8_0[] = { + 1, 3, 3,11,11,11,11,11,11, 3, 7, 6,11,11,11,11, + 11,11, 4, 8, 7,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12, +}; + +static float _vq_quantthresh__44c0_sm_p8_0[] = { + -773.5, -552.5, -331.5, -110.5, 110.5, 331.5, 552.5, 773.5, +}; + +static long _vq_quantmap__44c0_sm_p8_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44c0_sm_p8_0 = { + _vq_quantthresh__44c0_sm_p8_0, + _vq_quantmap__44c0_sm_p8_0, + 9, + 9 +}; + +static static_codebook _44c0_sm_p8_0 = { + 2, 81, + _vq_lengthlist__44c0_sm_p8_0, + 1, -516186112, 1627103232, 4, 0, + _vq_quantlist__44c0_sm_p8_0, + NULL, + &_vq_auxt__44c0_sm_p8_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c0_sm_p8_1[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c0_sm_p8_1[] = { + 1, 4, 4, 6, 6, 7, 7, 9, 9,10,11,12,12, 6, 5, 5, + 7, 7, 8, 8,10,10,12,11,12,12, 6, 5, 5, 7, 7, 8, + 8,10,10,12,11,12,12,17, 7, 7, 8, 8, 9, 9,10,10, + 12,12,13,13,18, 7, 7, 8, 7, 9, 9,10,10,12,12,12, + 13,19,10,10, 8, 8,10,10,11,11,12,12,13,14,19,11, + 10, 8, 7,10,10,11,11,12,12,13,12,19,19,19,10,10, + 10,10,11,11,12,12,13,13,19,19,19,11, 9,11, 9,14, + 12,13,12,13,13,19,20,18,13,14,11,11,12,12,13,13, + 14,13,20,20,20,15,13,11,10,13,11,13,13,14,13,20, + 20,20,20,20,13,14,12,12,13,13,13,13,20,20,20,20, + 20,13,13,12,12,16,13,15,13, +}; + +static float _vq_quantthresh__44c0_sm_p8_1[] = { + -93.5, -76.5, -59.5, -42.5, -25.5, -8.5, 8.5, 25.5, + 42.5, 59.5, 76.5, 93.5, +}; + +static long _vq_quantmap__44c0_sm_p8_1[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c0_sm_p8_1 = { + _vq_quantthresh__44c0_sm_p8_1, + _vq_quantmap__44c0_sm_p8_1, + 13, + 13 +}; + +static static_codebook _44c0_sm_p8_1 = { + 2, 169, + _vq_lengthlist__44c0_sm_p8_1, + 1, -522616832, 1620115456, 4, 0, + _vq_quantlist__44c0_sm_p8_1, + NULL, + &_vq_auxt__44c0_sm_p8_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c0_sm_p8_2[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44c0_sm_p8_2[] = { + 2, 5, 5, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, + 8,10, 6, 6, 7, 7, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9, + 9, 9,10, 6, 6, 7, 7, 8, 7, 8, 8, 9, 9, 9, 9, 9, + 9, 9, 9,10, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, + 9, 9, 9, 9,10,10,10, 7, 7, 8, 8, 9, 8, 9, 9, 9, + 9,10, 9, 9,10,10,10,11, 8, 8, 8, 8, 9, 9, 9, 9, + 9, 9, 9,10, 9,10,10,10,10, 8, 8, 8, 8, 9, 9, 9, + 9, 9, 9, 9, 9,10,10,11,10,10, 8, 8, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9,10,10,10,10,10,11,11, 8, 8, 9, + 9, 9, 9, 9, 9, 9, 9, 9,10,11,11,11,11,11, 9, 9, + 9, 9, 9, 9, 9, 9,10, 9,10, 9,11,11,10,11,11, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9,10, 9,11,11,10,11,11, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10, 9,11,10,11,11, + 11,11,11, 9, 9,10, 9, 9, 9, 9, 9, 9, 9,10,11,10, + 11,11,11,11,10,10,10,10, 9, 9, 9, 9, 9, 9,10,11, + 11,11,11,11,11, 9,10, 9, 9, 9, 9, 9, 9, 9, 9,11, + 11,10,11,11,11,10,10,10, 9, 9, 9, 9, 9, 9, 9, 9, + 10,11,10,11,11,11,11,11,11, 9, 9, 9, 9, 9, 9, 9, + 9, +}; + +static float _vq_quantthresh__44c0_sm_p8_2[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__44c0_sm_p8_2[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44c0_sm_p8_2 = { + _vq_quantthresh__44c0_sm_p8_2, + _vq_quantmap__44c0_sm_p8_2, + 17, + 17 +}; + +static static_codebook _44c0_sm_p8_2 = { + 2, 289, + _vq_lengthlist__44c0_sm_p8_2, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__44c0_sm_p8_2, + NULL, + &_vq_auxt__44c0_sm_p8_2, + NULL, + 0 +}; + +static long _huff_lengthlist__44c0_sm_short[] = { + 6, 6,12,13,13,14,16,17,17, 4, 2, 5, 8, 7, 9,12, + 15,15, 9, 4, 5, 9, 7, 9,12,16,18,11, 6, 7, 4, 6, + 8,11,14,18,10, 5, 6, 5, 5, 7,10,14,17,10, 5, 7, + 7, 6, 7,10,13,16,11, 5, 7, 7, 7, 8,10,12,15,13, + 6, 7, 5, 5, 7, 9,12,13,16, 8, 9, 6, 6, 7, 9,10, + 12, +}; + +static static_codebook _huff_book__44c0_sm_short = { + 2, 81, + _huff_lengthlist__44c0_sm_short, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__44c1_s_long[] = { + 5, 5, 9,10, 9, 9,10,11,12, 5, 1, 5, 6, 6, 7,10, + 12,14, 9, 5, 6, 8, 8,10,12,14,14,10, 5, 8, 5, 6, + 8,11,13,14, 9, 5, 7, 6, 6, 8,10,12,11, 9, 7, 9, + 7, 6, 6, 7,10,10,10, 9,12, 9, 8, 7, 7,10,12,11, + 11,13,12,10, 9, 8, 9,11,11,14,15,15,13,11, 9, 9, + 11, +}; + +static static_codebook _huff_book__44c1_s_long = { + 2, 81, + _huff_lengthlist__44c1_s_long, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__44c1_s_p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44c1_s_p1_0[] = { + 2, 4, 4, 0, 0, 0, 0, 0, 0, 5, 7, 6, 0, 0, 0, 0, + 0, 0, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, 0, + 0, 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, + 0, 0, 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 7, 7, 0, 0, 0, 0, + 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, 0, + 0, 0, 0, 8, 9,10, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 8, 8, 0, 0, + 0, 0, 0, 0, 8, 9, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 7, 7, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, + 0, 0, 0, 0, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 6, 8, 8, 0, 0, 0, 0, 0, 0, 8,10, 9, 0, + 0, 0, 0, 0, 0, 8, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9, + 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c1_s_p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44c1_s_p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44c1_s_p1_0 = { + _vq_quantthresh__44c1_s_p1_0, + _vq_quantmap__44c1_s_p1_0, + 3, + 3 +}; + +static static_codebook _44c1_s_p1_0 = { + 8, 6561, + _vq_lengthlist__44c1_s_p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44c1_s_p1_0, + NULL, + &_vq_auxt__44c1_s_p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c1_s_p2_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c1_s_p2_0[] = { + 2, 3, 4, 6, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 6, 6, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 4, 5, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 8, 8, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6, 6, 6, 8, 8, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c1_s_p2_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c1_s_p2_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c1_s_p2_0 = { + _vq_quantthresh__44c1_s_p2_0, + _vq_quantmap__44c1_s_p2_0, + 5, + 5 +}; + +static static_codebook _44c1_s_p2_0 = { + 4, 625, + _vq_lengthlist__44c1_s_p2_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c1_s_p2_0, + NULL, + &_vq_auxt__44c1_s_p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c1_s_p3_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44c1_s_p3_0[] = { + 1, 3, 2, 7, 7, 0, 0, 0, 0, 0,13,13, 6, 6, 0, 0, + 0, 0, 0,12, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, 7, 7, + 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0, + 8, 9, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, + 0, 0,11,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c1_s_p3_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44c1_s_p3_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44c1_s_p3_0 = { + _vq_quantthresh__44c1_s_p3_0, + _vq_quantmap__44c1_s_p3_0, + 9, + 9 +}; + +static static_codebook _44c1_s_p3_0 = { + 2, 81, + _vq_lengthlist__44c1_s_p3_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44c1_s_p3_0, + NULL, + &_vq_auxt__44c1_s_p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c1_s_p4_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44c1_s_p4_0[] = { + 1, 3, 3, 6, 5, 6, 6, 8, 8, 0, 0, 0, 7, 7, 7, 7, + 9, 9, 0, 0, 0, 7, 7, 7, 7, 9, 9, 0, 0, 0, 7, 7, + 8, 8,10,10, 0, 0, 0, 7, 7, 8, 8,10,10, 0, 0, 0, + 9, 9, 8, 8,10,10, 0, 0, 0, 8, 8, 8, 8,10,10, 0, + 0, 0,10,10, 9, 9,11,11, 0, 0, 0, 0, 0, 9, 9,11, + 11, +}; + +static float _vq_quantthresh__44c1_s_p4_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44c1_s_p4_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44c1_s_p4_0 = { + _vq_quantthresh__44c1_s_p4_0, + _vq_quantmap__44c1_s_p4_0, + 9, + 9 +}; + +static static_codebook _44c1_s_p4_0 = { + 2, 81, + _vq_lengthlist__44c1_s_p4_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44c1_s_p4_0, + NULL, + &_vq_auxt__44c1_s_p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c1_s_p5_0[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44c1_s_p5_0[] = { + 1, 4, 3, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,10,10,11, + 11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,10,10,10, + 11,11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,10,10, + 10,11,11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,10, + 11,11,11,11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10, + 10,11,11,12,11, 0, 0, 0, 8, 8, 9, 9, 9,10,10,10, + 10,10,11,11,12,12, 0, 0, 0, 8, 8, 9, 9,10, 9,10, + 10,10,10,11,11,12,12, 0, 0, 0, 9, 9, 9, 9,10,10, + 10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0, 9, 9,10, + 10,10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0, 9, 9, + 10,10,10,11,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9, + 9,10,10,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, + 10,10,10,10,11,11,12,12,12,12,13,13, 0, 0, 0, 0, + 0, 0, 0,10,10,11,11,12,12,12,12,13,13, 0, 0, 0, + 0, 0, 0, 0,11,11,12,12,12,12,13,13,13,13, 0, 0, + 0, 0, 0, 0, 0,11,11,11,11,12,12,13,13,13,13, 0, + 0, 0, 0, 0, 0, 0,12,12,12,12,12,12,13,13,14,14, + 0, 0, 0, 0, 0, 0, 0, 0, 0,12,12,12,12,13,13,14, + 14, +}; + +static float _vq_quantthresh__44c1_s_p5_0[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__44c1_s_p5_0[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44c1_s_p5_0 = { + _vq_quantthresh__44c1_s_p5_0, + _vq_quantmap__44c1_s_p5_0, + 17, + 17 +}; + +static static_codebook _44c1_s_p5_0 = { + 2, 289, + _vq_lengthlist__44c1_s_p5_0, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__44c1_s_p5_0, + NULL, + &_vq_auxt__44c1_s_p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c1_s_p6_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44c1_s_p6_0[] = { + 1, 4, 4, 7, 6, 6, 7, 6, 6, 4, 7, 7,10, 9, 9,11, + 9, 9, 4, 7, 7,10, 9, 9,11, 9, 9, 6,10,10,11,11, + 11,11,10,10, 6, 9, 9,11,10,10,11,10,10, 6, 9, 9, + 11,10,11,11,10,10, 7,11,10,11,11,11,12,11,11, 7, + 9, 9,11,10,10,11,11,10, 6, 9, 9,10,10,10,12,10, + 11, +}; + +static float _vq_quantthresh__44c1_s_p6_0[] = { + -5.5, 5.5, +}; + +static long _vq_quantmap__44c1_s_p6_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44c1_s_p6_0 = { + _vq_quantthresh__44c1_s_p6_0, + _vq_quantmap__44c1_s_p6_0, + 3, + 3 +}; + +static static_codebook _44c1_s_p6_0 = { + 4, 81, + _vq_lengthlist__44c1_s_p6_0, + 1, -529137664, 1618345984, 2, 0, + _vq_quantlist__44c1_s_p6_0, + NULL, + &_vq_auxt__44c1_s_p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c1_s_p6_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44c1_s_p6_1[] = { + 2, 3, 3, 6, 6, 7, 7, 7, 7, 8, 8,10,10,10, 6, 6, + 7, 7, 8, 8, 8, 8,10,10,10, 6, 6, 7, 7, 8, 8, 8, + 8,10,10,10, 7, 7, 7, 7, 8, 8, 8, 8,10,10,10, 7, + 7, 7, 7, 8, 8, 8, 8,10,10,10, 7, 7, 8, 8, 8, 8, + 8, 8,10,10,10, 7, 7, 8, 8, 8, 8, 8, 8,10,10,10, + 8, 8, 8, 8, 8, 8, 8, 8,10,10,10,10,10, 8, 8, 8, + 8, 8, 8,10,10,10,10,10, 9, 9, 8, 8, 8, 8,10,10, + 10,10,10, 8, 8, 8, 8, 8, 8, +}; + +static float _vq_quantthresh__44c1_s_p6_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__44c1_s_p6_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44c1_s_p6_1 = { + _vq_quantthresh__44c1_s_p6_1, + _vq_quantmap__44c1_s_p6_1, + 11, + 11 +}; + +static static_codebook _44c1_s_p6_1 = { + 2, 121, + _vq_lengthlist__44c1_s_p6_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__44c1_s_p6_1, + NULL, + &_vq_auxt__44c1_s_p6_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c1_s_p7_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c1_s_p7_0[] = { + 1, 4, 4, 6, 6, 7, 7, 7, 7, 8, 8,10, 9, 7, 5, 6, + 7, 7, 8, 8, 8, 8, 9, 9,10,10, 7, 5, 5, 7, 7, 8, + 8, 8, 8, 9, 9,10,10, 0, 8, 8, 8, 8, 9, 9, 9, 9, + 10,10,11,10, 0, 8, 8, 8, 8, 9, 9, 9, 9,10,10,11, + 11, 0,12,12, 9, 9, 9,10,10,10,11,11,11,11, 0,13, + 13, 9, 9, 9, 9,10,10,11,11,11,11, 0, 0, 0,10,10, + 10,10,11,11,12,11,12,12, 0, 0, 0,10,10,10, 9,11, + 11,12,11,13,12, 0, 0, 0,13,13,10,10,11,11,12,12, + 13,13, 0, 0, 0,14,14,10,10,11,11,12,12,13,13, 0, + 0, 0, 0, 0,11,12,11,11,12,12,14,13, 0, 0, 0, 0, + 0,12,11,11,11,13,10,14,13, +}; + +static float _vq_quantthresh__44c1_s_p7_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__44c1_s_p7_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c1_s_p7_0 = { + _vq_quantthresh__44c1_s_p7_0, + _vq_quantmap__44c1_s_p7_0, + 13, + 13 +}; + +static static_codebook _44c1_s_p7_0 = { + 2, 169, + _vq_lengthlist__44c1_s_p7_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__44c1_s_p7_0, + NULL, + &_vq_auxt__44c1_s_p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c1_s_p7_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c1_s_p7_1[] = { + 2, 3, 3, 5, 5, 6, 6, 6, 5, 5, 6, 6, 6, 5, 5, 6, + 6, 6, 5, 5, 6, 6, 6, 5, 5, +}; + +static float _vq_quantthresh__44c1_s_p7_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c1_s_p7_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c1_s_p7_1 = { + _vq_quantthresh__44c1_s_p7_1, + _vq_quantmap__44c1_s_p7_1, + 5, + 5 +}; + +static static_codebook _44c1_s_p7_1 = { + 2, 25, + _vq_lengthlist__44c1_s_p7_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c1_s_p7_1, + NULL, + &_vq_auxt__44c1_s_p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c1_s_p8_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c1_s_p8_0[] = { + 1, 4, 3,10,10,10,10,10,10,10,10,10,10, 4, 8, 6, + 10,10,10,10,10,10,10,10,10,10, 4, 8, 7,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10, +}; + +static float _vq_quantthresh__44c1_s_p8_0[] = { + -1215.5, -994.5, -773.5, -552.5, -331.5, -110.5, 110.5, 331.5, + 552.5, 773.5, 994.5, 1215.5, +}; + +static long _vq_quantmap__44c1_s_p8_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c1_s_p8_0 = { + _vq_quantthresh__44c1_s_p8_0, + _vq_quantmap__44c1_s_p8_0, + 13, + 13 +}; + +static static_codebook _44c1_s_p8_0 = { + 2, 169, + _vq_lengthlist__44c1_s_p8_0, + 1, -514541568, 1627103232, 4, 0, + _vq_quantlist__44c1_s_p8_0, + NULL, + &_vq_auxt__44c1_s_p8_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c1_s_p8_1[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c1_s_p8_1[] = { + 1, 4, 4, 6, 5, 7, 7, 9, 9,10,10,12,12, 6, 5, 5, + 7, 7, 8, 8,10,10,12,11,12,12, 6, 5, 5, 7, 7, 8, + 8,10,10,11,11,12,12,15, 7, 7, 8, 8, 9, 9,11,11, + 12,12,13,12,15, 8, 8, 8, 7, 9, 9,10,10,12,12,13, + 13,16,11,10, 8, 8,10,10,11,11,12,12,13,13,16,11, + 11, 9, 8,11,10,11,11,12,12,13,12,16,16,16,10,11, + 10,11,12,12,12,12,13,13,16,16,16,11, 9,11, 9,14, + 12,12,12,13,13,16,16,16,12,14,11,12,12,12,13,13, + 14,13,16,16,16,15,13,12,10,13,10,13,14,13,13,16, + 16,16,16,16,13,14,12,13,13,12,13,13,16,16,16,16, + 16,13,12,12,11,14,12,15,13, +}; + +static float _vq_quantthresh__44c1_s_p8_1[] = { + -93.5, -76.5, -59.5, -42.5, -25.5, -8.5, 8.5, 25.5, + 42.5, 59.5, 76.5, 93.5, +}; + +static long _vq_quantmap__44c1_s_p8_1[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c1_s_p8_1 = { + _vq_quantthresh__44c1_s_p8_1, + _vq_quantmap__44c1_s_p8_1, + 13, + 13 +}; + +static static_codebook _44c1_s_p8_1 = { + 2, 169, + _vq_lengthlist__44c1_s_p8_1, + 1, -522616832, 1620115456, 4, 0, + _vq_quantlist__44c1_s_p8_1, + NULL, + &_vq_auxt__44c1_s_p8_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c1_s_p8_2[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44c1_s_p8_2[] = { + 2, 4, 4, 6, 6, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 8, + 8,10,10,10, 7, 7, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9, + 9, 9,10,10,10, 7, 7, 8, 7, 8, 8, 9, 9, 9, 9, 9, + 9, 9, 9,10,10,10, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, + 9,10, 9, 9,10,10,10, 7, 7, 8, 8, 9, 8, 9, 9, 9, + 9,10, 9, 9,10,10,11,11, 8, 8, 8, 8, 9, 9, 9, 9, + 9, 9,10, 9, 9,10,10,10,10, 8, 8, 8, 8, 9, 9, 9, + 9, 9, 9, 9, 9,10,10,11,11,11, 8, 8, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9,10,10,10,10,11,11,11, 8, 8, 9, + 9, 9, 9,10, 9, 9, 9, 9, 9,11,11,11,11,11, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,11,10,10,11,11, 9, + 9, 9, 9, 9, 9, 9, 9, 9,10,10,10,10,11,10,11,11, + 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10, 9,10,10,11,11, + 11,11,11, 9, 9, 9,10, 9, 9, 9, 9, 9, 9,10,11,11, + 11,11,11,11,10,10,10,10, 9, 9, 9, 9, 9, 9,10,11, + 11,11,11,11,11, 9,10, 9, 9, 9, 9,10, 9, 9, 9,11, + 11,11,11,11,11,11,10,10, 9, 9, 9, 9, 9, 9,10, 9, + 11,11,10,11,11,11,11,10,11, 9, 9, 9, 9, 9, 9, 9, + 9, +}; + +static float _vq_quantthresh__44c1_s_p8_2[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__44c1_s_p8_2[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44c1_s_p8_2 = { + _vq_quantthresh__44c1_s_p8_2, + _vq_quantmap__44c1_s_p8_2, + 17, + 17 +}; + +static static_codebook _44c1_s_p8_2 = { + 2, 289, + _vq_lengthlist__44c1_s_p8_2, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__44c1_s_p8_2, + NULL, + &_vq_auxt__44c1_s_p8_2, + NULL, + 0 +}; + +static long _huff_lengthlist__44c1_s_short[] = { + 6, 8,13,12,13,14,15,16,16, 4, 2, 4, 7, 6, 8,11, + 13,15,10, 4, 4, 8, 6, 8,11,14,17,11, 5, 6, 5, 6, + 8,12,14,17,11, 5, 5, 6, 5, 7,10,13,16,12, 6, 7, + 8, 7, 8,10,13,15,13, 8, 8, 7, 7, 8,10,12,15,15, + 7, 7, 5, 5, 7, 9,12,14,15, 8, 8, 6, 6, 7, 8,10, + 11, +}; + +static static_codebook _huff_book__44c1_s_short = { + 2, 81, + _huff_lengthlist__44c1_s_short, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__44c1_sm_long[] = { + 5, 4, 8,10, 9, 9,10,11,12, 4, 2, 5, 6, 6, 8,10, + 11,13, 8, 4, 6, 8, 7, 9,12,12,14,10, 6, 8, 4, 5, + 6, 9,11,12, 9, 5, 6, 5, 5, 6, 9,11,11, 9, 7, 9, + 6, 5, 5, 7,10,10,10, 9,11, 8, 7, 6, 7, 9,11,11, + 12,13,10,10, 9, 8, 9,11,11,15,15,12,13,11, 9,10, + 11, +}; + +static static_codebook _huff_book__44c1_sm_long = { + 2, 81, + _huff_lengthlist__44c1_sm_long, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__44c1_sm_p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44c1_sm_p1_0[] = { + 1, 5, 5, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 0, + 0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 5, 8, 7, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, + 0, 0, 0, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 7, 9, 8, 0, 0, + 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 8, 7, 0, 0, 0, 0, + 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, + 0, 0, 0, 9, 9,10, 0, 0, 0, 0, 0, 0, 9,10,10, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, + 0, 0, 0, 0, 8,10, 9, 0, 0, 0, 0, 0, 0, 9,10,10, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 7, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0, + 0, 0, 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 9,10,10, 0, + 0, 0, 0, 0, 0, 8, 9,10, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 9,10,10, + 0, 0, 0, 0, 0, 0, 9,10, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c1_sm_p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44c1_sm_p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44c1_sm_p1_0 = { + _vq_quantthresh__44c1_sm_p1_0, + _vq_quantmap__44c1_sm_p1_0, + 3, + 3 +}; + +static static_codebook _44c1_sm_p1_0 = { + 8, 6561, + _vq_lengthlist__44c1_sm_p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44c1_sm_p1_0, + NULL, + &_vq_auxt__44c1_sm_p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c1_sm_p2_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c1_sm_p2_0[] = { + 2, 3, 4, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 6, 6, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 4, 4, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6, 6, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c1_sm_p2_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c1_sm_p2_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c1_sm_p2_0 = { + _vq_quantthresh__44c1_sm_p2_0, + _vq_quantmap__44c1_sm_p2_0, + 5, + 5 +}; + +static static_codebook _44c1_sm_p2_0 = { + 4, 625, + _vq_lengthlist__44c1_sm_p2_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c1_sm_p2_0, + NULL, + &_vq_auxt__44c1_sm_p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c1_sm_p3_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44c1_sm_p3_0[] = { + 1, 3, 3, 7, 7, 0, 0, 0, 0, 0, 5, 5, 6, 6, 0, 0, + 0, 0, 0, 5, 5, 7, 7, 0, 0, 0, 0, 0, 7, 7, 7, 7, + 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0, + 8, 9, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, + 0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44c1_sm_p3_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44c1_sm_p3_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44c1_sm_p3_0 = { + _vq_quantthresh__44c1_sm_p3_0, + _vq_quantmap__44c1_sm_p3_0, + 9, + 9 +}; + +static static_codebook _44c1_sm_p3_0 = { + 2, 81, + _vq_lengthlist__44c1_sm_p3_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44c1_sm_p3_0, + NULL, + &_vq_auxt__44c1_sm_p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c1_sm_p4_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44c1_sm_p4_0[] = { + 1, 3, 3, 6, 6, 7, 7, 9, 9, 0, 6, 6, 7, 7, 8, 8, + 9, 9, 0, 6, 6, 7, 7, 8, 8, 9, 9, 0, 7, 7, 8, 8, + 8, 8,10,10, 0, 0, 0, 8, 8, 8, 8,10,10, 0, 0, 0, + 8, 8, 9, 9,11,11, 0, 0, 0, 9, 9, 9, 9,11,11, 0, + 0, 0,10,10,10,10,11,11, 0, 0, 0, 0, 0, 9, 9,11, + 11, +}; + +static float _vq_quantthresh__44c1_sm_p4_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44c1_sm_p4_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44c1_sm_p4_0 = { + _vq_quantthresh__44c1_sm_p4_0, + _vq_quantmap__44c1_sm_p4_0, + 9, + 9 +}; + +static static_codebook _44c1_sm_p4_0 = { + 2, 81, + _vq_lengthlist__44c1_sm_p4_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44c1_sm_p4_0, + NULL, + &_vq_auxt__44c1_sm_p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c1_sm_p5_0[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44c1_sm_p5_0[] = { + 2, 3, 3, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,10,10,11, + 11, 0, 5, 5, 6, 6, 8, 8, 9, 9, 9, 9,10,10,10,10, + 11,11, 0, 5, 5, 6, 6, 8, 8, 9, 9, 9, 9,10,10,10, + 10,11,11, 0, 7, 7, 7, 7, 8, 8, 9, 9, 9, 9,10,10, + 11,11,12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10, + 10,11,11,12,12, 0, 0, 0, 8, 8, 8, 8, 9, 9,10,10, + 10,11,11,11,12,12, 0, 0, 0, 8, 8, 8, 8, 9, 9,10, + 10,10,10,11,11,12,12, 0, 0, 0, 9, 9, 9, 9,10,10, + 10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0, 9, 9,10, + 10,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9, 9, + 9, 9,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9, + 9, 9, 9,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, + 9, 9,10,10,11,11,12,12,12,12,13,13, 0, 0, 0, 0, + 0, 0, 0,10,10,11,11,12,12,12,12,13,13, 0, 0, 0, + 0, 0, 0, 0,11,11,11,11,12,12,13,13,13,13, 0, 0, + 0, 0, 0, 0, 0,11,11,11,11,12,12,13,13,13,13, 0, + 0, 0, 0, 0, 0, 0,11,11,12,12,12,12,13,13,14,14, + 0, 0, 0, 0, 0, 0, 0, 0, 0,12,12,12,12,13,13,14, + 14, +}; + +static float _vq_quantthresh__44c1_sm_p5_0[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__44c1_sm_p5_0[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44c1_sm_p5_0 = { + _vq_quantthresh__44c1_sm_p5_0, + _vq_quantmap__44c1_sm_p5_0, + 17, + 17 +}; + +static static_codebook _44c1_sm_p5_0 = { + 2, 289, + _vq_lengthlist__44c1_sm_p5_0, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__44c1_sm_p5_0, + NULL, + &_vq_auxt__44c1_sm_p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c1_sm_p6_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44c1_sm_p6_0[] = { + 1, 4, 4, 7, 6, 6, 7, 6, 6, 4, 7, 7,10, 9, 9,11, + 9, 9, 4, 7, 7,10, 9, 9,11, 9, 9, 7,10,10,10,11, + 11,11,10,10, 6, 9, 9,11,11,10,11,10,10, 6, 9, 9, + 11,10,11,11,10,10, 7,11,11,11,11,11,11,11,11, 6, + 9, 9,11,10,10,11,11,10, 6, 9, 9,10,10,10,11,10, + 11, +}; + +static float _vq_quantthresh__44c1_sm_p6_0[] = { + -5.5, 5.5, +}; + +static long _vq_quantmap__44c1_sm_p6_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44c1_sm_p6_0 = { + _vq_quantthresh__44c1_sm_p6_0, + _vq_quantmap__44c1_sm_p6_0, + 3, + 3 +}; + +static static_codebook _44c1_sm_p6_0 = { + 4, 81, + _vq_lengthlist__44c1_sm_p6_0, + 1, -529137664, 1618345984, 2, 0, + _vq_quantlist__44c1_sm_p6_0, + NULL, + &_vq_auxt__44c1_sm_p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c1_sm_p6_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44c1_sm_p6_1[] = { + 2, 4, 4, 6, 6, 7, 7, 7, 7, 8, 8,10, 5, 5, 6, 6, + 7, 7, 8, 8, 8, 8,10, 5, 5, 6, 6, 7, 7, 8, 8, 8, + 8,10, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8,10,10,10, 7, + 7, 7, 7, 8, 8, 8, 8,10,10,10, 7, 7, 8, 8, 8, 8, + 8, 8,10,10,10, 7, 7, 8, 8, 8, 8, 8, 8,10,10,10, + 8, 8, 8, 8, 8, 8, 9, 8,10,10,10,10,10, 8, 8, 8, + 8, 8, 8,10,10,10,10,10, 9, 9, 8, 8, 8, 8,10,10, + 10,10,10, 8, 8, 8, 8, 8, 8, +}; + +static float _vq_quantthresh__44c1_sm_p6_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__44c1_sm_p6_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44c1_sm_p6_1 = { + _vq_quantthresh__44c1_sm_p6_1, + _vq_quantmap__44c1_sm_p6_1, + 11, + 11 +}; + +static static_codebook _44c1_sm_p6_1 = { + 2, 121, + _vq_lengthlist__44c1_sm_p6_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__44c1_sm_p6_1, + NULL, + &_vq_auxt__44c1_sm_p6_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c1_sm_p7_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c1_sm_p7_0[] = { + 1, 4, 4, 6, 6, 7, 7, 7, 7, 8, 8, 9, 9, 7, 5, 5, + 7, 7, 8, 8, 8, 8, 9, 9,10,10, 7, 5, 6, 7, 7, 8, + 8, 8, 8, 9, 9,11,10, 0, 8, 8, 8, 8, 9, 9, 9, 9, + 10,10,11,11, 0, 8, 8, 8, 8, 9, 9, 9, 9,10,10,11, + 11, 0,12,12, 9, 9,10,10,10,10,11,11,11,11, 0,13, + 13, 9, 9, 9, 9,10,10,11,11,12,12, 0, 0, 0, 9,10, + 9,10,11,11,12,11,13,12, 0, 0, 0,10,10, 9, 9,11, + 11,12,12,13,12, 0, 0, 0,13,13,10,10,11,11,12,12, + 13,13, 0, 0, 0,14,14,10,10,11,11,12,12,13,13, 0, + 0, 0, 0, 0,11,12,11,11,12,13,14,13, 0, 0, 0, 0, + 0,12,12,11,11,13,12,14,13, +}; + +static float _vq_quantthresh__44c1_sm_p7_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__44c1_sm_p7_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c1_sm_p7_0 = { + _vq_quantthresh__44c1_sm_p7_0, + _vq_quantmap__44c1_sm_p7_0, + 13, + 13 +}; + +static static_codebook _44c1_sm_p7_0 = { + 2, 169, + _vq_lengthlist__44c1_sm_p7_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__44c1_sm_p7_0, + NULL, + &_vq_auxt__44c1_sm_p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c1_sm_p7_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44c1_sm_p7_1[] = { + 2, 4, 4, 4, 5, 6, 5, 5, 5, 5, 6, 5, 5, 5, 5, 6, + 5, 5, 5, 5, 6, 6, 6, 5, 5, +}; + +static float _vq_quantthresh__44c1_sm_p7_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44c1_sm_p7_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44c1_sm_p7_1 = { + _vq_quantthresh__44c1_sm_p7_1, + _vq_quantmap__44c1_sm_p7_1, + 5, + 5 +}; + +static static_codebook _44c1_sm_p7_1 = { + 2, 25, + _vq_lengthlist__44c1_sm_p7_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44c1_sm_p7_1, + NULL, + &_vq_auxt__44c1_sm_p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c1_sm_p8_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c1_sm_p8_0[] = { + 1, 3, 3,13,13,13,13,13,13,13,13,13,13, 3, 6, 6, + 13,13,13,13,13,13,13,13,13,13, 4, 8, 7,13,13,13, + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, + 13,13,13,13,13,13,13,13,13, +}; + +static float _vq_quantthresh__44c1_sm_p8_0[] = { + -1215.5, -994.5, -773.5, -552.5, -331.5, -110.5, 110.5, 331.5, + 552.5, 773.5, 994.5, 1215.5, +}; + +static long _vq_quantmap__44c1_sm_p8_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c1_sm_p8_0 = { + _vq_quantthresh__44c1_sm_p8_0, + _vq_quantmap__44c1_sm_p8_0, + 13, + 13 +}; + +static static_codebook _44c1_sm_p8_0 = { + 2, 169, + _vq_lengthlist__44c1_sm_p8_0, + 1, -514541568, 1627103232, 4, 0, + _vq_quantlist__44c1_sm_p8_0, + NULL, + &_vq_auxt__44c1_sm_p8_0, + NULL, + 0 +}; + +static long _vq_quantlist__44c1_sm_p8_1[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44c1_sm_p8_1[] = { + 1, 4, 4, 6, 6, 7, 7, 9, 9,10,11,12,12, 6, 5, 5, + 7, 7, 8, 7,10,10,11,11,12,12, 6, 5, 5, 7, 7, 8, + 8,10,10,11,11,12,12,16, 7, 7, 8, 8, 9, 9,11,11, + 12,12,13,13,17, 7, 7, 8, 7, 9, 9,11,10,12,12,13, + 13,19,11,10, 8, 8,10,10,11,11,12,12,13,13,19,11, + 11, 9, 7,11,10,11,11,12,12,13,12,19,19,19,10,10, + 10,10,11,12,12,12,13,14,18,19,19,11, 9,11, 9,13, + 12,12,12,13,13,19,20,19,13,15,11,11,12,12,13,13, + 14,13,18,19,20,15,13,12,10,13,10,13,13,13,14,20, + 20,20,20,20,13,14,12,12,13,12,13,13,20,20,20,20, + 20,13,12,12,12,14,12,14,13, +}; + +static float _vq_quantthresh__44c1_sm_p8_1[] = { + -93.5, -76.5, -59.5, -42.5, -25.5, -8.5, 8.5, 25.5, + 42.5, 59.5, 76.5, 93.5, +}; + +static long _vq_quantmap__44c1_sm_p8_1[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44c1_sm_p8_1 = { + _vq_quantthresh__44c1_sm_p8_1, + _vq_quantmap__44c1_sm_p8_1, + 13, + 13 +}; + +static static_codebook _44c1_sm_p8_1 = { + 2, 169, + _vq_lengthlist__44c1_sm_p8_1, + 1, -522616832, 1620115456, 4, 0, + _vq_quantlist__44c1_sm_p8_1, + NULL, + &_vq_auxt__44c1_sm_p8_1, + NULL, + 0 +}; + +static long _vq_quantlist__44c1_sm_p8_2[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44c1_sm_p8_2[] = { + 2, 5, 5, 6, 6, 7, 6, 7, 7, 8, 8, 8, 8, 8, 8, 8, + 8,10, 6, 6, 7, 7, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9, + 9, 9,10, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, + 9, 9, 9,10, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, + 9, 9, 9, 9,10,10,10, 7, 7, 8, 8, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9,10,11,11, 8, 8, 8, 8, 9, 9, 9, 9, + 9, 9,10,10, 9,10,10,10,10, 8, 8, 8, 8, 9, 9, 9, + 9, 9, 9, 9, 9,10,10,11,10,10, 8, 8, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9,10, 9,10,10,10,11,11, 8, 8, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9,11,11,11,11,11, 9, 9, + 9, 9, 9, 9, 9, 9,10, 9,10, 9,11,11,11,11,11, 9, + 8, 9, 9, 9, 9, 9, 9, 9,10,10, 9,11,11,10,11,11, + 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10, 9,11,11,11,11, + 11,11,11, 9, 9,10, 9, 9, 9, 9,10, 9,10,10,11,10, + 11,11,11,11, 9,10,10,10, 9, 9, 9, 9, 9, 9,10,11, + 11,11,11,11,11, 9, 9, 9, 9, 9, 9, 9, 9,10, 9,11, + 11,10,11,11,11,11,10,10, 9, 9, 9, 9, 9, 9,10, 9, + 10,11,10,11,11,11,11,11,11, 9, 9,10, 9, 9, 9, 9, + 9, +}; + +static float _vq_quantthresh__44c1_sm_p8_2[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__44c1_sm_p8_2[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44c1_sm_p8_2 = { + _vq_quantthresh__44c1_sm_p8_2, + _vq_quantmap__44c1_sm_p8_2, + 17, + 17 +}; + +static static_codebook _44c1_sm_p8_2 = { + 2, 289, + _vq_lengthlist__44c1_sm_p8_2, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__44c1_sm_p8_2, + NULL, + &_vq_auxt__44c1_sm_p8_2, + NULL, + 0 +}; + +static long _huff_lengthlist__44c1_sm_short[] = { + 4, 7,13,14,14,15,16,18,18, 4, 2, 5, 8, 7, 9,12, + 15,15,10, 4, 5,10, 6, 8,11,15,17,12, 5, 7, 5, 6, + 8,11,14,17,11, 5, 6, 6, 5, 6, 9,13,17,12, 6, 7, + 6, 5, 6, 8,12,14,14, 7, 8, 6, 6, 7, 9,11,14,14, + 8, 9, 6, 5, 6, 9,11,13,16,10,10, 7, 6, 7, 8,10, + 11, +}; + +static static_codebook _huff_book__44c1_sm_short = { + 2, 81, + _huff_lengthlist__44c1_sm_short, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__44cn1_s_long[] = { + 4, 4, 7, 8, 7, 8,10,12,17, 3, 1, 6, 6, 7, 8,10, + 12,15, 7, 6, 9, 9, 9,11,12,14,17, 8, 6, 9, 6, 7, + 9,11,13,17, 7, 6, 9, 7, 7, 8, 9,12,15, 8, 8,10, + 8, 7, 7, 7,10,14, 9,10,12,10, 8, 8, 8,10,14,11, + 13,15,13,12,11,11,12,16,17,18,18,19,20,18,16,16, + 20, +}; + +static static_codebook _huff_book__44cn1_s_long = { + 2, 81, + _huff_lengthlist__44cn1_s_long, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__44cn1_s_p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44cn1_s_p1_0[] = { + 1, 4, 4, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 0, + 0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 5, 8, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0, 0, + 0, 0, 0, 7, 9,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 8, 8, 0, 0, 0, 0, 0, 0, 7,10, 9, 0, 0, + 0, 0, 0, 0, 8,10, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 8, 8, 0, 0, 0, 0, + 0, 0, 8,10,10, 0, 0, 0, 0, 0, 0, 8, 9,10, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,10,10, 0, 0, 0, + 0, 0, 0, 9, 9,11, 0, 0, 0, 0, 0, 0,10,11,11, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,10,10, 0, 0, + 0, 0, 0, 0, 9,11, 9, 0, 0, 0, 0, 0, 0,10,11,11, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 8, 8, 0, 0, 0, 0, 0, 0, 8,10,10, 0, 0, + 0, 0, 0, 0, 8,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 7,10,10, 0, 0, 0, 0, 0, 0,10,11,11, 0, + 0, 0, 0, 0, 0, 9, 9,11, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7,10,10, 0, 0, 0, 0, 0, 0,10,11,11, + 0, 0, 0, 0, 0, 0, 9,11, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44cn1_s_p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44cn1_s_p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44cn1_s_p1_0 = { + _vq_quantthresh__44cn1_s_p1_0, + _vq_quantmap__44cn1_s_p1_0, + 3, + 3 +}; + +static static_codebook _44cn1_s_p1_0 = { + 8, 6561, + _vq_lengthlist__44cn1_s_p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44cn1_s_p1_0, + NULL, + &_vq_auxt__44cn1_s_p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__44cn1_s_p2_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44cn1_s_p2_0[] = { + 1, 4, 4, 7, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 5, 7, 7, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 5, 5, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 7, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6, 7, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44cn1_s_p2_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44cn1_s_p2_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44cn1_s_p2_0 = { + _vq_quantthresh__44cn1_s_p2_0, + _vq_quantmap__44cn1_s_p2_0, + 5, + 5 +}; + +static static_codebook _44cn1_s_p2_0 = { + 4, 625, + _vq_lengthlist__44cn1_s_p2_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44cn1_s_p2_0, + NULL, + &_vq_auxt__44cn1_s_p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__44cn1_s_p3_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44cn1_s_p3_0[] = { + 1, 2, 3, 7, 7, 0, 0, 0, 0, 0, 0, 0, 6, 6, 0, 0, + 0, 0, 0, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, 7, 7, + 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0, + 9, 8, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, + 0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44cn1_s_p3_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44cn1_s_p3_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44cn1_s_p3_0 = { + _vq_quantthresh__44cn1_s_p3_0, + _vq_quantmap__44cn1_s_p3_0, + 9, + 9 +}; + +static static_codebook _44cn1_s_p3_0 = { + 2, 81, + _vq_lengthlist__44cn1_s_p3_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44cn1_s_p3_0, + NULL, + &_vq_auxt__44cn1_s_p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__44cn1_s_p4_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44cn1_s_p4_0[] = { + 1, 3, 3, 6, 6, 6, 6, 8, 8, 0, 0, 0, 6, 6, 7, 7, + 9, 9, 0, 0, 0, 6, 6, 7, 7, 9, 9, 0, 0, 0, 7, 7, + 8, 8,10,10, 0, 0, 0, 7, 7, 8, 8,10,10, 0, 0, 0, + 9, 9, 9, 9,10,10, 0, 0, 0, 9, 9, 9, 9,10,10, 0, + 0, 0,10,10,10,10,11,11, 0, 0, 0, 0, 0,10,10,11, + 11, +}; + +static float _vq_quantthresh__44cn1_s_p4_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44cn1_s_p4_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44cn1_s_p4_0 = { + _vq_quantthresh__44cn1_s_p4_0, + _vq_quantmap__44cn1_s_p4_0, + 9, + 9 +}; + +static static_codebook _44cn1_s_p4_0 = { + 2, 81, + _vq_lengthlist__44cn1_s_p4_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44cn1_s_p4_0, + NULL, + &_vq_auxt__44cn1_s_p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__44cn1_s_p5_0[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44cn1_s_p5_0[] = { + 1, 4, 3, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,10,10,10, + 10, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,10,10,10, + 11,11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,10,10, + 10,11,11, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10,10, + 11,11,11,12, 0, 0, 0, 7, 7, 8, 8, 9, 9, 9, 9,10, + 10,11,11,11,11, 0, 0, 0, 8, 8, 9, 9, 9, 9,10,10, + 10,10,11,11,12,12, 0, 0, 0, 8, 8, 9, 9, 9, 9,10, + 10,10,11,11,11,12,12, 0, 0, 0, 9, 9,10, 9,10,10, + 10,10,11,11,11,11,12,12, 0, 0, 0, 0, 0, 9, 9,10, + 10,10,10,11,11,12,12,12,12, 0, 0, 0, 0, 0, 9, 9, + 10,10,10,11,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9, + 9,10,10,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, + 10,10,11,10,11,11,11,12,13,12,13,13, 0, 0, 0, 0, + 0, 0, 0,11,10,11,11,12,12,12,12,13,13, 0, 0, 0, + 0, 0, 0, 0,11,11,12,12,12,12,13,13,13,14, 0, 0, + 0, 0, 0, 0, 0,11,11,12,12,12,12,13,13,13,14, 0, + 0, 0, 0, 0, 0, 0,12,12,12,13,13,13,13,13,14,14, + 0, 0, 0, 0, 0, 0, 0, 0, 0,12,12,13,12,13,13,14, + 14, +}; + +static float _vq_quantthresh__44cn1_s_p5_0[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__44cn1_s_p5_0[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44cn1_s_p5_0 = { + _vq_quantthresh__44cn1_s_p5_0, + _vq_quantmap__44cn1_s_p5_0, + 17, + 17 +}; + +static static_codebook _44cn1_s_p5_0 = { + 2, 289, + _vq_lengthlist__44cn1_s_p5_0, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__44cn1_s_p5_0, + NULL, + &_vq_auxt__44cn1_s_p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__44cn1_s_p6_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44cn1_s_p6_0[] = { + 1, 4, 4, 7, 6, 6, 7, 6, 6, 4, 6, 6,10, 9, 9,11, + 9, 9, 4, 6, 6,10, 9, 9,10, 9, 9, 7,10,10,11,11, + 11,12,11,11, 7, 9, 9,11,11,10,11,10,10, 7, 9, 9, + 11,10,11,11,10,10, 7,10,10,11,11,11,12,11,11, 7, + 9, 9,11,10,10,11,10,10, 7, 9, 9,11,10,10,11,10, + 10, +}; + +static float _vq_quantthresh__44cn1_s_p6_0[] = { + -5.5, 5.5, +}; + +static long _vq_quantmap__44cn1_s_p6_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44cn1_s_p6_0 = { + _vq_quantthresh__44cn1_s_p6_0, + _vq_quantmap__44cn1_s_p6_0, + 3, + 3 +}; + +static static_codebook _44cn1_s_p6_0 = { + 4, 81, + _vq_lengthlist__44cn1_s_p6_0, + 1, -529137664, 1618345984, 2, 0, + _vq_quantlist__44cn1_s_p6_0, + NULL, + &_vq_auxt__44cn1_s_p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__44cn1_s_p6_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44cn1_s_p6_1[] = { + 1, 4, 4, 6, 6, 7, 7, 8, 8, 8, 8,10,10,10, 7, 6, + 8, 8, 8, 8, 8, 8,10,10,10, 7, 6, 7, 7, 8, 8, 8, + 8,10,10,10, 7, 7, 8, 8, 8, 8, 8, 8,10,10,10, 7, + 7, 8, 8, 8, 8, 8, 8,10,10,10, 8, 8, 8, 8, 9, 9, + 9, 9,10,10,10, 8, 8, 8, 8, 9, 9, 9, 9,10,10,10, + 9, 9, 9, 9, 9, 9, 9, 9,10,10,10,10,10, 9, 9, 9, + 9, 9, 9,10,10,10,10,10, 9, 9, 9, 9, 9, 9,10,10, + 10,10,10, 9, 9, 9, 9, 9, 9, +}; + +static float _vq_quantthresh__44cn1_s_p6_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__44cn1_s_p6_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44cn1_s_p6_1 = { + _vq_quantthresh__44cn1_s_p6_1, + _vq_quantmap__44cn1_s_p6_1, + 11, + 11 +}; + +static static_codebook _44cn1_s_p6_1 = { + 2, 121, + _vq_lengthlist__44cn1_s_p6_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__44cn1_s_p6_1, + NULL, + &_vq_auxt__44cn1_s_p6_1, + NULL, + 0 +}; + +static long _vq_quantlist__44cn1_s_p7_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44cn1_s_p7_0[] = { + 1, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9,10,10, 6, 5, 5, + 7, 7, 8, 8, 8, 8, 9, 9,11,11, 7, 5, 5, 7, 7, 8, + 8, 8, 8, 9,10,11,11, 0, 8, 8, 8, 8, 9, 9, 9, 9, + 10,10,11,11, 0, 8, 8, 8, 8, 9, 9, 9, 9,10,10,11, + 11, 0,12,12, 9, 9, 9,10,10,10,11,11,11,12, 0,13, + 13, 9, 9, 9, 9,10,10,11,11,11,12, 0, 0, 0,10,10, + 10,10,11,11,12,12,12,13, 0, 0, 0,10,10,10,10,11, + 11,12,12,13,12, 0, 0, 0,14,14,11,10,11,12,12,13, + 13,14, 0, 0, 0,15,15,11,11,12,11,12,12,14,13, 0, + 0, 0, 0, 0,12,12,12,12,13,13,14,14, 0, 0, 0, 0, + 0,13,13,12,12,13,13,13,14, +}; + +static float _vq_quantthresh__44cn1_s_p7_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__44cn1_s_p7_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44cn1_s_p7_0 = { + _vq_quantthresh__44cn1_s_p7_0, + _vq_quantmap__44cn1_s_p7_0, + 13, + 13 +}; + +static static_codebook _44cn1_s_p7_0 = { + 2, 169, + _vq_lengthlist__44cn1_s_p7_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__44cn1_s_p7_0, + NULL, + &_vq_auxt__44cn1_s_p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__44cn1_s_p7_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44cn1_s_p7_1[] = { + 2, 3, 3, 5, 5, 6, 6, 6, 5, 5, 6, 6, 6, 5, 5, 6, + 6, 6, 5, 5, 6, 6, 6, 5, 5, +}; + +static float _vq_quantthresh__44cn1_s_p7_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44cn1_s_p7_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44cn1_s_p7_1 = { + _vq_quantthresh__44cn1_s_p7_1, + _vq_quantmap__44cn1_s_p7_1, + 5, + 5 +}; + +static static_codebook _44cn1_s_p7_1 = { + 2, 25, + _vq_lengthlist__44cn1_s_p7_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44cn1_s_p7_1, + NULL, + &_vq_auxt__44cn1_s_p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__44cn1_s_p8_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44cn1_s_p8_0[] = { + 1, 7, 7,11,11, 8,11,11,11,11, 4,11, 3,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,10,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,10,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11, 7,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,10,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11, 8,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12, +}; + +static float _vq_quantthresh__44cn1_s_p8_0[] = { + -331.5, -110.5, 110.5, 331.5, +}; + +static long _vq_quantmap__44cn1_s_p8_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44cn1_s_p8_0 = { + _vq_quantthresh__44cn1_s_p8_0, + _vq_quantmap__44cn1_s_p8_0, + 5, + 5 +}; + +static static_codebook _44cn1_s_p8_0 = { + 4, 625, + _vq_lengthlist__44cn1_s_p8_0, + 1, -518283264, 1627103232, 3, 0, + _vq_quantlist__44cn1_s_p8_0, + NULL, + &_vq_auxt__44cn1_s_p8_0, + NULL, + 0 +}; + +static long _vq_quantlist__44cn1_s_p8_1[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44cn1_s_p8_1[] = { + 1, 4, 4, 6, 6, 8, 8, 9,10,10,11,11,11, 6, 5, 5, + 7, 7, 8, 8, 9,10, 9,11,11,12, 5, 5, 5, 7, 7, 8, + 9,10,10,12,12,14,13,15, 7, 7, 8, 8, 9,10,11,11, + 10,12,10,11,15, 7, 8, 8, 8, 9, 9,11,11,13,12,12, + 13,15,10,10, 8, 8,10,10,12,12,11,14,10,10,15,11, + 11, 8, 8,10,10,12,13,13,14,15,13,15,15,15,10,10, + 10,10,12,12,13,12,13,10,15,15,15,10,10,11,10,13, + 11,13,13,15,13,15,15,15,13,13,10,11,11,11,12,10, + 14,11,15,15,14,14,13,10,10,12,11,13,13,14,14,15, + 15,15,15,15,11,11,11,11,12,11,15,12,15,15,15,15, + 15,12,12,11,11,14,12,13,14, +}; + +static float _vq_quantthresh__44cn1_s_p8_1[] = { + -93.5, -76.5, -59.5, -42.5, -25.5, -8.5, 8.5, 25.5, + 42.5, 59.5, 76.5, 93.5, +}; + +static long _vq_quantmap__44cn1_s_p8_1[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44cn1_s_p8_1 = { + _vq_quantthresh__44cn1_s_p8_1, + _vq_quantmap__44cn1_s_p8_1, + 13, + 13 +}; + +static static_codebook _44cn1_s_p8_1 = { + 2, 169, + _vq_lengthlist__44cn1_s_p8_1, + 1, -522616832, 1620115456, 4, 0, + _vq_quantlist__44cn1_s_p8_1, + NULL, + &_vq_auxt__44cn1_s_p8_1, + NULL, + 0 +}; + +static long _vq_quantlist__44cn1_s_p8_2[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44cn1_s_p8_2[] = { + 3, 4, 3, 6, 6, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9, 9, + 9,10,11,11, 6, 6, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9, + 9, 9,10,10,10, 6, 6, 7, 7, 8, 8, 9, 9, 9, 9, 9, + 9, 9, 9,10,10,10, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, + 9, 9,10, 9,10,11,10, 7, 6, 7, 7, 8, 8, 9, 9, 9, + 9, 9, 9, 9,10,10,10,11, 7, 7, 8, 8, 8, 8, 9, 9, + 9, 9, 9, 9, 9, 9,10,10,10, 7, 7, 8, 8, 8, 8, 9, + 9, 9, 9, 9, 9, 9,10,11,11,11, 8, 8, 8, 8, 8, 8, + 9, 9, 9, 9, 9, 9, 9, 9,11,10,10,11,11, 8, 8, 8, + 9, 9, 9, 9, 9, 9,10, 9,10,10,10,10,11,11, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,11,11,10,11,11, 9, + 9, 9, 9, 9, 9, 9, 9, 9,10,10,10,10,11,10,11,11, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,11,10,10,11, + 11,11,11, 9, 9, 9, 9, 9, 9, 9, 9,10,10,10,11,11, + 10,11,11,11, 9,10,10, 9, 9, 9, 9, 9, 9, 9,10,11, + 11,11,11,11,11, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,11, + 11,11,11,11,11,11,10,10, 9, 9, 9, 9, 9, 9, 9, 9, + 11,11,11,10,11,11,11,11,11, 9, 9, 9,10, 9, 9, 9, + 9, +}; + +static float _vq_quantthresh__44cn1_s_p8_2[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__44cn1_s_p8_2[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44cn1_s_p8_2 = { + _vq_quantthresh__44cn1_s_p8_2, + _vq_quantmap__44cn1_s_p8_2, + 17, + 17 +}; + +static static_codebook _44cn1_s_p8_2 = { + 2, 289, + _vq_lengthlist__44cn1_s_p8_2, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__44cn1_s_p8_2, + NULL, + &_vq_auxt__44cn1_s_p8_2, + NULL, + 0 +}; + +static long _huff_lengthlist__44cn1_s_short[] = { + 10, 9,12,15,12,13,16,14,16, 7, 1, 5,14, 7,10,13, + 16,16, 9, 4, 6,16, 8,11,16,16,16,14, 4, 7,16, 9, + 12,14,16,16,10, 5, 7,14, 9,12,14,15,15,13, 8, 9, + 14,10,12,13,14,15,13, 9, 9, 7, 6, 8,11,12,12,14, + 8, 8, 5, 4, 5, 8,11,12,16,10,10, 6, 5, 6, 8, 9, + 10, +}; + +static static_codebook _huff_book__44cn1_s_short = { + 2, 81, + _huff_lengthlist__44cn1_s_short, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__44cn1_sm_long[] = { + 3, 3, 8, 8, 8, 8,10,12,14, 3, 2, 6, 7, 7, 8,10, + 12,16, 7, 6, 7, 9, 8,10,12,14,16, 8, 6, 8, 4, 5, + 7, 9,11,13, 7, 6, 8, 5, 6, 7, 9,11,14, 8, 8,10, + 7, 7, 6, 8,10,13, 9,11,12, 9, 9, 7, 8,10,12,10, + 13,15,11,11,10, 9,10,13,13,16,17,14,15,14,13,14, + 17, +}; + +static static_codebook _huff_book__44cn1_sm_long = { + 2, 81, + _huff_lengthlist__44cn1_sm_long, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__44cn1_sm_p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44cn1_sm_p1_0[] = { + 1, 4, 5, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 0, + 0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 5, 8, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0, 0, + 0, 0, 0, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 8, 8, 0, 0, 0, 0, 0, 0, 7, 9, 8, 0, 0, + 0, 0, 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 8, 8, 0, 0, 0, 0, + 0, 0, 8,10, 9, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,10, 9, 0, 0, 0, + 0, 0, 0, 9, 9,10, 0, 0, 0, 0, 0, 0, 9,10,10, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 9, 0, 0, + 0, 0, 0, 0, 8,10, 9, 0, 0, 0, 0, 0, 0, 9,10,10, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 8, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0, + 0, 0, 0, 0, 8, 9,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 7, 9, 9, 0, 0, 0, 0, 0, 0, 9,10,10, 0, + 0, 0, 0, 0, 0, 8, 9,10, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7, 9,10, 0, 0, 0, 0, 0, 0, 9,10,10, + 0, 0, 0, 0, 0, 0, 9,10, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44cn1_sm_p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44cn1_sm_p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44cn1_sm_p1_0 = { + _vq_quantthresh__44cn1_sm_p1_0, + _vq_quantmap__44cn1_sm_p1_0, + 3, + 3 +}; + +static static_codebook _44cn1_sm_p1_0 = { + 8, 6561, + _vq_lengthlist__44cn1_sm_p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44cn1_sm_p1_0, + NULL, + &_vq_auxt__44cn1_sm_p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__44cn1_sm_p2_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44cn1_sm_p2_0[] = { + 1, 4, 4, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 5, 7, 7, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 5, 5, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 7, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7, 7, 7, 9, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44cn1_sm_p2_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44cn1_sm_p2_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44cn1_sm_p2_0 = { + _vq_quantthresh__44cn1_sm_p2_0, + _vq_quantmap__44cn1_sm_p2_0, + 5, + 5 +}; + +static static_codebook _44cn1_sm_p2_0 = { + 4, 625, + _vq_lengthlist__44cn1_sm_p2_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44cn1_sm_p2_0, + NULL, + &_vq_auxt__44cn1_sm_p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__44cn1_sm_p3_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44cn1_sm_p3_0[] = { + 1, 3, 4, 7, 7, 0, 0, 0, 0, 0, 4, 4, 7, 7, 0, 0, + 0, 0, 0, 4, 5, 7, 7, 0, 0, 0, 0, 0, 6, 7, 8, 8, + 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 0, 0, 0, 0, 0, 0, 0,10, 9, 0, 0, 0, 0, 0, + 0, 0,11,11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + +static float _vq_quantthresh__44cn1_sm_p3_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44cn1_sm_p3_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44cn1_sm_p3_0 = { + _vq_quantthresh__44cn1_sm_p3_0, + _vq_quantmap__44cn1_sm_p3_0, + 9, + 9 +}; + +static static_codebook _44cn1_sm_p3_0 = { + 2, 81, + _vq_lengthlist__44cn1_sm_p3_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44cn1_sm_p3_0, + NULL, + &_vq_auxt__44cn1_sm_p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__44cn1_sm_p4_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44cn1_sm_p4_0[] = { + 1, 4, 3, 6, 6, 7, 7, 9, 9, 0, 5, 5, 7, 7, 8, 7, + 9, 9, 0, 5, 5, 7, 7, 8, 8, 9, 9, 0, 7, 7, 8, 8, + 8, 8,10,10, 0, 0, 0, 8, 8, 8, 8,10,10, 0, 0, 0, + 9, 9, 9, 9,10,10, 0, 0, 0, 9, 9, 9, 9,10,10, 0, + 0, 0,10,10,10,10,11,11, 0, 0, 0, 0, 0,10,10,11, + 11, +}; + +static float _vq_quantthresh__44cn1_sm_p4_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44cn1_sm_p4_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44cn1_sm_p4_0 = { + _vq_quantthresh__44cn1_sm_p4_0, + _vq_quantmap__44cn1_sm_p4_0, + 9, + 9 +}; + +static static_codebook _44cn1_sm_p4_0 = { + 2, 81, + _vq_lengthlist__44cn1_sm_p4_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44cn1_sm_p4_0, + NULL, + &_vq_auxt__44cn1_sm_p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__44cn1_sm_p5_0[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44cn1_sm_p5_0[] = { + 1, 4, 4, 6, 6, 8, 8, 9, 9, 8, 8, 9, 9,10,10,11, + 11, 0, 6, 6, 7, 7, 8, 8, 9, 9, 9, 9,10,10,11,11, + 12,12, 0, 6, 5, 7, 7, 8, 8, 9, 9, 9, 9,10,10,11, + 11,12,12, 0, 7, 7, 7, 7, 8, 8, 9, 9, 9, 9,10,10, + 11,11,12,12, 0, 0, 0, 7, 7, 8, 8, 9, 9,10,10,11, + 11,11,11,12,12, 0, 0, 0, 8, 8, 9, 9,10,10,10,10, + 11,11,12,12,12,12, 0, 0, 0, 8, 8, 9, 9,10,10,10, + 10,11,11,12,12,12,12, 0, 0, 0, 9, 9, 9, 9,10,10, + 10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9, 9,10, + 10,10,10,11,11,12,12,13,13, 0, 0, 0, 0, 0, 9, 9, + 10,10,11,11,12,12,13,13,13,13, 0, 0, 0, 0, 0, 9, + 9,10,10,11,11,12,12,12,13,13,13, 0, 0, 0, 0, 0, + 10,10,11,11,11,11,12,12,13,13,14,14, 0, 0, 0, 0, + 0, 0, 0,11,11,11,11,12,12,13,13,14,14, 0, 0, 0, + 0, 0, 0, 0,11,11,12,12,13,13,13,13,14,14, 0, 0, + 0, 0, 0, 0, 0,11,11,12,12,13,13,13,13,14,14, 0, + 0, 0, 0, 0, 0, 0,12,12,12,13,13,13,14,14,14,14, + 0, 0, 0, 0, 0, 0, 0, 0, 0,12,12,13,13,14,14,14, + 14, +}; + +static float _vq_quantthresh__44cn1_sm_p5_0[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__44cn1_sm_p5_0[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44cn1_sm_p5_0 = { + _vq_quantthresh__44cn1_sm_p5_0, + _vq_quantmap__44cn1_sm_p5_0, + 17, + 17 +}; + +static static_codebook _44cn1_sm_p5_0 = { + 2, 289, + _vq_lengthlist__44cn1_sm_p5_0, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__44cn1_sm_p5_0, + NULL, + &_vq_auxt__44cn1_sm_p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__44cn1_sm_p6_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44cn1_sm_p6_0[] = { + 1, 4, 4, 7, 6, 6, 7, 6, 6, 4, 7, 6,10, 9, 9,11, + 9, 9, 4, 6, 7,10, 9, 9,11, 9, 9, 7,10,10,10,11, + 11,11,11,10, 6, 9, 9,11,10,10,11,10,10, 6, 9, 9, + 11,10,11,11,10,10, 7,11,11,11,11,11,12,11,11, 7, + 9, 9,11,10,10,12,10,10, 7, 9, 9,11,10,10,11,10, + 10, +}; + +static float _vq_quantthresh__44cn1_sm_p6_0[] = { + -5.5, 5.5, +}; + +static long _vq_quantmap__44cn1_sm_p6_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44cn1_sm_p6_0 = { + _vq_quantthresh__44cn1_sm_p6_0, + _vq_quantmap__44cn1_sm_p6_0, + 3, + 3 +}; + +static static_codebook _44cn1_sm_p6_0 = { + 4, 81, + _vq_lengthlist__44cn1_sm_p6_0, + 1, -529137664, 1618345984, 2, 0, + _vq_quantlist__44cn1_sm_p6_0, + NULL, + &_vq_auxt__44cn1_sm_p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__44cn1_sm_p6_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44cn1_sm_p6_1[] = { + 2, 4, 4, 5, 5, 7, 7, 7, 7, 8, 8,10, 5, 5, 6, 6, + 7, 7, 8, 8, 8, 8,10, 5, 5, 6, 6, 7, 7, 8, 8, 8, + 8,10, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8,10,10,10, 7, + 7, 7, 7, 8, 8, 8, 8,10,10,10, 8, 8, 8, 8, 8, 8, + 8, 8,10,10,10, 8, 8, 8, 8, 8, 8, 8, 8,10,10,10, + 8, 8, 8, 8, 8, 8, 9, 9,10,10,10,10,10, 8, 8, 8, + 8, 9, 9,10,10,10,10,10, 9, 9, 9, 9, 8, 9,10,10, + 10,10,10, 8, 9, 8, 8, 9, 8, +}; + +static float _vq_quantthresh__44cn1_sm_p6_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__44cn1_sm_p6_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44cn1_sm_p6_1 = { + _vq_quantthresh__44cn1_sm_p6_1, + _vq_quantmap__44cn1_sm_p6_1, + 11, + 11 +}; + +static static_codebook _44cn1_sm_p6_1 = { + 2, 121, + _vq_lengthlist__44cn1_sm_p6_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__44cn1_sm_p6_1, + NULL, + &_vq_auxt__44cn1_sm_p6_1, + NULL, + 0 +}; + +static long _vq_quantlist__44cn1_sm_p7_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44cn1_sm_p7_0[] = { + 1, 4, 4, 6, 6, 7, 7, 7, 7, 9, 9,10,10, 7, 5, 5, + 7, 7, 8, 8, 8, 8,10, 9,11,10, 7, 5, 5, 7, 7, 8, + 8, 8, 8, 9,10,11,11, 0, 8, 8, 8, 8, 9, 9, 9, 9, + 10,10,11,11, 0, 8, 8, 8, 8, 9, 9, 9, 9,10,10,11, + 11, 0,12,12, 9, 9, 9,10,10,10,11,11,12,12, 0,13, + 13, 9, 9, 9, 9,10,10,11,11,12,12, 0, 0, 0,10,10, + 10,10,11,11,12,12,12,13, 0, 0, 0,10,10,10,10,11, + 11,12,12,12,12, 0, 0, 0,14,14,11,11,11,11,12,13, + 13,13, 0, 0, 0,14,14,11,10,11,11,12,12,13,13, 0, + 0, 0, 0, 0,12,12,12,12,13,13,13,14, 0, 0, 0, 0, + 0,13,12,12,12,13,13,13,14, +}; + +static float _vq_quantthresh__44cn1_sm_p7_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__44cn1_sm_p7_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44cn1_sm_p7_0 = { + _vq_quantthresh__44cn1_sm_p7_0, + _vq_quantmap__44cn1_sm_p7_0, + 13, + 13 +}; + +static static_codebook _44cn1_sm_p7_0 = { + 2, 169, + _vq_lengthlist__44cn1_sm_p7_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__44cn1_sm_p7_0, + NULL, + &_vq_auxt__44cn1_sm_p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__44cn1_sm_p7_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44cn1_sm_p7_1[] = { + 2, 4, 4, 4, 5, 6, 5, 5, 5, 5, 6, 5, 5, 5, 5, 6, + 5, 5, 5, 5, 6, 6, 6, 5, 5, +}; + +static float _vq_quantthresh__44cn1_sm_p7_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44cn1_sm_p7_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44cn1_sm_p7_1 = { + _vq_quantthresh__44cn1_sm_p7_1, + _vq_quantmap__44cn1_sm_p7_1, + 5, + 5 +}; + +static static_codebook _44cn1_sm_p7_1 = { + 2, 25, + _vq_lengthlist__44cn1_sm_p7_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44cn1_sm_p7_1, + NULL, + &_vq_auxt__44cn1_sm_p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__44cn1_sm_p8_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44cn1_sm_p8_0[] = { + 1, 4, 4,12,11,13,13,14,14, 4, 7, 7,11,13,14,14, + 14,14, 3, 8, 3,14,14,14,14,14,14,14,10,12,14,14, + 14,14,14,14,14,14, 5,14, 8,14,14,14,14,14,12,14, + 13,14,14,14,14,14,14,14,13,14,10,14,14,14,14,14, + 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, + 14, +}; + +static float _vq_quantthresh__44cn1_sm_p8_0[] = { + -773.5, -552.5, -331.5, -110.5, 110.5, 331.5, 552.5, 773.5, +}; + +static long _vq_quantmap__44cn1_sm_p8_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44cn1_sm_p8_0 = { + _vq_quantthresh__44cn1_sm_p8_0, + _vq_quantmap__44cn1_sm_p8_0, + 9, + 9 +}; + +static static_codebook _44cn1_sm_p8_0 = { + 2, 81, + _vq_lengthlist__44cn1_sm_p8_0, + 1, -516186112, 1627103232, 4, 0, + _vq_quantlist__44cn1_sm_p8_0, + NULL, + &_vq_auxt__44cn1_sm_p8_0, + NULL, + 0 +}; + +static long _vq_quantlist__44cn1_sm_p8_1[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44cn1_sm_p8_1[] = { + 1, 4, 4, 6, 6, 8, 8, 9, 9,10,11,11,11, 6, 5, 5, + 7, 7, 8, 8,10,10,10,11,11,11, 6, 5, 5, 7, 7, 8, + 8,10,10,11,12,12,12,14, 7, 7, 7, 8, 9, 9,11,11, + 11,12,11,12,17, 7, 7, 8, 7, 9, 9,11,11,12,12,12, + 12,14,11,11, 8, 8,10,10,11,12,12,13,11,12,14,11, + 11, 8, 8,10,10,11,12,12,13,13,12,14,15,14,10,10, + 10,10,11,12,12,12,12,11,14,13,16,10,10,10, 9,12, + 11,12,12,13,14,14,15,14,14,13,10,10,11,11,12,11, + 13,11,14,12,15,13,14,11,10,12,10,12,12,13,13,13, + 13,14,15,15,12,12,11,11,12,11,13,12,14,14,14,14, + 17,12,12,11,10,13,11,13,13, +}; + +static float _vq_quantthresh__44cn1_sm_p8_1[] = { + -93.5, -76.5, -59.5, -42.5, -25.5, -8.5, 8.5, 25.5, + 42.5, 59.5, 76.5, 93.5, +}; + +static long _vq_quantmap__44cn1_sm_p8_1[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44cn1_sm_p8_1 = { + _vq_quantthresh__44cn1_sm_p8_1, + _vq_quantmap__44cn1_sm_p8_1, + 13, + 13 +}; + +static static_codebook _44cn1_sm_p8_1 = { + 2, 169, + _vq_lengthlist__44cn1_sm_p8_1, + 1, -522616832, 1620115456, 4, 0, + _vq_quantlist__44cn1_sm_p8_1, + NULL, + &_vq_auxt__44cn1_sm_p8_1, + NULL, + 0 +}; + +static long _vq_quantlist__44cn1_sm_p8_2[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44cn1_sm_p8_2[] = { + 3, 4, 4, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, + 9,10, 6, 6, 6, 6, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, + 9, 9,10, 6, 6, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, 9, + 9, 9, 9,10, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, + 9, 9, 9, 9,10,10,10, 7, 7, 7, 8, 8, 8, 9, 9, 9, + 9, 9, 9, 9, 9,10,10,10, 8, 8, 8, 8, 8, 8, 9, 9, + 9, 9, 9, 9, 9, 9,10,10,10, 8, 8, 8, 8, 8, 8, 9, + 9, 9, 9, 9, 9, 9, 9,11,10,11, 8, 8, 8, 8, 8, 8, + 9, 9, 9, 9, 9, 9, 9, 9,10,10,10,11,11, 8, 8, 8, + 8, 9, 9, 9, 9, 9, 9, 9, 9,11,10,11,11,11, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,11,10,11,11, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,11,11,10,11,11, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,11,10,11,11, + 11,11,11, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,11,11, + 11,11,11,11, 9,10,10,10, 9, 9, 9, 9, 9, 9,11,10, + 11,11,11,11,11, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,11, + 11,11,11,11,11,11,10,10, 9, 9, 9, 9, 9, 9, 9, 9, + 10,11,11,11,11,11,11,11,11, 9, 9, 9, 9, 9, 9, 9, + 9, +}; + +static float _vq_quantthresh__44cn1_sm_p8_2[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__44cn1_sm_p8_2[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44cn1_sm_p8_2 = { + _vq_quantthresh__44cn1_sm_p8_2, + _vq_quantmap__44cn1_sm_p8_2, + 17, + 17 +}; + +static static_codebook _44cn1_sm_p8_2 = { + 2, 289, + _vq_lengthlist__44cn1_sm_p8_2, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__44cn1_sm_p8_2, + NULL, + &_vq_auxt__44cn1_sm_p8_2, + NULL, + 0 +}; + +static long _huff_lengthlist__44cn1_sm_short[] = { + 5, 6,12,14,12,14,16,17,18, 4, 2, 5,11, 7,10,12, + 14,15, 9, 4, 5,11, 7,10,13,15,18,15, 6, 7, 5, 6, + 8,11,13,16,11, 5, 6, 5, 5, 6, 9,13,15,12, 5, 7, + 6, 5, 6, 9,12,14,12, 6, 7, 8, 6, 7, 9,12,13,14, + 8, 8, 7, 5, 5, 8,10,12,16, 9, 9, 8, 6, 6, 7, 9, + 9, +}; + +static static_codebook _huff_book__44cn1_sm_short = { + 2, 81, + _huff_lengthlist__44cn1_sm_short, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/books/floor/floor_books.h b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/books/floor/floor_books.h new file mode 100644 index 0000000..fd838f7 --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/books/floor/floor_books.h @@ -0,0 +1,1838 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the Xiph.Org Foundation http://www.xiph.org/ * + * * + ******************************************************************** + + function: static codebooks autogenerated by huff/huffbuld + last modified: $Id: floor_books.h 7187 2004-07-20 07:24:27Z xiphmont $ + + ********************************************************************/ + +#include "codebook.h" + +static long _huff_lengthlist_line_256x7_0sub1[] = { + 0, 2, 3, 3, 3, 3, 4, 3, 4, +}; + +static static_codebook _huff_book_line_256x7_0sub1 = { + 1, 9, + _huff_lengthlist_line_256x7_0sub1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_256x7_0sub2[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 3, 4, 3, 5, 3, + 6, 3, 6, 4, 6, 4, 7, 5, 7, +}; + +static static_codebook _huff_book_line_256x7_0sub2 = { + 1, 25, + _huff_lengthlist_line_256x7_0sub2, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_256x7_0sub3[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 2, 5, 3, 5, 3, + 6, 3, 6, 4, 7, 6, 7, 8, 7, 9, 8, 9, 9, 9,10, 9, + 11,13,11,13,10,10,13,13,13,13,13,13,12,12,12,12, +}; + +static static_codebook _huff_book_line_256x7_0sub3 = { + 1, 64, + _huff_lengthlist_line_256x7_0sub3, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_256x7_1sub1[] = { + 0, 3, 3, 3, 3, 2, 4, 3, 4, +}; + +static static_codebook _huff_book_line_256x7_1sub1 = { + 1, 9, + _huff_lengthlist_line_256x7_1sub1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_256x7_1sub2[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 3, 4, 3, 4, 4, + 5, 4, 6, 5, 6, 7, 6, 8, 8, +}; + +static static_codebook _huff_book_line_256x7_1sub2 = { + 1, 25, + _huff_lengthlist_line_256x7_1sub2, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_256x7_1sub3[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 4, 3, 6, 3, 7, + 3, 8, 5, 8, 6, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, +}; + +static static_codebook _huff_book_line_256x7_1sub3 = { + 1, 64, + _huff_lengthlist_line_256x7_1sub3, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_256x7_class0[] = { + 7, 5, 5, 9, 9, 6, 6, 9,12, 8, 7, 8,11, 8, 9,15, + 6, 3, 3, 7, 7, 4, 3, 6, 9, 6, 5, 6, 8, 6, 8,15, + 8, 5, 5, 9, 8, 5, 4, 6,10, 7, 5, 5,11, 8, 7,15, + 14,15,13,13,13,13, 8,11,15,10, 7, 6,11, 9,10,15, +}; + +static static_codebook _huff_book_line_256x7_class0 = { + 1, 64, + _huff_lengthlist_line_256x7_class0, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_256x7_class1[] = { + 5, 6, 8,15, 6, 9,10,15,10,11,12,15,15,15,15,15, + 4, 6, 7,15, 6, 7, 8,15, 9, 8, 9,15,15,15,15,15, + 6, 8, 9,15, 7, 7, 8,15,10, 9,10,15,15,15,15,15, + 15,13,15,15,15,10,11,15,15,13,13,15,15,15,15,15, + 4, 6, 7,15, 6, 8, 9,15,10,10,12,15,15,15,15,15, + 2, 5, 6,15, 5, 6, 7,15, 8, 6, 7,15,15,15,15,15, + 5, 6, 8,15, 5, 6, 7,15, 9, 6, 7,15,15,15,15,15, + 14,12,13,15,12,10,11,15,15,15,15,15,15,15,15,15, + 7, 8, 9,15, 9,10,10,15,15,14,14,15,15,15,15,15, + 5, 6, 7,15, 7, 8, 9,15,12, 9,10,15,15,15,15,15, + 7, 7, 9,15, 7, 7, 8,15,12, 8, 9,15,15,15,15,15, + 13,13,14,15,12,11,12,15,15,15,15,15,15,15,15,15, + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, + 13,13,13,15,15,15,15,15,15,15,15,15,15,15,15,15, + 15,12,13,15,15,12,13,15,15,14,15,15,15,15,15,15, + 15,15,15,15,15,15,13,15,15,15,15,15,15,15,15,15, +}; + +static static_codebook _huff_book_line_256x7_class1 = { + 1, 256, + _huff_lengthlist_line_256x7_class1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_512x17_0sub0[] = { + 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 6, 5, 6, 6, 6, 6, 5, 6, 6, 7, 6, 7, 6, 7, 6, + 7, 6, 8, 7, 8, 7, 8, 7, 8, 7, 8, 7, 9, 7, 9, 7, + 9, 7, 9, 8, 9, 8,10, 8,10, 8,10, 7,10, 6,10, 8, + 10, 8,11, 7,10, 7,11, 8,11,11,12,12,11,11,12,11, + 13,11,13,11,13,12,15,12,13,13,14,14,14,14,14,15, + 15,15,16,14,17,19,19,18,18,18,18,18,18,18,18,18, + 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18, +}; + +static static_codebook _huff_book_line_512x17_0sub0 = { + 1, 128, + _huff_lengthlist_line_512x17_0sub0, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_512x17_1sub0[] = { + 2, 4, 5, 4, 5, 4, 5, 4, 5, 5, 5, 5, 5, 5, 6, 5, + 6, 5, 6, 6, 7, 6, 7, 6, 8, 7, 8, 7, 8, 7, 8, 7, +}; + +static static_codebook _huff_book_line_512x17_1sub0 = { + 1, 32, + _huff_lengthlist_line_512x17_1sub0, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_512x17_1sub1[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 4, 3, 5, 3, 5, 4, 5, 4, 5, 4, 5, 5, 5, 5, 6, 5, + 6, 5, 7, 5, 8, 6, 8, 6, 8, 6, 8, 6, 8, 7, 9, 7, + 9, 7,11, 9,11,11,12,11,14,12,14,16,14,16,13,16, + 14,16,12,15,13,16,14,16,13,14,12,15,13,15,13,13, + 13,15,12,14,14,15,13,15,12,15,15,15,15,15,15,15, + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, +}; + +static static_codebook _huff_book_line_512x17_1sub1 = { + 1, 128, + _huff_lengthlist_line_512x17_1sub1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_512x17_2sub1[] = { + 0, 4, 5, 4, 4, 4, 5, 4, 4, 4, 5, 4, 5, 4, 5, 3, + 5, 3, +}; + +static static_codebook _huff_book_line_512x17_2sub1 = { + 1, 18, + _huff_lengthlist_line_512x17_2sub1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_512x17_2sub2[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 3, 4, 3, 4, 4, 5, 4, 5, 4, 6, 4, 6, 5, + 6, 5, 7, 5, 7, 6, 8, 6, 8, 6, 8, 7, 8, 7, 9, 7, + 9, 8, +}; + +static static_codebook _huff_book_line_512x17_2sub2 = { + 1, 50, + _huff_lengthlist_line_512x17_2sub2, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_512x17_2sub3[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 3, 3, 3, 3, 4, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 7, 8, 8,11, 8, 9, 9, 9,10,11,11,11, 9,10,10,11, + 11,11,11,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, +}; + +static static_codebook _huff_book_line_512x17_2sub3 = { + 1, 128, + _huff_lengthlist_line_512x17_2sub3, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_512x17_3sub1[] = { + 0, 4, 4, 4, 4, 4, 4, 3, 4, 4, 4, 4, 4, 5, 4, 5, + 5, 5, +}; + +static static_codebook _huff_book_line_512x17_3sub1 = { + 1, 18, + _huff_lengthlist_line_512x17_3sub1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_512x17_3sub2[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 3, 3, 4, 3, 5, 4, 6, 4, 6, 5, 7, 6, 7, + 6, 8, 6, 8, 7, 9, 8,10, 8,12, 9,13,10,15,10,15, + 11,14, +}; + +static static_codebook _huff_book_line_512x17_3sub2 = { + 1, 50, + _huff_lengthlist_line_512x17_3sub2, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_512x17_3sub3[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 8, 4, 8, 4, 8, 4, 8, 5, 8, 5, 8, 6, 8, + 4, 8, 4, 8, 5, 8, 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, +}; + +static static_codebook _huff_book_line_512x17_3sub3 = { + 1, 128, + _huff_lengthlist_line_512x17_3sub3, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_512x17_class1[] = { + 1, 2, 3, 6, 5, 4, 7, 7, +}; + +static static_codebook _huff_book_line_512x17_class1 = { + 1, 8, + _huff_lengthlist_line_512x17_class1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_512x17_class2[] = { + 3, 3, 3,14, 5, 4, 4,11, 8, 6, 6,10,17,12,11,17, + 6, 5, 5,15, 5, 3, 4,11, 8, 5, 5, 8,16, 9,10,14, + 10, 8, 9,17, 8, 6, 6,13,10, 7, 7,10,16,11,13,14, + 17,17,17,17,17,16,16,16,16,15,16,16,16,16,16,16, +}; + +static static_codebook _huff_book_line_512x17_class2 = { + 1, 64, + _huff_lengthlist_line_512x17_class2, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_512x17_class3[] = { + 2, 4, 6,17, 4, 5, 7,17, 8, 7,10,17,17,17,17,17, + 3, 4, 6,15, 3, 3, 6,15, 7, 6, 9,17,17,17,17,17, + 6, 8,10,17, 6, 6, 8,16, 9, 8,10,17,17,15,16,17, + 17,17,17,17,12,15,15,16,12,15,15,16,16,16,16,16, +}; + +static static_codebook _huff_book_line_512x17_class3 = { + 1, 64, + _huff_lengthlist_line_512x17_class3, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x4_class0[] = { + 7, 7, 7,11, 6, 6, 7,11, 7, 6, 6,10,12,10,10,13, + 7, 7, 8,11, 7, 7, 7,11, 7, 6, 7,10,11,10,10,13, + 10,10, 9,12, 9, 9, 9,11, 8, 8, 8,11,13,11,10,14, + 15,15,14,15,15,14,13,14,15,12,12,17,17,17,17,17, + 7, 7, 6, 9, 6, 6, 6, 9, 7, 6, 6, 8,11,11,10,12, + 7, 7, 7, 9, 7, 6, 6, 9, 7, 6, 6, 9,13,10,10,11, + 10, 9, 8,10, 9, 8, 8,10, 8, 8, 7, 9,13,12,10,11, + 17,14,14,13,15,14,12,13,17,13,12,15,17,17,14,17, + 7, 6, 6, 7, 6, 6, 5, 7, 6, 6, 6, 6,11, 9, 9, 9, + 7, 7, 6, 7, 7, 6, 6, 7, 6, 6, 6, 6,10, 9, 8, 9, + 10, 9, 8, 8, 9, 8, 7, 8, 8, 7, 6, 8,11,10, 9,10, + 17,17,12,15,15,15,12,14,14,14,10,12,15,13,12,13, + 11,10, 8,10,11,10, 8, 8,10, 9, 7, 7,10, 9, 9,11, + 11,11, 9,10,11,10, 8, 9,10, 8, 6, 8,10, 9, 9,11, + 14,13,10,12,12,11,10,10, 8, 7, 8,10,10,11,11,12, + 17,17,15,17,17,17,17,17,17,13,12,17,17,17,14,17, +}; + +static static_codebook _huff_book_line_128x4_class0 = { + 1, 256, + _huff_lengthlist_line_128x4_class0, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x4_0sub0[] = { + 2, 2, 2, 2, +}; + +static static_codebook _huff_book_line_128x4_0sub0 = { + 1, 4, + _huff_lengthlist_line_128x4_0sub0, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x4_0sub1[] = { + 0, 0, 0, 0, 3, 2, 3, 2, 3, 3, +}; + +static static_codebook _huff_book_line_128x4_0sub1 = { + 1, 10, + _huff_lengthlist_line_128x4_0sub1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x4_0sub2[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 4, 3, 4, 3, + 4, 4, 5, 4, 5, 4, 6, 5, 6, +}; + +static static_codebook _huff_book_line_128x4_0sub2 = { + 1, 25, + _huff_lengthlist_line_128x4_0sub2, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x4_0sub3[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 3, 5, 3, 5, 3, + 5, 4, 6, 5, 6, 5, 7, 6, 6, 7, 7, 9, 9,11,11,16, + 11,14,10,11,11,13,16,15,15,15,15,15,15,15,15,15, +}; + +static static_codebook _huff_book_line_128x4_0sub3 = { + 1, 64, + _huff_lengthlist_line_128x4_0sub3, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_256x4_class0[] = { + 6, 7, 7,12, 6, 6, 7,12, 7, 6, 6,10,15,12,11,13, + 7, 7, 8,13, 7, 7, 8,12, 7, 7, 7,11,12,12,11,13, + 10, 9, 9,11, 9, 9, 9,10,10, 8, 8,12,14,12,12,14, + 11,11,12,14,11,12,11,15,15,12,13,15,15,15,15,15, + 6, 6, 7,10, 6, 6, 6,11, 7, 6, 6, 9,14,12,11,13, + 7, 7, 7,10, 6, 6, 7, 9, 7, 7, 6,10,13,12,10,12, + 9, 9, 9,11, 9, 9, 8, 9, 9, 8, 8,10,13,12,10,12, + 12,12,11,13,12,12,11,12,15,13,12,15,15,15,14,14, + 6, 6, 6, 8, 6, 6, 5, 6, 7, 7, 6, 5,11,10, 9, 8, + 7, 6, 6, 7, 6, 6, 5, 6, 7, 7, 6, 6,11,10, 9, 8, + 8, 8, 8, 9, 8, 8, 7, 8, 8, 8, 6, 7,11,10, 9, 9, + 14,11,10,14,14,11,10,15,13,11, 9,11,15,12,12,11, + 11, 9, 8, 8,10, 9, 8, 9,11,10, 9, 8,12,11,12,11, + 13,10, 8, 9,11,10, 8, 9,10, 9, 8, 9,10, 8,12,12, + 15,11,10,10,13,11,10,10, 8, 8, 7,12,10, 9,11,12, + 15,12,11,15,13,11,11,15,12,14,11,13,15,15,13,13, +}; + +static static_codebook _huff_book_line_256x4_class0 = { + 1, 256, + _huff_lengthlist_line_256x4_class0, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_256x4_0sub0[] = { + 2, 2, 2, 2, +}; + +static static_codebook _huff_book_line_256x4_0sub0 = { + 1, 4, + _huff_lengthlist_line_256x4_0sub0, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_256x4_0sub1[] = { + 0, 0, 0, 0, 2, 2, 3, 3, 3, 3, +}; + +static static_codebook _huff_book_line_256x4_0sub1 = { + 1, 10, + _huff_lengthlist_line_256x4_0sub1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_256x4_0sub2[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 3, 4, 3, 4, 3, + 5, 3, 5, 4, 5, 4, 6, 4, 6, +}; + +static static_codebook _huff_book_line_256x4_0sub2 = { + 1, 25, + _huff_lengthlist_line_256x4_0sub2, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_256x4_0sub3[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 3, 5, 3, 5, 3, + 6, 4, 7, 4, 7, 5, 7, 6, 7, 6, 7, 8,10,13,13,13, + 13,13,13,13,13,13,13,13,13,13,13,12,12,12,12,12, +}; + +static static_codebook _huff_book_line_256x4_0sub3 = { + 1, 64, + _huff_lengthlist_line_256x4_0sub3, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x7_class0[] = { + 10, 7, 8,13, 9, 6, 7,11,10, 8, 8,12,17,17,17,17, + 7, 5, 5, 9, 6, 4, 4, 8, 8, 5, 5, 8,16,14,13,16, + 7, 5, 5, 7, 6, 3, 3, 5, 8, 5, 4, 7,14,12,12,15, + 10, 7, 8, 9, 7, 5, 5, 6, 9, 6, 5, 5,15,12, 9,10, +}; + +static static_codebook _huff_book_line_128x7_class0 = { + 1, 64, + _huff_lengthlist_line_128x7_class0, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x7_class1[] = { + 8,13,17,17, 8,11,17,17,11,13,17,17,17,17,17,17, + 6,10,16,17, 6,10,15,17, 8,10,16,17,17,17,17,17, + 9,13,15,17, 8,11,17,17,10,12,17,17,17,17,17,17, + 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17, + 6,11,15,17, 7,10,15,17, 8,10,17,17,17,15,17,17, + 4, 8,13,17, 4, 7,13,17, 6, 8,15,17,16,15,17,17, + 6,11,15,17, 6, 9,13,17, 8,10,17,17,15,17,17,17, + 16,17,17,17,12,14,15,17,13,14,15,17,17,17,17,17, + 5,10,14,17, 5, 9,14,17, 7, 9,15,17,15,15,17,17, + 3, 7,12,17, 3, 6,11,17, 5, 7,13,17,12,12,17,17, + 5, 9,14,17, 3, 7,11,17, 5, 8,13,17,13,11,16,17, + 12,17,17,17, 9,14,15,17,10,11,14,17,16,14,17,17, + 8,12,17,17, 8,12,17,17,10,12,17,17,17,17,17,17, + 5,10,17,17, 5, 9,15,17, 7, 9,17,17,13,13,17,17, + 7,11,17,17, 6,10,15,17, 7, 9,15,17,12,11,17,17, + 12,15,17,17,11,14,17,17,11,10,15,17,17,16,17,17, +}; + +static static_codebook _huff_book_line_128x7_class1 = { + 1, 256, + _huff_lengthlist_line_128x7_class1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x7_0sub1[] = { + 0, 3, 3, 3, 3, 3, 3, 3, 3, +}; + +static static_codebook _huff_book_line_128x7_0sub1 = { + 1, 9, + _huff_lengthlist_line_128x7_0sub1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x7_0sub2[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 4, 4, 4, 4, + 5, 4, 5, 4, 5, 4, 6, 4, 6, +}; + +static static_codebook _huff_book_line_128x7_0sub2 = { + 1, 25, + _huff_lengthlist_line_128x7_0sub2, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x7_0sub3[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 3, 5, 3, 5, 4, + 5, 4, 5, 5, 5, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, + 7, 8, 9,11,13,13,13,13,13,13,13,13,13,13,13,13, +}; + +static static_codebook _huff_book_line_128x7_0sub3 = { + 1, 64, + _huff_lengthlist_line_128x7_0sub3, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x7_1sub1[] = { + 0, 3, 3, 2, 3, 3, 4, 3, 4, +}; + +static static_codebook _huff_book_line_128x7_1sub1 = { + 1, 9, + _huff_lengthlist_line_128x7_1sub1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x7_1sub2[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 3, 6, 3, 6, 3, + 6, 3, 7, 3, 8, 4, 9, 4, 9, +}; + +static static_codebook _huff_book_line_128x7_1sub2 = { + 1, 25, + _huff_lengthlist_line_128x7_1sub2, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x7_1sub3[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 7, 2, 7, 3, 8, 4, + 9, 5, 9, 8,10,11,11,12,14,14,14,14,14,14,14,14, + 14,14,14,14,14,14,14,14,14,14,14,14,13,13,13,13, +}; + +static static_codebook _huff_book_line_128x7_1sub3 = { + 1, 64, + _huff_lengthlist_line_128x7_1sub3, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x11_class1[] = { + 1, 6, 3, 7, 2, 4, 5, 7, +}; + +static static_codebook _huff_book_line_128x11_class1 = { + 1, 8, + _huff_lengthlist_line_128x11_class1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x11_class2[] = { + 1, 6,12,16, 4,12,15,16, 9,15,16,16,16,16,16,16, + 2, 5,11,16, 5,11,13,16, 9,13,16,16,16,16,16,16, + 4, 8,12,16, 5, 9,12,16, 9,13,15,16,16,16,16,16, + 15,16,16,16,11,14,13,16,12,15,16,16,16,16,16,15, +}; + +static static_codebook _huff_book_line_128x11_class2 = { + 1, 64, + _huff_lengthlist_line_128x11_class2, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x11_class3[] = { + 7, 6, 9,17, 7, 6, 8,17,12, 9,11,16,16,16,16,16, + 5, 4, 7,16, 5, 3, 6,14, 9, 6, 8,15,16,16,16,16, + 5, 4, 6,13, 3, 2, 4,11, 7, 4, 6,13,16,11,10,14, + 12,12,12,16, 9, 7,10,15,12, 9,11,16,16,15,15,16, +}; + +static static_codebook _huff_book_line_128x11_class3 = { + 1, 64, + _huff_lengthlist_line_128x11_class3, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x11_0sub0[] = { + 5, 5, 5, 5, 5, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, + 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 6, 6, 6, 7, 6, + 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 8, 6, 8, 6, 8, 7, + 8, 7, 8, 7, 8, 7, 9, 7, 9, 8, 9, 8, 9, 8,10, 8, + 10, 9,10, 9,10, 9,11, 9,11, 9,10,10,11,10,11,10, + 11,11,11,11,11,11,12,13,14,14,14,15,15,16,16,16, + 17,15,16,15,16,16,17,17,16,17,17,17,17,17,17,17, + 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17, +}; + +static static_codebook _huff_book_line_128x11_0sub0 = { + 1, 128, + _huff_lengthlist_line_128x11_0sub0, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x11_1sub0[] = { + 2, 5, 5, 5, 5, 5, 5, 4, 5, 5, 5, 5, 5, 5, 5, 5, + 6, 5, 6, 5, 6, 5, 7, 6, 7, 6, 7, 6, 8, 6, 8, 6, +}; + +static static_codebook _huff_book_line_128x11_1sub0 = { + 1, 32, + _huff_lengthlist_line_128x11_1sub0, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x11_1sub1[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 5, 3, 5, 3, 6, 4, 6, 4, 7, 4, 7, 4, 7, 4, 8, 4, + 8, 4, 9, 5, 9, 5, 9, 5, 9, 6,10, 6,10, 6,11, 7, + 10, 7,10, 8,11, 9,11, 9,11,10,11,11,12,11,11,12, + 15,15,12,14,11,14,12,14,11,14,13,14,12,14,11,14, + 11,14,12,14,11,14,11,14,13,13,14,14,14,14,14,14, + 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, +}; + +static static_codebook _huff_book_line_128x11_1sub1 = { + 1, 128, + _huff_lengthlist_line_128x11_1sub1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x11_2sub1[] = { + 0, 4, 5, 4, 5, 4, 5, 3, 5, 3, 5, 3, 5, 4, 4, 4, + 5, 5, +}; + +static static_codebook _huff_book_line_128x11_2sub1 = { + 1, 18, + _huff_lengthlist_line_128x11_2sub1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x11_2sub2[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 3, 3, 3, 4, 4, 4, 4, 5, 4, 5, 4, 6, 5, 7, + 5, 7, 6, 8, 6, 8, 6, 9, 7, 9, 7,10, 7, 9, 8,11, + 8,11, +}; + +static static_codebook _huff_book_line_128x11_2sub2 = { + 1, 50, + _huff_lengthlist_line_128x11_2sub2, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x11_2sub3[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 8, 3, 8, 4, 8, 4, 8, 6, 8, 5, 8, 4, 8, + 4, 8, 6, 8, 7, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, +}; + +static static_codebook _huff_book_line_128x11_2sub3 = { + 1, 128, + _huff_lengthlist_line_128x11_2sub3, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x11_3sub1[] = { + 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 4, + 5, 4, +}; + +static static_codebook _huff_book_line_128x11_3sub1 = { + 1, 18, + _huff_lengthlist_line_128x11_3sub1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x11_3sub2[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 3, 5, 4, 6, 4, 6, 4, 7, 4, 7, 4, 8, 4, + 8, 4, 9, 4, 9, 4,10, 4,10, 5,10, 5,11, 5,12, 6, + 12, 6, +}; + +static static_codebook _huff_book_line_128x11_3sub2 = { + 1, 50, + _huff_lengthlist_line_128x11_3sub2, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x11_3sub3[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 7, 1, 6, 3, 7, 3, 8, 4, 8, 5, 8, 8, 8, 9, + 7, 8, 8, 7, 7, 7, 8, 9,10, 9, 9,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10, 9, 9, +}; + +static static_codebook _huff_book_line_128x11_3sub3 = { + 1, 128, + _huff_lengthlist_line_128x11_3sub3, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x17_class1[] = { + 1, 3, 4, 7, 2, 5, 6, 7, +}; + +static static_codebook _huff_book_line_128x17_class1 = { + 1, 8, + _huff_lengthlist_line_128x17_class1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x17_class2[] = { + 1, 4,10,19, 3, 8,13,19, 7,12,19,19,19,19,19,19, + 2, 6,11,19, 8,13,19,19, 9,11,19,19,19,19,19,19, + 6, 7,13,19, 9,13,19,19,10,13,18,18,18,18,18,18, + 18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18, +}; + +static static_codebook _huff_book_line_128x17_class2 = { + 1, 64, + _huff_lengthlist_line_128x17_class2, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x17_class3[] = { + 3, 6,10,17, 4, 8,11,20, 8,10,11,20,20,20,20,20, + 2, 4, 8,18, 4, 6, 8,17, 7, 8,10,20,20,17,20,20, + 3, 5, 8,17, 3, 4, 6,17, 8, 8,10,17,17,12,16,20, + 13,13,15,20,10,10,12,20,15,14,15,20,20,20,19,19, +}; + +static static_codebook _huff_book_line_128x17_class3 = { + 1, 64, + _huff_lengthlist_line_128x17_class3, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x17_0sub0[] = { + 5, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, + 7, 5, 7, 5, 7, 5, 7, 5, 7, 5, 7, 5, 8, 5, 8, 5, + 8, 5, 8, 5, 8, 6, 8, 6, 8, 6, 9, 6, 9, 6, 9, 6, + 9, 6, 9, 7, 9, 7, 9, 7, 9, 7,10, 7,10, 8,10, 8, + 10, 8,10, 8,10, 8,11, 8,11, 8,11, 8,11, 8,11, 9, + 12, 9,12, 9,12, 9,12, 9,12,10,12,10,13,11,13,11, + 14,12,14,13,15,14,16,14,17,15,18,16,20,20,20,20, + 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20, +}; + +static static_codebook _huff_book_line_128x17_0sub0 = { + 1, 128, + _huff_lengthlist_line_128x17_0sub0, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x17_1sub0[] = { + 2, 5, 5, 4, 5, 4, 5, 4, 5, 5, 5, 5, 5, 5, 6, 5, + 6, 5, 6, 5, 7, 6, 7, 6, 7, 6, 8, 6, 9, 7, 9, 7, +}; + +static static_codebook _huff_book_line_128x17_1sub0 = { + 1, 32, + _huff_lengthlist_line_128x17_1sub0, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x17_1sub1[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 4, 3, 5, 3, 5, 3, 6, 3, 6, 4, 6, 4, 7, 4, 7, 5, + 8, 5, 8, 6, 9, 7, 9, 7, 9, 8,10, 9,10, 9,11,10, + 11,11,11,11,11,11,12,12,12,13,12,13,12,14,12,15, + 12,14,12,16,13,17,13,17,14,17,14,16,13,17,14,17, + 14,17,15,17,15,15,16,17,17,17,17,17,17,17,17,17, + 17,17,17,17,17,17,16,16,16,16,16,16,16,16,16,16, +}; + +static static_codebook _huff_book_line_128x17_1sub1 = { + 1, 128, + _huff_lengthlist_line_128x17_1sub1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x17_2sub1[] = { + 0, 4, 5, 4, 6, 4, 8, 3, 9, 3, 9, 2, 9, 3, 8, 4, + 9, 4, +}; + +static static_codebook _huff_book_line_128x17_2sub1 = { + 1, 18, + _huff_lengthlist_line_128x17_2sub1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x17_2sub2[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 1, 5, 3, 5, 3, 5, 4, 7, 5,10, 7,10, 7, + 12,10,14,10,14, 9,14,11,14,14,14,13,13,13,13,13, + 13,13, +}; + +static static_codebook _huff_book_line_128x17_2sub2 = { + 1, 50, + _huff_lengthlist_line_128x17_2sub2, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x17_2sub3[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, +}; + +static static_codebook _huff_book_line_128x17_2sub3 = { + 1, 128, + _huff_lengthlist_line_128x17_2sub3, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x17_3sub1[] = { + 0, 4, 4, 4, 4, 4, 4, 4, 5, 3, 5, 3, 5, 4, 6, 4, + 6, 4, +}; + +static static_codebook _huff_book_line_128x17_3sub1 = { + 1, 18, + _huff_lengthlist_line_128x17_3sub1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x17_3sub2[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 3, 6, 3, 6, 4, 7, 4, 7, 4, 7, 4, 8, 4, + 8, 4, 8, 4, 8, 4, 9, 4, 9, 5,10, 5,10, 7,10, 8, + 10, 8, +}; + +static static_codebook _huff_book_line_128x17_3sub2 = { + 1, 50, + _huff_lengthlist_line_128x17_3sub2, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_128x17_3sub3[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 3, 2, 4, 3, 4, 4, 4, 5, 4, 7, 5, 8, 5,11, + 6,10, 6,12, 7,12, 7,12, 8,12, 8,12,10,12,12,12, + 12,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, +}; + +static static_codebook _huff_book_line_128x17_3sub3 = { + 1, 128, + _huff_lengthlist_line_128x17_3sub3, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_1024x27_class1[] = { + 2,10, 8,14, 7,12,11,14, 1, 5, 3, 7, 4, 9, 7,13, +}; + +static static_codebook _huff_book_line_1024x27_class1 = { + 1, 16, + _huff_lengthlist_line_1024x27_class1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_1024x27_class2[] = { + 1, 4, 2, 6, 3, 7, 5, 7, +}; + +static static_codebook _huff_book_line_1024x27_class2 = { + 1, 8, + _huff_lengthlist_line_1024x27_class2, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_1024x27_class3[] = { + 1, 5, 7,21, 5, 8, 9,21,10, 9,12,20,20,16,20,20, + 4, 8, 9,20, 6, 8, 9,20,11,11,13,20,20,15,17,20, + 9,11,14,20, 8,10,15,20,11,13,15,20,20,20,20,20, + 20,20,20,20,13,20,20,20,18,18,20,20,20,20,20,20, + 3, 6, 8,20, 6, 7, 9,20,10, 9,12,20,20,20,20,20, + 5, 7, 9,20, 6, 6, 9,20,10, 9,12,20,20,20,20,20, + 8,10,13,20, 8, 9,12,20,11,10,12,20,20,20,20,20, + 18,20,20,20,15,17,18,20,18,17,18,20,20,20,20,20, + 7,10,12,20, 8, 9,11,20,14,13,14,20,20,20,20,20, + 6, 9,12,20, 7, 8,11,20,12,11,13,20,20,20,20,20, + 9,11,15,20, 8,10,14,20,12,11,14,20,20,20,20,20, + 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20, + 11,16,18,20,15,15,17,20,20,17,20,20,20,20,20,20, + 9,14,16,20,12,12,15,20,17,15,18,20,20,20,20,20, + 16,19,18,20,15,16,20,20,17,17,20,20,20,20,20,20, + 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20, +}; + +static static_codebook _huff_book_line_1024x27_class3 = { + 1, 256, + _huff_lengthlist_line_1024x27_class3, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_1024x27_class4[] = { + 2, 3, 7,13, 4, 4, 7,15, 8, 6, 9,17,21,16,15,21, + 2, 5, 7,11, 5, 5, 7,14, 9, 7,10,16,17,15,16,21, + 4, 7,10,17, 7, 7, 9,15,11, 9,11,16,21,18,15,21, + 18,21,21,21,15,17,17,19,21,19,18,20,21,21,21,20, +}; + +static static_codebook _huff_book_line_1024x27_class4 = { + 1, 64, + _huff_lengthlist_line_1024x27_class4, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_1024x27_0sub0[] = { + 5, 5, 5, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, + 6, 5, 6, 5, 6, 5, 6, 5, 7, 5, 7, 5, 7, 5, 7, 5, + 8, 6, 8, 6, 8, 6, 9, 6, 9, 6,10, 6,10, 6,11, 6, + 11, 7,11, 7,12, 7,12, 7,12, 7,12, 7,12, 7,12, 7, + 12, 7,12, 8,13, 8,12, 8,12, 8,13, 8,13, 9,13, 9, + 13, 9,13, 9,12,10,12,10,13,10,14,11,14,12,14,13, + 14,13,14,14,15,16,15,15,15,14,15,17,21,22,22,21, + 22,22,22,22,22,22,21,21,21,21,21,21,21,21,21,21, +}; + +static static_codebook _huff_book_line_1024x27_0sub0 = { + 1, 128, + _huff_lengthlist_line_1024x27_0sub0, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_1024x27_1sub0[] = { + 2, 5, 5, 4, 5, 4, 5, 4, 5, 4, 6, 5, 6, 5, 6, 5, + 6, 5, 7, 5, 7, 6, 8, 6, 8, 6, 8, 6, 9, 6, 9, 6, +}; + +static static_codebook _huff_book_line_1024x27_1sub0 = { + 1, 32, + _huff_lengthlist_line_1024x27_1sub0, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_1024x27_1sub1[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 8, 5, 8, 4, 9, 4, 9, 4, 9, 4, 9, 4, 9, 4, 9, 4, + 9, 4, 9, 4, 9, 4, 8, 4, 8, 4, 9, 5, 9, 5, 9, 5, + 9, 5, 9, 6,10, 6,10, 7,10, 8,11, 9,11,11,12,13, + 12,14,13,15,13,15,14,16,14,17,15,17,15,15,16,16, + 15,16,16,16,15,18,16,15,17,17,19,19,19,19,19,19, + 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +}; + +static static_codebook _huff_book_line_1024x27_1sub1 = { + 1, 128, + _huff_lengthlist_line_1024x27_1sub1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_1024x27_2sub0[] = { + 1, 5, 5, 5, 5, 5, 5, 5, 6, 5, 6, 5, 6, 5, 6, 5, + 6, 6, 7, 7, 7, 7, 8, 7, 8, 8, 9, 8,10, 9,10, 9, +}; + +static static_codebook _huff_book_line_1024x27_2sub0 = { + 1, 32, + _huff_lengthlist_line_1024x27_2sub0, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_1024x27_2sub1[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 4, 3, 4, 3, 4, 4, 5, 4, 5, 4, 5, 5, 6, 5, 6, 5, + 7, 5, 7, 6, 7, 6, 8, 7, 8, 7, 8, 7, 9, 8, 9, 9, + 9, 9,10,10,10,11, 9,12, 9,12, 9,15,10,14, 9,13, + 10,13,10,12,10,12,10,13,10,12,11,13,11,14,12,13, + 13,14,14,13,14,15,14,16,13,13,14,16,16,16,16,16, + 16,16,16,16,16,16,16,16,16,16,16,16,16,16,15,15, +}; + +static static_codebook _huff_book_line_1024x27_2sub1 = { + 1, 128, + _huff_lengthlist_line_1024x27_2sub1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_1024x27_3sub1[] = { + 0, 4, 5, 4, 5, 3, 5, 3, 5, 3, 5, 4, 4, 4, 4, 5, + 5, 5, +}; + +static static_codebook _huff_book_line_1024x27_3sub1 = { + 1, 18, + _huff_lengthlist_line_1024x27_3sub1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_1024x27_3sub2[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 3, 3, 4, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, + 5, 7, 5, 8, 6, 8, 6, 9, 7,10, 7,10, 8,10, 8,11, + 9,11, +}; + +static static_codebook _huff_book_line_1024x27_3sub2 = { + 1, 50, + _huff_lengthlist_line_1024x27_3sub2, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_1024x27_3sub3[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 3, 7, 3, 8, 3,10, 3, 8, 3, 9, 3, 8, 4, 9, + 4, 9, 5, 9, 6,10, 6, 9, 7,11, 7,12, 9,13,10,13, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, +}; + +static static_codebook _huff_book_line_1024x27_3sub3 = { + 1, 128, + _huff_lengthlist_line_1024x27_3sub3, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_1024x27_4sub1[] = { + 0, 4, 5, 4, 5, 4, 5, 4, 5, 3, 5, 3, 5, 3, 5, 4, + 5, 4, +}; + +static static_codebook _huff_book_line_1024x27_4sub1 = { + 1, 18, + _huff_lengthlist_line_1024x27_4sub1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_1024x27_4sub2[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 2, 4, 2, 5, 3, 5, 4, 6, 6, 6, 7, 7, 8, + 7, 8, 7, 8, 7, 9, 8, 9, 8, 9, 8,10, 8,11, 9,12, + 9,12, +}; + +static static_codebook _huff_book_line_1024x27_4sub2 = { + 1, 50, + _huff_lengthlist_line_1024x27_4sub2, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_1024x27_4sub3[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 5, 2, 6, 3, 6, 4, 7, 4, 7, 5, 9, 5,11, + 6,11, 6,11, 7,11, 6,11, 6,11, 9,11, 8,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,10,10,10,10,10,10, +}; + +static static_codebook _huff_book_line_1024x27_4sub3 = { + 1, 128, + _huff_lengthlist_line_1024x27_4sub3, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_2048x27_class1[] = { + 2, 6, 8, 9, 7,11,13,13, 1, 3, 5, 5, 6, 6,12,10, +}; + +static static_codebook _huff_book_line_2048x27_class1 = { + 1, 16, + _huff_lengthlist_line_2048x27_class1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_2048x27_class2[] = { + 1, 2, 3, 6, 4, 7, 5, 7, +}; + +static static_codebook _huff_book_line_2048x27_class2 = { + 1, 8, + _huff_lengthlist_line_2048x27_class2, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_2048x27_class3[] = { + 3, 3, 6,16, 5, 5, 7,16, 9, 8,11,16,16,16,16,16, + 5, 5, 8,16, 5, 5, 7,16, 8, 7, 9,16,16,16,16,16, + 9, 9,12,16, 6, 8,11,16, 9,10,11,16,16,16,16,16, + 16,16,16,16,13,16,16,16,15,16,16,16,16,16,16,16, + 5, 4, 7,16, 6, 5, 8,16, 9, 8,10,16,16,16,16,16, + 5, 5, 7,15, 5, 4, 6,15, 7, 6, 8,16,16,16,16,16, + 9, 9,11,15, 7, 7, 9,16, 8, 8, 9,16,16,16,16,16, + 16,16,16,16,15,15,15,16,15,15,14,16,16,16,16,16, + 8, 8,11,16, 8, 9,10,16,11,10,14,16,16,16,16,16, + 6, 8,10,16, 6, 7,10,16, 8, 8,11,16,14,16,16,16, + 10,11,14,16, 9, 9,11,16,10,10,11,16,16,16,16,16, + 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, + 16,16,16,16,15,16,16,16,16,16,16,16,16,16,16,16, + 12,16,15,16,12,14,16,16,16,16,16,16,16,16,16,16, + 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, + 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, +}; + +static static_codebook _huff_book_line_2048x27_class3 = { + 1, 256, + _huff_lengthlist_line_2048x27_class3, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_2048x27_class4[] = { + 2, 4, 7,13, 4, 5, 7,15, 8, 7,10,16,16,14,16,16, + 2, 4, 7,16, 3, 4, 7,14, 8, 8,10,16,16,16,15,16, + 6, 8,11,16, 7, 7, 9,16,11, 9,13,16,16,16,15,16, + 16,16,16,16,14,16,16,16,16,16,16,16,16,16,16,16, +}; + +static static_codebook _huff_book_line_2048x27_class4 = { + 1, 64, + _huff_lengthlist_line_2048x27_class4, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_2048x27_0sub0[] = { + 5, 5, 5, 5, 5, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, + 6, 5, 7, 5, 7, 5, 7, 5, 8, 5, 8, 5, 8, 5, 9, 5, + 9, 6,10, 6,10, 6,11, 6,11, 6,11, 6,11, 6,11, 6, + 11, 6,11, 6,12, 7,11, 7,11, 7,11, 7,11, 7,10, 7, + 11, 7,11, 7,12, 7,11, 8,11, 8,11, 8,11, 8,13, 8, + 12, 9,11, 9,11, 9,11,10,12,10,12, 9,12,10,12,11, + 14,12,16,12,12,11,14,16,17,17,17,17,17,17,17,17, + 17,17,17,17,17,17,17,17,17,17,17,17,16,16,16,16, +}; + +static static_codebook _huff_book_line_2048x27_0sub0 = { + 1, 128, + _huff_lengthlist_line_2048x27_0sub0, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_2048x27_1sub0[] = { + 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 6, 6, 6, 6, 6, 6, 7, 6, 7, 6, 7, 6, 7, 6, +}; + +static static_codebook _huff_book_line_2048x27_1sub0 = { + 1, 32, + _huff_lengthlist_line_2048x27_1sub0, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_2048x27_1sub1[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 6, 5, 7, 5, 7, 4, 7, 4, 8, 4, 8, 4, 8, 4, 8, 3, + 8, 4, 9, 4, 9, 4, 9, 4, 9, 4, 9, 5, 9, 5, 9, 6, + 9, 7, 9, 8, 9, 9, 9,10, 9,11, 9,14, 9,15,10,15, + 10,15,10,15,10,15,11,15,10,14,12,14,11,14,13,14, + 13,15,15,15,12,15,15,15,13,15,13,15,13,15,15,15, + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,14, +}; + +static static_codebook _huff_book_line_2048x27_1sub1 = { + 1, 128, + _huff_lengthlist_line_2048x27_1sub1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_2048x27_2sub0[] = { + 2, 4, 5, 4, 5, 4, 5, 4, 5, 5, 5, 5, 5, 5, 6, 5, + 6, 5, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, +}; + +static static_codebook _huff_book_line_2048x27_2sub0 = { + 1, 32, + _huff_lengthlist_line_2048x27_2sub0, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_2048x27_2sub1[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 4, 3, 4, 3, 4, 4, 5, 4, 5, 5, 5, 6, 6, 6, 7, + 6, 8, 6, 8, 6, 9, 7,10, 7,10, 7,10, 7,12, 7,12, + 7,12, 9,12,11,12,10,12,10,12,11,12,12,12,10,12, + 10,12,10,12, 9,12,11,12,12,12,12,12,11,12,11,12, + 12,12,12,12,12,12,12,12,10,10,12,12,12,12,12,10, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, +}; + +static static_codebook _huff_book_line_2048x27_2sub1 = { + 1, 128, + _huff_lengthlist_line_2048x27_2sub1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_2048x27_3sub1[] = { + 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 5, 5, +}; + +static static_codebook _huff_book_line_2048x27_3sub1 = { + 1, 18, + _huff_lengthlist_line_2048x27_3sub1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_2048x27_3sub2[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, + 6, 7, 6, 7, 6, 8, 6, 9, 7, 9, 7, 9, 9,11, 9,12, + 10,12, +}; + +static static_codebook _huff_book_line_2048x27_3sub2 = { + 1, 50, + _huff_lengthlist_line_2048x27_3sub2, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_2048x27_3sub3[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 3, 6, 3, 7, 3, 7, 5, 7, 7, 7, 7, 7, 6, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, +}; + +static static_codebook _huff_book_line_2048x27_3sub3 = { + 1, 128, + _huff_lengthlist_line_2048x27_3sub3, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_2048x27_4sub1[] = { + 0, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 4, 5, 4, 5, 4, + 4, 5, +}; + +static static_codebook _huff_book_line_2048x27_4sub1 = { + 1, 18, + _huff_lengthlist_line_2048x27_4sub1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_2048x27_4sub2[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 3, 2, 4, 3, 4, 4, 4, 5, 5, 6, 5, 6, 5, 7, + 6, 6, 6, 7, 7, 7, 8, 9, 9, 9,12,10,11,10,10,12, + 10,10, +}; + +static static_codebook _huff_book_line_2048x27_4sub2 = { + 1, 50, + _huff_lengthlist_line_2048x27_4sub2, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_2048x27_4sub3[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 3, 6, 5, 7, 5, 7, 7, 7, 7, 7, 5, 7, 5, 7, + 5, 7, 5, 7, 7, 7, 7, 7, 4, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, +}; + +static static_codebook _huff_book_line_2048x27_4sub3 = { + 1, 128, + _huff_lengthlist_line_2048x27_4sub3, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_256x4low_class0[] = { + 4, 5, 6,11, 5, 5, 6,10, 7, 7, 6, 6,14,13, 9, 9, + 6, 6, 6,10, 6, 6, 6, 9, 8, 7, 7, 9,14,12, 8,11, + 8, 7, 7,11, 8, 8, 7,11, 9, 9, 7, 9,13,11, 9,13, + 19,19,18,19,15,16,16,19,11,11,10,13,10,10, 9,15, + 5, 5, 6,13, 6, 6, 6,11, 8, 7, 6, 7,14,11,10,11, + 6, 6, 6,12, 7, 6, 6,11, 8, 7, 7,11,13,11, 9,11, + 9, 7, 6,12, 8, 7, 6,12, 9, 8, 8,11,13,10, 7,13, + 19,19,17,19,17,14,14,19,12,10, 8,12,13,10, 9,16, + 7, 8, 7,12, 7, 7, 7,11, 8, 7, 7, 8,12,12,11,11, + 8, 8, 7,12, 8, 7, 6,11, 8, 7, 7,10,10,11,10,11, + 9, 8, 8,13, 9, 8, 7,12,10, 9, 7,11, 9, 8, 7,11, + 18,18,15,18,18,16,17,18,15,11,10,18,11, 9, 9,18, + 16,16,13,16,12,11,10,16,12,11, 9, 6,15,12,11,13, + 16,16,14,14,13,11,12,16,12, 9, 9,13,13,10,10,12, + 17,18,17,17,14,15,14,16,14,12,14,15,12,10,11,12, + 18,18,18,18,18,18,18,18,18,12,13,18,16,11, 9,18, +}; + +static static_codebook _huff_book_line_256x4low_class0 = { + 1, 256, + _huff_lengthlist_line_256x4low_class0, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_256x4low_0sub0[] = { + 1, 3, 2, 3, +}; + +static static_codebook _huff_book_line_256x4low_0sub0 = { + 1, 4, + _huff_lengthlist_line_256x4low_0sub0, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_256x4low_0sub1[] = { + 0, 0, 0, 0, 2, 3, 2, 3, 3, 3, +}; + +static static_codebook _huff_book_line_256x4low_0sub1 = { + 1, 10, + _huff_lengthlist_line_256x4low_0sub1, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_256x4low_0sub2[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 4, 3, 4, + 4, 4, 4, 4, 5, 5, 5, 6, 6, +}; + +static static_codebook _huff_book_line_256x4low_0sub2 = { + 1, 25, + _huff_lengthlist_line_256x4low_0sub2, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist_line_256x4low_0sub3[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 2, 4, 3, 5, 4, + 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 7, 7, 8, 6, 9, + 7,12,11,16,13,16,12,15,13,15,12,14,12,15,15,15, +}; + +static static_codebook _huff_book_line_256x4low_0sub3 = { + 1, 64, + _huff_lengthlist_line_256x4low_0sub3, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/books/uncoupled/res_books_uncoupled.h b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/books/uncoupled/res_books_uncoupled.h new file mode 100644 index 0000000..d35cb91 --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/books/uncoupled/res_books_uncoupled.h @@ -0,0 +1,11517 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the Xiph.Org Foundation http://www.xiph.org/ * + * * + ******************************************************************** + + function: static codebooks autogenerated by huff/huffbuld + last modified: $Id: res_books_uncoupled.h 7187 2004-07-20 07:24:27Z xiphmont $ + + ********************************************************************/ + +#include "codebook.h" +static long _vq_quantlist__16u0__p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__16u0__p1_0[] = { + 1, 4, 4, 5, 7, 7, 5, 7, 8, 5, 8, 8, 8,10,10, 8, + 10,11, 5, 8, 8, 8,10,10, 8,10,10, 4, 9, 9, 9,12, + 11, 8,11,11, 8,12,11,10,12,14,10,13,13, 7,11,11, + 10,14,12,11,14,14, 4, 9, 9, 8,11,11, 9,11,12, 7, + 11,11,10,13,14,10,12,14, 8,11,12,10,14,14,10,13, + 12, +}; + +static float _vq_quantthresh__16u0__p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__16u0__p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__16u0__p1_0 = { + _vq_quantthresh__16u0__p1_0, + _vq_quantmap__16u0__p1_0, + 3, + 3 +}; + +static static_codebook _16u0__p1_0 = { + 4, 81, + _vq_lengthlist__16u0__p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__16u0__p1_0, + NULL, + &_vq_auxt__16u0__p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__16u0__p2_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__16u0__p2_0[] = { + 2, 4, 4, 5, 6, 6, 5, 6, 6, 5, 7, 7, 7, 8, 9, 7, + 8, 9, 5, 7, 7, 7, 9, 8, 7, 9, 7, 4, 7, 7, 7, 9, + 9, 7, 8, 8, 6, 9, 8, 7, 8,11, 9,11,10, 6, 8, 9, + 8,11, 8, 9,10,11, 4, 7, 7, 7, 8, 8, 7, 9, 9, 6, + 9, 8, 9,11,10, 8, 8,11, 6, 8, 9, 9,10,11, 8,11, + 8, +}; + +static float _vq_quantthresh__16u0__p2_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__16u0__p2_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__16u0__p2_0 = { + _vq_quantthresh__16u0__p2_0, + _vq_quantmap__16u0__p2_0, + 3, + 3 +}; + +static static_codebook _16u0__p2_0 = { + 4, 81, + _vq_lengthlist__16u0__p2_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__16u0__p2_0, + NULL, + &_vq_auxt__16u0__p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__16u0__p3_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__16u0__p3_0[] = { + 1, 5, 5, 7, 7, 6, 7, 7, 8, 8, 6, 7, 8, 8, 8, 8, + 9, 9,11,11, 8, 9, 9,11,11, 6, 9, 8,10,10, 8,10, + 10,11,11, 8,10,10,11,11,10,11,10,13,12, 9,11,10, + 13,13, 6, 8, 9,10,10, 8,10,10,11,11, 8,10,10,11, + 11, 9,10,11,13,12,10,10,11,12,12, 8,11,11,14,13, + 10,12,11,15,13, 9,12,11,15,14,12,14,13,16,14,12, + 13,13,17,14, 8,11,11,13,14, 9,11,12,14,15,10,11, + 12,13,15,11,13,13,14,16,12,13,14,14,16, 5, 9, 9, + 11,11, 9,11,11,12,12, 8,11,11,12,12,11,12,12,15, + 14,10,12,12,15,15, 8,11,11,13,12,10,12,12,13,13, + 10,12,12,14,13,12,12,13,14,15,11,13,13,17,16, 7, + 11,11,13,13,10,12,12,14,13,10,12,12,13,14,12,13, + 12,15,14,11,13,13,15,14, 9,12,12,16,15,11,13,13, + 17,16,10,13,13,16,16,13,14,15,15,16,13,15,14,19, + 17, 9,12,12,14,16,11,13,13,15,16,10,13,13,17,16, + 13,14,13,17,15,12,15,15,16,17, 5, 9, 9,11,11, 8, + 11,11,13,12, 9,11,11,12,12,10,12,12,14,15,11,12, + 12,14,14, 7,11,10,13,12,10,12,12,14,13,10,11,12, + 13,13,11,13,13,15,16,12,12,13,15,15, 7,11,11,13, + 13,10,13,13,14,14,10,12,12,13,13,11,13,13,16,15, + 12,13,13,15,14, 9,12,12,15,15,10,13,13,17,16,11, + 12,13,15,15,12,15,14,18,18,13,14,14,16,17, 9,12, + 12,15,16,10,13,13,15,16,11,13,13,15,16,13,15,15, + 17,17,13,15,14,16,15, 7,11,11,15,16,10,13,12,16, + 17,10,12,13,15,17,15,16,16,18,17,13,15,15,17,18, + 8,12,12,16,16,11,13,14,17,18,11,13,13,18,16,15, + 17,16,17,19,14,15,15,17,16, 8,12,12,16,15,11,14, + 13,18,17,11,13,14,18,17,15,16,16,18,17,13,16,16, + 18,18,11,15,14,18,17,13,14,15,18, 0,12,15,15, 0, + 17,17,16,17,17,18,14,16,18,18, 0,11,14,14,17, 0, + 12,15,14,17,19,12,15,14,18, 0,15,18,16, 0,17,14, + 18,16,18, 0, 7,11,11,16,15,10,12,12,18,16,10,13, + 13,16,15,13,15,14,17,17,14,16,16,19,18, 8,12,12, + 16,16,11,13,13,18,16,11,13,14,17,16,14,15,15,19, + 18,15,16,16, 0,19, 8,12,12,16,17,11,13,13,17,17, + 11,14,13,17,17,13,15,15,17,19,15,17,17,19, 0,11, + 14,15,19,17,12,15,16,18,18,12,14,15,19,17,14,16, + 17, 0,18,16,16,19,17, 0,11,14,14,18,19,12,15,14, + 17,17,13,16,14,17,16,14,17,16,18,18,15,18,15, 0, + 18, +}; + +static float _vq_quantthresh__16u0__p3_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__16u0__p3_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__16u0__p3_0 = { + _vq_quantthresh__16u0__p3_0, + _vq_quantmap__16u0__p3_0, + 5, + 5 +}; + +static static_codebook _16u0__p3_0 = { + 4, 625, + _vq_lengthlist__16u0__p3_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__16u0__p3_0, + NULL, + &_vq_auxt__16u0__p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__16u0__p4_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__16u0__p4_0[] = { + 3, 5, 5, 8, 8, 6, 6, 6, 9, 9, 6, 6, 6, 9, 9, 9, + 10, 9,11,11, 9, 9, 9,11,11, 6, 7, 7,10,10, 7, 7, + 8,10,10, 7, 7, 8,10,10,10,10,10,11,12, 9,10,10, + 11,12, 6, 7, 7,10,10, 7, 8, 7,10,10, 7, 8, 7,10, + 10,10,11,10,12,11,10,10,10,13,10, 9,10,10,12,12, + 10,11,10,14,12, 9,11,11,13,13,11,12,13,13,13,11, + 12,12,15,13, 9,10,10,12,13, 9,11,10,12,13,10,10, + 11,12,13,11,12,12,12,13,11,12,12,13,13, 5, 7, 7, + 10,10, 7, 8, 8,10,10, 7, 8, 8,10,10,10,11,10,12, + 13,10,10,11,12,12, 6, 8, 8,11,10, 7, 8, 9,10,12, + 8, 9, 9,11,11,11,10,11,11,12,10,11,11,13,12, 7, + 8, 8,10,11, 8, 9, 8,11,10, 8, 9, 9,11,11,10,12, + 10,13,11,10,11,11,13,13,10,11,10,14,13,10,10,11, + 13,13,10,12,11,14,13,12,11,13,12,13,13,12,13,14, + 14,10,11,11,13,13,10,11,10,12,13,10,12,12,12,14, + 12,12,12,14,12,12,13,12,17,15, 5, 7, 7,10,10, 7, + 8, 8,10,10, 7, 8, 8,11,10,10,10,11,12,12,10,11, + 11,12,13, 6, 8, 8,11,10, 8, 9, 9,11,11, 7, 8, 9, + 10,11,11,11,11,12,12,10,10,11,12,13, 6, 8, 8,10, + 11, 8, 9, 9,11,11, 7, 9, 7,11,10,10,12,12,13,13, + 11,11,10,13,11, 9,11,10,14,13,11,11,11,15,13,10, + 10,11,13,13,12,13,13,14,14,12,11,12,12,13,10,11, + 11,12,13,10,11,12,13,13,10,11,10,13,12,12,12,13, + 14, 0,12,13,11,13,11, 8,10,10,13,13,10,11,11,14, + 13,10,11,11,13,12,13,14,14,14,15,12,12,12,15,14, + 9,11,10,13,12,10,10,11,13,14,11,11,11,15,12,13, + 12,14,15,16,13,13,13,14,13, 9,11,11,12,12,10,12, + 11,13,13,10,11,11,13,14,13,13,13,15,15,13,13,14, + 17,15,11,12,12,14,14,10,11,12,13,15,12,13,13, 0, + 15,13,11,14,12,16,14,16,14, 0,15,11,12,12,14,16, + 11,13,12,16,15,12,13,13,14,15,12,14,12,15,13,15, + 14,14,16,16, 8,10,10,13,13,10,11,10,13,14,10,11, + 11,13,13,13,13,12,14,14,14,13,13,16,17, 9,10,10, + 12,14,10,12,11,14,13,10,11,12,13,14,12,12,12,15, + 15,13,13,13,14,14, 9,10,10,13,13,10,11,12,12,14, + 10,11,10,13,13,13,13,13,14,16,13,13,13,14,14,11, + 12,13,15,13,12,14,13,14,16,12,12,13,13,14,13,14, + 14,17,15,13,12,17,13,16,11,12,13,14,15,12,13,14, + 14,17,11,12,11,14,14,13,16,14,16, 0,14,15,11,15, + 11, +}; + +static float _vq_quantthresh__16u0__p4_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__16u0__p4_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__16u0__p4_0 = { + _vq_quantthresh__16u0__p4_0, + _vq_quantmap__16u0__p4_0, + 5, + 5 +}; + +static static_codebook _16u0__p4_0 = { + 4, 625, + _vq_lengthlist__16u0__p4_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__16u0__p4_0, + NULL, + &_vq_auxt__16u0__p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__16u0__p5_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__16u0__p5_0[] = { + 1, 4, 4, 7, 7, 7, 7, 9, 9, 4, 6, 6, 8, 8, 8, 8, + 9, 9, 4, 6, 6, 8, 8, 8, 8, 9, 9, 7, 8, 8, 9, 9, + 9, 9,11,10, 7, 8, 8, 9, 9, 9, 9,10,11, 7, 8, 8, + 9, 9,10,10,11,11, 7, 8, 8, 9, 9,10,10,11,11, 9, + 9, 9,10,10,11,11,12,12, 9, 9, 9,10,10,11,11,12, + 12, +}; + +static float _vq_quantthresh__16u0__p5_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__16u0__p5_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__16u0__p5_0 = { + _vq_quantthresh__16u0__p5_0, + _vq_quantmap__16u0__p5_0, + 9, + 9 +}; + +static static_codebook _16u0__p5_0 = { + 2, 81, + _vq_lengthlist__16u0__p5_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__16u0__p5_0, + NULL, + &_vq_auxt__16u0__p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__16u0__p6_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__16u0__p6_0[] = { + 1, 4, 4, 7, 7,10,10,12,12,13,13,18,17, 3, 6, 6, + 9, 9,11,11,13,13,14,14,18,17, 3, 6, 6, 9, 9,11, + 11,13,13,14,14,17,18, 7, 9, 9,11,11,13,13,14,14, + 15,15, 0, 0, 7, 9, 9,11,11,13,13,14,14,15,16,19, + 18,10,11,11,13,13,14,14,16,15,17,18, 0, 0,10,11, + 11,13,13,14,14,15,15,16,18, 0, 0,11,13,13,14,14, + 15,15,17,17, 0,19, 0, 0,11,13,13,14,14,14,15,16, + 18, 0,19, 0, 0,13,14,14,15,15,18,17,18,18, 0,19, + 0, 0,13,14,14,15,16,16,16,18,18,19, 0, 0, 0,16, + 17,17, 0,17,19,19, 0,19, 0, 0, 0, 0,16,19,16,17, + 18, 0,19, 0, 0, 0, 0, 0, 0, +}; + +static float _vq_quantthresh__16u0__p6_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__16u0__p6_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__16u0__p6_0 = { + _vq_quantthresh__16u0__p6_0, + _vq_quantmap__16u0__p6_0, + 13, + 13 +}; + +static static_codebook _16u0__p6_0 = { + 2, 169, + _vq_lengthlist__16u0__p6_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__16u0__p6_0, + NULL, + &_vq_auxt__16u0__p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__16u0__p6_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__16u0__p6_1[] = { + 1, 4, 5, 6, 6, 4, 6, 6, 6, 6, 4, 6, 6, 6, 6, 6, + 6, 6, 7, 7, 6, 6, 6, 7, 7, +}; + +static float _vq_quantthresh__16u0__p6_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__16u0__p6_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__16u0__p6_1 = { + _vq_quantthresh__16u0__p6_1, + _vq_quantmap__16u0__p6_1, + 5, + 5 +}; + +static static_codebook _16u0__p6_1 = { + 2, 25, + _vq_lengthlist__16u0__p6_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__16u0__p6_1, + NULL, + &_vq_auxt__16u0__p6_1, + NULL, + 0 +}; + +static long _vq_quantlist__16u0__p7_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__16u0__p7_0[] = { + 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, +}; + +static float _vq_quantthresh__16u0__p7_0[] = { + -157.5, 157.5, +}; + +static long _vq_quantmap__16u0__p7_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__16u0__p7_0 = { + _vq_quantthresh__16u0__p7_0, + _vq_quantmap__16u0__p7_0, + 3, + 3 +}; + +static static_codebook _16u0__p7_0 = { + 4, 81, + _vq_lengthlist__16u0__p7_0, + 1, -518803456, 1628680192, 2, 0, + _vq_quantlist__16u0__p7_0, + NULL, + &_vq_auxt__16u0__p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__16u0__p7_1[] = { + 7, + 6, + 8, + 5, + 9, + 4, + 10, + 3, + 11, + 2, + 12, + 1, + 13, + 0, + 14, +}; + +static long _vq_lengthlist__16u0__p7_1[] = { + 1, 5, 5, 6, 5, 9,10,11,11,10,10,10,10,10,10, 5, + 8, 8, 8,10,10,10,10,10,10,10,10,10,10,10, 5, 8, + 9, 9, 9,10,10,10,10,10,10,10,10,10,10, 5,10, 8, + 10,10,10,10,10,10,10,10,10,10,10,10, 4, 8, 9,10, + 10,10,10,10,10,10,10,10,10,10,10, 9,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10, 9,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10, +}; + +static float _vq_quantthresh__16u0__p7_1[] = { + -136.5, -115.5, -94.5, -73.5, -52.5, -31.5, -10.5, 10.5, + 31.5, 52.5, 73.5, 94.5, 115.5, 136.5, +}; + +static long _vq_quantmap__16u0__p7_1[] = { + 13, 11, 9, 7, 5, 3, 1, 0, + 2, 4, 6, 8, 10, 12, 14, +}; + +static encode_aux_threshmatch _vq_auxt__16u0__p7_1 = { + _vq_quantthresh__16u0__p7_1, + _vq_quantmap__16u0__p7_1, + 15, + 15 +}; + +static static_codebook _16u0__p7_1 = { + 2, 225, + _vq_lengthlist__16u0__p7_1, + 1, -520986624, 1620377600, 4, 0, + _vq_quantlist__16u0__p7_1, + NULL, + &_vq_auxt__16u0__p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__16u0__p7_2[] = { + 10, + 9, + 11, + 8, + 12, + 7, + 13, + 6, + 14, + 5, + 15, + 4, + 16, + 3, + 17, + 2, + 18, + 1, + 19, + 0, + 20, +}; + +static long _vq_lengthlist__16u0__p7_2[] = { + 1, 6, 6, 7, 8, 7, 7,10, 9,10, 9,11,10, 9,11,10, + 9, 9, 9, 9,10, 6, 8, 7, 9, 9, 8, 8,10,10, 9,11, + 11,12,12,10, 9,11, 9,12,10, 9, 6, 9, 8, 9,12, 8, + 8,11, 9,11,11,12,11,12,12,10,11,11,10,10,11, 7, + 10, 9, 9, 9, 9, 9,10, 9,10, 9,10,10,12,10,10,10, + 11,12,10,10, 7, 9, 9, 9,10, 9, 9,10,10, 9, 9, 9, + 11,11,10,10,10,10, 9, 9,12, 7, 9,10, 9,11, 9,10, + 9,10,11,11,11,10,11,12, 9,12,11,10,10,10, 7, 9, + 9, 9, 9,10,12,10, 9,11,12,10,11,12,12,11, 9,10, + 11,10,11, 7, 9,10,10,11,10, 9,10,11,11,11,10,12, + 12,12,11,11,10,11,11,12, 8, 9,10,12,11,10,10,12, + 12,12,12,12,10,11,11, 9,11,10,12,11,11, 8, 9,10, + 10,11,12,11,11,10,10,10,12,12,12, 9,10,12,12,12, + 12,12, 8,10,11,10,10,12, 9,11,12,12,11,12,12,12, + 12,10,12,10,10,10,10, 8,12,11,11,11,10,10,11,12, + 12,12,12,11,12,12,12,11,11,11,12,10, 9,10,10,12, + 10,12,10,12,12,10,10,10,11,12,12,12,11,12,12,12, + 11,10,11,12,12,12,11,12,12,11,12,12,11,12,12,12, + 12,11,12,12,10,10,10,10,11,11,12,11,12,12,12,12, + 12,12,12,11,12,11,10,11,11,12,11,11, 9,10,10,10, + 12,10,10,11, 9,11,12,11,12,11,12,12,10,11,10,12, + 9, 9, 9,12,11,10,11,10,12,10,12,10,12,12,12,11, + 11,11,11,11,10, 9,10,10,11,10,11,11,12,11,10,11, + 12,12,12,11,11, 9,12,10,12, 9,10,12,10,10,11,10, + 11,11,12,11,10,11,10,11,11,11,11,12,11,11,10, 9, + 10,10,10, 9,11,11,10, 9,12,10,11,12,11,12,12,11, + 12,11,12,11,10,11,10,12,11,12,11,12,11,12,10,11, + 10,10,12,11,10,11,11,11,10, +}; + +static float _vq_quantthresh__16u0__p7_2[] = { + -9.5, -8.5, -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, + -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, + 6.5, 7.5, 8.5, 9.5, +}; + +static long _vq_quantmap__16u0__p7_2[] = { + 19, 17, 15, 13, 11, 9, 7, 5, + 3, 1, 0, 2, 4, 6, 8, 10, + 12, 14, 16, 18, 20, +}; + +static encode_aux_threshmatch _vq_auxt__16u0__p7_2 = { + _vq_quantthresh__16u0__p7_2, + _vq_quantmap__16u0__p7_2, + 21, + 21 +}; + +static static_codebook _16u0__p7_2 = { + 2, 441, + _vq_lengthlist__16u0__p7_2, + 1, -529268736, 1611661312, 5, 0, + _vq_quantlist__16u0__p7_2, + NULL, + &_vq_auxt__16u0__p7_2, + NULL, + 0 +}; + +static long _huff_lengthlist__16u0__single[] = { + 3, 5, 8, 7,14, 8, 9,19, 5, 2, 5, 5, 9, 6, 9,19, + 8, 4, 5, 7, 8, 9,13,19, 7, 4, 6, 5, 9, 6, 9,19, + 12, 8, 7, 9,10,11,13,19, 8, 5, 8, 6, 9, 6, 7,19, + 8, 8,10, 7, 7, 4, 5,19,12,17,19,15,18,13,11,18, +}; + +static static_codebook _huff_book__16u0__single = { + 2, 64, + _huff_lengthlist__16u0__single, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__16u1__long[] = { + 3, 6,10, 8,12, 8,14, 8,14,19, 5, 3, 5, 5, 7, 6, + 11, 7,16,19, 7, 5, 6, 7, 7, 9,11,12,19,19, 6, 4, + 7, 5, 7, 6,10, 7,18,18, 8, 6, 7, 7, 7, 7, 8, 9, + 18,18, 7, 5, 8, 5, 7, 5, 8, 6,18,18,12, 9,10, 9, + 9, 9, 8, 9,18,18, 8, 7,10, 6, 8, 5, 6, 4,11,18, + 11,15,16,12,11, 8, 8, 6, 9,18,14,18,18,18,16,16, + 16,13,16,18, +}; + +static static_codebook _huff_book__16u1__long = { + 2, 100, + _huff_lengthlist__16u1__long, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__16u1__p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__16u1__p1_0[] = { + 1, 4, 4, 5, 7, 7, 5, 7, 7, 5, 8, 7, 7,10,10, 7, + 9,10, 5, 7, 8, 7,10, 9, 7,10,10, 5, 8, 8, 8,10, + 10, 8,10,10, 7,10,10,10,11,12,10,12,13, 7,10,10, + 9,13,11,10,12,13, 5, 8, 8, 8,10,10, 8,10,10, 7, + 10,10,10,12,12, 9,11,12, 7,10,11,10,12,12,10,13, + 11, +}; + +static float _vq_quantthresh__16u1__p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__16u1__p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__16u1__p1_0 = { + _vq_quantthresh__16u1__p1_0, + _vq_quantmap__16u1__p1_0, + 3, + 3 +}; + +static static_codebook _16u1__p1_0 = { + 4, 81, + _vq_lengthlist__16u1__p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__16u1__p1_0, + NULL, + &_vq_auxt__16u1__p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__16u1__p2_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__16u1__p2_0[] = { + 3, 4, 4, 5, 6, 6, 5, 6, 6, 5, 6, 6, 6, 7, 8, 6, + 7, 8, 5, 6, 6, 6, 8, 7, 6, 8, 7, 5, 6, 6, 6, 8, + 8, 6, 8, 8, 6, 8, 8, 7, 7,10, 8, 9, 9, 6, 8, 8, + 7, 9, 8, 8, 9,10, 5, 6, 6, 6, 8, 8, 7, 8, 8, 6, + 8, 8, 8,10, 9, 7, 8, 9, 6, 8, 8, 8, 9, 9, 7,10, + 8, +}; + +static float _vq_quantthresh__16u1__p2_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__16u1__p2_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__16u1__p2_0 = { + _vq_quantthresh__16u1__p2_0, + _vq_quantmap__16u1__p2_0, + 3, + 3 +}; + +static static_codebook _16u1__p2_0 = { + 4, 81, + _vq_lengthlist__16u1__p2_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__16u1__p2_0, + NULL, + &_vq_auxt__16u1__p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__16u1__p3_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__16u1__p3_0[] = { + 1, 5, 5, 8, 8, 6, 7, 7, 9, 9, 5, 7, 7, 9, 9, 9, + 10, 9,11,11, 9, 9,10,11,11, 6, 8, 8,10,10, 8, 9, + 10,11,11, 8, 9,10,11,11,10,11,11,12,13,10,11,11, + 13,13, 6, 8, 8,10,10, 8,10, 9,11,11, 8,10, 9,11, + 11,10,11,11,13,13,10,11,11,13,12, 9,11,11,14,13, + 10,12,12,15,14,10,12,11,14,13,12,13,13,15,15,12, + 13,13,16,14, 9,11,11,13,14,10,11,12,14,14,10,12, + 12,14,15,12,13,13,14,15,12,13,14,15,16, 5, 8, 8, + 11,11, 8,10,10,12,12, 8,10,10,12,12,11,12,12,14, + 14,11,12,12,14,14, 8,10,10,12,12, 9,11,12,12,13, + 10,12,12,13,13,12,12,13,14,15,11,13,13,15,15, 7, + 10,10,12,12, 9,12,11,13,12,10,11,12,13,13,12,13, + 12,15,14,11,12,13,15,15,10,12,12,15,14,11,13,13, + 16,15,11,13,13,16,15,14,13,14,15,16,13,15,15,17, + 17,10,12,12,14,15,11,12,12,15,15,11,13,13,15,16, + 13,15,13,16,15,13,15,15,16,17, 5, 8, 8,11,11, 8, + 10,10,12,12, 8,10,10,12,12,11,12,12,14,14,11,12, + 12,14,14, 7,10,10,12,12,10,12,12,14,13, 9,11,12, + 12,13,12,13,13,15,15,12,12,13,13,15, 7,10,10,12, + 13,10,11,12,13,13,10,12,11,13,13,11,13,13,15,15, + 12,13,12,15,14, 9,12,12,15,14,11,13,13,15,15,11, + 12,13,15,15,13,14,14,17,19,13,13,14,16,16,10,12, + 12,14,15,11,13,13,15,16,11,13,12,16,15,13,15,15, + 17,18,14,15,13,16,15, 8,11,11,15,14,10,12,12,16, + 15,10,12,12,16,16,14,15,15,18,17,13,14,15,16,18, + 9,12,12,15,15,11,12,14,16,17,11,13,13,16,15,15, + 15,15,17,18,14,15,16,17,17, 9,12,12,15,15,11,14, + 13,16,16,11,13,13,16,16,15,16,15,17,18,14,16,15, + 17,16,12,14,14,17,16,12,14,15,18,17,13,15,15,17, + 17,15,15,18,16,20,15,16,17,18,18,11,14,14,16,17, + 13,15,14,18,17,13,15,15,17,17,15,17,15,18,17,15, + 17,16,19,18, 8,11,11,14,15,10,12,12,15,15,10,12, + 12,16,16,13,14,14,17,16,14,15,15,17,17, 9,12,12, + 15,16,11,13,13,16,16,11,12,13,16,16,14,16,15,20, + 17,14,16,16,17,17, 9,12,12,15,16,11,13,13,16,17, + 11,13,13,17,16,14,15,15,17,18,15,15,15,18,18,11, + 14,14,17,16,13,15,15,17,17,13,14,14,18,17,15,16, + 16,18,19,15,15,17,17,19,11,14,14,16,17,13,15,14, + 17,19,13,15,14,18,17,15,17,16,18,18,15,17,15,18, + 16, +}; + +static float _vq_quantthresh__16u1__p3_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__16u1__p3_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__16u1__p3_0 = { + _vq_quantthresh__16u1__p3_0, + _vq_quantmap__16u1__p3_0, + 5, + 5 +}; + +static static_codebook _16u1__p3_0 = { + 4, 625, + _vq_lengthlist__16u1__p3_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__16u1__p3_0, + NULL, + &_vq_auxt__16u1__p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__16u1__p4_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__16u1__p4_0[] = { + 4, 5, 5, 8, 8, 6, 6, 7, 9, 9, 6, 6, 6, 9, 9, 9, + 10, 9,11,11, 9, 9,10,11,11, 6, 7, 7,10, 9, 7, 7, + 8, 9,10, 7, 7, 8,10,10,10,10,10,10,12, 9, 9,10, + 11,12, 6, 7, 7, 9, 9, 7, 8, 7,10,10, 7, 8, 7,10, + 10, 9,10, 9,12,11,10,10, 9,12,10, 9,10,10,12,11, + 10,10,10,12,12, 9,10,10,12,12,12,11,12,13,13,11, + 11,12,12,13, 9,10,10,11,12, 9,10,10,12,12,10,10, + 10,12,12,11,12,11,14,13,11,12,12,14,13, 5, 7, 7, + 10,10, 7, 8, 8,10,10, 7, 8, 7,10,10,10,10,10,12, + 12,10,10,10,12,12, 6, 8, 7,10,10, 7, 7, 9,10,11, + 8, 9, 9,11,10,10,10,11,11,13,10,10,11,12,13, 6, + 8, 8,10,10, 7, 9, 8,11,10, 8, 9, 9,10,11,10,11, + 10,13,11,10,11,10,12,12,10,11,10,12,11,10,10,10, + 12,13,10,11,11,13,12,11,11,13,11,14,12,12,13,14, + 14, 9,10,10,12,13,10,11,10,13,12,10,11,11,12,13, + 11,12,11,14,12,12,13,13,15,14, 5, 7, 7,10,10, 7, + 7, 8,10,10, 7, 8, 8,10,10,10,10,10,11,12,10,10, + 10,12,12, 7, 8, 8,10,10, 8, 9, 8,11,10, 7, 8, 9, + 10,11,10,11,11,12,12,10,10,11,11,13, 7, 7, 8,10, + 10, 8, 8, 9,10,11, 7, 9, 7,11,10,10,11,11,13,12, + 11,11,10,13,11, 9,10,10,12,12,10,11,11,13,12,10, + 10,11,12,12,12,13,13,14,14,11,11,12,12,14,10,10, + 11,12,12,10,11,11,12,13,10,10,10,13,12,12,13,13, + 15,14,12,13,10,14,11, 8,10,10,12,12,10,11,10,13, + 13, 9,10,10,12,12,12,13,13,15,14,11,12,12,13,13, + 9,10,10,13,12,10,10,11,13,13,10,11,10,13,12,12, + 12,13,14,15,12,13,12,15,13, 9,10,10,12,13,10,11, + 10,13,12,10,10,11,12,13,12,14,12,15,13,12,12,13, + 14,15,11,12,11,14,13,11,11,12,14,15,12,13,12,15, + 14,13,11,15,11,16,13,14,14,16,15,11,12,12,14,14, + 11,12,11,14,13,12,12,13,14,15,13,14,12,16,12,14, + 14,14,15,15, 8,10,10,12,12, 9,10,10,12,12,10,10, + 11,13,13,11,12,12,13,13,12,13,13,14,15, 9,10,10, + 13,12,10,11,11,13,12,10,10,11,13,13,12,13,12,15, + 14,12,12,13,13,16, 9, 9,10,12,13,10,10,11,12,13, + 10,11,10,13,13,12,12,13,13,15,13,13,12,15,13,11, + 12,12,14,14,12,13,12,15,14,11,11,12,13,14,14,14, + 14,16,15,13,12,15,12,16,11,11,12,13,14,12,13,13, + 14,15,10,12,11,14,13,14,15,14,16,16,13,14,11,15, + 11, +}; + +static float _vq_quantthresh__16u1__p4_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__16u1__p4_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__16u1__p4_0 = { + _vq_quantthresh__16u1__p4_0, + _vq_quantmap__16u1__p4_0, + 5, + 5 +}; + +static static_codebook _16u1__p4_0 = { + 4, 625, + _vq_lengthlist__16u1__p4_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__16u1__p4_0, + NULL, + &_vq_auxt__16u1__p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__16u1__p5_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__16u1__p5_0[] = { + 1, 4, 4, 7, 7, 7, 7, 9, 9, 4, 6, 6, 8, 8, 8, 8, + 10,10, 4, 5, 6, 8, 8, 8, 8,10,10, 7, 8, 8, 9, 9, + 9, 9,11,11, 7, 8, 8, 9, 9, 9, 9,11,11, 7, 8, 8, + 10, 9,11,11,12,11, 7, 8, 8, 9, 9,11,11,12,12, 9, + 10,10,11,11,12,12,13,12, 9,10,10,11,11,12,12,12, + 13, +}; + +static float _vq_quantthresh__16u1__p5_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__16u1__p5_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__16u1__p5_0 = { + _vq_quantthresh__16u1__p5_0, + _vq_quantmap__16u1__p5_0, + 9, + 9 +}; + +static static_codebook _16u1__p5_0 = { + 2, 81, + _vq_lengthlist__16u1__p5_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__16u1__p5_0, + NULL, + &_vq_auxt__16u1__p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__16u1__p6_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__16u1__p6_0[] = { + 3, 4, 4, 6, 6, 7, 7, 9, 9, 4, 4, 4, 6, 6, 8, 8, + 9, 9, 4, 4, 4, 6, 6, 7, 7, 9, 9, 6, 6, 6, 7, 7, + 8, 8,10, 9, 6, 6, 6, 7, 7, 8, 8, 9,10, 7, 8, 7, + 8, 8, 9, 9,10,10, 7, 8, 8, 8, 8, 9, 9,10,10, 9, + 9, 9,10,10,10,10,11,11, 9, 9, 9,10,10,10,10,11, + 11, +}; + +static float _vq_quantthresh__16u1__p6_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__16u1__p6_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__16u1__p6_0 = { + _vq_quantthresh__16u1__p6_0, + _vq_quantmap__16u1__p6_0, + 9, + 9 +}; + +static static_codebook _16u1__p6_0 = { + 2, 81, + _vq_lengthlist__16u1__p6_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__16u1__p6_0, + NULL, + &_vq_auxt__16u1__p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__16u1__p7_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__16u1__p7_0[] = { + 1, 4, 4, 4, 8, 8, 4, 8, 8, 5,11, 9, 8,12,11, 8, + 12,11, 5,10,11, 8,11,12, 8,11,12, 4,11,11,11,14, + 13,10,13,13, 8,14,13,12,14,16,12,16,15, 8,14,14, + 13,16,14,12,15,16, 4,11,11,10,14,13,11,14,14, 8, + 15,14,12,15,15,12,14,16, 8,14,14,11,16,15,12,15, + 13, +}; + +static float _vq_quantthresh__16u1__p7_0[] = { + -5.5, 5.5, +}; + +static long _vq_quantmap__16u1__p7_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__16u1__p7_0 = { + _vq_quantthresh__16u1__p7_0, + _vq_quantmap__16u1__p7_0, + 3, + 3 +}; + +static static_codebook _16u1__p7_0 = { + 4, 81, + _vq_lengthlist__16u1__p7_0, + 1, -529137664, 1618345984, 2, 0, + _vq_quantlist__16u1__p7_0, + NULL, + &_vq_auxt__16u1__p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__16u1__p7_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__16u1__p7_1[] = { + 2, 4, 4, 6, 6, 7, 7, 8, 8, 8, 8, 4, 6, 5, 7, 7, + 8, 8, 8, 8, 8, 8, 4, 5, 6, 7, 7, 8, 8, 8, 8, 8, + 8, 6, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 6, 7, 7, 8, + 8, 8, 8, 9, 9, 9, 9, 7, 8, 8, 8, 8, 9, 9, 9,10, + 9,10, 7, 8, 8, 8, 8, 9, 9, 9, 9,10, 9, 8, 8, 8, + 9, 9,10,10,10,10,10,10, 8, 8, 8, 9, 9, 9, 9,10, + 10,10,10, 8, 8, 8, 9, 9, 9,10,10,10,10,10, 8, 8, + 8, 9, 9,10,10,10,10,10,10, +}; + +static float _vq_quantthresh__16u1__p7_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__16u1__p7_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__16u1__p7_1 = { + _vq_quantthresh__16u1__p7_1, + _vq_quantmap__16u1__p7_1, + 11, + 11 +}; + +static static_codebook _16u1__p7_1 = { + 2, 121, + _vq_lengthlist__16u1__p7_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__16u1__p7_1, + NULL, + &_vq_auxt__16u1__p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__16u1__p8_0[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__16u1__p8_0[] = { + 1, 4, 4, 5, 5, 8, 8,10,10,12,12, 4, 7, 7, 8, 8, + 9, 9,12,11,14,13, 4, 7, 7, 7, 8, 9,10,11,11,13, + 12, 5, 8, 8, 9, 9,11,11,12,13,15,14, 5, 7, 8, 9, + 9,11,11,13,13,17,15, 8, 9,10,11,11,12,13,17,14, + 17,16, 8,10, 9,11,11,12,12,13,15,15,17,10,11,11, + 12,13,14,15,15,16,16,17, 9,11,11,12,12,14,15,17, + 15,15,16,11,14,12,14,15,16,15,16,16,16,15,11,13, + 13,14,14,15,15,16,16,15,16, +}; + +static float _vq_quantthresh__16u1__p8_0[] = { + -49.5, -38.5, -27.5, -16.5, -5.5, 5.5, 16.5, 27.5, + 38.5, 49.5, +}; + +static long _vq_quantmap__16u1__p8_0[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__16u1__p8_0 = { + _vq_quantthresh__16u1__p8_0, + _vq_quantmap__16u1__p8_0, + 11, + 11 +}; + +static static_codebook _16u1__p8_0 = { + 2, 121, + _vq_lengthlist__16u1__p8_0, + 1, -524582912, 1618345984, 4, 0, + _vq_quantlist__16u1__p8_0, + NULL, + &_vq_auxt__16u1__p8_0, + NULL, + 0 +}; + +static long _vq_quantlist__16u1__p8_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__16u1__p8_1[] = { + 2, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 4, 6, 6, 7, 7, + 8, 7, 8, 8, 8, 8, 4, 6, 6, 7, 7, 7, 7, 8, 8, 8, + 8, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 9, 6, 7, 7, 7, + 7, 8, 8, 8, 8, 9, 9, 7, 7, 7, 8, 8, 8, 8, 9, 9, + 9, 9, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 8, 8, 8, + 8, 8, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 9, 9, 9, + 9, 9, 9, 8, 8, 8, 9, 8, 9, 9, 9, 9, 9, 9, 8, 8, + 8, 9, 9, 9, 9, 9, 9, 9, 9, +}; + +static float _vq_quantthresh__16u1__p8_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__16u1__p8_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__16u1__p8_1 = { + _vq_quantthresh__16u1__p8_1, + _vq_quantmap__16u1__p8_1, + 11, + 11 +}; + +static static_codebook _16u1__p8_1 = { + 2, 121, + _vq_lengthlist__16u1__p8_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__16u1__p8_1, + NULL, + &_vq_auxt__16u1__p8_1, + NULL, + 0 +}; + +static long _vq_quantlist__16u1__p9_0[] = { + 7, + 6, + 8, + 5, + 9, + 4, + 10, + 3, + 11, + 2, + 12, + 1, + 13, + 0, + 14, +}; + +static long _vq_lengthlist__16u1__p9_0[] = { + 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, +}; + +static float _vq_quantthresh__16u1__p9_0[] = { + -1657.5, -1402.5, -1147.5, -892.5, -637.5, -382.5, -127.5, 127.5, + 382.5, 637.5, 892.5, 1147.5, 1402.5, 1657.5, +}; + +static long _vq_quantmap__16u1__p9_0[] = { + 13, 11, 9, 7, 5, 3, 1, 0, + 2, 4, 6, 8, 10, 12, 14, +}; + +static encode_aux_threshmatch _vq_auxt__16u1__p9_0 = { + _vq_quantthresh__16u1__p9_0, + _vq_quantmap__16u1__p9_0, + 15, + 15 +}; + +static static_codebook _16u1__p9_0 = { + 2, 225, + _vq_lengthlist__16u1__p9_0, + 1, -514071552, 1627381760, 4, 0, + _vq_quantlist__16u1__p9_0, + NULL, + &_vq_auxt__16u1__p9_0, + NULL, + 0 +}; + +static long _vq_quantlist__16u1__p9_1[] = { + 7, + 6, + 8, + 5, + 9, + 4, + 10, + 3, + 11, + 2, + 12, + 1, + 13, + 0, + 14, +}; + +static long _vq_lengthlist__16u1__p9_1[] = { + 1, 6, 5, 9, 9,10,10, 6, 7, 9, 9,10,10,10,10, 5, + 10, 8,10, 8,10,10, 8, 8,10, 9,10,10,10,10, 5, 8, + 9,10,10,10,10, 8,10,10,10,10,10,10,10, 9,10,10, + 10,10,10,10, 9, 9,10,10,10,10,10,10, 9, 9, 8, 9, + 10,10,10, 9,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10, 8,10,10,10,10, + 10,10,10,10,10,10,10,10,10, 6, 8, 8,10,10,10, 8, + 10,10,10,10,10,10,10,10, 5, 8, 8,10,10,10, 9, 9, + 10,10,10,10,10,10,10,10, 9,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, +}; + +static float _vq_quantthresh__16u1__p9_1[] = { + -110.5, -93.5, -76.5, -59.5, -42.5, -25.5, -8.5, 8.5, + 25.5, 42.5, 59.5, 76.5, 93.5, 110.5, +}; + +static long _vq_quantmap__16u1__p9_1[] = { + 13, 11, 9, 7, 5, 3, 1, 0, + 2, 4, 6, 8, 10, 12, 14, +}; + +static encode_aux_threshmatch _vq_auxt__16u1__p9_1 = { + _vq_quantthresh__16u1__p9_1, + _vq_quantmap__16u1__p9_1, + 15, + 15 +}; + +static static_codebook _16u1__p9_1 = { + 2, 225, + _vq_lengthlist__16u1__p9_1, + 1, -522338304, 1620115456, 4, 0, + _vq_quantlist__16u1__p9_1, + NULL, + &_vq_auxt__16u1__p9_1, + NULL, + 0 +}; + +static long _vq_quantlist__16u1__p9_2[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__16u1__p9_2[] = { + 1, 6, 6, 7, 8, 8,11,10, 9, 9,11, 9,10, 9,11,11, + 9, 6, 7, 6,11, 8,11, 9,10,10,11, 9,11,10,10,10, + 11, 9, 5, 7, 7, 8, 8,10,11, 8, 8,11, 9, 9,10,11, + 9,10,11, 8, 9, 6, 8, 8, 9, 9,10,10,11,11,11, 9, + 11,10, 9,11, 8, 8, 8, 9, 8, 9,10,11, 9, 9,11,11, + 10, 9, 9,11,10, 8,11, 8, 9, 8,11, 9,10, 9,10,11, + 11,10,10, 9,10,10, 8, 8, 9,10,10,10, 9,11, 9,10, + 11,11,11,11,10, 9,11, 9, 9,11,11,10, 8,11,11,11, + 9,10,10,11,10,11,11, 9,11,10, 9,11,10,10,10,10, + 9,11,10,11,10, 9, 9,10,11, 9, 8,10,11,11,10,10, + 11, 9,11,10,11,11,10,11, 9, 9, 8,10, 8, 9,11, 9, + 8,10,10, 9,11,10,11,10,11, 9,11, 8,10,11,11,11, + 11,10,10,11,11,11,11,10,11,11,10, 9, 8,10,10, 9, + 11,10,11,11,11, 9, 9, 9,11,11,11,10,10, 9, 9,10, + 9,11,11,11,11, 8,10,11,10,11,11,10,11,11, 9, 9, + 9,10, 9,11, 9,11,11,11,11,11,10,11,11,10,11,10, + 11,11, 9,11,10,11,10, 9,10, 9,10,10,11,11,11,11, + 9,10, 9,10,11,11,10,11,11,11,11,11,11,10,11,11, + 10, +}; + +static float _vq_quantthresh__16u1__p9_2[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__16u1__p9_2[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__16u1__p9_2 = { + _vq_quantthresh__16u1__p9_2, + _vq_quantmap__16u1__p9_2, + 17, + 17 +}; + +static static_codebook _16u1__p9_2 = { + 2, 289, + _vq_lengthlist__16u1__p9_2, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__16u1__p9_2, + NULL, + &_vq_auxt__16u1__p9_2, + NULL, + 0 +}; + +static long _huff_lengthlist__16u1__short[] = { + 5, 7,10, 9,11,10,15,11,13,16, 6, 4, 6, 6, 7, 7, + 10, 9,12,16,10, 6, 5, 6, 6, 7,10,11,16,16, 9, 6, + 7, 6, 7, 7,10, 8,14,16,11, 6, 5, 4, 5, 6, 8, 9, + 15,16, 9, 6, 6, 5, 6, 6, 9, 8,14,16,12, 7, 6, 6, + 5, 6, 6, 7,13,16, 8, 6, 7, 6, 5, 5, 4, 4,11,16, + 9, 8, 9, 9, 7, 7, 6, 5,13,16,14,14,16,15,16,15, + 16,16,16,16, +}; + +static static_codebook _huff_book__16u1__short = { + 2, 100, + _huff_lengthlist__16u1__short, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__16u2__long[] = { + 5, 7,10,10,10,11,11,13,18,19, 6, 5, 5, 6, 7, 8, + 9,12,19,19, 8, 5, 4, 4, 6, 7, 9,13,19,19, 8, 5, + 4, 4, 5, 6, 8,12,17,19, 7, 5, 5, 4, 4, 5, 7,12, + 18,18, 8, 7, 7, 6, 5, 5, 6,10,18,18, 9, 9, 9, 8, + 6, 5, 6, 9,18,18,11,13,13,13, 8, 7, 7, 9,16,18, + 13,17,18,16,11, 9, 9, 9,17,18,15,18,18,18,15,13, + 13,14,18,18, +}; + +static static_codebook _huff_book__16u2__long = { + 2, 100, + _huff_lengthlist__16u2__long, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__16u2__short[] = { + 8,11,12,12,14,15,16,16,16,16, 9, 7, 7, 8, 9,11, + 13,14,16,16,13, 7, 6, 6, 7, 9,12,13,15,16,15, 7, + 6, 5, 4, 6,10,11,14,16,12, 8, 7, 4, 2, 4, 7,10, + 14,16,11, 9, 7, 5, 3, 4, 6, 9,14,16,11,10, 9, 7, + 5, 5, 6, 9,16,16,10,10, 9, 8, 6, 6, 7,10,16,16, + 11,11,11,10,10,10,11,14,16,16,16,14,14,13,14,16, + 16,16,16,16, +}; + +static static_codebook _huff_book__16u2__short = { + 2, 100, + _huff_lengthlist__16u2__short, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__16u2_p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__16u2_p1_0[] = { + 1, 5, 5, 5, 7, 7, 5, 7, 7, 5, 7, 7, 7, 9, 9, 7, + 9, 9, 5, 7, 7, 7, 9, 9, 7, 9, 9, 5, 7, 7, 8, 9, + 9, 7, 9, 9, 7, 9, 9, 9,10,10, 9,10,10, 7, 9, 9, + 9,10,10, 9,10,11, 5, 7, 8, 8, 9, 9, 8, 9, 9, 7, + 9, 9, 9,10,10, 9, 9,10, 7, 9, 9, 9,10,10, 9,11, + 10, +}; + +static float _vq_quantthresh__16u2_p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__16u2_p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__16u2_p1_0 = { + _vq_quantthresh__16u2_p1_0, + _vq_quantmap__16u2_p1_0, + 3, + 3 +}; + +static static_codebook _16u2_p1_0 = { + 4, 81, + _vq_lengthlist__16u2_p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__16u2_p1_0, + NULL, + &_vq_auxt__16u2_p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__16u2_p2_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__16u2_p2_0[] = { + 3, 5, 5, 8, 8, 5, 7, 7, 9, 9, 5, 7, 7, 9, 9, 9, + 10, 9,11,11, 9, 9, 9,11,11, 5, 7, 7, 9, 9, 7, 8, + 8,10,10, 7, 8, 8,10,10,10,10,10,12,12, 9,10,10, + 11,12, 5, 7, 7, 9, 9, 7, 8, 8,10,10, 7, 8, 8,10, + 10, 9,10,10,12,11,10,10,10,12,12, 9,10,10,12,12, + 10,11,10,13,12, 9,10,10,12,12,12,12,12,14,14,11, + 12,12,13,14, 9,10,10,12,12, 9,10,10,12,12,10,10, + 10,12,12,11,12,12,14,13,12,13,12,14,14, 5, 7, 7, + 9, 9, 7, 8, 8,10,10, 7, 8, 8,10,10,10,11,10,12, + 12,10,10,11,12,12, 7, 8, 8,10,10, 8, 9, 9,11,11, + 8, 9, 9,11,11,11,11,11,12,13,10,11,11,12,13, 7, + 8, 8,10,10, 8, 9, 8,11,10, 8, 9, 9,11,11,10,11, + 10,13,12,10,11,11,13,13, 9,11,10,13,13,10,11,11, + 13,13,10,11,11,13,13,12,12,13,13,15,12,12,13,14, + 15, 9,10,10,12,12,10,11,10,13,12,10,11,11,13,13, + 11,13,11,14,13,12,13,13,15,15, 5, 7, 7, 9, 9, 7, + 8, 8,10,10, 7, 8, 8,10,10,10,10,10,12,12,10,10, + 11,12,12, 7, 8, 8,10,10, 8, 9, 9,11,11, 8, 8, 9, + 10,11,10,11,11,13,13,10,10,11,12,13, 7, 8, 8,10, + 11, 8, 9, 9,11,11, 8, 9, 9,11,11,10,11,11,13,12, + 11,11,11,13,12, 9,10,10,12,12,10,11,11,13,13,10, + 10,11,12,13,12,13,13,15,14,11,11,13,12,14,10,10, + 11,13,13,10,11,11,13,13,10,11,11,13,13,12,13,13, + 14,14,12,13,12,14,13, 8,10, 9,12,12, 9,11,10,13, + 13, 9,10,10,12,13,12,13,13,14,14,12,12,13,14,14, + 9,11,10,13,13,10,11,11,13,13,10,11,11,13,13,12, + 13,13,15,15,13,13,13,14,15, 9,10,10,12,13,10,11, + 10,13,12,10,11,11,13,13,12,13,12,15,14,13,13,13, + 14,15,11,12,12,15,14,12,12,13,15,15,12,13,13,15, + 14,14,13,15,14,16,13,14,15,16,16,11,12,12,14,14, + 11,12,12,15,14,12,13,13,15,15,13,14,13,16,14,14, + 14,14,16,16, 8, 9, 9,12,12, 9,10,10,13,12, 9,10, + 10,13,13,12,12,12,14,14,12,12,13,15,15, 9,10,10, + 13,12,10,11,11,13,13,10,10,11,13,14,12,13,13,15, + 15,12,12,13,14,15, 9,10,10,13,13,10,11,11,13,13, + 10,11,11,13,13,12,13,13,14,14,13,14,13,15,14,11, + 12,12,14,14,12,13,13,15,14,11,12,12,14,15,14,14, + 14,16,15,13,12,14,14,16,11,12,13,14,15,12,13,13, + 14,16,12,13,12,15,14,13,15,14,16,16,14,15,13,16, + 13, +}; + +static float _vq_quantthresh__16u2_p2_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__16u2_p2_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__16u2_p2_0 = { + _vq_quantthresh__16u2_p2_0, + _vq_quantmap__16u2_p2_0, + 5, + 5 +}; + +static static_codebook _16u2_p2_0 = { + 4, 625, + _vq_lengthlist__16u2_p2_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__16u2_p2_0, + NULL, + &_vq_auxt__16u2_p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__16u2_p3_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__16u2_p3_0[] = { + 2, 4, 4, 6, 6, 7, 7, 9, 9, 4, 5, 5, 6, 6, 8, 7, + 9, 9, 4, 5, 5, 6, 6, 7, 8, 9, 9, 6, 6, 6, 7, 7, + 8, 8,10,10, 6, 6, 6, 7, 7, 8, 8, 9,10, 7, 8, 7, + 8, 8, 9, 9,10,10, 7, 8, 8, 8, 8, 9, 9,10,10, 9, + 9, 9,10, 9,10,10,11,11, 9, 9, 9,10,10,10,10,11, + 11, +}; + +static float _vq_quantthresh__16u2_p3_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__16u2_p3_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__16u2_p3_0 = { + _vq_quantthresh__16u2_p3_0, + _vq_quantmap__16u2_p3_0, + 9, + 9 +}; + +static static_codebook _16u2_p3_0 = { + 2, 81, + _vq_lengthlist__16u2_p3_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__16u2_p3_0, + NULL, + &_vq_auxt__16u2_p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__16u2_p4_0[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__16u2_p4_0[] = { + 2, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9,10,10,11,11,11, + 11, 5, 5, 5, 7, 7, 8, 8, 9, 9, 9, 9,10,10,11,11, + 12,11, 5, 5, 5, 7, 7, 8, 8, 9, 9, 9, 9,10,10,11, + 11,12,12, 6, 7, 7, 7, 7, 8, 8, 9, 9, 9, 9,10,10, + 11,11,12,12, 6, 7, 7, 7, 7, 8, 8, 9, 9, 9, 9,10, + 10,11,11,12,12, 7, 8, 8, 8, 8, 9, 9, 9, 9,10,10, + 11,11,12,12,12,12, 7, 8, 8, 8, 8, 9, 9, 9, 9,10, + 10,11,11,11,12,12,12, 9, 9, 9, 9, 9, 9,10,10,10, + 10,10,11,11,12,12,13,13, 8, 9, 9, 9, 9,10, 9,10, + 10,10,10,11,11,12,12,13,13, 9, 9, 9, 9, 9,10,10, + 10,10,11,11,11,12,12,12,13,13, 9, 9, 9, 9, 9,10, + 10,10,10,11,11,12,11,12,12,13,13,10,10,10,10,10, + 11,11,11,11,11,12,12,12,12,13,13,14,10,10,10,10, + 10,11,11,11,11,12,11,12,12,13,12,13,13,11,11,11, + 11,11,12,12,12,12,12,12,13,13,13,13,14,14,11,11, + 11,11,11,12,12,12,12,12,12,13,12,13,13,14,14,11, + 12,12,12,12,12,12,13,13,13,13,13,13,14,14,14,14, + 11,12,12,12,12,12,12,13,13,13,13,14,13,14,14,14, + 14, +}; + +static float _vq_quantthresh__16u2_p4_0[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__16u2_p4_0[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__16u2_p4_0 = { + _vq_quantthresh__16u2_p4_0, + _vq_quantmap__16u2_p4_0, + 17, + 17 +}; + +static static_codebook _16u2_p4_0 = { + 2, 289, + _vq_lengthlist__16u2_p4_0, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__16u2_p4_0, + NULL, + &_vq_auxt__16u2_p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__16u2_p5_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__16u2_p5_0[] = { + 1, 4, 4, 5, 7, 7, 5, 7, 7, 5, 9, 8, 7,10, 9, 7, + 10, 9, 5, 8, 9, 7, 9,10, 7, 9,10, 4, 9, 9, 9,11, + 11, 8,11,11, 7,11,11,10,10,13,10,14,13, 7,11,11, + 10,13,11,10,13,14, 5, 9, 9, 8,11,11, 9,11,11, 7, + 11,11,10,14,13,10,12,14, 7,11,11,10,13,13,10,13, + 10, +}; + +static float _vq_quantthresh__16u2_p5_0[] = { + -5.5, 5.5, +}; + +static long _vq_quantmap__16u2_p5_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__16u2_p5_0 = { + _vq_quantthresh__16u2_p5_0, + _vq_quantmap__16u2_p5_0, + 3, + 3 +}; + +static static_codebook _16u2_p5_0 = { + 4, 81, + _vq_lengthlist__16u2_p5_0, + 1, -529137664, 1618345984, 2, 0, + _vq_quantlist__16u2_p5_0, + NULL, + &_vq_auxt__16u2_p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__16u2_p5_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__16u2_p5_1[] = { + 2, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 5, 5, 5, 7, 7, + 7, 7, 8, 8, 8, 8, 5, 5, 6, 7, 7, 7, 7, 8, 8, 8, + 8, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 6, 7, 7, 7, + 7, 8, 8, 8, 8, 8, 8, 7, 7, 7, 8, 8, 8, 8, 9, 9, + 9, 9, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 8, 8, 8, + 8, 8, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 9, 9, 9, + 9, 9, 9, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 8, 8, + 8, 8, 8, 9, 9, 9, 9, 9, 9, +}; + +static float _vq_quantthresh__16u2_p5_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__16u2_p5_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__16u2_p5_1 = { + _vq_quantthresh__16u2_p5_1, + _vq_quantmap__16u2_p5_1, + 11, + 11 +}; + +static static_codebook _16u2_p5_1 = { + 2, 121, + _vq_lengthlist__16u2_p5_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__16u2_p5_1, + NULL, + &_vq_auxt__16u2_p5_1, + NULL, + 0 +}; + +static long _vq_quantlist__16u2_p6_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__16u2_p6_0[] = { + 1, 4, 4, 7, 7, 8, 8, 8, 8, 9, 9,10,10, 4, 6, 6, + 8, 8, 9, 9, 9, 9,10,10,12,11, 4, 6, 6, 8, 8, 9, + 9, 9, 9,10,10,11,12, 7, 8, 8, 9, 9,10,10,10,10, + 12,12,13,12, 7, 8, 8, 9, 9,10,10,10,10,11,12,12, + 12, 8, 9, 9,10,10,11,11,11,11,12,12,13,13, 8, 9, + 9,10,10,11,11,11,11,12,13,13,13, 8, 9, 9,10,10, + 11,11,12,12,13,13,14,14, 8, 9, 9,10,10,11,11,12, + 12,13,13,14,14, 9,10,10,11,12,13,12,13,14,14,14, + 14,14, 9,10,10,11,12,12,13,13,13,14,14,14,14,10, + 11,11,12,12,13,13,14,14,15,15,15,15,10,11,11,12, + 12,13,13,14,14,14,14,15,15, +}; + +static float _vq_quantthresh__16u2_p6_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__16u2_p6_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__16u2_p6_0 = { + _vq_quantthresh__16u2_p6_0, + _vq_quantmap__16u2_p6_0, + 13, + 13 +}; + +static static_codebook _16u2_p6_0 = { + 2, 169, + _vq_lengthlist__16u2_p6_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__16u2_p6_0, + NULL, + &_vq_auxt__16u2_p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__16u2_p6_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__16u2_p6_1[] = { + 2, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 6, 6, 5, 5, 5, 6, 6, +}; + +static float _vq_quantthresh__16u2_p6_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__16u2_p6_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__16u2_p6_1 = { + _vq_quantthresh__16u2_p6_1, + _vq_quantmap__16u2_p6_1, + 5, + 5 +}; + +static static_codebook _16u2_p6_1 = { + 2, 25, + _vq_lengthlist__16u2_p6_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__16u2_p6_1, + NULL, + &_vq_auxt__16u2_p6_1, + NULL, + 0 +}; + +static long _vq_quantlist__16u2_p7_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__16u2_p7_0[] = { + 1, 4, 4, 7, 7, 7, 7, 8, 8, 9, 9,10,10, 4, 6, 6, + 9, 9, 9, 9, 9, 9,10,10,11,11, 4, 6, 6, 8, 9, 9, + 9, 9, 9,10,11,12,11, 7, 8, 9,10,10,10,10,11,10, + 11,12,12,13, 7, 9, 9,10,10,10,10,10,10,11,12,13, + 13, 7, 9, 8,10,10,11,11,11,12,12,13,13,14, 7, 9, + 9,10,10,11,11,11,12,13,13,13,13, 8, 9, 9,10,11, + 11,12,12,12,13,13,13,13, 8, 9, 9,10,11,11,11,12, + 12,13,13,14,14, 9,10,10,12,11,12,13,13,13,14,13, + 13,13, 9,10,10,11,11,12,12,13,14,13,13,14,13,10, + 11,11,12,13,14,14,14,15,14,14,14,14,10,11,11,12, + 12,13,13,13,14,14,14,15,14, +}; + +static float _vq_quantthresh__16u2_p7_0[] = { + -60.5, -49.5, -38.5, -27.5, -16.5, -5.5, 5.5, 16.5, + 27.5, 38.5, 49.5, 60.5, +}; + +static long _vq_quantmap__16u2_p7_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__16u2_p7_0 = { + _vq_quantthresh__16u2_p7_0, + _vq_quantmap__16u2_p7_0, + 13, + 13 +}; + +static static_codebook _16u2_p7_0 = { + 2, 169, + _vq_lengthlist__16u2_p7_0, + 1, -523206656, 1618345984, 4, 0, + _vq_quantlist__16u2_p7_0, + NULL, + &_vq_auxt__16u2_p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__16u2_p7_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__16u2_p7_1[] = { + 3, 5, 5, 6, 6, 7, 7, 7, 7, 7, 7, 5, 6, 6, 7, 7, + 7, 7, 7, 7, 8, 8, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, + 8, 6, 6, 7, 7, 7, 8, 7, 8, 8, 8, 8, 6, 7, 7, 7, + 7, 7, 7, 8, 8, 8, 8, 7, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 8, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, + 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 8, 8, 8, 8, 8, + 8, 8, 8, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, +}; + +static float _vq_quantthresh__16u2_p7_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__16u2_p7_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__16u2_p7_1 = { + _vq_quantthresh__16u2_p7_1, + _vq_quantmap__16u2_p7_1, + 11, + 11 +}; + +static static_codebook _16u2_p7_1 = { + 2, 121, + _vq_lengthlist__16u2_p7_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__16u2_p7_1, + NULL, + &_vq_auxt__16u2_p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__16u2_p8_0[] = { + 7, + 6, + 8, + 5, + 9, + 4, + 10, + 3, + 11, + 2, + 12, + 1, + 13, + 0, + 14, +}; + +static long _vq_lengthlist__16u2_p8_0[] = { + 1, 5, 5, 7, 7, 8, 8, 7, 7, 8, 8,10, 9,11,11, 4, + 6, 6, 8, 8,10, 9, 9, 8, 9, 9,10,10,12,14, 4, 6, + 7, 8, 9, 9,10, 9, 8, 9, 9,10,12,12,11, 7, 8, 8, + 10,10,10,10, 9, 9,10,10,11,13,13,12, 7, 8, 8, 9, + 11,11,10, 9, 9,11,10,12,11,11,14, 8, 9, 9,11,10, + 11,11,10,10,11,11,13,12,14,12, 8, 9, 9,11,12,11, + 11,10,10,12,11,12,12,12,14, 7, 8, 8, 9, 9,10,10, + 10,11,12,11,13,13,14,12, 7, 8, 9, 9, 9,10,10,11, + 11,11,12,12,14,14,14, 8,10, 9,10,11,11,11,11,14, + 12,12,13,14,14,13, 9, 9, 9,10,11,11,11,12,12,12, + 14,12,14,13,14,10,10,10,12,11,12,11,14,13,14,13, + 14,14,13,14, 9,10,10,11,12,11,13,12,13,13,14,14, + 14,13,14,10,13,13,12,12,11,12,14,13,14,13,14,12, + 14,13,10,11,11,12,11,12,12,14,14,14,13,14,14,14, + 14, +}; + +static float _vq_quantthresh__16u2_p8_0[] = { + -136.5, -115.5, -94.5, -73.5, -52.5, -31.5, -10.5, 10.5, + 31.5, 52.5, 73.5, 94.5, 115.5, 136.5, +}; + +static long _vq_quantmap__16u2_p8_0[] = { + 13, 11, 9, 7, 5, 3, 1, 0, + 2, 4, 6, 8, 10, 12, 14, +}; + +static encode_aux_threshmatch _vq_auxt__16u2_p8_0 = { + _vq_quantthresh__16u2_p8_0, + _vq_quantmap__16u2_p8_0, + 15, + 15 +}; + +static static_codebook _16u2_p8_0 = { + 2, 225, + _vq_lengthlist__16u2_p8_0, + 1, -520986624, 1620377600, 4, 0, + _vq_quantlist__16u2_p8_0, + NULL, + &_vq_auxt__16u2_p8_0, + NULL, + 0 +}; + +static long _vq_quantlist__16u2_p8_1[] = { + 10, + 9, + 11, + 8, + 12, + 7, + 13, + 6, + 14, + 5, + 15, + 4, + 16, + 3, + 17, + 2, + 18, + 1, + 19, + 0, + 20, +}; + +static long _vq_lengthlist__16u2_p8_1[] = { + 2, 5, 5, 7, 7, 8, 8, 8, 8, 9, 9,10, 9,10, 9, 9, + 9,10,10,10,10, 5, 6, 6, 7, 7, 8, 8, 9, 9, 9, 9, + 10, 9,10,10,10,10,10,10,11,10, 5, 6, 6, 7, 7, 8, + 8, 8, 9, 9,10,10,10,10,10,10,10,10,10,10,10, 7, + 7, 7, 8, 8, 9, 8, 9, 9,10, 9,10,10,10,10,10,10, + 11,10,11,10, 7, 7, 7, 8, 8, 8, 9, 9, 9,10, 9,10, + 10,10,10,10,10,10,10,10,10, 8, 8, 8, 9, 9, 9, 9, + 10, 9,10,10,10,10,10,10,10,11,10,10,11,10, 8, 8, + 8, 8, 9, 9, 9, 9,10,10,10,10,10,10,10,10,10,11, + 11,10,10, 8, 9, 9, 9, 9, 9, 9,10,10,10,10,10,10, + 11,10,11,10,11,10,11,10, 8, 9, 9, 9, 9, 9,10,10, + 10,10,10,10,10,10,10,10,11,11,10,10,10, 9,10, 9, + 9,10,10,10,11,10,10,10,10,10,10,10,10,11,11,11, + 11,11, 9, 9, 9,10, 9,10,10,10,10,10,10,11,10,11, + 10,11,11,11,11,10,10, 9,10, 9,10,10,10,10,11,10, + 10,10,10,10,11,10,11,10,11,10,10,11, 9,10,10,10, + 10,10,10,10,10,10,11,10,10,11,11,10,11,11,11,11, + 11, 9, 9,10,10,10,10,10,11,10,10,11,10,10,11,10, + 10,11,11,11,11,11, 9,10,10,10,10,10,10,10,11,10, + 11,10,11,10,11,11,11,11,11,10,11,10,10,10,10,10, + 10,10,10,10,11,11,11,11,11,11,11,11,11,10,11,11, + 10,10,10,10,10,11,10,10,10,11,10,11,11,11,11,10, + 12,11,11,11,10,10,10,10,10,10,11,10,10,10,11,11, + 12,11,11,11,11,11,11,11,11,11,10,10,10,11,10,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10, + 10,10,11,10,11,10,10,11,11,11,11,11,11,11,11,11, + 11,11,11,10,10,10,10,10,10,10,11,11,10,11,11,10, + 11,11,10,11,11,11,10,11,11, +}; + +static float _vq_quantthresh__16u2_p8_1[] = { + -9.5, -8.5, -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, + -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, + 6.5, 7.5, 8.5, 9.5, +}; + +static long _vq_quantmap__16u2_p8_1[] = { + 19, 17, 15, 13, 11, 9, 7, 5, + 3, 1, 0, 2, 4, 6, 8, 10, + 12, 14, 16, 18, 20, +}; + +static encode_aux_threshmatch _vq_auxt__16u2_p8_1 = { + _vq_quantthresh__16u2_p8_1, + _vq_quantmap__16u2_p8_1, + 21, + 21 +}; + +static static_codebook _16u2_p8_1 = { + 2, 441, + _vq_lengthlist__16u2_p8_1, + 1, -529268736, 1611661312, 5, 0, + _vq_quantlist__16u2_p8_1, + NULL, + &_vq_auxt__16u2_p8_1, + NULL, + 0 +}; + +static long _vq_quantlist__16u2_p9_0[] = { + 5586, + 4655, + 6517, + 3724, + 7448, + 2793, + 8379, + 1862, + 9310, + 931, + 10241, + 0, + 11172, + 5521, + 5651, +}; + +static long _vq_lengthlist__16u2_p9_0[] = { + 1,10,10,10,10,10,10,10,10,10,10,10,10, 5, 4,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10, 4,10,10,10,10,10,10,10,10,10,10,10,10, + 6, 6, 5,10,10,10,10, 9, 9, 9, 9, 9, 9, 9, 9, 5, + 5, +}; + +static float _vq_quantthresh__16u2_p9_0[] = { + -5120.5, -4189.5, -3258.5, -2327.5, -1396.5, -498, -32.5, 32.5, + 498, 1396.5, 2327.5, 3258.5, 4189.5, 5120.5, +}; + +static long _vq_quantmap__16u2_p9_0[] = { + 11, 9, 7, 5, 3, 1, 13, 0, + 14, 2, 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__16u2_p9_0 = { + _vq_quantthresh__16u2_p9_0, + _vq_quantmap__16u2_p9_0, + 15, + 15 +}; + +static static_codebook _16u2_p9_0 = { + 2, 225, + _vq_lengthlist__16u2_p9_0, + 1, -510275072, 1611661312, 14, 0, + _vq_quantlist__16u2_p9_0, + NULL, + &_vq_auxt__16u2_p9_0, + NULL, + 0 +}; + +static long _vq_quantlist__16u2_p9_1[] = { + 392, + 343, + 441, + 294, + 490, + 245, + 539, + 196, + 588, + 147, + 637, + 98, + 686, + 49, + 735, + 0, + 784, + 388, + 396, +}; + +static long _vq_lengthlist__16u2_p9_1[] = { + 1,12,10,12,10,12,10,12,11,12,12,12,12,12,12,12, + 12, 5, 5, 9,10,12,11,11,12,12,12,12,12,12,12,12, + 12,12,12,12,10, 9, 9,11, 9,11,11,12,11,12,12,12, + 12,12,12,12,12,12,12, 8, 8,10,11, 9,12,11,12,12, + 12,12,12,12,12,12,12,12,12,12, 9, 8,10,11,12,11, + 12,11,12,12,12,12,12,12,12,12,12,12,12, 8, 9,11, + 11,10,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 9,10,11,12,11,12,11,12,12,12,12,12,12,12,12,12, + 12,12,12, 9, 9,11,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11, 5, 8, 9, 9, 8,11, 9,11,11,11,11,11,11, + 11,11,11,11, 5, 5, 4, 8, 8, 8, 8,10, 9,10,10,11, + 11,11,11,11,11,11,11, 5, 4, +}; + +static float _vq_quantthresh__16u2_p9_1[] = { + -367.5, -318.5, -269.5, -220.5, -171.5, -122.5, -73.5, -26.5, + -2, 2, 26.5, 73.5, 122.5, 171.5, 220.5, 269.5, + 318.5, 367.5, +}; + +static long _vq_quantmap__16u2_p9_1[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 17, 0, 18, 2, 4, 6, 8, 10, + 12, 14, 16, +}; + +static encode_aux_threshmatch _vq_auxt__16u2_p9_1 = { + _vq_quantthresh__16u2_p9_1, + _vq_quantmap__16u2_p9_1, + 19, + 19 +}; + +static static_codebook _16u2_p9_1 = { + 2, 361, + _vq_lengthlist__16u2_p9_1, + 1, -518488064, 1611661312, 10, 0, + _vq_quantlist__16u2_p9_1, + NULL, + &_vq_auxt__16u2_p9_1, + NULL, + 0 +}; + +static long _vq_quantlist__16u2_p9_2[] = { + 24, + 23, + 25, + 22, + 26, + 21, + 27, + 20, + 28, + 19, + 29, + 18, + 30, + 17, + 31, + 16, + 32, + 15, + 33, + 14, + 34, + 13, + 35, + 12, + 36, + 11, + 37, + 10, + 38, + 9, + 39, + 8, + 40, + 7, + 41, + 6, + 42, + 5, + 43, + 4, + 44, + 3, + 45, + 2, + 46, + 1, + 47, + 0, + 48, +}; + +static long _vq_lengthlist__16u2_p9_2[] = { + 1, 3, 3, 4, 7, 7, 7, 8, 7, 7, 7, 7, 8, 8, 8, 8, + 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 9, 9, 8, 9, 9, + 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,12,12,10, + 11, +}; + +static float _vq_quantthresh__16u2_p9_2[] = { + -23.5, -22.5, -21.5, -20.5, -19.5, -18.5, -17.5, -16.5, + -15.5, -14.5, -13.5, -12.5, -11.5, -10.5, -9.5, -8.5, + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, + 8.5, 9.5, 10.5, 11.5, 12.5, 13.5, 14.5, 15.5, + 16.5, 17.5, 18.5, 19.5, 20.5, 21.5, 22.5, 23.5, +}; + +static long _vq_quantmap__16u2_p9_2[] = { + 47, 45, 43, 41, 39, 37, 35, 33, + 31, 29, 27, 25, 23, 21, 19, 17, + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, 18, 20, 22, 24, 26, 28, 30, + 32, 34, 36, 38, 40, 42, 44, 46, + 48, +}; + +static encode_aux_threshmatch _vq_auxt__16u2_p9_2 = { + _vq_quantthresh__16u2_p9_2, + _vq_quantmap__16u2_p9_2, + 49, + 49 +}; + +static static_codebook _16u2_p9_2 = { + 1, 49, + _vq_lengthlist__16u2_p9_2, + 1, -526909440, 1611661312, 6, 0, + _vq_quantlist__16u2_p9_2, + NULL, + &_vq_auxt__16u2_p9_2, + NULL, + 0 +}; + +static long _vq_quantlist__8u0__p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__8u0__p1_0[] = { + 1, 4, 4, 5, 7, 7, 5, 7, 7, 5, 8, 8, 8,10,10, 7, + 10,10, 5, 8, 8, 7,10,10, 8,10,10, 4, 9, 8, 8,11, + 11, 8,11,11, 7,11,11,10,11,13,10,13,13, 7,11,11, + 10,13,12,10,13,13, 5, 9, 8, 8,11,11, 8,11,11, 7, + 11,11, 9,13,13,10,12,13, 7,11,11,10,13,13,10,13, + 11, +}; + +static float _vq_quantthresh__8u0__p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__8u0__p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__8u0__p1_0 = { + _vq_quantthresh__8u0__p1_0, + _vq_quantmap__8u0__p1_0, + 3, + 3 +}; + +static static_codebook _8u0__p1_0 = { + 4, 81, + _vq_lengthlist__8u0__p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__8u0__p1_0, + NULL, + &_vq_auxt__8u0__p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__8u0__p2_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__8u0__p2_0[] = { + 2, 4, 4, 5, 6, 6, 5, 6, 6, 5, 7, 7, 6, 7, 8, 6, + 7, 8, 5, 7, 7, 6, 8, 8, 7, 9, 7, 5, 7, 7, 7, 9, + 9, 7, 8, 8, 6, 9, 8, 7, 7,10, 8,10,10, 6, 8, 8, + 8,10, 8, 8,10,10, 5, 7, 7, 7, 8, 8, 7, 8, 9, 6, + 8, 8, 8,10,10, 8, 8,10, 6, 8, 9, 8,10,10, 7,10, + 8, +}; + +static float _vq_quantthresh__8u0__p2_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__8u0__p2_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__8u0__p2_0 = { + _vq_quantthresh__8u0__p2_0, + _vq_quantmap__8u0__p2_0, + 3, + 3 +}; + +static static_codebook _8u0__p2_0 = { + 4, 81, + _vq_lengthlist__8u0__p2_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__8u0__p2_0, + NULL, + &_vq_auxt__8u0__p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__8u0__p3_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__8u0__p3_0[] = { + 1, 5, 5, 7, 7, 6, 7, 7, 9, 9, 6, 7, 7, 9, 9, 8, + 10, 9,11,11, 8, 9, 9,11,11, 6, 8, 8,10,10, 8,10, + 10,11,11, 8,10,10,11,11,10,11,11,12,12,10,11,11, + 12,13, 6, 8, 8,10,10, 8,10,10,11,11, 8,10,10,11, + 11, 9,10,11,12,12,10,11,11,12,12, 8,11,11,14,13, + 10,12,11,15,13,10,12,11,14,14,12,13,12,16,14,12, + 14,12,16,15, 8,11,11,13,14,10,11,12,13,15,10,11, + 12,13,15,11,12,13,14,15,12,12,14,14,16, 5, 8, 8, + 11,11, 9,11,11,12,12, 8,10,11,12,12,11,12,12,15, + 14,11,12,12,14,14, 7,11,10,13,12,10,11,12,13,14, + 10,12,12,14,13,12,13,13,14,15,12,13,13,15,15, 7, + 10,11,12,13,10,12,11,14,13,10,12,13,13,15,12,13, + 12,14,14,11,13,13,15,16, 9,12,12,15,14,11,13,13, + 15,16,11,13,13,16,16,13,14,15,15,15,12,14,15,17, + 16, 9,12,12,14,15,11,13,13,15,16,11,13,13,16,18, + 13,14,14,17,16,13,15,15,17,18, 5, 8, 9,11,11, 8, + 11,11,12,12, 8,10,11,12,12,11,12,12,14,14,11,12, + 12,14,15, 7,11,10,12,13,10,12,12,14,13,10,11,12, + 13,14,11,13,13,15,14,12,13,13,14,15, 7,10,11,13, + 13,10,12,12,13,14,10,12,12,13,13,11,13,13,16,16, + 12,13,13,15,14, 9,12,12,16,15,10,13,13,15,15,11, + 13,13,17,15,12,15,15,18,17,13,14,14,15,16, 9,12, + 12,15,15,11,13,13,15,16,11,13,13,15,15,12,15,15, + 16,16,13,15,14,17,15, 7,11,11,15,15,10,13,13,16, + 15,10,13,13,15,16,14,15,15,17,19,13,15,14,15,18, + 9,12,12,16,16,11,13,14,17,16,11,13,13,17,16,15, + 15,16,17,19,13,15,16, 0,18, 9,12,12,16,15,11,14, + 13,17,17,11,13,14,16,16,15,16,16,19,18,13,15,15, + 17,19,11,14,14,19,16,12,14,15, 0,18,12,16,15,18, + 17,15,15,18,16,19,14,15,17,19,19,11,14,14,18,19, + 13,15,14,19,19,12,16,15,18,17,15,17,15, 0,16,14, + 17,16,19, 0, 7,11,11,14,14,10,12,12,15,15,10,13, + 13,16,15,13,15,15,17, 0,14,15,15,16,19, 9,12,12, + 16,16,11,14,14,16,16,11,13,13,16,16,14,17,16,19, + 0,14,18,17,17,19, 9,12,12,15,16,11,13,13,15,17, + 12,14,13,19,16,13,15,15,17,19,15,17,16,17,19,11, + 14,14,19,16,12,15,15,19,17,13,14,15,17,19,14,16, + 17,19,19,16,15,16,17,19,11,15,14,16,16,12,15,15, + 19, 0,12,14,15,19,19,14,16,16, 0,18,15,19,14,18, + 16, +}; + +static float _vq_quantthresh__8u0__p3_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__8u0__p3_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__8u0__p3_0 = { + _vq_quantthresh__8u0__p3_0, + _vq_quantmap__8u0__p3_0, + 5, + 5 +}; + +static static_codebook _8u0__p3_0 = { + 4, 625, + _vq_lengthlist__8u0__p3_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__8u0__p3_0, + NULL, + &_vq_auxt__8u0__p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__8u0__p4_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__8u0__p4_0[] = { + 3, 5, 5, 8, 8, 5, 6, 7, 9, 9, 6, 7, 6, 9, 9, 9, + 9, 9,10,11, 9, 9, 9,11,10, 6, 7, 7,10,10, 7, 7, + 8,10,10, 7, 8, 8,10,10,10,10,10,10,11, 9,10,10, + 11,12, 6, 7, 7,10,10, 7, 8, 8,10,10, 7, 8, 7,10, + 10, 9,10,10,12,11,10,10,10,11,10, 9,10,10,12,11, + 10,10,10,13,11, 9,10,10,12,12,11,11,12,12,13,11, + 11,11,12,13, 9,10,10,12,12,10,10,11,12,12,10,10, + 11,12,12,11,11,11,13,13,11,12,12,13,13, 5, 7, 7, + 10,10, 7, 8, 8,10,10, 7, 8, 8,10,10,10,11,11,12, + 12,10,11,10,12,12, 7, 8, 8,11,11, 7, 8, 9,10,11, + 8, 9, 9,11,11,11,10,11,10,12,10,11,11,12,13, 7, + 8, 8,10,11, 8, 9, 8,12,10, 8, 9, 9,11,12,10,11, + 10,13,11,10,11,11,13,12, 9,11,10,13,12,10,10,11, + 12,12,10,11,11,13,13,12,10,13,11,14,11,12,12,15, + 13, 9,11,11,13,13,10,11,11,13,12,10,11,11,12,14, + 12,13,11,14,12,12,12,12,14,14, 5, 7, 7,10,10, 7, + 8, 8,10,10, 7, 8, 8,11,10,10,11,11,12,12,10,11, + 10,12,12, 7, 8, 8,10,11, 8, 9, 9,12,11, 8, 8, 9, + 10,11,10,11,11,12,13,11,10,11,11,13, 6, 8, 8,10, + 11, 8, 9, 9,11,11, 7, 9, 7,11,10,10,11,11,12,12, + 10,11,10,13,10, 9,11,10,13,12,10,12,11,13,13,10, + 10,11,12,13,11,12,13,15,14,11,11,13,12,13, 9,10, + 11,12,13,10,11,11,12,13,10,11,10,13,12,12,13,13, + 13,14,12,12,11,14,11, 8,10,10,12,13,10,11,11,13, + 13,10,11,10,13,13,12,13,14,15,14,12,12,12,14,13, + 9,10,10,13,12,10,10,12,13,13,10,11,11,15,12,12, + 12,13,15,14,12,13,13,15,13, 9,10,11,12,13,10,12, + 10,13,12,10,11,11,12,13,12,14,12,15,13,12,12,12, + 15,14,11,12,11,14,13,11,11,12,14,14,12,13,13,14, + 13,13,11,15,11,15,14,14,14,16,15,11,12,12,13,14, + 11,13,11,14,14,12,12,13,14,15,12,14,12,15,12,13, + 15,14,16,15, 8,10,10,12,12,10,10,10,12,13,10,11, + 11,13,13,12,12,12,13,14,13,13,13,15,15, 9,10,10, + 12,12,10,11,11,13,12,10,10,11,13,13,12,12,12,14, + 14,12,12,13,15,14, 9,10,10,13,12,10,10,12,12,13, + 10,11,10,13,13,12,13,13,14,14,12,13,12,14,13,11, + 12,12,14,13,12,13,12,14,14,10,12,12,14,14,14,14, + 14,16,14,13,12,14,12,15,10,12,12,14,15,12,13,13, + 14,16,11,12,11,15,14,13,14,14,14,15,13,14,11,14, + 12, +}; + +static float _vq_quantthresh__8u0__p4_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__8u0__p4_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__8u0__p4_0 = { + _vq_quantthresh__8u0__p4_0, + _vq_quantmap__8u0__p4_0, + 5, + 5 +}; + +static static_codebook _8u0__p4_0 = { + 4, 625, + _vq_lengthlist__8u0__p4_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__8u0__p4_0, + NULL, + &_vq_auxt__8u0__p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__8u0__p5_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__8u0__p5_0[] = { + 1, 4, 4, 7, 7, 7, 7, 9, 9, 4, 6, 6, 8, 7, 8, 8, + 10,10, 4, 6, 6, 8, 8, 8, 8,10,10, 6, 8, 8, 9, 9, + 9, 9,11,11, 7, 8, 8, 9, 9, 9, 9,11,11, 7, 8, 8, + 9, 9,10,10,12,11, 7, 8, 8, 9, 9,10,10,11,11, 9, + 10,10,11,11,11,12,12,12, 9,10,10,11,11,12,12,12, + 12, +}; + +static float _vq_quantthresh__8u0__p5_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__8u0__p5_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__8u0__p5_0 = { + _vq_quantthresh__8u0__p5_0, + _vq_quantmap__8u0__p5_0, + 9, + 9 +}; + +static static_codebook _8u0__p5_0 = { + 2, 81, + _vq_lengthlist__8u0__p5_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__8u0__p5_0, + NULL, + &_vq_auxt__8u0__p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__8u0__p6_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__8u0__p6_0[] = { + 1, 4, 4, 7, 7, 9, 9,11,11,12,12,16,16, 3, 6, 6, + 9, 9,11,11,12,12,13,14,18,16, 3, 6, 7, 9, 9,11, + 11,13,12,14,14,17,16, 7, 9, 9,11,11,12,12,14,14, + 14,14,17,16, 7, 9, 9,11,11,13,12,13,13,14,14,17, + 0, 9,11,11,12,13,14,14,14,13,15,14,17,17, 9,11, + 11,12,12,14,14,13,14,14,15, 0, 0,11,12,12,15,14, + 15,14,15,14,15,16,17, 0,11,12,13,13,13,14,14,15, + 14,15,15, 0, 0,12,14,14,15,15,14,16,15,15,17,16, + 0,18,13,14,14,15,14,15,14,15,16,17,16, 0, 0,17, + 17,18, 0,16,18,16, 0, 0, 0,17, 0, 0,16, 0, 0,16, + 16, 0,15, 0,17, 0, 0, 0, 0, +}; + +static float _vq_quantthresh__8u0__p6_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__8u0__p6_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__8u0__p6_0 = { + _vq_quantthresh__8u0__p6_0, + _vq_quantmap__8u0__p6_0, + 13, + 13 +}; + +static static_codebook _8u0__p6_0 = { + 2, 169, + _vq_lengthlist__8u0__p6_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__8u0__p6_0, + NULL, + &_vq_auxt__8u0__p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__8u0__p6_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__8u0__p6_1[] = { + 1, 4, 4, 6, 6, 4, 6, 5, 7, 7, 4, 5, 6, 7, 7, 6, + 7, 7, 7, 7, 6, 7, 7, 7, 7, +}; + +static float _vq_quantthresh__8u0__p6_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__8u0__p6_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__8u0__p6_1 = { + _vq_quantthresh__8u0__p6_1, + _vq_quantmap__8u0__p6_1, + 5, + 5 +}; + +static static_codebook _8u0__p6_1 = { + 2, 25, + _vq_lengthlist__8u0__p6_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__8u0__p6_1, + NULL, + &_vq_auxt__8u0__p6_1, + NULL, + 0 +}; + +static long _vq_quantlist__8u0__p7_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__8u0__p7_0[] = { + 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, +}; + +static float _vq_quantthresh__8u0__p7_0[] = { + -157.5, 157.5, +}; + +static long _vq_quantmap__8u0__p7_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__8u0__p7_0 = { + _vq_quantthresh__8u0__p7_0, + _vq_quantmap__8u0__p7_0, + 3, + 3 +}; + +static static_codebook _8u0__p7_0 = { + 4, 81, + _vq_lengthlist__8u0__p7_0, + 1, -518803456, 1628680192, 2, 0, + _vq_quantlist__8u0__p7_0, + NULL, + &_vq_auxt__8u0__p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__8u0__p7_1[] = { + 7, + 6, + 8, + 5, + 9, + 4, + 10, + 3, + 11, + 2, + 12, + 1, + 13, + 0, + 14, +}; + +static long _vq_lengthlist__8u0__p7_1[] = { + 1, 5, 5, 5, 5,10,10,11,11,11,11,11,11,11,11, 5, + 7, 6, 8, 8, 9,10,11,11,11,11,11,11,11,11, 6, 6, + 7, 9, 7,11,10,11,11,11,11,11,11,11,11, 5, 6, 6, + 11, 8,11,11,11,11,11,11,11,11,11,11, 5, 6, 6, 9, + 10,11,10,11,11,11,11,11,11,11,11, 7,10,10,11,11, + 11,11,11,11,11,11,11,11,11,11, 7,11, 8,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10, +}; + +static float _vq_quantthresh__8u0__p7_1[] = { + -136.5, -115.5, -94.5, -73.5, -52.5, -31.5, -10.5, 10.5, + 31.5, 52.5, 73.5, 94.5, 115.5, 136.5, +}; + +static long _vq_quantmap__8u0__p7_1[] = { + 13, 11, 9, 7, 5, 3, 1, 0, + 2, 4, 6, 8, 10, 12, 14, +}; + +static encode_aux_threshmatch _vq_auxt__8u0__p7_1 = { + _vq_quantthresh__8u0__p7_1, + _vq_quantmap__8u0__p7_1, + 15, + 15 +}; + +static static_codebook _8u0__p7_1 = { + 2, 225, + _vq_lengthlist__8u0__p7_1, + 1, -520986624, 1620377600, 4, 0, + _vq_quantlist__8u0__p7_1, + NULL, + &_vq_auxt__8u0__p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__8u0__p7_2[] = { + 10, + 9, + 11, + 8, + 12, + 7, + 13, + 6, + 14, + 5, + 15, + 4, + 16, + 3, + 17, + 2, + 18, + 1, + 19, + 0, + 20, +}; + +static long _vq_lengthlist__8u0__p7_2[] = { + 1, 6, 5, 7, 7, 9, 9, 9, 9,10,12,12,10,11,11,10, + 11,11,11,10,11, 6, 8, 8, 9, 9,10,10, 9,10,11,11, + 10,11,11,11,11,10,11,11,11,11, 6, 7, 8, 9, 9, 9, + 10,11,10,11,12,11,10,11,11,11,11,11,11,12,10, 8, + 9, 9,10, 9,10,10, 9,10,10,10,10,10, 9,10,10,10, + 10, 9,10,10, 9, 9, 9, 9,10,10, 9, 9,10,10,11,10, + 9,12,10,11,10, 9,10,10,10, 8, 9, 9,10, 9,10, 9, + 9,10,10, 9,10, 9,11,10,10,10,10,10, 9,10, 8, 8, + 9, 9,10, 9,11, 9, 8, 9, 9,10,11,10,10,10,11,12, + 9, 9,11, 8, 9, 8,11,10,11,10,10, 9,11,10,10,10, + 10,10,10,10,11,11,11,11, 8, 9, 9, 9,10,10,10,11, + 11,12,11,12,11,10,10,10,12,11,11,11,10, 8,10, 9, + 11,10,10,11,12,10,11,12,11,11,12,11,12,12,10,11, + 11,10, 9, 9,10,11,12,10,10,10,11,10,11,11,10,12, + 12,10,11,10,11,12,10, 9,10,10,11,10,11,11,11,11, + 11,12,11,11,11, 9,11,10,11,10,11,10, 9, 9,10,11, + 11,11,10,10,11,12,12,11,12,11,11,11,12,12,12,12, + 11, 9,11,11,12,10,11,11,11,11,11,11,12,11,11,12, + 11,11,11,10,11,11, 9,11,10,11,11,11,10,10,10,11, + 11,11,12,10,11,10,11,11,11,11,12, 9,11,10,11,11, + 10,10,11,11, 9,11,11,12,10,10,10,10,10,11,11,10, + 9,10,11,11,12,11,10,10,12,11,11,12,11,12,11,11, + 10,10,11,11,10,12,11,10,11,10,11,10,10,10,11,11, + 10,10,11,11,11,11,10,10,10,12,11,11,11,11,10, 9, + 10,11,11,11,12,11,11,11,12,10,11,11,11, 9,10,11, + 11,11,11,11,11,10,10,11,11,12,11,10,11,12,11,10, + 10,11, 9,10,11,11,11,11,11,10,11,11,10,12,11,11, + 11,12,11,11,11,10,10,11,11, +}; + +static float _vq_quantthresh__8u0__p7_2[] = { + -9.5, -8.5, -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, + -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, + 6.5, 7.5, 8.5, 9.5, +}; + +static long _vq_quantmap__8u0__p7_2[] = { + 19, 17, 15, 13, 11, 9, 7, 5, + 3, 1, 0, 2, 4, 6, 8, 10, + 12, 14, 16, 18, 20, +}; + +static encode_aux_threshmatch _vq_auxt__8u0__p7_2 = { + _vq_quantthresh__8u0__p7_2, + _vq_quantmap__8u0__p7_2, + 21, + 21 +}; + +static static_codebook _8u0__p7_2 = { + 2, 441, + _vq_lengthlist__8u0__p7_2, + 1, -529268736, 1611661312, 5, 0, + _vq_quantlist__8u0__p7_2, + NULL, + &_vq_auxt__8u0__p7_2, + NULL, + 0 +}; + +static long _huff_lengthlist__8u0__single[] = { + 4, 7,11, 9,12, 8, 7,10, 6, 4, 5, 5, 7, 5, 6,16, + 9, 5, 5, 6, 7, 7, 9,16, 7, 4, 6, 5, 7, 5, 7,17, + 10, 7, 7, 8, 7, 7, 8,18, 7, 5, 6, 4, 5, 4, 5,15, + 7, 6, 7, 5, 6, 4, 5,15,12,13,18,12,17,11, 9,17, +}; + +static static_codebook _huff_book__8u0__single = { + 2, 64, + _huff_lengthlist__8u0__single, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__8u1__p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__8u1__p1_0[] = { + 1, 4, 4, 5, 7, 7, 5, 7, 7, 5, 8, 8, 7, 9,10, 7, + 9, 9, 5, 8, 8, 7,10, 9, 7, 9, 9, 5, 8, 8, 8,10, + 10, 8,10,10, 7,10,10, 9,10,12,10,12,12, 7,10,10, + 9,12,11,10,12,12, 5, 8, 8, 8,10,10, 8,10,10, 7, + 10,10,10,12,12, 9,11,12, 7,10,10,10,12,12, 9,12, + 10, +}; + +static float _vq_quantthresh__8u1__p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__8u1__p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__8u1__p1_0 = { + _vq_quantthresh__8u1__p1_0, + _vq_quantmap__8u1__p1_0, + 3, + 3 +}; + +static static_codebook _8u1__p1_0 = { + 4, 81, + _vq_lengthlist__8u1__p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__8u1__p1_0, + NULL, + &_vq_auxt__8u1__p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__8u1__p2_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__8u1__p2_0[] = { + 3, 4, 5, 5, 6, 6, 5, 6, 6, 5, 7, 6, 6, 7, 8, 6, + 7, 8, 5, 6, 6, 6, 8, 7, 6, 8, 7, 5, 6, 6, 7, 8, + 8, 6, 7, 7, 6, 8, 7, 7, 7, 9, 8, 9, 9, 6, 7, 8, + 7, 9, 7, 8, 9, 9, 5, 6, 6, 6, 7, 7, 7, 8, 8, 6, + 8, 7, 8, 9, 9, 7, 7, 9, 6, 7, 8, 8, 9, 9, 7, 9, + 7, +}; + +static float _vq_quantthresh__8u1__p2_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__8u1__p2_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__8u1__p2_0 = { + _vq_quantthresh__8u1__p2_0, + _vq_quantmap__8u1__p2_0, + 3, + 3 +}; + +static static_codebook _8u1__p2_0 = { + 4, 81, + _vq_lengthlist__8u1__p2_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__8u1__p2_0, + NULL, + &_vq_auxt__8u1__p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__8u1__p3_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__8u1__p3_0[] = { + 1, 5, 5, 7, 7, 6, 7, 7, 9, 9, 6, 7, 7, 9, 9, 8, + 10, 9,11,11, 9, 9, 9,11,11, 6, 8, 8,10,10, 8,10, + 10,11,11, 8, 9,10,11,11,10,11,11,12,12,10,11,11, + 12,13, 6, 8, 8,10,10, 8,10, 9,11,11, 8,10, 9,11, + 11,10,11,11,12,12,10,11,11,12,12, 9,11,11,14,13, + 10,12,11,14,14,10,12,11,14,13,12,13,13,15,14,12, + 13,13,15,14, 8,11,11,13,14,10,11,12,13,15,10,11, + 12,14,14,12,13,13,14,15,12,13,13,14,15, 5, 8, 8, + 11,11, 8,10,10,12,12, 8,10,10,12,12,11,12,12,14, + 13,11,12,12,13,14, 8,10,10,12,12, 9,11,12,13,14, + 10,12,12,13,13,12,12,13,14,14,11,13,13,15,15, 7, + 10,10,12,12, 9,12,11,14,12,10,11,12,13,14,12,13, + 12,14,14,12,13,13,15,16,10,12,12,15,14,11,12,13, + 15,15,11,13,13,15,16,14,14,15,15,16,13,14,15,17, + 15, 9,12,12,14,15,11,13,12,15,15,11,13,13,15,15, + 13,14,13,15,14,13,14,14,17, 0, 5, 8, 8,11,11, 8, + 10,10,12,12, 8,10,10,12,12,11,12,12,14,14,11,12, + 12,14,14, 7,10,10,12,12,10,12,12,13,13, 9,11,12, + 12,13,11,12,13,15,15,11,12,13,14,15, 8,10,10,12, + 12,10,12,11,13,13,10,12,11,13,13,11,13,13,15,14, + 12,13,12,15,13, 9,12,12,14,14,11,13,13,16,15,11, + 12,13,16,15,13,14,15,16,16,13,13,15,15,16,10,12, + 12,15,14,11,13,13,14,16,11,13,13,15,16,13,15,15, + 16,17,13,15,14,16,15, 8,11,11,14,15,10,12,12,15, + 15,10,12,12,15,16,14,15,15,16,17,13,14,14,16,16, + 9,12,12,15,15,11,13,14,15,17,11,13,13,15,16,14, + 15,16,19,17,13,15,15, 0,17, 9,12,12,15,15,11,14, + 13,16,15,11,13,13,15,16,15,15,15,18,17,13,15,15, + 17,17,11,15,14,18,16,12,14,15,17,17,12,15,15,18, + 18,15,15,16,15,19,14,16,16, 0, 0,11,14,14,16,17, + 12,15,14,18,17,12,15,15,18,18,15,17,15,18,16,14, + 16,16,18,18, 7,11,11,14,14,10,12,12,15,15,10,12, + 13,15,15,13,14,15,16,16,14,15,15,18,18, 9,12,12, + 15,15,11,13,13,16,15,11,12,13,16,16,14,15,15,17, + 16,15,16,16,17,17, 9,12,12,15,15,11,13,13,15,17, + 11,14,13,16,15,13,15,15,17,17,15,15,15,18,17,11, + 14,14,17,15,12,14,15,17,18,13,13,15,17,17,14,16, + 16,19,18,16,15,17,17, 0,11,14,14,17,17,12,15,15, + 18, 0,12,15,14,18,16,14,17,17,19, 0,16,18,15, 0, + 16, +}; + +static float _vq_quantthresh__8u1__p3_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__8u1__p3_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__8u1__p3_0 = { + _vq_quantthresh__8u1__p3_0, + _vq_quantmap__8u1__p3_0, + 5, + 5 +}; + +static static_codebook _8u1__p3_0 = { + 4, 625, + _vq_lengthlist__8u1__p3_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__8u1__p3_0, + NULL, + &_vq_auxt__8u1__p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__8u1__p4_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__8u1__p4_0[] = { + 4, 5, 5, 9, 9, 6, 7, 7, 9, 9, 6, 7, 7, 9, 9, 9, + 9, 9,11,11, 9, 9, 9,11,11, 6, 7, 7, 9, 9, 7, 7, + 8, 9,10, 7, 7, 8, 9,10, 9, 9,10,10,11, 9, 9,10, + 10,12, 6, 7, 7, 9, 9, 7, 8, 7,10, 9, 7, 8, 7,10, + 9, 9,10, 9,12,11,10,10, 9,12,10, 9,10,10,12,11, + 9,10,10,12,11, 9,10,10,12,12,11,11,12,12,13,11, + 11,12,12,13, 9, 9,10,12,11, 9,10,10,12,12,10,10, + 10,12,12,11,12,11,13,12,11,12,11,13,12, 6, 7, 7, + 9, 9, 7, 8, 8,10,10, 7, 8, 7,10, 9,10,10,10,12, + 12,10,10,10,12,11, 7, 8, 7,10,10, 7, 7, 9,10,11, + 8, 9, 9,11,10,10,10,11,10,12,10,10,11,12,12, 7, + 8, 8,10,10, 7, 9, 8,11,10, 8, 8, 9,11,11,10,11, + 10,12,11,10,11,11,12,12, 9,10,10,12,12, 9,10,10, + 12,12,10,11,11,13,12,11,10,12,10,14,12,12,12,13, + 14, 9,10,10,12,12, 9,11,10,12,12,10,11,11,12,12, + 11,12,11,14,12,12,12,12,14,14, 5, 7, 7, 9, 9, 7, + 7, 7, 9,10, 7, 8, 8,10,10,10,10,10,11,11,10,10, + 10,12,12, 7, 8, 8,10,10, 8, 9, 8,11,10, 7, 8, 9, + 10,11,10,10,10,11,12,10,10,11,11,13, 6, 7, 8,10, + 10, 8, 9, 9,10,10, 7, 9, 7,11,10,10,11,10,12,12, + 10,11,10,12,10, 9,10,10,12,12,10,11,11,13,12, 9, + 10,10,12,12,12,12,12,14,13,11,11,12,11,14, 9,10, + 10,11,12,10,11,11,12,13, 9,10,10,12,12,12,12,12, + 14,13,11,12,10,14,11, 9, 9,10,11,12, 9,10,10,12, + 12, 9,10,10,12,12,12,12,12,14,14,11,12,12,13,12, + 9,10, 9,12,12, 9,10,11,12,13,10,11,10,13,11,12, + 12,13,13,14,12,12,12,13,13, 9,10,10,12,12,10,11, + 10,13,12,10,10,11,12,13,12,13,12,14,13,12,12,12, + 13,14,11,12,11,14,13,10,10,11,13,13,12,12,12,14, + 13,12,10,14,10,15,13,14,14,14,14,11,11,12,13,14, + 10,12,11,13,13,12,12,12,13,15,12,13,11,15,12,13, + 13,14,14,14, 9,10, 9,12,12, 9,10,10,12,12,10,10, + 10,12,12,11,11,12,12,13,12,12,12,14,14, 9,10,10, + 12,12,10,11,10,13,12,10,10,11,12,13,12,12,12,14, + 13,12,12,13,13,14, 9,10,10,12,13,10,10,11,11,12, + 9,11,10,13,12,12,12,12,13,14,12,13,12,14,13,11, + 12,11,13,13,12,13,12,14,13,10,11,12,13,13,13,13, + 13,14,15,12,11,14,12,14,11,11,12,12,13,12,12,12, + 13,14,10,12,10,14,13,13,13,13,14,15,12,14,11,15, + 10, +}; + +static float _vq_quantthresh__8u1__p4_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__8u1__p4_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__8u1__p4_0 = { + _vq_quantthresh__8u1__p4_0, + _vq_quantmap__8u1__p4_0, + 5, + 5 +}; + +static static_codebook _8u1__p4_0 = { + 4, 625, + _vq_lengthlist__8u1__p4_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__8u1__p4_0, + NULL, + &_vq_auxt__8u1__p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__8u1__p5_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__8u1__p5_0[] = { + 1, 4, 4, 7, 7, 7, 7, 9, 9, 4, 6, 5, 8, 7, 8, 8, + 10,10, 4, 6, 6, 8, 8, 8, 8,10,10, 7, 8, 8, 9, 9, + 9, 9,11,11, 7, 8, 8, 9, 9, 9, 9,11,11, 8, 8, 8, + 9, 9,10,10,12,11, 8, 8, 8, 9, 9,10,10,11,11, 9, + 10,10,11,11,11,11,13,12, 9,10,10,11,11,12,12,12, + 13, +}; + +static float _vq_quantthresh__8u1__p5_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__8u1__p5_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__8u1__p5_0 = { + _vq_quantthresh__8u1__p5_0, + _vq_quantmap__8u1__p5_0, + 9, + 9 +}; + +static static_codebook _8u1__p5_0 = { + 2, 81, + _vq_lengthlist__8u1__p5_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__8u1__p5_0, + NULL, + &_vq_auxt__8u1__p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__8u1__p6_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__8u1__p6_0[] = { + 3, 4, 4, 6, 6, 7, 7, 9, 9, 4, 4, 5, 6, 6, 7, 7, + 9, 9, 4, 4, 4, 6, 6, 7, 7, 9, 9, 6, 6, 6, 7, 7, + 8, 8, 9, 9, 6, 6, 6, 7, 7, 8, 8, 9, 9, 7, 7, 7, + 8, 8, 8, 9,10,10, 7, 7, 7, 8, 8, 9, 8,10,10, 9, + 9, 9, 9, 9,10,10,10,10, 9, 9, 9, 9, 9,10,10,10, + 10, +}; + +static float _vq_quantthresh__8u1__p6_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__8u1__p6_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__8u1__p6_0 = { + _vq_quantthresh__8u1__p6_0, + _vq_quantmap__8u1__p6_0, + 9, + 9 +}; + +static static_codebook _8u1__p6_0 = { + 2, 81, + _vq_lengthlist__8u1__p6_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__8u1__p6_0, + NULL, + &_vq_auxt__8u1__p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__8u1__p7_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__8u1__p7_0[] = { + 1, 4, 4, 5, 7, 7, 5, 7, 7, 5, 9, 9, 8,10,10, 8, + 10,10, 5, 9, 9, 7,10,10, 8,10,10, 4,10,10, 9,12, + 12, 9,11,11, 7,12,11,10,11,13,10,13,13, 7,12,12, + 10,13,12,10,13,13, 4,10,10, 9,12,12, 9,12,12, 7, + 12,12,10,13,13,10,12,13, 7,11,12,10,13,13,10,13, + 11, +}; + +static float _vq_quantthresh__8u1__p7_0[] = { + -5.5, 5.5, +}; + +static long _vq_quantmap__8u1__p7_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__8u1__p7_0 = { + _vq_quantthresh__8u1__p7_0, + _vq_quantmap__8u1__p7_0, + 3, + 3 +}; + +static static_codebook _8u1__p7_0 = { + 4, 81, + _vq_lengthlist__8u1__p7_0, + 1, -529137664, 1618345984, 2, 0, + _vq_quantlist__8u1__p7_0, + NULL, + &_vq_auxt__8u1__p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__8u1__p7_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__8u1__p7_1[] = { + 2, 4, 4, 6, 6, 7, 7, 8, 8, 8, 8, 4, 5, 5, 7, 7, + 8, 8, 9, 9, 9, 9, 4, 5, 5, 7, 7, 8, 8, 9, 9, 9, + 9, 6, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 6, 7, 7, 8, + 8, 8, 8, 9, 9, 9, 9, 8, 8, 8, 8, 8, 9, 9, 9, 9, + 9, 9, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 8, 9, 9, + 9, 9, 9, 9,10,10,10,10, 8, 9, 9, 9, 9, 9, 9,10, + 10,10,10, 8, 9, 9, 9, 9, 9, 9,10,10,10,10, 8, 9, + 9, 9, 9, 9, 9,10,10,10,10, +}; + +static float _vq_quantthresh__8u1__p7_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__8u1__p7_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__8u1__p7_1 = { + _vq_quantthresh__8u1__p7_1, + _vq_quantmap__8u1__p7_1, + 11, + 11 +}; + +static static_codebook _8u1__p7_1 = { + 2, 121, + _vq_lengthlist__8u1__p7_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__8u1__p7_1, + NULL, + &_vq_auxt__8u1__p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__8u1__p8_0[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__8u1__p8_0[] = { + 1, 4, 4, 6, 6, 8, 8,10,10,11,11, 4, 6, 6, 7, 7, + 9, 9,11,11,13,12, 4, 6, 6, 7, 7, 9, 9,11,11,12, + 12, 6, 7, 7, 9, 9,11,11,12,12,13,13, 6, 7, 7, 9, + 9,11,11,12,12,13,13, 8, 9, 9,11,11,12,12,13,13, + 14,14, 8, 9, 9,11,11,12,12,13,13,14,14, 9,11,11, + 12,12,13,13,14,14,15,15, 9,11,11,12,12,13,13,14, + 14,15,14,11,12,12,13,13,14,14,15,15,16,16,11,12, + 12,13,13,14,14,15,15,15,15, +}; + +static float _vq_quantthresh__8u1__p8_0[] = { + -49.5, -38.5, -27.5, -16.5, -5.5, 5.5, 16.5, 27.5, + 38.5, 49.5, +}; + +static long _vq_quantmap__8u1__p8_0[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__8u1__p8_0 = { + _vq_quantthresh__8u1__p8_0, + _vq_quantmap__8u1__p8_0, + 11, + 11 +}; + +static static_codebook _8u1__p8_0 = { + 2, 121, + _vq_lengthlist__8u1__p8_0, + 1, -524582912, 1618345984, 4, 0, + _vq_quantlist__8u1__p8_0, + NULL, + &_vq_auxt__8u1__p8_0, + NULL, + 0 +}; + +static long _vq_quantlist__8u1__p8_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__8u1__p8_1[] = { + 2, 5, 5, 6, 6, 7, 7, 7, 7, 8, 8, 5, 6, 6, 7, 7, + 7, 7, 8, 8, 8, 8, 5, 6, 6, 7, 7, 7, 7, 8, 8, 8, + 8, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 6, 7, 7, 7, + 7, 8, 8, 8, 8, 8, 8, 7, 7, 7, 8, 8, 8, 8, 8, 8, + 8, 8, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 9, 8, 9, 9, 7, 8, 8, 8, 8, 8, 8, 9, + 8, 9, 9, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 8, 8, + 8, 8, 8, 8, 8, 9, 9, 9, 9, +}; + +static float _vq_quantthresh__8u1__p8_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__8u1__p8_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__8u1__p8_1 = { + _vq_quantthresh__8u1__p8_1, + _vq_quantmap__8u1__p8_1, + 11, + 11 +}; + +static static_codebook _8u1__p8_1 = { + 2, 121, + _vq_lengthlist__8u1__p8_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__8u1__p8_1, + NULL, + &_vq_auxt__8u1__p8_1, + NULL, + 0 +}; + +static long _vq_quantlist__8u1__p9_0[] = { + 7, + 6, + 8, + 5, + 9, + 4, + 10, + 3, + 11, + 2, + 12, + 1, + 13, + 0, + 14, +}; + +static long _vq_lengthlist__8u1__p9_0[] = { + 1, 4, 4,11,11,11,11,11,11,11,11,11,11,11,11, 3, + 11, 8,11,11,11,11,11,11,11,11,11,11,11,11, 3, 9, + 9,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10, +}; + +static float _vq_quantthresh__8u1__p9_0[] = { + -1657.5, -1402.5, -1147.5, -892.5, -637.5, -382.5, -127.5, 127.5, + 382.5, 637.5, 892.5, 1147.5, 1402.5, 1657.5, +}; + +static long _vq_quantmap__8u1__p9_0[] = { + 13, 11, 9, 7, 5, 3, 1, 0, + 2, 4, 6, 8, 10, 12, 14, +}; + +static encode_aux_threshmatch _vq_auxt__8u1__p9_0 = { + _vq_quantthresh__8u1__p9_0, + _vq_quantmap__8u1__p9_0, + 15, + 15 +}; + +static static_codebook _8u1__p9_0 = { + 2, 225, + _vq_lengthlist__8u1__p9_0, + 1, -514071552, 1627381760, 4, 0, + _vq_quantlist__8u1__p9_0, + NULL, + &_vq_auxt__8u1__p9_0, + NULL, + 0 +}; + +static long _vq_quantlist__8u1__p9_1[] = { + 7, + 6, + 8, + 5, + 9, + 4, + 10, + 3, + 11, + 2, + 12, + 1, + 13, + 0, + 14, +}; + +static long _vq_lengthlist__8u1__p9_1[] = { + 1, 4, 4, 7, 7, 9, 9, 7, 7, 8, 8,10,10,11,11, 4, + 7, 7, 9, 9,10,10, 8, 8,10,10,10,11,10,11, 4, 7, + 7, 9, 9,10,10, 8, 8,10, 9,11,11,11,11, 7, 9, 9, + 12,12,11,12,10,10,11,10,12,11,11,11, 7, 9, 9,11, + 11,13,12, 9, 9,11,10,11,11,12,11, 9,10,10,12,12, + 14,14,10,10,11,12,12,11,11,11, 9,10,11,11,13,14, + 13,10,11,11,11,12,11,12,12, 7, 8, 8,10, 9,11,10, + 11,12,12,11,12,14,12,13, 7, 8, 8, 9,10,10,11,12, + 12,12,11,12,12,12,13, 9, 9, 9,11,11,13,12,12,12, + 12,11,12,12,13,12, 8,10,10,11,10,11,12,12,12,12, + 12,12,14,12,12, 9,11,11,11,12,12,12,12,13,13,12, + 12,13,13,12,10,11,11,12,11,12,12,12,11,12,13,12, + 12,12,13,11,11,12,12,12,13,12,12,11,12,13,13,12, + 12,13,12,11,12,12,13,13,12,13,12,13,13,13,13,14, + 13, +}; + +static float _vq_quantthresh__8u1__p9_1[] = { + -110.5, -93.5, -76.5, -59.5, -42.5, -25.5, -8.5, 8.5, + 25.5, 42.5, 59.5, 76.5, 93.5, 110.5, +}; + +static long _vq_quantmap__8u1__p9_1[] = { + 13, 11, 9, 7, 5, 3, 1, 0, + 2, 4, 6, 8, 10, 12, 14, +}; + +static encode_aux_threshmatch _vq_auxt__8u1__p9_1 = { + _vq_quantthresh__8u1__p9_1, + _vq_quantmap__8u1__p9_1, + 15, + 15 +}; + +static static_codebook _8u1__p9_1 = { + 2, 225, + _vq_lengthlist__8u1__p9_1, + 1, -522338304, 1620115456, 4, 0, + _vq_quantlist__8u1__p9_1, + NULL, + &_vq_auxt__8u1__p9_1, + NULL, + 0 +}; + +static long _vq_quantlist__8u1__p9_2[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__8u1__p9_2[] = { + 2, 5, 4, 6, 6, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, + 9, 5, 6, 6, 7, 7, 8, 8, 9, 8, 9, 9, 9, 9, 9, 9, + 9, 9, 5, 6, 6, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 7, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, + 9,10,10, 9, 7, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9,10,10, 8, 8, 8, 9, 9, 9, 9,10,10,10, 9, + 10,10,10,10,10,10, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, + 10,10,10,10,10,10,10, 9, 9, 9, 9, 9, 9, 9, 9,10, + 10,10,10,10,10,10,10,10, 9, 9, 9, 9, 9,10,10,10, + 10,10,10,10,10,10,10,10,10, 9, 9, 9, 9, 9, 9,10, + 10,10,10,10,10,10,10,10,10,10, 9, 9, 9, 9, 9,10, + 10,10,10,10,10,10,10,10,10,10,10, 9, 9, 9, 9,10, + 10,10,10,10,10,10,10,10,10,10,10,10, 9, 9, 9, 9, + 9,10,10,10,10,10,10,10,10,10,10,10,10, 9, 9, 9, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10, 9,10, + 9, 9, 9,10,10,10,10,10,10,10,10,10,10,10,10, 9, + 10, 9,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 9, 9,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10, +}; + +static float _vq_quantthresh__8u1__p9_2[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__8u1__p9_2[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__8u1__p9_2 = { + _vq_quantthresh__8u1__p9_2, + _vq_quantmap__8u1__p9_2, + 17, + 17 +}; + +static static_codebook _8u1__p9_2 = { + 2, 289, + _vq_lengthlist__8u1__p9_2, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__8u1__p9_2, + NULL, + &_vq_auxt__8u1__p9_2, + NULL, + 0 +}; + +static long _huff_lengthlist__8u1__single[] = { + 4, 7,13, 9,15, 9,16, 8,10,13, 7, 5, 8, 6, 9, 7, + 10, 7,10,11,11, 6, 7, 8, 8, 9, 9, 9,12,16, 8, 5, + 8, 6, 8, 6, 9, 7,10,12,11, 7, 7, 7, 6, 7, 7, 7, + 11,15, 7, 5, 8, 6, 7, 5, 7, 6, 9,13,13, 9, 9, 8, + 6, 6, 5, 5, 9,14, 8, 6, 8, 6, 6, 4, 5, 3, 5,13, + 9, 9,11, 8,10, 7, 8, 4, 5,12,11,16,17,15,17,12, + 13, 8, 8,15, +}; + +static static_codebook _huff_book__8u1__single = { + 2, 100, + _huff_lengthlist__8u1__single, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__44u0__long[] = { + 5, 8,13,10,17,11,11,15, 7, 2, 4, 5, 8, 7, 9,16, + 13, 4, 3, 5, 6, 8,11,20,10, 4, 5, 5, 7, 6, 8,18, + 15, 7, 6, 7, 8,10,14,20,10, 6, 7, 6, 9, 7, 8,17, + 9, 8,10, 8,10, 5, 4,11,12,17,19,14,16,10, 7,12, +}; + +static static_codebook _huff_book__44u0__long = { + 2, 64, + _huff_lengthlist__44u0__long, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__44u0__p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44u0__p1_0[] = { + 1, 4, 4, 5, 8, 7, 5, 7, 8, 5, 8, 8, 8,11,11, 8, + 10,10, 5, 8, 8, 8,11,10, 8,11,11, 4, 8, 8, 8,11, + 11, 8,11,11, 8,12,11,11,13,13,11,13,14, 7,11,11, + 10,13,12,11,13,14, 4, 8, 8, 8,11,11, 8,11,12, 8, + 11,11,11,13,13,10,12,13, 8,11,11,11,14,13,11,14, + 13, +}; + +static float _vq_quantthresh__44u0__p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44u0__p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44u0__p1_0 = { + _vq_quantthresh__44u0__p1_0, + _vq_quantmap__44u0__p1_0, + 3, + 3 +}; + +static static_codebook _44u0__p1_0 = { + 4, 81, + _vq_lengthlist__44u0__p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44u0__p1_0, + NULL, + &_vq_auxt__44u0__p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u0__p2_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44u0__p2_0[] = { + 2, 4, 4, 5, 6, 6, 5, 6, 6, 5, 7, 7, 7, 8, 8, 6, + 8, 8, 5, 7, 7, 6, 8, 8, 7, 8, 8, 4, 7, 7, 7, 8, + 8, 7, 8, 8, 7, 8, 8, 8, 9,10, 8,10,10, 6, 8, 8, + 8,10, 8, 8,10,10, 5, 7, 7, 7, 8, 8, 7, 8, 8, 6, + 8, 8, 8,10,10, 8, 8,10, 6, 8, 8, 8,10,10, 8,10, + 9, +}; + +static float _vq_quantthresh__44u0__p2_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44u0__p2_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44u0__p2_0 = { + _vq_quantthresh__44u0__p2_0, + _vq_quantmap__44u0__p2_0, + 3, + 3 +}; + +static static_codebook _44u0__p2_0 = { + 4, 81, + _vq_lengthlist__44u0__p2_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44u0__p2_0, + NULL, + &_vq_auxt__44u0__p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u0__p3_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44u0__p3_0[] = { + 1, 5, 5, 8, 8, 5, 8, 7, 9, 9, 5, 7, 8, 9, 9, 9, + 10, 9,12,12, 9, 9,10,12,12, 6, 8, 8,11,10, 8,10, + 10,11,11, 8, 9,10,11,11,10,11,11,14,13,10,11,11, + 13,13, 5, 8, 8,10,10, 8,10,10,11,11, 8,10,10,11, + 11,10,11,11,13,13,10,11,11,13,13, 9,11,11,15,14, + 10,12,12,15,14,10,12,11,15,14,13,14,14,16,16,12, + 14,13,17,15, 9,11,11,14,15,10,11,12,14,16,10,11, + 12,14,16,12,13,14,16,16,13,13,15,15,18, 5, 8, 8, + 11,11, 8,10,10,12,12, 8,10,10,12,13,11,12,12,14, + 14,11,12,12,15,15, 8,10,10,13,13,10,12,12,13,13, + 10,12,12,14,14,12,13,13,15,15,12,13,13,16,16, 7, + 10,10,12,12,10,12,11,13,13,10,12,12,13,14,12,13, + 12,15,14,12,13,13,16,16,10,12,12,17,16,12,13,13, + 16,15,11,13,13,17,17,15,15,15,16,17,14,15,15,19, + 19,10,12,12,15,16,11,13,12,15,18,11,13,13,16,16, + 14,15,15,17,17,14,15,15,17,19, 5, 8, 8,11,11, 8, + 10,10,12,12, 8,10,10,12,12,11,12,12,16,15,11,12, + 12,14,15, 7,10,10,13,13,10,12,12,14,13,10,11,12, + 13,13,12,13,13,16,16,12,12,13,15,15, 8,10,10,13, + 13,10,12,12,14,14,10,12,12,13,13,12,13,13,16,16, + 12,13,13,15,15,10,12,12,16,15,11,13,13,17,16,11, + 12,13,16,15,13,15,15,19,17,14,15,14,17,16,10,12, + 12,16,16,11,13,13,16,17,12,13,13,15,17,14,15,15, + 17,19,14,15,15,17,17, 8,11,11,16,16,10,13,12,17, + 17,10,12,13,16,16,15,17,16,20,19,14,15,17,18,19, + 9,12,12,16,17,11,13,14,17,18,11,13,13,19,18,16, + 17,18,19,19,15,16,16,19,19, 9,12,12,16,17,11,14, + 13,18,17,11,13,13,17,17,16,17,16,20,19,14,16,16, + 18,18,12,15,15,19,17,14,15,16, 0,20,13,15,16,20, + 17,18,16,20, 0, 0,15,16,19,20, 0,12,15,14,18,19, + 13,16,15,20,19,13,16,15,20,18,17,18,17, 0,20,16, + 17,16, 0, 0, 8,11,11,16,15,10,12,12,17,17,10,13, + 13,17,16,14,16,15,18,20,15,16,16,19,19, 9,12,12, + 16,16,11,13,13,17,16,11,13,14,17,18,15,15,16,20, + 20,16,16,17,19,19, 9,13,12,16,17,11,14,13,17,17, + 11,14,14,18,17,14,16,15,18,19,16,17,18,18,19,12, + 14,15,19,18,13,15,16,18, 0,13,14,15, 0, 0,16,16, + 17,20, 0,17,17,20,20, 0,12,15,15,19,20,13,15,15, + 0, 0,14,16,15, 0, 0,15,18,16, 0, 0,17,18,16, 0, + 19, +}; + +static float _vq_quantthresh__44u0__p3_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44u0__p3_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44u0__p3_0 = { + _vq_quantthresh__44u0__p3_0, + _vq_quantmap__44u0__p3_0, + 5, + 5 +}; + +static static_codebook _44u0__p3_0 = { + 4, 625, + _vq_lengthlist__44u0__p3_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44u0__p3_0, + NULL, + &_vq_auxt__44u0__p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u0__p4_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44u0__p4_0[] = { + 4, 5, 5, 9, 9, 5, 6, 6, 9, 9, 5, 6, 6, 9, 9, 9, + 10, 9,12,12, 9, 9,10,12,12, 5, 7, 7,10,10, 7, 7, + 8,10,10, 6, 7, 8,10,10,10,10,10,11,13,10, 9,10, + 12,13, 5, 7, 7,10,10, 6, 8, 7,10,10, 7, 8, 7,10, + 10, 9,10,10,12,12,10,10,10,13,11, 9,10,10,13,13, + 10,11,10,13,13,10,10,10,13,13,12,12,13,14,14,12, + 12,13,14,14, 9,10,10,13,13,10,10,10,13,13,10,10, + 10,13,13,12,13,12,15,14,12,13,12,15,15, 5, 7, 6, + 10,10, 7, 8, 8,10,10, 7, 8, 8,10,10,10,11,10,13, + 13,10,10,10,12,12, 7, 8, 8,11,10, 8, 8, 9,10,11, + 8, 9, 9,11,11,11,10,11,11,14,11,11,11,13,13, 6, + 8, 8,10,10, 7, 9, 8,11,10, 8, 9, 9,11,11,10,11, + 10,14,11,10,11,11,13,13,10,11,11,14,13,10,10,11, + 14,13,10,11,11,14,14,12,11,13,12,16,13,14,14,15, + 15,10,10,11,13,14,10,11,10,14,13,10,11,11,14,14, + 12,13,12,15,13,13,13,14,15,16, 5, 7, 7,10,10, 7, + 8, 8,10,10, 7, 8, 8,10,10,10,10,10,13,13,10,10, + 11,12,13, 6, 8, 8,11,10, 8, 9, 9,11,11, 7, 8, 9, + 10,11,10,11,11,13,13,10,10,11,11,13, 6, 8, 8,10, + 11, 8, 9, 9,11,11, 8, 9, 8,12,10,10,11,11,13,13, + 10,11,10,14,11,10,10,10,14,13,10,11,11,14,13,10, + 10,11,13,13,12,14,14,16,16,12,12,13,13,15,10,11, + 11,13,14,10,11,11,14,15,10,11,10,13,13,13,14,13, + 16,16,12,13,11,15,12, 9,10,10,13,13,10,11,11,14, + 13,10,10,11,13,14,13,14,13,16,16,13,13,13,15,16, + 9,10,10,13,13,10,10,11,13,14,10,11,11,15,13,13, + 13,14,14,18,13,13,14,16,15, 9,10,10,13,14,10,11, + 10,14,13,10,11,11,13,14,13,14,13,16,15,13,13,14, + 15,16,12,13,12,16,14,11,11,13,15,15,13,14,13,16, + 15,15,12,16,12,17,14,15,15,17,17,12,13,13,14,16, + 11,13,11,16,15,12,13,14,15,16,14,15,13, 0,14,14, + 16,16, 0, 0, 9,10,10,13,13,10,11,10,14,14,10,11, + 11,13,13,12,13,13,14,16,13,14,14,16,16, 9,10,10, + 14,14,11,11,11,14,13,10,10,11,14,14,13,13,13,16, + 16,13,13,14,14,17, 9,10,10,13,14,10,11,11,13,15, + 10,11,10,14,14,13,13,13,14,17,13,14,13,17,14,12, + 13,13,16,14,13,14,13,16,15,12,12,13,15,16,15,15, + 16,18,16,15,13,15,14, 0,12,12,13,14,16,13,13,14, + 15,16,11,12,11,16,14,15,16,16,17,17,14,15,12,17, + 12, +}; + +static float _vq_quantthresh__44u0__p4_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44u0__p4_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44u0__p4_0 = { + _vq_quantthresh__44u0__p4_0, + _vq_quantmap__44u0__p4_0, + 5, + 5 +}; + +static static_codebook _44u0__p4_0 = { + 4, 625, + _vq_lengthlist__44u0__p4_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44u0__p4_0, + NULL, + &_vq_auxt__44u0__p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u0__p5_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44u0__p5_0[] = { + 1, 4, 4, 7, 7, 7, 7, 9, 9, 4, 6, 6, 8, 8, 8, 8, + 9, 9, 4, 6, 6, 8, 8, 8, 8, 9, 9, 7, 8, 8, 9, 9, + 9, 9,11,10, 7, 8, 8, 9, 9, 9, 9,10,10, 7, 8, 8, + 9, 9,10,10,11,11, 7, 8, 8, 9, 9,10,10,11,11, 9, + 9, 9,10,10,11,11,12,12, 9, 9, 9,10,11,11,11,12, + 12, +}; + +static float _vq_quantthresh__44u0__p5_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44u0__p5_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44u0__p5_0 = { + _vq_quantthresh__44u0__p5_0, + _vq_quantmap__44u0__p5_0, + 9, + 9 +}; + +static static_codebook _44u0__p5_0 = { + 2, 81, + _vq_lengthlist__44u0__p5_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44u0__p5_0, + NULL, + &_vq_auxt__44u0__p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u0__p6_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44u0__p6_0[] = { + 1, 4, 4, 6, 6, 8, 8,10, 9,11,10,14,13, 4, 6, 5, + 8, 8, 9, 9,11,10,11,11,14,14, 4, 5, 6, 8, 8, 9, + 9,10,10,11,11,14,14, 6, 8, 8, 9, 9,10,10,11,11, + 12,12,16,15, 7, 8, 8, 9, 9,10,10,11,11,12,12,15, + 15, 9,10,10,10,10,11,11,12,12,12,12,15,15, 9,10, + 9,10,11,11,11,12,12,12,13,15,15,10,10,11,11,11, + 12,12,13,12,13,13,16,15,10,11,11,11,11,12,12,13, + 12,13,13,16,17,11,11,12,12,12,13,13,13,14,14,15, + 17,17,11,11,12,12,12,13,13,13,14,14,14,16,18,14, + 15,15,15,15,16,16,16,16,17,18, 0, 0,14,15,15,15, + 15,17,16,17,18,17,17,18, 0, +}; + +static float _vq_quantthresh__44u0__p6_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__44u0__p6_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44u0__p6_0 = { + _vq_quantthresh__44u0__p6_0, + _vq_quantmap__44u0__p6_0, + 13, + 13 +}; + +static static_codebook _44u0__p6_0 = { + 2, 169, + _vq_lengthlist__44u0__p6_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__44u0__p6_0, + NULL, + &_vq_auxt__44u0__p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u0__p6_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44u0__p6_1[] = { + 2, 4, 4, 5, 5, 4, 5, 5, 5, 5, 4, 5, 5, 5, 5, 5, + 6, 6, 6, 6, 5, 6, 6, 6, 6, +}; + +static float _vq_quantthresh__44u0__p6_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44u0__p6_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44u0__p6_1 = { + _vq_quantthresh__44u0__p6_1, + _vq_quantmap__44u0__p6_1, + 5, + 5 +}; + +static static_codebook _44u0__p6_1 = { + 2, 25, + _vq_lengthlist__44u0__p6_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44u0__p6_1, + NULL, + &_vq_auxt__44u0__p6_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u0__p7_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44u0__p7_0[] = { + 1, 4, 4,11,11, 9,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11, 9,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,10,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10, +}; + +static float _vq_quantthresh__44u0__p7_0[] = { + -253.5, -84.5, 84.5, 253.5, +}; + +static long _vq_quantmap__44u0__p7_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44u0__p7_0 = { + _vq_quantthresh__44u0__p7_0, + _vq_quantmap__44u0__p7_0, + 5, + 5 +}; + +static static_codebook _44u0__p7_0 = { + 4, 625, + _vq_lengthlist__44u0__p7_0, + 1, -518709248, 1626677248, 3, 0, + _vq_quantlist__44u0__p7_0, + NULL, + &_vq_auxt__44u0__p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u0__p7_1[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44u0__p7_1[] = { + 1, 4, 4, 6, 6, 6, 6, 7, 7, 8, 8, 9, 9, 5, 7, 7, + 8, 7, 7, 7, 9, 8,10, 9,10,11, 5, 7, 7, 8, 8, 7, + 7, 8, 9,10,10,11,11, 6, 8, 8, 9, 9, 9, 9,11,10, + 12,12,15,12, 6, 8, 8, 9, 9, 9, 9,11,11,12,11,14, + 12, 7, 8, 8,10,10,12,12,13,13,13,15,13,13, 7, 8, + 8,10,10,11,11,13,12,14,15,15,15, 9,10,10,11,12, + 13,13,14,15,14,15,14,15, 8,10,10,12,12,14,14,15, + 14,14,15,15,14,10,12,12,14,14,15,14,15,15,15,14, + 15,15,10,12,12,13,14,15,14,15,15,14,15,15,15,12, + 15,13,15,14,15,15,15,15,15,15,15,15,13,13,15,15, + 15,15,15,15,15,15,15,15,15, +}; + +static float _vq_quantthresh__44u0__p7_1[] = { + -71.5, -58.5, -45.5, -32.5, -19.5, -6.5, 6.5, 19.5, + 32.5, 45.5, 58.5, 71.5, +}; + +static long _vq_quantmap__44u0__p7_1[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44u0__p7_1 = { + _vq_quantthresh__44u0__p7_1, + _vq_quantmap__44u0__p7_1, + 13, + 13 +}; + +static static_codebook _44u0__p7_1 = { + 2, 169, + _vq_lengthlist__44u0__p7_1, + 1, -523010048, 1618608128, 4, 0, + _vq_quantlist__44u0__p7_1, + NULL, + &_vq_auxt__44u0__p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u0__p7_2[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44u0__p7_2[] = { + 2, 5, 4, 6, 6, 7, 7, 8, 8, 8, 8, 9, 8, 5, 5, 6, + 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 5, 6, 5, 7, 7, 8, + 8, 8, 8, 9, 9, 9, 9, 6, 7, 7, 8, 8, 8, 8, 9, 8, + 9, 9, 9, 9, 6, 7, 7, 8, 7, 8, 8, 9, 9, 9, 9, 9, + 9, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 7, 8, + 8, 9, 8, 9, 8, 9, 9, 9, 9, 9, 9, 8, 9, 8, 9, 9, + 9, 9, 9, 9, 9, 9,10,10, 8, 8, 9, 9, 9, 9, 9, 9, + 9, 9,10, 9,10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9,10,10,10, 9, 9, 9, 9, 9, + 9, 9, 9,10, 9, 9,10,10, 9, +}; + +static float _vq_quantthresh__44u0__p7_2[] = { + -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, + 2.5, 3.5, 4.5, 5.5, +}; + +static long _vq_quantmap__44u0__p7_2[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44u0__p7_2 = { + _vq_quantthresh__44u0__p7_2, + _vq_quantmap__44u0__p7_2, + 13, + 13 +}; + +static static_codebook _44u0__p7_2 = { + 2, 169, + _vq_lengthlist__44u0__p7_2, + 1, -531103744, 1611661312, 4, 0, + _vq_quantlist__44u0__p7_2, + NULL, + &_vq_auxt__44u0__p7_2, + NULL, + 0 +}; + +static long _huff_lengthlist__44u0__short[] = { + 12,13,14,13,17,12,15,17, 5, 5, 6,10,10,11,15,16, + 4, 3, 3, 7, 5, 7,10,16, 7, 7, 7,10, 9,11,12,16, + 6, 5, 5, 9, 5, 6,10,16, 8, 7, 7, 9, 6, 7, 9,16, + 11, 7, 3, 6, 4, 5, 8,16,12, 9, 4, 8, 5, 7, 9,16, +}; + +static static_codebook _huff_book__44u0__short = { + 2, 64, + _huff_lengthlist__44u0__short, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__44u1__long[] = { + 5, 8,13,10,17,11,11,15, 7, 2, 4, 5, 8, 7, 9,16, + 13, 4, 3, 5, 6, 8,11,20,10, 4, 5, 5, 7, 6, 8,18, + 15, 7, 6, 7, 8,10,14,20,10, 6, 7, 6, 9, 7, 8,17, + 9, 8,10, 8,10, 5, 4,11,12,17,19,14,16,10, 7,12, +}; + +static static_codebook _huff_book__44u1__long = { + 2, 64, + _huff_lengthlist__44u1__long, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__44u1__p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44u1__p1_0[] = { + 1, 4, 4, 5, 8, 7, 5, 7, 8, 5, 8, 8, 8,11,11, 8, + 10,10, 5, 8, 8, 8,11,10, 8,11,11, 4, 8, 8, 8,11, + 11, 8,11,11, 8,12,11,11,13,13,11,13,14, 7,11,11, + 10,13,12,11,13,14, 4, 8, 8, 8,11,11, 8,11,12, 8, + 11,11,11,13,13,10,12,13, 8,11,11,11,14,13,11,14, + 13, +}; + +static float _vq_quantthresh__44u1__p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44u1__p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44u1__p1_0 = { + _vq_quantthresh__44u1__p1_0, + _vq_quantmap__44u1__p1_0, + 3, + 3 +}; + +static static_codebook _44u1__p1_0 = { + 4, 81, + _vq_lengthlist__44u1__p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44u1__p1_0, + NULL, + &_vq_auxt__44u1__p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u1__p2_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44u1__p2_0[] = { + 2, 4, 4, 5, 6, 6, 5, 6, 6, 5, 7, 7, 7, 8, 8, 6, + 8, 8, 5, 7, 7, 6, 8, 8, 7, 8, 8, 4, 7, 7, 7, 8, + 8, 7, 8, 8, 7, 8, 8, 8, 9,10, 8,10,10, 6, 8, 8, + 8,10, 8, 8,10,10, 5, 7, 7, 7, 8, 8, 7, 8, 8, 6, + 8, 8, 8,10,10, 8, 8,10, 6, 8, 8, 8,10,10, 8,10, + 9, +}; + +static float _vq_quantthresh__44u1__p2_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44u1__p2_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44u1__p2_0 = { + _vq_quantthresh__44u1__p2_0, + _vq_quantmap__44u1__p2_0, + 3, + 3 +}; + +static static_codebook _44u1__p2_0 = { + 4, 81, + _vq_lengthlist__44u1__p2_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44u1__p2_0, + NULL, + &_vq_auxt__44u1__p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u1__p3_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44u1__p3_0[] = { + 1, 5, 5, 8, 8, 5, 8, 7, 9, 9, 5, 7, 8, 9, 9, 9, + 10, 9,12,12, 9, 9,10,12,12, 6, 8, 8,11,10, 8,10, + 10,11,11, 8, 9,10,11,11,10,11,11,14,13,10,11,11, + 13,13, 5, 8, 8,10,10, 8,10,10,11,11, 8,10,10,11, + 11,10,11,11,13,13,10,11,11,13,13, 9,11,11,15,14, + 10,12,12,15,14,10,12,11,15,14,13,14,14,16,16,12, + 14,13,17,15, 9,11,11,14,15,10,11,12,14,16,10,11, + 12,14,16,12,13,14,16,16,13,13,15,15,18, 5, 8, 8, + 11,11, 8,10,10,12,12, 8,10,10,12,13,11,12,12,14, + 14,11,12,12,15,15, 8,10,10,13,13,10,12,12,13,13, + 10,12,12,14,14,12,13,13,15,15,12,13,13,16,16, 7, + 10,10,12,12,10,12,11,13,13,10,12,12,13,14,12,13, + 12,15,14,12,13,13,16,16,10,12,12,17,16,12,13,13, + 16,15,11,13,13,17,17,15,15,15,16,17,14,15,15,19, + 19,10,12,12,15,16,11,13,12,15,18,11,13,13,16,16, + 14,15,15,17,17,14,15,15,17,19, 5, 8, 8,11,11, 8, + 10,10,12,12, 8,10,10,12,12,11,12,12,16,15,11,12, + 12,14,15, 7,10,10,13,13,10,12,12,14,13,10,11,12, + 13,13,12,13,13,16,16,12,12,13,15,15, 8,10,10,13, + 13,10,12,12,14,14,10,12,12,13,13,12,13,13,16,16, + 12,13,13,15,15,10,12,12,16,15,11,13,13,17,16,11, + 12,13,16,15,13,15,15,19,17,14,15,14,17,16,10,12, + 12,16,16,11,13,13,16,17,12,13,13,15,17,14,15,15, + 17,19,14,15,15,17,17, 8,11,11,16,16,10,13,12,17, + 17,10,12,13,16,16,15,17,16,20,19,14,15,17,18,19, + 9,12,12,16,17,11,13,14,17,18,11,13,13,19,18,16, + 17,18,19,19,15,16,16,19,19, 9,12,12,16,17,11,14, + 13,18,17,11,13,13,17,17,16,17,16,20,19,14,16,16, + 18,18,12,15,15,19,17,14,15,16, 0,20,13,15,16,20, + 17,18,16,20, 0, 0,15,16,19,20, 0,12,15,14,18,19, + 13,16,15,20,19,13,16,15,20,18,17,18,17, 0,20,16, + 17,16, 0, 0, 8,11,11,16,15,10,12,12,17,17,10,13, + 13,17,16,14,16,15,18,20,15,16,16,19,19, 9,12,12, + 16,16,11,13,13,17,16,11,13,14,17,18,15,15,16,20, + 20,16,16,17,19,19, 9,13,12,16,17,11,14,13,17,17, + 11,14,14,18,17,14,16,15,18,19,16,17,18,18,19,12, + 14,15,19,18,13,15,16,18, 0,13,14,15, 0, 0,16,16, + 17,20, 0,17,17,20,20, 0,12,15,15,19,20,13,15,15, + 0, 0,14,16,15, 0, 0,15,18,16, 0, 0,17,18,16, 0, + 19, +}; + +static float _vq_quantthresh__44u1__p3_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44u1__p3_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44u1__p3_0 = { + _vq_quantthresh__44u1__p3_0, + _vq_quantmap__44u1__p3_0, + 5, + 5 +}; + +static static_codebook _44u1__p3_0 = { + 4, 625, + _vq_lengthlist__44u1__p3_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44u1__p3_0, + NULL, + &_vq_auxt__44u1__p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u1__p4_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44u1__p4_0[] = { + 4, 5, 5, 9, 9, 5, 6, 6, 9, 9, 5, 6, 6, 9, 9, 9, + 10, 9,12,12, 9, 9,10,12,12, 5, 7, 7,10,10, 7, 7, + 8,10,10, 6, 7, 8,10,10,10,10,10,11,13,10, 9,10, + 12,13, 5, 7, 7,10,10, 6, 8, 7,10,10, 7, 8, 7,10, + 10, 9,10,10,12,12,10,10,10,13,11, 9,10,10,13,13, + 10,11,10,13,13,10,10,10,13,13,12,12,13,14,14,12, + 12,13,14,14, 9,10,10,13,13,10,10,10,13,13,10,10, + 10,13,13,12,13,12,15,14,12,13,12,15,15, 5, 7, 6, + 10,10, 7, 8, 8,10,10, 7, 8, 8,10,10,10,11,10,13, + 13,10,10,10,12,12, 7, 8, 8,11,10, 8, 8, 9,10,11, + 8, 9, 9,11,11,11,10,11,11,14,11,11,11,13,13, 6, + 8, 8,10,10, 7, 9, 8,11,10, 8, 9, 9,11,11,10,11, + 10,14,11,10,11,11,13,13,10,11,11,14,13,10,10,11, + 14,13,10,11,11,14,14,12,11,13,12,16,13,14,14,15, + 15,10,10,11,13,14,10,11,10,14,13,10,11,11,14,14, + 12,13,12,15,13,13,13,14,15,16, 5, 7, 7,10,10, 7, + 8, 8,10,10, 7, 8, 8,10,10,10,10,10,13,13,10,10, + 11,12,13, 6, 8, 8,11,10, 8, 9, 9,11,11, 7, 8, 9, + 10,11,10,11,11,13,13,10,10,11,11,13, 6, 8, 8,10, + 11, 8, 9, 9,11,11, 8, 9, 8,12,10,10,11,11,13,13, + 10,11,10,14,11,10,10,10,14,13,10,11,11,14,13,10, + 10,11,13,13,12,14,14,16,16,12,12,13,13,15,10,11, + 11,13,14,10,11,11,14,15,10,11,10,13,13,13,14,13, + 16,16,12,13,11,15,12, 9,10,10,13,13,10,11,11,14, + 13,10,10,11,13,14,13,14,13,16,16,13,13,13,15,16, + 9,10,10,13,13,10,10,11,13,14,10,11,11,15,13,13, + 13,14,14,18,13,13,14,16,15, 9,10,10,13,14,10,11, + 10,14,13,10,11,11,13,14,13,14,13,16,15,13,13,14, + 15,16,12,13,12,16,14,11,11,13,15,15,13,14,13,16, + 15,15,12,16,12,17,14,15,15,17,17,12,13,13,14,16, + 11,13,11,16,15,12,13,14,15,16,14,15,13, 0,14,14, + 16,16, 0, 0, 9,10,10,13,13,10,11,10,14,14,10,11, + 11,13,13,12,13,13,14,16,13,14,14,16,16, 9,10,10, + 14,14,11,11,11,14,13,10,10,11,14,14,13,13,13,16, + 16,13,13,14,14,17, 9,10,10,13,14,10,11,11,13,15, + 10,11,10,14,14,13,13,13,14,17,13,14,13,17,14,12, + 13,13,16,14,13,14,13,16,15,12,12,13,15,16,15,15, + 16,18,16,15,13,15,14, 0,12,12,13,14,16,13,13,14, + 15,16,11,12,11,16,14,15,16,16,17,17,14,15,12,17, + 12, +}; + +static float _vq_quantthresh__44u1__p4_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44u1__p4_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44u1__p4_0 = { + _vq_quantthresh__44u1__p4_0, + _vq_quantmap__44u1__p4_0, + 5, + 5 +}; + +static static_codebook _44u1__p4_0 = { + 4, 625, + _vq_lengthlist__44u1__p4_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44u1__p4_0, + NULL, + &_vq_auxt__44u1__p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u1__p5_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44u1__p5_0[] = { + 1, 4, 4, 7, 7, 7, 7, 9, 9, 4, 6, 6, 8, 8, 8, 8, + 9, 9, 4, 6, 6, 8, 8, 8, 8, 9, 9, 7, 8, 8, 9, 9, + 9, 9,11,10, 7, 8, 8, 9, 9, 9, 9,10,10, 7, 8, 8, + 9, 9,10,10,11,11, 7, 8, 8, 9, 9,10,10,11,11, 9, + 9, 9,10,10,11,11,12,12, 9, 9, 9,10,11,11,11,12, + 12, +}; + +static float _vq_quantthresh__44u1__p5_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44u1__p5_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44u1__p5_0 = { + _vq_quantthresh__44u1__p5_0, + _vq_quantmap__44u1__p5_0, + 9, + 9 +}; + +static static_codebook _44u1__p5_0 = { + 2, 81, + _vq_lengthlist__44u1__p5_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44u1__p5_0, + NULL, + &_vq_auxt__44u1__p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u1__p6_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44u1__p6_0[] = { + 1, 4, 4, 6, 6, 8, 8,10, 9,11,10,14,13, 4, 6, 5, + 8, 8, 9, 9,11,10,11,11,14,14, 4, 5, 6, 8, 8, 9, + 9,10,10,11,11,14,14, 6, 8, 8, 9, 9,10,10,11,11, + 12,12,16,15, 7, 8, 8, 9, 9,10,10,11,11,12,12,15, + 15, 9,10,10,10,10,11,11,12,12,12,12,15,15, 9,10, + 9,10,11,11,11,12,12,12,13,15,15,10,10,11,11,11, + 12,12,13,12,13,13,16,15,10,11,11,11,11,12,12,13, + 12,13,13,16,17,11,11,12,12,12,13,13,13,14,14,15, + 17,17,11,11,12,12,12,13,13,13,14,14,14,16,18,14, + 15,15,15,15,16,16,16,16,17,18, 0, 0,14,15,15,15, + 15,17,16,17,18,17,17,18, 0, +}; + +static float _vq_quantthresh__44u1__p6_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__44u1__p6_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44u1__p6_0 = { + _vq_quantthresh__44u1__p6_0, + _vq_quantmap__44u1__p6_0, + 13, + 13 +}; + +static static_codebook _44u1__p6_0 = { + 2, 169, + _vq_lengthlist__44u1__p6_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__44u1__p6_0, + NULL, + &_vq_auxt__44u1__p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u1__p6_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44u1__p6_1[] = { + 2, 4, 4, 5, 5, 4, 5, 5, 5, 5, 4, 5, 5, 5, 5, 5, + 6, 6, 6, 6, 5, 6, 6, 6, 6, +}; + +static float _vq_quantthresh__44u1__p6_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44u1__p6_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44u1__p6_1 = { + _vq_quantthresh__44u1__p6_1, + _vq_quantmap__44u1__p6_1, + 5, + 5 +}; + +static static_codebook _44u1__p6_1 = { + 2, 25, + _vq_lengthlist__44u1__p6_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44u1__p6_1, + NULL, + &_vq_auxt__44u1__p6_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u1__p7_0[] = { + 3, + 2, + 4, + 1, + 5, + 0, + 6, +}; + +static long _vq_lengthlist__44u1__p7_0[] = { + 1, 3, 2, 9, 9, 7, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, +}; + +static float _vq_quantthresh__44u1__p7_0[] = { + -422.5, -253.5, -84.5, 84.5, 253.5, 422.5, +}; + +static long _vq_quantmap__44u1__p7_0[] = { + 5, 3, 1, 0, 2, 4, 6, +}; + +static encode_aux_threshmatch _vq_auxt__44u1__p7_0 = { + _vq_quantthresh__44u1__p7_0, + _vq_quantmap__44u1__p7_0, + 7, + 7 +}; + +static static_codebook _44u1__p7_0 = { + 2, 49, + _vq_lengthlist__44u1__p7_0, + 1, -518017024, 1626677248, 3, 0, + _vq_quantlist__44u1__p7_0, + NULL, + &_vq_auxt__44u1__p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u1__p7_1[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44u1__p7_1[] = { + 1, 4, 4, 6, 6, 6, 6, 7, 7, 8, 8, 9, 9, 5, 7, 7, + 8, 7, 7, 7, 9, 8,10, 9,10,11, 5, 7, 7, 8, 8, 7, + 7, 8, 9,10,10,11,11, 6, 8, 8, 9, 9, 9, 9,11,10, + 12,12,15,12, 6, 8, 8, 9, 9, 9, 9,11,11,12,11,14, + 12, 7, 8, 8,10,10,12,12,13,13,13,15,13,13, 7, 8, + 8,10,10,11,11,13,12,14,15,15,15, 9,10,10,11,12, + 13,13,14,15,14,15,14,15, 8,10,10,12,12,14,14,15, + 14,14,15,15,14,10,12,12,14,14,15,14,15,15,15,14, + 15,15,10,12,12,13,14,15,14,15,15,14,15,15,15,12, + 15,13,15,14,15,15,15,15,15,15,15,15,13,13,15,15, + 15,15,15,15,15,15,15,15,15, +}; + +static float _vq_quantthresh__44u1__p7_1[] = { + -71.5, -58.5, -45.5, -32.5, -19.5, -6.5, 6.5, 19.5, + 32.5, 45.5, 58.5, 71.5, +}; + +static long _vq_quantmap__44u1__p7_1[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44u1__p7_1 = { + _vq_quantthresh__44u1__p7_1, + _vq_quantmap__44u1__p7_1, + 13, + 13 +}; + +static static_codebook _44u1__p7_1 = { + 2, 169, + _vq_lengthlist__44u1__p7_1, + 1, -523010048, 1618608128, 4, 0, + _vq_quantlist__44u1__p7_1, + NULL, + &_vq_auxt__44u1__p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u1__p7_2[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44u1__p7_2[] = { + 2, 5, 4, 6, 6, 7, 7, 8, 8, 8, 8, 9, 8, 5, 5, 6, + 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 5, 6, 5, 7, 7, 8, + 8, 8, 8, 9, 9, 9, 9, 6, 7, 7, 8, 8, 8, 8, 9, 8, + 9, 9, 9, 9, 6, 7, 7, 8, 7, 8, 8, 9, 9, 9, 9, 9, + 9, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 7, 8, + 8, 9, 8, 9, 8, 9, 9, 9, 9, 9, 9, 8, 9, 8, 9, 9, + 9, 9, 9, 9, 9, 9,10,10, 8, 8, 9, 9, 9, 9, 9, 9, + 9, 9,10, 9,10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9,10,10,10, 9, 9, 9, 9, 9, + 9, 9, 9,10, 9, 9,10,10, 9, +}; + +static float _vq_quantthresh__44u1__p7_2[] = { + -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, + 2.5, 3.5, 4.5, 5.5, +}; + +static long _vq_quantmap__44u1__p7_2[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44u1__p7_2 = { + _vq_quantthresh__44u1__p7_2, + _vq_quantmap__44u1__p7_2, + 13, + 13 +}; + +static static_codebook _44u1__p7_2 = { + 2, 169, + _vq_lengthlist__44u1__p7_2, + 1, -531103744, 1611661312, 4, 0, + _vq_quantlist__44u1__p7_2, + NULL, + &_vq_auxt__44u1__p7_2, + NULL, + 0 +}; + +static long _huff_lengthlist__44u1__short[] = { + 12,13,14,13,17,12,15,17, 5, 5, 6,10,10,11,15,16, + 4, 3, 3, 7, 5, 7,10,16, 7, 7, 7,10, 9,11,12,16, + 6, 5, 5, 9, 5, 6,10,16, 8, 7, 7, 9, 6, 7, 9,16, + 11, 7, 3, 6, 4, 5, 8,16,12, 9, 4, 8, 5, 7, 9,16, +}; + +static static_codebook _huff_book__44u1__short = { + 2, 64, + _huff_lengthlist__44u1__short, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__44u2__long[] = { + 5, 9,14,12,15,13,10,13, 7, 4, 5, 6, 8, 7, 8,12, + 13, 4, 3, 5, 5, 6, 9,15,12, 6, 5, 6, 6, 6, 7,14, + 14, 7, 4, 6, 4, 6, 8,15,12, 6, 6, 5, 5, 5, 6,14, + 9, 7, 8, 6, 7, 5, 4,10,10,13,14,14,15,10, 6, 8, +}; + +static static_codebook _huff_book__44u2__long = { + 2, 64, + _huff_lengthlist__44u2__long, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__44u2__p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44u2__p1_0[] = { + 1, 4, 4, 5, 8, 7, 5, 7, 8, 5, 8, 8, 8,11,11, 8, + 10,11, 5, 8, 8, 8,11,10, 8,11,11, 4, 8, 8, 8,11, + 11, 8,11,11, 8,11,11,11,13,14,11,13,13, 7,11,11, + 10,13,12,11,14,14, 4, 8, 8, 8,11,11, 8,11,11, 8, + 11,11,11,14,13,10,12,13, 8,11,11,11,13,13,11,13, + 13, +}; + +static float _vq_quantthresh__44u2__p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44u2__p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44u2__p1_0 = { + _vq_quantthresh__44u2__p1_0, + _vq_quantmap__44u2__p1_0, + 3, + 3 +}; + +static static_codebook _44u2__p1_0 = { + 4, 81, + _vq_lengthlist__44u2__p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44u2__p1_0, + NULL, + &_vq_auxt__44u2__p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u2__p2_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44u2__p2_0[] = { + 2, 5, 5, 5, 6, 6, 5, 6, 6, 5, 6, 6, 7, 8, 8, 6, + 8, 8, 5, 6, 6, 6, 8, 7, 7, 8, 8, 5, 6, 6, 7, 8, + 8, 6, 8, 8, 6, 8, 8, 8, 9,10, 8,10,10, 6, 8, 8, + 7,10, 8, 8,10,10, 5, 6, 6, 6, 8, 8, 7, 8, 8, 6, + 8, 8, 8,10,10, 8, 8,10, 6, 8, 8, 8,10,10, 8,10, + 9, +}; + +static float _vq_quantthresh__44u2__p2_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44u2__p2_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44u2__p2_0 = { + _vq_quantthresh__44u2__p2_0, + _vq_quantmap__44u2__p2_0, + 3, + 3 +}; + +static static_codebook _44u2__p2_0 = { + 4, 81, + _vq_lengthlist__44u2__p2_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44u2__p2_0, + NULL, + &_vq_auxt__44u2__p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u2__p3_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44u2__p3_0[] = { + 2, 4, 4, 7, 8, 5, 7, 7, 9, 9, 5, 7, 7, 9, 9, 8, + 9, 9,12,11, 8, 9, 9,11,12, 5, 7, 7,10,10, 7, 9, + 9,11,11, 7, 9, 9,10,11,10,11,11,13,13, 9,10,11, + 12,13, 5, 7, 7,10,10, 7, 9, 9,11,10, 7, 9, 9,11, + 11, 9,11,10,13,13,10,11,11,13,13, 8,10,10,14,13, + 10,11,11,15,14, 9,11,11,15,14,13,14,13,16,14,12, + 13,13,15,16, 8,10,10,13,14, 9,11,11,14,15,10,11, + 11,14,15,12,13,13,15,15,12,13,14,15,16, 5, 7, 7, + 10,10, 7, 9, 9,11,11, 7, 9, 9,11,12,10,11,11,14, + 13,10,11,11,14,14, 7, 9, 9,12,12, 9,11,11,13,13, + 9,11,11,13,13,12,13,12,14,14,11,12,13,15,15, 7, + 9, 9,12,12, 8,11,10,13,12, 9,11,11,13,13,11,13, + 12,15,13,11,13,13,15,16, 9,12,11,15,15,11,12,12, + 16,15,11,12,13,16,16,13,14,15,16,15,13,15,15,17, + 17, 9,11,11,14,15,10,12,12,15,15,11,13,12,15,16, + 13,15,14,16,16,13,15,15,17,19, 5, 7, 7,10,10, 7, + 9, 9,12,11, 7, 9, 9,11,11,10,11,11,14,14,10,11, + 11,13,14, 7, 9, 9,12,12, 9,11,11,13,13, 9,10,11, + 12,13,11,13,12,16,15,11,12,12,14,15, 7, 9, 9,12, + 12, 9,11,11,13,13, 9,11,11,13,12,11,13,12,15,16, + 12,13,13,15,14, 9,11,11,15,14,11,13,12,16,15,10, + 11,12,15,15,13,14,14,18,17,13,14,14,15,17,10,11, + 11,14,15,11,13,12,15,17,11,13,12,15,16,13,15,14, + 18,17,14,15,15,16,18, 7,10,10,14,14,10,12,12,15, + 15,10,12,12,15,15,14,15,15,18,17,13,15,15,16,16, + 9,11,11,16,15,11,13,13,16,18,11,13,13,16,16,15, + 16,16, 0, 0,14,15,16,18,17, 9,11,11,15,15,10,13, + 12,17,16,11,12,13,16,17,14,15,16,19,19,14,15,15, + 0,20,12,14,14, 0, 0,13,14,16,19,18,13,15,16,20, + 17,16,18, 0, 0, 0,15,16,17,18,19,11,14,14, 0,19, + 12,15,14,17,17,13,15,15, 0, 0,16,17,15,20,19,15, + 17,16,19, 0, 8,10,10,14,15,10,12,11,15,15,10,11, + 12,16,15,13,14,14,19,17,14,15,15, 0, 0, 9,11,11, + 16,15,11,13,13,17,16,10,12,13,16,17,14,15,15,18, + 18,14,15,16,20,19, 9,12,12, 0,15,11,13,13,16,17, + 11,13,13,19,17,14,16,16,18,17,15,16,16,17,19,11, + 14,14,18,18,13,14,15, 0, 0,12,14,15,19,18,15,16, + 19, 0,19,15,16,19,19,17,12,14,14,16,19,13,15,15, + 0,17,13,15,14,18,18,15,16,15, 0,18,16,17,17, 0, + 0, +}; + +static float _vq_quantthresh__44u2__p3_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44u2__p3_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44u2__p3_0 = { + _vq_quantthresh__44u2__p3_0, + _vq_quantmap__44u2__p3_0, + 5, + 5 +}; + +static static_codebook _44u2__p3_0 = { + 4, 625, + _vq_lengthlist__44u2__p3_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44u2__p3_0, + NULL, + &_vq_auxt__44u2__p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u2__p4_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44u2__p4_0[] = { + 4, 5, 5, 8, 8, 5, 7, 6, 9, 9, 5, 6, 7, 9, 9, 9, + 9, 9,11,11, 9, 9, 9,11,11, 5, 7, 7, 9, 9, 7, 8, + 8,10,10, 7, 7, 8,10,10,10,10,10,11,12, 9,10,10, + 11,12, 5, 7, 7, 9, 9, 6, 8, 7,10,10, 7, 8, 8,10, + 10, 9,10,10,12,11, 9,10,10,12,11, 9,10,10,12,12, + 10,10,10,13,12, 9,10,10,12,13,12,12,12,14,14,11, + 12,12,13,14, 9,10,10,12,12, 9,10,10,12,13,10,10, + 10,12,13,11,12,12,14,13,12,12,12,14,13, 5, 7, 7, + 10, 9, 7, 8, 8,10,10, 7, 8, 8,10,10,10,10,10,12, + 12,10,10,10,12,12, 7, 8, 8,11,10, 8, 8, 9,11,11, + 8, 9, 9,11,11,10,11,11,12,13,10,11,11,13,13, 6, + 8, 8,10,10, 7, 9, 8,11,10, 8, 9, 9,11,11,10,11, + 10,13,11,10,11,11,13,13, 9,10,10,13,13,10,11,11, + 13,13,10,11,11,14,13,12,11,13,12,15,12,13,13,15, + 15, 9,10,10,12,13,10,11,10,13,13,10,11,11,13,13, + 12,13,11,15,13,12,13,13,15,15, 5, 7, 7, 9,10, 7, + 8, 8,10,10, 7, 8, 8,10,10,10,10,10,12,12,10,10, + 11,12,12, 6, 8, 8,10,10, 8, 9, 9,11,11, 7, 8, 9, + 10,11,10,11,11,13,13,10,10,11,11,13, 7, 8, 8,10, + 11, 8, 9, 9,11,11, 8, 9, 8,11,11,10,11,11,13,13, + 10,11,11,13,12, 9,10,10,13,12,10,11,11,14,13,10, + 10,11,13,13,12,13,13,15,15,12,11,13,12,14, 9,10, + 10,12,13,10,11,11,13,14,10,11,11,13,13,12,13,13, + 15,15,12,13,12,15,12, 8, 9, 9,12,12, 9,11,10,13, + 13, 9,10,10,13,13,12,13,13,15,15,12,12,12,14,14, + 9,10,10,13,13,10,11,11,13,14,10,11,11,14,12,13, + 13,14,14,16,12,13,13,15,14, 9,10,10,13,13,10,11, + 10,14,13,10,11,11,13,14,12,14,13,16,14,13,13,13, + 14,15,11,13,12,15,14,11,12,13,14,15,12,13,13,16, + 15,14,12,15,12,16,14,15,15,17,16,11,12,12,14,15, + 11,13,11,15,14,12,13,13,15,16,13,15,12,17,13,14, + 15,15,16,16, 8, 9, 9,12,12, 9,10,10,13,13, 9,10, + 10,13,13,12,13,12,14,14,12,13,13,15,15, 9,10,10, + 13,13,10,11,11,14,13,10,10,11,13,14,12,13,13,15, + 14,12,12,14,14,16, 9,10,10,13,13,10,11,11,13,14, + 10,11,11,14,13,13,13,13,15,15,13,14,13,16,14,11, + 12,12,14,14,12,13,13,16,15,11,12,13,14,15,14,15, + 15,16,16,14,13,15,13,17,11,12,12,14,15,12,13,13, + 15,16,11,13,12,15,15,14,15,14,16,16,14,15,12,17, + 13, +}; + +static float _vq_quantthresh__44u2__p4_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44u2__p4_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44u2__p4_0 = { + _vq_quantthresh__44u2__p4_0, + _vq_quantmap__44u2__p4_0, + 5, + 5 +}; + +static static_codebook _44u2__p4_0 = { + 4, 625, + _vq_lengthlist__44u2__p4_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44u2__p4_0, + NULL, + &_vq_auxt__44u2__p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u2__p5_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44u2__p5_0[] = { + 1, 4, 4, 7, 7, 8, 8, 9, 9, 4, 6, 5, 8, 8, 8, 8, + 10,10, 4, 5, 6, 8, 8, 8, 8,10,10, 7, 8, 8, 9, 9, + 9, 9,11,11, 7, 8, 8, 9, 9, 9, 9,11,11, 8, 8, 8, + 9, 9,10,11,12,12, 8, 8, 8, 9, 9,10,10,12,12,10, + 10,10,11,11,12,12,13,13,10,10,10,11,11,12,12,13, + 13, +}; + +static float _vq_quantthresh__44u2__p5_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44u2__p5_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44u2__p5_0 = { + _vq_quantthresh__44u2__p5_0, + _vq_quantmap__44u2__p5_0, + 9, + 9 +}; + +static static_codebook _44u2__p5_0 = { + 2, 81, + _vq_lengthlist__44u2__p5_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44u2__p5_0, + NULL, + &_vq_auxt__44u2__p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u2__p6_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44u2__p6_0[] = { + 1, 4, 4, 6, 6, 8, 8,10,10,11,11,14,13, 4, 6, 5, + 8, 8, 9, 9,11,10,12,11,15,14, 4, 5, 6, 8, 8, 9, + 9,11,11,11,11,14,14, 6, 8, 8,10, 9,11,11,11,11, + 12,12,15,15, 6, 8, 8, 9, 9,11,11,11,12,12,12,15, + 15, 8,10,10,11,11,11,11,12,12,13,13,15,16, 8,10, + 10,11,11,11,11,12,12,13,13,16,16,10,11,11,12,12, + 12,12,13,13,13,13,17,16,10,11,11,12,12,12,12,13, + 13,13,14,16,17,11,12,12,13,13,13,13,14,14,15,14, + 18,17,11,12,12,13,13,13,13,14,14,14,15,19,18,14, + 15,15,15,15,16,16,18,19,18,18, 0, 0,14,15,15,16, + 15,17,17,16,18,17,18, 0, 0, +}; + +static float _vq_quantthresh__44u2__p6_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__44u2__p6_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44u2__p6_0 = { + _vq_quantthresh__44u2__p6_0, + _vq_quantmap__44u2__p6_0, + 13, + 13 +}; + +static static_codebook _44u2__p6_0 = { + 2, 169, + _vq_lengthlist__44u2__p6_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__44u2__p6_0, + NULL, + &_vq_auxt__44u2__p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u2__p6_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44u2__p6_1[] = { + 2, 4, 4, 5, 5, 4, 5, 5, 6, 5, 4, 5, 5, 5, 6, 5, + 6, 5, 6, 6, 5, 5, 6, 6, 6, +}; + +static float _vq_quantthresh__44u2__p6_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44u2__p6_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44u2__p6_1 = { + _vq_quantthresh__44u2__p6_1, + _vq_quantmap__44u2__p6_1, + 5, + 5 +}; + +static static_codebook _44u2__p6_1 = { + 2, 25, + _vq_lengthlist__44u2__p6_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44u2__p6_1, + NULL, + &_vq_auxt__44u2__p6_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u2__p7_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44u2__p7_0[] = { + 1, 3, 2,12,12,12,12,12,12, 4,12,12,12,12,12,12, + 12,12, 5,12,12,12,12,12,12,12,12,12,12,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11, +}; + +static float _vq_quantthresh__44u2__p7_0[] = { + -591.5, -422.5, -253.5, -84.5, 84.5, 253.5, 422.5, 591.5, +}; + +static long _vq_quantmap__44u2__p7_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44u2__p7_0 = { + _vq_quantthresh__44u2__p7_0, + _vq_quantmap__44u2__p7_0, + 9, + 9 +}; + +static static_codebook _44u2__p7_0 = { + 2, 81, + _vq_lengthlist__44u2__p7_0, + 1, -516612096, 1626677248, 4, 0, + _vq_quantlist__44u2__p7_0, + NULL, + &_vq_auxt__44u2__p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u2__p7_1[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44u2__p7_1[] = { + 1, 4, 4, 7, 6, 7, 6, 8, 7, 9, 7, 9, 8, 4, 7, 6, + 8, 8, 9, 8,10, 9,10,10,11,11, 4, 7, 7, 8, 8, 8, + 8, 9,10,11,11,11,11, 6, 8, 8,10,10,10,10,11,11, + 12,12,12,12, 7, 8, 8,10,10,10,10,11,11,12,12,13, + 13, 7, 9, 9,11,10,12,12,13,13,14,13,14,14, 7, 9, + 9,10,11,11,12,13,13,13,13,16,14, 9,10,10,12,12, + 13,13,14,14,15,16,15,16, 9,10,10,12,12,12,13,14, + 14,14,15,16,15,10,12,12,13,13,15,13,16,16,15,17, + 17,17,10,11,11,12,14,14,14,15,15,17,17,15,17,11, + 12,12,14,14,14,15,15,15,17,16,17,17,10,12,12,13, + 14,14,14,17,15,17,17,17,17, +}; + +static float _vq_quantthresh__44u2__p7_1[] = { + -71.5, -58.5, -45.5, -32.5, -19.5, -6.5, 6.5, 19.5, + 32.5, 45.5, 58.5, 71.5, +}; + +static long _vq_quantmap__44u2__p7_1[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44u2__p7_1 = { + _vq_quantthresh__44u2__p7_1, + _vq_quantmap__44u2__p7_1, + 13, + 13 +}; + +static static_codebook _44u2__p7_1 = { + 2, 169, + _vq_lengthlist__44u2__p7_1, + 1, -523010048, 1618608128, 4, 0, + _vq_quantlist__44u2__p7_1, + NULL, + &_vq_auxt__44u2__p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u2__p7_2[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44u2__p7_2[] = { + 2, 5, 5, 6, 6, 7, 7, 8, 7, 8, 8, 8, 8, 5, 6, 6, + 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 5, 6, 6, 7, 7, 8, + 7, 8, 8, 8, 8, 8, 8, 6, 7, 7, 7, 8, 8, 8, 8, 8, + 9, 9, 9, 9, 6, 7, 7, 8, 7, 8, 8, 9, 9, 9, 9, 9, + 9, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 7, 8, + 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, +}; + +static float _vq_quantthresh__44u2__p7_2[] = { + -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, + 2.5, 3.5, 4.5, 5.5, +}; + +static long _vq_quantmap__44u2__p7_2[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44u2__p7_2 = { + _vq_quantthresh__44u2__p7_2, + _vq_quantmap__44u2__p7_2, + 13, + 13 +}; + +static static_codebook _44u2__p7_2 = { + 2, 169, + _vq_lengthlist__44u2__p7_2, + 1, -531103744, 1611661312, 4, 0, + _vq_quantlist__44u2__p7_2, + NULL, + &_vq_auxt__44u2__p7_2, + NULL, + 0 +}; + +static long _huff_lengthlist__44u2__short[] = { + 13,15,17,17,15,15,12,17,11, 9, 7,10,10, 9,12,17, + 10, 6, 3, 6, 5, 7,10,17,15,10, 6, 9, 8, 9,11,17, + 15, 8, 4, 7, 3, 5, 9,16,16,10, 5, 8, 4, 5, 8,16, + 13,11, 5, 8, 3, 3, 5,14,13,12, 7,10, 5, 5, 7,14, +}; + +static static_codebook _huff_book__44u2__short = { + 2, 64, + _huff_lengthlist__44u2__short, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__44u3__long[] = { + 6, 9,13,12,14,11,10,13, 8, 4, 5, 7, 8, 7, 8,12, + 11, 4, 3, 5, 5, 7, 9,14,11, 6, 5, 6, 6, 6, 7,13, + 13, 7, 5, 6, 4, 5, 7,14,11, 7, 6, 6, 5, 5, 6,13, + 9, 7, 8, 6, 7, 5, 3, 9, 9,12,13,12,14,10, 6, 7, +}; + +static static_codebook _huff_book__44u3__long = { + 2, 64, + _huff_lengthlist__44u3__long, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__44u3__p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44u3__p1_0[] = { + 1, 4, 4, 5, 8, 7, 5, 7, 8, 5, 8, 8, 8,10,11, 8, + 10,11, 5, 8, 8, 8,11,10, 8,11,11, 4, 8, 8, 8,11, + 11, 8,11,11, 8,11,11,11,13,14,11,14,14, 8,11,11, + 10,14,12,11,14,14, 4, 8, 8, 8,11,11, 8,11,11, 7, + 11,11,11,14,14,10,12,14, 8,11,11,11,14,14,11,14, + 13, +}; + +static float _vq_quantthresh__44u3__p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44u3__p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44u3__p1_0 = { + _vq_quantthresh__44u3__p1_0, + _vq_quantmap__44u3__p1_0, + 3, + 3 +}; + +static static_codebook _44u3__p1_0 = { + 4, 81, + _vq_lengthlist__44u3__p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44u3__p1_0, + NULL, + &_vq_auxt__44u3__p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u3__p2_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44u3__p2_0[] = { + 2, 5, 4, 5, 6, 6, 5, 6, 6, 5, 6, 6, 7, 8, 8, 6, + 8, 8, 5, 6, 6, 6, 8, 8, 7, 8, 8, 5, 7, 6, 7, 8, + 8, 6, 8, 8, 7, 8, 8, 8, 9,10, 8,10,10, 6, 8, 8, + 8,10, 8, 8,10,10, 5, 6, 6, 6, 8, 8, 7, 8, 8, 6, + 8, 8, 8,10,10, 8, 8,10, 7, 8, 8, 8,10,10, 8,10, + 9, +}; + +static float _vq_quantthresh__44u3__p2_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44u3__p2_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44u3__p2_0 = { + _vq_quantthresh__44u3__p2_0, + _vq_quantmap__44u3__p2_0, + 3, + 3 +}; + +static static_codebook _44u3__p2_0 = { + 4, 81, + _vq_lengthlist__44u3__p2_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44u3__p2_0, + NULL, + &_vq_auxt__44u3__p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u3__p3_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44u3__p3_0[] = { + 2, 4, 4, 7, 7, 5, 7, 7, 9, 9, 5, 7, 7, 9, 9, 8, + 9, 9,12,12, 8, 9, 9,11,12, 5, 7, 7,10,10, 7, 9, + 9,11,11, 7, 9, 9,10,11,10,11,11,13,13, 9,10,11, + 13,13, 5, 7, 7,10,10, 7, 9, 9,11,10, 7, 9, 9,11, + 11, 9,11,10,13,13,10,11,11,14,13, 8,10,10,14,13, + 10,11,11,15,14, 9,11,11,14,14,13,14,13,16,16,12, + 13,13,15,15, 8,10,10,13,14, 9,11,11,14,14,10,11, + 11,14,15,12,13,13,15,15,13,14,14,15,16, 5, 7, 7, + 10,10, 7, 9, 9,11,11, 7, 9, 9,11,12,10,11,11,14, + 14,10,11,11,14,14, 7, 9, 9,12,12, 9,11,11,13,13, + 9,11,11,13,13,12,12,13,15,15,11,12,13,15,16, 7, + 9, 9,11,11, 8,11,10,13,12, 9,11,11,13,13,11,13, + 12,15,13,11,13,13,15,16, 9,12,11,15,14,11,12,13, + 16,15,11,13,13,15,16,14,14,15,17,16,13,15,16, 0, + 17, 9,11,11,15,15,10,13,12,15,15,11,13,13,15,16, + 13,15,13,16,15,14,16,15, 0,19, 5, 7, 7,10,10, 7, + 9, 9,11,11, 7, 9, 9,11,11,10,12,11,14,14,10,11, + 12,14,14, 7, 9, 9,12,12, 9,11,11,14,13, 9,10,11, + 12,13,11,13,13,16,16,11,12,13,13,16, 7, 9, 9,12, + 12, 9,11,11,13,13, 9,11,11,13,13,11,13,13,15,15, + 12,13,12,15,14, 9,11,11,15,14,11,13,12,16,16,10, + 12,12,15,15,13,15,15,17,19,13,14,15,16,17,10,12, + 12,15,15,11,13,13,16,16,11,13,13,15,16,13,15,15, + 0, 0,14,15,15,16,16, 8,10,10,14,14,10,12,12,15, + 15,10,12,11,15,16,14,15,15,19,20,13,14,14,18,16, + 9,11,11,15,15,11,13,13,17,16,11,13,13,16,16,15, + 17,17,20,20,14,15,16,17,20, 9,11,11,15,15,10,13, + 12,16,15,11,13,13,15,17,14,16,15,18, 0,14,16,15, + 18,20,12,14,14, 0, 0,14,14,16, 0, 0,13,16,15, 0, + 0,17,17,18, 0, 0,16,17,19,19, 0,12,14,14,18, 0, + 12,16,14, 0,17,13,15,15,18, 0,16,18,17, 0,17,16, + 18,17, 0, 0, 7,10,10,14,14,10,12,11,15,15,10,12, + 12,16,15,13,15,15,18, 0,14,15,15,17, 0, 9,11,11, + 15,15,11,13,13,16,16,11,12,13,16,16,14,15,16,17, + 17,14,16,16,16,18, 9,11,12,16,16,11,13,13,17,17, + 11,14,13,20,17,15,16,16,19, 0,15,16,17, 0,19,11, + 13,14,17,16,14,15,15,20,18,13,14,15,17,19,16,18, + 18, 0,20,16,16,19,17, 0,12,15,14,17, 0,14,15,15, + 18,19,13,16,15,19,20,15,18,18, 0,20,17, 0,16, 0, + 0, +}; + +static float _vq_quantthresh__44u3__p3_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44u3__p3_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44u3__p3_0 = { + _vq_quantthresh__44u3__p3_0, + _vq_quantmap__44u3__p3_0, + 5, + 5 +}; + +static static_codebook _44u3__p3_0 = { + 4, 625, + _vq_lengthlist__44u3__p3_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44u3__p3_0, + NULL, + &_vq_auxt__44u3__p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u3__p4_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44u3__p4_0[] = { + 4, 5, 5, 8, 8, 5, 7, 6, 9, 9, 5, 6, 7, 9, 9, 9, + 9, 9,11,11, 9, 9, 9,11,11, 5, 7, 7, 9, 9, 7, 8, + 8,10,10, 7, 7, 8,10,10, 9,10,10,11,12, 9,10,10, + 11,12, 5, 7, 7, 9, 9, 7, 8, 7,10,10, 7, 8, 8,10, + 10, 9,10, 9,12,11, 9,10,10,12,11, 9,10, 9,12,12, + 9,10,10,13,12, 9,10,10,12,13,12,12,12,14,14,11, + 12,12,13,14, 9, 9,10,12,12, 9,10,10,12,12, 9,10, + 10,12,13,11,12,11,14,13,12,12,12,14,13, 5, 7, 7, + 9, 9, 7, 8, 8,10,10, 7, 8, 8,10,10,10,10,10,12, + 12, 9,10,10,12,12, 7, 8, 8,11,10, 8, 8, 9,11,11, + 8, 9, 9,11,11,11,11,11,12,13,10,11,11,13,13, 6, + 8, 8,10,10, 7, 9, 8,11,10, 8, 9, 9,11,11,10,11, + 10,13,11,10,11,11,13,13, 9,11,10,13,12,10,11,11, + 13,13,10,11,11,13,13,12,12,13,12,15,12,13,13,15, + 15, 9,10,10,12,13,10,11,10,13,12,10,11,11,13,14, + 12,13,11,15,13,12,13,13,15,15, 5, 7, 7, 9, 9, 7, + 8, 8,10,10, 7, 8, 8,10,10, 9,10,10,12,12,10,10, + 11,12,12, 6, 8, 8,10,10, 8, 9, 9,11,11, 7, 8, 9, + 10,11,10,11,11,13,13,10,10,11,11,13, 7, 8, 8,10, + 10, 8, 9, 9,11,11, 8, 9, 9,11,11,10,11,11,13,13, + 11,11,11,13,12, 9,10,10,13,12,10,11,11,14,13,10, + 10,11,12,13,12,13,13,15,15,12,11,13,13,14, 9,10, + 11,12,13,10,11,11,13,13,10,11,11,13,13,12,13,13, + 15,15,12,13,12,15,12, 8, 9, 9,12,12, 9,11,10,13, + 13, 9,10,10,13,13,12,13,13,15,14,12,12,12,14,13, + 9,10,10,13,12,10,11,11,13,13,10,11,11,14,12,13, + 13,14,14,16,12,13,13,15,15, 9,10,10,13,13,10,11, + 10,14,13,10,11,11,13,14,12,14,13,15,14,13,13,13, + 15,15,11,13,12,15,14,11,12,13,14,15,12,13,13,16, + 14,14,12,15,12,16,14,15,15,17,15,11,12,12,14,14, + 11,13,11,15,14,12,13,13,15,15,13,15,12,17,13,14, + 15,15,16,16, 8, 9, 9,12,12, 9,10,10,12,13, 9,10, + 10,13,13,12,12,12,14,14,12,13,13,15,15, 9,10,10, + 13,12,10,11,11,14,13,10,10,11,13,14,12,13,13,15, + 15,12,12,13,14,16, 9,10,10,13,13,10,11,11,13,14, + 10,11,11,14,13,12,13,13,14,15,13,14,13,16,14,11, + 12,12,14,14,12,13,13,15,14,11,12,13,14,15,14,15, + 15,16,16,13,13,15,13,16,11,12,12,14,15,12,13,13, + 14,15,11,13,12,15,14,14,15,15,16,16,14,15,12,16, + 13, +}; + +static float _vq_quantthresh__44u3__p4_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44u3__p4_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44u3__p4_0 = { + _vq_quantthresh__44u3__p4_0, + _vq_quantmap__44u3__p4_0, + 5, + 5 +}; + +static static_codebook _44u3__p4_0 = { + 4, 625, + _vq_lengthlist__44u3__p4_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44u3__p4_0, + NULL, + &_vq_auxt__44u3__p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u3__p5_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44u3__p5_0[] = { + 2, 3, 3, 6, 6, 7, 7, 9, 9, 4, 5, 5, 7, 7, 8, 8, + 10,10, 4, 5, 5, 7, 7, 8, 8,10,10, 6, 7, 7, 8, 8, + 9, 9,11,10, 6, 7, 7, 8, 8, 9, 9,10,10, 7, 8, 8, + 9, 9,10,10,11,11, 7, 8, 8, 9, 9,10,10,11,11, 9, + 10,10,11,10,11,11,12,12, 9,10,10,10,10,11,11,12, + 12, +}; + +static float _vq_quantthresh__44u3__p5_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44u3__p5_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44u3__p5_0 = { + _vq_quantthresh__44u3__p5_0, + _vq_quantmap__44u3__p5_0, + 9, + 9 +}; + +static static_codebook _44u3__p5_0 = { + 2, 81, + _vq_lengthlist__44u3__p5_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44u3__p5_0, + NULL, + &_vq_auxt__44u3__p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u3__p6_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44u3__p6_0[] = { + 1, 4, 4, 6, 6, 8, 8, 9, 9,10,11,13,14, 4, 6, 5, + 8, 8, 9, 9,10,10,11,11,14,14, 4, 6, 6, 8, 8, 9, + 9,10,10,11,11,14,14, 6, 8, 8, 9, 9,10,10,11,11, + 12,12,15,15, 6, 8, 8, 9, 9,10,11,11,11,12,12,15, + 15, 8, 9, 9,11,10,11,11,12,12,13,13,15,16, 8, 9, + 9,10,11,11,11,12,12,13,13,16,16,10,10,11,11,11, + 12,12,13,13,13,14,17,16, 9,10,11,12,11,12,12,13, + 13,13,13,16,18,11,12,11,12,12,13,13,13,14,15,14, + 17,17,11,11,12,12,12,13,13,13,14,14,15,18,17,14, + 15,15,15,15,16,16,17,17,19,18, 0,20,14,15,14,15, + 15,16,16,16,17,18,16,20,18, +}; + +static float _vq_quantthresh__44u3__p6_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__44u3__p6_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44u3__p6_0 = { + _vq_quantthresh__44u3__p6_0, + _vq_quantmap__44u3__p6_0, + 13, + 13 +}; + +static static_codebook _44u3__p6_0 = { + 2, 169, + _vq_lengthlist__44u3__p6_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__44u3__p6_0, + NULL, + &_vq_auxt__44u3__p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u3__p6_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44u3__p6_1[] = { + 2, 4, 4, 5, 5, 4, 5, 5, 6, 5, 4, 5, 5, 5, 6, 5, + 6, 5, 6, 6, 5, 5, 6, 6, 6, +}; + +static float _vq_quantthresh__44u3__p6_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44u3__p6_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44u3__p6_1 = { + _vq_quantthresh__44u3__p6_1, + _vq_quantmap__44u3__p6_1, + 5, + 5 +}; + +static static_codebook _44u3__p6_1 = { + 2, 25, + _vq_lengthlist__44u3__p6_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44u3__p6_1, + NULL, + &_vq_auxt__44u3__p6_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u3__p7_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44u3__p7_0[] = { + 1, 3, 3,10,10,10,10,10,10, 4,10,10,10,10,10,10, + 10,10, 4,10,10,10,10,10,10,10,10,10,10, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, +}; + +static float _vq_quantthresh__44u3__p7_0[] = { + -892.5, -637.5, -382.5, -127.5, 127.5, 382.5, 637.5, 892.5, +}; + +static long _vq_quantmap__44u3__p7_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44u3__p7_0 = { + _vq_quantthresh__44u3__p7_0, + _vq_quantmap__44u3__p7_0, + 9, + 9 +}; + +static static_codebook _44u3__p7_0 = { + 2, 81, + _vq_lengthlist__44u3__p7_0, + 1, -515907584, 1627381760, 4, 0, + _vq_quantlist__44u3__p7_0, + NULL, + &_vq_auxt__44u3__p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u3__p7_1[] = { + 7, + 6, + 8, + 5, + 9, + 4, + 10, + 3, + 11, + 2, + 12, + 1, + 13, + 0, + 14, +}; + +static long _vq_lengthlist__44u3__p7_1[] = { + 1, 4, 4, 6, 6, 7, 6, 8, 7, 9, 8,10, 9,11,11, 4, + 7, 7, 8, 7, 9, 9,10,10,11,11,11,11,12,12, 4, 7, + 7, 7, 7, 9, 9,10,10,11,11,12,12,12,11, 6, 8, 8, + 9, 9,10,10,11,11,12,12,13,12,13,13, 6, 8, 8, 9, + 9,10,11,11,11,12,12,13,14,13,13, 8, 9, 9,11,11, + 12,12,12,13,14,13,14,14,14,15, 8, 9, 9,11,11,11, + 12,13,14,13,14,15,17,14,15, 9,10,10,12,12,13,13, + 13,14,15,15,15,16,16,16, 9,11,11,12,12,13,13,14, + 14,14,15,16,16,16,16,10,12,12,13,13,14,14,15,15, + 15,16,17,17,17,17,10,12,11,13,13,15,14,15,14,16, + 17,16,16,16,16,11,13,12,14,14,14,14,15,16,17,16, + 17,17,17,17,11,13,12,14,14,14,15,17,16,17,17,17, + 17,17,17,12,13,13,15,16,15,16,17,17,16,16,17,17, + 17,17,12,13,13,15,15,15,16,17,17,17,16,17,16,17, + 17, +}; + +static float _vq_quantthresh__44u3__p7_1[] = { + -110.5, -93.5, -76.5, -59.5, -42.5, -25.5, -8.5, 8.5, + 25.5, 42.5, 59.5, 76.5, 93.5, 110.5, +}; + +static long _vq_quantmap__44u3__p7_1[] = { + 13, 11, 9, 7, 5, 3, 1, 0, + 2, 4, 6, 8, 10, 12, 14, +}; + +static encode_aux_threshmatch _vq_auxt__44u3__p7_1 = { + _vq_quantthresh__44u3__p7_1, + _vq_quantmap__44u3__p7_1, + 15, + 15 +}; + +static static_codebook _44u3__p7_1 = { + 2, 225, + _vq_lengthlist__44u3__p7_1, + 1, -522338304, 1620115456, 4, 0, + _vq_quantlist__44u3__p7_1, + NULL, + &_vq_auxt__44u3__p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u3__p7_2[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44u3__p7_2[] = { + 2, 5, 5, 7, 6, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, + 9, 5, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, + 10,10, 5, 6, 6, 7, 7, 8, 8, 8, 8, 9, 8, 9, 9, 9, + 9,10, 9, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, + 10,10,10,10, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9,10, + 9,10,10,10,10, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, + 10,10,10,10,10,10, 7, 8, 8, 9, 8, 9, 9, 9, 9,10, + 9,10,10,10,10,10,10, 8, 8, 8, 9, 9, 9, 9, 9, 9, + 9,10,10,10,10,10,10,10, 8, 9, 8, 9, 9, 9, 9,10, + 9,10,10,10,10,10,10,10,10, 9, 9, 9, 9, 9, 9,10, + 9,10,10,10,10,10,10,10,10,10, 9, 9, 9, 9, 9,10, + 9,10,10,10,10,10,10,10,10,10,10, 9, 9, 9,10, 9, + 10,10,10,10,10,10,10,10,10,10,10,10, 9, 9, 9,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10, 9, 9, 9, + 10,10,10,10,10,10,10,10,10,10,10,10,10,11, 9,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,11, 9, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 9,10,10,10,10,10,10,10,10,10,10,10,11,11,11,10, + 11, +}; + +static float _vq_quantthresh__44u3__p7_2[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__44u3__p7_2[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44u3__p7_2 = { + _vq_quantthresh__44u3__p7_2, + _vq_quantmap__44u3__p7_2, + 17, + 17 +}; + +static static_codebook _44u3__p7_2 = { + 2, 289, + _vq_lengthlist__44u3__p7_2, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__44u3__p7_2, + NULL, + &_vq_auxt__44u3__p7_2, + NULL, + 0 +}; + +static long _huff_lengthlist__44u3__short[] = { + 14,14,14,15,13,15,12,16,10, 8, 7, 9, 9, 8,12,16, + 10, 5, 4, 6, 5, 6, 9,16,14, 8, 6, 8, 7, 8,10,16, + 14, 7, 4, 6, 3, 5, 8,16,15, 9, 5, 7, 4, 4, 7,16, + 13,10, 6, 7, 4, 3, 4,13,13,12, 7, 9, 5, 5, 6,12, +}; + +static static_codebook _huff_book__44u3__short = { + 2, 64, + _huff_lengthlist__44u3__short, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__44u4__long[] = { + 3, 8,12,12,13,12,11,13, 5, 4, 6, 7, 8, 8, 9,13, + 9, 5, 4, 5, 5, 7, 9,13, 9, 6, 5, 6, 6, 7, 8,12, + 12, 7, 5, 6, 4, 5, 8,13,11, 7, 6, 6, 5, 5, 6,12, + 10, 8, 8, 7, 7, 5, 3, 8,10,12,13,12,12, 9, 6, 7, +}; + +static static_codebook _huff_book__44u4__long = { + 2, 64, + _huff_lengthlist__44u4__long, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__44u4__p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44u4__p1_0[] = { + 1, 4, 4, 5, 8, 7, 5, 7, 8, 5, 8, 8, 8,10,11, 8, + 10,11, 5, 8, 8, 8,11,10, 8,11,11, 4, 8, 8, 8,11, + 11, 8,11,11, 8,11,11,11,13,14,11,15,14, 8,11,11, + 10,13,12,11,14,14, 4, 8, 8, 8,11,11, 8,11,11, 7, + 11,11,11,15,14,10,12,14, 8,11,11,11,14,14,11,14, + 13, +}; + +static float _vq_quantthresh__44u4__p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44u4__p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44u4__p1_0 = { + _vq_quantthresh__44u4__p1_0, + _vq_quantmap__44u4__p1_0, + 3, + 3 +}; + +static static_codebook _44u4__p1_0 = { + 4, 81, + _vq_lengthlist__44u4__p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44u4__p1_0, + NULL, + &_vq_auxt__44u4__p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u4__p2_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44u4__p2_0[] = { + 2, 5, 5, 5, 6, 6, 5, 6, 6, 5, 6, 6, 7, 8, 8, 6, + 8, 8, 5, 6, 6, 6, 8, 8, 7, 8, 8, 5, 7, 6, 6, 8, + 8, 6, 8, 8, 6, 8, 8, 8, 9,10, 8,10,10, 6, 8, 8, + 8,10, 8, 8,10,10, 5, 6, 6, 6, 8, 8, 6, 8, 8, 6, + 8, 8, 8,10,10, 8, 8,10, 6, 8, 8, 8,10,10, 8,10, + 9, +}; + +static float _vq_quantthresh__44u4__p2_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44u4__p2_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44u4__p2_0 = { + _vq_quantthresh__44u4__p2_0, + _vq_quantmap__44u4__p2_0, + 3, + 3 +}; + +static static_codebook _44u4__p2_0 = { + 4, 81, + _vq_lengthlist__44u4__p2_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44u4__p2_0, + NULL, + &_vq_auxt__44u4__p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u4__p3_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44u4__p3_0[] = { + 2, 4, 4, 8, 8, 5, 7, 7, 9, 9, 5, 7, 7, 9, 9, 8, + 10, 9,12,12, 8, 9,10,12,12, 5, 7, 7,10,10, 7, 9, + 9,11,11, 7, 9, 9,11,11,10,12,11,14,14, 9,10,11, + 13,14, 5, 7, 7,10,10, 7, 9, 9,11,11, 7, 9, 9,11, + 11, 9,11,10,14,13,10,11,11,14,14, 8,10,10,14,13, + 10,12,12,15,14, 9,11,11,15,14,13,14,14,17,17,12, + 14,14,16,16, 8,10,10,14,14, 9,11,11,14,15,10,12, + 12,14,15,12,14,13,16,16,13,14,15,15,18, 4, 7, 7, + 10,10, 7, 9, 9,12,11, 7, 9, 9,11,12,10,12,11,15, + 14,10,11,12,14,15, 7, 9, 9,12,12, 9,11,12,13,13, + 9,11,12,13,13,12,13,13,15,16,11,13,13,15,16, 7, + 9, 9,12,12, 9,11,10,13,12, 9,11,12,13,14,11,13, + 12,16,14,12,13,13,15,16,10,12,12,16,15,11,13,13, + 17,16,11,13,13,17,16,14,15,15,17,17,14,16,16,18, + 20, 9,11,11,15,16,11,13,12,16,16,11,13,13,16,17, + 14,15,14,18,16,14,16,16,17,20, 5, 7, 7,10,10, 7, + 9, 9,12,11, 7, 9,10,11,12,10,12,11,15,15,10,12, + 12,14,14, 7, 9, 9,12,12, 9,12,11,14,13, 9,10,11, + 12,13,12,13,14,16,16,11,12,13,14,16, 7, 9, 9,12, + 12, 9,12,11,13,13, 9,12,11,13,13,11,13,13,16,16, + 12,13,13,16,15, 9,11,11,16,14,11,13,13,16,16,11, + 12,13,16,16,14,16,16,17,17,13,14,15,16,17,10,12, + 12,15,15,11,13,13,16,17,11,13,13,16,16,14,16,15, + 19,19,14,15,15,17,18, 8,10,10,14,14,10,12,12,15, + 15,10,12,12,16,16,14,16,15,20,19,13,15,15,17,16, + 9,12,12,16,16,11,13,13,16,18,11,14,13,16,17,16, + 17,16,20, 0,15,16,18,18,20, 9,11,11,15,15,11,14, + 12,17,16,11,13,13,17,17,15,17,15,20,20,14,16,16, + 17, 0,13,15,14,18,16,14,15,16, 0,18,14,16,16, 0, + 0,18,16, 0, 0,20,16,18,18, 0, 0,12,14,14,17,18, + 13,15,14,20,18,14,16,15,19,19,16,20,16, 0,18,16, + 19,17,19, 0, 8,10,10,14,14,10,12,12,16,15,10,12, + 12,16,16,13,15,15,18,17,14,16,16,19, 0, 9,11,11, + 16,15,11,14,13,18,17,11,12,13,17,18,14,17,16,18, + 18,15,16,17,18,18, 9,12,12,16,16,11,13,13,16,18, + 11,14,13,17,17,15,16,16,18,20,16,17,17,20,20,12, + 14,14,18,17,14,16,16, 0,19,13,14,15,18, 0,16, 0, + 0, 0, 0,16,16, 0,19,20,13,15,14, 0, 0,14,16,16, + 18,19,14,16,15, 0,20,16,20,18, 0,20,17,20,17, 0, + 0, +}; + +static float _vq_quantthresh__44u4__p3_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44u4__p3_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44u4__p3_0 = { + _vq_quantthresh__44u4__p3_0, + _vq_quantmap__44u4__p3_0, + 5, + 5 +}; + +static static_codebook _44u4__p3_0 = { + 4, 625, + _vq_lengthlist__44u4__p3_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44u4__p3_0, + NULL, + &_vq_auxt__44u4__p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u4__p4_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44u4__p4_0[] = { + 4, 5, 5, 8, 8, 5, 7, 6, 9, 9, 5, 6, 7, 9, 9, 9, + 9, 9,11,11, 8, 9, 9,11,11, 5, 7, 7, 9, 9, 7, 8, + 8,10,10, 7, 7, 8,10,10, 9,10,10,11,12, 9,10,10, + 11,12, 5, 7, 7, 9, 9, 7, 8, 7,10,10, 7, 8, 8,10, + 10, 9,10,10,12,11, 9,10,10,12,11, 9,10, 9,12,12, + 9,10,10,13,12, 9,10,10,12,12,12,12,12,14,14,11, + 12,12,13,14, 9, 9,10,12,12, 9,10,10,13,13, 9,10, + 10,12,13,11,12,12,14,13,11,12,12,14,14, 5, 7, 7, + 9, 9, 7, 8, 8,10,10, 7, 8, 8,10,10,10,10,10,12, + 12, 9,10,10,12,12, 7, 8, 8,11,10, 8, 8, 9,11,11, + 8, 9, 9,11,11,11,11,11,12,13,10,11,11,13,13, 6, + 8, 8,10,10, 7, 9, 8,11,10, 8, 9, 9,11,11,10,11, + 10,13,11,10,11,11,13,13, 9,11,10,13,12,10,11,11, + 13,14,10,11,11,14,13,12,12,13,12,15,12,13,13,15, + 15, 9,10,10,12,13,10,11,10,13,12,10,11,11,13,14, + 12,13,11,15,13,13,13,13,15,15, 5, 7, 7, 9, 9, 7, + 8, 8,10,10, 7, 8, 8,10,10, 9,10,10,12,12,10,10, + 11,12,13, 6, 8, 8,10,10, 8, 9, 9,11,11, 7, 8, 9, + 10,11,10,11,11,13,13,10,10,11,11,13, 7, 8, 8,10, + 11, 8, 9, 9,11,11, 8, 9, 8,11,11,10,11,11,13,13, + 11,12,11,13,12, 9,10,10,13,12,10,11,11,14,13,10, + 10,11,12,13,12,13,13,15,15,12,11,13,13,14, 9,10, + 11,12,13,10,11,11,13,14,10,11,11,13,13,12,13,13, + 15,15,12,13,12,15,12, 8, 9, 9,12,12, 9,11,10,13, + 13, 9,10,10,13,13,12,13,13,15,15,12,12,12,14,14, + 9,10,10,13,13,10,11,11,13,14,10,11,11,14,13,13, + 13,14,14,16,13,13,13,15,15, 9,10,10,13,13,10,11, + 10,14,13,10,11,11,13,14,12,14,13,16,14,12,13,13, + 14,15,11,12,12,15,14,11,12,13,14,15,12,13,13,16, + 15,14,12,15,12,16,14,15,15,16,16,11,12,12,14,14, + 11,13,12,15,14,12,13,13,15,16,13,15,13,17,13,14, + 15,15,16,17, 8, 9, 9,12,12, 9,10,10,12,13, 9,10, + 10,13,13,12,12,12,14,14,12,13,13,15,15, 9,10,10, + 13,12,10,11,11,14,13,10,10,11,13,14,13,13,13,15, + 15,12,13,14,14,16, 9,10,10,13,13,10,11,11,13,14, + 10,11,11,14,14,13,13,13,15,15,13,14,13,16,14,11, + 12,12,15,14,12,13,13,16,15,11,12,13,14,15,14,15, + 15,17,16,13,13,15,13,16,11,12,13,14,15,13,13,13, + 15,16,11,13,12,15,14,14,15,15,16,16,14,15,12,17, + 13, +}; + +static float _vq_quantthresh__44u4__p4_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44u4__p4_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44u4__p4_0 = { + _vq_quantthresh__44u4__p4_0, + _vq_quantmap__44u4__p4_0, + 5, + 5 +}; + +static static_codebook _44u4__p4_0 = { + 4, 625, + _vq_lengthlist__44u4__p4_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44u4__p4_0, + NULL, + &_vq_auxt__44u4__p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u4__p5_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44u4__p5_0[] = { + 2, 3, 3, 6, 6, 7, 7, 9, 9, 4, 5, 5, 7, 7, 8, 8, + 10, 9, 4, 5, 5, 7, 7, 8, 8,10,10, 6, 7, 7, 8, 8, + 9, 9,11,10, 6, 7, 7, 8, 8, 9, 9,10,11, 7, 8, 8, + 9, 9,10,10,11,11, 7, 8, 8, 9, 9,10,10,11,11, 9, + 10,10,11,10,11,11,12,12, 9,10,10,10,11,11,11,12, + 12, +}; + +static float _vq_quantthresh__44u4__p5_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44u4__p5_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44u4__p5_0 = { + _vq_quantthresh__44u4__p5_0, + _vq_quantmap__44u4__p5_0, + 9, + 9 +}; + +static static_codebook _44u4__p5_0 = { + 2, 81, + _vq_lengthlist__44u4__p5_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44u4__p5_0, + NULL, + &_vq_auxt__44u4__p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u4__p6_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44u4__p6_0[] = { + 1, 4, 4, 6, 6, 8, 8, 9, 9,11,10,13,13, 4, 6, 5, + 8, 8, 9, 9,10,10,11,11,14,14, 4, 6, 6, 8, 8, 9, + 9,10,10,11,11,14,14, 6, 8, 8, 9, 9,10,10,11,11, + 12,12,15,15, 6, 8, 8, 9, 9,10,11,11,11,12,12,15, + 15, 8, 9, 9,11,10,11,11,12,12,13,13,16,16, 8, 9, + 9,10,10,11,11,12,12,13,13,16,16,10,10,10,12,11, + 12,12,13,13,14,14,16,16,10,10,10,11,12,12,12,13, + 13,13,14,16,17,11,12,11,12,12,13,13,14,14,15,14, + 18,17,11,11,12,12,12,13,13,14,14,14,15,19,18,14, + 15,14,15,15,17,16,17,17,17,17,21, 0,14,15,15,16, + 16,16,16,17,17,18,17,20,21, +}; + +static float _vq_quantthresh__44u4__p6_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__44u4__p6_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44u4__p6_0 = { + _vq_quantthresh__44u4__p6_0, + _vq_quantmap__44u4__p6_0, + 13, + 13 +}; + +static static_codebook _44u4__p6_0 = { + 2, 169, + _vq_lengthlist__44u4__p6_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__44u4__p6_0, + NULL, + &_vq_auxt__44u4__p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u4__p6_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44u4__p6_1[] = { + 2, 4, 4, 5, 5, 4, 5, 5, 6, 5, 4, 5, 5, 5, 6, 5, + 6, 5, 6, 6, 5, 5, 6, 6, 6, +}; + +static float _vq_quantthresh__44u4__p6_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44u4__p6_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44u4__p6_1 = { + _vq_quantthresh__44u4__p6_1, + _vq_quantmap__44u4__p6_1, + 5, + 5 +}; + +static static_codebook _44u4__p6_1 = { + 2, 25, + _vq_lengthlist__44u4__p6_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44u4__p6_1, + NULL, + &_vq_auxt__44u4__p6_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u4__p7_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44u4__p7_0[] = { + 1, 3, 3,12,12,12,12,12,12,12,12,12,12, 3,12,11, + 12,12,12,12,12,12,12,12,12,12, 4,11,10,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11, +}; + +static float _vq_quantthresh__44u4__p7_0[] = { + -1402.5, -1147.5, -892.5, -637.5, -382.5, -127.5, 127.5, 382.5, + 637.5, 892.5, 1147.5, 1402.5, +}; + +static long _vq_quantmap__44u4__p7_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44u4__p7_0 = { + _vq_quantthresh__44u4__p7_0, + _vq_quantmap__44u4__p7_0, + 13, + 13 +}; + +static static_codebook _44u4__p7_0 = { + 2, 169, + _vq_lengthlist__44u4__p7_0, + 1, -514332672, 1627381760, 4, 0, + _vq_quantlist__44u4__p7_0, + NULL, + &_vq_auxt__44u4__p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u4__p7_1[] = { + 7, + 6, + 8, + 5, + 9, + 4, + 10, + 3, + 11, + 2, + 12, + 1, + 13, + 0, + 14, +}; + +static long _vq_lengthlist__44u4__p7_1[] = { + 1, 4, 4, 6, 6, 7, 7, 9, 8,10, 8,10, 9,11,11, 4, + 7, 6, 8, 7, 9, 9,10,10,11,10,11,10,12,10, 4, 6, + 7, 8, 8, 9, 9,10,10,11,11,11,11,12,12, 6, 8, 8, + 10, 9,11,10,12,11,12,12,12,12,13,13, 6, 8, 8,10, + 10,10,11,11,11,12,12,13,12,13,13, 8, 9, 9,11,11, + 12,11,12,12,13,13,13,13,13,13, 8, 9, 9,11,11,11, + 12,12,12,13,13,13,13,13,13, 9,10,10,12,11,13,13, + 13,13,14,13,13,14,14,14, 9,10,11,11,12,12,13,13, + 13,13,13,14,15,14,14,10,11,11,12,12,13,13,14,14, + 14,14,14,15,16,16,10,11,11,12,13,13,13,13,15,14, + 14,15,16,15,16,10,12,12,13,13,14,14,14,15,15,15, + 15,15,15,16,11,12,12,13,13,14,14,14,15,15,15,16, + 15,17,16,11,12,12,13,13,13,15,15,14,16,16,16,16, + 16,17,11,12,12,13,13,14,14,15,14,15,15,17,17,16, + 16, +}; + +static float _vq_quantthresh__44u4__p7_1[] = { + -110.5, -93.5, -76.5, -59.5, -42.5, -25.5, -8.5, 8.5, + 25.5, 42.5, 59.5, 76.5, 93.5, 110.5, +}; + +static long _vq_quantmap__44u4__p7_1[] = { + 13, 11, 9, 7, 5, 3, 1, 0, + 2, 4, 6, 8, 10, 12, 14, +}; + +static encode_aux_threshmatch _vq_auxt__44u4__p7_1 = { + _vq_quantthresh__44u4__p7_1, + _vq_quantmap__44u4__p7_1, + 15, + 15 +}; + +static static_codebook _44u4__p7_1 = { + 2, 225, + _vq_lengthlist__44u4__p7_1, + 1, -522338304, 1620115456, 4, 0, + _vq_quantlist__44u4__p7_1, + NULL, + &_vq_auxt__44u4__p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u4__p7_2[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44u4__p7_2[] = { + 2, 5, 5, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, + 9, 5, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, + 9, 9, 5, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, + 9, 9, 9, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, + 10,10,10,10, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9,10, + 9,10, 9,10,10, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, + 10,10,10,10,10,10, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, + 9,10,10,10,10,10,10, 8, 9, 8, 9, 9, 9, 9, 9, 9, + 10,10,10,10,10,10,10,10, 8, 8, 8, 9, 9, 9, 9, 9, + 10,10,10,10,10,10,10,10,10, 9, 9, 9, 9, 9,10,10, + 10,10,10,10,10,10,10,10,10,10, 9, 9, 9, 9, 9,10, + 10,10,10,10,10,10,10,10,10,10,10, 9, 9, 9, 9,10, + 10,10,10,10,10,10,10,10,10,10,10,10, 9, 9, 9, 9, + 10,10,10,10,10,10,10,10,10,11,10,10,10, 9, 9, 9, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10, 9, 9, + 9,10,10,10,10,10,10,10,10,10,10,10,10,10,10, 9, + 10, 9,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 9,10, 9,10,10,10,10,10,10,10,10,10,10,11,10,10, + 10, +}; + +static float _vq_quantthresh__44u4__p7_2[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__44u4__p7_2[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44u4__p7_2 = { + _vq_quantthresh__44u4__p7_2, + _vq_quantmap__44u4__p7_2, + 17, + 17 +}; + +static static_codebook _44u4__p7_2 = { + 2, 289, + _vq_lengthlist__44u4__p7_2, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__44u4__p7_2, + NULL, + &_vq_auxt__44u4__p7_2, + NULL, + 0 +}; + +static long _huff_lengthlist__44u4__short[] = { + 14,17,15,17,16,14,13,16,10, 7, 7,10,13,10,15,16, + 9, 4, 4, 6, 5, 7, 9,16,12, 8, 7, 8, 8, 8,11,16, + 14, 7, 4, 6, 3, 5, 8,15,13, 8, 5, 7, 4, 5, 7,16, + 12, 9, 6, 8, 3, 3, 5,16,14,13, 7,10, 5, 5, 7,15, +}; + +static static_codebook _huff_book__44u4__short = { + 2, 64, + _huff_lengthlist__44u4__short, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__44u5__long[] = { + 3, 8,13,12,14,12,16,11,13,14, 5, 4, 5, 6, 7, 8, + 10, 9,12,15,10, 5, 5, 5, 6, 8, 9, 9,13,15,10, 5, + 5, 6, 6, 7, 8, 8,11,13,12, 7, 5, 6, 4, 6, 7, 7, + 11,14,11, 7, 7, 6, 6, 6, 7, 6,10,14,14, 9, 8, 8, + 6, 7, 7, 7,11,16,11, 8, 8, 7, 6, 6, 7, 4, 7,12, + 10,10,12,10,10, 9,10, 5, 6, 9,10,12,15,13,14,14, + 14, 8, 7, 8, +}; + +static static_codebook _huff_book__44u5__long = { + 2, 100, + _huff_lengthlist__44u5__long, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__44u5__p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44u5__p1_0[] = { + 1, 4, 4, 5, 8, 7, 5, 7, 7, 5, 8, 8, 8,10,10, 7, + 9,10, 5, 8, 8, 7,10, 9, 8,10,10, 5, 8, 8, 8,10, + 10, 8,10,10, 8,10,10,10,12,13,10,13,13, 7,10,10, + 10,13,11,10,13,13, 4, 8, 8, 8,11,10, 8,10,10, 7, + 10,10,10,13,13,10,11,13, 8,10,11,10,13,13,10,13, + 12, +}; + +static float _vq_quantthresh__44u5__p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44u5__p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44u5__p1_0 = { + _vq_quantthresh__44u5__p1_0, + _vq_quantmap__44u5__p1_0, + 3, + 3 +}; + +static static_codebook _44u5__p1_0 = { + 4, 81, + _vq_lengthlist__44u5__p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44u5__p1_0, + NULL, + &_vq_auxt__44u5__p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u5__p2_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44u5__p2_0[] = { + 3, 4, 4, 5, 6, 6, 5, 6, 6, 5, 6, 6, 6, 8, 8, 6, + 7, 8, 5, 6, 6, 6, 8, 7, 6, 8, 8, 5, 6, 6, 6, 8, + 8, 6, 8, 8, 6, 8, 8, 8, 9, 9, 8, 9, 9, 6, 8, 7, + 7, 9, 8, 8, 9, 9, 5, 6, 6, 6, 8, 7, 6, 8, 8, 6, + 8, 7, 8, 9, 9, 7, 8, 9, 6, 8, 8, 8, 9, 9, 8, 9, + 9, +}; + +static float _vq_quantthresh__44u5__p2_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44u5__p2_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44u5__p2_0 = { + _vq_quantthresh__44u5__p2_0, + _vq_quantmap__44u5__p2_0, + 3, + 3 +}; + +static static_codebook _44u5__p2_0 = { + 4, 81, + _vq_lengthlist__44u5__p2_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44u5__p2_0, + NULL, + &_vq_auxt__44u5__p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u5__p3_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44u5__p3_0[] = { + 2, 4, 5, 8, 8, 5, 7, 6, 9, 9, 5, 6, 7, 9, 9, 8, + 10, 9,13,12, 8, 9,10,12,12, 5, 7, 7,10,10, 7, 9, + 9,11,11, 6, 8, 9,11,11,10,11,11,14,14, 9,10,11, + 13,14, 5, 7, 7, 9,10, 7, 9, 8,11,11, 7, 9, 9,11, + 11, 9,11,10,14,13,10,11,11,14,14, 8,10,10,13,13, + 10,11,11,15,14, 9,11,11,14,14,13,14,14,17,16,12, + 13,13,15,16, 8,10,10,13,13, 9,11,11,14,15,10,11, + 11,14,15,12,14,13,16,16,13,15,14,15,17, 5, 7, 7, + 10,10, 7, 9, 9,11,11, 7, 9, 9,11,11,10,11,11,14, + 14,10,11,12,14,14, 7, 9, 9,12,11, 9,11,11,13,13, + 9,11,11,13,13,12,13,13,15,16,11,12,13,15,16, 6, + 9, 9,11,11, 8,11,10,13,12, 9,11,11,13,14,11,13, + 12,16,14,11,13,13,16,17,10,12,11,15,15,11,13,13, + 16,16,11,13,13,17,16,14,15,15,17,17,14,16,16,17, + 18, 9,11,11,14,15,10,12,12,15,15,11,13,13,16,17, + 13,15,13,17,15,14,15,16,18, 0, 5, 7, 7,10,10, 7, + 9, 9,11,11, 7, 9, 9,11,11,10,11,11,14,14,10,11, + 12,14,15, 6, 9, 9,12,11, 9,11,11,13,13, 8,10,11, + 12,13,11,13,13,16,15,11,12,13,14,15, 7, 9, 9,11, + 12, 9,11,11,13,13, 9,11,11,13,13,11,13,13,15,16, + 11,13,13,15,14, 9,11,11,15,14,11,13,13,17,15,10, + 12,12,15,15,14,16,16,17,17,13,13,15,15,17,10,11, + 12,15,15,11,13,13,16,16,11,13,13,15,15,14,15,15, + 18,18,14,15,15,17,17, 8,10,10,13,13,10,12,11,15, + 15,10,11,12,15,15,14,15,15,18,18,13,14,14,18,18, + 9,11,11,15,16,11,13,13,17,17,11,13,13,16,16,15, + 15,16,17, 0,14,15,17, 0, 0, 9,11,11,15,15,10,13, + 12,18,16,11,13,13,15,16,14,16,15,20,20,14,15,16, + 17, 0,13,14,14,20,16,14,15,16,19,18,14,15,15,19, + 0,18,16, 0,20,20,16,18,18, 0, 0,12,14,14,18,18, + 13,15,14,18,16,14,15,16,18,20,16,19,16, 0,17,17, + 18,18,19, 0, 8,10,10,14,14,10,11,11,14,15,10,11, + 12,15,15,13,15,14,19,17,13,15,15,17, 0, 9,11,11, + 16,15,11,13,13,16,16,10,12,13,15,17,14,16,16,18, + 18,14,15,15,18, 0, 9,11,11,15,15,11,13,13,16,17, + 11,13,13,18,17,14,18,16,18,18,15,17,17,18, 0,12, + 14,14,18,18,14,15,15,20, 0,13,14,15,17, 0,16,18, + 17, 0, 0,16,16, 0,17,20,12,14,14,18,18,14,16,15, + 0,18,14,16,15,18, 0,16,19,17, 0, 0,17,18,16, 0, + 0, +}; + +static float _vq_quantthresh__44u5__p3_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44u5__p3_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44u5__p3_0 = { + _vq_quantthresh__44u5__p3_0, + _vq_quantmap__44u5__p3_0, + 5, + 5 +}; + +static static_codebook _44u5__p3_0 = { + 4, 625, + _vq_lengthlist__44u5__p3_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44u5__p3_0, + NULL, + &_vq_auxt__44u5__p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u5__p4_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44u5__p4_0[] = { + 4, 5, 5, 8, 8, 6, 7, 6, 9, 9, 6, 6, 7, 9, 9, 8, + 9, 9,11,11, 8, 9, 9,11,11, 6, 7, 7, 9, 9, 7, 8, + 8,10,10, 6, 7, 8, 9,10, 9,10,10,11,12, 9, 9,10, + 11,12, 6, 7, 7, 9, 9, 6, 8, 7,10, 9, 7, 8, 8,10, + 10, 9,10, 9,12,11, 9,10,10,12,11, 8, 9, 9,12,11, + 9,10,10,12,12, 9,10,10,12,12,11,12,12,13,14,11, + 11,12,13,14, 8, 9, 9,11,12, 9,10,10,12,12, 9,10, + 10,12,12,11,12,11,14,13,11,12,12,13,13, 5, 7, 7, + 9, 9, 7, 8, 8,10,10, 7, 8, 8,10,10, 9,10,10,12, + 12, 9,10,10,12,12, 7, 8, 8,10,10, 8, 8, 9,10,11, + 8, 9, 9,11,11,10,10,11,11,13,10,11,11,12,13, 6, + 7, 8,10,10, 7, 9, 8,11,10, 8, 9, 9,11,11,10,11, + 10,13,11,10,11,11,12,12, 9,10,10,12,12,10,10,11, + 12,13,10,11,11,13,13,12,11,13,12,15,12,13,13,14, + 15, 9,10,10,12,12, 9,11,10,13,12,10,11,11,13,13, + 11,13,11,14,12,12,13,13,14,15, 5, 7, 7, 9, 9, 7, + 8, 8,10,10, 7, 8, 8,10,10, 9,10,10,12,12, 9,10, + 10,12,12, 6, 8, 7,10,10, 8, 9, 9,11,11, 7, 8, 9, + 10,11,10,11,11,12,12,10,10,11,11,13, 7, 8, 8,10, + 10, 8, 9, 9,11,11, 8, 9, 8,11,10,10,11,11,13,12, + 10,11,10,13,11, 9,10,10,12,12,10,11,11,13,12, 9, + 10,10,12,13,12,13,13,14,15,11,11,13,12,14, 9,10, + 10,12,12,10,11,11,13,13,10,11,10,13,12,12,13,13, + 14,14,12,13,11,14,12, 8, 9, 9,12,12, 9,10,10,12, + 12, 9,10,10,12,12,12,12,12,14,14,11,12,12,14,13, + 9,10,10,12,12,10,11,11,13,13,10,11,11,13,12,12, + 12,13,14,15,12,13,13,15,14, 9,10,10,12,12,10,11, + 10,13,12,10,11,11,12,13,12,13,12,15,13,12,13,13, + 14,15,11,12,12,14,13,11,12,12,14,15,12,13,13,15, + 14,13,12,14,12,16,13,14,14,15,15,11,11,12,14,14, + 11,12,11,14,13,12,13,13,14,15,13,14,12,16,12,14, + 14,15,16,16, 8, 9, 9,11,12, 9,10,10,12,12, 9,10, + 10,12,13,11,12,12,13,13,12,12,13,14,14, 9,10,10, + 12,12,10,11,10,13,12,10,10,11,12,13,12,13,13,15, + 14,12,12,13,13,15, 9,10,10,12,13,10,11,11,12,13, + 10,11,11,13,13,12,13,13,14,15,12,13,12,15,14,11, + 12,11,14,13,12,13,13,15,14,11,11,12,13,14,14,15, + 14,16,15,13,12,14,13,16,11,12,12,13,14,12,13,13, + 14,15,11,12,11,14,14,14,14,14,15,16,13,15,12,16, + 12, +}; + +static float _vq_quantthresh__44u5__p4_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44u5__p4_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44u5__p4_0 = { + _vq_quantthresh__44u5__p4_0, + _vq_quantmap__44u5__p4_0, + 5, + 5 +}; + +static static_codebook _44u5__p4_0 = { + 4, 625, + _vq_lengthlist__44u5__p4_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44u5__p4_0, + NULL, + &_vq_auxt__44u5__p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u5__p5_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44u5__p5_0[] = { + 2, 3, 3, 6, 6, 8, 8,10,10, 4, 5, 5, 8, 7, 8, 8, + 11,10, 3, 5, 5, 7, 8, 8, 8,10,11, 6, 8, 7,10, 9, + 10,10,11,11, 6, 7, 8, 9, 9, 9,10,11,12, 8, 8, 8, + 10,10,11,11,13,12, 8, 8, 9, 9,10,11,11,12,13,10, + 11,10,12,11,13,12,14,14,10,10,11,11,12,12,13,14, + 14, +}; + +static float _vq_quantthresh__44u5__p5_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44u5__p5_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44u5__p5_0 = { + _vq_quantthresh__44u5__p5_0, + _vq_quantmap__44u5__p5_0, + 9, + 9 +}; + +static static_codebook _44u5__p5_0 = { + 2, 81, + _vq_lengthlist__44u5__p5_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44u5__p5_0, + NULL, + &_vq_auxt__44u5__p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u5__p6_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44u5__p6_0[] = { + 3, 4, 4, 5, 5, 7, 7, 9, 9, 4, 5, 4, 6, 6, 7, 7, + 9, 9, 4, 4, 5, 6, 6, 7, 7, 9, 9, 5, 6, 6, 7, 7, + 8, 8,10,10, 6, 6, 6, 7, 7, 8, 8,10,10, 7, 7, 7, + 8, 8, 9, 9,11,10, 7, 7, 7, 8, 8, 9, 9,10,11, 9, + 9, 9,10,10,11,10,11,11, 9, 9, 9,10,10,11,10,11, + 11, +}; + +static float _vq_quantthresh__44u5__p6_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44u5__p6_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44u5__p6_0 = { + _vq_quantthresh__44u5__p6_0, + _vq_quantmap__44u5__p6_0, + 9, + 9 +}; + +static static_codebook _44u5__p6_0 = { + 2, 81, + _vq_lengthlist__44u5__p6_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44u5__p6_0, + NULL, + &_vq_auxt__44u5__p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u5__p7_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44u5__p7_0[] = { + 1, 4, 4, 5, 7, 7, 5, 7, 7, 5, 9, 9, 8,11,10, 7, + 11,10, 5, 9, 9, 7,10,10, 8,10,11, 4, 9, 9, 9,12, + 12, 9,12,12, 8,12,12,11,12,12,10,12,13, 7,12,12, + 11,12,12,10,12,13, 4, 9, 9, 9,12,12, 9,12,12, 7, + 12,11,10,13,13,11,12,12, 7,12,12,10,13,13,11,12, + 12, +}; + +static float _vq_quantthresh__44u5__p7_0[] = { + -5.5, 5.5, +}; + +static long _vq_quantmap__44u5__p7_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44u5__p7_0 = { + _vq_quantthresh__44u5__p7_0, + _vq_quantmap__44u5__p7_0, + 3, + 3 +}; + +static static_codebook _44u5__p7_0 = { + 4, 81, + _vq_lengthlist__44u5__p7_0, + 1, -529137664, 1618345984, 2, 0, + _vq_quantlist__44u5__p7_0, + NULL, + &_vq_auxt__44u5__p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u5__p7_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44u5__p7_1[] = { + 2, 4, 4, 6, 6, 7, 7, 8, 8, 8, 8, 4, 5, 5, 7, 7, + 8, 8, 9, 8, 8, 9, 4, 5, 5, 7, 7, 8, 8, 9, 9, 8, + 9, 6, 7, 7, 8, 8, 9, 8, 9, 9, 9, 9, 6, 7, 7, 8, + 8, 9, 9, 9, 9, 9, 9, 7, 8, 8, 9, 9, 9, 9, 9, 9, + 9, 9, 7, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 9, + 9, 9, 9, 9,10,10,10,10, 8, 9, 9, 9, 9, 9, 9,10, + 10,10,10, 8, 9, 9, 9, 9, 9, 9,10,10,10,10, 8, 9, + 9, 9, 9, 9, 9,10,10,10,10, +}; + +static float _vq_quantthresh__44u5__p7_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__44u5__p7_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44u5__p7_1 = { + _vq_quantthresh__44u5__p7_1, + _vq_quantmap__44u5__p7_1, + 11, + 11 +}; + +static static_codebook _44u5__p7_1 = { + 2, 121, + _vq_lengthlist__44u5__p7_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__44u5__p7_1, + NULL, + &_vq_auxt__44u5__p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u5__p8_0[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44u5__p8_0[] = { + 1, 4, 4, 6, 6, 8, 8, 9, 9,10,10, 4, 6, 6, 7, 7, + 9, 9,10,10,11,11, 4, 6, 6, 7, 7, 9, 9,10,10,11, + 11, 6, 8, 7, 9, 9,10,10,11,11,13,12, 6, 8, 8, 9, + 9,10,10,11,11,12,13, 8, 9, 9,10,10,12,12,13,12, + 14,13, 8, 9, 9,10,10,12,12,13,13,14,14, 9,11,11, + 12,12,13,13,14,14,15,14, 9,11,11,12,12,13,13,14, + 14,15,14,11,12,12,13,13,14,14,15,14,15,14,11,11, + 12,13,13,14,14,14,14,15,15, +}; + +static float _vq_quantthresh__44u5__p8_0[] = { + -49.5, -38.5, -27.5, -16.5, -5.5, 5.5, 16.5, 27.5, + 38.5, 49.5, +}; + +static long _vq_quantmap__44u5__p8_0[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44u5__p8_0 = { + _vq_quantthresh__44u5__p8_0, + _vq_quantmap__44u5__p8_0, + 11, + 11 +}; + +static static_codebook _44u5__p8_0 = { + 2, 121, + _vq_lengthlist__44u5__p8_0, + 1, -524582912, 1618345984, 4, 0, + _vq_quantlist__44u5__p8_0, + NULL, + &_vq_auxt__44u5__p8_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u5__p8_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44u5__p8_1[] = { + 3, 5, 5, 6, 6, 7, 7, 7, 7, 7, 7, 5, 6, 5, 7, 6, + 7, 7, 8, 8, 8, 8, 5, 5, 5, 6, 6, 7, 7, 8, 8, 8, + 8, 6, 7, 6, 7, 7, 8, 8, 8, 8, 8, 8, 6, 6, 7, 7, + 7, 8, 8, 8, 8, 8, 8, 7, 7, 7, 8, 8, 8, 8, 8, 8, + 8, 8, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 7, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 7, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, +}; + +static float _vq_quantthresh__44u5__p8_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__44u5__p8_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44u5__p8_1 = { + _vq_quantthresh__44u5__p8_1, + _vq_quantmap__44u5__p8_1, + 11, + 11 +}; + +static static_codebook _44u5__p8_1 = { + 2, 121, + _vq_lengthlist__44u5__p8_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__44u5__p8_1, + NULL, + &_vq_auxt__44u5__p8_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u5__p9_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44u5__p9_0[] = { + 1, 3, 2,12,10,13,13,13,13,13,13,13,13, 4, 9, 9, + 13,13,13,13,13,13,13,13,13,13, 5,10, 9,13,13,13, + 13,13,13,13,13,13,13,12,13,13,13,13,13,13,13,13, + 13,13,13,13,11,13,13,13,13,13,13,13,13,13,13,13, + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, + 13,13,13,13,13,13,13,13,13,13,13,13,13,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12, +}; + +static float _vq_quantthresh__44u5__p9_0[] = { + -1402.5, -1147.5, -892.5, -637.5, -382.5, -127.5, 127.5, 382.5, + 637.5, 892.5, 1147.5, 1402.5, +}; + +static long _vq_quantmap__44u5__p9_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44u5__p9_0 = { + _vq_quantthresh__44u5__p9_0, + _vq_quantmap__44u5__p9_0, + 13, + 13 +}; + +static static_codebook _44u5__p9_0 = { + 2, 169, + _vq_lengthlist__44u5__p9_0, + 1, -514332672, 1627381760, 4, 0, + _vq_quantlist__44u5__p9_0, + NULL, + &_vq_auxt__44u5__p9_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u5__p9_1[] = { + 7, + 6, + 8, + 5, + 9, + 4, + 10, + 3, + 11, + 2, + 12, + 1, + 13, + 0, + 14, +}; + +static long _vq_lengthlist__44u5__p9_1[] = { + 1, 4, 4, 7, 7, 8, 8, 8, 7, 8, 7, 9, 8, 9, 9, 4, + 7, 6, 9, 8,10,10, 9, 8, 9, 9, 9, 9, 9, 8, 5, 6, + 6, 8, 9,10,10, 9, 9, 9,10,10,10,10,11, 7, 8, 8, + 10,10,11,11,10,10,11,11,11,12,11,11, 7, 8, 8,10, + 10,11,11,10,10,11,11,12,11,11,11, 8, 9, 9,11,11, + 12,12,11,11,12,11,12,12,12,12, 8, 9,10,11,11,12, + 12,11,11,12,12,12,12,12,12, 8, 9, 9,10,10,12,11, + 12,12,12,12,12,12,12,13, 8, 9, 9,11,11,11,11,12, + 12,12,12,13,12,13,13, 9,10,10,11,11,12,12,12,13, + 12,13,13,13,14,13, 9,10,10,11,11,12,12,12,13,13, + 12,13,13,14,13, 9,11,10,12,11,13,12,12,13,13,13, + 13,13,13,14, 9,10,10,12,12,12,12,12,13,13,13,13, + 13,14,14,10,11,11,12,12,12,13,13,13,14,14,13,14, + 14,14,10,11,11,12,12,12,12,13,12,13,14,13,14,14, + 14, +}; + +static float _vq_quantthresh__44u5__p9_1[] = { + -110.5, -93.5, -76.5, -59.5, -42.5, -25.5, -8.5, 8.5, + 25.5, 42.5, 59.5, 76.5, 93.5, 110.5, +}; + +static long _vq_quantmap__44u5__p9_1[] = { + 13, 11, 9, 7, 5, 3, 1, 0, + 2, 4, 6, 8, 10, 12, 14, +}; + +static encode_aux_threshmatch _vq_auxt__44u5__p9_1 = { + _vq_quantthresh__44u5__p9_1, + _vq_quantmap__44u5__p9_1, + 15, + 15 +}; + +static static_codebook _44u5__p9_1 = { + 2, 225, + _vq_lengthlist__44u5__p9_1, + 1, -522338304, 1620115456, 4, 0, + _vq_quantlist__44u5__p9_1, + NULL, + &_vq_auxt__44u5__p9_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u5__p9_2[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44u5__p9_2[] = { + 2, 5, 5, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, + 9, 5, 6, 6, 7, 7, 8, 8, 9, 8, 9, 9, 9, 9, 9, 9, + 9, 9, 5, 6, 6, 7, 7, 8, 8, 9, 8, 9, 9, 9, 9, 9, + 9, 9, 9, 7, 7, 7, 8, 8, 9, 8, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 7, 7, 7, 8, 8, 9, 8, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, + 9,10, 9,10,10,10, 8, 8, 8, 9, 8, 9, 9, 9, 9, 9, + 9, 9,10, 9,10, 9,10, 8, 9, 9, 9, 9, 9, 9, 9, 9, + 9,10, 9,10,10,10,10,10, 8, 9, 9, 9, 9, 9, 9,10, + 9,10, 9,10,10,10,10,10,10, 9, 9, 9, 9, 9,10, 9, + 10,10,10,10,10,10,10,10,10,10, 9, 9, 9, 9, 9, 9, + 9,10, 9,10, 9,10,10,10,10,10,10, 9, 9, 9, 9, 9, + 10,10,10,10,10,10,10,10,10,10,10,10, 9, 9, 9, 9, + 9, 9,10,10,10,10,10,10,10,10,10,10,10, 9, 9, 9, + 9,10,10, 9,10,10,10,10,10,10,10,10,10,10, 9, 9, + 9, 9, 9,10,10,10,10,10,10,10,10,10,10,10,10, 9, + 9, 9, 9, 9,10,10,10,10,10,10,10,10,10,10,10,10, + 9, 9, 9,10, 9,10,10,10,10,10,10,10,10,10,10,10, + 10, +}; + +static float _vq_quantthresh__44u5__p9_2[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__44u5__p9_2[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44u5__p9_2 = { + _vq_quantthresh__44u5__p9_2, + _vq_quantmap__44u5__p9_2, + 17, + 17 +}; + +static static_codebook _44u5__p9_2 = { + 2, 289, + _vq_lengthlist__44u5__p9_2, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__44u5__p9_2, + NULL, + &_vq_auxt__44u5__p9_2, + NULL, + 0 +}; + +static long _huff_lengthlist__44u5__short[] = { + 4,10,17,13,17,13,17,17,17,17, 3, 6, 8, 9,11, 9, + 15,12,16,17, 6, 5, 5, 7, 7, 8,10,11,17,17, 7, 8, + 7, 9, 9,10,13,13,17,17, 8, 6, 5, 7, 4, 7, 5, 8, + 14,17, 9, 9, 8, 9, 7, 9, 8,10,16,17,12,10, 7, 8, + 4, 7, 4, 7,16,17,12,11, 9,10, 6, 9, 5, 7,14,17, + 14,13,10,15, 4, 8, 3, 5,14,17,17,14,11,15, 6,10, + 6, 8,15,17, +}; + +static static_codebook _huff_book__44u5__short = { + 2, 100, + _huff_lengthlist__44u5__short, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__44u6__long[] = { + 3, 9,14,13,14,13,16,12,13,14, 5, 4, 6, 6, 8, 9, + 11,10,12,15,10, 5, 5, 6, 6, 8,10,10,13,16,10, 6, + 6, 6, 6, 8, 9, 9,12,14,13, 7, 6, 6, 4, 6, 6, 7, + 11,14,10, 7, 7, 7, 6, 6, 6, 7,10,13,15,10, 9, 8, + 5, 6, 5, 6,10,14,10, 9, 8, 8, 6, 6, 5, 4, 6,11, + 11,11,12,11,10, 9, 9, 5, 5, 9,10,12,15,13,13,13, + 13, 8, 7, 7, +}; + +static static_codebook _huff_book__44u6__long = { + 2, 100, + _huff_lengthlist__44u6__long, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__44u6__p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44u6__p1_0[] = { + 1, 4, 4, 4, 8, 7, 5, 7, 7, 5, 8, 8, 8,10,10, 7, + 9,10, 5, 8, 8, 7,10, 9, 8,10,10, 5, 8, 8, 8,10, + 10, 8,10,10, 8,10,10,10,12,13,10,13,13, 7,10,10, + 10,13,11,10,13,13, 5, 8, 8, 8,11,10, 8,10,10, 7, + 10,10,10,13,13,10,11,13, 8,10,11,10,13,13,10,13, + 12, +}; + +static float _vq_quantthresh__44u6__p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44u6__p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44u6__p1_0 = { + _vq_quantthresh__44u6__p1_0, + _vq_quantmap__44u6__p1_0, + 3, + 3 +}; + +static static_codebook _44u6__p1_0 = { + 4, 81, + _vq_lengthlist__44u6__p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44u6__p1_0, + NULL, + &_vq_auxt__44u6__p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u6__p2_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44u6__p2_0[] = { + 3, 4, 4, 5, 6, 6, 5, 6, 6, 5, 6, 6, 6, 8, 8, 6, + 7, 8, 5, 6, 6, 6, 8, 7, 6, 8, 8, 5, 6, 6, 6, 8, + 8, 6, 8, 8, 6, 8, 8, 8, 9, 9, 8, 9, 9, 6, 7, 7, + 7, 9, 8, 8, 9, 9, 5, 6, 6, 6, 8, 7, 6, 8, 8, 6, + 8, 8, 8, 9, 9, 7, 8, 9, 6, 8, 8, 8, 9, 9, 8, 9, + 9, +}; + +static float _vq_quantthresh__44u6__p2_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44u6__p2_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44u6__p2_0 = { + _vq_quantthresh__44u6__p2_0, + _vq_quantmap__44u6__p2_0, + 3, + 3 +}; + +static static_codebook _44u6__p2_0 = { + 4, 81, + _vq_lengthlist__44u6__p2_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44u6__p2_0, + NULL, + &_vq_auxt__44u6__p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u6__p3_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44u6__p3_0[] = { + 2, 5, 4, 8, 8, 5, 7, 6, 9, 9, 5, 6, 7, 9, 9, 8, + 9, 9,13,12, 8, 9,10,12,13, 5, 7, 7,10, 9, 7, 9, + 9,11,11, 7, 8, 9,11,11,10,11,11,14,14, 9,10,11, + 13,14, 5, 7, 7, 9,10, 6, 9, 8,11,11, 7, 9, 9,11, + 11, 9,11,10,14,13,10,11,11,14,13, 8,10,10,13,13, + 10,11,11,15,15, 9,11,11,14,14,13,14,14,17,16,12, + 13,14,16,16, 8,10,10,13,14, 9,11,11,14,15,10,11, + 12,14,15,12,14,13,16,15,13,14,14,15,17, 5, 7, 7, + 10,10, 7, 9, 9,11,11, 7, 9, 9,11,11,10,12,11,14, + 14,10,11,11,14,14, 7, 9, 9,12,11, 9,11,11,13,13, + 9,11,11,13,13,11,13,13,14,15,11,12,13,15,16, 6, + 9, 9,11,12, 8,11,10,13,12, 9,11,11,13,14,11,13, + 12,16,14,11,13,13,15,16,10,12,11,14,15,11,13,13, + 15,17,11,13,13,17,16,15,15,16,17,16,14,15,16,18, + 0, 9,11,11,14,15,10,12,12,16,15,11,13,13,16,16, + 13,15,14,18,15,14,16,16, 0, 0, 5, 7, 7,10,10, 7, + 9, 9,11,11, 7, 9, 9,11,11,10,11,11,14,14,10,11, + 12,14,14, 6, 9, 9,11,11, 9,11,11,13,13, 8,10,11, + 12,13,11,13,13,16,15,11,12,13,14,16, 7, 9, 9,11, + 12, 9,11,11,13,13, 9,11,11,13,13,11,13,13,16,15, + 11,13,12,15,15, 9,11,11,15,14,11,13,13,17,16,10, + 12,13,15,16,14,16,16, 0,18,14,14,15,15,17,10,11, + 12,15,15,11,13,13,16,16,11,13,13,16,16,14,16,16, + 19,17,14,15,15,17,17, 8,10,10,14,14,10,12,11,15, + 15,10,11,12,16,15,14,15,15,18,20,13,14,16,17,18, + 9,11,11,15,16,11,13,13,17,17,11,13,13,17,16,15, + 16,16, 0, 0,15,16,16, 0, 0, 9,11,11,15,15,10,13, + 12,17,15,11,13,13,17,16,15,17,15,20,19,15,16,16, + 19, 0,13,15,14, 0,17,14,15,16, 0,20,15,16,16, 0, + 19,17,18, 0, 0, 0,16,17,18, 0, 0,12,14,14,19,18, + 13,15,14, 0,17,14,15,16,19,19,16,18,16, 0,19,19, + 20,17,20, 0, 8,10,10,13,14,10,11,11,15,15,10,12, + 12,15,16,14,15,14,19,16,14,15,15, 0,18, 9,11,11, + 16,15,11,13,13, 0,16,11,12,13,16,17,14,16,17, 0, + 19,15,16,16,18, 0, 9,11,11,15,16,11,13,13,16,16, + 11,14,13,18,17,15,16,16,18,20,15,17,19, 0, 0,12, + 14,14,17,17,14,16,15, 0, 0,13,14,15,19, 0,16,18, + 20, 0, 0,16,16,18,18, 0,12,14,14,17,20,14,16,16, + 19, 0,14,16,14, 0,20,16,20,17, 0, 0,17, 0,15, 0, + 19, +}; + +static float _vq_quantthresh__44u6__p3_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44u6__p3_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44u6__p3_0 = { + _vq_quantthresh__44u6__p3_0, + _vq_quantmap__44u6__p3_0, + 5, + 5 +}; + +static static_codebook _44u6__p3_0 = { + 4, 625, + _vq_lengthlist__44u6__p3_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44u6__p3_0, + NULL, + &_vq_auxt__44u6__p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u6__p4_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44u6__p4_0[] = { + 4, 5, 5, 8, 8, 6, 7, 6, 9, 9, 6, 6, 7, 9, 9, 8, + 9, 9,11,11, 8, 9, 9,11,11, 6, 7, 7, 9, 9, 7, 8, + 8,10,10, 7, 7, 8, 9,10, 9,10,10,11,11, 9, 9,10, + 11,12, 6, 7, 7, 9, 9, 7, 8, 7,10, 9, 7, 8, 8,10, + 10, 9,10, 9,12,11, 9,10,10,12,11, 8, 9, 9,11,11, + 9,10,10,12,12, 9,10,10,12,12,11,12,12,14,13,11, + 11,12,13,13, 8, 9, 9,11,11, 9,10,10,12,12, 9,10, + 10,12,12,11,12,11,13,12,11,12,12,13,13, 5, 7, 7, + 9, 9, 7, 8, 7,10,10, 7, 7, 8,10,10, 9,10,10,12, + 11, 9,10,10,11,12, 7, 8, 8,10,10, 8, 8, 9,11,11, + 8, 9, 9,11,11,10,10,11,12,13,10,10,11,12,12, 6, + 7, 7,10,10, 7, 9, 8,11,10, 8, 8, 9,10,11,10,11, + 10,13,11,10,11,11,12,12, 9,10,10,12,12,10,10,11, + 13,13,10,11,11,12,13,12,12,12,13,14,12,12,13,14, + 14, 9,10,10,12,12, 9,10,10,13,12,10,11,11,13,13, + 11,12,11,14,12,12,13,13,14,14, 6, 7, 7, 9, 9, 7, + 8, 7,10,10, 7, 8, 8,10,10, 9,10,10,12,11, 9,10, + 10,11,12, 6, 7, 7,10,10, 8, 9, 8,11,10, 7, 8, 9, + 10,11,10,11,11,12,12,10,10,11,11,13, 7, 8, 8,10, + 10, 8, 9, 9,11,11, 8, 9, 8,11,11,10,11,10,13,12, + 10,11,11,13,12, 9,10,10,12,12,10,11,11,13,12, 9, + 10,10,12,13,12,13,12,14,14,11,11,12,12,14, 9,10, + 10,12,12,10,11,11,13,13,10,11,10,13,12,12,12,12, + 14,14,12,13,12,14,13, 8, 9, 9,11,11, 9,10,10,12, + 12, 9,10,10,12,12,11,12,12,14,13,11,12,12,13,14, + 9,10,10,12,12,10,11,11,13,13,10,11,11,13,13,12, + 12,13,14,15,12,12,13,14,14, 9,10,10,12,12, 9,11, + 10,13,12,10,10,11,12,13,12,13,12,14,13,12,12,13, + 14,15,11,12,12,14,13,11,12,12,14,14,12,13,13,14, + 14,13,13,14,14,16,13,14,14,15,15,11,12,11,13,13, + 11,12,11,14,13,12,12,13,14,15,12,14,12,15,12,13, + 14,15,15,16, 8, 9, 9,11,11, 9,10,10,12,12, 9,10, + 10,12,12,11,12,12,14,13,11,12,12,13,13, 9,10,10, + 12,12,10,11,10,13,12, 9,10,11,12,13,12,13,12,14, + 14,12,12,13,13,14, 9,10,10,12,12,10,11,11,13,13, + 10,11,11,13,13,12,13,12,14,14,12,13,13,14,14,11, + 11,11,13,13,12,13,12,14,14,11,11,12,13,14,14,14, + 14,16,15,12,12,14,12,15,11,12,12,13,14,12,13,13, + 14,15,11,12,12,14,14,13,14,14,16,16,13,14,13,16, + 13, +}; + +static float _vq_quantthresh__44u6__p4_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44u6__p4_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44u6__p4_0 = { + _vq_quantthresh__44u6__p4_0, + _vq_quantmap__44u6__p4_0, + 5, + 5 +}; + +static static_codebook _44u6__p4_0 = { + 4, 625, + _vq_lengthlist__44u6__p4_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44u6__p4_0, + NULL, + &_vq_auxt__44u6__p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u6__p5_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44u6__p5_0[] = { + 2, 3, 3, 6, 6, 8, 8,10,10, 4, 5, 5, 8, 7, 8, 8, + 11,11, 3, 5, 5, 7, 8, 8, 8,11,11, 6, 8, 7, 9, 9, + 10, 9,12,11, 6, 7, 8, 9, 9, 9,10,11,12, 8, 8, 8, + 10, 9,12,11,13,13, 8, 8, 9, 9,10,11,12,13,13,10, + 11,11,12,12,13,13,14,14,10,10,11,11,12,13,13,14, + 14, +}; + +static float _vq_quantthresh__44u6__p5_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44u6__p5_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44u6__p5_0 = { + _vq_quantthresh__44u6__p5_0, + _vq_quantmap__44u6__p5_0, + 9, + 9 +}; + +static static_codebook _44u6__p5_0 = { + 2, 81, + _vq_lengthlist__44u6__p5_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44u6__p5_0, + NULL, + &_vq_auxt__44u6__p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u6__p6_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44u6__p6_0[] = { + 3, 4, 4, 5, 5, 7, 7, 9, 9, 4, 5, 4, 6, 6, 7, 7, + 9, 9, 4, 4, 5, 6, 6, 7, 8, 9, 9, 5, 6, 6, 7, 7, + 8, 8,10,10, 5, 6, 6, 7, 7, 8, 8,10,10, 7, 8, 7, + 8, 8,10, 9,11,11, 7, 7, 8, 8, 8, 9,10,10,11, 9, + 9, 9,10,10,11,11,12,11, 9, 9, 9,10,10,11,11,11, + 12, +}; + +static float _vq_quantthresh__44u6__p6_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44u6__p6_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44u6__p6_0 = { + _vq_quantthresh__44u6__p6_0, + _vq_quantmap__44u6__p6_0, + 9, + 9 +}; + +static static_codebook _44u6__p6_0 = { + 2, 81, + _vq_lengthlist__44u6__p6_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44u6__p6_0, + NULL, + &_vq_auxt__44u6__p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u6__p7_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44u6__p7_0[] = { + 1, 4, 4, 5, 7, 7, 5, 7, 7, 5, 9, 8, 7,10,10, 8, + 10,10, 5, 8, 9, 7,10,10, 7,10, 9, 4, 8, 8, 9,11, + 11, 8,11,11, 7,11,11,10,10,13,10,13,13, 7,11,11, + 10,13,12,10,13,13, 5, 9, 8, 8,11,11, 9,11,11, 7, + 11,11,10,13,13,10,12,13, 7,11,11,10,13,13, 9,13, + 10, +}; + +static float _vq_quantthresh__44u6__p7_0[] = { + -5.5, 5.5, +}; + +static long _vq_quantmap__44u6__p7_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44u6__p7_0 = { + _vq_quantthresh__44u6__p7_0, + _vq_quantmap__44u6__p7_0, + 3, + 3 +}; + +static static_codebook _44u6__p7_0 = { + 4, 81, + _vq_lengthlist__44u6__p7_0, + 1, -529137664, 1618345984, 2, 0, + _vq_quantlist__44u6__p7_0, + NULL, + &_vq_auxt__44u6__p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u6__p7_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44u6__p7_1[] = { + 3, 4, 4, 6, 6, 7, 7, 8, 8, 8, 8, 4, 5, 5, 7, 6, + 8, 8, 8, 8, 8, 8, 4, 5, 5, 6, 7, 8, 8, 8, 8, 8, + 8, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 6, 7, 7, 7, + 7, 8, 8, 8, 8, 8, 8, 7, 8, 8, 8, 8, 8, 8, 9, 9, + 9, 9, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 8, 8, 8, + 8, 8, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 9, 9, 9, + 9, 9, 9, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 8, 8, + 8, 8, 8, 9, 9, 9, 9, 9, 9, +}; + +static float _vq_quantthresh__44u6__p7_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__44u6__p7_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44u6__p7_1 = { + _vq_quantthresh__44u6__p7_1, + _vq_quantmap__44u6__p7_1, + 11, + 11 +}; + +static static_codebook _44u6__p7_1 = { + 2, 121, + _vq_lengthlist__44u6__p7_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__44u6__p7_1, + NULL, + &_vq_auxt__44u6__p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u6__p8_0[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44u6__p8_0[] = { + 1, 4, 4, 6, 6, 8, 8, 9, 9,10,10, 4, 6, 6, 7, 7, + 9, 9,10,10,11,11, 4, 6, 6, 7, 7, 9, 9,10,10,11, + 11, 6, 8, 8, 9, 9,10,10,11,11,12,12, 6, 8, 8, 9, + 9,10,10,11,11,12,12, 8, 9, 9,10,10,11,11,12,12, + 13,13, 8, 9, 9,10,10,11,11,12,12,13,13,10,10,10, + 11,11,13,13,13,13,15,14, 9,10,10,12,11,12,13,13, + 13,14,15,11,12,12,13,13,13,13,15,14,15,15,11,11, + 12,13,13,14,14,14,15,15,15, +}; + +static float _vq_quantthresh__44u6__p8_0[] = { + -49.5, -38.5, -27.5, -16.5, -5.5, 5.5, 16.5, 27.5, + 38.5, 49.5, +}; + +static long _vq_quantmap__44u6__p8_0[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44u6__p8_0 = { + _vq_quantthresh__44u6__p8_0, + _vq_quantmap__44u6__p8_0, + 11, + 11 +}; + +static static_codebook _44u6__p8_0 = { + 2, 121, + _vq_lengthlist__44u6__p8_0, + 1, -524582912, 1618345984, 4, 0, + _vq_quantlist__44u6__p8_0, + NULL, + &_vq_auxt__44u6__p8_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u6__p8_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44u6__p8_1[] = { + 3, 5, 5, 6, 6, 7, 7, 7, 7, 7, 7, 5, 6, 5, 7, 7, + 7, 7, 8, 7, 8, 8, 5, 5, 6, 6, 7, 7, 7, 7, 7, 8, + 8, 6, 7, 7, 7, 7, 8, 7, 8, 8, 8, 8, 6, 6, 7, 7, + 7, 7, 8, 8, 8, 8, 8, 7, 7, 7, 8, 8, 8, 8, 8, 8, + 8, 8, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, + 8, 8, 8, 8, 8, 8, 8, 8, 7, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, +}; + +static float _vq_quantthresh__44u6__p8_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__44u6__p8_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44u6__p8_1 = { + _vq_quantthresh__44u6__p8_1, + _vq_quantmap__44u6__p8_1, + 11, + 11 +}; + +static static_codebook _44u6__p8_1 = { + 2, 121, + _vq_lengthlist__44u6__p8_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__44u6__p8_1, + NULL, + &_vq_auxt__44u6__p8_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u6__p9_0[] = { + 7, + 6, + 8, + 5, + 9, + 4, + 10, + 3, + 11, + 2, + 12, + 1, + 13, + 0, + 14, +}; + +static long _vq_lengthlist__44u6__p9_0[] = { + 1, 3, 2, 9, 8,15,15,15,15,15,15,15,15,15,15, 4, + 8, 9,13,14,14,14,14,14,14,14,14,14,14,14, 5, 8, + 9,14,14,14,14,14,14,14,14,14,14,14,14,11,14,14, + 14,14,14,14,14,14,14,14,14,14,14,14,11,14,14,14, + 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, + 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, + 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, + 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, + 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, + 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, + 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, + 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, + 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, + 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, + 14, +}; + +static float _vq_quantthresh__44u6__p9_0[] = { + -1657.5, -1402.5, -1147.5, -892.5, -637.5, -382.5, -127.5, 127.5, + 382.5, 637.5, 892.5, 1147.5, 1402.5, 1657.5, +}; + +static long _vq_quantmap__44u6__p9_0[] = { + 13, 11, 9, 7, 5, 3, 1, 0, + 2, 4, 6, 8, 10, 12, 14, +}; + +static encode_aux_threshmatch _vq_auxt__44u6__p9_0 = { + _vq_quantthresh__44u6__p9_0, + _vq_quantmap__44u6__p9_0, + 15, + 15 +}; + +static static_codebook _44u6__p9_0 = { + 2, 225, + _vq_lengthlist__44u6__p9_0, + 1, -514071552, 1627381760, 4, 0, + _vq_quantlist__44u6__p9_0, + NULL, + &_vq_auxt__44u6__p9_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u6__p9_1[] = { + 7, + 6, + 8, + 5, + 9, + 4, + 10, + 3, + 11, + 2, + 12, + 1, + 13, + 0, + 14, +}; + +static long _vq_lengthlist__44u6__p9_1[] = { + 1, 4, 4, 7, 7, 8, 9, 8, 8, 9, 8, 9, 8, 9, 9, 4, + 7, 6, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 4, 7, + 6, 9, 9,10,10, 9, 9,10,10,10,10,11,11, 7, 9, 8, + 10,10,11,11,10,10,11,11,11,11,11,11, 7, 8, 9,10, + 10,11,11,10,10,11,11,11,11,11,12, 8,10,10,11,11, + 12,12,11,11,12,12,12,12,13,12, 8,10,10,11,11,12, + 11,11,11,11,12,12,12,12,13, 8, 9, 9,11,10,11,11, + 12,12,12,12,13,12,13,12, 8, 9, 9,11,11,11,11,12, + 12,12,12,12,13,13,13, 9,10,10,11,12,12,12,12,12, + 13,13,13,13,13,13, 9,10,10,11,11,12,12,12,12,13, + 13,13,13,14,13,10,10,10,12,11,12,12,13,13,13,13, + 13,13,13,13,10,10,11,11,11,12,12,13,13,13,13,13, + 13,13,13,10,11,11,12,12,13,12,12,13,13,13,13,13, + 13,14,10,11,11,12,12,13,12,13,13,13,14,13,13,14, + 13, +}; + +static float _vq_quantthresh__44u6__p9_1[] = { + -110.5, -93.5, -76.5, -59.5, -42.5, -25.5, -8.5, 8.5, + 25.5, 42.5, 59.5, 76.5, 93.5, 110.5, +}; + +static long _vq_quantmap__44u6__p9_1[] = { + 13, 11, 9, 7, 5, 3, 1, 0, + 2, 4, 6, 8, 10, 12, 14, +}; + +static encode_aux_threshmatch _vq_auxt__44u6__p9_1 = { + _vq_quantthresh__44u6__p9_1, + _vq_quantmap__44u6__p9_1, + 15, + 15 +}; + +static static_codebook _44u6__p9_1 = { + 2, 225, + _vq_lengthlist__44u6__p9_1, + 1, -522338304, 1620115456, 4, 0, + _vq_quantlist__44u6__p9_1, + NULL, + &_vq_auxt__44u6__p9_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u6__p9_2[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44u6__p9_2[] = { + 3, 5, 5, 7, 7, 8, 8, 8, 8, 8, 8, 9, 8, 8, 9, 9, + 9, 5, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, + 9, 9, 5, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, + 9, 9, 9, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9,10, 9, 8, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9,10, 9, 9, 9,10, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9,10, 9, 9, 9,10, 9, 9,10, 9, + 9, 9, 9, 9, 9, 9, 9, 9,10,10,10, 9,10, 9,10,10, + 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10, 9,10,10, 9, 9, + 10, +}; + +static float _vq_quantthresh__44u6__p9_2[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__44u6__p9_2[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44u6__p9_2 = { + _vq_quantthresh__44u6__p9_2, + _vq_quantmap__44u6__p9_2, + 17, + 17 +}; + +static static_codebook _44u6__p9_2 = { + 2, 289, + _vq_lengthlist__44u6__p9_2, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__44u6__p9_2, + NULL, + &_vq_auxt__44u6__p9_2, + NULL, + 0 +}; + +static long _huff_lengthlist__44u6__short[] = { + 4,11,16,13,17,13,17,16,17,17, 4, 7, 9, 9,13,10, + 16,12,16,17, 7, 6, 5, 7, 8, 9,12,12,16,17, 6, 9, + 7, 9,10,10,15,15,17,17, 6, 7, 5, 7, 5, 7, 7,10, + 16,17, 7, 9, 8, 9, 8,10,11,11,15,17, 7, 7, 7, 8, + 5, 8, 8, 9,15,17, 8, 7, 9, 9, 7, 8, 7, 2, 7,15, + 14,13,13,15, 5,10, 4, 3, 6,17,17,15,13,17, 7,11, + 7, 6, 9,16, +}; + +static static_codebook _huff_book__44u6__short = { + 2, 100, + _huff_lengthlist__44u6__short, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__44u7__long[] = { + 3, 9,14,13,15,14,16,13,13,14, 5, 5, 7, 7, 8, 9, + 11,10,12,15,10, 6, 5, 6, 6, 9,10,10,13,16,10, 6, + 6, 6, 6, 8, 9, 9,12,15,14, 7, 6, 6, 5, 6, 6, 8, + 12,15,10, 8, 7, 7, 6, 7, 7, 7,11,13,14,10, 9, 8, + 5, 6, 4, 5, 9,12,10, 9, 9, 8, 6, 6, 5, 3, 6,11, + 12,11,12,12,10, 9, 8, 5, 5, 8,10,11,15,13,13,13, + 12, 8, 6, 7, +}; + +static static_codebook _huff_book__44u7__long = { + 2, 100, + _huff_lengthlist__44u7__long, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__44u7__p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44u7__p1_0[] = { + 1, 4, 4, 4, 7, 7, 5, 7, 7, 5, 8, 8, 8,10,10, 7, + 10,10, 5, 8, 8, 7,10,10, 8,10,10, 5, 8, 8, 8,11, + 10, 8,10,10, 8,10,10,10,12,13,10,13,13, 7,10,10, + 10,13,12,10,13,13, 5, 8, 8, 8,11,10, 8,10,11, 7, + 10,10,10,13,13,10,12,13, 8,11,11,10,13,13,10,13, + 12, +}; + +static float _vq_quantthresh__44u7__p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44u7__p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44u7__p1_0 = { + _vq_quantthresh__44u7__p1_0, + _vq_quantmap__44u7__p1_0, + 3, + 3 +}; + +static static_codebook _44u7__p1_0 = { + 4, 81, + _vq_lengthlist__44u7__p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44u7__p1_0, + NULL, + &_vq_auxt__44u7__p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u7__p2_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44u7__p2_0[] = { + 3, 4, 4, 5, 6, 6, 5, 6, 6, 5, 6, 6, 6, 8, 8, 6, + 7, 8, 5, 6, 6, 6, 8, 7, 6, 8, 8, 5, 6, 6, 6, 8, + 7, 6, 8, 8, 6, 8, 8, 8, 9, 9, 8, 9, 9, 6, 8, 7, + 7, 9, 8, 8, 9, 9, 5, 6, 6, 6, 8, 7, 6, 8, 8, 6, + 8, 8, 8, 9, 9, 7, 8, 9, 6, 8, 8, 8, 9, 9, 8, 9, + 9, +}; + +static float _vq_quantthresh__44u7__p2_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44u7__p2_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44u7__p2_0 = { + _vq_quantthresh__44u7__p2_0, + _vq_quantmap__44u7__p2_0, + 3, + 3 +}; + +static static_codebook _44u7__p2_0 = { + 4, 81, + _vq_lengthlist__44u7__p2_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44u7__p2_0, + NULL, + &_vq_auxt__44u7__p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u7__p3_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44u7__p3_0[] = { + 2, 5, 4, 8, 8, 5, 7, 6, 9, 9, 5, 6, 7, 9, 9, 8, + 9, 9,13,12, 8, 9,10,12,13, 5, 7, 7,10, 9, 7, 9, + 9,11,11, 6, 8, 9,11,11,10,11,11,14,14, 9,10,11, + 13,14, 5, 7, 7, 9, 9, 7, 9, 8,11,11, 7, 9, 9,11, + 11, 9,11,10,14,13,10,11,11,14,14, 8,10,10,14,13, + 10,11,12,15,14, 9,11,11,15,14,13,14,14,16,16,12, + 13,14,17,16, 8,10,10,13,13, 9,11,11,14,15,10,11, + 12,14,15,12,14,13,16,16,13,14,15,15,17, 5, 7, 7, + 10,10, 7, 9, 9,11,11, 7, 9, 9,11,11,10,12,11,15, + 14,10,11,12,14,14, 7, 9, 9,12,12, 9,11,11,13,13, + 9,11,11,13,13,11,13,13,14,17,11,13,13,15,16, 6, + 9, 9,11,11, 8,11,10,13,12, 9,11,11,13,13,11,13, + 12,16,14,11,13,13,16,16,10,12,12,15,15,11,13,13, + 16,16,11,13,13,16,15,14,16,17,17,19,14,16,16,18, + 0, 9,11,11,14,15,10,13,12,16,15,11,13,13,16,16, + 14,15,14, 0,16,14,16,16,18, 0, 5, 7, 7,10,10, 7, + 9, 9,12,11, 7, 9, 9,11,12,10,11,11,15,14,10,11, + 12,14,14, 6, 9, 9,11,11, 9,11,11,13,13, 8,10,11, + 12,13,11,13,13,17,15,11,12,13,14,15, 7, 9, 9,11, + 12, 9,11,11,13,13, 9,11,11,13,13,11,13,12,16,16, + 11,13,13,15,14, 9,11,11,14,15,11,13,13,16,15,10, + 12,13,16,16,15,16,16, 0, 0,14,13,15,16,18,10,11, + 11,15,15,11,13,14,16,18,11,13,13,16,15,15,16,16, + 19, 0,14,15,15,16,16, 8,10,10,13,13,10,12,11,16, + 15,10,11,11,16,15,13,15,16,18, 0,13,14,15,17,17, + 9,11,11,15,15,11,13,13,16,18,11,13,13,16,17,15, + 16,16, 0, 0,15,18,16, 0,17, 9,11,11,15,15,11,13, + 12,17,15,11,13,14,16,17,15,18,15, 0,17,15,16,16, + 18,19,13,15,14, 0,18,14,16,16,19,18,14,16,15,19, + 19,16,18,19, 0, 0,16,17, 0, 0, 0,12,14,14,17,17, + 13,16,14, 0,18,14,16,15,18, 0,16,18,16,19,17,18, + 19,17, 0, 0, 8,10,10,14,14, 9,12,11,15,15,10,11, + 12,15,17,13,15,15,18,16,14,16,15,18,17, 9,11,11, + 16,15,11,13,13, 0,16,11,12,13,16,15,15,16,16, 0, + 17,15,15,16,18,17, 9,12,11,15,17,11,13,13,16,16, + 11,14,13,16,16,15,15,16,18,19,16,18,16, 0, 0,12, + 14,14, 0,16,14,16,16, 0,18,13,14,15,16, 0,17,16, + 18, 0, 0,16,16,17,19, 0,13,14,14,17, 0,14,17,16, + 0,19,14,15,15,18,19,17,16,18, 0, 0,15,19,16, 0, + 0, +}; + +static float _vq_quantthresh__44u7__p3_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44u7__p3_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44u7__p3_0 = { + _vq_quantthresh__44u7__p3_0, + _vq_quantmap__44u7__p3_0, + 5, + 5 +}; + +static static_codebook _44u7__p3_0 = { + 4, 625, + _vq_lengthlist__44u7__p3_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44u7__p3_0, + NULL, + &_vq_auxt__44u7__p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u7__p4_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44u7__p4_0[] = { + 4, 5, 5, 8, 8, 6, 7, 6, 9, 9, 6, 6, 7, 9, 9, 8, + 9, 9,11,11, 8, 9, 9,10,11, 6, 7, 7, 9, 9, 7, 8, + 8,10,10, 6, 7, 8, 9,10, 9,10,10,12,12, 9, 9,10, + 11,12, 6, 7, 7, 9, 9, 6, 8, 7,10, 9, 7, 8, 8,10, + 10, 9,10, 9,12,11, 9,10,10,12,11, 8, 9, 9,11,11, + 9,10,10,12,12, 9,10,10,12,12,11,12,12,13,14,11, + 11,12,13,13, 8, 9, 9,11,11, 9,10,10,12,11, 9,10, + 10,12,12,11,12,11,13,13,11,12,12,13,13, 6, 7, 7, + 9, 9, 7, 8, 7,10,10, 7, 7, 8,10,10, 9,10,10,12, + 11, 9,10,10,12,12, 7, 8, 8,10,10, 8, 8, 9,11,11, + 8, 9, 9,11,11,10,11,11,12,12,10,10,11,12,13, 6, + 7, 7,10,10, 7, 9, 8,11,10, 8, 8, 9,10,11,10,11, + 10,13,11,10,11,11,12,12, 9,10,10,12,12,10,10,11, + 13,13,10,11,11,13,12,12,12,13,13,14,12,12,13,14, + 14, 9,10,10,12,12, 9,10,10,12,12,10,11,11,13,13, + 11,12,11,14,12,12,13,13,14,14, 6, 7, 7, 9, 9, 7, + 8, 7,10,10, 7, 7, 8,10,10, 9,10,10,12,11, 9,10, + 10,11,12, 6, 7, 7,10,10, 8, 9, 8,11,10, 7, 8, 9, + 10,11,10,11,11,13,12,10,10,11,11,13, 7, 8, 8,10, + 10, 8, 9, 9,11,11, 8, 9, 9,11,11,10,11,10,13,12, + 10,11,11,12,12, 9,10,10,12,12,10,11,11,13,12, 9, + 10,10,12,13,12,13,12,14,14,11,11,12,12,14, 9,10, + 10,12,12,10,11,11,13,13,10,11,11,13,13,12,13,12, + 14,14,12,13,12,14,13, 8, 9, 9,11,11, 9,10,10,12, + 12, 9,10,10,12,12,11,12,12,14,13,11,12,12,13,13, + 9,10,10,12,12,10,11,11,13,13,10,11,11,13,12,12, + 13,13,14,14,12,12,13,14,14, 9,10,10,12,12, 9,11, + 10,13,12,10,10,11,12,13,11,13,12,14,13,12,12,13, + 14,14,11,12,12,13,13,11,12,13,14,14,12,13,13,14, + 14,13,13,14,14,16,13,14,14,16,16,11,11,11,13,13, + 11,12,11,14,13,12,12,13,14,15,13,14,12,16,13,14, + 14,14,15,16, 8, 9, 9,11,11, 9,10,10,12,12, 9,10, + 10,12,12,11,12,12,14,13,11,12,12,13,14, 9,10,10, + 12,12,10,11,10,13,12, 9,10,11,12,13,12,13,12,14, + 14,12,12,13,13,14, 9,10,10,12,12,10,11,11,12,13, + 10,11,11,13,13,12,13,12,14,14,12,13,13,14,14,11, + 12,12,13,13,12,13,12,14,14,11,11,12,13,14,13,15, + 14,16,15,13,12,14,13,16,11,12,12,13,13,12,13,13, + 14,14,12,12,12,14,14,13,14,14,15,15,13,14,13,16, + 14, +}; + +static float _vq_quantthresh__44u7__p4_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44u7__p4_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44u7__p4_0 = { + _vq_quantthresh__44u7__p4_0, + _vq_quantmap__44u7__p4_0, + 5, + 5 +}; + +static static_codebook _44u7__p4_0 = { + 4, 625, + _vq_lengthlist__44u7__p4_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44u7__p4_0, + NULL, + &_vq_auxt__44u7__p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u7__p5_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44u7__p5_0[] = { + 2, 3, 3, 6, 6, 7, 8,10,10, 4, 5, 5, 8, 7, 8, 8, + 11,11, 3, 5, 5, 7, 7, 8, 9,11,11, 6, 8, 7, 9, 9, + 10,10,12,12, 6, 7, 8, 9,10,10,10,12,12, 8, 8, 8, + 10,10,12,11,13,13, 8, 8, 9,10,10,11,11,13,13,10, + 11,11,12,12,13,13,14,14,10,11,11,12,12,13,13,14, + 14, +}; + +static float _vq_quantthresh__44u7__p5_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44u7__p5_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44u7__p5_0 = { + _vq_quantthresh__44u7__p5_0, + _vq_quantmap__44u7__p5_0, + 9, + 9 +}; + +static static_codebook _44u7__p5_0 = { + 2, 81, + _vq_lengthlist__44u7__p5_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44u7__p5_0, + NULL, + &_vq_auxt__44u7__p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u7__p6_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44u7__p6_0[] = { + 3, 4, 4, 5, 5, 7, 7, 9, 9, 4, 5, 4, 6, 6, 8, 7, + 9, 9, 4, 4, 5, 6, 6, 7, 7, 9, 9, 5, 6, 6, 7, 7, + 8, 8,10,10, 5, 6, 6, 7, 7, 8, 8,10,10, 7, 8, 7, + 8, 8,10, 9,11,11, 7, 7, 8, 8, 8, 9,10,11,11, 9, + 9, 9,10,10,11,10,12,11, 9, 9, 9,10,10,11,11,11, + 12, +}; + +static float _vq_quantthresh__44u7__p6_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44u7__p6_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44u7__p6_0 = { + _vq_quantthresh__44u7__p6_0, + _vq_quantmap__44u7__p6_0, + 9, + 9 +}; + +static static_codebook _44u7__p6_0 = { + 2, 81, + _vq_lengthlist__44u7__p6_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44u7__p6_0, + NULL, + &_vq_auxt__44u7__p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u7__p7_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44u7__p7_0[] = { + 1, 4, 4, 5, 7, 7, 5, 7, 7, 5, 9, 8, 8, 9, 9, 7, + 10,10, 5, 8, 9, 7, 9,10, 8, 9, 9, 4, 9, 9, 9,11, + 10, 8,10,10, 7,11,10,10,10,12,10,12,12, 7,10,10, + 10,12,11,10,12,12, 5, 9, 9, 8,10,10, 9,11,11, 7, + 11,10,10,12,12,10,11,12, 7,10,11,10,12,12,10,12, + 10, +}; + +static float _vq_quantthresh__44u7__p7_0[] = { + -5.5, 5.5, +}; + +static long _vq_quantmap__44u7__p7_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44u7__p7_0 = { + _vq_quantthresh__44u7__p7_0, + _vq_quantmap__44u7__p7_0, + 3, + 3 +}; + +static static_codebook _44u7__p7_0 = { + 4, 81, + _vq_lengthlist__44u7__p7_0, + 1, -529137664, 1618345984, 2, 0, + _vq_quantlist__44u7__p7_0, + NULL, + &_vq_auxt__44u7__p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u7__p7_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44u7__p7_1[] = { + 3, 4, 4, 6, 6, 7, 7, 8, 8, 8, 8, 4, 5, 5, 6, 6, + 8, 7, 8, 8, 8, 8, 4, 5, 5, 6, 6, 7, 8, 8, 8, 8, + 8, 6, 7, 6, 7, 7, 8, 8, 9, 9, 9, 9, 6, 6, 7, 7, + 7, 8, 8, 9, 9, 9, 9, 7, 8, 7, 8, 8, 9, 9, 9, 9, + 9, 9, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9, 8, 8, 8, + 9, 9, 9, 9,10, 9, 9, 9, 8, 8, 8, 9, 9, 9, 9, 9, + 9, 9,10, 8, 8, 8, 9, 9, 9, 9,10, 9,10,10, 8, 8, + 8, 9, 9, 9, 9, 9,10,10,10, +}; + +static float _vq_quantthresh__44u7__p7_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__44u7__p7_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44u7__p7_1 = { + _vq_quantthresh__44u7__p7_1, + _vq_quantmap__44u7__p7_1, + 11, + 11 +}; + +static static_codebook _44u7__p7_1 = { + 2, 121, + _vq_lengthlist__44u7__p7_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__44u7__p7_1, + NULL, + &_vq_auxt__44u7__p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u7__p8_0[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44u7__p8_0[] = { + 1, 4, 4, 6, 6, 8, 8,10,10,11,11, 4, 6, 6, 7, 7, + 9, 9,11,10,12,12, 5, 6, 5, 7, 7, 9, 9,10,11,12, + 12, 6, 7, 7, 8, 8,10,10,11,11,13,13, 6, 7, 7, 8, + 8,10,10,11,12,13,13, 8, 9, 9,10,10,11,11,12,12, + 14,14, 8, 9, 9,10,10,11,11,12,12,14,14,10,10,10, + 11,11,13,12,14,14,15,15,10,10,10,12,12,13,13,14, + 14,15,15,11,12,12,13,13,14,14,15,14,16,15,11,12, + 12,13,13,14,14,15,15,15,16, +}; + +static float _vq_quantthresh__44u7__p8_0[] = { + -49.5, -38.5, -27.5, -16.5, -5.5, 5.5, 16.5, 27.5, + 38.5, 49.5, +}; + +static long _vq_quantmap__44u7__p8_0[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44u7__p8_0 = { + _vq_quantthresh__44u7__p8_0, + _vq_quantmap__44u7__p8_0, + 11, + 11 +}; + +static static_codebook _44u7__p8_0 = { + 2, 121, + _vq_lengthlist__44u7__p8_0, + 1, -524582912, 1618345984, 4, 0, + _vq_quantlist__44u7__p8_0, + NULL, + &_vq_auxt__44u7__p8_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u7__p8_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44u7__p8_1[] = { + 4, 5, 5, 6, 6, 7, 7, 7, 7, 7, 7, 5, 6, 6, 7, 7, + 7, 7, 7, 7, 7, 7, 5, 6, 6, 6, 7, 7, 7, 7, 7, 7, + 7, 6, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 6, 7, 7, 7, + 7, 7, 7, 7, 7, 8, 8, 7, 7, 7, 7, 7, 8, 7, 8, 8, + 8, 8, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 7, 7, 7, + 7, 7, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 8, 8, 8, + 8, 8, 8, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, + 7, 8, 8, 8, 8, 8, 8, 8, 8, +}; + +static float _vq_quantthresh__44u7__p8_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__44u7__p8_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44u7__p8_1 = { + _vq_quantthresh__44u7__p8_1, + _vq_quantmap__44u7__p8_1, + 11, + 11 +}; + +static static_codebook _44u7__p8_1 = { + 2, 121, + _vq_lengthlist__44u7__p8_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__44u7__p8_1, + NULL, + &_vq_auxt__44u7__p8_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u7__p9_0[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44u7__p9_0[] = { + 1, 3, 3,10,10,10,10,10,10,10,10, 4,10,10,10,10, + 10,10,10,10,10,10, 4,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, +}; + +static float _vq_quantthresh__44u7__p9_0[] = { + -2866.5, -2229.5, -1592.5, -955.5, -318.5, 318.5, 955.5, 1592.5, + 2229.5, 2866.5, +}; + +static long _vq_quantmap__44u7__p9_0[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44u7__p9_0 = { + _vq_quantthresh__44u7__p9_0, + _vq_quantmap__44u7__p9_0, + 11, + 11 +}; + +static static_codebook _44u7__p9_0 = { + 2, 121, + _vq_lengthlist__44u7__p9_0, + 1, -512171520, 1630791680, 4, 0, + _vq_quantlist__44u7__p9_0, + NULL, + &_vq_auxt__44u7__p9_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u7__p9_1[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44u7__p9_1[] = { + 1, 4, 4, 6, 5, 8, 6, 9, 8,10, 9,11,10, 4, 6, 6, + 8, 8, 9, 9,11,10,11,11,11,11, 4, 6, 6, 8, 8,10, + 9,11,11,11,11,11,12, 6, 8, 8,10,10,11,11,12,12, + 13,12,13,13, 6, 8, 8,10,10,11,11,12,12,12,13,14, + 13, 8,10,10,11,11,12,13,14,14,14,14,15,15, 8,10, + 10,11,12,12,13,13,14,14,14,14,15, 9,11,11,13,13, + 14,14,15,14,16,15,17,15, 9,11,11,12,13,14,14,15, + 14,15,15,15,16,10,12,12,13,14,15,15,15,15,16,17, + 16,17,10,13,12,13,14,14,16,16,16,16,15,16,17,11, + 13,13,14,15,14,17,15,16,17,17,17,17,11,13,13,14, + 15,15,15,15,17,17,16,17,16, +}; + +static float _vq_quantthresh__44u7__p9_1[] = { + -269.5, -220.5, -171.5, -122.5, -73.5, -24.5, 24.5, 73.5, + 122.5, 171.5, 220.5, 269.5, +}; + +static long _vq_quantmap__44u7__p9_1[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44u7__p9_1 = { + _vq_quantthresh__44u7__p9_1, + _vq_quantmap__44u7__p9_1, + 13, + 13 +}; + +static static_codebook _44u7__p9_1 = { + 2, 169, + _vq_lengthlist__44u7__p9_1, + 1, -518889472, 1622704128, 4, 0, + _vq_quantlist__44u7__p9_1, + NULL, + &_vq_auxt__44u7__p9_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u7__p9_2[] = { + 24, + 23, + 25, + 22, + 26, + 21, + 27, + 20, + 28, + 19, + 29, + 18, + 30, + 17, + 31, + 16, + 32, + 15, + 33, + 14, + 34, + 13, + 35, + 12, + 36, + 11, + 37, + 10, + 38, + 9, + 39, + 8, + 40, + 7, + 41, + 6, + 42, + 5, + 43, + 4, + 44, + 3, + 45, + 2, + 46, + 1, + 47, + 0, + 48, +}; + +static long _vq_lengthlist__44u7__p9_2[] = { + 2, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, + 8, +}; + +static float _vq_quantthresh__44u7__p9_2[] = { + -23.5, -22.5, -21.5, -20.5, -19.5, -18.5, -17.5, -16.5, + -15.5, -14.5, -13.5, -12.5, -11.5, -10.5, -9.5, -8.5, + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, + 8.5, 9.5, 10.5, 11.5, 12.5, 13.5, 14.5, 15.5, + 16.5, 17.5, 18.5, 19.5, 20.5, 21.5, 22.5, 23.5, +}; + +static long _vq_quantmap__44u7__p9_2[] = { + 47, 45, 43, 41, 39, 37, 35, 33, + 31, 29, 27, 25, 23, 21, 19, 17, + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, 18, 20, 22, 24, 26, 28, 30, + 32, 34, 36, 38, 40, 42, 44, 46, + 48, +}; + +static encode_aux_threshmatch _vq_auxt__44u7__p9_2 = { + _vq_quantthresh__44u7__p9_2, + _vq_quantmap__44u7__p9_2, + 49, + 49 +}; + +static static_codebook _44u7__p9_2 = { + 1, 49, + _vq_lengthlist__44u7__p9_2, + 1, -526909440, 1611661312, 6, 0, + _vq_quantlist__44u7__p9_2, + NULL, + &_vq_auxt__44u7__p9_2, + NULL, + 0 +}; + +static long _huff_lengthlist__44u7__short[] = { + 5,12,17,16,16,17,17,17,17,17, 4, 7,11,11,12, 9, + 17,10,17,17, 7, 7, 8, 9, 7, 9,11,10,15,17, 7, 9, + 10,11,10,12,14,12,16,17, 7, 8, 5, 7, 4, 7, 7, 8, + 16,16, 6,10, 9,10, 7,10,11,11,16,17, 6, 8, 8, 9, + 5, 7, 5, 8,16,17, 5, 5, 8, 7, 6, 7, 7, 6, 6,14, + 12,10,12,11, 7,11, 4, 4, 2, 7,17,15,15,15, 8,15, + 6, 8, 5, 9, +}; + +static static_codebook _huff_book__44u7__short = { + 2, 100, + _huff_lengthlist__44u7__short, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__44u8__long[] = { + 3, 9,13,14,14,15,14,14,15,15, 5, 4, 6, 8,10,12, + 12,14,15,15, 9, 5, 4, 5, 8,10,11,13,16,16,10, 7, + 4, 3, 5, 7, 9,11,13,13,10, 9, 7, 4, 4, 6, 8,10, + 12,14,13,11, 9, 6, 5, 5, 6, 8,12,14,13,11,10, 8, + 7, 6, 6, 7,10,14,13,11,12,10, 8, 7, 6, 6, 9,13, + 12,11,14,12,11, 9, 8, 7, 9,11,11,12,14,13,14,11, + 10, 8, 8, 9, +}; + +static static_codebook _huff_book__44u8__long = { + 2, 100, + _huff_lengthlist__44u8__long, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__44u8__short[] = { + 6,14,18,18,17,17,17,17,17,17, 4, 7, 9, 9,10,13, + 15,17,17,17, 6, 7, 5, 6, 8,11,16,17,16,17, 5, 7, + 5, 4, 6,10,14,17,17,17, 6, 6, 6, 5, 7,10,13,16, + 17,17, 7, 6, 7, 7, 7, 8, 7,10,15,16,12, 9, 9, 6, + 6, 5, 3, 5,11,15,14,14,13, 5, 5, 7, 3, 4, 8,15, + 17,17,13, 7, 7,10, 6, 6,10,15,17,17,16,10,11,14, + 10,10,15,17, +}; + +static static_codebook _huff_book__44u8__short = { + 2, 100, + _huff_lengthlist__44u8__short, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__44u8_p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44u8_p1_0[] = { + 1, 5, 5, 5, 7, 7, 5, 7, 7, 5, 7, 7, 8, 9, 9, 7, + 9, 9, 5, 7, 7, 7, 9, 9, 8, 9, 9, 5, 7, 7, 7, 9, + 9, 7, 9, 9, 7, 9, 9, 9,10,11, 9,11,10, 7, 9, 9, + 9,11,10, 9,10,11, 5, 7, 7, 7, 9, 9, 7, 9, 9, 7, + 9, 9, 9,11,10, 9,10,10, 8, 9, 9, 9,11,11, 9,11, + 10, +}; + +static float _vq_quantthresh__44u8_p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44u8_p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44u8_p1_0 = { + _vq_quantthresh__44u8_p1_0, + _vq_quantmap__44u8_p1_0, + 3, + 3 +}; + +static static_codebook _44u8_p1_0 = { + 4, 81, + _vq_lengthlist__44u8_p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44u8_p1_0, + NULL, + &_vq_auxt__44u8_p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u8_p2_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44u8_p2_0[] = { + 4, 5, 5, 8, 8, 5, 7, 6, 9, 9, 5, 6, 7, 9, 9, 8, + 9, 9,11,11, 8, 9, 9,11,11, 5, 7, 7, 9, 9, 7, 8, + 8,10,10, 7, 8, 8,10,10, 9,10,10,12,12, 9,10,10, + 11,12, 5, 7, 7, 9, 9, 7, 8, 7,10,10, 7, 8, 8,10, + 10, 9,10, 9,12,11, 9,10,10,12,12, 8, 9, 9,12,11, + 9,10,10,12,12, 9,10,10,12,12,11,12,12,14,14,11, + 11,12,13,14, 8, 9, 9,11,11, 9,10,10,12,12, 9,10, + 10,12,12,11,12,11,13,13,11,12,12,14,14, 5, 7, 7, + 9, 9, 7, 8, 8,10,10, 7, 8, 8,10,10, 9,10,10,12, + 12, 9,10,10,11,12, 7, 8, 8,10,10, 8, 9, 9,11,11, + 8, 9, 9,11,11,10,11,11,12,13,10,11,11,12,13, 6, + 8, 8,10,10, 8, 9, 8,11,10, 8, 9, 9,11,11,10,11, + 10,13,12,10,11,11,13,13, 9,10,10,12,12,10,11,11, + 13,13,10,11,11,13,13,12,12,13,13,14,12,13,13,14, + 14, 9,10,10,12,12,10,11,10,13,12,10,11,11,13,13, + 11,13,12,14,13,12,13,13,14,14, 5, 7, 7, 9, 9, 7, + 8, 8,10,10, 7, 8, 8,10,10, 9,10,10,12,12, 9,10, + 10,12,12, 7, 8, 8,10,10, 8, 9, 9,11,11, 8, 8, 9, + 10,11,10,11,11,13,13,10,10,11,12,13, 7, 8, 8,10, + 10, 8, 9, 9,11,11, 8, 9, 9,11,11,10,11,11,13,13, + 10,11,11,13,12, 9,10,10,12,12,10,11,11,13,13,10, + 10,11,12,13,12,13,13,14,14,12,12,13,13,14, 9,10, + 10,12,12,10,11,11,13,13,10,11,11,13,13,12,13,13, + 15,14,12,13,13,14,13, 8, 9, 9,11,11, 9,10,10,12, + 12, 9,10,10,12,12,12,12,12,14,13,11,12,12,14,14, + 9,10,10,12,12,10,11,11,13,13,10,11,11,13,13,12, + 13,13,14,15,12,13,13,14,15, 9,10,10,12,12,10,11, + 10,13,12,10,11,11,13,13,12,13,12,15,14,12,13,13, + 14,15,11,12,12,14,14,12,13,13,14,14,12,13,13,15, + 14,14,14,14,14,16,14,14,15,16,16,11,12,12,14,14, + 11,12,12,14,14,12,13,13,14,15,13,14,13,16,14,14, + 14,14,16,16, 8, 9, 9,11,11, 9,10,10,12,12, 9,10, + 10,12,12,11,12,12,14,13,11,12,12,14,14, 9,10,10, + 12,12,10,11,11,13,13,10,10,11,12,13,12,13,13,15, + 14,12,12,13,13,14, 9,10,10,12,12,10,11,11,13,13, + 10,11,11,13,13,12,13,13,14,14,12,13,13,15,14,11, + 12,12,14,13,12,13,13,15,14,11,12,12,13,14,14,15, + 14,16,15,13,13,14,13,16,11,12,12,14,14,12,13,13, + 14,15,12,13,12,15,14,14,14,14,16,15,14,15,13,16, + 14, +}; + +static float _vq_quantthresh__44u8_p2_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44u8_p2_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44u8_p2_0 = { + _vq_quantthresh__44u8_p2_0, + _vq_quantmap__44u8_p2_0, + 5, + 5 +}; + +static static_codebook _44u8_p2_0 = { + 4, 625, + _vq_lengthlist__44u8_p2_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44u8_p2_0, + NULL, + &_vq_auxt__44u8_p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u8_p3_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44u8_p3_0[] = { + 3, 4, 4, 5, 5, 7, 7, 9, 9, 4, 5, 4, 6, 6, 7, 7, + 9, 9, 4, 4, 5, 6, 6, 7, 7, 9, 9, 5, 6, 6, 7, 7, + 8, 8,10,10, 6, 6, 6, 7, 7, 8, 8,10,10, 7, 7, 7, + 8, 8, 9, 9,11,10, 7, 7, 7, 8, 8, 9, 9,10,11, 9, + 9, 9,10,10,11,10,12,11, 9, 9, 9, 9,10,11,11,11, + 12, +}; + +static float _vq_quantthresh__44u8_p3_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44u8_p3_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44u8_p3_0 = { + _vq_quantthresh__44u8_p3_0, + _vq_quantmap__44u8_p3_0, + 9, + 9 +}; + +static static_codebook _44u8_p3_0 = { + 2, 81, + _vq_lengthlist__44u8_p3_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44u8_p3_0, + NULL, + &_vq_auxt__44u8_p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u8_p4_0[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44u8_p4_0[] = { + 4, 4, 4, 6, 6, 7, 7, 8, 8, 8, 8,10,10,11,11,11, + 11, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,10,10,11,11, + 12,12, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,10,10,11, + 11,12,12, 6, 6, 6, 7, 7, 8, 8, 9, 9, 9, 9,10,10, + 11,11,12,12, 6, 6, 6, 7, 7, 8, 8, 9, 9, 9, 9,10, + 10,11,11,12,12, 7, 7, 7, 8, 8, 9, 8,10, 9,10, 9, + 11,10,12,11,13,12, 7, 7, 7, 8, 8, 8, 9, 9,10, 9, + 10,10,11,11,12,12,13, 8, 8, 8, 9, 9, 9, 9,10,10, + 11,10,11,11,12,12,13,13, 8, 8, 8, 9, 9, 9,10,10, + 10,10,11,11,11,12,12,12,13, 8, 9, 9, 9, 9,10, 9, + 11,10,11,11,12,11,13,12,13,13, 8, 9, 9, 9, 9, 9, + 10,10,11,11,11,11,12,12,13,13,13,10,10,10,10,10, + 11,10,11,11,12,11,13,12,13,13,14,13,10,10,10,10, + 10,10,11,11,11,11,12,12,13,13,13,13,14,11,11,11, + 11,11,12,11,12,12,13,12,13,13,14,13,14,14,11,11, + 11,11,11,11,12,12,12,12,13,13,13,13,14,14,14,11, + 12,12,12,12,13,12,13,12,13,13,14,13,14,14,14,14, + 11,12,12,12,12,12,12,13,13,13,13,13,14,14,14,14, + 14, +}; + +static float _vq_quantthresh__44u8_p4_0[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__44u8_p4_0[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44u8_p4_0 = { + _vq_quantthresh__44u8_p4_0, + _vq_quantmap__44u8_p4_0, + 17, + 17 +}; + +static static_codebook _44u8_p4_0 = { + 2, 289, + _vq_lengthlist__44u8_p4_0, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__44u8_p4_0, + NULL, + &_vq_auxt__44u8_p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u8_p5_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44u8_p5_0[] = { + 1, 4, 4, 5, 7, 7, 5, 7, 7, 5, 8, 8, 8, 9, 9, 7, + 9, 9, 5, 8, 8, 7, 9, 9, 8, 9, 9, 5, 8, 8, 8,10, + 10, 8,10,10, 7,10,10, 9,10,12, 9,12,11, 7,10,10, + 9,11,10, 9,11,12, 5, 8, 8, 8,10,10, 8,10,10, 7, + 10,10, 9,11,11, 9,10,11, 7,10,10, 9,11,11,10,12, + 10, +}; + +static float _vq_quantthresh__44u8_p5_0[] = { + -5.5, 5.5, +}; + +static long _vq_quantmap__44u8_p5_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44u8_p5_0 = { + _vq_quantthresh__44u8_p5_0, + _vq_quantmap__44u8_p5_0, + 3, + 3 +}; + +static static_codebook _44u8_p5_0 = { + 4, 81, + _vq_lengthlist__44u8_p5_0, + 1, -529137664, 1618345984, 2, 0, + _vq_quantlist__44u8_p5_0, + NULL, + &_vq_auxt__44u8_p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u8_p5_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44u8_p5_1[] = { + 4, 5, 5, 6, 6, 7, 7, 7, 7, 8, 8, 5, 5, 5, 6, 6, + 7, 7, 8, 8, 8, 8, 5, 5, 5, 6, 6, 7, 7, 7, 8, 8, + 8, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 6, 6, 6, 7, + 7, 7, 7, 8, 8, 8, 8, 7, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 8, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 7, 8, 7, + 8, 8, 8, 8, 8, 8, 8, 8, 7, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 9, 9, +}; + +static float _vq_quantthresh__44u8_p5_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__44u8_p5_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44u8_p5_1 = { + _vq_quantthresh__44u8_p5_1, + _vq_quantmap__44u8_p5_1, + 11, + 11 +}; + +static static_codebook _44u8_p5_1 = { + 2, 121, + _vq_lengthlist__44u8_p5_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__44u8_p5_1, + NULL, + &_vq_auxt__44u8_p5_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u8_p6_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44u8_p6_0[] = { + 2, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9,10,10, 4, 6, 5, + 7, 7, 8, 8, 8, 8, 9, 9,10,10, 4, 6, 6, 7, 7, 8, + 8, 8, 8, 9, 9,10,10, 6, 7, 7, 7, 8, 8, 8, 8, 9, + 9,10,10,10, 6, 7, 7, 8, 8, 8, 8, 9, 8,10, 9,11, + 10, 7, 8, 8, 8, 8, 8, 9, 9, 9,10,10,11,11, 7, 8, + 8, 8, 8, 9, 8, 9, 9,10,10,11,11, 8, 8, 8, 9, 9, + 9, 9, 9,10,10,10,11,11, 8, 8, 8, 9, 9, 9, 9,10, + 9,10,10,11,11, 9, 9, 9, 9,10,10,10,10,10,10,11, + 11,12, 9, 9, 9,10, 9,10,10,10,10,11,10,12,11,10, + 10,10,10,10,11,11,11,11,11,12,12,12,10,10,10,10, + 11,11,11,11,11,12,11,12,12, +}; + +static float _vq_quantthresh__44u8_p6_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__44u8_p6_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44u8_p6_0 = { + _vq_quantthresh__44u8_p6_0, + _vq_quantmap__44u8_p6_0, + 13, + 13 +}; + +static static_codebook _44u8_p6_0 = { + 2, 169, + _vq_lengthlist__44u8_p6_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__44u8_p6_0, + NULL, + &_vq_auxt__44u8_p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u8_p6_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44u8_p6_1[] = { + 3, 4, 4, 5, 5, 4, 5, 5, 5, 5, 4, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, +}; + +static float _vq_quantthresh__44u8_p6_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44u8_p6_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44u8_p6_1 = { + _vq_quantthresh__44u8_p6_1, + _vq_quantmap__44u8_p6_1, + 5, + 5 +}; + +static static_codebook _44u8_p6_1 = { + 2, 25, + _vq_lengthlist__44u8_p6_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44u8_p6_1, + NULL, + &_vq_auxt__44u8_p6_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u8_p7_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44u8_p7_0[] = { + 1, 4, 5, 6, 6, 7, 7, 8, 8,10,10,11,11, 5, 6, 6, + 7, 7, 8, 8, 9, 9,11,10,12,11, 5, 6, 6, 7, 7, 8, + 8, 9, 9,10,11,11,12, 6, 7, 7, 8, 8, 9, 9,10,10, + 11,11,12,12, 6, 7, 7, 8, 8, 9, 9,10,10,11,12,13, + 12, 7, 8, 8, 9, 9,10,10,11,11,12,12,13,13, 8, 8, + 8, 9, 9,10,10,11,11,12,12,13,13, 9, 9, 9,10,10, + 11,11,12,12,13,13,14,14, 9, 9, 9,10,10,11,11,12, + 12,13,13,14,14,10,11,11,12,11,13,12,13,13,14,14, + 15,15,10,11,11,11,12,12,13,13,14,14,14,15,15,11, + 12,12,13,13,14,13,15,14,15,15,16,15,11,11,12,13, + 13,13,14,14,14,15,15,15,16, +}; + +static float _vq_quantthresh__44u8_p7_0[] = { + -60.5, -49.5, -38.5, -27.5, -16.5, -5.5, 5.5, 16.5, + 27.5, 38.5, 49.5, 60.5, +}; + +static long _vq_quantmap__44u8_p7_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44u8_p7_0 = { + _vq_quantthresh__44u8_p7_0, + _vq_quantmap__44u8_p7_0, + 13, + 13 +}; + +static static_codebook _44u8_p7_0 = { + 2, 169, + _vq_lengthlist__44u8_p7_0, + 1, -523206656, 1618345984, 4, 0, + _vq_quantlist__44u8_p7_0, + NULL, + &_vq_auxt__44u8_p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u8_p7_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44u8_p7_1[] = { + 4, 5, 5, 6, 6, 7, 7, 7, 7, 7, 7, 5, 6, 6, 7, 7, + 7, 7, 7, 7, 7, 7, 5, 6, 6, 7, 7, 7, 7, 7, 7, 7, + 7, 6, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 6, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 8, 7, 7, 7, 7, 7, 7, 7, 8, 8, + 8, 8, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 7, 7, 7, + 8, 7, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 8, 8, 8, + 8, 8, 8, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, + 7, 8, 8, 8, 8, 8, 8, 8, 8, +}; + +static float _vq_quantthresh__44u8_p7_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__44u8_p7_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44u8_p7_1 = { + _vq_quantthresh__44u8_p7_1, + _vq_quantmap__44u8_p7_1, + 11, + 11 +}; + +static static_codebook _44u8_p7_1 = { + 2, 121, + _vq_lengthlist__44u8_p7_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__44u8_p7_1, + NULL, + &_vq_auxt__44u8_p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u8_p8_0[] = { + 7, + 6, + 8, + 5, + 9, + 4, + 10, + 3, + 11, + 2, + 12, + 1, + 13, + 0, + 14, +}; + +static long _vq_lengthlist__44u8_p8_0[] = { + 1, 4, 4, 7, 7, 8, 8, 8, 7, 9, 8,10, 9,11,10, 4, + 6, 6, 8, 8,10, 9, 9, 9,10,10,11,10,12,10, 4, 6, + 6, 8, 8,10,10, 9, 9,10,10,11,11,11,12, 7, 8, 8, + 10,10,11,11,11,10,12,11,12,12,13,11, 7, 8, 8,10, + 10,11,11,10,10,11,11,12,12,13,13, 8,10,10,11,11, + 12,11,12,11,13,12,13,12,14,13, 8,10, 9,11,11,12, + 12,12,12,12,12,13,13,14,13, 8, 9, 9,11,10,12,11, + 13,12,13,13,14,13,14,13, 8, 9, 9,10,11,12,12,12, + 12,13,13,14,15,14,14, 9,10,10,12,11,13,12,13,13, + 14,13,14,14,14,14, 9,10,10,12,12,12,12,13,13,14, + 14,14,15,14,14,10,11,11,13,12,13,12,14,14,14,14, + 14,14,15,15,10,11,11,12,12,13,13,14,14,14,15,15, + 14,16,15,11,12,12,13,12,14,14,14,13,15,14,15,15, + 15,17,11,12,12,13,13,14,14,14,15,15,14,15,15,14, + 17, +}; + +static float _vq_quantthresh__44u8_p8_0[] = { + -136.5, -115.5, -94.5, -73.5, -52.5, -31.5, -10.5, 10.5, + 31.5, 52.5, 73.5, 94.5, 115.5, 136.5, +}; + +static long _vq_quantmap__44u8_p8_0[] = { + 13, 11, 9, 7, 5, 3, 1, 0, + 2, 4, 6, 8, 10, 12, 14, +}; + +static encode_aux_threshmatch _vq_auxt__44u8_p8_0 = { + _vq_quantthresh__44u8_p8_0, + _vq_quantmap__44u8_p8_0, + 15, + 15 +}; + +static static_codebook _44u8_p8_0 = { + 2, 225, + _vq_lengthlist__44u8_p8_0, + 1, -520986624, 1620377600, 4, 0, + _vq_quantlist__44u8_p8_0, + NULL, + &_vq_auxt__44u8_p8_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u8_p8_1[] = { + 10, + 9, + 11, + 8, + 12, + 7, + 13, + 6, + 14, + 5, + 15, + 4, + 16, + 3, + 17, + 2, + 18, + 1, + 19, + 0, + 20, +}; + +static long _vq_lengthlist__44u8_p8_1[] = { + 4, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 6, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 5, 6, 6, 7, 7, 8, + 8, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 7, + 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10, 9,10, 8, 8, + 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10, 9,10, + 10, 9,10, 8, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9,10, 9, + 10,10,10,10,10,10,10,10, 8, 9, 8, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9,10,10,10,10, 9,10,10, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9,10, 9,10,10,10,10,10,10, + 10,10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10, 9,10, + 10,10,10,10,10,10,10, 9, 9, 9, 9, 9, 9, 9,10, 9, + 10,10,10,10,10,10,10,10,10,10,10,10, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9,10,10,10,10,10,10,10,10,10,10, + 10, 9, 9, 9, 9, 9, 9,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10, 9, 9, 9, 9, 9, 9, 9,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10, 9, 9, 9, 9, 9, + 9, 9,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 9, 9, 9, 9, 9,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10, 9, 9, 9,10, 9,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10, 9, 9, 9, 9, 9,10, + 9,10,10,10,10,10,10,10,10,10,10,10,10,10,10, 9, + 9, 9, 9, 9, 9,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10, 9, 9, 9,10, 9,10, 9,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10, +}; + +static float _vq_quantthresh__44u8_p8_1[] = { + -9.5, -8.5, -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, + -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, + 6.5, 7.5, 8.5, 9.5, +}; + +static long _vq_quantmap__44u8_p8_1[] = { + 19, 17, 15, 13, 11, 9, 7, 5, + 3, 1, 0, 2, 4, 6, 8, 10, + 12, 14, 16, 18, 20, +}; + +static encode_aux_threshmatch _vq_auxt__44u8_p8_1 = { + _vq_quantthresh__44u8_p8_1, + _vq_quantmap__44u8_p8_1, + 21, + 21 +}; + +static static_codebook _44u8_p8_1 = { + 2, 441, + _vq_lengthlist__44u8_p8_1, + 1, -529268736, 1611661312, 5, 0, + _vq_quantlist__44u8_p8_1, + NULL, + &_vq_auxt__44u8_p8_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u8_p9_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44u8_p9_0[] = { + 1, 3, 3, 9, 9, 9, 9, 9, 9, 4, 9, 9, 9, 9, 9, 9, + 9, 9, 5, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, + 8, +}; + +static float _vq_quantthresh__44u8_p9_0[] = { + -3258.5, -2327.5, -1396.5, -465.5, 465.5, 1396.5, 2327.5, 3258.5, +}; + +static long _vq_quantmap__44u8_p9_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44u8_p9_0 = { + _vq_quantthresh__44u8_p9_0, + _vq_quantmap__44u8_p9_0, + 9, + 9 +}; + +static static_codebook _44u8_p9_0 = { + 2, 81, + _vq_lengthlist__44u8_p9_0, + 1, -511895552, 1631393792, 4, 0, + _vq_quantlist__44u8_p9_0, + NULL, + &_vq_auxt__44u8_p9_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u8_p9_1[] = { + 9, + 8, + 10, + 7, + 11, + 6, + 12, + 5, + 13, + 4, + 14, + 3, + 15, + 2, + 16, + 1, + 17, + 0, + 18, +}; + +static long _vq_lengthlist__44u8_p9_1[] = { + 1, 4, 4, 7, 7, 8, 7, 8, 6, 9, 7,10, 8,11,10,11, + 11,11,11, 4, 7, 6, 9, 9,10, 9, 9, 9,10,10,11,10, + 11,10,11,11,13,11, 4, 7, 7, 9, 9, 9, 9, 9, 9,10, + 10,11,10,11,11,11,12,11,12, 7, 9, 8,11,11,11,11, + 10,10,11,11,12,12,12,12,12,12,14,13, 7, 8, 9,10, + 11,11,11,10,10,11,11,11,11,12,12,14,12,13,14, 8, + 9, 9,11,11,11,11,11,11,12,12,14,12,15,14,14,14, + 15,14, 8, 9, 9,11,11,11,11,12,11,12,12,13,13,13, + 13,13,13,14,14, 8, 9, 9,11,10,12,11,12,12,13,13, + 13,13,15,14,14,14,16,16, 8, 9, 9,10,11,11,12,12, + 12,13,13,13,14,14,14,15,16,15,15, 9,10,10,11,12, + 12,13,13,13,14,14,16,14,14,16,16,16,16,15, 9,10, + 10,11,11,12,13,13,14,15,14,16,14,15,16,16,16,16, + 15,10,11,11,12,13,13,14,15,15,15,15,15,16,15,16, + 15,16,15,15,10,11,11,13,13,14,13,13,15,14,15,15, + 16,15,15,15,16,15,16,10,12,12,14,14,14,14,14,16, + 16,15,15,15,16,16,16,16,16,16,11,12,12,14,14,14, + 14,15,15,16,15,16,15,16,15,16,16,16,16,12,12,13, + 14,14,15,16,16,16,16,16,16,15,16,16,16,16,16,16, + 12,13,13,14,14,14,14,15,16,15,16,16,16,16,16,16, + 16,16,16,12,13,14,14,14,16,15,16,15,16,16,16,16, + 16,16,16,16,16,16,12,14,13,14,15,15,15,16,15,16, + 16,15,16,16,16,16,16,16,16, +}; + +static float _vq_quantthresh__44u8_p9_1[] = { + -416.5, -367.5, -318.5, -269.5, -220.5, -171.5, -122.5, -73.5, + -24.5, 24.5, 73.5, 122.5, 171.5, 220.5, 269.5, 318.5, + 367.5, 416.5, +}; + +static long _vq_quantmap__44u8_p9_1[] = { + 17, 15, 13, 11, 9, 7, 5, 3, + 1, 0, 2, 4, 6, 8, 10, 12, + 14, 16, 18, +}; + +static encode_aux_threshmatch _vq_auxt__44u8_p9_1 = { + _vq_quantthresh__44u8_p9_1, + _vq_quantmap__44u8_p9_1, + 19, + 19 +}; + +static static_codebook _44u8_p9_1 = { + 2, 361, + _vq_lengthlist__44u8_p9_1, + 1, -518287360, 1622704128, 5, 0, + _vq_quantlist__44u8_p9_1, + NULL, + &_vq_auxt__44u8_p9_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u8_p9_2[] = { + 24, + 23, + 25, + 22, + 26, + 21, + 27, + 20, + 28, + 19, + 29, + 18, + 30, + 17, + 31, + 16, + 32, + 15, + 33, + 14, + 34, + 13, + 35, + 12, + 36, + 11, + 37, + 10, + 38, + 9, + 39, + 8, + 40, + 7, + 41, + 6, + 42, + 5, + 43, + 4, + 44, + 3, + 45, + 2, + 46, + 1, + 47, + 0, + 48, +}; + +static long _vq_lengthlist__44u8_p9_2[] = { + 2, 3, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, +}; + +static float _vq_quantthresh__44u8_p9_2[] = { + -23.5, -22.5, -21.5, -20.5, -19.5, -18.5, -17.5, -16.5, + -15.5, -14.5, -13.5, -12.5, -11.5, -10.5, -9.5, -8.5, + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, + 8.5, 9.5, 10.5, 11.5, 12.5, 13.5, 14.5, 15.5, + 16.5, 17.5, 18.5, 19.5, 20.5, 21.5, 22.5, 23.5, +}; + +static long _vq_quantmap__44u8_p9_2[] = { + 47, 45, 43, 41, 39, 37, 35, 33, + 31, 29, 27, 25, 23, 21, 19, 17, + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, 18, 20, 22, 24, 26, 28, 30, + 32, 34, 36, 38, 40, 42, 44, 46, + 48, +}; + +static encode_aux_threshmatch _vq_auxt__44u8_p9_2 = { + _vq_quantthresh__44u8_p9_2, + _vq_quantmap__44u8_p9_2, + 49, + 49 +}; + +static static_codebook _44u8_p9_2 = { + 1, 49, + _vq_lengthlist__44u8_p9_2, + 1, -526909440, 1611661312, 6, 0, + _vq_quantlist__44u8_p9_2, + NULL, + &_vq_auxt__44u8_p9_2, + NULL, + 0 +}; + +static long _huff_lengthlist__44u9__long[] = { + 3, 9,13,13,14,15,14,14,15,15, 5, 5, 9,10,12,12, + 13,14,16,15,10, 6, 6, 6, 8,11,12,13,16,15,11, 7, + 5, 3, 5, 8,10,12,15,15,10,10, 7, 4, 3, 5, 8,10, + 12,12,12,12, 9, 7, 5, 4, 6, 8,10,13,13,12,11, 9, + 7, 5, 5, 6, 9,12,14,12,12,10, 8, 6, 6, 6, 7,11, + 13,12,14,13,10, 8, 7, 7, 7,10,11,11,12,13,12,11, + 10, 8, 8, 9, +}; + +static static_codebook _huff_book__44u9__long = { + 2, 100, + _huff_lengthlist__44u9__long, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _huff_lengthlist__44u9__short[] = { + 9,16,18,18,17,17,17,17,17,17, 5, 8,11,12,11,12, + 17,17,16,16, 6, 6, 8, 8, 9,10,14,15,16,16, 6, 7, + 7, 4, 6, 9,13,16,16,16, 6, 6, 7, 4, 5, 8,11,15, + 17,16, 7, 6, 7, 6, 6, 8, 9,10,14,16,11, 8, 8, 7, + 6, 6, 3, 4,10,15,14,12,12,10, 5, 6, 3, 3, 8,13, + 15,17,15,11, 6, 8, 6, 6, 9,14,17,15,15,12, 8,10, + 9, 9,12,15, +}; + +static static_codebook _huff_book__44u9__short = { + 2, 100, + _huff_lengthlist__44u9__short, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__44u9_p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44u9_p1_0[] = { + 1, 5, 5, 5, 7, 7, 5, 7, 7, 5, 7, 7, 7, 9, 9, 7, + 9, 9, 5, 7, 7, 7, 9, 9, 7, 9, 9, 5, 7, 7, 7, 9, + 9, 7, 9, 9, 8, 9, 9, 9,10,11, 9,11,11, 7, 9, 9, + 9,11,10, 9,11,11, 5, 7, 7, 7, 9, 9, 8, 9,10, 7, + 9, 9, 9,11,11, 9,10,11, 7, 9,10, 9,11,11, 9,11, + 10, +}; + +static float _vq_quantthresh__44u9_p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44u9_p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44u9_p1_0 = { + _vq_quantthresh__44u9_p1_0, + _vq_quantmap__44u9_p1_0, + 3, + 3 +}; + +static static_codebook _44u9_p1_0 = { + 4, 81, + _vq_lengthlist__44u9_p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44u9_p1_0, + NULL, + &_vq_auxt__44u9_p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u9_p2_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44u9_p2_0[] = { + 3, 5, 5, 8, 8, 5, 7, 7, 9, 9, 6, 7, 7, 9, 9, 8, + 9, 9,11,10, 8, 9, 9,11,11, 6, 7, 7, 9, 9, 7, 8, + 8,10,10, 7, 8, 8, 9,10, 9,10,10,11,11, 9, 9,10, + 11,11, 6, 7, 7, 9, 9, 7, 8, 8,10, 9, 7, 8, 8,10, + 10, 9,10, 9,11,11, 9,10,10,11,11, 8, 9, 9,11,11, + 9,10,10,12,11, 9,10,10,11,12,11,11,11,13,13,11, + 11,11,12,13, 8, 9, 9,11,11, 9,10,10,11,11, 9,10, + 10,12,11,11,12,11,13,12,11,11,12,13,13, 6, 7, 7, + 9, 9, 7, 8, 8,10,10, 7, 8, 8,10,10, 9,10,10,12, + 11, 9,10,10,11,12, 7, 8, 8,10,10, 8, 9, 9,11,11, + 8, 9, 9,10,10,10,11,11,12,12,10,10,11,12,12, 7, + 8, 8,10,10, 8, 9, 8,10,10, 8, 9, 9,10,10,10,11, + 10,12,11,10,10,11,12,12, 9,10,10,11,12,10,11,11, + 12,12,10,11,10,12,12,12,12,12,13,13,11,12,12,13, + 13, 9,10,10,11,11, 9,10,10,12,12,10,11,11,12,13, + 11,12,11,13,12,12,12,12,13,14, 6, 7, 7, 9, 9, 7, + 8, 8,10,10, 7, 8, 8,10,10, 9,10,10,11,11, 9,10, + 10,11,12, 7, 8, 8,10,10, 8, 9, 9,11,10, 8, 8, 9, + 10,10,10,11,10,12,12,10,10,11,11,12, 7, 8, 8,10, + 10, 8, 9, 9,10,10, 8, 9, 9,10,10,10,11,10,12,12, + 10,11,10,12,12, 9,10,10,12,11,10,11,11,12,12, 9, + 10,10,12,12,12,12,12,13,13,11,11,12,12,14, 9,10, + 10,11,12,10,11,11,12,12,10,11,11,12,12,11,12,12, + 14,14,12,12,12,13,13, 8, 9, 9,11,11, 9,10,10,12, + 11, 9,10,10,12,12,11,12,11,13,13,11,11,12,13,13, + 9,10,10,12,12,10,11,11,12,12,10,11,11,12,12,12, + 12,12,14,14,12,12,12,13,13, 9,10,10,12,11,10,11, + 10,12,12,10,11,11,12,12,11,12,12,14,13,12,12,12, + 13,14,11,12,11,13,13,11,12,12,13,13,12,12,12,14, + 14,13,13,13,13,15,13,13,14,15,15,11,11,11,13,13, + 11,12,11,13,13,11,12,12,13,13,12,13,12,15,13,13, + 13,14,14,15, 8, 9, 9,11,11, 9,10,10,11,12, 9,10, + 10,11,12,11,12,11,13,13,11,12,12,13,13, 9,10,10, + 11,12,10,11,10,12,12,10,10,11,12,13,12,12,12,14, + 13,11,12,12,13,14, 9,10,10,12,12,10,11,11,12,12, + 10,11,11,12,12,12,12,12,14,13,12,12,12,14,13,11, + 11,11,13,13,11,12,12,14,13,11,11,12,13,13,13,13, + 13,15,14,12,12,13,13,15,11,12,12,13,13,12,12,12, + 13,14,11,12,12,13,13,13,13,14,14,15,13,13,13,14, + 14, +}; + +static float _vq_quantthresh__44u9_p2_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44u9_p2_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44u9_p2_0 = { + _vq_quantthresh__44u9_p2_0, + _vq_quantmap__44u9_p2_0, + 5, + 5 +}; + +static static_codebook _44u9_p2_0 = { + 4, 625, + _vq_lengthlist__44u9_p2_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44u9_p2_0, + NULL, + &_vq_auxt__44u9_p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u9_p3_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44u9_p3_0[] = { + 3, 4, 4, 5, 5, 7, 7, 8, 8, 4, 5, 5, 6, 6, 7, 7, + 9, 9, 4, 4, 5, 6, 6, 7, 7, 9, 9, 5, 6, 6, 7, 7, + 8, 8, 9, 9, 5, 6, 6, 7, 7, 8, 8, 9, 9, 7, 7, 7, + 8, 8, 9, 9,10,10, 7, 7, 7, 8, 8, 9, 9,10,10, 8, + 9, 9,10, 9,10,10,11,11, 8, 9, 9, 9,10,10,10,11, + 11, +}; + +static float _vq_quantthresh__44u9_p3_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44u9_p3_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44u9_p3_0 = { + _vq_quantthresh__44u9_p3_0, + _vq_quantmap__44u9_p3_0, + 9, + 9 +}; + +static static_codebook _44u9_p3_0 = { + 2, 81, + _vq_lengthlist__44u9_p3_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44u9_p3_0, + NULL, + &_vq_auxt__44u9_p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u9_p4_0[] = { + 8, + 7, + 9, + 6, + 10, + 5, + 11, + 4, + 12, + 3, + 13, + 2, + 14, + 1, + 15, + 0, + 16, +}; + +static long _vq_lengthlist__44u9_p4_0[] = { + 4, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,10,10,11, + 11, 5, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,10,10, + 11,11, 5, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,10, + 10,11,11, 6, 6, 6, 7, 6, 7, 7, 8, 8, 9, 9,10,10, + 11,11,12,11, 6, 6, 6, 6, 7, 7, 7, 8, 8, 9, 9,10, + 10,11,11,11,12, 7, 7, 7, 7, 7, 8, 8, 9, 9, 9, 9, + 10,10,11,11,12,12, 7, 7, 7, 7, 7, 8, 8, 9, 9, 9, + 9,10,10,11,11,12,12, 8, 8, 8, 8, 8, 9, 8,10, 9, + 10,10,11,10,12,11,13,12, 8, 8, 8, 8, 8, 9, 9, 9, + 10,10,10,10,11,11,12,12,12, 8, 8, 8, 9, 9, 9, 9, + 10,10,11,10,12,11,12,12,13,12, 8, 8, 8, 9, 9, 9, + 9,10,10,10,11,11,11,12,12,12,13, 9, 9, 9,10,10, + 10,10,11,10,11,11,12,11,13,12,13,13, 9, 9,10,10, + 10,10,10,10,11,11,11,11,12,12,13,13,13,10,11,10, + 11,11,11,11,12,11,12,12,13,12,13,13,14,13,10,10, + 10,11,11,11,11,11,12,12,12,12,13,13,13,13,14,11, + 11,11,12,11,12,12,12,12,13,13,13,13,14,13,14,14, + 11,11,11,11,12,12,12,12,12,12,13,13,13,13,14,14, + 14, +}; + +static float _vq_quantthresh__44u9_p4_0[] = { + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, +}; + +static long _vq_quantmap__44u9_p4_0[] = { + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, +}; + +static encode_aux_threshmatch _vq_auxt__44u9_p4_0 = { + _vq_quantthresh__44u9_p4_0, + _vq_quantmap__44u9_p4_0, + 17, + 17 +}; + +static static_codebook _44u9_p4_0 = { + 2, 289, + _vq_lengthlist__44u9_p4_0, + 1, -529530880, 1611661312, 5, 0, + _vq_quantlist__44u9_p4_0, + NULL, + &_vq_auxt__44u9_p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u9_p5_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44u9_p5_0[] = { + 1, 4, 4, 5, 7, 7, 5, 7, 7, 5, 8, 8, 8, 9, 9, 7, + 9, 9, 5, 8, 8, 7, 9, 9, 8, 9, 9, 5, 8, 8, 8,10, + 10, 8,10,10, 7,10,10, 9,10,12, 9,11,11, 7,10,10, + 9,11,10, 9,11,12, 5, 8, 8, 8,10,10, 8,10,10, 7, + 10,10, 9,12,11, 9,10,11, 7,10,10, 9,11,11,10,12, + 10, +}; + +static float _vq_quantthresh__44u9_p5_0[] = { + -5.5, 5.5, +}; + +static long _vq_quantmap__44u9_p5_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44u9_p5_0 = { + _vq_quantthresh__44u9_p5_0, + _vq_quantmap__44u9_p5_0, + 3, + 3 +}; + +static static_codebook _44u9_p5_0 = { + 4, 81, + _vq_lengthlist__44u9_p5_0, + 1, -529137664, 1618345984, 2, 0, + _vq_quantlist__44u9_p5_0, + NULL, + &_vq_auxt__44u9_p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u9_p5_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44u9_p5_1[] = { + 5, 5, 5, 6, 6, 7, 7, 7, 7, 7, 7, 5, 6, 6, 6, 6, + 7, 7, 7, 7, 8, 7, 5, 6, 6, 6, 6, 7, 7, 7, 7, 7, + 7, 6, 6, 6, 7, 7, 7, 7, 7, 7, 8, 8, 6, 6, 6, 7, + 7, 7, 7, 7, 7, 8, 8, 7, 7, 7, 7, 7, 8, 7, 8, 8, + 8, 8, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 7, 7, 7, + 8, 7, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 8, 8, 7, 8, 7, 8, 8, 8, 8, 8, 8, 8, 8, 7, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, +}; + +static float _vq_quantthresh__44u9_p5_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__44u9_p5_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44u9_p5_1 = { + _vq_quantthresh__44u9_p5_1, + _vq_quantmap__44u9_p5_1, + 11, + 11 +}; + +static static_codebook _44u9_p5_1 = { + 2, 121, + _vq_lengthlist__44u9_p5_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__44u9_p5_1, + NULL, + &_vq_auxt__44u9_p5_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u9_p6_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44u9_p6_0[] = { + 2, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9,10,10, 4, 6, 5, + 7, 7, 8, 8, 8, 8, 9, 9,10,10, 4, 5, 6, 7, 7, 8, + 8, 8, 8, 9, 9,10,10, 6, 7, 7, 8, 8, 8, 8, 9, 9, + 10,10,10,10, 6, 7, 7, 8, 8, 8, 8, 9, 9,10,10,10, + 10, 7, 8, 8, 8, 8, 9, 9, 9, 9,10,10,11,11, 7, 8, + 8, 8, 8, 9, 9, 9, 9,10,10,11,11, 8, 8, 8, 9, 9, + 9, 9, 9,10,10,10,11,11, 8, 8, 8, 9, 9, 9, 9,10, + 9,10,10,11,11, 9, 9, 9,10,10,10,10,10,11,11,11, + 11,12, 9, 9, 9,10,10,10,10,10,10,11,10,12,11,10, + 10,10,10,10,11,11,11,11,11,12,12,12,10,10,10,10, + 10,11,11,11,11,12,11,12,12, +}; + +static float _vq_quantthresh__44u9_p6_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__44u9_p6_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44u9_p6_0 = { + _vq_quantthresh__44u9_p6_0, + _vq_quantmap__44u9_p6_0, + 13, + 13 +}; + +static static_codebook _44u9_p6_0 = { + 2, 169, + _vq_lengthlist__44u9_p6_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__44u9_p6_0, + NULL, + &_vq_auxt__44u9_p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u9_p6_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44u9_p6_1[] = { + 4, 4, 4, 5, 5, 4, 5, 4, 5, 5, 4, 4, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, +}; + +static float _vq_quantthresh__44u9_p6_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44u9_p6_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44u9_p6_1 = { + _vq_quantthresh__44u9_p6_1, + _vq_quantmap__44u9_p6_1, + 5, + 5 +}; + +static static_codebook _44u9_p6_1 = { + 2, 25, + _vq_lengthlist__44u9_p6_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44u9_p6_1, + NULL, + &_vq_auxt__44u9_p6_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u9_p7_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44u9_p7_0[] = { + 1, 4, 5, 6, 6, 7, 7, 8, 9,10,10,11,11, 5, 6, 6, + 7, 7, 8, 8, 9, 9,10,10,11,11, 5, 6, 6, 7, 7, 8, + 8, 9, 9,10,10,11,11, 6, 7, 7, 8, 8, 9, 9,10,10, + 11,11,12,12, 6, 7, 7, 8, 8, 9, 9,10,10,11,11,12, + 12, 8, 8, 8, 9, 9,10,10,11,11,12,12,13,13, 8, 8, + 8, 9, 9,10,10,11,11,12,12,13,13, 9, 9, 9,10,10, + 11,11,12,12,13,13,13,13, 9, 9, 9,10,10,11,11,12, + 12,13,13,14,14,10,10,10,11,11,12,12,13,13,14,13, + 15,14,10,10,10,11,11,12,12,13,13,14,14,14,14,11, + 11,12,12,12,13,13,14,14,14,14,15,15,11,11,12,12, + 12,13,13,14,14,14,15,15,15, +}; + +static float _vq_quantthresh__44u9_p7_0[] = { + -60.5, -49.5, -38.5, -27.5, -16.5, -5.5, 5.5, 16.5, + 27.5, 38.5, 49.5, 60.5, +}; + +static long _vq_quantmap__44u9_p7_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44u9_p7_0 = { + _vq_quantthresh__44u9_p7_0, + _vq_quantmap__44u9_p7_0, + 13, + 13 +}; + +static static_codebook _44u9_p7_0 = { + 2, 169, + _vq_lengthlist__44u9_p7_0, + 1, -523206656, 1618345984, 4, 0, + _vq_quantlist__44u9_p7_0, + NULL, + &_vq_auxt__44u9_p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u9_p7_1[] = { + 5, + 4, + 6, + 3, + 7, + 2, + 8, + 1, + 9, + 0, + 10, +}; + +static long _vq_lengthlist__44u9_p7_1[] = { + 5, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 7, 7, + 7, 7, 7, 7, 7, 7, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 8, 8, 7, 7, 7, 7, 7, 7, 7, 8, 7, 8, 8, 7, 7, + 7, 7, 7, 7, 7, 8, 8, 8, 8, +}; + +static float _vq_quantthresh__44u9_p7_1[] = { + -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, + 3.5, 4.5, +}; + +static long _vq_quantmap__44u9_p7_1[] = { + 9, 7, 5, 3, 1, 0, 2, 4, + 6, 8, 10, +}; + +static encode_aux_threshmatch _vq_auxt__44u9_p7_1 = { + _vq_quantthresh__44u9_p7_1, + _vq_quantmap__44u9_p7_1, + 11, + 11 +}; + +static static_codebook _44u9_p7_1 = { + 2, 121, + _vq_lengthlist__44u9_p7_1, + 1, -531365888, 1611661312, 4, 0, + _vq_quantlist__44u9_p7_1, + NULL, + &_vq_auxt__44u9_p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u9_p8_0[] = { + 7, + 6, + 8, + 5, + 9, + 4, + 10, + 3, + 11, + 2, + 12, + 1, + 13, + 0, + 14, +}; + +static long _vq_lengthlist__44u9_p8_0[] = { + 1, 4, 4, 7, 7, 8, 8, 8, 8, 9, 9,10, 9,11,10, 4, + 6, 6, 8, 8, 9, 9, 9, 9,10,10,11,10,12,10, 4, 6, + 6, 8, 8, 9,10, 9, 9,10,10,11,11,12,12, 7, 8, 8, + 10,10,11,11,10,10,11,11,12,12,13,12, 7, 8, 8,10, + 10,11,11,10,10,11,11,12,12,12,13, 8,10, 9,11,11, + 12,12,11,11,12,12,13,13,14,13, 8, 9, 9,11,11,12, + 12,11,12,12,12,13,13,14,13, 8, 9, 9,10,10,12,11, + 13,12,13,13,14,13,15,14, 8, 9, 9,10,10,11,12,12, + 12,13,13,13,14,14,14, 9,10,10,12,11,13,12,13,13, + 14,13,14,14,14,15, 9,10,10,11,12,12,12,13,13,14, + 14,14,15,15,15,10,11,11,12,12,13,13,14,14,14,14, + 15,14,16,15,10,11,11,12,12,13,13,13,14,14,14,14, + 14,15,16,11,12,12,13,13,14,13,14,14,15,14,15,16, + 16,16,11,12,12,13,13,14,13,14,14,15,15,15,16,15, + 15, +}; + +static float _vq_quantthresh__44u9_p8_0[] = { + -136.5, -115.5, -94.5, -73.5, -52.5, -31.5, -10.5, 10.5, + 31.5, 52.5, 73.5, 94.5, 115.5, 136.5, +}; + +static long _vq_quantmap__44u9_p8_0[] = { + 13, 11, 9, 7, 5, 3, 1, 0, + 2, 4, 6, 8, 10, 12, 14, +}; + +static encode_aux_threshmatch _vq_auxt__44u9_p8_0 = { + _vq_quantthresh__44u9_p8_0, + _vq_quantmap__44u9_p8_0, + 15, + 15 +}; + +static static_codebook _44u9_p8_0 = { + 2, 225, + _vq_lengthlist__44u9_p8_0, + 1, -520986624, 1620377600, 4, 0, + _vq_quantlist__44u9_p8_0, + NULL, + &_vq_auxt__44u9_p8_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u9_p8_1[] = { + 10, + 9, + 11, + 8, + 12, + 7, + 13, + 6, + 14, + 5, + 15, + 4, + 16, + 3, + 17, + 2, + 18, + 1, + 19, + 0, + 20, +}; + +static long _vq_lengthlist__44u9_p8_1[] = { + 4, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 6, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 6, 6, 6, 7, 7, 8, + 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 7, + 7, 7, 8, 8, 8, 8, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9,10, 9,10,10,10, 8, 8, + 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9,10,10, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 10, 9,10, 9,10,10,10,10, 8, 8, 8, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9,10,10, 9,10,10,10,10,10, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9,10, 9,10,10,10,10,10,10, + 10,10, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10,10, + 10,10,10,10,10,10,10, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9,10,10,10,10,10,10,10,10,10,10, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9,10,10,10,10,10,10,10,10,10, + 10, 9, 9, 9, 9, 9, 9, 9,10, 9,10,10,10,10,10,10, + 10,10,10,10,10,10, 9, 9, 9, 9, 9, 9, 9, 9,10,10, + 10,10,10,10,10,10,10,10,10,10,10, 9, 9, 9, 9, 9, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 9, 9, 9, 9,10, 9, 9,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10, 9, 9, 9,10, 9,10, 9,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10, 9, 9, 9,10, 9,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, 9, + 9, 9, 9, 9,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10, 9, 9, 9,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10, +}; + +static float _vq_quantthresh__44u9_p8_1[] = { + -9.5, -8.5, -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, + -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, + 6.5, 7.5, 8.5, 9.5, +}; + +static long _vq_quantmap__44u9_p8_1[] = { + 19, 17, 15, 13, 11, 9, 7, 5, + 3, 1, 0, 2, 4, 6, 8, 10, + 12, 14, 16, 18, 20, +}; + +static encode_aux_threshmatch _vq_auxt__44u9_p8_1 = { + _vq_quantthresh__44u9_p8_1, + _vq_quantmap__44u9_p8_1, + 21, + 21 +}; + +static static_codebook _44u9_p8_1 = { + 2, 441, + _vq_lengthlist__44u9_p8_1, + 1, -529268736, 1611661312, 5, 0, + _vq_quantlist__44u9_p8_1, + NULL, + &_vq_auxt__44u9_p8_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u9_p9_0[] = { + 7, + 6, + 8, + 5, + 9, + 4, + 10, + 3, + 11, + 2, + 12, + 1, + 13, + 0, + 14, +}; + +static long _vq_lengthlist__44u9_p9_0[] = { + 1, 3, 3,11,11,11,11,11,11,11,11,11,11,11,11, 4, + 10,11,11,11,11,11,11,11,11,11,11,11,11,11, 4,10, + 10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10, +}; + +static float _vq_quantthresh__44u9_p9_0[] = { + -6051.5, -5120.5, -4189.5, -3258.5, -2327.5, -1396.5, -465.5, 465.5, + 1396.5, 2327.5, 3258.5, 4189.5, 5120.5, 6051.5, +}; + +static long _vq_quantmap__44u9_p9_0[] = { + 13, 11, 9, 7, 5, 3, 1, 0, + 2, 4, 6, 8, 10, 12, 14, +}; + +static encode_aux_threshmatch _vq_auxt__44u9_p9_0 = { + _vq_quantthresh__44u9_p9_0, + _vq_quantmap__44u9_p9_0, + 15, + 15 +}; + +static static_codebook _44u9_p9_0 = { + 2, 225, + _vq_lengthlist__44u9_p9_0, + 1, -510036736, 1631393792, 4, 0, + _vq_quantlist__44u9_p9_0, + NULL, + &_vq_auxt__44u9_p9_0, + NULL, + 0 +}; + +static long _vq_quantlist__44u9_p9_1[] = { + 9, + 8, + 10, + 7, + 11, + 6, + 12, + 5, + 13, + 4, + 14, + 3, + 15, + 2, + 16, + 1, + 17, + 0, + 18, +}; + +static long _vq_lengthlist__44u9_p9_1[] = { + 1, 4, 4, 7, 7, 8, 7, 8, 7, 9, 8,10, 9,10,10,11, + 11,12,12, 4, 7, 6, 9, 9,10, 9, 9, 8,10,10,11,10, + 12,10,13,12,13,12, 4, 6, 6, 9, 9, 9, 9, 9, 9,10, + 10,11,11,11,12,12,12,12,12, 7, 9, 8,11,10,10,10, + 11,10,11,11,12,12,13,12,13,13,13,13, 7, 8, 9,10, + 10,11,11,10,10,11,11,11,12,13,13,13,13,14,14, 8, + 9, 9,11,11,12,11,12,12,13,12,12,13,13,14,15,14, + 14,14, 8, 9, 9,10,11,11,11,12,12,13,12,13,13,14, + 14,14,15,14,16, 8, 9, 9,11,10,12,12,12,12,15,13, + 13,13,17,14,15,15,15,14, 8, 9, 9,10,11,11,12,13, + 12,13,13,13,14,15,14,14,14,16,15, 9,11,10,12,12, + 13,13,13,13,14,14,16,15,14,14,14,15,15,17, 9,10, + 10,11,11,13,13,13,14,14,13,15,14,15,14,15,16,15, + 16,10,11,11,12,12,13,14,15,14,15,14,14,15,17,16, + 15,15,17,17,10,12,11,13,12,14,14,13,14,15,15,15, + 15,16,17,17,15,17,16,11,12,12,14,13,15,14,15,16, + 17,15,17,15,17,15,15,16,17,15,11,11,12,14,14,14, + 14,14,15,15,16,15,17,17,17,16,17,16,15,12,12,13, + 14,14,14,15,14,15,15,16,16,17,16,17,15,17,17,16, + 12,14,12,14,14,15,15,15,14,14,16,16,16,15,16,16, + 15,17,15,12,13,13,14,15,14,15,17,15,17,16,17,17, + 17,16,17,16,17,17,12,13,13,14,16,15,15,15,16,15, + 17,17,15,17,15,17,16,16,17, +}; + +static float _vq_quantthresh__44u9_p9_1[] = { + -416.5, -367.5, -318.5, -269.5, -220.5, -171.5, -122.5, -73.5, + -24.5, 24.5, 73.5, 122.5, 171.5, 220.5, 269.5, 318.5, + 367.5, 416.5, +}; + +static long _vq_quantmap__44u9_p9_1[] = { + 17, 15, 13, 11, 9, 7, 5, 3, + 1, 0, 2, 4, 6, 8, 10, 12, + 14, 16, 18, +}; + +static encode_aux_threshmatch _vq_auxt__44u9_p9_1 = { + _vq_quantthresh__44u9_p9_1, + _vq_quantmap__44u9_p9_1, + 19, + 19 +}; + +static static_codebook _44u9_p9_1 = { + 2, 361, + _vq_lengthlist__44u9_p9_1, + 1, -518287360, 1622704128, 5, 0, + _vq_quantlist__44u9_p9_1, + NULL, + &_vq_auxt__44u9_p9_1, + NULL, + 0 +}; + +static long _vq_quantlist__44u9_p9_2[] = { + 24, + 23, + 25, + 22, + 26, + 21, + 27, + 20, + 28, + 19, + 29, + 18, + 30, + 17, + 31, + 16, + 32, + 15, + 33, + 14, + 34, + 13, + 35, + 12, + 36, + 11, + 37, + 10, + 38, + 9, + 39, + 8, + 40, + 7, + 41, + 6, + 42, + 5, + 43, + 4, + 44, + 3, + 45, + 2, + 46, + 1, + 47, + 0, + 48, +}; + +static long _vq_lengthlist__44u9_p9_2[] = { + 2, 4, 4, 5, 4, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 7, 6, 7, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, +}; + +static float _vq_quantthresh__44u9_p9_2[] = { + -23.5, -22.5, -21.5, -20.5, -19.5, -18.5, -17.5, -16.5, + -15.5, -14.5, -13.5, -12.5, -11.5, -10.5, -9.5, -8.5, + -7.5, -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, + 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, + 8.5, 9.5, 10.5, 11.5, 12.5, 13.5, 14.5, 15.5, + 16.5, 17.5, 18.5, 19.5, 20.5, 21.5, 22.5, 23.5, +}; + +static long _vq_quantmap__44u9_p9_2[] = { + 47, 45, 43, 41, 39, 37, 35, 33, + 31, 29, 27, 25, 23, 21, 19, 17, + 15, 13, 11, 9, 7, 5, 3, 1, + 0, 2, 4, 6, 8, 10, 12, 14, + 16, 18, 20, 22, 24, 26, 28, 30, + 32, 34, 36, 38, 40, 42, 44, 46, + 48, +}; + +static encode_aux_threshmatch _vq_auxt__44u9_p9_2 = { + _vq_quantthresh__44u9_p9_2, + _vq_quantmap__44u9_p9_2, + 49, + 49 +}; + +static static_codebook _44u9_p9_2 = { + 1, 49, + _vq_lengthlist__44u9_p9_2, + 1, -526909440, 1611661312, 6, 0, + _vq_quantlist__44u9_p9_2, + NULL, + &_vq_auxt__44u9_p9_2, + NULL, + 0 +}; + +static long _huff_lengthlist__44un1__long[] = { + 5, 6,12, 9,14, 9, 9,19, 6, 1, 5, 5, 8, 7, 9,19, + 12, 4, 4, 7, 7, 9,11,18, 9, 5, 6, 6, 8, 7, 8,17, + 14, 8, 7, 8, 8,10,12,18, 9, 6, 8, 6, 8, 6, 8,18, + 9, 8,11, 8,11, 7, 5,15,16,18,18,18,17,15,11,18, +}; + +static static_codebook _huff_book__44un1__long = { + 2, 64, + _huff_lengthlist__44un1__long, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + +static long _vq_quantlist__44un1__p1_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44un1__p1_0[] = { + 1, 4, 4, 5, 8, 7, 5, 7, 8, 5, 8, 8, 8,10,11, 8, + 10,11, 5, 8, 8, 8,11,10, 8,11,10, 4, 9, 9, 8,11, + 11, 8,11,11, 8,12,11,10,12,14,11,13,13, 7,11,11, + 10,13,11,11,13,14, 4, 8, 9, 8,11,11, 8,11,12, 7, + 11,11,11,14,13,10,11,13, 8,11,12,11,13,13,10,14, + 12, +}; + +static float _vq_quantthresh__44un1__p1_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44un1__p1_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44un1__p1_0 = { + _vq_quantthresh__44un1__p1_0, + _vq_quantmap__44un1__p1_0, + 3, + 3 +}; + +static static_codebook _44un1__p1_0 = { + 4, 81, + _vq_lengthlist__44un1__p1_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44un1__p1_0, + NULL, + &_vq_auxt__44un1__p1_0, + NULL, + 0 +}; + +static long _vq_quantlist__44un1__p2_0[] = { + 1, + 0, + 2, +}; + +static long _vq_lengthlist__44un1__p2_0[] = { + 2, 4, 4, 5, 6, 6, 5, 6, 6, 5, 7, 7, 7, 8, 8, 6, + 7, 9, 5, 7, 7, 6, 8, 7, 7, 9, 8, 4, 7, 7, 7, 9, + 8, 7, 8, 8, 7, 9, 8, 8, 8,10, 9,10,10, 6, 8, 8, + 7,10, 8, 9,10,10, 5, 7, 7, 7, 8, 8, 7, 8, 9, 6, + 8, 8, 9,10,10, 7, 8,10, 6, 8, 9, 9,10,10, 8,10, + 8, +}; + +static float _vq_quantthresh__44un1__p2_0[] = { + -0.5, 0.5, +}; + +static long _vq_quantmap__44un1__p2_0[] = { + 1, 0, 2, +}; + +static encode_aux_threshmatch _vq_auxt__44un1__p2_0 = { + _vq_quantthresh__44un1__p2_0, + _vq_quantmap__44un1__p2_0, + 3, + 3 +}; + +static static_codebook _44un1__p2_0 = { + 4, 81, + _vq_lengthlist__44un1__p2_0, + 1, -535822336, 1611661312, 2, 0, + _vq_quantlist__44un1__p2_0, + NULL, + &_vq_auxt__44un1__p2_0, + NULL, + 0 +}; + +static long _vq_quantlist__44un1__p3_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44un1__p3_0[] = { + 1, 5, 5, 8, 8, 5, 8, 7, 9, 9, 5, 7, 8, 9, 9, 9, + 10, 9,12,12, 9, 9,10,11,12, 6, 8, 8,10,10, 8,10, + 10,11,11, 8, 9,10,11,11,10,11,11,13,13,10,11,11, + 12,13, 6, 8, 8,10,10, 8,10, 9,11,11, 8,10,10,11, + 11,10,11,11,13,12,10,11,11,13,12, 9,11,11,15,13, + 10,12,11,15,13,10,11,11,15,14,12,14,13,16,15,12, + 13,13,17,16, 9,11,11,13,15,10,11,12,14,15,10,11, + 12,14,15,12,13,13,15,16,12,13,13,16,16, 5, 8, 8, + 11,11, 8,10,10,12,12, 8,10,10,12,12,11,12,12,14, + 14,11,12,12,14,14, 8,11,10,13,12,10,11,12,12,13, + 10,12,12,13,13,12,12,13,13,15,11,12,13,15,14, 7, + 10,10,12,12, 9,12,11,13,12,10,12,12,13,14,12,13, + 12,15,13,11,13,12,14,15,10,12,12,16,14,11,12,12, + 16,15,11,13,12,17,16,13,13,15,15,17,13,15,15,20, + 17,10,12,12,14,16,11,12,12,15,15,11,13,13,15,18, + 13,14,13,15,15,13,15,14,16,16, 5, 8, 8,11,11, 8, + 10,10,12,12, 8,10,10,12,12,11,12,12,14,14,11,12, + 12,14,15, 7,10,10,13,12,10,12,12,14,13, 9,10,12, + 12,13,11,13,13,15,15,11,12,13,13,15, 8,10,10,12, + 13,10,12,12,13,13,10,12,11,13,13,11,13,12,15,15, + 12,13,12,15,13,10,12,12,16,14,11,12,12,16,15,10, + 12,12,16,14,14,15,14,18,16,13,13,14,15,16,10,12, + 12,14,16,11,13,13,16,16,11,13,12,14,16,13,15,15, + 18,18,13,15,13,16,14, 8,11,11,16,16,10,13,13,17, + 16,10,12,12,16,15,14,16,15,20,17,13,14,14,17,17, + 9,12,12,16,16,11,13,14,16,17,11,13,13,16,16,15, + 15,19,18, 0,14,15,15,18,18, 9,12,12,17,16,11,13, + 12,17,16,11,12,13,15,17,15,16,15, 0,19,14,15,14, + 19,18,12,14,14, 0,16,13,14,14,19,18,13,15,16,17, + 16,15,15,17,18, 0,14,16,16,19, 0,12,14,14,16,18, + 13,15,13,17,18,13,15,14,17,18,15,18,14,18,18,16, + 17,16, 0,17, 8,11,11,15,15,10,12,12,16,16,10,13, + 13,16,16,13,15,14,17,17,14,15,17,17,18, 9,12,12, + 16,15,11,13,13,16,16,11,12,13,17,17,14,14,15,17, + 17,14,15,16, 0,18, 9,12,12,16,17,11,13,13,16,17, + 11,14,13,18,17,14,16,14,17,17,15,17,17,18,18,12, + 14,14, 0,16,13,15,15,19, 0,12,13,15, 0, 0,14,17, + 16,19, 0,16,15,18,18, 0,12,14,14,17, 0,13,14,14, + 17, 0,13,15,14, 0,18,15,16,16, 0,18,15,18,15, 0, + 17, +}; + +static float _vq_quantthresh__44un1__p3_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44un1__p3_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44un1__p3_0 = { + _vq_quantthresh__44un1__p3_0, + _vq_quantmap__44un1__p3_0, + 5, + 5 +}; + +static static_codebook _44un1__p3_0 = { + 4, 625, + _vq_lengthlist__44un1__p3_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44un1__p3_0, + NULL, + &_vq_auxt__44un1__p3_0, + NULL, + 0 +}; + +static long _vq_quantlist__44un1__p4_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44un1__p4_0[] = { + 3, 5, 5, 9, 9, 5, 6, 6,10, 9, 5, 6, 6, 9,10,10, + 10,10,12,11, 9,10,10,12,12, 5, 7, 7,10,10, 7, 7, + 8,10,11, 7, 7, 8,10,11,10,10,11,11,13,10,10,11, + 11,13, 6, 7, 7,10,10, 7, 8, 7,11,10, 7, 8, 7,10, + 10,10,11, 9,13,11,10,11,10,13,11,10,10,10,14,13, + 10,11,11,14,13,10,10,11,13,14,12,12,13,15,15,12, + 12,13,13,14,10,10,10,12,13,10,11,10,13,13,10,11, + 11,13,13,12,13,12,14,13,12,13,13,14,13, 5, 7, 7, + 10,10, 7, 8, 8,11,10, 7, 8, 8,10,10,11,11,11,13, + 13,10,11,11,12,12, 7, 8, 8,11,11, 7, 8, 9,10,12, + 8, 9, 9,11,11,11,10,12,11,14,11,11,12,13,13, 6, + 8, 8,10,11, 7, 9, 7,12,10, 8, 9,10,11,12,10,12, + 10,14,11,11,12,11,13,13,10,11,11,14,14,10,10,11, + 13,14,11,12,12,15,13,12,11,14,12,16,12,13,14,15, + 16,10,10,11,13,14,10,11,10,14,12,11,12,12,13,14, + 12,13,11,15,12,14,14,14,15,15, 5, 7, 7,10,10, 7, + 8, 8,10,10, 7, 8, 8,10,11,10,11,10,12,12,10,11, + 11,12,13, 6, 8, 8,11,11, 8, 9, 9,12,11, 7, 7, 9, + 10,12,11,11,11,12,13,11,10,12,11,15, 7, 8, 8,11, + 11, 8, 9, 9,11,11, 7, 9, 8,12,10,11,12,11,13,12, + 11,12,10,15,11,10,11,10,14,12,11,12,11,14,13,10, + 10,11,13,14,13,13,13,17,15,12,11,14,12,15,10,10, + 11,13,14,11,12,12,14,14,10,11,10,14,13,13,14,13, + 16,17,12,14,11,16,12, 9,10,10,14,13,10,11,10,14, + 14,10,11,11,13,13,13,14,14,16,15,12,13,13,14,14, + 9,11,10,14,13,10,10,12,13,14,11,12,11,14,13,13, + 14,14,14,15,13,14,14,15,15, 9,10,11,13,14,10,11, + 10,15,13,11,11,12,12,15,13,14,12,15,14,13,13,14, + 14,15,12,13,12,16,14,11,11,12,15,14,13,15,13,16, + 14,13,12,15,12,17,15,16,15,16,16,12,12,13,13,15, + 11,13,11,15,14,13,13,14,15,17,13,14,12, 0,13,14, + 15,14,15, 0, 9,10,10,13,13,10,11,11,13,13,10,11, + 11,13,13,12,13,12,14,14,13,14,14,15,17, 9,10,10, + 13,13,11,12,11,15,12,10,10,11,13,16,13,14,13,15, + 14,13,13,14,15,16,10,10,11,13,14,11,11,12,13,14, + 10,12,11,14,14,13,13,13,14,15,13,15,13,16,15,12, + 13,12,15,13,12,15,13,15,15,11,11,13,14,15,15,15, + 15,15,17,13,12,14,13,17,12,12,14,14,15,13,13,14, + 14,16,11,13,11,16,15,14,16,16,17, 0,14,13,11,16, + 12, +}; + +static float _vq_quantthresh__44un1__p4_0[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44un1__p4_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44un1__p4_0 = { + _vq_quantthresh__44un1__p4_0, + _vq_quantmap__44un1__p4_0, + 5, + 5 +}; + +static static_codebook _44un1__p4_0 = { + 4, 625, + _vq_lengthlist__44un1__p4_0, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44un1__p4_0, + NULL, + &_vq_auxt__44un1__p4_0, + NULL, + 0 +}; + +static long _vq_quantlist__44un1__p5_0[] = { + 4, + 3, + 5, + 2, + 6, + 1, + 7, + 0, + 8, +}; + +static long _vq_lengthlist__44un1__p5_0[] = { + 1, 4, 4, 7, 7, 8, 8, 9, 9, 4, 6, 5, 8, 7, 8, 8, + 10, 9, 4, 6, 6, 8, 8, 8, 8,10,10, 7, 8, 7, 9, 9, + 9, 9,11,10, 7, 8, 8, 9, 9, 9, 9,10,11, 8, 8, 8, + 9, 9,10,10,11,11, 8, 8, 8, 9, 9,10,10,11,11, 9, + 10,10,11,10,11,11,12,12, 9,10,10,10,11,11,11,12, + 12, +}; + +static float _vq_quantthresh__44un1__p5_0[] = { + -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, +}; + +static long _vq_quantmap__44un1__p5_0[] = { + 7, 5, 3, 1, 0, 2, 4, 6, + 8, +}; + +static encode_aux_threshmatch _vq_auxt__44un1__p5_0 = { + _vq_quantthresh__44un1__p5_0, + _vq_quantmap__44un1__p5_0, + 9, + 9 +}; + +static static_codebook _44un1__p5_0 = { + 2, 81, + _vq_lengthlist__44un1__p5_0, + 1, -531628032, 1611661312, 4, 0, + _vq_quantlist__44un1__p5_0, + NULL, + &_vq_auxt__44un1__p5_0, + NULL, + 0 +}; + +static long _vq_quantlist__44un1__p6_0[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44un1__p6_0[] = { + 1, 4, 4, 6, 6, 8, 8,10,10,11,11,15,15, 4, 5, 5, + 8, 8, 9, 9,11,11,12,12,16,16, 4, 5, 6, 8, 8, 9, + 9,11,11,12,12,14,14, 7, 8, 8, 9, 9,10,10,11,12, + 13,13,16,17, 7, 8, 8, 9, 9,10,10,12,12,12,13,15, + 15, 9,10,10,10,10,11,11,12,12,13,13,15,16, 9, 9, + 9,10,10,11,11,13,12,13,13,17,17,10,11,11,11,12, + 12,12,13,13,14,15, 0,18,10,11,11,12,12,12,13,14, + 13,14,14,17,16,11,12,12,13,13,14,14,14,14,15,16, + 17,16,11,12,12,13,13,14,14,14,14,15,15,17,17,14, + 15,15,16,16,16,17,17,16, 0,17, 0,18,14,15,15,16, + 16, 0,15,18,18, 0,16, 0, 0, +}; + +static float _vq_quantthresh__44un1__p6_0[] = { + -27.5, -22.5, -17.5, -12.5, -7.5, -2.5, 2.5, 7.5, + 12.5, 17.5, 22.5, 27.5, +}; + +static long _vq_quantmap__44un1__p6_0[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44un1__p6_0 = { + _vq_quantthresh__44un1__p6_0, + _vq_quantmap__44un1__p6_0, + 13, + 13 +}; + +static static_codebook _44un1__p6_0 = { + 2, 169, + _vq_lengthlist__44un1__p6_0, + 1, -526516224, 1616117760, 4, 0, + _vq_quantlist__44un1__p6_0, + NULL, + &_vq_auxt__44un1__p6_0, + NULL, + 0 +}; + +static long _vq_quantlist__44un1__p6_1[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44un1__p6_1[] = { + 2, 4, 4, 5, 5, 4, 5, 5, 5, 5, 4, 5, 5, 6, 5, 5, + 6, 5, 6, 6, 5, 6, 6, 6, 6, +}; + +static float _vq_quantthresh__44un1__p6_1[] = { + -1.5, -0.5, 0.5, 1.5, +}; + +static long _vq_quantmap__44un1__p6_1[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44un1__p6_1 = { + _vq_quantthresh__44un1__p6_1, + _vq_quantmap__44un1__p6_1, + 5, + 5 +}; + +static static_codebook _44un1__p6_1 = { + 2, 25, + _vq_lengthlist__44un1__p6_1, + 1, -533725184, 1611661312, 3, 0, + _vq_quantlist__44un1__p6_1, + NULL, + &_vq_auxt__44un1__p6_1, + NULL, + 0 +}; + +static long _vq_quantlist__44un1__p7_0[] = { + 2, + 1, + 3, + 0, + 4, +}; + +static long _vq_lengthlist__44un1__p7_0[] = { + 1, 5, 3,11,11,11,11,11,11,11, 8,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,10,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,10,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11, 8,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11, 7,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,10,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10, +}; + +static float _vq_quantthresh__44un1__p7_0[] = { + -253.5, -84.5, 84.5, 253.5, +}; + +static long _vq_quantmap__44un1__p7_0[] = { + 3, 1, 0, 2, 4, +}; + +static encode_aux_threshmatch _vq_auxt__44un1__p7_0 = { + _vq_quantthresh__44un1__p7_0, + _vq_quantmap__44un1__p7_0, + 5, + 5 +}; + +static static_codebook _44un1__p7_0 = { + 4, 625, + _vq_lengthlist__44un1__p7_0, + 1, -518709248, 1626677248, 3, 0, + _vq_quantlist__44un1__p7_0, + NULL, + &_vq_auxt__44un1__p7_0, + NULL, + 0 +}; + +static long _vq_quantlist__44un1__p7_1[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44un1__p7_1[] = { + 1, 4, 4, 6, 6, 6, 6, 9, 8, 9, 8, 8, 8, 5, 7, 7, + 7, 7, 8, 8, 8,10, 8,10, 8, 9, 5, 7, 7, 8, 7, 7, + 8,10,10,11,10,12,11, 7, 8, 8, 9, 9, 9,10,11,11, + 11,11,11,11, 7, 8, 8, 8, 9, 9, 9,10,10,10,11,11, + 12, 7, 8, 8, 9, 9,10,11,11,12,11,12,11,11, 7, 8, + 8, 9, 9,10,10,11,11,11,12,12,11, 8,10,10,10,10, + 11,11,14,11,12,12,12,13, 9,10,10,10,10,12,11,14, + 11,14,11,12,13,10,11,11,11,11,13,11,14,14,13,13, + 13,14,11,11,11,12,11,12,12,12,13,14,14,13,14,12, + 11,12,12,12,12,13,13,13,14,13,14,14,11,12,12,14, + 12,13,13,12,13,13,14,14,14, +}; + +static float _vq_quantthresh__44un1__p7_1[] = { + -71.5, -58.5, -45.5, -32.5, -19.5, -6.5, 6.5, 19.5, + 32.5, 45.5, 58.5, 71.5, +}; + +static long _vq_quantmap__44un1__p7_1[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44un1__p7_1 = { + _vq_quantthresh__44un1__p7_1, + _vq_quantmap__44un1__p7_1, + 13, + 13 +}; + +static static_codebook _44un1__p7_1 = { + 2, 169, + _vq_lengthlist__44un1__p7_1, + 1, -523010048, 1618608128, 4, 0, + _vq_quantlist__44un1__p7_1, + NULL, + &_vq_auxt__44un1__p7_1, + NULL, + 0 +}; + +static long _vq_quantlist__44un1__p7_2[] = { + 6, + 5, + 7, + 4, + 8, + 3, + 9, + 2, + 10, + 1, + 11, + 0, + 12, +}; + +static long _vq_lengthlist__44un1__p7_2[] = { + 3, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9, 9, 8, 4, 5, 5, + 6, 6, 8, 8, 9, 8, 9, 9, 9, 9, 4, 5, 5, 7, 6, 8, + 8, 8, 8, 9, 8, 9, 8, 6, 7, 7, 7, 8, 8, 8, 9, 9, + 9, 9, 9, 9, 6, 7, 7, 7, 7, 8, 8, 9, 9, 9, 9, 9, + 9, 7, 8, 8, 8, 8, 9, 8, 9, 9,10, 9, 9,10, 7, 8, + 8, 8, 8, 9, 9, 9, 9, 9, 9,10,10, 8, 9, 9, 9, 9, + 9, 9, 9, 9,10,10, 9,10, 8, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9,10,10, 9, 9, 9,10, 9, 9,10, 9, 9,10,10, + 10,10, 9, 9, 9, 9, 9, 9, 9,10, 9,10,10,10,10, 9, + 9, 9,10, 9, 9,10,10, 9,10,10,10,10, 9, 9, 9,10, + 9, 9, 9,10,10,10,10,10,10, +}; + +static float _vq_quantthresh__44un1__p7_2[] = { + -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, + 2.5, 3.5, 4.5, 5.5, +}; + +static long _vq_quantmap__44un1__p7_2[] = { + 11, 9, 7, 5, 3, 1, 0, 2, + 4, 6, 8, 10, 12, +}; + +static encode_aux_threshmatch _vq_auxt__44un1__p7_2 = { + _vq_quantthresh__44un1__p7_2, + _vq_quantmap__44un1__p7_2, + 13, + 13 +}; + +static static_codebook _44un1__p7_2 = { + 2, 169, + _vq_lengthlist__44un1__p7_2, + 1, -531103744, 1611661312, 4, 0, + _vq_quantlist__44un1__p7_2, + NULL, + &_vq_auxt__44un1__p7_2, + NULL, + 0 +}; + +static long _huff_lengthlist__44un1__short[] = { + 12,12,14,12,14,14,14,14,12, 6, 6, 8, 9, 9,11,14, + 12, 4, 2, 6, 6, 7,11,14,13, 6, 5, 7, 8, 9,11,14, + 13, 8, 5, 8, 6, 8,12,14,12, 7, 7, 8, 8, 8,10,14, + 12, 6, 3, 4, 4, 4, 7,14,11, 7, 4, 6, 6, 6, 8,14, +}; + +static static_codebook _huff_book__44un1__short = { + 2, 64, + _huff_lengthlist__44un1__short, + 0, 0, 0, 0, 0, + NULL, + NULL, + NULL, + NULL, + 0 +}; + diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/codebook.c b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/codebook.c new file mode 100644 index 0000000..b272fad --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/codebook.c @@ -0,0 +1,615 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: basic codebook pack/unpack/code/decode operations + last mod: $Id: codebook.c 7187 2004-07-20 07:24:27Z xiphmont $ + + ********************************************************************/ + +#include +#include +#include +#include +#include "vorbis/codec.h" +#include "codebook.h" +#include "scales.h" +#include "misc.h" +#include "os.h" + +/* packs the given codebook into the bitstream **************************/ + +int vorbis_staticbook_pack(const static_codebook *c,oggpack_buffer *opb){ + long i,j; + int ordered=0; + + /* first the basic parameters */ + oggpack_write(opb,0x564342,24); + oggpack_write(opb,c->dim,16); + oggpack_write(opb,c->entries,24); + + /* pack the codewords. There are two packings; length ordered and + length random. Decide between the two now. */ + + for(i=1;ientries;i++) + if(c->lengthlist[i-1]==0 || c->lengthlist[i]lengthlist[i-1])break; + if(i==c->entries)ordered=1; + + if(ordered){ + /* length ordered. We only need to say how many codewords of + each length. The actual codewords are generated + deterministically */ + + long count=0; + oggpack_write(opb,1,1); /* ordered */ + oggpack_write(opb,c->lengthlist[0]-1,5); /* 1 to 32 */ + + for(i=1;ientries;i++){ + long this=c->lengthlist[i]; + long last=c->lengthlist[i-1]; + if(this>last){ + for(j=last;jentries-count)); + count=i; + } + } + } + oggpack_write(opb,i-count,_ilog(c->entries-count)); + + }else{ + /* length random. Again, we don't code the codeword itself, just + the length. This time, though, we have to encode each length */ + oggpack_write(opb,0,1); /* unordered */ + + /* algortihmic mapping has use for 'unused entries', which we tag + here. The algorithmic mapping happens as usual, but the unused + entry has no codeword. */ + for(i=0;ientries;i++) + if(c->lengthlist[i]==0)break; + + if(i==c->entries){ + oggpack_write(opb,0,1); /* no unused entries */ + for(i=0;ientries;i++) + oggpack_write(opb,c->lengthlist[i]-1,5); + }else{ + oggpack_write(opb,1,1); /* we have unused entries; thus we tag */ + for(i=0;ientries;i++){ + if(c->lengthlist[i]==0){ + oggpack_write(opb,0,1); + }else{ + oggpack_write(opb,1,1); + oggpack_write(opb,c->lengthlist[i]-1,5); + } + } + } + } + + /* is the entry number the desired return value, or do we have a + mapping? If we have a mapping, what type? */ + oggpack_write(opb,c->maptype,4); + switch(c->maptype){ + case 0: + /* no mapping */ + break; + case 1:case 2: + /* implicitly populated value mapping */ + /* explicitly populated value mapping */ + + if(!c->quantlist){ + /* no quantlist? error */ + return(-1); + } + + /* values that define the dequantization */ + oggpack_write(opb,c->q_min,32); + oggpack_write(opb,c->q_delta,32); + oggpack_write(opb,c->q_quant-1,4); + oggpack_write(opb,c->q_sequencep,1); + + { + int quantvals; + switch(c->maptype){ + case 1: + /* a single column of (c->entries/c->dim) quantized values for + building a full value list algorithmically (square lattice) */ + quantvals=_book_maptype1_quantvals(c); + break; + case 2: + /* every value (c->entries*c->dim total) specified explicitly */ + quantvals=c->entries*c->dim; + break; + default: /* NOT_REACHABLE */ + quantvals=-1; + } + + /* quantized values */ + for(i=0;iquantlist[i]),c->q_quant); + + } + break; + default: + /* error case; we don't have any other map types now */ + return(-1); + } + + return(0); +} + +/* unpacks a codebook from the packet buffer into the codebook struct, + readies the codebook auxiliary structures for decode *************/ +int vorbis_staticbook_unpack(oggpack_buffer *opb,static_codebook *s){ + long i,j; + memset(s,0,sizeof(*s)); + s->allocedp=1; + + /* make sure alignment is correct */ + if(oggpack_read(opb,24)!=0x564342)goto _eofout; + + /* first the basic parameters */ + s->dim=oggpack_read(opb,16); + s->entries=oggpack_read(opb,24); + if(s->entries==-1)goto _eofout; + + /* codeword ordering.... length ordered or unordered? */ + switch((int)oggpack_read(opb,1)){ + case 0: + /* unordered */ + s->lengthlist=_ogg_malloc(sizeof(*s->lengthlist)*s->entries); + + /* allocated but unused entries? */ + if(oggpack_read(opb,1)){ + /* yes, unused entries */ + + for(i=0;ientries;i++){ + if(oggpack_read(opb,1)){ + long num=oggpack_read(opb,5); + if(num==-1)goto _eofout; + s->lengthlist[i]=num+1; + }else + s->lengthlist[i]=0; + } + }else{ + /* all entries used; no tagging */ + for(i=0;ientries;i++){ + long num=oggpack_read(opb,5); + if(num==-1)goto _eofout; + s->lengthlist[i]=num+1; + } + } + + break; + case 1: + /* ordered */ + { + long length=oggpack_read(opb,5)+1; + s->lengthlist=_ogg_malloc(sizeof(*s->lengthlist)*s->entries); + + for(i=0;ientries;){ + long num=oggpack_read(opb,_ilog(s->entries-i)); + if(num==-1)goto _eofout; + for(j=0;jentries;j++,i++) + s->lengthlist[i]=length; + length++; + } + } + break; + default: + /* EOF */ + return(-1); + } + + /* Do we have a mapping to unpack? */ + switch((s->maptype=oggpack_read(opb,4))){ + case 0: + /* no mapping */ + break; + case 1: case 2: + /* implicitly populated value mapping */ + /* explicitly populated value mapping */ + + s->q_min=oggpack_read(opb,32); + s->q_delta=oggpack_read(opb,32); + s->q_quant=oggpack_read(opb,4)+1; + s->q_sequencep=oggpack_read(opb,1); + + { + int quantvals=0; + switch(s->maptype){ + case 1: + quantvals=_book_maptype1_quantvals(s); + break; + case 2: + quantvals=s->entries*s->dim; + break; + } + + /* quantized values */ + s->quantlist=_ogg_malloc(sizeof(*s->quantlist)*quantvals); + for(i=0;iquantlist[i]=oggpack_read(opb,s->q_quant); + + if(quantvals&&s->quantlist[quantvals-1]==-1)goto _eofout; + } + break; + default: + goto _errout; + } + + /* all set */ + return(0); + + _errout: + _eofout: + vorbis_staticbook_clear(s); + return(-1); +} + +/* returns the number of bits ************************************************/ +int vorbis_book_encode(codebook *book, int a, oggpack_buffer *b){ + oggpack_write(b,book->codelist[a],book->c->lengthlist[a]); + return(book->c->lengthlist[a]); +} + +/* One the encode side, our vector writers are each designed for a +specific purpose, and the encoder is not flexible without modification: + +The LSP vector coder uses a single stage nearest-match with no +interleave, so no step and no error return. This is specced by floor0 +and doesn't change. + +Residue0 encoding interleaves, uses multiple stages, and each stage +peels of a specific amount of resolution from a lattice (thus we want +to match by threshold, not nearest match). Residue doesn't *have* to +be encoded that way, but to change it, one will need to add more +infrastructure on the encode side (decode side is specced and simpler) */ + +/* floor0 LSP (single stage, non interleaved, nearest match) */ +/* returns entry number and *modifies a* to the quantization value *****/ +int vorbis_book_errorv(codebook *book,float *a){ + int dim=book->dim,k; + int best=_best(book,a,1); + for(k=0;kvaluelist+best*dim)[k]; + return(best); +} + +/* returns the number of bits and *modifies a* to the quantization value *****/ +int vorbis_book_encodev(codebook *book,int best,float *a,oggpack_buffer *b){ + int k,dim=book->dim; + for(k=0;kvaluelist+best*dim)[k]; + return(vorbis_book_encode(book,best,b)); +} + +/* the 'eliminate the decode tree' optimization actually requires the + codewords to be MSb first, not LSb. This is an annoying inelegancy + (and one of the first places where carefully thought out design + turned out to be wrong; Vorbis II and future Ogg codecs should go + to an MSb bitpacker), but not actually the huge hit it appears to + be. The first-stage decode table catches most words so that + bitreverse is not in the main execution path. */ + +static ogg_uint32_t bitreverse(ogg_uint32_t x){ + x= ((x>>16)&0x0000ffff) | ((x<<16)&0xffff0000); + x= ((x>> 8)&0x00ff00ff) | ((x<< 8)&0xff00ff00); + x= ((x>> 4)&0x0f0f0f0f) | ((x<< 4)&0xf0f0f0f0); + x= ((x>> 2)&0x33333333) | ((x<< 2)&0xcccccccc); + return((x>> 1)&0x55555555) | ((x<< 1)&0xaaaaaaaa); +} + +STIN long decode_packed_entry_number(codebook *book, oggpack_buffer *b){ + int read=book->dec_maxlength; + long lo,hi; + long lok = oggpack_look(b,book->dec_firsttablen); + + if (lok >= 0) { + long entry = book->dec_firsttable[lok]; + if(entry&0x80000000UL){ + lo=(entry>>15)&0x7fff; + hi=book->used_entries-(entry&0x7fff); + }else{ + oggpack_adv(b, book->dec_codelengths[entry-1]); + return(entry-1); + } + }else{ + lo=0; + hi=book->used_entries; + } + + lok = oggpack_look(b, read); + + while(lok<0 && read>1) + lok = oggpack_look(b, --read); + if(lok<0)return -1; + + /* bisect search for the codeword in the ordered list */ + { + ogg_uint32_t testword=bitreverse((ogg_uint32_t)lok); + + while(hi-lo>1){ + long p=(hi-lo)>>1; + long test=book->codelist[lo+p]>testword; + lo+=p&(test-1); + hi-=p&(-test); + } + + if(book->dec_codelengths[lo]<=read){ + oggpack_adv(b, book->dec_codelengths[lo]); + return(lo); + } + } + + oggpack_adv(b, read); + return(-1); +} + +/* Decode side is specced and easier, because we don't need to find + matches using different criteria; we simply read and map. There are + two things we need to do 'depending': + + We may need to support interleave. We don't really, but it's + convenient to do it here rather than rebuild the vector later. + + Cascades may be additive or multiplicitive; this is not inherent in + the codebook, but set in the code using the codebook. Like + interleaving, it's easiest to do it here. + addmul==0 -> declarative (set the value) + addmul==1 -> additive + addmul==2 -> multiplicitive */ + +/* returns the [original, not compacted] entry number or -1 on eof *********/ +long vorbis_book_decode(codebook *book, oggpack_buffer *b){ + long packed_entry=decode_packed_entry_number(book,b); + if(packed_entry>=0) + return(book->dec_index[packed_entry]); + + /* if there's no dec_index, the codebook unpacking isn't collapsed */ + return(packed_entry); +} + +/* returns 0 on OK or -1 on eof *************************************/ +long vorbis_book_decodevs_add(codebook *book,float *a,oggpack_buffer *b,int n){ + int step=n/book->dim; + long *entry = alloca(sizeof(*entry)*step); + float **t = alloca(sizeof(*t)*step); + int i,j,o; + + for (i = 0; i < step; i++) { + entry[i]=decode_packed_entry_number(book,b); + if(entry[i]==-1)return(-1); + t[i] = book->valuelist+entry[i]*book->dim; + } + for(i=0,o=0;idim;i++,o+=step) + for (j=0;jdim>8){ + for(i=0;ivaluelist+entry*book->dim; + for (j=0;jdim;) + a[i++]+=t[j++]; + } + }else{ + for(i=0;ivaluelist+entry*book->dim; + j=0; + switch((int)book->dim){ + case 8: + a[i++]+=t[j++]; + case 7: + a[i++]+=t[j++]; + case 6: + a[i++]+=t[j++]; + case 5: + a[i++]+=t[j++]; + case 4: + a[i++]+=t[j++]; + case 3: + a[i++]+=t[j++]; + case 2: + a[i++]+=t[j++]; + case 1: + a[i++]+=t[j++]; + case 0: + break; + } + } + } + return(0); +} + +long vorbis_book_decodev_set(codebook *book,float *a,oggpack_buffer *b,int n){ + int i,j,entry; + float *t; + + for(i=0;ivaluelist+entry*book->dim; + for (j=0;jdim;) + a[i++]=t[j++]; + } + return(0); +} + +long vorbis_book_decodevv_add(codebook *book,float **a,long offset,int ch, + oggpack_buffer *b,int n){ + long i,j,entry; + int chptr=0; + + for(i=offset/ch;i<(offset+n)/ch;){ + entry = decode_packed_entry_number(book,b); + if(entry==-1)return(-1); + { + const float *t = book->valuelist+entry*book->dim; + for (j=0;jdim;j++){ + a[chptr++][i]+=t[j]; + if(chptr==ch){ + chptr=0; + i++; + } + } + } + } + return(0); +} + +#ifdef _V_SELFTEST +/* Simple enough; pack a few candidate codebooks, unpack them. Code a + number of vectors through (keeping track of the quantized values), + and decode using the unpacked book. quantized version of in should + exactly equal out */ + +#include + +#include "vorbis/book/lsp20_0.vqh" +#include "vorbis/book/res0a_13.vqh" +#define TESTSIZE 40 + +float test1[TESTSIZE]={ + 0.105939f, + 0.215373f, + 0.429117f, + 0.587974f, + + 0.181173f, + 0.296583f, + 0.515707f, + 0.715261f, + + 0.162327f, + 0.263834f, + 0.342876f, + 0.406025f, + + 0.103571f, + 0.223561f, + 0.368513f, + 0.540313f, + + 0.136672f, + 0.395882f, + 0.587183f, + 0.652476f, + + 0.114338f, + 0.417300f, + 0.525486f, + 0.698679f, + + 0.147492f, + 0.324481f, + 0.643089f, + 0.757582f, + + 0.139556f, + 0.215795f, + 0.324559f, + 0.399387f, + + 0.120236f, + 0.267420f, + 0.446940f, + 0.608760f, + + 0.115587f, + 0.287234f, + 0.571081f, + 0.708603f, +}; + +float test3[TESTSIZE]={ + 0,1,-2,3,4,-5,6,7,8,9, + 8,-2,7,-1,4,6,8,3,1,-9, + 10,11,12,13,14,15,26,17,18,19, + 30,-25,-30,-1,-5,-32,4,3,-2,0}; + +static_codebook *testlist[]={&_vq_book_lsp20_0, + &_vq_book_res0a_13,NULL}; +float *testvec[]={test1,test3}; + +int main(){ + oggpack_buffer write; + oggpack_buffer read; + long ptr=0,i; + oggpack_writeinit(&write); + + fprintf(stderr,"Testing codebook abstraction...:\n"); + + while(testlist[ptr]){ + codebook c; + static_codebook s; + float *qv=alloca(sizeof(*qv)*TESTSIZE); + float *iv=alloca(sizeof(*iv)*TESTSIZE); + memcpy(qv,testvec[ptr],sizeof(*qv)*TESTSIZE); + memset(iv,0,sizeof(*iv)*TESTSIZE); + + fprintf(stderr,"\tpacking/coding %ld... ",ptr); + + /* pack the codebook, write the testvector */ + oggpack_reset(&write); + vorbis_book_init_encode(&c,testlist[ptr]); /* get it into memory + we can write */ + vorbis_staticbook_pack(testlist[ptr],&write); + fprintf(stderr,"Codebook size %ld bytes... ",oggpack_bytes(&write)); + for(i=0;i.000001){ + fprintf(stderr,"read (%g) != written (%g) at position (%ld)\n", + iv[i],qv[i],i); + exit(1); + } + + fprintf(stderr,"OK\n"); + ptr++; + } + + /* The above is the trivial stuff; now try unquantizing a log scale codebook */ + + exit(0); +} + +#endif diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/codebook.h b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/codebook.h new file mode 100644 index 0000000..2c1b738 --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/codebook.h @@ -0,0 +1,160 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: basic shared codebook operations + last mod: $Id: codebook.h 7187 2004-07-20 07:24:27Z xiphmont $ + + ********************************************************************/ + +#ifndef _V_CODEBOOK_H_ +#define _V_CODEBOOK_H_ + +#include + +/* This structure encapsulates huffman and VQ style encoding books; it + doesn't do anything specific to either. + + valuelist/quantlist are nonNULL (and q_* significant) only if + there's entry->value mapping to be done. + + If encode-side mapping must be done (and thus the entry needs to be + hunted), the auxiliary encode pointer will point to a decision + tree. This is true of both VQ and huffman, but is mostly useful + with VQ. + +*/ + +typedef struct static_codebook{ + long dim; /* codebook dimensions (elements per vector) */ + long entries; /* codebook entries */ + long *lengthlist; /* codeword lengths in bits */ + + /* mapping ***************************************************************/ + int maptype; /* 0=none + 1=implicitly populated values from map column + 2=listed arbitrary values */ + + /* The below does a linear, single monotonic sequence mapping. */ + long q_min; /* packed 32 bit float; quant value 0 maps to minval */ + long q_delta; /* packed 32 bit float; val 1 - val 0 == delta */ + int q_quant; /* bits: 0 < quant <= 16 */ + int q_sequencep; /* bitflag */ + + long *quantlist; /* map == 1: (int)(entries^(1/dim)) element column map + map == 2: list of dim*entries quantized entry vals + */ + + /* encode helpers ********************************************************/ + struct encode_aux_nearestmatch *nearest_tree; + struct encode_aux_threshmatch *thresh_tree; + struct encode_aux_pigeonhole *pigeon_tree; + + int allocedp; +} static_codebook; + +/* this structures an arbitrary trained book to quickly find the + nearest cell match */ +typedef struct encode_aux_nearestmatch{ + /* pre-calculated partitioning tree */ + long *ptr0; + long *ptr1; + + long *p; /* decision points (each is an entry) */ + long *q; /* decision points (each is an entry) */ + long aux; /* number of tree entries */ + long alloc; +} encode_aux_nearestmatch; + +/* assumes a maptype of 1; encode side only, so that's OK */ +typedef struct encode_aux_threshmatch{ + float *quantthresh; + long *quantmap; + int quantvals; + int threshvals; +} encode_aux_threshmatch; + +typedef struct encode_aux_pigeonhole{ + float min; + float del; + + int mapentries; + int quantvals; + long *pigeonmap; + + long fittotal; + long *fitlist; + long *fitmap; + long *fitlength; +} encode_aux_pigeonhole; + +typedef struct codebook{ + long dim; /* codebook dimensions (elements per vector) */ + long entries; /* codebook entries */ + long used_entries; /* populated codebook entries */ + const static_codebook *c; + + /* for encode, the below are entry-ordered, fully populated */ + /* for decode, the below are ordered by bitreversed codeword and only + used entries are populated */ + float *valuelist; /* list of dim*entries actual entry values */ + ogg_uint32_t *codelist; /* list of bitstream codewords for each entry */ + + int *dec_index; /* only used if sparseness collapsed */ + char *dec_codelengths; + ogg_uint32_t *dec_firsttable; + int dec_firsttablen; + int dec_maxlength; + +} codebook; + +extern void vorbis_staticbook_clear(static_codebook *b); +extern void vorbis_staticbook_destroy(static_codebook *b); +extern int vorbis_book_init_encode(codebook *dest,const static_codebook *source); +extern int vorbis_book_init_decode(codebook *dest,const static_codebook *source); +extern void vorbis_book_clear(codebook *b); + +extern float *_book_unquantize(const static_codebook *b,int n,int *map); +extern float *_book_logdist(const static_codebook *b,float *vals); +extern float _float32_unpack(long val); +extern long _float32_pack(float val); +extern int _best(codebook *book, float *a, int step); +extern int _ilog(unsigned int v); +extern long _book_maptype1_quantvals(const static_codebook *b); + +extern int vorbis_book_besterror(codebook *book,float *a,int step,int addmul); +extern long vorbis_book_codeword(codebook *book,int entry); +extern long vorbis_book_codelen(codebook *book,int entry); + + + +extern int vorbis_staticbook_pack(const static_codebook *c,oggpack_buffer *b); +extern int vorbis_staticbook_unpack(oggpack_buffer *b,static_codebook *c); + +extern int vorbis_book_encode(codebook *book, int a, oggpack_buffer *b); +extern int vorbis_book_errorv(codebook *book, float *a); +extern int vorbis_book_encodev(codebook *book, int best,float *a, + oggpack_buffer *b); + +extern long vorbis_book_decode(codebook *book, oggpack_buffer *b); +extern long vorbis_book_decodevs_add(codebook *book, float *a, + oggpack_buffer *b,int n); +extern long vorbis_book_decodev_set(codebook *book, float *a, + oggpack_buffer *b,int n); +extern long vorbis_book_decodev_add(codebook *book, float *a, + oggpack_buffer *b,int n); +extern long vorbis_book_decodevv_add(codebook *book, float **a, + long off,int ch, + oggpack_buffer *b,int n); + + + +#endif diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/codec_internal.h b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/codec_internal.h new file mode 100644 index 0000000..0029582 --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/codec_internal.h @@ -0,0 +1,137 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: libvorbis codec headers + last mod: $Id: codec_internal.h 7187 2004-07-20 07:24:27Z xiphmont $ + + ********************************************************************/ + +#ifndef _V_CODECI_H_ +#define _V_CODECI_H_ + +#include "envelope.h" +#include "codebook.h" + +#define BLOCKTYPE_IMPULSE 0 +#define BLOCKTYPE_PADDING 1 +#define BLOCKTYPE_TRANSITION 0 +#define BLOCKTYPE_LONG 1 + +#define PACKETBLOBS 15 + +typedef struct vorbis_block_internal{ + float **pcmdelay; /* this is a pointer into local storage */ + float ampmax; + int blocktype; + + oggpack_buffer *packetblob[PACKETBLOBS]; /* initialized, must be freed; + blob [PACKETBLOBS/2] points to + the oggpack_buffer in the + main vorbis_block */ +} vorbis_block_internal; + +typedef void vorbis_look_floor; +typedef void vorbis_look_residue; +typedef void vorbis_look_transform; + +/* mode ************************************************************/ +typedef struct { + int blockflag; + int windowtype; + int transformtype; + int mapping; +} vorbis_info_mode; + +typedef void vorbis_info_floor; +typedef void vorbis_info_residue; +typedef void vorbis_info_mapping; + +#include "psy.h" +#include "bitrate.h" + +typedef struct private_state { + /* local lookup storage */ + envelope_lookup *ve; /* envelope lookup */ + int window[2]; + vorbis_look_transform **transform[2]; /* block, type */ + drft_lookup fft_look[2]; + + int modebits; + vorbis_look_floor **flr; + vorbis_look_residue **residue; + vorbis_look_psy *psy; + vorbis_look_psy_global *psy_g_look; + + /* local storage, only used on the encoding side. This way the + application does not need to worry about freeing some packets' + memory and not others'; packet storage is always tracked. + Cleared next call to a _dsp_ function */ + unsigned char *header; + unsigned char *header1; + unsigned char *header2; + + bitrate_manager_state bms; + + ogg_int64_t sample_count; +} private_state; + +/* codec_setup_info contains all the setup information specific to the + specific compression/decompression mode in progress (eg, + psychoacoustic settings, channel setup, options, codebook + etc). +*********************************************************************/ + +#include "highlevel.h" +typedef struct codec_setup_info { + + /* Vorbis supports only short and long blocks, but allows the + encoder to choose the sizes */ + + long blocksizes[2]; + + /* modes are the primary means of supporting on-the-fly different + blocksizes, different channel mappings (LR or M/A), + different residue backends, etc. Each mode consists of a + blocksize flag and a mapping (along with the mapping setup */ + + int modes; + int maps; + int floors; + int residues; + int books; + int psys; /* encode only */ + + vorbis_info_mode *mode_param[64]; + int map_type[64]; + vorbis_info_mapping *map_param[64]; + int floor_type[64]; + vorbis_info_floor *floor_param[64]; + int residue_type[64]; + vorbis_info_residue *residue_param[64]; + static_codebook *book_param[256]; + codebook *fullbooks; + + vorbis_info_psy *psy_param[4]; /* encode only */ + vorbis_info_psy_global psy_g_param; + + bitrate_manager_info bi; + highlevel_encode_setup hi; /* used only by vorbisenc.c. It's a + highly redundant structure, but + improves clarity of program flow. */ + int halfrate_flag; /* painless downsample for decode */ +} codec_setup_info; + +extern vorbis_look_psy_global *_vp_global_look(vorbis_info *vi); +extern void _vp_global_free(vorbis_look_psy_global *look); + +#endif + diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/envelope.c b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/envelope.c new file mode 100644 index 0000000..75ddbc2 --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/envelope.c @@ -0,0 +1,382 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: PCM data envelope analysis + last mod: $Id: envelope.c 8921 2005-02-14 23:03:43Z msmith $ + + ********************************************************************/ + +#include +#include +#include +#include +#include +#include "vorbis/codec.h" +#include "codec_internal.h" + +#include "os.h" +#include "scales.h" +#include "envelope.h" +#include "mdct.h" +#include "misc.h" + +void _ve_envelope_init(envelope_lookup *e,vorbis_info *vi){ + codec_setup_info *ci=vi->codec_setup; + vorbis_info_psy_global *gi=&ci->psy_g_param; + int ch=vi->channels; + int i,j; + int n=e->winlength=128; + e->searchstep=64; /* not random */ + + e->minenergy=gi->preecho_minenergy; + e->ch=ch; + e->storage=128; + e->cursor=ci->blocksizes[1]/2; + e->mdct_win=_ogg_calloc(n,sizeof(*e->mdct_win)); + mdct_init(&e->mdct,n); + + for(i=0;imdct_win[i]=sin(i/(n-1.)*M_PI); + e->mdct_win[i]*=e->mdct_win[i]; + } + + /* magic follows */ + e->band[0].begin=2; e->band[0].end=4; + e->band[1].begin=4; e->band[1].end=5; + e->band[2].begin=6; e->band[2].end=6; + e->band[3].begin=9; e->band[3].end=8; + e->band[4].begin=13; e->band[4].end=8; + e->band[5].begin=17; e->band[5].end=8; + e->band[6].begin=22; e->band[6].end=8; + + for(j=0;jband[j].end; + e->band[j].window=_ogg_malloc(n*sizeof(*e->band[0].window)); + for(i=0;iband[j].window[i]=sin((i+.5)/n*M_PI); + e->band[j].total+=e->band[j].window[i]; + } + e->band[j].total=1./e->band[j].total; + } + + e->filter=_ogg_calloc(VE_BANDS*ch,sizeof(*e->filter)); + e->mark=_ogg_calloc(e->storage,sizeof(*e->mark)); + +} + +void _ve_envelope_clear(envelope_lookup *e){ + int i; + mdct_clear(&e->mdct); + for(i=0;iband[i].window); + _ogg_free(e->mdct_win); + _ogg_free(e->filter); + _ogg_free(e->mark); + memset(e,0,sizeof(*e)); +} + +/* fairly straight threshhold-by-band based until we find something + that works better and isn't patented. */ + +static int _ve_amp(envelope_lookup *ve, + vorbis_info_psy_global *gi, + float *data, + envelope_band *bands, + envelope_filter_state *filters, + long pos){ + long n=ve->winlength; + int ret=0; + long i,j; + float decay; + + /* we want to have a 'minimum bar' for energy, else we're just + basing blocks on quantization noise that outweighs the signal + itself (for low power signals) */ + + float minV=ve->minenergy; + float *vec=alloca(n*sizeof(*vec)); + + /* stretch is used to gradually lengthen the number of windows + considered prevoius-to-potential-trigger */ + int stretch=max(VE_MINSTRETCH,ve->stretch/2); + float penalty=gi->stretch_penalty-(ve->stretch/2-VE_MINSTRETCH); + if(penalty<0.f)penalty=0.f; + if(penalty>gi->stretch_penalty)penalty=gi->stretch_penalty; + + /*_analysis_output_always("lpcm",seq2,data,n,0,0, + totalshift+pos*ve->searchstep);*/ + + /* window and transform */ + for(i=0;imdct_win[i]; + mdct_forward(&ve->mdct,vec,vec); + + /*_analysis_output_always("mdct",seq2,vec,n/2,0,1,0); */ + + /* near-DC spreading function; this has nothing to do with + psychoacoustics, just sidelobe leakage and window size */ + { + float temp=vec[0]*vec[0]+.7*vec[1]*vec[1]+.2*vec[2]*vec[2]; + int ptr=filters->nearptr; + + /* the accumulation is regularly refreshed from scratch to avoid + floating point creep */ + if(ptr==0){ + decay=filters->nearDC_acc=filters->nearDC_partialacc+temp; + filters->nearDC_partialacc=temp; + }else{ + decay=filters->nearDC_acc+=temp; + filters->nearDC_partialacc+=temp; + } + filters->nearDC_acc-=filters->nearDC[ptr]; + filters->nearDC[ptr]=temp; + + decay*=(1./(VE_NEARDC+1)); + filters->nearptr++; + if(filters->nearptr>=VE_NEARDC)filters->nearptr=0; + decay=todB(&decay)*.5-15.f; + } + + /* perform spreading and limiting, also smooth the spectrum. yes, + the MDCT results in all real coefficients, but it still *behaves* + like real/imaginary pairs */ + for(i=0;i>1]=val; + decay-=8.; + } + + /*_analysis_output_always("spread",seq2++,vec,n/4,0,0,0);*/ + + /* perform preecho/postecho triggering by band */ + for(j=0;j=VE_AMP)filters[j].ampptr=0; + } + + /* look at min/max, decide trigger */ + if(valmax>gi->preecho_thresh[j]+penalty){ + ret|=1; + ret|=4; + } + if(valminpostecho_thresh[j]-penalty)ret|=2; + } + + return(ret); +} + +#if 0 +static int seq=0; +static ogg_int64_t totalshift=-1024; +#endif + +long _ve_envelope_search(vorbis_dsp_state *v){ + vorbis_info *vi=v->vi; + codec_setup_info *ci=vi->codec_setup; + vorbis_info_psy_global *gi=&ci->psy_g_param; + envelope_lookup *ve=((private_state *)(v->backend_state))->ve; + long i,j; + + int first=ve->current/ve->searchstep; + int last=v->pcm_current/ve->searchstep-VE_WIN; + if(first<0)first=0; + + /* make sure we have enough storage to match the PCM */ + if(last+VE_WIN+VE_POST>ve->storage){ + ve->storage=last+VE_WIN+VE_POST; /* be sure */ + ve->mark=_ogg_realloc(ve->mark,ve->storage*sizeof(*ve->mark)); + } + + for(j=first;jstretch++; + if(ve->stretch>VE_MAXSTRETCH*2) + ve->stretch=VE_MAXSTRETCH*2; + + for(i=0;ich;i++){ + float *pcm=v->pcm[i]+ve->searchstep*(j); + ret|=_ve_amp(ve,gi,pcm,ve->band,ve->filter+i*VE_BANDS,j); + } + + ve->mark[j+VE_POST]=0; + if(ret&1){ + ve->mark[j]=1; + ve->mark[j+1]=1; + } + + if(ret&2){ + ve->mark[j]=1; + if(j>0)ve->mark[j-1]=1; + } + + if(ret&4)ve->stretch=-1; + } + + ve->current=last*ve->searchstep; + + { + long centerW=v->centerW; + long testW= + centerW+ + ci->blocksizes[v->W]/4+ + ci->blocksizes[1]/2+ + ci->blocksizes[0]/4; + + j=ve->cursor; + + while(jcurrent-(ve->searchstep)){/* account for postecho + working back one window */ + if(j>=testW)return(1); + + ve->cursor=j; + + if(ve->mark[j/ve->searchstep]){ + if(j>centerW){ + +#if 0 + if(j>ve->curmark){ + float *marker=alloca(v->pcm_current*sizeof(*marker)); + int l,m; + memset(marker,0,sizeof(*marker)*v->pcm_current); + fprintf(stderr,"mark! seq=%d, cursor:%fs time:%fs\n", + seq, + (totalshift+ve->cursor)/44100., + (totalshift+j)/44100.); + _analysis_output_always("pcmL",seq,v->pcm[0],v->pcm_current,0,0,totalshift); + _analysis_output_always("pcmR",seq,v->pcm[1],v->pcm_current,0,0,totalshift); + + _analysis_output_always("markL",seq,v->pcm[0],j,0,0,totalshift); + _analysis_output_always("markR",seq,v->pcm[1],j,0,0,totalshift); + + for(m=0;msearchstep]=ve->filter[m].markers[l]*.1; + _analysis_output_always(buf,seq,marker,v->pcm_current,0,0,totalshift); + } + + for(m=0;msearchstep]=ve->filter[m+VE_BANDS].markers[l]*.1; + _analysis_output_always(buf,seq,marker,v->pcm_current,0,0,totalshift); + } + + for(l=0;lsearchstep]=ve->mark[l]*.4; + _analysis_output_always("mark",seq,marker,v->pcm_current,0,0,totalshift); + + + seq++; + + } +#endif + + ve->curmark=j; + if(j>=testW)return(1); + return(0); + } + } + j+=ve->searchstep; + } + } + + return(-1); +} + +int _ve_envelope_mark(vorbis_dsp_state *v){ + envelope_lookup *ve=((private_state *)(v->backend_state))->ve; + vorbis_info *vi=v->vi; + codec_setup_info *ci=vi->codec_setup; + long centerW=v->centerW; + long beginW=centerW-ci->blocksizes[v->W]/4; + long endW=centerW+ci->blocksizes[v->W]/4; + if(v->W){ + beginW-=ci->blocksizes[v->lW]/4; + endW+=ci->blocksizes[v->nW]/4; + }else{ + beginW-=ci->blocksizes[0]/4; + endW+=ci->blocksizes[0]/4; + } + + if(ve->curmark>=beginW && ve->curmarksearchstep; + long last=endW/ve->searchstep; + long i; + for(i=first;imark[i])return(1); + } + return(0); +} + +void _ve_envelope_shift(envelope_lookup *e,long shift){ + int smallsize=e->current/e->searchstep+VE_POST; /* adjust for placing marks + ahead of ve->current */ + int smallshift=shift/e->searchstep; + + memmove(e->mark,e->mark+smallshift,(smallsize-smallshift)*sizeof(*e->mark)); + +#if 0 + for(i=0;ich;i++) + memmove(e->filter[i].markers, + e->filter[i].markers+smallshift, + (1024-smallshift)*sizeof(*(*e->filter).markers)); + totalshift+=shift; +#endif + + e->current-=shift; + if(e->curmark>=0) + e->curmark-=shift; + e->cursor-=shift; +} + + + + + + diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/envelope.h b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/envelope.h new file mode 100644 index 0000000..a63b9c9 --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/envelope.h @@ -0,0 +1,81 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: PCM data envelope analysis and manipulation + last mod: $Id: envelope.h 7187 2004-07-20 07:24:27Z xiphmont $ + + ********************************************************************/ + +#ifndef _V_ENVELOPE_ +#define _V_ENVELOPE_ + +#include "mdct.h" + +#define VE_PRE 16 +#define VE_WIN 4 +#define VE_POST 2 +#define VE_AMP (VE_PRE+VE_POST-1) + +#define VE_BANDS 7 +#define VE_NEARDC 15 + +#define VE_MINSTRETCH 2 /* a bit less than short block */ +#define VE_MAXSTRETCH 12 /* one-third full block */ + +typedef struct { + float ampbuf[VE_AMP]; + int ampptr; + + float nearDC[VE_NEARDC]; + float nearDC_acc; + float nearDC_partialacc; + int nearptr; + +} envelope_filter_state; + +typedef struct { + int begin; + int end; + float *window; + float total; +} envelope_band; + +typedef struct { + int ch; + int winlength; + int searchstep; + float minenergy; + + mdct_lookup mdct; + float *mdct_win; + + envelope_band band[VE_BANDS]; + envelope_filter_state *filter; + int stretch; + + int *mark; + + long storage; + long current; + long curmark; + long cursor; +} envelope_lookup; + +extern void _ve_envelope_init(envelope_lookup *e,vorbis_info *vi); +extern void _ve_envelope_clear(envelope_lookup *e); +extern long _ve_envelope_search(vorbis_dsp_state *v); +extern void _ve_envelope_shift(envelope_lookup *e,long shift); +extern int _ve_envelope_mark(vorbis_dsp_state *v); + + +#endif + diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/floor0.c b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/floor0.c new file mode 100644 index 0000000..8c6aa72 --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/floor0.c @@ -0,0 +1,223 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: floor backend 0 implementation + last mod: $Id: floor0.c 7187 2004-07-20 07:24:27Z xiphmont $ + + ********************************************************************/ + +#include +#include +#include +#include +#include "vorbis/codec.h" +#include "codec_internal.h" +#include "registry.h" +#include "lpc.h" +#include "lsp.h" +#include "codebook.h" +#include "scales.h" +#include "misc.h" +#include "os.h" + +#include "misc.h" +#include + +typedef struct { + int ln; + int m; + int **linearmap; + int n[2]; + + vorbis_info_floor0 *vi; + + long bits; + long frames; +} vorbis_look_floor0; + + +/***********************************************/ + +static void floor0_free_info(vorbis_info_floor *i){ + vorbis_info_floor0 *info=(vorbis_info_floor0 *)i; + if(info){ + memset(info,0,sizeof(*info)); + _ogg_free(info); + } +} + +static void floor0_free_look(vorbis_look_floor *i){ + vorbis_look_floor0 *look=(vorbis_look_floor0 *)i; + if(look){ + + if(look->linearmap){ + + if(look->linearmap[0])_ogg_free(look->linearmap[0]); + if(look->linearmap[1])_ogg_free(look->linearmap[1]); + + _ogg_free(look->linearmap); + } + memset(look,0,sizeof(*look)); + _ogg_free(look); + } +} + +static vorbis_info_floor *floor0_unpack (vorbis_info *vi,oggpack_buffer *opb){ + codec_setup_info *ci=vi->codec_setup; + int j; + + vorbis_info_floor0 *info=_ogg_malloc(sizeof(*info)); + info->order=oggpack_read(opb,8); + info->rate=oggpack_read(opb,16); + info->barkmap=oggpack_read(opb,16); + info->ampbits=oggpack_read(opb,6); + info->ampdB=oggpack_read(opb,8); + info->numbooks=oggpack_read(opb,4)+1; + + if(info->order<1)goto err_out; + if(info->rate<1)goto err_out; + if(info->barkmap<1)goto err_out; + if(info->numbooks<1)goto err_out; + + for(j=0;jnumbooks;j++){ + info->books[j]=oggpack_read(opb,8); + if(info->books[j]<0 || info->books[j]>=ci->books)goto err_out; + } + return(info); + + err_out: + floor0_free_info(info); + return(NULL); +} + +/* initialize Bark scale and normalization lookups. We could do this + with static tables, but Vorbis allows a number of possible + combinations, so it's best to do it computationally. + + The below is authoritative in terms of defining scale mapping. + Note that the scale depends on the sampling rate as well as the + linear block and mapping sizes */ + +static void floor0_map_lazy_init(vorbis_block *vb, + vorbis_info_floor *infoX, + vorbis_look_floor0 *look){ + if(!look->linearmap[vb->W]){ + vorbis_dsp_state *vd=vb->vd; + vorbis_info *vi=vd->vi; + codec_setup_info *ci=vi->codec_setup; + vorbis_info_floor0 *info=(vorbis_info_floor0 *)infoX; + int W=vb->W; + int n=ci->blocksizes[W]/2,j; + + /* we choose a scaling constant so that: + floor(bark(rate/2-1)*C)=mapped-1 + floor(bark(rate/2)*C)=mapped */ + float scale=look->ln/toBARK(info->rate/2.f); + + /* the mapping from a linear scale to a smaller bark scale is + straightforward. We do *not* make sure that the linear mapping + does not skip bark-scale bins; the decoder simply skips them and + the encoder may do what it wishes in filling them. They're + necessary in some mapping combinations to keep the scale spacing + accurate */ + look->linearmap[W]=_ogg_malloc((n+1)*sizeof(**look->linearmap)); + for(j=0;jrate/2.f)/n*j) + *scale); /* bark numbers represent band edges */ + if(val>=look->ln)val=look->ln-1; /* guard against the approximation */ + look->linearmap[W][j]=val; + } + look->linearmap[W][j]=-1; + look->n[W]=n; + } +} + +static vorbis_look_floor *floor0_look(vorbis_dsp_state *vd, + vorbis_info_floor *i){ + vorbis_info_floor0 *info=(vorbis_info_floor0 *)i; + vorbis_look_floor0 *look=_ogg_calloc(1,sizeof(*look)); + look->m=info->order; + look->ln=info->barkmap; + look->vi=info; + + look->linearmap=_ogg_calloc(2,sizeof(*look->linearmap)); + + return look; +} + +static void *floor0_inverse1(vorbis_block *vb,vorbis_look_floor *i){ + vorbis_look_floor0 *look=(vorbis_look_floor0 *)i; + vorbis_info_floor0 *info=look->vi; + int j,k; + + int ampraw=oggpack_read(&vb->opb,info->ampbits); + if(ampraw>0){ /* also handles the -1 out of data case */ + long maxval=(1<ampbits)-1; + float amp=(float)ampraw/maxval*info->ampdB; + int booknum=oggpack_read(&vb->opb,_ilog(info->numbooks)); + + if(booknum!=-1 && booknumnumbooks){ /* be paranoid */ + codec_setup_info *ci=vb->vd->vi->codec_setup; + codebook *b=ci->fullbooks+info->books[booknum]; + float last=0.f; + + /* the additional b->dim is a guard against any possible stack + smash; b->dim is provably more than we can overflow the + vector */ + float *lsp=_vorbis_block_alloc(vb,sizeof(*lsp)*(look->m+b->dim+1)); + + for(j=0;jm;j+=b->dim) + if(vorbis_book_decodev_set(b,lsp+j,&vb->opb,b->dim)==-1)goto eop; + for(j=0;jm;){ + for(k=0;kdim;k++,j++)lsp[j]+=last; + last=lsp[j-1]; + } + + lsp[look->m]=amp; + return(lsp); + } + } + eop: + return(NULL); +} + +static int floor0_inverse2(vorbis_block *vb,vorbis_look_floor *i, + void *memo,float *out){ + vorbis_look_floor0 *look=(vorbis_look_floor0 *)i; + vorbis_info_floor0 *info=look->vi; + + floor0_map_lazy_init(vb,info,look); + + if(memo){ + float *lsp=(float *)memo; + float amp=lsp[look->m]; + + /* take the coefficients back to a spectral envelope curve */ + vorbis_lsp_to_curve(out, + look->linearmap[vb->W], + look->n[vb->W], + look->ln, + lsp,look->m,amp,(float)info->ampdB); + return(1); + } + memset(out,0,sizeof(*out)*look->n[vb->W]); + return(0); +} + +/* export hooks */ +vorbis_func_floor floor0_exportbundle={ + NULL,&floor0_unpack,&floor0_look,&floor0_free_info, + &floor0_free_look,&floor0_inverse1,&floor0_inverse2 +}; + + + diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/floor1.c b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/floor1.c new file mode 100644 index 0000000..6758503 --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/floor1.c @@ -0,0 +1,1090 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: floor backend 1 implementation + last mod: $Id: floor1.c 7187 2004-07-20 07:24:27Z xiphmont $ + + ********************************************************************/ + +#include +#include +#include +#include +#include "vorbis/codec.h" +#include "codec_internal.h" +#include "registry.h" +#include "codebook.h" +#include "misc.h" +#include "scales.h" + +#include + +#define floor1_rangedB 140 /* floor 1 fixed at -140dB to 0dB range */ + +typedef struct { + int sorted_index[VIF_POSIT+2]; + int forward_index[VIF_POSIT+2]; + int reverse_index[VIF_POSIT+2]; + + int hineighbor[VIF_POSIT]; + int loneighbor[VIF_POSIT]; + int posts; + + int n; + int quant_q; + vorbis_info_floor1 *vi; + + long phrasebits; + long postbits; + long frames; +} vorbis_look_floor1; + +typedef struct lsfit_acc{ + long x0; + long x1; + + long xa; + long ya; + long x2a; + long y2a; + long xya; + long an; +} lsfit_acc; + +/***********************************************/ + +static void floor1_free_info(vorbis_info_floor *i){ + vorbis_info_floor1 *info=(vorbis_info_floor1 *)i; + if(info){ + memset(info,0,sizeof(*info)); + _ogg_free(info); + } +} + +static void floor1_free_look(vorbis_look_floor *i){ + vorbis_look_floor1 *look=(vorbis_look_floor1 *)i; + if(look){ + /*fprintf(stderr,"floor 1 bit usage %f:%f (%f total)\n", + (float)look->phrasebits/look->frames, + (float)look->postbits/look->frames, + (float)(look->postbits+look->phrasebits)/look->frames);*/ + + memset(look,0,sizeof(*look)); + _ogg_free(look); + } +} + +static int ilog(unsigned int v){ + int ret=0; + while(v){ + ret++; + v>>=1; + } + return(ret); +} + +static int ilog2(unsigned int v){ + int ret=0; + if(v)--v; + while(v){ + ret++; + v>>=1; + } + return(ret); +} + +static void floor1_pack (vorbis_info_floor *i,oggpack_buffer *opb){ + vorbis_info_floor1 *info=(vorbis_info_floor1 *)i; + int j,k; + int count=0; + int rangebits; + int maxposit=info->postlist[1]; + int maxclass=-1; + + /* save out partitions */ + oggpack_write(opb,info->partitions,5); /* only 0 to 31 legal */ + for(j=0;jpartitions;j++){ + oggpack_write(opb,info->partitionclass[j],4); /* only 0 to 15 legal */ + if(maxclasspartitionclass[j])maxclass=info->partitionclass[j]; + } + + /* save out partition classes */ + for(j=0;jclass_dim[j]-1,3); /* 1 to 8 */ + oggpack_write(opb,info->class_subs[j],2); /* 0 to 3 */ + if(info->class_subs[j])oggpack_write(opb,info->class_book[j],8); + for(k=0;k<(1<class_subs[j]);k++) + oggpack_write(opb,info->class_subbook[j][k]+1,8); + } + + /* save out the post list */ + oggpack_write(opb,info->mult-1,2); /* only 1,2,3,4 legal now */ + oggpack_write(opb,ilog2(maxposit),4); + rangebits=ilog2(maxposit); + + for(j=0,k=0;jpartitions;j++){ + count+=info->class_dim[info->partitionclass[j]]; + for(;kpostlist[k+2],rangebits); + } +} + + +static vorbis_info_floor *floor1_unpack (vorbis_info *vi,oggpack_buffer *opb){ + codec_setup_info *ci=vi->codec_setup; + int j,k,count=0,maxclass=-1,rangebits; + + vorbis_info_floor1 *info=_ogg_calloc(1,sizeof(*info)); + /* read partitions */ + info->partitions=oggpack_read(opb,5); /* only 0 to 31 legal */ + for(j=0;jpartitions;j++){ + info->partitionclass[j]=oggpack_read(opb,4); /* only 0 to 15 legal */ + if(maxclasspartitionclass[j])maxclass=info->partitionclass[j]; + } + + /* read partition classes */ + for(j=0;jclass_dim[j]=oggpack_read(opb,3)+1; /* 1 to 8 */ + info->class_subs[j]=oggpack_read(opb,2); /* 0,1,2,3 bits */ + if(info->class_subs[j]<0) + goto err_out; + if(info->class_subs[j])info->class_book[j]=oggpack_read(opb,8); + if(info->class_book[j]<0 || info->class_book[j]>=ci->books) + goto err_out; + for(k=0;k<(1<class_subs[j]);k++){ + info->class_subbook[j][k]=oggpack_read(opb,8)-1; + if(info->class_subbook[j][k]<-1 || info->class_subbook[j][k]>=ci->books) + goto err_out; + } + } + + /* read the post list */ + info->mult=oggpack_read(opb,2)+1; /* only 1,2,3,4 legal now */ + rangebits=oggpack_read(opb,4); + + for(j=0,k=0;jpartitions;j++){ + count+=info->class_dim[info->partitionclass[j]]; + for(;kpostlist[k+2]=oggpack_read(opb,rangebits); + if(t<0 || t>=(1<postlist[0]=0; + info->postlist[1]=1<vi=info; + look->n=info->postlist[1]; + + /* we drop each position value in-between already decoded values, + and use linear interpolation to predict each new value past the + edges. The positions are read in the order of the position + list... we precompute the bounding positions in the lookup. Of + course, the neighbors can change (if a position is declined), but + this is an initial mapping */ + + for(i=0;ipartitions;i++)n+=info->class_dim[info->partitionclass[i]]; + n+=2; + look->posts=n; + + /* also store a sorted position index */ + for(i=0;ipostlist+i; + qsort(sortpointer,n,sizeof(*sortpointer),icomp); + + /* points from sort order back to range number */ + for(i=0;iforward_index[i]=sortpointer[i]-info->postlist; + /* points from range order to sorted position */ + for(i=0;ireverse_index[look->forward_index[i]]=i; + /* we actually need the post values too */ + for(i=0;isorted_index[i]=info->postlist[look->forward_index[i]]; + + /* quantize values to multiplier spec */ + switch(info->mult){ + case 1: /* 1024 -> 256 */ + look->quant_q=256; + break; + case 2: /* 1024 -> 128 */ + look->quant_q=128; + break; + case 3: /* 1024 -> 86 */ + look->quant_q=86; + break; + case 4: /* 1024 -> 64 */ + look->quant_q=64; + break; + } + + /* discover our neighbors for decode where we don't use fit flags + (that would push the neighbors outward) */ + for(i=0;in; + int currentx=info->postlist[i+2]; + for(j=0;jpostlist[j]; + if(x>lx && xcurrentx){ + hi=j; + hx=x; + } + } + look->loneighbor[i]=lo; + look->hineighbor[i]=hi; + } + + return(look); +} + +static int render_point(int x0,int x1,int y0,int y1,int x){ + y0&=0x7fff; /* mask off flag */ + y1&=0x7fff; + + { + int dy=y1-y0; + int adx=x1-x0; + int ady=abs(dy); + int err=ady*(x-x0); + + int off=err/adx; + if(dy<0)return(y0-off); + return(y0+off); + } +} + +static int vorbis_dBquant(const float *x){ + int i= *x*7.3142857f+1023.5f; + if(i>1023)return(1023); + if(i<0)return(0); + return i; +} + +static float FLOOR1_fromdB_LOOKUP[256]={ + 1.0649863e-07F, 1.1341951e-07F, 1.2079015e-07F, 1.2863978e-07F, + 1.3699951e-07F, 1.4590251e-07F, 1.5538408e-07F, 1.6548181e-07F, + 1.7623575e-07F, 1.8768855e-07F, 1.9988561e-07F, 2.128753e-07F, + 2.2670913e-07F, 2.4144197e-07F, 2.5713223e-07F, 2.7384213e-07F, + 2.9163793e-07F, 3.1059021e-07F, 3.3077411e-07F, 3.5226968e-07F, + 3.7516214e-07F, 3.9954229e-07F, 4.2550680e-07F, 4.5315863e-07F, + 4.8260743e-07F, 5.1396998e-07F, 5.4737065e-07F, 5.8294187e-07F, + 6.2082472e-07F, 6.6116941e-07F, 7.0413592e-07F, 7.4989464e-07F, + 7.9862701e-07F, 8.5052630e-07F, 9.0579828e-07F, 9.6466216e-07F, + 1.0273513e-06F, 1.0941144e-06F, 1.1652161e-06F, 1.2409384e-06F, + 1.3215816e-06F, 1.4074654e-06F, 1.4989305e-06F, 1.5963394e-06F, + 1.7000785e-06F, 1.8105592e-06F, 1.9282195e-06F, 2.0535261e-06F, + 2.1869758e-06F, 2.3290978e-06F, 2.4804557e-06F, 2.6416497e-06F, + 2.8133190e-06F, 2.9961443e-06F, 3.1908506e-06F, 3.3982101e-06F, + 3.6190449e-06F, 3.8542308e-06F, 4.1047004e-06F, 4.3714470e-06F, + 4.6555282e-06F, 4.9580707e-06F, 5.2802740e-06F, 5.6234160e-06F, + 5.9888572e-06F, 6.3780469e-06F, 6.7925283e-06F, 7.2339451e-06F, + 7.7040476e-06F, 8.2047000e-06F, 8.7378876e-06F, 9.3057248e-06F, + 9.9104632e-06F, 1.0554501e-05F, 1.1240392e-05F, 1.1970856e-05F, + 1.2748789e-05F, 1.3577278e-05F, 1.4459606e-05F, 1.5399272e-05F, + 1.6400004e-05F, 1.7465768e-05F, 1.8600792e-05F, 1.9809576e-05F, + 2.1096914e-05F, 2.2467911e-05F, 2.3928002e-05F, 2.5482978e-05F, + 2.7139006e-05F, 2.8902651e-05F, 3.0780908e-05F, 3.2781225e-05F, + 3.4911534e-05F, 3.7180282e-05F, 3.9596466e-05F, 4.2169667e-05F, + 4.4910090e-05F, 4.7828601e-05F, 5.0936773e-05F, 5.4246931e-05F, + 5.7772202e-05F, 6.1526565e-05F, 6.5524908e-05F, 6.9783085e-05F, + 7.4317983e-05F, 7.9147585e-05F, 8.4291040e-05F, 8.9768747e-05F, + 9.5602426e-05F, 0.00010181521F, 0.00010843174F, 0.00011547824F, + 0.00012298267F, 0.00013097477F, 0.00013948625F, 0.00014855085F, + 0.00015820453F, 0.00016848555F, 0.00017943469F, 0.00019109536F, + 0.00020351382F, 0.00021673929F, 0.00023082423F, 0.00024582449F, + 0.00026179955F, 0.00027881276F, 0.00029693158F, 0.00031622787F, + 0.00033677814F, 0.00035866388F, 0.00038197188F, 0.00040679456F, + 0.00043323036F, 0.00046138411F, 0.00049136745F, 0.00052329927F, + 0.00055730621F, 0.00059352311F, 0.00063209358F, 0.00067317058F, + 0.00071691700F, 0.00076350630F, 0.00081312324F, 0.00086596457F, + 0.00092223983F, 0.00098217216F, 0.0010459992F, 0.0011139742F, + 0.0011863665F, 0.0012634633F, 0.0013455702F, 0.0014330129F, + 0.0015261382F, 0.0016253153F, 0.0017309374F, 0.0018434235F, + 0.0019632195F, 0.0020908006F, 0.0022266726F, 0.0023713743F, + 0.0025254795F, 0.0026895994F, 0.0028643847F, 0.0030505286F, + 0.0032487691F, 0.0034598925F, 0.0036847358F, 0.0039241906F, + 0.0041792066F, 0.0044507950F, 0.0047400328F, 0.0050480668F, + 0.0053761186F, 0.0057254891F, 0.0060975636F, 0.0064938176F, + 0.0069158225F, 0.0073652516F, 0.0078438871F, 0.0083536271F, + 0.0088964928F, 0.009474637F, 0.010090352F, 0.010746080F, + 0.011444421F, 0.012188144F, 0.012980198F, 0.013823725F, + 0.014722068F, 0.015678791F, 0.016697687F, 0.017782797F, + 0.018938423F, 0.020169149F, 0.021479854F, 0.022875735F, + 0.024362330F, 0.025945531F, 0.027631618F, 0.029427276F, + 0.031339626F, 0.033376252F, 0.035545228F, 0.037855157F, + 0.040315199F, 0.042935108F, 0.045725273F, 0.048696758F, + 0.051861348F, 0.055231591F, 0.058820850F, 0.062643361F, + 0.066714279F, 0.071049749F, 0.075666962F, 0.080584227F, + 0.085821044F, 0.091398179F, 0.097337747F, 0.10366330F, + 0.11039993F, 0.11757434F, 0.12521498F, 0.13335215F, + 0.14201813F, 0.15124727F, 0.16107617F, 0.17154380F, + 0.18269168F, 0.19456402F, 0.20720788F, 0.22067342F, + 0.23501402F, 0.25028656F, 0.26655159F, 0.28387361F, + 0.30232132F, 0.32196786F, 0.34289114F, 0.36517414F, + 0.38890521F, 0.41417847F, 0.44109412F, 0.46975890F, + 0.50028648F, 0.53279791F, 0.56742212F, 0.60429640F, + 0.64356699F, 0.68538959F, 0.72993007F, 0.77736504F, + 0.82788260F, 0.88168307F, 0.9389798F, 1.F, +}; + +static void render_line(int x0,int x1,int y0,int y1,float *d){ + int dy=y1-y0; + int adx=x1-x0; + int ady=abs(dy); + int base=dy/adx; + int sy=(dy<0?base-1:base+1); + int x=x0; + int y=y0; + int err=0; + + ady-=abs(base*adx); + + d[x]*=FLOOR1_fromdB_LOOKUP[y]; + while(++x=adx){ + err-=adx; + y+=sy; + }else{ + y+=base; + } + d[x]*=FLOOR1_fromdB_LOOKUP[y]; + } +} + +static void render_line0(int x0,int x1,int y0,int y1,int *d){ + int dy=y1-y0; + int adx=x1-x0; + int ady=abs(dy); + int base=dy/adx; + int sy=(dy<0?base-1:base+1); + int x=x0; + int y=y0; + int err=0; + + ady-=abs(base*adx); + + d[x]=y; + while(++x=adx){ + err-=adx; + y+=sy; + }else{ + y+=base; + } + d[x]=y; + } +} + +/* the floor has already been filtered to only include relevant sections */ +static int accumulate_fit(const float *flr,const float *mdct, + int x0, int x1,lsfit_acc *a, + int n,vorbis_info_floor1 *info){ + long i; + int quantized=vorbis_dBquant(flr+x0); + + long xa=0,ya=0,x2a=0,y2a=0,xya=0,na=0, xb=0,yb=0,x2b=0,y2b=0,xyb=0,nb=0; + + memset(a,0,sizeof(*a)); + a->x0=x0; + a->x1=x1; + if(x1>=n)x1=n-1; + + for(i=x0;i<=x1;i++){ + int quantized=vorbis_dBquant(flr+i); + if(quantized){ + if(mdct[i]+info->twofitatten>=flr[i]){ + xa += i; + ya += quantized; + x2a += i*i; + y2a += quantized*quantized; + xya += i*quantized; + na++; + }else{ + xb += i; + yb += quantized; + x2b += i*i; + y2b += quantized*quantized; + xyb += i*quantized; + nb++; + } + } + } + + xb+=xa; + yb+=ya; + x2b+=x2a; + y2b+=y2a; + xyb+=xya; + nb+=na; + + /* weight toward the actually used frequencies if we meet the threshhold */ + { + int weight=nb*info->twofitweight/(na+1); + + a->xa=xa*weight+xb; + a->ya=ya*weight+yb; + a->x2a=x2a*weight+x2b; + a->y2a=y2a*weight+y2b; + a->xya=xya*weight+xyb; + a->an=na*weight+nb; + } + + return(na); +} + +static void fit_line(lsfit_acc *a,int fits,int *y0,int *y1){ + long x=0,y=0,x2=0,y2=0,xy=0,an=0,i; + long x0=a[0].x0; + long x1=a[fits-1].x1; + + for(i=0;i=0){ + x+= x0; + y+= *y0; + x2+= x0 * x0; + y2+= *y0 * *y0; + xy+= *y0 * x0; + an++; + } + + if(*y1>=0){ + x+= x1; + y+= *y1; + x2+= x1 * x1; + y2+= *y1 * *y1; + xy+= *y1 * x1; + an++; + } + + if(an){ + /* need 64 bit multiplies, which C doesn't give portably as int */ + double fx=x; + double fy=y; + double fx2=x2; + double fxy=xy; + double denom=1./(an*fx2-fx*fx); + double a=(fy*fx2-fxy*fx)*denom; + double b=(an*fxy-fx*fy)*denom; + *y0=rint(a+b*x0); + *y1=rint(a+b*x1); + + /* limit to our range! */ + if(*y0>1023)*y0=1023; + if(*y1>1023)*y1=1023; + if(*y0<0)*y0=0; + if(*y1<0)*y1=0; + + }else{ + *y0=0; + *y1=0; + } +} + +/*static void fit_line_point(lsfit_acc *a,int fits,int *y0,int *y1){ + long y=0; + int i; + + for(i=0;itwofitatten>=mask[x]){ + if(y+info->maxovermaxunder>val)return(1); + } + + while(++x=adx){ + err-=adx; + y+=sy; + }else{ + y+=base; + } + + val=vorbis_dBquant(mask+x); + mse+=((y-val)*(y-val)); + n++; + if(mdct[x]+info->twofitatten>=mask[x]){ + if(val){ + if(y+info->maxovermaxunder>val)return(1); + } + } + } + + if(info->maxover*info->maxover/n>info->maxerr)return(0); + if(info->maxunder*info->maxunder/n>info->maxerr)return(0); + if(mse/n>info->maxerr)return(1); + return(0); +} + +static int post_Y(int *A,int *B,int pos){ + if(A[pos]<0) + return B[pos]; + if(B[pos]<0) + return A[pos]; + + return (A[pos]+B[pos])>>1; +} + +static int seq=0; + +int *floor1_fit(vorbis_block *vb,vorbis_look_floor1 *look, + const float *logmdct, /* in */ + const float *logmask){ + long i,j; + vorbis_info_floor1 *info=look->vi; + long n=look->n; + long posts=look->posts; + long nonzero=0; + lsfit_acc fits[VIF_POSIT+1]; + int fit_valueA[VIF_POSIT+2]; /* index by range list position */ + int fit_valueB[VIF_POSIT+2]; /* index by range list position */ + + int loneighbor[VIF_POSIT+2]; /* sorted index of range list position (+2) */ + int hineighbor[VIF_POSIT+2]; + int *output=NULL; + int memo[VIF_POSIT+2]; + + for(i=0;isorted_index[i], + look->sorted_index[i+1],fits+i, + n,info); + } + + if(nonzero){ + /* start by fitting the implicit base case.... */ + int y0=-200; + int y1=-200; + fit_line(fits,posts-1,&y0,&y1); + + fit_valueA[0]=y0; + fit_valueB[0]=y0; + fit_valueB[1]=y1; + fit_valueA[1]=y1; + + /* Non degenerate case */ + /* start progressive splitting. This is a greedy, non-optimal + algorithm, but simple and close enough to the best + answer. */ + for(i=2;ireverse_index[i]; + int ln=loneighbor[sortpos]; + int hn=hineighbor[sortpos]; + + /* eliminate repeat searches of a particular range with a memo */ + if(memo[ln]!=hn){ + /* haven't performed this error search yet */ + int lsortpos=look->reverse_index[ln]; + int hsortpos=look->reverse_index[hn]; + memo[ln]=hn; + + { + /* A note: we want to bound/minimize *local*, not global, error */ + int lx=info->postlist[ln]; + int hx=info->postlist[hn]; + int ly=post_Y(fit_valueA,fit_valueB,ln); + int hy=post_Y(fit_valueA,fit_valueB,hn); + + if(ly==-1 || hy==-1){ + exit(1); + } + + if(inspect_error(lx,hx,ly,hy,logmask,logmdct,info)){ + /* outside error bounds/begin search area. Split it. */ + int ly0=-200; + int ly1=-200; + int hy0=-200; + int hy1=-200; + fit_line(fits+lsortpos,sortpos-lsortpos,&ly0,&ly1); + fit_line(fits+sortpos,hsortpos-sortpos,&hy0,&hy1); + + /* store new edge values */ + fit_valueB[ln]=ly0; + if(ln==0)fit_valueA[ln]=ly0; + fit_valueA[i]=ly1; + fit_valueB[i]=hy0; + fit_valueA[hn]=hy1; + if(hn==1)fit_valueB[hn]=hy1; + + if(ly1>=0 || hy0>=0){ + /* store new neighbor values */ + for(j=sortpos-1;j>=0;j--) + if(hineighbor[j]==hn) + hineighbor[j]=i; + else + break; + for(j=sortpos+1;jloneighbor[i-2]; + int hn=look->hineighbor[i-2]; + int x0=info->postlist[ln]; + int x1=info->postlist[hn]; + int y0=output[ln]; + int y1=output[hn]; + + int predicted=render_point(x0,x1,y0,y1,info->postlist[i]); + int vx=post_Y(fit_valueA,fit_valueB,i); + + if(vx>=0 && predicted!=vx){ + output[i]=vx; + }else{ + output[i]= predicted|0x8000; + } + } + } + + return(output); + +} + +int *floor1_interpolate_fit(vorbis_block *vb,vorbis_look_floor1 *look, + int *A,int *B, + int del){ + + long i; + long posts=look->posts; + int *output=NULL; + + if(A && B){ + output=_vorbis_block_alloc(vb,sizeof(*output)*posts); + + for(i=0;i>16; + if(A[i]&0x8000 && B[i]&0x8000)output[i]|=0x8000; + } + } + + return(output); +} + + +int floor1_encode(oggpack_buffer *opb,vorbis_block *vb, + vorbis_look_floor1 *look, + int *post,int *ilogmask){ + + long i,j; + vorbis_info_floor1 *info=look->vi; + long n=look->n; + long posts=look->posts; + codec_setup_info *ci=vb->vd->vi->codec_setup; + int out[VIF_POSIT+2]; + static_codebook **sbooks=ci->book_param; + codebook *books=ci->fullbooks; + static long seq=0; + + /* quantize values to multiplier spec */ + if(post){ + for(i=0;imult){ + case 1: /* 1024 -> 256 */ + val>>=2; + break; + case 2: /* 1024 -> 128 */ + val>>=3; + break; + case 3: /* 1024 -> 86 */ + val/=12; + break; + case 4: /* 1024 -> 64 */ + val>>=4; + break; + } + post[i]=val | (post[i]&0x8000); + } + + out[0]=post[0]; + out[1]=post[1]; + + /* find prediction values for each post and subtract them */ + for(i=2;iloneighbor[i-2]; + int hn=look->hineighbor[i-2]; + int x0=info->postlist[ln]; + int x1=info->postlist[hn]; + int y0=post[ln]; + int y1=post[hn]; + + int predicted=render_point(x0,x1,y0,y1,info->postlist[i]); + + if((post[i]&0x8000) || (predicted==post[i])){ + post[i]=predicted|0x8000; /* in case there was roundoff jitter + in interpolation */ + out[i]=0; + }else{ + int headroom=(look->quant_q-predictedquant_q-predicted:predicted); + + int val=post[i]-predicted; + + /* at this point the 'deviation' value is in the range +/- max + range, but the real, unique range can always be mapped to + only [0-maxrange). So we want to wrap the deviation into + this limited range, but do it in the way that least screws + an essentially gaussian probability distribution. */ + + if(val<0) + if(val<-headroom) + val=headroom-val-1; + else + val=-1-(val<<1); + else + if(val>=headroom) + val= val+headroom; + else + val<<=1; + + out[i]=val; + post[ln]&=0x7fff; + post[hn]&=0x7fff; + } + } + + /* we have everything we need. pack it out */ + /* mark nontrivial floor */ + oggpack_write(opb,1,1); + + /* beginning/end post */ + look->frames++; + look->postbits+=ilog(look->quant_q-1)*2; + oggpack_write(opb,out[0],ilog(look->quant_q-1)); + oggpack_write(opb,out[1],ilog(look->quant_q-1)); + + + /* partition by partition */ + for(i=0,j=2;ipartitions;i++){ + int class=info->partitionclass[i]; + int cdim=info->class_dim[class]; + int csubbits=info->class_subs[class]; + int csub=1<class_subbook[class][k]; + if(booknum<0){ + maxval[k]=1; + }else{ + maxval[k]=sbooks[info->class_subbook[class][k]]->entries; + } + } + for(k=0;kphrasebits+= + vorbis_book_encode(books+info->class_book[class],cval,opb); + +#ifdef TRAIN_FLOOR1 + { + FILE *of; + char buffer[80]; + sprintf(buffer,"line_%dx%ld_class%d.vqd", + vb->pcmend/2,posts-2,class); + of=fopen(buffer,"a"); + fprintf(of,"%d\n",cval); + fclose(of); + } +#endif + } + + /* write post values */ + for(k=0;kclass_subbook[class][bookas[k]]; + if(book>=0){ + /* hack to allow training with 'bad' books */ + if(out[j+k]<(books+book)->entries) + look->postbits+=vorbis_book_encode(books+book, + out[j+k],opb); + /*else + fprintf(stderr,"+!");*/ + +#ifdef TRAIN_FLOOR1 + { + FILE *of; + char buffer[80]; + sprintf(buffer,"line_%dx%ld_%dsub%d.vqd", + vb->pcmend/2,posts-2,class,bookas[k]); + of=fopen(buffer,"a"); + fprintf(of,"%d\n",out[j+k]); + fclose(of); + } +#endif + } + } + j+=cdim; + } + + { + /* generate quantized floor equivalent to what we'd unpack in decode */ + /* render the lines */ + int hx=0; + int lx=0; + int ly=post[0]*info->mult; + for(j=1;jposts;j++){ + int current=look->forward_index[j]; + int hy=post[current]&0x7fff; + if(hy==post[current]){ + + hy*=info->mult; + hx=info->postlist[current]; + + render_line0(lx,hx,ly,hy,ilogmask); + + lx=hx; + ly=hy; + } + } + for(j=hx;jpcmend/2;j++)ilogmask[j]=ly; /* be certain */ + seq++; + return(1); + } + }else{ + oggpack_write(opb,0,1); + memset(ilogmask,0,vb->pcmend/2*sizeof(*ilogmask)); + seq++; + return(0); + } +} + +static void *floor1_inverse1(vorbis_block *vb,vorbis_look_floor *in){ + vorbis_look_floor1 *look=(vorbis_look_floor1 *)in; + vorbis_info_floor1 *info=look->vi; + codec_setup_info *ci=vb->vd->vi->codec_setup; + + int i,j,k; + codebook *books=ci->fullbooks; + + /* unpack wrapped/predicted values from stream */ + if(oggpack_read(&vb->opb,1)==1){ + int *fit_value=_vorbis_block_alloc(vb,(look->posts)*sizeof(*fit_value)); + + fit_value[0]=oggpack_read(&vb->opb,ilog(look->quant_q-1)); + fit_value[1]=oggpack_read(&vb->opb,ilog(look->quant_q-1)); + + /* partition by partition */ + for(i=0,j=2;ipartitions;i++){ + int class=info->partitionclass[i]; + int cdim=info->class_dim[class]; + int csubbits=info->class_subs[class]; + int csub=1<class_book[class],&vb->opb); + + if(cval==-1)goto eop; + } + + for(k=0;kclass_subbook[class][cval&(csub-1)]; + cval>>=csubbits; + if(book>=0){ + if((fit_value[j+k]=vorbis_book_decode(books+book,&vb->opb))==-1) + goto eop; + }else{ + fit_value[j+k]=0; + } + } + j+=cdim; + } + + /* unwrap positive values and reconsitute via linear interpolation */ + for(i=2;iposts;i++){ + int predicted=render_point(info->postlist[look->loneighbor[i-2]], + info->postlist[look->hineighbor[i-2]], + fit_value[look->loneighbor[i-2]], + fit_value[look->hineighbor[i-2]], + info->postlist[i]); + int hiroom=look->quant_q-predicted; + int loroom=predicted; + int room=(hiroom=room){ + if(hiroom>loroom){ + val = val-loroom; + }else{ + val = -1-(val-hiroom); + } + }else{ + if(val&1){ + val= -((val+1)>>1); + }else{ + val>>=1; + } + } + + fit_value[i]=val+predicted; + fit_value[look->loneighbor[i-2]]&=0x7fff; + fit_value[look->hineighbor[i-2]]&=0x7fff; + + }else{ + fit_value[i]=predicted|0x8000; + } + + } + + return(fit_value); + } + eop: + return(NULL); +} + +static int floor1_inverse2(vorbis_block *vb,vorbis_look_floor *in,void *memo, + float *out){ + vorbis_look_floor1 *look=(vorbis_look_floor1 *)in; + vorbis_info_floor1 *info=look->vi; + + codec_setup_info *ci=vb->vd->vi->codec_setup; + int n=ci->blocksizes[vb->W]/2; + int j; + + if(memo){ + /* render the lines */ + int *fit_value=(int *)memo; + int hx=0; + int lx=0; + int ly=fit_value[0]*info->mult; + for(j=1;jposts;j++){ + int current=look->forward_index[j]; + int hy=fit_value[current]&0x7fff; + if(hy==fit_value[current]){ + + hy*=info->mult; + hx=info->postlist[current]; + + render_line(lx,hx,ly,hy,out); + + lx=hx; + ly=hy; + } + } + for(j=hx;j header packets + last mod: $Id: info.c 9513 2005-06-26 18:36:49Z giles $ + + ********************************************************************/ + +/* general handling of the header and the vorbis_info structure (and + substructures) */ + +#include +#include +#include +#include +#include "vorbis/codec.h" +#include "codec_internal.h" +#include "codebook.h" +#include "registry.h" +#include "window.h" +#include "psy.h" +#include "misc.h" +#include "os.h" + +/* helpers */ +static int ilog2(unsigned int v){ + int ret=0; + if(v)--v; + while(v){ + ret++; + v>>=1; + } + return(ret); +} + +static void _v_writestring(oggpack_buffer *o,char *s, int bytes){ + + while(bytes--){ + oggpack_write(o,*s++,8); + } +} + +static void _v_readstring(oggpack_buffer *o,char *buf,int bytes){ + while(bytes--){ + *buf++=oggpack_read(o,8); + } +} + +void vorbis_comment_init(vorbis_comment *vc){ + memset(vc,0,sizeof(*vc)); +} + +void vorbis_comment_add(vorbis_comment *vc,char *comment){ + vc->user_comments=_ogg_realloc(vc->user_comments, + (vc->comments+2)*sizeof(*vc->user_comments)); + vc->comment_lengths=_ogg_realloc(vc->comment_lengths, + (vc->comments+2)*sizeof(*vc->comment_lengths)); + vc->comment_lengths[vc->comments]=strlen(comment); + vc->user_comments[vc->comments]=_ogg_malloc(vc->comment_lengths[vc->comments]+1); + strcpy(vc->user_comments[vc->comments], comment); + vc->comments++; + vc->user_comments[vc->comments]=NULL; +} + +void vorbis_comment_add_tag(vorbis_comment *vc, char *tag, char *contents){ + char *comment=alloca(strlen(tag)+strlen(contents)+2); /* +2 for = and \0 */ + strcpy(comment, tag); + strcat(comment, "="); + strcat(comment, contents); + vorbis_comment_add(vc, comment); +} + +/* This is more or less the same as strncasecmp - but that doesn't exist + * everywhere, and this is a fairly trivial function, so we include it */ +static int tagcompare(const char *s1, const char *s2, int n){ + int c=0; + while(c < n){ + if(toupper(s1[c]) != toupper(s2[c])) + return !0; + c++; + } + return 0; +} + +char *vorbis_comment_query(vorbis_comment *vc, char *tag, int count){ + long i; + int found = 0; + int taglen = strlen(tag)+1; /* +1 for the = we append */ + char *fulltag = alloca(taglen+ 1); + + strcpy(fulltag, tag); + strcat(fulltag, "="); + + for(i=0;icomments;i++){ + if(!tagcompare(vc->user_comments[i], fulltag, taglen)){ + if(count == found) + /* We return a pointer to the data, not a copy */ + return vc->user_comments[i] + taglen; + else + found++; + } + } + return NULL; /* didn't find anything */ +} + +int vorbis_comment_query_count(vorbis_comment *vc, char *tag){ + int i,count=0; + int taglen = strlen(tag)+1; /* +1 for the = we append */ + char *fulltag = alloca(taglen+1); + strcpy(fulltag,tag); + strcat(fulltag, "="); + + for(i=0;icomments;i++){ + if(!tagcompare(vc->user_comments[i], fulltag, taglen)) + count++; + } + + return count; +} + +void vorbis_comment_clear(vorbis_comment *vc){ + if(vc){ + long i; + for(i=0;icomments;i++) + if(vc->user_comments[i])_ogg_free(vc->user_comments[i]); + if(vc->user_comments)_ogg_free(vc->user_comments); + if(vc->comment_lengths)_ogg_free(vc->comment_lengths); + if(vc->vendor)_ogg_free(vc->vendor); + } + memset(vc,0,sizeof(*vc)); +} + +/* blocksize 0 is guaranteed to be short, 1 is guarantted to be long. + They may be equal, but short will never ge greater than long */ +int vorbis_info_blocksize(vorbis_info *vi,int zo){ + codec_setup_info *ci = vi->codec_setup; + return ci ? ci->blocksizes[zo] : -1; +} + +/* used by synthesis, which has a full, alloced vi */ +void vorbis_info_init(vorbis_info *vi){ + memset(vi,0,sizeof(*vi)); + vi->codec_setup=_ogg_calloc(1,sizeof(codec_setup_info)); +} + +void vorbis_info_clear(vorbis_info *vi){ + codec_setup_info *ci=vi->codec_setup; + int i; + + if(ci){ + + for(i=0;imodes;i++) + if(ci->mode_param[i])_ogg_free(ci->mode_param[i]); + + for(i=0;imaps;i++) /* unpack does the range checking */ + _mapping_P[ci->map_type[i]]->free_info(ci->map_param[i]); + + for(i=0;ifloors;i++) /* unpack does the range checking */ + _floor_P[ci->floor_type[i]]->free_info(ci->floor_param[i]); + + for(i=0;iresidues;i++) /* unpack does the range checking */ + _residue_P[ci->residue_type[i]]->free_info(ci->residue_param[i]); + + for(i=0;ibooks;i++){ + if(ci->book_param[i]){ + /* knows if the book was not alloced */ + vorbis_staticbook_destroy(ci->book_param[i]); + } + if(ci->fullbooks) + vorbis_book_clear(ci->fullbooks+i); + } + if(ci->fullbooks) + _ogg_free(ci->fullbooks); + + for(i=0;ipsys;i++) + _vi_psy_free(ci->psy_param[i]); + + _ogg_free(ci); + } + + memset(vi,0,sizeof(*vi)); +} + +/* Header packing/unpacking ********************************************/ + +static int _vorbis_unpack_info(vorbis_info *vi,oggpack_buffer *opb){ + codec_setup_info *ci=vi->codec_setup; + if(!ci)return(OV_EFAULT); + + vi->version=oggpack_read(opb,32); + if(vi->version!=0)return(OV_EVERSION); + + vi->channels=oggpack_read(opb,8); + vi->rate=oggpack_read(opb,32); + + vi->bitrate_upper=oggpack_read(opb,32); + vi->bitrate_nominal=oggpack_read(opb,32); + vi->bitrate_lower=oggpack_read(opb,32); + + ci->blocksizes[0]=1<blocksizes[1]=1<rate<1)goto err_out; + if(vi->channels<1)goto err_out; + if(ci->blocksizes[0]<8)goto err_out; + if(ci->blocksizes[1]blocksizes[0])goto err_out; + + if(oggpack_read(opb,1)!=1)goto err_out; /* EOP check */ + + return(0); + err_out: + vorbis_info_clear(vi); + return(OV_EBADHEADER); +} + +static int _vorbis_unpack_comment(vorbis_comment *vc,oggpack_buffer *opb){ + int i; + int vendorlen=oggpack_read(opb,32); + if(vendorlen<0)goto err_out; + vc->vendor=_ogg_calloc(vendorlen+1,1); + _v_readstring(opb,vc->vendor,vendorlen); + vc->comments=oggpack_read(opb,32); + if(vc->comments<0)goto err_out; + vc->user_comments=_ogg_calloc(vc->comments+1,sizeof(*vc->user_comments)); + vc->comment_lengths=_ogg_calloc(vc->comments+1, sizeof(*vc->comment_lengths)); + + for(i=0;icomments;i++){ + int len=oggpack_read(opb,32); + if(len<0)goto err_out; + vc->comment_lengths[i]=len; + vc->user_comments[i]=_ogg_calloc(len+1,1); + _v_readstring(opb,vc->user_comments[i],len); + } + if(oggpack_read(opb,1)!=1)goto err_out; /* EOP check */ + + return(0); + err_out: + vorbis_comment_clear(vc); + return(OV_EBADHEADER); +} + +/* all of the real encoding details are here. The modes, books, + everything */ +static int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb){ + codec_setup_info *ci=vi->codec_setup; + int i; + if(!ci)return(OV_EFAULT); + + /* codebooks */ + ci->books=oggpack_read(opb,8)+1; + /*ci->book_param=_ogg_calloc(ci->books,sizeof(*ci->book_param));*/ + for(i=0;ibooks;i++){ + ci->book_param[i]=_ogg_calloc(1,sizeof(*ci->book_param[i])); + if(vorbis_staticbook_unpack(opb,ci->book_param[i]))goto err_out; + } + + /* time backend settings; hooks are unused */ + { + int times=oggpack_read(opb,6)+1; + for(i=0;i=VI_TIMEB)goto err_out; + } + } + + /* floor backend settings */ + ci->floors=oggpack_read(opb,6)+1; + /*ci->floor_type=_ogg_malloc(ci->floors*sizeof(*ci->floor_type));*/ + /*ci->floor_param=_ogg_calloc(ci->floors,sizeof(void *));*/ + for(i=0;ifloors;i++){ + ci->floor_type[i]=oggpack_read(opb,16); + if(ci->floor_type[i]<0 || ci->floor_type[i]>=VI_FLOORB)goto err_out; + ci->floor_param[i]=_floor_P[ci->floor_type[i]]->unpack(vi,opb); + if(!ci->floor_param[i])goto err_out; + } + + /* residue backend settings */ + ci->residues=oggpack_read(opb,6)+1; + /*ci->residue_type=_ogg_malloc(ci->residues*sizeof(*ci->residue_type));*/ + /*ci->residue_param=_ogg_calloc(ci->residues,sizeof(void *));*/ + for(i=0;iresidues;i++){ + ci->residue_type[i]=oggpack_read(opb,16); + if(ci->residue_type[i]<0 || ci->residue_type[i]>=VI_RESB)goto err_out; + ci->residue_param[i]=_residue_P[ci->residue_type[i]]->unpack(vi,opb); + if(!ci->residue_param[i])goto err_out; + } + + /* map backend settings */ + ci->maps=oggpack_read(opb,6)+1; + /*ci->map_type=_ogg_malloc(ci->maps*sizeof(*ci->map_type));*/ + /*ci->map_param=_ogg_calloc(ci->maps,sizeof(void *));*/ + for(i=0;imaps;i++){ + ci->map_type[i]=oggpack_read(opb,16); + if(ci->map_type[i]<0 || ci->map_type[i]>=VI_MAPB)goto err_out; + ci->map_param[i]=_mapping_P[ci->map_type[i]]->unpack(vi,opb); + if(!ci->map_param[i])goto err_out; + } + + /* mode settings */ + ci->modes=oggpack_read(opb,6)+1; + /*vi->mode_param=_ogg_calloc(vi->modes,sizeof(void *));*/ + for(i=0;imodes;i++){ + ci->mode_param[i]=_ogg_calloc(1,sizeof(*ci->mode_param[i])); + ci->mode_param[i]->blockflag=oggpack_read(opb,1); + ci->mode_param[i]->windowtype=oggpack_read(opb,16); + ci->mode_param[i]->transformtype=oggpack_read(opb,16); + ci->mode_param[i]->mapping=oggpack_read(opb,8); + + if(ci->mode_param[i]->windowtype>=VI_WINDOWB)goto err_out; + if(ci->mode_param[i]->transformtype>=VI_WINDOWB)goto err_out; + if(ci->mode_param[i]->mapping>=ci->maps)goto err_out; + } + + if(oggpack_read(opb,1)!=1)goto err_out; /* top level EOP check */ + + return(0); + err_out: + vorbis_info_clear(vi); + return(OV_EBADHEADER); +} + +/* The Vorbis header is in three packets; the initial small packet in + the first page that identifies basic parameters, a second packet + with bitstream comments and a third packet that holds the + codebook. */ + +int vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc,ogg_packet *op){ + oggpack_buffer opb; + + if(op){ + oggpack_readinit(&opb,op->packet,op->bytes); + + /* Which of the three types of header is this? */ + /* Also verify header-ness, vorbis */ + { + char buffer[6]; + int packtype=oggpack_read(&opb,8); + memset(buffer,0,6); + _v_readstring(&opb,buffer,6); + if(memcmp(buffer,"vorbis",6)){ + /* not a vorbis header */ + return(OV_ENOTVORBIS); + } + switch(packtype){ + case 0x01: /* least significant *bit* is read first */ + if(!op->b_o_s){ + /* Not the initial packet */ + return(OV_EBADHEADER); + } + if(vi->rate!=0){ + /* previously initialized info header */ + return(OV_EBADHEADER); + } + + return(_vorbis_unpack_info(vi,&opb)); + + case 0x03: /* least significant *bit* is read first */ + if(vi->rate==0){ + /* um... we didn't get the initial header */ + return(OV_EBADHEADER); + } + + return(_vorbis_unpack_comment(vc,&opb)); + + case 0x05: /* least significant *bit* is read first */ + if(vi->rate==0 || vc->vendor==NULL){ + /* um... we didn;t get the initial header or comments yet */ + return(OV_EBADHEADER); + } + + return(_vorbis_unpack_books(vi,&opb)); + + default: + /* Not a valid vorbis header type */ + return(OV_EBADHEADER); + break; + } + } + } + return(OV_EBADHEADER); +} + +/* pack side **********************************************************/ + +static int _vorbis_pack_info(oggpack_buffer *opb,vorbis_info *vi){ + codec_setup_info *ci=vi->codec_setup; + if(!ci)return(OV_EFAULT); + + /* preamble */ + oggpack_write(opb,0x01,8); + _v_writestring(opb,"vorbis", 6); + + /* basic information about the stream */ + oggpack_write(opb,0x00,32); + oggpack_write(opb,vi->channels,8); + oggpack_write(opb,vi->rate,32); + + oggpack_write(opb,vi->bitrate_upper,32); + oggpack_write(opb,vi->bitrate_nominal,32); + oggpack_write(opb,vi->bitrate_lower,32); + + oggpack_write(opb,ilog2(ci->blocksizes[0]),4); + oggpack_write(opb,ilog2(ci->blocksizes[1]),4); + oggpack_write(opb,1,1); + + return(0); +} + +static int _vorbis_pack_comment(oggpack_buffer *opb,vorbis_comment *vc){ + char temp[]="Xiph.Org libVorbis I 20050304"; + int bytes = strlen(temp); + + /* preamble */ + oggpack_write(opb,0x03,8); + _v_writestring(opb,"vorbis", 6); + + /* vendor */ + oggpack_write(opb,bytes,32); + _v_writestring(opb,temp, bytes); + + /* comments */ + + oggpack_write(opb,vc->comments,32); + if(vc->comments){ + int i; + for(i=0;icomments;i++){ + if(vc->user_comments[i]){ + oggpack_write(opb,vc->comment_lengths[i],32); + _v_writestring(opb,vc->user_comments[i], vc->comment_lengths[i]); + }else{ + oggpack_write(opb,0,32); + } + } + } + oggpack_write(opb,1,1); + + return(0); +} + +static int _vorbis_pack_books(oggpack_buffer *opb,vorbis_info *vi){ + codec_setup_info *ci=vi->codec_setup; + int i; + if(!ci)return(OV_EFAULT); + + oggpack_write(opb,0x05,8); + _v_writestring(opb,"vorbis", 6); + + /* books */ + oggpack_write(opb,ci->books-1,8); + for(i=0;ibooks;i++) + if(vorbis_staticbook_pack(ci->book_param[i],opb))goto err_out; + + /* times; hook placeholders */ + oggpack_write(opb,0,6); + oggpack_write(opb,0,16); + + /* floors */ + oggpack_write(opb,ci->floors-1,6); + for(i=0;ifloors;i++){ + oggpack_write(opb,ci->floor_type[i],16); + if(_floor_P[ci->floor_type[i]]->pack) + _floor_P[ci->floor_type[i]]->pack(ci->floor_param[i],opb); + else + goto err_out; + } + + /* residues */ + oggpack_write(opb,ci->residues-1,6); + for(i=0;iresidues;i++){ + oggpack_write(opb,ci->residue_type[i],16); + _residue_P[ci->residue_type[i]]->pack(ci->residue_param[i],opb); + } + + /* maps */ + oggpack_write(opb,ci->maps-1,6); + for(i=0;imaps;i++){ + oggpack_write(opb,ci->map_type[i],16); + _mapping_P[ci->map_type[i]]->pack(vi,ci->map_param[i],opb); + } + + /* modes */ + oggpack_write(opb,ci->modes-1,6); + for(i=0;imodes;i++){ + oggpack_write(opb,ci->mode_param[i]->blockflag,1); + oggpack_write(opb,ci->mode_param[i]->windowtype,16); + oggpack_write(opb,ci->mode_param[i]->transformtype,16); + oggpack_write(opb,ci->mode_param[i]->mapping,8); + } + oggpack_write(opb,1,1); + + return(0); +err_out: + return(-1); +} + +int vorbis_commentheader_out(vorbis_comment *vc, + ogg_packet *op){ + + oggpack_buffer opb; + + oggpack_writeinit(&opb); + if(_vorbis_pack_comment(&opb,vc)) return OV_EIMPL; + + op->packet = _ogg_malloc(oggpack_bytes(&opb)); + memcpy(op->packet, opb.buffer, oggpack_bytes(&opb)); + + op->bytes=oggpack_bytes(&opb); + op->b_o_s=0; + op->e_o_s=0; + op->granulepos=0; + op->packetno=1; + + return 0; +} + +int vorbis_analysis_headerout(vorbis_dsp_state *v, + vorbis_comment *vc, + ogg_packet *op, + ogg_packet *op_comm, + ogg_packet *op_code){ + int ret=OV_EIMPL; + vorbis_info *vi=v->vi; + oggpack_buffer opb; + private_state *b=v->backend_state; + + if(!b){ + ret=OV_EFAULT; + goto err_out; + } + + /* first header packet **********************************************/ + + oggpack_writeinit(&opb); + if(_vorbis_pack_info(&opb,vi))goto err_out; + + /* build the packet */ + if(b->header)_ogg_free(b->header); + b->header=_ogg_malloc(oggpack_bytes(&opb)); + memcpy(b->header,opb.buffer,oggpack_bytes(&opb)); + op->packet=b->header; + op->bytes=oggpack_bytes(&opb); + op->b_o_s=1; + op->e_o_s=0; + op->granulepos=0; + op->packetno=0; + + /* second header packet (comments) **********************************/ + + oggpack_reset(&opb); + if(_vorbis_pack_comment(&opb,vc))goto err_out; + + if(b->header1)_ogg_free(b->header1); + b->header1=_ogg_malloc(oggpack_bytes(&opb)); + memcpy(b->header1,opb.buffer,oggpack_bytes(&opb)); + op_comm->packet=b->header1; + op_comm->bytes=oggpack_bytes(&opb); + op_comm->b_o_s=0; + op_comm->e_o_s=0; + op_comm->granulepos=0; + op_comm->packetno=1; + + /* third header packet (modes/codebooks) ****************************/ + + oggpack_reset(&opb); + if(_vorbis_pack_books(&opb,vi))goto err_out; + + if(b->header2)_ogg_free(b->header2); + b->header2=_ogg_malloc(oggpack_bytes(&opb)); + memcpy(b->header2,opb.buffer,oggpack_bytes(&opb)); + op_code->packet=b->header2; + op_code->bytes=oggpack_bytes(&opb); + op_code->b_o_s=0; + op_code->e_o_s=0; + op_code->granulepos=0; + op_code->packetno=2; + + oggpack_writeclear(&opb); + return(0); + err_out: + oggpack_writeclear(&opb); + memset(op,0,sizeof(*op)); + memset(op_comm,0,sizeof(*op_comm)); + memset(op_code,0,sizeof(*op_code)); + + if(b->header)_ogg_free(b->header); + if(b->header1)_ogg_free(b->header1); + if(b->header2)_ogg_free(b->header2); + b->header=NULL; + b->header1=NULL; + b->header2=NULL; + return(ret); +} + +double vorbis_granule_time(vorbis_dsp_state *v,ogg_int64_t granulepos){ + if(granulepos>=0) + return((double)granulepos/v->vi->rate); + return(-1); +} diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/lookup.c b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/lookup.c new file mode 100644 index 0000000..ff18110 --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/lookup.c @@ -0,0 +1,94 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: lookup based functions + last mod: $Id: lookup.c 7187 2004-07-20 07:24:27Z xiphmont $ + + ********************************************************************/ + +#include +#include "lookup.h" +#include "lookup_data.h" +#include "os.h" +#include "misc.h" + +#ifdef FLOAT_LOOKUP + +/* interpolated lookup based cos function, domain 0 to PI only */ +float vorbis_coslook(float a){ + double d=a*(.31830989*(float)COS_LOOKUP_SZ); + int i=vorbis_ftoi(d-.5); + + return COS_LOOKUP[i]+ (d-i)*(COS_LOOKUP[i+1]-COS_LOOKUP[i]); +} + +/* interpolated 1./sqrt(p) where .5 <= p < 1. */ +float vorbis_invsqlook(float a){ + double d=a*(2.f*(float)INVSQ_LOOKUP_SZ)-(float)INVSQ_LOOKUP_SZ; + int i=vorbis_ftoi(d-.5f); + return INVSQ_LOOKUP[i]+ (d-i)*(INVSQ_LOOKUP[i+1]-INVSQ_LOOKUP[i]); +} + +/* interpolated 1./sqrt(p) where .5 <= p < 1. */ +float vorbis_invsq2explook(int a){ + return INVSQ2EXP_LOOKUP[a-INVSQ2EXP_LOOKUP_MIN]; +} + +#include +/* interpolated lookup based fromdB function, domain -140dB to 0dB only */ +float vorbis_fromdBlook(float a){ + int i=vorbis_ftoi(a*((float)(-(1<=(FROMdB_LOOKUP_SZ<>FROMdB_SHIFT]*FROMdB2_LOOKUP[i&FROMdB2_MASK]); +} + +#endif + +#ifdef INT_LOOKUP +/* interpolated 1./sqrt(p) where .5 <= a < 1. (.100000... to .111111...) in + 16.16 format + + returns in m.8 format */ +long vorbis_invsqlook_i(long a,long e){ + long i=(a&0x7fff)>>(INVSQ_LOOKUP_I_SHIFT-1); + long d=(a&INVSQ_LOOKUP_I_MASK)<<(16-INVSQ_LOOKUP_I_SHIFT); /* 0.16 */ + long val=INVSQ_LOOKUP_I[i]- /* 1.16 */ + (((INVSQ_LOOKUP_I[i]-INVSQ_LOOKUP_I[i+1])* /* 0.16 */ + d)>>16); /* result 1.16 */ + + e+=32; + if(e&1)val=(val*5792)>>13; /* multiply val by 1/sqrt(2) */ + e=(e>>1)-8; + + return(val>>e); +} + +/* interpolated lookup based fromdB function, domain -140dB to 0dB only */ +/* a is in n.12 format */ +float vorbis_fromdBlook_i(long a){ + int i=(-a)>>(12-FROMdB2_SHIFT); + return (i<0)?1.f: + ((i>=(FROMdB_LOOKUP_SZ<>FROMdB_SHIFT]*FROMdB2_LOOKUP[i&FROMdB2_MASK]); +} + +/* interpolated lookup based cos function, domain 0 to PI only */ +/* a is in 0.16 format, where 0==0, 2^^16-1==PI, return 0.14 */ +long vorbis_coslook_i(long a){ + int i=a>>COS_LOOKUP_I_SHIFT; + int d=a&COS_LOOKUP_I_MASK; + return COS_LOOKUP_I[i]- ((d*(COS_LOOKUP_I[i]-COS_LOOKUP_I[i+1]))>> + COS_LOOKUP_I_SHIFT); +} + +#endif diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/lookup.h b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/lookup.h new file mode 100644 index 0000000..2ee0904 --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/lookup.h @@ -0,0 +1,32 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: lookup based functions + last mod: $Id: lookup.h 7187 2004-07-20 07:24:27Z xiphmont $ + + ********************************************************************/ + +#ifndef _V_LOOKUP_H_ + +#ifdef FLOAT_LOOKUP +extern float vorbis_coslook(float a); +extern float vorbis_invsqlook(float a); +extern float vorbis_invsq2explook(int a); +extern float vorbis_fromdBlook(float a); +#endif +#ifdef INT_LOOKUP +extern long vorbis_invsqlook_i(long a,long e); +extern long vorbis_coslook_i(long a); +extern float vorbis_fromdBlook_i(long a); +#endif + +#endif diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/lookup_data.h b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/lookup_data.h new file mode 100644 index 0000000..e131605 --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/lookup_data.h @@ -0,0 +1,189 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: lookup data; generated by lookups.pl; edit there + last mod: $Id: lookup_data.h 7187 2004-07-20 07:24:27Z xiphmont $ + + ********************************************************************/ + +#ifndef _V_LOOKUP_DATA_H_ + +#ifdef FLOAT_LOOKUP +#define COS_LOOKUP_SZ 128 +static float COS_LOOKUP[COS_LOOKUP_SZ+1]={ + +1.0000000000000f,+0.9996988186962f,+0.9987954562052f,+0.9972904566787f, + +0.9951847266722f,+0.9924795345987f,+0.9891765099648f,+0.9852776423889f, + +0.9807852804032f,+0.9757021300385f,+0.9700312531945f,+0.9637760657954f, + +0.9569403357322f,+0.9495281805930f,+0.9415440651830f,+0.9329927988347f, + +0.9238795325113f,+0.9142097557035f,+0.9039892931234f,+0.8932243011955f, + +0.8819212643484f,+0.8700869911087f,+0.8577286100003f,+0.8448535652497f, + +0.8314696123025f,+0.8175848131516f,+0.8032075314806f,+0.7883464276266f, + +0.7730104533627f,+0.7572088465065f,+0.7409511253550f,+0.7242470829515f, + +0.7071067811865f,+0.6895405447371f,+0.6715589548470f,+0.6531728429538f, + +0.6343932841636f,+0.6152315905806f,+0.5956993044924f,+0.5758081914178f, + +0.5555702330196f,+0.5349976198871f,+0.5141027441932f,+0.4928981922298f, + +0.4713967368260f,+0.4496113296546f,+0.4275550934303f,+0.4052413140050f, + +0.3826834323651f,+0.3598950365350f,+0.3368898533922f,+0.3136817403989f, + +0.2902846772545f,+0.2667127574749f,+0.2429801799033f,+0.2191012401569f, + +0.1950903220161f,+0.1709618887603f,+0.1467304744554f,+0.1224106751992f, + +0.0980171403296f,+0.0735645635997f,+0.0490676743274f,+0.0245412285229f, + +0.0000000000000f,-0.0245412285229f,-0.0490676743274f,-0.0735645635997f, + -0.0980171403296f,-0.1224106751992f,-0.1467304744554f,-0.1709618887603f, + -0.1950903220161f,-0.2191012401569f,-0.2429801799033f,-0.2667127574749f, + -0.2902846772545f,-0.3136817403989f,-0.3368898533922f,-0.3598950365350f, + -0.3826834323651f,-0.4052413140050f,-0.4275550934303f,-0.4496113296546f, + -0.4713967368260f,-0.4928981922298f,-0.5141027441932f,-0.5349976198871f, + -0.5555702330196f,-0.5758081914178f,-0.5956993044924f,-0.6152315905806f, + -0.6343932841636f,-0.6531728429538f,-0.6715589548470f,-0.6895405447371f, + -0.7071067811865f,-0.7242470829515f,-0.7409511253550f,-0.7572088465065f, + -0.7730104533627f,-0.7883464276266f,-0.8032075314806f,-0.8175848131516f, + -0.8314696123025f,-0.8448535652497f,-0.8577286100003f,-0.8700869911087f, + -0.8819212643484f,-0.8932243011955f,-0.9039892931234f,-0.9142097557035f, + -0.9238795325113f,-0.9329927988347f,-0.9415440651830f,-0.9495281805930f, + -0.9569403357322f,-0.9637760657954f,-0.9700312531945f,-0.9757021300385f, + -0.9807852804032f,-0.9852776423889f,-0.9891765099648f,-0.9924795345987f, + -0.9951847266722f,-0.9972904566787f,-0.9987954562052f,-0.9996988186962f, + -1.0000000000000f, +}; + +#define INVSQ_LOOKUP_SZ 32 +static float INVSQ_LOOKUP[INVSQ_LOOKUP_SZ+1]={ + 1.414213562373f,1.392621247646f,1.371988681140f,1.352246807566f, + 1.333333333333f,1.315191898443f,1.297771369046f,1.281025230441f, + 1.264911064067f,1.249390095109f,1.234426799697f,1.219988562661f, + 1.206045378311f,1.192569588000f,1.179535649239f,1.166919931983f, + 1.154700538379f,1.142857142857f,1.131370849898f,1.120224067222f, + 1.109400392450f,1.098884511590f,1.088662107904f,1.078719779941f, + 1.069044967650f,1.059625885652f,1.050451462878f,1.041511287847f, + 1.032795558989f,1.024295039463f,1.016001016002f,1.007905261358f, + 1.000000000000f, +}; + +#define INVSQ2EXP_LOOKUP_MIN (-32) +#define INVSQ2EXP_LOOKUP_MAX 32 +static float INVSQ2EXP_LOOKUP[INVSQ2EXP_LOOKUP_MAX-\ + INVSQ2EXP_LOOKUP_MIN+1]={ + 65536.f, 46340.95001f, 32768.f, 23170.47501f, + 16384.f, 11585.2375f, 8192.f, 5792.618751f, + 4096.f, 2896.309376f, 2048.f, 1448.154688f, + 1024.f, 724.0773439f, 512.f, 362.038672f, + 256.f, 181.019336f, 128.f, 90.50966799f, + 64.f, 45.254834f, 32.f, 22.627417f, + 16.f, 11.3137085f, 8.f, 5.656854249f, + 4.f, 2.828427125f, 2.f, 1.414213562f, + 1.f, 0.7071067812f, 0.5f, 0.3535533906f, + 0.25f, 0.1767766953f, 0.125f, 0.08838834765f, + 0.0625f, 0.04419417382f, 0.03125f, 0.02209708691f, + 0.015625f, 0.01104854346f, 0.0078125f, 0.005524271728f, + 0.00390625f, 0.002762135864f, 0.001953125f, 0.001381067932f, + 0.0009765625f, 0.000690533966f, 0.00048828125f, 0.000345266983f, + 0.000244140625f,0.0001726334915f,0.0001220703125f,8.631674575e-05f, + 6.103515625e-05f,4.315837288e-05f,3.051757812e-05f,2.157918644e-05f, + 1.525878906e-05f, +}; + +#endif + +#define FROMdB_LOOKUP_SZ 35 +#define FROMdB2_LOOKUP_SZ 32 +#define FROMdB_SHIFT 5 +#define FROMdB2_SHIFT 3 +#define FROMdB2_MASK 31 +static float FROMdB_LOOKUP[FROMdB_LOOKUP_SZ]={ + 1.f, 0.6309573445f, 0.3981071706f, 0.2511886432f, + 0.1584893192f, 0.1f, 0.06309573445f, 0.03981071706f, + 0.02511886432f, 0.01584893192f, 0.01f, 0.006309573445f, + 0.003981071706f, 0.002511886432f, 0.001584893192f, 0.001f, + 0.0006309573445f,0.0003981071706f,0.0002511886432f,0.0001584893192f, + 0.0001f,6.309573445e-05f,3.981071706e-05f,2.511886432e-05f, + 1.584893192e-05f, 1e-05f,6.309573445e-06f,3.981071706e-06f, + 2.511886432e-06f,1.584893192e-06f, 1e-06f,6.309573445e-07f, + 3.981071706e-07f,2.511886432e-07f,1.584893192e-07f, +}; + +static float FROMdB2_LOOKUP[FROMdB2_LOOKUP_SZ]={ + 0.9928302478f, 0.9786445908f, 0.9646616199f, 0.9508784391f, + 0.9372921937f, 0.92390007f, 0.9106992942f, 0.8976871324f, + 0.8848608897f, 0.8722179097f, 0.8597555737f, 0.8474713009f, + 0.835362547f, 0.8234268041f, 0.8116616003f, 0.8000644989f, + 0.7886330981f, 0.7773650302f, 0.7662579617f, 0.755309592f, + 0.7445176537f, 0.7338799116f, 0.7233941627f, 0.7130582353f, + 0.7028699885f, 0.6928273125f, 0.6829281272f, 0.6731703824f, + 0.6635520573f, 0.6540711597f, 0.6447257262f, 0.6355138211f, +}; + +#ifdef INT_LOOKUP + +#define INVSQ_LOOKUP_I_SHIFT 10 +#define INVSQ_LOOKUP_I_MASK 1023 +static long INVSQ_LOOKUP_I[64+1]={ + 92682l, 91966l, 91267l, 90583l, + 89915l, 89261l, 88621l, 87995l, + 87381l, 86781l, 86192l, 85616l, + 85051l, 84497l, 83953l, 83420l, + 82897l, 82384l, 81880l, 81385l, + 80899l, 80422l, 79953l, 79492l, + 79039l, 78594l, 78156l, 77726l, + 77302l, 76885l, 76475l, 76072l, + 75674l, 75283l, 74898l, 74519l, + 74146l, 73778l, 73415l, 73058l, + 72706l, 72359l, 72016l, 71679l, + 71347l, 71019l, 70695l, 70376l, + 70061l, 69750l, 69444l, 69141l, + 68842l, 68548l, 68256l, 67969l, + 67685l, 67405l, 67128l, 66855l, + 66585l, 66318l, 66054l, 65794l, + 65536l, +}; + +#define COS_LOOKUP_I_SHIFT 9 +#define COS_LOOKUP_I_MASK 511 +#define COS_LOOKUP_I_SZ 128 +static long COS_LOOKUP_I[COS_LOOKUP_I_SZ+1]={ + 16384l, 16379l, 16364l, 16340l, + 16305l, 16261l, 16207l, 16143l, + 16069l, 15986l, 15893l, 15791l, + 15679l, 15557l, 15426l, 15286l, + 15137l, 14978l, 14811l, 14635l, + 14449l, 14256l, 14053l, 13842l, + 13623l, 13395l, 13160l, 12916l, + 12665l, 12406l, 12140l, 11866l, + 11585l, 11297l, 11003l, 10702l, + 10394l, 10080l, 9760l, 9434l, + 9102l, 8765l, 8423l, 8076l, + 7723l, 7366l, 7005l, 6639l, + 6270l, 5897l, 5520l, 5139l, + 4756l, 4370l, 3981l, 3590l, + 3196l, 2801l, 2404l, 2006l, + 1606l, 1205l, 804l, 402l, + 0l, -401l, -803l, -1204l, + -1605l, -2005l, -2403l, -2800l, + -3195l, -3589l, -3980l, -4369l, + -4755l, -5138l, -5519l, -5896l, + -6269l, -6638l, -7004l, -7365l, + -7722l, -8075l, -8422l, -8764l, + -9101l, -9433l, -9759l, -10079l, + -10393l, -10701l, -11002l, -11296l, + -11584l, -11865l, -12139l, -12405l, + -12664l, -12915l, -13159l, -13394l, + -13622l, -13841l, -14052l, -14255l, + -14448l, -14634l, -14810l, -14977l, + -15136l, -15285l, -15425l, -15556l, + -15678l, -15790l, -15892l, -15985l, + -16068l, -16142l, -16206l, -16260l, + -16304l, -16339l, -16363l, -16378l, + -16383l, +}; + +#endif + +#endif diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/lookups.pl b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/lookups.pl new file mode 100644 index 0000000..385617e --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/lookups.pl @@ -0,0 +1,142 @@ +#!/usr/bin/perl +print <<'EOD'; +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: lookup data; generated by lookups.pl; edit there + last mod: $Id: lookups.pl 7187 2004-07-20 07:24:27Z xiphmont $ + + ********************************************************************/ + +#ifndef _V_LOOKUP_DATA_H_ + +#ifdef FLOAT_LOOKUP +EOD + +$cos_sz=128; +$invsq_sz=32; +$invsq2exp_min=-32; +$invsq2exp_max=32; + +$fromdB_sz=35; +$fromdB_shift=5; +$fromdB2_shift=3; + +$invsq_i_shift=10; +$cos_i_shift=9; +$delta_shift=6; + +print "#define COS_LOOKUP_SZ $cos_sz\n"; +print "static float COS_LOOKUP[COS_LOOKUP_SZ+1]={\n"; + +for($i=0;$i<=$cos_sz;){ + print "\t"; + for($j=0;$j<4 && $i<=$cos_sz;$j++){ + printf "%+.13f,", cos(3.14159265358979323846*($i++)/$cos_sz) ; + } + print "\n"; +} +print "};\n\n"; + +print "#define INVSQ_LOOKUP_SZ $invsq_sz\n"; +print "static float INVSQ_LOOKUP[INVSQ_LOOKUP_SZ+1]={\n"; + +for($i=0;$i<=$invsq_sz;){ + print "\t"; + for($j=0;$j<4 && $i<=$invsq_sz;$j++){ + my$indexmap=$i++/$invsq_sz*.5+.5; + printf "%.12f,", 1./sqrt($indexmap); + } + print "\n"; +} +print "};\n\n"; + +print "#define INVSQ2EXP_LOOKUP_MIN $invsq2exp_min\n"; +print "#define INVSQ2EXP_LOOKUP_MAX $invsq2exp_max\n"; +print "static float INVSQ2EXP_LOOKUP[INVSQ2EXP_LOOKUP_MAX-\\\n". + " INVSQ2EXP_LOOKUP_MIN+1]={\n"; + +for($i=$invsq2exp_min;$i<=$invsq2exp_max;){ + print "\t"; + for($j=0;$j<4 && $i<=$invsq2exp_max;$j++){ + printf "%15.10g,", 2**($i++*-.5); + } + print "\n"; +} +print "};\n\n#endif\n\n"; + + +# 0 to -140 dB +$fromdB2_sz=1<<$fromdB_shift; +$fromdB_gran=1<<($fromdB_shift-$fromdB2_shift); +print "#define FROMdB_LOOKUP_SZ $fromdB_sz\n"; +print "#define FROMdB2_LOOKUP_SZ $fromdB2_sz\n"; +print "#define FROMdB_SHIFT $fromdB_shift\n"; +print "#define FROMdB2_SHIFT $fromdB2_shift\n"; +print "#define FROMdB2_MASK ".((1<<$fromdB_shift)-1)."\n"; + +print "static float FROMdB_LOOKUP[FROMdB_LOOKUP_SZ]={\n"; + +for($i=0;$i<$fromdB_sz;){ + print "\t"; + for($j=0;$j<4 && $i<$fromdB_sz;$j++){ + printf "%15.10g,", 10**(.05*(-$fromdB_gran*$i++)); + } + print "\n"; +} +print "};\n\n"; + +print "static float FROMdB2_LOOKUP[FROMdB2_LOOKUP_SZ]={\n"; + +for($i=0;$i<$fromdB2_sz;){ + print "\t"; + for($j=0;$j<4 && $i<$fromdB_sz;$j++){ + printf "%15.10g,", 10**(.05*(-$fromdB_gran/$fromdB2_sz*(.5+$i++))); + } + print "\n"; +} +print "};\n\n#ifdef INT_LOOKUP\n\n"; + + +$iisz=0x10000>>$invsq_i_shift; +print "#define INVSQ_LOOKUP_I_SHIFT $invsq_i_shift\n"; +print "#define INVSQ_LOOKUP_I_MASK ".(0x0ffff>>(16-$invsq_i_shift))."\n"; +print "static long INVSQ_LOOKUP_I[$iisz+1]={\n"; +for($i=0;$i<=$iisz;){ + print "\t"; + for($j=0;$j<4 && $i<=$iisz;$j++){ + my$indexmap=$i++/$iisz*.5+.5; + printf "%8d,", int(1./sqrt($indexmap)*65536.+.5); + } + print "\n"; +} +print "};\n\n"; + +$cisz=0x10000>>$cos_i_shift; +print "#define COS_LOOKUP_I_SHIFT $cos_i_shift\n"; +print "#define COS_LOOKUP_I_MASK ".(0x0ffff>>(16-$cos_i_shift))."\n"; +print "#define COS_LOOKUP_I_SZ $cisz\n"; +print "static long COS_LOOKUP_I[COS_LOOKUP_I_SZ+1]={\n"; + +for($i=0;$i<=$cisz;){ + print "\t"; + for($j=0;$j<4 && $i<=$cisz;$j++){ + printf "%8d,", int(cos(3.14159265358979323846*($i++)/$cos_sz)*16384.+.5) ; + } + print "\n"; +} +print "};\n\n"; + + +print "#endif\n\n#endif\n"; + + diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/lpc.c b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/lpc.c new file mode 100644 index 0000000..7e1bc13 --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/lpc.c @@ -0,0 +1,149 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: LPC low level routines + last mod: $Id: lpc.c 7187 2004-07-20 07:24:27Z xiphmont $ + + ********************************************************************/ + +/* Some of these routines (autocorrelator, LPC coefficient estimator) + are derived from code written by Jutta Degener and Carsten Bormann; + thus we include their copyright below. The entirety of this file + is freely redistributable on the condition that both of these + copyright notices are preserved without modification. */ + +/* Preserved Copyright: *********************************************/ + +/* Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann, +Technische Universita"t Berlin + +Any use of this software is permitted provided that this notice is not +removed and that neither the authors nor the Technische Universita"t +Berlin are deemed to have made any representations as to the +suitability of this software for any purpose nor are held responsible +for any defects of this software. THERE IS ABSOLUTELY NO WARRANTY FOR +THIS SOFTWARE. + +As a matter of courtesy, the authors request to be informed about uses +this software has found, about bugs in this software, and about any +improvements that may be of general interest. + +Berlin, 28.11.1994 +Jutta Degener +Carsten Bormann + +*********************************************************************/ + +#include +#include +#include +#include "os.h" +#include "smallft.h" +#include "lpc.h" +#include "scales.h" +#include "misc.h" + +/* Autocorrelation LPC coeff generation algorithm invented by + N. Levinson in 1947, modified by J. Durbin in 1959. */ + +/* Input : n elements of time doamin data + Output: m lpc coefficients, excitation energy */ + +float vorbis_lpc_from_data(float *data,float *lpci,int n,int m){ + double *aut=alloca(sizeof(*aut)*(m+1)); + double *lpc=alloca(sizeof(*lpc)*(m)); + double error; + int i,j; + + /* autocorrelation, p+1 lag coefficients */ + j=m+1; + while(j--){ + double d=0; /* double needed for accumulator depth */ + for(i=j;i +#include +#include +#include "lsp.h" +#include "os.h" +#include "misc.h" +#include "lookup.h" +#include "scales.h" + +/* three possible LSP to f curve functions; the exact computation + (float), a lookup based float implementation, and an integer + implementation. The float lookup is likely the optimal choice on + any machine with an FPU. The integer implementation is *not* fixed + point (due to the need for a large dynamic range and thus a + seperately tracked exponent) and thus much more complex than the + relatively simple float implementations. It's mostly for future + work on a fully fixed point implementation for processors like the + ARM family. */ + +/* undefine both for the 'old' but more precise implementation */ +#define FLOAT_LOOKUP +#undef INT_LOOKUP + +#ifdef FLOAT_LOOKUP +#include "lookup.c" /* catch this in the build system; we #include for + compilers (like gcc) that can't inline across + modules */ + +/* side effect: changes *lsp to cosines of lsp */ +void vorbis_lsp_to_curve(float *curve,int *map,int n,int ln,float *lsp,int m, + float amp,float ampoffset){ + int i; + float wdel=M_PI/ln; + vorbis_fpu_control fpu; + + vorbis_fpu_setround(&fpu); + for(i=0;i>1; + + do{ + q*=ftmp[0]-w; + p*=ftmp[1]-w; + ftmp+=2; + }while(--c); + + if(m&1){ + /* odd order filter; slightly assymetric */ + /* the last coefficient */ + q*=ftmp[0]-w; + q*=q; + p*=p*(1.f-w*w); + }else{ + /* even order filter; still symmetric */ + q*=q*(1.f+w); + p*=p*(1.f-w); + } + + q=frexp(p+q,&qexp); + q=vorbis_fromdBlook(amp* + vorbis_invsqlook(q)* + vorbis_invsq2explook(qexp+m)- + ampoffset); + + do{ + curve[i++]*=q; + }while(map[i]==k); + } + vorbis_fpu_restore(fpu); +} + +#else + +#ifdef INT_LOOKUP +#include "lookup.c" /* catch this in the build system; we #include for + compilers (like gcc) that can't inline across + modules */ + +static int MLOOP_1[64]={ + 0,10,11,11, 12,12,12,12, 13,13,13,13, 13,13,13,13, + 14,14,14,14, 14,14,14,14, 14,14,14,14, 14,14,14,14, + 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, + 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, +}; + +static int MLOOP_2[64]={ + 0,4,5,5, 6,6,6,6, 7,7,7,7, 7,7,7,7, + 8,8,8,8, 8,8,8,8, 8,8,8,8, 8,8,8,8, + 9,9,9,9, 9,9,9,9, 9,9,9,9, 9,9,9,9, + 9,9,9,9, 9,9,9,9, 9,9,9,9, 9,9,9,9, +}; + +static int MLOOP_3[8]={0,1,2,2,3,3,3,3}; + + +/* side effect: changes *lsp to cosines of lsp */ +void vorbis_lsp_to_curve(float *curve,int *map,int n,int ln,float *lsp,int m, + float amp,float ampoffset){ + + /* 0 <= m < 256 */ + + /* set up for using all int later */ + int i; + int ampoffseti=rint(ampoffset*4096.f); + int ampi=rint(amp*16.f); + long *ilsp=alloca(m*sizeof(*ilsp)); + for(i=0;i>25])) + if(!(shift=MLOOP_2[(pi|qi)>>19])) + shift=MLOOP_3[(pi|qi)>>16]; + qi=(qi>>shift)*labs(ilsp[j-1]-wi); + pi=(pi>>shift)*labs(ilsp[j]-wi); + qexp+=shift; + } + if(!(shift=MLOOP_1[(pi|qi)>>25])) + if(!(shift=MLOOP_2[(pi|qi)>>19])) + shift=MLOOP_3[(pi|qi)>>16]; + + /* pi,qi normalized collectively, both tracked using qexp */ + + if(m&1){ + /* odd order filter; slightly assymetric */ + /* the last coefficient */ + qi=(qi>>shift)*labs(ilsp[j-1]-wi); + pi=(pi>>shift)<<14; + qexp+=shift; + + if(!(shift=MLOOP_1[(pi|qi)>>25])) + if(!(shift=MLOOP_2[(pi|qi)>>19])) + shift=MLOOP_3[(pi|qi)>>16]; + + pi>>=shift; + qi>>=shift; + qexp+=shift-14*((m+1)>>1); + + pi=((pi*pi)>>16); + qi=((qi*qi)>>16); + qexp=qexp*2+m; + + pi*=(1<<14)-((wi*wi)>>14); + qi+=pi>>14; + + }else{ + /* even order filter; still symmetric */ + + /* p*=p(1-w), q*=q(1+w), let normalization drift because it isn't + worth tracking step by step */ + + pi>>=shift; + qi>>=shift; + qexp+=shift-7*m; + + pi=((pi*pi)>>16); + qi=((qi*qi)>>16); + qexp=qexp*2+m; + + pi*=(1<<14)-wi; + qi*=(1<<14)+wi; + qi=(qi+pi)>>14; + + } + + + /* we've let the normalization drift because it wasn't important; + however, for the lookup, things must be normalized again. We + need at most one right shift or a number of left shifts */ + + if(qi&0xffff0000){ /* checks for 1.xxxxxxxxxxxxxxxx */ + qi>>=1; qexp++; + }else + while(qi && !(qi&0x8000)){ /* checks for 0.0xxxxxxxxxxxxxxx or less*/ + qi<<=1; qexp--; + } + + amp=vorbis_fromdBlook_i(ampi* /* n.4 */ + vorbis_invsqlook_i(qi,qexp)- + /* m.8, m+n<=8 */ + ampoffseti); /* 8.12[0] */ + + curve[i]*=amp; + while(map[++i]==k)curve[i]*=amp; + } +} + +#else + +/* old, nonoptimized but simple version for any poor sap who needs to + figure out what the hell this code does, or wants the other + fraction of a dB precision */ + +/* side effect: changes *lsp to cosines of lsp */ +void vorbis_lsp_to_curve(float *curve,int *map,int n,int ln,float *lsp,int m, + float amp,float ampoffset){ + int i; + float wdel=M_PI/ln; + for(i=0;i= i; j--) { + g[j-2] -= g[j]; + g[j] += g[j]; + } + } +} + +static int comp(const void *a,const void *b){ + return (*(float *)a<*(float *)b)-(*(float *)a>*(float *)b); +} + +/* Newton-Raphson-Maehly actually functioned as a decent root finder, + but there are root sets for which it gets into limit cycles + (exacerbated by zero suppression) and fails. We can't afford to + fail, even if the failure is 1 in 100,000,000, so we now use + Laguerre and later polish with Newton-Raphson (which can then + afford to fail) */ + +#define EPSILON 10e-7 +static int Laguerre_With_Deflation(float *a,int ord,float *r){ + int i,m; + double lastdelta=0.f; + double *defl=alloca(sizeof(*defl)*(ord+1)); + for(i=0;i<=ord;i++)defl[i]=a[i]; + + for(m=ord;m>0;m--){ + double new=0.f,delta; + + /* iterate a root */ + while(1){ + double p=defl[m],pp=0.f,ppp=0.f,denom; + + /* eval the polynomial and its first two derivatives */ + for(i=m;i>0;i--){ + ppp = new*ppp + pp; + pp = new*pp + p; + p = new*p + defl[i-1]; + } + + /* Laguerre's method */ + denom=(m-1) * ((m-1)*pp*pp - m*p*ppp); + if(denom<0) + return(-1); /* complex root! The LPC generator handed us a bad filter */ + + if(pp>0){ + denom = pp + sqrt(denom); + if(denom-(EPSILON))denom=-(EPSILON); + } + + delta = m*p/denom; + new -= delta; + + if(delta<0.f)delta*=-1; + + if(fabs(delta/new)<10e-12)break; + lastdelta=delta; + } + + r[m-1]=new; + + /* forward deflation */ + + for(i=m;i>0;i--) + defl[i-1]+=new*defl[i]; + defl++; + + } + return(0); +} + + +/* for spit-and-polish only */ +static int Newton_Raphson(float *a,int ord,float *r){ + int i, k, count=0; + double error=1.f; + double *root=alloca(ord*sizeof(*root)); + + for(i=0; i1e-20){ + error=0; + + for(i=0; i= 0; k--) { + + pp= pp* rooti + p; + p = p * rooti + a[k]; + } + + delta = p/pp; + root[i] -= delta; + error+= delta*delta; + } + + if(count>40)return(-1); + + count++; + } + + /* Replaced the original bubble sort with a real sort. With your + help, we can eliminate the bubble sort in our lifetime. --Monty */ + + for(i=0; i>1; + int g1_order,g2_order; + float *g1=alloca(sizeof(*g1)*(order2+1)); + float *g2=alloca(sizeof(*g2)*(order2+1)); + float *g1r=alloca(sizeof(*g1r)*(order2+1)); + float *g2r=alloca(sizeof(*g2r)*(order2+1)); + int i; + + /* even and odd are slightly different base cases */ + g1_order=(m+1)>>1; + g2_order=(m) >>1; + + /* Compute the lengths of the x polynomials. */ + /* Compute the first half of K & R F1 & F2 polynomials. */ + /* Compute half of the symmetric and antisymmetric polynomials. */ + /* Remove the roots at +1 and -1. */ + + g1[g1_order] = 1.f; + for(i=1;i<=g1_order;i++) g1[g1_order-i] = lpc[i-1]+lpc[m-i]; + g2[g2_order] = 1.f; + for(i=1;i<=g2_order;i++) g2[g2_order-i] = lpc[i-1]-lpc[m-i]; + + if(g1_order>g2_order){ + for(i=2; i<=g2_order;i++) g2[g2_order-i] += g2[g2_order-i+2]; + }else{ + for(i=1; i<=g1_order;i++) g1[g1_order-i] -= g1[g1_order-i+1]; + for(i=1; i<=g2_order;i++) g2[g2_order-i] += g2[g2_order-i+1]; + } + + /* Convert into polynomials in cos(alpha) */ + cheby(g1,g1_order); + cheby(g2,g2_order); + + /* Find the roots of the 2 even polynomials.*/ + if(Laguerre_With_Deflation(g1,g1_order,g1r) || + Laguerre_With_Deflation(g2,g2_order,g2r)) + return(-1); + + Newton_Raphson(g1,g1_order,g1r); /* if it fails, it leaves g1r alone */ + Newton_Raphson(g2,g2_order,g2r); /* if it fails, it leaves g2r alone */ + + qsort(g1r,g1_order,sizeof(*g1r),comp); + qsort(g2r,g2_order,sizeof(*g2r),comp); + + for(i=0;i +#include +#include +#include +#include +#include "vorbis/codec.h" +#include "codec_internal.h" +#include "codebook.h" +#include "window.h" +#include "registry.h" +#include "psy.h" +#include "misc.h" + +/* simplistic, wasteful way of doing this (unique lookup for each + mode/submapping); there should be a central repository for + identical lookups. That will require minor work, so I'm putting it + off as low priority. + + Why a lookup for each backend in a given mode? Because the + blocksize is set by the mode, and low backend lookups may require + parameters from other areas of the mode/mapping */ + +static void mapping0_free_info(vorbis_info_mapping *i){ + vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)i; + if(info){ + memset(info,0,sizeof(*info)); + _ogg_free(info); + } +} + +static int ilog(unsigned int v){ + int ret=0; + if(v)--v; + while(v){ + ret++; + v>>=1; + } + return(ret); +} + +static void mapping0_pack(vorbis_info *vi,vorbis_info_mapping *vm, + oggpack_buffer *opb){ + int i; + vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)vm; + + /* another 'we meant to do it this way' hack... up to beta 4, we + packed 4 binary zeros here to signify one submapping in use. We + now redefine that to mean four bitflags that indicate use of + deeper features; bit0:submappings, bit1:coupling, + bit2,3:reserved. This is backward compatable with all actual uses + of the beta code. */ + + if(info->submaps>1){ + oggpack_write(opb,1,1); + oggpack_write(opb,info->submaps-1,4); + }else + oggpack_write(opb,0,1); + + if(info->coupling_steps>0){ + oggpack_write(opb,1,1); + oggpack_write(opb,info->coupling_steps-1,8); + + for(i=0;icoupling_steps;i++){ + oggpack_write(opb,info->coupling_mag[i],ilog(vi->channels)); + oggpack_write(opb,info->coupling_ang[i],ilog(vi->channels)); + } + }else + oggpack_write(opb,0,1); + + oggpack_write(opb,0,2); /* 2,3:reserved */ + + /* we don't write the channel submappings if we only have one... */ + if(info->submaps>1){ + for(i=0;ichannels;i++) + oggpack_write(opb,info->chmuxlist[i],4); + } + for(i=0;isubmaps;i++){ + oggpack_write(opb,0,8); /* time submap unused */ + oggpack_write(opb,info->floorsubmap[i],8); + oggpack_write(opb,info->residuesubmap[i],8); + } +} + +/* also responsible for range checking */ +static vorbis_info_mapping *mapping0_unpack(vorbis_info *vi,oggpack_buffer *opb){ + int i; + vorbis_info_mapping0 *info=_ogg_calloc(1,sizeof(*info)); + codec_setup_info *ci=vi->codec_setup; + memset(info,0,sizeof(*info)); + + if(oggpack_read(opb,1)) + info->submaps=oggpack_read(opb,4)+1; + else + info->submaps=1; + + if(oggpack_read(opb,1)){ + info->coupling_steps=oggpack_read(opb,8)+1; + + for(i=0;icoupling_steps;i++){ + int testM=info->coupling_mag[i]=oggpack_read(opb,ilog(vi->channels)); + int testA=info->coupling_ang[i]=oggpack_read(opb,ilog(vi->channels)); + + if(testM<0 || + testA<0 || + testM==testA || + testM>=vi->channels || + testA>=vi->channels) goto err_out; + } + + } + + if(oggpack_read(opb,2)>0)goto err_out; /* 2,3:reserved */ + + if(info->submaps>1){ + for(i=0;ichannels;i++){ + info->chmuxlist[i]=oggpack_read(opb,4); + if(info->chmuxlist[i]>=info->submaps)goto err_out; + } + } + for(i=0;isubmaps;i++){ + oggpack_read(opb,8); /* time submap unused */ + info->floorsubmap[i]=oggpack_read(opb,8); + if(info->floorsubmap[i]>=ci->floors)goto err_out; + info->residuesubmap[i]=oggpack_read(opb,8); + if(info->residuesubmap[i]>=ci->residues)goto err_out; + } + + return info; + + err_out: + mapping0_free_info(info); + return(NULL); +} + +#include "os.h" +#include "lpc.h" +#include "lsp.h" +#include "envelope.h" +#include "mdct.h" +#include "psy.h" +#include "scales.h" + +#if 0 +static long seq=0; +static ogg_int64_t total=0; +static float FLOOR1_fromdB_LOOKUP[256]={ + 1.0649863e-07F, 1.1341951e-07F, 1.2079015e-07F, 1.2863978e-07F, + 1.3699951e-07F, 1.4590251e-07F, 1.5538408e-07F, 1.6548181e-07F, + 1.7623575e-07F, 1.8768855e-07F, 1.9988561e-07F, 2.128753e-07F, + 2.2670913e-07F, 2.4144197e-07F, 2.5713223e-07F, 2.7384213e-07F, + 2.9163793e-07F, 3.1059021e-07F, 3.3077411e-07F, 3.5226968e-07F, + 3.7516214e-07F, 3.9954229e-07F, 4.2550680e-07F, 4.5315863e-07F, + 4.8260743e-07F, 5.1396998e-07F, 5.4737065e-07F, 5.8294187e-07F, + 6.2082472e-07F, 6.6116941e-07F, 7.0413592e-07F, 7.4989464e-07F, + 7.9862701e-07F, 8.5052630e-07F, 9.0579828e-07F, 9.6466216e-07F, + 1.0273513e-06F, 1.0941144e-06F, 1.1652161e-06F, 1.2409384e-06F, + 1.3215816e-06F, 1.4074654e-06F, 1.4989305e-06F, 1.5963394e-06F, + 1.7000785e-06F, 1.8105592e-06F, 1.9282195e-06F, 2.0535261e-06F, + 2.1869758e-06F, 2.3290978e-06F, 2.4804557e-06F, 2.6416497e-06F, + 2.8133190e-06F, 2.9961443e-06F, 3.1908506e-06F, 3.3982101e-06F, + 3.6190449e-06F, 3.8542308e-06F, 4.1047004e-06F, 4.3714470e-06F, + 4.6555282e-06F, 4.9580707e-06F, 5.2802740e-06F, 5.6234160e-06F, + 5.9888572e-06F, 6.3780469e-06F, 6.7925283e-06F, 7.2339451e-06F, + 7.7040476e-06F, 8.2047000e-06F, 8.7378876e-06F, 9.3057248e-06F, + 9.9104632e-06F, 1.0554501e-05F, 1.1240392e-05F, 1.1970856e-05F, + 1.2748789e-05F, 1.3577278e-05F, 1.4459606e-05F, 1.5399272e-05F, + 1.6400004e-05F, 1.7465768e-05F, 1.8600792e-05F, 1.9809576e-05F, + 2.1096914e-05F, 2.2467911e-05F, 2.3928002e-05F, 2.5482978e-05F, + 2.7139006e-05F, 2.8902651e-05F, 3.0780908e-05F, 3.2781225e-05F, + 3.4911534e-05F, 3.7180282e-05F, 3.9596466e-05F, 4.2169667e-05F, + 4.4910090e-05F, 4.7828601e-05F, 5.0936773e-05F, 5.4246931e-05F, + 5.7772202e-05F, 6.1526565e-05F, 6.5524908e-05F, 6.9783085e-05F, + 7.4317983e-05F, 7.9147585e-05F, 8.4291040e-05F, 8.9768747e-05F, + 9.5602426e-05F, 0.00010181521F, 0.00010843174F, 0.00011547824F, + 0.00012298267F, 0.00013097477F, 0.00013948625F, 0.00014855085F, + 0.00015820453F, 0.00016848555F, 0.00017943469F, 0.00019109536F, + 0.00020351382F, 0.00021673929F, 0.00023082423F, 0.00024582449F, + 0.00026179955F, 0.00027881276F, 0.00029693158F, 0.00031622787F, + 0.00033677814F, 0.00035866388F, 0.00038197188F, 0.00040679456F, + 0.00043323036F, 0.00046138411F, 0.00049136745F, 0.00052329927F, + 0.00055730621F, 0.00059352311F, 0.00063209358F, 0.00067317058F, + 0.00071691700F, 0.00076350630F, 0.00081312324F, 0.00086596457F, + 0.00092223983F, 0.00098217216F, 0.0010459992F, 0.0011139742F, + 0.0011863665F, 0.0012634633F, 0.0013455702F, 0.0014330129F, + 0.0015261382F, 0.0016253153F, 0.0017309374F, 0.0018434235F, + 0.0019632195F, 0.0020908006F, 0.0022266726F, 0.0023713743F, + 0.0025254795F, 0.0026895994F, 0.0028643847F, 0.0030505286F, + 0.0032487691F, 0.0034598925F, 0.0036847358F, 0.0039241906F, + 0.0041792066F, 0.0044507950F, 0.0047400328F, 0.0050480668F, + 0.0053761186F, 0.0057254891F, 0.0060975636F, 0.0064938176F, + 0.0069158225F, 0.0073652516F, 0.0078438871F, 0.0083536271F, + 0.0088964928F, 0.009474637F, 0.010090352F, 0.010746080F, + 0.011444421F, 0.012188144F, 0.012980198F, 0.013823725F, + 0.014722068F, 0.015678791F, 0.016697687F, 0.017782797F, + 0.018938423F, 0.020169149F, 0.021479854F, 0.022875735F, + 0.024362330F, 0.025945531F, 0.027631618F, 0.029427276F, + 0.031339626F, 0.033376252F, 0.035545228F, 0.037855157F, + 0.040315199F, 0.042935108F, 0.045725273F, 0.048696758F, + 0.051861348F, 0.055231591F, 0.058820850F, 0.062643361F, + 0.066714279F, 0.071049749F, 0.075666962F, 0.080584227F, + 0.085821044F, 0.091398179F, 0.097337747F, 0.10366330F, + 0.11039993F, 0.11757434F, 0.12521498F, 0.13335215F, + 0.14201813F, 0.15124727F, 0.16107617F, 0.17154380F, + 0.18269168F, 0.19456402F, 0.20720788F, 0.22067342F, + 0.23501402F, 0.25028656F, 0.26655159F, 0.28387361F, + 0.30232132F, 0.32196786F, 0.34289114F, 0.36517414F, + 0.38890521F, 0.41417847F, 0.44109412F, 0.46975890F, + 0.50028648F, 0.53279791F, 0.56742212F, 0.60429640F, + 0.64356699F, 0.68538959F, 0.72993007F, 0.77736504F, + 0.82788260F, 0.88168307F, 0.9389798F, 1.F, +}; + +#endif + +extern int *floor1_fit(vorbis_block *vb,vorbis_look_floor *look, + const float *logmdct, /* in */ + const float *logmask); +extern int *floor1_interpolate_fit(vorbis_block *vb,vorbis_look_floor *look, + int *A,int *B, + int del); +extern int floor1_encode(oggpack_buffer *opb,vorbis_block *vb, + vorbis_look_floor *look, + int *post,int *ilogmask); + + +static int mapping0_forward(vorbis_block *vb){ + vorbis_dsp_state *vd=vb->vd; + vorbis_info *vi=vd->vi; + codec_setup_info *ci=vi->codec_setup; + private_state *b=vb->vd->backend_state; + vorbis_block_internal *vbi=(vorbis_block_internal *)vb->internal; + int n=vb->pcmend; + int i,j,k; + + int *nonzero = alloca(sizeof(*nonzero)*vi->channels); + float **gmdct = _vorbis_block_alloc(vb,vi->channels*sizeof(*gmdct)); + int **ilogmaskch= _vorbis_block_alloc(vb,vi->channels*sizeof(*ilogmaskch)); + int ***floor_posts = _vorbis_block_alloc(vb,vi->channels*sizeof(*floor_posts)); + + float global_ampmax=vbi->ampmax; + float *local_ampmax=alloca(sizeof(*local_ampmax)*vi->channels); + int blocktype=vbi->blocktype; + + int modenumber=vb->W; + vorbis_info_mapping0 *info=ci->map_param[modenumber]; + vorbis_look_psy *psy_look= + b->psy+blocktype+(vb->W?2:0); + + vb->mode=modenumber; + + for(i=0;ichannels;i++){ + float scale=4.f/n; + float scale_dB; + + float *pcm =vb->pcm[i]; + float *logfft =pcm; + + gmdct[i]=_vorbis_block_alloc(vb,n/2*sizeof(**gmdct)); + + scale_dB=todB(&scale) + .345; /* + .345 is a hack; the original + todB estimation used on IEEE 754 + compliant machines had a bug that + returned dB values about a third + of a decibel too high. The bug + was harmless because tunings + implicitly took that into + account. However, fixing the bug + in the estimator requires + changing all the tunings as well. + For now, it's easier to sync + things back up here, and + recalibrate the tunings in the + next major model upgrade. */ + +#if 0 + if(vi->channels==2) + if(i==0) + _analysis_output("pcmL",seq,pcm,n,0,0,total-n/2); + else + _analysis_output("pcmR",seq,pcm,n,0,0,total-n/2); +#endif + + /* window the PCM data */ + _vorbis_apply_window(pcm,b->window,ci->blocksizes,vb->lW,vb->W,vb->nW); + +#if 0 + if(vi->channels==2) + if(i==0) + _analysis_output("windowedL",seq,pcm,n,0,0,total-n/2); + else + _analysis_output("windowedR",seq,pcm,n,0,0,total-n/2); +#endif + + /* transform the PCM data */ + /* only MDCT right now.... */ + mdct_forward(b->transform[vb->W][0],pcm,gmdct[i]); + + /* FFT yields more accurate tonal estimation (not phase sensitive) */ + drft_forward(&b->fft_look[vb->W],pcm); + logfft[0]=scale_dB+todB(pcm) + .345; /* + .345 is a hack; the + original todB estimation used on + IEEE 754 compliant machines had a + bug that returned dB values about + a third of a decibel too high. + The bug was harmless because + tunings implicitly took that into + account. However, fixing the bug + in the estimator requires + changing all the tunings as well. + For now, it's easier to sync + things back up here, and + recalibrate the tunings in the + next major model upgrade. */ + local_ampmax[i]=logfft[0]; + for(j=1;j>1]=scale_dB+.5f*todB(&temp) + .345; /* + + .345 is a hack; the original todB + estimation used on IEEE 754 + compliant machines had a bug that + returned dB values about a third + of a decibel too high. The bug + was harmless because tunings + implicitly took that into + account. However, fixing the bug + in the estimator requires + changing all the tunings as well. + For now, it's easier to sync + things back up here, and + recalibrate the tunings in the + next major model upgrade. */ + if(temp>local_ampmax[i])local_ampmax[i]=temp; + } + + if(local_ampmax[i]>0.f)local_ampmax[i]=0.f; + if(local_ampmax[i]>global_ampmax)global_ampmax=local_ampmax[i]; + +#if 0 + if(vi->channels==2){ + if(i==0){ + _analysis_output("fftL",seq,logfft,n/2,1,0,0); + }else{ + _analysis_output("fftR",seq,logfft,n/2,1,0,0); + } + } +#endif + + } + + { + float *noise = _vorbis_block_alloc(vb,n/2*sizeof(*noise)); + float *tone = _vorbis_block_alloc(vb,n/2*sizeof(*tone)); + + for(i=0;ichannels;i++){ + /* the encoder setup assumes that all the modes used by any + specific bitrate tweaking use the same floor */ + + int submap=info->chmuxlist[i]; + + /* the following makes things clearer to *me* anyway */ + float *mdct =gmdct[i]; + float *logfft =vb->pcm[i]; + + float *logmdct =logfft+n/2; + float *logmask =logfft; + + vb->mode=modenumber; + + floor_posts[i]=_vorbis_block_alloc(vb,PACKETBLOBS*sizeof(**floor_posts)); + memset(floor_posts[i],0,sizeof(**floor_posts)*PACKETBLOBS); + + for(j=0;jchannels==2){ + if(i==0) + _analysis_output("mdctL",seq,logmdct,n/2,1,0,0); + else + _analysis_output("mdctR",seq,logmdct,n/2,1,0,0); + }else{ + _analysis_output("mdct",seq,logmdct,n/2,1,0,0); + } +#endif + + /* first step; noise masking. Not only does 'noise masking' + give us curves from which we can decide how much resolution + to give noise parts of the spectrum, it also implicitly hands + us a tonality estimate (the larger the value in the + 'noise_depth' vector, the more tonal that area is) */ + + _vp_noisemask(psy_look, + logmdct, + noise); /* noise does not have by-frequency offset + bias applied yet */ +#if 0 + if(vi->channels==2){ + if(i==0) + _analysis_output("noiseL",seq,noise,n/2,1,0,0); + else + _analysis_output("noiseR",seq,noise,n/2,1,0,0); + } +#endif + + /* second step: 'all the other crap'; all the stuff that isn't + computed/fit for bitrate management goes in the second psy + vector. This includes tone masking, peak limiting and ATH */ + + _vp_tonemask(psy_look, + logfft, + tone, + global_ampmax, + local_ampmax[i]); + +#if 0 + if(vi->channels==2){ + if(i==0) + _analysis_output("toneL",seq,tone,n/2,1,0,0); + else + _analysis_output("toneR",seq,tone,n/2,1,0,0); + } +#endif + + /* third step; we offset the noise vectors, overlay tone + masking. We then do a floor1-specific line fit. If we're + performing bitrate management, the line fit is performed + multiple times for up/down tweakage on demand. */ + +#if 0 + { + float aotuv[psy_look->n]; +#endif + + _vp_offset_and_mix(psy_look, + noise, + tone, + 1, + logmask, + mdct, + logmdct); + +#if 0 + if(vi->channels==2){ + if(i==0) + _analysis_output("aotuvM1_L",seq,aotuv,psy_look->n,1,1,0); + else + _analysis_output("aotuvM1_R",seq,aotuv,psy_look->n,1,1,0); + } + } +#endif + + +#if 0 + if(vi->channels==2){ + if(i==0) + _analysis_output("mask1L",seq,logmask,n/2,1,0,0); + else + _analysis_output("mask1R",seq,logmask,n/2,1,0,0); + } +#endif + + /* this algorithm is hardwired to floor 1 for now; abort out if + we're *not* floor1. This won't happen unless someone has + broken the encode setup lib. Guard it anyway. */ + if(ci->floor_type[info->floorsubmap[submap]]!=1)return(-1); + + floor_posts[i][PACKETBLOBS/2]= + floor1_fit(vb,b->flr[info->floorsubmap[submap]], + logmdct, + logmask); + + /* are we managing bitrate? If so, perform two more fits for + later rate tweaking (fits represent hi/lo) */ + if(vorbis_bitrate_managed(vb) && floor_posts[i][PACKETBLOBS/2]){ + /* higher rate by way of lower noise curve */ + + _vp_offset_and_mix(psy_look, + noise, + tone, + 2, + logmask, + mdct, + logmdct); + +#if 0 + if(vi->channels==2){ + if(i==0) + _analysis_output("mask2L",seq,logmask,n/2,1,0,0); + else + _analysis_output("mask2R",seq,logmask,n/2,1,0,0); + } +#endif + + floor_posts[i][PACKETBLOBS-1]= + floor1_fit(vb,b->flr[info->floorsubmap[submap]], + logmdct, + logmask); + + /* lower rate by way of higher noise curve */ + _vp_offset_and_mix(psy_look, + noise, + tone, + 0, + logmask, + mdct, + logmdct); + +#if 0 + if(vi->channels==2) + if(i==0) + _analysis_output("mask0L",seq,logmask,n/2,1,0,0); + else + _analysis_output("mask0R",seq,logmask,n/2,1,0,0); +#endif + + floor_posts[i][0]= + floor1_fit(vb,b->flr[info->floorsubmap[submap]], + logmdct, + logmask); + + /* we also interpolate a range of intermediate curves for + intermediate rates */ + for(k=1;kflr[info->floorsubmap[submap]], + floor_posts[i][0], + floor_posts[i][PACKETBLOBS/2], + k*65536/(PACKETBLOBS/2)); + for(k=PACKETBLOBS/2+1;kflr[info->floorsubmap[submap]], + floor_posts[i][PACKETBLOBS/2], + floor_posts[i][PACKETBLOBS-1], + (k-PACKETBLOBS/2)*65536/(PACKETBLOBS/2)); + } + } + } + vbi->ampmax=global_ampmax; + + /* + the next phases are performed once for vbr-only and PACKETBLOB + times for bitrate managed modes. + + 1) encode actual mode being used + 2) encode the floor for each channel, compute coded mask curve/res + 3) normalize and couple. + 4) encode residue + 5) save packet bytes to the packetblob vector + + */ + + /* iterate over the many masking curve fits we've created */ + + { + float **res_bundle=alloca(sizeof(*res_bundle)*vi->channels); + float **couple_bundle=alloca(sizeof(*couple_bundle)*vi->channels); + int *zerobundle=alloca(sizeof(*zerobundle)*vi->channels); + int **sortindex=alloca(sizeof(*sortindex)*vi->channels); + float **mag_memo; + int **mag_sort; + + if(info->coupling_steps){ + mag_memo=_vp_quantize_couple_memo(vb, + &ci->psy_g_param, + psy_look, + info, + gmdct); + + mag_sort=_vp_quantize_couple_sort(vb, + psy_look, + info, + mag_memo); + + hf_reduction(&ci->psy_g_param, + psy_look, + info, + mag_memo); + } + + memset(sortindex,0,sizeof(*sortindex)*vi->channels); + if(psy_look->vi->normal_channel_p){ + for(i=0;ichannels;i++){ + float *mdct =gmdct[i]; + sortindex[i]=alloca(sizeof(**sortindex)*n/2); + _vp_noise_normalize_sort(psy_look,mdct,sortindex[i]); + } + } + + for(k=(vorbis_bitrate_managed(vb)?0:PACKETBLOBS/2); + k<=(vorbis_bitrate_managed(vb)?PACKETBLOBS-1:PACKETBLOBS/2); + k++){ + oggpack_buffer *opb=vbi->packetblob[k]; + + /* start out our new packet blob with packet type and mode */ + /* Encode the packet type */ + oggpack_write(opb,0,1); + /* Encode the modenumber */ + /* Encode frame mode, pre,post windowsize, then dispatch */ + oggpack_write(opb,modenumber,b->modebits); + if(vb->W){ + oggpack_write(opb,vb->lW,1); + oggpack_write(opb,vb->nW,1); + } + + /* encode floor, compute masking curve, sep out residue */ + for(i=0;ichannels;i++){ + int submap=info->chmuxlist[i]; + float *mdct =gmdct[i]; + float *res =vb->pcm[i]; + int *ilogmask=ilogmaskch[i]= + _vorbis_block_alloc(vb,n/2*sizeof(**gmdct)); + + nonzero[i]=floor1_encode(opb,vb,b->flr[info->floorsubmap[submap]], + floor_posts[i][k], + ilogmask); +#if 0 + { + char buf[80]; + sprintf(buf,"maskI%c%d",i?'R':'L',k); + float work[n/2]; + for(j=0;jpsy_g_param.sliding_lowpass[vb->W][k]); + + _vp_noise_normalize(psy_look,res,res+n/2,sortindex[i]); + + +#if 0 + { + char buf[80]; + float work[n/2]; + for(j=0;jcoupling_steps){ + _vp_couple(k, + &ci->psy_g_param, + psy_look, + info, + vb->pcm, + mag_memo, + mag_sort, + ilogmaskch, + nonzero, + ci->psy_g_param.sliding_lowpass[vb->W][k]); + } + + /* classify and encode by submap */ + for(i=0;isubmaps;i++){ + int ch_in_bundle=0; + long **classifications; + int resnum=info->residuesubmap[i]; + + for(j=0;jchannels;j++){ + if(info->chmuxlist[j]==i){ + zerobundle[ch_in_bundle]=0; + if(nonzero[j])zerobundle[ch_in_bundle]=1; + res_bundle[ch_in_bundle]=vb->pcm[j]; + couple_bundle[ch_in_bundle++]=vb->pcm[j]+n/2; + } + } + + classifications=_residue_P[ci->residue_type[resnum]]-> + class(vb,b->residue[resnum],couple_bundle,zerobundle,ch_in_bundle); + + _residue_P[ci->residue_type[resnum]]-> + forward(opb,vb,b->residue[resnum], + couple_bundle,NULL,zerobundle,ch_in_bundle,classifications); + } + + /* ok, done encoding. Next protopacket. */ + } + + } + +#if 0 + seq++; + total+=ci->blocksizes[vb->W]/4+ci->blocksizes[vb->nW]/4; +#endif + return(0); +} + +static int mapping0_inverse(vorbis_block *vb,vorbis_info_mapping *l){ + vorbis_dsp_state *vd=vb->vd; + vorbis_info *vi=vd->vi; + codec_setup_info *ci=vi->codec_setup; + private_state *b=vd->backend_state; + vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)l; + int hs=ci->halfrate_flag; + + int i,j; + long n=vb->pcmend=ci->blocksizes[vb->W]; + + float **pcmbundle=alloca(sizeof(*pcmbundle)*vi->channels); + int *zerobundle=alloca(sizeof(*zerobundle)*vi->channels); + + int *nonzero =alloca(sizeof(*nonzero)*vi->channels); + void **floormemo=alloca(sizeof(*floormemo)*vi->channels); + + /* recover the spectral envelope; store it in the PCM vector for now */ + for(i=0;ichannels;i++){ + int submap=info->chmuxlist[i]; + floormemo[i]=_floor_P[ci->floor_type[info->floorsubmap[submap]]]-> + inverse1(vb,b->flr[info->floorsubmap[submap]]); + if(floormemo[i]) + nonzero[i]=1; + else + nonzero[i]=0; + memset(vb->pcm[i],0,sizeof(*vb->pcm[i])*n/2); + } + + /* channel coupling can 'dirty' the nonzero listing */ + for(i=0;icoupling_steps;i++){ + if(nonzero[info->coupling_mag[i]] || + nonzero[info->coupling_ang[i]]){ + nonzero[info->coupling_mag[i]]=1; + nonzero[info->coupling_ang[i]]=1; + } + } + + /* recover the residue into our working vectors */ + for(i=0;isubmaps;i++){ + int ch_in_bundle=0; + for(j=0;jchannels;j++){ + if(info->chmuxlist[j]==i){ + if(nonzero[j]) + zerobundle[ch_in_bundle]=1; + else + zerobundle[ch_in_bundle]=0; + pcmbundle[ch_in_bundle++]=vb->pcm[j]; + } + } + + _residue_P[ci->residue_type[info->residuesubmap[i]]]-> + inverse(vb,b->residue[info->residuesubmap[i]], + pcmbundle,zerobundle,ch_in_bundle); + } + + /* channel coupling */ + for(i=info->coupling_steps-1;i>=0;i--){ + float *pcmM=vb->pcm[info->coupling_mag[i]]; + float *pcmA=vb->pcm[info->coupling_ang[i]]; + + for(j=0;j0) + if(ang>0){ + pcmM[j]=mag; + pcmA[j]=mag-ang; + }else{ + pcmA[j]=mag; + pcmM[j]=mag+ang; + } + else + if(ang>0){ + pcmM[j]=mag; + pcmA[j]=mag+ang; + }else{ + pcmA[j]=mag; + pcmM[j]=mag-ang; + } + } + } + + /* compute and apply spectral envelope */ + for(i=0;ichannels;i++){ + float *pcm=vb->pcm[i]; + int submap=info->chmuxlist[i]; + _floor_P[ci->floor_type[info->floorsubmap[submap]]]-> + inverse2(vb,b->flr[info->floorsubmap[submap]], + floormemo[i],pcm); + } + + /* transform the PCM data; takes PCM vector, vb; modifies PCM vector */ + /* only MDCT right now.... */ + for(i=0;ichannels;i++){ + float *pcm=vb->pcm[i]; + mdct_backward(b->transform[vb->W][0],pcm,pcm); + } + + /* all done! */ + return(0); +} + +/* export hooks */ +vorbis_func_mapping mapping0_exportbundle={ + &mapping0_pack, + &mapping0_unpack, + &mapping0_free_info, + &mapping0_forward, + &mapping0_inverse +}; + diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/masking.h b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/masking.h new file mode 100644 index 0000000..1e5af59 --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/masking.h @@ -0,0 +1,785 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: masking curve data for psychoacoustics + last mod: $Id: masking.h 7187 2004-07-20 07:24:27Z xiphmont $ + + ********************************************************************/ + +#ifndef _V_MASKING_H_ +#define _V_MASKING_H_ + +/* more detailed ATH; the bass if flat to save stressing the floor + overly for only a bin or two of savings. */ + +#define MAX_ATH 88 +static float ATH[]={ + /*15*/ -51, -52, -53, -54, -55, -56, -57, -58, + /*31*/ -59, -60, -61, -62, -63, -64, -65, -66, + /*63*/ -67, -68, -69, -70, -71, -72, -73, -74, + /*125*/ -75, -76, -77, -78, -80, -81, -82, -83, + /*250*/ -84, -85, -86, -87, -88, -88, -89, -89, + /*500*/ -90, -91, -91, -92, -93, -94, -95, -96, + /*1k*/ -96, -97, -98, -98, -99, -99,-100,-100, + /*2k*/ -101,-102,-103,-104,-106,-107,-107,-107, + /*4k*/ -107,-105,-103,-102,-101, -99, -98, -96, + /*8k*/ -95, -95, -96, -97, -96, -95, -93, -90, + /*16k*/ -80, -70, -50, -40, -30, -30, -30, -30 +}; + +/* The tone masking curves from Ehmer's and Fielder's papers have been + replaced by an empirically collected data set. The previously + published values were, far too often, simply on crack. */ + +#define EHMER_OFFSET 16 +#define EHMER_MAX 56 + +/* masking tones from -50 to 0dB, 62.5 through 16kHz at half octaves + test tones from -2 octaves to +5 octaves sampled at eighth octaves */ +/* (Vorbis 0dB, the loudest possible tone, is assumed to be ~100dB SPL + for collection of these curves) */ + +static float tonemasks[P_BANDS][6][EHMER_MAX]={ + /* 62.5 Hz */ + {{ -60, -60, -60, -60, -60, -60, -60, -60, + -60, -60, -60, -60, -62, -62, -65, -73, + -69, -68, -68, -67, -70, -70, -72, -74, + -75, -79, -79, -80, -83, -88, -93, -100, + -110, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + { -48, -48, -48, -48, -48, -48, -48, -48, + -48, -48, -48, -48, -48, -53, -61, -66, + -66, -68, -67, -70, -76, -76, -72, -73, + -75, -76, -78, -79, -83, -88, -93, -100, + -110, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + { -37, -37, -37, -37, -37, -37, -37, -37, + -38, -40, -42, -46, -48, -53, -55, -62, + -65, -58, -56, -56, -61, -60, -65, -67, + -69, -71, -77, -77, -78, -80, -82, -84, + -88, -93, -98, -106, -112, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + { -25, -25, -25, -25, -25, -25, -25, -25, + -25, -26, -27, -29, -32, -38, -48, -52, + -52, -50, -48, -48, -51, -52, -54, -60, + -67, -67, -66, -68, -69, -73, -73, -76, + -80, -81, -81, -85, -85, -86, -88, -93, + -100, -110, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + { -16, -16, -16, -16, -16, -16, -16, -16, + -17, -19, -20, -22, -26, -28, -31, -40, + -47, -39, -39, -40, -42, -43, -47, -51, + -57, -52, -55, -55, -60, -58, -62, -63, + -70, -67, -69, -72, -73, -77, -80, -82, + -83, -87, -90, -94, -98, -104, -115, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + { -8, -8, -8, -8, -8, -8, -8, -8, + -8, -8, -10, -11, -15, -19, -25, -30, + -34, -31, -30, -31, -29, -32, -35, -42, + -48, -42, -44, -46, -50, -50, -51, -52, + -59, -54, -55, -55, -58, -62, -63, -66, + -72, -73, -76, -75, -78, -80, -80, -81, + -84, -88, -90, -94, -98, -101, -106, -110}}, + /* 88Hz */ + {{ -66, -66, -66, -66, -66, -66, -66, -66, + -66, -66, -66, -66, -66, -67, -67, -67, + -76, -72, -71, -74, -76, -76, -75, -78, + -79, -79, -81, -83, -86, -89, -93, -97, + -100, -105, -110, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + { -47, -47, -47, -47, -47, -47, -47, -47, + -47, -47, -47, -48, -51, -55, -59, -66, + -66, -66, -67, -66, -68, -69, -70, -74, + -79, -77, -77, -78, -80, -81, -82, -84, + -86, -88, -91, -95, -100, -108, -116, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + { -36, -36, -36, -36, -36, -36, -36, -36, + -36, -37, -37, -41, -44, -48, -51, -58, + -62, -60, -57, -59, -59, -60, -63, -65, + -72, -71, -70, -72, -74, -77, -76, -78, + -81, -81, -80, -83, -86, -91, -96, -100, + -105, -110, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + { -28, -28, -28, -28, -28, -28, -28, -28, + -28, -30, -32, -32, -33, -35, -41, -49, + -50, -49, -47, -48, -48, -52, -51, -57, + -65, -61, -59, -61, -64, -69, -70, -74, + -77, -77, -78, -81, -84, -85, -87, -90, + -92, -96, -100, -107, -112, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + { -19, -19, -19, -19, -19, -19, -19, -19, + -20, -21, -23, -27, -30, -35, -36, -41, + -46, -44, -42, -40, -41, -41, -43, -48, + -55, -53, -52, -53, -56, -59, -58, -60, + -67, -66, -69, -71, -72, -75, -79, -81, + -84, -87, -90, -93, -97, -101, -107, -114, + -999, -999, -999, -999, -999, -999, -999, -999}, + { -9, -9, -9, -9, -9, -9, -9, -9, + -11, -12, -12, -15, -16, -20, -23, -30, + -37, -34, -33, -34, -31, -32, -32, -38, + -47, -44, -41, -40, -47, -49, -46, -46, + -58, -50, -50, -54, -58, -62, -64, -67, + -67, -70, -72, -76, -79, -83, -87, -91, + -96, -100, -104, -110, -999, -999, -999, -999}}, + /* 125 Hz */ + {{ -62, -62, -62, -62, -62, -62, -62, -62, + -62, -62, -63, -64, -66, -67, -66, -68, + -75, -72, -76, -75, -76, -78, -79, -82, + -84, -85, -90, -94, -101, -110, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + { -59, -59, -59, -59, -59, -59, -59, -59, + -59, -59, -59, -60, -60, -61, -63, -66, + -71, -68, -70, -70, -71, -72, -72, -75, + -81, -78, -79, -82, -83, -86, -90, -97, + -103, -113, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + { -53, -53, -53, -53, -53, -53, -53, -53, + -53, -54, -55, -57, -56, -57, -55, -61, + -65, -60, -60, -62, -63, -63, -66, -68, + -74, -73, -75, -75, -78, -80, -80, -82, + -85, -90, -96, -101, -108, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + { -46, -46, -46, -46, -46, -46, -46, -46, + -46, -46, -47, -47, -47, -47, -48, -51, + -57, -51, -49, -50, -51, -53, -54, -59, + -66, -60, -62, -67, -67, -70, -72, -75, + -76, -78, -81, -85, -88, -94, -97, -104, + -112, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + { -36, -36, -36, -36, -36, -36, -36, -36, + -39, -41, -42, -42, -39, -38, -41, -43, + -52, -44, -40, -39, -37, -37, -40, -47, + -54, -50, -48, -50, -55, -61, -59, -62, + -66, -66, -66, -69, -69, -73, -74, -74, + -75, -77, -79, -82, -87, -91, -95, -100, + -108, -115, -999, -999, -999, -999, -999, -999}, + { -28, -26, -24, -22, -20, -20, -23, -29, + -30, -31, -28, -27, -28, -28, -28, -35, + -40, -33, -32, -29, -30, -30, -30, -37, + -45, -41, -37, -38, -45, -47, -47, -48, + -53, -49, -48, -50, -49, -49, -51, -52, + -58, -56, -57, -56, -60, -61, -62, -70, + -72, -74, -78, -83, -88, -93, -100, -106}}, + /* 177 Hz */ + {{-999, -999, -999, -999, -999, -999, -999, -999, + -999, -110, -105, -100, -95, -91, -87, -83, + -80, -78, -76, -78, -78, -81, -83, -85, + -86, -85, -86, -87, -90, -97, -107, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -110, -105, -100, -95, -90, + -85, -81, -77, -73, -70, -67, -67, -68, + -75, -73, -70, -69, -70, -72, -75, -79, + -84, -83, -84, -86, -88, -89, -89, -93, + -98, -105, -112, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-105, -100, -95, -90, -85, -80, -76, -71, + -68, -68, -65, -63, -63, -62, -62, -64, + -65, -64, -61, -62, -63, -64, -66, -68, + -73, -73, -74, -75, -76, -81, -83, -85, + -88, -89, -92, -95, -100, -108, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + { -80, -75, -71, -68, -65, -63, -62, -61, + -61, -61, -61, -59, -56, -57, -53, -50, + -58, -52, -50, -50, -52, -53, -54, -58, + -67, -63, -67, -68, -72, -75, -78, -80, + -81, -81, -82, -85, -89, -90, -93, -97, + -101, -107, -114, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + { -65, -61, -59, -57, -56, -55, -55, -56, + -56, -57, -55, -53, -52, -47, -44, -44, + -50, -44, -41, -39, -39, -42, -40, -46, + -51, -49, -50, -53, -54, -63, -60, -61, + -62, -66, -66, -66, -70, -73, -74, -75, + -76, -75, -79, -85, -89, -91, -96, -102, + -110, -999, -999, -999, -999, -999, -999, -999}, + { -52, -50, -49, -49, -48, -48, -48, -49, + -50, -50, -49, -46, -43, -39, -35, -33, + -38, -36, -32, -29, -32, -32, -32, -35, + -44, -39, -38, -38, -46, -50, -45, -46, + -53, -50, -50, -50, -54, -54, -53, -53, + -56, -57, -59, -66, -70, -72, -74, -79, + -83, -85, -90, -97, -114, -999, -999, -999}}, + /* 250 Hz */ + {{-999, -999, -999, -999, -999, -999, -110, -105, + -100, -95, -90, -86, -80, -75, -75, -79, + -80, -79, -80, -81, -82, -88, -95, -103, + -110, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -108, -103, -98, -93, + -88, -83, -79, -78, -75, -71, -67, -68, + -73, -73, -72, -73, -75, -77, -80, -82, + -88, -93, -100, -107, -114, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -110, -105, -101, -96, -90, + -86, -81, -77, -73, -69, -66, -61, -62, + -66, -64, -62, -65, -66, -70, -72, -76, + -81, -80, -84, -90, -95, -102, -110, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -107, -103, -97, -92, -88, + -83, -79, -74, -70, -66, -59, -53, -58, + -62, -55, -54, -54, -54, -58, -61, -62, + -72, -70, -72, -75, -78, -80, -81, -80, + -83, -83, -88, -93, -100, -107, -115, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -105, -100, -95, -90, -85, + -80, -75, -70, -66, -62, -56, -48, -44, + -48, -46, -46, -43, -46, -48, -48, -51, + -58, -58, -59, -60, -62, -62, -61, -61, + -65, -64, -65, -68, -70, -74, -75, -78, + -81, -86, -95, -110, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -105, -100, -95, -90, -85, -80, + -75, -70, -65, -61, -55, -49, -39, -33, + -40, -35, -32, -38, -40, -33, -35, -37, + -46, -41, -45, -44, -46, -42, -45, -46, + -52, -50, -50, -50, -54, -54, -55, -57, + -62, -64, -66, -68, -70, -76, -81, -90, + -100, -110, -999, -999, -999, -999, -999, -999}}, + /* 354 hz */ + {{-999, -999, -999, -999, -999, -999, -999, -999, + -105, -98, -90, -85, -82, -83, -80, -78, + -84, -79, -80, -83, -87, -89, -91, -93, + -99, -106, -117, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -105, -98, -90, -85, -80, -75, -70, -68, + -74, -72, -74, -77, -80, -82, -85, -87, + -92, -89, -91, -95, -100, -106, -112, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -105, -98, -90, -83, -75, -71, -63, -64, + -67, -62, -64, -67, -70, -73, -77, -81, + -84, -83, -85, -89, -90, -93, -98, -104, + -109, -114, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -103, -96, -88, -81, -75, -68, -58, -54, + -56, -54, -56, -56, -58, -60, -63, -66, + -74, -69, -72, -72, -75, -74, -77, -81, + -81, -82, -84, -87, -93, -96, -99, -104, + -110, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -108, -102, -96, + -91, -85, -80, -74, -68, -60, -51, -46, + -48, -46, -43, -45, -47, -47, -49, -48, + -56, -53, -55, -58, -57, -63, -58, -60, + -66, -64, -67, -70, -70, -74, -77, -84, + -86, -89, -91, -93, -94, -101, -109, -118, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -108, -103, -98, -93, -88, + -83, -78, -73, -68, -60, -53, -44, -35, + -38, -38, -34, -34, -36, -40, -41, -44, + -51, -45, -46, -47, -46, -54, -50, -49, + -50, -50, -50, -51, -54, -57, -58, -60, + -66, -66, -66, -64, -65, -68, -77, -82, + -87, -95, -110, -999, -999, -999, -999, -999}}, + /* 500 Hz */ + {{-999, -999, -999, -999, -999, -999, -999, -999, + -107, -102, -97, -92, -87, -83, -78, -75, + -82, -79, -83, -85, -89, -92, -95, -98, + -101, -105, -109, -113, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -106, + -100, -95, -90, -86, -81, -78, -74, -69, + -74, -74, -76, -79, -83, -84, -86, -89, + -92, -97, -93, -100, -103, -107, -110, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -106, -100, + -95, -90, -87, -83, -80, -75, -69, -60, + -66, -66, -68, -70, -74, -78, -79, -81, + -81, -83, -84, -87, -93, -96, -99, -103, + -107, -110, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -108, -103, -98, + -93, -89, -85, -82, -78, -71, -62, -55, + -58, -58, -54, -54, -55, -59, -61, -62, + -70, -66, -66, -67, -70, -72, -75, -78, + -84, -84, -84, -88, -91, -90, -95, -98, + -102, -103, -106, -110, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -108, -103, -98, -94, + -90, -87, -82, -79, -73, -67, -58, -47, + -50, -45, -41, -45, -48, -44, -44, -49, + -54, -51, -48, -47, -49, -50, -51, -57, + -58, -60, -63, -69, -70, -69, -71, -74, + -78, -82, -90, -95, -101, -105, -110, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -105, -101, -97, -93, -90, + -85, -80, -77, -72, -65, -56, -48, -37, + -40, -36, -34, -40, -50, -47, -38, -41, + -47, -38, -35, -39, -38, -43, -40, -45, + -50, -45, -44, -47, -50, -55, -48, -48, + -52, -66, -70, -76, -82, -90, -97, -105, + -110, -999, -999, -999, -999, -999, -999, -999}}, + /* 707 Hz */ + {{-999, -999, -999, -999, -999, -999, -999, -999, + -999, -108, -103, -98, -93, -86, -79, -76, + -83, -81, -85, -87, -89, -93, -98, -102, + -107, -112, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -108, -103, -98, -93, -86, -79, -71, + -77, -74, -77, -79, -81, -84, -85, -90, + -92, -93, -92, -98, -101, -108, -112, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -108, -103, -98, -93, -87, -78, -68, -65, + -66, -62, -65, -67, -70, -73, -75, -78, + -82, -82, -83, -84, -91, -93, -98, -102, + -106, -110, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -105, -100, -95, -90, -82, -74, -62, -57, + -58, -56, -51, -52, -52, -54, -54, -58, + -66, -59, -60, -63, -66, -69, -73, -79, + -83, -84, -80, -81, -81, -82, -88, -92, + -98, -105, -113, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -107, + -102, -97, -92, -84, -79, -69, -57, -47, + -52, -47, -44, -45, -50, -52, -42, -42, + -53, -43, -43, -48, -51, -56, -55, -52, + -57, -59, -61, -62, -67, -71, -78, -83, + -86, -94, -98, -103, -110, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -105, -100, + -95, -90, -84, -78, -70, -61, -51, -41, + -40, -38, -40, -46, -52, -51, -41, -40, + -46, -40, -38, -38, -41, -46, -41, -46, + -47, -43, -43, -45, -41, -45, -56, -67, + -68, -83, -87, -90, -95, -102, -107, -113, + -999, -999, -999, -999, -999, -999, -999, -999}}, + /* 1000 Hz */ + {{-999, -999, -999, -999, -999, -999, -999, -999, + -999, -109, -105, -101, -96, -91, -84, -77, + -82, -82, -85, -89, -94, -100, -106, -110, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -106, -103, -98, -92, -85, -80, -71, + -75, -72, -76, -80, -84, -86, -89, -93, + -100, -107, -113, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -107, + -104, -101, -97, -92, -88, -84, -80, -64, + -66, -63, -64, -66, -69, -73, -77, -83, + -83, -86, -91, -98, -104, -111, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -107, + -104, -101, -97, -92, -90, -84, -74, -57, + -58, -52, -55, -54, -50, -52, -50, -52, + -63, -62, -69, -76, -77, -78, -78, -79, + -82, -88, -94, -100, -106, -111, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -106, -102, + -98, -95, -90, -85, -83, -78, -70, -50, + -50, -41, -44, -49, -47, -50, -50, -44, + -55, -46, -47, -48, -48, -54, -49, -49, + -58, -62, -71, -81, -87, -92, -97, -102, + -108, -114, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -106, -102, + -98, -95, -90, -85, -83, -78, -70, -45, + -43, -41, -47, -50, -51, -50, -49, -45, + -47, -41, -44, -41, -39, -43, -38, -37, + -40, -41, -44, -50, -58, -65, -73, -79, + -85, -92, -97, -101, -105, -109, -113, -999, + -999, -999, -999, -999, -999, -999, -999, -999}}, + /* 1414 Hz */ + {{-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -107, -100, -95, -87, -81, + -85, -83, -88, -93, -100, -107, -114, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -107, -101, -95, -88, -83, -76, + -73, -72, -79, -84, -90, -95, -100, -105, + -110, -115, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -104, -98, -92, -87, -81, -70, + -65, -62, -67, -71, -74, -80, -85, -91, + -95, -99, -103, -108, -111, -114, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -103, -97, -90, -85, -76, -60, + -56, -54, -60, -62, -61, -56, -63, -65, + -73, -74, -77, -75, -78, -81, -86, -87, + -88, -91, -94, -98, -103, -110, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -105, + -100, -97, -92, -86, -81, -79, -70, -57, + -51, -47, -51, -58, -60, -56, -53, -50, + -58, -52, -50, -50, -53, -55, -64, -69, + -71, -85, -82, -78, -81, -85, -95, -102, + -112, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -105, + -100, -97, -92, -85, -83, -79, -72, -49, + -40, -43, -43, -54, -56, -51, -50, -40, + -43, -38, -36, -35, -37, -38, -37, -44, + -54, -60, -57, -60, -70, -75, -84, -92, + -103, -112, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}}, + /* 2000 Hz */ + {{-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -110, -102, -95, -89, -82, + -83, -84, -90, -92, -99, -107, -113, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -107, -101, -95, -89, -83, -72, + -74, -78, -85, -88, -88, -90, -92, -98, + -105, -111, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -109, -103, -97, -93, -87, -81, -70, + -70, -67, -75, -73, -76, -79, -81, -83, + -88, -89, -97, -103, -110, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -107, -100, -94, -88, -83, -75, -63, + -59, -59, -63, -66, -60, -62, -67, -67, + -77, -76, -81, -88, -86, -92, -96, -102, + -109, -116, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -105, -98, -92, -86, -81, -73, -56, + -52, -47, -55, -60, -58, -52, -51, -45, + -49, -50, -53, -54, -61, -71, -70, -69, + -78, -79, -87, -90, -96, -104, -112, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -103, -96, -90, -86, -78, -70, -51, + -42, -47, -48, -55, -54, -54, -53, -42, + -35, -28, -33, -38, -37, -44, -47, -49, + -54, -63, -68, -78, -82, -89, -94, -99, + -104, -109, -114, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}}, + /* 2828 Hz */ + {{-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -110, -100, -90, -79, + -85, -81, -82, -82, -89, -94, -99, -103, + -109, -115, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -105, -97, -85, -72, + -74, -70, -70, -70, -76, -85, -91, -93, + -97, -103, -109, -115, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -112, -93, -81, -68, + -62, -60, -60, -57, -63, -70, -77, -82, + -90, -93, -98, -104, -109, -113, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -113, -100, -93, -84, -63, + -58, -48, -53, -54, -52, -52, -57, -64, + -66, -76, -83, -81, -85, -85, -90, -95, + -98, -101, -103, -106, -108, -111, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -105, -95, -86, -74, -53, + -50, -38, -43, -49, -43, -42, -39, -39, + -46, -52, -57, -56, -72, -69, -74, -81, + -87, -92, -94, -97, -99, -102, -105, -108, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -108, -99, -90, -76, -66, -45, + -43, -41, -44, -47, -43, -47, -40, -30, + -31, -31, -39, -33, -40, -41, -43, -53, + -59, -70, -73, -77, -79, -82, -84, -87, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}}, + /* 4000 Hz */ + {{-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -110, -91, -76, + -75, -85, -93, -98, -104, -110, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -110, -91, -70, + -70, -75, -86, -89, -94, -98, -101, -106, + -110, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -110, -95, -80, -60, + -65, -64, -74, -83, -88, -91, -95, -99, + -103, -107, -110, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -110, -95, -80, -58, + -55, -49, -66, -68, -71, -78, -78, -80, + -88, -85, -89, -97, -100, -105, -110, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -110, -95, -80, -53, + -52, -41, -59, -59, -49, -58, -56, -63, + -86, -79, -90, -93, -98, -103, -107, -112, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -110, -97, -91, -73, -45, + -40, -33, -53, -61, -49, -54, -50, -50, + -60, -52, -67, -74, -81, -92, -96, -100, + -105, -110, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}}, + /* 5657 Hz */ + {{-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -113, -106, -99, -92, -77, + -80, -88, -97, -106, -115, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -116, -109, -102, -95, -89, -74, + -72, -88, -87, -95, -102, -109, -116, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -116, -109, -102, -95, -89, -75, + -66, -74, -77, -78, -86, -87, -90, -96, + -105, -115, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -115, -108, -101, -94, -88, -66, + -56, -61, -70, -65, -78, -72, -83, -84, + -93, -98, -105, -110, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -110, -105, -95, -89, -82, -57, + -52, -52, -59, -56, -59, -58, -69, -67, + -88, -82, -82, -89, -94, -100, -108, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -110, -101, -96, -90, -83, -77, -54, + -43, -38, -50, -48, -52, -48, -42, -42, + -51, -52, -53, -59, -65, -71, -78, -85, + -95, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}}, + /* 8000 Hz */ + {{-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -120, -105, -86, -68, + -78, -79, -90, -100, -110, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -120, -105, -86, -66, + -73, -77, -88, -96, -105, -115, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -120, -105, -92, -80, -61, + -64, -68, -80, -87, -92, -100, -110, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -120, -104, -91, -79, -52, + -60, -54, -64, -69, -77, -80, -82, -84, + -85, -87, -88, -90, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -118, -100, -87, -77, -49, + -50, -44, -58, -61, -61, -67, -65, -62, + -62, -62, -65, -68, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -115, -98, -84, -62, -49, + -44, -38, -46, -49, -49, -46, -39, -37, + -39, -40, -42, -43, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}}, + /* 11314 Hz */ + {{-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -110, -88, -74, + -77, -82, -82, -85, -90, -94, -99, -104, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -110, -88, -66, + -70, -81, -80, -81, -84, -88, -91, -93, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -110, -88, -61, + -63, -70, -71, -74, -77, -80, -83, -85, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -110, -86, -62, + -63, -62, -62, -58, -52, -50, -50, -52, + -54, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -118, -108, -84, -53, + -50, -50, -50, -55, -47, -45, -40, -40, + -40, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -118, -100, -73, -43, + -37, -42, -43, -53, -38, -37, -35, -35, + -38, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}}, + /* 16000 Hz */ + {{-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -110, -100, -91, -84, -74, + -80, -80, -80, -80, -80, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -110, -100, -91, -84, -74, + -68, -68, -68, -68, -68, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -110, -100, -86, -78, -70, + -60, -45, -30, -21, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -110, -100, -87, -78, -67, + -48, -38, -29, -21, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -110, -100, -86, -69, -56, + -45, -35, -33, -29, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}, + {-999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -110, -100, -83, -71, -48, + -27, -38, -37, -34, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999, + -999, -999, -999, -999, -999, -999, -999, -999}} +}; + +#endif diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/mdct.c b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/mdct.c new file mode 100644 index 0000000..4e153b3 --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/mdct.c @@ -0,0 +1,564 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: normalized modified discrete cosine transform + power of two length transform only [64 <= n ] + last mod: $Id: mdct.c 7187 2004-07-20 07:24:27Z xiphmont $ + + Original algorithm adapted long ago from _The use of multirate filter + banks for coding of high quality digital audio_, by T. Sporer, + K. Brandenburg and B. Edler, collection of the European Signal + Processing Conference (EUSIPCO), Amsterdam, June 1992, Vol.1, pp + 211-214 + + The below code implements an algorithm that no longer looks much like + that presented in the paper, but the basic structure remains if you + dig deep enough to see it. + + This module DOES NOT INCLUDE code to generate/apply the window + function. Everybody has their own weird favorite including me... I + happen to like the properties of y=sin(.5PI*sin^2(x)), but others may + vehemently disagree. + + ********************************************************************/ + +/* this can also be run as an integer transform by uncommenting a + define in mdct.h; the integerization is a first pass and although + it's likely stable for Vorbis, the dynamic range is constrained and + roundoff isn't done (so it's noisy). Consider it functional, but + only a starting point. There's no point on a machine with an FPU */ + +#include +#include +#include +#include +#include "vorbis/codec.h" +#include "mdct.h" +#include "os.h" +#include "misc.h" + +/* build lookups for trig functions; also pre-figure scaling and + some window function algebra. */ + +void mdct_init(mdct_lookup *lookup,int n){ + int *bitrev=_ogg_malloc(sizeof(*bitrev)*(n/4)); + DATA_TYPE *T=_ogg_malloc(sizeof(*T)*(n+n/4)); + + int i; + int n2=n>>1; + int log2n=lookup->log2n=rint(log((float)n)/log(2.f)); + lookup->n=n; + lookup->trig=T; + lookup->bitrev=bitrev; + +/* trig lookups... */ + + for(i=0;i>j;j++) + if((msb>>j)&i)acc|=1<scale=FLOAT_CONV(4.f/n); +} + +/* 8 point butterfly (in place, 4 register) */ +STIN void mdct_butterfly_8(DATA_TYPE *x){ + REG_TYPE r0 = x[6] + x[2]; + REG_TYPE r1 = x[6] - x[2]; + REG_TYPE r2 = x[4] + x[0]; + REG_TYPE r3 = x[4] - x[0]; + + x[6] = r0 + r2; + x[4] = r0 - r2; + + r0 = x[5] - x[1]; + r2 = x[7] - x[3]; + x[0] = r1 + r0; + x[2] = r1 - r0; + + r0 = x[5] + x[1]; + r1 = x[7] + x[3]; + x[3] = r2 + r3; + x[1] = r2 - r3; + x[7] = r1 + r0; + x[5] = r1 - r0; + +} + +/* 16 point butterfly (in place, 4 register) */ +STIN void mdct_butterfly_16(DATA_TYPE *x){ + REG_TYPE r0 = x[1] - x[9]; + REG_TYPE r1 = x[0] - x[8]; + + x[8] += x[0]; + x[9] += x[1]; + x[0] = MULT_NORM((r0 + r1) * cPI2_8); + x[1] = MULT_NORM((r0 - r1) * cPI2_8); + + r0 = x[3] - x[11]; + r1 = x[10] - x[2]; + x[10] += x[2]; + x[11] += x[3]; + x[2] = r0; + x[3] = r1; + + r0 = x[12] - x[4]; + r1 = x[13] - x[5]; + x[12] += x[4]; + x[13] += x[5]; + x[4] = MULT_NORM((r0 - r1) * cPI2_8); + x[5] = MULT_NORM((r0 + r1) * cPI2_8); + + r0 = x[14] - x[6]; + r1 = x[15] - x[7]; + x[14] += x[6]; + x[15] += x[7]; + x[6] = r0; + x[7] = r1; + + mdct_butterfly_8(x); + mdct_butterfly_8(x+8); +} + +/* 32 point butterfly (in place, 4 register) */ +STIN void mdct_butterfly_32(DATA_TYPE *x){ + REG_TYPE r0 = x[30] - x[14]; + REG_TYPE r1 = x[31] - x[15]; + + x[30] += x[14]; + x[31] += x[15]; + x[14] = r0; + x[15] = r1; + + r0 = x[28] - x[12]; + r1 = x[29] - x[13]; + x[28] += x[12]; + x[29] += x[13]; + x[12] = MULT_NORM( r0 * cPI1_8 - r1 * cPI3_8 ); + x[13] = MULT_NORM( r0 * cPI3_8 + r1 * cPI1_8 ); + + r0 = x[26] - x[10]; + r1 = x[27] - x[11]; + x[26] += x[10]; + x[27] += x[11]; + x[10] = MULT_NORM(( r0 - r1 ) * cPI2_8); + x[11] = MULT_NORM(( r0 + r1 ) * cPI2_8); + + r0 = x[24] - x[8]; + r1 = x[25] - x[9]; + x[24] += x[8]; + x[25] += x[9]; + x[8] = MULT_NORM( r0 * cPI3_8 - r1 * cPI1_8 ); + x[9] = MULT_NORM( r1 * cPI3_8 + r0 * cPI1_8 ); + + r0 = x[22] - x[6]; + r1 = x[7] - x[23]; + x[22] += x[6]; + x[23] += x[7]; + x[6] = r1; + x[7] = r0; + + r0 = x[4] - x[20]; + r1 = x[5] - x[21]; + x[20] += x[4]; + x[21] += x[5]; + x[4] = MULT_NORM( r1 * cPI1_8 + r0 * cPI3_8 ); + x[5] = MULT_NORM( r1 * cPI3_8 - r0 * cPI1_8 ); + + r0 = x[2] - x[18]; + r1 = x[3] - x[19]; + x[18] += x[2]; + x[19] += x[3]; + x[2] = MULT_NORM(( r1 + r0 ) * cPI2_8); + x[3] = MULT_NORM(( r1 - r0 ) * cPI2_8); + + r0 = x[0] - x[16]; + r1 = x[1] - x[17]; + x[16] += x[0]; + x[17] += x[1]; + x[0] = MULT_NORM( r1 * cPI3_8 + r0 * cPI1_8 ); + x[1] = MULT_NORM( r1 * cPI1_8 - r0 * cPI3_8 ); + + mdct_butterfly_16(x); + mdct_butterfly_16(x+16); + +} + +/* N point first stage butterfly (in place, 2 register) */ +STIN void mdct_butterfly_first(DATA_TYPE *T, + DATA_TYPE *x, + int points){ + + DATA_TYPE *x1 = x + points - 8; + DATA_TYPE *x2 = x + (points>>1) - 8; + REG_TYPE r0; + REG_TYPE r1; + + do{ + + r0 = x1[6] - x2[6]; + r1 = x1[7] - x2[7]; + x1[6] += x2[6]; + x1[7] += x2[7]; + x2[6] = MULT_NORM(r1 * T[1] + r0 * T[0]); + x2[7] = MULT_NORM(r1 * T[0] - r0 * T[1]); + + r0 = x1[4] - x2[4]; + r1 = x1[5] - x2[5]; + x1[4] += x2[4]; + x1[5] += x2[5]; + x2[4] = MULT_NORM(r1 * T[5] + r0 * T[4]); + x2[5] = MULT_NORM(r1 * T[4] - r0 * T[5]); + + r0 = x1[2] - x2[2]; + r1 = x1[3] - x2[3]; + x1[2] += x2[2]; + x1[3] += x2[3]; + x2[2] = MULT_NORM(r1 * T[9] + r0 * T[8]); + x2[3] = MULT_NORM(r1 * T[8] - r0 * T[9]); + + r0 = x1[0] - x2[0]; + r1 = x1[1] - x2[1]; + x1[0] += x2[0]; + x1[1] += x2[1]; + x2[0] = MULT_NORM(r1 * T[13] + r0 * T[12]); + x2[1] = MULT_NORM(r1 * T[12] - r0 * T[13]); + + x1-=8; + x2-=8; + T+=16; + + }while(x2>=x); +} + +/* N/stage point generic N stage butterfly (in place, 2 register) */ +STIN void mdct_butterfly_generic(DATA_TYPE *T, + DATA_TYPE *x, + int points, + int trigint){ + + DATA_TYPE *x1 = x + points - 8; + DATA_TYPE *x2 = x + (points>>1) - 8; + REG_TYPE r0; + REG_TYPE r1; + + do{ + + r0 = x1[6] - x2[6]; + r1 = x1[7] - x2[7]; + x1[6] += x2[6]; + x1[7] += x2[7]; + x2[6] = MULT_NORM(r1 * T[1] + r0 * T[0]); + x2[7] = MULT_NORM(r1 * T[0] - r0 * T[1]); + + T+=trigint; + + r0 = x1[4] - x2[4]; + r1 = x1[5] - x2[5]; + x1[4] += x2[4]; + x1[5] += x2[5]; + x2[4] = MULT_NORM(r1 * T[1] + r0 * T[0]); + x2[5] = MULT_NORM(r1 * T[0] - r0 * T[1]); + + T+=trigint; + + r0 = x1[2] - x2[2]; + r1 = x1[3] - x2[3]; + x1[2] += x2[2]; + x1[3] += x2[3]; + x2[2] = MULT_NORM(r1 * T[1] + r0 * T[0]); + x2[3] = MULT_NORM(r1 * T[0] - r0 * T[1]); + + T+=trigint; + + r0 = x1[0] - x2[0]; + r1 = x1[1] - x2[1]; + x1[0] += x2[0]; + x1[1] += x2[1]; + x2[0] = MULT_NORM(r1 * T[1] + r0 * T[0]); + x2[1] = MULT_NORM(r1 * T[0] - r0 * T[1]); + + T+=trigint; + x1-=8; + x2-=8; + + }while(x2>=x); +} + +STIN void mdct_butterflies(mdct_lookup *init, + DATA_TYPE *x, + int points){ + + DATA_TYPE *T=init->trig; + int stages=init->log2n-5; + int i,j; + + if(--stages>0){ + mdct_butterfly_first(T,x,points); + } + + for(i=1;--stages>0;i++){ + for(j=0;j<(1<>i)*j,points>>i,4<trig)_ogg_free(l->trig); + if(l->bitrev)_ogg_free(l->bitrev); + memset(l,0,sizeof(*l)); + } +} + +STIN void mdct_bitreverse(mdct_lookup *init, + DATA_TYPE *x){ + int n = init->n; + int *bit = init->bitrev; + DATA_TYPE *w0 = x; + DATA_TYPE *w1 = x = w0+(n>>1); + DATA_TYPE *T = init->trig+n; + + do{ + DATA_TYPE *x0 = x+bit[0]; + DATA_TYPE *x1 = x+bit[1]; + + REG_TYPE r0 = x0[1] - x1[1]; + REG_TYPE r1 = x0[0] + x1[0]; + REG_TYPE r2 = MULT_NORM(r1 * T[0] + r0 * T[1]); + REG_TYPE r3 = MULT_NORM(r1 * T[1] - r0 * T[0]); + + w1 -= 4; + + r0 = HALVE(x0[1] + x1[1]); + r1 = HALVE(x0[0] - x1[0]); + + w0[0] = r0 + r2; + w1[2] = r0 - r2; + w0[1] = r1 + r3; + w1[3] = r3 - r1; + + x0 = x+bit[2]; + x1 = x+bit[3]; + + r0 = x0[1] - x1[1]; + r1 = x0[0] + x1[0]; + r2 = MULT_NORM(r1 * T[2] + r0 * T[3]); + r3 = MULT_NORM(r1 * T[3] - r0 * T[2]); + + r0 = HALVE(x0[1] + x1[1]); + r1 = HALVE(x0[0] - x1[0]); + + w0[2] = r0 + r2; + w1[0] = r0 - r2; + w0[3] = r1 + r3; + w1[1] = r3 - r1; + + T += 4; + bit += 4; + w0 += 4; + + }while(w0n; + int n2=n>>1; + int n4=n>>2; + + /* rotate */ + + DATA_TYPE *iX = in+n2-7; + DATA_TYPE *oX = out+n2+n4; + DATA_TYPE *T = init->trig+n4; + + do{ + oX -= 4; + oX[0] = MULT_NORM(-iX[2] * T[3] - iX[0] * T[2]); + oX[1] = MULT_NORM (iX[0] * T[3] - iX[2] * T[2]); + oX[2] = MULT_NORM(-iX[6] * T[1] - iX[4] * T[0]); + oX[3] = MULT_NORM (iX[4] * T[1] - iX[6] * T[0]); + iX -= 8; + T += 4; + }while(iX>=in); + + iX = in+n2-8; + oX = out+n2+n4; + T = init->trig+n4; + + do{ + T -= 4; + oX[0] = MULT_NORM (iX[4] * T[3] + iX[6] * T[2]); + oX[1] = MULT_NORM (iX[4] * T[2] - iX[6] * T[3]); + oX[2] = MULT_NORM (iX[0] * T[1] + iX[2] * T[0]); + oX[3] = MULT_NORM (iX[0] * T[0] - iX[2] * T[1]); + iX -= 8; + oX += 4; + }while(iX>=in); + + mdct_butterflies(init,out+n2,n2); + mdct_bitreverse(init,out); + + /* roatate + window */ + + { + DATA_TYPE *oX1=out+n2+n4; + DATA_TYPE *oX2=out+n2+n4; + DATA_TYPE *iX =out; + T =init->trig+n2; + + do{ + oX1-=4; + + oX1[3] = MULT_NORM (iX[0] * T[1] - iX[1] * T[0]); + oX2[0] = -MULT_NORM (iX[0] * T[0] + iX[1] * T[1]); + + oX1[2] = MULT_NORM (iX[2] * T[3] - iX[3] * T[2]); + oX2[1] = -MULT_NORM (iX[2] * T[2] + iX[3] * T[3]); + + oX1[1] = MULT_NORM (iX[4] * T[5] - iX[5] * T[4]); + oX2[2] = -MULT_NORM (iX[4] * T[4] + iX[5] * T[5]); + + oX1[0] = MULT_NORM (iX[6] * T[7] - iX[7] * T[6]); + oX2[3] = -MULT_NORM (iX[6] * T[6] + iX[7] * T[7]); + + oX2+=4; + iX += 8; + T += 8; + }while(iXoX2); + } +} + +void mdct_forward(mdct_lookup *init, DATA_TYPE *in, DATA_TYPE *out){ + int n=init->n; + int n2=n>>1; + int n4=n>>2; + int n8=n>>3; + DATA_TYPE *w=alloca(n*sizeof(*w)); /* forward needs working space */ + DATA_TYPE *w2=w+n2; + + /* rotate */ + + /* window + rotate + step 1 */ + + REG_TYPE r0; + REG_TYPE r1; + DATA_TYPE *x0=in+n2+n4; + DATA_TYPE *x1=x0+1; + DATA_TYPE *T=init->trig+n2; + + int i=0; + + for(i=0;itrig+n2; + x0=out+n2; + + for(i=0;iscale); + x0[0] =MULT_NORM((w[0]*T[1]-w[1]*T[0])*init->scale); + w+=2; + T+=2; + } +} + diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/mdct.h b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/mdct.h new file mode 100644 index 0000000..176daad --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/mdct.h @@ -0,0 +1,83 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: modified discrete cosine transform prototypes + last mod: $Id: mdct.h 7187 2004-07-20 07:24:27Z xiphmont $ + + ********************************************************************/ + +#ifndef _OGG_mdct_H_ +#define _OGG_mdct_H_ + +#include "vorbis/codec.h" + + + + + +/*#define MDCT_INTEGERIZED <- be warned there could be some hurt left here*/ +#ifdef MDCT_INTEGERIZED + +#define DATA_TYPE int +#define REG_TYPE register int +#define TRIGBITS 14 +#define cPI3_8 6270 +#define cPI2_8 11585 +#define cPI1_8 15137 + +#define FLOAT_CONV(x) ((int)((x)*(1<>TRIGBITS) +#define HALVE(x) ((x)>>1) + +#else + +#define DATA_TYPE float +#define REG_TYPE float +#define cPI3_8 .38268343236508977175F +#define cPI2_8 .70710678118654752441F +#define cPI1_8 .92387953251128675613F + +#define FLOAT_CONV(x) (x) +#define MULT_NORM(x) (x) +#define HALVE(x) ((x)*.5f) + +#endif + + +typedef struct { + int n; + int log2n; + + DATA_TYPE *trig; + int *bitrev; + + DATA_TYPE scale; +} mdct_lookup; + +extern void mdct_init(mdct_lookup *lookup,int n); +extern void mdct_clear(mdct_lookup *l); +extern void mdct_forward(mdct_lookup *init, DATA_TYPE *in, DATA_TYPE *out); +extern void mdct_backward(mdct_lookup *init, DATA_TYPE *in, DATA_TYPE *out); + +#endif + + + + + + + + + + + + diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/misc.h b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/misc.h new file mode 100644 index 0000000..0102232 --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/misc.h @@ -0,0 +1,52 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: miscellaneous prototypes + last mod: $Id: misc.h 7187 2004-07-20 07:24:27Z xiphmont $ + + ********************************************************************/ + +#ifndef _V_RANDOM_H_ +#define _V_RANDOM_H_ +#include "vorbis/codec.h" + +extern int analysis_noisy; + +extern void *_vorbis_block_alloc(vorbis_block *vb,long bytes); +extern void _vorbis_block_ripcord(vorbis_block *vb); +extern void _analysis_output(char *base,int i,float *v,int n,int bark,int dB, + ogg_int64_t off); + +#ifdef DEBUG_MALLOC + +#define _VDBG_GRAPHFILE "malloc.m" +extern void *_VDBG_malloc(void *ptr,long bytes,char *file,long line); +extern void _VDBG_free(void *ptr,char *file,long line); + +#ifndef MISC_C +#undef _ogg_malloc +#undef _ogg_calloc +#undef _ogg_realloc +#undef _ogg_free + +#define _ogg_malloc(x) _VDBG_malloc(NULL,(x),__FILE__,__LINE__) +#define _ogg_calloc(x,y) _VDBG_malloc(NULL,(x)*(y),__FILE__,__LINE__) +#define _ogg_realloc(x,y) _VDBG_malloc((x),(y),__FILE__,__LINE__) +#define _ogg_free(x) _VDBG_free((x),__FILE__,__LINE__) +#endif +#endif + +#endif + + + + diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/floor_all.h b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/floor_all.h new file mode 100644 index 0000000..0f5d4b0 --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/floor_all.h @@ -0,0 +1,248 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: key floor settings + last mod: $Id: floor_all.h 7187 2004-07-20 07:24:27Z xiphmont $ + + ********************************************************************/ + +#include "vorbis/codec.h" +#include "backends.h" +#include "books/floor/floor_books.h" + +static static_codebook *_floor_128x4_books[]={ + &_huff_book_line_128x4_class0, + &_huff_book_line_128x4_0sub0, + &_huff_book_line_128x4_0sub1, + &_huff_book_line_128x4_0sub2, + &_huff_book_line_128x4_0sub3, +}; +static static_codebook *_floor_256x4_books[]={ + &_huff_book_line_256x4_class0, + &_huff_book_line_256x4_0sub0, + &_huff_book_line_256x4_0sub1, + &_huff_book_line_256x4_0sub2, + &_huff_book_line_256x4_0sub3, +}; +static static_codebook *_floor_128x7_books[]={ + &_huff_book_line_128x7_class0, + &_huff_book_line_128x7_class1, + + &_huff_book_line_128x7_0sub1, + &_huff_book_line_128x7_0sub2, + &_huff_book_line_128x7_0sub3, + &_huff_book_line_128x7_1sub1, + &_huff_book_line_128x7_1sub2, + &_huff_book_line_128x7_1sub3, +}; +static static_codebook *_floor_256x7_books[]={ + &_huff_book_line_256x7_class0, + &_huff_book_line_256x7_class1, + + &_huff_book_line_256x7_0sub1, + &_huff_book_line_256x7_0sub2, + &_huff_book_line_256x7_0sub3, + &_huff_book_line_256x7_1sub1, + &_huff_book_line_256x7_1sub2, + &_huff_book_line_256x7_1sub3, +}; +static static_codebook *_floor_128x11_books[]={ + &_huff_book_line_128x11_class1, + &_huff_book_line_128x11_class2, + &_huff_book_line_128x11_class3, + + &_huff_book_line_128x11_0sub0, + &_huff_book_line_128x11_1sub0, + &_huff_book_line_128x11_1sub1, + &_huff_book_line_128x11_2sub1, + &_huff_book_line_128x11_2sub2, + &_huff_book_line_128x11_2sub3, + &_huff_book_line_128x11_3sub1, + &_huff_book_line_128x11_3sub2, + &_huff_book_line_128x11_3sub3, +}; +static static_codebook *_floor_128x17_books[]={ + &_huff_book_line_128x17_class1, + &_huff_book_line_128x17_class2, + &_huff_book_line_128x17_class3, + + &_huff_book_line_128x17_0sub0, + &_huff_book_line_128x17_1sub0, + &_huff_book_line_128x17_1sub1, + &_huff_book_line_128x17_2sub1, + &_huff_book_line_128x17_2sub2, + &_huff_book_line_128x17_2sub3, + &_huff_book_line_128x17_3sub1, + &_huff_book_line_128x17_3sub2, + &_huff_book_line_128x17_3sub3, +}; +static static_codebook *_floor_256x4low_books[]={ + &_huff_book_line_256x4low_class0, + &_huff_book_line_256x4low_0sub0, + &_huff_book_line_256x4low_0sub1, + &_huff_book_line_256x4low_0sub2, + &_huff_book_line_256x4low_0sub3, +}; +static static_codebook *_floor_1024x27_books[]={ + &_huff_book_line_1024x27_class1, + &_huff_book_line_1024x27_class2, + &_huff_book_line_1024x27_class3, + &_huff_book_line_1024x27_class4, + + &_huff_book_line_1024x27_0sub0, + &_huff_book_line_1024x27_1sub0, + &_huff_book_line_1024x27_1sub1, + &_huff_book_line_1024x27_2sub0, + &_huff_book_line_1024x27_2sub1, + &_huff_book_line_1024x27_3sub1, + &_huff_book_line_1024x27_3sub2, + &_huff_book_line_1024x27_3sub3, + &_huff_book_line_1024x27_4sub1, + &_huff_book_line_1024x27_4sub2, + &_huff_book_line_1024x27_4sub3, +}; +static static_codebook *_floor_2048x27_books[]={ + &_huff_book_line_2048x27_class1, + &_huff_book_line_2048x27_class2, + &_huff_book_line_2048x27_class3, + &_huff_book_line_2048x27_class4, + + &_huff_book_line_2048x27_0sub0, + &_huff_book_line_2048x27_1sub0, + &_huff_book_line_2048x27_1sub1, + &_huff_book_line_2048x27_2sub0, + &_huff_book_line_2048x27_2sub1, + &_huff_book_line_2048x27_3sub1, + &_huff_book_line_2048x27_3sub2, + &_huff_book_line_2048x27_3sub3, + &_huff_book_line_2048x27_4sub1, + &_huff_book_line_2048x27_4sub2, + &_huff_book_line_2048x27_4sub3, +}; + +static static_codebook *_floor_512x17_books[]={ + &_huff_book_line_512x17_class1, + &_huff_book_line_512x17_class2, + &_huff_book_line_512x17_class3, + + &_huff_book_line_512x17_0sub0, + &_huff_book_line_512x17_1sub0, + &_huff_book_line_512x17_1sub1, + &_huff_book_line_512x17_2sub1, + &_huff_book_line_512x17_2sub2, + &_huff_book_line_512x17_2sub3, + &_huff_book_line_512x17_3sub1, + &_huff_book_line_512x17_3sub2, + &_huff_book_line_512x17_3sub3, +}; + +static static_codebook **_floor_books[10]={ + _floor_128x4_books, + _floor_256x4_books, + _floor_128x7_books, + _floor_256x7_books, + _floor_128x11_books, + _floor_128x17_books, + _floor_256x4low_books, + _floor_1024x27_books, + _floor_2048x27_books, + _floor_512x17_books, +}; + +static vorbis_info_floor1 _floor[10]={ + /* 128 x 4 */ + { + 1,{0},{4},{2},{0}, + {{1,2,3,4}}, + 4,{0,128, 33,8,16,70}, + + 60,30,500, 1.,18., -1 + }, + /* 256 x 4 */ + { + 1,{0},{4},{2},{0}, + {{1,2,3,4}}, + 4,{0,256, 66,16,32,140}, + + 60,30,500, 1.,18., -1 + }, + /* 128 x 7 */ + { + 2,{0,1},{3,4},{2,2},{0,1}, + {{-1,2,3,4},{-1,5,6,7}}, + 4,{0,128, 14,4,58, 2,8,28,90}, + + 60,30,500, 1.,18., -1 + }, + /* 256 x 7 */ + { + 2,{0,1},{3,4},{2,2},{0,1}, + {{-1,2,3,4},{-1,5,6,7}}, + 4,{0,256, 28,8,116, 4,16,56,180}, + + 60,30,500, 1.,18., -1 + }, + /* 128 x 11 */ + { + 4,{0,1,2,3},{2,3,3,3},{0,1,2,2},{-1,0,1,2}, + {{3},{4,5},{-1,6,7,8},{-1,9,10,11}}, + + 2,{0,128, 8,33, 4,16,70, 2,6,12, 23,46,90}, + + 60,30,500, 1,18., -1 + }, + /* 128 x 17 */ + { + 6,{0,1,1,2,3,3},{2,3,3,3},{0,1,2,2},{-1,0,1,2}, + {{3},{4,5},{-1,6,7,8},{-1,9,10,11}}, + 2,{0,128, 12,46, 4,8,16, 23,33,70, 2,6,10, 14,19,28, 39,58,90}, + + 60,30,500, 1,18., -1 + }, + /* 256 x 4 (low bitrate version) */ + { + 1,{0},{4},{2},{0}, + {{1,2,3,4}}, + 4,{0,256, 66,16,32,140}, + + 60,30,500, 1.,18., -1 + }, + /* 1024 x 27 */ + { + 8,{0,1,2,2,3,3,4,4},{3,4,3,4,3},{0,1,1,2,2},{-1,0,1,2,3}, + {{4},{5,6},{7,8},{-1,9,10,11},{-1,12,13,14}}, + 2,{0,1024, 93,23,372, 6,46,186,750, 14,33,65, 130,260,556, + 3,10,18,28, 39,55,79,111, 158,220,312, 464,650,850}, + + 60,30,500, 3,18., -1 /* lowpass */ + }, + /* 2048 x 27 */ + { + 8,{0,1,2,2,3,3,4,4},{3,4,3,4,3},{0,1,1,2,2},{-1,0,1,2,3}, + {{4},{5,6},{7,8},{-1,9,10,11},{-1,12,13,14}}, + 2,{0,2048, 186,46,744, 12,92,372,1500, 28,66,130, 260,520,1112, + 6,20,36,56, 78,110,158,222, 316,440,624, 928,1300,1700}, + + 60,30,500, 3,18., -1 /* lowpass */ + }, + /* 512 x 17 */ + { + 6,{0,1,1,2,3,3},{2,3,3,3},{0,1,2,2},{-1,0,1,2}, + {{3},{4,5},{-1,6,7,8},{-1,9,10,11}}, + 2,{0,512, 46,186, 16,33,65, 93,130,278, + 7,23,39, 55,79,110, 156,232,360}, + + 60,30,500, 1,18., -1 /* lowpass! */ + }, + +}; + diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/psych_11.h b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/psych_11.h new file mode 100644 index 0000000..59660f3 --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/psych_11.h @@ -0,0 +1,51 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: 11kHz settings + last mod: $Id: psych_11.h 7187 2004-07-20 07:24:27Z xiphmont $ + + ********************************************************************/ + +static double _psy_lowpass_11[3]={4.5,5.5,30.,}; + +static att3 _psy_tone_masteratt_11[3]={ + {{ 30, 25, 12}, 0, 0}, /* 0 */ + {{ 30, 25, 12}, 0, 0}, /* 0 */ + {{ 20, 0, -14}, 0, 0}, /* 0 */ +}; + +static vp_adjblock _vp_tonemask_adj_11[3]={ + /* adjust for mode zero */ + /* 63 125 250 500 1 2 4 8 16 */ + {{-20,-20,-20,-20,-20,-16,-10, 0, 0, 0, 0,10, 2, 0,99,99,99}}, /* 0 */ + {{-20,-20,-20,-20,-20,-16,-10, 0, 0, 0, 0, 5, 0, 0,99,99,99}}, /* 1 */ + {{-20,-20,-20,-20,-20,-16,-10, 0, 0, 0, 0, 0, 0, 0,99,99,99}}, /* 2 */ +}; + + +static noise3 _psy_noisebias_11[3]={ + /* 63 125 250 500 1k 2k 4k 8k 16k*/ + {{{-10,-10,-10,-10, -5, -5, -5, 0, 4, 10, 10, 12, 12, 12, 99, 99, 99}, + {-15,-15,-15,-15,-10,-10, -5, 0, 0, 4, 4, 5, 5, 10, 99, 99, 99}, + {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, 99, 99, 99}}}, + + {{{-10,-10,-10,-10, -5, -5, -5, 0, 4, 10, 10, 12, 12, 12, 99, 99, 99}, + {-15,-15,-15,-15,-10,-10, -5, -5, -5, 0, 0, 0, 0, 0, 99, 99, 99}, + {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, 99, 99, 99}}}, + + {{{-15,-15,-15,-15,-15,-12,-10, -8, 0, 2, 4, 4, 5, 5, 99, 99, 99}, + {-30,-30,-30,-30,-26,-22,-20,-14,-12,-12,-10,-10,-10,-10, 99, 99, 99}, + {-30,-30,-30,-30,-26,-26,-26,-26,-26,-26,-26,-26,-26,-24, 99, 99, 99}}}, +}; + +static double _noise_thresh_11[3]={ .3,.5,.5 }; + diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/psych_16.h b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/psych_16.h new file mode 100644 index 0000000..2f34d11 --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/psych_16.h @@ -0,0 +1,129 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: 16kHz settings + last mod: $Id: psych_16.h 7187 2004-07-20 07:24:27Z xiphmont $ + + ********************************************************************/ + +/* stereo mode by base quality level */ +static adj_stereo _psy_stereo_modes_16[4]={ + /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 */ + {{ 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}, + { 6, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, + { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 4, 4}, + { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}}, + {{ 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}, + { 6, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, + { 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 4, 4, 4, 4, 4}, + { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}}, + {{ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}, + { 5, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}, + { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, + { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}}, + {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8}, + { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}}, +}; + +static double _psy_lowpass_16[4]={6.5,8,30.,99.}; + +static att3 _psy_tone_masteratt_16[4]={ + {{ 30, 25, 12}, 0, 0}, /* 0 */ + {{ 25, 22, 12}, 0, 0}, /* 0 */ + {{ 20, 12, 0}, 0, 0}, /* 0 */ + {{ 15, 0, -14}, 0, 0}, /* 0 */ +}; + +static vp_adjblock _vp_tonemask_adj_16[4]={ + /* adjust for mode zero */ + /* 63 125 250 500 1 2 4 8 16 */ + {{-20,-20,-20,-20,-20,-16,-10, 0, 0, 0, 0,10, 0, 0, 0, 0, 0}}, /* 0 */ + {{-20,-20,-20,-20,-20,-16,-10, 0, 0, 0, 0,10, 0, 0, 0, 0, 0}}, /* 1 */ + {{-20,-20,-20,-20,-20,-16,-10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 2 */ + {{-30,-30,-30,-30,-30,-26,-20,-10, -5, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 2 */ +}; + + +static noise3 _psy_noisebias_16_short[4]={ + /* 63 125 250 500 1k 2k 4k 8k 16k*/ + {{{-15,-15,-15,-15,-15,-10,-10,-5, 4, 10, 10, 10, 10, 12, 12, 14, 20}, + {-15,-15,-15,-15,-15,-10,-10, -5, 0, 0, 4, 5, 5, 6, 8, 8, 15}, + {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, -6, -6, -6}}}, + + {{{-15,-15,-15,-15,-15,-10,-10,-5, 4, 6, 6, 6, 6, 8, 10, 12, 20}, + {-15,-15,-15,-15,-15,-15,-15,-10, -5, -5, -5, 4, 5, 6, 8, 8, 15}, + {-30,-30,-30,-30,-30,-24,-20,-14,-10,-10,-10,-10,-10,-10,-10,-10,-10}}}, + + {{{-15,-15,-15,-15,-15,-12,-10, -8, 0, 2, 4, 4, 5, 5, 5, 8, 12}, + {-20,-20,-20,-20,-16,-12,-20,-14,-10,-10, -8, 0, 0, 0, 0, 2, 5}, + {-30,-30,-30,-30,-26,-26,-26,-26,-26,-26,-26,-26,-26,-24,-20,-20,-20}}}, + + {{{-15,-15,-15,-15,-15,-12,-10, -8, -5, -5, -5, -5, -5, 0, 0, 0, 6}, + {-30,-30,-30,-30,-26,-22,-20,-14,-12,-12,-10,-10,-10,-10,-10,-10, -6}, + {-30,-30,-30,-30,-26,-26,-26,-26,-26,-26,-26,-26,-26,-24,-20,-20,-20}}}, +}; + +static noise3 _psy_noisebias_16_impulse[4]={ + /* 63 125 250 500 1k 2k 4k 8k 16k*/ + {{{-15,-15,-15,-15,-15,-10,-10,-5, 4, 10, 10, 10, 10, 12, 12, 14, 20}, + {-15,-15,-15,-15,-15,-10,-10, -5, 0, 0, 4, 5, 5, 6, 8, 8, 15}, + {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, -6, -6, -6}}}, + + {{{-15,-15,-15,-15,-15,-10,-10,-5, 4, 4, 4, 4, 5, 5, 6, 8, 15}, + {-15,-15,-15,-15,-15,-15,-15,-10, -5, -5, -5, 0, 0, 0, 0, 4, 10}, + {-30,-30,-30,-30,-30,-24,-20,-14,-10,-10,-10,-10,-10,-10,-10,-10,-10}}}, + + {{{-15,-15,-15,-15,-15,-12,-10, -8, 0, 0, 0, 0, 0, 0, 0, 4, 10}, + {-20,-20,-20,-20,-16,-12,-20,-14,-10,-10,-10,-10,-10,-10,-10, -7, -5}, + {-30,-30,-30,-30,-26,-26,-26,-26,-26,-26,-26,-26,-26,-24,-20,-20,-20}}}, + + {{{-15,-15,-15,-15,-15,-12,-10, -8, -5, -5, -5, -5, -5, 0, 0, 0, 6}, + {-30,-30,-30,-30,-26,-22,-20,-18,-18,-18,-20,-20,-20,-20,-20,-20,-16}, + {-30,-30,-30,-30,-26,-26,-26,-26,-26,-26,-26,-26,-26,-24,-20,-20,-20}}}, +}; + +static noise3 _psy_noisebias_16[4]={ + /* 63 125 250 500 1k 2k 4k 8k 16k*/ + {{{-10,-10,-10,-10, -5, -5, -5, 0, 4, 6, 8, 8, 10, 10, 10, 14, 20}, + {-10,-10,-10,-10,-10, -5, -2, -2, 0, 0, 0, 4, 5, 6, 8, 8, 15}, + {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, -6, -6, -6}}}, + + {{{-10,-10,-10,-10, -5, -5, -5, 0, 4, 6, 6, 6, 6, 8, 10, 12, 20}, + {-15,-15,-15,-15,-15,-10, -5, -5, 0, 0, 0, 4, 5, 6, 8, 8, 15}, + {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, -6, -6, -6}}}, + + {{{-15,-15,-15,-15,-15,-12,-10, -8, 0, 2, 4, 4, 5, 5, 5, 8, 12}, + {-20,-20,-20,-20,-16,-12,-20,-10, -5, -5, 0, 0, 0, 0, 0, 2, 5}, + {-30,-30,-30,-30,-26,-26,-26,-26,-26,-26,-26,-26,-26,-24,-20,-20,-20}}}, + + {{{-15,-15,-15,-15,-15,-12,-10, -8, -5, -5, -5, -5, -5, 0, 0, 0, 6}, + {-30,-30,-30,-30,-26,-22,-20,-14,-12,-12,-10,-10,-10,-10,-10,-10, -6}, + {-30,-30,-30,-30,-26,-26,-26,-26,-26,-26,-26,-26,-26,-24,-20,-20,-20}}}, +}; + +static double _noise_thresh_16[4]={ .3,.5,.5,.5 }; + +static int _noise_start_16[3]={ 256,256,9999 }; +static int _noise_part_16[4]={ 8,8,8,8 }; + +static int _psy_ath_floater_16[4]={ + -100,-100,-100,-105, +}; + +static int _psy_ath_abs_16[4]={ + -130,-130,-130,-140, +}; + + + diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/psych_44.h b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/psych_44.h new file mode 100644 index 0000000..0e5659b --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/psych_44.h @@ -0,0 +1,666 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: key psychoacoustic settings for 44.1/48kHz + last mod: $Id: psych_44.h 7187 2004-07-20 07:24:27Z xiphmont $ + + ********************************************************************/ + + +/* preecho trigger settings *****************************************/ + +static vorbis_info_psy_global _psy_global_44[5]={ + + {8, /* lines per eighth octave */ + {20.f,14.f,12.f,12.f,12.f,12.f,12.f}, + {-60.f,-30.f,-40.f,-40.f,-40.f,-40.f,-40.f}, 2,-75.f, + -6.f, + {99.},{{99.},{99.}},{0},{0},{{0.},{0.}} + }, + {8, /* lines per eighth octave */ + {14.f,10.f,10.f,10.f,10.f,10.f,10.f}, + {-40.f,-30.f,-25.f,-25.f,-25.f,-25.f,-25.f}, 2,-80.f, + -6.f, + {99.},{{99.},{99.}},{0},{0},{{0.},{0.}} + }, + {8, /* lines per eighth octave */ + {12.f,10.f,10.f,10.f,10.f,10.f,10.f}, + {-20.f,-20.f,-15.f,-15.f,-15.f,-15.f,-15.f}, 0,-80.f, + -6.f, + {99.},{{99.},{99.}},{0},{0},{{0.},{0.}} + }, + {8, /* lines per eighth octave */ + {10.f,8.f,8.f,8.f,8.f,8.f,8.f}, + {-20.f,-15.f,-12.f,-12.f,-12.f,-12.f,-12.f}, 0,-80.f, + -6.f, + {99.},{{99.},{99.}},{0},{0},{{0.},{0.}} + }, + {8, /* lines per eighth octave */ + {10.f,6.f,6.f,6.f,6.f,6.f,6.f}, + {-15.f,-15.f,-12.f,-12.f,-12.f,-12.f,-12.f}, 0,-85.f, + -6.f, + {99.},{{99.},{99.}},{0},{0},{{0.},{0.}} + }, +}; + +/* noise compander lookups * low, mid, high quality ****************/ +static compandblock _psy_compand_44[6]={ + /* sub-mode Z short */ + {{ + 0, 1, 2, 3, 4, 5, 6, 7, /* 7dB */ + 8, 9,10,11,12,13,14, 15, /* 15dB */ + 16,17,18,19,20,21,22, 23, /* 23dB */ + 24,25,26,27,28,29,30, 31, /* 31dB */ + 32,33,34,35,36,37,38, 39, /* 39dB */ + }}, + /* mode_Z nominal short */ + {{ + 0, 1, 2, 3, 4, 5, 6, 6, /* 7dB */ + 7, 7, 7, 7, 6, 6, 6, 7, /* 15dB */ + 7, 8, 9,10,11,12,13, 14, /* 23dB */ + 15,16,17,17,17,18,18, 19, /* 31dB */ + 19,19,20,21,22,23,24, 25, /* 39dB */ + }}, + /* mode A short */ + {{ + 0, 1, 2, 3, 4, 5, 5, 5, /* 7dB */ + 6, 6, 6, 5, 4, 4, 4, 4, /* 15dB */ + 4, 4, 5, 5, 5, 6, 6, 6, /* 23dB */ + 7, 7, 7, 8, 8, 8, 9, 10, /* 31dB */ + 11,12,13,14,15,16,17, 18, /* 39dB */ + }}, + /* sub-mode Z long */ + {{ + 0, 1, 2, 3, 4, 5, 6, 7, /* 7dB */ + 8, 9,10,11,12,13,14, 15, /* 15dB */ + 16,17,18,19,20,21,22, 23, /* 23dB */ + 24,25,26,27,28,29,30, 31, /* 31dB */ + 32,33,34,35,36,37,38, 39, /* 39dB */ + }}, + /* mode_Z nominal long */ + {{ + 0, 1, 2, 3, 4, 5, 6, 7, /* 7dB */ + 8, 9,10,11,12,12,13, 13, /* 15dB */ + 13,14,14,14,15,15,15, 15, /* 23dB */ + 16,16,17,17,17,18,18, 19, /* 31dB */ + 19,19,20,21,22,23,24, 25, /* 39dB */ + }}, + /* mode A long */ + {{ + 0, 1, 2, 3, 4, 5, 6, 7, /* 7dB */ + 8, 8, 7, 6, 5, 4, 4, 4, /* 15dB */ + 4, 4, 5, 5, 5, 6, 6, 6, /* 23dB */ + 7, 7, 7, 8, 8, 8, 9, 10, /* 31dB */ + 11,12,13,14,15,16,17, 18, /* 39dB */ + }} +}; + +/* tonal masking curve level adjustments *************************/ + +static vp_adjblock _vp_tonemask_adj_longblock[12]={ + + /* 63 125 250 500 1 2 4 8 16 */ + + {{ -3, -8,-13,-15,-10,-10,-10,-10,-10,-10,-10, 0, 0, 0, 0, 0, 0}}, /* -1 */ + +/* {{-15,-15,-15,-15,-10, -8, -4, -2, 0, 0, 0, 10, 0, 0, 0, 0, 0}}, 0 */ + {{ -4,-10,-14,-16,-15,-14,-13,-12,-12,-12,-11, -1, -1, -1, -1, -1, 0}}, /* 0 */ + +/* {{-15,-15,-15,-15,-15,-12,-10, -8, 0, 0, 0, 5, 0, 0, 0, 0, 0}}, 1 */ + {{ -6,-12,-14,-16,-15,-15,-14,-13,-13,-12,-12, -2, -2, -1, -1, -1, 0}}, /* 1 */ + +/* {{-15,-15,-15,-15,-15,-12,-10, -8, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, 2 */ + {{-12,-13,-14,-16,-16,-16,-15,-14,-13,-12,-12, -6, -3, -1, -1, -1, 0}}, /* 2 */ + +/* {{-15,-15,-15,-15,-15,-12,-10, -8, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, 3 */ + {{-15,-15,-15,-16,-16,-16,-16,-14,-13,-13,-13,-10, -4, -2, -1, -1, 0}}, /* 3 */ + +/* {{-15,-15,-15,-15,-15,-12,-10, -8, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, *//* 4 */ + {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-13,-11, -7 -3, -1, -1 , 0}}, /* 4 */ + +/* {{-15,-15,-15,-15,-15,-12,-10, -8, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, 5 */ + {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-13,-11, -7 -3, -1, -1 , 0}}, /* 5 */ + +/* {{-15,-15,-15,-15,-15,-12,-10, -8, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, 6 */ + {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-14,-12, -8, -4, -2, -2, 0}}, /* 6 */ + +/* {{-15,-15,-15,-15,-15,-12,-10, -8, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, 7 */ + {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-14,-12, -9, -4, -2, -2, 0}}, /* 7 */ + +/* {{-15,-15,-15,-15,-15,-12,-10, -8, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, 8 */ + {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-14,-12, -9, -4, -2, -2, 0}}, /* 8 */ + +/* {{-15,-15,-15,-15,-15,-12,-10, -8, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, 9 */ + {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-14,-12, -9, -4, -2, -2, 0}}, /* 9 */ + +/* {{-15,-15,-15,-15,-15,-12,-10, -8, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, 10 */ + {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-14,-12, -9, -4, -2, -2, 0}}, /* 10 */ +}; + +static vp_adjblock _vp_tonemask_adj_otherblock[12]={ + /* 63 125 250 500 1 2 4 8 16 */ + + {{ -3, -8,-13,-15,-10,-10, -9, -9, -9, -9, -9, 1, 1, 1, 1, 1, 1}}, /* -1 */ + +/* {{-20,-20,-20,-20,-14,-12,-10, -8, -4, 0, 0, 10, 0, 0, 0, 0, 0}}, 0 */ + {{ -4,-10,-14,-16,-14,-13,-12,-12,-11,-11,-10, 0, 0, 0, 0, 0, 0}}, /* 0 */ + +/* {{-20,-20,-20,-20,-20,-18,-16,-14,-10, 0, 0, 5, 0, 0, 0, 0, 0}}, 1 */ + {{ -6,-12,-14,-16,-15,-15,-14,-13,-13,-12,-12, -2, -2, -1, 0, 0, 0}}, /* 1 */ + +/* {{-20,-20,-20,-20,-20,-18,-16,-14,-10, 0, 0, 0, 0, 0, 0, 0, 0}}, 2 */ + {{-12,-13,-14,-16,-16,-16,-15,-14,-13,-12,-12, -5, -2, -1, 0, 0, 0}}, /* 2 */ + +/* {{-20,-20,-20,-20,-20,-18,-16,-14,-10, 0, 0, 0, 0, 0, 0, 0, 0}}, 3 */ + {{-15,-15,-15,-16,-16,-16,-16,-14,-13,-13,-13,-10, -4, -2, 0, 0, 0}}, /* 3 */ + +/* {{-20,-20,-20,-20,-20,-18,-16,-14,-10, 0, 0, 0, 0, 0, 0, 0, 0}}, 4 */ + {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-13,-11, -7 -3, -1, -1 , 0}}, /* 4 */ + +/* {{-20,-20,-20,-20,-20,-18,-16,-14,-10, 0, 0, 0, 0, 0, 0, 0, 0}}, 5 */ + {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-13,-11, -7 -3, -1, -1 , 0}}, /* 5 */ + +/* {{-20,-20,-20,-20,-20,-18,-16,-14,-10, 0, 0, 0, 0, 0, 0, 0, 0}}, 6 */ + {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-14,-12, -8, -4, -2, -2, 0}}, /* 6 */ + +/* {{-20,-20,-20,-20,-20,-18,-16,-14,-10, 0, 0, 0, 0, 0, 0, 0, 0}}, 7 */ + {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-14,-12, -9, -4, -2, -2, 0}}, /* 7 */ + +/* {{-20,-20,-20,-20,-20,-18,-16,-14,-10, 0, 0, 0, 0, 0, 0, 0, 0}}, 8 */ + {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-14,-12, -9, -4, -2, -2, 0}}, /* 8 */ + +/* {{-20,-20,-20,-20,-20,-18,-16,-14,-10, 0, 0, 0, 0, 0, 0, 0, 0}}, 9 */ + {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-14,-12, -9, -4, -2, -2, 0}}, /* 9 */ + +/* {{-20,-20,-20,-20,-20,-18,-16,-14,-10, 0, 0, 0, 0, 0, 0, 0, 0}}, 10 */ + {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-14,-12, -9, -4, -2, -2, 0}}, /* 10 */ +}; + +/* noise bias (transition block) */ +static noise3 _psy_noisebias_trans[12]={ + /* 63 125 250 500 1k 2k 4k 8k 16k*/ + /* -1 */ + {{{-10,-10,-10,-10,-10, -4, 0, 0, 4, 8, 8, 8, 8, 10, 12, 14, 20}, + {-30,-30,-30,-30,-26,-20,-16, -8, -6, -6, -2, 2, 2, 3, 6, 6, 15}, + {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, -6, -4, -2}}}, + /* 0 + {{{-15,-15,-15,-15,-15,-12,-10, -8, 0, 2, 4, 4, 5, 5, 5, 8, 10}, + {-30,-30,-30,-30,-26,-22,-20,-14, -8, -4, 0, 0, 0, 0, 2, 4, 10}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10, -6, -6, -6, -6, -4, -4, -4, -2}}},*/ + {{{-15,-15,-15,-15,-15,-12, -6, -4, 0, 2, 4, 4, 5, 5, 5, 8, 10}, + {-30,-30,-30,-30,-26,-22,-20,-14, -8, -4, 0, 0, 0, 0, 2, 3, 6}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10, -6, -6, -6, -6, -4, -4, -4, -2}}}, + /* 1 + {{{-15,-15,-15,-15,-15,-12,-10, -8, 0, 2, 4, 4, 5, 5, 5, 8, 10}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, -2, -2, -2, -2, 0, 2, 8}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10, -8, -8, -8, -8, -6, -6, -6, -4}}},*/ + {{{-15,-15,-15,-15,-15,-12,-10, -8, 0, 2, 4, 4, 5, 5, 5, 8, 10}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, -2, -2, -2, -2, 0, 1, 4}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10, -8, -8, -8, -8, -6, -6, -6, -4}}}, + /* 2 + {{{-15,-15,-15,-15,-15,-12,-10, -8, 0, 2, 2, 2, 4, 4, 5, 6, 10}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, -2, -2, -2, -2, 0, 2, 6}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10,-10,-10,-10,-10, -8, -8, -8, -4}}}, */ + {{{-15,-15,-15,-15,-15,-12,-10, -8, 0, 2, 2, 2, 4, 4, 5, 6, 10}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, -3, -3, -3, -2, -1, 0, 3}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10,-10,-10,-10,-10, -8, -8, -7, -4}}}, + /* 3 + {{{-15,-15,-15,-15,-15,-12,-10, -8, 0, 2, 2, 2, 4, 4, 4, 5, 8}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, -3, -3, -3, -3, -1, 1, 6}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10,-10,-10,-10,-10, -8, -8, -8, -4}}},*/ + {{{-15,-15,-15,-15,-15,-12,-10, -8, 0, 2, 2, 2, 4, 4, 4, 5, 8}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, -3, -3, -3, -3, -2, 0, 2}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10,-10,-10,-10,-10, -8, -8, -8, -4}}}, + /* 4 + {{{-20,-20,-20,-20,-20,-18,-14, -8, -1, 1, 1, 1, 2, 3, 3, 4, 7}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, -3, -3, -3, -3, -1, 1, 5}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10,-10,-10,-10,-10, -8, -8, -8, -4}}},*/ + {{{-20,-20,-20,-20,-20,-18,-14, -8, -1, 1, 1, 1, 2, 3, 3, 4, 7}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, -3, -3, -3, -3, -2, -1, 1}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10,-10,-10,-10,-10, -8, -8, -8, -4}}}, + /* 5 + {{{-24,-24,-24,-24,-20,-18,-14, -8, -1, 1, 1, 1, 2, 3, 3, 4, 7}, + {-32,-32,-32,-32,-28,-24,-22,-16,-12, -6, -4, -4, -4, -4, -2, -1, 2}, + {-34,-34,-34,-34,-30,-24,-24,-18,-14,-12,-12,-12,-12,-10,-10, -9, -5}}}, */ + {{{-24,-24,-24,-24,-20,-18,-14, -8, -1, 1, 1, 1, 2, 3, 3, 4, 7}, + {-32,-32,-32,-32,-28,-24,-22,-16,-12, -6, -4, -4, -4, -4, -3, -1, 0}, + {-34,-34,-34,-34,-30,-24,-24,-18,-14,-12,-12,-12,-12,-10,-10, -9, -5}}}, + /* 6 + {{{-24,-24,-24,-24,-20,-18,-14, -8, -1, 1, 1, 1, 2, 3, 3, 4, 7}, + {-32,-32,-32,-32,-28,-24,-24,-18,-14, -8, -6, -6, -6, -6, -4, -2, 1}, + {-34,-34,-34,-34,-30,-26,-24,-18,-17,-15,-15,-15,-15,-13,-13,-12, -8}}},*/ + {{{-24,-24,-24,-24,-20,-18,-14, -8, -1, 1, 1, 1, 2, 3, 3, 4, 7}, + {-32,-32,-32,-32,-28,-24,-24,-18,-14, -8, -6, -6, -6, -6, -5, -2, 0}, + {-34,-34,-34,-34,-30,-26,-26,-24,-22,-19,-19,-19,-19,-18,-17,-16,-12}}}, + /* 7 + {{{-24,-24,-24,-24,-20,-18,-14, -8, -1, 1, 1, 1, 2, 3, 3, 4, 7}, + {-32,-32,-32,-32,-28,-24,-24,-18,-14,-12,-10, -8, -8, -8, -6, -4, 0}, + {-34,-34,-34,-34,-30,-26,-26,-24,-22,-19,-19,-19,-19,-18,-17,-16,-12}}},*/ + {{{-24,-24,-24,-24,-20,-18,-14, -8, -1, 1, 1, 1, 2, 3, 3, 4, 7}, + {-32,-32,-32,-32,-28,-24,-24,-24,-18,-14,-12,-10,-10,-10, -8, -6, -2}, + {-34,-34,-34,-34,-30,-26,-26,-26,-24,-24,-24,-24,-24,-24,-24,-20,-16}}}, + /* 8 + {{{-24,-24,-24,-24,-22,-20,-15,-10, -8, -2, 0, 0, 0, 1, 2, 3, 7}, + {-36,-36,-36,-36,-30,-30,-30,-24,-18,-14,-12,-10,-10,-10, -8, -6, -2}, + {-36,-36,-36,-36,-34,-30,-28,-26,-24,-24,-24,-24,-24,-24,-24,-20,-16}}},*/ + {{{-24,-24,-24,-24,-22,-20,-15,-10, -8, -2, 0, 0, 0, 1, 2, 3, 7}, + {-36,-36,-36,-36,-30,-30,-30,-24,-20,-16,-16,-16,-16,-14,-12,-10, -7}, + {-36,-36,-36,-36,-34,-30,-28,-26,-24,-30,-30,-30,-30,-30,-30,-24,-20}}}, + /* 9 + {{{-28,-28,-28,-28,-28,-28,-28,-20,-14, -8, -4, -4, -4, -4, -4, -2, 2}, + {-36,-36,-36,-36,-34,-32,-32,-28,-20,-16,-16,-16,-16,-14,-12,-10, -7}, + {-40,-40,-40,-40,-40,-40,-40,-32,-30,-30,-30,-30,-30,-30,-30,-24,-20}}},*/ + {{{-28,-28,-28,-28,-28,-28,-28,-20,-14, -8, -4, -4, -4, -4, -4, -2, 2}, + {-38,-38,-38,-38,-36,-34,-34,-30,-24,-20,-20,-20,-20,-18,-16,-12,-10}, + {-40,-40,-40,-40,-40,-40,-40,-38,-35,-35,-35,-35,-35,-35,-35,-35,-30}}}, + /* 10 */ + {{{-30,-30,-30,-30,-30,-30,-30,-28,-20,-14,-14,-14,-14,-14,-14,-12,-10}, + {-40,-40,-40,-40,-40,-40,-40,-40,-35,-30,-30,-30,-30,-30,-30,-30,-20}, + {-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40}}}, +}; + +/* noise bias (long block) */ +static noise3 _psy_noisebias_long[12]={ + /*63 125 250 500 1k 2k 4k 8k 16k*/ + /* -1 */ + {{{-10,-10,-10,-10,-10, -4, 0, 0, 0, 6, 6, 6, 6, 10, 10, 12, 20}, + {-20,-20,-20,-20,-20,-20,-10, -2, 0, 0, 0, 0, 0, 2, 4, 6, 15}, + {-20,-20,-20,-20,-20,-20,-20,-10, -6, -6, -6, -6, -6, -4, -4, -4, -2}}}, + + /* 0 */ + /* {{{-10,-10,-10,-10,-10,-10, -8, 2, 2, 2, 4, 4, 5, 5, 5, 8, 10}, + {-20,-20,-20,-20,-20,-20,-20,-14, -6, 0, 0, 0, 0, 0, 2, 4, 10}, + {-20,-20,-20,-20,-20,-20,-20,-14, -8, -6, -6, -6, -6, -4, -4, -4, -2}}},*/ + {{{-10,-10,-10,-10,-10,-10, -8, 2, 2, 2, 4, 4, 5, 5, 5, 8, 10}, + {-20,-20,-20,-20,-20,-20,-20,-14, -6, 0, 0, 0, 0, 0, 2, 3, 6}, + {-20,-20,-20,-20,-20,-20,-20,-14, -8, -6, -6, -6, -6, -4, -4, -4, -2}}}, + /* 1 */ + /* {{{-10,-10,-10,-10,-10,-10, -8, -4, 0, 2, 4, 4, 5, 5, 5, 8, 10}, + {-20,-20,-20,-20,-20,-20,-20,-14,-10, -4, -2, -2, -2, -2, 0, 2, 8}, + {-20,-20,-20,-20,-20,-20,-20,-14,-10, -8, -8, -8, -8, -6, -6, -6, -4}}},*/ + {{{-10,-10,-10,-10,-10,-10, -8, -4, 0, 2, 4, 4, 5, 5, 5, 8, 10}, + {-20,-20,-20,-20,-20,-20,-20,-14,-10, -4, -2, -2, -2, -2, 0, 1, 4}, + {-20,-20,-20,-20,-20,-20,-20,-14,-10, -8, -8, -8, -8, -6, -6, -6, -4}}}, + /* 2 */ + /* {{{-10,-10,-10,-10,-10,-10,-10, -8, 0, 2, 2, 2, 4, 4, 5, 6, 10}, + {-20,-20,-20,-20,-20,-20,-20,-14,-10, -4, -2, -2, -2, -2, 0, 2, 6}, + {-20,-20,-20,-20,-20,-20,-20,-14,-10,-10,-10,-10,-10, -8, -8, -8, -4}}},*/ + {{{-10,-10,-10,-10,-10,-10,-10, -8, 0, 2, 2, 2, 4, 4, 5, 6, 10}, + {-20,-20,-20,-20,-20,-20,-20,-14,-10, -4, -3, -3, -3, -2, -1, 0, 3}, + {-20,-20,-20,-20,-20,-20,-20,-14,-10,-10,-10,-10,-10, -8, -8, -8, -4}}}, + /* 3 */ + /* {{{-10,-10,-10,-10,-10,-10,-10, -8, 0, 2, 2, 2, 4, 4, 4, 5, 8}, + {-20,-20,-20,-20,-20,-20,-20,-14,-10, -4, -3, -3, -3, -3, -1, 1, 6}, + {-20,-20,-20,-20,-20,-20,-20,-14,-10,-10,-10,-10,-10, -8, -8, -8, -4}}},*/ + {{{-10,-10,-10,-10,-10,-10,-10, -8, 0, 2, 2, 2, 4, 4, 4, 5, 8}, + {-20,-20,-20,-20,-20,-20,-20,-14,-10, -4, -3, -3, -3, -3, -2, 0, 2}, + {-20,-20,-20,-20,-20,-20,-20,-14,-10,-10,-10,-10,-10, -8, -8, -8, -5}}}, + /* 4 */ + /* {{{-15,-15,-15,-15,-15,-15,-15,-10, -4, 1, 1, 1, 2, 3, 3, 4, 7}, + {-20,-20,-20,-20,-20,-20,-20,-14,-10, -4, -3, -3, -3, -3, -1, 1, 5}, + {-20,-20,-20,-20,-20,-20,-20,-14,-10,-10,-10,-10,-10, -8, -8, -8, -4}}},*/ + {{{-15,-15,-15,-15,-15,-15,-15,-10, -4, 1, 1, 1, 2, 3, 3, 4, 7}, + {-20,-20,-20,-20,-20,-20,-20,-14,-10, -4, -3, -3, -3, -3, -2, -1, 1}, + {-20,-20,-20,-20,-20,-20,-20,-14,-10,-10,-10,-10,-10, -8, -8, -8, -7}}}, + /* 5 */ + /* {{{-15,-15,-15,-15,-15,-15,-15,-10, -4, 1, 1, 1, 2, 3, 3, 4, 7}, + {-22,-22,-22,-22,-22,-22,-22,-16,-12, -6, -4, -4, -4, -4, -2, -1, 2}, + {-24,-24,-24,-24,-24,-24,-24,-18,-14,-12,-12,-12,-12,-10,-10, -9, -5}}},*/ + {{{-15,-15,-15,-15,-15,-15,-15,-10, -4, 1, 1, 1, 2, 3, 3, 4, 7}, + {-22,-22,-22,-22,-22,-22,-22,-16,-12, -6, -4, -4, -4, -4, -3, -1, 0}, + {-24,-24,-24,-24,-24,-24,-24,-18,-14,-12,-12,-12,-12,-10,-10, -9, -8}}}, + /* 6 */ + /* {{{-15,-15,-15,-15,-15,-15,-15,-10, -4, 1, 1, 1, 2, 3, 3, 4, 7}, + {-24,-24,-24,-24,-24,-24,-24,-18,-14, -8, -6, -6, -6, -6, -4, -2, 1}, + {-26,-26,-26,-26,-26,-26,-26,-18,-16,-15,-15,-15,-15,-13,-13,-12, -8}}},*/ + {{{-15,-15,-15,-15,-15,-15,-15,-10, -4, 1, 1, 1, 2, 3, 3, 4, 7}, + {-24,-24,-24,-24,-24,-24,-24,-18,-14, -8, -6, -6, -6, -6, -5, -2, 0}, + {-26,-26,-26,-26,-26,-26,-26,-18,-16,-15,-15,-15,-15,-13,-13,-12,-10}}}, + /* 7 */ + {{{-15,-15,-15,-15,-15,-15,-15,-10, -4, 1, 1, 1, 2, 3, 3, 4, 7}, + {-24,-24,-24,-24,-24,-24,-24,-18,-14,-10, -8, -8, -8, -8, -6, -4, 0}, + {-26,-26,-26,-26,-26,-26,-26,-22,-20,-19,-19,-19,-19,-18,-17,-16,-12}}}, + /* 8 */ + {{{-15,-15,-15,-15,-15,-15,-15,-10, -4, 0, 0, 0, 0, 1, 2, 3, 7}, + {-26,-26,-26,-26,-26,-26,-26,-20,-16,-12,-10,-10,-10,-10, -8, -6, -2}, + {-28,-28,-28,-28,-28,-28,-28,-26,-24,-24,-24,-24,-24,-24,-24,-20,-16}}}, + /* 9 */ + {{{-22,-22,-22,-22,-22,-22,-22,-18,-14, -8, -4, -4, -4, -4, -4, -2, 2}, + {-26,-26,-26,-26,-26,-26,-26,-22,-18,-16,-16,-16,-16,-14,-12,-10, -7}, + {-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-24,-20}}}, + /* 10 */ + {{{-24,-24,-24,-24,-24,-24,-24,-24,-24,-18,-14,-14,-14,-14,-14,-12,-10}, + {-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-20}, + {-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40}}}, +}; + +/* noise bias (impulse block) */ +static noise3 _psy_noisebias_impulse[12]={ + /* 63 125 250 500 1k 2k 4k 8k 16k*/ + /* -1 */ + {{{-10,-10,-10,-10,-10, -4, 0, 0, 4, 8, 8, 8, 8, 10, 12, 14, 20}, + {-30,-30,-30,-30,-26,-20,-16, -8, -6, -6, -2, 2, 2, 3, 6, 6, 15}, + {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, -6, -4, -2}}}, + + /* 0 */ + /* {{{-10,-10,-10,-10,-10, -4, 0, 0, 4, 4, 8, 8, 8, 10, 12, 14, 20}, + {-30,-30,-30,-30,-26,-22,-20,-14, -6, -2, 0, 0, 0, 0, 2, 4, 10}, + {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, -6, -4, -2}}},*/ + {{{-10,-10,-10,-10,-10, -4, 0, 0, 4, 4, 8, 8, 8, 10, 12, 14, 20}, + {-30,-30,-30,-30,-26,-22,-20,-14, -6, -2, 0, 0, 0, 0, 2, 3, 6}, + {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, -6, -4, -2}}}, + /* 1 */ + {{{-12,-12,-12,-12,-12, -8, -6, -4, 0, 4, 4, 4, 4, 10, 12, 14, 20}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10, -6, -4, -4, -2, -2, -2, -2, 2}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10, -8,-10,-10, -8, -8, -8, -6, -4}}}, + /* 2 */ + {{{-14,-14,-14,-14,-14,-10, -8, -6, -2, 2, 2, 2, 2, 8, 10, 10, 16}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10, -6, -6, -6, -4, -4, -4, -2, 0}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10,-10,-10,-10,-10,-10,-10, -8, -4}}}, + /* 3 */ + {{{-14,-14,-14,-14,-14,-10, -8, -6, -2, 2, 2, 2, 2, 6, 8, 8, 14}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10, -6, -6, -6, -4, -4, -4, -2, 0}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10,-10,-10,-10,-10,-10,-10, -8, -4}}}, + /* 4 */ + {{{-16,-16,-16,-16,-16,-12,-10, -6, -2, 0, 0, 0, 0, 4, 6, 6, 12}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10, -6, -6, -6, -4, -4, -4, -2, 0}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10,-10,-10,-10,-10,-10,-10, -8, -4}}}, + /* 5 */ + {{{-20,-20,-20,-20,-20,-18,-14,-10, -4, 0, 0, 0, 0, 4, 4, 6, 11}, + {-32,-32,-32,-32,-28,-24,-22,-16,-10, -6, -8, -8, -6, -6, -6, -4, -2}, + {-34,-34,-34,-34,-30,-26,-24,-18,-14,-12,-12,-12,-12,-12,-10, -9, -5}}}, + /* 6 + {{{-20,-20,-20,-20,-20,-18,-14,-10, -4, 0, 0, 0, 0, 4, 4, 6, 11}, + {-34,-34,-34,-34,-30,-30,-24,-20,-12,-12,-14,-14,-10, -9, -8, -6, -4}, + {-34,-34,-34,-34,-34,-30,-26,-20,-16,-15,-15,-15,-15,-15,-13,-12, -8}}},*/ + {{{-20,-20,-20,-20,-20,-18,-14,-10, -4, 0, 0, 0, 0, 4, 4, 6, 11}, + {-34,-34,-34,-34,-30,-30,-30,-24,-16,-16,-16,-16,-16,-16,-14,-14,-12}, + {-36,-36,-36,-36,-36,-34,-28,-24,-20,-20,-20,-20,-20,-20,-20,-18,-16}}}, + /* 7 */ + /* {{{-22,-22,-22,-22,-22,-20,-14,-10, -6, 0, 0, 0, 0, 4, 4, 6, 11}, + {-34,-34,-34,-34,-30,-30,-24,-20,-14,-14,-16,-16,-14,-12,-10,-10,-10}, + {-34,-34,-34,-34,-32,-32,-30,-24,-20,-19,-19,-19,-19,-19,-17,-16,-12}}},*/ + {{{-22,-22,-22,-22,-22,-20,-14,-10, -6, 0, 0, 0, 0, 4, 4, 6, 11}, + {-34,-34,-34,-34,-30,-30,-30,-30,-26,-26,-26,-26,-26,-26,-26,-24,-22}, + {-40,-40,-40,-40,-40,-40,-40,-32,-30,-30,-30,-30,-30,-30,-30,-30,-24}}}, + /* 8 */ + /* {{{-24,-24,-24,-24,-24,-22,-14,-10, -6, -1, -1, -1, -1, 3, 3, 5, 10}, + {-34,-34,-34,-34,-30,-30,-30,-24,-20,-20,-20,-20,-20,-18,-16,-16,-14}, + {-36,-36,-36,-36,-36,-34,-28,-24,-24,-24,-24,-24,-24,-24,-24,-20,-16}}},*/ + {{{-24,-24,-24,-24,-24,-22,-14,-10, -6, -1, -1, -1, -1, 3, 3, 5, 10}, + {-34,-34,-34,-34,-34,-32,-32,-30,-26,-26,-26,-26,-26,-26,-26,-26,-24}, + {-40,-40,-40,-40,-40,-40,-40,-32,-30,-30,-30,-30,-30,-30,-30,-30,-24}}}, + /* 9 */ + /* {{{-28,-28,-28,-28,-28,-28,-28,-20,-14, -8, -4, -4, -4, -4, -4, -2, 2}, + {-36,-36,-36,-36,-34,-32,-32,-30,-26,-26,-26,-26,-26,-22,-20,-20,-18}, + {-40,-40,-40,-40,-40,-40,-40,-32,-30,-30,-30,-30,-30,-30,-30,-24,-20}}},*/ + {{{-28,-28,-28,-28,-28,-28,-28,-20,-14, -8, -4, -4, -4, -4, -4, -2, 2}, + {-36,-36,-36,-36,-34,-32,-32,-30,-26,-26,-26,-26,-26,-26,-26,-26,-26}, + {-40,-40,-40,-40,-40,-40,-40,-32,-30,-30,-30,-30,-30,-30,-30,-24,-20}}}, + /* 10 */ + {{{-30,-30,-30,-30,-30,-26,-24,-24,-24,-20,-16,-16,-16,-16,-16,-14,-12}, + {-40,-40,-40,-40,-40,-40,-40,-40,-35,-30,-30,-30,-30,-30,-30,-30,-26}, + {-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40}}}, +}; + +/* noise bias (padding block) */ +static noise3 _psy_noisebias_padding[12]={ + /* 63 125 250 500 1k 2k 4k 8k 16k*/ + + /* -1 */ + {{{-10,-10,-10,-10,-10, -4, 0, 0, 4, 8, 8, 8, 8, 10, 12, 14, 20}, + {-30,-30,-30,-30,-26,-20,-16, -8, -6, -6, -2, 2, 2, 3, 6, 6, 15}, + {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, -6, -4, -2}}}, + + /* 0 */ + {{{-10,-10,-10,-10,-10, -4, 0, 0, 4, 8, 8, 8, 8, 10, 12, 14, 20}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, -2, 2, 3, 6, 6, 8, 10}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, -4, -4, -4, -4, -2, 0, 2}}}, + /* 1 */ + {{{-12,-12,-12,-12,-12, -8, -6, -4, 0, 4, 4, 4, 4, 10, 12, 14, 20}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, 0, 0, 0, 2, 2, 4, 8}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10, -6, -6, -6, -6, -6, -4, -2, 0}}}, + /* 2 */ + /* {{{-14,-14,-14,-14,-14,-10, -8, -6, -2, 2, 2, 2, 2, 8, 10, 10, 16}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, 0, 0, 0, 2, 2, 4, 8}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10, -8, -8, -8, -8, -8, -6, -4, -2}}},*/ + {{{-14,-14,-14,-14,-14,-10, -8, -6, -2, 2, 2, 2, 2, 8, 10, 10, 16}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10, -6, -1, -1, -1, 0, 0, 2, 6}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10, -8, -8, -8, -8, -8, -6, -4, -2}}}, + /* 3 */ + {{{-14,-14,-14,-14,-14,-10, -8, -6, -2, 2, 2, 2, 2, 6, 8, 8, 14}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10, -6, -1, -1, -1, 0, 0, 2, 6}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10, -8, -8, -8, -8, -8, -6, -4, -2}}}, + /* 4 */ + {{{-16,-16,-16,-16,-16,-12,-10, -6, -2, 0, 0, 0, 0, 4, 6, 6, 12}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10, -6, -1, -1, -1, -1, 0, 2, 6}, + {-30,-30,-30,-30,-26,-22,-20,-14,-10, -8, -8, -8, -8, -8, -6, -4, -2}}}, + /* 5 */ + {{{-20,-20,-20,-20,-20,-18,-14,-10, -4, 0, 0, 0, 0, 4, 6, 6, 12}, + {-32,-32,-32,-32,-28,-24,-22,-16,-12, -6, -3, -3, -3, -3, -2, 0, 4}, + {-34,-34,-34,-34,-30,-26,-24,-18,-14,-10,-10,-10,-10,-10, -8, -5, -3}}}, + /* 6 */ + {{{-20,-20,-20,-20,-20,-18,-14,-10, -4, 0, 0, 0, 0, 4, 6, 6, 12}, + {-34,-34,-34,-34,-30,-30,-24,-20,-14, -8, -4, -4, -4, -4, -3, -1, 4}, + {-34,-34,-34,-34,-34,-30,-26,-20,-16,-13,-13,-13,-13,-13,-11, -8, -6}}}, + /* 7 */ + {{{-20,-20,-20,-20,-20,-18,-14,-10, -4, 0, 0, 0, 0, 4, 6, 6, 12}, + {-34,-34,-34,-34,-30,-30,-30,-24,-16,-10, -8, -6, -6, -6, -5, -3, 1}, + {-34,-34,-34,-34,-32,-32,-28,-22,-18,-16,-16,-16,-16,-16,-14,-12,-10}}}, + /* 8 */ + {{{-22,-22,-22,-22,-22,-20,-14,-10, -4, 0, 0, 0, 0, 3, 5, 5, 11}, + {-34,-34,-34,-34,-30,-30,-30,-24,-16,-12,-10, -8, -8, -8, -7, -5, -2}, + {-36,-36,-36,-36,-36,-34,-28,-22,-20,-20,-20,-20,-20,-20,-20,-16,-14}}}, + /* 9 */ + {{{-28,-28,-28,-28,-28,-28,-28,-20,-14, -8, -2, -2, -2, -2, 0, 2, 6}, + {-36,-36,-36,-36,-34,-32,-32,-24,-16,-12,-12,-12,-12,-12,-10, -8, -5}, + {-40,-40,-40,-40,-40,-40,-40,-32,-26,-24,-24,-24,-24,-24,-24,-20,-18}}}, + /* 10 */ + {{{-30,-30,-30,-30,-30,-26,-24,-24,-24,-20,-12,-12,-12,-12,-12,-10, -8}, + {-40,-40,-40,-40,-40,-40,-40,-40,-35,-30,-25,-25,-25,-25,-25,-25,-15}, + {-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40}}}, +}; + + +static noiseguard _psy_noiseguards_44[4]={ + {3,3,15}, + {3,3,15}, + {10,10,100}, + {10,10,100}, +}; + +static int _psy_tone_suppress[12]={ + -20,-20,-20,-20,-20,-24,-30,-40,-40,-45,-45,-45, +}; +static int _psy_tone_0dB[12]={ + 90,90,95,95,95,95,105,105,105,105,105,105, +}; +static int _psy_noise_suppress[12]={ + -20,-20,-24,-24,-24,-24,-30,-40,-40,-45,-45,-45, +}; + +static vorbis_info_psy _psy_info_template={ + /* blockflag */ + -1, + /* ath_adjatt, ath_maxatt */ + -140.,-140., + /* tonemask att boost/decay,suppr,curves */ + {0.f,0.f,0.f}, 0.,0., -40.f, {0.}, + + /*noisemaskp,supp, low/high window, low/hi guard, minimum */ + 1, -0.f, .5f, .5f, 0,0,0, + /* noiseoffset*3, noisecompand, max_curve_dB */ + {{-1},{-1},{-1}},{-1},105.f, + /* noise normalization - channel_p, point_p, start, partition, thresh. */ + 0,0,-1,-1,0., +}; + +/* ath ****************/ + +static int _psy_ath_floater[12]={ + -100,-100,-100,-100,-100,-100,-105,-105,-105,-105,-110,-120, +}; +static int _psy_ath_abs[12]={ + -130,-130,-130,-130,-140,-140,-140,-140,-140,-140,-140,-150, +}; + +/* stereo setup. These don't map directly to quality level, there's + an additional indirection as several of the below may be used in a + single bitmanaged stream + +****************/ + +/* various stereo possibilities */ + +/* stereo mode by base quality level */ +static adj_stereo _psy_stereo_modes_44[12]={ + /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 -1 */ + {{ 4, 4, 4, 4, 4, 4, 4, 3, 2, 2, 1, 0, 0, 0, 0}, + { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 5, 4, 3}, + { 1, 2, 3, 4, 4, 4, 4, 4, 4, 5, 6, 7, 8, 8, 8}, + { 12,12.5, 13,13.5, 14,14.5, 15, 99, 99, 99, 99, 99, 99, 99, 99}}, + +/* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 0 */ +/*{{ 4, 4, 4, 4, 4, 4, 4, 3, 2, 2, 1, 0, 0, 0, 0}, + { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 5, 4, 3}, + { 1, 2, 3, 4, 5, 5, 6, 6, 6, 6, 6, 7, 8, 8, 8}, + { 12,12.5, 13,13.5, 14,14.5, 15, 99, 99, 99, 99, 99, 99, 99, 99}},*/ + {{ 4, 4, 4, 4, 4, 4, 4, 3, 2, 1, 0, 0, 0, 0, 0}, + { 8, 8, 8, 8, 6, 6, 5, 5, 5, 5, 5, 5, 5, 4, 3}, + { 1, 2, 3, 4, 4, 5, 6, 6, 6, 6, 6, 8, 8, 8, 8}, + { 12,12.5, 13,13.5, 14,14.5, 15, 99, 99, 99, 99, 99, 99, 99, 99}}, + + + /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 1 */ + {{ 3, 3, 3, 3, 3, 3, 3, 3, 2, 1, 0, 0, 0, 0, 0}, + { 8, 8, 8, 8, 6, 6, 5, 5, 5, 5, 5, 5, 5, 4, 3}, + { 1, 2, 3, 4, 4, 5, 6, 6, 6, 6, 6, 8, 8, 8, 8}, + { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}}, + + + /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 2 */ + /* {{ 3, 3, 3, 3, 3, 3, 2, 2, 2, 1, 0, 0, 0, 0, 0}, + { 8, 8, 8, 6, 5, 5, 5, 5, 5, 5, 5, 4, 3, 2, 1}, + { 3, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 8, 8, 8, 8}, + { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}}, */ + {{ 3, 3, 3, 3, 3, 3, 3, 2, 1, 1, 0, 0, 0, 0, 0}, + { 8, 8, 6, 6, 5, 5, 4, 4, 4, 4, 4, 4, 3, 2, 1}, + { 3, 4, 4, 5, 5, 6, 6, 6, 6, 6, 6, 8, 8, 8, 8}, + { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}}, + /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 3 */ + {{ 2, 2, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0}, + { 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 2, 1}, + { 4, 4, 5, 6, 6, 6, 6, 6, 8, 8, 10, 10, 10, 10, 10}, + { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}}, + /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 4 */ + {{ 2, 2, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 2, 1, 0}, + { 6, 6, 6, 8, 8, 8, 8, 8, 8, 8, 10, 10, 10, 10, 10}, + { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}}, + /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 5 */ + /* {{ 2, 2, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0}, + { 6, 6, 8, 8, 8, 8, 10, 10, 10, 10, 10, 10, 10, 10, 10}, + { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},*/ + {{ 2, 2, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0}, + { 6, 7, 8, 8, 8, 10, 10, 12, 12, 12, 12, 12, 12, 12, 12}, + { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}}, + /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 6 */ + /* {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 3, 3, 3, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 8, 8, 8, 8, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, + { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}}, */ + {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 3, 3, 3, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 8, 8, 8, 10, 10, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, + { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}}, + /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 7 */ + /* {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 3, 3, 3, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 8, 8, 8, 8, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, + { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},*/ + {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 3, 3, 3, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 8, 8, 10, 10, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, + { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}}, + /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 8 */ + /* {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 8, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, + { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},*/ + {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 8, 10, 10, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, + { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}}, + /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 9 */ + {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, + { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}}, + /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 10 */ + {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, + { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}}, +}; + +/* tone master attenuation by base quality mode and bitrate tweak */ +static att3 _psy_tone_masteratt_44[12]={ + {{ 35, 21, 9}, 0, 0}, /* -1 */ + {{ 30, 20, 8}, -2, 1.25}, /* 0 */ + /* {{ 25, 14, 4}, 0, 0}, *//* 1 */ + {{ 25, 12, 2}, 0, 0}, /* 1 */ + /* {{ 20, 10, -2}, 0, 0}, *//* 2 */ + {{ 20, 9, -3}, 0, 0}, /* 2 */ + {{ 20, 9, -4}, 0, 0}, /* 3 */ + {{ 20, 9, -4}, 0, 0}, /* 4 */ + {{ 20, 6, -6}, 0, 0}, /* 5 */ + {{ 20, 3, -10}, 0, 0}, /* 6 */ + {{ 18, 1, -14}, 0, 0}, /* 7 */ + {{ 18, 0, -16}, 0, 0}, /* 8 */ + {{ 18, -2, -16}, 0, 0}, /* 9 */ + {{ 12, -2, -20}, 0, 0}, /* 10 */ +}; + +/* lowpass by mode **************/ +static double _psy_lowpass_44[12]={ + /* 15.1,15.8,16.5,17.9,20.5,48.,999.,999.,999.,999.,999. */ + 13.9,15.1,15.8,16.5,17.2,18.9,20.1,48.,999.,999.,999.,999. +}; + +/* noise normalization **********/ + +static int _noise_start_short_44[11]={ + /* 16,16,16,16,32,32,9999,9999,9999,9999 */ + 32,16,16,16,32,9999,9999,9999,9999,9999,9999 +}; +static int _noise_start_long_44[11]={ + /* 128,128,128,256,512,512,9999,9999,9999,9999 */ + 256,128,128,256,512,9999,9999,9999,9999,9999,9999 +}; + +static int _noise_part_short_44[11]={ + 8,8,8,8,8,8,8,8,8,8,8 +}; +static int _noise_part_long_44[11]={ + 32,32,32,32,32,32,32,32,32,32,32 +}; + +static double _noise_thresh_44[11]={ + /* .2,.2,.3,.4,.5,.5,9999.,9999.,9999.,9999., */ + .2,.2,.2,.4,.6,9999.,9999.,9999.,9999.,9999.,9999., +}; + +static double _noise_thresh_5only[2]={ + .5,.5, +}; diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/psych_8.h b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/psych_8.h new file mode 100644 index 0000000..8a1485a --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/psych_8.h @@ -0,0 +1,102 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: 8kHz psychoacoustic settings + last mod: $Id: psych_8.h 7187 2004-07-20 07:24:27Z xiphmont $ + + ********************************************************************/ + +static att3 _psy_tone_masteratt_8[3]={ + {{ 32, 25, 12}, 0, 0}, /* 0 */ + {{ 30, 25, 12}, 0, 0}, /* 0 */ + {{ 20, 0, -14}, 0, 0}, /* 0 */ +}; + +static vp_adjblock _vp_tonemask_adj_8[3]={ + /* adjust for mode zero */ + /* 63 125 250 500 1 2 4 8 16 */ + {{-15,-15,-15,-15,-10,-10, -6, 0, 0, 0, 0,10, 0, 0,99,99,99}}, /* 1 */ + {{-15,-15,-15,-15,-10,-10, -6, 0, 0, 0, 0,10, 0, 0,99,99,99}}, /* 1 */ + {{-15,-15,-15,-15,-10,-10, -6, 0, 0, 0, 0, 0, 0, 0,99,99,99}}, /* 1 */ +}; + + +static noise3 _psy_noisebias_8[3]={ + /* 63 125 250 500 1k 2k 4k 8k 16k*/ + {{{-10,-10,-10,-10, -5, -5, -5, 0, 4, 8, 8, 8, 10, 10, 99, 99, 99}, + {-10,-10,-10,-10, -5, -5, -5, 0, 0, 4, 4, 4, 4, 4, 99, 99, 99}, + {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, 99, 99, 99}}}, + + {{{-10,-10,-10,-10, -5, -5, -5, 0, 4, 8, 8, 8, 10, 10, 99, 99, 99}, + {-10,-10,-10,-10,-10,-10, -5, -5, -5, 0, 0, 0, 0, 0, 99, 99, 99}, + {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, 99, 99, 99}}}, + + {{{-15,-15,-15,-15,-15,-12,-10, -8, 0, 2, 4, 4, 5, 5, 99, 99, 99}, + {-30,-30,-30,-30,-26,-22,-20,-14,-12,-12,-10,-10,-10,-10, 99, 99, 99}, + {-30,-30,-30,-30,-26,-26,-26,-26,-26,-26,-26,-26,-26,-24, 99, 99, 99}}}, +}; + +/* stereo mode by base quality level */ +static adj_stereo _psy_stereo_modes_8[3]={ + /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 */ + {{ 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}, + { 6, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, + { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}}, + {{ 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}, + { 6, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, + { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}}, + {{ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}, + { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, + { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}}, +}; + +static noiseguard _psy_noiseguards_8[2]={ + {10,10,-1}, + {10,10,-1}, +}; + +static compandblock _psy_compand_8[2]={ + {{ + 0, 1, 2, 3, 4, 5, 6, 7, /* 7dB */ + 8, 8, 9, 9,10,10,11, 11, /* 15dB */ + 12,12,13,13,14,14,15, 15, /* 23dB */ + 16,16,17,17,17,18,18, 19, /* 31dB */ + 19,19,20,21,22,23,24, 25, /* 39dB */ + }}, + {{ + 0, 1, 2, 3, 4, 5, 6, 6, /* 7dB */ + 7, 7, 6, 6, 5, 5, 4, 4, /* 15dB */ + 3, 3, 3, 4, 5, 6, 7, 8, /* 23dB */ + 9,10,11,12,13,14,15, 16, /* 31dB */ + 17,18,19,20,21,22,23, 24, /* 39dB */ + }}, +}; + +static double _psy_lowpass_8[3]={3.,4.,4.}; +static int _noise_start_8[2]={ + 64,64, +}; +static int _noise_part_8[2]={ + 8,8, +}; + +static int _psy_ath_floater_8[3]={ + -100,-100,-105, +}; + +static int _psy_ath_abs_8[3]={ + -130,-130,-140, +}; + diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/residue_16.h b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/residue_16.h new file mode 100644 index 0000000..267a36b --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/residue_16.h @@ -0,0 +1,163 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: toplevel residue templates 16/22kHz + last mod: $Id: residue_16.h 7187 2004-07-20 07:24:27Z xiphmont $ + + ********************************************************************/ + +/***** residue backends *********************************************/ + +static static_bookblock _resbook_16s_0={ + { + {0}, + {0,0,&_16c0_s_p1_0}, + {0,0,&_16c0_s_p2_0}, + {0,0,&_16c0_s_p3_0}, + {0,0,&_16c0_s_p4_0}, + {0,0,&_16c0_s_p5_0}, + {0,0,&_16c0_s_p6_0}, + {&_16c0_s_p7_0,&_16c0_s_p7_1}, + {&_16c0_s_p8_0,&_16c0_s_p8_1}, + {&_16c0_s_p9_0,&_16c0_s_p9_1,&_16c0_s_p9_2} + } +}; +static static_bookblock _resbook_16s_1={ + { + {0}, + {0,0,&_16c1_s_p1_0}, + {0,0,&_16c1_s_p2_0}, + {0,0,&_16c1_s_p3_0}, + {0,0,&_16c1_s_p4_0}, + {0,0,&_16c1_s_p5_0}, + {0,0,&_16c1_s_p6_0}, + {&_16c1_s_p7_0,&_16c1_s_p7_1}, + {&_16c1_s_p8_0,&_16c1_s_p8_1}, + {&_16c1_s_p9_0,&_16c1_s_p9_1,&_16c1_s_p9_2} + } +}; +static static_bookblock _resbook_16s_2={ + { + {0}, + {0,0,&_16c2_s_p1_0}, + {0,0,&_16c2_s_p2_0}, + {0,0,&_16c2_s_p3_0}, + {0,0,&_16c2_s_p4_0}, + {&_16c2_s_p5_0,&_16c2_s_p5_1}, + {&_16c2_s_p6_0,&_16c2_s_p6_1}, + {&_16c2_s_p7_0,&_16c2_s_p7_1}, + {&_16c2_s_p8_0,&_16c2_s_p8_1}, + {&_16c2_s_p9_0,&_16c2_s_p9_1,&_16c2_s_p9_2} + } +}; + +static vorbis_residue_template _res_16s_0[]={ + {2,0, &_residue_44_mid, + &_huff_book__16c0_s_single,&_huff_book__16c0_s_single, + &_resbook_16s_0,&_resbook_16s_0}, +}; +static vorbis_residue_template _res_16s_1[]={ + {2,0, &_residue_44_mid, + &_huff_book__16c1_s_short,&_huff_book__16c1_s_short, + &_resbook_16s_1,&_resbook_16s_1}, + + {2,0, &_residue_44_mid, + &_huff_book__16c1_s_long,&_huff_book__16c1_s_long, + &_resbook_16s_1,&_resbook_16s_1} +}; +static vorbis_residue_template _res_16s_2[]={ + {2,0, &_residue_44_high, + &_huff_book__16c2_s_short,&_huff_book__16c2_s_short, + &_resbook_16s_2,&_resbook_16s_2}, + + {2,0, &_residue_44_high, + &_huff_book__16c2_s_long,&_huff_book__16c2_s_long, + &_resbook_16s_2,&_resbook_16s_2} +}; + +static vorbis_mapping_template _mapres_template_16_stereo[3]={ + { _map_nominal, _res_16s_0 }, /* 0 */ + { _map_nominal, _res_16s_1 }, /* 1 */ + { _map_nominal, _res_16s_2 }, /* 2 */ +}; + +static static_bookblock _resbook_16u_0={ + { + {0}, + {0,0,&_16u0__p1_0}, + {0,0,&_16u0__p2_0}, + {0,0,&_16u0__p3_0}, + {0,0,&_16u0__p4_0}, + {0,0,&_16u0__p5_0}, + {&_16u0__p6_0,&_16u0__p6_1}, + {&_16u0__p7_0,&_16u0__p7_1,&_16u0__p7_2} + } +}; +static static_bookblock _resbook_16u_1={ + { + {0}, + {0,0,&_16u1__p1_0}, + {0,0,&_16u1__p2_0}, + {0,0,&_16u1__p3_0}, + {0,0,&_16u1__p4_0}, + {0,0,&_16u1__p5_0}, + {0,0,&_16u1__p6_0}, + {&_16u1__p7_0,&_16u1__p7_1}, + {&_16u1__p8_0,&_16u1__p8_1}, + {&_16u1__p9_0,&_16u1__p9_1,&_16u1__p9_2} + } +}; +static static_bookblock _resbook_16u_2={ + { + {0}, + {0,0,&_16u2_p1_0}, + {0,0,&_16u2_p2_0}, + {0,0,&_16u2_p3_0}, + {0,0,&_16u2_p4_0}, + {&_16u2_p5_0,&_16u2_p5_1}, + {&_16u2_p6_0,&_16u2_p6_1}, + {&_16u2_p7_0,&_16u2_p7_1}, + {&_16u2_p8_0,&_16u2_p8_1}, + {&_16u2_p9_0,&_16u2_p9_1,&_16u2_p9_2} + } +}; + +static vorbis_residue_template _res_16u_0[]={ + {1,0, &_residue_44_low_un, + &_huff_book__16u0__single,&_huff_book__16u0__single, + &_resbook_16u_0,&_resbook_16u_0}, +}; +static vorbis_residue_template _res_16u_1[]={ + {1,0, &_residue_44_mid_un, + &_huff_book__16u1__short,&_huff_book__16u1__short, + &_resbook_16u_1,&_resbook_16u_1}, + + {1,0, &_residue_44_mid_un, + &_huff_book__16u1__long,&_huff_book__16u1__long, + &_resbook_16u_1,&_resbook_16u_1} +}; +static vorbis_residue_template _res_16u_2[]={ + {1,0, &_residue_44_hi_un, + &_huff_book__16u2__short,&_huff_book__16u2__short, + &_resbook_16u_2,&_resbook_16u_2}, + + {1,0, &_residue_44_hi_un, + &_huff_book__16u2__long,&_huff_book__16u2__long, + &_resbook_16u_2,&_resbook_16u_2} +}; + + +static vorbis_mapping_template _mapres_template_16_uncoupled[3]={ + { _map_nominal_u, _res_16u_0 }, /* 0 */ + { _map_nominal_u, _res_16u_1 }, /* 1 */ + { _map_nominal_u, _res_16u_2 }, /* 2 */ +}; diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/residue_44.h b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/residue_44.h new file mode 100644 index 0000000..cbbfd23 --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/residue_44.h @@ -0,0 +1,294 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: toplevel residue templates for 32/44.1/48kHz + last mod: $Id: residue_44.h 7187 2004-07-20 07:24:27Z xiphmont $ + + ********************************************************************/ + +#include "vorbis/codec.h" +#include "backends.h" +#include "books/coupled/res_books_stereo.h" + +/***** residue backends *********************************************/ + +static vorbis_info_residue0 _residue_44_low={ + 0,-1, -1, 9,-1, + /* 0 1 2 3 4 5 6 7 */ + {0}, + {-1}, + { .5, 1.5, 2.5, 2.5, 4.5, 8.5, 16.5, 32.5}, + { .5, .5, .5, 999., 4.5, 8.5, 16.5, 32.5}, +}; + +static vorbis_info_residue0 _residue_44_mid={ + 0,-1, -1, 10,-1, + /* 0 1 2 3 4 5 6 7 8 */ + {0}, + {-1}, + { .5, 1.5, 1.5, 2.5, 2.5, 4.5, 8.5, 16.5, 32.5}, + { .5, .5, 999., .5, 999., 4.5, 8.5, 16.5, 32.5}, +}; + +static vorbis_info_residue0 _residue_44_high={ + 0,-1, -1, 10,-1, + /* 0 1 2 3 4 5 6 7 8 */ + {0}, + {-1}, + { .5, 1.5, 2.5, 4.5, 8.5, 16.5, 32.5, 71.5,157.5}, + { .5, 1.5, 2.5, 3.5, 4.5, 8.5, 16.5, 71.5,157.5}, +}; + +static static_bookblock _resbook_44s_n1={ + { + {0},{0,0,&_44cn1_s_p1_0},{0,0,&_44cn1_s_p2_0}, + {0,0,&_44cn1_s_p3_0},{0,0,&_44cn1_s_p4_0},{0,0,&_44cn1_s_p5_0}, + {&_44cn1_s_p6_0,&_44cn1_s_p6_1},{&_44cn1_s_p7_0,&_44cn1_s_p7_1}, + {&_44cn1_s_p8_0,&_44cn1_s_p8_1,&_44cn1_s_p8_2} + } +}; +static static_bookblock _resbook_44sm_n1={ + { + {0},{0,0,&_44cn1_sm_p1_0},{0,0,&_44cn1_sm_p2_0}, + {0,0,&_44cn1_sm_p3_0},{0,0,&_44cn1_sm_p4_0},{0,0,&_44cn1_sm_p5_0}, + {&_44cn1_sm_p6_0,&_44cn1_sm_p6_1},{&_44cn1_sm_p7_0,&_44cn1_sm_p7_1}, + {&_44cn1_sm_p8_0,&_44cn1_sm_p8_1,&_44cn1_sm_p8_2} + } +}; + +static static_bookblock _resbook_44s_0={ + { + {0},{0,0,&_44c0_s_p1_0},{0,0,&_44c0_s_p2_0}, + {0,0,&_44c0_s_p3_0},{0,0,&_44c0_s_p4_0},{0,0,&_44c0_s_p5_0}, + {&_44c0_s_p6_0,&_44c0_s_p6_1},{&_44c0_s_p7_0,&_44c0_s_p7_1}, + {&_44c0_s_p8_0,&_44c0_s_p8_1,&_44c0_s_p8_2} + } +}; +static static_bookblock _resbook_44sm_0={ + { + {0},{0,0,&_44c0_sm_p1_0},{0,0,&_44c0_sm_p2_0}, + {0,0,&_44c0_sm_p3_0},{0,0,&_44c0_sm_p4_0},{0,0,&_44c0_sm_p5_0}, + {&_44c0_sm_p6_0,&_44c0_sm_p6_1},{&_44c0_sm_p7_0,&_44c0_sm_p7_1}, + {&_44c0_sm_p8_0,&_44c0_sm_p8_1,&_44c0_sm_p8_2} + } +}; + +static static_bookblock _resbook_44s_1={ + { + {0},{0,0,&_44c1_s_p1_0},{0,0,&_44c1_s_p2_0}, + {0,0,&_44c1_s_p3_0},{0,0,&_44c1_s_p4_0},{0,0,&_44c1_s_p5_0}, + {&_44c1_s_p6_0,&_44c1_s_p6_1},{&_44c1_s_p7_0,&_44c1_s_p7_1}, + {&_44c1_s_p8_0,&_44c1_s_p8_1,&_44c1_s_p8_2} + } +}; +static static_bookblock _resbook_44sm_1={ + { + {0},{0,0,&_44c1_sm_p1_0},{0,0,&_44c1_sm_p2_0}, + {0,0,&_44c1_sm_p3_0},{0,0,&_44c1_sm_p4_0},{0,0,&_44c1_sm_p5_0}, + {&_44c1_sm_p6_0,&_44c1_sm_p6_1},{&_44c1_sm_p7_0,&_44c1_sm_p7_1}, + {&_44c1_sm_p8_0,&_44c1_sm_p8_1,&_44c1_sm_p8_2} + } +}; + +static static_bookblock _resbook_44s_2={ + { + {0},{0,0,&_44c2_s_p1_0},{0,0,&_44c2_s_p2_0},{0,0,&_44c2_s_p3_0}, + {0,0,&_44c2_s_p4_0},{0,0,&_44c2_s_p5_0},{0,0,&_44c2_s_p6_0}, + {&_44c2_s_p7_0,&_44c2_s_p7_1},{&_44c2_s_p8_0,&_44c2_s_p8_1}, + {&_44c2_s_p9_0,&_44c2_s_p9_1,&_44c2_s_p9_2} + } +}; +static static_bookblock _resbook_44s_3={ + { + {0},{0,0,&_44c3_s_p1_0},{0,0,&_44c3_s_p2_0},{0,0,&_44c3_s_p3_0}, + {0,0,&_44c3_s_p4_0},{0,0,&_44c3_s_p5_0},{0,0,&_44c3_s_p6_0}, + {&_44c3_s_p7_0,&_44c3_s_p7_1},{&_44c3_s_p8_0,&_44c3_s_p8_1}, + {&_44c3_s_p9_0,&_44c3_s_p9_1,&_44c3_s_p9_2} + } +}; +static static_bookblock _resbook_44s_4={ + { + {0},{0,0,&_44c4_s_p1_0},{0,0,&_44c4_s_p2_0},{0,0,&_44c4_s_p3_0}, + {0,0,&_44c4_s_p4_0},{0,0,&_44c4_s_p5_0},{0,0,&_44c4_s_p6_0}, + {&_44c4_s_p7_0,&_44c4_s_p7_1},{&_44c4_s_p8_0,&_44c4_s_p8_1}, + {&_44c4_s_p9_0,&_44c4_s_p9_1,&_44c4_s_p9_2} + } +}; +static static_bookblock _resbook_44s_5={ + { + {0},{0,0,&_44c5_s_p1_0},{0,0,&_44c5_s_p2_0},{0,0,&_44c5_s_p3_0}, + {0,0,&_44c5_s_p4_0},{0,0,&_44c5_s_p5_0},{0,0,&_44c5_s_p6_0}, + {&_44c5_s_p7_0,&_44c5_s_p7_1},{&_44c5_s_p8_0,&_44c5_s_p8_1}, + {&_44c5_s_p9_0,&_44c5_s_p9_1,&_44c5_s_p9_2} + } +}; +static static_bookblock _resbook_44s_6={ + { + {0},{0,0,&_44c6_s_p1_0},{0,0,&_44c6_s_p2_0},{0,0,&_44c6_s_p3_0}, + {0,0,&_44c6_s_p4_0}, + {&_44c6_s_p5_0,&_44c6_s_p5_1}, + {&_44c6_s_p6_0,&_44c6_s_p6_1}, + {&_44c6_s_p7_0,&_44c6_s_p7_1}, + {&_44c6_s_p8_0,&_44c6_s_p8_1}, + {&_44c6_s_p9_0,&_44c6_s_p9_1,&_44c6_s_p9_2} + } +}; +static static_bookblock _resbook_44s_7={ + { + {0},{0,0,&_44c7_s_p1_0},{0,0,&_44c7_s_p2_0},{0,0,&_44c7_s_p3_0}, + {0,0,&_44c7_s_p4_0}, + {&_44c7_s_p5_0,&_44c7_s_p5_1}, + {&_44c7_s_p6_0,&_44c7_s_p6_1}, + {&_44c7_s_p7_0,&_44c7_s_p7_1}, + {&_44c7_s_p8_0,&_44c7_s_p8_1}, + {&_44c7_s_p9_0,&_44c7_s_p9_1,&_44c7_s_p9_2} + } +}; +static static_bookblock _resbook_44s_8={ + { + {0},{0,0,&_44c8_s_p1_0},{0,0,&_44c8_s_p2_0},{0,0,&_44c8_s_p3_0}, + {0,0,&_44c8_s_p4_0}, + {&_44c8_s_p5_0,&_44c8_s_p5_1}, + {&_44c8_s_p6_0,&_44c8_s_p6_1}, + {&_44c8_s_p7_0,&_44c8_s_p7_1}, + {&_44c8_s_p8_0,&_44c8_s_p8_1}, + {&_44c8_s_p9_0,&_44c8_s_p9_1,&_44c8_s_p9_2} + } +}; +static static_bookblock _resbook_44s_9={ + { + {0},{0,0,&_44c9_s_p1_0},{0,0,&_44c9_s_p2_0},{0,0,&_44c9_s_p3_0}, + {0,0,&_44c9_s_p4_0}, + {&_44c9_s_p5_0,&_44c9_s_p5_1}, + {&_44c9_s_p6_0,&_44c9_s_p6_1}, + {&_44c9_s_p7_0,&_44c9_s_p7_1}, + {&_44c9_s_p8_0,&_44c9_s_p8_1}, + {&_44c9_s_p9_0,&_44c9_s_p9_1,&_44c9_s_p9_2} + } +}; + +static vorbis_residue_template _res_44s_n1[]={ + {2,0, &_residue_44_low, + &_huff_book__44cn1_s_short,&_huff_book__44cn1_sm_short, + &_resbook_44s_n1,&_resbook_44sm_n1}, + + {2,0, &_residue_44_low, + &_huff_book__44cn1_s_long,&_huff_book__44cn1_sm_long, + &_resbook_44s_n1,&_resbook_44sm_n1} +}; +static vorbis_residue_template _res_44s_0[]={ + {2,0, &_residue_44_low, + &_huff_book__44c0_s_short,&_huff_book__44c0_sm_short, + &_resbook_44s_0,&_resbook_44sm_0}, + + {2,0, &_residue_44_low, + &_huff_book__44c0_s_long,&_huff_book__44c0_sm_long, + &_resbook_44s_0,&_resbook_44sm_0} +}; +static vorbis_residue_template _res_44s_1[]={ + {2,0, &_residue_44_low, + &_huff_book__44c1_s_short,&_huff_book__44c1_sm_short, + &_resbook_44s_1,&_resbook_44sm_1}, + + {2,0, &_residue_44_low, + &_huff_book__44c1_s_long,&_huff_book__44c1_sm_long, + &_resbook_44s_1,&_resbook_44sm_1} +}; + +static vorbis_residue_template _res_44s_2[]={ + {2,0, &_residue_44_mid, + &_huff_book__44c2_s_short,&_huff_book__44c2_s_short, + &_resbook_44s_2,&_resbook_44s_2}, + + {2,0, &_residue_44_mid, + &_huff_book__44c2_s_long,&_huff_book__44c2_s_long, + &_resbook_44s_2,&_resbook_44s_2} +}; +static vorbis_residue_template _res_44s_3[]={ + {2,0, &_residue_44_mid, + &_huff_book__44c3_s_short,&_huff_book__44c3_s_short, + &_resbook_44s_3,&_resbook_44s_3}, + + {2,0, &_residue_44_mid, + &_huff_book__44c3_s_long,&_huff_book__44c3_s_long, + &_resbook_44s_3,&_resbook_44s_3} +}; +static vorbis_residue_template _res_44s_4[]={ + {2,0, &_residue_44_mid, + &_huff_book__44c4_s_short,&_huff_book__44c4_s_short, + &_resbook_44s_4,&_resbook_44s_4}, + + {2,0, &_residue_44_mid, + &_huff_book__44c4_s_long,&_huff_book__44c4_s_long, + &_resbook_44s_4,&_resbook_44s_4} +}; +static vorbis_residue_template _res_44s_5[]={ + {2,0, &_residue_44_mid, + &_huff_book__44c5_s_short,&_huff_book__44c5_s_short, + &_resbook_44s_5,&_resbook_44s_5}, + + {2,0, &_residue_44_mid, + &_huff_book__44c5_s_long,&_huff_book__44c5_s_long, + &_resbook_44s_5,&_resbook_44s_5} +}; +static vorbis_residue_template _res_44s_6[]={ + {2,0, &_residue_44_high, + &_huff_book__44c6_s_short,&_huff_book__44c6_s_short, + &_resbook_44s_6,&_resbook_44s_6}, + + {2,0, &_residue_44_high, + &_huff_book__44c6_s_long,&_huff_book__44c6_s_long, + &_resbook_44s_6,&_resbook_44s_6} +}; +static vorbis_residue_template _res_44s_7[]={ + {2,0, &_residue_44_high, + &_huff_book__44c7_s_short,&_huff_book__44c7_s_short, + &_resbook_44s_7,&_resbook_44s_7}, + + {2,0, &_residue_44_high, + &_huff_book__44c7_s_long,&_huff_book__44c7_s_long, + &_resbook_44s_7,&_resbook_44s_7} +}; +static vorbis_residue_template _res_44s_8[]={ + {2,0, &_residue_44_high, + &_huff_book__44c8_s_short,&_huff_book__44c8_s_short, + &_resbook_44s_8,&_resbook_44s_8}, + + {2,0, &_residue_44_high, + &_huff_book__44c8_s_long,&_huff_book__44c8_s_long, + &_resbook_44s_8,&_resbook_44s_8} +}; +static vorbis_residue_template _res_44s_9[]={ + {2,0, &_residue_44_high, + &_huff_book__44c9_s_short,&_huff_book__44c9_s_short, + &_resbook_44s_9,&_resbook_44s_9}, + + {2,0, &_residue_44_high, + &_huff_book__44c9_s_long,&_huff_book__44c9_s_long, + &_resbook_44s_9,&_resbook_44s_9} +}; + +static vorbis_mapping_template _mapres_template_44_stereo[]={ + { _map_nominal, _res_44s_n1 }, /* -1 */ + { _map_nominal, _res_44s_0 }, /* 0 */ + { _map_nominal, _res_44s_1 }, /* 1 */ + { _map_nominal, _res_44s_2 }, /* 2 */ + { _map_nominal, _res_44s_3 }, /* 3 */ + { _map_nominal, _res_44s_4 }, /* 4 */ + { _map_nominal, _res_44s_5 }, /* 5 */ + { _map_nominal, _res_44s_6 }, /* 6 */ + { _map_nominal, _res_44s_7 }, /* 7 */ + { _map_nominal, _res_44s_8 }, /* 8 */ + { _map_nominal, _res_44s_9 }, /* 9 */ +}; + + diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/residue_44u.h b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/residue_44u.h new file mode 100644 index 0000000..2ac4d54 --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/residue_44u.h @@ -0,0 +1,318 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: toplevel residue templates for 32/44.1/48kHz uncoupled + last mod: $Id: residue_44u.h 7187 2004-07-20 07:24:27Z xiphmont $ + + ********************************************************************/ + +#include "vorbis/codec.h" +#include "backends.h" +#include "books/uncoupled/res_books_uncoupled.h" + +/***** residue backends *********************************************/ + + +static vorbis_info_residue0 _residue_44_low_un={ + 0,-1, -1, 8,-1, + {0}, + {-1}, + { .5, 1.5, 1.5, 2.5, 2.5, 4.5, 28.5}, + { -1, 25, -1, 45, -1, -1, -1} +}; + +static vorbis_info_residue0 _residue_44_mid_un={ + 0,-1, -1, 10,-1, + /* 0 1 2 3 4 5 6 7 8 9 */ + {0}, + {-1}, + { .5, 1.5, 1.5, 2.5, 2.5, 4.5, 4.5, 16.5, 60.5}, + { -1, 30, -1, 50, -1, 80, -1, -1, -1} +}; + +static vorbis_info_residue0 _residue_44_hi_un={ + 0,-1, -1, 10,-1, + /* 0 1 2 3 4 5 6 7 8 9 */ + {0}, + {-1}, + { .5, 1.5, 2.5, 4.5, 8.5, 16.5, 32.5, 71.5,157.5}, + { -1, -1, -1, -1, -1, -1, -1, -1, -1} +}; + +/* mapping conventions: + only one submap (this would change for efficient 5.1 support for example)*/ +/* Four psychoacoustic profiles are used, one for each blocktype */ +static vorbis_info_mapping0 _map_nominal_u[2]={ + {1, {0,0}, {0}, {0}, 0,{0},{0}}, + {1, {0,0}, {1}, {1}, 0,{0},{0}} +}; + +static static_bookblock _resbook_44u_n1={ + { + {0}, + {0,0,&_44un1__p1_0}, + {0,0,&_44un1__p2_0}, + {0,0,&_44un1__p3_0}, + {0,0,&_44un1__p4_0}, + {0,0,&_44un1__p5_0}, + {&_44un1__p6_0,&_44un1__p6_1}, + {&_44un1__p7_0,&_44un1__p7_1,&_44un1__p7_2} + } +}; +static static_bookblock _resbook_44u_0={ + { + {0}, + {0,0,&_44u0__p1_0}, + {0,0,&_44u0__p2_0}, + {0,0,&_44u0__p3_0}, + {0,0,&_44u0__p4_0}, + {0,0,&_44u0__p5_0}, + {&_44u0__p6_0,&_44u0__p6_1}, + {&_44u0__p7_0,&_44u0__p7_1,&_44u0__p7_2} + } +}; +static static_bookblock _resbook_44u_1={ + { + {0}, + {0,0,&_44u1__p1_0}, + {0,0,&_44u1__p2_0}, + {0,0,&_44u1__p3_0}, + {0,0,&_44u1__p4_0}, + {0,0,&_44u1__p5_0}, + {&_44u1__p6_0,&_44u1__p6_1}, + {&_44u1__p7_0,&_44u1__p7_1,&_44u1__p7_2} + } +}; +static static_bookblock _resbook_44u_2={ + { + {0}, + {0,0,&_44u2__p1_0}, + {0,0,&_44u2__p2_0}, + {0,0,&_44u2__p3_0}, + {0,0,&_44u2__p4_0}, + {0,0,&_44u2__p5_0}, + {&_44u2__p6_0,&_44u2__p6_1}, + {&_44u2__p7_0,&_44u2__p7_1,&_44u2__p7_2} + } +}; +static static_bookblock _resbook_44u_3={ + { + {0}, + {0,0,&_44u3__p1_0}, + {0,0,&_44u3__p2_0}, + {0,0,&_44u3__p3_0}, + {0,0,&_44u3__p4_0}, + {0,0,&_44u3__p5_0}, + {&_44u3__p6_0,&_44u3__p6_1}, + {&_44u3__p7_0,&_44u3__p7_1,&_44u3__p7_2} + } +}; +static static_bookblock _resbook_44u_4={ + { + {0}, + {0,0,&_44u4__p1_0}, + {0,0,&_44u4__p2_0}, + {0,0,&_44u4__p3_0}, + {0,0,&_44u4__p4_0}, + {0,0,&_44u4__p5_0}, + {&_44u4__p6_0,&_44u4__p6_1}, + {&_44u4__p7_0,&_44u4__p7_1,&_44u4__p7_2} + } +}; +static static_bookblock _resbook_44u_5={ + { + {0}, + {0,0,&_44u5__p1_0}, + {0,0,&_44u5__p2_0}, + {0,0,&_44u5__p3_0}, + {0,0,&_44u5__p4_0}, + {0,0,&_44u5__p5_0}, + {0,0,&_44u5__p6_0}, + {&_44u5__p7_0,&_44u5__p7_1}, + {&_44u5__p8_0,&_44u5__p8_1}, + {&_44u5__p9_0,&_44u5__p9_1,&_44u5__p9_2} + } +}; +static static_bookblock _resbook_44u_6={ + { + {0}, + {0,0,&_44u6__p1_0}, + {0,0,&_44u6__p2_0}, + {0,0,&_44u6__p3_0}, + {0,0,&_44u6__p4_0}, + {0,0,&_44u6__p5_0}, + {0,0,&_44u6__p6_0}, + {&_44u6__p7_0,&_44u6__p7_1}, + {&_44u6__p8_0,&_44u6__p8_1}, + {&_44u6__p9_0,&_44u6__p9_1,&_44u6__p9_2} + } +}; +static static_bookblock _resbook_44u_7={ + { + {0}, + {0,0,&_44u7__p1_0}, + {0,0,&_44u7__p2_0}, + {0,0,&_44u7__p3_0}, + {0,0,&_44u7__p4_0}, + {0,0,&_44u7__p5_0}, + {0,0,&_44u7__p6_0}, + {&_44u7__p7_0,&_44u7__p7_1}, + {&_44u7__p8_0,&_44u7__p8_1}, + {&_44u7__p9_0,&_44u7__p9_1,&_44u7__p9_2} + } +}; +static static_bookblock _resbook_44u_8={ + { + {0}, + {0,0,&_44u8_p1_0}, + {0,0,&_44u8_p2_0}, + {0,0,&_44u8_p3_0}, + {0,0,&_44u8_p4_0}, + {&_44u8_p5_0,&_44u8_p5_1}, + {&_44u8_p6_0,&_44u8_p6_1}, + {&_44u8_p7_0,&_44u8_p7_1}, + {&_44u8_p8_0,&_44u8_p8_1}, + {&_44u8_p9_0,&_44u8_p9_1,&_44u8_p9_2} + } +}; +static static_bookblock _resbook_44u_9={ + { + {0}, + {0,0,&_44u9_p1_0}, + {0,0,&_44u9_p2_0}, + {0,0,&_44u9_p3_0}, + {0,0,&_44u9_p4_0}, + {&_44u9_p5_0,&_44u9_p5_1}, + {&_44u9_p6_0,&_44u9_p6_1}, + {&_44u9_p7_0,&_44u9_p7_1}, + {&_44u9_p8_0,&_44u9_p8_1}, + {&_44u9_p9_0,&_44u9_p9_1,&_44u9_p9_2} + } +}; + +static vorbis_residue_template _res_44u_n1[]={ + {1,0, &_residue_44_low_un, + &_huff_book__44un1__short,&_huff_book__44un1__short, + &_resbook_44u_n1,&_resbook_44u_n1}, + + {1,0, &_residue_44_low_un, + &_huff_book__44un1__long,&_huff_book__44un1__long, + &_resbook_44u_n1,&_resbook_44u_n1} +}; +static vorbis_residue_template _res_44u_0[]={ + {1,0, &_residue_44_low_un, + &_huff_book__44u0__short,&_huff_book__44u0__short, + &_resbook_44u_0,&_resbook_44u_0}, + + {1,0, &_residue_44_low_un, + &_huff_book__44u0__long,&_huff_book__44u0__long, + &_resbook_44u_0,&_resbook_44u_0} +}; +static vorbis_residue_template _res_44u_1[]={ + {1,0, &_residue_44_low_un, + &_huff_book__44u1__short,&_huff_book__44u1__short, + &_resbook_44u_1,&_resbook_44u_1}, + + {1,0, &_residue_44_low_un, + &_huff_book__44u1__long,&_huff_book__44u1__long, + &_resbook_44u_1,&_resbook_44u_1} +}; +static vorbis_residue_template _res_44u_2[]={ + {1,0, &_residue_44_low_un, + &_huff_book__44u2__short,&_huff_book__44u2__short, + &_resbook_44u_2,&_resbook_44u_2}, + + {1,0, &_residue_44_low_un, + &_huff_book__44u2__long,&_huff_book__44u2__long, + &_resbook_44u_2,&_resbook_44u_2} +}; +static vorbis_residue_template _res_44u_3[]={ + {1,0, &_residue_44_low_un, + &_huff_book__44u3__short,&_huff_book__44u3__short, + &_resbook_44u_3,&_resbook_44u_3}, + + {1,0, &_residue_44_low_un, + &_huff_book__44u3__long,&_huff_book__44u3__long, + &_resbook_44u_3,&_resbook_44u_3} +}; +static vorbis_residue_template _res_44u_4[]={ + {1,0, &_residue_44_low_un, + &_huff_book__44u4__short,&_huff_book__44u4__short, + &_resbook_44u_4,&_resbook_44u_4}, + + {1,0, &_residue_44_low_un, + &_huff_book__44u4__long,&_huff_book__44u4__long, + &_resbook_44u_4,&_resbook_44u_4} +}; + +static vorbis_residue_template _res_44u_5[]={ + {1,0, &_residue_44_mid_un, + &_huff_book__44u5__short,&_huff_book__44u5__short, + &_resbook_44u_5,&_resbook_44u_5}, + + {1,0, &_residue_44_mid_un, + &_huff_book__44u5__long,&_huff_book__44u5__long, + &_resbook_44u_5,&_resbook_44u_5} +}; + +static vorbis_residue_template _res_44u_6[]={ + {1,0, &_residue_44_mid_un, + &_huff_book__44u6__short,&_huff_book__44u6__short, + &_resbook_44u_6,&_resbook_44u_6}, + + {1,0, &_residue_44_mid_un, + &_huff_book__44u6__long,&_huff_book__44u6__long, + &_resbook_44u_6,&_resbook_44u_6} +}; + +static vorbis_residue_template _res_44u_7[]={ + {1,0, &_residue_44_mid_un, + &_huff_book__44u7__short,&_huff_book__44u7__short, + &_resbook_44u_7,&_resbook_44u_7}, + + {1,0, &_residue_44_mid_un, + &_huff_book__44u7__long,&_huff_book__44u7__long, + &_resbook_44u_7,&_resbook_44u_7} +}; + +static vorbis_residue_template _res_44u_8[]={ + {1,0, &_residue_44_hi_un, + &_huff_book__44u8__short,&_huff_book__44u8__short, + &_resbook_44u_8,&_resbook_44u_8}, + + {1,0, &_residue_44_hi_un, + &_huff_book__44u8__long,&_huff_book__44u8__long, + &_resbook_44u_8,&_resbook_44u_8} +}; +static vorbis_residue_template _res_44u_9[]={ + {1,0, &_residue_44_hi_un, + &_huff_book__44u9__short,&_huff_book__44u9__short, + &_resbook_44u_9,&_resbook_44u_9}, + + {1,0, &_residue_44_hi_un, + &_huff_book__44u9__long,&_huff_book__44u9__long, + &_resbook_44u_9,&_resbook_44u_9} +}; + +static vorbis_mapping_template _mapres_template_44_uncoupled[]={ + { _map_nominal_u, _res_44u_n1 }, /* -1 */ + { _map_nominal_u, _res_44u_0 }, /* 0 */ + { _map_nominal_u, _res_44u_1 }, /* 1 */ + { _map_nominal_u, _res_44u_2 }, /* 2 */ + { _map_nominal_u, _res_44u_3 }, /* 3 */ + { _map_nominal_u, _res_44u_4 }, /* 4 */ + { _map_nominal_u, _res_44u_5 }, /* 5 */ + { _map_nominal_u, _res_44u_6 }, /* 6 */ + { _map_nominal_u, _res_44u_7 }, /* 7 */ + { _map_nominal_u, _res_44u_8 }, /* 8 */ + { _map_nominal_u, _res_44u_9 }, /* 9 */ +}; diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/residue_8.h b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/residue_8.h new file mode 100644 index 0000000..89cdc91 --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/residue_8.h @@ -0,0 +1,97 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: toplevel residue templates 8/11kHz + last mod: $Id: residue_8.h 7187 2004-07-20 07:24:27Z xiphmont $ + + ********************************************************************/ + +#include "vorbis/codec.h" +#include "backends.h" + +/***** residue backends *********************************************/ + +static static_bookblock _resbook_8s_0={ + { + {0},{0,0,&_8c0_s_p1_0},{0,0,&_8c0_s_p2_0},{0,0,&_8c0_s_p3_0}, + {0,0,&_8c0_s_p4_0},{0,0,&_8c0_s_p5_0},{0,0,&_8c0_s_p6_0}, + {&_8c0_s_p7_0,&_8c0_s_p7_1},{&_8c0_s_p8_0,&_8c0_s_p8_1}, + {&_8c0_s_p9_0,&_8c0_s_p9_1,&_8c0_s_p9_2} + } +}; +static static_bookblock _resbook_8s_1={ + { + {0},{0,0,&_8c1_s_p1_0},{0,0,&_8c1_s_p2_0},{0,0,&_8c1_s_p3_0}, + {0,0,&_8c1_s_p4_0},{0,0,&_8c1_s_p5_0},{0,0,&_8c1_s_p6_0}, + {&_8c1_s_p7_0,&_8c1_s_p7_1},{&_8c1_s_p8_0,&_8c1_s_p8_1}, + {&_8c1_s_p9_0,&_8c1_s_p9_1,&_8c1_s_p9_2} + } +}; + +static vorbis_residue_template _res_8s_0[]={ + {2,0, &_residue_44_mid, + &_huff_book__8c0_s_single,&_huff_book__8c0_s_single, + &_resbook_8s_0,&_resbook_8s_0}, +}; +static vorbis_residue_template _res_8s_1[]={ + {2,0, &_residue_44_mid, + &_huff_book__8c1_s_single,&_huff_book__8c1_s_single, + &_resbook_8s_1,&_resbook_8s_1}, +}; + +static vorbis_mapping_template _mapres_template_8_stereo[2]={ + { _map_nominal, _res_8s_0 }, /* 0 */ + { _map_nominal, _res_8s_1 }, /* 1 */ +}; + +static static_bookblock _resbook_8u_0={ + { + {0}, + {0,0,&_8u0__p1_0}, + {0,0,&_8u0__p2_0}, + {0,0,&_8u0__p3_0}, + {0,0,&_8u0__p4_0}, + {0,0,&_8u0__p5_0}, + {&_8u0__p6_0,&_8u0__p6_1}, + {&_8u0__p7_0,&_8u0__p7_1,&_8u0__p7_2} + } +}; +static static_bookblock _resbook_8u_1={ + { + {0}, + {0,0,&_8u1__p1_0}, + {0,0,&_8u1__p2_0}, + {0,0,&_8u1__p3_0}, + {0,0,&_8u1__p4_0}, + {0,0,&_8u1__p5_0}, + {0,0,&_8u1__p6_0}, + {&_8u1__p7_0,&_8u1__p7_1}, + {&_8u1__p8_0,&_8u1__p8_1}, + {&_8u1__p9_0,&_8u1__p9_1,&_8u1__p9_2} + } +}; + +static vorbis_residue_template _res_8u_0[]={ + {1,0, &_residue_44_low_un, + &_huff_book__8u0__single,&_huff_book__8u0__single, + &_resbook_8u_0,&_resbook_8u_0}, +}; +static vorbis_residue_template _res_8u_1[]={ + {1,0, &_residue_44_mid_un, + &_huff_book__8u1__single,&_huff_book__8u1__single, + &_resbook_8u_1,&_resbook_8u_1}, +}; + +static vorbis_mapping_template _mapres_template_8_uncoupled[2]={ + { _map_nominal_u, _res_8u_0 }, /* 0 */ + { _map_nominal_u, _res_8u_1 }, /* 1 */ +}; diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/setup_11.h b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/setup_11.h new file mode 100644 index 0000000..a414bc6 --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/setup_11.h @@ -0,0 +1,141 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: 11kHz settings + last mod: $Id: setup_11.h 7187 2004-07-20 07:24:27Z xiphmont $ + + ********************************************************************/ + +#include "psych_11.h" + +static int blocksize_11[2]={ + 512,512 +}; + +static int _floor_mapping_11[2]={ + 6,6, +}; + +static double rate_mapping_11[3]={ + 8000.,13000.,44000., +}; + +static double rate_mapping_11_uncoupled[3]={ + 12000.,20000.,50000., +}; + +static double quality_mapping_11[3]={ + -.1,.0,1. +}; + +ve_setup_data_template ve_setup_11_stereo={ + 2, + rate_mapping_11, + quality_mapping_11, + 2, + 9000, + 15000, + + blocksize_11, + blocksize_11, + + _psy_tone_masteratt_11, + _psy_tone_0dB, + _psy_tone_suppress, + + _vp_tonemask_adj_11, + NULL, + _vp_tonemask_adj_11, + + _psy_noiseguards_8, + _psy_noisebias_11, + _psy_noisebias_11, + NULL, + NULL, + _psy_noise_suppress, + + _psy_compand_8, + _psy_compand_8_mapping, + NULL, + + {_noise_start_8,_noise_start_8}, + {_noise_part_8,_noise_part_8}, + _noise_thresh_11, + + _psy_ath_floater_8, + _psy_ath_abs_8, + + _psy_lowpass_11, + + _psy_global_44, + _global_mapping_8, + _psy_stereo_modes_8, + + _floor_books, + _floor, + _floor_mapping_11, + NULL, + + _mapres_template_8_stereo +}; + +ve_setup_data_template ve_setup_11_uncoupled={ + 2, + rate_mapping_11_uncoupled, + quality_mapping_11, + -1, + 9000, + 15000, + + blocksize_11, + blocksize_11, + + _psy_tone_masteratt_11, + _psy_tone_0dB, + _psy_tone_suppress, + + _vp_tonemask_adj_11, + NULL, + _vp_tonemask_adj_11, + + _psy_noiseguards_8, + _psy_noisebias_11, + _psy_noisebias_11, + NULL, + NULL, + _psy_noise_suppress, + + _psy_compand_8, + _psy_compand_8_mapping, + NULL, + + {_noise_start_8,_noise_start_8}, + {_noise_part_8,_noise_part_8}, + _noise_thresh_11, + + _psy_ath_floater_8, + _psy_ath_abs_8, + + _psy_lowpass_11, + + _psy_global_44, + _global_mapping_8, + _psy_stereo_modes_8, + + _floor_books, + _floor, + _floor_mapping_11, + NULL, + + _mapres_template_8_uncoupled +}; + diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/setup_16.h b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/setup_16.h new file mode 100644 index 0000000..d97179f --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/setup_16.h @@ -0,0 +1,149 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: 16kHz settings + last mod: $Id: setup_16.h 7187 2004-07-20 07:24:27Z xiphmont $ + + ********************************************************************/ + +#include "psych_16.h" +#include "residue_16.h" + +static int blocksize_16_short[3]={ + 1024,512,512 +}; +static int blocksize_16_long[3]={ + 1024,1024,1024 +}; + +static int _floor_mapping_16_short[3]={ + 9,3,3 +}; +static int _floor_mapping_16[3]={ + 9,9,9 +}; + +static double rate_mapping_16[4]={ + 12000.,20000.,44000.,86000. +}; + +static double rate_mapping_16_uncoupled[4]={ + 16000.,28000.,64000.,100000. +}; + +static double _global_mapping_16[4]={ 1., 2., 3., 4. }; + +static double quality_mapping_16[4]={ -.1,.05,.5,1. }; + +static double _psy_compand_16_mapping[4]={ 0., .8, 1., 1.}; + +ve_setup_data_template ve_setup_16_stereo={ + 3, + rate_mapping_16, + quality_mapping_16, + 2, + 15000, + 19000, + + blocksize_16_short, + blocksize_16_long, + + _psy_tone_masteratt_16, + _psy_tone_0dB, + _psy_tone_suppress, + + _vp_tonemask_adj_16, + _vp_tonemask_adj_16, + _vp_tonemask_adj_16, + + _psy_noiseguards_8, + _psy_noisebias_16_impulse, + _psy_noisebias_16_short, + _psy_noisebias_16_short, + _psy_noisebias_16, + _psy_noise_suppress, + + _psy_compand_8, + _psy_compand_16_mapping, + _psy_compand_16_mapping, + + {_noise_start_16,_noise_start_16}, + { _noise_part_16, _noise_part_16}, + _noise_thresh_16, + + _psy_ath_floater_16, + _psy_ath_abs_16, + + _psy_lowpass_16, + + _psy_global_44, + _global_mapping_16, + _psy_stereo_modes_16, + + _floor_books, + _floor, + _floor_mapping_16_short, + _floor_mapping_16, + + _mapres_template_16_stereo +}; + +ve_setup_data_template ve_setup_16_uncoupled={ + 3, + rate_mapping_16_uncoupled, + quality_mapping_16, + -1, + 15000, + 19000, + + blocksize_16_short, + blocksize_16_long, + + _psy_tone_masteratt_16, + _psy_tone_0dB, + _psy_tone_suppress, + + _vp_tonemask_adj_16, + _vp_tonemask_adj_16, + _vp_tonemask_adj_16, + + _psy_noiseguards_8, + _psy_noisebias_16_impulse, + _psy_noisebias_16_short, + _psy_noisebias_16_short, + _psy_noisebias_16, + _psy_noise_suppress, + + _psy_compand_8, + _psy_compand_16_mapping, + _psy_compand_16_mapping, + + {_noise_start_16,_noise_start_16}, + { _noise_part_16, _noise_part_16}, + _noise_thresh_16, + + _psy_ath_floater_16, + _psy_ath_abs_16, + + _psy_lowpass_16, + + _psy_global_44, + _global_mapping_16, + _psy_stereo_modes_16, + + _floor_books, + _floor, + _floor_mapping_16_short, + _floor_mapping_16, + + _mapres_template_16_uncoupled +}; diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/setup_22.h b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/setup_22.h new file mode 100644 index 0000000..f99e48e --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/setup_22.h @@ -0,0 +1,128 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: 22kHz settings + last mod: $Id: setup_22.h 7187 2004-07-20 07:24:27Z xiphmont $ + + ********************************************************************/ + +static double rate_mapping_22[4]={ + 15000.,20000.,44000.,86000. +}; + +static double rate_mapping_22_uncoupled[4]={ + 16000.,28000.,50000.,90000. +}; + +static double _psy_lowpass_22[4]={9.5,11.,30.,99.}; + +ve_setup_data_template ve_setup_22_stereo={ + 3, + rate_mapping_22, + quality_mapping_16, + 2, + 19000, + 26000, + + blocksize_16_short, + blocksize_16_long, + + _psy_tone_masteratt_16, + _psy_tone_0dB, + _psy_tone_suppress, + + _vp_tonemask_adj_16, + _vp_tonemask_adj_16, + _vp_tonemask_adj_16, + + _psy_noiseguards_8, + _psy_noisebias_16_impulse, + _psy_noisebias_16_short, + _psy_noisebias_16_short, + _psy_noisebias_16, + _psy_noise_suppress, + + _psy_compand_8, + _psy_compand_8_mapping, + _psy_compand_8_mapping, + + {_noise_start_16,_noise_start_16}, + { _noise_part_16, _noise_part_16}, + _noise_thresh_16, + + _psy_ath_floater_16, + _psy_ath_abs_16, + + _psy_lowpass_22, + + _psy_global_44, + _global_mapping_16, + _psy_stereo_modes_16, + + _floor_books, + _floor, + _floor_mapping_16_short, + _floor_mapping_16, + + _mapres_template_16_stereo +}; + +ve_setup_data_template ve_setup_22_uncoupled={ + 3, + rate_mapping_22_uncoupled, + quality_mapping_16, + -1, + 19000, + 26000, + + blocksize_16_short, + blocksize_16_long, + + _psy_tone_masteratt_16, + _psy_tone_0dB, + _psy_tone_suppress, + + _vp_tonemask_adj_16, + _vp_tonemask_adj_16, + _vp_tonemask_adj_16, + + _psy_noiseguards_8, + _psy_noisebias_16_impulse, + _psy_noisebias_16_short, + _psy_noisebias_16_short, + _psy_noisebias_16, + _psy_noise_suppress, + + _psy_compand_8, + _psy_compand_8_mapping, + _psy_compand_8_mapping, + + {_noise_start_16,_noise_start_16}, + { _noise_part_16, _noise_part_16}, + _noise_thresh_16, + + _psy_ath_floater_16, + _psy_ath_abs_16, + + _psy_lowpass_22, + + _psy_global_44, + _global_mapping_16, + _psy_stereo_modes_16, + + _floor_books, + _floor, + _floor_mapping_16_short, + _floor_mapping_16, + + _mapres_template_16_uncoupled +}; diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/setup_32.h b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/setup_32.h new file mode 100644 index 0000000..e29a1c7 --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/setup_32.h @@ -0,0 +1,132 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: toplevel settings for 32kHz + last mod: $Id: setup_32.h 7187 2004-07-20 07:24:27Z xiphmont $ + + ********************************************************************/ + +static double rate_mapping_32[12]={ + 18000.,28000.,35000.,45000.,56000.,60000., + 75000.,90000.,100000.,115000.,150000.,190000., +}; + +static double rate_mapping_32_un[12]={ + 30000.,42000.,52000.,64000.,72000.,78000., + 86000.,92000.,110000.,120000.,140000.,190000., +}; + +static double _psy_lowpass_32[12]={ + 12.3,13.,13.,14.,15.,99.,99.,99.,99.,99.,99.,99. +}; + +ve_setup_data_template ve_setup_32_stereo={ + 11, + rate_mapping_32, + quality_mapping_44, + 2, + 26000, + 40000, + + blocksize_short_44, + blocksize_long_44, + + _psy_tone_masteratt_44, + _psy_tone_0dB, + _psy_tone_suppress, + + _vp_tonemask_adj_otherblock, + _vp_tonemask_adj_longblock, + _vp_tonemask_adj_otherblock, + + _psy_noiseguards_44, + _psy_noisebias_impulse, + _psy_noisebias_padding, + _psy_noisebias_trans, + _psy_noisebias_long, + _psy_noise_suppress, + + _psy_compand_44, + _psy_compand_short_mapping, + _psy_compand_long_mapping, + + {_noise_start_short_44,_noise_start_long_44}, + {_noise_part_short_44,_noise_part_long_44}, + _noise_thresh_44, + + _psy_ath_floater, + _psy_ath_abs, + + _psy_lowpass_32, + + _psy_global_44, + _global_mapping_44, + _psy_stereo_modes_44, + + _floor_books, + _floor, + _floor_short_mapping_44, + _floor_long_mapping_44, + + _mapres_template_44_stereo +}; + +ve_setup_data_template ve_setup_32_uncoupled={ + 11, + rate_mapping_32_un, + quality_mapping_44, + -1, + 26000, + 40000, + + blocksize_short_44, + blocksize_long_44, + + _psy_tone_masteratt_44, + _psy_tone_0dB, + _psy_tone_suppress, + + _vp_tonemask_adj_otherblock, + _vp_tonemask_adj_longblock, + _vp_tonemask_adj_otherblock, + + _psy_noiseguards_44, + _psy_noisebias_impulse, + _psy_noisebias_padding, + _psy_noisebias_trans, + _psy_noisebias_long, + _psy_noise_suppress, + + _psy_compand_44, + _psy_compand_short_mapping, + _psy_compand_long_mapping, + + {_noise_start_short_44,_noise_start_long_44}, + {_noise_part_short_44,_noise_part_long_44}, + _noise_thresh_44, + + _psy_ath_floater, + _psy_ath_abs, + + _psy_lowpass_32, + + _psy_global_44, + _global_mapping_44, + NULL, + + _floor_books, + _floor, + _floor_short_mapping_44, + _floor_long_mapping_44, + + _mapres_template_44_uncoupled +}; diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/setup_44.h b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/setup_44.h new file mode 100644 index 0000000..b7ed667 --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/setup_44.h @@ -0,0 +1,107 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: toplevel settings for 44.1/48kHz + last mod: $Id: setup_44.h 7187 2004-07-20 07:24:27Z xiphmont $ + + ********************************************************************/ + +#include "modes/floor_all.h" +#include "modes/residue_44.h" +#include "modes/psych_44.h" + +static double rate_mapping_44_stereo[12]={ + 22500.,32000.,40000.,48000.,56000.,64000., + 80000.,96000.,112000.,128000.,160000.,250001. +}; + +static double quality_mapping_44[12]={ + -.1,.0,.1,.2,.3,.4,.5,.6,.7,.8,.9,1.0 +}; + +static int blocksize_short_44[11]={ + 512,256,256,256,256,256,256,256,256,256,256 +}; +static int blocksize_long_44[11]={ + 4096,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048 +}; + +static double _psy_compand_short_mapping[12]={ + 0.5, 1., 1., 1.3, 1.6, 2., 2., 2., 2., 2., 2., 2. +}; +static double _psy_compand_long_mapping[12]={ + 3.5, 4., 4., 4.3, 4.6, 5., 5., 5., 5., 5., 5., 5. +}; + +static double _global_mapping_44[12]={ + /* 1., 1., 1.5, 2., 2., 2.5, 2.7, 3.0, 3.5, 4., 4. */ + 0., 1., 1., 1.5, 2., 2., 2.5, 2.7, 3.0, 3.7, 4., 4. +}; + +static int _floor_short_mapping_44[11]={ + 1,0,0,2,2,4,5,5,5,5,5 +}; +static int _floor_long_mapping_44[11]={ + 8,7,7,7,7,7,7,7,7,7,7 +}; + +ve_setup_data_template ve_setup_44_stereo={ + 11, + rate_mapping_44_stereo, + quality_mapping_44, + 2, + 40000, + 50000, + + blocksize_short_44, + blocksize_long_44, + + _psy_tone_masteratt_44, + _psy_tone_0dB, + _psy_tone_suppress, + + _vp_tonemask_adj_otherblock, + _vp_tonemask_adj_longblock, + _vp_tonemask_adj_otherblock, + + _psy_noiseguards_44, + _psy_noisebias_impulse, + _psy_noisebias_padding, + _psy_noisebias_trans, + _psy_noisebias_long, + _psy_noise_suppress, + + _psy_compand_44, + _psy_compand_short_mapping, + _psy_compand_long_mapping, + + {_noise_start_short_44,_noise_start_long_44}, + {_noise_part_short_44,_noise_part_long_44}, + _noise_thresh_44, + + _psy_ath_floater, + _psy_ath_abs, + + _psy_lowpass_44, + + _psy_global_44, + _global_mapping_44, + _psy_stereo_modes_44, + + _floor_books, + _floor, + _floor_short_mapping_44, + _floor_long_mapping_44, + + _mapres_template_44_stereo +}; + diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/setup_44u.h b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/setup_44u.h new file mode 100644 index 0000000..59f8e3a --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/setup_44u.h @@ -0,0 +1,74 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: toplevel settings for 44.1/48kHz uncoupled modes + last mod: $Id: setup_44u.h 7187 2004-07-20 07:24:27Z xiphmont $ + + ********************************************************************/ + +#include "modes/residue_44u.h" + +static double rate_mapping_44_un[12]={ + 32000.,48000.,60000.,70000.,80000.,86000., + 96000.,110000.,120000.,140000.,160000.,240001. +}; + +ve_setup_data_template ve_setup_44_uncoupled={ + 11, + rate_mapping_44_un, + quality_mapping_44, + -1, + 40000, + 50000, + + blocksize_short_44, + blocksize_long_44, + + _psy_tone_masteratt_44, + _psy_tone_0dB, + _psy_tone_suppress, + + _vp_tonemask_adj_otherblock, + _vp_tonemask_adj_longblock, + _vp_tonemask_adj_otherblock, + + _psy_noiseguards_44, + _psy_noisebias_impulse, + _psy_noisebias_padding, + _psy_noisebias_trans, + _psy_noisebias_long, + _psy_noise_suppress, + + _psy_compand_44, + _psy_compand_short_mapping, + _psy_compand_long_mapping, + + {_noise_start_short_44,_noise_start_long_44}, + {_noise_part_short_44,_noise_part_long_44}, + _noise_thresh_44, + + _psy_ath_floater, + _psy_ath_abs, + + _psy_lowpass_44, + + _psy_global_44, + _global_mapping_44, + NULL, + + _floor_books, + _floor, + _floor_short_mapping_44, + _floor_long_mapping_44, + + _mapres_template_44_uncoupled +}; diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/setup_8.h b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/setup_8.h new file mode 100644 index 0000000..af1c718 --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/setup_8.h @@ -0,0 +1,146 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: 8kHz settings + last mod: $Id: setup_8.h 7187 2004-07-20 07:24:27Z xiphmont $ + + ********************************************************************/ + +#include "psych_8.h" +#include "residue_8.h" + +static int blocksize_8[2]={ + 512,512 +}; + +static int _floor_mapping_8[2]={ + 6,6, +}; + +static double rate_mapping_8[3]={ + 6000.,9000.,32000., +}; + +static double rate_mapping_8_uncoupled[3]={ + 8000.,14000.,42000., +}; + +static double quality_mapping_8[3]={ + -.1,.0,1. +}; + +static double _psy_compand_8_mapping[3]={ 0., 1., 1.}; + +static double _global_mapping_8[3]={ 1., 2., 3. }; + +ve_setup_data_template ve_setup_8_stereo={ + 2, + rate_mapping_8, + quality_mapping_8, + 2, + 8000, + 9000, + + blocksize_8, + blocksize_8, + + _psy_tone_masteratt_8, + _psy_tone_0dB, + _psy_tone_suppress, + + _vp_tonemask_adj_8, + NULL, + _vp_tonemask_adj_8, + + _psy_noiseguards_8, + _psy_noisebias_8, + _psy_noisebias_8, + NULL, + NULL, + _psy_noise_suppress, + + _psy_compand_8, + _psy_compand_8_mapping, + NULL, + + {_noise_start_8,_noise_start_8}, + {_noise_part_8,_noise_part_8}, + _noise_thresh_5only, + + _psy_ath_floater_8, + _psy_ath_abs_8, + + _psy_lowpass_8, + + _psy_global_44, + _global_mapping_8, + _psy_stereo_modes_8, + + _floor_books, + _floor, + _floor_mapping_8, + NULL, + + _mapres_template_8_stereo +}; + +ve_setup_data_template ve_setup_8_uncoupled={ + 2, + rate_mapping_8_uncoupled, + quality_mapping_8, + -1, + 8000, + 9000, + + blocksize_8, + blocksize_8, + + _psy_tone_masteratt_8, + _psy_tone_0dB, + _psy_tone_suppress, + + _vp_tonemask_adj_8, + NULL, + _vp_tonemask_adj_8, + + _psy_noiseguards_8, + _psy_noisebias_8, + _psy_noisebias_8, + NULL, + NULL, + _psy_noise_suppress, + + _psy_compand_8, + _psy_compand_8_mapping, + NULL, + + {_noise_start_8,_noise_start_8}, + {_noise_part_8,_noise_part_8}, + _noise_thresh_5only, + + _psy_ath_floater_8, + _psy_ath_abs_8, + + _psy_lowpass_8, + + _psy_global_44, + _global_mapping_8, + _psy_stereo_modes_8, + + _floor_books, + _floor, + _floor_mapping_8, + NULL, + + _mapres_template_8_uncoupled +}; + diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/setup_X.h b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/setup_X.h new file mode 100644 index 0000000..06414f0 --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/modes/setup_X.h @@ -0,0 +1,226 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: catch-all toplevel settings for q modes only + last mod: $Id: setup_X.h 7187 2004-07-20 07:24:27Z xiphmont $ + + ********************************************************************/ + +static double rate_mapping_X[12]={ + -1.,-1.,-1.,-1.,-1.,-1., + -1.,-1.,-1.,-1.,-1.,-1. +}; + +ve_setup_data_template ve_setup_X_stereo={ + 11, + rate_mapping_X, + quality_mapping_44, + 2, + 50000, + 200000, + + blocksize_short_44, + blocksize_long_44, + + _psy_tone_masteratt_44, + _psy_tone_0dB, + _psy_tone_suppress, + + _vp_tonemask_adj_otherblock, + _vp_tonemask_adj_longblock, + _vp_tonemask_adj_otherblock, + + _psy_noiseguards_44, + _psy_noisebias_impulse, + _psy_noisebias_padding, + _psy_noisebias_trans, + _psy_noisebias_long, + _psy_noise_suppress, + + _psy_compand_44, + _psy_compand_short_mapping, + _psy_compand_long_mapping, + + {_noise_start_short_44,_noise_start_long_44}, + {_noise_part_short_44,_noise_part_long_44}, + _noise_thresh_44, + + _psy_ath_floater, + _psy_ath_abs, + + _psy_lowpass_44, + + _psy_global_44, + _global_mapping_44, + _psy_stereo_modes_44, + + _floor_books, + _floor, + _floor_short_mapping_44, + _floor_long_mapping_44, + + _mapres_template_44_stereo +}; + +ve_setup_data_template ve_setup_X_uncoupled={ + 11, + rate_mapping_X, + quality_mapping_44, + -1, + 50000, + 200000, + + blocksize_short_44, + blocksize_long_44, + + _psy_tone_masteratt_44, + _psy_tone_0dB, + _psy_tone_suppress, + + _vp_tonemask_adj_otherblock, + _vp_tonemask_adj_longblock, + _vp_tonemask_adj_otherblock, + + _psy_noiseguards_44, + _psy_noisebias_impulse, + _psy_noisebias_padding, + _psy_noisebias_trans, + _psy_noisebias_long, + _psy_noise_suppress, + + _psy_compand_44, + _psy_compand_short_mapping, + _psy_compand_long_mapping, + + {_noise_start_short_44,_noise_start_long_44}, + {_noise_part_short_44,_noise_part_long_44}, + _noise_thresh_44, + + _psy_ath_floater, + _psy_ath_abs, + + _psy_lowpass_44, + + _psy_global_44, + _global_mapping_44, + NULL, + + _floor_books, + _floor, + _floor_short_mapping_44, + _floor_long_mapping_44, + + _mapres_template_44_uncoupled +}; + +ve_setup_data_template ve_setup_XX_stereo={ + 2, + rate_mapping_X, + quality_mapping_8, + 2, + 0, + 8000, + + blocksize_8, + blocksize_8, + + _psy_tone_masteratt_8, + _psy_tone_0dB, + _psy_tone_suppress, + + _vp_tonemask_adj_8, + NULL, + _vp_tonemask_adj_8, + + _psy_noiseguards_8, + _psy_noisebias_8, + _psy_noisebias_8, + NULL, + NULL, + _psy_noise_suppress, + + _psy_compand_8, + _psy_compand_8_mapping, + NULL, + + {_noise_start_8,_noise_start_8}, + {_noise_part_8,_noise_part_8}, + _noise_thresh_5only, + + _psy_ath_floater_8, + _psy_ath_abs_8, + + _psy_lowpass_8, + + _psy_global_44, + _global_mapping_8, + _psy_stereo_modes_8, + + _floor_books, + _floor, + _floor_mapping_8, + NULL, + + _mapres_template_8_stereo +}; + +ve_setup_data_template ve_setup_XX_uncoupled={ + 2, + rate_mapping_X, + quality_mapping_8, + -1, + 0, + 8000, + + blocksize_8, + blocksize_8, + + _psy_tone_masteratt_8, + _psy_tone_0dB, + _psy_tone_suppress, + + _vp_tonemask_adj_8, + NULL, + _vp_tonemask_adj_8, + + _psy_noiseguards_8, + _psy_noisebias_8, + _psy_noisebias_8, + NULL, + NULL, + _psy_noise_suppress, + + _psy_compand_8, + _psy_compand_8_mapping, + NULL, + + {_noise_start_8,_noise_start_8}, + {_noise_part_8,_noise_part_8}, + _noise_thresh_5only, + + _psy_ath_floater_8, + _psy_ath_abs_8, + + _psy_lowpass_8, + + _psy_global_44, + _global_mapping_8, + _psy_stereo_modes_8, + + _floor_books, + _floor, + _floor_mapping_8, + NULL, + + _mapres_template_8_uncoupled +}; + diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/os.h b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/os.h new file mode 100644 index 0000000..1c5d722 --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/os.h @@ -0,0 +1,159 @@ +#ifndef _OS_H +#define _OS_H +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: #ifdef jail to whip a few platforms into the UNIX ideal. + last mod: $Id: os.h 7543 2004-08-13 01:48:19Z conrad $ + + ********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include "misc.h" + +#ifndef _V_IFDEFJAIL_H_ +# define _V_IFDEFJAIL_H_ + +# ifdef __GNUC__ +# define STIN static __inline__ +# elif _WIN32 +# define STIN static __inline +# else +# define STIN static +# endif + +#ifdef DJGPP +# define rint(x) (floor((x)+0.5f)) +#endif + +#ifndef M_PI +# define M_PI (3.1415926536f) +#endif + +#if defined(_WIN32) && !defined(__SYMBIAN32__) +# include +# define rint(x) (floor((x)+0.5f)) +# define NO_FLOAT_MATH_LIB +# define FAST_HYPOT(a, b) sqrt((a)*(a) + (b)*(b)) +#endif + +#if defined(__SYMBIAN32__) && defined(__WINS__) +void *_alloca(size_t size); +# define alloca _alloca +#endif + +#ifndef FAST_HYPOT +# define FAST_HYPOT hypot +#endif + +#endif + +#ifdef HAVE_ALLOCA_H +# include +#endif + +#ifdef USE_MEMORY_H +# include +#endif + +#ifndef min +# define min(x,y) ((x)>(y)?(y):(x)) +#endif + +#ifndef max +# define max(x,y) ((x)<(y)?(y):(x)) +#endif + +//Mark was here! +// +//Added the last !defined(__APPLE__) as this kills llvm! +// +#if defined(__i386__) && defined(__GNUC__) && !defined(__BEOS__) && !defined(__APPLE__) +# define VORBIS_FPU_CONTROL +/* both GCC and MSVC are kinda stupid about rounding/casting to int. + Because of encapsulation constraints (GCC can't see inside the asm + block and so we end up doing stupid things like a store/load that + is collectively a noop), we do it this way */ + +/* we must set up the fpu before this works!! */ + +typedef ogg_int16_t vorbis_fpu_control; + +static inline void vorbis_fpu_setround(vorbis_fpu_control *fpu){ + ogg_int16_t ret; + ogg_int16_t temp; + __asm__ __volatile__("fnstcw %0\n\t" + "movw %0,%%dx\n\t" + "orw $62463,%%dx\n\t" + "movw %%dx,%1\n\t" + "fldcw %1\n\t":"=m"(ret):"m"(temp): "dx"); + *fpu=ret; +} + +static inline void vorbis_fpu_restore(vorbis_fpu_control fpu){ + __asm__ __volatile__("fldcw %0":: "m"(fpu)); +} + +/* assumes the FPU is in round mode! */ +static inline int vorbis_ftoi(double f){ /* yes, double! Otherwise, + we get extra fst/fld to + truncate precision */ + int i; + __asm__("fistl %0": "=m"(i) : "t"(f)); + return(i); +} +#endif + +#if defined(_WIN32) && !defined(__GNUC__) && !defined(__BORLANDC__) +# define VORBIS_FPU_CONTROL + +typedef ogg_int16_t vorbis_fpu_control; + +static __inline int vorbis_ftoi(double f){ + int i; + __asm{ + fld f + fistp i + } + return i; +} + +static __inline void vorbis_fpu_setround(vorbis_fpu_control *fpu){ +} + +static __inline void vorbis_fpu_restore(vorbis_fpu_control fpu){ +} + +#endif + + +#ifndef VORBIS_FPU_CONTROL + +typedef int vorbis_fpu_control; + +static int vorbis_ftoi(double f){ + return (int)(f+.5); +} + +/* We don't have special code for this compiler/arch, so do it the slow way */ +# define vorbis_fpu_setround(vorbis_fpu_control) {} +# define vorbis_fpu_restore(vorbis_fpu_control) {} + +#endif + +#endif /* _OS_H */ diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/psy.c b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/psy.c new file mode 100644 index 0000000..a68eda6 --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/psy.c @@ -0,0 +1,1224 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: psychoacoustics not including preecho + last mod: $Id: psy.c 7187 2004-07-20 07:24:27Z xiphmont $ + + ********************************************************************/ + +#include +#include +#include +#include "vorbis/codec.h" +#include "codec_internal.h" + +#include "masking.h" +#include "psy.h" +#include "os.h" +#include "lpc.h" +#include "smallft.h" +#include "scales.h" +#include "misc.h" + +#define NEGINF -9999.f +static double stereo_threshholds[]={0.0, .5, 1.0, 1.5, 2.5, 4.5, 8.5, 16.5, 9e10}; +static double stereo_threshholds_limited[]={0.0, .5, 1.0, 1.5, 2.0, 2.5, 4.5, 8.5, 9e10}; + +vorbis_look_psy_global *_vp_global_look(vorbis_info *vi){ + codec_setup_info *ci=vi->codec_setup; + vorbis_info_psy_global *gi=&ci->psy_g_param; + vorbis_look_psy_global *look=_ogg_calloc(1,sizeof(*look)); + + look->channels=vi->channels; + + look->ampmax=-9999.; + look->gi=gi; + return(look); +} + +void _vp_global_free(vorbis_look_psy_global *look){ + if(look){ + memset(look,0,sizeof(*look)); + _ogg_free(look); + } +} + +void _vi_gpsy_free(vorbis_info_psy_global *i){ + if(i){ + memset(i,0,sizeof(*i)); + _ogg_free(i); + } +} + +void _vi_psy_free(vorbis_info_psy *i){ + if(i){ + memset(i,0,sizeof(*i)); + _ogg_free(i); + } +} + +static void min_curve(float *c, + float *c2){ + int i; + for(i=0;ic[i])c[i]=c2[i]; +} + +static void attenuate_curve(float *c,float att){ + int i; + for(i=0;iATH[j+k+ath_offset])min=ATH[j+k+ath_offset]; + }else{ + if(min>ATH[MAX_ATH-1])min=ATH[MAX_ATH-1]; + } + ath[j]=min; + } + + /* copy curves into working space, replicate the 50dB curve to 30 + and 40, replicate the 100dB curve to 110 */ + for(j=0;j<6;j++) + memcpy(workc[i][j+2],tonemasks[i][j],EHMER_MAX*sizeof(*tonemasks[i][j])); + memcpy(workc[i][0],tonemasks[i][0],EHMER_MAX*sizeof(*tonemasks[i][0])); + memcpy(workc[i][1],tonemasks[i][0],EHMER_MAX*sizeof(*tonemasks[i][0])); + + /* apply centered curve boost/decay */ + for(j=0;j0)adj=0.; + if(adj>0. && center_boost<0)adj=0.; + workc[i][j][k]+=adj; + } + } + + /* normalize curves so the driving amplitude is 0dB */ + /* make temp curves with the ATH overlayed */ + for(j=0;j an eighth of an octave and that the eighth + octave values may also be composited. */ + + /* which octave curves will we be compositing? */ + bin=floor(fromOC(i*.5)/binHz); + lo_curve= ceil(toOC(bin*binHz+1)*2); + hi_curve= floor(toOC((bin+1)*binHz)*2); + if(lo_curve>i)lo_curve=i; + if(lo_curve<0)lo_curve=0; + if(hi_curve>=P_BANDS)hi_curve=P_BANDS-1; + + for(m=0;mn)lo_bin=n; + if(lo_binn)hi_bin=n; + + for(;lworkc[k][m][j]) + brute_buffer[l]=workc[k][m][j]; + } + + for(;lworkc[k][m][EHMER_MAX-1]) + brute_buffer[l]=workc[k][m][EHMER_MAX-1]; + + } + + /* be equally paranoid about being valid up to next half ocatve */ + if(i+1n)lo_bin=n; + if(lo_binn)hi_bin=n; + + for(;lworkc[k][m][j]) + brute_buffer[l]=workc[k][m][j]; + } + + for(;lworkc[k][m][EHMER_MAX-1]) + brute_buffer[l]=workc[k][m][EHMER_MAX-1]; + + } + + + for(j=0;j=n){ + ret[i][m][j+2]=-999.; + }else{ + ret[i][m][j+2]=brute_buffer[bin]; + } + } + } + + /* add fenceposts */ + for(j=0;j-200.f)break; + ret[i][m][0]=j; + + for(j=EHMER_MAX-1;j>EHMER_OFFSET+1;j--) + if(ret[i][m][j+2]>-200.f) + break; + ret[i][m][1]=j; + + } + } + + return(ret); +} + +void _vp_psy_init(vorbis_look_psy *p,vorbis_info_psy *vi, + vorbis_info_psy_global *gi,int n,long rate){ + long i,j,lo=-99,hi=1; + long maxoc; + memset(p,0,sizeof(*p)); + + p->eighth_octave_lines=gi->eighth_octave_lines; + p->shiftoc=rint(log(gi->eighth_octave_lines*8.f)/log(2.f))-1; + + p->firstoc=toOC(.25f*rate*.5/n)*(1<<(p->shiftoc+1))-gi->eighth_octave_lines; + maxoc=toOC((n+.25f)*rate*.5/n)*(1<<(p->shiftoc+1))+.5f; + p->total_octave_lines=maxoc-p->firstoc+1; + p->ath=_ogg_malloc(n*sizeof(*p->ath)); + + p->octave=_ogg_malloc(n*sizeof(*p->octave)); + p->bark=_ogg_malloc(n*sizeof(*p->bark)); + p->vi=vi; + p->n=n; + p->rate=rate; + + /* AoTuV HF weighting */ + p->m_val = 1.; + if(rate < 26000) p->m_val = 0; + else if(rate < 38000) p->m_val = .94; /* 32kHz */ + else if(rate > 46000) p->m_val = 1.275; /* 48kHz */ + + /* set up the lookups for a given blocksize and sample rate */ + + for(i=0,j=0;iath[j]=base+100.; + base+=delta; + } + } + } + + for(i=0;inoisewindowlominnoisewindowlo);lo++); + + for(;hi<=n && (hinoisewindowhimin || + toBARK(rate/(2*n)*hi)<(bark+vi->noisewindowhi));hi++); + + p->bark[i]=((lo-1)<<16)+(hi-1); + + } + + for(i=0;ioctave[i]=toOC((i+.25f)*.5*rate/n)*(1<<(p->shiftoc+1))+.5f; + + p->tonecurves=setup_tone_curves(vi->toneatt,rate*.5/n,n, + vi->tone_centerboost,vi->tone_decay); + + /* set up rolling noise median */ + p->noiseoffset=_ogg_malloc(P_NOISECURVES*sizeof(*p->noiseoffset)); + for(i=0;inoiseoffset[i]=_ogg_malloc(n*sizeof(**p->noiseoffset)); + + for(i=0;i=P_BANDS-1)halfoc=P_BANDS-1; + inthalfoc=(int)halfoc; + del=halfoc-inthalfoc; + + for(j=0;jnoiseoffset[j][i]= + p->vi->noiseoff[j][inthalfoc]*(1.-del) + + p->vi->noiseoff[j][inthalfoc+1]*del; + + } +#if 0 + { + static int ls=0; + _analysis_output_always("noiseoff0",ls,p->noiseoffset[0],n,1,0,0); + _analysis_output_always("noiseoff1",ls,p->noiseoffset[1],n,1,0,0); + _analysis_output_always("noiseoff2",ls++,p->noiseoffset[2],n,1,0,0); + } +#endif +} + +void _vp_psy_clear(vorbis_look_psy *p){ + int i,j; + if(p){ + if(p->ath)_ogg_free(p->ath); + if(p->octave)_ogg_free(p->octave); + if(p->bark)_ogg_free(p->bark); + if(p->tonecurves){ + for(i=0;itonecurves[i][j]); + } + _ogg_free(p->tonecurves[i]); + } + _ogg_free(p->tonecurves); + } + if(p->noiseoffset){ + for(i=0;inoiseoffset[i]); + } + _ogg_free(p->noiseoffset); + } + memset(p,0,sizeof(*p)); + } +} + +/* octave/(8*eighth_octave_lines) x scale and dB y scale */ +static void seed_curve(float *seed, + const float **curves, + float amp, + int oc, int n, + int linesper,float dBoffset){ + int i,post1; + int seedptr; + const float *posts,*curve; + + int choice=(int)((amp+dBoffset-P_LEVEL_0)*.1f); + choice=max(choice,0); + choice=min(choice,P_LEVELS-1); + posts=curves[choice]; + curve=posts+2; + post1=(int)posts[1]; + seedptr=oc+(posts[0]-EHMER_OFFSET)*linesper-(linesper>>1); + + for(i=posts[0];i0){ + float lin=amp+curve[i]; + if(seed[seedptr]=n)break; + } +} + +static void seed_loop(vorbis_look_psy *p, + const float ***curves, + const float *f, + const float *flr, + float *seed, + float specmax){ + vorbis_info_psy *vi=p->vi; + long n=p->n,i; + float dBoffset=vi->max_curve_dB-specmax; + + /* prime the working vector with peak values */ + + for(i=0;ioctave[i]; + while(i+1octave[i+1]==oc){ + i++; + if(f[i]>max)max=f[i]; + } + + if(max+6.f>flr[i]){ + oc=oc>>p->shiftoc; + + if(oc>=P_BANDS)oc=P_BANDS-1; + if(oc<0)oc=0; + + seed_curve(seed, + curves[oc], + max, + p->octave[i]-p->firstoc, + p->total_octave_lines, + p->eighth_octave_lines, + dBoffset); + } + } +} + +static void seed_chase(float *seeds, int linesper, long n){ + long *posstack=alloca(n*sizeof(*posstack)); + float *ampstack=alloca(n*sizeof(*ampstack)); + long stack=0; + long pos=0; + long i; + + for(i=0;i1 && ampstack[stack-1]<=ampstack[stack-2] && + iampstack[i]){ + endpos=posstack[i+1]; + }else{ + endpos=posstack[i]+linesper+1; /* +1 is important, else bin 0 is + discarded in short frames */ + } + if(endpos>n)endpos=n; + for(;pos +static void max_seeds(vorbis_look_psy *p, + float *seed, + float *flr){ + long n=p->total_octave_lines; + int linesper=p->eighth_octave_lines; + long linpos=0; + long pos; + + seed_chase(seed,linesper,n); /* for masking */ + + pos=p->octave[0]-p->firstoc-(linesper>>1); + + while(linpos+1n){ + float minV=seed[pos]; + long end=((p->octave[linpos]+p->octave[linpos+1])>>1)-p->firstoc; + if(minV>p->vi->tone_abs_limit)minV=p->vi->tone_abs_limit; + while(pos+1<=end){ + pos++; + if((seed[pos]>NEGINF && seed[pos]firstoc; + for(;linposn && p->octave[linpos]<=end;linpos++) + if(flr[linpos]total_octave_lines-1]; + for(;linposn;linpos++) + if(flr[linpos]> 16; + if( lo>=0 ) break; + hi = b[i] & 0xffff; + + tN = N[hi] + N[-lo]; + tX = X[hi] - X[-lo]; + tXX = XX[hi] + XX[-lo]; + tY = Y[hi] + Y[-lo]; + tXY = XY[hi] - XY[-lo]; + + A = tY * tXX - tX * tXY; + B = tN * tXY - tX * tY; + D = tN * tXX - tX * tX; + R = (A + x * B) / D; + if (R < 0.f) + R = 0.f; + + noise[i] = R - offset; + } + + for ( ;; i++, x += 1.f) { + + lo = b[i] >> 16; + hi = b[i] & 0xffff; + if(hi>=n)break; + + tN = N[hi] - N[lo]; + tX = X[hi] - X[lo]; + tXX = XX[hi] - XX[lo]; + tY = Y[hi] - Y[lo]; + tXY = XY[hi] - XY[lo]; + + A = tY * tXX - tX * tXY; + B = tN * tXY - tX * tY; + D = tN * tXX - tX * tX; + R = (A + x * B) / D; + if (R < 0.f) R = 0.f; + + noise[i] = R - offset; + } + for ( ; i < n; i++, x += 1.f) { + + R = (A + x * B) / D; + if (R < 0.f) R = 0.f; + + noise[i] = R - offset; + } + + if (fixed <= 0) return; + + for (i = 0, x = 0.f;; i++, x += 1.f) { + hi = i + fixed / 2; + lo = hi - fixed; + if(lo>=0)break; + + tN = N[hi] + N[-lo]; + tX = X[hi] - X[-lo]; + tXX = XX[hi] + XX[-lo]; + tY = Y[hi] + Y[-lo]; + tXY = XY[hi] - XY[-lo]; + + + A = tY * tXX - tX * tXY; + B = tN * tXY - tX * tY; + D = tN * tXX - tX * tX; + R = (A + x * B) / D; + + if (R - offset < noise[i]) noise[i] = R - offset; + } + for ( ;; i++, x += 1.f) { + + hi = i + fixed / 2; + lo = hi - fixed; + if(hi>=n)break; + + tN = N[hi] - N[lo]; + tX = X[hi] - X[lo]; + tXX = XX[hi] - XX[lo]; + tY = Y[hi] - Y[lo]; + tXY = XY[hi] - XY[lo]; + + A = tY * tXX - tX * tXY; + B = tN * tXY - tX * tY; + D = tN * tXX - tX * tX; + R = (A + x * B) / D; + + if (R - offset < noise[i]) noise[i] = R - offset; + } + for ( ; i < n; i++, x += 1.f) { + R = (A + x * B) / D; + if (R - offset < noise[i]) noise[i] = R - offset; + } +} + +static float FLOOR1_fromdB_INV_LOOKUP[256]={ + 0.F, 8.81683e+06F, 8.27882e+06F, 7.77365e+06F, + 7.29930e+06F, 6.85389e+06F, 6.43567e+06F, 6.04296e+06F, + 5.67422e+06F, 5.32798e+06F, 5.00286e+06F, 4.69759e+06F, + 4.41094e+06F, 4.14178e+06F, 3.88905e+06F, 3.65174e+06F, + 3.42891e+06F, 3.21968e+06F, 3.02321e+06F, 2.83873e+06F, + 2.66551e+06F, 2.50286e+06F, 2.35014e+06F, 2.20673e+06F, + 2.07208e+06F, 1.94564e+06F, 1.82692e+06F, 1.71544e+06F, + 1.61076e+06F, 1.51247e+06F, 1.42018e+06F, 1.33352e+06F, + 1.25215e+06F, 1.17574e+06F, 1.10400e+06F, 1.03663e+06F, + 973377.F, 913981.F, 858210.F, 805842.F, + 756669.F, 710497.F, 667142.F, 626433.F, + 588208.F, 552316.F, 518613.F, 486967.F, + 457252.F, 429351.F, 403152.F, 378551.F, + 355452.F, 333762.F, 313396.F, 294273.F, + 276316.F, 259455.F, 243623.F, 228757.F, + 214798.F, 201691.F, 189384.F, 177828.F, + 166977.F, 156788.F, 147221.F, 138237.F, + 129802.F, 121881.F, 114444.F, 107461.F, + 100903.F, 94746.3F, 88964.9F, 83536.2F, + 78438.8F, 73652.5F, 69158.2F, 64938.1F, + 60975.6F, 57254.9F, 53761.2F, 50480.6F, + 47400.3F, 44507.9F, 41792.0F, 39241.9F, + 36847.3F, 34598.9F, 32487.7F, 30505.3F, + 28643.8F, 26896.0F, 25254.8F, 23713.7F, + 22266.7F, 20908.0F, 19632.2F, 18434.2F, + 17309.4F, 16253.1F, 15261.4F, 14330.1F, + 13455.7F, 12634.6F, 11863.7F, 11139.7F, + 10460.0F, 9821.72F, 9222.39F, 8659.64F, + 8131.23F, 7635.06F, 7169.17F, 6731.70F, + 6320.93F, 5935.23F, 5573.06F, 5232.99F, + 4913.67F, 4613.84F, 4332.30F, 4067.94F, + 3819.72F, 3586.64F, 3367.78F, 3162.28F, + 2969.31F, 2788.13F, 2617.99F, 2458.24F, + 2308.24F, 2167.39F, 2035.14F, 1910.95F, + 1794.35F, 1684.85F, 1582.04F, 1485.51F, + 1394.86F, 1309.75F, 1229.83F, 1154.78F, + 1084.32F, 1018.15F, 956.024F, 897.687F, + 842.910F, 791.475F, 743.179F, 697.830F, + 655.249F, 615.265F, 577.722F, 542.469F, + 509.367F, 478.286F, 449.101F, 421.696F, + 395.964F, 371.803F, 349.115F, 327.812F, + 307.809F, 289.026F, 271.390F, 254.830F, + 239.280F, 224.679F, 210.969F, 198.096F, + 186.008F, 174.658F, 164.000F, 153.993F, + 144.596F, 135.773F, 127.488F, 119.708F, + 112.404F, 105.545F, 99.1046F, 93.0572F, + 87.3788F, 82.0469F, 77.0404F, 72.3394F, + 67.9252F, 63.7804F, 59.8885F, 56.2341F, + 52.8027F, 49.5807F, 46.5553F, 43.7144F, + 41.0470F, 38.5423F, 36.1904F, 33.9821F, + 31.9085F, 29.9614F, 28.1332F, 26.4165F, + 24.8045F, 23.2910F, 21.8697F, 20.5352F, + 19.2822F, 18.1056F, 17.0008F, 15.9634F, + 14.9893F, 14.0746F, 13.2158F, 12.4094F, + 11.6522F, 10.9411F, 10.2735F, 9.64662F, + 9.05798F, 8.50526F, 7.98626F, 7.49894F, + 7.04135F, 6.61169F, 6.20824F, 5.82941F, + 5.47370F, 5.13970F, 4.82607F, 4.53158F, + 4.25507F, 3.99542F, 3.75162F, 3.52269F, + 3.30774F, 3.10590F, 2.91638F, 2.73842F, + 2.57132F, 2.41442F, 2.26709F, 2.12875F, + 1.99885F, 1.87688F, 1.76236F, 1.65482F, + 1.55384F, 1.45902F, 1.36999F, 1.28640F, + 1.20790F, 1.13419F, 1.06499F, 1.F +}; + +void _vp_remove_floor(vorbis_look_psy *p, + float *mdct, + int *codedflr, + float *residue, + int sliding_lowpass){ + + int i,n=p->n; + + if(sliding_lowpass>n)sliding_lowpass=n; + + for(i=0;in; + float *work=alloca(n*sizeof(*work)); + + bark_noise_hybridmp(n,p->bark,logmdct,logmask, + 140.,-1); + + for(i=0;ibark,work,logmask,0., + p->vi->noisewindowfixed); + + for(i=0;i=NOISE_COMPAND_LEVELS)dB=NOISE_COMPAND_LEVELS-1; + if(dB<0)dB=0; + logmask[i]= work[i]+p->vi->noisecompand[dB]; + } + +} + +void _vp_tonemask(vorbis_look_psy *p, + float *logfft, + float *logmask, + float global_specmax, + float local_specmax){ + + int i,n=p->n; + + float *seed=alloca(sizeof(*seed)*p->total_octave_lines); + float att=local_specmax+p->vi->ath_adjatt; + for(i=0;itotal_octave_lines;i++)seed[i]=NEGINF; + + /* set the ATH (floating below localmax, not global max by a + specified att) */ + if(attvi->ath_maxatt)att=p->vi->ath_maxatt; + + for(i=0;iath[i]+att; + + /* tone masking */ + seed_loop(p,(const float ***)p->tonecurves,logfft,logmask,seed,global_specmax); + max_seeds(p,seed,logmask); + +} + +void _vp_offset_and_mix(vorbis_look_psy *p, + float *noise, + float *tone, + int offset_select, + float *logmask, + float *mdct, + float *logmdct){ + int i,n=p->n; + float de, coeffi, cx;/* AoTuV */ + float toneatt=p->vi->tone_masteratt[offset_select]; + + cx = p->m_val; + + for(i=0;inoiseoffset[offset_select][i]; + if(val>p->vi->noisemaxsupp)val=p->vi->noisemaxsupp; + logmask[i]=max(val,tone[i]+toneatt); + + + /* AoTuV */ + /** @ M1 ** + The following codes improve a noise problem. + A fundamental idea uses the value of masking and carries out + the relative compensation of the MDCT. + However, this code is not perfect and all noise problems cannot be solved. + by Aoyumi @ 2004/04/18 + */ + + if(offset_select == 1) { + coeffi = -17.2; /* coeffi is a -17.2dB threshold */ + val = val - logmdct[i]; /* val == mdct line value relative to floor in dB */ + + if(val > coeffi){ + /* mdct value is > -17.2 dB below floor */ + + de = 1.0-((val-coeffi)*0.005*cx); + /* pro-rated attenuation: + -0.00 dB boost if mdct value is -17.2dB (relative to floor) + -0.77 dB boost if mdct value is 0dB (relative to floor) + -1.64 dB boost if mdct value is +17.2dB (relative to floor) + etc... */ + + if(de < 0) de = 0.0001; + }else + /* mdct value is <= -17.2 dB below floor */ + + de = 1.0-((val-coeffi)*0.0003*cx); + /* pro-rated attenuation: + +0.00 dB atten if mdct value is -17.2dB (relative to floor) + +0.45 dB atten if mdct value is -34.4dB (relative to floor) + etc... */ + + mdct[i] *= de; + + } + } +} + +float _vp_ampmax_decay(float amp,vorbis_dsp_state *vd){ + vorbis_info *vi=vd->vi; + codec_setup_info *ci=vi->codec_setup; + vorbis_info_psy_global *gi=&ci->psy_g_param; + + int n=ci->blocksizes[vd->W]/2; + float secs=(float)n/vi->rate; + + amp+=secs*gi->ampmax_att_per_sec; + if(amp<-9999)amp=-9999; + return(amp); +} + +static void couple_lossless(float A, float B, + float *qA, float *qB){ + int test1=fabs(*qA)>fabs(*qB); + test1-= fabs(*qA)fabs(B))<<1)-1; + if(test1==1){ + *qB=(*qA>0.f?*qA-*qB:*qB-*qA); + }else{ + float temp=*qB; + *qB=(*qB>0.f?*qA-*qB:*qB-*qA); + *qA=temp; + } + + if(*qB>fabs(*qA)*1.9999f){ + *qB= -fabs(*qA)*2.f; + *qA= -*qA; + } +} + +static float hypot_lookup[32]={ + -0.009935, -0.011245, -0.012726, -0.014397, + -0.016282, -0.018407, -0.020800, -0.023494, + -0.026522, -0.029923, -0.033737, -0.038010, + -0.042787, -0.048121, -0.054064, -0.060671, + -0.068000, -0.076109, -0.085054, -0.094892, + -0.105675, -0.117451, -0.130260, -0.144134, + -0.159093, -0.175146, -0.192286, -0.210490, + -0.229718, -0.249913, -0.271001, -0.292893}; + +static void precomputed_couple_point(float premag, + int floorA,int floorB, + float *mag, float *ang){ + + int test=(floorA>floorB)-1; + int offset=31-abs(floorA-floorB); + float floormag=hypot_lookup[((offset<0)-1)&offset]+1.f; + + floormag*=FLOOR1_fromdB_INV_LOOKUP[(floorB&test)|(floorA&(~test))]; + + *mag=premag*floormag; + *ang=0.f; +} + +/* just like below, this is currently set up to only do + single-step-depth coupling. Otherwise, we'd have to do more + copying (which will be inevitable later) */ + +/* doing the real circular magnitude calculation is audibly superior + to (A+B)/sqrt(2) */ +static float dipole_hypot(float a, float b){ + if(a>0.){ + if(b>0.)return sqrt(a*a+b*b); + if(a>-b)return sqrt(a*a-b*b); + return -sqrt(b*b-a*a); + } + if(b<0.)return -sqrt(a*a+b*b); + if(-a>b)return -sqrt(a*a-b*b); + return sqrt(b*b-a*a); +} +static float round_hypot(float a, float b){ + if(a>0.){ + if(b>0.)return sqrt(a*a+b*b); + if(a>-b)return sqrt(a*a+b*b); + return -sqrt(b*b+a*a); + } + if(b<0.)return -sqrt(a*a+b*b); + if(-a>b)return -sqrt(a*a+b*b); + return sqrt(b*b+a*a); +} + +/* revert to round hypot for now */ +float **_vp_quantize_couple_memo(vorbis_block *vb, + vorbis_info_psy_global *g, + vorbis_look_psy *p, + vorbis_info_mapping0 *vi, + float **mdct){ + + int i,j,n=p->n; + float **ret=_vorbis_block_alloc(vb,vi->coupling_steps*sizeof(*ret)); + int limit=g->coupling_pointlimit[p->vi->blockflag][PACKETBLOBS/2]; + + for(i=0;icoupling_steps;i++){ + float *mdctM=mdct[vi->coupling_mag[i]]; + float *mdctA=mdct[vi->coupling_ang[i]]; + ret[i]=_vorbis_block_alloc(vb,n*sizeof(**ret)); + for(j=0;jf2); +} + +int **_vp_quantize_couple_sort(vorbis_block *vb, + vorbis_look_psy *p, + vorbis_info_mapping0 *vi, + float **mags){ + + + if(p->vi->normal_point_p){ + int i,j,k,n=p->n; + int **ret=_vorbis_block_alloc(vb,vi->coupling_steps*sizeof(*ret)); + int partition=p->vi->normal_partition; + float **work=alloca(sizeof(*work)*partition); + + for(i=0;icoupling_steps;i++){ + ret[i]=_vorbis_block_alloc(vb,n*sizeof(**ret)); + + for(j=0;jn; + vorbis_info_psy *vi=p->vi; + int partition=vi->normal_partition; + float **work=alloca(sizeof(*work)*partition); + int start=vi->normal_start; + + for(j=start;jn)partition=n-j; + for(i=0;in; + vorbis_info_psy *vi=p->vi; + int partition=vi->normal_partition; + int start=vi->normal_start; + + if(start>n)start=n; + + if(vi->normal_channel_p){ + for(;j=.25f){ + out[k]=rint(in[k]); + acc-=in[k]*in[k]; + flag=1; + }else{ + if(accnormal_thresh)break; + out[k]=unitnorm(in[k]); + acc-=1.; + } + } + + for(;in; + + /* perform any requested channel coupling */ + /* point stereo can only be used in a first stage (in this encoder) + because of the dependency on floor lookups */ + for(i=0;icoupling_steps;i++){ + + /* once we're doing multistage coupling in which a channel goes + through more than one coupling step, the floor vector + magnitudes will also have to be recalculated an propogated + along with PCM. Right now, we're not (that will wait until 5.1 + most likely), so the code isn't here yet. The memory management + here is all assuming single depth couplings anyway. */ + + /* make sure coupling a zero and a nonzero channel results in two + nonzero channels. */ + if(nonzero[vi->coupling_mag[i]] || + nonzero[vi->coupling_ang[i]]){ + + + float *rM=res[vi->coupling_mag[i]]; + float *rA=res[vi->coupling_ang[i]]; + float *qM=rM+n; + float *qA=rA+n; + int *floorM=ifloor[vi->coupling_mag[i]]; + int *floorA=ifloor[vi->coupling_ang[i]]; + float prepoint=stereo_threshholds[g->coupling_prepointamp[blobno]]; + float postpoint=stereo_threshholds[g->coupling_postpointamp[blobno]]; + int partition=(p->vi->normal_point_p?p->vi->normal_partition:p->n); + int limit=g->coupling_pointlimit[p->vi->blockflag][blobno]; + int pointlimit=limit; + + nonzero[vi->coupling_mag[i]]=1; + nonzero[vi->coupling_ang[i]]=1; + + /* The threshold of a stereo is changed with the size of n */ + if(n > 1000) + postpoint=stereo_threshholds_limited[g->coupling_postpointamp[blobno]]; + + for(j=0;jn;j+=partition){ + float acc=0.f; + + for(k=0;k=limit && fabs(rM[l])vi->normal_point_p){ + for(k=0;k=p->vi->normal_thresh;k++){ + int l=mag_sort[i][j+k]; + if(l=pointlimit && rint(qM[l])==0.f){ + qM[l]=unitnorm(qM[l]); + acc-=1.f; + } + } + } + } + } + } +} + +/* AoTuV */ +/** @ M2 ** + The boost problem by the combination of noise normalization and point stereo is eased. + However, this is a temporary patch. + by Aoyumi @ 2004/04/18 +*/ + +void hf_reduction(vorbis_info_psy_global *g, + vorbis_look_psy *p, + vorbis_info_mapping0 *vi, + float **mdct){ + + int i,j,n=p->n, de=0.3*p->m_val; + int limit=g->coupling_pointlimit[p->vi->blockflag][PACKETBLOBS/2]; + int start=p->vi->normal_start; + + for(i=0; icoupling_steps; i++){ + /* for(j=start; j +#include +#include +#include + +#include "vorbis/codec.h" +#include "codec_internal.h" +#include "os.h" +#include "misc.h" +#include "psy.h" +#include "mdct.h" +#include "smallft.h" +#include "window.h" +#include "scales.h" +#include "lpc.h" +#include "lsp.h" +#include "masking.h" +#include "registry.h" + +static vorbis_info_psy_global _psy_set0G={ + 0, /* decaydBpms */ + 8, /* lines per eighth octave */ + + /* thresh sample period, preecho clamp trigger threshhold, range, minenergy */ + 256, {26.f,26.f,26.f,30.f}, {-90.f,-90.f,-90.f,-90.f}, -90.f, + -6.f, + + 0, + + 0., + 0., +}; + +static vp_part _vp_part0[]={ + { 1,9e10f, 9e10f, 1.f,9999.f}, + { 9999, .75f, 9e10f, .5f,9999.f}, +/*{ 9999, 1.5f, 9e10f, .5f,9999.f},*/ + { 18,9e10f, 9e10f, .5f, 30.f}, + { 9999,9e10f, 9e10f, .5f, 30.f} +}; + +static vp_couple _vp_couple0[]={ + { 1, {9e10f,9e10f,0}, { 0.f, 0.f,0}, { 0.f, 0.f,0}, {0.f,0.f,0}}, + { 18, {9e10f,9e10f,0}, { 0.f, 0.f,0}, { 0.f, 0.f,0}, {0.f,0.f,0}}, + { 9999, {9e10f,9e10f,0}, { 0.f, 9e10f,0}, { 0.f,22.f,1}, {0.f,0.f,0}} +}; + +static vorbis_info_psy _psy_set0={ + ATH_Bark_dB_lineaggressive, + + -100.f, + -140.f, + 6.f, /* floor master att */ + + /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 */ + /* x: 63 88 125 175 250 350 500 700 1k 1.4k 2k 2.8k 4k 5.6k 8k 11.5k 16k Hz */ + /* y: 0 10 20 30 40 50 60 70 80 90 100 dB */ + 1, /* tonemaskp */ + 0.f, /* tone master att */ + /* 0 10 20 30 40 50 60 70 80 90 100 */ + { + {-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f}, /*63*/ + {-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f}, /*88*/ + {-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f}, /*125*/ + + {-30.f,-30.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*175*/ + {-30.f,-30.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*250*/ + {-30.f,-30.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*350*/ + {-30.f,-30.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*500*/ + {-30.f,-30.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*700*/ + {-30.f,-30.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*1000*/ + {-30.f,-30.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*1400*/ + {-40.f,-40.f,-40.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*2000*/ + {-40.f,-40.f,-40.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*2800*/ + {-40.f,-40.f,-40.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*4000*/ + + {-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*5600*/ + + {-30.f,-30.f,-33.f,-35.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*8000*/ + {-30.f,-30.f,-33.f,-35.f,-40.f,-45.f,-50.f,-60.f,-70.f,-85.f,-100.f}, /*11500*/ + {-24.f,-24.f,-26.f,-32.f,-32.f,-42.f,-50.f,-60.f,-70.f,-85.f,-100.f}, /*16000*/ + + }, + + 1,/* peakattp */ + {{-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*63*/ + {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*88*/ + {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*125*/ + {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*175*/ + {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*250*/ + {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*350*/ + {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*500*/ + {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*700*/ + {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*1000*/ + {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*1400*/ + {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*2000*/ + {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*2800*/ + {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*4000*/ + {-10.f,-12.f,-14.f,-16.f,-16.f,-20.f,-24.f,-30.f,-32.f,-40.f,-40.f},/*5600*/ + {-10.f,-12.f,-14.f,-16.f,-16.f,-20.f,-24.f,-30.f,-32.f,-40.f,-40.f},/*8000*/ + {-10.f,-10.f,-10.f,-12.f,-14.f,-18.f,-22.f,-28.f,-32.f,-40.f,-40.f},/*11500*/ + {-10.f,-10.f,-10.f,-12.f,-14.f,-18.f,-22.f,-28.f,-32.f,-40.f,-40.f},/*16000*/ + }, + + 1,/*noisemaskp */ + -10.f, /* suppress any noise curve over maxspec+n */ + .5f, /* low window */ + .5f, /* high window */ + 10, + 10, + 25, + {.000f, 0.f, /*63*/ + .000f, 0.f, /*88*/ + .000f, 0.f, /*125*/ + .000f, 0.f, /*175*/ + .000f, 0.f, /*250*/ + .000f, 0.f, /*350*/ + .000f, 0.f, /*500*/ + .000f, 0.f, /*700*/ + .000f, 0.f, /*1000*/ + .300f, 0.f, /*1400*/ + .300f, 0.f, /*2000*/ + .300f, 0.f, /*2800*/ + .500f, 0.f, /*4000*/ + .700f, 0.f, /*5600*/ + .850f, 0.f, /*8000*/ + .900f, 0.f, /*11500*/ + .900f, 1.f, /*16000*/ + }, + + 95.f, /* even decade + 5 is important; saves an rint() later in a + tight loop) */ + -44., + + 32, + _vp_part0,_vp_couple0 +}; + +static vorbis_info_floor1 _floor_set0={1, + {0}, + + {32}, + {0}, + {0}, + {{-1}}, + + 2, + {0,1024, + + 88,31,243, + + 14,54,143,460, + + 6,3,10, 22,18,26, 41,36,47, + 69,61,78, 112,99,126, 185,162,211, + 329,282,387, 672,553,825 + }, + + 60,30,400, + 20,8,1,18., + 20,600, + 960}; + + +static vorbis_info_mapping0 mapping_info={1,{0,1},{0},{0},{0},0, 1, {0},{1}}; +static codec_setup_info codec_setup0={ {0,0}, + 1,1,1,1,1,0,1, + {NULL}, + {0},{&mapping_info}, + {0},{NULL}, + {1},{&_floor_set0}, + {2},{NULL}, + {NULL}, + {&_psy_set0}, + &_psy_set0G}; + +static int noisy=0; +void analysis(char *base,int i,float *v,int n,int bark,int dB){ + if(noisy){ + int j; + FILE *of; + char buffer[80]; + sprintf(buffer,"%s_%d.m",base,i); + of=fopen(buffer,"w"); + + for(j=0;jlook(NULL,NULL,&_floor_set0); + + /* we cheat on the WAV header; we just bypass 44 bytes and never + verify that it matches 16bit/stereo/44.1kHz. */ + + fread(buffer,1,44,stdin); + fwrite(buffer,1,44,stdout); + memset(buffer,0,framesize*2); + + analysis("window",0,window,framesize,0,0); + + fprintf(stderr,"Processing for frame size %d...\n",framesize); + + while(!eos){ + long bytes=fread(buffer2,1,framesize*2,stdin); + if(bytes>1]=todB(&temp); + if(temp>local_ampmax[i])local_ampmax[i]=temp; + } + if(local_ampmax[i]>ampmax)ampmax=local_ampmax[i]; + + mdct_forward(&m_look,pcm[i],mdct); + for(j=0;jforward(&vb,floor_look, + mdct, + logmdct, + mask, + logmax, + + flr[i]); + } + + _vp_remove_floor(&p_look, + pg_look, + logmdct, + mdct, + flr[i], + pcm[i], + local_ampmax[i]); + + for(j=0;j1500) + fprintf(stderr,"%ld ",frameno+i); + + analysis("res",frameno+i,pcm[i],framesize/2,1,0); + analysis("codedflr",frameno+i,flr[i],framesize/2,1,1); + } + + /* residue prequantization */ + _vp_partition_prequant(&p_look, + &vi, + pcm, + nonzero); + + for(i=0;i<2;i++) + analysis("quant",frameno+i,pcm[i],framesize/2,1,0); + + /* channel coupling / stereo quantization */ + + _vp_couple(&p_look, + &mapping_info, + pcm, + nonzero); + + for(i=0;i<2;i++) + analysis("coupled",frameno+i,pcm[i],framesize/2,1,0); + + /* decoupling */ + for(i=mapping_info.coupling_steps-1;i>=0;i--){ + float *pcmM=pcm[mapping_info.coupling_mag[i]]; + float *pcmA=pcm[mapping_info.coupling_ang[i]]; + + for(j=0;j0) + if(ang>0){ + pcmM[j]=mag; + pcmA[j]=mag-ang; + }else{ + pcmA[j]=mag; + pcmM[j]=mag+ang; + } + else + if(ang>0){ + pcmM[j]=mag; + pcmA[j]=mag+ang; + }else{ + pcmA[j]=mag; + pcmM[j]=mag-ang; + } + } + } + + for(i=0;i<2;i++) + analysis("decoupled",frameno+i,pcm[i],framesize/2,1,0); + + for(i=0;i<2;i++){ + float amp; + + for(j=0;j32767){ + if(!flag)fprintf(stderr,"clipping in frame %ld ",frameno+i); + flag=1; + val=32767; + } + if(val<-32768){ + if(!flag)fprintf(stderr,"clipping in frame %ld ",frameno+i); + flag=1; + val=-32768; + } + ptr[0]=val&0xff; + ptr[1]=(val>>8)&0xff; + ptr+=4; + } + } + + fprintf(stderr,"*"); + fwrite(buffer,1,framesize*2,stdout); + memmove(buffer,buffer2,framesize*2); + + for(i=0;i<2;i++){ + for(j=0,k=framesize/2;j +#include +#include +#include +#include "vorbis/codec.h" +#include "codec_internal.h" +#include "registry.h" +#include "codebook.h" +#include "misc.h" +#include "os.h" + +#if defined(TRAIN_RES) || defined (TRAIN_RESAUX) +#include +#endif + +typedef struct { + vorbis_info_residue0 *info; + + int parts; + int stages; + codebook *fullbooks; + codebook *phrasebook; + codebook ***partbooks; + + int partvals; + int **decodemap; + + long postbits; + long phrasebits; + long frames; + +#if defined(TRAIN_RES) || defined(TRAIN_RESAUX) + int train_seq; + long *training_data[8][64]; + float training_max[8][64]; + float training_min[8][64]; + float tmin; + float tmax; +#endif + +} vorbis_look_residue0; + +void res0_free_info(vorbis_info_residue *i){ + vorbis_info_residue0 *info=(vorbis_info_residue0 *)i; + if(info){ + memset(info,0,sizeof(*info)); + _ogg_free(info); + } +} + +void res0_free_look(vorbis_look_residue *i){ + int j; + if(i){ + + vorbis_look_residue0 *look=(vorbis_look_residue0 *)i; + +#ifdef TRAIN_RES + { + int j,k,l; + for(j=0;jparts;j++){ + /*fprintf(stderr,"partition %d: ",j);*/ + for(k=0;k<8;k++) + if(look->training_data[k][j]){ + char buffer[80]; + FILE *of; + codebook *statebook=look->partbooks[j][k]; + + /* long and short into the same bucket by current convention */ + sprintf(buffer,"res_part%d_pass%d.vqd",j,k); + of=fopen(buffer,"a"); + + for(l=0;lentries;l++) + fprintf(of,"%d:%ld\n",l,look->training_data[k][j][l]); + + fclose(of); + + /*fprintf(stderr,"%d(%.2f|%.2f) ",k, + look->training_min[k][j],look->training_max[k][j]);*/ + + _ogg_free(look->training_data[k][j]); + look->training_data[k][j]=NULL; + } + /*fprintf(stderr,"\n");*/ + } + } + fprintf(stderr,"min/max residue: %g::%g\n",look->tmin,look->tmax); + + /*fprintf(stderr,"residue bit usage %f:%f (%f total)\n", + (float)look->phrasebits/look->frames, + (float)look->postbits/look->frames, + (float)(look->postbits+look->phrasebits)/look->frames);*/ +#endif + + + /*vorbis_info_residue0 *info=look->info; + + fprintf(stderr, + "%ld frames encoded in %ld phrasebits and %ld residue bits " + "(%g/frame) \n",look->frames,look->phrasebits, + look->resbitsflat, + (look->phrasebits+look->resbitsflat)/(float)look->frames); + + for(j=0;jparts;j++){ + long acc=0; + fprintf(stderr,"\t[%d] == ",j); + for(k=0;kstages;k++) + if((info->secondstages[j]>>k)&1){ + fprintf(stderr,"%ld,",look->resbits[j][k]); + acc+=look->resbits[j][k]; + } + + fprintf(stderr,":: (%ld vals) %1.2fbits/sample\n",look->resvals[j], + acc?(float)acc/(look->resvals[j]*info->grouping):0); + } + fprintf(stderr,"\n");*/ + + for(j=0;jparts;j++) + if(look->partbooks[j])_ogg_free(look->partbooks[j]); + _ogg_free(look->partbooks); + for(j=0;jpartvals;j++) + _ogg_free(look->decodemap[j]); + _ogg_free(look->decodemap); + + memset(look,0,sizeof(*look)); + _ogg_free(look); + } +} + +static int ilog(unsigned int v){ + int ret=0; + while(v){ + ret++; + v>>=1; + } + return(ret); +} + +static int icount(unsigned int v){ + int ret=0; + while(v){ + ret+=v&1; + v>>=1; + } + return(ret); +} + + +void res0_pack(vorbis_info_residue *vr,oggpack_buffer *opb){ + vorbis_info_residue0 *info=(vorbis_info_residue0 *)vr; + int j,acc=0; + oggpack_write(opb,info->begin,24); + oggpack_write(opb,info->end,24); + + oggpack_write(opb,info->grouping-1,24); /* residue vectors to group and + code with a partitioned book */ + oggpack_write(opb,info->partitions-1,6); /* possible partition choices */ + oggpack_write(opb,info->groupbook,8); /* group huffman book */ + + /* secondstages is a bitmask; as encoding progresses pass by pass, a + bitmask of one indicates this partition class has bits to write + this pass */ + for(j=0;jpartitions;j++){ + if(ilog(info->secondstages[j])>3){ + /* yes, this is a minor hack due to not thinking ahead */ + oggpack_write(opb,info->secondstages[j],3); + oggpack_write(opb,1,1); + oggpack_write(opb,info->secondstages[j]>>3,5); + }else + oggpack_write(opb,info->secondstages[j],4); /* trailing zero */ + acc+=icount(info->secondstages[j]); + } + for(j=0;jbooklist[j],8); + +} + +/* vorbis_info is for range checking */ +vorbis_info_residue *res0_unpack(vorbis_info *vi,oggpack_buffer *opb){ + int j,acc=0; + vorbis_info_residue0 *info=_ogg_calloc(1,sizeof(*info)); + codec_setup_info *ci=vi->codec_setup; + + info->begin=oggpack_read(opb,24); + info->end=oggpack_read(opb,24); + info->grouping=oggpack_read(opb,24)+1; + info->partitions=oggpack_read(opb,6)+1; + info->groupbook=oggpack_read(opb,8); + + for(j=0;jpartitions;j++){ + int cascade=oggpack_read(opb,3); + if(oggpack_read(opb,1)) + cascade|=(oggpack_read(opb,5)<<3); + info->secondstages[j]=cascade; + + acc+=icount(cascade); + } + for(j=0;jbooklist[j]=oggpack_read(opb,8); + + if(info->groupbook>=ci->books)goto errout; + for(j=0;jbooklist[j]>=ci->books)goto errout; + + return(info); + errout: + res0_free_info(info); + return(NULL); +} + +vorbis_look_residue *res0_look(vorbis_dsp_state *vd, + vorbis_info_residue *vr){ + vorbis_info_residue0 *info=(vorbis_info_residue0 *)vr; + vorbis_look_residue0 *look=_ogg_calloc(1,sizeof(*look)); + codec_setup_info *ci=vd->vi->codec_setup; + + int j,k,acc=0; + int dim; + int maxstage=0; + look->info=info; + + look->parts=info->partitions; + look->fullbooks=ci->fullbooks; + look->phrasebook=ci->fullbooks+info->groupbook; + dim=look->phrasebook->dim; + + look->partbooks=_ogg_calloc(look->parts,sizeof(*look->partbooks)); + + for(j=0;jparts;j++){ + int stages=ilog(info->secondstages[j]); + if(stages){ + if(stages>maxstage)maxstage=stages; + look->partbooks[j]=_ogg_calloc(stages,sizeof(*look->partbooks[j])); + for(k=0;ksecondstages[j]&(1<partbooks[j][k]=ci->fullbooks+info->booklist[acc++]; +#ifdef TRAIN_RES + look->training_data[k][j]=_ogg_calloc(look->partbooks[j][k]->entries, + sizeof(***look->training_data)); +#endif + } + } + } + + look->partvals=rint(pow((float)look->parts,(float)dim)); + look->stages=maxstage; + look->decodemap=_ogg_malloc(look->partvals*sizeof(*look->decodemap)); + for(j=0;jpartvals;j++){ + long val=j; + long mult=look->partvals/look->parts; + look->decodemap[j]=_ogg_malloc(dim*sizeof(*look->decodemap[j])); + for(k=0;kparts; + look->decodemap[j][k]=deco; + } + } +#if defined(TRAIN_RES) || defined (TRAIN_RESAUX) + { + static int train_seq=0; + look->train_seq=train_seq++; + } +#endif + return(look); +} + +/* break an abstraction and copy some code for performance purposes */ +static int local_book_besterror(codebook *book,float *a){ + int dim=book->dim,i,k,o; + int best=0; + encode_aux_threshmatch *tt=book->c->thresh_tree; + + /* find the quant val of each scalar */ + for(k=0,o=dim;kthreshvals>>1; + + if(valquantthresh[i]){ + if(valquantthresh[i-1]){ + for(--i;i>0;--i) + if(val>=tt->quantthresh[i-1]) + break; + } + }else{ + + for(++i;ithreshvals-1;++i) + if(valquantthresh[i])break; + + } + + best=(best*tt->quantvals)+tt->quantmap[i]; + } + /* regular lattices are easy :-) */ + + if(book->c->lengthlist[best]<=0){ + const static_codebook *c=book->c; + int i,j; + float bestf=0.f; + float *e=book->valuelist; + best=-1; + for(i=0;ientries;i++){ + if(c->lengthlist[i]>0){ + float this=0.f; + for(j=0;jvaluelist+best*dim; + for(i=0;idim; + int step=n/dim; + + for(i=0;iinfo; + vorbis_info *vi=vb->vd->vi; + codec_setup_info *ci=vi->codec_setup; + + /* move all this setup out later */ + int samples_per_partition=info->grouping; + int possible_partitions=info->partitions; + int n=info->end-info->begin; + + int partvals=n/samples_per_partition; + long **partword=_vorbis_block_alloc(vb,ch*sizeof(*partword)); + float scale=100./samples_per_partition; + + /* we find the partition type for each partition of each + channel. We'll go back and do the interleaved encoding in a + bit. For now, clarity */ + + for(i=0;ibegin; + for(j=0;jmax)max=fabs(in[j][offset+k]); + ent+=fabs(rint(in[j][offset+k])); + } + ent*=scale; + + for(k=0;kclassmetric1[k] && + (info->classmetric2[k]<0 || (int)entclassmetric2[k])) + break; + + partword[j][i]=k; + } + } + +#ifdef TRAIN_RESAUX + { + FILE *of; + char buffer[80]; + + for(i=0;itrain_seq); + of=fopen(buffer,"a"); + for(j=0;jframes++; + + return(partword); +} + +/* designed for stereo or other modes where the partition size is an + integer multiple of the number of channels encoded in the current + submap */ +static long **_2class(vorbis_block *vb,vorbis_look_residue *vl,float **in, + int ch){ + long i,j,k,l; + vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl; + vorbis_info_residue0 *info=look->info; + + /* move all this setup out later */ + int samples_per_partition=info->grouping; + int possible_partitions=info->partitions; + int n=info->end-info->begin; + + int partvals=n/samples_per_partition; + long **partword=_vorbis_block_alloc(vb,sizeof(*partword)); + +#if defined(TRAIN_RES) || defined (TRAIN_RESAUX) + FILE *of; + char buffer[80]; +#endif + + partword[0]=_vorbis_block_alloc(vb,n*ch/samples_per_partition*sizeof(*partword[0])); + memset(partword[0],0,n*ch/samples_per_partition*sizeof(*partword[0])); + + for(i=0,l=info->begin/ch;imagmax)magmax=fabs(in[0][l]); + for(k=1;kangmax)angmax=fabs(in[k][l]); + l++; + } + + for(j=0;jclassmetric1[j] && + angmax<=info->classmetric2[j]) + break; + + partword[0][i]=j; + + } + +#ifdef TRAIN_RESAUX + sprintf(buffer,"resaux_%d.vqd",look->train_seq); + of=fopen(buffer,"a"); + for(i=0;iframes++; + + return(partword); +} + +static int _01forward(oggpack_buffer *opb, + vorbis_block *vb,vorbis_look_residue *vl, + float **in,int ch, + long **partword, + int (*encode)(oggpack_buffer *,float *,int, + codebook *,long *)){ + long i,j,k,s; + vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl; + vorbis_info_residue0 *info=look->info; + + vorbis_dsp_state *vd=vb->vd; + + /* move all this setup out later */ + int samples_per_partition=info->grouping; + int possible_partitions=info->partitions; + int partitions_per_word=look->phrasebook->dim; + int n=info->end-info->begin; + + int partvals=n/samples_per_partition; + long resbits[128]; + long resvals[128]; + +#ifdef TRAIN_RES + for(i=0;ibegin;jend;j++){ + if(in[i][j]>look->tmax)look->tmax=in[i][j]; + if(in[i][j]tmin)look->tmin=in[i][j]; + } +#endif + + memset(resbits,0,sizeof(resbits)); + memset(resvals,0,sizeof(resvals)); + + /* we code the partition words for each channel, then the residual + words for a partition per channel until we've written all the + residual words for that partition word. Then write the next + partition channel words... */ + + for(s=0;sstages;s++){ + + for(i=0;iphrasebook->entries) + look->phrasebits+=vorbis_book_encode(look->phrasebook,val,opb); +#if 0 /*def TRAIN_RES*/ + else + fprintf(stderr,"!"); +#endif + + } + } + + /* now we encode interleaved residual values for the partitions */ + for(k=0;kbegin; + + for(j=0;jsecondstages[partword[j][i]]&(1<partbooks[partword[j][i]][s]; + if(statebook){ + int ret; + long *accumulator=NULL; + +#ifdef TRAIN_RES + accumulator=look->training_data[s][partword[j][i]]; + { + int l; + float *samples=in[j]+offset; + for(l=0;ltraining_min[s][partword[j][i]]) + look->training_min[s][partword[j][i]]=samples[l]; + if(samples[l]>look->training_max[s][partword[j][i]]) + look->training_max[s][partword[j][i]]=samples[l]; + } + } +#endif + + ret=encode(opb,in[j]+offset,samples_per_partition, + statebook,accumulator); + + look->postbits+=ret; + resbits[partword[j][i]]+=ret; + } + } + } + } + } + } + + /*{ + long total=0; + long totalbits=0; + fprintf(stderr,"%d :: ",vb->mode); + for(k=0;kinfo; + + /* move all this setup out later */ + int samples_per_partition=info->grouping; + int partitions_per_word=look->phrasebook->dim; + int n=info->end-info->begin; + + int partvals=n/samples_per_partition; + int partwords=(partvals+partitions_per_word-1)/partitions_per_word; + int ***partword=alloca(ch*sizeof(*partword)); + + for(j=0;jstages;s++){ + + /* each loop decodes on partition codeword containing + partitions_pre_word partitions */ + for(i=0,l=0;iphrasebook,&vb->opb); + if(temp==-1)goto eopbreak; + partword[j][l]=look->decodemap[temp]; + if(partword[j][l]==NULL)goto errout; + } + } + + /* now we decode residual values for the partitions */ + for(k=0;kbegin+i*samples_per_partition; + if(info->secondstages[partword[j][l][k]]&(1<partbooks[partword[j][l][k]][s]; + if(stagebook){ + if(decodepart(stagebook,in[j]+offset,&vb->opb, + samples_per_partition)==-1)goto eopbreak; + } + } + } + } + } + + errout: + eopbreak: + return(0); +} + +#if 0 +/* residue 0 and 1 are just slight variants of one another. 0 is + interleaved, 1 is not */ +long **res0_class(vorbis_block *vb,vorbis_look_residue *vl, + float **in,int *nonzero,int ch){ + /* we encode only the nonzero parts of a bundle */ + int i,used=0; + for(i=0;ipcmend/2; + for(i=0;ipcmend/2; + for(i=0;ipcmend/2,used=0; + + /* don't duplicate the code; use a working vector hack for now and + reshape ourselves into a single channel res1 */ + /* ugly; reallocs for each coupling pass :-( */ + float *work=_vorbis_block_alloc(vb,ch*n*sizeof(*work)); + for(i=0;iinfo; + + /* move all this setup out later */ + int samples_per_partition=info->grouping; + int partitions_per_word=look->phrasebook->dim; + int n=info->end-info->begin; + + int partvals=n/samples_per_partition; + int partwords=(partvals+partitions_per_word-1)/partitions_per_word; + int **partword=_vorbis_block_alloc(vb,partwords*sizeof(*partword)); + + for(i=0;istages;s++){ + for(i=0,l=0;iphrasebook,&vb->opb); + if(temp==-1)goto eopbreak; + partword[l]=look->decodemap[temp]; + if(partword[l]==NULL)goto errout; + } + + /* now we decode residual values for the partitions */ + for(k=0;ksecondstages[partword[l][k]]&(1<partbooks[partword[l][k]][s]; + + if(stagebook){ + if(vorbis_book_decodevv_add(stagebook,in, + i*samples_per_partition+info->begin,ch, + &vb->opb,samples_per_partition)==-1) + goto eopbreak; + } + } + } + } + + errout: + eopbreak: + return(0); +} + + +vorbis_func_residue residue0_exportbundle={ + NULL, + &res0_unpack, + &res0_look, + &res0_free_info, + &res0_free_look, + NULL, + NULL, + &res0_inverse +}; + +vorbis_func_residue residue1_exportbundle={ + &res0_pack, + &res0_unpack, + &res0_look, + &res0_free_info, + &res0_free_look, + &res1_class, + &res1_forward, + &res1_inverse +}; + +vorbis_func_residue residue2_exportbundle={ + &res0_pack, + &res0_unpack, + &res0_look, + &res0_free_info, + &res0_free_look, + &res2_class, + &res2_forward, + &res2_inverse +}; + diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/scales.h b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/scales.h new file mode 100644 index 0000000..fb2fd5f --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/scales.h @@ -0,0 +1,86 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: linear scale -> dB, Bark and Mel scales + last mod: $Id: scales.h 9959 2005-09-05 11:04:48Z msmith $ + + ********************************************************************/ + +#ifndef _V_SCALES_H_ +#define _V_SCALES_H_ + +#include +#include "os.h" + +/* 20log10(x) */ +#define VORBIS_IEEE_FLOAT32 1 +#ifdef VORBIS_IEEE_FLOAT32 + +static float unitnorm(float x){ + union { + ogg_uint32_t i; + float f; + } ix; + ix.f = x; + ix.i = (ix.i & 0x80000000U) | (0x3f800000U); + return ix.f; +} + +/* Segher was off (too high) by ~ .3 decibel. Center the conversion correctly. */ +static float todB(const float *x){ + union { + ogg_uint32_t i; + float f; + } ix; + ix.f = *x; + ix.i = ix.i&0x7fffffff; + return (float)(ix.i * 7.17711438e-7f -764.6161886f); +} + +#define todB_nn(x) todB(x) + +#else + +static float unitnorm(float x){ + if(x<0)return(-1.f); + return(1.f); +} + +#define todB(x) (*(x)==0?-400.f:log(*(x)**(x))*4.34294480f) +#define todB_nn(x) (*(x)==0.f?-400.f:log(*(x))*8.6858896f) + +#endif + +#define fromdB(x) (exp((x)*.11512925f)) + +/* The bark scale equations are approximations, since the original + table was somewhat hand rolled. The below are chosen to have the + best possible fit to the rolled tables, thus their somewhat odd + appearance (these are more accurate and over a longer range than + the oft-quoted bark equations found in the texts I have). The + approximations are valid from 0 - 30kHz (nyquist) or so. + + all f in Hz, z in Bark */ + +#define toBARK(n) (13.1f*atan(.00074f*(n))+2.24f*atan((n)*(n)*1.85e-8f)+1e-4f*(n)) +#define fromBARK(z) (102.f*(z)-2.f*pow(z,2.f)+.4f*pow(z,3.f)+pow(1.46f,z)-1.f) +#define toMEL(n) (log(1.f+(n)*.001f)*1442.695f) +#define fromMEL(m) (1000.f*exp((m)/1442.695f)-1000.f) + +/* Frequency to octave. We arbitrarily declare 63.5 Hz to be octave + 0.0 */ + +#define toOC(n) (log(n)*1.442695f-5.965784f) +#define fromOC(o) (exp(((o)+5.965784f)*.693147f)) + +#endif + diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/sharedbook.c b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/sharedbook.c new file mode 100644 index 0000000..58f8e57 --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/sharedbook.c @@ -0,0 +1,734 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: basic shared codebook operations + last mod: $Id: sharedbook.c 7187 2004-07-20 07:24:27Z xiphmont $ + + ********************************************************************/ + +#include +#include +#include +#include +#include "os.h" +#include "misc.h" +#include "vorbis/codec.h" +#include "codebook.h" +#include "scales.h" + +/**** pack/unpack helpers ******************************************/ +int _ilog(unsigned int v){ + int ret=0; + while(v){ + ret++; + v>>=1; + } + return(ret); +} + +/* 32 bit float (not IEEE; nonnormalized mantissa + + biased exponent) : neeeeeee eeemmmmm mmmmmmmm mmmmmmmm + Why not IEEE? It's just not that important here. */ + +#define VQ_FEXP 10 +#define VQ_FMAN 21 +#define VQ_FEXP_BIAS 768 /* bias toward values smaller than 1. */ + +/* doesn't currently guard under/overflow */ +long _float32_pack(float val){ + int sign=0; + long exp; + long mant; + if(val<0){ + sign=0x80000000; + val= -val; + } + exp= floor(log(val)/log(2.f)); + mant=rint(ldexp(val,(VQ_FMAN-1)-exp)); + exp=(exp+VQ_FEXP_BIAS)<>VQ_FMAN; + if(sign)mant= -mant; + return(ldexp(mant,exp-(VQ_FMAN-1)-VQ_FEXP_BIAS)); +} + +/* given a list of word lengths, generate a list of codewords. Works + for length ordered or unordered, always assigns the lowest valued + codewords first. Extended to handle unused entries (length 0) */ +ogg_uint32_t *_make_words(long *l,long n,long sparsecount){ + long i,j,count=0; + ogg_uint32_t marker[33]; + ogg_uint32_t *r=_ogg_malloc((sparsecount?sparsecount:n)*sizeof(*r)); + memset(marker,0,sizeof(marker)); + + for(i=0;i0){ + ogg_uint32_t entry=marker[length]; + + /* when we claim a node for an entry, we also claim the nodes + below it (pruning off the imagined tree that may have dangled + from it) as well as blocking the use of any nodes directly + above for leaves */ + + /* update ourself */ + if(length<32 && (entry>>length)){ + /* error condition; the lengths must specify an overpopulated tree */ + _ogg_free(r); + return(NULL); + } + r[count++]=entry; + + /* Look to see if the next shorter marker points to the node + above. if so, update it and repeat. */ + { + for(j=length;j>0;j--){ + + if(marker[j]&1){ + /* have to jump branches */ + if(j==1) + marker[1]++; + else + marker[j]=marker[j-1]<<1; + break; /* invariant says next upper marker would already + have been moved if it was on the same path */ + } + marker[j]++; + } + } + + /* prune the tree; the implicit invariant says all the longer + markers were dangling from our just-taken node. Dangle them + from our *new* node. */ + for(j=length+1;j<33;j++) + if((marker[j]>>1) == entry){ + entry=marker[j]; + marker[j]=marker[j-1]<<1; + }else + break; + }else + if(sparsecount==0)count++; + } + + /* bitreverse the words because our bitwise packer/unpacker is LSb + endian */ + for(i=0,count=0;i>j)&1; + } + + if(sparsecount){ + if(l[i]) + r[count++]=temp; + }else + r[count++]=temp; + } + + return(r); +} + +/* there might be a straightforward one-line way to do the below + that's portable and totally safe against roundoff, but I haven't + thought of it. Therefore, we opt on the side of caution */ +long _book_maptype1_quantvals(const static_codebook *b){ + long vals=floor(pow((float)b->entries,1.f/b->dim)); + + /* the above *should* be reliable, but we'll not assume that FP is + ever reliable when bitstream sync is at stake; verify via integer + means that vals really is the greatest value of dim for which + vals^b->bim <= b->entries */ + /* treat the above as an initial guess */ + while(1){ + long acc=1; + long acc1=1; + int i; + for(i=0;idim;i++){ + acc*=vals; + acc1*=vals+1; + } + if(acc<=b->entries && acc1>b->entries){ + return(vals); + }else{ + if(acc>b->entries){ + vals--; + }else{ + vals++; + } + } + } +} + +/* unpack the quantized list of values for encode/decode ***********/ +/* we need to deal with two map types: in map type 1, the values are + generated algorithmically (each column of the vector counts through + the values in the quant vector). in map type 2, all the values came + in in an explicit list. Both value lists must be unpacked */ +float *_book_unquantize(const static_codebook *b,int n,int *sparsemap){ + long j,k,count=0; + if(b->maptype==1 || b->maptype==2){ + int quantvals; + float mindel=_float32_unpack(b->q_min); + float delta=_float32_unpack(b->q_delta); + float *r=_ogg_calloc(n*b->dim,sizeof(*r)); + + /* maptype 1 and 2 both use a quantized value vector, but + different sizes */ + switch(b->maptype){ + case 1: + /* most of the time, entries%dimensions == 0, but we need to be + well defined. We define that the possible vales at each + scalar is values == entries/dim. If entries%dim != 0, we'll + have 'too few' values (values*dimentries;j++){ + if((sparsemap && b->lengthlist[j]) || !sparsemap){ + float last=0.f; + int indexdiv=1; + for(k=0;kdim;k++){ + int index= (j/indexdiv)%quantvals; + float val=b->quantlist[index]; + val=fabs(val)*delta+mindel+last; + if(b->q_sequencep)last=val; + if(sparsemap) + r[sparsemap[count]*b->dim+k]=val; + else + r[count*b->dim+k]=val; + indexdiv*=quantvals; + } + count++; + } + + } + break; + case 2: + for(j=0;jentries;j++){ + if((sparsemap && b->lengthlist[j]) || !sparsemap){ + float last=0.f; + + for(k=0;kdim;k++){ + float val=b->quantlist[j*b->dim+k]; + val=fabs(val)*delta+mindel+last; + if(b->q_sequencep)last=val; + if(sparsemap) + r[sparsemap[count]*b->dim+k]=val; + else + r[count*b->dim+k]=val; + } + count++; + } + } + break; + } + + return(r); + } + return(NULL); +} + +void vorbis_staticbook_clear(static_codebook *b){ + if(b->allocedp){ + if(b->quantlist)_ogg_free(b->quantlist); + if(b->lengthlist)_ogg_free(b->lengthlist); + if(b->nearest_tree){ + _ogg_free(b->nearest_tree->ptr0); + _ogg_free(b->nearest_tree->ptr1); + _ogg_free(b->nearest_tree->p); + _ogg_free(b->nearest_tree->q); + memset(b->nearest_tree,0,sizeof(*b->nearest_tree)); + _ogg_free(b->nearest_tree); + } + if(b->thresh_tree){ + _ogg_free(b->thresh_tree->quantthresh); + _ogg_free(b->thresh_tree->quantmap); + memset(b->thresh_tree,0,sizeof(*b->thresh_tree)); + _ogg_free(b->thresh_tree); + } + + memset(b,0,sizeof(*b)); + } +} + +void vorbis_staticbook_destroy(static_codebook *b){ + if(b->allocedp){ + vorbis_staticbook_clear(b); + _ogg_free(b); + } +} + +void vorbis_book_clear(codebook *b){ + /* static book is not cleared; we're likely called on the lookup and + the static codebook belongs to the info struct */ + if(b->valuelist)_ogg_free(b->valuelist); + if(b->codelist)_ogg_free(b->codelist); + + if(b->dec_index)_ogg_free(b->dec_index); + if(b->dec_codelengths)_ogg_free(b->dec_codelengths); + if(b->dec_firsttable)_ogg_free(b->dec_firsttable); + + memset(b,0,sizeof(*b)); +} + +int vorbis_book_init_encode(codebook *c,const static_codebook *s){ + + memset(c,0,sizeof(*c)); + c->c=s; + c->entries=s->entries; + c->used_entries=s->entries; + c->dim=s->dim; + c->codelist=_make_words(s->lengthlist,s->entries,0); + c->valuelist=_book_unquantize(s,s->entries,NULL); + + return(0); +} + +static ogg_uint32_t bitreverse(ogg_uint32_t x){ + x= ((x>>16)&0x0000ffffUL) | ((x<<16)&0xffff0000UL); + x= ((x>> 8)&0x00ff00ffUL) | ((x<< 8)&0xff00ff00UL); + x= ((x>> 4)&0x0f0f0f0fUL) | ((x<< 4)&0xf0f0f0f0UL); + x= ((x>> 2)&0x33333333UL) | ((x<< 2)&0xccccccccUL); + return((x>> 1)&0x55555555UL) | ((x<< 1)&0xaaaaaaaaUL); +} + +static int sort32a(const void *a,const void *b){ + return ( **(ogg_uint32_t **)a>**(ogg_uint32_t **)b)- + ( **(ogg_uint32_t **)a<**(ogg_uint32_t **)b); +} + +/* decode codebook arrangement is more heavily optimized than encode */ +int vorbis_book_init_decode(codebook *c,const static_codebook *s){ + int i,j,n=0,tabn; + int *sortindex; + memset(c,0,sizeof(*c)); + + /* count actually used entries */ + for(i=0;ientries;i++) + if(s->lengthlist[i]>0) + n++; + + c->entries=s->entries; + c->used_entries=n; + c->dim=s->dim; + + /* two different remappings go on here. + + First, we collapse the likely sparse codebook down only to + actually represented values/words. This collapsing needs to be + indexed as map-valueless books are used to encode original entry + positions as integers. + + Second, we reorder all vectors, including the entry index above, + by sorted bitreversed codeword to allow treeless decode. */ + + { + /* perform sort */ + ogg_uint32_t *codes=_make_words(s->lengthlist,s->entries,c->used_entries); + ogg_uint32_t **codep=alloca(sizeof(*codep)*n); + + if(codes==NULL)goto err_out; + + for(i=0;icodelist=_ogg_malloc(n*sizeof(*c->codelist)); + /* the index is a reverse index */ + for(i=0;icodelist[sortindex[i]]=codes[i]; + _ogg_free(codes); + } + + c->valuelist=_book_unquantize(s,n,sortindex); + c->dec_index=_ogg_malloc(n*sizeof(*c->dec_index)); + + for(n=0,i=0;ientries;i++) + if(s->lengthlist[i]>0) + c->dec_index[sortindex[n++]]=i; + + c->dec_codelengths=_ogg_malloc(n*sizeof(*c->dec_codelengths)); + for(n=0,i=0;ientries;i++) + if(s->lengthlist[i]>0) + c->dec_codelengths[sortindex[n++]]=s->lengthlist[i]; + + c->dec_firsttablen=_ilog(c->used_entries)-4; /* this is magic */ + if(c->dec_firsttablen<5)c->dec_firsttablen=5; + if(c->dec_firsttablen>8)c->dec_firsttablen=8; + + tabn=1<dec_firsttablen; + c->dec_firsttable=_ogg_calloc(tabn,sizeof(*c->dec_firsttable)); + c->dec_maxlength=0; + + for(i=0;idec_maxlengthdec_codelengths[i]) + c->dec_maxlength=c->dec_codelengths[i]; + if(c->dec_codelengths[i]<=c->dec_firsttablen){ + ogg_uint32_t orig=bitreverse(c->codelist[i]); + for(j=0;j<(1<<(c->dec_firsttablen-c->dec_codelengths[i]));j++) + c->dec_firsttable[orig|(j<dec_codelengths[i])]=i+1; + } + } + + /* now fill in 'unused' entries in the firsttable with hi/lo search + hints for the non-direct-hits */ + { + ogg_uint32_t mask=0xfffffffeUL<<(31-c->dec_firsttablen); + long lo=0,hi=0; + + for(i=0;idec_firsttablen); + if(c->dec_firsttable[bitreverse(word)]==0){ + while((lo+1)codelist[lo+1]<=word)lo++; + while( hi=(c->codelist[hi]&mask))hi++; + + /* we only actually have 15 bits per hint to play with here. + In order to overflow gracefully (nothing breaks, efficiency + just drops), encode as the difference from the extremes. */ + { + unsigned long loval=lo; + unsigned long hival=n-hi; + + if(loval>0x7fff)loval=0x7fff; + if(hival>0x7fff)hival=0x7fff; + c->dec_firsttable[bitreverse(word)]= + 0x80000000UL | (loval<<15) | hival; + } + } + } + } + + + return(0); + err_out: + vorbis_book_clear(c); + return(-1); +} + +static float _dist(int el,float *ref, float *b,int step){ + int i; + float acc=0.f; + for(i=0;ic->thresh_tree; + +#if 0 + encode_aux_nearestmatch *nt=book->c->nearest_tree; + encode_aux_pigeonhole *pt=book->c->pigeon_tree; +#endif + int dim=book->dim; + int k,o; + /*int savebest=-1; + float saverr;*/ + + /* do we have a threshhold encode hint? */ + if(tt){ + int index=0,i; + /* find the quant val of each scalar */ + for(k=0,o=step*(dim-1);kthreshvals>>1; + if(a[o]quantthresh[i]){ + + for(;i>0;i--) + if(a[o]>=tt->quantthresh[i-1]) + break; + + }else{ + + for(i++;ithreshvals-1;i++) + if(a[o]quantthresh[i])break; + + } + + index=(index*tt->quantvals)+tt->quantmap[i]; + } + /* regular lattices are easy :-) */ + if(book->c->lengthlist[index]>0) /* is this unused? If so, we'll + use a decision tree after all + and fall through*/ + return(index); + } + +#if 0 + /* do we have a pigeonhole encode hint? */ + if(pt){ + const static_codebook *c=book->c; + int i,besti=-1; + float best=0.f; + int entry=0; + + /* dealing with sequentialness is a pain in the ass */ + if(c->q_sequencep){ + int pv; + long mul=1; + float qlast=0; + for(k=0,o=0;kmin)/pt->del); + if(pv<0 || pv>=pt->mapentries)break; + entry+=pt->pigeonmap[pv]*mul; + mul*=pt->quantvals; + qlast+=pv*pt->del+pt->min; + } + }else{ + for(k=0,o=step*(dim-1);kmin)/pt->del); + if(pv<0 || pv>=pt->mapentries)break; + entry=entry*pt->quantvals+pt->pigeonmap[pv]; + } + } + + /* must be within the pigeonholable range; if we quant outside (or + in an entry that we define no list for), brute force it */ + if(k==dim && pt->fitlength[entry]){ + /* search the abbreviated list */ + long *list=pt->fitlist+pt->fitmap[entry]; + for(i=0;ifitlength[entry];i++){ + float this=_dist(dim,book->valuelist+list[i]*dim,a,step); + if(besti==-1 || thisvaluelist+nt->p[ptr]; + float *q=book->valuelist+nt->q[ptr]; + + for(k=0,o=0;k0.f) /* in A */ + ptr= -nt->ptr0[ptr]; + else /* in B */ + ptr= -nt->ptr1[ptr]; + if(ptr<=0)break; + } + return(-ptr); + } +#endif + + /* brute force it! */ + { + const static_codebook *c=book->c; + int i,besti=-1; + float best=0.f; + float *e=book->valuelist; + for(i=0;ientries;i++){ + if(c->lengthlist[i]>0){ + float this=_dist(dim,e,a,step); + if(besti==-1 || thisvaluelist+savebest*dim)[i]); + fprintf(stderr,"\n" + "bruteforce (entry %d, err %g):",besti,best); + for(i=0;ivaluelist+besti*dim)[i]); + fprintf(stderr,"\n"); + }*/ + return(besti); + } +} + +long vorbis_book_codeword(codebook *book,int entry){ + if(book->c) /* only use with encode; decode optimizations are + allowed to break this */ + return book->codelist[entry]; + return -1; +} + +long vorbis_book_codelen(codebook *book,int entry){ + if(book->c) /* only use with encode; decode optimizations are + allowed to break this */ + return book->c->lengthlist[entry]; + return -1; +} + +#ifdef _V_SELFTEST + +/* Unit tests of the dequantizer; this stuff will be OK + cross-platform, I simply want to be sure that special mapping cases + actually work properly; a bug could go unnoticed for a while */ + +#include + +/* cases: + + no mapping + full, explicit mapping + algorithmic mapping + + nonsequential + sequential +*/ + +static long full_quantlist1[]={0,1,2,3, 4,5,6,7, 8,3,6,1}; +static long partial_quantlist1[]={0,7,2}; + +/* no mapping */ +static_codebook test1={ + 4,16, + NULL, + 0, + 0,0,0,0, + NULL, + NULL,NULL +}; +static float *test1_result=NULL; + +/* linear, full mapping, nonsequential */ +static_codebook test2={ + 4,3, + NULL, + 2, + -533200896,1611661312,4,0, + full_quantlist1, + NULL,NULL +}; +static float test2_result[]={-3,-2,-1,0, 1,2,3,4, 5,0,3,-2}; + +/* linear, full mapping, sequential */ +static_codebook test3={ + 4,3, + NULL, + 2, + -533200896,1611661312,4,1, + full_quantlist1, + NULL,NULL +}; +static float test3_result[]={-3,-5,-6,-6, 1,3,6,10, 5,5,8,6}; + +/* linear, algorithmic mapping, nonsequential */ +static_codebook test4={ + 3,27, + NULL, + 1, + -533200896,1611661312,4,0, + partial_quantlist1, + NULL,NULL +}; +static float test4_result[]={-3,-3,-3, 4,-3,-3, -1,-3,-3, + -3, 4,-3, 4, 4,-3, -1, 4,-3, + -3,-1,-3, 4,-1,-3, -1,-1,-3, + -3,-3, 4, 4,-3, 4, -1,-3, 4, + -3, 4, 4, 4, 4, 4, -1, 4, 4, + -3,-1, 4, 4,-1, 4, -1,-1, 4, + -3,-3,-1, 4,-3,-1, -1,-3,-1, + -3, 4,-1, 4, 4,-1, -1, 4,-1, + -3,-1,-1, 4,-1,-1, -1,-1,-1}; + +/* linear, algorithmic mapping, sequential */ +static_codebook test5={ + 3,27, + NULL, + 1, + -533200896,1611661312,4,1, + partial_quantlist1, + NULL,NULL +}; +static float test5_result[]={-3,-6,-9, 4, 1,-2, -1,-4,-7, + -3, 1,-2, 4, 8, 5, -1, 3, 0, + -3,-4,-7, 4, 3, 0, -1,-2,-5, + -3,-6,-2, 4, 1, 5, -1,-4, 0, + -3, 1, 5, 4, 8,12, -1, 3, 7, + -3,-4, 0, 4, 3, 7, -1,-2, 2, + -3,-6,-7, 4, 1, 0, -1,-4,-5, + -3, 1, 0, 4, 8, 7, -1, 3, 2, + -3,-4,-5, 4, 3, 2, -1,-2,-3}; + +void run_test(static_codebook *b,float *comp){ + float *out=_book_unquantize(b,b->entries,NULL); + int i; + + if(comp){ + if(!out){ + fprintf(stderr,"_book_unquantize incorrectly returned NULL\n"); + exit(1); + } + + for(i=0;ientries*b->dim;i++) + if(fabs(out[i]-comp[i])>.0001){ + fprintf(stderr,"disagreement in unquantized and reference data:\n" + "position %d, %g != %g\n",i,out[i],comp[i]); + exit(1); + } + + }else{ + if(out){ + fprintf(stderr,"_book_unquantize returned a value array: \n" + " correct result should have been NULL\n"); + exit(1); + } + } +} + +int main(){ + /* run the nine dequant tests, and compare to the hand-rolled results */ + fprintf(stderr,"Dequant test 1... "); + run_test(&test1,test1_result); + fprintf(stderr,"OK\nDequant test 2... "); + run_test(&test2,test2_result); + fprintf(stderr,"OK\nDequant test 3... "); + run_test(&test3,test3_result); + fprintf(stderr,"OK\nDequant test 4... "); + run_test(&test4,test4_result); + fprintf(stderr,"OK\nDequant test 5... "); + run_test(&test5,test5_result); + fprintf(stderr,"OK\n\n"); + + return(0); +} + +#endif diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/smallft.c b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/smallft.c new file mode 100644 index 0000000..26a7e1a --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/smallft.c @@ -0,0 +1,1255 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: *unnormalized* fft transform + last mod: $Id: smallft.c 7573 2004-08-16 01:26:52Z conrad $ + + ********************************************************************/ + +/* FFT implementation from OggSquish, minus cosine transforms, + * minus all but radix 2/4 case. In Vorbis we only need this + * cut-down version. + * + * To do more than just power-of-two sized vectors, see the full + * version I wrote for NetLib. + * + * Note that the packing is a little strange; rather than the FFT r/i + * packing following R_0, I_n, R_1, I_1, R_2, I_2 ... R_n-1, I_n-1, + * it follows R_0, R_1, I_1, R_2, I_2 ... R_n-1, I_n-1, I_n like the + * FORTRAN version + */ + +#include +#include +#include +#include "smallft.h" +#include "os.h" +#include "misc.h" + +static void drfti1(int n, float *wa, int *ifac){ + static int ntryh[4] = { 4,2,3,5 }; + static float tpi = 6.28318530717958648f; + float arg,argh,argld,fi; + int ntry=0,i,j=-1; + int k1, l1, l2, ib; + int ld, ii, ip, is, nq, nr; + int ido, ipm, nfm1; + int nl=n; + int nf=0; + + L101: + j++; + if (j < 4) + ntry=ntryh[j]; + else + ntry+=2; + + L104: + nq=nl/ntry; + nr=nl-ntry*nq; + if (nr!=0) goto L101; + + nf++; + ifac[nf+1]=ntry; + nl=nq; + if(ntry!=2)goto L107; + if(nf==1)goto L107; + + for (i=1;i>1; + ipp2=ip; + idp2=ido; + nbd=(ido-1)>>1; + t0=l1*ido; + t10=ip*ido; + + if(ido==1)goto L119; + for(ik=0;ikl1){ + for(j=1;j>1; + ipp2=ip; + ipph=(ip+1)>>1; + if(idol1)goto L139; + + is= -ido-1; + t1=0; + for(j=1;jn==1)return; + drftf1(l->n,data,l->trigcache,l->trigcache+l->n,l->splitcache); +} + +void drft_backward(drft_lookup *l,float *data){ + if (l->n==1)return; + drftb1(l->n,data,l->trigcache,l->trigcache+l->n,l->splitcache); +} + +void drft_init(drft_lookup *l,int n){ + l->n=n; + l->trigcache=_ogg_calloc(3*n,sizeof(*l->trigcache)); + l->splitcache=_ogg_calloc(32,sizeof(*l->splitcache)); + fdrffti(n, l->trigcache, l->splitcache); +} + +void drft_clear(drft_lookup *l){ + if(l){ + if(l->trigcache)_ogg_free(l->trigcache); + if(l->splitcache)_ogg_free(l->splitcache); + memset(l,0,sizeof(*l)); + } +} diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/smallft.h b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/smallft.h new file mode 100644 index 0000000..8280100 --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/smallft.h @@ -0,0 +1,34 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: fft transform + last mod: $Id: smallft.h 7187 2004-07-20 07:24:27Z xiphmont $ + + ********************************************************************/ + +#ifndef _V_SMFT_H_ +#define _V_SMFT_H_ + +#include "vorbis/codec.h" + +typedef struct { + int n; + float *trigcache; + int *splitcache; +} drft_lookup; + +extern void drft_forward(drft_lookup *l,float *data); +extern void drft_backward(drft_lookup *l,float *data); +extern void drft_init(drft_lookup *l,int n); +extern void drft_clear(drft_lookup *l); + +#endif diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/synthesis.c b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/synthesis.c new file mode 100644 index 0000000..8596a38 --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/synthesis.c @@ -0,0 +1,170 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: single-block PCM synthesis + last mod: $Id: synthesis.c 7187 2004-07-20 07:24:27Z xiphmont $ + + ********************************************************************/ + +#include +#include +#include "vorbis/codec.h" +#include "codec_internal.h" +#include "registry.h" +#include "misc.h" +#include "os.h" + +int vorbis_synthesis(vorbis_block *vb,ogg_packet *op){ + vorbis_dsp_state *vd=vb->vd; + private_state *b=vd->backend_state; + vorbis_info *vi=vd->vi; + codec_setup_info *ci=vi->codec_setup; + oggpack_buffer *opb=&vb->opb; + int type,mode,i; + + /* first things first. Make sure decode is ready */ + _vorbis_block_ripcord(vb); + oggpack_readinit(opb,op->packet,op->bytes); + + /* Check the packet type */ + if(oggpack_read(opb,1)!=0){ + /* Oops. This is not an audio data packet */ + return(OV_ENOTAUDIO); + } + + /* read our mode and pre/post windowsize */ + mode=oggpack_read(opb,b->modebits); + if(mode==-1)return(OV_EBADPACKET); + + vb->mode=mode; + vb->W=ci->mode_param[mode]->blockflag; + if(vb->W){ + + /* this doesn;t get mapped through mode selection as it's used + only for window selection */ + vb->lW=oggpack_read(opb,1); + vb->nW=oggpack_read(opb,1); + if(vb->nW==-1) return(OV_EBADPACKET); + }else{ + vb->lW=0; + vb->nW=0; + } + + /* more setup */ + vb->granulepos=op->granulepos; + vb->sequence=op->packetno; + vb->eofflag=op->e_o_s; + + /* alloc pcm passback storage */ + vb->pcmend=ci->blocksizes[vb->W]; + vb->pcm=_vorbis_block_alloc(vb,sizeof(*vb->pcm)*vi->channels); + for(i=0;ichannels;i++) + vb->pcm[i]=_vorbis_block_alloc(vb,vb->pcmend*sizeof(*vb->pcm[i])); + + /* unpack_header enforces range checking */ + type=ci->map_type[ci->mode_param[mode]->mapping]; + + return(_mapping_P[type]->inverse(vb,ci->map_param[ci->mode_param[mode]-> + mapping])); +} + +/* used to track pcm position without actually performing decode. + Useful for sequential 'fast forward' */ +int vorbis_synthesis_trackonly(vorbis_block *vb,ogg_packet *op){ + vorbis_dsp_state *vd=vb->vd; + private_state *b=vd->backend_state; + vorbis_info *vi=vd->vi; + codec_setup_info *ci=vi->codec_setup; + oggpack_buffer *opb=&vb->opb; + int mode; + + /* first things first. Make sure decode is ready */ + _vorbis_block_ripcord(vb); + oggpack_readinit(opb,op->packet,op->bytes); + + /* Check the packet type */ + if(oggpack_read(opb,1)!=0){ + /* Oops. This is not an audio data packet */ + return(OV_ENOTAUDIO); + } + + /* read our mode and pre/post windowsize */ + mode=oggpack_read(opb,b->modebits); + if(mode==-1)return(OV_EBADPACKET); + + vb->mode=mode; + vb->W=ci->mode_param[mode]->blockflag; + if(vb->W){ + vb->lW=oggpack_read(opb,1); + vb->nW=oggpack_read(opb,1); + if(vb->nW==-1) return(OV_EBADPACKET); + }else{ + vb->lW=0; + vb->nW=0; + } + + /* more setup */ + vb->granulepos=op->granulepos; + vb->sequence=op->packetno; + vb->eofflag=op->e_o_s; + + /* no pcm */ + vb->pcmend=0; + vb->pcm=NULL; + + return(0); +} + +long vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op){ + codec_setup_info *ci=vi->codec_setup; + oggpack_buffer opb; + int mode; + + oggpack_readinit(&opb,op->packet,op->bytes); + + /* Check the packet type */ + if(oggpack_read(&opb,1)!=0){ + /* Oops. This is not an audio data packet */ + return(OV_ENOTAUDIO); + } + + { + int modebits=0; + int v=ci->modes; + while(v>1){ + modebits++; + v>>=1; + } + + /* read our mode and pre/post windowsize */ + mode=oggpack_read(&opb,modebits); + } + if(mode==-1)return(OV_EBADPACKET); + return(ci->blocksizes[ci->mode_param[mode]->blockflag]); +} + +int vorbis_synthesis_halfrate(vorbis_info *vi,int flag){ + /* set / clear half-sample-rate mode */ + codec_setup_info *ci=vi->codec_setup; + + /* right now, our MDCT can't handle < 64 sample windows. */ + if(ci->blocksizes[0]<=64 && flag)return -1; + ci->halfrate_flag=(flag?1:0); + return 0; +} + +int vorbis_synthesis_halfrate_p(vorbis_info *vi){ + codec_setup_info *ci=vi->codec_setup; + return ci->halfrate_flag; +} + + diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/tone.c b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/tone.c new file mode 100644 index 0000000..daf2f93 --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/tone.c @@ -0,0 +1,54 @@ +#include +#include +#include +#include + +void usage(){ + fprintf(stderr,"tone ,[] [,[]...]\n"); + exit(1); +} + +int main (int argc,char *argv[]){ + int i,j; + double *f; + double *amp; + + if(argc<2)usage(); + + f=alloca(sizeof(*f)*(argc-1)); + amp=alloca(sizeof(*amp)*(argc-1)); + + i=0; + while(argv[i+1]){ + char *pos=strchr(argv[i+1],','); + + f[i]=atof(argv[i+1]); + if(pos) + amp[i]=atof(pos+1)*32767.f; + else + amp[i]=32767.f; + + fprintf(stderr,"%g Hz, %g amp\n",f[i],amp[i]); + + i++; + } + + for(i=0;i<44100*10;i++){ + float val=0; + int ival; + for(j=0;j32767.f)ival=32767.f; + if(ival<-32768.f)ival=-32768.f; + + fprintf(stdout,"%c%c%c%c", + (char)(ival&0xff), + (char)((ival>>8)&0xff), + (char)(ival&0xff), + (char)((ival>>8)&0xff)); + } + return(0); +} + diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/vorbisenc.c b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/vorbisenc.c new file mode 100644 index 0000000..f2bd86a --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/vorbisenc.c @@ -0,0 +1,1184 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: simple programmatic interface for encoder mode setup + last mod: $Id: vorbisenc.c 9033 2005-03-04 04:33:03Z msmith $ + + ********************************************************************/ + +#include +#include +#include + +#include "vorbis/codec.h" +#include "vorbis/vorbisenc.h" + +#include "codec_internal.h" + +#include "os.h" +#include "misc.h" + +/* careful with this; it's using static array sizing to make managing + all the modes a little less annoying. If we use a residue backend + with > 12 partition types, or a different division of iteration, + this needs to be updated. */ +typedef struct { + static_codebook *books[12][3]; +} static_bookblock; + +typedef struct { + int res_type; + int limit_type; /* 0 lowpass limited, 1 point stereo limited */ + vorbis_info_residue0 *res; + static_codebook *book_aux; + static_codebook *book_aux_managed; + static_bookblock *books_base; + static_bookblock *books_base_managed; +} vorbis_residue_template; + +typedef struct { + vorbis_info_mapping0 *map; + vorbis_residue_template *res; +} vorbis_mapping_template; + +typedef struct vp_adjblock{ + int block[P_BANDS]; +} vp_adjblock; + +typedef struct { + int data[NOISE_COMPAND_LEVELS]; +} compandblock; + +/* high level configuration information for setting things up + step-by-step with the detailed vorbis_encode_ctl interface. + There's a fair amount of redundancy such that interactive setup + does not directly deal with any vorbis_info or codec_setup_info + initialization; it's all stored (until full init) in this highlevel + setup, then flushed out to the real codec setup structs later. */ + +typedef struct { + int att[P_NOISECURVES]; + float boost; + float decay; +} att3; +typedef struct { int data[P_NOISECURVES]; } adj3; + +typedef struct { + int pre[PACKETBLOBS]; + int post[PACKETBLOBS]; + float kHz[PACKETBLOBS]; + float lowpasskHz[PACKETBLOBS]; +} adj_stereo; + +typedef struct { + int lo; + int hi; + int fixed; +} noiseguard; +typedef struct { + int data[P_NOISECURVES][17]; +} noise3; + +typedef struct { + int mappings; + double *rate_mapping; + double *quality_mapping; + int coupling_restriction; + long samplerate_min_restriction; + long samplerate_max_restriction; + + + int *blocksize_short; + int *blocksize_long; + + att3 *psy_tone_masteratt; + int *psy_tone_0dB; + int *psy_tone_dBsuppress; + + vp_adjblock *psy_tone_adj_impulse; + vp_adjblock *psy_tone_adj_long; + vp_adjblock *psy_tone_adj_other; + + noiseguard *psy_noiseguards; + noise3 *psy_noise_bias_impulse; + noise3 *psy_noise_bias_padding; + noise3 *psy_noise_bias_trans; + noise3 *psy_noise_bias_long; + int *psy_noise_dBsuppress; + + compandblock *psy_noise_compand; + double *psy_noise_compand_short_mapping; + double *psy_noise_compand_long_mapping; + + int *psy_noise_normal_start[2]; + int *psy_noise_normal_partition[2]; + double *psy_noise_normal_thresh; + + int *psy_ath_float; + int *psy_ath_abs; + + double *psy_lowpass; + + vorbis_info_psy_global *global_params; + double *global_mapping; + adj_stereo *stereo_modes; + + static_codebook ***floor_books; + vorbis_info_floor1 *floor_params; + int *floor_short_mapping; + int *floor_long_mapping; + + vorbis_mapping_template *maps; +} ve_setup_data_template; + +/* a few static coder conventions */ +static vorbis_info_mode _mode_template[2]={ + {0,0,0,0}, + {1,0,0,1} +}; + +static vorbis_info_mapping0 _map_nominal[2]={ + {1, {0,0}, {0}, {0}, 1,{0},{1}}, + {1, {0,0}, {1}, {1}, 1,{0},{1}} +}; + +#include "modes/setup_44.h" +#include "modes/setup_44u.h" +#include "modes/setup_32.h" +#include "modes/setup_8.h" +#include "modes/setup_11.h" +#include "modes/setup_16.h" +#include "modes/setup_22.h" +#include "modes/setup_X.h" + +static ve_setup_data_template *setup_list[]={ + &ve_setup_44_stereo, + &ve_setup_44_uncoupled, + + &ve_setup_32_stereo, + &ve_setup_32_uncoupled, + + &ve_setup_22_stereo, + &ve_setup_22_uncoupled, + &ve_setup_16_stereo, + &ve_setup_16_uncoupled, + + &ve_setup_11_stereo, + &ve_setup_11_uncoupled, + &ve_setup_8_stereo, + &ve_setup_8_uncoupled, + + &ve_setup_X_stereo, + &ve_setup_X_uncoupled, + &ve_setup_XX_stereo, + &ve_setup_XX_uncoupled, + 0 +}; + +static int vorbis_encode_toplevel_setup(vorbis_info *vi,int ch,long rate){ + if(vi && vi->codec_setup){ + + vi->version=0; + vi->channels=ch; + vi->rate=rate; + + return(0); + } + return(OV_EINVAL); +} + +static void vorbis_encode_floor_setup(vorbis_info *vi,double s,int block, + static_codebook ***books, + vorbis_info_floor1 *in, + int *x){ + int i,k,is=s; + vorbis_info_floor1 *f=_ogg_calloc(1,sizeof(*f)); + codec_setup_info *ci=vi->codec_setup; + + memcpy(f,in+x[is],sizeof(*f)); + /* fill in the lowpass field, even if it's temporary */ + f->n=ci->blocksizes[block]>>1; + + /* books */ + { + int partitions=f->partitions; + int maxclass=-1; + int maxbook=-1; + for(i=0;ipartitionclass[i]>maxclass)maxclass=f->partitionclass[i]; + for(i=0;i<=maxclass;i++){ + if(f->class_book[i]>maxbook)maxbook=f->class_book[i]; + f->class_book[i]+=ci->books; + for(k=0;k<(1<class_subs[i]);k++){ + if(f->class_subbook[i][k]>maxbook)maxbook=f->class_subbook[i][k]; + if(f->class_subbook[i][k]>=0)f->class_subbook[i][k]+=ci->books; + } + } + + for(i=0;i<=maxbook;i++) + ci->book_param[ci->books++]=books[x[is]][i]; + } + + /* for now, we're only using floor 1 */ + ci->floor_type[ci->floors]=1; + ci->floor_param[ci->floors]=f; + ci->floors++; + + return; +} + +static void vorbis_encode_global_psych_setup(vorbis_info *vi,double s, + vorbis_info_psy_global *in, + double *x){ + int i,is=s; + double ds=s-is; + codec_setup_info *ci=vi->codec_setup; + vorbis_info_psy_global *g=&ci->psy_g_param; + + memcpy(g,in+(int)x[is],sizeof(*g)); + + ds=x[is]*(1.-ds)+x[is+1]*ds; + is=(int)ds; + ds-=is; + if(ds==0 && is>0){ + is--; + ds=1.; + } + + /* interpolate the trigger threshholds */ + for(i=0;i<4;i++){ + g->preecho_thresh[i]=in[is].preecho_thresh[i]*(1.-ds)+in[is+1].preecho_thresh[i]*ds; + g->postecho_thresh[i]=in[is].postecho_thresh[i]*(1.-ds)+in[is+1].postecho_thresh[i]*ds; + } + g->ampmax_att_per_sec=ci->hi.amplitude_track_dBpersec; + return; +} + +static void vorbis_encode_global_stereo(vorbis_info *vi, + highlevel_encode_setup *hi, + adj_stereo *p){ + float s=hi->stereo_point_setting; + int i,is=s; + double ds=s-is; + codec_setup_info *ci=vi->codec_setup; + vorbis_info_psy_global *g=&ci->psy_g_param; + + if(p){ + memcpy(g->coupling_prepointamp,p[is].pre,sizeof(*p[is].pre)*PACKETBLOBS); + memcpy(g->coupling_postpointamp,p[is].post,sizeof(*p[is].post)*PACKETBLOBS); + + if(hi->managed){ + /* interpolate the kHz threshholds */ + for(i=0;icoupling_pointlimit[0][i]=kHz*1000./vi->rate*ci->blocksizes[0]; + g->coupling_pointlimit[1][i]=kHz*1000./vi->rate*ci->blocksizes[1]; + g->coupling_pkHz[i]=kHz; + + kHz=p[is].lowpasskHz[i]*(1.-ds)+p[is+1].lowpasskHz[i]*ds; + g->sliding_lowpass[0][i]=kHz*1000./vi->rate*ci->blocksizes[0]; + g->sliding_lowpass[1][i]=kHz*1000./vi->rate*ci->blocksizes[1]; + + } + }else{ + float kHz=p[is].kHz[PACKETBLOBS/2]*(1.-ds)+p[is+1].kHz[PACKETBLOBS/2]*ds; + for(i=0;icoupling_pointlimit[0][i]=kHz*1000./vi->rate*ci->blocksizes[0]; + g->coupling_pointlimit[1][i]=kHz*1000./vi->rate*ci->blocksizes[1]; + g->coupling_pkHz[i]=kHz; + } + + kHz=p[is].lowpasskHz[PACKETBLOBS/2]*(1.-ds)+p[is+1].lowpasskHz[PACKETBLOBS/2]*ds; + for(i=0;isliding_lowpass[0][i]=kHz*1000./vi->rate*ci->blocksizes[0]; + g->sliding_lowpass[1][i]=kHz*1000./vi->rate*ci->blocksizes[1]; + } + } + }else{ + for(i=0;isliding_lowpass[0][i]=ci->blocksizes[0]; + g->sliding_lowpass[1][i]=ci->blocksizes[1]; + } + } + return; +} + +static void vorbis_encode_psyset_setup(vorbis_info *vi,double s, + int *nn_start, + int *nn_partition, + double *nn_thresh, + int block){ + codec_setup_info *ci=vi->codec_setup; + vorbis_info_psy *p=ci->psy_param[block]; + highlevel_encode_setup *hi=&ci->hi; + int is=s; + + if(block>=ci->psys) + ci->psys=block+1; + if(!p){ + p=_ogg_calloc(1,sizeof(*p)); + ci->psy_param[block]=p; + } + + memcpy(p,&_psy_info_template,sizeof(*p)); + p->blockflag=block>>1; + + if(hi->noise_normalize_p){ + p->normal_channel_p=1; + p->normal_point_p=1; + p->normal_start=nn_start[is]; + p->normal_partition=nn_partition[is]; + p->normal_thresh=nn_thresh[is]; + } + + return; +} + +static void vorbis_encode_tonemask_setup(vorbis_info *vi,double s,int block, + att3 *att, + int *max, + vp_adjblock *in){ + int i,is=s; + double ds=s-is; + codec_setup_info *ci=vi->codec_setup; + vorbis_info_psy *p=ci->psy_param[block]; + + /* 0 and 2 are only used by bitmanagement, but there's no harm to always + filling the values in here */ + p->tone_masteratt[0]=att[is].att[0]*(1.-ds)+att[is+1].att[0]*ds; + p->tone_masteratt[1]=att[is].att[1]*(1.-ds)+att[is+1].att[1]*ds; + p->tone_masteratt[2]=att[is].att[2]*(1.-ds)+att[is+1].att[2]*ds; + p->tone_centerboost=att[is].boost*(1.-ds)+att[is+1].boost*ds; + p->tone_decay=att[is].decay*(1.-ds)+att[is+1].decay*ds; + + p->max_curve_dB=max[is]*(1.-ds)+max[is+1]*ds; + + for(i=0;itoneatt[i]=in[is].block[i]*(1.-ds)+in[is+1].block[i]*ds; + return; +} + + +static void vorbis_encode_compand_setup(vorbis_info *vi,double s,int block, + compandblock *in, double *x){ + int i,is=s; + double ds=s-is; + codec_setup_info *ci=vi->codec_setup; + vorbis_info_psy *p=ci->psy_param[block]; + + ds=x[is]*(1.-ds)+x[is+1]*ds; + is=(int)ds; + ds-=is; + if(ds==0 && is>0){ + is--; + ds=1.; + } + + /* interpolate the compander settings */ + for(i=0;inoisecompand[i]=in[is].data[i]*(1.-ds)+in[is+1].data[i]*ds; + return; +} + +static void vorbis_encode_peak_setup(vorbis_info *vi,double s,int block, + int *suppress){ + int is=s; + double ds=s-is; + codec_setup_info *ci=vi->codec_setup; + vorbis_info_psy *p=ci->psy_param[block]; + + p->tone_abs_limit=suppress[is]*(1.-ds)+suppress[is+1]*ds; + + return; +} + +static void vorbis_encode_noisebias_setup(vorbis_info *vi,double s,int block, + int *suppress, + noise3 *in, + noiseguard *guard, + double userbias){ + int i,is=s,j; + double ds=s-is; + codec_setup_info *ci=vi->codec_setup; + vorbis_info_psy *p=ci->psy_param[block]; + + p->noisemaxsupp=suppress[is]*(1.-ds)+suppress[is+1]*ds; + p->noisewindowlomin=guard[block].lo; + p->noisewindowhimin=guard[block].hi; + p->noisewindowfixed=guard[block].fixed; + + for(j=0;jnoiseoff[j][i]=in[is].data[j][i]*(1.-ds)+in[is+1].data[j][i]*ds; + + /* impulse blocks may take a user specified bias to boost the + nominal/high noise encoding depth */ + for(j=0;jnoiseoff[j][0]+6; /* the lowest it can go */ + for(i=0;inoiseoff[j][i]+=userbias; + if(p->noiseoff[j][i]noiseoff[j][i]=min; + } + } + + return; +} + +static void vorbis_encode_ath_setup(vorbis_info *vi,int block){ + codec_setup_info *ci=vi->codec_setup; + vorbis_info_psy *p=ci->psy_param[block]; + + p->ath_adjatt=ci->hi.ath_floating_dB; + p->ath_maxatt=ci->hi.ath_absolute_dB; + return; +} + + +static int book_dup_or_new(codec_setup_info *ci,static_codebook *book){ + int i; + for(i=0;ibooks;i++) + if(ci->book_param[i]==book)return(i); + + return(ci->books++); +} + +static void vorbis_encode_blocksize_setup(vorbis_info *vi,double s, + int *shortb,int *longb){ + + codec_setup_info *ci=vi->codec_setup; + int is=s; + + int blockshort=shortb[is]; + int blocklong=longb[is]; + ci->blocksizes[0]=blockshort; + ci->blocksizes[1]=blocklong; + +} + +static void vorbis_encode_residue_setup(vorbis_info *vi, + int number, int block, + vorbis_residue_template *res){ + + codec_setup_info *ci=vi->codec_setup; + int i,n; + + vorbis_info_residue0 *r=ci->residue_param[number]= + _ogg_malloc(sizeof(*r)); + + memcpy(r,res->res,sizeof(*r)); + if(ci->residues<=number)ci->residues=number+1; + + switch(ci->blocksizes[block]){ + case 64:case 128:case 256: + r->grouping=16; + break; + default: + r->grouping=32; + break; + } + ci->residue_type[number]=res->res_type; + + /* to be adjusted by lowpass/pointlimit later */ + n=r->end=ci->blocksizes[block]>>1; + if(res->res_type==2) + n=r->end*=vi->channels; + + /* fill in all the books */ + { + int booklist=0,k; + + if(ci->hi.managed){ + for(i=0;ipartitions;i++) + for(k=0;k<3;k++) + if(res->books_base_managed->books[i][k]) + r->secondstages[i]|=(1<groupbook=book_dup_or_new(ci,res->book_aux_managed); + ci->book_param[r->groupbook]=res->book_aux_managed; + + for(i=0;ipartitions;i++){ + for(k=0;k<3;k++){ + if(res->books_base_managed->books[i][k]){ + int bookid=book_dup_or_new(ci,res->books_base_managed->books[i][k]); + r->booklist[booklist++]=bookid; + ci->book_param[bookid]=res->books_base_managed->books[i][k]; + } + } + } + + }else{ + + for(i=0;ipartitions;i++) + for(k=0;k<3;k++) + if(res->books_base->books[i][k]) + r->secondstages[i]|=(1<groupbook=book_dup_or_new(ci,res->book_aux); + ci->book_param[r->groupbook]=res->book_aux; + + for(i=0;ipartitions;i++){ + for(k=0;k<3;k++){ + if(res->books_base->books[i][k]){ + int bookid=book_dup_or_new(ci,res->books_base->books[i][k]); + r->booklist[booklist++]=bookid; + ci->book_param[bookid]=res->books_base->books[i][k]; + } + } + } + } + } + + /* lowpass setup/pointlimit */ + { + double freq=ci->hi.lowpass_kHz*1000.; + vorbis_info_floor1 *f=ci->floor_param[block]; /* by convention */ + double nyq=vi->rate/2.; + long blocksize=ci->blocksizes[block]>>1; + + /* lowpass needs to be set in the floor and the residue. */ + if(freq>nyq)freq=nyq; + /* in the floor, the granularity can be very fine; it doesn't alter + the encoding structure, only the samples used to fit the floor + approximation */ + f->n=freq/nyq*blocksize; + + /* this res may by limited by the maximum pointlimit of the mode, + not the lowpass. the floor is always lowpass limited. */ + if(res->limit_type){ + if(ci->hi.managed) + freq=ci->psy_g_param.coupling_pkHz[PACKETBLOBS-1]*1000.; + else + freq=ci->psy_g_param.coupling_pkHz[PACKETBLOBS/2]*1000.; + if(freq>nyq)freq=nyq; + } + + /* in the residue, we're constrained, physically, by partition + boundaries. We still lowpass 'wherever', but we have to round up + here to next boundary, or the vorbis spec will round it *down* to + previous boundary in encode/decode */ + if(ci->residue_type[block]==2) + r->end=(int)((freq/nyq*blocksize*2)/r->grouping+.9)* /* round up only if we're well past */ + r->grouping; + else + r->end=(int)((freq/nyq*blocksize)/r->grouping+.9)* /* round up only if we're well past */ + r->grouping; + } +} + +/* we assume two maps in this encoder */ +static void vorbis_encode_map_n_res_setup(vorbis_info *vi,double s, + vorbis_mapping_template *maps){ + + codec_setup_info *ci=vi->codec_setup; + int i,j,is=s,modes=2; + vorbis_info_mapping0 *map=maps[is].map; + vorbis_info_mode *mode=_mode_template; + vorbis_residue_template *res=maps[is].res; + + if(ci->blocksizes[0]==ci->blocksizes[1])modes=1; + + for(i=0;imap_param[i]=_ogg_calloc(1,sizeof(*map)); + ci->mode_param[i]=_ogg_calloc(1,sizeof(*mode)); + + memcpy(ci->mode_param[i],mode+i,sizeof(*_mode_template)); + if(i>=ci->modes)ci->modes=i+1; + + ci->map_type[i]=0; + memcpy(ci->map_param[i],map+i,sizeof(*map)); + if(i>=ci->maps)ci->maps=i+1; + + for(j=0;jcodec_setup; + highlevel_encode_setup *hi=&ci->hi; + ve_setup_data_template *setup=(ve_setup_data_template *)hi->setup; + int is=hi->base_setting; + double ds=hi->base_setting-is; + int ch=vi->channels; + double *r=setup->rate_mapping; + + if(r==NULL) + return(-1); + + return((r[is]*(1.-ds)+r[is+1]*ds)*ch); +} + +static void get_setup_template(vorbis_info *vi, + long ch,long srate, + double req,int q_or_bitrate){ + int i=0,j; + codec_setup_info *ci=vi->codec_setup; + highlevel_encode_setup *hi=&ci->hi; + if(q_or_bitrate)req/=ch; + + while(setup_list[i]){ + if(setup_list[i]->coupling_restriction==-1 || + setup_list[i]->coupling_restriction==ch){ + if(srate>=setup_list[i]->samplerate_min_restriction && + srate<=setup_list[i]->samplerate_max_restriction){ + int mappings=setup_list[i]->mappings; + double *map=(q_or_bitrate? + setup_list[i]->rate_mapping: + setup_list[i]->quality_mapping); + + /* the template matches. Does the requested quality mode + fall within this template's modes? */ + if(reqmap[setup_list[i]->mappings]){++i;continue;} + for(j=0;j=map[j] && reqsetup=setup_list[i]; + if(j==mappings) + hi->base_setting=j-.001; + else{ + float low=map[j]; + float high=map[j+1]; + float del=(req-low)/(high-low); + hi->base_setting=j+del; + } + + return; + } + } + i++; + } + + hi->setup=NULL; +} + +/* encoders will need to use vorbis_info_init beforehand and call + vorbis_info clear when all done */ + +/* two interfaces; this, more detailed one, and later a convenience + layer on top */ + +/* the final setup call */ +int vorbis_encode_setup_init(vorbis_info *vi){ + int i0=0,singleblock=0; + codec_setup_info *ci=vi->codec_setup; + ve_setup_data_template *setup=NULL; + highlevel_encode_setup *hi=&ci->hi; + + if(ci==NULL)return(OV_EINVAL); + if(!hi->impulse_block_p)i0=1; + + /* too low/high an ATH floater is nonsensical, but doesn't break anything */ + if(hi->ath_floating_dB>-80)hi->ath_floating_dB=-80; + if(hi->ath_floating_dB<-200)hi->ath_floating_dB=-200; + + /* again, bound this to avoid the app shooting itself int he foot + too badly */ + if(hi->amplitude_track_dBpersec>0.)hi->amplitude_track_dBpersec=0.; + if(hi->amplitude_track_dBpersec<-99999.)hi->amplitude_track_dBpersec=-99999.; + + /* get the appropriate setup template; matches the fetch in previous + stages */ + setup=(ve_setup_data_template *)hi->setup; + if(setup==NULL)return(OV_EINVAL); + + hi->set_in_stone=1; + /* choose block sizes from configured sizes as well as paying + attention to long_block_p and short_block_p. If the configured + short and long blocks are the same length, we set long_block_p + and unset short_block_p */ + vorbis_encode_blocksize_setup(vi,hi->base_setting, + setup->blocksize_short, + setup->blocksize_long); + if(ci->blocksizes[0]==ci->blocksizes[1])singleblock=1; + + /* floor setup; choose proper floor params. Allocated on the floor + stack in order; if we alloc only long floor, it's 0 */ + vorbis_encode_floor_setup(vi,hi->short_setting,0, + setup->floor_books, + setup->floor_params, + setup->floor_short_mapping); + if(!singleblock) + vorbis_encode_floor_setup(vi,hi->long_setting,1, + setup->floor_books, + setup->floor_params, + setup->floor_long_mapping); + + /* setup of [mostly] short block detection and stereo*/ + vorbis_encode_global_psych_setup(vi,hi->trigger_setting, + setup->global_params, + setup->global_mapping); + vorbis_encode_global_stereo(vi,hi,setup->stereo_modes); + + /* basic psych setup and noise normalization */ + vorbis_encode_psyset_setup(vi,hi->short_setting, + setup->psy_noise_normal_start[0], + setup->psy_noise_normal_partition[0], + setup->psy_noise_normal_thresh, + 0); + vorbis_encode_psyset_setup(vi,hi->short_setting, + setup->psy_noise_normal_start[0], + setup->psy_noise_normal_partition[0], + setup->psy_noise_normal_thresh, + 1); + if(!singleblock){ + vorbis_encode_psyset_setup(vi,hi->long_setting, + setup->psy_noise_normal_start[1], + setup->psy_noise_normal_partition[1], + setup->psy_noise_normal_thresh, + 2); + vorbis_encode_psyset_setup(vi,hi->long_setting, + setup->psy_noise_normal_start[1], + setup->psy_noise_normal_partition[1], + setup->psy_noise_normal_thresh, + 3); + } + + /* tone masking setup */ + vorbis_encode_tonemask_setup(vi,hi->block[i0].tone_mask_setting,0, + setup->psy_tone_masteratt, + setup->psy_tone_0dB, + setup->psy_tone_adj_impulse); + vorbis_encode_tonemask_setup(vi,hi->block[1].tone_mask_setting,1, + setup->psy_tone_masteratt, + setup->psy_tone_0dB, + setup->psy_tone_adj_other); + if(!singleblock){ + vorbis_encode_tonemask_setup(vi,hi->block[2].tone_mask_setting,2, + setup->psy_tone_masteratt, + setup->psy_tone_0dB, + setup->psy_tone_adj_other); + vorbis_encode_tonemask_setup(vi,hi->block[3].tone_mask_setting,3, + setup->psy_tone_masteratt, + setup->psy_tone_0dB, + setup->psy_tone_adj_long); + } + + /* noise companding setup */ + vorbis_encode_compand_setup(vi,hi->block[i0].noise_compand_setting,0, + setup->psy_noise_compand, + setup->psy_noise_compand_short_mapping); + vorbis_encode_compand_setup(vi,hi->block[1].noise_compand_setting,1, + setup->psy_noise_compand, + setup->psy_noise_compand_short_mapping); + if(!singleblock){ + vorbis_encode_compand_setup(vi,hi->block[2].noise_compand_setting,2, + setup->psy_noise_compand, + setup->psy_noise_compand_long_mapping); + vorbis_encode_compand_setup(vi,hi->block[3].noise_compand_setting,3, + setup->psy_noise_compand, + setup->psy_noise_compand_long_mapping); + } + + /* peak guarding setup */ + vorbis_encode_peak_setup(vi,hi->block[i0].tone_peaklimit_setting,0, + setup->psy_tone_dBsuppress); + vorbis_encode_peak_setup(vi,hi->block[1].tone_peaklimit_setting,1, + setup->psy_tone_dBsuppress); + if(!singleblock){ + vorbis_encode_peak_setup(vi,hi->block[2].tone_peaklimit_setting,2, + setup->psy_tone_dBsuppress); + vorbis_encode_peak_setup(vi,hi->block[3].tone_peaklimit_setting,3, + setup->psy_tone_dBsuppress); + } + + /* noise bias setup */ + vorbis_encode_noisebias_setup(vi,hi->block[i0].noise_bias_setting,0, + setup->psy_noise_dBsuppress, + setup->psy_noise_bias_impulse, + setup->psy_noiseguards, + (i0==0?hi->impulse_noisetune:0.)); + vorbis_encode_noisebias_setup(vi,hi->block[1].noise_bias_setting,1, + setup->psy_noise_dBsuppress, + setup->psy_noise_bias_padding, + setup->psy_noiseguards,0.); + if(!singleblock){ + vorbis_encode_noisebias_setup(vi,hi->block[2].noise_bias_setting,2, + setup->psy_noise_dBsuppress, + setup->psy_noise_bias_trans, + setup->psy_noiseguards,0.); + vorbis_encode_noisebias_setup(vi,hi->block[3].noise_bias_setting,3, + setup->psy_noise_dBsuppress, + setup->psy_noise_bias_long, + setup->psy_noiseguards,0.); + } + + vorbis_encode_ath_setup(vi,0); + vorbis_encode_ath_setup(vi,1); + if(!singleblock){ + vorbis_encode_ath_setup(vi,2); + vorbis_encode_ath_setup(vi,3); + } + + vorbis_encode_map_n_res_setup(vi,hi->base_setting,setup->maps); + + /* set bitrate readonlies and management */ + if(hi->bitrate_av>0) + vi->bitrate_nominal=hi->bitrate_av; + else{ + vi->bitrate_nominal=setting_to_approx_bitrate(vi); + } + + vi->bitrate_lower=hi->bitrate_min; + vi->bitrate_upper=hi->bitrate_max; + if(hi->bitrate_av) + vi->bitrate_window=(double)hi->bitrate_reservoir/hi->bitrate_av; + else + vi->bitrate_window=0.; + + if(hi->managed){ + ci->bi.avg_rate=hi->bitrate_av; + ci->bi.min_rate=hi->bitrate_min; + ci->bi.max_rate=hi->bitrate_max; + + ci->bi.reservoir_bits=hi->bitrate_reservoir; + ci->bi.reservoir_bias= + hi->bitrate_reservoir_bias; + + ci->bi.slew_damp=hi->bitrate_av_damp; + + } + + return(0); + +} + +static int vorbis_encode_setup_setting(vorbis_info *vi, + long channels, + long rate){ + int ret=0,i,is; + codec_setup_info *ci=vi->codec_setup; + highlevel_encode_setup *hi=&ci->hi; + ve_setup_data_template *setup=hi->setup; + double ds; + + ret=vorbis_encode_toplevel_setup(vi,channels,rate); + if(ret)return(ret); + + is=hi->base_setting; + ds=hi->base_setting-is; + + hi->short_setting=hi->base_setting; + hi->long_setting=hi->base_setting; + + hi->managed=0; + + hi->impulse_block_p=1; + hi->noise_normalize_p=1; + + hi->stereo_point_setting=hi->base_setting; + hi->lowpass_kHz= + setup->psy_lowpass[is]*(1.-ds)+setup->psy_lowpass[is+1]*ds; + + hi->ath_floating_dB=setup->psy_ath_float[is]*(1.-ds)+ + setup->psy_ath_float[is+1]*ds; + hi->ath_absolute_dB=setup->psy_ath_abs[is]*(1.-ds)+ + setup->psy_ath_abs[is+1]*ds; + + hi->amplitude_track_dBpersec=-6.; + hi->trigger_setting=hi->base_setting; + + for(i=0;i<4;i++){ + hi->block[i].tone_mask_setting=hi->base_setting; + hi->block[i].tone_peaklimit_setting=hi->base_setting; + hi->block[i].noise_bias_setting=hi->base_setting; + hi->block[i].noise_compand_setting=hi->base_setting; + } + + return(ret); +} + +int vorbis_encode_setup_vbr(vorbis_info *vi, + long channels, + long rate, + float quality){ + codec_setup_info *ci=vi->codec_setup; + highlevel_encode_setup *hi=&ci->hi; + + quality+=.0000001; + if(quality>=1.)quality=.9999; + + get_setup_template(vi,channels,rate,quality,0); + if(!hi->setup)return OV_EIMPL; + + return vorbis_encode_setup_setting(vi,channels,rate); +} + +int vorbis_encode_init_vbr(vorbis_info *vi, + long channels, + long rate, + + float base_quality /* 0. to 1. */ + ){ + int ret=0; + + ret=vorbis_encode_setup_vbr(vi,channels,rate,base_quality); + + if(ret){ + vorbis_info_clear(vi); + return ret; + } + ret=vorbis_encode_setup_init(vi); + if(ret) + vorbis_info_clear(vi); + return(ret); +} + +int vorbis_encode_setup_managed(vorbis_info *vi, + long channels, + long rate, + + long max_bitrate, + long nominal_bitrate, + long min_bitrate){ + + codec_setup_info *ci=vi->codec_setup; + highlevel_encode_setup *hi=&ci->hi; + double tnominal=nominal_bitrate; + int ret=0; + + if(nominal_bitrate<=0.){ + if(max_bitrate>0.){ + if(min_bitrate>0.) + nominal_bitrate=(max_bitrate+min_bitrate)*.5; + else + nominal_bitrate=max_bitrate*.875; + }else{ + if(min_bitrate>0.){ + nominal_bitrate=min_bitrate; + }else{ + return(OV_EINVAL); + } + } + } + + get_setup_template(vi,channels,rate,nominal_bitrate,1); + if(!hi->setup)return OV_EIMPL; + + ret=vorbis_encode_setup_setting(vi,channels,rate); + if(ret){ + vorbis_info_clear(vi); + return ret; + } + + /* initialize management with sane defaults */ + hi->managed=1; + hi->bitrate_min=min_bitrate; + hi->bitrate_max=max_bitrate; + hi->bitrate_av=tnominal; + hi->bitrate_av_damp=1.5f; /* full range in no less than 1.5 second */ + hi->bitrate_reservoir=nominal_bitrate*2; + hi->bitrate_reservoir_bias=.1; /* bias toward hoarding bits */ + + return(ret); + +} + +int vorbis_encode_init(vorbis_info *vi, + long channels, + long rate, + + long max_bitrate, + long nominal_bitrate, + long min_bitrate){ + + int ret=vorbis_encode_setup_managed(vi,channels,rate, + max_bitrate, + nominal_bitrate, + min_bitrate); + if(ret){ + vorbis_info_clear(vi); + return(ret); + } + + ret=vorbis_encode_setup_init(vi); + if(ret) + vorbis_info_clear(vi); + return(ret); +} + +int vorbis_encode_ctl(vorbis_info *vi,int number,void *arg){ + if(vi){ + codec_setup_info *ci=vi->codec_setup; + highlevel_encode_setup *hi=&ci->hi; + int setp=(number&0xf); /* a read request has a low nibble of 0 */ + + if(setp && hi->set_in_stone)return(OV_EINVAL); + + switch(number){ + + /* now deprecated *****************/ + case OV_ECTL_RATEMANAGE_GET: + { + + struct ovectl_ratemanage_arg *ai= + (struct ovectl_ratemanage_arg *)arg; + + ai->management_active=hi->managed; + ai->bitrate_hard_window=ai->bitrate_av_window= + (double)hi->bitrate_reservoir/vi->rate; + ai->bitrate_av_window_center=1.; + ai->bitrate_hard_min=hi->bitrate_min; + ai->bitrate_hard_max=hi->bitrate_max; + ai->bitrate_av_lo=hi->bitrate_av; + ai->bitrate_av_hi=hi->bitrate_av; + + } + return(0); + + /* now deprecated *****************/ + case OV_ECTL_RATEMANAGE_SET: + { + struct ovectl_ratemanage_arg *ai= + (struct ovectl_ratemanage_arg *)arg; + if(ai==NULL){ + hi->managed=0; + }else{ + hi->managed=ai->management_active; + vorbis_encode_ctl(vi,OV_ECTL_RATEMANAGE_AVG,arg); + vorbis_encode_ctl(vi,OV_ECTL_RATEMANAGE_HARD,arg); + } + } + return 0; + + /* now deprecated *****************/ + case OV_ECTL_RATEMANAGE_AVG: + { + struct ovectl_ratemanage_arg *ai= + (struct ovectl_ratemanage_arg *)arg; + if(ai==NULL){ + hi->bitrate_av=0; + }else{ + hi->bitrate_av=(ai->bitrate_av_lo+ai->bitrate_av_hi)*.5; + } + } + return(0); + /* now deprecated *****************/ + case OV_ECTL_RATEMANAGE_HARD: + { + struct ovectl_ratemanage_arg *ai= + (struct ovectl_ratemanage_arg *)arg; + if(ai==NULL){ + hi->bitrate_min=0; + hi->bitrate_max=0; + }else{ + hi->bitrate_min=ai->bitrate_hard_min; + hi->bitrate_max=ai->bitrate_hard_max; + hi->bitrate_reservoir=ai->bitrate_hard_window* + (hi->bitrate_max+hi->bitrate_min)*.5; + } + if(hi->bitrate_reservoir<128.) + hi->bitrate_reservoir=128.; + } + return(0); + + /* replacement ratemanage interface */ + case OV_ECTL_RATEMANAGE2_GET: + { + struct ovectl_ratemanage2_arg *ai= + (struct ovectl_ratemanage2_arg *)arg; + if(ai==NULL)return OV_EINVAL; + + ai->management_active=hi->managed; + ai->bitrate_limit_min_kbps=hi->bitrate_min/1000; + ai->bitrate_limit_max_kbps=hi->bitrate_max/1000; + ai->bitrate_average_kbps=hi->bitrate_av/1000; + ai->bitrate_average_damping=hi->bitrate_av_damp; + ai->bitrate_limit_reservoir_bits=hi->bitrate_reservoir; + ai->bitrate_limit_reservoir_bias=hi->bitrate_reservoir_bias; + } + return (0); + case OV_ECTL_RATEMANAGE2_SET: + { + struct ovectl_ratemanage2_arg *ai= + (struct ovectl_ratemanage2_arg *)arg; + if(ai==NULL){ + hi->managed=0; + }else{ + /* sanity check; only catch invariant violations */ + if(ai->bitrate_limit_min_kbps>0 && + ai->bitrate_average_kbps>0 && + ai->bitrate_limit_min_kbps>ai->bitrate_average_kbps) + return OV_EINVAL; + + if(ai->bitrate_limit_max_kbps>0 && + ai->bitrate_average_kbps>0 && + ai->bitrate_limit_max_kbpsbitrate_average_kbps) + return OV_EINVAL; + + if(ai->bitrate_limit_min_kbps>0 && + ai->bitrate_limit_max_kbps>0 && + ai->bitrate_limit_min_kbps>ai->bitrate_limit_max_kbps) + return OV_EINVAL; + + if(ai->bitrate_average_damping <= 0.) + return OV_EINVAL; + + if(ai->bitrate_limit_reservoir_bits < 0) + return OV_EINVAL; + + if(ai->bitrate_limit_reservoir_bias < 0.) + return OV_EINVAL; + + if(ai->bitrate_limit_reservoir_bias > 1.) + return OV_EINVAL; + + hi->managed=ai->management_active; + hi->bitrate_min=ai->bitrate_limit_min_kbps * 1000; + hi->bitrate_max=ai->bitrate_limit_max_kbps * 1000; + hi->bitrate_av=ai->bitrate_average_kbps * 1000; + hi->bitrate_av_damp=ai->bitrate_average_damping; + hi->bitrate_reservoir=ai->bitrate_limit_reservoir_bits; + hi->bitrate_reservoir_bias=ai->bitrate_limit_reservoir_bias; + } + } + return 0; + + case OV_ECTL_LOWPASS_GET: + { + double *farg=(double *)arg; + *farg=hi->lowpass_kHz; + } + return(0); + case OV_ECTL_LOWPASS_SET: + { + double *farg=(double *)arg; + hi->lowpass_kHz=*farg; + + if(hi->lowpass_kHz<2.)hi->lowpass_kHz=2.; + if(hi->lowpass_kHz>99.)hi->lowpass_kHz=99.; + } + return(0); + case OV_ECTL_IBLOCK_GET: + { + double *farg=(double *)arg; + *farg=hi->impulse_noisetune; + } + return(0); + case OV_ECTL_IBLOCK_SET: + { + double *farg=(double *)arg; + hi->impulse_noisetune=*farg; + + if(hi->impulse_noisetune>0.)hi->impulse_noisetune=0.; + if(hi->impulse_noisetune<-15.)hi->impulse_noisetune=-15.; + } + return(0); + } + + + return(OV_EIMPL); + } + return(OV_EINVAL); +} diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/vorbisfile.c b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/vorbisfile.c new file mode 100644 index 0000000..95dacb8 --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/vorbisfile.c @@ -0,0 +1,1981 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: stdio-based convenience library for opening/seeking/decoding + last mod: $Id: vorbisfile.c 7198 2004-07-21 01:35:06Z msmith $ + + ********************************************************************/ + +#include +#include +#include +#include +#include + +#include "vorbis/codec.h" +#include "vorbis/vorbisfile.h" + +#include "os.h" +#include "misc.h" + +/* A 'chained bitstream' is a Vorbis bitstream that contains more than + one logical bitstream arranged end to end (the only form of Ogg + multiplexing allowed in a Vorbis bitstream; grouping [parallel + multiplexing] is not allowed in Vorbis) */ + +/* A Vorbis file can be played beginning to end (streamed) without + worrying ahead of time about chaining (see decoder_example.c). If + we have the whole file, however, and want random access + (seeking/scrubbing) or desire to know the total length/time of a + file, we need to account for the possibility of chaining. */ + +/* We can handle things a number of ways; we can determine the entire + bitstream structure right off the bat, or find pieces on demand. + This example determines and caches structure for the entire + bitstream, but builds a virtual decoder on the fly when moving + between links in the chain. */ + +/* There are also different ways to implement seeking. Enough + information exists in an Ogg bitstream to seek to + sample-granularity positions in the output. Or, one can seek by + picking some portion of the stream roughly in the desired area if + we only want coarse navigation through the stream. */ + +/************************************************************************* + * Many, many internal helpers. The intention is not to be confusing; + * rampant duplication and monolithic function implementation would be + * harder to understand anyway. The high level functions are last. Begin + * grokking near the end of the file */ + +/* read a little more data from the file/pipe into the ogg_sync framer +*/ +#define CHUNKSIZE 8500 /* a shade over 8k; anyone using pages well + over 8k gets what they deserve */ +static long _get_data(OggVorbis_File *vf){ + errno=0; + if(vf->datasource){ + char *buffer=ogg_sync_buffer(&vf->oy,CHUNKSIZE); + long bytes=(vf->callbacks.read_func)(buffer,1,CHUNKSIZE,vf->datasource); + if(bytes>0)ogg_sync_wrote(&vf->oy,bytes); + if(bytes==0 && errno)return(-1); + return(bytes); + }else + return(0); +} + +/* save a tiny smidge of verbosity to make the code more readable */ +static void _seek_helper(OggVorbis_File *vf,ogg_int64_t offset){ + if(vf->datasource){ + (vf->callbacks.seek_func)(vf->datasource, offset, SEEK_SET); + vf->offset=offset; + ogg_sync_reset(&vf->oy); + }else{ + /* shouldn't happen unless someone writes a broken callback */ + return; + } +} + +/* The read/seek functions track absolute position within the stream */ + +/* from the head of the stream, get the next page. boundary specifies + if the function is allowed to fetch more data from the stream (and + how much) or only use internally buffered data. + + boundary: -1) unbounded search + 0) read no additional data; use cached only + n) search for a new page beginning for n bytes + + return: <0) did not find a page (OV_FALSE, OV_EOF, OV_EREAD) + n) found a page at absolute offset n */ + +static ogg_int64_t _get_next_page(OggVorbis_File *vf,ogg_page *og, + ogg_int64_t boundary){ + if(boundary>0)boundary+=vf->offset; + while(1){ + long more; + + if(boundary>0 && vf->offset>=boundary)return(OV_FALSE); + more=ogg_sync_pageseek(&vf->oy,og); + + if(more<0){ + /* skipped n bytes */ + vf->offset-=more; + }else{ + if(more==0){ + /* send more paramedics */ + if(!boundary)return(OV_FALSE); + { + long ret=_get_data(vf); + if(ret==0)return(OV_EOF); + if(ret<0)return(OV_EREAD); + } + }else{ + /* got a page. Return the offset at the page beginning, + advance the internal offset past the page end */ + ogg_int64_t ret=vf->offset; + vf->offset+=more; + return(ret); + + } + } + } +} + +/* find the latest page beginning before the current stream cursor + position. Much dirtier than the above as Ogg doesn't have any + backward search linkage. no 'readp' as it will certainly have to + read. */ +/* returns offset or OV_EREAD, OV_FAULT */ +static ogg_int64_t _get_prev_page(OggVorbis_File *vf,ogg_page *og){ + ogg_int64_t begin=vf->offset; + ogg_int64_t end=begin; + ogg_int64_t ret; + ogg_int64_t offset=-1; + + while(offset==-1){ + begin-=CHUNKSIZE; + if(begin<0) + begin=0; + _seek_helper(vf,begin); + while(vf->offsetoffset); + if(ret==OV_EREAD)return(OV_EREAD); + if(ret<0){ + break; + }else{ + offset=ret; + } + } + } + + /* we have the offset. Actually snork and hold the page now */ + _seek_helper(vf,offset); + ret=_get_next_page(vf,og,CHUNKSIZE); + if(ret<0) + /* this shouldn't be possible */ + return(OV_EFAULT); + + return(offset); +} + +/* finds each bitstream link one at a time using a bisection search + (has to begin by knowing the offset of the lb's initial page). + Recurses for each link so it can alloc the link storage after + finding them all, then unroll and fill the cache at the same time */ +static int _bisect_forward_serialno(OggVorbis_File *vf, + ogg_int64_t begin, + ogg_int64_t searched, + ogg_int64_t end, + long currentno, + long m){ + ogg_int64_t endsearched=end; + ogg_int64_t next=end; + ogg_page og; + ogg_int64_t ret; + + /* the below guards against garbage seperating the last and + first pages of two links. */ + while(searched=0)next=ret; + }else{ + searched=ret+og.header_len+og.body_len; + } + } + + _seek_helper(vf,next); + ret=_get_next_page(vf,&og,-1); + if(ret==OV_EREAD)return(OV_EREAD); + + if(searched>=end || ret<0){ + vf->links=m+1; + vf->offsets=_ogg_malloc((vf->links+1)*sizeof(*vf->offsets)); + vf->serialnos=_ogg_malloc(vf->links*sizeof(*vf->serialnos)); + vf->offsets[m+1]=searched; + }else{ + ret=_bisect_forward_serialno(vf,next,vf->offset, + end,ogg_page_serialno(&og),m+1); + if(ret==OV_EREAD)return(OV_EREAD); + } + + vf->offsets[m]=begin; + vf->serialnos[m]=currentno; + return(0); +} + +/* uses the local ogg_stream storage in vf; this is important for + non-streaming input sources */ +static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc, + long *serialno,ogg_page *og_ptr){ + ogg_page og; + ogg_packet op; + int i,ret; + + if(!og_ptr){ + ogg_int64_t llret=_get_next_page(vf,&og,CHUNKSIZE); + if(llret==OV_EREAD)return(OV_EREAD); + if(llret<0)return OV_ENOTVORBIS; + og_ptr=&og; + } + + ogg_stream_reset_serialno(&vf->os,ogg_page_serialno(og_ptr)); + if(serialno)*serialno=vf->os.serialno; + vf->ready_state=STREAMSET; + + /* extract the initial header from the first page and verify that the + Ogg bitstream is in fact Vorbis data */ + + vorbis_info_init(vi); + vorbis_comment_init(vc); + + i=0; + while(i<3){ + ogg_stream_pagein(&vf->os,og_ptr); + while(i<3){ + int result=ogg_stream_packetout(&vf->os,&op); + if(result==0)break; + if(result==-1){ + ret=OV_EBADHEADER; + goto bail_header; + } + if((ret=vorbis_synthesis_headerin(vi,vc,&op))){ + goto bail_header; + } + i++; + } + if(i<3) + if(_get_next_page(vf,og_ptr,CHUNKSIZE)<0){ + ret=OV_EBADHEADER; + goto bail_header; + } + } + return 0; + + bail_header: + vorbis_info_clear(vi); + vorbis_comment_clear(vc); + vf->ready_state=OPENED; + + return ret; +} + +/* last step of the OggVorbis_File initialization; get all the + vorbis_info structs and PCM positions. Only called by the seekable + initialization (local stream storage is hacked slightly; pay + attention to how that's done) */ + +/* this is void and does not propogate errors up because we want to be + able to open and use damaged bitstreams as well as we can. Just + watch out for missing information for links in the OggVorbis_File + struct */ +static void _prefetch_all_headers(OggVorbis_File *vf, ogg_int64_t dataoffset){ + ogg_page og; + int i; + ogg_int64_t ret; + + vf->vi=_ogg_realloc(vf->vi,vf->links*sizeof(*vf->vi)); + vf->vc=_ogg_realloc(vf->vc,vf->links*sizeof(*vf->vc)); + vf->dataoffsets=_ogg_malloc(vf->links*sizeof(*vf->dataoffsets)); + vf->pcmlengths=_ogg_malloc(vf->links*2*sizeof(*vf->pcmlengths)); + + for(i=0;ilinks;i++){ + if(i==0){ + /* we already grabbed the initial header earlier. Just set the offset */ + vf->dataoffsets[i]=dataoffset; + _seek_helper(vf,dataoffset); + + }else{ + + /* seek to the location of the initial header */ + + _seek_helper(vf,vf->offsets[i]); + if(_fetch_headers(vf,vf->vi+i,vf->vc+i,NULL,NULL)<0){ + vf->dataoffsets[i]=-1; + }else{ + vf->dataoffsets[i]=vf->offset; + } + } + + /* fetch beginning PCM offset */ + + if(vf->dataoffsets[i]!=-1){ + ogg_int64_t accumulated=0; + long lastblock=-1; + int result; + + ogg_stream_reset_serialno(&vf->os,vf->serialnos[i]); + + while(1){ + ogg_packet op; + + ret=_get_next_page(vf,&og,-1); + if(ret<0) + /* this should not be possible unless the file is + truncated/mangled */ + break; + + if(ogg_page_serialno(&og)!=vf->serialnos[i]) + break; + + /* count blocksizes of all frames in the page */ + ogg_stream_pagein(&vf->os,&og); + while((result=ogg_stream_packetout(&vf->os,&op))){ + if(result>0){ /* ignore holes */ + long thisblock=vorbis_packet_blocksize(vf->vi+i,&op); + if(lastblock!=-1) + accumulated+=(lastblock+thisblock)>>2; + lastblock=thisblock; + } + } + + if(ogg_page_granulepos(&og)!=-1){ + /* pcm offset of last packet on the first audio page */ + accumulated= ogg_page_granulepos(&og)-accumulated; + break; + } + } + + /* less than zero? This is a stream with samples trimmed off + the beginning, a normal occurrence; set the offset to zero */ + if(accumulated<0)accumulated=0; + + vf->pcmlengths[i*2]=accumulated; + } + + /* get the PCM length of this link. To do this, + get the last page of the stream */ + { + ogg_int64_t end=vf->offsets[i+1]; + _seek_helper(vf,end); + + while(1){ + ret=_get_prev_page(vf,&og); + if(ret<0){ + /* this should not be possible */ + vorbis_info_clear(vf->vi+i); + vorbis_comment_clear(vf->vc+i); + break; + } + if(ogg_page_granulepos(&og)!=-1){ + vf->pcmlengths[i*2+1]=ogg_page_granulepos(&og)-vf->pcmlengths[i*2]; + break; + } + vf->offset=ret; + } + } + } +} + +static int _make_decode_ready(OggVorbis_File *vf){ + if(vf->ready_state>STREAMSET)return 0; + if(vf->ready_stateseekable){ + if(vorbis_synthesis_init(&vf->vd,vf->vi+vf->current_link)) + return OV_EBADLINK; + }else{ + if(vorbis_synthesis_init(&vf->vd,vf->vi)) + return OV_EBADLINK; + } + vorbis_block_init(&vf->vd,&vf->vb); + vf->ready_state=INITSET; + vf->bittrack=0.f; + vf->samptrack=0.f; + return 0; +} + +static int _open_seekable2(OggVorbis_File *vf){ + long serialno=vf->current_serialno; + ogg_int64_t dataoffset=vf->offset, end; + ogg_page og; + + /* we're partially open and have a first link header state in + storage in vf */ + /* we can seek, so set out learning all about this file */ + (vf->callbacks.seek_func)(vf->datasource,0,SEEK_END); + vf->offset=vf->end=(vf->callbacks.tell_func)(vf->datasource); + + /* We get the offset for the last page of the physical bitstream. + Most OggVorbis files will contain a single logical bitstream */ + end=_get_prev_page(vf,&og); + if(end<0)return(end); + + /* more than one logical bitstream? */ + if(ogg_page_serialno(&og)!=serialno){ + + /* Chained bitstream. Bisect-search each logical bitstream + section. Do so based on serial number only */ + if(_bisect_forward_serialno(vf,0,0,end+1,serialno,0)<0)return(OV_EREAD); + + }else{ + + /* Only one logical bitstream */ + if(_bisect_forward_serialno(vf,0,end,end+1,serialno,0))return(OV_EREAD); + + } + + /* the initial header memory is referenced by vf after; don't free it */ + _prefetch_all_headers(vf,dataoffset); + return(ov_raw_seek(vf,0)); +} + +/* clear out the current logical bitstream decoder */ +static void _decode_clear(OggVorbis_File *vf){ + vorbis_dsp_clear(&vf->vd); + vorbis_block_clear(&vf->vb); + vf->ready_state=OPENED; +} + +/* fetch and process a packet. Handles the case where we're at a + bitstream boundary and dumps the decoding machine. If the decoding + machine is unloaded, it loads it. It also keeps pcm_offset up to + date (seek and read both use this. seek uses a special hack with + readp). + + return: <0) error, OV_HOLE (lost packet) or OV_EOF + 0) need more data (only if readp==0) + 1) got a packet +*/ + +static int _fetch_and_process_packet(OggVorbis_File *vf, + ogg_packet *op_in, + int readp, + int spanp){ + ogg_page og; + + /* handle one packet. Try to fetch it from current stream state */ + /* extract packets from page */ + while(1){ + + /* process a packet if we can. If the machine isn't loaded, + neither is a page */ + if(vf->ready_state==INITSET){ + while(1) { + ogg_packet op; + ogg_packet *op_ptr=(op_in?op_in:&op); + int result=ogg_stream_packetout(&vf->os,op_ptr); + ogg_int64_t granulepos; + + op_in=NULL; + if(result==-1)return(OV_HOLE); /* hole in the data. */ + if(result>0){ + /* got a packet. process it */ + granulepos=op_ptr->granulepos; + if(!vorbis_synthesis(&vf->vb,op_ptr)){ /* lazy check for lazy + header handling. The + header packets aren't + audio, so if/when we + submit them, + vorbis_synthesis will + reject them */ + + /* suck in the synthesis data and track bitrate */ + { + int oldsamples=vorbis_synthesis_pcmout(&vf->vd,NULL); + /* for proper use of libvorbis within libvorbisfile, + oldsamples will always be zero. */ + if(oldsamples)return(OV_EFAULT); + + vorbis_synthesis_blockin(&vf->vd,&vf->vb); + vf->samptrack+=vorbis_synthesis_pcmout(&vf->vd,NULL)-oldsamples; + vf->bittrack+=op_ptr->bytes*8; + } + + /* update the pcm offset. */ + if(granulepos!=-1 && !op_ptr->e_o_s){ + int link=(vf->seekable?vf->current_link:0); + int i,samples; + + /* this packet has a pcm_offset on it (the last packet + completed on a page carries the offset) After processing + (above), we know the pcm position of the *last* sample + ready to be returned. Find the offset of the *first* + + As an aside, this trick is inaccurate if we begin + reading anew right at the last page; the end-of-stream + granulepos declares the last frame in the stream, and the + last packet of the last page may be a partial frame. + So, we need a previous granulepos from an in-sequence page + to have a reference point. Thus the !op_ptr->e_o_s clause + above */ + + if(vf->seekable && link>0) + granulepos-=vf->pcmlengths[link*2]; + if(granulepos<0)granulepos=0; /* actually, this + shouldn't be possible + here unless the stream + is very broken */ + + samples=vorbis_synthesis_pcmout(&vf->vd,NULL); + + granulepos-=samples; + for(i=0;ipcmlengths[i*2+1]; + vf->pcm_offset=granulepos; + } + return(1); + } + } + else + break; + } + } + + if(vf->ready_state>=OPENED){ + ogg_int64_t ret; + if(!readp)return(0); + if((ret=_get_next_page(vf,&og,-1))<0){ + return(OV_EOF); /* eof. + leave unitialized */ + } + + /* bitrate tracking; add the header's bytes here, the body bytes + are done by packet above */ + vf->bittrack+=og.header_len*8; + + /* has our decoding just traversed a bitstream boundary? */ + if(vf->ready_state==INITSET){ + if(vf->current_serialno!=ogg_page_serialno(&og)){ + if(!spanp) + return(OV_EOF); + + _decode_clear(vf); + + if(!vf->seekable){ + vorbis_info_clear(vf->vi); + vorbis_comment_clear(vf->vc); + } + } + } + } + + /* Do we need to load a new machine before submitting the page? */ + /* This is different in the seekable and non-seekable cases. + + In the seekable case, we already have all the header + information loaded and cached; we just initialize the machine + with it and continue on our merry way. + + In the non-seekable (streaming) case, we'll only be at a + boundary if we just left the previous logical bitstream and + we're now nominally at the header of the next bitstream + */ + + if(vf->ready_state!=INITSET){ + int link; + + if(vf->ready_stateseekable){ + vf->current_serialno=ogg_page_serialno(&og); + + /* match the serialno to bitstream section. We use this rather than + offset positions to avoid problems near logical bitstream + boundaries */ + for(link=0;linklinks;link++) + if(vf->serialnos[link]==vf->current_serialno)break; + if(link==vf->links)return(OV_EBADLINK); /* sign of a bogus + stream. error out, + leave machine + uninitialized */ + + vf->current_link=link; + + ogg_stream_reset_serialno(&vf->os,vf->current_serialno); + vf->ready_state=STREAMSET; + + }else{ + /* we're streaming */ + /* fetch the three header packets, build the info struct */ + + int ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,&og); + if(ret)return(ret); + vf->current_link++; + link=0; + } + } + + { + int ret=_make_decode_ready(vf); + if(ret<0)return ret; + } + } + ogg_stream_pagein(&vf->os,&og); + } +} + +/* if, eg, 64 bit stdio is configured by default, this will build with + fseek64 */ +static int _fseek64_wrap(FILE *f,ogg_int64_t off,int whence){ + if(f==NULL)return(-1); + return fseek(f,off,whence); +} + +static int _ov_open1(void *f,OggVorbis_File *vf,char *initial, + long ibytes, ov_callbacks callbacks){ + int offsettest=(f?callbacks.seek_func(f,0,SEEK_CUR):-1); + int ret; + + memset(vf,0,sizeof(*vf)); + vf->datasource=f; + vf->callbacks = callbacks; + + /* init the framing state */ + ogg_sync_init(&vf->oy); + + /* perhaps some data was previously read into a buffer for testing + against other stream types. Allow initialization from this + previously read data (as we may be reading from a non-seekable + stream) */ + if(initial){ + char *buffer=ogg_sync_buffer(&vf->oy,ibytes); + memcpy(buffer,initial,ibytes); + ogg_sync_wrote(&vf->oy,ibytes); + } + + /* can we seek? Stevens suggests the seek test was portable */ + if(offsettest!=-1)vf->seekable=1; + + /* No seeking yet; Set up a 'single' (current) logical bitstream + entry for partial open */ + vf->links=1; + vf->vi=_ogg_calloc(vf->links,sizeof(*vf->vi)); + vf->vc=_ogg_calloc(vf->links,sizeof(*vf->vc)); + ogg_stream_init(&vf->os,-1); /* fill in the serialno later */ + + /* Try to fetch the headers, maintaining all the storage */ + if((ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,NULL))<0){ + vf->datasource=NULL; + ov_clear(vf); + }else + vf->ready_state=PARTOPEN; + return(ret); +} + +static int _ov_open2(OggVorbis_File *vf){ + if(vf->ready_state != PARTOPEN) return OV_EINVAL; + vf->ready_state=OPENED; + if(vf->seekable){ + int ret=_open_seekable2(vf); + if(ret){ + vf->datasource=NULL; + ov_clear(vf); + } + return(ret); + }else + vf->ready_state=STREAMSET; + + return 0; +} + + +/* clear out the OggVorbis_File struct */ +int ov_clear(OggVorbis_File *vf){ + if(vf){ + vorbis_block_clear(&vf->vb); + vorbis_dsp_clear(&vf->vd); + ogg_stream_clear(&vf->os); + + if(vf->vi && vf->links){ + int i; + for(i=0;ilinks;i++){ + vorbis_info_clear(vf->vi+i); + vorbis_comment_clear(vf->vc+i); + } + _ogg_free(vf->vi); + _ogg_free(vf->vc); + } + if(vf->dataoffsets)_ogg_free(vf->dataoffsets); + if(vf->pcmlengths)_ogg_free(vf->pcmlengths); + if(vf->serialnos)_ogg_free(vf->serialnos); + if(vf->offsets)_ogg_free(vf->offsets); + ogg_sync_clear(&vf->oy); + if(vf->datasource)(vf->callbacks.close_func)(vf->datasource); + memset(vf,0,sizeof(*vf)); + } +#ifdef DEBUG_LEAKS + _VDBG_dump(); +#endif + return(0); +} + +/* inspects the OggVorbis file and finds/documents all the logical + bitstreams contained in it. Tries to be tolerant of logical + bitstream sections that are truncated/woogie. + + return: -1) error + 0) OK +*/ + +int ov_open_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes, + ov_callbacks callbacks){ + int ret=_ov_open1(f,vf,initial,ibytes,callbacks); + if(ret)return ret; + return _ov_open2(vf); +} + +int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){ + ov_callbacks callbacks = { + (size_t (*)(void *, size_t, size_t, void *)) fread, + (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap, + (int (*)(void *)) fclose, + (long (*)(void *)) ftell + }; + + return ov_open_callbacks((void *)f, vf, initial, ibytes, callbacks); +} + +/* cheap hack for game usage where downsampling is desirable; there's + no need for SRC as we can just do it cheaply in libvorbis. */ + +int ov_halfrate(OggVorbis_File *vf,int flag){ + int i; + if(vf->vi==NULL)return OV_EINVAL; + if(!vf->seekable)return OV_EINVAL; + if(vf->ready_state>=STREAMSET) + _decode_clear(vf); /* clear out stream state; later on libvorbis + will be able to swap this on the fly, but + for now dumping the decode machine is needed + to reinit the MDCT lookups. 1.1 libvorbis + is planned to be able to switch on the fly */ + + for(i=0;ilinks;i++){ + if(vorbis_synthesis_halfrate(vf->vi+i,flag)){ + ov_halfrate(vf,0); + return OV_EINVAL; + } + } + return 0; +} + +int ov_halfrate_p(OggVorbis_File *vf){ + if(vf->vi==NULL)return OV_EINVAL; + return vorbis_synthesis_halfrate_p(vf->vi); +} + +/* Only partially open the vorbis file; test for Vorbisness, and load + the headers for the first chain. Do not seek (although test for + seekability). Use ov_test_open to finish opening the file, else + ov_clear to close/free it. Same return codes as open. */ + +int ov_test_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes, + ov_callbacks callbacks) +{ + return _ov_open1(f,vf,initial,ibytes,callbacks); +} + +int ov_test(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){ + ov_callbacks callbacks = { + (size_t (*)(void *, size_t, size_t, void *)) fread, + (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap, + (int (*)(void *)) fclose, + (long (*)(void *)) ftell + }; + + return ov_test_callbacks((void *)f, vf, initial, ibytes, callbacks); +} + +int ov_test_open(OggVorbis_File *vf){ + if(vf->ready_state!=PARTOPEN)return(OV_EINVAL); + return _ov_open2(vf); +} + +/* How many logical bitstreams in this physical bitstream? */ +long ov_streams(OggVorbis_File *vf){ + return vf->links; +} + +/* Is the FILE * associated with vf seekable? */ +long ov_seekable(OggVorbis_File *vf){ + return vf->seekable; +} + +/* returns the bitrate for a given logical bitstream or the entire + physical bitstream. If the file is open for random access, it will + find the *actual* average bitrate. If the file is streaming, it + returns the nominal bitrate (if set) else the average of the + upper/lower bounds (if set) else -1 (unset). + + If you want the actual bitrate field settings, get them from the + vorbis_info structs */ + +long ov_bitrate(OggVorbis_File *vf,int i){ + if(vf->ready_state=vf->links)return(OV_EINVAL); + if(!vf->seekable && i!=0)return(ov_bitrate(vf,0)); + if(i<0){ + ogg_int64_t bits=0; + int i; + float br; + for(i=0;ilinks;i++) + bits+=(vf->offsets[i+1]-vf->dataoffsets[i])*8; + /* This once read: return(rint(bits/ov_time_total(vf,-1))); + * gcc 3.x on x86 miscompiled this at optimisation level 2 and above, + * so this is slightly transformed to make it work. + */ + br = bits/ov_time_total(vf,-1); + return(rint(br)); + }else{ + if(vf->seekable){ + /* return the actual bitrate */ + return(rint((vf->offsets[i+1]-vf->dataoffsets[i])*8/ov_time_total(vf,i))); + }else{ + /* return nominal if set */ + if(vf->vi[i].bitrate_nominal>0){ + return vf->vi[i].bitrate_nominal; + }else{ + if(vf->vi[i].bitrate_upper>0){ + if(vf->vi[i].bitrate_lower>0){ + return (vf->vi[i].bitrate_upper+vf->vi[i].bitrate_lower)/2; + }else{ + return vf->vi[i].bitrate_upper; + } + } + return(OV_FALSE); + } + } + } +} + +/* returns the actual bitrate since last call. returns -1 if no + additional data to offer since last call (or at beginning of stream), + EINVAL if stream is only partially open +*/ +long ov_bitrate_instant(OggVorbis_File *vf){ + int link=(vf->seekable?vf->current_link:0); + long ret; + if(vf->ready_statesamptrack==0)return(OV_FALSE); + ret=vf->bittrack/vf->samptrack*vf->vi[link].rate+.5; + vf->bittrack=0.f; + vf->samptrack=0.f; + return(ret); +} + +/* Guess */ +long ov_serialnumber(OggVorbis_File *vf,int i){ + if(i>=vf->links)return(ov_serialnumber(vf,vf->links-1)); + if(!vf->seekable && i>=0)return(ov_serialnumber(vf,-1)); + if(i<0){ + return(vf->current_serialno); + }else{ + return(vf->serialnos[i]); + } +} + +/* returns: total raw (compressed) length of content if i==-1 + raw (compressed) length of that logical bitstream for i==0 to n + OV_EINVAL if the stream is not seekable (we can't know the length) + or if stream is only partially open +*/ +ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i){ + if(vf->ready_stateseekable || i>=vf->links)return(OV_EINVAL); + if(i<0){ + ogg_int64_t acc=0; + int i; + for(i=0;ilinks;i++) + acc+=ov_raw_total(vf,i); + return(acc); + }else{ + return(vf->offsets[i+1]-vf->offsets[i]); + } +} + +/* returns: total PCM length (samples) of content if i==-1 PCM length + (samples) of that logical bitstream for i==0 to n + OV_EINVAL if the stream is not seekable (we can't know the + length) or only partially open +*/ +ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i){ + if(vf->ready_stateseekable || i>=vf->links)return(OV_EINVAL); + if(i<0){ + ogg_int64_t acc=0; + int i; + for(i=0;ilinks;i++) + acc+=ov_pcm_total(vf,i); + return(acc); + }else{ + return(vf->pcmlengths[i*2+1]); + } +} + +/* returns: total seconds of content if i==-1 + seconds in that logical bitstream for i==0 to n + OV_EINVAL if the stream is not seekable (we can't know the + length) or only partially open +*/ +double ov_time_total(OggVorbis_File *vf,int i){ + if(vf->ready_stateseekable || i>=vf->links)return(OV_EINVAL); + if(i<0){ + double acc=0; + int i; + for(i=0;ilinks;i++) + acc+=ov_time_total(vf,i); + return(acc); + }else{ + return((double)(vf->pcmlengths[i*2+1])/vf->vi[i].rate); + } +} + +/* seek to an offset relative to the *compressed* data. This also + scans packets to update the PCM cursor. It will cross a logical + bitstream boundary, but only if it can't get any packets out of the + tail of the bitstream we seek to (so no surprises). + + returns zero on success, nonzero on failure */ + +int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos){ + ogg_stream_state work_os; + + if(vf->ready_stateseekable) + return(OV_ENOSEEK); /* don't dump machine if we can't seek */ + + if(pos<0 || pos>vf->end)return(OV_EINVAL); + + /* don't yet clear out decoding machine (if it's initialized), in + the case we're in the same link. Restart the decode lapping, and + let _fetch_and_process_packet deal with a potential bitstream + boundary */ + vf->pcm_offset=-1; + ogg_stream_reset_serialno(&vf->os, + vf->current_serialno); /* must set serialno */ + vorbis_synthesis_restart(&vf->vd); + + _seek_helper(vf,pos); + + /* we need to make sure the pcm_offset is set, but we don't want to + advance the raw cursor past good packets just to get to the first + with a granulepos. That's not equivalent behavior to beginning + decoding as immediately after the seek position as possible. + + So, a hack. We use two stream states; a local scratch state and + the shared vf->os stream state. We use the local state to + scan, and the shared state as a buffer for later decode. + + Unfortuantely, on the last page we still advance to last packet + because the granulepos on the last page is not necessarily on a + packet boundary, and we need to make sure the granpos is + correct. + */ + + { + ogg_page og; + ogg_packet op; + int lastblock=0; + int accblock=0; + int thisblock; + int eosflag; + + ogg_stream_init(&work_os,vf->current_serialno); /* get the memory ready */ + ogg_stream_reset(&work_os); /* eliminate the spurious OV_HOLE + return from not necessarily + starting from the beginning */ + + while(1){ + if(vf->ready_state>=STREAMSET){ + /* snarf/scan a packet if we can */ + int result=ogg_stream_packetout(&work_os,&op); + + if(result>0){ + + if(vf->vi[vf->current_link].codec_setup){ + thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op); + if(thisblock<0){ + ogg_stream_packetout(&vf->os,NULL); + thisblock=0; + }else{ + + if(eosflag) + ogg_stream_packetout(&vf->os,NULL); + else + if(lastblock)accblock+=(lastblock+thisblock)>>2; + } + + if(op.granulepos!=-1){ + int i,link=vf->current_link; + ogg_int64_t granulepos=op.granulepos-vf->pcmlengths[link*2]; + if(granulepos<0)granulepos=0; + + for(i=0;ipcmlengths[i*2+1]; + vf->pcm_offset=granulepos-accblock; + break; + } + lastblock=thisblock; + continue; + }else + ogg_stream_packetout(&vf->os,NULL); + } + } + + if(!lastblock){ + if(_get_next_page(vf,&og,-1)<0){ + vf->pcm_offset=ov_pcm_total(vf,-1); + break; + } + }else{ + /* huh? Bogus stream with packets but no granulepos */ + vf->pcm_offset=-1; + break; + } + + /* has our decoding just traversed a bitstream boundary? */ + if(vf->ready_state>=STREAMSET) + if(vf->current_serialno!=ogg_page_serialno(&og)){ + _decode_clear(vf); /* clear out stream state */ + ogg_stream_clear(&work_os); + } + + if(vf->ready_statecurrent_serialno=ogg_page_serialno(&og); + for(link=0;linklinks;link++) + if(vf->serialnos[link]==vf->current_serialno)break; + if(link==vf->links)goto seek_error; /* sign of a bogus stream. + error out, leave + machine uninitialized */ + vf->current_link=link; + + ogg_stream_reset_serialno(&vf->os,vf->current_serialno); + ogg_stream_reset_serialno(&work_os,vf->current_serialno); + vf->ready_state=STREAMSET; + + } + + ogg_stream_pagein(&vf->os,&og); + ogg_stream_pagein(&work_os,&og); + eosflag=ogg_page_eos(&og); + } + } + + ogg_stream_clear(&work_os); + vf->bittrack=0.f; + vf->samptrack=0.f; + return(0); + + seek_error: + /* dump the machine so we're in a known state */ + vf->pcm_offset=-1; + ogg_stream_clear(&work_os); + _decode_clear(vf); + return OV_EBADLINK; +} + +/* Page granularity seek (faster than sample granularity because we + don't do the last bit of decode to find a specific sample). + + Seek to the last [granule marked] page preceeding the specified pos + location, such that decoding past the returned point will quickly + arrive at the requested position. */ +int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){ + int link=-1; + ogg_int64_t result=0; + ogg_int64_t total=ov_pcm_total(vf,-1); + + if(vf->ready_stateseekable)return(OV_ENOSEEK); + + if(pos<0 || pos>total)return(OV_EINVAL); + + /* which bitstream section does this pcm offset occur in? */ + for(link=vf->links-1;link>=0;link--){ + total-=vf->pcmlengths[link*2+1]; + if(pos>=total)break; + } + + /* search within the logical bitstream for the page with the highest + pcm_pos preceeding (or equal to) pos. There is a danger here; + missing pages or incorrect frame number information in the + bitstream could make our task impossible. Account for that (it + would be an error condition) */ + + /* new search algorithm by HB (Nicholas Vinen) */ + { + ogg_int64_t end=vf->offsets[link+1]; + ogg_int64_t begin=vf->offsets[link]; + ogg_int64_t begintime = vf->pcmlengths[link*2]; + ogg_int64_t endtime = vf->pcmlengths[link*2+1]+begintime; + ogg_int64_t target=pos-total+begintime; + ogg_int64_t best=begin; + + ogg_page og; + while(beginoffset); + if(result==OV_EREAD) goto seek_error; + if(result<0){ + if(bisect<=begin+1) + end=begin; /* found it */ + else{ + if(bisect==0) goto seek_error; + bisect-=CHUNKSIZE; + if(bisect<=begin)bisect=begin+1; + _seek_helper(vf,bisect); + } + }else{ + ogg_int64_t granulepos=ogg_page_granulepos(&og); + if(granulepos==-1)continue; + if(granuleposoffset; /* raw offset of next page */ + begintime=granulepos; + + if(target-begintime>44100)break; + bisect=begin; /* *not* begin + 1 */ + }else{ + if(bisect<=begin+1) + end=begin; /* found it */ + else{ + if(end==vf->offset){ /* we're pretty close - we'd be stuck in */ + end=result; + bisect-=CHUNKSIZE; /* an endless loop otherwise. */ + if(bisect<=begin)bisect=begin+1; + _seek_helper(vf,bisect); + }else{ + end=result; + endtime=granulepos; + break; + } + } + } + } + } + } + + /* found our page. seek to it, update pcm offset. Easier case than + raw_seek, don't keep packets preceeding granulepos. */ + { + ogg_page og; + ogg_packet op; + + /* seek */ + _seek_helper(vf,best); + vf->pcm_offset=-1; + + if(_get_next_page(vf,&og,-1)<0)return(OV_EOF); /* shouldn't happen */ + + if(link!=vf->current_link){ + /* Different link; dump entire decode machine */ + _decode_clear(vf); + + vf->current_link=link; + vf->current_serialno=ogg_page_serialno(&og); + vf->ready_state=STREAMSET; + + }else{ + vorbis_synthesis_restart(&vf->vd); + } + + ogg_stream_reset_serialno(&vf->os,vf->current_serialno); + ogg_stream_pagein(&vf->os,&og); + + /* pull out all but last packet; the one with granulepos */ + while(1){ + result=ogg_stream_packetpeek(&vf->os,&op); + if(result==0){ + /* !!! the packet finishing this page originated on a + preceeding page. Keep fetching previous pages until we + get one with a granulepos or without the 'continued' flag + set. Then just use raw_seek for simplicity. */ + + _seek_helper(vf,best); + + while(1){ + result=_get_prev_page(vf,&og); + if(result<0) goto seek_error; + if(ogg_page_granulepos(&og)>-1 || + !ogg_page_continued(&og)){ + return ov_raw_seek(vf,result); + } + vf->offset=result; + } + } + if(result<0){ + result = OV_EBADPACKET; + goto seek_error; + } + if(op.granulepos!=-1){ + vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2]; + if(vf->pcm_offset<0)vf->pcm_offset=0; + vf->pcm_offset+=total; + break; + }else + result=ogg_stream_packetout(&vf->os,NULL); + } + } + } + + /* verify result */ + if(vf->pcm_offset>pos || pos>ov_pcm_total(vf,-1)){ + result=OV_EFAULT; + goto seek_error; + } + vf->bittrack=0.f; + vf->samptrack=0.f; + return(0); + + seek_error: + /* dump machine so we're in a known state */ + vf->pcm_offset=-1; + _decode_clear(vf); + return (int)result; +} + +/* seek to a sample offset relative to the decompressed pcm stream + returns zero on success, nonzero on failure */ + +int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){ + int thisblock,lastblock=0; + int ret=ov_pcm_seek_page(vf,pos); + if(ret<0)return(ret); + if((ret=_make_decode_ready(vf)))return ret; + + /* discard leading packets we don't need for the lapping of the + position we want; don't decode them */ + + while(1){ + ogg_packet op; + ogg_page og; + + int ret=ogg_stream_packetpeek(&vf->os,&op); + if(ret>0){ + thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op); + if(thisblock<0){ + ogg_stream_packetout(&vf->os,NULL); + continue; /* non audio packet */ + } + if(lastblock)vf->pcm_offset+=(lastblock+thisblock)>>2; + + if(vf->pcm_offset+((thisblock+ + vorbis_info_blocksize(vf->vi,1))>>2)>=pos)break; + + /* remove the packet from packet queue and track its granulepos */ + ogg_stream_packetout(&vf->os,NULL); + vorbis_synthesis_trackonly(&vf->vb,&op); /* set up a vb with + only tracking, no + pcm_decode */ + vorbis_synthesis_blockin(&vf->vd,&vf->vb); + + /* end of logical stream case is hard, especially with exact + length positioning. */ + + if(op.granulepos>-1){ + int i; + /* always believe the stream markers */ + vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2]; + if(vf->pcm_offset<0)vf->pcm_offset=0; + for(i=0;icurrent_link;i++) + vf->pcm_offset+=vf->pcmlengths[i*2+1]; + } + + lastblock=thisblock; + + }else{ + if(ret<0 && ret!=OV_HOLE)break; + + /* suck in a new page */ + if(_get_next_page(vf,&og,-1)<0)break; + if(vf->current_serialno!=ogg_page_serialno(&og))_decode_clear(vf); + + if(vf->ready_statecurrent_serialno=ogg_page_serialno(&og); + for(link=0;linklinks;link++) + if(vf->serialnos[link]==vf->current_serialno)break; + if(link==vf->links)return(OV_EBADLINK); + vf->current_link=link; + + ogg_stream_reset_serialno(&vf->os,vf->current_serialno); + vf->ready_state=STREAMSET; + ret=_make_decode_ready(vf); + if(ret)return ret; + lastblock=0; + } + + ogg_stream_pagein(&vf->os,&og); + } + } + + vf->bittrack=0.f; + vf->samptrack=0.f; + /* discard samples until we reach the desired position. Crossing a + logical bitstream boundary with abandon is OK. */ + while(vf->pcm_offsetpcm_offset; + long samples=vorbis_synthesis_pcmout(&vf->vd,NULL); + + if(samples>target)samples=target; + vorbis_synthesis_read(&vf->vd,samples); + vf->pcm_offset+=samples; + + if(samplespcm_offset=ov_pcm_total(vf,-1); /* eof */ + } + return 0; +} + +/* seek to a playback time relative to the decompressed pcm stream + returns zero on success, nonzero on failure */ +int ov_time_seek(OggVorbis_File *vf,double seconds){ + /* translate time to PCM position and call ov_pcm_seek */ + + int link=-1; + ogg_int64_t pcm_total=ov_pcm_total(vf,-1); + double time_total=ov_time_total(vf,-1); + + if(vf->ready_stateseekable)return(OV_ENOSEEK); + if(seconds<0 || seconds>time_total)return(OV_EINVAL); + + /* which bitstream section does this time offset occur in? */ + for(link=vf->links-1;link>=0;link--){ + pcm_total-=vf->pcmlengths[link*2+1]; + time_total-=ov_time_total(vf,link); + if(seconds>=time_total)break; + } + + /* enough information to convert time offset to pcm offset */ + { + ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate; + return(ov_pcm_seek(vf,target)); + } +} + +/* page-granularity version of ov_time_seek + returns zero on success, nonzero on failure */ +int ov_time_seek_page(OggVorbis_File *vf,double seconds){ + /* translate time to PCM position and call ov_pcm_seek */ + + int link=-1; + ogg_int64_t pcm_total=ov_pcm_total(vf,-1); + double time_total=ov_time_total(vf,-1); + + if(vf->ready_stateseekable)return(OV_ENOSEEK); + if(seconds<0 || seconds>time_total)return(OV_EINVAL); + + /* which bitstream section does this time offset occur in? */ + for(link=vf->links-1;link>=0;link--){ + pcm_total-=vf->pcmlengths[link*2+1]; + time_total-=ov_time_total(vf,link); + if(seconds>=time_total)break; + } + + /* enough information to convert time offset to pcm offset */ + { + ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate; + return(ov_pcm_seek_page(vf,target)); + } +} + +/* tell the current stream offset cursor. Note that seek followed by + tell will likely not give the set offset due to caching */ +ogg_int64_t ov_raw_tell(OggVorbis_File *vf){ + if(vf->ready_stateoffset); +} + +/* return PCM offset (sample) of next PCM sample to be read */ +ogg_int64_t ov_pcm_tell(OggVorbis_File *vf){ + if(vf->ready_statepcm_offset); +} + +/* return time offset (seconds) of next PCM sample to be read */ +double ov_time_tell(OggVorbis_File *vf){ + int link=0; + ogg_int64_t pcm_total=0; + double time_total=0.f; + + if(vf->ready_stateseekable){ + pcm_total=ov_pcm_total(vf,-1); + time_total=ov_time_total(vf,-1); + + /* which bitstream section does this time offset occur in? */ + for(link=vf->links-1;link>=0;link--){ + pcm_total-=vf->pcmlengths[link*2+1]; + time_total-=ov_time_total(vf,link); + if(vf->pcm_offset>=pcm_total)break; + } + } + + return((double)time_total+(double)(vf->pcm_offset-pcm_total)/vf->vi[link].rate); +} + +/* link: -1) return the vorbis_info struct for the bitstream section + currently being decoded + 0-n) to request information for a specific bitstream section + + In the case of a non-seekable bitstream, any call returns the + current bitstream. NULL in the case that the machine is not + initialized */ + +vorbis_info *ov_info(OggVorbis_File *vf,int link){ + if(vf->seekable){ + if(link<0) + if(vf->ready_state>=STREAMSET) + return vf->vi+vf->current_link; + else + return vf->vi; + else + if(link>=vf->links) + return NULL; + else + return vf->vi+link; + }else{ + return vf->vi; + } +} + +/* grr, strong typing, grr, no templates/inheritence, grr */ +vorbis_comment *ov_comment(OggVorbis_File *vf,int link){ + if(vf->seekable){ + if(link<0) + if(vf->ready_state>=STREAMSET) + return vf->vc+vf->current_link; + else + return vf->vc; + else + if(link>=vf->links) + return NULL; + else + return vf->vc+link; + }else{ + return vf->vc; + } +} + +static int host_is_big_endian() { + ogg_int32_t pattern = 0xfeedface; /* deadbeef */ + unsigned char *bytewise = (unsigned char *)&pattern; + if (bytewise[0] == 0xfe) return 1; + return 0; +} + +/* up to this point, everything could more or less hide the multiple + logical bitstream nature of chaining from the toplevel application + if the toplevel application didn't particularly care. However, at + the point that we actually read audio back, the multiple-section + nature must surface: Multiple bitstream sections do not necessarily + have to have the same number of channels or sampling rate. + + ov_read returns the sequential logical bitstream number currently + being decoded along with the PCM data in order that the toplevel + application can take action on channel/sample rate changes. This + number will be incremented even for streamed (non-seekable) streams + (for seekable streams, it represents the actual logical bitstream + index within the physical bitstream. Note that the accessor + functions above are aware of this dichotomy). + + input values: buffer) a buffer to hold packed PCM data for return + length) the byte length requested to be placed into buffer + bigendianp) should the data be packed LSB first (0) or + MSB first (1) + word) word size for output. currently 1 (byte) or + 2 (16 bit short) + + return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL) + 0) EOF + n) number of bytes of PCM actually returned. The + below works on a packet-by-packet basis, so the + return length is not related to the 'length' passed + in, just guaranteed to fit. + + *section) set to the logical bitstream number */ + +long ov_read(OggVorbis_File *vf,char *buffer,int length, + int bigendianp,int word,int sgned,int *bitstream){ + int i,j; + int host_endian = host_is_big_endian(); + + float **pcm; + long samples; + + if(vf->ready_stateready_state==INITSET){ + samples=vorbis_synthesis_pcmout(&vf->vd,&pcm); + if(samples)break; + } + + /* suck in another packet */ + { + int ret=_fetch_and_process_packet(vf,NULL,1,1); + if(ret==OV_EOF) + return(0); + if(ret<=0) + return(ret); + } + + } + + if(samples>0){ + + /* yay! proceed to pack data into the byte buffer */ + + long channels=ov_info(vf,-1)->channels; + long bytespersample=word * channels; + vorbis_fpu_control fpu; + if(samples>length/bytespersample)samples=length/bytespersample; + + if(samples <= 0) + return OV_EINVAL; + + /* a tight loop to pack each size */ + { + int val; + if(word==1){ + int off=(sgned?0:128); + vorbis_fpu_setround(&fpu); + for(j=0;j127)val=127; + else if(val<-128)val=-128; + *buffer++=val+off; + } + vorbis_fpu_restore(fpu); + }else{ + int off=(sgned?0:32768); + + if(host_endian==bigendianp){ + if(sgned){ + + vorbis_fpu_setround(&fpu); + for(i=0;i32767)val=32767; + else if(val<-32768)val=-32768; + *dest=val; + dest+=channels; + } + } + vorbis_fpu_restore(fpu); + + }else{ + + vorbis_fpu_setround(&fpu); + for(i=0;i32767)val=32767; + else if(val<-32768)val=-32768; + *dest=val+off; + dest+=channels; + } + } + vorbis_fpu_restore(fpu); + + } + }else if(bigendianp){ + + vorbis_fpu_setround(&fpu); + for(j=0;j32767)val=32767; + else if(val<-32768)val=-32768; + val+=off; + *buffer++=(val>>8); + *buffer++=(val&0xff); + } + vorbis_fpu_restore(fpu); + + }else{ + int val; + vorbis_fpu_setround(&fpu); + for(j=0;j32767)val=32767; + else if(val<-32768)val=-32768; + val+=off; + *buffer++=(val&0xff); + *buffer++=(val>>8); + } + vorbis_fpu_restore(fpu); + + } + } + } + + vorbis_synthesis_read(&vf->vd,samples); + vf->pcm_offset+=samples; + if(bitstream)*bitstream=vf->current_link; + return(samples*bytespersample); + }else{ + return(samples); + } +} + +/* input values: pcm_channels) a float vector per channel of output + length) the sample length being read by the app + + return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL) + 0) EOF + n) number of samples of PCM actually returned. The + below works on a packet-by-packet basis, so the + return length is not related to the 'length' passed + in, just guaranteed to fit. + + *section) set to the logical bitstream number */ + + + +long ov_read_float(OggVorbis_File *vf,float ***pcm_channels,int length, + int *bitstream){ + + if(vf->ready_stateready_state==INITSET){ + float **pcm; + long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm); + if(samples){ + if(pcm_channels)*pcm_channels=pcm; + if(samples>length)samples=length; + vorbis_synthesis_read(&vf->vd,samples); + vf->pcm_offset+=samples; + if(bitstream)*bitstream=vf->current_link; + return samples; + + } + } + + /* suck in another packet */ + { + int ret=_fetch_and_process_packet(vf,NULL,1,1); + if(ret==OV_EOF)return(0); + if(ret<=0)return(ret); + } + + } +} + +extern float *vorbis_window(vorbis_dsp_state *v,int W); +extern void _analysis_output_always(char *base,int i,float *v,int n,int bark,int dB, + ogg_int64_t off); + +static void _ov_splice(float **pcm,float **lappcm, + int n1, int n2, + int ch1, int ch2, + float *w1, float *w2){ + int i,j; + float *w=w1; + int n=n1; + + if(n1>n2){ + n=n2; + w=w2; + } + + /* splice */ + for(j=0;jready_state==INITSET)break; + /* suck in another packet */ + { + int ret=_fetch_and_process_packet(vf,NULL,1,0); + if(ret<0 && ret!=OV_HOLE)return(ret); + } + } + return 0; +} + +/* make sure vf is INITSET and that we have a primed buffer; if + we're crosslapping at a stream section boundary, this also makes + sure we're sanity checking against the right stream information */ +static int _ov_initprime(OggVorbis_File *vf){ + vorbis_dsp_state *vd=&vf->vd; + while(1){ + if(vf->ready_state==INITSET) + if(vorbis_synthesis_pcmout(vd,NULL))break; + + /* suck in another packet */ + { + int ret=_fetch_and_process_packet(vf,NULL,1,0); + if(ret<0 && ret!=OV_HOLE)return(ret); + } + } + return 0; +} + +/* grab enough data for lapping from vf; this may be in the form of + unreturned, already-decoded pcm, remaining PCM we will need to + decode, or synthetic postextrapolation from last packets. */ +static void _ov_getlap(OggVorbis_File *vf,vorbis_info *vi,vorbis_dsp_state *vd, + float **lappcm,int lapsize){ + int lapcount=0,i; + float **pcm; + + /* try first to decode the lapping data */ + while(lapcountlapsize-lapcount)samples=lapsize-lapcount; + for(i=0;ichannels;i++) + memcpy(lappcm[i]+lapcount,pcm[i],sizeof(**pcm)*samples); + lapcount+=samples; + vorbis_synthesis_read(vd,samples); + }else{ + /* suck in another packet */ + int ret=_fetch_and_process_packet(vf,NULL,1,0); /* do *not* span */ + if(ret==OV_EOF)break; + } + } + if(lapcountvd,&pcm); + if(samples==0){ + for(i=0;ichannels;i++) + memset(lappcm[i]+lapcount,0,sizeof(**pcm)*lapsize-lapcount); + lapcount=lapsize; + }else{ + if(samples>lapsize-lapcount)samples=lapsize-lapcount; + for(i=0;ichannels;i++) + memcpy(lappcm[i]+lapcount,pcm[i],sizeof(**pcm)*samples); + lapcount+=samples; + } + } +} + +/* this sets up crosslapping of a sample by using trailing data from + sample 1 and lapping it into the windowing buffer of sample 2 */ +int ov_crosslap(OggVorbis_File *vf1, OggVorbis_File *vf2){ + vorbis_info *vi1,*vi2; + float **lappcm; + float **pcm; + float *w1,*w2; + int n1,n2,i,ret,hs1,hs2; + + if(vf1==vf2)return(0); /* degenerate case */ + if(vf1->ready_stateready_statechannels); + n1=vorbis_info_blocksize(vi1,0)>>(1+hs1); + n2=vorbis_info_blocksize(vi2,0)>>(1+hs2); + w1=vorbis_window(&vf1->vd,0); + w2=vorbis_window(&vf2->vd,0); + + for(i=0;ichannels;i++) + lappcm[i]=alloca(sizeof(**lappcm)*n1); + + _ov_getlap(vf1,vi1,&vf1->vd,lappcm,n1); + + /* have a lapping buffer from vf1; now to splice it into the lapping + buffer of vf2 */ + /* consolidate and expose the buffer. */ + vorbis_synthesis_lapout(&vf2->vd,&pcm); + _analysis_output_always("pcmL",0,pcm[0],n1*2,0,0,0); + _analysis_output_always("pcmR",0,pcm[1],n1*2,0,0,0); + + /* splice */ + _ov_splice(pcm,lappcm,n1,n2,vi1->channels,vi2->channels,w1,w2); + + /* done */ + return(0); +} + +static int _ov_64_seek_lap(OggVorbis_File *vf,ogg_int64_t pos, + int (*localseek)(OggVorbis_File *,ogg_int64_t)){ + vorbis_info *vi; + float **lappcm; + float **pcm; + float *w1,*w2; + int n1,n2,ch1,ch2,hs; + int i,ret; + + if(vf->ready_statechannels; + n1=vorbis_info_blocksize(vi,0)>>(1+hs); + w1=vorbis_window(&vf->vd,0); /* window arrays from libvorbis are + persistent; even if the decode state + from this link gets dumped, this + window array continues to exist */ + + lappcm=alloca(sizeof(*lappcm)*ch1); + for(i=0;ivd,lappcm,n1); + + /* have lapping data; seek and prime the buffer */ + ret=localseek(vf,pos); + if(ret)return ret; + ret=_ov_initprime(vf); + if(ret)return(ret); + + /* Guard against cross-link changes; they're perfectly legal */ + vi=ov_info(vf,-1); + ch2=vi->channels; + n2=vorbis_info_blocksize(vi,0)>>(1+hs); + w2=vorbis_window(&vf->vd,0); + + /* consolidate and expose the buffer. */ + vorbis_synthesis_lapout(&vf->vd,&pcm); + + /* splice */ + _ov_splice(pcm,lappcm,n1,n2,ch1,ch2,w1,w2); + + /* done */ + return(0); +} + +int ov_raw_seek_lap(OggVorbis_File *vf,ogg_int64_t pos){ + return _ov_64_seek_lap(vf,pos,ov_raw_seek); +} + +int ov_pcm_seek_lap(OggVorbis_File *vf,ogg_int64_t pos){ + return _ov_64_seek_lap(vf,pos,ov_pcm_seek); +} + +int ov_pcm_seek_page_lap(OggVorbis_File *vf,ogg_int64_t pos){ + return _ov_64_seek_lap(vf,pos,ov_pcm_seek_page); +} + +static int _ov_d_seek_lap(OggVorbis_File *vf,double pos, + int (*localseek)(OggVorbis_File *,double)){ + vorbis_info *vi; + float **lappcm; + float **pcm; + float *w1,*w2; + int n1,n2,ch1,ch2,hs; + int i,ret; + + if(vf->ready_statechannels; + n1=vorbis_info_blocksize(vi,0)>>(1+hs); + w1=vorbis_window(&vf->vd,0); /* window arrays from libvorbis are + persistent; even if the decode state + from this link gets dumped, this + window array continues to exist */ + + lappcm=alloca(sizeof(*lappcm)*ch1); + for(i=0;ivd,lappcm,n1); + + /* have lapping data; seek and prime the buffer */ + ret=localseek(vf,pos); + if(ret)return ret; + ret=_ov_initprime(vf); + if(ret)return(ret); + + /* Guard against cross-link changes; they're perfectly legal */ + vi=ov_info(vf,-1); + ch2=vi->channels; + n2=vorbis_info_blocksize(vi,0)>>(1+hs); + w2=vorbis_window(&vf->vd,0); + + /* consolidate and expose the buffer. */ + vorbis_synthesis_lapout(&vf->vd,&pcm); + + /* splice */ + _ov_splice(pcm,lappcm,n1,n2,ch1,ch2,w1,w2); + + /* done */ + return(0); +} + +int ov_time_seek_lap(OggVorbis_File *vf,double pos){ + return _ov_d_seek_lap(vf,pos,ov_time_seek); +} + +int ov_time_seek_page_lap(OggVorbis_File *vf,double pos){ + return _ov_d_seek_lap(vf,pos,ov_time_seek_page); +} diff --git a/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/window.c b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/window.c new file mode 100644 index 0000000..38dd8fa --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/libvorbis-1.1.2/lib/window.c @@ -0,0 +1,2136 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: window functions + last mod: $Id: window.c 7187 2004-07-20 07:24:27Z xiphmont $ + + ********************************************************************/ + +#include +#include +#include "os.h" +#include "misc.h" + +static float vwin64[32] = { + 0.0009460463F, 0.0085006468F, 0.0235352254F, 0.0458950567F, + 0.0753351908F, 0.1115073077F, 0.1539457973F, 0.2020557475F, + 0.2551056759F, 0.3122276645F, 0.3724270287F, 0.4346027792F, + 0.4975789974F, 0.5601459521F, 0.6211085051F, 0.6793382689F, + 0.7338252629F, 0.7837245849F, 0.8283939355F, 0.8674186656F, + 0.9006222429F, 0.9280614787F, 0.9500073081F, 0.9669131782F, + 0.9793740220F, 0.9880792941F, 0.9937636139F, 0.9971582668F, + 0.9989462667F, 0.9997230082F, 0.9999638688F, 0.9999995525F, +}; + +static float vwin128[64] = { + 0.0002365472F, 0.0021280687F, 0.0059065254F, 0.0115626550F, + 0.0190823442F, 0.0284463735F, 0.0396300935F, 0.0526030430F, + 0.0673285281F, 0.0837631763F, 0.1018564887F, 0.1215504095F, + 0.1427789367F, 0.1654677960F, 0.1895342001F, 0.2148867160F, + 0.2414252576F, 0.2690412240F, 0.2976177952F, 0.3270303960F, + 0.3571473350F, 0.3878306189F, 0.4189369387F, 0.4503188188F, + 0.4818259135F, 0.5133064334F, 0.5446086751F, 0.5755826278F, + 0.6060816248F, 0.6359640047F, 0.6650947483F, 0.6933470543F, + 0.7206038179F, 0.7467589810F, 0.7717187213F, 0.7954024542F, + 0.8177436264F, 0.8386902831F, 0.8582053981F, 0.8762669622F, + 0.8928678298F, 0.9080153310F, 0.9217306608F, 0.9340480615F, + 0.9450138200F, 0.9546851041F, 0.9631286621F, 0.9704194171F, + 0.9766389810F, 0.9818741197F, 0.9862151938F, 0.9897546035F, + 0.9925852598F, 0.9947991032F, 0.9964856900F, 0.9977308602F, + 0.9986155015F, 0.9992144193F, 0.9995953200F, 0.9998179155F, + 0.9999331503F, 0.9999825563F, 0.9999977357F, 0.9999999720F, +}; + +static float vwin256[128] = { + 0.0000591390F, 0.0005321979F, 0.0014780301F, 0.0028960636F, + 0.0047854363F, 0.0071449926F, 0.0099732775F, 0.0132685298F, + 0.0170286741F, 0.0212513119F, 0.0259337111F, 0.0310727950F, + 0.0366651302F, 0.0427069140F, 0.0491939614F, 0.0561216907F, + 0.0634851102F, 0.0712788035F, 0.0794969160F, 0.0881331402F, + 0.0971807028F, 0.1066323515F, 0.1164803426F, 0.1267164297F, + 0.1373318534F, 0.1483173323F, 0.1596630553F, 0.1713586755F, + 0.1833933062F, 0.1957555184F, 0.2084333404F, 0.2214142599F, + 0.2346852280F, 0.2482326664F, 0.2620424757F, 0.2761000481F, + 0.2903902813F, 0.3048975959F, 0.3196059553F, 0.3344988887F, + 0.3495595160F, 0.3647705766F, 0.3801144597F, 0.3955732382F, + 0.4111287047F, 0.4267624093F, 0.4424557009F, 0.4581897696F, + 0.4739456913F, 0.4897044744F, 0.5054471075F, 0.5211546088F, + 0.5368080763F, 0.5523887395F, 0.5678780103F, 0.5832575361F, + 0.5985092508F, 0.6136154277F, 0.6285587300F, 0.6433222619F, + 0.6578896175F, 0.6722449294F, 0.6863729144F, 0.7002589187F, + 0.7138889597F, 0.7272497662F, 0.7403288154F, 0.7531143679F, + 0.7655954985F, 0.7777621249F, 0.7896050322F, 0.8011158947F, + 0.8122872932F, 0.8231127294F, 0.8335866365F, 0.8437043850F, + 0.8534622861F, 0.8628575905F, 0.8718884835F, 0.8805540765F, + 0.8888543947F, 0.8967903616F, 0.9043637797F, 0.9115773078F, + 0.9184344360F, 0.9249394562F, 0.9310974312F, 0.9369141608F, + 0.9423961446F, 0.9475505439F, 0.9523851406F, 0.9569082947F, + 0.9611289005F, 0.9650563408F, 0.9687004405F, 0.9720714191F, + 0.9751798427F, 0.9780365753F, 0.9806527301F, 0.9830396204F, + 0.9852087111F, 0.9871715701F, 0.9889398207F, 0.9905250941F, + 0.9919389832F, 0.9931929973F, 0.9942985174F, 0.9952667537F, + 0.9961087037F, 0.9968351119F, 0.9974564312F, 0.9979827858F, + 0.9984239359F, 0.9987892441F, 0.9990876435F, 0.9993276081F, + 0.9995171241F, 0.9996636648F, 0.9997741654F, 0.9998550016F, + 0.9999119692F, 0.9999502656F, 0.9999744742F, 0.9999885497F, + 0.9999958064F, 0.9999989077F, 0.9999998584F, 0.9999999983F, +}; + +static float vwin512[256] = { + 0.0000147849F, 0.0001330607F, 0.0003695946F, 0.0007243509F, + 0.0011972759F, 0.0017882983F, 0.0024973285F, 0.0033242588F, + 0.0042689632F, 0.0053312973F, 0.0065110982F, 0.0078081841F, + 0.0092223540F, 0.0107533880F, 0.0124010466F, 0.0141650703F, + 0.0160451800F, 0.0180410758F, 0.0201524373F, 0.0223789233F, + 0.0247201710F, 0.0271757958F, 0.0297453914F, 0.0324285286F, + 0.0352247556F, 0.0381335972F, 0.0411545545F, 0.0442871045F, + 0.0475306997F, 0.0508847676F, 0.0543487103F, 0.0579219038F, + 0.0616036982F, 0.0653934164F, 0.0692903546F, 0.0732937809F, + 0.0774029356F, 0.0816170305F, 0.0859352485F, 0.0903567428F, + 0.0948806375F, 0.0995060259F, 0.1042319712F, 0.1090575056F, + 0.1139816300F, 0.1190033137F, 0.1241214941F, 0.1293350764F, + 0.1346429333F, 0.1400439046F, 0.1455367974F, 0.1511203852F, + 0.1567934083F, 0.1625545735F, 0.1684025537F, 0.1743359881F, + 0.1803534820F, 0.1864536069F, 0.1926349000F, 0.1988958650F, + 0.2052349715F, 0.2116506555F, 0.2181413191F, 0.2247053313F, + 0.2313410275F, 0.2380467105F, 0.2448206500F, 0.2516610835F, + 0.2585662164F, 0.2655342226F, 0.2725632448F, 0.2796513950F, + 0.2867967551F, 0.2939973773F, 0.3012512852F, 0.3085564739F, + 0.3159109111F, 0.3233125375F, 0.3307592680F, 0.3382489922F, + 0.3457795756F, 0.3533488602F, 0.3609546657F, 0.3685947904F, + 0.3762670121F, 0.3839690896F, 0.3916987634F, 0.3994537572F, + 0.4072317788F, 0.4150305215F, 0.4228476653F, 0.4306808783F, + 0.4385278181F, 0.4463861329F, 0.4542534630F, 0.4621274424F, + 0.4700057001F, 0.4778858615F, 0.4857655502F, 0.4936423891F, + 0.5015140023F, 0.5093780165F, 0.5172320626F, 0.5250737772F, + 0.5329008043F, 0.5407107971F, 0.5485014192F, 0.5562703465F, + 0.5640152688F, 0.5717338914F, 0.5794239366F, 0.5870831457F, + 0.5947092801F, 0.6023001235F, 0.6098534829F, 0.6173671907F, + 0.6248391059F, 0.6322671161F, 0.6396491384F, 0.6469831217F, + 0.6542670475F, 0.6614989319F, 0.6686768267F, 0.6757988210F, + 0.6828630426F, 0.6898676592F, 0.6968108799F, 0.7036909564F, + 0.7105061843F, 0.7172549043F, 0.7239355032F, 0.7305464154F, + 0.7370861235F, 0.7435531598F, 0.7499461068F, 0.7562635986F, + 0.7625043214F, 0.7686670148F, 0.7747504721F, 0.7807535410F, + 0.7866751247F, 0.7925141825F, 0.7982697296F, 0.8039408387F, + 0.8095266395F, 0.8150263196F, 0.8204391248F, 0.8257643590F, + 0.8310013848F, 0.8361496236F, 0.8412085555F, 0.8461777194F, + 0.8510567129F, 0.8558451924F, 0.8605428730F, 0.8651495278F, + 0.8696649882F, 0.8740891432F, 0.8784219392F, 0.8826633797F, + 0.8868135244F, 0.8908724888F, 0.8948404441F, 0.8987176157F, + 0.9025042831F, 0.9062007791F, 0.9098074886F, 0.9133248482F, + 0.9167533451F, 0.9200935163F, 0.9233459472F, 0.9265112712F, + 0.9295901680F, 0.9325833632F, 0.9354916263F, 0.9383157705F, + 0.9410566504F, 0.9437151618F, 0.9462922398F, 0.9487888576F, + 0.9512060252F, 0.9535447882F, 0.9558062262F, 0.9579914516F, + 0.9601016078F, 0.9621378683F, 0.9641014348F, 0.9659935361F, + 0.9678154261F, 0.9695683830F, 0.9712537071F, 0.9728727198F, + 0.9744267618F, 0.9759171916F, 0.9773453842F, 0.9787127293F, + 0.9800206298F, 0.9812705006F, 0.9824637665F, 0.9836018613F, + 0.9846862258F, 0.9857183066F, 0.9866995544F, 0.9876314227F, + 0.9885153662F, 0.9893528393F, 0.9901452948F, 0.9908941823F, + 0.9916009470F, 0.9922670279F, 0.9928938570F, 0.9934828574F, + 0.9940354423F, 0.9945530133F, 0.9950369595F, 0.9954886562F, + 0.9959094633F, 0.9963007242F, 0.9966637649F, 0.9969998925F, + 0.9973103939F, 0.9975965351F, 0.9978595598F, 0.9981006885F, + 0.9983211172F, 0.9985220166F, 0.9987045311F, 0.9988697776F, + 0.9990188449F, 0.9991527924F, 0.9992726499F, 0.9993794157F, + 0.9994740570F, 0.9995575079F, 0.9996306699F, 0.9996944099F, + 0.9997495605F, 0.9997969190F, 0.9998372465F, 0.9998712678F, + 0.9998996704F, 0.9999231041F, 0.9999421807F, 0.9999574732F, + 0.9999695157F, 0.9999788026F, 0.9999857885F, 0.9999908879F, + 0.9999944746F, 0.9999968817F, 0.9999984010F, 0.9999992833F, + 0.9999997377F, 0.9999999317F, 0.9999999911F, 0.9999999999F, +}; + +static float vwin1024[512] = { + 0.0000036962F, 0.0000332659F, 0.0000924041F, 0.0001811086F, + 0.0002993761F, 0.0004472021F, 0.0006245811F, 0.0008315063F, + 0.0010679699F, 0.0013339631F, 0.0016294757F, 0.0019544965F, + 0.0023090133F, 0.0026930125F, 0.0031064797F, 0.0035493989F, + 0.0040217533F, 0.0045235250F, 0.0050546946F, 0.0056152418F, + 0.0062051451F, 0.0068243817F, 0.0074729278F, 0.0081507582F, + 0.0088578466F, 0.0095941655F, 0.0103596863F, 0.0111543789F, + 0.0119782122F, 0.0128311538F, 0.0137131701F, 0.0146242260F, + 0.0155642855F, 0.0165333111F, 0.0175312640F, 0.0185581042F, + 0.0196137903F, 0.0206982797F, 0.0218115284F, 0.0229534910F, + 0.0241241208F, 0.0253233698F, 0.0265511886F, 0.0278075263F, + 0.0290923308F, 0.0304055484F, 0.0317471241F, 0.0331170013F, + 0.0345151222F, 0.0359414274F, 0.0373958560F, 0.0388783456F, + 0.0403888325F, 0.0419272511F, 0.0434935347F, 0.0450876148F, + 0.0467094213F, 0.0483588828F, 0.0500359261F, 0.0517404765F, + 0.0534724575F, 0.0552317913F, 0.0570183983F, 0.0588321971F, + 0.0606731048F, 0.0625410369F, 0.0644359070F, 0.0663576272F, + 0.0683061077F, 0.0702812571F, 0.0722829821F, 0.0743111878F, + 0.0763657775F, 0.0784466526F, 0.0805537129F, 0.0826868561F, + 0.0848459782F, 0.0870309736F, 0.0892417345F, 0.0914781514F, + 0.0937401128F, 0.0960275056F, 0.0983402145F, 0.1006781223F, + 0.1030411101F, 0.1054290568F, 0.1078418397F, 0.1102793336F, + 0.1127414119F, 0.1152279457F, 0.1177388042F, 0.1202738544F, + 0.1228329618F, 0.1254159892F, 0.1280227980F, 0.1306532471F, + 0.1333071937F, 0.1359844927F, 0.1386849970F, 0.1414085575F, + 0.1441550230F, 0.1469242403F, 0.1497160539F, 0.1525303063F, + 0.1553668381F, 0.1582254875F, 0.1611060909F, 0.1640084822F, + 0.1669324936F, 0.1698779549F, 0.1728446939F, 0.1758325362F, + 0.1788413055F, 0.1818708232F, 0.1849209084F, 0.1879913785F, + 0.1910820485F, 0.1941927312F, 0.1973232376F, 0.2004733764F, + 0.2036429541F, 0.2068317752F, 0.2100396421F, 0.2132663552F, + 0.2165117125F, 0.2197755102F, 0.2230575422F, 0.2263576007F, + 0.2296754753F, 0.2330109540F, 0.2363638225F, 0.2397338646F, + 0.2431208619F, 0.2465245941F, 0.2499448389F, 0.2533813719F, + 0.2568339669F, 0.2603023956F, 0.2637864277F, 0.2672858312F, + 0.2708003718F, 0.2743298135F, 0.2778739186F, 0.2814324472F, + 0.2850051576F, 0.2885918065F, 0.2921921485F, 0.2958059366F, + 0.2994329219F, 0.3030728538F, 0.3067254799F, 0.3103905462F, + 0.3140677969F, 0.3177569747F, 0.3214578205F, 0.3251700736F, + 0.3288934718F, 0.3326277513F, 0.3363726468F, 0.3401278914F, + 0.3438932168F, 0.3476683533F, 0.3514530297F, 0.3552469734F, + 0.3590499106F, 0.3628615659F, 0.3666816630F, 0.3705099239F, + 0.3743460698F, 0.3781898204F, 0.3820408945F, 0.3858990095F, + 0.3897638820F, 0.3936352274F, 0.3975127601F, 0.4013961936F, + 0.4052852405F, 0.4091796123F, 0.4130790198F, 0.4169831732F, + 0.4208917815F, 0.4248045534F, 0.4287211965F, 0.4326414181F, + 0.4365649248F, 0.4404914225F, 0.4444206167F, 0.4483522125F, + 0.4522859146F, 0.4562214270F, 0.4601584538F, 0.4640966984F, + 0.4680358644F, 0.4719756548F, 0.4759157726F, 0.4798559209F, + 0.4837958024F, 0.4877351199F, 0.4916735765F, 0.4956108751F, + 0.4995467188F, 0.5034808109F, 0.5074128550F, 0.5113425550F, + 0.5152696149F, 0.5191937395F, 0.5231146336F, 0.5270320028F, + 0.5309455530F, 0.5348549910F, 0.5387600239F, 0.5426603597F, + 0.5465557070F, 0.5504457754F, 0.5543302752F, 0.5582089175F, + 0.5620814145F, 0.5659474793F, 0.5698068262F, 0.5736591704F, + 0.5775042283F, 0.5813417176F, 0.5851713571F, 0.5889928670F, + 0.5928059689F, 0.5966103856F, 0.6004058415F, 0.6041920626F, + 0.6079687761F, 0.6117357113F, 0.6154925986F, 0.6192391705F, + 0.6229751612F, 0.6267003064F, 0.6304143441F, 0.6341170137F, + 0.6378080569F, 0.6414872173F, 0.6451542405F, 0.6488088741F, + 0.6524508681F, 0.6560799742F, 0.6596959469F, 0.6632985424F, + 0.6668875197F, 0.6704626398F, 0.6740236662F, 0.6775703649F, + 0.6811025043F, 0.6846198554F, 0.6881221916F, 0.6916092892F, + 0.6950809269F, 0.6985368861F, 0.7019769510F, 0.7054009085F, + 0.7088085484F, 0.7121996632F, 0.7155740484F, 0.7189315023F, + 0.7222718263F, 0.7255948245F, 0.7289003043F, 0.7321880760F, + 0.7354579530F, 0.7387097518F, 0.7419432921F, 0.7451583966F, + 0.7483548915F, 0.7515326059F, 0.7546913723F, 0.7578310265F, + 0.7609514077F, 0.7640523581F, 0.7671337237F, 0.7701953535F, + 0.7732371001F, 0.7762588195F, 0.7792603711F, 0.7822416178F, + 0.7852024259F, 0.7881426654F, 0.7910622097F, 0.7939609356F, + 0.7968387237F, 0.7996954579F, 0.8025310261F, 0.8053453193F, + 0.8081382324F, 0.8109096638F, 0.8136595156F, 0.8163876936F, + 0.8190941071F, 0.8217786690F, 0.8244412960F, 0.8270819086F, + 0.8297004305F, 0.8322967896F, 0.8348709171F, 0.8374227481F, + 0.8399522213F, 0.8424592789F, 0.8449438672F, 0.8474059356F, + 0.8498454378F, 0.8522623306F, 0.8546565748F, 0.8570281348F, + 0.8593769787F, 0.8617030779F, 0.8640064080F, 0.8662869477F, + 0.8685446796F, 0.8707795899F, 0.8729916682F, 0.8751809079F, + 0.8773473059F, 0.8794908626F, 0.8816115819F, 0.8837094713F, + 0.8857845418F, 0.8878368079F, 0.8898662874F, 0.8918730019F, + 0.8938569760F, 0.8958182380F, 0.8977568194F, 0.8996727552F, + 0.9015660837F, 0.9034368465F, 0.9052850885F, 0.9071108577F, + 0.9089142057F, 0.9106951869F, 0.9124538591F, 0.9141902832F, + 0.9159045233F, 0.9175966464F, 0.9192667228F, 0.9209148257F, + 0.9225410313F, 0.9241454187F, 0.9257280701F, 0.9272890704F, + 0.9288285075F, 0.9303464720F, 0.9318430576F, 0.9333183603F, + 0.9347724792F, 0.9362055158F, 0.9376175745F, 0.9390087622F, + 0.9403791881F, 0.9417289644F, 0.9430582055F, 0.9443670283F, + 0.9456555521F, 0.9469238986F, 0.9481721917F, 0.9494005577F, + 0.9506091252F, 0.9517980248F, 0.9529673894F, 0.9541173540F, + 0.9552480557F, 0.9563596334F, 0.9574522282F, 0.9585259830F, + 0.9595810428F, 0.9606175542F, 0.9616356656F, 0.9626355274F, + 0.9636172915F, 0.9645811114F, 0.9655271425F, 0.9664555414F, + 0.9673664664F, 0.9682600774F, 0.9691365355F, 0.9699960034F, + 0.9708386448F, 0.9716646250F, 0.9724741103F, 0.9732672685F, + 0.9740442683F, 0.9748052795F, 0.9755504729F, 0.9762800205F, + 0.9769940950F, 0.9776928703F, 0.9783765210F, 0.9790452223F, + 0.9796991504F, 0.9803384823F, 0.9809633954F, 0.9815740679F, + 0.9821706784F, 0.9827534063F, 0.9833224312F, 0.9838779332F, + 0.9844200928F, 0.9849490910F, 0.9854651087F, 0.9859683274F, + 0.9864589286F, 0.9869370940F, 0.9874030054F, 0.9878568447F, + 0.9882987937F, 0.9887290343F, 0.9891477481F, 0.9895551169F, + 0.9899513220F, 0.9903365446F, 0.9907109658F, 0.9910747662F, + 0.9914281260F, 0.9917712252F, 0.9921042433F, 0.9924273593F, + 0.9927407516F, 0.9930445982F, 0.9933390763F, 0.9936243626F, + 0.9939006331F, 0.9941680631F, 0.9944268269F, 0.9946770982F, + 0.9949190498F, 0.9951528537F, 0.9953786808F, 0.9955967011F, + 0.9958070836F, 0.9960099963F, 0.9962056061F, 0.9963940787F, + 0.9965755786F, 0.9967502693F, 0.9969183129F, 0.9970798704F, + 0.9972351013F, 0.9973841640F, 0.9975272151F, 0.9976644103F, + 0.9977959036F, 0.9979218476F, 0.9980423932F, 0.9981576901F, + 0.9982678862F, 0.9983731278F, 0.9984735596F, 0.9985693247F, + 0.9986605645F, 0.9987474186F, 0.9988300248F, 0.9989085193F, + 0.9989830364F, 0.9990537085F, 0.9991206662F, 0.9991840382F, + 0.9992439513F, 0.9993005303F, 0.9993538982F, 0.9994041757F, + 0.9994514817F, 0.9994959330F, 0.9995376444F, 0.9995767286F, + 0.9996132960F, 0.9996474550F, 0.9996793121F, 0.9997089710F, + 0.9997365339F, 0.9997621003F, 0.9997857677F, 0.9998076311F, + 0.9998277836F, 0.9998463156F, 0.9998633155F, 0.9998788692F, + 0.9998930603F, 0.9999059701F, 0.9999176774F, 0.9999282586F, + 0.9999377880F, 0.9999463370F, 0.9999539749F, 0.9999607685F, + 0.9999667820F, 0.9999720773F, 0.9999767136F, 0.9999807479F, + 0.9999842344F, 0.9999872249F, 0.9999897688F, 0.9999919127F, + 0.9999937009F, 0.9999951749F, 0.9999963738F, 0.9999973342F, + 0.9999980900F, 0.9999986724F, 0.9999991103F, 0.9999994297F, + 0.9999996543F, 0.9999998049F, 0.9999999000F, 0.9999999552F, + 0.9999999836F, 0.9999999957F, 0.9999999994F, 1.0000000000F, +}; + +static float vwin2048[1024] = { + 0.0000009241F, 0.0000083165F, 0.0000231014F, 0.0000452785F, + 0.0000748476F, 0.0001118085F, 0.0001561608F, 0.0002079041F, + 0.0002670379F, 0.0003335617F, 0.0004074748F, 0.0004887765F, + 0.0005774661F, 0.0006735427F, 0.0007770054F, 0.0008878533F, + 0.0010060853F, 0.0011317002F, 0.0012646969F, 0.0014050742F, + 0.0015528307F, 0.0017079650F, 0.0018704756F, 0.0020403610F, + 0.0022176196F, 0.0024022497F, 0.0025942495F, 0.0027936173F, + 0.0030003511F, 0.0032144490F, 0.0034359088F, 0.0036647286F, + 0.0039009061F, 0.0041444391F, 0.0043953253F, 0.0046535621F, + 0.0049191472F, 0.0051920781F, 0.0054723520F, 0.0057599664F, + 0.0060549184F, 0.0063572052F, 0.0066668239F, 0.0069837715F, + 0.0073080449F, 0.0076396410F, 0.0079785566F, 0.0083247884F, + 0.0086783330F, 0.0090391871F, 0.0094073470F, 0.0097828092F, + 0.0101655700F, 0.0105556258F, 0.0109529726F, 0.0113576065F, + 0.0117695237F, 0.0121887200F, 0.0126151913F, 0.0130489335F, + 0.0134899422F, 0.0139382130F, 0.0143937415F, 0.0148565233F, + 0.0153265536F, 0.0158038279F, 0.0162883413F, 0.0167800889F, + 0.0172790660F, 0.0177852675F, 0.0182986882F, 0.0188193231F, + 0.0193471668F, 0.0198822141F, 0.0204244594F, 0.0209738974F, + 0.0215305225F, 0.0220943289F, 0.0226653109F, 0.0232434627F, + 0.0238287784F, 0.0244212519F, 0.0250208772F, 0.0256276481F, + 0.0262415582F, 0.0268626014F, 0.0274907711F, 0.0281260608F, + 0.0287684638F, 0.0294179736F, 0.0300745833F, 0.0307382859F, + 0.0314090747F, 0.0320869424F, 0.0327718819F, 0.0334638860F, + 0.0341629474F, 0.0348690586F, 0.0355822122F, 0.0363024004F, + 0.0370296157F, 0.0377638502F, 0.0385050960F, 0.0392533451F, + 0.0400085896F, 0.0407708211F, 0.0415400315F, 0.0423162123F, + 0.0430993552F, 0.0438894515F, 0.0446864926F, 0.0454904698F, + 0.0463013742F, 0.0471191969F, 0.0479439288F, 0.0487755607F, + 0.0496140836F, 0.0504594879F, 0.0513117642F, 0.0521709031F, + 0.0530368949F, 0.0539097297F, 0.0547893979F, 0.0556758894F, + 0.0565691941F, 0.0574693019F, 0.0583762026F, 0.0592898858F, + 0.0602103410F, 0.0611375576F, 0.0620715250F, 0.0630122324F, + 0.0639596688F, 0.0649138234F, 0.0658746848F, 0.0668422421F, + 0.0678164838F, 0.0687973985F, 0.0697849746F, 0.0707792005F, + 0.0717800645F, 0.0727875547F, 0.0738016591F, 0.0748223656F, + 0.0758496620F, 0.0768835359F, 0.0779239751F, 0.0789709668F, + 0.0800244985F, 0.0810845574F, 0.0821511306F, 0.0832242052F, + 0.0843037679F, 0.0853898056F, 0.0864823050F, 0.0875812525F, + 0.0886866347F, 0.0897984378F, 0.0909166480F, 0.0920412513F, + 0.0931722338F, 0.0943095813F, 0.0954532795F, 0.0966033140F, + 0.0977596702F, 0.0989223336F, 0.1000912894F, 0.1012665227F, + 0.1024480185F, 0.1036357616F, 0.1048297369F, 0.1060299290F, + 0.1072363224F, 0.1084489014F, 0.1096676504F, 0.1108925534F, + 0.1121235946F, 0.1133607577F, 0.1146040267F, 0.1158533850F, + 0.1171088163F, 0.1183703040F, 0.1196378312F, 0.1209113812F, + 0.1221909370F, 0.1234764815F, 0.1247679974F, 0.1260654674F, + 0.1273688740F, 0.1286781995F, 0.1299934263F, 0.1313145365F, + 0.1326415121F, 0.1339743349F, 0.1353129866F, 0.1366574490F, + 0.1380077035F, 0.1393637315F, 0.1407255141F, 0.1420930325F, + 0.1434662677F, 0.1448452004F, 0.1462298115F, 0.1476200814F, + 0.1490159906F, 0.1504175195F, 0.1518246482F, 0.1532373569F, + 0.1546556253F, 0.1560794333F, 0.1575087606F, 0.1589435866F, + 0.1603838909F, 0.1618296526F, 0.1632808509F, 0.1647374648F, + 0.1661994731F, 0.1676668546F, 0.1691395880F, 0.1706176516F, + 0.1721010238F, 0.1735896829F, 0.1750836068F, 0.1765827736F, + 0.1780871610F, 0.1795967468F, 0.1811115084F, 0.1826314234F, + 0.1841564689F, 0.1856866221F, 0.1872218600F, 0.1887621595F, + 0.1903074974F, 0.1918578503F, 0.1934131947F, 0.1949735068F, + 0.1965387630F, 0.1981089393F, 0.1996840117F, 0.2012639560F, + 0.2028487479F, 0.2044383630F, 0.2060327766F, 0.2076319642F, + 0.2092359007F, 0.2108445614F, 0.2124579211F, 0.2140759545F, + 0.2156986364F, 0.2173259411F, 0.2189578432F, 0.2205943168F, + 0.2222353361F, 0.2238808751F, 0.2255309076F, 0.2271854073F, + 0.2288443480F, 0.2305077030F, 0.2321754457F, 0.2338475493F, + 0.2355239869F, 0.2372047315F, 0.2388897560F, 0.2405790329F, + 0.2422725350F, 0.2439702347F, 0.2456721043F, 0.2473781159F, + 0.2490882418F, 0.2508024539F, 0.2525207240F, 0.2542430237F, + 0.2559693248F, 0.2576995986F, 0.2594338166F, 0.2611719498F, + 0.2629139695F, 0.2646598466F, 0.2664095520F, 0.2681630564F, + 0.2699203304F, 0.2716813445F, 0.2734460691F, 0.2752144744F, + 0.2769865307F, 0.2787622079F, 0.2805414760F, 0.2823243047F, + 0.2841106637F, 0.2859005227F, 0.2876938509F, 0.2894906179F, + 0.2912907928F, 0.2930943447F, 0.2949012426F, 0.2967114554F, + 0.2985249520F, 0.3003417009F, 0.3021616708F, 0.3039848301F, + 0.3058111471F, 0.3076405901F, 0.3094731273F, 0.3113087266F, + 0.3131473560F, 0.3149889833F, 0.3168335762F, 0.3186811024F, + 0.3205315294F, 0.3223848245F, 0.3242409552F, 0.3260998886F, + 0.3279615918F, 0.3298260319F, 0.3316931758F, 0.3335629903F, + 0.3354354423F, 0.3373104982F, 0.3391881247F, 0.3410682882F, + 0.3429509551F, 0.3448360917F, 0.3467236642F, 0.3486136387F, + 0.3505059811F, 0.3524006575F, 0.3542976336F, 0.3561968753F, + 0.3580983482F, 0.3600020179F, 0.3619078499F, 0.3638158096F, + 0.3657258625F, 0.3676379737F, 0.3695521086F, 0.3714682321F, + 0.3733863094F, 0.3753063055F, 0.3772281852F, 0.3791519134F, + 0.3810774548F, 0.3830047742F, 0.3849338362F, 0.3868646053F, + 0.3887970459F, 0.3907311227F, 0.3926667998F, 0.3946040417F, + 0.3965428125F, 0.3984830765F, 0.4004247978F, 0.4023679403F, + 0.4043124683F, 0.4062583455F, 0.4082055359F, 0.4101540034F, + 0.4121037117F, 0.4140546246F, 0.4160067058F, 0.4179599190F, + 0.4199142277F, 0.4218695956F, 0.4238259861F, 0.4257833627F, + 0.4277416888F, 0.4297009279F, 0.4316610433F, 0.4336219983F, + 0.4355837562F, 0.4375462803F, 0.4395095337F, 0.4414734797F, + 0.4434380815F, 0.4454033021F, 0.4473691046F, 0.4493354521F, + 0.4513023078F, 0.4532696345F, 0.4552373954F, 0.4572055533F, + 0.4591740713F, 0.4611429123F, 0.4631120393F, 0.4650814151F, + 0.4670510028F, 0.4690207650F, 0.4709906649F, 0.4729606651F, + 0.4749307287F, 0.4769008185F, 0.4788708972F, 0.4808409279F, + 0.4828108732F, 0.4847806962F, 0.4867503597F, 0.4887198264F, + 0.4906890593F, 0.4926580213F, 0.4946266753F, 0.4965949840F, + 0.4985629105F, 0.5005304176F, 0.5024974683F, 0.5044640255F, + 0.5064300522F, 0.5083955114F, 0.5103603659F, 0.5123245790F, + 0.5142881136F, 0.5162509328F, 0.5182129997F, 0.5201742774F, + 0.5221347290F, 0.5240943178F, 0.5260530070F, 0.5280107598F, + 0.5299675395F, 0.5319233095F, 0.5338780330F, 0.5358316736F, + 0.5377841946F, 0.5397355596F, 0.5416857320F, 0.5436346755F, + 0.5455823538F, 0.5475287304F, 0.5494737691F, 0.5514174337F, + 0.5533596881F, 0.5553004962F, 0.5572398218F, 0.5591776291F, + 0.5611138821F, 0.5630485449F, 0.5649815818F, 0.5669129570F, + 0.5688426349F, 0.5707705799F, 0.5726967564F, 0.5746211290F, + 0.5765436624F, 0.5784643212F, 0.5803830702F, 0.5822998743F, + 0.5842146984F, 0.5861275076F, 0.5880382669F, 0.5899469416F, + 0.5918534968F, 0.5937578981F, 0.5956601107F, 0.5975601004F, + 0.5994578326F, 0.6013532732F, 0.6032463880F, 0.6051371429F, + 0.6070255039F, 0.6089114372F, 0.6107949090F, 0.6126758856F, + 0.6145543334F, 0.6164302191F, 0.6183035092F, 0.6201741706F, + 0.6220421700F, 0.6239074745F, 0.6257700513F, 0.6276298674F, + 0.6294868903F, 0.6313410873F, 0.6331924262F, 0.6350408745F, + 0.6368864001F, 0.6387289710F, 0.6405685552F, 0.6424051209F, + 0.6442386364F, 0.6460690702F, 0.6478963910F, 0.6497205673F, + 0.6515415682F, 0.6533593625F, 0.6551739194F, 0.6569852082F, + 0.6587931984F, 0.6605978593F, 0.6623991609F, 0.6641970728F, + 0.6659915652F, 0.6677826081F, 0.6695701718F, 0.6713542268F, + 0.6731347437F, 0.6749116932F, 0.6766850461F, 0.6784547736F, + 0.6802208469F, 0.6819832374F, 0.6837419164F, 0.6854968559F, + 0.6872480275F, 0.6889954034F, 0.6907389556F, 0.6924786566F, + 0.6942144788F, 0.6959463950F, 0.6976743780F, 0.6993984008F, + 0.7011184365F, 0.7028344587F, 0.7045464407F, 0.7062543564F, + 0.7079581796F, 0.7096578844F, 0.7113534450F, 0.7130448359F, + 0.7147320316F, 0.7164150070F, 0.7180937371F, 0.7197681970F, + 0.7214383620F, 0.7231042077F, 0.7247657098F, 0.7264228443F, + 0.7280755871F, 0.7297239147F, 0.7313678035F, 0.7330072301F, + 0.7346421715F, 0.7362726046F, 0.7378985069F, 0.7395198556F, + 0.7411366285F, 0.7427488034F, 0.7443563584F, 0.7459592717F, + 0.7475575218F, 0.7491510873F, 0.7507399471F, 0.7523240803F, + 0.7539034661F, 0.7554780839F, 0.7570479136F, 0.7586129349F, + 0.7601731279F, 0.7617284730F, 0.7632789506F, 0.7648245416F, + 0.7663652267F, 0.7679009872F, 0.7694318044F, 0.7709576599F, + 0.7724785354F, 0.7739944130F, 0.7755052749F, 0.7770111035F, + 0.7785118815F, 0.7800075916F, 0.7814982170F, 0.7829837410F, + 0.7844641472F, 0.7859394191F, 0.7874095408F, 0.7888744965F, + 0.7903342706F, 0.7917888476F, 0.7932382124F, 0.7946823501F, + 0.7961212460F, 0.7975548855F, 0.7989832544F, 0.8004063386F, + 0.8018241244F, 0.8032365981F, 0.8046437463F, 0.8060455560F, + 0.8074420141F, 0.8088331080F, 0.8102188253F, 0.8115991536F, + 0.8129740810F, 0.8143435957F, 0.8157076861F, 0.8170663409F, + 0.8184195489F, 0.8197672994F, 0.8211095817F, 0.8224463853F, + 0.8237777001F, 0.8251035161F, 0.8264238235F, 0.8277386129F, + 0.8290478750F, 0.8303516008F, 0.8316497814F, 0.8329424083F, + 0.8342294731F, 0.8355109677F, 0.8367868841F, 0.8380572148F, + 0.8393219523F, 0.8405810893F, 0.8418346190F, 0.8430825345F, + 0.8443248294F, 0.8455614974F, 0.8467925323F, 0.8480179285F, + 0.8492376802F, 0.8504517822F, 0.8516602292F, 0.8528630164F, + 0.8540601391F, 0.8552515928F, 0.8564373733F, 0.8576174766F, + 0.8587918990F, 0.8599606368F, 0.8611236868F, 0.8622810460F, + 0.8634327113F, 0.8645786802F, 0.8657189504F, 0.8668535195F, + 0.8679823857F, 0.8691055472F, 0.8702230025F, 0.8713347503F, + 0.8724407896F, 0.8735411194F, 0.8746357394F, 0.8757246489F, + 0.8768078479F, 0.8778853364F, 0.8789571146F, 0.8800231832F, + 0.8810835427F, 0.8821381942F, 0.8831871387F, 0.8842303777F, + 0.8852679127F, 0.8862997456F, 0.8873258784F, 0.8883463132F, + 0.8893610527F, 0.8903700994F, 0.8913734562F, 0.8923711263F, + 0.8933631129F, 0.8943494196F, 0.8953300500F, 0.8963050083F, + 0.8972742985F, 0.8982379249F, 0.8991958922F, 0.9001482052F, + 0.9010948688F, 0.9020358883F, 0.9029712690F, 0.9039010165F, + 0.9048251367F, 0.9057436357F, 0.9066565195F, 0.9075637946F, + 0.9084654678F, 0.9093615456F, 0.9102520353F, 0.9111369440F, + 0.9120162792F, 0.9128900484F, 0.9137582595F, 0.9146209204F, + 0.9154780394F, 0.9163296248F, 0.9171756853F, 0.9180162296F, + 0.9188512667F, 0.9196808057F, 0.9205048559F, 0.9213234270F, + 0.9221365285F, 0.9229441704F, 0.9237463629F, 0.9245431160F, + 0.9253344404F, 0.9261203465F, 0.9269008453F, 0.9276759477F, + 0.9284456648F, 0.9292100080F, 0.9299689889F, 0.9307226190F, + 0.9314709103F, 0.9322138747F, 0.9329515245F, 0.9336838721F, + 0.9344109300F, 0.9351327108F, 0.9358492275F, 0.9365604931F, + 0.9372665208F, 0.9379673239F, 0.9386629160F, 0.9393533107F, + 0.9400385220F, 0.9407185637F, 0.9413934501F, 0.9420631954F, + 0.9427278141F, 0.9433873208F, 0.9440417304F, 0.9446910576F, + 0.9453353176F, 0.9459745255F, 0.9466086968F, 0.9472378469F, + 0.9478619915F, 0.9484811463F, 0.9490953274F, 0.9497045506F, + 0.9503088323F, 0.9509081888F, 0.9515026365F, 0.9520921921F, + 0.9526768723F, 0.9532566940F, 0.9538316742F, 0.9544018300F, + 0.9549671786F, 0.9555277375F, 0.9560835241F, 0.9566345562F, + 0.9571808513F, 0.9577224275F, 0.9582593027F, 0.9587914949F, + 0.9593190225F, 0.9598419038F, 0.9603601571F, 0.9608738012F, + 0.9613828546F, 0.9618873361F, 0.9623872646F, 0.9628826591F, + 0.9633735388F, 0.9638599227F, 0.9643418303F, 0.9648192808F, + 0.9652922939F, 0.9657608890F, 0.9662250860F, 0.9666849046F, + 0.9671403646F, 0.9675914861F, 0.9680382891F, 0.9684807937F, + 0.9689190202F, 0.9693529890F, 0.9697827203F, 0.9702082347F, + 0.9706295529F, 0.9710466953F, 0.9714596828F, 0.9718685362F, + 0.9722732762F, 0.9726739240F, 0.9730705005F, 0.9734630267F, + 0.9738515239F, 0.9742360134F, 0.9746165163F, 0.9749930540F, + 0.9753656481F, 0.9757343198F, 0.9760990909F, 0.9764599829F, + 0.9768170175F, 0.9771702164F, 0.9775196013F, 0.9778651941F, + 0.9782070167F, 0.9785450909F, 0.9788794388F, 0.9792100824F, + 0.9795370437F, 0.9798603449F, 0.9801800080F, 0.9804960554F, + 0.9808085092F, 0.9811173916F, 0.9814227251F, 0.9817245318F, + 0.9820228343F, 0.9823176549F, 0.9826090160F, 0.9828969402F, + 0.9831814498F, 0.9834625674F, 0.9837403156F, 0.9840147169F, + 0.9842857939F, 0.9845535692F, 0.9848180654F, 0.9850793052F, + 0.9853373113F, 0.9855921062F, 0.9858437127F, 0.9860921535F, + 0.9863374512F, 0.9865796287F, 0.9868187085F, 0.9870547136F, + 0.9872876664F, 0.9875175899F, 0.9877445067F, 0.9879684396F, + 0.9881894112F, 0.9884074444F, 0.9886225619F, 0.9888347863F, + 0.9890441404F, 0.9892506468F, 0.9894543284F, 0.9896552077F, + 0.9898533074F, 0.9900486502F, 0.9902412587F, 0.9904311555F, + 0.9906183633F, 0.9908029045F, 0.9909848019F, 0.9911640779F, + 0.9913407550F, 0.9915148557F, 0.9916864025F, 0.9918554179F, + 0.9920219241F, 0.9921859437F, 0.9923474989F, 0.9925066120F, + 0.9926633054F, 0.9928176012F, 0.9929695218F, 0.9931190891F, + 0.9932663254F, 0.9934112527F, 0.9935538932F, 0.9936942686F, + 0.9938324012F, 0.9939683126F, 0.9941020248F, 0.9942335597F, + 0.9943629388F, 0.9944901841F, 0.9946153170F, 0.9947383593F, + 0.9948593325F, 0.9949782579F, 0.9950951572F, 0.9952100516F, + 0.9953229625F, 0.9954339111F, 0.9955429186F, 0.9956500062F, + 0.9957551948F, 0.9958585056F, 0.9959599593F, 0.9960595769F, + 0.9961573792F, 0.9962533869F, 0.9963476206F, 0.9964401009F, + 0.9965308483F, 0.9966198833F, 0.9967072261F, 0.9967928971F, + 0.9968769164F, 0.9969593041F, 0.9970400804F, 0.9971192651F, + 0.9971968781F, 0.9972729391F, 0.9973474680F, 0.9974204842F, + 0.9974920074F, 0.9975620569F, 0.9976306521F, 0.9976978122F, + 0.9977635565F, 0.9978279039F, 0.9978908736F, 0.9979524842F, + 0.9980127547F, 0.9980717037F, 0.9981293499F, 0.9981857116F, + 0.9982408073F, 0.9982946554F, 0.9983472739F, 0.9983986810F, + 0.9984488947F, 0.9984979328F, 0.9985458132F, 0.9985925534F, + 0.9986381711F, 0.9986826838F, 0.9987261086F, 0.9987684630F, + 0.9988097640F, 0.9988500286F, 0.9988892738F, 0.9989275163F, + 0.9989647727F, 0.9990010597F, 0.9990363938F, 0.9990707911F, + 0.9991042679F, 0.9991368404F, 0.9991685244F, 0.9991993358F, + 0.9992292905F, 0.9992584038F, 0.9992866914F, 0.9993141686F, + 0.9993408506F, 0.9993667526F, 0.9993918895F, 0.9994162761F, + 0.9994399273F, 0.9994628576F, 0.9994850815F, 0.9995066133F, + 0.9995274672F, 0.9995476574F, 0.9995671978F, 0.9995861021F, + 0.9996043841F, 0.9996220573F, 0.9996391352F, 0.9996556310F, + 0.9996715579F, 0.9996869288F, 0.9997017568F, 0.9997160543F, + 0.9997298342F, 0.9997431088F, 0.9997558905F, 0.9997681914F, + 0.9997800236F, 0.9997913990F, 0.9998023292F, 0.9998128261F, + 0.9998229009F, 0.9998325650F, 0.9998418296F, 0.9998507058F, + 0.9998592044F, 0.9998673362F, 0.9998751117F, 0.9998825415F, + 0.9998896358F, 0.9998964047F, 0.9999028584F, 0.9999090066F, + 0.9999148590F, 0.9999204253F, 0.9999257148F, 0.9999307368F, + 0.9999355003F, 0.9999400144F, 0.9999442878F, 0.9999483293F, + 0.9999521472F, 0.9999557499F, 0.9999591457F, 0.9999623426F, + 0.9999653483F, 0.9999681708F, 0.9999708175F, 0.9999732959F, + 0.9999756132F, 0.9999777765F, 0.9999797928F, 0.9999816688F, + 0.9999834113F, 0.9999850266F, 0.9999865211F, 0.9999879009F, + 0.9999891721F, 0.9999903405F, 0.9999914118F, 0.9999923914F, + 0.9999932849F, 0.9999940972F, 0.9999948336F, 0.9999954989F, + 0.9999960978F, 0.9999966349F, 0.9999971146F, 0.9999975411F, + 0.9999979185F, 0.9999982507F, 0.9999985414F, 0.9999987944F, + 0.9999990129F, 0.9999992003F, 0.9999993596F, 0.9999994939F, + 0.9999996059F, 0.9999996981F, 0.9999997732F, 0.9999998333F, + 0.9999998805F, 0.9999999170F, 0.9999999444F, 0.9999999643F, + 0.9999999784F, 0.9999999878F, 0.9999999937F, 0.9999999972F, + 0.9999999990F, 0.9999999997F, 1.0000000000F, 1.0000000000F, +}; + +static float vwin4096[2048] = { + 0.0000002310F, 0.0000020791F, 0.0000057754F, 0.0000113197F, + 0.0000187121F, 0.0000279526F, 0.0000390412F, 0.0000519777F, + 0.0000667623F, 0.0000833949F, 0.0001018753F, 0.0001222036F, + 0.0001443798F, 0.0001684037F, 0.0001942754F, 0.0002219947F, + 0.0002515616F, 0.0002829761F, 0.0003162380F, 0.0003513472F, + 0.0003883038F, 0.0004271076F, 0.0004677584F, 0.0005102563F, + 0.0005546011F, 0.0006007928F, 0.0006488311F, 0.0006987160F, + 0.0007504474F, 0.0008040251F, 0.0008594490F, 0.0009167191F, + 0.0009758351F, 0.0010367969F, 0.0010996044F, 0.0011642574F, + 0.0012307558F, 0.0012990994F, 0.0013692880F, 0.0014413216F, + 0.0015151998F, 0.0015909226F, 0.0016684898F, 0.0017479011F, + 0.0018291565F, 0.0019122556F, 0.0019971983F, 0.0020839845F, + 0.0021726138F, 0.0022630861F, 0.0023554012F, 0.0024495588F, + 0.0025455588F, 0.0026434008F, 0.0027430847F, 0.0028446103F, + 0.0029479772F, 0.0030531853F, 0.0031602342F, 0.0032691238F, + 0.0033798538F, 0.0034924239F, 0.0036068338F, 0.0037230833F, + 0.0038411721F, 0.0039610999F, 0.0040828664F, 0.0042064714F, + 0.0043319145F, 0.0044591954F, 0.0045883139F, 0.0047192696F, + 0.0048520622F, 0.0049866914F, 0.0051231569F, 0.0052614583F, + 0.0054015953F, 0.0055435676F, 0.0056873748F, 0.0058330166F, + 0.0059804926F, 0.0061298026F, 0.0062809460F, 0.0064339226F, + 0.0065887320F, 0.0067453738F, 0.0069038476F, 0.0070641531F, + 0.0072262899F, 0.0073902575F, 0.0075560556F, 0.0077236838F, + 0.0078931417F, 0.0080644288F, 0.0082375447F, 0.0084124891F, + 0.0085892615F, 0.0087678614F, 0.0089482885F, 0.0091305422F, + 0.0093146223F, 0.0095005281F, 0.0096882592F, 0.0098778153F, + 0.0100691958F, 0.0102624002F, 0.0104574281F, 0.0106542791F, + 0.0108529525F, 0.0110534480F, 0.0112557651F, 0.0114599032F, + 0.0116658618F, 0.0118736405F, 0.0120832387F, 0.0122946560F, + 0.0125078917F, 0.0127229454F, 0.0129398166F, 0.0131585046F, + 0.0133790090F, 0.0136013292F, 0.0138254647F, 0.0140514149F, + 0.0142791792F, 0.0145087572F, 0.0147401481F, 0.0149733515F, + 0.0152083667F, 0.0154451932F, 0.0156838304F, 0.0159242777F, + 0.0161665345F, 0.0164106001F, 0.0166564741F, 0.0169041557F, + 0.0171536443F, 0.0174049393F, 0.0176580401F, 0.0179129461F, + 0.0181696565F, 0.0184281708F, 0.0186884883F, 0.0189506084F, + 0.0192145303F, 0.0194802535F, 0.0197477772F, 0.0200171008F, + 0.0202882236F, 0.0205611449F, 0.0208358639F, 0.0211123801F, + 0.0213906927F, 0.0216708011F, 0.0219527043F, 0.0222364019F, + 0.0225218930F, 0.0228091769F, 0.0230982529F, 0.0233891203F, + 0.0236817782F, 0.0239762259F, 0.0242724628F, 0.0245704880F, + 0.0248703007F, 0.0251719002F, 0.0254752858F, 0.0257804565F, + 0.0260874117F, 0.0263961506F, 0.0267066722F, 0.0270189760F, + 0.0273330609F, 0.0276489263F, 0.0279665712F, 0.0282859949F, + 0.0286071966F, 0.0289301753F, 0.0292549303F, 0.0295814607F, + 0.0299097656F, 0.0302398442F, 0.0305716957F, 0.0309053191F, + 0.0312407135F, 0.0315778782F, 0.0319168122F, 0.0322575145F, + 0.0325999844F, 0.0329442209F, 0.0332902231F, 0.0336379900F, + 0.0339875208F, 0.0343388146F, 0.0346918703F, 0.0350466871F, + 0.0354032640F, 0.0357616000F, 0.0361216943F, 0.0364835458F, + 0.0368471535F, 0.0372125166F, 0.0375796339F, 0.0379485046F, + 0.0383191276F, 0.0386915020F, 0.0390656267F, 0.0394415008F, + 0.0398191231F, 0.0401984927F, 0.0405796086F, 0.0409624698F, + 0.0413470751F, 0.0417334235F, 0.0421215141F, 0.0425113457F, + 0.0429029172F, 0.0432962277F, 0.0436912760F, 0.0440880610F, + 0.0444865817F, 0.0448868370F, 0.0452888257F, 0.0456925468F, + 0.0460979992F, 0.0465051816F, 0.0469140931F, 0.0473247325F, + 0.0477370986F, 0.0481511902F, 0.0485670064F, 0.0489845458F, + 0.0494038074F, 0.0498247899F, 0.0502474922F, 0.0506719131F, + 0.0510980514F, 0.0515259060F, 0.0519554756F, 0.0523867590F, + 0.0528197550F, 0.0532544624F, 0.0536908800F, 0.0541290066F, + 0.0545688408F, 0.0550103815F, 0.0554536274F, 0.0558985772F, + 0.0563452297F, 0.0567935837F, 0.0572436377F, 0.0576953907F, + 0.0581488412F, 0.0586039880F, 0.0590608297F, 0.0595193651F, + 0.0599795929F, 0.0604415117F, 0.0609051202F, 0.0613704170F, + 0.0618374009F, 0.0623060704F, 0.0627764243F, 0.0632484611F, + 0.0637221795F, 0.0641975781F, 0.0646746555F, 0.0651534104F, + 0.0656338413F, 0.0661159469F, 0.0665997257F, 0.0670851763F, + 0.0675722973F, 0.0680610873F, 0.0685515448F, 0.0690436684F, + 0.0695374567F, 0.0700329081F, 0.0705300213F, 0.0710287947F, + 0.0715292269F, 0.0720313163F, 0.0725350616F, 0.0730404612F, + 0.0735475136F, 0.0740562172F, 0.0745665707F, 0.0750785723F, + 0.0755922207F, 0.0761075143F, 0.0766244515F, 0.0771430307F, + 0.0776632505F, 0.0781851092F, 0.0787086052F, 0.0792337371F, + 0.0797605032F, 0.0802889018F, 0.0808189315F, 0.0813505905F, + 0.0818838773F, 0.0824187903F, 0.0829553277F, 0.0834934881F, + 0.0840332697F, 0.0845746708F, 0.0851176899F, 0.0856623252F, + 0.0862085751F, 0.0867564379F, 0.0873059119F, 0.0878569954F, + 0.0884096867F, 0.0889639840F, 0.0895198858F, 0.0900773902F, + 0.0906364955F, 0.0911972000F, 0.0917595019F, 0.0923233995F, + 0.0928888909F, 0.0934559745F, 0.0940246485F, 0.0945949110F, + 0.0951667604F, 0.0957401946F, 0.0963152121F, 0.0968918109F, + 0.0974699893F, 0.0980497454F, 0.0986310773F, 0.0992139832F, + 0.0997984614F, 0.1003845098F, 0.1009721267F, 0.1015613101F, + 0.1021520582F, 0.1027443692F, 0.1033382410F, 0.1039336718F, + 0.1045306597F, 0.1051292027F, 0.1057292990F, 0.1063309466F, + 0.1069341435F, 0.1075388878F, 0.1081451776F, 0.1087530108F, + 0.1093623856F, 0.1099732998F, 0.1105857516F, 0.1111997389F, + 0.1118152597F, 0.1124323121F, 0.1130508939F, 0.1136710032F, + 0.1142926379F, 0.1149157960F, 0.1155404755F, 0.1161666742F, + 0.1167943901F, 0.1174236211F, 0.1180543652F, 0.1186866202F, + 0.1193203841F, 0.1199556548F, 0.1205924300F, 0.1212307078F, + 0.1218704860F, 0.1225117624F, 0.1231545349F, 0.1237988013F, + 0.1244445596F, 0.1250918074F, 0.1257405427F, 0.1263907632F, + 0.1270424667F, 0.1276956512F, 0.1283503142F, 0.1290064537F, + 0.1296640674F, 0.1303231530F, 0.1309837084F, 0.1316457312F, + 0.1323092193F, 0.1329741703F, 0.1336405820F, 0.1343084520F, + 0.1349777782F, 0.1356485582F, 0.1363207897F, 0.1369944704F, + 0.1376695979F, 0.1383461700F, 0.1390241842F, 0.1397036384F, + 0.1403845300F, 0.1410668567F, 0.1417506162F, 0.1424358061F, + 0.1431224240F, 0.1438104674F, 0.1444999341F, 0.1451908216F, + 0.1458831274F, 0.1465768492F, 0.1472719844F, 0.1479685308F, + 0.1486664857F, 0.1493658468F, 0.1500666115F, 0.1507687775F, + 0.1514723422F, 0.1521773031F, 0.1528836577F, 0.1535914035F, + 0.1543005380F, 0.1550110587F, 0.1557229631F, 0.1564362485F, + 0.1571509124F, 0.1578669524F, 0.1585843657F, 0.1593031499F, + 0.1600233024F, 0.1607448205F, 0.1614677017F, 0.1621919433F, + 0.1629175428F, 0.1636444975F, 0.1643728047F, 0.1651024619F, + 0.1658334665F, 0.1665658156F, 0.1672995067F, 0.1680345371F, + 0.1687709041F, 0.1695086050F, 0.1702476372F, 0.1709879978F, + 0.1717296843F, 0.1724726938F, 0.1732170237F, 0.1739626711F, + 0.1747096335F, 0.1754579079F, 0.1762074916F, 0.1769583819F, + 0.1777105760F, 0.1784640710F, 0.1792188642F, 0.1799749529F, + 0.1807323340F, 0.1814910049F, 0.1822509628F, 0.1830122046F, + 0.1837747277F, 0.1845385292F, 0.1853036062F, 0.1860699558F, + 0.1868375751F, 0.1876064613F, 0.1883766114F, 0.1891480226F, + 0.1899206919F, 0.1906946164F, 0.1914697932F, 0.1922462194F, + 0.1930238919F, 0.1938028079F, 0.1945829643F, 0.1953643583F, + 0.1961469868F, 0.1969308468F, 0.1977159353F, 0.1985022494F, + 0.1992897859F, 0.2000785420F, 0.2008685145F, 0.2016597005F, + 0.2024520968F, 0.2032457005F, 0.2040405084F, 0.2048365175F, + 0.2056337247F, 0.2064321269F, 0.2072317211F, 0.2080325041F, + 0.2088344727F, 0.2096376240F, 0.2104419547F, 0.2112474618F, + 0.2120541420F, 0.2128619923F, 0.2136710094F, 0.2144811902F, + 0.2152925315F, 0.2161050301F, 0.2169186829F, 0.2177334866F, + 0.2185494381F, 0.2193665340F, 0.2201847712F, 0.2210041465F, + 0.2218246565F, 0.2226462981F, 0.2234690680F, 0.2242929629F, + 0.2251179796F, 0.2259441147F, 0.2267713650F, 0.2275997272F, + 0.2284291979F, 0.2292597739F, 0.2300914518F, 0.2309242283F, + 0.2317581001F, 0.2325930638F, 0.2334291160F, 0.2342662534F, + 0.2351044727F, 0.2359437703F, 0.2367841431F, 0.2376255875F, + 0.2384681001F, 0.2393116776F, 0.2401563165F, 0.2410020134F, + 0.2418487649F, 0.2426965675F, 0.2435454178F, 0.2443953122F, + 0.2452462474F, 0.2460982199F, 0.2469512262F, 0.2478052628F, + 0.2486603262F, 0.2495164129F, 0.2503735194F, 0.2512316421F, + 0.2520907776F, 0.2529509222F, 0.2538120726F, 0.2546742250F, + 0.2555373760F, 0.2564015219F, 0.2572666593F, 0.2581327845F, + 0.2589998939F, 0.2598679840F, 0.2607370510F, 0.2616070916F, + 0.2624781019F, 0.2633500783F, 0.2642230173F, 0.2650969152F, + 0.2659717684F, 0.2668475731F, 0.2677243257F, 0.2686020226F, + 0.2694806601F, 0.2703602344F, 0.2712407419F, 0.2721221789F, + 0.2730045417F, 0.2738878265F, 0.2747720297F, 0.2756571474F, + 0.2765431760F, 0.2774301117F, 0.2783179508F, 0.2792066895F, + 0.2800963240F, 0.2809868505F, 0.2818782654F, 0.2827705647F, + 0.2836637447F, 0.2845578016F, 0.2854527315F, 0.2863485307F, + 0.2872451953F, 0.2881427215F, 0.2890411055F, 0.2899403433F, + 0.2908404312F, 0.2917413654F, 0.2926431418F, 0.2935457567F, + 0.2944492061F, 0.2953534863F, 0.2962585932F, 0.2971645230F, + 0.2980712717F, 0.2989788356F, 0.2998872105F, 0.3007963927F, + 0.3017063781F, 0.3026171629F, 0.3035287430F, 0.3044411145F, + 0.3053542736F, 0.3062682161F, 0.3071829381F, 0.3080984356F, + 0.3090147047F, 0.3099317413F, 0.3108495414F, 0.3117681011F, + 0.3126874163F, 0.3136074830F, 0.3145282972F, 0.3154498548F, + 0.3163721517F, 0.3172951841F, 0.3182189477F, 0.3191434385F, + 0.3200686525F, 0.3209945856F, 0.3219212336F, 0.3228485927F, + 0.3237766585F, 0.3247054271F, 0.3256348943F, 0.3265650560F, + 0.3274959081F, 0.3284274465F, 0.3293596671F, 0.3302925657F, + 0.3312261382F, 0.3321603804F, 0.3330952882F, 0.3340308574F, + 0.3349670838F, 0.3359039634F, 0.3368414919F, 0.3377796651F, + 0.3387184789F, 0.3396579290F, 0.3405980113F, 0.3415387216F, + 0.3424800556F, 0.3434220091F, 0.3443645779F, 0.3453077578F, + 0.3462515446F, 0.3471959340F, 0.3481409217F, 0.3490865036F, + 0.3500326754F, 0.3509794328F, 0.3519267715F, 0.3528746873F, + 0.3538231759F, 0.3547722330F, 0.3557218544F, 0.3566720357F, + 0.3576227727F, 0.3585740610F, 0.3595258964F, 0.3604782745F, + 0.3614311910F, 0.3623846417F, 0.3633386221F, 0.3642931280F, + 0.3652481549F, 0.3662036987F, 0.3671597548F, 0.3681163191F, + 0.3690733870F, 0.3700309544F, 0.3709890167F, 0.3719475696F, + 0.3729066089F, 0.3738661299F, 0.3748261285F, 0.3757866002F, + 0.3767475406F, 0.3777089453F, 0.3786708100F, 0.3796331302F, + 0.3805959014F, 0.3815591194F, 0.3825227796F, 0.3834868777F, + 0.3844514093F, 0.3854163698F, 0.3863817549F, 0.3873475601F, + 0.3883137810F, 0.3892804131F, 0.3902474521F, 0.3912148933F, + 0.3921827325F, 0.3931509650F, 0.3941195865F, 0.3950885925F, + 0.3960579785F, 0.3970277400F, 0.3979978725F, 0.3989683716F, + 0.3999392328F, 0.4009104516F, 0.4018820234F, 0.4028539438F, + 0.4038262084F, 0.4047988125F, 0.4057717516F, 0.4067450214F, + 0.4077186172F, 0.4086925345F, 0.4096667688F, 0.4106413155F, + 0.4116161703F, 0.4125913284F, 0.4135667854F, 0.4145425368F, + 0.4155185780F, 0.4164949044F, 0.4174715116F, 0.4184483949F, + 0.4194255498F, 0.4204029718F, 0.4213806563F, 0.4223585987F, + 0.4233367946F, 0.4243152392F, 0.4252939281F, 0.4262728566F, + 0.4272520202F, 0.4282314144F, 0.4292110345F, 0.4301908760F, + 0.4311709343F, 0.4321512047F, 0.4331316828F, 0.4341123639F, + 0.4350932435F, 0.4360743168F, 0.4370555794F, 0.4380370267F, + 0.4390186540F, 0.4400004567F, 0.4409824303F, 0.4419645701F, + 0.4429468716F, 0.4439293300F, 0.4449119409F, 0.4458946996F, + 0.4468776014F, 0.4478606418F, 0.4488438162F, 0.4498271199F, + 0.4508105483F, 0.4517940967F, 0.4527777607F, 0.4537615355F, + 0.4547454165F, 0.4557293991F, 0.4567134786F, 0.4576976505F, + 0.4586819101F, 0.4596662527F, 0.4606506738F, 0.4616351687F, + 0.4626197328F, 0.4636043614F, 0.4645890499F, 0.4655737936F, + 0.4665585880F, 0.4675434284F, 0.4685283101F, 0.4695132286F, + 0.4704981791F, 0.4714831570F, 0.4724681577F, 0.4734531766F, + 0.4744382089F, 0.4754232501F, 0.4764082956F, 0.4773933406F, + 0.4783783806F, 0.4793634108F, 0.4803484267F, 0.4813334237F, + 0.4823183969F, 0.4833033419F, 0.4842882540F, 0.4852731285F, + 0.4862579608F, 0.4872427462F, 0.4882274802F, 0.4892121580F, + 0.4901967751F, 0.4911813267F, 0.4921658083F, 0.4931502151F, + 0.4941345427F, 0.4951187863F, 0.4961029412F, 0.4970870029F, + 0.4980709667F, 0.4990548280F, 0.5000385822F, 0.5010222245F, + 0.5020057505F, 0.5029891553F, 0.5039724345F, 0.5049555834F, + 0.5059385973F, 0.5069214716F, 0.5079042018F, 0.5088867831F, + 0.5098692110F, 0.5108514808F, 0.5118335879F, 0.5128155277F, + 0.5137972956F, 0.5147788869F, 0.5157602971F, 0.5167415215F, + 0.5177225555F, 0.5187033945F, 0.5196840339F, 0.5206644692F, + 0.5216446956F, 0.5226247086F, 0.5236045035F, 0.5245840759F, + 0.5255634211F, 0.5265425344F, 0.5275214114F, 0.5285000474F, + 0.5294784378F, 0.5304565781F, 0.5314344637F, 0.5324120899F, + 0.5333894522F, 0.5343665461F, 0.5353433670F, 0.5363199102F, + 0.5372961713F, 0.5382721457F, 0.5392478287F, 0.5402232159F, + 0.5411983027F, 0.5421730845F, 0.5431475569F, 0.5441217151F, + 0.5450955548F, 0.5460690714F, 0.5470422602F, 0.5480151169F, + 0.5489876368F, 0.5499598155F, 0.5509316484F, 0.5519031310F, + 0.5528742587F, 0.5538450271F, 0.5548154317F, 0.5557854680F, + 0.5567551314F, 0.5577244174F, 0.5586933216F, 0.5596618395F, + 0.5606299665F, 0.5615976983F, 0.5625650302F, 0.5635319580F, + 0.5644984770F, 0.5654645828F, 0.5664302709F, 0.5673955370F, + 0.5683603765F, 0.5693247850F, 0.5702887580F, 0.5712522912F, + 0.5722153800F, 0.5731780200F, 0.5741402069F, 0.5751019362F, + 0.5760632034F, 0.5770240042F, 0.5779843341F, 0.5789441889F, + 0.5799035639F, 0.5808624549F, 0.5818208575F, 0.5827787673F, + 0.5837361800F, 0.5846930910F, 0.5856494961F, 0.5866053910F, + 0.5875607712F, 0.5885156324F, 0.5894699703F, 0.5904237804F, + 0.5913770586F, 0.5923298004F, 0.5932820016F, 0.5942336578F, + 0.5951847646F, 0.5961353179F, 0.5970853132F, 0.5980347464F, + 0.5989836131F, 0.5999319090F, 0.6008796298F, 0.6018267713F, + 0.6027733292F, 0.6037192993F, 0.6046646773F, 0.6056094589F, + 0.6065536400F, 0.6074972162F, 0.6084401833F, 0.6093825372F, + 0.6103242736F, 0.6112653884F, 0.6122058772F, 0.6131457359F, + 0.6140849604F, 0.6150235464F, 0.6159614897F, 0.6168987862F, + 0.6178354318F, 0.6187714223F, 0.6197067535F, 0.6206414213F, + 0.6215754215F, 0.6225087501F, 0.6234414028F, 0.6243733757F, + 0.6253046646F, 0.6262352654F, 0.6271651739F, 0.6280943862F, + 0.6290228982F, 0.6299507057F, 0.6308778048F, 0.6318041913F, + 0.6327298612F, 0.6336548105F, 0.6345790352F, 0.6355025312F, + 0.6364252945F, 0.6373473211F, 0.6382686070F, 0.6391891483F, + 0.6401089409F, 0.6410279808F, 0.6419462642F, 0.6428637869F, + 0.6437805452F, 0.6446965350F, 0.6456117524F, 0.6465261935F, + 0.6474398544F, 0.6483527311F, 0.6492648197F, 0.6501761165F, + 0.6510866174F, 0.6519963186F, 0.6529052162F, 0.6538133064F, + 0.6547205854F, 0.6556270492F, 0.6565326941F, 0.6574375162F, + 0.6583415117F, 0.6592446769F, 0.6601470079F, 0.6610485009F, + 0.6619491521F, 0.6628489578F, 0.6637479143F, 0.6646460177F, + 0.6655432643F, 0.6664396505F, 0.6673351724F, 0.6682298264F, + 0.6691236087F, 0.6700165157F, 0.6709085436F, 0.6717996889F, + 0.6726899478F, 0.6735793167F, 0.6744677918F, 0.6753553697F, + 0.6762420466F, 0.6771278190F, 0.6780126832F, 0.6788966357F, + 0.6797796728F, 0.6806617909F, 0.6815429866F, 0.6824232562F, + 0.6833025961F, 0.6841810030F, 0.6850584731F, 0.6859350031F, + 0.6868105894F, 0.6876852284F, 0.6885589168F, 0.6894316510F, + 0.6903034275F, 0.6911742430F, 0.6920440939F, 0.6929129769F, + 0.6937808884F, 0.6946478251F, 0.6955137837F, 0.6963787606F, + 0.6972427525F, 0.6981057560F, 0.6989677678F, 0.6998287845F, + 0.7006888028F, 0.7015478194F, 0.7024058309F, 0.7032628340F, + 0.7041188254F, 0.7049738019F, 0.7058277601F, 0.7066806969F, + 0.7075326089F, 0.7083834929F, 0.7092333457F, 0.7100821640F, + 0.7109299447F, 0.7117766846F, 0.7126223804F, 0.7134670291F, + 0.7143106273F, 0.7151531721F, 0.7159946602F, 0.7168350885F, + 0.7176744539F, 0.7185127534F, 0.7193499837F, 0.7201861418F, + 0.7210212247F, 0.7218552293F, 0.7226881526F, 0.7235199914F, + 0.7243507428F, 0.7251804039F, 0.7260089715F, 0.7268364426F, + 0.7276628144F, 0.7284880839F, 0.7293122481F, 0.7301353040F, + 0.7309572487F, 0.7317780794F, 0.7325977930F, 0.7334163868F, + 0.7342338579F, 0.7350502033F, 0.7358654202F, 0.7366795059F, + 0.7374924573F, 0.7383042718F, 0.7391149465F, 0.7399244787F, + 0.7407328655F, 0.7415401041F, 0.7423461920F, 0.7431511261F, + 0.7439549040F, 0.7447575227F, 0.7455589797F, 0.7463592723F, + 0.7471583976F, 0.7479563532F, 0.7487531363F, 0.7495487443F, + 0.7503431745F, 0.7511364244F, 0.7519284913F, 0.7527193726F, + 0.7535090658F, 0.7542975683F, 0.7550848776F, 0.7558709910F, + 0.7566559062F, 0.7574396205F, 0.7582221314F, 0.7590034366F, + 0.7597835334F, 0.7605624194F, 0.7613400923F, 0.7621165495F, + 0.7628917886F, 0.7636658072F, 0.7644386030F, 0.7652101735F, + 0.7659805164F, 0.7667496292F, 0.7675175098F, 0.7682841556F, + 0.7690495645F, 0.7698137341F, 0.7705766622F, 0.7713383463F, + 0.7720987844F, 0.7728579741F, 0.7736159132F, 0.7743725994F, + 0.7751280306F, 0.7758822046F, 0.7766351192F, 0.7773867722F, + 0.7781371614F, 0.7788862848F, 0.7796341401F, 0.7803807253F, + 0.7811260383F, 0.7818700769F, 0.7826128392F, 0.7833543230F, + 0.7840945263F, 0.7848334471F, 0.7855710833F, 0.7863074330F, + 0.7870424941F, 0.7877762647F, 0.7885087428F, 0.7892399264F, + 0.7899698137F, 0.7906984026F, 0.7914256914F, 0.7921516780F, + 0.7928763607F, 0.7935997375F, 0.7943218065F, 0.7950425661F, + 0.7957620142F, 0.7964801492F, 0.7971969692F, 0.7979124724F, + 0.7986266570F, 0.7993395214F, 0.8000510638F, 0.8007612823F, + 0.8014701754F, 0.8021777413F, 0.8028839784F, 0.8035888849F, + 0.8042924592F, 0.8049946997F, 0.8056956048F, 0.8063951727F, + 0.8070934020F, 0.8077902910F, 0.8084858381F, 0.8091800419F, + 0.8098729007F, 0.8105644130F, 0.8112545774F, 0.8119433922F, + 0.8126308561F, 0.8133169676F, 0.8140017251F, 0.8146851272F, + 0.8153671726F, 0.8160478598F, 0.8167271874F, 0.8174051539F, + 0.8180817582F, 0.8187569986F, 0.8194308741F, 0.8201033831F, + 0.8207745244F, 0.8214442966F, 0.8221126986F, 0.8227797290F, + 0.8234453865F, 0.8241096700F, 0.8247725781F, 0.8254341097F, + 0.8260942636F, 0.8267530385F, 0.8274104334F, 0.8280664470F, + 0.8287210782F, 0.8293743259F, 0.8300261889F, 0.8306766662F, + 0.8313257566F, 0.8319734591F, 0.8326197727F, 0.8332646963F, + 0.8339082288F, 0.8345503692F, 0.8351911167F, 0.8358304700F, + 0.8364684284F, 0.8371049907F, 0.8377401562F, 0.8383739238F, + 0.8390062927F, 0.8396372618F, 0.8402668305F, 0.8408949977F, + 0.8415217626F, 0.8421471245F, 0.8427710823F, 0.8433936354F, + 0.8440147830F, 0.8446345242F, 0.8452528582F, 0.8458697844F, + 0.8464853020F, 0.8470994102F, 0.8477121084F, 0.8483233958F, + 0.8489332718F, 0.8495417356F, 0.8501487866F, 0.8507544243F, + 0.8513586479F, 0.8519614568F, 0.8525628505F, 0.8531628283F, + 0.8537613897F, 0.8543585341F, 0.8549542611F, 0.8555485699F, + 0.8561414603F, 0.8567329315F, 0.8573229832F, 0.8579116149F, + 0.8584988262F, 0.8590846165F, 0.8596689855F, 0.8602519327F, + 0.8608334577F, 0.8614135603F, 0.8619922399F, 0.8625694962F, + 0.8631453289F, 0.8637197377F, 0.8642927222F, 0.8648642821F, + 0.8654344172F, 0.8660031272F, 0.8665704118F, 0.8671362708F, + 0.8677007039F, 0.8682637109F, 0.8688252917F, 0.8693854460F, + 0.8699441737F, 0.8705014745F, 0.8710573485F, 0.8716117953F, + 0.8721648150F, 0.8727164073F, 0.8732665723F, 0.8738153098F, + 0.8743626197F, 0.8749085021F, 0.8754529569F, 0.8759959840F, + 0.8765375835F, 0.8770777553F, 0.8776164996F, 0.8781538162F, + 0.8786897054F, 0.8792241670F, 0.8797572013F, 0.8802888082F, + 0.8808189880F, 0.8813477407F, 0.8818750664F, 0.8824009653F, + 0.8829254375F, 0.8834484833F, 0.8839701028F, 0.8844902961F, + 0.8850090636F, 0.8855264054F, 0.8860423218F, 0.8865568131F, + 0.8870698794F, 0.8875815212F, 0.8880917386F, 0.8886005319F, + 0.8891079016F, 0.8896138479F, 0.8901183712F, 0.8906214719F, + 0.8911231503F, 0.8916234067F, 0.8921222417F, 0.8926196556F, + 0.8931156489F, 0.8936102219F, 0.8941033752F, 0.8945951092F, + 0.8950854244F, 0.8955743212F, 0.8960618003F, 0.8965478621F, + 0.8970325071F, 0.8975157359F, 0.8979975490F, 0.8984779471F, + 0.8989569307F, 0.8994345004F, 0.8999106568F, 0.9003854005F, + 0.9008587323F, 0.9013306526F, 0.9018011623F, 0.9022702619F, + 0.9027379521F, 0.9032042337F, 0.9036691074F, 0.9041325739F, + 0.9045946339F, 0.9050552882F, 0.9055145376F, 0.9059723828F, + 0.9064288246F, 0.9068838638F, 0.9073375013F, 0.9077897379F, + 0.9082405743F, 0.9086900115F, 0.9091380503F, 0.9095846917F, + 0.9100299364F, 0.9104737854F, 0.9109162397F, 0.9113573001F, + 0.9117969675F, 0.9122352430F, 0.9126721275F, 0.9131076219F, + 0.9135417273F, 0.9139744447F, 0.9144057750F, 0.9148357194F, + 0.9152642787F, 0.9156914542F, 0.9161172468F, 0.9165416576F, + 0.9169646877F, 0.9173863382F, 0.9178066102F, 0.9182255048F, + 0.9186430232F, 0.9190591665F, 0.9194739359F, 0.9198873324F, + 0.9202993574F, 0.9207100120F, 0.9211192973F, 0.9215272147F, + 0.9219337653F, 0.9223389504F, 0.9227427713F, 0.9231452290F, + 0.9235463251F, 0.9239460607F, 0.9243444371F, 0.9247414557F, + 0.9251371177F, 0.9255314245F, 0.9259243774F, 0.9263159778F, + 0.9267062270F, 0.9270951264F, 0.9274826774F, 0.9278688814F, + 0.9282537398F, 0.9286372540F, 0.9290194254F, 0.9294002555F, + 0.9297797458F, 0.9301578976F, 0.9305347125F, 0.9309101919F, + 0.9312843373F, 0.9316571503F, 0.9320286323F, 0.9323987849F, + 0.9327676097F, 0.9331351080F, 0.9335012816F, 0.9338661320F, + 0.9342296607F, 0.9345918694F, 0.9349527596F, 0.9353123330F, + 0.9356705911F, 0.9360275357F, 0.9363831683F, 0.9367374905F, + 0.9370905042F, 0.9374422108F, 0.9377926122F, 0.9381417099F, + 0.9384895057F, 0.9388360014F, 0.9391811985F, 0.9395250989F, + 0.9398677043F, 0.9402090165F, 0.9405490371F, 0.9408877680F, + 0.9412252110F, 0.9415613678F, 0.9418962402F, 0.9422298301F, + 0.9425621392F, 0.9428931695F, 0.9432229226F, 0.9435514005F, + 0.9438786050F, 0.9442045381F, 0.9445292014F, 0.9448525971F, + 0.9451747268F, 0.9454955926F, 0.9458151963F, 0.9461335399F, + 0.9464506253F, 0.9467664545F, 0.9470810293F, 0.9473943517F, + 0.9477064238F, 0.9480172474F, 0.9483268246F, 0.9486351573F, + 0.9489422475F, 0.9492480973F, 0.9495527087F, 0.9498560837F, + 0.9501582243F, 0.9504591325F, 0.9507588105F, 0.9510572603F, + 0.9513544839F, 0.9516504834F, 0.9519452609F, 0.9522388186F, + 0.9525311584F, 0.9528222826F, 0.9531121932F, 0.9534008923F, + 0.9536883821F, 0.9539746647F, 0.9542597424F, 0.9545436171F, + 0.9548262912F, 0.9551077667F, 0.9553880459F, 0.9556671309F, + 0.9559450239F, 0.9562217272F, 0.9564972429F, 0.9567715733F, + 0.9570447206F, 0.9573166871F, 0.9575874749F, 0.9578570863F, + 0.9581255236F, 0.9583927890F, 0.9586588849F, 0.9589238134F, + 0.9591875769F, 0.9594501777F, 0.9597116180F, 0.9599719003F, + 0.9602310267F, 0.9604889995F, 0.9607458213F, 0.9610014942F, + 0.9612560206F, 0.9615094028F, 0.9617616433F, 0.9620127443F, + 0.9622627083F, 0.9625115376F, 0.9627592345F, 0.9630058016F, + 0.9632512411F, 0.9634955555F, 0.9637387471F, 0.9639808185F, + 0.9642217720F, 0.9644616100F, 0.9647003349F, 0.9649379493F, + 0.9651744556F, 0.9654098561F, 0.9656441534F, 0.9658773499F, + 0.9661094480F, 0.9663404504F, 0.9665703593F, 0.9667991774F, + 0.9670269071F, 0.9672535509F, 0.9674791114F, 0.9677035909F, + 0.9679269921F, 0.9681493174F, 0.9683705694F, 0.9685907506F, + 0.9688098636F, 0.9690279108F, 0.9692448948F, 0.9694608182F, + 0.9696756836F, 0.9698894934F, 0.9701022503F, 0.9703139569F, + 0.9705246156F, 0.9707342291F, 0.9709428000F, 0.9711503309F, + 0.9713568243F, 0.9715622829F, 0.9717667093F, 0.9719701060F, + 0.9721724757F, 0.9723738210F, 0.9725741446F, 0.9727734490F, + 0.9729717369F, 0.9731690109F, 0.9733652737F, 0.9735605279F, + 0.9737547762F, 0.9739480212F, 0.9741402656F, 0.9743315120F, + 0.9745217631F, 0.9747110216F, 0.9748992901F, 0.9750865714F, + 0.9752728681F, 0.9754581829F, 0.9756425184F, 0.9758258775F, + 0.9760082627F, 0.9761896768F, 0.9763701224F, 0.9765496024F, + 0.9767281193F, 0.9769056760F, 0.9770822751F, 0.9772579193F, + 0.9774326114F, 0.9776063542F, 0.9777791502F, 0.9779510023F, + 0.9781219133F, 0.9782918858F, 0.9784609226F, 0.9786290264F, + 0.9787962000F, 0.9789624461F, 0.9791277676F, 0.9792921671F, + 0.9794556474F, 0.9796182113F, 0.9797798615F, 0.9799406009F, + 0.9801004321F, 0.9802593580F, 0.9804173813F, 0.9805745049F, + 0.9807307314F, 0.9808860637F, 0.9810405046F, 0.9811940568F, + 0.9813467232F, 0.9814985065F, 0.9816494095F, 0.9817994351F, + 0.9819485860F, 0.9820968650F, 0.9822442750F, 0.9823908186F, + 0.9825364988F, 0.9826813184F, 0.9828252801F, 0.9829683868F, + 0.9831106413F, 0.9832520463F, 0.9833926048F, 0.9835323195F, + 0.9836711932F, 0.9838092288F, 0.9839464291F, 0.9840827969F, + 0.9842183351F, 0.9843530464F, 0.9844869337F, 0.9846199998F, + 0.9847522475F, 0.9848836798F, 0.9850142993F, 0.9851441090F, + 0.9852731117F, 0.9854013101F, 0.9855287073F, 0.9856553058F, + 0.9857811087F, 0.9859061188F, 0.9860303388F, 0.9861537717F, + 0.9862764202F, 0.9863982872F, 0.9865193756F, 0.9866396882F, + 0.9867592277F, 0.9868779972F, 0.9869959993F, 0.9871132370F, + 0.9872297131F, 0.9873454304F, 0.9874603918F, 0.9875746001F, + 0.9876880581F, 0.9878007688F, 0.9879127348F, 0.9880239592F, + 0.9881344447F, 0.9882441941F, 0.9883532104F, 0.9884614962F, + 0.9885690546F, 0.9886758883F, 0.9887820001F, 0.9888873930F, + 0.9889920697F, 0.9890960331F, 0.9891992859F, 0.9893018312F, + 0.9894036716F, 0.9895048100F, 0.9896052493F, 0.9897049923F, + 0.9898040418F, 0.9899024006F, 0.9900000717F, 0.9900970577F, + 0.9901933616F, 0.9902889862F, 0.9903839343F, 0.9904782087F, + 0.9905718122F, 0.9906647477F, 0.9907570180F, 0.9908486259F, + 0.9909395742F, 0.9910298658F, 0.9911195034F, 0.9912084899F, + 0.9912968281F, 0.9913845208F, 0.9914715708F, 0.9915579810F, + 0.9916437540F, 0.9917288928F, 0.9918134001F, 0.9918972788F, + 0.9919805316F, 0.9920631613F, 0.9921451707F, 0.9922265626F, + 0.9923073399F, 0.9923875052F, 0.9924670615F, 0.9925460114F, + 0.9926243577F, 0.9927021033F, 0.9927792508F, 0.9928558032F, + 0.9929317631F, 0.9930071333F, 0.9930819167F, 0.9931561158F, + 0.9932297337F, 0.9933027728F, 0.9933752362F, 0.9934471264F, + 0.9935184462F, 0.9935891985F, 0.9936593859F, 0.9937290112F, + 0.9937980771F, 0.9938665864F, 0.9939345418F, 0.9940019460F, + 0.9940688018F, 0.9941351118F, 0.9942008789F, 0.9942661057F, + 0.9943307950F, 0.9943949494F, 0.9944585717F, 0.9945216645F, + 0.9945842307F, 0.9946462728F, 0.9947077936F, 0.9947687957F, + 0.9948292820F, 0.9948892550F, 0.9949487174F, 0.9950076719F, + 0.9950661212F, 0.9951240679F, 0.9951815148F, 0.9952384645F, + 0.9952949196F, 0.9953508828F, 0.9954063568F, 0.9954613442F, + 0.9955158476F, 0.9955698697F, 0.9956234132F, 0.9956764806F, + 0.9957290746F, 0.9957811978F, 0.9958328528F, 0.9958840423F, + 0.9959347688F, 0.9959850351F, 0.9960348435F, 0.9960841969F, + 0.9961330977F, 0.9961815486F, 0.9962295521F, 0.9962771108F, + 0.9963242274F, 0.9963709043F, 0.9964171441F, 0.9964629494F, + 0.9965083228F, 0.9965532668F, 0.9965977840F, 0.9966418768F, + 0.9966855479F, 0.9967287998F, 0.9967716350F, 0.9968140559F, + 0.9968560653F, 0.9968976655F, 0.9969388591F, 0.9969796485F, + 0.9970200363F, 0.9970600250F, 0.9970996170F, 0.9971388149F, + 0.9971776211F, 0.9972160380F, 0.9972540683F, 0.9972917142F, + 0.9973289783F, 0.9973658631F, 0.9974023709F, 0.9974385042F, + 0.9974742655F, 0.9975096571F, 0.9975446816F, 0.9975793413F, + 0.9976136386F, 0.9976475759F, 0.9976811557F, 0.9977143803F, + 0.9977472521F, 0.9977797736F, 0.9978119470F, 0.9978437748F, + 0.9978752593F, 0.9979064029F, 0.9979372079F, 0.9979676768F, + 0.9979978117F, 0.9980276151F, 0.9980570893F, 0.9980862367F, + 0.9981150595F, 0.9981435600F, 0.9981717406F, 0.9981996035F, + 0.9982271511F, 0.9982543856F, 0.9982813093F, 0.9983079246F, + 0.9983342336F, 0.9983602386F, 0.9983859418F, 0.9984113456F, + 0.9984364522F, 0.9984612638F, 0.9984857825F, 0.9985100108F, + 0.9985339507F, 0.9985576044F, 0.9985809743F, 0.9986040624F, + 0.9986268710F, 0.9986494022F, 0.9986716583F, 0.9986936413F, + 0.9987153535F, 0.9987367969F, 0.9987579738F, 0.9987788864F, + 0.9987995366F, 0.9988199267F, 0.9988400587F, 0.9988599348F, + 0.9988795572F, 0.9988989278F, 0.9989180487F, 0.9989369222F, + 0.9989555501F, 0.9989739347F, 0.9989920780F, 0.9990099820F, + 0.9990276487F, 0.9990450803F, 0.9990622787F, 0.9990792460F, + 0.9990959841F, 0.9991124952F, 0.9991287812F, 0.9991448440F, + 0.9991606858F, 0.9991763084F, 0.9991917139F, 0.9992069042F, + 0.9992218813F, 0.9992366471F, 0.9992512035F, 0.9992655525F, + 0.9992796961F, 0.9992936361F, 0.9993073744F, 0.9993209131F, + 0.9993342538F, 0.9993473987F, 0.9993603494F, 0.9993731080F, + 0.9993856762F, 0.9993980559F, 0.9994102490F, 0.9994222573F, + 0.9994340827F, 0.9994457269F, 0.9994571918F, 0.9994684793F, + 0.9994795910F, 0.9994905288F, 0.9995012945F, 0.9995118898F, + 0.9995223165F, 0.9995325765F, 0.9995426713F, 0.9995526029F, + 0.9995623728F, 0.9995719829F, 0.9995814349F, 0.9995907304F, + 0.9995998712F, 0.9996088590F, 0.9996176954F, 0.9996263821F, + 0.9996349208F, 0.9996433132F, 0.9996515609F, 0.9996596656F, + 0.9996676288F, 0.9996754522F, 0.9996831375F, 0.9996906862F, + 0.9996981000F, 0.9997053804F, 0.9997125290F, 0.9997195474F, + 0.9997264371F, 0.9997331998F, 0.9997398369F, 0.9997463500F, + 0.9997527406F, 0.9997590103F, 0.9997651606F, 0.9997711930F, + 0.9997771089F, 0.9997829098F, 0.9997885973F, 0.9997941728F, + 0.9997996378F, 0.9998049936F, 0.9998102419F, 0.9998153839F, + 0.9998204211F, 0.9998253550F, 0.9998301868F, 0.9998349182F, + 0.9998395503F, 0.9998440847F, 0.9998485226F, 0.9998528654F, + 0.9998571146F, 0.9998612713F, 0.9998653370F, 0.9998693130F, + 0.9998732007F, 0.9998770012F, 0.9998807159F, 0.9998843461F, + 0.9998878931F, 0.9998913581F, 0.9998947424F, 0.9998980473F, + 0.9999012740F, 0.9999044237F, 0.9999074976F, 0.9999104971F, + 0.9999134231F, 0.9999162771F, 0.9999190601F, 0.9999217733F, + 0.9999244179F, 0.9999269950F, 0.9999295058F, 0.9999319515F, + 0.9999343332F, 0.9999366519F, 0.9999389088F, 0.9999411050F, + 0.9999432416F, 0.9999453196F, 0.9999473402F, 0.9999493044F, + 0.9999512132F, 0.9999530677F, 0.9999548690F, 0.9999566180F, + 0.9999583157F, 0.9999599633F, 0.9999615616F, 0.9999631116F, + 0.9999646144F, 0.9999660709F, 0.9999674820F, 0.9999688487F, + 0.9999701719F, 0.9999714526F, 0.9999726917F, 0.9999738900F, + 0.9999750486F, 0.9999761682F, 0.9999772497F, 0.9999782941F, + 0.9999793021F, 0.9999802747F, 0.9999812126F, 0.9999821167F, + 0.9999829878F, 0.9999838268F, 0.9999846343F, 0.9999854113F, + 0.9999861584F, 0.9999868765F, 0.9999875664F, 0.9999882287F, + 0.9999888642F, 0.9999894736F, 0.9999900577F, 0.9999906172F, + 0.9999911528F, 0.9999916651F, 0.9999921548F, 0.9999926227F, + 0.9999930693F, 0.9999934954F, 0.9999939015F, 0.9999942883F, + 0.9999946564F, 0.9999950064F, 0.9999953390F, 0.9999956547F, + 0.9999959541F, 0.9999962377F, 0.9999965062F, 0.9999967601F, + 0.9999969998F, 0.9999972260F, 0.9999974392F, 0.9999976399F, + 0.9999978285F, 0.9999980056F, 0.9999981716F, 0.9999983271F, + 0.9999984724F, 0.9999986081F, 0.9999987345F, 0.9999988521F, + 0.9999989613F, 0.9999990625F, 0.9999991562F, 0.9999992426F, + 0.9999993223F, 0.9999993954F, 0.9999994625F, 0.9999995239F, + 0.9999995798F, 0.9999996307F, 0.9999996768F, 0.9999997184F, + 0.9999997559F, 0.9999997895F, 0.9999998195F, 0.9999998462F, + 0.9999998698F, 0.9999998906F, 0.9999999088F, 0.9999999246F, + 0.9999999383F, 0.9999999500F, 0.9999999600F, 0.9999999684F, + 0.9999999754F, 0.9999999811F, 0.9999999858F, 0.9999999896F, + 0.9999999925F, 0.9999999948F, 0.9999999965F, 0.9999999978F, + 0.9999999986F, 0.9999999992F, 0.9999999996F, 0.9999999998F, + 0.9999999999F, 1.0000000000F, 1.0000000000F, 1.0000000000F, +}; + +static float vwin8192[4096] = { + 0.0000000578F, 0.0000005198F, 0.0000014438F, 0.0000028299F, + 0.0000046780F, 0.0000069882F, 0.0000097604F, 0.0000129945F, + 0.0000166908F, 0.0000208490F, 0.0000254692F, 0.0000305515F, + 0.0000360958F, 0.0000421021F, 0.0000485704F, 0.0000555006F, + 0.0000628929F, 0.0000707472F, 0.0000790635F, 0.0000878417F, + 0.0000970820F, 0.0001067842F, 0.0001169483F, 0.0001275744F, + 0.0001386625F, 0.0001502126F, 0.0001622245F, 0.0001746984F, + 0.0001876343F, 0.0002010320F, 0.0002148917F, 0.0002292132F, + 0.0002439967F, 0.0002592421F, 0.0002749493F, 0.0002911184F, + 0.0003077493F, 0.0003248421F, 0.0003423967F, 0.0003604132F, + 0.0003788915F, 0.0003978316F, 0.0004172335F, 0.0004370971F, + 0.0004574226F, 0.0004782098F, 0.0004994587F, 0.0005211694F, + 0.0005433418F, 0.0005659759F, 0.0005890717F, 0.0006126292F, + 0.0006366484F, 0.0006611292F, 0.0006860716F, 0.0007114757F, + 0.0007373414F, 0.0007636687F, 0.0007904576F, 0.0008177080F, + 0.0008454200F, 0.0008735935F, 0.0009022285F, 0.0009313250F, + 0.0009608830F, 0.0009909025F, 0.0010213834F, 0.0010523257F, + 0.0010837295F, 0.0011155946F, 0.0011479211F, 0.0011807090F, + 0.0012139582F, 0.0012476687F, 0.0012818405F, 0.0013164736F, + 0.0013515679F, 0.0013871235F, 0.0014231402F, 0.0014596182F, + 0.0014965573F, 0.0015339576F, 0.0015718190F, 0.0016101415F, + 0.0016489251F, 0.0016881698F, 0.0017278754F, 0.0017680421F, + 0.0018086698F, 0.0018497584F, 0.0018913080F, 0.0019333185F, + 0.0019757898F, 0.0020187221F, 0.0020621151F, 0.0021059690F, + 0.0021502837F, 0.0021950591F, 0.0022402953F, 0.0022859921F, + 0.0023321497F, 0.0023787679F, 0.0024258467F, 0.0024733861F, + 0.0025213861F, 0.0025698466F, 0.0026187676F, 0.0026681491F, + 0.0027179911F, 0.0027682935F, 0.0028190562F, 0.0028702794F, + 0.0029219628F, 0.0029741066F, 0.0030267107F, 0.0030797749F, + 0.0031332994F, 0.0031872841F, 0.0032417289F, 0.0032966338F, + 0.0033519988F, 0.0034078238F, 0.0034641089F, 0.0035208539F, + 0.0035780589F, 0.0036357237F, 0.0036938485F, 0.0037524331F, + 0.0038114775F, 0.0038709817F, 0.0039309456F, 0.0039913692F, + 0.0040522524F, 0.0041135953F, 0.0041753978F, 0.0042376599F, + 0.0043003814F, 0.0043635624F, 0.0044272029F, 0.0044913028F, + 0.0045558620F, 0.0046208806F, 0.0046863585F, 0.0047522955F, + 0.0048186919F, 0.0048855473F, 0.0049528619F, 0.0050206356F, + 0.0050888684F, 0.0051575601F, 0.0052267108F, 0.0052963204F, + 0.0053663890F, 0.0054369163F, 0.0055079025F, 0.0055793474F, + 0.0056512510F, 0.0057236133F, 0.0057964342F, 0.0058697137F, + 0.0059434517F, 0.0060176482F, 0.0060923032F, 0.0061674166F, + 0.0062429883F, 0.0063190183F, 0.0063955066F, 0.0064724532F, + 0.0065498579F, 0.0066277207F, 0.0067060416F, 0.0067848205F, + 0.0068640575F, 0.0069437523F, 0.0070239051F, 0.0071045157F, + 0.0071855840F, 0.0072671102F, 0.0073490940F, 0.0074315355F, + 0.0075144345F, 0.0075977911F, 0.0076816052F, 0.0077658768F, + 0.0078506057F, 0.0079357920F, 0.0080214355F, 0.0081075363F, + 0.0081940943F, 0.0082811094F, 0.0083685816F, 0.0084565108F, + 0.0085448970F, 0.0086337401F, 0.0087230401F, 0.0088127969F, + 0.0089030104F, 0.0089936807F, 0.0090848076F, 0.0091763911F, + 0.0092684311F, 0.0093609276F, 0.0094538805F, 0.0095472898F, + 0.0096411554F, 0.0097354772F, 0.0098302552F, 0.0099254894F, + 0.0100211796F, 0.0101173259F, 0.0102139281F, 0.0103109863F, + 0.0104085002F, 0.0105064700F, 0.0106048955F, 0.0107037766F, + 0.0108031133F, 0.0109029056F, 0.0110031534F, 0.0111038565F, + 0.0112050151F, 0.0113066289F, 0.0114086980F, 0.0115112222F, + 0.0116142015F, 0.0117176359F, 0.0118215252F, 0.0119258695F, + 0.0120306686F, 0.0121359225F, 0.0122416312F, 0.0123477944F, + 0.0124544123F, 0.0125614847F, 0.0126690116F, 0.0127769928F, + 0.0128854284F, 0.0129943182F, 0.0131036623F, 0.0132134604F, + 0.0133237126F, 0.0134344188F, 0.0135455790F, 0.0136571929F, + 0.0137692607F, 0.0138817821F, 0.0139947572F, 0.0141081859F, + 0.0142220681F, 0.0143364037F, 0.0144511927F, 0.0145664350F, + 0.0146821304F, 0.0147982791F, 0.0149148808F, 0.0150319355F, + 0.0151494431F, 0.0152674036F, 0.0153858168F, 0.0155046828F, + 0.0156240014F, 0.0157437726F, 0.0158639962F, 0.0159846723F, + 0.0161058007F, 0.0162273814F, 0.0163494142F, 0.0164718991F, + 0.0165948361F, 0.0167182250F, 0.0168420658F, 0.0169663584F, + 0.0170911027F, 0.0172162987F, 0.0173419462F, 0.0174680452F, + 0.0175945956F, 0.0177215974F, 0.0178490504F, 0.0179769545F, + 0.0181053098F, 0.0182341160F, 0.0183633732F, 0.0184930812F, + 0.0186232399F, 0.0187538494F, 0.0188849094F, 0.0190164200F, + 0.0191483809F, 0.0192807923F, 0.0194136539F, 0.0195469656F, + 0.0196807275F, 0.0198149394F, 0.0199496012F, 0.0200847128F, + 0.0202202742F, 0.0203562853F, 0.0204927460F, 0.0206296561F, + 0.0207670157F, 0.0209048245F, 0.0210430826F, 0.0211817899F, + 0.0213209462F, 0.0214605515F, 0.0216006057F, 0.0217411086F, + 0.0218820603F, 0.0220234605F, 0.0221653093F, 0.0223076066F, + 0.0224503521F, 0.0225935459F, 0.0227371879F, 0.0228812779F, + 0.0230258160F, 0.0231708018F, 0.0233162355F, 0.0234621169F, + 0.0236084459F, 0.0237552224F, 0.0239024462F, 0.0240501175F, + 0.0241982359F, 0.0243468015F, 0.0244958141F, 0.0246452736F, + 0.0247951800F, 0.0249455331F, 0.0250963329F, 0.0252475792F, + 0.0253992720F, 0.0255514111F, 0.0257039965F, 0.0258570281F, + 0.0260105057F, 0.0261644293F, 0.0263187987F, 0.0264736139F, + 0.0266288747F, 0.0267845811F, 0.0269407330F, 0.0270973302F, + 0.0272543727F, 0.0274118604F, 0.0275697930F, 0.0277281707F, + 0.0278869932F, 0.0280462604F, 0.0282059723F, 0.0283661287F, + 0.0285267295F, 0.0286877747F, 0.0288492641F, 0.0290111976F, + 0.0291735751F, 0.0293363965F, 0.0294996617F, 0.0296633706F, + 0.0298275231F, 0.0299921190F, 0.0301571583F, 0.0303226409F, + 0.0304885667F, 0.0306549354F, 0.0308217472F, 0.0309890017F, + 0.0311566989F, 0.0313248388F, 0.0314934211F, 0.0316624459F, + 0.0318319128F, 0.0320018220F, 0.0321721732F, 0.0323429663F, + 0.0325142013F, 0.0326858779F, 0.0328579962F, 0.0330305559F, + 0.0332035570F, 0.0333769994F, 0.0335508829F, 0.0337252074F, + 0.0338999728F, 0.0340751790F, 0.0342508259F, 0.0344269134F, + 0.0346034412F, 0.0347804094F, 0.0349578178F, 0.0351356663F, + 0.0353139548F, 0.0354926831F, 0.0356718511F, 0.0358514588F, + 0.0360315059F, 0.0362119924F, 0.0363929182F, 0.0365742831F, + 0.0367560870F, 0.0369383297F, 0.0371210113F, 0.0373041315F, + 0.0374876902F, 0.0376716873F, 0.0378561226F, 0.0380409961F, + 0.0382263077F, 0.0384120571F, 0.0385982443F, 0.0387848691F, + 0.0389719315F, 0.0391594313F, 0.0393473683F, 0.0395357425F, + 0.0397245537F, 0.0399138017F, 0.0401034866F, 0.0402936080F, + 0.0404841660F, 0.0406751603F, 0.0408665909F, 0.0410584576F, + 0.0412507603F, 0.0414434988F, 0.0416366731F, 0.0418302829F, + 0.0420243282F, 0.0422188088F, 0.0424137246F, 0.0426090755F, + 0.0428048613F, 0.0430010819F, 0.0431977371F, 0.0433948269F, + 0.0435923511F, 0.0437903095F, 0.0439887020F, 0.0441875285F, + 0.0443867889F, 0.0445864830F, 0.0447866106F, 0.0449871717F, + 0.0451881661F, 0.0453895936F, 0.0455914542F, 0.0457937477F, + 0.0459964738F, 0.0461996326F, 0.0464032239F, 0.0466072475F, + 0.0468117032F, 0.0470165910F, 0.0472219107F, 0.0474276622F, + 0.0476338452F, 0.0478404597F, 0.0480475056F, 0.0482549827F, + 0.0484628907F, 0.0486712297F, 0.0488799994F, 0.0490891998F, + 0.0492988306F, 0.0495088917F, 0.0497193830F, 0.0499303043F, + 0.0501416554F, 0.0503534363F, 0.0505656468F, 0.0507782867F, + 0.0509913559F, 0.0512048542F, 0.0514187815F, 0.0516331376F, + 0.0518479225F, 0.0520631358F, 0.0522787775F, 0.0524948475F, + 0.0527113455F, 0.0529282715F, 0.0531456252F, 0.0533634066F, + 0.0535816154F, 0.0538002515F, 0.0540193148F, 0.0542388051F, + 0.0544587222F, 0.0546790660F, 0.0548998364F, 0.0551210331F, + 0.0553426561F, 0.0555647051F, 0.0557871801F, 0.0560100807F, + 0.0562334070F, 0.0564571587F, 0.0566813357F, 0.0569059378F, + 0.0571309649F, 0.0573564168F, 0.0575822933F, 0.0578085942F, + 0.0580353195F, 0.0582624689F, 0.0584900423F, 0.0587180396F, + 0.0589464605F, 0.0591753049F, 0.0594045726F, 0.0596342635F, + 0.0598643774F, 0.0600949141F, 0.0603258735F, 0.0605572555F, + 0.0607890597F, 0.0610212862F, 0.0612539346F, 0.0614870049F, + 0.0617204968F, 0.0619544103F, 0.0621887451F, 0.0624235010F, + 0.0626586780F, 0.0628942758F, 0.0631302942F, 0.0633667331F, + 0.0636035923F, 0.0638408717F, 0.0640785710F, 0.0643166901F, + 0.0645552288F, 0.0647941870F, 0.0650335645F, 0.0652733610F, + 0.0655135765F, 0.0657542108F, 0.0659952636F, 0.0662367348F, + 0.0664786242F, 0.0667209316F, 0.0669636570F, 0.0672068000F, + 0.0674503605F, 0.0676943384F, 0.0679387334F, 0.0681835454F, + 0.0684287742F, 0.0686744196F, 0.0689204814F, 0.0691669595F, + 0.0694138536F, 0.0696611637F, 0.0699088894F, 0.0701570307F, + 0.0704055873F, 0.0706545590F, 0.0709039458F, 0.0711537473F, + 0.0714039634F, 0.0716545939F, 0.0719056387F, 0.0721570975F, + 0.0724089702F, 0.0726612565F, 0.0729139563F, 0.0731670694F, + 0.0734205956F, 0.0736745347F, 0.0739288866F, 0.0741836510F, + 0.0744388277F, 0.0746944166F, 0.0749504175F, 0.0752068301F, + 0.0754636543F, 0.0757208899F, 0.0759785367F, 0.0762365946F, + 0.0764950632F, 0.0767539424F, 0.0770132320F, 0.0772729319F, + 0.0775330418F, 0.0777935616F, 0.0780544909F, 0.0783158298F, + 0.0785775778F, 0.0788397349F, 0.0791023009F, 0.0793652755F, + 0.0796286585F, 0.0798924498F, 0.0801566492F, 0.0804212564F, + 0.0806862712F, 0.0809516935F, 0.0812175231F, 0.0814837597F, + 0.0817504031F, 0.0820174532F, 0.0822849097F, 0.0825527724F, + 0.0828210412F, 0.0830897158F, 0.0833587960F, 0.0836282816F, + 0.0838981724F, 0.0841684682F, 0.0844391688F, 0.0847102740F, + 0.0849817835F, 0.0852536973F, 0.0855260150F, 0.0857987364F, + 0.0860718614F, 0.0863453897F, 0.0866193211F, 0.0868936554F, + 0.0871683924F, 0.0874435319F, 0.0877190737F, 0.0879950175F, + 0.0882713632F, 0.0885481105F, 0.0888252592F, 0.0891028091F, + 0.0893807600F, 0.0896591117F, 0.0899378639F, 0.0902170165F, + 0.0904965692F, 0.0907765218F, 0.0910568740F, 0.0913376258F, + 0.0916187767F, 0.0919003268F, 0.0921822756F, 0.0924646230F, + 0.0927473687F, 0.0930305126F, 0.0933140545F, 0.0935979940F, + 0.0938823310F, 0.0941670653F, 0.0944521966F, 0.0947377247F, + 0.0950236494F, 0.0953099704F, 0.0955966876F, 0.0958838007F, + 0.0961713094F, 0.0964592136F, 0.0967475131F, 0.0970362075F, + 0.0973252967F, 0.0976147805F, 0.0979046585F, 0.0981949307F, + 0.0984855967F, 0.0987766563F, 0.0990681093F, 0.0993599555F, + 0.0996521945F, 0.0999448263F, 0.1002378506F, 0.1005312671F, + 0.1008250755F, 0.1011192757F, 0.1014138675F, 0.1017088505F, + 0.1020042246F, 0.1022999895F, 0.1025961450F, 0.1028926909F, + 0.1031896268F, 0.1034869526F, 0.1037846680F, 0.1040827729F, + 0.1043812668F, 0.1046801497F, 0.1049794213F, 0.1052790813F, + 0.1055791294F, 0.1058795656F, 0.1061803894F, 0.1064816006F, + 0.1067831991F, 0.1070851846F, 0.1073875568F, 0.1076903155F, + 0.1079934604F, 0.1082969913F, 0.1086009079F, 0.1089052101F, + 0.1092098975F, 0.1095149699F, 0.1098204270F, 0.1101262687F, + 0.1104324946F, 0.1107391045F, 0.1110460982F, 0.1113534754F, + 0.1116612359F, 0.1119693793F, 0.1122779055F, 0.1125868142F, + 0.1128961052F, 0.1132057781F, 0.1135158328F, 0.1138262690F, + 0.1141370863F, 0.1144482847F, 0.1147598638F, 0.1150718233F, + 0.1153841631F, 0.1156968828F, 0.1160099822F, 0.1163234610F, + 0.1166373190F, 0.1169515559F, 0.1172661714F, 0.1175811654F, + 0.1178965374F, 0.1182122874F, 0.1185284149F, 0.1188449198F, + 0.1191618018F, 0.1194790606F, 0.1197966960F, 0.1201147076F, + 0.1204330953F, 0.1207518587F, 0.1210709976F, 0.1213905118F, + 0.1217104009F, 0.1220306647F, 0.1223513029F, 0.1226723153F, + 0.1229937016F, 0.1233154615F, 0.1236375948F, 0.1239601011F, + 0.1242829803F, 0.1246062319F, 0.1249298559F, 0.1252538518F, + 0.1255782195F, 0.1259029586F, 0.1262280689F, 0.1265535501F, + 0.1268794019F, 0.1272056241F, 0.1275322163F, 0.1278591784F, + 0.1281865099F, 0.1285142108F, 0.1288422805F, 0.1291707190F, + 0.1294995259F, 0.1298287009F, 0.1301582437F, 0.1304881542F, + 0.1308184319F, 0.1311490766F, 0.1314800881F, 0.1318114660F, + 0.1321432100F, 0.1324753200F, 0.1328077955F, 0.1331406364F, + 0.1334738422F, 0.1338074129F, 0.1341413479F, 0.1344756472F, + 0.1348103103F, 0.1351453370F, 0.1354807270F, 0.1358164801F, + 0.1361525959F, 0.1364890741F, 0.1368259145F, 0.1371631167F, + 0.1375006805F, 0.1378386056F, 0.1381768917F, 0.1385155384F, + 0.1388545456F, 0.1391939129F, 0.1395336400F, 0.1398737266F, + 0.1402141724F, 0.1405549772F, 0.1408961406F, 0.1412376623F, + 0.1415795421F, 0.1419217797F, 0.1422643746F, 0.1426073268F, + 0.1429506358F, 0.1432943013F, 0.1436383231F, 0.1439827008F, + 0.1443274342F, 0.1446725229F, 0.1450179667F, 0.1453637652F, + 0.1457099181F, 0.1460564252F, 0.1464032861F, 0.1467505006F, + 0.1470980682F, 0.1474459888F, 0.1477942620F, 0.1481428875F, + 0.1484918651F, 0.1488411942F, 0.1491908748F, 0.1495409065F, + 0.1498912889F, 0.1502420218F, 0.1505931048F, 0.1509445376F, + 0.1512963200F, 0.1516484516F, 0.1520009321F, 0.1523537612F, + 0.1527069385F, 0.1530604638F, 0.1534143368F, 0.1537685571F, + 0.1541231244F, 0.1544780384F, 0.1548332987F, 0.1551889052F, + 0.1555448574F, 0.1559011550F, 0.1562577978F, 0.1566147853F, + 0.1569721173F, 0.1573297935F, 0.1576878135F, 0.1580461771F, + 0.1584048838F, 0.1587639334F, 0.1591233255F, 0.1594830599F, + 0.1598431361F, 0.1602035540F, 0.1605643131F, 0.1609254131F, + 0.1612868537F, 0.1616486346F, 0.1620107555F, 0.1623732160F, + 0.1627360158F, 0.1630991545F, 0.1634626319F, 0.1638264476F, + 0.1641906013F, 0.1645550926F, 0.1649199212F, 0.1652850869F, + 0.1656505892F, 0.1660164278F, 0.1663826024F, 0.1667491127F, + 0.1671159583F, 0.1674831388F, 0.1678506541F, 0.1682185036F, + 0.1685866872F, 0.1689552044F, 0.1693240549F, 0.1696932384F, + 0.1700627545F, 0.1704326029F, 0.1708027833F, 0.1711732952F, + 0.1715441385F, 0.1719153127F, 0.1722868175F, 0.1726586526F, + 0.1730308176F, 0.1734033121F, 0.1737761359F, 0.1741492886F, + 0.1745227698F, 0.1748965792F, 0.1752707164F, 0.1756451812F, + 0.1760199731F, 0.1763950918F, 0.1767705370F, 0.1771463083F, + 0.1775224054F, 0.1778988279F, 0.1782755754F, 0.1786526477F, + 0.1790300444F, 0.1794077651F, 0.1797858094F, 0.1801641771F, + 0.1805428677F, 0.1809218810F, 0.1813012165F, 0.1816808739F, + 0.1820608528F, 0.1824411530F, 0.1828217739F, 0.1832027154F, + 0.1835839770F, 0.1839655584F, 0.1843474592F, 0.1847296790F, + 0.1851122175F, 0.1854950744F, 0.1858782492F, 0.1862617417F, + 0.1866455514F, 0.1870296780F, 0.1874141211F, 0.1877988804F, + 0.1881839555F, 0.1885693461F, 0.1889550517F, 0.1893410721F, + 0.1897274068F, 0.1901140555F, 0.1905010178F, 0.1908882933F, + 0.1912758818F, 0.1916637828F, 0.1920519959F, 0.1924405208F, + 0.1928293571F, 0.1932185044F, 0.1936079625F, 0.1939977308F, + 0.1943878091F, 0.1947781969F, 0.1951688939F, 0.1955598998F, + 0.1959512141F, 0.1963428364F, 0.1967347665F, 0.1971270038F, + 0.1975195482F, 0.1979123990F, 0.1983055561F, 0.1986990190F, + 0.1990927873F, 0.1994868607F, 0.1998812388F, 0.2002759212F, + 0.2006709075F, 0.2010661974F, 0.2014617904F, 0.2018576862F, + 0.2022538844F, 0.2026503847F, 0.2030471865F, 0.2034442897F, + 0.2038416937F, 0.2042393982F, 0.2046374028F, 0.2050357071F, + 0.2054343107F, 0.2058332133F, 0.2062324145F, 0.2066319138F, + 0.2070317110F, 0.2074318055F, 0.2078321970F, 0.2082328852F, + 0.2086338696F, 0.2090351498F, 0.2094367255F, 0.2098385962F, + 0.2102407617F, 0.2106432213F, 0.2110459749F, 0.2114490220F, + 0.2118523621F, 0.2122559950F, 0.2126599202F, 0.2130641373F, + 0.2134686459F, 0.2138734456F, 0.2142785361F, 0.2146839168F, + 0.2150895875F, 0.2154955478F, 0.2159017972F, 0.2163083353F, + 0.2167151617F, 0.2171222761F, 0.2175296780F, 0.2179373670F, + 0.2183453428F, 0.2187536049F, 0.2191621529F, 0.2195709864F, + 0.2199801051F, 0.2203895085F, 0.2207991961F, 0.2212091677F, + 0.2216194228F, 0.2220299610F, 0.2224407818F, 0.2228518850F, + 0.2232632699F, 0.2236749364F, 0.2240868839F, 0.2244991121F, + 0.2249116204F, 0.2253244086F, 0.2257374763F, 0.2261508229F, + 0.2265644481F, 0.2269783514F, 0.2273925326F, 0.2278069911F, + 0.2282217265F, 0.2286367384F, 0.2290520265F, 0.2294675902F, + 0.2298834292F, 0.2302995431F, 0.2307159314F, 0.2311325937F, + 0.2315495297F, 0.2319667388F, 0.2323842207F, 0.2328019749F, + 0.2332200011F, 0.2336382988F, 0.2340568675F, 0.2344757070F, + 0.2348948166F, 0.2353141961F, 0.2357338450F, 0.2361537629F, + 0.2365739493F, 0.2369944038F, 0.2374151261F, 0.2378361156F, + 0.2382573720F, 0.2386788948F, 0.2391006836F, 0.2395227380F, + 0.2399450575F, 0.2403676417F, 0.2407904902F, 0.2412136026F, + 0.2416369783F, 0.2420606171F, 0.2424845185F, 0.2429086820F, + 0.2433331072F, 0.2437577936F, 0.2441827409F, 0.2446079486F, + 0.2450334163F, 0.2454591435F, 0.2458851298F, 0.2463113747F, + 0.2467378779F, 0.2471646389F, 0.2475916573F, 0.2480189325F, + 0.2484464643F, 0.2488742521F, 0.2493022955F, 0.2497305940F, + 0.2501591473F, 0.2505879549F, 0.2510170163F, 0.2514463311F, + 0.2518758989F, 0.2523057193F, 0.2527357916F, 0.2531661157F, + 0.2535966909F, 0.2540275169F, 0.2544585931F, 0.2548899193F, + 0.2553214948F, 0.2557533193F, 0.2561853924F, 0.2566177135F, + 0.2570502822F, 0.2574830981F, 0.2579161608F, 0.2583494697F, + 0.2587830245F, 0.2592168246F, 0.2596508697F, 0.2600851593F, + 0.2605196929F, 0.2609544701F, 0.2613894904F, 0.2618247534F, + 0.2622602586F, 0.2626960055F, 0.2631319938F, 0.2635682230F, + 0.2640046925F, 0.2644414021F, 0.2648783511F, 0.2653155391F, + 0.2657529657F, 0.2661906305F, 0.2666285329F, 0.2670666725F, + 0.2675050489F, 0.2679436616F, 0.2683825101F, 0.2688215940F, + 0.2692609127F, 0.2697004660F, 0.2701402532F, 0.2705802739F, + 0.2710205278F, 0.2714610142F, 0.2719017327F, 0.2723426830F, + 0.2727838644F, 0.2732252766F, 0.2736669191F, 0.2741087914F, + 0.2745508930F, 0.2749932235F, 0.2754357824F, 0.2758785693F, + 0.2763215837F, 0.2767648251F, 0.2772082930F, 0.2776519870F, + 0.2780959066F, 0.2785400513F, 0.2789844207F, 0.2794290143F, + 0.2798738316F, 0.2803188722F, 0.2807641355F, 0.2812096211F, + 0.2816553286F, 0.2821012574F, 0.2825474071F, 0.2829937773F, + 0.2834403673F, 0.2838871768F, 0.2843342053F, 0.2847814523F, + 0.2852289174F, 0.2856765999F, 0.2861244996F, 0.2865726159F, + 0.2870209482F, 0.2874694962F, 0.2879182594F, 0.2883672372F, + 0.2888164293F, 0.2892658350F, 0.2897154540F, 0.2901652858F, + 0.2906153298F, 0.2910655856F, 0.2915160527F, 0.2919667306F, + 0.2924176189F, 0.2928687171F, 0.2933200246F, 0.2937715409F, + 0.2942232657F, 0.2946751984F, 0.2951273386F, 0.2955796856F, + 0.2960322391F, 0.2964849986F, 0.2969379636F, 0.2973911335F, + 0.2978445080F, 0.2982980864F, 0.2987518684F, 0.2992058534F, + 0.2996600409F, 0.3001144305F, 0.3005690217F, 0.3010238139F, + 0.3014788067F, 0.3019339995F, 0.3023893920F, 0.3028449835F, + 0.3033007736F, 0.3037567618F, 0.3042129477F, 0.3046693306F, + 0.3051259102F, 0.3055826859F, 0.3060396572F, 0.3064968236F, + 0.3069541847F, 0.3074117399F, 0.3078694887F, 0.3083274307F, + 0.3087855653F, 0.3092438920F, 0.3097024104F, 0.3101611199F, + 0.3106200200F, 0.3110791103F, 0.3115383902F, 0.3119978592F, + 0.3124575169F, 0.3129173627F, 0.3133773961F, 0.3138376166F, + 0.3142980238F, 0.3147586170F, 0.3152193959F, 0.3156803598F, + 0.3161415084F, 0.3166028410F, 0.3170643573F, 0.3175260566F, + 0.3179879384F, 0.3184500023F, 0.3189122478F, 0.3193746743F, + 0.3198372814F, 0.3203000685F, 0.3207630351F, 0.3212261807F, + 0.3216895048F, 0.3221530069F, 0.3226166865F, 0.3230805430F, + 0.3235445760F, 0.3240087849F, 0.3244731693F, 0.3249377285F, + 0.3254024622F, 0.3258673698F, 0.3263324507F, 0.3267977045F, + 0.3272631306F, 0.3277287286F, 0.3281944978F, 0.3286604379F, + 0.3291265482F, 0.3295928284F, 0.3300592777F, 0.3305258958F, + 0.3309926821F, 0.3314596361F, 0.3319267573F, 0.3323940451F, + 0.3328614990F, 0.3333291186F, 0.3337969033F, 0.3342648525F, + 0.3347329658F, 0.3352012427F, 0.3356696825F, 0.3361382849F, + 0.3366070492F, 0.3370759749F, 0.3375450616F, 0.3380143087F, + 0.3384837156F, 0.3389532819F, 0.3394230071F, 0.3398928905F, + 0.3403629317F, 0.3408331302F, 0.3413034854F, 0.3417739967F, + 0.3422446638F, 0.3427154860F, 0.3431864628F, 0.3436575938F, + 0.3441288782F, 0.3446003158F, 0.3450719058F, 0.3455436478F, + 0.3460155412F, 0.3464875856F, 0.3469597804F, 0.3474321250F, + 0.3479046189F, 0.3483772617F, 0.3488500527F, 0.3493229914F, + 0.3497960774F, 0.3502693100F, 0.3507426887F, 0.3512162131F, + 0.3516898825F, 0.3521636965F, 0.3526376545F, 0.3531117559F, + 0.3535860003F, 0.3540603870F, 0.3545349157F, 0.3550095856F, + 0.3554843964F, 0.3559593474F, 0.3564344381F, 0.3569096680F, + 0.3573850366F, 0.3578605432F, 0.3583361875F, 0.3588119687F, + 0.3592878865F, 0.3597639402F, 0.3602401293F, 0.3607164533F, + 0.3611929117F, 0.3616695038F, 0.3621462292F, 0.3626230873F, + 0.3631000776F, 0.3635771995F, 0.3640544525F, 0.3645318360F, + 0.3650093496F, 0.3654869926F, 0.3659647645F, 0.3664426648F, + 0.3669206930F, 0.3673988484F, 0.3678771306F, 0.3683555390F, + 0.3688340731F, 0.3693127322F, 0.3697915160F, 0.3702704237F, + 0.3707494549F, 0.3712286091F, 0.3717078857F, 0.3721872840F, + 0.3726668037F, 0.3731464441F, 0.3736262047F, 0.3741060850F, + 0.3745860843F, 0.3750662023F, 0.3755464382F, 0.3760267915F, + 0.3765072618F, 0.3769878484F, 0.3774685509F, 0.3779493686F, + 0.3784303010F, 0.3789113475F, 0.3793925076F, 0.3798737809F, + 0.3803551666F, 0.3808366642F, 0.3813182733F, 0.3817999932F, + 0.3822818234F, 0.3827637633F, 0.3832458124F, 0.3837279702F, + 0.3842102360F, 0.3846926093F, 0.3851750897F, 0.3856576764F, + 0.3861403690F, 0.3866231670F, 0.3871060696F, 0.3875890765F, + 0.3880721870F, 0.3885554007F, 0.3890387168F, 0.3895221349F, + 0.3900056544F, 0.3904892748F, 0.3909729955F, 0.3914568160F, + 0.3919407356F, 0.3924247539F, 0.3929088702F, 0.3933930841F, + 0.3938773949F, 0.3943618021F, 0.3948463052F, 0.3953309035F, + 0.3958155966F, 0.3963003838F, 0.3967852646F, 0.3972702385F, + 0.3977553048F, 0.3982404631F, 0.3987257127F, 0.3992110531F, + 0.3996964838F, 0.4001820041F, 0.4006676136F, 0.4011533116F, + 0.4016390976F, 0.4021249710F, 0.4026109313F, 0.4030969779F, + 0.4035831102F, 0.4040693277F, 0.4045556299F, 0.4050420160F, + 0.4055284857F, 0.4060150383F, 0.4065016732F, 0.4069883899F, + 0.4074751879F, 0.4079620665F, 0.4084490252F, 0.4089360635F, + 0.4094231807F, 0.4099103763F, 0.4103976498F, 0.4108850005F, + 0.4113724280F, 0.4118599315F, 0.4123475107F, 0.4128351648F, + 0.4133228934F, 0.4138106959F, 0.4142985716F, 0.4147865201F, + 0.4152745408F, 0.4157626330F, 0.4162507963F, 0.4167390301F, + 0.4172273337F, 0.4177157067F, 0.4182041484F, 0.4186926583F, + 0.4191812359F, 0.4196698805F, 0.4201585915F, 0.4206473685F, + 0.4211362108F, 0.4216251179F, 0.4221140892F, 0.4226031241F, + 0.4230922221F, 0.4235813826F, 0.4240706050F, 0.4245598887F, + 0.4250492332F, 0.4255386379F, 0.4260281022F, 0.4265176256F, + 0.4270072075F, 0.4274968473F, 0.4279865445F, 0.4284762984F, + 0.4289661086F, 0.4294559743F, 0.4299458951F, 0.4304358704F, + 0.4309258996F, 0.4314159822F, 0.4319061175F, 0.4323963050F, + 0.4328865441F, 0.4333768342F, 0.4338671749F, 0.4343575654F, + 0.4348480052F, 0.4353384938F, 0.4358290306F, 0.4363196149F, + 0.4368102463F, 0.4373009241F, 0.4377916478F, 0.4382824168F, + 0.4387732305F, 0.4392640884F, 0.4397549899F, 0.4402459343F, + 0.4407369212F, 0.4412279499F, 0.4417190198F, 0.4422101305F, + 0.4427012813F, 0.4431924717F, 0.4436837010F, 0.4441749686F, + 0.4446662742F, 0.4451576169F, 0.4456489963F, 0.4461404118F, + 0.4466318628F, 0.4471233487F, 0.4476148690F, 0.4481064230F, + 0.4485980103F, 0.4490896302F, 0.4495812821F, 0.4500729654F, + 0.4505646797F, 0.4510564243F, 0.4515481986F, 0.4520400021F, + 0.4525318341F, 0.4530236942F, 0.4535155816F, 0.4540074959F, + 0.4544994365F, 0.4549914028F, 0.4554833941F, 0.4559754100F, + 0.4564674499F, 0.4569595131F, 0.4574515991F, 0.4579437074F, + 0.4584358372F, 0.4589279881F, 0.4594201595F, 0.4599123508F, + 0.4604045615F, 0.4608967908F, 0.4613890383F, 0.4618813034F, + 0.4623735855F, 0.4628658841F, 0.4633581984F, 0.4638505281F, + 0.4643428724F, 0.4648352308F, 0.4653276028F, 0.4658199877F, + 0.4663123849F, 0.4668047940F, 0.4672972143F, 0.4677896451F, + 0.4682820861F, 0.4687745365F, 0.4692669958F, 0.4697594634F, + 0.4702519387F, 0.4707444211F, 0.4712369102F, 0.4717294052F, + 0.4722219056F, 0.4727144109F, 0.4732069204F, 0.4736994336F, + 0.4741919498F, 0.4746844686F, 0.4751769893F, 0.4756695113F, + 0.4761620341F, 0.4766545571F, 0.4771470797F, 0.4776396013F, + 0.4781321213F, 0.4786246392F, 0.4791171544F, 0.4796096663F, + 0.4801021744F, 0.4805946779F, 0.4810871765F, 0.4815796694F, + 0.4820721561F, 0.4825646360F, 0.4830571086F, 0.4835495732F, + 0.4840420293F, 0.4845344763F, 0.4850269136F, 0.4855193407F, + 0.4860117569F, 0.4865041617F, 0.4869965545F, 0.4874889347F, + 0.4879813018F, 0.4884736551F, 0.4889659941F, 0.4894583182F, + 0.4899506268F, 0.4904429193F, 0.4909351952F, 0.4914274538F, + 0.4919196947F, 0.4924119172F, 0.4929041207F, 0.4933963046F, + 0.4938884685F, 0.4943806116F, 0.4948727335F, 0.4953648335F, + 0.4958569110F, 0.4963489656F, 0.4968409965F, 0.4973330032F, + 0.4978249852F, 0.4983169419F, 0.4988088726F, 0.4993007768F, + 0.4997926539F, 0.5002845034F, 0.5007763247F, 0.5012681171F, + 0.5017598801F, 0.5022516132F, 0.5027433157F, 0.5032349871F, + 0.5037266268F, 0.5042182341F, 0.5047098086F, 0.5052013497F, + 0.5056928567F, 0.5061843292F, 0.5066757664F, 0.5071671679F, + 0.5076585330F, 0.5081498613F, 0.5086411520F, 0.5091324047F, + 0.5096236187F, 0.5101147934F, 0.5106059284F, 0.5110970230F, + 0.5115880766F, 0.5120790887F, 0.5125700587F, 0.5130609860F, + 0.5135518700F, 0.5140427102F, 0.5145335059F, 0.5150242566F, + 0.5155149618F, 0.5160056208F, 0.5164962331F, 0.5169867980F, + 0.5174773151F, 0.5179677837F, 0.5184582033F, 0.5189485733F, + 0.5194388931F, 0.5199291621F, 0.5204193798F, 0.5209095455F, + 0.5213996588F, 0.5218897190F, 0.5223797256F, 0.5228696779F, + 0.5233595755F, 0.5238494177F, 0.5243392039F, 0.5248289337F, + 0.5253186063F, 0.5258082213F, 0.5262977781F, 0.5267872760F, + 0.5272767146F, 0.5277660932F, 0.5282554112F, 0.5287446682F, + 0.5292338635F, 0.5297229965F, 0.5302120667F, 0.5307010736F, + 0.5311900164F, 0.5316788947F, 0.5321677079F, 0.5326564554F, + 0.5331451366F, 0.5336337511F, 0.5341222981F, 0.5346107771F, + 0.5350991876F, 0.5355875290F, 0.5360758007F, 0.5365640021F, + 0.5370521327F, 0.5375401920F, 0.5380281792F, 0.5385160939F, + 0.5390039355F, 0.5394917034F, 0.5399793971F, 0.5404670159F, + 0.5409545594F, 0.5414420269F, 0.5419294179F, 0.5424167318F, + 0.5429039680F, 0.5433911261F, 0.5438782053F, 0.5443652051F, + 0.5448521250F, 0.5453389644F, 0.5458257228F, 0.5463123995F, + 0.5467989940F, 0.5472855057F, 0.5477719341F, 0.5482582786F, + 0.5487445387F, 0.5492307137F, 0.5497168031F, 0.5502028063F, + 0.5506887228F, 0.5511745520F, 0.5516602934F, 0.5521459463F, + 0.5526315103F, 0.5531169847F, 0.5536023690F, 0.5540876626F, + 0.5545728649F, 0.5550579755F, 0.5555429937F, 0.5560279189F, + 0.5565127507F, 0.5569974884F, 0.5574821315F, 0.5579666794F, + 0.5584511316F, 0.5589354875F, 0.5594197465F, 0.5599039080F, + 0.5603879716F, 0.5608719367F, 0.5613558026F, 0.5618395689F, + 0.5623232350F, 0.5628068002F, 0.5632902642F, 0.5637736262F, + 0.5642568858F, 0.5647400423F, 0.5652230953F, 0.5657060442F, + 0.5661888883F, 0.5666716272F, 0.5671542603F, 0.5676367870F, + 0.5681192069F, 0.5686015192F, 0.5690837235F, 0.5695658192F, + 0.5700478058F, 0.5705296827F, 0.5710114494F, 0.5714931052F, + 0.5719746497F, 0.5724560822F, 0.5729374023F, 0.5734186094F, + 0.5738997029F, 0.5743806823F, 0.5748615470F, 0.5753422965F, + 0.5758229301F, 0.5763034475F, 0.5767838480F, 0.5772641310F, + 0.5777442960F, 0.5782243426F, 0.5787042700F, 0.5791840778F, + 0.5796637654F, 0.5801433322F, 0.5806227778F, 0.5811021016F, + 0.5815813029F, 0.5820603814F, 0.5825393363F, 0.5830181673F, + 0.5834968737F, 0.5839754549F, 0.5844539105F, 0.5849322399F, + 0.5854104425F, 0.5858885179F, 0.5863664653F, 0.5868442844F, + 0.5873219746F, 0.5877995353F, 0.5882769660F, 0.5887542661F, + 0.5892314351F, 0.5897084724F, 0.5901853776F, 0.5906621500F, + 0.5911387892F, 0.5916152945F, 0.5920916655F, 0.5925679016F, + 0.5930440022F, 0.5935199669F, 0.5939957950F, 0.5944714861F, + 0.5949470396F, 0.5954224550F, 0.5958977317F, 0.5963728692F, + 0.5968478669F, 0.5973227244F, 0.5977974411F, 0.5982720163F, + 0.5987464497F, 0.5992207407F, 0.5996948887F, 0.6001688932F, + 0.6006427537F, 0.6011164696F, 0.6015900405F, 0.6020634657F, + 0.6025367447F, 0.6030098770F, 0.6034828621F, 0.6039556995F, + 0.6044283885F, 0.6049009288F, 0.6053733196F, 0.6058455606F, + 0.6063176512F, 0.6067895909F, 0.6072613790F, 0.6077330152F, + 0.6082044989F, 0.6086758295F, 0.6091470065F, 0.6096180294F, + 0.6100888977F, 0.6105596108F, 0.6110301682F, 0.6115005694F, + 0.6119708139F, 0.6124409011F, 0.6129108305F, 0.6133806017F, + 0.6138502139F, 0.6143196669F, 0.6147889599F, 0.6152580926F, + 0.6157270643F, 0.6161958746F, 0.6166645230F, 0.6171330088F, + 0.6176013317F, 0.6180694910F, 0.6185374863F, 0.6190053171F, + 0.6194729827F, 0.6199404828F, 0.6204078167F, 0.6208749841F, + 0.6213419842F, 0.6218088168F, 0.6222754811F, 0.6227419768F, + 0.6232083032F, 0.6236744600F, 0.6241404465F, 0.6246062622F, + 0.6250719067F, 0.6255373795F, 0.6260026799F, 0.6264678076F, + 0.6269327619F, 0.6273975425F, 0.6278621487F, 0.6283265800F, + 0.6287908361F, 0.6292549163F, 0.6297188201F, 0.6301825471F, + 0.6306460966F, 0.6311094683F, 0.6315726617F, 0.6320356761F, + 0.6324985111F, 0.6329611662F, 0.6334236410F, 0.6338859348F, + 0.6343480472F, 0.6348099777F, 0.6352717257F, 0.6357332909F, + 0.6361946726F, 0.6366558704F, 0.6371168837F, 0.6375777122F, + 0.6380383552F, 0.6384988123F, 0.6389590830F, 0.6394191668F, + 0.6398790631F, 0.6403387716F, 0.6407982916F, 0.6412576228F, + 0.6417167645F, 0.6421757163F, 0.6426344778F, 0.6430930483F, + 0.6435514275F, 0.6440096149F, 0.6444676098F, 0.6449254119F, + 0.6453830207F, 0.6458404356F, 0.6462976562F, 0.6467546820F, + 0.6472115125F, 0.6476681472F, 0.6481245856F, 0.6485808273F, + 0.6490368717F, 0.6494927183F, 0.6499483667F, 0.6504038164F, + 0.6508590670F, 0.6513141178F, 0.6517689684F, 0.6522236185F, + 0.6526780673F, 0.6531323146F, 0.6535863598F, 0.6540402024F, + 0.6544938419F, 0.6549472779F, 0.6554005099F, 0.6558535373F, + 0.6563063598F, 0.6567589769F, 0.6572113880F, 0.6576635927F, + 0.6581155906F, 0.6585673810F, 0.6590189637F, 0.6594703380F, + 0.6599215035F, 0.6603724598F, 0.6608232064F, 0.6612737427F, + 0.6617240684F, 0.6621741829F, 0.6626240859F, 0.6630737767F, + 0.6635232550F, 0.6639725202F, 0.6644215720F, 0.6648704098F, + 0.6653190332F, 0.6657674417F, 0.6662156348F, 0.6666636121F, + 0.6671113731F, 0.6675589174F, 0.6680062445F, 0.6684533538F, + 0.6689002450F, 0.6693469177F, 0.6697933712F, 0.6702396052F, + 0.6706856193F, 0.6711314129F, 0.6715769855F, 0.6720223369F, + 0.6724674664F, 0.6729123736F, 0.6733570581F, 0.6738015194F, + 0.6742457570F, 0.6746897706F, 0.6751335596F, 0.6755771236F, + 0.6760204621F, 0.6764635747F, 0.6769064609F, 0.6773491204F, + 0.6777915525F, 0.6782337570F, 0.6786757332F, 0.6791174809F, + 0.6795589995F, 0.6800002886F, 0.6804413477F, 0.6808821765F, + 0.6813227743F, 0.6817631409F, 0.6822032758F, 0.6826431785F, + 0.6830828485F, 0.6835222855F, 0.6839614890F, 0.6844004585F, + 0.6848391936F, 0.6852776939F, 0.6857159589F, 0.6861539883F, + 0.6865917815F, 0.6870293381F, 0.6874666576F, 0.6879037398F, + 0.6883405840F, 0.6887771899F, 0.6892135571F, 0.6896496850F, + 0.6900855733F, 0.6905212216F, 0.6909566294F, 0.6913917963F, + 0.6918267218F, 0.6922614055F, 0.6926958471F, 0.6931300459F, + 0.6935640018F, 0.6939977141F, 0.6944311825F, 0.6948644066F, + 0.6952973859F, 0.6957301200F, 0.6961626085F, 0.6965948510F, + 0.6970268470F, 0.6974585961F, 0.6978900980F, 0.6983213521F, + 0.6987523580F, 0.6991831154F, 0.6996136238F, 0.7000438828F, + 0.7004738921F, 0.7009036510F, 0.7013331594F, 0.7017624166F, + 0.7021914224F, 0.7026201763F, 0.7030486779F, 0.7034769268F, + 0.7039049226F, 0.7043326648F, 0.7047601531F, 0.7051873870F, + 0.7056143662F, 0.7060410902F, 0.7064675586F, 0.7068937711F, + 0.7073197271F, 0.7077454264F, 0.7081708684F, 0.7085960529F, + 0.7090209793F, 0.7094456474F, 0.7098700566F, 0.7102942066F, + 0.7107180970F, 0.7111417274F, 0.7115650974F, 0.7119882066F, + 0.7124110545F, 0.7128336409F, 0.7132559653F, 0.7136780272F, + 0.7140998264F, 0.7145213624F, 0.7149426348F, 0.7153636433F, + 0.7157843874F, 0.7162048668F, 0.7166250810F, 0.7170450296F, + 0.7174647124F, 0.7178841289F, 0.7183032786F, 0.7187221613F, + 0.7191407765F, 0.7195591239F, 0.7199772030F, 0.7203950135F, + 0.7208125550F, 0.7212298271F, 0.7216468294F, 0.7220635616F, + 0.7224800233F, 0.7228962140F, 0.7233121335F, 0.7237277813F, + 0.7241431571F, 0.7245582604F, 0.7249730910F, 0.7253876484F, + 0.7258019322F, 0.7262159422F, 0.7266296778F, 0.7270431388F, + 0.7274563247F, 0.7278692353F, 0.7282818700F, 0.7286942287F, + 0.7291063108F, 0.7295181160F, 0.7299296440F, 0.7303408944F, + 0.7307518669F, 0.7311625609F, 0.7315729763F, 0.7319831126F, + 0.7323929695F, 0.7328025466F, 0.7332118435F, 0.7336208600F, + 0.7340295955F, 0.7344380499F, 0.7348462226F, 0.7352541134F, + 0.7356617220F, 0.7360690478F, 0.7364760907F, 0.7368828502F, + 0.7372893259F, 0.7376955176F, 0.7381014249F, 0.7385070475F, + 0.7389123849F, 0.7393174368F, 0.7397222029F, 0.7401266829F, + 0.7405308763F, 0.7409347829F, 0.7413384023F, 0.7417417341F, + 0.7421447780F, 0.7425475338F, 0.7429500009F, 0.7433521791F, + 0.7437540681F, 0.7441556674F, 0.7445569769F, 0.7449579960F, + 0.7453587245F, 0.7457591621F, 0.7461593084F, 0.7465591631F, + 0.7469587259F, 0.7473579963F, 0.7477569741F, 0.7481556590F, + 0.7485540506F, 0.7489521486F, 0.7493499526F, 0.7497474623F, + 0.7501446775F, 0.7505415977F, 0.7509382227F, 0.7513345521F, + 0.7517305856F, 0.7521263229F, 0.7525217636F, 0.7529169074F, + 0.7533117541F, 0.7537063032F, 0.7541005545F, 0.7544945076F, + 0.7548881623F, 0.7552815182F, 0.7556745749F, 0.7560673323F, + 0.7564597899F, 0.7568519474F, 0.7572438046F, 0.7576353611F, + 0.7580266166F, 0.7584175708F, 0.7588082235F, 0.7591985741F, + 0.7595886226F, 0.7599783685F, 0.7603678116F, 0.7607569515F, + 0.7611457879F, 0.7615343206F, 0.7619225493F, 0.7623104735F, + 0.7626980931F, 0.7630854078F, 0.7634724171F, 0.7638591209F, + 0.7642455188F, 0.7646316106F, 0.7650173959F, 0.7654028744F, + 0.7657880459F, 0.7661729100F, 0.7665574664F, 0.7669417150F, + 0.7673256553F, 0.7677092871F, 0.7680926100F, 0.7684756239F, + 0.7688583284F, 0.7692407232F, 0.7696228080F, 0.7700045826F, + 0.7703860467F, 0.7707671999F, 0.7711480420F, 0.7715285728F, + 0.7719087918F, 0.7722886989F, 0.7726682938F, 0.7730475762F, + 0.7734265458F, 0.7738052023F, 0.7741835454F, 0.7745615750F, + 0.7749392906F, 0.7753166921F, 0.7756937791F, 0.7760705514F, + 0.7764470087F, 0.7768231508F, 0.7771989773F, 0.7775744880F, + 0.7779496827F, 0.7783245610F, 0.7786991227F, 0.7790733676F, + 0.7794472953F, 0.7798209056F, 0.7801941982F, 0.7805671729F, + 0.7809398294F, 0.7813121675F, 0.7816841869F, 0.7820558873F, + 0.7824272684F, 0.7827983301F, 0.7831690720F, 0.7835394940F, + 0.7839095957F, 0.7842793768F, 0.7846488373F, 0.7850179767F, + 0.7853867948F, 0.7857552914F, 0.7861234663F, 0.7864913191F, + 0.7868588497F, 0.7872260578F, 0.7875929431F, 0.7879595055F, + 0.7883257445F, 0.7886916601F, 0.7890572520F, 0.7894225198F, + 0.7897874635F, 0.7901520827F, 0.7905163772F, 0.7908803468F, + 0.7912439912F, 0.7916073102F, 0.7919703035F, 0.7923329710F, + 0.7926953124F, 0.7930573274F, 0.7934190158F, 0.7937803774F, + 0.7941414120F, 0.7945021193F, 0.7948624991F, 0.7952225511F, + 0.7955822752F, 0.7959416711F, 0.7963007387F, 0.7966594775F, + 0.7970178875F, 0.7973759685F, 0.7977337201F, 0.7980911422F, + 0.7984482346F, 0.7988049970F, 0.7991614292F, 0.7995175310F, + 0.7998733022F, 0.8002287426F, 0.8005838519F, 0.8009386299F, + 0.8012930765F, 0.8016471914F, 0.8020009744F, 0.8023544253F, + 0.8027075438F, 0.8030603298F, 0.8034127831F, 0.8037649035F, + 0.8041166906F, 0.8044681445F, 0.8048192647F, 0.8051700512F, + 0.8055205038F, 0.8058706222F, 0.8062204062F, 0.8065698556F, + 0.8069189702F, 0.8072677499F, 0.8076161944F, 0.8079643036F, + 0.8083120772F, 0.8086595151F, 0.8090066170F, 0.8093533827F, + 0.8096998122F, 0.8100459051F, 0.8103916613F, 0.8107370806F, + 0.8110821628F, 0.8114269077F, 0.8117713151F, 0.8121153849F, + 0.8124591169F, 0.8128025108F, 0.8131455666F, 0.8134882839F, + 0.8138306627F, 0.8141727027F, 0.8145144038F, 0.8148557658F, + 0.8151967886F, 0.8155374718F, 0.8158778154F, 0.8162178192F, + 0.8165574830F, 0.8168968067F, 0.8172357900F, 0.8175744328F, + 0.8179127349F, 0.8182506962F, 0.8185883164F, 0.8189255955F, + 0.8192625332F, 0.8195991295F, 0.8199353840F, 0.8202712967F, + 0.8206068673F, 0.8209420958F, 0.8212769820F, 0.8216115256F, + 0.8219457266F, 0.8222795848F, 0.8226131000F, 0.8229462721F, + 0.8232791009F, 0.8236115863F, 0.8239437280F, 0.8242755260F, + 0.8246069801F, 0.8249380901F, 0.8252688559F, 0.8255992774F, + 0.8259293544F, 0.8262590867F, 0.8265884741F, 0.8269175167F, + 0.8272462141F, 0.8275745663F, 0.8279025732F, 0.8282302344F, + 0.8285575501F, 0.8288845199F, 0.8292111437F, 0.8295374215F, + 0.8298633530F, 0.8301889382F, 0.8305141768F, 0.8308390688F, + 0.8311636141F, 0.8314878124F, 0.8318116637F, 0.8321351678F, + 0.8324583246F, 0.8327811340F, 0.8331035957F, 0.8334257098F, + 0.8337474761F, 0.8340688944F, 0.8343899647F, 0.8347106867F, + 0.8350310605F, 0.8353510857F, 0.8356707624F, 0.8359900904F, + 0.8363090696F, 0.8366276999F, 0.8369459811F, 0.8372639131F, + 0.8375814958F, 0.8378987292F, 0.8382156130F, 0.8385321472F, + 0.8388483316F, 0.8391641662F, 0.8394796508F, 0.8397947853F, + 0.8401095697F, 0.8404240037F, 0.8407380873F, 0.8410518204F, + 0.8413652029F, 0.8416782347F, 0.8419909156F, 0.8423032456F, + 0.8426152245F, 0.8429268523F, 0.8432381289F, 0.8435490541F, + 0.8438596279F, 0.8441698502F, 0.8444797208F, 0.8447892396F, + 0.8450984067F, 0.8454072218F, 0.8457156849F, 0.8460237959F, + 0.8463315547F, 0.8466389612F, 0.8469460154F, 0.8472527170F, + 0.8475590661F, 0.8478650625F, 0.8481707063F, 0.8484759971F, + 0.8487809351F, 0.8490855201F, 0.8493897521F, 0.8496936308F, + 0.8499971564F, 0.8503003286F, 0.8506031474F, 0.8509056128F, + 0.8512077246F, 0.8515094828F, 0.8518108872F, 0.8521119379F, + 0.8524126348F, 0.8527129777F, 0.8530129666F, 0.8533126015F, + 0.8536118822F, 0.8539108087F, 0.8542093809F, 0.8545075988F, + 0.8548054623F, 0.8551029712F, 0.8554001257F, 0.8556969255F, + 0.8559933707F, 0.8562894611F, 0.8565851968F, 0.8568805775F, + 0.8571756034F, 0.8574702743F, 0.8577645902F, 0.8580585509F, + 0.8583521566F, 0.8586454070F, 0.8589383021F, 0.8592308420F, + 0.8595230265F, 0.8598148556F, 0.8601063292F, 0.8603974473F, + 0.8606882098F, 0.8609786167F, 0.8612686680F, 0.8615583636F, + 0.8618477034F, 0.8621366874F, 0.8624253156F, 0.8627135878F, + 0.8630015042F, 0.8632890646F, 0.8635762690F, 0.8638631173F, + 0.8641496096F, 0.8644357457F, 0.8647215257F, 0.8650069495F, + 0.8652920171F, 0.8655767283F, 0.8658610833F, 0.8661450820F, + 0.8664287243F, 0.8667120102F, 0.8669949397F, 0.8672775127F, + 0.8675597293F, 0.8678415894F, 0.8681230929F, 0.8684042398F, + 0.8686850302F, 0.8689654640F, 0.8692455412F, 0.8695252617F, + 0.8698046255F, 0.8700836327F, 0.8703622831F, 0.8706405768F, + 0.8709185138F, 0.8711960940F, 0.8714733174F, 0.8717501840F, + 0.8720266939F, 0.8723028469F, 0.8725786430F, 0.8728540824F, + 0.8731291648F, 0.8734038905F, 0.8736782592F, 0.8739522711F, + 0.8742259261F, 0.8744992242F, 0.8747721653F, 0.8750447496F, + 0.8753169770F, 0.8755888475F, 0.8758603611F, 0.8761315177F, + 0.8764023175F, 0.8766727603F, 0.8769428462F, 0.8772125752F, + 0.8774819474F, 0.8777509626F, 0.8780196209F, 0.8782879224F, + 0.8785558669F, 0.8788234546F, 0.8790906854F, 0.8793575594F, + 0.8796240765F, 0.8798902368F, 0.8801560403F, 0.8804214870F, + 0.8806865768F, 0.8809513099F, 0.8812156863F, 0.8814797059F, + 0.8817433687F, 0.8820066749F, 0.8822696243F, 0.8825322171F, + 0.8827944532F, 0.8830563327F, 0.8833178556F, 0.8835790219F, + 0.8838398316F, 0.8841002848F, 0.8843603815F, 0.8846201217F, + 0.8848795054F, 0.8851385327F, 0.8853972036F, 0.8856555182F, + 0.8859134764F, 0.8861710783F, 0.8864283239F, 0.8866852133F, + 0.8869417464F, 0.8871979234F, 0.8874537443F, 0.8877092090F, + 0.8879643177F, 0.8882190704F, 0.8884734671F, 0.8887275078F, + 0.8889811927F, 0.8892345216F, 0.8894874948F, 0.8897401122F, + 0.8899923738F, 0.8902442798F, 0.8904958301F, 0.8907470248F, + 0.8909978640F, 0.8912483477F, 0.8914984759F, 0.8917482487F, + 0.8919976662F, 0.8922467284F, 0.8924954353F, 0.8927437871F, + 0.8929917837F, 0.8932394252F, 0.8934867118F, 0.8937336433F, + 0.8939802199F, 0.8942264417F, 0.8944723087F, 0.8947178210F, + 0.8949629785F, 0.8952077815F, 0.8954522299F, 0.8956963239F, + 0.8959400634F, 0.8961834486F, 0.8964264795F, 0.8966691561F, + 0.8969114786F, 0.8971534470F, 0.8973950614F, 0.8976363219F, + 0.8978772284F, 0.8981177812F, 0.8983579802F, 0.8985978256F, + 0.8988373174F, 0.8990764556F, 0.8993152405F, 0.8995536720F, + 0.8997917502F, 0.9000294751F, 0.9002668470F, 0.9005038658F, + 0.9007405317F, 0.9009768446F, 0.9012128048F, 0.9014484123F, + 0.9016836671F, 0.9019185693F, 0.9021531191F, 0.9023873165F, + 0.9026211616F, 0.9028546546F, 0.9030877954F, 0.9033205841F, + 0.9035530210F, 0.9037851059F, 0.9040168392F, 0.9042482207F, + 0.9044792507F, 0.9047099293F, 0.9049402564F, 0.9051702323F, + 0.9053998569F, 0.9056291305F, 0.9058580531F, 0.9060866248F, + 0.9063148457F, 0.9065427159F, 0.9067702355F, 0.9069974046F, + 0.9072242233F, 0.9074506917F, 0.9076768100F, 0.9079025782F, + 0.9081279964F, 0.9083530647F, 0.9085777833F, 0.9088021523F, + 0.9090261717F, 0.9092498417F, 0.9094731623F, 0.9096961338F, + 0.9099187561F, 0.9101410295F, 0.9103629540F, 0.9105845297F, + 0.9108057568F, 0.9110266354F, 0.9112471656F, 0.9114673475F, + 0.9116871812F, 0.9119066668F, 0.9121258046F, 0.9123445945F, + 0.9125630367F, 0.9127811314F, 0.9129988786F, 0.9132162785F, + 0.9134333312F, 0.9136500368F, 0.9138663954F, 0.9140824073F, + 0.9142980724F, 0.9145133910F, 0.9147283632F, 0.9149429890F, + 0.9151572687F, 0.9153712023F, 0.9155847900F, 0.9157980319F, + 0.9160109282F, 0.9162234790F, 0.9164356844F, 0.9166475445F, + 0.9168590595F, 0.9170702296F, 0.9172810548F, 0.9174915354F, + 0.9177016714F, 0.9179114629F, 0.9181209102F, 0.9183300134F, + 0.9185387726F, 0.9187471879F, 0.9189552595F, 0.9191629876F, + 0.9193703723F, 0.9195774136F, 0.9197841119F, 0.9199904672F, + 0.9201964797F, 0.9204021495F, 0.9206074767F, 0.9208124616F, + 0.9210171043F, 0.9212214049F, 0.9214253636F, 0.9216289805F, + 0.9218322558F, 0.9220351896F, 0.9222377821F, 0.9224400335F, + 0.9226419439F, 0.9228435134F, 0.9230447423F, 0.9232456307F, + 0.9234461787F, 0.9236463865F, 0.9238462543F, 0.9240457822F, + 0.9242449704F, 0.9244438190F, 0.9246423282F, 0.9248404983F, + 0.9250383293F, 0.9252358214F, 0.9254329747F, 0.9256297896F, + 0.9258262660F, 0.9260224042F, 0.9262182044F, 0.9264136667F, + 0.9266087913F, 0.9268035783F, 0.9269980280F, 0.9271921405F, + 0.9273859160F, 0.9275793546F, 0.9277724566F, 0.9279652221F, + 0.9281576513F, 0.9283497443F, 0.9285415014F, 0.9287329227F, + 0.9289240084F, 0.9291147586F, 0.9293051737F, 0.9294952536F, + 0.9296849987F, 0.9298744091F, 0.9300634850F, 0.9302522266F, + 0.9304406340F, 0.9306287074F, 0.9308164471F, 0.9310038532F, + 0.9311909259F, 0.9313776654F, 0.9315640719F, 0.9317501455F, + 0.9319358865F, 0.9321212951F, 0.9323063713F, 0.9324911155F, + 0.9326755279F, 0.9328596085F, 0.9330433577F, 0.9332267756F, + 0.9334098623F, 0.9335926182F, 0.9337750434F, 0.9339571380F, + 0.9341389023F, 0.9343203366F, 0.9345014409F, 0.9346822155F, + 0.9348626606F, 0.9350427763F, 0.9352225630F, 0.9354020207F, + 0.9355811498F, 0.9357599503F, 0.9359384226F, 0.9361165667F, + 0.9362943830F, 0.9364718716F, 0.9366490327F, 0.9368258666F, + 0.9370023733F, 0.9371785533F, 0.9373544066F, 0.9375299335F, + 0.9377051341F, 0.9378800087F, 0.9380545576F, 0.9382287809F, + 0.9384026787F, 0.9385762515F, 0.9387494993F, 0.9389224223F, + 0.9390950209F, 0.9392672951F, 0.9394392453F, 0.9396108716F, + 0.9397821743F, 0.9399531536F, 0.9401238096F, 0.9402941427F, + 0.9404641530F, 0.9406338407F, 0.9408032061F, 0.9409722495F, + 0.9411409709F, 0.9413093707F, 0.9414774491F, 0.9416452062F, + 0.9418126424F, 0.9419797579F, 0.9421465528F, 0.9423130274F, + 0.9424791819F, 0.9426450166F, 0.9428105317F, 0.9429757274F, + 0.9431406039F, 0.9433051616F, 0.9434694005F, 0.9436333209F, + 0.9437969232F, 0.9439602074F, 0.9441231739F, 0.9442858229F, + 0.9444481545F, 0.9446101691F, 0.9447718669F, 0.9449332481F, + 0.9450943129F, 0.9452550617F, 0.9454154945F, 0.9455756118F, + 0.9457354136F, 0.9458949003F, 0.9460540721F, 0.9462129292F, + 0.9463714719F, 0.9465297003F, 0.9466876149F, 0.9468452157F, + 0.9470025031F, 0.9471594772F, 0.9473161384F, 0.9474724869F, + 0.9476285229F, 0.9477842466F, 0.9479396584F, 0.9480947585F, + 0.9482495470F, 0.9484040243F, 0.9485581906F, 0.9487120462F, + 0.9488655913F, 0.9490188262F, 0.9491717511F, 0.9493243662F, + 0.9494766718F, 0.9496286683F, 0.9497803557F, 0.9499317345F, + 0.9500828047F, 0.9502335668F, 0.9503840209F, 0.9505341673F, + 0.9506840062F, 0.9508335380F, 0.9509827629F, 0.9511316810F, + 0.9512802928F, 0.9514285984F, 0.9515765982F, 0.9517242923F, + 0.9518716810F, 0.9520187646F, 0.9521655434F, 0.9523120176F, + 0.9524581875F, 0.9526040534F, 0.9527496154F, 0.9528948739F, + 0.9530398292F, 0.9531844814F, 0.9533288310F, 0.9534728780F, + 0.9536166229F, 0.9537600659F, 0.9539032071F, 0.9540460470F, + 0.9541885858F, 0.9543308237F, 0.9544727611F, 0.9546143981F, + 0.9547557351F, 0.9548967723F, 0.9550375100F, 0.9551779485F, + 0.9553180881F, 0.9554579290F, 0.9555974714F, 0.9557367158F, + 0.9558756623F, 0.9560143112F, 0.9561526628F, 0.9562907174F, + 0.9564284752F, 0.9565659366F, 0.9567031017F, 0.9568399710F, + 0.9569765446F, 0.9571128229F, 0.9572488061F, 0.9573844944F, + 0.9575198883F, 0.9576549879F, 0.9577897936F, 0.9579243056F, + 0.9580585242F, 0.9581924497F, 0.9583260824F, 0.9584594226F, + 0.9585924705F, 0.9587252264F, 0.9588576906F, 0.9589898634F, + 0.9591217452F, 0.9592533360F, 0.9593846364F, 0.9595156465F, + 0.9596463666F, 0.9597767971F, 0.9599069382F, 0.9600367901F, + 0.9601663533F, 0.9602956279F, 0.9604246143F, 0.9605533128F, + 0.9606817236F, 0.9608098471F, 0.9609376835F, 0.9610652332F, + 0.9611924963F, 0.9613194733F, 0.9614461644F, 0.9615725699F, + 0.9616986901F, 0.9618245253F, 0.9619500757F, 0.9620753418F, + 0.9622003238F, 0.9623250219F, 0.9624494365F, 0.9625735679F, + 0.9626974163F, 0.9628209821F, 0.9629442656F, 0.9630672671F, + 0.9631899868F, 0.9633124251F, 0.9634345822F, 0.9635564585F, + 0.9636780543F, 0.9637993699F, 0.9639204056F, 0.9640411616F, + 0.9641616383F, 0.9642818359F, 0.9644017549F, 0.9645213955F, + 0.9646407579F, 0.9647598426F, 0.9648786497F, 0.9649971797F, + 0.9651154328F, 0.9652334092F, 0.9653511095F, 0.9654685337F, + 0.9655856823F, 0.9657025556F, 0.9658191538F, 0.9659354773F, + 0.9660515263F, 0.9661673013F, 0.9662828024F, 0.9663980300F, + 0.9665129845F, 0.9666276660F, 0.9667420750F, 0.9668562118F, + 0.9669700766F, 0.9670836698F, 0.9671969917F, 0.9673100425F, + 0.9674228227F, 0.9675353325F, 0.9676475722F, 0.9677595422F, + 0.9678712428F, 0.9679826742F, 0.9680938368F, 0.9682047309F, + 0.9683153569F, 0.9684257150F, 0.9685358056F, 0.9686456289F, + 0.9687551853F, 0.9688644752F, 0.9689734987F, 0.9690822564F, + 0.9691907483F, 0.9692989750F, 0.9694069367F, 0.9695146337F, + 0.9696220663F, 0.9697292349F, 0.9698361398F, 0.9699427813F, + 0.9700491597F, 0.9701552754F, 0.9702611286F, 0.9703667197F, + 0.9704720490F, 0.9705771169F, 0.9706819236F, 0.9707864695F, + 0.9708907549F, 0.9709947802F, 0.9710985456F, 0.9712020514F, + 0.9713052981F, 0.9714082859F, 0.9715110151F, 0.9716134862F, + 0.9717156993F, 0.9718176549F, 0.9719193532F, 0.9720207946F, + 0.9721219794F, 0.9722229080F, 0.9723235806F, 0.9724239976F, + 0.9725241593F, 0.9726240661F, 0.9727237183F, 0.9728231161F, + 0.9729222601F, 0.9730211503F, 0.9731197873F, 0.9732181713F, + 0.9733163027F, 0.9734141817F, 0.9735118088F, 0.9736091842F, + 0.9737063083F, 0.9738031814F, 0.9738998039F, 0.9739961760F, + 0.9740922981F, 0.9741881706F, 0.9742837938F, 0.9743791680F, + 0.9744742935F, 0.9745691707F, 0.9746637999F, 0.9747581814F, + 0.9748523157F, 0.9749462029F, 0.9750398435F, 0.9751332378F, + 0.9752263861F, 0.9753192887F, 0.9754119461F, 0.9755043585F, + 0.9755965262F, 0.9756884496F, 0.9757801291F, 0.9758715650F, + 0.9759627575F, 0.9760537071F, 0.9761444141F, 0.9762348789F, + 0.9763251016F, 0.9764150828F, 0.9765048228F, 0.9765943218F, + 0.9766835802F, 0.9767725984F, 0.9768613767F, 0.9769499154F, + 0.9770382149F, 0.9771262755F, 0.9772140976F, 0.9773016815F, + 0.9773890275F, 0.9774761360F, 0.9775630073F, 0.9776496418F, + 0.9777360398F, 0.9778222016F, 0.9779081277F, 0.9779938182F, + 0.9780792736F, 0.9781644943F, 0.9782494805F, 0.9783342326F, + 0.9784187509F, 0.9785030359F, 0.9785870877F, 0.9786709069F, + 0.9787544936F, 0.9788378484F, 0.9789209714F, 0.9790038631F, + 0.9790865238F, 0.9791689538F, 0.9792511535F, 0.9793331232F, + 0.9794148633F, 0.9794963742F, 0.9795776561F, 0.9796587094F, + 0.9797395345F, 0.9798201316F, 0.9799005013F, 0.9799806437F, + 0.9800605593F, 0.9801402483F, 0.9802197112F, 0.9802989483F, + 0.9803779600F, 0.9804567465F, 0.9805353082F, 0.9806136455F, + 0.9806917587F, 0.9807696482F, 0.9808473143F, 0.9809247574F, + 0.9810019778F, 0.9810789759F, 0.9811557519F, 0.9812323064F, + 0.9813086395F, 0.9813847517F, 0.9814606433F, 0.9815363147F, + 0.9816117662F, 0.9816869981F, 0.9817620108F, 0.9818368047F, + 0.9819113801F, 0.9819857374F, 0.9820598769F, 0.9821337989F, + 0.9822075038F, 0.9822809920F, 0.9823542638F, 0.9824273195F, + 0.9825001596F, 0.9825727843F, 0.9826451940F, 0.9827173891F, + 0.9827893700F, 0.9828611368F, 0.9829326901F, 0.9830040302F, + 0.9830751574F, 0.9831460720F, 0.9832167745F, 0.9832872652F, + 0.9833575444F, 0.9834276124F, 0.9834974697F, 0.9835671166F, + 0.9836365535F, 0.9837057806F, 0.9837747983F, 0.9838436071F, + 0.9839122072F, 0.9839805990F, 0.9840487829F, 0.9841167591F, + 0.9841845282F, 0.9842520903F, 0.9843194459F, 0.9843865953F, + 0.9844535389F, 0.9845202771F, 0.9845868101F, 0.9846531383F, + 0.9847192622F, 0.9847851820F, 0.9848508980F, 0.9849164108F, + 0.9849817205F, 0.9850468276F, 0.9851117324F, 0.9851764352F, + 0.9852409365F, 0.9853052366F, 0.9853693358F, 0.9854332344F, + 0.9854969330F, 0.9855604317F, 0.9856237309F, 0.9856868310F, + 0.9857497325F, 0.9858124355F, 0.9858749404F, 0.9859372477F, + 0.9859993577F, 0.9860612707F, 0.9861229871F, 0.9861845072F, + 0.9862458315F, 0.9863069601F, 0.9863678936F, 0.9864286322F, + 0.9864891764F, 0.9865495264F, 0.9866096826F, 0.9866696454F, + 0.9867294152F, 0.9867889922F, 0.9868483769F, 0.9869075695F, + 0.9869665706F, 0.9870253803F, 0.9870839991F, 0.9871424273F, + 0.9872006653F, 0.9872587135F, 0.9873165721F, 0.9873742415F, + 0.9874317222F, 0.9874890144F, 0.9875461185F, 0.9876030348F, + 0.9876597638F, 0.9877163057F, 0.9877726610F, 0.9878288300F, + 0.9878848130F, 0.9879406104F, 0.9879962225F, 0.9880516497F, + 0.9881068924F, 0.9881619509F, 0.9882168256F, 0.9882715168F, + 0.9883260249F, 0.9883803502F, 0.9884344931F, 0.9884884539F, + 0.9885422331F, 0.9885958309F, 0.9886492477F, 0.9887024838F, + 0.9887555397F, 0.9888084157F, 0.9888611120F, 0.9889136292F, + 0.9889659675F, 0.9890181273F, 0.9890701089F, 0.9891219128F, + 0.9891735392F, 0.9892249885F, 0.9892762610F, 0.9893273572F, + 0.9893782774F, 0.9894290219F, 0.9894795911F, 0.9895299853F, + 0.9895802049F, 0.9896302502F, 0.9896801217F, 0.9897298196F, + 0.9897793443F, 0.9898286961F, 0.9898778755F, 0.9899268828F, + 0.9899757183F, 0.9900243823F, 0.9900728753F, 0.9901211976F, + 0.9901693495F, 0.9902173314F, 0.9902651436F, 0.9903127865F, + 0.9903602605F, 0.9904075659F, 0.9904547031F, 0.9905016723F, + 0.9905484740F, 0.9905951086F, 0.9906415763F, 0.9906878775F, + 0.9907340126F, 0.9907799819F, 0.9908257858F, 0.9908714247F, + 0.9909168988F, 0.9909622086F, 0.9910073543F, 0.9910523364F, + 0.9910971552F, 0.9911418110F, 0.9911863042F, 0.9912306351F, + 0.9912748042F, 0.9913188117F, 0.9913626580F, 0.9914063435F, + 0.9914498684F, 0.9914932333F, 0.9915364383F, 0.9915794839F, + 0.9916223703F, 0.9916650981F, 0.9917076674F, 0.9917500787F, + 0.9917923323F, 0.9918344286F, 0.9918763679F, 0.9919181505F, + 0.9919597769F, 0.9920012473F, 0.9920425621F, 0.9920837217F, + 0.9921247263F, 0.9921655765F, 0.9922062724F, 0.9922468145F, + 0.9922872030F, 0.9923274385F, 0.9923675211F, 0.9924074513F, + 0.9924472294F, 0.9924868557F, 0.9925263306F, 0.9925656544F, + 0.9926048275F, 0.9926438503F, 0.9926827230F, 0.9927214461F, + 0.9927600199F, 0.9927984446F, 0.9928367208F, 0.9928748486F, + 0.9929128285F, 0.9929506608F, 0.9929883459F, 0.9930258841F, + 0.9930632757F, 0.9931005211F, 0.9931376207F, 0.9931745747F, + 0.9932113836F, 0.9932480476F, 0.9932845671F, 0.9933209425F, + 0.9933571742F, 0.9933932623F, 0.9934292074F, 0.9934650097F, + 0.9935006696F, 0.9935361874F, 0.9935715635F, 0.9936067982F, + 0.9936418919F, 0.9936768448F, 0.9937116574F, 0.9937463300F, + 0.9937808629F, 0.9938152565F, 0.9938495111F, 0.9938836271F, + 0.9939176047F, 0.9939514444F, 0.9939851465F, 0.9940187112F, + 0.9940521391F, 0.9940854303F, 0.9941185853F, 0.9941516044F, + 0.9941844879F, 0.9942172361F, 0.9942498495F, 0.9942823283F, + 0.9943146729F, 0.9943468836F, 0.9943789608F, 0.9944109047F, + 0.9944427158F, 0.9944743944F, 0.9945059408F, 0.9945373553F, + 0.9945686384F, 0.9945997902F, 0.9946308112F, 0.9946617017F, + 0.9946924621F, 0.9947230926F, 0.9947535937F, 0.9947839656F, + 0.9948142086F, 0.9948443232F, 0.9948743097F, 0.9949041683F, + 0.9949338995F, 0.9949635035F, 0.9949929807F, 0.9950223315F, + 0.9950515561F, 0.9950806549F, 0.9951096282F, 0.9951384764F, + 0.9951671998F, 0.9951957987F, 0.9952242735F, 0.9952526245F, + 0.9952808520F, 0.9953089564F, 0.9953369380F, 0.9953647971F, + 0.9953925340F, 0.9954201491F, 0.9954476428F, 0.9954750153F, + 0.9955022670F, 0.9955293981F, 0.9955564092F, 0.9955833003F, + 0.9956100720F, 0.9956367245F, 0.9956632582F, 0.9956896733F, + 0.9957159703F, 0.9957421494F, 0.9957682110F, 0.9957941553F, + 0.9958199828F, 0.9958456937F, 0.9958712884F, 0.9958967672F, + 0.9959221305F, 0.9959473784F, 0.9959725115F, 0.9959975300F, + 0.9960224342F, 0.9960472244F, 0.9960719011F, 0.9960964644F, + 0.9961209148F, 0.9961452525F, 0.9961694779F, 0.9961935913F, + 0.9962175930F, 0.9962414834F, 0.9962652627F, 0.9962889313F, + 0.9963124895F, 0.9963359377F, 0.9963592761F, 0.9963825051F, + 0.9964056250F, 0.9964286361F, 0.9964515387F, 0.9964743332F, + 0.9964970198F, 0.9965195990F, 0.9965420709F, 0.9965644360F, + 0.9965866946F, 0.9966088469F, 0.9966308932F, 0.9966528340F, + 0.9966746695F, 0.9966964001F, 0.9967180260F, 0.9967395475F, + 0.9967609651F, 0.9967822789F, 0.9968034894F, 0.9968245968F, + 0.9968456014F, 0.9968665036F, 0.9968873037F, 0.9969080019F, + 0.9969285987F, 0.9969490942F, 0.9969694889F, 0.9969897830F, + 0.9970099769F, 0.9970300708F, 0.9970500651F, 0.9970699601F, + 0.9970897561F, 0.9971094533F, 0.9971290522F, 0.9971485531F, + 0.9971679561F, 0.9971872617F, 0.9972064702F, 0.9972255818F, + 0.9972445968F, 0.9972635157F, 0.9972823386F, 0.9973010659F, + 0.9973196980F, 0.9973382350F, 0.9973566773F, 0.9973750253F, + 0.9973932791F, 0.9974114392F, 0.9974295059F, 0.9974474793F, + 0.9974653599F, 0.9974831480F, 0.9975008438F, 0.9975184476F, + 0.9975359598F, 0.9975533806F, 0.9975707104F, 0.9975879495F, + 0.9976050981F, 0.9976221566F, 0.9976391252F, 0.9976560043F, + 0.9976727941F, 0.9976894950F, 0.9977061073F, 0.9977226312F, + 0.9977390671F, 0.9977554152F, 0.9977716759F, 0.9977878495F, + 0.9978039361F, 0.9978199363F, 0.9978358501F, 0.9978516780F, + 0.9978674202F, 0.9978830771F, 0.9978986488F, 0.9979141358F, + 0.9979295383F, 0.9979448566F, 0.9979600909F, 0.9979752417F, + 0.9979903091F, 0.9980052936F, 0.9980201952F, 0.9980350145F, + 0.9980497515F, 0.9980644067F, 0.9980789804F, 0.9980934727F, + 0.9981078841F, 0.9981222147F, 0.9981364649F, 0.9981506350F, + 0.9981647253F, 0.9981787360F, 0.9981926674F, 0.9982065199F, + 0.9982202936F, 0.9982339890F, 0.9982476062F, 0.9982611456F, + 0.9982746074F, 0.9982879920F, 0.9983012996F, 0.9983145304F, + 0.9983276849F, 0.9983407632F, 0.9983537657F, 0.9983666926F, + 0.9983795442F, 0.9983923208F, 0.9984050226F, 0.9984176501F, + 0.9984302033F, 0.9984426827F, 0.9984550884F, 0.9984674208F, + 0.9984796802F, 0.9984918667F, 0.9985039808F, 0.9985160227F, + 0.9985279926F, 0.9985398909F, 0.9985517177F, 0.9985634734F, + 0.9985751583F, 0.9985867727F, 0.9985983167F, 0.9986097907F, + 0.9986211949F, 0.9986325297F, 0.9986437953F, 0.9986549919F, + 0.9986661199F, 0.9986771795F, 0.9986881710F, 0.9986990946F, + 0.9987099507F, 0.9987207394F, 0.9987314611F, 0.9987421161F, + 0.9987527045F, 0.9987632267F, 0.9987736829F, 0.9987840734F, + 0.9987943985F, 0.9988046584F, 0.9988148534F, 0.9988249838F, + 0.9988350498F, 0.9988450516F, 0.9988549897F, 0.9988648641F, + 0.9988746753F, 0.9988844233F, 0.9988941086F, 0.9989037313F, + 0.9989132918F, 0.9989227902F, 0.9989322269F, 0.9989416021F, + 0.9989509160F, 0.9989601690F, 0.9989693613F, 0.9989784931F, + 0.9989875647F, 0.9989965763F, 0.9990055283F, 0.9990144208F, + 0.9990232541F, 0.9990320286F, 0.9990407443F, 0.9990494016F, + 0.9990580008F, 0.9990665421F, 0.9990750257F, 0.9990834519F, + 0.9990918209F, 0.9991001331F, 0.9991083886F, 0.9991165877F, + 0.9991247307F, 0.9991328177F, 0.9991408491F, 0.9991488251F, + 0.9991567460F, 0.9991646119F, 0.9991724232F, 0.9991801801F, + 0.9991878828F, 0.9991955316F, 0.9992031267F, 0.9992106684F, + 0.9992181569F, 0.9992255925F, 0.9992329753F, 0.9992403057F, + 0.9992475839F, 0.9992548101F, 0.9992619846F, 0.9992691076F, + 0.9992761793F, 0.9992832001F, 0.9992901701F, 0.9992970895F, + 0.9993039587F, 0.9993107777F, 0.9993175470F, 0.9993242667F, + 0.9993309371F, 0.9993375583F, 0.9993441307F, 0.9993506545F, + 0.9993571298F, 0.9993635570F, 0.9993699362F, 0.9993762678F, + 0.9993825519F, 0.9993887887F, 0.9993949785F, 0.9994011216F, + 0.9994072181F, 0.9994132683F, 0.9994192725F, 0.9994252307F, + 0.9994311434F, 0.9994370107F, 0.9994428327F, 0.9994486099F, + 0.9994543423F, 0.9994600303F, 0.9994656739F, 0.9994712736F, + 0.9994768294F, 0.9994823417F, 0.9994878105F, 0.9994932363F, + 0.9994986191F, 0.9995039592F, 0.9995092568F, 0.9995145122F, + 0.9995197256F, 0.9995248971F, 0.9995300270F, 0.9995351156F, + 0.9995401630F, 0.9995451695F, 0.9995501352F, 0.9995550604F, + 0.9995599454F, 0.9995647903F, 0.9995695953F, 0.9995743607F, + 0.9995790866F, 0.9995837734F, 0.9995884211F, 0.9995930300F, + 0.9995976004F, 0.9996021324F, 0.9996066263F, 0.9996110822F, + 0.9996155004F, 0.9996198810F, 0.9996242244F, 0.9996285306F, + 0.9996327999F, 0.9996370326F, 0.9996412287F, 0.9996453886F, + 0.9996495125F, 0.9996536004F, 0.9996576527F, 0.9996616696F, + 0.9996656512F, 0.9996695977F, 0.9996735094F, 0.9996773865F, + 0.9996812291F, 0.9996850374F, 0.9996888118F, 0.9996925523F, + 0.9996962591F, 0.9996999325F, 0.9997035727F, 0.9997071798F, + 0.9997107541F, 0.9997142957F, 0.9997178049F, 0.9997212818F, + 0.9997247266F, 0.9997281396F, 0.9997315209F, 0.9997348708F, + 0.9997381893F, 0.9997414767F, 0.9997447333F, 0.9997479591F, + 0.9997511544F, 0.9997543194F, 0.9997574542F, 0.9997605591F, + 0.9997636342F, 0.9997666797F, 0.9997696958F, 0.9997726828F, + 0.9997756407F, 0.9997785698F, 0.9997814703F, 0.9997843423F, + 0.9997871860F, 0.9997900016F, 0.9997927894F, 0.9997955494F, + 0.9997982818F, 0.9998009869F, 0.9998036648F, 0.9998063157F, + 0.9998089398F, 0.9998115373F, 0.9998141082F, 0.9998166529F, + 0.9998191715F, 0.9998216642F, 0.9998241311F, 0.9998265724F, + 0.9998289884F, 0.9998313790F, 0.9998337447F, 0.9998360854F, + 0.9998384015F, 0.9998406930F, 0.9998429602F, 0.9998452031F, + 0.9998474221F, 0.9998496171F, 0.9998517885F, 0.9998539364F, + 0.9998560610F, 0.9998581624F, 0.9998602407F, 0.9998622962F, + 0.9998643291F, 0.9998663394F, 0.9998683274F, 0.9998702932F, + 0.9998722370F, 0.9998741589F, 0.9998760591F, 0.9998779378F, + 0.9998797952F, 0.9998816313F, 0.9998834464F, 0.9998852406F, + 0.9998870141F, 0.9998887670F, 0.9998904995F, 0.9998922117F, + 0.9998939039F, 0.9998955761F, 0.9998972285F, 0.9998988613F, + 0.9999004746F, 0.9999020686F, 0.9999036434F, 0.9999051992F, + 0.9999067362F, 0.9999082544F, 0.9999097541F, 0.9999112354F, + 0.9999126984F, 0.9999141433F, 0.9999155703F, 0.9999169794F, + 0.9999183709F, 0.9999197449F, 0.9999211014F, 0.9999224408F, + 0.9999237631F, 0.9999250684F, 0.9999263570F, 0.9999276289F, + 0.9999288843F, 0.9999301233F, 0.9999313461F, 0.9999325529F, + 0.9999337437F, 0.9999349187F, 0.9999360780F, 0.9999372218F, + 0.9999383503F, 0.9999394635F, 0.9999405616F, 0.9999416447F, + 0.9999427129F, 0.9999437665F, 0.9999448055F, 0.9999458301F, + 0.9999468404F, 0.9999478365F, 0.9999488185F, 0.9999497867F, + 0.9999507411F, 0.9999516819F, 0.9999526091F, 0.9999535230F, + 0.9999544236F, 0.9999553111F, 0.9999561856F, 0.9999570472F, + 0.9999578960F, 0.9999587323F, 0.9999595560F, 0.9999603674F, + 0.9999611666F, 0.9999619536F, 0.9999627286F, 0.9999634917F, + 0.9999642431F, 0.9999649828F, 0.9999657110F, 0.9999664278F, + 0.9999671334F, 0.9999678278F, 0.9999685111F, 0.9999691835F, + 0.9999698451F, 0.9999704960F, 0.9999711364F, 0.9999717662F, + 0.9999723858F, 0.9999729950F, 0.9999735942F, 0.9999741834F, + 0.9999747626F, 0.9999753321F, 0.9999758919F, 0.9999764421F, + 0.9999769828F, 0.9999775143F, 0.9999780364F, 0.9999785495F, + 0.9999790535F, 0.9999795485F, 0.9999800348F, 0.9999805124F, + 0.9999809813F, 0.9999814417F, 0.9999818938F, 0.9999823375F, + 0.9999827731F, 0.9999832005F, 0.9999836200F, 0.9999840316F, + 0.9999844353F, 0.9999848314F, 0.9999852199F, 0.9999856008F, + 0.9999859744F, 0.9999863407F, 0.9999866997F, 0.9999870516F, + 0.9999873965F, 0.9999877345F, 0.9999880656F, 0.9999883900F, + 0.9999887078F, 0.9999890190F, 0.9999893237F, 0.9999896220F, + 0.9999899140F, 0.9999901999F, 0.9999904796F, 0.9999907533F, + 0.9999910211F, 0.9999912830F, 0.9999915391F, 0.9999917896F, + 0.9999920345F, 0.9999922738F, 0.9999925077F, 0.9999927363F, + 0.9999929596F, 0.9999931777F, 0.9999933907F, 0.9999935987F, + 0.9999938018F, 0.9999940000F, 0.9999941934F, 0.9999943820F, + 0.9999945661F, 0.9999947456F, 0.9999949206F, 0.9999950912F, + 0.9999952575F, 0.9999954195F, 0.9999955773F, 0.9999957311F, + 0.9999958807F, 0.9999960265F, 0.9999961683F, 0.9999963063F, + 0.9999964405F, 0.9999965710F, 0.9999966979F, 0.9999968213F, + 0.9999969412F, 0.9999970576F, 0.9999971707F, 0.9999972805F, + 0.9999973871F, 0.9999974905F, 0.9999975909F, 0.9999976881F, + 0.9999977824F, 0.9999978738F, 0.9999979624F, 0.9999980481F, + 0.9999981311F, 0.9999982115F, 0.9999982892F, 0.9999983644F, + 0.9999984370F, 0.9999985072F, 0.9999985750F, 0.9999986405F, + 0.9999987037F, 0.9999987647F, 0.9999988235F, 0.9999988802F, + 0.9999989348F, 0.9999989873F, 0.9999990379F, 0.9999990866F, + 0.9999991334F, 0.9999991784F, 0.9999992217F, 0.9999992632F, + 0.9999993030F, 0.9999993411F, 0.9999993777F, 0.9999994128F, + 0.9999994463F, 0.9999994784F, 0.9999995091F, 0.9999995384F, + 0.9999995663F, 0.9999995930F, 0.9999996184F, 0.9999996426F, + 0.9999996657F, 0.9999996876F, 0.9999997084F, 0.9999997282F, + 0.9999997469F, 0.9999997647F, 0.9999997815F, 0.9999997973F, + 0.9999998123F, 0.9999998265F, 0.9999998398F, 0.9999998524F, + 0.9999998642F, 0.9999998753F, 0.9999998857F, 0.9999998954F, + 0.9999999045F, 0.9999999130F, 0.9999999209F, 0.9999999282F, + 0.9999999351F, 0.9999999414F, 0.9999999472F, 0.9999999526F, + 0.9999999576F, 0.9999999622F, 0.9999999664F, 0.9999999702F, + 0.9999999737F, 0.9999999769F, 0.9999999798F, 0.9999999824F, + 0.9999999847F, 0.9999999868F, 0.9999999887F, 0.9999999904F, + 0.9999999919F, 0.9999999932F, 0.9999999943F, 0.9999999953F, + 0.9999999961F, 0.9999999969F, 0.9999999975F, 0.9999999980F, + 0.9999999985F, 0.9999999988F, 0.9999999991F, 0.9999999993F, + 0.9999999995F, 0.9999999997F, 0.9999999998F, 0.9999999999F, + 0.9999999999F, 1.0000000000F, 1.0000000000F, 1.0000000000F, + 1.0000000000F, 1.0000000000F, 1.0000000000F, 1.0000000000F, +}; + +static float *vwin[8] = { + vwin64, + vwin128, + vwin256, + vwin512, + vwin1024, + vwin2048, + vwin4096, + vwin8192, +}; + +float *_vorbis_window_get(int n){ + return vwin[n]; +} + +void _vorbis_apply_window(float *d,int *winno,long *blocksizes, + int lW,int W,int nW){ + lW=(W?lW:0); + nW=(W?nW:0); + + { + float *windowLW=vwin[winno[lW]]; + float *windowNW=vwin[winno[nW]]; + + long n=blocksizes[W]; + long ln=blocksizes[lW]; + long rn=blocksizes[nW]; + + long leftbegin=n/4-ln/4; + long leftend=leftbegin+ln/2; + + long rightbegin=n/2+n/4-rn/4; + long rightend=rightbegin+rn/2; + + int i,p; + + for(i=0;i +#include +#include +#include + +#include + +static int quiet = 0; +static int bits = 16; +#if __APPLE__ && __BIG_ENDIAN__ +static int endian = 1; +#else +static int endian = 0; +#endif +static int raw = 0; +static int sign = 1; + +typedef struct oggio oggio; + +struct oggio +{ + OggVorbis_File vf; + ov_callbacks cb; +}; + +/* +void _analysis_output_always(char *base,int i,float *v,int n,int bark,int dB,ogg_int64_t off) +{ +}; +*/ + +void *Decode_Ogg(void *stream,void *oread,void *oseek,void *oclose,void *otell,int *samples,int *channels,int *freq) +{ + oggio *ogg; + int res; + ogg_int64_t samples64; + + *samples=-1; + + ogg=(oggio*)malloc(sizeof(oggio)); + ogg->cb.read_func=oread; + ogg->cb.seek_func=oseek; + ogg->cb.close_func=oclose; + ogg->cb.tell_func=otell; + + res=ov_open_callbacks(stream,&ogg->vf,0,0,ogg->cb); + if (res<0) {free(ogg);return 0;} + + samples64=ov_pcm_total(&ogg->vf,0); + *samples=(int)samples64; + + *channels=ov_info(&ogg->vf,-1)->channels; + *freq=ov_info(&ogg->vf,-1)->rate; + + return ogg; +} + +int Read_Ogg(oggio *ogg,char *buf,int bytes) // null buffer to close +{ + int res,bs; + + if (buf==0) return ov_clear(&ogg->vf); + + while (bytes>0) + { + res=ov_read(&ogg->vf,buf,bytes,endian,bits/8,sign,&bs); + if (res<0) + { + if (bs) return -1; // Only one logical bitstream currently supported + return -2; // Warning: hole in data + } + buf+=res; + bytes-=res; + } + return 0; +} diff --git a/mod/pub.mod/oggvorbis.mod/oggvorbis.bmx b/mod/pub.mod/oggvorbis.mod/oggvorbis.bmx new file mode 100644 index 0000000..c833aa1 --- /dev/null +++ b/mod/pub.mod/oggvorbis.mod/oggvorbis.bmx @@ -0,0 +1,60 @@ + +Strict + +Module Pub.OggVorbis + +ModuleInfo "Version: 1.07" +ModuleInfo "License: OggVorbis License" +ModuleInfo "Copyright: Xiph.Org Foundation http://www.xiph.org/" +ModuleInfo "Credit: Adapted for BlitzMax by Simon Armstrong" +ModuleInfo "Modserver: BRL" + +ModuleInfo "History: 1.07 Release" +ModuleInfo "History: Hacked around Lion llvm bug in libvorbis-1.1.2/lib/os.h" +ModuleInfo "History: 1.06 Release" +ModuleInfo "History: Moved Encode_OGG stub to axe.oggsaver module" +ModuleInfo "History: 1.05 Release" +ModuleInfo "History: Added Encode_OGG stub" +ModuleInfo "History: Updated to libogg-1.1.3 and libvorbis-1.1.2" + +Import "libogg-1.1.3/include/*.h" +Import "libogg-1.1.3/src/bitwise.c" +Import "libogg-1.1.3/src/framing.c" + +Import "libvorbis-1.1.2/include/*.h" +Import "libvorbis-1.1.2/lib/bitrate.c" +Import "libvorbis-1.1.2/lib/block.c" +Import "libvorbis-1.1.2/lib/codebook.c" +Import "libvorbis-1.1.2/lib/envelope.c" +Import "libvorbis-1.1.2/lib/floor0.c" +Import "libvorbis-1.1.2/lib/floor1.c" +Import "libvorbis-1.1.2/lib/info.c" +Import "libvorbis-1.1.2/lib/lpc.c" +Import "libvorbis-1.1.2/lib/lsp.c" +Import "libvorbis-1.1.2/lib/mapping0.c" +Import "libvorbis-1.1.2/lib/mdct.c" +Import "libvorbis-1.1.2/lib/psy.c" +Import "libvorbis-1.1.2/lib/registry.c" +Import "libvorbis-1.1.2/lib/res0.c" +Import "libvorbis-1.1.2/lib/sharedbook.c" +Import "libvorbis-1.1.2/lib/smallft.c" +Import "libvorbis-1.1.2/lib/synthesis.c" +Import "libvorbis-1.1.2/lib/vorbisfile.c" +Import "libvorbis-1.1.2/lib/window.c" +Import "libvorbis-1.1.2/lib/analysis.c" + +Import "oggdecoder.c" + +Extern + +Function Decode_Ogg:Byte Ptr(.. + datasource:Object,.. + reado(buf@Ptr,size,nmemb,src:Object),.. + seeko(src:Object,off0,off1,whence),.. + closeo(src:Object),.. + tello(src:Object ),.. + samples Var,channels Var,freq Var) + +Function Read_Ogg(ogg:Byte Ptr,buf:Byte Ptr,size) 'null buffer to close + +End Extern diff --git a/mod/pub.mod/openal.mod/openal.bmx b/mod/pub.mod/openal.mod/openal.bmx new file mode 100644 index 0000000..abf0694 --- /dev/null +++ b/mod/pub.mod/openal.mod/openal.bmx @@ -0,0 +1,1325 @@ + +Strict + +Rem +bbdoc: Audio/OpenAL 1.1 +about: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      ConstantsDescription
      AL_INVALID
      AL_NONE
      bad value
      AL_FALSEBoolean False.
      AL_TRUEBoolean True.
      AL_SOURCE_RELATIVEIndicate Source has relative coordinates.
      AL_CONE_INNER_ANGLEDirectional source, inner cone angle, in degrees.
      Range: [0-360]
      Default: 360
      AL_CONE_OUTER_ANGLEDirectional source, outer cone angle, in degrees.
      Range: [0-360]
      Default: 360
      AL_PITCHSpecify the pitch to be applied, either at source,or on mixer results, at listener.
      Range: [0.5-2.0]
      Default: 1.0
      AL_POSITIONSpecify the current location in three dimensional space.
      OpenAL, like OpenGL, uses a right handed coordinate system, where in a frontal default view X (thumb) points right, Y points up (index finger), and Z points towards the viewer/camera (middle finger).
      To switch from a left handed coordinate system, flip the sign on the Z coordinate.
      Listener position is always in the world coordinate system.
      AL_DIRECTIONSpecify the current direction.
      AL_VELOCITYSpecify the current velocity in three dimensional space.
      AL_LOOPINGIndicate whether source is looping.
      Type: ALboolean?
      Range: [AL_TRUE, AL_FALSE]
      Default: FALSE.
      AL_BUFFERIndicate the buffer to provide sound samples.
      Type: ALuint.
      Range: any valid Buffer id.
      AL_GAINIndicate the gain (volume amplification) applied.
      Type: ALfloat.
      Range: ]0.0- ]
      A value of 1.0 means un-attenuated/unchanged.
      Each division by 2 equals an attenuation of -6dB.
      Each multiplicaton with 2 equals an amplification of +6dB.
      A value of 0.0 is meaningless with respect to a logarithmic scale; it is interpreted as zero volume - the channel is effectively disabled.
      AL_MIN_GAINIndicate minimum source attenuation
      Type: ALfloat
      Range: [0.0 - 1.0]
      AL_MAX_GAINIndicate maximum source attenuation
      Type: ALfloat
      Range: [0.0 - 1.0]
      AL_ORIENTATIONIndicate listener orientation.
      AL_CHANNEL_MASKSpecify the channel mask. (Creative)
      Type: ALuint
      Range: [0 - 255]
      AL_SOURCE_STATE
      AL_INITIAL
      AL_PLAYING
      AL_PAUSED
      AL_STOPPED
      Source state information.
      AL_BUFFERS_QUEUED
      AL_BUFFERS_PROCESSED
      Buffer Queue params
      AL_SEC_OFFSET
      AL_SAMPLE_OFFSET
      AL_BYTE_OFFSET
      Source buffer position information
      AL_SOURCE_TYPESource type (Static, Streaming or undetermined)
      AL_STATICSource is Static if a Buffer has been attached using AL_BUFFER
      AL_STREAMINGSource is Streaming if one or more Buffers have been attached using alSourceQueueBuffers
      AL_UNDETERMINEDSource is undetermined when it has the NULL buffer attached
      AL_FORMAT_MONO8
      AL_FORMAT_STEREO8
      AL_FORMAT_MONO16
      AL_FORMAT_STEREO16
      Sound samples: format specifier.
      AL_REFERENCE_DISTANCEsource specific reference distance
      Type: ALfloat
      Range: 0.0 - +inf

      at 0.0, no distance attenuation occurs. Default is 1.0.
      AL_ROLLOFF_FACTORsource specific rolloff factor
      Type: ALfloat
      Range: 0.0 - +inf
      AL_CONE_OUTER_GAINDirectional source, outer cone gain.
      Default: 0.0
      Range: [0.0 - 1.0]
      AL_MAX_DISTANCEIndicate distance above which sources are not attenuated using the inverse clamped distance model.
      Default: +inf
      Type: ALfloat
      AL_FREQUENCY
      AL_BITS
      AL_CHANNELS
      AL_SIZE
      frequency, in units of Hertz [Hz].
      This is the number of samples per second. Half of the sample frequency marks the maximum significant frequency component.
      AL_UNUSED
      AL_PENDING
      AL_PROCESSED
      Buffer state.
      not supported for public use (yet).
      AL_NO_ERRORNo Error
      AL_INVALID_NAMEInvalid Name paramater passed to AL call.
      AL_ILLEGAL_ENUM
      AL_INVALID_ENUM
      Invalid parameter passed to AL call.
      AL_INVALID_VALUEInvalid enum parameter value.
      AL_ILLEGAL_COMMAND
      AL_INVALID_OPERATION
      Illegal call.
      AL_OUT_OF_MEMORYNo mojo.
      AL_VENDOR
      AL_VERSION
      AL_RENDERER
      AL_EXTENSIONS
      Context strings: Vendor Name.
      AL_DOPPLER_FACTORDoppler scale. Default 1.0
      AL_DOPPLER_VELOCITYTweaks speed of propagation.
      AL_SPEED_OF_SOUNDSpeed of Sound in units per second
      AL_DISTANCE_MODEL
      AL_INVERSE_DISTANCE
      AL_INVERSE_DISTANCE_CLAMPED
      AL_LINEAR_DISTANCE
      AL_LINEAR_DISTANCE_CLAMPED
      AL_EXPONENT_DISTANCE
      AL_EXPONENT_DISTANCE_CLAMPED
      Distance models

      used in conjunction with DistanceModel

      implicit: NONE, which disances distance attenuation.

      + + + + + + + + + + + + + + + + + + + + + + + + + +
      ALC constantsDescription
      ALC_FALSEFalse
      ALC_TRUETrue
      ALC_FREQUENCYFrequency for mixing output buffer, in units of Hz
      ALC_REFRESHRefresh intervals, in units of Hz
      ALC_SYNCFlag, indicating a synchronous context
      ALC_MONO_SOURCESA hint indicating how many sources should be capable of supporting mono data
      ALC_STEREO_SOURCESA hint indicating how many sources should be capable of supporting stereo data
      ALC_NO_ERRORThere is no current error.
      ALC_INVALID_DEVICEThe device handle or specifier names an accessible driver/server
      ALC_INVALID_CONTEXTThe Context argument does not name a valid context.
      ALC_INVALID_ENUMA token used is not valid, or not applicable.
      ALC_INVALID_VALUEA value (e.g. Attribute) is not valid, or not applicable.
      ALC_OUT_OF_MEMORYUnable to allocate memory.
      ALC_DEFAULT_DEVICE_SPECIFIERThe specifier string for the default device
      ALC_DEVICE_SPECIFIERThe specifier string for the device
      ALC_EXTENSIONSA list of available context extensions separated by spaces.
      ALC_MAJOR_VERSIONThe specification revision for this implementation (major version). NULL is an acceptable device.
      ALC_MINOR_VERSIONThe specification revision for this implementation (minor version). NULL is an acceptable device.
      ALC_ATTRIBUTES_SIZEThe size (number of ALCint values) required for a zero-terminated attributes list, for the current context. NULL is an invalid device.
      ALC_ALL_ATTRIBUTESExpects a destination of ALC_ATTRIBUTES_SIZE, and provides an attribute list for the current context of the specified device. NULL is an invalid device.
      ALC_CAPTURE_DEVICE_SPECIFIERThe name of the specified capture device, or a list of all available capture devices if no capture device is specified.
      ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIERThe name of the default capture device
      ALC_CAPTURE_SAMPLESThe number of capture samples available. NULL is an invalid device.

      +End Rem +Module Pub.OpenAL + +ModuleInfo "Version: 1.03" +ModuleInfo "Modserver: BRL" + +ModuleInfo "History: 1.03 Release" +ModuleInfo "History: alGetProcAddress now returns Byte Ptr" +ModuleInfo "History: 1.02 Release" +ModuleInfo "History: Added missing func check" +ModuleInfo "History: Fixed mispelled funcs" +ModuleInfo "History: Added Redi's docs" +ModuleInfo "History: 1.01 Initial Release" + +Import "openal.c" + +' download openal runtime library from http://www.openal.org + +Private + +Extern +Function LoadOpenAL() +Function GetOpenALFunction:Byte Ptr( fname$z ) +End Extern + +Global _ok=LoadOpenAL() + +Function P:Byte Ptr(t$) + Return GetOpenALFunction( t ) +End Function + +Public + +Rem +bbdoc: Check if OpenAL is installed. +returns: True if OpenAL is installed. +about: +This function allows you to determine whether OpenAL is installed on the current machine. +End Rem +Function OpenALInstalled() + Return _ok +End Function + +'***** alc ***** +Const ALC_FALSE=0 +Const ALC_TRUE=1 +Const ALC_FREQUENCY=$1007 +Const ALC_REFRESH=$1008 +Const ALC_SYNC=$1009 +Const ALC_MONO_SOURCES=$1010 +Const ALC_STEREO_SOURCES=$1011 +Const ALC_NO_ERROR=ALC_FALSE +Const ALC_INVALID_DEVICE=$a001 +Const ALC_INVALID_CONTEXT=$a002 +Const ALC_INVALID_ENUM=$a003 +Const ALC_INVALID_VALUE=$a004 +Const ALC_OUT_OF_MEMORY=$a005 +Const ALC_DEFAULT_DEVICE_SPECIFIER=$1004 +Const ALC_DEVICE_SPECIFIER=$1005 +Const ALC_EXTENSIONS=$1006 +Const ALC_MAJOR_VERSION=$1000 +Const ALC_MINOR_VERSION=$1001 +Const ALC_ATTRIBUTES_SIZE=$1002 +Const ALC_ALL_ATTRIBUTES=$1003 +Const ALC_CAPTURE_DEVICE_SPECIFIER=$310 +Const ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER=$311 +Const ALC_CAPTURE_SAMPLES=$312 + +Rem +bbdoc: This function opens a device by name. +about: + +
      ParametersDescription
      devicenamea null-terminated string describing a device

      +The return value will be NULL if there is an error.

      +Returns a pointer to the opened device. Will return NULL if a device can not be opened. +End Rem +Global alcOpenDevice( devicename$z )=P("alcOpenDevice") +Rem +bbdoc: This function closes a device by name. +about: + +
      ParametersDescription
      devicea pointer to an opened device

      + +
      Possible Error StatesDescription
      ALC_INVALID_DEVICEThe specified device name doesn't exist.

      +Any contexts and buffers within the device will be destroyed when the device is closed, and ALC_TRUE will be returned on success or ALC_FALSE on failure. +End Rem +Global alcCloseDevice( device )=P("alcCloseDevice") +Rem +bbdoc: This function retrieves the current context error state. +about: + +
      ParametersDescription
      devicea pointer to the device to retrieve the error state from

      +End Rem +Global alcGetError( device )=P("alcGetError") +Rem +bbdoc: This function returns pointers to strings related to the context. +about: + + +
      ParametersDescription
      devicea pointer to the device to be queried
      paraman attribute to be retrieved:
      ALC_DEFAULT_DEVICE_SPECIFIER
      ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER
      ALC_DEVICE_SPECIFIER
      ALC_CAPTURE_DEVICE_SPECIFIER
      ALC_EXTENSIONS

      + +
      Possible Error StatesDescription
      ALC_INVALID_ENUMThe specified parameter is not valid.

      +ALC_DEFAULT_DEVICE_SPECIFIER will return the name of the default output device.

      +ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER will return the name of the default capture device.

      +ALC_DEVICE_SPECIFIER will return the name of the specified output device if a pointer is supplied, or will return a list of all available devices if a NULL device pointer is supplied. A list is a pointer to a series of strings separated by NULL characters, with the list terminated by two NULL characters.

      +ALC_CAPTURE_DEVICE_SPECIFIER will return the name of the specified capture device if a pointer is supplied, or will return a list of all available devices if a NULL device pointer is supplied.

      +ALC_EXTENSIONS returns a list of available context extensions, with each extension separated by a space and the list terminated by a NULL character.

      +End Rem +Global alcGetString:Byte Ptr( device,param )=P("alcGetString") +Rem +bbdoc: This function returns integers related to the context. +about: + + + + +
      ParametersDescription
      devicea pointer to the device to be queried
      paraman attribute to be retrieved:
      ALC_MAJOR_VERSION
      ALC_MINOR_VERSION
      ALC_ATTRIBUTES_SIZE
      ALC_ALL_ATTRIBUTES
      sizethe size of the destination buffer provided
      dataa pointer to the data to be returned

      + + + + +
      Possible Error StatesDescription
      ALC_INVALID_VALUEThe specified data pointer or size is not valid.
      ALC_INVALID_ENUMThe specified parameter is not valid.
      ALC_INVALID_DEVICEThe specified device is not valid.
      ALC_INVALID_CONTEXTThe specified context is not valid.

      +The versions returned refer to the specification version that the implementation meets. +End Rem +Global alcGetIntegerv( device,param,size,data:Int Ptr )=P("alcGetIntegerv") +Rem +bbdoc: This function creates a context using a specified device. +about: + + +
      ParametersDescription
      devicea pointer to a device
      attrlista pointer to a set of attributes:
      ALC_FREQUENCY
      ALC_REFRESH
      ALC_SYNC

      + + +
      Possible Error StatesDescription
      ALC_INVALID_VALUEAn additional context can not be created for this device.
      ALC_INVALID_DEVICEThe specified device is not a valid output device.

      +returns: A pointer to the new context (NULL on failure). +End Rem +Global alcCreateContext( device,attrlist:Int Ptr )=P("alcCreateContext") +Rem +bbdoc: This function makes a specified context the current context. +about: + +
      ParametersDescription
      contexta pointer to the new context

      + +
      Possible Error StatesDescription
      ALC_INVALID_CONTEXTThe specified context is invalid.

      +Returns ALC_TRUE on success, or ALC_FALSE on failure. +End Rem +Global alcMakeContextCurrent( context )=P("alcMakeContextCurrent") +Rem +bbdoc: This function tells a context to begin processing. +about: + +
      ParametersDescription
      contexta pointer to the new context

      + +
      Possible Error StatesDescription
      ALC_INVALID_CONTEXTThe specified context is invalid.

      +When a context is suspended, changes in OpenAL state will be accepted but will not be processed. #alcSuspendContext can be used to suspend a context, and then all the OpenAL state changes can be applied at once, followed by a call to alcProcessContext to apply all the state changes immediately. In some cases, this procedure may be more efficient than application of properties in a non-suspended state. In some implementations, process and suspend calls are each a NOP. +End Rem +Global alcProcessContext( context )=P("alcProcessContext") +Rem +bbdoc: This function suspends processing on a specified context. +about: + +
      ParametersDescription
      contexta pointer to the context to be suspended

      + +
      Possible Error StatesDescription
      ALC_INVALID_CONTEXTThe specified context is invalid.

      +When a context is suspended, changes in OpenAL state will be accepted but will not be processed. A typical use of alcSuspendContext would be to suspend a context, apply all the OpenAL state changes at once, and then call #alcProcessContext to apply all the state changes at once. In some cases, this procedure may be more efficient than application of properties in a non-suspended state. In some implementations, process and suspend calls are each a NOP. +End Rem +Global alcSuspendContext( context )=P("alcSuspendContext") +Rem +bbdoc: This function destroys a context. +about: + +
      ParametersDescription
      contexta pointer to the new context

      + +
      Possible Error StatesDescription
      ALC_INVALID_CONTEXTThe specified context is invalid.

      +A context which is not current can be destroyed at any time (all sources within that context will also be deleted - buffers are not affected). #alcMakeContextCurrent should be used to make sure the context to be destroyed is not current (NULL is valid for #alcMakeContextCurrent). +End Rem +Global alcDestroyContext( context )=P("alcDestroyContext") +Rem +bbdoc: This function retrieves the current context. +returns: a pointer to the current context. +End Rem +Global alcGetCurrentContext()=P("alcGetCurrentContext") +Rem +bbdoc: This function retrieves a context's device pointer. +about: + +
      ParametersDescription
      contexta pointer to a context

      + +
      Possible Error StatesDescription
      ALC_INVALID_CONTEXTThe specified context is invalid.

      +Returns: a pointer to the specified context's device. +End Rem +Global alcGetContextsDevice( context )=P("alcGetContextsDevice") +Rem +bbdoc: This function queries if a specified context extension is available. +about: + + +
      ParametersDescription
      devicea pointer to the device to be queried for an extension
      extNamea null-terminated string describing the extension

      + +
      Possible Error StatesDescription
      ALC_INVALID_VALUEThe string pointer is not valid.

      +Returns ALC_TRUE if the extension is available, ALC_FALSE if the extension is not available. +End Rem +Global alcIsExtensionPresent( device,extName$z )=P("alcIsExtensionPresent") +Rem +bbdoc: This function retrieves the address of a specified context extension function. +about: + + +
      ParametersDescription
      devicea pointer to the device to be queried for the function
      funcNamea null-terminated string describing the function

      + +
      Possible Error StatesDescription
      ALC_INVALID_VALUEThe string pointer is not valid.

      +Returns the address of the function, or NULL if it is not found. +End Rem +Global alcGetProcAddress:Byte Ptr( device,funcName$z )=P("alcGetProcAddress") +Rem +bbdoc: This function retrieves the enum value for a specified enumeration name. +about: + + +
      ParametersDescription
      devicea pointer to the device to be queried
      enumNamea null terminated string describing the enum value

      + +
      Possible Error StatesDescription
      ALC_INVALID_VALUEThe string pointer is not valid.

      +Returns the enum value described by the enumName string. This is most often used for querying an enum value for an ALC extension. +End Rem +Global alcGetEnumValue( device,enumName$z )=P("alcGetEnumValue") +Rem +bbdoc: This function opens a capture device by name. +about: + + + + +
      ParametersDescription
      devicenamea pointer to a device name string
      frequencythe frequency that the data should be captured at
      formatthe requested capture buffer format
      buffersizethe size of the capture buffer

      + + +
      Possible Error StatesDescription
      ALC_INVALID_VALUEOne of the parameters has an invalid value.
      ALC_OUT_OF_MEMORYThe specified device is invalid, or can not capture audio.

      +Returns the capture device pointer, or NULL on failure. +End Rem +Global alcCaptureOpenDevice( devicename$z,frequency,format,buffersize )=P("alcCaptureOpenDevice") +Rem +bbdoc: This function closes the specified capture device. +about: + +
      ParametersDescription
      devicea pointer to a capture device

      + +
      Possible Error StatesDescription
      ALC_INVALID_DEVICEThe specified device is not a valid capture device.

      +Returns ALC_TRUE if the close operation was successful, ALC_FALSE on failure. +End Rem +Global alcCaptureCloseDevice( device )=P("alcCaptureCloseDevice") +Rem +bbdoc: This function begins a capture operation. +about: + +
      ParametersDescription
      devicea pointer to a capture device

      + +
      Possible Error StatesDescription
      ALC_INVALID_DEVICEThe specified device is not a valid capture device.

      +alcCaptureStart will begin recording to an internal ring buffer of the size specified when opening the capture device. The application can then retrieve the number of samples currently available using the ALC_CAPTURE_SAPMPLES token with #alcGetIntegerv. When the application determines that enough samples are available for processing, then it can obtain them with a call to #alcCaptureSamples. +End Rem +Global alcCaptureStart( device )=P("alcCaptureStart") +Rem +bbdoc: This function stops a capture operation. +about: + +
      ParametersDescription
      devicea pointer to a capture device

      + +
      Possible Error StatesDescription
      ALC_INVALID_DEVICEThe specified device is not a valid capture device.

      +End Rem +Global alcCaptureStop( device )=P("alcCaptureStop") +Rem +bbdoc: This function completes a capture operation. +about: + + + +
      ParametersDescription
      devicea pointer to a capture device
      buffera pointer to a data buffer, which must be large enough to accommodate samples number of samples
      samplesthe number of samples to be retrieved

      + + +
      Possible Error StatesDescription
      ALC_INVALID_VALUEThe specified number of samples is larger than the number of available samples.
      ALC_INVALID_DEVICEThe specified device is not a valid capture device.

      +End Rem +Global alcCaptureSamples( device,buffer:Byte Ptr,samples )=P("alcCaptureSamples") + +Const AL_NONE=0 +Const AL_FALSE=0 +Const AL_TRUE=1 +Const AL_SOURCE_RELATIVE=$202 +Const AL_CONE_INNER_ANGLE=$1001 +Const AL_CONE_OUTER_ANGLE=$1002 +Const AL_PITCH=$1003 +Const AL_POSITION=$1004 +Const AL_DIRECTION=$1005 +Const AL_VELOCITY=$1006 +Const AL_LOOPING=$1007 +Const AL_BUFFER=$1009 +Const AL_GAIN=$100a +Const AL_MIN_GAIN=$100d +Const AL_MAX_GAIN=$100e +Const AL_ORIENTATION=$100f +Const AL_SOURCE_STATE=$1010 +Const AL_INITIAL=$1011 +Const AL_PLAYING=$1012 +Const AL_PAUSED=$1013 +Const AL_STOPPED=$1014 +Const AL_BUFFERS_QUEUED=$1015 +Const AL_BUFFERS_PROCESSED=$1016 +Const AL_SEC_OFFSET=$1024 +Const AL_SAMPLE_OFFSET=$1025 +Const AL_BYTE_OFFSET=$1026 +Const AL_SOURCE_TYPE=$1027 +Const AL_STATIC=$1028 +Const AL_STREAMING=$1029 +Const AL_UNDETERMINED=$1030 +Const AL_FORMAT_MONO8=$1100 +Const AL_FORMAT_MONO16=$1101 +Const AL_FORMAT_STEREO8=$1102 +Const AL_FORMAT_STEREO16=$1103 +Const AL_REFERENCE_DISTANCE=$1020 +Const AL_ROLLOFF_FACTOR=$1021 +Const AL_CONE_OUTER_GAIN=$1022 +Const AL_MAX_DISTANCE=$1023 +Const AL_FREQUENCY=$2001 +Const AL_BITS=$2002 +Const AL_CHANNELS=$2003 +Const AL_SIZE=$2004 +Const AL_UNUSED=$2010 +Const AL_PENDING=$2011 +Const AL_PROCESSED=$2012 +Const AL_NO_ERROR=AL_FALSE +Const AL_INVALID_NAME=$a001 +Const AL_INVALID_ENUM=$a002 +Const AL_INVALID_VALUE=$a003 +Const AL_INVALID_OPERATION=$a004 +Const AL_OUT_OF_MEMORY=$a005 +Const AL_VENDOR=$b001 +Const AL_VERSION=$b002 +Const AL_RENDERER=$b003 +Const AL_EXTENSIONS=$b004 +Const AL_DOPPLER_FACTOR=$c000 +Const AL_DOPPLER_VELOCITY=$c001 +Const AL_SPEED_OF_SOUND=$c003 +Const AL_DISTANCE_MODEL=$d000 +Const AL_INVERSE_DISTANCE=$d001 +Const AL_INVERSE_DISTANCE_CLAMPED=$d002 +Const AL_LINEAR_DISTANCE=$d003 +Const AL_LINEAR_DISTANCE_CLAMPED=$d004 +Const AL_EXPONENT_DISTANCE=$d005 +Const AL_EXPONENT_DISTANCE_CLAMPED=$d006 + +Rem +bbdoc: This function enables a feature of the OpenAL driver. +about: + +
      ParametersDescription
      capabilitythe name of a capability to enable

      + + +
      Possible Error StatesDescription
      AL_INVALID_ENUMThe specified capability is not valid.
      AL_INVALID_OPERATIONThere is no current context.

      +There are no capabilities defined in OpenAL 1.1 to be used with this function, but it may be used by an extension. +End Rem +Global alEnable( capability )=P("alEnable") +Rem +bbdoc: This function disables a feature of the OpenAL driver. +about: + +
      ParametersDescription
      capabilitythe name of a capability to disable

      + + +
      Possible Error StatesDescription
      AL_INVALID_ENUMThe specified capability is not valid.
      AL_INVALID_OPERATIONThere is no current context.

      +There are no capabilities defined in OpenAL 1.1 to be used with this function, but it may be used by an extension. +End Rem +Global alDisable( capability )=P("alDisable") +Rem +bbdoc: This function returns a boolean indicating if a specific feature is enabled in the OpenAL +about: + +
      ParametersDescription
      capabilitythe name of a capability to disable

      + + +
      Possible Error StatesDescription
      AL_INVALID_ENUMThe specified capability is not valid.
      AL_INVALID_OPERATIONThere is no current context.

      +Returns AL_TRUE if the capability is enabled, AL_FALSE if the capability is disabled. There are no capabilities defined in OpenAL 1.1 to be used with this function, but it may be used by an extension. +End Rem +Global alIsEnabled( capability )=P("alIsEnabled") +Rem +bbdoc: This function retrieves an OpenAL string property. +about: + +
      ParametersDescription
      paramThe property to be returned:
      AL_VENDOR
      AL_VERSION
      AL_RENDERER
      AL_EXTENSIONS

      + +
      Possible Error StatesDescription
      AL_INVALID_ENUMThe specified parameter is not valid.

      +Returns a pointer to a null-terminated string. +End Rem +Global alGetString:Byte Ptr( param )=P("alGetString") +Rem +bbdoc: This function retrieves a boolean OpenAL state. +about: + + +
      ParametersDescription
      paramthe state to be returned:
      AL_DOPPLER_FACTOR
      AL_SPEED_OF_SOUND
      AL_DISTANCE_MODEL
      dataa pointer to the location where the state will be stored

      + + + +
      Possible Error StatesDescription
      AL_INVALID_ENUMThe specified parameter is not valid.
      AL_INVALID_VALUEThe specified data pointer is not valid.
      AL_INVALID_OPERATIONThere is no current context.

      +End Rem +Global alGetBooleanv( param,data:Byte Ptr )=P("alGetBooleanv") +Rem +bbdoc: This function retrieves an integer OpenAL state. +about: + + +
      ParametersDescription
      paramthe state to be returned:
      AL_DOPPLER_FACTOR
      AL_SPEED_OF_SOUND
      AL_DISTANCE_MODEL
      dataa pointer to the location where the state will be stored

      + + + +
      Possible Error StatesDescription
      AL_INVALID_ENUMThe specified parameter is not valid.
      AL_INVALID_VALUEThe specified data pointer is not valid.
      AL_INVALID_OPERATIONThere is no current context.

      +End Rem +Global alGetIntegerv( param,data:Int Ptr )=P("alGetIntegerv") +Rem +bbdoc: This function retrieves a floating point OpenAL state. +about: + + +
      ParametersDescription
      paramthe state to be returned:
      AL_DOPPLER_FACTOR
      AL_SPEED_OF_SOUND
      AL_DISTANCE_MODEL
      dataa pointer to the location where the state will be stored

      + + + +
      Possible Error StatesDescription
      AL_INVALID_ENUMThe specified parameter is not valid.
      AL_INVALID_VALUEThe specified data pointer is not valid.
      AL_INVALID_OPERATIONThere is no current context.

      +End Rem +Global alGetFloatv( param,data:Float Ptr )=P("alGetFloatv") +Rem +bbdoc: This function retrieves a double precision floating point OpenAL state. +about: + + +
      ParametersDescription
      paramthe state to be returned:
      AL_DOPPLER_FACTOR
      AL_SPEED_OF_SOUND
      AL_DISTANCE_MODEL
      dataa pointer to the location where the state will be stored

      + + + +
      Possible Error StatesDescription
      AL_INVALID_ENUMThe specified parameter is not valid.
      AL_INVALID_VALUEThe specified data pointer is not valid.
      AL_INVALID_OPERATIONThere is no current context.

      +End Rem +Global alGetDoublev( param,data:Double Ptr )=P("alGetDoublev") +Rem +bbdoc: This function returns a boolean OpenAL state. +about: + +
      ParametersDescription
      paramthe state to be queried:
      AL_DOPPLER_FACTOR
      AL_SPEED_OF_SOUND
      AL_DISTANCE_MODEL

      + + +
      Possible Error StatesDescription
      AL_INVALID_ENUMThe specified parameter is not valid.
      AL_INVALID_OPERATIONThere is no current context.

      +The boolean state described by param will be returned. +End Rem +Global alGetBoolean( param )=P("alGetBoolean") +Rem +bbdoc: This function returns an integer OpenAL state. +about: + +
      ParametersDescription
      paramthe state to be queried:
      AL_DOPPLER_FACTOR
      AL_SPEED_OF_SOUND
      AL_DISTANCE_MODEL

      + + +
      Possible Error StatesDescription
      AL_INVALID_ENUMThe specified parameter is not valid.
      AL_INVALID_OPERATIONThere is no current context.

      +The integer state described by param will be returned. +End Rem +Global alGetInteger( param )=P("alGetInteger") +Rem +bbdoc: This function returns a floating point OpenAL state. +about: + +
      ParametersDescription
      paramthe state to be queried:
      AL_DOPPLER_FACTOR
      AL_SPEED_OF_SOUND
      AL_DISTANCE_MODEL

      + + +
      Possible Error StatesDescription
      AL_INVALID_ENUMThe specified parameter is not valid.
      AL_INVALID_OPERATIONThere is no current context.

      +The floating point state described by param will be returned. +End Rem +Global alGetFloat#( param )=P("alGetFloat") +Rem +bbdoc: This function returns a double precision floating point OpenAL state. +about: + +
      ParametersDescription
      paramthe state to be queried:
      AL_DOPPLER_FACTOR
      AL_SPEED_OF_SOUND
      AL_DISTANCE_MODEL

      + + +
      Possible Error StatesDescription
      AL_INVALID_ENUMThe specified parameter is not valid.
      AL_INVALID_OPERATIONThere is no current context.

      +The double value described by param will be returned. +End Rem +Global alGetDouble!( param )=P("alGetDouble") +Rem +bbdoc: This function returns the current error state and then clears the error state. +about: Returns an Alenum representing the error state. When an OpenAL error occurs, the error state is set and will not be changed until the error state is retrieved using alGetError. Whenever alGetError is called, the error state is cleared and the last state (the current state when the call was made) is returned. To isolate error detection to a specific portion of code, alGetError should be called before the isolated section to clear the current error state. +End Rem +Global alGetError()=P("alGetError") +Rem +bbdoc: This function tests if a specific extension is available for the OpenAL driver. +about: + +
      ParametersDescription
      extnamea null-terminated string describing the desired extension

      + +
      Possible Error StatesDescription
      AL_INVALID_VALUEThe specified extension string is not a valid pointer.

      +Returns AL_TRUE if the extension is available, AL_FALSE if the extension is not available. +End Rem +Global alIsExtensionPresent( extname$z )=P("alIsExtensionPresent") +Rem +bbdoc: This function returns the address of an OpenAL extension function. +about: + +
      ParametersDescription
      fnamea null-terminated string containing the function name

      +The return value is a pointer to the specified function. The return value will be NULL if the function is not found. +End Rem +Global alGetProcAddress:Byte Ptr( fname$z )=P("alGetProcAddress") +Rem +bbdoc: This function returns the enumeration value of an OpenAL enum described by a string. +about: + +
      ParametersDescription
      enamea null-terminated string describing an OpenAL enum

      +Returns the actual ALenum described by a string. Returns NULL if the string doesnt describe a valid OpenAL enum. +EndRem +Global alGetEnumValue( ename$z )=P("alGetEnumValue") + +Rem +bbdoc: This function sets a floating point property for the listener. The relevant properties are listed in the table Listener Properties. +about: + + +
      ParametersDescription
      paramthe name of the attribute to be set: AL_GAIN
      valuethe ALfloat value to set the attribute to

      + + + +
      Possible Error StatesDescription
      AL_INVALID_VALUEThe value given is not valid.
      AL_INVALID_ENUMThe specified parameter is not valid.
      AL_INVALID_OPERATIONThere is no current context.

      +End Rem +Global alListenerf( param,value# )=P("alListenerf") +Rem +bbdoc: This function sets a floating point property for the listener. The relevant properties are listed in the table Listener Properties. +about: + + +
      ParametersDescription
      paramthe name of the attribute to set:
      AL_POSITION
      AL_VELOCITY
      v1, v2, v3the value to set the attribute to

      + + + +
      Possible Error StatesDescription
      AL_INVALID_VALUEThe value given is not valid.
      AL_INVALID_ENUMThe specified parameter is not valid.
      AL_INVALID_OPERATIONThere is no current context.

      +End Rem +Global alListener3f( param,value1#,value2#,value3# )=P("alListener3f") +Rem +bbdoc: This function sets a floating point-vector property of the listener. The relevant properties are listed in the table Listener Properties. +about: + + +
      ParametersDescription
      paramthe name of the attribute to be set:
      AL_POSITION
      AL_VELOCITY
      AL_ORIENTATION
      valuespointer to floating point-vector values

      + + + +
      Possible Error StatesDescription
      AL_INVALID_VALUEThe value given is not valid.
      AL_INVALID_ENUMThe specified parameter is not valid.
      AL_INVALID_OPERATIONThere is no current context.

      +End Rem +Global alListenerfv( param,values:Float Ptr )=P("alListenerfv") +Rem +bbdoc: This function sets an integer property of the listener. +about: + + +
      ParametersDescription
      paramthe name of the attribute to be set
      valuethe integer value to set the attribute to

      + + + +
      Possible Error StatesDescription
      AL_INVALID_VALUEThe value given is not valid.
      AL_INVALID_ENUMThe specified parameter is not valid.
      AL_INVALID_OPERATIONThere is no current context.

      +There are no integer listener attributes defined for OpenAL 1.1, but this function may be used by an extension. +End Rem +Global alListeneri( param,value )=P("alListeneri") +Rem +bbdoc: This function sets an integer property of the listener. The relevant properties are listed in the table Listener Properties. +about: + + +
      ParametersDescription
      paramthe name of the attribute to be set:
      AL_POSITION
      AL_VELOCITY
      value1, value2, value3the integer values to set the attribute to

      + + + +
      Possible Error StatesDescription
      AL_INVALID_VALUEThe value given is not valid.
      AL_INVALID_ENUMThe specified parameter is not valid.
      AL_INVALID_OPERATIONThere is no current context.

      +End Rem +Global alListener3i( param,value1,value2,value3 )=P("alListener3i") +Rem +bbdoc: This function sets an integer property of the listener. The relevant properties are listed in the table Listener Properties. +about: + + +
      ParametersDescription
      paramthe name of the attribute to be set:
      AL_POSITION
      AL_VELOCITY
      AL_ORIENTATION
      valuespointer to the integer values to set the attribute to

      + + + +
      Possible Error StatesDescription
      AL_INVALID_VALUEThe value given is not valid.
      AL_INVALID_ENUMThe specified parameter is not valid.
      AL_INVALID_OPERATIONThere is no current context.

      +End Rem +Global alListeneriv( param,values:Int Ptr )=P("alListeneriv") +Rem +bbdoc: This function retrieves a floating point property of the listener. The relevant properties are listed in the table Listener Properties. +about: + + +
      ParametersDescription
      paramthe name of the attribute to be retrieved: AL_GAIN
      valuea pointer to the floating point value being retrieved

      + + + +
      Possible Error StatesDescription
      AL_INVALID_VALUEThe value pointer given is not valid.
      AL_INVALID_ENUMThe specified parameter is not valid.
      AL_INVALID_OPERATIONThere is no current context.

      +End Rem +Global alGetListenerf( param,value:Float Ptr )=P("alGetListenerf") +Rem +bbdoc: This function retrieves a set of three floating point values from a property of the listener. The relevant properties are listed in the table Listener Properties. +about: + + +
      ParametersDescription
      paramthe name of the attribute to be retrieved:
      AL_POSITION
      AL_VELOCITY
      value1, value2, value3pointers to the three floating point being retrieved

      + + + +
      Possible Error StatesDescription
      AL_INVALID_VALUEThe value pointer given is not valid.
      AL_INVALID_ENUMThe specified parameter is not valid.
      AL_INVALID_OPERATIONThere is no current context.

      +End Rem +Global alGetListener3f( param,value1:Float Ptr,value2:Float Ptr,value3:Float Ptr )=P("alGetListener3f") +Rem +bbdoc: This function retrieves a floating point-vector property of the listener. The relevant properties are listed in the table Listener Properties. +about: + + +
      ParametersDescription
      paramthe name of the attribute to be retrieved:
      AL_POSITION
      AL_VELOCITY
      AL_ORIENTATION
      valuesa pointer to the floating point-vector value being retrieved

      + + + +
      Possible Error StatesDescription
      AL_INVALID_VALUEThe value pointer given is not valid.
      AL_INVALID_ENUMThe specified parameter is not valid.
      AL_INVALID_OPERATIONThere is no current context.

      +End Rem +Global alGetListenerfv( param,values:Float Ptr )=P("alGetListenerfv") +Rem +bbdoc: This function retrieves an integer property of the listener. +about: + + +
      ParametersDescription
      paramthe name of the attribute to be retrieved
      valuea pointer to the integer value being retrieved

      + + + +
      Possible Error StatesDescription
      AL_INVALID_VALUEThe value pointer given is not valid.
      AL_INVALID_ENUMThe specified parameter is not valid.
      AL_INVALID_OPERATIONThere is no current context.

      +There are no integer listener attributes defined for OpenAL 1.1, but this function may be used by an extension. +End Rem +Global alGetListeneri( param,value:Int Ptr )=P("alGetListeneri") +Rem +bbdoc: This function retrieves an integer property of the listener. The relevant properties are listed in the table Listener Properties. +about: + + +
      ParametersDescription
      paramthe name of the attribute to be retrieved:
      AL_POSITION
      AL_VELOCITY
      value1, value2, value3pointers to the integer values being retrieved

      + + + +
      Possible Error StatesDescription
      AL_INVALID_VALUEThe value pointer given is not valid.
      AL_INVALID_ENUMThe specified parameter is not valid.
      AL_INVALID_OPERATIONThere is no current context.

      +End Rem +Global alGetListener3i( param,value1:Int Ptr,value2:Int Ptr,value3:Int Ptr )=P("alGetListener3i") + +Rem +bbdoc: This function retrieves an integer property of the listener. The relevant properties are listed in the table Listener Properties. +about: + + +
      ParametersDescription
      paramthe name of the attribute to be retrieved:
      AL_POSITION
      AL_VELOCITY
      AL_ORIENTATION
      valuesa pointer to the integer values being retrieved

      + + + +
      Possible Error StatesDescription
      AL_INVALID_VALUEThe value pointer given is not valid.
      AL_INVALID_ENUMThe specified parameter is not valid.
      AL_INVALID_OPERATIONThere is no current context.

      +End Rem +Global alGetListeneriv( param,values:Int Ptr )=P("alGetListeneriv") + +Rem +bbdoc: This Function generates one or more buffers, which contain audio data (see #alBufferData). References To buffers are ALuint values, which are used wherever a buffer reference is needed (in calls such as #alDeleteBuffers, #alSourcei, #alSourceQueueBuffers, and #alSourceUnqueueBuffers). +about: + + +
      ParametersDescription
      nthe number of buffers To be generated
      bufferspointer To an array of ALuint values which will store the names of the New buffers

      + + +
      Possible Error StatesDescription
      AL_INVALID_VALUEThe buffer array isn't large enough to hold the number of buffers requested.
      AL_OUT_OF_MEMORYThere is not enough memory available To generate all the buffers requested.

      +If the requested number of buffers cannot be created, an error will be generated which can be detected with #alGetError. If an error occurs, no buffers will be generated. If n equals zero, #alGenBuffers does nothing and does not Return an error. +End Rem +Global alGenBuffers( n,buffers:Int Ptr )=P("alGenBuffers") +Rem +bbdoc: This function deletes one or more buffers, freeing the resources used by the buffer. Buffers which are attached to a source can not be deleted. See #alSourcei and #alSourceUnqueueBuffers for information on how to detach a buffer from a source. +about: + + +
      ParametersDescription
      nthe number of buffers to be deleted
      bufferspointer to an array of buffer names identifying the buffers to be deleted

      + + + +
      Possible Error StatesDescription
      AL_INVALID_OPERATIONThe buffer is still in use and can not be deleted.
      AL_INVALID_NAMEA buffer name is invalid.
      AL_INVALID_VALUEThe requested number of buffers can not be deleted.

      +If the requested number of buffers cannot be deleted, an error will be generated which can be detected with #alGetError. If an error occurs, no buffers will be deleted. If n equals zero, #alDeleteBuffers does nothing and will not return an error. +End Rem +Global alDeleteBuffers( n,buffers:Int Ptr )=P("alDeleteBuffers") +Rem +bbdoc: This function tests if a buffer name is valid, returning AL_TRUE if valid, AL_FALSE if not. +about: + +
      ParametersDescription
      bida buffer name to be tested for validity

      +The NULL buffer is always valid (see #alSourcei for information on how the NULL buffer is used). +End Rem +Global alIsBuffer( bid )=P("alIsBuffer") +Rem +bbdoc: This function fills a buffer with audio data. All the pre-defined formats are PCM data, but this function may be used by extensions to load other data types as well. +about: + + + + + +
      ParametersDescription
      bidbuffer name to be filled with data
      formatformat type from among the following: AL_FORMAT_MONO8, AL_FORMAT_MONO16, AL_FORMAT_STEREO8, AL_FORMAT_STEREO16
      datapointer to the audio data
      sizethe size of the audio data in bytes
      freqthe frequency of the audio data

      + + + +
      Possible Error StatesDescription
      AL_OUT_OF_MEMORYThere is not enough memory available to create this buffer.
      AL_INVALID_VALUEThe size parameter is not valid for the format specified, the buffer is in use, or the data is a NULL pointer.
      AL_INVALID_ENUMThe specified format does not exist.

      +8-bit PCM data is expressed as an unsigned value over the range 0 to 255, 128 being an audio output level of zero. 16-bit PCM data is expressed as a signed value over the range -32768 to 32767, 0 being an audio output level of zero. Stereo data is expressed in interleaved format, left channel first. Buffers containing more than one channel of data will be played without 3D spatialization. +End Rem +Global alBufferData( bid,format,data:Byte Ptr,size,freq )=P("alBufferData") +Rem +bbdoc: This Function sets a floating point property of a buffer. +about: + + + +
      ParametersDescription
      bidbuffer name whose attribute is being retrieved
      paramthe name of the attribute To be set
      valuethe ALfloat value To be set

      + + +
      Possible Error StatesDescription
      AL_INVALID_ENUMThe specified parameter is not valid.
      AL_INVALID_NAMEThe specified buffer doesn't have parameters (the NULL buffer), or doesn't exist.

      +There are no relevant buffer properties defined in OpenAL 1.1 which can be affected by this call, but this Function may be used by OpenAL extensions. +End Rem +Global alBufferf( bid,param,value# )=P("alBufferf") +Rem +bbdoc: This function sets a floating point property of a buffer. +about: + + + +
      ParametersDescription
      bidbuffer name whose attribute is being retrieved
      paramthe name of the attribute to be set
      value1, value2, value3the ALfloat values to be set

      + + +
      Possible Error StatesDescription
      AL_INVALID_ENUMThe specified parameter is not valid.
      AL_INVALID_NAMEThe specified buffer doesn't have parameters (the NULL buffer), or doesn't exist.

      +There are no relevant buffer properties defined in OpenAL 1.1 which can be affected by this call, but this function may be used by OpenAL extensions. +End Rem +Global alBuffer3f( bid,param,value1#,value2#,value3# )=P("alBuffer3f") +Rem +bbdoc: This function sets a floating point property of a buffer. +about: + + + +
      ParametersDescription
      bidbuffer name whose attribute is being retrieved
      paramthe name of the attribute to be set
      valuesa pointer to the ALfloat values to be set

      + + +
      Possible Error StatesDescription
      AL_INVALID_ENUMThe specified parameter is not valid.
      AL_INVALID_NAMEThe specified buffer doesn't have parameters (the NULL buffer), or doesn't exist.

      +There are no relevant buffer properties defined in OpenAL 1.1 which can be affected by this call, but this function may be used by OpenAL extensions. +End Rem +Global alBufferfv( bid,param,values:Float Ptr )=P("alBufferfv") +Rem +bbdoc: This Function sets a floating point property of a buffer. +about: + + + +
      ParametersDescription
      bidbuffer name whose attribute is being retrieved
      paramthe name of the attribute To be set
      valuethe ALint value To be set

      + + +
      Possible Error StatesDescription
      AL_INVALID_ENUMThe specified parameter is not valid.
      AL_INVALID_NAMEThe specified buffer doesn't have parameters (the NULL buffer), or doesn't exist.

      +There are no relevant buffer properties defined in OpenAL 1.1 which can be affected by this call, but this Function may be used by OpenAL extensions. +End Rem +Global alBufferi( bid,param,value )=P("alBufferi") +Rem +bbdoc: This Function sets a floating point property of a buffer. +about: + + + +
      ParametersDescription
      bidbuffer name whose attribute is being retrieved
      paramthe name of the attribute To be set
      value1, value2, value3the ALint values To be set

      + + +
      Possible Error StatesDescription
      AL_INVALID_ENUMThe specified parameter is not valid.
      AL_INVALID_NAMEThe specified buffer doesn't have parameters (the NULL buffer), or doesn't exist.

      +There are no relevant buffer properties defined in OpenAL 1.1 which can be affected by this call, but this Function may be used by OpenAL extensions. +End Rem +Global alBuffer3i( bid,param,value1,value2,value3 )=P("alBuffer3i") +Rem +bbdoc: This Function sets a floating point property of a buffer. +about: + + + +
      ParametersDescription
      bidbuffer name whose attribute is being retrieved
      paramthe name of the attribute To be set
      valuesa pointer To the ALint values To be set

      + + +
      Possible Error StatesDescription
      AL_INVALID_ENUMThe specified parameter is not valid.
      AL_INVALID_NAMEThe specified buffer doesn't have parameters (the NULL buffer), or doesn't exist.

      +There are no relevant buffer properties defined in OpenAL 1.1 which can be affected by this call, but this Function may be used by OpenAL extensions. +End Rem +Global alBufferiv( bid,param,values:Int Ptr )=P("alBufferiv") +Rem +bbdoc: This Function retrieves a floating point property of a buffer. +about: + + + +
      ParametersDescription
      bidbuffer name whose attribute is being retrieved
      pnamethe name of the attribute To be retrieved
      valuea pointer to an ALfloat To hold the retrieved data

      + + + +
      Possible Error StatesDescription
      AL_INVALID_ENUMThe specified parameter is not valid.
      AL_INVALID_NAMEThe specified buffer doesn't have parameters (the NULL buffer), or doesn't exist.
      AL_INVALID_VALUEThe specified value pointer is not valid.

      +There are no relevant buffer properties defined in OpenAL 1.1 which can be retrieved by this call, but this Function may be used by OpenAL extensions. +End Rem +Global alGetBufferf( bid,param,value:Float Ptr )=P("alGetBufferf") +Rem +bbdoc: This Function retrieves a floating point property of a buffer. +about: + + + +
      ParametersDescription
      bidbuffer name whose attribute is being retrieved
      pnamethe name of the attribute To be retrieved
      value1, value2, value3pointers to a ALfloat values To hold the retrieved data

      + + + +
      Possible Error StatesDescription
      AL_INVALID_ENUMThe specified parameter is not valid.
      AL_INVALID_NAMEThe specified buffer doesn't have parameters (the NULL buffer), or doesn't exist.
      AL_INVALID_VALUEThe specified value pointer is not valid.

      +There are no relevant buffer properties defined in OpenAL 1.1 which can be retrieved by this call, but this Function may be used by OpenAL extensions. +End Rem +Global alGetBuffer3f( bid,param,value1:Float Ptr,value2:Float Ptr,value3:Float Ptr )=P("alGetBuffer3f") +Rem +bbdoc: This Function retrieves a floating point property of a buffer. +about: + + + +
      ParametersDescription
      bidbuffer name whose attribute is being retrieved
      pnamethe name of the attribute to be retrieved
      valuespointer To an ALfloat vector To hold the retrieved data

      + + + +
      Possible Error StatesDescription
      AL_INVALID_ENUMThe specified parameter is not valid.
      AL_INVALID_NAMEThe specified buffer doesn't have parameters (the NULL buffer), or doesn't exist.
      AL_INVALID_VALUEThe specified value pointer is not valid.

      +There are no relevant buffer properties defined in OpenAL 1.1 which can be retrieved by this call, but this Function may be used by OpenAL extensions. +End Rem +Global alGetBufferfv( bid,param,values:Float Ptr )=P("alGetBufferfv") +Rem +bbdoc: This Function retrieves a floating point property of a buffer. +about: + + + +
      ParametersDescription
      bidbuffer name whose attribute is being retrieved
      pnamethe name of the attribute to be retrieved: AL_FREQUENCY, AL_BITS, AL_CHANNELS, AL_SIZE, AL_DATA
      valuea pointer To an ALint To hold the retrieved data

      + + + +
      Possible Error StatesDescription
      AL_INVALID_ENUMThe specified parameter is not valid.
      AL_INVALID_NAMEThe specified buffer doesn't have parameters (the NULL buffer), or doesn't exist.
      AL_INVALID_VALUEThe specified value pointer is not valid.

      +There are no relevant buffer properties defined in OpenAL 1.1 which can be retrieved by this call, but this Function may be used by OpenAL extensions. +End Rem +Global alGetBufferi( bid,param,value:Int Ptr )=P("alGetBufferi") +Rem +bbdoc: This Function retrieves a floating point property of a buffer. +about: + + + +
      ParametersDescription
      bidbuffer name whose attribute is being retrieved
      pnamethe name of the attribute To be retrieved
      value1, value2, value3pointers To ALint values To hold the retrieved data

      + + + +
      Possible Error StatesDescription
      AL_INVALID_ENUMThe specified parameter is not valid.
      AL_INVALID_NAMEThe specified buffer doesn't have parameters (the NULL buffer), or doesn't exist.
      AL_INVALID_VALUEThe specified value pointer is not valid.

      +There are no relevant buffer properties defined in OpenAL 1.1 which can be retrieved by this call, but this Function may be used by OpenAL extensions. +End Rem +Global alGetBuffer3i( bid,param,value1:Int Ptr,value2:Int Ptr,value3:Int Ptr )=P("alGetBuffer3i") +Rem +bbdoc: This Function retrieves a floating point property of a buffer. The relevant properties are listed in the table Buffer Properties. +about: + + + +
      ParametersDescription
      bidbuffer name whose attribute is being retrieved
      pnamethe name of the attribute To be retrieved
      valuespointer to an ALint vector To hold the retrieved data

      + + + +
      Possible Error StatesDescription
      AL_INVALID_ENUMThe specified parameter is not valid.
      AL_INVALID_NAMEThe specified buffer doesn't have parameters (the NULL buffer), or doesn't exist.
      AL_INVALID_VALUEThe specified value pointer is not valid.

      +There are no relevant buffer properties defined in OpenAL 1.1 which can be retrieved by this call, but this function may be used by OpenAL extensions. +End Rem +Global alGetBufferiv( bid,param,values:Int Ptr )=P("alGetBufferiv") + +Rem +bbdoc: This Function generates one or more sources. References To sources are ALuint values, which are used wherever a source reference is needed (in calls such as #alDeleteSources and #alSourcei). +about: + + +
      ParametersDescription
      nthe number of sources To be generated
      sourcespointer To an array of ALuint values which will store the names of the New sources

      + + + +
      Possible Error StatesDescription
      AL_OUT_OF_MEMORYThere is not enough memory To generate all the requested sources.
      AL_INVALID_VALUEThere are not enough non-memory resources To create all the requested sources, or the array pointer is not valid.
      AL_INVALID_OPERATIONThere is no context To create sources in.

      +If the requested number of sources cannot be created, an error will be generated which can be detected with #alGetError. If an error occurs, no sources will be generated. If n equals zero, #alGenSources does nothing and does not Return an error. +End Rem +Global alGenSources( n,sources:Int Ptr )=P("alGenSources") +Rem +bbdoc: This function deletes one or more sources. +about: + + +
      ParametersDescription
      nthe number of sources to be deleted
      sourcespointer to an array of source names identifying the sources to be deleted

      + + +
      Possible Error StatesDescription
      AL_INVALID_NAMEat least one specified source is not valid, or an attempt is being made to delete more sources than exist.
      AL_INVALID_OPERATIONThere is no current context.

      +If the requested number of sources cannot be deleted, an error will be generated which can be detected with #alGetError. If an error occurs, no sources will be deleted. If n equals zero, #alDeleteSources does nothing and will not return an error.

      +A playing source can be deleted - the source will be stopped and then deleted. +End Rem +Global alDeleteSources( n,sources:Int Ptr )=P("alDeleteSources") +Rem +bbdoc: This function tests if a source name is valid, returning AL_TRUE if valid and AL_FALSE if not. +about: + +
      ParametersDescription
      sida source name to be tested for validity

      + + +
      Possible Error StatesDescription
      AL_INVALID_OPERATIONThere is no current context.

      +End Rem +Global alIsSource( sid )=P("alIsSource") +Rem +bbdoc: This function sets a floating point property of a source. The relevant properties are listed in the table Source Properties. +about: + + + +
      ParametersDescription
      sidsource name whose attribute is being set
      paramthe name of the attribute to set:
      AL_PITCH
      AL_GAIN
      AL_MAX_DISTANCE
      AL_ROLLOFF_FACTOR
      AL_REFERENCE_DISTANCE
      AL_MIN_GAIN
      AL_MAX_GAIN
      AL_CONE_OUTER_GAIN
      valuethe value to set the attribute t

      + + + + +
      Possible Error StatesDescription
      AL_INVALID_VALUEThe value given is out of range.
      AL_INVALID_ENUMThe specified parameter is not valid.
      AL_INVALID_NAMEThe specified source name is not valid.
      AL_INVALID_OPERATIONThere is no current context.

      +End Rem +Global alSourcef( sid,param,value# )=P("alSourcef") +Rem +bbdoc: This function sets a source property requiring three floating point values. The relevant properties are listed in the table Source Properties. +about: + + + +
      ParametersDescription
      sidsource name whose attribute is being set
      paramthe name of the attribute to set:
      AL_POSITION
      AL_VELOCITY
      AL_DIRECTION
      v1, v2, v3the three ALfloat values which the attribute will be set to

      + + + + +
      Possible Error StatesDescription
      AL_INVALID_VALUEThe value given is out of range.
      AL_INVALID_ENUMThe specified parameter is not valid.
      AL_INVALID_NAMEThe specified source name is not valid.
      AL_INVALID_OPERATIONThere is no current context.

      +This function is an alternative to alSourcefv. +End Rem +Global alSource3f( sid,param,value1#,value2#,value3# )=P("alSource3f") +Rem +bbdoc: This function sets a source property requiring three floating point values. The relevant properties are listed in the table Source Properties. +about: + + + +
      ParametersDescription
      sidsource name whose attribute is being set
      paramthe name of the attribute to set:
      AL_POSITION
      AL_VELOCITY
      AL_DIRECTION
      valuesa pointer to the vector to set the attribute to

      + + + + +
      Possible Error StatesDescription
      AL_INVALID_VALUEThe value given is out of range.
      AL_INVALID_ENUMThe specified parameter is not valid.
      AL_INVALID_NAMEThe specified source name is not valid.
      AL_INVALID_OPERATIONThere is no current context.

      +This function is an alternative to alSource3f. +End Rem +Global alSourcefv( sid,param,values:Float Ptr )=P("alSourcefv") +Rem +bbdoc: This function sets an integer property of a source. The relevant properties are listed in the table Source Properties. +about: + + + +
      ParametersDescription
      sidsource name whose attribute is being set
      paramthe name of the attribute to set:
      AL_SOURCE_RELATIVE
      AL_CONE_INNER_ANGLE
      AL_CONE_OUTER_ANGLE
      AL_LOOPING
      AL_BUFFER
      AL_SOURCE_STATE
      valuea pointer to the vector to set the attribute to

      + + + + +
      Possible Error StatesDescription
      AL_INVALID_VALUEThe value given is out of range.
      AL_INVALID_ENUMThe specified parameter is not valid.
      AL_INVALID_NAMEThe specified source name is not valid.
      AL_INVALID_OPERATIONThere is no current context.

      +The buffer name zero is reserved as a "NULL Buffer" and is accepted by alSourcei(..., AL_BUFFER, ...) as a valid buffer of zero length. The NULL Buffer is extremely useful for detaching buffers from a source which were attached using this call or with alSourceQueueBuffers. +End Rem +Global alSourcei( sid,param,value )=P("alSourcei") +Rem +bbdoc: This function sets an integer property of a source. The relevant properties are listed in the table Source Properties. +about: + + + +
      ParametersDescription
      sidsource name whose attribute is being set
      paramthe name of the attribute to set:
      AL_POSITION
      AL_VELOCITY
      AL_DIRECTION
      value1, value2, value3the values to set the attribute to

      + + + + +
      Possible Error StatesDescription
      AL_INVALID_VALUEThe value given is out of range.
      AL_INVALID_ENUMThe specified parameter is not valid.
      AL_INVALID_NAMEThe specified source name is not valid.
      AL_INVALID_OPERATIONThere is no current context.

      +End Rem +Global alSource3i( sid,param,value1,value2,value3 )=P("alSource3i") +Rem +bbdoc: This function sets an integer property of a source. The relevant properties are listed in the table Source Properties. +about: + + + +
      ParametersDescription
      sidsource name whose attribute is being set
      paramthe name of the attribute to set:
      AL_POSITION
      AL_VELOCITY
      AL_DIRECTION
      valuesthe values to set the attribute to

      + + + + +
      Possible Error StatesDescription
      AL_INVALID_VALUEThe value given is out of range.
      AL_INVALID_ENUMThe specified parameter is not valid.
      AL_INVALID_NAMEThe specified source name is not valid.
      AL_INVALID_OPERATIONThere is no current context.

      +End Rem +Global alSourceiv( sid,param,values:Int Ptr )=P("alSourceiv") +Rem +bbdoc: This function retrieves a floating point property of a source. The relevant properties are listed in the table Source Properties. +about: + + + +
      ParametersDescription
      sidsource name whose attribute is being retrieved
      paramthe name of the attribute to retrieve:
      AL_PITCH
      AL_GAIN
      AL_MIN_GAIN
      AL_MAX_GAIN
      AL_MAX_DISTANCE
      AL_ROLLOFF_FACTOR
      AL_CONE_OUTER_GAIN
      AL_CONE_INNER_ANGLE
      AL_CONE_OUTER_ANGLE
      AL_REFERENCE_DISTANCE
      valuea pointer to the floating point value being retrieved

      + + + + +
      Possible Error StatesDescription
      AL_INVALID_VALUEThe value given is out of range.
      AL_INVALID_ENUMThe specified parameter is not valid.
      AL_INVALID_NAMEThe specified source name is not valid.
      AL_INVALID_OPERATIONThere is no current context.

      +End Rem +Global alGetSourcef( sid,param,value:Float Ptr )=P("alGetSourcef") +Rem +bbdoc: This function retrieves three floating point values representing a property of a source. The relevant properties are listed in the table Source Properties. +about: + + + +
      ParametersDescription
      sidsource name whose attribute is being retrieved
      paramthe name of the attribute to retrieve:
      AL_POSITION
      AL_VELOCITY
      AL_DIRECTION
      value1,value2,value3pointers to the values to retrieve

      + + + + +
      Possible Error StatesDescription
      AL_INVALID_VALUEThe value given is out of range.
      AL_INVALID_ENUMThe specified parameter is not valid.
      AL_INVALID_NAMEThe specified source name is not valid.
      AL_INVALID_OPERATIONThere is no current context.

      +End Rem +Global alGetSource3f( sid,param,value1:Float Ptr,value2:Float Ptr,value3:Float Ptr )=P("alGetSource3f") +Rem +bbdoc: This function retrieves a floating point-vector property of a source. The relevant properties are listed in the table Source Properties. +about: + + + +
      ParametersDescription
      sidsource name whose attribute is being retrieved
      paramthe name of the attribute to retrieve:
      AL_POSITION
      AL_VELOCITY
      AL_DIRECTION
      valuesa pointer to the vector to retrieve

      + + + + +
      Possible Error StatesDescription
      AL_INVALID_VALUEThe value given is out of range.
      AL_INVALID_ENUMThe specified parameter is not valid.
      AL_INVALID_NAMEThe specified source name is not valid.
      AL_INVALID_OPERATIONThere is no current context.

      +End Rem +Global alGetSourcefv( sid,param,values:Float Ptr )=P("alGetSourcefv") +Rem +bbdoc: This function retrieves an integer property of a source. The relevant properties are listed in the table Source Properties. +about: + + + +
      ParametersDescription
      sidsource name whose attribute is being retrieved
      pnamethe name of the attribute to retrieve:
      AL_SOURCE_RELATIVE
      AL_BUFFER
      AL_SOURCE_STATE
      AL_BUFFERS_QUEUED
      AL_BUFFERS_PROCESSED
      valuea pointer to the integer value being retrieved

      + + + + +
      Possible Error StatesDescription
      AL_INVALID_VALUEThe value given is out of range.
      AL_INVALID_ENUMThe specified parameter is not valid.
      AL_INVALID_NAMEThe specified source name is not valid.
      AL_INVALID_OPERATIONThere is no current context.

      +End Rem +Global alGetSourcei( sid,param,value:Int Ptr )=P("alGetSourcei") +Rem +bbdoc: This function retrieves an integer property of a source. The relevant properties are listed in the table Source Properties. +about: + + + +
      ParametersDescription
      sidsource name whose attribute is being retrieved
      pnamethe name of the attribute to retrieve:
      AL_POSITION
      AL_VELOCITY
      AL_DIRECTION
      value1, value2, value3pointers to the integer values being retrieved

      + + + + +
      Possible Error StatesDescription
      AL_INVALID_VALUEThe value given is out of range.
      AL_INVALID_ENUMThe specified parameter is not valid.
      AL_INVALID_NAMEThe specified source name is not valid.
      AL_INVALID_OPERATIONThere is no current context.

      +End Rem +Global alGetSource3i( sid,param,value1:Int Ptr,value2:Int Ptr,value3:Int Ptr )=P("alGetSource3i") +Rem +bbdoc: This function retrieves an integer property of a source. The relevant properties are listed in the table Source Properties. +about: + + + +
      ParametersDescription
      sidsource name whose attribute is being retrieved
      pnamethe name of the attribute to retrieve:
      AL_POSITION
      AL_VELOCITY
      AL_DIRECTION
      valuespointers to the integer values being retrieved

      + + + + +
      Possible Error StatesDescription
      AL_INVALID_VALUEThe value given is out of range.
      AL_INVALID_ENUMThe specified parameter is not valid.
      AL_INVALID_NAMEThe specified source name is not valid.
      AL_INVALID_OPERATIONThere is no current context.

      +End Rem +Global alGetSourceiv( sid,param,values:Int Ptr )=P("alGetSourceiv") + +Rem +bbdoc: This function plays a set of sources. +about: + + +
      ParametersDescription
      nsthe number of sources to be played
      sidsa pointer to an array of sources to be played

      + + + +
      Possible Error StatesDescription
      AL_INVALID_VALUEThe value pointer given is not valid.
      AL_INVALID_NAMEThe specified source name is not valid.
      AL_INVALID_OPERATIONThere is no current context.

      +The playing sources will have their state changed to AL_PLAYING. When called on a source which is already playing, the source will restart at the beginning. When the attached buffer(s) are done playing, the source will progress to the AL_STOPPED state. +End Rem +Global alSourcePlayv( ns,sids:Int Ptr )=P("alSourcePlayv") +Rem +bbdoc: This function stops a set of sources. +about: + + +
      ParametersDescription
      nsthe number of sources to stop
      sidsa pointer to an array of sources to be stopped

      + + + +
      Possible Error StatesDescription
      AL_INVALID_VALUEThe value pointer given is not valid.
      AL_INVALID_NAMEThe specified source name is not valid.
      AL_INVALID_OPERATIONThere is no current context.

      +The stopped sources will have their state changed to AL_STOPPED. +End Rem +Global alSourceStopv( ns,sids:Int Ptr )=P("alSourceStopv") +Rem +bbdoc: This function stops a set of sources and sets all their states to AL_INITIAL. +about: + + +
      ParametersDescription
      nsthe number of sources to be rewound
      sidsa pointer to an array of sources to be rewound

      + + + +
      Possible Error StatesDescription
      AL_INVALID_VALUEThe value pointer given is not valid.
      AL_INVALID_NAMEThe specified source name is not valid.
      AL_INVALID_OPERATIONThere is no current context.

      +End Rem +Global alSourceRewindv( ns,sids:Int Ptr )=P("alSourceRewindv") +Rem +bbdoc: This function pauses a set of sources. +about: + + +
      ParametersDescription
      nsthe number of sources to be paused
      sidsa pointer to an array of sources to be paused

      + + + +
      Possible Error StatesDescription
      AL_INVALID_VALUEThe value pointer given is not valid.
      AL_INVALID_NAMEThe specified source name is not valid.
      AL_INVALID_OPERATIONThere is no current context.

      +The paused sources will have their state changed to AL_PAUSED. +End Rem +Global alSourcePausev( ns,sids:Int Ptr )=P("alSourcePausev") +Rem +bbdoc: This function plays a source. +about: + +
      ParametersDescription
      sidthe name of the source to be played

      + + +
      Possible Error StatesDescription
      AL_INVALID_NAMEThe specified source name is not valid.
      AL_INVALID_OPERATIONThere is no current context.

      +The playing source will have its state changed to AL_PLAYING. When called on a source which is already playing, the source will restart at the beginning. When the attached buffer(s) are done playing, the source will progress to the AL_STOPPED state. +End Rem +Global alSourcePlay( sid )=P("alSourcePlay") +Rem +bbdoc: This function stops a source. +about: + +
      ParametersDescription
      sidthe name of the source to be stopped

      + + +
      Possible Error StatesDescription
      AL_INVALID_NAMEThe specified source name is not valid.
      AL_INVALID_OPERATIONThere is no current context.

      +The stopped source will have its state changed to AL_STOPPED. +End Rem +Global alSourceStop( sid )=P("alSourceStop") +Rem +bbdoc: This function stops the source and sets its state to AL_INITIAL. +about: + +
      ParametersDescription
      sidthe name of the source to be rewound

      + + +
      Possible Error StatesDescription
      AL_INVALID_NAMEThe specified source name is not valid.
      AL_INVALID_OPERATIONThere is no current context.

      +End Rem +Global alSourceRewind( sid )=P("alSourceRewind") +Rem +bbdoc: This function pauses a source. +about: + +
      ParametersDescription
      sidthe name of the source to be paused

      + + +
      Possible Error StatesDescription
      AL_INVALID_NAMEThe specified source name is not valid.
      AL_INVALID_OPERATIONThere is no current context.

      +The paused source will have its state changed to AL_PAUSED. +End Rem +Global alSourcePause( sid )=P("alSourcePause") +Rem +bbdoc: This function queues a set of buffers on a source. All buffers attached to a source will be played in sequence, and the number of processed buffers can be detected using an #alSourcei call to retrieve AL_BUFFERS_PROCESSED. +about: + + + +
      ParametersDescription
      sidthe name of the source to queue buffers onto
      numEntriesthe number of buffers to be queued
      bidsa pointer to an array of buffer names to be queued

      + + +
      Possible Error StatesDescription
      AL_INVALID_NAMEat least one specified buffer name is not valid, or the specified source name is not valid.
      AL_INVALID_OPERATIONThere is no current context, an attempt was made to add a new buffer which is not the same format as the buffers already in the queue, or the source already has a static buffer attached.

      +When first created, a source will be of type AL_UNDETERMINED. A successful #alSourceQueueBuffers call will change the source type to AL_STREAMING. +End Rem +Global alSourceQueueBuffers( sid,numEntries,bids:Int Ptr )=P("alSourceQueueBuffers") +Rem +bbdoc: This function unqueues a set of buffers attached to a source. The number of processed buffers can be detected using an #alSourcei call to retrieve AL_BUFFERS_PROCESSED, which is the maximum number of buffers that can be unqueued using this call. +about: + + + +
      ParametersDescription
      sidthe name of the source to unqueue buffers from
      numEntriesthe number of buffers to be unqueued
      bidsa pointer to an array of buffer names that were removed

      + + + +
      Possible Error StatesDescription
      AL_INVALID_VALUEat least one buffer can not be unqueued because it has not been processed yet.
      AL_INVALID_NAMEThe specified source name is not valid.
      AL_INVALID_OPERATIONThere is no current context.

      +The unqueue operation will only take place if all n buffers can be removed from the queue. +End Rem +Global alSourceUnqueueBuffers( sid,numEntries,bids:Int Ptr )=P("alSourceUnqueueBuffers") + +Rem +bbdoc: This function selects the OpenAL Doppler factor value. +about: + +
      ParametersDescription
      valuethe Doppler scale value to set

      + + +
      Possible Error StatesDescription
      AL_INVALID_VALUEThe specified value is not valid.
      AL_INVALID_OPERATIONThere is no current context.

      +The default Doppler factor value is 1.0. +End Rem +Global alDopplerFactor( value# )=P("alDopplerFactor") +Rem +bbdoc: This function selects the speed of sound for use in Doppler calculations. +about: + +
      ParametersDescription
      valuethe speed of sound value to set

      + + +
      Possible Error StatesDescription
      AL_INVALID_VALUEThe specified value is not valid.
      AL_INVALID_OPERATIONThere is no current context.

      +The default speed of sound value is 343.3. +End Rem +Global alDopplerVelocity( value# )=P("alDopplerVelocity") +Rem +bbdoc: This function selects the speed of sound for use in Doppler calculations. +about: + +
      ParametersDescription
      value#the speed of sound value to set

      + + +
      Possible Error StatesDescription
      AL_INVALID_VALUEThe specified value is not valid.
      AL_INVALID_OPERATIONThere is no current context.

      +The default speed of sound value is 343.3. +End Rem +Global alSpeedOfSound( value# )=P("alSpeedOfSound") +Rem +bbdoc:This function selects the OpenAL distance model.

      The AL_INVERSE_DISTANCE model works according to the following formula:

      G_dB = AL_GAIN - 20log10(1 + AL_ROLLOFF_FACTOR*(distance - AL_REFERENCE_DISTANCE)/AL_REFERENCE_DISTANCE));
      G_dB = min(G_dB, AL_MAX_GAIN);
      G_dB = max(G_dB, AL_MIN_GAIN);

      The AL_INVERSE_DISTANCE_CLAMPED model works according to the following formula:

      distance = max(distance, AL_REFERENCE_DISTANCE);
      distance = min(distance, AL_MAX_DISTANCE);
      G_dB = AL_GAIN - 20log10(1 + AL_ROLLOFF_FACTOR*(distance - AL_REFERENCE_DISTANCE)/AL_REFERENCE_DISTANCE));
      G_dB = min(G_dB, AL_MAX_GAIN);
      G_dB = max(G_dB, AL_MIN_GAIN);

      The AL_NONE model works according to the following formula:

      G_db = AL_GAIN;
      +about: + +
      ParametersDescription
      distanceModelthe distance model to be set:
      AL_NONE
      AL_INVERSE_DISTANCE
      AL_INVERSE_DISTANCE_CLAMPED

      + + +
      Possible Error StatesDescription
      AL_INVALID_VALUEThe specified distance model is not valid.
      AL_INVALID_OPERATIONThere is no current context.

      +The default distance model in OpenAL is AL_INVERSE_DISTANCE_CLAMPED. +End Rem +Global alDistanceModel( distanceModel )=P("alDistanceModel") diff --git a/mod/pub.mod/openal.mod/openal.c b/mod/pub.mod/openal.mod/openal.c new file mode 100644 index 0000000..75fb47c --- /dev/null +++ b/mod/pub.mod/openal.mod/openal.c @@ -0,0 +1,89 @@ + +#if _WIN32 + +#include + +static HMODULE openAL; + +int LoadOpenAL(){ + + openAL=LoadLibrary( "OpenAL32.dll" ); + + return openAL!=0; +} + +void *GetOpenALFunction( const char *fname ){ + + if( !openAL ) return 0; + + return GetProcAddress( openAL,fname ); +} + +#endif + +#if __APPLE__ + +#import + +static CFBundleRef openAL; + +static CFBundleRef OpenBundle( const char *path ){ + CFURLRef url; + CFStringRef str; + CFBundleRef bundle; + str=CFStringCreateWithCString( kCFAllocatorDefault,path,kCFStringEncodingASCII ); + url=CFURLCreateWithFileSystemPath( kCFAllocatorDefault,str,kCFURLPOSIXPathStyle,true ); + bundle=CFBundleCreate( kCFAllocatorDefault,url ); + CFRelease( url ); + CFRelease( str ); + return bundle; +} + +int LoadOpenAL(){ + + openAL=OpenBundle( "/System/Library/Frameworks/OpenAL.framework" ); + if( !openAL ) openAL=OpenBundle( "/Library/Frameworks/OpenAL.framework" ); + + return openAL!=0; +} + +void *GetOpenALFunction( const char *fname ){ + void *p; + CFStringRef str; + + if( !openAL ) return 0; + + str=CFStringCreateWithCString( kCFAllocatorDefault,fname,kCFStringEncodingASCII ); + + p=CFBundleGetFunctionPointerForName( openAL,str ); + + CFRelease( str ); + + return p; +} + +#endif + +#if __linux + +#include + +static void *openAL; + +int LoadOpenAL(){ + + openAL=dlopen( "libopenal.so",RTLD_NOW ); + if( !openAL ) openAL=dlopen( "libopenal.so.0",RTLD_NOW ); + if( !openAL ) openAL=dlopen( "libopenal.so.0.0.8",RTLD_NOW ); + + return openAL!=0; +} + +void *GetOpenALFunction( const char *fname ){ + + if( !openAL ) return 0; + + return dlsym( openAL,fname ); +} + +#endif diff --git a/mod/pub.mod/opengl.mod/doc/intro.bbdoc b/mod/pub.mod/opengl.mod/doc/intro.bbdoc new file mode 100644 index 0000000..35cde3a --- /dev/null +++ b/mod/pub.mod/opengl.mod/doc/intro.bbdoc @@ -0,0 +1,5 @@ + +The OpenGL module provides the full OpenGL 1.1 command set. + +To use OpenGL, you must first create an %{OpenGL context}. The #{OpenGL Graphics} module +provides a simple mechanism for creating OpenGL contexts. diff --git a/mod/pub.mod/opengl.mod/glu.bmx b/mod/pub.mod/opengl.mod/glu.bmx new file mode 100644 index 0000000..7bae688 --- /dev/null +++ b/mod/pub.mod/opengl.mod/glu.bmx @@ -0,0 +1,60 @@ + +Strict + +Extern "Os" + +Function gluBeginCurve(nurbs_nurb:Byte Ptr) +Function gluBeginPolygon(tesselator_tess:Byte Ptr) +Function gluBeginSurface(nurbs_nurb:Byte Ptr) +Function gluBeginTrim(nurbs_nurb:Byte Ptr) +Function gluBuild1DMipmapLevels(enum_target,int_internalFormat,sizei_width,enum_format,enum_type,int_level,int_base,int_max,void_data:Byte Ptr) +Function gluBuild1DMipmaps(enum_target,int_internalFormat,sizei_width,enum_format,enum_type,void_data:Byte Ptr) +Function gluBuild2DMipmapLevels(enum_target,int_internalFormat,sizei_width,sizei_height,enum_format,enum_type,int_level,int_base,int_max,void_data:Byte Ptr) +Function gluBuild2DMipmaps(enum_target,int_internalFormat,sizei_width,sizei_height,enum_format,enum_type,void_data:Byte Ptr) +Function gluBuild3DMipmapLevels(enum_target,int_internalFormat,sizei_width,sizei_height,sizei_depth,enum_format,enum_type,int_level,int_base,int_max,void_data:Byte Ptr) +Function gluBuild3DMipmaps(enum_target,int_internalFormat,sizei_width,sizei_height,sizei_depth,enum_format,enum_type,void_data:Byte Ptr) +Function gluCylinder(quadric_quad:Byte Ptr,double_base!,double_top!,double_height!,int_slices,int_stacks) +Function gluDeleteNurbsRenderer(nurbs_nurb:Byte Ptr) +Function gluDeleteQuadric(quadric_quad:Byte Ptr) +Function gluDeleteTess(tesselator_tess:Byte Ptr) +Function gluDisk(quadric_quad:Byte Ptr,double_inner!,double_outer!,int_slices,int_loops) +Function gluEndCurve(nurbs_nurb:Byte Ptr) +Function gluEndPolygon(tesselator_tess:Byte Ptr) +Function gluEndSurface(nurbs_nurb:Byte Ptr) +Function gluEndTrim(nurbs_nurb:Byte Ptr) +Function gluGetNurbsProperty(nurbs_nurb:Byte Ptr,enum_property,float_data# Ptr) +Function gluGetTessProperty(tesselator_tess:Byte Ptr,enum_which,double_data! Ptr) +Function gluLoadSamplingMatrices(nurbs_nurb:Byte Ptr,float_model# Ptr,float_perspective# Ptr,int_view Ptr) +Function gluLookAt(double_eyeX!,double_eyeY!,double_eyeZ!,double_centerX!,double_centerY!,double_centerZ!,double_upX!,double_upY!,double_upZ!) +Function gluNewNurbsRenderer:Byte Ptr() +Function gluNewQuadric:Byte Ptr() +Function gluNewTess:Byte Ptr() +Function gluNextContour(tesselator_tess:Byte Ptr,enum_type) +Function gluNurbsCallbackData(nurbs_nurb:Byte Ptr,void_userData:Byte Ptr) +Function gluNurbsCallbackDataEXT(nurbs_nurb:Byte Ptr,void_userData:Byte Ptr) +Function gluNurbsCurve(nurbs_nurb:Byte Ptr,int_knotCount,float_knots# Ptr,int_stride,float_control# Ptr,int_order,enum_type) +Function gluNurbsProperty(nurbs_nurb:Byte Ptr,enum_property,float_value#) +Function gluNurbsSurface(nurbs_nurb:Byte Ptr,int_sKnotCount,float_sKnots# Ptr,int_tKnotCount,float_tKnots# Ptr,int_sStride,int_tStride,float_control# Ptr,int_sOrder,int_tOrder,enum_type) +Function gluOrtho2D(double_left!,double_right!,double_bottom!,double_top!) +Function gluPartialDisk(quadric_quad:Byte Ptr,double_inner!,double_outer!,int_slices,int_loops,double_start!,double_sweep!) +Function gluPerspective(double_fovy!,double_aspect!,double_zNear!,double_zFar!) +Function gluPickMatrix(double_x!,double_y!,double_delX!,double_delY!,int_viewport Ptr) +Function gluProject(double_objX!,double_objY!,double_objZ!,double_model! Ptr,double_proj! Ptr,int_view Ptr,double_winX! Ptr,double_winY! Ptr,double_winZ! Ptr) +Function gluPwlCurve(nurbs_nurb:Byte Ptr,int_count,float_data# Ptr,int_stride,enum_type) +Function gluQuadricDrawStyle(quadric_quad:Byte Ptr,enum_draw) +Function gluQuadricNormals(quadric_quad:Byte Ptr,enum_normal) +Function gluQuadricOrientation(quadric_quad:Byte Ptr,enum_orientation) +Function gluQuadricTexture(quadric_quad:Byte Ptr,boolean_texture@) +Function gluScaleImage(enum_format,sizei_wIn,sizei_hIn,enum_typeIn,void_dataIn:Byte Ptr,sizei_wOut,sizei_hOut,enum_typeOut,void_dataOut:Byte Ptr) +Function gluSphere(quadric_quad:Byte Ptr,double_radius!,int_slices,int_stacks) +Function gluTessBeginContour(tesselator_tess:Byte Ptr) +Function gluTessBeginPolygon(tesselator_tess:Byte Ptr,void_data:Byte Ptr) +Function gluTessEndContour(tesselator_tess:Byte Ptr) +Function gluTessEndPolygon(tesselator_tess:Byte Ptr) +Function gluTessNormal(tesselator_tess:Byte Ptr,double_valueX!,double_valueY!,double_valueZ!) +Function gluTessProperty(tesselator_tess:Byte Ptr,enum_which,double_data!) +Function gluTessVertex(tesselator_tess:Byte Ptr,double_location! Ptr,void_data:Byte Ptr) +Function gluUnProject(double_winX!,double_winY!,double_winZ!,double_model! Ptr,double_proj! Ptr,int_view Ptr,double_objX! Ptr,double_objY! Ptr,double_objZ! Ptr) +Function gluUnProject4(double_winX!,double_winY!,double_winZ!,double_clipW!,double_model! Ptr,double_proj! Ptr,int_view Ptr,double_nearVal!,double_farVal!,double_objX! Ptr,double_objY! Ptr,double_objZ! Ptr,double_objW! Ptr) + +End Extern diff --git a/mod/pub.mod/opengl.mod/opengl.bmx b/mod/pub.mod/opengl.mod/opengl.bmx new file mode 100644 index 0000000..514352b --- /dev/null +++ b/mod/pub.mod/opengl.mod/opengl.bmx @@ -0,0 +1,900 @@ + +Strict + +Rem +bbdoc: Graphics/OpenGL 1.1 +End Rem +Module Pub.OpenGL + +ModuleInfo "Version: 1.02" +ModuleInfo "License: SGI Free Software License B" +ModuleInfo "Modserver: BRL" + +ModuleInfo "History: 1.02 Release" +ModuleInfo "History: Restored GLU" + +?MacOS +Import "-framework AGL" +Import "-framework OpenGL" +?Win32 +Import "-lglu32" +Import "-lopengl32" +?Linux +Import "-lGL" +Import "-lGLU" +? + +Import "glu.bmx" + +Extern "Os" + +Const GL_ACCUM=$0100 +Const GL_LOAD=$0101 +Const GL_RETURN=$0102 +Const GL_MULT=$0103 +Const GL_ADD=$0104 +Const GL_NEVER=$0200 +Const GL_LESS=$0201 +Const GL_EQUAL=$0202 +Const GL_LEQUAL=$0203 +Const GL_GREATER=$0204 +Const GL_NOTEQUAL=$0205 +Const GL_GEQUAL=$0206 +Const GL_ALWAYS=$0207 +Const GL_CURRENT_BIT=$00000001 +Const GL_POINT_BIT=$00000002 +Const GL_LINE_BIT=$00000004 +Const GL_POLYGON_BIT=$00000008 +Const GL_POLYGON_STIPPLE_BIT=$00000010 +Const GL_PIXEL_MODE_BIT=$00000020 +Const GL_LIGHTING_BIT=$00000040 +Const GL_FOG_BIT=$00000080 +Const GL_DEPTH_BUFFER_BIT=$00000100 +Const GL_ACCUM_BUFFER_BIT=$00000200 +Const GL_STENCIL_BUFFER_BIT=$00000400 +Const GL_VIEWPORT_BIT=$00000800 +Const GL_TRANSFORM_BIT=$00001000 +Const GL_ENABLE_BIT=$00002000 +Const GL_COLOR_BUFFER_BIT=$00004000 +Const GL_HINT_BIT=$00008000 +Const GL_EVAL_BIT=$00010000 +Const GL_LIST_BIT=$00020000 +Const GL_TEXTURE_BIT=$00040000 +Const GL_SCISSOR_BIT=$00080000 +Const GL_ALL_ATTRIB_BITS=$000fffff +Const GL_POINTS=$0000 +Const GL_LINES=$0001 +Const GL_LINE_LOOP=$0002 +Const GL_LINE_STRIP=$0003 +Const GL_TRIANGLES=$0004 +Const GL_TRIANGLE_STRIP=$0005 +Const GL_TRIANGLE_FAN=$0006 +Const GL_QUADS=$0007 +Const GL_QUAD_STRIP=$0008 +Const GL_POLYGON=$0009 +Const GL_ZERO=0 +Const GL_ONE=1 +Const GL_SRC_COLOR=$0300 +Const GL_ONE_MINUS_SRC_COLOR=$0301 +Const GL_SRC_ALPHA=$0302 +Const GL_ONE_MINUS_SRC_ALPHA=$0303 +Const GL_DST_ALPHA=$0304 +Const GL_ONE_MINUS_DST_ALPHA=$0305 +Const GL_DST_COLOR=$0306 +Const GL_ONE_MINUS_DST_COLOR=$0307 +Const GL_SRC_ALPHA_SATURATE=$0308 +Const GL_TRUE=1 +Const GL_FALSE=0 +Const GL_CLIP_PLANE0=$3000 +Const GL_CLIP_PLANE1=$3001 +Const GL_CLIP_PLANE2=$3002 +Const GL_CLIP_PLANE3=$3003 +Const GL_CLIP_PLANE4=$3004 +Const GL_CLIP_PLANE5=$3005 +Const GL_BYTE=$1400 +Const GL_UNSIGNED_BYTE=$1401 +Const GL_SHORT=$1402 +Const GL_UNSIGNED_SHORT=$1403 +Const GL_INT=$1404 +Const GL_UNSIGNED_INT=$1405 +Const GL_FLOAT=$1406 +Const GL_2_BYTES=$1407 +Const GL_3_BYTES=$1408 +Const GL_4_BYTES=$1409 +Const GL_DOUBLE=$140A +Const GL_NONE=0 +Const GL_FRONT_LEFT=$0400 +Const GL_FRONT_RIGHT=$0401 +Const GL_BACK_LEFT=$0402 +Const GL_BACK_RIGHT=$0403 +Const GL_FRONT=$0404 +Const GL_BACK=$0405 +Const GL_LEFT=$0406 +Const GL_RIGHT=$0407 +Const GL_FRONT_AND_BACK=$0408 +Const GL_AUX0=$0409 +Const GL_AUX1=$040A +Const GL_AUX2=$040B +Const GL_AUX3=$040C +Const GL_NO_ERROR=0 +Const GL_INVALID_ENUM=$0500 +Const GL_INVALID_VALUE=$0501 +Const GL_INVALID_OPERATION=$0502 +Const GL_STACK_OVERFLOW=$0503 +Const GL_STACK_UNDERFLOW=$0504 +Const GL_OUT_OF_MEMORY=$0505 +Const GL_2D=$0600 +Const GL_3D=$0601 +Const GL_3D_COLOR=$0602 +Const GL_3D_COLOR_TEXTURE=$0603 +Const GL_4D_COLOR_TEXTURE=$0604 +Const GL_PASS_THROUGH_TOKEN=$0700 +Const GL_POINT_TOKEN=$0701 +Const GL_LINE_TOKEN=$0702 +Const GL_POLYGON_TOKEN=$0703 +Const GL_BITMAP_TOKEN=$0704 +Const GL_DRAW_PIXEL_TOKEN=$0705 +Const GL_COPY_PIXEL_TOKEN=$0706 +Const GL_LINE_RESET_TOKEN=$0707 +Const GL_EXP=$0800 +Const GL_EXP2=$0801 +Const GL_CW=$0900 +Const GL_CCW=$0901 +Const GL_COEFF=$0A00 +Const GL_ORDER=$0A01 +Const GL_DOMAIN=$0A02 +Const GL_CURRENT_COLOR=$0B00 +Const GL_CURRENT_INDEX=$0B01 +Const GL_CURRENT_NORMAL=$0B02 +Const GL_CURRENT_TEXTURE_COORDS=$0B03 +Const GL_CURRENT_RASTER_COLOR=$0B04 +Const GL_CURRENT_RASTER_INDEX=$0B05 +Const GL_CURRENT_RASTER_TEXTURE_COORDS=$0B06 +Const GL_CURRENT_RASTER_POSITION=$0B07 +Const GL_CURRENT_RASTER_POSITION_VALID=$0B08 +Const GL_CURRENT_RASTER_DISTANCE=$0B09 +Const GL_POINT_SMOOTH=$0B10 +Const GL_POINT_SIZE=$0B11 +Const GL_POINT_SIZE_RANGE=$0B12 +Const GL_POINT_SIZE_GRANULARITY=$0B13 +Const GL_LINE_SMOOTH=$0B20 +Const GL_LINE_WIDTH=$0B21 +Const GL_LINE_WIDTH_RANGE=$0B22 +Const GL_LINE_WIDTH_GRANULARITY=$0B23 +Const GL_LINE_STIPPLE=$0B24 +Const GL_LINE_STIPPLE_PATTERN=$0B25 +Const GL_LINE_STIPPLE_REPEAT=$0B26 +Const GL_LIST_MODE=$0B30 +Const GL_MAX_LIST_NESTING=$0B31 +Const GL_LIST_BASE=$0B32 +Const GL_LIST_INDEX=$0B33 +Const GL_POLYGON_MODE=$0B40 +Const GL_POLYGON_SMOOTH=$0B41 +Const GL_POLYGON_STIPPLE=$0B42 +Const GL_EDGE_FLAG=$0B43 +Const GL_CULL_FACE=$0B44 +Const GL_CULL_FACE_MODE=$0B45 +Const GL_FRONT_FACE=$0B46 +Const GL_LIGHTING=$0B50 +Const GL_LIGHT_MODEL_LOCAL_VIEWER=$0B51 +Const GL_LIGHT_MODEL_TWO_SIDE=$0B52 +Const GL_LIGHT_MODEL_AMBIENT=$0B53 +Const GL_SHADE_MODEL=$0B54 +Const GL_COLOR_MATERIAL_FACE=$0B55 +Const GL_COLOR_MATERIAL_PARAMETER=$0B56 +Const GL_COLOR_MATERIAL=$0B57 +Const GL_FOG=$0B60 +Const GL_FOG_INDEX=$0B61 +Const GL_FOG_DENSITY=$0B62 +Const GL_FOG_START=$0B63 +Const GL_FOG_END=$0B64 +Const GL_FOG_MODE=$0B65 +Const GL_FOG_COLOR=$0B66 +Const GL_DEPTH_RANGE=$0B70 +Const GL_DEPTH_TEST=$0B71 +Const GL_DEPTH_WRITEMASK=$0B72 +Const GL_DEPTH_CLEAR_VALUE=$0B73 +Const GL_DEPTH_FUNC=$0B74 +Const GL_ACCUM_CLEAR_VALUE=$0B80 +Const GL_STENCIL_TEST=$0B90 +Const GL_STENCIL_CLEAR_VALUE=$0B91 +Const GL_STENCIL_FUNC=$0B92 +Const GL_STENCIL_VALUE_MASK=$0B93 +Const GL_STENCIL_FAIL=$0B94 +Const GL_STENCIL_PASS_DEPTH_FAIL=$0B95 +Const GL_STENCIL_PASS_DEPTH_PASS=$0B96 +Const GL_STENCIL_REF=$0B97 +Const GL_STENCIL_WRITEMASK=$0B98 +Const GL_MATRIX_MODE=$0BA0 +Const GL_NORMALIZE=$0BA1 +Const GL_VIEWPORT=$0BA2 +Const GL_MODELVIEW_STACK_DEPTH=$0BA3 +Const GL_PROJECTION_STACK_DEPTH=$0BA4 +Const GL_TEXTURE_STACK_DEPTH=$0BA5 +Const GL_MODELVIEW_MATRIX=$0BA6 +Const GL_PROJECTION_MATRIX=$0BA7 +Const GL_TEXTURE_MATRIX=$0BA8 +Const GL_ATTRIB_STACK_DEPTH=$0BB0 +Const GL_CLIENT_ATTRIB_STACK_DEPTH=$0BB1 +Const GL_ALPHA_TEST=$0BC0 +Const GL_ALPHA_TEST_FUNC=$0BC1 +Const GL_ALPHA_TEST_REF=$0BC2 +Const GL_DITHER=$0BD0 +Const GL_BLEND_DST=$0BE0 +Const GL_BLEND_SRC=$0BE1 +Const GL_BLEND=$0BE2 +Const GL_LOGIC_OP_MODE=$0BF0 +Const GL_INDEX_LOGIC_OP=$0BF1 +Const GL_COLOR_LOGIC_OP=$0BF2 +Const GL_AUX_BUFFERS=$0C00 +Const GL_DRAW_BUFFER=$0C01 +Const GL_READ_BUFFER=$0C02 +Const GL_SCISSOR_BOX=$0C10 +Const GL_SCISSOR_TEST=$0C11 +Const GL_INDEX_CLEAR_VALUE=$0C20 +Const GL_INDEX_WRITEMASK=$0C21 +Const GL_COLOR_CLEAR_VALUE=$0C22 +Const GL_COLOR_WRITEMASK=$0C23 +Const GL_INDEX_MODE=$0C30 +Const GL_RGBA_MODE=$0C31 +Const GL_DOUBLEBUFFER=$0C32 +Const GL_STEREO=$0C33 +Const GL_RENDER_MODE=$0C40 +Const GL_PERSPECTIVE_CORRECTION_HINT=$0C50 +Const GL_POINT_SMOOTH_HINT=$0C51 +Const GL_LINE_SMOOTH_HINT=$0C52 +Const GL_POLYGON_SMOOTH_HINT=$0C53 +Const GL_FOG_HINT=$0C54 +Const GL_TEXTURE_GEN_S=$0C60 +Const GL_TEXTURE_GEN_T=$0C61 +Const GL_TEXTURE_GEN_R=$0C62 +Const GL_TEXTURE_GEN_Q=$0C63 +Const GL_PIXEL_MAP_I_TO_I=$0C70 +Const GL_PIXEL_MAP_S_TO_S=$0C71 +Const GL_PIXEL_MAP_I_TO_R=$0C72 +Const GL_PIXEL_MAP_I_TO_G=$0C73 +Const GL_PIXEL_MAP_I_TO_B=$0C74 +Const GL_PIXEL_MAP_I_TO_A=$0C75 +Const GL_PIXEL_MAP_R_TO_R=$0C76 +Const GL_PIXEL_MAP_G_TO_G=$0C77 +Const GL_PIXEL_MAP_B_TO_B=$0C78 +Const GL_PIXEL_MAP_A_TO_A=$0C79 +Const GL_PIXEL_MAP_I_TO_I_SIZE=$0CB0 +Const GL_PIXEL_MAP_S_TO_S_SIZE=$0CB1 +Const GL_PIXEL_MAP_I_TO_R_SIZE=$0CB2 +Const GL_PIXEL_MAP_I_TO_G_SIZE=$0CB3 +Const GL_PIXEL_MAP_I_TO_B_SIZE=$0CB4 +Const GL_PIXEL_MAP_I_TO_A_SIZE=$0CB5 +Const GL_PIXEL_MAP_R_TO_R_SIZE=$0CB6 +Const GL_PIXEL_MAP_G_TO_G_SIZE=$0CB7 +Const GL_PIXEL_MAP_B_TO_B_SIZE=$0CB8 +Const GL_PIXEL_MAP_A_TO_A_SIZE=$0CB9 +Const GL_UNPACK_SWAP_BYTES=$0CF0 +Const GL_UNPACK_LSB_FIRST=$0CF1 +Const GL_UNPACK_ROW_LENGTH=$0CF2 +Const GL_UNPACK_SKIP_ROWS=$0CF3 +Const GL_UNPACK_SKIP_PIXELS=$0CF4 +Const GL_UNPACK_ALIGNMENT=$0CF5 +Const GL_PACK_SWAP_BYTES=$0D00 +Const GL_PACK_LSB_FIRST=$0D01 +Const GL_PACK_ROW_LENGTH=$0D02 +Const GL_PACK_SKIP_ROWS=$0D03 +Const GL_PACK_SKIP_PIXELS=$0D04 +Const GL_PACK_ALIGNMENT=$0D05 +Const GL_MAP_COLOR=$0D10 +Const GL_MAP_STENCIL=$0D11 +Const GL_INDEX_SHIFT=$0D12 +Const GL_INDEX_OFFSET=$0D13 +Const GL_RED_SCALE=$0D14 +Const GL_RED_BIAS=$0D15 +Const GL_ZOOM_X=$0D16 +Const GL_ZOOM_Y=$0D17 +Const GL_GREEN_SCALE=$0D18 +Const GL_GREEN_BIAS=$0D19 +Const GL_BLUE_SCALE=$0D1A +Const GL_BLUE_BIAS=$0D1B +Const GL_ALPHA_SCALE=$0D1C +Const GL_ALPHA_BIAS=$0D1D +Const GL_DEPTH_SCALE=$0D1E +Const GL_DEPTH_BIAS=$0D1F +Const GL_MAX_EVAL_ORDER=$0D30 +Const GL_MAX_LIGHTS=$0D31 +Const GL_MAX_CLIP_PLANES=$0D32 +Const GL_MAX_TEXTURE_SIZE=$0D33 +Const GL_MAX_PIXEL_MAP_TABLE=$0D34 +Const GL_MAX_ATTRIB_STACK_DEPTH=$0D35 +Const GL_MAX_MODELVIEW_STACK_DEPTH=$0D36 +Const GL_MAX_NAME_STACK_DEPTH=$0D37 +Const GL_MAX_PROJECTION_STACK_DEPTH=$0D38 +Const GL_MAX_TEXTURE_STACK_DEPTH=$0D39 +Const GL_MAX_VIEWPORT_DIMS=$0D3A +Const GL_MAX_CLIENT_ATTRIB_STACK_DEPTH=$0D3B +Const GL_SUBPIXEL_BITS=$0D50 +Const GL_INDEX_BITS=$0D51 +Const GL_RED_BITS=$0D52 +Const GL_GREEN_BITS=$0D53 +Const GL_BLUE_BITS=$0D54 +Const GL_ALPHA_BITS=$0D55 +Const GL_DEPTH_BITS=$0D56 +Const GL_STENCIL_BITS=$0D57 +Const GL_ACCUM_RED_BITS=$0D58 +Const GL_ACCUM_GREEN_BITS=$0D59 +Const GL_ACCUM_BLUE_BITS=$0D5A +Const GL_ACCUM_ALPHA_BITS=$0D5B +Const GL_NAME_STACK_DEPTH=$0D70 +Const GL_AUTO_NORMAL=$0D80 +Const GL_MAP1_COLOR_4=$0D90 +Const GL_MAP1_INDEX=$0D91 +Const GL_MAP1_NORMAL=$0D92 +Const GL_MAP1_TEXTURE_COORD_1=$0D93 +Const GL_MAP1_TEXTURE_COORD_2=$0D94 +Const GL_MAP1_TEXTURE_COORD_3=$0D95 +Const GL_MAP1_TEXTURE_COORD_4=$0D96 +Const GL_MAP1_VERTEX_3=$0D97 +Const GL_MAP1_VERTEX_4=$0D98 +Const GL_MAP2_COLOR_4=$0DB0 +Const GL_MAP2_INDEX=$0DB1 +Const GL_MAP2_NORMAL=$0DB2 +Const GL_MAP2_TEXTURE_COORD_1=$0DB3 +Const GL_MAP2_TEXTURE_COORD_2=$0DB4 +Const GL_MAP2_TEXTURE_COORD_3=$0DB5 +Const GL_MAP2_TEXTURE_COORD_4=$0DB6 +Const GL_MAP2_VERTEX_3=$0DB7 +Const GL_MAP2_VERTEX_4=$0DB8 +Const GL_MAP1_GRID_DOMAIN=$0DD0 +Const GL_MAP1_GRID_SEGMENTS=$0DD1 +Const GL_MAP2_GRID_DOMAIN=$0DD2 +Const GL_MAP2_GRID_SEGMENTS=$0DD3 +Const GL_TEXTURE_1D=$0DE0 +Const GL_TEXTURE_2D=$0DE1 +Const GL_FEEDBACK_BUFFER_POINTER=$0DF0 +Const GL_FEEDBACK_BUFFER_SIZE=$0DF1 +Const GL_FEEDBACK_BUFFER_TYPE=$0DF2 +Const GL_SELECTION_BUFFER_POINTER=$0DF3 +Const GL_SELECTION_BUFFER_SIZE=$0DF4 +Const GL_TEXTURE_WIDTH=$1000 +Const GL_TEXTURE_HEIGHT=$1001 +Const GL_TEXTURE_INTERNAL_FORMAT=$1003 +Const GL_TEXTURE_BORDER_COLOR=$1004 +Const GL_TEXTURE_BORDER=$1005 +Const GL_DONT_CARE=$1100 +Const GL_FASTEST=$1101 +Const GL_NICEST=$1102 +Const GL_LIGHT0=$4000 +Const GL_LIGHT1=$4001 +Const GL_LIGHT2=$4002 +Const GL_LIGHT3=$4003 +Const GL_LIGHT4=$4004 +Const GL_LIGHT5=$4005 +Const GL_LIGHT6=$4006 +Const GL_LIGHT7=$4007 +Const GL_AMBIENT=$1200 +Const GL_DIFFUSE=$1201 +Const GL_SPECULAR=$1202 +Const GL_POSITION=$1203 +Const GL_SPOT_DIRECTION=$1204 +Const GL_SPOT_EXPONENT=$1205 +Const GL_SPOT_CUTOFF=$1206 +Const GL_CONSTANT_ATTENUATION=$1207 +Const GL_LINEAR_ATTENUATION=$1208 +Const GL_QUADRATIC_ATTENUATION=$1209 +Const GL_COMPILE=$1300 +Const GL_COMPILE_AND_EXECUTE=$1301 +Const GL_CLEAR=$1500 +Const GL_AND=$1501 +Const GL_AND_REVERSE=$1502 +Const GL_COPY=$1503 +Const GL_AND_INVERTED=$1504 +Const GL_NOOP=$1505 +Const GL_XOR=$1506 +Const GL_OR=$1507 +Const GL_NOR=$1508 +Const GL_EQUIV=$1509 +Const GL_INVERT=$150A +Const GL_OR_REVERSE=$150B +Const GL_COPY_INVERTED=$150C +Const GL_OR_INVERTED=$150D +Const GL_NAND=$150E +Const GL_SET=$150F +Const GL_EMISSION=$1600 +Const GL_SHININESS=$1601 +Const GL_AMBIENT_AND_DIFFUSE=$1602 +Const GL_COLOR_INDEXES=$1603 +Const GL_MODELVIEW=$1700 +Const GL_PROJECTION=$1701 +Const GL_TEXTURE=$1702 +Const GL_COLOR=$1800 +Const GL_DEPTH=$1801 +Const GL_STENCIL=$1802 +Const GL_COLOR_INDEX=$1900 +Const GL_STENCIL_INDEX=$1901 +Const GL_DEPTH_COMPONENT=$1902 +Const GL_RED=$1903 +Const GL_GREEN=$1904 +Const GL_BLUE=$1905 +Const GL_ALPHA=$1906 +Const GL_RGB=$1907 +Const GL_RGBA=$1908 +Const GL_LUMINANCE=$1909 +Const GL_LUMINANCE_ALPHA=$190A +Const GL_BITMAP=$1A00 +Const GL_POINT=$1B00 +Const GL_LINE=$1B01 +Const GL_FILL=$1B02 +Const GL_RENDER=$1C00 +Const GL_FEEDBACK=$1C01 +Const GL_SELECT=$1C02 +Const GL_FLAT=$1D00 +Const GL_SMOOTH=$1D01 +Const GL_KEEP=$1E00 +Const GL_REPLACE=$1E01 +Const GL_INCR=$1E02 +Const GL_DECR=$1E03 +Const GL_VENDOR=$1F00 +Const GL_RENDERER=$1F01 +Const GL_VERSION=$1F02 +Const GL_EXTENSIONS=$1F03 +Const GL_S=$2000 +Const GL_T=$2001 +Const GL_R=$2002 +Const GL_Q=$2003 +Const GL_MODULATE=$2100 +Const GL_DECAL=$2101 +Const GL_TEXTURE_ENV_MODE=$2200 +Const GL_TEXTURE_ENV_COLOR=$2201 +Const GL_TEXTURE_ENV=$2300 +Const GL_EYE_LINEAR=$2400 +Const GL_OBJECT_LINEAR=$2401 +Const GL_SPHERE_MAP=$2402 +Const GL_TEXTURE_GEN_MODE=$2500 +Const GL_OBJECT_PLANE=$2501 +Const GL_EYE_PLANE=$2502 +Const GL_NEAREST=$2600 +Const GL_LINEAR=$2601 +Const GL_NEAREST_MIPMAP_NEAREST=$2700 +Const GL_LINEAR_MIPMAP_NEAREST=$2701 +Const GL_NEAREST_MIPMAP_LINEAR=$2702 +Const GL_LINEAR_MIPMAP_LINEAR=$2703 +Const GL_TEXTURE_MAG_FILTER=$2800 +Const GL_TEXTURE_MIN_FILTER=$2801 +Const GL_TEXTURE_WRAP_S=$2802 +Const GL_TEXTURE_WRAP_T=$2803 +Const GL_CLAMP=$2900 +Const GL_REPEAT=$2901 +Const GL_CLIENT_PIXEL_STORE_BIT=$00000001 +Const GL_CLIENT_VERTEX_ARRAY_BIT=$00000002 +Const GL_CLIENT_ALL_ATTRIB_BITS=$ffffffff +Const GL_POLYGON_OFFSET_FACTOR=$8038 +Const GL_POLYGON_OFFSET_UNITS=$2A00 +Const GL_POLYGON_OFFSET_POINT=$2A01 +Const GL_POLYGON_OFFSET_LINE=$2A02 +Const GL_POLYGON_OFFSET_FILL=$8037 +Const GL_ALPHA4=$803B +Const GL_ALPHA8=$803C +Const GL_ALPHA12=$803D +Const GL_ALPHA16=$803E +Const GL_LUMINANCE4=$803F +Const GL_LUMINANCE8=$8040 +Const GL_LUMINANCE12=$8041 +Const GL_LUMINANCE16=$8042 +Const GL_LUMINANCE4_ALPHA4=$8043 +Const GL_LUMINANCE6_ALPHA2=$8044 +Const GL_LUMINANCE8_ALPHA8=$8045 +Const GL_LUMINANCE12_ALPHA4=$8046 +Const GL_LUMINANCE12_ALPHA12=$8047 +Const GL_LUMINANCE16_ALPHA16=$8048 +Const GL_INTENSITY=$8049 +Const GL_INTENSITY4=$804A +Const GL_INTENSITY8=$804B +Const GL_INTENSITY12=$804C +Const GL_INTENSITY16=$804D +Const GL_R3_G3_B2=$2A10 +Const GL_RGB4=$804F +Const GL_RGB5=$8050 +Const GL_RGB8=$8051 +Const GL_RGB10=$8052 +Const GL_RGB12=$8053 +Const GL_RGB16=$8054 +Const GL_RGBA2=$8055 +Const GL_RGBA4=$8056 +Const GL_RGB5_A1=$8057 +Const GL_RGBA8=$8058 +Const GL_RGB10_A2=$8059 +Const GL_RGBA12=$805A +Const GL_RGBA16=$805B +Const GL_TEXTURE_RED_SIZE=$805C +Const GL_TEXTURE_GREEN_SIZE=$805D +Const GL_TEXTURE_BLUE_SIZE=$805E +Const GL_TEXTURE_ALPHA_SIZE=$805F +Const GL_TEXTURE_LUMINANCE_SIZE=$8060 +Const GL_TEXTURE_INTENSITY_SIZE=$8061 +Const GL_PROXY_TEXTURE_1D=$8063 +Const GL_PROXY_TEXTURE_2D=$8064 +Const GL_TEXTURE_PRIORITY=$8066 +Const GL_TEXTURE_RESIDENT=$8067 +Const GL_TEXTURE_BINDING_1D=$8068 +Const GL_TEXTURE_BINDING_2D=$8069 +Const GL_VERTEX_ARRAY=$8074 +Const GL_NORMAL_ARRAY=$8075 +Const GL_COLOR_ARRAY=$8076 +Const GL_INDEX_ARRAY=$8077 +Const GL_TEXTURE_COORD_ARRAY=$8078 +Const GL_EDGE_FLAG_ARRAY=$8079 +Const GL_VERTEX_ARRAY_SIZE=$807A +Const GL_VERTEX_ARRAY_TYPE=$807B +Const GL_VERTEX_ARRAY_STRIDE=$807C +Const GL_NORMAL_ARRAY_TYPE=$807E +Const GL_NORMAL_ARRAY_STRIDE=$807F +Const GL_COLOR_ARRAY_SIZE=$8081 +Const GL_COLOR_ARRAY_TYPE=$8082 +Const GL_COLOR_ARRAY_STRIDE=$8083 +Const GL_INDEX_ARRAY_TYPE=$8085 +Const GL_INDEX_ARRAY_STRIDE=$8086 +Const GL_TEXTURE_COORD_ARRAY_SIZE=$8088 +Const GL_TEXTURE_COORD_ARRAY_TYPE=$8089 +Const GL_TEXTURE_COORD_ARRAY_STRIDE=$808A +Const GL_EDGE_FLAG_ARRAY_STRIDE=$808C +Const GL_VERTEX_ARRAY_POINTER=$808E +Const GL_NORMAL_ARRAY_POINTER=$808F +Const GL_COLOR_ARRAY_POINTER=$8090 +Const GL_INDEX_ARRAY_POINTER=$8091 +Const GL_TEXTURE_COORD_ARRAY_POINTER=$8092 +Const GL_EDGE_FLAG_ARRAY_POINTER=$8093 +Const GL_V2F=$2A20 +Const GL_V3F=$2A21 +Const GL_C4UB_V2F=$2A22 +Const GL_C4UB_V3F=$2A23 +Const GL_C3F_V3F=$2A24 +Const GL_N3F_V3F=$2A25 +Const GL_C4F_N3F_V3F=$2A26 +Const GL_T2F_V3F=$2A27 +Const GL_T4F_V4F=$2A28 +Const GL_T2F_C4UB_V3F=$2A29 +Const GL_T2F_C3F_V3F=$2A2A +Const GL_T2F_N3F_V3F=$2A2B +Const GL_T2F_C4F_N3F_V3F=$2A2C +Const GL_T4F_C4F_N3F_V4F=$2A2D +Const GL_COLOR_INDEX1_EXT=$80E2 +Const GL_COLOR_INDEX2_EXT=$80E3 +Const GL_COLOR_INDEX4_EXT=$80E4 +Const GL_COLOR_INDEX8_EXT=$80E5 +Const GL_COLOR_INDEX12_EXT=$80E6 +Const GL_COLOR_INDEX16_EXT=$80E7 +Function glAccum(op_:Int,value_:Float) +Function glAlphaFunc(func_:Int,ref_:Float) +Function glAreTexturesResident:Byte(n_:Int,textures_:Int Ptr,residences_:Byte Ptr) +Function glArrayElement(i_:Int) +Function glBegin(mode_:Int) +Function glBindTexture(target_:Int,texture_:Int) +Function glBitmap(width_:Int,height_:Int,xorig_:Float,yorig_:Float,xmove_:Float,ymove_:Float,bitmap_:Byte Ptr) +Function glBlendFunc(sfactor_:Int,dfactor_:Int) +Function glCallList(list_:Int) +Function glCallLists(n_:Int,type_:Int,lists_:Byte Ptr) +Function glClear(mask_:Int) +Function glClearAccum(red_:Float,green_:Float,blue_:Float,alpha_:Float) +Function glClearColor(red_:Float,green_:Float,blue_:Float,alpha_:Float) +Function glClearDepth(depth_:Double) +Function glClearIndex(c_:Float) +Function glClearStencil(s_:Int) +Function glClipPlane(plane_:Int,equation_:Double Ptr) +Function glColor3b(red_:Byte,green_:Byte,blue_:Byte) +Function glColor3bv(v_:Byte Ptr) +Function glColor3d(red_:Double,green_:Double,blue_:Double) +Function glColor3dv(v_:Double Ptr) +Function glColor3f(red_:Float,green_:Float,blue_:Float) +Function glColor3fv(v_:Float Ptr) +Function glColor3i(red_:Int,green_:Int,blue_:Int) +Function glColor3iv(v_:Int Ptr) +Function glColor3s(red_:Short,green_:Short,blue_:Short) +Function glColor3sv(v_:Short Ptr) +Function glColor3ub(red_:Byte,green_:Byte,blue_:Byte) +Function glColor3ubv(v_:Byte Ptr) +Function glColor3ui(red_:Int,green_:Int,blue_:Int) +Function glColor3uiv(v_:Int Ptr) +Function glColor3us(red_:Short,green_:Short,blue_:Short) +Function glColor3usv(v_:Short Ptr) +Function glColor4b(red_:Byte,green_:Byte,blue_:Byte,alpha_:Byte) +Function glColor4bv(v_:Byte Ptr) +Function glColor4d(red_:Double,green_:Double,blue_:Double,alpha_:Double) +Function glColor4dv(v_:Double Ptr) +Function glColor4f(red_:Float,green_:Float,blue_:Float,alpha_:Float) +Function glColor4fv(v_:Float Ptr) +Function glColor4i(red_:Int,green_:Int,blue_:Int,alpha_:Int) +Function glColor4iv(v_:Int Ptr) +Function glColor4s(red_:Short,green_:Short,blue_:Short,alpha_:Short) +Function glColor4sv(v_:Short Ptr) +Function glColor4ub(red_:Byte,green_:Byte,blue_:Byte,alpha_:Byte) +Function glColor4ubv(v_:Byte Ptr) +Function glColor4ui(red_:Int,green_:Int,blue_:Int,alpha_:Int) +Function glColor4uiv(v_:Int Ptr) +Function glColor4us(red_:Short,green_:Short,blue_:Short,alpha_:Short) +Function glColor4usv(v_:Short Ptr) +Function glColorMask(red_:Byte,green_:Byte,blue_:Byte,alpha_:Byte) +Function glColorMaterial(face_:Int,mode_:Int) +Function glColorPointer(size_:Int,type_:Int,stride_:Int,pointer_:Byte Ptr) +Function glCopyPixels(x_:Int,y_:Int,width_:Int,height_:Int,type_:Int) +Function glCopyTexImage1D(target_:Int,level_:Int,internalFormat_:Int,x_:Int,y_:Int,width_:Int,border_:Int) +Function glCopyTexImage2D(target_:Int,level_:Int,internalFormat_:Int,x_:Int,y_:Int,width_:Int,height_:Int,border_:Int) +Function glCopyTexSubImage1D(target_:Int,level_:Int,xoffset_:Int,x_:Int,y_:Int,width_:Int) +Function glCopyTexSubImage2D(target_:Int,level_:Int,xoffset_:Int,yoffset_:Int,x_:Int,y_:Int,width_:Int,height_:Int) +Function glCullFace(mode_:Int) +Function glDeleteLists(list_:Int,range_:Int) +Function glDeleteTextures(n_:Int,textures_:Int Ptr) +Function glDepthFunc(func_:Int) +Function glDepthMask(flag_:Byte) +Function glDepthRange(zNear_:Double,zFar_:Double) +Function glDisable(cap_:Int) +Function glDisableClientState(array_:Int) +Function glDrawArrays(mode_:Int,first_:Int,count_:Int) +Function glDrawBuffer(mode_:Int) +Function glDrawElements(mode_:Int,count_:Int,type_:Int,indices_:Byte Ptr) +Function glDrawPixels(width_:Int,height_:Int,format_:Int,type_:Int,pixels_:Byte Ptr) +Function glEdgeFlag(flag_:Byte) +Function glEdgeFlagPointer(stride_:Int,pointer_:Byte Ptr) +Function glEdgeFlagv(flag_:Byte Ptr) +Function glEnable(cap_:Int) +Function glEnableClientState(array_:Int) +Function glEnd() +Function glEndList() +Function glEvalCoord1d(u_:Double) +Function glEvalCoord1dv(u_:Double Ptr) +Function glEvalCoord1f(u_:Float) +Function glEvalCoord1fv(u_:Float Ptr) +Function glEvalCoord2d(u_:Double,v_:Double) +Function glEvalCoord2dv(u_:Double Ptr) +Function glEvalCoord2f(u_:Float,v_:Float) +Function glEvalCoord2fv(u_:Float Ptr) +Function glEvalMesh1(mode_:Int,i1_:Int,i2_:Int) +Function glEvalMesh2(mode_:Int,i1_:Int,i2_:Int,j1_:Int,j2_:Int) +Function glEvalPoint1(i_:Int) +Function glEvalPoint2(i_:Int,j_:Int) +Function glFeedbackBuffer(size_:Int,type_:Int,buffer_:Float Ptr) +Function glFinish() +Function glFlush() +Function glFogf(pname_:Int,param_:Float) +Function glFogfv(pname_:Int,params_:Float Ptr) +Function glFogi(pname_:Int,param_:Int) +Function glFogiv(pname_:Int,params_:Int Ptr) +Function glFrontFace(mode_:Int) +Function glFrustum(left_:Double,right_:Double,bottom_:Double,top_:Double,zNear_:Double,zFar_:Double) +Function glGenLists:Int(range_:Int) +Function glGenTextures(n_:Int,textures_:Int Ptr) +Function glGetBooleanv(pname_:Int,params_:Byte Ptr) +Function glGetClipPlane(plane_:Int,equation_:Double Ptr) +Function glGetDoublev(pname_:Int,params_:Double Ptr) +Function glGetError:Int() +Function glGetFloatv(pname_:Int,params_:Float Ptr) +Function glGetIntegerv(pname_:Int,params_:Int Ptr) +Function glGetLightfv(light_:Int,pname_:Int,params_:Float Ptr) +Function glGetLightiv(light_:Int,pname_:Int,params_:Int Ptr) +Function glGetMapdv(target_:Int,query_:Int,v_:Double Ptr) +Function glGetMapfv(target_:Int,query_:Int,v_:Float Ptr) +Function glGetMapiv(target_:Int,query_:Int,v_:Int Ptr) +Function glGetMaterialfv(face_:Int,pname_:Int,params_:Float Ptr) +Function glGetMaterialiv(face_:Int,pname_:Int,params_:Int Ptr) +Function glGetPixelMapfv(map_:Int,values_:Float Ptr) +Function glGetPixelMapuiv(map_:Int,values_:Int Ptr) +Function glGetPixelMapusv(map_:Int,values_:Short Ptr) +Function glGetPointerv(pname_:Int,params_:Byte Ptr Ptr) +Function glGetPolygonStipple(mask_:Byte Ptr) +Function glGetString:Byte Ptr(name_:Int) +Function glGetTexEnvfv(target_:Int,pname_:Int,params_:Float Ptr) +Function glGetTexEnviv(target_:Int,pname_:Int,params_:Int Ptr) +Function glGetTexGendv(coord_:Int,pname_:Int,params_:Double Ptr) +Function glGetTexGenfv(coord_:Int,pname_:Int,params_:Float Ptr) +Function glGetTexGeniv(coord_:Int,pname_:Int,params_:Int Ptr) +Function glGetTexImage(target_:Int,level_:Int,format_:Int,type_:Int,pixels_:Byte Ptr) +Function glGetTexLevelParameterfv(target_:Int,level_:Int,pname_:Int,params_:Float Ptr) +Function glGetTexLevelParameteriv(target_:Int,level_:Int,pname_:Int,params_:Int Ptr) +Function glGetTexParameterfv(target_:Int,pname_:Int,params_:Float Ptr) +Function glGetTexParameteriv(target_:Int,pname_:Int,params_:Int Ptr) +Function glHint(target_:Int,mode_:Int) +Function glIndexMask(mask_:Int) +Function glIndexPointer(type_:Int,stride_:Int,pointer_:Byte Ptr) +Function glIndexd(c_:Double) +Function glIndexdv(c_:Double Ptr) +Function glIndexf(c_:Float) +Function glIndexfv(c_:Float Ptr) +Function glIndexi(c_:Int) +Function glIndexiv(c_:Int Ptr) +Function glIndexs(c_:Short) +Function glIndexsv(c_:Short Ptr) +Function glIndexub(c_:Byte) +Function glIndexubv(c_:Byte Ptr) +Function glInitNames() +Function glInterleavedArrays(format_:Int,stride_:Int,pointer_:Byte Ptr) +Function glIsEnabled:Byte(cap_:Int) +Function glIsList:Byte(list_:Int) +Function glIsTexture:Byte(texture_:Int) +Function glLightModelf(pname_:Int,param_:Float) +Function glLightModelfv(pname_:Int,params_:Float Ptr) +Function glLightModeli(pname_:Int,param_:Int) +Function glLightModeliv(pname_:Int,params_:Int Ptr) +Function glLightf(light_:Int,pname_:Int,param_:Float) +Function glLightfv(light_:Int,pname_:Int,params_:Float Ptr) +Function glLighti(light_:Int,pname_:Int,param_:Int) +Function glLightiv(light_:Int,pname_:Int,params_:Int Ptr) +Function glLineStipple(factor_:Int,pattern_:Short) +Function glLineWidth(width_:Float) +Function glListBase(base_:Int) +Function glLoadIdentity() +Function glLoadMatrixd(m_:Double Ptr) +Function glLoadMatrixf(m_:Float Ptr) +Function glLoadName(name_:Int) +Function glLogicOp(opcode_:Int) +Function glMap1d(target_:Int,u1_:Double,u2_:Double,stride_:Int,order_:Int,points_:Double Ptr) +Function glMap1f(target_:Int,u1_:Float,u2_:Float,stride_:Int,order_:Int,points_:Float Ptr) +Function glMap2d(target_:Int,u1_:Double,u2_:Double,ustride_:Int,uorder_:Int,v1_:Double,v2_:Double,vstride_:Int,vorder_:Int,points_:Double Ptr) +Function glMap2f(target_:Int,u1_:Float,u2_:Float,ustride_:Int,uorder_:Int,v1_:Float,v2_:Float,vstride_:Int,vorder_:Int,points_:Float Ptr) +Function glMapGrid1d(un_:Int,u1_:Double,u2_:Double) +Function glMapGrid1f(un_:Int,u1_:Float,u2_:Float) +Function glMapGrid2d(un_:Int,u1_:Double,u2_:Double,vn_:Int,v1_:Double,v2_:Double) +Function glMapGrid2f(un_:Int,u1_:Float,u2_:Float,vn_:Int,v1_:Float,v2_:Float) +Function glMaterialf(face_:Int,pname_:Int,param_:Float) +Function glMaterialfv(face_:Int,pname_:Int,params_:Float Ptr) +Function glMateriali(face_:Int,pname_:Int,param_:Int) +Function glMaterialiv(face_:Int,pname_:Int,params_:Int Ptr) +Function glMatrixMode(mode_:Int) +Function glMultMatrixd(m_:Double Ptr) +Function glMultMatrixf(m_:Float Ptr) +Function glNewList(list_:Int,mode_:Int) +Function glNormal3b(nx_:Byte,ny_:Byte,nz_:Byte) +Function glNormal3bv(v_:Byte Ptr) +Function glNormal3d(nx_:Double,ny_:Double,nz_:Double) +Function glNormal3dv(v_:Double Ptr) +Function glNormal3f(nx_:Float,ny_:Float,nz_:Float) +Function glNormal3fv(v_:Float Ptr) +Function glNormal3i(nx_:Int,ny_:Int,nz_:Int) +Function glNormal3iv(v_:Int Ptr) +Function glNormal3s(nx_:Short,ny_:Short,nz_:Short) +Function glNormal3sv(v_:Short Ptr) +Function glNormalPointer(type_:Int,stride_:Int,pointer_:Byte Ptr) +Function glOrtho(left_:Double,right_:Double,bottom_:Double,top_:Double,zNear_:Double,zFar_:Double) +Function glPassThrough(token_:Float) +Function glPixelMapfv(map_:Int,mapsize_:Int,values_:Float Ptr) +Function glPixelMapuiv(map_:Int,mapsize_:Int,values_:Int Ptr) +Function glPixelMapusv(map_:Int,mapsize_:Int,values_:Short Ptr) +Function glPixelStoref(pname_:Int,param_:Float) +Function glPixelStorei(pname_:Int,param_:Int) +Function glPixelTransferf(pname_:Int,param_:Float) +Function glPixelTransferi(pname_:Int,param_:Int) +Function glPixelZoom(xfactor_:Float,yfactor_:Float) +Function glPointSize(size_:Float) +Function glPolygonMode(face_:Int,mode_:Int) +Function glPolygonOffset(factor_:Float,units_:Float) +Function glPolygonStipple(mask_:Byte Ptr) +Function glPopAttrib() +Function glPopClientAttrib() +Function glPopMatrix() +Function glPopName() +Function glPrioritizeTextures(n_:Int,textures_:Int Ptr,priorities_:Float Ptr) +Function glPushAttrib(mask_:Int) +Function glPushClientAttrib(mask_:Int) +Function glPushMatrix() +Function glPushName(name_:Int) +Function glRasterPos2d(x_:Double,y_:Double) +Function glRasterPos2dv(v_:Double Ptr) +Function glRasterPos2f(x_:Float,y_:Float) +Function glRasterPos2fv(v_:Float Ptr) +Function glRasterPos2i(x_:Int,y_:Int) +Function glRasterPos2iv(v_:Int Ptr) +Function glRasterPos2s(x_:Short,y_:Short) +Function glRasterPos2sv(v_:Short Ptr) +Function glRasterPos3d(x_:Double,y_:Double,z_:Double) +Function glRasterPos3dv(v_:Double Ptr) +Function glRasterPos3f(x_:Float,y_:Float,z_:Float) +Function glRasterPos3fv(v_:Float Ptr) +Function glRasterPos3i(x_:Int,y_:Int,z_:Int) +Function glRasterPos3iv(v_:Int Ptr) +Function glRasterPos3s(x_:Short,y_:Short,z_:Short) +Function glRasterPos3sv(v_:Short Ptr) +Function glRasterPos4d(x_:Double,y_:Double,z_:Double,w_:Double) +Function glRasterPos4dv(v_:Double Ptr) +Function glRasterPos4f(x_:Float,y_:Float,z_:Float,w_:Float) +Function glRasterPos4fv(v_:Float Ptr) +Function glRasterPos4i(x_:Int,y_:Int,z_:Int,w_:Int) +Function glRasterPos4iv(v_:Int Ptr) +Function glRasterPos4s(x_:Short,y_:Short,z_:Short,w_:Short) +Function glRasterPos4sv(v_:Short Ptr) +Function glReadBuffer(mode_:Int) +Function glReadPixels(x_:Int,y_:Int,width_:Int,height_:Int,format_:Int,type_:Int,pixels_:Byte Ptr) +Function glRectd(x1_:Double,y1_:Double,x2_:Double,y2_:Double) +Function glRectdv(v1_:Double Ptr,v2_:Double Ptr) +Function glRectf(x1_:Float,y1_:Float,x2_:Float,y2_:Float) +Function glRectfv(v1_:Float Ptr,v2_:Float Ptr) +Function glRecti(x1_:Int,y1_:Int,x2_:Int,y2_:Int) +Function glRectiv(v1_:Int Ptr,v2_:Int Ptr) +Function glRects(x1_:Short,y1_:Short,x2_:Short,y2_:Short) +Function glRectsv(v1_:Short Ptr,v2_:Short Ptr) +Function glRenderMode:Int(mode_:Int) +Function glRotated(angle_:Double,x_:Double,y_:Double,z_:Double) +Function glRotatef(angle_:Float,x_:Float,y_:Float,z_:Float) +Function glScaled(x_:Double,y_:Double,z_:Double) +Function glScalef(x_:Float,y_:Float,z_:Float) +Function glScissor(x_:Int,y_:Int,width_:Int,height_:Int) +Function glSelectBuffer(size_:Int,buffer_:Int Ptr) +Function glShadeModel(mode_:Int) +Function glStencilFunc(func_:Int,ref_:Int,mask_:Int) +Function glStencilMask(mask_:Int) +Function glStencilOp(fail_:Int,zfail_:Int,zpass_:Int) +Function glTexCoord1d(s_:Double) +Function glTexCoord1dv(v_:Double Ptr) +Function glTexCoord1f(s_:Float) +Function glTexCoord1fv(v_:Float Ptr) +Function glTexCoord1i(s_:Int) +Function glTexCoord1iv(v_:Int Ptr) +Function glTexCoord1s(s_:Short) +Function glTexCoord1sv(v_:Short Ptr) +Function glTexCoord2d(s_:Double,t_:Double) +Function glTexCoord2dv(v_:Double Ptr) +Function glTexCoord2f(s_:Float,t_:Float) +Function glTexCoord2fv(v_:Float Ptr) +Function glTexCoord2i(s_:Int,t_:Int) +Function glTexCoord2iv(v_:Int Ptr) +Function glTexCoord2s(s_:Short,t_:Short) +Function glTexCoord2sv(v_:Short Ptr) +Function glTexCoord3d(s_:Double,t_:Double,r_:Double) +Function glTexCoord3dv(v_:Double Ptr) +Function glTexCoord3f(s_:Float,t_:Float,r_:Float) +Function glTexCoord3fv(v_:Float Ptr) +Function glTexCoord3i(s_:Int,t_:Int,r_:Int) +Function glTexCoord3iv(v_:Int Ptr) +Function glTexCoord3s(s_:Short,t_:Short,r_:Short) +Function glTexCoord3sv(v_:Short Ptr) +Function glTexCoord4d(s_:Double,t_:Double,r_:Double,q_:Double) +Function glTexCoord4dv(v_:Double Ptr) +Function glTexCoord4f(s_:Float,t_:Float,r_:Float,q_:Float) +Function glTexCoord4fv(v_:Float Ptr) +Function glTexCoord4i(s_:Int,t_:Int,r_:Int,q_:Int) +Function glTexCoord4iv(v_:Int Ptr) +Function glTexCoord4s(s_:Short,t_:Short,r_:Short,q_:Short) +Function glTexCoord4sv(v_:Short Ptr) +Function glTexCoordPointer(size_:Int,type_:Int,stride_:Int,pointer_:Byte Ptr) +Function glTexEnvf(target_:Int,pname_:Int,param_:Float) +Function glTexEnvfv(target_:Int,pname_:Int,params_:Float Ptr) +Function glTexEnvi(target_:Int,pname_:Int,param_:Int) +Function glTexEnviv(target_:Int,pname_:Int,params_:Int Ptr) +Function glTexGend(coord_:Int,pname_:Int,param_:Double) +Function glTexGendv(coord_:Int,pname_:Int,params_:Double Ptr) +Function glTexGenf(coord_:Int,pname_:Int,param_:Float) +Function glTexGenfv(coord_:Int,pname_:Int,params_:Float Ptr) +Function glTexGeni(coord_:Int,pname_:Int,param_:Int) +Function glTexGeniv(coord_:Int,pname_:Int,params_:Int Ptr) +Function glTexImage1D(target_:Int,level_:Int,internalformat_:Int,width_:Int,border_:Int,format_:Int,type_:Int,pixels_:Byte Ptr) +Function glTexImage2D(target_:Int,level_:Int,internalformat_:Int,width_:Int,height_:Int,border_:Int,format_:Int,type_:Int,pixels_:Byte Ptr) +Function glTexParameterf(target_:Int,pname_:Int,param_:Float) +Function glTexParameterfv(target_:Int,pname_:Int,params_:Float Ptr) +Function glTexParameteri(target_:Int,pname_:Int,param_:Int) +Function glTexParameteriv(target_:Int,pname_:Int,params_:Int Ptr) +Function glTexSubImage1D(target_:Int,level_:Int,xoffset_:Int,width_:Int,format_:Int,type_:Int,pixels_:Byte Ptr) +Function glTexSubImage2D(target_:Int,level_:Int,xoffset_:Int,yoffset_:Int,width_:Int,height_:Int,format_:Int,type_:Int,pixels_:Byte Ptr) +Function glTranslated(x_:Double,y_:Double,z_:Double) +Function glTranslatef(x_:Float,y_:Float,z_:Float) +Function glVertex2d(x_:Double,y_:Double) +Function glVertex2dv(v_:Double Ptr) +Function glVertex2f(x_:Float,y_:Float) +Function glVertex2fv(v_:Float Ptr) +Function glVertex2i(x_:Int,y_:Int) +Function glVertex2iv(v_:Int Ptr) +Function glVertex2s(x_:Short,y_:Short) +Function glVertex2sv(v_:Short Ptr) +Function glVertex3d(x_:Double,y_:Double,z_:Double) +Function glVertex3dv(v_:Double Ptr) +Function glVertex3f(x_:Float,y_:Float,z_:Float) +Function glVertex3fv(v_:Float Ptr) +Function glVertex3i(x_:Int,y_:Int,z_:Int) +Function glVertex3iv(v_:Int Ptr) +Function glVertex3s(x_:Short,y_:Short,z_:Short) +Function glVertex3sv(v_:Short Ptr) +Function glVertex4d(x_:Double,y_:Double,z_:Double,w_:Double) +Function glVertex4dv(v_:Double Ptr) +Function glVertex4f(x_:Float,y_:Float,z_:Float,w_:Float) +Function glVertex4fv(v_:Float Ptr) +Function glVertex4i(x_:Int,y_:Int,z_:Int,w_:Int) +Function glVertex4iv(v_:Int Ptr) +Function glVertex4s(x_:Short,y_:Short,z_:Short,w_:Short) +Function glVertex4sv(v_:Short Ptr) +Function glVertexPointer(size_:Int,type_:Int,stride_:Int,pointer_:Byte Ptr) +Function glViewport(x_:Int,y_:Int,width_:Int,height_:Int) + +End Extern diff --git a/mod/pub.mod/stdc.mod/stdc.bmx b/mod/pub.mod/stdc.mod/stdc.bmx new file mode 100644 index 0000000..012ebc9 --- /dev/null +++ b/mod/pub.mod/stdc.mod/stdc.bmx @@ -0,0 +1,207 @@ + +Rem + +Standard C library (And friends!) functions. + +To simplify life, this is a 'structless' interface meaning some functions have been wrapped. + +End Rem + +Strict + +Module Pub.StdC + +ModuleInfo "Version: 1.13" +ModuleInfo "Author: Various" +ModuleInfo "License: zlib/libpng" +ModuleInfo "Modserver: BRL" +ModuleInfo "Credit: Adapted for BlitzMax by Mark Sibly" + +ModuleInfo "History: 1.13 Release" +ModuleInfo "History: Added totally awesome stat_() hack for '<' and '>' in Win32 paths" +ModuleInfo "History: 1.12 Release" +ModuleInfo "History: remove_ now does a chmod 0x1b6 beforehand on Win32 - ie: will remove write protected files" +ModuleInfo "History: chmod_ now does something on Win32" +ModuleInfo "History: 1.11 Release" +ModuleInfo "History: Fixed getsockopt" +ModuleInfo "History: 1.10 Release" +ModuleInfo "History: Fixed network byte ordering for sento_ and recvfrom_" +ModuleInfo "History: 1.09 Release" +ModuleInfo "History: More socket stuff added" +ModuleInfo "History: 1.07 Release" +ModuleInfo "History: More socket stuff added" +ModuleInfo "History: 1.06 Release" +ModuleInfo "History: Cleaned up Win32 system_" +ModuleInfo "History: 1.05 Release" +ModuleInfo "History: 1.04 Release" +ModuleInfo "History: Fixed C Compiler warnings" + +Import "stdc.c" + +'c lib +Extern "c" + +Const SEEK_SET_=0 +Const SEEK_CUR_=1 +Const SEEK_END_=2 + +Const S_IFMT_=$f000 +Const S_IFIFO_=$1000 +Const S_IFCHR_=$2000 +Const S_IFBLK_=$3000 +Const S_IFDIR_=$4000 +Const S_IFREG_=$8000 + +Global stdin_ +Global stdout_ +Global stderr_ + +Function getchar_() +Function puts_( str$ ) +Function putenv_( str$ ) +Function getenv_$( env$ ) + +'file system + +Function fopen_( file$,mode$ ) +Function fclose_( c_stream )="fclose" +Function fread_( buf:Byte Ptr,size,count,c_stream )="fread" +Function fwrite_( buf:Byte Ptr,size,count,c_stream )="fwrite" +Function fflush_( c_stream )="fflush" +Function fseek_( c_stream,offset,origin )="fseek" +Function ftell_( c_stream )="ftell" +Function feof_( c_stream )="feof" +Function fgetc_( c_stream )="fgetc" +Function ungetc_( char,c_stream )="ungetc" +Function fputs_( str$,c_stream ) + +'posix + +Function chdir_( dir$ ) +Function getcwd_$() +Function chmod_( path$,mode ) +Function mkdir_( path$,mode ) +Function rmdir_( path$ ) +Function rename_( from_path$,to_path$ ) +Function remove_( path$ ) +Function opendir_( path$ ) +Function closedir_( dir ) +Function readdir_$( dir ) +Function stat_( path$,st_mode Var,st_size Var,st_mtime Var,st_ctime Var ) +Function system_( cmd$ ) + +'misc +Function abort_()="abort" +Function malloc_:Byte Ptr( size )="malloc" +Function realloc_:Byte Ptr( p:Byte Ptr,size )="realloc" +Function free_( buf:Byte Ptr )="free" +Function exit_( exit_code )="exit" +Function atexit_( fun() )="atexit" +Function memset_( buf:Byte Ptr,val,size )="memset" +Function memcmp_( lhs:Byte Ptr,rhs:Byte Ptr,size )="memcmp" +Function memcpy_( dst:Byte Ptr,src:Byte Ptr,size )="memcpy" +Function memmove_( dst:Byte Ptr,src:Byte Ptr,size )="memmove" + +'math + +Function sin_!( n! )="sin" +Function cos_!( n! )="cos" +Function tan_!( n! )="tan" +Function sinh_!( n! )="sinh" +Function cosh_!( n! )="cosh" +Function tanh_!( n! )="tanh" +Function asin_!( n! )="asin" +Function acos_!( n! )="acos" +Function atan_!( n! )="atan" + +'sockets + +Const AF_INET_=2 'address types +Const SOCK_STREAM_=1,SOCK_DGRAM_=2 'communication types +Const SOCKET_ERROR_=-1 + +Const SO_DEBUG=1 'turn on debugging info recording +Const SO_ACCEPTCONN=2 'socket has had listen() +Const SO_REUSEADDR=4 'allow local address reuse +Const SO_KEEPALIVE=8 'keep connections alive +Const SO_DONTROUTE=$10 'just use interface addresses +Const SO_BROADCAST=$20 'permit sending of broadcast msgs +Const SO_USELOOPBACK=$40 'bypass hardware when possible +Const SO_LINGER=$80 'linger on close if data present +Const SO_OOBINLINE=$100 'leave received OOB data in line + +'Additional options. + +Const SO_SNDBUF=$1001 'sendbuffersize +Const SO_RCVBUF=$1002 'receivebuffersize +Const SO_SNDLOWAT=$1003 'sendlow-watermark +Const SO_RCVLOWAT=$1004 'receivelow-watermark +Const SO_SNDTIMEO=$1005 'sendtimeout +Const SO_RCVTIMEO=$1006 'receivetimeout +Const SO_ERROR=$1007 'geterrorstatusandclear +Const SO_TYPE=$1008 'getsockettype + +'Option for opening sockets for synchronous access. +Const SO_SYNCHRONOUS_ALERT=$10 +Const SO_SYNCHRONOUS_NONALERT=$20 +?Win32 +Const SO_OPENTYPE=$7008 +Const SO_MAXDG=$7009 +Const SO_MAXPATHDG=$700A +Const SO_UPDATE_ACCEPT_CONTEXT=$700B +Const SO_CONNECT_TIME=$700C +? +Const TCP_NODELAY=$0001 +Const TCP_BSDURGENT=$7000 + +Const IPPROTO_UDP=17 +Const IPPROTO_TCP=6 + +'how params for shutdown_ + +Const SD_SEND=1 +Const SD_RECEIVE=0 +Const SD_BOTH=2 + +Function htons_( n ) +Function ntohs_( n ) +Function htonl_( n ) +Function ntohl_( n ) +Function socket_( addr_type,comm_type,protocol=0 ) +Function closesocket_( socket ) +Function bind_( socket,addr_type,port ) +Function gethostbyaddr_:Byte Ptr( addr:Byte Ptr,addr_len,addr_type ) + +Function gethostbyname_:Byte Ptr Ptr( name$,addr_type Var,addr_len Var ) + +Function connect_( socket,addr:Byte Ptr,addr_type,addr_len,port ) +Function listen_( socket,backlog ) +Function accept_( socket,addr:Byte Ptr,addr_len:Byte Ptr) +Function select_( n_read,read_socks:Int Ptr,n_write,write_socks:Int Ptr,n_except,except_socks:Int Ptr,millis ) +Function send_( socket,buf:Byte Ptr,size,flags ) +Function sendto_( socket,buf:Byte Ptr,size,flags,dest_ip,dest_port ) +Function recv_( socket,buf:Byte Ptr,size,flags ) +Function recvfrom_( socket,buf:Byte Ptr,size,flags,sender_ip Var,sender_port Var) +Function setsockopt_( socket,level,optname,optval:Byte Ptr,count) +Function getsockopt_( socket,level,optname,optval:Byte Ptr,count Var) +Function shutdown_( socket,how ) +Function getsockname_( socket,addr:Byte Ptr,addr_len Var ) +Function getpeername_( socket,addr:Byte Ptr,addr_len Var ) + +'time + +Function time_( time:Byte Ptr ) +Function localtime_:Byte Ptr( time:Byte Ptr ) +Function strftime_( buf:Byte Ptr,size,fmt$,time:Byte Ptr ) + +End Extern + +Private + +Extern "c" +Function Startup()="bb_stdc_Startup" +End Extern + +Startup + +Public diff --git a/mod/pub.mod/stdc.mod/stdc.c b/mod/pub.mod/stdc.mod/stdc.c new file mode 100644 index 0000000..9fbd20e --- /dev/null +++ b/mod/pub.mod/stdc.mod/stdc.c @@ -0,0 +1,487 @@ + +#include + +#include +#include +#include + +#if _WIN32 + +#include +#include + +#define WIN32_LEAN_AND_MEAN +#include +#include + +extern int _bbusew; + +#else + +#include +#include +#include //PATH_MAX +#include +#include +#include +#include +#include + +#endif + +int stdin_; +int stdout_; +int stderr_; + +#if _WIN32 + +int getchar_(){ + if( _bbusew ) return getwchar(); + return getchar(); +} + +int puts_( BBString *str ){ + if( _bbusew ) return _putws( bbTmpWString(str) ); + return puts( bbTmpCString(str) ); +} + +int putenv_( BBString *str ){ + if( _bbusew ) return _wputenv( bbTmpWString(str) ); + return putenv( bbTmpCString(str) ); +} + +BBString *getenv_( BBString *str ){ + if( _bbusew ) return bbStringFromWString( _wgetenv( bbTmpWString(str) ) ); + return bbStringFromCString( getenv( bbTmpCString(str) ) ); +} + +int fputs_( BBString *str,int file ){ + if( _bbusew ) return fputws( bbTmpWString(str),(FILE*)file ); + return fputs( bbTmpCString(str),(FILE*)file ); +} + +int chdir_( BBString *path ){ + if( _bbusew ) return _wchdir( bbTmpWString(path) ); + return _chdir( bbTmpCString(path) ); +} + +int fopen_( BBString *file,BBString *mode ){ + if( _bbusew ) return (int)_wfopen( bbTmpWString(file),bbTmpWString(mode) ); + return (int)fopen( bbTmpCString(file),bbTmpCString(mode) ); +} + +BBString *getcwd_(){ + if( _bbusew ){ + wchar_t buf[MAX_PATH]; + _wgetcwd( buf,MAX_PATH ); + return bbStringFromWString( buf ); + }else{ + char buf[MAX_PATH]; + _getcwd( buf,MAX_PATH ); + return bbStringFromCString( buf ); + } + return &bbEmptyString; +} + +int chmod_( BBString *path,int mode ){ + if( _bbusew ) return _wchmod( bbTmpWString(path),mode ); + return _chmod( bbTmpCString(path),mode ); +} + +int mkdir_( BBString *path,int mode ){ + if( _bbusew ) return _wmkdir( bbTmpWString(path) ); + return _mkdir( bbTmpCString(path) ); +} + +int rmdir_( BBString *path ){ + if( _bbusew ) return _wrmdir( bbTmpWString(path) ); + return _rmdir( bbTmpCString(path) ); +} + +int rename_( BBString *src,BBString *dst ){ + if( _bbusew ) return _wrename( bbTmpWString(src),bbTmpWString(dst) ); + return rename( bbTmpCString(src),bbTmpCString(dst) ); +} + +void remove_( BBString *path ){ + chmod_( path,0x1b6 ); + if( _bbusew ){ + _wremove( bbTmpWString(path) ); + }else{ + remove( bbTmpCString(path) ); + } +} + +int opendir_( BBString *path ){ + if( _bbusew ) return (int)_wopendir( bbTmpWString(path) ); + return (int)opendir( bbTmpCString(path) ); +} + +int closedir_( int dir ){ + if( _bbusew ) return _wclosedir( (_WDIR*)dir ); + return closedir( (DIR*)dir ); +} + +BBString *readdir_( int dir ){ + if( _bbusew ){ + struct _wdirent *t=_wreaddir( (_WDIR*)dir ); + return t ? bbStringFromWString( t->d_name ) : &bbEmptyString; + } + struct dirent *t=readdir( (DIR*)dir ); + return t ? bbStringFromCString( t->d_name ) : &bbEmptyString; +} + +int stat_( BBString *path,int *t_mode,int *t_size,int *t_mtime,int *t_ctime ){ + int i; + struct _stat st; + + for( i=0;ilength;++i ){ + if( path->buf[i]=='<' || path->buf[i]=='>' ) return -1; + } + + if( _bbusew ){ + if( _wstat( bbTmpWString(path),&st ) ) return -1; + }else{ + if( _stat( bbTmpCString(path),&st ) ) return -1; + } + + *t_mode=st.st_mode; + *t_size=st.st_size; + *t_mtime=st.st_mtime; + *t_ctime=st.st_ctime; + return 0; +} + +int system_( BBString *cmd ){ + int res; + PROCESS_INFORMATION pi={0}; + + if( _bbusew ){ + STARTUPINFOW si={sizeof(si)}; + wchar_t *tmp=bbTmpWString(cmd); + + if( CreateProcessW( 0,tmp,0,0,1,CREATE_DEFAULT_ERROR_MODE,0,0,&si,&pi ) ){ + WaitForSingleObject( pi.hProcess,INFINITE ); + + res=GetExitCodeProcess( pi.hProcess,(DWORD*)&res ) ? res : -1; + + CloseHandle( pi.hProcess ); + CloseHandle( pi.hThread ); + }else{ + res=GetLastError(); + } + + } else { + STARTUPINFO si={sizeof(si)}; + char *tmp=bbTmpCString(cmd); + + if( CreateProcessA( 0,tmp,0,0,1,CREATE_DEFAULT_ERROR_MODE,0,0,&si,&pi ) ){ + WaitForSingleObject( pi.hProcess,INFINITE ); + + res=GetExitCodeProcess( pi.hProcess,(DWORD*)&res ) ? res : -1; + + CloseHandle( pi.hProcess ); + CloseHandle( pi.hThread ); + }else{ + res=GetLastError(); + } + } + return res; +} + +#else + +int getchar_(){ + return getchar(); +} + +int puts_( BBString *str ){ + return puts( bbTmpUTF8String( str ) ); +} + +int putenv_( BBString *str ){ + char *t=bbTmpUTF8String( str ); + char *p=(char*)malloc( strlen(t)+1 ); + strcpy( p,t ); + return putenv( p ); +} + +BBString *getenv_( BBString *str ){ + return bbStringFromUTF8String( getenv( bbTmpUTF8String(str) ) ); +} + +int fopen_( BBString *file,BBString *mode ){ + return fopen( bbTmpUTF8String(file),bbTmpUTF8String(mode) ); +} + +int fputs_( BBString *str,int file ){ + return fputs( bbTmpUTF8String(str),(FILE*)file ); +} + +int chdir_( BBString *path ){ + return chdir( bbTmpUTF8String(path) ); +} + +BBString *getcwd_(){ + char buf[PATH_MAX]; + getcwd( buf,PATH_MAX ); + return bbStringFromUTF8String( buf ); +} + +int chmod_( BBString *path,int mode ){ + return chmod( bbTmpUTF8String(path),mode ); +} + +int mkdir_( BBString *path,int mode ){ + return mkdir( bbTmpUTF8String(path),mode ); +} + +int rmdir_( BBString *path ){ + return rmdir( bbTmpUTF8String(path) ); +} + +int rename_( BBString *src,BBString *dst ){ + return rename( bbTmpUTF8String(src),bbTmpUTF8String(dst) ); +} + +int remove_( BBString *path ){ + return remove( bbTmpUTF8String(path) ); +} + +int opendir_( BBString *path ){ + return opendir( bbTmpUTF8String(path) ); +} + +BBString *readdir_( int dir ){ + struct dirent *t=readdir( (DIR*)dir ); + return t ? bbStringFromUTF8String( t->d_name ) : &bbEmptyString; +} + +int closedir_( int dir ){ + return closedir( (DIR*)dir ); +} + +int stat_( BBString *path,int *t_mode,int *t_size,int *t_mtime,int *t_ctime ){ + struct stat st; + if( stat( bbTmpUTF8String(path),&st ) ) return -1; + *t_mode=st.st_mode; + *t_size=st.st_size; + *t_mtime=st.st_mtime; + *t_ctime=st.st_ctime; + return 0; +} + +int system_( BBString *cmd ){ + return system( bbTmpUTF8String(cmd) ); +} + +#endif + + +int htons_( int n ){ + return htons( n ); +} + +int ntohs_( int n ){ + return ntohs( n ); +} + +int htonl_( int n ){ + return htonl( n ); +} + +int ntohl_( int n ){ + return ntohl( n ); +} + +int socket_( int addr_type,int comm_type,int protocol ){ + return socket( addr_type,comm_type,protocol ); +} + +void closesocket_( int s ){ +#if _WIN32 + closesocket( s ); +#else + close( s ); +#endif +} + +int bind_( int socket,int addr_type,int port ){ + int r; + struct sockaddr_in sa; + + if( addr_type!=AF_INET ) return -1; + + memset( &sa,0,sizeof(sa) ); + sa.sin_family=addr_type; + sa.sin_addr.s_addr=htonl(INADDR_ANY); + sa.sin_port=htons( port ); + + return bind( socket,(void*)&sa,sizeof(sa) ); +} + +char *gethostbyaddr_( void *addr,int addr_len,int addr_type ){ + struct hostent *e=gethostbyaddr( addr,addr_len,addr_type ); + return e ? e->h_name : 0; +} + +char **gethostbyname_( BBString *name,int *addr_type,int *addr_len ){ + struct hostent *e=gethostbyname( bbTmpCString( name ) ); + if( !e ) return 0; + *addr_type=e->h_addrtype; + *addr_len=e->h_length; + return e->h_addr_list; +} + +int connect_( int socket,const char *addr,int addr_type,int addr_len,int port ){ + struct sockaddr_in sa; + + if( addr_type!=AF_INET ) return -1; + + memset( &sa,0,sizeof(sa) ); + sa.sin_family=addr_type; + sa.sin_port=htons( port ); + memcpy( &sa.sin_addr,addr,addr_len ); + + return connect( socket,(void*)&sa,sizeof(sa) ); +} + +int listen_( int socket,int backlog ){ + return listen( socket,backlog ); +} + +int accept_( int socket,const char *addr,unsigned int *addr_len ){ + return accept( socket,(void*)addr,addr_len ); +} + +int select_( int n_read,int *r_socks,int n_write,int *w_socks,int n_except,int *e_socks,int millis ){ + + int i,n,r; + struct timeval tv,*tvp; + fd_set r_set,w_set,e_set; + + n=-1; + + FD_ZERO( &r_set ); + for( i=0;in ) n=r_socks[i]; + } + FD_ZERO( &w_set ); + for( i=0;in ) n=w_socks[i]; + } + FD_ZERO( &e_set ); + for( i=0;in ) n=e_socks[i]; + } + + if( millis<0 ){ + tvp=0; + }else{ + tv.tv_sec=millis/1000; + tv.tv_usec=(millis%1000)*1000; + tvp=&tv; + } + + r=select( n+1,&r_set,&w_set,&e_set,tvp ); + if( r<0 ) return r; + + for( i=0;i

      zlib 1.1.4 Manual

      +
      +

      Contents

      +
        +
      1. Prologue +
      2. Introduction +
      3. Utility functions +
      4. Basic functions +
      5. Advanced functions +
      6. Constants +
      7. struct z_stream_s +
      8. Checksum functions +
      9. Misc +
      +
      +

      Prologue

      + 'zlib' general purpose compression library version 1.1.4, March 11th, 2002 +

      + Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler +

      + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. +

      + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: +

        +
      1. The origin of this software must not be misrepresented ; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. +
      2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. +
      3. This notice may not be removed or altered from any source distribution. +
      + +
      +
      Jean-loup Gailly +
      jloup@gzip.org +
      Mark Adler +
      madler@alumni.caltech.edu +
      + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files + + ftp://ds.internic.net/rfc/rfc1950.txt + (zlib format), + + rfc1951.txt + (deflate format) and + + rfc1952.txt + (gzip format). +

      + This manual is converted from zlib.h by + piaip +

      + Visit + http://ftp.cdrom.com/pub/infozip/zlib/ + for the official zlib web page. +

      + +


      +

      Introduction

      + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed + data. This version of the library supports only one compression method + (deflation) but other algorithms will be added later and will have the same + stream interface. +

      + + Compression can be done in a single step if the buffers are large + enough (for example if an input file is mmap'ed), or can be done by + repeated calls of the compression function. In the latter case, the + application must provide more input and/or consume the output + (providing more output space) before each call. +

      + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio. +

      + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never + crash even in case of corrupted input. +

      + +


      +

      Utility functions

      + The following utility functions are implemented on top of the +
      basic stream-oriented functions. + To simplify the interface, some + default options are assumed (compression level and memory usage, + standard memory allocation functions). The source code of these + utility functions can easily be modified if you need special options. +

      Function list

      +
        +
      • int compress (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen); +
      • int compress2 (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen, int level); +
      • int uncompress (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen); +
      • typedef voidp gzFile; +
      • gzFile gzopen (const char *path, const char *mode); +
      • gzFile gzdopen (int fd, const char *mode); +
      • int gzsetparams (gzFile file, int level, int strategy); +
      • int gzread (gzFile file, voidp buf, unsigned len); +
      • int gzwrite (gzFile file, const voidp buf, unsigned len); +
      • int VA gzprintf (gzFile file, const char *format, ...); +
      • int gzputs (gzFile file, const char *s); +
      • char * gzgets (gzFile file, char *buf, int len); +
      • int gzputc (gzFile file, int c); +
      • int gzgetc (gzFile file); +
      • int gzflush (gzFile file, int flush); +
      • z_off_t gzseek (gzFile file, z_off_t offset, int whence); +
      • z_off_t gztell (gzFile file); +
      • int gzrewind (gzFile file); +
      • int gzeof (gzFile file); +
      • int gzclose (gzFile file); +
      • const char * gzerror (gzFile file, int *errnum); +
      +

      Function description

      +
      +
      int compress (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen); +
      + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be at least 0.1% larger than + sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the + compressed buffer.

      + This function can be used to compress a whole file at once if the + input file is mmap'ed.

      + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer.

      + +

      int compress2 (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen, int level); +
      + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least 0.1% larger than sourceLen plus + 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. +

      + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +

      + +

      int uncompress (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen); +
      + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be large enough to hold the + entire uncompressed data. (The size of the uncompressed data must have + been saved previously by the compressor and transmitted to the decompressor + by some mechanism outside the scope of this compression library.) + Upon exit, destLen is the actual size of the compressed buffer.

      + This function can be used to decompress a whole file at once if the + input file is mmap'ed. +

      + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted. +

      + +

      typedef voidp gzFile; +

      + +

      gzFile gzopen (const char *path, const char *mode); +
      + Opens a gzip (.gz) file for reading or writing. The mode parameter + is as in fopen ("rb" or "wb") but can also include a compression level + ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for + Huffman only compression as in "wb1h". (See the description + of deflateInit2 for more information about the strategy parameter.) +

      + + gzopen can be used to read a file which is not in gzip format ; in this + case gzread will directly read from the file without decompression. +

      + + gzopen returns NULL if the file could not be opened or if there was + insufficient memory to allocate the (de)compression state ; errno + can be checked to distinguish the two cases (if errno is zero, the + zlib error is Z_MEM_ERROR). +

      + +

      gzFile gzdopen (int fd, const char *mode); +
      + gzdopen() associates a gzFile with the file descriptor fd. File + descriptors are obtained from calls like open, dup, creat, pipe or + fileno (in the file has been previously opened with fopen). + The mode parameter is as in gzopen. +

      + The next call of gzclose on the returned gzFile will also close the + file descriptor fd, just like fclose(fdopen(fd), mode) closes the file + descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode). +

      + gzdopen returns NULL if there was insufficient memory to allocate + the (de)compression state. +

      + +

      int gzsetparams (gzFile file, int level, int strategy); +
      + Dynamically update the compression level or strategy. See the description + of deflateInit2 for the meaning of these parameters. +

      + gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not + opened for writing. +

      + +

      int gzread (gzFile file, voidp buf, unsigned len); +
      + Reads the given number of uncompressed bytes from the compressed file. + If the input file was not in gzip format, gzread copies the given number + of bytes into the buffer. +

      + gzread returns the number of uncompressed bytes actually read (0 for + end of file, -1 for error). +

      + +

      int gzwrite (gzFile file, const voidp buf, unsigned len); +
      + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of uncompressed bytes actually written + (0 in case of error). +

      + +

      int VA gzprintf (gzFile file, const char *format, ...); +
      + Converts, formats, and writes the args to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written (0 in case of error). +

      + +

      int gzputs (gzFile file, const char *s); +
      + Writes the given null-terminated string to the compressed file, excluding + the terminating null character. +

      + gzputs returns the number of characters written, or -1 in case of error. +

      + +

      char * gzgets (gzFile file, char *buf, int len); +
      + Reads bytes from the compressed file until len-1 characters are read, or + a newline character is read and transferred to buf, or an end-of-file + condition is encountered. The string is then terminated with a null + character. +

      + gzgets returns buf, or Z_NULL in case of error. +

      + +

      int gzputc (gzFile file, int c); +
      + Writes c, converted to an unsigned char, into the compressed file. + gzputc returns the value that was written, or -1 in case of error. +

      + +

      int gzgetc (gzFile file); +
      + Reads one byte from the compressed file. gzgetc returns this byte + or -1 in case of end of file or error. +

      + +

      int gzflush (gzFile file, int flush); +
      + Flushes all pending output into the compressed file. The parameter + flush is as in the deflate() function. The return value is the zlib + error number (see function gzerror below). gzflush returns Z_OK if + the flush parameter is Z_FINISH and all output could be flushed. +

      + gzflush should be called only when strictly necessary because it can + degrade compression. +

      + +

      z_off_t gzseek (gzFile file, z_off_t offset, int whence); +
      + Sets the starting position for the next gzread or gzwrite on the + given compressed file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); + the value SEEK_END is not supported. +

      + If the file is opened for reading, this function is emulated but can be + extremely slow. If the file is opened for writing, only forward seeks are + supported ; gzseek then compresses a sequence of zeroes up to the new + starting position. +

      + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error, in + particular if the file is opened for writing and the new starting position + would be before the current position. +

      + +

      int gzrewind (gzFile file); +
      + Rewinds the given file. This function is supported only for reading. +

      + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) +

      + +

      z_off_t gztell (gzFile file); +
      + Returns the starting position for the next gzread or gzwrite on the + given compressed file. This position represents a number of bytes in the + uncompressed data stream. +

      + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +

      + +

      int gzeof (gzFile file); +
      + Returns 1 when EOF has previously been detected reading the given + input stream, otherwise zero. +

      + +

      int gzclose (gzFile file); +
      + Flushes all pending output if necessary, closes the compressed file + and deallocates all the (de)compression state. The return value is the zlib + error number (see function gzerror below). +

      + +

      const char * gzerror (gzFile file, int *errnum); +
      + Returns the error message for the last error which occurred on the + given compressed file. errnum is set to zlib error number. If an + error occurred in the file system and not in the compression library, + errnum is set to Z_ERRNO and the application may consult errno + to get the exact error code. +

      +

      +
      +

      Basic functions

      +

      Function list

      +
      + +

      Function description

      +
      +
      const char * zlibVersion (void); +
      The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is + not compatible with the zlib.h header file used by the application. + This check is automatically made by deflateInit and inflateInit. +

      + +

      int deflateInit (z_streamp strm, int level); +
      + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. + If zalloc and zfree are set to Z_NULL, deflateInit updates them to + use default allocation functions. +

      + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at + all (the input data is simply copied a block at a time). +

      + + Z_DEFAULT_COMPRESSION requests a default compromise between speed and + compression (currently equivalent to level 6). +

      + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if level is not a valid compression level, + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). + msg is set to null if there is no error message. deflateInit does not + perform any compression: this will be done by deflate(). +

      + +

      int deflate (z_streamp strm, int flush); +
      + deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce some + output latency (reading input without producing any output) except when + forced to flush.

      + + The detailed semantics are as follows. deflate performs one or both of the + following actions: + +

        +
      • Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + +
      • + Provide more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary (in interactive applications). + Some output may be provided even if flush is not set. +

      + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating avail_in or avail_out accordingly ; avail_out + should never be zero before the call. The application can consume the + compressed output when it wants, for example when the output buffer is full + (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK + and with zero avail_out, it must be called again after making room in the + output buffer because there might be more output pending. +

      + + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In particular + avail_in is zero after the call if enough output space has been provided + before the call.) Flushing may degrade compression for some compression + algorithms and so it should be used only when necessary. +

      + + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + the compression. +

      + + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). +

      + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there + was enough output space ; if deflate returns with Z_OK, this function must be + called again with Z_FINISH and more output space (updated avail_out) but no + more input data, until it returns with Z_STREAM_END or an error. After + deflate has returned Z_STREAM_END, the only possible operations on the + stream are deflateReset or deflateEnd. +

      + + Z_FINISH can be used immediately after deflateInit if all the compression + is to be done in a single step. In this case, avail_out must be at least + 0.1% larger than avail_in plus 12 bytes. If deflate does not return + Z_STREAM_END, then it must be called again as described above. +

      + + deflate() sets strm-> adler to the adler32 checksum of all input read + so far (that is, total_in bytes). +

      + + deflate() may update data_type if it can make a good guess about + the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered + binary. This field is only for information purposes and does not affect + the compression algorithm in any manner. +

      + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible + (for example avail_in or avail_out was zero). +

      + +

      int deflateEnd (z_streamp strm); +
      + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. +

      + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, + msg may be set but then points to a static string (which must not be + deallocated). +

      + +

      int inflateInit (z_streamp strm); +
      + Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. If next_in is not Z_NULL and avail_in is large enough (the exact + value depends on the compression method), inflateInit determines the + compression method from the zlib header and allocates all data structures + accordingly ; otherwise the allocation will be deferred to the first call of + inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to + use default allocation functions. +

      + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller. msg is set to null if there is no error + message. inflateInit does not perform any decompression apart from reading + the zlib header if present: this will be done by inflate(). (So next_in and + avail_in may be modified, but next_out and avail_out are unchanged.) +

      + +

      int inflate (z_streamp strm, int flush); +
      + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may some + introduce some output latency (reading input without producing any output) + except when forced to flush. +

      + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + +

        +
      • Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in is updated and processing + will resume at this point for the next call of inflate(). + +
      • Provide more output starting at next_out and update next_out and + avail_out accordingly. inflate() provides as much output as possible, + until there is no more input data or no more space in the output buffer + (see below about the flush parameter). +

      + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating the next_* and avail_* values accordingly. + The application can consume the uncompressed output when it wants, for + example when the output buffer is full (avail_out == 0), or after each + call of inflate(). If inflate returns Z_OK and with zero avail_out, it + must be called again after making room in the output buffer because there + might be more output pending. +

      + + If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much + output as possible to the output buffer. The flushing behavior of inflate is + not specified for values of the flush parameter other than Z_SYNC_FLUSH + and Z_FINISH, but the current implementation actually flushes as much output + as possible anyway. +

      + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step + (a single call of inflate), the parameter flush should be set to + Z_FINISH. In this case all pending input is processed and all pending + output is flushed ; avail_out must be large enough to hold all the + uncompressed data. (The size of the uncompressed data may have been saved + by the compressor for this purpose.) The next operation on this stream must + be inflateEnd to deallocate the decompression state. The use of Z_FINISH + is never required, but can be used to inform inflate that a faster routine + may be used for the single inflate() call. +

      + + If a preset dictionary is needed at this point (see inflateSetDictionary + below), inflate sets strm-adler to the adler32 checksum of the + dictionary chosen by the compressor and returns Z_NEED_DICT ; otherwise + it sets strm-> adler to the adler32 checksum of all output produced + so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or + an error code as described below. At the end of the stream, inflate() + checks that its computed adler32 checksum is equal to that saved by the + compressor and returns Z_STREAM_END only if the checksum is correct. +

      + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect + adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent + (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if no progress is possible or if there was not + enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR + case, the application may then call inflateSync to look for a good + compression block. +

      + +

      int inflateEnd (z_streamp strm); +
      + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. +

      + + inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state + was inconsistent. In the error case, msg may be set but then points to a + static string (which must not be deallocated). +

      +
      +

      Advanced functions

      + The following functions are needed only in some special applications. +

      Function list

      +
      +

      Function description

      +
      +
      int deflateInit2 (z_streamp strm, int level, int method, int windowBits, int memLevel, int strategy); + +
      This is another version of deflateInit with more compression options. The + fields next_in, zalloc, zfree and opaque must be initialized before by + the caller.

      + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library.

      + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead.

      + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but + is slow and reduces compression ratio ; memLevel=9 uses maximum memory + for optimal speed. The default value is 8. See zconf.h for total memory + usage as a function of windowBits and memLevel.

      + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match). Filtered data consists mostly of small values with a + somewhat random distribution. In this case, the compression algorithm is + tuned to compress them better. The effect of Z_FILTERED is to force more + Huffman coding and less string matching ; it is somewhat intermediate + between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects + the compression ratio but not the correctness of the compressed output even + if it is not set appropriately.

      + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid + method). msg is set to null if there is no error message. deflateInit2 does + not perform any compression: this will be done by deflate().

      + +

      int deflateSetDictionary (z_streamp strm, const Bytef *dictionary, uInt dictLength); +
      + Initializes the compression dictionary from the given byte sequence + without producing any compressed output. This function must be called + immediately after deflateInit, deflateInit2 or deflateReset, before any + call of deflate. The compressor and decompressor must use exactly the same + dictionary (see inflateSetDictionary).

      + + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy ; the data can then be compressed better than + with the default empty dictionary.

      + + Depending on the size of the compression data structures selected by + deflateInit or deflateInit2, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size in + deflate or deflate2. Thus the strings most likely to be useful should be + put at the end of the dictionary, not at the front.

      + + Upon return of this function, strm-> adler is set to the Adler32 value + of the dictionary ; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The Adler32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.)

      + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if the compression method is bsort). deflateSetDictionary does not + perform any compression: this will be done by deflate().

      + +

      int deflateCopy (z_streamp dest, z_streamp source); +
      + Sets the destination stream as a complete copy of the source stream.

      + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and + can consume lots of memory.

      + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination.

      + +

      int deflateReset (z_streamp strm); +
      This function is equivalent to deflateEnd followed by deflateInit, + but does not free and reallocate all the internal compression state. + The stream will keep the same compression level and any other attributes + that may have been set by deflateInit2.

      + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL).

      + +

      int deflateParams (z_streamp strm, int level, int strategy); +
      + Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in deflateInit2. This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different + strategy. If the compression level is changed, the input available so far + is compressed with the old level (and may be flushed); the new level will + take effect only at the next call of deflate().

      + + Before the call of deflateParams, the stream state must be set as for + a call of deflate(), since the currently available input may have to + be compressed and flushed. In particular, strm-> avail_out must be + non-zero.

      + + deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source + stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR + if strm->avail_out was zero.

      + +

      int inflateInit2 (z_streamp strm, int windowBits); + +
      This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller.

      + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. If a compressed stream with a larger window size is given as + input, inflate() will return with the error code Z_DATA_ERROR instead of + trying to allocate a larger window.

      + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative + memLevel). msg is set to null if there is no error message. inflateInit2 + does not perform any decompression apart from reading the zlib header if + present: this will be done by inflate(). (So next_in and avail_in may be + modified, but next_out and avail_out are unchanged.)

      + +

      int inflateSetDictionary (z_streamp strm, const Bytef *dictionary, uInt dictLength); +
      + Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of inflate + if this call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the Adler32 value returned by this call of + inflate. The compressor and decompressor must use exactly the same + dictionary (see deflateSetDictionary).

      + + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect Adler32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate().

      + +

      int inflateSync (z_streamp strm); + +
      Skips invalid compressed data until a full flush point (see above the + description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided.

      + + inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR + if no more input was provided, Z_DATA_ERROR if no flush point has been found, + or Z_STREAM_ERROR if the stream structure was inconsistent. In the success + case, the application may save the current current value of total_in which + indicates where valid compressed data was found. In the error case, the + application may repeatedly call inflateSync, providing more input each time, + until success or end of the input data.

      + +

      int inflateReset (z_streamp strm); +
      + This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate all the internal decompression state. + The stream will keep attributes that may have been set by inflateInit2. +

      + + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +

      +

      + +
      +

      Checksum functions

      + These functions are not related to compression but are exported + anyway because they might be useful in applications using the + compression library. +

      Function list

      +
      +

      Function description

      +
      +
      uLong adler32 (uLong adler, const Bytef *buf, uInt len); +
      + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. If buf is NULL, this function returns + the required initial value for the checksum. +

      + An Adler-32 checksum is almost as reliable as a CRC32 but can be computed + much faster. Usage example: +

      +
      +     uLong adler = adler32(0L, Z_NULL, 0);
      +
      +     while (read_buffer(buffer, length) != EOF) {
      +       adler = adler32(adler, buffer, length);
      +     }
      +     if (adler != original_adler) error();
      +   
      + +
      uLong crc32 (uLong crc, const Bytef *buf, uInt len); +
      + Update a running crc with the bytes buf[0..len-1] and return the updated + crc. If buf is NULL, this function returns the required initial value + for the crc. Pre- and post-conditioning (one's complement) is performed + within this function so it shouldn't be done by the application. + Usage example: +
      +
      +     uLong crc = crc32(0L, Z_NULL, 0);
      +
      +     while (read_buffer(buffer, length) != EOF) {
      +       crc = crc32(crc, buffer, length);
      +     }
      +     if (crc != original_crc) error();
      +   
      +
      +
      +

      struct z_stream_s

      + +
      +
      +typedef struct z_stream_s {
      +    Bytef    *next_in;  /* next input byte */
      +    uInt     avail_in;  /* number of bytes available at next_in */
      +    uLong    total_in;  /* total nb of input bytes read so far */
      +
      +    Bytef    *next_out; /* next output byte should be put there */
      +    uInt     avail_out; /* remaining free space at next_out */
      +    uLong    total_out; /* total nb of bytes output so far */
      +
      +    char     *msg;      /* last error message, NULL if no error */
      +    struct internal_state FAR *state; /* not visible by applications */
      +
      +    alloc_func zalloc;  /* used to allocate the internal state */
      +    free_func  zfree;   /* used to free the internal state */
      +    voidpf     opaque;  /* private data object passed to zalloc and zfree */
      +
      +    int     data_type;  /* best guess about the data type: ascii or binary */
      +    uLong   adler;      /* adler32 value of the uncompressed data */
      +    uLong   reserved;   /* reserved for future use */
      +} z_stream ;
      +
      +typedef z_stream FAR * z_streamp;  ΓΏ 
      +
      +
      + The application must update next_in and avail_in when avail_in has + dropped to zero. It must update next_out and avail_out when avail_out + has dropped to zero. The application must initialize zalloc, zfree and + opaque before calling the init function. All other fields are set by the + compression library and must not be updated by the application.

      + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value.

      + + zalloc must return Z_NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe.

      + + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this + if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, + pointers returned by zalloc for objects of exactly 65536 bytes *must* + have their offset normalized to zero. The default allocation function + provided by this library ensures this (see zutil.c). To reduce memory + requirements and avoid any allocation of 64K objects, at the expense of + compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). +

      + + The fields total_in and total_out can be used for statistics or + progress reports. After compression, total_in holds the total size of + the uncompressed data and may be saved for use in the decompressor + (particularly if the decompressor wants to decompress everything in + a single step).

      + +


      +

      Constants

      + +
      +#define Z_NO_FLUSH      0
      +#define Z_PARTIAL_FLUSH 1 
      +	/* will be removed, use Z_SYNC_FLUSH instead */
      +#define Z_SYNC_FLUSH    2
      +#define Z_FULL_FLUSH    3
      +#define Z_FINISH        4
      +/* Allowed flush values ; see deflate() below for details */
      +
      +#define Z_OK            0
      +#define Z_STREAM_END    1
      +#define Z_NEED_DICT     2
      +#define Z_ERRNO        (-1)
      +#define Z_STREAM_ERROR (-2)
      +#define Z_DATA_ERROR   (-3)
      +#define Z_MEM_ERROR    (-4)
      +#define Z_BUF_ERROR    (-5)
      +#define Z_VERSION_ERROR (-6)
      +/* Return codes for the compression/decompression functions. Negative
      + * values are errors, positive values are used for special but normal events.
      + */
      +
      +#define Z_NO_COMPRESSION         0
      +#define Z_BEST_SPEED             1
      +#define Z_BEST_COMPRESSION       9
      +#define Z_DEFAULT_COMPRESSION  (-1)
      +/* compression levels */
      +
      +#define Z_FILTERED            1
      +#define Z_HUFFMAN_ONLY        2
      +#define Z_DEFAULT_STRATEGY    0
      +/* compression strategy ; see deflateInit2() below for details */
      +
      +#define Z_BINARY   0
      +#define Z_ASCII    1
      +#define Z_UNKNOWN  2
      +/* Possible values of the data_type field */
      +
      +#define Z_DEFLATED   8
      +/* The deflate compression method (the only one supported in this version) */
      +
      +#define Z_NULL  0  /* for initializing zalloc, zfree, opaque */
      +
      +#define zlib_version zlibVersion()
      +/* for compatibility with versions less than 1.0.2 */
      +
      +
      + +
      +

      Misc

      +
      deflateInit and inflateInit are macros to allow checking the zlib version + and the compiler's view of z_stream. +

      + Other functions: +

      +
      const char * zError (int err); +
      int inflateSyncPoint (z_streamp z); +
      const uLongf * get_crc_table (void); +
      +
      + + Last update: Wed Oct 13 20:42:34 1999
      + piapi@csie.ntu.edu.tw +
      + + + diff --git a/mod/pub.mod/zlib.mod/zutil.c b/mod/pub.mod/zlib.mod/zutil.c new file mode 100644 index 0000000..d55f594 --- /dev/null +++ b/mod/pub.mod/zlib.mod/zutil.c @@ -0,0 +1,318 @@ +/* zutil.c -- target dependent utility functions for the compression library + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#include "zutil.h" + +#ifndef NO_DUMMY_DECL +struct internal_state {int dummy;}; /* for buggy compilers */ +#endif + +const char * const z_errmsg[10] = { +"need dictionary", /* Z_NEED_DICT 2 */ +"stream end", /* Z_STREAM_END 1 */ +"", /* Z_OK 0 */ +"file error", /* Z_ERRNO (-1) */ +"stream error", /* Z_STREAM_ERROR (-2) */ +"data error", /* Z_DATA_ERROR (-3) */ +"insufficient memory", /* Z_MEM_ERROR (-4) */ +"buffer error", /* Z_BUF_ERROR (-5) */ +"incompatible version",/* Z_VERSION_ERROR (-6) */ +""}; + + +const char * ZEXPORT zlibVersion() +{ + return ZLIB_VERSION; +} + +uLong ZEXPORT zlibCompileFlags() +{ + uLong flags; + + flags = 0; + switch (sizeof(uInt)) { + case 2: break; + case 4: flags += 1; break; + case 8: flags += 2; break; + default: flags += 3; + } + switch (sizeof(uLong)) { + case 2: break; + case 4: flags += 1 << 2; break; + case 8: flags += 2 << 2; break; + default: flags += 3 << 2; + } + switch (sizeof(voidpf)) { + case 2: break; + case 4: flags += 1 << 4; break; + case 8: flags += 2 << 4; break; + default: flags += 3 << 4; + } + switch (sizeof(z_off_t)) { + case 2: break; + case 4: flags += 1 << 6; break; + case 8: flags += 2 << 6; break; + default: flags += 3 << 6; + } +#ifdef DEBUG + flags += 1 << 8; +#endif +#if defined(ASMV) || defined(ASMINF) + flags += 1 << 9; +#endif +#ifdef ZLIB_WINAPI + flags += 1 << 10; +#endif +#ifdef BUILDFIXED + flags += 1 << 12; +#endif +#ifdef DYNAMIC_CRC_TABLE + flags += 1 << 13; +#endif +#ifdef NO_GZCOMPRESS + flags += 1L << 16; +#endif +#ifdef NO_GZIP + flags += 1L << 17; +#endif +#ifdef PKZIP_BUG_WORKAROUND + flags += 1L << 20; +#endif +#ifdef FASTEST + flags += 1L << 21; +#endif +#ifdef STDC +# ifdef NO_vsnprintf + flags += 1L << 25; +# ifdef HAS_vsprintf_void + flags += 1L << 26; +# endif +# else +# ifdef HAS_vsnprintf_void + flags += 1L << 26; +# endif +# endif +#else + flags += 1L << 24; +# ifdef NO_snprintf + flags += 1L << 25; +# ifdef HAS_sprintf_void + flags += 1L << 26; +# endif +# else +# ifdef HAS_snprintf_void + flags += 1L << 26; +# endif +# endif +#endif + return flags; +} + +#ifdef DEBUG + +# ifndef verbose +# define verbose 0 +# endif +int z_verbose = verbose; + +void z_error (m) + char *m; +{ + fprintf(stderr, "%s\n", m); + exit(1); +} +#endif + +/* exported to allow conversion of error code to string for compress() and + * uncompress() + */ +const char * ZEXPORT zError(err) + int err; +{ + return ERR_MSG(err); +} + +#if defined(_WIN32_WCE) + /* The Microsoft C Run-Time Library for Windows CE doesn't have + * errno. We define it as a global variable to simplify porting. + * Its value is always 0 and should not be used. + */ + int errno = 0; +#endif + +#ifndef HAVE_MEMCPY + +void zmemcpy(dest, source, len) + Bytef* dest; + const Bytef* source; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = *source++; /* ??? to be unrolled */ + } while (--len != 0); +} + +int zmemcmp(s1, s2, len) + const Bytef* s1; + const Bytef* s2; + uInt len; +{ + uInt j; + + for (j = 0; j < len; j++) { + if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; + } + return 0; +} + +void zmemzero(dest, len) + Bytef* dest; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = 0; /* ??? to be unrolled */ + } while (--len != 0); +} +#endif + + +#ifdef SYS16BIT + +#ifdef __TURBOC__ +/* Turbo C in 16-bit mode */ + +# define MY_ZCALLOC + +/* Turbo C malloc() does not allow dynamic allocation of 64K bytes + * and farmalloc(64K) returns a pointer with an offset of 8, so we + * must fix the pointer. Warning: the pointer must be put back to its + * original form in order to free it, use zcfree(). + */ + +#define MAX_PTR 10 +/* 10*64K = 640K */ + +local int next_ptr = 0; + +typedef struct ptr_table_s { + voidpf org_ptr; + voidpf new_ptr; +} ptr_table; + +local ptr_table table[MAX_PTR]; +/* This table is used to remember the original form of pointers + * to large buffers (64K). Such pointers are normalized with a zero offset. + * Since MSDOS is not a preemptive multitasking OS, this table is not + * protected from concurrent access. This hack doesn't work anyway on + * a protected system like OS/2. Use Microsoft C instead. + */ + +voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) +{ + voidpf buf = opaque; /* just to make some compilers happy */ + ulg bsize = (ulg)items*size; + + /* If we allocate less than 65520 bytes, we assume that farmalloc + * will return a usable pointer which doesn't have to be normalized. + */ + if (bsize < 65520L) { + buf = farmalloc(bsize); + if (*(ush*)&buf != 0) return buf; + } else { + buf = farmalloc(bsize + 16L); + } + if (buf == NULL || next_ptr >= MAX_PTR) return NULL; + table[next_ptr].org_ptr = buf; + + /* Normalize the pointer to seg:0 */ + *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; + *(ush*)&buf = 0; + table[next_ptr++].new_ptr = buf; + return buf; +} + +void zcfree (voidpf opaque, voidpf ptr) +{ + int n; + if (*(ush*)&ptr != 0) { /* object < 64K */ + farfree(ptr); + return; + } + /* Find the original pointer */ + for (n = 0; n < next_ptr; n++) { + if (ptr != table[n].new_ptr) continue; + + farfree(table[n].org_ptr); + while (++n < next_ptr) { + table[n-1] = table[n]; + } + next_ptr--; + return; + } + ptr = opaque; /* just to make some compilers happy */ + Assert(0, "zcfree: ptr not found"); +} + +#endif /* __TURBOC__ */ + + +#ifdef M_I86 +/* Microsoft C in 16-bit mode */ + +# define MY_ZCALLOC + +#if (!defined(_MSC_VER) || (_MSC_VER <= 600)) +# define _halloc halloc +# define _hfree hfree +#endif + +voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) +{ + if (opaque) opaque = 0; /* to make compiler happy */ + return _halloc((long)items, size); +} + +void zcfree (voidpf opaque, voidpf ptr) +{ + if (opaque) opaque = 0; /* to make compiler happy */ + _hfree(ptr); +} + +#endif /* M_I86 */ + +#endif /* SYS16BIT */ + + +#ifndef MY_ZCALLOC /* Any system without a special alloc function */ + +#ifndef STDC +extern voidp malloc OF((uInt size)); +extern voidp calloc OF((uInt items, uInt size)); +extern void free OF((voidpf ptr)); +#endif + +voidpf zcalloc (opaque, items, size) + voidpf opaque; + unsigned items; + unsigned size; +{ + if (opaque) items += size - size; /* make compiler happy */ + return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : + (voidpf)calloc(items, size); +} + +void zcfree (opaque, ptr) + voidpf opaque; + voidpf ptr; +{ + free(ptr); + if (opaque) return; /* make compiler happy */ +} + +#endif /* MY_ZCALLOC */ diff --git a/mod/pub.mod/zlib.mod/zutil.h b/mod/pub.mod/zlib.mod/zutil.h new file mode 100644 index 0000000..b7d5eff --- /dev/null +++ b/mod/pub.mod/zlib.mod/zutil.h @@ -0,0 +1,269 @@ +/* zutil.h -- internal interface and configuration of the compression library + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id$ */ + +#ifndef ZUTIL_H +#define ZUTIL_H + +#define ZLIB_INTERNAL +#include "zlib.h" + +#ifdef STDC +# ifndef _WIN32_WCE +# include +# endif +# include +# include +#endif +#ifdef NO_ERRNO_H +# ifdef _WIN32_WCE + /* The Microsoft C Run-Time Library for Windows CE doesn't have + * errno. We define it as a global variable to simplify porting. + * Its value is always 0 and should not be used. We rename it to + * avoid conflict with other libraries that use the same workaround. + */ +# define errno z_errno +# endif + extern int errno; +#else +# ifndef _WIN32_WCE +# include +# endif +#endif + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +typedef unsigned char uch; +typedef uch FAR uchf; +typedef unsigned short ush; +typedef ush FAR ushf; +typedef unsigned long ulg; + +extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ +/* (size given to avoid silly warnings with Visual C++) */ + +#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] + +#define ERR_RETURN(strm,err) \ + return (strm->msg = (char*)ERR_MSG(err), (err)) +/* To be used only when the state is known to be valid */ + + /* common constants */ + +#ifndef DEF_WBITS +# define DEF_WBITS MAX_WBITS +#endif +/* default windowBits for decompression. MAX_WBITS is for compression only */ + +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif +/* default memLevel */ + +#define STORED_BLOCK 0 +#define STATIC_TREES 1 +#define DYN_TREES 2 +/* The three kinds of block type */ + +#define MIN_MATCH 3 +#define MAX_MATCH 258 +/* The minimum and maximum match lengths */ + +#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ + + /* target dependencies */ + +#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) +# define OS_CODE 0x00 +# if defined(__TURBOC__) || defined(__BORLANDC__) +# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) + /* Allow compilation with ANSI keywords only enabled */ + void _Cdecl farfree( void *block ); + void *_Cdecl farmalloc( unsigned long nbytes ); +# else +# include +# endif +# else /* MSC or DJGPP */ +# include +# endif +#endif + +#ifdef AMIGA +# define OS_CODE 0x01 +#endif + +#if defined(VAXC) || defined(VMS) +# define OS_CODE 0x02 +# define F_OPEN(name, mode) \ + fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") +#endif + +#if defined(ATARI) || defined(atarist) +# define OS_CODE 0x05 +#endif + +#ifdef OS2 +# define OS_CODE 0x06 +# ifdef M_I86 + #include +# endif +#endif + +#if defined(MACOS) || defined(TARGET_OS_MAC) +# define OS_CODE 0x07 +# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os +# include /* for fdopen */ +# else +# ifndef fdopen +# define fdopen(fd,mode) NULL /* No fdopen() */ +# endif +# endif +#endif + +#ifdef TOPS20 +# define OS_CODE 0x0a +#endif + +#ifdef WIN32 +# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */ +# define OS_CODE 0x0b +# endif +#endif + +#ifdef __50SERIES /* Prime/PRIMOS */ +# define OS_CODE 0x0f +#endif + +#if defined(_BEOS_) || defined(RISCOS) +# define fdopen(fd,mode) NULL /* No fdopen() */ +#endif + +#if (defined(_MSC_VER) && (_MSC_VER > 600)) +# if defined(_WIN32_WCE) +# define fdopen(fd,mode) NULL /* No fdopen() */ +# ifndef _PTRDIFF_T_DEFINED + typedef int ptrdiff_t; +# define _PTRDIFF_T_DEFINED +# endif +# else +# define fdopen(fd,type) _fdopen(fd,type) +# endif +#endif + + /* common defaults */ + +#ifndef OS_CODE +# define OS_CODE 0x03 /* assume Unix */ +#endif + +#ifndef F_OPEN +# define F_OPEN(name, mode) fopen((name), (mode)) +#endif + + /* functions */ + +#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif +#if defined(__CYGWIN__) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif +#ifndef HAVE_VSNPRINTF +# ifdef MSDOS + /* vsnprintf may exist on some MS-DOS compilers (DJGPP?), + but for now we just assume it doesn't. */ +# define NO_vsnprintf +# endif +# ifdef __TURBOC__ +# define NO_vsnprintf +# endif +# ifdef WIN32 + /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ +# if !defined(vsnprintf) && !defined(NO_vsnprintf) +# define vsnprintf _vsnprintf +# endif +# endif +# ifdef __SASC +# define NO_vsnprintf +# endif +#endif +#ifdef VMS +# define NO_vsnprintf +#endif + +#if defined(pyr) +# define NO_MEMCPY +#endif +#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) + /* Use our own functions for small and medium model with MSC <= 5.0. + * You may have to use the same strategy for Borland C (untested). + * The __SC__ check is for Symantec. + */ +# define NO_MEMCPY +#endif +#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) +# define HAVE_MEMCPY +#endif +#ifdef HAVE_MEMCPY +# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ +# define zmemcpy _fmemcpy +# define zmemcmp _fmemcmp +# define zmemzero(dest, len) _fmemset(dest, 0, len) +# else +# define zmemcpy memcpy +# define zmemcmp memcmp +# define zmemzero(dest, len) memset(dest, 0, len) +# endif +#else + extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); + extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); + extern void zmemzero OF((Bytef* dest, uInt len)); +#endif + +/* Diagnostic functions */ +#ifdef DEBUG +# include + extern int z_verbose; + extern void z_error OF((char *m)); +# define Assert(cond,msg) {if(!(cond)) z_error(msg);} +# define Trace(x) {if (z_verbose>=0) fprintf x ;} +# define Tracev(x) {if (z_verbose>0) fprintf x ;} +# define Tracevv(x) {if (z_verbose>1) fprintf x ;} +# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} +# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} +#else +# define Assert(cond,msg) +# define Trace(x) +# define Tracev(x) +# define Tracevv(x) +# define Tracec(c,x) +# define Tracecv(c,x) +#endif + + +voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); +void zcfree OF((voidpf opaque, voidpf ptr)); + +#define ZALLOC(strm, items, size) \ + (*((strm)->zalloc))((strm)->opaque, (items), (size)) +#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) +#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} + +#endif /* ZUTIL_H */ -- 2.30.2